1 // SPDX-License-Identifier: GPL-2.0 OR BSD-3-Clause 2 /* Copyright(c) 2019-2020 Realtek Corporation 3 */ 4 5 #include "cam.h" 6 #include "chan.h" 7 #include "coex.h" 8 #include "debug.h" 9 #include "fw.h" 10 #include "mac.h" 11 #include "phy.h" 12 #include "reg.h" 13 #include "util.h" 14 15 static void rtw89_fw_c2h_cmd_handle(struct rtw89_dev *rtwdev, 16 struct sk_buff *skb); 17 18 static struct sk_buff *rtw89_fw_h2c_alloc_skb(struct rtw89_dev *rtwdev, u32 len, 19 bool header) 20 { 21 struct sk_buff *skb; 22 u32 header_len = 0; 23 u32 h2c_desc_size = rtwdev->chip->h2c_desc_size; 24 25 if (header) 26 header_len = H2C_HEADER_LEN; 27 28 skb = dev_alloc_skb(len + header_len + h2c_desc_size); 29 if (!skb) 30 return NULL; 31 skb_reserve(skb, header_len + h2c_desc_size); 32 memset(skb->data, 0, len); 33 34 return skb; 35 } 36 37 struct sk_buff *rtw89_fw_h2c_alloc_skb_with_hdr(struct rtw89_dev *rtwdev, u32 len) 38 { 39 return rtw89_fw_h2c_alloc_skb(rtwdev, len, true); 40 } 41 42 struct sk_buff *rtw89_fw_h2c_alloc_skb_no_hdr(struct rtw89_dev *rtwdev, u32 len) 43 { 44 return rtw89_fw_h2c_alloc_skb(rtwdev, len, false); 45 } 46 47 static u8 _fw_get_rdy(struct rtw89_dev *rtwdev) 48 { 49 u8 val = rtw89_read8(rtwdev, R_AX_WCPU_FW_CTRL); 50 51 return FIELD_GET(B_AX_WCPU_FWDL_STS_MASK, val); 52 } 53 54 #define FWDL_WAIT_CNT 400000 55 int rtw89_fw_check_rdy(struct rtw89_dev *rtwdev) 56 { 57 u8 val; 58 int ret; 59 60 ret = read_poll_timeout_atomic(_fw_get_rdy, val, 61 val == RTW89_FWDL_WCPU_FW_INIT_RDY, 62 1, FWDL_WAIT_CNT, false, rtwdev); 63 if (ret) { 64 switch (val) { 65 case RTW89_FWDL_CHECKSUM_FAIL: 66 rtw89_err(rtwdev, "fw checksum fail\n"); 67 return -EINVAL; 68 69 case RTW89_FWDL_SECURITY_FAIL: 70 rtw89_err(rtwdev, "fw security fail\n"); 71 return -EINVAL; 72 73 case RTW89_FWDL_CV_NOT_MATCH: 74 rtw89_err(rtwdev, "fw cv not match\n"); 75 return -EINVAL; 76 77 default: 78 return -EBUSY; 79 } 80 } 81 82 set_bit(RTW89_FLAG_FW_RDY, rtwdev->flags); 83 84 return 0; 85 } 86 87 static int rtw89_fw_hdr_parser(struct rtw89_dev *rtwdev, const u8 *fw, u32 len, 88 struct rtw89_fw_bin_info *info) 89 { 90 struct rtw89_fw_hdr_section_info *section_info; 91 const u8 *fw_end = fw + len; 92 const u8 *fwdynhdr; 93 const u8 *bin; 94 u32 base_hdr_len; 95 u32 mssc_len = 0; 96 u32 i; 97 98 if (!info) 99 return -EINVAL; 100 101 info->section_num = GET_FW_HDR_SEC_NUM(fw); 102 base_hdr_len = RTW89_FW_HDR_SIZE + 103 info->section_num * RTW89_FW_SECTION_HDR_SIZE; 104 info->dynamic_hdr_en = GET_FW_HDR_DYN_HDR(fw); 105 106 if (info->dynamic_hdr_en) { 107 info->hdr_len = GET_FW_HDR_LEN(fw); 108 info->dynamic_hdr_len = info->hdr_len - base_hdr_len; 109 fwdynhdr = fw + base_hdr_len; 110 if (GET_FW_DYNHDR_LEN(fwdynhdr) != info->dynamic_hdr_len) { 111 rtw89_err(rtwdev, "[ERR]invalid fw dynamic header len\n"); 112 return -EINVAL; 113 } 114 } else { 115 info->hdr_len = base_hdr_len; 116 info->dynamic_hdr_len = 0; 117 } 118 119 bin = fw + info->hdr_len; 120 121 /* jump to section header */ 122 fw += RTW89_FW_HDR_SIZE; 123 section_info = info->section_info; 124 for (i = 0; i < info->section_num; i++) { 125 section_info->type = GET_FWSECTION_HDR_SECTIONTYPE(fw); 126 if (section_info->type == FWDL_SECURITY_SECTION_TYPE) { 127 section_info->mssc = GET_FWSECTION_HDR_MSSC(fw); 128 mssc_len += section_info->mssc * FWDL_SECURITY_SIGLEN; 129 } else { 130 section_info->mssc = 0; 131 } 132 133 section_info->len = GET_FWSECTION_HDR_SEC_SIZE(fw); 134 if (GET_FWSECTION_HDR_CHECKSUM(fw)) 135 section_info->len += FWDL_SECTION_CHKSUM_LEN; 136 section_info->redl = GET_FWSECTION_HDR_REDL(fw); 137 section_info->dladdr = 138 GET_FWSECTION_HDR_DL_ADDR(fw) & 0x1fffffff; 139 section_info->addr = bin; 140 bin += section_info->len; 141 fw += RTW89_FW_SECTION_HDR_SIZE; 142 section_info++; 143 } 144 145 if (fw_end != bin + mssc_len) { 146 rtw89_err(rtwdev, "[ERR]fw bin size\n"); 147 return -EINVAL; 148 } 149 150 return 0; 151 } 152 153 static 154 int rtw89_mfw_recognize(struct rtw89_dev *rtwdev, enum rtw89_fw_type type, 155 struct rtw89_fw_suit *fw_suit, bool nowarn) 156 { 157 struct rtw89_fw_info *fw_info = &rtwdev->fw; 158 const u8 *mfw = fw_info->firmware->data; 159 u32 mfw_len = fw_info->firmware->size; 160 const struct rtw89_mfw_hdr *mfw_hdr = (const struct rtw89_mfw_hdr *)mfw; 161 const struct rtw89_mfw_info *mfw_info; 162 int i; 163 164 if (mfw_hdr->sig != RTW89_MFW_SIG) { 165 rtw89_debug(rtwdev, RTW89_DBG_FW, "use legacy firmware\n"); 166 /* legacy firmware support normal type only */ 167 if (type != RTW89_FW_NORMAL) 168 return -EINVAL; 169 fw_suit->data = mfw; 170 fw_suit->size = mfw_len; 171 return 0; 172 } 173 174 for (i = 0; i < mfw_hdr->fw_nr; i++) { 175 mfw_info = &mfw_hdr->info[i]; 176 if (mfw_info->cv != rtwdev->hal.cv || 177 mfw_info->type != type || 178 mfw_info->mp) 179 continue; 180 181 fw_suit->data = mfw + le32_to_cpu(mfw_info->shift); 182 fw_suit->size = le32_to_cpu(mfw_info->size); 183 return 0; 184 } 185 186 if (!nowarn) 187 rtw89_err(rtwdev, "no suitable firmware found\n"); 188 return -ENOENT; 189 } 190 191 static void rtw89_fw_update_ver(struct rtw89_dev *rtwdev, 192 enum rtw89_fw_type type, 193 struct rtw89_fw_suit *fw_suit) 194 { 195 const u8 *hdr = fw_suit->data; 196 197 fw_suit->major_ver = GET_FW_HDR_MAJOR_VERSION(hdr); 198 fw_suit->minor_ver = GET_FW_HDR_MINOR_VERSION(hdr); 199 fw_suit->sub_ver = GET_FW_HDR_SUBVERSION(hdr); 200 fw_suit->sub_idex = GET_FW_HDR_SUBINDEX(hdr); 201 fw_suit->build_year = GET_FW_HDR_YEAR(hdr); 202 fw_suit->build_mon = GET_FW_HDR_MONTH(hdr); 203 fw_suit->build_date = GET_FW_HDR_DATE(hdr); 204 fw_suit->build_hour = GET_FW_HDR_HOUR(hdr); 205 fw_suit->build_min = GET_FW_HDR_MIN(hdr); 206 fw_suit->cmd_ver = GET_FW_HDR_CMD_VERSERION(hdr); 207 208 rtw89_info(rtwdev, 209 "Firmware version %u.%u.%u.%u, cmd version %u, type %u\n", 210 fw_suit->major_ver, fw_suit->minor_ver, fw_suit->sub_ver, 211 fw_suit->sub_idex, fw_suit->cmd_ver, type); 212 } 213 214 static 215 int __rtw89_fw_recognize(struct rtw89_dev *rtwdev, enum rtw89_fw_type type, 216 bool nowarn) 217 { 218 struct rtw89_fw_suit *fw_suit = rtw89_fw_suit_get(rtwdev, type); 219 int ret; 220 221 ret = rtw89_mfw_recognize(rtwdev, type, fw_suit, nowarn); 222 if (ret) 223 return ret; 224 225 rtw89_fw_update_ver(rtwdev, type, fw_suit); 226 227 return 0; 228 } 229 230 #define __DEF_FW_FEAT_COND(__cond, __op) \ 231 static bool __fw_feat_cond_ ## __cond(u32 suit_ver_code, u32 comp_ver_code) \ 232 { \ 233 return suit_ver_code __op comp_ver_code; \ 234 } 235 236 __DEF_FW_FEAT_COND(ge, >=); /* greater or equal */ 237 __DEF_FW_FEAT_COND(le, <=); /* less or equal */ 238 __DEF_FW_FEAT_COND(lt, <); /* less than */ 239 240 struct __fw_feat_cfg { 241 enum rtw89_core_chip_id chip_id; 242 enum rtw89_fw_feature feature; 243 u32 ver_code; 244 bool (*cond)(u32 suit_ver_code, u32 comp_ver_code); 245 }; 246 247 #define __CFG_FW_FEAT(_chip, _cond, _maj, _min, _sub, _idx, _feat) \ 248 { \ 249 .chip_id = _chip, \ 250 .feature = RTW89_FW_FEATURE_ ## _feat, \ 251 .ver_code = RTW89_FW_VER_CODE(_maj, _min, _sub, _idx), \ 252 .cond = __fw_feat_cond_ ## _cond, \ 253 } 254 255 static const struct __fw_feat_cfg fw_feat_tbl[] = { 256 __CFG_FW_FEAT(RTL8852A, le, 0, 13, 29, 0, OLD_HT_RA_FORMAT), 257 __CFG_FW_FEAT(RTL8852A, ge, 0, 13, 35, 0, SCAN_OFFLOAD), 258 __CFG_FW_FEAT(RTL8852A, ge, 0, 13, 35, 0, TX_WAKE), 259 __CFG_FW_FEAT(RTL8852A, ge, 0, 13, 36, 0, CRASH_TRIGGER), 260 __CFG_FW_FEAT(RTL8852A, lt, 0, 13, 38, 0, NO_PACKET_DROP), 261 __CFG_FW_FEAT(RTL8852B, ge, 0, 29, 26, 0, NO_LPS_PG), 262 __CFG_FW_FEAT(RTL8852B, ge, 0, 29, 26, 0, TX_WAKE), 263 __CFG_FW_FEAT(RTL8852B, ge, 0, 29, 29, 0, CRASH_TRIGGER), 264 __CFG_FW_FEAT(RTL8852B, ge, 0, 29, 29, 0, SCAN_OFFLOAD), 265 __CFG_FW_FEAT(RTL8852C, le, 0, 27, 33, 0, NO_DEEP_PS), 266 __CFG_FW_FEAT(RTL8852C, ge, 0, 27, 34, 0, TX_WAKE), 267 __CFG_FW_FEAT(RTL8852C, ge, 0, 27, 36, 0, SCAN_OFFLOAD), 268 __CFG_FW_FEAT(RTL8852C, ge, 0, 27, 40, 0, CRASH_TRIGGER), 269 }; 270 271 static void rtw89_fw_recognize_features(struct rtw89_dev *rtwdev) 272 { 273 const struct rtw89_chip_info *chip = rtwdev->chip; 274 const struct __fw_feat_cfg *ent; 275 const struct rtw89_fw_suit *fw_suit; 276 u32 suit_ver_code; 277 int i; 278 279 fw_suit = rtw89_fw_suit_get(rtwdev, RTW89_FW_NORMAL); 280 suit_ver_code = RTW89_FW_SUIT_VER_CODE(fw_suit); 281 282 for (i = 0; i < ARRAY_SIZE(fw_feat_tbl); i++) { 283 ent = &fw_feat_tbl[i]; 284 if (chip->chip_id != ent->chip_id) 285 continue; 286 287 if (ent->cond(suit_ver_code, ent->ver_code)) 288 RTW89_SET_FW_FEATURE(ent->feature, &rtwdev->fw); 289 } 290 } 291 292 const struct firmware * 293 rtw89_early_fw_feature_recognize(struct device *device, 294 const struct rtw89_chip_info *chip, 295 u32 *early_feat_map) 296 { 297 union rtw89_compat_fw_hdr buf = {}; 298 const struct firmware *firmware; 299 bool full_req = false; 300 u32 ver_code; 301 int ret; 302 int i; 303 304 /* If SECURITY_LOADPIN_ENFORCE is enabled, reading partial files will 305 * be denied (-EPERM). Then, we don't get right firmware things as 306 * expected. So, in this case, we have to request full firmware here. 307 */ 308 if (IS_ENABLED(CONFIG_SECURITY_LOADPIN_ENFORCE)) 309 full_req = true; 310 311 if (full_req) 312 ret = request_firmware(&firmware, chip->fw_name, device); 313 else 314 ret = request_partial_firmware_into_buf(&firmware, chip->fw_name, 315 device, &buf, sizeof(buf), 316 0); 317 318 if (ret) { 319 dev_err(device, "failed to early request firmware: %d\n", ret); 320 return NULL; 321 } 322 323 if (full_req) 324 ver_code = rtw89_compat_fw_hdr_ver_code(firmware->data); 325 else 326 ver_code = rtw89_compat_fw_hdr_ver_code(&buf); 327 328 if (!ver_code) 329 goto out; 330 331 for (i = 0; i < ARRAY_SIZE(fw_feat_tbl); i++) { 332 const struct __fw_feat_cfg *ent = &fw_feat_tbl[i]; 333 334 if (chip->chip_id != ent->chip_id) 335 continue; 336 337 if (ent->cond(ver_code, ent->ver_code)) 338 *early_feat_map |= BIT(ent->feature); 339 } 340 341 out: 342 if (full_req) 343 return firmware; 344 345 release_firmware(firmware); 346 return NULL; 347 } 348 349 int rtw89_fw_recognize(struct rtw89_dev *rtwdev) 350 { 351 const struct rtw89_chip_info *chip = rtwdev->chip; 352 int ret; 353 354 if (chip->try_ce_fw) { 355 ret = __rtw89_fw_recognize(rtwdev, RTW89_FW_NORMAL_CE, true); 356 if (!ret) 357 goto normal_done; 358 } 359 360 ret = __rtw89_fw_recognize(rtwdev, RTW89_FW_NORMAL, false); 361 if (ret) 362 return ret; 363 364 normal_done: 365 /* It still works if wowlan firmware isn't existing. */ 366 __rtw89_fw_recognize(rtwdev, RTW89_FW_WOWLAN, false); 367 368 rtw89_fw_recognize_features(rtwdev); 369 370 rtw89_coex_recognize_ver(rtwdev); 371 372 return 0; 373 } 374 375 void rtw89_h2c_pkt_set_hdr(struct rtw89_dev *rtwdev, struct sk_buff *skb, 376 u8 type, u8 cat, u8 class, u8 func, 377 bool rack, bool dack, u32 len) 378 { 379 struct fwcmd_hdr *hdr; 380 381 hdr = (struct fwcmd_hdr *)skb_push(skb, 8); 382 383 if (!(rtwdev->fw.h2c_seq % 4)) 384 rack = true; 385 hdr->hdr0 = cpu_to_le32(FIELD_PREP(H2C_HDR_DEL_TYPE, type) | 386 FIELD_PREP(H2C_HDR_CAT, cat) | 387 FIELD_PREP(H2C_HDR_CLASS, class) | 388 FIELD_PREP(H2C_HDR_FUNC, func) | 389 FIELD_PREP(H2C_HDR_H2C_SEQ, rtwdev->fw.h2c_seq)); 390 391 hdr->hdr1 = cpu_to_le32(FIELD_PREP(H2C_HDR_TOTAL_LEN, 392 len + H2C_HEADER_LEN) | 393 (rack ? H2C_HDR_REC_ACK : 0) | 394 (dack ? H2C_HDR_DONE_ACK : 0)); 395 396 rtwdev->fw.h2c_seq++; 397 } 398 399 static void rtw89_h2c_pkt_set_hdr_fwdl(struct rtw89_dev *rtwdev, 400 struct sk_buff *skb, 401 u8 type, u8 cat, u8 class, u8 func, 402 u32 len) 403 { 404 struct fwcmd_hdr *hdr; 405 406 hdr = (struct fwcmd_hdr *)skb_push(skb, 8); 407 408 hdr->hdr0 = cpu_to_le32(FIELD_PREP(H2C_HDR_DEL_TYPE, type) | 409 FIELD_PREP(H2C_HDR_CAT, cat) | 410 FIELD_PREP(H2C_HDR_CLASS, class) | 411 FIELD_PREP(H2C_HDR_FUNC, func) | 412 FIELD_PREP(H2C_HDR_H2C_SEQ, rtwdev->fw.h2c_seq)); 413 414 hdr->hdr1 = cpu_to_le32(FIELD_PREP(H2C_HDR_TOTAL_LEN, 415 len + H2C_HEADER_LEN)); 416 } 417 418 static int __rtw89_fw_download_hdr(struct rtw89_dev *rtwdev, const u8 *fw, u32 len) 419 { 420 struct sk_buff *skb; 421 u32 ret = 0; 422 423 skb = rtw89_fw_h2c_alloc_skb_with_hdr(rtwdev, len); 424 if (!skb) { 425 rtw89_err(rtwdev, "failed to alloc skb for fw hdr dl\n"); 426 return -ENOMEM; 427 } 428 429 skb_put_data(skb, fw, len); 430 SET_FW_HDR_PART_SIZE(skb->data, FWDL_SECTION_PER_PKT_LEN); 431 rtw89_h2c_pkt_set_hdr_fwdl(rtwdev, skb, FWCMD_TYPE_H2C, 432 H2C_CAT_MAC, H2C_CL_MAC_FWDL, 433 H2C_FUNC_MAC_FWHDR_DL, len); 434 435 ret = rtw89_h2c_tx(rtwdev, skb, false); 436 if (ret) { 437 rtw89_err(rtwdev, "failed to send h2c\n"); 438 ret = -1; 439 goto fail; 440 } 441 442 return 0; 443 fail: 444 dev_kfree_skb_any(skb); 445 446 return ret; 447 } 448 449 static int rtw89_fw_download_hdr(struct rtw89_dev *rtwdev, const u8 *fw, u32 len) 450 { 451 u8 val; 452 int ret; 453 454 ret = __rtw89_fw_download_hdr(rtwdev, fw, len); 455 if (ret) { 456 rtw89_err(rtwdev, "[ERR]FW header download\n"); 457 return ret; 458 } 459 460 ret = read_poll_timeout_atomic(rtw89_read8, val, val & B_AX_FWDL_PATH_RDY, 461 1, FWDL_WAIT_CNT, false, 462 rtwdev, R_AX_WCPU_FW_CTRL); 463 if (ret) { 464 rtw89_err(rtwdev, "[ERR]FWDL path ready\n"); 465 return ret; 466 } 467 468 rtw89_write32(rtwdev, R_AX_HALT_H2C_CTRL, 0); 469 rtw89_write32(rtwdev, R_AX_HALT_C2H_CTRL, 0); 470 471 return 0; 472 } 473 474 static int __rtw89_fw_download_main(struct rtw89_dev *rtwdev, 475 struct rtw89_fw_hdr_section_info *info) 476 { 477 struct sk_buff *skb; 478 const u8 *section = info->addr; 479 u32 residue_len = info->len; 480 u32 pkt_len; 481 int ret; 482 483 while (residue_len) { 484 if (residue_len >= FWDL_SECTION_PER_PKT_LEN) 485 pkt_len = FWDL_SECTION_PER_PKT_LEN; 486 else 487 pkt_len = residue_len; 488 489 skb = rtw89_fw_h2c_alloc_skb_no_hdr(rtwdev, pkt_len); 490 if (!skb) { 491 rtw89_err(rtwdev, "failed to alloc skb for fw dl\n"); 492 return -ENOMEM; 493 } 494 skb_put_data(skb, section, pkt_len); 495 496 ret = rtw89_h2c_tx(rtwdev, skb, true); 497 if (ret) { 498 rtw89_err(rtwdev, "failed to send h2c\n"); 499 ret = -1; 500 goto fail; 501 } 502 503 section += pkt_len; 504 residue_len -= pkt_len; 505 } 506 507 return 0; 508 fail: 509 dev_kfree_skb_any(skb); 510 511 return ret; 512 } 513 514 static int rtw89_fw_download_main(struct rtw89_dev *rtwdev, const u8 *fw, 515 struct rtw89_fw_bin_info *info) 516 { 517 struct rtw89_fw_hdr_section_info *section_info = info->section_info; 518 u8 section_num = info->section_num; 519 int ret; 520 521 while (section_num--) { 522 ret = __rtw89_fw_download_main(rtwdev, section_info); 523 if (ret) 524 return ret; 525 section_info++; 526 } 527 528 mdelay(5); 529 530 ret = rtw89_fw_check_rdy(rtwdev); 531 if (ret) { 532 rtw89_warn(rtwdev, "download firmware fail\n"); 533 return ret; 534 } 535 536 return 0; 537 } 538 539 static void rtw89_fw_prog_cnt_dump(struct rtw89_dev *rtwdev) 540 { 541 u32 val32; 542 u16 index; 543 544 rtw89_write32(rtwdev, R_AX_DBG_CTRL, 545 FIELD_PREP(B_AX_DBG_SEL0, FW_PROG_CNTR_DBG_SEL) | 546 FIELD_PREP(B_AX_DBG_SEL1, FW_PROG_CNTR_DBG_SEL)); 547 rtw89_write32_mask(rtwdev, R_AX_SYS_STATUS1, B_AX_SEL_0XC0_MASK, MAC_DBG_SEL); 548 549 for (index = 0; index < 15; index++) { 550 val32 = rtw89_read32(rtwdev, R_AX_DBG_PORT_SEL); 551 rtw89_err(rtwdev, "[ERR]fw PC = 0x%x\n", val32); 552 fsleep(10); 553 } 554 } 555 556 static void rtw89_fw_dl_fail_dump(struct rtw89_dev *rtwdev) 557 { 558 u32 val32; 559 u16 val16; 560 561 val32 = rtw89_read32(rtwdev, R_AX_WCPU_FW_CTRL); 562 rtw89_err(rtwdev, "[ERR]fwdl 0x1E0 = 0x%x\n", val32); 563 564 val16 = rtw89_read16(rtwdev, R_AX_BOOT_DBG + 2); 565 rtw89_err(rtwdev, "[ERR]fwdl 0x83F2 = 0x%x\n", val16); 566 567 rtw89_fw_prog_cnt_dump(rtwdev); 568 } 569 570 int rtw89_fw_download(struct rtw89_dev *rtwdev, enum rtw89_fw_type type) 571 { 572 struct rtw89_fw_info *fw_info = &rtwdev->fw; 573 struct rtw89_fw_suit *fw_suit = rtw89_fw_suit_get(rtwdev, type); 574 struct rtw89_fw_bin_info info; 575 const u8 *fw = fw_suit->data; 576 u32 len = fw_suit->size; 577 u8 val; 578 int ret; 579 580 rtw89_mac_disable_cpu(rtwdev); 581 ret = rtw89_mac_enable_cpu(rtwdev, 0, true); 582 if (ret) 583 return ret; 584 585 if (!fw || !len) { 586 rtw89_err(rtwdev, "fw type %d isn't recognized\n", type); 587 return -ENOENT; 588 } 589 590 ret = rtw89_fw_hdr_parser(rtwdev, fw, len, &info); 591 if (ret) { 592 rtw89_err(rtwdev, "parse fw header fail\n"); 593 goto fwdl_err; 594 } 595 596 ret = read_poll_timeout_atomic(rtw89_read8, val, val & B_AX_H2C_PATH_RDY, 597 1, FWDL_WAIT_CNT, false, 598 rtwdev, R_AX_WCPU_FW_CTRL); 599 if (ret) { 600 rtw89_err(rtwdev, "[ERR]H2C path ready\n"); 601 goto fwdl_err; 602 } 603 604 ret = rtw89_fw_download_hdr(rtwdev, fw, info.hdr_len - info.dynamic_hdr_len); 605 if (ret) { 606 ret = -EBUSY; 607 goto fwdl_err; 608 } 609 610 ret = rtw89_fw_download_main(rtwdev, fw, &info); 611 if (ret) { 612 ret = -EBUSY; 613 goto fwdl_err; 614 } 615 616 fw_info->h2c_seq = 0; 617 fw_info->rec_seq = 0; 618 fw_info->h2c_counter = 0; 619 fw_info->c2h_counter = 0; 620 rtwdev->mac.rpwm_seq_num = RPWM_SEQ_NUM_MAX; 621 rtwdev->mac.cpwm_seq_num = CPWM_SEQ_NUM_MAX; 622 623 return ret; 624 625 fwdl_err: 626 rtw89_fw_dl_fail_dump(rtwdev); 627 return ret; 628 } 629 630 int rtw89_wait_firmware_completion(struct rtw89_dev *rtwdev) 631 { 632 struct rtw89_fw_info *fw = &rtwdev->fw; 633 634 wait_for_completion(&fw->completion); 635 if (!fw->firmware) 636 return -EINVAL; 637 638 return 0; 639 } 640 641 static void rtw89_load_firmware_cb(const struct firmware *firmware, void *context) 642 { 643 struct rtw89_fw_info *fw = context; 644 struct rtw89_dev *rtwdev = fw->rtwdev; 645 646 if (!firmware || !firmware->data) { 647 rtw89_err(rtwdev, "failed to request firmware\n"); 648 complete_all(&fw->completion); 649 return; 650 } 651 652 fw->firmware = firmware; 653 complete_all(&fw->completion); 654 } 655 656 int rtw89_load_firmware(struct rtw89_dev *rtwdev) 657 { 658 struct rtw89_fw_info *fw = &rtwdev->fw; 659 const char *fw_name = rtwdev->chip->fw_name; 660 int ret; 661 662 fw->rtwdev = rtwdev; 663 init_completion(&fw->completion); 664 665 if (fw->firmware) { 666 rtw89_debug(rtwdev, RTW89_DBG_FW, 667 "full firmware has been early requested\n"); 668 complete_all(&fw->completion); 669 return 0; 670 } 671 672 ret = request_firmware_nowait(THIS_MODULE, true, fw_name, rtwdev->dev, 673 GFP_KERNEL, fw, rtw89_load_firmware_cb); 674 if (ret) { 675 rtw89_err(rtwdev, "failed to async firmware request\n"); 676 return ret; 677 } 678 679 return 0; 680 } 681 682 void rtw89_unload_firmware(struct rtw89_dev *rtwdev) 683 { 684 struct rtw89_fw_info *fw = &rtwdev->fw; 685 686 rtw89_wait_firmware_completion(rtwdev); 687 688 if (fw->firmware) { 689 release_firmware(fw->firmware); 690 691 /* assign NULL back in case rtw89_free_ieee80211_hw() 692 * try to release the same one again. 693 */ 694 fw->firmware = NULL; 695 } 696 } 697 698 #define H2C_CAM_LEN 60 699 int rtw89_fw_h2c_cam(struct rtw89_dev *rtwdev, struct rtw89_vif *rtwvif, 700 struct rtw89_sta *rtwsta, const u8 *scan_mac_addr) 701 { 702 struct sk_buff *skb; 703 int ret; 704 705 skb = rtw89_fw_h2c_alloc_skb_with_hdr(rtwdev, H2C_CAM_LEN); 706 if (!skb) { 707 rtw89_err(rtwdev, "failed to alloc skb for fw dl\n"); 708 return -ENOMEM; 709 } 710 skb_put(skb, H2C_CAM_LEN); 711 rtw89_cam_fill_addr_cam_info(rtwdev, rtwvif, rtwsta, scan_mac_addr, skb->data); 712 rtw89_cam_fill_bssid_cam_info(rtwdev, rtwvif, rtwsta, skb->data); 713 714 rtw89_h2c_pkt_set_hdr(rtwdev, skb, FWCMD_TYPE_H2C, 715 H2C_CAT_MAC, 716 H2C_CL_MAC_ADDR_CAM_UPDATE, 717 H2C_FUNC_MAC_ADDR_CAM_UPD, 0, 1, 718 H2C_CAM_LEN); 719 720 ret = rtw89_h2c_tx(rtwdev, skb, false); 721 if (ret) { 722 rtw89_err(rtwdev, "failed to send h2c\n"); 723 goto fail; 724 } 725 726 return 0; 727 fail: 728 dev_kfree_skb_any(skb); 729 730 return ret; 731 } 732 733 #define H2C_DCTL_SEC_CAM_LEN 68 734 int rtw89_fw_h2c_dctl_sec_cam_v1(struct rtw89_dev *rtwdev, 735 struct rtw89_vif *rtwvif, 736 struct rtw89_sta *rtwsta) 737 { 738 struct sk_buff *skb; 739 int ret; 740 741 skb = rtw89_fw_h2c_alloc_skb_with_hdr(rtwdev, H2C_DCTL_SEC_CAM_LEN); 742 if (!skb) { 743 rtw89_err(rtwdev, "failed to alloc skb for dctl sec cam\n"); 744 return -ENOMEM; 745 } 746 skb_put(skb, H2C_DCTL_SEC_CAM_LEN); 747 748 rtw89_cam_fill_dctl_sec_cam_info_v1(rtwdev, rtwvif, rtwsta, skb->data); 749 750 rtw89_h2c_pkt_set_hdr(rtwdev, skb, FWCMD_TYPE_H2C, 751 H2C_CAT_MAC, 752 H2C_CL_MAC_FR_EXCHG, 753 H2C_FUNC_MAC_DCTLINFO_UD_V1, 0, 0, 754 H2C_DCTL_SEC_CAM_LEN); 755 756 ret = rtw89_h2c_tx(rtwdev, skb, false); 757 if (ret) { 758 rtw89_err(rtwdev, "failed to send h2c\n"); 759 goto fail; 760 } 761 762 return 0; 763 fail: 764 dev_kfree_skb_any(skb); 765 766 return ret; 767 } 768 EXPORT_SYMBOL(rtw89_fw_h2c_dctl_sec_cam_v1); 769 770 #define H2C_BA_CAM_LEN 8 771 int rtw89_fw_h2c_ba_cam(struct rtw89_dev *rtwdev, struct rtw89_sta *rtwsta, 772 bool valid, struct ieee80211_ampdu_params *params) 773 { 774 const struct rtw89_chip_info *chip = rtwdev->chip; 775 struct rtw89_vif *rtwvif = rtwsta->rtwvif; 776 u8 macid = rtwsta->mac_id; 777 struct sk_buff *skb; 778 u8 entry_idx; 779 int ret; 780 781 ret = valid ? 782 rtw89_core_acquire_sta_ba_entry(rtwdev, rtwsta, params->tid, &entry_idx) : 783 rtw89_core_release_sta_ba_entry(rtwdev, rtwsta, params->tid, &entry_idx); 784 if (ret) { 785 /* it still works even if we don't have static BA CAM, because 786 * hardware can create dynamic BA CAM automatically. 787 */ 788 rtw89_debug(rtwdev, RTW89_DBG_TXRX, 789 "failed to %s entry tid=%d for h2c ba cam\n", 790 valid ? "alloc" : "free", params->tid); 791 return 0; 792 } 793 794 skb = rtw89_fw_h2c_alloc_skb_with_hdr(rtwdev, H2C_BA_CAM_LEN); 795 if (!skb) { 796 rtw89_err(rtwdev, "failed to alloc skb for h2c ba cam\n"); 797 return -ENOMEM; 798 } 799 skb_put(skb, H2C_BA_CAM_LEN); 800 SET_BA_CAM_MACID(skb->data, macid); 801 if (chip->bacam_v1) 802 SET_BA_CAM_ENTRY_IDX_V1(skb->data, entry_idx); 803 else 804 SET_BA_CAM_ENTRY_IDX(skb->data, entry_idx); 805 if (!valid) 806 goto end; 807 SET_BA_CAM_VALID(skb->data, valid); 808 SET_BA_CAM_TID(skb->data, params->tid); 809 if (params->buf_size > 64) 810 SET_BA_CAM_BMAP_SIZE(skb->data, 4); 811 else 812 SET_BA_CAM_BMAP_SIZE(skb->data, 0); 813 /* If init req is set, hw will set the ssn */ 814 SET_BA_CAM_INIT_REQ(skb->data, 1); 815 SET_BA_CAM_SSN(skb->data, params->ssn); 816 817 if (chip->bacam_v1) { 818 SET_BA_CAM_STD_EN(skb->data, 1); 819 SET_BA_CAM_BAND(skb->data, rtwvif->mac_idx); 820 } 821 822 end: 823 rtw89_h2c_pkt_set_hdr(rtwdev, skb, FWCMD_TYPE_H2C, 824 H2C_CAT_MAC, 825 H2C_CL_BA_CAM, 826 H2C_FUNC_MAC_BA_CAM, 0, 1, 827 H2C_BA_CAM_LEN); 828 829 ret = rtw89_h2c_tx(rtwdev, skb, false); 830 if (ret) { 831 rtw89_err(rtwdev, "failed to send h2c\n"); 832 goto fail; 833 } 834 835 return 0; 836 fail: 837 dev_kfree_skb_any(skb); 838 839 return ret; 840 } 841 842 static int rtw89_fw_h2c_init_dynamic_ba_cam_v1(struct rtw89_dev *rtwdev, 843 u8 entry_idx, u8 uid) 844 { 845 struct sk_buff *skb; 846 int ret; 847 848 skb = rtw89_fw_h2c_alloc_skb_with_hdr(rtwdev, H2C_BA_CAM_LEN); 849 if (!skb) { 850 rtw89_err(rtwdev, "failed to alloc skb for dynamic h2c ba cam\n"); 851 return -ENOMEM; 852 } 853 skb_put(skb, H2C_BA_CAM_LEN); 854 855 SET_BA_CAM_VALID(skb->data, 1); 856 SET_BA_CAM_ENTRY_IDX_V1(skb->data, entry_idx); 857 SET_BA_CAM_UID(skb->data, uid); 858 SET_BA_CAM_BAND(skb->data, 0); 859 SET_BA_CAM_STD_EN(skb->data, 0); 860 861 rtw89_h2c_pkt_set_hdr(rtwdev, skb, FWCMD_TYPE_H2C, 862 H2C_CAT_MAC, 863 H2C_CL_BA_CAM, 864 H2C_FUNC_MAC_BA_CAM, 0, 1, 865 H2C_BA_CAM_LEN); 866 867 ret = rtw89_h2c_tx(rtwdev, skb, false); 868 if (ret) { 869 rtw89_err(rtwdev, "failed to send h2c\n"); 870 goto fail; 871 } 872 873 return 0; 874 fail: 875 dev_kfree_skb_any(skb); 876 877 return ret; 878 } 879 880 void rtw89_fw_h2c_init_ba_cam_v1(struct rtw89_dev *rtwdev) 881 { 882 const struct rtw89_chip_info *chip = rtwdev->chip; 883 u8 entry_idx = chip->bacam_num; 884 u8 uid = 0; 885 int i; 886 887 for (i = 0; i < chip->bacam_dynamic_num; i++) { 888 rtw89_fw_h2c_init_dynamic_ba_cam_v1(rtwdev, entry_idx, uid); 889 entry_idx++; 890 uid++; 891 } 892 } 893 894 #define H2C_LOG_CFG_LEN 12 895 int rtw89_fw_h2c_fw_log(struct rtw89_dev *rtwdev, bool enable) 896 { 897 struct sk_buff *skb; 898 u32 comp = enable ? BIT(RTW89_FW_LOG_COMP_INIT) | BIT(RTW89_FW_LOG_COMP_TASK) | 899 BIT(RTW89_FW_LOG_COMP_PS) | BIT(RTW89_FW_LOG_COMP_ERROR) : 0; 900 int ret; 901 902 skb = rtw89_fw_h2c_alloc_skb_with_hdr(rtwdev, H2C_LOG_CFG_LEN); 903 if (!skb) { 904 rtw89_err(rtwdev, "failed to alloc skb for fw log cfg\n"); 905 return -ENOMEM; 906 } 907 908 skb_put(skb, H2C_LOG_CFG_LEN); 909 SET_LOG_CFG_LEVEL(skb->data, RTW89_FW_LOG_LEVEL_SER); 910 SET_LOG_CFG_PATH(skb->data, BIT(RTW89_FW_LOG_LEVEL_C2H)); 911 SET_LOG_CFG_COMP(skb->data, comp); 912 SET_LOG_CFG_COMP_EXT(skb->data, 0); 913 914 rtw89_h2c_pkt_set_hdr(rtwdev, skb, FWCMD_TYPE_H2C, 915 H2C_CAT_MAC, 916 H2C_CL_FW_INFO, 917 H2C_FUNC_LOG_CFG, 0, 0, 918 H2C_LOG_CFG_LEN); 919 920 ret = rtw89_h2c_tx(rtwdev, skb, false); 921 if (ret) { 922 rtw89_err(rtwdev, "failed to send h2c\n"); 923 goto fail; 924 } 925 926 return 0; 927 fail: 928 dev_kfree_skb_any(skb); 929 930 return ret; 931 } 932 933 static int rtw89_fw_h2c_add_general_pkt(struct rtw89_dev *rtwdev, 934 struct rtw89_vif *rtwvif, 935 enum rtw89_fw_pkt_ofld_type type, 936 u8 *id) 937 { 938 struct ieee80211_vif *vif = rtwvif_to_vif(rtwvif); 939 struct rtw89_pktofld_info *info; 940 struct sk_buff *skb; 941 int ret; 942 943 info = kzalloc(sizeof(*info), GFP_KERNEL); 944 if (!info) 945 return -ENOMEM; 946 947 switch (type) { 948 case RTW89_PKT_OFLD_TYPE_PS_POLL: 949 skb = ieee80211_pspoll_get(rtwdev->hw, vif); 950 break; 951 case RTW89_PKT_OFLD_TYPE_PROBE_RSP: 952 skb = ieee80211_proberesp_get(rtwdev->hw, vif); 953 break; 954 case RTW89_PKT_OFLD_TYPE_NULL_DATA: 955 skb = ieee80211_nullfunc_get(rtwdev->hw, vif, -1, false); 956 break; 957 case RTW89_PKT_OFLD_TYPE_QOS_NULL: 958 skb = ieee80211_nullfunc_get(rtwdev->hw, vif, -1, true); 959 break; 960 default: 961 goto err; 962 } 963 964 if (!skb) 965 goto err; 966 967 ret = rtw89_fw_h2c_add_pkt_offload(rtwdev, &info->id, skb); 968 kfree_skb(skb); 969 970 if (ret) 971 goto err; 972 973 list_add_tail(&info->list, &rtwvif->general_pkt_list); 974 *id = info->id; 975 return 0; 976 977 err: 978 kfree(info); 979 return -ENOMEM; 980 } 981 982 void rtw89_fw_release_general_pkt_list_vif(struct rtw89_dev *rtwdev, 983 struct rtw89_vif *rtwvif, bool notify_fw) 984 { 985 struct list_head *pkt_list = &rtwvif->general_pkt_list; 986 struct rtw89_pktofld_info *info, *tmp; 987 988 list_for_each_entry_safe(info, tmp, pkt_list, list) { 989 if (notify_fw) 990 rtw89_fw_h2c_del_pkt_offload(rtwdev, info->id); 991 rtw89_core_release_bit_map(rtwdev->pkt_offload, 992 info->id); 993 list_del(&info->list); 994 kfree(info); 995 } 996 } 997 998 void rtw89_fw_release_general_pkt_list(struct rtw89_dev *rtwdev, bool notify_fw) 999 { 1000 struct rtw89_vif *rtwvif; 1001 1002 rtw89_for_each_rtwvif(rtwdev, rtwvif) 1003 rtw89_fw_release_general_pkt_list_vif(rtwdev, rtwvif, notify_fw); 1004 } 1005 1006 #define H2C_GENERAL_PKT_LEN 6 1007 #define H2C_GENERAL_PKT_ID_UND 0xff 1008 int rtw89_fw_h2c_general_pkt(struct rtw89_dev *rtwdev, 1009 struct rtw89_vif *rtwvif, u8 macid) 1010 { 1011 u8 pkt_id_ps_poll = H2C_GENERAL_PKT_ID_UND; 1012 u8 pkt_id_null = H2C_GENERAL_PKT_ID_UND; 1013 u8 pkt_id_qos_null = H2C_GENERAL_PKT_ID_UND; 1014 struct sk_buff *skb; 1015 int ret; 1016 1017 rtw89_fw_h2c_add_general_pkt(rtwdev, rtwvif, 1018 RTW89_PKT_OFLD_TYPE_PS_POLL, &pkt_id_ps_poll); 1019 rtw89_fw_h2c_add_general_pkt(rtwdev, rtwvif, 1020 RTW89_PKT_OFLD_TYPE_NULL_DATA, &pkt_id_null); 1021 rtw89_fw_h2c_add_general_pkt(rtwdev, rtwvif, 1022 RTW89_PKT_OFLD_TYPE_QOS_NULL, &pkt_id_qos_null); 1023 1024 skb = rtw89_fw_h2c_alloc_skb_with_hdr(rtwdev, H2C_GENERAL_PKT_LEN); 1025 if (!skb) { 1026 rtw89_err(rtwdev, "failed to alloc skb for fw dl\n"); 1027 return -ENOMEM; 1028 } 1029 skb_put(skb, H2C_GENERAL_PKT_LEN); 1030 SET_GENERAL_PKT_MACID(skb->data, macid); 1031 SET_GENERAL_PKT_PROBRSP_ID(skb->data, H2C_GENERAL_PKT_ID_UND); 1032 SET_GENERAL_PKT_PSPOLL_ID(skb->data, pkt_id_ps_poll); 1033 SET_GENERAL_PKT_NULL_ID(skb->data, pkt_id_null); 1034 SET_GENERAL_PKT_QOS_NULL_ID(skb->data, pkt_id_qos_null); 1035 SET_GENERAL_PKT_CTS2SELF_ID(skb->data, H2C_GENERAL_PKT_ID_UND); 1036 1037 rtw89_h2c_pkt_set_hdr(rtwdev, skb, FWCMD_TYPE_H2C, 1038 H2C_CAT_MAC, 1039 H2C_CL_FW_INFO, 1040 H2C_FUNC_MAC_GENERAL_PKT, 0, 1, 1041 H2C_GENERAL_PKT_LEN); 1042 1043 ret = rtw89_h2c_tx(rtwdev, skb, false); 1044 if (ret) { 1045 rtw89_err(rtwdev, "failed to send h2c\n"); 1046 goto fail; 1047 } 1048 1049 return 0; 1050 fail: 1051 dev_kfree_skb_any(skb); 1052 1053 return ret; 1054 } 1055 1056 #define H2C_LPS_PARM_LEN 8 1057 int rtw89_fw_h2c_lps_parm(struct rtw89_dev *rtwdev, 1058 struct rtw89_lps_parm *lps_param) 1059 { 1060 struct sk_buff *skb; 1061 int ret; 1062 1063 skb = rtw89_fw_h2c_alloc_skb_with_hdr(rtwdev, H2C_LPS_PARM_LEN); 1064 if (!skb) { 1065 rtw89_err(rtwdev, "failed to alloc skb for fw dl\n"); 1066 return -ENOMEM; 1067 } 1068 skb_put(skb, H2C_LPS_PARM_LEN); 1069 1070 SET_LPS_PARM_MACID(skb->data, lps_param->macid); 1071 SET_LPS_PARM_PSMODE(skb->data, lps_param->psmode); 1072 SET_LPS_PARM_LASTRPWM(skb->data, lps_param->lastrpwm); 1073 SET_LPS_PARM_RLBM(skb->data, 1); 1074 SET_LPS_PARM_SMARTPS(skb->data, 1); 1075 SET_LPS_PARM_AWAKEINTERVAL(skb->data, 1); 1076 SET_LPS_PARM_VOUAPSD(skb->data, 0); 1077 SET_LPS_PARM_VIUAPSD(skb->data, 0); 1078 SET_LPS_PARM_BEUAPSD(skb->data, 0); 1079 SET_LPS_PARM_BKUAPSD(skb->data, 0); 1080 1081 rtw89_h2c_pkt_set_hdr(rtwdev, skb, FWCMD_TYPE_H2C, 1082 H2C_CAT_MAC, 1083 H2C_CL_MAC_PS, 1084 H2C_FUNC_MAC_LPS_PARM, 0, 1, 1085 H2C_LPS_PARM_LEN); 1086 1087 ret = rtw89_h2c_tx(rtwdev, skb, false); 1088 if (ret) { 1089 rtw89_err(rtwdev, "failed to send h2c\n"); 1090 goto fail; 1091 } 1092 1093 return 0; 1094 fail: 1095 dev_kfree_skb_any(skb); 1096 1097 return ret; 1098 } 1099 1100 #define H2C_P2P_ACT_LEN 20 1101 int rtw89_fw_h2c_p2p_act(struct rtw89_dev *rtwdev, struct ieee80211_vif *vif, 1102 struct ieee80211_p2p_noa_desc *desc, 1103 u8 act, u8 noa_id) 1104 { 1105 struct rtw89_vif *rtwvif = (struct rtw89_vif *)vif->drv_priv; 1106 bool p2p_type_gc = rtwvif->wifi_role == RTW89_WIFI_ROLE_P2P_CLIENT; 1107 u8 ctwindow_oppps = vif->bss_conf.p2p_noa_attr.oppps_ctwindow; 1108 struct sk_buff *skb; 1109 u8 *cmd; 1110 int ret; 1111 1112 skb = rtw89_fw_h2c_alloc_skb_with_hdr(rtwdev, H2C_P2P_ACT_LEN); 1113 if (!skb) { 1114 rtw89_err(rtwdev, "failed to alloc skb for h2c p2p act\n"); 1115 return -ENOMEM; 1116 } 1117 skb_put(skb, H2C_P2P_ACT_LEN); 1118 cmd = skb->data; 1119 1120 RTW89_SET_FWCMD_P2P_MACID(cmd, rtwvif->mac_id); 1121 RTW89_SET_FWCMD_P2P_P2PID(cmd, 0); 1122 RTW89_SET_FWCMD_P2P_NOAID(cmd, noa_id); 1123 RTW89_SET_FWCMD_P2P_ACT(cmd, act); 1124 RTW89_SET_FWCMD_P2P_TYPE(cmd, p2p_type_gc); 1125 RTW89_SET_FWCMD_P2P_ALL_SLEP(cmd, 0); 1126 if (desc) { 1127 RTW89_SET_FWCMD_NOA_START_TIME(cmd, desc->start_time); 1128 RTW89_SET_FWCMD_NOA_INTERVAL(cmd, desc->interval); 1129 RTW89_SET_FWCMD_NOA_DURATION(cmd, desc->duration); 1130 RTW89_SET_FWCMD_NOA_COUNT(cmd, desc->count); 1131 RTW89_SET_FWCMD_NOA_CTWINDOW(cmd, ctwindow_oppps); 1132 } 1133 1134 rtw89_h2c_pkt_set_hdr(rtwdev, skb, FWCMD_TYPE_H2C, 1135 H2C_CAT_MAC, H2C_CL_MAC_PS, 1136 H2C_FUNC_P2P_ACT, 0, 0, 1137 H2C_P2P_ACT_LEN); 1138 1139 ret = rtw89_h2c_tx(rtwdev, skb, false); 1140 if (ret) { 1141 rtw89_err(rtwdev, "failed to send h2c\n"); 1142 goto fail; 1143 } 1144 1145 return 0; 1146 fail: 1147 dev_kfree_skb_any(skb); 1148 1149 return ret; 1150 } 1151 1152 static void __rtw89_fw_h2c_set_tx_path(struct rtw89_dev *rtwdev, 1153 struct sk_buff *skb) 1154 { 1155 struct rtw89_hal *hal = &rtwdev->hal; 1156 u8 ntx_path = hal->antenna_tx ? hal->antenna_tx : RF_B; 1157 u8 map_b = hal->antenna_tx == RF_AB ? 1 : 0; 1158 1159 SET_CMC_TBL_NTX_PATH_EN(skb->data, ntx_path); 1160 SET_CMC_TBL_PATH_MAP_A(skb->data, 0); 1161 SET_CMC_TBL_PATH_MAP_B(skb->data, map_b); 1162 SET_CMC_TBL_PATH_MAP_C(skb->data, 0); 1163 SET_CMC_TBL_PATH_MAP_D(skb->data, 0); 1164 } 1165 1166 #define H2C_CMC_TBL_LEN 68 1167 int rtw89_fw_h2c_default_cmac_tbl(struct rtw89_dev *rtwdev, 1168 struct rtw89_vif *rtwvif) 1169 { 1170 const struct rtw89_chip_info *chip = rtwdev->chip; 1171 struct sk_buff *skb; 1172 u8 macid = rtwvif->mac_id; 1173 int ret; 1174 1175 skb = rtw89_fw_h2c_alloc_skb_with_hdr(rtwdev, H2C_CMC_TBL_LEN); 1176 if (!skb) { 1177 rtw89_err(rtwdev, "failed to alloc skb for fw dl\n"); 1178 return -ENOMEM; 1179 } 1180 skb_put(skb, H2C_CMC_TBL_LEN); 1181 SET_CTRL_INFO_MACID(skb->data, macid); 1182 SET_CTRL_INFO_OPERATION(skb->data, 1); 1183 if (chip->h2c_cctl_func_id == H2C_FUNC_MAC_CCTLINFO_UD) { 1184 SET_CMC_TBL_TXPWR_MODE(skb->data, 0); 1185 __rtw89_fw_h2c_set_tx_path(rtwdev, skb); 1186 SET_CMC_TBL_ANTSEL_A(skb->data, 0); 1187 SET_CMC_TBL_ANTSEL_B(skb->data, 0); 1188 SET_CMC_TBL_ANTSEL_C(skb->data, 0); 1189 SET_CMC_TBL_ANTSEL_D(skb->data, 0); 1190 } 1191 SET_CMC_TBL_DOPPLER_CTRL(skb->data, 0); 1192 SET_CMC_TBL_TXPWR_TOLERENCE(skb->data, 0); 1193 if (rtwvif->net_type == RTW89_NET_TYPE_AP_MODE) 1194 SET_CMC_TBL_DATA_DCM(skb->data, 0); 1195 1196 rtw89_h2c_pkt_set_hdr(rtwdev, skb, FWCMD_TYPE_H2C, 1197 H2C_CAT_MAC, H2C_CL_MAC_FR_EXCHG, 1198 chip->h2c_cctl_func_id, 0, 1, 1199 H2C_CMC_TBL_LEN); 1200 1201 ret = rtw89_h2c_tx(rtwdev, skb, false); 1202 if (ret) { 1203 rtw89_err(rtwdev, "failed to send h2c\n"); 1204 goto fail; 1205 } 1206 1207 return 0; 1208 fail: 1209 dev_kfree_skb_any(skb); 1210 1211 return ret; 1212 } 1213 1214 static void __get_sta_he_pkt_padding(struct rtw89_dev *rtwdev, 1215 struct ieee80211_sta *sta, u8 *pads) 1216 { 1217 bool ppe_th; 1218 u8 ppe16, ppe8; 1219 u8 nss = min(sta->deflink.rx_nss, rtwdev->hal.tx_nss) - 1; 1220 u8 ppe_thres_hdr = sta->deflink.he_cap.ppe_thres[0]; 1221 u8 ru_bitmap; 1222 u8 n, idx, sh; 1223 u16 ppe; 1224 int i; 1225 1226 if (!sta->deflink.he_cap.has_he) 1227 return; 1228 1229 ppe_th = FIELD_GET(IEEE80211_HE_PHY_CAP6_PPE_THRESHOLD_PRESENT, 1230 sta->deflink.he_cap.he_cap_elem.phy_cap_info[6]); 1231 if (!ppe_th) { 1232 u8 pad; 1233 1234 pad = FIELD_GET(IEEE80211_HE_PHY_CAP9_NOMINAL_PKT_PADDING_MASK, 1235 sta->deflink.he_cap.he_cap_elem.phy_cap_info[9]); 1236 1237 for (i = 0; i < RTW89_PPE_BW_NUM; i++) 1238 pads[i] = pad; 1239 1240 return; 1241 } 1242 1243 ru_bitmap = FIELD_GET(IEEE80211_PPE_THRES_RU_INDEX_BITMASK_MASK, ppe_thres_hdr); 1244 n = hweight8(ru_bitmap); 1245 n = 7 + (n * IEEE80211_PPE_THRES_INFO_PPET_SIZE * 2) * nss; 1246 1247 for (i = 0; i < RTW89_PPE_BW_NUM; i++) { 1248 if (!(ru_bitmap & BIT(i))) { 1249 pads[i] = 1; 1250 continue; 1251 } 1252 1253 idx = n >> 3; 1254 sh = n & 7; 1255 n += IEEE80211_PPE_THRES_INFO_PPET_SIZE * 2; 1256 1257 ppe = le16_to_cpu(*((__le16 *)&sta->deflink.he_cap.ppe_thres[idx])); 1258 ppe16 = (ppe >> sh) & IEEE80211_PPE_THRES_NSS_MASK; 1259 sh += IEEE80211_PPE_THRES_INFO_PPET_SIZE; 1260 ppe8 = (ppe >> sh) & IEEE80211_PPE_THRES_NSS_MASK; 1261 1262 if (ppe16 != 7 && ppe8 == 7) 1263 pads[i] = 2; 1264 else if (ppe8 != 7) 1265 pads[i] = 1; 1266 else 1267 pads[i] = 0; 1268 } 1269 } 1270 1271 int rtw89_fw_h2c_assoc_cmac_tbl(struct rtw89_dev *rtwdev, 1272 struct ieee80211_vif *vif, 1273 struct ieee80211_sta *sta) 1274 { 1275 const struct rtw89_chip_info *chip = rtwdev->chip; 1276 struct rtw89_sta *rtwsta = sta_to_rtwsta_safe(sta); 1277 struct rtw89_vif *rtwvif = (struct rtw89_vif *)vif->drv_priv; 1278 const struct rtw89_chan *chan = rtw89_chan_get(rtwdev, RTW89_SUB_ENTITY_0); 1279 struct sk_buff *skb; 1280 u8 pads[RTW89_PPE_BW_NUM]; 1281 u8 mac_id = rtwsta ? rtwsta->mac_id : rtwvif->mac_id; 1282 u16 lowest_rate; 1283 int ret; 1284 1285 memset(pads, 0, sizeof(pads)); 1286 if (sta) 1287 __get_sta_he_pkt_padding(rtwdev, sta, pads); 1288 1289 if (vif->p2p) 1290 lowest_rate = RTW89_HW_RATE_OFDM6; 1291 else if (chan->band_type == RTW89_BAND_2G) 1292 lowest_rate = RTW89_HW_RATE_CCK1; 1293 else 1294 lowest_rate = RTW89_HW_RATE_OFDM6; 1295 1296 skb = rtw89_fw_h2c_alloc_skb_with_hdr(rtwdev, H2C_CMC_TBL_LEN); 1297 if (!skb) { 1298 rtw89_err(rtwdev, "failed to alloc skb for fw dl\n"); 1299 return -ENOMEM; 1300 } 1301 skb_put(skb, H2C_CMC_TBL_LEN); 1302 SET_CTRL_INFO_MACID(skb->data, mac_id); 1303 SET_CTRL_INFO_OPERATION(skb->data, 1); 1304 SET_CMC_TBL_DISRTSFB(skb->data, 1); 1305 SET_CMC_TBL_DISDATAFB(skb->data, 1); 1306 SET_CMC_TBL_RTS_RTY_LOWEST_RATE(skb->data, lowest_rate); 1307 SET_CMC_TBL_RTS_TXCNT_LMT_SEL(skb->data, 0); 1308 SET_CMC_TBL_DATA_TXCNT_LMT_SEL(skb->data, 0); 1309 if (vif->type == NL80211_IFTYPE_STATION) 1310 SET_CMC_TBL_ULDL(skb->data, 1); 1311 else 1312 SET_CMC_TBL_ULDL(skb->data, 0); 1313 SET_CMC_TBL_MULTI_PORT_ID(skb->data, rtwvif->port); 1314 if (chip->h2c_cctl_func_id == H2C_FUNC_MAC_CCTLINFO_UD_V1) { 1315 SET_CMC_TBL_NOMINAL_PKT_PADDING_V1(skb->data, pads[RTW89_CHANNEL_WIDTH_20]); 1316 SET_CMC_TBL_NOMINAL_PKT_PADDING40_V1(skb->data, pads[RTW89_CHANNEL_WIDTH_40]); 1317 SET_CMC_TBL_NOMINAL_PKT_PADDING80_V1(skb->data, pads[RTW89_CHANNEL_WIDTH_80]); 1318 SET_CMC_TBL_NOMINAL_PKT_PADDING160_V1(skb->data, pads[RTW89_CHANNEL_WIDTH_160]); 1319 } else if (chip->h2c_cctl_func_id == H2C_FUNC_MAC_CCTLINFO_UD) { 1320 SET_CMC_TBL_NOMINAL_PKT_PADDING(skb->data, pads[RTW89_CHANNEL_WIDTH_20]); 1321 SET_CMC_TBL_NOMINAL_PKT_PADDING40(skb->data, pads[RTW89_CHANNEL_WIDTH_40]); 1322 SET_CMC_TBL_NOMINAL_PKT_PADDING80(skb->data, pads[RTW89_CHANNEL_WIDTH_80]); 1323 SET_CMC_TBL_NOMINAL_PKT_PADDING160(skb->data, pads[RTW89_CHANNEL_WIDTH_160]); 1324 } 1325 if (sta) 1326 SET_CMC_TBL_BSR_QUEUE_SIZE_FORMAT(skb->data, 1327 sta->deflink.he_cap.has_he); 1328 if (rtwvif->net_type == RTW89_NET_TYPE_AP_MODE) 1329 SET_CMC_TBL_DATA_DCM(skb->data, 0); 1330 1331 rtw89_h2c_pkt_set_hdr(rtwdev, skb, FWCMD_TYPE_H2C, 1332 H2C_CAT_MAC, H2C_CL_MAC_FR_EXCHG, 1333 chip->h2c_cctl_func_id, 0, 1, 1334 H2C_CMC_TBL_LEN); 1335 1336 ret = rtw89_h2c_tx(rtwdev, skb, false); 1337 if (ret) { 1338 rtw89_err(rtwdev, "failed to send h2c\n"); 1339 goto fail; 1340 } 1341 1342 return 0; 1343 fail: 1344 dev_kfree_skb_any(skb); 1345 1346 return ret; 1347 } 1348 1349 int rtw89_fw_h2c_txtime_cmac_tbl(struct rtw89_dev *rtwdev, 1350 struct rtw89_sta *rtwsta) 1351 { 1352 const struct rtw89_chip_info *chip = rtwdev->chip; 1353 struct sk_buff *skb; 1354 int ret; 1355 1356 skb = rtw89_fw_h2c_alloc_skb_with_hdr(rtwdev, H2C_CMC_TBL_LEN); 1357 if (!skb) { 1358 rtw89_err(rtwdev, "failed to alloc skb for fw dl\n"); 1359 return -ENOMEM; 1360 } 1361 skb_put(skb, H2C_CMC_TBL_LEN); 1362 SET_CTRL_INFO_MACID(skb->data, rtwsta->mac_id); 1363 SET_CTRL_INFO_OPERATION(skb->data, 1); 1364 if (rtwsta->cctl_tx_time) { 1365 SET_CMC_TBL_AMPDU_TIME_SEL(skb->data, 1); 1366 SET_CMC_TBL_AMPDU_MAX_TIME(skb->data, rtwsta->ampdu_max_time); 1367 } 1368 if (rtwsta->cctl_tx_retry_limit) { 1369 SET_CMC_TBL_DATA_TXCNT_LMT_SEL(skb->data, 1); 1370 SET_CMC_TBL_DATA_TX_CNT_LMT(skb->data, rtwsta->data_tx_cnt_lmt); 1371 } 1372 1373 rtw89_h2c_pkt_set_hdr(rtwdev, skb, FWCMD_TYPE_H2C, 1374 H2C_CAT_MAC, H2C_CL_MAC_FR_EXCHG, 1375 chip->h2c_cctl_func_id, 0, 1, 1376 H2C_CMC_TBL_LEN); 1377 1378 ret = rtw89_h2c_tx(rtwdev, skb, false); 1379 if (ret) { 1380 rtw89_err(rtwdev, "failed to send h2c\n"); 1381 goto fail; 1382 } 1383 1384 return 0; 1385 fail: 1386 dev_kfree_skb_any(skb); 1387 1388 return ret; 1389 } 1390 1391 int rtw89_fw_h2c_txpath_cmac_tbl(struct rtw89_dev *rtwdev, 1392 struct rtw89_sta *rtwsta) 1393 { 1394 const struct rtw89_chip_info *chip = rtwdev->chip; 1395 struct sk_buff *skb; 1396 int ret; 1397 1398 if (chip->h2c_cctl_func_id != H2C_FUNC_MAC_CCTLINFO_UD) 1399 return 0; 1400 1401 skb = rtw89_fw_h2c_alloc_skb_with_hdr(rtwdev, H2C_CMC_TBL_LEN); 1402 if (!skb) { 1403 rtw89_err(rtwdev, "failed to alloc skb for fw dl\n"); 1404 return -ENOMEM; 1405 } 1406 skb_put(skb, H2C_CMC_TBL_LEN); 1407 SET_CTRL_INFO_MACID(skb->data, rtwsta->mac_id); 1408 SET_CTRL_INFO_OPERATION(skb->data, 1); 1409 1410 __rtw89_fw_h2c_set_tx_path(rtwdev, skb); 1411 1412 rtw89_h2c_pkt_set_hdr(rtwdev, skb, FWCMD_TYPE_H2C, 1413 H2C_CAT_MAC, H2C_CL_MAC_FR_EXCHG, 1414 H2C_FUNC_MAC_CCTLINFO_UD, 0, 1, 1415 H2C_CMC_TBL_LEN); 1416 1417 ret = rtw89_h2c_tx(rtwdev, skb, false); 1418 if (ret) { 1419 rtw89_err(rtwdev, "failed to send h2c\n"); 1420 goto fail; 1421 } 1422 1423 return 0; 1424 fail: 1425 dev_kfree_skb_any(skb); 1426 1427 return ret; 1428 } 1429 1430 #define H2C_BCN_BASE_LEN 12 1431 int rtw89_fw_h2c_update_beacon(struct rtw89_dev *rtwdev, 1432 struct rtw89_vif *rtwvif) 1433 { 1434 struct ieee80211_vif *vif = rtwvif_to_vif(rtwvif); 1435 const struct rtw89_chan *chan = rtw89_chan_get(rtwdev, RTW89_SUB_ENTITY_0); 1436 struct sk_buff *skb; 1437 struct sk_buff *skb_beacon; 1438 u16 tim_offset; 1439 int bcn_total_len; 1440 u16 beacon_rate; 1441 int ret; 1442 1443 if (vif->p2p) 1444 beacon_rate = RTW89_HW_RATE_OFDM6; 1445 else if (chan->band_type == RTW89_BAND_2G) 1446 beacon_rate = RTW89_HW_RATE_CCK1; 1447 else 1448 beacon_rate = RTW89_HW_RATE_OFDM6; 1449 1450 skb_beacon = ieee80211_beacon_get_tim(rtwdev->hw, vif, &tim_offset, 1451 NULL, 0); 1452 if (!skb_beacon) { 1453 rtw89_err(rtwdev, "failed to get beacon skb\n"); 1454 return -ENOMEM; 1455 } 1456 1457 bcn_total_len = H2C_BCN_BASE_LEN + skb_beacon->len; 1458 skb = rtw89_fw_h2c_alloc_skb_with_hdr(rtwdev, bcn_total_len); 1459 if (!skb) { 1460 rtw89_err(rtwdev, "failed to alloc skb for fw dl\n"); 1461 dev_kfree_skb_any(skb_beacon); 1462 return -ENOMEM; 1463 } 1464 skb_put(skb, H2C_BCN_BASE_LEN); 1465 1466 SET_BCN_UPD_PORT(skb->data, rtwvif->port); 1467 SET_BCN_UPD_MBSSID(skb->data, 0); 1468 SET_BCN_UPD_BAND(skb->data, rtwvif->mac_idx); 1469 SET_BCN_UPD_GRP_IE_OFST(skb->data, tim_offset); 1470 SET_BCN_UPD_MACID(skb->data, rtwvif->mac_id); 1471 SET_BCN_UPD_SSN_SEL(skb->data, RTW89_MGMT_HW_SSN_SEL); 1472 SET_BCN_UPD_SSN_MODE(skb->data, RTW89_MGMT_HW_SEQ_MODE); 1473 SET_BCN_UPD_RATE(skb->data, beacon_rate); 1474 1475 skb_put_data(skb, skb_beacon->data, skb_beacon->len); 1476 dev_kfree_skb_any(skb_beacon); 1477 1478 rtw89_h2c_pkt_set_hdr(rtwdev, skb, FWCMD_TYPE_H2C, 1479 H2C_CAT_MAC, H2C_CL_MAC_FR_EXCHG, 1480 H2C_FUNC_MAC_BCN_UPD, 0, 1, 1481 bcn_total_len); 1482 1483 ret = rtw89_h2c_tx(rtwdev, skb, false); 1484 if (ret) { 1485 rtw89_err(rtwdev, "failed to send h2c\n"); 1486 dev_kfree_skb_any(skb); 1487 return ret; 1488 } 1489 1490 return 0; 1491 } 1492 1493 #define H2C_ROLE_MAINTAIN_LEN 4 1494 int rtw89_fw_h2c_role_maintain(struct rtw89_dev *rtwdev, 1495 struct rtw89_vif *rtwvif, 1496 struct rtw89_sta *rtwsta, 1497 enum rtw89_upd_mode upd_mode) 1498 { 1499 struct sk_buff *skb; 1500 u8 mac_id = rtwsta ? rtwsta->mac_id : rtwvif->mac_id; 1501 u8 self_role; 1502 int ret; 1503 1504 if (rtwvif->net_type == RTW89_NET_TYPE_AP_MODE) { 1505 if (rtwsta) 1506 self_role = RTW89_SELF_ROLE_AP_CLIENT; 1507 else 1508 self_role = rtwvif->self_role; 1509 } else { 1510 self_role = rtwvif->self_role; 1511 } 1512 1513 skb = rtw89_fw_h2c_alloc_skb_with_hdr(rtwdev, H2C_ROLE_MAINTAIN_LEN); 1514 if (!skb) { 1515 rtw89_err(rtwdev, "failed to alloc skb for h2c join\n"); 1516 return -ENOMEM; 1517 } 1518 skb_put(skb, H2C_ROLE_MAINTAIN_LEN); 1519 SET_FWROLE_MAINTAIN_MACID(skb->data, mac_id); 1520 SET_FWROLE_MAINTAIN_SELF_ROLE(skb->data, self_role); 1521 SET_FWROLE_MAINTAIN_UPD_MODE(skb->data, upd_mode); 1522 SET_FWROLE_MAINTAIN_WIFI_ROLE(skb->data, rtwvif->wifi_role); 1523 1524 rtw89_h2c_pkt_set_hdr(rtwdev, skb, FWCMD_TYPE_H2C, 1525 H2C_CAT_MAC, H2C_CL_MAC_MEDIA_RPT, 1526 H2C_FUNC_MAC_FWROLE_MAINTAIN, 0, 1, 1527 H2C_ROLE_MAINTAIN_LEN); 1528 1529 ret = rtw89_h2c_tx(rtwdev, skb, false); 1530 if (ret) { 1531 rtw89_err(rtwdev, "failed to send h2c\n"); 1532 goto fail; 1533 } 1534 1535 return 0; 1536 fail: 1537 dev_kfree_skb_any(skb); 1538 1539 return ret; 1540 } 1541 1542 #define H2C_JOIN_INFO_LEN 4 1543 int rtw89_fw_h2c_join_info(struct rtw89_dev *rtwdev, struct rtw89_vif *rtwvif, 1544 struct rtw89_sta *rtwsta, bool dis_conn) 1545 { 1546 struct sk_buff *skb; 1547 u8 mac_id = rtwsta ? rtwsta->mac_id : rtwvif->mac_id; 1548 u8 self_role = rtwvif->self_role; 1549 u8 net_type = rtwvif->net_type; 1550 int ret; 1551 1552 if (net_type == RTW89_NET_TYPE_AP_MODE && rtwsta) { 1553 self_role = RTW89_SELF_ROLE_AP_CLIENT; 1554 net_type = dis_conn ? RTW89_NET_TYPE_NO_LINK : net_type; 1555 } 1556 1557 skb = rtw89_fw_h2c_alloc_skb_with_hdr(rtwdev, H2C_JOIN_INFO_LEN); 1558 if (!skb) { 1559 rtw89_err(rtwdev, "failed to alloc skb for h2c join\n"); 1560 return -ENOMEM; 1561 } 1562 skb_put(skb, H2C_JOIN_INFO_LEN); 1563 SET_JOININFO_MACID(skb->data, mac_id); 1564 SET_JOININFO_OP(skb->data, dis_conn); 1565 SET_JOININFO_BAND(skb->data, rtwvif->mac_idx); 1566 SET_JOININFO_WMM(skb->data, rtwvif->wmm); 1567 SET_JOININFO_TGR(skb->data, rtwvif->trigger); 1568 SET_JOININFO_ISHESTA(skb->data, 0); 1569 SET_JOININFO_DLBW(skb->data, 0); 1570 SET_JOININFO_TF_MAC_PAD(skb->data, 0); 1571 SET_JOININFO_DL_T_PE(skb->data, 0); 1572 SET_JOININFO_PORT_ID(skb->data, rtwvif->port); 1573 SET_JOININFO_NET_TYPE(skb->data, net_type); 1574 SET_JOININFO_WIFI_ROLE(skb->data, rtwvif->wifi_role); 1575 SET_JOININFO_SELF_ROLE(skb->data, self_role); 1576 1577 rtw89_h2c_pkt_set_hdr(rtwdev, skb, FWCMD_TYPE_H2C, 1578 H2C_CAT_MAC, H2C_CL_MAC_MEDIA_RPT, 1579 H2C_FUNC_MAC_JOININFO, 0, 1, 1580 H2C_JOIN_INFO_LEN); 1581 1582 ret = rtw89_h2c_tx(rtwdev, skb, false); 1583 if (ret) { 1584 rtw89_err(rtwdev, "failed to send h2c\n"); 1585 goto fail; 1586 } 1587 1588 return 0; 1589 fail: 1590 dev_kfree_skb_any(skb); 1591 1592 return ret; 1593 } 1594 1595 int rtw89_fw_h2c_macid_pause(struct rtw89_dev *rtwdev, u8 sh, u8 grp, 1596 bool pause) 1597 { 1598 struct rtw89_fw_macid_pause_grp h2c = {{0}}; 1599 u8 len = sizeof(struct rtw89_fw_macid_pause_grp); 1600 struct sk_buff *skb; 1601 int ret; 1602 1603 skb = rtw89_fw_h2c_alloc_skb_with_hdr(rtwdev, H2C_JOIN_INFO_LEN); 1604 if (!skb) { 1605 rtw89_err(rtwdev, "failed to alloc skb for h2c join\n"); 1606 return -ENOMEM; 1607 } 1608 h2c.mask_grp[grp] = cpu_to_le32(BIT(sh)); 1609 if (pause) 1610 h2c.pause_grp[grp] = cpu_to_le32(BIT(sh)); 1611 skb_put_data(skb, &h2c, len); 1612 1613 rtw89_h2c_pkt_set_hdr(rtwdev, skb, FWCMD_TYPE_H2C, 1614 H2C_CAT_MAC, H2C_CL_MAC_FW_OFLD, 1615 H2C_FUNC_MAC_MACID_PAUSE, 1, 0, 1616 len); 1617 1618 ret = rtw89_h2c_tx(rtwdev, skb, false); 1619 if (ret) { 1620 rtw89_err(rtwdev, "failed to send h2c\n"); 1621 goto fail; 1622 } 1623 1624 return 0; 1625 fail: 1626 dev_kfree_skb_any(skb); 1627 1628 return ret; 1629 } 1630 1631 #define H2C_EDCA_LEN 12 1632 int rtw89_fw_h2c_set_edca(struct rtw89_dev *rtwdev, struct rtw89_vif *rtwvif, 1633 u8 ac, u32 val) 1634 { 1635 struct sk_buff *skb; 1636 int ret; 1637 1638 skb = rtw89_fw_h2c_alloc_skb_with_hdr(rtwdev, H2C_EDCA_LEN); 1639 if (!skb) { 1640 rtw89_err(rtwdev, "failed to alloc skb for h2c edca\n"); 1641 return -ENOMEM; 1642 } 1643 skb_put(skb, H2C_EDCA_LEN); 1644 RTW89_SET_EDCA_SEL(skb->data, 0); 1645 RTW89_SET_EDCA_BAND(skb->data, rtwvif->mac_idx); 1646 RTW89_SET_EDCA_WMM(skb->data, 0); 1647 RTW89_SET_EDCA_AC(skb->data, ac); 1648 RTW89_SET_EDCA_PARAM(skb->data, val); 1649 1650 rtw89_h2c_pkt_set_hdr(rtwdev, skb, FWCMD_TYPE_H2C, 1651 H2C_CAT_MAC, H2C_CL_MAC_FW_OFLD, 1652 H2C_FUNC_USR_EDCA, 0, 1, 1653 H2C_EDCA_LEN); 1654 1655 ret = rtw89_h2c_tx(rtwdev, skb, false); 1656 if (ret) { 1657 rtw89_err(rtwdev, "failed to send h2c\n"); 1658 goto fail; 1659 } 1660 1661 return 0; 1662 fail: 1663 dev_kfree_skb_any(skb); 1664 1665 return ret; 1666 } 1667 1668 #define H2C_TSF32_TOGL_LEN 4 1669 int rtw89_fw_h2c_tsf32_toggle(struct rtw89_dev *rtwdev, struct rtw89_vif *rtwvif, 1670 bool en) 1671 { 1672 struct sk_buff *skb; 1673 u16 early_us = en ? 2000 : 0; 1674 u8 *cmd; 1675 int ret; 1676 1677 skb = rtw89_fw_h2c_alloc_skb_with_hdr(rtwdev, H2C_TSF32_TOGL_LEN); 1678 if (!skb) { 1679 rtw89_err(rtwdev, "failed to alloc skb for h2c p2p act\n"); 1680 return -ENOMEM; 1681 } 1682 skb_put(skb, H2C_TSF32_TOGL_LEN); 1683 cmd = skb->data; 1684 1685 RTW89_SET_FWCMD_TSF32_TOGL_BAND(cmd, rtwvif->mac_idx); 1686 RTW89_SET_FWCMD_TSF32_TOGL_EN(cmd, en); 1687 RTW89_SET_FWCMD_TSF32_TOGL_PORT(cmd, rtwvif->port); 1688 RTW89_SET_FWCMD_TSF32_TOGL_EARLY(cmd, early_us); 1689 1690 rtw89_h2c_pkt_set_hdr(rtwdev, skb, FWCMD_TYPE_H2C, 1691 H2C_CAT_MAC, H2C_CL_MAC_FW_OFLD, 1692 H2C_FUNC_TSF32_TOGL, 0, 0, 1693 H2C_TSF32_TOGL_LEN); 1694 1695 ret = rtw89_h2c_tx(rtwdev, skb, false); 1696 if (ret) { 1697 rtw89_err(rtwdev, "failed to send h2c\n"); 1698 goto fail; 1699 } 1700 1701 return 0; 1702 fail: 1703 dev_kfree_skb_any(skb); 1704 1705 return ret; 1706 } 1707 1708 #define H2C_OFLD_CFG_LEN 8 1709 int rtw89_fw_h2c_set_ofld_cfg(struct rtw89_dev *rtwdev) 1710 { 1711 static const u8 cfg[] = {0x09, 0x00, 0x00, 0x00, 0x5e, 0x00, 0x00, 0x00}; 1712 struct sk_buff *skb; 1713 int ret; 1714 1715 skb = rtw89_fw_h2c_alloc_skb_with_hdr(rtwdev, H2C_OFLD_CFG_LEN); 1716 if (!skb) { 1717 rtw89_err(rtwdev, "failed to alloc skb for h2c ofld\n"); 1718 return -ENOMEM; 1719 } 1720 skb_put_data(skb, cfg, H2C_OFLD_CFG_LEN); 1721 1722 rtw89_h2c_pkt_set_hdr(rtwdev, skb, FWCMD_TYPE_H2C, 1723 H2C_CAT_MAC, H2C_CL_MAC_FW_OFLD, 1724 H2C_FUNC_OFLD_CFG, 0, 1, 1725 H2C_OFLD_CFG_LEN); 1726 1727 ret = rtw89_h2c_tx(rtwdev, skb, false); 1728 if (ret) { 1729 rtw89_err(rtwdev, "failed to send h2c\n"); 1730 goto fail; 1731 } 1732 1733 return 0; 1734 fail: 1735 dev_kfree_skb_any(skb); 1736 1737 return ret; 1738 } 1739 1740 #define H2C_RA_LEN 16 1741 int rtw89_fw_h2c_ra(struct rtw89_dev *rtwdev, struct rtw89_ra_info *ra, bool csi) 1742 { 1743 struct sk_buff *skb; 1744 u8 *cmd; 1745 int ret; 1746 1747 skb = rtw89_fw_h2c_alloc_skb_with_hdr(rtwdev, H2C_RA_LEN); 1748 if (!skb) { 1749 rtw89_err(rtwdev, "failed to alloc skb for h2c join\n"); 1750 return -ENOMEM; 1751 } 1752 skb_put(skb, H2C_RA_LEN); 1753 cmd = skb->data; 1754 rtw89_debug(rtwdev, RTW89_DBG_RA, 1755 "ra cmd msk: %llx ", ra->ra_mask); 1756 1757 RTW89_SET_FWCMD_RA_MODE(cmd, ra->mode_ctrl); 1758 RTW89_SET_FWCMD_RA_BW_CAP(cmd, ra->bw_cap); 1759 RTW89_SET_FWCMD_RA_MACID(cmd, ra->macid); 1760 RTW89_SET_FWCMD_RA_DCM(cmd, ra->dcm_cap); 1761 RTW89_SET_FWCMD_RA_ER(cmd, ra->er_cap); 1762 RTW89_SET_FWCMD_RA_INIT_RATE_LV(cmd, ra->init_rate_lv); 1763 RTW89_SET_FWCMD_RA_UPD_ALL(cmd, ra->upd_all); 1764 RTW89_SET_FWCMD_RA_SGI(cmd, ra->en_sgi); 1765 RTW89_SET_FWCMD_RA_LDPC(cmd, ra->ldpc_cap); 1766 RTW89_SET_FWCMD_RA_STBC(cmd, ra->stbc_cap); 1767 RTW89_SET_FWCMD_RA_SS_NUM(cmd, ra->ss_num); 1768 RTW89_SET_FWCMD_RA_GILTF(cmd, ra->giltf); 1769 RTW89_SET_FWCMD_RA_UPD_BW_NSS_MASK(cmd, ra->upd_bw_nss_mask); 1770 RTW89_SET_FWCMD_RA_UPD_MASK(cmd, ra->upd_mask); 1771 RTW89_SET_FWCMD_RA_MASK_0(cmd, FIELD_GET(MASKBYTE0, ra->ra_mask)); 1772 RTW89_SET_FWCMD_RA_MASK_1(cmd, FIELD_GET(MASKBYTE1, ra->ra_mask)); 1773 RTW89_SET_FWCMD_RA_MASK_2(cmd, FIELD_GET(MASKBYTE2, ra->ra_mask)); 1774 RTW89_SET_FWCMD_RA_MASK_3(cmd, FIELD_GET(MASKBYTE3, ra->ra_mask)); 1775 RTW89_SET_FWCMD_RA_MASK_4(cmd, FIELD_GET(MASKBYTE4, ra->ra_mask)); 1776 RTW89_SET_FWCMD_RA_FIX_GILTF_EN(cmd, ra->fix_giltf_en); 1777 RTW89_SET_FWCMD_RA_FIX_GILTF(cmd, ra->fix_giltf); 1778 1779 if (csi) { 1780 RTW89_SET_FWCMD_RA_BFEE_CSI_CTL(cmd, 1); 1781 RTW89_SET_FWCMD_RA_BAND_NUM(cmd, ra->band_num); 1782 RTW89_SET_FWCMD_RA_CR_TBL_SEL(cmd, ra->cr_tbl_sel); 1783 RTW89_SET_FWCMD_RA_FIXED_CSI_RATE_EN(cmd, ra->fixed_csi_rate_en); 1784 RTW89_SET_FWCMD_RA_RA_CSI_RATE_EN(cmd, ra->ra_csi_rate_en); 1785 RTW89_SET_FWCMD_RA_FIXED_CSI_MCS_SS_IDX(cmd, ra->csi_mcs_ss_idx); 1786 RTW89_SET_FWCMD_RA_FIXED_CSI_MODE(cmd, ra->csi_mode); 1787 RTW89_SET_FWCMD_RA_FIXED_CSI_GI_LTF(cmd, ra->csi_gi_ltf); 1788 RTW89_SET_FWCMD_RA_FIXED_CSI_BW(cmd, ra->csi_bw); 1789 } 1790 1791 rtw89_h2c_pkt_set_hdr(rtwdev, skb, FWCMD_TYPE_H2C, 1792 H2C_CAT_OUTSRC, H2C_CL_OUTSRC_RA, 1793 H2C_FUNC_OUTSRC_RA_MACIDCFG, 0, 0, 1794 H2C_RA_LEN); 1795 1796 ret = rtw89_h2c_tx(rtwdev, skb, false); 1797 if (ret) { 1798 rtw89_err(rtwdev, "failed to send h2c\n"); 1799 goto fail; 1800 } 1801 1802 return 0; 1803 fail: 1804 dev_kfree_skb_any(skb); 1805 1806 return ret; 1807 } 1808 1809 #define H2C_LEN_CXDRVHDR 2 1810 #define H2C_LEN_CXDRVINFO_INIT (12 + H2C_LEN_CXDRVHDR) 1811 int rtw89_fw_h2c_cxdrv_init(struct rtw89_dev *rtwdev) 1812 { 1813 struct rtw89_btc *btc = &rtwdev->btc; 1814 struct rtw89_btc_dm *dm = &btc->dm; 1815 struct rtw89_btc_init_info *init_info = &dm->init_info; 1816 struct rtw89_btc_module *module = &init_info->module; 1817 struct rtw89_btc_ant_info *ant = &module->ant; 1818 struct sk_buff *skb; 1819 u8 *cmd; 1820 int ret; 1821 1822 skb = rtw89_fw_h2c_alloc_skb_with_hdr(rtwdev, H2C_LEN_CXDRVINFO_INIT); 1823 if (!skb) { 1824 rtw89_err(rtwdev, "failed to alloc skb for h2c cxdrv_init\n"); 1825 return -ENOMEM; 1826 } 1827 skb_put(skb, H2C_LEN_CXDRVINFO_INIT); 1828 cmd = skb->data; 1829 1830 RTW89_SET_FWCMD_CXHDR_TYPE(cmd, CXDRVINFO_INIT); 1831 RTW89_SET_FWCMD_CXHDR_LEN(cmd, H2C_LEN_CXDRVINFO_INIT - H2C_LEN_CXDRVHDR); 1832 1833 RTW89_SET_FWCMD_CXINIT_ANT_TYPE(cmd, ant->type); 1834 RTW89_SET_FWCMD_CXINIT_ANT_NUM(cmd, ant->num); 1835 RTW89_SET_FWCMD_CXINIT_ANT_ISO(cmd, ant->isolation); 1836 RTW89_SET_FWCMD_CXINIT_ANT_POS(cmd, ant->single_pos); 1837 RTW89_SET_FWCMD_CXINIT_ANT_DIVERSITY(cmd, ant->diversity); 1838 1839 RTW89_SET_FWCMD_CXINIT_MOD_RFE(cmd, module->rfe_type); 1840 RTW89_SET_FWCMD_CXINIT_MOD_CV(cmd, module->cv); 1841 RTW89_SET_FWCMD_CXINIT_MOD_BT_SOLO(cmd, module->bt_solo); 1842 RTW89_SET_FWCMD_CXINIT_MOD_BT_POS(cmd, module->bt_pos); 1843 RTW89_SET_FWCMD_CXINIT_MOD_SW_TYPE(cmd, module->switch_type); 1844 1845 RTW89_SET_FWCMD_CXINIT_WL_GCH(cmd, init_info->wl_guard_ch); 1846 RTW89_SET_FWCMD_CXINIT_WL_ONLY(cmd, init_info->wl_only); 1847 RTW89_SET_FWCMD_CXINIT_WL_INITOK(cmd, init_info->wl_init_ok); 1848 RTW89_SET_FWCMD_CXINIT_DBCC_EN(cmd, init_info->dbcc_en); 1849 RTW89_SET_FWCMD_CXINIT_CX_OTHER(cmd, init_info->cx_other); 1850 RTW89_SET_FWCMD_CXINIT_BT_ONLY(cmd, init_info->bt_only); 1851 1852 rtw89_h2c_pkt_set_hdr(rtwdev, skb, FWCMD_TYPE_H2C, 1853 H2C_CAT_OUTSRC, BTFC_SET, 1854 SET_DRV_INFO, 0, 0, 1855 H2C_LEN_CXDRVINFO_INIT); 1856 1857 ret = rtw89_h2c_tx(rtwdev, skb, false); 1858 if (ret) { 1859 rtw89_err(rtwdev, "failed to send h2c\n"); 1860 goto fail; 1861 } 1862 1863 return 0; 1864 fail: 1865 dev_kfree_skb_any(skb); 1866 1867 return ret; 1868 } 1869 1870 #define PORT_DATA_OFFSET 4 1871 #define H2C_LEN_CXDRVINFO_ROLE_DBCC_LEN 12 1872 #define H2C_LEN_CXDRVINFO_ROLE_SIZE(max_role_num) \ 1873 (4 + 12 * (max_role_num) + H2C_LEN_CXDRVHDR) 1874 1875 int rtw89_fw_h2c_cxdrv_role(struct rtw89_dev *rtwdev) 1876 { 1877 struct rtw89_btc *btc = &rtwdev->btc; 1878 const struct rtw89_btc_ver *ver = btc->ver; 1879 struct rtw89_btc_wl_info *wl = &btc->cx.wl; 1880 struct rtw89_btc_wl_role_info *role_info = &wl->role_info; 1881 struct rtw89_btc_wl_role_info_bpos *bpos = &role_info->role_map.role; 1882 struct rtw89_btc_wl_active_role *active = role_info->active_role; 1883 struct sk_buff *skb; 1884 u32 len; 1885 u8 offset = 0; 1886 u8 *cmd; 1887 int ret; 1888 int i; 1889 1890 len = H2C_LEN_CXDRVINFO_ROLE_SIZE(ver->max_role_num); 1891 1892 skb = rtw89_fw_h2c_alloc_skb_with_hdr(rtwdev, len); 1893 if (!skb) { 1894 rtw89_err(rtwdev, "failed to alloc skb for h2c cxdrv_role\n"); 1895 return -ENOMEM; 1896 } 1897 skb_put(skb, len); 1898 cmd = skb->data; 1899 1900 RTW89_SET_FWCMD_CXHDR_TYPE(cmd, CXDRVINFO_ROLE); 1901 RTW89_SET_FWCMD_CXHDR_LEN(cmd, len - H2C_LEN_CXDRVHDR); 1902 1903 RTW89_SET_FWCMD_CXROLE_CONNECT_CNT(cmd, role_info->connect_cnt); 1904 RTW89_SET_FWCMD_CXROLE_LINK_MODE(cmd, role_info->link_mode); 1905 1906 RTW89_SET_FWCMD_CXROLE_ROLE_NONE(cmd, bpos->none); 1907 RTW89_SET_FWCMD_CXROLE_ROLE_STA(cmd, bpos->station); 1908 RTW89_SET_FWCMD_CXROLE_ROLE_AP(cmd, bpos->ap); 1909 RTW89_SET_FWCMD_CXROLE_ROLE_VAP(cmd, bpos->vap); 1910 RTW89_SET_FWCMD_CXROLE_ROLE_ADHOC(cmd, bpos->adhoc); 1911 RTW89_SET_FWCMD_CXROLE_ROLE_ADHOC_MASTER(cmd, bpos->adhoc_master); 1912 RTW89_SET_FWCMD_CXROLE_ROLE_MESH(cmd, bpos->mesh); 1913 RTW89_SET_FWCMD_CXROLE_ROLE_MONITOR(cmd, bpos->moniter); 1914 RTW89_SET_FWCMD_CXROLE_ROLE_P2P_DEV(cmd, bpos->p2p_device); 1915 RTW89_SET_FWCMD_CXROLE_ROLE_P2P_GC(cmd, bpos->p2p_gc); 1916 RTW89_SET_FWCMD_CXROLE_ROLE_P2P_GO(cmd, bpos->p2p_go); 1917 RTW89_SET_FWCMD_CXROLE_ROLE_NAN(cmd, bpos->nan); 1918 1919 for (i = 0; i < RTW89_PORT_NUM; i++, active++) { 1920 RTW89_SET_FWCMD_CXROLE_ACT_CONNECTED(cmd, active->connected, i, offset); 1921 RTW89_SET_FWCMD_CXROLE_ACT_PID(cmd, active->pid, i, offset); 1922 RTW89_SET_FWCMD_CXROLE_ACT_PHY(cmd, active->phy, i, offset); 1923 RTW89_SET_FWCMD_CXROLE_ACT_NOA(cmd, active->noa, i, offset); 1924 RTW89_SET_FWCMD_CXROLE_ACT_BAND(cmd, active->band, i, offset); 1925 RTW89_SET_FWCMD_CXROLE_ACT_CLIENT_PS(cmd, active->client_ps, i, offset); 1926 RTW89_SET_FWCMD_CXROLE_ACT_BW(cmd, active->bw, i, offset); 1927 RTW89_SET_FWCMD_CXROLE_ACT_ROLE(cmd, active->role, i, offset); 1928 RTW89_SET_FWCMD_CXROLE_ACT_CH(cmd, active->ch, i, offset); 1929 RTW89_SET_FWCMD_CXROLE_ACT_TX_LVL(cmd, active->tx_lvl, i, offset); 1930 RTW89_SET_FWCMD_CXROLE_ACT_RX_LVL(cmd, active->rx_lvl, i, offset); 1931 RTW89_SET_FWCMD_CXROLE_ACT_TX_RATE(cmd, active->tx_rate, i, offset); 1932 RTW89_SET_FWCMD_CXROLE_ACT_RX_RATE(cmd, active->rx_rate, i, offset); 1933 } 1934 1935 rtw89_h2c_pkt_set_hdr(rtwdev, skb, FWCMD_TYPE_H2C, 1936 H2C_CAT_OUTSRC, BTFC_SET, 1937 SET_DRV_INFO, 0, 0, 1938 len); 1939 1940 ret = rtw89_h2c_tx(rtwdev, skb, false); 1941 if (ret) { 1942 rtw89_err(rtwdev, "failed to send h2c\n"); 1943 goto fail; 1944 } 1945 1946 return 0; 1947 fail: 1948 dev_kfree_skb_any(skb); 1949 1950 return ret; 1951 } 1952 1953 #define H2C_LEN_CXDRVINFO_ROLE_SIZE_V1(max_role_num) \ 1954 (4 + 16 * (max_role_num) + H2C_LEN_CXDRVINFO_ROLE_DBCC_LEN + H2C_LEN_CXDRVHDR) 1955 1956 int rtw89_fw_h2c_cxdrv_role_v1(struct rtw89_dev *rtwdev) 1957 { 1958 struct rtw89_btc *btc = &rtwdev->btc; 1959 const struct rtw89_btc_ver *ver = btc->ver; 1960 struct rtw89_btc_wl_info *wl = &btc->cx.wl; 1961 struct rtw89_btc_wl_role_info_v1 *role_info = &wl->role_info_v1; 1962 struct rtw89_btc_wl_role_info_bpos *bpos = &role_info->role_map.role; 1963 struct rtw89_btc_wl_active_role_v1 *active = role_info->active_role_v1; 1964 struct sk_buff *skb; 1965 u32 len; 1966 u8 *cmd, offset; 1967 int ret; 1968 int i; 1969 1970 len = H2C_LEN_CXDRVINFO_ROLE_SIZE_V1(ver->max_role_num); 1971 1972 skb = rtw89_fw_h2c_alloc_skb_with_hdr(rtwdev, len); 1973 if (!skb) { 1974 rtw89_err(rtwdev, "failed to alloc skb for h2c cxdrv_role\n"); 1975 return -ENOMEM; 1976 } 1977 skb_put(skb, len); 1978 cmd = skb->data; 1979 1980 RTW89_SET_FWCMD_CXHDR_TYPE(cmd, CXDRVINFO_ROLE); 1981 RTW89_SET_FWCMD_CXHDR_LEN(cmd, len - H2C_LEN_CXDRVHDR); 1982 1983 RTW89_SET_FWCMD_CXROLE_CONNECT_CNT(cmd, role_info->connect_cnt); 1984 RTW89_SET_FWCMD_CXROLE_LINK_MODE(cmd, role_info->link_mode); 1985 1986 RTW89_SET_FWCMD_CXROLE_ROLE_NONE(cmd, bpos->none); 1987 RTW89_SET_FWCMD_CXROLE_ROLE_STA(cmd, bpos->station); 1988 RTW89_SET_FWCMD_CXROLE_ROLE_AP(cmd, bpos->ap); 1989 RTW89_SET_FWCMD_CXROLE_ROLE_VAP(cmd, bpos->vap); 1990 RTW89_SET_FWCMD_CXROLE_ROLE_ADHOC(cmd, bpos->adhoc); 1991 RTW89_SET_FWCMD_CXROLE_ROLE_ADHOC_MASTER(cmd, bpos->adhoc_master); 1992 RTW89_SET_FWCMD_CXROLE_ROLE_MESH(cmd, bpos->mesh); 1993 RTW89_SET_FWCMD_CXROLE_ROLE_MONITOR(cmd, bpos->moniter); 1994 RTW89_SET_FWCMD_CXROLE_ROLE_P2P_DEV(cmd, bpos->p2p_device); 1995 RTW89_SET_FWCMD_CXROLE_ROLE_P2P_GC(cmd, bpos->p2p_gc); 1996 RTW89_SET_FWCMD_CXROLE_ROLE_P2P_GO(cmd, bpos->p2p_go); 1997 RTW89_SET_FWCMD_CXROLE_ROLE_NAN(cmd, bpos->nan); 1998 1999 offset = PORT_DATA_OFFSET; 2000 for (i = 0; i < RTW89_PORT_NUM; i++, active++) { 2001 RTW89_SET_FWCMD_CXROLE_ACT_CONNECTED(cmd, active->connected, i, offset); 2002 RTW89_SET_FWCMD_CXROLE_ACT_PID(cmd, active->pid, i, offset); 2003 RTW89_SET_FWCMD_CXROLE_ACT_PHY(cmd, active->phy, i, offset); 2004 RTW89_SET_FWCMD_CXROLE_ACT_NOA(cmd, active->noa, i, offset); 2005 RTW89_SET_FWCMD_CXROLE_ACT_BAND(cmd, active->band, i, offset); 2006 RTW89_SET_FWCMD_CXROLE_ACT_CLIENT_PS(cmd, active->client_ps, i, offset); 2007 RTW89_SET_FWCMD_CXROLE_ACT_BW(cmd, active->bw, i, offset); 2008 RTW89_SET_FWCMD_CXROLE_ACT_ROLE(cmd, active->role, i, offset); 2009 RTW89_SET_FWCMD_CXROLE_ACT_CH(cmd, active->ch, i, offset); 2010 RTW89_SET_FWCMD_CXROLE_ACT_TX_LVL(cmd, active->tx_lvl, i, offset); 2011 RTW89_SET_FWCMD_CXROLE_ACT_RX_LVL(cmd, active->rx_lvl, i, offset); 2012 RTW89_SET_FWCMD_CXROLE_ACT_TX_RATE(cmd, active->tx_rate, i, offset); 2013 RTW89_SET_FWCMD_CXROLE_ACT_RX_RATE(cmd, active->rx_rate, i, offset); 2014 RTW89_SET_FWCMD_CXROLE_ACT_NOA_DUR(cmd, active->noa_duration, i, offset); 2015 } 2016 2017 offset = len - H2C_LEN_CXDRVINFO_ROLE_DBCC_LEN; 2018 RTW89_SET_FWCMD_CXROLE_MROLE_TYPE(cmd, role_info->mrole_type, offset); 2019 RTW89_SET_FWCMD_CXROLE_MROLE_NOA(cmd, role_info->mrole_noa_duration, offset); 2020 RTW89_SET_FWCMD_CXROLE_DBCC_EN(cmd, role_info->dbcc_en, offset); 2021 RTW89_SET_FWCMD_CXROLE_DBCC_CHG(cmd, role_info->dbcc_chg, offset); 2022 RTW89_SET_FWCMD_CXROLE_DBCC_2G_PHY(cmd, role_info->dbcc_2g_phy, offset); 2023 RTW89_SET_FWCMD_CXROLE_LINK_MODE_CHG(cmd, role_info->link_mode_chg, offset); 2024 2025 rtw89_h2c_pkt_set_hdr(rtwdev, skb, FWCMD_TYPE_H2C, 2026 H2C_CAT_OUTSRC, BTFC_SET, 2027 SET_DRV_INFO, 0, 0, 2028 len); 2029 2030 ret = rtw89_h2c_tx(rtwdev, skb, false); 2031 if (ret) { 2032 rtw89_err(rtwdev, "failed to send h2c\n"); 2033 goto fail; 2034 } 2035 2036 return 0; 2037 fail: 2038 dev_kfree_skb_any(skb); 2039 2040 return ret; 2041 } 2042 2043 #define H2C_LEN_CXDRVINFO_ROLE_SIZE_V2(max_role_num) \ 2044 (4 + 8 * (max_role_num) + H2C_LEN_CXDRVINFO_ROLE_DBCC_LEN + H2C_LEN_CXDRVHDR) 2045 2046 int rtw89_fw_h2c_cxdrv_role_v2(struct rtw89_dev *rtwdev) 2047 { 2048 struct rtw89_btc *btc = &rtwdev->btc; 2049 const struct rtw89_btc_ver *ver = btc->ver; 2050 struct rtw89_btc_wl_info *wl = &btc->cx.wl; 2051 struct rtw89_btc_wl_role_info_v2 *role_info = &wl->role_info_v2; 2052 struct rtw89_btc_wl_role_info_bpos *bpos = &role_info->role_map.role; 2053 struct rtw89_btc_wl_active_role_v2 *active = role_info->active_role_v2; 2054 struct sk_buff *skb; 2055 u32 len; 2056 u8 *cmd, offset; 2057 int ret; 2058 int i; 2059 2060 len = H2C_LEN_CXDRVINFO_ROLE_SIZE_V2(ver->max_role_num); 2061 2062 skb = rtw89_fw_h2c_alloc_skb_with_hdr(rtwdev, len); 2063 if (!skb) { 2064 rtw89_err(rtwdev, "failed to alloc skb for h2c cxdrv_role\n"); 2065 return -ENOMEM; 2066 } 2067 skb_put(skb, len); 2068 cmd = skb->data; 2069 2070 RTW89_SET_FWCMD_CXHDR_TYPE(cmd, CXDRVINFO_ROLE); 2071 RTW89_SET_FWCMD_CXHDR_LEN(cmd, len - H2C_LEN_CXDRVHDR); 2072 2073 RTW89_SET_FWCMD_CXROLE_CONNECT_CNT(cmd, role_info->connect_cnt); 2074 RTW89_SET_FWCMD_CXROLE_LINK_MODE(cmd, role_info->link_mode); 2075 2076 RTW89_SET_FWCMD_CXROLE_ROLE_NONE(cmd, bpos->none); 2077 RTW89_SET_FWCMD_CXROLE_ROLE_STA(cmd, bpos->station); 2078 RTW89_SET_FWCMD_CXROLE_ROLE_AP(cmd, bpos->ap); 2079 RTW89_SET_FWCMD_CXROLE_ROLE_VAP(cmd, bpos->vap); 2080 RTW89_SET_FWCMD_CXROLE_ROLE_ADHOC(cmd, bpos->adhoc); 2081 RTW89_SET_FWCMD_CXROLE_ROLE_ADHOC_MASTER(cmd, bpos->adhoc_master); 2082 RTW89_SET_FWCMD_CXROLE_ROLE_MESH(cmd, bpos->mesh); 2083 RTW89_SET_FWCMD_CXROLE_ROLE_MONITOR(cmd, bpos->moniter); 2084 RTW89_SET_FWCMD_CXROLE_ROLE_P2P_DEV(cmd, bpos->p2p_device); 2085 RTW89_SET_FWCMD_CXROLE_ROLE_P2P_GC(cmd, bpos->p2p_gc); 2086 RTW89_SET_FWCMD_CXROLE_ROLE_P2P_GO(cmd, bpos->p2p_go); 2087 RTW89_SET_FWCMD_CXROLE_ROLE_NAN(cmd, bpos->nan); 2088 2089 offset = PORT_DATA_OFFSET; 2090 for (i = 0; i < RTW89_PORT_NUM; i++, active++) { 2091 RTW89_SET_FWCMD_CXROLE_ACT_CONNECTED_V2(cmd, active->connected, i, offset); 2092 RTW89_SET_FWCMD_CXROLE_ACT_PID_V2(cmd, active->pid, i, offset); 2093 RTW89_SET_FWCMD_CXROLE_ACT_PHY_V2(cmd, active->phy, i, offset); 2094 RTW89_SET_FWCMD_CXROLE_ACT_NOA_V2(cmd, active->noa, i, offset); 2095 RTW89_SET_FWCMD_CXROLE_ACT_BAND_V2(cmd, active->band, i, offset); 2096 RTW89_SET_FWCMD_CXROLE_ACT_CLIENT_PS_V2(cmd, active->client_ps, i, offset); 2097 RTW89_SET_FWCMD_CXROLE_ACT_BW_V2(cmd, active->bw, i, offset); 2098 RTW89_SET_FWCMD_CXROLE_ACT_ROLE_V2(cmd, active->role, i, offset); 2099 RTW89_SET_FWCMD_CXROLE_ACT_CH_V2(cmd, active->ch, i, offset); 2100 RTW89_SET_FWCMD_CXROLE_ACT_NOA_DUR_V2(cmd, active->noa_duration, i, offset); 2101 } 2102 2103 offset = len - H2C_LEN_CXDRVINFO_ROLE_DBCC_LEN; 2104 RTW89_SET_FWCMD_CXROLE_MROLE_TYPE(cmd, role_info->mrole_type, offset); 2105 RTW89_SET_FWCMD_CXROLE_MROLE_NOA(cmd, role_info->mrole_noa_duration, offset); 2106 RTW89_SET_FWCMD_CXROLE_DBCC_EN(cmd, role_info->dbcc_en, offset); 2107 RTW89_SET_FWCMD_CXROLE_DBCC_CHG(cmd, role_info->dbcc_chg, offset); 2108 RTW89_SET_FWCMD_CXROLE_DBCC_2G_PHY(cmd, role_info->dbcc_2g_phy, offset); 2109 RTW89_SET_FWCMD_CXROLE_LINK_MODE_CHG(cmd, role_info->link_mode_chg, offset); 2110 2111 rtw89_h2c_pkt_set_hdr(rtwdev, skb, FWCMD_TYPE_H2C, 2112 H2C_CAT_OUTSRC, BTFC_SET, 2113 SET_DRV_INFO, 0, 0, 2114 len); 2115 2116 ret = rtw89_h2c_tx(rtwdev, skb, false); 2117 if (ret) { 2118 rtw89_err(rtwdev, "failed to send h2c\n"); 2119 goto fail; 2120 } 2121 2122 return 0; 2123 fail: 2124 dev_kfree_skb_any(skb); 2125 2126 return ret; 2127 } 2128 2129 #define H2C_LEN_CXDRVINFO_CTRL (4 + H2C_LEN_CXDRVHDR) 2130 int rtw89_fw_h2c_cxdrv_ctrl(struct rtw89_dev *rtwdev) 2131 { 2132 struct rtw89_btc *btc = &rtwdev->btc; 2133 const struct rtw89_btc_ver *ver = btc->ver; 2134 struct rtw89_btc_ctrl *ctrl = &btc->ctrl; 2135 struct sk_buff *skb; 2136 u8 *cmd; 2137 int ret; 2138 2139 skb = rtw89_fw_h2c_alloc_skb_with_hdr(rtwdev, H2C_LEN_CXDRVINFO_CTRL); 2140 if (!skb) { 2141 rtw89_err(rtwdev, "failed to alloc skb for h2c cxdrv_ctrl\n"); 2142 return -ENOMEM; 2143 } 2144 skb_put(skb, H2C_LEN_CXDRVINFO_CTRL); 2145 cmd = skb->data; 2146 2147 RTW89_SET_FWCMD_CXHDR_TYPE(cmd, CXDRVINFO_CTRL); 2148 RTW89_SET_FWCMD_CXHDR_LEN(cmd, H2C_LEN_CXDRVINFO_CTRL - H2C_LEN_CXDRVHDR); 2149 2150 RTW89_SET_FWCMD_CXCTRL_MANUAL(cmd, ctrl->manual); 2151 RTW89_SET_FWCMD_CXCTRL_IGNORE_BT(cmd, ctrl->igno_bt); 2152 RTW89_SET_FWCMD_CXCTRL_ALWAYS_FREERUN(cmd, ctrl->always_freerun); 2153 if (ver->fcxctrl == 0) 2154 RTW89_SET_FWCMD_CXCTRL_TRACE_STEP(cmd, ctrl->trace_step); 2155 2156 rtw89_h2c_pkt_set_hdr(rtwdev, skb, FWCMD_TYPE_H2C, 2157 H2C_CAT_OUTSRC, BTFC_SET, 2158 SET_DRV_INFO, 0, 0, 2159 H2C_LEN_CXDRVINFO_CTRL); 2160 2161 ret = rtw89_h2c_tx(rtwdev, skb, false); 2162 if (ret) { 2163 rtw89_err(rtwdev, "failed to send h2c\n"); 2164 goto fail; 2165 } 2166 2167 return 0; 2168 fail: 2169 dev_kfree_skb_any(skb); 2170 2171 return ret; 2172 } 2173 2174 #define H2C_LEN_CXDRVINFO_TRX (28 + H2C_LEN_CXDRVHDR) 2175 int rtw89_fw_h2c_cxdrv_trx(struct rtw89_dev *rtwdev) 2176 { 2177 struct rtw89_btc *btc = &rtwdev->btc; 2178 struct rtw89_btc_trx_info *trx = &btc->dm.trx_info; 2179 struct sk_buff *skb; 2180 u8 *cmd; 2181 int ret; 2182 2183 skb = rtw89_fw_h2c_alloc_skb_with_hdr(rtwdev, H2C_LEN_CXDRVINFO_TRX); 2184 if (!skb) { 2185 rtw89_err(rtwdev, "failed to alloc skb for h2c cxdrv_trx\n"); 2186 return -ENOMEM; 2187 } 2188 skb_put(skb, H2C_LEN_CXDRVINFO_TRX); 2189 cmd = skb->data; 2190 2191 RTW89_SET_FWCMD_CXHDR_TYPE(cmd, CXDRVINFO_TRX); 2192 RTW89_SET_FWCMD_CXHDR_LEN(cmd, H2C_LEN_CXDRVINFO_TRX - H2C_LEN_CXDRVHDR); 2193 2194 RTW89_SET_FWCMD_CXTRX_TXLV(cmd, trx->tx_lvl); 2195 RTW89_SET_FWCMD_CXTRX_RXLV(cmd, trx->rx_lvl); 2196 RTW89_SET_FWCMD_CXTRX_WLRSSI(cmd, trx->wl_rssi); 2197 RTW89_SET_FWCMD_CXTRX_BTRSSI(cmd, trx->bt_rssi); 2198 RTW89_SET_FWCMD_CXTRX_TXPWR(cmd, trx->tx_power); 2199 RTW89_SET_FWCMD_CXTRX_RXGAIN(cmd, trx->rx_gain); 2200 RTW89_SET_FWCMD_CXTRX_BTTXPWR(cmd, trx->bt_tx_power); 2201 RTW89_SET_FWCMD_CXTRX_BTRXGAIN(cmd, trx->bt_rx_gain); 2202 RTW89_SET_FWCMD_CXTRX_CN(cmd, trx->cn); 2203 RTW89_SET_FWCMD_CXTRX_NHM(cmd, trx->nhm); 2204 RTW89_SET_FWCMD_CXTRX_BTPROFILE(cmd, trx->bt_profile); 2205 RTW89_SET_FWCMD_CXTRX_RSVD2(cmd, trx->rsvd2); 2206 RTW89_SET_FWCMD_CXTRX_TXRATE(cmd, trx->tx_rate); 2207 RTW89_SET_FWCMD_CXTRX_RXRATE(cmd, trx->rx_rate); 2208 RTW89_SET_FWCMD_CXTRX_TXTP(cmd, trx->tx_tp); 2209 RTW89_SET_FWCMD_CXTRX_RXTP(cmd, trx->rx_tp); 2210 RTW89_SET_FWCMD_CXTRX_RXERRRA(cmd, trx->rx_err_ratio); 2211 2212 rtw89_h2c_pkt_set_hdr(rtwdev, skb, FWCMD_TYPE_H2C, 2213 H2C_CAT_OUTSRC, BTFC_SET, 2214 SET_DRV_INFO, 0, 0, 2215 H2C_LEN_CXDRVINFO_TRX); 2216 2217 ret = rtw89_h2c_tx(rtwdev, skb, false); 2218 if (ret) { 2219 rtw89_err(rtwdev, "failed to send h2c\n"); 2220 goto fail; 2221 } 2222 2223 return 0; 2224 fail: 2225 dev_kfree_skb_any(skb); 2226 2227 return ret; 2228 } 2229 2230 #define H2C_LEN_CXDRVINFO_RFK (4 + H2C_LEN_CXDRVHDR) 2231 int rtw89_fw_h2c_cxdrv_rfk(struct rtw89_dev *rtwdev) 2232 { 2233 struct rtw89_btc *btc = &rtwdev->btc; 2234 struct rtw89_btc_wl_info *wl = &btc->cx.wl; 2235 struct rtw89_btc_wl_rfk_info *rfk_info = &wl->rfk_info; 2236 struct sk_buff *skb; 2237 u8 *cmd; 2238 int ret; 2239 2240 skb = rtw89_fw_h2c_alloc_skb_with_hdr(rtwdev, H2C_LEN_CXDRVINFO_RFK); 2241 if (!skb) { 2242 rtw89_err(rtwdev, "failed to alloc skb for h2c cxdrv_ctrl\n"); 2243 return -ENOMEM; 2244 } 2245 skb_put(skb, H2C_LEN_CXDRVINFO_RFK); 2246 cmd = skb->data; 2247 2248 RTW89_SET_FWCMD_CXHDR_TYPE(cmd, CXDRVINFO_RFK); 2249 RTW89_SET_FWCMD_CXHDR_LEN(cmd, H2C_LEN_CXDRVINFO_RFK - H2C_LEN_CXDRVHDR); 2250 2251 RTW89_SET_FWCMD_CXRFK_STATE(cmd, rfk_info->state); 2252 RTW89_SET_FWCMD_CXRFK_PATH_MAP(cmd, rfk_info->path_map); 2253 RTW89_SET_FWCMD_CXRFK_PHY_MAP(cmd, rfk_info->phy_map); 2254 RTW89_SET_FWCMD_CXRFK_BAND(cmd, rfk_info->band); 2255 RTW89_SET_FWCMD_CXRFK_TYPE(cmd, rfk_info->type); 2256 2257 rtw89_h2c_pkt_set_hdr(rtwdev, skb, FWCMD_TYPE_H2C, 2258 H2C_CAT_OUTSRC, BTFC_SET, 2259 SET_DRV_INFO, 0, 0, 2260 H2C_LEN_CXDRVINFO_RFK); 2261 2262 ret = rtw89_h2c_tx(rtwdev, skb, false); 2263 if (ret) { 2264 rtw89_err(rtwdev, "failed to send h2c\n"); 2265 goto fail; 2266 } 2267 2268 return 0; 2269 fail: 2270 dev_kfree_skb_any(skb); 2271 2272 return ret; 2273 } 2274 2275 #define H2C_LEN_PKT_OFLD 4 2276 int rtw89_fw_h2c_del_pkt_offload(struct rtw89_dev *rtwdev, u8 id) 2277 { 2278 struct sk_buff *skb; 2279 u8 *cmd; 2280 int ret; 2281 2282 skb = rtw89_fw_h2c_alloc_skb_with_hdr(rtwdev, H2C_LEN_PKT_OFLD); 2283 if (!skb) { 2284 rtw89_err(rtwdev, "failed to alloc skb for h2c pkt offload\n"); 2285 return -ENOMEM; 2286 } 2287 skb_put(skb, H2C_LEN_PKT_OFLD); 2288 cmd = skb->data; 2289 2290 RTW89_SET_FWCMD_PACKET_OFLD_PKT_IDX(cmd, id); 2291 RTW89_SET_FWCMD_PACKET_OFLD_PKT_OP(cmd, RTW89_PKT_OFLD_OP_DEL); 2292 2293 rtw89_h2c_pkt_set_hdr(rtwdev, skb, FWCMD_TYPE_H2C, 2294 H2C_CAT_MAC, H2C_CL_MAC_FW_OFLD, 2295 H2C_FUNC_PACKET_OFLD, 1, 1, 2296 H2C_LEN_PKT_OFLD); 2297 2298 ret = rtw89_h2c_tx(rtwdev, skb, false); 2299 if (ret) { 2300 rtw89_err(rtwdev, "failed to send h2c\n"); 2301 goto fail; 2302 } 2303 2304 return 0; 2305 fail: 2306 dev_kfree_skb_any(skb); 2307 2308 return ret; 2309 } 2310 2311 int rtw89_fw_h2c_add_pkt_offload(struct rtw89_dev *rtwdev, u8 *id, 2312 struct sk_buff *skb_ofld) 2313 { 2314 struct sk_buff *skb; 2315 u8 *cmd; 2316 u8 alloc_id; 2317 int ret; 2318 2319 alloc_id = rtw89_core_acquire_bit_map(rtwdev->pkt_offload, 2320 RTW89_MAX_PKT_OFLD_NUM); 2321 if (alloc_id == RTW89_MAX_PKT_OFLD_NUM) 2322 return -ENOSPC; 2323 2324 *id = alloc_id; 2325 2326 skb = rtw89_fw_h2c_alloc_skb_with_hdr(rtwdev, H2C_LEN_PKT_OFLD + skb_ofld->len); 2327 if (!skb) { 2328 rtw89_err(rtwdev, "failed to alloc skb for h2c pkt offload\n"); 2329 rtw89_core_release_bit_map(rtwdev->pkt_offload, alloc_id); 2330 return -ENOMEM; 2331 } 2332 skb_put(skb, H2C_LEN_PKT_OFLD); 2333 cmd = skb->data; 2334 2335 RTW89_SET_FWCMD_PACKET_OFLD_PKT_IDX(cmd, alloc_id); 2336 RTW89_SET_FWCMD_PACKET_OFLD_PKT_OP(cmd, RTW89_PKT_OFLD_OP_ADD); 2337 RTW89_SET_FWCMD_PACKET_OFLD_PKT_LENGTH(cmd, skb_ofld->len); 2338 skb_put_data(skb, skb_ofld->data, skb_ofld->len); 2339 2340 rtw89_h2c_pkt_set_hdr(rtwdev, skb, FWCMD_TYPE_H2C, 2341 H2C_CAT_MAC, H2C_CL_MAC_FW_OFLD, 2342 H2C_FUNC_PACKET_OFLD, 1, 1, 2343 H2C_LEN_PKT_OFLD + skb_ofld->len); 2344 2345 ret = rtw89_h2c_tx(rtwdev, skb, false); 2346 if (ret) { 2347 rtw89_err(rtwdev, "failed to send h2c\n"); 2348 rtw89_core_release_bit_map(rtwdev->pkt_offload, alloc_id); 2349 goto fail; 2350 } 2351 2352 return 0; 2353 fail: 2354 dev_kfree_skb_any(skb); 2355 2356 return ret; 2357 } 2358 2359 #define H2C_LEN_SCAN_LIST_OFFLOAD 4 2360 int rtw89_fw_h2c_scan_list_offload(struct rtw89_dev *rtwdev, int len, 2361 struct list_head *chan_list) 2362 { 2363 struct rtw89_mac_chinfo *ch_info; 2364 struct sk_buff *skb; 2365 int skb_len = H2C_LEN_SCAN_LIST_OFFLOAD + len * RTW89_MAC_CHINFO_SIZE; 2366 u8 *cmd; 2367 int ret; 2368 2369 skb = rtw89_fw_h2c_alloc_skb_with_hdr(rtwdev, skb_len); 2370 if (!skb) { 2371 rtw89_err(rtwdev, "failed to alloc skb for h2c scan list\n"); 2372 return -ENOMEM; 2373 } 2374 skb_put(skb, H2C_LEN_SCAN_LIST_OFFLOAD); 2375 cmd = skb->data; 2376 2377 RTW89_SET_FWCMD_SCANOFLD_CH_NUM(cmd, len); 2378 /* in unit of 4 bytes */ 2379 RTW89_SET_FWCMD_SCANOFLD_CH_SIZE(cmd, RTW89_MAC_CHINFO_SIZE / 4); 2380 2381 list_for_each_entry(ch_info, chan_list, list) { 2382 cmd = skb_put(skb, RTW89_MAC_CHINFO_SIZE); 2383 2384 RTW89_SET_FWCMD_CHINFO_PERIOD(cmd, ch_info->period); 2385 RTW89_SET_FWCMD_CHINFO_DWELL(cmd, ch_info->dwell_time); 2386 RTW89_SET_FWCMD_CHINFO_CENTER_CH(cmd, ch_info->central_ch); 2387 RTW89_SET_FWCMD_CHINFO_PRI_CH(cmd, ch_info->pri_ch); 2388 RTW89_SET_FWCMD_CHINFO_BW(cmd, ch_info->bw); 2389 RTW89_SET_FWCMD_CHINFO_ACTION(cmd, ch_info->notify_action); 2390 RTW89_SET_FWCMD_CHINFO_NUM_PKT(cmd, ch_info->num_pkt); 2391 RTW89_SET_FWCMD_CHINFO_TX(cmd, ch_info->tx_pkt); 2392 RTW89_SET_FWCMD_CHINFO_PAUSE_DATA(cmd, ch_info->pause_data); 2393 RTW89_SET_FWCMD_CHINFO_BAND(cmd, ch_info->ch_band); 2394 RTW89_SET_FWCMD_CHINFO_PKT_ID(cmd, ch_info->probe_id); 2395 RTW89_SET_FWCMD_CHINFO_DFS(cmd, ch_info->dfs_ch); 2396 RTW89_SET_FWCMD_CHINFO_TX_NULL(cmd, ch_info->tx_null); 2397 RTW89_SET_FWCMD_CHINFO_RANDOM(cmd, ch_info->rand_seq_num); 2398 RTW89_SET_FWCMD_CHINFO_PKT0(cmd, ch_info->pkt_id[0]); 2399 RTW89_SET_FWCMD_CHINFO_PKT1(cmd, ch_info->pkt_id[1]); 2400 RTW89_SET_FWCMD_CHINFO_PKT2(cmd, ch_info->pkt_id[2]); 2401 RTW89_SET_FWCMD_CHINFO_PKT3(cmd, ch_info->pkt_id[3]); 2402 RTW89_SET_FWCMD_CHINFO_PKT4(cmd, ch_info->pkt_id[4]); 2403 RTW89_SET_FWCMD_CHINFO_PKT5(cmd, ch_info->pkt_id[5]); 2404 RTW89_SET_FWCMD_CHINFO_PKT6(cmd, ch_info->pkt_id[6]); 2405 RTW89_SET_FWCMD_CHINFO_PKT7(cmd, ch_info->pkt_id[7]); 2406 } 2407 2408 rtw89_h2c_pkt_set_hdr(rtwdev, skb, FWCMD_TYPE_H2C, 2409 H2C_CAT_MAC, H2C_CL_MAC_FW_OFLD, 2410 H2C_FUNC_ADD_SCANOFLD_CH, 1, 1, skb_len); 2411 2412 ret = rtw89_h2c_tx(rtwdev, skb, false); 2413 if (ret) { 2414 rtw89_err(rtwdev, "failed to send h2c\n"); 2415 goto fail; 2416 } 2417 2418 return 0; 2419 fail: 2420 dev_kfree_skb_any(skb); 2421 2422 return ret; 2423 } 2424 2425 #define H2C_LEN_SCAN_OFFLOAD 28 2426 int rtw89_fw_h2c_scan_offload(struct rtw89_dev *rtwdev, 2427 struct rtw89_scan_option *option, 2428 struct rtw89_vif *rtwvif) 2429 { 2430 struct rtw89_hw_scan_info *scan_info = &rtwdev->scan_info; 2431 struct sk_buff *skb; 2432 u8 *cmd; 2433 int ret; 2434 2435 skb = rtw89_fw_h2c_alloc_skb_with_hdr(rtwdev, H2C_LEN_SCAN_OFFLOAD); 2436 if (!skb) { 2437 rtw89_err(rtwdev, "failed to alloc skb for h2c scan offload\n"); 2438 return -ENOMEM; 2439 } 2440 skb_put(skb, H2C_LEN_SCAN_OFFLOAD); 2441 cmd = skb->data; 2442 2443 RTW89_SET_FWCMD_SCANOFLD_MACID(cmd, rtwvif->mac_id); 2444 RTW89_SET_FWCMD_SCANOFLD_PORT_ID(cmd, rtwvif->port); 2445 RTW89_SET_FWCMD_SCANOFLD_BAND(cmd, RTW89_PHY_0); 2446 RTW89_SET_FWCMD_SCANOFLD_OPERATION(cmd, option->enable); 2447 RTW89_SET_FWCMD_SCANOFLD_NOTIFY_END(cmd, true); 2448 RTW89_SET_FWCMD_SCANOFLD_TARGET_CH_MODE(cmd, option->target_ch_mode); 2449 RTW89_SET_FWCMD_SCANOFLD_START_MODE(cmd, RTW89_SCAN_IMMEDIATE); 2450 RTW89_SET_FWCMD_SCANOFLD_SCAN_TYPE(cmd, RTW89_SCAN_ONCE); 2451 if (option->target_ch_mode) { 2452 RTW89_SET_FWCMD_SCANOFLD_TARGET_CH_BW(cmd, scan_info->op_bw); 2453 RTW89_SET_FWCMD_SCANOFLD_TARGET_PRI_CH(cmd, 2454 scan_info->op_pri_ch); 2455 RTW89_SET_FWCMD_SCANOFLD_TARGET_CENTRAL_CH(cmd, 2456 scan_info->op_chan); 2457 RTW89_SET_FWCMD_SCANOFLD_TARGET_CH_BAND(cmd, 2458 scan_info->op_band); 2459 } 2460 2461 rtw89_h2c_pkt_set_hdr(rtwdev, skb, FWCMD_TYPE_H2C, 2462 H2C_CAT_MAC, H2C_CL_MAC_FW_OFLD, 2463 H2C_FUNC_SCANOFLD, 1, 1, 2464 H2C_LEN_SCAN_OFFLOAD); 2465 2466 ret = rtw89_h2c_tx(rtwdev, skb, false); 2467 if (ret) { 2468 rtw89_err(rtwdev, "failed to send h2c\n"); 2469 goto fail; 2470 } 2471 2472 return 0; 2473 fail: 2474 dev_kfree_skb_any(skb); 2475 2476 return ret; 2477 } 2478 2479 int rtw89_fw_h2c_rf_reg(struct rtw89_dev *rtwdev, 2480 struct rtw89_fw_h2c_rf_reg_info *info, 2481 u16 len, u8 page) 2482 { 2483 struct sk_buff *skb; 2484 u8 class = info->rf_path == RF_PATH_A ? 2485 H2C_CL_OUTSRC_RF_REG_A : H2C_CL_OUTSRC_RF_REG_B; 2486 int ret; 2487 2488 skb = rtw89_fw_h2c_alloc_skb_with_hdr(rtwdev, len); 2489 if (!skb) { 2490 rtw89_err(rtwdev, "failed to alloc skb for h2c rf reg\n"); 2491 return -ENOMEM; 2492 } 2493 skb_put_data(skb, info->rtw89_phy_config_rf_h2c[page], len); 2494 2495 rtw89_h2c_pkt_set_hdr(rtwdev, skb, FWCMD_TYPE_H2C, 2496 H2C_CAT_OUTSRC, class, page, 0, 0, 2497 len); 2498 2499 ret = rtw89_h2c_tx(rtwdev, skb, false); 2500 if (ret) { 2501 rtw89_err(rtwdev, "failed to send h2c\n"); 2502 goto fail; 2503 } 2504 2505 return 0; 2506 fail: 2507 dev_kfree_skb_any(skb); 2508 2509 return ret; 2510 } 2511 2512 int rtw89_fw_h2c_rf_ntfy_mcc(struct rtw89_dev *rtwdev) 2513 { 2514 const struct rtw89_chan *chan = rtw89_chan_get(rtwdev, RTW89_SUB_ENTITY_0); 2515 struct rtw89_rfk_mcc_info *rfk_mcc = &rtwdev->rfk_mcc; 2516 struct rtw89_fw_h2c_rf_get_mccch *mccch; 2517 struct sk_buff *skb; 2518 int ret; 2519 2520 skb = rtw89_fw_h2c_alloc_skb_with_hdr(rtwdev, sizeof(*mccch)); 2521 if (!skb) { 2522 rtw89_err(rtwdev, "failed to alloc skb for h2c cxdrv_ctrl\n"); 2523 return -ENOMEM; 2524 } 2525 skb_put(skb, sizeof(*mccch)); 2526 mccch = (struct rtw89_fw_h2c_rf_get_mccch *)skb->data; 2527 2528 mccch->ch_0 = cpu_to_le32(rfk_mcc->ch[0]); 2529 mccch->ch_1 = cpu_to_le32(rfk_mcc->ch[1]); 2530 mccch->band_0 = cpu_to_le32(rfk_mcc->band[0]); 2531 mccch->band_1 = cpu_to_le32(rfk_mcc->band[1]); 2532 mccch->current_channel = cpu_to_le32(chan->channel); 2533 mccch->current_band_type = cpu_to_le32(chan->band_type); 2534 2535 rtw89_h2c_pkt_set_hdr(rtwdev, skb, FWCMD_TYPE_H2C, 2536 H2C_CAT_OUTSRC, H2C_CL_OUTSRC_RF_FW_NOTIFY, 2537 H2C_FUNC_OUTSRC_RF_GET_MCCCH, 0, 0, 2538 sizeof(*mccch)); 2539 2540 ret = rtw89_h2c_tx(rtwdev, skb, false); 2541 if (ret) { 2542 rtw89_err(rtwdev, "failed to send h2c\n"); 2543 goto fail; 2544 } 2545 2546 return 0; 2547 fail: 2548 dev_kfree_skb_any(skb); 2549 2550 return ret; 2551 } 2552 EXPORT_SYMBOL(rtw89_fw_h2c_rf_ntfy_mcc); 2553 2554 int rtw89_fw_h2c_raw_with_hdr(struct rtw89_dev *rtwdev, 2555 u8 h2c_class, u8 h2c_func, u8 *buf, u16 len, 2556 bool rack, bool dack) 2557 { 2558 struct sk_buff *skb; 2559 int ret; 2560 2561 skb = rtw89_fw_h2c_alloc_skb_with_hdr(rtwdev, len); 2562 if (!skb) { 2563 rtw89_err(rtwdev, "failed to alloc skb for raw with hdr\n"); 2564 return -ENOMEM; 2565 } 2566 skb_put_data(skb, buf, len); 2567 2568 rtw89_h2c_pkt_set_hdr(rtwdev, skb, FWCMD_TYPE_H2C, 2569 H2C_CAT_OUTSRC, h2c_class, h2c_func, rack, dack, 2570 len); 2571 2572 ret = rtw89_h2c_tx(rtwdev, skb, false); 2573 if (ret) { 2574 rtw89_err(rtwdev, "failed to send h2c\n"); 2575 goto fail; 2576 } 2577 2578 return 0; 2579 fail: 2580 dev_kfree_skb_any(skb); 2581 2582 return ret; 2583 } 2584 2585 int rtw89_fw_h2c_raw(struct rtw89_dev *rtwdev, const u8 *buf, u16 len) 2586 { 2587 struct sk_buff *skb; 2588 int ret; 2589 2590 skb = rtw89_fw_h2c_alloc_skb_no_hdr(rtwdev, len); 2591 if (!skb) { 2592 rtw89_err(rtwdev, "failed to alloc skb for h2c raw\n"); 2593 return -ENOMEM; 2594 } 2595 skb_put_data(skb, buf, len); 2596 2597 ret = rtw89_h2c_tx(rtwdev, skb, false); 2598 if (ret) { 2599 rtw89_err(rtwdev, "failed to send h2c\n"); 2600 goto fail; 2601 } 2602 2603 return 0; 2604 fail: 2605 dev_kfree_skb_any(skb); 2606 2607 return ret; 2608 } 2609 2610 void rtw89_fw_send_all_early_h2c(struct rtw89_dev *rtwdev) 2611 { 2612 struct rtw89_early_h2c *early_h2c; 2613 2614 lockdep_assert_held(&rtwdev->mutex); 2615 2616 list_for_each_entry(early_h2c, &rtwdev->early_h2c_list, list) { 2617 rtw89_fw_h2c_raw(rtwdev, early_h2c->h2c, early_h2c->h2c_len); 2618 } 2619 } 2620 2621 void rtw89_fw_free_all_early_h2c(struct rtw89_dev *rtwdev) 2622 { 2623 struct rtw89_early_h2c *early_h2c, *tmp; 2624 2625 mutex_lock(&rtwdev->mutex); 2626 list_for_each_entry_safe(early_h2c, tmp, &rtwdev->early_h2c_list, list) { 2627 list_del(&early_h2c->list); 2628 kfree(early_h2c->h2c); 2629 kfree(early_h2c); 2630 } 2631 mutex_unlock(&rtwdev->mutex); 2632 } 2633 2634 static void rtw89_fw_c2h_parse_attr(struct sk_buff *c2h) 2635 { 2636 struct rtw89_fw_c2h_attr *attr = RTW89_SKB_C2H_CB(c2h); 2637 2638 attr->category = RTW89_GET_C2H_CATEGORY(c2h->data); 2639 attr->class = RTW89_GET_C2H_CLASS(c2h->data); 2640 attr->func = RTW89_GET_C2H_FUNC(c2h->data); 2641 attr->len = RTW89_GET_C2H_LEN(c2h->data); 2642 } 2643 2644 static bool rtw89_fw_c2h_chk_atomic(struct rtw89_dev *rtwdev, 2645 struct sk_buff *c2h) 2646 { 2647 struct rtw89_fw_c2h_attr *attr = RTW89_SKB_C2H_CB(c2h); 2648 u8 category = attr->category; 2649 u8 class = attr->class; 2650 u8 func = attr->func; 2651 2652 switch (category) { 2653 default: 2654 return false; 2655 case RTW89_C2H_CAT_MAC: 2656 return rtw89_mac_c2h_chk_atomic(rtwdev, class, func); 2657 } 2658 } 2659 2660 void rtw89_fw_c2h_irqsafe(struct rtw89_dev *rtwdev, struct sk_buff *c2h) 2661 { 2662 rtw89_fw_c2h_parse_attr(c2h); 2663 if (!rtw89_fw_c2h_chk_atomic(rtwdev, c2h)) 2664 goto enqueue; 2665 2666 rtw89_fw_c2h_cmd_handle(rtwdev, c2h); 2667 dev_kfree_skb_any(c2h); 2668 return; 2669 2670 enqueue: 2671 skb_queue_tail(&rtwdev->c2h_queue, c2h); 2672 ieee80211_queue_work(rtwdev->hw, &rtwdev->c2h_work); 2673 } 2674 2675 static void rtw89_fw_c2h_cmd_handle(struct rtw89_dev *rtwdev, 2676 struct sk_buff *skb) 2677 { 2678 struct rtw89_fw_c2h_attr *attr = RTW89_SKB_C2H_CB(skb); 2679 u8 category = attr->category; 2680 u8 class = attr->class; 2681 u8 func = attr->func; 2682 u16 len = attr->len; 2683 bool dump = true; 2684 2685 if (!test_bit(RTW89_FLAG_RUNNING, rtwdev->flags)) 2686 return; 2687 2688 switch (category) { 2689 case RTW89_C2H_CAT_TEST: 2690 break; 2691 case RTW89_C2H_CAT_MAC: 2692 rtw89_mac_c2h_handle(rtwdev, skb, len, class, func); 2693 if (class == RTW89_MAC_C2H_CLASS_INFO && 2694 func == RTW89_MAC_C2H_FUNC_C2H_LOG) 2695 dump = false; 2696 break; 2697 case RTW89_C2H_CAT_OUTSRC: 2698 if (class >= RTW89_PHY_C2H_CLASS_BTC_MIN && 2699 class <= RTW89_PHY_C2H_CLASS_BTC_MAX) 2700 rtw89_btc_c2h_handle(rtwdev, skb, len, class, func); 2701 else 2702 rtw89_phy_c2h_handle(rtwdev, skb, len, class, func); 2703 break; 2704 } 2705 2706 if (dump) 2707 rtw89_hex_dump(rtwdev, RTW89_DBG_FW, "C2H: ", skb->data, skb->len); 2708 } 2709 2710 void rtw89_fw_c2h_work(struct work_struct *work) 2711 { 2712 struct rtw89_dev *rtwdev = container_of(work, struct rtw89_dev, 2713 c2h_work); 2714 struct sk_buff *skb, *tmp; 2715 2716 skb_queue_walk_safe(&rtwdev->c2h_queue, skb, tmp) { 2717 skb_unlink(skb, &rtwdev->c2h_queue); 2718 mutex_lock(&rtwdev->mutex); 2719 rtw89_fw_c2h_cmd_handle(rtwdev, skb); 2720 mutex_unlock(&rtwdev->mutex); 2721 dev_kfree_skb_any(skb); 2722 } 2723 } 2724 2725 static int rtw89_fw_write_h2c_reg(struct rtw89_dev *rtwdev, 2726 struct rtw89_mac_h2c_info *info) 2727 { 2728 const struct rtw89_chip_info *chip = rtwdev->chip; 2729 struct rtw89_fw_info *fw_info = &rtwdev->fw; 2730 const u32 *h2c_reg = chip->h2c_regs; 2731 u8 i, val, len; 2732 int ret; 2733 2734 ret = read_poll_timeout(rtw89_read8, val, val == 0, 1000, 5000, false, 2735 rtwdev, chip->h2c_ctrl_reg); 2736 if (ret) { 2737 rtw89_warn(rtwdev, "FW does not process h2c registers\n"); 2738 return ret; 2739 } 2740 2741 len = DIV_ROUND_UP(info->content_len + RTW89_H2CREG_HDR_LEN, 2742 sizeof(info->h2creg[0])); 2743 2744 RTW89_SET_H2CREG_HDR_FUNC(&info->h2creg[0], info->id); 2745 RTW89_SET_H2CREG_HDR_LEN(&info->h2creg[0], len); 2746 for (i = 0; i < RTW89_H2CREG_MAX; i++) 2747 rtw89_write32(rtwdev, h2c_reg[i], info->h2creg[i]); 2748 2749 fw_info->h2c_counter++; 2750 rtw89_write8_mask(rtwdev, chip->h2c_counter_reg.addr, 2751 chip->h2c_counter_reg.mask, fw_info->h2c_counter); 2752 rtw89_write8(rtwdev, chip->h2c_ctrl_reg, B_AX_H2CREG_TRIGGER); 2753 2754 return 0; 2755 } 2756 2757 static int rtw89_fw_read_c2h_reg(struct rtw89_dev *rtwdev, 2758 struct rtw89_mac_c2h_info *info) 2759 { 2760 const struct rtw89_chip_info *chip = rtwdev->chip; 2761 struct rtw89_fw_info *fw_info = &rtwdev->fw; 2762 const u32 *c2h_reg = chip->c2h_regs; 2763 u32 ret; 2764 u8 i, val; 2765 2766 info->id = RTW89_FWCMD_C2HREG_FUNC_NULL; 2767 2768 ret = read_poll_timeout_atomic(rtw89_read8, val, val, 1, 2769 RTW89_C2H_TIMEOUT, false, rtwdev, 2770 chip->c2h_ctrl_reg); 2771 if (ret) { 2772 rtw89_warn(rtwdev, "c2h reg timeout\n"); 2773 return ret; 2774 } 2775 2776 for (i = 0; i < RTW89_C2HREG_MAX; i++) 2777 info->c2hreg[i] = rtw89_read32(rtwdev, c2h_reg[i]); 2778 2779 rtw89_write8(rtwdev, chip->c2h_ctrl_reg, 0); 2780 2781 info->id = RTW89_GET_C2H_HDR_FUNC(*info->c2hreg); 2782 info->content_len = (RTW89_GET_C2H_HDR_LEN(*info->c2hreg) << 2) - 2783 RTW89_C2HREG_HDR_LEN; 2784 2785 fw_info->c2h_counter++; 2786 rtw89_write8_mask(rtwdev, chip->c2h_counter_reg.addr, 2787 chip->c2h_counter_reg.mask, fw_info->c2h_counter); 2788 2789 return 0; 2790 } 2791 2792 int rtw89_fw_msg_reg(struct rtw89_dev *rtwdev, 2793 struct rtw89_mac_h2c_info *h2c_info, 2794 struct rtw89_mac_c2h_info *c2h_info) 2795 { 2796 u32 ret; 2797 2798 if (h2c_info && h2c_info->id != RTW89_FWCMD_H2CREG_FUNC_GET_FEATURE) 2799 lockdep_assert_held(&rtwdev->mutex); 2800 2801 if (!h2c_info && !c2h_info) 2802 return -EINVAL; 2803 2804 if (!h2c_info) 2805 goto recv_c2h; 2806 2807 ret = rtw89_fw_write_h2c_reg(rtwdev, h2c_info); 2808 if (ret) 2809 return ret; 2810 2811 recv_c2h: 2812 if (!c2h_info) 2813 return 0; 2814 2815 ret = rtw89_fw_read_c2h_reg(rtwdev, c2h_info); 2816 if (ret) 2817 return ret; 2818 2819 return 0; 2820 } 2821 2822 void rtw89_fw_st_dbg_dump(struct rtw89_dev *rtwdev) 2823 { 2824 if (!test_bit(RTW89_FLAG_POWERON, rtwdev->flags)) { 2825 rtw89_err(rtwdev, "[ERR]pwr is off\n"); 2826 return; 2827 } 2828 2829 rtw89_info(rtwdev, "FW status = 0x%x\n", rtw89_read32(rtwdev, R_AX_UDM0)); 2830 rtw89_info(rtwdev, "FW BADADDR = 0x%x\n", rtw89_read32(rtwdev, R_AX_UDM1)); 2831 rtw89_info(rtwdev, "FW EPC/RA = 0x%x\n", rtw89_read32(rtwdev, R_AX_UDM2)); 2832 rtw89_info(rtwdev, "FW MISC = 0x%x\n", rtw89_read32(rtwdev, R_AX_UDM3)); 2833 rtw89_info(rtwdev, "R_AX_HALT_C2H = 0x%x\n", 2834 rtw89_read32(rtwdev, R_AX_HALT_C2H)); 2835 rtw89_info(rtwdev, "R_AX_SER_DBG_INFO = 0x%x\n", 2836 rtw89_read32(rtwdev, R_AX_SER_DBG_INFO)); 2837 2838 rtw89_fw_prog_cnt_dump(rtwdev); 2839 } 2840 2841 static void rtw89_release_pkt_list(struct rtw89_dev *rtwdev) 2842 { 2843 struct list_head *pkt_list = rtwdev->scan_info.pkt_list; 2844 struct rtw89_pktofld_info *info, *tmp; 2845 u8 idx; 2846 2847 for (idx = NL80211_BAND_2GHZ; idx < NUM_NL80211_BANDS; idx++) { 2848 if (!(rtwdev->chip->support_bands & BIT(idx))) 2849 continue; 2850 2851 list_for_each_entry_safe(info, tmp, &pkt_list[idx], list) { 2852 rtw89_fw_h2c_del_pkt_offload(rtwdev, info->id); 2853 rtw89_core_release_bit_map(rtwdev->pkt_offload, 2854 info->id); 2855 list_del(&info->list); 2856 kfree(info); 2857 } 2858 } 2859 } 2860 2861 static bool rtw89_is_6ghz_wildcard_probe_req(struct rtw89_dev *rtwdev, 2862 struct rtw89_vif *rtwvif, 2863 struct rtw89_pktofld_info *info, 2864 enum nl80211_band band, u8 ssid_idx) 2865 { 2866 struct cfg80211_scan_request *req = rtwvif->scan_req; 2867 2868 if (band != NL80211_BAND_6GHZ) 2869 return false; 2870 2871 if (req->ssids[ssid_idx].ssid_len) { 2872 memcpy(info->ssid, req->ssids[ssid_idx].ssid, 2873 req->ssids[ssid_idx].ssid_len); 2874 info->ssid_len = req->ssids[ssid_idx].ssid_len; 2875 return false; 2876 } else { 2877 return true; 2878 } 2879 } 2880 2881 static int rtw89_append_probe_req_ie(struct rtw89_dev *rtwdev, 2882 struct rtw89_vif *rtwvif, 2883 struct sk_buff *skb, u8 ssid_idx) 2884 { 2885 struct rtw89_hw_scan_info *scan_info = &rtwdev->scan_info; 2886 struct ieee80211_scan_ies *ies = rtwvif->scan_ies; 2887 struct rtw89_pktofld_info *info; 2888 struct sk_buff *new; 2889 int ret = 0; 2890 u8 band; 2891 2892 for (band = NL80211_BAND_2GHZ; band < NUM_NL80211_BANDS; band++) { 2893 if (!(rtwdev->chip->support_bands & BIT(band))) 2894 continue; 2895 2896 new = skb_copy(skb, GFP_KERNEL); 2897 if (!new) { 2898 ret = -ENOMEM; 2899 goto out; 2900 } 2901 skb_put_data(new, ies->ies[band], ies->len[band]); 2902 skb_put_data(new, ies->common_ies, ies->common_ie_len); 2903 2904 info = kzalloc(sizeof(*info), GFP_KERNEL); 2905 if (!info) { 2906 ret = -ENOMEM; 2907 kfree_skb(new); 2908 goto out; 2909 } 2910 2911 if (rtw89_is_6ghz_wildcard_probe_req(rtwdev, rtwvif, info, band, 2912 ssid_idx)) { 2913 kfree_skb(new); 2914 kfree(info); 2915 goto out; 2916 } 2917 2918 ret = rtw89_fw_h2c_add_pkt_offload(rtwdev, &info->id, new); 2919 if (ret) { 2920 kfree_skb(new); 2921 kfree(info); 2922 goto out; 2923 } 2924 2925 list_add_tail(&info->list, &scan_info->pkt_list[band]); 2926 kfree_skb(new); 2927 } 2928 out: 2929 return ret; 2930 } 2931 2932 static int rtw89_hw_scan_update_probe_req(struct rtw89_dev *rtwdev, 2933 struct rtw89_vif *rtwvif) 2934 { 2935 struct cfg80211_scan_request *req = rtwvif->scan_req; 2936 struct sk_buff *skb; 2937 u8 num = req->n_ssids, i; 2938 int ret; 2939 2940 for (i = 0; i < num; i++) { 2941 skb = ieee80211_probereq_get(rtwdev->hw, rtwvif->mac_addr, 2942 req->ssids[i].ssid, 2943 req->ssids[i].ssid_len, 2944 req->ie_len); 2945 if (!skb) 2946 return -ENOMEM; 2947 2948 ret = rtw89_append_probe_req_ie(rtwdev, rtwvif, skb, i); 2949 kfree_skb(skb); 2950 2951 if (ret) 2952 return ret; 2953 } 2954 2955 return 0; 2956 } 2957 2958 static int rtw89_update_6ghz_rnr_chan(struct rtw89_dev *rtwdev, 2959 struct cfg80211_scan_request *req, 2960 struct rtw89_mac_chinfo *ch_info) 2961 { 2962 struct ieee80211_vif *vif = rtwdev->scan_info.scanning_vif; 2963 struct list_head *pkt_list = rtwdev->scan_info.pkt_list; 2964 struct rtw89_vif *rtwvif = vif_to_rtwvif_safe(vif); 2965 struct ieee80211_scan_ies *ies = rtwvif->scan_ies; 2966 struct cfg80211_scan_6ghz_params *params; 2967 struct rtw89_pktofld_info *info, *tmp; 2968 struct ieee80211_hdr *hdr; 2969 struct sk_buff *skb; 2970 bool found; 2971 int ret = 0; 2972 u8 i; 2973 2974 if (!req->n_6ghz_params) 2975 return 0; 2976 2977 for (i = 0; i < req->n_6ghz_params; i++) { 2978 params = &req->scan_6ghz_params[i]; 2979 2980 if (req->channels[params->channel_idx]->hw_value != 2981 ch_info->pri_ch) 2982 continue; 2983 2984 found = false; 2985 list_for_each_entry(tmp, &pkt_list[NL80211_BAND_6GHZ], list) { 2986 if (ether_addr_equal(tmp->bssid, params->bssid)) { 2987 found = true; 2988 break; 2989 } 2990 } 2991 if (found) 2992 continue; 2993 2994 skb = ieee80211_probereq_get(rtwdev->hw, rtwvif->mac_addr, 2995 NULL, 0, req->ie_len); 2996 skb_put_data(skb, ies->ies[NL80211_BAND_6GHZ], ies->len[NL80211_BAND_6GHZ]); 2997 skb_put_data(skb, ies->common_ies, ies->common_ie_len); 2998 hdr = (struct ieee80211_hdr *)skb->data; 2999 ether_addr_copy(hdr->addr3, params->bssid); 3000 3001 info = kzalloc(sizeof(*info), GFP_KERNEL); 3002 if (!info) { 3003 ret = -ENOMEM; 3004 kfree_skb(skb); 3005 goto out; 3006 } 3007 3008 ret = rtw89_fw_h2c_add_pkt_offload(rtwdev, &info->id, skb); 3009 if (ret) { 3010 kfree_skb(skb); 3011 kfree(info); 3012 goto out; 3013 } 3014 3015 ether_addr_copy(info->bssid, params->bssid); 3016 info->channel_6ghz = req->channels[params->channel_idx]->hw_value; 3017 list_add_tail(&info->list, &rtwdev->scan_info.pkt_list[NL80211_BAND_6GHZ]); 3018 3019 ch_info->tx_pkt = true; 3020 ch_info->period = RTW89_CHANNEL_TIME_6G + RTW89_DWELL_TIME_6G; 3021 3022 kfree_skb(skb); 3023 } 3024 3025 out: 3026 return ret; 3027 } 3028 3029 static void rtw89_hw_scan_add_chan(struct rtw89_dev *rtwdev, int chan_type, 3030 int ssid_num, 3031 struct rtw89_mac_chinfo *ch_info) 3032 { 3033 struct rtw89_hw_scan_info *scan_info = &rtwdev->scan_info; 3034 struct ieee80211_vif *vif = rtwdev->scan_info.scanning_vif; 3035 struct rtw89_vif *rtwvif = (struct rtw89_vif *)vif->drv_priv; 3036 struct cfg80211_scan_request *req = rtwvif->scan_req; 3037 struct rtw89_pktofld_info *info; 3038 u8 band, probe_count = 0; 3039 int ret; 3040 3041 ch_info->notify_action = RTW89_SCANOFLD_DEBUG_MASK; 3042 ch_info->dfs_ch = chan_type == RTW89_CHAN_DFS; 3043 ch_info->bw = RTW89_SCAN_WIDTH; 3044 ch_info->tx_pkt = true; 3045 ch_info->cfg_tx_pwr = false; 3046 ch_info->tx_pwr_idx = 0; 3047 ch_info->tx_null = false; 3048 ch_info->pause_data = false; 3049 ch_info->probe_id = RTW89_SCANOFLD_PKT_NONE; 3050 3051 if (ch_info->ch_band == RTW89_BAND_6G) { 3052 if ((ssid_num == 1 && req->ssids[0].ssid_len == 0) || 3053 !ch_info->is_psc) { 3054 ch_info->tx_pkt = false; 3055 if (!req->duration_mandatory) 3056 ch_info->period -= RTW89_DWELL_TIME_6G; 3057 } 3058 } 3059 3060 ret = rtw89_update_6ghz_rnr_chan(rtwdev, req, ch_info); 3061 if (ret) 3062 rtw89_warn(rtwdev, "RNR fails: %d\n", ret); 3063 3064 if (ssid_num) { 3065 band = rtw89_hw_to_nl80211_band(ch_info->ch_band); 3066 3067 list_for_each_entry(info, &scan_info->pkt_list[band], list) { 3068 if (info->channel_6ghz && 3069 ch_info->pri_ch != info->channel_6ghz) 3070 continue; 3071 ch_info->pkt_id[probe_count++] = info->id; 3072 if (probe_count >= RTW89_SCANOFLD_MAX_SSID) 3073 break; 3074 } 3075 ch_info->num_pkt = probe_count; 3076 } 3077 3078 switch (chan_type) { 3079 case RTW89_CHAN_OPERATE: 3080 ch_info->central_ch = scan_info->op_chan; 3081 ch_info->pri_ch = scan_info->op_pri_ch; 3082 ch_info->ch_band = scan_info->op_band; 3083 ch_info->bw = scan_info->op_bw; 3084 ch_info->tx_null = true; 3085 ch_info->num_pkt = 0; 3086 break; 3087 case RTW89_CHAN_DFS: 3088 if (ch_info->ch_band != RTW89_BAND_6G) 3089 ch_info->period = max_t(u8, ch_info->period, 3090 RTW89_DFS_CHAN_TIME); 3091 ch_info->dwell_time = RTW89_DWELL_TIME; 3092 break; 3093 case RTW89_CHAN_ACTIVE: 3094 break; 3095 default: 3096 rtw89_err(rtwdev, "Channel type out of bound\n"); 3097 } 3098 } 3099 3100 static int rtw89_hw_scan_add_chan_list(struct rtw89_dev *rtwdev, 3101 struct rtw89_vif *rtwvif) 3102 { 3103 struct cfg80211_scan_request *req = rtwvif->scan_req; 3104 struct rtw89_mac_chinfo *ch_info, *tmp; 3105 struct ieee80211_channel *channel; 3106 struct list_head chan_list; 3107 bool random_seq = req->flags & NL80211_SCAN_FLAG_RANDOM_SN; 3108 int list_len, off_chan_time = 0; 3109 enum rtw89_chan_type type; 3110 int ret = 0; 3111 u32 idx; 3112 3113 INIT_LIST_HEAD(&chan_list); 3114 for (idx = rtwdev->scan_info.last_chan_idx, list_len = 0; 3115 idx < req->n_channels && list_len < RTW89_SCAN_LIST_LIMIT; 3116 idx++, list_len++) { 3117 channel = req->channels[idx]; 3118 ch_info = kzalloc(sizeof(*ch_info), GFP_KERNEL); 3119 if (!ch_info) { 3120 ret = -ENOMEM; 3121 goto out; 3122 } 3123 3124 if (req->duration_mandatory) 3125 ch_info->period = req->duration; 3126 else if (channel->band == NL80211_BAND_6GHZ) 3127 ch_info->period = RTW89_CHANNEL_TIME_6G + 3128 RTW89_DWELL_TIME_6G; 3129 else 3130 ch_info->period = RTW89_CHANNEL_TIME; 3131 3132 ch_info->ch_band = rtw89_nl80211_to_hw_band(channel->band); 3133 ch_info->central_ch = channel->hw_value; 3134 ch_info->pri_ch = channel->hw_value; 3135 ch_info->rand_seq_num = random_seq; 3136 ch_info->is_psc = cfg80211_channel_is_psc(channel); 3137 3138 if (channel->flags & 3139 (IEEE80211_CHAN_RADAR | IEEE80211_CHAN_NO_IR)) 3140 type = RTW89_CHAN_DFS; 3141 else 3142 type = RTW89_CHAN_ACTIVE; 3143 rtw89_hw_scan_add_chan(rtwdev, type, req->n_ssids, ch_info); 3144 3145 if (rtwvif->net_type != RTW89_NET_TYPE_NO_LINK && 3146 off_chan_time + ch_info->period > RTW89_OFF_CHAN_TIME) { 3147 tmp = kzalloc(sizeof(*tmp), GFP_KERNEL); 3148 if (!tmp) { 3149 ret = -ENOMEM; 3150 kfree(ch_info); 3151 goto out; 3152 } 3153 3154 type = RTW89_CHAN_OPERATE; 3155 tmp->period = req->duration_mandatory ? 3156 req->duration : RTW89_CHANNEL_TIME; 3157 rtw89_hw_scan_add_chan(rtwdev, type, 0, tmp); 3158 list_add_tail(&tmp->list, &chan_list); 3159 off_chan_time = 0; 3160 list_len++; 3161 } 3162 list_add_tail(&ch_info->list, &chan_list); 3163 off_chan_time += ch_info->period; 3164 } 3165 rtwdev->scan_info.last_chan_idx = idx; 3166 ret = rtw89_fw_h2c_scan_list_offload(rtwdev, list_len, &chan_list); 3167 3168 out: 3169 list_for_each_entry_safe(ch_info, tmp, &chan_list, list) { 3170 list_del(&ch_info->list); 3171 kfree(ch_info); 3172 } 3173 3174 return ret; 3175 } 3176 3177 static int rtw89_hw_scan_prehandle(struct rtw89_dev *rtwdev, 3178 struct rtw89_vif *rtwvif) 3179 { 3180 int ret; 3181 3182 ret = rtw89_hw_scan_update_probe_req(rtwdev, rtwvif); 3183 if (ret) { 3184 rtw89_err(rtwdev, "Update probe request failed\n"); 3185 goto out; 3186 } 3187 ret = rtw89_hw_scan_add_chan_list(rtwdev, rtwvif); 3188 out: 3189 return ret; 3190 } 3191 3192 void rtw89_hw_scan_start(struct rtw89_dev *rtwdev, struct ieee80211_vif *vif, 3193 struct ieee80211_scan_request *scan_req) 3194 { 3195 struct rtw89_vif *rtwvif = (struct rtw89_vif *)vif->drv_priv; 3196 struct cfg80211_scan_request *req = &scan_req->req; 3197 u32 rx_fltr = rtwdev->hal.rx_fltr; 3198 u8 mac_addr[ETH_ALEN]; 3199 3200 rtwdev->scan_info.scanning_vif = vif; 3201 rtwdev->scan_info.last_chan_idx = 0; 3202 rtwvif->scan_ies = &scan_req->ies; 3203 rtwvif->scan_req = req; 3204 ieee80211_stop_queues(rtwdev->hw); 3205 3206 if (req->flags & NL80211_SCAN_FLAG_RANDOM_ADDR) 3207 get_random_mask_addr(mac_addr, req->mac_addr, 3208 req->mac_addr_mask); 3209 else 3210 ether_addr_copy(mac_addr, vif->addr); 3211 rtw89_core_scan_start(rtwdev, rtwvif, mac_addr, true); 3212 3213 rx_fltr &= ~B_AX_A_BCN_CHK_EN; 3214 rx_fltr &= ~B_AX_A_BC; 3215 rx_fltr &= ~B_AX_A_A1_MATCH; 3216 rtw89_write32_mask(rtwdev, 3217 rtw89_mac_reg_by_idx(R_AX_RX_FLTR_OPT, RTW89_MAC_0), 3218 B_AX_RX_FLTR_CFG_MASK, 3219 rx_fltr); 3220 } 3221 3222 void rtw89_hw_scan_complete(struct rtw89_dev *rtwdev, struct ieee80211_vif *vif, 3223 bool aborted) 3224 { 3225 struct cfg80211_scan_info info = { 3226 .aborted = aborted, 3227 }; 3228 struct rtw89_vif *rtwvif; 3229 3230 if (!vif) 3231 return; 3232 3233 rtw89_write32_mask(rtwdev, 3234 rtw89_mac_reg_by_idx(R_AX_RX_FLTR_OPT, RTW89_MAC_0), 3235 B_AX_RX_FLTR_CFG_MASK, 3236 rtwdev->hal.rx_fltr); 3237 3238 rtw89_core_scan_complete(rtwdev, vif, true); 3239 ieee80211_scan_completed(rtwdev->hw, &info); 3240 ieee80211_wake_queues(rtwdev->hw); 3241 3242 rtw89_release_pkt_list(rtwdev); 3243 rtwvif = (struct rtw89_vif *)vif->drv_priv; 3244 rtwvif->scan_req = NULL; 3245 rtwvif->scan_ies = NULL; 3246 rtwdev->scan_info.last_chan_idx = 0; 3247 rtwdev->scan_info.scanning_vif = NULL; 3248 3249 if (rtwvif->net_type != RTW89_NET_TYPE_NO_LINK) 3250 rtw89_store_op_chan(rtwdev, false); 3251 rtw89_set_channel(rtwdev); 3252 } 3253 3254 void rtw89_hw_scan_abort(struct rtw89_dev *rtwdev, struct ieee80211_vif *vif) 3255 { 3256 rtw89_hw_scan_offload(rtwdev, vif, false); 3257 rtw89_hw_scan_complete(rtwdev, vif, true); 3258 } 3259 3260 int rtw89_hw_scan_offload(struct rtw89_dev *rtwdev, struct ieee80211_vif *vif, 3261 bool enable) 3262 { 3263 struct rtw89_scan_option opt = {0}; 3264 struct rtw89_vif *rtwvif; 3265 int ret = 0; 3266 3267 rtwvif = vif ? (struct rtw89_vif *)vif->drv_priv : NULL; 3268 if (!rtwvif) 3269 return -EINVAL; 3270 3271 opt.enable = enable; 3272 opt.target_ch_mode = rtwvif->net_type != RTW89_NET_TYPE_NO_LINK; 3273 if (enable) { 3274 ret = rtw89_hw_scan_prehandle(rtwdev, rtwvif); 3275 if (ret) 3276 goto out; 3277 } 3278 ret = rtw89_fw_h2c_scan_offload(rtwdev, &opt, rtwvif); 3279 out: 3280 return ret; 3281 } 3282 3283 void rtw89_store_op_chan(struct rtw89_dev *rtwdev, bool backup) 3284 { 3285 struct rtw89_hw_scan_info *scan_info = &rtwdev->scan_info; 3286 const struct rtw89_chan *cur = rtw89_chan_get(rtwdev, RTW89_SUB_ENTITY_0); 3287 struct rtw89_chan new; 3288 3289 if (backup) { 3290 scan_info->op_pri_ch = cur->primary_channel; 3291 scan_info->op_chan = cur->channel; 3292 scan_info->op_bw = cur->band_width; 3293 scan_info->op_band = cur->band_type; 3294 } else { 3295 rtw89_chan_create(&new, scan_info->op_chan, scan_info->op_pri_ch, 3296 scan_info->op_band, scan_info->op_bw); 3297 rtw89_assign_entity_chan(rtwdev, RTW89_SUB_ENTITY_0, &new); 3298 } 3299 } 3300 3301 #define H2C_FW_CPU_EXCEPTION_LEN 4 3302 #define H2C_FW_CPU_EXCEPTION_TYPE_DEF 0x5566 3303 int rtw89_fw_h2c_trigger_cpu_exception(struct rtw89_dev *rtwdev) 3304 { 3305 struct sk_buff *skb; 3306 int ret; 3307 3308 skb = rtw89_fw_h2c_alloc_skb_with_hdr(rtwdev, H2C_FW_CPU_EXCEPTION_LEN); 3309 if (!skb) { 3310 rtw89_err(rtwdev, 3311 "failed to alloc skb for fw cpu exception\n"); 3312 return -ENOMEM; 3313 } 3314 3315 skb_put(skb, H2C_FW_CPU_EXCEPTION_LEN); 3316 RTW89_SET_FWCMD_CPU_EXCEPTION_TYPE(skb->data, 3317 H2C_FW_CPU_EXCEPTION_TYPE_DEF); 3318 3319 rtw89_h2c_pkt_set_hdr(rtwdev, skb, FWCMD_TYPE_H2C, 3320 H2C_CAT_TEST, 3321 H2C_CL_FW_STATUS_TEST, 3322 H2C_FUNC_CPU_EXCEPTION, 0, 0, 3323 H2C_FW_CPU_EXCEPTION_LEN); 3324 3325 ret = rtw89_h2c_tx(rtwdev, skb, false); 3326 if (ret) { 3327 rtw89_err(rtwdev, "failed to send h2c\n"); 3328 goto fail; 3329 } 3330 3331 return 0; 3332 3333 fail: 3334 dev_kfree_skb_any(skb); 3335 return ret; 3336 } 3337 3338 #define H2C_PKT_DROP_LEN 24 3339 int rtw89_fw_h2c_pkt_drop(struct rtw89_dev *rtwdev, 3340 const struct rtw89_pkt_drop_params *params) 3341 { 3342 struct sk_buff *skb; 3343 int ret; 3344 3345 skb = rtw89_fw_h2c_alloc_skb_with_hdr(rtwdev, H2C_PKT_DROP_LEN); 3346 if (!skb) { 3347 rtw89_err(rtwdev, 3348 "failed to alloc skb for packet drop\n"); 3349 return -ENOMEM; 3350 } 3351 3352 switch (params->sel) { 3353 case RTW89_PKT_DROP_SEL_MACID_BE_ONCE: 3354 case RTW89_PKT_DROP_SEL_MACID_BK_ONCE: 3355 case RTW89_PKT_DROP_SEL_MACID_VI_ONCE: 3356 case RTW89_PKT_DROP_SEL_MACID_VO_ONCE: 3357 case RTW89_PKT_DROP_SEL_BAND_ONCE: 3358 break; 3359 default: 3360 rtw89_debug(rtwdev, RTW89_DBG_FW, 3361 "H2C of pkt drop might not fully support sel: %d yet\n", 3362 params->sel); 3363 break; 3364 } 3365 3366 skb_put(skb, H2C_PKT_DROP_LEN); 3367 RTW89_SET_FWCMD_PKT_DROP_SEL(skb->data, params->sel); 3368 RTW89_SET_FWCMD_PKT_DROP_MACID(skb->data, params->macid); 3369 RTW89_SET_FWCMD_PKT_DROP_BAND(skb->data, params->mac_band); 3370 RTW89_SET_FWCMD_PKT_DROP_PORT(skb->data, params->port); 3371 RTW89_SET_FWCMD_PKT_DROP_MBSSID(skb->data, params->mbssid); 3372 RTW89_SET_FWCMD_PKT_DROP_ROLE_A_INFO_TF_TRS(skb->data, params->tf_trs); 3373 RTW89_SET_FWCMD_PKT_DROP_MACID_BAND_SEL_0(skb->data, 3374 params->macid_band_sel[0]); 3375 RTW89_SET_FWCMD_PKT_DROP_MACID_BAND_SEL_1(skb->data, 3376 params->macid_band_sel[1]); 3377 RTW89_SET_FWCMD_PKT_DROP_MACID_BAND_SEL_2(skb->data, 3378 params->macid_band_sel[2]); 3379 RTW89_SET_FWCMD_PKT_DROP_MACID_BAND_SEL_3(skb->data, 3380 params->macid_band_sel[3]); 3381 3382 rtw89_h2c_pkt_set_hdr(rtwdev, skb, FWCMD_TYPE_H2C, 3383 H2C_CAT_MAC, 3384 H2C_CL_MAC_FW_OFLD, 3385 H2C_FUNC_PKT_DROP, 0, 0, 3386 H2C_PKT_DROP_LEN); 3387 3388 ret = rtw89_h2c_tx(rtwdev, skb, false); 3389 if (ret) { 3390 rtw89_err(rtwdev, "failed to send h2c\n"); 3391 goto fail; 3392 } 3393 3394 return 0; 3395 3396 fail: 3397 dev_kfree_skb_any(skb); 3398 return ret; 3399 } 3400 3401 #define H2C_KEEP_ALIVE_LEN 4 3402 int rtw89_fw_h2c_keep_alive(struct rtw89_dev *rtwdev, struct rtw89_vif *rtwvif, 3403 bool enable) 3404 { 3405 struct sk_buff *skb; 3406 u8 pkt_id = 0; 3407 int ret; 3408 3409 if (enable) { 3410 ret = rtw89_fw_h2c_add_general_pkt(rtwdev, rtwvif, 3411 RTW89_PKT_OFLD_TYPE_NULL_DATA, 3412 &pkt_id); 3413 if (ret) 3414 return -EPERM; 3415 } 3416 3417 skb = rtw89_fw_h2c_alloc_skb_with_hdr(rtwdev, H2C_KEEP_ALIVE_LEN); 3418 if (!skb) { 3419 rtw89_err(rtwdev, "failed to alloc skb for keep alive\n"); 3420 return -ENOMEM; 3421 } 3422 3423 skb_put(skb, H2C_KEEP_ALIVE_LEN); 3424 3425 RTW89_SET_KEEP_ALIVE_ENABLE(skb->data, enable); 3426 RTW89_SET_KEEP_ALIVE_PKT_NULL_ID(skb->data, pkt_id); 3427 RTW89_SET_KEEP_ALIVE_PERIOD(skb->data, 5); 3428 RTW89_SET_KEEP_ALIVE_MACID(skb->data, rtwvif->mac_id); 3429 3430 rtw89_h2c_pkt_set_hdr(rtwdev, skb, FWCMD_TYPE_H2C, 3431 H2C_CAT_MAC, 3432 H2C_CL_MAC_WOW, 3433 H2C_FUNC_KEEP_ALIVE, 0, 1, 3434 H2C_KEEP_ALIVE_LEN); 3435 3436 ret = rtw89_h2c_tx(rtwdev, skb, false); 3437 if (ret) { 3438 rtw89_err(rtwdev, "failed to send h2c\n"); 3439 goto fail; 3440 } 3441 3442 return 0; 3443 3444 fail: 3445 dev_kfree_skb_any(skb); 3446 3447 return ret; 3448 } 3449 3450 #define H2C_DISCONNECT_DETECT_LEN 8 3451 int rtw89_fw_h2c_disconnect_detect(struct rtw89_dev *rtwdev, 3452 struct rtw89_vif *rtwvif, bool enable) 3453 { 3454 struct rtw89_wow_param *rtw_wow = &rtwdev->wow; 3455 struct sk_buff *skb; 3456 u8 macid = rtwvif->mac_id; 3457 int ret; 3458 3459 skb = rtw89_fw_h2c_alloc_skb_with_hdr(rtwdev, H2C_DISCONNECT_DETECT_LEN); 3460 if (!skb) { 3461 rtw89_err(rtwdev, "failed to alloc skb for keep alive\n"); 3462 return -ENOMEM; 3463 } 3464 3465 skb_put(skb, H2C_DISCONNECT_DETECT_LEN); 3466 3467 if (test_bit(RTW89_WOW_FLAG_EN_DISCONNECT, rtw_wow->flags)) { 3468 RTW89_SET_DISCONNECT_DETECT_ENABLE(skb->data, enable); 3469 RTW89_SET_DISCONNECT_DETECT_DISCONNECT(skb->data, !enable); 3470 RTW89_SET_DISCONNECT_DETECT_MAC_ID(skb->data, macid); 3471 RTW89_SET_DISCONNECT_DETECT_CHECK_PERIOD(skb->data, 100); 3472 RTW89_SET_DISCONNECT_DETECT_TRY_PKT_COUNT(skb->data, 5); 3473 } 3474 3475 rtw89_h2c_pkt_set_hdr(rtwdev, skb, FWCMD_TYPE_H2C, 3476 H2C_CAT_MAC, 3477 H2C_CL_MAC_WOW, 3478 H2C_FUNC_DISCONNECT_DETECT, 0, 1, 3479 H2C_DISCONNECT_DETECT_LEN); 3480 3481 ret = rtw89_h2c_tx(rtwdev, skb, false); 3482 if (ret) { 3483 rtw89_err(rtwdev, "failed to send h2c\n"); 3484 goto fail; 3485 } 3486 3487 return 0; 3488 3489 fail: 3490 dev_kfree_skb_any(skb); 3491 3492 return ret; 3493 } 3494 3495 #define H2C_WOW_GLOBAL_LEN 8 3496 int rtw89_fw_h2c_wow_global(struct rtw89_dev *rtwdev, struct rtw89_vif *rtwvif, 3497 bool enable) 3498 { 3499 struct sk_buff *skb; 3500 u8 macid = rtwvif->mac_id; 3501 int ret; 3502 3503 skb = rtw89_fw_h2c_alloc_skb_with_hdr(rtwdev, H2C_WOW_GLOBAL_LEN); 3504 if (!skb) { 3505 rtw89_err(rtwdev, "failed to alloc skb for keep alive\n"); 3506 return -ENOMEM; 3507 } 3508 3509 skb_put(skb, H2C_WOW_GLOBAL_LEN); 3510 3511 RTW89_SET_WOW_GLOBAL_ENABLE(skb->data, enable); 3512 RTW89_SET_WOW_GLOBAL_MAC_ID(skb->data, macid); 3513 3514 rtw89_h2c_pkt_set_hdr(rtwdev, skb, FWCMD_TYPE_H2C, 3515 H2C_CAT_MAC, 3516 H2C_CL_MAC_WOW, 3517 H2C_FUNC_WOW_GLOBAL, 0, 1, 3518 H2C_WOW_GLOBAL_LEN); 3519 3520 ret = rtw89_h2c_tx(rtwdev, skb, false); 3521 if (ret) { 3522 rtw89_err(rtwdev, "failed to send h2c\n"); 3523 goto fail; 3524 } 3525 3526 return 0; 3527 3528 fail: 3529 dev_kfree_skb_any(skb); 3530 3531 return ret; 3532 } 3533 3534 #define H2C_WAKEUP_CTRL_LEN 4 3535 int rtw89_fw_h2c_wow_wakeup_ctrl(struct rtw89_dev *rtwdev, 3536 struct rtw89_vif *rtwvif, 3537 bool enable) 3538 { 3539 struct rtw89_wow_param *rtw_wow = &rtwdev->wow; 3540 struct sk_buff *skb; 3541 u8 macid = rtwvif->mac_id; 3542 int ret; 3543 3544 skb = rtw89_fw_h2c_alloc_skb_with_hdr(rtwdev, H2C_WAKEUP_CTRL_LEN); 3545 if (!skb) { 3546 rtw89_err(rtwdev, "failed to alloc skb for keep alive\n"); 3547 return -ENOMEM; 3548 } 3549 3550 skb_put(skb, H2C_WAKEUP_CTRL_LEN); 3551 3552 if (rtw_wow->pattern_cnt) 3553 RTW89_SET_WOW_WAKEUP_CTRL_PATTERN_MATCH_ENABLE(skb->data, enable); 3554 if (test_bit(RTW89_WOW_FLAG_EN_MAGIC_PKT, rtw_wow->flags)) 3555 RTW89_SET_WOW_WAKEUP_CTRL_MAGIC_ENABLE(skb->data, enable); 3556 if (test_bit(RTW89_WOW_FLAG_EN_DISCONNECT, rtw_wow->flags)) 3557 RTW89_SET_WOW_WAKEUP_CTRL_DEAUTH_ENABLE(skb->data, enable); 3558 3559 RTW89_SET_WOW_WAKEUP_CTRL_MAC_ID(skb->data, macid); 3560 3561 rtw89_h2c_pkt_set_hdr(rtwdev, skb, FWCMD_TYPE_H2C, 3562 H2C_CAT_MAC, 3563 H2C_CL_MAC_WOW, 3564 H2C_FUNC_WAKEUP_CTRL, 0, 1, 3565 H2C_WAKEUP_CTRL_LEN); 3566 3567 ret = rtw89_h2c_tx(rtwdev, skb, false); 3568 if (ret) { 3569 rtw89_err(rtwdev, "failed to send h2c\n"); 3570 goto fail; 3571 } 3572 3573 return 0; 3574 3575 fail: 3576 dev_kfree_skb_any(skb); 3577 3578 return ret; 3579 } 3580 3581 #define H2C_WOW_CAM_UPD_LEN 24 3582 int rtw89_fw_wow_cam_update(struct rtw89_dev *rtwdev, 3583 struct rtw89_wow_cam_info *cam_info) 3584 { 3585 struct sk_buff *skb; 3586 int ret; 3587 3588 skb = rtw89_fw_h2c_alloc_skb_with_hdr(rtwdev, H2C_WOW_CAM_UPD_LEN); 3589 if (!skb) { 3590 rtw89_err(rtwdev, "failed to alloc skb for keep alive\n"); 3591 return -ENOMEM; 3592 } 3593 3594 skb_put(skb, H2C_WOW_CAM_UPD_LEN); 3595 3596 RTW89_SET_WOW_CAM_UPD_R_W(skb->data, cam_info->r_w); 3597 RTW89_SET_WOW_CAM_UPD_IDX(skb->data, cam_info->idx); 3598 if (cam_info->valid) { 3599 RTW89_SET_WOW_CAM_UPD_WKFM1(skb->data, cam_info->mask[0]); 3600 RTW89_SET_WOW_CAM_UPD_WKFM2(skb->data, cam_info->mask[1]); 3601 RTW89_SET_WOW_CAM_UPD_WKFM3(skb->data, cam_info->mask[2]); 3602 RTW89_SET_WOW_CAM_UPD_WKFM4(skb->data, cam_info->mask[3]); 3603 RTW89_SET_WOW_CAM_UPD_CRC(skb->data, cam_info->crc); 3604 RTW89_SET_WOW_CAM_UPD_NEGATIVE_PATTERN_MATCH(skb->data, 3605 cam_info->negative_pattern_match); 3606 RTW89_SET_WOW_CAM_UPD_SKIP_MAC_HDR(skb->data, 3607 cam_info->skip_mac_hdr); 3608 RTW89_SET_WOW_CAM_UPD_UC(skb->data, cam_info->uc); 3609 RTW89_SET_WOW_CAM_UPD_MC(skb->data, cam_info->mc); 3610 RTW89_SET_WOW_CAM_UPD_BC(skb->data, cam_info->bc); 3611 } 3612 RTW89_SET_WOW_CAM_UPD_VALID(skb->data, cam_info->valid); 3613 3614 rtw89_h2c_pkt_set_hdr(rtwdev, skb, FWCMD_TYPE_H2C, 3615 H2C_CAT_MAC, 3616 H2C_CL_MAC_WOW, 3617 H2C_FUNC_WOW_CAM_UPD, 0, 1, 3618 H2C_WOW_CAM_UPD_LEN); 3619 3620 ret = rtw89_h2c_tx(rtwdev, skb, false); 3621 if (ret) { 3622 rtw89_err(rtwdev, "failed to send h2c\n"); 3623 goto fail; 3624 } 3625 3626 return 0; 3627 fail: 3628 dev_kfree_skb_any(skb); 3629 3630 return ret; 3631 } 3632 3633 static int rtw89_h2c_tx_and_wait(struct rtw89_dev *rtwdev, struct sk_buff *skb, 3634 struct rtw89_wait_info *wait, unsigned int cond) 3635 { 3636 int ret; 3637 3638 ret = rtw89_h2c_tx(rtwdev, skb, false); 3639 if (ret) { 3640 rtw89_err(rtwdev, "failed to send h2c\n"); 3641 dev_kfree_skb_any(skb); 3642 return -EBUSY; 3643 } 3644 3645 return rtw89_wait_for_cond(wait, cond); 3646 } 3647 3648 #define H2C_ADD_MCC_LEN 16 3649 int rtw89_fw_h2c_add_mcc(struct rtw89_dev *rtwdev, 3650 const struct rtw89_fw_mcc_add_req *p) 3651 { 3652 struct rtw89_wait_info *wait = &rtwdev->mcc.wait; 3653 struct sk_buff *skb; 3654 unsigned int cond; 3655 3656 skb = rtw89_fw_h2c_alloc_skb_with_hdr(rtwdev, H2C_ADD_MCC_LEN); 3657 if (!skb) { 3658 rtw89_err(rtwdev, 3659 "failed to alloc skb for add mcc\n"); 3660 return -ENOMEM; 3661 } 3662 3663 skb_put(skb, H2C_ADD_MCC_LEN); 3664 RTW89_SET_FWCMD_ADD_MCC_MACID(skb->data, p->macid); 3665 RTW89_SET_FWCMD_ADD_MCC_CENTRAL_CH_SEG0(skb->data, p->central_ch_seg0); 3666 RTW89_SET_FWCMD_ADD_MCC_CENTRAL_CH_SEG1(skb->data, p->central_ch_seg1); 3667 RTW89_SET_FWCMD_ADD_MCC_PRIMARY_CH(skb->data, p->primary_ch); 3668 RTW89_SET_FWCMD_ADD_MCC_BANDWIDTH(skb->data, p->bandwidth); 3669 RTW89_SET_FWCMD_ADD_MCC_GROUP(skb->data, p->group); 3670 RTW89_SET_FWCMD_ADD_MCC_C2H_RPT(skb->data, p->c2h_rpt); 3671 RTW89_SET_FWCMD_ADD_MCC_DIS_TX_NULL(skb->data, p->dis_tx_null); 3672 RTW89_SET_FWCMD_ADD_MCC_DIS_SW_RETRY(skb->data, p->dis_sw_retry); 3673 RTW89_SET_FWCMD_ADD_MCC_IN_CURR_CH(skb->data, p->in_curr_ch); 3674 RTW89_SET_FWCMD_ADD_MCC_SW_RETRY_COUNT(skb->data, p->sw_retry_count); 3675 RTW89_SET_FWCMD_ADD_MCC_TX_NULL_EARLY(skb->data, p->tx_null_early); 3676 RTW89_SET_FWCMD_ADD_MCC_BTC_IN_2G(skb->data, p->btc_in_2g); 3677 RTW89_SET_FWCMD_ADD_MCC_PTA_EN(skb->data, p->pta_en); 3678 RTW89_SET_FWCMD_ADD_MCC_RFK_BY_PASS(skb->data, p->rfk_by_pass); 3679 RTW89_SET_FWCMD_ADD_MCC_CH_BAND_TYPE(skb->data, p->ch_band_type); 3680 RTW89_SET_FWCMD_ADD_MCC_DURATION(skb->data, p->duration); 3681 RTW89_SET_FWCMD_ADD_MCC_COURTESY_EN(skb->data, p->courtesy_en); 3682 RTW89_SET_FWCMD_ADD_MCC_COURTESY_NUM(skb->data, p->courtesy_num); 3683 RTW89_SET_FWCMD_ADD_MCC_COURTESY_TARGET(skb->data, p->courtesy_target); 3684 3685 rtw89_h2c_pkt_set_hdr(rtwdev, skb, FWCMD_TYPE_H2C, 3686 H2C_CAT_MAC, 3687 H2C_CL_MCC, 3688 H2C_FUNC_ADD_MCC, 0, 0, 3689 H2C_ADD_MCC_LEN); 3690 3691 cond = RTW89_MCC_WAIT_COND(p->group, H2C_FUNC_ADD_MCC); 3692 return rtw89_h2c_tx_and_wait(rtwdev, skb, wait, cond); 3693 } 3694 3695 #define H2C_START_MCC_LEN 12 3696 int rtw89_fw_h2c_start_mcc(struct rtw89_dev *rtwdev, 3697 const struct rtw89_fw_mcc_start_req *p) 3698 { 3699 struct rtw89_wait_info *wait = &rtwdev->mcc.wait; 3700 struct sk_buff *skb; 3701 unsigned int cond; 3702 3703 skb = rtw89_fw_h2c_alloc_skb_with_hdr(rtwdev, H2C_START_MCC_LEN); 3704 if (!skb) { 3705 rtw89_err(rtwdev, 3706 "failed to alloc skb for start mcc\n"); 3707 return -ENOMEM; 3708 } 3709 3710 skb_put(skb, H2C_START_MCC_LEN); 3711 RTW89_SET_FWCMD_START_MCC_GROUP(skb->data, p->group); 3712 RTW89_SET_FWCMD_START_MCC_BTC_IN_GROUP(skb->data, p->btc_in_group); 3713 RTW89_SET_FWCMD_START_MCC_OLD_GROUP_ACTION(skb->data, p->old_group_action); 3714 RTW89_SET_FWCMD_START_MCC_OLD_GROUP(skb->data, p->old_group); 3715 RTW89_SET_FWCMD_START_MCC_NOTIFY_CNT(skb->data, p->notify_cnt); 3716 RTW89_SET_FWCMD_START_MCC_NOTIFY_RXDBG_EN(skb->data, p->notify_rxdbg_en); 3717 RTW89_SET_FWCMD_START_MCC_MACID(skb->data, p->macid); 3718 RTW89_SET_FWCMD_START_MCC_TSF_LOW(skb->data, p->tsf_low); 3719 RTW89_SET_FWCMD_START_MCC_TSF_HIGH(skb->data, p->tsf_high); 3720 3721 rtw89_h2c_pkt_set_hdr(rtwdev, skb, FWCMD_TYPE_H2C, 3722 H2C_CAT_MAC, 3723 H2C_CL_MCC, 3724 H2C_FUNC_START_MCC, 0, 0, 3725 H2C_START_MCC_LEN); 3726 3727 cond = RTW89_MCC_WAIT_COND(p->group, H2C_FUNC_START_MCC); 3728 return rtw89_h2c_tx_and_wait(rtwdev, skb, wait, cond); 3729 } 3730 3731 #define H2C_STOP_MCC_LEN 4 3732 int rtw89_fw_h2c_stop_mcc(struct rtw89_dev *rtwdev, u8 group, u8 macid, 3733 bool prev_groups) 3734 { 3735 struct rtw89_wait_info *wait = &rtwdev->mcc.wait; 3736 struct sk_buff *skb; 3737 unsigned int cond; 3738 3739 skb = rtw89_fw_h2c_alloc_skb_with_hdr(rtwdev, H2C_STOP_MCC_LEN); 3740 if (!skb) { 3741 rtw89_err(rtwdev, 3742 "failed to alloc skb for stop mcc\n"); 3743 return -ENOMEM; 3744 } 3745 3746 skb_put(skb, H2C_STOP_MCC_LEN); 3747 RTW89_SET_FWCMD_STOP_MCC_MACID(skb->data, macid); 3748 RTW89_SET_FWCMD_STOP_MCC_GROUP(skb->data, group); 3749 RTW89_SET_FWCMD_STOP_MCC_PREV_GROUPS(skb->data, prev_groups); 3750 3751 rtw89_h2c_pkt_set_hdr(rtwdev, skb, FWCMD_TYPE_H2C, 3752 H2C_CAT_MAC, 3753 H2C_CL_MCC, 3754 H2C_FUNC_STOP_MCC, 0, 0, 3755 H2C_STOP_MCC_LEN); 3756 3757 cond = RTW89_MCC_WAIT_COND(group, H2C_FUNC_STOP_MCC); 3758 return rtw89_h2c_tx_and_wait(rtwdev, skb, wait, cond); 3759 } 3760 3761 #define H2C_DEL_MCC_GROUP_LEN 4 3762 int rtw89_fw_h2c_del_mcc_group(struct rtw89_dev *rtwdev, u8 group, 3763 bool prev_groups) 3764 { 3765 struct rtw89_wait_info *wait = &rtwdev->mcc.wait; 3766 struct sk_buff *skb; 3767 unsigned int cond; 3768 3769 skb = rtw89_fw_h2c_alloc_skb_with_hdr(rtwdev, H2C_DEL_MCC_GROUP_LEN); 3770 if (!skb) { 3771 rtw89_err(rtwdev, 3772 "failed to alloc skb for del mcc group\n"); 3773 return -ENOMEM; 3774 } 3775 3776 skb_put(skb, H2C_DEL_MCC_GROUP_LEN); 3777 RTW89_SET_FWCMD_DEL_MCC_GROUP_GROUP(skb->data, group); 3778 RTW89_SET_FWCMD_DEL_MCC_GROUP_PREV_GROUPS(skb->data, prev_groups); 3779 3780 rtw89_h2c_pkt_set_hdr(rtwdev, skb, FWCMD_TYPE_H2C, 3781 H2C_CAT_MAC, 3782 H2C_CL_MCC, 3783 H2C_FUNC_DEL_MCC_GROUP, 0, 0, 3784 H2C_DEL_MCC_GROUP_LEN); 3785 3786 cond = RTW89_MCC_WAIT_COND(group, H2C_FUNC_DEL_MCC_GROUP); 3787 return rtw89_h2c_tx_and_wait(rtwdev, skb, wait, cond); 3788 } 3789 3790 #define H2C_RESET_MCC_GROUP_LEN 4 3791 int rtw89_fw_h2c_reset_mcc_group(struct rtw89_dev *rtwdev, u8 group) 3792 { 3793 struct rtw89_wait_info *wait = &rtwdev->mcc.wait; 3794 struct sk_buff *skb; 3795 unsigned int cond; 3796 3797 skb = rtw89_fw_h2c_alloc_skb_with_hdr(rtwdev, H2C_RESET_MCC_GROUP_LEN); 3798 if (!skb) { 3799 rtw89_err(rtwdev, 3800 "failed to alloc skb for reset mcc group\n"); 3801 return -ENOMEM; 3802 } 3803 3804 skb_put(skb, H2C_RESET_MCC_GROUP_LEN); 3805 RTW89_SET_FWCMD_RESET_MCC_GROUP_GROUP(skb->data, group); 3806 3807 rtw89_h2c_pkt_set_hdr(rtwdev, skb, FWCMD_TYPE_H2C, 3808 H2C_CAT_MAC, 3809 H2C_CL_MCC, 3810 H2C_FUNC_RESET_MCC_GROUP, 0, 0, 3811 H2C_RESET_MCC_GROUP_LEN); 3812 3813 cond = RTW89_MCC_WAIT_COND(group, H2C_FUNC_RESET_MCC_GROUP); 3814 return rtw89_h2c_tx_and_wait(rtwdev, skb, wait, cond); 3815 } 3816 3817 #define H2C_MCC_REQ_TSF_LEN 4 3818 int rtw89_fw_h2c_mcc_req_tsf(struct rtw89_dev *rtwdev, 3819 const struct rtw89_fw_mcc_tsf_req *req, 3820 struct rtw89_mac_mcc_tsf_rpt *rpt) 3821 { 3822 struct rtw89_wait_info *wait = &rtwdev->mcc.wait; 3823 struct rtw89_mac_mcc_tsf_rpt *tmp; 3824 struct sk_buff *skb; 3825 unsigned int cond; 3826 int ret; 3827 3828 skb = rtw89_fw_h2c_alloc_skb_with_hdr(rtwdev, H2C_MCC_REQ_TSF_LEN); 3829 if (!skb) { 3830 rtw89_err(rtwdev, 3831 "failed to alloc skb for mcc req tsf\n"); 3832 return -ENOMEM; 3833 } 3834 3835 skb_put(skb, H2C_MCC_REQ_TSF_LEN); 3836 RTW89_SET_FWCMD_MCC_REQ_TSF_GROUP(skb->data, req->group); 3837 RTW89_SET_FWCMD_MCC_REQ_TSF_MACID_X(skb->data, req->macid_x); 3838 RTW89_SET_FWCMD_MCC_REQ_TSF_MACID_Y(skb->data, req->macid_y); 3839 3840 rtw89_h2c_pkt_set_hdr(rtwdev, skb, FWCMD_TYPE_H2C, 3841 H2C_CAT_MAC, 3842 H2C_CL_MCC, 3843 H2C_FUNC_MCC_REQ_TSF, 0, 0, 3844 H2C_MCC_REQ_TSF_LEN); 3845 3846 cond = RTW89_MCC_WAIT_COND(req->group, H2C_FUNC_MCC_REQ_TSF); 3847 ret = rtw89_h2c_tx_and_wait(rtwdev, skb, wait, cond); 3848 if (ret) 3849 return ret; 3850 3851 tmp = (struct rtw89_mac_mcc_tsf_rpt *)wait->data.buf; 3852 *rpt = *tmp; 3853 3854 return 0; 3855 } 3856 3857 #define H2C_MCC_MACID_BITMAP_DSC_LEN 4 3858 int rtw89_fw_h2c_mcc_macid_bitamp(struct rtw89_dev *rtwdev, u8 group, u8 macid, 3859 u8 *bitmap) 3860 { 3861 struct rtw89_wait_info *wait = &rtwdev->mcc.wait; 3862 struct sk_buff *skb; 3863 unsigned int cond; 3864 u8 map_len; 3865 u8 h2c_len; 3866 3867 BUILD_BUG_ON(RTW89_MAX_MAC_ID_NUM % 8); 3868 map_len = RTW89_MAX_MAC_ID_NUM / 8; 3869 h2c_len = H2C_MCC_MACID_BITMAP_DSC_LEN + map_len; 3870 skb = rtw89_fw_h2c_alloc_skb_with_hdr(rtwdev, h2c_len); 3871 if (!skb) { 3872 rtw89_err(rtwdev, 3873 "failed to alloc skb for mcc macid bitmap\n"); 3874 return -ENOMEM; 3875 } 3876 3877 skb_put(skb, h2c_len); 3878 RTW89_SET_FWCMD_MCC_MACID_BITMAP_GROUP(skb->data, group); 3879 RTW89_SET_FWCMD_MCC_MACID_BITMAP_MACID(skb->data, macid); 3880 RTW89_SET_FWCMD_MCC_MACID_BITMAP_BITMAP_LENGTH(skb->data, map_len); 3881 RTW89_SET_FWCMD_MCC_MACID_BITMAP_BITMAP(skb->data, bitmap, map_len); 3882 3883 rtw89_h2c_pkt_set_hdr(rtwdev, skb, FWCMD_TYPE_H2C, 3884 H2C_CAT_MAC, 3885 H2C_CL_MCC, 3886 H2C_FUNC_MCC_MACID_BITMAP, 0, 0, 3887 h2c_len); 3888 3889 cond = RTW89_MCC_WAIT_COND(group, H2C_FUNC_MCC_MACID_BITMAP); 3890 return rtw89_h2c_tx_and_wait(rtwdev, skb, wait, cond); 3891 } 3892 3893 #define H2C_MCC_SYNC_LEN 4 3894 int rtw89_fw_h2c_mcc_sync(struct rtw89_dev *rtwdev, u8 group, u8 source, 3895 u8 target, u8 offset) 3896 { 3897 struct rtw89_wait_info *wait = &rtwdev->mcc.wait; 3898 struct sk_buff *skb; 3899 unsigned int cond; 3900 3901 skb = rtw89_fw_h2c_alloc_skb_with_hdr(rtwdev, H2C_MCC_SYNC_LEN); 3902 if (!skb) { 3903 rtw89_err(rtwdev, 3904 "failed to alloc skb for mcc sync\n"); 3905 return -ENOMEM; 3906 } 3907 3908 skb_put(skb, H2C_MCC_SYNC_LEN); 3909 RTW89_SET_FWCMD_MCC_SYNC_GROUP(skb->data, group); 3910 RTW89_SET_FWCMD_MCC_SYNC_MACID_SOURCE(skb->data, source); 3911 RTW89_SET_FWCMD_MCC_SYNC_MACID_TARGET(skb->data, target); 3912 RTW89_SET_FWCMD_MCC_SYNC_SYNC_OFFSET(skb->data, offset); 3913 3914 rtw89_h2c_pkt_set_hdr(rtwdev, skb, FWCMD_TYPE_H2C, 3915 H2C_CAT_MAC, 3916 H2C_CL_MCC, 3917 H2C_FUNC_MCC_SYNC, 0, 0, 3918 H2C_MCC_SYNC_LEN); 3919 3920 cond = RTW89_MCC_WAIT_COND(group, H2C_FUNC_MCC_SYNC); 3921 return rtw89_h2c_tx_and_wait(rtwdev, skb, wait, cond); 3922 } 3923 3924 #define H2C_MCC_SET_DURATION_LEN 20 3925 int rtw89_fw_h2c_mcc_set_duration(struct rtw89_dev *rtwdev, 3926 const struct rtw89_fw_mcc_duration *p) 3927 { 3928 struct rtw89_wait_info *wait = &rtwdev->mcc.wait; 3929 struct sk_buff *skb; 3930 unsigned int cond; 3931 3932 skb = rtw89_fw_h2c_alloc_skb_with_hdr(rtwdev, H2C_MCC_SET_DURATION_LEN); 3933 if (!skb) { 3934 rtw89_err(rtwdev, 3935 "failed to alloc skb for mcc set duration\n"); 3936 return -ENOMEM; 3937 } 3938 3939 skb_put(skb, H2C_MCC_SET_DURATION_LEN); 3940 RTW89_SET_FWCMD_MCC_SET_DURATION_GROUP(skb->data, p->group); 3941 RTW89_SET_FWCMD_MCC_SET_DURATION_BTC_IN_GROUP(skb->data, p->btc_in_group); 3942 RTW89_SET_FWCMD_MCC_SET_DURATION_START_MACID(skb->data, p->start_macid); 3943 RTW89_SET_FWCMD_MCC_SET_DURATION_MACID_X(skb->data, p->macid_x); 3944 RTW89_SET_FWCMD_MCC_SET_DURATION_MACID_Y(skb->data, p->macid_y); 3945 RTW89_SET_FWCMD_MCC_SET_DURATION_START_TSF_LOW(skb->data, 3946 p->start_tsf_low); 3947 RTW89_SET_FWCMD_MCC_SET_DURATION_START_TSF_HIGH(skb->data, 3948 p->start_tsf_high); 3949 RTW89_SET_FWCMD_MCC_SET_DURATION_DURATION_X(skb->data, p->duration_x); 3950 RTW89_SET_FWCMD_MCC_SET_DURATION_DURATION_Y(skb->data, p->duration_y); 3951 3952 rtw89_h2c_pkt_set_hdr(rtwdev, skb, FWCMD_TYPE_H2C, 3953 H2C_CAT_MAC, 3954 H2C_CL_MCC, 3955 H2C_FUNC_MCC_SET_DURATION, 0, 0, 3956 H2C_MCC_SET_DURATION_LEN); 3957 3958 cond = RTW89_MCC_WAIT_COND(p->group, H2C_FUNC_MCC_SET_DURATION); 3959 return rtw89_h2c_tx_and_wait(rtwdev, skb, wait, cond); 3960 } 3961