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 #if defined(__linux__) 75 const void *content, 76 #elif defined(__FreeBSD__) 77 const u8 *content, 78 #endif 79 u32 *mssc_len); 80 81 static struct sk_buff *rtw89_fw_h2c_alloc_skb(struct rtw89_dev *rtwdev, u32 len, 82 bool header) 83 { 84 struct sk_buff *skb; 85 u32 header_len = 0; 86 u32 h2c_desc_size = rtwdev->chip->h2c_desc_size; 87 88 if (header) 89 header_len = H2C_HEADER_LEN; 90 91 skb = dev_alloc_skb(len + header_len + h2c_desc_size); 92 if (!skb) 93 return NULL; 94 skb_reserve(skb, header_len + h2c_desc_size); 95 memset(skb->data, 0, len); 96 97 return skb; 98 } 99 100 struct sk_buff *rtw89_fw_h2c_alloc_skb_with_hdr(struct rtw89_dev *rtwdev, u32 len) 101 { 102 return rtw89_fw_h2c_alloc_skb(rtwdev, len, true); 103 } 104 105 struct sk_buff *rtw89_fw_h2c_alloc_skb_no_hdr(struct rtw89_dev *rtwdev, u32 len) 106 { 107 return rtw89_fw_h2c_alloc_skb(rtwdev, len, false); 108 } 109 110 int rtw89_fw_check_rdy(struct rtw89_dev *rtwdev, enum rtw89_fwdl_check_type type) 111 { 112 const struct rtw89_mac_gen_def *mac = rtwdev->chip->mac_def; 113 u8 val; 114 int ret; 115 116 ret = read_poll_timeout_atomic(mac->fwdl_get_status, val, 117 val == RTW89_FWDL_WCPU_FW_INIT_RDY, 118 1, FWDL_WAIT_CNT, false, rtwdev, type); 119 if (ret) { 120 switch (val) { 121 case RTW89_FWDL_CHECKSUM_FAIL: 122 rtw89_err(rtwdev, "fw checksum fail\n"); 123 return -EINVAL; 124 125 case RTW89_FWDL_SECURITY_FAIL: 126 rtw89_err(rtwdev, "fw security fail\n"); 127 return -EINVAL; 128 129 case RTW89_FWDL_CV_NOT_MATCH: 130 rtw89_err(rtwdev, "fw cv not match\n"); 131 return -EINVAL; 132 133 default: 134 rtw89_err(rtwdev, "fw unexpected status %d\n", val); 135 return -EBUSY; 136 } 137 } 138 139 set_bit(RTW89_FLAG_FW_RDY, rtwdev->flags); 140 141 return 0; 142 } 143 144 static int rtw89_fw_hdr_parser_v0(struct rtw89_dev *rtwdev, const u8 *fw, u32 len, 145 struct rtw89_fw_bin_info *info) 146 { 147 const struct rtw89_fw_hdr *fw_hdr = (const struct rtw89_fw_hdr *)fw; 148 const struct rtw89_chip_info *chip = rtwdev->chip; 149 struct rtw89_fw_hdr_section_info *section_info; 150 struct rtw89_fw_secure *sec = &rtwdev->fw.sec; 151 const struct rtw89_fw_dynhdr_hdr *fwdynhdr; 152 const struct rtw89_fw_hdr_section *section; 153 const u8 *fw_end = fw + len; 154 const u8 *bin; 155 u32 base_hdr_len; 156 u32 mssc_len; 157 int ret; 158 u32 i; 159 160 if (!info) 161 return -EINVAL; 162 163 info->section_num = le32_get_bits(fw_hdr->w6, FW_HDR_W6_SEC_NUM); 164 base_hdr_len = struct_size(fw_hdr, sections, info->section_num); 165 info->dynamic_hdr_en = le32_get_bits(fw_hdr->w7, FW_HDR_W7_DYN_HDR); 166 info->idmem_share_mode = le32_get_bits(fw_hdr->w7, FW_HDR_W7_IDMEM_SHARE_MODE); 167 168 if (info->dynamic_hdr_en) { 169 info->hdr_len = le32_get_bits(fw_hdr->w3, FW_HDR_W3_LEN); 170 info->dynamic_hdr_len = info->hdr_len - base_hdr_len; 171 fwdynhdr = (const struct rtw89_fw_dynhdr_hdr *)(fw + base_hdr_len); 172 if (le32_to_cpu(fwdynhdr->hdr_len) != info->dynamic_hdr_len) { 173 rtw89_err(rtwdev, "[ERR]invalid fw dynamic header len\n"); 174 return -EINVAL; 175 } 176 } else { 177 info->hdr_len = base_hdr_len; 178 info->dynamic_hdr_len = 0; 179 } 180 181 bin = fw + info->hdr_len; 182 183 /* jump to section header */ 184 section_info = info->section_info; 185 for (i = 0; i < info->section_num; i++) { 186 section = &fw_hdr->sections[i]; 187 section_info->type = 188 le32_get_bits(section->w1, FWSECTION_HDR_W1_SECTIONTYPE); 189 section_info->len = le32_get_bits(section->w1, FWSECTION_HDR_W1_SEC_SIZE); 190 191 if (le32_get_bits(section->w1, FWSECTION_HDR_W1_CHECKSUM)) 192 section_info->len += FWDL_SECTION_CHKSUM_LEN; 193 section_info->redl = le32_get_bits(section->w1, FWSECTION_HDR_W1_REDL); 194 section_info->dladdr = 195 le32_get_bits(section->w0, FWSECTION_HDR_W0_DL_ADDR) & 0x1fffffff; 196 section_info->addr = bin; 197 198 if (section_info->type == FWDL_SECURITY_SECTION_TYPE) { 199 section_info->mssc = 200 le32_get_bits(section->w2, FWSECTION_HDR_W2_MSSC); 201 202 ret = __parse_security_section(rtwdev, info, section_info, 203 bin, &mssc_len); 204 if (ret) 205 return ret; 206 207 if (sec->secure_boot && chip->chip_id == RTL8852B) 208 section_info->len_override = 960; 209 } else { 210 section_info->mssc = 0; 211 mssc_len = 0; 212 } 213 214 rtw89_debug(rtwdev, RTW89_DBG_FW, 215 "section[%d] type=%d len=0x%-6x mssc=%d mssc_len=%d addr=%tx\n", 216 i, section_info->type, section_info->len, 217 section_info->mssc, mssc_len, bin - fw); 218 rtw89_debug(rtwdev, RTW89_DBG_FW, 219 " ignore=%d key_addr=%p (0x%tx) key_len=%d key_idx=%d\n", 220 section_info->ignore, section_info->key_addr, 221 section_info->key_addr ? 222 section_info->key_addr - section_info->addr : 0, 223 section_info->key_len, section_info->key_idx); 224 225 bin += section_info->len + mssc_len; 226 section_info++; 227 } 228 229 if (fw_end != bin) { 230 rtw89_err(rtwdev, "[ERR]fw bin size\n"); 231 return -EINVAL; 232 } 233 234 return 0; 235 } 236 237 static int __get_mssc_key_idx(struct rtw89_dev *rtwdev, 238 const struct rtw89_fw_mss_pool_hdr *mss_hdr, 239 u32 rmp_tbl_size, u32 *key_idx) 240 { 241 struct rtw89_fw_secure *sec = &rtwdev->fw.sec; 242 u32 sel_byte_idx; 243 u32 mss_sel_idx; 244 u8 sel_bit_idx; 245 int i; 246 247 if (sec->mss_dev_type == RTW89_FW_MSS_DEV_TYPE_FWSEC_DEF) { 248 if (!mss_hdr->defen) 249 return -ENOENT; 250 251 mss_sel_idx = sec->mss_cust_idx * le16_to_cpu(mss_hdr->msskey_num_max) + 252 sec->mss_key_num; 253 } else { 254 if (mss_hdr->defen) 255 mss_sel_idx = FWDL_MSS_POOL_DEFKEYSETS_SIZE << 3; 256 else 257 mss_sel_idx = 0; 258 mss_sel_idx += sec->mss_dev_type * le16_to_cpu(mss_hdr->msskey_num_max) * 259 le16_to_cpu(mss_hdr->msscust_max) + 260 sec->mss_cust_idx * le16_to_cpu(mss_hdr->msskey_num_max) + 261 sec->mss_key_num; 262 } 263 264 sel_byte_idx = mss_sel_idx >> 3; 265 sel_bit_idx = mss_sel_idx & 0x7; 266 267 if (sel_byte_idx >= rmp_tbl_size) 268 return -EFAULT; 269 270 if (!(mss_hdr->rmp_tbl[sel_byte_idx] & BIT(sel_bit_idx))) 271 return -ENOENT; 272 273 *key_idx = hweight8(mss_hdr->rmp_tbl[sel_byte_idx] & (BIT(sel_bit_idx) - 1)); 274 275 for (i = 0; i < sel_byte_idx; i++) 276 *key_idx += hweight8(mss_hdr->rmp_tbl[i]); 277 278 return 0; 279 } 280 281 static int __parse_formatted_mssc(struct rtw89_dev *rtwdev, 282 struct rtw89_fw_bin_info *info, 283 struct rtw89_fw_hdr_section_info *section_info, 284 #if defined(__linux__) 285 const void *content, 286 #elif defined(__FreeBSD__) 287 const u8 *content, 288 #endif 289 u32 *mssc_len) 290 { 291 #if defined(__linux__) 292 const struct rtw89_fw_mss_pool_hdr *mss_hdr = content + section_info->len; 293 const union rtw89_fw_section_mssc_content *section_content = content; 294 #elif defined(__FreeBSD__) 295 const struct rtw89_fw_mss_pool_hdr *mss_hdr = (const void *)(content + section_info->len); 296 const union rtw89_fw_section_mssc_content *section_content = (const void *)content; 297 #endif 298 struct rtw89_fw_secure *sec = &rtwdev->fw.sec; 299 u32 rmp_tbl_size; 300 u32 key_sign_len; 301 u32 real_key_idx; 302 u32 sb_sel_ver; 303 int ret; 304 305 if (memcmp(mss_signature, mss_hdr->signature, sizeof(mss_signature)) != 0) { 306 rtw89_err(rtwdev, "[ERR] wrong MSS signature\n"); 307 return -ENOENT; 308 } 309 310 if (mss_hdr->rmpfmt == MSS_POOL_RMP_TBL_BITMASK) { 311 rmp_tbl_size = (le16_to_cpu(mss_hdr->msskey_num_max) * 312 le16_to_cpu(mss_hdr->msscust_max) * 313 mss_hdr->mssdev_max) >> 3; 314 if (mss_hdr->defen) 315 rmp_tbl_size += FWDL_MSS_POOL_DEFKEYSETS_SIZE; 316 } else { 317 rtw89_err(rtwdev, "[ERR] MSS Key Pool Remap Table Format Unsupport:%X\n", 318 mss_hdr->rmpfmt); 319 return -EINVAL; 320 } 321 322 if (rmp_tbl_size + sizeof(*mss_hdr) != le32_to_cpu(mss_hdr->key_raw_offset)) { 323 rtw89_err(rtwdev, "[ERR] MSS Key Pool Format Error:0x%X + 0x%X != 0x%X\n", 324 rmp_tbl_size, (int)sizeof(*mss_hdr), 325 le32_to_cpu(mss_hdr->key_raw_offset)); 326 return -EINVAL; 327 } 328 329 key_sign_len = le16_to_cpu(section_content->key_sign_len.v) >> 2; 330 if (!key_sign_len) 331 key_sign_len = 512; 332 333 if (info->dsp_checksum) 334 key_sign_len += FWDL_SECURITY_CHKSUM_LEN; 335 336 *mssc_len = sizeof(*mss_hdr) + rmp_tbl_size + 337 le16_to_cpu(mss_hdr->keypair_num) * key_sign_len; 338 339 if (!sec->secure_boot) 340 goto out; 341 342 sb_sel_ver = get_unaligned_le32(§ion_content->sb_sel_ver.v); 343 if (sb_sel_ver && sb_sel_ver != sec->sb_sel_mgn) 344 goto ignore; 345 346 ret = __get_mssc_key_idx(rtwdev, mss_hdr, rmp_tbl_size, &real_key_idx); 347 if (ret) 348 goto ignore; 349 350 section_info->key_addr = content + section_info->len + 351 le32_to_cpu(mss_hdr->key_raw_offset) + 352 key_sign_len * real_key_idx; 353 section_info->key_len = key_sign_len; 354 section_info->key_idx = real_key_idx; 355 356 out: 357 if (info->secure_section_exist) { 358 section_info->ignore = true; 359 return 0; 360 } 361 362 info->secure_section_exist = true; 363 364 return 0; 365 366 ignore: 367 section_info->ignore = true; 368 369 return 0; 370 } 371 372 static int __check_secure_blacklist(struct rtw89_dev *rtwdev, 373 struct rtw89_fw_bin_info *info, 374 struct rtw89_fw_hdr_section_info *section_info, 375 const void *content) 376 { 377 const struct rtw89_fw_blacklist *chip_blacklist = rtwdev->chip->fw_blacklist; 378 const union rtw89_fw_section_mssc_content *section_content = content; 379 struct rtw89_fw_secure *sec = &rtwdev->fw.sec; 380 u8 byte_idx; 381 u8 bit_mask; 382 383 if (!sec->secure_boot) 384 return 0; 385 386 if (!info->secure_section_exist || section_info->ignore) 387 return 0; 388 389 if (!chip_blacklist) { 390 rtw89_warn(rtwdev, "chip no blacklist for secure firmware\n"); 391 return -ENOENT; 392 } 393 394 byte_idx = section_content->blacklist.bit_in_chip_list >> 3; 395 bit_mask = BIT(section_content->blacklist.bit_in_chip_list & 0x7); 396 397 if (section_content->blacklist.ver > chip_blacklist->ver) { 398 rtw89_warn(rtwdev, "chip blacklist out of date (%u, %u)\n", 399 section_content->blacklist.ver, chip_blacklist->ver); 400 return -EINVAL; 401 } 402 403 if (chip_blacklist->list[byte_idx] & bit_mask) { 404 rtw89_warn(rtwdev, "firmware %u in chip blacklist\n", 405 section_content->blacklist.ver); 406 return -EPERM; 407 } 408 409 return 0; 410 } 411 412 static int __parse_security_section(struct rtw89_dev *rtwdev, 413 struct rtw89_fw_bin_info *info, 414 struct rtw89_fw_hdr_section_info *section_info, 415 #if defined(__linux__) 416 const void *content, 417 #elif defined(__FreeBSD__) 418 const u8 *content, 419 #endif 420 u32 *mssc_len) 421 { 422 struct rtw89_fw_secure *sec = &rtwdev->fw.sec; 423 int ret; 424 425 if ((section_info->mssc & FORMATTED_MSSC_MASK) == FORMATTED_MSSC) { 426 ret = __parse_formatted_mssc(rtwdev, info, section_info, 427 content, mssc_len); 428 if (ret) 429 return -EINVAL; 430 } else { 431 *mssc_len = section_info->mssc * FWDL_SECURITY_SIGLEN; 432 if (info->dsp_checksum) 433 *mssc_len += section_info->mssc * FWDL_SECURITY_CHKSUM_LEN; 434 435 if (sec->secure_boot) { 436 if (sec->mss_idx >= section_info->mssc) { 437 rtw89_err(rtwdev, "unexpected MSS %d >= %d\n", 438 sec->mss_idx, section_info->mssc); 439 return -EFAULT; 440 } 441 section_info->key_addr = content + section_info->len + 442 sec->mss_idx * FWDL_SECURITY_SIGLEN; 443 section_info->key_len = FWDL_SECURITY_SIGLEN; 444 } 445 446 info->secure_section_exist = true; 447 } 448 449 ret = __check_secure_blacklist(rtwdev, info, section_info, content); 450 WARN_ONCE(ret, "Current firmware in blacklist. Please update firmware.\n"); 451 452 return 0; 453 } 454 455 static int rtw89_fw_hdr_parser_v1(struct rtw89_dev *rtwdev, const u8 *fw, u32 len, 456 struct rtw89_fw_bin_info *info) 457 { 458 const struct rtw89_fw_hdr_v1 *fw_hdr = (const struct rtw89_fw_hdr_v1 *)fw; 459 struct rtw89_fw_hdr_section_info *section_info; 460 const struct rtw89_fw_dynhdr_hdr *fwdynhdr; 461 const struct rtw89_fw_hdr_section_v1 *section; 462 const u8 *fw_end = fw + len; 463 const u8 *bin; 464 u32 base_hdr_len; 465 u32 mssc_len; 466 int ret; 467 u32 i; 468 469 info->section_num = le32_get_bits(fw_hdr->w6, FW_HDR_V1_W6_SEC_NUM); 470 info->dsp_checksum = le32_get_bits(fw_hdr->w6, FW_HDR_V1_W6_DSP_CHKSUM); 471 base_hdr_len = struct_size(fw_hdr, sections, info->section_num); 472 info->dynamic_hdr_en = le32_get_bits(fw_hdr->w7, FW_HDR_V1_W7_DYN_HDR); 473 info->idmem_share_mode = le32_get_bits(fw_hdr->w7, FW_HDR_V1_W7_IDMEM_SHARE_MODE); 474 475 if (info->dynamic_hdr_en) { 476 info->hdr_len = le32_get_bits(fw_hdr->w5, FW_HDR_V1_W5_HDR_SIZE); 477 info->dynamic_hdr_len = info->hdr_len - base_hdr_len; 478 fwdynhdr = (const struct rtw89_fw_dynhdr_hdr *)(fw + base_hdr_len); 479 if (le32_to_cpu(fwdynhdr->hdr_len) != info->dynamic_hdr_len) { 480 rtw89_err(rtwdev, "[ERR]invalid fw dynamic header len\n"); 481 return -EINVAL; 482 } 483 } else { 484 info->hdr_len = base_hdr_len; 485 info->dynamic_hdr_len = 0; 486 } 487 488 bin = fw + info->hdr_len; 489 490 /* jump to section header */ 491 section_info = info->section_info; 492 for (i = 0; i < info->section_num; i++) { 493 section = &fw_hdr->sections[i]; 494 495 section_info->type = 496 le32_get_bits(section->w1, FWSECTION_HDR_V1_W1_SECTIONTYPE); 497 section_info->len = 498 le32_get_bits(section->w1, FWSECTION_HDR_V1_W1_SEC_SIZE); 499 if (le32_get_bits(section->w1, FWSECTION_HDR_V1_W1_CHECKSUM)) 500 section_info->len += FWDL_SECTION_CHKSUM_LEN; 501 section_info->redl = le32_get_bits(section->w1, FWSECTION_HDR_V1_W1_REDL); 502 section_info->dladdr = 503 le32_get_bits(section->w0, FWSECTION_HDR_V1_W0_DL_ADDR); 504 section_info->addr = bin; 505 506 if (section_info->type == FWDL_SECURITY_SECTION_TYPE) { 507 section_info->mssc = 508 le32_get_bits(section->w2, FWSECTION_HDR_V1_W2_MSSC); 509 510 ret = __parse_security_section(rtwdev, info, section_info, 511 bin, &mssc_len); 512 if (ret) 513 return ret; 514 } else { 515 section_info->mssc = 0; 516 mssc_len = 0; 517 } 518 519 rtw89_debug(rtwdev, RTW89_DBG_FW, 520 "section[%d] type=%d len=0x%-6x mssc=%d mssc_len=%d addr=%tx\n", 521 i, section_info->type, section_info->len, 522 section_info->mssc, mssc_len, bin - fw); 523 rtw89_debug(rtwdev, RTW89_DBG_FW, 524 " ignore=%d key_addr=%p (0x%tx) key_len=%d key_idx=%d\n", 525 section_info->ignore, section_info->key_addr, 526 section_info->key_addr ? 527 section_info->key_addr - section_info->addr : 0, 528 section_info->key_len, section_info->key_idx); 529 530 bin += section_info->len + mssc_len; 531 section_info++; 532 } 533 534 if (fw_end != bin) { 535 rtw89_err(rtwdev, "[ERR]fw bin size\n"); 536 return -EINVAL; 537 } 538 539 if (!info->secure_section_exist) 540 rtw89_warn(rtwdev, "no firmware secure section\n"); 541 542 return 0; 543 } 544 545 static int rtw89_fw_hdr_parser(struct rtw89_dev *rtwdev, 546 const struct rtw89_fw_suit *fw_suit, 547 struct rtw89_fw_bin_info *info) 548 { 549 const u8 *fw = fw_suit->data; 550 u32 len = fw_suit->size; 551 552 if (!fw || !len) { 553 rtw89_err(rtwdev, "fw type %d isn't recognized\n", fw_suit->type); 554 return -ENOENT; 555 } 556 557 switch (fw_suit->hdr_ver) { 558 case 0: 559 return rtw89_fw_hdr_parser_v0(rtwdev, fw, len, info); 560 case 1: 561 return rtw89_fw_hdr_parser_v1(rtwdev, fw, len, info); 562 default: 563 return -ENOENT; 564 } 565 } 566 567 static 568 const struct rtw89_mfw_hdr *rtw89_mfw_get_hdr_ptr(struct rtw89_dev *rtwdev, 569 const struct firmware *firmware) 570 { 571 const struct rtw89_mfw_hdr *mfw_hdr; 572 573 if (sizeof(*mfw_hdr) > firmware->size) 574 return NULL; 575 576 mfw_hdr = (const struct rtw89_mfw_hdr *)&firmware->data[0]; 577 578 if (mfw_hdr->sig != RTW89_MFW_SIG) 579 return NULL; 580 581 return mfw_hdr; 582 } 583 584 static int rtw89_mfw_validate_hdr(struct rtw89_dev *rtwdev, 585 const struct firmware *firmware, 586 const struct rtw89_mfw_hdr *mfw_hdr) 587 { 588 #if defined(__linux__) 589 const void *mfw = firmware->data; 590 #elif defined(__FreeBSD__) 591 const u8 *mfw = firmware->data; 592 #endif 593 u32 mfw_len = firmware->size; 594 u8 fw_nr = mfw_hdr->fw_nr; 595 const void *ptr; 596 597 if (fw_nr == 0) { 598 rtw89_err(rtwdev, "mfw header has no fw entry\n"); 599 return -ENOENT; 600 } 601 602 ptr = &mfw_hdr->info[fw_nr]; 603 604 #if defined(__linux__) 605 if (ptr > mfw + mfw_len) { 606 #elif defined(__FreeBSD__) 607 if ((const u8 *)ptr > mfw + mfw_len) { 608 #endif 609 rtw89_err(rtwdev, "mfw header out of address\n"); 610 return -EFAULT; 611 } 612 613 return 0; 614 } 615 616 static 617 int rtw89_mfw_recognize(struct rtw89_dev *rtwdev, enum rtw89_fw_type type, 618 struct rtw89_fw_suit *fw_suit, bool nowarn) 619 { 620 struct rtw89_fw_info *fw_info = &rtwdev->fw; 621 const struct firmware *firmware = fw_info->req.firmware; 622 const struct rtw89_mfw_info *mfw_info = NULL, *tmp; 623 const struct rtw89_mfw_hdr *mfw_hdr; 624 const u8 *mfw = firmware->data; 625 u32 mfw_len = firmware->size; 626 int ret; 627 int i; 628 629 mfw_hdr = rtw89_mfw_get_hdr_ptr(rtwdev, firmware); 630 if (!mfw_hdr) { 631 rtw89_debug(rtwdev, RTW89_DBG_FW, "use legacy firmware\n"); 632 /* legacy firmware support normal type only */ 633 if (type != RTW89_FW_NORMAL) 634 return -EINVAL; 635 fw_suit->data = mfw; 636 fw_suit->size = mfw_len; 637 return 0; 638 } 639 640 ret = rtw89_mfw_validate_hdr(rtwdev, firmware, mfw_hdr); 641 if (ret) 642 return ret; 643 644 for (i = 0; i < mfw_hdr->fw_nr; i++) { 645 tmp = &mfw_hdr->info[i]; 646 if (tmp->type != type) 647 continue; 648 649 if (type == RTW89_FW_LOGFMT) { 650 mfw_info = tmp; 651 goto found; 652 } 653 654 /* Version order of WiFi firmware in firmware file are not in order, 655 * pass all firmware to find the equal or less but closest version. 656 */ 657 if (tmp->cv <= rtwdev->hal.cv && !tmp->mp) { 658 if (!mfw_info || mfw_info->cv < tmp->cv) 659 mfw_info = tmp; 660 } 661 } 662 663 if (mfw_info) 664 goto found; 665 666 if (!nowarn) 667 rtw89_err(rtwdev, "no suitable firmware found\n"); 668 return -ENOENT; 669 670 found: 671 fw_suit->data = mfw + le32_to_cpu(mfw_info->shift); 672 fw_suit->size = le32_to_cpu(mfw_info->size); 673 674 if (fw_suit->data + fw_suit->size > mfw + mfw_len) { 675 rtw89_err(rtwdev, "fw_suit %d out of address\n", type); 676 return -EFAULT; 677 } 678 679 return 0; 680 } 681 682 static u32 rtw89_mfw_get_size(struct rtw89_dev *rtwdev) 683 { 684 struct rtw89_fw_info *fw_info = &rtwdev->fw; 685 const struct firmware *firmware = fw_info->req.firmware; 686 const struct rtw89_mfw_info *mfw_info; 687 const struct rtw89_mfw_hdr *mfw_hdr; 688 u32 size; 689 int ret; 690 691 mfw_hdr = rtw89_mfw_get_hdr_ptr(rtwdev, firmware); 692 if (!mfw_hdr) { 693 rtw89_warn(rtwdev, "not mfw format\n"); 694 return 0; 695 } 696 697 ret = rtw89_mfw_validate_hdr(rtwdev, firmware, mfw_hdr); 698 if (ret) 699 return ret; 700 701 mfw_info = &mfw_hdr->info[mfw_hdr->fw_nr - 1]; 702 size = le32_to_cpu(mfw_info->shift) + le32_to_cpu(mfw_info->size); 703 704 return size; 705 } 706 707 static void rtw89_fw_update_ver_v0(struct rtw89_dev *rtwdev, 708 struct rtw89_fw_suit *fw_suit, 709 const struct rtw89_fw_hdr *hdr) 710 { 711 fw_suit->major_ver = le32_get_bits(hdr->w1, FW_HDR_W1_MAJOR_VERSION); 712 fw_suit->minor_ver = le32_get_bits(hdr->w1, FW_HDR_W1_MINOR_VERSION); 713 fw_suit->sub_ver = le32_get_bits(hdr->w1, FW_HDR_W1_SUBVERSION); 714 fw_suit->sub_idex = le32_get_bits(hdr->w1, FW_HDR_W1_SUBINDEX); 715 fw_suit->commitid = le32_get_bits(hdr->w2, FW_HDR_W2_COMMITID); 716 fw_suit->build_year = le32_get_bits(hdr->w5, FW_HDR_W5_YEAR); 717 fw_suit->build_mon = le32_get_bits(hdr->w4, FW_HDR_W4_MONTH); 718 fw_suit->build_date = le32_get_bits(hdr->w4, FW_HDR_W4_DATE); 719 fw_suit->build_hour = le32_get_bits(hdr->w4, FW_HDR_W4_HOUR); 720 fw_suit->build_min = le32_get_bits(hdr->w4, FW_HDR_W4_MIN); 721 fw_suit->cmd_ver = le32_get_bits(hdr->w7, FW_HDR_W7_CMD_VERSERION); 722 } 723 724 static void rtw89_fw_update_ver_v1(struct rtw89_dev *rtwdev, 725 struct rtw89_fw_suit *fw_suit, 726 const struct rtw89_fw_hdr_v1 *hdr) 727 { 728 fw_suit->major_ver = le32_get_bits(hdr->w1, FW_HDR_V1_W1_MAJOR_VERSION); 729 fw_suit->minor_ver = le32_get_bits(hdr->w1, FW_HDR_V1_W1_MINOR_VERSION); 730 fw_suit->sub_ver = le32_get_bits(hdr->w1, FW_HDR_V1_W1_SUBVERSION); 731 fw_suit->sub_idex = le32_get_bits(hdr->w1, FW_HDR_V1_W1_SUBINDEX); 732 fw_suit->commitid = le32_get_bits(hdr->w2, FW_HDR_V1_W2_COMMITID); 733 fw_suit->build_year = le32_get_bits(hdr->w5, FW_HDR_V1_W5_YEAR); 734 fw_suit->build_mon = le32_get_bits(hdr->w4, FW_HDR_V1_W4_MONTH); 735 fw_suit->build_date = le32_get_bits(hdr->w4, FW_HDR_V1_W4_DATE); 736 fw_suit->build_hour = le32_get_bits(hdr->w4, FW_HDR_V1_W4_HOUR); 737 fw_suit->build_min = le32_get_bits(hdr->w4, FW_HDR_V1_W4_MIN); 738 fw_suit->cmd_ver = le32_get_bits(hdr->w7, FW_HDR_V1_W3_CMD_VERSERION); 739 } 740 741 static int rtw89_fw_update_ver(struct rtw89_dev *rtwdev, 742 enum rtw89_fw_type type, 743 struct rtw89_fw_suit *fw_suit) 744 { 745 const struct rtw89_fw_hdr *v0 = (const struct rtw89_fw_hdr *)fw_suit->data; 746 const struct rtw89_fw_hdr_v1 *v1 = (const struct rtw89_fw_hdr_v1 *)fw_suit->data; 747 748 if (type == RTW89_FW_LOGFMT) 749 return 0; 750 751 fw_suit->type = type; 752 fw_suit->hdr_ver = le32_get_bits(v0->w3, FW_HDR_W3_HDR_VER); 753 754 switch (fw_suit->hdr_ver) { 755 case 0: 756 rtw89_fw_update_ver_v0(rtwdev, fw_suit, v0); 757 break; 758 case 1: 759 rtw89_fw_update_ver_v1(rtwdev, fw_suit, v1); 760 break; 761 default: 762 rtw89_err(rtwdev, "Unknown firmware header version %u\n", 763 fw_suit->hdr_ver); 764 return -ENOENT; 765 } 766 767 rtw89_info(rtwdev, 768 "Firmware version %u.%u.%u.%u (%08x), cmd version %u, type %u\n", 769 fw_suit->major_ver, fw_suit->minor_ver, fw_suit->sub_ver, 770 fw_suit->sub_idex, fw_suit->commitid, fw_suit->cmd_ver, type); 771 772 return 0; 773 } 774 775 static 776 int __rtw89_fw_recognize(struct rtw89_dev *rtwdev, enum rtw89_fw_type type, 777 bool nowarn) 778 { 779 struct rtw89_fw_suit *fw_suit = rtw89_fw_suit_get(rtwdev, type); 780 int ret; 781 782 ret = rtw89_mfw_recognize(rtwdev, type, fw_suit, nowarn); 783 if (ret) 784 return ret; 785 786 return rtw89_fw_update_ver(rtwdev, type, fw_suit); 787 } 788 789 static 790 int __rtw89_fw_recognize_from_elm(struct rtw89_dev *rtwdev, 791 const struct rtw89_fw_element_hdr *elm, 792 const union rtw89_fw_element_arg arg) 793 { 794 #if defined(__linux__) 795 enum rtw89_fw_type type = arg.fw_type; 796 #elif defined(__FreeBSD__) 797 const enum rtw89_fw_type type = arg.fw_type; 798 #endif 799 struct rtw89_hal *hal = &rtwdev->hal; 800 struct rtw89_fw_suit *fw_suit; 801 802 /* Version of BB MCU is in decreasing order in firmware file, so take 803 * first equal or less version, which is equal or less but closest version. 804 */ 805 if (hal->cv < elm->u.bbmcu.cv) 806 return 1; /* ignore this element */ 807 808 fw_suit = rtw89_fw_suit_get(rtwdev, type); 809 if (fw_suit->data) 810 return 1; /* ignore this element (a firmware is taken already) */ 811 812 fw_suit->data = elm->u.bbmcu.contents; 813 fw_suit->size = le32_to_cpu(elm->size); 814 815 return rtw89_fw_update_ver(rtwdev, type, fw_suit); 816 } 817 818 #define __DEF_FW_FEAT_COND(__cond, __op) \ 819 static bool __fw_feat_cond_ ## __cond(u32 suit_ver_code, u32 comp_ver_code) \ 820 { \ 821 return suit_ver_code __op comp_ver_code; \ 822 } 823 824 __DEF_FW_FEAT_COND(ge, >=); /* greater or equal */ 825 __DEF_FW_FEAT_COND(le, <=); /* less or equal */ 826 __DEF_FW_FEAT_COND(lt, <); /* less than */ 827 828 struct __fw_feat_cfg { 829 enum rtw89_core_chip_id chip_id; 830 enum rtw89_fw_feature feature; 831 u32 ver_code; 832 bool (*cond)(u32 suit_ver_code, u32 comp_ver_code); 833 }; 834 835 #define __CFG_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 } 842 843 static const struct __fw_feat_cfg fw_feat_tbl[] = { 844 __CFG_FW_FEAT(RTL8851B, ge, 0, 29, 37, 1, TX_WAKE), 845 __CFG_FW_FEAT(RTL8851B, ge, 0, 29, 37, 1, SCAN_OFFLOAD), 846 __CFG_FW_FEAT(RTL8851B, ge, 0, 29, 41, 0, CRASH_TRIGGER_TYPE_0), 847 __CFG_FW_FEAT(RTL8852A, le, 0, 13, 29, 0, OLD_HT_RA_FORMAT), 848 __CFG_FW_FEAT(RTL8852A, ge, 0, 13, 35, 0, SCAN_OFFLOAD), 849 __CFG_FW_FEAT(RTL8852A, ge, 0, 13, 35, 0, TX_WAKE), 850 __CFG_FW_FEAT(RTL8852A, ge, 0, 13, 36, 0, CRASH_TRIGGER_TYPE_0), 851 __CFG_FW_FEAT(RTL8852A, lt, 0, 13, 37, 0, NO_WOW_CPU_IO_RX), 852 __CFG_FW_FEAT(RTL8852A, lt, 0, 13, 38, 0, NO_PACKET_DROP), 853 __CFG_FW_FEAT(RTL8852B, ge, 0, 29, 26, 0, NO_LPS_PG), 854 __CFG_FW_FEAT(RTL8852B, ge, 0, 29, 26, 0, TX_WAKE), 855 __CFG_FW_FEAT(RTL8852B, ge, 0, 29, 29, 0, CRASH_TRIGGER_TYPE_0), 856 __CFG_FW_FEAT(RTL8852B, ge, 0, 29, 29, 0, SCAN_OFFLOAD), 857 __CFG_FW_FEAT(RTL8852B, ge, 0, 29, 29, 7, BEACON_FILTER), 858 __CFG_FW_FEAT(RTL8852B, lt, 0, 29, 30, 0, NO_WOW_CPU_IO_RX), 859 __CFG_FW_FEAT(RTL8852B, ge, 0, 29, 127, 0, LPS_DACK_BY_C2H_REG), 860 __CFG_FW_FEAT(RTL8852B, ge, 0, 29, 128, 0, CRASH_TRIGGER_TYPE_1), 861 __CFG_FW_FEAT(RTL8852B, ge, 0, 29, 128, 0, SCAN_OFFLOAD_EXTRA_OP), 862 __CFG_FW_FEAT(RTL8852BT, ge, 0, 29, 74, 0, NO_LPS_PG), 863 __CFG_FW_FEAT(RTL8852BT, ge, 0, 29, 74, 0, TX_WAKE), 864 __CFG_FW_FEAT(RTL8852BT, ge, 0, 29, 90, 0, CRASH_TRIGGER_TYPE_0), 865 __CFG_FW_FEAT(RTL8852BT, ge, 0, 29, 91, 0, SCAN_OFFLOAD), 866 __CFG_FW_FEAT(RTL8852BT, ge, 0, 29, 110, 0, BEACON_FILTER), 867 __CFG_FW_FEAT(RTL8852BT, ge, 0, 29, 127, 0, SCAN_OFFLOAD_EXTRA_OP), 868 __CFG_FW_FEAT(RTL8852BT, ge, 0, 29, 127, 0, LPS_DACK_BY_C2H_REG), 869 __CFG_FW_FEAT(RTL8852BT, ge, 0, 29, 127, 0, CRASH_TRIGGER_TYPE_1), 870 __CFG_FW_FEAT(RTL8852C, le, 0, 27, 33, 0, NO_DEEP_PS), 871 __CFG_FW_FEAT(RTL8852C, ge, 0, 0, 0, 0, RFK_NTFY_MCC_V0), 872 __CFG_FW_FEAT(RTL8852C, ge, 0, 27, 34, 0, TX_WAKE), 873 __CFG_FW_FEAT(RTL8852C, ge, 0, 27, 36, 0, SCAN_OFFLOAD), 874 __CFG_FW_FEAT(RTL8852C, ge, 0, 27, 40, 0, CRASH_TRIGGER_TYPE_0), 875 __CFG_FW_FEAT(RTL8852C, ge, 0, 27, 56, 10, BEACON_FILTER), 876 __CFG_FW_FEAT(RTL8852C, ge, 0, 27, 80, 0, WOW_REASON_V1), 877 __CFG_FW_FEAT(RTL8852C, ge, 0, 27, 128, 0, BEACON_LOSS_COUNT_V1), 878 __CFG_FW_FEAT(RTL8922A, ge, 0, 34, 30, 0, CRASH_TRIGGER_TYPE_0), 879 __CFG_FW_FEAT(RTL8922A, ge, 0, 34, 11, 0, MACID_PAUSE_SLEEP), 880 __CFG_FW_FEAT(RTL8922A, ge, 0, 34, 35, 0, SCAN_OFFLOAD), 881 __CFG_FW_FEAT(RTL8922A, lt, 0, 35, 21, 0, SCAN_OFFLOAD_BE_V0), 882 __CFG_FW_FEAT(RTL8922A, ge, 0, 35, 12, 0, BEACON_FILTER), 883 __CFG_FW_FEAT(RTL8922A, ge, 0, 35, 22, 0, WOW_REASON_V1), 884 __CFG_FW_FEAT(RTL8922A, lt, 0, 35, 28, 0, RFK_IQK_V0), 885 __CFG_FW_FEAT(RTL8922A, lt, 0, 35, 31, 0, RFK_PRE_NOTIFY_V0), 886 __CFG_FW_FEAT(RTL8922A, lt, 0, 35, 31, 0, LPS_CH_INFO), 887 __CFG_FW_FEAT(RTL8922A, lt, 0, 35, 42, 0, RFK_RXDCK_V0), 888 __CFG_FW_FEAT(RTL8922A, ge, 0, 35, 46, 0, NOTIFY_AP_INFO), 889 __CFG_FW_FEAT(RTL8922A, lt, 0, 35, 47, 0, CH_INFO_BE_V0), 890 __CFG_FW_FEAT(RTL8922A, lt, 0, 35, 49, 0, RFK_PRE_NOTIFY_V1), 891 __CFG_FW_FEAT(RTL8922A, lt, 0, 35, 51, 0, NO_PHYCAP_P1), 892 __CFG_FW_FEAT(RTL8922A, lt, 0, 35, 64, 0, NO_POWER_DIFFERENCE), 893 __CFG_FW_FEAT(RTL8922A, ge, 0, 35, 71, 0, BEACON_LOSS_COUNT_V1), 894 __CFG_FW_FEAT(RTL8922A, ge, 0, 35, 76, 0, LPS_DACK_BY_C2H_REG), 895 __CFG_FW_FEAT(RTL8922A, ge, 0, 35, 79, 0, CRASH_TRIGGER_TYPE_1), 896 }; 897 898 static void rtw89_fw_iterate_feature_cfg(struct rtw89_fw_info *fw, 899 const struct rtw89_chip_info *chip, 900 u32 ver_code) 901 { 902 int i; 903 904 for (i = 0; i < ARRAY_SIZE(fw_feat_tbl); i++) { 905 const struct __fw_feat_cfg *ent = &fw_feat_tbl[i]; 906 907 if (chip->chip_id != ent->chip_id) 908 continue; 909 910 if (ent->cond(ver_code, ent->ver_code)) 911 RTW89_SET_FW_FEATURE(ent->feature, fw); 912 } 913 } 914 915 static void rtw89_fw_recognize_features(struct rtw89_dev *rtwdev) 916 { 917 const struct rtw89_chip_info *chip = rtwdev->chip; 918 const struct rtw89_fw_suit *fw_suit; 919 u32 suit_ver_code; 920 921 fw_suit = rtw89_fw_suit_get(rtwdev, RTW89_FW_NORMAL); 922 suit_ver_code = RTW89_FW_SUIT_VER_CODE(fw_suit); 923 924 rtw89_fw_iterate_feature_cfg(&rtwdev->fw, chip, suit_ver_code); 925 } 926 927 const struct firmware * 928 rtw89_early_fw_feature_recognize(struct device *device, 929 const struct rtw89_chip_info *chip, 930 struct rtw89_fw_info *early_fw, 931 int *used_fw_format) 932 { 933 const struct firmware *firmware; 934 char fw_name[64]; 935 int fw_format; 936 u32 ver_code; 937 int ret; 938 939 for (fw_format = chip->fw_format_max; fw_format >= 0; fw_format--) { 940 rtw89_fw_get_filename(fw_name, sizeof(fw_name), 941 chip->fw_basename, fw_format); 942 943 ret = request_firmware(&firmware, fw_name, device); 944 if (!ret) { 945 dev_info(device, "loaded firmware %s\n", fw_name); 946 *used_fw_format = fw_format; 947 break; 948 } 949 } 950 951 if (ret) { 952 dev_err(device, "failed to early request firmware: %d\n", ret); 953 return NULL; 954 } 955 956 ver_code = rtw89_compat_fw_hdr_ver_code(firmware->data); 957 958 if (!ver_code) 959 goto out; 960 961 rtw89_fw_iterate_feature_cfg(early_fw, chip, ver_code); 962 963 out: 964 return firmware; 965 } 966 967 static int rtw89_fw_validate_ver_required(struct rtw89_dev *rtwdev) 968 { 969 const struct rtw89_chip_variant *variant = rtwdev->variant; 970 const struct rtw89_fw_suit *fw_suit; 971 u32 suit_ver_code; 972 973 if (!variant) 974 return 0; 975 976 fw_suit = rtw89_fw_suit_get(rtwdev, RTW89_FW_NORMAL); 977 suit_ver_code = RTW89_FW_SUIT_VER_CODE(fw_suit); 978 979 if (variant->fw_min_ver_code > suit_ver_code) { 980 rtw89_err(rtwdev, "minimum required firmware version is 0x%x\n", 981 variant->fw_min_ver_code); 982 return -ENOENT; 983 } 984 985 return 0; 986 } 987 988 int rtw89_fw_recognize(struct rtw89_dev *rtwdev) 989 { 990 const struct rtw89_chip_info *chip = rtwdev->chip; 991 int ret; 992 993 if (chip->try_ce_fw) { 994 ret = __rtw89_fw_recognize(rtwdev, RTW89_FW_NORMAL_CE, true); 995 if (!ret) 996 goto normal_done; 997 } 998 999 ret = __rtw89_fw_recognize(rtwdev, RTW89_FW_NORMAL, false); 1000 if (ret) 1001 return ret; 1002 1003 normal_done: 1004 ret = rtw89_fw_validate_ver_required(rtwdev); 1005 if (ret) 1006 return ret; 1007 1008 /* It still works if wowlan firmware isn't existing. */ 1009 __rtw89_fw_recognize(rtwdev, RTW89_FW_WOWLAN, false); 1010 1011 /* It still works if log format file isn't existing. */ 1012 __rtw89_fw_recognize(rtwdev, RTW89_FW_LOGFMT, true); 1013 1014 rtw89_fw_recognize_features(rtwdev); 1015 1016 rtw89_coex_recognize_ver(rtwdev); 1017 1018 return 0; 1019 } 1020 1021 static 1022 int rtw89_build_phy_tbl_from_elm(struct rtw89_dev *rtwdev, 1023 const struct rtw89_fw_element_hdr *elm, 1024 const union rtw89_fw_element_arg arg) 1025 { 1026 struct rtw89_fw_elm_info *elm_info = &rtwdev->fw.elm_info; 1027 struct rtw89_phy_table *tbl; 1028 struct rtw89_reg2_def *regs; 1029 enum rtw89_rf_path rf_path; 1030 u32 n_regs, i; 1031 u8 idx; 1032 1033 tbl = kzalloc(sizeof(*tbl), GFP_KERNEL); 1034 if (!tbl) 1035 return -ENOMEM; 1036 1037 switch (le32_to_cpu(elm->id)) { 1038 case RTW89_FW_ELEMENT_ID_BB_REG: 1039 elm_info->bb_tbl = tbl; 1040 break; 1041 case RTW89_FW_ELEMENT_ID_BB_GAIN: 1042 elm_info->bb_gain = tbl; 1043 break; 1044 case RTW89_FW_ELEMENT_ID_RADIO_A: 1045 case RTW89_FW_ELEMENT_ID_RADIO_B: 1046 case RTW89_FW_ELEMENT_ID_RADIO_C: 1047 case RTW89_FW_ELEMENT_ID_RADIO_D: 1048 rf_path = arg.rf_path; 1049 idx = elm->u.reg2.idx; 1050 1051 elm_info->rf_radio[idx] = tbl; 1052 tbl->rf_path = rf_path; 1053 tbl->config = rtw89_phy_config_rf_reg_v1; 1054 break; 1055 case RTW89_FW_ELEMENT_ID_RF_NCTL: 1056 elm_info->rf_nctl = tbl; 1057 break; 1058 default: 1059 kfree(tbl); 1060 return -ENOENT; 1061 } 1062 1063 n_regs = le32_to_cpu(elm->size) / sizeof(tbl->regs[0]); 1064 regs = kcalloc(n_regs, sizeof(*regs), GFP_KERNEL); 1065 if (!regs) 1066 goto out; 1067 1068 for (i = 0; i < n_regs; i++) { 1069 regs[i].addr = le32_to_cpu(elm->u.reg2.regs[i].addr); 1070 regs[i].data = le32_to_cpu(elm->u.reg2.regs[i].data); 1071 } 1072 1073 tbl->n_regs = n_regs; 1074 tbl->regs = regs; 1075 1076 return 0; 1077 1078 out: 1079 kfree(tbl); 1080 return -ENOMEM; 1081 } 1082 1083 static 1084 int rtw89_fw_recognize_txpwr_from_elm(struct rtw89_dev *rtwdev, 1085 const struct rtw89_fw_element_hdr *elm, 1086 const union rtw89_fw_element_arg arg) 1087 { 1088 const struct __rtw89_fw_txpwr_element *txpwr_elm = &elm->u.txpwr; 1089 const unsigned long offset = arg.offset; 1090 struct rtw89_efuse *efuse = &rtwdev->efuse; 1091 struct rtw89_txpwr_conf *conf; 1092 1093 if (!rtwdev->rfe_data) { 1094 rtwdev->rfe_data = kzalloc(sizeof(*rtwdev->rfe_data), GFP_KERNEL); 1095 if (!rtwdev->rfe_data) 1096 return -ENOMEM; 1097 } 1098 1099 #if defined(__linux__) 1100 conf = (void *)rtwdev->rfe_data + offset; 1101 #elif defined(__FreeBSD__) 1102 conf = (void *)((u8 *)rtwdev->rfe_data + offset); 1103 #endif 1104 1105 /* if multiple matched, take the last eventually */ 1106 if (txpwr_elm->rfe_type == efuse->rfe_type) 1107 goto setup; 1108 1109 /* without one is matched, accept default */ 1110 if (txpwr_elm->rfe_type == RTW89_TXPWR_CONF_DFLT_RFE_TYPE && 1111 (!rtw89_txpwr_conf_valid(conf) || 1112 conf->rfe_type == RTW89_TXPWR_CONF_DFLT_RFE_TYPE)) 1113 goto setup; 1114 1115 rtw89_debug(rtwdev, RTW89_DBG_FW, "skip txpwr element ID %u RFE %u\n", 1116 elm->id, txpwr_elm->rfe_type); 1117 return 0; 1118 1119 setup: 1120 rtw89_debug(rtwdev, RTW89_DBG_FW, "take txpwr element ID %u RFE %u\n", 1121 elm->id, txpwr_elm->rfe_type); 1122 1123 conf->rfe_type = txpwr_elm->rfe_type; 1124 conf->ent_sz = txpwr_elm->ent_sz; 1125 conf->num_ents = le32_to_cpu(txpwr_elm->num_ents); 1126 conf->data = txpwr_elm->content; 1127 return 0; 1128 } 1129 1130 static 1131 int rtw89_build_txpwr_trk_tbl_from_elm(struct rtw89_dev *rtwdev, 1132 const struct rtw89_fw_element_hdr *elm, 1133 const union rtw89_fw_element_arg arg) 1134 { 1135 struct rtw89_fw_elm_info *elm_info = &rtwdev->fw.elm_info; 1136 const struct rtw89_chip_info *chip = rtwdev->chip; 1137 u32 needed_bitmap = 0; 1138 u32 offset = 0; 1139 int subband; 1140 u32 bitmap; 1141 int type; 1142 1143 if (chip->support_bands & BIT(NL80211_BAND_6GHZ)) 1144 needed_bitmap |= RTW89_DEFAULT_NEEDED_FW_TXPWR_TRK_6GHZ; 1145 if (chip->support_bands & BIT(NL80211_BAND_5GHZ)) 1146 needed_bitmap |= RTW89_DEFAULT_NEEDED_FW_TXPWR_TRK_5GHZ; 1147 if (chip->support_bands & BIT(NL80211_BAND_2GHZ)) 1148 needed_bitmap |= RTW89_DEFAULT_NEEDED_FW_TXPWR_TRK_2GHZ; 1149 1150 bitmap = le32_to_cpu(elm->u.txpwr_trk.bitmap); 1151 1152 if ((bitmap & needed_bitmap) != needed_bitmap) { 1153 rtw89_warn(rtwdev, "needed txpwr trk bitmap %08x but %08x\n", 1154 needed_bitmap, bitmap); 1155 return -ENOENT; 1156 } 1157 1158 elm_info->txpwr_trk = kzalloc(sizeof(*elm_info->txpwr_trk), GFP_KERNEL); 1159 if (!elm_info->txpwr_trk) 1160 return -ENOMEM; 1161 1162 for (type = 0; bitmap; type++, bitmap >>= 1) { 1163 if (!(bitmap & BIT(0))) 1164 continue; 1165 1166 if (type >= __RTW89_FW_TXPWR_TRK_TYPE_6GHZ_START && 1167 type <= __RTW89_FW_TXPWR_TRK_TYPE_6GHZ_MAX) 1168 subband = 4; 1169 else if (type >= __RTW89_FW_TXPWR_TRK_TYPE_5GHZ_START && 1170 type <= __RTW89_FW_TXPWR_TRK_TYPE_5GHZ_MAX) 1171 subband = 3; 1172 else if (type >= __RTW89_FW_TXPWR_TRK_TYPE_2GHZ_START && 1173 type <= __RTW89_FW_TXPWR_TRK_TYPE_2GHZ_MAX) 1174 subband = 1; 1175 else 1176 break; 1177 1178 elm_info->txpwr_trk->delta[type] = &elm->u.txpwr_trk.contents[offset]; 1179 1180 offset += subband; 1181 if (offset * DELTA_SWINGIDX_SIZE > le32_to_cpu(elm->size)) 1182 goto err; 1183 } 1184 1185 return 0; 1186 1187 err: 1188 rtw89_warn(rtwdev, "unexpected txpwr trk offset %d over size %d\n", 1189 offset, le32_to_cpu(elm->size)); 1190 kfree(elm_info->txpwr_trk); 1191 elm_info->txpwr_trk = NULL; 1192 1193 return -EFAULT; 1194 } 1195 1196 static 1197 int rtw89_build_rfk_log_fmt_from_elm(struct rtw89_dev *rtwdev, 1198 const struct rtw89_fw_element_hdr *elm, 1199 const union rtw89_fw_element_arg arg) 1200 { 1201 struct rtw89_fw_elm_info *elm_info = &rtwdev->fw.elm_info; 1202 u8 rfk_id; 1203 1204 if (elm_info->rfk_log_fmt) 1205 goto allocated; 1206 1207 elm_info->rfk_log_fmt = kzalloc(sizeof(*elm_info->rfk_log_fmt), GFP_KERNEL); 1208 if (!elm_info->rfk_log_fmt) 1209 return 1; /* this is an optional element, so just ignore this */ 1210 1211 allocated: 1212 rfk_id = elm->u.rfk_log_fmt.rfk_id; 1213 if (rfk_id >= RTW89_PHY_C2H_RFK_LOG_FUNC_NUM) 1214 return 1; 1215 1216 elm_info->rfk_log_fmt->elm[rfk_id] = elm; 1217 1218 return 0; 1219 } 1220 1221 static bool rtw89_regd_entcpy(struct rtw89_regd *regd, const void *cursor, 1222 u8 cursor_size) 1223 { 1224 /* fill default values if needed for backward compatibility */ 1225 struct rtw89_fw_regd_entry entry = { 1226 .rule_2ghz = RTW89_NA, 1227 .rule_5ghz = RTW89_NA, 1228 .rule_6ghz = RTW89_NA, 1229 .fmap = cpu_to_le32(0x0), 1230 }; 1231 u8 valid_size = min_t(u8, sizeof(entry), cursor_size); 1232 unsigned int i; 1233 u32 fmap; 1234 1235 memcpy(&entry, cursor, valid_size); 1236 memset(regd, 0, sizeof(*regd)); 1237 1238 regd->alpha2[0] = entry.alpha2_0; 1239 regd->alpha2[1] = entry.alpha2_1; 1240 regd->alpha2[2] = '\0'; 1241 1242 /* also need to consider forward compatibility */ 1243 regd->txpwr_regd[RTW89_BAND_2G] = entry.rule_2ghz < RTW89_REGD_NUM ? 1244 entry.rule_2ghz : RTW89_NA; 1245 regd->txpwr_regd[RTW89_BAND_5G] = entry.rule_5ghz < RTW89_REGD_NUM ? 1246 entry.rule_5ghz : RTW89_NA; 1247 regd->txpwr_regd[RTW89_BAND_6G] = entry.rule_6ghz < RTW89_REGD_NUM ? 1248 entry.rule_6ghz : RTW89_NA; 1249 1250 BUILD_BUG_ON(sizeof(fmap) != sizeof(entry.fmap)); 1251 BUILD_BUG_ON(sizeof(fmap) * 8 < NUM_OF_RTW89_REGD_FUNC); 1252 1253 fmap = le32_to_cpu(entry.fmap); 1254 for (i = 0; i < NUM_OF_RTW89_REGD_FUNC; i++) { 1255 if (fmap & BIT(i)) 1256 set_bit(i, regd->func_bitmap); 1257 } 1258 1259 return true; 1260 } 1261 1262 #if defined(__linux__) 1263 #define rtw89_for_each_in_regd_element(regd, element) \ 1264 for (const void *cursor = (element)->content, \ 1265 *end = (element)->content + \ 1266 le32_to_cpu((element)->num_ents) * (element)->ent_sz; \ 1267 cursor < end; cursor += (element)->ent_sz) \ 1268 if (rtw89_regd_entcpy(regd, cursor, (element)->ent_sz)) 1269 #elif defined(__FreeBSD__) 1270 #define rtw89_for_each_in_regd_element(regd, element) \ 1271 for (const u8 *cursor = (element)->content, \ 1272 *end = (element)->content + \ 1273 le32_to_cpu((element)->num_ents) * (element)->ent_sz; \ 1274 cursor < end; cursor += (element)->ent_sz) \ 1275 if (rtw89_regd_entcpy(regd, cursor, (element)->ent_sz)) 1276 #endif 1277 1278 static 1279 int rtw89_recognize_regd_from_elm(struct rtw89_dev *rtwdev, 1280 const struct rtw89_fw_element_hdr *elm, 1281 const union rtw89_fw_element_arg arg) 1282 { 1283 const struct __rtw89_fw_regd_element *regd_elm = &elm->u.regd; 1284 struct rtw89_fw_elm_info *elm_info = &rtwdev->fw.elm_info; 1285 u32 num_ents = le32_to_cpu(regd_elm->num_ents); 1286 struct rtw89_regd_data *p; 1287 struct rtw89_regd regd; 1288 u32 i = 0; 1289 1290 if (num_ents > RTW89_REGD_MAX_COUNTRY_NUM) { 1291 rtw89_warn(rtwdev, 1292 "regd element ents (%d) are over max num (%d)\n", 1293 num_ents, RTW89_REGD_MAX_COUNTRY_NUM); 1294 rtw89_warn(rtwdev, 1295 "regd element ignore and take another/common\n"); 1296 return 1; 1297 } 1298 1299 if (elm_info->regd) { 1300 rtw89_debug(rtwdev, RTW89_DBG_REGD, 1301 "regd element take the latter\n"); 1302 devm_kfree(rtwdev->dev, elm_info->regd); 1303 elm_info->regd = NULL; 1304 } 1305 1306 p = devm_kzalloc(rtwdev->dev, struct_size(p, map, num_ents), GFP_KERNEL); 1307 if (!p) 1308 return -ENOMEM; 1309 1310 p->nr = num_ents; 1311 rtw89_for_each_in_regd_element(®d, regd_elm) 1312 p->map[i++] = regd; 1313 1314 if (i != num_ents) { 1315 rtw89_err(rtwdev, "regd element has %d invalid ents\n", 1316 num_ents - i); 1317 devm_kfree(rtwdev->dev, p); 1318 return -EINVAL; 1319 } 1320 1321 elm_info->regd = p; 1322 return 0; 1323 } 1324 1325 static const struct rtw89_fw_element_handler __fw_element_handlers[] = { 1326 [RTW89_FW_ELEMENT_ID_BBMCU0] = {__rtw89_fw_recognize_from_elm, 1327 { .fw_type = RTW89_FW_BBMCU0 }, NULL}, 1328 [RTW89_FW_ELEMENT_ID_BBMCU1] = {__rtw89_fw_recognize_from_elm, 1329 { .fw_type = RTW89_FW_BBMCU1 }, NULL}, 1330 [RTW89_FW_ELEMENT_ID_BB_REG] = {rtw89_build_phy_tbl_from_elm, {}, "BB"}, 1331 [RTW89_FW_ELEMENT_ID_BB_GAIN] = {rtw89_build_phy_tbl_from_elm, {}, NULL}, 1332 [RTW89_FW_ELEMENT_ID_RADIO_A] = {rtw89_build_phy_tbl_from_elm, 1333 { .rf_path = RF_PATH_A }, "radio A"}, 1334 [RTW89_FW_ELEMENT_ID_RADIO_B] = {rtw89_build_phy_tbl_from_elm, 1335 { .rf_path = RF_PATH_B }, NULL}, 1336 [RTW89_FW_ELEMENT_ID_RADIO_C] = {rtw89_build_phy_tbl_from_elm, 1337 { .rf_path = RF_PATH_C }, NULL}, 1338 [RTW89_FW_ELEMENT_ID_RADIO_D] = {rtw89_build_phy_tbl_from_elm, 1339 { .rf_path = RF_PATH_D }, NULL}, 1340 [RTW89_FW_ELEMENT_ID_RF_NCTL] = {rtw89_build_phy_tbl_from_elm, {}, "NCTL"}, 1341 [RTW89_FW_ELEMENT_ID_TXPWR_BYRATE] = { 1342 rtw89_fw_recognize_txpwr_from_elm, 1343 { .offset = offsetof(struct rtw89_rfe_data, byrate.conf) }, "TXPWR", 1344 }, 1345 [RTW89_FW_ELEMENT_ID_TXPWR_LMT_2GHZ] = { 1346 rtw89_fw_recognize_txpwr_from_elm, 1347 { .offset = offsetof(struct rtw89_rfe_data, lmt_2ghz.conf) }, NULL, 1348 }, 1349 [RTW89_FW_ELEMENT_ID_TXPWR_LMT_5GHZ] = { 1350 rtw89_fw_recognize_txpwr_from_elm, 1351 { .offset = offsetof(struct rtw89_rfe_data, lmt_5ghz.conf) }, NULL, 1352 }, 1353 [RTW89_FW_ELEMENT_ID_TXPWR_LMT_6GHZ] = { 1354 rtw89_fw_recognize_txpwr_from_elm, 1355 { .offset = offsetof(struct rtw89_rfe_data, lmt_6ghz.conf) }, NULL, 1356 }, 1357 [RTW89_FW_ELEMENT_ID_TXPWR_DA_LMT_2GHZ] = { 1358 rtw89_fw_recognize_txpwr_from_elm, 1359 { .offset = offsetof(struct rtw89_rfe_data, da_lmt_2ghz.conf) }, NULL, 1360 }, 1361 [RTW89_FW_ELEMENT_ID_TXPWR_DA_LMT_5GHZ] = { 1362 rtw89_fw_recognize_txpwr_from_elm, 1363 { .offset = offsetof(struct rtw89_rfe_data, da_lmt_5ghz.conf) }, NULL, 1364 }, 1365 [RTW89_FW_ELEMENT_ID_TXPWR_DA_LMT_6GHZ] = { 1366 rtw89_fw_recognize_txpwr_from_elm, 1367 { .offset = offsetof(struct rtw89_rfe_data, da_lmt_6ghz.conf) }, NULL, 1368 }, 1369 [RTW89_FW_ELEMENT_ID_TXPWR_LMT_RU_2GHZ] = { 1370 rtw89_fw_recognize_txpwr_from_elm, 1371 { .offset = offsetof(struct rtw89_rfe_data, lmt_ru_2ghz.conf) }, NULL, 1372 }, 1373 [RTW89_FW_ELEMENT_ID_TXPWR_LMT_RU_5GHZ] = { 1374 rtw89_fw_recognize_txpwr_from_elm, 1375 { .offset = offsetof(struct rtw89_rfe_data, lmt_ru_5ghz.conf) }, NULL, 1376 }, 1377 [RTW89_FW_ELEMENT_ID_TXPWR_LMT_RU_6GHZ] = { 1378 rtw89_fw_recognize_txpwr_from_elm, 1379 { .offset = offsetof(struct rtw89_rfe_data, lmt_ru_6ghz.conf) }, NULL, 1380 }, 1381 [RTW89_FW_ELEMENT_ID_TXPWR_DA_LMT_RU_2GHZ] = { 1382 rtw89_fw_recognize_txpwr_from_elm, 1383 { .offset = offsetof(struct rtw89_rfe_data, da_lmt_ru_2ghz.conf) }, NULL, 1384 }, 1385 [RTW89_FW_ELEMENT_ID_TXPWR_DA_LMT_RU_5GHZ] = { 1386 rtw89_fw_recognize_txpwr_from_elm, 1387 { .offset = offsetof(struct rtw89_rfe_data, da_lmt_ru_5ghz.conf) }, NULL, 1388 }, 1389 [RTW89_FW_ELEMENT_ID_TXPWR_DA_LMT_RU_6GHZ] = { 1390 rtw89_fw_recognize_txpwr_from_elm, 1391 { .offset = offsetof(struct rtw89_rfe_data, da_lmt_ru_6ghz.conf) }, NULL, 1392 }, 1393 [RTW89_FW_ELEMENT_ID_TX_SHAPE_LMT] = { 1394 rtw89_fw_recognize_txpwr_from_elm, 1395 { .offset = offsetof(struct rtw89_rfe_data, tx_shape_lmt.conf) }, NULL, 1396 }, 1397 [RTW89_FW_ELEMENT_ID_TX_SHAPE_LMT_RU] = { 1398 rtw89_fw_recognize_txpwr_from_elm, 1399 { .offset = offsetof(struct rtw89_rfe_data, tx_shape_lmt_ru.conf) }, NULL, 1400 }, 1401 [RTW89_FW_ELEMENT_ID_TXPWR_TRK] = { 1402 rtw89_build_txpwr_trk_tbl_from_elm, {}, "PWR_TRK", 1403 }, 1404 [RTW89_FW_ELEMENT_ID_RFKLOG_FMT] = { 1405 rtw89_build_rfk_log_fmt_from_elm, {}, NULL, 1406 }, 1407 [RTW89_FW_ELEMENT_ID_REGD] = { 1408 rtw89_recognize_regd_from_elm, {}, "REGD", 1409 }, 1410 }; 1411 1412 int rtw89_fw_recognize_elements(struct rtw89_dev *rtwdev) 1413 { 1414 struct rtw89_fw_info *fw_info = &rtwdev->fw; 1415 const struct firmware *firmware = fw_info->req.firmware; 1416 const struct rtw89_chip_info *chip = rtwdev->chip; 1417 u32 unrecognized_elements = chip->needed_fw_elms; 1418 const struct rtw89_fw_element_handler *handler; 1419 const struct rtw89_fw_element_hdr *hdr; 1420 u32 elm_size; 1421 u32 elem_id; 1422 u32 offset; 1423 int ret; 1424 1425 BUILD_BUG_ON(sizeof(chip->needed_fw_elms) * 8 < RTW89_FW_ELEMENT_ID_NUM); 1426 1427 offset = rtw89_mfw_get_size(rtwdev); 1428 offset = ALIGN(offset, RTW89_FW_ELEMENT_ALIGN); 1429 if (offset == 0) 1430 return -EINVAL; 1431 1432 while (offset + sizeof(*hdr) < firmware->size) { 1433 hdr = (const struct rtw89_fw_element_hdr *)(firmware->data + offset); 1434 1435 elm_size = le32_to_cpu(hdr->size); 1436 if (offset + elm_size >= firmware->size) { 1437 rtw89_warn(rtwdev, "firmware element size exceeds\n"); 1438 break; 1439 } 1440 1441 elem_id = le32_to_cpu(hdr->id); 1442 if (elem_id >= ARRAY_SIZE(__fw_element_handlers)) 1443 goto next; 1444 1445 handler = &__fw_element_handlers[elem_id]; 1446 if (!handler->fn) 1447 goto next; 1448 1449 ret = handler->fn(rtwdev, hdr, handler->arg); 1450 if (ret == 1) /* ignore this element */ 1451 goto next; 1452 if (ret) 1453 return ret; 1454 1455 if (handler->name) 1456 rtw89_info(rtwdev, "Firmware element %s version: %4ph\n", 1457 handler->name, hdr->ver); 1458 1459 unrecognized_elements &= ~BIT(elem_id); 1460 next: 1461 offset += sizeof(*hdr) + elm_size; 1462 offset = ALIGN(offset, RTW89_FW_ELEMENT_ALIGN); 1463 } 1464 1465 if (unrecognized_elements) { 1466 rtw89_err(rtwdev, "Firmware elements 0x%08x are unrecognized\n", 1467 unrecognized_elements); 1468 return -ENOENT; 1469 } 1470 1471 return 0; 1472 } 1473 1474 void rtw89_h2c_pkt_set_hdr(struct rtw89_dev *rtwdev, struct sk_buff *skb, 1475 u8 type, u8 cat, u8 class, u8 func, 1476 bool rack, bool dack, u32 len) 1477 { 1478 struct fwcmd_hdr *hdr; 1479 1480 hdr = (struct fwcmd_hdr *)skb_push(skb, 8); 1481 1482 if (!(rtwdev->fw.h2c_seq % 4)) 1483 rack = true; 1484 hdr->hdr0 = cpu_to_le32(FIELD_PREP(H2C_HDR_DEL_TYPE, type) | 1485 FIELD_PREP(H2C_HDR_CAT, cat) | 1486 FIELD_PREP(H2C_HDR_CLASS, class) | 1487 FIELD_PREP(H2C_HDR_FUNC, func) | 1488 FIELD_PREP(H2C_HDR_H2C_SEQ, rtwdev->fw.h2c_seq)); 1489 1490 hdr->hdr1 = cpu_to_le32(FIELD_PREP(H2C_HDR_TOTAL_LEN, 1491 len + H2C_HEADER_LEN) | 1492 (rack ? H2C_HDR_REC_ACK : 0) | 1493 (dack ? H2C_HDR_DONE_ACK : 0)); 1494 1495 rtwdev->fw.h2c_seq++; 1496 } 1497 1498 static void rtw89_h2c_pkt_set_hdr_fwdl(struct rtw89_dev *rtwdev, 1499 struct sk_buff *skb, 1500 u8 type, u8 cat, u8 class, u8 func, 1501 u32 len) 1502 { 1503 struct fwcmd_hdr *hdr; 1504 1505 hdr = (struct fwcmd_hdr *)skb_push(skb, 8); 1506 1507 hdr->hdr0 = cpu_to_le32(FIELD_PREP(H2C_HDR_DEL_TYPE, type) | 1508 FIELD_PREP(H2C_HDR_CAT, cat) | 1509 FIELD_PREP(H2C_HDR_CLASS, class) | 1510 FIELD_PREP(H2C_HDR_FUNC, func) | 1511 FIELD_PREP(H2C_HDR_H2C_SEQ, rtwdev->fw.h2c_seq)); 1512 1513 hdr->hdr1 = cpu_to_le32(FIELD_PREP(H2C_HDR_TOTAL_LEN, 1514 len + H2C_HEADER_LEN)); 1515 } 1516 1517 static u32 __rtw89_fw_download_tweak_hdr_v0(struct rtw89_dev *rtwdev, 1518 struct rtw89_fw_bin_info *info, 1519 struct rtw89_fw_hdr *fw_hdr) 1520 { 1521 struct rtw89_fw_hdr_section_info *section_info; 1522 struct rtw89_fw_hdr_section *section; 1523 int i; 1524 1525 le32p_replace_bits(&fw_hdr->w7, FWDL_SECTION_PER_PKT_LEN, 1526 FW_HDR_W7_PART_SIZE); 1527 1528 for (i = 0; i < info->section_num; i++) { 1529 section_info = &info->section_info[i]; 1530 1531 if (!section_info->len_override) 1532 continue; 1533 1534 section = &fw_hdr->sections[i]; 1535 le32p_replace_bits(§ion->w1, section_info->len_override, 1536 FWSECTION_HDR_W1_SEC_SIZE); 1537 } 1538 1539 return 0; 1540 } 1541 1542 static u32 __rtw89_fw_download_tweak_hdr_v1(struct rtw89_dev *rtwdev, 1543 struct rtw89_fw_bin_info *info, 1544 struct rtw89_fw_hdr_v1 *fw_hdr) 1545 { 1546 struct rtw89_fw_hdr_section_info *section_info; 1547 struct rtw89_fw_hdr_section_v1 *section; 1548 u8 dst_sec_idx = 0; 1549 u8 sec_idx; 1550 1551 le32p_replace_bits(&fw_hdr->w7, FWDL_SECTION_PER_PKT_LEN, 1552 FW_HDR_V1_W7_PART_SIZE); 1553 1554 for (sec_idx = 0; sec_idx < info->section_num; sec_idx++) { 1555 section_info = &info->section_info[sec_idx]; 1556 section = &fw_hdr->sections[sec_idx]; 1557 1558 if (section_info->ignore) 1559 continue; 1560 1561 if (dst_sec_idx != sec_idx) 1562 fw_hdr->sections[dst_sec_idx] = *section; 1563 1564 dst_sec_idx++; 1565 } 1566 1567 le32p_replace_bits(&fw_hdr->w6, dst_sec_idx, FW_HDR_V1_W6_SEC_NUM); 1568 1569 return (info->section_num - dst_sec_idx) * sizeof(*section); 1570 } 1571 1572 static int __rtw89_fw_download_hdr(struct rtw89_dev *rtwdev, 1573 const struct rtw89_fw_suit *fw_suit, 1574 struct rtw89_fw_bin_info *info) 1575 { 1576 u32 len = info->hdr_len - info->dynamic_hdr_len; 1577 struct rtw89_fw_hdr_v1 *fw_hdr_v1; 1578 const u8 *fw = fw_suit->data; 1579 struct rtw89_fw_hdr *fw_hdr; 1580 struct sk_buff *skb; 1581 u32 truncated; 1582 u32 ret = 0; 1583 1584 skb = rtw89_fw_h2c_alloc_skb_with_hdr(rtwdev, len); 1585 if (!skb) { 1586 rtw89_err(rtwdev, "failed to alloc skb for fw hdr dl\n"); 1587 return -ENOMEM; 1588 } 1589 1590 skb_put_data(skb, fw, len); 1591 1592 switch (fw_suit->hdr_ver) { 1593 case 0: 1594 fw_hdr = (struct rtw89_fw_hdr *)skb->data; 1595 truncated = __rtw89_fw_download_tweak_hdr_v0(rtwdev, info, fw_hdr); 1596 break; 1597 case 1: 1598 fw_hdr_v1 = (struct rtw89_fw_hdr_v1 *)skb->data; 1599 truncated = __rtw89_fw_download_tweak_hdr_v1(rtwdev, info, fw_hdr_v1); 1600 break; 1601 default: 1602 ret = -EOPNOTSUPP; 1603 goto fail; 1604 } 1605 1606 if (truncated) { 1607 len -= truncated; 1608 skb_trim(skb, len); 1609 } 1610 1611 rtw89_h2c_pkt_set_hdr_fwdl(rtwdev, skb, FWCMD_TYPE_H2C, 1612 H2C_CAT_MAC, H2C_CL_MAC_FWDL, 1613 H2C_FUNC_MAC_FWHDR_DL, len); 1614 1615 ret = rtw89_h2c_tx(rtwdev, skb, false); 1616 if (ret) { 1617 rtw89_err(rtwdev, "failed to send h2c\n"); 1618 goto fail; 1619 } 1620 1621 return 0; 1622 fail: 1623 dev_kfree_skb_any(skb); 1624 1625 return ret; 1626 } 1627 1628 static int rtw89_fw_download_hdr(struct rtw89_dev *rtwdev, 1629 const struct rtw89_fw_suit *fw_suit, 1630 struct rtw89_fw_bin_info *info) 1631 { 1632 const struct rtw89_mac_gen_def *mac = rtwdev->chip->mac_def; 1633 int ret; 1634 1635 ret = __rtw89_fw_download_hdr(rtwdev, fw_suit, info); 1636 if (ret) { 1637 rtw89_err(rtwdev, "[ERR]FW header download\n"); 1638 return ret; 1639 } 1640 1641 ret = mac->fwdl_check_path_ready(rtwdev, false); 1642 if (ret) { 1643 rtw89_err(rtwdev, "[ERR]FWDL path ready\n"); 1644 return ret; 1645 } 1646 1647 rtw89_write32(rtwdev, R_AX_HALT_H2C_CTRL, 0); 1648 rtw89_write32(rtwdev, R_AX_HALT_C2H_CTRL, 0); 1649 1650 return 0; 1651 } 1652 1653 static int __rtw89_fw_download_main(struct rtw89_dev *rtwdev, 1654 struct rtw89_fw_hdr_section_info *info) 1655 { 1656 struct sk_buff *skb; 1657 const u8 *section = info->addr; 1658 u32 residue_len = info->len; 1659 bool copy_key = false; 1660 u32 pkt_len; 1661 int ret; 1662 1663 if (info->ignore) 1664 return 0; 1665 1666 if (info->len_override) { 1667 if (info->len_override > info->len) 1668 rtw89_warn(rtwdev, "override length %u larger than original %u\n", 1669 info->len_override, info->len); 1670 else 1671 residue_len = info->len_override; 1672 } 1673 1674 if (info->key_addr && info->key_len) { 1675 if (residue_len > FWDL_SECTION_PER_PKT_LEN || info->len < info->key_len) 1676 rtw89_warn(rtwdev, 1677 "ignore to copy key data because of len %d, %d, %d, %d\n", 1678 info->len, FWDL_SECTION_PER_PKT_LEN, 1679 info->key_len, residue_len); 1680 else 1681 copy_key = true; 1682 } 1683 1684 while (residue_len) { 1685 if (residue_len >= FWDL_SECTION_PER_PKT_LEN) 1686 pkt_len = FWDL_SECTION_PER_PKT_LEN; 1687 else 1688 pkt_len = residue_len; 1689 1690 skb = rtw89_fw_h2c_alloc_skb_no_hdr(rtwdev, pkt_len); 1691 if (!skb) { 1692 rtw89_err(rtwdev, "failed to alloc skb for fw dl\n"); 1693 return -ENOMEM; 1694 } 1695 skb_put_data(skb, section, pkt_len); 1696 1697 if (copy_key) 1698 memcpy(skb->data + pkt_len - info->key_len, 1699 info->key_addr, info->key_len); 1700 1701 ret = rtw89_h2c_tx(rtwdev, skb, true); 1702 if (ret) { 1703 rtw89_err(rtwdev, "failed to send h2c\n"); 1704 goto fail; 1705 } 1706 1707 section += pkt_len; 1708 residue_len -= pkt_len; 1709 } 1710 1711 return 0; 1712 fail: 1713 dev_kfree_skb_any(skb); 1714 1715 return ret; 1716 } 1717 1718 static enum rtw89_fwdl_check_type 1719 rtw89_fw_get_fwdl_chk_type_from_suit(struct rtw89_dev *rtwdev, 1720 const struct rtw89_fw_suit *fw_suit) 1721 { 1722 switch (fw_suit->type) { 1723 case RTW89_FW_BBMCU0: 1724 return RTW89_FWDL_CHECK_BB0_FWDL_DONE; 1725 case RTW89_FW_BBMCU1: 1726 return RTW89_FWDL_CHECK_BB1_FWDL_DONE; 1727 default: 1728 return RTW89_FWDL_CHECK_WCPU_FWDL_DONE; 1729 } 1730 } 1731 1732 static int rtw89_fw_download_main(struct rtw89_dev *rtwdev, 1733 const struct rtw89_fw_suit *fw_suit, 1734 struct rtw89_fw_bin_info *info) 1735 { 1736 struct rtw89_fw_hdr_section_info *section_info = info->section_info; 1737 const struct rtw89_chip_info *chip = rtwdev->chip; 1738 enum rtw89_fwdl_check_type chk_type; 1739 u8 section_num = info->section_num; 1740 int ret; 1741 1742 while (section_num--) { 1743 ret = __rtw89_fw_download_main(rtwdev, section_info); 1744 if (ret) 1745 return ret; 1746 section_info++; 1747 } 1748 1749 if (chip->chip_gen == RTW89_CHIP_AX) 1750 return 0; 1751 1752 chk_type = rtw89_fw_get_fwdl_chk_type_from_suit(rtwdev, fw_suit); 1753 ret = rtw89_fw_check_rdy(rtwdev, chk_type); 1754 if (ret) { 1755 rtw89_warn(rtwdev, "failed to download firmware type %u\n", 1756 fw_suit->type); 1757 return ret; 1758 } 1759 1760 return 0; 1761 } 1762 1763 static void rtw89_fw_prog_cnt_dump(struct rtw89_dev *rtwdev) 1764 { 1765 enum rtw89_chip_gen chip_gen = rtwdev->chip->chip_gen; 1766 u32 addr = R_AX_DBG_PORT_SEL; 1767 u32 val32; 1768 u16 index; 1769 1770 if (chip_gen == RTW89_CHIP_BE) { 1771 addr = R_BE_WLCPU_PORT_PC; 1772 goto dump; 1773 } 1774 1775 rtw89_write32(rtwdev, R_AX_DBG_CTRL, 1776 FIELD_PREP(B_AX_DBG_SEL0, FW_PROG_CNTR_DBG_SEL) | 1777 FIELD_PREP(B_AX_DBG_SEL1, FW_PROG_CNTR_DBG_SEL)); 1778 rtw89_write32_mask(rtwdev, R_AX_SYS_STATUS1, B_AX_SEL_0XC0_MASK, MAC_DBG_SEL); 1779 1780 dump: 1781 for (index = 0; index < 15; index++) { 1782 val32 = rtw89_read32(rtwdev, addr); 1783 rtw89_err(rtwdev, "[ERR]fw PC = 0x%x\n", val32); 1784 #if defined(__linux__) 1785 fsleep(10); 1786 #elif defined(__FreeBSD__) 1787 /* Seems we are called from a context we cannot sleep. */ 1788 udelay(10); 1789 #endif 1790 } 1791 } 1792 1793 static void rtw89_fw_dl_fail_dump(struct rtw89_dev *rtwdev) 1794 { 1795 u32 val32; 1796 1797 val32 = rtw89_read32(rtwdev, R_AX_WCPU_FW_CTRL); 1798 rtw89_err(rtwdev, "[ERR]fwdl 0x1E0 = 0x%x\n", val32); 1799 1800 val32 = rtw89_read32(rtwdev, R_AX_BOOT_DBG); 1801 rtw89_err(rtwdev, "[ERR]fwdl 0x83F0 = 0x%x\n", val32); 1802 1803 rtw89_fw_prog_cnt_dump(rtwdev); 1804 } 1805 1806 static int rtw89_fw_download_suit(struct rtw89_dev *rtwdev, 1807 struct rtw89_fw_suit *fw_suit) 1808 { 1809 const struct rtw89_mac_gen_def *mac = rtwdev->chip->mac_def; 1810 struct rtw89_fw_bin_info info = {}; 1811 int ret; 1812 1813 ret = rtw89_fw_hdr_parser(rtwdev, fw_suit, &info); 1814 if (ret) { 1815 rtw89_err(rtwdev, "parse fw header fail\n"); 1816 return ret; 1817 } 1818 1819 rtw89_fwdl_secure_idmem_share_mode(rtwdev, info.idmem_share_mode); 1820 1821 if (rtwdev->chip->chip_id == RTL8922A && 1822 (fw_suit->type == RTW89_FW_NORMAL || fw_suit->type == RTW89_FW_WOWLAN)) 1823 rtw89_write32(rtwdev, R_BE_SECURE_BOOT_MALLOC_INFO, 0x20248000); 1824 1825 ret = mac->fwdl_check_path_ready(rtwdev, true); 1826 if (ret) { 1827 rtw89_err(rtwdev, "[ERR]H2C path ready\n"); 1828 return ret; 1829 } 1830 1831 ret = rtw89_fw_download_hdr(rtwdev, fw_suit, &info); 1832 if (ret) 1833 return ret; 1834 1835 ret = rtw89_fw_download_main(rtwdev, fw_suit, &info); 1836 if (ret) 1837 return ret; 1838 1839 return 0; 1840 } 1841 1842 static 1843 int __rtw89_fw_download(struct rtw89_dev *rtwdev, enum rtw89_fw_type type, 1844 bool include_bb) 1845 { 1846 const struct rtw89_mac_gen_def *mac = rtwdev->chip->mac_def; 1847 struct rtw89_fw_info *fw_info = &rtwdev->fw; 1848 struct rtw89_fw_suit *fw_suit = rtw89_fw_suit_get(rtwdev, type); 1849 u8 bbmcu_nr = rtwdev->chip->bbmcu_nr; 1850 int ret; 1851 int i; 1852 1853 mac->disable_cpu(rtwdev); 1854 ret = mac->fwdl_enable_wcpu(rtwdev, 0, true, include_bb); 1855 if (ret) 1856 return ret; 1857 1858 ret = rtw89_fw_download_suit(rtwdev, fw_suit); 1859 if (ret) 1860 goto fwdl_err; 1861 1862 for (i = 0; i < bbmcu_nr && include_bb; i++) { 1863 fw_suit = rtw89_fw_suit_get(rtwdev, RTW89_FW_BBMCU0 + i); 1864 1865 ret = rtw89_fw_download_suit(rtwdev, fw_suit); 1866 if (ret) 1867 goto fwdl_err; 1868 } 1869 1870 fw_info->h2c_seq = 0; 1871 fw_info->rec_seq = 0; 1872 fw_info->h2c_counter = 0; 1873 fw_info->c2h_counter = 0; 1874 rtwdev->mac.rpwm_seq_num = RPWM_SEQ_NUM_MAX; 1875 rtwdev->mac.cpwm_seq_num = CPWM_SEQ_NUM_MAX; 1876 1877 mdelay(5); 1878 1879 ret = rtw89_fw_check_rdy(rtwdev, RTW89_FWDL_CHECK_FREERTOS_DONE); 1880 if (ret) { 1881 rtw89_warn(rtwdev, "download firmware fail\n"); 1882 goto fwdl_err; 1883 } 1884 1885 return ret; 1886 1887 fwdl_err: 1888 rtw89_fw_dl_fail_dump(rtwdev); 1889 return ret; 1890 } 1891 1892 int rtw89_fw_download(struct rtw89_dev *rtwdev, enum rtw89_fw_type type, 1893 bool include_bb) 1894 { 1895 int retry; 1896 int ret; 1897 1898 for (retry = 0; retry < 5; retry++) { 1899 ret = __rtw89_fw_download(rtwdev, type, include_bb); 1900 if (!ret) 1901 return 0; 1902 } 1903 1904 return ret; 1905 } 1906 1907 int rtw89_wait_firmware_completion(struct rtw89_dev *rtwdev) 1908 { 1909 struct rtw89_fw_info *fw = &rtwdev->fw; 1910 1911 wait_for_completion(&fw->req.completion); 1912 if (!fw->req.firmware) 1913 return -EINVAL; 1914 1915 return 0; 1916 } 1917 1918 static int rtw89_load_firmware_req(struct rtw89_dev *rtwdev, 1919 struct rtw89_fw_req_info *req, 1920 const char *fw_name, bool nowarn) 1921 { 1922 int ret; 1923 1924 if (req->firmware) { 1925 rtw89_debug(rtwdev, RTW89_DBG_FW, 1926 "full firmware has been early requested\n"); 1927 complete_all(&req->completion); 1928 return 0; 1929 } 1930 1931 if (nowarn) 1932 ret = firmware_request_nowarn(&req->firmware, fw_name, rtwdev->dev); 1933 else 1934 ret = request_firmware(&req->firmware, fw_name, rtwdev->dev); 1935 1936 complete_all(&req->completion); 1937 1938 return ret; 1939 } 1940 1941 void rtw89_load_firmware_work(struct work_struct *work) 1942 { 1943 struct rtw89_dev *rtwdev = 1944 container_of(work, struct rtw89_dev, load_firmware_work); 1945 const struct rtw89_chip_info *chip = rtwdev->chip; 1946 char fw_name[64]; 1947 1948 rtw89_fw_get_filename(fw_name, sizeof(fw_name), 1949 chip->fw_basename, rtwdev->fw.fw_format); 1950 1951 rtw89_load_firmware_req(rtwdev, &rtwdev->fw.req, fw_name, false); 1952 } 1953 1954 static void rtw89_free_phy_tbl_from_elm(struct rtw89_phy_table *tbl) 1955 { 1956 if (!tbl) 1957 return; 1958 1959 kfree(tbl->regs); 1960 kfree(tbl); 1961 } 1962 1963 static void rtw89_unload_firmware_elements(struct rtw89_dev *rtwdev) 1964 { 1965 struct rtw89_fw_elm_info *elm_info = &rtwdev->fw.elm_info; 1966 int i; 1967 1968 rtw89_free_phy_tbl_from_elm(elm_info->bb_tbl); 1969 rtw89_free_phy_tbl_from_elm(elm_info->bb_gain); 1970 for (i = 0; i < ARRAY_SIZE(elm_info->rf_radio); i++) 1971 rtw89_free_phy_tbl_from_elm(elm_info->rf_radio[i]); 1972 rtw89_free_phy_tbl_from_elm(elm_info->rf_nctl); 1973 1974 kfree(elm_info->txpwr_trk); 1975 kfree(elm_info->rfk_log_fmt); 1976 } 1977 1978 void rtw89_unload_firmware(struct rtw89_dev *rtwdev) 1979 { 1980 struct rtw89_fw_info *fw = &rtwdev->fw; 1981 1982 cancel_work_sync(&rtwdev->load_firmware_work); 1983 1984 if (fw->req.firmware) { 1985 release_firmware(fw->req.firmware); 1986 1987 /* assign NULL back in case rtw89_free_ieee80211_hw() 1988 * try to release the same one again. 1989 */ 1990 fw->req.firmware = NULL; 1991 } 1992 1993 kfree(fw->log.fmts); 1994 rtw89_unload_firmware_elements(rtwdev); 1995 } 1996 1997 static u32 rtw89_fw_log_get_fmt_idx(struct rtw89_dev *rtwdev, u32 fmt_id) 1998 { 1999 struct rtw89_fw_log *fw_log = &rtwdev->fw.log; 2000 u32 i; 2001 2002 if (fmt_id > fw_log->last_fmt_id) 2003 return 0; 2004 2005 for (i = 0; i < fw_log->fmt_count; i++) { 2006 if (le32_to_cpu(fw_log->fmt_ids[i]) == fmt_id) 2007 return i; 2008 } 2009 return 0; 2010 } 2011 2012 static int rtw89_fw_log_create_fmts_dict(struct rtw89_dev *rtwdev) 2013 { 2014 struct rtw89_fw_log *log = &rtwdev->fw.log; 2015 const struct rtw89_fw_logsuit_hdr *suit_hdr; 2016 struct rtw89_fw_suit *suit = &log->suit; 2017 #if defined(__linux__) 2018 const void *fmts_ptr, *fmts_end_ptr; 2019 #elif defined(__FreeBSD__) 2020 const u8 *fmts_ptr, *fmts_end_ptr; 2021 #endif 2022 u32 fmt_count; 2023 int i; 2024 2025 suit_hdr = (const struct rtw89_fw_logsuit_hdr *)suit->data; 2026 fmt_count = le32_to_cpu(suit_hdr->count); 2027 log->fmt_ids = suit_hdr->ids; 2028 #if defined(__linux__) 2029 fmts_ptr = &suit_hdr->ids[fmt_count]; 2030 #elif defined(__FreeBSD__) 2031 fmts_ptr = (const u8 *)&suit_hdr->ids[fmt_count]; 2032 #endif 2033 fmts_end_ptr = suit->data + suit->size; 2034 log->fmts = kcalloc(fmt_count, sizeof(char *), GFP_KERNEL); 2035 if (!log->fmts) 2036 return -ENOMEM; 2037 2038 for (i = 0; i < fmt_count; i++) { 2039 fmts_ptr = memchr_inv(fmts_ptr, 0, fmts_end_ptr - fmts_ptr); 2040 if (!fmts_ptr) 2041 break; 2042 2043 (*log->fmts)[i] = fmts_ptr; 2044 log->last_fmt_id = le32_to_cpu(log->fmt_ids[i]); 2045 log->fmt_count++; 2046 fmts_ptr += strlen(fmts_ptr); 2047 } 2048 2049 return 0; 2050 } 2051 2052 int rtw89_fw_log_prepare(struct rtw89_dev *rtwdev) 2053 { 2054 struct rtw89_fw_log *log = &rtwdev->fw.log; 2055 struct rtw89_fw_suit *suit = &log->suit; 2056 2057 if (!suit || !suit->data) { 2058 rtw89_debug(rtwdev, RTW89_DBG_FW, "no log format file\n"); 2059 return -EINVAL; 2060 } 2061 if (log->fmts) 2062 return 0; 2063 2064 return rtw89_fw_log_create_fmts_dict(rtwdev); 2065 } 2066 2067 static void rtw89_fw_log_dump_data(struct rtw89_dev *rtwdev, 2068 const struct rtw89_fw_c2h_log_fmt *log_fmt, 2069 u32 fmt_idx, u8 para_int, bool raw_data) 2070 { 2071 const char *(*fmts)[] = rtwdev->fw.log.fmts; 2072 char str_buf[RTW89_C2H_FW_LOG_STR_BUF_SIZE]; 2073 u32 args[RTW89_C2H_FW_LOG_MAX_PARA_NUM] = {0}; 2074 int i; 2075 2076 if (log_fmt->argc > RTW89_C2H_FW_LOG_MAX_PARA_NUM) { 2077 rtw89_warn(rtwdev, "C2H log: Arg count is unexpected %d\n", 2078 log_fmt->argc); 2079 return; 2080 } 2081 2082 if (para_int) 2083 for (i = 0 ; i < log_fmt->argc; i++) 2084 args[i] = le32_to_cpu(log_fmt->u.argv[i]); 2085 2086 if (raw_data) { 2087 if (para_int) 2088 snprintf(str_buf, RTW89_C2H_FW_LOG_STR_BUF_SIZE, 2089 "fw_enc(%d, %d, %d) %*ph", le32_to_cpu(log_fmt->fmt_id), 2090 para_int, log_fmt->argc, (int)sizeof(args), args); 2091 else 2092 snprintf(str_buf, RTW89_C2H_FW_LOG_STR_BUF_SIZE, 2093 "fw_enc(%d, %d, %d, %s)", le32_to_cpu(log_fmt->fmt_id), 2094 para_int, log_fmt->argc, log_fmt->u.raw); 2095 } else { 2096 snprintf(str_buf, RTW89_C2H_FW_LOG_STR_BUF_SIZE, (*fmts)[fmt_idx], 2097 args[0x0], args[0x1], args[0x2], args[0x3], args[0x4], 2098 args[0x5], args[0x6], args[0x7], args[0x8], args[0x9], 2099 args[0xa], args[0xb], args[0xc], args[0xd], args[0xe], 2100 args[0xf]); 2101 } 2102 2103 rtw89_info(rtwdev, "C2H log: %s", str_buf); 2104 } 2105 2106 void rtw89_fw_log_dump(struct rtw89_dev *rtwdev, u8 *buf, u32 len) 2107 { 2108 const struct rtw89_fw_c2h_log_fmt *log_fmt; 2109 u8 para_int; 2110 u32 fmt_idx; 2111 2112 if (len < RTW89_C2H_HEADER_LEN) { 2113 rtw89_err(rtwdev, "c2h log length is wrong!\n"); 2114 return; 2115 } 2116 2117 buf += RTW89_C2H_HEADER_LEN; 2118 len -= RTW89_C2H_HEADER_LEN; 2119 log_fmt = (const struct rtw89_fw_c2h_log_fmt *)buf; 2120 2121 if (len < RTW89_C2H_FW_FORMATTED_LOG_MIN_LEN) 2122 goto plain_log; 2123 2124 if (log_fmt->signature != cpu_to_le16(RTW89_C2H_FW_LOG_SIGNATURE)) 2125 goto plain_log; 2126 2127 if (!rtwdev->fw.log.fmts) 2128 return; 2129 2130 para_int = u8_get_bits(log_fmt->feature, RTW89_C2H_FW_LOG_FEATURE_PARA_INT); 2131 fmt_idx = rtw89_fw_log_get_fmt_idx(rtwdev, le32_to_cpu(log_fmt->fmt_id)); 2132 2133 if (!para_int && log_fmt->argc != 0 && fmt_idx != 0) 2134 rtw89_info(rtwdev, "C2H log: %s%s", 2135 (*rtwdev->fw.log.fmts)[fmt_idx], log_fmt->u.raw); 2136 else if (fmt_idx != 0 && para_int) 2137 rtw89_fw_log_dump_data(rtwdev, log_fmt, fmt_idx, para_int, false); 2138 else 2139 rtw89_fw_log_dump_data(rtwdev, log_fmt, fmt_idx, para_int, true); 2140 return; 2141 2142 plain_log: 2143 rtw89_info(rtwdev, "C2H log: %.*s", len, buf); 2144 2145 } 2146 2147 #define H2C_CAM_LEN 60 2148 int rtw89_fw_h2c_cam(struct rtw89_dev *rtwdev, struct rtw89_vif_link *rtwvif_link, 2149 struct rtw89_sta_link *rtwsta_link, const u8 *scan_mac_addr) 2150 { 2151 struct sk_buff *skb; 2152 int ret; 2153 2154 skb = rtw89_fw_h2c_alloc_skb_with_hdr(rtwdev, H2C_CAM_LEN); 2155 if (!skb) { 2156 rtw89_err(rtwdev, "failed to alloc skb for fw dl\n"); 2157 return -ENOMEM; 2158 } 2159 skb_put(skb, H2C_CAM_LEN); 2160 rtw89_cam_fill_addr_cam_info(rtwdev, rtwvif_link, rtwsta_link, scan_mac_addr, 2161 skb->data); 2162 rtw89_cam_fill_bssid_cam_info(rtwdev, rtwvif_link, rtwsta_link, skb->data); 2163 2164 rtw89_h2c_pkt_set_hdr(rtwdev, skb, FWCMD_TYPE_H2C, 2165 H2C_CAT_MAC, 2166 H2C_CL_MAC_ADDR_CAM_UPDATE, 2167 H2C_FUNC_MAC_ADDR_CAM_UPD, 0, 1, 2168 H2C_CAM_LEN); 2169 2170 ret = rtw89_h2c_tx(rtwdev, skb, false); 2171 if (ret) { 2172 rtw89_err(rtwdev, "failed to send h2c\n"); 2173 goto fail; 2174 } 2175 2176 return 0; 2177 fail: 2178 dev_kfree_skb_any(skb); 2179 2180 return ret; 2181 } 2182 2183 int rtw89_fw_h2c_dctl_sec_cam_v1(struct rtw89_dev *rtwdev, 2184 struct rtw89_vif_link *rtwvif_link, 2185 struct rtw89_sta_link *rtwsta_link) 2186 { 2187 struct rtw89_h2c_dctlinfo_ud_v1 *h2c; 2188 u32 len = sizeof(*h2c); 2189 struct sk_buff *skb; 2190 int ret; 2191 2192 skb = rtw89_fw_h2c_alloc_skb_with_hdr(rtwdev, len); 2193 if (!skb) { 2194 rtw89_err(rtwdev, "failed to alloc skb for dctl sec cam\n"); 2195 return -ENOMEM; 2196 } 2197 skb_put(skb, len); 2198 h2c = (struct rtw89_h2c_dctlinfo_ud_v1 *)skb->data; 2199 2200 rtw89_cam_fill_dctl_sec_cam_info_v1(rtwdev, rtwvif_link, rtwsta_link, h2c); 2201 2202 rtw89_h2c_pkt_set_hdr(rtwdev, skb, FWCMD_TYPE_H2C, 2203 H2C_CAT_MAC, 2204 H2C_CL_MAC_FR_EXCHG, 2205 H2C_FUNC_MAC_DCTLINFO_UD_V1, 0, 0, 2206 len); 2207 2208 ret = rtw89_h2c_tx(rtwdev, skb, false); 2209 if (ret) { 2210 rtw89_err(rtwdev, "failed to send h2c\n"); 2211 goto fail; 2212 } 2213 2214 return 0; 2215 fail: 2216 dev_kfree_skb_any(skb); 2217 2218 return ret; 2219 } 2220 EXPORT_SYMBOL(rtw89_fw_h2c_dctl_sec_cam_v1); 2221 2222 int rtw89_fw_h2c_dctl_sec_cam_v2(struct rtw89_dev *rtwdev, 2223 struct rtw89_vif_link *rtwvif_link, 2224 struct rtw89_sta_link *rtwsta_link) 2225 { 2226 struct rtw89_h2c_dctlinfo_ud_v2 *h2c; 2227 u32 len = sizeof(*h2c); 2228 struct sk_buff *skb; 2229 int ret; 2230 2231 skb = rtw89_fw_h2c_alloc_skb_with_hdr(rtwdev, len); 2232 if (!skb) { 2233 rtw89_err(rtwdev, "failed to alloc skb for dctl sec cam\n"); 2234 return -ENOMEM; 2235 } 2236 skb_put(skb, len); 2237 h2c = (struct rtw89_h2c_dctlinfo_ud_v2 *)skb->data; 2238 2239 rtw89_cam_fill_dctl_sec_cam_info_v2(rtwdev, rtwvif_link, rtwsta_link, h2c); 2240 2241 rtw89_h2c_pkt_set_hdr(rtwdev, skb, FWCMD_TYPE_H2C, 2242 H2C_CAT_MAC, 2243 H2C_CL_MAC_FR_EXCHG, 2244 H2C_FUNC_MAC_DCTLINFO_UD_V2, 0, 0, 2245 len); 2246 2247 ret = rtw89_h2c_tx(rtwdev, skb, false); 2248 if (ret) { 2249 rtw89_err(rtwdev, "failed to send h2c\n"); 2250 goto fail; 2251 } 2252 2253 return 0; 2254 fail: 2255 dev_kfree_skb_any(skb); 2256 2257 return ret; 2258 } 2259 EXPORT_SYMBOL(rtw89_fw_h2c_dctl_sec_cam_v2); 2260 2261 int rtw89_fw_h2c_default_dmac_tbl_v2(struct rtw89_dev *rtwdev, 2262 struct rtw89_vif_link *rtwvif_link, 2263 struct rtw89_sta_link *rtwsta_link) 2264 { 2265 u8 mac_id = rtwsta_link ? rtwsta_link->mac_id : rtwvif_link->mac_id; 2266 struct rtw89_h2c_dctlinfo_ud_v2 *h2c; 2267 u32 len = sizeof(*h2c); 2268 struct sk_buff *skb; 2269 int ret; 2270 2271 skb = rtw89_fw_h2c_alloc_skb_with_hdr(rtwdev, len); 2272 if (!skb) { 2273 rtw89_err(rtwdev, "failed to alloc skb for dctl v2\n"); 2274 return -ENOMEM; 2275 } 2276 skb_put(skb, len); 2277 h2c = (struct rtw89_h2c_dctlinfo_ud_v2 *)skb->data; 2278 2279 h2c->c0 = le32_encode_bits(mac_id, DCTLINFO_V2_C0_MACID) | 2280 le32_encode_bits(1, DCTLINFO_V2_C0_OP); 2281 2282 h2c->m0 = cpu_to_le32(DCTLINFO_V2_W0_ALL); 2283 h2c->m1 = cpu_to_le32(DCTLINFO_V2_W1_ALL); 2284 h2c->m2 = cpu_to_le32(DCTLINFO_V2_W2_ALL); 2285 h2c->m3 = cpu_to_le32(DCTLINFO_V2_W3_ALL); 2286 h2c->m4 = cpu_to_le32(DCTLINFO_V2_W4_ALL); 2287 h2c->m5 = cpu_to_le32(DCTLINFO_V2_W5_ALL); 2288 h2c->m6 = cpu_to_le32(DCTLINFO_V2_W6_ALL); 2289 h2c->m7 = cpu_to_le32(DCTLINFO_V2_W7_ALL); 2290 h2c->m8 = cpu_to_le32(DCTLINFO_V2_W8_ALL); 2291 h2c->m9 = cpu_to_le32(DCTLINFO_V2_W9_ALL); 2292 h2c->m10 = cpu_to_le32(DCTLINFO_V2_W10_ALL); 2293 h2c->m11 = cpu_to_le32(DCTLINFO_V2_W11_ALL); 2294 h2c->m12 = cpu_to_le32(DCTLINFO_V2_W12_ALL); 2295 2296 rtw89_h2c_pkt_set_hdr(rtwdev, skb, FWCMD_TYPE_H2C, 2297 H2C_CAT_MAC, 2298 H2C_CL_MAC_FR_EXCHG, 2299 H2C_FUNC_MAC_DCTLINFO_UD_V2, 0, 0, 2300 len); 2301 2302 ret = rtw89_h2c_tx(rtwdev, skb, false); 2303 if (ret) { 2304 rtw89_err(rtwdev, "failed to send h2c\n"); 2305 goto fail; 2306 } 2307 2308 return 0; 2309 fail: 2310 dev_kfree_skb_any(skb); 2311 2312 return ret; 2313 } 2314 EXPORT_SYMBOL(rtw89_fw_h2c_default_dmac_tbl_v2); 2315 2316 int rtw89_fw_h2c_ba_cam(struct rtw89_dev *rtwdev, 2317 struct rtw89_vif_link *rtwvif_link, 2318 struct rtw89_sta_link *rtwsta_link, 2319 bool valid, struct ieee80211_ampdu_params *params) 2320 { 2321 const struct rtw89_chip_info *chip = rtwdev->chip; 2322 struct rtw89_h2c_ba_cam *h2c; 2323 u8 macid = rtwsta_link->mac_id; 2324 u32 len = sizeof(*h2c); 2325 struct sk_buff *skb; 2326 u8 entry_idx; 2327 int ret; 2328 2329 ret = valid ? 2330 rtw89_core_acquire_sta_ba_entry(rtwdev, rtwsta_link, params->tid, 2331 &entry_idx) : 2332 rtw89_core_release_sta_ba_entry(rtwdev, rtwsta_link, params->tid, 2333 &entry_idx); 2334 if (ret) { 2335 /* it still works even if we don't have static BA CAM, because 2336 * hardware can create dynamic BA CAM automatically. 2337 */ 2338 rtw89_debug(rtwdev, RTW89_DBG_TXRX, 2339 "failed to %s entry tid=%d for h2c ba cam\n", 2340 valid ? "alloc" : "free", params->tid); 2341 return 0; 2342 } 2343 2344 skb = rtw89_fw_h2c_alloc_skb_with_hdr(rtwdev, len); 2345 if (!skb) { 2346 rtw89_err(rtwdev, "failed to alloc skb for h2c ba cam\n"); 2347 return -ENOMEM; 2348 } 2349 skb_put(skb, len); 2350 h2c = (struct rtw89_h2c_ba_cam *)skb->data; 2351 2352 h2c->w0 = le32_encode_bits(macid, RTW89_H2C_BA_CAM_W0_MACID); 2353 if (chip->bacam_ver == RTW89_BACAM_V0_EXT) 2354 h2c->w1 |= le32_encode_bits(entry_idx, RTW89_H2C_BA_CAM_W1_ENTRY_IDX_V1); 2355 else 2356 h2c->w0 |= le32_encode_bits(entry_idx, RTW89_H2C_BA_CAM_W0_ENTRY_IDX); 2357 if (!valid) 2358 goto end; 2359 h2c->w0 |= le32_encode_bits(valid, RTW89_H2C_BA_CAM_W0_VALID) | 2360 le32_encode_bits(params->tid, RTW89_H2C_BA_CAM_W0_TID); 2361 if (params->buf_size > 64) 2362 h2c->w0 |= le32_encode_bits(4, RTW89_H2C_BA_CAM_W0_BMAP_SIZE); 2363 else 2364 h2c->w0 |= le32_encode_bits(0, RTW89_H2C_BA_CAM_W0_BMAP_SIZE); 2365 /* If init req is set, hw will set the ssn */ 2366 h2c->w0 |= le32_encode_bits(1, RTW89_H2C_BA_CAM_W0_INIT_REQ) | 2367 le32_encode_bits(params->ssn, RTW89_H2C_BA_CAM_W0_SSN); 2368 2369 if (chip->bacam_ver == RTW89_BACAM_V0_EXT) { 2370 h2c->w1 |= le32_encode_bits(1, RTW89_H2C_BA_CAM_W1_STD_EN) | 2371 le32_encode_bits(rtwvif_link->mac_idx, 2372 RTW89_H2C_BA_CAM_W1_BAND); 2373 } 2374 2375 end: 2376 rtw89_h2c_pkt_set_hdr(rtwdev, skb, FWCMD_TYPE_H2C, 2377 H2C_CAT_MAC, 2378 H2C_CL_BA_CAM, 2379 H2C_FUNC_MAC_BA_CAM, 0, 1, 2380 len); 2381 2382 ret = rtw89_h2c_tx(rtwdev, skb, false); 2383 if (ret) { 2384 rtw89_err(rtwdev, "failed to send h2c\n"); 2385 goto fail; 2386 } 2387 2388 return 0; 2389 fail: 2390 dev_kfree_skb_any(skb); 2391 2392 return ret; 2393 } 2394 EXPORT_SYMBOL(rtw89_fw_h2c_ba_cam); 2395 2396 static int rtw89_fw_h2c_init_ba_cam_v0_ext(struct rtw89_dev *rtwdev, 2397 u8 entry_idx, u8 uid) 2398 { 2399 struct rtw89_h2c_ba_cam *h2c; 2400 u32 len = sizeof(*h2c); 2401 struct sk_buff *skb; 2402 int ret; 2403 2404 skb = rtw89_fw_h2c_alloc_skb_with_hdr(rtwdev, len); 2405 if (!skb) { 2406 rtw89_err(rtwdev, "failed to alloc skb for dynamic h2c ba cam\n"); 2407 return -ENOMEM; 2408 } 2409 skb_put(skb, len); 2410 h2c = (struct rtw89_h2c_ba_cam *)skb->data; 2411 2412 h2c->w0 = le32_encode_bits(1, RTW89_H2C_BA_CAM_W0_VALID); 2413 h2c->w1 = le32_encode_bits(entry_idx, RTW89_H2C_BA_CAM_W1_ENTRY_IDX_V1) | 2414 le32_encode_bits(uid, RTW89_H2C_BA_CAM_W1_UID) | 2415 le32_encode_bits(0, RTW89_H2C_BA_CAM_W1_BAND) | 2416 le32_encode_bits(0, RTW89_H2C_BA_CAM_W1_STD_EN); 2417 2418 rtw89_h2c_pkt_set_hdr(rtwdev, skb, FWCMD_TYPE_H2C, 2419 H2C_CAT_MAC, 2420 H2C_CL_BA_CAM, 2421 H2C_FUNC_MAC_BA_CAM, 0, 1, 2422 len); 2423 2424 ret = rtw89_h2c_tx(rtwdev, skb, false); 2425 if (ret) { 2426 rtw89_err(rtwdev, "failed to send h2c\n"); 2427 goto fail; 2428 } 2429 2430 return 0; 2431 fail: 2432 dev_kfree_skb_any(skb); 2433 2434 return ret; 2435 } 2436 2437 void rtw89_fw_h2c_init_dynamic_ba_cam_v0_ext(struct rtw89_dev *rtwdev) 2438 { 2439 const struct rtw89_chip_info *chip = rtwdev->chip; 2440 u8 entry_idx = chip->bacam_num; 2441 u8 uid = 0; 2442 int i; 2443 2444 for (i = 0; i < chip->bacam_dynamic_num; i++) { 2445 rtw89_fw_h2c_init_ba_cam_v0_ext(rtwdev, entry_idx, uid); 2446 entry_idx++; 2447 uid++; 2448 } 2449 } 2450 2451 int rtw89_fw_h2c_ba_cam_v1(struct rtw89_dev *rtwdev, 2452 struct rtw89_vif_link *rtwvif_link, 2453 struct rtw89_sta_link *rtwsta_link, 2454 bool valid, struct ieee80211_ampdu_params *params) 2455 { 2456 const struct rtw89_chip_info *chip = rtwdev->chip; 2457 struct rtw89_h2c_ba_cam_v1 *h2c; 2458 u8 macid = rtwsta_link->mac_id; 2459 u32 len = sizeof(*h2c); 2460 struct sk_buff *skb; 2461 u8 entry_idx; 2462 u8 bmap_size; 2463 int ret; 2464 2465 ret = valid ? 2466 rtw89_core_acquire_sta_ba_entry(rtwdev, rtwsta_link, params->tid, 2467 &entry_idx) : 2468 rtw89_core_release_sta_ba_entry(rtwdev, rtwsta_link, params->tid, 2469 &entry_idx); 2470 if (ret) { 2471 /* it still works even if we don't have static BA CAM, because 2472 * hardware can create dynamic BA CAM automatically. 2473 */ 2474 rtw89_debug(rtwdev, RTW89_DBG_TXRX, 2475 "failed to %s entry tid=%d for h2c ba cam\n", 2476 valid ? "alloc" : "free", params->tid); 2477 return 0; 2478 } 2479 2480 skb = rtw89_fw_h2c_alloc_skb_with_hdr(rtwdev, len); 2481 if (!skb) { 2482 rtw89_err(rtwdev, "failed to alloc skb for h2c ba cam\n"); 2483 return -ENOMEM; 2484 } 2485 skb_put(skb, len); 2486 h2c = (struct rtw89_h2c_ba_cam_v1 *)skb->data; 2487 2488 if (params->buf_size > 512) 2489 bmap_size = 10; 2490 else if (params->buf_size > 256) 2491 bmap_size = 8; 2492 else if (params->buf_size > 64) 2493 bmap_size = 4; 2494 else 2495 bmap_size = 0; 2496 2497 h2c->w0 = le32_encode_bits(valid, RTW89_H2C_BA_CAM_V1_W0_VALID) | 2498 le32_encode_bits(1, RTW89_H2C_BA_CAM_V1_W0_INIT_REQ) | 2499 le32_encode_bits(macid, RTW89_H2C_BA_CAM_V1_W0_MACID_MASK) | 2500 le32_encode_bits(params->tid, RTW89_H2C_BA_CAM_V1_W0_TID_MASK) | 2501 le32_encode_bits(bmap_size, RTW89_H2C_BA_CAM_V1_W0_BMAP_SIZE_MASK) | 2502 le32_encode_bits(params->ssn, RTW89_H2C_BA_CAM_V1_W0_SSN_MASK); 2503 2504 entry_idx += chip->bacam_dynamic_num; /* std entry right after dynamic ones */ 2505 h2c->w1 = le32_encode_bits(entry_idx, RTW89_H2C_BA_CAM_V1_W1_ENTRY_IDX_MASK) | 2506 le32_encode_bits(1, RTW89_H2C_BA_CAM_V1_W1_STD_ENTRY_EN) | 2507 le32_encode_bits(!!rtwvif_link->mac_idx, 2508 RTW89_H2C_BA_CAM_V1_W1_BAND_SEL); 2509 2510 rtw89_h2c_pkt_set_hdr(rtwdev, skb, FWCMD_TYPE_H2C, 2511 H2C_CAT_MAC, 2512 H2C_CL_BA_CAM, 2513 H2C_FUNC_MAC_BA_CAM_V1, 0, 1, 2514 len); 2515 2516 ret = rtw89_h2c_tx(rtwdev, skb, false); 2517 if (ret) { 2518 rtw89_err(rtwdev, "failed to send h2c\n"); 2519 goto fail; 2520 } 2521 2522 return 0; 2523 fail: 2524 dev_kfree_skb_any(skb); 2525 2526 return ret; 2527 } 2528 EXPORT_SYMBOL(rtw89_fw_h2c_ba_cam_v1); 2529 2530 int rtw89_fw_h2c_init_ba_cam_users(struct rtw89_dev *rtwdev, u8 users, 2531 u8 offset, u8 mac_idx) 2532 { 2533 struct rtw89_h2c_ba_cam_init *h2c; 2534 u32 len = sizeof(*h2c); 2535 struct sk_buff *skb; 2536 int ret; 2537 2538 skb = rtw89_fw_h2c_alloc_skb_with_hdr(rtwdev, len); 2539 if (!skb) { 2540 rtw89_err(rtwdev, "failed to alloc skb for h2c ba cam init\n"); 2541 return -ENOMEM; 2542 } 2543 skb_put(skb, len); 2544 h2c = (struct rtw89_h2c_ba_cam_init *)skb->data; 2545 2546 h2c->w0 = le32_encode_bits(users, RTW89_H2C_BA_CAM_INIT_USERS_MASK) | 2547 le32_encode_bits(offset, RTW89_H2C_BA_CAM_INIT_OFFSET_MASK) | 2548 le32_encode_bits(mac_idx, RTW89_H2C_BA_CAM_INIT_BAND_SEL); 2549 2550 rtw89_h2c_pkt_set_hdr(rtwdev, skb, FWCMD_TYPE_H2C, 2551 H2C_CAT_MAC, 2552 H2C_CL_BA_CAM, 2553 H2C_FUNC_MAC_BA_CAM_INIT, 0, 1, 2554 len); 2555 2556 ret = rtw89_h2c_tx(rtwdev, skb, false); 2557 if (ret) { 2558 rtw89_err(rtwdev, "failed to send h2c\n"); 2559 goto fail; 2560 } 2561 2562 return 0; 2563 fail: 2564 dev_kfree_skb_any(skb); 2565 2566 return ret; 2567 } 2568 2569 #define H2C_LOG_CFG_LEN 12 2570 int rtw89_fw_h2c_fw_log(struct rtw89_dev *rtwdev, bool enable) 2571 { 2572 struct sk_buff *skb; 2573 u32 comp = 0; 2574 int ret; 2575 2576 if (enable) 2577 comp = BIT(RTW89_FW_LOG_COMP_INIT) | BIT(RTW89_FW_LOG_COMP_TASK) | 2578 BIT(RTW89_FW_LOG_COMP_PS) | BIT(RTW89_FW_LOG_COMP_ERROR) | 2579 BIT(RTW89_FW_LOG_COMP_MLO) | BIT(RTW89_FW_LOG_COMP_SCAN); 2580 2581 skb = rtw89_fw_h2c_alloc_skb_with_hdr(rtwdev, H2C_LOG_CFG_LEN); 2582 if (!skb) { 2583 rtw89_err(rtwdev, "failed to alloc skb for fw log cfg\n"); 2584 return -ENOMEM; 2585 } 2586 2587 skb_put(skb, H2C_LOG_CFG_LEN); 2588 SET_LOG_CFG_LEVEL(skb->data, RTW89_FW_LOG_LEVEL_LOUD); 2589 SET_LOG_CFG_PATH(skb->data, BIT(RTW89_FW_LOG_LEVEL_C2H)); 2590 SET_LOG_CFG_COMP(skb->data, comp); 2591 SET_LOG_CFG_COMP_EXT(skb->data, 0); 2592 2593 rtw89_h2c_pkt_set_hdr(rtwdev, skb, FWCMD_TYPE_H2C, 2594 H2C_CAT_MAC, 2595 H2C_CL_FW_INFO, 2596 H2C_FUNC_LOG_CFG, 0, 0, 2597 H2C_LOG_CFG_LEN); 2598 2599 ret = rtw89_h2c_tx(rtwdev, skb, false); 2600 if (ret) { 2601 rtw89_err(rtwdev, "failed to send h2c\n"); 2602 goto fail; 2603 } 2604 2605 return 0; 2606 fail: 2607 dev_kfree_skb_any(skb); 2608 2609 return ret; 2610 } 2611 2612 static struct sk_buff *rtw89_eapol_get(struct rtw89_dev *rtwdev, 2613 struct rtw89_vif_link *rtwvif_link) 2614 { 2615 static const u8 gtkbody[] = {0xAA, 0xAA, 0x03, 0x00, 0x00, 0x00, 0x88, 2616 0x8E, 0x01, 0x03, 0x00, 0x5F, 0x02, 0x03}; 2617 u8 sec_hdr_len = rtw89_wow_get_sec_hdr_len(rtwdev); 2618 struct rtw89_wow_param *rtw_wow = &rtwdev->wow; 2619 struct rtw89_eapol_2_of_2 *eapol_pkt; 2620 struct ieee80211_bss_conf *bss_conf; 2621 struct ieee80211_hdr_3addr *hdr; 2622 struct sk_buff *skb; 2623 u8 key_des_ver; 2624 2625 if (rtw_wow->ptk_alg == 3) 2626 key_des_ver = 1; 2627 else if (rtw_wow->akm == 1 || rtw_wow->akm == 2) 2628 key_des_ver = 2; 2629 else if (rtw_wow->akm > 2 && rtw_wow->akm < 7) 2630 key_des_ver = 3; 2631 else 2632 key_des_ver = 0; 2633 2634 skb = dev_alloc_skb(sizeof(*hdr) + sec_hdr_len + sizeof(*eapol_pkt)); 2635 if (!skb) 2636 return NULL; 2637 2638 hdr = skb_put_zero(skb, sizeof(*hdr)); 2639 hdr->frame_control = cpu_to_le16(IEEE80211_FTYPE_DATA | 2640 IEEE80211_FCTL_TODS | 2641 IEEE80211_FCTL_PROTECTED); 2642 2643 rcu_read_lock(); 2644 2645 bss_conf = rtw89_vif_rcu_dereference_link(rtwvif_link, true); 2646 2647 ether_addr_copy(hdr->addr1, bss_conf->bssid); 2648 ether_addr_copy(hdr->addr2, bss_conf->addr); 2649 ether_addr_copy(hdr->addr3, bss_conf->bssid); 2650 2651 rcu_read_unlock(); 2652 2653 skb_put_zero(skb, sec_hdr_len); 2654 2655 eapol_pkt = skb_put_zero(skb, sizeof(*eapol_pkt)); 2656 memcpy(eapol_pkt->gtkbody, gtkbody, sizeof(gtkbody)); 2657 eapol_pkt->key_des_ver = key_des_ver; 2658 2659 return skb; 2660 } 2661 2662 static struct sk_buff *rtw89_sa_query_get(struct rtw89_dev *rtwdev, 2663 struct rtw89_vif_link *rtwvif_link) 2664 { 2665 u8 sec_hdr_len = rtw89_wow_get_sec_hdr_len(rtwdev); 2666 struct ieee80211_bss_conf *bss_conf; 2667 struct ieee80211_hdr_3addr *hdr; 2668 struct rtw89_sa_query *sa_query; 2669 struct sk_buff *skb; 2670 2671 skb = dev_alloc_skb(sizeof(*hdr) + sec_hdr_len + sizeof(*sa_query)); 2672 if (!skb) 2673 return NULL; 2674 2675 hdr = skb_put_zero(skb, sizeof(*hdr)); 2676 hdr->frame_control = cpu_to_le16(IEEE80211_FTYPE_MGMT | 2677 IEEE80211_STYPE_ACTION | 2678 IEEE80211_FCTL_PROTECTED); 2679 2680 rcu_read_lock(); 2681 2682 bss_conf = rtw89_vif_rcu_dereference_link(rtwvif_link, true); 2683 2684 ether_addr_copy(hdr->addr1, bss_conf->bssid); 2685 ether_addr_copy(hdr->addr2, bss_conf->addr); 2686 ether_addr_copy(hdr->addr3, bss_conf->bssid); 2687 2688 rcu_read_unlock(); 2689 2690 skb_put_zero(skb, sec_hdr_len); 2691 2692 sa_query = skb_put_zero(skb, sizeof(*sa_query)); 2693 sa_query->category = WLAN_CATEGORY_SA_QUERY; 2694 sa_query->action = WLAN_ACTION_SA_QUERY_RESPONSE; 2695 2696 return skb; 2697 } 2698 2699 static struct sk_buff *rtw89_arp_response_get(struct rtw89_dev *rtwdev, 2700 struct rtw89_vif_link *rtwvif_link) 2701 { 2702 struct rtw89_vif *rtwvif = rtwvif_link->rtwvif; 2703 u8 sec_hdr_len = rtw89_wow_get_sec_hdr_len(rtwdev); 2704 struct rtw89_wow_param *rtw_wow = &rtwdev->wow; 2705 struct ieee80211_hdr_3addr *hdr; 2706 struct rtw89_arp_rsp *arp_skb; 2707 struct arphdr *arp_hdr; 2708 struct sk_buff *skb; 2709 __le16 fc; 2710 2711 skb = dev_alloc_skb(sizeof(*hdr) + sec_hdr_len + sizeof(*arp_skb)); 2712 if (!skb) 2713 return NULL; 2714 2715 hdr = skb_put_zero(skb, sizeof(*hdr)); 2716 2717 if (rtw_wow->ptk_alg) 2718 fc = cpu_to_le16(IEEE80211_FTYPE_DATA | IEEE80211_FCTL_TODS | 2719 IEEE80211_FCTL_PROTECTED); 2720 else 2721 fc = cpu_to_le16(IEEE80211_FTYPE_DATA | IEEE80211_FCTL_TODS); 2722 2723 hdr->frame_control = fc; 2724 ether_addr_copy(hdr->addr1, rtwvif_link->bssid); 2725 ether_addr_copy(hdr->addr2, rtwvif_link->mac_addr); 2726 ether_addr_copy(hdr->addr3, rtwvif_link->bssid); 2727 2728 skb_put_zero(skb, sec_hdr_len); 2729 2730 arp_skb = skb_put_zero(skb, sizeof(*arp_skb)); 2731 memcpy(arp_skb->llc_hdr, rfc1042_header, sizeof(rfc1042_header)); 2732 arp_skb->llc_type = htons(ETH_P_ARP); 2733 2734 arp_hdr = &arp_skb->arp_hdr; 2735 arp_hdr->ar_hrd = htons(ARPHRD_ETHER); 2736 arp_hdr->ar_pro = htons(ETH_P_IP); 2737 arp_hdr->ar_hln = ETH_ALEN; 2738 arp_hdr->ar_pln = 4; 2739 arp_hdr->ar_op = htons(ARPOP_REPLY); 2740 2741 ether_addr_copy(arp_skb->sender_hw, rtwvif_link->mac_addr); 2742 arp_skb->sender_ip = rtwvif->ip_addr; 2743 2744 return skb; 2745 } 2746 2747 static int rtw89_fw_h2c_add_general_pkt(struct rtw89_dev *rtwdev, 2748 struct rtw89_vif_link *rtwvif_link, 2749 enum rtw89_fw_pkt_ofld_type type, 2750 u8 *id) 2751 { 2752 struct ieee80211_vif *vif = rtwvif_link_to_vif(rtwvif_link); 2753 int link_id = ieee80211_vif_is_mld(vif) ? rtwvif_link->link_id : -1; 2754 struct rtw89_pktofld_info *info; 2755 struct sk_buff *skb; 2756 int ret; 2757 2758 info = kzalloc(sizeof(*info), GFP_KERNEL); 2759 if (!info) 2760 return -ENOMEM; 2761 2762 switch (type) { 2763 case RTW89_PKT_OFLD_TYPE_PS_POLL: 2764 skb = ieee80211_pspoll_get(rtwdev->hw, vif); 2765 break; 2766 case RTW89_PKT_OFLD_TYPE_PROBE_RSP: 2767 skb = ieee80211_proberesp_get(rtwdev->hw, vif); 2768 break; 2769 case RTW89_PKT_OFLD_TYPE_NULL_DATA: 2770 skb = ieee80211_nullfunc_get(rtwdev->hw, vif, link_id, false); 2771 break; 2772 case RTW89_PKT_OFLD_TYPE_QOS_NULL: 2773 skb = ieee80211_nullfunc_get(rtwdev->hw, vif, link_id, true); 2774 break; 2775 case RTW89_PKT_OFLD_TYPE_EAPOL_KEY: 2776 skb = rtw89_eapol_get(rtwdev, rtwvif_link); 2777 break; 2778 case RTW89_PKT_OFLD_TYPE_SA_QUERY: 2779 skb = rtw89_sa_query_get(rtwdev, rtwvif_link); 2780 break; 2781 case RTW89_PKT_OFLD_TYPE_ARP_RSP: 2782 skb = rtw89_arp_response_get(rtwdev, rtwvif_link); 2783 break; 2784 default: 2785 goto err; 2786 } 2787 2788 if (!skb) 2789 goto err; 2790 2791 ret = rtw89_fw_h2c_add_pkt_offload(rtwdev, &info->id, skb); 2792 kfree_skb(skb); 2793 2794 if (ret) 2795 goto err; 2796 2797 list_add_tail(&info->list, &rtwvif_link->general_pkt_list); 2798 *id = info->id; 2799 return 0; 2800 2801 err: 2802 kfree(info); 2803 return -ENOMEM; 2804 } 2805 2806 void rtw89_fw_release_general_pkt_list_vif(struct rtw89_dev *rtwdev, 2807 struct rtw89_vif_link *rtwvif_link, 2808 bool notify_fw) 2809 { 2810 struct list_head *pkt_list = &rtwvif_link->general_pkt_list; 2811 struct rtw89_pktofld_info *info, *tmp; 2812 2813 list_for_each_entry_safe(info, tmp, pkt_list, list) { 2814 if (notify_fw) 2815 rtw89_fw_h2c_del_pkt_offload(rtwdev, info->id); 2816 else 2817 rtw89_core_release_bit_map(rtwdev->pkt_offload, info->id); 2818 list_del(&info->list); 2819 kfree(info); 2820 } 2821 } 2822 2823 void rtw89_fw_release_general_pkt_list(struct rtw89_dev *rtwdev, bool notify_fw) 2824 { 2825 struct rtw89_vif_link *rtwvif_link; 2826 struct rtw89_vif *rtwvif; 2827 unsigned int link_id; 2828 2829 rtw89_for_each_rtwvif(rtwdev, rtwvif) 2830 rtw89_vif_for_each_link(rtwvif, rtwvif_link, link_id) 2831 rtw89_fw_release_general_pkt_list_vif(rtwdev, rtwvif_link, 2832 notify_fw); 2833 } 2834 2835 #define H2C_GENERAL_PKT_LEN 6 2836 #define H2C_GENERAL_PKT_ID_UND 0xff 2837 int rtw89_fw_h2c_general_pkt(struct rtw89_dev *rtwdev, 2838 struct rtw89_vif_link *rtwvif_link, u8 macid) 2839 { 2840 u8 pkt_id_ps_poll = H2C_GENERAL_PKT_ID_UND; 2841 u8 pkt_id_null = H2C_GENERAL_PKT_ID_UND; 2842 u8 pkt_id_qos_null = H2C_GENERAL_PKT_ID_UND; 2843 struct sk_buff *skb; 2844 int ret; 2845 2846 rtw89_fw_h2c_add_general_pkt(rtwdev, rtwvif_link, 2847 RTW89_PKT_OFLD_TYPE_PS_POLL, &pkt_id_ps_poll); 2848 rtw89_fw_h2c_add_general_pkt(rtwdev, rtwvif_link, 2849 RTW89_PKT_OFLD_TYPE_NULL_DATA, &pkt_id_null); 2850 rtw89_fw_h2c_add_general_pkt(rtwdev, rtwvif_link, 2851 RTW89_PKT_OFLD_TYPE_QOS_NULL, &pkt_id_qos_null); 2852 2853 skb = rtw89_fw_h2c_alloc_skb_with_hdr(rtwdev, H2C_GENERAL_PKT_LEN); 2854 if (!skb) { 2855 rtw89_err(rtwdev, "failed to alloc skb for fw dl\n"); 2856 return -ENOMEM; 2857 } 2858 skb_put(skb, H2C_GENERAL_PKT_LEN); 2859 SET_GENERAL_PKT_MACID(skb->data, macid); 2860 SET_GENERAL_PKT_PROBRSP_ID(skb->data, H2C_GENERAL_PKT_ID_UND); 2861 SET_GENERAL_PKT_PSPOLL_ID(skb->data, pkt_id_ps_poll); 2862 SET_GENERAL_PKT_NULL_ID(skb->data, pkt_id_null); 2863 SET_GENERAL_PKT_QOS_NULL_ID(skb->data, pkt_id_qos_null); 2864 SET_GENERAL_PKT_CTS2SELF_ID(skb->data, H2C_GENERAL_PKT_ID_UND); 2865 2866 rtw89_h2c_pkt_set_hdr(rtwdev, skb, FWCMD_TYPE_H2C, 2867 H2C_CAT_MAC, 2868 H2C_CL_FW_INFO, 2869 H2C_FUNC_MAC_GENERAL_PKT, 0, 1, 2870 H2C_GENERAL_PKT_LEN); 2871 2872 ret = rtw89_h2c_tx(rtwdev, skb, false); 2873 if (ret) { 2874 rtw89_err(rtwdev, "failed to send h2c\n"); 2875 goto fail; 2876 } 2877 2878 return 0; 2879 fail: 2880 dev_kfree_skb_any(skb); 2881 2882 return ret; 2883 } 2884 2885 #define H2C_LPS_PARM_LEN 8 2886 int rtw89_fw_h2c_lps_parm(struct rtw89_dev *rtwdev, 2887 struct rtw89_lps_parm *lps_param) 2888 { 2889 struct sk_buff *skb; 2890 bool done_ack; 2891 int ret; 2892 2893 if (RTW89_CHK_FW_FEATURE(LPS_DACK_BY_C2H_REG, &rtwdev->fw)) 2894 done_ack = false; 2895 else 2896 done_ack = !lps_param->psmode; 2897 2898 skb = rtw89_fw_h2c_alloc_skb_with_hdr(rtwdev, H2C_LPS_PARM_LEN); 2899 if (!skb) { 2900 rtw89_err(rtwdev, "failed to alloc skb for fw dl\n"); 2901 return -ENOMEM; 2902 } 2903 skb_put(skb, H2C_LPS_PARM_LEN); 2904 2905 SET_LPS_PARM_MACID(skb->data, lps_param->macid); 2906 SET_LPS_PARM_PSMODE(skb->data, lps_param->psmode); 2907 SET_LPS_PARM_LASTRPWM(skb->data, lps_param->lastrpwm); 2908 SET_LPS_PARM_RLBM(skb->data, 1); 2909 SET_LPS_PARM_SMARTPS(skb->data, 1); 2910 SET_LPS_PARM_AWAKEINTERVAL(skb->data, 1); 2911 SET_LPS_PARM_VOUAPSD(skb->data, 0); 2912 SET_LPS_PARM_VIUAPSD(skb->data, 0); 2913 SET_LPS_PARM_BEUAPSD(skb->data, 0); 2914 SET_LPS_PARM_BKUAPSD(skb->data, 0); 2915 2916 rtw89_h2c_pkt_set_hdr(rtwdev, skb, FWCMD_TYPE_H2C, 2917 H2C_CAT_MAC, 2918 H2C_CL_MAC_PS, 2919 H2C_FUNC_MAC_LPS_PARM, 0, done_ack, 2920 H2C_LPS_PARM_LEN); 2921 2922 ret = rtw89_h2c_tx(rtwdev, skb, false); 2923 if (ret) { 2924 rtw89_err(rtwdev, "failed to send h2c\n"); 2925 goto fail; 2926 } 2927 2928 return 0; 2929 fail: 2930 dev_kfree_skb_any(skb); 2931 2932 return ret; 2933 } 2934 2935 int rtw89_fw_h2c_lps_ch_info(struct rtw89_dev *rtwdev, struct rtw89_vif *rtwvif) 2936 { 2937 const struct rtw89_chip_info *chip = rtwdev->chip; 2938 const struct rtw89_chan *chan; 2939 struct rtw89_vif_link *rtwvif_link; 2940 struct rtw89_h2c_lps_ch_info *h2c; 2941 u32 len = sizeof(*h2c); 2942 unsigned int link_id; 2943 struct sk_buff *skb; 2944 bool no_chan = true; 2945 u8 phy_idx; 2946 u32 done; 2947 int ret; 2948 2949 if (chip->chip_gen != RTW89_CHIP_BE) 2950 return 0; 2951 2952 skb = rtw89_fw_h2c_alloc_skb_with_hdr(rtwdev, len); 2953 if (!skb) { 2954 rtw89_err(rtwdev, "failed to alloc skb for h2c lps_ch_info\n"); 2955 return -ENOMEM; 2956 } 2957 skb_put(skb, len); 2958 h2c = (struct rtw89_h2c_lps_ch_info *)skb->data; 2959 2960 rtw89_vif_for_each_link(rtwvif, rtwvif_link, link_id) { 2961 phy_idx = rtwvif_link->phy_idx; 2962 if (phy_idx >= ARRAY_SIZE(h2c->info)) 2963 continue; 2964 2965 chan = rtw89_chan_get(rtwdev, rtwvif_link->chanctx_idx); 2966 no_chan = false; 2967 2968 h2c->info[phy_idx].central_ch = chan->channel; 2969 h2c->info[phy_idx].pri_ch = chan->primary_channel; 2970 h2c->info[phy_idx].band = chan->band_type; 2971 h2c->info[phy_idx].bw = chan->band_width; 2972 } 2973 2974 if (no_chan) { 2975 rtw89_err(rtwdev, "no chan for h2c lps_ch_info\n"); 2976 ret = -ENOENT; 2977 goto fail; 2978 } 2979 2980 h2c->mlo_dbcc_mode_lps = cpu_to_le32(rtwdev->mlo_dbcc_mode); 2981 2982 rtw89_h2c_pkt_set_hdr(rtwdev, skb, FWCMD_TYPE_H2C, 2983 H2C_CAT_OUTSRC, H2C_CL_OUTSRC_DM, 2984 H2C_FUNC_FW_LPS_CH_INFO, 0, 0, len); 2985 2986 rtw89_phy_write32_mask(rtwdev, R_CHK_LPS_STAT, B_CHK_LPS_STAT, 0); 2987 ret = rtw89_h2c_tx(rtwdev, skb, false); 2988 if (ret) { 2989 rtw89_err(rtwdev, "failed to send h2c\n"); 2990 goto fail; 2991 } 2992 2993 ret = read_poll_timeout(rtw89_phy_read32_mask, done, done, 50, 5000, 2994 true, rtwdev, R_CHK_LPS_STAT, B_CHK_LPS_STAT); 2995 if (ret) 2996 rtw89_warn(rtwdev, "h2c_lps_ch_info done polling timeout\n"); 2997 2998 return 0; 2999 fail: 3000 dev_kfree_skb_any(skb); 3001 3002 return ret; 3003 } 3004 3005 int rtw89_fw_h2c_lps_ml_cmn_info(struct rtw89_dev *rtwdev, 3006 struct rtw89_vif *rtwvif) 3007 { 3008 const struct rtw89_phy_bb_gain_info_be *gain = &rtwdev->bb_gain.be; 3009 struct rtw89_pkt_stat *pkt_stat = &rtwdev->phystat.cur_pkt_stat; 3010 static const u8 bcn_bw_ofst[] = {0, 0, 0, 3, 6, 9, 0, 12}; 3011 const struct rtw89_chip_info *chip = rtwdev->chip; 3012 struct rtw89_efuse *efuse = &rtwdev->efuse; 3013 struct rtw89_h2c_lps_ml_cmn_info *h2c; 3014 struct rtw89_vif_link *rtwvif_link; 3015 const struct rtw89_chan *chan; 3016 u8 bw_idx = RTW89_BB_BW_20_40; 3017 u32 len = sizeof(*h2c); 3018 unsigned int link_id; 3019 struct sk_buff *skb; 3020 u8 beacon_bw_ofst; 3021 u8 gain_band; 3022 u32 done; 3023 u8 path; 3024 int ret; 3025 int i; 3026 3027 if (chip->chip_gen != RTW89_CHIP_BE) 3028 return 0; 3029 3030 skb = rtw89_fw_h2c_alloc_skb_with_hdr(rtwdev, len); 3031 if (!skb) { 3032 rtw89_err(rtwdev, "failed to alloc skb for h2c lps_ml_cmn_info\n"); 3033 return -ENOMEM; 3034 } 3035 skb_put(skb, len); 3036 h2c = (struct rtw89_h2c_lps_ml_cmn_info *)skb->data; 3037 3038 h2c->fmt_id = 0x3; 3039 3040 h2c->mlo_dbcc_mode = cpu_to_le32(rtwdev->mlo_dbcc_mode); 3041 h2c->rfe_type = efuse->rfe_type; 3042 3043 rtw89_vif_for_each_link(rtwvif, rtwvif_link, link_id) { 3044 path = rtwvif_link->phy_idx == RTW89_PHY_1 ? RF_PATH_B : RF_PATH_A; 3045 chan = rtw89_chan_get(rtwdev, rtwvif_link->chanctx_idx); 3046 gain_band = rtw89_subband_to_gain_band_be(chan->subband_type); 3047 3048 h2c->central_ch[rtwvif_link->phy_idx] = chan->channel; 3049 h2c->pri_ch[rtwvif_link->phy_idx] = chan->primary_channel; 3050 h2c->band[rtwvif_link->phy_idx] = chan->band_type; 3051 h2c->bw[rtwvif_link->phy_idx] = chan->band_width; 3052 if (pkt_stat->beacon_rate < RTW89_HW_RATE_OFDM6) 3053 h2c->bcn_rate_type[rtwvif_link->phy_idx] = 0x1; 3054 else 3055 h2c->bcn_rate_type[rtwvif_link->phy_idx] = 0x2; 3056 3057 /* Fill BW20 RX gain table for beacon mode */ 3058 for (i = 0; i < TIA_GAIN_NUM; i++) { 3059 h2c->tia_gain[rtwvif_link->phy_idx][i] = 3060 cpu_to_le16(gain->tia_gain[gain_band][bw_idx][path][i]); 3061 } 3062 3063 if (rtwvif_link->bcn_bw_idx < ARRAY_SIZE(bcn_bw_ofst)) { 3064 beacon_bw_ofst = bcn_bw_ofst[rtwvif_link->bcn_bw_idx]; 3065 h2c->dup_bcn_ofst[rtwvif_link->phy_idx] = beacon_bw_ofst; 3066 } 3067 3068 memcpy(h2c->lna_gain[rtwvif_link->phy_idx], 3069 gain->lna_gain[gain_band][bw_idx][path], 3070 LNA_GAIN_NUM); 3071 memcpy(h2c->tia_lna_op1db[rtwvif_link->phy_idx], 3072 gain->tia_lna_op1db[gain_band][bw_idx][path], 3073 LNA_GAIN_NUM + 1); 3074 memcpy(h2c->lna_op1db[rtwvif_link->phy_idx], 3075 gain->lna_op1db[gain_band][bw_idx][path], 3076 LNA_GAIN_NUM); 3077 } 3078 3079 rtw89_h2c_pkt_set_hdr(rtwdev, skb, FWCMD_TYPE_H2C, 3080 H2C_CAT_OUTSRC, H2C_CL_OUTSRC_DM, 3081 H2C_FUNC_FW_LPS_ML_CMN_INFO, 0, 0, len); 3082 3083 rtw89_phy_write32_mask(rtwdev, R_CHK_LPS_STAT, B_CHK_LPS_STAT, 0); 3084 ret = rtw89_h2c_tx(rtwdev, skb, false); 3085 if (ret) { 3086 rtw89_err(rtwdev, "failed to send h2c\n"); 3087 goto fail; 3088 } 3089 3090 ret = read_poll_timeout(rtw89_phy_read32_mask, done, done, 50, 5000, 3091 true, rtwdev, R_CHK_LPS_STAT, B_CHK_LPS_STAT); 3092 if (ret) 3093 rtw89_warn(rtwdev, "h2c_lps_ml_cmn_info done polling timeout\n"); 3094 3095 return 0; 3096 fail: 3097 dev_kfree_skb_any(skb); 3098 3099 return ret; 3100 } 3101 3102 #define H2C_P2P_ACT_LEN 20 3103 int rtw89_fw_h2c_p2p_act(struct rtw89_dev *rtwdev, 3104 struct rtw89_vif_link *rtwvif_link, 3105 struct ieee80211_p2p_noa_desc *desc, 3106 u8 act, u8 noa_id, u8 ctwindow_oppps) 3107 { 3108 bool p2p_type_gc = rtwvif_link->wifi_role == RTW89_WIFI_ROLE_P2P_CLIENT; 3109 struct sk_buff *skb; 3110 u8 *cmd; 3111 int ret; 3112 3113 skb = rtw89_fw_h2c_alloc_skb_with_hdr(rtwdev, H2C_P2P_ACT_LEN); 3114 if (!skb) { 3115 rtw89_err(rtwdev, "failed to alloc skb for h2c p2p act\n"); 3116 return -ENOMEM; 3117 } 3118 skb_put(skb, H2C_P2P_ACT_LEN); 3119 cmd = skb->data; 3120 3121 RTW89_SET_FWCMD_P2P_MACID(cmd, rtwvif_link->mac_id); 3122 RTW89_SET_FWCMD_P2P_P2PID(cmd, 0); 3123 RTW89_SET_FWCMD_P2P_NOAID(cmd, noa_id); 3124 RTW89_SET_FWCMD_P2P_ACT(cmd, act); 3125 RTW89_SET_FWCMD_P2P_TYPE(cmd, p2p_type_gc); 3126 RTW89_SET_FWCMD_P2P_ALL_SLEP(cmd, 0); 3127 if (desc) { 3128 RTW89_SET_FWCMD_NOA_START_TIME(cmd, desc->start_time); 3129 RTW89_SET_FWCMD_NOA_INTERVAL(cmd, desc->interval); 3130 RTW89_SET_FWCMD_NOA_DURATION(cmd, desc->duration); 3131 RTW89_SET_FWCMD_NOA_COUNT(cmd, desc->count); 3132 RTW89_SET_FWCMD_NOA_CTWINDOW(cmd, ctwindow_oppps); 3133 } 3134 3135 rtw89_h2c_pkt_set_hdr(rtwdev, skb, FWCMD_TYPE_H2C, 3136 H2C_CAT_MAC, H2C_CL_MAC_PS, 3137 H2C_FUNC_P2P_ACT, 0, 0, 3138 H2C_P2P_ACT_LEN); 3139 3140 ret = rtw89_h2c_tx(rtwdev, skb, false); 3141 if (ret) { 3142 rtw89_err(rtwdev, "failed to send h2c\n"); 3143 goto fail; 3144 } 3145 3146 return 0; 3147 fail: 3148 dev_kfree_skb_any(skb); 3149 3150 return ret; 3151 } 3152 3153 static void __rtw89_fw_h2c_set_tx_path(struct rtw89_dev *rtwdev, 3154 struct sk_buff *skb) 3155 { 3156 const struct rtw89_chip_info *chip = rtwdev->chip; 3157 struct rtw89_hal *hal = &rtwdev->hal; 3158 u8 ntx_path; 3159 u8 map_b; 3160 3161 if (chip->rf_path_num == 1) { 3162 ntx_path = RF_A; 3163 map_b = 0; 3164 } else { 3165 ntx_path = hal->antenna_tx ? hal->antenna_tx : RF_AB; 3166 map_b = ntx_path == RF_AB ? 1 : 0; 3167 } 3168 3169 SET_CMC_TBL_NTX_PATH_EN(skb->data, ntx_path); 3170 SET_CMC_TBL_PATH_MAP_A(skb->data, 0); 3171 SET_CMC_TBL_PATH_MAP_B(skb->data, map_b); 3172 SET_CMC_TBL_PATH_MAP_C(skb->data, 0); 3173 SET_CMC_TBL_PATH_MAP_D(skb->data, 0); 3174 } 3175 3176 #define H2C_CMC_TBL_LEN 68 3177 int rtw89_fw_h2c_default_cmac_tbl(struct rtw89_dev *rtwdev, 3178 struct rtw89_vif_link *rtwvif_link, 3179 struct rtw89_sta_link *rtwsta_link) 3180 { 3181 const struct rtw89_chip_info *chip = rtwdev->chip; 3182 u8 macid = rtwsta_link ? rtwsta_link->mac_id : rtwvif_link->mac_id; 3183 struct sk_buff *skb; 3184 int ret; 3185 3186 skb = rtw89_fw_h2c_alloc_skb_with_hdr(rtwdev, H2C_CMC_TBL_LEN); 3187 if (!skb) { 3188 rtw89_err(rtwdev, "failed to alloc skb for fw dl\n"); 3189 return -ENOMEM; 3190 } 3191 skb_put(skb, H2C_CMC_TBL_LEN); 3192 SET_CTRL_INFO_MACID(skb->data, macid); 3193 SET_CTRL_INFO_OPERATION(skb->data, 1); 3194 if (chip->h2c_cctl_func_id == H2C_FUNC_MAC_CCTLINFO_UD) { 3195 SET_CMC_TBL_TXPWR_MODE(skb->data, 0); 3196 __rtw89_fw_h2c_set_tx_path(rtwdev, skb); 3197 SET_CMC_TBL_ANTSEL_A(skb->data, 0); 3198 SET_CMC_TBL_ANTSEL_B(skb->data, 0); 3199 SET_CMC_TBL_ANTSEL_C(skb->data, 0); 3200 SET_CMC_TBL_ANTSEL_D(skb->data, 0); 3201 } 3202 SET_CMC_TBL_DOPPLER_CTRL(skb->data, 0); 3203 SET_CMC_TBL_TXPWR_TOLERENCE(skb->data, 0); 3204 if (rtwvif_link->net_type == RTW89_NET_TYPE_AP_MODE) 3205 SET_CMC_TBL_DATA_DCM(skb->data, 0); 3206 3207 rtw89_h2c_pkt_set_hdr(rtwdev, skb, FWCMD_TYPE_H2C, 3208 H2C_CAT_MAC, H2C_CL_MAC_FR_EXCHG, 3209 chip->h2c_cctl_func_id, 0, 1, 3210 H2C_CMC_TBL_LEN); 3211 3212 ret = rtw89_h2c_tx(rtwdev, skb, false); 3213 if (ret) { 3214 rtw89_err(rtwdev, "failed to send h2c\n"); 3215 goto fail; 3216 } 3217 3218 return 0; 3219 fail: 3220 dev_kfree_skb_any(skb); 3221 3222 return ret; 3223 } 3224 EXPORT_SYMBOL(rtw89_fw_h2c_default_cmac_tbl); 3225 3226 int rtw89_fw_h2c_default_cmac_tbl_g7(struct rtw89_dev *rtwdev, 3227 struct rtw89_vif_link *rtwvif_link, 3228 struct rtw89_sta_link *rtwsta_link) 3229 { 3230 u8 mac_id = rtwsta_link ? rtwsta_link->mac_id : rtwvif_link->mac_id; 3231 struct rtw89_h2c_cctlinfo_ud_g7 *h2c; 3232 u32 len = sizeof(*h2c); 3233 struct sk_buff *skb; 3234 int ret; 3235 3236 skb = rtw89_fw_h2c_alloc_skb_with_hdr(rtwdev, len); 3237 if (!skb) { 3238 rtw89_err(rtwdev, "failed to alloc skb for cmac g7\n"); 3239 return -ENOMEM; 3240 } 3241 skb_put(skb, len); 3242 h2c = (struct rtw89_h2c_cctlinfo_ud_g7 *)skb->data; 3243 3244 h2c->c0 = le32_encode_bits(mac_id, CCTLINFO_G7_C0_MACID) | 3245 le32_encode_bits(1, CCTLINFO_G7_C0_OP); 3246 3247 h2c->w0 = le32_encode_bits(4, CCTLINFO_G7_W0_DATARATE); 3248 h2c->m0 = cpu_to_le32(CCTLINFO_G7_W0_ALL); 3249 3250 h2c->w1 = le32_encode_bits(4, CCTLINFO_G7_W1_DATA_RTY_LOWEST_RATE) | 3251 le32_encode_bits(0xa, CCTLINFO_G7_W1_RTSRATE) | 3252 le32_encode_bits(4, CCTLINFO_G7_W1_RTS_RTY_LOWEST_RATE); 3253 h2c->m1 = cpu_to_le32(CCTLINFO_G7_W1_ALL); 3254 3255 h2c->m2 = cpu_to_le32(CCTLINFO_G7_W2_ALL); 3256 3257 h2c->m3 = cpu_to_le32(CCTLINFO_G7_W3_ALL); 3258 3259 h2c->w4 = le32_encode_bits(0xFFFF, CCTLINFO_G7_W4_ACT_SUBCH_CBW); 3260 h2c->m4 = cpu_to_le32(CCTLINFO_G7_W4_ALL); 3261 3262 h2c->w5 = le32_encode_bits(2, CCTLINFO_G7_W5_NOMINAL_PKT_PADDING0) | 3263 le32_encode_bits(2, CCTLINFO_G7_W5_NOMINAL_PKT_PADDING1) | 3264 le32_encode_bits(2, CCTLINFO_G7_W5_NOMINAL_PKT_PADDING2) | 3265 le32_encode_bits(2, CCTLINFO_G7_W5_NOMINAL_PKT_PADDING3) | 3266 le32_encode_bits(2, CCTLINFO_G7_W5_NOMINAL_PKT_PADDING4); 3267 h2c->m5 = cpu_to_le32(CCTLINFO_G7_W5_ALL); 3268 3269 h2c->w6 = le32_encode_bits(0xb, CCTLINFO_G7_W6_RESP_REF_RATE); 3270 h2c->m6 = cpu_to_le32(CCTLINFO_G7_W6_ALL); 3271 3272 h2c->w7 = le32_encode_bits(1, CCTLINFO_G7_W7_NC) | 3273 le32_encode_bits(1, CCTLINFO_G7_W7_NR) | 3274 le32_encode_bits(1, CCTLINFO_G7_W7_CB) | 3275 le32_encode_bits(0x1, CCTLINFO_G7_W7_CSI_PARA_EN) | 3276 le32_encode_bits(0xb, CCTLINFO_G7_W7_CSI_FIX_RATE); 3277 h2c->m7 = cpu_to_le32(CCTLINFO_G7_W7_ALL); 3278 3279 h2c->m8 = cpu_to_le32(CCTLINFO_G7_W8_ALL); 3280 3281 h2c->w14 = le32_encode_bits(0, CCTLINFO_G7_W14_VO_CURR_RATE) | 3282 le32_encode_bits(0, CCTLINFO_G7_W14_VI_CURR_RATE) | 3283 le32_encode_bits(0, CCTLINFO_G7_W14_BE_CURR_RATE_L); 3284 h2c->m14 = cpu_to_le32(CCTLINFO_G7_W14_ALL); 3285 3286 h2c->w15 = le32_encode_bits(0, CCTLINFO_G7_W15_BE_CURR_RATE_H) | 3287 le32_encode_bits(0, CCTLINFO_G7_W15_BK_CURR_RATE) | 3288 le32_encode_bits(0, CCTLINFO_G7_W15_MGNT_CURR_RATE); 3289 h2c->m15 = cpu_to_le32(CCTLINFO_G7_W15_ALL); 3290 3291 rtw89_h2c_pkt_set_hdr(rtwdev, skb, FWCMD_TYPE_H2C, 3292 H2C_CAT_MAC, H2C_CL_MAC_FR_EXCHG, 3293 H2C_FUNC_MAC_CCTLINFO_UD_G7, 0, 1, 3294 len); 3295 3296 ret = rtw89_h2c_tx(rtwdev, skb, false); 3297 if (ret) { 3298 rtw89_err(rtwdev, "failed to send h2c\n"); 3299 goto fail; 3300 } 3301 3302 return 0; 3303 fail: 3304 dev_kfree_skb_any(skb); 3305 3306 return ret; 3307 } 3308 EXPORT_SYMBOL(rtw89_fw_h2c_default_cmac_tbl_g7); 3309 3310 static void __get_sta_he_pkt_padding(struct rtw89_dev *rtwdev, 3311 struct ieee80211_link_sta *link_sta, 3312 u8 *pads) 3313 { 3314 bool ppe_th; 3315 u8 ppe16, ppe8; 3316 u8 nss = min(link_sta->rx_nss, rtwdev->hal.tx_nss) - 1; 3317 u8 ppe_thres_hdr = link_sta->he_cap.ppe_thres[0]; 3318 u8 ru_bitmap; 3319 u8 n, idx, sh; 3320 u16 ppe; 3321 int i; 3322 3323 ppe_th = FIELD_GET(IEEE80211_HE_PHY_CAP6_PPE_THRESHOLD_PRESENT, 3324 link_sta->he_cap.he_cap_elem.phy_cap_info[6]); 3325 if (!ppe_th) { 3326 u8 pad; 3327 3328 pad = FIELD_GET(IEEE80211_HE_PHY_CAP9_NOMINAL_PKT_PADDING_MASK, 3329 link_sta->he_cap.he_cap_elem.phy_cap_info[9]); 3330 3331 for (i = 0; i < RTW89_PPE_BW_NUM; i++) 3332 pads[i] = pad; 3333 3334 return; 3335 } 3336 3337 ru_bitmap = FIELD_GET(IEEE80211_PPE_THRES_RU_INDEX_BITMASK_MASK, ppe_thres_hdr); 3338 n = hweight8(ru_bitmap); 3339 n = 7 + (n * IEEE80211_PPE_THRES_INFO_PPET_SIZE * 2) * nss; 3340 3341 for (i = 0; i < RTW89_PPE_BW_NUM; i++) { 3342 if (!(ru_bitmap & BIT(i))) { 3343 pads[i] = 1; 3344 continue; 3345 } 3346 3347 idx = n >> 3; 3348 sh = n & 7; 3349 n += IEEE80211_PPE_THRES_INFO_PPET_SIZE * 2; 3350 3351 ppe = le16_to_cpu(*((__le16 *)&link_sta->he_cap.ppe_thres[idx])); 3352 ppe16 = (ppe >> sh) & IEEE80211_PPE_THRES_NSS_MASK; 3353 sh += IEEE80211_PPE_THRES_INFO_PPET_SIZE; 3354 ppe8 = (ppe >> sh) & IEEE80211_PPE_THRES_NSS_MASK; 3355 3356 if (ppe16 != 7 && ppe8 == 7) 3357 pads[i] = RTW89_PE_DURATION_16; 3358 else if (ppe8 != 7) 3359 pads[i] = RTW89_PE_DURATION_8; 3360 else 3361 pads[i] = RTW89_PE_DURATION_0; 3362 } 3363 } 3364 3365 int rtw89_fw_h2c_assoc_cmac_tbl(struct rtw89_dev *rtwdev, 3366 struct rtw89_vif_link *rtwvif_link, 3367 struct rtw89_sta_link *rtwsta_link) 3368 { 3369 struct ieee80211_vif *vif = rtwvif_link_to_vif(rtwvif_link); 3370 const struct rtw89_chip_info *chip = rtwdev->chip; 3371 const struct rtw89_chan *chan = rtw89_chan_get(rtwdev, 3372 rtwvif_link->chanctx_idx); 3373 struct ieee80211_link_sta *link_sta; 3374 struct sk_buff *skb; 3375 u8 pads[RTW89_PPE_BW_NUM]; 3376 u8 mac_id = rtwsta_link ? rtwsta_link->mac_id : rtwvif_link->mac_id; 3377 u16 lowest_rate; 3378 int ret; 3379 3380 memset(pads, 0, sizeof(pads)); 3381 3382 skb = rtw89_fw_h2c_alloc_skb_with_hdr(rtwdev, H2C_CMC_TBL_LEN); 3383 if (!skb) { 3384 rtw89_err(rtwdev, "failed to alloc skb for fw dl\n"); 3385 return -ENOMEM; 3386 } 3387 3388 rcu_read_lock(); 3389 3390 if (rtwsta_link) 3391 link_sta = rtw89_sta_rcu_dereference_link(rtwsta_link, true); 3392 3393 if (rtwsta_link && link_sta->he_cap.has_he) 3394 __get_sta_he_pkt_padding(rtwdev, link_sta, pads); 3395 3396 if (vif->p2p) 3397 lowest_rate = RTW89_HW_RATE_OFDM6; 3398 else if (chan->band_type == RTW89_BAND_2G) 3399 lowest_rate = RTW89_HW_RATE_CCK1; 3400 else 3401 lowest_rate = RTW89_HW_RATE_OFDM6; 3402 3403 skb_put(skb, H2C_CMC_TBL_LEN); 3404 SET_CTRL_INFO_MACID(skb->data, mac_id); 3405 SET_CTRL_INFO_OPERATION(skb->data, 1); 3406 SET_CMC_TBL_DISRTSFB(skb->data, 1); 3407 SET_CMC_TBL_DISDATAFB(skb->data, 1); 3408 SET_CMC_TBL_RTS_RTY_LOWEST_RATE(skb->data, lowest_rate); 3409 SET_CMC_TBL_RTS_TXCNT_LMT_SEL(skb->data, 0); 3410 SET_CMC_TBL_DATA_TXCNT_LMT_SEL(skb->data, 0); 3411 if (vif->type == NL80211_IFTYPE_STATION) 3412 SET_CMC_TBL_ULDL(skb->data, 1); 3413 else 3414 SET_CMC_TBL_ULDL(skb->data, 0); 3415 SET_CMC_TBL_MULTI_PORT_ID(skb->data, rtwvif_link->port); 3416 if (chip->h2c_cctl_func_id == H2C_FUNC_MAC_CCTLINFO_UD_V1) { 3417 SET_CMC_TBL_NOMINAL_PKT_PADDING_V1(skb->data, pads[RTW89_CHANNEL_WIDTH_20]); 3418 SET_CMC_TBL_NOMINAL_PKT_PADDING40_V1(skb->data, pads[RTW89_CHANNEL_WIDTH_40]); 3419 SET_CMC_TBL_NOMINAL_PKT_PADDING80_V1(skb->data, pads[RTW89_CHANNEL_WIDTH_80]); 3420 SET_CMC_TBL_NOMINAL_PKT_PADDING160_V1(skb->data, pads[RTW89_CHANNEL_WIDTH_160]); 3421 } else if (chip->h2c_cctl_func_id == H2C_FUNC_MAC_CCTLINFO_UD) { 3422 SET_CMC_TBL_NOMINAL_PKT_PADDING(skb->data, pads[RTW89_CHANNEL_WIDTH_20]); 3423 SET_CMC_TBL_NOMINAL_PKT_PADDING40(skb->data, pads[RTW89_CHANNEL_WIDTH_40]); 3424 SET_CMC_TBL_NOMINAL_PKT_PADDING80(skb->data, pads[RTW89_CHANNEL_WIDTH_80]); 3425 SET_CMC_TBL_NOMINAL_PKT_PADDING160(skb->data, pads[RTW89_CHANNEL_WIDTH_160]); 3426 } 3427 if (rtwsta_link) 3428 SET_CMC_TBL_BSR_QUEUE_SIZE_FORMAT(skb->data, 3429 link_sta->he_cap.has_he); 3430 if (rtwvif_link->net_type == RTW89_NET_TYPE_AP_MODE) 3431 SET_CMC_TBL_DATA_DCM(skb->data, 0); 3432 3433 rcu_read_unlock(); 3434 3435 rtw89_h2c_pkt_set_hdr(rtwdev, skb, FWCMD_TYPE_H2C, 3436 H2C_CAT_MAC, H2C_CL_MAC_FR_EXCHG, 3437 chip->h2c_cctl_func_id, 0, 1, 3438 H2C_CMC_TBL_LEN); 3439 3440 ret = rtw89_h2c_tx(rtwdev, skb, false); 3441 if (ret) { 3442 rtw89_err(rtwdev, "failed to send h2c\n"); 3443 goto fail; 3444 } 3445 3446 return 0; 3447 fail: 3448 dev_kfree_skb_any(skb); 3449 3450 return ret; 3451 } 3452 EXPORT_SYMBOL(rtw89_fw_h2c_assoc_cmac_tbl); 3453 3454 static void __get_sta_eht_pkt_padding(struct rtw89_dev *rtwdev, 3455 struct ieee80211_link_sta *link_sta, 3456 u8 *pads) 3457 { 3458 u8 nss = min(link_sta->rx_nss, rtwdev->hal.tx_nss) - 1; 3459 u16 ppe_thres_hdr; 3460 u8 ppe16, ppe8; 3461 u8 n, idx, sh; 3462 u8 ru_bitmap; 3463 bool ppe_th; 3464 u16 ppe; 3465 int i; 3466 3467 ppe_th = !!u8_get_bits(link_sta->eht_cap.eht_cap_elem.phy_cap_info[5], 3468 IEEE80211_EHT_PHY_CAP5_PPE_THRESHOLD_PRESENT); 3469 if (!ppe_th) { 3470 u8 pad; 3471 3472 pad = u8_get_bits(link_sta->eht_cap.eht_cap_elem.phy_cap_info[5], 3473 IEEE80211_EHT_PHY_CAP5_COMMON_NOMINAL_PKT_PAD_MASK); 3474 3475 for (i = 0; i < RTW89_PPE_BW_NUM; i++) 3476 pads[i] = pad; 3477 3478 return; 3479 } 3480 3481 ppe_thres_hdr = get_unaligned_le16(link_sta->eht_cap.eht_ppe_thres); 3482 ru_bitmap = u16_get_bits(ppe_thres_hdr, 3483 IEEE80211_EHT_PPE_THRES_RU_INDEX_BITMASK_MASK); 3484 n = hweight8(ru_bitmap); 3485 n = IEEE80211_EHT_PPE_THRES_INFO_HEADER_SIZE + 3486 (n * IEEE80211_EHT_PPE_THRES_INFO_PPET_SIZE * 2) * nss; 3487 3488 for (i = 0; i < RTW89_PPE_BW_NUM; i++) { 3489 if (!(ru_bitmap & BIT(i))) { 3490 pads[i] = 1; 3491 continue; 3492 } 3493 3494 idx = n >> 3; 3495 sh = n & 7; 3496 n += IEEE80211_EHT_PPE_THRES_INFO_PPET_SIZE * 2; 3497 3498 ppe = get_unaligned_le16(link_sta->eht_cap.eht_ppe_thres + idx); 3499 ppe16 = (ppe >> sh) & IEEE80211_PPE_THRES_NSS_MASK; 3500 sh += IEEE80211_EHT_PPE_THRES_INFO_PPET_SIZE; 3501 ppe8 = (ppe >> sh) & IEEE80211_PPE_THRES_NSS_MASK; 3502 3503 if (ppe16 != 7 && ppe8 == 7) 3504 pads[i] = RTW89_PE_DURATION_16_20; 3505 else if (ppe8 != 7) 3506 pads[i] = RTW89_PE_DURATION_8; 3507 else 3508 pads[i] = RTW89_PE_DURATION_0; 3509 } 3510 } 3511 3512 int rtw89_fw_h2c_assoc_cmac_tbl_g7(struct rtw89_dev *rtwdev, 3513 struct rtw89_vif_link *rtwvif_link, 3514 struct rtw89_sta_link *rtwsta_link) 3515 { 3516 struct ieee80211_vif *vif = rtwvif_link_to_vif(rtwvif_link); 3517 const struct rtw89_chan *chan = rtw89_chan_get(rtwdev, rtwvif_link->chanctx_idx); 3518 u8 mac_id = rtwsta_link ? rtwsta_link->mac_id : rtwvif_link->mac_id; 3519 struct rtw89_h2c_cctlinfo_ud_g7 *h2c; 3520 struct ieee80211_bss_conf *bss_conf; 3521 struct ieee80211_link_sta *link_sta; 3522 u8 pads[RTW89_PPE_BW_NUM]; 3523 u32 len = sizeof(*h2c); 3524 struct sk_buff *skb; 3525 u16 lowest_rate; 3526 int ret; 3527 3528 memset(pads, 0, sizeof(pads)); 3529 3530 skb = rtw89_fw_h2c_alloc_skb_with_hdr(rtwdev, len); 3531 if (!skb) { 3532 rtw89_err(rtwdev, "failed to alloc skb for cmac g7\n"); 3533 return -ENOMEM; 3534 } 3535 3536 rcu_read_lock(); 3537 3538 bss_conf = rtw89_vif_rcu_dereference_link(rtwvif_link, true); 3539 3540 if (rtwsta_link) { 3541 link_sta = rtw89_sta_rcu_dereference_link(rtwsta_link, true); 3542 3543 if (link_sta->eht_cap.has_eht) 3544 __get_sta_eht_pkt_padding(rtwdev, link_sta, pads); 3545 else if (link_sta->he_cap.has_he) 3546 __get_sta_he_pkt_padding(rtwdev, link_sta, pads); 3547 } 3548 3549 if (vif->p2p) 3550 lowest_rate = RTW89_HW_RATE_OFDM6; 3551 else if (chan->band_type == RTW89_BAND_2G) 3552 lowest_rate = RTW89_HW_RATE_CCK1; 3553 else 3554 lowest_rate = RTW89_HW_RATE_OFDM6; 3555 3556 skb_put(skb, len); 3557 h2c = (struct rtw89_h2c_cctlinfo_ud_g7 *)skb->data; 3558 3559 h2c->c0 = le32_encode_bits(mac_id, CCTLINFO_G7_C0_MACID) | 3560 le32_encode_bits(1, CCTLINFO_G7_C0_OP); 3561 3562 h2c->w0 = le32_encode_bits(1, CCTLINFO_G7_W0_DISRTSFB) | 3563 le32_encode_bits(1, CCTLINFO_G7_W0_DISDATAFB); 3564 h2c->m0 = cpu_to_le32(CCTLINFO_G7_W0_DISRTSFB | 3565 CCTLINFO_G7_W0_DISDATAFB); 3566 3567 h2c->w1 = le32_encode_bits(lowest_rate, CCTLINFO_G7_W1_RTS_RTY_LOWEST_RATE); 3568 h2c->m1 = cpu_to_le32(CCTLINFO_G7_W1_RTS_RTY_LOWEST_RATE); 3569 3570 h2c->w2 = le32_encode_bits(0, CCTLINFO_G7_W2_DATA_TXCNT_LMT_SEL); 3571 h2c->m2 = cpu_to_le32(CCTLINFO_G7_W2_DATA_TXCNT_LMT_SEL); 3572 3573 h2c->w3 = le32_encode_bits(0, CCTLINFO_G7_W3_RTS_TXCNT_LMT_SEL); 3574 h2c->m3 = cpu_to_le32(CCTLINFO_G7_W3_RTS_TXCNT_LMT_SEL); 3575 3576 h2c->w4 = le32_encode_bits(rtwvif_link->port, CCTLINFO_G7_W4_MULTI_PORT_ID); 3577 h2c->m4 = cpu_to_le32(CCTLINFO_G7_W4_MULTI_PORT_ID); 3578 3579 if (rtwvif_link->net_type == RTW89_NET_TYPE_AP_MODE) { 3580 h2c->w4 |= le32_encode_bits(0, CCTLINFO_G7_W4_DATA_DCM); 3581 h2c->m4 |= cpu_to_le32(CCTLINFO_G7_W4_DATA_DCM); 3582 } 3583 3584 if (bss_conf->eht_support) { 3585 u16 punct = bss_conf->chanreq.oper.punctured; 3586 3587 h2c->w4 |= le32_encode_bits(~punct, 3588 CCTLINFO_G7_W4_ACT_SUBCH_CBW); 3589 h2c->m4 |= cpu_to_le32(CCTLINFO_G7_W4_ACT_SUBCH_CBW); 3590 } 3591 3592 h2c->w5 = le32_encode_bits(pads[RTW89_CHANNEL_WIDTH_20], 3593 CCTLINFO_G7_W5_NOMINAL_PKT_PADDING0) | 3594 le32_encode_bits(pads[RTW89_CHANNEL_WIDTH_40], 3595 CCTLINFO_G7_W5_NOMINAL_PKT_PADDING1) | 3596 le32_encode_bits(pads[RTW89_CHANNEL_WIDTH_80], 3597 CCTLINFO_G7_W5_NOMINAL_PKT_PADDING2) | 3598 le32_encode_bits(pads[RTW89_CHANNEL_WIDTH_160], 3599 CCTLINFO_G7_W5_NOMINAL_PKT_PADDING3) | 3600 le32_encode_bits(pads[RTW89_CHANNEL_WIDTH_320], 3601 CCTLINFO_G7_W5_NOMINAL_PKT_PADDING4); 3602 h2c->m5 = cpu_to_le32(CCTLINFO_G7_W5_NOMINAL_PKT_PADDING0 | 3603 CCTLINFO_G7_W5_NOMINAL_PKT_PADDING1 | 3604 CCTLINFO_G7_W5_NOMINAL_PKT_PADDING2 | 3605 CCTLINFO_G7_W5_NOMINAL_PKT_PADDING3 | 3606 CCTLINFO_G7_W5_NOMINAL_PKT_PADDING4); 3607 3608 h2c->w6 = le32_encode_bits(vif->cfg.aid, CCTLINFO_G7_W6_AID12_PAID) | 3609 le32_encode_bits(vif->type == NL80211_IFTYPE_STATION ? 1 : 0, 3610 CCTLINFO_G7_W6_ULDL); 3611 h2c->m6 = cpu_to_le32(CCTLINFO_G7_W6_AID12_PAID | CCTLINFO_G7_W6_ULDL); 3612 3613 if (rtwsta_link) { 3614 h2c->w8 = le32_encode_bits(link_sta->he_cap.has_he, 3615 CCTLINFO_G7_W8_BSR_QUEUE_SIZE_FORMAT); 3616 h2c->m8 = cpu_to_le32(CCTLINFO_G7_W8_BSR_QUEUE_SIZE_FORMAT); 3617 } 3618 3619 rcu_read_unlock(); 3620 3621 rtw89_h2c_pkt_set_hdr(rtwdev, skb, FWCMD_TYPE_H2C, 3622 H2C_CAT_MAC, H2C_CL_MAC_FR_EXCHG, 3623 H2C_FUNC_MAC_CCTLINFO_UD_G7, 0, 1, 3624 len); 3625 3626 ret = rtw89_h2c_tx(rtwdev, skb, false); 3627 if (ret) { 3628 rtw89_err(rtwdev, "failed to send h2c\n"); 3629 goto fail; 3630 } 3631 3632 return 0; 3633 fail: 3634 dev_kfree_skb_any(skb); 3635 3636 return ret; 3637 } 3638 EXPORT_SYMBOL(rtw89_fw_h2c_assoc_cmac_tbl_g7); 3639 3640 int rtw89_fw_h2c_ampdu_cmac_tbl_g7(struct rtw89_dev *rtwdev, 3641 struct rtw89_vif_link *rtwvif_link, 3642 struct rtw89_sta_link *rtwsta_link) 3643 { 3644 struct rtw89_sta *rtwsta = rtwsta_link->rtwsta; 3645 struct rtw89_h2c_cctlinfo_ud_g7 *h2c; 3646 u32 len = sizeof(*h2c); 3647 struct sk_buff *skb; 3648 u16 agg_num = 0; 3649 u8 ba_bmap = 0; 3650 int ret; 3651 u8 tid; 3652 3653 skb = rtw89_fw_h2c_alloc_skb_with_hdr(rtwdev, len); 3654 if (!skb) { 3655 rtw89_err(rtwdev, "failed to alloc skb for ampdu cmac g7\n"); 3656 return -ENOMEM; 3657 } 3658 skb_put(skb, len); 3659 h2c = (struct rtw89_h2c_cctlinfo_ud_g7 *)skb->data; 3660 3661 for_each_set_bit(tid, rtwsta->ampdu_map, IEEE80211_NUM_TIDS) { 3662 if (agg_num == 0) 3663 agg_num = rtwsta->ampdu_params[tid].agg_num; 3664 else 3665 agg_num = min(agg_num, rtwsta->ampdu_params[tid].agg_num); 3666 } 3667 3668 if (agg_num <= 0x20) 3669 ba_bmap = 3; 3670 else if (agg_num > 0x20 && agg_num <= 0x40) 3671 ba_bmap = 0; 3672 else if (agg_num > 0x40 && agg_num <= 0x80) 3673 ba_bmap = 1; 3674 else if (agg_num > 0x80 && agg_num <= 0x100) 3675 ba_bmap = 2; 3676 else if (agg_num > 0x100 && agg_num <= 0x200) 3677 ba_bmap = 4; 3678 else if (agg_num > 0x200 && agg_num <= 0x400) 3679 ba_bmap = 5; 3680 3681 h2c->c0 = le32_encode_bits(rtwsta_link->mac_id, CCTLINFO_G7_C0_MACID) | 3682 le32_encode_bits(1, CCTLINFO_G7_C0_OP); 3683 3684 h2c->w3 = le32_encode_bits(ba_bmap, CCTLINFO_G7_W3_BA_BMAP); 3685 h2c->m3 = cpu_to_le32(CCTLINFO_G7_W3_BA_BMAP); 3686 3687 rtw89_h2c_pkt_set_hdr(rtwdev, skb, FWCMD_TYPE_H2C, 3688 H2C_CAT_MAC, H2C_CL_MAC_FR_EXCHG, 3689 H2C_FUNC_MAC_CCTLINFO_UD_G7, 0, 0, 3690 len); 3691 3692 ret = rtw89_h2c_tx(rtwdev, skb, false); 3693 if (ret) { 3694 rtw89_err(rtwdev, "failed to send h2c\n"); 3695 goto fail; 3696 } 3697 3698 return 0; 3699 fail: 3700 dev_kfree_skb_any(skb); 3701 3702 return ret; 3703 } 3704 EXPORT_SYMBOL(rtw89_fw_h2c_ampdu_cmac_tbl_g7); 3705 3706 int rtw89_fw_h2c_txtime_cmac_tbl(struct rtw89_dev *rtwdev, 3707 struct rtw89_sta_link *rtwsta_link) 3708 { 3709 const struct rtw89_chip_info *chip = rtwdev->chip; 3710 struct sk_buff *skb; 3711 int ret; 3712 3713 skb = rtw89_fw_h2c_alloc_skb_with_hdr(rtwdev, H2C_CMC_TBL_LEN); 3714 if (!skb) { 3715 rtw89_err(rtwdev, "failed to alloc skb for fw dl\n"); 3716 return -ENOMEM; 3717 } 3718 skb_put(skb, H2C_CMC_TBL_LEN); 3719 SET_CTRL_INFO_MACID(skb->data, rtwsta_link->mac_id); 3720 SET_CTRL_INFO_OPERATION(skb->data, 1); 3721 if (rtwsta_link->cctl_tx_time) { 3722 SET_CMC_TBL_AMPDU_TIME_SEL(skb->data, 1); 3723 SET_CMC_TBL_AMPDU_MAX_TIME(skb->data, rtwsta_link->ampdu_max_time); 3724 } 3725 if (rtwsta_link->cctl_tx_retry_limit) { 3726 SET_CMC_TBL_DATA_TXCNT_LMT_SEL(skb->data, 1); 3727 SET_CMC_TBL_DATA_TX_CNT_LMT(skb->data, rtwsta_link->data_tx_cnt_lmt); 3728 } 3729 3730 rtw89_h2c_pkt_set_hdr(rtwdev, skb, FWCMD_TYPE_H2C, 3731 H2C_CAT_MAC, H2C_CL_MAC_FR_EXCHG, 3732 chip->h2c_cctl_func_id, 0, 1, 3733 H2C_CMC_TBL_LEN); 3734 3735 ret = rtw89_h2c_tx(rtwdev, skb, false); 3736 if (ret) { 3737 rtw89_err(rtwdev, "failed to send h2c\n"); 3738 goto fail; 3739 } 3740 3741 return 0; 3742 fail: 3743 dev_kfree_skb_any(skb); 3744 3745 return ret; 3746 } 3747 EXPORT_SYMBOL(rtw89_fw_h2c_txtime_cmac_tbl); 3748 3749 int rtw89_fw_h2c_txtime_cmac_tbl_g7(struct rtw89_dev *rtwdev, 3750 struct rtw89_sta_link *rtwsta_link) 3751 { 3752 struct rtw89_h2c_cctlinfo_ud_g7 *h2c; 3753 u32 len = sizeof(*h2c); 3754 struct sk_buff *skb; 3755 int ret; 3756 3757 skb = rtw89_fw_h2c_alloc_skb_with_hdr(rtwdev, len); 3758 if (!skb) { 3759 rtw89_err(rtwdev, "failed to alloc skb for txtime_cmac_g7\n"); 3760 return -ENOMEM; 3761 } 3762 skb_put(skb, len); 3763 h2c = (struct rtw89_h2c_cctlinfo_ud_g7 *)skb->data; 3764 3765 h2c->c0 = le32_encode_bits(rtwsta_link->mac_id, CCTLINFO_G7_C0_MACID) | 3766 le32_encode_bits(1, CCTLINFO_G7_C0_OP); 3767 3768 if (rtwsta_link->cctl_tx_time) { 3769 h2c->w3 |= le32_encode_bits(1, CCTLINFO_G7_W3_AMPDU_TIME_SEL); 3770 h2c->m3 |= cpu_to_le32(CCTLINFO_G7_W3_AMPDU_TIME_SEL); 3771 3772 h2c->w2 |= le32_encode_bits(rtwsta_link->ampdu_max_time, 3773 CCTLINFO_G7_W2_AMPDU_MAX_TIME); 3774 h2c->m2 |= cpu_to_le32(CCTLINFO_G7_W2_AMPDU_MAX_TIME); 3775 } 3776 if (rtwsta_link->cctl_tx_retry_limit) { 3777 h2c->w2 |= le32_encode_bits(1, CCTLINFO_G7_W2_DATA_TXCNT_LMT_SEL) | 3778 le32_encode_bits(rtwsta_link->data_tx_cnt_lmt, 3779 CCTLINFO_G7_W2_DATA_TX_CNT_LMT); 3780 h2c->m2 |= cpu_to_le32(CCTLINFO_G7_W2_DATA_TXCNT_LMT_SEL | 3781 CCTLINFO_G7_W2_DATA_TX_CNT_LMT); 3782 } 3783 3784 rtw89_h2c_pkt_set_hdr(rtwdev, skb, FWCMD_TYPE_H2C, 3785 H2C_CAT_MAC, H2C_CL_MAC_FR_EXCHG, 3786 H2C_FUNC_MAC_CCTLINFO_UD_G7, 0, 1, 3787 len); 3788 3789 ret = rtw89_h2c_tx(rtwdev, skb, false); 3790 if (ret) { 3791 rtw89_err(rtwdev, "failed to send h2c\n"); 3792 goto fail; 3793 } 3794 3795 return 0; 3796 fail: 3797 dev_kfree_skb_any(skb); 3798 3799 return ret; 3800 } 3801 EXPORT_SYMBOL(rtw89_fw_h2c_txtime_cmac_tbl_g7); 3802 3803 int rtw89_fw_h2c_punctured_cmac_tbl_g7(struct rtw89_dev *rtwdev, 3804 struct rtw89_vif_link *rtwvif_link, 3805 u16 punctured) 3806 { 3807 struct rtw89_h2c_cctlinfo_ud_g7 *h2c; 3808 u32 len = sizeof(*h2c); 3809 struct sk_buff *skb; 3810 int ret; 3811 3812 skb = rtw89_fw_h2c_alloc_skb_with_hdr(rtwdev, len); 3813 if (!skb) { 3814 rtw89_err(rtwdev, "failed to alloc skb for punctured cmac g7\n"); 3815 return -ENOMEM; 3816 } 3817 3818 skb_put(skb, len); 3819 h2c = (struct rtw89_h2c_cctlinfo_ud_g7 *)skb->data; 3820 3821 h2c->c0 = le32_encode_bits(rtwvif_link->mac_id, CCTLINFO_G7_C0_MACID) | 3822 le32_encode_bits(1, CCTLINFO_G7_C0_OP); 3823 3824 h2c->w4 = le32_encode_bits(~punctured, CCTLINFO_G7_W4_ACT_SUBCH_CBW); 3825 h2c->m4 = cpu_to_le32(CCTLINFO_G7_W4_ACT_SUBCH_CBW); 3826 3827 rtw89_h2c_pkt_set_hdr(rtwdev, skb, FWCMD_TYPE_H2C, 3828 H2C_CAT_MAC, H2C_CL_MAC_FR_EXCHG, 3829 H2C_FUNC_MAC_CCTLINFO_UD_G7, 0, 1, 3830 len); 3831 3832 ret = rtw89_h2c_tx(rtwdev, skb, false); 3833 if (ret) { 3834 rtw89_err(rtwdev, "failed to send h2c\n"); 3835 goto fail; 3836 } 3837 3838 return 0; 3839 fail: 3840 dev_kfree_skb_any(skb); 3841 3842 return ret; 3843 } 3844 EXPORT_SYMBOL(rtw89_fw_h2c_punctured_cmac_tbl_g7); 3845 3846 int rtw89_fw_h2c_txpath_cmac_tbl(struct rtw89_dev *rtwdev, 3847 struct rtw89_sta_link *rtwsta_link) 3848 { 3849 const struct rtw89_chip_info *chip = rtwdev->chip; 3850 struct sk_buff *skb; 3851 int ret; 3852 3853 if (chip->h2c_cctl_func_id != H2C_FUNC_MAC_CCTLINFO_UD) 3854 return 0; 3855 3856 skb = rtw89_fw_h2c_alloc_skb_with_hdr(rtwdev, H2C_CMC_TBL_LEN); 3857 if (!skb) { 3858 rtw89_err(rtwdev, "failed to alloc skb for fw dl\n"); 3859 return -ENOMEM; 3860 } 3861 skb_put(skb, H2C_CMC_TBL_LEN); 3862 SET_CTRL_INFO_MACID(skb->data, rtwsta_link->mac_id); 3863 SET_CTRL_INFO_OPERATION(skb->data, 1); 3864 3865 __rtw89_fw_h2c_set_tx_path(rtwdev, skb); 3866 3867 rtw89_h2c_pkt_set_hdr(rtwdev, skb, FWCMD_TYPE_H2C, 3868 H2C_CAT_MAC, H2C_CL_MAC_FR_EXCHG, 3869 H2C_FUNC_MAC_CCTLINFO_UD, 0, 1, 3870 H2C_CMC_TBL_LEN); 3871 3872 ret = rtw89_h2c_tx(rtwdev, skb, false); 3873 if (ret) { 3874 rtw89_err(rtwdev, "failed to send h2c\n"); 3875 goto fail; 3876 } 3877 3878 return 0; 3879 fail: 3880 dev_kfree_skb_any(skb); 3881 3882 return ret; 3883 } 3884 3885 int rtw89_fw_h2c_update_beacon(struct rtw89_dev *rtwdev, 3886 struct rtw89_vif_link *rtwvif_link) 3887 { 3888 const struct rtw89_chan *chan = rtw89_chan_get(rtwdev, 3889 rtwvif_link->chanctx_idx); 3890 struct ieee80211_vif *vif = rtwvif_link_to_vif(rtwvif_link); 3891 struct rtw89_h2c_bcn_upd *h2c; 3892 struct sk_buff *skb_beacon; 3893 struct ieee80211_hdr *hdr; 3894 u32 len = sizeof(*h2c); 3895 struct sk_buff *skb; 3896 int bcn_total_len; 3897 u16 beacon_rate; 3898 u16 tim_offset; 3899 void *noa_data; 3900 u8 noa_len; 3901 int ret; 3902 3903 if (vif->p2p) 3904 beacon_rate = RTW89_HW_RATE_OFDM6; 3905 else if (chan->band_type == RTW89_BAND_2G) 3906 beacon_rate = RTW89_HW_RATE_CCK1; 3907 else 3908 beacon_rate = RTW89_HW_RATE_OFDM6; 3909 3910 skb_beacon = ieee80211_beacon_get_tim(rtwdev->hw, vif, &tim_offset, 3911 NULL, 0); 3912 if (!skb_beacon) { 3913 rtw89_err(rtwdev, "failed to get beacon skb\n"); 3914 return -ENOMEM; 3915 } 3916 3917 noa_len = rtw89_p2p_noa_fetch(rtwvif_link, &noa_data); 3918 if (noa_len && 3919 (noa_len <= skb_tailroom(skb_beacon) || 3920 pskb_expand_head(skb_beacon, 0, noa_len, GFP_KERNEL) == 0)) { 3921 skb_put_data(skb_beacon, noa_data, noa_len); 3922 } 3923 3924 hdr = (struct ieee80211_hdr *)skb_beacon; 3925 tim_offset -= ieee80211_hdrlen(hdr->frame_control); 3926 3927 bcn_total_len = len + skb_beacon->len; 3928 skb = rtw89_fw_h2c_alloc_skb_with_hdr(rtwdev, bcn_total_len); 3929 if (!skb) { 3930 rtw89_err(rtwdev, "failed to alloc skb for fw dl\n"); 3931 dev_kfree_skb_any(skb_beacon); 3932 return -ENOMEM; 3933 } 3934 skb_put(skb, len); 3935 h2c = (struct rtw89_h2c_bcn_upd *)skb->data; 3936 3937 h2c->w0 = le32_encode_bits(rtwvif_link->port, RTW89_H2C_BCN_UPD_W0_PORT) | 3938 le32_encode_bits(0, RTW89_H2C_BCN_UPD_W0_MBSSID) | 3939 le32_encode_bits(rtwvif_link->mac_idx, RTW89_H2C_BCN_UPD_W0_BAND) | 3940 le32_encode_bits(tim_offset | BIT(7), RTW89_H2C_BCN_UPD_W0_GRP_IE_OFST); 3941 h2c->w1 = le32_encode_bits(rtwvif_link->mac_id, RTW89_H2C_BCN_UPD_W1_MACID) | 3942 le32_encode_bits(RTW89_MGMT_HW_SSN_SEL, RTW89_H2C_BCN_UPD_W1_SSN_SEL) | 3943 le32_encode_bits(RTW89_MGMT_HW_SEQ_MODE, RTW89_H2C_BCN_UPD_W1_SSN_MODE) | 3944 le32_encode_bits(beacon_rate, RTW89_H2C_BCN_UPD_W1_RATE); 3945 3946 skb_put_data(skb, skb_beacon->data, skb_beacon->len); 3947 dev_kfree_skb_any(skb_beacon); 3948 3949 rtw89_h2c_pkt_set_hdr(rtwdev, skb, FWCMD_TYPE_H2C, 3950 H2C_CAT_MAC, H2C_CL_MAC_FR_EXCHG, 3951 H2C_FUNC_MAC_BCN_UPD, 0, 1, 3952 bcn_total_len); 3953 3954 ret = rtw89_h2c_tx(rtwdev, skb, false); 3955 if (ret) { 3956 rtw89_err(rtwdev, "failed to send h2c\n"); 3957 dev_kfree_skb_any(skb); 3958 return ret; 3959 } 3960 3961 return 0; 3962 } 3963 EXPORT_SYMBOL(rtw89_fw_h2c_update_beacon); 3964 3965 int rtw89_fw_h2c_update_beacon_be(struct rtw89_dev *rtwdev, 3966 struct rtw89_vif_link *rtwvif_link) 3967 { 3968 const struct rtw89_chan *chan = rtw89_chan_get(rtwdev, rtwvif_link->chanctx_idx); 3969 struct ieee80211_vif *vif = rtwvif_link_to_vif(rtwvif_link); 3970 struct rtw89_h2c_bcn_upd_be *h2c; 3971 struct sk_buff *skb_beacon; 3972 struct ieee80211_hdr *hdr; 3973 u32 len = sizeof(*h2c); 3974 struct sk_buff *skb; 3975 int bcn_total_len; 3976 u16 beacon_rate; 3977 u16 tim_offset; 3978 void *noa_data; 3979 u8 noa_len; 3980 int ret; 3981 3982 if (vif->p2p) 3983 beacon_rate = RTW89_HW_RATE_OFDM6; 3984 else if (chan->band_type == RTW89_BAND_2G) 3985 beacon_rate = RTW89_HW_RATE_CCK1; 3986 else 3987 beacon_rate = RTW89_HW_RATE_OFDM6; 3988 3989 skb_beacon = ieee80211_beacon_get_tim(rtwdev->hw, vif, &tim_offset, 3990 NULL, 0); 3991 if (!skb_beacon) { 3992 rtw89_err(rtwdev, "failed to get beacon skb\n"); 3993 return -ENOMEM; 3994 } 3995 3996 noa_len = rtw89_p2p_noa_fetch(rtwvif_link, &noa_data); 3997 if (noa_len && 3998 (noa_len <= skb_tailroom(skb_beacon) || 3999 pskb_expand_head(skb_beacon, 0, noa_len, GFP_KERNEL) == 0)) { 4000 skb_put_data(skb_beacon, noa_data, noa_len); 4001 } 4002 4003 hdr = (struct ieee80211_hdr *)skb_beacon; 4004 tim_offset -= ieee80211_hdrlen(hdr->frame_control); 4005 4006 bcn_total_len = len + skb_beacon->len; 4007 skb = rtw89_fw_h2c_alloc_skb_with_hdr(rtwdev, bcn_total_len); 4008 if (!skb) { 4009 rtw89_err(rtwdev, "failed to alloc skb for fw dl\n"); 4010 dev_kfree_skb_any(skb_beacon); 4011 return -ENOMEM; 4012 } 4013 skb_put(skb, len); 4014 h2c = (struct rtw89_h2c_bcn_upd_be *)skb->data; 4015 4016 h2c->w0 = le32_encode_bits(rtwvif_link->port, RTW89_H2C_BCN_UPD_BE_W0_PORT) | 4017 le32_encode_bits(0, RTW89_H2C_BCN_UPD_BE_W0_MBSSID) | 4018 le32_encode_bits(rtwvif_link->mac_idx, RTW89_H2C_BCN_UPD_BE_W0_BAND) | 4019 le32_encode_bits(tim_offset | BIT(7), RTW89_H2C_BCN_UPD_BE_W0_GRP_IE_OFST); 4020 h2c->w1 = le32_encode_bits(rtwvif_link->mac_id, RTW89_H2C_BCN_UPD_BE_W1_MACID) | 4021 le32_encode_bits(RTW89_MGMT_HW_SSN_SEL, RTW89_H2C_BCN_UPD_BE_W1_SSN_SEL) | 4022 le32_encode_bits(RTW89_MGMT_HW_SEQ_MODE, RTW89_H2C_BCN_UPD_BE_W1_SSN_MODE) | 4023 le32_encode_bits(beacon_rate, RTW89_H2C_BCN_UPD_BE_W1_RATE); 4024 4025 skb_put_data(skb, skb_beacon->data, skb_beacon->len); 4026 dev_kfree_skb_any(skb_beacon); 4027 4028 rtw89_h2c_pkt_set_hdr(rtwdev, skb, FWCMD_TYPE_H2C, 4029 H2C_CAT_MAC, H2C_CL_MAC_FR_EXCHG, 4030 H2C_FUNC_MAC_BCN_UPD_BE, 0, 1, 4031 bcn_total_len); 4032 4033 ret = rtw89_h2c_tx(rtwdev, skb, false); 4034 if (ret) { 4035 rtw89_err(rtwdev, "failed to send h2c\n"); 4036 goto fail; 4037 } 4038 4039 return 0; 4040 4041 fail: 4042 dev_kfree_skb_any(skb); 4043 4044 return ret; 4045 } 4046 EXPORT_SYMBOL(rtw89_fw_h2c_update_beacon_be); 4047 4048 int rtw89_fw_h2c_role_maintain(struct rtw89_dev *rtwdev, 4049 struct rtw89_vif_link *rtwvif_link, 4050 struct rtw89_sta_link *rtwsta_link, 4051 enum rtw89_upd_mode upd_mode) 4052 { 4053 u8 mac_id = rtwsta_link ? rtwsta_link->mac_id : rtwvif_link->mac_id; 4054 struct rtw89_h2c_role_maintain *h2c; 4055 u32 len = sizeof(*h2c); 4056 struct sk_buff *skb; 4057 u8 self_role; 4058 int ret; 4059 4060 if (rtwvif_link->net_type == RTW89_NET_TYPE_AP_MODE) { 4061 if (rtwsta_link) 4062 self_role = RTW89_SELF_ROLE_AP_CLIENT; 4063 else 4064 self_role = rtwvif_link->self_role; 4065 } else { 4066 self_role = rtwvif_link->self_role; 4067 } 4068 4069 skb = rtw89_fw_h2c_alloc_skb_with_hdr(rtwdev, len); 4070 if (!skb) { 4071 rtw89_err(rtwdev, "failed to alloc skb for h2c join\n"); 4072 return -ENOMEM; 4073 } 4074 skb_put(skb, len); 4075 h2c = (struct rtw89_h2c_role_maintain *)skb->data; 4076 4077 h2c->w0 = le32_encode_bits(mac_id, RTW89_H2C_ROLE_MAINTAIN_W0_MACID) | 4078 le32_encode_bits(self_role, RTW89_H2C_ROLE_MAINTAIN_W0_SELF_ROLE) | 4079 le32_encode_bits(upd_mode, RTW89_H2C_ROLE_MAINTAIN_W0_UPD_MODE) | 4080 le32_encode_bits(rtwvif_link->wifi_role, 4081 RTW89_H2C_ROLE_MAINTAIN_W0_WIFI_ROLE) | 4082 le32_encode_bits(rtwvif_link->mac_idx, 4083 RTW89_H2C_ROLE_MAINTAIN_W0_BAND) | 4084 le32_encode_bits(rtwvif_link->port, RTW89_H2C_ROLE_MAINTAIN_W0_PORT); 4085 4086 rtw89_h2c_pkt_set_hdr(rtwdev, skb, FWCMD_TYPE_H2C, 4087 H2C_CAT_MAC, H2C_CL_MAC_MEDIA_RPT, 4088 H2C_FUNC_MAC_FWROLE_MAINTAIN, 0, 1, 4089 len); 4090 4091 ret = rtw89_h2c_tx(rtwdev, skb, false); 4092 if (ret) { 4093 rtw89_err(rtwdev, "failed to send h2c\n"); 4094 goto fail; 4095 } 4096 4097 return 0; 4098 fail: 4099 dev_kfree_skb_any(skb); 4100 4101 return ret; 4102 } 4103 4104 static enum rtw89_fw_sta_type 4105 rtw89_fw_get_sta_type(struct rtw89_dev *rtwdev, struct rtw89_vif_link *rtwvif_link, 4106 struct rtw89_sta_link *rtwsta_link) 4107 { 4108 struct ieee80211_bss_conf *bss_conf; 4109 struct ieee80211_link_sta *link_sta; 4110 enum rtw89_fw_sta_type type; 4111 4112 rcu_read_lock(); 4113 4114 if (!rtwsta_link) 4115 goto by_vif; 4116 4117 link_sta = rtw89_sta_rcu_dereference_link(rtwsta_link, true); 4118 4119 if (link_sta->eht_cap.has_eht) 4120 type = RTW89_FW_BE_STA; 4121 else if (link_sta->he_cap.has_he) 4122 type = RTW89_FW_AX_STA; 4123 else 4124 type = RTW89_FW_N_AC_STA; 4125 4126 goto out; 4127 4128 by_vif: 4129 bss_conf = rtw89_vif_rcu_dereference_link(rtwvif_link, true); 4130 4131 if (bss_conf->eht_support) 4132 type = RTW89_FW_BE_STA; 4133 else if (bss_conf->he_support) 4134 type = RTW89_FW_AX_STA; 4135 else 4136 type = RTW89_FW_N_AC_STA; 4137 4138 out: 4139 rcu_read_unlock(); 4140 4141 return type; 4142 } 4143 4144 int rtw89_fw_h2c_join_info(struct rtw89_dev *rtwdev, struct rtw89_vif_link *rtwvif_link, 4145 struct rtw89_sta_link *rtwsta_link, bool dis_conn) 4146 { 4147 u8 mac_id = rtwsta_link ? rtwsta_link->mac_id : rtwvif_link->mac_id; 4148 struct ieee80211_vif *vif = rtwvif_link_to_vif(rtwvif_link); 4149 bool is_mld = ieee80211_vif_is_mld(vif); 4150 u8 self_role = rtwvif_link->self_role; 4151 enum rtw89_fw_sta_type sta_type; 4152 u8 net_type = rtwvif_link->net_type; 4153 struct rtw89_h2c_join_v1 *h2c_v1; 4154 struct rtw89_h2c_join *h2c; 4155 u32 len = sizeof(*h2c); 4156 bool format_v1 = false; 4157 struct sk_buff *skb; 4158 u8 main_mac_id; 4159 bool init_ps; 4160 int ret; 4161 4162 if (rtwdev->chip->chip_gen == RTW89_CHIP_BE) { 4163 len = sizeof(*h2c_v1); 4164 format_v1 = true; 4165 } 4166 4167 if (net_type == RTW89_NET_TYPE_AP_MODE && rtwsta_link) { 4168 self_role = RTW89_SELF_ROLE_AP_CLIENT; 4169 net_type = dis_conn ? RTW89_NET_TYPE_NO_LINK : net_type; 4170 } 4171 4172 skb = rtw89_fw_h2c_alloc_skb_with_hdr(rtwdev, len); 4173 if (!skb) { 4174 rtw89_err(rtwdev, "failed to alloc skb for h2c join\n"); 4175 return -ENOMEM; 4176 } 4177 skb_put(skb, len); 4178 h2c = (struct rtw89_h2c_join *)skb->data; 4179 4180 h2c->w0 = le32_encode_bits(mac_id, RTW89_H2C_JOININFO_W0_MACID) | 4181 le32_encode_bits(dis_conn, RTW89_H2C_JOININFO_W0_OP) | 4182 le32_encode_bits(rtwvif_link->mac_idx, RTW89_H2C_JOININFO_W0_BAND) | 4183 le32_encode_bits(rtwvif_link->wmm, RTW89_H2C_JOININFO_W0_WMM) | 4184 le32_encode_bits(rtwvif_link->trigger, RTW89_H2C_JOININFO_W0_TGR) | 4185 le32_encode_bits(0, RTW89_H2C_JOININFO_W0_ISHESTA) | 4186 le32_encode_bits(0, RTW89_H2C_JOININFO_W0_DLBW) | 4187 le32_encode_bits(0, RTW89_H2C_JOININFO_W0_TF_MAC_PAD) | 4188 le32_encode_bits(0, RTW89_H2C_JOININFO_W0_DL_T_PE) | 4189 le32_encode_bits(rtwvif_link->port, RTW89_H2C_JOININFO_W0_PORT_ID) | 4190 le32_encode_bits(net_type, RTW89_H2C_JOININFO_W0_NET_TYPE) | 4191 le32_encode_bits(rtwvif_link->wifi_role, 4192 RTW89_H2C_JOININFO_W0_WIFI_ROLE) | 4193 le32_encode_bits(self_role, RTW89_H2C_JOININFO_W0_SELF_ROLE); 4194 4195 if (!format_v1) 4196 goto done; 4197 4198 h2c_v1 = (struct rtw89_h2c_join_v1 *)skb->data; 4199 4200 sta_type = rtw89_fw_get_sta_type(rtwdev, rtwvif_link, rtwsta_link); 4201 init_ps = rtwvif_link != rtw89_get_designated_link(rtwvif_link->rtwvif); 4202 4203 if (rtwsta_link) 4204 main_mac_id = rtw89_sta_get_main_macid(rtwsta_link->rtwsta); 4205 else 4206 main_mac_id = rtw89_vif_get_main_macid(rtwvif_link->rtwvif); 4207 4208 h2c_v1->w1 = le32_encode_bits(sta_type, RTW89_H2C_JOININFO_W1_STA_TYPE) | 4209 le32_encode_bits(is_mld, RTW89_H2C_JOININFO_W1_IS_MLD) | 4210 le32_encode_bits(main_mac_id, RTW89_H2C_JOININFO_W1_MAIN_MACID) | 4211 le32_encode_bits(RTW89_H2C_JOININFO_MLO_MODE_MLSR, 4212 RTW89_H2C_JOININFO_W1_MLO_MODE) | 4213 le32_encode_bits(0, RTW89_H2C_JOININFO_W1_EMLSR_CAB) | 4214 le32_encode_bits(0, RTW89_H2C_JOININFO_W1_NSTR_EN) | 4215 le32_encode_bits(init_ps, RTW89_H2C_JOININFO_W1_INIT_PWR_STATE) | 4216 le32_encode_bits(IEEE80211_EML_CAP_EMLSR_PADDING_DELAY_256US, 4217 RTW89_H2C_JOININFO_W1_EMLSR_PADDING) | 4218 le32_encode_bits(IEEE80211_EML_CAP_EMLSR_TRANSITION_DELAY_256US, 4219 RTW89_H2C_JOININFO_W1_EMLSR_TRANS_DELAY) | 4220 le32_encode_bits(0, RTW89_H2C_JOININFO_W2_MACID_EXT) | 4221 le32_encode_bits(0, RTW89_H2C_JOININFO_W2_MAIN_MACID_EXT); 4222 4223 h2c_v1->w2 = 0; 4224 4225 done: 4226 rtw89_h2c_pkt_set_hdr(rtwdev, skb, FWCMD_TYPE_H2C, 4227 H2C_CAT_MAC, H2C_CL_MAC_MEDIA_RPT, 4228 H2C_FUNC_MAC_JOININFO, 0, 1, 4229 len); 4230 4231 ret = rtw89_h2c_tx(rtwdev, skb, false); 4232 if (ret) { 4233 rtw89_err(rtwdev, "failed to send h2c\n"); 4234 goto fail; 4235 } 4236 4237 return 0; 4238 fail: 4239 dev_kfree_skb_any(skb); 4240 4241 return ret; 4242 } 4243 4244 int rtw89_fw_h2c_notify_dbcc(struct rtw89_dev *rtwdev, bool en) 4245 { 4246 struct rtw89_h2c_notify_dbcc *h2c; 4247 u32 len = sizeof(*h2c); 4248 struct sk_buff *skb; 4249 int ret; 4250 4251 skb = rtw89_fw_h2c_alloc_skb_with_hdr(rtwdev, len); 4252 if (!skb) { 4253 rtw89_err(rtwdev, "failed to alloc skb for h2c notify dbcc\n"); 4254 return -ENOMEM; 4255 } 4256 skb_put(skb, len); 4257 h2c = (struct rtw89_h2c_notify_dbcc *)skb->data; 4258 4259 h2c->w0 = le32_encode_bits(en, RTW89_H2C_NOTIFY_DBCC_EN); 4260 4261 rtw89_h2c_pkt_set_hdr(rtwdev, skb, FWCMD_TYPE_H2C, 4262 H2C_CAT_MAC, H2C_CL_MAC_MEDIA_RPT, 4263 H2C_FUNC_NOTIFY_DBCC, 0, 1, 4264 len); 4265 4266 ret = rtw89_h2c_tx(rtwdev, skb, false); 4267 if (ret) { 4268 rtw89_err(rtwdev, "failed to send h2c\n"); 4269 goto fail; 4270 } 4271 4272 return 0; 4273 fail: 4274 dev_kfree_skb_any(skb); 4275 4276 return ret; 4277 } 4278 4279 int rtw89_fw_h2c_macid_pause(struct rtw89_dev *rtwdev, u8 sh, u8 grp, 4280 bool pause) 4281 { 4282 struct rtw89_fw_macid_pause_sleep_grp *h2c_new; 4283 struct rtw89_fw_macid_pause_grp *h2c; 4284 __le32 set = cpu_to_le32(BIT(sh)); 4285 u8 h2c_macid_pause_id; 4286 struct sk_buff *skb; 4287 u32 len; 4288 int ret; 4289 4290 if (RTW89_CHK_FW_FEATURE(MACID_PAUSE_SLEEP, &rtwdev->fw)) { 4291 h2c_macid_pause_id = H2C_FUNC_MAC_MACID_PAUSE_SLEEP; 4292 len = sizeof(*h2c_new); 4293 } else { 4294 h2c_macid_pause_id = H2C_FUNC_MAC_MACID_PAUSE; 4295 len = sizeof(*h2c); 4296 } 4297 4298 skb = rtw89_fw_h2c_alloc_skb_with_hdr(rtwdev, len); 4299 if (!skb) { 4300 rtw89_err(rtwdev, "failed to alloc skb for h2c macid pause\n"); 4301 return -ENOMEM; 4302 } 4303 skb_put(skb, len); 4304 4305 if (h2c_macid_pause_id == H2C_FUNC_MAC_MACID_PAUSE_SLEEP) { 4306 h2c_new = (struct rtw89_fw_macid_pause_sleep_grp *)skb->data; 4307 4308 h2c_new->n[0].pause_mask_grp[grp] = set; 4309 h2c_new->n[0].sleep_mask_grp[grp] = set; 4310 if (pause) { 4311 h2c_new->n[0].pause_grp[grp] = set; 4312 h2c_new->n[0].sleep_grp[grp] = set; 4313 } 4314 } else { 4315 h2c = (struct rtw89_fw_macid_pause_grp *)skb->data; 4316 4317 h2c->mask_grp[grp] = set; 4318 if (pause) 4319 h2c->pause_grp[grp] = set; 4320 } 4321 4322 rtw89_h2c_pkt_set_hdr(rtwdev, skb, FWCMD_TYPE_H2C, 4323 H2C_CAT_MAC, H2C_CL_MAC_FW_OFLD, 4324 h2c_macid_pause_id, 1, 0, 4325 len); 4326 4327 ret = rtw89_h2c_tx(rtwdev, skb, false); 4328 if (ret) { 4329 rtw89_err(rtwdev, "failed to send h2c\n"); 4330 goto fail; 4331 } 4332 4333 return 0; 4334 fail: 4335 dev_kfree_skb_any(skb); 4336 4337 return ret; 4338 } 4339 4340 #define H2C_EDCA_LEN 12 4341 int rtw89_fw_h2c_set_edca(struct rtw89_dev *rtwdev, struct rtw89_vif_link *rtwvif_link, 4342 u8 ac, u32 val) 4343 { 4344 struct sk_buff *skb; 4345 int ret; 4346 4347 skb = rtw89_fw_h2c_alloc_skb_with_hdr(rtwdev, H2C_EDCA_LEN); 4348 if (!skb) { 4349 rtw89_err(rtwdev, "failed to alloc skb for h2c edca\n"); 4350 return -ENOMEM; 4351 } 4352 skb_put(skb, H2C_EDCA_LEN); 4353 RTW89_SET_EDCA_SEL(skb->data, 0); 4354 RTW89_SET_EDCA_BAND(skb->data, rtwvif_link->mac_idx); 4355 RTW89_SET_EDCA_WMM(skb->data, 0); 4356 RTW89_SET_EDCA_AC(skb->data, ac); 4357 RTW89_SET_EDCA_PARAM(skb->data, val); 4358 4359 rtw89_h2c_pkt_set_hdr(rtwdev, skb, FWCMD_TYPE_H2C, 4360 H2C_CAT_MAC, H2C_CL_MAC_FW_OFLD, 4361 H2C_FUNC_USR_EDCA, 0, 1, 4362 H2C_EDCA_LEN); 4363 4364 ret = rtw89_h2c_tx(rtwdev, skb, false); 4365 if (ret) { 4366 rtw89_err(rtwdev, "failed to send h2c\n"); 4367 goto fail; 4368 } 4369 4370 return 0; 4371 fail: 4372 dev_kfree_skb_any(skb); 4373 4374 return ret; 4375 } 4376 4377 #define H2C_TSF32_TOGL_LEN 4 4378 int rtw89_fw_h2c_tsf32_toggle(struct rtw89_dev *rtwdev, 4379 struct rtw89_vif_link *rtwvif_link, 4380 bool en) 4381 { 4382 struct sk_buff *skb; 4383 u16 early_us = en ? 2000 : 0; 4384 u8 *cmd; 4385 int ret; 4386 4387 skb = rtw89_fw_h2c_alloc_skb_with_hdr(rtwdev, H2C_TSF32_TOGL_LEN); 4388 if (!skb) { 4389 rtw89_err(rtwdev, "failed to alloc skb for h2c p2p act\n"); 4390 return -ENOMEM; 4391 } 4392 skb_put(skb, H2C_TSF32_TOGL_LEN); 4393 cmd = skb->data; 4394 4395 RTW89_SET_FWCMD_TSF32_TOGL_BAND(cmd, rtwvif_link->mac_idx); 4396 RTW89_SET_FWCMD_TSF32_TOGL_EN(cmd, en); 4397 RTW89_SET_FWCMD_TSF32_TOGL_PORT(cmd, rtwvif_link->port); 4398 RTW89_SET_FWCMD_TSF32_TOGL_EARLY(cmd, early_us); 4399 4400 rtw89_h2c_pkt_set_hdr(rtwdev, skb, FWCMD_TYPE_H2C, 4401 H2C_CAT_MAC, H2C_CL_MAC_FW_OFLD, 4402 H2C_FUNC_TSF32_TOGL, 0, 0, 4403 H2C_TSF32_TOGL_LEN); 4404 4405 ret = rtw89_h2c_tx(rtwdev, skb, false); 4406 if (ret) { 4407 rtw89_err(rtwdev, "failed to send h2c\n"); 4408 goto fail; 4409 } 4410 4411 return 0; 4412 fail: 4413 dev_kfree_skb_any(skb); 4414 4415 return ret; 4416 } 4417 4418 #define H2C_OFLD_CFG_LEN 8 4419 int rtw89_fw_h2c_set_ofld_cfg(struct rtw89_dev *rtwdev) 4420 { 4421 static const u8 cfg[] = {0x09, 0x00, 0x00, 0x00, 0x5e, 0x00, 0x00, 0x00}; 4422 struct sk_buff *skb; 4423 int ret; 4424 4425 skb = rtw89_fw_h2c_alloc_skb_with_hdr(rtwdev, H2C_OFLD_CFG_LEN); 4426 if (!skb) { 4427 rtw89_err(rtwdev, "failed to alloc skb for h2c ofld\n"); 4428 return -ENOMEM; 4429 } 4430 skb_put_data(skb, cfg, H2C_OFLD_CFG_LEN); 4431 4432 rtw89_h2c_pkt_set_hdr(rtwdev, skb, FWCMD_TYPE_H2C, 4433 H2C_CAT_MAC, H2C_CL_MAC_FW_OFLD, 4434 H2C_FUNC_OFLD_CFG, 0, 1, 4435 H2C_OFLD_CFG_LEN); 4436 4437 ret = rtw89_h2c_tx(rtwdev, skb, false); 4438 if (ret) { 4439 rtw89_err(rtwdev, "failed to send h2c\n"); 4440 goto fail; 4441 } 4442 4443 return 0; 4444 fail: 4445 dev_kfree_skb_any(skb); 4446 4447 return ret; 4448 } 4449 4450 int rtw89_fw_h2c_tx_duty(struct rtw89_dev *rtwdev, u8 lv) 4451 { 4452 struct rtw89_h2c_tx_duty *h2c; 4453 u32 len = sizeof(*h2c); 4454 struct sk_buff *skb; 4455 u16 pause, active; 4456 int ret; 4457 4458 skb = rtw89_fw_h2c_alloc_skb_with_hdr(rtwdev, len); 4459 if (!skb) { 4460 rtw89_err(rtwdev, "failed to alloc skb for h2c tx duty\n"); 4461 return -ENOMEM; 4462 } 4463 4464 skb_put(skb, len); 4465 h2c = (struct rtw89_h2c_tx_duty *)skb->data; 4466 4467 static_assert(RTW89_THERMAL_PROT_LV_MAX * RTW89_THERMAL_PROT_STEP < 100); 4468 4469 if (lv == 0 || lv > RTW89_THERMAL_PROT_LV_MAX) { 4470 h2c->w1 = le32_encode_bits(1, RTW89_H2C_TX_DUTY_W1_STOP); 4471 } else { 4472 active = 100 - lv * RTW89_THERMAL_PROT_STEP; 4473 pause = 100 - active; 4474 4475 h2c->w0 = le32_encode_bits(pause, RTW89_H2C_TX_DUTY_W0_PAUSE_INTVL_MASK) | 4476 le32_encode_bits(active, RTW89_H2C_TX_DUTY_W0_TX_INTVL_MASK); 4477 } 4478 4479 rtw89_h2c_pkt_set_hdr(rtwdev, skb, FWCMD_TYPE_H2C, 4480 H2C_CAT_MAC, H2C_CL_MAC_FW_OFLD, 4481 H2C_FUNC_TX_DUTY, 0, 0, len); 4482 4483 ret = rtw89_h2c_tx(rtwdev, skb, false); 4484 if (ret) { 4485 rtw89_err(rtwdev, "failed to send h2c\n"); 4486 goto fail; 4487 } 4488 4489 return 0; 4490 fail: 4491 dev_kfree_skb_any(skb); 4492 4493 return ret; 4494 } 4495 4496 int rtw89_fw_h2c_set_bcn_fltr_cfg(struct rtw89_dev *rtwdev, 4497 struct rtw89_vif_link *rtwvif_link, 4498 bool connect) 4499 { 4500 struct ieee80211_bss_conf *bss_conf; 4501 s32 thold = RTW89_DEFAULT_CQM_THOLD; 4502 u32 hyst = RTW89_DEFAULT_CQM_HYST; 4503 struct rtw89_h2c_bcnfltr *h2c; 4504 u32 len = sizeof(*h2c); 4505 struct sk_buff *skb; 4506 u8 max_cnt, cnt; 4507 int ret; 4508 4509 if (!RTW89_CHK_FW_FEATURE(BEACON_FILTER, &rtwdev->fw)) 4510 return -EINVAL; 4511 4512 if (!rtwvif_link || rtwvif_link->net_type != RTW89_NET_TYPE_INFRA) 4513 return -EINVAL; 4514 4515 rcu_read_lock(); 4516 4517 bss_conf = rtw89_vif_rcu_dereference_link(rtwvif_link, false); 4518 4519 if (bss_conf->cqm_rssi_hyst) 4520 hyst = bss_conf->cqm_rssi_hyst; 4521 if (bss_conf->cqm_rssi_thold) 4522 thold = bss_conf->cqm_rssi_thold; 4523 4524 rcu_read_unlock(); 4525 4526 skb = rtw89_fw_h2c_alloc_skb_with_hdr(rtwdev, len); 4527 if (!skb) { 4528 rtw89_err(rtwdev, "failed to alloc skb for h2c bcn filter\n"); 4529 return -ENOMEM; 4530 } 4531 4532 skb_put(skb, len); 4533 h2c = (struct rtw89_h2c_bcnfltr *)skb->data; 4534 4535 if (RTW89_CHK_FW_FEATURE(BEACON_LOSS_COUNT_V1, &rtwdev->fw)) 4536 max_cnt = BIT(7) - 1; 4537 else 4538 max_cnt = BIT(4) - 1; 4539 4540 cnt = min(RTW89_BCN_LOSS_CNT, max_cnt); 4541 4542 h2c->w0 = le32_encode_bits(connect, RTW89_H2C_BCNFLTR_W0_MON_RSSI) | 4543 le32_encode_bits(connect, RTW89_H2C_BCNFLTR_W0_MON_BCN) | 4544 le32_encode_bits(connect, RTW89_H2C_BCNFLTR_W0_MON_EN) | 4545 le32_encode_bits(RTW89_BCN_FLTR_OFFLOAD_MODE_DEFAULT, 4546 RTW89_H2C_BCNFLTR_W0_MODE) | 4547 le32_encode_bits(cnt >> 4, RTW89_H2C_BCNFLTR_W0_BCN_LOSS_CNT_H3) | 4548 le32_encode_bits(cnt & 0xf, RTW89_H2C_BCNFLTR_W0_BCN_LOSS_CNT_L4) | 4549 le32_encode_bits(hyst, RTW89_H2C_BCNFLTR_W0_RSSI_HYST) | 4550 le32_encode_bits(thold + MAX_RSSI, 4551 RTW89_H2C_BCNFLTR_W0_RSSI_THRESHOLD) | 4552 le32_encode_bits(rtwvif_link->mac_id, RTW89_H2C_BCNFLTR_W0_MAC_ID); 4553 4554 rtw89_h2c_pkt_set_hdr(rtwdev, skb, FWCMD_TYPE_H2C, 4555 H2C_CAT_MAC, H2C_CL_MAC_FW_OFLD, 4556 H2C_FUNC_CFG_BCNFLTR, 0, 1, len); 4557 4558 ret = rtw89_h2c_tx(rtwdev, skb, false); 4559 if (ret) { 4560 rtw89_err(rtwdev, "failed to send h2c\n"); 4561 goto fail; 4562 } 4563 4564 return 0; 4565 fail: 4566 dev_kfree_skb_any(skb); 4567 4568 return ret; 4569 } 4570 4571 int rtw89_fw_h2c_rssi_offload(struct rtw89_dev *rtwdev, 4572 struct rtw89_rx_phy_ppdu *phy_ppdu) 4573 { 4574 struct rtw89_h2c_ofld_rssi *h2c; 4575 u32 len = sizeof(*h2c); 4576 struct sk_buff *skb; 4577 s8 rssi; 4578 int ret; 4579 4580 if (!RTW89_CHK_FW_FEATURE(BEACON_FILTER, &rtwdev->fw)) 4581 return -EINVAL; 4582 4583 if (!phy_ppdu) 4584 return -EINVAL; 4585 4586 skb = rtw89_fw_h2c_alloc_skb_with_hdr(rtwdev, len); 4587 if (!skb) { 4588 rtw89_err(rtwdev, "failed to alloc skb for h2c rssi\n"); 4589 return -ENOMEM; 4590 } 4591 4592 rssi = phy_ppdu->rssi_avg >> RSSI_FACTOR; 4593 skb_put(skb, len); 4594 h2c = (struct rtw89_h2c_ofld_rssi *)skb->data; 4595 4596 h2c->w0 = le32_encode_bits(phy_ppdu->mac_id, RTW89_H2C_OFLD_RSSI_W0_MACID) | 4597 le32_encode_bits(1, RTW89_H2C_OFLD_RSSI_W0_NUM); 4598 h2c->w1 = le32_encode_bits(rssi, RTW89_H2C_OFLD_RSSI_W1_VAL); 4599 4600 rtw89_h2c_pkt_set_hdr(rtwdev, skb, FWCMD_TYPE_H2C, 4601 H2C_CAT_MAC, H2C_CL_MAC_FW_OFLD, 4602 H2C_FUNC_OFLD_RSSI, 0, 1, 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 4617 int rtw89_fw_h2c_tp_offload(struct rtw89_dev *rtwdev, struct rtw89_vif_link *rtwvif_link) 4618 { 4619 struct rtw89_vif *rtwvif = rtwvif_link->rtwvif; 4620 struct rtw89_traffic_stats *stats = &rtwvif->stats; 4621 struct rtw89_h2c_ofld *h2c; 4622 u32 len = sizeof(*h2c); 4623 struct sk_buff *skb; 4624 int ret; 4625 4626 if (rtwvif_link->net_type != RTW89_NET_TYPE_INFRA) 4627 return -EINVAL; 4628 4629 skb = rtw89_fw_h2c_alloc_skb_with_hdr(rtwdev, len); 4630 if (!skb) { 4631 rtw89_err(rtwdev, "failed to alloc skb for h2c tp\n"); 4632 return -ENOMEM; 4633 } 4634 4635 skb_put(skb, len); 4636 h2c = (struct rtw89_h2c_ofld *)skb->data; 4637 4638 h2c->w0 = le32_encode_bits(rtwvif_link->mac_id, RTW89_H2C_OFLD_W0_MAC_ID) | 4639 le32_encode_bits(stats->tx_throughput, RTW89_H2C_OFLD_W0_TX_TP) | 4640 le32_encode_bits(stats->rx_throughput, RTW89_H2C_OFLD_W0_RX_TP); 4641 4642 rtw89_h2c_pkt_set_hdr(rtwdev, skb, FWCMD_TYPE_H2C, 4643 H2C_CAT_MAC, H2C_CL_MAC_FW_OFLD, 4644 H2C_FUNC_OFLD_TP, 0, 1, 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 4659 int rtw89_fw_h2c_ra(struct rtw89_dev *rtwdev, struct rtw89_ra_info *ra, bool csi) 4660 { 4661 const struct rtw89_chip_info *chip = rtwdev->chip; 4662 struct rtw89_h2c_ra_v1 *h2c_v1; 4663 struct rtw89_h2c_ra *h2c; 4664 u32 len = sizeof(*h2c); 4665 bool format_v1 = false; 4666 struct sk_buff *skb; 4667 int ret; 4668 4669 if (chip->chip_gen == RTW89_CHIP_BE) { 4670 len = sizeof(*h2c_v1); 4671 format_v1 = true; 4672 } 4673 4674 skb = rtw89_fw_h2c_alloc_skb_with_hdr(rtwdev, len); 4675 if (!skb) { 4676 rtw89_err(rtwdev, "failed to alloc skb for h2c join\n"); 4677 return -ENOMEM; 4678 } 4679 skb_put(skb, len); 4680 h2c = (struct rtw89_h2c_ra *)skb->data; 4681 rtw89_debug(rtwdev, RTW89_DBG_RA, 4682 #if defined(__linux__) 4683 "ra cmd msk: %llx ", ra->ra_mask); 4684 #elif defined(__FreeBSD__) 4685 "ra cmd msk: %jx ", (uintmax_t)ra->ra_mask); 4686 #endif 4687 4688 h2c->w0 = le32_encode_bits(ra->mode_ctrl, RTW89_H2C_RA_W0_MODE) | 4689 le32_encode_bits(ra->bw_cap, RTW89_H2C_RA_W0_BW_CAP) | 4690 le32_encode_bits(ra->macid, RTW89_H2C_RA_W0_MACID) | 4691 le32_encode_bits(ra->dcm_cap, RTW89_H2C_RA_W0_DCM) | 4692 le32_encode_bits(ra->er_cap, RTW89_H2C_RA_W0_ER) | 4693 le32_encode_bits(ra->init_rate_lv, RTW89_H2C_RA_W0_INIT_RATE_LV) | 4694 le32_encode_bits(ra->upd_all, RTW89_H2C_RA_W0_UPD_ALL) | 4695 le32_encode_bits(ra->en_sgi, RTW89_H2C_RA_W0_SGI) | 4696 le32_encode_bits(ra->ldpc_cap, RTW89_H2C_RA_W0_LDPC) | 4697 le32_encode_bits(ra->stbc_cap, RTW89_H2C_RA_W0_STBC) | 4698 le32_encode_bits(ra->ss_num, RTW89_H2C_RA_W0_SS_NUM) | 4699 le32_encode_bits(ra->giltf, RTW89_H2C_RA_W0_GILTF) | 4700 le32_encode_bits(ra->upd_bw_nss_mask, RTW89_H2C_RA_W0_UPD_BW_NSS_MASK) | 4701 le32_encode_bits(ra->upd_mask, RTW89_H2C_RA_W0_UPD_MASK); 4702 h2c->w1 = le32_encode_bits(ra->ra_mask, RTW89_H2C_RA_W1_RAMASK_LO32); 4703 h2c->w2 = le32_encode_bits(ra->ra_mask >> 32, RTW89_H2C_RA_W2_RAMASK_HI32); 4704 h2c->w3 = le32_encode_bits(ra->fix_giltf_en, RTW89_H2C_RA_W3_FIX_GILTF_EN) | 4705 le32_encode_bits(ra->fix_giltf, RTW89_H2C_RA_W3_FIX_GILTF); 4706 4707 if (!format_v1) 4708 goto csi; 4709 4710 h2c_v1 = (struct rtw89_h2c_ra_v1 *)h2c; 4711 h2c_v1->w4 = le32_encode_bits(ra->mode_ctrl, RTW89_H2C_RA_V1_W4_MODE_EHT) | 4712 le32_encode_bits(ra->bw_cap, RTW89_H2C_RA_V1_W4_BW_EHT); 4713 4714 csi: 4715 if (!csi) 4716 goto done; 4717 4718 h2c->w2 |= le32_encode_bits(1, RTW89_H2C_RA_W2_BFEE_CSI_CTL); 4719 h2c->w3 |= le32_encode_bits(ra->band_num, RTW89_H2C_RA_W3_BAND_NUM) | 4720 le32_encode_bits(ra->cr_tbl_sel, RTW89_H2C_RA_W3_CR_TBL_SEL) | 4721 le32_encode_bits(ra->fixed_csi_rate_en, RTW89_H2C_RA_W3_FIXED_CSI_RATE_EN) | 4722 le32_encode_bits(ra->ra_csi_rate_en, RTW89_H2C_RA_W3_RA_CSI_RATE_EN) | 4723 le32_encode_bits(ra->csi_mcs_ss_idx, RTW89_H2C_RA_W3_FIXED_CSI_MCS_SS_IDX) | 4724 le32_encode_bits(ra->csi_mode, RTW89_H2C_RA_W3_FIXED_CSI_MODE) | 4725 le32_encode_bits(ra->csi_gi_ltf, RTW89_H2C_RA_W3_FIXED_CSI_GI_LTF) | 4726 le32_encode_bits(ra->csi_bw, RTW89_H2C_RA_W3_FIXED_CSI_BW); 4727 4728 done: 4729 rtw89_h2c_pkt_set_hdr(rtwdev, skb, FWCMD_TYPE_H2C, 4730 H2C_CAT_OUTSRC, H2C_CL_OUTSRC_RA, 4731 H2C_FUNC_OUTSRC_RA_MACIDCFG, 0, 0, 4732 len); 4733 4734 ret = rtw89_h2c_tx(rtwdev, skb, false); 4735 if (ret) { 4736 rtw89_err(rtwdev, "failed to send h2c\n"); 4737 goto fail; 4738 } 4739 4740 return 0; 4741 fail: 4742 dev_kfree_skb_any(skb); 4743 4744 return ret; 4745 } 4746 4747 int rtw89_fw_h2c_cxdrv_init(struct rtw89_dev *rtwdev, u8 type) 4748 { 4749 struct rtw89_btc *btc = &rtwdev->btc; 4750 struct rtw89_btc_dm *dm = &btc->dm; 4751 struct rtw89_btc_init_info *init_info = &dm->init_info.init; 4752 struct rtw89_btc_module *module = &init_info->module; 4753 struct rtw89_btc_ant_info *ant = &module->ant; 4754 struct rtw89_h2c_cxinit *h2c; 4755 u32 len = sizeof(*h2c); 4756 struct sk_buff *skb; 4757 int ret; 4758 4759 skb = rtw89_fw_h2c_alloc_skb_with_hdr(rtwdev, len); 4760 if (!skb) { 4761 rtw89_err(rtwdev, "failed to alloc skb for h2c cxdrv_init\n"); 4762 return -ENOMEM; 4763 } 4764 skb_put(skb, len); 4765 h2c = (struct rtw89_h2c_cxinit *)skb->data; 4766 4767 h2c->hdr.type = type; 4768 h2c->hdr.len = len - H2C_LEN_CXDRVHDR; 4769 4770 h2c->ant_type = ant->type; 4771 h2c->ant_num = ant->num; 4772 h2c->ant_iso = ant->isolation; 4773 h2c->ant_info = 4774 u8_encode_bits(ant->single_pos, RTW89_H2C_CXINIT_ANT_INFO_POS) | 4775 u8_encode_bits(ant->diversity, RTW89_H2C_CXINIT_ANT_INFO_DIVERSITY) | 4776 u8_encode_bits(ant->btg_pos, RTW89_H2C_CXINIT_ANT_INFO_BTG_POS) | 4777 u8_encode_bits(ant->stream_cnt, RTW89_H2C_CXINIT_ANT_INFO_STREAM_CNT); 4778 4779 h2c->mod_rfe = module->rfe_type; 4780 h2c->mod_cv = module->cv; 4781 h2c->mod_info = 4782 u8_encode_bits(module->bt_solo, RTW89_H2C_CXINIT_MOD_INFO_BT_SOLO) | 4783 u8_encode_bits(module->bt_pos, RTW89_H2C_CXINIT_MOD_INFO_BT_POS) | 4784 u8_encode_bits(module->switch_type, RTW89_H2C_CXINIT_MOD_INFO_SW_TYPE) | 4785 u8_encode_bits(module->wa_type, RTW89_H2C_CXINIT_MOD_INFO_WA_TYPE); 4786 h2c->mod_adie_kt = module->kt_ver_adie; 4787 h2c->wl_gch = init_info->wl_guard_ch; 4788 4789 h2c->info = 4790 u8_encode_bits(init_info->wl_only, RTW89_H2C_CXINIT_INFO_WL_ONLY) | 4791 u8_encode_bits(init_info->wl_init_ok, RTW89_H2C_CXINIT_INFO_WL_INITOK) | 4792 u8_encode_bits(init_info->dbcc_en, RTW89_H2C_CXINIT_INFO_DBCC_EN) | 4793 u8_encode_bits(init_info->cx_other, RTW89_H2C_CXINIT_INFO_CX_OTHER) | 4794 u8_encode_bits(init_info->bt_only, RTW89_H2C_CXINIT_INFO_BT_ONLY); 4795 4796 rtw89_h2c_pkt_set_hdr(rtwdev, skb, FWCMD_TYPE_H2C, 4797 H2C_CAT_OUTSRC, BTFC_SET, 4798 SET_DRV_INFO, 0, 0, 4799 len); 4800 4801 ret = rtw89_h2c_tx(rtwdev, skb, false); 4802 if (ret) { 4803 rtw89_err(rtwdev, "failed to send h2c\n"); 4804 goto fail; 4805 } 4806 4807 return 0; 4808 fail: 4809 dev_kfree_skb_any(skb); 4810 4811 return ret; 4812 } 4813 4814 int rtw89_fw_h2c_cxdrv_init_v7(struct rtw89_dev *rtwdev, u8 type) 4815 { 4816 struct rtw89_btc *btc = &rtwdev->btc; 4817 struct rtw89_btc_dm *dm = &btc->dm; 4818 struct rtw89_btc_init_info_v7 *init_info = &dm->init_info.init_v7; 4819 struct rtw89_h2c_cxinit_v7 *h2c; 4820 u32 len = sizeof(*h2c); 4821 struct sk_buff *skb; 4822 int ret; 4823 4824 skb = rtw89_fw_h2c_alloc_skb_with_hdr(rtwdev, len); 4825 if (!skb) { 4826 rtw89_err(rtwdev, "failed to alloc skb for h2c cxdrv_init_v7\n"); 4827 return -ENOMEM; 4828 } 4829 skb_put(skb, len); 4830 h2c = (struct rtw89_h2c_cxinit_v7 *)skb->data; 4831 4832 h2c->hdr.type = type; 4833 h2c->hdr.ver = btc->ver->fcxinit; 4834 h2c->hdr.len = len - H2C_LEN_CXDRVHDR_V7; 4835 h2c->init = *init_info; 4836 4837 rtw89_h2c_pkt_set_hdr(rtwdev, skb, FWCMD_TYPE_H2C, 4838 H2C_CAT_OUTSRC, BTFC_SET, 4839 SET_DRV_INFO, 0, 0, 4840 len); 4841 4842 ret = rtw89_h2c_tx(rtwdev, skb, false); 4843 if (ret) { 4844 rtw89_err(rtwdev, "failed to send h2c\n"); 4845 goto fail; 4846 } 4847 4848 return 0; 4849 fail: 4850 dev_kfree_skb_any(skb); 4851 4852 return ret; 4853 } 4854 4855 #define PORT_DATA_OFFSET 4 4856 #define H2C_LEN_CXDRVINFO_ROLE_DBCC_LEN 12 4857 #define H2C_LEN_CXDRVINFO_ROLE_SIZE(max_role_num) \ 4858 (4 + 12 * (max_role_num) + H2C_LEN_CXDRVHDR) 4859 4860 int rtw89_fw_h2c_cxdrv_role(struct rtw89_dev *rtwdev, u8 type) 4861 { 4862 struct rtw89_btc *btc = &rtwdev->btc; 4863 const struct rtw89_btc_ver *ver = btc->ver; 4864 struct rtw89_btc_wl_info *wl = &btc->cx.wl; 4865 struct rtw89_btc_wl_role_info *role_info = &wl->role_info; 4866 struct rtw89_btc_wl_role_info_bpos *bpos = &role_info->role_map.role; 4867 struct rtw89_btc_wl_active_role *active = role_info->active_role; 4868 struct sk_buff *skb; 4869 u32 len; 4870 u8 offset = 0; 4871 u8 *cmd; 4872 int ret; 4873 int i; 4874 4875 len = H2C_LEN_CXDRVINFO_ROLE_SIZE(ver->max_role_num); 4876 4877 skb = rtw89_fw_h2c_alloc_skb_with_hdr(rtwdev, len); 4878 if (!skb) { 4879 rtw89_err(rtwdev, "failed to alloc skb for h2c cxdrv_role\n"); 4880 return -ENOMEM; 4881 } 4882 skb_put(skb, len); 4883 cmd = skb->data; 4884 4885 RTW89_SET_FWCMD_CXHDR_TYPE(cmd, type); 4886 RTW89_SET_FWCMD_CXHDR_LEN(cmd, len - H2C_LEN_CXDRVHDR); 4887 4888 RTW89_SET_FWCMD_CXROLE_CONNECT_CNT(cmd, role_info->connect_cnt); 4889 RTW89_SET_FWCMD_CXROLE_LINK_MODE(cmd, role_info->link_mode); 4890 4891 RTW89_SET_FWCMD_CXROLE_ROLE_NONE(cmd, bpos->none); 4892 RTW89_SET_FWCMD_CXROLE_ROLE_STA(cmd, bpos->station); 4893 RTW89_SET_FWCMD_CXROLE_ROLE_AP(cmd, bpos->ap); 4894 RTW89_SET_FWCMD_CXROLE_ROLE_VAP(cmd, bpos->vap); 4895 RTW89_SET_FWCMD_CXROLE_ROLE_ADHOC(cmd, bpos->adhoc); 4896 RTW89_SET_FWCMD_CXROLE_ROLE_ADHOC_MASTER(cmd, bpos->adhoc_master); 4897 RTW89_SET_FWCMD_CXROLE_ROLE_MESH(cmd, bpos->mesh); 4898 RTW89_SET_FWCMD_CXROLE_ROLE_MONITOR(cmd, bpos->moniter); 4899 RTW89_SET_FWCMD_CXROLE_ROLE_P2P_DEV(cmd, bpos->p2p_device); 4900 RTW89_SET_FWCMD_CXROLE_ROLE_P2P_GC(cmd, bpos->p2p_gc); 4901 RTW89_SET_FWCMD_CXROLE_ROLE_P2P_GO(cmd, bpos->p2p_go); 4902 RTW89_SET_FWCMD_CXROLE_ROLE_NAN(cmd, bpos->nan); 4903 4904 for (i = 0; i < RTW89_PORT_NUM; i++, active++) { 4905 RTW89_SET_FWCMD_CXROLE_ACT_CONNECTED(cmd, active->connected, i, offset); 4906 RTW89_SET_FWCMD_CXROLE_ACT_PID(cmd, active->pid, i, offset); 4907 RTW89_SET_FWCMD_CXROLE_ACT_PHY(cmd, active->phy, i, offset); 4908 RTW89_SET_FWCMD_CXROLE_ACT_NOA(cmd, active->noa, i, offset); 4909 RTW89_SET_FWCMD_CXROLE_ACT_BAND(cmd, active->band, i, offset); 4910 RTW89_SET_FWCMD_CXROLE_ACT_CLIENT_PS(cmd, active->client_ps, i, offset); 4911 RTW89_SET_FWCMD_CXROLE_ACT_BW(cmd, active->bw, i, offset); 4912 RTW89_SET_FWCMD_CXROLE_ACT_ROLE(cmd, active->role, i, offset); 4913 RTW89_SET_FWCMD_CXROLE_ACT_CH(cmd, active->ch, i, offset); 4914 RTW89_SET_FWCMD_CXROLE_ACT_TX_LVL(cmd, active->tx_lvl, i, offset); 4915 RTW89_SET_FWCMD_CXROLE_ACT_RX_LVL(cmd, active->rx_lvl, i, offset); 4916 RTW89_SET_FWCMD_CXROLE_ACT_TX_RATE(cmd, active->tx_rate, i, offset); 4917 RTW89_SET_FWCMD_CXROLE_ACT_RX_RATE(cmd, active->rx_rate, i, offset); 4918 } 4919 4920 rtw89_h2c_pkt_set_hdr(rtwdev, skb, FWCMD_TYPE_H2C, 4921 H2C_CAT_OUTSRC, BTFC_SET, 4922 SET_DRV_INFO, 0, 0, 4923 len); 4924 4925 ret = rtw89_h2c_tx(rtwdev, skb, false); 4926 if (ret) { 4927 rtw89_err(rtwdev, "failed to send h2c\n"); 4928 goto fail; 4929 } 4930 4931 return 0; 4932 fail: 4933 dev_kfree_skb_any(skb); 4934 4935 return ret; 4936 } 4937 4938 #define H2C_LEN_CXDRVINFO_ROLE_SIZE_V1(max_role_num) \ 4939 (4 + 16 * (max_role_num) + H2C_LEN_CXDRVINFO_ROLE_DBCC_LEN + H2C_LEN_CXDRVHDR) 4940 4941 int rtw89_fw_h2c_cxdrv_role_v1(struct rtw89_dev *rtwdev, u8 type) 4942 { 4943 struct rtw89_btc *btc = &rtwdev->btc; 4944 const struct rtw89_btc_ver *ver = btc->ver; 4945 struct rtw89_btc_wl_info *wl = &btc->cx.wl; 4946 struct rtw89_btc_wl_role_info_v1 *role_info = &wl->role_info_v1; 4947 struct rtw89_btc_wl_role_info_bpos *bpos = &role_info->role_map.role; 4948 struct rtw89_btc_wl_active_role_v1 *active = role_info->active_role_v1; 4949 struct sk_buff *skb; 4950 u32 len; 4951 u8 *cmd, offset; 4952 int ret; 4953 int i; 4954 4955 len = H2C_LEN_CXDRVINFO_ROLE_SIZE_V1(ver->max_role_num); 4956 4957 skb = rtw89_fw_h2c_alloc_skb_with_hdr(rtwdev, len); 4958 if (!skb) { 4959 rtw89_err(rtwdev, "failed to alloc skb for h2c cxdrv_role\n"); 4960 return -ENOMEM; 4961 } 4962 skb_put(skb, len); 4963 cmd = skb->data; 4964 4965 RTW89_SET_FWCMD_CXHDR_TYPE(cmd, type); 4966 RTW89_SET_FWCMD_CXHDR_LEN(cmd, len - H2C_LEN_CXDRVHDR); 4967 4968 RTW89_SET_FWCMD_CXROLE_CONNECT_CNT(cmd, role_info->connect_cnt); 4969 RTW89_SET_FWCMD_CXROLE_LINK_MODE(cmd, role_info->link_mode); 4970 4971 RTW89_SET_FWCMD_CXROLE_ROLE_NONE(cmd, bpos->none); 4972 RTW89_SET_FWCMD_CXROLE_ROLE_STA(cmd, bpos->station); 4973 RTW89_SET_FWCMD_CXROLE_ROLE_AP(cmd, bpos->ap); 4974 RTW89_SET_FWCMD_CXROLE_ROLE_VAP(cmd, bpos->vap); 4975 RTW89_SET_FWCMD_CXROLE_ROLE_ADHOC(cmd, bpos->adhoc); 4976 RTW89_SET_FWCMD_CXROLE_ROLE_ADHOC_MASTER(cmd, bpos->adhoc_master); 4977 RTW89_SET_FWCMD_CXROLE_ROLE_MESH(cmd, bpos->mesh); 4978 RTW89_SET_FWCMD_CXROLE_ROLE_MONITOR(cmd, bpos->moniter); 4979 RTW89_SET_FWCMD_CXROLE_ROLE_P2P_DEV(cmd, bpos->p2p_device); 4980 RTW89_SET_FWCMD_CXROLE_ROLE_P2P_GC(cmd, bpos->p2p_gc); 4981 RTW89_SET_FWCMD_CXROLE_ROLE_P2P_GO(cmd, bpos->p2p_go); 4982 RTW89_SET_FWCMD_CXROLE_ROLE_NAN(cmd, bpos->nan); 4983 4984 offset = PORT_DATA_OFFSET; 4985 for (i = 0; i < RTW89_PORT_NUM; i++, active++) { 4986 RTW89_SET_FWCMD_CXROLE_ACT_CONNECTED(cmd, active->connected, i, offset); 4987 RTW89_SET_FWCMD_CXROLE_ACT_PID(cmd, active->pid, i, offset); 4988 RTW89_SET_FWCMD_CXROLE_ACT_PHY(cmd, active->phy, i, offset); 4989 RTW89_SET_FWCMD_CXROLE_ACT_NOA(cmd, active->noa, i, offset); 4990 RTW89_SET_FWCMD_CXROLE_ACT_BAND(cmd, active->band, i, offset); 4991 RTW89_SET_FWCMD_CXROLE_ACT_CLIENT_PS(cmd, active->client_ps, i, offset); 4992 RTW89_SET_FWCMD_CXROLE_ACT_BW(cmd, active->bw, i, offset); 4993 RTW89_SET_FWCMD_CXROLE_ACT_ROLE(cmd, active->role, i, offset); 4994 RTW89_SET_FWCMD_CXROLE_ACT_CH(cmd, active->ch, i, offset); 4995 RTW89_SET_FWCMD_CXROLE_ACT_TX_LVL(cmd, active->tx_lvl, i, offset); 4996 RTW89_SET_FWCMD_CXROLE_ACT_RX_LVL(cmd, active->rx_lvl, i, offset); 4997 RTW89_SET_FWCMD_CXROLE_ACT_TX_RATE(cmd, active->tx_rate, i, offset); 4998 RTW89_SET_FWCMD_CXROLE_ACT_RX_RATE(cmd, active->rx_rate, i, offset); 4999 RTW89_SET_FWCMD_CXROLE_ACT_NOA_DUR(cmd, active->noa_duration, i, offset); 5000 } 5001 5002 offset = len - H2C_LEN_CXDRVINFO_ROLE_DBCC_LEN; 5003 RTW89_SET_FWCMD_CXROLE_MROLE_TYPE(cmd, role_info->mrole_type, offset); 5004 RTW89_SET_FWCMD_CXROLE_MROLE_NOA(cmd, role_info->mrole_noa_duration, offset); 5005 RTW89_SET_FWCMD_CXROLE_DBCC_EN(cmd, role_info->dbcc_en, offset); 5006 RTW89_SET_FWCMD_CXROLE_DBCC_CHG(cmd, role_info->dbcc_chg, offset); 5007 RTW89_SET_FWCMD_CXROLE_DBCC_2G_PHY(cmd, role_info->dbcc_2g_phy, offset); 5008 RTW89_SET_FWCMD_CXROLE_LINK_MODE_CHG(cmd, role_info->link_mode_chg, offset); 5009 5010 rtw89_h2c_pkt_set_hdr(rtwdev, skb, FWCMD_TYPE_H2C, 5011 H2C_CAT_OUTSRC, BTFC_SET, 5012 SET_DRV_INFO, 0, 0, 5013 len); 5014 5015 ret = rtw89_h2c_tx(rtwdev, skb, false); 5016 if (ret) { 5017 rtw89_err(rtwdev, "failed to send h2c\n"); 5018 goto fail; 5019 } 5020 5021 return 0; 5022 fail: 5023 dev_kfree_skb_any(skb); 5024 5025 return ret; 5026 } 5027 5028 #define H2C_LEN_CXDRVINFO_ROLE_SIZE_V2(max_role_num) \ 5029 (4 + 8 * (max_role_num) + H2C_LEN_CXDRVINFO_ROLE_DBCC_LEN + H2C_LEN_CXDRVHDR) 5030 5031 int rtw89_fw_h2c_cxdrv_role_v2(struct rtw89_dev *rtwdev, u8 type) 5032 { 5033 struct rtw89_btc *btc = &rtwdev->btc; 5034 const struct rtw89_btc_ver *ver = btc->ver; 5035 struct rtw89_btc_wl_info *wl = &btc->cx.wl; 5036 struct rtw89_btc_wl_role_info_v2 *role_info = &wl->role_info_v2; 5037 struct rtw89_btc_wl_role_info_bpos *bpos = &role_info->role_map.role; 5038 struct rtw89_btc_wl_active_role_v2 *active = role_info->active_role_v2; 5039 struct sk_buff *skb; 5040 u32 len; 5041 u8 *cmd, offset; 5042 int ret; 5043 int i; 5044 5045 len = H2C_LEN_CXDRVINFO_ROLE_SIZE_V2(ver->max_role_num); 5046 5047 skb = rtw89_fw_h2c_alloc_skb_with_hdr(rtwdev, len); 5048 if (!skb) { 5049 rtw89_err(rtwdev, "failed to alloc skb for h2c cxdrv_role\n"); 5050 return -ENOMEM; 5051 } 5052 skb_put(skb, len); 5053 cmd = skb->data; 5054 5055 RTW89_SET_FWCMD_CXHDR_TYPE(cmd, type); 5056 RTW89_SET_FWCMD_CXHDR_LEN(cmd, len - H2C_LEN_CXDRVHDR); 5057 5058 RTW89_SET_FWCMD_CXROLE_CONNECT_CNT(cmd, role_info->connect_cnt); 5059 RTW89_SET_FWCMD_CXROLE_LINK_MODE(cmd, role_info->link_mode); 5060 5061 RTW89_SET_FWCMD_CXROLE_ROLE_NONE(cmd, bpos->none); 5062 RTW89_SET_FWCMD_CXROLE_ROLE_STA(cmd, bpos->station); 5063 RTW89_SET_FWCMD_CXROLE_ROLE_AP(cmd, bpos->ap); 5064 RTW89_SET_FWCMD_CXROLE_ROLE_VAP(cmd, bpos->vap); 5065 RTW89_SET_FWCMD_CXROLE_ROLE_ADHOC(cmd, bpos->adhoc); 5066 RTW89_SET_FWCMD_CXROLE_ROLE_ADHOC_MASTER(cmd, bpos->adhoc_master); 5067 RTW89_SET_FWCMD_CXROLE_ROLE_MESH(cmd, bpos->mesh); 5068 RTW89_SET_FWCMD_CXROLE_ROLE_MONITOR(cmd, bpos->moniter); 5069 RTW89_SET_FWCMD_CXROLE_ROLE_P2P_DEV(cmd, bpos->p2p_device); 5070 RTW89_SET_FWCMD_CXROLE_ROLE_P2P_GC(cmd, bpos->p2p_gc); 5071 RTW89_SET_FWCMD_CXROLE_ROLE_P2P_GO(cmd, bpos->p2p_go); 5072 RTW89_SET_FWCMD_CXROLE_ROLE_NAN(cmd, bpos->nan); 5073 5074 offset = PORT_DATA_OFFSET; 5075 for (i = 0; i < RTW89_PORT_NUM; i++, active++) { 5076 RTW89_SET_FWCMD_CXROLE_ACT_CONNECTED_V2(cmd, active->connected, i, offset); 5077 RTW89_SET_FWCMD_CXROLE_ACT_PID_V2(cmd, active->pid, i, offset); 5078 RTW89_SET_FWCMD_CXROLE_ACT_PHY_V2(cmd, active->phy, i, offset); 5079 RTW89_SET_FWCMD_CXROLE_ACT_NOA_V2(cmd, active->noa, i, offset); 5080 RTW89_SET_FWCMD_CXROLE_ACT_BAND_V2(cmd, active->band, i, offset); 5081 RTW89_SET_FWCMD_CXROLE_ACT_CLIENT_PS_V2(cmd, active->client_ps, i, offset); 5082 RTW89_SET_FWCMD_CXROLE_ACT_BW_V2(cmd, active->bw, i, offset); 5083 RTW89_SET_FWCMD_CXROLE_ACT_ROLE_V2(cmd, active->role, i, offset); 5084 RTW89_SET_FWCMD_CXROLE_ACT_CH_V2(cmd, active->ch, i, offset); 5085 RTW89_SET_FWCMD_CXROLE_ACT_NOA_DUR_V2(cmd, active->noa_duration, i, offset); 5086 } 5087 5088 offset = len - H2C_LEN_CXDRVINFO_ROLE_DBCC_LEN; 5089 RTW89_SET_FWCMD_CXROLE_MROLE_TYPE(cmd, role_info->mrole_type, offset); 5090 RTW89_SET_FWCMD_CXROLE_MROLE_NOA(cmd, role_info->mrole_noa_duration, offset); 5091 RTW89_SET_FWCMD_CXROLE_DBCC_EN(cmd, role_info->dbcc_en, offset); 5092 RTW89_SET_FWCMD_CXROLE_DBCC_CHG(cmd, role_info->dbcc_chg, offset); 5093 RTW89_SET_FWCMD_CXROLE_DBCC_2G_PHY(cmd, role_info->dbcc_2g_phy, offset); 5094 RTW89_SET_FWCMD_CXROLE_LINK_MODE_CHG(cmd, role_info->link_mode_chg, offset); 5095 5096 rtw89_h2c_pkt_set_hdr(rtwdev, skb, FWCMD_TYPE_H2C, 5097 H2C_CAT_OUTSRC, BTFC_SET, 5098 SET_DRV_INFO, 0, 0, 5099 len); 5100 5101 ret = rtw89_h2c_tx(rtwdev, skb, false); 5102 if (ret) { 5103 rtw89_err(rtwdev, "failed to send h2c\n"); 5104 goto fail; 5105 } 5106 5107 return 0; 5108 fail: 5109 dev_kfree_skb_any(skb); 5110 5111 return ret; 5112 } 5113 5114 int rtw89_fw_h2c_cxdrv_role_v7(struct rtw89_dev *rtwdev, u8 type) 5115 { 5116 struct rtw89_btc *btc = &rtwdev->btc; 5117 struct rtw89_btc_wl_role_info_v7 *role = &btc->cx.wl.role_info_v7; 5118 struct rtw89_h2c_cxrole_v7 *h2c; 5119 u32 len = sizeof(*h2c); 5120 struct sk_buff *skb; 5121 int ret; 5122 5123 skb = rtw89_fw_h2c_alloc_skb_with_hdr(rtwdev, len); 5124 if (!skb) { 5125 rtw89_err(rtwdev, "failed to alloc skb for h2c cxdrv_ctrl\n"); 5126 return -ENOMEM; 5127 } 5128 skb_put(skb, len); 5129 h2c = (struct rtw89_h2c_cxrole_v7 *)skb->data; 5130 5131 h2c->hdr.type = type; 5132 h2c->hdr.ver = btc->ver->fwlrole; 5133 h2c->hdr.len = len - H2C_LEN_CXDRVHDR_V7; 5134 memcpy(&h2c->_u8, role, sizeof(h2c->_u8)); 5135 h2c->_u32.role_map = cpu_to_le32(role->role_map); 5136 h2c->_u32.mrole_type = cpu_to_le32(role->mrole_type); 5137 h2c->_u32.mrole_noa_duration = cpu_to_le32(role->mrole_noa_duration); 5138 h2c->_u32.dbcc_en = cpu_to_le32(role->dbcc_en); 5139 h2c->_u32.dbcc_chg = cpu_to_le32(role->dbcc_chg); 5140 h2c->_u32.dbcc_2g_phy = cpu_to_le32(role->dbcc_2g_phy); 5141 5142 rtw89_h2c_pkt_set_hdr(rtwdev, skb, FWCMD_TYPE_H2C, 5143 H2C_CAT_OUTSRC, BTFC_SET, 5144 SET_DRV_INFO, 0, 0, 5145 len); 5146 5147 ret = rtw89_h2c_tx(rtwdev, skb, false); 5148 if (ret) { 5149 rtw89_err(rtwdev, "failed to send h2c\n"); 5150 goto fail; 5151 } 5152 5153 return 0; 5154 fail: 5155 dev_kfree_skb_any(skb); 5156 5157 return ret; 5158 } 5159 5160 int rtw89_fw_h2c_cxdrv_role_v8(struct rtw89_dev *rtwdev, u8 type) 5161 { 5162 struct rtw89_btc *btc = &rtwdev->btc; 5163 struct rtw89_btc_wl_role_info_v8 *role = &btc->cx.wl.role_info_v8; 5164 struct rtw89_h2c_cxrole_v8 *h2c; 5165 u32 len = sizeof(*h2c); 5166 struct sk_buff *skb; 5167 int ret; 5168 5169 skb = rtw89_fw_h2c_alloc_skb_with_hdr(rtwdev, len); 5170 if (!skb) { 5171 rtw89_err(rtwdev, "failed to alloc skb for h2c cxdrv_ctrl\n"); 5172 return -ENOMEM; 5173 } 5174 skb_put(skb, len); 5175 h2c = (struct rtw89_h2c_cxrole_v8 *)skb->data; 5176 5177 h2c->hdr.type = type; 5178 h2c->hdr.ver = btc->ver->fwlrole; 5179 h2c->hdr.len = len - H2C_LEN_CXDRVHDR_V7; 5180 memcpy(&h2c->_u8, role, sizeof(h2c->_u8)); 5181 h2c->_u32.role_map = cpu_to_le32(role->role_map); 5182 h2c->_u32.mrole_type = cpu_to_le32(role->mrole_type); 5183 h2c->_u32.mrole_noa_duration = cpu_to_le32(role->mrole_noa_duration); 5184 5185 rtw89_h2c_pkt_set_hdr(rtwdev, skb, FWCMD_TYPE_H2C, 5186 H2C_CAT_OUTSRC, BTFC_SET, 5187 SET_DRV_INFO, 0, 0, 5188 len); 5189 5190 ret = rtw89_h2c_tx(rtwdev, skb, false); 5191 if (ret) { 5192 rtw89_err(rtwdev, "failed to send h2c\n"); 5193 goto fail; 5194 } 5195 5196 return 0; 5197 fail: 5198 dev_kfree_skb_any(skb); 5199 5200 return ret; 5201 } 5202 5203 int rtw89_fw_h2c_cxdrv_osi_info(struct rtw89_dev *rtwdev, u8 type) 5204 { 5205 struct rtw89_btc *btc = &rtwdev->btc; 5206 struct rtw89_btc_fbtc_outsrc_set_info *osi = &btc->dm.ost_info; 5207 struct rtw89_h2c_cxosi *h2c; 5208 u32 len = sizeof(*h2c); 5209 struct sk_buff *skb; 5210 int ret; 5211 5212 skb = rtw89_fw_h2c_alloc_skb_with_hdr(rtwdev, len); 5213 if (!skb) { 5214 rtw89_err(rtwdev, "failed to alloc skb for h2c cxdrv_osi\n"); 5215 return -ENOMEM; 5216 } 5217 skb_put(skb, len); 5218 h2c = (struct rtw89_h2c_cxosi *)skb->data; 5219 5220 h2c->hdr.type = type; 5221 h2c->hdr.ver = btc->ver->fcxosi; 5222 h2c->hdr.len = len - H2C_LEN_CXDRVHDR_V7; 5223 h2c->osi = *osi; 5224 5225 rtw89_h2c_pkt_set_hdr(rtwdev, skb, FWCMD_TYPE_H2C, 5226 H2C_CAT_OUTSRC, BTFC_SET, 5227 SET_DRV_INFO, 0, 0, 5228 len); 5229 5230 ret = rtw89_h2c_tx(rtwdev, skb, false); 5231 if (ret) { 5232 rtw89_err(rtwdev, "failed to send h2c\n"); 5233 goto fail; 5234 } 5235 5236 return 0; 5237 fail: 5238 dev_kfree_skb_any(skb); 5239 5240 return ret; 5241 } 5242 5243 #define H2C_LEN_CXDRVINFO_CTRL (4 + H2C_LEN_CXDRVHDR) 5244 int rtw89_fw_h2c_cxdrv_ctrl(struct rtw89_dev *rtwdev, u8 type) 5245 { 5246 struct rtw89_btc *btc = &rtwdev->btc; 5247 const struct rtw89_btc_ver *ver = btc->ver; 5248 struct rtw89_btc_ctrl *ctrl = &btc->ctrl.ctrl; 5249 struct sk_buff *skb; 5250 u8 *cmd; 5251 int ret; 5252 5253 skb = rtw89_fw_h2c_alloc_skb_with_hdr(rtwdev, H2C_LEN_CXDRVINFO_CTRL); 5254 if (!skb) { 5255 rtw89_err(rtwdev, "failed to alloc skb for h2c cxdrv_ctrl\n"); 5256 return -ENOMEM; 5257 } 5258 skb_put(skb, H2C_LEN_CXDRVINFO_CTRL); 5259 cmd = skb->data; 5260 5261 RTW89_SET_FWCMD_CXHDR_TYPE(cmd, type); 5262 RTW89_SET_FWCMD_CXHDR_LEN(cmd, H2C_LEN_CXDRVINFO_CTRL - H2C_LEN_CXDRVHDR); 5263 5264 RTW89_SET_FWCMD_CXCTRL_MANUAL(cmd, ctrl->manual); 5265 RTW89_SET_FWCMD_CXCTRL_IGNORE_BT(cmd, ctrl->igno_bt); 5266 RTW89_SET_FWCMD_CXCTRL_ALWAYS_FREERUN(cmd, ctrl->always_freerun); 5267 if (ver->fcxctrl == 0) 5268 RTW89_SET_FWCMD_CXCTRL_TRACE_STEP(cmd, ctrl->trace_step); 5269 5270 rtw89_h2c_pkt_set_hdr(rtwdev, skb, FWCMD_TYPE_H2C, 5271 H2C_CAT_OUTSRC, BTFC_SET, 5272 SET_DRV_INFO, 0, 0, 5273 H2C_LEN_CXDRVINFO_CTRL); 5274 5275 ret = rtw89_h2c_tx(rtwdev, skb, false); 5276 if (ret) { 5277 rtw89_err(rtwdev, "failed to send h2c\n"); 5278 goto fail; 5279 } 5280 5281 return 0; 5282 fail: 5283 dev_kfree_skb_any(skb); 5284 5285 return ret; 5286 } 5287 5288 int rtw89_fw_h2c_cxdrv_ctrl_v7(struct rtw89_dev *rtwdev, u8 type) 5289 { 5290 struct rtw89_btc *btc = &rtwdev->btc; 5291 struct rtw89_btc_ctrl_v7 *ctrl = &btc->ctrl.ctrl_v7; 5292 struct rtw89_h2c_cxctrl_v7 *h2c; 5293 u32 len = sizeof(*h2c); 5294 struct sk_buff *skb; 5295 int ret; 5296 5297 skb = rtw89_fw_h2c_alloc_skb_with_hdr(rtwdev, len); 5298 if (!skb) { 5299 rtw89_err(rtwdev, "failed to alloc skb for h2c cxdrv_ctrl_v7\n"); 5300 return -ENOMEM; 5301 } 5302 skb_put(skb, len); 5303 h2c = (struct rtw89_h2c_cxctrl_v7 *)skb->data; 5304 5305 h2c->hdr.type = type; 5306 h2c->hdr.ver = btc->ver->fcxctrl; 5307 h2c->hdr.len = sizeof(*h2c) - H2C_LEN_CXDRVHDR_V7; 5308 h2c->ctrl = *ctrl; 5309 5310 rtw89_h2c_pkt_set_hdr(rtwdev, skb, FWCMD_TYPE_H2C, 5311 H2C_CAT_OUTSRC, BTFC_SET, 5312 SET_DRV_INFO, 0, 0, len); 5313 5314 ret = rtw89_h2c_tx(rtwdev, skb, false); 5315 if (ret) { 5316 rtw89_err(rtwdev, "failed to send h2c\n"); 5317 goto fail; 5318 } 5319 5320 return 0; 5321 fail: 5322 dev_kfree_skb_any(skb); 5323 5324 return ret; 5325 } 5326 5327 #define H2C_LEN_CXDRVINFO_TRX (28 + H2C_LEN_CXDRVHDR) 5328 int rtw89_fw_h2c_cxdrv_trx(struct rtw89_dev *rtwdev, u8 type) 5329 { 5330 struct rtw89_btc *btc = &rtwdev->btc; 5331 struct rtw89_btc_trx_info *trx = &btc->dm.trx_info; 5332 struct sk_buff *skb; 5333 u8 *cmd; 5334 int ret; 5335 5336 skb = rtw89_fw_h2c_alloc_skb_with_hdr(rtwdev, H2C_LEN_CXDRVINFO_TRX); 5337 if (!skb) { 5338 rtw89_err(rtwdev, "failed to alloc skb for h2c cxdrv_trx\n"); 5339 return -ENOMEM; 5340 } 5341 skb_put(skb, H2C_LEN_CXDRVINFO_TRX); 5342 cmd = skb->data; 5343 5344 RTW89_SET_FWCMD_CXHDR_TYPE(cmd, type); 5345 RTW89_SET_FWCMD_CXHDR_LEN(cmd, H2C_LEN_CXDRVINFO_TRX - H2C_LEN_CXDRVHDR); 5346 5347 RTW89_SET_FWCMD_CXTRX_TXLV(cmd, trx->tx_lvl); 5348 RTW89_SET_FWCMD_CXTRX_RXLV(cmd, trx->rx_lvl); 5349 RTW89_SET_FWCMD_CXTRX_WLRSSI(cmd, trx->wl_rssi); 5350 RTW89_SET_FWCMD_CXTRX_BTRSSI(cmd, trx->bt_rssi); 5351 RTW89_SET_FWCMD_CXTRX_TXPWR(cmd, trx->tx_power); 5352 RTW89_SET_FWCMD_CXTRX_RXGAIN(cmd, trx->rx_gain); 5353 RTW89_SET_FWCMD_CXTRX_BTTXPWR(cmd, trx->bt_tx_power); 5354 RTW89_SET_FWCMD_CXTRX_BTRXGAIN(cmd, trx->bt_rx_gain); 5355 RTW89_SET_FWCMD_CXTRX_CN(cmd, trx->cn); 5356 RTW89_SET_FWCMD_CXTRX_NHM(cmd, trx->nhm); 5357 RTW89_SET_FWCMD_CXTRX_BTPROFILE(cmd, trx->bt_profile); 5358 RTW89_SET_FWCMD_CXTRX_RSVD2(cmd, trx->rsvd2); 5359 RTW89_SET_FWCMD_CXTRX_TXRATE(cmd, trx->tx_rate); 5360 RTW89_SET_FWCMD_CXTRX_RXRATE(cmd, trx->rx_rate); 5361 RTW89_SET_FWCMD_CXTRX_TXTP(cmd, trx->tx_tp); 5362 RTW89_SET_FWCMD_CXTRX_RXTP(cmd, trx->rx_tp); 5363 RTW89_SET_FWCMD_CXTRX_RXERRRA(cmd, trx->rx_err_ratio); 5364 5365 rtw89_h2c_pkt_set_hdr(rtwdev, skb, FWCMD_TYPE_H2C, 5366 H2C_CAT_OUTSRC, BTFC_SET, 5367 SET_DRV_INFO, 0, 0, 5368 H2C_LEN_CXDRVINFO_TRX); 5369 5370 ret = rtw89_h2c_tx(rtwdev, skb, false); 5371 if (ret) { 5372 rtw89_err(rtwdev, "failed to send h2c\n"); 5373 goto fail; 5374 } 5375 5376 return 0; 5377 fail: 5378 dev_kfree_skb_any(skb); 5379 5380 return ret; 5381 } 5382 5383 #define H2C_LEN_CXDRVINFO_RFK (4 + H2C_LEN_CXDRVHDR) 5384 int rtw89_fw_h2c_cxdrv_rfk(struct rtw89_dev *rtwdev, u8 type) 5385 { 5386 struct rtw89_btc *btc = &rtwdev->btc; 5387 struct rtw89_btc_wl_info *wl = &btc->cx.wl; 5388 struct rtw89_btc_wl_rfk_info *rfk_info = &wl->rfk_info; 5389 struct sk_buff *skb; 5390 u8 *cmd; 5391 int ret; 5392 5393 skb = rtw89_fw_h2c_alloc_skb_with_hdr(rtwdev, H2C_LEN_CXDRVINFO_RFK); 5394 if (!skb) { 5395 rtw89_err(rtwdev, "failed to alloc skb for h2c cxdrv_ctrl\n"); 5396 return -ENOMEM; 5397 } 5398 skb_put(skb, H2C_LEN_CXDRVINFO_RFK); 5399 cmd = skb->data; 5400 5401 RTW89_SET_FWCMD_CXHDR_TYPE(cmd, type); 5402 RTW89_SET_FWCMD_CXHDR_LEN(cmd, H2C_LEN_CXDRVINFO_RFK - H2C_LEN_CXDRVHDR); 5403 5404 RTW89_SET_FWCMD_CXRFK_STATE(cmd, rfk_info->state); 5405 RTW89_SET_FWCMD_CXRFK_PATH_MAP(cmd, rfk_info->path_map); 5406 RTW89_SET_FWCMD_CXRFK_PHY_MAP(cmd, rfk_info->phy_map); 5407 RTW89_SET_FWCMD_CXRFK_BAND(cmd, rfk_info->band); 5408 RTW89_SET_FWCMD_CXRFK_TYPE(cmd, rfk_info->type); 5409 5410 rtw89_h2c_pkt_set_hdr(rtwdev, skb, FWCMD_TYPE_H2C, 5411 H2C_CAT_OUTSRC, BTFC_SET, 5412 SET_DRV_INFO, 0, 0, 5413 H2C_LEN_CXDRVINFO_RFK); 5414 5415 ret = rtw89_h2c_tx(rtwdev, skb, false); 5416 if (ret) { 5417 rtw89_err(rtwdev, "failed to send h2c\n"); 5418 goto fail; 5419 } 5420 5421 return 0; 5422 fail: 5423 dev_kfree_skb_any(skb); 5424 5425 return ret; 5426 } 5427 5428 #define H2C_LEN_PKT_OFLD 4 5429 int rtw89_fw_h2c_del_pkt_offload(struct rtw89_dev *rtwdev, u8 id) 5430 { 5431 struct rtw89_wait_info *wait = &rtwdev->mac.fw_ofld_wait; 5432 struct sk_buff *skb; 5433 unsigned int cond; 5434 u8 *cmd; 5435 int ret; 5436 5437 skb = rtw89_fw_h2c_alloc_skb_with_hdr(rtwdev, H2C_LEN_PKT_OFLD); 5438 if (!skb) { 5439 rtw89_err(rtwdev, "failed to alloc skb for h2c pkt offload\n"); 5440 return -ENOMEM; 5441 } 5442 skb_put(skb, H2C_LEN_PKT_OFLD); 5443 cmd = skb->data; 5444 5445 RTW89_SET_FWCMD_PACKET_OFLD_PKT_IDX(cmd, id); 5446 RTW89_SET_FWCMD_PACKET_OFLD_PKT_OP(cmd, RTW89_PKT_OFLD_OP_DEL); 5447 5448 rtw89_h2c_pkt_set_hdr(rtwdev, skb, FWCMD_TYPE_H2C, 5449 H2C_CAT_MAC, H2C_CL_MAC_FW_OFLD, 5450 H2C_FUNC_PACKET_OFLD, 1, 1, 5451 H2C_LEN_PKT_OFLD); 5452 5453 cond = RTW89_FW_OFLD_WAIT_COND_PKT_OFLD(id, RTW89_PKT_OFLD_OP_DEL); 5454 5455 ret = rtw89_h2c_tx_and_wait(rtwdev, skb, wait, cond); 5456 if (ret < 0) { 5457 rtw89_debug(rtwdev, RTW89_DBG_FW, 5458 "failed to del pkt ofld: id %d, ret %d\n", 5459 id, ret); 5460 return ret; 5461 } 5462 5463 rtw89_core_release_bit_map(rtwdev->pkt_offload, id); 5464 return 0; 5465 } 5466 5467 int rtw89_fw_h2c_add_pkt_offload(struct rtw89_dev *rtwdev, u8 *id, 5468 struct sk_buff *skb_ofld) 5469 { 5470 struct rtw89_wait_info *wait = &rtwdev->mac.fw_ofld_wait; 5471 struct sk_buff *skb; 5472 unsigned int cond; 5473 u8 *cmd; 5474 u8 alloc_id; 5475 int ret; 5476 5477 alloc_id = rtw89_core_acquire_bit_map(rtwdev->pkt_offload, 5478 RTW89_MAX_PKT_OFLD_NUM); 5479 if (alloc_id == RTW89_MAX_PKT_OFLD_NUM) 5480 return -ENOSPC; 5481 5482 *id = alloc_id; 5483 5484 skb = rtw89_fw_h2c_alloc_skb_with_hdr(rtwdev, H2C_LEN_PKT_OFLD + skb_ofld->len); 5485 if (!skb) { 5486 rtw89_err(rtwdev, "failed to alloc skb for h2c pkt offload\n"); 5487 rtw89_core_release_bit_map(rtwdev->pkt_offload, alloc_id); 5488 return -ENOMEM; 5489 } 5490 skb_put(skb, H2C_LEN_PKT_OFLD); 5491 cmd = skb->data; 5492 5493 RTW89_SET_FWCMD_PACKET_OFLD_PKT_IDX(cmd, alloc_id); 5494 RTW89_SET_FWCMD_PACKET_OFLD_PKT_OP(cmd, RTW89_PKT_OFLD_OP_ADD); 5495 RTW89_SET_FWCMD_PACKET_OFLD_PKT_LENGTH(cmd, skb_ofld->len); 5496 skb_put_data(skb, skb_ofld->data, skb_ofld->len); 5497 5498 rtw89_h2c_pkt_set_hdr(rtwdev, skb, FWCMD_TYPE_H2C, 5499 H2C_CAT_MAC, H2C_CL_MAC_FW_OFLD, 5500 H2C_FUNC_PACKET_OFLD, 1, 1, 5501 H2C_LEN_PKT_OFLD + skb_ofld->len); 5502 5503 cond = RTW89_FW_OFLD_WAIT_COND_PKT_OFLD(alloc_id, RTW89_PKT_OFLD_OP_ADD); 5504 5505 ret = rtw89_h2c_tx_and_wait(rtwdev, skb, wait, cond); 5506 if (ret < 0) { 5507 rtw89_debug(rtwdev, RTW89_DBG_FW, 5508 "failed to add pkt ofld: id %d, ret %d\n", 5509 alloc_id, ret); 5510 rtw89_core_release_bit_map(rtwdev->pkt_offload, alloc_id); 5511 return ret; 5512 } 5513 5514 return 0; 5515 } 5516 5517 static 5518 int rtw89_fw_h2c_scan_list_offload_ax(struct rtw89_dev *rtwdev, int ch_num, 5519 struct list_head *chan_list) 5520 { 5521 struct rtw89_hw_scan_info *scan_info = &rtwdev->scan_info; 5522 struct rtw89_wait_info *wait = &rtwdev->mac.fw_ofld_wait; 5523 struct rtw89_h2c_chinfo_elem *elem; 5524 struct rtw89_mac_chinfo_ax *ch_info; 5525 struct rtw89_h2c_chinfo *h2c; 5526 struct sk_buff *skb; 5527 unsigned int cond; 5528 int skb_len; 5529 int ret; 5530 5531 static_assert(sizeof(*elem) == RTW89_MAC_CHINFO_SIZE); 5532 5533 skb_len = struct_size(h2c, elem, ch_num); 5534 skb = rtw89_fw_h2c_alloc_skb_with_hdr(rtwdev, skb_len); 5535 if (!skb) { 5536 rtw89_err(rtwdev, "failed to alloc skb for h2c scan list\n"); 5537 return -ENOMEM; 5538 } 5539 skb_put(skb, sizeof(*h2c)); 5540 h2c = (struct rtw89_h2c_chinfo *)skb->data; 5541 5542 h2c->ch_num = ch_num; 5543 h2c->elem_size = sizeof(*elem) / 4; /* in unit of 4 bytes */ 5544 5545 list_for_each_entry(ch_info, chan_list, list) { 5546 elem = (struct rtw89_h2c_chinfo_elem *)skb_put(skb, sizeof(*elem)); 5547 5548 elem->w0 = le32_encode_bits(ch_info->period, RTW89_H2C_CHINFO_W0_PERIOD) | 5549 le32_encode_bits(ch_info->dwell_time, RTW89_H2C_CHINFO_W0_DWELL) | 5550 le32_encode_bits(ch_info->central_ch, RTW89_H2C_CHINFO_W0_CENTER_CH) | 5551 le32_encode_bits(ch_info->pri_ch, RTW89_H2C_CHINFO_W0_PRI_CH); 5552 5553 elem->w1 = le32_encode_bits(ch_info->bw, RTW89_H2C_CHINFO_W1_BW) | 5554 le32_encode_bits(ch_info->notify_action, RTW89_H2C_CHINFO_W1_ACTION) | 5555 le32_encode_bits(ch_info->num_pkt, RTW89_H2C_CHINFO_W1_NUM_PKT) | 5556 le32_encode_bits(ch_info->tx_pkt, RTW89_H2C_CHINFO_W1_TX) | 5557 le32_encode_bits(ch_info->pause_data, RTW89_H2C_CHINFO_W1_PAUSE_DATA) | 5558 le32_encode_bits(ch_info->ch_band, RTW89_H2C_CHINFO_W1_BAND) | 5559 le32_encode_bits(ch_info->probe_id, RTW89_H2C_CHINFO_W1_PKT_ID) | 5560 le32_encode_bits(ch_info->dfs_ch, RTW89_H2C_CHINFO_W1_DFS) | 5561 le32_encode_bits(ch_info->tx_null, RTW89_H2C_CHINFO_W1_TX_NULL) | 5562 le32_encode_bits(ch_info->rand_seq_num, RTW89_H2C_CHINFO_W1_RANDOM); 5563 5564 if (scan_info->extra_op.set) 5565 elem->w1 |= le32_encode_bits(ch_info->macid_tx, 5566 RTW89_H2C_CHINFO_W1_MACID_TX); 5567 5568 elem->w2 = le32_encode_bits(ch_info->pkt_id[0], RTW89_H2C_CHINFO_W2_PKT0) | 5569 le32_encode_bits(ch_info->pkt_id[1], RTW89_H2C_CHINFO_W2_PKT1) | 5570 le32_encode_bits(ch_info->pkt_id[2], RTW89_H2C_CHINFO_W2_PKT2) | 5571 le32_encode_bits(ch_info->pkt_id[3], RTW89_H2C_CHINFO_W2_PKT3); 5572 5573 elem->w3 = le32_encode_bits(ch_info->pkt_id[4], RTW89_H2C_CHINFO_W3_PKT4) | 5574 le32_encode_bits(ch_info->pkt_id[5], RTW89_H2C_CHINFO_W3_PKT5) | 5575 le32_encode_bits(ch_info->pkt_id[6], RTW89_H2C_CHINFO_W3_PKT6) | 5576 le32_encode_bits(ch_info->pkt_id[7], RTW89_H2C_CHINFO_W3_PKT7); 5577 } 5578 5579 rtw89_h2c_pkt_set_hdr(rtwdev, skb, FWCMD_TYPE_H2C, 5580 H2C_CAT_MAC, H2C_CL_MAC_FW_OFLD, 5581 H2C_FUNC_ADD_SCANOFLD_CH, 1, 1, skb_len); 5582 5583 cond = RTW89_SCANOFLD_WAIT_COND_ADD_CH; 5584 5585 ret = rtw89_h2c_tx_and_wait(rtwdev, skb, wait, cond); 5586 if (ret) { 5587 rtw89_debug(rtwdev, RTW89_DBG_FW, "failed to add scan ofld ch\n"); 5588 return ret; 5589 } 5590 5591 return 0; 5592 } 5593 5594 static 5595 int rtw89_fw_h2c_scan_list_offload_be(struct rtw89_dev *rtwdev, int ch_num, 5596 struct list_head *chan_list, 5597 struct rtw89_vif_link *rtwvif_link) 5598 { 5599 struct rtw89_wait_info *wait = &rtwdev->mac.fw_ofld_wait; 5600 struct rtw89_h2c_chinfo_elem_be *elem; 5601 struct rtw89_mac_chinfo_be *ch_info; 5602 struct rtw89_h2c_chinfo_be *h2c; 5603 struct sk_buff *skb; 5604 unsigned int cond; 5605 u8 ver = U8_MAX; 5606 int skb_len; 5607 int ret; 5608 5609 static_assert(sizeof(*elem) == RTW89_MAC_CHINFO_SIZE_BE); 5610 5611 skb_len = struct_size(h2c, elem, ch_num); 5612 skb = rtw89_fw_h2c_alloc_skb_with_hdr(rtwdev, skb_len); 5613 if (!skb) { 5614 rtw89_err(rtwdev, "failed to alloc skb for h2c scan list\n"); 5615 return -ENOMEM; 5616 } 5617 5618 if (RTW89_CHK_FW_FEATURE(CH_INFO_BE_V0, &rtwdev->fw)) 5619 ver = 0; 5620 5621 skb_put(skb, sizeof(*h2c)); 5622 h2c = (struct rtw89_h2c_chinfo_be *)skb->data; 5623 5624 h2c->ch_num = ch_num; 5625 h2c->elem_size = sizeof(*elem) / 4; /* in unit of 4 bytes */ 5626 h2c->arg = u8_encode_bits(rtwvif_link->mac_idx, 5627 RTW89_H2C_CHINFO_ARG_MAC_IDX_MASK); 5628 5629 list_for_each_entry(ch_info, chan_list, list) { 5630 elem = (struct rtw89_h2c_chinfo_elem_be *)skb_put(skb, sizeof(*elem)); 5631 5632 elem->w0 = le32_encode_bits(ch_info->dwell_time, RTW89_H2C_CHINFO_BE_W0_DWELL) | 5633 le32_encode_bits(ch_info->central_ch, 5634 RTW89_H2C_CHINFO_BE_W0_CENTER_CH) | 5635 le32_encode_bits(ch_info->pri_ch, RTW89_H2C_CHINFO_BE_W0_PRI_CH); 5636 5637 elem->w1 = le32_encode_bits(ch_info->bw, RTW89_H2C_CHINFO_BE_W1_BW) | 5638 le32_encode_bits(ch_info->ch_band, RTW89_H2C_CHINFO_BE_W1_CH_BAND) | 5639 le32_encode_bits(ch_info->dfs_ch, RTW89_H2C_CHINFO_BE_W1_DFS) | 5640 le32_encode_bits(ch_info->pause_data, 5641 RTW89_H2C_CHINFO_BE_W1_PAUSE_DATA) | 5642 le32_encode_bits(ch_info->tx_null, RTW89_H2C_CHINFO_BE_W1_TX_NULL) | 5643 le32_encode_bits(ch_info->rand_seq_num, 5644 RTW89_H2C_CHINFO_BE_W1_RANDOM) | 5645 le32_encode_bits(ch_info->notify_action, 5646 RTW89_H2C_CHINFO_BE_W1_NOTIFY) | 5647 le32_encode_bits(ch_info->probe_id != 0xff ? 1 : 0, 5648 RTW89_H2C_CHINFO_BE_W1_PROBE) | 5649 le32_encode_bits(ch_info->leave_crit, 5650 RTW89_H2C_CHINFO_BE_W1_EARLY_LEAVE_CRIT) | 5651 le32_encode_bits(ch_info->chkpt_timer, 5652 RTW89_H2C_CHINFO_BE_W1_CHKPT_TIMER); 5653 5654 elem->w2 = le32_encode_bits(ch_info->leave_time, 5655 RTW89_H2C_CHINFO_BE_W2_EARLY_LEAVE_TIME) | 5656 le32_encode_bits(ch_info->leave_th, 5657 RTW89_H2C_CHINFO_BE_W2_EARLY_LEAVE_TH) | 5658 le32_encode_bits(ch_info->tx_pkt_ctrl, 5659 RTW89_H2C_CHINFO_BE_W2_TX_PKT_CTRL); 5660 5661 elem->w3 = le32_encode_bits(ch_info->pkt_id[0], RTW89_H2C_CHINFO_BE_W3_PKT0) | 5662 le32_encode_bits(ch_info->pkt_id[1], RTW89_H2C_CHINFO_BE_W3_PKT1) | 5663 le32_encode_bits(ch_info->pkt_id[2], RTW89_H2C_CHINFO_BE_W3_PKT2) | 5664 le32_encode_bits(ch_info->pkt_id[3], RTW89_H2C_CHINFO_BE_W3_PKT3); 5665 5666 elem->w4 = le32_encode_bits(ch_info->pkt_id[4], RTW89_H2C_CHINFO_BE_W4_PKT4) | 5667 le32_encode_bits(ch_info->pkt_id[5], RTW89_H2C_CHINFO_BE_W4_PKT5) | 5668 le32_encode_bits(ch_info->pkt_id[6], RTW89_H2C_CHINFO_BE_W4_PKT6) | 5669 le32_encode_bits(ch_info->pkt_id[7], RTW89_H2C_CHINFO_BE_W4_PKT7); 5670 5671 elem->w5 = le32_encode_bits(ch_info->sw_def, RTW89_H2C_CHINFO_BE_W5_SW_DEF) | 5672 le32_encode_bits(ch_info->fw_probe0_ssids, 5673 RTW89_H2C_CHINFO_BE_W5_FW_PROBE0_SSIDS); 5674 5675 elem->w6 = le32_encode_bits(ch_info->fw_probe0_shortssids, 5676 RTW89_H2C_CHINFO_BE_W6_FW_PROBE0_SHORTSSIDS) | 5677 le32_encode_bits(ch_info->fw_probe0_bssids, 5678 RTW89_H2C_CHINFO_BE_W6_FW_PROBE0_BSSIDS); 5679 if (ver == 0) 5680 elem->w0 |= 5681 le32_encode_bits(ch_info->period, RTW89_H2C_CHINFO_BE_W0_PERIOD); 5682 else 5683 elem->w7 = le32_encode_bits(ch_info->period, 5684 RTW89_H2C_CHINFO_BE_W7_PERIOD_V1); 5685 } 5686 5687 rtw89_h2c_pkt_set_hdr(rtwdev, skb, FWCMD_TYPE_H2C, 5688 H2C_CAT_MAC, H2C_CL_MAC_FW_OFLD, 5689 H2C_FUNC_ADD_SCANOFLD_CH, 1, 1, skb_len); 5690 5691 cond = RTW89_SCANOFLD_WAIT_COND_ADD_CH; 5692 5693 ret = rtw89_h2c_tx_and_wait(rtwdev, skb, wait, cond); 5694 if (ret) { 5695 rtw89_debug(rtwdev, RTW89_DBG_FW, "failed to add scan ofld ch\n"); 5696 return ret; 5697 } 5698 5699 return 0; 5700 } 5701 5702 int rtw89_fw_h2c_scan_offload_ax(struct rtw89_dev *rtwdev, 5703 struct rtw89_scan_option *option, 5704 struct rtw89_vif_link *rtwvif_link, 5705 bool wowlan) 5706 { 5707 struct rtw89_hw_scan_info *scan_info = &rtwdev->scan_info; 5708 struct rtw89_wait_info *wait = &rtwdev->mac.fw_ofld_wait; 5709 struct rtw89_chan *op = &rtwdev->scan_info.op_chan; 5710 enum rtw89_scan_mode scan_mode = RTW89_SCAN_IMMEDIATE; 5711 struct rtw89_h2c_scanofld *h2c; 5712 u32 len = sizeof(*h2c); 5713 struct sk_buff *skb; 5714 unsigned int cond; 5715 u64 tsf = 0; 5716 int ret; 5717 5718 skb = rtw89_fw_h2c_alloc_skb_with_hdr(rtwdev, len); 5719 if (!skb) { 5720 rtw89_err(rtwdev, "failed to alloc skb for h2c scan offload\n"); 5721 return -ENOMEM; 5722 } 5723 skb_put(skb, len); 5724 h2c = (struct rtw89_h2c_scanofld *)skb->data; 5725 5726 if (option->delay) { 5727 ret = rtw89_mac_port_get_tsf(rtwdev, rtwvif_link, &tsf); 5728 if (ret) { 5729 rtw89_warn(rtwdev, "NLO failed to get port tsf: %d\n", ret); 5730 scan_mode = RTW89_SCAN_IMMEDIATE; 5731 } else { 5732 scan_mode = RTW89_SCAN_DELAY; 5733 tsf += (u64)option->delay * 1000; 5734 } 5735 } 5736 5737 h2c->w0 = le32_encode_bits(rtwvif_link->mac_id, RTW89_H2C_SCANOFLD_W0_MACID) | 5738 le32_encode_bits(rtwvif_link->port, RTW89_H2C_SCANOFLD_W0_PORT_ID) | 5739 le32_encode_bits(rtwvif_link->mac_idx, RTW89_H2C_SCANOFLD_W0_BAND) | 5740 le32_encode_bits(option->enable, RTW89_H2C_SCANOFLD_W0_OPERATION); 5741 5742 h2c->w1 = le32_encode_bits(true, RTW89_H2C_SCANOFLD_W1_NOTIFY_END) | 5743 le32_encode_bits(option->target_ch_mode, 5744 RTW89_H2C_SCANOFLD_W1_TARGET_CH_MODE) | 5745 le32_encode_bits(scan_mode, RTW89_H2C_SCANOFLD_W1_START_MODE) | 5746 le32_encode_bits(option->repeat, RTW89_H2C_SCANOFLD_W1_SCAN_TYPE); 5747 5748 h2c->w2 = le32_encode_bits(option->norm_pd, RTW89_H2C_SCANOFLD_W2_NORM_PD) | 5749 le32_encode_bits(option->slow_pd, RTW89_H2C_SCANOFLD_W2_SLOW_PD); 5750 5751 if (option->target_ch_mode) { 5752 h2c->w1 |= le32_encode_bits(op->band_width, 5753 RTW89_H2C_SCANOFLD_W1_TARGET_CH_BW) | 5754 le32_encode_bits(op->primary_channel, 5755 RTW89_H2C_SCANOFLD_W1_TARGET_PRI_CH) | 5756 le32_encode_bits(op->channel, 5757 RTW89_H2C_SCANOFLD_W1_TARGET_CENTRAL_CH); 5758 h2c->w0 |= le32_encode_bits(op->band_type, 5759 RTW89_H2C_SCANOFLD_W0_TARGET_CH_BAND); 5760 } 5761 5762 h2c->tsf_high = le32_encode_bits(upper_32_bits(tsf), 5763 RTW89_H2C_SCANOFLD_W3_TSF_HIGH); 5764 h2c->tsf_low = le32_encode_bits(lower_32_bits(tsf), 5765 RTW89_H2C_SCANOFLD_W4_TSF_LOW); 5766 5767 if (scan_info->extra_op.set) 5768 h2c->w6 = le32_encode_bits(scan_info->extra_op.macid, 5769 RTW89_H2C_SCANOFLD_W6_SECOND_MACID); 5770 5771 rtw89_h2c_pkt_set_hdr(rtwdev, skb, FWCMD_TYPE_H2C, 5772 H2C_CAT_MAC, H2C_CL_MAC_FW_OFLD, 5773 H2C_FUNC_SCANOFLD, 1, 1, 5774 len); 5775 5776 if (option->enable) 5777 cond = RTW89_SCANOFLD_WAIT_COND_START; 5778 else 5779 cond = RTW89_SCANOFLD_WAIT_COND_STOP; 5780 5781 ret = rtw89_h2c_tx_and_wait(rtwdev, skb, wait, cond); 5782 if (ret) { 5783 rtw89_debug(rtwdev, RTW89_DBG_FW, "failed to scan ofld\n"); 5784 return ret; 5785 } 5786 5787 return 0; 5788 } 5789 5790 static void rtw89_scan_get_6g_disabled_chan(struct rtw89_dev *rtwdev, 5791 struct rtw89_scan_option *option) 5792 { 5793 struct ieee80211_supported_band *sband; 5794 struct ieee80211_channel *chan; 5795 u8 i, idx; 5796 5797 sband = rtwdev->hw->wiphy->bands[NL80211_BAND_6GHZ]; 5798 if (!sband) { 5799 option->prohib_chan = U64_MAX; 5800 return; 5801 } 5802 5803 for (i = 0; i < sband->n_channels; i++) { 5804 chan = &sband->channels[i]; 5805 if (chan->flags & IEEE80211_CHAN_DISABLED) { 5806 idx = (chan->hw_value - 1) / 4; 5807 option->prohib_chan |= BIT(idx); 5808 } 5809 } 5810 } 5811 5812 int rtw89_fw_h2c_scan_offload_be(struct rtw89_dev *rtwdev, 5813 struct rtw89_scan_option *option, 5814 struct rtw89_vif_link *rtwvif_link, 5815 bool wowlan) 5816 { 5817 struct rtw89_vif *rtwvif = rtwvif_link->rtwvif; 5818 struct rtw89_hw_scan_info *scan_info = &rtwdev->scan_info; 5819 const struct rtw89_hw_scan_extra_op *ext = &scan_info->extra_op; 5820 struct rtw89_wait_info *wait = &rtwdev->mac.fw_ofld_wait; 5821 struct cfg80211_scan_request *req = rtwvif->scan_req; 5822 struct rtw89_h2c_scanofld_be_macc_role *macc_role; 5823 struct rtw89_hw_scan_extra_op scan_op[2] = {}; 5824 struct rtw89_chan *op = &scan_info->op_chan; 5825 struct rtw89_h2c_scanofld_be_opch *opch; 5826 struct rtw89_pktofld_info *pkt_info; 5827 struct rtw89_h2c_scanofld_be *h2c; 5828 struct ieee80211_vif *vif; 5829 struct sk_buff *skb; 5830 u8 macc_role_size = sizeof(*macc_role) * option->num_macc_role; 5831 u8 opch_size = sizeof(*opch) * option->num_opch; 5832 enum rtw89_scan_be_opmode opmode; 5833 u8 probe_id[NUM_NL80211_BANDS]; 5834 u8 scan_offload_ver = U8_MAX; 5835 u8 cfg_len = sizeof(*h2c); 5836 unsigned int cond; 5837 u8 ap_idx = U8_MAX; 5838 u8 ver = U8_MAX; 5839 u8 policy_val; 5840 #if defined(__linux__) 5841 void *ptr; 5842 #elif defined(__FreeBSD__) 5843 u8 *ptr; 5844 #endif 5845 u8 txbcn; 5846 int ret; 5847 u32 len; 5848 u8 i; 5849 5850 scan_op[0].macid = rtwvif_link->mac_id; 5851 scan_op[0].port = rtwvif_link->port; 5852 scan_op[0].chan = *op; 5853 vif = rtwvif_to_vif(rtwvif_link->rtwvif); 5854 if (vif->type == NL80211_IFTYPE_AP) 5855 ap_idx = 0; 5856 5857 if (ext->set) { 5858 scan_op[1] = *ext; 5859 vif = rtwvif_to_vif(ext->rtwvif_link->rtwvif); 5860 if (vif->type == NL80211_IFTYPE_AP) 5861 ap_idx = 1; 5862 } 5863 5864 rtw89_scan_get_6g_disabled_chan(rtwdev, option); 5865 5866 if (RTW89_CHK_FW_FEATURE(SCAN_OFFLOAD_BE_V0, &rtwdev->fw)) { 5867 cfg_len = offsetofend(typeof(*h2c), w8); 5868 scan_offload_ver = 0; 5869 } 5870 5871 len = cfg_len + macc_role_size + opch_size; 5872 skb = rtw89_fw_h2c_alloc_skb_with_hdr(rtwdev, len); 5873 if (!skb) { 5874 rtw89_err(rtwdev, "failed to alloc skb for h2c scan offload\n"); 5875 return -ENOMEM; 5876 } 5877 5878 skb_put(skb, len); 5879 h2c = (struct rtw89_h2c_scanofld_be *)skb->data; 5880 ptr = skb->data; 5881 5882 memset(probe_id, RTW89_SCANOFLD_PKT_NONE, sizeof(probe_id)); 5883 5884 if (RTW89_CHK_FW_FEATURE(CH_INFO_BE_V0, &rtwdev->fw)) 5885 ver = 0; 5886 5887 if (!wowlan) { 5888 list_for_each_entry(pkt_info, &scan_info->pkt_list[NL80211_BAND_6GHZ], list) { 5889 if (pkt_info->wildcard_6ghz) { 5890 /* Provide wildcard as template */ 5891 probe_id[NL80211_BAND_6GHZ] = pkt_info->id; 5892 break; 5893 } 5894 } 5895 } 5896 5897 h2c->w0 = le32_encode_bits(option->operation, RTW89_H2C_SCANOFLD_BE_W0_OP) | 5898 le32_encode_bits(option->scan_mode, 5899 RTW89_H2C_SCANOFLD_BE_W0_SCAN_MODE) | 5900 le32_encode_bits(option->repeat, RTW89_H2C_SCANOFLD_BE_W0_REPEAT) | 5901 le32_encode_bits(true, RTW89_H2C_SCANOFLD_BE_W0_NOTIFY_END) | 5902 le32_encode_bits(true, RTW89_H2C_SCANOFLD_BE_W0_LEARN_CH) | 5903 le32_encode_bits(rtwvif_link->mac_id, RTW89_H2C_SCANOFLD_BE_W0_MACID) | 5904 le32_encode_bits(rtwvif_link->port, RTW89_H2C_SCANOFLD_BE_W0_PORT) | 5905 le32_encode_bits(option->band, RTW89_H2C_SCANOFLD_BE_W0_BAND); 5906 5907 h2c->w1 = le32_encode_bits(option->num_macc_role, RTW89_H2C_SCANOFLD_BE_W1_NUM_MACC_ROLE) | 5908 le32_encode_bits(option->num_opch, RTW89_H2C_SCANOFLD_BE_W1_NUM_OP) | 5909 le32_encode_bits(option->norm_pd, RTW89_H2C_SCANOFLD_BE_W1_NORM_PD); 5910 5911 h2c->w2 = le32_encode_bits(option->slow_pd, RTW89_H2C_SCANOFLD_BE_W2_SLOW_PD) | 5912 le32_encode_bits(option->norm_cy, RTW89_H2C_SCANOFLD_BE_W2_NORM_CY) | 5913 le32_encode_bits(option->opch_end, RTW89_H2C_SCANOFLD_BE_W2_OPCH_END); 5914 5915 h2c->w3 = le32_encode_bits(0, RTW89_H2C_SCANOFLD_BE_W3_NUM_SSID) | 5916 le32_encode_bits(0, RTW89_H2C_SCANOFLD_BE_W3_NUM_SHORT_SSID) | 5917 le32_encode_bits(0, RTW89_H2C_SCANOFLD_BE_W3_NUM_BSSID) | 5918 le32_encode_bits(probe_id[NL80211_BAND_2GHZ], RTW89_H2C_SCANOFLD_BE_W3_PROBEID); 5919 5920 h2c->w4 = le32_encode_bits(probe_id[NL80211_BAND_5GHZ], 5921 RTW89_H2C_SCANOFLD_BE_W4_PROBE_5G) | 5922 le32_encode_bits(probe_id[NL80211_BAND_6GHZ], 5923 RTW89_H2C_SCANOFLD_BE_W4_PROBE_6G) | 5924 le32_encode_bits(option->delay / 1000, RTW89_H2C_SCANOFLD_BE_W4_DELAY_START); 5925 5926 h2c->w5 = le32_encode_bits(option->mlo_mode, RTW89_H2C_SCANOFLD_BE_W5_MLO_MODE); 5927 5928 h2c->w6 = le32_encode_bits(option->prohib_chan, 5929 RTW89_H2C_SCANOFLD_BE_W6_CHAN_PROHIB_LOW); 5930 h2c->w7 = le32_encode_bits(option->prohib_chan >> 32, 5931 RTW89_H2C_SCANOFLD_BE_W7_CHAN_PROHIB_HIGH); 5932 if (!wowlan && req->no_cck) { 5933 h2c->w0 |= le32_encode_bits(true, RTW89_H2C_SCANOFLD_BE_W0_PROBE_WITH_RATE); 5934 h2c->w8 = le32_encode_bits(RTW89_HW_RATE_OFDM6, 5935 RTW89_H2C_SCANOFLD_BE_W8_PROBE_RATE_2GHZ) | 5936 le32_encode_bits(RTW89_HW_RATE_OFDM6, 5937 RTW89_H2C_SCANOFLD_BE_W8_PROBE_RATE_5GHZ) | 5938 le32_encode_bits(RTW89_HW_RATE_OFDM6, 5939 RTW89_H2C_SCANOFLD_BE_W8_PROBE_RATE_6GHZ); 5940 } 5941 5942 if (scan_offload_ver == 0) 5943 goto flex_member; 5944 5945 h2c->w9 = le32_encode_bits(sizeof(*h2c) / sizeof(h2c->w0), 5946 RTW89_H2C_SCANOFLD_BE_W9_SIZE_CFG) | 5947 le32_encode_bits(sizeof(*macc_role) / sizeof(macc_role->w0), 5948 RTW89_H2C_SCANOFLD_BE_W9_SIZE_MACC) | 5949 le32_encode_bits(sizeof(*opch) / sizeof(opch->w0), 5950 RTW89_H2C_SCANOFLD_BE_W9_SIZE_OP); 5951 5952 flex_member: 5953 ptr += cfg_len; 5954 5955 for (i = 0; i < option->num_macc_role; i++) { 5956 #if defined(__linux__) 5957 macc_role = ptr; 5958 #elif defined(__FreeBSD__) 5959 macc_role = (void *)ptr; 5960 #endif 5961 macc_role->w0 = 5962 le32_encode_bits(0, RTW89_H2C_SCANOFLD_BE_MACC_ROLE_W0_BAND) | 5963 le32_encode_bits(0, RTW89_H2C_SCANOFLD_BE_MACC_ROLE_W0_PORT) | 5964 le32_encode_bits(0, RTW89_H2C_SCANOFLD_BE_MACC_ROLE_W0_MACID) | 5965 le32_encode_bits(0, RTW89_H2C_SCANOFLD_BE_MACC_ROLE_W0_OPCH_END); 5966 ptr += sizeof(*macc_role); 5967 } 5968 5969 for (i = 0; i < option->num_opch; i++) { 5970 bool is_ap_idx = i == ap_idx; 5971 5972 opmode = is_ap_idx ? RTW89_SCAN_OPMODE_TBTT : RTW89_SCAN_OPMODE_INTV; 5973 policy_val = is_ap_idx ? 2 : RTW89_OFF_CHAN_TIME / 10; 5974 txbcn = is_ap_idx ? 1 : 0; 5975 5976 #if defined(__linux__) 5977 opch = ptr; 5978 #elif defined(__FreeBSD__) 5979 opch = (void *)ptr; 5980 #endif 5981 opch->w0 = le32_encode_bits(scan_op[i].macid, 5982 RTW89_H2C_SCANOFLD_BE_OPCH_W0_MACID) | 5983 le32_encode_bits(option->band, 5984 RTW89_H2C_SCANOFLD_BE_OPCH_W0_BAND) | 5985 le32_encode_bits(scan_op[i].port, 5986 RTW89_H2C_SCANOFLD_BE_OPCH_W0_PORT) | 5987 le32_encode_bits(opmode, 5988 RTW89_H2C_SCANOFLD_BE_OPCH_W0_POLICY) | 5989 le32_encode_bits(true, 5990 RTW89_H2C_SCANOFLD_BE_OPCH_W0_TXNULL) | 5991 le32_encode_bits(policy_val, 5992 RTW89_H2C_SCANOFLD_BE_OPCH_W0_POLICY_VAL); 5993 5994 opch->w1 = le32_encode_bits(scan_op[i].chan.band_type, 5995 RTW89_H2C_SCANOFLD_BE_OPCH_W1_CH_BAND) | 5996 le32_encode_bits(scan_op[i].chan.band_width, 5997 RTW89_H2C_SCANOFLD_BE_OPCH_W1_BW) | 5998 le32_encode_bits(0x3, 5999 RTW89_H2C_SCANOFLD_BE_OPCH_W1_NOTIFY) | 6000 le32_encode_bits(scan_op[i].chan.primary_channel, 6001 RTW89_H2C_SCANOFLD_BE_OPCH_W1_PRI_CH) | 6002 le32_encode_bits(scan_op[i].chan.channel, 6003 RTW89_H2C_SCANOFLD_BE_OPCH_W1_CENTRAL_CH); 6004 6005 opch->w2 = le32_encode_bits(0, 6006 RTW89_H2C_SCANOFLD_BE_OPCH_W2_PKTS_CTRL) | 6007 le32_encode_bits(0, 6008 RTW89_H2C_SCANOFLD_BE_OPCH_W2_SW_DEF) | 6009 le32_encode_bits(rtw89_is_mlo_1_1(rtwdev) ? 1 : 2, 6010 RTW89_H2C_SCANOFLD_BE_OPCH_W2_SS) | 6011 le32_encode_bits(txbcn, 6012 RTW89_H2C_SCANOFLD_BE_OPCH_W2_TXBCN); 6013 6014 opch->w3 = le32_encode_bits(RTW89_SCANOFLD_PKT_NONE, 6015 RTW89_H2C_SCANOFLD_BE_OPCH_W3_PKT0) | 6016 le32_encode_bits(RTW89_SCANOFLD_PKT_NONE, 6017 RTW89_H2C_SCANOFLD_BE_OPCH_W3_PKT1) | 6018 le32_encode_bits(RTW89_SCANOFLD_PKT_NONE, 6019 RTW89_H2C_SCANOFLD_BE_OPCH_W3_PKT2) | 6020 le32_encode_bits(RTW89_SCANOFLD_PKT_NONE, 6021 RTW89_H2C_SCANOFLD_BE_OPCH_W3_PKT3); 6022 6023 if (ver == 0) 6024 opch->w1 |= le32_encode_bits(RTW89_CHANNEL_TIME, 6025 RTW89_H2C_SCANOFLD_BE_OPCH_W1_DURATION); 6026 else 6027 opch->w4 = le32_encode_bits(RTW89_CHANNEL_TIME, 6028 RTW89_H2C_SCANOFLD_BE_OPCH_W4_DURATION_V1); 6029 ptr += sizeof(*opch); 6030 } 6031 6032 rtw89_h2c_pkt_set_hdr(rtwdev, skb, FWCMD_TYPE_H2C, 6033 H2C_CAT_MAC, H2C_CL_MAC_FW_OFLD, 6034 H2C_FUNC_SCANOFLD_BE, 1, 1, 6035 len); 6036 6037 if (option->enable) 6038 cond = RTW89_SCANOFLD_BE_WAIT_COND_START; 6039 else 6040 cond = RTW89_SCANOFLD_BE_WAIT_COND_STOP; 6041 6042 ret = rtw89_h2c_tx_and_wait(rtwdev, skb, wait, cond); 6043 if (ret) { 6044 rtw89_debug(rtwdev, RTW89_DBG_FW, "failed to scan be ofld\n"); 6045 return ret; 6046 } 6047 6048 return 0; 6049 } 6050 6051 int rtw89_fw_h2c_rf_reg(struct rtw89_dev *rtwdev, 6052 struct rtw89_fw_h2c_rf_reg_info *info, 6053 u16 len, u8 page) 6054 { 6055 struct sk_buff *skb; 6056 u8 class = info->rf_path == RF_PATH_A ? 6057 H2C_CL_OUTSRC_RF_REG_A : H2C_CL_OUTSRC_RF_REG_B; 6058 int ret; 6059 6060 skb = rtw89_fw_h2c_alloc_skb_with_hdr(rtwdev, len); 6061 if (!skb) { 6062 rtw89_err(rtwdev, "failed to alloc skb for h2c rf reg\n"); 6063 return -ENOMEM; 6064 } 6065 skb_put_data(skb, info->rtw89_phy_config_rf_h2c[page], len); 6066 6067 rtw89_h2c_pkt_set_hdr(rtwdev, skb, FWCMD_TYPE_H2C, 6068 H2C_CAT_OUTSRC, class, page, 0, 0, 6069 len); 6070 6071 ret = rtw89_h2c_tx(rtwdev, skb, false); 6072 if (ret) { 6073 rtw89_err(rtwdev, "failed to send h2c\n"); 6074 goto fail; 6075 } 6076 6077 return 0; 6078 fail: 6079 dev_kfree_skb_any(skb); 6080 6081 return ret; 6082 } 6083 6084 int rtw89_fw_h2c_rf_ntfy_mcc(struct rtw89_dev *rtwdev) 6085 { 6086 struct rtw89_rfk_mcc_info_data *rfk_mcc = rtwdev->rfk_mcc.data; 6087 struct rtw89_fw_h2c_rf_get_mccch_v0 *mccch_v0; 6088 struct rtw89_fw_h2c_rf_get_mccch *mccch; 6089 u32 len = sizeof(*mccch); 6090 struct sk_buff *skb; 6091 u8 ver = U8_MAX; 6092 int ret; 6093 u8 idx; 6094 6095 if (RTW89_CHK_FW_FEATURE(RFK_NTFY_MCC_V0, &rtwdev->fw)) { 6096 len = sizeof(*mccch_v0); 6097 ver = 0; 6098 } 6099 6100 skb = rtw89_fw_h2c_alloc_skb_with_hdr(rtwdev, len); 6101 if (!skb) { 6102 rtw89_err(rtwdev, "failed to alloc skb for h2c cxdrv_ctrl\n"); 6103 return -ENOMEM; 6104 } 6105 skb_put(skb, len); 6106 6107 idx = rfk_mcc->table_idx; 6108 if (ver == 0) { 6109 mccch_v0 = (struct rtw89_fw_h2c_rf_get_mccch_v0 *)skb->data; 6110 mccch_v0->ch_0 = cpu_to_le32(rfk_mcc->ch[0]); 6111 mccch_v0->ch_1 = cpu_to_le32(rfk_mcc->ch[1]); 6112 mccch_v0->band_0 = cpu_to_le32(rfk_mcc->band[0]); 6113 mccch_v0->band_1 = cpu_to_le32(rfk_mcc->band[1]); 6114 mccch_v0->current_band_type = cpu_to_le32(rfk_mcc->band[idx]); 6115 mccch_v0->current_channel = cpu_to_le32(rfk_mcc->ch[idx]); 6116 } else { 6117 mccch = (struct rtw89_fw_h2c_rf_get_mccch *)skb->data; 6118 mccch->ch_0_0 = cpu_to_le32(rfk_mcc->ch[0]); 6119 mccch->ch_0_1 = cpu_to_le32(rfk_mcc->ch[0]); 6120 mccch->ch_1_0 = cpu_to_le32(rfk_mcc->ch[1]); 6121 mccch->ch_1_1 = cpu_to_le32(rfk_mcc->ch[1]); 6122 mccch->current_channel = cpu_to_le32(rfk_mcc->ch[idx]); 6123 } 6124 6125 rtw89_h2c_pkt_set_hdr(rtwdev, skb, FWCMD_TYPE_H2C, 6126 H2C_CAT_OUTSRC, H2C_CL_OUTSRC_RF_FW_NOTIFY, 6127 H2C_FUNC_OUTSRC_RF_GET_MCCCH, 0, 0, 6128 len); 6129 6130 ret = rtw89_h2c_tx(rtwdev, skb, false); 6131 if (ret) { 6132 rtw89_err(rtwdev, "failed to send h2c\n"); 6133 goto fail; 6134 } 6135 6136 return 0; 6137 fail: 6138 dev_kfree_skb_any(skb); 6139 6140 return ret; 6141 } 6142 EXPORT_SYMBOL(rtw89_fw_h2c_rf_ntfy_mcc); 6143 6144 int rtw89_fw_h2c_mcc_dig(struct rtw89_dev *rtwdev, 6145 enum rtw89_chanctx_idx chanctx_idx, 6146 u8 mcc_role_idx, u8 pd_val, bool en) 6147 { 6148 const struct rtw89_chan *chan = rtw89_chan_get(rtwdev, chanctx_idx); 6149 const struct rtw89_dig_regs *dig_regs = rtwdev->chip->dig_regs; 6150 struct rtw89_h2c_mcc_dig *h2c; 6151 u32 len = sizeof(*h2c); 6152 struct sk_buff *skb; 6153 int ret; 6154 6155 skb = rtw89_fw_h2c_alloc_skb_with_hdr(rtwdev, len); 6156 if (!skb) { 6157 rtw89_err(rtwdev, "failed to alloc skb for h2c mcc_dig\n"); 6158 return -ENOMEM; 6159 } 6160 skb_put(skb, len); 6161 h2c = (struct rtw89_h2c_mcc_dig *)skb->data; 6162 6163 h2c->w0 = le32_encode_bits(1, RTW89_H2C_MCC_DIG_W0_REG_CNT) | 6164 le32_encode_bits(en, RTW89_H2C_MCC_DIG_W0_DM_EN) | 6165 le32_encode_bits(mcc_role_idx, RTW89_H2C_MCC_DIG_W0_IDX) | 6166 le32_encode_bits(1, RTW89_H2C_MCC_DIG_W0_SET) | 6167 le32_encode_bits(1, RTW89_H2C_MCC_DIG_W0_PHY0_EN) | 6168 le32_encode_bits(chan->channel, RTW89_H2C_MCC_DIG_W0_CENTER_CH) | 6169 le32_encode_bits(chan->band_type, RTW89_H2C_MCC_DIG_W0_BAND_TYPE); 6170 h2c->w1 = le32_encode_bits(dig_regs->seg0_pd_reg, 6171 RTW89_H2C_MCC_DIG_W1_ADDR_LSB) | 6172 le32_encode_bits(dig_regs->seg0_pd_reg >> 8, 6173 RTW89_H2C_MCC_DIG_W1_ADDR_MSB) | 6174 le32_encode_bits(dig_regs->pd_lower_bound_mask, 6175 RTW89_H2C_MCC_DIG_W1_BMASK_LSB) | 6176 le32_encode_bits(dig_regs->pd_lower_bound_mask >> 8, 6177 RTW89_H2C_MCC_DIG_W1_BMASK_MSB); 6178 h2c->w2 = le32_encode_bits(pd_val, RTW89_H2C_MCC_DIG_W2_VAL_LSB); 6179 6180 rtw89_h2c_pkt_set_hdr(rtwdev, skb, FWCMD_TYPE_H2C, 6181 H2C_CAT_OUTSRC, H2C_CL_OUTSRC_DM, 6182 H2C_FUNC_FW_MCC_DIG, 0, 0, len); 6183 6184 ret = rtw89_h2c_tx(rtwdev, skb, false); 6185 if (ret) { 6186 rtw89_err(rtwdev, "failed to send h2c\n"); 6187 goto fail; 6188 } 6189 6190 return 0; 6191 fail: 6192 dev_kfree_skb_any(skb); 6193 6194 return ret; 6195 } 6196 6197 int rtw89_fw_h2c_rf_ps_info(struct rtw89_dev *rtwdev, struct rtw89_vif *rtwvif) 6198 { 6199 const struct rtw89_chip_info *chip = rtwdev->chip; 6200 struct rtw89_vif_link *rtwvif_link; 6201 struct rtw89_h2c_rf_ps_info *h2c; 6202 const struct rtw89_chan *chan; 6203 u32 len = sizeof(*h2c); 6204 unsigned int link_id; 6205 struct sk_buff *skb; 6206 int ret; 6207 u8 path; 6208 u32 val; 6209 6210 if (chip->chip_gen != RTW89_CHIP_BE) 6211 return 0; 6212 6213 skb = rtw89_fw_h2c_alloc_skb_with_hdr(rtwdev, len); 6214 if (!skb) { 6215 rtw89_err(rtwdev, "failed to alloc skb for h2c rf ps info\n"); 6216 return -ENOMEM; 6217 } 6218 skb_put(skb, len); 6219 h2c = (struct rtw89_h2c_rf_ps_info *)skb->data; 6220 h2c->mlo_mode = cpu_to_le32(rtwdev->mlo_dbcc_mode); 6221 6222 rtw89_vif_for_each_link(rtwvif, rtwvif_link, link_id) { 6223 chan = rtw89_chan_get(rtwdev, rtwvif_link->chanctx_idx); 6224 path = rtw89_phy_get_syn_sel(rtwdev, rtwvif_link->phy_idx); 6225 val = rtw89_chip_chan_to_rf18_val(rtwdev, chan); 6226 6227 if (path >= chip->rf_path_num || path >= NUM_OF_RTW89_FW_RFK_PATH) { 6228 rtw89_err(rtwdev, "unsupported rf path (%d)\n", path); 6229 ret = -ENOENT; 6230 goto fail; 6231 } 6232 6233 h2c->rf18[path] = cpu_to_le32(val); 6234 h2c->pri_ch[path] = chan->primary_channel; 6235 } 6236 6237 rtw89_h2c_pkt_set_hdr(rtwdev, skb, FWCMD_TYPE_H2C, 6238 H2C_CAT_OUTSRC, H2C_CL_OUTSRC_RF_FW_NOTIFY, 6239 H2C_FUNC_OUTSRC_RF_PS_INFO, 0, 0, 6240 sizeof(*h2c)); 6241 6242 ret = rtw89_h2c_tx(rtwdev, skb, false); 6243 if (ret) { 6244 rtw89_err(rtwdev, "failed to send h2c\n"); 6245 goto fail; 6246 } 6247 6248 return 0; 6249 fail: 6250 dev_kfree_skb_any(skb); 6251 6252 return ret; 6253 } 6254 EXPORT_SYMBOL(rtw89_fw_h2c_rf_ps_info); 6255 6256 int rtw89_fw_h2c_rf_pre_ntfy(struct rtw89_dev *rtwdev, 6257 enum rtw89_phy_idx phy_idx) 6258 { 6259 struct rtw89_rfk_mcc_info *rfk_mcc = &rtwdev->rfk_mcc; 6260 struct rtw89_fw_h2c_rfk_pre_info_common *common; 6261 struct rtw89_fw_h2c_rfk_pre_info_v0 *h2c_v0; 6262 struct rtw89_fw_h2c_rfk_pre_info_v1 *h2c_v1; 6263 struct rtw89_fw_h2c_rfk_pre_info *h2c; 6264 u8 tbl_sel[NUM_OF_RTW89_FW_RFK_PATH]; 6265 u32 len = sizeof(*h2c); 6266 struct sk_buff *skb; 6267 u8 ver = U8_MAX; 6268 u8 tbl, path; 6269 u32 val32; 6270 int ret; 6271 6272 if (RTW89_CHK_FW_FEATURE(RFK_PRE_NOTIFY_V1, &rtwdev->fw)) { 6273 len = sizeof(*h2c_v1); 6274 ver = 1; 6275 } else if (RTW89_CHK_FW_FEATURE(RFK_PRE_NOTIFY_V0, &rtwdev->fw)) { 6276 len = sizeof(*h2c_v0); 6277 ver = 0; 6278 } 6279 6280 skb = rtw89_fw_h2c_alloc_skb_with_hdr(rtwdev, len); 6281 if (!skb) { 6282 rtw89_err(rtwdev, "failed to alloc skb for h2c rfk_pre_ntfy\n"); 6283 return -ENOMEM; 6284 } 6285 skb_put(skb, len); 6286 h2c = (struct rtw89_fw_h2c_rfk_pre_info *)skb->data; 6287 common = &h2c->base_v1.common; 6288 6289 common->mlo_mode = cpu_to_le32(rtwdev->mlo_dbcc_mode); 6290 6291 BUILD_BUG_ON(NUM_OF_RTW89_FW_RFK_TBL > RTW89_RFK_CHS_NR); 6292 BUILD_BUG_ON(ARRAY_SIZE(rfk_mcc->data) < NUM_OF_RTW89_FW_RFK_PATH); 6293 6294 for (tbl = 0; tbl < NUM_OF_RTW89_FW_RFK_TBL; tbl++) { 6295 for (path = 0; path < NUM_OF_RTW89_FW_RFK_PATH; path++) { 6296 common->dbcc.ch[path][tbl] = 6297 cpu_to_le32(rfk_mcc->data[path].ch[tbl]); 6298 common->dbcc.band[path][tbl] = 6299 cpu_to_le32(rfk_mcc->data[path].band[tbl]); 6300 } 6301 } 6302 6303 for (path = 0; path < NUM_OF_RTW89_FW_RFK_PATH; path++) { 6304 tbl_sel[path] = rfk_mcc->data[path].table_idx; 6305 6306 common->tbl.cur_ch[path] = 6307 cpu_to_le32(rfk_mcc->data[path].ch[tbl_sel[path]]); 6308 common->tbl.cur_band[path] = 6309 cpu_to_le32(rfk_mcc->data[path].band[tbl_sel[path]]); 6310 6311 if (ver <= 1) 6312 continue; 6313 6314 h2c->cur_bandwidth[path] = 6315 cpu_to_le32(rfk_mcc->data[path].bw[tbl_sel[path]]); 6316 } 6317 6318 common->phy_idx = cpu_to_le32(phy_idx); 6319 6320 if (ver == 0) { /* RFK_PRE_NOTIFY_V0 */ 6321 h2c_v0 = (struct rtw89_fw_h2c_rfk_pre_info_v0 *)skb->data; 6322 6323 h2c_v0->cur_band = cpu_to_le32(rfk_mcc->data[0].band[tbl_sel[0]]); 6324 h2c_v0->cur_bw = cpu_to_le32(rfk_mcc->data[0].bw[tbl_sel[0]]); 6325 h2c_v0->cur_center_ch = cpu_to_le32(rfk_mcc->data[0].ch[tbl_sel[0]]); 6326 6327 val32 = rtw89_phy_read32_mask(rtwdev, R_COEF_SEL, B_COEF_SEL_IQC_V1); 6328 h2c_v0->ktbl_sel0 = cpu_to_le32(val32); 6329 val32 = rtw89_phy_read32_mask(rtwdev, R_COEF_SEL_C1, B_COEF_SEL_IQC_V1); 6330 h2c_v0->ktbl_sel1 = cpu_to_le32(val32); 6331 val32 = rtw89_read_rf(rtwdev, RF_PATH_A, RR_CFGCH, RFREG_MASK); 6332 h2c_v0->rfmod0 = cpu_to_le32(val32); 6333 val32 = rtw89_read_rf(rtwdev, RF_PATH_B, RR_CFGCH, RFREG_MASK); 6334 h2c_v0->rfmod1 = cpu_to_le32(val32); 6335 6336 if (rtw89_is_mlo_1_1(rtwdev)) 6337 h2c_v0->mlo_1_1 = cpu_to_le32(1); 6338 6339 h2c_v0->rfe_type = cpu_to_le32(rtwdev->efuse.rfe_type); 6340 6341 goto done; 6342 } 6343 6344 if (rtw89_is_mlo_1_1(rtwdev)) { 6345 h2c_v1 = &h2c->base_v1; 6346 h2c_v1->mlo_1_1 = cpu_to_le32(1); 6347 } 6348 done: 6349 rtw89_h2c_pkt_set_hdr(rtwdev, skb, FWCMD_TYPE_H2C, 6350 H2C_CAT_OUTSRC, H2C_CL_OUTSRC_RF_FW_RFK, 6351 H2C_FUNC_RFK_PRE_NOTIFY, 0, 0, 6352 len); 6353 6354 ret = rtw89_h2c_tx(rtwdev, skb, false); 6355 if (ret) { 6356 rtw89_err(rtwdev, "failed to send h2c\n"); 6357 goto fail; 6358 } 6359 6360 return 0; 6361 fail: 6362 dev_kfree_skb_any(skb); 6363 6364 return ret; 6365 } 6366 6367 int rtw89_fw_h2c_rf_tssi(struct rtw89_dev *rtwdev, enum rtw89_phy_idx phy_idx, 6368 const struct rtw89_chan *chan, enum rtw89_tssi_mode tssi_mode) 6369 { 6370 struct rtw89_efuse *efuse = &rtwdev->efuse; 6371 struct rtw89_hal *hal = &rtwdev->hal; 6372 struct rtw89_h2c_rf_tssi *h2c; 6373 u32 len = sizeof(*h2c); 6374 struct sk_buff *skb; 6375 int ret; 6376 6377 skb = rtw89_fw_h2c_alloc_skb_with_hdr(rtwdev, len); 6378 if (!skb) { 6379 rtw89_err(rtwdev, "failed to alloc skb for h2c RF TSSI\n"); 6380 return -ENOMEM; 6381 } 6382 skb_put(skb, len); 6383 h2c = (struct rtw89_h2c_rf_tssi *)skb->data; 6384 6385 h2c->len = cpu_to_le16(len); 6386 h2c->phy = phy_idx; 6387 h2c->ch = chan->channel; 6388 h2c->bw = chan->band_width; 6389 h2c->band = chan->band_type; 6390 h2c->hwtx_en = true; 6391 h2c->cv = hal->cv; 6392 h2c->tssi_mode = tssi_mode; 6393 h2c->rfe_type = efuse->rfe_type; 6394 6395 rtw89_phy_rfk_tssi_fill_fwcmd_efuse_to_de(rtwdev, phy_idx, chan, h2c); 6396 rtw89_phy_rfk_tssi_fill_fwcmd_tmeter_tbl(rtwdev, phy_idx, chan, h2c); 6397 6398 rtw89_h2c_pkt_set_hdr(rtwdev, skb, FWCMD_TYPE_H2C, 6399 H2C_CAT_OUTSRC, H2C_CL_OUTSRC_RF_FW_RFK, 6400 H2C_FUNC_RFK_TSSI_OFFLOAD, 0, 0, len); 6401 6402 ret = rtw89_h2c_tx(rtwdev, skb, false); 6403 if (ret) { 6404 rtw89_err(rtwdev, "failed to send h2c\n"); 6405 goto fail; 6406 } 6407 6408 return 0; 6409 fail: 6410 dev_kfree_skb_any(skb); 6411 6412 return ret; 6413 } 6414 6415 int rtw89_fw_h2c_rf_iqk(struct rtw89_dev *rtwdev, enum rtw89_phy_idx phy_idx, 6416 const struct rtw89_chan *chan) 6417 { 6418 struct rtw89_hal *hal = &rtwdev->hal; 6419 struct rtw89_h2c_rf_iqk_v0 *h2c_v0; 6420 struct rtw89_h2c_rf_iqk *h2c; 6421 u32 len = sizeof(*h2c); 6422 struct sk_buff *skb; 6423 u8 ver = U8_MAX; 6424 int ret; 6425 6426 if (RTW89_CHK_FW_FEATURE(RFK_IQK_V0, &rtwdev->fw)) { 6427 len = sizeof(*h2c_v0); 6428 ver = 0; 6429 } 6430 6431 skb = rtw89_fw_h2c_alloc_skb_with_hdr(rtwdev, len); 6432 if (!skb) { 6433 rtw89_err(rtwdev, "failed to alloc skb for h2c RF IQK\n"); 6434 return -ENOMEM; 6435 } 6436 skb_put(skb, len); 6437 6438 if (ver == 0) { 6439 h2c_v0 = (struct rtw89_h2c_rf_iqk_v0 *)skb->data; 6440 6441 h2c_v0->phy_idx = cpu_to_le32(phy_idx); 6442 h2c_v0->dbcc = cpu_to_le32(rtwdev->dbcc_en); 6443 6444 goto done; 6445 } 6446 6447 h2c = (struct rtw89_h2c_rf_iqk *)skb->data; 6448 6449 h2c->len = sizeof(*h2c); 6450 h2c->ktype = 0; 6451 h2c->phy = phy_idx; 6452 h2c->kpath = rtw89_phy_get_kpath(rtwdev, phy_idx); 6453 h2c->band = chan->band_type; 6454 h2c->bw = chan->band_width; 6455 h2c->ch = chan->channel; 6456 h2c->cv = hal->cv; 6457 6458 done: 6459 rtw89_h2c_pkt_set_hdr(rtwdev, skb, FWCMD_TYPE_H2C, 6460 H2C_CAT_OUTSRC, H2C_CL_OUTSRC_RF_FW_RFK, 6461 H2C_FUNC_RFK_IQK_OFFLOAD, 0, 0, len); 6462 6463 ret = rtw89_h2c_tx(rtwdev, skb, false); 6464 if (ret) { 6465 rtw89_err(rtwdev, "failed to send h2c\n"); 6466 goto fail; 6467 } 6468 6469 return 0; 6470 fail: 6471 dev_kfree_skb_any(skb); 6472 6473 return ret; 6474 } 6475 6476 int rtw89_fw_h2c_rf_dpk(struct rtw89_dev *rtwdev, enum rtw89_phy_idx phy_idx, 6477 const struct rtw89_chan *chan) 6478 { 6479 struct rtw89_h2c_rf_dpk *h2c; 6480 u32 len = sizeof(*h2c); 6481 struct sk_buff *skb; 6482 int ret; 6483 6484 skb = rtw89_fw_h2c_alloc_skb_with_hdr(rtwdev, len); 6485 if (!skb) { 6486 rtw89_err(rtwdev, "failed to alloc skb for h2c RF DPK\n"); 6487 return -ENOMEM; 6488 } 6489 skb_put(skb, len); 6490 h2c = (struct rtw89_h2c_rf_dpk *)skb->data; 6491 6492 h2c->len = len; 6493 h2c->phy = phy_idx; 6494 h2c->dpk_enable = true; 6495 h2c->kpath = RF_AB; 6496 h2c->cur_band = chan->band_type; 6497 h2c->cur_bw = chan->band_width; 6498 h2c->cur_ch = chan->channel; 6499 h2c->dpk_dbg_en = rtw89_debug_is_enabled(rtwdev, RTW89_DBG_RFK); 6500 6501 rtw89_h2c_pkt_set_hdr(rtwdev, skb, FWCMD_TYPE_H2C, 6502 H2C_CAT_OUTSRC, H2C_CL_OUTSRC_RF_FW_RFK, 6503 H2C_FUNC_RFK_DPK_OFFLOAD, 0, 0, len); 6504 6505 ret = rtw89_h2c_tx(rtwdev, skb, false); 6506 if (ret) { 6507 rtw89_err(rtwdev, "failed to send h2c\n"); 6508 goto fail; 6509 } 6510 6511 return 0; 6512 fail: 6513 dev_kfree_skb_any(skb); 6514 6515 return ret; 6516 } 6517 6518 int rtw89_fw_h2c_rf_txgapk(struct rtw89_dev *rtwdev, enum rtw89_phy_idx phy_idx, 6519 const struct rtw89_chan *chan) 6520 { 6521 struct rtw89_hal *hal = &rtwdev->hal; 6522 struct rtw89_h2c_rf_txgapk *h2c; 6523 u32 len = sizeof(*h2c); 6524 struct sk_buff *skb; 6525 int ret; 6526 6527 skb = rtw89_fw_h2c_alloc_skb_with_hdr(rtwdev, len); 6528 if (!skb) { 6529 rtw89_err(rtwdev, "failed to alloc skb for h2c RF TXGAPK\n"); 6530 return -ENOMEM; 6531 } 6532 skb_put(skb, len); 6533 h2c = (struct rtw89_h2c_rf_txgapk *)skb->data; 6534 6535 h2c->len = len; 6536 h2c->ktype = 2; 6537 h2c->phy = phy_idx; 6538 h2c->kpath = RF_AB; 6539 h2c->band = chan->band_type; 6540 h2c->bw = chan->band_width; 6541 h2c->ch = chan->channel; 6542 h2c->cv = hal->cv; 6543 6544 rtw89_h2c_pkt_set_hdr(rtwdev, skb, FWCMD_TYPE_H2C, 6545 H2C_CAT_OUTSRC, H2C_CL_OUTSRC_RF_FW_RFK, 6546 H2C_FUNC_RFK_TXGAPK_OFFLOAD, 0, 0, len); 6547 6548 ret = rtw89_h2c_tx(rtwdev, skb, false); 6549 if (ret) { 6550 rtw89_err(rtwdev, "failed to send h2c\n"); 6551 goto fail; 6552 } 6553 6554 return 0; 6555 fail: 6556 dev_kfree_skb_any(skb); 6557 6558 return ret; 6559 } 6560 6561 int rtw89_fw_h2c_rf_dack(struct rtw89_dev *rtwdev, enum rtw89_phy_idx phy_idx, 6562 const struct rtw89_chan *chan) 6563 { 6564 struct rtw89_h2c_rf_dack *h2c; 6565 u32 len = sizeof(*h2c); 6566 struct sk_buff *skb; 6567 int ret; 6568 6569 skb = rtw89_fw_h2c_alloc_skb_with_hdr(rtwdev, len); 6570 if (!skb) { 6571 rtw89_err(rtwdev, "failed to alloc skb for h2c RF DACK\n"); 6572 return -ENOMEM; 6573 } 6574 skb_put(skb, len); 6575 h2c = (struct rtw89_h2c_rf_dack *)skb->data; 6576 6577 h2c->len = cpu_to_le32(len); 6578 h2c->phy = cpu_to_le32(phy_idx); 6579 h2c->type = cpu_to_le32(0); 6580 6581 rtw89_h2c_pkt_set_hdr(rtwdev, skb, FWCMD_TYPE_H2C, 6582 H2C_CAT_OUTSRC, H2C_CL_OUTSRC_RF_FW_RFK, 6583 H2C_FUNC_RFK_DACK_OFFLOAD, 0, 0, len); 6584 6585 ret = rtw89_h2c_tx(rtwdev, skb, false); 6586 if (ret) { 6587 rtw89_err(rtwdev, "failed to send h2c\n"); 6588 goto fail; 6589 } 6590 6591 return 0; 6592 fail: 6593 dev_kfree_skb_any(skb); 6594 6595 return ret; 6596 } 6597 6598 int rtw89_fw_h2c_rf_rxdck(struct rtw89_dev *rtwdev, enum rtw89_phy_idx phy_idx, 6599 const struct rtw89_chan *chan, bool is_chl_k) 6600 { 6601 struct rtw89_h2c_rf_rxdck_v0 *v0; 6602 struct rtw89_h2c_rf_rxdck *h2c; 6603 u32 len = sizeof(*h2c); 6604 struct sk_buff *skb; 6605 int ver = -1; 6606 int ret; 6607 6608 if (RTW89_CHK_FW_FEATURE(RFK_RXDCK_V0, &rtwdev->fw)) { 6609 len = sizeof(*v0); 6610 ver = 0; 6611 } 6612 6613 skb = rtw89_fw_h2c_alloc_skb_with_hdr(rtwdev, len); 6614 if (!skb) { 6615 rtw89_err(rtwdev, "failed to alloc skb for h2c RF RXDCK\n"); 6616 return -ENOMEM; 6617 } 6618 skb_put(skb, len); 6619 v0 = (struct rtw89_h2c_rf_rxdck_v0 *)skb->data; 6620 6621 v0->len = len; 6622 v0->phy = phy_idx; 6623 v0->is_afe = false; 6624 v0->kpath = RF_AB; 6625 v0->cur_band = chan->band_type; 6626 v0->cur_bw = chan->band_width; 6627 v0->cur_ch = chan->channel; 6628 v0->rxdck_dbg_en = rtw89_debug_is_enabled(rtwdev, RTW89_DBG_RFK); 6629 6630 if (ver == 0) 6631 goto hdr; 6632 6633 h2c = (struct rtw89_h2c_rf_rxdck *)skb->data; 6634 h2c->is_chl_k = is_chl_k; 6635 6636 hdr: 6637 rtw89_h2c_pkt_set_hdr(rtwdev, skb, FWCMD_TYPE_H2C, 6638 H2C_CAT_OUTSRC, H2C_CL_OUTSRC_RF_FW_RFK, 6639 H2C_FUNC_RFK_RXDCK_OFFLOAD, 0, 0, len); 6640 6641 ret = rtw89_h2c_tx(rtwdev, skb, false); 6642 if (ret) { 6643 rtw89_err(rtwdev, "failed to send h2c\n"); 6644 goto fail; 6645 } 6646 6647 return 0; 6648 fail: 6649 dev_kfree_skb_any(skb); 6650 6651 return ret; 6652 } 6653 6654 int rtw89_fw_h2c_raw_with_hdr(struct rtw89_dev *rtwdev, 6655 u8 h2c_class, u8 h2c_func, u8 *buf, u16 len, 6656 bool rack, bool dack) 6657 { 6658 struct sk_buff *skb; 6659 int ret; 6660 6661 skb = rtw89_fw_h2c_alloc_skb_with_hdr(rtwdev, len); 6662 if (!skb) { 6663 rtw89_err(rtwdev, "failed to alloc skb for raw with hdr\n"); 6664 return -ENOMEM; 6665 } 6666 skb_put_data(skb, buf, len); 6667 6668 rtw89_h2c_pkt_set_hdr(rtwdev, skb, FWCMD_TYPE_H2C, 6669 H2C_CAT_OUTSRC, h2c_class, h2c_func, rack, dack, 6670 len); 6671 6672 ret = rtw89_h2c_tx(rtwdev, skb, false); 6673 if (ret) { 6674 rtw89_err(rtwdev, "failed to send h2c\n"); 6675 goto fail; 6676 } 6677 6678 return 0; 6679 fail: 6680 dev_kfree_skb_any(skb); 6681 6682 return ret; 6683 } 6684 6685 int rtw89_fw_h2c_raw(struct rtw89_dev *rtwdev, const u8 *buf, u16 len) 6686 { 6687 struct sk_buff *skb; 6688 int ret; 6689 6690 skb = rtw89_fw_h2c_alloc_skb_no_hdr(rtwdev, len); 6691 if (!skb) { 6692 rtw89_err(rtwdev, "failed to alloc skb for h2c raw\n"); 6693 return -ENOMEM; 6694 } 6695 skb_put_data(skb, buf, len); 6696 6697 ret = rtw89_h2c_tx(rtwdev, skb, false); 6698 if (ret) { 6699 rtw89_err(rtwdev, "failed to send h2c\n"); 6700 goto fail; 6701 } 6702 6703 return 0; 6704 fail: 6705 dev_kfree_skb_any(skb); 6706 6707 return ret; 6708 } 6709 6710 void rtw89_fw_send_all_early_h2c(struct rtw89_dev *rtwdev) 6711 { 6712 struct rtw89_early_h2c *early_h2c; 6713 6714 lockdep_assert_wiphy(rtwdev->hw->wiphy); 6715 6716 list_for_each_entry(early_h2c, &rtwdev->early_h2c_list, list) { 6717 rtw89_fw_h2c_raw(rtwdev, early_h2c->h2c, early_h2c->h2c_len); 6718 } 6719 } 6720 6721 void __rtw89_fw_free_all_early_h2c(struct rtw89_dev *rtwdev) 6722 { 6723 struct rtw89_early_h2c *early_h2c, *tmp; 6724 6725 list_for_each_entry_safe(early_h2c, tmp, &rtwdev->early_h2c_list, list) { 6726 list_del(&early_h2c->list); 6727 kfree(early_h2c->h2c); 6728 kfree(early_h2c); 6729 } 6730 } 6731 6732 void rtw89_fw_free_all_early_h2c(struct rtw89_dev *rtwdev) 6733 { 6734 lockdep_assert_wiphy(rtwdev->hw->wiphy); 6735 6736 __rtw89_fw_free_all_early_h2c(rtwdev); 6737 } 6738 6739 static void rtw89_fw_c2h_parse_attr(struct sk_buff *c2h) 6740 { 6741 const struct rtw89_c2h_hdr *hdr = (const struct rtw89_c2h_hdr *)c2h->data; 6742 struct rtw89_fw_c2h_attr *attr = RTW89_SKB_C2H_CB(c2h); 6743 6744 attr->category = le32_get_bits(hdr->w0, RTW89_C2H_HDR_W0_CATEGORY); 6745 attr->class = le32_get_bits(hdr->w0, RTW89_C2H_HDR_W0_CLASS); 6746 attr->func = le32_get_bits(hdr->w0, RTW89_C2H_HDR_W0_FUNC); 6747 attr->len = le32_get_bits(hdr->w1, RTW89_C2H_HDR_W1_LEN); 6748 } 6749 6750 static bool rtw89_fw_c2h_chk_atomic(struct rtw89_dev *rtwdev, 6751 struct sk_buff *c2h) 6752 { 6753 struct rtw89_fw_c2h_attr *attr = RTW89_SKB_C2H_CB(c2h); 6754 u8 category = attr->category; 6755 u8 class = attr->class; 6756 u8 func = attr->func; 6757 6758 switch (category) { 6759 default: 6760 return false; 6761 case RTW89_C2H_CAT_MAC: 6762 return rtw89_mac_c2h_chk_atomic(rtwdev, c2h, class, func); 6763 case RTW89_C2H_CAT_OUTSRC: 6764 return rtw89_phy_c2h_chk_atomic(rtwdev, class, func); 6765 } 6766 } 6767 6768 void rtw89_fw_c2h_irqsafe(struct rtw89_dev *rtwdev, struct sk_buff *c2h) 6769 { 6770 rtw89_fw_c2h_parse_attr(c2h); 6771 if (!rtw89_fw_c2h_chk_atomic(rtwdev, c2h)) 6772 goto enqueue; 6773 6774 rtw89_fw_c2h_cmd_handle(rtwdev, c2h); 6775 dev_kfree_skb_any(c2h); 6776 return; 6777 6778 enqueue: 6779 skb_queue_tail(&rtwdev->c2h_queue, c2h); 6780 wiphy_work_queue(rtwdev->hw->wiphy, &rtwdev->c2h_work); 6781 } 6782 6783 static void rtw89_fw_c2h_cmd_handle(struct rtw89_dev *rtwdev, 6784 struct sk_buff *skb) 6785 { 6786 struct rtw89_fw_c2h_attr *attr = RTW89_SKB_C2H_CB(skb); 6787 u8 category = attr->category; 6788 u8 class = attr->class; 6789 u8 func = attr->func; 6790 u16 len = attr->len; 6791 bool dump = true; 6792 6793 if (!test_bit(RTW89_FLAG_RUNNING, rtwdev->flags)) 6794 return; 6795 6796 switch (category) { 6797 case RTW89_C2H_CAT_TEST: 6798 break; 6799 case RTW89_C2H_CAT_MAC: 6800 rtw89_mac_c2h_handle(rtwdev, skb, len, class, func); 6801 if (class == RTW89_MAC_C2H_CLASS_INFO && 6802 func == RTW89_MAC_C2H_FUNC_C2H_LOG) 6803 dump = false; 6804 break; 6805 case RTW89_C2H_CAT_OUTSRC: 6806 if (class >= RTW89_PHY_C2H_CLASS_BTC_MIN && 6807 class <= RTW89_PHY_C2H_CLASS_BTC_MAX) 6808 rtw89_btc_c2h_handle(rtwdev, skb, len, class, func); 6809 else 6810 rtw89_phy_c2h_handle(rtwdev, skb, len, class, func); 6811 break; 6812 } 6813 6814 if (dump) 6815 rtw89_hex_dump(rtwdev, RTW89_DBG_FW, "C2H: ", skb->data, skb->len); 6816 } 6817 6818 void rtw89_fw_c2h_work(struct wiphy *wiphy, struct wiphy_work *work) 6819 { 6820 struct rtw89_dev *rtwdev = container_of(work, struct rtw89_dev, 6821 c2h_work); 6822 struct sk_buff *skb, *tmp; 6823 6824 lockdep_assert_wiphy(rtwdev->hw->wiphy); 6825 6826 skb_queue_walk_safe(&rtwdev->c2h_queue, skb, tmp) { 6827 skb_unlink(skb, &rtwdev->c2h_queue); 6828 rtw89_fw_c2h_cmd_handle(rtwdev, skb); 6829 dev_kfree_skb_any(skb); 6830 } 6831 } 6832 6833 void rtw89_fw_c2h_purge_obsoleted_scan_events(struct rtw89_dev *rtwdev) 6834 { 6835 struct rtw89_hw_scan_info *scan_info = &rtwdev->scan_info; 6836 struct sk_buff *skb, *tmp; 6837 int limit; 6838 6839 lockdep_assert_wiphy(rtwdev->hw->wiphy); 6840 6841 limit = skb_queue_len(&rtwdev->c2h_queue); 6842 6843 skb_queue_walk_safe(&rtwdev->c2h_queue, skb, tmp) { 6844 struct rtw89_fw_c2h_attr *attr = RTW89_SKB_C2H_CB(skb); 6845 6846 if (--limit < 0) 6847 return; 6848 6849 if (!attr->is_scan_event || attr->scan_seq == scan_info->seq) 6850 continue; 6851 6852 rtw89_debug(rtwdev, RTW89_DBG_HW_SCAN, 6853 "purge obsoleted scan event with seq=%d (cur=%d)\n", 6854 attr->scan_seq, scan_info->seq); 6855 6856 skb_unlink(skb, &rtwdev->c2h_queue); 6857 dev_kfree_skb_any(skb); 6858 } 6859 } 6860 6861 static int rtw89_fw_write_h2c_reg(struct rtw89_dev *rtwdev, 6862 struct rtw89_mac_h2c_info *info) 6863 { 6864 const struct rtw89_chip_info *chip = rtwdev->chip; 6865 struct rtw89_fw_info *fw_info = &rtwdev->fw; 6866 const u32 *h2c_reg = chip->h2c_regs; 6867 u8 i, val, len; 6868 int ret; 6869 6870 ret = read_poll_timeout(rtw89_read8, val, val == 0, 1000, 5000, false, 6871 rtwdev, chip->h2c_ctrl_reg); 6872 if (ret) { 6873 rtw89_warn(rtwdev, "FW does not process h2c registers\n"); 6874 return ret; 6875 } 6876 6877 len = DIV_ROUND_UP(info->content_len + RTW89_H2CREG_HDR_LEN, 6878 sizeof(info->u.h2creg[0])); 6879 6880 u32p_replace_bits(&info->u.hdr.w0, info->id, RTW89_H2CREG_HDR_FUNC_MASK); 6881 u32p_replace_bits(&info->u.hdr.w0, len, RTW89_H2CREG_HDR_LEN_MASK); 6882 6883 for (i = 0; i < RTW89_H2CREG_MAX; i++) 6884 rtw89_write32(rtwdev, h2c_reg[i], info->u.h2creg[i]); 6885 6886 fw_info->h2c_counter++; 6887 rtw89_write8_mask(rtwdev, chip->h2c_counter_reg.addr, 6888 chip->h2c_counter_reg.mask, fw_info->h2c_counter); 6889 rtw89_write8(rtwdev, chip->h2c_ctrl_reg, B_AX_H2CREG_TRIGGER); 6890 6891 return 0; 6892 } 6893 6894 static int rtw89_fw_read_c2h_reg(struct rtw89_dev *rtwdev, 6895 struct rtw89_mac_c2h_info *info) 6896 { 6897 const struct rtw89_chip_info *chip = rtwdev->chip; 6898 struct rtw89_fw_info *fw_info = &rtwdev->fw; 6899 const u32 *c2h_reg = chip->c2h_regs; 6900 u32 ret, timeout; 6901 u8 i, val; 6902 6903 info->id = RTW89_FWCMD_C2HREG_FUNC_NULL; 6904 6905 if (rtwdev->hci.type == RTW89_HCI_TYPE_USB) 6906 timeout = RTW89_C2H_TIMEOUT_USB; 6907 else 6908 timeout = RTW89_C2H_TIMEOUT; 6909 6910 ret = read_poll_timeout_atomic(rtw89_read8, val, val, 1, 6911 timeout, false, rtwdev, 6912 chip->c2h_ctrl_reg); 6913 if (ret) { 6914 rtw89_warn(rtwdev, "c2h reg timeout\n"); 6915 return ret; 6916 } 6917 6918 for (i = 0; i < RTW89_C2HREG_MAX; i++) 6919 info->u.c2hreg[i] = rtw89_read32(rtwdev, c2h_reg[i]); 6920 6921 rtw89_write8(rtwdev, chip->c2h_ctrl_reg, 0); 6922 6923 info->id = u32_get_bits(info->u.hdr.w0, RTW89_C2HREG_HDR_FUNC_MASK); 6924 info->content_len = 6925 (u32_get_bits(info->u.hdr.w0, RTW89_C2HREG_HDR_LEN_MASK) << 2) - 6926 RTW89_C2HREG_HDR_LEN; 6927 6928 fw_info->c2h_counter++; 6929 rtw89_write8_mask(rtwdev, chip->c2h_counter_reg.addr, 6930 chip->c2h_counter_reg.mask, fw_info->c2h_counter); 6931 6932 return 0; 6933 } 6934 6935 int rtw89_fw_msg_reg(struct rtw89_dev *rtwdev, 6936 struct rtw89_mac_h2c_info *h2c_info, 6937 struct rtw89_mac_c2h_info *c2h_info) 6938 { 6939 u32 ret; 6940 6941 if (h2c_info && h2c_info->id != RTW89_FWCMD_H2CREG_FUNC_GET_FEATURE) 6942 lockdep_assert_wiphy(rtwdev->hw->wiphy); 6943 6944 if (!h2c_info && !c2h_info) 6945 return -EINVAL; 6946 6947 if (!h2c_info) 6948 goto recv_c2h; 6949 6950 ret = rtw89_fw_write_h2c_reg(rtwdev, h2c_info); 6951 if (ret) 6952 return ret; 6953 6954 recv_c2h: 6955 if (!c2h_info) 6956 return 0; 6957 6958 ret = rtw89_fw_read_c2h_reg(rtwdev, c2h_info); 6959 if (ret) 6960 return ret; 6961 6962 return 0; 6963 } 6964 6965 void rtw89_fw_st_dbg_dump(struct rtw89_dev *rtwdev) 6966 { 6967 if (!test_bit(RTW89_FLAG_POWERON, rtwdev->flags)) { 6968 rtw89_err(rtwdev, "[ERR]pwr is off\n"); 6969 return; 6970 } 6971 6972 rtw89_info(rtwdev, "FW status = 0x%x\n", rtw89_read32(rtwdev, R_AX_UDM0)); 6973 rtw89_info(rtwdev, "FW BADADDR = 0x%x\n", rtw89_read32(rtwdev, R_AX_UDM1)); 6974 rtw89_info(rtwdev, "FW EPC/RA = 0x%x\n", rtw89_read32(rtwdev, R_AX_UDM2)); 6975 rtw89_info(rtwdev, "FW MISC = 0x%x\n", rtw89_read32(rtwdev, R_AX_UDM3)); 6976 rtw89_info(rtwdev, "R_AX_HALT_C2H = 0x%x\n", 6977 rtw89_read32(rtwdev, R_AX_HALT_C2H)); 6978 rtw89_info(rtwdev, "R_AX_SER_DBG_INFO = 0x%x\n", 6979 rtw89_read32(rtwdev, R_AX_SER_DBG_INFO)); 6980 6981 rtw89_fw_prog_cnt_dump(rtwdev); 6982 } 6983 6984 static void rtw89_hw_scan_release_pkt_list(struct rtw89_dev *rtwdev) 6985 { 6986 struct list_head *pkt_list = rtwdev->scan_info.pkt_list; 6987 struct rtw89_pktofld_info *info, *tmp; 6988 u8 idx; 6989 6990 for (idx = NL80211_BAND_2GHZ; idx < NUM_NL80211_BANDS; idx++) { 6991 if (!(rtwdev->chip->support_bands & BIT(idx))) 6992 continue; 6993 6994 list_for_each_entry_safe(info, tmp, &pkt_list[idx], list) { 6995 if (test_bit(info->id, rtwdev->pkt_offload)) 6996 rtw89_fw_h2c_del_pkt_offload(rtwdev, info->id); 6997 list_del(&info->list); 6998 kfree(info); 6999 } 7000 } 7001 } 7002 7003 static void rtw89_hw_scan_cleanup(struct rtw89_dev *rtwdev, 7004 struct rtw89_vif_link *rtwvif_link) 7005 { 7006 const struct rtw89_mac_gen_def *mac = rtwdev->chip->mac_def; 7007 struct rtw89_hw_scan_info *scan_info = &rtwdev->scan_info; 7008 struct rtw89_vif *rtwvif = rtwvif_link->rtwvif; 7009 7010 mac->free_chan_list(rtwdev); 7011 rtw89_hw_scan_release_pkt_list(rtwdev); 7012 7013 rtwvif->scan_req = NULL; 7014 rtwvif->scan_ies = NULL; 7015 scan_info->scanning_vif = NULL; 7016 scan_info->abort = false; 7017 scan_info->connected = false; 7018 scan_info->delay = 0; 7019 } 7020 7021 static bool rtw89_is_6ghz_wildcard_probe_req(struct rtw89_dev *rtwdev, 7022 struct cfg80211_scan_request *req, 7023 struct rtw89_pktofld_info *info, 7024 enum nl80211_band band, u8 ssid_idx) 7025 { 7026 if (band != NL80211_BAND_6GHZ) 7027 return false; 7028 7029 if (req->ssids[ssid_idx].ssid_len) { 7030 memcpy(info->ssid, req->ssids[ssid_idx].ssid, 7031 req->ssids[ssid_idx].ssid_len); 7032 info->ssid_len = req->ssids[ssid_idx].ssid_len; 7033 return false; 7034 } else { 7035 info->wildcard_6ghz = true; 7036 return true; 7037 } 7038 } 7039 7040 static int rtw89_append_probe_req_ie(struct rtw89_dev *rtwdev, 7041 struct rtw89_vif_link *rtwvif_link, 7042 struct sk_buff *skb, u8 ssid_idx) 7043 { 7044 struct rtw89_hw_scan_info *scan_info = &rtwdev->scan_info; 7045 struct rtw89_vif *rtwvif = rtwvif_link->rtwvif; 7046 struct ieee80211_scan_ies *ies = rtwvif->scan_ies; 7047 struct cfg80211_scan_request *req = rtwvif->scan_req; 7048 struct rtw89_pktofld_info *info; 7049 struct sk_buff *new; 7050 int ret = 0; 7051 u8 band; 7052 7053 for (band = NL80211_BAND_2GHZ; band < NUM_NL80211_BANDS; band++) { 7054 if (!(rtwdev->chip->support_bands & BIT(band))) 7055 continue; 7056 7057 new = skb_copy(skb, GFP_KERNEL); 7058 if (!new) { 7059 ret = -ENOMEM; 7060 goto out; 7061 } 7062 skb_put_data(new, ies->ies[band], ies->len[band]); 7063 skb_put_data(new, ies->common_ies, ies->common_ie_len); 7064 7065 info = kzalloc(sizeof(*info), GFP_KERNEL); 7066 if (!info) { 7067 ret = -ENOMEM; 7068 kfree_skb(new); 7069 goto out; 7070 } 7071 7072 rtw89_is_6ghz_wildcard_probe_req(rtwdev, req, info, band, ssid_idx); 7073 7074 ret = rtw89_fw_h2c_add_pkt_offload(rtwdev, &info->id, new); 7075 if (ret) { 7076 kfree_skb(new); 7077 kfree(info); 7078 goto out; 7079 } 7080 7081 list_add_tail(&info->list, &scan_info->pkt_list[band]); 7082 kfree_skb(new); 7083 } 7084 out: 7085 return ret; 7086 } 7087 7088 static int rtw89_hw_scan_update_probe_req(struct rtw89_dev *rtwdev, 7089 struct rtw89_vif_link *rtwvif_link, 7090 const u8 *mac_addr) 7091 { 7092 struct rtw89_vif *rtwvif = rtwvif_link->rtwvif; 7093 struct cfg80211_scan_request *req = rtwvif->scan_req; 7094 struct sk_buff *skb; 7095 u8 num = req->n_ssids, i; 7096 int ret; 7097 7098 for (i = 0; i < num; i++) { 7099 skb = ieee80211_probereq_get(rtwdev->hw, mac_addr, 7100 req->ssids[i].ssid, 7101 req->ssids[i].ssid_len, 7102 req->ie_len); 7103 if (!skb) 7104 return -ENOMEM; 7105 7106 ret = rtw89_append_probe_req_ie(rtwdev, rtwvif_link, skb, i); 7107 kfree_skb(skb); 7108 7109 if (ret) 7110 return ret; 7111 } 7112 7113 return 0; 7114 } 7115 7116 static int rtw89_update_6ghz_rnr_chan_ax(struct rtw89_dev *rtwdev, 7117 struct ieee80211_scan_ies *ies, 7118 struct cfg80211_scan_request *req, 7119 struct rtw89_mac_chinfo_ax *ch_info) 7120 { 7121 struct rtw89_vif_link *rtwvif_link = rtwdev->scan_info.scanning_vif; 7122 struct list_head *pkt_list = rtwdev->scan_info.pkt_list; 7123 struct cfg80211_scan_6ghz_params *params; 7124 struct rtw89_pktofld_info *info, *tmp; 7125 struct ieee80211_hdr *hdr; 7126 struct sk_buff *skb; 7127 bool found; 7128 int ret = 0; 7129 u8 i; 7130 7131 if (!req->n_6ghz_params) 7132 return 0; 7133 7134 for (i = 0; i < req->n_6ghz_params; i++) { 7135 params = &req->scan_6ghz_params[i]; 7136 7137 if (req->channels[params->channel_idx]->hw_value != 7138 ch_info->pri_ch) 7139 continue; 7140 7141 found = false; 7142 list_for_each_entry(tmp, &pkt_list[NL80211_BAND_6GHZ], list) { 7143 if (ether_addr_equal(tmp->bssid, params->bssid)) { 7144 found = true; 7145 break; 7146 } 7147 } 7148 if (found) 7149 continue; 7150 7151 skb = ieee80211_probereq_get(rtwdev->hw, rtwvif_link->mac_addr, 7152 NULL, 0, req->ie_len); 7153 if (!skb) 7154 return -ENOMEM; 7155 7156 skb_put_data(skb, ies->ies[NL80211_BAND_6GHZ], ies->len[NL80211_BAND_6GHZ]); 7157 skb_put_data(skb, ies->common_ies, ies->common_ie_len); 7158 hdr = (struct ieee80211_hdr *)skb->data; 7159 ether_addr_copy(hdr->addr3, params->bssid); 7160 7161 info = kzalloc(sizeof(*info), GFP_KERNEL); 7162 if (!info) { 7163 ret = -ENOMEM; 7164 kfree_skb(skb); 7165 goto out; 7166 } 7167 7168 ret = rtw89_fw_h2c_add_pkt_offload(rtwdev, &info->id, skb); 7169 if (ret) { 7170 kfree_skb(skb); 7171 kfree(info); 7172 goto out; 7173 } 7174 7175 ether_addr_copy(info->bssid, params->bssid); 7176 info->channel_6ghz = req->channels[params->channel_idx]->hw_value; 7177 list_add_tail(&info->list, &rtwdev->scan_info.pkt_list[NL80211_BAND_6GHZ]); 7178 7179 ch_info->tx_pkt = true; 7180 ch_info->period = RTW89_CHANNEL_TIME_6G + RTW89_DWELL_TIME_6G; 7181 7182 kfree_skb(skb); 7183 } 7184 7185 out: 7186 return ret; 7187 } 7188 7189 static void rtw89_pno_scan_add_chan_ax(struct rtw89_dev *rtwdev, 7190 int chan_type, int ssid_num, 7191 struct rtw89_mac_chinfo_ax *ch_info) 7192 { 7193 struct rtw89_wow_param *rtw_wow = &rtwdev->wow; 7194 struct rtw89_pktofld_info *info; 7195 u8 probe_count = 0; 7196 7197 ch_info->notify_action = RTW89_SCANOFLD_DEBUG_MASK; 7198 ch_info->dfs_ch = chan_type == RTW89_CHAN_DFS; 7199 ch_info->bw = RTW89_SCAN_WIDTH; 7200 ch_info->tx_pkt = true; 7201 ch_info->cfg_tx_pwr = false; 7202 ch_info->tx_pwr_idx = 0; 7203 ch_info->tx_null = false; 7204 ch_info->pause_data = false; 7205 ch_info->probe_id = RTW89_SCANOFLD_PKT_NONE; 7206 7207 if (ssid_num) { 7208 list_for_each_entry(info, &rtw_wow->pno_pkt_list, list) { 7209 if (info->channel_6ghz && 7210 ch_info->pri_ch != info->channel_6ghz) 7211 continue; 7212 else if (info->channel_6ghz && probe_count != 0) 7213 ch_info->period += RTW89_CHANNEL_TIME_6G; 7214 7215 if (info->wildcard_6ghz) 7216 continue; 7217 7218 ch_info->pkt_id[probe_count++] = info->id; 7219 if (probe_count >= RTW89_SCANOFLD_MAX_SSID) 7220 break; 7221 } 7222 ch_info->num_pkt = probe_count; 7223 } 7224 7225 switch (chan_type) { 7226 case RTW89_CHAN_DFS: 7227 if (ch_info->ch_band != RTW89_BAND_6G) 7228 ch_info->period = max_t(u8, ch_info->period, 7229 RTW89_DFS_CHAN_TIME); 7230 ch_info->dwell_time = RTW89_DWELL_TIME; 7231 break; 7232 case RTW89_CHAN_ACTIVE: 7233 break; 7234 default: 7235 rtw89_err(rtwdev, "Channel type out of bound\n"); 7236 } 7237 } 7238 7239 static void rtw89_hw_scan_add_chan_ax(struct rtw89_dev *rtwdev, int chan_type, 7240 int ssid_num, 7241 struct rtw89_mac_chinfo_ax *ch_info) 7242 { 7243 struct rtw89_hw_scan_info *scan_info = &rtwdev->scan_info; 7244 struct rtw89_vif_link *rtwvif_link = rtwdev->scan_info.scanning_vif; 7245 const struct rtw89_hw_scan_extra_op *ext = &scan_info->extra_op; 7246 struct rtw89_vif *rtwvif = rtwvif_link->rtwvif; 7247 struct ieee80211_scan_ies *ies = rtwvif->scan_ies; 7248 struct cfg80211_scan_request *req = rtwvif->scan_req; 7249 struct rtw89_chan *op = &rtwdev->scan_info.op_chan; 7250 struct rtw89_pktofld_info *info; 7251 u8 band, probe_count = 0; 7252 int ret; 7253 7254 ch_info->notify_action = RTW89_SCANOFLD_DEBUG_MASK; 7255 ch_info->dfs_ch = chan_type == RTW89_CHAN_DFS; 7256 ch_info->bw = RTW89_SCAN_WIDTH; 7257 ch_info->tx_pkt = true; 7258 ch_info->cfg_tx_pwr = false; 7259 ch_info->tx_pwr_idx = 0; 7260 ch_info->tx_null = false; 7261 ch_info->pause_data = false; 7262 ch_info->probe_id = RTW89_SCANOFLD_PKT_NONE; 7263 7264 if (ch_info->ch_band == RTW89_BAND_6G) { 7265 if ((ssid_num == 1 && req->ssids[0].ssid_len == 0) || 7266 !ch_info->is_psc) { 7267 ch_info->tx_pkt = false; 7268 if (!req->duration_mandatory) 7269 ch_info->period -= RTW89_DWELL_TIME_6G; 7270 } 7271 } 7272 7273 ret = rtw89_update_6ghz_rnr_chan_ax(rtwdev, ies, req, ch_info); 7274 if (ret) 7275 rtw89_warn(rtwdev, "RNR fails: %d\n", ret); 7276 7277 if (ssid_num) { 7278 band = rtw89_hw_to_nl80211_band(ch_info->ch_band); 7279 7280 list_for_each_entry(info, &scan_info->pkt_list[band], list) { 7281 if (info->channel_6ghz && 7282 ch_info->pri_ch != info->channel_6ghz) 7283 continue; 7284 else if (info->channel_6ghz && probe_count != 0) 7285 ch_info->period += RTW89_CHANNEL_TIME_6G; 7286 7287 if (info->wildcard_6ghz) 7288 continue; 7289 7290 ch_info->pkt_id[probe_count++] = info->id; 7291 if (probe_count >= RTW89_SCANOFLD_MAX_SSID) 7292 break; 7293 } 7294 ch_info->num_pkt = probe_count; 7295 } 7296 7297 switch (chan_type) { 7298 case RTW89_CHAN_OPERATE: 7299 ch_info->central_ch = op->channel; 7300 ch_info->pri_ch = op->primary_channel; 7301 ch_info->ch_band = op->band_type; 7302 ch_info->bw = op->band_width; 7303 ch_info->tx_null = true; 7304 ch_info->num_pkt = 0; 7305 break; 7306 case RTW89_CHAN_DFS: 7307 if (ch_info->ch_band != RTW89_BAND_6G) 7308 ch_info->period = max_t(u8, ch_info->period, 7309 RTW89_DFS_CHAN_TIME); 7310 ch_info->dwell_time = RTW89_DWELL_TIME; 7311 ch_info->pause_data = true; 7312 break; 7313 case RTW89_CHAN_ACTIVE: 7314 ch_info->pause_data = true; 7315 break; 7316 case RTW89_CHAN_EXTRA_OP: 7317 ch_info->central_ch = ext->chan.channel; 7318 ch_info->pri_ch = ext->chan.primary_channel; 7319 ch_info->ch_band = ext->chan.band_type; 7320 ch_info->bw = ext->chan.band_width; 7321 ch_info->tx_null = true; 7322 ch_info->num_pkt = 0; 7323 ch_info->macid_tx = true; 7324 break; 7325 default: 7326 rtw89_err(rtwdev, "Channel type out of bound\n"); 7327 } 7328 } 7329 7330 static void rtw89_pno_scan_add_chan_be(struct rtw89_dev *rtwdev, int chan_type, 7331 int ssid_num, 7332 struct rtw89_mac_chinfo_be *ch_info) 7333 { 7334 struct rtw89_wow_param *rtw_wow = &rtwdev->wow; 7335 struct rtw89_pktofld_info *info; 7336 u8 probe_count = 0, i; 7337 7338 ch_info->notify_action = RTW89_SCANOFLD_DEBUG_MASK; 7339 ch_info->dfs_ch = chan_type == RTW89_CHAN_DFS; 7340 ch_info->bw = RTW89_SCAN_WIDTH; 7341 ch_info->tx_null = false; 7342 ch_info->pause_data = false; 7343 ch_info->probe_id = RTW89_SCANOFLD_PKT_NONE; 7344 7345 if (ssid_num) { 7346 list_for_each_entry(info, &rtw_wow->pno_pkt_list, list) { 7347 ch_info->pkt_id[probe_count++] = info->id; 7348 if (probe_count >= RTW89_SCANOFLD_MAX_SSID) 7349 break; 7350 } 7351 } 7352 7353 for (i = probe_count; i < RTW89_SCANOFLD_MAX_SSID; i++) 7354 ch_info->pkt_id[i] = RTW89_SCANOFLD_PKT_NONE; 7355 7356 switch (chan_type) { 7357 case RTW89_CHAN_DFS: 7358 ch_info->period = max_t(u8, ch_info->period, RTW89_DFS_CHAN_TIME); 7359 ch_info->dwell_time = RTW89_DWELL_TIME; 7360 break; 7361 case RTW89_CHAN_ACTIVE: 7362 break; 7363 default: 7364 rtw89_warn(rtwdev, "Channel type out of bound\n"); 7365 break; 7366 } 7367 } 7368 7369 static void rtw89_hw_scan_add_chan_be(struct rtw89_dev *rtwdev, int chan_type, 7370 int ssid_num, 7371 struct rtw89_mac_chinfo_be *ch_info) 7372 { 7373 struct rtw89_hw_scan_info *scan_info = &rtwdev->scan_info; 7374 struct rtw89_vif_link *rtwvif_link = rtwdev->scan_info.scanning_vif; 7375 struct rtw89_vif *rtwvif = rtwvif_link->rtwvif; 7376 struct cfg80211_scan_request *req = rtwvif->scan_req; 7377 struct rtw89_pktofld_info *info; 7378 u8 band, probe_count = 0, i; 7379 7380 ch_info->notify_action = RTW89_SCANOFLD_DEBUG_MASK; 7381 ch_info->dfs_ch = chan_type == RTW89_CHAN_DFS; 7382 ch_info->bw = RTW89_SCAN_WIDTH; 7383 ch_info->tx_null = false; 7384 ch_info->pause_data = false; 7385 ch_info->probe_id = RTW89_SCANOFLD_PKT_NONE; 7386 7387 if (ssid_num) { 7388 band = rtw89_hw_to_nl80211_band(ch_info->ch_band); 7389 7390 list_for_each_entry(info, &scan_info->pkt_list[band], list) { 7391 if (info->channel_6ghz && 7392 ch_info->pri_ch != info->channel_6ghz) 7393 continue; 7394 7395 if (info->wildcard_6ghz) 7396 continue; 7397 7398 ch_info->pkt_id[probe_count++] = info->id; 7399 if (probe_count >= RTW89_SCANOFLD_MAX_SSID) 7400 break; 7401 } 7402 } 7403 7404 if (ch_info->ch_band == RTW89_BAND_6G) { 7405 if ((ssid_num == 1 && req->ssids[0].ssid_len == 0) || 7406 !ch_info->is_psc) { 7407 ch_info->probe_id = RTW89_SCANOFLD_PKT_NONE; 7408 if (!req->duration_mandatory) 7409 ch_info->period -= RTW89_DWELL_TIME_6G; 7410 } 7411 } 7412 7413 for (i = probe_count; i < RTW89_SCANOFLD_MAX_SSID; i++) 7414 ch_info->pkt_id[i] = RTW89_SCANOFLD_PKT_NONE; 7415 7416 switch (chan_type) { 7417 case RTW89_CHAN_DFS: 7418 if (ch_info->ch_band != RTW89_BAND_6G) 7419 ch_info->period = 7420 max_t(u8, ch_info->period, RTW89_DFS_CHAN_TIME); 7421 ch_info->dwell_time = RTW89_DWELL_TIME; 7422 ch_info->pause_data = true; 7423 break; 7424 case RTW89_CHAN_ACTIVE: 7425 ch_info->pause_data = true; 7426 break; 7427 default: 7428 rtw89_warn(rtwdev, "Channel type out of bound\n"); 7429 break; 7430 } 7431 } 7432 7433 int rtw89_pno_scan_add_chan_list_ax(struct rtw89_dev *rtwdev, 7434 struct rtw89_vif_link *rtwvif_link) 7435 { 7436 struct rtw89_wow_param *rtw_wow = &rtwdev->wow; 7437 struct cfg80211_sched_scan_request *nd_config = rtw_wow->nd_config; 7438 struct rtw89_mac_chinfo_ax *ch_info, *tmp; 7439 struct ieee80211_channel *channel; 7440 struct list_head chan_list; 7441 int list_len; 7442 enum rtw89_chan_type type; 7443 int ret = 0; 7444 u32 idx; 7445 7446 INIT_LIST_HEAD(&chan_list); 7447 for (idx = 0, list_len = 0; 7448 idx < nd_config->n_channels && list_len < RTW89_SCAN_LIST_LIMIT_AX; 7449 idx++, list_len++) { 7450 channel = nd_config->channels[idx]; 7451 ch_info = kzalloc(sizeof(*ch_info), GFP_KERNEL); 7452 if (!ch_info) { 7453 ret = -ENOMEM; 7454 goto out; 7455 } 7456 7457 ch_info->period = RTW89_CHANNEL_TIME; 7458 ch_info->ch_band = rtw89_nl80211_to_hw_band(channel->band); 7459 ch_info->central_ch = channel->hw_value; 7460 ch_info->pri_ch = channel->hw_value; 7461 ch_info->is_psc = cfg80211_channel_is_psc(channel); 7462 7463 if (channel->flags & 7464 (IEEE80211_CHAN_RADAR | IEEE80211_CHAN_NO_IR)) 7465 type = RTW89_CHAN_DFS; 7466 else 7467 type = RTW89_CHAN_ACTIVE; 7468 7469 rtw89_pno_scan_add_chan_ax(rtwdev, type, nd_config->n_match_sets, ch_info); 7470 list_add_tail(&ch_info->list, &chan_list); 7471 } 7472 ret = rtw89_fw_h2c_scan_list_offload_ax(rtwdev, list_len, &chan_list); 7473 7474 out: 7475 list_for_each_entry_safe(ch_info, tmp, &chan_list, list) { 7476 list_del(&ch_info->list); 7477 kfree(ch_info); 7478 } 7479 7480 return ret; 7481 } 7482 7483 static int rtw89_hw_scan_add_op_types_ax(struct rtw89_dev *rtwdev, 7484 enum rtw89_chan_type type, 7485 struct list_head *chan_list, 7486 struct cfg80211_scan_request *req, 7487 int *off_chan_time) 7488 { 7489 struct rtw89_mac_chinfo_ax *tmp; 7490 7491 tmp = kzalloc(sizeof(*tmp), GFP_KERNEL); 7492 if (!tmp) 7493 return -ENOMEM; 7494 7495 switch (type) { 7496 case RTW89_CHAN_OPERATE: 7497 tmp->period = req->duration_mandatory ? 7498 req->duration : RTW89_CHANNEL_TIME; 7499 *off_chan_time = 0; 7500 break; 7501 case RTW89_CHAN_EXTRA_OP: 7502 tmp->period = RTW89_CHANNEL_TIME_EXTRA_OP; 7503 /* still calc @off_chan_time for scan op */ 7504 *off_chan_time += tmp->period; 7505 break; 7506 default: 7507 kfree(tmp); 7508 return -EINVAL; 7509 } 7510 7511 rtw89_hw_scan_add_chan_ax(rtwdev, type, 0, tmp); 7512 list_add_tail(&tmp->list, chan_list); 7513 7514 return 0; 7515 } 7516 7517 int rtw89_hw_scan_prep_chan_list_ax(struct rtw89_dev *rtwdev, 7518 struct rtw89_vif_link *rtwvif_link) 7519 { 7520 struct rtw89_hw_scan_info *scan_info = &rtwdev->scan_info; 7521 const struct rtw89_hw_scan_extra_op *ext = &scan_info->extra_op; 7522 struct rtw89_vif *rtwvif = rtwvif_link->rtwvif; 7523 struct cfg80211_scan_request *req = rtwvif->scan_req; 7524 struct rtw89_mac_chinfo_ax *ch_info, *tmp; 7525 struct ieee80211_channel *channel; 7526 struct list_head chan_list; 7527 bool random_seq = req->flags & NL80211_SCAN_FLAG_RANDOM_SN; 7528 enum rtw89_chan_type type; 7529 int off_chan_time = 0; 7530 int ret; 7531 u32 idx; 7532 7533 INIT_LIST_HEAD(&chan_list); 7534 7535 for (idx = 0; idx < req->n_channels; idx++) { 7536 channel = req->channels[idx]; 7537 ch_info = kzalloc(sizeof(*ch_info), GFP_KERNEL); 7538 if (!ch_info) { 7539 ret = -ENOMEM; 7540 goto out; 7541 } 7542 7543 if (req->duration) 7544 ch_info->period = req->duration; 7545 else if (channel->band == NL80211_BAND_6GHZ) 7546 ch_info->period = RTW89_CHANNEL_TIME_6G + 7547 RTW89_DWELL_TIME_6G; 7548 else if (rtwvif_link->wifi_role == RTW89_WIFI_ROLE_P2P_CLIENT) 7549 ch_info->period = RTW89_P2P_CHAN_TIME; 7550 else 7551 ch_info->period = RTW89_CHANNEL_TIME; 7552 7553 ch_info->ch_band = rtw89_nl80211_to_hw_band(channel->band); 7554 ch_info->central_ch = channel->hw_value; 7555 ch_info->pri_ch = channel->hw_value; 7556 ch_info->rand_seq_num = random_seq; 7557 ch_info->is_psc = cfg80211_channel_is_psc(channel); 7558 7559 if (channel->flags & 7560 (IEEE80211_CHAN_RADAR | IEEE80211_CHAN_NO_IR)) 7561 type = RTW89_CHAN_DFS; 7562 else 7563 type = RTW89_CHAN_ACTIVE; 7564 rtw89_hw_scan_add_chan_ax(rtwdev, type, req->n_ssids, ch_info); 7565 7566 if (!(scan_info->connected && 7567 off_chan_time + ch_info->period > RTW89_OFF_CHAN_TIME)) 7568 goto next; 7569 7570 ret = rtw89_hw_scan_add_op_types_ax(rtwdev, RTW89_CHAN_OPERATE, 7571 &chan_list, req, &off_chan_time); 7572 if (ret) { 7573 kfree(ch_info); 7574 goto out; 7575 } 7576 7577 if (!ext->set) 7578 goto next; 7579 7580 ret = rtw89_hw_scan_add_op_types_ax(rtwdev, RTW89_CHAN_EXTRA_OP, 7581 &chan_list, req, &off_chan_time); 7582 if (ret) { 7583 kfree(ch_info); 7584 goto out; 7585 } 7586 7587 next: 7588 list_add_tail(&ch_info->list, &chan_list); 7589 off_chan_time += ch_info->period; 7590 } 7591 7592 list_splice_tail(&chan_list, &scan_info->chan_list); 7593 return 0; 7594 7595 out: 7596 list_for_each_entry_safe(ch_info, tmp, &chan_list, list) { 7597 list_del(&ch_info->list); 7598 kfree(ch_info); 7599 } 7600 7601 return ret; 7602 } 7603 7604 void rtw89_hw_scan_free_chan_list_ax(struct rtw89_dev *rtwdev) 7605 { 7606 struct rtw89_hw_scan_info *scan_info = &rtwdev->scan_info; 7607 struct rtw89_mac_chinfo_ax *ch_info, *tmp; 7608 7609 list_for_each_entry_safe(ch_info, tmp, &scan_info->chan_list, list) { 7610 list_del(&ch_info->list); 7611 kfree(ch_info); 7612 } 7613 } 7614 7615 int rtw89_hw_scan_add_chan_list_ax(struct rtw89_dev *rtwdev, 7616 struct rtw89_vif_link *rtwvif_link) 7617 { 7618 struct rtw89_hw_scan_info *scan_info = &rtwdev->scan_info; 7619 struct rtw89_mac_chinfo_ax *ch_info, *tmp; 7620 unsigned int list_len = 0; 7621 struct list_head list; 7622 int ret; 7623 7624 INIT_LIST_HEAD(&list); 7625 7626 list_for_each_entry_safe(ch_info, tmp, &scan_info->chan_list, list) { 7627 list_move_tail(&ch_info->list, &list); 7628 7629 list_len++; 7630 if (list_len == RTW89_SCAN_LIST_LIMIT_AX) 7631 break; 7632 } 7633 7634 ret = rtw89_fw_h2c_scan_list_offload_ax(rtwdev, list_len, &list); 7635 7636 list_for_each_entry_safe(ch_info, tmp, &list, list) { 7637 list_del(&ch_info->list); 7638 kfree(ch_info); 7639 } 7640 7641 return ret; 7642 } 7643 7644 int rtw89_pno_scan_add_chan_list_be(struct rtw89_dev *rtwdev, 7645 struct rtw89_vif_link *rtwvif_link) 7646 { 7647 struct rtw89_wow_param *rtw_wow = &rtwdev->wow; 7648 struct cfg80211_sched_scan_request *nd_config = rtw_wow->nd_config; 7649 struct rtw89_mac_chinfo_be *ch_info, *tmp; 7650 struct ieee80211_channel *channel; 7651 struct list_head chan_list; 7652 enum rtw89_chan_type type; 7653 int list_len, ret; 7654 u32 idx; 7655 7656 INIT_LIST_HEAD(&chan_list); 7657 7658 for (idx = 0, list_len = 0; 7659 idx < nd_config->n_channels && list_len < RTW89_SCAN_LIST_LIMIT_BE; 7660 idx++, list_len++) { 7661 channel = nd_config->channels[idx]; 7662 ch_info = kzalloc(sizeof(*ch_info), GFP_KERNEL); 7663 if (!ch_info) { 7664 ret = -ENOMEM; 7665 goto out; 7666 } 7667 7668 ch_info->period = RTW89_CHANNEL_TIME; 7669 ch_info->ch_band = rtw89_nl80211_to_hw_band(channel->band); 7670 ch_info->central_ch = channel->hw_value; 7671 ch_info->pri_ch = channel->hw_value; 7672 ch_info->is_psc = cfg80211_channel_is_psc(channel); 7673 7674 if (channel->flags & 7675 (IEEE80211_CHAN_RADAR | IEEE80211_CHAN_NO_IR)) 7676 type = RTW89_CHAN_DFS; 7677 else 7678 type = RTW89_CHAN_ACTIVE; 7679 7680 rtw89_pno_scan_add_chan_be(rtwdev, type, 7681 nd_config->n_match_sets, ch_info); 7682 list_add_tail(&ch_info->list, &chan_list); 7683 } 7684 7685 ret = rtw89_fw_h2c_scan_list_offload_be(rtwdev, list_len, &chan_list, 7686 rtwvif_link); 7687 7688 out: 7689 list_for_each_entry_safe(ch_info, tmp, &chan_list, list) { 7690 list_del(&ch_info->list); 7691 kfree(ch_info); 7692 } 7693 7694 return ret; 7695 } 7696 7697 int rtw89_hw_scan_prep_chan_list_be(struct rtw89_dev *rtwdev, 7698 struct rtw89_vif_link *rtwvif_link) 7699 { 7700 struct rtw89_hw_scan_info *scan_info = &rtwdev->scan_info; 7701 struct rtw89_vif *rtwvif = rtwvif_link->rtwvif; 7702 struct cfg80211_scan_request *req = rtwvif->scan_req; 7703 struct rtw89_mac_chinfo_be *ch_info, *tmp; 7704 struct ieee80211_channel *channel; 7705 struct list_head chan_list; 7706 enum rtw89_chan_type type; 7707 bool random_seq; 7708 int ret; 7709 u32 idx; 7710 7711 random_seq = !!(req->flags & NL80211_SCAN_FLAG_RANDOM_SN); 7712 INIT_LIST_HEAD(&chan_list); 7713 7714 for (idx = 0; idx < req->n_channels; idx++) { 7715 channel = req->channels[idx]; 7716 ch_info = kzalloc(sizeof(*ch_info), GFP_KERNEL); 7717 if (!ch_info) { 7718 ret = -ENOMEM; 7719 goto out; 7720 } 7721 7722 if (req->duration) 7723 ch_info->period = req->duration; 7724 else if (channel->band == NL80211_BAND_6GHZ) 7725 ch_info->period = RTW89_CHANNEL_TIME_6G + RTW89_DWELL_TIME_6G; 7726 else if (rtwvif_link->wifi_role == RTW89_WIFI_ROLE_P2P_CLIENT) 7727 ch_info->period = RTW89_P2P_CHAN_TIME; 7728 else 7729 ch_info->period = RTW89_CHANNEL_TIME; 7730 7731 ch_info->ch_band = rtw89_nl80211_to_hw_band(channel->band); 7732 ch_info->central_ch = channel->hw_value; 7733 ch_info->pri_ch = channel->hw_value; 7734 ch_info->rand_seq_num = random_seq; 7735 ch_info->is_psc = cfg80211_channel_is_psc(channel); 7736 7737 if (channel->flags & (IEEE80211_CHAN_RADAR | IEEE80211_CHAN_NO_IR)) 7738 type = RTW89_CHAN_DFS; 7739 else 7740 type = RTW89_CHAN_ACTIVE; 7741 rtw89_hw_scan_add_chan_be(rtwdev, type, req->n_ssids, ch_info); 7742 7743 list_add_tail(&ch_info->list, &chan_list); 7744 } 7745 7746 list_splice_tail(&chan_list, &scan_info->chan_list); 7747 return 0; 7748 7749 out: 7750 list_for_each_entry_safe(ch_info, tmp, &chan_list, list) { 7751 list_del(&ch_info->list); 7752 kfree(ch_info); 7753 } 7754 7755 return ret; 7756 } 7757 7758 void rtw89_hw_scan_free_chan_list_be(struct rtw89_dev *rtwdev) 7759 { 7760 struct rtw89_hw_scan_info *scan_info = &rtwdev->scan_info; 7761 struct rtw89_mac_chinfo_be *ch_info, *tmp; 7762 7763 list_for_each_entry_safe(ch_info, tmp, &scan_info->chan_list, list) { 7764 list_del(&ch_info->list); 7765 kfree(ch_info); 7766 } 7767 } 7768 7769 int rtw89_hw_scan_add_chan_list_be(struct rtw89_dev *rtwdev, 7770 struct rtw89_vif_link *rtwvif_link) 7771 { 7772 struct rtw89_hw_scan_info *scan_info = &rtwdev->scan_info; 7773 struct rtw89_mac_chinfo_be *ch_info, *tmp; 7774 unsigned int list_len = 0; 7775 struct list_head list; 7776 int ret; 7777 7778 INIT_LIST_HEAD(&list); 7779 7780 list_for_each_entry_safe(ch_info, tmp, &scan_info->chan_list, list) { 7781 list_move_tail(&ch_info->list, &list); 7782 7783 list_len++; 7784 if (list_len == RTW89_SCAN_LIST_LIMIT_BE) 7785 break; 7786 } 7787 7788 ret = rtw89_fw_h2c_scan_list_offload_be(rtwdev, list_len, &list, 7789 rtwvif_link); 7790 7791 list_for_each_entry_safe(ch_info, tmp, &list, list) { 7792 list_del(&ch_info->list); 7793 kfree(ch_info); 7794 } 7795 7796 return ret; 7797 } 7798 7799 static int rtw89_hw_scan_prehandle(struct rtw89_dev *rtwdev, 7800 struct rtw89_vif_link *rtwvif_link, 7801 const u8 *mac_addr) 7802 { 7803 const struct rtw89_mac_gen_def *mac = rtwdev->chip->mac_def; 7804 int ret; 7805 7806 ret = rtw89_hw_scan_update_probe_req(rtwdev, rtwvif_link, mac_addr); 7807 if (ret) { 7808 #if defined(__linux__) 7809 rtw89_err(rtwdev, "Update probe request failed\n"); 7810 #elif defined(__FreeBSD__) 7811 rtw89_err(rtwdev, "Update probe request failed: ret %d\n", ret); 7812 #endif 7813 goto out; 7814 } 7815 ret = mac->prep_chan_list(rtwdev, rtwvif_link); 7816 out: 7817 return ret; 7818 } 7819 7820 static void rtw89_hw_scan_update_link_beacon_noa(struct rtw89_dev *rtwdev, 7821 struct rtw89_vif_link *rtwvif_link, 7822 u16 tu, bool scan) 7823 { 7824 struct ieee80211_p2p_noa_desc noa_desc = {}; 7825 struct ieee80211_bss_conf *bss_conf; 7826 u16 beacon_int; 7827 u64 tsf; 7828 int ret; 7829 7830 rcu_read_lock(); 7831 7832 bss_conf = rtw89_vif_rcu_dereference_link(rtwvif_link, true); 7833 beacon_int = bss_conf->beacon_int; 7834 7835 rcu_read_unlock(); 7836 7837 tu += beacon_int * 3; 7838 if (rtwdev->chip->chip_gen == RTW89_CHIP_AX) 7839 rtwdev->scan_info.delay = ieee80211_tu_to_usec(beacon_int * 3) / 1000; 7840 7841 ret = rtw89_mac_port_get_tsf(rtwdev, rtwvif_link, &tsf); 7842 if (ret) { 7843 rtw89_warn(rtwdev, "%s: failed to get tsf\n", __func__); 7844 return; 7845 } 7846 7847 noa_desc.start_time = cpu_to_le32(tsf); 7848 if (rtwdev->chip->chip_gen == RTW89_CHIP_AX) { 7849 noa_desc.interval = cpu_to_le32(ieee80211_tu_to_usec(tu)); 7850 noa_desc.duration = cpu_to_le32(ieee80211_tu_to_usec(tu)); 7851 noa_desc.count = 1; 7852 } else { 7853 noa_desc.duration = cpu_to_le32(ieee80211_tu_to_usec(20000)); 7854 noa_desc.interval = cpu_to_le32(ieee80211_tu_to_usec(20000)); 7855 noa_desc.count = 255; 7856 } 7857 7858 rtw89_p2p_noa_renew(rtwvif_link); 7859 if (scan) 7860 rtw89_p2p_noa_append(rtwvif_link, &noa_desc); 7861 7862 rtw89_chip_h2c_update_beacon(rtwdev, rtwvif_link); 7863 } 7864 7865 static void rtw89_hw_scan_update_beacon_noa(struct rtw89_dev *rtwdev, bool scan) 7866 { 7867 const struct rtw89_entity_mgnt *mgnt = &rtwdev->hal.entity_mgnt; 7868 const struct rtw89_hw_scan_info *scan_info = &rtwdev->scan_info; 7869 const struct rtw89_chip_info *chip = rtwdev->chip; 7870 struct rtw89_mac_chinfo_ax *chinfo_ax; 7871 struct rtw89_mac_chinfo_be *chinfo_be; 7872 struct rtw89_vif_link *rtwvif_link; 7873 struct list_head *pos, *tmp; 7874 struct ieee80211_vif *vif; 7875 struct rtw89_vif *rtwvif; 7876 u16 tu = 0; 7877 7878 lockdep_assert_wiphy(rtwdev->hw->wiphy); 7879 7880 if (!scan) 7881 goto update; 7882 7883 list_for_each_safe(pos, tmp, &scan_info->chan_list) { 7884 switch (chip->chip_gen) { 7885 case RTW89_CHIP_AX: 7886 chinfo_ax = list_entry(pos, typeof(*chinfo_ax), list); 7887 tu += chinfo_ax->period; 7888 break; 7889 case RTW89_CHIP_BE: 7890 chinfo_be = list_entry(pos, typeof(*chinfo_be), list); 7891 tu += chinfo_be->period; 7892 break; 7893 default: 7894 rtw89_warn(rtwdev, "%s: invalid chip gen %d\n", 7895 __func__, chip->chip_gen); 7896 return; 7897 } 7898 } 7899 7900 if (unlikely(tu == 0)) { 7901 rtw89_debug(rtwdev, RTW89_DBG_HW_SCAN, 7902 "%s: cannot estimate needed TU\n", __func__); 7903 return; 7904 } 7905 7906 update: 7907 list_for_each_entry(rtwvif, &mgnt->active_list, mgnt_entry) { 7908 unsigned int link_id; 7909 7910 vif = rtwvif_to_vif(rtwvif); 7911 if (vif->type != NL80211_IFTYPE_AP || !vif->p2p) 7912 continue; 7913 7914 rtw89_vif_for_each_link(rtwvif, rtwvif_link, link_id) 7915 rtw89_hw_scan_update_link_beacon_noa(rtwdev, rtwvif_link, 7916 tu, scan); 7917 } 7918 } 7919 7920 static void rtw89_hw_scan_set_extra_op_info(struct rtw89_dev *rtwdev, 7921 struct rtw89_vif *scan_rtwvif, 7922 const struct rtw89_chan *scan_op) 7923 { 7924 struct rtw89_entity_mgnt *mgnt = &rtwdev->hal.entity_mgnt; 7925 struct rtw89_hw_scan_info *scan_info = &rtwdev->scan_info; 7926 struct rtw89_hw_scan_extra_op *ext = &scan_info->extra_op; 7927 struct rtw89_vif *tmp; 7928 7929 ext->set = false; 7930 if (!RTW89_CHK_FW_FEATURE(SCAN_OFFLOAD_EXTRA_OP, &rtwdev->fw)) 7931 return; 7932 7933 list_for_each_entry(tmp, &mgnt->active_list, mgnt_entry) { 7934 const struct rtw89_chan *tmp_chan; 7935 struct rtw89_vif_link *tmp_link; 7936 7937 if (tmp == scan_rtwvif) 7938 continue; 7939 7940 tmp_link = rtw89_vif_get_link_inst(tmp, 0); 7941 if (unlikely(!tmp_link)) { 7942 rtw89_debug(rtwdev, RTW89_DBG_HW_SCAN, 7943 "hw scan: no HW-0 link for extra op\n"); 7944 continue; 7945 } 7946 7947 tmp_chan = rtw89_chan_get(rtwdev, tmp_link->chanctx_idx); 7948 *ext = (struct rtw89_hw_scan_extra_op){ 7949 .set = true, 7950 .macid = tmp_link->mac_id, 7951 .port = tmp_link->port, 7952 .chan = *tmp_chan, 7953 .rtwvif_link = tmp_link, 7954 }; 7955 7956 rtw89_debug(rtwdev, RTW89_DBG_HW_SCAN, 7957 "hw scan: extra op: center %d primary %d\n", 7958 ext->chan.channel, ext->chan.primary_channel); 7959 break; 7960 } 7961 } 7962 7963 int rtw89_hw_scan_start(struct rtw89_dev *rtwdev, 7964 struct rtw89_vif_link *rtwvif_link, 7965 struct ieee80211_scan_request *scan_req) 7966 { 7967 const struct rtw89_mac_gen_def *mac = rtwdev->chip->mac_def; 7968 enum rtw89_entity_mode mode = rtw89_get_entity_mode(rtwdev); 7969 struct cfg80211_scan_request *req = &scan_req->req; 7970 const struct rtw89_chan *chan = rtw89_chan_get(rtwdev, 7971 rtwvif_link->chanctx_idx); 7972 struct rtw89_vif *rtwvif = rtwvif_link->rtwvif; 7973 struct rtw89_chanctx_pause_parm pause_parm = { 7974 .rsn = RTW89_CHANCTX_PAUSE_REASON_HW_SCAN, 7975 .trigger = rtwvif_link, 7976 }; 7977 u32 rx_fltr = rtwdev->hal.rx_fltr; 7978 u8 mac_addr[ETH_ALEN]; 7979 u32 reg; 7980 int ret; 7981 7982 /* clone op and keep it during scan */ 7983 rtwdev->scan_info.op_chan = *chan; 7984 7985 rtw89_debug(rtwdev, RTW89_DBG_HW_SCAN, 7986 "hw scan: op: center %d primary %d\n", 7987 chan->channel, chan->primary_channel); 7988 7989 rtw89_hw_scan_set_extra_op_info(rtwdev, rtwvif, chan); 7990 7991 rtwdev->scan_info.connected = rtw89_is_any_vif_connected_or_connecting(rtwdev); 7992 rtwdev->scan_info.scanning_vif = rtwvif_link; 7993 rtwdev->scan_info.abort = false; 7994 rtwdev->scan_info.delay = 0; 7995 rtwvif->scan_ies = &scan_req->ies; 7996 rtwvif->scan_req = req; 7997 7998 if (req->flags & NL80211_SCAN_FLAG_RANDOM_ADDR) 7999 get_random_mask_addr(mac_addr, req->mac_addr, 8000 req->mac_addr_mask); 8001 else 8002 ether_addr_copy(mac_addr, rtwvif_link->mac_addr); 8003 8004 ret = rtw89_hw_scan_prehandle(rtwdev, rtwvif_link, mac_addr); 8005 if (ret) { 8006 rtw89_hw_scan_cleanup(rtwdev, rtwvif_link); 8007 return ret; 8008 } 8009 8010 ieee80211_stop_queues(rtwdev->hw); 8011 rtw89_mac_port_cfg_rx_sync(rtwdev, rtwvif_link, false); 8012 8013 rtw89_core_scan_start(rtwdev, rtwvif_link, mac_addr, true); 8014 8015 rx_fltr &= ~B_AX_A_BCN_CHK_EN; 8016 rx_fltr &= ~B_AX_A_BC; 8017 rx_fltr &= ~B_AX_A_A1_MATCH; 8018 8019 reg = rtw89_mac_reg_by_idx(rtwdev, mac->rx_fltr, rtwvif_link->mac_idx); 8020 rtw89_write32_mask(rtwdev, reg, B_AX_RX_FLTR_CFG_MASK, rx_fltr); 8021 8022 rtw89_chanctx_pause(rtwdev, &pause_parm); 8023 rtw89_phy_dig_suspend(rtwdev); 8024 8025 if (mode == RTW89_ENTITY_MODE_MCC) 8026 rtw89_hw_scan_update_beacon_noa(rtwdev, true); 8027 8028 return 0; 8029 } 8030 8031 struct rtw89_hw_scan_complete_cb_data { 8032 struct rtw89_vif_link *rtwvif_link; 8033 bool aborted; 8034 }; 8035 8036 static int rtw89_hw_scan_complete_cb(struct rtw89_dev *rtwdev, void *data) 8037 { 8038 const struct rtw89_mac_gen_def *mac = rtwdev->chip->mac_def; 8039 enum rtw89_entity_mode mode = rtw89_get_entity_mode(rtwdev); 8040 struct rtw89_hw_scan_complete_cb_data *cb_data = data; 8041 struct rtw89_vif_link *rtwvif_link = cb_data->rtwvif_link; 8042 struct cfg80211_scan_info info = { 8043 .aborted = cb_data->aborted, 8044 }; 8045 u32 reg; 8046 8047 if (!rtwvif_link) 8048 return -EINVAL; 8049 8050 reg = rtw89_mac_reg_by_idx(rtwdev, mac->rx_fltr, rtwvif_link->mac_idx); 8051 rtw89_write32_mask(rtwdev, reg, B_AX_RX_FLTR_CFG_MASK, rtwdev->hal.rx_fltr); 8052 8053 rtw89_core_scan_complete(rtwdev, rtwvif_link, true); 8054 ieee80211_scan_completed(rtwdev->hw, &info); 8055 ieee80211_wake_queues(rtwdev->hw); 8056 rtw89_mac_port_cfg_rx_sync(rtwdev, rtwvif_link, true); 8057 rtw89_mac_enable_beacon_for_ap_vifs(rtwdev, true); 8058 rtw89_phy_dig_resume(rtwdev, true); 8059 8060 rtw89_hw_scan_cleanup(rtwdev, rtwvif_link); 8061 8062 if (mode == RTW89_ENTITY_MODE_MCC) 8063 rtw89_hw_scan_update_beacon_noa(rtwdev, false); 8064 8065 return 0; 8066 } 8067 8068 void rtw89_hw_scan_complete(struct rtw89_dev *rtwdev, 8069 struct rtw89_vif_link *rtwvif_link, 8070 bool aborted) 8071 { 8072 struct rtw89_hw_scan_complete_cb_data cb_data = { 8073 .rtwvif_link = rtwvif_link, 8074 .aborted = aborted, 8075 }; 8076 const struct rtw89_chanctx_cb_parm cb_parm = { 8077 .cb = rtw89_hw_scan_complete_cb, 8078 .data = &cb_data, 8079 .caller = __func__, 8080 }; 8081 8082 /* The things here needs to be done after setting channel (for coex) 8083 * and before proceeding entity mode (for MCC). So, pass a callback 8084 * of them for the right sequence rather than doing them directly. 8085 */ 8086 rtw89_chanctx_proceed(rtwdev, &cb_parm); 8087 } 8088 8089 void rtw89_hw_scan_abort(struct rtw89_dev *rtwdev, 8090 struct rtw89_vif_link *rtwvif_link) 8091 { 8092 struct rtw89_hw_scan_info *scan_info = &rtwdev->scan_info; 8093 int ret; 8094 8095 scan_info->abort = true; 8096 8097 ret = rtw89_hw_scan_offload(rtwdev, rtwvif_link, false); 8098 if (ret) 8099 rtw89_warn(rtwdev, "rtw89_hw_scan_offload failed ret %d\n", ret); 8100 8101 /* Indicate ieee80211_scan_completed() before returning, which is safe 8102 * because scan abort command always waits for completion of 8103 * RTW89_SCAN_END_SCAN_NOTIFY, so that ieee80211_stop() can flush scan 8104 * work properly. 8105 */ 8106 rtw89_hw_scan_complete(rtwdev, rtwvif_link, true); 8107 } 8108 8109 static bool rtw89_is_any_vif_connected_or_connecting(struct rtw89_dev *rtwdev) 8110 { 8111 struct rtw89_vif_link *rtwvif_link; 8112 struct rtw89_vif *rtwvif; 8113 unsigned int link_id; 8114 8115 rtw89_for_each_rtwvif(rtwdev, rtwvif) { 8116 rtw89_vif_for_each_link(rtwvif, rtwvif_link, link_id) { 8117 /* This variable implies connected or during attempt to connect */ 8118 if (!is_zero_ether_addr(rtwvif_link->bssid)) 8119 return true; 8120 } 8121 } 8122 8123 return false; 8124 } 8125 8126 int rtw89_hw_scan_offload(struct rtw89_dev *rtwdev, 8127 struct rtw89_vif_link *rtwvif_link, 8128 bool enable) 8129 { 8130 const struct rtw89_mac_gen_def *mac = rtwdev->chip->mac_def; 8131 struct rtw89_hw_scan_info *scan_info = &rtwdev->scan_info; 8132 const struct rtw89_hw_scan_extra_op *ext = &scan_info->extra_op; 8133 struct rtw89_scan_option opt = {0}; 8134 bool connected; 8135 int ret = 0; 8136 8137 if (!rtwvif_link) 8138 return -EINVAL; 8139 8140 connected = rtwdev->scan_info.connected; 8141 opt.enable = enable; 8142 opt.target_ch_mode = connected; 8143 opt.delay = rtwdev->scan_info.delay; 8144 if (enable) { 8145 ret = mac->add_chan_list(rtwdev, rtwvif_link); 8146 if (ret) 8147 goto out; 8148 } 8149 8150 if (rtwdev->chip->chip_gen == RTW89_CHIP_BE) { 8151 opt.operation = enable ? RTW89_SCAN_OP_START : RTW89_SCAN_OP_STOP; 8152 opt.scan_mode = RTW89_SCAN_MODE_SA; 8153 opt.band = rtwvif_link->mac_idx; 8154 opt.num_macc_role = 0; 8155 opt.mlo_mode = rtwdev->mlo_dbcc_mode; 8156 opt.num_opch = connected ? 1 : 0; 8157 if (connected && ext->set) 8158 opt.num_opch++; 8159 8160 opt.opch_end = connected ? 0 : RTW89_CHAN_INVALID; 8161 } 8162 8163 ret = rtw89_mac_scan_offload(rtwdev, &opt, rtwvif_link, false); 8164 8165 out: 8166 return ret; 8167 } 8168 8169 #define H2C_FW_CPU_EXCEPTION_TYPE_0 0x5566 8170 #define H2C_FW_CPU_EXCEPTION_TYPE_1 0x0 8171 int rtw89_fw_h2c_trigger_cpu_exception(struct rtw89_dev *rtwdev) 8172 { 8173 struct rtw89_h2c_trig_cpu_except *h2c; 8174 u32 cpu_exception_type_def; 8175 u32 len = sizeof(*h2c); 8176 struct sk_buff *skb; 8177 int ret; 8178 8179 if (RTW89_CHK_FW_FEATURE(CRASH_TRIGGER_TYPE_1, &rtwdev->fw)) 8180 cpu_exception_type_def = H2C_FW_CPU_EXCEPTION_TYPE_1; 8181 else if (RTW89_CHK_FW_FEATURE(CRASH_TRIGGER_TYPE_0, &rtwdev->fw)) 8182 cpu_exception_type_def = H2C_FW_CPU_EXCEPTION_TYPE_0; 8183 else 8184 return -EOPNOTSUPP; 8185 8186 skb = rtw89_fw_h2c_alloc_skb_with_hdr(rtwdev, len); 8187 if (!skb) { 8188 rtw89_err(rtwdev, 8189 "failed to alloc skb for fw cpu exception\n"); 8190 return -ENOMEM; 8191 } 8192 8193 skb_put(skb, len); 8194 h2c = (struct rtw89_h2c_trig_cpu_except *)skb->data; 8195 8196 h2c->w0 = le32_encode_bits(cpu_exception_type_def, 8197 RTW89_H2C_CPU_EXCEPTION_TYPE); 8198 8199 rtw89_h2c_pkt_set_hdr(rtwdev, skb, FWCMD_TYPE_H2C, 8200 H2C_CAT_TEST, 8201 H2C_CL_FW_STATUS_TEST, 8202 H2C_FUNC_CPU_EXCEPTION, 0, 0, 8203 len); 8204 8205 ret = rtw89_h2c_tx(rtwdev, skb, false); 8206 if (ret) { 8207 rtw89_err(rtwdev, "failed to send h2c\n"); 8208 dev_kfree_skb_any(skb); 8209 return ret; 8210 } 8211 8212 return 0; 8213 } 8214 8215 #define H2C_PKT_DROP_LEN 24 8216 int rtw89_fw_h2c_pkt_drop(struct rtw89_dev *rtwdev, 8217 const struct rtw89_pkt_drop_params *params) 8218 { 8219 struct sk_buff *skb; 8220 int ret; 8221 8222 skb = rtw89_fw_h2c_alloc_skb_with_hdr(rtwdev, H2C_PKT_DROP_LEN); 8223 if (!skb) { 8224 rtw89_err(rtwdev, 8225 "failed to alloc skb for packet drop\n"); 8226 return -ENOMEM; 8227 } 8228 8229 switch (params->sel) { 8230 case RTW89_PKT_DROP_SEL_MACID_BE_ONCE: 8231 case RTW89_PKT_DROP_SEL_MACID_BK_ONCE: 8232 case RTW89_PKT_DROP_SEL_MACID_VI_ONCE: 8233 case RTW89_PKT_DROP_SEL_MACID_VO_ONCE: 8234 case RTW89_PKT_DROP_SEL_BAND_ONCE: 8235 break; 8236 default: 8237 rtw89_debug(rtwdev, RTW89_DBG_FW, 8238 "H2C of pkt drop might not fully support sel: %d yet\n", 8239 params->sel); 8240 break; 8241 } 8242 8243 skb_put(skb, H2C_PKT_DROP_LEN); 8244 RTW89_SET_FWCMD_PKT_DROP_SEL(skb->data, params->sel); 8245 RTW89_SET_FWCMD_PKT_DROP_MACID(skb->data, params->macid); 8246 RTW89_SET_FWCMD_PKT_DROP_BAND(skb->data, params->mac_band); 8247 RTW89_SET_FWCMD_PKT_DROP_PORT(skb->data, params->port); 8248 RTW89_SET_FWCMD_PKT_DROP_MBSSID(skb->data, params->mbssid); 8249 RTW89_SET_FWCMD_PKT_DROP_ROLE_A_INFO_TF_TRS(skb->data, params->tf_trs); 8250 RTW89_SET_FWCMD_PKT_DROP_MACID_BAND_SEL_0(skb->data, 8251 params->macid_band_sel[0]); 8252 RTW89_SET_FWCMD_PKT_DROP_MACID_BAND_SEL_1(skb->data, 8253 params->macid_band_sel[1]); 8254 RTW89_SET_FWCMD_PKT_DROP_MACID_BAND_SEL_2(skb->data, 8255 params->macid_band_sel[2]); 8256 RTW89_SET_FWCMD_PKT_DROP_MACID_BAND_SEL_3(skb->data, 8257 params->macid_band_sel[3]); 8258 8259 rtw89_h2c_pkt_set_hdr(rtwdev, skb, FWCMD_TYPE_H2C, 8260 H2C_CAT_MAC, 8261 H2C_CL_MAC_FW_OFLD, 8262 H2C_FUNC_PKT_DROP, 0, 0, 8263 H2C_PKT_DROP_LEN); 8264 8265 ret = rtw89_h2c_tx(rtwdev, skb, false); 8266 if (ret) { 8267 rtw89_err(rtwdev, "failed to send h2c\n"); 8268 goto fail; 8269 } 8270 8271 return 0; 8272 8273 fail: 8274 dev_kfree_skb_any(skb); 8275 return ret; 8276 } 8277 8278 #define H2C_KEEP_ALIVE_LEN 4 8279 int rtw89_fw_h2c_keep_alive(struct rtw89_dev *rtwdev, struct rtw89_vif_link *rtwvif_link, 8280 bool enable) 8281 { 8282 struct sk_buff *skb; 8283 u8 pkt_id = 0; 8284 int ret; 8285 8286 if (enable) { 8287 ret = rtw89_fw_h2c_add_general_pkt(rtwdev, rtwvif_link, 8288 RTW89_PKT_OFLD_TYPE_NULL_DATA, 8289 &pkt_id); 8290 if (ret) 8291 return -EPERM; 8292 } 8293 8294 skb = rtw89_fw_h2c_alloc_skb_with_hdr(rtwdev, H2C_KEEP_ALIVE_LEN); 8295 if (!skb) { 8296 rtw89_err(rtwdev, "failed to alloc skb for keep alive\n"); 8297 return -ENOMEM; 8298 } 8299 8300 skb_put(skb, H2C_KEEP_ALIVE_LEN); 8301 8302 RTW89_SET_KEEP_ALIVE_ENABLE(skb->data, enable); 8303 RTW89_SET_KEEP_ALIVE_PKT_NULL_ID(skb->data, pkt_id); 8304 RTW89_SET_KEEP_ALIVE_PERIOD(skb->data, 5); 8305 RTW89_SET_KEEP_ALIVE_MACID(skb->data, rtwvif_link->mac_id); 8306 8307 rtw89_h2c_pkt_set_hdr(rtwdev, skb, FWCMD_TYPE_H2C, 8308 H2C_CAT_MAC, 8309 H2C_CL_MAC_WOW, 8310 H2C_FUNC_KEEP_ALIVE, 0, 1, 8311 H2C_KEEP_ALIVE_LEN); 8312 8313 ret = rtw89_h2c_tx(rtwdev, skb, false); 8314 if (ret) { 8315 rtw89_err(rtwdev, "failed to send h2c\n"); 8316 goto fail; 8317 } 8318 8319 return 0; 8320 8321 fail: 8322 dev_kfree_skb_any(skb); 8323 8324 return ret; 8325 } 8326 8327 int rtw89_fw_h2c_arp_offload(struct rtw89_dev *rtwdev, struct rtw89_vif_link *rtwvif_link, 8328 bool enable) 8329 { 8330 struct rtw89_h2c_arp_offload *h2c; 8331 u32 len = sizeof(*h2c); 8332 struct sk_buff *skb; 8333 u8 pkt_id = 0; 8334 int ret; 8335 8336 if (enable) { 8337 ret = rtw89_fw_h2c_add_general_pkt(rtwdev, rtwvif_link, 8338 RTW89_PKT_OFLD_TYPE_ARP_RSP, 8339 &pkt_id); 8340 if (ret) 8341 return ret; 8342 } 8343 8344 skb = rtw89_fw_h2c_alloc_skb_with_hdr(rtwdev, len); 8345 if (!skb) { 8346 rtw89_err(rtwdev, "failed to alloc skb for arp offload\n"); 8347 return -ENOMEM; 8348 } 8349 8350 skb_put(skb, len); 8351 h2c = (struct rtw89_h2c_arp_offload *)skb->data; 8352 8353 h2c->w0 = le32_encode_bits(enable, RTW89_H2C_ARP_OFFLOAD_W0_ENABLE) | 8354 le32_encode_bits(0, RTW89_H2C_ARP_OFFLOAD_W0_ACTION) | 8355 le32_encode_bits(rtwvif_link->mac_id, RTW89_H2C_ARP_OFFLOAD_W0_MACID) | 8356 le32_encode_bits(pkt_id, RTW89_H2C_ARP_OFFLOAD_W0_PKT_ID); 8357 8358 rtw89_h2c_pkt_set_hdr(rtwdev, skb, FWCMD_TYPE_H2C, 8359 H2C_CAT_MAC, 8360 H2C_CL_MAC_WOW, 8361 H2C_FUNC_ARP_OFLD, 0, 1, 8362 len); 8363 8364 ret = rtw89_h2c_tx(rtwdev, skb, false); 8365 if (ret) { 8366 rtw89_err(rtwdev, "failed to send h2c\n"); 8367 goto fail; 8368 } 8369 8370 return 0; 8371 8372 fail: 8373 dev_kfree_skb_any(skb); 8374 8375 return ret; 8376 } 8377 8378 #define H2C_DISCONNECT_DETECT_LEN 8 8379 int rtw89_fw_h2c_disconnect_detect(struct rtw89_dev *rtwdev, 8380 struct rtw89_vif_link *rtwvif_link, bool enable) 8381 { 8382 struct rtw89_wow_param *rtw_wow = &rtwdev->wow; 8383 struct sk_buff *skb; 8384 u8 macid = rtwvif_link->mac_id; 8385 int ret; 8386 8387 skb = rtw89_fw_h2c_alloc_skb_with_hdr(rtwdev, H2C_DISCONNECT_DETECT_LEN); 8388 if (!skb) { 8389 rtw89_err(rtwdev, "failed to alloc skb for keep alive\n"); 8390 return -ENOMEM; 8391 } 8392 8393 skb_put(skb, H2C_DISCONNECT_DETECT_LEN); 8394 8395 if (test_bit(RTW89_WOW_FLAG_EN_DISCONNECT, rtw_wow->flags)) { 8396 RTW89_SET_DISCONNECT_DETECT_ENABLE(skb->data, enable); 8397 RTW89_SET_DISCONNECT_DETECT_DISCONNECT(skb->data, !enable); 8398 RTW89_SET_DISCONNECT_DETECT_MAC_ID(skb->data, macid); 8399 RTW89_SET_DISCONNECT_DETECT_CHECK_PERIOD(skb->data, 100); 8400 RTW89_SET_DISCONNECT_DETECT_TRY_PKT_COUNT(skb->data, 5); 8401 } 8402 8403 rtw89_h2c_pkt_set_hdr(rtwdev, skb, FWCMD_TYPE_H2C, 8404 H2C_CAT_MAC, 8405 H2C_CL_MAC_WOW, 8406 H2C_FUNC_DISCONNECT_DETECT, 0, 1, 8407 H2C_DISCONNECT_DETECT_LEN); 8408 8409 ret = rtw89_h2c_tx(rtwdev, skb, false); 8410 if (ret) { 8411 rtw89_err(rtwdev, "failed to send h2c\n"); 8412 goto fail; 8413 } 8414 8415 return 0; 8416 8417 fail: 8418 dev_kfree_skb_any(skb); 8419 8420 return ret; 8421 } 8422 8423 int rtw89_fw_h2c_cfg_pno(struct rtw89_dev *rtwdev, struct rtw89_vif_link *rtwvif_link, 8424 bool enable) 8425 { 8426 struct rtw89_wow_param *rtw_wow = &rtwdev->wow; 8427 struct cfg80211_sched_scan_request *nd_config = rtw_wow->nd_config; 8428 struct rtw89_h2c_cfg_nlo *h2c; 8429 u32 len = sizeof(*h2c); 8430 struct sk_buff *skb; 8431 int ret, i; 8432 8433 skb = rtw89_fw_h2c_alloc_skb_with_hdr(rtwdev, len); 8434 if (!skb) { 8435 rtw89_err(rtwdev, "failed to alloc skb for nlo\n"); 8436 return -ENOMEM; 8437 } 8438 8439 skb_put(skb, len); 8440 h2c = (struct rtw89_h2c_cfg_nlo *)skb->data; 8441 8442 h2c->w0 = le32_encode_bits(enable, RTW89_H2C_NLO_W0_ENABLE) | 8443 le32_encode_bits(enable, RTW89_H2C_NLO_W0_IGNORE_CIPHER) | 8444 le32_encode_bits(rtwvif_link->mac_id, RTW89_H2C_NLO_W0_MACID); 8445 8446 if (enable) { 8447 h2c->nlo_cnt = nd_config->n_match_sets; 8448 for (i = 0 ; i < nd_config->n_match_sets; i++) { 8449 h2c->ssid_len[i] = nd_config->match_sets[i].ssid.ssid_len; 8450 memcpy(h2c->ssid[i], nd_config->match_sets[i].ssid.ssid, 8451 nd_config->match_sets[i].ssid.ssid_len); 8452 } 8453 } 8454 8455 rtw89_h2c_pkt_set_hdr(rtwdev, skb, FWCMD_TYPE_H2C, 8456 H2C_CAT_MAC, 8457 H2C_CL_MAC_WOW, 8458 H2C_FUNC_NLO, 0, 1, 8459 len); 8460 8461 ret = rtw89_h2c_tx(rtwdev, skb, false); 8462 if (ret) { 8463 rtw89_err(rtwdev, "failed to send h2c\n"); 8464 goto fail; 8465 } 8466 8467 return 0; 8468 8469 fail: 8470 dev_kfree_skb_any(skb); 8471 return ret; 8472 } 8473 8474 int rtw89_fw_h2c_wow_global(struct rtw89_dev *rtwdev, struct rtw89_vif_link *rtwvif_link, 8475 bool enable) 8476 { 8477 struct rtw89_wow_param *rtw_wow = &rtwdev->wow; 8478 struct rtw89_h2c_wow_global *h2c; 8479 u8 macid = rtwvif_link->mac_id; 8480 u32 len = sizeof(*h2c); 8481 struct sk_buff *skb; 8482 int ret; 8483 8484 skb = rtw89_fw_h2c_alloc_skb_with_hdr(rtwdev, len); 8485 if (!skb) { 8486 rtw89_err(rtwdev, "failed to alloc skb for wow global\n"); 8487 return -ENOMEM; 8488 } 8489 8490 skb_put(skb, len); 8491 h2c = (struct rtw89_h2c_wow_global *)skb->data; 8492 8493 h2c->w0 = le32_encode_bits(enable, RTW89_H2C_WOW_GLOBAL_W0_ENABLE) | 8494 le32_encode_bits(macid, RTW89_H2C_WOW_GLOBAL_W0_MAC_ID) | 8495 le32_encode_bits(rtw_wow->ptk_alg, 8496 RTW89_H2C_WOW_GLOBAL_W0_PAIRWISE_SEC_ALGO) | 8497 le32_encode_bits(rtw_wow->gtk_alg, 8498 RTW89_H2C_WOW_GLOBAL_W0_GROUP_SEC_ALGO); 8499 h2c->key_info = rtw_wow->key_info; 8500 8501 rtw89_h2c_pkt_set_hdr(rtwdev, skb, FWCMD_TYPE_H2C, 8502 H2C_CAT_MAC, 8503 H2C_CL_MAC_WOW, 8504 H2C_FUNC_WOW_GLOBAL, 0, 1, 8505 len); 8506 8507 ret = rtw89_h2c_tx(rtwdev, skb, false); 8508 if (ret) { 8509 rtw89_err(rtwdev, "failed to send h2c\n"); 8510 goto fail; 8511 } 8512 8513 return 0; 8514 8515 fail: 8516 dev_kfree_skb_any(skb); 8517 8518 return ret; 8519 } 8520 8521 #define H2C_WAKEUP_CTRL_LEN 4 8522 int rtw89_fw_h2c_wow_wakeup_ctrl(struct rtw89_dev *rtwdev, 8523 struct rtw89_vif_link *rtwvif_link, 8524 bool enable) 8525 { 8526 struct rtw89_wow_param *rtw_wow = &rtwdev->wow; 8527 struct sk_buff *skb; 8528 u8 macid = rtwvif_link->mac_id; 8529 int ret; 8530 8531 skb = rtw89_fw_h2c_alloc_skb_with_hdr(rtwdev, H2C_WAKEUP_CTRL_LEN); 8532 if (!skb) { 8533 rtw89_err(rtwdev, "failed to alloc skb for wakeup ctrl\n"); 8534 return -ENOMEM; 8535 } 8536 8537 skb_put(skb, H2C_WAKEUP_CTRL_LEN); 8538 8539 if (rtw_wow->pattern_cnt) 8540 RTW89_SET_WOW_WAKEUP_CTRL_PATTERN_MATCH_ENABLE(skb->data, enable); 8541 if (test_bit(RTW89_WOW_FLAG_EN_MAGIC_PKT, rtw_wow->flags)) 8542 RTW89_SET_WOW_WAKEUP_CTRL_MAGIC_ENABLE(skb->data, enable); 8543 if (test_bit(RTW89_WOW_FLAG_EN_DISCONNECT, rtw_wow->flags)) 8544 RTW89_SET_WOW_WAKEUP_CTRL_DEAUTH_ENABLE(skb->data, enable); 8545 8546 RTW89_SET_WOW_WAKEUP_CTRL_MAC_ID(skb->data, macid); 8547 8548 rtw89_h2c_pkt_set_hdr(rtwdev, skb, FWCMD_TYPE_H2C, 8549 H2C_CAT_MAC, 8550 H2C_CL_MAC_WOW, 8551 H2C_FUNC_WAKEUP_CTRL, 0, 1, 8552 H2C_WAKEUP_CTRL_LEN); 8553 8554 ret = rtw89_h2c_tx(rtwdev, skb, false); 8555 if (ret) { 8556 rtw89_err(rtwdev, "failed to send h2c\n"); 8557 goto fail; 8558 } 8559 8560 return 0; 8561 8562 fail: 8563 dev_kfree_skb_any(skb); 8564 8565 return ret; 8566 } 8567 8568 #define H2C_WOW_CAM_UPD_LEN 24 8569 int rtw89_fw_wow_cam_update(struct rtw89_dev *rtwdev, 8570 struct rtw89_wow_cam_info *cam_info) 8571 { 8572 struct sk_buff *skb; 8573 int ret; 8574 8575 skb = rtw89_fw_h2c_alloc_skb_with_hdr(rtwdev, H2C_WOW_CAM_UPD_LEN); 8576 if (!skb) { 8577 rtw89_err(rtwdev, "failed to alloc skb for keep alive\n"); 8578 return -ENOMEM; 8579 } 8580 8581 skb_put(skb, H2C_WOW_CAM_UPD_LEN); 8582 8583 RTW89_SET_WOW_CAM_UPD_R_W(skb->data, cam_info->r_w); 8584 RTW89_SET_WOW_CAM_UPD_IDX(skb->data, cam_info->idx); 8585 if (cam_info->valid) { 8586 RTW89_SET_WOW_CAM_UPD_WKFM1(skb->data, cam_info->mask[0]); 8587 RTW89_SET_WOW_CAM_UPD_WKFM2(skb->data, cam_info->mask[1]); 8588 RTW89_SET_WOW_CAM_UPD_WKFM3(skb->data, cam_info->mask[2]); 8589 RTW89_SET_WOW_CAM_UPD_WKFM4(skb->data, cam_info->mask[3]); 8590 RTW89_SET_WOW_CAM_UPD_CRC(skb->data, cam_info->crc); 8591 RTW89_SET_WOW_CAM_UPD_NEGATIVE_PATTERN_MATCH(skb->data, 8592 cam_info->negative_pattern_match); 8593 RTW89_SET_WOW_CAM_UPD_SKIP_MAC_HDR(skb->data, 8594 cam_info->skip_mac_hdr); 8595 RTW89_SET_WOW_CAM_UPD_UC(skb->data, cam_info->uc); 8596 RTW89_SET_WOW_CAM_UPD_MC(skb->data, cam_info->mc); 8597 RTW89_SET_WOW_CAM_UPD_BC(skb->data, cam_info->bc); 8598 } 8599 RTW89_SET_WOW_CAM_UPD_VALID(skb->data, cam_info->valid); 8600 8601 rtw89_h2c_pkt_set_hdr(rtwdev, skb, FWCMD_TYPE_H2C, 8602 H2C_CAT_MAC, 8603 H2C_CL_MAC_WOW, 8604 H2C_FUNC_WOW_CAM_UPD, 0, 1, 8605 H2C_WOW_CAM_UPD_LEN); 8606 8607 ret = rtw89_h2c_tx(rtwdev, skb, false); 8608 if (ret) { 8609 rtw89_err(rtwdev, "failed to send h2c\n"); 8610 goto fail; 8611 } 8612 8613 return 0; 8614 fail: 8615 dev_kfree_skb_any(skb); 8616 8617 return ret; 8618 } 8619 8620 int rtw89_fw_h2c_wow_gtk_ofld(struct rtw89_dev *rtwdev, 8621 struct rtw89_vif_link *rtwvif_link, 8622 bool enable) 8623 { 8624 struct rtw89_wow_param *rtw_wow = &rtwdev->wow; 8625 struct rtw89_wow_gtk_info *gtk_info = &rtw_wow->gtk_info; 8626 struct rtw89_h2c_wow_gtk_ofld *h2c; 8627 u8 macid = rtwvif_link->mac_id; 8628 u32 len = sizeof(*h2c); 8629 u8 pkt_id_sa_query = 0; 8630 struct sk_buff *skb; 8631 u8 pkt_id_eapol = 0; 8632 int ret; 8633 8634 if (!rtw_wow->gtk_alg) 8635 return 0; 8636 8637 skb = rtw89_fw_h2c_alloc_skb_with_hdr(rtwdev, len); 8638 if (!skb) { 8639 rtw89_err(rtwdev, "failed to alloc skb for gtk ofld\n"); 8640 return -ENOMEM; 8641 } 8642 8643 skb_put(skb, len); 8644 h2c = (struct rtw89_h2c_wow_gtk_ofld *)skb->data; 8645 8646 if (!enable) 8647 goto hdr; 8648 8649 ret = rtw89_fw_h2c_add_general_pkt(rtwdev, rtwvif_link, 8650 RTW89_PKT_OFLD_TYPE_EAPOL_KEY, 8651 &pkt_id_eapol); 8652 if (ret) 8653 goto fail; 8654 8655 if (gtk_info->igtk_keyid) { 8656 ret = rtw89_fw_h2c_add_general_pkt(rtwdev, rtwvif_link, 8657 RTW89_PKT_OFLD_TYPE_SA_QUERY, 8658 &pkt_id_sa_query); 8659 if (ret) 8660 goto fail; 8661 } 8662 8663 /* not support TKIP yet */ 8664 h2c->w0 = le32_encode_bits(enable, RTW89_H2C_WOW_GTK_OFLD_W0_EN) | 8665 le32_encode_bits(0, RTW89_H2C_WOW_GTK_OFLD_W0_TKIP_EN) | 8666 le32_encode_bits(gtk_info->igtk_keyid ? 1 : 0, 8667 RTW89_H2C_WOW_GTK_OFLD_W0_IEEE80211W_EN) | 8668 le32_encode_bits(macid, RTW89_H2C_WOW_GTK_OFLD_W0_MAC_ID) | 8669 le32_encode_bits(pkt_id_eapol, RTW89_H2C_WOW_GTK_OFLD_W0_GTK_RSP_ID); 8670 h2c->w1 = le32_encode_bits(gtk_info->igtk_keyid ? pkt_id_sa_query : 0, 8671 RTW89_H2C_WOW_GTK_OFLD_W1_PMF_SA_QUERY_ID) | 8672 le32_encode_bits(rtw_wow->akm, RTW89_H2C_WOW_GTK_OFLD_W1_ALGO_AKM_SUIT); 8673 h2c->gtk_info = rtw_wow->gtk_info; 8674 8675 hdr: 8676 rtw89_h2c_pkt_set_hdr(rtwdev, skb, FWCMD_TYPE_H2C, 8677 H2C_CAT_MAC, 8678 H2C_CL_MAC_WOW, 8679 H2C_FUNC_GTK_OFLD, 0, 1, 8680 len); 8681 8682 ret = rtw89_h2c_tx(rtwdev, skb, false); 8683 if (ret) { 8684 rtw89_err(rtwdev, "failed to send h2c\n"); 8685 goto fail; 8686 } 8687 return 0; 8688 fail: 8689 dev_kfree_skb_any(skb); 8690 8691 return ret; 8692 } 8693 8694 int rtw89_fw_h2c_fwips(struct rtw89_dev *rtwdev, struct rtw89_vif_link *rtwvif_link, 8695 bool enable) 8696 { 8697 struct rtw89_wait_info *wait = &rtwdev->mac.ps_wait; 8698 struct rtw89_h2c_fwips *h2c; 8699 u32 len = sizeof(*h2c); 8700 struct sk_buff *skb; 8701 8702 skb = rtw89_fw_h2c_alloc_skb_with_hdr(rtwdev, len); 8703 if (!skb) { 8704 rtw89_err(rtwdev, "failed to alloc skb for fw ips\n"); 8705 return -ENOMEM; 8706 } 8707 skb_put(skb, len); 8708 h2c = (struct rtw89_h2c_fwips *)skb->data; 8709 8710 h2c->w0 = le32_encode_bits(rtwvif_link->mac_id, RTW89_H2C_FW_IPS_W0_MACID) | 8711 le32_encode_bits(enable, RTW89_H2C_FW_IPS_W0_ENABLE); 8712 8713 rtw89_h2c_pkt_set_hdr(rtwdev, skb, FWCMD_TYPE_H2C, 8714 H2C_CAT_MAC, 8715 H2C_CL_MAC_PS, 8716 H2C_FUNC_IPS_CFG, 0, 1, 8717 len); 8718 8719 return rtw89_h2c_tx_and_wait(rtwdev, skb, wait, RTW89_PS_WAIT_COND_IPS_CFG); 8720 } 8721 8722 int rtw89_fw_h2c_wow_request_aoac(struct rtw89_dev *rtwdev) 8723 { 8724 struct rtw89_wait_info *wait = &rtwdev->wow.wait; 8725 struct rtw89_h2c_wow_aoac *h2c; 8726 u32 len = sizeof(*h2c); 8727 struct sk_buff *skb; 8728 8729 skb = rtw89_fw_h2c_alloc_skb_with_hdr(rtwdev, len); 8730 if (!skb) { 8731 rtw89_err(rtwdev, "failed to alloc skb for aoac\n"); 8732 return -ENOMEM; 8733 } 8734 8735 skb_put(skb, len); 8736 8737 /* This H2C only nofity firmware to generate AOAC report C2H, 8738 * no need any parameter. 8739 */ 8740 rtw89_h2c_pkt_set_hdr(rtwdev, skb, FWCMD_TYPE_H2C, 8741 H2C_CAT_MAC, 8742 H2C_CL_MAC_WOW, 8743 H2C_FUNC_AOAC_REPORT_REQ, 1, 0, 8744 len); 8745 8746 return rtw89_h2c_tx_and_wait(rtwdev, skb, wait, RTW89_WOW_WAIT_COND_AOAC); 8747 } 8748 8749 /* Return < 0, if failures happen during waiting for the condition. 8750 * Return 0, when waiting for the condition succeeds. 8751 * Return > 0, if the wait is considered unreachable due to driver/FW design, 8752 * where 1 means during SER. 8753 */ 8754 static int rtw89_h2c_tx_and_wait(struct rtw89_dev *rtwdev, struct sk_buff *skb, 8755 struct rtw89_wait_info *wait, unsigned int cond) 8756 { 8757 int ret; 8758 8759 ret = rtw89_h2c_tx(rtwdev, skb, false); 8760 if (ret) { 8761 rtw89_err(rtwdev, "failed to send h2c\n"); 8762 dev_kfree_skb_any(skb); 8763 return -EBUSY; 8764 } 8765 8766 if (test_bit(RTW89_FLAG_SER_HANDLING, rtwdev->flags)) 8767 return 1; 8768 8769 return rtw89_wait_for_cond(wait, cond); 8770 } 8771 8772 #define H2C_ADD_MCC_LEN 16 8773 int rtw89_fw_h2c_add_mcc(struct rtw89_dev *rtwdev, 8774 const struct rtw89_fw_mcc_add_req *p) 8775 { 8776 struct rtw89_wait_info *wait = &rtwdev->mcc.wait; 8777 struct sk_buff *skb; 8778 unsigned int cond; 8779 8780 skb = rtw89_fw_h2c_alloc_skb_with_hdr(rtwdev, H2C_ADD_MCC_LEN); 8781 if (!skb) { 8782 rtw89_err(rtwdev, 8783 "failed to alloc skb for add mcc\n"); 8784 return -ENOMEM; 8785 } 8786 8787 skb_put(skb, H2C_ADD_MCC_LEN); 8788 RTW89_SET_FWCMD_ADD_MCC_MACID(skb->data, p->macid); 8789 RTW89_SET_FWCMD_ADD_MCC_CENTRAL_CH_SEG0(skb->data, p->central_ch_seg0); 8790 RTW89_SET_FWCMD_ADD_MCC_CENTRAL_CH_SEG1(skb->data, p->central_ch_seg1); 8791 RTW89_SET_FWCMD_ADD_MCC_PRIMARY_CH(skb->data, p->primary_ch); 8792 RTW89_SET_FWCMD_ADD_MCC_BANDWIDTH(skb->data, p->bandwidth); 8793 RTW89_SET_FWCMD_ADD_MCC_GROUP(skb->data, p->group); 8794 RTW89_SET_FWCMD_ADD_MCC_C2H_RPT(skb->data, p->c2h_rpt); 8795 RTW89_SET_FWCMD_ADD_MCC_DIS_TX_NULL(skb->data, p->dis_tx_null); 8796 RTW89_SET_FWCMD_ADD_MCC_DIS_SW_RETRY(skb->data, p->dis_sw_retry); 8797 RTW89_SET_FWCMD_ADD_MCC_IN_CURR_CH(skb->data, p->in_curr_ch); 8798 RTW89_SET_FWCMD_ADD_MCC_SW_RETRY_COUNT(skb->data, p->sw_retry_count); 8799 RTW89_SET_FWCMD_ADD_MCC_TX_NULL_EARLY(skb->data, p->tx_null_early); 8800 RTW89_SET_FWCMD_ADD_MCC_BTC_IN_2G(skb->data, p->btc_in_2g); 8801 RTW89_SET_FWCMD_ADD_MCC_PTA_EN(skb->data, p->pta_en); 8802 RTW89_SET_FWCMD_ADD_MCC_RFK_BY_PASS(skb->data, p->rfk_by_pass); 8803 RTW89_SET_FWCMD_ADD_MCC_CH_BAND_TYPE(skb->data, p->ch_band_type); 8804 RTW89_SET_FWCMD_ADD_MCC_DURATION(skb->data, p->duration); 8805 RTW89_SET_FWCMD_ADD_MCC_COURTESY_EN(skb->data, p->courtesy_en); 8806 RTW89_SET_FWCMD_ADD_MCC_COURTESY_NUM(skb->data, p->courtesy_num); 8807 RTW89_SET_FWCMD_ADD_MCC_COURTESY_TARGET(skb->data, p->courtesy_target); 8808 8809 rtw89_h2c_pkt_set_hdr(rtwdev, skb, FWCMD_TYPE_H2C, 8810 H2C_CAT_MAC, 8811 H2C_CL_MCC, 8812 H2C_FUNC_ADD_MCC, 0, 0, 8813 H2C_ADD_MCC_LEN); 8814 8815 cond = RTW89_MCC_WAIT_COND(p->group, H2C_FUNC_ADD_MCC); 8816 return rtw89_h2c_tx_and_wait(rtwdev, skb, wait, cond); 8817 } 8818 8819 #define H2C_START_MCC_LEN 12 8820 int rtw89_fw_h2c_start_mcc(struct rtw89_dev *rtwdev, 8821 const struct rtw89_fw_mcc_start_req *p) 8822 { 8823 struct rtw89_wait_info *wait = &rtwdev->mcc.wait; 8824 struct sk_buff *skb; 8825 unsigned int cond; 8826 8827 skb = rtw89_fw_h2c_alloc_skb_with_hdr(rtwdev, H2C_START_MCC_LEN); 8828 if (!skb) { 8829 rtw89_err(rtwdev, 8830 "failed to alloc skb for start mcc\n"); 8831 return -ENOMEM; 8832 } 8833 8834 skb_put(skb, H2C_START_MCC_LEN); 8835 RTW89_SET_FWCMD_START_MCC_GROUP(skb->data, p->group); 8836 RTW89_SET_FWCMD_START_MCC_BTC_IN_GROUP(skb->data, p->btc_in_group); 8837 RTW89_SET_FWCMD_START_MCC_OLD_GROUP_ACTION(skb->data, p->old_group_action); 8838 RTW89_SET_FWCMD_START_MCC_OLD_GROUP(skb->data, p->old_group); 8839 RTW89_SET_FWCMD_START_MCC_NOTIFY_CNT(skb->data, p->notify_cnt); 8840 RTW89_SET_FWCMD_START_MCC_NOTIFY_RXDBG_EN(skb->data, p->notify_rxdbg_en); 8841 RTW89_SET_FWCMD_START_MCC_MACID(skb->data, p->macid); 8842 RTW89_SET_FWCMD_START_MCC_TSF_LOW(skb->data, p->tsf_low); 8843 RTW89_SET_FWCMD_START_MCC_TSF_HIGH(skb->data, p->tsf_high); 8844 8845 rtw89_h2c_pkt_set_hdr(rtwdev, skb, FWCMD_TYPE_H2C, 8846 H2C_CAT_MAC, 8847 H2C_CL_MCC, 8848 H2C_FUNC_START_MCC, 0, 0, 8849 H2C_START_MCC_LEN); 8850 8851 cond = RTW89_MCC_WAIT_COND(p->group, H2C_FUNC_START_MCC); 8852 return rtw89_h2c_tx_and_wait(rtwdev, skb, wait, cond); 8853 } 8854 8855 #define H2C_STOP_MCC_LEN 4 8856 int rtw89_fw_h2c_stop_mcc(struct rtw89_dev *rtwdev, u8 group, u8 macid, 8857 bool prev_groups) 8858 { 8859 struct rtw89_wait_info *wait = &rtwdev->mcc.wait; 8860 struct sk_buff *skb; 8861 unsigned int cond; 8862 8863 skb = rtw89_fw_h2c_alloc_skb_with_hdr(rtwdev, H2C_STOP_MCC_LEN); 8864 if (!skb) { 8865 rtw89_err(rtwdev, 8866 "failed to alloc skb for stop mcc\n"); 8867 return -ENOMEM; 8868 } 8869 8870 skb_put(skb, H2C_STOP_MCC_LEN); 8871 RTW89_SET_FWCMD_STOP_MCC_MACID(skb->data, macid); 8872 RTW89_SET_FWCMD_STOP_MCC_GROUP(skb->data, group); 8873 RTW89_SET_FWCMD_STOP_MCC_PREV_GROUPS(skb->data, prev_groups); 8874 8875 rtw89_h2c_pkt_set_hdr(rtwdev, skb, FWCMD_TYPE_H2C, 8876 H2C_CAT_MAC, 8877 H2C_CL_MCC, 8878 H2C_FUNC_STOP_MCC, 0, 0, 8879 H2C_STOP_MCC_LEN); 8880 8881 cond = RTW89_MCC_WAIT_COND(group, H2C_FUNC_STOP_MCC); 8882 return rtw89_h2c_tx_and_wait(rtwdev, skb, wait, cond); 8883 } 8884 8885 #define H2C_DEL_MCC_GROUP_LEN 4 8886 int rtw89_fw_h2c_del_mcc_group(struct rtw89_dev *rtwdev, u8 group, 8887 bool prev_groups) 8888 { 8889 struct rtw89_wait_info *wait = &rtwdev->mcc.wait; 8890 struct sk_buff *skb; 8891 unsigned int cond; 8892 8893 skb = rtw89_fw_h2c_alloc_skb_with_hdr(rtwdev, H2C_DEL_MCC_GROUP_LEN); 8894 if (!skb) { 8895 rtw89_err(rtwdev, 8896 "failed to alloc skb for del mcc group\n"); 8897 return -ENOMEM; 8898 } 8899 8900 skb_put(skb, H2C_DEL_MCC_GROUP_LEN); 8901 RTW89_SET_FWCMD_DEL_MCC_GROUP_GROUP(skb->data, group); 8902 RTW89_SET_FWCMD_DEL_MCC_GROUP_PREV_GROUPS(skb->data, prev_groups); 8903 8904 rtw89_h2c_pkt_set_hdr(rtwdev, skb, FWCMD_TYPE_H2C, 8905 H2C_CAT_MAC, 8906 H2C_CL_MCC, 8907 H2C_FUNC_DEL_MCC_GROUP, 0, 0, 8908 H2C_DEL_MCC_GROUP_LEN); 8909 8910 cond = RTW89_MCC_WAIT_COND(group, H2C_FUNC_DEL_MCC_GROUP); 8911 return rtw89_h2c_tx_and_wait(rtwdev, skb, wait, cond); 8912 } 8913 8914 #define H2C_RESET_MCC_GROUP_LEN 4 8915 int rtw89_fw_h2c_reset_mcc_group(struct rtw89_dev *rtwdev, u8 group) 8916 { 8917 struct rtw89_wait_info *wait = &rtwdev->mcc.wait; 8918 struct sk_buff *skb; 8919 unsigned int cond; 8920 8921 skb = rtw89_fw_h2c_alloc_skb_with_hdr(rtwdev, H2C_RESET_MCC_GROUP_LEN); 8922 if (!skb) { 8923 rtw89_err(rtwdev, 8924 "failed to alloc skb for reset mcc group\n"); 8925 return -ENOMEM; 8926 } 8927 8928 skb_put(skb, H2C_RESET_MCC_GROUP_LEN); 8929 RTW89_SET_FWCMD_RESET_MCC_GROUP_GROUP(skb->data, group); 8930 8931 rtw89_h2c_pkt_set_hdr(rtwdev, skb, FWCMD_TYPE_H2C, 8932 H2C_CAT_MAC, 8933 H2C_CL_MCC, 8934 H2C_FUNC_RESET_MCC_GROUP, 0, 0, 8935 H2C_RESET_MCC_GROUP_LEN); 8936 8937 cond = RTW89_MCC_WAIT_COND(group, H2C_FUNC_RESET_MCC_GROUP); 8938 return rtw89_h2c_tx_and_wait(rtwdev, skb, wait, cond); 8939 } 8940 8941 #define H2C_MCC_REQ_TSF_LEN 4 8942 int rtw89_fw_h2c_mcc_req_tsf(struct rtw89_dev *rtwdev, 8943 const struct rtw89_fw_mcc_tsf_req *req, 8944 struct rtw89_mac_mcc_tsf_rpt *rpt) 8945 { 8946 struct rtw89_wait_info *wait = &rtwdev->mcc.wait; 8947 struct rtw89_mac_mcc_tsf_rpt *tmp; 8948 struct sk_buff *skb; 8949 unsigned int cond; 8950 int ret; 8951 8952 skb = rtw89_fw_h2c_alloc_skb_with_hdr(rtwdev, H2C_MCC_REQ_TSF_LEN); 8953 if (!skb) { 8954 rtw89_err(rtwdev, 8955 "failed to alloc skb for mcc req tsf\n"); 8956 return -ENOMEM; 8957 } 8958 8959 skb_put(skb, H2C_MCC_REQ_TSF_LEN); 8960 RTW89_SET_FWCMD_MCC_REQ_TSF_GROUP(skb->data, req->group); 8961 RTW89_SET_FWCMD_MCC_REQ_TSF_MACID_X(skb->data, req->macid_x); 8962 RTW89_SET_FWCMD_MCC_REQ_TSF_MACID_Y(skb->data, req->macid_y); 8963 8964 rtw89_h2c_pkt_set_hdr(rtwdev, skb, FWCMD_TYPE_H2C, 8965 H2C_CAT_MAC, 8966 H2C_CL_MCC, 8967 H2C_FUNC_MCC_REQ_TSF, 0, 0, 8968 H2C_MCC_REQ_TSF_LEN); 8969 8970 cond = RTW89_MCC_WAIT_COND(req->group, H2C_FUNC_MCC_REQ_TSF); 8971 ret = rtw89_h2c_tx_and_wait(rtwdev, skb, wait, cond); 8972 if (ret) 8973 return ret; 8974 8975 tmp = (struct rtw89_mac_mcc_tsf_rpt *)wait->data.buf; 8976 *rpt = *tmp; 8977 8978 return 0; 8979 } 8980 8981 #define H2C_MCC_MACID_BITMAP_DSC_LEN 4 8982 int rtw89_fw_h2c_mcc_macid_bitmap(struct rtw89_dev *rtwdev, u8 group, u8 macid, 8983 u8 *bitmap) 8984 { 8985 struct rtw89_wait_info *wait = &rtwdev->mcc.wait; 8986 struct sk_buff *skb; 8987 unsigned int cond; 8988 u8 map_len; 8989 u8 h2c_len; 8990 8991 BUILD_BUG_ON(RTW89_MAX_MAC_ID_NUM % 8); 8992 map_len = RTW89_MAX_MAC_ID_NUM / 8; 8993 h2c_len = H2C_MCC_MACID_BITMAP_DSC_LEN + map_len; 8994 skb = rtw89_fw_h2c_alloc_skb_with_hdr(rtwdev, h2c_len); 8995 if (!skb) { 8996 rtw89_err(rtwdev, 8997 "failed to alloc skb for mcc macid bitmap\n"); 8998 return -ENOMEM; 8999 } 9000 9001 skb_put(skb, h2c_len); 9002 RTW89_SET_FWCMD_MCC_MACID_BITMAP_GROUP(skb->data, group); 9003 RTW89_SET_FWCMD_MCC_MACID_BITMAP_MACID(skb->data, macid); 9004 RTW89_SET_FWCMD_MCC_MACID_BITMAP_BITMAP_LENGTH(skb->data, map_len); 9005 RTW89_SET_FWCMD_MCC_MACID_BITMAP_BITMAP(skb->data, bitmap, map_len); 9006 9007 rtw89_h2c_pkt_set_hdr(rtwdev, skb, FWCMD_TYPE_H2C, 9008 H2C_CAT_MAC, 9009 H2C_CL_MCC, 9010 H2C_FUNC_MCC_MACID_BITMAP, 0, 0, 9011 h2c_len); 9012 9013 cond = RTW89_MCC_WAIT_COND(group, H2C_FUNC_MCC_MACID_BITMAP); 9014 return rtw89_h2c_tx_and_wait(rtwdev, skb, wait, cond); 9015 } 9016 9017 #define H2C_MCC_SYNC_LEN 4 9018 int rtw89_fw_h2c_mcc_sync(struct rtw89_dev *rtwdev, u8 group, u8 source, 9019 u8 target, u8 offset) 9020 { 9021 struct rtw89_wait_info *wait = &rtwdev->mcc.wait; 9022 struct sk_buff *skb; 9023 unsigned int cond; 9024 9025 skb = rtw89_fw_h2c_alloc_skb_with_hdr(rtwdev, H2C_MCC_SYNC_LEN); 9026 if (!skb) { 9027 rtw89_err(rtwdev, 9028 "failed to alloc skb for mcc sync\n"); 9029 return -ENOMEM; 9030 } 9031 9032 skb_put(skb, H2C_MCC_SYNC_LEN); 9033 RTW89_SET_FWCMD_MCC_SYNC_GROUP(skb->data, group); 9034 RTW89_SET_FWCMD_MCC_SYNC_MACID_SOURCE(skb->data, source); 9035 RTW89_SET_FWCMD_MCC_SYNC_MACID_TARGET(skb->data, target); 9036 RTW89_SET_FWCMD_MCC_SYNC_SYNC_OFFSET(skb->data, offset); 9037 9038 rtw89_h2c_pkt_set_hdr(rtwdev, skb, FWCMD_TYPE_H2C, 9039 H2C_CAT_MAC, 9040 H2C_CL_MCC, 9041 H2C_FUNC_MCC_SYNC, 0, 0, 9042 H2C_MCC_SYNC_LEN); 9043 9044 cond = RTW89_MCC_WAIT_COND(group, H2C_FUNC_MCC_SYNC); 9045 return rtw89_h2c_tx_and_wait(rtwdev, skb, wait, cond); 9046 } 9047 9048 #define H2C_MCC_SET_DURATION_LEN 20 9049 int rtw89_fw_h2c_mcc_set_duration(struct rtw89_dev *rtwdev, 9050 const struct rtw89_fw_mcc_duration *p) 9051 { 9052 struct rtw89_wait_info *wait = &rtwdev->mcc.wait; 9053 struct sk_buff *skb; 9054 unsigned int cond; 9055 9056 skb = rtw89_fw_h2c_alloc_skb_with_hdr(rtwdev, H2C_MCC_SET_DURATION_LEN); 9057 if (!skb) { 9058 rtw89_err(rtwdev, 9059 "failed to alloc skb for mcc set duration\n"); 9060 return -ENOMEM; 9061 } 9062 9063 skb_put(skb, H2C_MCC_SET_DURATION_LEN); 9064 RTW89_SET_FWCMD_MCC_SET_DURATION_GROUP(skb->data, p->group); 9065 RTW89_SET_FWCMD_MCC_SET_DURATION_BTC_IN_GROUP(skb->data, p->btc_in_group); 9066 RTW89_SET_FWCMD_MCC_SET_DURATION_START_MACID(skb->data, p->start_macid); 9067 RTW89_SET_FWCMD_MCC_SET_DURATION_MACID_X(skb->data, p->macid_x); 9068 RTW89_SET_FWCMD_MCC_SET_DURATION_MACID_Y(skb->data, p->macid_y); 9069 RTW89_SET_FWCMD_MCC_SET_DURATION_START_TSF_LOW(skb->data, 9070 p->start_tsf_low); 9071 RTW89_SET_FWCMD_MCC_SET_DURATION_START_TSF_HIGH(skb->data, 9072 p->start_tsf_high); 9073 RTW89_SET_FWCMD_MCC_SET_DURATION_DURATION_X(skb->data, p->duration_x); 9074 RTW89_SET_FWCMD_MCC_SET_DURATION_DURATION_Y(skb->data, p->duration_y); 9075 9076 rtw89_h2c_pkt_set_hdr(rtwdev, skb, FWCMD_TYPE_H2C, 9077 H2C_CAT_MAC, 9078 H2C_CL_MCC, 9079 H2C_FUNC_MCC_SET_DURATION, 0, 0, 9080 H2C_MCC_SET_DURATION_LEN); 9081 9082 cond = RTW89_MCC_WAIT_COND(p->group, H2C_FUNC_MCC_SET_DURATION); 9083 return rtw89_h2c_tx_and_wait(rtwdev, skb, wait, cond); 9084 } 9085 9086 static 9087 u32 rtw89_fw_h2c_mrc_add_slot(struct rtw89_dev *rtwdev, 9088 const struct rtw89_fw_mrc_add_slot_arg *slot_arg, 9089 struct rtw89_h2c_mrc_add_slot *slot_h2c) 9090 { 9091 bool fill_h2c = !!slot_h2c; 9092 unsigned int i; 9093 9094 if (!fill_h2c) 9095 goto calc_len; 9096 9097 slot_h2c->w0 = le32_encode_bits(slot_arg->duration, 9098 RTW89_H2C_MRC_ADD_SLOT_W0_DURATION) | 9099 le32_encode_bits(slot_arg->courtesy_en, 9100 RTW89_H2C_MRC_ADD_SLOT_W0_COURTESY_EN) | 9101 le32_encode_bits(slot_arg->role_num, 9102 RTW89_H2C_MRC_ADD_SLOT_W0_ROLE_NUM); 9103 slot_h2c->w1 = le32_encode_bits(slot_arg->courtesy_period, 9104 RTW89_H2C_MRC_ADD_SLOT_W1_COURTESY_PERIOD) | 9105 le32_encode_bits(slot_arg->courtesy_target, 9106 RTW89_H2C_MRC_ADD_SLOT_W1_COURTESY_TARGET); 9107 9108 for (i = 0; i < slot_arg->role_num; i++) { 9109 slot_h2c->roles[i].w0 = 9110 le32_encode_bits(slot_arg->roles[i].macid, 9111 RTW89_H2C_MRC_ADD_ROLE_W0_MACID) | 9112 le32_encode_bits(slot_arg->roles[i].role_type, 9113 RTW89_H2C_MRC_ADD_ROLE_W0_ROLE_TYPE) | 9114 le32_encode_bits(slot_arg->roles[i].is_master, 9115 RTW89_H2C_MRC_ADD_ROLE_W0_IS_MASTER) | 9116 le32_encode_bits(slot_arg->roles[i].en_tx_null, 9117 RTW89_H2C_MRC_ADD_ROLE_W0_TX_NULL_EN) | 9118 le32_encode_bits(false, 9119 RTW89_H2C_MRC_ADD_ROLE_W0_IS_ALT_ROLE) | 9120 le32_encode_bits(false, 9121 RTW89_H2C_MRC_ADD_ROLE_W0_ROLE_ALT_EN); 9122 slot_h2c->roles[i].w1 = 9123 le32_encode_bits(slot_arg->roles[i].central_ch, 9124 RTW89_H2C_MRC_ADD_ROLE_W1_CENTRAL_CH_SEG) | 9125 le32_encode_bits(slot_arg->roles[i].primary_ch, 9126 RTW89_H2C_MRC_ADD_ROLE_W1_PRI_CH) | 9127 le32_encode_bits(slot_arg->roles[i].bw, 9128 RTW89_H2C_MRC_ADD_ROLE_W1_BW) | 9129 le32_encode_bits(slot_arg->roles[i].band, 9130 RTW89_H2C_MRC_ADD_ROLE_W1_CH_BAND_TYPE) | 9131 le32_encode_bits(slot_arg->roles[i].null_early, 9132 RTW89_H2C_MRC_ADD_ROLE_W1_NULL_EARLY) | 9133 le32_encode_bits(false, 9134 RTW89_H2C_MRC_ADD_ROLE_W1_RFK_BY_PASS) | 9135 le32_encode_bits(true, 9136 RTW89_H2C_MRC_ADD_ROLE_W1_CAN_BTC); 9137 slot_h2c->roles[i].macid_main_bitmap = 9138 cpu_to_le32(slot_arg->roles[i].macid_main_bitmap); 9139 slot_h2c->roles[i].macid_paired_bitmap = 9140 cpu_to_le32(slot_arg->roles[i].macid_paired_bitmap); 9141 } 9142 9143 calc_len: 9144 return struct_size(slot_h2c, roles, slot_arg->role_num); 9145 } 9146 9147 int rtw89_fw_h2c_mrc_add(struct rtw89_dev *rtwdev, 9148 const struct rtw89_fw_mrc_add_arg *arg) 9149 { 9150 struct rtw89_h2c_mrc_add *h2c_head; 9151 struct sk_buff *skb; 9152 unsigned int i; 9153 #if defined(__linux__) 9154 void *tmp; 9155 #elif defined(__FreeBSD__) 9156 u8 *tmp; 9157 #endif 9158 u32 len; 9159 int ret; 9160 9161 len = sizeof(*h2c_head); 9162 for (i = 0; i < arg->slot_num; i++) 9163 len += rtw89_fw_h2c_mrc_add_slot(rtwdev, &arg->slots[i], NULL); 9164 9165 skb = rtw89_fw_h2c_alloc_skb_with_hdr(rtwdev, len); 9166 if (!skb) { 9167 rtw89_err(rtwdev, "failed to alloc skb for mrc add\n"); 9168 return -ENOMEM; 9169 } 9170 9171 skb_put(skb, len); 9172 tmp = skb->data; 9173 9174 #if defined(__linux__) 9175 h2c_head = tmp; 9176 #elif defined(__FreeBSD__) 9177 h2c_head = (void *)tmp; 9178 #endif 9179 h2c_head->w0 = le32_encode_bits(arg->sch_idx, 9180 RTW89_H2C_MRC_ADD_W0_SCH_IDX) | 9181 le32_encode_bits(arg->sch_type, 9182 RTW89_H2C_MRC_ADD_W0_SCH_TYPE) | 9183 le32_encode_bits(arg->slot_num, 9184 RTW89_H2C_MRC_ADD_W0_SLOT_NUM) | 9185 le32_encode_bits(arg->btc_in_sch, 9186 RTW89_H2C_MRC_ADD_W0_BTC_IN_SCH); 9187 9188 tmp += sizeof(*h2c_head); 9189 for (i = 0; i < arg->slot_num; i++) 9190 #if defined(__linux__) 9191 tmp += rtw89_fw_h2c_mrc_add_slot(rtwdev, &arg->slots[i], tmp); 9192 #elif defined(__FreeBSD__) 9193 tmp += rtw89_fw_h2c_mrc_add_slot(rtwdev, &arg->slots[i], (void *)tmp); 9194 #endif 9195 9196 rtw89_h2c_pkt_set_hdr(rtwdev, skb, FWCMD_TYPE_H2C, 9197 H2C_CAT_MAC, 9198 H2C_CL_MRC, 9199 H2C_FUNC_ADD_MRC, 0, 0, 9200 len); 9201 9202 ret = rtw89_h2c_tx(rtwdev, skb, false); 9203 if (ret) { 9204 rtw89_err(rtwdev, "failed to send h2c\n"); 9205 dev_kfree_skb_any(skb); 9206 return -EBUSY; 9207 } 9208 9209 return 0; 9210 } 9211 9212 int rtw89_fw_h2c_mrc_start(struct rtw89_dev *rtwdev, 9213 const struct rtw89_fw_mrc_start_arg *arg) 9214 { 9215 struct rtw89_wait_info *wait = &rtwdev->mcc.wait; 9216 struct rtw89_h2c_mrc_start *h2c; 9217 u32 len = sizeof(*h2c); 9218 struct sk_buff *skb; 9219 unsigned int cond; 9220 9221 skb = rtw89_fw_h2c_alloc_skb_with_hdr(rtwdev, len); 9222 if (!skb) { 9223 rtw89_err(rtwdev, "failed to alloc skb for mrc start\n"); 9224 return -ENOMEM; 9225 } 9226 9227 skb_put(skb, len); 9228 h2c = (struct rtw89_h2c_mrc_start *)skb->data; 9229 9230 h2c->w0 = le32_encode_bits(arg->sch_idx, 9231 RTW89_H2C_MRC_START_W0_SCH_IDX) | 9232 le32_encode_bits(arg->old_sch_idx, 9233 RTW89_H2C_MRC_START_W0_OLD_SCH_IDX) | 9234 le32_encode_bits(arg->action, 9235 RTW89_H2C_MRC_START_W0_ACTION); 9236 9237 h2c->start_tsf_high = cpu_to_le32(arg->start_tsf >> 32); 9238 h2c->start_tsf_low = cpu_to_le32(arg->start_tsf); 9239 9240 rtw89_h2c_pkt_set_hdr(rtwdev, skb, FWCMD_TYPE_H2C, 9241 H2C_CAT_MAC, 9242 H2C_CL_MRC, 9243 H2C_FUNC_START_MRC, 0, 0, 9244 len); 9245 9246 cond = RTW89_MRC_WAIT_COND(arg->sch_idx, H2C_FUNC_START_MRC); 9247 return rtw89_h2c_tx_and_wait(rtwdev, skb, wait, cond); 9248 } 9249 9250 int rtw89_fw_h2c_mrc_del(struct rtw89_dev *rtwdev, u8 sch_idx, u8 slot_idx) 9251 { 9252 struct rtw89_wait_info *wait = &rtwdev->mcc.wait; 9253 struct rtw89_h2c_mrc_del *h2c; 9254 u32 len = sizeof(*h2c); 9255 struct sk_buff *skb; 9256 unsigned int cond; 9257 9258 skb = rtw89_fw_h2c_alloc_skb_with_hdr(rtwdev, len); 9259 if (!skb) { 9260 rtw89_err(rtwdev, "failed to alloc skb for mrc del\n"); 9261 return -ENOMEM; 9262 } 9263 9264 skb_put(skb, len); 9265 h2c = (struct rtw89_h2c_mrc_del *)skb->data; 9266 9267 h2c->w0 = le32_encode_bits(sch_idx, RTW89_H2C_MRC_DEL_W0_SCH_IDX) | 9268 le32_encode_bits(slot_idx, RTW89_H2C_MRC_DEL_W0_STOP_SLOT_IDX); 9269 9270 rtw89_h2c_pkt_set_hdr(rtwdev, skb, FWCMD_TYPE_H2C, 9271 H2C_CAT_MAC, 9272 H2C_CL_MRC, 9273 H2C_FUNC_DEL_MRC, 0, 0, 9274 len); 9275 9276 cond = RTW89_MRC_WAIT_COND(sch_idx, H2C_FUNC_DEL_MRC); 9277 return rtw89_h2c_tx_and_wait(rtwdev, skb, wait, cond); 9278 } 9279 9280 int rtw89_fw_h2c_mrc_req_tsf(struct rtw89_dev *rtwdev, 9281 const struct rtw89_fw_mrc_req_tsf_arg *arg, 9282 struct rtw89_mac_mrc_tsf_rpt *rpt) 9283 { 9284 struct rtw89_wait_info *wait = &rtwdev->mcc.wait; 9285 struct rtw89_h2c_mrc_req_tsf *h2c; 9286 struct rtw89_mac_mrc_tsf_rpt *tmp; 9287 struct sk_buff *skb; 9288 unsigned int i; 9289 u32 len; 9290 int ret; 9291 9292 len = struct_size(h2c, infos, arg->num); 9293 skb = rtw89_fw_h2c_alloc_skb_with_hdr(rtwdev, len); 9294 if (!skb) { 9295 rtw89_err(rtwdev, "failed to alloc skb for mrc req tsf\n"); 9296 return -ENOMEM; 9297 } 9298 9299 skb_put(skb, len); 9300 h2c = (struct rtw89_h2c_mrc_req_tsf *)skb->data; 9301 9302 h2c->req_tsf_num = arg->num; 9303 for (i = 0; i < arg->num; i++) 9304 h2c->infos[i] = 9305 u8_encode_bits(arg->infos[i].band, 9306 RTW89_H2C_MRC_REQ_TSF_INFO_BAND) | 9307 u8_encode_bits(arg->infos[i].port, 9308 RTW89_H2C_MRC_REQ_TSF_INFO_PORT); 9309 9310 rtw89_h2c_pkt_set_hdr(rtwdev, skb, FWCMD_TYPE_H2C, 9311 H2C_CAT_MAC, 9312 H2C_CL_MRC, 9313 H2C_FUNC_MRC_REQ_TSF, 0, 0, 9314 len); 9315 9316 ret = rtw89_h2c_tx_and_wait(rtwdev, skb, wait, RTW89_MRC_WAIT_COND_REQ_TSF); 9317 if (ret) 9318 return ret; 9319 9320 tmp = (struct rtw89_mac_mrc_tsf_rpt *)wait->data.buf; 9321 *rpt = *tmp; 9322 9323 return 0; 9324 } 9325 9326 int rtw89_fw_h2c_mrc_upd_bitmap(struct rtw89_dev *rtwdev, 9327 const struct rtw89_fw_mrc_upd_bitmap_arg *arg) 9328 { 9329 struct rtw89_h2c_mrc_upd_bitmap *h2c; 9330 u32 len = sizeof(*h2c); 9331 struct sk_buff *skb; 9332 int ret; 9333 9334 skb = rtw89_fw_h2c_alloc_skb_with_hdr(rtwdev, len); 9335 if (!skb) { 9336 rtw89_err(rtwdev, "failed to alloc skb for mrc upd bitmap\n"); 9337 return -ENOMEM; 9338 } 9339 9340 skb_put(skb, len); 9341 h2c = (struct rtw89_h2c_mrc_upd_bitmap *)skb->data; 9342 9343 h2c->w0 = le32_encode_bits(arg->sch_idx, 9344 RTW89_H2C_MRC_UPD_BITMAP_W0_SCH_IDX) | 9345 le32_encode_bits(arg->action, 9346 RTW89_H2C_MRC_UPD_BITMAP_W0_ACTION) | 9347 le32_encode_bits(arg->macid, 9348 RTW89_H2C_MRC_UPD_BITMAP_W0_MACID); 9349 h2c->w1 = le32_encode_bits(arg->client_macid, 9350 RTW89_H2C_MRC_UPD_BITMAP_W1_CLIENT_MACID); 9351 9352 rtw89_h2c_pkt_set_hdr(rtwdev, skb, FWCMD_TYPE_H2C, 9353 H2C_CAT_MAC, 9354 H2C_CL_MRC, 9355 H2C_FUNC_MRC_UPD_BITMAP, 0, 0, 9356 len); 9357 9358 ret = rtw89_h2c_tx(rtwdev, skb, false); 9359 if (ret) { 9360 rtw89_err(rtwdev, "failed to send h2c\n"); 9361 dev_kfree_skb_any(skb); 9362 return -EBUSY; 9363 } 9364 9365 return 0; 9366 } 9367 9368 int rtw89_fw_h2c_mrc_sync(struct rtw89_dev *rtwdev, 9369 const struct rtw89_fw_mrc_sync_arg *arg) 9370 { 9371 struct rtw89_h2c_mrc_sync *h2c; 9372 u32 len = sizeof(*h2c); 9373 struct sk_buff *skb; 9374 int ret; 9375 9376 skb = rtw89_fw_h2c_alloc_skb_with_hdr(rtwdev, len); 9377 if (!skb) { 9378 rtw89_err(rtwdev, "failed to alloc skb for mrc sync\n"); 9379 return -ENOMEM; 9380 } 9381 9382 skb_put(skb, len); 9383 h2c = (struct rtw89_h2c_mrc_sync *)skb->data; 9384 9385 h2c->w0 = le32_encode_bits(true, RTW89_H2C_MRC_SYNC_W0_SYNC_EN) | 9386 le32_encode_bits(arg->src.port, 9387 RTW89_H2C_MRC_SYNC_W0_SRC_PORT) | 9388 le32_encode_bits(arg->src.band, 9389 RTW89_H2C_MRC_SYNC_W0_SRC_BAND) | 9390 le32_encode_bits(arg->dest.port, 9391 RTW89_H2C_MRC_SYNC_W0_DEST_PORT) | 9392 le32_encode_bits(arg->dest.band, 9393 RTW89_H2C_MRC_SYNC_W0_DEST_BAND); 9394 h2c->w1 = le32_encode_bits(arg->offset, RTW89_H2C_MRC_SYNC_W1_OFFSET); 9395 9396 rtw89_h2c_pkt_set_hdr(rtwdev, skb, FWCMD_TYPE_H2C, 9397 H2C_CAT_MAC, 9398 H2C_CL_MRC, 9399 H2C_FUNC_MRC_SYNC, 0, 0, 9400 len); 9401 9402 ret = rtw89_h2c_tx(rtwdev, skb, false); 9403 if (ret) { 9404 rtw89_err(rtwdev, "failed to send h2c\n"); 9405 dev_kfree_skb_any(skb); 9406 return -EBUSY; 9407 } 9408 9409 return 0; 9410 } 9411 9412 int rtw89_fw_h2c_mrc_upd_duration(struct rtw89_dev *rtwdev, 9413 const struct rtw89_fw_mrc_upd_duration_arg *arg) 9414 { 9415 struct rtw89_h2c_mrc_upd_duration *h2c; 9416 struct sk_buff *skb; 9417 unsigned int i; 9418 u32 len; 9419 int ret; 9420 9421 len = struct_size(h2c, slots, arg->slot_num); 9422 skb = rtw89_fw_h2c_alloc_skb_with_hdr(rtwdev, len); 9423 if (!skb) { 9424 rtw89_err(rtwdev, "failed to alloc skb for mrc upd duration\n"); 9425 return -ENOMEM; 9426 } 9427 9428 skb_put(skb, len); 9429 h2c = (struct rtw89_h2c_mrc_upd_duration *)skb->data; 9430 9431 h2c->w0 = le32_encode_bits(arg->sch_idx, 9432 RTW89_H2C_MRC_UPD_DURATION_W0_SCH_IDX) | 9433 le32_encode_bits(arg->slot_num, 9434 RTW89_H2C_MRC_UPD_DURATION_W0_SLOT_NUM) | 9435 le32_encode_bits(false, 9436 RTW89_H2C_MRC_UPD_DURATION_W0_BTC_IN_SCH); 9437 9438 h2c->start_tsf_high = cpu_to_le32(arg->start_tsf >> 32); 9439 h2c->start_tsf_low = cpu_to_le32(arg->start_tsf); 9440 9441 for (i = 0; i < arg->slot_num; i++) { 9442 h2c->slots[i] = 9443 le32_encode_bits(arg->slots[i].slot_idx, 9444 RTW89_H2C_MRC_UPD_DURATION_SLOT_SLOT_IDX) | 9445 le32_encode_bits(arg->slots[i].duration, 9446 RTW89_H2C_MRC_UPD_DURATION_SLOT_DURATION); 9447 } 9448 9449 rtw89_h2c_pkt_set_hdr(rtwdev, skb, FWCMD_TYPE_H2C, 9450 H2C_CAT_MAC, 9451 H2C_CL_MRC, 9452 H2C_FUNC_MRC_UPD_DURATION, 0, 0, 9453 len); 9454 9455 ret = rtw89_h2c_tx(rtwdev, skb, false); 9456 if (ret) { 9457 rtw89_err(rtwdev, "failed to send h2c\n"); 9458 dev_kfree_skb_any(skb); 9459 return -EBUSY; 9460 } 9461 9462 return 0; 9463 } 9464 9465 static int rtw89_fw_h2c_ap_info(struct rtw89_dev *rtwdev, bool en) 9466 { 9467 struct rtw89_h2c_ap_info *h2c; 9468 u32 len = sizeof(*h2c); 9469 struct sk_buff *skb; 9470 int ret; 9471 9472 skb = rtw89_fw_h2c_alloc_skb_with_hdr(rtwdev, len); 9473 if (!skb) { 9474 rtw89_err(rtwdev, "failed to alloc skb for ap info\n"); 9475 return -ENOMEM; 9476 } 9477 9478 skb_put(skb, len); 9479 h2c = (struct rtw89_h2c_ap_info *)skb->data; 9480 9481 h2c->w0 = le32_encode_bits(en, RTW89_H2C_AP_INFO_W0_PWR_INT_EN); 9482 9483 rtw89_h2c_pkt_set_hdr(rtwdev, skb, FWCMD_TYPE_H2C, 9484 H2C_CAT_MAC, 9485 H2C_CL_AP, 9486 H2C_FUNC_AP_INFO, 0, 0, 9487 len); 9488 9489 ret = rtw89_h2c_tx(rtwdev, skb, false); 9490 if (ret) { 9491 rtw89_err(rtwdev, "failed to send h2c\n"); 9492 dev_kfree_skb_any(skb); 9493 return -EBUSY; 9494 } 9495 9496 return 0; 9497 } 9498 9499 int rtw89_fw_h2c_ap_info_refcount(struct rtw89_dev *rtwdev, bool en) 9500 { 9501 int ret; 9502 9503 if (en) { 9504 if (refcount_inc_not_zero(&rtwdev->refcount_ap_info)) 9505 return 0; 9506 } else { 9507 if (!refcount_dec_and_test(&rtwdev->refcount_ap_info)) 9508 return 0; 9509 } 9510 9511 ret = rtw89_fw_h2c_ap_info(rtwdev, en); 9512 if (ret) { 9513 if (!test_bit(RTW89_FLAG_SER_HANDLING, rtwdev->flags)) 9514 return ret; 9515 9516 /* During recovery, neither driver nor stack has full error 9517 * handling, so show a warning, but return 0 with refcount 9518 * increased normally. It can avoid underflow when calling 9519 * with @en == false later. 9520 */ 9521 rtw89_warn(rtwdev, "h2c ap_info failed during SER\n"); 9522 } 9523 9524 if (en) 9525 refcount_set(&rtwdev->refcount_ap_info, 1); 9526 9527 return 0; 9528 } 9529 9530 int rtw89_fw_h2c_mlo_link_cfg(struct rtw89_dev *rtwdev, struct rtw89_vif_link *rtwvif_link, 9531 bool enable) 9532 { 9533 struct rtw89_wait_info *wait = &rtwdev->mlo.wait; 9534 struct rtw89_h2c_mlo_link_cfg *h2c; 9535 u8 mac_id = rtwvif_link->mac_id; 9536 u32 len = sizeof(*h2c); 9537 struct sk_buff *skb; 9538 unsigned int cond; 9539 int ret; 9540 9541 skb = rtw89_fw_h2c_alloc_skb_with_hdr(rtwdev, len); 9542 if (!skb) { 9543 rtw89_err(rtwdev, "failed to alloc skb for mlo link cfg\n"); 9544 return -ENOMEM; 9545 } 9546 9547 skb_put(skb, len); 9548 h2c = (struct rtw89_h2c_mlo_link_cfg *)skb->data; 9549 9550 h2c->w0 = le32_encode_bits(mac_id, RTW89_H2C_MLO_LINK_CFG_W0_MACID) | 9551 le32_encode_bits(enable, RTW89_H2C_MLO_LINK_CFG_W0_OPTION); 9552 9553 rtw89_h2c_pkt_set_hdr(rtwdev, skb, FWCMD_TYPE_H2C, 9554 H2C_CAT_MAC, 9555 H2C_CL_MLO, 9556 H2C_FUNC_MLO_LINK_CFG, 0, 0, 9557 len); 9558 9559 cond = RTW89_MLO_WAIT_COND(mac_id, H2C_FUNC_MLO_LINK_CFG); 9560 9561 ret = rtw89_h2c_tx_and_wait(rtwdev, skb, wait, cond); 9562 if (ret) { 9563 rtw89_err(rtwdev, "mlo link cfg (%s link id %u) failed: %d\n", 9564 str_enable_disable(enable), rtwvif_link->link_id, ret); 9565 return ret; 9566 } 9567 9568 return 0; 9569 } 9570 9571 static bool __fw_txpwr_entry_zero_ext(const void *ext_ptr, u8 ext_len) 9572 { 9573 static const u8 zeros[U8_MAX] = {}; 9574 9575 return memcmp(ext_ptr, zeros, ext_len) == 0; 9576 } 9577 9578 #if defined(__linux__) 9579 #define __fw_txpwr_entry_acceptable(e, cursor, ent_sz) \ 9580 ({ \ 9581 u8 __var_sz = sizeof(*(e)); \ 9582 bool __accept; \ 9583 if (__var_sz >= (ent_sz)) \ 9584 __accept = true; \ 9585 else \ 9586 __accept = __fw_txpwr_entry_zero_ext((cursor) + __var_sz,\ 9587 (ent_sz) - __var_sz);\ 9588 __accept; \ 9589 }) 9590 #elif defined(__FreeBSD__) 9591 #define __fw_txpwr_entry_acceptable(e, cursor, ent_sz) \ 9592 ({ \ 9593 u8 __var_sz = sizeof(*(e)); \ 9594 bool __accept; \ 9595 if (__var_sz >= (ent_sz)) \ 9596 __accept = true; \ 9597 else \ 9598 __accept = __fw_txpwr_entry_zero_ext((const u8 *)(cursor) + __var_sz,\ 9599 (ent_sz) - __var_sz);\ 9600 __accept; \ 9601 }) 9602 #endif 9603 9604 static bool 9605 fw_txpwr_byrate_entry_valid(const struct rtw89_fw_txpwr_byrate_entry *e, 9606 const void *cursor, 9607 const struct rtw89_txpwr_conf *conf) 9608 { 9609 if (!__fw_txpwr_entry_acceptable(e, cursor, conf->ent_sz)) 9610 return false; 9611 9612 if (e->band >= RTW89_BAND_NUM || e->bw >= RTW89_BYR_BW_NUM) 9613 return false; 9614 9615 switch (e->rs) { 9616 case RTW89_RS_CCK: 9617 if (e->shf + e->len > RTW89_RATE_CCK_NUM) 9618 return false; 9619 break; 9620 case RTW89_RS_OFDM: 9621 if (e->shf + e->len > RTW89_RATE_OFDM_NUM) 9622 return false; 9623 break; 9624 case RTW89_RS_MCS: 9625 if (e->shf + e->len > __RTW89_RATE_MCS_NUM || 9626 e->nss >= RTW89_NSS_NUM || 9627 e->ofdma >= RTW89_OFDMA_NUM) 9628 return false; 9629 break; 9630 case RTW89_RS_HEDCM: 9631 if (e->shf + e->len > RTW89_RATE_HEDCM_NUM || 9632 e->nss >= RTW89_NSS_HEDCM_NUM || 9633 e->ofdma >= RTW89_OFDMA_NUM) 9634 return false; 9635 break; 9636 case RTW89_RS_OFFSET: 9637 if (e->shf + e->len > __RTW89_RATE_OFFSET_NUM) 9638 return false; 9639 break; 9640 default: 9641 return false; 9642 } 9643 9644 return true; 9645 } 9646 9647 static 9648 void rtw89_fw_load_txpwr_byrate(struct rtw89_dev *rtwdev, 9649 const struct rtw89_txpwr_table *tbl) 9650 { 9651 const struct rtw89_txpwr_conf *conf = tbl->data; 9652 struct rtw89_fw_txpwr_byrate_entry entry = {}; 9653 struct rtw89_txpwr_byrate *byr_head; 9654 struct rtw89_rate_desc desc = {}; 9655 #if defined(__linux__) 9656 const void *cursor; 9657 #elif defined(__FreeBSD__) 9658 const u8 *cursor; 9659 #endif 9660 u32 data; 9661 s8 *byr; 9662 int i; 9663 9664 rtw89_for_each_in_txpwr_conf(entry, cursor, conf) { 9665 if (!fw_txpwr_byrate_entry_valid(&entry, cursor, conf)) 9666 continue; 9667 9668 byr_head = &rtwdev->byr[entry.band][entry.bw]; 9669 data = le32_to_cpu(entry.data); 9670 desc.ofdma = entry.ofdma; 9671 desc.nss = entry.nss; 9672 desc.rs = entry.rs; 9673 9674 for (i = 0; i < entry.len; i++, data >>= 8) { 9675 desc.idx = entry.shf + i; 9676 byr = rtw89_phy_raw_byr_seek(rtwdev, byr_head, &desc); 9677 *byr = data & 0xff; 9678 } 9679 } 9680 } 9681 9682 static bool 9683 fw_txpwr_lmt_2ghz_entry_valid(const struct rtw89_fw_txpwr_lmt_2ghz_entry *e, 9684 const void *cursor, 9685 const struct rtw89_txpwr_conf *conf) 9686 { 9687 if (!__fw_txpwr_entry_acceptable(e, cursor, conf->ent_sz)) 9688 return false; 9689 9690 if (e->bw >= RTW89_2G_BW_NUM) 9691 return false; 9692 if (e->nt >= RTW89_NTX_NUM) 9693 return false; 9694 if (e->rs >= RTW89_RS_LMT_NUM) 9695 return false; 9696 if (e->bf >= RTW89_BF_NUM) 9697 return false; 9698 if (e->regd >= RTW89_REGD_NUM) 9699 return false; 9700 if (e->ch_idx >= RTW89_2G_CH_NUM) 9701 return false; 9702 9703 return true; 9704 } 9705 9706 static 9707 void rtw89_fw_load_txpwr_lmt_2ghz(struct rtw89_txpwr_lmt_2ghz_data *data) 9708 { 9709 const struct rtw89_txpwr_conf *conf = &data->conf; 9710 struct rtw89_fw_txpwr_lmt_2ghz_entry entry = {}; 9711 #if defined(__linux__) 9712 const void *cursor; 9713 #elif defined(__FreeBSD__) 9714 const u8 *cursor; 9715 #endif 9716 9717 rtw89_for_each_in_txpwr_conf(entry, cursor, conf) { 9718 if (!fw_txpwr_lmt_2ghz_entry_valid(&entry, cursor, conf)) 9719 continue; 9720 9721 data->v[entry.bw][entry.nt][entry.rs][entry.bf][entry.regd] 9722 [entry.ch_idx] = entry.v; 9723 } 9724 } 9725 9726 static bool 9727 fw_txpwr_lmt_5ghz_entry_valid(const struct rtw89_fw_txpwr_lmt_5ghz_entry *e, 9728 const void *cursor, 9729 const struct rtw89_txpwr_conf *conf) 9730 { 9731 if (!__fw_txpwr_entry_acceptable(e, cursor, conf->ent_sz)) 9732 return false; 9733 9734 if (e->bw >= RTW89_5G_BW_NUM) 9735 return false; 9736 if (e->nt >= RTW89_NTX_NUM) 9737 return false; 9738 if (e->rs >= RTW89_RS_LMT_NUM) 9739 return false; 9740 if (e->bf >= RTW89_BF_NUM) 9741 return false; 9742 if (e->regd >= RTW89_REGD_NUM) 9743 return false; 9744 if (e->ch_idx >= RTW89_5G_CH_NUM) 9745 return false; 9746 9747 return true; 9748 } 9749 9750 static 9751 void rtw89_fw_load_txpwr_lmt_5ghz(struct rtw89_txpwr_lmt_5ghz_data *data) 9752 { 9753 const struct rtw89_txpwr_conf *conf = &data->conf; 9754 struct rtw89_fw_txpwr_lmt_5ghz_entry entry = {}; 9755 #if defined(__linux__) 9756 const void *cursor; 9757 #elif defined(__FreeBSD__) 9758 const u8 *cursor; 9759 #endif 9760 9761 rtw89_for_each_in_txpwr_conf(entry, cursor, conf) { 9762 if (!fw_txpwr_lmt_5ghz_entry_valid(&entry, cursor, conf)) 9763 continue; 9764 9765 data->v[entry.bw][entry.nt][entry.rs][entry.bf][entry.regd] 9766 [entry.ch_idx] = entry.v; 9767 } 9768 } 9769 9770 static bool 9771 fw_txpwr_lmt_6ghz_entry_valid(const struct rtw89_fw_txpwr_lmt_6ghz_entry *e, 9772 const void *cursor, 9773 const struct rtw89_txpwr_conf *conf) 9774 { 9775 if (!__fw_txpwr_entry_acceptable(e, cursor, conf->ent_sz)) 9776 return false; 9777 9778 if (e->bw >= RTW89_6G_BW_NUM) 9779 return false; 9780 if (e->nt >= RTW89_NTX_NUM) 9781 return false; 9782 if (e->rs >= RTW89_RS_LMT_NUM) 9783 return false; 9784 if (e->bf >= RTW89_BF_NUM) 9785 return false; 9786 if (e->regd >= RTW89_REGD_NUM) 9787 return false; 9788 if (e->reg_6ghz_power >= NUM_OF_RTW89_REG_6GHZ_POWER) 9789 return false; 9790 if (e->ch_idx >= RTW89_6G_CH_NUM) 9791 return false; 9792 9793 return true; 9794 } 9795 9796 static 9797 void rtw89_fw_load_txpwr_lmt_6ghz(struct rtw89_txpwr_lmt_6ghz_data *data) 9798 { 9799 const struct rtw89_txpwr_conf *conf = &data->conf; 9800 struct rtw89_fw_txpwr_lmt_6ghz_entry entry = {}; 9801 #if defined(__linux__) 9802 const void *cursor; 9803 #elif defined(__FreeBSD__) 9804 const u8 *cursor; 9805 #endif 9806 9807 rtw89_for_each_in_txpwr_conf(entry, cursor, conf) { 9808 if (!fw_txpwr_lmt_6ghz_entry_valid(&entry, cursor, conf)) 9809 continue; 9810 9811 data->v[entry.bw][entry.nt][entry.rs][entry.bf][entry.regd] 9812 [entry.reg_6ghz_power][entry.ch_idx] = entry.v; 9813 } 9814 } 9815 9816 static bool 9817 fw_txpwr_lmt_ru_2ghz_entry_valid(const struct rtw89_fw_txpwr_lmt_ru_2ghz_entry *e, 9818 const void *cursor, 9819 const struct rtw89_txpwr_conf *conf) 9820 { 9821 if (!__fw_txpwr_entry_acceptable(e, cursor, conf->ent_sz)) 9822 return false; 9823 9824 if (e->ru >= RTW89_RU_NUM) 9825 return false; 9826 if (e->nt >= RTW89_NTX_NUM) 9827 return false; 9828 if (e->regd >= RTW89_REGD_NUM) 9829 return false; 9830 if (e->ch_idx >= RTW89_2G_CH_NUM) 9831 return false; 9832 9833 return true; 9834 } 9835 9836 static 9837 void rtw89_fw_load_txpwr_lmt_ru_2ghz(struct rtw89_txpwr_lmt_ru_2ghz_data *data) 9838 { 9839 const struct rtw89_txpwr_conf *conf = &data->conf; 9840 struct rtw89_fw_txpwr_lmt_ru_2ghz_entry entry = {}; 9841 #if defined(__linux__) 9842 const void *cursor; 9843 #elif defined(__FreeBSD__) 9844 const u8 *cursor; 9845 #endif 9846 9847 rtw89_for_each_in_txpwr_conf(entry, cursor, conf) { 9848 if (!fw_txpwr_lmt_ru_2ghz_entry_valid(&entry, cursor, conf)) 9849 continue; 9850 9851 data->v[entry.ru][entry.nt][entry.regd][entry.ch_idx] = entry.v; 9852 } 9853 } 9854 9855 static bool 9856 fw_txpwr_lmt_ru_5ghz_entry_valid(const struct rtw89_fw_txpwr_lmt_ru_5ghz_entry *e, 9857 const void *cursor, 9858 const struct rtw89_txpwr_conf *conf) 9859 { 9860 if (!__fw_txpwr_entry_acceptable(e, cursor, conf->ent_sz)) 9861 return false; 9862 9863 if (e->ru >= RTW89_RU_NUM) 9864 return false; 9865 if (e->nt >= RTW89_NTX_NUM) 9866 return false; 9867 if (e->regd >= RTW89_REGD_NUM) 9868 return false; 9869 if (e->ch_idx >= RTW89_5G_CH_NUM) 9870 return false; 9871 9872 return true; 9873 } 9874 9875 static 9876 void rtw89_fw_load_txpwr_lmt_ru_5ghz(struct rtw89_txpwr_lmt_ru_5ghz_data *data) 9877 { 9878 const struct rtw89_txpwr_conf *conf = &data->conf; 9879 struct rtw89_fw_txpwr_lmt_ru_5ghz_entry entry = {}; 9880 #if defined(__linux__) 9881 const void *cursor; 9882 #elif defined(__FreeBSD__) 9883 const u8 *cursor; 9884 #endif 9885 9886 rtw89_for_each_in_txpwr_conf(entry, cursor, conf) { 9887 if (!fw_txpwr_lmt_ru_5ghz_entry_valid(&entry, cursor, conf)) 9888 continue; 9889 9890 data->v[entry.ru][entry.nt][entry.regd][entry.ch_idx] = entry.v; 9891 } 9892 } 9893 9894 static bool 9895 fw_txpwr_lmt_ru_6ghz_entry_valid(const struct rtw89_fw_txpwr_lmt_ru_6ghz_entry *e, 9896 const void *cursor, 9897 const struct rtw89_txpwr_conf *conf) 9898 { 9899 if (!__fw_txpwr_entry_acceptable(e, cursor, conf->ent_sz)) 9900 return false; 9901 9902 if (e->ru >= RTW89_RU_NUM) 9903 return false; 9904 if (e->nt >= RTW89_NTX_NUM) 9905 return false; 9906 if (e->regd >= RTW89_REGD_NUM) 9907 return false; 9908 if (e->reg_6ghz_power >= NUM_OF_RTW89_REG_6GHZ_POWER) 9909 return false; 9910 if (e->ch_idx >= RTW89_6G_CH_NUM) 9911 return false; 9912 9913 return true; 9914 } 9915 9916 static 9917 void rtw89_fw_load_txpwr_lmt_ru_6ghz(struct rtw89_txpwr_lmt_ru_6ghz_data *data) 9918 { 9919 const struct rtw89_txpwr_conf *conf = &data->conf; 9920 struct rtw89_fw_txpwr_lmt_ru_6ghz_entry entry = {}; 9921 #if defined(__linux__) 9922 const void *cursor; 9923 #elif defined(__FreeBSD__) 9924 const u8 *cursor; 9925 #endif 9926 9927 rtw89_for_each_in_txpwr_conf(entry, cursor, conf) { 9928 if (!fw_txpwr_lmt_ru_6ghz_entry_valid(&entry, cursor, conf)) 9929 continue; 9930 9931 data->v[entry.ru][entry.nt][entry.regd][entry.reg_6ghz_power] 9932 [entry.ch_idx] = entry.v; 9933 } 9934 } 9935 9936 static bool 9937 fw_tx_shape_lmt_entry_valid(const struct rtw89_fw_tx_shape_lmt_entry *e, 9938 const void *cursor, 9939 const struct rtw89_txpwr_conf *conf) 9940 { 9941 if (!__fw_txpwr_entry_acceptable(e, cursor, conf->ent_sz)) 9942 return false; 9943 9944 if (e->band >= RTW89_BAND_NUM) 9945 return false; 9946 if (e->tx_shape_rs >= RTW89_RS_TX_SHAPE_NUM) 9947 return false; 9948 if (e->regd >= RTW89_REGD_NUM) 9949 return false; 9950 9951 return true; 9952 } 9953 9954 static 9955 void rtw89_fw_load_tx_shape_lmt(struct rtw89_tx_shape_lmt_data *data) 9956 { 9957 const struct rtw89_txpwr_conf *conf = &data->conf; 9958 struct rtw89_fw_tx_shape_lmt_entry entry = {}; 9959 #if defined(__linux__) 9960 const void *cursor; 9961 #elif defined(__FreeBSD__) 9962 const u8 *cursor; 9963 #endif 9964 9965 rtw89_for_each_in_txpwr_conf(entry, cursor, conf) { 9966 if (!fw_tx_shape_lmt_entry_valid(&entry, cursor, conf)) 9967 continue; 9968 9969 data->v[entry.band][entry.tx_shape_rs][entry.regd] = entry.v; 9970 } 9971 } 9972 9973 static bool 9974 fw_tx_shape_lmt_ru_entry_valid(const struct rtw89_fw_tx_shape_lmt_ru_entry *e, 9975 const void *cursor, 9976 const struct rtw89_txpwr_conf *conf) 9977 { 9978 if (!__fw_txpwr_entry_acceptable(e, cursor, conf->ent_sz)) 9979 return false; 9980 9981 if (e->band >= RTW89_BAND_NUM) 9982 return false; 9983 if (e->regd >= RTW89_REGD_NUM) 9984 return false; 9985 9986 return true; 9987 } 9988 9989 static 9990 void rtw89_fw_load_tx_shape_lmt_ru(struct rtw89_tx_shape_lmt_ru_data *data) 9991 { 9992 const struct rtw89_txpwr_conf *conf = &data->conf; 9993 struct rtw89_fw_tx_shape_lmt_ru_entry entry = {}; 9994 #if defined(__linux__) 9995 const void *cursor; 9996 #elif defined(__FreeBSD__) 9997 const u8 *cursor; 9998 #endif 9999 10000 rtw89_for_each_in_txpwr_conf(entry, cursor, conf) { 10001 if (!fw_tx_shape_lmt_ru_entry_valid(&entry, cursor, conf)) 10002 continue; 10003 10004 data->v[entry.band][entry.regd] = entry.v; 10005 } 10006 } 10007 10008 static bool rtw89_fw_has_da_txpwr_table(struct rtw89_dev *rtwdev, 10009 const struct rtw89_rfe_parms *parms) 10010 { 10011 const struct rtw89_chip_info *chip = rtwdev->chip; 10012 10013 if (chip->support_bands & BIT(NL80211_BAND_2GHZ) && 10014 !(parms->rule_da_2ghz.lmt && parms->rule_da_2ghz.lmt_ru)) 10015 return false; 10016 10017 if (chip->support_bands & BIT(NL80211_BAND_5GHZ) && 10018 !(parms->rule_da_5ghz.lmt && parms->rule_da_5ghz.lmt_ru)) 10019 return false; 10020 10021 if (chip->support_bands & BIT(NL80211_BAND_6GHZ) && 10022 !(parms->rule_da_6ghz.lmt && parms->rule_da_6ghz.lmt_ru)) 10023 return false; 10024 10025 return true; 10026 } 10027 10028 const struct rtw89_rfe_parms * 10029 rtw89_load_rfe_data_from_fw(struct rtw89_dev *rtwdev, 10030 const struct rtw89_rfe_parms *init) 10031 { 10032 struct rtw89_rfe_data *rfe_data = rtwdev->rfe_data; 10033 struct rtw89_rfe_parms *parms; 10034 10035 if (!rfe_data) 10036 return init; 10037 10038 parms = &rfe_data->rfe_parms; 10039 if (init) 10040 *parms = *init; 10041 10042 if (rtw89_txpwr_conf_valid(&rfe_data->byrate.conf)) { 10043 rfe_data->byrate.tbl.data = &rfe_data->byrate.conf; 10044 rfe_data->byrate.tbl.size = 0; /* don't care here */ 10045 rfe_data->byrate.tbl.load = rtw89_fw_load_txpwr_byrate; 10046 parms->byr_tbl = &rfe_data->byrate.tbl; 10047 } 10048 10049 if (rtw89_txpwr_conf_valid(&rfe_data->lmt_2ghz.conf)) { 10050 rtw89_fw_load_txpwr_lmt_2ghz(&rfe_data->lmt_2ghz); 10051 parms->rule_2ghz.lmt = &rfe_data->lmt_2ghz.v; 10052 } 10053 10054 if (rtw89_txpwr_conf_valid(&rfe_data->lmt_5ghz.conf)) { 10055 rtw89_fw_load_txpwr_lmt_5ghz(&rfe_data->lmt_5ghz); 10056 parms->rule_5ghz.lmt = &rfe_data->lmt_5ghz.v; 10057 } 10058 10059 if (rtw89_txpwr_conf_valid(&rfe_data->lmt_6ghz.conf)) { 10060 rtw89_fw_load_txpwr_lmt_6ghz(&rfe_data->lmt_6ghz); 10061 parms->rule_6ghz.lmt = &rfe_data->lmt_6ghz.v; 10062 } 10063 10064 if (rtw89_txpwr_conf_valid(&rfe_data->da_lmt_2ghz.conf)) { 10065 rtw89_fw_load_txpwr_lmt_2ghz(&rfe_data->da_lmt_2ghz); 10066 parms->rule_da_2ghz.lmt = &rfe_data->da_lmt_2ghz.v; 10067 } 10068 10069 if (rtw89_txpwr_conf_valid(&rfe_data->da_lmt_5ghz.conf)) { 10070 rtw89_fw_load_txpwr_lmt_5ghz(&rfe_data->da_lmt_5ghz); 10071 parms->rule_da_5ghz.lmt = &rfe_data->da_lmt_5ghz.v; 10072 } 10073 10074 if (rtw89_txpwr_conf_valid(&rfe_data->da_lmt_6ghz.conf)) { 10075 rtw89_fw_load_txpwr_lmt_6ghz(&rfe_data->da_lmt_6ghz); 10076 parms->rule_da_6ghz.lmt = &rfe_data->da_lmt_6ghz.v; 10077 } 10078 10079 if (rtw89_txpwr_conf_valid(&rfe_data->lmt_ru_2ghz.conf)) { 10080 rtw89_fw_load_txpwr_lmt_ru_2ghz(&rfe_data->lmt_ru_2ghz); 10081 parms->rule_2ghz.lmt_ru = &rfe_data->lmt_ru_2ghz.v; 10082 } 10083 10084 if (rtw89_txpwr_conf_valid(&rfe_data->lmt_ru_5ghz.conf)) { 10085 rtw89_fw_load_txpwr_lmt_ru_5ghz(&rfe_data->lmt_ru_5ghz); 10086 parms->rule_5ghz.lmt_ru = &rfe_data->lmt_ru_5ghz.v; 10087 } 10088 10089 if (rtw89_txpwr_conf_valid(&rfe_data->lmt_ru_6ghz.conf)) { 10090 rtw89_fw_load_txpwr_lmt_ru_6ghz(&rfe_data->lmt_ru_6ghz); 10091 parms->rule_6ghz.lmt_ru = &rfe_data->lmt_ru_6ghz.v; 10092 } 10093 10094 if (rtw89_txpwr_conf_valid(&rfe_data->da_lmt_ru_2ghz.conf)) { 10095 rtw89_fw_load_txpwr_lmt_ru_2ghz(&rfe_data->da_lmt_ru_2ghz); 10096 parms->rule_da_2ghz.lmt_ru = &rfe_data->da_lmt_ru_2ghz.v; 10097 } 10098 10099 if (rtw89_txpwr_conf_valid(&rfe_data->da_lmt_ru_5ghz.conf)) { 10100 rtw89_fw_load_txpwr_lmt_ru_5ghz(&rfe_data->da_lmt_ru_5ghz); 10101 parms->rule_da_5ghz.lmt_ru = &rfe_data->da_lmt_ru_5ghz.v; 10102 } 10103 10104 if (rtw89_txpwr_conf_valid(&rfe_data->da_lmt_ru_6ghz.conf)) { 10105 rtw89_fw_load_txpwr_lmt_ru_6ghz(&rfe_data->da_lmt_ru_6ghz); 10106 parms->rule_da_6ghz.lmt_ru = &rfe_data->da_lmt_ru_6ghz.v; 10107 } 10108 10109 if (rtw89_txpwr_conf_valid(&rfe_data->tx_shape_lmt.conf)) { 10110 rtw89_fw_load_tx_shape_lmt(&rfe_data->tx_shape_lmt); 10111 parms->tx_shape.lmt = &rfe_data->tx_shape_lmt.v; 10112 } 10113 10114 if (rtw89_txpwr_conf_valid(&rfe_data->tx_shape_lmt_ru.conf)) { 10115 rtw89_fw_load_tx_shape_lmt_ru(&rfe_data->tx_shape_lmt_ru); 10116 parms->tx_shape.lmt_ru = &rfe_data->tx_shape_lmt_ru.v; 10117 } 10118 10119 parms->has_da = rtw89_fw_has_da_txpwr_table(rtwdev, parms); 10120 10121 return parms; 10122 } 10123