1 // SPDX-License-Identifier: GPL-2.0 OR BSD-3-Clause 2 /* Copyright(c) 2019-2020 Realtek Corporation 3 */ 4 5 #include <linux/if_arp.h> 6 #include <linux/vmalloc.h> 7 #include "cam.h" 8 #include "chan.h" 9 #include "coex.h" 10 #include "debug.h" 11 #include "fw.h" 12 #include "mac.h" 13 #include "phy.h" 14 #include "ps.h" 15 #include "reg.h" 16 #include "util.h" 17 #include "wow.h" 18 19 static bool rtw89_is_any_vif_connected_or_connecting(struct rtw89_dev *rtwdev); 20 21 struct rtw89_eapol_2_of_2 { 22 u8 gtkbody[14]; 23 u8 key_des_ver; 24 u8 rsvd[92]; 25 } __packed; 26 27 struct rtw89_sa_query { 28 u8 category; 29 u8 action; 30 } __packed; 31 32 struct rtw89_arp_rsp { 33 u8 llc_hdr[sizeof(rfc1042_header)]; 34 __be16 llc_type; 35 struct arphdr arp_hdr; 36 u8 sender_hw[ETH_ALEN]; 37 __be32 sender_ip; 38 u8 target_hw[ETH_ALEN]; 39 __be32 target_ip; 40 } __packed; 41 42 static const u8 mss_signature[] = {0x4D, 0x53, 0x53, 0x4B, 0x50, 0x4F, 0x4F, 0x4C}; 43 44 const struct rtw89_fw_blacklist rtw89_fw_blacklist_default = { 45 .ver = 0x00, 46 .list = {0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 47 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 48 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 49 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 50 }, 51 }; 52 EXPORT_SYMBOL(rtw89_fw_blacklist_default); 53 54 union rtw89_fw_element_arg { 55 size_t offset; 56 enum rtw89_rf_path rf_path; 57 enum rtw89_fw_type fw_type; 58 }; 59 60 struct rtw89_fw_element_handler { 61 int (*fn)(struct rtw89_dev *rtwdev, 62 const struct rtw89_fw_element_hdr *elm, 63 const union rtw89_fw_element_arg arg); 64 const union rtw89_fw_element_arg arg; 65 const char *name; 66 }; 67 68 static void rtw89_fw_c2h_cmd_handle(struct rtw89_dev *rtwdev, 69 struct sk_buff *skb); 70 static int rtw89_h2c_tx_and_wait(struct rtw89_dev *rtwdev, struct sk_buff *skb, 71 struct rtw89_wait_info *wait, unsigned int cond); 72 static int __parse_security_section(struct rtw89_dev *rtwdev, 73 struct rtw89_fw_bin_info *info, 74 struct rtw89_fw_hdr_section_info *section_info, 75 const void *content, 76 u32 *mssc_len); 77 78 static struct sk_buff *rtw89_fw_h2c_alloc_skb(struct rtw89_dev *rtwdev, u32 len, 79 bool header) 80 { 81 struct sk_buff *skb; 82 u32 header_len = 0; 83 u32 h2c_desc_size = rtwdev->chip->h2c_desc_size; 84 85 if (header) 86 header_len = H2C_HEADER_LEN; 87 88 skb = dev_alloc_skb(len + header_len + h2c_desc_size); 89 if (!skb) 90 return NULL; 91 skb_reserve(skb, header_len + h2c_desc_size); 92 memset(skb->data, 0, len); 93 94 return skb; 95 } 96 97 struct sk_buff *rtw89_fw_h2c_alloc_skb_with_hdr(struct rtw89_dev *rtwdev, u32 len) 98 { 99 return rtw89_fw_h2c_alloc_skb(rtwdev, len, true); 100 } 101 102 struct sk_buff *rtw89_fw_h2c_alloc_skb_no_hdr(struct rtw89_dev *rtwdev, u32 len) 103 { 104 return rtw89_fw_h2c_alloc_skb(rtwdev, len, false); 105 } 106 107 int rtw89_fw_check_rdy(struct rtw89_dev *rtwdev, enum rtw89_fwdl_check_type type) 108 { 109 const struct rtw89_mac_gen_def *mac = rtwdev->chip->mac_def; 110 u8 val; 111 int ret; 112 113 ret = read_poll_timeout_atomic(mac->fwdl_get_status, val, 114 val == RTW89_FWDL_WCPU_FW_INIT_RDY, 115 1, FWDL_WAIT_CNT, false, rtwdev, type); 116 if (ret) { 117 switch (val) { 118 case RTW89_FWDL_CHECKSUM_FAIL: 119 rtw89_err(rtwdev, "fw checksum fail\n"); 120 return -EINVAL; 121 122 case RTW89_FWDL_SECURITY_FAIL: 123 rtw89_err(rtwdev, "fw security fail\n"); 124 return -EINVAL; 125 126 case RTW89_FWDL_CV_NOT_MATCH: 127 rtw89_err(rtwdev, "fw cv not match\n"); 128 return -EINVAL; 129 130 default: 131 rtw89_err(rtwdev, "fw unexpected status %d\n", val); 132 return -EBUSY; 133 } 134 } 135 136 set_bit(RTW89_FLAG_FW_RDY, rtwdev->flags); 137 138 return 0; 139 } 140 141 static const void *__rtw89_fw_elem_dup_if_needed(struct rtw89_dev *rtwdev, 142 const void *src, size_t len, 143 bool is_fw_suit) 144 { 145 struct rtw89_fw_req_info *fw_req = &rtwdev->fw.req; 146 void *dup; 147 148 if (!fw_req->free_after_probe) 149 return src; 150 151 if (is_fw_suit) { 152 dup = vmalloc(len); 153 if (dup) 154 memcpy(dup, src, len); 155 } else { 156 dup = devm_kmemdup(rtwdev->dev, src, len, GFP_KERNEL); 157 } 158 159 if (!dup) { 160 /* If failed to memdup, fallback to point to firmware->data. */ 161 fw_req->free_after_probe = false; 162 return src; 163 } 164 165 return dup; 166 } 167 168 static const void *rtw89_fw_elem_dup_if_needed(struct rtw89_dev *rtwdev, 169 const struct rtw89_fw_element_hdr *elm) 170 { 171 size_t len = sizeof(*elm) + le32_to_cpu(elm->size); 172 173 return __rtw89_fw_elem_dup_if_needed(rtwdev, elm, len, false); 174 } 175 176 static const void *rtw89_fw_suit_data_dup_if_needed(struct rtw89_dev *rtwdev, 177 struct rtw89_fw_suit *fw_suit, 178 const void *src) 179 { 180 struct rtw89_fw_info *fw = &rtwdev->fw; 181 const void *dup; 182 183 dup = __rtw89_fw_elem_dup_if_needed(rtwdev, src, fw_suit->size, true); 184 185 if (dup != src) 186 list_add_tail(&fw_suit->list, &fw->dup_data_list); 187 188 return dup; 189 } 190 191 static int rtw89_fw_hdr_parser_v0(struct rtw89_dev *rtwdev, const u8 *fw, u32 len, 192 struct rtw89_fw_bin_info *info) 193 { 194 const struct rtw89_fw_hdr *fw_hdr = (const struct rtw89_fw_hdr *)fw; 195 const struct rtw89_chip_info *chip = rtwdev->chip; 196 struct rtw89_fw_hdr_section_info *section_info; 197 struct rtw89_fw_secure *sec = &rtwdev->fw.sec; 198 const struct rtw89_fw_dynhdr_hdr *fwdynhdr; 199 const struct rtw89_fw_hdr_section *section; 200 const u8 *fw_end = fw + len; 201 const u8 *bin; 202 u32 base_hdr_len; 203 u32 mssc_len; 204 int ret; 205 u32 i; 206 207 if (!info) 208 return -EINVAL; 209 210 if (len < sizeof(*fw_hdr)) { 211 rtw89_err(rtwdev, "[ERR]fw header truncated\n"); 212 return -EINVAL; 213 } 214 215 info->section_num = le32_get_bits(fw_hdr->w6, FW_HDR_W6_SEC_NUM); 216 if (!info->section_num || info->section_num > FWDL_SECTION_MAX_NUM) { 217 rtw89_err(rtwdev, "[ERR]invalid fw section num %u\n", 218 info->section_num); 219 return -EINVAL; 220 } 221 222 base_hdr_len = struct_size(fw_hdr, sections, info->section_num); 223 if (base_hdr_len > len) { 224 rtw89_err(rtwdev, "[ERR]fw header truncated\n"); 225 return -EINVAL; 226 } 227 228 info->dynamic_hdr_en = le32_get_bits(fw_hdr->w7, FW_HDR_W7_DYN_HDR); 229 info->idmem_share_mode = le32_get_bits(fw_hdr->w7, FW_HDR_W7_IDMEM_SHARE_MODE); 230 231 if (chip->chip_gen == RTW89_CHIP_AX) 232 info->part_size = FWDL_SECTION_PER_PKT_LEN; 233 else 234 info->part_size = le32_get_bits(fw_hdr->w7, FW_HDR_W7_PART_SIZE); 235 236 if (info->dynamic_hdr_en) { 237 info->hdr_len = le32_get_bits(fw_hdr->w3, FW_HDR_W3_LEN); 238 info->dynamic_hdr_len = info->hdr_len - base_hdr_len; 239 fwdynhdr = (const struct rtw89_fw_dynhdr_hdr *)(fw + base_hdr_len); 240 if (le32_to_cpu(fwdynhdr->hdr_len) != info->dynamic_hdr_len) { 241 rtw89_err(rtwdev, "[ERR]invalid fw dynamic header len\n"); 242 return -EINVAL; 243 } 244 } else { 245 info->hdr_len = base_hdr_len; 246 info->dynamic_hdr_len = 0; 247 } 248 249 bin = fw + info->hdr_len; 250 251 /* jump to section header */ 252 section_info = info->section_info; 253 for (i = 0; i < info->section_num; i++) { 254 section = &fw_hdr->sections[i]; 255 section_info->type = 256 le32_get_bits(section->w1, FWSECTION_HDR_W1_SECTIONTYPE); 257 section_info->len = le32_get_bits(section->w1, FWSECTION_HDR_W1_SEC_SIZE); 258 259 if (le32_get_bits(section->w1, FWSECTION_HDR_W1_CHECKSUM)) 260 section_info->len += FWDL_SECTION_CHKSUM_LEN; 261 section_info->redl = le32_get_bits(section->w1, FWSECTION_HDR_W1_REDL); 262 section_info->dladdr = 263 le32_get_bits(section->w0, FWSECTION_HDR_W0_DL_ADDR) & 0x1fffffff; 264 section_info->addr = bin; 265 266 if (section_info->type == FWDL_SECURITY_SECTION_TYPE) { 267 section_info->mssc = 268 le32_get_bits(section->w2, FWSECTION_HDR_W2_MSSC); 269 270 ret = __parse_security_section(rtwdev, info, section_info, 271 bin, &mssc_len); 272 if (ret) 273 return ret; 274 275 if (sec->secure_boot && chip->chip_id == RTL8852B) 276 section_info->len_override = 960; 277 } else { 278 section_info->mssc = 0; 279 mssc_len = 0; 280 } 281 282 rtw89_debug(rtwdev, RTW89_DBG_FW, 283 "section[%d] type=%d len=0x%-6x mssc=%d mssc_len=%d addr=%tx\n", 284 i, section_info->type, section_info->len, 285 section_info->mssc, mssc_len, bin - fw); 286 rtw89_debug(rtwdev, RTW89_DBG_FW, 287 " ignore=%d key_addr=%p (0x%tx) key_len=%d key_idx=%d\n", 288 section_info->ignore, section_info->key_addr, 289 section_info->key_addr ? 290 section_info->key_addr - section_info->addr : 0, 291 section_info->key_len, section_info->key_idx); 292 293 bin += section_info->len + mssc_len; 294 section_info++; 295 } 296 297 if (fw_end != bin) { 298 rtw89_err(rtwdev, "[ERR]fw bin size\n"); 299 return -EINVAL; 300 } 301 302 return 0; 303 } 304 305 static int __get_mssc_key_idx(struct rtw89_dev *rtwdev, 306 const struct rtw89_fw_mss_pool_hdr *mss_hdr, 307 u32 rmp_tbl_size, u32 *key_idx) 308 { 309 struct rtw89_fw_secure *sec = &rtwdev->fw.sec; 310 u32 sel_byte_idx; 311 u32 mss_sel_idx; 312 u8 sel_bit_idx; 313 int i; 314 315 if (sec->mss_dev_type == RTW89_FW_MSS_DEV_TYPE_FWSEC_DEF) { 316 if (!mss_hdr->defen) 317 return -ENOENT; 318 319 mss_sel_idx = sec->mss_cust_idx * le16_to_cpu(mss_hdr->msskey_num_max) + 320 sec->mss_key_num; 321 } else { 322 if (mss_hdr->defen) 323 mss_sel_idx = FWDL_MSS_POOL_DEFKEYSETS_SIZE << 3; 324 else 325 mss_sel_idx = 0; 326 mss_sel_idx += sec->mss_dev_type * le16_to_cpu(mss_hdr->msskey_num_max) * 327 le16_to_cpu(mss_hdr->msscust_max) + 328 sec->mss_cust_idx * le16_to_cpu(mss_hdr->msskey_num_max) + 329 sec->mss_key_num; 330 } 331 332 sel_byte_idx = mss_sel_idx >> 3; 333 sel_bit_idx = mss_sel_idx & 0x7; 334 335 if (sel_byte_idx >= rmp_tbl_size) 336 return -EFAULT; 337 338 if (!(mss_hdr->rmp_tbl[sel_byte_idx] & BIT(sel_bit_idx))) 339 return -ENOENT; 340 341 *key_idx = hweight8(mss_hdr->rmp_tbl[sel_byte_idx] & (BIT(sel_bit_idx) - 1)); 342 343 for (i = 0; i < sel_byte_idx; i++) 344 *key_idx += hweight8(mss_hdr->rmp_tbl[i]); 345 346 return 0; 347 } 348 349 static int __parse_formatted_mssc(struct rtw89_dev *rtwdev, 350 struct rtw89_fw_bin_info *info, 351 struct rtw89_fw_hdr_section_info *section_info, 352 const void *content, 353 u32 *mssc_len) 354 { 355 const struct rtw89_fw_mss_pool_hdr *mss_hdr = content + section_info->len; 356 const union rtw89_fw_section_mssc_content *section_content = content; 357 struct rtw89_fw_secure *sec = &rtwdev->fw.sec; 358 u32 rmp_tbl_size; 359 u32 key_sign_len; 360 u32 real_key_idx; 361 u32 sb_sel_ver; 362 int ret; 363 364 if (memcmp(mss_signature, mss_hdr->signature, sizeof(mss_signature)) != 0) { 365 rtw89_err(rtwdev, "[ERR] wrong MSS signature\n"); 366 return -ENOENT; 367 } 368 369 if (mss_hdr->rmpfmt == MSS_POOL_RMP_TBL_BITMASK) { 370 rmp_tbl_size = (le16_to_cpu(mss_hdr->msskey_num_max) * 371 le16_to_cpu(mss_hdr->msscust_max) * 372 mss_hdr->mssdev_max) >> 3; 373 if (mss_hdr->defen) 374 rmp_tbl_size += FWDL_MSS_POOL_DEFKEYSETS_SIZE; 375 } else { 376 rtw89_err(rtwdev, "[ERR] MSS Key Pool Remap Table Format Unsupported:%X\n", 377 mss_hdr->rmpfmt); 378 return -EINVAL; 379 } 380 381 if (rmp_tbl_size + sizeof(*mss_hdr) != le32_to_cpu(mss_hdr->key_raw_offset)) { 382 rtw89_err(rtwdev, "[ERR] MSS Key Pool Format Error:0x%X + 0x%X != 0x%X\n", 383 rmp_tbl_size, (int)sizeof(*mss_hdr), 384 le32_to_cpu(mss_hdr->key_raw_offset)); 385 return -EINVAL; 386 } 387 388 key_sign_len = le16_to_cpu(section_content->key_sign_len.v) >> 2; 389 if (!key_sign_len) 390 key_sign_len = 512; 391 392 if (info->dsp_checksum) 393 key_sign_len += FWDL_SECURITY_CHKSUM_LEN; 394 395 *mssc_len = sizeof(*mss_hdr) + rmp_tbl_size + 396 le16_to_cpu(mss_hdr->keypair_num) * key_sign_len; 397 398 if (!sec->secure_boot) 399 goto out; 400 401 sb_sel_ver = get_unaligned_le32(§ion_content->sb_sel_ver.v); 402 if (sb_sel_ver && sb_sel_ver != sec->sb_sel_mgn) 403 goto ignore; 404 405 ret = __get_mssc_key_idx(rtwdev, mss_hdr, rmp_tbl_size, &real_key_idx); 406 if (ret) 407 goto ignore; 408 409 section_info->key_addr = content + section_info->len + 410 le32_to_cpu(mss_hdr->key_raw_offset) + 411 key_sign_len * real_key_idx; 412 section_info->key_len = key_sign_len; 413 section_info->key_idx = real_key_idx; 414 415 out: 416 if (info->secure_section_exist) { 417 section_info->ignore = true; 418 return 0; 419 } 420 421 info->secure_section_exist = true; 422 423 return 0; 424 425 ignore: 426 section_info->ignore = true; 427 428 return 0; 429 } 430 431 static int __check_secure_blacklist(struct rtw89_dev *rtwdev, 432 struct rtw89_fw_bin_info *info, 433 struct rtw89_fw_hdr_section_info *section_info, 434 const void *content) 435 { 436 const struct rtw89_fw_blacklist *chip_blacklist = rtwdev->chip->fw_blacklist; 437 const union rtw89_fw_section_mssc_content *section_content = content; 438 struct rtw89_fw_secure *sec = &rtwdev->fw.sec; 439 u8 byte_idx; 440 u8 bit_mask; 441 442 if (!sec->secure_boot) 443 return 0; 444 445 if (!info->secure_section_exist || section_info->ignore) 446 return 0; 447 448 if (!chip_blacklist) { 449 rtw89_warn(rtwdev, "chip no blacklist for secure firmware\n"); 450 return -ENOENT; 451 } 452 453 byte_idx = section_content->blacklist.bit_in_chip_list >> 3; 454 bit_mask = BIT(section_content->blacklist.bit_in_chip_list & 0x7); 455 456 if (section_content->blacklist.ver > chip_blacklist->ver) { 457 rtw89_warn(rtwdev, "chip blacklist out of date (%u, %u)\n", 458 section_content->blacklist.ver, chip_blacklist->ver); 459 return -EINVAL; 460 } 461 462 if (chip_blacklist->list[byte_idx] & bit_mask) { 463 rtw89_warn(rtwdev, "firmware %u in chip blacklist\n", 464 section_content->blacklist.ver); 465 return -EPERM; 466 } 467 468 return 0; 469 } 470 471 static int __parse_security_section(struct rtw89_dev *rtwdev, 472 struct rtw89_fw_bin_info *info, 473 struct rtw89_fw_hdr_section_info *section_info, 474 const void *content, 475 u32 *mssc_len) 476 { 477 struct rtw89_fw_secure *sec = &rtwdev->fw.sec; 478 int ret; 479 480 if ((section_info->mssc & FORMATTED_MSSC_MASK) == FORMATTED_MSSC) { 481 ret = __parse_formatted_mssc(rtwdev, info, section_info, 482 content, mssc_len); 483 if (ret) 484 return -EINVAL; 485 } else { 486 *mssc_len = section_info->mssc * FWDL_SECURITY_SIGLEN; 487 if (info->dsp_checksum) 488 *mssc_len += section_info->mssc * FWDL_SECURITY_CHKSUM_LEN; 489 490 if (sec->secure_boot) { 491 if (sec->mss_idx >= section_info->mssc) { 492 rtw89_err(rtwdev, "unexpected MSS %d >= %d\n", 493 sec->mss_idx, section_info->mssc); 494 return -EFAULT; 495 } 496 section_info->key_addr = content + section_info->len + 497 sec->mss_idx * FWDL_SECURITY_SIGLEN; 498 section_info->key_len = FWDL_SECURITY_SIGLEN; 499 } 500 501 info->secure_section_exist = true; 502 } 503 504 ret = __check_secure_blacklist(rtwdev, info, section_info, content); 505 WARN_ONCE(ret, "Current firmware in blacklist. Please update firmware.\n"); 506 507 return 0; 508 } 509 510 static int rtw89_fw_hdr_parser_v1(struct rtw89_dev *rtwdev, const u8 *fw, u32 len, 511 struct rtw89_fw_bin_info *info) 512 { 513 const struct rtw89_fw_hdr_v1 *fw_hdr = (const struct rtw89_fw_hdr_v1 *)fw; 514 const struct rtw89_chip_info *chip = rtwdev->chip; 515 struct rtw89_fw_hdr_section_info *section_info; 516 const struct rtw89_fw_dynhdr_hdr *fwdynhdr; 517 const struct rtw89_fw_hdr_section_v1 *section; 518 const u8 *fw_end = fw + len; 519 const u8 *bin; 520 u32 base_hdr_len; 521 u32 mssc_len; 522 int ret; 523 u32 i; 524 525 if (len < sizeof(*fw_hdr)) { 526 rtw89_err(rtwdev, "[ERR]fw header truncated\n"); 527 return -EINVAL; 528 } 529 530 info->section_num = le32_get_bits(fw_hdr->w6, FW_HDR_V1_W6_SEC_NUM); 531 if (!info->section_num || info->section_num > FWDL_SECTION_MAX_NUM) { 532 rtw89_err(rtwdev, "[ERR]invalid fw section num %u\n", 533 info->section_num); 534 return -EINVAL; 535 } 536 537 info->dsp_checksum = le32_get_bits(fw_hdr->w6, FW_HDR_V1_W6_DSP_CHKSUM); 538 base_hdr_len = struct_size(fw_hdr, sections, info->section_num); 539 if (base_hdr_len > len) { 540 rtw89_err(rtwdev, "[ERR]fw header truncated\n"); 541 return -EINVAL; 542 } 543 544 info->dynamic_hdr_en = le32_get_bits(fw_hdr->w7, FW_HDR_V1_W7_DYN_HDR); 545 info->idmem_share_mode = le32_get_bits(fw_hdr->w7, FW_HDR_V1_W7_IDMEM_SHARE_MODE); 546 547 if (chip->chip_gen == RTW89_CHIP_AX) 548 info->part_size = FWDL_SECTION_PER_PKT_LEN; 549 else 550 info->part_size = le32_get_bits(fw_hdr->w7, FW_HDR_V1_W7_PART_SIZE); 551 552 if (info->dynamic_hdr_en) { 553 info->hdr_len = le32_get_bits(fw_hdr->w5, FW_HDR_V1_W5_HDR_SIZE); 554 info->dynamic_hdr_len = info->hdr_len - base_hdr_len; 555 fwdynhdr = (const struct rtw89_fw_dynhdr_hdr *)(fw + base_hdr_len); 556 if (le32_to_cpu(fwdynhdr->hdr_len) != info->dynamic_hdr_len) { 557 rtw89_err(rtwdev, "[ERR]invalid fw dynamic header len\n"); 558 return -EINVAL; 559 } 560 } else { 561 info->hdr_len = base_hdr_len; 562 info->dynamic_hdr_len = 0; 563 } 564 565 bin = fw + info->hdr_len; 566 567 /* jump to section header */ 568 section_info = info->section_info; 569 for (i = 0; i < info->section_num; i++) { 570 section = &fw_hdr->sections[i]; 571 572 section_info->type = 573 le32_get_bits(section->w1, FWSECTION_HDR_V1_W1_SECTIONTYPE); 574 section_info->len = 575 le32_get_bits(section->w1, FWSECTION_HDR_V1_W1_SEC_SIZE); 576 if (le32_get_bits(section->w1, FWSECTION_HDR_V1_W1_CHECKSUM)) 577 section_info->len += FWDL_SECTION_CHKSUM_LEN; 578 section_info->redl = le32_get_bits(section->w1, FWSECTION_HDR_V1_W1_REDL); 579 section_info->dladdr = 580 le32_get_bits(section->w0, FWSECTION_HDR_V1_W0_DL_ADDR); 581 section_info->addr = bin; 582 583 if (section_info->type == FWDL_SECURITY_SECTION_TYPE) { 584 section_info->mssc = 585 le32_get_bits(section->w2, FWSECTION_HDR_V1_W2_MSSC); 586 587 ret = __parse_security_section(rtwdev, info, section_info, 588 bin, &mssc_len); 589 if (ret) 590 return ret; 591 } else { 592 section_info->mssc = 0; 593 mssc_len = 0; 594 } 595 596 rtw89_debug(rtwdev, RTW89_DBG_FW, 597 "section[%d] type=%d len=0x%-6x mssc=%d mssc_len=%d addr=%tx\n", 598 i, section_info->type, section_info->len, 599 section_info->mssc, mssc_len, bin - fw); 600 rtw89_debug(rtwdev, RTW89_DBG_FW, 601 " ignore=%d key_addr=%p (0x%tx) key_len=%d key_idx=%d\n", 602 section_info->ignore, section_info->key_addr, 603 section_info->key_addr ? 604 section_info->key_addr - section_info->addr : 0, 605 section_info->key_len, section_info->key_idx); 606 607 bin += section_info->len + mssc_len; 608 section_info++; 609 } 610 611 if (fw_end != bin) { 612 rtw89_err(rtwdev, "[ERR]fw bin size\n"); 613 return -EINVAL; 614 } 615 616 if (!info->secure_section_exist) 617 rtw89_warn(rtwdev, "no firmware secure section\n"); 618 619 return 0; 620 } 621 622 static int rtw89_fw_hdr_parser(struct rtw89_dev *rtwdev, 623 const struct rtw89_fw_suit *fw_suit, 624 struct rtw89_fw_bin_info *info) 625 { 626 const u8 *fw = fw_suit->data; 627 u32 len = fw_suit->size; 628 629 if (!fw || !len) { 630 rtw89_err(rtwdev, "fw type %d isn't recognized\n", fw_suit->type); 631 return -ENOENT; 632 } 633 634 switch (fw_suit->hdr_ver) { 635 case 0: 636 return rtw89_fw_hdr_parser_v0(rtwdev, fw, len, info); 637 case 1: 638 return rtw89_fw_hdr_parser_v1(rtwdev, fw, len, info); 639 default: 640 return -ENOENT; 641 } 642 } 643 644 static 645 const struct rtw89_mfw_hdr *rtw89_mfw_get_hdr_ptr(struct rtw89_dev *rtwdev, 646 const struct firmware *firmware) 647 { 648 const struct rtw89_mfw_hdr *mfw_hdr; 649 650 if (sizeof(*mfw_hdr) > firmware->size) 651 return NULL; 652 653 mfw_hdr = (const struct rtw89_mfw_hdr *)&firmware->data[0]; 654 655 if (mfw_hdr->sig != RTW89_MFW_SIG) 656 return NULL; 657 658 return mfw_hdr; 659 } 660 661 static int rtw89_mfw_validate_hdr(struct rtw89_dev *rtwdev, 662 const struct firmware *firmware, 663 const struct rtw89_mfw_hdr *mfw_hdr) 664 { 665 const void *mfw = firmware->data; 666 u32 mfw_len = firmware->size; 667 u8 fw_nr = mfw_hdr->fw_nr; 668 const void *ptr; 669 670 if (fw_nr == 0) { 671 rtw89_err(rtwdev, "mfw header has no fw entry\n"); 672 return -ENOENT; 673 } 674 675 ptr = &mfw_hdr->info[fw_nr]; 676 677 if (ptr > mfw + mfw_len) { 678 rtw89_err(rtwdev, "mfw header out of address\n"); 679 return -EFAULT; 680 } 681 682 return 0; 683 } 684 685 static 686 int rtw89_mfw_recognize(struct rtw89_dev *rtwdev, enum rtw89_fw_type type, 687 struct rtw89_fw_suit *fw_suit, bool nowarn) 688 { 689 struct rtw89_fw_info *fw_info = &rtwdev->fw; 690 const struct firmware *firmware = fw_info->req.firmware; 691 const struct rtw89_mfw_info *mfw_info = NULL, *tmp; 692 const struct rtw89_mfw_hdr *mfw_hdr; 693 const u8 *mfw = firmware->data; 694 u32 mfw_len = firmware->size; 695 const u8 *mfw_info_ptr; 696 u32 mfw_info_size; 697 int ret; 698 int i; 699 700 mfw_hdr = rtw89_mfw_get_hdr_ptr(rtwdev, firmware); 701 if (!mfw_hdr) { 702 rtw89_debug(rtwdev, RTW89_DBG_FW, "use legacy firmware\n"); 703 /* legacy firmware support normal type only */ 704 if (type != RTW89_FW_NORMAL) 705 return -EINVAL; 706 fw_suit->size = mfw_len; 707 fw_suit->data = rtw89_fw_suit_data_dup_if_needed(rtwdev, fw_suit, mfw); 708 return 0; 709 } 710 711 ret = rtw89_mfw_validate_hdr(rtwdev, firmware, mfw_hdr); 712 if (ret) 713 return ret; 714 715 for (i = 0; i < mfw_hdr->fw_nr; i++) { 716 tmp = &mfw_hdr->info[i]; 717 if (tmp->type != type) 718 continue; 719 720 if (type == RTW89_FW_LOGFMT) { 721 mfw_info = tmp; 722 goto found; 723 } 724 725 /* Version order of WiFi firmware in firmware file are not in order, 726 * pass all firmware to find the equal or less but closest version. 727 */ 728 if (tmp->cv <= rtwdev->hal.cv && !tmp->mp) { 729 if (!mfw_info || mfw_info->cv < tmp->cv) 730 mfw_info = tmp; 731 } 732 } 733 734 if (mfw_info) 735 goto found; 736 737 if (!nowarn) 738 rtw89_err(rtwdev, "no suitable firmware found\n"); 739 return -ENOENT; 740 741 found: 742 mfw_info_ptr = mfw + le32_to_cpu(mfw_info->shift); 743 mfw_info_size = le32_to_cpu(mfw_info->size); 744 745 if (mfw_info_ptr + mfw_info_size > mfw + mfw_len) { 746 rtw89_err(rtwdev, "fw_suit %d out of address\n", type); 747 return -EFAULT; 748 } 749 750 fw_suit->size = mfw_info_size; 751 fw_suit->data = rtw89_fw_suit_data_dup_if_needed(rtwdev, fw_suit, mfw_info_ptr); 752 753 return 0; 754 } 755 756 static u32 rtw89_mfw_get_size(struct rtw89_dev *rtwdev) 757 { 758 struct rtw89_fw_info *fw_info = &rtwdev->fw; 759 const struct firmware *firmware = fw_info->req.firmware; 760 const struct rtw89_mfw_info *mfw_info; 761 const struct rtw89_mfw_hdr *mfw_hdr; 762 u32 size; 763 int ret; 764 765 mfw_hdr = rtw89_mfw_get_hdr_ptr(rtwdev, firmware); 766 if (!mfw_hdr) { 767 rtw89_warn(rtwdev, "not mfw format\n"); 768 return 0; 769 } 770 771 ret = rtw89_mfw_validate_hdr(rtwdev, firmware, mfw_hdr); 772 if (ret) 773 return ret; 774 775 mfw_info = &mfw_hdr->info[mfw_hdr->fw_nr - 1]; 776 size = le32_to_cpu(mfw_info->shift) + le32_to_cpu(mfw_info->size); 777 778 return size; 779 } 780 781 static void rtw89_fw_update_ver_v0(struct rtw89_dev *rtwdev, 782 struct rtw89_fw_suit *fw_suit, 783 const struct rtw89_fw_hdr *hdr) 784 { 785 fw_suit->major_ver = le32_get_bits(hdr->w1, FW_HDR_W1_MAJOR_VERSION); 786 fw_suit->minor_ver = le32_get_bits(hdr->w1, FW_HDR_W1_MINOR_VERSION); 787 fw_suit->sub_ver = le32_get_bits(hdr->w1, FW_HDR_W1_SUBVERSION); 788 fw_suit->sub_idex = le32_get_bits(hdr->w1, FW_HDR_W1_SUBINDEX); 789 fw_suit->commitid = le32_get_bits(hdr->w2, FW_HDR_W2_COMMITID); 790 fw_suit->build_year = le32_get_bits(hdr->w5, FW_HDR_W5_YEAR); 791 fw_suit->build_mon = le32_get_bits(hdr->w4, FW_HDR_W4_MONTH); 792 fw_suit->build_date = le32_get_bits(hdr->w4, FW_HDR_W4_DATE); 793 fw_suit->build_hour = le32_get_bits(hdr->w4, FW_HDR_W4_HOUR); 794 fw_suit->build_min = le32_get_bits(hdr->w4, FW_HDR_W4_MIN); 795 fw_suit->cmd_ver = le32_get_bits(hdr->w7, FW_HDR_W7_CMD_VERSERION); 796 } 797 798 static void rtw89_fw_update_ver_v1(struct rtw89_dev *rtwdev, 799 struct rtw89_fw_suit *fw_suit, 800 const struct rtw89_fw_hdr_v1 *hdr) 801 { 802 fw_suit->major_ver = le32_get_bits(hdr->w1, FW_HDR_V1_W1_MAJOR_VERSION); 803 fw_suit->minor_ver = le32_get_bits(hdr->w1, FW_HDR_V1_W1_MINOR_VERSION); 804 fw_suit->sub_ver = le32_get_bits(hdr->w1, FW_HDR_V1_W1_SUBVERSION); 805 fw_suit->sub_idex = le32_get_bits(hdr->w1, FW_HDR_V1_W1_SUBINDEX); 806 fw_suit->commitid = le32_get_bits(hdr->w2, FW_HDR_V1_W2_COMMITID); 807 fw_suit->build_year = le32_get_bits(hdr->w5, FW_HDR_V1_W5_YEAR); 808 fw_suit->build_mon = le32_get_bits(hdr->w4, FW_HDR_V1_W4_MONTH); 809 fw_suit->build_date = le32_get_bits(hdr->w4, FW_HDR_V1_W4_DATE); 810 fw_suit->build_hour = le32_get_bits(hdr->w4, FW_HDR_V1_W4_HOUR); 811 fw_suit->build_min = le32_get_bits(hdr->w4, FW_HDR_V1_W4_MIN); 812 fw_suit->cmd_ver = le32_get_bits(hdr->w7, FW_HDR_V1_W3_CMD_VERSERION); 813 } 814 815 static int rtw89_fw_update_ver(struct rtw89_dev *rtwdev, 816 enum rtw89_fw_type type, 817 struct rtw89_fw_suit *fw_suit) 818 { 819 const struct rtw89_fw_hdr *v0 = (const struct rtw89_fw_hdr *)fw_suit->data; 820 const struct rtw89_fw_hdr_v1 *v1 = (const struct rtw89_fw_hdr_v1 *)fw_suit->data; 821 struct wiphy *wiphy = rtwdev->hw->wiphy; 822 823 if (type == RTW89_FW_LOGFMT) 824 return 0; 825 826 fw_suit->type = type; 827 fw_suit->hdr_ver = le32_get_bits(v0->w3, FW_HDR_W3_HDR_VER); 828 829 switch (fw_suit->hdr_ver) { 830 case 0: 831 rtw89_fw_update_ver_v0(rtwdev, fw_suit, v0); 832 break; 833 case 1: 834 rtw89_fw_update_ver_v1(rtwdev, fw_suit, v1); 835 break; 836 default: 837 rtw89_err(rtwdev, "Unknown firmware header version %u\n", 838 fw_suit->hdr_ver); 839 return -ENOENT; 840 } 841 842 rtw89_info(rtwdev, 843 "Firmware version %u.%u.%u.%u (%08x), cmd version %u, type %u\n", 844 fw_suit->major_ver, fw_suit->minor_ver, fw_suit->sub_ver, 845 fw_suit->sub_idex, fw_suit->commitid, fw_suit->cmd_ver, type); 846 847 if (type == RTW89_FW_NORMAL || type == RTW89_FW_NORMAL_CE || 848 type == RTW89_FW_NORMAL_B) 849 snprintf(wiphy->fw_version, sizeof(wiphy->fw_version), 850 "%u.%u.%u.%u", 851 fw_suit->major_ver, fw_suit->minor_ver, 852 fw_suit->sub_ver, fw_suit->sub_idex); 853 854 return 0; 855 } 856 857 static 858 int __rtw89_fw_recognize(struct rtw89_dev *rtwdev, enum rtw89_fw_type type, 859 bool nowarn) 860 { 861 struct rtw89_fw_suit *fw_suit = rtw89_fw_suit_get(rtwdev, type); 862 int ret; 863 864 ret = rtw89_mfw_recognize(rtwdev, type, fw_suit, nowarn); 865 if (ret) 866 return ret; 867 868 return rtw89_fw_update_ver(rtwdev, type, fw_suit); 869 } 870 871 static 872 int __rtw89_fw_recognize_from_elm(struct rtw89_dev *rtwdev, 873 const struct rtw89_fw_element_hdr *elm, 874 const union rtw89_fw_element_arg arg) 875 { 876 enum rtw89_fw_type type = arg.fw_type; 877 struct rtw89_hal *hal = &rtwdev->hal; 878 struct rtw89_fw_suit *fw_suit; 879 880 /* Version of BB MCU is in decreasing order in firmware file, so take 881 * first equal or less version, which is equal or less but closest version. 882 */ 883 if (hal->cv < elm->u.bbmcu.cv) 884 return 1; /* ignore this element */ 885 886 fw_suit = rtw89_fw_suit_get(rtwdev, type); 887 if (fw_suit->data) 888 return 1; /* ignore this element (a firmware is taken already) */ 889 890 fw_suit->size = le32_to_cpu(elm->size); 891 fw_suit->data = 892 rtw89_fw_suit_data_dup_if_needed(rtwdev, fw_suit, elm->u.bbmcu.contents); 893 894 return rtw89_fw_update_ver(rtwdev, type, fw_suit); 895 } 896 897 #define __DEF_FW_FEAT_COND(__cond, __op) \ 898 static bool __fw_feat_cond_ ## __cond(u32 suit_ver_code, u32 comp_ver_code) \ 899 { \ 900 return suit_ver_code __op comp_ver_code; \ 901 } 902 903 __DEF_FW_FEAT_COND(ge, >=); /* greater or equal */ 904 __DEF_FW_FEAT_COND(le, <=); /* less or equal */ 905 __DEF_FW_FEAT_COND(lt, <); /* less than */ 906 907 struct __fw_feat_cfg { 908 enum rtw89_core_chip_id chip_id; 909 enum rtw89_fw_feature feature; 910 u32 ver_code; 911 bool (*cond)(u32 suit_ver_code, u32 comp_ver_code); 912 bool disable; 913 int size; 914 }; 915 916 #define __CFG_FW_FEAT(_chip, _cond, _maj, _min, _sub, _idx, _feat) \ 917 { \ 918 .chip_id = _chip, \ 919 .feature = RTW89_FW_FEATURE_ ## _feat, \ 920 .ver_code = RTW89_FW_VER_CODE(_maj, _min, _sub, _idx), \ 921 .cond = __fw_feat_cond_ ## _cond, \ 922 } 923 924 #define __S_DIS_FW_FEAT(_chip, _cond, _maj, _min, _sub, _idx, _feat) \ 925 { \ 926 .chip_id = _chip, \ 927 .feature = RTW89_FW_FEATURE_ ## _feat, \ 928 .ver_code = RTW89_FW_VER_CODE(_maj, _min, _sub, _idx), \ 929 .cond = __fw_feat_cond_ ## _cond, \ 930 .disable = true, \ 931 .size = 1, \ 932 } 933 934 #define __G_DIS_FW_FEAT(_chip, _cond, _maj, _min, _sub, _idx, _grp) \ 935 { \ 936 .chip_id = _chip, \ 937 .feature = RTW89_FW_FEATURE_ ## _grp ## _MIN, \ 938 .ver_code = RTW89_FW_VER_CODE(_maj, _min, _sub, _idx), \ 939 .cond = __fw_feat_cond_ ## _cond, \ 940 .disable = true, \ 941 .size = RTW89_FW_FEATURE_ ## _grp ## _MAX - \ 942 RTW89_FW_FEATURE_ ## _grp ## _MIN + 1, \ 943 } 944 945 #define __DIS_FW_FEAT(_chip, _cond, _maj, _min, _sub, _idx, _feat, _type) \ 946 __##_type##_DIS_FW_FEAT(_chip, _cond, _maj, _min, _sub, _idx, _feat) 947 948 static const struct __fw_feat_cfg fw_feat_tbl[] = { 949 __CFG_FW_FEAT(RTL8851B, ge, 0, 29, 37, 1, TX_WAKE), 950 __CFG_FW_FEAT(RTL8851B, ge, 0, 29, 37, 1, SCAN_OFFLOAD), 951 __CFG_FW_FEAT(RTL8851B, ge, 0, 29, 41, 0, CRASH_TRIGGER_TYPE_0), 952 __CFG_FW_FEAT(RTL8851B, lt, 0, 29, 57, 0, NO_WOW_CPU_IO_RX), 953 __CFG_FW_FEAT(RTL8851B, ge, 0, 29, 127, 0, SER_L1_BY_EVENT), 954 __CFG_FW_FEAT(RTL8851B, ge, 0, 29, 130, 0, SIM_SER_L0L1_BY_HALT_H2C), 955 __CFG_FW_FEAT(RTL8852A, le, 0, 13, 29, 0, OLD_HT_RA_FORMAT), 956 __CFG_FW_FEAT(RTL8852A, ge, 0, 13, 35, 0, SCAN_OFFLOAD), 957 __CFG_FW_FEAT(RTL8852A, ge, 0, 13, 35, 0, TX_WAKE), 958 __CFG_FW_FEAT(RTL8852A, ge, 0, 13, 36, 0, CRASH_TRIGGER_TYPE_0), 959 __CFG_FW_FEAT(RTL8852A, lt, 0, 13, 37, 0, NO_WOW_CPU_IO_RX), 960 __CFG_FW_FEAT(RTL8852A, lt, 0, 13, 38, 0, NO_PACKET_DROP), 961 __CFG_FW_FEAT(RTL8852B, ge, 0, 29, 26, 0, NO_LPS_PG), 962 __CFG_FW_FEAT(RTL8852B, ge, 0, 29, 26, 0, TX_WAKE), 963 __CFG_FW_FEAT(RTL8852B, ge, 0, 29, 29, 0, CRASH_TRIGGER_TYPE_0), 964 __CFG_FW_FEAT(RTL8852B, ge, 0, 29, 29, 0, SCAN_OFFLOAD), 965 __CFG_FW_FEAT(RTL8852B, ge, 0, 29, 29, 7, BEACON_FILTER), 966 __CFG_FW_FEAT(RTL8852B, ge, 0, 29, 29, 15, BEACON_LOSS_COUNT_V1), 967 __CFG_FW_FEAT(RTL8852B, lt, 0, 29, 30, 0, NO_WOW_CPU_IO_RX), 968 __CFG_FW_FEAT(RTL8852B, ge, 0, 29, 127, 0, LPS_DACK_BY_C2H_REG), 969 __CFG_FW_FEAT(RTL8852B, ge, 0, 29, 127, 0, SER_L1_BY_EVENT), 970 __CFG_FW_FEAT(RTL8852B, ge, 0, 29, 128, 0, CRASH_TRIGGER_TYPE_1), 971 __CFG_FW_FEAT(RTL8852B, ge, 0, 29, 128, 0, SCAN_OFFLOAD_EXTRA_OP), 972 __CFG_FW_FEAT(RTL8852B, ge, 0, 29, 128, 0, BEACON_TRACKING), 973 __CFG_FW_FEAT(RTL8852B, ge, 0, 29, 130, 0, SIM_SER_L0L1_BY_HALT_H2C), 974 __CFG_FW_FEAT(RTL8852BT, ge, 0, 29, 74, 0, NO_LPS_PG), 975 __CFG_FW_FEAT(RTL8852BT, ge, 0, 29, 74, 0, TX_WAKE), 976 __CFG_FW_FEAT(RTL8852BT, ge, 0, 29, 90, 0, CRASH_TRIGGER_TYPE_0), 977 __CFG_FW_FEAT(RTL8852BT, ge, 0, 29, 91, 0, SCAN_OFFLOAD), 978 __CFG_FW_FEAT(RTL8852BT, ge, 0, 29, 110, 0, BEACON_FILTER), 979 __CFG_FW_FEAT(RTL8852BT, ge, 0, 29, 122, 0, BEACON_TRACKING), 980 __CFG_FW_FEAT(RTL8852BT, ge, 0, 29, 127, 0, SCAN_OFFLOAD_EXTRA_OP), 981 __CFG_FW_FEAT(RTL8852BT, ge, 0, 29, 127, 0, LPS_DACK_BY_C2H_REG), 982 __CFG_FW_FEAT(RTL8852BT, ge, 0, 29, 127, 0, CRASH_TRIGGER_TYPE_1), 983 __CFG_FW_FEAT(RTL8852BT, ge, 0, 29, 127, 0, SER_L1_BY_EVENT), 984 __CFG_FW_FEAT(RTL8852BT, ge, 0, 29, 130, 0, SIM_SER_L0L1_BY_HALT_H2C), 985 __CFG_FW_FEAT(RTL8852C, ge, 0, 0, 0, 0, RFK_NTFY_MCC_V0), 986 __CFG_FW_FEAT(RTL8852C, le, 0, 27, 33, 0, NO_DEEP_PS), 987 __CFG_FW_FEAT(RTL8852C, ge, 0, 27, 34, 0, TX_WAKE), 988 __CFG_FW_FEAT(RTL8852C, ge, 0, 27, 36, 0, SCAN_OFFLOAD), 989 __CFG_FW_FEAT(RTL8852C, ge, 0, 27, 40, 0, CRASH_TRIGGER_TYPE_0), 990 __CFG_FW_FEAT(RTL8852C, ge, 0, 27, 56, 10, BEACON_FILTER), 991 __CFG_FW_FEAT(RTL8852C, ge, 0, 27, 80, 0, WOW_REASON_V1), 992 __CFG_FW_FEAT(RTL8852C, ge, 0, 27, 128, 0, BEACON_LOSS_COUNT_V1), 993 __CFG_FW_FEAT(RTL8852C, ge, 0, 27, 128, 0, LPS_DACK_BY_C2H_REG), 994 __CFG_FW_FEAT(RTL8852C, ge, 0, 27, 128, 0, CRASH_TRIGGER_TYPE_1), 995 __CFG_FW_FEAT(RTL8852C, ge, 0, 27, 129, 1, BEACON_TRACKING), 996 __CFG_FW_FEAT(RTL8852C, ge, 0, 29, 94, 0, SER_L1_BY_EVENT), 997 __CFG_FW_FEAT(RTL8852C, ge, 0, 29, 130, 0, SIM_SER_L0L1_BY_HALT_H2C), 998 __CFG_FW_FEAT(RTL8922A, ge, 0, 0, 0, 0, RFK_PRE_NOTIFY_V0), 999 __CFG_FW_FEAT(RTL8922A, ge, 0, 34, 11, 0, MACID_PAUSE_SLEEP), 1000 __CFG_FW_FEAT(RTL8922A, ge, 0, 34, 30, 0, CRASH_TRIGGER_TYPE_0), 1001 __CFG_FW_FEAT(RTL8922A, ge, 0, 34, 35, 0, SCAN_OFFLOAD), 1002 __CFG_FW_FEAT(RTL8922A, ge, 0, 34, 35, 0, SCAN_OFFLOAD_EXTRA_OP), 1003 __CFG_FW_FEAT(RTL8922A, ge, 0, 35, 12, 0, BEACON_FILTER), 1004 __CFG_FW_FEAT(RTL8922A, lt, 0, 35, 21, 0, SCAN_OFFLOAD_BE_V0), 1005 __CFG_FW_FEAT(RTL8922A, ge, 0, 35, 22, 0, WOW_REASON_V1), 1006 __CFG_FW_FEAT(RTL8922A, lt, 0, 35, 28, 0, RFK_IQK_V0), 1007 __CFG_FW_FEAT(RTL8922A, ge, 0, 35, 31, 0, RFK_PRE_NOTIFY_V1), 1008 __CFG_FW_FEAT(RTL8922A, lt, 0, 35, 31, 0, LPS_CH_INFO), 1009 __CFG_FW_FEAT(RTL8922A, lt, 0, 35, 42, 0, RFK_RXDCK_V0), 1010 __CFG_FW_FEAT(RTL8922A, ge, 0, 35, 46, 0, NOTIFY_AP_INFO), 1011 __CFG_FW_FEAT(RTL8922A, lt, 0, 35, 47, 0, CH_INFO_BE_V0), 1012 __CFG_FW_FEAT(RTL8922A, ge, 0, 35, 49, 0, RFK_PRE_NOTIFY_V2), 1013 __CFG_FW_FEAT(RTL8922A, ge, 0, 35, 49, 0, RFK_PRE_NOTIFY_MCC_V0), 1014 __CFG_FW_FEAT(RTL8922A, lt, 0, 35, 51, 0, NO_PHYCAP_P1), 1015 __CFG_FW_FEAT(RTL8922A, lt, 0, 35, 64, 0, NO_POWER_DIFFERENCE), 1016 __CFG_FW_FEAT(RTL8922A, ge, 0, 35, 71, 0, BEACON_LOSS_COUNT_V1), 1017 __CFG_FW_FEAT(RTL8922A, ge, 0, 35, 76, 0, LPS_DACK_BY_C2H_REG), 1018 __CFG_FW_FEAT(RTL8922A, ge, 0, 35, 79, 0, CRASH_TRIGGER_TYPE_1), 1019 __CFG_FW_FEAT(RTL8922A, ge, 0, 35, 80, 0, BEACON_TRACKING), 1020 __DIS_FW_FEAT(RTL8922A, ge, 0, 35, 84, 0, WITH_RFK_PRE_NOTIFY, G), 1021 __CFG_FW_FEAT(RTL8922A, ge, 0, 35, 84, 0, RFK_PRE_NOTIFY_MCC_V1), 1022 __CFG_FW_FEAT(RTL8922A, lt, 0, 35, 84, 0, ADDR_CAM_V0), 1023 __CFG_FW_FEAT(RTL8922A, ge, 0, 35, 92, 0, TX_HISTORY_V1), 1024 __CFG_FW_FEAT(RTL8922A, ge, 0, 35, 100, 0, SER_POST_RECOVER_DMAC), 1025 __CFG_FW_FEAT(RTL8922A, ge, 0, 35, 108, 0, SIM_SER_L0L1_BY_HALT_H2C), 1026 __CFG_FW_FEAT(RTL8922A, lt, 0, 35, 109, 1, SCAN_OFFLOAD_BE_V1), 1027 __CFG_FW_FEAT(RTL8922A, lt, 0, 35, 113, 2, SCAN_OFFLOAD_BE_V2), 1028 __CFG_FW_FEAT(RTL8922A, lt, 0, 35, 119, 0, CH_INFO_BE_V1), 1029 __CFG_FW_FEAT(RTL8922A, lt, 0, 35, 119, 3, NO_DRV_BT_TXRX_EN), 1030 __CFG_FW_FEAT(RTL8922D, ge, 0, 0, 0, 0, MACID_PAUSE_SLEEP), 1031 __CFG_FW_FEAT(RTL8922D, ge, 0, 35, 75, 2, SCAN_OFFLOAD), 1032 __CFG_FW_FEAT(RTL8922D, ge, 0, 35, 75, 2, BEACON_FILTER), 1033 __CFG_FW_FEAT(RTL8922D, ge, 0, 35, 76, 0, LPS_DACK_BY_C2H_REG), 1034 __CFG_FW_FEAT(RTL8922D, ge, 0, 35, 84, 0, CRASH_TRIGGER_TYPE_1), 1035 __CFG_FW_FEAT(RTL8922D, lt, 0, 35, 84, 0, ADDR_CAM_V0), 1036 __CFG_FW_FEAT(RTL8922D, ge, 0, 35, 87, 0, BEACON_LOSS_COUNT_V1), 1037 __CFG_FW_FEAT(RTL8922D, ge, 0, 35, 91, 0, RFK_PRE_NOTIFY_MCC_V2), 1038 __CFG_FW_FEAT(RTL8922D, ge, 0, 35, 91, 4, LPS_ML_INFO_V1), 1039 __CFG_FW_FEAT(RTL8922D, ge, 0, 35, 93, 0, NOTIFY_AP_INFO), 1040 __CFG_FW_FEAT(RTL8922D, ge, 0, 35, 100, 0, SER_POST_RECOVER_DMAC), 1041 __CFG_FW_FEAT(RTL8922D, ge, 0, 35, 104, 0, TX_HISTORY_V1), 1042 __CFG_FW_FEAT(RTL8922D, ge, 0, 35, 108, 0, SIM_SER_L0L1_BY_HALT_H2C), 1043 __CFG_FW_FEAT(RTL8922D, lt, 0, 35, 109, 1, SCAN_OFFLOAD_BE_V1), 1044 __CFG_FW_FEAT(RTL8922D, lt, 0, 35, 113, 0, RFK_TXIQK_V0), 1045 __CFG_FW_FEAT(RTL8922D, lt, 0, 35, 113, 2, SCAN_OFFLOAD_BE_V2), 1046 __CFG_FW_FEAT(RTL8922D, ge, 0, 35, 119, 0, LPS_ML_INFO_V1_EXTRA), 1047 __CFG_FW_FEAT(RTL8922D, lt, 0, 35, 119, 0, CH_INFO_BE_V1), 1048 __CFG_FW_FEAT(RTL8922D, lt, 0, 35, 119, 3, NO_DRV_BT_TXRX_EN), 1049 }; 1050 1051 static void rtw89_fw_iterate_feature_cfg(struct rtw89_fw_info *fw, 1052 const struct rtw89_chip_info *chip, 1053 u32 ver_code) 1054 { 1055 int i; 1056 1057 for (i = 0; i < ARRAY_SIZE(fw_feat_tbl); i++) { 1058 const struct __fw_feat_cfg *ent = &fw_feat_tbl[i]; 1059 1060 if (chip->chip_id != ent->chip_id) 1061 continue; 1062 1063 if (!ent->cond(ver_code, ent->ver_code)) 1064 continue; 1065 1066 if (!ent->disable) { 1067 RTW89_SET_FW_FEATURE(ent->feature, fw); 1068 continue; 1069 } 1070 1071 for (int n = 0; n < ent->size; n++) 1072 RTW89_CLR_FW_FEATURE(ent->feature + n, fw); 1073 } 1074 } 1075 1076 static void rtw89_fw_recognize_features(struct rtw89_dev *rtwdev) 1077 { 1078 const struct rtw89_chip_info *chip = rtwdev->chip; 1079 const struct rtw89_fw_suit *fw_suit; 1080 u32 suit_ver_code; 1081 1082 fw_suit = rtw89_fw_suit_get(rtwdev, RTW89_FW_NORMAL); 1083 suit_ver_code = RTW89_FW_SUIT_VER_CODE(fw_suit); 1084 1085 rtw89_fw_iterate_feature_cfg(&rtwdev->fw, chip, suit_ver_code); 1086 } 1087 1088 const struct firmware * 1089 rtw89_early_fw_feature_recognize(struct device *device, 1090 const struct rtw89_chip_info *chip, 1091 const struct rtw89_chip_variant *variant, 1092 struct rtw89_fw_info *early_fw, 1093 int *used_fw_format) 1094 { 1095 const struct rtw89_fw_def *fw_def = __rtw89_chip_get_fw_def(chip, variant); 1096 const struct firmware *firmware; 1097 char fw_name[64]; 1098 int fw_format; 1099 u32 ver_code; 1100 int ret; 1101 1102 for (fw_format = fw_def->fw_format_max; fw_format >= 0; fw_format--) { 1103 rtw89_fw_get_filename(fw_name, sizeof(fw_name), 1104 fw_def->fw_basename, fw_format); 1105 1106 ret = request_firmware(&firmware, fw_name, device); 1107 if (!ret) { 1108 dev_info(device, "loaded firmware %s\n", fw_name); 1109 *used_fw_format = fw_format; 1110 break; 1111 } 1112 } 1113 1114 if (ret) { 1115 dev_err(device, "failed to early request firmware: %d\n", ret); 1116 return NULL; 1117 } 1118 1119 ver_code = rtw89_compat_fw_hdr_ver_code(firmware->data); 1120 1121 if (!ver_code) 1122 goto out; 1123 1124 rtw89_fw_iterate_feature_cfg(early_fw, chip, ver_code); 1125 1126 out: 1127 return firmware; 1128 } 1129 1130 static int rtw89_fw_validate_ver_required(struct rtw89_dev *rtwdev) 1131 { 1132 const struct rtw89_chip_variant *variant = rtwdev->variant; 1133 const struct rtw89_fw_suit *fw_suit; 1134 u32 suit_ver_code; 1135 1136 if (!variant) 1137 return 0; 1138 1139 fw_suit = rtw89_fw_suit_get(rtwdev, RTW89_FW_NORMAL); 1140 suit_ver_code = RTW89_FW_SUIT_VER_CODE(fw_suit); 1141 1142 if (variant->fw_min_ver_code > suit_ver_code) { 1143 rtw89_err(rtwdev, "minimum required firmware version is 0x%x\n", 1144 variant->fw_min_ver_code); 1145 return -ENOENT; 1146 } 1147 1148 return 0; 1149 } 1150 1151 int rtw89_fw_recognize(struct rtw89_dev *rtwdev) 1152 { 1153 const struct rtw89_fw_def *fw_def = rtw89_chip_get_fw_def(rtwdev); 1154 const struct rtw89_chip_info *chip = rtwdev->chip; 1155 const struct rtw89_hal *hal = &rtwdev->hal; 1156 enum rtw89_fw_type normal_fw_type = RTW89_FW_NORMAL; 1157 enum rtw89_fw_type wowlan_fw_type = RTW89_FW_WOWLAN; 1158 int ret; 1159 1160 if (fw_def->fw_b_aid && fw_def->fw_b_aid == hal->aid) { 1161 normal_fw_type = RTW89_FW_NORMAL_B; 1162 wowlan_fw_type = RTW89_FW_WOWLAN_B; 1163 } 1164 1165 if (chip->try_ce_fw) { 1166 ret = __rtw89_fw_recognize(rtwdev, RTW89_FW_NORMAL_CE, true); 1167 if (!ret) 1168 goto normal_done; 1169 } 1170 1171 ret = __rtw89_fw_recognize(rtwdev, normal_fw_type, false); 1172 if (ret) 1173 return ret; 1174 1175 normal_done: 1176 ret = rtw89_fw_validate_ver_required(rtwdev); 1177 if (ret) 1178 return ret; 1179 1180 /* It still works if wowlan firmware isn't existing. */ 1181 __rtw89_fw_recognize(rtwdev, wowlan_fw_type, false); 1182 1183 /* It still works if log format file isn't existing. */ 1184 __rtw89_fw_recognize(rtwdev, RTW89_FW_LOGFMT, true); 1185 1186 rtw89_fw_recognize_features(rtwdev); 1187 1188 rtw89_coex_recognize_ver(rtwdev); 1189 1190 return 0; 1191 } 1192 1193 static 1194 int rtw89_build_phy_tbl_from_elm(struct rtw89_dev *rtwdev, 1195 const struct rtw89_fw_element_hdr *elm, 1196 const union rtw89_fw_element_arg arg) 1197 { 1198 struct rtw89_fw_elm_info *elm_info = &rtwdev->fw.elm_info; 1199 const struct rtw89_chip_info *chip = rtwdev->chip; 1200 struct rtw89_hal *hal = &rtwdev->hal; 1201 struct rtw89_phy_table *tbl, **pp; 1202 struct rtw89_reg2_def *regs; 1203 bool radio = false; 1204 u32 n_regs, i; 1205 u16 aid; 1206 u8 idx; 1207 1208 switch (le32_to_cpu(elm->id)) { 1209 case RTW89_FW_ELEMENT_ID_BB_REG: 1210 pp = &elm_info->bb_tbl; 1211 break; 1212 case RTW89_FW_ELEMENT_ID_BB_GAIN: 1213 pp = &elm_info->bb_gain; 1214 break; 1215 case RTW89_FW_ELEMENT_ID_RADIO_A: 1216 case RTW89_FW_ELEMENT_ID_RADIO_B: 1217 case RTW89_FW_ELEMENT_ID_RADIO_C: 1218 case RTW89_FW_ELEMENT_ID_RADIO_D: 1219 idx = elm->u.reg2.idx; 1220 pp = &elm_info->rf_radio[idx]; 1221 1222 radio = true; 1223 break; 1224 case RTW89_FW_ELEMENT_ID_RF_NCTL: 1225 pp = &elm_info->rf_nctl; 1226 break; 1227 default: 1228 return -ENOENT; 1229 } 1230 1231 aid = le16_to_cpu(elm->aid); 1232 if (aid && aid != hal->aid) 1233 return 1; /* ignore if aid not matched */ 1234 else if (*pp) 1235 return 1; /* ignore if an element is existing */ 1236 1237 tbl = kzalloc_obj(*tbl); 1238 if (!tbl) 1239 return -ENOMEM; 1240 1241 n_regs = le32_to_cpu(elm->size) / sizeof(tbl->regs[0]); 1242 regs = kzalloc_objs(*regs, n_regs); 1243 if (!regs) 1244 goto out; 1245 1246 for (i = 0; i < n_regs; i++) { 1247 regs[i].addr = le32_to_cpu(elm->u.reg2.regs[i].addr); 1248 regs[i].data = le32_to_cpu(elm->u.reg2.regs[i].data); 1249 } 1250 1251 tbl->n_regs = n_regs; 1252 tbl->regs = regs; 1253 1254 if (radio) { 1255 tbl->rf_path = arg.rf_path; 1256 tbl->config = chip->chip_id == RTL8852A ? 1257 rtw89_phy_config_rf_reg : 1258 rtw89_phy_config_rf_reg_v1; 1259 } 1260 1261 *pp = tbl; 1262 1263 return 0; 1264 1265 out: 1266 kfree(tbl); 1267 return -ENOMEM; 1268 } 1269 1270 static 1271 int rtw89_fw_recognize_txpwr_from_elm(struct rtw89_dev *rtwdev, 1272 const struct rtw89_fw_element_hdr *elm, 1273 const union rtw89_fw_element_arg arg) 1274 { 1275 const struct __rtw89_fw_txpwr_element *txpwr_elm = &elm->u.txpwr; 1276 const unsigned long offset = arg.offset; 1277 struct rtw89_efuse *efuse = &rtwdev->efuse; 1278 struct rtw89_hal *hal = &rtwdev->hal; 1279 u16 aid = le16_to_cpu(elm->aid); 1280 struct rtw89_txpwr_conf *conf; 1281 1282 if (aid && aid != hal->aid) 1283 return 1; 1284 1285 if (!rtwdev->rfe_data) { 1286 rtwdev->rfe_data = kzalloc_obj(*rtwdev->rfe_data); 1287 if (!rtwdev->rfe_data) 1288 return -ENOMEM; 1289 } 1290 1291 conf = (void *)rtwdev->rfe_data + offset; 1292 1293 /* if multiple matched, take the last eventually */ 1294 if (txpwr_elm->rfe_type == efuse->rfe_type) 1295 goto setup; 1296 1297 /* without one is matched, accept default */ 1298 if (txpwr_elm->rfe_type == RTW89_TXPWR_CONF_DFLT_RFE_TYPE && 1299 (!rtw89_txpwr_conf_valid(conf) || 1300 conf->rfe_type == RTW89_TXPWR_CONF_DFLT_RFE_TYPE)) 1301 goto setup; 1302 1303 rtw89_debug(rtwdev, RTW89_DBG_FW, "skip txpwr element ID %u RFE %u\n", 1304 elm->id, txpwr_elm->rfe_type); 1305 return 0; 1306 1307 setup: 1308 rtw89_debug(rtwdev, RTW89_DBG_FW, "take txpwr element ID %u RFE %u\n", 1309 elm->id, txpwr_elm->rfe_type); 1310 1311 conf->rfe_type = txpwr_elm->rfe_type; 1312 conf->ent_sz = txpwr_elm->ent_sz; 1313 conf->num_ents = le32_to_cpu(txpwr_elm->num_ents); 1314 /* 1315 * The conf->data is used by rtw89_core_setup_rfe_parms() to do format 1316 * conversion before releasing firmware. No need to duplicate. 1317 */ 1318 conf->data = txpwr_elm->content; 1319 1320 return 0; 1321 } 1322 1323 static 1324 int rtw89_build_txpwr_trk_tbl_from_elm(struct rtw89_dev *rtwdev, 1325 const struct rtw89_fw_element_hdr *elm, 1326 const union rtw89_fw_element_arg arg) 1327 { 1328 struct rtw89_fw_elm_info *elm_info = &rtwdev->fw.elm_info; 1329 const struct rtw89_chip_info *chip = rtwdev->chip; 1330 const struct rtw89_fw_element_hdr *elm_dup; 1331 struct rtw89_hal *hal = &rtwdev->hal; 1332 u16 aid = le16_to_cpu(elm->aid); 1333 u32 needed_bitmap = 0; 1334 u32 offset = 0; 1335 int subband; 1336 u32 bitmap; 1337 int type; 1338 1339 if (aid && aid != hal->aid) 1340 return 1; 1341 1342 if (chip->support_bands & BIT(NL80211_BAND_6GHZ)) 1343 needed_bitmap |= RTW89_DEFAULT_NEEDED_FW_TXPWR_TRK_6GHZ; 1344 if (chip->support_bands & BIT(NL80211_BAND_5GHZ)) 1345 needed_bitmap |= RTW89_DEFAULT_NEEDED_FW_TXPWR_TRK_5GHZ; 1346 if (chip->support_bands & BIT(NL80211_BAND_2GHZ)) 1347 needed_bitmap |= RTW89_DEFAULT_NEEDED_FW_TXPWR_TRK_2GHZ; 1348 1349 bitmap = le32_to_cpu(elm->u.txpwr_trk.bitmap); 1350 1351 if ((bitmap & needed_bitmap) != needed_bitmap) { 1352 rtw89_warn(rtwdev, "needed txpwr trk bitmap %08x but %08x\n", 1353 needed_bitmap, bitmap); 1354 return -ENOENT; 1355 } 1356 1357 elm_info->txpwr_trk = kzalloc_obj(*elm_info->txpwr_trk); 1358 if (!elm_info->txpwr_trk) 1359 return -ENOMEM; 1360 1361 elm_dup = rtw89_fw_elem_dup_if_needed(rtwdev, elm); 1362 1363 for (type = 0; bitmap; type++, bitmap >>= 1) { 1364 if (!(bitmap & BIT(0))) 1365 continue; 1366 1367 if (type >= __RTW89_FW_TXPWR_TRK_TYPE_6GHZ_START && 1368 type <= __RTW89_FW_TXPWR_TRK_TYPE_6GHZ_MAX) 1369 subband = 4; 1370 else if (type >= __RTW89_FW_TXPWR_TRK_TYPE_5GHZ_START && 1371 type <= __RTW89_FW_TXPWR_TRK_TYPE_5GHZ_MAX) 1372 subband = 3; 1373 else if (type >= __RTW89_FW_TXPWR_TRK_TYPE_2GHZ_START && 1374 type <= __RTW89_FW_TXPWR_TRK_TYPE_2GHZ_MAX) 1375 subband = 1; 1376 else 1377 break; 1378 1379 elm_info->txpwr_trk->delta[type] = &elm_dup->u.txpwr_trk.contents[offset]; 1380 1381 offset += subband; 1382 if (offset * DELTA_SWINGIDX_SIZE > le32_to_cpu(elm_dup->size)) 1383 goto err; 1384 } 1385 1386 return 0; 1387 1388 err: 1389 rtw89_warn(rtwdev, "unexpected txpwr trk offset %d over size %d\n", 1390 offset, le32_to_cpu(elm->size)); 1391 kfree(elm_info->txpwr_trk); 1392 elm_info->txpwr_trk = NULL; 1393 1394 return -EFAULT; 1395 } 1396 1397 static 1398 int rtw89_build_rfk_log_fmt_from_elm(struct rtw89_dev *rtwdev, 1399 const struct rtw89_fw_element_hdr *elm, 1400 const union rtw89_fw_element_arg arg) 1401 { 1402 struct rtw89_fw_elm_info *elm_info = &rtwdev->fw.elm_info; 1403 u8 rfk_id; 1404 1405 if (elm_info->rfk_log_fmt) 1406 goto allocated; 1407 1408 elm_info->rfk_log_fmt = kzalloc_obj(*elm_info->rfk_log_fmt); 1409 if (!elm_info->rfk_log_fmt) 1410 return 1; /* this is an optional element, so just ignore this */ 1411 1412 allocated: 1413 rfk_id = elm->u.rfk_log_fmt.rfk_id; 1414 if (rfk_id >= RTW89_PHY_C2H_RFK_LOG_FUNC_NUM) 1415 return 1; 1416 1417 elm_info->rfk_log_fmt->elm[rfk_id] = rtw89_fw_elem_dup_if_needed(rtwdev, elm); 1418 1419 return 0; 1420 } 1421 1422 static bool rtw89_regd_entcpy(struct rtw89_regd *regd, const void *cursor, 1423 u8 cursor_size) 1424 { 1425 /* fill default values if needed for backward compatibility */ 1426 struct rtw89_fw_regd_entry entry = { 1427 .rule_2ghz = RTW89_NA, 1428 .rule_5ghz = RTW89_NA, 1429 .rule_6ghz = RTW89_NA, 1430 .fmap = cpu_to_le32(0x0), 1431 }; 1432 u8 valid_size = min_t(u8, sizeof(entry), cursor_size); 1433 unsigned int i; 1434 u32 fmap; 1435 1436 memcpy(&entry, cursor, valid_size); 1437 memset(regd, 0, sizeof(*regd)); 1438 1439 regd->alpha2[0] = entry.alpha2_0; 1440 regd->alpha2[1] = entry.alpha2_1; 1441 regd->alpha2[2] = '\0'; 1442 1443 /* also need to consider forward compatibility */ 1444 regd->txpwr_regd[RTW89_BAND_2G] = entry.rule_2ghz < RTW89_REGD_NUM ? 1445 entry.rule_2ghz : RTW89_NA; 1446 regd->txpwr_regd[RTW89_BAND_5G] = entry.rule_5ghz < RTW89_REGD_NUM ? 1447 entry.rule_5ghz : RTW89_NA; 1448 regd->txpwr_regd[RTW89_BAND_6G] = entry.rule_6ghz < RTW89_REGD_NUM ? 1449 entry.rule_6ghz : RTW89_NA; 1450 1451 BUILD_BUG_ON(sizeof(fmap) != sizeof(entry.fmap)); 1452 BUILD_BUG_ON(sizeof(fmap) * 8 < NUM_OF_RTW89_REGD_FUNC); 1453 1454 fmap = le32_to_cpu(entry.fmap); 1455 for (i = 0; i < NUM_OF_RTW89_REGD_FUNC; i++) { 1456 if (fmap & BIT(i)) 1457 set_bit(i, regd->func_bitmap); 1458 } 1459 1460 return true; 1461 } 1462 1463 #define rtw89_for_each_in_regd_element(regd, element) \ 1464 for (const void *cursor = (element)->content, \ 1465 *end = (element)->content + \ 1466 le32_to_cpu((element)->num_ents) * (element)->ent_sz; \ 1467 cursor < end; cursor += (element)->ent_sz) \ 1468 if (rtw89_regd_entcpy(regd, cursor, (element)->ent_sz)) 1469 1470 static 1471 int rtw89_recognize_regd_from_elm(struct rtw89_dev *rtwdev, 1472 const struct rtw89_fw_element_hdr *elm, 1473 const union rtw89_fw_element_arg arg) 1474 { 1475 const struct __rtw89_fw_regd_element *regd_elm = &elm->u.regd; 1476 struct rtw89_fw_elm_info *elm_info = &rtwdev->fw.elm_info; 1477 u32 num_ents = le32_to_cpu(regd_elm->num_ents); 1478 struct rtw89_regd_data *p; 1479 struct rtw89_regd regd; 1480 u32 i = 0; 1481 1482 if (num_ents > RTW89_REGD_MAX_COUNTRY_NUM) { 1483 rtw89_warn(rtwdev, 1484 "regd element ents (%d) are over max num (%d)\n", 1485 num_ents, RTW89_REGD_MAX_COUNTRY_NUM); 1486 rtw89_warn(rtwdev, 1487 "regd element ignore and take another/common\n"); 1488 return 1; 1489 } 1490 1491 if (elm_info->regd) { 1492 rtw89_debug(rtwdev, RTW89_DBG_REGD, 1493 "regd element take the latter\n"); 1494 devm_kfree(rtwdev->dev, elm_info->regd); 1495 elm_info->regd = NULL; 1496 } 1497 1498 p = devm_kzalloc(rtwdev->dev, struct_size(p, map, num_ents), GFP_KERNEL); 1499 if (!p) 1500 return -ENOMEM; 1501 1502 p->nr = num_ents; 1503 rtw89_for_each_in_regd_element(®d, regd_elm) 1504 p->map[i++] = regd; 1505 1506 if (i != num_ents) { 1507 rtw89_err(rtwdev, "regd element has %d invalid ents\n", 1508 num_ents - i); 1509 devm_kfree(rtwdev->dev, p); 1510 return -EINVAL; 1511 } 1512 1513 elm_info->regd = p; 1514 return 0; 1515 } 1516 1517 static 1518 int rtw89_build_afe_pwr_seq_from_elm(struct rtw89_dev *rtwdev, 1519 const struct rtw89_fw_element_hdr *elm, 1520 const union rtw89_fw_element_arg arg) 1521 { 1522 struct rtw89_fw_elm_info *elm_info = &rtwdev->fw.elm_info; 1523 1524 elm_info->afe = rtw89_fw_elem_dup_if_needed(rtwdev, elm); 1525 1526 return 0; 1527 } 1528 1529 static 1530 int rtw89_recognize_diag_mac_from_elm(struct rtw89_dev *rtwdev, 1531 const struct rtw89_fw_element_hdr *elm, 1532 const union rtw89_fw_element_arg arg) 1533 { 1534 struct rtw89_fw_elm_info *elm_info = &rtwdev->fw.elm_info; 1535 1536 elm_info->diag_mac = rtw89_fw_elem_dup_if_needed(rtwdev, elm); 1537 1538 return 0; 1539 } 1540 1541 static 1542 int rtw89_build_tx_comp_from_elm(struct rtw89_dev *rtwdev, 1543 const struct rtw89_fw_element_hdr *elm, 1544 const union rtw89_fw_element_arg arg) 1545 { 1546 struct rtw89_fw_elm_info *elm_info = &rtwdev->fw.elm_info; 1547 struct rtw89_efuse *efuse = &rtwdev->efuse; 1548 struct rtw89_hal *hal = &rtwdev->hal; 1549 u8 rfe_type; 1550 u16 aid; 1551 1552 aid = le16_to_cpu(elm->aid); 1553 rfe_type = elm->u.tx_comp.rfe_type; 1554 1555 if (aid && aid != hal->aid) 1556 return 1; /* ignore if aid not matched */ 1557 else if (rfe_type && rfe_type != efuse->rfe_type) 1558 return 1; /* ignore if rfe_type not matched */ 1559 else if (elm_info->tx_comp) 1560 return 1; /* ignore if an element is existing */ 1561 1562 elm_info->tx_comp = rtw89_fw_elem_dup_if_needed(rtwdev, elm); 1563 1564 return 0; 1565 } 1566 1567 static const struct rtw89_fw_element_handler __fw_element_handlers[] = { 1568 [RTW89_FW_ELEMENT_ID_BBMCU0] = {__rtw89_fw_recognize_from_elm, 1569 { .fw_type = RTW89_FW_BBMCU0 }, NULL}, 1570 [RTW89_FW_ELEMENT_ID_BBMCU1] = {__rtw89_fw_recognize_from_elm, 1571 { .fw_type = RTW89_FW_BBMCU1 }, NULL}, 1572 [RTW89_FW_ELEMENT_ID_BB_REG] = {rtw89_build_phy_tbl_from_elm, {}, "BB"}, 1573 [RTW89_FW_ELEMENT_ID_BB_GAIN] = {rtw89_build_phy_tbl_from_elm, {}, NULL}, 1574 [RTW89_FW_ELEMENT_ID_RADIO_A] = {rtw89_build_phy_tbl_from_elm, 1575 { .rf_path = RF_PATH_A }, "radio A"}, 1576 [RTW89_FW_ELEMENT_ID_RADIO_B] = {rtw89_build_phy_tbl_from_elm, 1577 { .rf_path = RF_PATH_B }, NULL}, 1578 [RTW89_FW_ELEMENT_ID_RADIO_C] = {rtw89_build_phy_tbl_from_elm, 1579 { .rf_path = RF_PATH_C }, NULL}, 1580 [RTW89_FW_ELEMENT_ID_RADIO_D] = {rtw89_build_phy_tbl_from_elm, 1581 { .rf_path = RF_PATH_D }, NULL}, 1582 [RTW89_FW_ELEMENT_ID_RF_NCTL] = {rtw89_build_phy_tbl_from_elm, {}, "NCTL"}, 1583 [RTW89_FW_ELEMENT_ID_TXPWR_BYRATE] = { 1584 rtw89_fw_recognize_txpwr_from_elm, 1585 { .offset = offsetof(struct rtw89_rfe_data, byrate.conf) }, "TXPWR", 1586 }, 1587 [RTW89_FW_ELEMENT_ID_TXPWR_LMT_2GHZ] = { 1588 rtw89_fw_recognize_txpwr_from_elm, 1589 { .offset = offsetof(struct rtw89_rfe_data, lmt_2ghz.conf) }, NULL, 1590 }, 1591 [RTW89_FW_ELEMENT_ID_TXPWR_LMT_5GHZ] = { 1592 rtw89_fw_recognize_txpwr_from_elm, 1593 { .offset = offsetof(struct rtw89_rfe_data, lmt_5ghz.conf) }, NULL, 1594 }, 1595 [RTW89_FW_ELEMENT_ID_TXPWR_LMT_6GHZ] = { 1596 rtw89_fw_recognize_txpwr_from_elm, 1597 { .offset = offsetof(struct rtw89_rfe_data, lmt_6ghz.conf) }, NULL, 1598 }, 1599 [RTW89_FW_ELEMENT_ID_TXPWR_DA_LMT_2GHZ] = { 1600 rtw89_fw_recognize_txpwr_from_elm, 1601 { .offset = offsetof(struct rtw89_rfe_data, da_lmt_2ghz.conf) }, NULL, 1602 }, 1603 [RTW89_FW_ELEMENT_ID_TXPWR_DA_LMT_5GHZ] = { 1604 rtw89_fw_recognize_txpwr_from_elm, 1605 { .offset = offsetof(struct rtw89_rfe_data, da_lmt_5ghz.conf) }, NULL, 1606 }, 1607 [RTW89_FW_ELEMENT_ID_TXPWR_DA_LMT_6GHZ] = { 1608 rtw89_fw_recognize_txpwr_from_elm, 1609 { .offset = offsetof(struct rtw89_rfe_data, da_lmt_6ghz.conf) }, NULL, 1610 }, 1611 [RTW89_FW_ELEMENT_ID_TXPWR_LMT_RU_2GHZ] = { 1612 rtw89_fw_recognize_txpwr_from_elm, 1613 { .offset = offsetof(struct rtw89_rfe_data, lmt_ru_2ghz.conf) }, NULL, 1614 }, 1615 [RTW89_FW_ELEMENT_ID_TXPWR_LMT_RU_5GHZ] = { 1616 rtw89_fw_recognize_txpwr_from_elm, 1617 { .offset = offsetof(struct rtw89_rfe_data, lmt_ru_5ghz.conf) }, NULL, 1618 }, 1619 [RTW89_FW_ELEMENT_ID_TXPWR_LMT_RU_6GHZ] = { 1620 rtw89_fw_recognize_txpwr_from_elm, 1621 { .offset = offsetof(struct rtw89_rfe_data, lmt_ru_6ghz.conf) }, NULL, 1622 }, 1623 [RTW89_FW_ELEMENT_ID_TXPWR_DA_LMT_RU_2GHZ] = { 1624 rtw89_fw_recognize_txpwr_from_elm, 1625 { .offset = offsetof(struct rtw89_rfe_data, da_lmt_ru_2ghz.conf) }, NULL, 1626 }, 1627 [RTW89_FW_ELEMENT_ID_TXPWR_DA_LMT_RU_5GHZ] = { 1628 rtw89_fw_recognize_txpwr_from_elm, 1629 { .offset = offsetof(struct rtw89_rfe_data, da_lmt_ru_5ghz.conf) }, NULL, 1630 }, 1631 [RTW89_FW_ELEMENT_ID_TXPWR_DA_LMT_RU_6GHZ] = { 1632 rtw89_fw_recognize_txpwr_from_elm, 1633 { .offset = offsetof(struct rtw89_rfe_data, da_lmt_ru_6ghz.conf) }, NULL, 1634 }, 1635 [RTW89_FW_ELEMENT_ID_TX_SHAPE_LMT] = { 1636 rtw89_fw_recognize_txpwr_from_elm, 1637 { .offset = offsetof(struct rtw89_rfe_data, tx_shape_lmt.conf) }, NULL, 1638 }, 1639 [RTW89_FW_ELEMENT_ID_TX_SHAPE_LMT_RU] = { 1640 rtw89_fw_recognize_txpwr_from_elm, 1641 { .offset = offsetof(struct rtw89_rfe_data, tx_shape_lmt_ru.conf) }, NULL, 1642 }, 1643 [RTW89_FW_ELEMENT_ID_TXPWR_TRK] = { 1644 rtw89_build_txpwr_trk_tbl_from_elm, {}, "PWR_TRK", 1645 }, 1646 [RTW89_FW_ELEMENT_ID_RFKLOG_FMT] = { 1647 rtw89_build_rfk_log_fmt_from_elm, {}, NULL, 1648 }, 1649 [RTW89_FW_ELEMENT_ID_REGD] = { 1650 rtw89_recognize_regd_from_elm, {}, "REGD", 1651 }, 1652 [RTW89_FW_ELEMENT_ID_AFE_PWR_SEQ] = { 1653 rtw89_build_afe_pwr_seq_from_elm, {}, "AFE", 1654 }, 1655 [RTW89_FW_ELEMENT_ID_DIAG_MAC] = { 1656 rtw89_recognize_diag_mac_from_elm, {}, NULL, 1657 }, 1658 [RTW89_FW_ELEMENT_ID_TX_COMP] = { 1659 rtw89_build_tx_comp_from_elm, {}, NULL, 1660 }, 1661 }; 1662 1663 static int __rtw89_fw_recognize_elements(struct rtw89_dev *rtwdev, 1664 const struct firmware *firmware, 1665 u32 offset, u32 skipped_elements, 1666 u32 *unrecognized_elements) 1667 { 1668 const struct rtw89_fw_element_handler *handler; 1669 const struct rtw89_fw_element_hdr *hdr; 1670 u32 elm_size; 1671 u32 elem_id; 1672 int ret; 1673 1674 while (offset + sizeof(*hdr) < firmware->size) { 1675 hdr = (const struct rtw89_fw_element_hdr *)(firmware->data + offset); 1676 1677 elm_size = le32_to_cpu(hdr->size); 1678 if (offset + elm_size >= firmware->size) { 1679 rtw89_warn(rtwdev, "firmware element size exceeds\n"); 1680 break; 1681 } 1682 1683 elem_id = le32_to_cpu(hdr->id); 1684 if (elem_id >= ARRAY_SIZE(__fw_element_handlers)) 1685 goto next; 1686 if (skipped_elements & BIT(elem_id)) 1687 goto next; 1688 1689 handler = &__fw_element_handlers[elem_id]; 1690 if (!handler->fn) 1691 goto next; 1692 1693 ret = handler->fn(rtwdev, hdr, handler->arg); 1694 if (ret == 1) /* ignore this element */ 1695 goto next; 1696 if (ret) 1697 return ret; 1698 1699 if (handler->name) 1700 rtw89_info(rtwdev, "Firmware element %s version: %4ph\n", 1701 handler->name, hdr->ver); 1702 1703 *unrecognized_elements &= ~BIT(elem_id); 1704 next: 1705 offset += sizeof(*hdr) + elm_size; 1706 offset = ALIGN(offset, RTW89_FW_ELEMENT_ALIGN); 1707 } 1708 1709 return 0; 1710 } 1711 1712 static int rtw89_board_elm_seek(const struct firmware *board_elm, 1713 enum rtw89_board_id board_id, 1714 struct firmware *pseudo_fw) 1715 { 1716 const struct rtw89_board_elm_hdr *hdr; 1717 const struct rtw89_board_elm_ent *ent; 1718 u32 ofst; 1719 u32 size; 1720 u16 num; 1721 1722 if (board_elm->size < sizeof(*hdr)) 1723 return -EINVAL; 1724 1725 hdr = (const struct rtw89_board_elm_hdr *)board_elm->data; 1726 if (hdr->sig != RTW89_BOARD_ELM_SIG) 1727 return -EINVAL; 1728 1729 BUILD_BUG_ON(U16_MAX < NUM_OF_RTW89_BOARD_IDS); 1730 1731 num = le16_to_cpu(hdr->num); 1732 if (unlikely(board_elm->size < struct_size(hdr, ents, num))) 1733 return -EFAULT; 1734 if (num <= board_id) 1735 return -ENOENT; 1736 1737 ent = &hdr->ents[board_id]; 1738 1739 ofst = le32_to_cpu(ent->ofst); 1740 size = le32_to_cpu(ent->size); 1741 1742 if (unlikely(board_elm->size < ofst + size)) 1743 return -EFAULT; 1744 1745 memset(pseudo_fw, 0, sizeof(*pseudo_fw)); 1746 1747 pseudo_fw->data = (const void *)board_elm->data + ofst; 1748 pseudo_fw->size = size; 1749 1750 return 0; 1751 } 1752 1753 int rtw89_fw_recognize_elements(struct rtw89_dev *rtwdev) 1754 { 1755 const struct rtw89_board_variant *board = rtwdev->board; 1756 struct rtw89_fw_req_info *fw_req = &rtwdev->fw.req; 1757 const struct firmware *firmware = fw_req->firmware; 1758 const struct rtw89_chip_info *chip = rtwdev->chip; 1759 u32 unrecognized_elements = chip->needed_fw_elms; 1760 u32 skipped_elements = 0; 1761 bool transition; 1762 u32 offset; 1763 int ret; 1764 1765 BUILD_BUG_ON(sizeof(chip->needed_fw_elms) * 8 < RTW89_FW_ELEMENT_ID_NUM); 1766 BUILD_BUG_ON(!__same_type(unrecognized_elements, chip->needed_fw_elms)); 1767 BUILD_BUG_ON(!__same_type(skipped_elements, chip->needed_fw_elms)); 1768 1769 transition = !!((chip->needed_fw_elms & BIT(__RTW89_FW_ELEMENT_ID_INTL_TRANSITION))); 1770 unrecognized_elements &= ~BIT(__RTW89_FW_ELEMENT_ID_INTL_TRANSITION); 1771 1772 if (fw_req->board_elm) { 1773 struct firmware pseudo_fw; 1774 1775 ret = rtw89_board_elm_seek(fw_req->board_elm, board->id, &pseudo_fw); 1776 if (ret) 1777 goto mfw; 1778 1779 ret = __rtw89_fw_recognize_elements(rtwdev, &pseudo_fw, 0, 0, 1780 &unrecognized_elements); 1781 if (ret) 1782 goto mfw; 1783 1784 skipped_elements = chip->needed_fw_elms & ~unrecognized_elements; 1785 1786 rtw89_debug(rtwdev, RTW89_DBG_FW, "apply elements 0x08%x from %s\n", 1787 skipped_elements, RTW89_FWNAME_BOARD_ELM); 1788 } 1789 1790 mfw: 1791 offset = rtw89_mfw_get_size(rtwdev); 1792 offset = ALIGN(offset, RTW89_FW_ELEMENT_ALIGN); 1793 if (offset == 0) 1794 return -EINVAL; 1795 1796 ret = __rtw89_fw_recognize_elements(rtwdev, firmware, offset, 1797 skipped_elements, 1798 &unrecognized_elements); 1799 if (ret) 1800 return ret; 1801 1802 if (unrecognized_elements) { 1803 if (transition) { 1804 rtw89_info(rtwdev, "NOTE: This firmware is going to be obsolete!\n" 1805 "Please download the latest firmware from https://gitlab.com/kernel-firmware/linux-firmware.git\n"); 1806 return 0; 1807 } 1808 1809 rtw89_err(rtwdev, "Firmware elements 0x%08x are unrecognized\n", 1810 unrecognized_elements); 1811 return -ENOENT; 1812 } 1813 1814 return 0; 1815 } 1816 1817 void rtw89_h2c_pkt_set_hdr(struct rtw89_dev *rtwdev, struct sk_buff *skb, 1818 u8 type, u8 cat, u8 class, u8 func, 1819 bool rack, bool dack, u32 len) 1820 { 1821 const struct rtw89_chip_info *chip = rtwdev->chip; 1822 struct fwcmd_hdr *hdr; 1823 1824 hdr = (struct fwcmd_hdr *)skb_push(skb, 8); 1825 1826 if (chip->chip_gen == RTW89_CHIP_AX && !(rtwdev->fw.h2c_seq % 4)) 1827 rack = true; 1828 hdr->hdr0 = cpu_to_le32(FIELD_PREP(H2C_HDR_DEL_TYPE, type) | 1829 FIELD_PREP(H2C_HDR_CAT, cat) | 1830 FIELD_PREP(H2C_HDR_CLASS, class) | 1831 FIELD_PREP(H2C_HDR_FUNC, func) | 1832 FIELD_PREP(H2C_HDR_H2C_SEQ, rtwdev->fw.h2c_seq)); 1833 1834 hdr->hdr1 = cpu_to_le32(FIELD_PREP(H2C_HDR_TOTAL_LEN, 1835 len + H2C_HEADER_LEN) | 1836 (rack ? H2C_HDR_REC_ACK : 0) | 1837 (dack ? H2C_HDR_DONE_ACK : 0)); 1838 1839 rtwdev->fw.h2c_seq++; 1840 } 1841 1842 static void rtw89_h2c_pkt_set_hdr_fwdl(struct rtw89_dev *rtwdev, 1843 struct sk_buff *skb, 1844 u8 type, u8 cat, u8 class, u8 func, 1845 u32 len) 1846 { 1847 struct fwcmd_hdr *hdr; 1848 1849 hdr = (struct fwcmd_hdr *)skb_push(skb, 8); 1850 1851 hdr->hdr0 = cpu_to_le32(FIELD_PREP(H2C_HDR_DEL_TYPE, type) | 1852 FIELD_PREP(H2C_HDR_CAT, cat) | 1853 FIELD_PREP(H2C_HDR_CLASS, class) | 1854 FIELD_PREP(H2C_HDR_FUNC, func) | 1855 FIELD_PREP(H2C_HDR_H2C_SEQ, rtwdev->fw.h2c_seq)); 1856 1857 hdr->hdr1 = cpu_to_le32(FIELD_PREP(H2C_HDR_TOTAL_LEN, 1858 len + H2C_HEADER_LEN)); 1859 } 1860 1861 static u32 __rtw89_fw_download_tweak_hdr_v0(struct rtw89_dev *rtwdev, 1862 struct rtw89_fw_bin_info *info, 1863 struct rtw89_fw_hdr *fw_hdr) 1864 { 1865 struct rtw89_fw_hdr_section_info *section_info; 1866 struct rtw89_fw_hdr_section *section; 1867 int i; 1868 1869 le32p_replace_bits(&fw_hdr->w7, info->part_size, FW_HDR_W7_PART_SIZE); 1870 1871 for (i = 0; i < info->section_num; i++) { 1872 section_info = &info->section_info[i]; 1873 1874 if (!section_info->len_override) 1875 continue; 1876 1877 section = &fw_hdr->sections[i]; 1878 le32p_replace_bits(§ion->w1, section_info->len_override, 1879 FWSECTION_HDR_W1_SEC_SIZE); 1880 } 1881 1882 return 0; 1883 } 1884 1885 static u32 __rtw89_fw_download_tweak_hdr_v1(struct rtw89_dev *rtwdev, 1886 struct rtw89_fw_bin_info *info, 1887 struct rtw89_fw_hdr_v1 *fw_hdr) 1888 { 1889 struct rtw89_fw_hdr_section_info *section_info; 1890 struct rtw89_fw_hdr_section_v1 *section; 1891 u8 dst_sec_idx = 0; 1892 u8 sec_idx; 1893 1894 le32p_replace_bits(&fw_hdr->w7, info->part_size, FW_HDR_V1_W7_PART_SIZE); 1895 1896 for (sec_idx = 0; sec_idx < info->section_num; sec_idx++) { 1897 section_info = &info->section_info[sec_idx]; 1898 section = &fw_hdr->sections[sec_idx]; 1899 1900 if (section_info->ignore) 1901 continue; 1902 1903 if (dst_sec_idx != sec_idx) 1904 fw_hdr->sections[dst_sec_idx] = *section; 1905 1906 dst_sec_idx++; 1907 } 1908 1909 le32p_replace_bits(&fw_hdr->w6, dst_sec_idx, FW_HDR_V1_W6_SEC_NUM); 1910 1911 return (info->section_num - dst_sec_idx) * sizeof(*section); 1912 } 1913 1914 static int __rtw89_fw_download_hdr(struct rtw89_dev *rtwdev, 1915 const struct rtw89_fw_suit *fw_suit, 1916 struct rtw89_fw_bin_info *info) 1917 { 1918 u32 len = info->hdr_len - info->dynamic_hdr_len; 1919 struct rtw89_fw_hdr_v1 *fw_hdr_v1; 1920 const u8 *fw = fw_suit->data; 1921 struct rtw89_fw_hdr *fw_hdr; 1922 struct sk_buff *skb; 1923 u32 truncated; 1924 int ret; 1925 1926 skb = rtw89_fw_h2c_alloc_skb_with_hdr(rtwdev, len); 1927 if (!skb) { 1928 rtw89_err(rtwdev, "failed to alloc skb for fw hdr dl\n"); 1929 return -ENOMEM; 1930 } 1931 1932 skb_put_data(skb, fw, len); 1933 1934 switch (fw_suit->hdr_ver) { 1935 case 0: 1936 fw_hdr = (struct rtw89_fw_hdr *)skb->data; 1937 truncated = __rtw89_fw_download_tweak_hdr_v0(rtwdev, info, fw_hdr); 1938 break; 1939 case 1: 1940 fw_hdr_v1 = (struct rtw89_fw_hdr_v1 *)skb->data; 1941 truncated = __rtw89_fw_download_tweak_hdr_v1(rtwdev, info, fw_hdr_v1); 1942 break; 1943 default: 1944 ret = -EOPNOTSUPP; 1945 goto fail; 1946 } 1947 1948 if (truncated) { 1949 len -= truncated; 1950 skb_trim(skb, len); 1951 } 1952 1953 rtw89_h2c_pkt_set_hdr_fwdl(rtwdev, skb, FWCMD_TYPE_H2C, 1954 H2C_CAT_MAC, H2C_CL_MAC_FWDL, 1955 H2C_FUNC_MAC_FWHDR_DL, len); 1956 1957 ret = rtw89_h2c_tx(rtwdev, skb, false); 1958 if (ret) { 1959 rtw89_err(rtwdev, "failed to send h2c\n"); 1960 goto fail; 1961 } 1962 1963 return 0; 1964 fail: 1965 dev_kfree_skb_any(skb); 1966 1967 return ret; 1968 } 1969 1970 static int rtw89_fw_download_hdr(struct rtw89_dev *rtwdev, 1971 const struct rtw89_fw_suit *fw_suit, 1972 struct rtw89_fw_bin_info *info) 1973 { 1974 const struct rtw89_mac_gen_def *mac = rtwdev->chip->mac_def; 1975 int ret; 1976 1977 ret = __rtw89_fw_download_hdr(rtwdev, fw_suit, info); 1978 if (ret) { 1979 rtw89_err(rtwdev, "[ERR]FW header download\n"); 1980 return ret; 1981 } 1982 1983 ret = mac->fwdl_check_path_ready(rtwdev, false); 1984 if (ret) { 1985 rtw89_err(rtwdev, "[ERR]FWDL path ready\n"); 1986 return ret; 1987 } 1988 1989 rtw89_write32(rtwdev, R_AX_HALT_H2C_CTRL, 0); 1990 rtw89_write32(rtwdev, R_AX_HALT_C2H_CTRL, 0); 1991 1992 return 0; 1993 } 1994 1995 static int __rtw89_fw_download_main(struct rtw89_dev *rtwdev, 1996 struct rtw89_fw_hdr_section_info *info, 1997 u32 part_size) 1998 { 1999 struct sk_buff *skb; 2000 const u8 *section = info->addr; 2001 u32 residue_len = info->len; 2002 bool copy_key = false; 2003 u32 pkt_len; 2004 int ret; 2005 2006 if (info->ignore) 2007 return 0; 2008 2009 if (info->len_override) { 2010 if (info->len_override > info->len) 2011 rtw89_warn(rtwdev, "override length %u larger than original %u\n", 2012 info->len_override, info->len); 2013 else 2014 residue_len = info->len_override; 2015 } 2016 2017 if (info->key_addr && info->key_len) { 2018 if (residue_len > part_size || info->len < info->key_len) 2019 rtw89_warn(rtwdev, 2020 "ignore to copy key data because of len %d, %d, %d, %d\n", 2021 info->len, part_size, 2022 info->key_len, residue_len); 2023 else 2024 copy_key = true; 2025 } 2026 2027 while (residue_len) { 2028 pkt_len = min(residue_len, part_size); 2029 2030 skb = rtw89_fw_h2c_alloc_skb_no_hdr(rtwdev, pkt_len); 2031 if (!skb) { 2032 rtw89_err(rtwdev, "failed to alloc skb for fw dl\n"); 2033 return -ENOMEM; 2034 } 2035 skb_put_data(skb, section, pkt_len); 2036 2037 if (copy_key) 2038 memcpy(skb->data + pkt_len - info->key_len, 2039 info->key_addr, info->key_len); 2040 2041 ret = rtw89_h2c_tx(rtwdev, skb, true); 2042 if (ret) { 2043 rtw89_err(rtwdev, "failed to send h2c\n"); 2044 goto fail; 2045 } 2046 2047 section += pkt_len; 2048 residue_len -= pkt_len; 2049 } 2050 2051 return 0; 2052 fail: 2053 dev_kfree_skb_any(skb); 2054 2055 return ret; 2056 } 2057 2058 static enum rtw89_fwdl_check_type 2059 rtw89_fw_get_fwdl_chk_type_from_suit(struct rtw89_dev *rtwdev, 2060 const struct rtw89_fw_suit *fw_suit) 2061 { 2062 switch (fw_suit->type) { 2063 case RTW89_FW_BBMCU0: 2064 return RTW89_FWDL_CHECK_BB0_FWDL_DONE; 2065 case RTW89_FW_BBMCU1: 2066 return RTW89_FWDL_CHECK_BB1_FWDL_DONE; 2067 default: 2068 return RTW89_FWDL_CHECK_WCPU_FWDL_DONE; 2069 } 2070 } 2071 2072 static int rtw89_fw_download_main(struct rtw89_dev *rtwdev, 2073 const struct rtw89_fw_suit *fw_suit, 2074 struct rtw89_fw_bin_info *info) 2075 { 2076 struct rtw89_fw_hdr_section_info *section_info = info->section_info; 2077 const struct rtw89_chip_info *chip = rtwdev->chip; 2078 enum rtw89_fwdl_check_type chk_type; 2079 u8 section_num = info->section_num; 2080 int ret; 2081 2082 while (section_num--) { 2083 ret = __rtw89_fw_download_main(rtwdev, section_info, info->part_size); 2084 if (ret) 2085 return ret; 2086 section_info++; 2087 } 2088 2089 if (chip->chip_gen == RTW89_CHIP_AX) 2090 return 0; 2091 2092 chk_type = rtw89_fw_get_fwdl_chk_type_from_suit(rtwdev, fw_suit); 2093 ret = rtw89_fw_check_rdy(rtwdev, chk_type); 2094 if (ret) { 2095 rtw89_warn(rtwdev, "failed to download firmware type %u\n", 2096 fw_suit->type); 2097 return ret; 2098 } 2099 2100 return 0; 2101 } 2102 2103 static void rtw89_fw_prog_cnt_dump(struct rtw89_dev *rtwdev) 2104 { 2105 enum rtw89_chip_gen chip_gen = rtwdev->chip->chip_gen; 2106 u32 addr = R_AX_DBG_PORT_SEL; 2107 u32 val32; 2108 u16 index; 2109 2110 if (chip_gen == RTW89_CHIP_BE) { 2111 addr = R_BE_WLCPU_PORT_PC; 2112 goto dump; 2113 } 2114 2115 rtw89_write32(rtwdev, R_AX_DBG_CTRL, 2116 FIELD_PREP(B_AX_DBG_SEL0, FW_PROG_CNTR_DBG_SEL) | 2117 FIELD_PREP(B_AX_DBG_SEL1, FW_PROG_CNTR_DBG_SEL)); 2118 rtw89_write32_mask(rtwdev, R_AX_SYS_STATUS1, B_AX_SEL_0XC0_MASK, MAC_DBG_SEL); 2119 2120 dump: 2121 for (index = 0; index < 15; index++) { 2122 val32 = rtw89_read32(rtwdev, addr); 2123 rtw89_err(rtwdev, "[ERR]fw PC = 0x%x\n", val32); 2124 fsleep(10); 2125 } 2126 } 2127 2128 static void rtw89_fw_dl_fail_dump(struct rtw89_dev *rtwdev) 2129 { 2130 const struct rtw89_mac_gen_def *mac = rtwdev->chip->mac_def; 2131 u32 val32; 2132 2133 val32 = rtw89_read32(rtwdev, R_AX_WCPU_FW_CTRL); 2134 rtw89_err(rtwdev, "[ERR]fwdl 0x1E0 = 0x%x\n", val32); 2135 2136 val32 = rtw89_read32(rtwdev, mac->boot_dbg); 2137 rtw89_err(rtwdev, "[ERR]fwdl 0x%x = 0x%x\n", mac->boot_dbg, val32); 2138 2139 rtw89_fw_prog_cnt_dump(rtwdev); 2140 } 2141 2142 static int rtw89_fw_download_suit(struct rtw89_dev *rtwdev, 2143 struct rtw89_fw_suit *fw_suit) 2144 { 2145 const struct rtw89_mac_gen_def *mac = rtwdev->chip->mac_def; 2146 struct rtw89_fw_bin_info info = {}; 2147 int ret; 2148 2149 ret = rtw89_fw_hdr_parser(rtwdev, fw_suit, &info); 2150 if (ret) { 2151 rtw89_err(rtwdev, "parse fw header fail\n"); 2152 return ret; 2153 } 2154 2155 rtw89_fwdl_secure_idmem_share_mode(rtwdev, info.idmem_share_mode); 2156 2157 if (rtwdev->chip->chip_id == RTL8922A && 2158 (fw_suit->type == RTW89_FW_NORMAL || fw_suit->type == RTW89_FW_WOWLAN)) 2159 rtw89_write32(rtwdev, R_BE_SECURE_BOOT_MALLOC_INFO, 0x20248000); 2160 2161 ret = mac->fwdl_check_path_ready(rtwdev, true); 2162 if (ret) { 2163 rtw89_err(rtwdev, "[ERR]H2C path ready\n"); 2164 return ret; 2165 } 2166 2167 ret = rtw89_fw_download_hdr(rtwdev, fw_suit, &info); 2168 if (ret) 2169 return ret; 2170 2171 ret = rtw89_fw_download_main(rtwdev, fw_suit, &info); 2172 if (ret) 2173 return ret; 2174 2175 return 0; 2176 } 2177 2178 static 2179 int __rtw89_fw_download(struct rtw89_dev *rtwdev, enum rtw89_fw_type type, 2180 bool include_bb) 2181 { 2182 const struct rtw89_mac_gen_def *mac = rtwdev->chip->mac_def; 2183 struct rtw89_fw_info *fw_info = &rtwdev->fw; 2184 struct rtw89_fw_suit *fw_suit = rtw89_fw_suit_get(rtwdev, type); 2185 u8 bbmcu_nr = rtwdev->chip->bbmcu_nr; 2186 int ret; 2187 int i; 2188 2189 mac->disable_cpu(rtwdev); 2190 ret = mac->fwdl_enable_wcpu(rtwdev, 0, true, include_bb); 2191 if (ret) 2192 return ret; 2193 2194 ret = rtw89_fw_download_suit(rtwdev, fw_suit); 2195 if (ret) 2196 goto fwdl_err; 2197 2198 for (i = 0; i < bbmcu_nr && include_bb; i++) { 2199 fw_suit = rtw89_fw_suit_get(rtwdev, RTW89_FW_BBMCU0 + i); 2200 2201 ret = rtw89_fw_download_suit(rtwdev, fw_suit); 2202 if (ret) 2203 goto fwdl_err; 2204 } 2205 2206 fw_info->h2c_seq = 0; 2207 fw_info->rec_seq = 0; 2208 fw_info->h2c_counter = 0; 2209 fw_info->c2h_counter = 0; 2210 rtwdev->mac.rpwm_seq_num = RPWM_SEQ_NUM_MAX; 2211 rtwdev->mac.cpwm_seq_num = CPWM_SEQ_NUM_MAX; 2212 2213 mdelay(5); 2214 2215 ret = rtw89_fw_check_rdy(rtwdev, RTW89_FWDL_CHECK_FREERTOS_DONE); 2216 if (ret) { 2217 rtw89_warn(rtwdev, "download firmware fail\n"); 2218 goto fwdl_err; 2219 } 2220 2221 return ret; 2222 2223 fwdl_err: 2224 rtw89_fw_dl_fail_dump(rtwdev); 2225 return ret; 2226 } 2227 2228 int rtw89_fw_download(struct rtw89_dev *rtwdev, enum rtw89_fw_type type, 2229 bool include_bb) 2230 { 2231 int retry; 2232 int ret; 2233 2234 for (retry = 0; retry < 5; retry++) { 2235 ret = __rtw89_fw_download(rtwdev, type, include_bb); 2236 if (!ret) 2237 return 0; 2238 } 2239 2240 return ret; 2241 } 2242 2243 int rtw89_wait_firmware_completion(struct rtw89_dev *rtwdev) 2244 { 2245 struct rtw89_fw_info *fw = &rtwdev->fw; 2246 2247 wait_for_completion(&fw->req.completion); 2248 if (!fw->req.firmware) 2249 return -EINVAL; 2250 2251 return 0; 2252 } 2253 2254 static int rtw89_load_firmware_req(struct rtw89_dev *rtwdev, 2255 struct rtw89_fw_req_info *req, 2256 const char *fw_name, bool nowarn) 2257 { 2258 const struct rtw89_board_variant *board = rtwdev->board; 2259 int ret = 0; 2260 2261 if (req->firmware) { 2262 rtw89_debug(rtwdev, RTW89_DBG_FW, 2263 "full firmware has been early requested\n"); 2264 goto out; 2265 } 2266 2267 if (nowarn) 2268 ret = firmware_request_nowarn(&req->firmware, fw_name, rtwdev->dev); 2269 else 2270 ret = request_firmware(&req->firmware, fw_name, rtwdev->dev); 2271 2272 out: 2273 if (board && board->id) 2274 firmware_request_nowarn(&req->board_elm, RTW89_FWNAME_BOARD_ELM, rtwdev->dev); 2275 2276 req->free_after_probe = req->firmware && req->firmware->size > 0x200000; 2277 complete_all(&req->completion); 2278 2279 return ret; 2280 } 2281 2282 void rtw89_load_firmware_work(struct work_struct *work) 2283 { 2284 struct rtw89_dev *rtwdev = 2285 container_of(work, struct rtw89_dev, load_firmware_work); 2286 const struct rtw89_fw_def *fw_def = rtw89_chip_get_fw_def(rtwdev); 2287 char fw_name[64]; 2288 2289 rtw89_fw_get_filename(fw_name, sizeof(fw_name), 2290 fw_def->fw_basename, rtwdev->fw.fw_format); 2291 2292 rtw89_load_firmware_req(rtwdev, &rtwdev->fw.req, fw_name, false); 2293 } 2294 2295 static void rtw89_free_phy_tbl_from_elm(struct rtw89_phy_table *tbl) 2296 { 2297 if (!tbl) 2298 return; 2299 2300 kfree(tbl->regs); 2301 kfree(tbl); 2302 } 2303 2304 static void rtw89_unload_firmware_elements(struct rtw89_dev *rtwdev) 2305 { 2306 struct rtw89_fw_elm_info *elm_info = &rtwdev->fw.elm_info; 2307 int i; 2308 2309 rtw89_free_phy_tbl_from_elm(elm_info->bb_tbl); 2310 rtw89_free_phy_tbl_from_elm(elm_info->bb_gain); 2311 for (i = 0; i < ARRAY_SIZE(elm_info->rf_radio); i++) 2312 rtw89_free_phy_tbl_from_elm(elm_info->rf_radio[i]); 2313 rtw89_free_phy_tbl_from_elm(elm_info->rf_nctl); 2314 2315 kfree(elm_info->txpwr_trk); 2316 kfree(elm_info->rfk_log_fmt); 2317 } 2318 2319 static void rtw89_unload_firmware_dup_data(struct rtw89_dev *rtwdev) 2320 { 2321 struct rtw89_fw_info *fw = &rtwdev->fw; 2322 struct rtw89_fw_suit *fw_suit; 2323 2324 list_for_each_entry(fw_suit, &fw->dup_data_list, list) 2325 vfree(fw_suit->data); 2326 } 2327 2328 void __rtw89_unload_firmware(struct rtw89_dev *rtwdev) 2329 { 2330 struct rtw89_fw_info *fw = &rtwdev->fw; 2331 2332 release_firmware(fw->req.firmware); 2333 release_firmware(fw->req.board_elm); 2334 2335 /* 2336 * Directly call this to free firmware early in normal flow. Assign 2337 * NULL back in case rtw89_free_ieee80211_hw() or tw89_core_deinit() 2338 * try to release the same one again in error handling paths. 2339 */ 2340 fw->req.firmware = NULL; 2341 fw->req.board_elm = NULL; 2342 } 2343 2344 void rtw89_unload_firmware(struct rtw89_dev *rtwdev) 2345 { 2346 struct rtw89_fw_info *fw = &rtwdev->fw; 2347 2348 cancel_work_sync(&rtwdev->load_firmware_work); 2349 __rtw89_unload_firmware(rtwdev); 2350 2351 kfree(fw->log.fmts); 2352 rtw89_unload_firmware_elements(rtwdev); 2353 rtw89_unload_firmware_dup_data(rtwdev); 2354 } 2355 2356 static u32 rtw89_fw_log_get_fmt_idx(struct rtw89_dev *rtwdev, u32 fmt_id) 2357 { 2358 struct rtw89_fw_log *fw_log = &rtwdev->fw.log; 2359 u32 i; 2360 2361 if (fmt_id > fw_log->last_fmt_id) 2362 return 0; 2363 2364 for (i = 0; i < fw_log->fmt_count; i++) { 2365 if (le32_to_cpu(fw_log->fmt_ids[i]) == fmt_id) 2366 return i; 2367 } 2368 return 0; 2369 } 2370 2371 static int rtw89_fw_log_create_fmts_dict(struct rtw89_dev *rtwdev) 2372 { 2373 struct rtw89_fw_log *log = &rtwdev->fw.log; 2374 const struct rtw89_fw_logsuit_hdr *suit_hdr; 2375 struct rtw89_fw_suit *suit = &log->suit; 2376 const void *fmts_ptr, *fmts_end_ptr; 2377 u32 fmt_count; 2378 int i; 2379 2380 suit_hdr = (const struct rtw89_fw_logsuit_hdr *)suit->data; 2381 fmt_count = le32_to_cpu(suit_hdr->count); 2382 log->fmt_ids = suit_hdr->ids; 2383 fmts_ptr = &suit_hdr->ids[fmt_count]; 2384 fmts_end_ptr = suit->data + suit->size; 2385 log->fmts = kcalloc(fmt_count, sizeof(char *), GFP_KERNEL); 2386 if (!log->fmts) 2387 return -ENOMEM; 2388 2389 for (i = 0; i < fmt_count; i++) { 2390 fmts_ptr = memchr_inv(fmts_ptr, 0, fmts_end_ptr - fmts_ptr); 2391 if (!fmts_ptr) 2392 break; 2393 2394 (*log->fmts)[i] = fmts_ptr; 2395 log->last_fmt_id = le32_to_cpu(log->fmt_ids[i]); 2396 log->fmt_count++; 2397 fmts_ptr += strlen(fmts_ptr); 2398 } 2399 2400 return 0; 2401 } 2402 2403 int rtw89_fw_log_prepare(struct rtw89_dev *rtwdev) 2404 { 2405 struct rtw89_fw_log *log = &rtwdev->fw.log; 2406 struct rtw89_fw_suit *suit = &log->suit; 2407 2408 if (!suit || !suit->data) { 2409 rtw89_debug(rtwdev, RTW89_DBG_FW, "no log format file\n"); 2410 return -EINVAL; 2411 } 2412 if (log->fmts) 2413 return 0; 2414 2415 return rtw89_fw_log_create_fmts_dict(rtwdev); 2416 } 2417 2418 static void rtw89_fw_log_dump_data(struct rtw89_dev *rtwdev, 2419 const struct rtw89_fw_c2h_log_fmt *log_fmt, 2420 u32 fmt_idx, u8 para_int, bool raw_data) 2421 { 2422 const char *(*fmts)[] = rtwdev->fw.log.fmts; 2423 char str_buf[RTW89_C2H_FW_LOG_STR_BUF_SIZE]; 2424 u32 args[RTW89_C2H_FW_LOG_MAX_PARA_NUM] = {0}; 2425 int i; 2426 2427 if (log_fmt->argc > RTW89_C2H_FW_LOG_MAX_PARA_NUM) { 2428 rtw89_warn(rtwdev, "C2H log: Arg count is unexpected %d\n", 2429 log_fmt->argc); 2430 return; 2431 } 2432 2433 if (para_int) 2434 for (i = 0 ; i < log_fmt->argc; i++) 2435 args[i] = le32_to_cpu(log_fmt->u.argv[i]); 2436 2437 if (raw_data) { 2438 if (para_int) 2439 snprintf(str_buf, RTW89_C2H_FW_LOG_STR_BUF_SIZE, 2440 "fw_enc(%d, %d, %d) %*ph", le32_to_cpu(log_fmt->fmt_id), 2441 para_int, log_fmt->argc, (int)sizeof(args), args); 2442 else 2443 snprintf(str_buf, RTW89_C2H_FW_LOG_STR_BUF_SIZE, 2444 "fw_enc(%d, %d, %d, %s)", le32_to_cpu(log_fmt->fmt_id), 2445 para_int, log_fmt->argc, log_fmt->u.raw); 2446 } else { 2447 snprintf(str_buf, RTW89_C2H_FW_LOG_STR_BUF_SIZE, (*fmts)[fmt_idx], 2448 args[0x0], args[0x1], args[0x2], args[0x3], args[0x4], 2449 args[0x5], args[0x6], args[0x7], args[0x8], args[0x9], 2450 args[0xa], args[0xb], args[0xc], args[0xd], args[0xe], 2451 args[0xf]); 2452 } 2453 2454 rtw89_info(rtwdev, "C2H log: %s", str_buf); 2455 } 2456 2457 void rtw89_fw_log_dump(struct rtw89_dev *rtwdev, u8 *buf, u32 len) 2458 { 2459 const struct rtw89_fw_c2h_log_fmt *log_fmt; 2460 u8 para_int; 2461 u32 fmt_idx; 2462 2463 if (len < RTW89_C2H_HEADER_LEN) { 2464 rtw89_err(rtwdev, "c2h log length is wrong!\n"); 2465 return; 2466 } 2467 2468 buf += RTW89_C2H_HEADER_LEN; 2469 len -= RTW89_C2H_HEADER_LEN; 2470 log_fmt = (const struct rtw89_fw_c2h_log_fmt *)buf; 2471 2472 if (len < RTW89_C2H_FW_FORMATTED_LOG_MIN_LEN) 2473 goto plain_log; 2474 2475 if (log_fmt->signature != cpu_to_le16(RTW89_C2H_FW_LOG_SIGNATURE)) 2476 goto plain_log; 2477 2478 if (!rtwdev->fw.log.fmts) 2479 return; 2480 2481 para_int = u8_get_bits(log_fmt->feature, RTW89_C2H_FW_LOG_FEATURE_PARA_INT); 2482 fmt_idx = rtw89_fw_log_get_fmt_idx(rtwdev, le32_to_cpu(log_fmt->fmt_id)); 2483 2484 if (!para_int && log_fmt->argc != 0 && fmt_idx != 0) 2485 rtw89_info(rtwdev, "C2H log: %s%s", 2486 (*rtwdev->fw.log.fmts)[fmt_idx], log_fmt->u.raw); 2487 else if (fmt_idx != 0 && para_int) 2488 rtw89_fw_log_dump_data(rtwdev, log_fmt, fmt_idx, para_int, false); 2489 else 2490 rtw89_fw_log_dump_data(rtwdev, log_fmt, fmt_idx, para_int, true); 2491 return; 2492 2493 plain_log: 2494 rtw89_info(rtwdev, "C2H log: %.*s", len, buf); 2495 2496 } 2497 2498 int rtw89_fw_h2c_cam(struct rtw89_dev *rtwdev, struct rtw89_vif_link *rtwvif_link, 2499 struct rtw89_sta_link *rtwsta_link, const u8 *scan_mac_addr, 2500 enum rtw89_upd_mode upd_mode) 2501 { 2502 const struct rtw89_chip_info *chip = rtwdev->chip; 2503 struct rtw89_h2c_addr_cam_v0 *h2c_v0; 2504 struct rtw89_h2c_addr_cam *h2c; 2505 u32 len = sizeof(*h2c); 2506 struct sk_buff *skb; 2507 u8 ver = U8_MAX; 2508 int ret; 2509 2510 if (RTW89_CHK_FW_FEATURE(ADDR_CAM_V0, &rtwdev->fw) || 2511 chip->chip_gen == RTW89_CHIP_AX) { 2512 len = sizeof(*h2c_v0); 2513 ver = 0; 2514 } 2515 2516 skb = rtw89_fw_h2c_alloc_skb_with_hdr(rtwdev, len); 2517 if (!skb) { 2518 rtw89_err(rtwdev, "failed to alloc skb for fw dl\n"); 2519 return -ENOMEM; 2520 } 2521 skb_put(skb, len); 2522 h2c_v0 = (struct rtw89_h2c_addr_cam_v0 *)skb->data; 2523 2524 rtw89_cam_fill_addr_cam_info(rtwdev, rtwvif_link, rtwsta_link, 2525 scan_mac_addr, h2c_v0); 2526 rtw89_cam_fill_bssid_cam_info(rtwdev, rtwvif_link, rtwsta_link, h2c_v0); 2527 2528 if (ver == 0) 2529 goto hdr; 2530 2531 h2c = (struct rtw89_h2c_addr_cam *)skb->data; 2532 h2c->w15 = le32_encode_bits(upd_mode, ADDR_CAM_W15_UPD_MODE); 2533 2534 hdr: 2535 rtw89_h2c_pkt_set_hdr(rtwdev, skb, FWCMD_TYPE_H2C, 2536 H2C_CAT_MAC, 2537 H2C_CL_MAC_ADDR_CAM_UPDATE, 2538 H2C_FUNC_MAC_ADDR_CAM_UPD, 0, 1, 2539 len); 2540 2541 ret = rtw89_h2c_tx(rtwdev, skb, false); 2542 if (ret) { 2543 rtw89_err(rtwdev, "failed to send h2c\n"); 2544 goto fail; 2545 } 2546 2547 return 0; 2548 fail: 2549 dev_kfree_skb_any(skb); 2550 2551 return ret; 2552 } 2553 2554 int rtw89_fw_h2c_dctl_sec_cam_v1(struct rtw89_dev *rtwdev, 2555 struct rtw89_vif_link *rtwvif_link, 2556 struct rtw89_sta_link *rtwsta_link) 2557 { 2558 struct rtw89_h2c_dctlinfo_ud_v1 *h2c; 2559 u32 len = sizeof(*h2c); 2560 struct sk_buff *skb; 2561 int ret; 2562 2563 skb = rtw89_fw_h2c_alloc_skb_with_hdr(rtwdev, len); 2564 if (!skb) { 2565 rtw89_err(rtwdev, "failed to alloc skb for dctl sec cam\n"); 2566 return -ENOMEM; 2567 } 2568 skb_put(skb, len); 2569 h2c = (struct rtw89_h2c_dctlinfo_ud_v1 *)skb->data; 2570 2571 rtw89_cam_fill_dctl_sec_cam_info_v1(rtwdev, rtwvif_link, rtwsta_link, h2c); 2572 2573 rtw89_h2c_pkt_set_hdr(rtwdev, skb, FWCMD_TYPE_H2C, 2574 H2C_CAT_MAC, 2575 H2C_CL_MAC_FR_EXCHG, 2576 H2C_FUNC_MAC_DCTLINFO_UD_V1, 0, 0, 2577 len); 2578 2579 ret = rtw89_h2c_tx(rtwdev, skb, false); 2580 if (ret) { 2581 rtw89_err(rtwdev, "failed to send h2c\n"); 2582 goto fail; 2583 } 2584 2585 return 0; 2586 fail: 2587 dev_kfree_skb_any(skb); 2588 2589 return ret; 2590 } 2591 EXPORT_SYMBOL(rtw89_fw_h2c_dctl_sec_cam_v1); 2592 2593 int rtw89_fw_h2c_dctl_sec_cam_v2(struct rtw89_dev *rtwdev, 2594 struct rtw89_vif_link *rtwvif_link, 2595 struct rtw89_sta_link *rtwsta_link) 2596 { 2597 struct rtw89_h2c_dctlinfo_ud_v2 *h2c; 2598 u32 len = sizeof(*h2c); 2599 struct sk_buff *skb; 2600 int ret; 2601 2602 skb = rtw89_fw_h2c_alloc_skb_with_hdr(rtwdev, len); 2603 if (!skb) { 2604 rtw89_err(rtwdev, "failed to alloc skb for dctl sec cam\n"); 2605 return -ENOMEM; 2606 } 2607 skb_put(skb, len); 2608 h2c = (struct rtw89_h2c_dctlinfo_ud_v2 *)skb->data; 2609 2610 rtw89_cam_fill_dctl_sec_cam_info_v2(rtwdev, rtwvif_link, rtwsta_link, h2c); 2611 2612 rtw89_h2c_pkt_set_hdr(rtwdev, skb, FWCMD_TYPE_H2C, 2613 H2C_CAT_MAC, 2614 H2C_CL_MAC_FR_EXCHG, 2615 H2C_FUNC_MAC_DCTLINFO_UD_V2, 0, 0, 2616 len); 2617 2618 ret = rtw89_h2c_tx(rtwdev, skb, false); 2619 if (ret) { 2620 rtw89_err(rtwdev, "failed to send h2c\n"); 2621 goto fail; 2622 } 2623 2624 return 0; 2625 fail: 2626 dev_kfree_skb_any(skb); 2627 2628 return ret; 2629 } 2630 EXPORT_SYMBOL(rtw89_fw_h2c_dctl_sec_cam_v2); 2631 2632 int rtw89_fw_h2c_dctl_sec_cam_v3(struct rtw89_dev *rtwdev, 2633 struct rtw89_vif_link *rtwvif_link, 2634 struct rtw89_sta_link *rtwsta_link) 2635 { 2636 struct rtw89_h2c_dctlinfo_ud_v3 *h2c; 2637 u32 len = sizeof(*h2c); 2638 struct sk_buff *skb; 2639 int ret; 2640 2641 skb = rtw89_fw_h2c_alloc_skb_with_hdr(rtwdev, len); 2642 if (!skb) { 2643 rtw89_err(rtwdev, "failed to alloc skb for dctl sec cam\n"); 2644 return -ENOMEM; 2645 } 2646 skb_put(skb, len); 2647 h2c = (struct rtw89_h2c_dctlinfo_ud_v3 *)skb->data; 2648 2649 rtw89_cam_fill_dctl_sec_cam_info_v3(rtwdev, rtwvif_link, rtwsta_link, h2c); 2650 2651 rtw89_h2c_pkt_set_hdr(rtwdev, skb, FWCMD_TYPE_H2C, 2652 H2C_CAT_MAC, 2653 H2C_CL_MAC_FR_EXCHG, 2654 H2C_FUNC_MAC_DCTLINFO_UD_V3, 0, 0, 2655 len); 2656 2657 ret = rtw89_h2c_tx(rtwdev, skb, false); 2658 if (ret) { 2659 rtw89_err(rtwdev, "failed to send h2c\n"); 2660 goto fail; 2661 } 2662 2663 return 0; 2664 fail: 2665 dev_kfree_skb_any(skb); 2666 2667 return ret; 2668 } 2669 EXPORT_SYMBOL(rtw89_fw_h2c_dctl_sec_cam_v3); 2670 2671 int rtw89_fw_h2c_default_dmac_tbl_v2(struct rtw89_dev *rtwdev, 2672 struct rtw89_vif_link *rtwvif_link, 2673 struct rtw89_sta_link *rtwsta_link) 2674 { 2675 u8 mac_id = rtwsta_link ? rtwsta_link->mac_id : rtwvif_link->mac_id; 2676 struct rtw89_h2c_dctlinfo_ud_v2 *h2c; 2677 u32 len = sizeof(*h2c); 2678 struct sk_buff *skb; 2679 int ret; 2680 2681 skb = rtw89_fw_h2c_alloc_skb_with_hdr(rtwdev, len); 2682 if (!skb) { 2683 rtw89_err(rtwdev, "failed to alloc skb for dctl v2\n"); 2684 return -ENOMEM; 2685 } 2686 skb_put(skb, len); 2687 h2c = (struct rtw89_h2c_dctlinfo_ud_v2 *)skb->data; 2688 2689 h2c->c0 = le32_encode_bits(mac_id, DCTLINFO_V2_C0_MACID) | 2690 le32_encode_bits(1, DCTLINFO_V2_C0_OP); 2691 2692 h2c->m0 = cpu_to_le32(DCTLINFO_V2_W0_ALL); 2693 h2c->m1 = cpu_to_le32(DCTLINFO_V2_W1_ALL); 2694 h2c->m2 = cpu_to_le32(DCTLINFO_V2_W2_ALL); 2695 h2c->m3 = cpu_to_le32(DCTLINFO_V2_W3_ALL); 2696 h2c->m4 = cpu_to_le32(DCTLINFO_V2_W4_ALL); 2697 h2c->m5 = cpu_to_le32(DCTLINFO_V2_W5_ALL); 2698 h2c->m6 = cpu_to_le32(DCTLINFO_V2_W6_ALL); 2699 h2c->m7 = cpu_to_le32(DCTLINFO_V2_W7_ALL); 2700 h2c->m8 = cpu_to_le32(DCTLINFO_V2_W8_ALL); 2701 h2c->m9 = cpu_to_le32(DCTLINFO_V2_W9_ALL); 2702 h2c->m10 = cpu_to_le32(DCTLINFO_V2_W10_ALL); 2703 h2c->m11 = cpu_to_le32(DCTLINFO_V2_W11_ALL); 2704 h2c->m12 = cpu_to_le32(DCTLINFO_V2_W12_ALL); 2705 2706 rtw89_h2c_pkt_set_hdr(rtwdev, skb, FWCMD_TYPE_H2C, 2707 H2C_CAT_MAC, 2708 H2C_CL_MAC_FR_EXCHG, 2709 H2C_FUNC_MAC_DCTLINFO_UD_V2, 0, 0, 2710 len); 2711 2712 ret = rtw89_h2c_tx(rtwdev, skb, false); 2713 if (ret) { 2714 rtw89_err(rtwdev, "failed to send h2c\n"); 2715 goto fail; 2716 } 2717 2718 return 0; 2719 fail: 2720 dev_kfree_skb_any(skb); 2721 2722 return ret; 2723 } 2724 EXPORT_SYMBOL(rtw89_fw_h2c_default_dmac_tbl_v2); 2725 2726 int rtw89_fw_h2c_default_dmac_tbl_v3(struct rtw89_dev *rtwdev, 2727 struct rtw89_vif_link *rtwvif_link, 2728 struct rtw89_sta_link *rtwsta_link) 2729 { 2730 u8 mac_id = rtwsta_link ? rtwsta_link->mac_id : rtwvif_link->mac_id; 2731 struct rtw89_h2c_dctlinfo_ud_v3 *h2c; 2732 u32 len = sizeof(*h2c); 2733 struct sk_buff *skb; 2734 int ret; 2735 2736 skb = rtw89_fw_h2c_alloc_skb_with_hdr(rtwdev, len); 2737 if (!skb) { 2738 rtw89_err(rtwdev, "failed to alloc skb for dctl v2\n"); 2739 return -ENOMEM; 2740 } 2741 skb_put(skb, len); 2742 h2c = (struct rtw89_h2c_dctlinfo_ud_v3 *)skb->data; 2743 2744 h2c->c0 = le32_encode_bits(mac_id, DCTLINFO_V3_C0_MACID) | 2745 le32_encode_bits(1, DCTLINFO_V3_C0_OP); 2746 2747 h2c->m0 = cpu_to_le32(DCTLINFO_V3_W0_ALL); 2748 h2c->m1 = cpu_to_le32(DCTLINFO_V3_W1_ALL); 2749 h2c->m2 = cpu_to_le32(DCTLINFO_V3_W2_ALL); 2750 h2c->m3 = cpu_to_le32(DCTLINFO_V3_W3_ALL); 2751 h2c->m4 = cpu_to_le32(DCTLINFO_V3_W4_ALL); 2752 h2c->m5 = cpu_to_le32(DCTLINFO_V3_W5_ALL); 2753 h2c->m6 = cpu_to_le32(DCTLINFO_V3_W6_ALL); 2754 h2c->m7 = cpu_to_le32(DCTLINFO_V3_W7_ALL); 2755 h2c->m8 = cpu_to_le32(DCTLINFO_V3_W8_ALL); 2756 h2c->m9 = cpu_to_le32(DCTLINFO_V3_W9_ALL); 2757 h2c->m10 = cpu_to_le32(DCTLINFO_V3_W10_ALL); 2758 h2c->m11 = cpu_to_le32(DCTLINFO_V3_W11_ALL); 2759 h2c->m12 = cpu_to_le32(DCTLINFO_V3_W12_ALL); 2760 h2c->m13 = cpu_to_le32(DCTLINFO_V3_W13_ALL); 2761 2762 rtw89_h2c_pkt_set_hdr(rtwdev, skb, FWCMD_TYPE_H2C, 2763 H2C_CAT_MAC, 2764 H2C_CL_MAC_FR_EXCHG, 2765 H2C_FUNC_MAC_DCTLINFO_UD_V3, 0, 0, 2766 len); 2767 2768 ret = rtw89_h2c_tx(rtwdev, skb, false); 2769 if (ret) { 2770 rtw89_err(rtwdev, "failed to send h2c\n"); 2771 goto fail; 2772 } 2773 2774 return 0; 2775 fail: 2776 dev_kfree_skb_any(skb); 2777 2778 return ret; 2779 } 2780 EXPORT_SYMBOL(rtw89_fw_h2c_default_dmac_tbl_v3); 2781 2782 int rtw89_fw_h2c_ba_cam(struct rtw89_dev *rtwdev, struct rtw89_sta *rtwsta, 2783 bool valid, struct ieee80211_ampdu_params *params) 2784 { 2785 const struct rtw89_chip_info *chip = rtwdev->chip; 2786 struct rtw89_vif_link *rtwvif_link; 2787 struct rtw89_sta_link *rtwsta_link; 2788 struct rtw89_h2c_ba_cam *h2c; 2789 u32 len = sizeof(*h2c); 2790 struct sk_buff *skb; 2791 u8 entry_idx; 2792 u8 macid; 2793 int ret; 2794 2795 rtwsta_link = rtw89_get_designated_link(rtwsta); 2796 rtwvif_link = rtwsta_link->rtwvif_link; 2797 2798 macid = rtwsta_link->mac_id; 2799 2800 ret = valid ? 2801 rtw89_core_acquire_sta_ba_entry(rtwdev, rtwsta, params->tid, 2802 &entry_idx) : 2803 rtw89_core_release_sta_ba_entry(rtwdev, rtwsta, params->tid, 2804 &entry_idx); 2805 if (ret) { 2806 /* it still works even if we don't have static BA CAM, because 2807 * hardware can create dynamic BA CAM automatically. 2808 */ 2809 rtw89_debug(rtwdev, RTW89_DBG_TXRX, 2810 "failed to %s entry tid=%d for h2c ba cam\n", 2811 valid ? "alloc" : "free", params->tid); 2812 return 0; 2813 } 2814 2815 skb = rtw89_fw_h2c_alloc_skb_with_hdr(rtwdev, len); 2816 if (!skb) { 2817 rtw89_err(rtwdev, "failed to alloc skb for h2c ba cam\n"); 2818 return -ENOMEM; 2819 } 2820 skb_put(skb, len); 2821 h2c = (struct rtw89_h2c_ba_cam *)skb->data; 2822 2823 h2c->w0 = le32_encode_bits(macid, RTW89_H2C_BA_CAM_W0_MACID); 2824 if (chip->bacam_ver == RTW89_BACAM_V0_EXT) 2825 h2c->w1 |= le32_encode_bits(entry_idx, RTW89_H2C_BA_CAM_W1_ENTRY_IDX_V1); 2826 else 2827 h2c->w0 |= le32_encode_bits(entry_idx, RTW89_H2C_BA_CAM_W0_ENTRY_IDX); 2828 if (!valid) 2829 goto end; 2830 h2c->w0 |= le32_encode_bits(valid, RTW89_H2C_BA_CAM_W0_VALID) | 2831 le32_encode_bits(params->tid, RTW89_H2C_BA_CAM_W0_TID); 2832 if (params->buf_size > 64) 2833 h2c->w0 |= le32_encode_bits(4, RTW89_H2C_BA_CAM_W0_BMAP_SIZE); 2834 else 2835 h2c->w0 |= le32_encode_bits(0, RTW89_H2C_BA_CAM_W0_BMAP_SIZE); 2836 /* If init req is set, hw will set the ssn */ 2837 h2c->w0 |= le32_encode_bits(1, RTW89_H2C_BA_CAM_W0_INIT_REQ) | 2838 le32_encode_bits(params->ssn, RTW89_H2C_BA_CAM_W0_SSN); 2839 2840 if (chip->bacam_ver == RTW89_BACAM_V0_EXT) { 2841 h2c->w1 |= le32_encode_bits(1, RTW89_H2C_BA_CAM_W1_STD_EN) | 2842 le32_encode_bits(rtwvif_link->mac_idx, 2843 RTW89_H2C_BA_CAM_W1_BAND); 2844 } 2845 2846 end: 2847 rtw89_h2c_pkt_set_hdr(rtwdev, skb, FWCMD_TYPE_H2C, 2848 H2C_CAT_MAC, 2849 H2C_CL_BA_CAM, 2850 H2C_FUNC_MAC_BA_CAM, 0, 1, 2851 len); 2852 2853 ret = rtw89_h2c_tx(rtwdev, skb, false); 2854 if (ret) { 2855 rtw89_err(rtwdev, "failed to send h2c\n"); 2856 goto fail; 2857 } 2858 2859 return 0; 2860 fail: 2861 dev_kfree_skb_any(skb); 2862 2863 return ret; 2864 } 2865 EXPORT_SYMBOL(rtw89_fw_h2c_ba_cam); 2866 2867 static int rtw89_fw_h2c_init_ba_cam_v0_ext(struct rtw89_dev *rtwdev, 2868 u8 entry_idx, u8 uid) 2869 { 2870 struct rtw89_h2c_ba_cam *h2c; 2871 u32 len = sizeof(*h2c); 2872 struct sk_buff *skb; 2873 int ret; 2874 2875 skb = rtw89_fw_h2c_alloc_skb_with_hdr(rtwdev, len); 2876 if (!skb) { 2877 rtw89_err(rtwdev, "failed to alloc skb for dynamic h2c ba cam\n"); 2878 return -ENOMEM; 2879 } 2880 skb_put(skb, len); 2881 h2c = (struct rtw89_h2c_ba_cam *)skb->data; 2882 2883 h2c->w0 = le32_encode_bits(1, RTW89_H2C_BA_CAM_W0_VALID); 2884 h2c->w1 = le32_encode_bits(entry_idx, RTW89_H2C_BA_CAM_W1_ENTRY_IDX_V1) | 2885 le32_encode_bits(uid, RTW89_H2C_BA_CAM_W1_UID) | 2886 le32_encode_bits(0, RTW89_H2C_BA_CAM_W1_BAND) | 2887 le32_encode_bits(0, RTW89_H2C_BA_CAM_W1_STD_EN); 2888 2889 rtw89_h2c_pkt_set_hdr(rtwdev, skb, FWCMD_TYPE_H2C, 2890 H2C_CAT_MAC, 2891 H2C_CL_BA_CAM, 2892 H2C_FUNC_MAC_BA_CAM, 0, 1, 2893 len); 2894 2895 ret = rtw89_h2c_tx(rtwdev, skb, false); 2896 if (ret) { 2897 rtw89_err(rtwdev, "failed to send h2c\n"); 2898 goto fail; 2899 } 2900 2901 return 0; 2902 fail: 2903 dev_kfree_skb_any(skb); 2904 2905 return ret; 2906 } 2907 2908 void rtw89_fw_h2c_init_dynamic_ba_cam_v0_ext(struct rtw89_dev *rtwdev) 2909 { 2910 const struct rtw89_chip_info *chip = rtwdev->chip; 2911 u8 entry_idx = chip->bacam_num; 2912 u8 uid = 0; 2913 int i; 2914 2915 for (i = 0; i < chip->bacam_dynamic_num; i++) { 2916 rtw89_fw_h2c_init_ba_cam_v0_ext(rtwdev, entry_idx, uid); 2917 entry_idx++; 2918 uid++; 2919 } 2920 } 2921 2922 int rtw89_fw_h2c_ba_cam_v1(struct rtw89_dev *rtwdev, struct rtw89_sta *rtwsta, 2923 bool valid, struct ieee80211_ampdu_params *params) 2924 { 2925 const struct rtw89_chip_info *chip = rtwdev->chip; 2926 struct rtw89_vif_link *rtwvif_link; 2927 struct rtw89_sta_link *rtwsta_link; 2928 struct rtw89_h2c_ba_cam_v1 *h2c; 2929 struct ieee80211_vif *vif; 2930 u32 len = sizeof(*h2c); 2931 struct sk_buff *skb; 2932 u8 entry_idx; 2933 u8 bmap_size; 2934 bool is_mld; 2935 u8 macid; 2936 int ret; 2937 2938 rtwsta_link = rtw89_get_designated_link(rtwsta); 2939 rtwvif_link = rtwsta_link->rtwvif_link; 2940 vif = rtwvif_link_to_vif(rtwvif_link); 2941 2942 macid = rtwsta_link->mac_id; 2943 is_mld = ieee80211_vif_is_mld(vif); 2944 2945 ret = valid ? 2946 rtw89_core_acquire_sta_ba_entry(rtwdev, rtwsta, params->tid, 2947 &entry_idx) : 2948 rtw89_core_release_sta_ba_entry(rtwdev, rtwsta, params->tid, 2949 &entry_idx); 2950 if (ret) { 2951 /* it still works even if we don't have static BA CAM, because 2952 * hardware can create dynamic BA CAM automatically. 2953 */ 2954 rtw89_debug(rtwdev, RTW89_DBG_TXRX, 2955 "failed to %s entry tid=%d for h2c ba cam\n", 2956 valid ? "alloc" : "free", params->tid); 2957 return 0; 2958 } 2959 2960 skb = rtw89_fw_h2c_alloc_skb_with_hdr(rtwdev, len); 2961 if (!skb) { 2962 rtw89_err(rtwdev, "failed to alloc skb for h2c ba cam\n"); 2963 return -ENOMEM; 2964 } 2965 skb_put(skb, len); 2966 h2c = (struct rtw89_h2c_ba_cam_v1 *)skb->data; 2967 2968 if (params->buf_size > 512) 2969 bmap_size = 10; 2970 else if (params->buf_size > 256) 2971 bmap_size = 8; 2972 else if (params->buf_size > 64) 2973 bmap_size = 4; 2974 else 2975 bmap_size = 0; 2976 2977 h2c->w0 = le32_encode_bits(valid, RTW89_H2C_BA_CAM_V1_W0_VALID) | 2978 le32_encode_bits(1, RTW89_H2C_BA_CAM_V1_W0_INIT_REQ) | 2979 le32_encode_bits(macid, RTW89_H2C_BA_CAM_V1_W0_MACID_MASK) | 2980 le32_encode_bits(params->tid, RTW89_H2C_BA_CAM_V1_W0_TID_MASK) | 2981 le32_encode_bits(bmap_size, RTW89_H2C_BA_CAM_V1_W0_BMAP_SIZE_MASK) | 2982 le32_encode_bits(params->ssn, RTW89_H2C_BA_CAM_V1_W0_SSN_MASK); 2983 2984 entry_idx += chip->bacam_dynamic_num; /* std entry right after dynamic ones */ 2985 h2c->w1 = le32_encode_bits(entry_idx, RTW89_H2C_BA_CAM_V1_W1_ENTRY_IDX_MASK) | 2986 le32_encode_bits(1, RTW89_H2C_BA_CAM_V1_W1_STD_ENTRY_EN) | 2987 le32_encode_bits(is_mld, RTW89_H2C_BA_CAM_V1_W1_MLD_EN) | 2988 le32_encode_bits(!!rtwvif_link->mac_idx, 2989 RTW89_H2C_BA_CAM_V1_W1_BAND_SEL); 2990 2991 rtw89_h2c_pkt_set_hdr(rtwdev, skb, FWCMD_TYPE_H2C, 2992 H2C_CAT_MAC, 2993 H2C_CL_BA_CAM, 2994 H2C_FUNC_MAC_BA_CAM_V1, 0, 1, 2995 len); 2996 2997 ret = rtw89_h2c_tx(rtwdev, skb, false); 2998 if (ret) { 2999 rtw89_err(rtwdev, "failed to send h2c\n"); 3000 goto fail; 3001 } 3002 3003 return 0; 3004 fail: 3005 dev_kfree_skb_any(skb); 3006 3007 return ret; 3008 } 3009 EXPORT_SYMBOL(rtw89_fw_h2c_ba_cam_v1); 3010 3011 int rtw89_fw_h2c_ba_cam_g7(struct rtw89_dev *rtwdev, struct rtw89_sta *rtwsta, 3012 bool valid, struct ieee80211_ampdu_params *params) 3013 { 3014 const struct rtw89_chip_info *chip = rtwdev->chip; 3015 struct rtw89_vif_link *rtwvif_link; 3016 struct rtw89_sta_link *rtwsta_link; 3017 struct rtw89_h2c_ba_cam_g7 *h2c; 3018 struct ieee80211_vif *vif; 3019 u32 len = sizeof(*h2c); 3020 struct sk_buff *skb; 3021 u8 entry_idx; 3022 u8 bmap_size; 3023 bool is_mld; 3024 u16 macid; 3025 int ret; 3026 3027 rtwsta_link = rtw89_get_designated_link(rtwsta); 3028 rtwvif_link = rtwsta_link->rtwvif_link; 3029 vif = rtwvif_link_to_vif(rtwvif_link); 3030 3031 macid = rtwsta_link->mac_id; 3032 is_mld = ieee80211_vif_is_mld(vif); 3033 3034 ret = valid ? 3035 rtw89_core_acquire_sta_ba_entry(rtwdev, rtwsta, params->tid, 3036 &entry_idx) : 3037 rtw89_core_release_sta_ba_entry(rtwdev, rtwsta, params->tid, 3038 &entry_idx); 3039 if (ret) { 3040 /* 3041 * it still works even if we don't have static BA CAM, because 3042 * hardware can create dynamic BA CAM automatically. 3043 */ 3044 rtw89_debug(rtwdev, RTW89_DBG_TXRX, 3045 "failed to %s entry tid=%d for h2c ba cam\n", 3046 valid ? "alloc" : "free", params->tid); 3047 return 0; 3048 } 3049 3050 skb = rtw89_fw_h2c_alloc_skb_with_hdr(rtwdev, len); 3051 if (!skb) { 3052 rtw89_err(rtwdev, "failed to alloc skb for h2c ba cam\n"); 3053 return -ENOMEM; 3054 } 3055 skb_put(skb, len); 3056 h2c = (struct rtw89_h2c_ba_cam_g7 *)skb->data; 3057 3058 if (params->buf_size > 512) 3059 bmap_size = 10; 3060 else if (params->buf_size > 256) 3061 bmap_size = 8; 3062 else if (params->buf_size > 64) 3063 bmap_size = 4; 3064 else 3065 bmap_size = 0; 3066 3067 h2c->w0 = le32_encode_bits(valid, RTW89_H2C_BA_CAM_G7_W0_VALID) | 3068 le32_encode_bits(1, RTW89_H2C_BA_CAM_G7_W0_INIT_REQ) | 3069 le32_encode_bits(params->tid, RTW89_H2C_BA_CAM_G7_W0_TID_MASK) | 3070 le32_encode_bits(1, RTW89_H2C_BA_CAM_G7_W0_STD_ENTRY_EN) | 3071 le32_encode_bits(is_mld, RTW89_H2C_BA_CAM_G7_W0_MLD_EN) | 3072 le32_encode_bits(!!rtwvif_link->mac_idx, 3073 RTW89_H2C_BA_CAM_G7_W0_BAND_SEL) | 3074 le32_encode_bits(bmap_size, RTW89_H2C_BA_CAM_G7_W0_BMAP_SIZE_MASK) | 3075 le32_encode_bits(params->ssn, RTW89_H2C_BA_CAM_G7_W0_SSN_MASK); 3076 3077 entry_idx += chip->bacam_dynamic_num; /* std entry right after dynamic ones */ 3078 h2c->w1 = le32_encode_bits(macid, RTW89_H2C_BA_CAM_G7_W1_MACID_MASK) | 3079 le32_encode_bits(entry_idx, RTW89_H2C_BA_CAM_G7_W1_ENTRY_IDX_MASK); 3080 3081 rtw89_h2c_pkt_set_hdr(rtwdev, skb, FWCMD_TYPE_H2C, 3082 H2C_CAT_MAC, 3083 H2C_CL_BA_CAM, 3084 H2C_FUNC_MAC_BA_CAM_V1, 0, 1, 3085 len); 3086 3087 ret = rtw89_h2c_tx(rtwdev, skb, false); 3088 if (ret) { 3089 rtw89_err(rtwdev, "failed to send h2c\n"); 3090 goto fail; 3091 } 3092 3093 return 0; 3094 fail: 3095 dev_kfree_skb_any(skb); 3096 3097 return ret; 3098 } 3099 EXPORT_SYMBOL(rtw89_fw_h2c_ba_cam_g7); 3100 3101 int rtw89_fw_h2c_init_ba_cam_users(struct rtw89_dev *rtwdev, u8 users, 3102 u8 offset, u8 mac_idx) 3103 { 3104 struct rtw89_h2c_ba_cam_init *h2c; 3105 u32 len = sizeof(*h2c); 3106 struct sk_buff *skb; 3107 int ret; 3108 3109 skb = rtw89_fw_h2c_alloc_skb_with_hdr(rtwdev, len); 3110 if (!skb) { 3111 rtw89_err(rtwdev, "failed to alloc skb for h2c ba cam init\n"); 3112 return -ENOMEM; 3113 } 3114 skb_put(skb, len); 3115 h2c = (struct rtw89_h2c_ba_cam_init *)skb->data; 3116 3117 h2c->w0 = le32_encode_bits(users, RTW89_H2C_BA_CAM_INIT_USERS_MASK) | 3118 le32_encode_bits(offset, RTW89_H2C_BA_CAM_INIT_OFFSET_MASK) | 3119 le32_encode_bits(mac_idx, RTW89_H2C_BA_CAM_INIT_BAND_SEL); 3120 3121 rtw89_h2c_pkt_set_hdr(rtwdev, skb, FWCMD_TYPE_H2C, 3122 H2C_CAT_MAC, 3123 H2C_CL_BA_CAM, 3124 H2C_FUNC_MAC_BA_CAM_INIT, 0, 1, 3125 len); 3126 3127 ret = rtw89_h2c_tx(rtwdev, skb, false); 3128 if (ret) { 3129 rtw89_err(rtwdev, "failed to send h2c\n"); 3130 goto fail; 3131 } 3132 3133 return 0; 3134 fail: 3135 dev_kfree_skb_any(skb); 3136 3137 return ret; 3138 } 3139 3140 #define H2C_LOG_CFG_LEN 12 3141 int rtw89_fw_h2c_fw_log(struct rtw89_dev *rtwdev, bool enable) 3142 { 3143 struct sk_buff *skb; 3144 u32 comp = 0; 3145 int ret; 3146 3147 if (enable) 3148 comp = BIT(RTW89_FW_LOG_COMP_INIT) | BIT(RTW89_FW_LOG_COMP_TASK) | 3149 BIT(RTW89_FW_LOG_COMP_PS) | BIT(RTW89_FW_LOG_COMP_ERROR) | 3150 BIT(RTW89_FW_LOG_COMP_MLO) | BIT(RTW89_FW_LOG_COMP_SCAN); 3151 3152 skb = rtw89_fw_h2c_alloc_skb_with_hdr(rtwdev, H2C_LOG_CFG_LEN); 3153 if (!skb) { 3154 rtw89_err(rtwdev, "failed to alloc skb for fw log cfg\n"); 3155 return -ENOMEM; 3156 } 3157 3158 skb_put(skb, H2C_LOG_CFG_LEN); 3159 SET_LOG_CFG_LEVEL(skb->data, RTW89_FW_LOG_LEVEL_LOUD); 3160 SET_LOG_CFG_PATH(skb->data, BIT(RTW89_FW_LOG_LEVEL_C2H)); 3161 SET_LOG_CFG_COMP(skb->data, comp); 3162 SET_LOG_CFG_COMP_EXT(skb->data, 0); 3163 3164 rtw89_h2c_pkt_set_hdr(rtwdev, skb, FWCMD_TYPE_H2C, 3165 H2C_CAT_MAC, 3166 H2C_CL_FW_INFO, 3167 H2C_FUNC_LOG_CFG, 0, 0, 3168 H2C_LOG_CFG_LEN); 3169 3170 ret = rtw89_h2c_tx(rtwdev, skb, false); 3171 if (ret) { 3172 rtw89_err(rtwdev, "failed to send h2c\n"); 3173 goto fail; 3174 } 3175 3176 return 0; 3177 fail: 3178 dev_kfree_skb_any(skb); 3179 3180 return ret; 3181 } 3182 3183 static struct sk_buff *rtw89_eapol_get(struct rtw89_dev *rtwdev, 3184 struct rtw89_vif_link *rtwvif_link) 3185 { 3186 static const u8 gtkbody[] = {0xAA, 0xAA, 0x03, 0x00, 0x00, 0x00, 0x88, 3187 0x8E, 0x01, 0x03, 0x00, 0x5F, 0x02, 0x03}; 3188 u8 sec_hdr_len = rtw89_wow_get_sec_hdr_len(rtwdev); 3189 struct rtw89_wow_param *rtw_wow = &rtwdev->wow; 3190 struct rtw89_eapol_2_of_2 *eapol_pkt; 3191 struct ieee80211_bss_conf *bss_conf; 3192 struct ieee80211_hdr_3addr *hdr; 3193 struct sk_buff *skb; 3194 u8 key_des_ver; 3195 3196 if (rtw_wow->ptk_alg == 3) 3197 key_des_ver = 1; 3198 else if (rtw_wow->akm == 1 || rtw_wow->akm == 2) 3199 key_des_ver = 2; 3200 else if (rtw_wow->akm > 2 && rtw_wow->akm < 7) 3201 key_des_ver = 3; 3202 else 3203 key_des_ver = 0; 3204 3205 skb = dev_alloc_skb(sizeof(*hdr) + sec_hdr_len + sizeof(*eapol_pkt)); 3206 if (!skb) 3207 return NULL; 3208 3209 hdr = skb_put_zero(skb, sizeof(*hdr)); 3210 hdr->frame_control = cpu_to_le16(IEEE80211_FTYPE_DATA | 3211 IEEE80211_FCTL_TODS | 3212 IEEE80211_FCTL_PROTECTED); 3213 3214 rcu_read_lock(); 3215 3216 bss_conf = rtw89_vif_rcu_dereference_link(rtwvif_link, true); 3217 3218 ether_addr_copy(hdr->addr1, bss_conf->bssid); 3219 ether_addr_copy(hdr->addr2, bss_conf->addr); 3220 ether_addr_copy(hdr->addr3, bss_conf->bssid); 3221 3222 rcu_read_unlock(); 3223 3224 skb_put_zero(skb, sec_hdr_len); 3225 3226 eapol_pkt = skb_put_zero(skb, sizeof(*eapol_pkt)); 3227 memcpy(eapol_pkt->gtkbody, gtkbody, sizeof(gtkbody)); 3228 eapol_pkt->key_des_ver = key_des_ver; 3229 3230 return skb; 3231 } 3232 3233 static struct sk_buff *rtw89_sa_query_get(struct rtw89_dev *rtwdev, 3234 struct rtw89_vif_link *rtwvif_link) 3235 { 3236 u8 sec_hdr_len = rtw89_wow_get_sec_hdr_len(rtwdev); 3237 struct ieee80211_bss_conf *bss_conf; 3238 struct ieee80211_hdr_3addr *hdr; 3239 struct rtw89_sa_query *sa_query; 3240 struct sk_buff *skb; 3241 3242 skb = dev_alloc_skb(sizeof(*hdr) + sec_hdr_len + sizeof(*sa_query)); 3243 if (!skb) 3244 return NULL; 3245 3246 hdr = skb_put_zero(skb, sizeof(*hdr)); 3247 hdr->frame_control = cpu_to_le16(IEEE80211_FTYPE_MGMT | 3248 IEEE80211_STYPE_ACTION | 3249 IEEE80211_FCTL_PROTECTED); 3250 3251 rcu_read_lock(); 3252 3253 bss_conf = rtw89_vif_rcu_dereference_link(rtwvif_link, true); 3254 3255 ether_addr_copy(hdr->addr1, bss_conf->bssid); 3256 ether_addr_copy(hdr->addr2, bss_conf->addr); 3257 ether_addr_copy(hdr->addr3, bss_conf->bssid); 3258 3259 rcu_read_unlock(); 3260 3261 skb_put_zero(skb, sec_hdr_len); 3262 3263 sa_query = skb_put_zero(skb, sizeof(*sa_query)); 3264 sa_query->category = WLAN_CATEGORY_SA_QUERY; 3265 sa_query->action = WLAN_ACTION_SA_QUERY_RESPONSE; 3266 3267 return skb; 3268 } 3269 3270 static struct sk_buff *rtw89_arp_response_get(struct rtw89_dev *rtwdev, 3271 struct rtw89_vif_link *rtwvif_link) 3272 { 3273 struct ieee80211_vif *vif = rtwvif_to_vif(rtwvif_link->rtwvif); 3274 struct rtw89_vif *rtwvif = rtwvif_link->rtwvif; 3275 u8 sec_hdr_len = rtw89_wow_get_sec_hdr_len(rtwdev); 3276 struct rtw89_wow_param *rtw_wow = &rtwdev->wow; 3277 struct ieee80211_hdr_3addr *hdr; 3278 struct rtw89_arp_rsp *arp_skb; 3279 struct arphdr *arp_hdr; 3280 struct sk_buff *skb; 3281 bool with_qos; 3282 u16 fc; 3283 3284 with_qos = ieee80211_vif_is_mld(vif); 3285 3286 rtw89_debug(rtwdev, RTW89_DBG_WOW, "[arp_reply] with qos field: %s\n", 3287 str_yes_no(with_qos)); 3288 3289 skb = dev_alloc_skb(sizeof(*hdr) + sec_hdr_len + sizeof(*arp_skb) + 3290 (with_qos ? 2 : 0)); 3291 if (!skb) 3292 return NULL; 3293 3294 hdr = skb_put_zero(skb, sizeof(*hdr)); 3295 3296 fc = IEEE80211_FTYPE_DATA | IEEE80211_FCTL_TODS; 3297 3298 if (rtw_wow->ptk_alg) 3299 fc |= IEEE80211_FCTL_PROTECTED; 3300 3301 if (with_qos) 3302 fc |= IEEE80211_STYPE_QOS_DATA; 3303 else 3304 fc |= IEEE80211_STYPE_DATA; 3305 3306 hdr->frame_control = cpu_to_le16(fc); 3307 3308 ether_addr_copy(hdr->addr1, rtwvif_link->bssid); 3309 ether_addr_copy(hdr->addr2, rtwvif_link->mac_addr); 3310 ether_addr_copy(hdr->addr3, rtwvif_link->bssid); 3311 3312 if (with_qos) 3313 skb_put_zero(skb, sizeof(__le16)); 3314 3315 if (sec_hdr_len) 3316 skb_put_zero(skb, sec_hdr_len); 3317 3318 arp_skb = skb_put_zero(skb, sizeof(*arp_skb)); 3319 memcpy(arp_skb->llc_hdr, rfc1042_header, sizeof(rfc1042_header)); 3320 arp_skb->llc_type = htons(ETH_P_ARP); 3321 3322 arp_hdr = &arp_skb->arp_hdr; 3323 arp_hdr->ar_hrd = htons(ARPHRD_ETHER); 3324 arp_hdr->ar_pro = htons(ETH_P_IP); 3325 arp_hdr->ar_hln = ETH_ALEN; 3326 arp_hdr->ar_pln = 4; 3327 arp_hdr->ar_op = htons(ARPOP_REPLY); 3328 3329 ether_addr_copy(arp_skb->sender_hw, rtwvif->mac_addr); 3330 arp_skb->sender_ip = rtwvif->ip_addr; 3331 ether_addr_copy(arp_skb->target_hw, rtwvif->mac_addr); 3332 arp_skb->target_ip = rtwvif->ip_addr; 3333 3334 return skb; 3335 } 3336 3337 static int rtw89_fw_h2c_add_general_pkt(struct rtw89_dev *rtwdev, 3338 struct rtw89_vif_link *rtwvif_link, 3339 enum rtw89_fw_pkt_ofld_type type, 3340 u8 *id) 3341 { 3342 struct ieee80211_vif *vif = rtwvif_link_to_vif(rtwvif_link); 3343 int link_id = ieee80211_vif_is_mld(vif) ? rtwvif_link->link_id : -1; 3344 struct rtw89_pktofld_info *info; 3345 struct sk_buff *skb; 3346 int ret; 3347 3348 info = kzalloc_obj(*info); 3349 if (!info) 3350 return -ENOMEM; 3351 3352 switch (type) { 3353 case RTW89_PKT_OFLD_TYPE_PS_POLL: 3354 skb = ieee80211_pspoll_get(rtwdev->hw, vif); 3355 break; 3356 case RTW89_PKT_OFLD_TYPE_PROBE_RSP: 3357 skb = ieee80211_proberesp_get(rtwdev->hw, vif); 3358 break; 3359 case RTW89_PKT_OFLD_TYPE_NULL_DATA: 3360 skb = ieee80211_nullfunc_get(rtwdev->hw, vif, link_id, false); 3361 break; 3362 case RTW89_PKT_OFLD_TYPE_QOS_NULL: 3363 skb = ieee80211_nullfunc_get(rtwdev->hw, vif, link_id, true); 3364 break; 3365 case RTW89_PKT_OFLD_TYPE_EAPOL_KEY: 3366 skb = rtw89_eapol_get(rtwdev, rtwvif_link); 3367 break; 3368 case RTW89_PKT_OFLD_TYPE_SA_QUERY: 3369 skb = rtw89_sa_query_get(rtwdev, rtwvif_link); 3370 break; 3371 case RTW89_PKT_OFLD_TYPE_ARP_RSP: 3372 skb = rtw89_arp_response_get(rtwdev, rtwvif_link); 3373 break; 3374 default: 3375 ret = -EINVAL; 3376 goto err; 3377 } 3378 3379 if (!skb) { 3380 ret = -ENOMEM; 3381 goto err; 3382 } 3383 3384 ret = rtw89_fw_h2c_add_pkt_offload(rtwdev, &info->id, skb); 3385 kfree_skb(skb); 3386 3387 if (ret) 3388 goto err; 3389 3390 list_add_tail(&info->list, &rtwvif_link->general_pkt_list); 3391 *id = info->id; 3392 return 0; 3393 3394 err: 3395 kfree(info); 3396 return ret; 3397 } 3398 3399 void rtw89_fw_release_general_pkt_list_vif(struct rtw89_dev *rtwdev, 3400 struct rtw89_vif_link *rtwvif_link, 3401 bool notify_fw) 3402 { 3403 struct list_head *pkt_list = &rtwvif_link->general_pkt_list; 3404 struct rtw89_pktofld_info *info, *tmp; 3405 3406 list_for_each_entry_safe(info, tmp, pkt_list, list) { 3407 if (notify_fw) 3408 rtw89_fw_h2c_del_pkt_offload(rtwdev, info->id); 3409 else 3410 rtw89_core_release_bit_map(rtwdev->pkt_offload, info->id); 3411 list_del(&info->list); 3412 kfree(info); 3413 } 3414 } 3415 3416 void rtw89_fw_release_general_pkt_list(struct rtw89_dev *rtwdev, bool notify_fw) 3417 { 3418 struct rtw89_vif_link *rtwvif_link; 3419 struct rtw89_vif *rtwvif; 3420 unsigned int link_id; 3421 3422 rtw89_for_each_rtwvif(rtwdev, rtwvif) 3423 rtw89_vif_for_each_link(rtwvif, rtwvif_link, link_id) 3424 rtw89_fw_release_general_pkt_list_vif(rtwdev, rtwvif_link, 3425 notify_fw); 3426 } 3427 3428 #define H2C_GENERAL_PKT_LEN 6 3429 #define H2C_GENERAL_PKT_ID_UND 0xff 3430 int rtw89_fw_h2c_general_pkt(struct rtw89_dev *rtwdev, 3431 struct rtw89_vif_link *rtwvif_link, u8 macid) 3432 { 3433 u8 pkt_id_ps_poll = H2C_GENERAL_PKT_ID_UND; 3434 u8 pkt_id_null = H2C_GENERAL_PKT_ID_UND; 3435 u8 pkt_id_qos_null = H2C_GENERAL_PKT_ID_UND; 3436 struct sk_buff *skb; 3437 int ret; 3438 3439 rtw89_fw_h2c_add_general_pkt(rtwdev, rtwvif_link, 3440 RTW89_PKT_OFLD_TYPE_PS_POLL, &pkt_id_ps_poll); 3441 rtw89_fw_h2c_add_general_pkt(rtwdev, rtwvif_link, 3442 RTW89_PKT_OFLD_TYPE_NULL_DATA, &pkt_id_null); 3443 rtw89_fw_h2c_add_general_pkt(rtwdev, rtwvif_link, 3444 RTW89_PKT_OFLD_TYPE_QOS_NULL, &pkt_id_qos_null); 3445 3446 skb = rtw89_fw_h2c_alloc_skb_with_hdr(rtwdev, H2C_GENERAL_PKT_LEN); 3447 if (!skb) { 3448 rtw89_err(rtwdev, "failed to alloc skb for fw dl\n"); 3449 return -ENOMEM; 3450 } 3451 skb_put(skb, H2C_GENERAL_PKT_LEN); 3452 SET_GENERAL_PKT_MACID(skb->data, macid); 3453 SET_GENERAL_PKT_PROBRSP_ID(skb->data, H2C_GENERAL_PKT_ID_UND); 3454 SET_GENERAL_PKT_PSPOLL_ID(skb->data, pkt_id_ps_poll); 3455 SET_GENERAL_PKT_NULL_ID(skb->data, pkt_id_null); 3456 SET_GENERAL_PKT_QOS_NULL_ID(skb->data, pkt_id_qos_null); 3457 SET_GENERAL_PKT_CTS2SELF_ID(skb->data, H2C_GENERAL_PKT_ID_UND); 3458 3459 rtw89_h2c_pkt_set_hdr(rtwdev, skb, FWCMD_TYPE_H2C, 3460 H2C_CAT_MAC, 3461 H2C_CL_FW_INFO, 3462 H2C_FUNC_MAC_GENERAL_PKT, 0, 1, 3463 H2C_GENERAL_PKT_LEN); 3464 3465 ret = rtw89_h2c_tx(rtwdev, skb, false); 3466 if (ret) { 3467 rtw89_err(rtwdev, "failed to send h2c\n"); 3468 goto fail; 3469 } 3470 3471 return 0; 3472 fail: 3473 dev_kfree_skb_any(skb); 3474 3475 return ret; 3476 } 3477 3478 #define H2C_LPS_PARM_LEN 8 3479 int rtw89_fw_h2c_lps_parm(struct rtw89_dev *rtwdev, 3480 struct rtw89_lps_parm *lps_param) 3481 { 3482 struct sk_buff *skb; 3483 bool done_ack; 3484 int ret; 3485 3486 if (RTW89_CHK_FW_FEATURE(LPS_DACK_BY_C2H_REG, &rtwdev->fw)) 3487 done_ack = false; 3488 else 3489 done_ack = !lps_param->psmode; 3490 3491 skb = rtw89_fw_h2c_alloc_skb_with_hdr(rtwdev, H2C_LPS_PARM_LEN); 3492 if (!skb) { 3493 rtw89_err(rtwdev, "failed to alloc skb for fw dl\n"); 3494 return -ENOMEM; 3495 } 3496 skb_put(skb, H2C_LPS_PARM_LEN); 3497 3498 SET_LPS_PARM_MACID(skb->data, lps_param->macid); 3499 SET_LPS_PARM_PSMODE(skb->data, lps_param->psmode); 3500 SET_LPS_PARM_LASTRPWM(skb->data, lps_param->lastrpwm); 3501 SET_LPS_PARM_RLBM(skb->data, 1); 3502 SET_LPS_PARM_SMARTPS(skb->data, 1); 3503 SET_LPS_PARM_AWAKEINTERVAL(skb->data, 1); 3504 SET_LPS_PARM_VOUAPSD(skb->data, 0); 3505 SET_LPS_PARM_VIUAPSD(skb->data, 0); 3506 SET_LPS_PARM_BEUAPSD(skb->data, 0); 3507 SET_LPS_PARM_BKUAPSD(skb->data, 0); 3508 3509 rtw89_h2c_pkt_set_hdr(rtwdev, skb, FWCMD_TYPE_H2C, 3510 H2C_CAT_MAC, 3511 H2C_CL_MAC_PS, 3512 H2C_FUNC_MAC_LPS_PARM, 0, done_ack, 3513 H2C_LPS_PARM_LEN); 3514 3515 ret = rtw89_h2c_tx(rtwdev, skb, false); 3516 if (ret) { 3517 rtw89_err(rtwdev, "failed to send h2c\n"); 3518 goto fail; 3519 } 3520 3521 return 0; 3522 fail: 3523 dev_kfree_skb_any(skb); 3524 3525 return ret; 3526 } 3527 3528 int rtw89_fw_h2c_lps_ch_info(struct rtw89_dev *rtwdev, struct rtw89_vif *rtwvif) 3529 { 3530 const struct rtw89_chip_info *chip = rtwdev->chip; 3531 const struct rtw89_chan *chan; 3532 struct rtw89_vif_link *rtwvif_link; 3533 struct rtw89_h2c_lps_ch_info *h2c; 3534 u32 len = sizeof(*h2c); 3535 unsigned int link_id; 3536 struct sk_buff *skb; 3537 bool no_chan = true; 3538 u8 phy_idx; 3539 u32 done; 3540 int ret; 3541 3542 if (chip->chip_gen != RTW89_CHIP_BE) 3543 return 0; 3544 3545 skb = rtw89_fw_h2c_alloc_skb_with_hdr(rtwdev, len); 3546 if (!skb) { 3547 rtw89_err(rtwdev, "failed to alloc skb for h2c lps_ch_info\n"); 3548 return -ENOMEM; 3549 } 3550 skb_put(skb, len); 3551 h2c = (struct rtw89_h2c_lps_ch_info *)skb->data; 3552 3553 rtw89_vif_for_each_link(rtwvif, rtwvif_link, link_id) { 3554 phy_idx = rtwvif_link->phy_idx; 3555 if (phy_idx >= ARRAY_SIZE(h2c->info)) 3556 continue; 3557 3558 chan = rtw89_chan_get(rtwdev, rtwvif_link->chanctx_idx); 3559 no_chan = false; 3560 3561 h2c->info[phy_idx].central_ch = chan->channel; 3562 h2c->info[phy_idx].pri_ch = chan->primary_channel; 3563 h2c->info[phy_idx].band = chan->band_type; 3564 h2c->info[phy_idx].bw = chan->band_width; 3565 } 3566 3567 if (no_chan) { 3568 rtw89_err(rtwdev, "no chan for h2c lps_ch_info\n"); 3569 ret = -ENOENT; 3570 goto fail; 3571 } 3572 3573 h2c->mlo_dbcc_mode_lps = cpu_to_le32(rtwdev->mlo_dbcc_mode); 3574 3575 rtw89_h2c_pkt_set_hdr(rtwdev, skb, FWCMD_TYPE_H2C, 3576 H2C_CAT_OUTSRC, H2C_CL_OUTSRC_DM, 3577 H2C_FUNC_FW_LPS_CH_INFO, 0, 0, len); 3578 3579 rtw89_phy_write32_mask(rtwdev, R_CHK_LPS_STAT, B_CHK_LPS_STAT, 0); 3580 ret = rtw89_h2c_tx(rtwdev, skb, false); 3581 if (ret) { 3582 rtw89_err(rtwdev, "failed to send h2c\n"); 3583 goto fail; 3584 } 3585 3586 ret = read_poll_timeout(rtw89_phy_read32_mask, done, done, 50, 5000, 3587 true, rtwdev, R_CHK_LPS_STAT, B_CHK_LPS_STAT); 3588 if (ret) 3589 rtw89_warn(rtwdev, "h2c_lps_ch_info done polling timeout\n"); 3590 3591 return 0; 3592 fail: 3593 dev_kfree_skb_any(skb); 3594 3595 return ret; 3596 } 3597 3598 int rtw89_fw_h2c_lps_ml_cmn_info(struct rtw89_dev *rtwdev, 3599 struct rtw89_vif *rtwvif) 3600 { 3601 const struct rtw89_phy_bb_gain_info_be *gain = &rtwdev->bb_gain.be; 3602 static const u8 bcn_bw_ofst[] = {0, 0, 0, 3, 6, 9, 0, 12}; 3603 const struct rtw89_chip_info *chip = rtwdev->chip; 3604 struct rtw89_efuse *efuse = &rtwdev->efuse; 3605 struct rtw89_h2c_lps_ml_cmn_info *h2c; 3606 struct rtw89_vif_link *rtwvif_link; 3607 struct rtw89_pkt_stat *pkt_stat; 3608 const struct rtw89_chan *chan; 3609 u8 bw_idx = RTW89_BB_BW_20_40; 3610 struct rtw89_bb_ctx *bb; 3611 u32 len = sizeof(*h2c); 3612 unsigned int link_id; 3613 struct sk_buff *skb; 3614 u8 beacon_bw_ofst; 3615 u8 gain_band; 3616 u32 done; 3617 u8 path; 3618 int ret; 3619 int i; 3620 3621 if (chip->chip_gen != RTW89_CHIP_BE) 3622 return 0; 3623 3624 skb = rtw89_fw_h2c_alloc_skb_with_hdr(rtwdev, len); 3625 if (!skb) { 3626 rtw89_err(rtwdev, "failed to alloc skb for h2c lps_ml_cmn_info\n"); 3627 return -ENOMEM; 3628 } 3629 skb_put(skb, len); 3630 h2c = (struct rtw89_h2c_lps_ml_cmn_info *)skb->data; 3631 3632 h2c->fmt_id = 0x3; 3633 3634 h2c->mlo_dbcc_mode = cpu_to_le32(rtwdev->mlo_dbcc_mode); 3635 h2c->rfe_type = efuse->rfe_type; 3636 3637 rtw89_vif_for_each_link(rtwvif, rtwvif_link, link_id) { 3638 path = rtwvif_link->phy_idx == RTW89_PHY_1 ? RF_PATH_B : RF_PATH_A; 3639 chan = rtw89_chan_get(rtwdev, rtwvif_link->chanctx_idx); 3640 gain_band = rtw89_subband_to_gain_band_be(chan->subband_type); 3641 bb = rtw89_get_bb_ctx(rtwdev, rtwvif_link->phy_idx); 3642 3643 h2c->central_ch[rtwvif_link->phy_idx] = chan->channel; 3644 h2c->pri_ch[rtwvif_link->phy_idx] = chan->primary_channel; 3645 h2c->band[rtwvif_link->phy_idx] = chan->band_type; 3646 h2c->bw[rtwvif_link->phy_idx] = chan->band_width; 3647 3648 pkt_stat = &bb->cur_pkt_stat; 3649 if (pkt_stat->beacon_rate < RTW89_HW_RATE_OFDM6) 3650 h2c->bcn_rate_type[rtwvif_link->phy_idx] = 0x1; 3651 else 3652 h2c->bcn_rate_type[rtwvif_link->phy_idx] = 0x2; 3653 3654 /* Fill BW20 RX gain table for beacon mode */ 3655 for (i = 0; i < TIA_GAIN_NUM; i++) { 3656 h2c->tia_gain[rtwvif_link->phy_idx][i] = 3657 cpu_to_le16(gain->tia_gain[gain_band][bw_idx][path][i]); 3658 } 3659 3660 if (rtwvif_link->bcn_bw_idx < ARRAY_SIZE(bcn_bw_ofst)) { 3661 beacon_bw_ofst = bcn_bw_ofst[rtwvif_link->bcn_bw_idx]; 3662 h2c->dup_bcn_ofst[rtwvif_link->phy_idx] = beacon_bw_ofst; 3663 } 3664 3665 memcpy(h2c->lna_gain[rtwvif_link->phy_idx], 3666 gain->lna_gain[gain_band][bw_idx][path], 3667 LNA_GAIN_NUM); 3668 memcpy(h2c->tia_lna_op1db[rtwvif_link->phy_idx], 3669 gain->tia_lna_op1db[gain_band][bw_idx][path], 3670 LNA_GAIN_NUM + 1); 3671 memcpy(h2c->lna_op1db[rtwvif_link->phy_idx], 3672 gain->lna_op1db[gain_band][bw_idx][path], 3673 LNA_GAIN_NUM); 3674 } 3675 3676 rtw89_h2c_pkt_set_hdr(rtwdev, skb, FWCMD_TYPE_H2C, 3677 H2C_CAT_OUTSRC, H2C_CL_OUTSRC_DM, 3678 H2C_FUNC_FW_LPS_ML_CMN_INFO, 0, 0, len); 3679 3680 rtw89_phy_write32_mask(rtwdev, R_CHK_LPS_STAT, B_CHK_LPS_STAT, 0); 3681 ret = rtw89_h2c_tx(rtwdev, skb, false); 3682 if (ret) { 3683 rtw89_err(rtwdev, "failed to send h2c\n"); 3684 goto fail; 3685 } 3686 3687 ret = read_poll_timeout(rtw89_phy_read32_mask, done, done, 50, 5000, 3688 true, rtwdev, R_CHK_LPS_STAT, B_CHK_LPS_STAT); 3689 if (ret) 3690 rtw89_warn(rtwdev, "h2c_lps_ml_cmn_info done polling timeout\n"); 3691 3692 return 0; 3693 fail: 3694 dev_kfree_skb_any(skb); 3695 3696 return ret; 3697 } 3698 3699 void rtw89_bb_lps_cmn_info_rx_gain_fill(struct rtw89_dev *rtwdev, 3700 struct rtw89_bb_link_info_rx_gain *h2c_gain, 3701 const struct rtw89_chan *chan, u8 phy_idx) 3702 { 3703 const struct rtw89_phy_bb_gain_info_be *gain = &rtwdev->bb_gain.be; 3704 enum rtw89_bb_link_rx_gain_table_type tab_idx; 3705 struct rtw89_chan chan_bcn; 3706 u8 bw = chan->band_width; 3707 u8 gain_band; 3708 u8 bw_idx; 3709 u8 path; 3710 int i; 3711 3712 rtw89_chan_create(&chan_bcn, chan->primary_channel, chan->primary_channel, 3713 chan->band_type, RTW89_CHANNEL_WIDTH_20); 3714 3715 for (tab_idx = RTW89_BB_PS_LINK_RX_GAIN_TAB_BCN_PATH_A; 3716 tab_idx < RTW89_BB_PS_LINK_RX_GAIN_TAB_MAX; tab_idx++) { 3717 struct rtw89_phy_calc_efuse_gain calc = {}; 3718 3719 path = (tab_idx & BIT(0)) ? (RF_PATH_B) : (RF_PATH_A); 3720 if (tab_idx & BIT(1)) { 3721 rtw89_chip_calc_rx_gain_normal(rtwdev, chan, path, phy_idx, 3722 &calc); 3723 gain_band = rtw89_subband_to_gain_band_be(chan->subband_type); 3724 if (bw > RTW89_CHANNEL_WIDTH_40) 3725 bw_idx = RTW89_BB_BW_80_160_320; 3726 else 3727 bw_idx = RTW89_BB_BW_20_40; 3728 } else { 3729 rtw89_chip_calc_rx_gain_normal(rtwdev, &chan_bcn, path, phy_idx, 3730 &calc); 3731 gain_band = rtw89_subband_to_gain_band_be(chan_bcn.subband_type); 3732 bw_idx = RTW89_BB_BW_20_40; 3733 } 3734 3735 /* efuse ofst and comp */ 3736 h2c_gain->gain_ofst[tab_idx] = calc.rssi_ofst; 3737 h2c_gain->cck_gain_ofst[tab_idx] = calc.cck_rpl_ofst; 3738 h2c_gain->cck_rpl_bias_comp[tab_idx][0] = calc.cck_mean_gain_bias; 3739 h2c_gain->cck_rpl_bias_comp[tab_idx][1] = calc.cck_mean_gain_bias; 3740 3741 for (i = 0; i < TIA_GAIN_NUM; i++) { 3742 h2c_gain->gain_err_tia[tab_idx][i] = 3743 cpu_to_le16(gain->tia_gain[gain_band][bw_idx][path][i]); 3744 } 3745 memcpy(h2c_gain->gain_err_lna[tab_idx], 3746 gain->lna_gain[gain_band][bw_idx][path], 3747 LNA_GAIN_NUM); 3748 memcpy(h2c_gain->op1db_lna[tab_idx], 3749 gain->lna_op1db[gain_band][bw_idx][path], 3750 LNA_GAIN_NUM); 3751 memcpy(h2c_gain->op1db_tia[tab_idx], 3752 gain->tia_lna_op1db[gain_band][bw_idx][path], 3753 LNA_GAIN_NUM + 1); 3754 3755 memcpy(h2c_gain->rpl_bias_comp_bw[tab_idx]._20M, 3756 gain->rpl_ofst_20[gain_band][path], 3757 RTW89_BW20_SC_20M); 3758 memcpy(h2c_gain->rpl_bias_comp_bw[tab_idx]._40M, 3759 gain->rpl_ofst_40[gain_band][path], 3760 RTW89_BW20_SC_40M); 3761 memcpy(h2c_gain->rpl_bias_comp_bw[tab_idx]._80M, 3762 gain->rpl_ofst_80[gain_band][path], 3763 RTW89_BW20_SC_80M); 3764 memcpy(h2c_gain->rpl_bias_comp_bw[tab_idx]._160M, 3765 gain->rpl_ofst_160[gain_band][path], 3766 RTW89_BW20_SC_160M); 3767 } 3768 } 3769 3770 static void 3771 rtw89_fw_h2c_lps_ml_cmn_info_v1_extra_fill(struct rtw89_dev *rtwdev, 3772 struct rtw89_vif *rtwvif, 3773 struct rtw89_h2c_lps_ml_cmn_info_v1_extra *h2c) 3774 { 3775 u8 regd = rtw89_regd_get(rtwdev, RTW89_BAND_2G); 3776 struct ieee80211_bss_conf *bss_conf; 3777 struct rtw89_vif_link *rtwvif_link; 3778 unsigned int link_id; 3779 3780 static_assert(sizeof(*h2c) % 4 == 0); 3781 3782 h2c->regu_mode_on_24g = regd == RTW89_FCC ? RTW89_BB_REGULATION_FCC : 3783 RTW89_BB_REGULATION_CE; 3784 3785 rtw89_vif_for_each_link(rtwvif, rtwvif_link, link_id) { 3786 u8 phy_idx = rtwvif_link->phy_idx; 3787 3788 rcu_read_lock(); 3789 bss_conf = rtw89_vif_rcu_dereference_link(rtwvif_link, true); 3790 h2c->bss_color[phy_idx] = bss_conf->he_bss_color.color; 3791 rcu_read_unlock(); 3792 } 3793 } 3794 3795 int rtw89_fw_h2c_lps_ml_cmn_info_v1(struct rtw89_dev *rtwdev, 3796 struct rtw89_vif *rtwvif) 3797 { 3798 static const u8 bcn_bw_ofst[] = {0, 0, 0, 3, 6, 9, 0, 12}; 3799 struct rtw89_h2c_lps_ml_cmn_info_v1_extra *h2c_extra; 3800 const struct rtw89_chip_info *chip = rtwdev->chip; 3801 struct rtw89_efuse *efuse = &rtwdev->efuse; 3802 struct rtw89_h2c_lps_ml_cmn_info_v1 *h2c; 3803 struct rtw89_vif_link *rtwvif_link; 3804 const struct rtw89_chan *chan; 3805 struct rtw89_bb_ctx *bb; 3806 unsigned int link_id; 3807 struct sk_buff *skb; 3808 u8 beacon_bw_ofst; 3809 bool has_extra; 3810 u32 done; 3811 u32 len; 3812 int ret; 3813 3814 if (chip->chip_gen != RTW89_CHIP_BE) 3815 return 0; 3816 3817 has_extra = RTW89_CHK_FW_FEATURE(LPS_ML_INFO_V1_EXTRA, &rtwdev->fw); 3818 if (has_extra) 3819 len = sizeof(*h2c_extra); 3820 else 3821 len = sizeof(*h2c); 3822 3823 skb = rtw89_fw_h2c_alloc_skb_with_hdr(rtwdev, len); 3824 if (!skb) { 3825 rtw89_err(rtwdev, "failed to alloc skb for h2c lps_ml_cmn_info_v1\n"); 3826 return -ENOMEM; 3827 } 3828 skb_put(skb, len); 3829 h2c = (struct rtw89_h2c_lps_ml_cmn_info_v1 *)skb->data; 3830 3831 if (has_extra) { 3832 h2c_extra = container_of(h2c, typeof(*h2c_extra), v1); 3833 h2c->fmt_id = RTW89_H2C_LPS_ML_CMN_INFO_FMT_ID_V1_EXTRA; 3834 rtw89_fw_h2c_lps_ml_cmn_info_v1_extra_fill(rtwdev, rtwvif, h2c_extra); 3835 } else { 3836 h2c->fmt_id = RTW89_H2C_LPS_ML_CMN_INFO_FMT_ID_V1; 3837 } 3838 3839 h2c->mlo_dbcc_mode = cpu_to_le32(rtwdev->mlo_dbcc_mode); 3840 h2c->rfe_type = efuse->rfe_type; 3841 h2c->rssi_main = U8_MAX; 3842 3843 memset(h2c->link_id, RTW89_BB_PS_LINK_ID_SKIP, RTW89_BB_PS_LINK_BUF_MAX); 3844 3845 rtw89_vif_for_each_link(rtwvif, rtwvif_link, link_id) { 3846 u8 phy_idx = rtwvif_link->phy_idx; 3847 3848 bb = rtw89_get_bb_ctx(rtwdev, phy_idx); 3849 chan = rtw89_chan_get(rtwdev, rtwvif_link->chanctx_idx); 3850 3851 h2c->link_id[phy_idx] = link_id; 3852 h2c->central_ch[phy_idx] = chan->channel; 3853 h2c->pri_ch[phy_idx] = chan->primary_channel; 3854 h2c->band[phy_idx] = chan->band_type; 3855 h2c->bw[phy_idx] = chan->band_width; 3856 3857 if (rtwvif_link->bcn_bw_idx < ARRAY_SIZE(bcn_bw_ofst)) { 3858 beacon_bw_ofst = bcn_bw_ofst[rtwvif_link->bcn_bw_idx]; 3859 h2c->dup_bcn_ofst[phy_idx] = beacon_bw_ofst; 3860 } 3861 3862 if (h2c->rssi_main > bb->ch_info.rssi_min) 3863 h2c->rssi_main = bb->ch_info.rssi_min; 3864 3865 rtw89_bb_lps_cmn_info_rx_gain_fill(rtwdev, 3866 &h2c->rx_gain[phy_idx], 3867 chan, phy_idx); 3868 } 3869 3870 rtw89_h2c_pkt_set_hdr(rtwdev, skb, FWCMD_TYPE_H2C, 3871 H2C_CAT_OUTSRC, H2C_CL_OUTSRC_DM, 3872 H2C_FUNC_FW_LPS_ML_CMN_INFO, 0, 0, len); 3873 3874 rtw89_phy_write32_mask(rtwdev, R_CHK_LPS_STAT_BE4, B_CHK_LPS_STAT, 0); 3875 ret = rtw89_h2c_tx(rtwdev, skb, false); 3876 if (ret) { 3877 rtw89_err(rtwdev, "failed to send h2c\n"); 3878 goto fail; 3879 } 3880 3881 ret = read_poll_timeout(rtw89_phy_read32_mask, done, done, 50, 5000, 3882 true, rtwdev, R_CHK_LPS_STAT_BE4, B_CHK_LPS_STAT); 3883 if (ret) 3884 rtw89_warn(rtwdev, "h2c_lps_ml_cmn_info done polling timeout\n"); 3885 3886 return 0; 3887 fail: 3888 dev_kfree_skb_any(skb); 3889 3890 return ret; 3891 } 3892 3893 int rtw89_fw_h2c_phy_rfe_type(struct rtw89_dev *rtwdev) 3894 { 3895 const struct rtw89_chip_info *chip = rtwdev->chip; 3896 struct rtw89_efuse *efuse = &rtwdev->efuse; 3897 struct rtw89_h2c_phy_rfe_type *h2c; 3898 u32 len = sizeof(*h2c); 3899 struct sk_buff *skb; 3900 int ret; 3901 3902 if (chip->chip_id != RTL8922D) 3903 return 0; 3904 3905 skb = rtw89_fw_h2c_alloc_skb_with_hdr(rtwdev, len); 3906 if (!skb) { 3907 rtw89_err(rtwdev, "failed to alloc skb for h2c phy_rfe_type\n"); 3908 return -ENOMEM; 3909 } 3910 skb_put(skb, len); 3911 h2c = (struct rtw89_h2c_phy_rfe_type *)skb->data; 3912 3913 h2c->rfe_type = efuse->rfe_type; 3914 3915 rtw89_h2c_pkt_set_hdr(rtwdev, skb, FWCMD_TYPE_H2C, 3916 H2C_CAT_OUTSRC, H2C_CL_OUTSRC_DM, 3917 H2C_FUNC_FW_RFE_TYPE, 0, 0, len); 3918 3919 ret = rtw89_h2c_tx(rtwdev, skb, false); 3920 if (ret) { 3921 rtw89_err(rtwdev, "failed to send h2c\n"); 3922 goto fail; 3923 } 3924 3925 return 0; 3926 fail: 3927 dev_kfree_skb_any(skb); 3928 3929 return ret; 3930 } 3931 EXPORT_SYMBOL(rtw89_fw_h2c_phy_rfe_type); 3932 3933 #define H2C_P2P_ACT_LEN 20 3934 int rtw89_fw_h2c_p2p_act(struct rtw89_dev *rtwdev, 3935 struct rtw89_vif_link *rtwvif_link, 3936 struct ieee80211_p2p_noa_desc *desc, 3937 u8 act, u8 noa_id, u8 ctwindow_oppps) 3938 { 3939 bool p2p_type_gc = rtwvif_link->wifi_role == RTW89_WIFI_ROLE_P2P_CLIENT; 3940 struct sk_buff *skb; 3941 u8 *cmd; 3942 int ret; 3943 3944 skb = rtw89_fw_h2c_alloc_skb_with_hdr(rtwdev, H2C_P2P_ACT_LEN); 3945 if (!skb) { 3946 rtw89_err(rtwdev, "failed to alloc skb for h2c p2p act\n"); 3947 return -ENOMEM; 3948 } 3949 skb_put(skb, H2C_P2P_ACT_LEN); 3950 cmd = skb->data; 3951 3952 RTW89_SET_FWCMD_P2P_MACID(cmd, rtwvif_link->mac_id); 3953 RTW89_SET_FWCMD_P2P_P2PID(cmd, 0); 3954 RTW89_SET_FWCMD_P2P_NOAID(cmd, noa_id); 3955 RTW89_SET_FWCMD_P2P_ACT(cmd, act); 3956 RTW89_SET_FWCMD_P2P_TYPE(cmd, p2p_type_gc); 3957 RTW89_SET_FWCMD_P2P_ALL_SLEP(cmd, 0); 3958 if (desc) { 3959 RTW89_SET_FWCMD_NOA_START_TIME(cmd, desc->start_time); 3960 RTW89_SET_FWCMD_NOA_INTERVAL(cmd, desc->interval); 3961 RTW89_SET_FWCMD_NOA_DURATION(cmd, desc->duration); 3962 RTW89_SET_FWCMD_NOA_COUNT(cmd, desc->count); 3963 RTW89_SET_FWCMD_NOA_CTWINDOW(cmd, ctwindow_oppps); 3964 } 3965 3966 rtw89_h2c_pkt_set_hdr(rtwdev, skb, FWCMD_TYPE_H2C, 3967 H2C_CAT_MAC, H2C_CL_MAC_PS, 3968 H2C_FUNC_P2P_ACT, 0, 0, 3969 H2C_P2P_ACT_LEN); 3970 3971 ret = rtw89_h2c_tx(rtwdev, skb, false); 3972 if (ret) { 3973 rtw89_err(rtwdev, "failed to send h2c\n"); 3974 goto fail; 3975 } 3976 3977 return 0; 3978 fail: 3979 dev_kfree_skb_any(skb); 3980 3981 return ret; 3982 } 3983 3984 static void __rtw89_fw_h2c_set_tx_path(struct rtw89_dev *rtwdev, 3985 struct sk_buff *skb) 3986 { 3987 const struct rtw89_chip_info *chip = rtwdev->chip; 3988 struct rtw89_hal *hal = &rtwdev->hal; 3989 u8 ntx_path; 3990 u8 map_b; 3991 3992 if (chip->rf_path_num == 1) { 3993 ntx_path = RF_A; 3994 map_b = 0; 3995 } else { 3996 ntx_path = hal->antenna_tx ? hal->antenna_tx : RF_AB; 3997 map_b = ntx_path == RF_AB ? 1 : 0; 3998 } 3999 4000 SET_CMC_TBL_NTX_PATH_EN(skb->data, ntx_path); 4001 SET_CMC_TBL_PATH_MAP_A(skb->data, 0); 4002 SET_CMC_TBL_PATH_MAP_B(skb->data, map_b); 4003 SET_CMC_TBL_PATH_MAP_C(skb->data, 0); 4004 SET_CMC_TBL_PATH_MAP_D(skb->data, 0); 4005 } 4006 4007 #define H2C_CMC_TBL_LEN 68 4008 int rtw89_fw_h2c_default_cmac_tbl(struct rtw89_dev *rtwdev, 4009 struct rtw89_vif_link *rtwvif_link, 4010 struct rtw89_sta_link *rtwsta_link) 4011 { 4012 const struct rtw89_chip_info *chip = rtwdev->chip; 4013 u8 macid = rtwsta_link ? rtwsta_link->mac_id : rtwvif_link->mac_id; 4014 struct sk_buff *skb; 4015 int ret; 4016 4017 skb = rtw89_fw_h2c_alloc_skb_with_hdr(rtwdev, H2C_CMC_TBL_LEN); 4018 if (!skb) { 4019 rtw89_err(rtwdev, "failed to alloc skb for fw dl\n"); 4020 return -ENOMEM; 4021 } 4022 skb_put(skb, H2C_CMC_TBL_LEN); 4023 SET_CTRL_INFO_MACID(skb->data, macid); 4024 SET_CTRL_INFO_OPERATION(skb->data, 1); 4025 if (chip->h2c_cctl_func_id == H2C_FUNC_MAC_CCTLINFO_UD) { 4026 SET_CMC_TBL_TXPWR_MODE(skb->data, 0); 4027 __rtw89_fw_h2c_set_tx_path(rtwdev, skb); 4028 SET_CMC_TBL_ANTSEL_A(skb->data, 0); 4029 SET_CMC_TBL_ANTSEL_B(skb->data, 0); 4030 SET_CMC_TBL_ANTSEL_C(skb->data, 0); 4031 SET_CMC_TBL_ANTSEL_D(skb->data, 0); 4032 } 4033 SET_CMC_TBL_MGQ_RPT_EN(skb->data, rtwdev->hci.tx_rpt_enabled); 4034 SET_CMC_TBL_DOPPLER_CTRL(skb->data, 0); 4035 SET_CMC_TBL_TXPWR_TOLERENCE(skb->data, 0); 4036 if (rtwvif_link->net_type == RTW89_NET_TYPE_AP_MODE) 4037 SET_CMC_TBL_DATA_DCM(skb->data, 0); 4038 4039 rtw89_h2c_pkt_set_hdr(rtwdev, skb, FWCMD_TYPE_H2C, 4040 H2C_CAT_MAC, H2C_CL_MAC_FR_EXCHG, 4041 chip->h2c_cctl_func_id, 0, 1, 4042 H2C_CMC_TBL_LEN); 4043 4044 ret = rtw89_h2c_tx(rtwdev, skb, false); 4045 if (ret) { 4046 rtw89_err(rtwdev, "failed to send h2c\n"); 4047 goto fail; 4048 } 4049 4050 return 0; 4051 fail: 4052 dev_kfree_skb_any(skb); 4053 4054 return ret; 4055 } 4056 EXPORT_SYMBOL(rtw89_fw_h2c_default_cmac_tbl); 4057 4058 int rtw89_fw_h2c_default_cmac_tbl_g7(struct rtw89_dev *rtwdev, 4059 struct rtw89_vif_link *rtwvif_link, 4060 struct rtw89_sta_link *rtwsta_link) 4061 { 4062 u8 mac_id = rtwsta_link ? rtwsta_link->mac_id : rtwvif_link->mac_id; 4063 struct rtw89_h2c_cctlinfo_ud_g7 *h2c; 4064 u32 len = sizeof(*h2c); 4065 struct sk_buff *skb; 4066 int ret; 4067 4068 skb = rtw89_fw_h2c_alloc_skb_with_hdr(rtwdev, len); 4069 if (!skb) { 4070 rtw89_err(rtwdev, "failed to alloc skb for cmac g7\n"); 4071 return -ENOMEM; 4072 } 4073 skb_put(skb, len); 4074 h2c = (struct rtw89_h2c_cctlinfo_ud_g7 *)skb->data; 4075 4076 h2c->c0 = le32_encode_bits(mac_id, CCTLINFO_G7_C0_MACID) | 4077 le32_encode_bits(1, CCTLINFO_G7_C0_OP); 4078 4079 h2c->w0 = le32_encode_bits(4, CCTLINFO_G7_W0_DATARATE) | 4080 le32_encode_bits(rtwdev->hci.tx_rpt_enabled, CCTLINFO_G7_W0_MGQ_RPT_EN); 4081 h2c->m0 = cpu_to_le32(CCTLINFO_G7_W0_ALL); 4082 4083 h2c->w1 = le32_encode_bits(4, CCTLINFO_G7_W1_DATA_RTY_LOWEST_RATE) | 4084 le32_encode_bits(0xa, CCTLINFO_G7_W1_RTSRATE) | 4085 le32_encode_bits(4, CCTLINFO_G7_W1_RTS_RTY_LOWEST_RATE); 4086 h2c->m1 = cpu_to_le32(CCTLINFO_G7_W1_ALL); 4087 4088 h2c->m2 = cpu_to_le32(CCTLINFO_G7_W2_ALL); 4089 4090 h2c->m3 = cpu_to_le32(CCTLINFO_G7_W3_ALL); 4091 4092 h2c->w4 = le32_encode_bits(0xFFFF, CCTLINFO_G7_W4_ACT_SUBCH_CBW); 4093 h2c->m4 = cpu_to_le32(CCTLINFO_G7_W4_ALL); 4094 4095 h2c->w5 = le32_encode_bits(2, CCTLINFO_G7_W5_NOMINAL_PKT_PADDING0) | 4096 le32_encode_bits(2, CCTLINFO_G7_W5_NOMINAL_PKT_PADDING1) | 4097 le32_encode_bits(2, CCTLINFO_G7_W5_NOMINAL_PKT_PADDING2) | 4098 le32_encode_bits(2, CCTLINFO_G7_W5_NOMINAL_PKT_PADDING3) | 4099 le32_encode_bits(2, CCTLINFO_G7_W5_NOMINAL_PKT_PADDING4); 4100 h2c->m5 = cpu_to_le32(CCTLINFO_G7_W5_ALL); 4101 4102 h2c->w6 = le32_encode_bits(0xb, CCTLINFO_G7_W6_RESP_REF_RATE); 4103 h2c->m6 = cpu_to_le32(CCTLINFO_G7_W6_ALL); 4104 4105 h2c->w7 = le32_encode_bits(1, CCTLINFO_G7_W7_NC) | 4106 le32_encode_bits(1, CCTLINFO_G7_W7_NR) | 4107 le32_encode_bits(1, CCTLINFO_G7_W7_CB) | 4108 le32_encode_bits(0x1, CCTLINFO_G7_W7_CSI_PARA_EN) | 4109 le32_encode_bits(0xb, CCTLINFO_G7_W7_CSI_FIX_RATE); 4110 h2c->m7 = cpu_to_le32(CCTLINFO_G7_W7_ALL); 4111 4112 h2c->m8 = cpu_to_le32(CCTLINFO_G7_W8_ALL); 4113 4114 h2c->w14 = le32_encode_bits(0, CCTLINFO_G7_W14_VO_CURR_RATE) | 4115 le32_encode_bits(0, CCTLINFO_G7_W14_VI_CURR_RATE) | 4116 le32_encode_bits(0, CCTLINFO_G7_W14_BE_CURR_RATE_L); 4117 h2c->m14 = cpu_to_le32(CCTLINFO_G7_W14_ALL); 4118 4119 h2c->w15 = le32_encode_bits(0, CCTLINFO_G7_W15_BE_CURR_RATE_H) | 4120 le32_encode_bits(0, CCTLINFO_G7_W15_BK_CURR_RATE) | 4121 le32_encode_bits(0, CCTLINFO_G7_W15_MGNT_CURR_RATE); 4122 h2c->m15 = cpu_to_le32(CCTLINFO_G7_W15_ALL); 4123 4124 rtw89_h2c_pkt_set_hdr(rtwdev, skb, FWCMD_TYPE_H2C, 4125 H2C_CAT_MAC, H2C_CL_MAC_FR_EXCHG, 4126 H2C_FUNC_MAC_CCTLINFO_UD_G7, 0, 1, 4127 len); 4128 4129 ret = rtw89_h2c_tx(rtwdev, skb, false); 4130 if (ret) { 4131 rtw89_err(rtwdev, "failed to send h2c\n"); 4132 goto fail; 4133 } 4134 4135 return 0; 4136 fail: 4137 dev_kfree_skb_any(skb); 4138 4139 return ret; 4140 } 4141 EXPORT_SYMBOL(rtw89_fw_h2c_default_cmac_tbl_g7); 4142 4143 int rtw89_fw_h2c_default_cmac_tbl_be(struct rtw89_dev *rtwdev, 4144 struct rtw89_vif_link *rtwvif_link, 4145 struct rtw89_sta_link *rtwsta_link) 4146 { 4147 u8 mac_id = rtwsta_link ? rtwsta_link->mac_id : rtwvif_link->mac_id; 4148 bool preld = rtw89_mac_chk_preload_allow(rtwdev); 4149 struct rtw89_h2c_cctlinfo_ud_be *h2c; 4150 u32 len = sizeof(*h2c); 4151 struct sk_buff *skb; 4152 int ret; 4153 4154 skb = rtw89_fw_h2c_alloc_skb_with_hdr(rtwdev, len); 4155 if (!skb) { 4156 rtw89_err(rtwdev, "failed to alloc skb for default cmac be\n"); 4157 return -ENOMEM; 4158 } 4159 skb_put(skb, len); 4160 h2c = (struct rtw89_h2c_cctlinfo_ud_be *)skb->data; 4161 4162 h2c->c0 = le32_encode_bits(mac_id, BE_CCTL_INFO_C0_V1_MACID) | 4163 le32_encode_bits(1, BE_CCTL_INFO_C0_V1_OP); 4164 4165 h2c->w0 = le32_encode_bits(4, BE_CCTL_INFO_W0_DATARATE); 4166 h2c->m0 = cpu_to_le32(BE_CCTL_INFO_W0_ALL); 4167 4168 h2c->w1 = le32_encode_bits(4, BE_CCTL_INFO_W1_DATA_RTY_LOWEST_RATE) | 4169 le32_encode_bits(0xa, BE_CCTL_INFO_W1_RTSRATE) | 4170 le32_encode_bits(4, BE_CCTL_INFO_W1_RTS_RTY_LOWEST_RATE); 4171 h2c->m1 = cpu_to_le32(BE_CCTL_INFO_W1_ALL); 4172 4173 h2c->w2 = le32_encode_bits(preld, BE_CCTL_INFO_W2_PRELOAD_ENABLE); 4174 h2c->m2 = cpu_to_le32(BE_CCTL_INFO_W2_ALL); 4175 4176 h2c->m3 = cpu_to_le32(BE_CCTL_INFO_W3_ALL); 4177 4178 h2c->w4 = le32_encode_bits(0xFFFF, BE_CCTL_INFO_W4_ACT_SUBCH_CBW); 4179 h2c->m4 = cpu_to_le32(BE_CCTL_INFO_W4_ALL); 4180 4181 h2c->w5 = le32_encode_bits(2, BE_CCTL_INFO_W5_NOMINAL_PKT_PADDING0_V1) | 4182 le32_encode_bits(2, BE_CCTL_INFO_W5_NOMINAL_PKT_PADDING1_V1) | 4183 le32_encode_bits(2, BE_CCTL_INFO_W5_NOMINAL_PKT_PADDING2_V1) | 4184 le32_encode_bits(2, BE_CCTL_INFO_W5_NOMINAL_PKT_PADDING3_V1) | 4185 le32_encode_bits(2, BE_CCTL_INFO_W5_NOMINAL_PKT_PADDING4_V1); 4186 h2c->m5 = cpu_to_le32(BE_CCTL_INFO_W5_ALL); 4187 4188 h2c->w6 = le32_encode_bits(0xb, BE_CCTL_INFO_W6_RESP_REF_RATE); 4189 h2c->m6 = cpu_to_le32(BE_CCTL_INFO_W6_ALL); 4190 4191 h2c->w7 = le32_encode_bits(1, BE_CCTL_INFO_W7_NC) | 4192 le32_encode_bits(1, BE_CCTL_INFO_W7_NR) | 4193 le32_encode_bits(1, BE_CCTL_INFO_W7_CB) | 4194 le32_encode_bits(0x1, BE_CCTL_INFO_W7_CSI_PARA_EN) | 4195 le32_encode_bits(0xb, BE_CCTL_INFO_W7_CSI_FIX_RATE); 4196 h2c->m7 = cpu_to_le32(BE_CCTL_INFO_W7_ALL); 4197 4198 h2c->m8 = cpu_to_le32(BE_CCTL_INFO_W8_ALL); 4199 4200 h2c->w14 = le32_encode_bits(0, BE_CCTL_INFO_W14_VO_CURR_RATE) | 4201 le32_encode_bits(0, BE_CCTL_INFO_W14_VI_CURR_RATE) | 4202 le32_encode_bits(0, BE_CCTL_INFO_W14_BE_CURR_RATE_L); 4203 h2c->m14 = cpu_to_le32(BE_CCTL_INFO_W14_ALL); 4204 4205 h2c->w15 = le32_encode_bits(0, BE_CCTL_INFO_W15_BE_CURR_RATE_H) | 4206 le32_encode_bits(0, BE_CCTL_INFO_W15_BK_CURR_RATE) | 4207 le32_encode_bits(0, BE_CCTL_INFO_W15_MGNT_CURR_RATE); 4208 h2c->m15 = cpu_to_le32(BE_CCTL_INFO_W15_ALL); 4209 4210 rtw89_h2c_pkt_set_hdr(rtwdev, skb, FWCMD_TYPE_H2C, 4211 H2C_CAT_MAC, H2C_CL_MAC_FR_EXCHG, 4212 H2C_FUNC_MAC_CCTLINFO_UD_G7, 0, 1, 4213 len); 4214 4215 ret = rtw89_h2c_tx(rtwdev, skb, false); 4216 if (ret) { 4217 rtw89_err(rtwdev, "failed to send h2c\n"); 4218 goto fail; 4219 } 4220 4221 return 0; 4222 fail: 4223 dev_kfree_skb_any(skb); 4224 4225 return ret; 4226 } 4227 EXPORT_SYMBOL(rtw89_fw_h2c_default_cmac_tbl_be); 4228 4229 static void __get_sta_he_pkt_padding(struct rtw89_dev *rtwdev, 4230 struct ieee80211_link_sta *link_sta, 4231 u8 *pads) 4232 { 4233 bool ppe_th; 4234 u8 ppe16, ppe8; 4235 u8 nss = min(link_sta->rx_nss, rtwdev->hal.tx_nss) - 1; 4236 u8 ppe_thres_hdr = link_sta->he_cap.ppe_thres[0]; 4237 u8 ru_bitmap; 4238 u8 n, idx, sh; 4239 u16 ppe; 4240 int i; 4241 4242 ppe_th = FIELD_GET(IEEE80211_HE_PHY_CAP6_PPE_THRESHOLD_PRESENT, 4243 link_sta->he_cap.he_cap_elem.phy_cap_info[6]); 4244 if (!ppe_th) { 4245 u8 pad; 4246 4247 pad = FIELD_GET(IEEE80211_HE_PHY_CAP9_NOMINAL_PKT_PADDING_MASK, 4248 link_sta->he_cap.he_cap_elem.phy_cap_info[9]); 4249 4250 for (i = 0; i < RTW89_PPE_BW_NUM; i++) 4251 pads[i] = pad; 4252 4253 return; 4254 } 4255 4256 ru_bitmap = FIELD_GET(IEEE80211_PPE_THRES_RU_INDEX_BITMASK_MASK, ppe_thres_hdr); 4257 n = hweight8(ru_bitmap); 4258 n = 7 + (n * IEEE80211_PPE_THRES_INFO_PPET_SIZE * 2) * nss; 4259 4260 for (i = 0; i < RTW89_PPE_BW_NUM; i++) { 4261 if (!(ru_bitmap & BIT(i))) { 4262 pads[i] = 1; 4263 continue; 4264 } 4265 4266 idx = n >> 3; 4267 sh = n & 7; 4268 n += IEEE80211_PPE_THRES_INFO_PPET_SIZE * 2; 4269 4270 ppe = le16_to_cpu(*((__le16 *)&link_sta->he_cap.ppe_thres[idx])); 4271 ppe16 = (ppe >> sh) & IEEE80211_PPE_THRES_NSS_MASK; 4272 sh += IEEE80211_PPE_THRES_INFO_PPET_SIZE; 4273 ppe8 = (ppe >> sh) & IEEE80211_PPE_THRES_NSS_MASK; 4274 4275 if (ppe16 != 7 && ppe8 == 7) 4276 pads[i] = RTW89_PE_DURATION_16; 4277 else if (ppe8 != 7) 4278 pads[i] = RTW89_PE_DURATION_8; 4279 else 4280 pads[i] = RTW89_PE_DURATION_0; 4281 } 4282 } 4283 4284 int rtw89_fw_h2c_assoc_cmac_tbl(struct rtw89_dev *rtwdev, 4285 struct rtw89_vif_link *rtwvif_link, 4286 struct rtw89_sta_link *rtwsta_link) 4287 { 4288 struct ieee80211_vif *vif = rtwvif_link_to_vif(rtwvif_link); 4289 const struct rtw89_chip_info *chip = rtwdev->chip; 4290 const struct rtw89_chan *chan = rtw89_chan_get(rtwdev, 4291 rtwvif_link->chanctx_idx); 4292 struct ieee80211_link_sta *link_sta; 4293 struct sk_buff *skb; 4294 u8 pads[RTW89_PPE_BW_NUM]; 4295 u8 mac_id = rtwsta_link ? rtwsta_link->mac_id : rtwvif_link->mac_id; 4296 u16 lowest_rate; 4297 int ret; 4298 4299 memset(pads, 0, sizeof(pads)); 4300 4301 skb = rtw89_fw_h2c_alloc_skb_with_hdr(rtwdev, H2C_CMC_TBL_LEN); 4302 if (!skb) { 4303 rtw89_err(rtwdev, "failed to alloc skb for fw dl\n"); 4304 return -ENOMEM; 4305 } 4306 4307 rcu_read_lock(); 4308 4309 if (rtwsta_link) 4310 link_sta = rtw89_sta_rcu_dereference_link(rtwsta_link, true); 4311 4312 if (rtwsta_link && link_sta->he_cap.has_he) 4313 __get_sta_he_pkt_padding(rtwdev, link_sta, pads); 4314 4315 if (vif->p2p) 4316 lowest_rate = RTW89_HW_RATE_OFDM6; 4317 else if (chan->band_type == RTW89_BAND_2G) 4318 lowest_rate = RTW89_HW_RATE_CCK1; 4319 else 4320 lowest_rate = RTW89_HW_RATE_OFDM6; 4321 4322 skb_put(skb, H2C_CMC_TBL_LEN); 4323 SET_CTRL_INFO_MACID(skb->data, mac_id); 4324 SET_CTRL_INFO_OPERATION(skb->data, 1); 4325 SET_CMC_TBL_DISRTSFB(skb->data, 1); 4326 SET_CMC_TBL_DISDATAFB(skb->data, 1); 4327 SET_CMC_TBL_RTS_RTY_LOWEST_RATE(skb->data, lowest_rate); 4328 SET_CMC_TBL_RTS_TXCNT_LMT_SEL(skb->data, 0); 4329 SET_CMC_TBL_DATA_TXCNT_LMT_SEL(skb->data, 0); 4330 if (vif->type == NL80211_IFTYPE_STATION) 4331 SET_CMC_TBL_ULDL(skb->data, 1); 4332 else 4333 SET_CMC_TBL_ULDL(skb->data, 0); 4334 SET_CMC_TBL_MULTI_PORT_ID(skb->data, rtwvif_link->port); 4335 if (chip->h2c_cctl_func_id == H2C_FUNC_MAC_CCTLINFO_UD_V1) { 4336 SET_CMC_TBL_NOMINAL_PKT_PADDING_V1(skb->data, pads[RTW89_CHANNEL_WIDTH_20]); 4337 SET_CMC_TBL_NOMINAL_PKT_PADDING40_V1(skb->data, pads[RTW89_CHANNEL_WIDTH_40]); 4338 SET_CMC_TBL_NOMINAL_PKT_PADDING80_V1(skb->data, pads[RTW89_CHANNEL_WIDTH_80]); 4339 SET_CMC_TBL_NOMINAL_PKT_PADDING160_V1(skb->data, pads[RTW89_CHANNEL_WIDTH_160]); 4340 } else if (chip->h2c_cctl_func_id == H2C_FUNC_MAC_CCTLINFO_UD) { 4341 SET_CMC_TBL_NOMINAL_PKT_PADDING(skb->data, pads[RTW89_CHANNEL_WIDTH_20]); 4342 SET_CMC_TBL_NOMINAL_PKT_PADDING40(skb->data, pads[RTW89_CHANNEL_WIDTH_40]); 4343 SET_CMC_TBL_NOMINAL_PKT_PADDING80(skb->data, pads[RTW89_CHANNEL_WIDTH_80]); 4344 SET_CMC_TBL_NOMINAL_PKT_PADDING160(skb->data, pads[RTW89_CHANNEL_WIDTH_160]); 4345 } 4346 if (rtwsta_link) 4347 SET_CMC_TBL_BSR_QUEUE_SIZE_FORMAT(skb->data, 4348 link_sta->he_cap.has_he); 4349 if (rtwvif_link->net_type == RTW89_NET_TYPE_AP_MODE) 4350 SET_CMC_TBL_DATA_DCM(skb->data, 0); 4351 4352 rcu_read_unlock(); 4353 4354 rtw89_h2c_pkt_set_hdr(rtwdev, skb, FWCMD_TYPE_H2C, 4355 H2C_CAT_MAC, H2C_CL_MAC_FR_EXCHG, 4356 chip->h2c_cctl_func_id, 0, 1, 4357 H2C_CMC_TBL_LEN); 4358 4359 ret = rtw89_h2c_tx(rtwdev, skb, false); 4360 if (ret) { 4361 rtw89_err(rtwdev, "failed to send h2c\n"); 4362 goto fail; 4363 } 4364 4365 return 0; 4366 fail: 4367 dev_kfree_skb_any(skb); 4368 4369 return ret; 4370 } 4371 EXPORT_SYMBOL(rtw89_fw_h2c_assoc_cmac_tbl); 4372 4373 static void __get_sta_eht_pkt_padding(struct rtw89_dev *rtwdev, 4374 struct ieee80211_link_sta *link_sta, 4375 u8 *pads) 4376 { 4377 u8 nss = min(link_sta->rx_nss, rtwdev->hal.tx_nss) - 1; 4378 u16 ppe_thres_hdr; 4379 u8 ppe16, ppe8; 4380 u8 n, idx, sh; 4381 u8 ru_bitmap; 4382 bool ppe_th; 4383 u16 ppe; 4384 int i; 4385 4386 ppe_th = !!u8_get_bits(link_sta->eht_cap.eht_cap_elem.phy_cap_info[5], 4387 IEEE80211_EHT_PHY_CAP5_PPE_THRESHOLD_PRESENT); 4388 if (!ppe_th) { 4389 u8 pad; 4390 4391 pad = u8_get_bits(link_sta->eht_cap.eht_cap_elem.phy_cap_info[5], 4392 IEEE80211_EHT_PHY_CAP5_COMMON_NOMINAL_PKT_PAD_MASK); 4393 4394 for (i = 0; i < RTW89_PPE_BW_NUM; i++) 4395 pads[i] = pad; 4396 4397 return; 4398 } 4399 4400 ppe_thres_hdr = get_unaligned_le16(link_sta->eht_cap.eht_ppe_thres); 4401 ru_bitmap = u16_get_bits(ppe_thres_hdr, 4402 IEEE80211_EHT_PPE_THRES_RU_INDEX_BITMASK_MASK); 4403 n = hweight8(ru_bitmap); 4404 n = IEEE80211_EHT_PPE_THRES_INFO_HEADER_SIZE + 4405 (n * IEEE80211_EHT_PPE_THRES_INFO_PPET_SIZE * 2) * nss; 4406 4407 for (i = 0; i < RTW89_PPE_BW_NUM; i++) { 4408 if (!(ru_bitmap & BIT(i))) { 4409 pads[i] = 1; 4410 continue; 4411 } 4412 4413 idx = n >> 3; 4414 sh = n & 7; 4415 n += IEEE80211_EHT_PPE_THRES_INFO_PPET_SIZE * 2; 4416 4417 ppe = get_unaligned_le16(link_sta->eht_cap.eht_ppe_thres + idx); 4418 ppe16 = (ppe >> sh) & IEEE80211_PPE_THRES_NSS_MASK; 4419 sh += IEEE80211_EHT_PPE_THRES_INFO_PPET_SIZE; 4420 ppe8 = (ppe >> sh) & IEEE80211_PPE_THRES_NSS_MASK; 4421 4422 if (ppe16 != 7 && ppe8 == 7) 4423 pads[i] = RTW89_PE_DURATION_16_20; 4424 else if (ppe8 != 7) 4425 pads[i] = RTW89_PE_DURATION_8; 4426 else 4427 pads[i] = RTW89_PE_DURATION_0; 4428 } 4429 } 4430 4431 int rtw89_fw_h2c_assoc_cmac_tbl_g7(struct rtw89_dev *rtwdev, 4432 struct rtw89_vif_link *rtwvif_link, 4433 struct rtw89_sta_link *rtwsta_link) 4434 { 4435 struct ieee80211_vif *vif = rtwvif_link_to_vif(rtwvif_link); 4436 const struct rtw89_chan *chan = rtw89_chan_get(rtwdev, rtwvif_link->chanctx_idx); 4437 u8 mac_id = rtwsta_link ? rtwsta_link->mac_id : rtwvif_link->mac_id; 4438 struct rtw89_h2c_cctlinfo_ud_g7 *h2c; 4439 struct ieee80211_bss_conf *bss_conf; 4440 struct ieee80211_link_sta *link_sta; 4441 u8 pads[RTW89_PPE_BW_NUM]; 4442 u32 len = sizeof(*h2c); 4443 struct sk_buff *skb; 4444 u16 lowest_rate; 4445 int ret; 4446 4447 memset(pads, 0, sizeof(pads)); 4448 4449 skb = rtw89_fw_h2c_alloc_skb_with_hdr(rtwdev, len); 4450 if (!skb) { 4451 rtw89_err(rtwdev, "failed to alloc skb for cmac g7\n"); 4452 return -ENOMEM; 4453 } 4454 4455 rcu_read_lock(); 4456 4457 bss_conf = rtw89_vif_rcu_dereference_link(rtwvif_link, true); 4458 4459 if (rtwsta_link) { 4460 link_sta = rtw89_sta_rcu_dereference_link(rtwsta_link, true); 4461 4462 if (link_sta->eht_cap.has_eht) 4463 __get_sta_eht_pkt_padding(rtwdev, link_sta, pads); 4464 else if (link_sta->he_cap.has_he) 4465 __get_sta_he_pkt_padding(rtwdev, link_sta, pads); 4466 } 4467 4468 if (vif->p2p) 4469 lowest_rate = RTW89_HW_RATE_OFDM6; 4470 else if (chan->band_type == RTW89_BAND_2G) 4471 lowest_rate = RTW89_HW_RATE_CCK1; 4472 else 4473 lowest_rate = RTW89_HW_RATE_OFDM6; 4474 4475 skb_put(skb, len); 4476 h2c = (struct rtw89_h2c_cctlinfo_ud_g7 *)skb->data; 4477 4478 h2c->c0 = le32_encode_bits(mac_id, CCTLINFO_G7_C0_MACID) | 4479 le32_encode_bits(1, CCTLINFO_G7_C0_OP); 4480 4481 h2c->w0 = le32_encode_bits(1, CCTLINFO_G7_W0_DISRTSFB) | 4482 le32_encode_bits(1, CCTLINFO_G7_W0_DISDATAFB); 4483 h2c->m0 = cpu_to_le32(CCTLINFO_G7_W0_DISRTSFB | 4484 CCTLINFO_G7_W0_DISDATAFB); 4485 4486 h2c->w1 = le32_encode_bits(lowest_rate, CCTLINFO_G7_W1_RTS_RTY_LOWEST_RATE); 4487 h2c->m1 = cpu_to_le32(CCTLINFO_G7_W1_RTS_RTY_LOWEST_RATE); 4488 4489 h2c->w2 = le32_encode_bits(0, CCTLINFO_G7_W2_DATA_TXCNT_LMT_SEL); 4490 h2c->m2 = cpu_to_le32(CCTLINFO_G7_W2_DATA_TXCNT_LMT_SEL); 4491 4492 h2c->w3 = le32_encode_bits(0, CCTLINFO_G7_W3_RTS_TXCNT_LMT_SEL); 4493 h2c->m3 = cpu_to_le32(CCTLINFO_G7_W3_RTS_TXCNT_LMT_SEL); 4494 4495 h2c->w4 = le32_encode_bits(rtwvif_link->port, CCTLINFO_G7_W4_MULTI_PORT_ID); 4496 h2c->m4 = cpu_to_le32(CCTLINFO_G7_W4_MULTI_PORT_ID); 4497 4498 if (rtwvif_link->net_type == RTW89_NET_TYPE_AP_MODE) { 4499 h2c->w4 |= le32_encode_bits(0, CCTLINFO_G7_W4_DATA_DCM); 4500 h2c->m4 |= cpu_to_le32(CCTLINFO_G7_W4_DATA_DCM); 4501 } 4502 4503 if (bss_conf->eht_support) { 4504 u16 punct = bss_conf->chanreq.oper.punctured; 4505 4506 h2c->w4 |= le32_encode_bits(~punct, 4507 CCTLINFO_G7_W4_ACT_SUBCH_CBW); 4508 h2c->m4 |= cpu_to_le32(CCTLINFO_G7_W4_ACT_SUBCH_CBW); 4509 } 4510 4511 h2c->w5 = le32_encode_bits(pads[RTW89_CHANNEL_WIDTH_20], 4512 CCTLINFO_G7_W5_NOMINAL_PKT_PADDING0) | 4513 le32_encode_bits(pads[RTW89_CHANNEL_WIDTH_40], 4514 CCTLINFO_G7_W5_NOMINAL_PKT_PADDING1) | 4515 le32_encode_bits(pads[RTW89_CHANNEL_WIDTH_80], 4516 CCTLINFO_G7_W5_NOMINAL_PKT_PADDING2) | 4517 le32_encode_bits(pads[RTW89_CHANNEL_WIDTH_160], 4518 CCTLINFO_G7_W5_NOMINAL_PKT_PADDING3) | 4519 le32_encode_bits(pads[RTW89_CHANNEL_WIDTH_320], 4520 CCTLINFO_G7_W5_NOMINAL_PKT_PADDING4); 4521 h2c->m5 = cpu_to_le32(CCTLINFO_G7_W5_NOMINAL_PKT_PADDING0 | 4522 CCTLINFO_G7_W5_NOMINAL_PKT_PADDING1 | 4523 CCTLINFO_G7_W5_NOMINAL_PKT_PADDING2 | 4524 CCTLINFO_G7_W5_NOMINAL_PKT_PADDING3 | 4525 CCTLINFO_G7_W5_NOMINAL_PKT_PADDING4); 4526 4527 h2c->w6 = le32_encode_bits(vif->cfg.aid, CCTLINFO_G7_W6_AID12_PAID) | 4528 le32_encode_bits(vif->type == NL80211_IFTYPE_STATION ? 1 : 0, 4529 CCTLINFO_G7_W6_ULDL); 4530 h2c->m6 = cpu_to_le32(CCTLINFO_G7_W6_AID12_PAID | CCTLINFO_G7_W6_ULDL); 4531 4532 if (rtwsta_link) { 4533 h2c->w8 = le32_encode_bits(link_sta->he_cap.has_he, 4534 CCTLINFO_G7_W8_BSR_QUEUE_SIZE_FORMAT); 4535 h2c->m8 = cpu_to_le32(CCTLINFO_G7_W8_BSR_QUEUE_SIZE_FORMAT); 4536 } 4537 4538 rcu_read_unlock(); 4539 4540 rtw89_h2c_pkt_set_hdr(rtwdev, skb, FWCMD_TYPE_H2C, 4541 H2C_CAT_MAC, H2C_CL_MAC_FR_EXCHG, 4542 H2C_FUNC_MAC_CCTLINFO_UD_G7, 0, 1, 4543 len); 4544 4545 ret = rtw89_h2c_tx(rtwdev, skb, false); 4546 if (ret) { 4547 rtw89_err(rtwdev, "failed to send h2c\n"); 4548 goto fail; 4549 } 4550 4551 return 0; 4552 fail: 4553 dev_kfree_skb_any(skb); 4554 4555 return ret; 4556 } 4557 EXPORT_SYMBOL(rtw89_fw_h2c_assoc_cmac_tbl_g7); 4558 4559 int rtw89_fw_h2c_assoc_cmac_tbl_be(struct rtw89_dev *rtwdev, 4560 struct rtw89_vif_link *rtwvif_link, 4561 struct rtw89_sta_link *rtwsta_link) 4562 { 4563 struct ieee80211_vif *vif = rtwvif_link_to_vif(rtwvif_link); 4564 const struct rtw89_chan *chan = rtw89_chan_get(rtwdev, rtwvif_link->chanctx_idx); 4565 u8 mac_id = rtwsta_link ? rtwsta_link->mac_id : rtwvif_link->mac_id; 4566 struct rtw89_h2c_cctlinfo_ud_be *h2c; 4567 struct ieee80211_bss_conf *bss_conf; 4568 struct ieee80211_link_sta *link_sta; 4569 u8 pads[RTW89_PPE_BW_NUM]; 4570 u32 len = sizeof(*h2c); 4571 struct sk_buff *skb; 4572 u16 lowest_rate; 4573 int ret; 4574 4575 memset(pads, 0, sizeof(pads)); 4576 4577 skb = rtw89_fw_h2c_alloc_skb_with_hdr(rtwdev, len); 4578 if (!skb) { 4579 rtw89_err(rtwdev, "failed to alloc skb for assoc cmac be\n"); 4580 return -ENOMEM; 4581 } 4582 4583 rcu_read_lock(); 4584 4585 bss_conf = rtw89_vif_rcu_dereference_link(rtwvif_link, true); 4586 4587 if (rtwsta_link) { 4588 link_sta = rtw89_sta_rcu_dereference_link(rtwsta_link, true); 4589 4590 if (link_sta->eht_cap.has_eht) 4591 __get_sta_eht_pkt_padding(rtwdev, link_sta, pads); 4592 else if (link_sta->he_cap.has_he) 4593 __get_sta_he_pkt_padding(rtwdev, link_sta, pads); 4594 } 4595 4596 if (vif->p2p) 4597 lowest_rate = RTW89_HW_RATE_OFDM6; 4598 else if (chan->band_type == RTW89_BAND_2G) 4599 lowest_rate = RTW89_HW_RATE_CCK1; 4600 else 4601 lowest_rate = RTW89_HW_RATE_OFDM6; 4602 4603 skb_put(skb, len); 4604 h2c = (struct rtw89_h2c_cctlinfo_ud_be *)skb->data; 4605 4606 h2c->c0 = le32_encode_bits(mac_id, BE_CCTL_INFO_C0_V1_MACID) | 4607 le32_encode_bits(1, BE_CCTL_INFO_C0_V1_OP); 4608 4609 h2c->w0 = le32_encode_bits(1, BE_CCTL_INFO_W0_DISRTSFB) | 4610 le32_encode_bits(1, BE_CCTL_INFO_W0_DISDATAFB); 4611 h2c->m0 = cpu_to_le32(BE_CCTL_INFO_W0_DISRTSFB | 4612 BE_CCTL_INFO_W0_DISDATAFB); 4613 4614 h2c->w1 = le32_encode_bits(lowest_rate, BE_CCTL_INFO_W1_RTS_RTY_LOWEST_RATE); 4615 h2c->m1 = cpu_to_le32(BE_CCTL_INFO_W1_RTS_RTY_LOWEST_RATE); 4616 4617 h2c->w2 = le32_encode_bits(0, BE_CCTL_INFO_W2_DATA_TXCNT_LMT_SEL); 4618 h2c->m2 = cpu_to_le32(BE_CCTL_INFO_W2_DATA_TXCNT_LMT_SEL); 4619 4620 h2c->w3 = le32_encode_bits(0, BE_CCTL_INFO_W3_RTS_TXCNT_LMT_SEL); 4621 h2c->m3 = cpu_to_le32(BE_CCTL_INFO_W3_RTS_TXCNT_LMT_SEL); 4622 4623 h2c->w4 = le32_encode_bits(rtwvif_link->port, BE_CCTL_INFO_W4_MULTI_PORT_ID); 4624 h2c->m4 = cpu_to_le32(BE_CCTL_INFO_W4_MULTI_PORT_ID); 4625 4626 if (bss_conf->eht_support) { 4627 u16 punct = bss_conf->chanreq.oper.punctured; 4628 4629 h2c->w4 |= le32_encode_bits(~punct, 4630 BE_CCTL_INFO_W4_ACT_SUBCH_CBW); 4631 h2c->m4 |= cpu_to_le32(BE_CCTL_INFO_W4_ACT_SUBCH_CBW); 4632 } 4633 4634 h2c->w5 = le32_encode_bits(pads[RTW89_CHANNEL_WIDTH_20], 4635 BE_CCTL_INFO_W5_NOMINAL_PKT_PADDING0_V1) | 4636 le32_encode_bits(pads[RTW89_CHANNEL_WIDTH_40], 4637 BE_CCTL_INFO_W5_NOMINAL_PKT_PADDING1_V1) | 4638 le32_encode_bits(pads[RTW89_CHANNEL_WIDTH_80], 4639 BE_CCTL_INFO_W5_NOMINAL_PKT_PADDING2_V1) | 4640 le32_encode_bits(pads[RTW89_CHANNEL_WIDTH_160], 4641 BE_CCTL_INFO_W5_NOMINAL_PKT_PADDING3_V1) | 4642 le32_encode_bits(pads[RTW89_CHANNEL_WIDTH_320], 4643 BE_CCTL_INFO_W5_NOMINAL_PKT_PADDING4_V1); 4644 h2c->m5 = cpu_to_le32(BE_CCTL_INFO_W5_NOMINAL_PKT_PADDING0_V1 | 4645 BE_CCTL_INFO_W5_NOMINAL_PKT_PADDING1_V1 | 4646 BE_CCTL_INFO_W5_NOMINAL_PKT_PADDING2_V1 | 4647 BE_CCTL_INFO_W5_NOMINAL_PKT_PADDING3_V1 | 4648 BE_CCTL_INFO_W5_NOMINAL_PKT_PADDING4_V1); 4649 4650 if (rtwvif_link->net_type == RTW89_NET_TYPE_AP_MODE) { 4651 h2c->w5 |= le32_encode_bits(0, BE_CCTL_INFO_W5_DATA_DCM_V1); 4652 h2c->m5 |= cpu_to_le32(BE_CCTL_INFO_W5_DATA_DCM_V1); 4653 } 4654 4655 h2c->w6 = le32_encode_bits(vif->cfg.aid, BE_CCTL_INFO_W6_AID12_PAID) | 4656 le32_encode_bits(vif->type == NL80211_IFTYPE_STATION ? 1 : 0, 4657 BE_CCTL_INFO_W6_ULDL); 4658 h2c->m6 = cpu_to_le32(BE_CCTL_INFO_W6_AID12_PAID | BE_CCTL_INFO_W6_ULDL); 4659 4660 if (rtwsta_link) { 4661 h2c->w8 = le32_encode_bits(link_sta->he_cap.has_he, 4662 BE_CCTL_INFO_W8_BSR_QUEUE_SIZE_FORMAT_V1); 4663 h2c->m8 = cpu_to_le32(BE_CCTL_INFO_W8_BSR_QUEUE_SIZE_FORMAT_V1); 4664 } 4665 4666 rcu_read_unlock(); 4667 4668 rtw89_h2c_pkt_set_hdr(rtwdev, skb, FWCMD_TYPE_H2C, 4669 H2C_CAT_MAC, H2C_CL_MAC_FR_EXCHG, 4670 H2C_FUNC_MAC_CCTLINFO_UD_G7, 0, 1, 4671 len); 4672 4673 ret = rtw89_h2c_tx(rtwdev, skb, false); 4674 if (ret) { 4675 rtw89_err(rtwdev, "failed to send h2c\n"); 4676 goto fail; 4677 } 4678 4679 return 0; 4680 fail: 4681 dev_kfree_skb_any(skb); 4682 4683 return ret; 4684 } 4685 EXPORT_SYMBOL(rtw89_fw_h2c_assoc_cmac_tbl_be); 4686 4687 int rtw89_fw_h2c_ampdu_cmac_tbl_g7(struct rtw89_dev *rtwdev, 4688 struct rtw89_vif_link *rtwvif_link, 4689 struct rtw89_sta_link *rtwsta_link) 4690 { 4691 struct rtw89_sta *rtwsta = rtwsta_link->rtwsta; 4692 struct rtw89_h2c_cctlinfo_ud_g7 *h2c; 4693 u32 len = sizeof(*h2c); 4694 struct sk_buff *skb; 4695 u16 agg_num = 0; 4696 u8 ba_bmap = 0; 4697 int ret; 4698 u8 tid; 4699 4700 skb = rtw89_fw_h2c_alloc_skb_with_hdr(rtwdev, len); 4701 if (!skb) { 4702 rtw89_err(rtwdev, "failed to alloc skb for ampdu cmac g7\n"); 4703 return -ENOMEM; 4704 } 4705 skb_put(skb, len); 4706 h2c = (struct rtw89_h2c_cctlinfo_ud_g7 *)skb->data; 4707 4708 for_each_set_bit(tid, rtwsta->ampdu_map, IEEE80211_NUM_TIDS) { 4709 if (agg_num == 0) 4710 agg_num = rtwsta->ampdu_params[tid].agg_num; 4711 else 4712 agg_num = min(agg_num, rtwsta->ampdu_params[tid].agg_num); 4713 } 4714 4715 if (agg_num <= 0x20) 4716 ba_bmap = 3; 4717 else if (agg_num > 0x20 && agg_num <= 0x40) 4718 ba_bmap = 0; 4719 else if (agg_num > 0x40 && agg_num <= 0x80) 4720 ba_bmap = 1; 4721 else if (agg_num > 0x80 && agg_num <= 0x100) 4722 ba_bmap = 2; 4723 else if (agg_num > 0x100 && agg_num <= 0x200) 4724 ba_bmap = 4; 4725 else if (agg_num > 0x200 && agg_num <= 0x400) 4726 ba_bmap = 5; 4727 4728 h2c->c0 = le32_encode_bits(rtwsta_link->mac_id, CCTLINFO_G7_C0_MACID) | 4729 le32_encode_bits(1, CCTLINFO_G7_C0_OP); 4730 4731 h2c->w3 = le32_encode_bits(ba_bmap, CCTLINFO_G7_W3_BA_BMAP); 4732 h2c->m3 = cpu_to_le32(CCTLINFO_G7_W3_BA_BMAP); 4733 4734 rtw89_h2c_pkt_set_hdr(rtwdev, skb, FWCMD_TYPE_H2C, 4735 H2C_CAT_MAC, H2C_CL_MAC_FR_EXCHG, 4736 H2C_FUNC_MAC_CCTLINFO_UD_G7, 0, 0, 4737 len); 4738 4739 ret = rtw89_h2c_tx(rtwdev, skb, false); 4740 if (ret) { 4741 rtw89_err(rtwdev, "failed to send h2c\n"); 4742 goto fail; 4743 } 4744 4745 return 0; 4746 fail: 4747 dev_kfree_skb_any(skb); 4748 4749 return ret; 4750 } 4751 EXPORT_SYMBOL(rtw89_fw_h2c_ampdu_cmac_tbl_g7); 4752 4753 int rtw89_fw_h2c_ampdu_cmac_tbl_be(struct rtw89_dev *rtwdev, 4754 struct rtw89_vif_link *rtwvif_link, 4755 struct rtw89_sta_link *rtwsta_link) 4756 { 4757 struct rtw89_sta *rtwsta = rtwsta_link->rtwsta; 4758 struct rtw89_h2c_cctlinfo_ud_be *h2c; 4759 u32 len = sizeof(*h2c); 4760 struct sk_buff *skb; 4761 u16 agg_num = 0; 4762 u8 ba_bmap = 0; 4763 int ret; 4764 u8 tid; 4765 4766 skb = rtw89_fw_h2c_alloc_skb_with_hdr(rtwdev, len); 4767 if (!skb) { 4768 rtw89_err(rtwdev, "failed to alloc skb for ampdu cmac be\n"); 4769 return -ENOMEM; 4770 } 4771 skb_put(skb, len); 4772 h2c = (struct rtw89_h2c_cctlinfo_ud_be *)skb->data; 4773 4774 for_each_set_bit(tid, rtwsta->ampdu_map, IEEE80211_NUM_TIDS) { 4775 if (agg_num == 0) 4776 agg_num = rtwsta->ampdu_params[tid].agg_num; 4777 else 4778 agg_num = min(agg_num, rtwsta->ampdu_params[tid].agg_num); 4779 } 4780 4781 if (agg_num <= 0x20) 4782 ba_bmap = 3; 4783 else if (agg_num > 0x20 && agg_num <= 0x40) 4784 ba_bmap = 0; 4785 else if (agg_num > 0x40 && agg_num <= 0x80) 4786 ba_bmap = 1; 4787 else if (agg_num > 0x80 && agg_num <= 0x100) 4788 ba_bmap = 2; 4789 else if (agg_num > 0x100 && agg_num <= 0x200) 4790 ba_bmap = 4; 4791 else if (agg_num > 0x200 && agg_num <= 0x400) 4792 ba_bmap = 5; 4793 4794 h2c->c0 = le32_encode_bits(rtwsta_link->mac_id, BE_CCTL_INFO_C0_V1_MACID) | 4795 le32_encode_bits(1, BE_CCTL_INFO_C0_V1_OP); 4796 4797 h2c->w3 = le32_encode_bits(ba_bmap, BE_CCTL_INFO_W3_BA_BMAP); 4798 h2c->m3 = cpu_to_le32(BE_CCTL_INFO_W3_BA_BMAP); 4799 4800 rtw89_h2c_pkt_set_hdr(rtwdev, skb, FWCMD_TYPE_H2C, 4801 H2C_CAT_MAC, H2C_CL_MAC_FR_EXCHG, 4802 H2C_FUNC_MAC_CCTLINFO_UD_G7, 0, 0, 4803 len); 4804 4805 ret = rtw89_h2c_tx(rtwdev, skb, false); 4806 if (ret) { 4807 rtw89_err(rtwdev, "failed to send h2c\n"); 4808 goto fail; 4809 } 4810 4811 return 0; 4812 fail: 4813 dev_kfree_skb_any(skb); 4814 4815 return ret; 4816 } 4817 EXPORT_SYMBOL(rtw89_fw_h2c_ampdu_cmac_tbl_be); 4818 4819 int rtw89_fw_h2c_txtime_cmac_tbl(struct rtw89_dev *rtwdev, 4820 struct rtw89_sta_link *rtwsta_link) 4821 { 4822 const struct rtw89_chip_info *chip = rtwdev->chip; 4823 struct sk_buff *skb; 4824 int ret; 4825 4826 skb = rtw89_fw_h2c_alloc_skb_with_hdr(rtwdev, H2C_CMC_TBL_LEN); 4827 if (!skb) { 4828 rtw89_err(rtwdev, "failed to alloc skb for fw dl\n"); 4829 return -ENOMEM; 4830 } 4831 skb_put(skb, H2C_CMC_TBL_LEN); 4832 SET_CTRL_INFO_MACID(skb->data, rtwsta_link->mac_id); 4833 SET_CTRL_INFO_OPERATION(skb->data, 1); 4834 if (rtwsta_link->cctl_tx_time) { 4835 SET_CMC_TBL_AMPDU_TIME_SEL(skb->data, 1); 4836 SET_CMC_TBL_AMPDU_MAX_TIME(skb->data, rtwsta_link->ampdu_max_time); 4837 } 4838 if (rtwsta_link->cctl_tx_retry_limit) { 4839 SET_CMC_TBL_DATA_TXCNT_LMT_SEL(skb->data, 1); 4840 SET_CMC_TBL_DATA_TX_CNT_LMT(skb->data, rtwsta_link->data_tx_cnt_lmt); 4841 } 4842 4843 rtw89_h2c_pkt_set_hdr(rtwdev, skb, FWCMD_TYPE_H2C, 4844 H2C_CAT_MAC, H2C_CL_MAC_FR_EXCHG, 4845 chip->h2c_cctl_func_id, 0, 1, 4846 H2C_CMC_TBL_LEN); 4847 4848 ret = rtw89_h2c_tx(rtwdev, skb, false); 4849 if (ret) { 4850 rtw89_err(rtwdev, "failed to send h2c\n"); 4851 goto fail; 4852 } 4853 4854 return 0; 4855 fail: 4856 dev_kfree_skb_any(skb); 4857 4858 return ret; 4859 } 4860 EXPORT_SYMBOL(rtw89_fw_h2c_txtime_cmac_tbl); 4861 4862 int rtw89_fw_h2c_txtime_cmac_tbl_g7(struct rtw89_dev *rtwdev, 4863 struct rtw89_sta_link *rtwsta_link) 4864 { 4865 struct rtw89_h2c_cctlinfo_ud_g7 *h2c; 4866 u32 len = sizeof(*h2c); 4867 struct sk_buff *skb; 4868 int ret; 4869 4870 skb = rtw89_fw_h2c_alloc_skb_with_hdr(rtwdev, len); 4871 if (!skb) { 4872 rtw89_err(rtwdev, "failed to alloc skb for txtime_cmac_g7\n"); 4873 return -ENOMEM; 4874 } 4875 skb_put(skb, len); 4876 h2c = (struct rtw89_h2c_cctlinfo_ud_g7 *)skb->data; 4877 4878 h2c->c0 = le32_encode_bits(rtwsta_link->mac_id, CCTLINFO_G7_C0_MACID) | 4879 le32_encode_bits(1, CCTLINFO_G7_C0_OP); 4880 4881 if (rtwsta_link->cctl_tx_time) { 4882 h2c->w3 |= le32_encode_bits(1, CCTLINFO_G7_W3_AMPDU_TIME_SEL); 4883 h2c->m3 |= cpu_to_le32(CCTLINFO_G7_W3_AMPDU_TIME_SEL); 4884 4885 h2c->w2 |= le32_encode_bits(rtwsta_link->ampdu_max_time, 4886 CCTLINFO_G7_W2_AMPDU_MAX_TIME); 4887 h2c->m2 |= cpu_to_le32(CCTLINFO_G7_W2_AMPDU_MAX_TIME); 4888 } 4889 if (rtwsta_link->cctl_tx_retry_limit) { 4890 h2c->w2 |= le32_encode_bits(1, CCTLINFO_G7_W2_DATA_TXCNT_LMT_SEL) | 4891 le32_encode_bits(rtwsta_link->data_tx_cnt_lmt, 4892 CCTLINFO_G7_W2_DATA_TX_CNT_LMT); 4893 h2c->m2 |= cpu_to_le32(CCTLINFO_G7_W2_DATA_TXCNT_LMT_SEL | 4894 CCTLINFO_G7_W2_DATA_TX_CNT_LMT); 4895 } 4896 4897 rtw89_h2c_pkt_set_hdr(rtwdev, skb, FWCMD_TYPE_H2C, 4898 H2C_CAT_MAC, H2C_CL_MAC_FR_EXCHG, 4899 H2C_FUNC_MAC_CCTLINFO_UD_G7, 0, 1, 4900 len); 4901 4902 ret = rtw89_h2c_tx(rtwdev, skb, false); 4903 if (ret) { 4904 rtw89_err(rtwdev, "failed to send h2c\n"); 4905 goto fail; 4906 } 4907 4908 return 0; 4909 fail: 4910 dev_kfree_skb_any(skb); 4911 4912 return ret; 4913 } 4914 EXPORT_SYMBOL(rtw89_fw_h2c_txtime_cmac_tbl_g7); 4915 4916 int rtw89_fw_h2c_txtime_cmac_tbl_be(struct rtw89_dev *rtwdev, 4917 struct rtw89_sta_link *rtwsta_link) 4918 { 4919 struct rtw89_h2c_cctlinfo_ud_be *h2c; 4920 u32 len = sizeof(*h2c); 4921 struct sk_buff *skb; 4922 int ret; 4923 4924 skb = rtw89_fw_h2c_alloc_skb_with_hdr(rtwdev, len); 4925 if (!skb) { 4926 rtw89_err(rtwdev, "failed to alloc skb for txtime_cmac_be\n"); 4927 return -ENOMEM; 4928 } 4929 skb_put(skb, len); 4930 h2c = (struct rtw89_h2c_cctlinfo_ud_be *)skb->data; 4931 4932 h2c->c0 = le32_encode_bits(rtwsta_link->mac_id, BE_CCTL_INFO_C0_V1_MACID) | 4933 le32_encode_bits(1, BE_CCTL_INFO_C0_V1_OP); 4934 4935 if (rtwsta_link->cctl_tx_time) { 4936 h2c->w3 |= le32_encode_bits(1, BE_CCTL_INFO_W3_AMPDU_TIME_SEL); 4937 h2c->m3 |= cpu_to_le32(BE_CCTL_INFO_W3_AMPDU_TIME_SEL); 4938 4939 h2c->w2 |= le32_encode_bits(rtwsta_link->ampdu_max_time, 4940 BE_CCTL_INFO_W2_AMPDU_MAX_TIME); 4941 h2c->m2 |= cpu_to_le32(BE_CCTL_INFO_W2_AMPDU_MAX_TIME); 4942 } 4943 if (rtwsta_link->cctl_tx_retry_limit) { 4944 h2c->w2 |= le32_encode_bits(1, BE_CCTL_INFO_W2_DATA_TXCNT_LMT_SEL) | 4945 le32_encode_bits(rtwsta_link->data_tx_cnt_lmt, 4946 BE_CCTL_INFO_W2_DATA_TX_CNT_LMT); 4947 h2c->m2 |= cpu_to_le32(BE_CCTL_INFO_W2_DATA_TXCNT_LMT_SEL | 4948 BE_CCTL_INFO_W2_DATA_TX_CNT_LMT); 4949 } 4950 4951 rtw89_h2c_pkt_set_hdr(rtwdev, skb, FWCMD_TYPE_H2C, 4952 H2C_CAT_MAC, H2C_CL_MAC_FR_EXCHG, 4953 H2C_FUNC_MAC_CCTLINFO_UD_G7, 0, 1, 4954 len); 4955 4956 ret = rtw89_h2c_tx(rtwdev, skb, false); 4957 if (ret) { 4958 rtw89_err(rtwdev, "failed to send h2c\n"); 4959 goto fail; 4960 } 4961 4962 return 0; 4963 fail: 4964 dev_kfree_skb_any(skb); 4965 4966 return ret; 4967 } 4968 EXPORT_SYMBOL(rtw89_fw_h2c_txtime_cmac_tbl_be); 4969 4970 int rtw89_fw_h2c_punctured_cmac_tbl_g7(struct rtw89_dev *rtwdev, 4971 struct rtw89_vif_link *rtwvif_link, 4972 u16 punctured) 4973 { 4974 struct rtw89_h2c_cctlinfo_ud_g7 *h2c; 4975 u32 len = sizeof(*h2c); 4976 struct sk_buff *skb; 4977 int ret; 4978 4979 skb = rtw89_fw_h2c_alloc_skb_with_hdr(rtwdev, len); 4980 if (!skb) { 4981 rtw89_err(rtwdev, "failed to alloc skb for punctured cmac g7\n"); 4982 return -ENOMEM; 4983 } 4984 4985 skb_put(skb, len); 4986 h2c = (struct rtw89_h2c_cctlinfo_ud_g7 *)skb->data; 4987 4988 h2c->c0 = le32_encode_bits(rtwvif_link->mac_id, CCTLINFO_G7_C0_MACID) | 4989 le32_encode_bits(1, CCTLINFO_G7_C0_OP); 4990 4991 h2c->w4 = le32_encode_bits(~punctured, CCTLINFO_G7_W4_ACT_SUBCH_CBW); 4992 h2c->m4 = cpu_to_le32(CCTLINFO_G7_W4_ACT_SUBCH_CBW); 4993 4994 rtw89_h2c_pkt_set_hdr(rtwdev, skb, FWCMD_TYPE_H2C, 4995 H2C_CAT_MAC, H2C_CL_MAC_FR_EXCHG, 4996 H2C_FUNC_MAC_CCTLINFO_UD_G7, 0, 1, 4997 len); 4998 4999 ret = rtw89_h2c_tx(rtwdev, skb, false); 5000 if (ret) { 5001 rtw89_err(rtwdev, "failed to send h2c\n"); 5002 goto fail; 5003 } 5004 5005 return 0; 5006 fail: 5007 dev_kfree_skb_any(skb); 5008 5009 return ret; 5010 } 5011 EXPORT_SYMBOL(rtw89_fw_h2c_punctured_cmac_tbl_g7); 5012 5013 int rtw89_fw_h2c_punctured_cmac_tbl_be(struct rtw89_dev *rtwdev, 5014 struct rtw89_vif_link *rtwvif_link, 5015 u16 punctured) 5016 { 5017 struct rtw89_h2c_cctlinfo_ud_be *h2c; 5018 u32 len = sizeof(*h2c); 5019 struct sk_buff *skb; 5020 int ret; 5021 5022 skb = rtw89_fw_h2c_alloc_skb_with_hdr(rtwdev, len); 5023 if (!skb) { 5024 rtw89_err(rtwdev, "failed to alloc skb for punctured cmac be\n"); 5025 return -ENOMEM; 5026 } 5027 skb_put(skb, len); 5028 h2c = (struct rtw89_h2c_cctlinfo_ud_be *)skb->data; 5029 5030 h2c->c0 = le32_encode_bits(rtwvif_link->mac_id, BE_CCTL_INFO_C0_V1_MACID) | 5031 le32_encode_bits(1, BE_CCTL_INFO_C0_V1_OP); 5032 5033 h2c->w4 = le32_encode_bits(~punctured, BE_CCTL_INFO_W4_ACT_SUBCH_CBW); 5034 h2c->m4 = cpu_to_le32(BE_CCTL_INFO_W4_ACT_SUBCH_CBW); 5035 5036 rtw89_h2c_pkt_set_hdr(rtwdev, skb, FWCMD_TYPE_H2C, 5037 H2C_CAT_MAC, H2C_CL_MAC_FR_EXCHG, 5038 H2C_FUNC_MAC_CCTLINFO_UD_G7, 0, 1, 5039 len); 5040 5041 ret = rtw89_h2c_tx(rtwdev, skb, false); 5042 if (ret) { 5043 rtw89_err(rtwdev, "failed to send h2c\n"); 5044 goto fail; 5045 } 5046 5047 return 0; 5048 fail: 5049 dev_kfree_skb_any(skb); 5050 5051 return ret; 5052 } 5053 EXPORT_SYMBOL(rtw89_fw_h2c_punctured_cmac_tbl_be); 5054 5055 int rtw89_fw_h2c_txpath_cmac_tbl(struct rtw89_dev *rtwdev, 5056 struct rtw89_sta_link *rtwsta_link) 5057 { 5058 const struct rtw89_chip_info *chip = rtwdev->chip; 5059 struct sk_buff *skb; 5060 int ret; 5061 5062 if (chip->h2c_cctl_func_id != H2C_FUNC_MAC_CCTLINFO_UD) 5063 return 0; 5064 5065 skb = rtw89_fw_h2c_alloc_skb_with_hdr(rtwdev, H2C_CMC_TBL_LEN); 5066 if (!skb) { 5067 rtw89_err(rtwdev, "failed to alloc skb for fw dl\n"); 5068 return -ENOMEM; 5069 } 5070 skb_put(skb, H2C_CMC_TBL_LEN); 5071 SET_CTRL_INFO_MACID(skb->data, rtwsta_link->mac_id); 5072 SET_CTRL_INFO_OPERATION(skb->data, 1); 5073 5074 __rtw89_fw_h2c_set_tx_path(rtwdev, skb); 5075 5076 rtw89_h2c_pkt_set_hdr(rtwdev, skb, FWCMD_TYPE_H2C, 5077 H2C_CAT_MAC, H2C_CL_MAC_FR_EXCHG, 5078 H2C_FUNC_MAC_CCTLINFO_UD, 0, 1, 5079 H2C_CMC_TBL_LEN); 5080 5081 ret = rtw89_h2c_tx(rtwdev, skb, false); 5082 if (ret) { 5083 rtw89_err(rtwdev, "failed to send h2c\n"); 5084 goto fail; 5085 } 5086 5087 return 0; 5088 fail: 5089 dev_kfree_skb_any(skb); 5090 5091 return ret; 5092 } 5093 5094 int rtw89_fw_h2c_update_beacon(struct rtw89_dev *rtwdev, 5095 struct rtw89_vif_link *rtwvif_link) 5096 { 5097 const struct rtw89_chan *chan = rtw89_chan_get(rtwdev, 5098 rtwvif_link->chanctx_idx); 5099 struct ieee80211_vif *vif = rtwvif_link_to_vif(rtwvif_link); 5100 struct rtw89_h2c_bcn_upd *h2c; 5101 struct sk_buff *skb_beacon; 5102 struct ieee80211_hdr *hdr; 5103 u32 len = sizeof(*h2c); 5104 struct sk_buff *skb; 5105 int bcn_total_len; 5106 u16 beacon_rate; 5107 u16 tim_offset; 5108 void *noa_data; 5109 u8 noa_len; 5110 int ret; 5111 5112 if (vif->p2p) 5113 beacon_rate = RTW89_HW_RATE_OFDM6; 5114 else if (chan->band_type == RTW89_BAND_2G) 5115 beacon_rate = RTW89_HW_RATE_CCK1; 5116 else 5117 beacon_rate = RTW89_HW_RATE_OFDM6; 5118 5119 skb_beacon = ieee80211_beacon_get_tim(rtwdev->hw, vif, &tim_offset, 5120 NULL, 0); 5121 if (!skb_beacon) { 5122 rtw89_err(rtwdev, "failed to get beacon skb\n"); 5123 return -ENOMEM; 5124 } 5125 5126 noa_len = rtw89_p2p_noa_fetch(rtwvif_link, &noa_data); 5127 if (noa_len && 5128 (noa_len <= skb_tailroom(skb_beacon) || 5129 pskb_expand_head(skb_beacon, 0, noa_len, GFP_KERNEL) == 0)) { 5130 skb_put_data(skb_beacon, noa_data, noa_len); 5131 } 5132 5133 hdr = (struct ieee80211_hdr *)skb_beacon; 5134 tim_offset -= ieee80211_hdrlen(hdr->frame_control); 5135 5136 bcn_total_len = len + skb_beacon->len; 5137 skb = rtw89_fw_h2c_alloc_skb_with_hdr(rtwdev, bcn_total_len); 5138 if (!skb) { 5139 rtw89_err(rtwdev, "failed to alloc skb for fw dl\n"); 5140 dev_kfree_skb_any(skb_beacon); 5141 return -ENOMEM; 5142 } 5143 skb_put(skb, len); 5144 h2c = (struct rtw89_h2c_bcn_upd *)skb->data; 5145 5146 h2c->w0 = le32_encode_bits(rtwvif_link->port, RTW89_H2C_BCN_UPD_W0_PORT) | 5147 le32_encode_bits(0, RTW89_H2C_BCN_UPD_W0_MBSSID) | 5148 le32_encode_bits(rtwvif_link->mac_idx, RTW89_H2C_BCN_UPD_W0_BAND) | 5149 le32_encode_bits(tim_offset | BIT(7), RTW89_H2C_BCN_UPD_W0_GRP_IE_OFST); 5150 h2c->w1 = le32_encode_bits(rtwvif_link->mac_id, RTW89_H2C_BCN_UPD_W1_MACID) | 5151 le32_encode_bits(RTW89_MGMT_HW_SSN_SEL, RTW89_H2C_BCN_UPD_W1_SSN_SEL) | 5152 le32_encode_bits(RTW89_MGMT_HW_SEQ_MODE, RTW89_H2C_BCN_UPD_W1_SSN_MODE) | 5153 le32_encode_bits(beacon_rate, RTW89_H2C_BCN_UPD_W1_RATE); 5154 5155 skb_put_data(skb, skb_beacon->data, skb_beacon->len); 5156 dev_kfree_skb_any(skb_beacon); 5157 5158 rtw89_h2c_pkt_set_hdr(rtwdev, skb, FWCMD_TYPE_H2C, 5159 H2C_CAT_MAC, H2C_CL_MAC_FR_EXCHG, 5160 H2C_FUNC_MAC_BCN_UPD, 0, 1, 5161 bcn_total_len); 5162 5163 ret = rtw89_h2c_tx(rtwdev, skb, false); 5164 if (ret) { 5165 rtw89_err(rtwdev, "failed to send h2c\n"); 5166 dev_kfree_skb_any(skb); 5167 return ret; 5168 } 5169 5170 return 0; 5171 } 5172 EXPORT_SYMBOL(rtw89_fw_h2c_update_beacon); 5173 5174 int rtw89_fw_h2c_update_beacon_be(struct rtw89_dev *rtwdev, 5175 struct rtw89_vif_link *rtwvif_link) 5176 { 5177 const struct rtw89_chan *chan = rtw89_chan_get(rtwdev, rtwvif_link->chanctx_idx); 5178 struct ieee80211_vif *vif = rtwvif_link_to_vif(rtwvif_link); 5179 struct rtw89_h2c_bcn_upd_be *h2c; 5180 struct sk_buff *skb_beacon; 5181 struct ieee80211_hdr *hdr; 5182 u32 len = sizeof(*h2c); 5183 struct sk_buff *skb; 5184 int bcn_total_len; 5185 u16 beacon_rate; 5186 u16 tim_offset; 5187 void *noa_data; 5188 u8 noa_len; 5189 int ret; 5190 5191 if (vif->p2p) 5192 beacon_rate = RTW89_HW_RATE_OFDM6; 5193 else if (chan->band_type == RTW89_BAND_2G) 5194 beacon_rate = RTW89_HW_RATE_CCK1; 5195 else 5196 beacon_rate = RTW89_HW_RATE_OFDM6; 5197 5198 skb_beacon = ieee80211_beacon_get_tim(rtwdev->hw, vif, &tim_offset, 5199 NULL, 0); 5200 if (!skb_beacon) { 5201 rtw89_err(rtwdev, "failed to get beacon skb\n"); 5202 return -ENOMEM; 5203 } 5204 5205 noa_len = rtw89_p2p_noa_fetch(rtwvif_link, &noa_data); 5206 if (noa_len && 5207 (noa_len <= skb_tailroom(skb_beacon) || 5208 pskb_expand_head(skb_beacon, 0, noa_len, GFP_KERNEL) == 0)) { 5209 skb_put_data(skb_beacon, noa_data, noa_len); 5210 } 5211 5212 hdr = (struct ieee80211_hdr *)skb_beacon; 5213 tim_offset -= ieee80211_hdrlen(hdr->frame_control); 5214 5215 bcn_total_len = len + skb_beacon->len; 5216 skb = rtw89_fw_h2c_alloc_skb_with_hdr(rtwdev, bcn_total_len); 5217 if (!skb) { 5218 rtw89_err(rtwdev, "failed to alloc skb for fw dl\n"); 5219 dev_kfree_skb_any(skb_beacon); 5220 return -ENOMEM; 5221 } 5222 skb_put(skb, len); 5223 h2c = (struct rtw89_h2c_bcn_upd_be *)skb->data; 5224 5225 h2c->w0 = le32_encode_bits(rtwvif_link->port, RTW89_H2C_BCN_UPD_BE_W0_PORT) | 5226 le32_encode_bits(0, RTW89_H2C_BCN_UPD_BE_W0_MBSSID) | 5227 le32_encode_bits(rtwvif_link->mac_idx, RTW89_H2C_BCN_UPD_BE_W0_BAND) | 5228 le32_encode_bits(tim_offset | BIT(7), RTW89_H2C_BCN_UPD_BE_W0_GRP_IE_OFST); 5229 h2c->w1 = le32_encode_bits(rtwvif_link->mac_id, RTW89_H2C_BCN_UPD_BE_W1_MACID) | 5230 le32_encode_bits(RTW89_MGMT_HW_SSN_SEL, RTW89_H2C_BCN_UPD_BE_W1_SSN_SEL) | 5231 le32_encode_bits(RTW89_MGMT_HW_SEQ_MODE, RTW89_H2C_BCN_UPD_BE_W1_SSN_MODE) | 5232 le32_encode_bits(beacon_rate, RTW89_H2C_BCN_UPD_BE_W1_RATE); 5233 5234 skb_put_data(skb, skb_beacon->data, skb_beacon->len); 5235 dev_kfree_skb_any(skb_beacon); 5236 5237 rtw89_h2c_pkt_set_hdr(rtwdev, skb, FWCMD_TYPE_H2C, 5238 H2C_CAT_MAC, H2C_CL_MAC_FR_EXCHG, 5239 H2C_FUNC_MAC_BCN_UPD_BE, 0, 1, 5240 bcn_total_len); 5241 5242 ret = rtw89_h2c_tx(rtwdev, skb, false); 5243 if (ret) { 5244 rtw89_err(rtwdev, "failed to send h2c\n"); 5245 goto fail; 5246 } 5247 5248 return 0; 5249 5250 fail: 5251 dev_kfree_skb_any(skb); 5252 5253 return ret; 5254 } 5255 EXPORT_SYMBOL(rtw89_fw_h2c_update_beacon_be); 5256 5257 int rtw89_fw_h2c_tbtt_tuning(struct rtw89_dev *rtwdev, 5258 struct rtw89_vif_link *rtwvif_link, u32 offset) 5259 { 5260 struct rtw89_h2c_tbtt_tuning *h2c; 5261 u32 len = sizeof(*h2c); 5262 struct sk_buff *skb; 5263 int ret; 5264 5265 skb = rtw89_fw_h2c_alloc_skb_with_hdr(rtwdev, len); 5266 if (!skb) { 5267 rtw89_err(rtwdev, "failed to alloc skb for h2c tbtt tuning\n"); 5268 return -ENOMEM; 5269 } 5270 skb_put(skb, len); 5271 h2c = (struct rtw89_h2c_tbtt_tuning *)skb->data; 5272 5273 h2c->w0 = le32_encode_bits(rtwvif_link->phy_idx, RTW89_H2C_TBTT_TUNING_W0_BAND) | 5274 le32_encode_bits(rtwvif_link->port, RTW89_H2C_TBTT_TUNING_W0_PORT); 5275 h2c->w1 = le32_encode_bits(offset, RTW89_H2C_TBTT_TUNING_W1_SHIFT); 5276 5277 rtw89_h2c_pkt_set_hdr(rtwdev, skb, FWCMD_TYPE_H2C, 5278 H2C_CAT_MAC, H2C_CL_MAC_PS, 5279 H2C_FUNC_TBTT_TUNING, 0, 0, 5280 len); 5281 5282 ret = rtw89_h2c_tx(rtwdev, skb, false); 5283 if (ret) { 5284 rtw89_err(rtwdev, "failed to send h2c\n"); 5285 goto fail; 5286 } 5287 5288 return 0; 5289 fail: 5290 dev_kfree_skb_any(skb); 5291 5292 return ret; 5293 } 5294 5295 int rtw89_fw_h2c_pwr_lvl(struct rtw89_dev *rtwdev, struct rtw89_vif_link *rtwvif_link) 5296 { 5297 #define RTW89_BCN_TO_VAL_MIN 4 5298 #define RTW89_BCN_TO_VAL_MAX 64 5299 #define RTW89_DTIM_TO_VAL_MIN 7 5300 #define RTW89_DTIM_TO_VAL_MAX 15 5301 struct rtw89_beacon_track_info *bcn_track = &rtwdev->bcn_track; 5302 struct rtw89_h2c_pwr_lvl *h2c; 5303 u32 len = sizeof(*h2c); 5304 struct sk_buff *skb; 5305 u8 bcn_to_val; 5306 int ret; 5307 5308 skb = rtw89_fw_h2c_alloc_skb_with_hdr(rtwdev, len); 5309 if (!skb) { 5310 rtw89_err(rtwdev, "failed to alloc skb for h2c pwr lvl\n"); 5311 return -ENOMEM; 5312 } 5313 skb_put(skb, len); 5314 h2c = (struct rtw89_h2c_pwr_lvl *)skb->data; 5315 5316 bcn_to_val = clamp_t(u8, bcn_track->bcn_timeout, 5317 RTW89_BCN_TO_VAL_MIN, RTW89_BCN_TO_VAL_MAX); 5318 5319 h2c->w0 = le32_encode_bits(rtwvif_link->mac_id, RTW89_H2C_PWR_LVL_W0_MACID) | 5320 le32_encode_bits(bcn_to_val, RTW89_H2C_PWR_LVL_W0_BCN_TO_VAL) | 5321 le32_encode_bits(0, RTW89_H2C_PWR_LVL_W0_PS_LVL) | 5322 le32_encode_bits(0, RTW89_H2C_PWR_LVL_W0_TRX_LVL) | 5323 le32_encode_bits(RTW89_DTIM_TO_VAL_MIN, 5324 RTW89_H2C_PWR_LVL_W0_DTIM_TO_VAL); 5325 5326 rtw89_h2c_pkt_set_hdr(rtwdev, skb, FWCMD_TYPE_H2C, 5327 H2C_CAT_MAC, H2C_CL_MAC_PS, 5328 H2C_FUNC_PS_POWER_LEVEL, 0, 0, 5329 len); 5330 5331 ret = rtw89_h2c_tx(rtwdev, skb, false); 5332 if (ret) { 5333 rtw89_err(rtwdev, "failed to send h2c\n"); 5334 goto fail; 5335 } 5336 5337 return 0; 5338 fail: 5339 dev_kfree_skb_any(skb); 5340 5341 return ret; 5342 } 5343 5344 int rtw89_fw_h2c_role_maintain(struct rtw89_dev *rtwdev, 5345 struct rtw89_vif_link *rtwvif_link, 5346 struct rtw89_sta_link *rtwsta_link, 5347 enum rtw89_upd_mode upd_mode) 5348 { 5349 u8 mac_id = rtwsta_link ? rtwsta_link->mac_id : rtwvif_link->mac_id; 5350 struct rtw89_h2c_role_maintain *h2c; 5351 u32 len = sizeof(*h2c); 5352 struct sk_buff *skb; 5353 u8 self_role; 5354 int ret; 5355 5356 if (rtwvif_link->net_type == RTW89_NET_TYPE_AP_MODE) { 5357 if (rtwsta_link) 5358 self_role = RTW89_SELF_ROLE_AP_CLIENT; 5359 else 5360 self_role = rtwvif_link->self_role; 5361 } else { 5362 self_role = rtwvif_link->self_role; 5363 } 5364 5365 skb = rtw89_fw_h2c_alloc_skb_with_hdr(rtwdev, len); 5366 if (!skb) { 5367 rtw89_err(rtwdev, "failed to alloc skb for h2c join\n"); 5368 return -ENOMEM; 5369 } 5370 skb_put(skb, len); 5371 h2c = (struct rtw89_h2c_role_maintain *)skb->data; 5372 5373 h2c->w0 = le32_encode_bits(mac_id, RTW89_H2C_ROLE_MAINTAIN_W0_MACID) | 5374 le32_encode_bits(self_role, RTW89_H2C_ROLE_MAINTAIN_W0_SELF_ROLE) | 5375 le32_encode_bits(upd_mode, RTW89_H2C_ROLE_MAINTAIN_W0_UPD_MODE) | 5376 le32_encode_bits(rtwvif_link->wifi_role, 5377 RTW89_H2C_ROLE_MAINTAIN_W0_WIFI_ROLE) | 5378 le32_encode_bits(rtwvif_link->mac_idx, 5379 RTW89_H2C_ROLE_MAINTAIN_W0_BAND) | 5380 le32_encode_bits(rtwvif_link->port, RTW89_H2C_ROLE_MAINTAIN_W0_PORT); 5381 5382 rtw89_h2c_pkt_set_hdr(rtwdev, skb, FWCMD_TYPE_H2C, 5383 H2C_CAT_MAC, H2C_CL_MAC_MEDIA_RPT, 5384 H2C_FUNC_MAC_FWROLE_MAINTAIN, 0, 1, 5385 len); 5386 5387 ret = rtw89_h2c_tx(rtwdev, skb, false); 5388 if (ret) { 5389 rtw89_err(rtwdev, "failed to send h2c\n"); 5390 goto fail; 5391 } 5392 5393 return 0; 5394 fail: 5395 dev_kfree_skb_any(skb); 5396 5397 return ret; 5398 } 5399 5400 static enum rtw89_fw_sta_type 5401 rtw89_fw_get_sta_type(struct rtw89_dev *rtwdev, struct rtw89_vif_link *rtwvif_link, 5402 struct rtw89_sta_link *rtwsta_link) 5403 { 5404 struct ieee80211_bss_conf *bss_conf; 5405 struct ieee80211_link_sta *link_sta; 5406 enum rtw89_fw_sta_type type; 5407 5408 rcu_read_lock(); 5409 5410 if (!rtwsta_link) 5411 goto by_vif; 5412 5413 link_sta = rtw89_sta_rcu_dereference_link(rtwsta_link, true); 5414 5415 if (link_sta->eht_cap.has_eht) 5416 type = RTW89_FW_BE_STA; 5417 else if (link_sta->he_cap.has_he) 5418 type = RTW89_FW_AX_STA; 5419 else 5420 type = RTW89_FW_N_AC_STA; 5421 5422 goto out; 5423 5424 by_vif: 5425 bss_conf = rtw89_vif_rcu_dereference_link(rtwvif_link, true); 5426 5427 if (bss_conf->eht_support) 5428 type = RTW89_FW_BE_STA; 5429 else if (bss_conf->he_support) 5430 type = RTW89_FW_AX_STA; 5431 else 5432 type = RTW89_FW_N_AC_STA; 5433 5434 out: 5435 rcu_read_unlock(); 5436 5437 return type; 5438 } 5439 5440 int rtw89_fw_h2c_join_info(struct rtw89_dev *rtwdev, struct rtw89_vif_link *rtwvif_link, 5441 struct rtw89_sta_link *rtwsta_link, bool dis_conn) 5442 { 5443 u8 mac_id = rtwsta_link ? rtwsta_link->mac_id : rtwvif_link->mac_id; 5444 struct ieee80211_vif *vif = rtwvif_link_to_vif(rtwvif_link); 5445 bool is_mld = ieee80211_vif_is_mld(vif); 5446 u8 self_role = rtwvif_link->self_role; 5447 enum rtw89_fw_sta_type sta_type; 5448 u8 net_type = rtwvif_link->net_type; 5449 struct rtw89_h2c_join_v1 *h2c_v1; 5450 struct rtw89_h2c_join *h2c; 5451 u32 len = sizeof(*h2c); 5452 bool format_v1 = false; 5453 struct sk_buff *skb; 5454 u8 main_mac_id; 5455 bool init_ps; 5456 int ret; 5457 5458 if (rtwdev->chip->chip_gen == RTW89_CHIP_BE) { 5459 len = sizeof(*h2c_v1); 5460 format_v1 = true; 5461 } 5462 5463 if (net_type == RTW89_NET_TYPE_AP_MODE && rtwsta_link) { 5464 self_role = RTW89_SELF_ROLE_AP_CLIENT; 5465 net_type = dis_conn ? RTW89_NET_TYPE_NO_LINK : net_type; 5466 } 5467 5468 skb = rtw89_fw_h2c_alloc_skb_with_hdr(rtwdev, len); 5469 if (!skb) { 5470 rtw89_err(rtwdev, "failed to alloc skb for h2c join\n"); 5471 return -ENOMEM; 5472 } 5473 skb_put(skb, len); 5474 h2c = (struct rtw89_h2c_join *)skb->data; 5475 5476 h2c->w0 = le32_encode_bits(mac_id, RTW89_H2C_JOININFO_W0_MACID) | 5477 le32_encode_bits(dis_conn, RTW89_H2C_JOININFO_W0_OP) | 5478 le32_encode_bits(rtwvif_link->mac_idx, RTW89_H2C_JOININFO_W0_BAND) | 5479 le32_encode_bits(rtwvif_link->wmm, RTW89_H2C_JOININFO_W0_WMM) | 5480 le32_encode_bits(rtwvif_link->trigger, RTW89_H2C_JOININFO_W0_TGR) | 5481 le32_encode_bits(0, RTW89_H2C_JOININFO_W0_ISHESTA) | 5482 le32_encode_bits(0, RTW89_H2C_JOININFO_W0_DLBW) | 5483 le32_encode_bits(0, RTW89_H2C_JOININFO_W0_TF_MAC_PAD) | 5484 le32_encode_bits(0, RTW89_H2C_JOININFO_W0_DL_T_PE) | 5485 le32_encode_bits(rtwvif_link->port, RTW89_H2C_JOININFO_W0_PORT_ID) | 5486 le32_encode_bits(net_type, RTW89_H2C_JOININFO_W0_NET_TYPE) | 5487 le32_encode_bits(rtwvif_link->wifi_role, 5488 RTW89_H2C_JOININFO_W0_WIFI_ROLE) | 5489 le32_encode_bits(self_role, RTW89_H2C_JOININFO_W0_SELF_ROLE); 5490 5491 if (!format_v1) 5492 goto done; 5493 5494 h2c_v1 = (struct rtw89_h2c_join_v1 *)skb->data; 5495 5496 sta_type = rtw89_fw_get_sta_type(rtwdev, rtwvif_link, rtwsta_link); 5497 init_ps = rtwvif_link != rtw89_get_designated_link(rtwvif_link->rtwvif); 5498 5499 if (rtwsta_link) 5500 main_mac_id = rtw89_sta_get_main_macid(rtwsta_link->rtwsta); 5501 else 5502 main_mac_id = rtw89_vif_get_main_macid(rtwvif_link->rtwvif); 5503 5504 h2c_v1->w1 = le32_encode_bits(sta_type, RTW89_H2C_JOININFO_W1_STA_TYPE) | 5505 le32_encode_bits(is_mld, RTW89_H2C_JOININFO_W1_IS_MLD) | 5506 le32_encode_bits(main_mac_id, RTW89_H2C_JOININFO_W1_MAIN_MACID) | 5507 le32_encode_bits(RTW89_H2C_JOININFO_MLO_MODE_MLSR, 5508 RTW89_H2C_JOININFO_W1_MLO_MODE) | 5509 le32_encode_bits(0, RTW89_H2C_JOININFO_W1_EMLSR_CAB) | 5510 le32_encode_bits(0, RTW89_H2C_JOININFO_W1_NSTR_EN) | 5511 le32_encode_bits(init_ps, RTW89_H2C_JOININFO_W1_INIT_PWR_STATE) | 5512 le32_encode_bits(IEEE80211_EML_CAP_EML_PADDING_DELAY_256US, 5513 RTW89_H2C_JOININFO_W1_EMLSR_PADDING) | 5514 le32_encode_bits(IEEE80211_EML_CAP_EMLSR_TRANSITION_DELAY_256US, 5515 RTW89_H2C_JOININFO_W1_EMLSR_TRANS_DELAY) | 5516 le32_encode_bits(rtwvif_link->link_id, RTW89_H2C_JOININFO_W1_LINK_ID); 5517 5518 h2c_v1->w2 = le32_encode_bits(0, RTW89_H2C_JOININFO_W2_MACID_EXT) | 5519 le32_encode_bits(0, RTW89_H2C_JOININFO_W2_MAIN_MACID_EXT); 5520 5521 done: 5522 rtw89_h2c_pkt_set_hdr(rtwdev, skb, FWCMD_TYPE_H2C, 5523 H2C_CAT_MAC, H2C_CL_MAC_MEDIA_RPT, 5524 H2C_FUNC_MAC_JOININFO, 0, 1, 5525 len); 5526 5527 ret = rtw89_h2c_tx(rtwdev, skb, false); 5528 if (ret) { 5529 rtw89_err(rtwdev, "failed to send h2c\n"); 5530 goto fail; 5531 } 5532 5533 return 0; 5534 fail: 5535 dev_kfree_skb_any(skb); 5536 5537 return ret; 5538 } 5539 5540 int rtw89_fw_h2c_notify_dbcc(struct rtw89_dev *rtwdev, bool en) 5541 { 5542 struct rtw89_h2c_notify_dbcc *h2c; 5543 u32 len = sizeof(*h2c); 5544 struct sk_buff *skb; 5545 int ret; 5546 5547 skb = rtw89_fw_h2c_alloc_skb_with_hdr(rtwdev, len); 5548 if (!skb) { 5549 rtw89_err(rtwdev, "failed to alloc skb for h2c notify dbcc\n"); 5550 return -ENOMEM; 5551 } 5552 skb_put(skb, len); 5553 h2c = (struct rtw89_h2c_notify_dbcc *)skb->data; 5554 5555 h2c->w0 = le32_encode_bits(en, RTW89_H2C_NOTIFY_DBCC_EN); 5556 5557 rtw89_h2c_pkt_set_hdr(rtwdev, skb, FWCMD_TYPE_H2C, 5558 H2C_CAT_MAC, H2C_CL_MAC_MEDIA_RPT, 5559 H2C_FUNC_NOTIFY_DBCC, 0, 1, 5560 len); 5561 5562 ret = rtw89_h2c_tx(rtwdev, skb, false); 5563 if (ret) { 5564 rtw89_err(rtwdev, "failed to send h2c\n"); 5565 goto fail; 5566 } 5567 5568 return 0; 5569 fail: 5570 dev_kfree_skb_any(skb); 5571 5572 return ret; 5573 } 5574 5575 int rtw89_fw_h2c_macid_pause(struct rtw89_dev *rtwdev, u8 sh, u8 grp, 5576 bool pause) 5577 { 5578 struct rtw89_fw_macid_pause_sleep_grp *h2c_new; 5579 struct rtw89_fw_macid_pause_grp *h2c; 5580 __le32 set = cpu_to_le32(BIT(sh)); 5581 u8 h2c_macid_pause_id; 5582 struct sk_buff *skb; 5583 u32 len; 5584 int ret; 5585 5586 if (RTW89_CHK_FW_FEATURE(MACID_PAUSE_SLEEP, &rtwdev->fw)) { 5587 h2c_macid_pause_id = H2C_FUNC_MAC_MACID_PAUSE_SLEEP; 5588 len = sizeof(*h2c_new); 5589 } else { 5590 h2c_macid_pause_id = H2C_FUNC_MAC_MACID_PAUSE; 5591 len = sizeof(*h2c); 5592 } 5593 5594 skb = rtw89_fw_h2c_alloc_skb_with_hdr(rtwdev, len); 5595 if (!skb) { 5596 rtw89_err(rtwdev, "failed to alloc skb for h2c macid pause\n"); 5597 return -ENOMEM; 5598 } 5599 skb_put(skb, len); 5600 5601 if (h2c_macid_pause_id == H2C_FUNC_MAC_MACID_PAUSE_SLEEP) { 5602 h2c_new = (struct rtw89_fw_macid_pause_sleep_grp *)skb->data; 5603 5604 h2c_new->n[0].pause_mask_grp[grp] = set; 5605 h2c_new->n[0].sleep_mask_grp[grp] = set; 5606 if (pause) { 5607 h2c_new->n[0].pause_grp[grp] = set; 5608 h2c_new->n[0].sleep_grp[grp] = set; 5609 } 5610 } else { 5611 h2c = (struct rtw89_fw_macid_pause_grp *)skb->data; 5612 5613 h2c->mask_grp[grp] = set; 5614 if (pause) 5615 h2c->pause_grp[grp] = set; 5616 } 5617 5618 rtw89_h2c_pkt_set_hdr(rtwdev, skb, FWCMD_TYPE_H2C, 5619 H2C_CAT_MAC, H2C_CL_MAC_FW_OFLD, 5620 h2c_macid_pause_id, 1, 0, 5621 len); 5622 5623 ret = rtw89_h2c_tx(rtwdev, skb, false); 5624 if (ret) { 5625 rtw89_err(rtwdev, "failed to send h2c\n"); 5626 goto fail; 5627 } 5628 5629 return 0; 5630 fail: 5631 dev_kfree_skb_any(skb); 5632 5633 return ret; 5634 } 5635 5636 #define H2C_EDCA_LEN 12 5637 int rtw89_fw_h2c_set_edca(struct rtw89_dev *rtwdev, struct rtw89_vif_link *rtwvif_link, 5638 u8 ac, u32 val) 5639 { 5640 struct sk_buff *skb; 5641 int ret; 5642 5643 skb = rtw89_fw_h2c_alloc_skb_with_hdr(rtwdev, H2C_EDCA_LEN); 5644 if (!skb) { 5645 rtw89_err(rtwdev, "failed to alloc skb for h2c edca\n"); 5646 return -ENOMEM; 5647 } 5648 skb_put(skb, H2C_EDCA_LEN); 5649 RTW89_SET_EDCA_SEL(skb->data, 0); 5650 RTW89_SET_EDCA_BAND(skb->data, rtwvif_link->mac_idx); 5651 RTW89_SET_EDCA_WMM(skb->data, 0); 5652 RTW89_SET_EDCA_AC(skb->data, ac); 5653 RTW89_SET_EDCA_PARAM(skb->data, val); 5654 5655 rtw89_h2c_pkt_set_hdr(rtwdev, skb, FWCMD_TYPE_H2C, 5656 H2C_CAT_MAC, H2C_CL_MAC_FW_OFLD, 5657 H2C_FUNC_USR_EDCA, 0, 1, 5658 H2C_EDCA_LEN); 5659 5660 ret = rtw89_h2c_tx(rtwdev, skb, false); 5661 if (ret) { 5662 rtw89_err(rtwdev, "failed to send h2c\n"); 5663 goto fail; 5664 } 5665 5666 return 0; 5667 fail: 5668 dev_kfree_skb_any(skb); 5669 5670 return ret; 5671 } 5672 5673 #define H2C_TSF32_TOGL_LEN 4 5674 int rtw89_fw_h2c_tsf32_toggle(struct rtw89_dev *rtwdev, 5675 struct rtw89_vif_link *rtwvif_link, 5676 bool en) 5677 { 5678 struct sk_buff *skb; 5679 u16 early_us = en ? 2000 : 0; 5680 u8 *cmd; 5681 int ret; 5682 5683 skb = rtw89_fw_h2c_alloc_skb_with_hdr(rtwdev, H2C_TSF32_TOGL_LEN); 5684 if (!skb) { 5685 rtw89_err(rtwdev, "failed to alloc skb for h2c p2p act\n"); 5686 return -ENOMEM; 5687 } 5688 skb_put(skb, H2C_TSF32_TOGL_LEN); 5689 cmd = skb->data; 5690 5691 RTW89_SET_FWCMD_TSF32_TOGL_BAND(cmd, rtwvif_link->mac_idx); 5692 RTW89_SET_FWCMD_TSF32_TOGL_EN(cmd, en); 5693 RTW89_SET_FWCMD_TSF32_TOGL_PORT(cmd, rtwvif_link->port); 5694 RTW89_SET_FWCMD_TSF32_TOGL_EARLY(cmd, early_us); 5695 5696 rtw89_h2c_pkt_set_hdr(rtwdev, skb, FWCMD_TYPE_H2C, 5697 H2C_CAT_MAC, H2C_CL_MAC_FW_OFLD, 5698 H2C_FUNC_TSF32_TOGL, 0, 0, 5699 H2C_TSF32_TOGL_LEN); 5700 5701 ret = rtw89_h2c_tx(rtwdev, skb, false); 5702 if (ret) { 5703 rtw89_err(rtwdev, "failed to send h2c\n"); 5704 goto fail; 5705 } 5706 5707 return 0; 5708 fail: 5709 dev_kfree_skb_any(skb); 5710 5711 return ret; 5712 } 5713 5714 #define H2C_OFLD_CFG_LEN 8 5715 int rtw89_fw_h2c_set_ofld_cfg(struct rtw89_dev *rtwdev) 5716 { 5717 static const u8 cfg[] = {0x09, 0x00, 0x00, 0x00, 0x5e, 0x00, 0x00, 0x00}; 5718 struct sk_buff *skb; 5719 int ret; 5720 5721 skb = rtw89_fw_h2c_alloc_skb_with_hdr(rtwdev, H2C_OFLD_CFG_LEN); 5722 if (!skb) { 5723 rtw89_err(rtwdev, "failed to alloc skb for h2c ofld\n"); 5724 return -ENOMEM; 5725 } 5726 skb_put_data(skb, cfg, H2C_OFLD_CFG_LEN); 5727 5728 rtw89_h2c_pkt_set_hdr(rtwdev, skb, FWCMD_TYPE_H2C, 5729 H2C_CAT_MAC, H2C_CL_MAC_FW_OFLD, 5730 H2C_FUNC_OFLD_CFG, 0, 1, 5731 H2C_OFLD_CFG_LEN); 5732 5733 ret = rtw89_h2c_tx(rtwdev, skb, false); 5734 if (ret) { 5735 rtw89_err(rtwdev, "failed to send h2c\n"); 5736 goto fail; 5737 } 5738 5739 return 0; 5740 fail: 5741 dev_kfree_skb_any(skb); 5742 5743 return ret; 5744 } 5745 5746 int rtw89_fw_h2c_tx_duty(struct rtw89_dev *rtwdev, u8 lv) 5747 { 5748 struct rtw89_h2c_tx_duty *h2c; 5749 u32 len = sizeof(*h2c); 5750 struct sk_buff *skb; 5751 u16 pause, active; 5752 int ret; 5753 5754 skb = rtw89_fw_h2c_alloc_skb_with_hdr(rtwdev, len); 5755 if (!skb) { 5756 rtw89_err(rtwdev, "failed to alloc skb for h2c tx duty\n"); 5757 return -ENOMEM; 5758 } 5759 5760 skb_put(skb, len); 5761 h2c = (struct rtw89_h2c_tx_duty *)skb->data; 5762 5763 static_assert(RTW89_THERMAL_PROT_LV_MAX * RTW89_THERMAL_PROT_STEP < 100); 5764 5765 if (lv == 0 || lv > RTW89_THERMAL_PROT_LV_MAX) { 5766 h2c->w1 = le32_encode_bits(1, RTW89_H2C_TX_DUTY_W1_STOP); 5767 } else { 5768 active = 100 - lv * RTW89_THERMAL_PROT_STEP; 5769 pause = 100 - active; 5770 5771 h2c->w0 = le32_encode_bits(pause, RTW89_H2C_TX_DUTY_W0_PAUSE_INTVL_MASK) | 5772 le32_encode_bits(active, RTW89_H2C_TX_DUTY_W0_TX_INTVL_MASK); 5773 } 5774 5775 rtw89_h2c_pkt_set_hdr(rtwdev, skb, FWCMD_TYPE_H2C, 5776 H2C_CAT_MAC, H2C_CL_MAC_FW_OFLD, 5777 H2C_FUNC_TX_DUTY, 0, 0, len); 5778 5779 ret = rtw89_h2c_tx(rtwdev, skb, false); 5780 if (ret) { 5781 rtw89_err(rtwdev, "failed to send h2c\n"); 5782 goto fail; 5783 } 5784 5785 return 0; 5786 fail: 5787 dev_kfree_skb_any(skb); 5788 5789 return ret; 5790 } 5791 5792 int rtw89_fw_h2c_set_bcn_fltr_cfg(struct rtw89_dev *rtwdev, 5793 struct rtw89_vif_link *rtwvif_link, 5794 bool connect) 5795 { 5796 struct ieee80211_bss_conf *bss_conf; 5797 s32 thold = RTW89_DEFAULT_CQM_THOLD; 5798 u32 hyst = RTW89_DEFAULT_CQM_HYST; 5799 struct rtw89_h2c_bcnfltr *h2c; 5800 u32 len = sizeof(*h2c); 5801 struct sk_buff *skb; 5802 u8 max_cnt, cnt; 5803 int ret; 5804 5805 if (!RTW89_CHK_FW_FEATURE(BEACON_FILTER, &rtwdev->fw)) 5806 return -EINVAL; 5807 5808 if (!rtwvif_link || rtwvif_link->net_type != RTW89_NET_TYPE_INFRA) 5809 return -EINVAL; 5810 5811 rcu_read_lock(); 5812 5813 bss_conf = rtw89_vif_rcu_dereference_link(rtwvif_link, false); 5814 5815 if (bss_conf->cqm_rssi_hyst) 5816 hyst = bss_conf->cqm_rssi_hyst; 5817 if (bss_conf->cqm_rssi_thold) 5818 thold = bss_conf->cqm_rssi_thold; 5819 5820 rcu_read_unlock(); 5821 5822 skb = rtw89_fw_h2c_alloc_skb_with_hdr(rtwdev, len); 5823 if (!skb) { 5824 rtw89_err(rtwdev, "failed to alloc skb for h2c bcn filter\n"); 5825 return -ENOMEM; 5826 } 5827 5828 skb_put(skb, len); 5829 h2c = (struct rtw89_h2c_bcnfltr *)skb->data; 5830 5831 if (RTW89_CHK_FW_FEATURE(BEACON_LOSS_COUNT_V1, &rtwdev->fw)) 5832 max_cnt = BIT(7) - 1; 5833 else 5834 max_cnt = BIT(4) - 1; 5835 5836 cnt = min(RTW89_BCN_LOSS_CNT, max_cnt); 5837 5838 h2c->w0 = le32_encode_bits(connect, RTW89_H2C_BCNFLTR_W0_MON_RSSI) | 5839 le32_encode_bits(connect, RTW89_H2C_BCNFLTR_W0_MON_BCN) | 5840 le32_encode_bits(connect, RTW89_H2C_BCNFLTR_W0_MON_EN) | 5841 le32_encode_bits(RTW89_BCN_FLTR_OFFLOAD_MODE_DEFAULT, 5842 RTW89_H2C_BCNFLTR_W0_MODE) | 5843 le32_encode_bits(cnt >> 4, RTW89_H2C_BCNFLTR_W0_BCN_LOSS_CNT_H3) | 5844 le32_encode_bits(cnt & 0xf, RTW89_H2C_BCNFLTR_W0_BCN_LOSS_CNT_L4) | 5845 le32_encode_bits(hyst, RTW89_H2C_BCNFLTR_W0_RSSI_HYST) | 5846 le32_encode_bits(thold + MAX_RSSI, 5847 RTW89_H2C_BCNFLTR_W0_RSSI_THRESHOLD) | 5848 le32_encode_bits(rtwvif_link->mac_id, RTW89_H2C_BCNFLTR_W0_MAC_ID); 5849 5850 rtw89_h2c_pkt_set_hdr(rtwdev, skb, FWCMD_TYPE_H2C, 5851 H2C_CAT_MAC, H2C_CL_MAC_FW_OFLD, 5852 H2C_FUNC_CFG_BCNFLTR, 0, 1, len); 5853 5854 ret = rtw89_h2c_tx(rtwdev, skb, false); 5855 if (ret) { 5856 rtw89_err(rtwdev, "failed to send h2c\n"); 5857 goto fail; 5858 } 5859 5860 return 0; 5861 fail: 5862 dev_kfree_skb_any(skb); 5863 5864 return ret; 5865 } 5866 5867 int rtw89_fw_h2c_rssi_offload(struct rtw89_dev *rtwdev, 5868 struct rtw89_rx_phy_ppdu *phy_ppdu) 5869 { 5870 struct rtw89_h2c_ofld_rssi *h2c; 5871 u32 len = sizeof(*h2c); 5872 struct sk_buff *skb; 5873 s8 rssi; 5874 int ret; 5875 5876 if (!RTW89_CHK_FW_FEATURE(BEACON_FILTER, &rtwdev->fw)) 5877 return -EINVAL; 5878 5879 if (!phy_ppdu) 5880 return -EINVAL; 5881 5882 skb = rtw89_fw_h2c_alloc_skb_with_hdr(rtwdev, len); 5883 if (!skb) { 5884 rtw89_err(rtwdev, "failed to alloc skb for h2c rssi\n"); 5885 return -ENOMEM; 5886 } 5887 5888 rssi = phy_ppdu->rssi_avg >> RSSI_FACTOR; 5889 skb_put(skb, len); 5890 h2c = (struct rtw89_h2c_ofld_rssi *)skb->data; 5891 5892 h2c->w0 = le32_encode_bits(phy_ppdu->mac_id, RTW89_H2C_OFLD_RSSI_W0_MACID) | 5893 le32_encode_bits(1, RTW89_H2C_OFLD_RSSI_W0_NUM); 5894 h2c->w1 = le32_encode_bits(rssi, RTW89_H2C_OFLD_RSSI_W1_VAL); 5895 5896 rtw89_h2c_pkt_set_hdr(rtwdev, skb, FWCMD_TYPE_H2C, 5897 H2C_CAT_MAC, H2C_CL_MAC_FW_OFLD, 5898 H2C_FUNC_OFLD_RSSI, 0, 1, len); 5899 5900 ret = rtw89_h2c_tx(rtwdev, skb, false); 5901 if (ret) { 5902 rtw89_err(rtwdev, "failed to send h2c\n"); 5903 goto fail; 5904 } 5905 5906 return 0; 5907 fail: 5908 dev_kfree_skb_any(skb); 5909 5910 return ret; 5911 } 5912 5913 int rtw89_fw_h2c_tp_offload(struct rtw89_dev *rtwdev, struct rtw89_vif_link *rtwvif_link) 5914 { 5915 struct rtw89_vif *rtwvif = rtwvif_link->rtwvif; 5916 struct rtw89_traffic_stats *stats = &rtwvif->stats; 5917 struct rtw89_h2c_ofld *h2c; 5918 u32 len = sizeof(*h2c); 5919 struct sk_buff *skb; 5920 int ret; 5921 5922 if (rtwvif_link->net_type != RTW89_NET_TYPE_INFRA) 5923 return -EINVAL; 5924 5925 skb = rtw89_fw_h2c_alloc_skb_with_hdr(rtwdev, len); 5926 if (!skb) { 5927 rtw89_err(rtwdev, "failed to alloc skb for h2c tp\n"); 5928 return -ENOMEM; 5929 } 5930 5931 skb_put(skb, len); 5932 h2c = (struct rtw89_h2c_ofld *)skb->data; 5933 5934 h2c->w0 = le32_encode_bits(rtwvif_link->mac_id, RTW89_H2C_OFLD_W0_MAC_ID) | 5935 le32_encode_bits(stats->tx_throughput, RTW89_H2C_OFLD_W0_TX_TP) | 5936 le32_encode_bits(stats->rx_throughput, RTW89_H2C_OFLD_W0_RX_TP); 5937 5938 rtw89_h2c_pkt_set_hdr(rtwdev, skb, FWCMD_TYPE_H2C, 5939 H2C_CAT_MAC, H2C_CL_MAC_FW_OFLD, 5940 H2C_FUNC_OFLD_TP, 0, 1, len); 5941 5942 ret = rtw89_h2c_tx(rtwdev, skb, false); 5943 if (ret) { 5944 rtw89_err(rtwdev, "failed to send h2c\n"); 5945 goto fail; 5946 } 5947 5948 return 0; 5949 fail: 5950 dev_kfree_skb_any(skb); 5951 5952 return ret; 5953 } 5954 5955 int rtw89_fw_h2c_ra(struct rtw89_dev *rtwdev, struct rtw89_ra_info *ra, bool csi) 5956 { 5957 const struct rtw89_chip_info *chip = rtwdev->chip; 5958 struct rtw89_h2c_ra_v1 *h2c_v1; 5959 struct rtw89_h2c_ra *h2c; 5960 u32 len = sizeof(*h2c); 5961 struct sk_buff *skb; 5962 u8 ver = U8_MAX; 5963 int ret; 5964 5965 if (chip->chip_gen == RTW89_CHIP_AX) { 5966 len = sizeof(*h2c); 5967 ver = 0; 5968 } else { 5969 len = sizeof(*h2c_v1); 5970 ver = 1; 5971 } 5972 5973 skb = rtw89_fw_h2c_alloc_skb_with_hdr(rtwdev, len); 5974 if (!skb) { 5975 rtw89_err(rtwdev, "failed to alloc skb for h2c join\n"); 5976 return -ENOMEM; 5977 } 5978 skb_put(skb, len); 5979 h2c = (struct rtw89_h2c_ra *)skb->data; 5980 rtw89_debug(rtwdev, RTW89_DBG_RA, 5981 "ra cmd msk: %llx ", ra->ra_mask); 5982 5983 h2c->w0 = le32_encode_bits(ra->mode_ctrl, RTW89_H2C_RA_W0_MODE) | 5984 le32_encode_bits(ra->bw_cap, RTW89_H2C_RA_W0_BW_CAP) | 5985 le32_encode_bits(ra->macid, RTW89_H2C_RA_W0_MACID) | 5986 le32_encode_bits(ra->dcm_cap, RTW89_H2C_RA_W0_DCM) | 5987 le32_encode_bits(ra->er_cap, RTW89_H2C_RA_W0_ER) | 5988 le32_encode_bits(ra->init_rate_lv, RTW89_H2C_RA_W0_INIT_RATE_LV) | 5989 le32_encode_bits(ra->upd_all, RTW89_H2C_RA_W0_UPD_ALL) | 5990 le32_encode_bits(ra->en_sgi, RTW89_H2C_RA_W0_SGI) | 5991 le32_encode_bits(ra->ldpc_cap, RTW89_H2C_RA_W0_LDPC) | 5992 le32_encode_bits(ra->stbc_cap, RTW89_H2C_RA_W0_STBC) | 5993 le32_encode_bits(ra->ss_num, RTW89_H2C_RA_W0_SS_NUM) | 5994 le32_encode_bits(ra->giltf, RTW89_H2C_RA_W0_GILTF) | 5995 le32_encode_bits(ra->upd_bw_nss_mask, RTW89_H2C_RA_W0_UPD_BW_NSS_MASK) | 5996 le32_encode_bits(ra->upd_mask, RTW89_H2C_RA_W0_UPD_MASK); 5997 h2c->w1 = le32_encode_bits(ra->ra_mask, RTW89_H2C_RA_W1_RAMASK_LO32); 5998 h2c->w2 = le32_encode_bits(ra->ra_mask >> 32, RTW89_H2C_RA_W2_RAMASK_HI32); 5999 h2c->w3 = le32_encode_bits(ra->fix_giltf_en, RTW89_H2C_RA_W3_FIX_GILTF_EN) | 6000 le32_encode_bits(ra->fix_giltf, RTW89_H2C_RA_W3_FIX_GILTF); 6001 6002 if (!csi || ver >= 1) 6003 goto next_v1; 6004 6005 h2c->w2 |= le32_encode_bits(1, RTW89_H2C_RA_W2_BFEE_CSI_CTL); 6006 h2c->w3 |= le32_encode_bits(ra->band_num, RTW89_H2C_RA_W3_BAND_NUM) | 6007 le32_encode_bits(ra->cr_tbl_sel, RTW89_H2C_RA_W3_CR_TBL_SEL) | 6008 le32_encode_bits(ra->fixed_csi_rate_en, RTW89_H2C_RA_W3_FIXED_CSI_RATE_EN) | 6009 le32_encode_bits(ra->ra_csi_rate_en, RTW89_H2C_RA_W3_RA_CSI_RATE_EN) | 6010 le32_encode_bits(ra->csi_mcs_ss_idx, RTW89_H2C_RA_W3_FIXED_CSI_MCS_SS_IDX) | 6011 le32_encode_bits(ra->csi_mode, RTW89_H2C_RA_W3_FIXED_CSI_MODE) | 6012 le32_encode_bits(ra->csi_gi_ltf, RTW89_H2C_RA_W3_FIXED_CSI_GI_LTF) | 6013 le32_encode_bits(ra->csi_bw, RTW89_H2C_RA_W3_FIXED_CSI_BW); 6014 6015 next_v1: 6016 if (ver < 1) 6017 goto done; 6018 6019 h2c->w3 |= le32_encode_bits(ra->partial_bw_er, 6020 RTW89_H2C_RA_V1_W3_PARTIAL_BW_SU_ER) | 6021 le32_encode_bits(ra->band, RTW89_H2C_RA_V1_W3_BAND); 6022 6023 h2c_v1 = (struct rtw89_h2c_ra_v1 *)h2c; 6024 h2c_v1->w4 = le32_encode_bits(ra->mode_ctrl, RTW89_H2C_RA_V1_W4_MODE_EHT) | 6025 le32_encode_bits(ra->bw_cap, RTW89_H2C_RA_V1_W4_BW_EHT); 6026 6027 done: 6028 rtw89_h2c_pkt_set_hdr(rtwdev, skb, FWCMD_TYPE_H2C, 6029 H2C_CAT_OUTSRC, H2C_CL_OUTSRC_RA, 6030 H2C_FUNC_OUTSRC_RA_MACIDCFG, 0, 0, 6031 len); 6032 6033 ret = rtw89_h2c_tx(rtwdev, skb, false); 6034 if (ret) { 6035 rtw89_err(rtwdev, "failed to send h2c\n"); 6036 goto fail; 6037 } 6038 6039 return 0; 6040 fail: 6041 dev_kfree_skb_any(skb); 6042 6043 return ret; 6044 } 6045 6046 int rtw89_fw_h2c_tx_history(struct rtw89_dev *rtwdev, u16 mac_id) 6047 { 6048 struct rtw89_bb_stat_cfg *bb_stat = &rtwdev->phy_info.bb_stat_cfg; 6049 const struct rtw89_chip_info *chip = rtwdev->chip; 6050 struct rtw89_h2c_ra_tx_history *h2c; 6051 u32 len = sizeof(*h2c); 6052 struct sk_buff *skb; 6053 int ret; 6054 6055 if (chip->chip_gen == RTW89_CHIP_AX) 6056 return 0; 6057 6058 skb = rtw89_fw_h2c_alloc_skb_with_hdr(rtwdev, len); 6059 if (!skb) { 6060 rtw89_err(rtwdev, "failed to alloc skb for h2c tx history\n"); 6061 return -ENOMEM; 6062 } 6063 6064 skb_put(skb, len); 6065 h2c = (struct rtw89_h2c_ra_tx_history *)skb->data; 6066 6067 h2c->w0 = le32_encode_bits(mac_id, RTW89_H2C_RA_TX_HISTORY_W0_MACID) | 6068 le32_encode_bits(0, RTW89_H2C_RA_TX_HISTORY_W0_PER_PPDU); 6069 6070 rtw89_h2c_pkt_set_hdr(rtwdev, skb, FWCMD_TYPE_H2C, 6071 H2C_CAT_OUTSRC, H2C_CL_OUTSRC_RA, 6072 H2C_FUNC_OUTSRC_RA_TX_HISTORY, 0, 0, len); 6073 6074 ret = rtw89_h2c_tx(rtwdev, skb, false); 6075 if (ret) { 6076 rtw89_err(rtwdev, "failed to send h2c\n"); 6077 goto fail; 6078 } 6079 6080 bb_stat->mac_id = mac_id; 6081 6082 return 0; 6083 fail: 6084 dev_kfree_skb_any(skb); 6085 6086 return ret; 6087 } 6088 6089 int rtw89_fw_h2c_phy_ch_rpt(struct rtw89_dev *rtwdev) 6090 { 6091 const struct rtw89_chip_info *chip = rtwdev->chip; 6092 struct rtw89_h2c_ra_phy_ch_rpt *h2c; 6093 u32 len = sizeof(*h2c); 6094 struct sk_buff *skb; 6095 int ret; 6096 6097 if (chip->chip_gen == RTW89_CHIP_AX) 6098 return 0; 6099 6100 skb = rtw89_fw_h2c_alloc_skb_with_hdr(rtwdev, len); 6101 if (!skb) { 6102 rtw89_err(rtwdev, "failed to alloc skb for h2c phy ch rpt\n"); 6103 return -ENOMEM; 6104 } 6105 6106 skb_put(skb, len); 6107 h2c = (struct rtw89_h2c_ra_phy_ch_rpt *)skb->data; 6108 6109 h2c->w1 = le32_encode_bits(1, RTW89_H2C_RA_PHY_CH_RPT_W1_RPT_TX_COUNT); 6110 6111 rtw89_h2c_pkt_set_hdr(rtwdev, skb, FWCMD_TYPE_H2C, 6112 H2C_CAT_OUTSRC, H2C_CL_OUTSRC_RA, 6113 H2C_FUNC_OUTSRC_RA_PHY_CH_RPT, 0, 0, len); 6114 6115 ret = rtw89_h2c_tx(rtwdev, skb, false); 6116 if (ret) { 6117 rtw89_err(rtwdev, "failed to send h2c\n"); 6118 goto fail; 6119 } 6120 6121 return 0; 6122 fail: 6123 dev_kfree_skb_any(skb); 6124 6125 return ret; 6126 } 6127 6128 int rtw89_fw_h2c_drv_ctrl_fw(struct rtw89_dev *rtwdev) 6129 { 6130 const struct rtw89_chip_info *chip = rtwdev->chip; 6131 struct rtw89_h2c_ra_drv_ctrl_fw *h2c; 6132 u32 len = sizeof(*h2c); 6133 struct sk_buff *skb; 6134 int ret; 6135 6136 if (chip->chip_gen == RTW89_CHIP_AX) 6137 return 0; 6138 6139 skb = rtw89_fw_h2c_alloc_skb_with_hdr(rtwdev, len); 6140 if (!skb) { 6141 rtw89_err(rtwdev, "failed to alloc skb for h2c drv ctrl fw\n"); 6142 return -ENOMEM; 6143 } 6144 6145 skb_put(skb, len); 6146 h2c = (struct rtw89_h2c_ra_drv_ctrl_fw *)skb->data; 6147 6148 h2c->w0 = le32_encode_bits(1, RTW89_H2C_RA_DRV_CTRL_FW_W0_RPT_TX_COUNT); 6149 6150 rtw89_h2c_pkt_set_hdr(rtwdev, skb, FWCMD_TYPE_H2C, 6151 H2C_CAT_OUTSRC, H2C_CL_OUTSRC_RA, 6152 H2C_FUNC_OUTSRC_RA_DRV_CTRL_FW, 0, 0, len); 6153 6154 ret = rtw89_h2c_tx(rtwdev, skb, false); 6155 if (ret) { 6156 rtw89_err(rtwdev, "failed to send h2c\n"); 6157 goto fail; 6158 } 6159 6160 return 0; 6161 fail: 6162 dev_kfree_skb_any(skb); 6163 6164 return ret; 6165 } 6166 6167 int rtw89_fw_h2c_cxdrv_init(struct rtw89_dev *rtwdev, u8 type) 6168 { 6169 struct rtw89_btc *btc = &rtwdev->btc; 6170 struct rtw89_btc_dm *dm = &btc->dm; 6171 struct rtw89_btc_init_info *init = &dm->init_info; 6172 struct rtw89_btc_module *md = &init->module; 6173 struct rtw89_btc_ant_info *ant = &md->ant; 6174 struct rtw89_h2c_cxinit *h2c; 6175 u32 len = sizeof(*h2c); 6176 struct sk_buff *skb; 6177 int ret; 6178 6179 skb = rtw89_fw_h2c_alloc_skb_with_hdr(rtwdev, len); 6180 if (!skb) { 6181 rtw89_err(rtwdev, "failed to alloc skb for h2c cxdrv_init\n"); 6182 return -ENOMEM; 6183 } 6184 skb_put(skb, len); 6185 h2c = (struct rtw89_h2c_cxinit *)skb->data; 6186 6187 h2c->hdr.type = type; 6188 h2c->hdr.len = len - H2C_LEN_CXDRVHDR; 6189 6190 h2c->ant_type = ant->type; 6191 h2c->ant_num = ant->num; 6192 h2c->ant_iso = ant->isolation; 6193 h2c->ant_info = 6194 u8_encode_bits(ant->single_pos, RTW89_H2C_CXINIT_ANT_INFO_POS) | 6195 u8_encode_bits(ant->diversity, RTW89_H2C_CXINIT_ANT_INFO_DIVERSITY) | 6196 u8_encode_bits(ant->btg_pos, RTW89_H2C_CXINIT_ANT_INFO_BTG_POS) | 6197 u8_encode_bits(ant->stream_cnt, RTW89_H2C_CXINIT_ANT_INFO_STREAM_CNT); 6198 6199 h2c->mod_rfe = md->rfe_type; 6200 h2c->mod_cv = md->kt_ver; 6201 h2c->mod_info = 6202 u8_encode_bits(md->bt_solo, RTW89_H2C_CXINIT_MOD_INFO_BT_SOLO) | 6203 u8_encode_bits(md->bt0_pos, RTW89_H2C_CXINIT_MOD_INFO_BT_POS) | 6204 u8_encode_bits(md->bt0_sw_type, RTW89_H2C_CXINIT_MOD_INFO_SW_TYPE) | 6205 u8_encode_bits(md->wa_type, RTW89_H2C_CXINIT_MOD_INFO_WA_TYPE); 6206 h2c->mod_adie_kt = md->kt_ver_adie; 6207 h2c->wl_gch = init->wl_guard_ch; 6208 6209 h2c->info = 6210 u8_encode_bits(init->wl_only, RTW89_H2C_CXINIT_INFO_WL_ONLY) | 6211 u8_encode_bits(init->wl_init_ok, RTW89_H2C_CXINIT_INFO_WL_INITOK) | 6212 u8_encode_bits(init->dbcc_en, RTW89_H2C_CXINIT_INFO_DBCC_EN) | 6213 u8_encode_bits(init->cx_other, RTW89_H2C_CXINIT_INFO_CX_OTHER) | 6214 u8_encode_bits(init->bt_only, RTW89_H2C_CXINIT_INFO_BT_ONLY); 6215 6216 rtw89_h2c_pkt_set_hdr(rtwdev, skb, FWCMD_TYPE_H2C, 6217 H2C_CAT_OUTSRC, BTFC_SET, 6218 SET_DRV_INFO, 0, 0, 6219 len); 6220 6221 ret = rtw89_h2c_tx(rtwdev, skb, false); 6222 if (ret) { 6223 rtw89_err(rtwdev, "failed to send h2c\n"); 6224 goto fail; 6225 } 6226 6227 return 0; 6228 fail: 6229 dev_kfree_skb_any(skb); 6230 6231 return ret; 6232 } 6233 6234 int rtw89_fw_h2c_cxdrv_init_v7(struct rtw89_dev *rtwdev, u8 type) 6235 { 6236 struct rtw89_btc *btc = &rtwdev->btc; 6237 struct rtw89_btc_dm *dm = &btc->dm; 6238 struct rtw89_btc_init_info *init = &dm->init_info; 6239 struct rtw89_btc_module *md = &init->module; 6240 struct rtw89_btc_ant_info *ant = &md->ant; 6241 struct rtw89_h2c_cxinit_v7 *h2c; 6242 u32 len = sizeof(*h2c); 6243 struct sk_buff *skb; 6244 int ret; 6245 6246 skb = rtw89_fw_h2c_alloc_skb_with_hdr(rtwdev, len); 6247 if (!skb) { 6248 rtw89_err(rtwdev, "failed to alloc skb for h2c cxdrv_init_v7\n"); 6249 return -ENOMEM; 6250 } 6251 skb_put(skb, len); 6252 h2c = (struct rtw89_h2c_cxinit_v7 *)skb->data; 6253 6254 h2c->hdr.type = type; 6255 h2c->hdr.ver = 7; 6256 h2c->hdr.len = len - H2C_LEN_CXDRVHDR_V7; 6257 6258 h2c->init.wl_guard_ch = init->wl_guard_ch; 6259 h2c->init.wl_only = init->wl_only; 6260 h2c->init.wl_init_ok = init->wl_init_ok; 6261 h2c->init.cx_other = init->cx_other; 6262 h2c->init.bt_only = init->bt_only; 6263 h2c->init.pta_mode = init->pta_mode; 6264 h2c->init.pta_direction = init->pta_direction; 6265 h2c->init.rsvd3 = init->dbcc_en; /* available at v107 */ 6266 6267 h2c->init.module.rfe_type = md->rfe_type; 6268 h2c->init.module.kt_ver = md->kt_ver; 6269 h2c->init.module.bt_solo = md->bt_solo; 6270 h2c->init.module.bt_pos = md->bt0_pos; 6271 h2c->init.module.switch_type = md->bt0_sw_type; 6272 h2c->init.module.wa_type = md->wa_type; 6273 h2c->init.module.kt_ver_adie = md->kt_ver_adie; 6274 6275 h2c->init.module.ant.type = ant->type; 6276 h2c->init.module.ant.num = ant->num; 6277 h2c->init.module.ant.isolation = ant->isolation; 6278 h2c->init.module.ant.single_pos = ant->single_pos; 6279 h2c->init.module.ant.diversity = ant->diversity; 6280 h2c->init.module.ant.btg_pos = ant->btg_pos; 6281 h2c->init.module.ant.stream_cnt = ant->stream_cnt; 6282 6283 rtw89_h2c_pkt_set_hdr(rtwdev, skb, FWCMD_TYPE_H2C, 6284 H2C_CAT_OUTSRC, BTFC_SET, 6285 SET_DRV_INFO, 0, 0, 6286 len); 6287 6288 ret = rtw89_h2c_tx(rtwdev, skb, false); 6289 if (ret) { 6290 rtw89_err(rtwdev, "failed to send h2c\n"); 6291 goto fail; 6292 } 6293 6294 return 0; 6295 fail: 6296 dev_kfree_skb_any(skb); 6297 6298 return ret; 6299 } 6300 6301 int rtw89_fw_h2c_cxdrv_init_v10(struct rtw89_dev *rtwdev, u8 type) 6302 { 6303 struct rtw89_btc *btc = &rtwdev->btc; 6304 struct rtw89_btc_dm *dm = &btc->dm; 6305 struct rtw89_btc_init_info *init = &dm->init_info; 6306 struct rtw89_btc_module *md = &init->module; 6307 struct rtw89_btc_ant_info *ant = &md->ant; 6308 struct rtw89_h2c_cxinit_v10 *h2c; 6309 u32 len = sizeof(*h2c); 6310 struct sk_buff *skb; 6311 int ret; 6312 6313 skb = rtw89_fw_h2c_alloc_skb_with_hdr(rtwdev, len); 6314 if (!skb) { 6315 rtw89_err(rtwdev, "failed to alloc skb for h2c cxdrv_init_v10\n"); 6316 return -ENOMEM; 6317 } 6318 skb_put(skb, len); 6319 h2c = (struct rtw89_h2c_cxinit_v10 *)skb->data; 6320 6321 h2c->hdr.type = type; 6322 h2c->hdr.ver = 10; 6323 h2c->hdr.len = len - H2C_LEN_CXDRVHDR_V7; 6324 6325 h2c->init.endian_type = init->endian_type; 6326 h2c->init.init_mode = init->init_mode; 6327 h2c->init.wl_init_ok = init->wl_init_ok; 6328 h2c->init.bt0_function = init->bt0_function; 6329 h2c->init.bt1_function = init->bt1_function; 6330 h2c->init.bt2_function = init->bt2_function; 6331 h2c->init.pta_mode = init->pta_mode; 6332 h2c->init.pta_direction = init->pta_direction; 6333 6334 h2c->init.module.rfe_type = md->rfe_type; 6335 h2c->init.module.wa_type = md->wa_type; 6336 h2c->init.module.kt_ver = md->kt_ver; 6337 h2c->init.module.kt_ver_adie = md->kt_ver_adie; 6338 h2c->init.module.bt0_pos = md->bt0_pos; 6339 h2c->init.module.bt0_sw_type = md->bt0_sw_type; 6340 h2c->init.module.bt1_pos = md->bt1_pos; 6341 h2c->init.module.bt1_sw_type = md->bt1_sw_type; 6342 6343 h2c->init.module.ant.type = ant->type; 6344 h2c->init.module.ant.num = ant->num; 6345 h2c->init.module.ant.isolation = ant->isolation; 6346 h2c->init.module.ant.single_pos = ant->single_pos; 6347 h2c->init.module.ant.stream_cnt = ant->stream_cnt; 6348 h2c->init.module.ant.btg_pos = ant->btg_pos; 6349 h2c->init.module.ant.btg1_pos = ant->btg1_pos; 6350 6351 memcpy(h2c->init.module.ant.func, ant->func, sizeof(ant->func)); 6352 memcpy(h2c->init.module.ant.ant_xmap, ant->ant_xmap, 6353 sizeof(ant->ant_xmap)); 6354 6355 rtw89_h2c_pkt_set_hdr(rtwdev, skb, FWCMD_TYPE_H2C, 6356 H2C_CAT_OUTSRC, BTFC_SET, 6357 SET_DRV_INFO, 0, 0, 6358 len); 6359 6360 ret = rtw89_h2c_tx(rtwdev, skb, false); 6361 if (ret) { 6362 rtw89_err(rtwdev, "failed to send h2c\n"); 6363 goto fail; 6364 } 6365 6366 return 0; 6367 fail: 6368 dev_kfree_skb_any(skb); 6369 6370 return ret; 6371 } 6372 6373 int rtw89_fw_h2c_cxdrv_init_v11(struct rtw89_dev *rtwdev, u8 type) 6374 { 6375 struct rtw89_btc *btc = &rtwdev->btc; 6376 struct rtw89_btc_dm *dm = &btc->dm; 6377 struct rtw89_btc_init_info *init = &dm->init_info; 6378 struct rtw89_h2c_cxinit_v11 *h2c; 6379 u32 len = sizeof(*h2c); 6380 struct sk_buff *skb; 6381 int ret; 6382 6383 skb = rtw89_fw_h2c_alloc_skb_with_hdr(rtwdev, len); 6384 if (!skb) { 6385 rtw89_err(rtwdev, "failed to alloc skb for h2c cxdrv_init_v11\n"); 6386 return -ENOMEM; 6387 } 6388 skb_put(skb, len); 6389 h2c = (struct rtw89_h2c_cxinit_v11 *)skb->data; 6390 6391 h2c->hdr.type = type; 6392 h2c->hdr.ver = 11; 6393 h2c->hdr.len = len - H2C_LEN_CXDRVHDR_V7; 6394 6395 h2c->init.endian_type = init->endian_type; 6396 h2c->init.init_mode = init->init_mode; 6397 h2c->init.wl_init_ok = init->wl_init_ok; 6398 h2c->init.bt0_function = init->bt0_function; 6399 6400 h2c->init.bt1_function = init->bt1_function; 6401 h2c->init.bt2_function = init->bt2_function; 6402 h2c->init.pta_mode = init->pta_mode; 6403 h2c->init.pta_direction = init->pta_direction; 6404 6405 h2c->init.module.rfe_type = init->module.rfe_type; 6406 h2c->init.module.wa_type = init->module.wa_type; 6407 h2c->init.module.kt_ver = init->module.kt_ver; 6408 h2c->init.module.kt_ver_adie = init->module.kt_ver_adie; 6409 6410 h2c->init.module.bt0_pos = init->module.bt0_pos; 6411 h2c->init.module.bt0_sw_type = init->module.bt0_sw_type; 6412 h2c->init.module.bt1_pos = init->module.bt1_pos; 6413 h2c->init.module.bt1_sw_type = init->module.bt1_sw_type; 6414 6415 h2c->init.module.ant.type = init->module.ant.type; 6416 h2c->init.module.ant.num = init->module.ant.num; 6417 h2c->init.module.ant.isolation = init->module.ant.isolation; 6418 h2c->init.module.ant.single_pos = init->module.ant.single_pos; 6419 6420 h2c->init.module.ant.stream_cnt = init->module.ant.stream_cnt; 6421 h2c->init.module.ant.path_pos = init->module.ant.path_pos; 6422 h2c->init.module.ant.btg_pos = init->module.ant.btg_pos; 6423 h2c->init.module.ant.btg1_pos = init->module.ant.btg1_pos; 6424 memcpy(h2c->init.module.ant.func, init->module.ant.func, 6425 sizeof(init->module.ant.func)); 6426 6427 memcpy(h2c->init.module.ant.ant_xmap, init->module.ant.ant_xmap, 6428 sizeof(init->module.ant.ant_xmap)); 6429 6430 rtw89_h2c_pkt_set_hdr(rtwdev, skb, FWCMD_TYPE_H2C, 6431 H2C_CAT_OUTSRC, BTFC_SET, 6432 SET_DRV_INFO, 0, 0, 6433 len); 6434 6435 ret = rtw89_h2c_tx(rtwdev, skb, false); 6436 if (ret) { 6437 rtw89_err(rtwdev, "failed to send h2c\n"); 6438 goto fail; 6439 } 6440 6441 return 0; 6442 fail: 6443 dev_kfree_skb_any(skb); 6444 6445 return ret; 6446 } 6447 6448 #define PORT_DATA_OFFSET 4 6449 #define H2C_LEN_CXDRVINFO_ROLE_DBCC_LEN 12 6450 #define H2C_LEN_CXDRVINFO_ROLE_SIZE(max_role_num) \ 6451 (4 + 12 * (max_role_num) + H2C_LEN_CXDRVHDR) 6452 6453 int rtw89_fw_h2c_cxdrv_role(struct rtw89_dev *rtwdev, u8 type) 6454 { 6455 struct rtw89_btc *btc = &rtwdev->btc; 6456 struct rtw89_btc_wl_info *wl = &btc->cx.wl; 6457 struct rtw89_btc_wl_role_info *r = &wl->role_info; 6458 const struct rtw89_btc_ver *ver = btc->ver; 6459 struct rtw89_btc_wl_rlink *rl; 6460 struct sk_buff *skb; 6461 u32 rmap = r->role_map[RTW89_MAC_0]; 6462 u8 offset = 0; 6463 u32 len; 6464 u8 *cmd; 6465 int ret; 6466 int i; 6467 6468 len = H2C_LEN_CXDRVINFO_ROLE_SIZE(ver->max_role_num); 6469 6470 skb = rtw89_fw_h2c_alloc_skb_with_hdr(rtwdev, len); 6471 if (!skb) { 6472 rtw89_err(rtwdev, "failed to alloc skb for h2c cxdrv_role\n"); 6473 return -ENOMEM; 6474 } 6475 skb_put(skb, len); 6476 cmd = skb->data; 6477 6478 RTW89_SET_FWCMD_CXHDR_TYPE(cmd, type); 6479 RTW89_SET_FWCMD_CXHDR_LEN(cmd, len - H2C_LEN_CXDRVHDR); 6480 6481 RTW89_SET_FWCMD_CXROLE_CONNECT_CNT(cmd, r->connect_cnt); 6482 RTW89_SET_FWCMD_CXROLE_LINK_MODE(cmd, r->link_mode[RTW89_MAC_0]); 6483 6484 RTW89_SET_FWCMD_CXROLE_ROLE_NONE(cmd, !!(rmap & BIT(RTW89_WIFI_ROLE_NONE))); 6485 RTW89_SET_FWCMD_CXROLE_ROLE_STA(cmd, !!(rmap & BIT(RTW89_WIFI_ROLE_STATION))); 6486 RTW89_SET_FWCMD_CXROLE_ROLE_AP(cmd, !!(rmap & BIT(RTW89_WIFI_ROLE_AP))); 6487 RTW89_SET_FWCMD_CXROLE_ROLE_VAP(cmd, !!(rmap & BIT(RTW89_WIFI_ROLE_AP_VLAN))); 6488 RTW89_SET_FWCMD_CXROLE_ROLE_ADHOC(cmd, !!(rmap & BIT(RTW89_WIFI_ROLE_ADHOC))); 6489 RTW89_SET_FWCMD_CXROLE_ROLE_ADHOC_MASTER(cmd, !!(rmap & BIT(RTW89_WIFI_ROLE_ADHOC_MASTER))); 6490 RTW89_SET_FWCMD_CXROLE_ROLE_MESH(cmd, !!(rmap & BIT(RTW89_WIFI_ROLE_MESH_POINT))); 6491 RTW89_SET_FWCMD_CXROLE_ROLE_MONITOR(cmd, !!(rmap & BIT(RTW89_WIFI_ROLE_MONITOR))); 6492 RTW89_SET_FWCMD_CXROLE_ROLE_P2P_DEV(cmd, !!(rmap & BIT(RTW89_WIFI_ROLE_P2P_DEVICE))); 6493 RTW89_SET_FWCMD_CXROLE_ROLE_P2P_GC(cmd, !!(rmap & BIT(RTW89_WIFI_ROLE_P2P_CLIENT))); 6494 RTW89_SET_FWCMD_CXROLE_ROLE_P2P_GO(cmd, !!(rmap & BIT(RTW89_WIFI_ROLE_P2P_GO))); 6495 RTW89_SET_FWCMD_CXROLE_ROLE_NAN(cmd, !!(rmap & BIT(RTW89_WIFI_ROLE_NAN))); 6496 6497 for (i = 0; i < RTW89_PORT_NUM; i++) { 6498 rl = &r->rlink[i][RTW89_MAC_0]; 6499 RTW89_SET_FWCMD_CXROLE_ACT_CONNECTED(cmd, rl->connected, i, offset); 6500 RTW89_SET_FWCMD_CXROLE_ACT_PID(cmd, rl->pid, i, offset); 6501 RTW89_SET_FWCMD_CXROLE_ACT_PHY(cmd, rl->phy, i, offset); 6502 RTW89_SET_FWCMD_CXROLE_ACT_NOA(cmd, rl->noa, i, offset); 6503 RTW89_SET_FWCMD_CXROLE_ACT_BAND(cmd, rl->rf_band, i, offset); 6504 RTW89_SET_FWCMD_CXROLE_ACT_CLIENT_PS(cmd, rl->client_ps, i, offset); 6505 RTW89_SET_FWCMD_CXROLE_ACT_BW(cmd, rl->bw, i, offset); 6506 RTW89_SET_FWCMD_CXROLE_ACT_ROLE(cmd, rl->role, i, offset); 6507 RTW89_SET_FWCMD_CXROLE_ACT_CH(cmd, rl->ch, i, offset); 6508 RTW89_SET_FWCMD_CXROLE_ACT_TX_LVL(cmd, rl->tx_lvl, i, offset); 6509 RTW89_SET_FWCMD_CXROLE_ACT_RX_LVL(cmd, rl->rx_lvl, i, offset); 6510 RTW89_SET_FWCMD_CXROLE_ACT_TX_RATE(cmd, rl->tx_rate, i, offset); 6511 RTW89_SET_FWCMD_CXROLE_ACT_RX_RATE(cmd, rl->rx_rate, i, offset); 6512 } 6513 6514 rtw89_h2c_pkt_set_hdr(rtwdev, skb, FWCMD_TYPE_H2C, 6515 H2C_CAT_OUTSRC, BTFC_SET, 6516 SET_DRV_INFO, 0, 0, 6517 len); 6518 6519 ret = rtw89_h2c_tx(rtwdev, skb, false); 6520 if (ret) { 6521 rtw89_err(rtwdev, "failed to send h2c\n"); 6522 goto fail; 6523 } 6524 6525 return 0; 6526 fail: 6527 dev_kfree_skb_any(skb); 6528 6529 return ret; 6530 } 6531 6532 #define H2C_LEN_CXDRVINFO_ROLE_SIZE_V1(max_role_num) \ 6533 (4 + 16 * (max_role_num) + H2C_LEN_CXDRVINFO_ROLE_DBCC_LEN + H2C_LEN_CXDRVHDR) 6534 6535 int rtw89_fw_h2c_cxdrv_role_v1(struct rtw89_dev *rtwdev, u8 type) 6536 { 6537 struct rtw89_btc *btc = &rtwdev->btc; 6538 const struct rtw89_btc_ver *ver = btc->ver; 6539 struct rtw89_btc_wl_info *wl = &btc->cx.wl; 6540 struct rtw89_btc_wl_role_info *r = &wl->role_info; 6541 struct rtw89_btc_wl_rlink *rl; 6542 struct sk_buff *skb; 6543 u32 rmap = r->role_map[RTW89_MAC_0]; 6544 u8 *cmd, offset; 6545 u32 len; 6546 int ret; 6547 int i; 6548 6549 len = H2C_LEN_CXDRVINFO_ROLE_SIZE_V1(ver->max_role_num); 6550 6551 skb = rtw89_fw_h2c_alloc_skb_with_hdr(rtwdev, len); 6552 if (!skb) { 6553 rtw89_err(rtwdev, "failed to alloc skb for h2c cxdrv_role\n"); 6554 return -ENOMEM; 6555 } 6556 skb_put(skb, len); 6557 cmd = skb->data; 6558 6559 RTW89_SET_FWCMD_CXHDR_TYPE(cmd, type); 6560 RTW89_SET_FWCMD_CXHDR_LEN(cmd, len - H2C_LEN_CXDRVHDR); 6561 6562 RTW89_SET_FWCMD_CXROLE_CONNECT_CNT(cmd, r->connect_cnt); 6563 RTW89_SET_FWCMD_CXROLE_LINK_MODE(cmd, r->link_mode[RTW89_MAC_0]); 6564 6565 RTW89_SET_FWCMD_CXROLE_ROLE_NONE(cmd, !!(rmap & BIT(RTW89_WIFI_ROLE_NONE))); 6566 RTW89_SET_FWCMD_CXROLE_ROLE_STA(cmd, !!(rmap & BIT(RTW89_WIFI_ROLE_STATION))); 6567 RTW89_SET_FWCMD_CXROLE_ROLE_AP(cmd, !!(rmap & BIT(RTW89_WIFI_ROLE_AP))); 6568 RTW89_SET_FWCMD_CXROLE_ROLE_VAP(cmd, !!(rmap & BIT(RTW89_WIFI_ROLE_AP_VLAN))); 6569 RTW89_SET_FWCMD_CXROLE_ROLE_ADHOC(cmd, !!(rmap & BIT(RTW89_WIFI_ROLE_ADHOC))); 6570 RTW89_SET_FWCMD_CXROLE_ROLE_ADHOC_MASTER(cmd, !!(rmap & BIT(RTW89_WIFI_ROLE_ADHOC_MASTER))); 6571 RTW89_SET_FWCMD_CXROLE_ROLE_MESH(cmd, !!(rmap & BIT(RTW89_WIFI_ROLE_MESH_POINT))); 6572 RTW89_SET_FWCMD_CXROLE_ROLE_MONITOR(cmd, !!(rmap & BIT(RTW89_WIFI_ROLE_MONITOR))); 6573 RTW89_SET_FWCMD_CXROLE_ROLE_P2P_DEV(cmd, !!(rmap & BIT(RTW89_WIFI_ROLE_P2P_DEVICE))); 6574 RTW89_SET_FWCMD_CXROLE_ROLE_P2P_GC(cmd, !!(rmap & BIT(RTW89_WIFI_ROLE_P2P_CLIENT))); 6575 RTW89_SET_FWCMD_CXROLE_ROLE_P2P_GO(cmd, !!(rmap & BIT(RTW89_WIFI_ROLE_P2P_GO))); 6576 RTW89_SET_FWCMD_CXROLE_ROLE_NAN(cmd, !!(rmap & BIT(RTW89_WIFI_ROLE_NAN))); 6577 6578 offset = PORT_DATA_OFFSET; 6579 6580 for (i = 0; i < RTW89_PORT_NUM; i++) { 6581 rl = &r->rlink[i][RTW89_MAC_0]; 6582 RTW89_SET_FWCMD_CXROLE_ACT_CONNECTED(cmd, rl->connected, i, offset); 6583 RTW89_SET_FWCMD_CXROLE_ACT_PID(cmd, rl->pid, i, offset); 6584 RTW89_SET_FWCMD_CXROLE_ACT_PHY(cmd, rl->phy, i, offset); 6585 RTW89_SET_FWCMD_CXROLE_ACT_NOA(cmd, rl->noa, i, offset); 6586 RTW89_SET_FWCMD_CXROLE_ACT_BAND(cmd, rl->rf_band, i, offset); 6587 RTW89_SET_FWCMD_CXROLE_ACT_CLIENT_PS(cmd, rl->client_ps, i, offset); 6588 RTW89_SET_FWCMD_CXROLE_ACT_BW(cmd, rl->bw, i, offset); 6589 RTW89_SET_FWCMD_CXROLE_ACT_ROLE(cmd, rl->role, i, offset); 6590 RTW89_SET_FWCMD_CXROLE_ACT_CH(cmd, rl->ch, i, offset); 6591 RTW89_SET_FWCMD_CXROLE_ACT_TX_LVL(cmd, rl->tx_lvl, i, offset); 6592 RTW89_SET_FWCMD_CXROLE_ACT_RX_LVL(cmd, rl->rx_lvl, i, offset); 6593 RTW89_SET_FWCMD_CXROLE_ACT_TX_RATE(cmd, rl->tx_rate, i, offset); 6594 RTW89_SET_FWCMD_CXROLE_ACT_RX_RATE(cmd, rl->rx_rate, i, offset); 6595 RTW89_SET_FWCMD_CXROLE_ACT_NOA_DUR(cmd, rl->noa_dur, i, offset); 6596 } 6597 6598 offset = len - H2C_LEN_CXDRVINFO_ROLE_DBCC_LEN; 6599 RTW89_SET_FWCMD_CXROLE_MROLE_TYPE(cmd, r->mrole_type, offset); 6600 RTW89_SET_FWCMD_CXROLE_MROLE_NOA(cmd, r->mrole_noa_duration, offset); 6601 RTW89_SET_FWCMD_CXROLE_DBCC_EN(cmd, r->dbcc_en, offset); 6602 RTW89_SET_FWCMD_CXROLE_DBCC_CHG(cmd, r->dbcc_chg, offset); 6603 RTW89_SET_FWCMD_CXROLE_DBCC_2G_PHY(cmd, r->dbcc_2g_phy, offset); 6604 RTW89_SET_FWCMD_CXROLE_LINK_MODE_CHG(cmd, r->link_mode_chg, offset); 6605 6606 rtw89_h2c_pkt_set_hdr(rtwdev, skb, FWCMD_TYPE_H2C, 6607 H2C_CAT_OUTSRC, BTFC_SET, 6608 SET_DRV_INFO, 0, 0, 6609 len); 6610 6611 ret = rtw89_h2c_tx(rtwdev, skb, false); 6612 if (ret) { 6613 rtw89_err(rtwdev, "failed to send h2c\n"); 6614 goto fail; 6615 } 6616 6617 return 0; 6618 fail: 6619 dev_kfree_skb_any(skb); 6620 6621 return ret; 6622 } 6623 6624 int rtw89_fw_h2c_cxdrv_role_v101(struct rtw89_dev *rtwdev, u8 type) 6625 { 6626 struct rtw89_btc *btc = &rtwdev->btc; 6627 struct rtw89_btc_wl_info *wl = &btc->cx.wl; 6628 struct rtw89_btc_wl_role_info *role_info = &wl->role_info; 6629 struct rtw89_btc_wl_rlink *active; 6630 struct rtw89_h2c_cxrole_v101 *h2c; 6631 u32 len = sizeof(*h2c); 6632 struct sk_buff *skb; 6633 int ret; 6634 u8 i; 6635 6636 skb = rtw89_fw_h2c_alloc_skb_with_hdr(rtwdev, len); 6637 if (!skb) { 6638 rtw89_err(rtwdev, "failed to alloc skb for h2c cxdrv_role_v101\n"); 6639 return -ENOMEM; 6640 } 6641 skb_put(skb, len); 6642 h2c = (struct rtw89_h2c_cxrole_v101 *)skb->data; 6643 6644 h2c->hdr.type = type; 6645 h2c->hdr.len = len - H2C_LEN_CXDRVHDR; 6646 6647 h2c->connect_cnt = role_info->connect_cnt; 6648 h2c->link_mode = role_info->link_mode[RTW89_MAC_0]; 6649 h2c->role_map = cpu_to_le16(role_info->role_map[RTW89_MAC_0]); 6650 6651 for (i = 0; i < RTW89_PORT_NUM; i++) { 6652 active = &role_info->rlink[i][0]; 6653 h2c->act_role[i].map_role_status = 6654 u8_encode_bits(active->connected, 6655 RTW89_H2C_CXROLE_V101_ROLE_STAT_CONNTECTED) | 6656 u8_encode_bits(active->pid, 6657 RTW89_H2C_CXROLE_V101_ROLE_STAT_PID) | 6658 u8_encode_bits(active->phy, 6659 RTW89_H2C_CXROLE_V101_ROLE_STAT_PHY) | 6660 u8_encode_bits(active->noa, 6661 RTW89_H2C_CXROLE_V101_ROLE_STAT_NOA) | 6662 u8_encode_bits(active->rf_band, 6663 RTW89_H2C_CXROLE_V101_ROLE_STAT_BADN); 6664 h2c->act_role[i].map_clips_bw = 6665 u8_encode_bits(active->client_ps, 6666 RTW89_H2C_CXROLE_V101_CLIPS_BW_CLIENTPS) | 6667 u8_encode_bits(active->bw, 6668 RTW89_H2C_CXROLE_V101_CLIPS_BW_BW); 6669 h2c->act_role[i].role = active->role; 6670 h2c->act_role[i].ch = active->ch; 6671 h2c->act_role[i].noa_duration = cpu_to_le32(active->noa_dur); 6672 } 6673 6674 h2c->mrole_type = cpu_to_le32(role_info->mrole_type); 6675 h2c->mrole_noa_duration = cpu_to_le32(role_info->mrole_noa_duration); 6676 h2c->map_dbcc_linkmode_chg = 6677 le32_encode_bits(role_info->dbcc_en, 6678 RTW89_H2C_CXROLE_V101_DBCC_EN) | 6679 le32_encode_bits(role_info->dbcc_chg, 6680 RTW89_H2C_CXROLE_V101_DBCC_CHG) | 6681 le32_encode_bits(role_info->dbcc_2g_phy, 6682 RTW89_H2C_CXROLE_V101_DBCC_2G_PHY) | 6683 le32_encode_bits(role_info->link_mode_chg, 6684 RTW89_H2C_CXROLE_V101_DBCC_LINKMODE_CHG) | 6685 le32_encode_bits(role_info->rsvd, 6686 RTW89_H2C_CXROLE_V101_DBCC_RSVD); 6687 6688 rtw89_h2c_pkt_set_hdr(rtwdev, skb, FWCMD_TYPE_H2C, 6689 H2C_CAT_OUTSRC, BTFC_SET, 6690 SET_DRV_INFO, 0, 0, 6691 len); 6692 6693 ret = rtw89_h2c_tx(rtwdev, skb, false); 6694 if (ret) { 6695 rtw89_err(rtwdev, "failed to send h2c\n"); 6696 goto fail; 6697 } 6698 6699 return 0; 6700 fail: 6701 dev_kfree_skb_any(skb); 6702 6703 return ret; 6704 } 6705 6706 #define H2C_LEN_CXDRVINFO_ROLE_SIZE_V2(max_role_num) \ 6707 (4 + 8 * (max_role_num) + H2C_LEN_CXDRVINFO_ROLE_DBCC_LEN + H2C_LEN_CXDRVHDR) 6708 6709 int rtw89_fw_h2c_cxdrv_role_v2(struct rtw89_dev *rtwdev, u8 type) 6710 { 6711 struct rtw89_btc *btc = &rtwdev->btc; 6712 const struct rtw89_btc_ver *ver = btc->ver; 6713 struct rtw89_btc_wl_info *wl = &btc->cx.wl; 6714 struct rtw89_btc_wl_role_info *r = &wl->role_info; 6715 struct rtw89_btc_wl_rlink *rl; 6716 struct sk_buff *skb; 6717 u32 rmap = r->role_map[RTW89_MAC_0]; 6718 u32 len; 6719 u8 *cmd, offset; 6720 int ret; 6721 int i; 6722 6723 len = H2C_LEN_CXDRVINFO_ROLE_SIZE_V2(ver->max_role_num); 6724 6725 skb = rtw89_fw_h2c_alloc_skb_with_hdr(rtwdev, len); 6726 if (!skb) { 6727 rtw89_err(rtwdev, "failed to alloc skb for h2c cxdrv_role\n"); 6728 return -ENOMEM; 6729 } 6730 skb_put(skb, len); 6731 cmd = skb->data; 6732 6733 RTW89_SET_FWCMD_CXHDR_TYPE(cmd, type); 6734 RTW89_SET_FWCMD_CXHDR_LEN(cmd, len - H2C_LEN_CXDRVHDR); 6735 6736 RTW89_SET_FWCMD_CXROLE_CONNECT_CNT(cmd, r->connect_cnt); 6737 RTW89_SET_FWCMD_CXROLE_LINK_MODE(cmd, r->link_mode[RTW89_MAC_0]); 6738 6739 RTW89_SET_FWCMD_CXROLE_ROLE_NONE(cmd, !!(rmap & BIT(RTW89_WIFI_ROLE_NONE))); 6740 RTW89_SET_FWCMD_CXROLE_ROLE_STA(cmd, !!(rmap & BIT(RTW89_WIFI_ROLE_STATION))); 6741 RTW89_SET_FWCMD_CXROLE_ROLE_AP(cmd, !!(rmap & BIT(RTW89_WIFI_ROLE_AP))); 6742 RTW89_SET_FWCMD_CXROLE_ROLE_VAP(cmd, !!(rmap & BIT(RTW89_WIFI_ROLE_AP_VLAN))); 6743 RTW89_SET_FWCMD_CXROLE_ROLE_ADHOC(cmd, !!(rmap & BIT(RTW89_WIFI_ROLE_ADHOC))); 6744 RTW89_SET_FWCMD_CXROLE_ROLE_ADHOC_MASTER(cmd, !!(rmap & BIT(RTW89_WIFI_ROLE_ADHOC_MASTER))); 6745 RTW89_SET_FWCMD_CXROLE_ROLE_MESH(cmd, !!(rmap & BIT(RTW89_WIFI_ROLE_MESH_POINT))); 6746 RTW89_SET_FWCMD_CXROLE_ROLE_MONITOR(cmd, !!(rmap & BIT(RTW89_WIFI_ROLE_MONITOR))); 6747 RTW89_SET_FWCMD_CXROLE_ROLE_P2P_DEV(cmd, !!(rmap & BIT(RTW89_WIFI_ROLE_P2P_DEVICE))); 6748 RTW89_SET_FWCMD_CXROLE_ROLE_P2P_GC(cmd, !!(rmap & BIT(RTW89_WIFI_ROLE_P2P_CLIENT))); 6749 RTW89_SET_FWCMD_CXROLE_ROLE_P2P_GO(cmd, !!(rmap & BIT(RTW89_WIFI_ROLE_P2P_GO))); 6750 RTW89_SET_FWCMD_CXROLE_ROLE_NAN(cmd, !!(rmap & BIT(RTW89_WIFI_ROLE_NAN))); 6751 6752 offset = PORT_DATA_OFFSET; 6753 6754 for (i = 0; i < RTW89_PORT_NUM; i++) { 6755 rl = &r->rlink[i][RTW89_MAC_0]; 6756 RTW89_SET_FWCMD_CXROLE_ACT_CONNECTED_V2(cmd, rl->connected, i, offset); 6757 RTW89_SET_FWCMD_CXROLE_ACT_PID_V2(cmd, rl->pid, i, offset); 6758 RTW89_SET_FWCMD_CXROLE_ACT_PHY_V2(cmd, rl->phy, i, offset); 6759 RTW89_SET_FWCMD_CXROLE_ACT_NOA_V2(cmd, rl->noa, i, offset); 6760 RTW89_SET_FWCMD_CXROLE_ACT_BAND_V2(cmd, rl->rf_band, i, offset); 6761 RTW89_SET_FWCMD_CXROLE_ACT_CLIENT_PS_V2(cmd, rl->client_ps, i, offset); 6762 RTW89_SET_FWCMD_CXROLE_ACT_BW_V2(cmd, rl->bw, i, offset); 6763 RTW89_SET_FWCMD_CXROLE_ACT_ROLE_V2(cmd, rl->role, i, offset); 6764 RTW89_SET_FWCMD_CXROLE_ACT_CH_V2(cmd, rl->ch, i, offset); 6765 RTW89_SET_FWCMD_CXROLE_ACT_NOA_DUR_V2(cmd, rl->noa_dur, i, offset); 6766 } 6767 6768 offset = len - H2C_LEN_CXDRVINFO_ROLE_DBCC_LEN; 6769 RTW89_SET_FWCMD_CXROLE_MROLE_TYPE(cmd, r->mrole_type, offset); 6770 RTW89_SET_FWCMD_CXROLE_MROLE_NOA(cmd, r->mrole_noa_duration, offset); 6771 RTW89_SET_FWCMD_CXROLE_DBCC_EN(cmd, r->dbcc_en, offset); 6772 RTW89_SET_FWCMD_CXROLE_DBCC_CHG(cmd, r->dbcc_chg, offset); 6773 RTW89_SET_FWCMD_CXROLE_DBCC_2G_PHY(cmd, r->dbcc_2g_phy, offset); 6774 RTW89_SET_FWCMD_CXROLE_LINK_MODE_CHG(cmd, r->link_mode_chg, offset); 6775 6776 rtw89_h2c_pkt_set_hdr(rtwdev, skb, FWCMD_TYPE_H2C, 6777 H2C_CAT_OUTSRC, BTFC_SET, 6778 SET_DRV_INFO, 0, 0, 6779 len); 6780 6781 ret = rtw89_h2c_tx(rtwdev, skb, false); 6782 if (ret) { 6783 rtw89_err(rtwdev, "failed to send h2c\n"); 6784 goto fail; 6785 } 6786 6787 return 0; 6788 fail: 6789 dev_kfree_skb_any(skb); 6790 6791 return ret; 6792 } 6793 6794 int rtw89_fw_h2c_cxdrv_role_v7(struct rtw89_dev *rtwdev, u8 type) 6795 { 6796 struct rtw89_btc_wl_role_info *r = &rtwdev->btc.cx.wl.role_info; 6797 struct rtw89_h2c_cxrole_v7 *h2c; 6798 struct rtw89_btc_wl_rlink *rl; 6799 u32 len = sizeof(*h2c); 6800 struct sk_buff *skb; 6801 __le32 rm; 6802 int ret; 6803 u8 i; 6804 6805 skb = rtw89_fw_h2c_alloc_skb_with_hdr(rtwdev, len); 6806 if (!skb) { 6807 rtw89_err(rtwdev, "failed to alloc skb for h2c cxdrv_ctrl\n"); 6808 return -ENOMEM; 6809 } 6810 skb_put(skb, len); 6811 h2c = (struct rtw89_h2c_cxrole_v7 *)skb->data; 6812 6813 h2c->hdr.type = type; 6814 h2c->hdr.ver = 7; 6815 h2c->hdr.len = len - H2C_LEN_CXDRVHDR_V7; 6816 6817 h2c->r.connect_cnt = r->connect_cnt; 6818 h2c->r.link_mode = r->link_mode[RTW89_MAC_0]; 6819 h2c->r.link_mode_chg = r->link_mode_chg; 6820 h2c->r.p2p_2g = r->p2p_2g; 6821 6822 for (i = 0; i < RTW89_BE_BTC_WL_MAX_ROLE_NUMBER; i++) { 6823 rl = &r->rlink[i][RTW89_MAC_0]; 6824 h2c->r.active_role[i].connected = rl->connected; 6825 h2c->r.active_role[i].pid = rl->pid; 6826 h2c->r.active_role[i].phy = rl->phy; 6827 h2c->r.active_role[i].noa = rl->noa; 6828 6829 h2c->r.active_role[i].band = rl->rf_band; 6830 h2c->r.active_role[i].client_ps = rl->client_ps; 6831 h2c->r.active_role[i].bw = rl->bw; 6832 h2c->r.active_role[i].role = rl->role; 6833 6834 h2c->r.active_role[i].ch = rl->ch; 6835 h2c->r.active_role[i].noa_dur = rl->noa_dur; 6836 h2c->r.active_role[i].client_cnt = rl->client_cnt; 6837 } 6838 6839 rm = cpu_to_le32(r->role_map[RTW89_MAC_0]); 6840 memcpy(&h2c->r.role_map, &rm, sizeof(h2c->r.role_map)); 6841 h2c->r.mrole_type = cpu_to_le32(r->mrole_type); 6842 h2c->r.mrole_noa_duration = cpu_to_le32(r->mrole_noa_duration); 6843 h2c->r.dbcc_en = cpu_to_le32((u32)r->dbcc_en); 6844 h2c->r.dbcc_chg = cpu_to_le32(r->dbcc_chg); 6845 h2c->r.dbcc_2g_phy = cpu_to_le32(r->dbcc_2g_phy); 6846 6847 rtw89_h2c_pkt_set_hdr(rtwdev, skb, FWCMD_TYPE_H2C, 6848 H2C_CAT_OUTSRC, BTFC_SET, 6849 SET_DRV_INFO, 0, 0, 6850 len); 6851 6852 ret = rtw89_h2c_tx(rtwdev, skb, false); 6853 if (ret) { 6854 rtw89_err(rtwdev, "failed to send h2c\n"); 6855 goto fail; 6856 } 6857 6858 return 0; 6859 fail: 6860 dev_kfree_skb_any(skb); 6861 6862 return ret; 6863 } 6864 6865 int rtw89_fw_h2c_cxdrv_role_v8(struct rtw89_dev *rtwdev, u8 type) 6866 { 6867 struct rtw89_btc_wl_role_info *r = &rtwdev->btc.cx.wl.role_info; 6868 struct rtw89_h2c_cxrole_v8 *h2c; 6869 struct rtw89_btc_wl_rlink *rl; 6870 u32 len = sizeof(*h2c); 6871 struct sk_buff *skb; 6872 __le32 rm; 6873 int ret; 6874 u8 i, j; 6875 6876 skb = rtw89_fw_h2c_alloc_skb_with_hdr(rtwdev, len); 6877 if (!skb) { 6878 rtw89_err(rtwdev, "failed to alloc skb for h2c cxdrv_ctrl\n"); 6879 return -ENOMEM; 6880 } 6881 skb_put(skb, len); 6882 h2c = (struct rtw89_h2c_cxrole_v8 *)skb->data; 6883 6884 h2c->hdr.type = type; 6885 h2c->hdr.ver = 8; 6886 h2c->hdr.len = len - H2C_LEN_CXDRVHDR_V7; 6887 h2c->r.connect_cnt = r->connect_cnt; 6888 h2c->r.link_mode = r->link_mode[RTW89_MAC_0]; 6889 h2c->r.link_mode_chg = r->link_mode_chg; 6890 h2c->r.p2p_2g = r->p2p_2g; 6891 h2c->r.pta_req_band = r->pta_req_band; 6892 h2c->r.dbcc_en = r->dbcc_en; 6893 h2c->r.dbcc_chg = r->dbcc_chg; 6894 h2c->r.dbcc_2g_phy = r->dbcc_2g_phy; 6895 6896 for (j = RTW89_MAC_0; j <= RTW89_MAC_1; j++) { 6897 for (i = 0; i < RTW89_BE_BTC_WL_MAX_ROLE_NUMBER; i++) { 6898 rl = &r->rlink[i][j]; 6899 h2c->r.rlink[i][j].connected = rl->connected; 6900 h2c->r.rlink[i][j].pid = rl->pid; 6901 h2c->r.rlink[i][j].phy = rl->phy; 6902 h2c->r.rlink[i][j].noa = rl->noa; 6903 6904 h2c->r.rlink[i][j].rf_band = rl->rf_band; 6905 h2c->r.rlink[i][j].active = rl->active; 6906 h2c->r.rlink[i][j].bw = rl->bw; 6907 h2c->r.rlink[i][j].role = rl->role; 6908 6909 h2c->r.rlink[i][j].ch = rl->ch; 6910 h2c->r.rlink[i][j].noa_dur = rl->noa_dur; 6911 h2c->r.rlink[i][j].client_cnt = rl->client_cnt; 6912 h2c->r.rlink[i][j].mode = rl->mode; 6913 } 6914 } 6915 6916 rm = cpu_to_le32(r->role_map[RTW89_MAC_0]); 6917 memcpy(&h2c->r.role_map, &rm, sizeof(h2c->r.role_map)); 6918 h2c->r.mrole_type = cpu_to_le32(r->mrole_type); 6919 h2c->r.mrole_noa_duration = cpu_to_le32(r->mrole_noa_duration); 6920 6921 rtw89_h2c_pkt_set_hdr(rtwdev, skb, FWCMD_TYPE_H2C, 6922 H2C_CAT_OUTSRC, BTFC_SET, 6923 SET_DRV_INFO, 0, 0, 6924 len); 6925 6926 ret = rtw89_h2c_tx(rtwdev, skb, false); 6927 if (ret) { 6928 rtw89_err(rtwdev, "failed to send h2c\n"); 6929 goto fail; 6930 } 6931 6932 return 0; 6933 fail: 6934 dev_kfree_skb_any(skb); 6935 6936 return ret; 6937 } 6938 6939 int rtw89_fw_h2c_cxdrv_role_v10(struct rtw89_dev *rtwdev, u8 type) 6940 { 6941 struct rtw89_btc_wl_role_info *r = &rtwdev->btc.cx.wl.role_info; 6942 struct rtw89_h2c_cxrole_v10 *h2c; 6943 struct rtw89_btc_wl_rlink *rl; 6944 u32 len = sizeof(*h2c); 6945 struct sk_buff *skb; 6946 __le32 rm; 6947 int ret; 6948 u8 i, j; 6949 6950 skb = rtw89_fw_h2c_alloc_skb_with_hdr(rtwdev, len); 6951 if (!skb) { 6952 rtw89_err(rtwdev, "failed to alloc skb for h2c cxdrv_role\n"); 6953 return -ENOMEM; 6954 } 6955 skb_put(skb, len); 6956 h2c = (struct rtw89_h2c_cxrole_v10 *)skb->data; 6957 6958 h2c->hdr.type = type; 6959 h2c->hdr.ver = 10; 6960 h2c->hdr.len = len - H2C_LEN_CXDRVHDR_V7; 6961 6962 for (j = RTW89_MAC_0; j <= RTW89_MAC_1; j++) { 6963 for (i = 0; i < RTW89_BE_BTC_WL_MAX_ROLE_NUMBER; i++) { 6964 rl = &r->rlink[i][j]; 6965 h2c->r.rlink[i][j].connected = rl->connected; 6966 h2c->r.rlink[i][j].pid = rl->pid; 6967 h2c->r.rlink[i][j].phy = rl->phy; 6968 h2c->r.rlink[i][j].noa = rl->noa; 6969 6970 h2c->r.rlink[i][j].rf_band = rl->rf_band; 6971 h2c->r.rlink[i][j].active = rl->active; 6972 h2c->r.rlink[i][j].bw = rl->bw; 6973 h2c->r.rlink[i][j].role = rl->role; 6974 6975 h2c->r.rlink[i][j].ch = rl->ch; 6976 h2c->r.rlink[i][j].noa_dur = rl->noa_dur; 6977 h2c->r.rlink[i][j].client_cnt = rl->client_cnt; 6978 h2c->r.rlink[i][j].mode = rl->mode; 6979 h2c->r.rlink[i][j].mac_id = rl->mac_id; 6980 } 6981 } 6982 6983 h2c->r.link_mode = r->link_mode[RTW89_MAC_0]; 6984 h2c->r.link_mode_hb1 = r->link_mode[RTW89_MAC_1]; 6985 h2c->r.p2p_exist = r->p2p_exist[RTW89_MAC_0]; 6986 h2c->r.p2p_exist_hb1 = r->p2p_exist[RTW89_MAC_1]; 6987 6988 h2c->r.pta_req_band = r->pta_req_band; 6989 h2c->r.dbcc_en = r->dbcc_en; 6990 h2c->r.dbcc_2g_phy = r->dbcc_2g_phy; 6991 6992 rm = cpu_to_le32(r->role_map[RTW89_MAC_0]); 6993 memcpy(&h2c->r.role_map, &rm, sizeof(h2c->r.role_map)); 6994 rm = cpu_to_le32(r->role_map[RTW89_MAC_1]); 6995 memcpy(&h2c->r.role_map_hb1, &rm, sizeof(h2c->r.role_map_hb1)); 6996 h2c->r.mrole_type = cpu_to_le32(r->mrole_type); 6997 6998 rtw89_h2c_pkt_set_hdr(rtwdev, skb, FWCMD_TYPE_H2C, 6999 H2C_CAT_OUTSRC, BTFC_SET, 7000 SET_DRV_INFO, 0, 0, 7001 len); 7002 7003 ret = rtw89_h2c_tx(rtwdev, skb, false); 7004 if (ret) { 7005 rtw89_err(rtwdev, "failed to send h2c\n"); 7006 goto fail; 7007 } 7008 7009 return 0; 7010 fail: 7011 dev_kfree_skb_any(skb); 7012 7013 return ret; 7014 } 7015 7016 int rtw89_fw_h2c_cxdrv_role_v11(struct rtw89_dev *rtwdev, u8 type) 7017 { 7018 struct rtw89_btc_wl_role_info *r = &rtwdev->btc.cx.wl.role_info; 7019 struct rtw89_h2c_cxrole_v11 *h2c; 7020 struct rtw89_btc_wl_rlink *rl; 7021 u32 len = sizeof(*h2c); 7022 struct sk_buff *skb; 7023 __le32 rm; 7024 int ret; 7025 u8 i, j; 7026 7027 skb = rtw89_fw_h2c_alloc_skb_with_hdr(rtwdev, len); 7028 if (!skb) { 7029 rtw89_err(rtwdev, "failed to alloc skb for h2c cxdrv_role\n"); 7030 return -ENOMEM; 7031 } 7032 skb_put(skb, len); 7033 h2c = (struct rtw89_h2c_cxrole_v11 *)skb->data; 7034 7035 h2c->hdr.type = type; 7036 h2c->hdr.ver = 11; 7037 h2c->hdr.len = len - H2C_LEN_CXDRVHDR_V7; 7038 7039 for (j = RTW89_MAC_0; j <= RTW89_MAC_1; j++) { 7040 for (i = 0; i < RTW89_BE_BTC_WL_MAX_ROLE_NUMBER; i++) { 7041 rl = &r->rlink[i][j]; 7042 h2c->r.rlink[i][j].connected = rl->connected; 7043 h2c->r.rlink[i][j].pid = rl->pid; 7044 h2c->r.rlink[i][j].phy = rl->phy; 7045 h2c->r.rlink[i][j].noa = rl->noa; 7046 7047 h2c->r.rlink[i][j].rf_band = rl->rf_band; 7048 h2c->r.rlink[i][j].active = rl->active; 7049 h2c->r.rlink[i][j].bw = rl->bw; 7050 h2c->r.rlink[i][j].role = rl->role; 7051 7052 h2c->r.rlink[i][j].ch = rl->ch; 7053 h2c->r.rlink[i][j].noa_dur = rl->noa_dur; 7054 h2c->r.rlink[i][j].client_cnt = rl->client_cnt; 7055 h2c->r.rlink[i][j].mode = rl->mode; 7056 h2c->r.rlink[i][j].mac_id = rl->mac_id; 7057 } 7058 } 7059 7060 h2c->r.link_mode = r->link_mode[RTW89_MAC_0]; 7061 h2c->r.link_mode_hb1 = r->link_mode[RTW89_MAC_1]; 7062 h2c->r.p2p_exist = r->p2p_exist[RTW89_MAC_0]; 7063 h2c->r.p2p_exist_hb1 = r->p2p_exist[RTW89_MAC_1]; 7064 7065 h2c->r.pta_req_band = r->pta_req_band; 7066 h2c->r.dbcc_en = r->dbcc_en; 7067 h2c->r.dbcc_2g_phy = r->dbcc_2g_phy; 7068 7069 rm = cpu_to_le32(r->role_map[RTW89_MAC_0]); 7070 memcpy(&h2c->r.role_map, &rm, sizeof(h2c->r.role_map)); 7071 rm = cpu_to_le32(r->role_map[RTW89_MAC_1]); 7072 memcpy(&h2c->r.role_map_hb1, &rm, sizeof(h2c->r.role_map_hb1)); 7073 h2c->r.mrole_type = cpu_to_le32(r->mrole_type); 7074 7075 rtw89_h2c_pkt_set_hdr(rtwdev, skb, FWCMD_TYPE_H2C, 7076 H2C_CAT_OUTSRC, BTFC_SET, 7077 SET_DRV_INFO, 0, 0, 7078 len); 7079 7080 ret = rtw89_h2c_tx(rtwdev, skb, false); 7081 if (ret) { 7082 rtw89_err(rtwdev, "failed to send h2c\n"); 7083 goto fail; 7084 } 7085 7086 return 0; 7087 fail: 7088 dev_kfree_skb_any(skb); 7089 7090 return ret; 7091 } 7092 7093 int rtw89_fw_h2c_cxdrv_mlo_v2(struct rtw89_dev *rtwdev, u8 type) 7094 { 7095 struct rtw89_btc_wl_mlo_info *mlo = &rtwdev->btc.cx.wl.mlo_info; 7096 struct rtw89_h2c_cxmlo_v2 *h2c; 7097 u32 len = sizeof(*h2c); 7098 struct sk_buff *skb; 7099 int ret; 7100 7101 skb = rtw89_fw_h2c_alloc_skb_with_hdr(rtwdev, len); 7102 if (!skb) { 7103 rtw89_err(rtwdev, "failed to alloc skb for h2c cxdrv_mlo_v2\n"); 7104 return -ENOMEM; 7105 } 7106 skb_put(skb, len); 7107 h2c = (struct rtw89_h2c_cxmlo_v2 *)skb->data; 7108 7109 h2c->hdr.type = type; 7110 h2c->hdr.ver = 2; 7111 h2c->hdr.len = len - H2C_LEN_CXDRVHDR_V7; 7112 7113 memcpy(h2c->mlo.wmode, mlo->wmode, 7114 sizeof(h2c->mlo.wmode)); 7115 memcpy(h2c->mlo.ch_type, mlo->ch_type, 7116 sizeof(h2c->mlo.ch_type)); 7117 memcpy(h2c->mlo.hwb_rf_band, mlo->hwb_rf_band, 7118 sizeof(h2c->mlo.hwb_rf_band)); 7119 memcpy(h2c->mlo.path_rf_band, mlo->path_rf_band, 7120 sizeof(h2c->mlo.path_rf_band)); 7121 7122 h2c->mlo.wtype = mlo->wtype; 7123 h2c->mlo.mrcx_mode = mlo->mrcx_mode; 7124 h2c->mlo.mrcx_act_hwb_map = mlo->mrcx_act_hwb_map; 7125 h2c->mlo.mrcx_bt_slot_rsp = mlo->mrcx_bt_slot_rsp; 7126 7127 h2c->mlo.rf_combination = mlo->rf_combination; 7128 h2c->mlo.mlo_en = mlo->mlo_en; 7129 h2c->mlo.mlo_adie = mlo->mlo_adie; 7130 h2c->mlo.dual_hw_band_en = mlo->dual_hw_band_en; 7131 h2c->mlo.link_status = cpu_to_le32(mlo->link_status); 7132 7133 rtw89_h2c_pkt_set_hdr(rtwdev, skb, FWCMD_TYPE_H2C, 7134 H2C_CAT_OUTSRC, BTFC_SET, 7135 SET_DRV_INFO, 0, 0, 7136 len); 7137 7138 ret = rtw89_h2c_tx(rtwdev, skb, false); 7139 if (ret) { 7140 rtw89_err(rtwdev, "failed to send h2c\n"); 7141 goto fail; 7142 } 7143 7144 return 0; 7145 fail: 7146 dev_kfree_skb_any(skb); 7147 7148 return ret; 7149 } 7150 7151 int rtw89_fw_h2c_cxdrv_osi_info(struct rtw89_dev *rtwdev, u8 type) 7152 { 7153 struct rtw89_btc *btc = &rtwdev->btc; 7154 struct rtw89_btc_fbtc_outsrc_set_info *osi = &btc->dm.ost_info; 7155 struct rtw89_h2c_cxosi *h2c; 7156 u32 len = sizeof(*h2c); 7157 struct sk_buff *skb; 7158 int ret; 7159 u8 i, j; 7160 7161 skb = rtw89_fw_h2c_alloc_skb_with_hdr(rtwdev, len); 7162 if (!skb) { 7163 rtw89_err(rtwdev, "failed to alloc skb for h2c cxdrv_osi\n"); 7164 return -ENOMEM; 7165 } 7166 skb_put(skb, len); 7167 h2c = (struct rtw89_h2c_cxosi *)skb->data; 7168 7169 h2c->hdr.type = type; 7170 h2c->hdr.ver = btc->ver->fcxosi; 7171 h2c->hdr.len = len - H2C_LEN_CXDRVHDR_V7; 7172 7173 memcpy(h2c->osi.rf_band, osi->rf_band, sizeof(osi->rf_band)); 7174 memcpy(h2c->osi.btg_rx, osi->btg_rx, sizeof(osi->btg_rx)); 7175 memcpy(h2c->osi.nbtg_tx, osi->nbtg_tx, sizeof(osi->nbtg_tx)); 7176 7177 for (i = 0; i < BTC_RF_NUM; i++) { 7178 h2c->osi.gnt_set[i] = osi->gnt_set[i]; 7179 h2c->osi.wlact_set[i] = osi->wlact_set[i]; 7180 } 7181 7182 h2c->osi.pta_req_hw_band = osi->pta_req_hw_band; 7183 h2c->osi.rf_gbt_source = osi->rf_gbt_source; 7184 h2c->osi.bt_enable_state = osi->bt_enable_state; 7185 h2c->osi.wl_btg_standby_chg = osi->wl_btg_standby_chg; 7186 7187 memcpy(h2c->osi.fbd_group_en, osi->fbd_group_en, sizeof(osi->fbd_group_en)); 7188 7189 for (i = 0; i < RTW89_MAC_NUM; i++) { 7190 h2c->osi.rf_center_freq[i] = cpu_to_le16(osi->rf_center_freq[i]); 7191 for (j = 0; j < BTC_RF_NUM; j++) 7192 h2c->osi.fbd_group_bound[i][j] = cpu_to_le16(osi->fbd_group_bound[i][j]); 7193 } 7194 7195 for (i = 0; i < RTW89_MAC_NUM; i++) { 7196 for (j = 0; j < BTC_ALL_BT; j++) 7197 h2c->osi.freq_diff_thres[i][j] = cpu_to_le16(osi->freq_diff_thres[i][j]); 7198 } 7199 7200 rtw89_h2c_pkt_set_hdr(rtwdev, skb, FWCMD_TYPE_H2C, 7201 H2C_CAT_OUTSRC, BTFC_SET, 7202 SET_DRV_INFO, 0, 0, 7203 len); 7204 7205 ret = rtw89_h2c_tx(rtwdev, skb, false); 7206 if (ret) { 7207 rtw89_err(rtwdev, "failed to send h2c\n"); 7208 goto fail; 7209 } 7210 7211 return 0; 7212 fail: 7213 dev_kfree_skb_any(skb); 7214 7215 return ret; 7216 } 7217 7218 int rtw89_fw_h2c_cxdrv_osi_info_v6(struct rtw89_dev *rtwdev, u8 type) 7219 { 7220 struct rtw89_btc *btc = &rtwdev->btc; 7221 struct rtw89_btc_fbtc_outsrc_set_info *osi = &btc->dm.ost_info; 7222 struct rtw89_h2c_cxosi_v6 *h2c; 7223 u32 len = sizeof(*h2c); 7224 struct sk_buff *skb; 7225 int ret; 7226 u8 i, j; 7227 7228 skb = rtw89_fw_h2c_alloc_skb_with_hdr(rtwdev, len); 7229 if (!skb) { 7230 rtw89_err(rtwdev, "failed to alloc skb for h2c cxdrv_osi_v6\n"); 7231 return -ENOMEM; 7232 } 7233 skb_put(skb, len); 7234 h2c = (struct rtw89_h2c_cxosi_v6 *)skb->data; 7235 7236 h2c->hdr.type = type; 7237 h2c->hdr.ver = btc->ver->fcxosi; 7238 h2c->hdr.len = len - H2C_LEN_CXDRVHDR_V7; 7239 7240 memcpy(h2c->osi.rf_band, osi->rf_band, sizeof(osi->rf_band)); 7241 memcpy(h2c->osi.btg_rx, osi->btg_rx, sizeof(osi->btg_rx)); 7242 memcpy(h2c->osi.nbtg_tx, osi->nbtg_tx, sizeof(osi->nbtg_tx)); 7243 memcpy(h2c->osi.gnt_set, osi->gnt_set, sizeof(osi->gnt_set)); 7244 memcpy(h2c->osi.wlact_set, osi->wlact_set, sizeof(osi->wlact_set)); 7245 7246 h2c->osi.pta_req_hw_band = osi->pta_req_hw_band; 7247 h2c->osi.rf_gbt_source = osi->rf_gbt_source; 7248 h2c->osi.bt_enable_state = osi->bt_enable_state; 7249 h2c->osi.bt_plut_type = osi->bt_plut_type; 7250 h2c->osi.wl_tx_limit_en = osi->wl_tx_limit_en; 7251 h2c->osi.fc_exec = osi->fc_exec; 7252 h2c->osi.wl_btg_standby_chg = osi->wl_btg_standby_chg; 7253 h2c->osi.rsvd = 0; 7254 7255 memcpy(h2c->osi.bb_path_sel_bt, osi->bb_path_sel_bt, sizeof(osi->bb_path_sel_bt)); 7256 memcpy(h2c->osi.bb_phy_sel_bt, osi->bb_phy_sel_bt, sizeof(osi->bb_phy_sel_bt)); 7257 memcpy(h2c->osi.fbd_group_en, osi->fbd_group_en, sizeof(osi->fbd_group_en)); 7258 7259 for (i = 0; i < RTW89_MAC_NUM; i++) { 7260 h2c->osi.rf_center_freq[i] = cpu_to_le16(osi->rf_center_freq[i]); 7261 for (j = 0; j < BTC_RF_NUM; j++) 7262 h2c->osi.fbd_group_bound[i][j] = 7263 cpu_to_le16(osi->fbd_group_bound[i][j]); 7264 } 7265 7266 for (i = 0; i < RTW89_MAC_NUM; i++) { 7267 for (j = 0; j < BTC_ALL_BT_EZL; j++) 7268 h2c->osi.freq_diff_thres[i][j] = 7269 cpu_to_le16(osi->freq_diff_thres[i][j]); 7270 } 7271 7272 h2c->osi.wl_tx_limit_time = cpu_to_le32(osi->wl_tx_limit_time); 7273 7274 rtw89_h2c_pkt_set_hdr(rtwdev, skb, FWCMD_TYPE_H2C, 7275 H2C_CAT_OUTSRC, BTFC_SET, 7276 SET_DRV_INFO, 0, 0, 7277 len); 7278 7279 ret = rtw89_h2c_tx(rtwdev, skb, false); 7280 if (ret) { 7281 rtw89_err(rtwdev, "failed to send h2c\n"); 7282 goto fail; 7283 } 7284 7285 return 0; 7286 fail: 7287 dev_kfree_skb_any(skb); 7288 7289 return ret; 7290 } 7291 7292 int rtw89_fw_h2c_cxdrv_osi_info_v7(struct rtw89_dev *rtwdev, u8 type) 7293 { 7294 struct rtw89_btc *btc = &rtwdev->btc; 7295 struct rtw89_btc_fbtc_outsrc_set_info *osi = &btc->dm.ost_info; 7296 struct rtw89_h2c_cxosi_v7 *h2c; 7297 u32 len = sizeof(*h2c); 7298 struct sk_buff *skb; 7299 int ret; 7300 u8 i, j; 7301 7302 skb = rtw89_fw_h2c_alloc_skb_with_hdr(rtwdev, len); 7303 if (!skb) { 7304 rtw89_err(rtwdev, "failed to alloc skb for h2c cxdrv_osi_v7\n"); 7305 return -ENOMEM; 7306 } 7307 skb_put(skb, len); 7308 h2c = (struct rtw89_h2c_cxosi_v7 *)skb->data; 7309 7310 h2c->hdr.type = type; 7311 h2c->hdr.ver = btc->ver->fcxosi; 7312 h2c->hdr.len = len - H2C_LEN_CXDRVHDR_V7; 7313 7314 memcpy(h2c->osi.rf_band, osi->rf_band, sizeof(osi->rf_band)); 7315 memcpy(h2c->osi.btg_rx, osi->btg_rx, sizeof(osi->btg_rx)); 7316 memcpy(h2c->osi.nbtg_tx, osi->nbtg_tx, sizeof(osi->nbtg_tx)); 7317 memcpy(h2c->osi.gnt_set, osi->gnt_set, sizeof(osi->gnt_set)); 7318 memcpy(h2c->osi.wlact_set, osi->wlact_set, sizeof(osi->wlact_set)); 7319 7320 h2c->osi.pta_req_hw_band = osi->pta_req_hw_band; 7321 h2c->osi.rf_gbt_source = osi->rf_gbt_source; 7322 h2c->osi.bt_enable_state = osi->bt_enable_state; 7323 h2c->osi.bt_plut_type = osi->bt_plut_type; 7324 h2c->osi.wl_tx_limit_en = osi->wl_tx_limit_en; 7325 h2c->osi.fc_exec = osi->fc_exec; 7326 h2c->osi.wl_btg_standby_chg = osi->wl_btg_standby_chg; 7327 h2c->osi.option = u8_encode_bits(!!osi->is_spdt_bb, OPTION_SPDT_BB); 7328 7329 memcpy(h2c->osi.bb_path_sel_bt, osi->bb_path_sel_bt, sizeof(osi->bb_path_sel_bt)); 7330 memcpy(h2c->osi.bb_phy_sel_bt, osi->bb_phy_sel_bt, sizeof(osi->bb_phy_sel_bt)); 7331 memcpy(h2c->osi.fbd_group_en, osi->fbd_group_en, sizeof(osi->fbd_group_en)); 7332 7333 for (i = 0; i < RTW89_MAC_NUM; i++) { 7334 h2c->osi.rf_center_freq[i] = cpu_to_le16(osi->rf_center_freq[i]); 7335 for (j = 0; j < BTC_RF_NUM; j++) 7336 h2c->osi.fbd_group_bound[i][j] = cpu_to_le16(osi->fbd_group_bound[i][j]); 7337 } 7338 7339 for (i = 0; i < RTW89_MAC_NUM; i++) { 7340 for (j = 0; j < BTC_ALL_BT_EZL; j++) 7341 h2c->osi.freq_diff_thres[i][j] = cpu_to_le16(osi->freq_diff_thres[i][j]); 7342 } 7343 7344 h2c->osi.wl_tx_limit_time = cpu_to_le32(osi->wl_tx_limit_time); 7345 7346 rtw89_h2c_pkt_set_hdr(rtwdev, skb, FWCMD_TYPE_H2C, 7347 H2C_CAT_OUTSRC, BTFC_SET, 7348 SET_DRV_INFO, 0, 0, 7349 len); 7350 7351 ret = rtw89_h2c_tx(rtwdev, skb, false); 7352 if (ret) { 7353 rtw89_err(rtwdev, "failed to send h2c\n"); 7354 goto fail; 7355 } 7356 7357 return 0; 7358 fail: 7359 dev_kfree_skb_any(skb); 7360 7361 return ret; 7362 } 7363 7364 #define H2C_LEN_CXDRVINFO_CTRL (4 + H2C_LEN_CXDRVHDR) 7365 int rtw89_fw_h2c_cxdrv_ctrl(struct rtw89_dev *rtwdev, u8 type) 7366 { 7367 struct rtw89_btc *btc = &rtwdev->btc; 7368 const struct rtw89_btc_ver *ver = btc->ver; 7369 struct rtw89_btc_ctrl *ctrl = &btc->ctrl; 7370 struct sk_buff *skb; 7371 u8 *cmd; 7372 int ret; 7373 7374 skb = rtw89_fw_h2c_alloc_skb_with_hdr(rtwdev, H2C_LEN_CXDRVINFO_CTRL); 7375 if (!skb) { 7376 rtw89_err(rtwdev, "failed to alloc skb for h2c cxdrv_ctrl\n"); 7377 return -ENOMEM; 7378 } 7379 skb_put(skb, H2C_LEN_CXDRVINFO_CTRL); 7380 cmd = skb->data; 7381 7382 RTW89_SET_FWCMD_CXHDR_TYPE(cmd, type); 7383 RTW89_SET_FWCMD_CXHDR_LEN(cmd, H2C_LEN_CXDRVINFO_CTRL - H2C_LEN_CXDRVHDR); 7384 7385 RTW89_SET_FWCMD_CXCTRL_MANUAL(cmd, ctrl->manual); 7386 RTW89_SET_FWCMD_CXCTRL_IGNORE_BT(cmd, ctrl->igno_bt); 7387 RTW89_SET_FWCMD_CXCTRL_ALWAYS_FREERUN(cmd, ctrl->always_freerun); 7388 if (ver->fcxctrl == 0) 7389 RTW89_SET_FWCMD_CXCTRL_TRACE_STEP(cmd, ctrl->trace_step); 7390 7391 rtw89_h2c_pkt_set_hdr(rtwdev, skb, FWCMD_TYPE_H2C, 7392 H2C_CAT_OUTSRC, BTFC_SET, 7393 SET_DRV_INFO, 0, 0, 7394 H2C_LEN_CXDRVINFO_CTRL); 7395 7396 ret = rtw89_h2c_tx(rtwdev, skb, false); 7397 if (ret) { 7398 rtw89_err(rtwdev, "failed to send h2c\n"); 7399 goto fail; 7400 } 7401 7402 return 0; 7403 fail: 7404 dev_kfree_skb_any(skb); 7405 7406 return ret; 7407 } 7408 7409 int rtw89_fw_h2c_cxdrv_ctrl_v7(struct rtw89_dev *rtwdev, u8 type) 7410 { 7411 struct rtw89_btc *btc = &rtwdev->btc; 7412 struct rtw89_btc_ctrl *ctrl = &btc->ctrl; 7413 struct rtw89_h2c_cxctrl_v7 *h2c; 7414 u32 len = sizeof(*h2c); 7415 struct sk_buff *skb; 7416 int ret; 7417 7418 skb = rtw89_fw_h2c_alloc_skb_with_hdr(rtwdev, len); 7419 if (!skb) { 7420 rtw89_err(rtwdev, "failed to alloc skb for h2c cxdrv_ctrl_v7\n"); 7421 return -ENOMEM; 7422 } 7423 skb_put(skb, len); 7424 h2c = (struct rtw89_h2c_cxctrl_v7 *)skb->data; 7425 7426 h2c->hdr.type = type; 7427 h2c->hdr.ver = btc->ver->fcxctrl; 7428 h2c->hdr.len = sizeof(*h2c) - H2C_LEN_CXDRVHDR_V7; 7429 7430 h2c->ctrl.manual = ctrl->manual; 7431 h2c->ctrl.igno_bt = ctrl->igno_bt; 7432 h2c->ctrl.always_freerun = ctrl->always_freerun; 7433 7434 rtw89_h2c_pkt_set_hdr(rtwdev, skb, FWCMD_TYPE_H2C, 7435 H2C_CAT_OUTSRC, BTFC_SET, 7436 SET_DRV_INFO, 0, 0, len); 7437 7438 ret = rtw89_h2c_tx(rtwdev, skb, false); 7439 if (ret) { 7440 rtw89_err(rtwdev, "failed to send h2c\n"); 7441 goto fail; 7442 } 7443 7444 return 0; 7445 fail: 7446 dev_kfree_skb_any(skb); 7447 7448 return ret; 7449 } 7450 7451 int rtw89_fw_h2c_cxdrv_ctrl_v9(struct rtw89_dev *rtwdev, u8 type) 7452 { 7453 struct rtw89_btc *btc = &rtwdev->btc; 7454 struct rtw89_btc_ctrl *ctrl = &btc->ctrl; 7455 struct rtw89_fbtc_wl_ctrl_info_v9 *cinfo; 7456 struct rtw89_h2c_cxctrl_v9 *h2c; 7457 u32 len = sizeof(*h2c); 7458 struct sk_buff *skb; 7459 int ret; 7460 7461 skb = rtw89_fw_h2c_alloc_skb_with_hdr(rtwdev, len); 7462 if (!skb) { 7463 rtw89_err(rtwdev, "failed to alloc skb for h2c cxdrv_ctrl_v7\n"); 7464 return -ENOMEM; 7465 } 7466 skb_put(skb, len); 7467 h2c = (struct rtw89_h2c_cxctrl_v9 *)skb->data; 7468 cinfo = &h2c->ctrl.wl_ctrl_info; 7469 7470 h2c->hdr.type = type; 7471 h2c->hdr.ver = btc->ver->fcxctrl; 7472 h2c->hdr.len = sizeof(*h2c) - H2C_LEN_CXDRVHDR_V7; 7473 7474 h2c->ctrl.manual = ctrl->manual; 7475 h2c->ctrl.always_freerun = ctrl->always_freerun; 7476 h2c->ctrl.wl_only = ctrl->wl_only; 7477 h2c->ctrl.bt_only = ctrl->bt_only; 7478 h2c->ctrl.ntfy_type = ctrl->ntfy_type; 7479 memcpy(cinfo->rf_band_map, ctrl->wl_ctrl_info.rf_band_map, 7480 sizeof(cinfo->rf_band_map)); 7481 memcpy(cinfo->rf_ch, ctrl->wl_ctrl_info.rf_ch, sizeof(cinfo->rf_ch)); 7482 cinfo->client_pstdma_on = ctrl->wl_ctrl_info.client_pstdma_on; 7483 cinfo->fw_scan = ctrl->wl_ctrl_info.fw_scan; 7484 cinfo->rfk_state = ctrl->wl_ctrl_info.rfk_state; 7485 cinfo->rfk_type = ctrl->wl_ctrl_info.rfk_type; 7486 cinfo->smap_val = cpu_to_le32(ctrl->wl_ctrl_info.smap_val); 7487 7488 rtw89_h2c_pkt_set_hdr(rtwdev, skb, FWCMD_TYPE_H2C, 7489 H2C_CAT_OUTSRC, BTFC_SET, 7490 SET_DRV_INFO, 0, 0, len); 7491 7492 ret = rtw89_h2c_tx(rtwdev, skb, false); 7493 if (ret) { 7494 rtw89_err(rtwdev, "failed to send h2c\n"); 7495 goto fail; 7496 } 7497 7498 return 0; 7499 fail: 7500 dev_kfree_skb_any(skb); 7501 7502 return ret; 7503 } 7504 7505 static void rtw89_btc_load_trx_para(struct rtw89_dev *rtwdev) 7506 { 7507 struct rtw89_btc *btc = &rtwdev->btc; 7508 struct rtw89_btc_rf_trx_para_v9 rf_para = btc->dm.rf_trx_para; 7509 struct rtw89_btc_trx_info *trx = &btc->dm.trx_info; 7510 struct rtw89_btc_wl_info *wl = &btc->cx.wl; 7511 u8 i; 7512 7513 for (i = 0; i < RTW89_PHY_NUM; i++) { 7514 trx->wl_tx_power[i] = u32_get_bits(rf_para.wl_tx_power[i], 7515 RTW89_BTC_WL_DEF_TX_PWR); 7516 trx->wl_rx_gain[i] = u32_get_bits(rf_para.wl_rx_gain[i], 7517 RTW89_BTC_WL_DEF_TX_PWR); 7518 if (btc->ver->fcxtrx == 107) 7519 break; 7520 } 7521 7522 for (i = 0; i < BTC_ALL_BT; i++) { 7523 trx->bt_tx_power[i] = u32_get_bits(rf_para.bt_tx_power[i], 7524 RTW89_BTC_WL_DEF_TX_PWR); 7525 trx->bt_rx_gain[i] = u32_get_bits(rf_para.bt_rx_gain[i], 7526 RTW89_BTC_WL_DEF_TX_PWR); 7527 if (btc->ver->fcxtrx == 107) 7528 break; 7529 7530 trx->zb_tx_power[i] = u32_get_bits(rf_para.zb_tx_power[i], 7531 RTW89_BTC_WL_DEF_TX_PWR); 7532 trx->zb_rx_gain[i] = u32_get_bits(rf_para.zb_rx_gain[i], 7533 RTW89_BTC_WL_DEF_TX_PWR); 7534 } 7535 7536 trx->cn = wl->cn_report; 7537 trx->nhm = wl->nhm.pwr; 7538 } 7539 7540 int rtw89_fw_h2c_cxdrv_trx_v7(struct rtw89_dev *rtwdev, u8 type) 7541 { 7542 struct rtw89_btc *btc = &rtwdev->btc; 7543 struct rtw89_btc_trx_info *trx = &btc->dm.trx_info; 7544 struct rtw89_h2c_cxtrx_v7 *h2c; 7545 u32 len = sizeof(*h2c); 7546 struct sk_buff *skb; 7547 int ret; 7548 7549 rtw89_btc_load_trx_para(rtwdev); 7550 7551 skb = rtw89_fw_h2c_alloc_skb_with_hdr(rtwdev, len); 7552 if (!skb) { 7553 rtw89_err(rtwdev, "failed to alloc skb for h2c cxtrx_v9\n"); 7554 return -ENOMEM; 7555 } 7556 skb_put(skb, len); 7557 h2c = (struct rtw89_h2c_cxtrx_v7 *)skb->data; 7558 7559 h2c->hdr.type = type; 7560 h2c->hdr.ver = 7; 7561 h2c->hdr.len = sizeof(*h2c) - H2C_LEN_CXDRVHDR_V7; 7562 7563 h2c->v7_u8.tx_lvl = trx->tx_lvl; 7564 h2c->v7_u8.rx_lvl = trx->rx_lvl; 7565 h2c->v7_u8.wl_rssi = trx->wl_rssi; 7566 h2c->v7_u8.bt_rssi = trx->bt_rssi; 7567 h2c->v7_u8.wl_tx_power = trx->wl_tx_power[RTW89_PHY_0]; 7568 h2c->v7_u8.wl_rx_gain = trx->wl_rx_gain[RTW89_PHY_0]; 7569 h2c->v7_u8.bt_tx_power = trx->bt_tx_power[BTC_BT_1ST]; 7570 h2c->v7_u8.bt_rx_gain = trx->bt_rx_gain[BTC_BT_1ST]; 7571 h2c->v7_u8.zb_tx_power = trx->zb_tx_power[BTC_BT_1ST]; 7572 h2c->v7_u8.zb_rx_gain = trx->zb_rx_gain[BTC_BT_1ST]; 7573 h2c->v7_u8.cn = trx->cn; 7574 h2c->v7_u8.nhm = trx->nhm; 7575 h2c->v7_u8.bt0_profile = trx->bt0_profile; 7576 h2c->v7_u8.bt1_profile = trx->bt1_profile; 7577 h2c->v7_le.tx_rate = cpu_to_le16(trx->tx_rate); 7578 h2c->v7_le.rx_rate = cpu_to_le16(trx->rx_rate); 7579 h2c->v7_le.tx_tp = cpu_to_le32(trx->tx_tp); 7580 h2c->v7_le.rx_tp = cpu_to_le32(trx->rx_tp); 7581 h2c->v7_le.rx_err_ratio = cpu_to_le32(trx->rx_err_ratio); 7582 7583 rtw89_h2c_pkt_set_hdr(rtwdev, skb, FWCMD_TYPE_H2C, 7584 H2C_CAT_OUTSRC, BTFC_SET, 7585 SET_DRV_INFO, 0, 0, len); 7586 7587 ret = rtw89_h2c_tx(rtwdev, skb, false); 7588 if (ret) { 7589 rtw89_err(rtwdev, "failed to send h2c\n"); 7590 goto fail; 7591 } 7592 7593 return 0; 7594 fail: 7595 dev_kfree_skb_any(skb); 7596 7597 return ret; 7598 } 7599 7600 int rtw89_fw_h2c_cxdrv_trx_v9(struct rtw89_dev *rtwdev, u8 type) 7601 { 7602 struct rtw89_btc *btc = &rtwdev->btc; 7603 struct rtw89_btc_trx_info *trx = &btc->dm.trx_info; 7604 struct rtw89_h2c_cxtrx_v9 *h2c; 7605 u32 len = sizeof(*h2c); 7606 struct sk_buff *skb; 7607 int ret; 7608 u8 i; 7609 7610 rtw89_btc_load_trx_para(rtwdev); 7611 7612 skb = rtw89_fw_h2c_alloc_skb_with_hdr(rtwdev, len); 7613 if (!skb) { 7614 rtw89_err(rtwdev, "failed to alloc skb for h2c cxtrx_v9\n"); 7615 return -ENOMEM; 7616 } 7617 skb_put(skb, len); 7618 h2c = (struct rtw89_h2c_cxtrx_v9 *)skb->data; 7619 7620 h2c->hdr.type = type; 7621 h2c->hdr.ver = 9; 7622 h2c->hdr.len = sizeof(*h2c) - H2C_LEN_CXDRVHDR_V7; 7623 7624 h2c->v9_u8.tx_lvl = trx->tx_lvl; 7625 h2c->v9_u8.rx_lvl = trx->rx_lvl; 7626 h2c->v9_u8.wl_rssi = trx->wl_rssi; 7627 h2c->v9_u8.bt_rssi = trx->bt_rssi; 7628 7629 for (i = 0; i < RTW89_PHY_NUM; i++) { 7630 h2c->v9_u8.wl_tx_power[i] = trx->wl_tx_power[i]; 7631 h2c->v9_u8.wl_rx_gain[i] = trx->wl_rx_gain[i]; 7632 } 7633 7634 for (i = 0; i < BTC_ALL_BT; i++) { 7635 h2c->v9_u8.bt_tx_power[i] = trx->bt_tx_power[i]; 7636 h2c->v9_u8.bt_rx_gain[i] = trx->bt_rx_gain[i]; 7637 h2c->v9_u8.zb_tx_power[i] = trx->zb_tx_power[i]; 7638 h2c->v9_u8.zb_rx_gain[i] = trx->zb_rx_gain[i]; 7639 } 7640 h2c->v9_u8.cn = trx->cn; 7641 h2c->v9_u8.nhm = trx->nhm; 7642 h2c->v9_u8.bt0_profile = trx->bt0_profile; 7643 h2c->v9_u8.bt1_profile = trx->bt1_profile; 7644 h2c->v9_le.tx_rate = cpu_to_le16(trx->tx_rate); 7645 h2c->v9_le.rx_rate = cpu_to_le16(trx->rx_rate); 7646 h2c->v9_le.tx_tp = cpu_to_le32(trx->tx_tp); 7647 h2c->v9_le.rx_tp = cpu_to_le32(trx->rx_tp); 7648 h2c->v9_le.rx_err_ratio = cpu_to_le32(trx->rx_err_ratio); 7649 7650 rtw89_h2c_pkt_set_hdr(rtwdev, skb, FWCMD_TYPE_H2C, 7651 H2C_CAT_OUTSRC, BTFC_SET, 7652 SET_DRV_INFO, 0, 0, len); 7653 7654 ret = rtw89_h2c_tx(rtwdev, skb, false); 7655 if (ret) { 7656 rtw89_err(rtwdev, "failed to send h2c\n"); 7657 goto fail; 7658 } 7659 7660 return 0; 7661 fail: 7662 dev_kfree_skb_any(skb); 7663 7664 return ret; 7665 } 7666 7667 int rtw89_fw_h2c_cxdrv_trx_v107(struct rtw89_dev *rtwdev, u8 type) 7668 { 7669 struct rtw89_btc *btc = &rtwdev->btc; 7670 struct rtw89_btc_trx_info *trx = &btc->dm.trx_info; 7671 struct rtw89_h2c_cxtrx_v107 *h2c; 7672 u32 len = sizeof(*h2c); 7673 struct sk_buff *skb; 7674 int ret; 7675 7676 rtw89_btc_load_trx_para(rtwdev); 7677 7678 skb = rtw89_fw_h2c_alloc_skb_with_hdr(rtwdev, len); 7679 if (!skb) { 7680 rtw89_err(rtwdev, "failed to alloc skb for h2c cxtrx_v107\n"); 7681 return -ENOMEM; 7682 } 7683 skb_put(skb, len); 7684 h2c = (struct rtw89_h2c_cxtrx_v107 *)skb->data; 7685 7686 h2c->hdr.type = type; 7687 h2c->hdr.ver = 7; 7688 h2c->hdr.len = sizeof(*h2c) - H2C_LEN_CXDRVHDR_V7; 7689 7690 h2c->v107_u8.tx_lvl = trx->tx_lvl; 7691 h2c->v107_u8.rx_lvl = trx->rx_lvl; 7692 h2c->v107_u8.wl_rssi = trx->wl_rssi; 7693 h2c->v107_u8.bt_rssi = trx->bt_rssi; 7694 h2c->v107_u8.wl_tx_power = trx->bt_tx_power[RTW89_PHY_0]; 7695 h2c->v107_u8.wl_rx_gain = trx->wl_rx_gain[RTW89_PHY_0]; 7696 h2c->v107_u8.bt_tx_power = trx->bt_tx_power[BTC_BT_1ST]; 7697 h2c->v107_u8.bt_rx_gain = trx->bt_rx_gain[BTC_BT_1ST]; 7698 h2c->v107_u8.cn = trx->cn; 7699 h2c->v107_u8.nhm = trx->nhm; 7700 h2c->v107_u8.bt0_profile = trx->bt0_profile; 7701 h2c->v107_u8.bt1_profile = trx->bt1_profile; 7702 h2c->v7_le.tx_rate = cpu_to_le16(trx->tx_rate); 7703 h2c->v7_le.rx_rate = cpu_to_le16(trx->rx_rate); 7704 h2c->v7_le.tx_tp = cpu_to_le32(trx->tx_tp); 7705 h2c->v7_le.rx_tp = cpu_to_le32(trx->rx_tp); 7706 h2c->v7_le.rx_err_ratio = cpu_to_le32(trx->rx_err_ratio); 7707 7708 rtw89_h2c_pkt_set_hdr(rtwdev, skb, FWCMD_TYPE_H2C, 7709 H2C_CAT_OUTSRC, BTFC_SET, 7710 SET_DRV_INFO, 0, 0, len); 7711 7712 ret = rtw89_h2c_tx(rtwdev, skb, false); 7713 if (ret) { 7714 rtw89_err(rtwdev, "failed to send h2c\n"); 7715 goto fail; 7716 } 7717 7718 return 0; 7719 fail: 7720 dev_kfree_skb_any(skb); 7721 7722 return ret; 7723 } 7724 7725 #define H2C_LEN_CXDRVINFO_RFK (4 + H2C_LEN_CXDRVHDR) 7726 int rtw89_fw_h2c_cxdrv_rfk(struct rtw89_dev *rtwdev, u8 type) 7727 { 7728 struct rtw89_btc *btc = &rtwdev->btc; 7729 struct rtw89_btc_wl_info *wl = &btc->cx.wl; 7730 struct rtw89_btc_wl_rfk_info *rfk_info = &wl->rfk_info; 7731 struct sk_buff *skb; 7732 u8 *cmd; 7733 int ret; 7734 7735 skb = rtw89_fw_h2c_alloc_skb_with_hdr(rtwdev, H2C_LEN_CXDRVINFO_RFK); 7736 if (!skb) { 7737 rtw89_err(rtwdev, "failed to alloc skb for h2c cxdrv_ctrl\n"); 7738 return -ENOMEM; 7739 } 7740 skb_put(skb, H2C_LEN_CXDRVINFO_RFK); 7741 cmd = skb->data; 7742 7743 RTW89_SET_FWCMD_CXHDR_TYPE(cmd, type); 7744 RTW89_SET_FWCMD_CXHDR_LEN(cmd, H2C_LEN_CXDRVINFO_RFK - H2C_LEN_CXDRVHDR); 7745 7746 RTW89_SET_FWCMD_CXRFK_STATE(cmd, rfk_info->state); 7747 RTW89_SET_FWCMD_CXRFK_PATH_MAP(cmd, rfk_info->path_map); 7748 RTW89_SET_FWCMD_CXRFK_PHY_MAP(cmd, rfk_info->phy_map); 7749 RTW89_SET_FWCMD_CXRFK_BAND(cmd, rfk_info->band); 7750 RTW89_SET_FWCMD_CXRFK_TYPE(cmd, rfk_info->type); 7751 7752 rtw89_h2c_pkt_set_hdr(rtwdev, skb, FWCMD_TYPE_H2C, 7753 H2C_CAT_OUTSRC, BTFC_SET, 7754 SET_DRV_INFO, 0, 0, 7755 H2C_LEN_CXDRVINFO_RFK); 7756 7757 ret = rtw89_h2c_tx(rtwdev, skb, false); 7758 if (ret) { 7759 rtw89_err(rtwdev, "failed to send h2c\n"); 7760 goto fail; 7761 } 7762 7763 return 0; 7764 fail: 7765 dev_kfree_skb_any(skb); 7766 7767 return ret; 7768 } 7769 7770 int rtw89_fw_h2c_cxtxpwr_v7(struct rtw89_dev *rtwdev, u8 type) 7771 { 7772 struct rtw89_btc *btc = &rtwdev->btc; 7773 struct rtw89_btc_dm *dm = &btc->dm; 7774 struct rtw89_btc_rf_trx_para_v9 rp = dm->rf_trx_para; 7775 struct rtw89_h2c_cxtxpwr_v7 *h2c; 7776 u32 len = sizeof(*h2c); 7777 struct sk_buff *skb; 7778 int ret; 7779 7780 skb = rtw89_fw_h2c_alloc_skb_with_hdr(rtwdev, len); 7781 if (!skb) { 7782 rtw89_err(rtwdev, "failed to alloc skb for h2c cxdrv_ctrl\n"); 7783 return -ENOMEM; 7784 } 7785 skb_put(skb, len); 7786 h2c = (struct rtw89_h2c_cxtxpwr_v7 *)skb->data; 7787 7788 h2c->hdr.type = type; 7789 h2c->hdr.ver = 7; 7790 h2c->hdr.len = sizeof(*h2c) - H2C_LEN_CXDRVHDR_V7; 7791 h2c->pwr = rp.wl_tx_power[RTW89_PHY_0] & 0xff; 7792 7793 rtw89_h2c_pkt_set_hdr(rtwdev, skb, FWCMD_TYPE_H2C, 7794 H2C_CAT_OUTSRC, BTFC_SET, 7795 SET_DRV_INFO, 0, 0, len); 7796 7797 ret = rtw89_h2c_tx(rtwdev, skb, false); 7798 if (ret) { 7799 rtw89_err(rtwdev, "failed to send h2c\n"); 7800 goto fail; 7801 } 7802 7803 return 0; 7804 fail: 7805 dev_kfree_skb_any(skb); 7806 7807 return ret; 7808 } 7809 7810 int rtw89_fw_h2c_cxtxpwr_v9(struct rtw89_dev *rtwdev, u8 type, u8 ver) 7811 { 7812 struct rtw89_btc *btc = &rtwdev->btc; 7813 struct rtw89_btc_dm *dm = &btc->dm; 7814 struct rtw89_btc_rf_trx_para_v9 rp = dm->rf_trx_para; 7815 struct rtw89_h2c_cxtxpwr_v9 *h2c; 7816 u32 len = sizeof(*h2c); 7817 struct sk_buff *skb; 7818 int ret; 7819 7820 skb = rtw89_fw_h2c_alloc_skb_with_hdr(rtwdev, len); 7821 if (!skb) { 7822 rtw89_err(rtwdev, "failed to alloc skb for h2c cxtxpwr\n"); 7823 return -ENOMEM; 7824 } 7825 skb_put(skb, len); 7826 h2c = (struct rtw89_h2c_cxtxpwr_v9 *)skb->data; 7827 7828 h2c->hdr.type = type; 7829 h2c->hdr.ver = ver; 7830 h2c->hdr.len = sizeof(*h2c) - H2C_LEN_CXDRVHDR_V7; 7831 if (dm->wl_tx_pwr_phy_map == BIT(RTW89_PHY_1)) 7832 h2c->pwr = rp.wl_tx_power[RTW89_PHY_1] & 0xff; 7833 else 7834 h2c->pwr = rp.wl_tx_power[RTW89_PHY_0] & 0xff; 7835 h2c->band = dm->wl_tx_pwr_phy_map; 7836 7837 rtw89_h2c_pkt_set_hdr(rtwdev, skb, FWCMD_TYPE_H2C, 7838 H2C_CAT_OUTSRC, BTFC_SET, 7839 SET_DRV_INFO, 0, 0, len); 7840 7841 ret = rtw89_h2c_tx(rtwdev, skb, false); 7842 if (ret) { 7843 rtw89_err(rtwdev, "failed to send h2c\n"); 7844 goto fail; 7845 } 7846 7847 return 0; 7848 fail: 7849 dev_kfree_skb_any(skb); 7850 7851 return ret; 7852 } 7853 7854 #define H2C_LEN_PKT_OFLD 4 7855 int rtw89_fw_h2c_del_pkt_offload(struct rtw89_dev *rtwdev, u8 id) 7856 { 7857 struct rtw89_wait_info *wait = &rtwdev->mac.fw_ofld_wait; 7858 struct sk_buff *skb; 7859 unsigned int cond; 7860 u8 *cmd; 7861 int ret; 7862 7863 skb = rtw89_fw_h2c_alloc_skb_with_hdr(rtwdev, H2C_LEN_PKT_OFLD); 7864 if (!skb) { 7865 rtw89_err(rtwdev, "failed to alloc skb for h2c pkt offload\n"); 7866 return -ENOMEM; 7867 } 7868 skb_put(skb, H2C_LEN_PKT_OFLD); 7869 cmd = skb->data; 7870 7871 RTW89_SET_FWCMD_PACKET_OFLD_PKT_IDX(cmd, id); 7872 RTW89_SET_FWCMD_PACKET_OFLD_PKT_OP(cmd, RTW89_PKT_OFLD_OP_DEL); 7873 7874 rtw89_h2c_pkt_set_hdr(rtwdev, skb, FWCMD_TYPE_H2C, 7875 H2C_CAT_MAC, H2C_CL_MAC_FW_OFLD, 7876 H2C_FUNC_PACKET_OFLD, 1, 1, 7877 H2C_LEN_PKT_OFLD); 7878 7879 cond = RTW89_FW_OFLD_WAIT_COND_PKT_OFLD(id, RTW89_PKT_OFLD_OP_DEL); 7880 7881 ret = rtw89_h2c_tx_and_wait(rtwdev, skb, wait, cond); 7882 if (ret < 0) { 7883 rtw89_debug(rtwdev, RTW89_DBG_FW, 7884 "failed to del pkt ofld: id %d, ret %d\n", 7885 id, ret); 7886 return ret; 7887 } 7888 7889 rtw89_core_release_bit_map(rtwdev->pkt_offload, id); 7890 return 0; 7891 } 7892 7893 static int __rtw89_fw_h2c_add_pkt_offload(struct rtw89_dev *rtwdev, u8 *id, 7894 struct sk_buff *skb_ofld) 7895 { 7896 struct rtw89_wait_info *wait = &rtwdev->mac.fw_ofld_wait; 7897 struct sk_buff *skb; 7898 unsigned int cond; 7899 u8 *cmd; 7900 u8 alloc_id; 7901 int ret; 7902 7903 alloc_id = rtw89_core_acquire_bit_map(rtwdev->pkt_offload, 7904 RTW89_MAX_PKT_OFLD_NUM); 7905 if (alloc_id == RTW89_MAX_PKT_OFLD_NUM) 7906 return -ENOSPC; 7907 7908 *id = alloc_id; 7909 7910 skb = rtw89_fw_h2c_alloc_skb_with_hdr(rtwdev, H2C_LEN_PKT_OFLD + skb_ofld->len); 7911 if (!skb) { 7912 rtw89_err(rtwdev, "failed to alloc skb for h2c pkt offload\n"); 7913 rtw89_core_release_bit_map(rtwdev->pkt_offload, alloc_id); 7914 return -ENOMEM; 7915 } 7916 skb_put(skb, H2C_LEN_PKT_OFLD); 7917 cmd = skb->data; 7918 7919 RTW89_SET_FWCMD_PACKET_OFLD_PKT_IDX(cmd, alloc_id); 7920 RTW89_SET_FWCMD_PACKET_OFLD_PKT_OP(cmd, RTW89_PKT_OFLD_OP_ADD); 7921 RTW89_SET_FWCMD_PACKET_OFLD_PKT_LENGTH(cmd, skb_ofld->len); 7922 skb_put_data(skb, skb_ofld->data, skb_ofld->len); 7923 7924 rtw89_h2c_pkt_set_hdr(rtwdev, skb, FWCMD_TYPE_H2C, 7925 H2C_CAT_MAC, H2C_CL_MAC_FW_OFLD, 7926 H2C_FUNC_PACKET_OFLD, 1, 1, 7927 H2C_LEN_PKT_OFLD + skb_ofld->len); 7928 7929 cond = RTW89_FW_OFLD_WAIT_COND_PKT_OFLD(alloc_id, RTW89_PKT_OFLD_OP_ADD); 7930 7931 ret = rtw89_h2c_tx_and_wait(rtwdev, skb, wait, cond); 7932 if (ret < 0) { 7933 rtw89_debug(rtwdev, RTW89_DBG_FW, 7934 "failed to add pkt ofld: id %d, ret %d\n", 7935 alloc_id, ret); 7936 /* 7937 * Firmware may consider that it has added this entry 7938 * successfully even though the H2C return timeout. 7939 * Send a delete H2C command to drop it, and thus the 7940 * next add on the same id won't be rejected as duplicate. 7941 */ 7942 rtw89_fw_h2c_del_pkt_offload(rtwdev, alloc_id); 7943 rtw89_core_release_bit_map(rtwdev->pkt_offload, alloc_id); 7944 7945 return -EAGAIN; 7946 } 7947 7948 return 0; 7949 } 7950 7951 int rtw89_fw_h2c_add_pkt_offload(struct rtw89_dev *rtwdev, u8 *id, 7952 struct sk_buff *skb_ofld) 7953 { 7954 int ret; 7955 7956 ret = __rtw89_fw_h2c_add_pkt_offload(rtwdev, id, skb_ofld); 7957 if (ret == -EAGAIN) 7958 ret = __rtw89_fw_h2c_add_pkt_offload(rtwdev, id, skb_ofld); 7959 7960 return ret; 7961 } 7962 7963 static 7964 int rtw89_fw_h2c_scan_list_offload_ax(struct rtw89_dev *rtwdev, int ch_num, 7965 struct list_head *chan_list) 7966 { 7967 struct rtw89_hw_scan_info *scan_info = &rtwdev->scan_info; 7968 struct rtw89_wait_info *wait = &rtwdev->mac.fw_ofld_wait; 7969 struct rtw89_h2c_chinfo_elem *elem; 7970 struct rtw89_mac_chinfo_ax *ch_info; 7971 struct rtw89_h2c_chinfo *h2c; 7972 struct sk_buff *skb; 7973 unsigned int cond; 7974 int skb_len; 7975 int ret; 7976 7977 static_assert(sizeof(*elem) == RTW89_MAC_CHINFO_SIZE); 7978 7979 skb_len = struct_size(h2c, elem, ch_num); 7980 skb = rtw89_fw_h2c_alloc_skb_with_hdr(rtwdev, skb_len); 7981 if (!skb) { 7982 rtw89_err(rtwdev, "failed to alloc skb for h2c scan list\n"); 7983 return -ENOMEM; 7984 } 7985 skb_put(skb, sizeof(*h2c)); 7986 h2c = (struct rtw89_h2c_chinfo *)skb->data; 7987 7988 h2c->ch_num = ch_num; 7989 h2c->elem_size = sizeof(*elem) / 4; /* in unit of 4 bytes */ 7990 7991 list_for_each_entry(ch_info, chan_list, list) { 7992 elem = (struct rtw89_h2c_chinfo_elem *)skb_put(skb, sizeof(*elem)); 7993 7994 elem->w0 = le32_encode_bits(ch_info->period, RTW89_H2C_CHINFO_W0_PERIOD) | 7995 le32_encode_bits(ch_info->dwell_time, RTW89_H2C_CHINFO_W0_DWELL) | 7996 le32_encode_bits(ch_info->central_ch, RTW89_H2C_CHINFO_W0_CENTER_CH) | 7997 le32_encode_bits(ch_info->pri_ch, RTW89_H2C_CHINFO_W0_PRI_CH); 7998 7999 elem->w1 = le32_encode_bits(ch_info->bw, RTW89_H2C_CHINFO_W1_BW) | 8000 le32_encode_bits(ch_info->notify_action, RTW89_H2C_CHINFO_W1_ACTION) | 8001 le32_encode_bits(ch_info->num_pkt, RTW89_H2C_CHINFO_W1_NUM_PKT) | 8002 le32_encode_bits(ch_info->tx_pkt, RTW89_H2C_CHINFO_W1_TX) | 8003 le32_encode_bits(ch_info->pause_data, RTW89_H2C_CHINFO_W1_PAUSE_DATA) | 8004 le32_encode_bits(ch_info->ch_band, RTW89_H2C_CHINFO_W1_BAND) | 8005 le32_encode_bits(ch_info->probe_id, RTW89_H2C_CHINFO_W1_PKT_ID) | 8006 le32_encode_bits(ch_info->dfs_ch, RTW89_H2C_CHINFO_W1_DFS) | 8007 le32_encode_bits(ch_info->tx_null, RTW89_H2C_CHINFO_W1_TX_NULL) | 8008 le32_encode_bits(ch_info->rand_seq_num, RTW89_H2C_CHINFO_W1_RANDOM); 8009 8010 if (scan_info->extra_op.set) 8011 elem->w1 |= le32_encode_bits(ch_info->macid_tx, 8012 RTW89_H2C_CHINFO_W1_MACID_TX); 8013 8014 elem->w2 = le32_encode_bits(ch_info->pkt_id[0], RTW89_H2C_CHINFO_W2_PKT0) | 8015 le32_encode_bits(ch_info->pkt_id[1], RTW89_H2C_CHINFO_W2_PKT1) | 8016 le32_encode_bits(ch_info->pkt_id[2], RTW89_H2C_CHINFO_W2_PKT2) | 8017 le32_encode_bits(ch_info->pkt_id[3], RTW89_H2C_CHINFO_W2_PKT3); 8018 8019 elem->w3 = le32_encode_bits(ch_info->pkt_id[4], RTW89_H2C_CHINFO_W3_PKT4) | 8020 le32_encode_bits(ch_info->pkt_id[5], RTW89_H2C_CHINFO_W3_PKT5) | 8021 le32_encode_bits(ch_info->pkt_id[6], RTW89_H2C_CHINFO_W3_PKT6) | 8022 le32_encode_bits(ch_info->pkt_id[7], RTW89_H2C_CHINFO_W3_PKT7); 8023 } 8024 8025 rtw89_h2c_pkt_set_hdr(rtwdev, skb, FWCMD_TYPE_H2C, 8026 H2C_CAT_MAC, H2C_CL_MAC_FW_OFLD, 8027 H2C_FUNC_ADD_SCANOFLD_CH, 1, 1, skb_len); 8028 8029 cond = RTW89_SCANOFLD_WAIT_COND_ADD_CH; 8030 8031 ret = rtw89_h2c_tx_and_wait(rtwdev, skb, wait, cond); 8032 if (ret) { 8033 rtw89_debug(rtwdev, RTW89_DBG_FW, "failed to add scan ofld ch\n"); 8034 return ret; 8035 } 8036 8037 return 0; 8038 } 8039 8040 static 8041 int rtw89_fw_h2c_scan_list_offload_be(struct rtw89_dev *rtwdev, int ch_num, 8042 struct list_head *chan_list, 8043 struct rtw89_vif_link *rtwvif_link) 8044 { 8045 struct rtw89_wait_info *wait = &rtwdev->mac.fw_ofld_wait; 8046 struct rtw89_h2c_chinfo_elem_be *elem; 8047 struct rtw89_mac_chinfo_be *ch_info; 8048 struct rtw89_h2c_chinfo_be *h2c; 8049 u8 elem_size = sizeof(*elem); 8050 bool wildcard_by_drv; 8051 struct sk_buff *skb; 8052 unsigned int cond; 8053 u8 ver = U8_MAX; 8054 int used_len; 8055 int skb_len; 8056 int ret; 8057 8058 static_assert(sizeof(*elem) == RTW89_MAC_CHINFO_SIZE_BE); 8059 8060 skb_len = struct_size(h2c, elem, ch_num); 8061 used_len = skb_len; 8062 skb = rtw89_fw_h2c_alloc_skb_with_hdr(rtwdev, skb_len); 8063 if (!skb) { 8064 rtw89_err(rtwdev, "failed to alloc skb for h2c scan list\n"); 8065 return -ENOMEM; 8066 } 8067 8068 if (RTW89_CHK_FW_FEATURE(CH_INFO_BE_V0, &rtwdev->fw)) { 8069 ver = 0; 8070 elem_size = offsetofend(typeof(*elem), w7); 8071 used_len = sizeof(*h2c) + elem_size * ch_num; 8072 } else if (RTW89_CHK_FW_FEATURE(CH_INFO_BE_V1, &rtwdev->fw)) { 8073 ver = 1; 8074 elem_size = offsetofend(typeof(*elem), w7); 8075 used_len = sizeof(*h2c) + elem_size * ch_num; 8076 } 8077 8078 wildcard_by_drv = !(RTW89_CHK_FW_FEATURE(SCAN_OFFLOAD_BE_V0, &rtwdev->fw) || 8079 RTW89_CHK_FW_FEATURE(SCAN_OFFLOAD_BE_V1, &rtwdev->fw) || 8080 RTW89_CHK_FW_FEATURE(SCAN_OFFLOAD_BE_V2, &rtwdev->fw)); 8081 8082 skb_put(skb, sizeof(*h2c)); 8083 h2c = (struct rtw89_h2c_chinfo_be *)skb->data; 8084 8085 h2c->ch_num = ch_num; 8086 h2c->elem_size = elem_size / 4; /* in unit of 4 bytes */ 8087 h2c->arg = u8_encode_bits(rtwvif_link->mac_idx, 8088 RTW89_H2C_CHINFO_ARG_MAC_IDX_MASK); 8089 8090 list_for_each_entry(ch_info, chan_list, list) { 8091 bool with_probe_id = ch_info->probe_id != RTW89_SCANOFLD_PKT_NONE; 8092 8093 elem = (struct rtw89_h2c_chinfo_elem_be *)skb_put(skb, elem_size); 8094 8095 elem->w0 = le32_encode_bits(ch_info->dwell_time, RTW89_H2C_CHINFO_BE_W0_DWELL) | 8096 le32_encode_bits(ch_info->central_ch, 8097 RTW89_H2C_CHINFO_BE_W0_CENTER_CH) | 8098 le32_encode_bits(ch_info->pri_ch, RTW89_H2C_CHINFO_BE_W0_PRI_CH); 8099 8100 elem->w1 = le32_encode_bits(ch_info->bw, RTW89_H2C_CHINFO_BE_W1_BW) | 8101 le32_encode_bits(ch_info->ch_band, RTW89_H2C_CHINFO_BE_W1_CH_BAND) | 8102 le32_encode_bits(ch_info->dfs_ch, RTW89_H2C_CHINFO_BE_W1_DFS) | 8103 le32_encode_bits(ch_info->pause_data, 8104 RTW89_H2C_CHINFO_BE_W1_PAUSE_DATA) | 8105 le32_encode_bits(ch_info->tx_null, RTW89_H2C_CHINFO_BE_W1_TX_NULL) | 8106 le32_encode_bits(ch_info->rand_seq_num, 8107 RTW89_H2C_CHINFO_BE_W1_RANDOM) | 8108 le32_encode_bits(ch_info->notify_action, 8109 RTW89_H2C_CHINFO_BE_W1_NOTIFY) | 8110 le32_encode_bits(wildcard_by_drv || with_probe_id, 8111 RTW89_H2C_CHINFO_BE_W1_PROBE) | 8112 le32_encode_bits(ch_info->leave_crit, 8113 RTW89_H2C_CHINFO_BE_W1_EARLY_LEAVE_CRIT) | 8114 le32_encode_bits(ch_info->chkpt_timer, 8115 RTW89_H2C_CHINFO_BE_W1_CHKPT_TIMER); 8116 8117 elem->w2 = le32_encode_bits(ch_info->leave_time, 8118 RTW89_H2C_CHINFO_BE_W2_EARLY_LEAVE_TIME) | 8119 le32_encode_bits(ch_info->leave_th, 8120 RTW89_H2C_CHINFO_BE_W2_EARLY_LEAVE_TH) | 8121 le32_encode_bits(ch_info->tx_pkt_ctrl, 8122 RTW89_H2C_CHINFO_BE_W2_TX_PKT_CTRL); 8123 8124 elem->w3 = le32_encode_bits(ch_info->pkt_id[0], RTW89_H2C_CHINFO_BE_W3_PKT0) | 8125 le32_encode_bits(ch_info->pkt_id[1], RTW89_H2C_CHINFO_BE_W3_PKT1) | 8126 le32_encode_bits(ch_info->pkt_id[2], RTW89_H2C_CHINFO_BE_W3_PKT2) | 8127 le32_encode_bits(ch_info->pkt_id[3], RTW89_H2C_CHINFO_BE_W3_PKT3); 8128 8129 elem->w4 = le32_encode_bits(ch_info->pkt_id[4], RTW89_H2C_CHINFO_BE_W4_PKT4) | 8130 le32_encode_bits(ch_info->pkt_id[5], RTW89_H2C_CHINFO_BE_W4_PKT5) | 8131 le32_encode_bits(ch_info->pkt_id[6], RTW89_H2C_CHINFO_BE_W4_PKT6) | 8132 le32_encode_bits(ch_info->pkt_id[7], RTW89_H2C_CHINFO_BE_W4_PKT7); 8133 8134 elem->w5 = le32_encode_bits(ch_info->sw_def, RTW89_H2C_CHINFO_BE_W5_SW_DEF) | 8135 le32_encode_bits(ch_info->fw_probe0_ssids, 8136 RTW89_H2C_CHINFO_BE_W5_FW_PROBE0_SSIDS); 8137 8138 elem->w6 = le32_encode_bits(ch_info->fw_probe0_shortssids, 8139 RTW89_H2C_CHINFO_BE_W6_FW_PROBE0_SHORTSSIDS) | 8140 le32_encode_bits(ch_info->fw_probe0_bssids, 8141 RTW89_H2C_CHINFO_BE_W6_FW_PROBE0_BSSIDS); 8142 if (ver == 0) 8143 elem->w0 |= 8144 le32_encode_bits(ch_info->period, RTW89_H2C_CHINFO_BE_W0_PERIOD); 8145 else 8146 elem->w7 = le32_encode_bits(ch_info->period, 8147 RTW89_H2C_CHINFO_BE_W7_PERIOD_V1); 8148 8149 if (ver < 2) 8150 continue; 8151 8152 elem->w8 = 0; 8153 } 8154 8155 rtw89_h2c_pkt_set_hdr(rtwdev, skb, FWCMD_TYPE_H2C, 8156 H2C_CAT_MAC, H2C_CL_MAC_FW_OFLD, 8157 H2C_FUNC_ADD_SCANOFLD_CH, 1, 1, used_len); 8158 8159 cond = RTW89_SCANOFLD_WAIT_COND_ADD_CH; 8160 8161 ret = rtw89_h2c_tx_and_wait(rtwdev, skb, wait, cond); 8162 if (ret) { 8163 rtw89_debug(rtwdev, RTW89_DBG_FW, "failed to add scan ofld ch\n"); 8164 return ret; 8165 } 8166 8167 return 0; 8168 } 8169 8170 int rtw89_fw_h2c_scan_offload_ax(struct rtw89_dev *rtwdev, 8171 struct rtw89_scan_option *option, 8172 struct rtw89_vif_link *rtwvif_link, 8173 bool wowlan) 8174 { 8175 struct rtw89_hw_scan_info *scan_info = &rtwdev->scan_info; 8176 struct rtw89_wait_info *wait = &rtwdev->mac.fw_ofld_wait; 8177 struct rtw89_chan *op = &rtwdev->scan_info.op_chan; 8178 enum rtw89_scan_mode scan_mode = RTW89_SCAN_IMMEDIATE; 8179 struct rtw89_h2c_scanofld *h2c; 8180 u32 len = sizeof(*h2c); 8181 struct sk_buff *skb; 8182 unsigned int cond; 8183 u64 tsf = 0; 8184 int ret; 8185 8186 skb = rtw89_fw_h2c_alloc_skb_with_hdr(rtwdev, len); 8187 if (!skb) { 8188 rtw89_err(rtwdev, "failed to alloc skb for h2c scan offload\n"); 8189 return -ENOMEM; 8190 } 8191 skb_put(skb, len); 8192 h2c = (struct rtw89_h2c_scanofld *)skb->data; 8193 8194 if (option->delay) { 8195 ret = rtw89_mac_port_get_tsf(rtwdev, rtwvif_link, &tsf); 8196 if (ret) { 8197 rtw89_warn(rtwdev, "NLO failed to get port tsf: %d\n", ret); 8198 scan_mode = RTW89_SCAN_IMMEDIATE; 8199 } else { 8200 scan_mode = RTW89_SCAN_DELAY; 8201 tsf += (u64)option->delay * 1000; 8202 } 8203 } 8204 8205 h2c->w0 = le32_encode_bits(rtwvif_link->mac_id, RTW89_H2C_SCANOFLD_W0_MACID) | 8206 le32_encode_bits(rtwvif_link->port, RTW89_H2C_SCANOFLD_W0_PORT_ID) | 8207 le32_encode_bits(rtwvif_link->mac_idx, RTW89_H2C_SCANOFLD_W0_BAND) | 8208 le32_encode_bits(option->enable, RTW89_H2C_SCANOFLD_W0_OPERATION); 8209 8210 h2c->w1 = le32_encode_bits(true, RTW89_H2C_SCANOFLD_W1_NOTIFY_END) | 8211 le32_encode_bits(option->target_ch_mode, 8212 RTW89_H2C_SCANOFLD_W1_TARGET_CH_MODE) | 8213 le32_encode_bits(scan_mode, RTW89_H2C_SCANOFLD_W1_START_MODE) | 8214 le32_encode_bits(option->repeat, RTW89_H2C_SCANOFLD_W1_SCAN_TYPE); 8215 8216 h2c->w2 = le32_encode_bits(option->norm_pd, RTW89_H2C_SCANOFLD_W2_NORM_PD) | 8217 le32_encode_bits(option->slow_pd, RTW89_H2C_SCANOFLD_W2_SLOW_PD); 8218 8219 if (option->target_ch_mode) { 8220 h2c->w1 |= le32_encode_bits(op->band_width, 8221 RTW89_H2C_SCANOFLD_W1_TARGET_CH_BW) | 8222 le32_encode_bits(op->primary_channel, 8223 RTW89_H2C_SCANOFLD_W1_TARGET_PRI_CH) | 8224 le32_encode_bits(op->channel, 8225 RTW89_H2C_SCANOFLD_W1_TARGET_CENTRAL_CH); 8226 h2c->w0 |= le32_encode_bits(op->band_type, 8227 RTW89_H2C_SCANOFLD_W0_TARGET_CH_BAND); 8228 } 8229 8230 h2c->tsf_high = le32_encode_bits(upper_32_bits(tsf), 8231 RTW89_H2C_SCANOFLD_W3_TSF_HIGH); 8232 h2c->tsf_low = le32_encode_bits(lower_32_bits(tsf), 8233 RTW89_H2C_SCANOFLD_W4_TSF_LOW); 8234 8235 if (scan_info->extra_op.set) 8236 h2c->w6 = le32_encode_bits(scan_info->extra_op.macid, 8237 RTW89_H2C_SCANOFLD_W6_SECOND_MACID); 8238 8239 rtw89_h2c_pkt_set_hdr(rtwdev, skb, FWCMD_TYPE_H2C, 8240 H2C_CAT_MAC, H2C_CL_MAC_FW_OFLD, 8241 H2C_FUNC_SCANOFLD, 1, 1, 8242 len); 8243 8244 if (option->enable) 8245 cond = RTW89_SCANOFLD_WAIT_COND_START; 8246 else 8247 cond = RTW89_SCANOFLD_WAIT_COND_STOP; 8248 8249 ret = rtw89_h2c_tx_and_wait(rtwdev, skb, wait, cond); 8250 if (ret) { 8251 rtw89_debug(rtwdev, RTW89_DBG_FW, "failed to scan ofld\n"); 8252 return ret; 8253 } 8254 8255 return 0; 8256 } 8257 8258 static void rtw89_scan_get_6g_disabled_chan(struct rtw89_dev *rtwdev, 8259 struct rtw89_scan_option *option) 8260 { 8261 struct ieee80211_supported_band *sband; 8262 struct ieee80211_channel *chan; 8263 u8 i, idx; 8264 8265 sband = rtwdev->hw->wiphy->bands[NL80211_BAND_6GHZ]; 8266 if (!sband) { 8267 option->prohib_chan = U64_MAX; 8268 return; 8269 } 8270 8271 for (i = 0; i < sband->n_channels; i++) { 8272 chan = &sband->channels[i]; 8273 if (chan->flags & IEEE80211_CHAN_DISABLED) { 8274 idx = (chan->hw_value - 1) / 4; 8275 option->prohib_chan |= BIT(idx); 8276 } 8277 } 8278 } 8279 8280 void rtw89_hw_scan_calc_req_ssid(struct rtw89_dev *rtwdev, 8281 struct rtw89_vif_link *rtwvif_link, bool wowlan) 8282 { 8283 struct rtw89_hw_scan_info *scan_info = &rtwdev->scan_info; 8284 struct rtw89_vif *rtwvif = rtwvif_link->rtwvif; 8285 struct cfg80211_scan_request *req = rtwvif->scan_req; 8286 struct rtw89_wow_param *rtw_wow = &rtwdev->wow; 8287 struct cfg80211_sched_scan_request *nd_config; 8288 struct cfg80211_ssid *s; 8289 u16 sum = 0, n_ssids; 8290 int i, num = 0; 8291 8292 nd_config = rtw_wow->nd_config; 8293 n_ssids = wowlan ? nd_config->n_match_sets : req->n_ssids; 8294 8295 for (i = 0; i < n_ssids; i++) { 8296 s = wowlan ? &nd_config->match_sets[i].ssid : &req->ssids[i]; 8297 if (s->ssid_len == 0) 8298 continue; 8299 8300 num++; 8301 sum += s->ssid_len + 1; 8302 } 8303 8304 scan_info->n_ssids = num; 8305 scan_info->ssid_total_len = sum; 8306 } 8307 8308 int rtw89_fw_h2c_scan_offload_be(struct rtw89_dev *rtwdev, 8309 struct rtw89_scan_option *option, 8310 struct rtw89_vif_link *rtwvif_link, 8311 bool wowlan) 8312 { 8313 struct rtw89_vif *rtwvif = rtwvif_link->rtwvif; 8314 struct rtw89_hw_scan_info *scan_info = &rtwdev->scan_info; 8315 const struct rtw89_hw_scan_extra_op *ext = &scan_info->extra_op; 8316 struct rtw89_wait_info *wait = &rtwdev->mac.fw_ofld_wait; 8317 struct cfg80211_scan_request *req = rtwvif->scan_req; 8318 struct rtw89_h2c_scanofld_be_macc_role *macc_role; 8319 struct rtw89_hw_scan_extra_op scan_op[2] = {}; 8320 struct rtw89_chan *op = &scan_info->op_chan; 8321 struct rtw89_h2c_scanofld_be_opch *opch; 8322 struct rtw89_h2c_scanofld_be *h2c; 8323 struct ieee80211_vif *vif; 8324 struct sk_buff *skb; 8325 u8 macc_role_size = sizeof(*macc_role) * option->num_macc_role; 8326 u8 opch_size = sizeof(*opch) * option->num_opch; 8327 struct rtw89_wow_param *rtw_wow = &rtwdev->wow; 8328 struct cfg80211_sched_scan_request *nd_config; 8329 u8 *probe_id = scan_info->wildcard_pkt_id; 8330 enum rtw89_scan_be_opmode opmode; 8331 u8 scan_offload_ver = U8_MAX; 8332 u8 cfg_len = sizeof(*h2c); 8333 struct cfg80211_ssid *s; 8334 unsigned int cond; 8335 u8 ver = U8_MAX; 8336 u8 n_ssids = 0; 8337 u8 policy_val; 8338 void *ptr; 8339 u8 txnull; 8340 u8 txbcn; 8341 int ret; 8342 u32 len; 8343 u8 i; 8344 8345 if (option->num_opch > RTW89_MAX_OP_NUM_BE) { 8346 rtw89_err(rtwdev, "num of scan OP chan %d over limit\n", option->num_opch); 8347 return -ENOENT; 8348 } 8349 8350 rtw89_scan_get_6g_disabled_chan(rtwdev, option); 8351 8352 if (RTW89_CHK_FW_FEATURE(SCAN_OFFLOAD_BE_V0, &rtwdev->fw)) { 8353 cfg_len = offsetofend(typeof(*h2c), w8); 8354 scan_offload_ver = 0; 8355 } else if (RTW89_CHK_FW_FEATURE(SCAN_OFFLOAD_BE_V1, &rtwdev->fw)) { 8356 cfg_len = offsetofend(typeof(*h2c), w9); 8357 scan_offload_ver = 1; 8358 } else if (RTW89_CHK_FW_FEATURE(SCAN_OFFLOAD_BE_V2, &rtwdev->fw)) { 8359 scan_offload_ver = 2; 8360 } 8361 8362 len = cfg_len + macc_role_size + opch_size; 8363 if (scan_offload_ver > 2) 8364 len += scan_info->ssid_total_len; 8365 8366 skb = rtw89_fw_h2c_alloc_skb_with_hdr(rtwdev, len); 8367 if (!skb) { 8368 rtw89_err(rtwdev, "failed to alloc skb for h2c scan offload\n"); 8369 return -ENOMEM; 8370 } 8371 8372 skb_put(skb, len); 8373 h2c = (struct rtw89_h2c_scanofld_be *)skb->data; 8374 ptr = skb->data; 8375 8376 if (RTW89_CHK_FW_FEATURE(CH_INFO_BE_V0, &rtwdev->fw)) 8377 ver = 0; 8378 else if (RTW89_CHK_FW_FEATURE(CH_INFO_BE_V1, &rtwdev->fw)) 8379 ver = 1; 8380 8381 h2c->w0 = le32_encode_bits(option->operation, RTW89_H2C_SCANOFLD_BE_W0_OP) | 8382 le32_encode_bits(option->scan_mode, 8383 RTW89_H2C_SCANOFLD_BE_W0_SCAN_MODE) | 8384 le32_encode_bits(option->repeat, RTW89_H2C_SCANOFLD_BE_W0_REPEAT) | 8385 le32_encode_bits(true, RTW89_H2C_SCANOFLD_BE_W0_NOTIFY_END) | 8386 le32_encode_bits(true, RTW89_H2C_SCANOFLD_BE_W0_LEARN_CH) | 8387 le32_encode_bits(rtwvif_link->mac_id, RTW89_H2C_SCANOFLD_BE_W0_MACID) | 8388 le32_encode_bits(rtwvif_link->port, RTW89_H2C_SCANOFLD_BE_W0_PORT) | 8389 le32_encode_bits(option->band, RTW89_H2C_SCANOFLD_BE_W0_BAND); 8390 8391 h2c->w1 = le32_encode_bits(option->num_macc_role, RTW89_H2C_SCANOFLD_BE_W1_NUM_MACC_ROLE) | 8392 le32_encode_bits(option->num_opch, RTW89_H2C_SCANOFLD_BE_W1_NUM_OP) | 8393 le32_encode_bits(option->norm_pd, RTW89_H2C_SCANOFLD_BE_W1_NORM_PD); 8394 8395 h2c->w2 = le32_encode_bits(option->slow_pd, RTW89_H2C_SCANOFLD_BE_W2_SLOW_PD) | 8396 le32_encode_bits(option->norm_cy, RTW89_H2C_SCANOFLD_BE_W2_NORM_CY) | 8397 le32_encode_bits(option->opch_end, RTW89_H2C_SCANOFLD_BE_W2_OPCH_END); 8398 8399 if (scan_offload_ver > 2) 8400 n_ssids = scan_info->n_ssids; 8401 8402 h2c->w3 = le32_encode_bits(n_ssids, RTW89_H2C_SCANOFLD_BE_W3_NUM_SSID) | 8403 le32_encode_bits(0, RTW89_H2C_SCANOFLD_BE_W3_NUM_SHORT_SSID) | 8404 le32_encode_bits(0, RTW89_H2C_SCANOFLD_BE_W3_NUM_BSSID) | 8405 le32_encode_bits(probe_id[NL80211_BAND_2GHZ], RTW89_H2C_SCANOFLD_BE_W3_PROBEID); 8406 8407 h2c->w4 = le32_encode_bits(probe_id[NL80211_BAND_5GHZ], 8408 RTW89_H2C_SCANOFLD_BE_W4_PROBE_5G) | 8409 le32_encode_bits(probe_id[NL80211_BAND_6GHZ], 8410 RTW89_H2C_SCANOFLD_BE_W4_PROBE_6G) | 8411 le32_encode_bits(option->delay / 1000, RTW89_H2C_SCANOFLD_BE_W4_DELAY_START); 8412 8413 h2c->w5 = le32_encode_bits(option->mlo_mode, RTW89_H2C_SCANOFLD_BE_W5_MLO_MODE); 8414 8415 h2c->w6 = le32_encode_bits(option->prohib_chan, 8416 RTW89_H2C_SCANOFLD_BE_W6_CHAN_PROHIB_LOW); 8417 h2c->w7 = le32_encode_bits(option->prohib_chan >> 32, 8418 RTW89_H2C_SCANOFLD_BE_W7_CHAN_PROHIB_HIGH); 8419 if (!wowlan && req->no_cck) { 8420 h2c->w0 |= le32_encode_bits(true, RTW89_H2C_SCANOFLD_BE_W0_PROBE_WITH_RATE); 8421 h2c->w8 = le32_encode_bits(RTW89_HW_RATE_OFDM6, 8422 RTW89_H2C_SCANOFLD_BE_W8_PROBE_RATE_2GHZ) | 8423 le32_encode_bits(RTW89_HW_RATE_OFDM6, 8424 RTW89_H2C_SCANOFLD_BE_W8_PROBE_RATE_5GHZ) | 8425 le32_encode_bits(RTW89_HW_RATE_OFDM6, 8426 RTW89_H2C_SCANOFLD_BE_W8_PROBE_RATE_6GHZ); 8427 } 8428 8429 if (scan_offload_ver == 0) 8430 goto flex_member; 8431 8432 h2c->w9 = le32_encode_bits(cfg_len / sizeof(h2c->w0), 8433 RTW89_H2C_SCANOFLD_BE_W9_SIZE_CFG) | 8434 le32_encode_bits(sizeof(*macc_role) / sizeof(macc_role->w0), 8435 RTW89_H2C_SCANOFLD_BE_W9_SIZE_MACC) | 8436 le32_encode_bits(sizeof(*opch) / sizeof(opch->w0), 8437 RTW89_H2C_SCANOFLD_BE_W9_SIZE_OP); 8438 8439 flex_member: 8440 ptr += cfg_len; 8441 8442 for (i = 0; i < option->num_macc_role; i++) { 8443 macc_role = ptr; 8444 macc_role->w0 = 8445 le32_encode_bits(0, RTW89_H2C_SCANOFLD_BE_MACC_ROLE_W0_BAND) | 8446 le32_encode_bits(0, RTW89_H2C_SCANOFLD_BE_MACC_ROLE_W0_PORT) | 8447 le32_encode_bits(0, RTW89_H2C_SCANOFLD_BE_MACC_ROLE_W0_MACID) | 8448 le32_encode_bits(0, RTW89_H2C_SCANOFLD_BE_MACC_ROLE_W0_OPCH_END); 8449 ptr += sizeof(*macc_role); 8450 } 8451 8452 for (i = 0; i < option->num_opch; i++) { 8453 struct rtw89_vif_link *rtwvif_link_op; 8454 bool is_ap; 8455 8456 switch (i) { 8457 case 0: 8458 scan_op[0].macid = rtwvif_link->mac_id; 8459 scan_op[0].port = rtwvif_link->port; 8460 scan_op[0].chan = *op; 8461 rtwvif_link_op = rtwvif_link; 8462 break; 8463 case 1: 8464 scan_op[1] = *ext; 8465 rtwvif_link_op = ext->rtwvif_link; 8466 break; 8467 } 8468 8469 vif = rtwvif_to_vif(rtwvif_link_op->rtwvif); 8470 is_ap = vif->type == NL80211_IFTYPE_AP; 8471 txnull = !is_zero_ether_addr(rtwvif_link_op->bssid) && 8472 vif->type != NL80211_IFTYPE_AP; 8473 opmode = is_ap ? RTW89_SCAN_OPMODE_TBTT : RTW89_SCAN_OPMODE_INTV; 8474 policy_val = is_ap ? 2 : RTW89_OFF_CHAN_TIME / 10; 8475 txbcn = is_ap ? 1 : 0; 8476 8477 opch = ptr; 8478 opch->w0 = le32_encode_bits(scan_op[i].macid, 8479 RTW89_H2C_SCANOFLD_BE_OPCH_W0_MACID) | 8480 le32_encode_bits(option->band, 8481 RTW89_H2C_SCANOFLD_BE_OPCH_W0_BAND) | 8482 le32_encode_bits(scan_op[i].port, 8483 RTW89_H2C_SCANOFLD_BE_OPCH_W0_PORT) | 8484 le32_encode_bits(opmode, 8485 RTW89_H2C_SCANOFLD_BE_OPCH_W0_POLICY) | 8486 le32_encode_bits(txnull, 8487 RTW89_H2C_SCANOFLD_BE_OPCH_W0_TXNULL) | 8488 le32_encode_bits(policy_val, 8489 RTW89_H2C_SCANOFLD_BE_OPCH_W0_POLICY_VAL); 8490 8491 opch->w1 = le32_encode_bits(scan_op[i].chan.band_type, 8492 RTW89_H2C_SCANOFLD_BE_OPCH_W1_CH_BAND) | 8493 le32_encode_bits(scan_op[i].chan.band_width, 8494 RTW89_H2C_SCANOFLD_BE_OPCH_W1_BW) | 8495 le32_encode_bits(0x3, 8496 RTW89_H2C_SCANOFLD_BE_OPCH_W1_NOTIFY) | 8497 le32_encode_bits(scan_op[i].chan.primary_channel, 8498 RTW89_H2C_SCANOFLD_BE_OPCH_W1_PRI_CH) | 8499 le32_encode_bits(scan_op[i].chan.channel, 8500 RTW89_H2C_SCANOFLD_BE_OPCH_W1_CENTRAL_CH); 8501 8502 opch->w2 = le32_encode_bits(0, 8503 RTW89_H2C_SCANOFLD_BE_OPCH_W2_PKTS_CTRL) | 8504 le32_encode_bits(0, 8505 RTW89_H2C_SCANOFLD_BE_OPCH_W2_SW_DEF) | 8506 le32_encode_bits(rtw89_is_mlo_1_1(rtwdev) ? 1 : 2, 8507 RTW89_H2C_SCANOFLD_BE_OPCH_W2_SS) | 8508 le32_encode_bits(txbcn, 8509 RTW89_H2C_SCANOFLD_BE_OPCH_W2_TXBCN); 8510 8511 opch->w3 = le32_encode_bits(RTW89_SCANOFLD_PKT_NONE, 8512 RTW89_H2C_SCANOFLD_BE_OPCH_W3_PKT0) | 8513 le32_encode_bits(RTW89_SCANOFLD_PKT_NONE, 8514 RTW89_H2C_SCANOFLD_BE_OPCH_W3_PKT1) | 8515 le32_encode_bits(RTW89_SCANOFLD_PKT_NONE, 8516 RTW89_H2C_SCANOFLD_BE_OPCH_W3_PKT2) | 8517 le32_encode_bits(RTW89_SCANOFLD_PKT_NONE, 8518 RTW89_H2C_SCANOFLD_BE_OPCH_W3_PKT3); 8519 8520 if (ver == 0) 8521 opch->w1 |= le32_encode_bits(RTW89_CHANNEL_TIME, 8522 RTW89_H2C_SCANOFLD_BE_OPCH_W1_DURATION); 8523 else 8524 opch->w4 = le32_encode_bits(RTW89_CHANNEL_TIME, 8525 RTW89_H2C_SCANOFLD_BE_OPCH_W4_DURATION_V1); 8526 ptr += sizeof(*opch); 8527 } 8528 8529 if (scan_offload_ver <= 2) 8530 goto set_hdr; 8531 8532 nd_config = rtw_wow->nd_config; 8533 n_ssids = wowlan ? nd_config->n_match_sets : req->n_ssids; 8534 8535 for (i = 0; i < n_ssids; i++) { 8536 s = wowlan ? &nd_config->match_sets[i].ssid : &req->ssids[i]; 8537 if (s->ssid_len == 0) 8538 continue; 8539 8540 memcpy(ptr, &s->ssid_len, 1); 8541 ptr++; 8542 memcpy(ptr, s->ssid, s->ssid_len); 8543 ptr += s->ssid_len; 8544 } 8545 8546 set_hdr: 8547 rtw89_h2c_pkt_set_hdr(rtwdev, skb, FWCMD_TYPE_H2C, 8548 H2C_CAT_MAC, H2C_CL_MAC_FW_OFLD, 8549 H2C_FUNC_SCANOFLD_BE, 1, 1, 8550 len); 8551 8552 if (option->enable) 8553 cond = RTW89_SCANOFLD_BE_WAIT_COND_START; 8554 else 8555 cond = RTW89_SCANOFLD_BE_WAIT_COND_STOP; 8556 8557 ret = rtw89_h2c_tx_and_wait(rtwdev, skb, wait, cond); 8558 if (ret) { 8559 rtw89_debug(rtwdev, RTW89_DBG_FW, "failed to scan be ofld\n"); 8560 return ret; 8561 } 8562 8563 return 0; 8564 } 8565 8566 int rtw89_fw_h2c_trx_protect(struct rtw89_dev *rtwdev, 8567 enum rtw89_phy_idx phy_idx, bool enable) 8568 { 8569 struct rtw89_wait_info *wait = &rtwdev->mac.fw_ofld_wait; 8570 const struct rtw89_chip_info *chip = rtwdev->chip; 8571 struct rtw89_h2c_trx_protect *h2c; 8572 u32 len = sizeof(*h2c); 8573 struct sk_buff *skb; 8574 int ret; 8575 8576 if (chip->chip_gen != RTW89_CHIP_BE) 8577 return 0; 8578 8579 skb = rtw89_fw_h2c_alloc_skb_with_hdr(rtwdev, len); 8580 if (!skb) { 8581 rtw89_err(rtwdev, "failed to alloc skb for h2c trx protect\n"); 8582 return -ENOMEM; 8583 } 8584 8585 skb_put(skb, len); 8586 h2c = (struct rtw89_h2c_trx_protect *)skb->data; 8587 8588 h2c->c0 = le32_encode_bits(BIT(phy_idx), RTW89_H2C_TRX_PROTECT_C0_BAND_BITMAP) | 8589 le32_encode_bits(0, RTW89_H2C_TRX_PROTECT_C0_OP_MODE); 8590 h2c->c1 = le32_encode_bits(enable, RTW89_H2C_TRX_PROTECT_C1_RX_IN) | 8591 le32_encode_bits(enable, RTW89_H2C_TRX_PROTECT_C1_PPDU_STS) | 8592 le32_encode_bits(1, RTW89_H2C_TRX_PROTECT_C1_MSK_RX_IN) | 8593 le32_encode_bits(1, RTW89_H2C_TRX_PROTECT_C1_MSK_PPDU_STS); 8594 h2c->w0 = le32_encode_bits(enable, RTW89_H2C_TRX_PROTECT_W0_TXEN_BE0) | 8595 le32_encode_bits(enable, RTW89_H2C_TRX_PROTECT_W0_TXEN_BK0) | 8596 le32_encode_bits(enable, RTW89_H2C_TRX_PROTECT_W0_TXEN_VI0) | 8597 le32_encode_bits(enable, RTW89_H2C_TRX_PROTECT_W0_TXEN_VO0) | 8598 le32_encode_bits(enable, RTW89_H2C_TRX_PROTECT_W0_TXEN_BE1) | 8599 le32_encode_bits(enable, RTW89_H2C_TRX_PROTECT_W0_TXEN_BK1) | 8600 le32_encode_bits(enable, RTW89_H2C_TRX_PROTECT_W0_TXEN_VI1) | 8601 le32_encode_bits(enable, RTW89_H2C_TRX_PROTECT_W0_TXEN_VO1) | 8602 le32_encode_bits(enable, RTW89_H2C_TRX_PROTECT_W0_TXEN_MG0) | 8603 le32_encode_bits(enable, RTW89_H2C_TRX_PROTECT_W0_TXEN_MG1) | 8604 le32_encode_bits(enable, RTW89_H2C_TRX_PROTECT_W0_TXEN_MG2) | 8605 le32_encode_bits(enable, RTW89_H2C_TRX_PROTECT_W0_TXEN_HI) | 8606 le32_encode_bits(enable, RTW89_H2C_TRX_PROTECT_W0_TXEN_BCN) | 8607 le32_encode_bits(enable, RTW89_H2C_TRX_PROTECT_W0_TXEN_UL) | 8608 le32_encode_bits(enable, RTW89_H2C_TRX_PROTECT_W0_TXEN_TWT0) | 8609 le32_encode_bits(enable, RTW89_H2C_TRX_PROTECT_W0_TXEN_TWT1) | 8610 le32_encode_bits(enable, RTW89_H2C_TRX_PROTECT_W0_TXEN_TWT2) | 8611 le32_encode_bits(enable, RTW89_H2C_TRX_PROTECT_W0_TXEN_TWT3) | 8612 le32_encode_bits(enable, RTW89_H2C_TRX_PROTECT_W0_TXEN_SPEQ0) | 8613 le32_encode_bits(enable, RTW89_H2C_TRX_PROTECT_W0_TXEN_SPEQ1); 8614 h2c->m0 = cpu_to_le32(RTW89_H2C_TRX_PROTECT_W0_TXEN_BE0 | 8615 RTW89_H2C_TRX_PROTECT_W0_TXEN_BK0 | 8616 RTW89_H2C_TRX_PROTECT_W0_TXEN_VI0 | 8617 RTW89_H2C_TRX_PROTECT_W0_TXEN_VO0 | 8618 RTW89_H2C_TRX_PROTECT_W0_TXEN_BE1 | 8619 RTW89_H2C_TRX_PROTECT_W0_TXEN_BK1 | 8620 RTW89_H2C_TRX_PROTECT_W0_TXEN_VI1 | 8621 RTW89_H2C_TRX_PROTECT_W0_TXEN_VO1 | 8622 RTW89_H2C_TRX_PROTECT_W0_TXEN_MG0 | 8623 RTW89_H2C_TRX_PROTECT_W0_TXEN_MG1 | 8624 RTW89_H2C_TRX_PROTECT_W0_TXEN_MG2 | 8625 RTW89_H2C_TRX_PROTECT_W0_TXEN_HI | 8626 RTW89_H2C_TRX_PROTECT_W0_TXEN_BCN | 8627 RTW89_H2C_TRX_PROTECT_W0_TXEN_UL | 8628 RTW89_H2C_TRX_PROTECT_W0_TXEN_TWT0 | 8629 RTW89_H2C_TRX_PROTECT_W0_TXEN_TWT1 | 8630 RTW89_H2C_TRX_PROTECT_W0_TXEN_TWT2 | 8631 RTW89_H2C_TRX_PROTECT_W0_TXEN_TWT3 | 8632 RTW89_H2C_TRX_PROTECT_W0_TXEN_SPEQ0 | 8633 RTW89_H2C_TRX_PROTECT_W0_TXEN_SPEQ1); 8634 h2c->w1 = le32_encode_bits(enable, RTW89_H2C_TRX_PROTECT_W1_CHINFO_EN) | 8635 le32_encode_bits(enable, RTW89_H2C_TRX_PROTECT_W1_DFS_EN); 8636 h2c->m1 = cpu_to_le32(RTW89_H2C_TRX_PROTECT_W1_CHINFO_EN | 8637 RTW89_H2C_TRX_PROTECT_W1_DFS_EN); 8638 8639 rtw89_h2c_pkt_set_hdr(rtwdev, skb, FWCMD_TYPE_H2C, 8640 H2C_CAT_MAC, H2C_CL_MAC_FW_OFLD, 8641 H2C_FUNC_TRX_PROTECT, 0, 1, len); 8642 8643 ret = rtw89_h2c_tx_and_wait(rtwdev, skb, wait, 8644 RTW89_FW_OFLD_WAIT_COND_TRX_PROTECT); 8645 if (ret) { 8646 rtw89_debug(rtwdev, RTW89_DBG_FW, "failed to trx protect\n"); 8647 return ret; 8648 } 8649 8650 return 0; 8651 } 8652 8653 int rtw89_fw_h2c_rf_reg(struct rtw89_dev *rtwdev, 8654 struct rtw89_fw_h2c_rf_reg_info *info, 8655 u16 len, u8 page) 8656 { 8657 struct sk_buff *skb; 8658 u8 class = info->rf_path == RF_PATH_A ? 8659 H2C_CL_OUTSRC_RF_REG_A : H2C_CL_OUTSRC_RF_REG_B; 8660 int ret; 8661 8662 skb = rtw89_fw_h2c_alloc_skb_with_hdr(rtwdev, len); 8663 if (!skb) { 8664 rtw89_err(rtwdev, "failed to alloc skb for h2c rf reg\n"); 8665 return -ENOMEM; 8666 } 8667 skb_put_data(skb, info->rtw89_phy_config_rf_h2c[page], len); 8668 8669 rtw89_h2c_pkt_set_hdr(rtwdev, skb, FWCMD_TYPE_H2C, 8670 H2C_CAT_OUTSRC, class, page, 0, 0, 8671 len); 8672 8673 ret = rtw89_h2c_tx(rtwdev, skb, false); 8674 if (ret) { 8675 rtw89_err(rtwdev, "failed to send h2c\n"); 8676 goto fail; 8677 } 8678 8679 return 0; 8680 fail: 8681 dev_kfree_skb_any(skb); 8682 8683 return ret; 8684 } 8685 8686 int rtw89_fw_h2c_rf_ntfy_mcc(struct rtw89_dev *rtwdev) 8687 { 8688 struct rtw89_rfk_mcc_info_data *rfk_mcc = rtwdev->rfk_mcc.data; 8689 struct rtw89_fw_h2c_rf_get_mccch_v0 *mccch_v0; 8690 struct rtw89_fw_h2c_rf_get_mccch *mccch; 8691 u32 len = sizeof(*mccch); 8692 struct sk_buff *skb; 8693 u8 ver = U8_MAX; 8694 int ret; 8695 u8 idx; 8696 8697 if (RTW89_CHK_FW_FEATURE(RFK_NTFY_MCC_V0, &rtwdev->fw)) { 8698 len = sizeof(*mccch_v0); 8699 ver = 0; 8700 } 8701 8702 skb = rtw89_fw_h2c_alloc_skb_with_hdr(rtwdev, len); 8703 if (!skb) { 8704 rtw89_err(rtwdev, "failed to alloc skb for h2c cxdrv_ctrl\n"); 8705 return -ENOMEM; 8706 } 8707 skb_put(skb, len); 8708 8709 idx = rfk_mcc->table_idx; 8710 if (ver == 0) { 8711 mccch_v0 = (struct rtw89_fw_h2c_rf_get_mccch_v0 *)skb->data; 8712 mccch_v0->ch_0 = cpu_to_le32(rfk_mcc->ch[0]); 8713 mccch_v0->ch_1 = cpu_to_le32(rfk_mcc->ch[1]); 8714 mccch_v0->band_0 = cpu_to_le32(rfk_mcc->band[0]); 8715 mccch_v0->band_1 = cpu_to_le32(rfk_mcc->band[1]); 8716 mccch_v0->current_band_type = cpu_to_le32(rfk_mcc->band[idx]); 8717 mccch_v0->current_channel = cpu_to_le32(rfk_mcc->ch[idx]); 8718 } else { 8719 mccch = (struct rtw89_fw_h2c_rf_get_mccch *)skb->data; 8720 mccch->ch_0_0 = cpu_to_le32(rfk_mcc->ch[0]); 8721 mccch->ch_0_1 = cpu_to_le32(rfk_mcc->ch[0]); 8722 mccch->ch_1_0 = cpu_to_le32(rfk_mcc->ch[1]); 8723 mccch->ch_1_1 = cpu_to_le32(rfk_mcc->ch[1]); 8724 mccch->current_channel = cpu_to_le32(rfk_mcc->ch[idx]); 8725 } 8726 8727 rtw89_h2c_pkt_set_hdr(rtwdev, skb, FWCMD_TYPE_H2C, 8728 H2C_CAT_OUTSRC, H2C_CL_OUTSRC_RF_FW_NOTIFY, 8729 H2C_FUNC_OUTSRC_RF_GET_MCCCH, 0, 0, 8730 len); 8731 8732 ret = rtw89_h2c_tx(rtwdev, skb, false); 8733 if (ret) { 8734 rtw89_err(rtwdev, "failed to send h2c\n"); 8735 goto fail; 8736 } 8737 8738 return 0; 8739 fail: 8740 dev_kfree_skb_any(skb); 8741 8742 return ret; 8743 } 8744 EXPORT_SYMBOL(rtw89_fw_h2c_rf_ntfy_mcc); 8745 8746 int rtw89_fw_h2c_mcc_dig(struct rtw89_dev *rtwdev, 8747 enum rtw89_chanctx_idx chanctx_idx, 8748 u8 mcc_role_idx, u8 pd_val, bool en) 8749 { 8750 const struct rtw89_chan *chan = rtw89_chan_get(rtwdev, chanctx_idx); 8751 const struct rtw89_dig_regs *dig_regs = rtwdev->chip->dig_regs; 8752 struct rtw89_h2c_mcc_dig *h2c; 8753 u32 len = sizeof(*h2c); 8754 struct sk_buff *skb; 8755 int ret; 8756 8757 skb = rtw89_fw_h2c_alloc_skb_with_hdr(rtwdev, len); 8758 if (!skb) { 8759 rtw89_err(rtwdev, "failed to alloc skb for h2c mcc_dig\n"); 8760 return -ENOMEM; 8761 } 8762 skb_put(skb, len); 8763 h2c = (struct rtw89_h2c_mcc_dig *)skb->data; 8764 8765 h2c->w0 = le32_encode_bits(1, RTW89_H2C_MCC_DIG_W0_REG_CNT) | 8766 le32_encode_bits(en, RTW89_H2C_MCC_DIG_W0_DM_EN) | 8767 le32_encode_bits(mcc_role_idx, RTW89_H2C_MCC_DIG_W0_IDX) | 8768 le32_encode_bits(1, RTW89_H2C_MCC_DIG_W0_SET) | 8769 le32_encode_bits(1, RTW89_H2C_MCC_DIG_W0_PHY0_EN) | 8770 le32_encode_bits(chan->channel, RTW89_H2C_MCC_DIG_W0_CENTER_CH) | 8771 le32_encode_bits(chan->band_type, RTW89_H2C_MCC_DIG_W0_BAND_TYPE); 8772 h2c->w1 = le32_encode_bits(dig_regs->seg0_pd_reg, 8773 RTW89_H2C_MCC_DIG_W1_ADDR_LSB) | 8774 le32_encode_bits(dig_regs->seg0_pd_reg >> 8, 8775 RTW89_H2C_MCC_DIG_W1_ADDR_MSB) | 8776 le32_encode_bits(dig_regs->pd_lower_bound_mask, 8777 RTW89_H2C_MCC_DIG_W1_BMASK_LSB) | 8778 le32_encode_bits(dig_regs->pd_lower_bound_mask >> 8, 8779 RTW89_H2C_MCC_DIG_W1_BMASK_MSB); 8780 h2c->w2 = le32_encode_bits(pd_val, RTW89_H2C_MCC_DIG_W2_VAL_LSB); 8781 8782 rtw89_h2c_pkt_set_hdr(rtwdev, skb, FWCMD_TYPE_H2C, 8783 H2C_CAT_OUTSRC, H2C_CL_OUTSRC_DM, 8784 H2C_FUNC_FW_MCC_DIG, 0, 0, len); 8785 8786 ret = rtw89_h2c_tx(rtwdev, skb, false); 8787 if (ret) { 8788 rtw89_err(rtwdev, "failed to send h2c\n"); 8789 goto fail; 8790 } 8791 8792 return 0; 8793 fail: 8794 dev_kfree_skb_any(skb); 8795 8796 return ret; 8797 } 8798 8799 int rtw89_fw_h2c_rf_ps_info(struct rtw89_dev *rtwdev, struct rtw89_vif *rtwvif) 8800 { 8801 const struct rtw89_chip_info *chip = rtwdev->chip; 8802 struct rtw89_vif_link *rtwvif_link; 8803 struct rtw89_h2c_rf_ps_info *h2c; 8804 const struct rtw89_chan *chan; 8805 u32 len = sizeof(*h2c); 8806 unsigned int link_id; 8807 struct sk_buff *skb; 8808 int ret; 8809 u8 path; 8810 u32 val; 8811 8812 if (chip->chip_gen != RTW89_CHIP_BE) 8813 return 0; 8814 8815 skb = rtw89_fw_h2c_alloc_skb_with_hdr(rtwdev, len); 8816 if (!skb) { 8817 rtw89_err(rtwdev, "failed to alloc skb for h2c rf ps info\n"); 8818 return -ENOMEM; 8819 } 8820 skb_put(skb, len); 8821 h2c = (struct rtw89_h2c_rf_ps_info *)skb->data; 8822 h2c->mlo_mode = cpu_to_le32(rtwdev->mlo_dbcc_mode); 8823 8824 rtw89_vif_for_each_link(rtwvif, rtwvif_link, link_id) { 8825 chan = rtw89_chan_get(rtwdev, rtwvif_link->chanctx_idx); 8826 path = rtw89_phy_get_syn_sel(rtwdev, rtwvif_link->phy_idx); 8827 val = rtw89_chip_chan_to_rf18_val(rtwdev, chan); 8828 8829 if (path >= chip->rf_path_num || path >= NUM_OF_RTW89_FW_RFK_PATH) { 8830 rtw89_err(rtwdev, "unsupported rf path (%d)\n", path); 8831 ret = -ENOENT; 8832 goto fail; 8833 } 8834 8835 h2c->rf18[path] = cpu_to_le32(val); 8836 h2c->pri_ch[path] = chan->primary_channel; 8837 } 8838 8839 rtw89_h2c_pkt_set_hdr(rtwdev, skb, FWCMD_TYPE_H2C, 8840 H2C_CAT_OUTSRC, H2C_CL_OUTSRC_RF_FW_NOTIFY, 8841 H2C_FUNC_OUTSRC_RF_PS_INFO, 0, 0, 8842 sizeof(*h2c)); 8843 8844 ret = rtw89_h2c_tx(rtwdev, skb, false); 8845 if (ret) { 8846 rtw89_err(rtwdev, "failed to send h2c\n"); 8847 goto fail; 8848 } 8849 8850 return 0; 8851 fail: 8852 dev_kfree_skb_any(skb); 8853 8854 return ret; 8855 } 8856 EXPORT_SYMBOL(rtw89_fw_h2c_rf_ps_info); 8857 8858 int rtw89_fw_h2c_rf_pre_ntfy(struct rtw89_dev *rtwdev, 8859 enum rtw89_phy_idx phy_idx) 8860 { 8861 struct rtw89_rfk_mcc_info *rfk_mcc = &rtwdev->rfk_mcc; 8862 struct rtw89_fw_h2c_rfk_pre_info_common *common; 8863 struct rtw89_fw_h2c_rfk_pre_info_v0 *h2c_v0; 8864 struct rtw89_fw_h2c_rfk_pre_info_v1 *h2c_v1; 8865 struct rtw89_fw_h2c_rfk_pre_info_v2 *h2c_v2; 8866 struct rtw89_fw_h2c_rfk_pre_info *h2c; 8867 u8 tbl_sel[NUM_OF_RTW89_FW_RFK_PATH]; 8868 u32 len = sizeof(*h2c); 8869 struct sk_buff *skb; 8870 u8 ver = U8_MAX; 8871 u8 tbl, path; 8872 u32 val32; 8873 int ret; 8874 8875 if (RTW89_CHK_FW_FEATURE(RFK_PRE_NOTIFY_V3, &rtwdev->fw)) { 8876 } else if (RTW89_CHK_FW_FEATURE(RFK_PRE_NOTIFY_V2, &rtwdev->fw)) { 8877 len = sizeof(*h2c_v2); 8878 ver = 2; 8879 } else if (RTW89_CHK_FW_FEATURE(RFK_PRE_NOTIFY_V1, &rtwdev->fw)) { 8880 len = sizeof(*h2c_v1); 8881 ver = 1; 8882 } else if (RTW89_CHK_FW_FEATURE(RFK_PRE_NOTIFY_V0, &rtwdev->fw)) { 8883 len = sizeof(*h2c_v0); 8884 ver = 0; 8885 } 8886 8887 skb = rtw89_fw_h2c_alloc_skb_with_hdr(rtwdev, len); 8888 if (!skb) { 8889 rtw89_err(rtwdev, "failed to alloc skb for h2c rfk_pre_ntfy\n"); 8890 return -ENOMEM; 8891 } 8892 skb_put(skb, len); 8893 8894 if (ver <= 2) 8895 goto old_format; 8896 8897 h2c = (struct rtw89_fw_h2c_rfk_pre_info *)skb->data; 8898 8899 h2c->mlo_mode = cpu_to_le32(rtwdev->mlo_dbcc_mode); 8900 h2c->phy_idx = cpu_to_le32(phy_idx); 8901 h2c->mlo_1_1 = cpu_to_le32(rtw89_is_mlo_1_1(rtwdev)); 8902 8903 goto done; 8904 8905 old_format: 8906 h2c_v2 = (struct rtw89_fw_h2c_rfk_pre_info_v2 *)skb->data; 8907 common = &h2c_v2->base_v1.common; 8908 8909 common->mlo_mode = cpu_to_le32(rtwdev->mlo_dbcc_mode); 8910 8911 BUILD_BUG_ON(NUM_OF_RTW89_FW_RFK_TBL > RTW89_RFK_CHS_NR); 8912 BUILD_BUG_ON(ARRAY_SIZE(rfk_mcc->data) < NUM_OF_RTW89_FW_RFK_PATH); 8913 8914 for (tbl = 0; tbl < NUM_OF_RTW89_FW_RFK_TBL; tbl++) { 8915 for (path = 0; path < NUM_OF_RTW89_FW_RFK_PATH; path++) { 8916 common->dbcc.ch[path][tbl] = 8917 cpu_to_le32(rfk_mcc->data[path].ch[tbl]); 8918 common->dbcc.band[path][tbl] = 8919 cpu_to_le32(rfk_mcc->data[path].band[tbl]); 8920 } 8921 } 8922 8923 for (path = 0; path < NUM_OF_RTW89_FW_RFK_PATH; path++) { 8924 tbl_sel[path] = rfk_mcc->data[path].table_idx; 8925 8926 common->tbl.cur_ch[path] = 8927 cpu_to_le32(rfk_mcc->data[path].ch[tbl_sel[path]]); 8928 common->tbl.cur_band[path] = 8929 cpu_to_le32(rfk_mcc->data[path].band[tbl_sel[path]]); 8930 8931 if (ver <= 1) 8932 continue; 8933 8934 h2c_v2->cur_bandwidth[path] = 8935 cpu_to_le32(rfk_mcc->data[path].bw[tbl_sel[path]]); 8936 } 8937 8938 common->phy_idx = cpu_to_le32(phy_idx); 8939 8940 if (ver == 0) { /* RFK_PRE_NOTIFY_V0 */ 8941 h2c_v0 = (struct rtw89_fw_h2c_rfk_pre_info_v0 *)skb->data; 8942 8943 h2c_v0->cur_band = cpu_to_le32(rfk_mcc->data[0].band[tbl_sel[0]]); 8944 h2c_v0->cur_bw = cpu_to_le32(rfk_mcc->data[0].bw[tbl_sel[0]]); 8945 h2c_v0->cur_center_ch = cpu_to_le32(rfk_mcc->data[0].ch[tbl_sel[0]]); 8946 8947 val32 = rtw89_phy_read32_mask(rtwdev, R_COEF_SEL, B_COEF_SEL_IQC_V1); 8948 h2c_v0->ktbl_sel0 = cpu_to_le32(val32); 8949 val32 = rtw89_phy_read32_mask(rtwdev, R_COEF_SEL_C1, B_COEF_SEL_IQC_V1); 8950 h2c_v0->ktbl_sel1 = cpu_to_le32(val32); 8951 val32 = rtw89_read_rf(rtwdev, RF_PATH_A, RR_CFGCH, RFREG_MASK); 8952 h2c_v0->rfmod0 = cpu_to_le32(val32); 8953 val32 = rtw89_read_rf(rtwdev, RF_PATH_B, RR_CFGCH, RFREG_MASK); 8954 h2c_v0->rfmod1 = cpu_to_le32(val32); 8955 8956 if (rtw89_is_mlo_1_1(rtwdev)) 8957 h2c_v0->mlo_1_1 = cpu_to_le32(1); 8958 8959 h2c_v0->rfe_type = cpu_to_le32(rtwdev->efuse.rfe_type); 8960 8961 goto done; 8962 } 8963 8964 if (rtw89_is_mlo_1_1(rtwdev)) { 8965 h2c_v1 = &h2c_v2->base_v1; 8966 h2c_v1->mlo_1_1 = cpu_to_le32(1); 8967 } 8968 done: 8969 rtw89_h2c_pkt_set_hdr(rtwdev, skb, FWCMD_TYPE_H2C, 8970 H2C_CAT_OUTSRC, H2C_CL_OUTSRC_RF_FW_RFK, 8971 H2C_FUNC_RFK_PRE_NOTIFY, 0, 0, 8972 len); 8973 8974 ret = rtw89_h2c_tx(rtwdev, skb, false); 8975 if (ret) { 8976 rtw89_err(rtwdev, "failed to send h2c\n"); 8977 goto fail; 8978 } 8979 8980 return 0; 8981 fail: 8982 dev_kfree_skb_any(skb); 8983 8984 return ret; 8985 } 8986 8987 int rtw89_fw_h2c_rf_pre_ntfy_mcc(struct rtw89_dev *rtwdev, enum rtw89_phy_idx phy_idx) 8988 { 8989 struct rtw89_rfk_mcc_info_data *rfk_mcc = rtwdev->rfk_mcc.data; 8990 struct rtw89_rfk_mcc_info *rfk_mcc_v0 = &rtwdev->rfk_mcc; 8991 struct rtw89_fw_h2c_rfk_pre_info_mcc_v0 *h2c_v0; 8992 struct rtw89_fw_h2c_rfk_pre_info_mcc_v1 *h2c_v1; 8993 struct rtw89_fw_h2c_rfk_pre_info_mcc *h2c; 8994 struct rtw89_hal *hal = &rtwdev->hal; 8995 u32 len = sizeof(*h2c); 8996 struct sk_buff *skb; 8997 u8 ver = U8_MAX; 8998 u8 tbl, path; 8999 u8 tbl_sel; 9000 int ret; 9001 9002 if (RTW89_CHK_FW_FEATURE(RFK_PRE_NOTIFY_MCC_V2, &rtwdev->fw)) { 9003 } else if (RTW89_CHK_FW_FEATURE(RFK_PRE_NOTIFY_MCC_V1, &rtwdev->fw)) { 9004 len = sizeof(*h2c_v1); 9005 ver = 1; 9006 } else if (RTW89_CHK_FW_FEATURE(RFK_PRE_NOTIFY_MCC_V0, &rtwdev->fw)) { 9007 len = sizeof(*h2c_v0); 9008 ver = 0; 9009 } 9010 9011 skb = rtw89_fw_h2c_alloc_skb_with_hdr(rtwdev, len); 9012 if (!skb) { 9013 rtw89_err(rtwdev, "failed to alloc skb for h2c rfk_pre_ntfy_mcc\n"); 9014 return -ENOMEM; 9015 } 9016 skb_put(skb, len); 9017 9018 if (ver != 0) 9019 goto v1; 9020 9021 h2c_v0 = (struct rtw89_fw_h2c_rfk_pre_info_mcc_v0 *)skb->data; 9022 for (tbl = 0; tbl < NUM_OF_RTW89_FW_RFK_TBL; tbl++) { 9023 for (path = 0; path < NUM_OF_RTW89_FW_RFK_PATH; path++) { 9024 h2c_v0->tbl_18[tbl][path] = 9025 cpu_to_le32(rfk_mcc_v0->data[path].rf18[tbl]); 9026 tbl_sel = rfk_mcc_v0->data[path].table_idx; 9027 h2c_v0->cur_18[path] = 9028 cpu_to_le32(rfk_mcc_v0->data[path].rf18[tbl_sel]); 9029 } 9030 } 9031 9032 h2c_v0->mlo_mode = cpu_to_le32(rtwdev->mlo_dbcc_mode); 9033 goto done; 9034 9035 v1: 9036 h2c_v1 = (struct rtw89_fw_h2c_rfk_pre_info_mcc_v1 *)skb->data; 9037 9038 BUILD_BUG_ON(NUM_OF_RTW89_FW_RFK_TBL > RTW89_RFK_CHS_NR); 9039 9040 for (tbl = 0; tbl < NUM_OF_RTW89_FW_RFK_TBL; tbl++) 9041 h2c_v1->tbl_18[tbl] = cpu_to_le32(rfk_mcc->rf18[tbl]); 9042 9043 BUILD_BUG_ON(ARRAY_SIZE(rtwdev->rfk_mcc.data) < NUM_OF_RTW89_FW_RFK_PATH); 9044 9045 /* shared table array, but tbl_sel can be independent by path */ 9046 for (path = 0; path < NUM_OF_RTW89_FW_RFK_PATH; path++) { 9047 tbl = rfk_mcc[path].table_idx; 9048 h2c_v1->cur_18[path] = cpu_to_le32(rfk_mcc->rf18[tbl]); 9049 9050 if (path == phy_idx) 9051 h2c_v1->tbl_idx = tbl; 9052 } 9053 9054 h2c_v1->mlo_mode = cpu_to_le32(rtwdev->mlo_dbcc_mode); 9055 h2c_v1->phy_idx = phy_idx; 9056 9057 if (rtw89_is_mlo_1_1(rtwdev)) 9058 h2c_v1->mlo_1_1 = cpu_to_le32(1); 9059 9060 if (ver == 1) 9061 goto done; 9062 9063 h2c = (struct rtw89_fw_h2c_rfk_pre_info_mcc *)skb->data; 9064 9065 h2c->aid = cpu_to_le32(hal->aid); 9066 h2c->acv = hal->acv; 9067 9068 done: 9069 rtw89_h2c_pkt_set_hdr(rtwdev, skb, FWCMD_TYPE_H2C, 9070 H2C_CAT_OUTSRC, H2C_CL_OUTSRC_RF_FW_NOTIFY, 9071 H2C_FUNC_OUTSRC_RF_MCC_INFO, 0, 0, len); 9072 9073 ret = rtw89_h2c_tx(rtwdev, skb, false); 9074 if (ret) { 9075 rtw89_err(rtwdev, "failed to send h2c\n"); 9076 goto fail; 9077 } 9078 9079 return 0; 9080 fail: 9081 dev_kfree_skb_any(skb); 9082 9083 return ret; 9084 } 9085 9086 int rtw89_fw_h2c_rf_tssi(struct rtw89_dev *rtwdev, enum rtw89_phy_idx phy_idx, 9087 const struct rtw89_chan *chan, enum rtw89_tssi_mode tssi_mode) 9088 { 9089 const struct rtw89_chip_info *chip = rtwdev->chip; 9090 struct rtw89_efuse *efuse = &rtwdev->efuse; 9091 struct rtw89_hal *hal = &rtwdev->hal; 9092 struct rtw89_h2c_rf_tssi *h2c; 9093 u32 len = sizeof(*h2c); 9094 struct sk_buff *skb; 9095 int ret; 9096 9097 skb = rtw89_fw_h2c_alloc_skb_with_hdr(rtwdev, len); 9098 if (!skb) { 9099 rtw89_err(rtwdev, "failed to alloc skb for h2c RF TSSI\n"); 9100 return -ENOMEM; 9101 } 9102 skb_put(skb, len); 9103 h2c = (struct rtw89_h2c_rf_tssi *)skb->data; 9104 9105 h2c->len = cpu_to_le16(len); 9106 h2c->phy = phy_idx; 9107 h2c->ch = chan->channel; 9108 h2c->bw = chan->band_width; 9109 h2c->band = chan->band_type; 9110 h2c->cv = hal->cv; 9111 h2c->tssi_mode = tssi_mode; 9112 h2c->rfe_type = efuse->rfe_type; 9113 9114 if (chip->chip_id == RTL8922A) 9115 h2c->hwtx_en = true; 9116 else 9117 h2c->hwtx_en = false; 9118 9119 rtw89_phy_rfk_tssi_fill_fwcmd_efuse_to_de(rtwdev, phy_idx, chan, h2c); 9120 rtw89_phy_rfk_tssi_fill_fwcmd_tmeter_tbl(rtwdev, phy_idx, chan, h2c); 9121 9122 rtw89_h2c_pkt_set_hdr(rtwdev, skb, FWCMD_TYPE_H2C, 9123 H2C_CAT_OUTSRC, H2C_CL_OUTSRC_RF_FW_RFK, 9124 H2C_FUNC_RFK_TSSI_OFFLOAD, 0, 0, len); 9125 9126 ret = rtw89_h2c_tx(rtwdev, skb, false); 9127 if (ret) { 9128 rtw89_err(rtwdev, "failed to send h2c\n"); 9129 goto fail; 9130 } 9131 9132 return 0; 9133 fail: 9134 dev_kfree_skb_any(skb); 9135 9136 return ret; 9137 } 9138 9139 int rtw89_fw_h2c_rf_iqk(struct rtw89_dev *rtwdev, enum rtw89_phy_idx phy_idx, 9140 const struct rtw89_chan *chan) 9141 { 9142 struct rtw89_hal *hal = &rtwdev->hal; 9143 struct rtw89_h2c_rf_iqk_v0 *h2c_v0; 9144 struct rtw89_h2c_rf_iqk *h2c; 9145 u32 len = sizeof(*h2c); 9146 struct sk_buff *skb; 9147 u8 ver = U8_MAX; 9148 int ret; 9149 9150 if (RTW89_CHK_FW_FEATURE(RFK_IQK_V0, &rtwdev->fw)) { 9151 len = sizeof(*h2c_v0); 9152 ver = 0; 9153 } 9154 9155 skb = rtw89_fw_h2c_alloc_skb_with_hdr(rtwdev, len); 9156 if (!skb) { 9157 rtw89_err(rtwdev, "failed to alloc skb for h2c RF IQK\n"); 9158 return -ENOMEM; 9159 } 9160 skb_put(skb, len); 9161 9162 if (ver == 0) { 9163 h2c_v0 = (struct rtw89_h2c_rf_iqk_v0 *)skb->data; 9164 9165 h2c_v0->phy_idx = cpu_to_le32(phy_idx); 9166 h2c_v0->dbcc = cpu_to_le32(rtwdev->dbcc_en); 9167 9168 goto done; 9169 } 9170 9171 h2c = (struct rtw89_h2c_rf_iqk *)skb->data; 9172 9173 h2c->len = sizeof(*h2c); 9174 h2c->ktype = 0; 9175 h2c->phy = phy_idx; 9176 h2c->kpath = rtw89_phy_get_kpath(rtwdev, phy_idx); 9177 h2c->band = chan->band_type; 9178 h2c->bw = chan->band_width; 9179 h2c->ch = chan->channel; 9180 h2c->cv = hal->cv; 9181 9182 done: 9183 rtw89_h2c_pkt_set_hdr(rtwdev, skb, FWCMD_TYPE_H2C, 9184 H2C_CAT_OUTSRC, H2C_CL_OUTSRC_RF_FW_RFK, 9185 H2C_FUNC_RFK_IQK_OFFLOAD, 0, 0, len); 9186 9187 ret = rtw89_h2c_tx(rtwdev, skb, false); 9188 if (ret) { 9189 rtw89_err(rtwdev, "failed to send h2c\n"); 9190 goto fail; 9191 } 9192 9193 return 0; 9194 fail: 9195 dev_kfree_skb_any(skb); 9196 9197 return ret; 9198 } 9199 9200 int rtw89_fw_h2c_rf_dpk(struct rtw89_dev *rtwdev, enum rtw89_phy_idx phy_idx, 9201 const struct rtw89_chan *chan) 9202 { 9203 struct rtw89_h2c_rf_dpk *h2c; 9204 u32 len = sizeof(*h2c); 9205 struct sk_buff *skb; 9206 int ret; 9207 9208 skb = rtw89_fw_h2c_alloc_skb_with_hdr(rtwdev, len); 9209 if (!skb) { 9210 rtw89_err(rtwdev, "failed to alloc skb for h2c RF DPK\n"); 9211 return -ENOMEM; 9212 } 9213 skb_put(skb, len); 9214 h2c = (struct rtw89_h2c_rf_dpk *)skb->data; 9215 9216 h2c->len = len; 9217 h2c->phy = phy_idx; 9218 h2c->dpk_enable = true; 9219 h2c->kpath = RF_AB; 9220 h2c->cur_band = chan->band_type; 9221 h2c->cur_bw = chan->band_width; 9222 h2c->cur_ch = chan->channel; 9223 h2c->dpk_dbg_en = rtw89_debug_is_enabled(rtwdev, RTW89_DBG_RFK); 9224 9225 rtw89_h2c_pkt_set_hdr(rtwdev, skb, FWCMD_TYPE_H2C, 9226 H2C_CAT_OUTSRC, H2C_CL_OUTSRC_RF_FW_RFK, 9227 H2C_FUNC_RFK_DPK_OFFLOAD, 0, 0, len); 9228 9229 ret = rtw89_h2c_tx(rtwdev, skb, false); 9230 if (ret) { 9231 rtw89_err(rtwdev, "failed to send h2c\n"); 9232 goto fail; 9233 } 9234 9235 return 0; 9236 fail: 9237 dev_kfree_skb_any(skb); 9238 9239 return ret; 9240 } 9241 9242 int rtw89_fw_h2c_rf_txgapk(struct rtw89_dev *rtwdev, enum rtw89_phy_idx phy_idx, 9243 const struct rtw89_chan *chan) 9244 { 9245 struct rtw89_hal *hal = &rtwdev->hal; 9246 struct rtw89_h2c_rf_txgapk *h2c; 9247 u32 len = sizeof(*h2c); 9248 struct sk_buff *skb; 9249 int ret; 9250 9251 skb = rtw89_fw_h2c_alloc_skb_with_hdr(rtwdev, len); 9252 if (!skb) { 9253 rtw89_err(rtwdev, "failed to alloc skb for h2c RF TXGAPK\n"); 9254 return -ENOMEM; 9255 } 9256 skb_put(skb, len); 9257 h2c = (struct rtw89_h2c_rf_txgapk *)skb->data; 9258 9259 h2c->len = len; 9260 h2c->ktype = 2; 9261 h2c->phy = phy_idx; 9262 h2c->kpath = RF_AB; 9263 h2c->band = chan->band_type; 9264 h2c->bw = chan->band_width; 9265 h2c->ch = chan->channel; 9266 h2c->cv = hal->cv; 9267 9268 rtw89_h2c_pkt_set_hdr(rtwdev, skb, FWCMD_TYPE_H2C, 9269 H2C_CAT_OUTSRC, H2C_CL_OUTSRC_RF_FW_RFK, 9270 H2C_FUNC_RFK_TXGAPK_OFFLOAD, 0, 0, len); 9271 9272 ret = rtw89_h2c_tx(rtwdev, skb, false); 9273 if (ret) { 9274 rtw89_err(rtwdev, "failed to send h2c\n"); 9275 goto fail; 9276 } 9277 9278 return 0; 9279 fail: 9280 dev_kfree_skb_any(skb); 9281 9282 return ret; 9283 } 9284 9285 int rtw89_fw_h2c_rf_dack(struct rtw89_dev *rtwdev, enum rtw89_phy_idx phy_idx, 9286 const struct rtw89_chan *chan) 9287 { 9288 struct rtw89_h2c_rf_dack *h2c; 9289 u32 len = sizeof(*h2c); 9290 struct sk_buff *skb; 9291 int ret; 9292 9293 skb = rtw89_fw_h2c_alloc_skb_with_hdr(rtwdev, len); 9294 if (!skb) { 9295 rtw89_err(rtwdev, "failed to alloc skb for h2c RF DACK\n"); 9296 return -ENOMEM; 9297 } 9298 skb_put(skb, len); 9299 h2c = (struct rtw89_h2c_rf_dack *)skb->data; 9300 9301 h2c->len = len; 9302 h2c->phy = phy_idx; 9303 h2c->type = 0; 9304 9305 rtw89_h2c_pkt_set_hdr(rtwdev, skb, FWCMD_TYPE_H2C, 9306 H2C_CAT_OUTSRC, H2C_CL_OUTSRC_RF_FW_RFK, 9307 H2C_FUNC_RFK_DACK_OFFLOAD, 0, 0, len); 9308 9309 ret = rtw89_h2c_tx(rtwdev, skb, false); 9310 if (ret) { 9311 rtw89_err(rtwdev, "failed to send h2c\n"); 9312 goto fail; 9313 } 9314 9315 return 0; 9316 fail: 9317 dev_kfree_skb_any(skb); 9318 9319 return ret; 9320 } 9321 9322 int rtw89_fw_h2c_rf_rxdck(struct rtw89_dev *rtwdev, enum rtw89_phy_idx phy_idx, 9323 const struct rtw89_chan *chan, bool is_chl_k) 9324 { 9325 struct rtw89_h2c_rf_rxdck_v0 *v0; 9326 struct rtw89_h2c_rf_rxdck *h2c; 9327 u32 len = sizeof(*h2c); 9328 struct sk_buff *skb; 9329 int ver = -1; 9330 int ret; 9331 9332 if (RTW89_CHK_FW_FEATURE(RFK_RXDCK_V0, &rtwdev->fw)) { 9333 len = sizeof(*v0); 9334 ver = 0; 9335 } 9336 9337 skb = rtw89_fw_h2c_alloc_skb_with_hdr(rtwdev, len); 9338 if (!skb) { 9339 rtw89_err(rtwdev, "failed to alloc skb for h2c RF RXDCK\n"); 9340 return -ENOMEM; 9341 } 9342 skb_put(skb, len); 9343 v0 = (struct rtw89_h2c_rf_rxdck_v0 *)skb->data; 9344 9345 v0->len = len; 9346 v0->phy = phy_idx; 9347 v0->is_afe = false; 9348 v0->kpath = RF_AB; 9349 v0->cur_band = chan->band_type; 9350 v0->cur_bw = chan->band_width; 9351 v0->cur_ch = chan->channel; 9352 v0->rxdck_dbg_en = rtw89_debug_is_enabled(rtwdev, RTW89_DBG_RFK); 9353 9354 if (ver == 0) 9355 goto hdr; 9356 9357 h2c = (struct rtw89_h2c_rf_rxdck *)skb->data; 9358 h2c->is_chl_k = is_chl_k; 9359 9360 hdr: 9361 rtw89_h2c_pkt_set_hdr(rtwdev, skb, FWCMD_TYPE_H2C, 9362 H2C_CAT_OUTSRC, H2C_CL_OUTSRC_RF_FW_RFK, 9363 H2C_FUNC_RFK_RXDCK_OFFLOAD, 0, 0, len); 9364 9365 ret = rtw89_h2c_tx(rtwdev, skb, false); 9366 if (ret) { 9367 rtw89_err(rtwdev, "failed to send h2c\n"); 9368 goto fail; 9369 } 9370 9371 return 0; 9372 fail: 9373 dev_kfree_skb_any(skb); 9374 9375 return ret; 9376 } 9377 9378 int rtw89_fw_h2c_rf_tas_trigger(struct rtw89_dev *rtwdev, bool enable) 9379 { 9380 struct rtw89_h2c_rf_tas *h2c; 9381 u32 len = sizeof(*h2c); 9382 struct sk_buff *skb; 9383 int ret; 9384 9385 skb = rtw89_fw_h2c_alloc_skb_with_hdr(rtwdev, len); 9386 if (!skb) { 9387 rtw89_err(rtwdev, "failed to alloc skb for h2c RF TAS\n"); 9388 return -ENOMEM; 9389 } 9390 skb_put(skb, len); 9391 h2c = (struct rtw89_h2c_rf_tas *)skb->data; 9392 9393 h2c->enable = cpu_to_le32(enable); 9394 9395 rtw89_h2c_pkt_set_hdr(rtwdev, skb, FWCMD_TYPE_H2C, 9396 H2C_CAT_OUTSRC, H2C_CL_OUTSRC_RF_FW_RFK, 9397 H2C_FUNC_RFK_TAS_OFFLOAD, 0, 0, len); 9398 9399 ret = rtw89_h2c_tx(rtwdev, skb, false); 9400 if (ret) { 9401 rtw89_err(rtwdev, "failed to send h2c\n"); 9402 goto fail; 9403 } 9404 9405 return 0; 9406 fail: 9407 dev_kfree_skb_any(skb); 9408 9409 return ret; 9410 } 9411 9412 int rtw89_fw_h2c_rf_txiqk(struct rtw89_dev *rtwdev, enum rtw89_phy_idx phy_idx, 9413 const struct rtw89_chan *chan) 9414 { 9415 struct rtw89_h2c_rf_txiqk_v0 *h2c_v0; 9416 struct rtw89_h2c_rf_txiqk *h2c; 9417 u32 len = sizeof(*h2c); 9418 struct sk_buff *skb; 9419 u8 ver = U8_MAX; 9420 int ret; 9421 9422 if (RTW89_CHK_FW_FEATURE(RFK_TXIQK_V0, &rtwdev->fw)) { 9423 len = sizeof(*h2c_v0); 9424 ver = 0; 9425 } 9426 9427 skb = rtw89_fw_h2c_alloc_skb_with_hdr(rtwdev, len); 9428 if (!skb) { 9429 rtw89_err(rtwdev, "failed to alloc skb for h2c RF TXIQK\n"); 9430 return -ENOMEM; 9431 } 9432 skb_put(skb, len); 9433 h2c_v0 = (struct rtw89_h2c_rf_txiqk_v0 *)skb->data; 9434 9435 h2c_v0->len = len; 9436 h2c_v0->phy = phy_idx; 9437 h2c_v0->txiqk_enable = true; 9438 h2c_v0->is_wb_txiqk = true; 9439 h2c_v0->kpath = RF_AB; 9440 h2c_v0->cur_band = chan->band_type; 9441 h2c_v0->cur_bw = chan->band_width; 9442 h2c_v0->cur_ch = chan->channel; 9443 h2c_v0->txiqk_dbg_en = rtw89_debug_is_enabled(rtwdev, RTW89_DBG_RFK); 9444 9445 if (ver == 0) 9446 goto hdr; 9447 9448 h2c = (struct rtw89_h2c_rf_txiqk *)skb->data; 9449 h2c->is_ther_rek = false; 9450 9451 hdr: 9452 rtw89_h2c_pkt_set_hdr(rtwdev, skb, FWCMD_TYPE_H2C, 9453 H2C_CAT_OUTSRC, H2C_CL_OUTSRC_RF_FW_RFK, 9454 H2C_FUNC_RFK_TXIQK_OFFOAD, 0, 0, len); 9455 9456 ret = rtw89_h2c_tx(rtwdev, skb, false); 9457 if (ret) { 9458 rtw89_err(rtwdev, "failed to send h2c\n"); 9459 goto fail; 9460 } 9461 9462 return 0; 9463 fail: 9464 dev_kfree_skb_any(skb); 9465 9466 return ret; 9467 } 9468 9469 int rtw89_fw_h2c_rf_cim3k(struct rtw89_dev *rtwdev, enum rtw89_phy_idx phy_idx, 9470 const struct rtw89_chan *chan) 9471 { 9472 struct rtw89_h2c_rf_cim3k *h2c; 9473 u32 len = sizeof(*h2c); 9474 struct sk_buff *skb; 9475 int ret; 9476 9477 skb = rtw89_fw_h2c_alloc_skb_with_hdr(rtwdev, len); 9478 if (!skb) { 9479 rtw89_err(rtwdev, "failed to alloc skb for h2c RF CIM3K\n"); 9480 return -ENOMEM; 9481 } 9482 skb_put(skb, len); 9483 h2c = (struct rtw89_h2c_rf_cim3k *)skb->data; 9484 9485 h2c->len = len; 9486 h2c->phy = phy_idx; 9487 h2c->kpath = RF_AB; 9488 h2c->cur_band = chan->band_type; 9489 h2c->cur_bw = chan->band_width; 9490 h2c->cur_ch = chan->channel; 9491 h2c->cim3k_dbg_en = rtw89_debug_is_enabled(rtwdev, RTW89_DBG_RFK); 9492 9493 rtw89_h2c_pkt_set_hdr(rtwdev, skb, FWCMD_TYPE_H2C, 9494 H2C_CAT_OUTSRC, H2C_CL_OUTSRC_RF_FW_RFK, 9495 H2C_FUNC_RFK_CIM3K_OFFOAD, 0, 0, len); 9496 9497 ret = rtw89_h2c_tx(rtwdev, skb, false); 9498 if (ret) { 9499 rtw89_err(rtwdev, "failed to send h2c\n"); 9500 goto fail; 9501 } 9502 9503 return 0; 9504 fail: 9505 dev_kfree_skb_any(skb); 9506 9507 return ret; 9508 } 9509 9510 int rtw89_fw_h2c_raw_with_hdr(struct rtw89_dev *rtwdev, 9511 u8 h2c_class, u8 h2c_func, u8 *buf, u16 len, 9512 bool rack, bool dack) 9513 { 9514 struct sk_buff *skb; 9515 int ret; 9516 9517 skb = rtw89_fw_h2c_alloc_skb_with_hdr(rtwdev, len); 9518 if (!skb) { 9519 rtw89_err(rtwdev, "failed to alloc skb for raw with hdr\n"); 9520 return -ENOMEM; 9521 } 9522 skb_put_data(skb, buf, len); 9523 9524 rtw89_h2c_pkt_set_hdr(rtwdev, skb, FWCMD_TYPE_H2C, 9525 H2C_CAT_OUTSRC, h2c_class, h2c_func, rack, dack, 9526 len); 9527 9528 ret = rtw89_h2c_tx(rtwdev, skb, false); 9529 if (ret) { 9530 rtw89_err(rtwdev, "failed to send h2c\n"); 9531 goto fail; 9532 } 9533 9534 return 0; 9535 fail: 9536 dev_kfree_skb_any(skb); 9537 9538 return ret; 9539 } 9540 9541 int rtw89_fw_h2c_raw(struct rtw89_dev *rtwdev, const u8 *buf, u16 len) 9542 { 9543 struct sk_buff *skb; 9544 int ret; 9545 9546 skb = rtw89_fw_h2c_alloc_skb_no_hdr(rtwdev, len); 9547 if (!skb) { 9548 rtw89_err(rtwdev, "failed to alloc skb for h2c raw\n"); 9549 return -ENOMEM; 9550 } 9551 skb_put_data(skb, buf, len); 9552 9553 ret = rtw89_h2c_tx(rtwdev, skb, false); 9554 if (ret) { 9555 rtw89_err(rtwdev, "failed to send h2c\n"); 9556 goto fail; 9557 } 9558 9559 return 0; 9560 fail: 9561 dev_kfree_skb_any(skb); 9562 9563 return ret; 9564 } 9565 9566 void rtw89_fw_send_all_early_h2c(struct rtw89_dev *rtwdev) 9567 { 9568 struct rtw89_early_h2c *early_h2c; 9569 9570 lockdep_assert_wiphy(rtwdev->hw->wiphy); 9571 9572 list_for_each_entry(early_h2c, &rtwdev->early_h2c_list, list) { 9573 rtw89_fw_h2c_raw(rtwdev, early_h2c->h2c, early_h2c->h2c_len); 9574 } 9575 } 9576 9577 void __rtw89_fw_free_all_early_h2c(struct rtw89_dev *rtwdev) 9578 { 9579 struct rtw89_early_h2c *early_h2c, *tmp; 9580 9581 list_for_each_entry_safe(early_h2c, tmp, &rtwdev->early_h2c_list, list) { 9582 list_del(&early_h2c->list); 9583 kfree(early_h2c->h2c); 9584 kfree(early_h2c); 9585 } 9586 } 9587 9588 void rtw89_fw_free_all_early_h2c(struct rtw89_dev *rtwdev) 9589 { 9590 lockdep_assert_wiphy(rtwdev->hw->wiphy); 9591 9592 __rtw89_fw_free_all_early_h2c(rtwdev); 9593 } 9594 9595 void rtw89_fw_c2h_dummy_handler(struct rtw89_dev *rtwdev, struct sk_buff *c2h, u32 len) 9596 { 9597 struct rtw89_fw_c2h_attr *attr = RTW89_SKB_C2H_CB(c2h); 9598 u8 category = attr->category; 9599 u8 class = attr->class; 9600 u8 func = attr->func; 9601 9602 rtw89_debug(rtwdev, RTW89_DBG_FW, 9603 "C2H cate=%u cls=%u func=%u is dummy\n", category, class, func); 9604 } 9605 9606 static void rtw89_fw_c2h_parse_attr(struct sk_buff *c2h) 9607 { 9608 const struct rtw89_c2h_hdr *hdr = (const struct rtw89_c2h_hdr *)c2h->data; 9609 struct rtw89_fw_c2h_attr *attr = RTW89_SKB_C2H_CB(c2h); 9610 9611 attr->category = le32_get_bits(hdr->w0, RTW89_C2H_HDR_W0_CATEGORY); 9612 attr->class = le32_get_bits(hdr->w0, RTW89_C2H_HDR_W0_CLASS); 9613 attr->func = le32_get_bits(hdr->w0, RTW89_C2H_HDR_W0_FUNC); 9614 attr->len = le32_get_bits(hdr->w1, RTW89_C2H_HDR_W1_LEN); 9615 } 9616 9617 static bool rtw89_fw_c2h_chk_atomic(struct rtw89_dev *rtwdev, 9618 struct sk_buff *c2h) 9619 { 9620 struct rtw89_fw_c2h_attr *attr = RTW89_SKB_C2H_CB(c2h); 9621 u8 category = attr->category; 9622 u8 class = attr->class; 9623 u8 func = attr->func; 9624 9625 switch (category) { 9626 default: 9627 return false; 9628 case RTW89_C2H_CAT_MAC: 9629 return rtw89_mac_c2h_chk_atomic(rtwdev, c2h, class, func); 9630 case RTW89_C2H_CAT_OUTSRC: 9631 return rtw89_phy_c2h_chk_atomic(rtwdev, class, func); 9632 } 9633 } 9634 9635 void rtw89_fw_c2h_irqsafe(struct rtw89_dev *rtwdev, struct sk_buff *c2h) 9636 { 9637 rtw89_fw_c2h_parse_attr(c2h); 9638 if (!rtw89_fw_c2h_chk_atomic(rtwdev, c2h)) 9639 goto enqueue; 9640 9641 rtw89_fw_c2h_cmd_handle(rtwdev, c2h); 9642 dev_kfree_skb_any(c2h); 9643 return; 9644 9645 enqueue: 9646 skb_queue_tail(&rtwdev->c2h_queue, c2h); 9647 wiphy_work_queue(rtwdev->hw->wiphy, &rtwdev->c2h_work); 9648 } 9649 9650 static void rtw89_fw_c2h_cmd_handle(struct rtw89_dev *rtwdev, 9651 struct sk_buff *skb) 9652 { 9653 struct rtw89_fw_c2h_attr *attr = RTW89_SKB_C2H_CB(skb); 9654 u8 category = attr->category; 9655 u8 class = attr->class; 9656 u8 func = attr->func; 9657 u16 len = attr->len; 9658 bool dump = true; 9659 9660 if (!test_bit(RTW89_FLAG_RUNNING, rtwdev->flags)) 9661 return; 9662 9663 switch (category) { 9664 case RTW89_C2H_CAT_TEST: 9665 break; 9666 case RTW89_C2H_CAT_MAC: 9667 rtw89_mac_c2h_handle(rtwdev, skb, len, class, func); 9668 if (class == RTW89_MAC_C2H_CLASS_INFO && 9669 func == RTW89_MAC_C2H_FUNC_C2H_LOG) 9670 dump = false; 9671 break; 9672 case RTW89_C2H_CAT_OUTSRC: 9673 if (class >= RTW89_PHY_C2H_CLASS_BTC_MIN && 9674 class <= RTW89_PHY_C2H_CLASS_BTC_MAX) 9675 rtw89_btc_c2h_handle(rtwdev, skb, len, class, func); 9676 else 9677 rtw89_phy_c2h_handle(rtwdev, skb, len, class, func); 9678 break; 9679 } 9680 9681 if (dump) 9682 rtw89_hex_dump(rtwdev, RTW89_DBG_FW, "C2H: ", skb->data, skb->len); 9683 } 9684 9685 void rtw89_fw_c2h_work(struct wiphy *wiphy, struct wiphy_work *work) 9686 { 9687 struct rtw89_dev *rtwdev = container_of(work, struct rtw89_dev, 9688 c2h_work); 9689 struct sk_buff *skb, *tmp; 9690 struct sk_buff_head c2hq; 9691 unsigned long flags; 9692 9693 lockdep_assert_wiphy(rtwdev->hw->wiphy); 9694 9695 __skb_queue_head_init(&c2hq); 9696 9697 spin_lock_irqsave(&rtwdev->c2h_queue.lock, flags); 9698 skb_queue_splice_init(&rtwdev->c2h_queue, &c2hq); 9699 spin_unlock_irqrestore(&rtwdev->c2h_queue.lock, flags); 9700 9701 skb_queue_walk_safe(&c2hq, skb, tmp) { 9702 rtw89_fw_c2h_cmd_handle(rtwdev, skb); 9703 dev_kfree_skb_any(skb); 9704 } 9705 } 9706 9707 void rtw89_fw_c2h_purge_obsoleted_scan_events(struct rtw89_dev *rtwdev) 9708 { 9709 struct rtw89_hw_scan_info *scan_info = &rtwdev->scan_info; 9710 struct sk_buff *skb, *tmp; 9711 struct sk_buff_head c2hq; 9712 unsigned long flags; 9713 9714 lockdep_assert_wiphy(rtwdev->hw->wiphy); 9715 9716 __skb_queue_head_init(&c2hq); 9717 9718 spin_lock_irqsave(&rtwdev->c2h_queue.lock, flags); 9719 skb_queue_splice_init(&rtwdev->c2h_queue, &c2hq); 9720 spin_unlock_irqrestore(&rtwdev->c2h_queue.lock, flags); 9721 9722 skb_queue_walk_safe(&c2hq, skb, tmp) { 9723 struct rtw89_fw_c2h_attr *attr = RTW89_SKB_C2H_CB(skb); 9724 9725 if (!attr->is_scan_event || attr->scan_seq == scan_info->seq) 9726 continue; 9727 9728 rtw89_debug(rtwdev, RTW89_DBG_HW_SCAN, 9729 "purge obsoleted scan event with seq=%d (cur=%d)\n", 9730 attr->scan_seq, scan_info->seq); 9731 9732 __skb_unlink(skb, &c2hq); 9733 dev_kfree_skb_any(skb); 9734 } 9735 9736 spin_lock_irqsave(&rtwdev->c2h_queue.lock, flags); 9737 skb_queue_splice(&c2hq, &rtwdev->c2h_queue); 9738 spin_unlock_irqrestore(&rtwdev->c2h_queue.lock, flags); 9739 } 9740 9741 static int rtw89_fw_write_h2c_reg(struct rtw89_dev *rtwdev, 9742 struct rtw89_mac_h2c_info *info) 9743 { 9744 const struct rtw89_chip_info *chip = rtwdev->chip; 9745 struct rtw89_fw_info *fw_info = &rtwdev->fw; 9746 const u32 *h2c_reg = chip->h2c_regs; 9747 u8 i, val, len; 9748 int ret; 9749 9750 ret = read_poll_timeout(rtw89_read8, val, val == 0, 1000, 5000, false, 9751 rtwdev, chip->h2c_ctrl_reg); 9752 if (ret) { 9753 rtw89_warn(rtwdev, "FW does not process h2c registers\n"); 9754 return ret; 9755 } 9756 9757 len = DIV_ROUND_UP(info->content_len + RTW89_H2CREG_HDR_LEN, 9758 sizeof(info->u.h2creg[0])); 9759 9760 u32p_replace_bits(&info->u.hdr.w0, info->id, RTW89_H2CREG_HDR_FUNC_MASK); 9761 u32p_replace_bits(&info->u.hdr.w0, len, RTW89_H2CREG_HDR_LEN_MASK); 9762 9763 for (i = 0; i < RTW89_H2CREG_MAX; i++) 9764 rtw89_write32(rtwdev, h2c_reg[i], info->u.h2creg[i]); 9765 9766 fw_info->h2c_counter++; 9767 rtw89_write8_mask(rtwdev, chip->h2c_counter_reg.addr, 9768 chip->h2c_counter_reg.mask, fw_info->h2c_counter); 9769 rtw89_write8(rtwdev, chip->h2c_ctrl_reg, B_AX_H2CREG_TRIGGER); 9770 9771 return 0; 9772 } 9773 9774 static int rtw89_fw_read_c2h_reg(struct rtw89_dev *rtwdev, 9775 struct rtw89_mac_c2h_info *info) 9776 { 9777 const struct rtw89_chip_info *chip = rtwdev->chip; 9778 struct rtw89_fw_info *fw_info = &rtwdev->fw; 9779 const u32 *c2h_reg = chip->c2h_regs; 9780 u32 timeout; 9781 u8 i, val; 9782 int ret; 9783 9784 info->id = RTW89_FWCMD_C2HREG_FUNC_NULL; 9785 9786 if (rtwdev->hci.type == RTW89_HCI_TYPE_USB) 9787 timeout = RTW89_C2H_TIMEOUT_USB; 9788 else 9789 timeout = RTW89_C2H_TIMEOUT; 9790 9791 if (info->timeout) 9792 timeout = info->timeout; 9793 9794 ret = read_poll_timeout_atomic(rtw89_read8, val, val, 1, 9795 timeout, false, rtwdev, 9796 chip->c2h_ctrl_reg); 9797 if (ret) { 9798 rtw89_warn(rtwdev, "c2h reg timeout\n"); 9799 return ret; 9800 } 9801 9802 for (i = 0; i < RTW89_C2HREG_MAX; i++) 9803 info->u.c2hreg[i] = rtw89_read32(rtwdev, c2h_reg[i]); 9804 9805 rtw89_write8(rtwdev, chip->c2h_ctrl_reg, 0); 9806 9807 info->id = u32_get_bits(info->u.hdr.w0, RTW89_C2HREG_HDR_FUNC_MASK); 9808 info->content_len = 9809 (u32_get_bits(info->u.hdr.w0, RTW89_C2HREG_HDR_LEN_MASK) << 2) - 9810 RTW89_C2HREG_HDR_LEN; 9811 9812 fw_info->c2h_counter++; 9813 rtw89_write8_mask(rtwdev, chip->c2h_counter_reg.addr, 9814 chip->c2h_counter_reg.mask, fw_info->c2h_counter); 9815 9816 return 0; 9817 } 9818 9819 int rtw89_fw_msg_reg(struct rtw89_dev *rtwdev, 9820 struct rtw89_mac_h2c_info *h2c_info, 9821 struct rtw89_mac_c2h_info *c2h_info) 9822 { 9823 int ret; 9824 9825 if (h2c_info && h2c_info->id != RTW89_FWCMD_H2CREG_FUNC_GET_FEATURE) 9826 lockdep_assert_wiphy(rtwdev->hw->wiphy); 9827 9828 if (!h2c_info && !c2h_info) 9829 return -EINVAL; 9830 9831 if (!h2c_info) 9832 goto recv_c2h; 9833 9834 ret = rtw89_fw_write_h2c_reg(rtwdev, h2c_info); 9835 if (ret) 9836 return ret; 9837 9838 recv_c2h: 9839 if (!c2h_info) 9840 return 0; 9841 9842 ret = rtw89_fw_read_c2h_reg(rtwdev, c2h_info); 9843 if (ret) 9844 return ret; 9845 9846 return 0; 9847 } 9848 9849 void rtw89_fw_st_dbg_dump(struct rtw89_dev *rtwdev) 9850 { 9851 if (!test_bit(RTW89_FLAG_POWERON, rtwdev->flags)) { 9852 rtw89_err(rtwdev, "[ERR]pwr is off\n"); 9853 return; 9854 } 9855 9856 rtw89_info(rtwdev, "FW status = 0x%x\n", rtw89_read32(rtwdev, R_AX_UDM0)); 9857 rtw89_info(rtwdev, "FW BADADDR = 0x%x\n", rtw89_read32(rtwdev, R_AX_UDM1)); 9858 rtw89_info(rtwdev, "FW EPC/RA = 0x%x\n", rtw89_read32(rtwdev, R_AX_UDM2)); 9859 rtw89_info(rtwdev, "FW MISC = 0x%x\n", rtw89_read32(rtwdev, R_AX_UDM3)); 9860 rtw89_info(rtwdev, "R_AX_HALT_C2H = 0x%x\n", 9861 rtw89_read32(rtwdev, R_AX_HALT_C2H)); 9862 rtw89_info(rtwdev, "R_AX_HALT_C2H_CTRL = 0x%x\n", 9863 rtw89_read32(rtwdev, R_AX_HALT_C2H_CTRL)); 9864 rtw89_info(rtwdev, "R_AX_HALT_H2C = 0x%x\n", 9865 rtw89_read32(rtwdev, R_AX_HALT_H2C)); 9866 rtw89_info(rtwdev, "R_AX_HALT_H2C_CTRL = 0x%x\n", 9867 rtw89_read32(rtwdev, R_AX_HALT_H2C_CTRL)); 9868 rtw89_info(rtwdev, "R_AX_SER_DBG_INFO = 0x%x\n", 9869 rtw89_read32(rtwdev, R_AX_SER_DBG_INFO)); 9870 9871 rtw89_fw_prog_cnt_dump(rtwdev); 9872 } 9873 9874 static void rtw89_hw_scan_release_pkt_list(struct rtw89_dev *rtwdev) 9875 { 9876 struct rtw89_hw_scan_info *scan_info = &rtwdev->scan_info; 9877 struct list_head *pkt_list = rtwdev->scan_info.pkt_list; 9878 struct rtw89_pktofld_info *info, *tmp; 9879 u8 idx, wildcard_pkt_id; 9880 9881 for (idx = NL80211_BAND_2GHZ; idx < NUM_NL80211_BANDS; idx++) { 9882 if (!(rtwdev->chip->support_bands & BIT(idx))) 9883 continue; 9884 9885 wildcard_pkt_id = scan_info->wildcard_pkt_id[idx]; 9886 if (wildcard_pkt_id != RTW89_SCANOFLD_PKT_NONE) 9887 rtw89_fw_h2c_del_pkt_offload(rtwdev, wildcard_pkt_id); 9888 9889 list_for_each_entry_safe(info, tmp, &pkt_list[idx], list) { 9890 if (test_bit(info->id, rtwdev->pkt_offload)) 9891 rtw89_fw_h2c_del_pkt_offload(rtwdev, info->id); 9892 list_del(&info->list); 9893 kfree(info); 9894 } 9895 } 9896 } 9897 9898 static void rtw89_hw_scan_cleanup(struct rtw89_dev *rtwdev, 9899 struct rtw89_vif_link *rtwvif_link) 9900 { 9901 const struct rtw89_mac_gen_def *mac = rtwdev->chip->mac_def; 9902 struct rtw89_hw_scan_info *scan_info = &rtwdev->scan_info; 9903 struct rtw89_vif *rtwvif = rtwvif_link->rtwvif; 9904 9905 mac->free_chan_list(rtwdev); 9906 rtw89_hw_scan_release_pkt_list(rtwdev); 9907 9908 rtwvif->scan_req = NULL; 9909 rtwvif->scan_ies = NULL; 9910 scan_info->scanning_vif = NULL; 9911 scan_info->abort = false; 9912 scan_info->connected = false; 9913 scan_info->delay = 0; 9914 } 9915 9916 static bool rtw89_is_6ghz_wildcard_probe_req(struct rtw89_dev *rtwdev, 9917 struct cfg80211_scan_request *req, 9918 struct rtw89_pktofld_info *info, 9919 enum nl80211_band band, u8 ssid_idx) 9920 { 9921 if (band != NL80211_BAND_6GHZ) 9922 return false; 9923 9924 if (req->ssids[ssid_idx].ssid_len) { 9925 memcpy(info->ssid, req->ssids[ssid_idx].ssid, 9926 req->ssids[ssid_idx].ssid_len); 9927 info->ssid_len = req->ssids[ssid_idx].ssid_len; 9928 return false; 9929 } else { 9930 info->wildcard_6ghz = true; 9931 return true; 9932 } 9933 } 9934 9935 static int rtw89_append_probe_req_ie(struct rtw89_dev *rtwdev, 9936 struct rtw89_vif_link *rtwvif_link, 9937 struct sk_buff *skb, u8 ssid_idx) 9938 { 9939 struct rtw89_hw_scan_info *scan_info = &rtwdev->scan_info; 9940 struct rtw89_vif *rtwvif = rtwvif_link->rtwvif; 9941 struct ieee80211_scan_ies *ies = rtwvif->scan_ies; 9942 struct cfg80211_scan_request *req = rtwvif->scan_req; 9943 struct rtw89_pktofld_info *info; 9944 struct sk_buff *new; 9945 int ret = 0; 9946 u8 band; 9947 9948 for (band = NL80211_BAND_2GHZ; band < NUM_NL80211_BANDS; band++) { 9949 if (!(rtwdev->chip->support_bands & BIT(band))) 9950 continue; 9951 9952 new = skb_copy(skb, GFP_KERNEL); 9953 if (!new) { 9954 ret = -ENOMEM; 9955 goto out; 9956 } 9957 skb_put_data(new, ies->ies[band], ies->len[band]); 9958 skb_put_data(new, ies->common_ies, ies->common_ie_len); 9959 9960 info = kzalloc_obj(*info); 9961 if (!info) { 9962 ret = -ENOMEM; 9963 kfree_skb(new); 9964 goto out; 9965 } 9966 9967 rtw89_is_6ghz_wildcard_probe_req(rtwdev, req, info, band, ssid_idx); 9968 9969 ret = rtw89_fw_h2c_add_pkt_offload(rtwdev, &info->id, new); 9970 if (ret) { 9971 kfree_skb(new); 9972 kfree(info); 9973 goto out; 9974 } 9975 9976 list_add_tail(&info->list, &scan_info->pkt_list[band]); 9977 kfree_skb(new); 9978 } 9979 out: 9980 return ret; 9981 } 9982 9983 int rtw89_hw_scan_append_wildcard_probe_req(struct rtw89_dev *rtwdev, 9984 struct rtw89_vif_link *rtwvif_link, 9985 const u8 *mac_addr, bool wowlan) 9986 { 9987 static const u8 basic_rate_ie[] = {WLAN_EID_SUPP_RATES, 0x08, 0x0c, 0x12, 9988 0x18, 0x24, 0x30, 0x48, 0x60, 0x6c}; 9989 struct rtw89_hw_scan_info *scan_info = &rtwdev->scan_info; 9990 struct rtw89_vif *rtwvif = rtwvif_link->rtwvif; 9991 struct cfg80211_scan_request *req = rtwvif->scan_req; 9992 struct ieee80211_scan_ies *ies = rtwvif->scan_ies; 9993 struct rtw89_wow_param *rtw_wow = &rtwdev->wow; 9994 struct cfg80211_sched_scan_request *nd_config; 9995 enum nl80211_band band; 9996 struct sk_buff *skb; 9997 int ret; 9998 u8 id; 9999 10000 for (band = NL80211_BAND_2GHZ; band < NUM_NL80211_BANDS; band++) { 10001 if (!(rtwdev->chip->support_bands & BIT(band))) 10002 continue; 10003 10004 if (wowlan) { 10005 nd_config = rtw_wow->nd_config; 10006 10007 skb = ieee80211_probereq_get(rtwdev->hw, rtwvif_link->mac_addr, NULL, 0, 10008 nd_config->ie_len + 10009 sizeof(basic_rate_ie)); 10010 if (!skb) 10011 return -ENOMEM; 10012 10013 skb_put_data(skb, basic_rate_ie, sizeof(basic_rate_ie)); 10014 skb_put_data(skb, nd_config->ie, nd_config->ie_len); 10015 } else { 10016 skb = ieee80211_probereq_get(rtwdev->hw, mac_addr, 10017 NULL, 0, req->ie_len); 10018 if (!skb) 10019 return -ENOMEM; 10020 10021 skb_put_data(skb, ies->ies[band], ies->len[band]); 10022 skb_put_data(skb, ies->common_ies, ies->common_ie_len); 10023 } 10024 10025 ret = rtw89_fw_h2c_add_pkt_offload(rtwdev, &id, skb); 10026 kfree_skb(skb); 10027 10028 if (ret) 10029 return ret; 10030 10031 scan_info->wildcard_pkt_id[band] = id; 10032 } 10033 10034 return 0; 10035 } 10036 10037 static int rtw89_hw_scan_update_probe_req(struct rtw89_dev *rtwdev, 10038 struct rtw89_vif_link *rtwvif_link, 10039 const u8 *mac_addr) 10040 { 10041 struct rtw89_vif *rtwvif = rtwvif_link->rtwvif; 10042 struct cfg80211_scan_request *req = rtwvif->scan_req; 10043 u8 num = req->n_ssids, i; 10044 struct sk_buff *skb; 10045 int ret; 10046 10047 ret = rtw89_hw_scan_append_wildcard_probe_req(rtwdev, rtwvif_link, mac_addr, false); 10048 if (ret) 10049 return ret; 10050 10051 for (i = 0; i < num; i++) { 10052 skb = ieee80211_probereq_get(rtwdev->hw, mac_addr, 10053 req->ssids[i].ssid, 10054 req->ssids[i].ssid_len, 10055 req->ie_len); 10056 if (!skb) 10057 return -ENOMEM; 10058 10059 ret = rtw89_append_probe_req_ie(rtwdev, rtwvif_link, skb, i); 10060 kfree_skb(skb); 10061 10062 if (ret) 10063 return ret; 10064 } 10065 10066 return 0; 10067 } 10068 10069 static int rtw89_update_6ghz_rnr_chan_ax(struct rtw89_dev *rtwdev, 10070 struct ieee80211_scan_ies *ies, 10071 struct cfg80211_scan_request *req, 10072 struct rtw89_mac_chinfo_ax *ch_info) 10073 { 10074 struct rtw89_vif_link *rtwvif_link = rtwdev->scan_info.scanning_vif; 10075 struct list_head *pkt_list = rtwdev->scan_info.pkt_list; 10076 struct cfg80211_scan_6ghz_params *params; 10077 struct rtw89_pktofld_info *info, *tmp; 10078 struct ieee80211_hdr *hdr; 10079 struct sk_buff *skb; 10080 bool found; 10081 int ret = 0; 10082 u32 i; 10083 10084 if (!req->n_6ghz_params) 10085 return 0; 10086 10087 for (i = 0; i < req->n_6ghz_params; i++) { 10088 params = &req->scan_6ghz_params[i]; 10089 10090 if (req->channels[params->channel_idx]->hw_value != 10091 ch_info->pri_ch) 10092 continue; 10093 10094 found = false; 10095 list_for_each_entry(tmp, &pkt_list[NL80211_BAND_6GHZ], list) { 10096 if (ether_addr_equal(tmp->bssid, params->bssid)) { 10097 found = true; 10098 break; 10099 } 10100 } 10101 if (found) 10102 continue; 10103 10104 skb = ieee80211_probereq_get(rtwdev->hw, rtwvif_link->mac_addr, 10105 NULL, 0, req->ie_len); 10106 if (!skb) 10107 return -ENOMEM; 10108 10109 skb_put_data(skb, ies->ies[NL80211_BAND_6GHZ], ies->len[NL80211_BAND_6GHZ]); 10110 skb_put_data(skb, ies->common_ies, ies->common_ie_len); 10111 hdr = (struct ieee80211_hdr *)skb->data; 10112 ether_addr_copy(hdr->addr3, params->bssid); 10113 10114 info = kzalloc_obj(*info); 10115 if (!info) { 10116 ret = -ENOMEM; 10117 kfree_skb(skb); 10118 goto out; 10119 } 10120 10121 ret = rtw89_fw_h2c_add_pkt_offload(rtwdev, &info->id, skb); 10122 if (ret) { 10123 kfree_skb(skb); 10124 kfree(info); 10125 goto out; 10126 } 10127 10128 ether_addr_copy(info->bssid, params->bssid); 10129 info->channel_6ghz = req->channels[params->channel_idx]->hw_value; 10130 list_add_tail(&info->list, &rtwdev->scan_info.pkt_list[NL80211_BAND_6GHZ]); 10131 10132 ch_info->tx_pkt = true; 10133 ch_info->period = RTW89_CHANNEL_TIME_6G + RTW89_DWELL_TIME_6G; 10134 10135 kfree_skb(skb); 10136 } 10137 10138 out: 10139 return ret; 10140 } 10141 10142 static void rtw89_pno_scan_add_chan_ax(struct rtw89_dev *rtwdev, 10143 int chan_type, int ssid_num, 10144 struct rtw89_mac_chinfo_ax *ch_info) 10145 { 10146 struct rtw89_wow_param *rtw_wow = &rtwdev->wow; 10147 struct rtw89_pktofld_info *info; 10148 u8 probe_count = 0; 10149 10150 ch_info->dfs_ch = chan_type == RTW89_CHAN_DFS; 10151 ch_info->bw = RTW89_SCAN_WIDTH; 10152 ch_info->tx_pkt = true; 10153 ch_info->cfg_tx_pwr = false; 10154 ch_info->tx_pwr_idx = 0; 10155 ch_info->tx_null = false; 10156 ch_info->pause_data = false; 10157 ch_info->probe_id = RTW89_SCANOFLD_PKT_NONE; 10158 10159 if (ssid_num) { 10160 list_for_each_entry(info, &rtw_wow->pno_pkt_list, list) { 10161 if (info->channel_6ghz && 10162 ch_info->pri_ch != info->channel_6ghz) 10163 continue; 10164 else if (info->channel_6ghz && probe_count != 0) 10165 ch_info->period += RTW89_CHANNEL_TIME_6G; 10166 10167 if (info->wildcard_6ghz) 10168 continue; 10169 10170 ch_info->pkt_id[probe_count++] = info->id; 10171 if (probe_count >= RTW89_SCANOFLD_MAX_SSID) 10172 break; 10173 } 10174 ch_info->num_pkt = probe_count; 10175 } 10176 10177 switch (chan_type) { 10178 case RTW89_CHAN_DFS: 10179 if (ch_info->ch_band != RTW89_BAND_6G) 10180 ch_info->period = max_t(u8, ch_info->period, 10181 RTW89_DFS_CHAN_TIME); 10182 ch_info->dwell_time = RTW89_DWELL_TIME; 10183 break; 10184 case RTW89_CHAN_ACTIVE: 10185 break; 10186 default: 10187 rtw89_err(rtwdev, "Channel type out of bound\n"); 10188 } 10189 } 10190 10191 static void rtw89_hw_scan_add_chan_ax(struct rtw89_dev *rtwdev, int chan_type, 10192 int ssid_num, 10193 struct rtw89_mac_chinfo_ax *ch_info) 10194 { 10195 struct rtw89_hw_scan_info *scan_info = &rtwdev->scan_info; 10196 struct rtw89_vif_link *rtwvif_link = rtwdev->scan_info.scanning_vif; 10197 const struct rtw89_hw_scan_extra_op *ext = &scan_info->extra_op; 10198 struct rtw89_vif *rtwvif = rtwvif_link->rtwvif; 10199 struct ieee80211_scan_ies *ies = rtwvif->scan_ies; 10200 struct cfg80211_scan_request *req = rtwvif->scan_req; 10201 struct rtw89_chan *op = &rtwdev->scan_info.op_chan; 10202 struct rtw89_pktofld_info *info; 10203 struct ieee80211_vif *vif; 10204 u8 band, probe_count = 0; 10205 int ret; 10206 10207 ch_info->notify_action = RTW89_SCANOFLD_DEBUG_MASK; 10208 ch_info->dfs_ch = chan_type == RTW89_CHAN_DFS; 10209 ch_info->bw = RTW89_SCAN_WIDTH; 10210 ch_info->tx_pkt = true; 10211 ch_info->cfg_tx_pwr = false; 10212 ch_info->tx_pwr_idx = 0; 10213 ch_info->tx_null = false; 10214 ch_info->pause_data = false; 10215 ch_info->probe_id = RTW89_SCANOFLD_PKT_NONE; 10216 10217 if (ch_info->ch_band == RTW89_BAND_6G) { 10218 if ((ssid_num == 1 && req->ssids[0].ssid_len == 0) || 10219 !ch_info->is_psc) { 10220 ch_info->tx_pkt = false; 10221 if (!req->duration_mandatory) 10222 ch_info->period -= RTW89_DWELL_TIME_6G; 10223 } 10224 } 10225 10226 ret = rtw89_update_6ghz_rnr_chan_ax(rtwdev, ies, req, ch_info); 10227 if (ret) 10228 rtw89_warn(rtwdev, "RNR fails: %d\n", ret); 10229 10230 if (ssid_num) { 10231 band = rtw89_hw_to_nl80211_band(ch_info->ch_band); 10232 10233 list_for_each_entry(info, &scan_info->pkt_list[band], list) { 10234 if (info->channel_6ghz && 10235 ch_info->pri_ch != info->channel_6ghz) 10236 continue; 10237 else if (info->channel_6ghz && probe_count != 0) 10238 ch_info->period += RTW89_CHANNEL_TIME_6G; 10239 10240 if (info->wildcard_6ghz) 10241 continue; 10242 10243 ch_info->pkt_id[probe_count++] = info->id; 10244 if (probe_count >= RTW89_SCANOFLD_MAX_SSID) 10245 break; 10246 } 10247 ch_info->num_pkt = probe_count; 10248 } 10249 10250 switch (chan_type) { 10251 case RTW89_CHAN_OPERATE: 10252 ch_info->central_ch = op->channel; 10253 ch_info->pri_ch = op->primary_channel; 10254 ch_info->ch_band = op->band_type; 10255 ch_info->bw = op->band_width; 10256 vif = rtwvif_link_to_vif(rtwvif_link); 10257 ch_info->tx_null = !is_zero_ether_addr(rtwvif_link->bssid) && 10258 vif->type != NL80211_IFTYPE_AP; 10259 ch_info->num_pkt = 0; 10260 break; 10261 case RTW89_CHAN_DFS: 10262 if (ch_info->ch_band != RTW89_BAND_6G) 10263 ch_info->period = max_t(u8, ch_info->period, 10264 RTW89_DFS_CHAN_TIME); 10265 ch_info->dwell_time = RTW89_DWELL_TIME; 10266 ch_info->pause_data = true; 10267 break; 10268 case RTW89_CHAN_ACTIVE: 10269 ch_info->pause_data = true; 10270 break; 10271 case RTW89_CHAN_EXTRA_OP: 10272 ch_info->central_ch = ext->chan.channel; 10273 ch_info->pri_ch = ext->chan.primary_channel; 10274 ch_info->ch_band = ext->chan.band_type; 10275 ch_info->bw = ext->chan.band_width; 10276 vif = rtwvif_link_to_vif(ext->rtwvif_link); 10277 ch_info->tx_null = !is_zero_ether_addr(ext->rtwvif_link->bssid) && 10278 vif->type != NL80211_IFTYPE_AP; 10279 ch_info->num_pkt = 0; 10280 ch_info->macid_tx = true; 10281 break; 10282 default: 10283 rtw89_err(rtwdev, "Channel type out of bound\n"); 10284 } 10285 } 10286 10287 static void rtw89_pno_scan_add_chan_be(struct rtw89_dev *rtwdev, int chan_type, 10288 int ssid_num, 10289 struct rtw89_mac_chinfo_be *ch_info) 10290 { 10291 struct rtw89_wow_param *rtw_wow = &rtwdev->wow; 10292 struct rtw89_pktofld_info *info; 10293 u8 probe_count = 0, i; 10294 10295 ch_info->dfs_ch = chan_type == RTW89_CHAN_DFS; 10296 ch_info->bw = RTW89_SCAN_WIDTH; 10297 ch_info->tx_null = false; 10298 ch_info->pause_data = false; 10299 ch_info->probe_id = RTW89_SCANOFLD_PKT_NONE; 10300 10301 if (ssid_num) { 10302 list_for_each_entry(info, &rtw_wow->pno_pkt_list, list) { 10303 ch_info->pkt_id[probe_count++] = info->id; 10304 if (probe_count >= RTW89_SCANOFLD_MAX_SSID) 10305 break; 10306 } 10307 } 10308 10309 for (i = probe_count; i < RTW89_SCANOFLD_MAX_SSID; i++) 10310 ch_info->pkt_id[i] = RTW89_SCANOFLD_PKT_NONE; 10311 10312 switch (chan_type) { 10313 case RTW89_CHAN_DFS: 10314 ch_info->period = max_t(u8, ch_info->period, RTW89_DFS_CHAN_TIME); 10315 ch_info->dwell_time = RTW89_DWELL_TIME; 10316 break; 10317 case RTW89_CHAN_ACTIVE: 10318 break; 10319 default: 10320 rtw89_warn(rtwdev, "Channel type out of bound\n"); 10321 break; 10322 } 10323 } 10324 10325 static void rtw89_hw_scan_add_chan_be(struct rtw89_dev *rtwdev, int chan_type, 10326 int ssid_num, 10327 struct rtw89_mac_chinfo_be *ch_info) 10328 { 10329 struct rtw89_hw_scan_info *scan_info = &rtwdev->scan_info; 10330 struct rtw89_vif_link *rtwvif_link = rtwdev->scan_info.scanning_vif; 10331 struct rtw89_vif *rtwvif = rtwvif_link->rtwvif; 10332 struct cfg80211_scan_request *req = rtwvif->scan_req; 10333 struct rtw89_pktofld_info *info; 10334 u8 band, probe_count = 0, i; 10335 10336 ch_info->notify_action = RTW89_SCANOFLD_DEBUG_MASK; 10337 ch_info->dfs_ch = chan_type == RTW89_CHAN_DFS; 10338 ch_info->bw = RTW89_SCAN_WIDTH; 10339 ch_info->tx_null = false; 10340 ch_info->pause_data = false; 10341 ch_info->probe_id = RTW89_SCANOFLD_PKT_NONE; 10342 10343 if (ssid_num) { 10344 band = rtw89_hw_to_nl80211_band(ch_info->ch_band); 10345 10346 list_for_each_entry(info, &scan_info->pkt_list[band], list) { 10347 if (info->channel_6ghz && 10348 ch_info->pri_ch != info->channel_6ghz) 10349 continue; 10350 10351 if (info->wildcard_6ghz) 10352 continue; 10353 10354 ch_info->pkt_id[probe_count++] = info->id; 10355 if (probe_count >= RTW89_SCANOFLD_MAX_SSID) 10356 break; 10357 } 10358 10359 if (scan_info->n_ssids) 10360 ch_info->fw_probe0_ssids = GENMASK(scan_info->n_ssids - 1, 0); 10361 } 10362 10363 if (ch_info->ch_band == RTW89_BAND_6G) { 10364 if ((ssid_num == 1 && req->ssids[0].ssid_len == 0) || 10365 !ch_info->is_psc) { 10366 ch_info->probe_id = RTW89_SCANOFLD_PKT_NONE; 10367 if (!req->duration_mandatory) 10368 ch_info->period -= RTW89_DWELL_TIME_6G; 10369 } 10370 } 10371 10372 for (i = probe_count; i < RTW89_SCANOFLD_MAX_SSID; i++) 10373 ch_info->pkt_id[i] = RTW89_SCANOFLD_PKT_NONE; 10374 10375 switch (chan_type) { 10376 case RTW89_CHAN_DFS: 10377 if (ch_info->ch_band != RTW89_BAND_6G) 10378 ch_info->period = 10379 max_t(u8, ch_info->period, RTW89_DFS_CHAN_TIME); 10380 ch_info->dwell_time = RTW89_DWELL_TIME; 10381 ch_info->pause_data = true; 10382 break; 10383 case RTW89_CHAN_ACTIVE: 10384 ch_info->pause_data = true; 10385 break; 10386 default: 10387 rtw89_warn(rtwdev, "Channel type out of bound\n"); 10388 break; 10389 } 10390 } 10391 10392 int rtw89_pno_scan_add_chan_list_ax(struct rtw89_dev *rtwdev, 10393 struct rtw89_vif_link *rtwvif_link) 10394 { 10395 struct rtw89_wow_param *rtw_wow = &rtwdev->wow; 10396 struct cfg80211_sched_scan_request *nd_config = rtw_wow->nd_config; 10397 struct rtw89_mac_chinfo_ax *ch_info, *tmp; 10398 struct ieee80211_channel *channel; 10399 struct list_head chan_list; 10400 int list_len; 10401 enum rtw89_chan_type type; 10402 int ret = 0; 10403 u32 idx; 10404 10405 INIT_LIST_HEAD(&chan_list); 10406 for (idx = 0, list_len = 0; 10407 idx < nd_config->n_channels && list_len < RTW89_SCAN_LIST_LIMIT_AX; 10408 idx++, list_len++) { 10409 channel = nd_config->channels[idx]; 10410 ch_info = kzalloc_obj(*ch_info); 10411 if (!ch_info) { 10412 ret = -ENOMEM; 10413 goto out; 10414 } 10415 10416 ch_info->period = RTW89_CHANNEL_TIME; 10417 ch_info->ch_band = rtw89_nl80211_to_hw_band(channel->band); 10418 ch_info->central_ch = channel->hw_value; 10419 ch_info->pri_ch = channel->hw_value; 10420 ch_info->is_psc = cfg80211_channel_is_psc(channel); 10421 10422 if (channel->flags & 10423 (IEEE80211_CHAN_RADAR | IEEE80211_CHAN_NO_IR)) 10424 type = RTW89_CHAN_DFS; 10425 else 10426 type = RTW89_CHAN_ACTIVE; 10427 10428 rtw89_pno_scan_add_chan_ax(rtwdev, type, nd_config->n_match_sets, ch_info); 10429 list_add_tail(&ch_info->list, &chan_list); 10430 } 10431 ret = rtw89_fw_h2c_scan_list_offload_ax(rtwdev, list_len, &chan_list); 10432 10433 out: 10434 list_for_each_entry_safe(ch_info, tmp, &chan_list, list) { 10435 list_del(&ch_info->list); 10436 kfree(ch_info); 10437 } 10438 10439 return ret; 10440 } 10441 10442 static int rtw89_hw_scan_add_op_types_ax(struct rtw89_dev *rtwdev, 10443 enum rtw89_chan_type type, 10444 struct list_head *chan_list, 10445 struct cfg80211_scan_request *req, 10446 int *off_chan_time) 10447 { 10448 struct rtw89_mac_chinfo_ax *tmp; 10449 10450 tmp = kzalloc_obj(*tmp); 10451 if (!tmp) 10452 return -ENOMEM; 10453 10454 switch (type) { 10455 case RTW89_CHAN_OPERATE: 10456 tmp->period = req->duration_mandatory ? 10457 req->duration : RTW89_CHANNEL_TIME; 10458 *off_chan_time = 0; 10459 break; 10460 case RTW89_CHAN_EXTRA_OP: 10461 tmp->period = RTW89_CHANNEL_TIME_EXTRA_OP; 10462 /* still calc @off_chan_time for scan op */ 10463 *off_chan_time += tmp->period; 10464 break; 10465 default: 10466 kfree(tmp); 10467 return -EINVAL; 10468 } 10469 10470 rtw89_hw_scan_add_chan_ax(rtwdev, type, 0, tmp); 10471 list_add_tail(&tmp->list, chan_list); 10472 10473 return 0; 10474 } 10475 10476 int rtw89_hw_scan_prep_chan_list_ax(struct rtw89_dev *rtwdev, 10477 struct rtw89_vif_link *rtwvif_link) 10478 { 10479 struct rtw89_hw_scan_info *scan_info = &rtwdev->scan_info; 10480 const struct rtw89_hw_scan_extra_op *ext = &scan_info->extra_op; 10481 struct rtw89_vif *rtwvif = rtwvif_link->rtwvif; 10482 struct cfg80211_scan_request *req = rtwvif->scan_req; 10483 struct rtw89_mac_chinfo_ax *ch_info, *tmp; 10484 struct ieee80211_channel *channel; 10485 struct list_head chan_list; 10486 bool random_seq = req->flags & NL80211_SCAN_FLAG_RANDOM_SN; 10487 enum rtw89_chan_type type; 10488 int off_chan_time = 0; 10489 int ret; 10490 u32 idx; 10491 10492 INIT_LIST_HEAD(&chan_list); 10493 10494 for (idx = 0; idx < req->n_channels; idx++) { 10495 channel = req->channels[idx]; 10496 ch_info = kzalloc_obj(*ch_info); 10497 if (!ch_info) { 10498 ret = -ENOMEM; 10499 goto out; 10500 } 10501 10502 if (req->duration) 10503 ch_info->period = req->duration; 10504 else if (channel->band == NL80211_BAND_6GHZ) 10505 ch_info->period = RTW89_CHANNEL_TIME_6G + 10506 RTW89_DWELL_TIME_6G; 10507 else if (rtwvif_link->wifi_role == RTW89_WIFI_ROLE_P2P_CLIENT) 10508 ch_info->period = RTW89_P2P_CHAN_TIME; 10509 else 10510 ch_info->period = RTW89_CHANNEL_TIME; 10511 10512 ch_info->ch_band = rtw89_nl80211_to_hw_band(channel->band); 10513 ch_info->central_ch = channel->hw_value; 10514 ch_info->pri_ch = channel->hw_value; 10515 ch_info->rand_seq_num = random_seq; 10516 ch_info->is_psc = cfg80211_channel_is_psc(channel); 10517 10518 if (channel->flags & 10519 (IEEE80211_CHAN_RADAR | IEEE80211_CHAN_NO_IR)) 10520 type = RTW89_CHAN_DFS; 10521 else 10522 type = RTW89_CHAN_ACTIVE; 10523 rtw89_hw_scan_add_chan_ax(rtwdev, type, req->n_ssids, ch_info); 10524 10525 if (!(scan_info->connected && 10526 off_chan_time + ch_info->period > RTW89_OFF_CHAN_TIME)) 10527 goto next; 10528 10529 ret = rtw89_hw_scan_add_op_types_ax(rtwdev, RTW89_CHAN_OPERATE, 10530 &chan_list, req, &off_chan_time); 10531 if (ret) { 10532 kfree(ch_info); 10533 goto out; 10534 } 10535 10536 if (!ext->set) 10537 goto next; 10538 10539 ret = rtw89_hw_scan_add_op_types_ax(rtwdev, RTW89_CHAN_EXTRA_OP, 10540 &chan_list, req, &off_chan_time); 10541 if (ret) { 10542 kfree(ch_info); 10543 goto out; 10544 } 10545 10546 next: 10547 list_add_tail(&ch_info->list, &chan_list); 10548 off_chan_time += ch_info->period; 10549 } 10550 10551 list_splice_tail(&chan_list, &scan_info->chan_list); 10552 return 0; 10553 10554 out: 10555 list_for_each_entry_safe(ch_info, tmp, &chan_list, list) { 10556 list_del(&ch_info->list); 10557 kfree(ch_info); 10558 } 10559 10560 return ret; 10561 } 10562 10563 void rtw89_hw_scan_free_chan_list_ax(struct rtw89_dev *rtwdev) 10564 { 10565 struct rtw89_hw_scan_info *scan_info = &rtwdev->scan_info; 10566 struct rtw89_mac_chinfo_ax *ch_info, *tmp; 10567 10568 list_for_each_entry_safe(ch_info, tmp, &scan_info->chan_list, list) { 10569 list_del(&ch_info->list); 10570 kfree(ch_info); 10571 } 10572 } 10573 10574 int rtw89_hw_scan_add_chan_list_ax(struct rtw89_dev *rtwdev, 10575 struct rtw89_vif_link *rtwvif_link) 10576 { 10577 struct rtw89_hw_scan_info *scan_info = &rtwdev->scan_info; 10578 struct rtw89_mac_chinfo_ax *ch_info, *tmp; 10579 unsigned int list_len = 0; 10580 struct list_head list; 10581 int ret; 10582 10583 INIT_LIST_HEAD(&list); 10584 10585 list_for_each_entry_safe(ch_info, tmp, &scan_info->chan_list, list) { 10586 /* The operating channel (tx_null == true) should 10587 * not be last in the list, to avoid breaking 10588 * RTL8851BU and RTL8832BU. 10589 */ 10590 if (list_len + 1 == RTW89_SCAN_LIST_LIMIT_AX && ch_info->tx_null) 10591 break; 10592 10593 list_move_tail(&ch_info->list, &list); 10594 10595 list_len++; 10596 if (list_len == RTW89_SCAN_LIST_LIMIT_AX) 10597 break; 10598 } 10599 10600 ret = rtw89_fw_h2c_scan_list_offload_ax(rtwdev, list_len, &list); 10601 10602 list_for_each_entry_safe(ch_info, tmp, &list, list) { 10603 list_del(&ch_info->list); 10604 kfree(ch_info); 10605 } 10606 10607 return ret; 10608 } 10609 10610 int rtw89_pno_scan_add_chan_list_be(struct rtw89_dev *rtwdev, 10611 struct rtw89_vif_link *rtwvif_link) 10612 { 10613 struct rtw89_wow_param *rtw_wow = &rtwdev->wow; 10614 struct cfg80211_sched_scan_request *nd_config = rtw_wow->nd_config; 10615 struct rtw89_mac_chinfo_be *ch_info, *tmp; 10616 struct ieee80211_channel *channel; 10617 struct list_head chan_list; 10618 enum rtw89_chan_type type; 10619 int list_len, ret; 10620 u32 idx; 10621 10622 INIT_LIST_HEAD(&chan_list); 10623 10624 for (idx = 0, list_len = 0; 10625 idx < nd_config->n_channels && list_len < RTW89_SCAN_LIST_LIMIT_BE; 10626 idx++, list_len++) { 10627 channel = nd_config->channels[idx]; 10628 ch_info = kzalloc_obj(*ch_info); 10629 if (!ch_info) { 10630 ret = -ENOMEM; 10631 goto out; 10632 } 10633 10634 ch_info->period = RTW89_CHANNEL_TIME; 10635 ch_info->ch_band = rtw89_nl80211_to_hw_band(channel->band); 10636 ch_info->central_ch = channel->hw_value; 10637 ch_info->pri_ch = channel->hw_value; 10638 ch_info->is_psc = cfg80211_channel_is_psc(channel); 10639 10640 if (channel->flags & 10641 (IEEE80211_CHAN_RADAR | IEEE80211_CHAN_NO_IR)) 10642 type = RTW89_CHAN_DFS; 10643 else 10644 type = RTW89_CHAN_ACTIVE; 10645 10646 rtw89_pno_scan_add_chan_be(rtwdev, type, 10647 nd_config->n_match_sets, ch_info); 10648 list_add_tail(&ch_info->list, &chan_list); 10649 } 10650 10651 ret = rtw89_fw_h2c_scan_list_offload_be(rtwdev, list_len, &chan_list, 10652 rtwvif_link); 10653 10654 out: 10655 list_for_each_entry_safe(ch_info, tmp, &chan_list, list) { 10656 list_del(&ch_info->list); 10657 kfree(ch_info); 10658 } 10659 10660 return ret; 10661 } 10662 10663 int rtw89_hw_scan_prep_chan_list_be(struct rtw89_dev *rtwdev, 10664 struct rtw89_vif_link *rtwvif_link) 10665 { 10666 struct rtw89_hw_scan_info *scan_info = &rtwdev->scan_info; 10667 struct rtw89_vif *rtwvif = rtwvif_link->rtwvif; 10668 struct cfg80211_scan_request *req = rtwvif->scan_req; 10669 struct rtw89_mac_chinfo_be *ch_info, *tmp; 10670 struct ieee80211_channel *channel; 10671 struct list_head chan_list; 10672 enum rtw89_chan_type type; 10673 bool chan_by_rnr; 10674 bool random_seq; 10675 int ret; 10676 u32 idx; 10677 10678 random_seq = !!(req->flags & NL80211_SCAN_FLAG_RANDOM_SN); 10679 chan_by_rnr = rtwdev->chip->support_rnr && 10680 (req->flags & NL80211_SCAN_FLAG_COLOCATED_6GHZ); 10681 INIT_LIST_HEAD(&chan_list); 10682 10683 for (idx = 0; idx < req->n_channels; idx++) { 10684 channel = req->channels[idx]; 10685 10686 if (channel->band == NL80211_BAND_6GHZ && 10687 !cfg80211_channel_is_psc(channel) && chan_by_rnr) 10688 continue; 10689 10690 ch_info = kzalloc_obj(*ch_info); 10691 if (!ch_info) { 10692 ret = -ENOMEM; 10693 goto out; 10694 } 10695 10696 if (req->duration) 10697 ch_info->period = req->duration; 10698 else if (channel->band == NL80211_BAND_6GHZ) 10699 ch_info->period = RTW89_CHANNEL_TIME_6G + RTW89_DWELL_TIME_6G; 10700 else if (rtwvif_link->wifi_role == RTW89_WIFI_ROLE_P2P_CLIENT) 10701 ch_info->period = RTW89_P2P_CHAN_TIME; 10702 else 10703 ch_info->period = RTW89_CHANNEL_TIME; 10704 10705 ch_info->ch_band = rtw89_nl80211_to_hw_band(channel->band); 10706 ch_info->central_ch = channel->hw_value; 10707 ch_info->pri_ch = channel->hw_value; 10708 ch_info->rand_seq_num = random_seq; 10709 ch_info->is_psc = cfg80211_channel_is_psc(channel); 10710 10711 if (channel->flags & (IEEE80211_CHAN_RADAR | IEEE80211_CHAN_NO_IR)) 10712 type = RTW89_CHAN_DFS; 10713 else 10714 type = RTW89_CHAN_ACTIVE; 10715 rtw89_hw_scan_add_chan_be(rtwdev, type, req->n_ssids, ch_info); 10716 10717 list_add_tail(&ch_info->list, &chan_list); 10718 } 10719 10720 list_splice_tail(&chan_list, &scan_info->chan_list); 10721 return 0; 10722 10723 out: 10724 list_for_each_entry_safe(ch_info, tmp, &chan_list, list) { 10725 list_del(&ch_info->list); 10726 kfree(ch_info); 10727 } 10728 10729 return ret; 10730 } 10731 10732 void rtw89_hw_scan_free_chan_list_be(struct rtw89_dev *rtwdev) 10733 { 10734 struct rtw89_hw_scan_info *scan_info = &rtwdev->scan_info; 10735 struct rtw89_mac_chinfo_be *ch_info, *tmp; 10736 10737 list_for_each_entry_safe(ch_info, tmp, &scan_info->chan_list, list) { 10738 list_del(&ch_info->list); 10739 kfree(ch_info); 10740 } 10741 } 10742 10743 int rtw89_hw_scan_add_chan_list_be(struct rtw89_dev *rtwdev, 10744 struct rtw89_vif_link *rtwvif_link) 10745 { 10746 struct rtw89_hw_scan_info *scan_info = &rtwdev->scan_info; 10747 struct rtw89_mac_chinfo_be *ch_info, *tmp; 10748 unsigned int list_len = 0; 10749 struct list_head list; 10750 int ret; 10751 10752 INIT_LIST_HEAD(&list); 10753 10754 list_for_each_entry_safe(ch_info, tmp, &scan_info->chan_list, list) { 10755 list_move_tail(&ch_info->list, &list); 10756 10757 list_len++; 10758 if (list_len == RTW89_SCAN_LIST_LIMIT_BE) 10759 break; 10760 } 10761 10762 ret = rtw89_fw_h2c_scan_list_offload_be(rtwdev, list_len, &list, 10763 rtwvif_link); 10764 10765 list_for_each_entry_safe(ch_info, tmp, &list, list) { 10766 list_del(&ch_info->list); 10767 kfree(ch_info); 10768 } 10769 10770 return ret; 10771 } 10772 10773 static int rtw89_hw_scan_prehandle(struct rtw89_dev *rtwdev, 10774 struct rtw89_vif_link *rtwvif_link, 10775 const u8 *mac_addr) 10776 { 10777 const struct rtw89_mac_gen_def *mac = rtwdev->chip->mac_def; 10778 int ret; 10779 10780 ret = rtw89_hw_scan_update_probe_req(rtwdev, rtwvif_link, mac_addr); 10781 if (ret) { 10782 rtw89_err(rtwdev, "Update probe request failed\n"); 10783 goto out; 10784 } 10785 ret = mac->prep_chan_list(rtwdev, rtwvif_link); 10786 out: 10787 return ret; 10788 } 10789 10790 static void rtw89_hw_scan_update_link_beacon_noa(struct rtw89_dev *rtwdev, 10791 struct rtw89_vif_link *rtwvif_link, 10792 u16 tu, bool scan) 10793 { 10794 struct ieee80211_p2p_noa_desc noa_desc = {}; 10795 struct ieee80211_bss_conf *bss_conf; 10796 u16 beacon_int; 10797 u64 tsf; 10798 int ret; 10799 10800 rcu_read_lock(); 10801 10802 bss_conf = rtw89_vif_rcu_dereference_link(rtwvif_link, true); 10803 beacon_int = bss_conf->beacon_int; 10804 10805 rcu_read_unlock(); 10806 10807 tu += beacon_int * 3; 10808 if (rtwdev->chip->chip_gen == RTW89_CHIP_AX) 10809 rtwdev->scan_info.delay = ieee80211_tu_to_usec(beacon_int * 3) / 1000; 10810 10811 ret = rtw89_mac_port_get_tsf(rtwdev, rtwvif_link, &tsf); 10812 if (ret) { 10813 rtw89_warn(rtwdev, "%s: failed to get tsf\n", __func__); 10814 return; 10815 } 10816 10817 noa_desc.start_time = cpu_to_le32(tsf); 10818 if (rtwdev->chip->chip_gen == RTW89_CHIP_AX) { 10819 noa_desc.interval = cpu_to_le32(ieee80211_tu_to_usec(tu)); 10820 noa_desc.duration = cpu_to_le32(ieee80211_tu_to_usec(tu)); 10821 noa_desc.count = 1; 10822 } else { 10823 noa_desc.duration = cpu_to_le32(ieee80211_tu_to_usec(20000)); 10824 noa_desc.interval = cpu_to_le32(ieee80211_tu_to_usec(20000)); 10825 noa_desc.count = 255; 10826 } 10827 10828 rtw89_p2p_noa_renew(rtwvif_link); 10829 if (scan) 10830 rtw89_p2p_noa_append(rtwvif_link, &noa_desc); 10831 10832 rtw89_chip_h2c_update_beacon(rtwdev, rtwvif_link); 10833 } 10834 10835 static void rtw89_hw_scan_update_beacon_noa(struct rtw89_dev *rtwdev, bool scan) 10836 { 10837 const struct rtw89_hw_scan_info *scan_info = &rtwdev->scan_info; 10838 const struct rtw89_chip_info *chip = rtwdev->chip; 10839 struct rtw89_mac_chinfo_ax *chinfo_ax; 10840 struct rtw89_mac_chinfo_be *chinfo_be; 10841 struct rtw89_vif_link *rtwvif_link; 10842 struct list_head *pos, *tmp; 10843 struct ieee80211_vif *vif; 10844 struct rtw89_vif *rtwvif; 10845 u16 tu = 0; 10846 10847 lockdep_assert_wiphy(rtwdev->hw->wiphy); 10848 10849 if (!scan) 10850 goto update; 10851 10852 list_for_each_safe(pos, tmp, &scan_info->chan_list) { 10853 switch (chip->chip_gen) { 10854 case RTW89_CHIP_AX: 10855 chinfo_ax = list_entry(pos, typeof(*chinfo_ax), list); 10856 tu += chinfo_ax->period; 10857 break; 10858 case RTW89_CHIP_BE: 10859 chinfo_be = list_entry(pos, typeof(*chinfo_be), list); 10860 tu += chinfo_be->period; 10861 break; 10862 default: 10863 rtw89_warn(rtwdev, "%s: invalid chip gen %d\n", 10864 __func__, chip->chip_gen); 10865 return; 10866 } 10867 } 10868 10869 if (unlikely(tu == 0)) { 10870 rtw89_debug(rtwdev, RTW89_DBG_HW_SCAN, 10871 "%s: cannot estimate needed TU\n", __func__); 10872 return; 10873 } 10874 10875 update: 10876 rtw89_for_each_active_rtwvif(rtwdev, rtwvif) { 10877 unsigned int link_id; 10878 10879 vif = rtwvif_to_vif(rtwvif); 10880 if (vif->type != NL80211_IFTYPE_AP || !vif->p2p) 10881 continue; 10882 10883 rtw89_vif_for_each_link(rtwvif, rtwvif_link, link_id) 10884 rtw89_hw_scan_update_link_beacon_noa(rtwdev, rtwvif_link, 10885 tu, scan); 10886 } 10887 } 10888 10889 static void rtw89_hw_scan_set_extra_op_info(struct rtw89_dev *rtwdev, 10890 struct rtw89_vif *scan_rtwvif, 10891 const struct rtw89_chan *scan_op) 10892 { 10893 struct rtw89_hw_scan_info *scan_info = &rtwdev->scan_info; 10894 struct rtw89_hw_scan_extra_op *ext = &scan_info->extra_op; 10895 struct rtw89_vif *tmp; 10896 10897 ext->set = false; 10898 if (!RTW89_CHK_FW_FEATURE(SCAN_OFFLOAD_EXTRA_OP, &rtwdev->fw)) 10899 return; 10900 10901 rtw89_for_each_active_rtwvif(rtwdev, tmp) { 10902 const struct rtw89_chan *tmp_chan; 10903 struct rtw89_vif_link *tmp_link; 10904 10905 if (tmp == scan_rtwvif) 10906 continue; 10907 10908 tmp_link = rtw89_get_designated_link(tmp); 10909 if (unlikely(!tmp_link)) 10910 continue; 10911 10912 tmp_chan = rtw89_chan_get(rtwdev, tmp_link->chanctx_idx); 10913 *ext = (struct rtw89_hw_scan_extra_op){ 10914 .set = true, 10915 .macid = tmp_link->mac_id, 10916 .port = tmp_link->port, 10917 .chan = *tmp_chan, 10918 .rtwvif_link = tmp_link, 10919 }; 10920 10921 rtw89_debug(rtwdev, RTW89_DBG_HW_SCAN, 10922 "hw scan: extra op: center %d primary %d\n", 10923 ext->chan.channel, ext->chan.primary_channel); 10924 break; 10925 } 10926 } 10927 10928 int rtw89_hw_scan_start(struct rtw89_dev *rtwdev, 10929 struct rtw89_vif_link *rtwvif_link, 10930 struct ieee80211_scan_request *scan_req) 10931 { 10932 enum rtw89_entity_mode mode = rtw89_get_entity_mode(rtwdev); 10933 struct cfg80211_scan_request *req = &scan_req->req; 10934 const struct rtw89_chan *chan = rtw89_chan_get(rtwdev, 10935 rtwvif_link->chanctx_idx); 10936 struct rtw89_vif *rtwvif = rtwvif_link->rtwvif; 10937 struct rtw89_chanctx_pause_parm pause_parm = { 10938 .rsn = RTW89_CHANCTX_PAUSE_REASON_HW_SCAN, 10939 .trigger = rtwvif_link, 10940 }; 10941 u32 rx_fltr = rtwdev->hal.rx_fltr; 10942 u8 mac_addr[ETH_ALEN]; 10943 int ret; 10944 10945 /* clone op and keep it during scan */ 10946 rtwdev->scan_info.op_chan = *chan; 10947 10948 rtw89_debug(rtwdev, RTW89_DBG_HW_SCAN, 10949 "hw scan: op: center %d primary %d\n", 10950 chan->channel, chan->primary_channel); 10951 10952 rtw89_hw_scan_set_extra_op_info(rtwdev, rtwvif, chan); 10953 10954 rtwdev->scan_info.connected = rtw89_is_any_vif_connected_or_connecting(rtwdev); 10955 rtwdev->scan_info.scanning_vif = rtwvif_link; 10956 rtwdev->scan_info.abort = false; 10957 rtwdev->scan_info.delay = 0; 10958 rtwvif->scan_ies = &scan_req->ies; 10959 rtwvif->scan_req = req; 10960 rtw89_hw_scan_calc_req_ssid(rtwdev, rtwvif_link, false); 10961 10962 memset(rtwdev->scan_info.wildcard_pkt_id, RTW89_SCANOFLD_PKT_NONE, 10963 sizeof(rtwdev->scan_info.wildcard_pkt_id)); 10964 10965 if (req->flags & NL80211_SCAN_FLAG_RANDOM_ADDR) 10966 get_random_mask_addr(mac_addr, req->mac_addr, 10967 req->mac_addr_mask); 10968 else 10969 ether_addr_copy(mac_addr, rtwvif_link->mac_addr); 10970 10971 ret = rtw89_hw_scan_prehandle(rtwdev, rtwvif_link, mac_addr); 10972 if (ret) { 10973 rtw89_hw_scan_cleanup(rtwdev, rtwvif_link); 10974 return ret; 10975 } 10976 10977 ieee80211_stop_queues(rtwdev->hw); 10978 rtw89_mac_port_cfg_rx_sync(rtwdev, rtwvif_link, false); 10979 10980 rtw89_core_scan_start(rtwdev, rtwvif_link, mac_addr, true); 10981 10982 rx_fltr &= ~B_AX_A_BCN_CHK_EN; 10983 rx_fltr &= ~B_AX_A_BC; 10984 rx_fltr &= ~B_AX_A_A1_MATCH; 10985 10986 rtw89_mac_set_rx_fltr(rtwdev, rtwvif_link->mac_idx, rx_fltr); 10987 10988 rtw89_chanctx_pause(rtwdev, &pause_parm); 10989 rtw89_phy_dig_suspend(rtwdev); 10990 10991 if (mode == RTW89_ENTITY_MODE_MCC) 10992 rtw89_hw_scan_update_beacon_noa(rtwdev, true); 10993 10994 return 0; 10995 } 10996 10997 struct rtw89_hw_scan_complete_cb_data { 10998 struct rtw89_vif_link *rtwvif_link; 10999 bool aborted; 11000 }; 11001 11002 static int rtw89_hw_scan_complete_cb(struct rtw89_dev *rtwdev, void *data) 11003 { 11004 enum rtw89_entity_mode mode = rtw89_get_entity_mode(rtwdev); 11005 struct rtw89_hw_scan_complete_cb_data *cb_data = data; 11006 struct rtw89_vif_link *rtwvif_link = cb_data->rtwvif_link; 11007 struct cfg80211_scan_info info = { 11008 .aborted = cb_data->aborted, 11009 }; 11010 11011 if (!rtwvif_link) 11012 return -EINVAL; 11013 11014 rtw89_mac_set_rx_fltr(rtwdev, rtwvif_link->mac_idx, rtwdev->hal.rx_fltr); 11015 11016 rtw89_core_scan_complete(rtwdev, rtwvif_link, true); 11017 ieee80211_scan_completed(rtwdev->hw, &info); 11018 ieee80211_wake_queues(rtwdev->hw); 11019 rtw89_mac_port_cfg_rx_sync(rtwdev, rtwvif_link, true); 11020 rtw89_mac_enable_beacon_for_ap_vifs(rtwdev, true); 11021 rtw89_phy_dig_resume(rtwdev, true); 11022 11023 rtw89_hw_scan_cleanup(rtwdev, rtwvif_link); 11024 11025 if (mode == RTW89_ENTITY_MODE_MCC) 11026 rtw89_hw_scan_update_beacon_noa(rtwdev, false); 11027 11028 return 0; 11029 } 11030 11031 void rtw89_hw_scan_complete(struct rtw89_dev *rtwdev, 11032 struct rtw89_vif_link *rtwvif_link, 11033 bool aborted) 11034 { 11035 struct rtw89_hw_scan_complete_cb_data cb_data = { 11036 .rtwvif_link = rtwvif_link, 11037 .aborted = aborted, 11038 }; 11039 const struct rtw89_chanctx_cb_parm cb_parm = { 11040 .cb = rtw89_hw_scan_complete_cb, 11041 .data = &cb_data, 11042 .caller = __func__, 11043 }; 11044 11045 /* The things here needs to be done after setting channel (for coex) 11046 * and before proceeding entity mode (for MCC). So, pass a callback 11047 * of them for the right sequence rather than doing them directly. 11048 */ 11049 rtw89_chanctx_proceed(rtwdev, &cb_parm); 11050 } 11051 11052 void rtw89_hw_scan_abort(struct rtw89_dev *rtwdev, 11053 struct rtw89_vif_link *rtwvif_link) 11054 { 11055 struct rtw89_hw_scan_info *scan_info = &rtwdev->scan_info; 11056 int ret; 11057 11058 scan_info->abort = true; 11059 11060 ret = rtw89_hw_scan_offload(rtwdev, rtwvif_link, false); 11061 if (ret) 11062 rtw89_warn(rtwdev, "rtw89_hw_scan_offload failed ret %d\n", ret); 11063 11064 /* Indicate ieee80211_scan_completed() before returning, which is safe 11065 * because scan abort command always waits for completion of 11066 * RTW89_SCAN_END_SCAN_NOTIFY, so that ieee80211_stop() can flush scan 11067 * work properly. 11068 */ 11069 rtw89_hw_scan_complete(rtwdev, rtwvif_link, true); 11070 } 11071 11072 static bool rtw89_is_any_vif_connected_or_connecting(struct rtw89_dev *rtwdev) 11073 { 11074 struct rtw89_vif_link *rtwvif_link; 11075 struct rtw89_vif *rtwvif; 11076 unsigned int link_id; 11077 11078 rtw89_for_each_rtwvif(rtwdev, rtwvif) { 11079 rtw89_vif_for_each_link(rtwvif, rtwvif_link, link_id) { 11080 /* This variable implies connected or during attempt to connect */ 11081 if (!is_zero_ether_addr(rtwvif_link->bssid)) 11082 return true; 11083 } 11084 } 11085 11086 return false; 11087 } 11088 11089 int rtw89_hw_scan_offload(struct rtw89_dev *rtwdev, 11090 struct rtw89_vif_link *rtwvif_link, 11091 bool enable) 11092 { 11093 const struct rtw89_mac_gen_def *mac = rtwdev->chip->mac_def; 11094 struct rtw89_hw_scan_info *scan_info = &rtwdev->scan_info; 11095 const struct rtw89_hw_scan_extra_op *ext = &scan_info->extra_op; 11096 struct rtw89_scan_option opt = {0}; 11097 bool connected; 11098 int ret = 0; 11099 11100 if (!rtwvif_link) 11101 return -EINVAL; 11102 11103 connected = rtwdev->scan_info.connected; 11104 opt.enable = enable; 11105 opt.target_ch_mode = connected; 11106 opt.delay = rtwdev->scan_info.delay; 11107 if (enable) { 11108 ret = mac->add_chan_list(rtwdev, rtwvif_link); 11109 if (ret) 11110 goto out; 11111 } 11112 11113 if (rtwdev->chip->chip_gen == RTW89_CHIP_BE) { 11114 opt.operation = enable ? RTW89_SCAN_OP_START : RTW89_SCAN_OP_STOP; 11115 opt.scan_mode = RTW89_SCAN_MODE_SA; 11116 opt.band = rtwvif_link->mac_idx; 11117 opt.num_macc_role = 0; 11118 opt.mlo_mode = rtwdev->mlo_dbcc_mode; 11119 opt.num_opch = connected ? 1 : 0; 11120 if (connected && ext->set) 11121 opt.num_opch++; 11122 11123 opt.opch_end = connected ? 0 : RTW89_CHAN_INVALID; 11124 } 11125 11126 ret = rtw89_mac_scan_offload(rtwdev, &opt, rtwvif_link, false); 11127 11128 out: 11129 return ret; 11130 } 11131 11132 #define H2C_FW_CPU_EXCEPTION_TYPE_0 0x5566 11133 #define H2C_FW_CPU_EXCEPTION_TYPE_1 0x0 11134 int rtw89_fw_h2c_trigger_cpu_exception(struct rtw89_dev *rtwdev) 11135 { 11136 struct rtw89_h2c_trig_cpu_except *h2c; 11137 u32 cpu_exception_type_def; 11138 u32 len = sizeof(*h2c); 11139 struct sk_buff *skb; 11140 int ret; 11141 11142 if (RTW89_CHK_FW_FEATURE(CRASH_TRIGGER_TYPE_1, &rtwdev->fw)) 11143 cpu_exception_type_def = H2C_FW_CPU_EXCEPTION_TYPE_1; 11144 else if (RTW89_CHK_FW_FEATURE(CRASH_TRIGGER_TYPE_0, &rtwdev->fw)) 11145 cpu_exception_type_def = H2C_FW_CPU_EXCEPTION_TYPE_0; 11146 else 11147 return -EOPNOTSUPP; 11148 11149 skb = rtw89_fw_h2c_alloc_skb_with_hdr(rtwdev, len); 11150 if (!skb) { 11151 rtw89_err(rtwdev, 11152 "failed to alloc skb for fw cpu exception\n"); 11153 return -ENOMEM; 11154 } 11155 11156 skb_put(skb, len); 11157 h2c = (struct rtw89_h2c_trig_cpu_except *)skb->data; 11158 11159 h2c->w0 = le32_encode_bits(cpu_exception_type_def, 11160 RTW89_H2C_CPU_EXCEPTION_TYPE); 11161 11162 rtw89_h2c_pkt_set_hdr(rtwdev, skb, FWCMD_TYPE_H2C, 11163 H2C_CAT_TEST, 11164 H2C_CL_FW_STATUS_TEST, 11165 H2C_FUNC_CPU_EXCEPTION, 0, 0, 11166 len); 11167 11168 ret = rtw89_h2c_tx(rtwdev, skb, false); 11169 if (ret) { 11170 rtw89_err(rtwdev, "failed to send h2c\n"); 11171 dev_kfree_skb_any(skb); 11172 return ret; 11173 } 11174 11175 return 0; 11176 } 11177 11178 #define H2C_PKT_DROP_LEN 24 11179 int rtw89_fw_h2c_pkt_drop(struct rtw89_dev *rtwdev, 11180 const struct rtw89_pkt_drop_params *params) 11181 { 11182 struct sk_buff *skb; 11183 int ret; 11184 11185 skb = rtw89_fw_h2c_alloc_skb_with_hdr(rtwdev, H2C_PKT_DROP_LEN); 11186 if (!skb) { 11187 rtw89_err(rtwdev, 11188 "failed to alloc skb for packet drop\n"); 11189 return -ENOMEM; 11190 } 11191 11192 switch (params->sel) { 11193 case RTW89_PKT_DROP_SEL_MACID_BE_ONCE: 11194 case RTW89_PKT_DROP_SEL_MACID_BK_ONCE: 11195 case RTW89_PKT_DROP_SEL_MACID_VI_ONCE: 11196 case RTW89_PKT_DROP_SEL_MACID_VO_ONCE: 11197 case RTW89_PKT_DROP_SEL_BAND_ONCE: 11198 break; 11199 default: 11200 rtw89_debug(rtwdev, RTW89_DBG_FW, 11201 "H2C of pkt drop might not fully support sel: %d yet\n", 11202 params->sel); 11203 break; 11204 } 11205 11206 skb_put(skb, H2C_PKT_DROP_LEN); 11207 RTW89_SET_FWCMD_PKT_DROP_SEL(skb->data, params->sel); 11208 RTW89_SET_FWCMD_PKT_DROP_MACID(skb->data, params->macid); 11209 RTW89_SET_FWCMD_PKT_DROP_BAND(skb->data, params->mac_band); 11210 RTW89_SET_FWCMD_PKT_DROP_PORT(skb->data, params->port); 11211 RTW89_SET_FWCMD_PKT_DROP_MBSSID(skb->data, params->mbssid); 11212 RTW89_SET_FWCMD_PKT_DROP_ROLE_A_INFO_TF_TRS(skb->data, params->tf_trs); 11213 RTW89_SET_FWCMD_PKT_DROP_MACID_BAND_SEL_0(skb->data, 11214 params->macid_band_sel[0]); 11215 RTW89_SET_FWCMD_PKT_DROP_MACID_BAND_SEL_1(skb->data, 11216 params->macid_band_sel[1]); 11217 RTW89_SET_FWCMD_PKT_DROP_MACID_BAND_SEL_2(skb->data, 11218 params->macid_band_sel[2]); 11219 RTW89_SET_FWCMD_PKT_DROP_MACID_BAND_SEL_3(skb->data, 11220 params->macid_band_sel[3]); 11221 11222 rtw89_h2c_pkt_set_hdr(rtwdev, skb, FWCMD_TYPE_H2C, 11223 H2C_CAT_MAC, 11224 H2C_CL_MAC_FW_OFLD, 11225 H2C_FUNC_PKT_DROP, 0, 0, 11226 H2C_PKT_DROP_LEN); 11227 11228 ret = rtw89_h2c_tx(rtwdev, skb, false); 11229 if (ret) { 11230 rtw89_err(rtwdev, "failed to send h2c\n"); 11231 goto fail; 11232 } 11233 11234 return 0; 11235 11236 fail: 11237 dev_kfree_skb_any(skb); 11238 return ret; 11239 } 11240 11241 #define H2C_KEEP_ALIVE_LEN 4 11242 int rtw89_fw_h2c_keep_alive(struct rtw89_dev *rtwdev, struct rtw89_vif_link *rtwvif_link, 11243 bool enable) 11244 { 11245 struct sk_buff *skb; 11246 u8 pkt_id = 0; 11247 int ret; 11248 11249 if (enable) { 11250 ret = rtw89_fw_h2c_add_general_pkt(rtwdev, rtwvif_link, 11251 RTW89_PKT_OFLD_TYPE_ARP_RSP, 11252 &pkt_id); 11253 if (ret) 11254 return -EPERM; 11255 } 11256 11257 skb = rtw89_fw_h2c_alloc_skb_with_hdr(rtwdev, H2C_KEEP_ALIVE_LEN); 11258 if (!skb) { 11259 rtw89_err(rtwdev, "failed to alloc skb for keep alive\n"); 11260 return -ENOMEM; 11261 } 11262 11263 skb_put(skb, H2C_KEEP_ALIVE_LEN); 11264 11265 RTW89_SET_KEEP_ALIVE_ENABLE(skb->data, enable); 11266 RTW89_SET_KEEP_ALIVE_PKT_NULL_ID(skb->data, pkt_id); 11267 RTW89_SET_KEEP_ALIVE_PERIOD(skb->data, 5); 11268 RTW89_SET_KEEP_ALIVE_MACID(skb->data, rtwvif_link->mac_id); 11269 11270 rtw89_h2c_pkt_set_hdr(rtwdev, skb, FWCMD_TYPE_H2C, 11271 H2C_CAT_MAC, 11272 H2C_CL_MAC_WOW, 11273 H2C_FUNC_KEEP_ALIVE, 0, 1, 11274 H2C_KEEP_ALIVE_LEN); 11275 11276 ret = rtw89_h2c_tx(rtwdev, skb, false); 11277 if (ret) { 11278 rtw89_err(rtwdev, "failed to send h2c\n"); 11279 goto fail; 11280 } 11281 11282 return 0; 11283 11284 fail: 11285 dev_kfree_skb_any(skb); 11286 11287 return ret; 11288 } 11289 11290 int rtw89_fw_h2c_arp_offload(struct rtw89_dev *rtwdev, struct rtw89_vif_link *rtwvif_link, 11291 bool enable) 11292 { 11293 struct rtw89_h2c_arp_offload *h2c; 11294 u32 len = sizeof(*h2c); 11295 struct sk_buff *skb; 11296 u8 pkt_id = 0; 11297 int ret; 11298 11299 if (enable) { 11300 ret = rtw89_fw_h2c_add_general_pkt(rtwdev, rtwvif_link, 11301 RTW89_PKT_OFLD_TYPE_ARP_RSP, 11302 &pkt_id); 11303 if (ret) 11304 return ret; 11305 } 11306 11307 skb = rtw89_fw_h2c_alloc_skb_with_hdr(rtwdev, len); 11308 if (!skb) { 11309 rtw89_err(rtwdev, "failed to alloc skb for arp offload\n"); 11310 return -ENOMEM; 11311 } 11312 11313 skb_put(skb, len); 11314 h2c = (struct rtw89_h2c_arp_offload *)skb->data; 11315 11316 h2c->w0 = le32_encode_bits(enable, RTW89_H2C_ARP_OFFLOAD_W0_ENABLE) | 11317 le32_encode_bits(0, RTW89_H2C_ARP_OFFLOAD_W0_ACTION) | 11318 le32_encode_bits(rtwvif_link->mac_id, RTW89_H2C_ARP_OFFLOAD_W0_MACID) | 11319 le32_encode_bits(pkt_id, RTW89_H2C_ARP_OFFLOAD_W0_PKT_ID); 11320 11321 rtw89_h2c_pkt_set_hdr(rtwdev, skb, FWCMD_TYPE_H2C, 11322 H2C_CAT_MAC, 11323 H2C_CL_MAC_WOW, 11324 H2C_FUNC_ARP_OFLD, 0, 1, 11325 len); 11326 11327 ret = rtw89_h2c_tx(rtwdev, skb, false); 11328 if (ret) { 11329 rtw89_err(rtwdev, "failed to send h2c\n"); 11330 goto fail; 11331 } 11332 11333 return 0; 11334 11335 fail: 11336 dev_kfree_skb_any(skb); 11337 11338 return ret; 11339 } 11340 11341 #define H2C_DISCONNECT_DETECT_LEN 8 11342 int rtw89_fw_h2c_disconnect_detect(struct rtw89_dev *rtwdev, 11343 struct rtw89_vif_link *rtwvif_link, bool enable) 11344 { 11345 struct rtw89_wow_param *rtw_wow = &rtwdev->wow; 11346 struct sk_buff *skb; 11347 u8 macid = rtwvif_link->mac_id; 11348 int ret; 11349 11350 skb = rtw89_fw_h2c_alloc_skb_with_hdr(rtwdev, H2C_DISCONNECT_DETECT_LEN); 11351 if (!skb) { 11352 rtw89_err(rtwdev, "failed to alloc skb for keep alive\n"); 11353 return -ENOMEM; 11354 } 11355 11356 skb_put(skb, H2C_DISCONNECT_DETECT_LEN); 11357 11358 if (test_bit(RTW89_WOW_FLAG_EN_DISCONNECT, rtw_wow->flags)) { 11359 RTW89_SET_DISCONNECT_DETECT_ENABLE(skb->data, enable); 11360 RTW89_SET_DISCONNECT_DETECT_DISCONNECT(skb->data, !enable); 11361 RTW89_SET_DISCONNECT_DETECT_MAC_ID(skb->data, macid); 11362 RTW89_SET_DISCONNECT_DETECT_CHECK_PERIOD(skb->data, 100); 11363 RTW89_SET_DISCONNECT_DETECT_TRY_PKT_COUNT(skb->data, 5); 11364 } 11365 11366 rtw89_h2c_pkt_set_hdr(rtwdev, skb, FWCMD_TYPE_H2C, 11367 H2C_CAT_MAC, 11368 H2C_CL_MAC_WOW, 11369 H2C_FUNC_DISCONNECT_DETECT, 0, 1, 11370 H2C_DISCONNECT_DETECT_LEN); 11371 11372 ret = rtw89_h2c_tx(rtwdev, skb, false); 11373 if (ret) { 11374 rtw89_err(rtwdev, "failed to send h2c\n"); 11375 goto fail; 11376 } 11377 11378 return 0; 11379 11380 fail: 11381 dev_kfree_skb_any(skb); 11382 11383 return ret; 11384 } 11385 11386 int rtw89_fw_h2c_cfg_pno(struct rtw89_dev *rtwdev, struct rtw89_vif_link *rtwvif_link, 11387 bool enable) 11388 { 11389 struct rtw89_wow_param *rtw_wow = &rtwdev->wow; 11390 struct cfg80211_sched_scan_request *nd_config = rtw_wow->nd_config; 11391 struct rtw89_h2c_cfg_nlo *h2c; 11392 u32 len = sizeof(*h2c); 11393 struct sk_buff *skb; 11394 int ret, i; 11395 11396 skb = rtw89_fw_h2c_alloc_skb_with_hdr(rtwdev, len); 11397 if (!skb) { 11398 rtw89_err(rtwdev, "failed to alloc skb for nlo\n"); 11399 return -ENOMEM; 11400 } 11401 11402 skb_put(skb, len); 11403 h2c = (struct rtw89_h2c_cfg_nlo *)skb->data; 11404 11405 h2c->w0 = le32_encode_bits(enable, RTW89_H2C_NLO_W0_ENABLE) | 11406 le32_encode_bits(enable, RTW89_H2C_NLO_W0_IGNORE_CIPHER) | 11407 le32_encode_bits(rtwvif_link->mac_id, RTW89_H2C_NLO_W0_MACID); 11408 11409 if (enable) { 11410 h2c->nlo_cnt = nd_config->n_match_sets; 11411 for (i = 0 ; i < nd_config->n_match_sets; i++) { 11412 h2c->ssid_len[i] = nd_config->match_sets[i].ssid.ssid_len; 11413 memcpy(h2c->ssid[i], nd_config->match_sets[i].ssid.ssid, 11414 nd_config->match_sets[i].ssid.ssid_len); 11415 } 11416 } 11417 11418 rtw89_h2c_pkt_set_hdr(rtwdev, skb, FWCMD_TYPE_H2C, 11419 H2C_CAT_MAC, 11420 H2C_CL_MAC_WOW, 11421 H2C_FUNC_NLO, 0, 1, 11422 len); 11423 11424 ret = rtw89_h2c_tx(rtwdev, skb, false); 11425 if (ret) { 11426 rtw89_err(rtwdev, "failed to send h2c\n"); 11427 goto fail; 11428 } 11429 11430 return 0; 11431 11432 fail: 11433 dev_kfree_skb_any(skb); 11434 return ret; 11435 } 11436 11437 int rtw89_fw_h2c_wow_global(struct rtw89_dev *rtwdev, struct rtw89_vif_link *rtwvif_link, 11438 bool enable) 11439 { 11440 struct rtw89_wow_param *rtw_wow = &rtwdev->wow; 11441 struct rtw89_h2c_wow_global *h2c; 11442 u8 macid = rtwvif_link->mac_id; 11443 u32 len = sizeof(*h2c); 11444 struct sk_buff *skb; 11445 int ret; 11446 11447 skb = rtw89_fw_h2c_alloc_skb_with_hdr(rtwdev, len); 11448 if (!skb) { 11449 rtw89_err(rtwdev, "failed to alloc skb for wow global\n"); 11450 return -ENOMEM; 11451 } 11452 11453 skb_put(skb, len); 11454 h2c = (struct rtw89_h2c_wow_global *)skb->data; 11455 11456 h2c->w0 = le32_encode_bits(enable, RTW89_H2C_WOW_GLOBAL_W0_ENABLE) | 11457 le32_encode_bits(macid, RTW89_H2C_WOW_GLOBAL_W0_MAC_ID) | 11458 le32_encode_bits(rtw_wow->ptk_alg, 11459 RTW89_H2C_WOW_GLOBAL_W0_PAIRWISE_SEC_ALGO) | 11460 le32_encode_bits(rtw_wow->gtk_alg, 11461 RTW89_H2C_WOW_GLOBAL_W0_GROUP_SEC_ALGO); 11462 h2c->key_info = rtw_wow->key_info; 11463 11464 rtw89_h2c_pkt_set_hdr(rtwdev, skb, FWCMD_TYPE_H2C, 11465 H2C_CAT_MAC, 11466 H2C_CL_MAC_WOW, 11467 H2C_FUNC_WOW_GLOBAL, 0, 1, 11468 len); 11469 11470 ret = rtw89_h2c_tx(rtwdev, skb, false); 11471 if (ret) { 11472 rtw89_err(rtwdev, "failed to send h2c\n"); 11473 goto fail; 11474 } 11475 11476 return 0; 11477 11478 fail: 11479 dev_kfree_skb_any(skb); 11480 11481 return ret; 11482 } 11483 11484 int rtw89_fw_h2c_wow_wakeup_ctrl(struct rtw89_dev *rtwdev, 11485 struct rtw89_vif_link *rtwvif_link, 11486 bool enable) 11487 { 11488 struct ieee80211_vif *vif = rtwvif_link_to_vif(rtwvif_link); 11489 struct rtw89_wow_param *rtw_wow = &rtwdev->wow; 11490 struct rtw89_h2c_wow_wakeup_ctrl *h2c; 11491 struct sk_buff *skb; 11492 u32 len = sizeof(*h2c); 11493 u8 macid = rtwvif_link->mac_id; 11494 int ret; 11495 11496 skb = rtw89_fw_h2c_alloc_skb_with_hdr(rtwdev, len); 11497 if (!skb) { 11498 rtw89_err(rtwdev, "failed to alloc skb for wakeup ctrl\n"); 11499 return -ENOMEM; 11500 } 11501 11502 skb_put(skb, len); 11503 h2c = (struct rtw89_h2c_wow_wakeup_ctrl *)skb->data; 11504 11505 if (rtw_wow->pattern_cnt) 11506 h2c->w0 |= le32_encode_bits(enable, 11507 RTW89_H2C_WOW_WAKEUP_CTRL_W0_PATTERN_MATCH_ENABLE); 11508 if (test_bit(RTW89_WOW_FLAG_EN_MAGIC_PKT, rtw_wow->flags)) { 11509 h2c->w0 |= le32_encode_bits(enable, 11510 RTW89_H2C_WOW_WAKEUP_CTRL_W0_MAGIC_ENABLE); 11511 if (ieee80211_vif_is_mld(vif)) 11512 h2c->w0 |= le32_encode_bits(enable, 11513 RTW89_H2C_WOW_WAKEUP_CTRL_W0_MAGIC_MLD_ENABLE); 11514 } 11515 11516 if (test_bit(RTW89_WOW_FLAG_EN_DISCONNECT, rtw_wow->flags)) 11517 h2c->w0 |= le32_encode_bits(enable, 11518 RTW89_H2C_WOW_WAKEUP_CTRL_W0_DEAUTH_ENABLE); 11519 11520 h2c->w0 |= le32_encode_bits(macid, RTW89_H2C_WOW_WAKEUP_CTRL_W0_MAC_ID); 11521 11522 rtw89_h2c_pkt_set_hdr(rtwdev, skb, FWCMD_TYPE_H2C, 11523 H2C_CAT_MAC, 11524 H2C_CL_MAC_WOW, 11525 H2C_FUNC_WAKEUP_CTRL, 0, 1, 11526 len); 11527 11528 ret = rtw89_h2c_tx(rtwdev, skb, false); 11529 if (ret) { 11530 rtw89_err(rtwdev, "failed to send h2c\n"); 11531 goto fail; 11532 } 11533 11534 return 0; 11535 11536 fail: 11537 dev_kfree_skb_any(skb); 11538 11539 return ret; 11540 } 11541 11542 int rtw89_fw_h2c_wow_cam_update(struct rtw89_dev *rtwdev, 11543 struct rtw89_wow_cam_info *cam_info) 11544 { 11545 struct rtw89_h2c_wow_cam_update *h2c; 11546 u32 len = sizeof(*h2c); 11547 struct sk_buff *skb; 11548 int ret; 11549 11550 skb = rtw89_fw_h2c_alloc_skb_with_hdr(rtwdev, len); 11551 if (!skb) { 11552 rtw89_err(rtwdev, "failed to alloc skb for wow cam update\n"); 11553 return -ENOMEM; 11554 } 11555 skb_put(skb, len); 11556 h2c = (struct rtw89_h2c_wow_cam_update *)skb->data; 11557 11558 h2c->w0 = le32_encode_bits(cam_info->r_w, RTW89_H2C_WOW_CAM_UPD_W0_R_W) | 11559 le32_encode_bits(cam_info->idx, RTW89_H2C_WOW_CAM_UPD_W0_IDX); 11560 11561 if (!cam_info->valid) 11562 goto fill_valid; 11563 11564 h2c->wkfm0 = cam_info->mask[0]; 11565 h2c->wkfm1 = cam_info->mask[1]; 11566 h2c->wkfm2 = cam_info->mask[2]; 11567 h2c->wkfm3 = cam_info->mask[3]; 11568 h2c->w5 = le32_encode_bits(cam_info->crc, RTW89_H2C_WOW_CAM_UPD_W5_CRC) | 11569 le32_encode_bits(cam_info->negative_pattern_match, 11570 RTW89_H2C_WOW_CAM_UPD_W5_NEGATIVE_PATTERN_MATCH) | 11571 le32_encode_bits(cam_info->skip_mac_hdr, 11572 RTW89_H2C_WOW_CAM_UPD_W5_SKIP_MAC_HDR) | 11573 le32_encode_bits(cam_info->uc, RTW89_H2C_WOW_CAM_UPD_W5_UC) | 11574 le32_encode_bits(cam_info->mc, RTW89_H2C_WOW_CAM_UPD_W5_MC) | 11575 le32_encode_bits(cam_info->bc, RTW89_H2C_WOW_CAM_UPD_W5_BC); 11576 fill_valid: 11577 h2c->w5 |= le32_encode_bits(cam_info->valid, RTW89_H2C_WOW_CAM_UPD_W5_VALID); 11578 11579 rtw89_h2c_pkt_set_hdr(rtwdev, skb, FWCMD_TYPE_H2C, 11580 H2C_CAT_MAC, 11581 H2C_CL_MAC_WOW, 11582 H2C_FUNC_WOW_CAM_UPD, 0, 1, 11583 len); 11584 11585 ret = rtw89_h2c_tx(rtwdev, skb, false); 11586 if (ret) { 11587 rtw89_err(rtwdev, "failed to send h2c\n"); 11588 goto fail; 11589 } 11590 11591 return 0; 11592 fail: 11593 dev_kfree_skb_any(skb); 11594 11595 return ret; 11596 } 11597 EXPORT_SYMBOL(rtw89_fw_h2c_wow_cam_update); 11598 11599 int rtw89_fw_h2c_wow_cam_update_v1(struct rtw89_dev *rtwdev, 11600 struct rtw89_wow_cam_info *cam_info) 11601 { 11602 struct rtw89_h2c_wow_payload_cam_update *h2c; 11603 u32 len = sizeof(*h2c); 11604 struct sk_buff *skb; 11605 int ret; 11606 11607 skb = rtw89_fw_h2c_alloc_skb_with_hdr(rtwdev, len); 11608 if (!skb) { 11609 rtw89_err(rtwdev, "failed to alloc skb for wow payload cam update\n"); 11610 return -ENOMEM; 11611 } 11612 skb_put(skb, len); 11613 h2c = (struct rtw89_h2c_wow_payload_cam_update *)skb->data; 11614 11615 h2c->w0 = le32_encode_bits(cam_info->r_w, RTW89_H2C_WOW_PLD_CAM_UPD_W0_R_W) | 11616 le32_encode_bits(cam_info->idx, RTW89_H2C_WOW_PLD_CAM_UPD_W0_IDX); 11617 h2c->w8 = le32_encode_bits(cam_info->valid, RTW89_H2C_WOW_PLD_CAM_UPD_W8_VALID) | 11618 le32_encode_bits(1, RTW89_H2C_WOW_PLD_CAM_UPD_W8_WOW_PTR); 11619 11620 if (!cam_info->valid) 11621 goto done; 11622 11623 h2c->wkfm0 = cam_info->mask[0]; 11624 h2c->wkfm1 = cam_info->mask[1]; 11625 h2c->wkfm2 = cam_info->mask[2]; 11626 h2c->wkfm3 = cam_info->mask[3]; 11627 h2c->w5 = le32_encode_bits(cam_info->uc, RTW89_H2C_WOW_PLD_CAM_UPD_W5_UC) | 11628 le32_encode_bits(cam_info->mc, RTW89_H2C_WOW_PLD_CAM_UPD_W5_MC) | 11629 le32_encode_bits(cam_info->bc, RTW89_H2C_WOW_PLD_CAM_UPD_W5_BC) | 11630 le32_encode_bits(cam_info->skip_mac_hdr, 11631 RTW89_H2C_WOW_PLD_CAM_UPD_W5_SKIP_MAC_HDR); 11632 h2c->w6 = le32_encode_bits(cam_info->crc, RTW89_H2C_WOW_PLD_CAM_UPD_W6_CRC); 11633 h2c->w7 = le32_encode_bits(cam_info->negative_pattern_match, 11634 RTW89_H2C_WOW_PLD_CAM_UPD_W7_NEGATIVE_PATTERN_MATCH); 11635 11636 done: 11637 rtw89_h2c_pkt_set_hdr(rtwdev, skb, FWCMD_TYPE_H2C, 11638 H2C_CAT_MAC, 11639 H2C_CL_MAC_WOW, 11640 H2C_FUNC_WOW_PLD_CAM_UPD, 0, 1, 11641 len); 11642 11643 ret = rtw89_h2c_tx(rtwdev, skb, false); 11644 if (ret) { 11645 rtw89_err(rtwdev, "failed to send h2c\n"); 11646 goto fail; 11647 } 11648 11649 return 0; 11650 fail: 11651 dev_kfree_skb_any(skb); 11652 11653 return ret; 11654 } 11655 EXPORT_SYMBOL(rtw89_fw_h2c_wow_cam_update_v1); 11656 11657 int rtw89_fw_h2c_wow_gtk_ofld(struct rtw89_dev *rtwdev, 11658 struct rtw89_vif_link *rtwvif_link, 11659 bool enable) 11660 { 11661 struct rtw89_wow_param *rtw_wow = &rtwdev->wow; 11662 struct rtw89_wow_gtk_info *gtk_info = &rtw_wow->gtk_info; 11663 struct rtw89_h2c_wow_gtk_ofld *h2c; 11664 u8 macid = rtwvif_link->mac_id; 11665 u32 len = sizeof(*h2c); 11666 u8 pkt_id_sa_query = 0; 11667 struct sk_buff *skb; 11668 u8 pkt_id_eapol = 0; 11669 int ret; 11670 11671 if (!rtw_wow->gtk_alg) 11672 return 0; 11673 11674 skb = rtw89_fw_h2c_alloc_skb_with_hdr(rtwdev, len); 11675 if (!skb) { 11676 rtw89_err(rtwdev, "failed to alloc skb for gtk ofld\n"); 11677 return -ENOMEM; 11678 } 11679 11680 skb_put(skb, len); 11681 h2c = (struct rtw89_h2c_wow_gtk_ofld *)skb->data; 11682 11683 if (!enable) 11684 goto hdr; 11685 11686 ret = rtw89_fw_h2c_add_general_pkt(rtwdev, rtwvif_link, 11687 RTW89_PKT_OFLD_TYPE_EAPOL_KEY, 11688 &pkt_id_eapol); 11689 if (ret) 11690 goto fail; 11691 11692 if (gtk_info->igtk_keyid) { 11693 ret = rtw89_fw_h2c_add_general_pkt(rtwdev, rtwvif_link, 11694 RTW89_PKT_OFLD_TYPE_SA_QUERY, 11695 &pkt_id_sa_query); 11696 if (ret) 11697 goto fail; 11698 } 11699 11700 h2c->w0 = le32_encode_bits(enable, RTW89_H2C_WOW_GTK_OFLD_W0_EN) | 11701 le32_encode_bits(!!memchr_inv(gtk_info->txmickey, 0, 11702 sizeof(gtk_info->txmickey)), 11703 RTW89_H2C_WOW_GTK_OFLD_W0_TKIP_EN) | 11704 le32_encode_bits(gtk_info->igtk_keyid ? 1 : 0, 11705 RTW89_H2C_WOW_GTK_OFLD_W0_IEEE80211W_EN) | 11706 le32_encode_bits(macid, RTW89_H2C_WOW_GTK_OFLD_W0_MAC_ID) | 11707 le32_encode_bits(pkt_id_eapol, RTW89_H2C_WOW_GTK_OFLD_W0_GTK_RSP_ID); 11708 h2c->w1 = le32_encode_bits(gtk_info->igtk_keyid ? pkt_id_sa_query : 0, 11709 RTW89_H2C_WOW_GTK_OFLD_W1_PMF_SA_QUERY_ID) | 11710 le32_encode_bits(rtw_wow->akm, RTW89_H2C_WOW_GTK_OFLD_W1_ALGO_AKM_SUIT); 11711 h2c->gtk_info = rtw_wow->gtk_info; 11712 11713 hdr: 11714 rtw89_h2c_pkt_set_hdr(rtwdev, skb, FWCMD_TYPE_H2C, 11715 H2C_CAT_MAC, 11716 H2C_CL_MAC_WOW, 11717 H2C_FUNC_GTK_OFLD, 0, 1, 11718 len); 11719 11720 ret = rtw89_h2c_tx(rtwdev, skb, false); 11721 if (ret) { 11722 rtw89_err(rtwdev, "failed to send h2c\n"); 11723 goto fail; 11724 } 11725 return 0; 11726 fail: 11727 dev_kfree_skb_any(skb); 11728 11729 return ret; 11730 } 11731 11732 int rtw89_fw_h2c_fwips(struct rtw89_dev *rtwdev, struct rtw89_vif_link *rtwvif_link, 11733 bool enable) 11734 { 11735 struct rtw89_wait_info *wait = &rtwdev->mac.ps_wait; 11736 struct rtw89_h2c_fwips *h2c; 11737 u32 len = sizeof(*h2c); 11738 struct sk_buff *skb; 11739 11740 skb = rtw89_fw_h2c_alloc_skb_with_hdr(rtwdev, len); 11741 if (!skb) { 11742 rtw89_err(rtwdev, "failed to alloc skb for fw ips\n"); 11743 return -ENOMEM; 11744 } 11745 skb_put(skb, len); 11746 h2c = (struct rtw89_h2c_fwips *)skb->data; 11747 11748 h2c->w0 = le32_encode_bits(rtwvif_link->mac_id, RTW89_H2C_FW_IPS_W0_MACID) | 11749 le32_encode_bits(enable, RTW89_H2C_FW_IPS_W0_ENABLE); 11750 11751 rtw89_h2c_pkt_set_hdr(rtwdev, skb, FWCMD_TYPE_H2C, 11752 H2C_CAT_MAC, 11753 H2C_CL_MAC_PS, 11754 H2C_FUNC_IPS_CFG, 0, 1, 11755 len); 11756 11757 return rtw89_h2c_tx_and_wait(rtwdev, skb, wait, RTW89_PS_WAIT_COND_IPS_CFG); 11758 } 11759 11760 int rtw89_fw_h2c_wow_request_aoac(struct rtw89_dev *rtwdev) 11761 { 11762 struct rtw89_wait_info *wait = &rtwdev->wow.wait; 11763 struct rtw89_h2c_wow_aoac *h2c; 11764 u32 len = sizeof(*h2c); 11765 struct sk_buff *skb; 11766 11767 skb = rtw89_fw_h2c_alloc_skb_with_hdr(rtwdev, len); 11768 if (!skb) { 11769 rtw89_err(rtwdev, "failed to alloc skb for aoac\n"); 11770 return -ENOMEM; 11771 } 11772 11773 skb_put(skb, len); 11774 11775 /* This H2C only notify firmware to generate AOAC report C2H, 11776 * no need any parameter. 11777 */ 11778 rtw89_h2c_pkt_set_hdr(rtwdev, skb, FWCMD_TYPE_H2C, 11779 H2C_CAT_MAC, 11780 H2C_CL_MAC_WOW, 11781 H2C_FUNC_AOAC_REPORT_REQ, 1, 0, 11782 len); 11783 11784 return rtw89_h2c_tx_and_wait(rtwdev, skb, wait, RTW89_WOW_WAIT_COND_AOAC); 11785 } 11786 11787 /* Return < 0, if failures happen during waiting for the condition. 11788 * Return 0, when waiting for the condition succeeds. 11789 * Return > 0, if the wait is considered unreachable due to driver/FW design, 11790 * where 1 means during SER. 11791 */ 11792 static int rtw89_h2c_tx_and_wait(struct rtw89_dev *rtwdev, struct sk_buff *skb, 11793 struct rtw89_wait_info *wait, unsigned int cond) 11794 { 11795 struct rtw89_wait_response *prep; 11796 int ret = 0; 11797 11798 lockdep_assert_wiphy(rtwdev->hw->wiphy); 11799 11800 prep = rtw89_wait_for_cond_prep(wait, cond); 11801 if (IS_ERR(prep)) 11802 goto out; 11803 11804 ret = rtw89_h2c_tx(rtwdev, skb, false); 11805 if (ret) { 11806 rtw89_err(rtwdev, "failed to send h2c\n"); 11807 dev_kfree_skb_any(skb); 11808 ret = -EBUSY; 11809 goto out; 11810 } 11811 11812 if (test_bit(RTW89_FLAG_SER_HANDLING, rtwdev->flags)) { 11813 ret = 1; 11814 goto out; 11815 } 11816 11817 out: 11818 return rtw89_wait_for_cond_eval(wait, prep, ret); 11819 } 11820 11821 #define H2C_ADD_MCC_LEN 16 11822 int rtw89_fw_h2c_add_mcc(struct rtw89_dev *rtwdev, 11823 const struct rtw89_fw_mcc_add_req *p) 11824 { 11825 struct rtw89_wait_info *wait = &rtwdev->mcc.wait; 11826 struct sk_buff *skb; 11827 unsigned int cond; 11828 11829 skb = rtw89_fw_h2c_alloc_skb_with_hdr(rtwdev, H2C_ADD_MCC_LEN); 11830 if (!skb) { 11831 rtw89_err(rtwdev, 11832 "failed to alloc skb for add mcc\n"); 11833 return -ENOMEM; 11834 } 11835 11836 skb_put(skb, H2C_ADD_MCC_LEN); 11837 RTW89_SET_FWCMD_ADD_MCC_MACID(skb->data, p->macid); 11838 RTW89_SET_FWCMD_ADD_MCC_CENTRAL_CH_SEG0(skb->data, p->central_ch_seg0); 11839 RTW89_SET_FWCMD_ADD_MCC_CENTRAL_CH_SEG1(skb->data, p->central_ch_seg1); 11840 RTW89_SET_FWCMD_ADD_MCC_PRIMARY_CH(skb->data, p->primary_ch); 11841 RTW89_SET_FWCMD_ADD_MCC_BANDWIDTH(skb->data, p->bandwidth); 11842 RTW89_SET_FWCMD_ADD_MCC_GROUP(skb->data, p->group); 11843 RTW89_SET_FWCMD_ADD_MCC_C2H_RPT(skb->data, p->c2h_rpt); 11844 RTW89_SET_FWCMD_ADD_MCC_DIS_TX_NULL(skb->data, p->dis_tx_null); 11845 RTW89_SET_FWCMD_ADD_MCC_DIS_SW_RETRY(skb->data, p->dis_sw_retry); 11846 RTW89_SET_FWCMD_ADD_MCC_IN_CURR_CH(skb->data, p->in_curr_ch); 11847 RTW89_SET_FWCMD_ADD_MCC_SW_RETRY_COUNT(skb->data, p->sw_retry_count); 11848 RTW89_SET_FWCMD_ADD_MCC_TX_NULL_EARLY(skb->data, p->tx_null_early); 11849 RTW89_SET_FWCMD_ADD_MCC_BTC_IN_2G(skb->data, p->btc_in_2g); 11850 RTW89_SET_FWCMD_ADD_MCC_PTA_EN(skb->data, p->pta_en); 11851 RTW89_SET_FWCMD_ADD_MCC_RFK_BY_PASS(skb->data, p->rfk_by_pass); 11852 RTW89_SET_FWCMD_ADD_MCC_CH_BAND_TYPE(skb->data, p->ch_band_type); 11853 RTW89_SET_FWCMD_ADD_MCC_DURATION(skb->data, p->duration); 11854 RTW89_SET_FWCMD_ADD_MCC_COURTESY_EN(skb->data, p->courtesy_en); 11855 RTW89_SET_FWCMD_ADD_MCC_COURTESY_NUM(skb->data, p->courtesy_num); 11856 RTW89_SET_FWCMD_ADD_MCC_COURTESY_TARGET(skb->data, p->courtesy_target); 11857 11858 rtw89_h2c_pkt_set_hdr(rtwdev, skb, FWCMD_TYPE_H2C, 11859 H2C_CAT_MAC, 11860 H2C_CL_MCC, 11861 H2C_FUNC_ADD_MCC, 0, 0, 11862 H2C_ADD_MCC_LEN); 11863 11864 cond = RTW89_MCC_WAIT_COND(p->group, H2C_FUNC_ADD_MCC); 11865 return rtw89_h2c_tx_and_wait(rtwdev, skb, wait, cond); 11866 } 11867 11868 #define H2C_START_MCC_LEN 12 11869 int rtw89_fw_h2c_start_mcc(struct rtw89_dev *rtwdev, 11870 const struct rtw89_fw_mcc_start_req *p) 11871 { 11872 struct rtw89_wait_info *wait = &rtwdev->mcc.wait; 11873 struct sk_buff *skb; 11874 unsigned int cond; 11875 11876 skb = rtw89_fw_h2c_alloc_skb_with_hdr(rtwdev, H2C_START_MCC_LEN); 11877 if (!skb) { 11878 rtw89_err(rtwdev, 11879 "failed to alloc skb for start mcc\n"); 11880 return -ENOMEM; 11881 } 11882 11883 skb_put(skb, H2C_START_MCC_LEN); 11884 RTW89_SET_FWCMD_START_MCC_GROUP(skb->data, p->group); 11885 RTW89_SET_FWCMD_START_MCC_BTC_IN_GROUP(skb->data, p->btc_in_group); 11886 RTW89_SET_FWCMD_START_MCC_OLD_GROUP_ACTION(skb->data, p->old_group_action); 11887 RTW89_SET_FWCMD_START_MCC_OLD_GROUP(skb->data, p->old_group); 11888 RTW89_SET_FWCMD_START_MCC_NOTIFY_CNT(skb->data, p->notify_cnt); 11889 RTW89_SET_FWCMD_START_MCC_NOTIFY_RXDBG_EN(skb->data, p->notify_rxdbg_en); 11890 RTW89_SET_FWCMD_START_MCC_MACID(skb->data, p->macid); 11891 RTW89_SET_FWCMD_START_MCC_TSF_LOW(skb->data, p->tsf_low); 11892 RTW89_SET_FWCMD_START_MCC_TSF_HIGH(skb->data, p->tsf_high); 11893 11894 rtw89_h2c_pkt_set_hdr(rtwdev, skb, FWCMD_TYPE_H2C, 11895 H2C_CAT_MAC, 11896 H2C_CL_MCC, 11897 H2C_FUNC_START_MCC, 0, 0, 11898 H2C_START_MCC_LEN); 11899 11900 cond = RTW89_MCC_WAIT_COND(p->group, H2C_FUNC_START_MCC); 11901 return rtw89_h2c_tx_and_wait(rtwdev, skb, wait, cond); 11902 } 11903 11904 #define H2C_STOP_MCC_LEN 4 11905 int rtw89_fw_h2c_stop_mcc(struct rtw89_dev *rtwdev, u8 group, u8 macid, 11906 bool prev_groups) 11907 { 11908 struct rtw89_wait_info *wait = &rtwdev->mcc.wait; 11909 struct sk_buff *skb; 11910 unsigned int cond; 11911 11912 skb = rtw89_fw_h2c_alloc_skb_with_hdr(rtwdev, H2C_STOP_MCC_LEN); 11913 if (!skb) { 11914 rtw89_err(rtwdev, 11915 "failed to alloc skb for stop mcc\n"); 11916 return -ENOMEM; 11917 } 11918 11919 skb_put(skb, H2C_STOP_MCC_LEN); 11920 RTW89_SET_FWCMD_STOP_MCC_MACID(skb->data, macid); 11921 RTW89_SET_FWCMD_STOP_MCC_GROUP(skb->data, group); 11922 RTW89_SET_FWCMD_STOP_MCC_PREV_GROUPS(skb->data, prev_groups); 11923 11924 rtw89_h2c_pkt_set_hdr(rtwdev, skb, FWCMD_TYPE_H2C, 11925 H2C_CAT_MAC, 11926 H2C_CL_MCC, 11927 H2C_FUNC_STOP_MCC, 0, 0, 11928 H2C_STOP_MCC_LEN); 11929 11930 cond = RTW89_MCC_WAIT_COND(group, H2C_FUNC_STOP_MCC); 11931 return rtw89_h2c_tx_and_wait(rtwdev, skb, wait, cond); 11932 } 11933 11934 #define H2C_DEL_MCC_GROUP_LEN 4 11935 int rtw89_fw_h2c_del_mcc_group(struct rtw89_dev *rtwdev, u8 group, 11936 bool prev_groups) 11937 { 11938 struct rtw89_wait_info *wait = &rtwdev->mcc.wait; 11939 struct sk_buff *skb; 11940 unsigned int cond; 11941 11942 skb = rtw89_fw_h2c_alloc_skb_with_hdr(rtwdev, H2C_DEL_MCC_GROUP_LEN); 11943 if (!skb) { 11944 rtw89_err(rtwdev, 11945 "failed to alloc skb for del mcc group\n"); 11946 return -ENOMEM; 11947 } 11948 11949 skb_put(skb, H2C_DEL_MCC_GROUP_LEN); 11950 RTW89_SET_FWCMD_DEL_MCC_GROUP_GROUP(skb->data, group); 11951 RTW89_SET_FWCMD_DEL_MCC_GROUP_PREV_GROUPS(skb->data, prev_groups); 11952 11953 rtw89_h2c_pkt_set_hdr(rtwdev, skb, FWCMD_TYPE_H2C, 11954 H2C_CAT_MAC, 11955 H2C_CL_MCC, 11956 H2C_FUNC_DEL_MCC_GROUP, 0, 0, 11957 H2C_DEL_MCC_GROUP_LEN); 11958 11959 cond = RTW89_MCC_WAIT_COND(group, H2C_FUNC_DEL_MCC_GROUP); 11960 return rtw89_h2c_tx_and_wait(rtwdev, skb, wait, cond); 11961 } 11962 11963 #define H2C_RESET_MCC_GROUP_LEN 4 11964 int rtw89_fw_h2c_reset_mcc_group(struct rtw89_dev *rtwdev, u8 group) 11965 { 11966 struct rtw89_wait_info *wait = &rtwdev->mcc.wait; 11967 struct sk_buff *skb; 11968 unsigned int cond; 11969 11970 skb = rtw89_fw_h2c_alloc_skb_with_hdr(rtwdev, H2C_RESET_MCC_GROUP_LEN); 11971 if (!skb) { 11972 rtw89_err(rtwdev, 11973 "failed to alloc skb for reset mcc group\n"); 11974 return -ENOMEM; 11975 } 11976 11977 skb_put(skb, H2C_RESET_MCC_GROUP_LEN); 11978 RTW89_SET_FWCMD_RESET_MCC_GROUP_GROUP(skb->data, group); 11979 11980 rtw89_h2c_pkt_set_hdr(rtwdev, skb, FWCMD_TYPE_H2C, 11981 H2C_CAT_MAC, 11982 H2C_CL_MCC, 11983 H2C_FUNC_RESET_MCC_GROUP, 0, 0, 11984 H2C_RESET_MCC_GROUP_LEN); 11985 11986 cond = RTW89_MCC_WAIT_COND(group, H2C_FUNC_RESET_MCC_GROUP); 11987 return rtw89_h2c_tx_and_wait(rtwdev, skb, wait, cond); 11988 } 11989 11990 #define H2C_MCC_REQ_TSF_LEN 4 11991 int rtw89_fw_h2c_mcc_req_tsf(struct rtw89_dev *rtwdev, 11992 const struct rtw89_fw_mcc_tsf_req *req, 11993 struct rtw89_mac_mcc_tsf_rpt *rpt) 11994 { 11995 struct rtw89_wait_info *wait = &rtwdev->mcc.wait; 11996 struct rtw89_mac_mcc_tsf_rpt *tmp; 11997 struct sk_buff *skb; 11998 unsigned int cond; 11999 int ret; 12000 12001 skb = rtw89_fw_h2c_alloc_skb_with_hdr(rtwdev, H2C_MCC_REQ_TSF_LEN); 12002 if (!skb) { 12003 rtw89_err(rtwdev, 12004 "failed to alloc skb for mcc req tsf\n"); 12005 return -ENOMEM; 12006 } 12007 12008 skb_put(skb, H2C_MCC_REQ_TSF_LEN); 12009 RTW89_SET_FWCMD_MCC_REQ_TSF_GROUP(skb->data, req->group); 12010 RTW89_SET_FWCMD_MCC_REQ_TSF_MACID_X(skb->data, req->macid_x); 12011 RTW89_SET_FWCMD_MCC_REQ_TSF_MACID_Y(skb->data, req->macid_y); 12012 12013 rtw89_h2c_pkt_set_hdr(rtwdev, skb, FWCMD_TYPE_H2C, 12014 H2C_CAT_MAC, 12015 H2C_CL_MCC, 12016 H2C_FUNC_MCC_REQ_TSF, 0, 0, 12017 H2C_MCC_REQ_TSF_LEN); 12018 12019 cond = RTW89_MCC_WAIT_COND(req->group, H2C_FUNC_MCC_REQ_TSF); 12020 ret = rtw89_h2c_tx_and_wait(rtwdev, skb, wait, cond); 12021 if (ret) 12022 return ret; 12023 12024 tmp = (struct rtw89_mac_mcc_tsf_rpt *)wait->data.buf; 12025 *rpt = *tmp; 12026 12027 return 0; 12028 } 12029 12030 #define H2C_MCC_MACID_BITMAP_DSC_LEN 4 12031 int rtw89_fw_h2c_mcc_macid_bitmap(struct rtw89_dev *rtwdev, u8 group, u8 macid, 12032 u8 *bitmap) 12033 { 12034 struct rtw89_wait_info *wait = &rtwdev->mcc.wait; 12035 struct sk_buff *skb; 12036 unsigned int cond; 12037 u8 map_len; 12038 u8 h2c_len; 12039 12040 BUILD_BUG_ON(RTW89_MAX_MAC_ID_NUM % 8); 12041 map_len = RTW89_MAX_MAC_ID_NUM / 8; 12042 h2c_len = H2C_MCC_MACID_BITMAP_DSC_LEN + map_len; 12043 skb = rtw89_fw_h2c_alloc_skb_with_hdr(rtwdev, h2c_len); 12044 if (!skb) { 12045 rtw89_err(rtwdev, 12046 "failed to alloc skb for mcc macid bitmap\n"); 12047 return -ENOMEM; 12048 } 12049 12050 skb_put(skb, h2c_len); 12051 RTW89_SET_FWCMD_MCC_MACID_BITMAP_GROUP(skb->data, group); 12052 RTW89_SET_FWCMD_MCC_MACID_BITMAP_MACID(skb->data, macid); 12053 RTW89_SET_FWCMD_MCC_MACID_BITMAP_BITMAP_LENGTH(skb->data, map_len); 12054 RTW89_SET_FWCMD_MCC_MACID_BITMAP_BITMAP(skb->data, bitmap, map_len); 12055 12056 rtw89_h2c_pkt_set_hdr(rtwdev, skb, FWCMD_TYPE_H2C, 12057 H2C_CAT_MAC, 12058 H2C_CL_MCC, 12059 H2C_FUNC_MCC_MACID_BITMAP, 0, 0, 12060 h2c_len); 12061 12062 cond = RTW89_MCC_WAIT_COND(group, H2C_FUNC_MCC_MACID_BITMAP); 12063 return rtw89_h2c_tx_and_wait(rtwdev, skb, wait, cond); 12064 } 12065 12066 #define H2C_MCC_SYNC_LEN 4 12067 int rtw89_fw_h2c_mcc_sync(struct rtw89_dev *rtwdev, u8 group, u8 source, 12068 u8 target, u8 offset) 12069 { 12070 struct rtw89_wait_info *wait = &rtwdev->mcc.wait; 12071 struct sk_buff *skb; 12072 unsigned int cond; 12073 12074 skb = rtw89_fw_h2c_alloc_skb_with_hdr(rtwdev, H2C_MCC_SYNC_LEN); 12075 if (!skb) { 12076 rtw89_err(rtwdev, 12077 "failed to alloc skb for mcc sync\n"); 12078 return -ENOMEM; 12079 } 12080 12081 skb_put(skb, H2C_MCC_SYNC_LEN); 12082 RTW89_SET_FWCMD_MCC_SYNC_GROUP(skb->data, group); 12083 RTW89_SET_FWCMD_MCC_SYNC_MACID_SOURCE(skb->data, source); 12084 RTW89_SET_FWCMD_MCC_SYNC_MACID_TARGET(skb->data, target); 12085 RTW89_SET_FWCMD_MCC_SYNC_SYNC_OFFSET(skb->data, offset); 12086 12087 rtw89_h2c_pkt_set_hdr(rtwdev, skb, FWCMD_TYPE_H2C, 12088 H2C_CAT_MAC, 12089 H2C_CL_MCC, 12090 H2C_FUNC_MCC_SYNC, 0, 0, 12091 H2C_MCC_SYNC_LEN); 12092 12093 cond = RTW89_MCC_WAIT_COND(group, H2C_FUNC_MCC_SYNC); 12094 return rtw89_h2c_tx_and_wait(rtwdev, skb, wait, cond); 12095 } 12096 12097 #define H2C_MCC_SET_DURATION_LEN 20 12098 int rtw89_fw_h2c_mcc_set_duration(struct rtw89_dev *rtwdev, 12099 const struct rtw89_fw_mcc_duration *p) 12100 { 12101 struct rtw89_wait_info *wait = &rtwdev->mcc.wait; 12102 struct sk_buff *skb; 12103 unsigned int cond; 12104 12105 skb = rtw89_fw_h2c_alloc_skb_with_hdr(rtwdev, H2C_MCC_SET_DURATION_LEN); 12106 if (!skb) { 12107 rtw89_err(rtwdev, 12108 "failed to alloc skb for mcc set duration\n"); 12109 return -ENOMEM; 12110 } 12111 12112 skb_put(skb, H2C_MCC_SET_DURATION_LEN); 12113 RTW89_SET_FWCMD_MCC_SET_DURATION_GROUP(skb->data, p->group); 12114 RTW89_SET_FWCMD_MCC_SET_DURATION_BTC_IN_GROUP(skb->data, p->btc_in_group); 12115 RTW89_SET_FWCMD_MCC_SET_DURATION_START_MACID(skb->data, p->start_macid); 12116 RTW89_SET_FWCMD_MCC_SET_DURATION_MACID_X(skb->data, p->macid_x); 12117 RTW89_SET_FWCMD_MCC_SET_DURATION_MACID_Y(skb->data, p->macid_y); 12118 RTW89_SET_FWCMD_MCC_SET_DURATION_START_TSF_LOW(skb->data, 12119 p->start_tsf_low); 12120 RTW89_SET_FWCMD_MCC_SET_DURATION_START_TSF_HIGH(skb->data, 12121 p->start_tsf_high); 12122 RTW89_SET_FWCMD_MCC_SET_DURATION_DURATION_X(skb->data, p->duration_x); 12123 RTW89_SET_FWCMD_MCC_SET_DURATION_DURATION_Y(skb->data, p->duration_y); 12124 12125 rtw89_h2c_pkt_set_hdr(rtwdev, skb, FWCMD_TYPE_H2C, 12126 H2C_CAT_MAC, 12127 H2C_CL_MCC, 12128 H2C_FUNC_MCC_SET_DURATION, 0, 0, 12129 H2C_MCC_SET_DURATION_LEN); 12130 12131 cond = RTW89_MCC_WAIT_COND(p->group, H2C_FUNC_MCC_SET_DURATION); 12132 return rtw89_h2c_tx_and_wait(rtwdev, skb, wait, cond); 12133 } 12134 12135 static 12136 u32 rtw89_fw_h2c_mrc_add_slot(struct rtw89_dev *rtwdev, 12137 const struct rtw89_fw_mrc_add_slot_arg *slot_arg, 12138 struct rtw89_h2c_mrc_add_slot *slot_h2c) 12139 { 12140 bool fill_h2c = !!slot_h2c; 12141 unsigned int i; 12142 12143 if (!fill_h2c) 12144 goto calc_len; 12145 12146 slot_h2c->w0 = le32_encode_bits(slot_arg->duration, 12147 RTW89_H2C_MRC_ADD_SLOT_W0_DURATION) | 12148 le32_encode_bits(slot_arg->courtesy_en, 12149 RTW89_H2C_MRC_ADD_SLOT_W0_COURTESY_EN) | 12150 le32_encode_bits(slot_arg->role_num, 12151 RTW89_H2C_MRC_ADD_SLOT_W0_ROLE_NUM); 12152 slot_h2c->w1 = le32_encode_bits(slot_arg->courtesy_period, 12153 RTW89_H2C_MRC_ADD_SLOT_W1_COURTESY_PERIOD) | 12154 le32_encode_bits(slot_arg->courtesy_target, 12155 RTW89_H2C_MRC_ADD_SLOT_W1_COURTESY_TARGET); 12156 12157 for (i = 0; i < slot_arg->role_num; i++) { 12158 slot_h2c->roles[i].w0 = 12159 le32_encode_bits(slot_arg->roles[i].macid, 12160 RTW89_H2C_MRC_ADD_ROLE_W0_MACID) | 12161 le32_encode_bits(slot_arg->roles[i].role_type, 12162 RTW89_H2C_MRC_ADD_ROLE_W0_ROLE_TYPE) | 12163 le32_encode_bits(slot_arg->roles[i].is_master, 12164 RTW89_H2C_MRC_ADD_ROLE_W0_IS_MASTER) | 12165 le32_encode_bits(slot_arg->roles[i].en_tx_null, 12166 RTW89_H2C_MRC_ADD_ROLE_W0_TX_NULL_EN) | 12167 le32_encode_bits(false, 12168 RTW89_H2C_MRC_ADD_ROLE_W0_IS_ALT_ROLE) | 12169 le32_encode_bits(false, 12170 RTW89_H2C_MRC_ADD_ROLE_W0_ROLE_ALT_EN); 12171 slot_h2c->roles[i].w1 = 12172 le32_encode_bits(slot_arg->roles[i].central_ch, 12173 RTW89_H2C_MRC_ADD_ROLE_W1_CENTRAL_CH_SEG) | 12174 le32_encode_bits(slot_arg->roles[i].primary_ch, 12175 RTW89_H2C_MRC_ADD_ROLE_W1_PRI_CH) | 12176 le32_encode_bits(slot_arg->roles[i].bw, 12177 RTW89_H2C_MRC_ADD_ROLE_W1_BW) | 12178 le32_encode_bits(slot_arg->roles[i].band, 12179 RTW89_H2C_MRC_ADD_ROLE_W1_CH_BAND_TYPE) | 12180 le32_encode_bits(slot_arg->roles[i].null_early, 12181 RTW89_H2C_MRC_ADD_ROLE_W1_NULL_EARLY) | 12182 le32_encode_bits(false, 12183 RTW89_H2C_MRC_ADD_ROLE_W1_RFK_BY_PASS) | 12184 le32_encode_bits(true, 12185 RTW89_H2C_MRC_ADD_ROLE_W1_CAN_BTC); 12186 slot_h2c->roles[i].macid_main_bitmap = 12187 cpu_to_le32(slot_arg->roles[i].macid_main_bitmap); 12188 slot_h2c->roles[i].macid_paired_bitmap = 12189 cpu_to_le32(slot_arg->roles[i].macid_paired_bitmap); 12190 } 12191 12192 calc_len: 12193 return struct_size(slot_h2c, roles, slot_arg->role_num); 12194 } 12195 12196 int rtw89_fw_h2c_mrc_add(struct rtw89_dev *rtwdev, 12197 const struct rtw89_fw_mrc_add_arg *arg) 12198 { 12199 struct rtw89_h2c_mrc_add *h2c_head; 12200 struct sk_buff *skb; 12201 unsigned int i; 12202 void *tmp; 12203 u32 len; 12204 int ret; 12205 12206 len = sizeof(*h2c_head); 12207 for (i = 0; i < arg->slot_num; i++) 12208 len += rtw89_fw_h2c_mrc_add_slot(rtwdev, &arg->slots[i], NULL); 12209 12210 skb = rtw89_fw_h2c_alloc_skb_with_hdr(rtwdev, len); 12211 if (!skb) { 12212 rtw89_err(rtwdev, "failed to alloc skb for mrc add\n"); 12213 return -ENOMEM; 12214 } 12215 12216 skb_put(skb, len); 12217 tmp = skb->data; 12218 12219 h2c_head = tmp; 12220 h2c_head->w0 = le32_encode_bits(arg->sch_idx, 12221 RTW89_H2C_MRC_ADD_W0_SCH_IDX) | 12222 le32_encode_bits(arg->sch_type, 12223 RTW89_H2C_MRC_ADD_W0_SCH_TYPE) | 12224 le32_encode_bits(arg->slot_num, 12225 RTW89_H2C_MRC_ADD_W0_SLOT_NUM) | 12226 le32_encode_bits(arg->btc_in_sch, 12227 RTW89_H2C_MRC_ADD_W0_BTC_IN_SCH); 12228 12229 tmp += sizeof(*h2c_head); 12230 for (i = 0; i < arg->slot_num; i++) 12231 tmp += rtw89_fw_h2c_mrc_add_slot(rtwdev, &arg->slots[i], tmp); 12232 12233 rtw89_h2c_pkt_set_hdr(rtwdev, skb, FWCMD_TYPE_H2C, 12234 H2C_CAT_MAC, 12235 H2C_CL_MRC, 12236 H2C_FUNC_ADD_MRC, 0, 0, 12237 len); 12238 12239 ret = rtw89_h2c_tx(rtwdev, skb, false); 12240 if (ret) { 12241 rtw89_err(rtwdev, "failed to send h2c\n"); 12242 dev_kfree_skb_any(skb); 12243 return -EBUSY; 12244 } 12245 12246 return 0; 12247 } 12248 12249 int rtw89_fw_h2c_mrc_start(struct rtw89_dev *rtwdev, 12250 const struct rtw89_fw_mrc_start_arg *arg) 12251 { 12252 struct rtw89_wait_info *wait = &rtwdev->mcc.wait; 12253 struct rtw89_h2c_mrc_start *h2c; 12254 u32 len = sizeof(*h2c); 12255 struct sk_buff *skb; 12256 unsigned int cond; 12257 12258 skb = rtw89_fw_h2c_alloc_skb_with_hdr(rtwdev, len); 12259 if (!skb) { 12260 rtw89_err(rtwdev, "failed to alloc skb for mrc start\n"); 12261 return -ENOMEM; 12262 } 12263 12264 skb_put(skb, len); 12265 h2c = (struct rtw89_h2c_mrc_start *)skb->data; 12266 12267 h2c->w0 = le32_encode_bits(arg->sch_idx, 12268 RTW89_H2C_MRC_START_W0_SCH_IDX) | 12269 le32_encode_bits(arg->old_sch_idx, 12270 RTW89_H2C_MRC_START_W0_OLD_SCH_IDX) | 12271 le32_encode_bits(arg->action, 12272 RTW89_H2C_MRC_START_W0_ACTION); 12273 12274 h2c->start_tsf_high = cpu_to_le32(arg->start_tsf >> 32); 12275 h2c->start_tsf_low = cpu_to_le32(arg->start_tsf); 12276 12277 rtw89_h2c_pkt_set_hdr(rtwdev, skb, FWCMD_TYPE_H2C, 12278 H2C_CAT_MAC, 12279 H2C_CL_MRC, 12280 H2C_FUNC_START_MRC, 0, 0, 12281 len); 12282 12283 cond = RTW89_MRC_WAIT_COND(arg->sch_idx, H2C_FUNC_START_MRC); 12284 return rtw89_h2c_tx_and_wait(rtwdev, skb, wait, cond); 12285 } 12286 12287 int rtw89_fw_h2c_mrc_del(struct rtw89_dev *rtwdev, u8 sch_idx, u8 slot_idx) 12288 { 12289 struct rtw89_wait_info *wait = &rtwdev->mcc.wait; 12290 struct rtw89_h2c_mrc_del *h2c; 12291 u32 len = sizeof(*h2c); 12292 struct sk_buff *skb; 12293 unsigned int cond; 12294 12295 skb = rtw89_fw_h2c_alloc_skb_with_hdr(rtwdev, len); 12296 if (!skb) { 12297 rtw89_err(rtwdev, "failed to alloc skb for mrc del\n"); 12298 return -ENOMEM; 12299 } 12300 12301 skb_put(skb, len); 12302 h2c = (struct rtw89_h2c_mrc_del *)skb->data; 12303 12304 h2c->w0 = le32_encode_bits(sch_idx, RTW89_H2C_MRC_DEL_W0_SCH_IDX) | 12305 le32_encode_bits(slot_idx, RTW89_H2C_MRC_DEL_W0_STOP_SLOT_IDX); 12306 12307 rtw89_h2c_pkt_set_hdr(rtwdev, skb, FWCMD_TYPE_H2C, 12308 H2C_CAT_MAC, 12309 H2C_CL_MRC, 12310 H2C_FUNC_DEL_MRC, 0, 0, 12311 len); 12312 12313 cond = RTW89_MRC_WAIT_COND(sch_idx, H2C_FUNC_DEL_MRC); 12314 return rtw89_h2c_tx_and_wait(rtwdev, skb, wait, cond); 12315 } 12316 12317 int rtw89_fw_h2c_mrc_req_tsf(struct rtw89_dev *rtwdev, 12318 const struct rtw89_fw_mrc_req_tsf_arg *arg, 12319 struct rtw89_mac_mrc_tsf_rpt *rpt) 12320 { 12321 struct rtw89_wait_info *wait = &rtwdev->mcc.wait; 12322 struct rtw89_h2c_mrc_req_tsf *h2c; 12323 struct rtw89_mac_mrc_tsf_rpt *tmp; 12324 struct sk_buff *skb; 12325 unsigned int i; 12326 u32 len; 12327 int ret; 12328 12329 len = struct_size(h2c, infos, arg->num); 12330 skb = rtw89_fw_h2c_alloc_skb_with_hdr(rtwdev, len); 12331 if (!skb) { 12332 rtw89_err(rtwdev, "failed to alloc skb for mrc req tsf\n"); 12333 return -ENOMEM; 12334 } 12335 12336 skb_put(skb, len); 12337 h2c = (struct rtw89_h2c_mrc_req_tsf *)skb->data; 12338 12339 h2c->req_tsf_num = arg->num; 12340 for (i = 0; i < arg->num; i++) 12341 h2c->infos[i] = 12342 u8_encode_bits(arg->infos[i].band, 12343 RTW89_H2C_MRC_REQ_TSF_INFO_BAND) | 12344 u8_encode_bits(arg->infos[i].port, 12345 RTW89_H2C_MRC_REQ_TSF_INFO_PORT); 12346 12347 rtw89_h2c_pkt_set_hdr(rtwdev, skb, FWCMD_TYPE_H2C, 12348 H2C_CAT_MAC, 12349 H2C_CL_MRC, 12350 H2C_FUNC_MRC_REQ_TSF, 0, 0, 12351 len); 12352 12353 ret = rtw89_h2c_tx_and_wait(rtwdev, skb, wait, RTW89_MRC_WAIT_COND_REQ_TSF); 12354 if (ret) 12355 return ret; 12356 12357 tmp = (struct rtw89_mac_mrc_tsf_rpt *)wait->data.buf; 12358 *rpt = *tmp; 12359 12360 return 0; 12361 } 12362 12363 int rtw89_fw_h2c_mrc_upd_bitmap(struct rtw89_dev *rtwdev, 12364 const struct rtw89_fw_mrc_upd_bitmap_arg *arg) 12365 { 12366 struct rtw89_h2c_mrc_upd_bitmap *h2c; 12367 u32 len = sizeof(*h2c); 12368 struct sk_buff *skb; 12369 int ret; 12370 12371 skb = rtw89_fw_h2c_alloc_skb_with_hdr(rtwdev, len); 12372 if (!skb) { 12373 rtw89_err(rtwdev, "failed to alloc skb for mrc upd bitmap\n"); 12374 return -ENOMEM; 12375 } 12376 12377 skb_put(skb, len); 12378 h2c = (struct rtw89_h2c_mrc_upd_bitmap *)skb->data; 12379 12380 h2c->w0 = le32_encode_bits(arg->sch_idx, 12381 RTW89_H2C_MRC_UPD_BITMAP_W0_SCH_IDX) | 12382 le32_encode_bits(arg->action, 12383 RTW89_H2C_MRC_UPD_BITMAP_W0_ACTION) | 12384 le32_encode_bits(arg->macid, 12385 RTW89_H2C_MRC_UPD_BITMAP_W0_MACID); 12386 h2c->w1 = le32_encode_bits(arg->client_macid, 12387 RTW89_H2C_MRC_UPD_BITMAP_W1_CLIENT_MACID); 12388 12389 rtw89_h2c_pkt_set_hdr(rtwdev, skb, FWCMD_TYPE_H2C, 12390 H2C_CAT_MAC, 12391 H2C_CL_MRC, 12392 H2C_FUNC_MRC_UPD_BITMAP, 0, 0, 12393 len); 12394 12395 ret = rtw89_h2c_tx(rtwdev, skb, false); 12396 if (ret) { 12397 rtw89_err(rtwdev, "failed to send h2c\n"); 12398 dev_kfree_skb_any(skb); 12399 return -EBUSY; 12400 } 12401 12402 return 0; 12403 } 12404 12405 int rtw89_fw_h2c_mrc_sync(struct rtw89_dev *rtwdev, 12406 const struct rtw89_fw_mrc_sync_arg *arg) 12407 { 12408 struct rtw89_h2c_mrc_sync *h2c; 12409 u32 len = sizeof(*h2c); 12410 struct sk_buff *skb; 12411 int ret; 12412 12413 skb = rtw89_fw_h2c_alloc_skb_with_hdr(rtwdev, len); 12414 if (!skb) { 12415 rtw89_err(rtwdev, "failed to alloc skb for mrc sync\n"); 12416 return -ENOMEM; 12417 } 12418 12419 skb_put(skb, len); 12420 h2c = (struct rtw89_h2c_mrc_sync *)skb->data; 12421 12422 h2c->w0 = le32_encode_bits(true, RTW89_H2C_MRC_SYNC_W0_SYNC_EN) | 12423 le32_encode_bits(arg->src.port, 12424 RTW89_H2C_MRC_SYNC_W0_SRC_PORT) | 12425 le32_encode_bits(arg->src.band, 12426 RTW89_H2C_MRC_SYNC_W0_SRC_BAND) | 12427 le32_encode_bits(arg->dest.port, 12428 RTW89_H2C_MRC_SYNC_W0_DEST_PORT) | 12429 le32_encode_bits(arg->dest.band, 12430 RTW89_H2C_MRC_SYNC_W0_DEST_BAND); 12431 h2c->w1 = le32_encode_bits(arg->offset, RTW89_H2C_MRC_SYNC_W1_OFFSET); 12432 12433 rtw89_h2c_pkt_set_hdr(rtwdev, skb, FWCMD_TYPE_H2C, 12434 H2C_CAT_MAC, 12435 H2C_CL_MRC, 12436 H2C_FUNC_MRC_SYNC, 0, 0, 12437 len); 12438 12439 ret = rtw89_h2c_tx(rtwdev, skb, false); 12440 if (ret) { 12441 rtw89_err(rtwdev, "failed to send h2c\n"); 12442 dev_kfree_skb_any(skb); 12443 return -EBUSY; 12444 } 12445 12446 return 0; 12447 } 12448 12449 int rtw89_fw_h2c_mrc_upd_duration(struct rtw89_dev *rtwdev, 12450 const struct rtw89_fw_mrc_upd_duration_arg *arg) 12451 { 12452 struct rtw89_h2c_mrc_upd_duration *h2c; 12453 struct sk_buff *skb; 12454 unsigned int i; 12455 u32 len; 12456 int ret; 12457 12458 len = struct_size(h2c, slots, arg->slot_num); 12459 skb = rtw89_fw_h2c_alloc_skb_with_hdr(rtwdev, len); 12460 if (!skb) { 12461 rtw89_err(rtwdev, "failed to alloc skb for mrc upd duration\n"); 12462 return -ENOMEM; 12463 } 12464 12465 skb_put(skb, len); 12466 h2c = (struct rtw89_h2c_mrc_upd_duration *)skb->data; 12467 12468 h2c->w0 = le32_encode_bits(arg->sch_idx, 12469 RTW89_H2C_MRC_UPD_DURATION_W0_SCH_IDX) | 12470 le32_encode_bits(arg->slot_num, 12471 RTW89_H2C_MRC_UPD_DURATION_W0_SLOT_NUM) | 12472 le32_encode_bits(false, 12473 RTW89_H2C_MRC_UPD_DURATION_W0_BTC_IN_SCH); 12474 12475 h2c->start_tsf_high = cpu_to_le32(arg->start_tsf >> 32); 12476 h2c->start_tsf_low = cpu_to_le32(arg->start_tsf); 12477 12478 for (i = 0; i < arg->slot_num; i++) { 12479 h2c->slots[i] = 12480 le32_encode_bits(arg->slots[i].slot_idx, 12481 RTW89_H2C_MRC_UPD_DURATION_SLOT_SLOT_IDX) | 12482 le32_encode_bits(arg->slots[i].duration, 12483 RTW89_H2C_MRC_UPD_DURATION_SLOT_DURATION); 12484 } 12485 12486 rtw89_h2c_pkt_set_hdr(rtwdev, skb, FWCMD_TYPE_H2C, 12487 H2C_CAT_MAC, 12488 H2C_CL_MRC, 12489 H2C_FUNC_MRC_UPD_DURATION, 0, 0, 12490 len); 12491 12492 ret = rtw89_h2c_tx(rtwdev, skb, false); 12493 if (ret) { 12494 rtw89_err(rtwdev, "failed to send h2c\n"); 12495 dev_kfree_skb_any(skb); 12496 return -EBUSY; 12497 } 12498 12499 return 0; 12500 } 12501 12502 static int rtw89_fw_h2c_ap_info(struct rtw89_dev *rtwdev, bool en) 12503 { 12504 struct rtw89_h2c_ap_info *h2c; 12505 u32 len = sizeof(*h2c); 12506 struct sk_buff *skb; 12507 int ret; 12508 12509 skb = rtw89_fw_h2c_alloc_skb_with_hdr(rtwdev, len); 12510 if (!skb) { 12511 rtw89_err(rtwdev, "failed to alloc skb for ap info\n"); 12512 return -ENOMEM; 12513 } 12514 12515 skb_put(skb, len); 12516 h2c = (struct rtw89_h2c_ap_info *)skb->data; 12517 12518 h2c->w0 = le32_encode_bits(en, RTW89_H2C_AP_INFO_W0_PWR_INT_EN); 12519 12520 rtw89_h2c_pkt_set_hdr(rtwdev, skb, FWCMD_TYPE_H2C, 12521 H2C_CAT_MAC, 12522 H2C_CL_AP, 12523 H2C_FUNC_AP_INFO, 0, 0, 12524 len); 12525 12526 ret = rtw89_h2c_tx(rtwdev, skb, false); 12527 if (ret) { 12528 rtw89_err(rtwdev, "failed to send h2c\n"); 12529 dev_kfree_skb_any(skb); 12530 return -EBUSY; 12531 } 12532 12533 return 0; 12534 } 12535 12536 int rtw89_fw_h2c_ap_info_refcount(struct rtw89_dev *rtwdev, bool en) 12537 { 12538 int ret; 12539 12540 if (en) { 12541 if (refcount_inc_not_zero(&rtwdev->refcount_ap_info)) 12542 return 0; 12543 } else { 12544 if (!refcount_dec_and_test(&rtwdev->refcount_ap_info)) 12545 return 0; 12546 } 12547 12548 ret = rtw89_fw_h2c_ap_info(rtwdev, en); 12549 if (ret) { 12550 if (!test_bit(RTW89_FLAG_SER_HANDLING, rtwdev->flags)) 12551 return ret; 12552 12553 /* During recovery, neither driver nor stack has full error 12554 * handling, so show a warning, but return 0 with refcount 12555 * increased normally. It can avoid underflow when calling 12556 * with @en == false later. 12557 */ 12558 rtw89_warn(rtwdev, "h2c ap_info failed during SER\n"); 12559 } 12560 12561 if (en) 12562 refcount_set(&rtwdev->refcount_ap_info, 1); 12563 12564 return 0; 12565 } 12566 12567 int rtw89_fw_h2c_mlo_link_cfg(struct rtw89_dev *rtwdev, struct rtw89_vif_link *rtwvif_link, 12568 bool enable) 12569 { 12570 struct rtw89_wait_info *wait = &rtwdev->mlo.wait; 12571 struct rtw89_h2c_mlo_link_cfg *h2c; 12572 u8 mac_id = rtwvif_link->mac_id; 12573 u32 len = sizeof(*h2c); 12574 struct sk_buff *skb; 12575 unsigned int cond; 12576 int ret; 12577 12578 skb = rtw89_fw_h2c_alloc_skb_with_hdr(rtwdev, len); 12579 if (!skb) { 12580 rtw89_err(rtwdev, "failed to alloc skb for mlo link cfg\n"); 12581 return -ENOMEM; 12582 } 12583 12584 skb_put(skb, len); 12585 h2c = (struct rtw89_h2c_mlo_link_cfg *)skb->data; 12586 12587 h2c->w0 = le32_encode_bits(mac_id, RTW89_H2C_MLO_LINK_CFG_W0_MACID) | 12588 le32_encode_bits(enable, RTW89_H2C_MLO_LINK_CFG_W0_OPTION); 12589 12590 rtw89_h2c_pkt_set_hdr(rtwdev, skb, FWCMD_TYPE_H2C, 12591 H2C_CAT_MAC, 12592 H2C_CL_MLO, 12593 H2C_FUNC_MLO_LINK_CFG, 0, 0, 12594 len); 12595 12596 cond = RTW89_MLO_WAIT_COND(mac_id, H2C_FUNC_MLO_LINK_CFG); 12597 12598 ret = rtw89_h2c_tx_and_wait(rtwdev, skb, wait, cond); 12599 if (ret) { 12600 rtw89_err(rtwdev, "mlo link cfg (%s link id %u) failed: %d\n", 12601 str_enable_disable(enable), rtwvif_link->link_id, ret); 12602 return ret; 12603 } 12604 12605 return 0; 12606 } 12607 12608 static bool __fw_txpwr_entry_zero_ext(const void *ext_ptr, u8 ext_len) 12609 { 12610 static const u8 zeros[U8_MAX] = {}; 12611 12612 return memcmp(ext_ptr, zeros, ext_len) == 0; 12613 } 12614 12615 #define __fw_txpwr_entry_acceptable(e, cursor, ent_sz) \ 12616 ({ \ 12617 u8 __var_sz = sizeof(*(e)); \ 12618 bool __accept; \ 12619 if (__var_sz >= (ent_sz)) \ 12620 __accept = true; \ 12621 else \ 12622 __accept = __fw_txpwr_entry_zero_ext((cursor) + __var_sz,\ 12623 (ent_sz) - __var_sz);\ 12624 __accept; \ 12625 }) 12626 12627 static bool 12628 fw_txpwr_byrate_entry_valid(const struct rtw89_fw_txpwr_byrate_entry *e, 12629 const void *cursor, 12630 const struct rtw89_txpwr_conf *conf) 12631 { 12632 if (!__fw_txpwr_entry_acceptable(e, cursor, conf->ent_sz)) 12633 return false; 12634 12635 if (e->band >= RTW89_BAND_NUM || e->bw >= RTW89_BYR_BW_NUM) 12636 return false; 12637 12638 switch (e->rs) { 12639 case RTW89_RS_CCK: 12640 if (e->shf + e->len > RTW89_RATE_CCK_NUM) 12641 return false; 12642 break; 12643 case RTW89_RS_OFDM: 12644 if (e->shf + e->len > RTW89_RATE_OFDM_NUM) 12645 return false; 12646 break; 12647 case RTW89_RS_MCS: 12648 if (e->shf + e->len > __RTW89_RATE_MCS_NUM || 12649 e->nss >= RTW89_NSS_NUM || 12650 e->ofdma >= RTW89_OFDMA_NUM) 12651 return false; 12652 break; 12653 case RTW89_RS_HEDCM: 12654 if (e->shf + e->len > RTW89_RATE_HEDCM_NUM || 12655 e->nss >= RTW89_NSS_HEDCM_NUM || 12656 e->ofdma >= RTW89_OFDMA_NUM) 12657 return false; 12658 break; 12659 case RTW89_RS_OFFSET: 12660 if (e->shf + e->len > __RTW89_RATE_OFFSET_NUM) 12661 return false; 12662 break; 12663 default: 12664 return false; 12665 } 12666 12667 return true; 12668 } 12669 12670 static 12671 void rtw89_fw_load_txpwr_byrate(struct rtw89_dev *rtwdev, 12672 const struct rtw89_txpwr_table *tbl) 12673 { 12674 const struct rtw89_txpwr_conf *conf = tbl->data; 12675 struct rtw89_fw_txpwr_byrate_entry entry = {}; 12676 struct rtw89_txpwr_byrate *byr_head; 12677 struct rtw89_rate_desc desc = {}; 12678 const void *cursor; 12679 u32 data; 12680 s8 *byr; 12681 int i; 12682 12683 rtw89_for_each_in_txpwr_conf(entry, cursor, conf) { 12684 if (!fw_txpwr_byrate_entry_valid(&entry, cursor, conf)) 12685 continue; 12686 12687 byr_head = &rtwdev->byr[entry.band][entry.bw]; 12688 data = le32_to_cpu(entry.data); 12689 desc.ofdma = entry.ofdma; 12690 desc.nss = entry.nss; 12691 desc.rs = entry.rs; 12692 12693 for (i = 0; i < entry.len; i++, data >>= 8) { 12694 desc.idx = entry.shf + i; 12695 byr = rtw89_phy_raw_byr_seek(rtwdev, byr_head, &desc); 12696 *byr = data & 0xff; 12697 } 12698 } 12699 } 12700 12701 static bool 12702 fw_txpwr_lmt_2ghz_entry_valid(const struct rtw89_fw_txpwr_lmt_2ghz_entry *e, 12703 const void *cursor, 12704 const struct rtw89_txpwr_conf *conf) 12705 { 12706 if (!__fw_txpwr_entry_acceptable(e, cursor, conf->ent_sz)) 12707 return false; 12708 12709 if (e->bw >= RTW89_2G_BW_NUM) 12710 return false; 12711 if (e->nt >= RTW89_NTX_NUM) 12712 return false; 12713 if (e->rs >= RTW89_RS_LMT_NUM) 12714 return false; 12715 if (e->bf >= RTW89_BF_NUM) 12716 return false; 12717 if (e->regd >= RTW89_REGD_NUM) 12718 return false; 12719 if (e->ch_idx >= RTW89_2G_CH_NUM) 12720 return false; 12721 12722 return true; 12723 } 12724 12725 static 12726 void rtw89_fw_load_txpwr_lmt_2ghz(struct rtw89_txpwr_lmt_2ghz_data *data) 12727 { 12728 const struct rtw89_txpwr_conf *conf = &data->conf; 12729 struct rtw89_fw_txpwr_lmt_2ghz_entry entry = {}; 12730 const void *cursor; 12731 12732 rtw89_for_each_in_txpwr_conf(entry, cursor, conf) { 12733 if (!fw_txpwr_lmt_2ghz_entry_valid(&entry, cursor, conf)) 12734 continue; 12735 12736 data->v[entry.bw][entry.nt][entry.rs][entry.bf][entry.regd] 12737 [entry.ch_idx] = entry.v; 12738 } 12739 } 12740 12741 static bool 12742 fw_txpwr_lmt_5ghz_entry_valid(const struct rtw89_fw_txpwr_lmt_5ghz_entry *e, 12743 const void *cursor, 12744 const struct rtw89_txpwr_conf *conf) 12745 { 12746 if (!__fw_txpwr_entry_acceptable(e, cursor, conf->ent_sz)) 12747 return false; 12748 12749 if (e->bw >= RTW89_5G_BW_NUM) 12750 return false; 12751 if (e->nt >= RTW89_NTX_NUM) 12752 return false; 12753 if (e->rs >= RTW89_RS_LMT_NUM) 12754 return false; 12755 if (e->bf >= RTW89_BF_NUM) 12756 return false; 12757 if (e->regd >= RTW89_REGD_NUM) 12758 return false; 12759 if (e->ch_idx >= RTW89_5G_CH_NUM) 12760 return false; 12761 12762 return true; 12763 } 12764 12765 static 12766 void rtw89_fw_load_txpwr_lmt_5ghz(struct rtw89_txpwr_lmt_5ghz_data *data) 12767 { 12768 const struct rtw89_txpwr_conf *conf = &data->conf; 12769 struct rtw89_fw_txpwr_lmt_5ghz_entry entry = {}; 12770 const void *cursor; 12771 12772 rtw89_for_each_in_txpwr_conf(entry, cursor, conf) { 12773 if (!fw_txpwr_lmt_5ghz_entry_valid(&entry, cursor, conf)) 12774 continue; 12775 12776 data->v[entry.bw][entry.nt][entry.rs][entry.bf][entry.regd] 12777 [entry.ch_idx] = entry.v; 12778 } 12779 } 12780 12781 static bool 12782 fw_txpwr_lmt_6ghz_entry_valid(const struct rtw89_fw_txpwr_lmt_6ghz_entry *e, 12783 const void *cursor, 12784 const struct rtw89_txpwr_conf *conf) 12785 { 12786 if (!__fw_txpwr_entry_acceptable(e, cursor, conf->ent_sz)) 12787 return false; 12788 12789 if (e->bw >= RTW89_6G_BW_NUM) 12790 return false; 12791 if (e->nt >= RTW89_NTX_NUM) 12792 return false; 12793 if (e->rs >= RTW89_RS_LMT_NUM) 12794 return false; 12795 if (e->bf >= RTW89_BF_NUM) 12796 return false; 12797 if (e->regd >= RTW89_REGD_NUM) 12798 return false; 12799 if (e->reg_6ghz_power >= NUM_OF_RTW89_REG_6GHZ_POWER) 12800 return false; 12801 if (e->ch_idx >= RTW89_6G_CH_NUM) 12802 return false; 12803 12804 return true; 12805 } 12806 12807 static 12808 void rtw89_fw_load_txpwr_lmt_6ghz(struct rtw89_txpwr_lmt_6ghz_data *data) 12809 { 12810 const struct rtw89_txpwr_conf *conf = &data->conf; 12811 struct rtw89_fw_txpwr_lmt_6ghz_entry entry = {}; 12812 const void *cursor; 12813 12814 rtw89_for_each_in_txpwr_conf(entry, cursor, conf) { 12815 if (!fw_txpwr_lmt_6ghz_entry_valid(&entry, cursor, conf)) 12816 continue; 12817 12818 data->v[entry.bw][entry.nt][entry.rs][entry.bf][entry.regd] 12819 [entry.reg_6ghz_power][entry.ch_idx] = entry.v; 12820 } 12821 } 12822 12823 static bool 12824 fw_txpwr_lmt_ru_2ghz_entry_valid(const struct rtw89_fw_txpwr_lmt_ru_2ghz_entry *e, 12825 const void *cursor, 12826 const struct rtw89_txpwr_conf *conf) 12827 { 12828 if (!__fw_txpwr_entry_acceptable(e, cursor, conf->ent_sz)) 12829 return false; 12830 12831 if (e->ru >= RTW89_RU_NUM) 12832 return false; 12833 if (e->nt >= RTW89_NTX_NUM) 12834 return false; 12835 if (e->regd >= RTW89_REGD_NUM) 12836 return false; 12837 if (e->ch_idx >= RTW89_2G_CH_NUM) 12838 return false; 12839 12840 return true; 12841 } 12842 12843 static 12844 void rtw89_fw_load_txpwr_lmt_ru_2ghz(struct rtw89_txpwr_lmt_ru_2ghz_data *data) 12845 { 12846 const struct rtw89_txpwr_conf *conf = &data->conf; 12847 struct rtw89_fw_txpwr_lmt_ru_2ghz_entry entry = {}; 12848 const void *cursor; 12849 12850 rtw89_for_each_in_txpwr_conf(entry, cursor, conf) { 12851 if (!fw_txpwr_lmt_ru_2ghz_entry_valid(&entry, cursor, conf)) 12852 continue; 12853 12854 data->v[entry.ru][entry.nt][entry.regd][entry.ch_idx] = entry.v; 12855 } 12856 } 12857 12858 static bool 12859 fw_txpwr_lmt_ru_5ghz_entry_valid(const struct rtw89_fw_txpwr_lmt_ru_5ghz_entry *e, 12860 const void *cursor, 12861 const struct rtw89_txpwr_conf *conf) 12862 { 12863 if (!__fw_txpwr_entry_acceptable(e, cursor, conf->ent_sz)) 12864 return false; 12865 12866 if (e->ru >= RTW89_RU_NUM) 12867 return false; 12868 if (e->nt >= RTW89_NTX_NUM) 12869 return false; 12870 if (e->regd >= RTW89_REGD_NUM) 12871 return false; 12872 if (e->ch_idx >= RTW89_5G_CH_NUM) 12873 return false; 12874 12875 return true; 12876 } 12877 12878 static 12879 void rtw89_fw_load_txpwr_lmt_ru_5ghz(struct rtw89_txpwr_lmt_ru_5ghz_data *data) 12880 { 12881 const struct rtw89_txpwr_conf *conf = &data->conf; 12882 struct rtw89_fw_txpwr_lmt_ru_5ghz_entry entry = {}; 12883 const void *cursor; 12884 12885 rtw89_for_each_in_txpwr_conf(entry, cursor, conf) { 12886 if (!fw_txpwr_lmt_ru_5ghz_entry_valid(&entry, cursor, conf)) 12887 continue; 12888 12889 data->v[entry.ru][entry.nt][entry.regd][entry.ch_idx] = entry.v; 12890 } 12891 } 12892 12893 static bool 12894 fw_txpwr_lmt_ru_6ghz_entry_valid(const struct rtw89_fw_txpwr_lmt_ru_6ghz_entry *e, 12895 const void *cursor, 12896 const struct rtw89_txpwr_conf *conf) 12897 { 12898 if (!__fw_txpwr_entry_acceptable(e, cursor, conf->ent_sz)) 12899 return false; 12900 12901 if (e->ru >= RTW89_RU_NUM) 12902 return false; 12903 if (e->nt >= RTW89_NTX_NUM) 12904 return false; 12905 if (e->regd >= RTW89_REGD_NUM) 12906 return false; 12907 if (e->reg_6ghz_power >= NUM_OF_RTW89_REG_6GHZ_POWER) 12908 return false; 12909 if (e->ch_idx >= RTW89_6G_CH_NUM) 12910 return false; 12911 12912 return true; 12913 } 12914 12915 static 12916 void rtw89_fw_load_txpwr_lmt_ru_6ghz(struct rtw89_txpwr_lmt_ru_6ghz_data *data) 12917 { 12918 const struct rtw89_txpwr_conf *conf = &data->conf; 12919 struct rtw89_fw_txpwr_lmt_ru_6ghz_entry entry = {}; 12920 const void *cursor; 12921 12922 rtw89_for_each_in_txpwr_conf(entry, cursor, conf) { 12923 if (!fw_txpwr_lmt_ru_6ghz_entry_valid(&entry, cursor, conf)) 12924 continue; 12925 12926 data->v[entry.ru][entry.nt][entry.regd][entry.reg_6ghz_power] 12927 [entry.ch_idx] = entry.v; 12928 } 12929 } 12930 12931 static bool 12932 fw_tx_shape_lmt_entry_valid(const struct rtw89_fw_tx_shape_lmt_entry *e, 12933 const void *cursor, 12934 const struct rtw89_txpwr_conf *conf) 12935 { 12936 if (!__fw_txpwr_entry_acceptable(e, cursor, conf->ent_sz)) 12937 return false; 12938 12939 if (e->band >= RTW89_BAND_NUM) 12940 return false; 12941 if (e->tx_shape_rs >= RTW89_RS_TX_SHAPE_NUM) 12942 return false; 12943 if (e->regd >= RTW89_REGD_NUM) 12944 return false; 12945 12946 /* ensure compatibility work with 2/5 GHz */ 12947 static_assert(RTW89_REG_6GHZ_POWER_DFLT == 0); 12948 12949 if (e->reg6_pwr >= NUM_OF_RTW89_REG_6GHZ_POWER) 12950 return false; 12951 12952 return true; 12953 } 12954 12955 static 12956 void rtw89_fw_load_tx_shape_lmt(struct rtw89_tx_shape_lmt_data *data) 12957 { 12958 const struct rtw89_txpwr_conf *conf = &data->conf; 12959 struct rtw89_fw_tx_shape_lmt_entry entry = {}; 12960 const void *cursor; 12961 12962 rtw89_for_each_in_txpwr_conf(entry, cursor, conf) { 12963 if (!fw_tx_shape_lmt_entry_valid(&entry, cursor, conf)) 12964 continue; 12965 12966 data->v[entry.band][entry.tx_shape_rs][entry.regd][entry.reg6_pwr] = entry.v; 12967 } 12968 } 12969 12970 static bool 12971 fw_tx_shape_lmt_ru_entry_valid(const struct rtw89_fw_tx_shape_lmt_ru_entry *e, 12972 const void *cursor, 12973 const struct rtw89_txpwr_conf *conf) 12974 { 12975 if (!__fw_txpwr_entry_acceptable(e, cursor, conf->ent_sz)) 12976 return false; 12977 12978 if (e->band >= RTW89_BAND_NUM) 12979 return false; 12980 if (e->regd >= RTW89_REGD_NUM) 12981 return false; 12982 12983 /* ensure compatibility work with 2/5 GHz */ 12984 static_assert(RTW89_REG_6GHZ_POWER_DFLT == 0); 12985 12986 if (e->reg6_pwr >= NUM_OF_RTW89_REG_6GHZ_POWER) 12987 return false; 12988 12989 return true; 12990 } 12991 12992 static 12993 void rtw89_fw_load_tx_shape_lmt_ru(struct rtw89_tx_shape_lmt_ru_data *data) 12994 { 12995 const struct rtw89_txpwr_conf *conf = &data->conf; 12996 struct rtw89_fw_tx_shape_lmt_ru_entry entry = {}; 12997 const void *cursor; 12998 12999 rtw89_for_each_in_txpwr_conf(entry, cursor, conf) { 13000 if (!fw_tx_shape_lmt_ru_entry_valid(&entry, cursor, conf)) 13001 continue; 13002 13003 data->v[entry.band][entry.regd][entry.reg6_pwr] = entry.v; 13004 } 13005 } 13006 13007 static bool rtw89_fw_has_da_txpwr_table(struct rtw89_dev *rtwdev, 13008 const struct rtw89_rfe_parms *parms) 13009 { 13010 const struct rtw89_chip_info *chip = rtwdev->chip; 13011 13012 if (chip->support_bands & BIT(NL80211_BAND_2GHZ) && 13013 !(parms->rule_da_2ghz.lmt && parms->rule_da_2ghz.lmt_ru)) 13014 return false; 13015 13016 if (chip->support_bands & BIT(NL80211_BAND_5GHZ) && 13017 !(parms->rule_da_5ghz.lmt && parms->rule_da_5ghz.lmt_ru)) 13018 return false; 13019 13020 if (chip->support_bands & BIT(NL80211_BAND_6GHZ) && 13021 !(parms->rule_da_6ghz.lmt && parms->rule_da_6ghz.lmt_ru)) 13022 return false; 13023 13024 return true; 13025 } 13026 13027 const struct rtw89_rfe_parms * 13028 rtw89_load_rfe_data_from_fw(struct rtw89_dev *rtwdev, 13029 const struct rtw89_rfe_parms *init) 13030 { 13031 struct rtw89_rfe_data *rfe_data = rtwdev->rfe_data; 13032 struct rtw89_rfe_parms *parms; 13033 13034 if (!rfe_data) 13035 return init; 13036 13037 parms = &rfe_data->rfe_parms; 13038 if (init) 13039 *parms = *init; 13040 13041 if (rtw89_txpwr_conf_valid(&rfe_data->byrate.conf)) { 13042 rfe_data->byrate.tbl.data = &rfe_data->byrate.conf; 13043 rfe_data->byrate.tbl.size = 0; /* don't care here */ 13044 rfe_data->byrate.tbl.load = rtw89_fw_load_txpwr_byrate; 13045 parms->byr_tbl = &rfe_data->byrate.tbl; 13046 } 13047 13048 if (rtw89_txpwr_conf_valid(&rfe_data->lmt_2ghz.conf)) { 13049 rtw89_fw_load_txpwr_lmt_2ghz(&rfe_data->lmt_2ghz); 13050 parms->rule_2ghz.lmt = &rfe_data->lmt_2ghz.v; 13051 } 13052 13053 if (rtw89_txpwr_conf_valid(&rfe_data->lmt_5ghz.conf)) { 13054 rtw89_fw_load_txpwr_lmt_5ghz(&rfe_data->lmt_5ghz); 13055 parms->rule_5ghz.lmt = &rfe_data->lmt_5ghz.v; 13056 } 13057 13058 if (rtw89_txpwr_conf_valid(&rfe_data->lmt_6ghz.conf)) { 13059 rtw89_fw_load_txpwr_lmt_6ghz(&rfe_data->lmt_6ghz); 13060 parms->rule_6ghz.lmt = &rfe_data->lmt_6ghz.v; 13061 } 13062 13063 if (rtw89_txpwr_conf_valid(&rfe_data->da_lmt_2ghz.conf)) { 13064 rtw89_fw_load_txpwr_lmt_2ghz(&rfe_data->da_lmt_2ghz); 13065 parms->rule_da_2ghz.lmt = &rfe_data->da_lmt_2ghz.v; 13066 } 13067 13068 if (rtw89_txpwr_conf_valid(&rfe_data->da_lmt_5ghz.conf)) { 13069 rtw89_fw_load_txpwr_lmt_5ghz(&rfe_data->da_lmt_5ghz); 13070 parms->rule_da_5ghz.lmt = &rfe_data->da_lmt_5ghz.v; 13071 } 13072 13073 if (rtw89_txpwr_conf_valid(&rfe_data->da_lmt_6ghz.conf)) { 13074 rtw89_fw_load_txpwr_lmt_6ghz(&rfe_data->da_lmt_6ghz); 13075 parms->rule_da_6ghz.lmt = &rfe_data->da_lmt_6ghz.v; 13076 } 13077 13078 if (rtw89_txpwr_conf_valid(&rfe_data->lmt_ru_2ghz.conf)) { 13079 rtw89_fw_load_txpwr_lmt_ru_2ghz(&rfe_data->lmt_ru_2ghz); 13080 parms->rule_2ghz.lmt_ru = &rfe_data->lmt_ru_2ghz.v; 13081 } 13082 13083 if (rtw89_txpwr_conf_valid(&rfe_data->lmt_ru_5ghz.conf)) { 13084 rtw89_fw_load_txpwr_lmt_ru_5ghz(&rfe_data->lmt_ru_5ghz); 13085 parms->rule_5ghz.lmt_ru = &rfe_data->lmt_ru_5ghz.v; 13086 } 13087 13088 if (rtw89_txpwr_conf_valid(&rfe_data->lmt_ru_6ghz.conf)) { 13089 rtw89_fw_load_txpwr_lmt_ru_6ghz(&rfe_data->lmt_ru_6ghz); 13090 parms->rule_6ghz.lmt_ru = &rfe_data->lmt_ru_6ghz.v; 13091 } 13092 13093 if (rtw89_txpwr_conf_valid(&rfe_data->da_lmt_ru_2ghz.conf)) { 13094 rtw89_fw_load_txpwr_lmt_ru_2ghz(&rfe_data->da_lmt_ru_2ghz); 13095 parms->rule_da_2ghz.lmt_ru = &rfe_data->da_lmt_ru_2ghz.v; 13096 } 13097 13098 if (rtw89_txpwr_conf_valid(&rfe_data->da_lmt_ru_5ghz.conf)) { 13099 rtw89_fw_load_txpwr_lmt_ru_5ghz(&rfe_data->da_lmt_ru_5ghz); 13100 parms->rule_da_5ghz.lmt_ru = &rfe_data->da_lmt_ru_5ghz.v; 13101 } 13102 13103 if (rtw89_txpwr_conf_valid(&rfe_data->da_lmt_ru_6ghz.conf)) { 13104 rtw89_fw_load_txpwr_lmt_ru_6ghz(&rfe_data->da_lmt_ru_6ghz); 13105 parms->rule_da_6ghz.lmt_ru = &rfe_data->da_lmt_ru_6ghz.v; 13106 } 13107 13108 if (rtw89_txpwr_conf_valid(&rfe_data->tx_shape_lmt.conf)) { 13109 rtw89_fw_load_tx_shape_lmt(&rfe_data->tx_shape_lmt); 13110 parms->tx_shape.lmt = &rfe_data->tx_shape_lmt.v; 13111 } 13112 13113 if (rtw89_txpwr_conf_valid(&rfe_data->tx_shape_lmt_ru.conf)) { 13114 rtw89_fw_load_tx_shape_lmt_ru(&rfe_data->tx_shape_lmt_ru); 13115 parms->tx_shape.lmt_ru = &rfe_data->tx_shape_lmt_ru.v; 13116 } 13117 13118 parms->has_da = rtw89_fw_has_da_txpwr_table(rtwdev, parms); 13119 13120 return parms; 13121 } 13122 13123 static int rtw89_fw_cmd_ofld_pack(struct rtw89_dev *rtwdev) 13124 { 13125 struct rtw89_fw_cmd_ofld_info *info = rtwdev->fw_cmd_ofld_info; 13126 13127 lockdep_assert_wiphy(rtwdev->hw->wiphy); 13128 13129 info->pack_level++; 13130 13131 return 0; 13132 } 13133 13134 static void rtw89_fw_cmd_ofld_flush(struct rtw89_dev *rtwdev, 13135 struct rtw89_fw_cmd_ofld_info *info) 13136 { 13137 struct sk_buff *skb; 13138 int ret; 13139 u32 len; 13140 13141 len = info->cnt * sizeof(info->cmds[0]); 13142 skb = rtw89_fw_h2c_alloc_skb_with_hdr(rtwdev, len); 13143 if (!skb) { 13144 rtw89_err(rtwdev, "alloc skb fail\n"); 13145 goto out; 13146 } 13147 13148 skb_put_data(skb, info->cmds, len); 13149 13150 rtw89_h2c_pkt_set_hdr(rtwdev, skb, FWCMD_TYPE_H2C, 13151 H2C_CAT_MAC, 13152 H2C_CL_MAC_FW_OFLD, 13153 H2C_FUNC_CMD_OFLD_PKT, 0, 0, 13154 len); 13155 13156 ret = rtw89_h2c_tx(rtwdev, skb, false); 13157 if (ret) { 13158 rtw89_err(rtwdev, "failed to send cmd ofld\n"); 13159 dev_kfree_skb_any(skb); 13160 goto out; 13161 } 13162 13163 if (info->accu_delay) 13164 fsleep(info->accu_delay); 13165 13166 out: 13167 info->cnt = 0; 13168 info->accu_delay = 0; 13169 } 13170 13171 static int rtw89_fw_cmd_ofld_unpack(struct rtw89_dev *rtwdev) 13172 { 13173 struct rtw89_fw_cmd_ofld_info *info = rtwdev->fw_cmd_ofld_info; 13174 13175 lockdep_assert_wiphy(rtwdev->hw->wiphy); 13176 13177 if (info->pack_level == 0) 13178 return -EFAULT; 13179 13180 if (--info->pack_level != 0) 13181 return 0; 13182 13183 if (info->cnt == 0) 13184 return 0; 13185 13186 rtw89_fw_cmd_ofld_flush(rtwdev, info); 13187 13188 return 0; 13189 } 13190 13191 static int rtw89_fw_cmd_ofld_enqueue(struct rtw89_dev *rtwdev, 13192 const struct rtw89_fw_cmd_ofld_arg *cmd) 13193 { 13194 struct rtw89_fw_cmd_ofld_info *info = rtwdev->fw_cmd_ofld_info; 13195 struct rtw89_h2c_cmd_ofld *h2c; 13196 u32 base_off; 13197 13198 lockdep_assert_wiphy(rtwdev->hw->wiphy); 13199 13200 if (info->pack_level == 0) 13201 return 1; 13202 13203 if (!test_bit(RTW89_FLAG_FW_RDY, rtwdev->flags)) 13204 return -EBUSY; 13205 13206 if (cmd->type != RTW89_FW_CMD_OFLD_DELAY && 13207 cmd->src != RTW89_FW_CMD_OFLD_SRC_RF && 13208 cmd->src != RTW89_FW_CMD_OFLD_SRC_RF_DDIE && 13209 !IS_ALIGNED(cmd->offset, 4)) 13210 return -EFAULT; 13211 13212 if (info->cnt >= ARRAY_SIZE(info->cmds)) 13213 rtw89_fw_cmd_ofld_flush(rtwdev, info); 13214 13215 h2c = &info->cmds[info->cnt++]; 13216 13217 h2c->w0 = le32_encode_bits(cmd->src, RTW89_H2C_CMD_OFLD_W0_SRC) | 13218 le32_encode_bits(cmd->type, RTW89_H2C_CMD_OFLD_W0_TYPE) | 13219 le32_encode_bits(cmd->rf_path, RTW89_H2C_CMD_OFLD_W0_PATH) | 13220 le32_encode_bits(info->cnt, RTW89_H2C_CMD_OFLD_W0_CMD_NUM) | 13221 le32_encode_bits(cmd->offset, RTW89_H2C_CMD_OFLD_W0_OFFSET); 13222 13223 if (cmd->src == RTW89_FW_CMD_OFLD_SRC_RF_DDIE) 13224 base_off = 1; 13225 else if (cmd->src == RTW89_FW_CMD_OFLD_SRC_RF) 13226 base_off = 0; 13227 else 13228 base_off = cmd->offset >> 16; 13229 13230 h2c->w1 = le32_encode_bits(cmd->id, RTW89_H2C_CMD_OFLD_W1_ID) | 13231 le32_encode_bits(base_off, RTW89_H2C_CMD_OFLD_W1_BASE_OFFSET); 13232 h2c->w2 = le32_encode_bits(cmd->value, RTW89_H2C_CMD_OFLD_W2_VALUE); 13233 h2c->w3 = le32_encode_bits(cmd->mask, RTW89_H2C_CMD_OFLD_W3_MASK); 13234 13235 if (cmd->type == RTW89_FW_CMD_OFLD_DELAY) 13236 info->accu_delay += cmd->value; 13237 13238 return 0; 13239 } 13240 13241 static const struct rtw89_io_ops rtw89_raw_io = { 13242 .pack = rtw89_raw_io_pack, 13243 .unpack = rtw89_raw_io_unpack, 13244 .do_udelay = rtw89_raw_io_udelay, 13245 .do_mdelay = rtw89_raw_io_mdelay, 13246 .write8 = rtw89_raw_write8, 13247 .write16 = rtw89_raw_write16, 13248 .write32 = rtw89_raw_write32, 13249 .write8_set = rtw89_raw_write8_set, 13250 .write16_set = rtw89_raw_write16_set, 13251 .write32_set = rtw89_raw_write32_set, 13252 .write8_clr = rtw89_raw_write8_clr, 13253 .write16_clr = rtw89_raw_write16_clr, 13254 .write32_clr = rtw89_raw_write32_clr, 13255 .write8_mask = rtw89_raw_write8_mask, 13256 .write16_mask = rtw89_raw_write16_mask, 13257 .write32_mask = rtw89_raw_write32_mask, 13258 .phy_write8 = rtw89_raw_phy_write8, 13259 .phy_write16 = rtw89_raw_phy_write16, 13260 .phy_write32 = rtw89_raw_phy_write32, 13261 .write_rf = rtw89_raw_write_rf, 13262 }; 13263 13264 static 13265 void rtw89_fw_cmd_ofld_phy_write8(struct rtw89_dev *rtwdev, u32 addr, u8 data) 13266 { 13267 struct rtw89_fw_cmd_ofld_arg cmd = { 13268 .src = RTW89_FW_CMD_OFLD_SRC_BB, 13269 .type = RTW89_FW_CMD_OFLD_WRITE, 13270 .offset = ALIGN_DOWN(addr, 4), 13271 .mask = RTW89_W8_MASK_OF_ALIGNED_ADDR(addr), 13272 .value = data, 13273 }; 13274 int ret; 13275 13276 ret = rtw89_fw_cmd_ofld_enqueue(rtwdev, &cmd); 13277 if (ret) 13278 rtw89_raw_io.phy_write8(rtwdev, addr, data); 13279 } 13280 13281 static 13282 void rtw89_fw_cmd_ofld_phy_write16(struct rtw89_dev *rtwdev, u32 addr, u16 data) 13283 { 13284 struct rtw89_fw_cmd_ofld_arg cmd = { 13285 .src = RTW89_FW_CMD_OFLD_SRC_BB, 13286 .type = RTW89_FW_CMD_OFLD_WRITE, 13287 .offset = ALIGN_DOWN(addr, 2), 13288 .mask = RTW89_W16_MASK_OF_ALIGNED_ADDR(addr), 13289 .value = data, 13290 }; 13291 int ret; 13292 13293 ret = rtw89_fw_cmd_ofld_enqueue(rtwdev, &cmd); 13294 if (ret) 13295 rtw89_raw_io.phy_write16(rtwdev, addr, data); 13296 } 13297 13298 static 13299 void rtw89_fw_cmd_ofld_phy_write32(struct rtw89_dev *rtwdev, u32 addr, u32 data) 13300 { 13301 struct rtw89_fw_cmd_ofld_arg cmd = { 13302 .src = RTW89_FW_CMD_OFLD_SRC_BB, 13303 .type = RTW89_FW_CMD_OFLD_WRITE, 13304 .offset = addr, 13305 .mask = MASKDWORD, 13306 .value = data, 13307 }; 13308 int ret; 13309 13310 ret = rtw89_fw_cmd_ofld_enqueue(rtwdev, &cmd); 13311 if (ret) 13312 rtw89_raw_io.phy_write32(rtwdev, addr, data); 13313 } 13314 13315 static 13316 void rtw89_fw_cmd_ofld_write8(struct rtw89_dev *rtwdev, u32 addr, u8 data) 13317 { 13318 struct rtw89_fw_cmd_ofld_arg cmd = { 13319 .src = RTW89_FW_CMD_OFLD_SRC_MAC, 13320 .type = RTW89_FW_CMD_OFLD_WRITE, 13321 .offset = ALIGN_DOWN(addr, 4), 13322 .mask = RTW89_W8_MASK_OF_ALIGNED_ADDR(addr), 13323 .value = data, 13324 }; 13325 int ret; 13326 13327 ret = rtw89_fw_cmd_ofld_enqueue(rtwdev, &cmd); 13328 if (ret) 13329 rtw89_raw_io.write8(rtwdev, addr, data); 13330 } 13331 13332 static 13333 void rtw89_fw_cmd_ofld_write16(struct rtw89_dev *rtwdev, u32 addr, u16 data) 13334 { 13335 struct rtw89_fw_cmd_ofld_arg cmd = { 13336 .src = RTW89_FW_CMD_OFLD_SRC_MAC, 13337 .type = RTW89_FW_CMD_OFLD_WRITE, 13338 .offset = ALIGN_DOWN(addr, 2), 13339 .mask = RTW89_W16_MASK_OF_ALIGNED_ADDR(addr), 13340 .value = data, 13341 }; 13342 int ret; 13343 13344 ret = rtw89_fw_cmd_ofld_enqueue(rtwdev, &cmd); 13345 if (ret) 13346 rtw89_raw_io.write16(rtwdev, addr, data); 13347 } 13348 13349 static 13350 void rtw89_fw_cmd_ofld_write32(struct rtw89_dev *rtwdev, u32 addr, u32 data) 13351 { 13352 struct rtw89_fw_cmd_ofld_arg cmd = { 13353 .src = RTW89_FW_CMD_OFLD_SRC_MAC, 13354 .type = RTW89_FW_CMD_OFLD_WRITE, 13355 .offset = addr, 13356 .mask = MASKDWORD, 13357 .value = data, 13358 }; 13359 int ret; 13360 13361 ret = rtw89_fw_cmd_ofld_enqueue(rtwdev, &cmd); 13362 if (ret) 13363 rtw89_raw_io.write32(rtwdev, addr, data); 13364 } 13365 13366 static void 13367 rtw89_fw_cmd_ofld_write8_mask(struct rtw89_dev *rtwdev, u32 addr, u32 mask, 13368 u8 data) 13369 { 13370 u32 dword_mask = RTW89_W8_MASK_OF_ALIGNED_ADDR(addr); 13371 u32 shift = RTW89_W8_SHIFT_OF_ALIGNED_ADDR(addr); 13372 struct rtw89_fw_cmd_ofld_arg cmd = { 13373 .src = RTW89_FW_CMD_OFLD_SRC_MAC, 13374 .type = RTW89_FW_CMD_OFLD_WRITE, 13375 .offset = ALIGN_DOWN(addr, 4), 13376 .mask = (mask << shift) & dword_mask, 13377 .value = (data << shift) & dword_mask, 13378 }; 13379 int ret; 13380 13381 ret = rtw89_fw_cmd_ofld_enqueue(rtwdev, &cmd); 13382 if (ret) 13383 rtw89_raw_io.write8_mask(rtwdev, addr, mask, data); 13384 } 13385 13386 static void 13387 rtw89_fw_cmd_ofld_write16_mask(struct rtw89_dev *rtwdev, u32 addr, u32 mask, 13388 u16 data) 13389 { 13390 u32 dword_mask = RTW89_W16_MASK_OF_ALIGNED_ADDR(addr); 13391 u32 shift = RTW89_W16_SHIFT_OF_ALIGNED_ADDR(addr); 13392 struct rtw89_fw_cmd_ofld_arg cmd = { 13393 .src = RTW89_FW_CMD_OFLD_SRC_MAC, 13394 .type = RTW89_FW_CMD_OFLD_WRITE, 13395 .offset = ALIGN_DOWN(addr, 4), 13396 .mask = (mask << shift) & dword_mask, 13397 .value = (data << shift) & dword_mask, 13398 }; 13399 int ret; 13400 13401 ret = rtw89_fw_cmd_ofld_enqueue(rtwdev, &cmd); 13402 if (ret) 13403 rtw89_raw_io.write16_mask(rtwdev, addr, mask, data); 13404 } 13405 13406 static void 13407 rtw89_fw_cmd_ofld_write32_mask(struct rtw89_dev *rtwdev, u32 addr, u32 mask, 13408 u32 data) 13409 { 13410 struct rtw89_fw_cmd_ofld_arg cmd = { 13411 .src = RTW89_FW_CMD_OFLD_SRC_MAC, 13412 .type = RTW89_FW_CMD_OFLD_WRITE, 13413 .offset = addr, 13414 .mask = mask, 13415 .value = data, 13416 }; 13417 int ret; 13418 13419 ret = rtw89_fw_cmd_ofld_enqueue(rtwdev, &cmd); 13420 if (ret) 13421 rtw89_raw_io.write32_mask(rtwdev, addr, mask, data); 13422 } 13423 13424 static void 13425 rtw89_fw_cmd_ofld_write8_set(struct rtw89_dev *rtwdev, u32 addr, u8 bit) 13426 { 13427 rtw89_fw_cmd_ofld_write8_mask(rtwdev, addr, bit, bit); 13428 } 13429 13430 static void 13431 rtw89_fw_cmd_ofld_write16_set(struct rtw89_dev *rtwdev, u32 addr, u16 bit) 13432 { 13433 rtw89_fw_cmd_ofld_write16_mask(rtwdev, addr, bit, bit); 13434 } 13435 13436 static void 13437 rtw89_fw_cmd_ofld_write32_set(struct rtw89_dev *rtwdev, u32 addr, u32 bit) 13438 { 13439 rtw89_fw_cmd_ofld_write32_mask(rtwdev, addr, bit, bit); 13440 } 13441 13442 static void 13443 rtw89_fw_cmd_ofld_write8_clr(struct rtw89_dev *rtwdev, u32 addr, u8 bit) 13444 { 13445 rtw89_fw_cmd_ofld_write8_mask(rtwdev, addr, bit, 0); 13446 } 13447 13448 static void 13449 rtw89_fw_cmd_ofld_write16_clr(struct rtw89_dev *rtwdev, u32 addr, u16 bit) 13450 { 13451 rtw89_fw_cmd_ofld_write16_mask(rtwdev, addr, bit, 0); 13452 } 13453 13454 static void 13455 rtw89_fw_cmd_ofld_write32_clr(struct rtw89_dev *rtwdev, u32 addr, u32 bit) 13456 { 13457 rtw89_fw_cmd_ofld_write32_mask(rtwdev, addr, bit, 0); 13458 } 13459 13460 static void rtw89_fw_cmd_ofld_write_rf_ddv(struct rtw89_dev *rtwdev, 13461 struct rtw89_fw_cmd_ofld_arg *cmd, 13462 enum rtw89_rf_path rf_path, u32 addr, u32 mask, 13463 u32 data) 13464 { 13465 const struct rtw89_chip_info *chip = rtwdev->chip; 13466 13467 *cmd = (typeof(*cmd)){ 13468 .src = RTW89_FW_CMD_OFLD_SRC_BB, 13469 .type = RTW89_FW_CMD_OFLD_WRITE, 13470 .rf_path = 0, /* Set rf_path to zero in rf_ddv */ 13471 .offset = chip->rf_base_addr[rf_path] + ((addr & 0xff) << 2), 13472 .mask = mask, 13473 .value = data, 13474 }; 13475 } 13476 13477 static void rtw89_fw_cmd_ofld_write_rf_dav(struct rtw89_dev *rtwdev, 13478 struct rtw89_fw_cmd_ofld_arg *cmd, 13479 enum rtw89_rf_path rf_path, u32 addr, u32 mask, 13480 u32 data) 13481 { 13482 *cmd = (typeof(*cmd)){ 13483 .src = RTW89_FW_CMD_OFLD_SRC_RF, 13484 .type = RTW89_FW_CMD_OFLD_WRITE, 13485 .rf_path = rf_path, 13486 .offset = addr, 13487 .mask = mask, 13488 .value = data, 13489 }; 13490 } 13491 13492 static void rtw89_fw_cmd_ofld_write_rf(struct rtw89_dev *rtwdev, 13493 enum rtw89_rf_path rf_path, u32 addr, u32 mask, 13494 u32 data) 13495 { 13496 const struct rtw89_chip_info *chip = rtwdev->chip; 13497 bool ad_sel = u32_get_bits(addr, RTW89_RF_ADDR_ADSEL_MASK); 13498 struct rtw89_fw_cmd_ofld_arg cmd; 13499 int ret; 13500 13501 if (unlikely(rf_path >= chip->rf_path_num)) { 13502 rtw89_warn(rtwdev, "unsupported rf path (%d) in fw offload\n", rf_path); 13503 return; 13504 } 13505 13506 if (ad_sel) 13507 rtw89_fw_cmd_ofld_write_rf_ddv(rtwdev, &cmd, rf_path, addr, mask, data); 13508 else 13509 rtw89_fw_cmd_ofld_write_rf_dav(rtwdev, &cmd, rf_path, addr, mask, data); 13510 13511 ret = rtw89_fw_cmd_ofld_enqueue(rtwdev, &cmd); 13512 if (ret) 13513 rtw89_raw_io.write_rf(rtwdev, rf_path, addr, mask, data); 13514 } 13515 13516 static void rtw89_fw_cmd_ofld_udelay(struct rtw89_dev *rtwdev, u32 us) 13517 { 13518 struct rtw89_fw_cmd_ofld_arg cmd = { 13519 .src = RTW89_FW_CMD_OFLD_SRC_MAC, 13520 .type = RTW89_FW_CMD_OFLD_DELAY, 13521 .value = us, 13522 }; 13523 int ret; 13524 13525 ret = rtw89_fw_cmd_ofld_enqueue(rtwdev, &cmd); 13526 if (ret) 13527 rtw89_raw_io.do_udelay(rtwdev, us); 13528 } 13529 13530 static void rtw89_fw_cmd_ofld_mdelay(struct rtw89_dev *rtwdev, u32 ms) 13531 { 13532 struct rtw89_fw_cmd_ofld_arg cmd = { 13533 .src = RTW89_FW_CMD_OFLD_SRC_MAC, 13534 .type = RTW89_FW_CMD_OFLD_DELAY, 13535 .value = ms * 1000, 13536 }; 13537 int ret; 13538 13539 ret = rtw89_fw_cmd_ofld_enqueue(rtwdev, &cmd); 13540 if (ret) 13541 rtw89_raw_io.do_mdelay(rtwdev, ms); 13542 } 13543 13544 static const struct rtw89_io_ops rtw89_fw_cmd_ofld_io = { 13545 .pack = rtw89_fw_cmd_ofld_pack, 13546 .unpack = rtw89_fw_cmd_ofld_unpack, 13547 .do_udelay = rtw89_fw_cmd_ofld_udelay, 13548 .do_mdelay = rtw89_fw_cmd_ofld_mdelay, 13549 .write8 = rtw89_fw_cmd_ofld_write8, 13550 .write16 = rtw89_fw_cmd_ofld_write16, 13551 .write32 = rtw89_fw_cmd_ofld_write32, 13552 .phy_write8 = rtw89_fw_cmd_ofld_phy_write8, 13553 .phy_write16 = rtw89_fw_cmd_ofld_phy_write16, 13554 .phy_write32 = rtw89_fw_cmd_ofld_phy_write32, 13555 .write_rf = rtw89_fw_cmd_ofld_write_rf, 13556 .write8_set = rtw89_fw_cmd_ofld_write8_set, 13557 .write16_set = rtw89_fw_cmd_ofld_write16_set, 13558 .write32_set = rtw89_fw_cmd_ofld_write32_set, 13559 .write8_clr = rtw89_fw_cmd_ofld_write8_clr, 13560 .write16_clr = rtw89_fw_cmd_ofld_write16_clr, 13561 .write32_clr = rtw89_fw_cmd_ofld_write32_clr, 13562 .write8_mask = rtw89_fw_cmd_ofld_write8_mask, 13563 .write16_mask = rtw89_fw_cmd_ofld_write16_mask, 13564 .write32_mask = rtw89_fw_cmd_ofld_write32_mask, 13565 }; 13566 13567 const struct rtw89_io_ops * 13568 rtw89_fw_cmd_ofld_alloc_and_get_io_ops(struct rtw89_dev *rtwdev) 13569 { 13570 const struct rtw89_chip_info *chip = rtwdev->chip; 13571 struct rtw89_fw_cmd_ofld_info *info; 13572 13573 if (!(rtwdev->hci.type == RTW89_HCI_TYPE_USB && chip->support_fw_cmd_ofld)) 13574 return &rtw89_raw_io; 13575 13576 info = devm_kzalloc(rtwdev->dev, sizeof(*info), GFP_KERNEL); 13577 if (!info) 13578 return &rtw89_raw_io; 13579 13580 rtwdev->fw_cmd_ofld_info = info; 13581 13582 return &rtw89_fw_cmd_ofld_io; 13583 } 13584