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