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