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