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