1 // SPDX-License-Identifier: GPL-2.0 OR BSD-3-Clause 2 /* Copyright(c) 2019-2020 Realtek Corporation 3 */ 4 5 #include "cam.h" 6 #include "chan.h" 7 #include "coex.h" 8 #include "debug.h" 9 #include "fw.h" 10 #include "mac.h" 11 #include "phy.h" 12 #include "reg.h" 13 #include "util.h" 14 15 static void rtw89_fw_c2h_cmd_handle(struct rtw89_dev *rtwdev, 16 struct sk_buff *skb); 17 static int rtw89_h2c_tx_and_wait(struct rtw89_dev *rtwdev, struct sk_buff *skb, 18 struct rtw89_wait_info *wait, unsigned int cond); 19 20 static struct sk_buff *rtw89_fw_h2c_alloc_skb(struct rtw89_dev *rtwdev, u32 len, 21 bool header) 22 { 23 struct sk_buff *skb; 24 u32 header_len = 0; 25 u32 h2c_desc_size = rtwdev->chip->h2c_desc_size; 26 27 if (header) 28 header_len = H2C_HEADER_LEN; 29 30 skb = dev_alloc_skb(len + header_len + h2c_desc_size); 31 if (!skb) 32 return NULL; 33 skb_reserve(skb, header_len + h2c_desc_size); 34 memset(skb->data, 0, len); 35 36 return skb; 37 } 38 39 struct sk_buff *rtw89_fw_h2c_alloc_skb_with_hdr(struct rtw89_dev *rtwdev, u32 len) 40 { 41 return rtw89_fw_h2c_alloc_skb(rtwdev, len, true); 42 } 43 44 struct sk_buff *rtw89_fw_h2c_alloc_skb_no_hdr(struct rtw89_dev *rtwdev, u32 len) 45 { 46 return rtw89_fw_h2c_alloc_skb(rtwdev, len, false); 47 } 48 49 static u8 _fw_get_rdy(struct rtw89_dev *rtwdev) 50 { 51 u8 val = rtw89_read8(rtwdev, R_AX_WCPU_FW_CTRL); 52 53 return FIELD_GET(B_AX_WCPU_FWDL_STS_MASK, val); 54 } 55 56 #define FWDL_WAIT_CNT 400000 57 int rtw89_fw_check_rdy(struct rtw89_dev *rtwdev) 58 { 59 u8 val; 60 int ret; 61 62 ret = read_poll_timeout_atomic(_fw_get_rdy, val, 63 val == RTW89_FWDL_WCPU_FW_INIT_RDY, 64 1, FWDL_WAIT_CNT, false, rtwdev); 65 if (ret) { 66 switch (val) { 67 case RTW89_FWDL_CHECKSUM_FAIL: 68 rtw89_err(rtwdev, "fw checksum fail\n"); 69 return -EINVAL; 70 71 case RTW89_FWDL_SECURITY_FAIL: 72 rtw89_err(rtwdev, "fw security fail\n"); 73 return -EINVAL; 74 75 case RTW89_FWDL_CV_NOT_MATCH: 76 rtw89_err(rtwdev, "fw cv not match\n"); 77 return -EINVAL; 78 79 default: 80 return -EBUSY; 81 } 82 } 83 84 set_bit(RTW89_FLAG_FW_RDY, rtwdev->flags); 85 86 return 0; 87 } 88 89 static int rtw89_fw_hdr_parser_v0(struct rtw89_dev *rtwdev, const u8 *fw, u32 len, 90 struct rtw89_fw_bin_info *info) 91 { 92 const struct rtw89_fw_hdr *fw_hdr = (const struct rtw89_fw_hdr *)fw; 93 struct rtw89_fw_hdr_section_info *section_info; 94 const struct rtw89_fw_dynhdr_hdr *fwdynhdr; 95 const struct rtw89_fw_hdr_section *section; 96 const u8 *fw_end = fw + len; 97 const u8 *bin; 98 u32 base_hdr_len; 99 u32 mssc_len = 0; 100 u32 i; 101 102 if (!info) 103 return -EINVAL; 104 105 info->section_num = le32_get_bits(fw_hdr->w6, FW_HDR_W6_SEC_NUM); 106 base_hdr_len = struct_size(fw_hdr, sections, info->section_num); 107 info->dynamic_hdr_en = le32_get_bits(fw_hdr->w7, FW_HDR_W7_DYN_HDR); 108 109 if (info->dynamic_hdr_en) { 110 info->hdr_len = le32_get_bits(fw_hdr->w3, FW_HDR_W3_LEN); 111 info->dynamic_hdr_len = info->hdr_len - base_hdr_len; 112 fwdynhdr = (const struct rtw89_fw_dynhdr_hdr *)(fw + base_hdr_len); 113 if (le32_to_cpu(fwdynhdr->hdr_len) != info->dynamic_hdr_len) { 114 rtw89_err(rtwdev, "[ERR]invalid fw dynamic header len\n"); 115 return -EINVAL; 116 } 117 } else { 118 info->hdr_len = base_hdr_len; 119 info->dynamic_hdr_len = 0; 120 } 121 122 bin = fw + info->hdr_len; 123 124 /* jump to section header */ 125 section_info = info->section_info; 126 for (i = 0; i < info->section_num; i++) { 127 section = &fw_hdr->sections[i]; 128 section_info->type = 129 le32_get_bits(section->w1, FWSECTION_HDR_W1_SECTIONTYPE); 130 if (section_info->type == FWDL_SECURITY_SECTION_TYPE) { 131 section_info->mssc = 132 le32_get_bits(section->w2, FWSECTION_HDR_W2_MSSC); 133 mssc_len += section_info->mssc * FWDL_SECURITY_SIGLEN; 134 } else { 135 section_info->mssc = 0; 136 } 137 138 section_info->len = le32_get_bits(section->w1, FWSECTION_HDR_W1_SEC_SIZE); 139 if (le32_get_bits(section->w1, FWSECTION_HDR_W1_CHECKSUM)) 140 section_info->len += FWDL_SECTION_CHKSUM_LEN; 141 section_info->redl = le32_get_bits(section->w1, FWSECTION_HDR_W1_REDL); 142 section_info->dladdr = 143 le32_get_bits(section->w0, FWSECTION_HDR_W0_DL_ADDR) & 0x1fffffff; 144 section_info->addr = bin; 145 bin += section_info->len; 146 section_info++; 147 } 148 149 if (fw_end != bin + mssc_len) { 150 rtw89_err(rtwdev, "[ERR]fw bin size\n"); 151 return -EINVAL; 152 } 153 154 return 0; 155 } 156 157 static int rtw89_fw_hdr_parser_v1(struct rtw89_dev *rtwdev, const u8 *fw, u32 len, 158 struct rtw89_fw_bin_info *info) 159 { 160 const struct rtw89_fw_hdr_v1 *fw_hdr = (const struct rtw89_fw_hdr_v1 *)fw; 161 struct rtw89_fw_hdr_section_info *section_info; 162 const struct rtw89_fw_dynhdr_hdr *fwdynhdr; 163 const struct rtw89_fw_hdr_section_v1 *section; 164 const u8 *fw_end = fw + len; 165 const u8 *bin; 166 u32 base_hdr_len; 167 u32 mssc_len = 0; 168 u32 i; 169 170 info->section_num = le32_get_bits(fw_hdr->w6, FW_HDR_V1_W6_SEC_NUM); 171 base_hdr_len = struct_size(fw_hdr, sections, info->section_num); 172 info->dynamic_hdr_en = le32_get_bits(fw_hdr->w7, FW_HDR_V1_W7_DYN_HDR); 173 174 if (info->dynamic_hdr_en) { 175 info->hdr_len = le32_get_bits(fw_hdr->w5, FW_HDR_V1_W5_HDR_SIZE); 176 info->dynamic_hdr_len = info->hdr_len - base_hdr_len; 177 fwdynhdr = (const struct rtw89_fw_dynhdr_hdr *)(fw + base_hdr_len); 178 if (le32_to_cpu(fwdynhdr->hdr_len) != info->dynamic_hdr_len) { 179 rtw89_err(rtwdev, "[ERR]invalid fw dynamic header len\n"); 180 return -EINVAL; 181 } 182 } else { 183 info->hdr_len = base_hdr_len; 184 info->dynamic_hdr_len = 0; 185 } 186 187 bin = fw + info->hdr_len; 188 189 /* jump to section header */ 190 section_info = info->section_info; 191 for (i = 0; i < info->section_num; i++) { 192 section = &fw_hdr->sections[i]; 193 section_info->type = 194 le32_get_bits(section->w1, FWSECTION_HDR_V1_W1_SECTIONTYPE); 195 if (section_info->type == FWDL_SECURITY_SECTION_TYPE) { 196 section_info->mssc = 197 le32_get_bits(section->w2, FWSECTION_HDR_V1_W2_MSSC); 198 mssc_len += section_info->mssc * FWDL_SECURITY_SIGLEN; 199 } else { 200 section_info->mssc = 0; 201 } 202 203 section_info->len = 204 le32_get_bits(section->w1, FWSECTION_HDR_V1_W1_SEC_SIZE); 205 if (le32_get_bits(section->w1, FWSECTION_HDR_V1_W1_CHECKSUM)) 206 section_info->len += FWDL_SECTION_CHKSUM_LEN; 207 section_info->redl = le32_get_bits(section->w1, FWSECTION_HDR_V1_W1_REDL); 208 section_info->dladdr = 209 le32_get_bits(section->w0, FWSECTION_HDR_V1_W0_DL_ADDR); 210 section_info->addr = bin; 211 bin += section_info->len; 212 section_info++; 213 } 214 215 if (fw_end != bin + mssc_len) { 216 rtw89_err(rtwdev, "[ERR]fw bin size\n"); 217 return -EINVAL; 218 } 219 220 return 0; 221 } 222 223 static int rtw89_fw_hdr_parser(struct rtw89_dev *rtwdev, 224 const struct rtw89_fw_suit *fw_suit, 225 struct rtw89_fw_bin_info *info) 226 { 227 const u8 *fw = fw_suit->data; 228 u32 len = fw_suit->size; 229 230 if (!fw || !len) { 231 rtw89_err(rtwdev, "fw type %d isn't recognized\n", fw_suit->type); 232 return -ENOENT; 233 } 234 235 switch (fw_suit->hdr_ver) { 236 case 0: 237 return rtw89_fw_hdr_parser_v0(rtwdev, fw, len, info); 238 case 1: 239 return rtw89_fw_hdr_parser_v1(rtwdev, fw, len, info); 240 default: 241 return -ENOENT; 242 } 243 } 244 245 static 246 int rtw89_mfw_recognize(struct rtw89_dev *rtwdev, enum rtw89_fw_type type, 247 struct rtw89_fw_suit *fw_suit, bool nowarn) 248 { 249 struct rtw89_fw_info *fw_info = &rtwdev->fw; 250 const struct firmware *firmware = fw_info->req.firmware; 251 const u8 *mfw = firmware->data; 252 u32 mfw_len = firmware->size; 253 const struct rtw89_mfw_hdr *mfw_hdr = (const struct rtw89_mfw_hdr *)mfw; 254 const struct rtw89_mfw_info *mfw_info; 255 int i; 256 257 if (mfw_hdr->sig != RTW89_MFW_SIG) { 258 rtw89_debug(rtwdev, RTW89_DBG_FW, "use legacy firmware\n"); 259 /* legacy firmware support normal type only */ 260 if (type != RTW89_FW_NORMAL) 261 return -EINVAL; 262 fw_suit->data = mfw; 263 fw_suit->size = mfw_len; 264 return 0; 265 } 266 267 for (i = 0; i < mfw_hdr->fw_nr; i++) { 268 mfw_info = &mfw_hdr->info[i]; 269 if (mfw_info->type == type) { 270 if (mfw_info->cv == rtwdev->hal.cv && !mfw_info->mp) 271 goto found; 272 if (type == RTW89_FW_LOGFMT) 273 goto found; 274 } 275 } 276 277 if (!nowarn) 278 rtw89_err(rtwdev, "no suitable firmware found\n"); 279 return -ENOENT; 280 281 found: 282 fw_suit->data = mfw + le32_to_cpu(mfw_info->shift); 283 fw_suit->size = le32_to_cpu(mfw_info->size); 284 return 0; 285 } 286 287 static u32 rtw89_mfw_get_size(struct rtw89_dev *rtwdev) 288 { 289 struct rtw89_fw_info *fw_info = &rtwdev->fw; 290 const struct firmware *firmware = fw_info->req.firmware; 291 const struct rtw89_mfw_hdr *mfw_hdr = 292 (const struct rtw89_mfw_hdr *)firmware->data; 293 const struct rtw89_mfw_info *mfw_info; 294 u32 size; 295 296 if (mfw_hdr->sig != RTW89_MFW_SIG) { 297 rtw89_warn(rtwdev, "not mfw format\n"); 298 return 0; 299 } 300 301 mfw_info = &mfw_hdr->info[mfw_hdr->fw_nr - 1]; 302 size = le32_to_cpu(mfw_info->shift) + le32_to_cpu(mfw_info->size); 303 304 return size; 305 } 306 307 static void rtw89_fw_update_ver_v0(struct rtw89_dev *rtwdev, 308 struct rtw89_fw_suit *fw_suit, 309 const struct rtw89_fw_hdr *hdr) 310 { 311 fw_suit->major_ver = le32_get_bits(hdr->w1, FW_HDR_W1_MAJOR_VERSION); 312 fw_suit->minor_ver = le32_get_bits(hdr->w1, FW_HDR_W1_MINOR_VERSION); 313 fw_suit->sub_ver = le32_get_bits(hdr->w1, FW_HDR_W1_SUBVERSION); 314 fw_suit->sub_idex = le32_get_bits(hdr->w1, FW_HDR_W1_SUBINDEX); 315 fw_suit->commitid = le32_get_bits(hdr->w2, FW_HDR_W2_COMMITID); 316 fw_suit->build_year = le32_get_bits(hdr->w5, FW_HDR_W5_YEAR); 317 fw_suit->build_mon = le32_get_bits(hdr->w4, FW_HDR_W4_MONTH); 318 fw_suit->build_date = le32_get_bits(hdr->w4, FW_HDR_W4_DATE); 319 fw_suit->build_hour = le32_get_bits(hdr->w4, FW_HDR_W4_HOUR); 320 fw_suit->build_min = le32_get_bits(hdr->w4, FW_HDR_W4_MIN); 321 fw_suit->cmd_ver = le32_get_bits(hdr->w7, FW_HDR_W7_CMD_VERSERION); 322 } 323 324 static void rtw89_fw_update_ver_v1(struct rtw89_dev *rtwdev, 325 struct rtw89_fw_suit *fw_suit, 326 const struct rtw89_fw_hdr_v1 *hdr) 327 { 328 fw_suit->major_ver = le32_get_bits(hdr->w1, FW_HDR_V1_W1_MAJOR_VERSION); 329 fw_suit->minor_ver = le32_get_bits(hdr->w1, FW_HDR_V1_W1_MINOR_VERSION); 330 fw_suit->sub_ver = le32_get_bits(hdr->w1, FW_HDR_V1_W1_SUBVERSION); 331 fw_suit->sub_idex = le32_get_bits(hdr->w1, FW_HDR_V1_W1_SUBINDEX); 332 fw_suit->commitid = le32_get_bits(hdr->w2, FW_HDR_V1_W2_COMMITID); 333 fw_suit->build_year = le32_get_bits(hdr->w5, FW_HDR_V1_W5_YEAR); 334 fw_suit->build_mon = le32_get_bits(hdr->w4, FW_HDR_V1_W4_MONTH); 335 fw_suit->build_date = le32_get_bits(hdr->w4, FW_HDR_V1_W4_DATE); 336 fw_suit->build_hour = le32_get_bits(hdr->w4, FW_HDR_V1_W4_HOUR); 337 fw_suit->build_min = le32_get_bits(hdr->w4, FW_HDR_V1_W4_MIN); 338 fw_suit->cmd_ver = le32_get_bits(hdr->w7, FW_HDR_V1_W3_CMD_VERSERION); 339 } 340 341 static int rtw89_fw_update_ver(struct rtw89_dev *rtwdev, 342 enum rtw89_fw_type type, 343 struct rtw89_fw_suit *fw_suit) 344 { 345 const struct rtw89_fw_hdr *v0 = (const struct rtw89_fw_hdr *)fw_suit->data; 346 const struct rtw89_fw_hdr_v1 *v1 = (const struct rtw89_fw_hdr_v1 *)fw_suit->data; 347 348 if (type == RTW89_FW_LOGFMT) 349 return 0; 350 351 fw_suit->type = type; 352 fw_suit->hdr_ver = le32_get_bits(v0->w3, FW_HDR_W3_HDR_VER); 353 354 switch (fw_suit->hdr_ver) { 355 case 0: 356 rtw89_fw_update_ver_v0(rtwdev, fw_suit, v0); 357 break; 358 case 1: 359 rtw89_fw_update_ver_v1(rtwdev, fw_suit, v1); 360 break; 361 default: 362 rtw89_err(rtwdev, "Unknown firmware header version %u\n", 363 fw_suit->hdr_ver); 364 return -ENOENT; 365 } 366 367 rtw89_info(rtwdev, 368 "Firmware version %u.%u.%u.%u (%08x), cmd version %u, type %u\n", 369 fw_suit->major_ver, fw_suit->minor_ver, fw_suit->sub_ver, 370 fw_suit->sub_idex, fw_suit->commitid, fw_suit->cmd_ver, type); 371 372 return 0; 373 } 374 375 static 376 int __rtw89_fw_recognize(struct rtw89_dev *rtwdev, enum rtw89_fw_type type, 377 bool nowarn) 378 { 379 struct rtw89_fw_suit *fw_suit = rtw89_fw_suit_get(rtwdev, type); 380 int ret; 381 382 ret = rtw89_mfw_recognize(rtwdev, type, fw_suit, nowarn); 383 if (ret) 384 return ret; 385 386 return rtw89_fw_update_ver(rtwdev, type, fw_suit); 387 } 388 389 static 390 int __rtw89_fw_recognize_from_elm(struct rtw89_dev *rtwdev, 391 const struct rtw89_fw_element_hdr *elm, 392 #if defined(__linux__) 393 const void *data) 394 #elif defined(__FreeBSD__) 395 const int data) 396 #endif 397 { 398 #if defined(__linux__) 399 enum rtw89_fw_type type = (enum rtw89_fw_type)data; 400 #elif defined(__FreeBSD__) 401 const enum rtw89_fw_type type = (const enum rtw89_fw_type)data; 402 #endif 403 struct rtw89_fw_suit *fw_suit; 404 405 fw_suit = rtw89_fw_suit_get(rtwdev, type); 406 fw_suit->data = elm->u.common.contents; 407 fw_suit->size = le32_to_cpu(elm->size); 408 409 return rtw89_fw_update_ver(rtwdev, type, fw_suit); 410 } 411 412 #define __DEF_FW_FEAT_COND(__cond, __op) \ 413 static bool __fw_feat_cond_ ## __cond(u32 suit_ver_code, u32 comp_ver_code) \ 414 { \ 415 return suit_ver_code __op comp_ver_code; \ 416 } 417 418 __DEF_FW_FEAT_COND(ge, >=); /* greater or equal */ 419 __DEF_FW_FEAT_COND(le, <=); /* less or equal */ 420 __DEF_FW_FEAT_COND(lt, <); /* less than */ 421 422 struct __fw_feat_cfg { 423 enum rtw89_core_chip_id chip_id; 424 enum rtw89_fw_feature feature; 425 u32 ver_code; 426 bool (*cond)(u32 suit_ver_code, u32 comp_ver_code); 427 }; 428 429 #define __CFG_FW_FEAT(_chip, _cond, _maj, _min, _sub, _idx, _feat) \ 430 { \ 431 .chip_id = _chip, \ 432 .feature = RTW89_FW_FEATURE_ ## _feat, \ 433 .ver_code = RTW89_FW_VER_CODE(_maj, _min, _sub, _idx), \ 434 .cond = __fw_feat_cond_ ## _cond, \ 435 } 436 437 static const struct __fw_feat_cfg fw_feat_tbl[] = { 438 __CFG_FW_FEAT(RTL8851B, ge, 0, 29, 37, 1, TX_WAKE), 439 __CFG_FW_FEAT(RTL8851B, ge, 0, 29, 37, 1, SCAN_OFFLOAD), 440 __CFG_FW_FEAT(RTL8851B, ge, 0, 29, 41, 0, CRASH_TRIGGER), 441 __CFG_FW_FEAT(RTL8852A, le, 0, 13, 29, 0, OLD_HT_RA_FORMAT), 442 __CFG_FW_FEAT(RTL8852A, ge, 0, 13, 35, 0, SCAN_OFFLOAD), 443 __CFG_FW_FEAT(RTL8852A, ge, 0, 13, 35, 0, TX_WAKE), 444 __CFG_FW_FEAT(RTL8852A, ge, 0, 13, 36, 0, CRASH_TRIGGER), 445 __CFG_FW_FEAT(RTL8852A, lt, 0, 13, 38, 0, NO_PACKET_DROP), 446 __CFG_FW_FEAT(RTL8852B, ge, 0, 29, 26, 0, NO_LPS_PG), 447 __CFG_FW_FEAT(RTL8852B, ge, 0, 29, 26, 0, TX_WAKE), 448 __CFG_FW_FEAT(RTL8852B, ge, 0, 29, 29, 0, CRASH_TRIGGER), 449 __CFG_FW_FEAT(RTL8852B, ge, 0, 29, 29, 0, SCAN_OFFLOAD), 450 __CFG_FW_FEAT(RTL8852C, le, 0, 27, 33, 0, NO_DEEP_PS), 451 __CFG_FW_FEAT(RTL8852C, ge, 0, 27, 34, 0, TX_WAKE), 452 __CFG_FW_FEAT(RTL8852C, ge, 0, 27, 36, 0, SCAN_OFFLOAD), 453 __CFG_FW_FEAT(RTL8852C, ge, 0, 27, 40, 0, CRASH_TRIGGER), 454 __CFG_FW_FEAT(RTL8852C, ge, 0, 27, 56, 10, BEACON_FILTER), 455 }; 456 457 static void rtw89_fw_iterate_feature_cfg(struct rtw89_fw_info *fw, 458 const struct rtw89_chip_info *chip, 459 u32 ver_code) 460 { 461 int i; 462 463 for (i = 0; i < ARRAY_SIZE(fw_feat_tbl); i++) { 464 const struct __fw_feat_cfg *ent = &fw_feat_tbl[i]; 465 466 if (chip->chip_id != ent->chip_id) 467 continue; 468 469 if (ent->cond(ver_code, ent->ver_code)) 470 RTW89_SET_FW_FEATURE(ent->feature, fw); 471 } 472 } 473 474 static void rtw89_fw_recognize_features(struct rtw89_dev *rtwdev) 475 { 476 const struct rtw89_chip_info *chip = rtwdev->chip; 477 const struct rtw89_fw_suit *fw_suit; 478 u32 suit_ver_code; 479 480 fw_suit = rtw89_fw_suit_get(rtwdev, RTW89_FW_NORMAL); 481 suit_ver_code = RTW89_FW_SUIT_VER_CODE(fw_suit); 482 483 rtw89_fw_iterate_feature_cfg(&rtwdev->fw, chip, suit_ver_code); 484 } 485 486 const struct firmware * 487 rtw89_early_fw_feature_recognize(struct device *device, 488 const struct rtw89_chip_info *chip, 489 struct rtw89_fw_info *early_fw, 490 int *used_fw_format) 491 { 492 const struct firmware *firmware; 493 char fw_name[64]; 494 int fw_format; 495 u32 ver_code; 496 int ret; 497 498 for (fw_format = chip->fw_format_max; fw_format >= 0; fw_format--) { 499 rtw89_fw_get_filename(fw_name, sizeof(fw_name), 500 chip->fw_basename, fw_format); 501 502 ret = request_firmware(&firmware, fw_name, device); 503 if (!ret) { 504 dev_info(device, "loaded firmware %s\n", fw_name); 505 *used_fw_format = fw_format; 506 break; 507 } 508 } 509 510 if (ret) { 511 dev_err(device, "failed to early request firmware: %d\n", ret); 512 return NULL; 513 } 514 515 ver_code = rtw89_compat_fw_hdr_ver_code(firmware->data); 516 517 if (!ver_code) 518 goto out; 519 520 rtw89_fw_iterate_feature_cfg(early_fw, chip, ver_code); 521 522 out: 523 return firmware; 524 } 525 526 int rtw89_fw_recognize(struct rtw89_dev *rtwdev) 527 { 528 const struct rtw89_chip_info *chip = rtwdev->chip; 529 int ret; 530 531 if (chip->try_ce_fw) { 532 ret = __rtw89_fw_recognize(rtwdev, RTW89_FW_NORMAL_CE, true); 533 if (!ret) 534 goto normal_done; 535 } 536 537 ret = __rtw89_fw_recognize(rtwdev, RTW89_FW_NORMAL, false); 538 if (ret) 539 return ret; 540 541 normal_done: 542 /* It still works if wowlan firmware isn't existing. */ 543 __rtw89_fw_recognize(rtwdev, RTW89_FW_WOWLAN, false); 544 545 /* It still works if log format file isn't existing. */ 546 __rtw89_fw_recognize(rtwdev, RTW89_FW_LOGFMT, true); 547 548 rtw89_fw_recognize_features(rtwdev); 549 550 rtw89_coex_recognize_ver(rtwdev); 551 552 return 0; 553 } 554 555 static 556 int rtw89_build_phy_tbl_from_elm(struct rtw89_dev *rtwdev, 557 const struct rtw89_fw_element_hdr *elm, 558 #if defined(__linux__) 559 const void *data) 560 #elif defined(__FreeBSD__) 561 const int data) 562 #endif 563 { 564 struct rtw89_fw_elm_info *elm_info = &rtwdev->fw.elm_info; 565 struct rtw89_phy_table *tbl; 566 struct rtw89_reg2_def *regs; 567 enum rtw89_rf_path rf_path; 568 u32 n_regs, i; 569 u8 idx; 570 571 tbl = kzalloc(sizeof(*tbl), GFP_KERNEL); 572 if (!tbl) 573 return -ENOMEM; 574 575 switch (le32_to_cpu(elm->id)) { 576 case RTW89_FW_ELEMENT_ID_BB_REG: 577 elm_info->bb_tbl = tbl; 578 break; 579 case RTW89_FW_ELEMENT_ID_BB_GAIN: 580 elm_info->bb_gain = tbl; 581 break; 582 case RTW89_FW_ELEMENT_ID_RADIO_A: 583 case RTW89_FW_ELEMENT_ID_RADIO_B: 584 case RTW89_FW_ELEMENT_ID_RADIO_C: 585 case RTW89_FW_ELEMENT_ID_RADIO_D: 586 rf_path = (enum rtw89_rf_path)data; 587 idx = elm->u.reg2.idx; 588 589 elm_info->rf_radio[idx] = tbl; 590 tbl->rf_path = rf_path; 591 tbl->config = rtw89_phy_config_rf_reg_v1; 592 break; 593 case RTW89_FW_ELEMENT_ID_RF_NCTL: 594 elm_info->rf_nctl = tbl; 595 break; 596 default: 597 kfree(tbl); 598 return -ENOENT; 599 } 600 601 n_regs = le32_to_cpu(elm->size) / sizeof(tbl->regs[0]); 602 regs = kcalloc(n_regs, sizeof(tbl->regs[0]), GFP_KERNEL); 603 if (!regs) 604 goto out; 605 606 for (i = 0; i < n_regs; i++) { 607 regs[i].addr = le32_to_cpu(elm->u.reg2.regs[i].addr); 608 regs[i].data = le32_to_cpu(elm->u.reg2.regs[i].data); 609 } 610 611 tbl->n_regs = n_regs; 612 tbl->regs = regs; 613 614 return 0; 615 616 out: 617 kfree(tbl); 618 return -ENOMEM; 619 } 620 621 struct rtw89_fw_element_handler { 622 int (*fn)(struct rtw89_dev *rtwdev, 623 #if defined(__linux__) 624 const struct rtw89_fw_element_hdr *elm, const void *data); 625 const void *data; 626 #elif defined(__FreeBSD__) 627 const struct rtw89_fw_element_hdr *elm, const int data); 628 const int data; 629 #endif 630 const char *name; 631 }; 632 633 static const struct rtw89_fw_element_handler __fw_element_handlers[] = { 634 #if defined(__linux__) 635 [RTW89_FW_ELEMENT_ID_BBMCU0] = {__rtw89_fw_recognize_from_elm, 636 (const void *)RTW89_FW_BBMCU0, NULL}, 637 [RTW89_FW_ELEMENT_ID_BBMCU1] = {__rtw89_fw_recognize_from_elm, 638 (const void *)RTW89_FW_BBMCU1, NULL}, 639 [RTW89_FW_ELEMENT_ID_BB_REG] = {rtw89_build_phy_tbl_from_elm, NULL, "BB"}, 640 [RTW89_FW_ELEMENT_ID_BB_GAIN] = {rtw89_build_phy_tbl_from_elm, NULL, NULL}, 641 [RTW89_FW_ELEMENT_ID_RADIO_A] = {rtw89_build_phy_tbl_from_elm, 642 (const void *)RF_PATH_A, "radio A"}, 643 [RTW89_FW_ELEMENT_ID_RADIO_B] = {rtw89_build_phy_tbl_from_elm, 644 (const void *)RF_PATH_B, NULL}, 645 [RTW89_FW_ELEMENT_ID_RADIO_C] = {rtw89_build_phy_tbl_from_elm, 646 (const void *)RF_PATH_C, NULL}, 647 [RTW89_FW_ELEMENT_ID_RADIO_D] = {rtw89_build_phy_tbl_from_elm, 648 (const void *)RF_PATH_D, NULL}, 649 [RTW89_FW_ELEMENT_ID_RF_NCTL] = {rtw89_build_phy_tbl_from_elm, NULL, "NCTL"}, 650 #elif defined(__FreeBSD__) 651 [RTW89_FW_ELEMENT_ID_BBMCU0] = {__rtw89_fw_recognize_from_elm, 652 RTW89_FW_BBMCU0, NULL}, 653 [RTW89_FW_ELEMENT_ID_BBMCU1] = {__rtw89_fw_recognize_from_elm, 654 RTW89_FW_BBMCU1, NULL}, 655 [RTW89_FW_ELEMENT_ID_BB_REG] = {rtw89_build_phy_tbl_from_elm, -1, "BB"}, 656 [RTW89_FW_ELEMENT_ID_BB_GAIN] = {rtw89_build_phy_tbl_from_elm, -1, NULL}, 657 [RTW89_FW_ELEMENT_ID_RADIO_A] = {rtw89_build_phy_tbl_from_elm, 658 RF_PATH_A, "radio A"}, 659 [RTW89_FW_ELEMENT_ID_RADIO_B] = {rtw89_build_phy_tbl_from_elm, 660 RF_PATH_B, NULL}, 661 [RTW89_FW_ELEMENT_ID_RADIO_C] = {rtw89_build_phy_tbl_from_elm, 662 RF_PATH_C, NULL}, 663 [RTW89_FW_ELEMENT_ID_RADIO_D] = {rtw89_build_phy_tbl_from_elm, 664 RF_PATH_D, NULL}, 665 [RTW89_FW_ELEMENT_ID_RF_NCTL] = {rtw89_build_phy_tbl_from_elm, -1, "NCTL"}, 666 #endif 667 }; 668 669 int rtw89_fw_recognize_elements(struct rtw89_dev *rtwdev) 670 { 671 struct rtw89_fw_info *fw_info = &rtwdev->fw; 672 const struct firmware *firmware = fw_info->req.firmware; 673 const struct rtw89_chip_info *chip = rtwdev->chip; 674 u32 unrecognized_elements = chip->needed_fw_elms; 675 const struct rtw89_fw_element_handler *handler; 676 const struct rtw89_fw_element_hdr *hdr; 677 u32 elm_size; 678 u32 elem_id; 679 u32 offset; 680 int ret; 681 682 BUILD_BUG_ON(sizeof(chip->needed_fw_elms) * 8 < RTW89_FW_ELEMENT_ID_NUM); 683 684 offset = rtw89_mfw_get_size(rtwdev); 685 offset = ALIGN(offset, RTW89_FW_ELEMENT_ALIGN); 686 if (offset == 0) 687 return -EINVAL; 688 689 while (offset + sizeof(*hdr) < firmware->size) { 690 hdr = (const struct rtw89_fw_element_hdr *)(firmware->data + offset); 691 692 elm_size = le32_to_cpu(hdr->size); 693 if (offset + elm_size >= firmware->size) { 694 rtw89_warn(rtwdev, "firmware element size exceeds\n"); 695 break; 696 } 697 698 elem_id = le32_to_cpu(hdr->id); 699 if (elem_id >= ARRAY_SIZE(__fw_element_handlers)) 700 goto next; 701 702 handler = &__fw_element_handlers[elem_id]; 703 if (!handler->fn) 704 goto next; 705 706 ret = handler->fn(rtwdev, hdr, handler->data); 707 if (ret) 708 return ret; 709 710 if (handler->name) 711 rtw89_info(rtwdev, "Firmware element %s version: %4ph\n", 712 handler->name, hdr->ver); 713 714 unrecognized_elements &= ~BIT(elem_id); 715 next: 716 offset += sizeof(*hdr) + elm_size; 717 offset = ALIGN(offset, RTW89_FW_ELEMENT_ALIGN); 718 } 719 720 if (unrecognized_elements) { 721 rtw89_err(rtwdev, "Firmware elements 0x%08x are unrecognized\n", 722 unrecognized_elements); 723 return -ENOENT; 724 } 725 726 return 0; 727 } 728 729 void rtw89_h2c_pkt_set_hdr(struct rtw89_dev *rtwdev, struct sk_buff *skb, 730 u8 type, u8 cat, u8 class, u8 func, 731 bool rack, bool dack, u32 len) 732 { 733 struct fwcmd_hdr *hdr; 734 735 hdr = (struct fwcmd_hdr *)skb_push(skb, 8); 736 737 if (!(rtwdev->fw.h2c_seq % 4)) 738 rack = true; 739 hdr->hdr0 = cpu_to_le32(FIELD_PREP(H2C_HDR_DEL_TYPE, type) | 740 FIELD_PREP(H2C_HDR_CAT, cat) | 741 FIELD_PREP(H2C_HDR_CLASS, class) | 742 FIELD_PREP(H2C_HDR_FUNC, func) | 743 FIELD_PREP(H2C_HDR_H2C_SEQ, rtwdev->fw.h2c_seq)); 744 745 hdr->hdr1 = cpu_to_le32(FIELD_PREP(H2C_HDR_TOTAL_LEN, 746 len + H2C_HEADER_LEN) | 747 (rack ? H2C_HDR_REC_ACK : 0) | 748 (dack ? H2C_HDR_DONE_ACK : 0)); 749 750 rtwdev->fw.h2c_seq++; 751 } 752 753 static void rtw89_h2c_pkt_set_hdr_fwdl(struct rtw89_dev *rtwdev, 754 struct sk_buff *skb, 755 u8 type, u8 cat, u8 class, u8 func, 756 u32 len) 757 { 758 struct fwcmd_hdr *hdr; 759 760 hdr = (struct fwcmd_hdr *)skb_push(skb, 8); 761 762 hdr->hdr0 = cpu_to_le32(FIELD_PREP(H2C_HDR_DEL_TYPE, type) | 763 FIELD_PREP(H2C_HDR_CAT, cat) | 764 FIELD_PREP(H2C_HDR_CLASS, class) | 765 FIELD_PREP(H2C_HDR_FUNC, func) | 766 FIELD_PREP(H2C_HDR_H2C_SEQ, rtwdev->fw.h2c_seq)); 767 768 hdr->hdr1 = cpu_to_le32(FIELD_PREP(H2C_HDR_TOTAL_LEN, 769 len + H2C_HEADER_LEN)); 770 } 771 772 static int __rtw89_fw_download_hdr(struct rtw89_dev *rtwdev, const u8 *fw, u32 len) 773 { 774 struct sk_buff *skb; 775 u32 ret = 0; 776 777 skb = rtw89_fw_h2c_alloc_skb_with_hdr(rtwdev, len); 778 if (!skb) { 779 rtw89_err(rtwdev, "failed to alloc skb for fw hdr dl\n"); 780 return -ENOMEM; 781 } 782 783 skb_put_data(skb, fw, len); 784 SET_FW_HDR_PART_SIZE(skb->data, FWDL_SECTION_PER_PKT_LEN); 785 rtw89_h2c_pkt_set_hdr_fwdl(rtwdev, skb, FWCMD_TYPE_H2C, 786 H2C_CAT_MAC, H2C_CL_MAC_FWDL, 787 H2C_FUNC_MAC_FWHDR_DL, len); 788 789 ret = rtw89_h2c_tx(rtwdev, skb, false); 790 if (ret) { 791 rtw89_err(rtwdev, "failed to send h2c\n"); 792 ret = -1; 793 goto fail; 794 } 795 796 return 0; 797 fail: 798 dev_kfree_skb_any(skb); 799 800 return ret; 801 } 802 803 static int rtw89_fw_download_hdr(struct rtw89_dev *rtwdev, const u8 *fw, u32 len) 804 { 805 u8 val; 806 int ret; 807 808 ret = __rtw89_fw_download_hdr(rtwdev, fw, len); 809 if (ret) { 810 rtw89_err(rtwdev, "[ERR]FW header download\n"); 811 return ret; 812 } 813 814 ret = read_poll_timeout_atomic(rtw89_read8, val, val & B_AX_FWDL_PATH_RDY, 815 1, FWDL_WAIT_CNT, false, 816 rtwdev, R_AX_WCPU_FW_CTRL); 817 if (ret) { 818 rtw89_err(rtwdev, "[ERR]FWDL path ready\n"); 819 return ret; 820 } 821 822 rtw89_write32(rtwdev, R_AX_HALT_H2C_CTRL, 0); 823 rtw89_write32(rtwdev, R_AX_HALT_C2H_CTRL, 0); 824 825 return 0; 826 } 827 828 static int __rtw89_fw_download_main(struct rtw89_dev *rtwdev, 829 struct rtw89_fw_hdr_section_info *info) 830 { 831 struct sk_buff *skb; 832 const u8 *section = info->addr; 833 u32 residue_len = info->len; 834 u32 pkt_len; 835 int ret; 836 837 while (residue_len) { 838 if (residue_len >= FWDL_SECTION_PER_PKT_LEN) 839 pkt_len = FWDL_SECTION_PER_PKT_LEN; 840 else 841 pkt_len = residue_len; 842 843 skb = rtw89_fw_h2c_alloc_skb_no_hdr(rtwdev, pkt_len); 844 if (!skb) { 845 rtw89_err(rtwdev, "failed to alloc skb for fw dl\n"); 846 return -ENOMEM; 847 } 848 skb_put_data(skb, section, pkt_len); 849 850 ret = rtw89_h2c_tx(rtwdev, skb, true); 851 if (ret) { 852 rtw89_err(rtwdev, "failed to send h2c\n"); 853 ret = -1; 854 goto fail; 855 } 856 857 section += pkt_len; 858 residue_len -= pkt_len; 859 } 860 861 return 0; 862 fail: 863 dev_kfree_skb_any(skb); 864 865 return ret; 866 } 867 868 static int rtw89_fw_download_main(struct rtw89_dev *rtwdev, const u8 *fw, 869 struct rtw89_fw_bin_info *info) 870 { 871 struct rtw89_fw_hdr_section_info *section_info = info->section_info; 872 u8 section_num = info->section_num; 873 int ret; 874 875 while (section_num--) { 876 ret = __rtw89_fw_download_main(rtwdev, section_info); 877 if (ret) 878 return ret; 879 section_info++; 880 } 881 882 mdelay(5); 883 884 ret = rtw89_fw_check_rdy(rtwdev); 885 if (ret) { 886 rtw89_warn(rtwdev, "download firmware fail\n"); 887 return ret; 888 } 889 890 return 0; 891 } 892 893 static void rtw89_fw_prog_cnt_dump(struct rtw89_dev *rtwdev) 894 { 895 u32 val32; 896 u16 index; 897 898 rtw89_write32(rtwdev, R_AX_DBG_CTRL, 899 FIELD_PREP(B_AX_DBG_SEL0, FW_PROG_CNTR_DBG_SEL) | 900 FIELD_PREP(B_AX_DBG_SEL1, FW_PROG_CNTR_DBG_SEL)); 901 rtw89_write32_mask(rtwdev, R_AX_SYS_STATUS1, B_AX_SEL_0XC0_MASK, MAC_DBG_SEL); 902 903 for (index = 0; index < 15; index++) { 904 val32 = rtw89_read32(rtwdev, R_AX_DBG_PORT_SEL); 905 rtw89_err(rtwdev, "[ERR]fw PC = 0x%x\n", val32); 906 fsleep(10); 907 } 908 } 909 910 static void rtw89_fw_dl_fail_dump(struct rtw89_dev *rtwdev) 911 { 912 u32 val32; 913 u16 val16; 914 915 val32 = rtw89_read32(rtwdev, R_AX_WCPU_FW_CTRL); 916 rtw89_err(rtwdev, "[ERR]fwdl 0x1E0 = 0x%x\n", val32); 917 918 val16 = rtw89_read16(rtwdev, R_AX_BOOT_DBG + 2); 919 rtw89_err(rtwdev, "[ERR]fwdl 0x83F2 = 0x%x\n", val16); 920 921 rtw89_fw_prog_cnt_dump(rtwdev); 922 } 923 924 int rtw89_fw_download(struct rtw89_dev *rtwdev, enum rtw89_fw_type type) 925 { 926 struct rtw89_fw_info *fw_info = &rtwdev->fw; 927 struct rtw89_fw_suit *fw_suit = rtw89_fw_suit_get(rtwdev, type); 928 struct rtw89_fw_bin_info info; 929 u8 val; 930 int ret; 931 932 rtw89_mac_disable_cpu(rtwdev); 933 ret = rtw89_mac_enable_cpu(rtwdev, 0, true); 934 if (ret) 935 return ret; 936 937 ret = rtw89_fw_hdr_parser(rtwdev, fw_suit, &info); 938 if (ret) { 939 rtw89_err(rtwdev, "parse fw header fail\n"); 940 goto fwdl_err; 941 } 942 943 ret = read_poll_timeout_atomic(rtw89_read8, val, val & B_AX_H2C_PATH_RDY, 944 1, FWDL_WAIT_CNT, false, 945 rtwdev, R_AX_WCPU_FW_CTRL); 946 if (ret) { 947 rtw89_err(rtwdev, "[ERR]H2C path ready\n"); 948 goto fwdl_err; 949 } 950 951 ret = rtw89_fw_download_hdr(rtwdev, fw_suit->data, info.hdr_len - 952 info.dynamic_hdr_len); 953 if (ret) { 954 ret = -EBUSY; 955 goto fwdl_err; 956 } 957 958 ret = rtw89_fw_download_main(rtwdev, fw_suit->data, &info); 959 if (ret) { 960 ret = -EBUSY; 961 goto fwdl_err; 962 } 963 964 fw_info->h2c_seq = 0; 965 fw_info->rec_seq = 0; 966 fw_info->h2c_counter = 0; 967 fw_info->c2h_counter = 0; 968 rtwdev->mac.rpwm_seq_num = RPWM_SEQ_NUM_MAX; 969 rtwdev->mac.cpwm_seq_num = CPWM_SEQ_NUM_MAX; 970 971 return ret; 972 973 fwdl_err: 974 rtw89_fw_dl_fail_dump(rtwdev); 975 return ret; 976 } 977 978 int rtw89_wait_firmware_completion(struct rtw89_dev *rtwdev) 979 { 980 struct rtw89_fw_info *fw = &rtwdev->fw; 981 982 wait_for_completion(&fw->req.completion); 983 if (!fw->req.firmware) 984 return -EINVAL; 985 986 return 0; 987 } 988 989 static int rtw89_load_firmware_req(struct rtw89_dev *rtwdev, 990 struct rtw89_fw_req_info *req, 991 const char *fw_name, bool nowarn) 992 { 993 int ret; 994 995 if (req->firmware) { 996 rtw89_debug(rtwdev, RTW89_DBG_FW, 997 "full firmware has been early requested\n"); 998 complete_all(&req->completion); 999 return 0; 1000 } 1001 1002 if (nowarn) 1003 ret = firmware_request_nowarn(&req->firmware, fw_name, rtwdev->dev); 1004 else 1005 ret = request_firmware(&req->firmware, fw_name, rtwdev->dev); 1006 1007 complete_all(&req->completion); 1008 1009 return ret; 1010 } 1011 1012 void rtw89_load_firmware_work(struct work_struct *work) 1013 { 1014 struct rtw89_dev *rtwdev = 1015 container_of(work, struct rtw89_dev, load_firmware_work); 1016 const struct rtw89_chip_info *chip = rtwdev->chip; 1017 char fw_name[64]; 1018 1019 rtw89_fw_get_filename(fw_name, sizeof(fw_name), 1020 chip->fw_basename, rtwdev->fw.fw_format); 1021 1022 rtw89_load_firmware_req(rtwdev, &rtwdev->fw.req, fw_name, false); 1023 } 1024 1025 static void rtw89_free_phy_tbl_from_elm(struct rtw89_phy_table *tbl) 1026 { 1027 if (!tbl) 1028 return; 1029 1030 kfree(tbl->regs); 1031 kfree(tbl); 1032 } 1033 1034 static void rtw89_unload_firmware_elements(struct rtw89_dev *rtwdev) 1035 { 1036 struct rtw89_fw_elm_info *elm_info = &rtwdev->fw.elm_info; 1037 int i; 1038 1039 rtw89_free_phy_tbl_from_elm(elm_info->bb_tbl); 1040 rtw89_free_phy_tbl_from_elm(elm_info->bb_gain); 1041 for (i = 0; i < ARRAY_SIZE(elm_info->rf_radio); i++) 1042 rtw89_free_phy_tbl_from_elm(elm_info->rf_radio[i]); 1043 rtw89_free_phy_tbl_from_elm(elm_info->rf_nctl); 1044 } 1045 1046 void rtw89_unload_firmware(struct rtw89_dev *rtwdev) 1047 { 1048 struct rtw89_fw_info *fw = &rtwdev->fw; 1049 1050 cancel_work_sync(&rtwdev->load_firmware_work); 1051 1052 if (fw->req.firmware) { 1053 release_firmware(fw->req.firmware); 1054 1055 /* assign NULL back in case rtw89_free_ieee80211_hw() 1056 * try to release the same one again. 1057 */ 1058 fw->req.firmware = NULL; 1059 } 1060 1061 kfree(fw->log.fmts); 1062 rtw89_unload_firmware_elements(rtwdev); 1063 } 1064 1065 static u32 rtw89_fw_log_get_fmt_idx(struct rtw89_dev *rtwdev, u32 fmt_id) 1066 { 1067 struct rtw89_fw_log *fw_log = &rtwdev->fw.log; 1068 u32 i; 1069 1070 if (fmt_id > fw_log->last_fmt_id) 1071 return 0; 1072 1073 for (i = 0; i < fw_log->fmt_count; i++) { 1074 if (le32_to_cpu(fw_log->fmt_ids[i]) == fmt_id) 1075 return i; 1076 } 1077 return 0; 1078 } 1079 1080 static int rtw89_fw_log_create_fmts_dict(struct rtw89_dev *rtwdev) 1081 { 1082 struct rtw89_fw_log *log = &rtwdev->fw.log; 1083 const struct rtw89_fw_logsuit_hdr *suit_hdr; 1084 struct rtw89_fw_suit *suit = &log->suit; 1085 #if defined(__linux__) 1086 const void *fmts_ptr, *fmts_end_ptr; 1087 #elif defined(__FreeBSD__) 1088 const u8 *fmts_ptr, *fmts_end_ptr; 1089 #endif 1090 u32 fmt_count; 1091 int i; 1092 1093 suit_hdr = (const struct rtw89_fw_logsuit_hdr *)suit->data; 1094 fmt_count = le32_to_cpu(suit_hdr->count); 1095 log->fmt_ids = suit_hdr->ids; 1096 #if defined(__linux__) 1097 fmts_ptr = &suit_hdr->ids[fmt_count]; 1098 #elif defined(__FreeBSD__) 1099 fmts_ptr = (const u8 *)&suit_hdr->ids[fmt_count]; 1100 #endif 1101 fmts_end_ptr = suit->data + suit->size; 1102 log->fmts = kcalloc(fmt_count, sizeof(char *), GFP_KERNEL); 1103 if (!log->fmts) 1104 return -ENOMEM; 1105 1106 for (i = 0; i < fmt_count; i++) { 1107 fmts_ptr = memchr_inv(fmts_ptr, 0, fmts_end_ptr - fmts_ptr); 1108 if (!fmts_ptr) 1109 break; 1110 1111 (*log->fmts)[i] = fmts_ptr; 1112 log->last_fmt_id = le32_to_cpu(log->fmt_ids[i]); 1113 log->fmt_count++; 1114 fmts_ptr += strlen(fmts_ptr); 1115 } 1116 1117 return 0; 1118 } 1119 1120 int rtw89_fw_log_prepare(struct rtw89_dev *rtwdev) 1121 { 1122 struct rtw89_fw_log *log = &rtwdev->fw.log; 1123 struct rtw89_fw_suit *suit = &log->suit; 1124 1125 if (!suit || !suit->data) { 1126 rtw89_debug(rtwdev, RTW89_DBG_FW, "no log format file\n"); 1127 return -EINVAL; 1128 } 1129 if (log->fmts) 1130 return 0; 1131 1132 return rtw89_fw_log_create_fmts_dict(rtwdev); 1133 } 1134 1135 static void rtw89_fw_log_dump_data(struct rtw89_dev *rtwdev, 1136 const struct rtw89_fw_c2h_log_fmt *log_fmt, 1137 u32 fmt_idx, u8 para_int, bool raw_data) 1138 { 1139 const char *(*fmts)[] = rtwdev->fw.log.fmts; 1140 char str_buf[RTW89_C2H_FW_LOG_STR_BUF_SIZE]; 1141 u32 args[RTW89_C2H_FW_LOG_MAX_PARA_NUM] = {0}; 1142 int i; 1143 1144 if (log_fmt->argc > RTW89_C2H_FW_LOG_MAX_PARA_NUM) { 1145 rtw89_warn(rtwdev, "C2H log: Arg count is unexpected %d\n", 1146 log_fmt->argc); 1147 return; 1148 } 1149 1150 if (para_int) 1151 for (i = 0 ; i < log_fmt->argc; i++) 1152 args[i] = le32_to_cpu(log_fmt->u.argv[i]); 1153 1154 if (raw_data) { 1155 if (para_int) 1156 snprintf(str_buf, RTW89_C2H_FW_LOG_STR_BUF_SIZE, 1157 "fw_enc(%d, %d, %d) %*ph", le32_to_cpu(log_fmt->fmt_id), 1158 para_int, log_fmt->argc, (int)sizeof(args), args); 1159 else 1160 snprintf(str_buf, RTW89_C2H_FW_LOG_STR_BUF_SIZE, 1161 "fw_enc(%d, %d, %d, %s)", le32_to_cpu(log_fmt->fmt_id), 1162 para_int, log_fmt->argc, log_fmt->u.raw); 1163 } else { 1164 snprintf(str_buf, RTW89_C2H_FW_LOG_STR_BUF_SIZE, (*fmts)[fmt_idx], 1165 args[0x0], args[0x1], args[0x2], args[0x3], args[0x4], 1166 args[0x5], args[0x6], args[0x7], args[0x8], args[0x9], 1167 args[0xa], args[0xb], args[0xc], args[0xd], args[0xe], 1168 args[0xf]); 1169 } 1170 1171 rtw89_info(rtwdev, "C2H log: %s", str_buf); 1172 } 1173 1174 void rtw89_fw_log_dump(struct rtw89_dev *rtwdev, u8 *buf, u32 len) 1175 { 1176 const struct rtw89_fw_c2h_log_fmt *log_fmt; 1177 u8 para_int; 1178 u32 fmt_idx; 1179 1180 if (len < RTW89_C2H_HEADER_LEN) { 1181 rtw89_err(rtwdev, "c2h log length is wrong!\n"); 1182 return; 1183 } 1184 1185 buf += RTW89_C2H_HEADER_LEN; 1186 len -= RTW89_C2H_HEADER_LEN; 1187 log_fmt = (const struct rtw89_fw_c2h_log_fmt *)buf; 1188 1189 if (len < RTW89_C2H_FW_FORMATTED_LOG_MIN_LEN) 1190 goto plain_log; 1191 1192 if (log_fmt->signature != cpu_to_le16(RTW89_C2H_FW_LOG_SIGNATURE)) 1193 goto plain_log; 1194 1195 if (!rtwdev->fw.log.fmts) 1196 return; 1197 1198 para_int = u8_get_bits(log_fmt->feature, RTW89_C2H_FW_LOG_FEATURE_PARA_INT); 1199 fmt_idx = rtw89_fw_log_get_fmt_idx(rtwdev, le32_to_cpu(log_fmt->fmt_id)); 1200 1201 if (!para_int && log_fmt->argc != 0 && fmt_idx != 0) 1202 rtw89_info(rtwdev, "C2H log: %s%s", 1203 (*rtwdev->fw.log.fmts)[fmt_idx], log_fmt->u.raw); 1204 else if (fmt_idx != 0 && para_int) 1205 rtw89_fw_log_dump_data(rtwdev, log_fmt, fmt_idx, para_int, false); 1206 else 1207 rtw89_fw_log_dump_data(rtwdev, log_fmt, fmt_idx, para_int, true); 1208 return; 1209 1210 plain_log: 1211 rtw89_info(rtwdev, "C2H log: %*s", len, buf); 1212 1213 } 1214 1215 #define H2C_CAM_LEN 60 1216 int rtw89_fw_h2c_cam(struct rtw89_dev *rtwdev, struct rtw89_vif *rtwvif, 1217 struct rtw89_sta *rtwsta, const u8 *scan_mac_addr) 1218 { 1219 struct sk_buff *skb; 1220 int ret; 1221 1222 skb = rtw89_fw_h2c_alloc_skb_with_hdr(rtwdev, H2C_CAM_LEN); 1223 if (!skb) { 1224 rtw89_err(rtwdev, "failed to alloc skb for fw dl\n"); 1225 return -ENOMEM; 1226 } 1227 skb_put(skb, H2C_CAM_LEN); 1228 rtw89_cam_fill_addr_cam_info(rtwdev, rtwvif, rtwsta, scan_mac_addr, skb->data); 1229 rtw89_cam_fill_bssid_cam_info(rtwdev, rtwvif, rtwsta, skb->data); 1230 1231 rtw89_h2c_pkt_set_hdr(rtwdev, skb, FWCMD_TYPE_H2C, 1232 H2C_CAT_MAC, 1233 H2C_CL_MAC_ADDR_CAM_UPDATE, 1234 H2C_FUNC_MAC_ADDR_CAM_UPD, 0, 1, 1235 H2C_CAM_LEN); 1236 1237 ret = rtw89_h2c_tx(rtwdev, skb, false); 1238 if (ret) { 1239 rtw89_err(rtwdev, "failed to send h2c\n"); 1240 goto fail; 1241 } 1242 1243 return 0; 1244 fail: 1245 dev_kfree_skb_any(skb); 1246 1247 return ret; 1248 } 1249 1250 #define H2C_DCTL_SEC_CAM_LEN 68 1251 int rtw89_fw_h2c_dctl_sec_cam_v1(struct rtw89_dev *rtwdev, 1252 struct rtw89_vif *rtwvif, 1253 struct rtw89_sta *rtwsta) 1254 { 1255 struct sk_buff *skb; 1256 int ret; 1257 1258 skb = rtw89_fw_h2c_alloc_skb_with_hdr(rtwdev, H2C_DCTL_SEC_CAM_LEN); 1259 if (!skb) { 1260 rtw89_err(rtwdev, "failed to alloc skb for dctl sec cam\n"); 1261 return -ENOMEM; 1262 } 1263 skb_put(skb, H2C_DCTL_SEC_CAM_LEN); 1264 1265 rtw89_cam_fill_dctl_sec_cam_info_v1(rtwdev, rtwvif, rtwsta, skb->data); 1266 1267 rtw89_h2c_pkt_set_hdr(rtwdev, skb, FWCMD_TYPE_H2C, 1268 H2C_CAT_MAC, 1269 H2C_CL_MAC_FR_EXCHG, 1270 H2C_FUNC_MAC_DCTLINFO_UD_V1, 0, 0, 1271 H2C_DCTL_SEC_CAM_LEN); 1272 1273 ret = rtw89_h2c_tx(rtwdev, skb, false); 1274 if (ret) { 1275 rtw89_err(rtwdev, "failed to send h2c\n"); 1276 goto fail; 1277 } 1278 1279 return 0; 1280 fail: 1281 dev_kfree_skb_any(skb); 1282 1283 return ret; 1284 } 1285 EXPORT_SYMBOL(rtw89_fw_h2c_dctl_sec_cam_v1); 1286 1287 #define H2C_BA_CAM_LEN 8 1288 int rtw89_fw_h2c_ba_cam(struct rtw89_dev *rtwdev, struct rtw89_sta *rtwsta, 1289 bool valid, struct ieee80211_ampdu_params *params) 1290 { 1291 const struct rtw89_chip_info *chip = rtwdev->chip; 1292 struct rtw89_vif *rtwvif = rtwsta->rtwvif; 1293 u8 macid = rtwsta->mac_id; 1294 struct sk_buff *skb; 1295 u8 entry_idx; 1296 int ret; 1297 1298 ret = valid ? 1299 rtw89_core_acquire_sta_ba_entry(rtwdev, rtwsta, params->tid, &entry_idx) : 1300 rtw89_core_release_sta_ba_entry(rtwdev, rtwsta, params->tid, &entry_idx); 1301 if (ret) { 1302 /* it still works even if we don't have static BA CAM, because 1303 * hardware can create dynamic BA CAM automatically. 1304 */ 1305 rtw89_debug(rtwdev, RTW89_DBG_TXRX, 1306 "failed to %s entry tid=%d for h2c ba cam\n", 1307 valid ? "alloc" : "free", params->tid); 1308 return 0; 1309 } 1310 1311 skb = rtw89_fw_h2c_alloc_skb_with_hdr(rtwdev, H2C_BA_CAM_LEN); 1312 if (!skb) { 1313 rtw89_err(rtwdev, "failed to alloc skb for h2c ba cam\n"); 1314 return -ENOMEM; 1315 } 1316 skb_put(skb, H2C_BA_CAM_LEN); 1317 SET_BA_CAM_MACID(skb->data, macid); 1318 if (chip->bacam_ver == RTW89_BACAM_V0_EXT) 1319 SET_BA_CAM_ENTRY_IDX_V1(skb->data, entry_idx); 1320 else 1321 SET_BA_CAM_ENTRY_IDX(skb->data, entry_idx); 1322 if (!valid) 1323 goto end; 1324 SET_BA_CAM_VALID(skb->data, valid); 1325 SET_BA_CAM_TID(skb->data, params->tid); 1326 if (params->buf_size > 64) 1327 SET_BA_CAM_BMAP_SIZE(skb->data, 4); 1328 else 1329 SET_BA_CAM_BMAP_SIZE(skb->data, 0); 1330 /* If init req is set, hw will set the ssn */ 1331 SET_BA_CAM_INIT_REQ(skb->data, 1); 1332 SET_BA_CAM_SSN(skb->data, params->ssn); 1333 1334 if (chip->bacam_ver == RTW89_BACAM_V0_EXT) { 1335 SET_BA_CAM_STD_EN(skb->data, 1); 1336 SET_BA_CAM_BAND(skb->data, rtwvif->mac_idx); 1337 } 1338 1339 end: 1340 rtw89_h2c_pkt_set_hdr(rtwdev, skb, FWCMD_TYPE_H2C, 1341 H2C_CAT_MAC, 1342 H2C_CL_BA_CAM, 1343 H2C_FUNC_MAC_BA_CAM, 0, 1, 1344 H2C_BA_CAM_LEN); 1345 1346 ret = rtw89_h2c_tx(rtwdev, skb, false); 1347 if (ret) { 1348 rtw89_err(rtwdev, "failed to send h2c\n"); 1349 goto fail; 1350 } 1351 1352 return 0; 1353 fail: 1354 dev_kfree_skb_any(skb); 1355 1356 return ret; 1357 } 1358 1359 static int rtw89_fw_h2c_init_ba_cam_v0_ext(struct rtw89_dev *rtwdev, 1360 u8 entry_idx, u8 uid) 1361 { 1362 struct sk_buff *skb; 1363 int ret; 1364 1365 skb = rtw89_fw_h2c_alloc_skb_with_hdr(rtwdev, H2C_BA_CAM_LEN); 1366 if (!skb) { 1367 rtw89_err(rtwdev, "failed to alloc skb for dynamic h2c ba cam\n"); 1368 return -ENOMEM; 1369 } 1370 skb_put(skb, H2C_BA_CAM_LEN); 1371 1372 SET_BA_CAM_VALID(skb->data, 1); 1373 SET_BA_CAM_ENTRY_IDX_V1(skb->data, entry_idx); 1374 SET_BA_CAM_UID(skb->data, uid); 1375 SET_BA_CAM_BAND(skb->data, 0); 1376 SET_BA_CAM_STD_EN(skb->data, 0); 1377 1378 rtw89_h2c_pkt_set_hdr(rtwdev, skb, FWCMD_TYPE_H2C, 1379 H2C_CAT_MAC, 1380 H2C_CL_BA_CAM, 1381 H2C_FUNC_MAC_BA_CAM, 0, 1, 1382 H2C_BA_CAM_LEN); 1383 1384 ret = rtw89_h2c_tx(rtwdev, skb, false); 1385 if (ret) { 1386 rtw89_err(rtwdev, "failed to send h2c\n"); 1387 goto fail; 1388 } 1389 1390 return 0; 1391 fail: 1392 dev_kfree_skb_any(skb); 1393 1394 return ret; 1395 } 1396 1397 void rtw89_fw_h2c_init_dynamic_ba_cam_v0_ext(struct rtw89_dev *rtwdev) 1398 { 1399 const struct rtw89_chip_info *chip = rtwdev->chip; 1400 u8 entry_idx = chip->bacam_num; 1401 u8 uid = 0; 1402 int i; 1403 1404 for (i = 0; i < chip->bacam_dynamic_num; i++) { 1405 rtw89_fw_h2c_init_ba_cam_v0_ext(rtwdev, entry_idx, uid); 1406 entry_idx++; 1407 uid++; 1408 } 1409 } 1410 1411 #define H2C_LOG_CFG_LEN 12 1412 int rtw89_fw_h2c_fw_log(struct rtw89_dev *rtwdev, bool enable) 1413 { 1414 struct sk_buff *skb; 1415 u32 comp = enable ? BIT(RTW89_FW_LOG_COMP_INIT) | BIT(RTW89_FW_LOG_COMP_TASK) | 1416 BIT(RTW89_FW_LOG_COMP_PS) | BIT(RTW89_FW_LOG_COMP_ERROR) : 0; 1417 int ret; 1418 1419 skb = rtw89_fw_h2c_alloc_skb_with_hdr(rtwdev, H2C_LOG_CFG_LEN); 1420 if (!skb) { 1421 rtw89_err(rtwdev, "failed to alloc skb for fw log cfg\n"); 1422 return -ENOMEM; 1423 } 1424 1425 skb_put(skb, H2C_LOG_CFG_LEN); 1426 SET_LOG_CFG_LEVEL(skb->data, RTW89_FW_LOG_LEVEL_LOUD); 1427 SET_LOG_CFG_PATH(skb->data, BIT(RTW89_FW_LOG_LEVEL_C2H)); 1428 SET_LOG_CFG_COMP(skb->data, comp); 1429 SET_LOG_CFG_COMP_EXT(skb->data, 0); 1430 1431 rtw89_h2c_pkt_set_hdr(rtwdev, skb, FWCMD_TYPE_H2C, 1432 H2C_CAT_MAC, 1433 H2C_CL_FW_INFO, 1434 H2C_FUNC_LOG_CFG, 0, 0, 1435 H2C_LOG_CFG_LEN); 1436 1437 ret = rtw89_h2c_tx(rtwdev, skb, false); 1438 if (ret) { 1439 rtw89_err(rtwdev, "failed to send h2c\n"); 1440 goto fail; 1441 } 1442 1443 return 0; 1444 fail: 1445 dev_kfree_skb_any(skb); 1446 1447 return ret; 1448 } 1449 1450 static int rtw89_fw_h2c_add_general_pkt(struct rtw89_dev *rtwdev, 1451 struct rtw89_vif *rtwvif, 1452 enum rtw89_fw_pkt_ofld_type type, 1453 u8 *id) 1454 { 1455 struct ieee80211_vif *vif = rtwvif_to_vif(rtwvif); 1456 struct rtw89_pktofld_info *info; 1457 struct sk_buff *skb; 1458 int ret; 1459 1460 info = kzalloc(sizeof(*info), GFP_KERNEL); 1461 if (!info) 1462 return -ENOMEM; 1463 1464 switch (type) { 1465 case RTW89_PKT_OFLD_TYPE_PS_POLL: 1466 skb = ieee80211_pspoll_get(rtwdev->hw, vif); 1467 break; 1468 case RTW89_PKT_OFLD_TYPE_PROBE_RSP: 1469 skb = ieee80211_proberesp_get(rtwdev->hw, vif); 1470 break; 1471 case RTW89_PKT_OFLD_TYPE_NULL_DATA: 1472 skb = ieee80211_nullfunc_get(rtwdev->hw, vif, -1, false); 1473 break; 1474 case RTW89_PKT_OFLD_TYPE_QOS_NULL: 1475 skb = ieee80211_nullfunc_get(rtwdev->hw, vif, -1, true); 1476 break; 1477 default: 1478 goto err; 1479 } 1480 1481 if (!skb) 1482 goto err; 1483 1484 ret = rtw89_fw_h2c_add_pkt_offload(rtwdev, &info->id, skb); 1485 kfree_skb(skb); 1486 1487 if (ret) 1488 goto err; 1489 1490 list_add_tail(&info->list, &rtwvif->general_pkt_list); 1491 *id = info->id; 1492 return 0; 1493 1494 err: 1495 kfree(info); 1496 return -ENOMEM; 1497 } 1498 1499 void rtw89_fw_release_general_pkt_list_vif(struct rtw89_dev *rtwdev, 1500 struct rtw89_vif *rtwvif, bool notify_fw) 1501 { 1502 struct list_head *pkt_list = &rtwvif->general_pkt_list; 1503 struct rtw89_pktofld_info *info, *tmp; 1504 1505 list_for_each_entry_safe(info, tmp, pkt_list, list) { 1506 if (notify_fw) 1507 rtw89_fw_h2c_del_pkt_offload(rtwdev, info->id); 1508 else 1509 rtw89_core_release_bit_map(rtwdev->pkt_offload, info->id); 1510 list_del(&info->list); 1511 kfree(info); 1512 } 1513 } 1514 1515 void rtw89_fw_release_general_pkt_list(struct rtw89_dev *rtwdev, bool notify_fw) 1516 { 1517 struct rtw89_vif *rtwvif; 1518 1519 rtw89_for_each_rtwvif(rtwdev, rtwvif) 1520 rtw89_fw_release_general_pkt_list_vif(rtwdev, rtwvif, notify_fw); 1521 } 1522 1523 #define H2C_GENERAL_PKT_LEN 6 1524 #define H2C_GENERAL_PKT_ID_UND 0xff 1525 int rtw89_fw_h2c_general_pkt(struct rtw89_dev *rtwdev, 1526 struct rtw89_vif *rtwvif, u8 macid) 1527 { 1528 u8 pkt_id_ps_poll = H2C_GENERAL_PKT_ID_UND; 1529 u8 pkt_id_null = H2C_GENERAL_PKT_ID_UND; 1530 u8 pkt_id_qos_null = H2C_GENERAL_PKT_ID_UND; 1531 struct sk_buff *skb; 1532 int ret; 1533 1534 rtw89_fw_h2c_add_general_pkt(rtwdev, rtwvif, 1535 RTW89_PKT_OFLD_TYPE_PS_POLL, &pkt_id_ps_poll); 1536 rtw89_fw_h2c_add_general_pkt(rtwdev, rtwvif, 1537 RTW89_PKT_OFLD_TYPE_NULL_DATA, &pkt_id_null); 1538 rtw89_fw_h2c_add_general_pkt(rtwdev, rtwvif, 1539 RTW89_PKT_OFLD_TYPE_QOS_NULL, &pkt_id_qos_null); 1540 1541 skb = rtw89_fw_h2c_alloc_skb_with_hdr(rtwdev, H2C_GENERAL_PKT_LEN); 1542 if (!skb) { 1543 rtw89_err(rtwdev, "failed to alloc skb for fw dl\n"); 1544 return -ENOMEM; 1545 } 1546 skb_put(skb, H2C_GENERAL_PKT_LEN); 1547 SET_GENERAL_PKT_MACID(skb->data, macid); 1548 SET_GENERAL_PKT_PROBRSP_ID(skb->data, H2C_GENERAL_PKT_ID_UND); 1549 SET_GENERAL_PKT_PSPOLL_ID(skb->data, pkt_id_ps_poll); 1550 SET_GENERAL_PKT_NULL_ID(skb->data, pkt_id_null); 1551 SET_GENERAL_PKT_QOS_NULL_ID(skb->data, pkt_id_qos_null); 1552 SET_GENERAL_PKT_CTS2SELF_ID(skb->data, H2C_GENERAL_PKT_ID_UND); 1553 1554 rtw89_h2c_pkt_set_hdr(rtwdev, skb, FWCMD_TYPE_H2C, 1555 H2C_CAT_MAC, 1556 H2C_CL_FW_INFO, 1557 H2C_FUNC_MAC_GENERAL_PKT, 0, 1, 1558 H2C_GENERAL_PKT_LEN); 1559 1560 ret = rtw89_h2c_tx(rtwdev, skb, false); 1561 if (ret) { 1562 rtw89_err(rtwdev, "failed to send h2c\n"); 1563 goto fail; 1564 } 1565 1566 return 0; 1567 fail: 1568 dev_kfree_skb_any(skb); 1569 1570 return ret; 1571 } 1572 1573 #define H2C_LPS_PARM_LEN 8 1574 int rtw89_fw_h2c_lps_parm(struct rtw89_dev *rtwdev, 1575 struct rtw89_lps_parm *lps_param) 1576 { 1577 struct sk_buff *skb; 1578 int ret; 1579 1580 skb = rtw89_fw_h2c_alloc_skb_with_hdr(rtwdev, H2C_LPS_PARM_LEN); 1581 if (!skb) { 1582 rtw89_err(rtwdev, "failed to alloc skb for fw dl\n"); 1583 return -ENOMEM; 1584 } 1585 skb_put(skb, H2C_LPS_PARM_LEN); 1586 1587 SET_LPS_PARM_MACID(skb->data, lps_param->macid); 1588 SET_LPS_PARM_PSMODE(skb->data, lps_param->psmode); 1589 SET_LPS_PARM_LASTRPWM(skb->data, lps_param->lastrpwm); 1590 SET_LPS_PARM_RLBM(skb->data, 1); 1591 SET_LPS_PARM_SMARTPS(skb->data, 1); 1592 SET_LPS_PARM_AWAKEINTERVAL(skb->data, 1); 1593 SET_LPS_PARM_VOUAPSD(skb->data, 0); 1594 SET_LPS_PARM_VIUAPSD(skb->data, 0); 1595 SET_LPS_PARM_BEUAPSD(skb->data, 0); 1596 SET_LPS_PARM_BKUAPSD(skb->data, 0); 1597 1598 rtw89_h2c_pkt_set_hdr(rtwdev, skb, FWCMD_TYPE_H2C, 1599 H2C_CAT_MAC, 1600 H2C_CL_MAC_PS, 1601 H2C_FUNC_MAC_LPS_PARM, 0, 1, 1602 H2C_LPS_PARM_LEN); 1603 1604 ret = rtw89_h2c_tx(rtwdev, skb, false); 1605 if (ret) { 1606 rtw89_err(rtwdev, "failed to send h2c\n"); 1607 goto fail; 1608 } 1609 1610 return 0; 1611 fail: 1612 dev_kfree_skb_any(skb); 1613 1614 return ret; 1615 } 1616 1617 #define H2C_P2P_ACT_LEN 20 1618 int rtw89_fw_h2c_p2p_act(struct rtw89_dev *rtwdev, struct ieee80211_vif *vif, 1619 struct ieee80211_p2p_noa_desc *desc, 1620 u8 act, u8 noa_id) 1621 { 1622 struct rtw89_vif *rtwvif = (struct rtw89_vif *)vif->drv_priv; 1623 bool p2p_type_gc = rtwvif->wifi_role == RTW89_WIFI_ROLE_P2P_CLIENT; 1624 u8 ctwindow_oppps = vif->bss_conf.p2p_noa_attr.oppps_ctwindow; 1625 struct sk_buff *skb; 1626 u8 *cmd; 1627 int ret; 1628 1629 skb = rtw89_fw_h2c_alloc_skb_with_hdr(rtwdev, H2C_P2P_ACT_LEN); 1630 if (!skb) { 1631 rtw89_err(rtwdev, "failed to alloc skb for h2c p2p act\n"); 1632 return -ENOMEM; 1633 } 1634 skb_put(skb, H2C_P2P_ACT_LEN); 1635 cmd = skb->data; 1636 1637 RTW89_SET_FWCMD_P2P_MACID(cmd, rtwvif->mac_id); 1638 RTW89_SET_FWCMD_P2P_P2PID(cmd, 0); 1639 RTW89_SET_FWCMD_P2P_NOAID(cmd, noa_id); 1640 RTW89_SET_FWCMD_P2P_ACT(cmd, act); 1641 RTW89_SET_FWCMD_P2P_TYPE(cmd, p2p_type_gc); 1642 RTW89_SET_FWCMD_P2P_ALL_SLEP(cmd, 0); 1643 if (desc) { 1644 RTW89_SET_FWCMD_NOA_START_TIME(cmd, desc->start_time); 1645 RTW89_SET_FWCMD_NOA_INTERVAL(cmd, desc->interval); 1646 RTW89_SET_FWCMD_NOA_DURATION(cmd, desc->duration); 1647 RTW89_SET_FWCMD_NOA_COUNT(cmd, desc->count); 1648 RTW89_SET_FWCMD_NOA_CTWINDOW(cmd, ctwindow_oppps); 1649 } 1650 1651 rtw89_h2c_pkt_set_hdr(rtwdev, skb, FWCMD_TYPE_H2C, 1652 H2C_CAT_MAC, H2C_CL_MAC_PS, 1653 H2C_FUNC_P2P_ACT, 0, 0, 1654 H2C_P2P_ACT_LEN); 1655 1656 ret = rtw89_h2c_tx(rtwdev, skb, false); 1657 if (ret) { 1658 rtw89_err(rtwdev, "failed to send h2c\n"); 1659 goto fail; 1660 } 1661 1662 return 0; 1663 fail: 1664 dev_kfree_skb_any(skb); 1665 1666 return ret; 1667 } 1668 1669 static void __rtw89_fw_h2c_set_tx_path(struct rtw89_dev *rtwdev, 1670 struct sk_buff *skb) 1671 { 1672 const struct rtw89_chip_info *chip = rtwdev->chip; 1673 struct rtw89_hal *hal = &rtwdev->hal; 1674 u8 ntx_path; 1675 u8 map_b; 1676 1677 if (chip->rf_path_num == 1) { 1678 ntx_path = RF_A; 1679 map_b = 0; 1680 } else { 1681 ntx_path = hal->antenna_tx ? hal->antenna_tx : RF_B; 1682 map_b = hal->antenna_tx == RF_AB ? 1 : 0; 1683 } 1684 1685 SET_CMC_TBL_NTX_PATH_EN(skb->data, ntx_path); 1686 SET_CMC_TBL_PATH_MAP_A(skb->data, 0); 1687 SET_CMC_TBL_PATH_MAP_B(skb->data, map_b); 1688 SET_CMC_TBL_PATH_MAP_C(skb->data, 0); 1689 SET_CMC_TBL_PATH_MAP_D(skb->data, 0); 1690 } 1691 1692 #define H2C_CMC_TBL_LEN 68 1693 int rtw89_fw_h2c_default_cmac_tbl(struct rtw89_dev *rtwdev, 1694 struct rtw89_vif *rtwvif) 1695 { 1696 const struct rtw89_chip_info *chip = rtwdev->chip; 1697 struct sk_buff *skb; 1698 u8 macid = rtwvif->mac_id; 1699 int ret; 1700 1701 skb = rtw89_fw_h2c_alloc_skb_with_hdr(rtwdev, H2C_CMC_TBL_LEN); 1702 if (!skb) { 1703 rtw89_err(rtwdev, "failed to alloc skb for fw dl\n"); 1704 return -ENOMEM; 1705 } 1706 skb_put(skb, H2C_CMC_TBL_LEN); 1707 SET_CTRL_INFO_MACID(skb->data, macid); 1708 SET_CTRL_INFO_OPERATION(skb->data, 1); 1709 if (chip->h2c_cctl_func_id == H2C_FUNC_MAC_CCTLINFO_UD) { 1710 SET_CMC_TBL_TXPWR_MODE(skb->data, 0); 1711 __rtw89_fw_h2c_set_tx_path(rtwdev, skb); 1712 SET_CMC_TBL_ANTSEL_A(skb->data, 0); 1713 SET_CMC_TBL_ANTSEL_B(skb->data, 0); 1714 SET_CMC_TBL_ANTSEL_C(skb->data, 0); 1715 SET_CMC_TBL_ANTSEL_D(skb->data, 0); 1716 } 1717 SET_CMC_TBL_DOPPLER_CTRL(skb->data, 0); 1718 SET_CMC_TBL_TXPWR_TOLERENCE(skb->data, 0); 1719 if (rtwvif->net_type == RTW89_NET_TYPE_AP_MODE) 1720 SET_CMC_TBL_DATA_DCM(skb->data, 0); 1721 1722 rtw89_h2c_pkt_set_hdr(rtwdev, skb, FWCMD_TYPE_H2C, 1723 H2C_CAT_MAC, H2C_CL_MAC_FR_EXCHG, 1724 chip->h2c_cctl_func_id, 0, 1, 1725 H2C_CMC_TBL_LEN); 1726 1727 ret = rtw89_h2c_tx(rtwdev, skb, false); 1728 if (ret) { 1729 rtw89_err(rtwdev, "failed to send h2c\n"); 1730 goto fail; 1731 } 1732 1733 return 0; 1734 fail: 1735 dev_kfree_skb_any(skb); 1736 1737 return ret; 1738 } 1739 1740 static void __get_sta_he_pkt_padding(struct rtw89_dev *rtwdev, 1741 struct ieee80211_sta *sta, u8 *pads) 1742 { 1743 bool ppe_th; 1744 u8 ppe16, ppe8; 1745 u8 nss = min(sta->deflink.rx_nss, rtwdev->hal.tx_nss) - 1; 1746 u8 ppe_thres_hdr = sta->deflink.he_cap.ppe_thres[0]; 1747 u8 ru_bitmap; 1748 u8 n, idx, sh; 1749 u16 ppe; 1750 int i; 1751 1752 if (!sta->deflink.he_cap.has_he) 1753 return; 1754 1755 ppe_th = FIELD_GET(IEEE80211_HE_PHY_CAP6_PPE_THRESHOLD_PRESENT, 1756 sta->deflink.he_cap.he_cap_elem.phy_cap_info[6]); 1757 if (!ppe_th) { 1758 u8 pad; 1759 1760 pad = FIELD_GET(IEEE80211_HE_PHY_CAP9_NOMINAL_PKT_PADDING_MASK, 1761 sta->deflink.he_cap.he_cap_elem.phy_cap_info[9]); 1762 1763 for (i = 0; i < RTW89_PPE_BW_NUM; i++) 1764 pads[i] = pad; 1765 1766 return; 1767 } 1768 1769 ru_bitmap = FIELD_GET(IEEE80211_PPE_THRES_RU_INDEX_BITMASK_MASK, ppe_thres_hdr); 1770 n = hweight8(ru_bitmap); 1771 n = 7 + (n * IEEE80211_PPE_THRES_INFO_PPET_SIZE * 2) * nss; 1772 1773 for (i = 0; i < RTW89_PPE_BW_NUM; i++) { 1774 if (!(ru_bitmap & BIT(i))) { 1775 pads[i] = 1; 1776 continue; 1777 } 1778 1779 idx = n >> 3; 1780 sh = n & 7; 1781 n += IEEE80211_PPE_THRES_INFO_PPET_SIZE * 2; 1782 1783 ppe = le16_to_cpu(*((__le16 *)&sta->deflink.he_cap.ppe_thres[idx])); 1784 ppe16 = (ppe >> sh) & IEEE80211_PPE_THRES_NSS_MASK; 1785 sh += IEEE80211_PPE_THRES_INFO_PPET_SIZE; 1786 ppe8 = (ppe >> sh) & IEEE80211_PPE_THRES_NSS_MASK; 1787 1788 if (ppe16 != 7 && ppe8 == 7) 1789 pads[i] = 2; 1790 else if (ppe8 != 7) 1791 pads[i] = 1; 1792 else 1793 pads[i] = 0; 1794 } 1795 } 1796 1797 int rtw89_fw_h2c_assoc_cmac_tbl(struct rtw89_dev *rtwdev, 1798 struct ieee80211_vif *vif, 1799 struct ieee80211_sta *sta) 1800 { 1801 const struct rtw89_chip_info *chip = rtwdev->chip; 1802 struct rtw89_sta *rtwsta = sta_to_rtwsta_safe(sta); 1803 struct rtw89_vif *rtwvif = (struct rtw89_vif *)vif->drv_priv; 1804 const struct rtw89_chan *chan = rtw89_chan_get(rtwdev, RTW89_SUB_ENTITY_0); 1805 struct sk_buff *skb; 1806 u8 pads[RTW89_PPE_BW_NUM]; 1807 u8 mac_id = rtwsta ? rtwsta->mac_id : rtwvif->mac_id; 1808 u16 lowest_rate; 1809 int ret; 1810 1811 memset(pads, 0, sizeof(pads)); 1812 if (sta) 1813 __get_sta_he_pkt_padding(rtwdev, sta, pads); 1814 1815 if (vif->p2p) 1816 lowest_rate = RTW89_HW_RATE_OFDM6; 1817 else if (chan->band_type == RTW89_BAND_2G) 1818 lowest_rate = RTW89_HW_RATE_CCK1; 1819 else 1820 lowest_rate = RTW89_HW_RATE_OFDM6; 1821 1822 skb = rtw89_fw_h2c_alloc_skb_with_hdr(rtwdev, H2C_CMC_TBL_LEN); 1823 if (!skb) { 1824 rtw89_err(rtwdev, "failed to alloc skb for fw dl\n"); 1825 return -ENOMEM; 1826 } 1827 skb_put(skb, H2C_CMC_TBL_LEN); 1828 SET_CTRL_INFO_MACID(skb->data, mac_id); 1829 SET_CTRL_INFO_OPERATION(skb->data, 1); 1830 SET_CMC_TBL_DISRTSFB(skb->data, 1); 1831 SET_CMC_TBL_DISDATAFB(skb->data, 1); 1832 SET_CMC_TBL_RTS_RTY_LOWEST_RATE(skb->data, lowest_rate); 1833 SET_CMC_TBL_RTS_TXCNT_LMT_SEL(skb->data, 0); 1834 SET_CMC_TBL_DATA_TXCNT_LMT_SEL(skb->data, 0); 1835 if (vif->type == NL80211_IFTYPE_STATION) 1836 SET_CMC_TBL_ULDL(skb->data, 1); 1837 else 1838 SET_CMC_TBL_ULDL(skb->data, 0); 1839 SET_CMC_TBL_MULTI_PORT_ID(skb->data, rtwvif->port); 1840 if (chip->h2c_cctl_func_id == H2C_FUNC_MAC_CCTLINFO_UD_V1) { 1841 SET_CMC_TBL_NOMINAL_PKT_PADDING_V1(skb->data, pads[RTW89_CHANNEL_WIDTH_20]); 1842 SET_CMC_TBL_NOMINAL_PKT_PADDING40_V1(skb->data, pads[RTW89_CHANNEL_WIDTH_40]); 1843 SET_CMC_TBL_NOMINAL_PKT_PADDING80_V1(skb->data, pads[RTW89_CHANNEL_WIDTH_80]); 1844 SET_CMC_TBL_NOMINAL_PKT_PADDING160_V1(skb->data, pads[RTW89_CHANNEL_WIDTH_160]); 1845 } else if (chip->h2c_cctl_func_id == H2C_FUNC_MAC_CCTLINFO_UD) { 1846 SET_CMC_TBL_NOMINAL_PKT_PADDING(skb->data, pads[RTW89_CHANNEL_WIDTH_20]); 1847 SET_CMC_TBL_NOMINAL_PKT_PADDING40(skb->data, pads[RTW89_CHANNEL_WIDTH_40]); 1848 SET_CMC_TBL_NOMINAL_PKT_PADDING80(skb->data, pads[RTW89_CHANNEL_WIDTH_80]); 1849 SET_CMC_TBL_NOMINAL_PKT_PADDING160(skb->data, pads[RTW89_CHANNEL_WIDTH_160]); 1850 } 1851 if (sta) 1852 SET_CMC_TBL_BSR_QUEUE_SIZE_FORMAT(skb->data, 1853 sta->deflink.he_cap.has_he); 1854 if (rtwvif->net_type == RTW89_NET_TYPE_AP_MODE) 1855 SET_CMC_TBL_DATA_DCM(skb->data, 0); 1856 1857 rtw89_h2c_pkt_set_hdr(rtwdev, skb, FWCMD_TYPE_H2C, 1858 H2C_CAT_MAC, H2C_CL_MAC_FR_EXCHG, 1859 chip->h2c_cctl_func_id, 0, 1, 1860 H2C_CMC_TBL_LEN); 1861 1862 ret = rtw89_h2c_tx(rtwdev, skb, false); 1863 if (ret) { 1864 rtw89_err(rtwdev, "failed to send h2c\n"); 1865 goto fail; 1866 } 1867 1868 return 0; 1869 fail: 1870 dev_kfree_skb_any(skb); 1871 1872 return ret; 1873 } 1874 1875 int rtw89_fw_h2c_txtime_cmac_tbl(struct rtw89_dev *rtwdev, 1876 struct rtw89_sta *rtwsta) 1877 { 1878 const struct rtw89_chip_info *chip = rtwdev->chip; 1879 struct sk_buff *skb; 1880 int ret; 1881 1882 skb = rtw89_fw_h2c_alloc_skb_with_hdr(rtwdev, H2C_CMC_TBL_LEN); 1883 if (!skb) { 1884 rtw89_err(rtwdev, "failed to alloc skb for fw dl\n"); 1885 return -ENOMEM; 1886 } 1887 skb_put(skb, H2C_CMC_TBL_LEN); 1888 SET_CTRL_INFO_MACID(skb->data, rtwsta->mac_id); 1889 SET_CTRL_INFO_OPERATION(skb->data, 1); 1890 if (rtwsta->cctl_tx_time) { 1891 SET_CMC_TBL_AMPDU_TIME_SEL(skb->data, 1); 1892 SET_CMC_TBL_AMPDU_MAX_TIME(skb->data, rtwsta->ampdu_max_time); 1893 } 1894 if (rtwsta->cctl_tx_retry_limit) { 1895 SET_CMC_TBL_DATA_TXCNT_LMT_SEL(skb->data, 1); 1896 SET_CMC_TBL_DATA_TX_CNT_LMT(skb->data, rtwsta->data_tx_cnt_lmt); 1897 } 1898 1899 rtw89_h2c_pkt_set_hdr(rtwdev, skb, FWCMD_TYPE_H2C, 1900 H2C_CAT_MAC, H2C_CL_MAC_FR_EXCHG, 1901 chip->h2c_cctl_func_id, 0, 1, 1902 H2C_CMC_TBL_LEN); 1903 1904 ret = rtw89_h2c_tx(rtwdev, skb, false); 1905 if (ret) { 1906 rtw89_err(rtwdev, "failed to send h2c\n"); 1907 goto fail; 1908 } 1909 1910 return 0; 1911 fail: 1912 dev_kfree_skb_any(skb); 1913 1914 return ret; 1915 } 1916 1917 int rtw89_fw_h2c_txpath_cmac_tbl(struct rtw89_dev *rtwdev, 1918 struct rtw89_sta *rtwsta) 1919 { 1920 const struct rtw89_chip_info *chip = rtwdev->chip; 1921 struct sk_buff *skb; 1922 int ret; 1923 1924 if (chip->h2c_cctl_func_id != H2C_FUNC_MAC_CCTLINFO_UD) 1925 return 0; 1926 1927 skb = rtw89_fw_h2c_alloc_skb_with_hdr(rtwdev, H2C_CMC_TBL_LEN); 1928 if (!skb) { 1929 rtw89_err(rtwdev, "failed to alloc skb for fw dl\n"); 1930 return -ENOMEM; 1931 } 1932 skb_put(skb, H2C_CMC_TBL_LEN); 1933 SET_CTRL_INFO_MACID(skb->data, rtwsta->mac_id); 1934 SET_CTRL_INFO_OPERATION(skb->data, 1); 1935 1936 __rtw89_fw_h2c_set_tx_path(rtwdev, skb); 1937 1938 rtw89_h2c_pkt_set_hdr(rtwdev, skb, FWCMD_TYPE_H2C, 1939 H2C_CAT_MAC, H2C_CL_MAC_FR_EXCHG, 1940 H2C_FUNC_MAC_CCTLINFO_UD, 0, 1, 1941 H2C_CMC_TBL_LEN); 1942 1943 ret = rtw89_h2c_tx(rtwdev, skb, false); 1944 if (ret) { 1945 rtw89_err(rtwdev, "failed to send h2c\n"); 1946 goto fail; 1947 } 1948 1949 return 0; 1950 fail: 1951 dev_kfree_skb_any(skb); 1952 1953 return ret; 1954 } 1955 1956 #define H2C_BCN_BASE_LEN 12 1957 int rtw89_fw_h2c_update_beacon(struct rtw89_dev *rtwdev, 1958 struct rtw89_vif *rtwvif) 1959 { 1960 struct ieee80211_vif *vif = rtwvif_to_vif(rtwvif); 1961 const struct rtw89_chan *chan = rtw89_chan_get(rtwdev, RTW89_SUB_ENTITY_0); 1962 struct sk_buff *skb; 1963 struct sk_buff *skb_beacon; 1964 u16 tim_offset; 1965 int bcn_total_len; 1966 u16 beacon_rate; 1967 int ret; 1968 1969 if (vif->p2p) 1970 beacon_rate = RTW89_HW_RATE_OFDM6; 1971 else if (chan->band_type == RTW89_BAND_2G) 1972 beacon_rate = RTW89_HW_RATE_CCK1; 1973 else 1974 beacon_rate = RTW89_HW_RATE_OFDM6; 1975 1976 skb_beacon = ieee80211_beacon_get_tim(rtwdev->hw, vif, &tim_offset, 1977 NULL, 0); 1978 if (!skb_beacon) { 1979 rtw89_err(rtwdev, "failed to get beacon skb\n"); 1980 return -ENOMEM; 1981 } 1982 1983 bcn_total_len = H2C_BCN_BASE_LEN + skb_beacon->len; 1984 skb = rtw89_fw_h2c_alloc_skb_with_hdr(rtwdev, bcn_total_len); 1985 if (!skb) { 1986 rtw89_err(rtwdev, "failed to alloc skb for fw dl\n"); 1987 dev_kfree_skb_any(skb_beacon); 1988 return -ENOMEM; 1989 } 1990 skb_put(skb, H2C_BCN_BASE_LEN); 1991 1992 SET_BCN_UPD_PORT(skb->data, rtwvif->port); 1993 SET_BCN_UPD_MBSSID(skb->data, 0); 1994 SET_BCN_UPD_BAND(skb->data, rtwvif->mac_idx); 1995 SET_BCN_UPD_GRP_IE_OFST(skb->data, tim_offset); 1996 SET_BCN_UPD_MACID(skb->data, rtwvif->mac_id); 1997 SET_BCN_UPD_SSN_SEL(skb->data, RTW89_MGMT_HW_SSN_SEL); 1998 SET_BCN_UPD_SSN_MODE(skb->data, RTW89_MGMT_HW_SEQ_MODE); 1999 SET_BCN_UPD_RATE(skb->data, beacon_rate); 2000 2001 skb_put_data(skb, skb_beacon->data, skb_beacon->len); 2002 dev_kfree_skb_any(skb_beacon); 2003 2004 rtw89_h2c_pkt_set_hdr(rtwdev, skb, FWCMD_TYPE_H2C, 2005 H2C_CAT_MAC, H2C_CL_MAC_FR_EXCHG, 2006 H2C_FUNC_MAC_BCN_UPD, 0, 1, 2007 bcn_total_len); 2008 2009 ret = rtw89_h2c_tx(rtwdev, skb, false); 2010 if (ret) { 2011 rtw89_err(rtwdev, "failed to send h2c\n"); 2012 dev_kfree_skb_any(skb); 2013 return ret; 2014 } 2015 2016 return 0; 2017 } 2018 2019 #define H2C_ROLE_MAINTAIN_LEN 4 2020 int rtw89_fw_h2c_role_maintain(struct rtw89_dev *rtwdev, 2021 struct rtw89_vif *rtwvif, 2022 struct rtw89_sta *rtwsta, 2023 enum rtw89_upd_mode upd_mode) 2024 { 2025 struct sk_buff *skb; 2026 u8 mac_id = rtwsta ? rtwsta->mac_id : rtwvif->mac_id; 2027 u8 self_role; 2028 int ret; 2029 2030 if (rtwvif->net_type == RTW89_NET_TYPE_AP_MODE) { 2031 if (rtwsta) 2032 self_role = RTW89_SELF_ROLE_AP_CLIENT; 2033 else 2034 self_role = rtwvif->self_role; 2035 } else { 2036 self_role = rtwvif->self_role; 2037 } 2038 2039 skb = rtw89_fw_h2c_alloc_skb_with_hdr(rtwdev, H2C_ROLE_MAINTAIN_LEN); 2040 if (!skb) { 2041 rtw89_err(rtwdev, "failed to alloc skb for h2c join\n"); 2042 return -ENOMEM; 2043 } 2044 skb_put(skb, H2C_ROLE_MAINTAIN_LEN); 2045 SET_FWROLE_MAINTAIN_MACID(skb->data, mac_id); 2046 SET_FWROLE_MAINTAIN_SELF_ROLE(skb->data, self_role); 2047 SET_FWROLE_MAINTAIN_UPD_MODE(skb->data, upd_mode); 2048 SET_FWROLE_MAINTAIN_WIFI_ROLE(skb->data, rtwvif->wifi_role); 2049 2050 rtw89_h2c_pkt_set_hdr(rtwdev, skb, FWCMD_TYPE_H2C, 2051 H2C_CAT_MAC, H2C_CL_MAC_MEDIA_RPT, 2052 H2C_FUNC_MAC_FWROLE_MAINTAIN, 0, 1, 2053 H2C_ROLE_MAINTAIN_LEN); 2054 2055 ret = rtw89_h2c_tx(rtwdev, skb, false); 2056 if (ret) { 2057 rtw89_err(rtwdev, "failed to send h2c\n"); 2058 goto fail; 2059 } 2060 2061 return 0; 2062 fail: 2063 dev_kfree_skb_any(skb); 2064 2065 return ret; 2066 } 2067 2068 #define H2C_JOIN_INFO_LEN 4 2069 int rtw89_fw_h2c_join_info(struct rtw89_dev *rtwdev, struct rtw89_vif *rtwvif, 2070 struct rtw89_sta *rtwsta, bool dis_conn) 2071 { 2072 struct sk_buff *skb; 2073 u8 mac_id = rtwsta ? rtwsta->mac_id : rtwvif->mac_id; 2074 u8 self_role = rtwvif->self_role; 2075 u8 net_type = rtwvif->net_type; 2076 int ret; 2077 2078 if (net_type == RTW89_NET_TYPE_AP_MODE && rtwsta) { 2079 self_role = RTW89_SELF_ROLE_AP_CLIENT; 2080 net_type = dis_conn ? RTW89_NET_TYPE_NO_LINK : net_type; 2081 } 2082 2083 skb = rtw89_fw_h2c_alloc_skb_with_hdr(rtwdev, H2C_JOIN_INFO_LEN); 2084 if (!skb) { 2085 rtw89_err(rtwdev, "failed to alloc skb for h2c join\n"); 2086 return -ENOMEM; 2087 } 2088 skb_put(skb, H2C_JOIN_INFO_LEN); 2089 SET_JOININFO_MACID(skb->data, mac_id); 2090 SET_JOININFO_OP(skb->data, dis_conn); 2091 SET_JOININFO_BAND(skb->data, rtwvif->mac_idx); 2092 SET_JOININFO_WMM(skb->data, rtwvif->wmm); 2093 SET_JOININFO_TGR(skb->data, rtwvif->trigger); 2094 SET_JOININFO_ISHESTA(skb->data, 0); 2095 SET_JOININFO_DLBW(skb->data, 0); 2096 SET_JOININFO_TF_MAC_PAD(skb->data, 0); 2097 SET_JOININFO_DL_T_PE(skb->data, 0); 2098 SET_JOININFO_PORT_ID(skb->data, rtwvif->port); 2099 SET_JOININFO_NET_TYPE(skb->data, net_type); 2100 SET_JOININFO_WIFI_ROLE(skb->data, rtwvif->wifi_role); 2101 SET_JOININFO_SELF_ROLE(skb->data, self_role); 2102 2103 rtw89_h2c_pkt_set_hdr(rtwdev, skb, FWCMD_TYPE_H2C, 2104 H2C_CAT_MAC, H2C_CL_MAC_MEDIA_RPT, 2105 H2C_FUNC_MAC_JOININFO, 0, 1, 2106 H2C_JOIN_INFO_LEN); 2107 2108 ret = rtw89_h2c_tx(rtwdev, skb, false); 2109 if (ret) { 2110 rtw89_err(rtwdev, "failed to send h2c\n"); 2111 goto fail; 2112 } 2113 2114 return 0; 2115 fail: 2116 dev_kfree_skb_any(skb); 2117 2118 return ret; 2119 } 2120 2121 int rtw89_fw_h2c_macid_pause(struct rtw89_dev *rtwdev, u8 sh, u8 grp, 2122 bool pause) 2123 { 2124 struct rtw89_fw_macid_pause_grp h2c = {{0}}; 2125 u8 len = sizeof(struct rtw89_fw_macid_pause_grp); 2126 struct sk_buff *skb; 2127 int ret; 2128 2129 #if defined(__linux__) 2130 skb = rtw89_fw_h2c_alloc_skb_with_hdr(rtwdev, H2C_JOIN_INFO_LEN); 2131 #elif defined(__FreeBSD__) 2132 skb = rtw89_fw_h2c_alloc_skb_with_hdr(rtwdev, len); 2133 #endif 2134 if (!skb) { 2135 rtw89_err(rtwdev, "failed to alloc skb for h2c join\n"); 2136 return -ENOMEM; 2137 } 2138 h2c.mask_grp[grp] = cpu_to_le32(BIT(sh)); 2139 if (pause) 2140 h2c.pause_grp[grp] = cpu_to_le32(BIT(sh)); 2141 skb_put_data(skb, &h2c, len); 2142 2143 rtw89_h2c_pkt_set_hdr(rtwdev, skb, FWCMD_TYPE_H2C, 2144 H2C_CAT_MAC, H2C_CL_MAC_FW_OFLD, 2145 H2C_FUNC_MAC_MACID_PAUSE, 1, 0, 2146 len); 2147 2148 ret = rtw89_h2c_tx(rtwdev, skb, false); 2149 if (ret) { 2150 rtw89_err(rtwdev, "failed to send h2c\n"); 2151 goto fail; 2152 } 2153 2154 return 0; 2155 fail: 2156 dev_kfree_skb_any(skb); 2157 2158 return ret; 2159 } 2160 2161 #define H2C_EDCA_LEN 12 2162 int rtw89_fw_h2c_set_edca(struct rtw89_dev *rtwdev, struct rtw89_vif *rtwvif, 2163 u8 ac, u32 val) 2164 { 2165 struct sk_buff *skb; 2166 int ret; 2167 2168 skb = rtw89_fw_h2c_alloc_skb_with_hdr(rtwdev, H2C_EDCA_LEN); 2169 if (!skb) { 2170 rtw89_err(rtwdev, "failed to alloc skb for h2c edca\n"); 2171 return -ENOMEM; 2172 } 2173 skb_put(skb, H2C_EDCA_LEN); 2174 RTW89_SET_EDCA_SEL(skb->data, 0); 2175 RTW89_SET_EDCA_BAND(skb->data, rtwvif->mac_idx); 2176 RTW89_SET_EDCA_WMM(skb->data, 0); 2177 RTW89_SET_EDCA_AC(skb->data, ac); 2178 RTW89_SET_EDCA_PARAM(skb->data, val); 2179 2180 rtw89_h2c_pkt_set_hdr(rtwdev, skb, FWCMD_TYPE_H2C, 2181 H2C_CAT_MAC, H2C_CL_MAC_FW_OFLD, 2182 H2C_FUNC_USR_EDCA, 0, 1, 2183 H2C_EDCA_LEN); 2184 2185 ret = rtw89_h2c_tx(rtwdev, skb, false); 2186 if (ret) { 2187 rtw89_err(rtwdev, "failed to send h2c\n"); 2188 goto fail; 2189 } 2190 2191 return 0; 2192 fail: 2193 dev_kfree_skb_any(skb); 2194 2195 return ret; 2196 } 2197 2198 #define H2C_TSF32_TOGL_LEN 4 2199 int rtw89_fw_h2c_tsf32_toggle(struct rtw89_dev *rtwdev, struct rtw89_vif *rtwvif, 2200 bool en) 2201 { 2202 struct sk_buff *skb; 2203 u16 early_us = en ? 2000 : 0; 2204 u8 *cmd; 2205 int ret; 2206 2207 skb = rtw89_fw_h2c_alloc_skb_with_hdr(rtwdev, H2C_TSF32_TOGL_LEN); 2208 if (!skb) { 2209 rtw89_err(rtwdev, "failed to alloc skb for h2c p2p act\n"); 2210 return -ENOMEM; 2211 } 2212 skb_put(skb, H2C_TSF32_TOGL_LEN); 2213 cmd = skb->data; 2214 2215 RTW89_SET_FWCMD_TSF32_TOGL_BAND(cmd, rtwvif->mac_idx); 2216 RTW89_SET_FWCMD_TSF32_TOGL_EN(cmd, en); 2217 RTW89_SET_FWCMD_TSF32_TOGL_PORT(cmd, rtwvif->port); 2218 RTW89_SET_FWCMD_TSF32_TOGL_EARLY(cmd, early_us); 2219 2220 rtw89_h2c_pkt_set_hdr(rtwdev, skb, FWCMD_TYPE_H2C, 2221 H2C_CAT_MAC, H2C_CL_MAC_FW_OFLD, 2222 H2C_FUNC_TSF32_TOGL, 0, 0, 2223 H2C_TSF32_TOGL_LEN); 2224 2225 ret = rtw89_h2c_tx(rtwdev, skb, false); 2226 if (ret) { 2227 rtw89_err(rtwdev, "failed to send h2c\n"); 2228 goto fail; 2229 } 2230 2231 return 0; 2232 fail: 2233 dev_kfree_skb_any(skb); 2234 2235 return ret; 2236 } 2237 2238 #define H2C_OFLD_CFG_LEN 8 2239 int rtw89_fw_h2c_set_ofld_cfg(struct rtw89_dev *rtwdev) 2240 { 2241 static const u8 cfg[] = {0x09, 0x00, 0x00, 0x00, 0x5e, 0x00, 0x00, 0x00}; 2242 struct sk_buff *skb; 2243 int ret; 2244 2245 skb = rtw89_fw_h2c_alloc_skb_with_hdr(rtwdev, H2C_OFLD_CFG_LEN); 2246 if (!skb) { 2247 rtw89_err(rtwdev, "failed to alloc skb for h2c ofld\n"); 2248 return -ENOMEM; 2249 } 2250 skb_put_data(skb, cfg, H2C_OFLD_CFG_LEN); 2251 2252 rtw89_h2c_pkt_set_hdr(rtwdev, skb, FWCMD_TYPE_H2C, 2253 H2C_CAT_MAC, H2C_CL_MAC_FW_OFLD, 2254 H2C_FUNC_OFLD_CFG, 0, 1, 2255 H2C_OFLD_CFG_LEN); 2256 2257 ret = rtw89_h2c_tx(rtwdev, skb, false); 2258 if (ret) { 2259 rtw89_err(rtwdev, "failed to send h2c\n"); 2260 goto fail; 2261 } 2262 2263 return 0; 2264 fail: 2265 dev_kfree_skb_any(skb); 2266 2267 return ret; 2268 } 2269 2270 int rtw89_fw_h2c_set_bcn_fltr_cfg(struct rtw89_dev *rtwdev, 2271 struct ieee80211_vif *vif, 2272 bool connect) 2273 { 2274 struct rtw89_vif *rtwvif = vif_to_rtwvif_safe(vif); 2275 struct ieee80211_bss_conf *bss_conf = vif ? &vif->bss_conf : NULL; 2276 struct rtw89_h2c_bcnfltr *h2c; 2277 u32 len = sizeof(*h2c); 2278 struct sk_buff *skb; 2279 int ret; 2280 2281 if (!RTW89_CHK_FW_FEATURE(BEACON_FILTER, &rtwdev->fw)) 2282 return -EINVAL; 2283 2284 if (!rtwvif || !bss_conf || rtwvif->net_type != RTW89_NET_TYPE_INFRA) 2285 return -EINVAL; 2286 2287 skb = rtw89_fw_h2c_alloc_skb_with_hdr(rtwdev, len); 2288 if (!skb) { 2289 rtw89_err(rtwdev, "failed to alloc skb for h2c bcn filter\n"); 2290 return -ENOMEM; 2291 } 2292 2293 skb_put(skb, len); 2294 h2c = (struct rtw89_h2c_bcnfltr *)skb->data; 2295 2296 h2c->w0 = le32_encode_bits(connect, RTW89_H2C_BCNFLTR_W0_MON_RSSI) | 2297 le32_encode_bits(connect, RTW89_H2C_BCNFLTR_W0_MON_BCN) | 2298 le32_encode_bits(connect, RTW89_H2C_BCNFLTR_W0_MON_EN) | 2299 le32_encode_bits(RTW89_BCN_FLTR_OFFLOAD_MODE_DEFAULT, 2300 RTW89_H2C_BCNFLTR_W0_MODE) | 2301 le32_encode_bits(RTW89_BCN_LOSS_CNT, RTW89_H2C_BCNFLTR_W0_BCN_LOSS_CNT) | 2302 le32_encode_bits(bss_conf->cqm_rssi_hyst, RTW89_H2C_BCNFLTR_W0_RSSI_HYST) | 2303 le32_encode_bits(bss_conf->cqm_rssi_thold + MAX_RSSI, 2304 RTW89_H2C_BCNFLTR_W0_RSSI_THRESHOLD) | 2305 le32_encode_bits(rtwvif->mac_id, RTW89_H2C_BCNFLTR_W0_MAC_ID); 2306 2307 rtw89_h2c_pkt_set_hdr(rtwdev, skb, FWCMD_TYPE_H2C, 2308 H2C_CAT_MAC, H2C_CL_MAC_FW_OFLD, 2309 H2C_FUNC_CFG_BCNFLTR, 0, 1, len); 2310 2311 ret = rtw89_h2c_tx(rtwdev, skb, false); 2312 if (ret) { 2313 rtw89_err(rtwdev, "failed to send h2c\n"); 2314 goto fail; 2315 } 2316 2317 return 0; 2318 fail: 2319 dev_kfree_skb_any(skb); 2320 2321 return ret; 2322 } 2323 2324 int rtw89_fw_h2c_rssi_offload(struct rtw89_dev *rtwdev, 2325 struct rtw89_rx_phy_ppdu *phy_ppdu) 2326 { 2327 struct rtw89_h2c_ofld_rssi *h2c; 2328 u32 len = sizeof(*h2c); 2329 struct sk_buff *skb; 2330 s8 rssi; 2331 int ret; 2332 2333 if (!RTW89_CHK_FW_FEATURE(BEACON_FILTER, &rtwdev->fw)) 2334 return -EINVAL; 2335 2336 if (!phy_ppdu) 2337 return -EINVAL; 2338 2339 skb = rtw89_fw_h2c_alloc_skb_with_hdr(rtwdev, len); 2340 if (!skb) { 2341 rtw89_err(rtwdev, "failed to alloc skb for h2c rssi\n"); 2342 return -ENOMEM; 2343 } 2344 2345 rssi = phy_ppdu->rssi_avg >> RSSI_FACTOR; 2346 skb_put(skb, len); 2347 h2c = (struct rtw89_h2c_ofld_rssi *)skb->data; 2348 2349 h2c->w0 = le32_encode_bits(phy_ppdu->mac_id, RTW89_H2C_OFLD_RSSI_W0_MACID) | 2350 le32_encode_bits(1, RTW89_H2C_OFLD_RSSI_W0_NUM); 2351 h2c->w1 = le32_encode_bits(rssi, RTW89_H2C_OFLD_RSSI_W1_VAL); 2352 2353 rtw89_h2c_pkt_set_hdr(rtwdev, skb, FWCMD_TYPE_H2C, 2354 H2C_CAT_MAC, H2C_CL_MAC_FW_OFLD, 2355 H2C_FUNC_OFLD_RSSI, 0, 1, len); 2356 2357 ret = rtw89_h2c_tx(rtwdev, skb, false); 2358 if (ret) { 2359 rtw89_err(rtwdev, "failed to send h2c\n"); 2360 goto fail; 2361 } 2362 2363 return 0; 2364 fail: 2365 dev_kfree_skb_any(skb); 2366 2367 return ret; 2368 } 2369 2370 int rtw89_fw_h2c_tp_offload(struct rtw89_dev *rtwdev, struct rtw89_vif *rtwvif) 2371 { 2372 struct rtw89_traffic_stats *stats = &rtwvif->stats; 2373 struct rtw89_h2c_ofld *h2c; 2374 u32 len = sizeof(*h2c); 2375 struct sk_buff *skb; 2376 int ret; 2377 2378 if (rtwvif->net_type != RTW89_NET_TYPE_INFRA) 2379 return -EINVAL; 2380 2381 skb = rtw89_fw_h2c_alloc_skb_with_hdr(rtwdev, len); 2382 if (!skb) { 2383 rtw89_err(rtwdev, "failed to alloc skb for h2c tp\n"); 2384 return -ENOMEM; 2385 } 2386 2387 skb_put(skb, len); 2388 h2c = (struct rtw89_h2c_ofld *)skb->data; 2389 2390 h2c->w0 = le32_encode_bits(rtwvif->mac_id, RTW89_H2C_OFLD_W0_MAC_ID) | 2391 le32_encode_bits(stats->tx_throughput, RTW89_H2C_OFLD_W0_TX_TP) | 2392 le32_encode_bits(stats->rx_throughput, RTW89_H2C_OFLD_W0_RX_TP); 2393 2394 rtw89_h2c_pkt_set_hdr(rtwdev, skb, FWCMD_TYPE_H2C, 2395 H2C_CAT_MAC, H2C_CL_MAC_FW_OFLD, 2396 H2C_FUNC_OFLD_TP, 0, 1, len); 2397 2398 ret = rtw89_h2c_tx(rtwdev, skb, false); 2399 if (ret) { 2400 rtw89_err(rtwdev, "failed to send h2c\n"); 2401 goto fail; 2402 } 2403 2404 return 0; 2405 fail: 2406 dev_kfree_skb_any(skb); 2407 2408 return ret; 2409 } 2410 2411 int rtw89_fw_h2c_ra(struct rtw89_dev *rtwdev, struct rtw89_ra_info *ra, bool csi) 2412 { 2413 const struct rtw89_chip_info *chip = rtwdev->chip; 2414 struct rtw89_h2c_ra_v1 *h2c_v1; 2415 struct rtw89_h2c_ra *h2c; 2416 u32 len = sizeof(*h2c); 2417 bool format_v1 = false; 2418 struct sk_buff *skb; 2419 int ret; 2420 2421 if (chip->chip_gen == RTW89_CHIP_BE) { 2422 len = sizeof(*h2c_v1); 2423 format_v1 = true; 2424 } 2425 2426 skb = rtw89_fw_h2c_alloc_skb_with_hdr(rtwdev, len); 2427 if (!skb) { 2428 rtw89_err(rtwdev, "failed to alloc skb for h2c join\n"); 2429 return -ENOMEM; 2430 } 2431 skb_put(skb, len); 2432 h2c = (struct rtw89_h2c_ra *)skb->data; 2433 rtw89_debug(rtwdev, RTW89_DBG_RA, 2434 #if defined(__linux__) 2435 "ra cmd msk: %llx ", ra->ra_mask); 2436 #elif defined(__FreeBSD__) 2437 "ra cmd msk: %jx ", (uintmax_t)ra->ra_mask); 2438 #endif 2439 2440 h2c->w0 = le32_encode_bits(ra->mode_ctrl, RTW89_H2C_RA_W0_MODE) | 2441 le32_encode_bits(ra->bw_cap, RTW89_H2C_RA_W0_BW_CAP) | 2442 le32_encode_bits(ra->macid, RTW89_H2C_RA_W0_MACID) | 2443 le32_encode_bits(ra->dcm_cap, RTW89_H2C_RA_W0_DCM) | 2444 le32_encode_bits(ra->er_cap, RTW89_H2C_RA_W0_ER) | 2445 le32_encode_bits(ra->init_rate_lv, RTW89_H2C_RA_W0_INIT_RATE_LV) | 2446 le32_encode_bits(ra->upd_all, RTW89_H2C_RA_W0_UPD_ALL) | 2447 le32_encode_bits(ra->en_sgi, RTW89_H2C_RA_W0_SGI) | 2448 le32_encode_bits(ra->ldpc_cap, RTW89_H2C_RA_W0_LDPC) | 2449 le32_encode_bits(ra->stbc_cap, RTW89_H2C_RA_W0_STBC) | 2450 le32_encode_bits(ra->ss_num, RTW89_H2C_RA_W0_SS_NUM) | 2451 le32_encode_bits(ra->giltf, RTW89_H2C_RA_W0_GILTF) | 2452 le32_encode_bits(ra->upd_bw_nss_mask, RTW89_H2C_RA_W0_UPD_BW_NSS_MASK) | 2453 le32_encode_bits(ra->upd_mask, RTW89_H2C_RA_W0_UPD_MASK); 2454 h2c->w1 = le32_encode_bits(ra->ra_mask, RTW89_H2C_RA_W1_RAMASK_LO32); 2455 h2c->w2 = le32_encode_bits(ra->ra_mask >> 32, RTW89_H2C_RA_W2_RAMASK_HI32); 2456 h2c->w3 = le32_encode_bits(ra->fix_giltf_en, RTW89_H2C_RA_W3_FIX_GILTF_EN) | 2457 le32_encode_bits(ra->fix_giltf, RTW89_H2C_RA_W3_FIX_GILTF); 2458 2459 if (!format_v1) 2460 goto csi; 2461 2462 h2c_v1 = (struct rtw89_h2c_ra_v1 *)h2c; 2463 h2c_v1->w4 = le32_encode_bits(ra->mode_ctrl, RTW89_H2C_RA_V1_W4_MODE_EHT) | 2464 le32_encode_bits(ra->bw_cap, RTW89_H2C_RA_V1_W4_BW_EHT); 2465 2466 csi: 2467 if (!csi) 2468 goto done; 2469 2470 h2c->w2 |= le32_encode_bits(1, RTW89_H2C_RA_W2_BFEE_CSI_CTL); 2471 h2c->w3 |= le32_encode_bits(ra->band_num, RTW89_H2C_RA_W3_BAND_NUM) | 2472 le32_encode_bits(ra->cr_tbl_sel, RTW89_H2C_RA_W3_CR_TBL_SEL) | 2473 le32_encode_bits(ra->fixed_csi_rate_en, RTW89_H2C_RA_W3_FIXED_CSI_RATE_EN) | 2474 le32_encode_bits(ra->ra_csi_rate_en, RTW89_H2C_RA_W3_RA_CSI_RATE_EN) | 2475 le32_encode_bits(ra->csi_mcs_ss_idx, RTW89_H2C_RA_W3_FIXED_CSI_MCS_SS_IDX) | 2476 le32_encode_bits(ra->csi_mode, RTW89_H2C_RA_W3_FIXED_CSI_MODE) | 2477 le32_encode_bits(ra->csi_gi_ltf, RTW89_H2C_RA_W3_FIXED_CSI_GI_LTF) | 2478 le32_encode_bits(ra->csi_bw, RTW89_H2C_RA_W3_FIXED_CSI_BW); 2479 2480 done: 2481 rtw89_h2c_pkt_set_hdr(rtwdev, skb, FWCMD_TYPE_H2C, 2482 H2C_CAT_OUTSRC, H2C_CL_OUTSRC_RA, 2483 H2C_FUNC_OUTSRC_RA_MACIDCFG, 0, 0, 2484 len); 2485 2486 ret = rtw89_h2c_tx(rtwdev, skb, false); 2487 if (ret) { 2488 rtw89_err(rtwdev, "failed to send h2c\n"); 2489 goto fail; 2490 } 2491 2492 return 0; 2493 fail: 2494 dev_kfree_skb_any(skb); 2495 2496 return ret; 2497 } 2498 2499 int rtw89_fw_h2c_cxdrv_init(struct rtw89_dev *rtwdev) 2500 { 2501 struct rtw89_btc *btc = &rtwdev->btc; 2502 struct rtw89_btc_dm *dm = &btc->dm; 2503 struct rtw89_btc_init_info *init_info = &dm->init_info; 2504 struct rtw89_btc_module *module = &init_info->module; 2505 struct rtw89_btc_ant_info *ant = &module->ant; 2506 struct rtw89_h2c_cxinit *h2c; 2507 u32 len = sizeof(*h2c); 2508 struct sk_buff *skb; 2509 int ret; 2510 2511 skb = rtw89_fw_h2c_alloc_skb_with_hdr(rtwdev, len); 2512 if (!skb) { 2513 rtw89_err(rtwdev, "failed to alloc skb for h2c cxdrv_init\n"); 2514 return -ENOMEM; 2515 } 2516 skb_put(skb, len); 2517 h2c = (struct rtw89_h2c_cxinit *)skb->data; 2518 2519 h2c->hdr.type = CXDRVINFO_INIT; 2520 h2c->hdr.len = len - H2C_LEN_CXDRVHDR; 2521 2522 h2c->ant_type = ant->type; 2523 h2c->ant_num = ant->num; 2524 h2c->ant_iso = ant->isolation; 2525 h2c->ant_info = 2526 u8_encode_bits(ant->single_pos, RTW89_H2C_CXINIT_ANT_INFO_POS) | 2527 u8_encode_bits(ant->diversity, RTW89_H2C_CXINIT_ANT_INFO_DIVERSITY) | 2528 u8_encode_bits(ant->btg_pos, RTW89_H2C_CXINIT_ANT_INFO_BTG_POS) | 2529 u8_encode_bits(ant->stream_cnt, RTW89_H2C_CXINIT_ANT_INFO_STREAM_CNT); 2530 2531 h2c->mod_rfe = module->rfe_type; 2532 h2c->mod_cv = module->cv; 2533 h2c->mod_info = 2534 u8_encode_bits(module->bt_solo, RTW89_H2C_CXINIT_MOD_INFO_BT_SOLO) | 2535 u8_encode_bits(module->bt_pos, RTW89_H2C_CXINIT_MOD_INFO_BT_POS) | 2536 u8_encode_bits(module->switch_type, RTW89_H2C_CXINIT_MOD_INFO_SW_TYPE) | 2537 u8_encode_bits(module->wa_type, RTW89_H2C_CXINIT_MOD_INFO_WA_TYPE); 2538 h2c->mod_adie_kt = module->kt_ver_adie; 2539 h2c->wl_gch = init_info->wl_guard_ch; 2540 2541 h2c->info = 2542 u8_encode_bits(init_info->wl_only, RTW89_H2C_CXINIT_INFO_WL_ONLY) | 2543 u8_encode_bits(init_info->wl_init_ok, RTW89_H2C_CXINIT_INFO_WL_INITOK) | 2544 u8_encode_bits(init_info->dbcc_en, RTW89_H2C_CXINIT_INFO_DBCC_EN) | 2545 u8_encode_bits(init_info->cx_other, RTW89_H2C_CXINIT_INFO_CX_OTHER) | 2546 u8_encode_bits(init_info->bt_only, RTW89_H2C_CXINIT_INFO_BT_ONLY); 2547 2548 rtw89_h2c_pkt_set_hdr(rtwdev, skb, FWCMD_TYPE_H2C, 2549 H2C_CAT_OUTSRC, BTFC_SET, 2550 SET_DRV_INFO, 0, 0, 2551 len); 2552 2553 ret = rtw89_h2c_tx(rtwdev, skb, false); 2554 if (ret) { 2555 rtw89_err(rtwdev, "failed to send h2c\n"); 2556 goto fail; 2557 } 2558 2559 return 0; 2560 fail: 2561 dev_kfree_skb_any(skb); 2562 2563 return ret; 2564 } 2565 2566 #define PORT_DATA_OFFSET 4 2567 #define H2C_LEN_CXDRVINFO_ROLE_DBCC_LEN 12 2568 #define H2C_LEN_CXDRVINFO_ROLE_SIZE(max_role_num) \ 2569 (4 + 12 * (max_role_num) + H2C_LEN_CXDRVHDR) 2570 2571 int rtw89_fw_h2c_cxdrv_role(struct rtw89_dev *rtwdev) 2572 { 2573 struct rtw89_btc *btc = &rtwdev->btc; 2574 const struct rtw89_btc_ver *ver = btc->ver; 2575 struct rtw89_btc_wl_info *wl = &btc->cx.wl; 2576 struct rtw89_btc_wl_role_info *role_info = &wl->role_info; 2577 struct rtw89_btc_wl_role_info_bpos *bpos = &role_info->role_map.role; 2578 struct rtw89_btc_wl_active_role *active = role_info->active_role; 2579 struct sk_buff *skb; 2580 u32 len; 2581 u8 offset = 0; 2582 u8 *cmd; 2583 int ret; 2584 int i; 2585 2586 len = H2C_LEN_CXDRVINFO_ROLE_SIZE(ver->max_role_num); 2587 2588 skb = rtw89_fw_h2c_alloc_skb_with_hdr(rtwdev, len); 2589 if (!skb) { 2590 rtw89_err(rtwdev, "failed to alloc skb for h2c cxdrv_role\n"); 2591 return -ENOMEM; 2592 } 2593 skb_put(skb, len); 2594 cmd = skb->data; 2595 2596 RTW89_SET_FWCMD_CXHDR_TYPE(cmd, CXDRVINFO_ROLE); 2597 RTW89_SET_FWCMD_CXHDR_LEN(cmd, len - H2C_LEN_CXDRVHDR); 2598 2599 RTW89_SET_FWCMD_CXROLE_CONNECT_CNT(cmd, role_info->connect_cnt); 2600 RTW89_SET_FWCMD_CXROLE_LINK_MODE(cmd, role_info->link_mode); 2601 2602 RTW89_SET_FWCMD_CXROLE_ROLE_NONE(cmd, bpos->none); 2603 RTW89_SET_FWCMD_CXROLE_ROLE_STA(cmd, bpos->station); 2604 RTW89_SET_FWCMD_CXROLE_ROLE_AP(cmd, bpos->ap); 2605 RTW89_SET_FWCMD_CXROLE_ROLE_VAP(cmd, bpos->vap); 2606 RTW89_SET_FWCMD_CXROLE_ROLE_ADHOC(cmd, bpos->adhoc); 2607 RTW89_SET_FWCMD_CXROLE_ROLE_ADHOC_MASTER(cmd, bpos->adhoc_master); 2608 RTW89_SET_FWCMD_CXROLE_ROLE_MESH(cmd, bpos->mesh); 2609 RTW89_SET_FWCMD_CXROLE_ROLE_MONITOR(cmd, bpos->moniter); 2610 RTW89_SET_FWCMD_CXROLE_ROLE_P2P_DEV(cmd, bpos->p2p_device); 2611 RTW89_SET_FWCMD_CXROLE_ROLE_P2P_GC(cmd, bpos->p2p_gc); 2612 RTW89_SET_FWCMD_CXROLE_ROLE_P2P_GO(cmd, bpos->p2p_go); 2613 RTW89_SET_FWCMD_CXROLE_ROLE_NAN(cmd, bpos->nan); 2614 2615 for (i = 0; i < RTW89_PORT_NUM; i++, active++) { 2616 RTW89_SET_FWCMD_CXROLE_ACT_CONNECTED(cmd, active->connected, i, offset); 2617 RTW89_SET_FWCMD_CXROLE_ACT_PID(cmd, active->pid, i, offset); 2618 RTW89_SET_FWCMD_CXROLE_ACT_PHY(cmd, active->phy, i, offset); 2619 RTW89_SET_FWCMD_CXROLE_ACT_NOA(cmd, active->noa, i, offset); 2620 RTW89_SET_FWCMD_CXROLE_ACT_BAND(cmd, active->band, i, offset); 2621 RTW89_SET_FWCMD_CXROLE_ACT_CLIENT_PS(cmd, active->client_ps, i, offset); 2622 RTW89_SET_FWCMD_CXROLE_ACT_BW(cmd, active->bw, i, offset); 2623 RTW89_SET_FWCMD_CXROLE_ACT_ROLE(cmd, active->role, i, offset); 2624 RTW89_SET_FWCMD_CXROLE_ACT_CH(cmd, active->ch, i, offset); 2625 RTW89_SET_FWCMD_CXROLE_ACT_TX_LVL(cmd, active->tx_lvl, i, offset); 2626 RTW89_SET_FWCMD_CXROLE_ACT_RX_LVL(cmd, active->rx_lvl, i, offset); 2627 RTW89_SET_FWCMD_CXROLE_ACT_TX_RATE(cmd, active->tx_rate, i, offset); 2628 RTW89_SET_FWCMD_CXROLE_ACT_RX_RATE(cmd, active->rx_rate, i, offset); 2629 } 2630 2631 rtw89_h2c_pkt_set_hdr(rtwdev, skb, FWCMD_TYPE_H2C, 2632 H2C_CAT_OUTSRC, BTFC_SET, 2633 SET_DRV_INFO, 0, 0, 2634 len); 2635 2636 ret = rtw89_h2c_tx(rtwdev, skb, false); 2637 if (ret) { 2638 rtw89_err(rtwdev, "failed to send h2c\n"); 2639 goto fail; 2640 } 2641 2642 return 0; 2643 fail: 2644 dev_kfree_skb_any(skb); 2645 2646 return ret; 2647 } 2648 2649 #define H2C_LEN_CXDRVINFO_ROLE_SIZE_V1(max_role_num) \ 2650 (4 + 16 * (max_role_num) + H2C_LEN_CXDRVINFO_ROLE_DBCC_LEN + H2C_LEN_CXDRVHDR) 2651 2652 int rtw89_fw_h2c_cxdrv_role_v1(struct rtw89_dev *rtwdev) 2653 { 2654 struct rtw89_btc *btc = &rtwdev->btc; 2655 const struct rtw89_btc_ver *ver = btc->ver; 2656 struct rtw89_btc_wl_info *wl = &btc->cx.wl; 2657 struct rtw89_btc_wl_role_info_v1 *role_info = &wl->role_info_v1; 2658 struct rtw89_btc_wl_role_info_bpos *bpos = &role_info->role_map.role; 2659 struct rtw89_btc_wl_active_role_v1 *active = role_info->active_role_v1; 2660 struct sk_buff *skb; 2661 u32 len; 2662 u8 *cmd, offset; 2663 int ret; 2664 int i; 2665 2666 len = H2C_LEN_CXDRVINFO_ROLE_SIZE_V1(ver->max_role_num); 2667 2668 skb = rtw89_fw_h2c_alloc_skb_with_hdr(rtwdev, len); 2669 if (!skb) { 2670 rtw89_err(rtwdev, "failed to alloc skb for h2c cxdrv_role\n"); 2671 return -ENOMEM; 2672 } 2673 skb_put(skb, len); 2674 cmd = skb->data; 2675 2676 RTW89_SET_FWCMD_CXHDR_TYPE(cmd, CXDRVINFO_ROLE); 2677 RTW89_SET_FWCMD_CXHDR_LEN(cmd, len - H2C_LEN_CXDRVHDR); 2678 2679 RTW89_SET_FWCMD_CXROLE_CONNECT_CNT(cmd, role_info->connect_cnt); 2680 RTW89_SET_FWCMD_CXROLE_LINK_MODE(cmd, role_info->link_mode); 2681 2682 RTW89_SET_FWCMD_CXROLE_ROLE_NONE(cmd, bpos->none); 2683 RTW89_SET_FWCMD_CXROLE_ROLE_STA(cmd, bpos->station); 2684 RTW89_SET_FWCMD_CXROLE_ROLE_AP(cmd, bpos->ap); 2685 RTW89_SET_FWCMD_CXROLE_ROLE_VAP(cmd, bpos->vap); 2686 RTW89_SET_FWCMD_CXROLE_ROLE_ADHOC(cmd, bpos->adhoc); 2687 RTW89_SET_FWCMD_CXROLE_ROLE_ADHOC_MASTER(cmd, bpos->adhoc_master); 2688 RTW89_SET_FWCMD_CXROLE_ROLE_MESH(cmd, bpos->mesh); 2689 RTW89_SET_FWCMD_CXROLE_ROLE_MONITOR(cmd, bpos->moniter); 2690 RTW89_SET_FWCMD_CXROLE_ROLE_P2P_DEV(cmd, bpos->p2p_device); 2691 RTW89_SET_FWCMD_CXROLE_ROLE_P2P_GC(cmd, bpos->p2p_gc); 2692 RTW89_SET_FWCMD_CXROLE_ROLE_P2P_GO(cmd, bpos->p2p_go); 2693 RTW89_SET_FWCMD_CXROLE_ROLE_NAN(cmd, bpos->nan); 2694 2695 offset = PORT_DATA_OFFSET; 2696 for (i = 0; i < RTW89_PORT_NUM; i++, active++) { 2697 RTW89_SET_FWCMD_CXROLE_ACT_CONNECTED(cmd, active->connected, i, offset); 2698 RTW89_SET_FWCMD_CXROLE_ACT_PID(cmd, active->pid, i, offset); 2699 RTW89_SET_FWCMD_CXROLE_ACT_PHY(cmd, active->phy, i, offset); 2700 RTW89_SET_FWCMD_CXROLE_ACT_NOA(cmd, active->noa, i, offset); 2701 RTW89_SET_FWCMD_CXROLE_ACT_BAND(cmd, active->band, i, offset); 2702 RTW89_SET_FWCMD_CXROLE_ACT_CLIENT_PS(cmd, active->client_ps, i, offset); 2703 RTW89_SET_FWCMD_CXROLE_ACT_BW(cmd, active->bw, i, offset); 2704 RTW89_SET_FWCMD_CXROLE_ACT_ROLE(cmd, active->role, i, offset); 2705 RTW89_SET_FWCMD_CXROLE_ACT_CH(cmd, active->ch, i, offset); 2706 RTW89_SET_FWCMD_CXROLE_ACT_TX_LVL(cmd, active->tx_lvl, i, offset); 2707 RTW89_SET_FWCMD_CXROLE_ACT_RX_LVL(cmd, active->rx_lvl, i, offset); 2708 RTW89_SET_FWCMD_CXROLE_ACT_TX_RATE(cmd, active->tx_rate, i, offset); 2709 RTW89_SET_FWCMD_CXROLE_ACT_RX_RATE(cmd, active->rx_rate, i, offset); 2710 RTW89_SET_FWCMD_CXROLE_ACT_NOA_DUR(cmd, active->noa_duration, i, offset); 2711 } 2712 2713 offset = len - H2C_LEN_CXDRVINFO_ROLE_DBCC_LEN; 2714 RTW89_SET_FWCMD_CXROLE_MROLE_TYPE(cmd, role_info->mrole_type, offset); 2715 RTW89_SET_FWCMD_CXROLE_MROLE_NOA(cmd, role_info->mrole_noa_duration, offset); 2716 RTW89_SET_FWCMD_CXROLE_DBCC_EN(cmd, role_info->dbcc_en, offset); 2717 RTW89_SET_FWCMD_CXROLE_DBCC_CHG(cmd, role_info->dbcc_chg, offset); 2718 RTW89_SET_FWCMD_CXROLE_DBCC_2G_PHY(cmd, role_info->dbcc_2g_phy, offset); 2719 RTW89_SET_FWCMD_CXROLE_LINK_MODE_CHG(cmd, role_info->link_mode_chg, offset); 2720 2721 rtw89_h2c_pkt_set_hdr(rtwdev, skb, FWCMD_TYPE_H2C, 2722 H2C_CAT_OUTSRC, BTFC_SET, 2723 SET_DRV_INFO, 0, 0, 2724 len); 2725 2726 ret = rtw89_h2c_tx(rtwdev, skb, false); 2727 if (ret) { 2728 rtw89_err(rtwdev, "failed to send h2c\n"); 2729 goto fail; 2730 } 2731 2732 return 0; 2733 fail: 2734 dev_kfree_skb_any(skb); 2735 2736 return ret; 2737 } 2738 2739 #define H2C_LEN_CXDRVINFO_ROLE_SIZE_V2(max_role_num) \ 2740 (4 + 8 * (max_role_num) + H2C_LEN_CXDRVINFO_ROLE_DBCC_LEN + H2C_LEN_CXDRVHDR) 2741 2742 int rtw89_fw_h2c_cxdrv_role_v2(struct rtw89_dev *rtwdev) 2743 { 2744 struct rtw89_btc *btc = &rtwdev->btc; 2745 const struct rtw89_btc_ver *ver = btc->ver; 2746 struct rtw89_btc_wl_info *wl = &btc->cx.wl; 2747 struct rtw89_btc_wl_role_info_v2 *role_info = &wl->role_info_v2; 2748 struct rtw89_btc_wl_role_info_bpos *bpos = &role_info->role_map.role; 2749 struct rtw89_btc_wl_active_role_v2 *active = role_info->active_role_v2; 2750 struct sk_buff *skb; 2751 u32 len; 2752 u8 *cmd, offset; 2753 int ret; 2754 int i; 2755 2756 len = H2C_LEN_CXDRVINFO_ROLE_SIZE_V2(ver->max_role_num); 2757 2758 skb = rtw89_fw_h2c_alloc_skb_with_hdr(rtwdev, len); 2759 if (!skb) { 2760 rtw89_err(rtwdev, "failed to alloc skb for h2c cxdrv_role\n"); 2761 return -ENOMEM; 2762 } 2763 skb_put(skb, len); 2764 cmd = skb->data; 2765 2766 RTW89_SET_FWCMD_CXHDR_TYPE(cmd, CXDRVINFO_ROLE); 2767 RTW89_SET_FWCMD_CXHDR_LEN(cmd, len - H2C_LEN_CXDRVHDR); 2768 2769 RTW89_SET_FWCMD_CXROLE_CONNECT_CNT(cmd, role_info->connect_cnt); 2770 RTW89_SET_FWCMD_CXROLE_LINK_MODE(cmd, role_info->link_mode); 2771 2772 RTW89_SET_FWCMD_CXROLE_ROLE_NONE(cmd, bpos->none); 2773 RTW89_SET_FWCMD_CXROLE_ROLE_STA(cmd, bpos->station); 2774 RTW89_SET_FWCMD_CXROLE_ROLE_AP(cmd, bpos->ap); 2775 RTW89_SET_FWCMD_CXROLE_ROLE_VAP(cmd, bpos->vap); 2776 RTW89_SET_FWCMD_CXROLE_ROLE_ADHOC(cmd, bpos->adhoc); 2777 RTW89_SET_FWCMD_CXROLE_ROLE_ADHOC_MASTER(cmd, bpos->adhoc_master); 2778 RTW89_SET_FWCMD_CXROLE_ROLE_MESH(cmd, bpos->mesh); 2779 RTW89_SET_FWCMD_CXROLE_ROLE_MONITOR(cmd, bpos->moniter); 2780 RTW89_SET_FWCMD_CXROLE_ROLE_P2P_DEV(cmd, bpos->p2p_device); 2781 RTW89_SET_FWCMD_CXROLE_ROLE_P2P_GC(cmd, bpos->p2p_gc); 2782 RTW89_SET_FWCMD_CXROLE_ROLE_P2P_GO(cmd, bpos->p2p_go); 2783 RTW89_SET_FWCMD_CXROLE_ROLE_NAN(cmd, bpos->nan); 2784 2785 offset = PORT_DATA_OFFSET; 2786 for (i = 0; i < RTW89_PORT_NUM; i++, active++) { 2787 RTW89_SET_FWCMD_CXROLE_ACT_CONNECTED_V2(cmd, active->connected, i, offset); 2788 RTW89_SET_FWCMD_CXROLE_ACT_PID_V2(cmd, active->pid, i, offset); 2789 RTW89_SET_FWCMD_CXROLE_ACT_PHY_V2(cmd, active->phy, i, offset); 2790 RTW89_SET_FWCMD_CXROLE_ACT_NOA_V2(cmd, active->noa, i, offset); 2791 RTW89_SET_FWCMD_CXROLE_ACT_BAND_V2(cmd, active->band, i, offset); 2792 RTW89_SET_FWCMD_CXROLE_ACT_CLIENT_PS_V2(cmd, active->client_ps, i, offset); 2793 RTW89_SET_FWCMD_CXROLE_ACT_BW_V2(cmd, active->bw, i, offset); 2794 RTW89_SET_FWCMD_CXROLE_ACT_ROLE_V2(cmd, active->role, i, offset); 2795 RTW89_SET_FWCMD_CXROLE_ACT_CH_V2(cmd, active->ch, i, offset); 2796 RTW89_SET_FWCMD_CXROLE_ACT_NOA_DUR_V2(cmd, active->noa_duration, i, offset); 2797 } 2798 2799 offset = len - H2C_LEN_CXDRVINFO_ROLE_DBCC_LEN; 2800 RTW89_SET_FWCMD_CXROLE_MROLE_TYPE(cmd, role_info->mrole_type, offset); 2801 RTW89_SET_FWCMD_CXROLE_MROLE_NOA(cmd, role_info->mrole_noa_duration, offset); 2802 RTW89_SET_FWCMD_CXROLE_DBCC_EN(cmd, role_info->dbcc_en, offset); 2803 RTW89_SET_FWCMD_CXROLE_DBCC_CHG(cmd, role_info->dbcc_chg, offset); 2804 RTW89_SET_FWCMD_CXROLE_DBCC_2G_PHY(cmd, role_info->dbcc_2g_phy, offset); 2805 RTW89_SET_FWCMD_CXROLE_LINK_MODE_CHG(cmd, role_info->link_mode_chg, offset); 2806 2807 rtw89_h2c_pkt_set_hdr(rtwdev, skb, FWCMD_TYPE_H2C, 2808 H2C_CAT_OUTSRC, BTFC_SET, 2809 SET_DRV_INFO, 0, 0, 2810 len); 2811 2812 ret = rtw89_h2c_tx(rtwdev, skb, false); 2813 if (ret) { 2814 rtw89_err(rtwdev, "failed to send h2c\n"); 2815 goto fail; 2816 } 2817 2818 return 0; 2819 fail: 2820 dev_kfree_skb_any(skb); 2821 2822 return ret; 2823 } 2824 2825 #define H2C_LEN_CXDRVINFO_CTRL (4 + H2C_LEN_CXDRVHDR) 2826 int rtw89_fw_h2c_cxdrv_ctrl(struct rtw89_dev *rtwdev) 2827 { 2828 struct rtw89_btc *btc = &rtwdev->btc; 2829 const struct rtw89_btc_ver *ver = btc->ver; 2830 struct rtw89_btc_ctrl *ctrl = &btc->ctrl; 2831 struct sk_buff *skb; 2832 u8 *cmd; 2833 int ret; 2834 2835 skb = rtw89_fw_h2c_alloc_skb_with_hdr(rtwdev, H2C_LEN_CXDRVINFO_CTRL); 2836 if (!skb) { 2837 rtw89_err(rtwdev, "failed to alloc skb for h2c cxdrv_ctrl\n"); 2838 return -ENOMEM; 2839 } 2840 skb_put(skb, H2C_LEN_CXDRVINFO_CTRL); 2841 cmd = skb->data; 2842 2843 RTW89_SET_FWCMD_CXHDR_TYPE(cmd, CXDRVINFO_CTRL); 2844 RTW89_SET_FWCMD_CXHDR_LEN(cmd, H2C_LEN_CXDRVINFO_CTRL - H2C_LEN_CXDRVHDR); 2845 2846 RTW89_SET_FWCMD_CXCTRL_MANUAL(cmd, ctrl->manual); 2847 RTW89_SET_FWCMD_CXCTRL_IGNORE_BT(cmd, ctrl->igno_bt); 2848 RTW89_SET_FWCMD_CXCTRL_ALWAYS_FREERUN(cmd, ctrl->always_freerun); 2849 if (ver->fcxctrl == 0) 2850 RTW89_SET_FWCMD_CXCTRL_TRACE_STEP(cmd, ctrl->trace_step); 2851 2852 rtw89_h2c_pkt_set_hdr(rtwdev, skb, FWCMD_TYPE_H2C, 2853 H2C_CAT_OUTSRC, BTFC_SET, 2854 SET_DRV_INFO, 0, 0, 2855 H2C_LEN_CXDRVINFO_CTRL); 2856 2857 ret = rtw89_h2c_tx(rtwdev, skb, false); 2858 if (ret) { 2859 rtw89_err(rtwdev, "failed to send h2c\n"); 2860 goto fail; 2861 } 2862 2863 return 0; 2864 fail: 2865 dev_kfree_skb_any(skb); 2866 2867 return ret; 2868 } 2869 2870 #define H2C_LEN_CXDRVINFO_TRX (28 + H2C_LEN_CXDRVHDR) 2871 int rtw89_fw_h2c_cxdrv_trx(struct rtw89_dev *rtwdev) 2872 { 2873 struct rtw89_btc *btc = &rtwdev->btc; 2874 struct rtw89_btc_trx_info *trx = &btc->dm.trx_info; 2875 struct sk_buff *skb; 2876 u8 *cmd; 2877 int ret; 2878 2879 skb = rtw89_fw_h2c_alloc_skb_with_hdr(rtwdev, H2C_LEN_CXDRVINFO_TRX); 2880 if (!skb) { 2881 rtw89_err(rtwdev, "failed to alloc skb for h2c cxdrv_trx\n"); 2882 return -ENOMEM; 2883 } 2884 skb_put(skb, H2C_LEN_CXDRVINFO_TRX); 2885 cmd = skb->data; 2886 2887 RTW89_SET_FWCMD_CXHDR_TYPE(cmd, CXDRVINFO_TRX); 2888 RTW89_SET_FWCMD_CXHDR_LEN(cmd, H2C_LEN_CXDRVINFO_TRX - H2C_LEN_CXDRVHDR); 2889 2890 RTW89_SET_FWCMD_CXTRX_TXLV(cmd, trx->tx_lvl); 2891 RTW89_SET_FWCMD_CXTRX_RXLV(cmd, trx->rx_lvl); 2892 RTW89_SET_FWCMD_CXTRX_WLRSSI(cmd, trx->wl_rssi); 2893 RTW89_SET_FWCMD_CXTRX_BTRSSI(cmd, trx->bt_rssi); 2894 RTW89_SET_FWCMD_CXTRX_TXPWR(cmd, trx->tx_power); 2895 RTW89_SET_FWCMD_CXTRX_RXGAIN(cmd, trx->rx_gain); 2896 RTW89_SET_FWCMD_CXTRX_BTTXPWR(cmd, trx->bt_tx_power); 2897 RTW89_SET_FWCMD_CXTRX_BTRXGAIN(cmd, trx->bt_rx_gain); 2898 RTW89_SET_FWCMD_CXTRX_CN(cmd, trx->cn); 2899 RTW89_SET_FWCMD_CXTRX_NHM(cmd, trx->nhm); 2900 RTW89_SET_FWCMD_CXTRX_BTPROFILE(cmd, trx->bt_profile); 2901 RTW89_SET_FWCMD_CXTRX_RSVD2(cmd, trx->rsvd2); 2902 RTW89_SET_FWCMD_CXTRX_TXRATE(cmd, trx->tx_rate); 2903 RTW89_SET_FWCMD_CXTRX_RXRATE(cmd, trx->rx_rate); 2904 RTW89_SET_FWCMD_CXTRX_TXTP(cmd, trx->tx_tp); 2905 RTW89_SET_FWCMD_CXTRX_RXTP(cmd, trx->rx_tp); 2906 RTW89_SET_FWCMD_CXTRX_RXERRRA(cmd, trx->rx_err_ratio); 2907 2908 rtw89_h2c_pkt_set_hdr(rtwdev, skb, FWCMD_TYPE_H2C, 2909 H2C_CAT_OUTSRC, BTFC_SET, 2910 SET_DRV_INFO, 0, 0, 2911 H2C_LEN_CXDRVINFO_TRX); 2912 2913 ret = rtw89_h2c_tx(rtwdev, skb, false); 2914 if (ret) { 2915 rtw89_err(rtwdev, "failed to send h2c\n"); 2916 goto fail; 2917 } 2918 2919 return 0; 2920 fail: 2921 dev_kfree_skb_any(skb); 2922 2923 return ret; 2924 } 2925 2926 #define H2C_LEN_CXDRVINFO_RFK (4 + H2C_LEN_CXDRVHDR) 2927 int rtw89_fw_h2c_cxdrv_rfk(struct rtw89_dev *rtwdev) 2928 { 2929 struct rtw89_btc *btc = &rtwdev->btc; 2930 struct rtw89_btc_wl_info *wl = &btc->cx.wl; 2931 struct rtw89_btc_wl_rfk_info *rfk_info = &wl->rfk_info; 2932 struct sk_buff *skb; 2933 u8 *cmd; 2934 int ret; 2935 2936 skb = rtw89_fw_h2c_alloc_skb_with_hdr(rtwdev, H2C_LEN_CXDRVINFO_RFK); 2937 if (!skb) { 2938 rtw89_err(rtwdev, "failed to alloc skb for h2c cxdrv_ctrl\n"); 2939 return -ENOMEM; 2940 } 2941 skb_put(skb, H2C_LEN_CXDRVINFO_RFK); 2942 cmd = skb->data; 2943 2944 RTW89_SET_FWCMD_CXHDR_TYPE(cmd, CXDRVINFO_RFK); 2945 RTW89_SET_FWCMD_CXHDR_LEN(cmd, H2C_LEN_CXDRVINFO_RFK - H2C_LEN_CXDRVHDR); 2946 2947 RTW89_SET_FWCMD_CXRFK_STATE(cmd, rfk_info->state); 2948 RTW89_SET_FWCMD_CXRFK_PATH_MAP(cmd, rfk_info->path_map); 2949 RTW89_SET_FWCMD_CXRFK_PHY_MAP(cmd, rfk_info->phy_map); 2950 RTW89_SET_FWCMD_CXRFK_BAND(cmd, rfk_info->band); 2951 RTW89_SET_FWCMD_CXRFK_TYPE(cmd, rfk_info->type); 2952 2953 rtw89_h2c_pkt_set_hdr(rtwdev, skb, FWCMD_TYPE_H2C, 2954 H2C_CAT_OUTSRC, BTFC_SET, 2955 SET_DRV_INFO, 0, 0, 2956 H2C_LEN_CXDRVINFO_RFK); 2957 2958 ret = rtw89_h2c_tx(rtwdev, skb, false); 2959 if (ret) { 2960 rtw89_err(rtwdev, "failed to send h2c\n"); 2961 goto fail; 2962 } 2963 2964 return 0; 2965 fail: 2966 dev_kfree_skb_any(skb); 2967 2968 return ret; 2969 } 2970 2971 #define H2C_LEN_PKT_OFLD 4 2972 int rtw89_fw_h2c_del_pkt_offload(struct rtw89_dev *rtwdev, u8 id) 2973 { 2974 struct rtw89_wait_info *wait = &rtwdev->mac.fw_ofld_wait; 2975 struct sk_buff *skb; 2976 unsigned int cond; 2977 u8 *cmd; 2978 int ret; 2979 2980 skb = rtw89_fw_h2c_alloc_skb_with_hdr(rtwdev, H2C_LEN_PKT_OFLD); 2981 if (!skb) { 2982 rtw89_err(rtwdev, "failed to alloc skb for h2c pkt offload\n"); 2983 return -ENOMEM; 2984 } 2985 skb_put(skb, H2C_LEN_PKT_OFLD); 2986 cmd = skb->data; 2987 2988 RTW89_SET_FWCMD_PACKET_OFLD_PKT_IDX(cmd, id); 2989 RTW89_SET_FWCMD_PACKET_OFLD_PKT_OP(cmd, RTW89_PKT_OFLD_OP_DEL); 2990 2991 rtw89_h2c_pkt_set_hdr(rtwdev, skb, FWCMD_TYPE_H2C, 2992 H2C_CAT_MAC, H2C_CL_MAC_FW_OFLD, 2993 H2C_FUNC_PACKET_OFLD, 1, 1, 2994 H2C_LEN_PKT_OFLD); 2995 2996 cond = RTW89_FW_OFLD_WAIT_COND_PKT_OFLD(id, RTW89_PKT_OFLD_OP_DEL); 2997 2998 ret = rtw89_h2c_tx_and_wait(rtwdev, skb, wait, cond); 2999 if (ret < 0) { 3000 rtw89_debug(rtwdev, RTW89_DBG_FW, 3001 "failed to del pkt ofld: id %d, ret %d\n", 3002 id, ret); 3003 return ret; 3004 } 3005 3006 rtw89_core_release_bit_map(rtwdev->pkt_offload, id); 3007 return 0; 3008 } 3009 3010 int rtw89_fw_h2c_add_pkt_offload(struct rtw89_dev *rtwdev, u8 *id, 3011 struct sk_buff *skb_ofld) 3012 { 3013 struct rtw89_wait_info *wait = &rtwdev->mac.fw_ofld_wait; 3014 struct sk_buff *skb; 3015 unsigned int cond; 3016 u8 *cmd; 3017 u8 alloc_id; 3018 int ret; 3019 3020 alloc_id = rtw89_core_acquire_bit_map(rtwdev->pkt_offload, 3021 RTW89_MAX_PKT_OFLD_NUM); 3022 if (alloc_id == RTW89_MAX_PKT_OFLD_NUM) 3023 return -ENOSPC; 3024 3025 *id = alloc_id; 3026 3027 skb = rtw89_fw_h2c_alloc_skb_with_hdr(rtwdev, H2C_LEN_PKT_OFLD + skb_ofld->len); 3028 if (!skb) { 3029 rtw89_err(rtwdev, "failed to alloc skb for h2c pkt offload\n"); 3030 rtw89_core_release_bit_map(rtwdev->pkt_offload, alloc_id); 3031 return -ENOMEM; 3032 } 3033 skb_put(skb, H2C_LEN_PKT_OFLD); 3034 cmd = skb->data; 3035 3036 RTW89_SET_FWCMD_PACKET_OFLD_PKT_IDX(cmd, alloc_id); 3037 RTW89_SET_FWCMD_PACKET_OFLD_PKT_OP(cmd, RTW89_PKT_OFLD_OP_ADD); 3038 RTW89_SET_FWCMD_PACKET_OFLD_PKT_LENGTH(cmd, skb_ofld->len); 3039 skb_put_data(skb, skb_ofld->data, skb_ofld->len); 3040 3041 rtw89_h2c_pkt_set_hdr(rtwdev, skb, FWCMD_TYPE_H2C, 3042 H2C_CAT_MAC, H2C_CL_MAC_FW_OFLD, 3043 H2C_FUNC_PACKET_OFLD, 1, 1, 3044 H2C_LEN_PKT_OFLD + skb_ofld->len); 3045 3046 cond = RTW89_FW_OFLD_WAIT_COND_PKT_OFLD(alloc_id, RTW89_PKT_OFLD_OP_ADD); 3047 3048 ret = rtw89_h2c_tx_and_wait(rtwdev, skb, wait, cond); 3049 if (ret < 0) { 3050 rtw89_debug(rtwdev, RTW89_DBG_FW, 3051 "failed to add pkt ofld: id %d, ret %d\n", 3052 alloc_id, ret); 3053 rtw89_core_release_bit_map(rtwdev->pkt_offload, alloc_id); 3054 return ret; 3055 } 3056 3057 return 0; 3058 } 3059 3060 #define H2C_LEN_SCAN_LIST_OFFLOAD 4 3061 int rtw89_fw_h2c_scan_list_offload(struct rtw89_dev *rtwdev, int len, 3062 struct list_head *chan_list) 3063 { 3064 struct rtw89_wait_info *wait = &rtwdev->mac.fw_ofld_wait; 3065 struct rtw89_mac_chinfo *ch_info; 3066 struct sk_buff *skb; 3067 int skb_len = H2C_LEN_SCAN_LIST_OFFLOAD + len * RTW89_MAC_CHINFO_SIZE; 3068 unsigned int cond; 3069 u8 *cmd; 3070 int ret; 3071 3072 skb = rtw89_fw_h2c_alloc_skb_with_hdr(rtwdev, skb_len); 3073 if (!skb) { 3074 rtw89_err(rtwdev, "failed to alloc skb for h2c scan list\n"); 3075 return -ENOMEM; 3076 } 3077 skb_put(skb, H2C_LEN_SCAN_LIST_OFFLOAD); 3078 cmd = skb->data; 3079 3080 RTW89_SET_FWCMD_SCANOFLD_CH_NUM(cmd, len); 3081 /* in unit of 4 bytes */ 3082 RTW89_SET_FWCMD_SCANOFLD_CH_SIZE(cmd, RTW89_MAC_CHINFO_SIZE / 4); 3083 3084 list_for_each_entry(ch_info, chan_list, list) { 3085 cmd = skb_put(skb, RTW89_MAC_CHINFO_SIZE); 3086 3087 RTW89_SET_FWCMD_CHINFO_PERIOD(cmd, ch_info->period); 3088 RTW89_SET_FWCMD_CHINFO_DWELL(cmd, ch_info->dwell_time); 3089 RTW89_SET_FWCMD_CHINFO_CENTER_CH(cmd, ch_info->central_ch); 3090 RTW89_SET_FWCMD_CHINFO_PRI_CH(cmd, ch_info->pri_ch); 3091 RTW89_SET_FWCMD_CHINFO_BW(cmd, ch_info->bw); 3092 RTW89_SET_FWCMD_CHINFO_ACTION(cmd, ch_info->notify_action); 3093 RTW89_SET_FWCMD_CHINFO_NUM_PKT(cmd, ch_info->num_pkt); 3094 RTW89_SET_FWCMD_CHINFO_TX(cmd, ch_info->tx_pkt); 3095 RTW89_SET_FWCMD_CHINFO_PAUSE_DATA(cmd, ch_info->pause_data); 3096 RTW89_SET_FWCMD_CHINFO_BAND(cmd, ch_info->ch_band); 3097 RTW89_SET_FWCMD_CHINFO_PKT_ID(cmd, ch_info->probe_id); 3098 RTW89_SET_FWCMD_CHINFO_DFS(cmd, ch_info->dfs_ch); 3099 RTW89_SET_FWCMD_CHINFO_TX_NULL(cmd, ch_info->tx_null); 3100 RTW89_SET_FWCMD_CHINFO_RANDOM(cmd, ch_info->rand_seq_num); 3101 RTW89_SET_FWCMD_CHINFO_PKT0(cmd, ch_info->pkt_id[0]); 3102 RTW89_SET_FWCMD_CHINFO_PKT1(cmd, ch_info->pkt_id[1]); 3103 RTW89_SET_FWCMD_CHINFO_PKT2(cmd, ch_info->pkt_id[2]); 3104 RTW89_SET_FWCMD_CHINFO_PKT3(cmd, ch_info->pkt_id[3]); 3105 RTW89_SET_FWCMD_CHINFO_PKT4(cmd, ch_info->pkt_id[4]); 3106 RTW89_SET_FWCMD_CHINFO_PKT5(cmd, ch_info->pkt_id[5]); 3107 RTW89_SET_FWCMD_CHINFO_PKT6(cmd, ch_info->pkt_id[6]); 3108 RTW89_SET_FWCMD_CHINFO_PKT7(cmd, ch_info->pkt_id[7]); 3109 } 3110 3111 rtw89_h2c_pkt_set_hdr(rtwdev, skb, FWCMD_TYPE_H2C, 3112 H2C_CAT_MAC, H2C_CL_MAC_FW_OFLD, 3113 H2C_FUNC_ADD_SCANOFLD_CH, 1, 1, skb_len); 3114 3115 cond = RTW89_FW_OFLD_WAIT_COND(0, H2C_FUNC_ADD_SCANOFLD_CH); 3116 3117 ret = rtw89_h2c_tx_and_wait(rtwdev, skb, wait, cond); 3118 if (ret) { 3119 rtw89_debug(rtwdev, RTW89_DBG_FW, "failed to add scan ofld ch\n"); 3120 return ret; 3121 } 3122 3123 return 0; 3124 } 3125 3126 int rtw89_fw_h2c_scan_offload(struct rtw89_dev *rtwdev, 3127 struct rtw89_scan_option *option, 3128 struct rtw89_vif *rtwvif) 3129 { 3130 struct rtw89_wait_info *wait = &rtwdev->mac.fw_ofld_wait; 3131 struct rtw89_chan *op = &rtwdev->scan_info.op_chan; 3132 struct rtw89_h2c_scanofld *h2c; 3133 u32 len = sizeof(*h2c); 3134 struct sk_buff *skb; 3135 unsigned int cond; 3136 int ret; 3137 3138 skb = rtw89_fw_h2c_alloc_skb_with_hdr(rtwdev, len); 3139 if (!skb) { 3140 rtw89_err(rtwdev, "failed to alloc skb for h2c scan offload\n"); 3141 return -ENOMEM; 3142 } 3143 skb_put(skb, len); 3144 h2c = (struct rtw89_h2c_scanofld *)skb->data; 3145 3146 h2c->w0 = le32_encode_bits(rtwvif->mac_id, RTW89_H2C_SCANOFLD_W0_MACID) | 3147 le32_encode_bits(rtwvif->port, RTW89_H2C_SCANOFLD_W0_PORT_ID) | 3148 le32_encode_bits(RTW89_PHY_0, RTW89_H2C_SCANOFLD_W0_BAND) | 3149 le32_encode_bits(option->enable, RTW89_H2C_SCANOFLD_W0_OPERATION); 3150 3151 h2c->w1 = le32_encode_bits(true, RTW89_H2C_SCANOFLD_W1_NOTIFY_END) | 3152 le32_encode_bits(option->target_ch_mode, 3153 RTW89_H2C_SCANOFLD_W1_TARGET_CH_MODE) | 3154 le32_encode_bits(RTW89_SCAN_IMMEDIATE, 3155 RTW89_H2C_SCANOFLD_W1_START_MODE) | 3156 le32_encode_bits(RTW89_SCAN_ONCE, RTW89_H2C_SCANOFLD_W1_SCAN_TYPE); 3157 3158 if (option->target_ch_mode) { 3159 h2c->w1 |= le32_encode_bits(op->band_width, 3160 RTW89_H2C_SCANOFLD_W1_TARGET_CH_BW) | 3161 le32_encode_bits(op->primary_channel, 3162 RTW89_H2C_SCANOFLD_W1_TARGET_PRI_CH) | 3163 le32_encode_bits(op->channel, 3164 RTW89_H2C_SCANOFLD_W1_TARGET_CENTRAL_CH); 3165 h2c->w0 |= le32_encode_bits(op->band_type, 3166 RTW89_H2C_SCANOFLD_W0_TARGET_CH_BAND); 3167 } 3168 3169 rtw89_h2c_pkt_set_hdr(rtwdev, skb, FWCMD_TYPE_H2C, 3170 H2C_CAT_MAC, H2C_CL_MAC_FW_OFLD, 3171 H2C_FUNC_SCANOFLD, 1, 1, 3172 len); 3173 3174 cond = RTW89_FW_OFLD_WAIT_COND(0, H2C_FUNC_SCANOFLD); 3175 3176 ret = rtw89_h2c_tx_and_wait(rtwdev, skb, wait, cond); 3177 if (ret) { 3178 rtw89_debug(rtwdev, RTW89_DBG_FW, "failed to scan ofld\n"); 3179 return ret; 3180 } 3181 3182 return 0; 3183 } 3184 3185 int rtw89_fw_h2c_rf_reg(struct rtw89_dev *rtwdev, 3186 struct rtw89_fw_h2c_rf_reg_info *info, 3187 u16 len, u8 page) 3188 { 3189 struct sk_buff *skb; 3190 u8 class = info->rf_path == RF_PATH_A ? 3191 H2C_CL_OUTSRC_RF_REG_A : H2C_CL_OUTSRC_RF_REG_B; 3192 int ret; 3193 3194 skb = rtw89_fw_h2c_alloc_skb_with_hdr(rtwdev, len); 3195 if (!skb) { 3196 rtw89_err(rtwdev, "failed to alloc skb for h2c rf reg\n"); 3197 return -ENOMEM; 3198 } 3199 skb_put_data(skb, info->rtw89_phy_config_rf_h2c[page], len); 3200 3201 rtw89_h2c_pkt_set_hdr(rtwdev, skb, FWCMD_TYPE_H2C, 3202 H2C_CAT_OUTSRC, class, page, 0, 0, 3203 len); 3204 3205 ret = rtw89_h2c_tx(rtwdev, skb, false); 3206 if (ret) { 3207 rtw89_err(rtwdev, "failed to send h2c\n"); 3208 goto fail; 3209 } 3210 3211 return 0; 3212 fail: 3213 dev_kfree_skb_any(skb); 3214 3215 return ret; 3216 } 3217 3218 int rtw89_fw_h2c_rf_ntfy_mcc(struct rtw89_dev *rtwdev) 3219 { 3220 const struct rtw89_chan *chan = rtw89_chan_get(rtwdev, RTW89_SUB_ENTITY_0); 3221 struct rtw89_rfk_mcc_info *rfk_mcc = &rtwdev->rfk_mcc; 3222 struct rtw89_fw_h2c_rf_get_mccch *mccch; 3223 struct sk_buff *skb; 3224 int ret; 3225 3226 skb = rtw89_fw_h2c_alloc_skb_with_hdr(rtwdev, sizeof(*mccch)); 3227 if (!skb) { 3228 rtw89_err(rtwdev, "failed to alloc skb for h2c cxdrv_ctrl\n"); 3229 return -ENOMEM; 3230 } 3231 skb_put(skb, sizeof(*mccch)); 3232 mccch = (struct rtw89_fw_h2c_rf_get_mccch *)skb->data; 3233 3234 mccch->ch_0 = cpu_to_le32(rfk_mcc->ch[0]); 3235 mccch->ch_1 = cpu_to_le32(rfk_mcc->ch[1]); 3236 mccch->band_0 = cpu_to_le32(rfk_mcc->band[0]); 3237 mccch->band_1 = cpu_to_le32(rfk_mcc->band[1]); 3238 mccch->current_channel = cpu_to_le32(chan->channel); 3239 mccch->current_band_type = cpu_to_le32(chan->band_type); 3240 3241 rtw89_h2c_pkt_set_hdr(rtwdev, skb, FWCMD_TYPE_H2C, 3242 H2C_CAT_OUTSRC, H2C_CL_OUTSRC_RF_FW_NOTIFY, 3243 H2C_FUNC_OUTSRC_RF_GET_MCCCH, 0, 0, 3244 sizeof(*mccch)); 3245 3246 ret = rtw89_h2c_tx(rtwdev, skb, false); 3247 if (ret) { 3248 rtw89_err(rtwdev, "failed to send h2c\n"); 3249 goto fail; 3250 } 3251 3252 return 0; 3253 fail: 3254 dev_kfree_skb_any(skb); 3255 3256 return ret; 3257 } 3258 EXPORT_SYMBOL(rtw89_fw_h2c_rf_ntfy_mcc); 3259 3260 int rtw89_fw_h2c_raw_with_hdr(struct rtw89_dev *rtwdev, 3261 u8 h2c_class, u8 h2c_func, u8 *buf, u16 len, 3262 bool rack, bool dack) 3263 { 3264 struct sk_buff *skb; 3265 int ret; 3266 3267 skb = rtw89_fw_h2c_alloc_skb_with_hdr(rtwdev, len); 3268 if (!skb) { 3269 rtw89_err(rtwdev, "failed to alloc skb for raw with hdr\n"); 3270 return -ENOMEM; 3271 } 3272 skb_put_data(skb, buf, len); 3273 3274 rtw89_h2c_pkt_set_hdr(rtwdev, skb, FWCMD_TYPE_H2C, 3275 H2C_CAT_OUTSRC, h2c_class, h2c_func, rack, dack, 3276 len); 3277 3278 ret = rtw89_h2c_tx(rtwdev, skb, false); 3279 if (ret) { 3280 rtw89_err(rtwdev, "failed to send h2c\n"); 3281 goto fail; 3282 } 3283 3284 return 0; 3285 fail: 3286 dev_kfree_skb_any(skb); 3287 3288 return ret; 3289 } 3290 3291 int rtw89_fw_h2c_raw(struct rtw89_dev *rtwdev, const u8 *buf, u16 len) 3292 { 3293 struct sk_buff *skb; 3294 int ret; 3295 3296 skb = rtw89_fw_h2c_alloc_skb_no_hdr(rtwdev, len); 3297 if (!skb) { 3298 rtw89_err(rtwdev, "failed to alloc skb for h2c raw\n"); 3299 return -ENOMEM; 3300 } 3301 skb_put_data(skb, buf, len); 3302 3303 ret = rtw89_h2c_tx(rtwdev, skb, false); 3304 if (ret) { 3305 rtw89_err(rtwdev, "failed to send h2c\n"); 3306 goto fail; 3307 } 3308 3309 return 0; 3310 fail: 3311 dev_kfree_skb_any(skb); 3312 3313 return ret; 3314 } 3315 3316 void rtw89_fw_send_all_early_h2c(struct rtw89_dev *rtwdev) 3317 { 3318 struct rtw89_early_h2c *early_h2c; 3319 3320 lockdep_assert_held(&rtwdev->mutex); 3321 3322 list_for_each_entry(early_h2c, &rtwdev->early_h2c_list, list) { 3323 rtw89_fw_h2c_raw(rtwdev, early_h2c->h2c, early_h2c->h2c_len); 3324 } 3325 } 3326 3327 void rtw89_fw_free_all_early_h2c(struct rtw89_dev *rtwdev) 3328 { 3329 struct rtw89_early_h2c *early_h2c, *tmp; 3330 3331 mutex_lock(&rtwdev->mutex); 3332 list_for_each_entry_safe(early_h2c, tmp, &rtwdev->early_h2c_list, list) { 3333 list_del(&early_h2c->list); 3334 kfree(early_h2c->h2c); 3335 kfree(early_h2c); 3336 } 3337 mutex_unlock(&rtwdev->mutex); 3338 } 3339 3340 static void rtw89_fw_c2h_parse_attr(struct sk_buff *c2h) 3341 { 3342 const struct rtw89_c2h_hdr *hdr = (const struct rtw89_c2h_hdr *)c2h->data; 3343 struct rtw89_fw_c2h_attr *attr = RTW89_SKB_C2H_CB(c2h); 3344 3345 attr->category = le32_get_bits(hdr->w0, RTW89_C2H_HDR_W0_CATEGORY); 3346 attr->class = le32_get_bits(hdr->w0, RTW89_C2H_HDR_W0_CLASS); 3347 attr->func = le32_get_bits(hdr->w0, RTW89_C2H_HDR_W0_FUNC); 3348 attr->len = le32_get_bits(hdr->w1, RTW89_C2H_HDR_W1_LEN); 3349 } 3350 3351 static bool rtw89_fw_c2h_chk_atomic(struct rtw89_dev *rtwdev, 3352 struct sk_buff *c2h) 3353 { 3354 struct rtw89_fw_c2h_attr *attr = RTW89_SKB_C2H_CB(c2h); 3355 u8 category = attr->category; 3356 u8 class = attr->class; 3357 u8 func = attr->func; 3358 3359 switch (category) { 3360 default: 3361 return false; 3362 case RTW89_C2H_CAT_MAC: 3363 return rtw89_mac_c2h_chk_atomic(rtwdev, class, func); 3364 } 3365 } 3366 3367 void rtw89_fw_c2h_irqsafe(struct rtw89_dev *rtwdev, struct sk_buff *c2h) 3368 { 3369 rtw89_fw_c2h_parse_attr(c2h); 3370 if (!rtw89_fw_c2h_chk_atomic(rtwdev, c2h)) 3371 goto enqueue; 3372 3373 rtw89_fw_c2h_cmd_handle(rtwdev, c2h); 3374 dev_kfree_skb_any(c2h); 3375 return; 3376 3377 enqueue: 3378 skb_queue_tail(&rtwdev->c2h_queue, c2h); 3379 ieee80211_queue_work(rtwdev->hw, &rtwdev->c2h_work); 3380 } 3381 3382 static void rtw89_fw_c2h_cmd_handle(struct rtw89_dev *rtwdev, 3383 struct sk_buff *skb) 3384 { 3385 struct rtw89_fw_c2h_attr *attr = RTW89_SKB_C2H_CB(skb); 3386 u8 category = attr->category; 3387 u8 class = attr->class; 3388 u8 func = attr->func; 3389 u16 len = attr->len; 3390 bool dump = true; 3391 3392 if (!test_bit(RTW89_FLAG_RUNNING, rtwdev->flags)) 3393 return; 3394 3395 switch (category) { 3396 case RTW89_C2H_CAT_TEST: 3397 break; 3398 case RTW89_C2H_CAT_MAC: 3399 rtw89_mac_c2h_handle(rtwdev, skb, len, class, func); 3400 if (class == RTW89_MAC_C2H_CLASS_INFO && 3401 func == RTW89_MAC_C2H_FUNC_C2H_LOG) 3402 dump = false; 3403 break; 3404 case RTW89_C2H_CAT_OUTSRC: 3405 if (class >= RTW89_PHY_C2H_CLASS_BTC_MIN && 3406 class <= RTW89_PHY_C2H_CLASS_BTC_MAX) 3407 rtw89_btc_c2h_handle(rtwdev, skb, len, class, func); 3408 else 3409 rtw89_phy_c2h_handle(rtwdev, skb, len, class, func); 3410 break; 3411 } 3412 3413 if (dump) 3414 rtw89_hex_dump(rtwdev, RTW89_DBG_FW, "C2H: ", skb->data, skb->len); 3415 } 3416 3417 void rtw89_fw_c2h_work(struct work_struct *work) 3418 { 3419 struct rtw89_dev *rtwdev = container_of(work, struct rtw89_dev, 3420 c2h_work); 3421 struct sk_buff *skb, *tmp; 3422 3423 skb_queue_walk_safe(&rtwdev->c2h_queue, skb, tmp) { 3424 skb_unlink(skb, &rtwdev->c2h_queue); 3425 mutex_lock(&rtwdev->mutex); 3426 rtw89_fw_c2h_cmd_handle(rtwdev, skb); 3427 mutex_unlock(&rtwdev->mutex); 3428 dev_kfree_skb_any(skb); 3429 } 3430 } 3431 3432 static int rtw89_fw_write_h2c_reg(struct rtw89_dev *rtwdev, 3433 struct rtw89_mac_h2c_info *info) 3434 { 3435 const struct rtw89_chip_info *chip = rtwdev->chip; 3436 struct rtw89_fw_info *fw_info = &rtwdev->fw; 3437 const u32 *h2c_reg = chip->h2c_regs; 3438 u8 i, val, len; 3439 int ret; 3440 3441 ret = read_poll_timeout(rtw89_read8, val, val == 0, 1000, 5000, false, 3442 rtwdev, chip->h2c_ctrl_reg); 3443 if (ret) { 3444 rtw89_warn(rtwdev, "FW does not process h2c registers\n"); 3445 return ret; 3446 } 3447 3448 len = DIV_ROUND_UP(info->content_len + RTW89_H2CREG_HDR_LEN, 3449 sizeof(info->u.h2creg[0])); 3450 3451 u32p_replace_bits(&info->u.hdr.w0, info->id, RTW89_H2CREG_HDR_FUNC_MASK); 3452 u32p_replace_bits(&info->u.hdr.w0, len, RTW89_H2CREG_HDR_LEN_MASK); 3453 3454 for (i = 0; i < RTW89_H2CREG_MAX; i++) 3455 rtw89_write32(rtwdev, h2c_reg[i], info->u.h2creg[i]); 3456 3457 fw_info->h2c_counter++; 3458 rtw89_write8_mask(rtwdev, chip->h2c_counter_reg.addr, 3459 chip->h2c_counter_reg.mask, fw_info->h2c_counter); 3460 rtw89_write8(rtwdev, chip->h2c_ctrl_reg, B_AX_H2CREG_TRIGGER); 3461 3462 return 0; 3463 } 3464 3465 static int rtw89_fw_read_c2h_reg(struct rtw89_dev *rtwdev, 3466 struct rtw89_mac_c2h_info *info) 3467 { 3468 const struct rtw89_chip_info *chip = rtwdev->chip; 3469 struct rtw89_fw_info *fw_info = &rtwdev->fw; 3470 const u32 *c2h_reg = chip->c2h_regs; 3471 u32 ret; 3472 u8 i, val; 3473 3474 info->id = RTW89_FWCMD_C2HREG_FUNC_NULL; 3475 3476 ret = read_poll_timeout_atomic(rtw89_read8, val, val, 1, 3477 RTW89_C2H_TIMEOUT, false, rtwdev, 3478 chip->c2h_ctrl_reg); 3479 if (ret) { 3480 rtw89_warn(rtwdev, "c2h reg timeout\n"); 3481 return ret; 3482 } 3483 3484 for (i = 0; i < RTW89_C2HREG_MAX; i++) 3485 info->u.c2hreg[i] = rtw89_read32(rtwdev, c2h_reg[i]); 3486 3487 rtw89_write8(rtwdev, chip->c2h_ctrl_reg, 0); 3488 3489 info->id = u32_get_bits(info->u.hdr.w0, RTW89_C2HREG_HDR_FUNC_MASK); 3490 info->content_len = 3491 (u32_get_bits(info->u.hdr.w0, RTW89_C2HREG_HDR_LEN_MASK) << 2) - 3492 RTW89_C2HREG_HDR_LEN; 3493 3494 fw_info->c2h_counter++; 3495 rtw89_write8_mask(rtwdev, chip->c2h_counter_reg.addr, 3496 chip->c2h_counter_reg.mask, fw_info->c2h_counter); 3497 3498 return 0; 3499 } 3500 3501 int rtw89_fw_msg_reg(struct rtw89_dev *rtwdev, 3502 struct rtw89_mac_h2c_info *h2c_info, 3503 struct rtw89_mac_c2h_info *c2h_info) 3504 { 3505 u32 ret; 3506 3507 if (h2c_info && h2c_info->id != RTW89_FWCMD_H2CREG_FUNC_GET_FEATURE) 3508 lockdep_assert_held(&rtwdev->mutex); 3509 3510 if (!h2c_info && !c2h_info) 3511 return -EINVAL; 3512 3513 if (!h2c_info) 3514 goto recv_c2h; 3515 3516 ret = rtw89_fw_write_h2c_reg(rtwdev, h2c_info); 3517 if (ret) 3518 return ret; 3519 3520 recv_c2h: 3521 if (!c2h_info) 3522 return 0; 3523 3524 ret = rtw89_fw_read_c2h_reg(rtwdev, c2h_info); 3525 if (ret) 3526 return ret; 3527 3528 return 0; 3529 } 3530 3531 void rtw89_fw_st_dbg_dump(struct rtw89_dev *rtwdev) 3532 { 3533 if (!test_bit(RTW89_FLAG_POWERON, rtwdev->flags)) { 3534 rtw89_err(rtwdev, "[ERR]pwr is off\n"); 3535 return; 3536 } 3537 3538 rtw89_info(rtwdev, "FW status = 0x%x\n", rtw89_read32(rtwdev, R_AX_UDM0)); 3539 rtw89_info(rtwdev, "FW BADADDR = 0x%x\n", rtw89_read32(rtwdev, R_AX_UDM1)); 3540 rtw89_info(rtwdev, "FW EPC/RA = 0x%x\n", rtw89_read32(rtwdev, R_AX_UDM2)); 3541 rtw89_info(rtwdev, "FW MISC = 0x%x\n", rtw89_read32(rtwdev, R_AX_UDM3)); 3542 rtw89_info(rtwdev, "R_AX_HALT_C2H = 0x%x\n", 3543 rtw89_read32(rtwdev, R_AX_HALT_C2H)); 3544 rtw89_info(rtwdev, "R_AX_SER_DBG_INFO = 0x%x\n", 3545 rtw89_read32(rtwdev, R_AX_SER_DBG_INFO)); 3546 3547 rtw89_fw_prog_cnt_dump(rtwdev); 3548 } 3549 3550 static void rtw89_release_pkt_list(struct rtw89_dev *rtwdev) 3551 { 3552 struct list_head *pkt_list = rtwdev->scan_info.pkt_list; 3553 struct rtw89_pktofld_info *info, *tmp; 3554 u8 idx; 3555 3556 for (idx = NL80211_BAND_2GHZ; idx < NUM_NL80211_BANDS; idx++) { 3557 if (!(rtwdev->chip->support_bands & BIT(idx))) 3558 continue; 3559 3560 list_for_each_entry_safe(info, tmp, &pkt_list[idx], list) { 3561 if (test_bit(info->id, rtwdev->pkt_offload)) 3562 rtw89_fw_h2c_del_pkt_offload(rtwdev, info->id); 3563 list_del(&info->list); 3564 kfree(info); 3565 } 3566 } 3567 } 3568 3569 static bool rtw89_is_6ghz_wildcard_probe_req(struct rtw89_dev *rtwdev, 3570 struct rtw89_vif *rtwvif, 3571 struct rtw89_pktofld_info *info, 3572 enum nl80211_band band, u8 ssid_idx) 3573 { 3574 struct cfg80211_scan_request *req = rtwvif->scan_req; 3575 3576 if (band != NL80211_BAND_6GHZ) 3577 return false; 3578 3579 if (req->ssids[ssid_idx].ssid_len) { 3580 memcpy(info->ssid, req->ssids[ssid_idx].ssid, 3581 req->ssids[ssid_idx].ssid_len); 3582 info->ssid_len = req->ssids[ssid_idx].ssid_len; 3583 return false; 3584 } else { 3585 return true; 3586 } 3587 } 3588 3589 static int rtw89_append_probe_req_ie(struct rtw89_dev *rtwdev, 3590 struct rtw89_vif *rtwvif, 3591 struct sk_buff *skb, u8 ssid_idx) 3592 { 3593 struct rtw89_hw_scan_info *scan_info = &rtwdev->scan_info; 3594 struct ieee80211_scan_ies *ies = rtwvif->scan_ies; 3595 struct rtw89_pktofld_info *info; 3596 struct sk_buff *new; 3597 int ret = 0; 3598 u8 band; 3599 3600 for (band = NL80211_BAND_2GHZ; band < NUM_NL80211_BANDS; band++) { 3601 if (!(rtwdev->chip->support_bands & BIT(band))) 3602 continue; 3603 3604 new = skb_copy(skb, GFP_KERNEL); 3605 if (!new) { 3606 ret = -ENOMEM; 3607 goto out; 3608 } 3609 skb_put_data(new, ies->ies[band], ies->len[band]); 3610 skb_put_data(new, ies->common_ies, ies->common_ie_len); 3611 3612 info = kzalloc(sizeof(*info), GFP_KERNEL); 3613 if (!info) { 3614 ret = -ENOMEM; 3615 kfree_skb(new); 3616 goto out; 3617 } 3618 3619 if (rtw89_is_6ghz_wildcard_probe_req(rtwdev, rtwvif, info, band, 3620 ssid_idx)) { 3621 kfree_skb(new); 3622 kfree(info); 3623 goto out; 3624 } 3625 3626 ret = rtw89_fw_h2c_add_pkt_offload(rtwdev, &info->id, new); 3627 if (ret) { 3628 kfree_skb(new); 3629 kfree(info); 3630 goto out; 3631 } 3632 3633 list_add_tail(&info->list, &scan_info->pkt_list[band]); 3634 kfree_skb(new); 3635 } 3636 out: 3637 return ret; 3638 } 3639 3640 static int rtw89_hw_scan_update_probe_req(struct rtw89_dev *rtwdev, 3641 struct rtw89_vif *rtwvif) 3642 { 3643 struct cfg80211_scan_request *req = rtwvif->scan_req; 3644 struct sk_buff *skb; 3645 u8 num = req->n_ssids, i; 3646 int ret; 3647 3648 for (i = 0; i < num; i++) { 3649 skb = ieee80211_probereq_get(rtwdev->hw, rtwvif->mac_addr, 3650 req->ssids[i].ssid, 3651 req->ssids[i].ssid_len, 3652 req->ie_len); 3653 if (!skb) 3654 return -ENOMEM; 3655 3656 ret = rtw89_append_probe_req_ie(rtwdev, rtwvif, skb, i); 3657 kfree_skb(skb); 3658 3659 if (ret) 3660 return ret; 3661 } 3662 3663 return 0; 3664 } 3665 3666 static int rtw89_update_6ghz_rnr_chan(struct rtw89_dev *rtwdev, 3667 struct cfg80211_scan_request *req, 3668 struct rtw89_mac_chinfo *ch_info) 3669 { 3670 struct ieee80211_vif *vif = rtwdev->scan_info.scanning_vif; 3671 struct list_head *pkt_list = rtwdev->scan_info.pkt_list; 3672 struct rtw89_vif *rtwvif = vif_to_rtwvif_safe(vif); 3673 struct ieee80211_scan_ies *ies = rtwvif->scan_ies; 3674 struct cfg80211_scan_6ghz_params *params; 3675 struct rtw89_pktofld_info *info, *tmp; 3676 struct ieee80211_hdr *hdr; 3677 struct sk_buff *skb; 3678 bool found; 3679 int ret = 0; 3680 u8 i; 3681 3682 if (!req->n_6ghz_params) 3683 return 0; 3684 3685 for (i = 0; i < req->n_6ghz_params; i++) { 3686 params = &req->scan_6ghz_params[i]; 3687 3688 if (req->channels[params->channel_idx]->hw_value != 3689 ch_info->pri_ch) 3690 continue; 3691 3692 found = false; 3693 list_for_each_entry(tmp, &pkt_list[NL80211_BAND_6GHZ], list) { 3694 if (ether_addr_equal(tmp->bssid, params->bssid)) { 3695 found = true; 3696 break; 3697 } 3698 } 3699 if (found) 3700 continue; 3701 3702 skb = ieee80211_probereq_get(rtwdev->hw, rtwvif->mac_addr, 3703 NULL, 0, req->ie_len); 3704 skb_put_data(skb, ies->ies[NL80211_BAND_6GHZ], ies->len[NL80211_BAND_6GHZ]); 3705 skb_put_data(skb, ies->common_ies, ies->common_ie_len); 3706 hdr = (struct ieee80211_hdr *)skb->data; 3707 ether_addr_copy(hdr->addr3, params->bssid); 3708 3709 info = kzalloc(sizeof(*info), GFP_KERNEL); 3710 if (!info) { 3711 ret = -ENOMEM; 3712 kfree_skb(skb); 3713 goto out; 3714 } 3715 3716 ret = rtw89_fw_h2c_add_pkt_offload(rtwdev, &info->id, skb); 3717 if (ret) { 3718 kfree_skb(skb); 3719 kfree(info); 3720 goto out; 3721 } 3722 3723 ether_addr_copy(info->bssid, params->bssid); 3724 info->channel_6ghz = req->channels[params->channel_idx]->hw_value; 3725 list_add_tail(&info->list, &rtwdev->scan_info.pkt_list[NL80211_BAND_6GHZ]); 3726 3727 ch_info->tx_pkt = true; 3728 ch_info->period = RTW89_CHANNEL_TIME_6G + RTW89_DWELL_TIME_6G; 3729 3730 kfree_skb(skb); 3731 } 3732 3733 out: 3734 return ret; 3735 } 3736 3737 static void rtw89_hw_scan_add_chan(struct rtw89_dev *rtwdev, int chan_type, 3738 int ssid_num, 3739 struct rtw89_mac_chinfo *ch_info) 3740 { 3741 struct rtw89_hw_scan_info *scan_info = &rtwdev->scan_info; 3742 struct ieee80211_vif *vif = rtwdev->scan_info.scanning_vif; 3743 struct rtw89_vif *rtwvif = (struct rtw89_vif *)vif->drv_priv; 3744 struct cfg80211_scan_request *req = rtwvif->scan_req; 3745 struct rtw89_chan *op = &rtwdev->scan_info.op_chan; 3746 struct rtw89_pktofld_info *info; 3747 u8 band, probe_count = 0; 3748 int ret; 3749 3750 ch_info->notify_action = RTW89_SCANOFLD_DEBUG_MASK; 3751 ch_info->dfs_ch = chan_type == RTW89_CHAN_DFS; 3752 ch_info->bw = RTW89_SCAN_WIDTH; 3753 ch_info->tx_pkt = true; 3754 ch_info->cfg_tx_pwr = false; 3755 ch_info->tx_pwr_idx = 0; 3756 ch_info->tx_null = false; 3757 ch_info->pause_data = false; 3758 ch_info->probe_id = RTW89_SCANOFLD_PKT_NONE; 3759 3760 if (ch_info->ch_band == RTW89_BAND_6G) { 3761 if ((ssid_num == 1 && req->ssids[0].ssid_len == 0) || 3762 !ch_info->is_psc) { 3763 ch_info->tx_pkt = false; 3764 if (!req->duration_mandatory) 3765 ch_info->period -= RTW89_DWELL_TIME_6G; 3766 } 3767 } 3768 3769 ret = rtw89_update_6ghz_rnr_chan(rtwdev, req, ch_info); 3770 if (ret) 3771 rtw89_warn(rtwdev, "RNR fails: %d\n", ret); 3772 3773 if (ssid_num) { 3774 band = rtw89_hw_to_nl80211_band(ch_info->ch_band); 3775 3776 list_for_each_entry(info, &scan_info->pkt_list[band], list) { 3777 if (info->channel_6ghz && 3778 ch_info->pri_ch != info->channel_6ghz) 3779 continue; 3780 ch_info->pkt_id[probe_count++] = info->id; 3781 if (probe_count >= RTW89_SCANOFLD_MAX_SSID) 3782 break; 3783 } 3784 ch_info->num_pkt = probe_count; 3785 } 3786 3787 switch (chan_type) { 3788 case RTW89_CHAN_OPERATE: 3789 ch_info->central_ch = op->channel; 3790 ch_info->pri_ch = op->primary_channel; 3791 ch_info->ch_band = op->band_type; 3792 ch_info->bw = op->band_width; 3793 ch_info->tx_null = true; 3794 ch_info->num_pkt = 0; 3795 break; 3796 case RTW89_CHAN_DFS: 3797 if (ch_info->ch_band != RTW89_BAND_6G) 3798 ch_info->period = max_t(u8, ch_info->period, 3799 RTW89_DFS_CHAN_TIME); 3800 ch_info->dwell_time = RTW89_DWELL_TIME; 3801 break; 3802 case RTW89_CHAN_ACTIVE: 3803 break; 3804 default: 3805 rtw89_err(rtwdev, "Channel type out of bound\n"); 3806 } 3807 } 3808 3809 static int rtw89_hw_scan_add_chan_list(struct rtw89_dev *rtwdev, 3810 struct rtw89_vif *rtwvif, bool connected) 3811 { 3812 struct cfg80211_scan_request *req = rtwvif->scan_req; 3813 struct rtw89_mac_chinfo *ch_info, *tmp; 3814 struct ieee80211_channel *channel; 3815 struct list_head chan_list; 3816 bool random_seq = req->flags & NL80211_SCAN_FLAG_RANDOM_SN; 3817 int list_len, off_chan_time = 0; 3818 enum rtw89_chan_type type; 3819 int ret = 0; 3820 u32 idx; 3821 3822 INIT_LIST_HEAD(&chan_list); 3823 for (idx = rtwdev->scan_info.last_chan_idx, list_len = 0; 3824 idx < req->n_channels && list_len < RTW89_SCAN_LIST_LIMIT; 3825 idx++, list_len++) { 3826 channel = req->channels[idx]; 3827 ch_info = kzalloc(sizeof(*ch_info), GFP_KERNEL); 3828 if (!ch_info) { 3829 ret = -ENOMEM; 3830 goto out; 3831 } 3832 3833 if (req->duration_mandatory) 3834 ch_info->period = req->duration; 3835 else if (channel->band == NL80211_BAND_6GHZ) 3836 ch_info->period = RTW89_CHANNEL_TIME_6G + 3837 RTW89_DWELL_TIME_6G; 3838 else 3839 ch_info->period = RTW89_CHANNEL_TIME; 3840 3841 ch_info->ch_band = rtw89_nl80211_to_hw_band(channel->band); 3842 ch_info->central_ch = channel->hw_value; 3843 ch_info->pri_ch = channel->hw_value; 3844 ch_info->rand_seq_num = random_seq; 3845 ch_info->is_psc = cfg80211_channel_is_psc(channel); 3846 3847 if (channel->flags & 3848 (IEEE80211_CHAN_RADAR | IEEE80211_CHAN_NO_IR)) 3849 type = RTW89_CHAN_DFS; 3850 else 3851 type = RTW89_CHAN_ACTIVE; 3852 rtw89_hw_scan_add_chan(rtwdev, type, req->n_ssids, ch_info); 3853 3854 if (connected && 3855 off_chan_time + ch_info->period > RTW89_OFF_CHAN_TIME) { 3856 tmp = kzalloc(sizeof(*tmp), GFP_KERNEL); 3857 if (!tmp) { 3858 ret = -ENOMEM; 3859 kfree(ch_info); 3860 goto out; 3861 } 3862 3863 type = RTW89_CHAN_OPERATE; 3864 tmp->period = req->duration_mandatory ? 3865 req->duration : RTW89_CHANNEL_TIME; 3866 rtw89_hw_scan_add_chan(rtwdev, type, 0, tmp); 3867 list_add_tail(&tmp->list, &chan_list); 3868 off_chan_time = 0; 3869 list_len++; 3870 } 3871 list_add_tail(&ch_info->list, &chan_list); 3872 off_chan_time += ch_info->period; 3873 } 3874 rtwdev->scan_info.last_chan_idx = idx; 3875 ret = rtw89_fw_h2c_scan_list_offload(rtwdev, list_len, &chan_list); 3876 3877 out: 3878 list_for_each_entry_safe(ch_info, tmp, &chan_list, list) { 3879 list_del(&ch_info->list); 3880 kfree(ch_info); 3881 } 3882 3883 return ret; 3884 } 3885 3886 static int rtw89_hw_scan_prehandle(struct rtw89_dev *rtwdev, 3887 struct rtw89_vif *rtwvif, bool connected) 3888 { 3889 int ret; 3890 3891 ret = rtw89_hw_scan_update_probe_req(rtwdev, rtwvif); 3892 if (ret) { 3893 rtw89_err(rtwdev, "Update probe request failed\n"); 3894 goto out; 3895 } 3896 ret = rtw89_hw_scan_add_chan_list(rtwdev, rtwvif, connected); 3897 out: 3898 return ret; 3899 } 3900 3901 void rtw89_hw_scan_start(struct rtw89_dev *rtwdev, struct ieee80211_vif *vif, 3902 struct ieee80211_scan_request *scan_req) 3903 { 3904 struct rtw89_vif *rtwvif = (struct rtw89_vif *)vif->drv_priv; 3905 struct cfg80211_scan_request *req = &scan_req->req; 3906 u32 rx_fltr = rtwdev->hal.rx_fltr; 3907 u8 mac_addr[ETH_ALEN]; 3908 3909 rtw89_get_channel(rtwdev, rtwvif, &rtwdev->scan_info.op_chan); 3910 rtwdev->scan_info.scanning_vif = vif; 3911 rtwdev->scan_info.last_chan_idx = 0; 3912 rtwvif->scan_ies = &scan_req->ies; 3913 rtwvif->scan_req = req; 3914 ieee80211_stop_queues(rtwdev->hw); 3915 3916 if (req->flags & NL80211_SCAN_FLAG_RANDOM_ADDR) 3917 get_random_mask_addr(mac_addr, req->mac_addr, 3918 req->mac_addr_mask); 3919 else 3920 ether_addr_copy(mac_addr, vif->addr); 3921 rtw89_core_scan_start(rtwdev, rtwvif, mac_addr, true); 3922 3923 rx_fltr &= ~B_AX_A_BCN_CHK_EN; 3924 rx_fltr &= ~B_AX_A_BC; 3925 rx_fltr &= ~B_AX_A_A1_MATCH; 3926 rtw89_write32_mask(rtwdev, 3927 rtw89_mac_reg_by_idx(R_AX_RX_FLTR_OPT, RTW89_MAC_0), 3928 B_AX_RX_FLTR_CFG_MASK, 3929 rx_fltr); 3930 } 3931 3932 void rtw89_hw_scan_complete(struct rtw89_dev *rtwdev, struct ieee80211_vif *vif, 3933 bool aborted) 3934 { 3935 struct rtw89_hw_scan_info *scan_info = &rtwdev->scan_info; 3936 struct cfg80211_scan_info info = { 3937 .aborted = aborted, 3938 }; 3939 struct rtw89_vif *rtwvif; 3940 3941 if (!vif) 3942 return; 3943 3944 rtw89_write32_mask(rtwdev, 3945 rtw89_mac_reg_by_idx(R_AX_RX_FLTR_OPT, RTW89_MAC_0), 3946 B_AX_RX_FLTR_CFG_MASK, 3947 rtwdev->hal.rx_fltr); 3948 3949 rtw89_core_scan_complete(rtwdev, vif, true); 3950 ieee80211_scan_completed(rtwdev->hw, &info); 3951 ieee80211_wake_queues(rtwdev->hw); 3952 3953 rtw89_release_pkt_list(rtwdev); 3954 rtwvif = (struct rtw89_vif *)vif->drv_priv; 3955 rtwvif->scan_req = NULL; 3956 rtwvif->scan_ies = NULL; 3957 scan_info->last_chan_idx = 0; 3958 scan_info->scanning_vif = NULL; 3959 3960 rtw89_set_channel(rtwdev); 3961 } 3962 3963 void rtw89_hw_scan_abort(struct rtw89_dev *rtwdev, struct ieee80211_vif *vif) 3964 { 3965 rtw89_hw_scan_offload(rtwdev, vif, false); 3966 rtw89_hw_scan_complete(rtwdev, vif, true); 3967 } 3968 3969 int rtw89_hw_scan_offload(struct rtw89_dev *rtwdev, struct ieee80211_vif *vif, 3970 bool enable) 3971 { 3972 struct rtw89_scan_option opt = {0}; 3973 struct rtw89_vif *rtwvif; 3974 bool connected; 3975 int ret = 0; 3976 3977 rtwvif = vif ? (struct rtw89_vif *)vif->drv_priv : NULL; 3978 if (!rtwvif) 3979 return -EINVAL; 3980 3981 /* This variable implies connected or during attempt to connect */ 3982 connected = !is_zero_ether_addr(rtwvif->bssid); 3983 opt.enable = enable; 3984 opt.target_ch_mode = connected; 3985 if (enable) { 3986 ret = rtw89_hw_scan_prehandle(rtwdev, rtwvif, connected); 3987 if (ret) 3988 goto out; 3989 } 3990 ret = rtw89_fw_h2c_scan_offload(rtwdev, &opt, rtwvif); 3991 out: 3992 return ret; 3993 } 3994 3995 #define H2C_FW_CPU_EXCEPTION_LEN 4 3996 #define H2C_FW_CPU_EXCEPTION_TYPE_DEF 0x5566 3997 int rtw89_fw_h2c_trigger_cpu_exception(struct rtw89_dev *rtwdev) 3998 { 3999 struct sk_buff *skb; 4000 int ret; 4001 4002 skb = rtw89_fw_h2c_alloc_skb_with_hdr(rtwdev, H2C_FW_CPU_EXCEPTION_LEN); 4003 if (!skb) { 4004 rtw89_err(rtwdev, 4005 "failed to alloc skb for fw cpu exception\n"); 4006 return -ENOMEM; 4007 } 4008 4009 skb_put(skb, H2C_FW_CPU_EXCEPTION_LEN); 4010 RTW89_SET_FWCMD_CPU_EXCEPTION_TYPE(skb->data, 4011 H2C_FW_CPU_EXCEPTION_TYPE_DEF); 4012 4013 rtw89_h2c_pkt_set_hdr(rtwdev, skb, FWCMD_TYPE_H2C, 4014 H2C_CAT_TEST, 4015 H2C_CL_FW_STATUS_TEST, 4016 H2C_FUNC_CPU_EXCEPTION, 0, 0, 4017 H2C_FW_CPU_EXCEPTION_LEN); 4018 4019 ret = rtw89_h2c_tx(rtwdev, skb, false); 4020 if (ret) { 4021 rtw89_err(rtwdev, "failed to send h2c\n"); 4022 goto fail; 4023 } 4024 4025 return 0; 4026 4027 fail: 4028 dev_kfree_skb_any(skb); 4029 return ret; 4030 } 4031 4032 #define H2C_PKT_DROP_LEN 24 4033 int rtw89_fw_h2c_pkt_drop(struct rtw89_dev *rtwdev, 4034 const struct rtw89_pkt_drop_params *params) 4035 { 4036 struct sk_buff *skb; 4037 int ret; 4038 4039 skb = rtw89_fw_h2c_alloc_skb_with_hdr(rtwdev, H2C_PKT_DROP_LEN); 4040 if (!skb) { 4041 rtw89_err(rtwdev, 4042 "failed to alloc skb for packet drop\n"); 4043 return -ENOMEM; 4044 } 4045 4046 switch (params->sel) { 4047 case RTW89_PKT_DROP_SEL_MACID_BE_ONCE: 4048 case RTW89_PKT_DROP_SEL_MACID_BK_ONCE: 4049 case RTW89_PKT_DROP_SEL_MACID_VI_ONCE: 4050 case RTW89_PKT_DROP_SEL_MACID_VO_ONCE: 4051 case RTW89_PKT_DROP_SEL_BAND_ONCE: 4052 break; 4053 default: 4054 rtw89_debug(rtwdev, RTW89_DBG_FW, 4055 "H2C of pkt drop might not fully support sel: %d yet\n", 4056 params->sel); 4057 break; 4058 } 4059 4060 skb_put(skb, H2C_PKT_DROP_LEN); 4061 RTW89_SET_FWCMD_PKT_DROP_SEL(skb->data, params->sel); 4062 RTW89_SET_FWCMD_PKT_DROP_MACID(skb->data, params->macid); 4063 RTW89_SET_FWCMD_PKT_DROP_BAND(skb->data, params->mac_band); 4064 RTW89_SET_FWCMD_PKT_DROP_PORT(skb->data, params->port); 4065 RTW89_SET_FWCMD_PKT_DROP_MBSSID(skb->data, params->mbssid); 4066 RTW89_SET_FWCMD_PKT_DROP_ROLE_A_INFO_TF_TRS(skb->data, params->tf_trs); 4067 RTW89_SET_FWCMD_PKT_DROP_MACID_BAND_SEL_0(skb->data, 4068 params->macid_band_sel[0]); 4069 RTW89_SET_FWCMD_PKT_DROP_MACID_BAND_SEL_1(skb->data, 4070 params->macid_band_sel[1]); 4071 RTW89_SET_FWCMD_PKT_DROP_MACID_BAND_SEL_2(skb->data, 4072 params->macid_band_sel[2]); 4073 RTW89_SET_FWCMD_PKT_DROP_MACID_BAND_SEL_3(skb->data, 4074 params->macid_band_sel[3]); 4075 4076 rtw89_h2c_pkt_set_hdr(rtwdev, skb, FWCMD_TYPE_H2C, 4077 H2C_CAT_MAC, 4078 H2C_CL_MAC_FW_OFLD, 4079 H2C_FUNC_PKT_DROP, 0, 0, 4080 H2C_PKT_DROP_LEN); 4081 4082 ret = rtw89_h2c_tx(rtwdev, skb, false); 4083 if (ret) { 4084 rtw89_err(rtwdev, "failed to send h2c\n"); 4085 goto fail; 4086 } 4087 4088 return 0; 4089 4090 fail: 4091 dev_kfree_skb_any(skb); 4092 return ret; 4093 } 4094 4095 #define H2C_KEEP_ALIVE_LEN 4 4096 int rtw89_fw_h2c_keep_alive(struct rtw89_dev *rtwdev, struct rtw89_vif *rtwvif, 4097 bool enable) 4098 { 4099 struct sk_buff *skb; 4100 u8 pkt_id = 0; 4101 int ret; 4102 4103 if (enable) { 4104 ret = rtw89_fw_h2c_add_general_pkt(rtwdev, rtwvif, 4105 RTW89_PKT_OFLD_TYPE_NULL_DATA, 4106 &pkt_id); 4107 if (ret) 4108 return -EPERM; 4109 } 4110 4111 skb = rtw89_fw_h2c_alloc_skb_with_hdr(rtwdev, H2C_KEEP_ALIVE_LEN); 4112 if (!skb) { 4113 rtw89_err(rtwdev, "failed to alloc skb for keep alive\n"); 4114 return -ENOMEM; 4115 } 4116 4117 skb_put(skb, H2C_KEEP_ALIVE_LEN); 4118 4119 RTW89_SET_KEEP_ALIVE_ENABLE(skb->data, enable); 4120 RTW89_SET_KEEP_ALIVE_PKT_NULL_ID(skb->data, pkt_id); 4121 RTW89_SET_KEEP_ALIVE_PERIOD(skb->data, 5); 4122 RTW89_SET_KEEP_ALIVE_MACID(skb->data, rtwvif->mac_id); 4123 4124 rtw89_h2c_pkt_set_hdr(rtwdev, skb, FWCMD_TYPE_H2C, 4125 H2C_CAT_MAC, 4126 H2C_CL_MAC_WOW, 4127 H2C_FUNC_KEEP_ALIVE, 0, 1, 4128 H2C_KEEP_ALIVE_LEN); 4129 4130 ret = rtw89_h2c_tx(rtwdev, skb, false); 4131 if (ret) { 4132 rtw89_err(rtwdev, "failed to send h2c\n"); 4133 goto fail; 4134 } 4135 4136 return 0; 4137 4138 fail: 4139 dev_kfree_skb_any(skb); 4140 4141 return ret; 4142 } 4143 4144 #define H2C_DISCONNECT_DETECT_LEN 8 4145 int rtw89_fw_h2c_disconnect_detect(struct rtw89_dev *rtwdev, 4146 struct rtw89_vif *rtwvif, bool enable) 4147 { 4148 struct rtw89_wow_param *rtw_wow = &rtwdev->wow; 4149 struct sk_buff *skb; 4150 u8 macid = rtwvif->mac_id; 4151 int ret; 4152 4153 skb = rtw89_fw_h2c_alloc_skb_with_hdr(rtwdev, H2C_DISCONNECT_DETECT_LEN); 4154 if (!skb) { 4155 rtw89_err(rtwdev, "failed to alloc skb for keep alive\n"); 4156 return -ENOMEM; 4157 } 4158 4159 skb_put(skb, H2C_DISCONNECT_DETECT_LEN); 4160 4161 if (test_bit(RTW89_WOW_FLAG_EN_DISCONNECT, rtw_wow->flags)) { 4162 RTW89_SET_DISCONNECT_DETECT_ENABLE(skb->data, enable); 4163 RTW89_SET_DISCONNECT_DETECT_DISCONNECT(skb->data, !enable); 4164 RTW89_SET_DISCONNECT_DETECT_MAC_ID(skb->data, macid); 4165 RTW89_SET_DISCONNECT_DETECT_CHECK_PERIOD(skb->data, 100); 4166 RTW89_SET_DISCONNECT_DETECT_TRY_PKT_COUNT(skb->data, 5); 4167 } 4168 4169 rtw89_h2c_pkt_set_hdr(rtwdev, skb, FWCMD_TYPE_H2C, 4170 H2C_CAT_MAC, 4171 H2C_CL_MAC_WOW, 4172 H2C_FUNC_DISCONNECT_DETECT, 0, 1, 4173 H2C_DISCONNECT_DETECT_LEN); 4174 4175 ret = rtw89_h2c_tx(rtwdev, skb, false); 4176 if (ret) { 4177 rtw89_err(rtwdev, "failed to send h2c\n"); 4178 goto fail; 4179 } 4180 4181 return 0; 4182 4183 fail: 4184 dev_kfree_skb_any(skb); 4185 4186 return ret; 4187 } 4188 4189 #define H2C_WOW_GLOBAL_LEN 8 4190 int rtw89_fw_h2c_wow_global(struct rtw89_dev *rtwdev, struct rtw89_vif *rtwvif, 4191 bool enable) 4192 { 4193 struct sk_buff *skb; 4194 u8 macid = rtwvif->mac_id; 4195 int ret; 4196 4197 skb = rtw89_fw_h2c_alloc_skb_with_hdr(rtwdev, H2C_WOW_GLOBAL_LEN); 4198 if (!skb) { 4199 rtw89_err(rtwdev, "failed to alloc skb for keep alive\n"); 4200 return -ENOMEM; 4201 } 4202 4203 skb_put(skb, H2C_WOW_GLOBAL_LEN); 4204 4205 RTW89_SET_WOW_GLOBAL_ENABLE(skb->data, enable); 4206 RTW89_SET_WOW_GLOBAL_MAC_ID(skb->data, macid); 4207 4208 rtw89_h2c_pkt_set_hdr(rtwdev, skb, FWCMD_TYPE_H2C, 4209 H2C_CAT_MAC, 4210 H2C_CL_MAC_WOW, 4211 H2C_FUNC_WOW_GLOBAL, 0, 1, 4212 H2C_WOW_GLOBAL_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 4222 fail: 4223 dev_kfree_skb_any(skb); 4224 4225 return ret; 4226 } 4227 4228 #define H2C_WAKEUP_CTRL_LEN 4 4229 int rtw89_fw_h2c_wow_wakeup_ctrl(struct rtw89_dev *rtwdev, 4230 struct rtw89_vif *rtwvif, 4231 bool enable) 4232 { 4233 struct rtw89_wow_param *rtw_wow = &rtwdev->wow; 4234 struct sk_buff *skb; 4235 u8 macid = rtwvif->mac_id; 4236 int ret; 4237 4238 skb = rtw89_fw_h2c_alloc_skb_with_hdr(rtwdev, H2C_WAKEUP_CTRL_LEN); 4239 if (!skb) { 4240 rtw89_err(rtwdev, "failed to alloc skb for keep alive\n"); 4241 return -ENOMEM; 4242 } 4243 4244 skb_put(skb, H2C_WAKEUP_CTRL_LEN); 4245 4246 if (rtw_wow->pattern_cnt) 4247 RTW89_SET_WOW_WAKEUP_CTRL_PATTERN_MATCH_ENABLE(skb->data, enable); 4248 if (test_bit(RTW89_WOW_FLAG_EN_MAGIC_PKT, rtw_wow->flags)) 4249 RTW89_SET_WOW_WAKEUP_CTRL_MAGIC_ENABLE(skb->data, enable); 4250 if (test_bit(RTW89_WOW_FLAG_EN_DISCONNECT, rtw_wow->flags)) 4251 RTW89_SET_WOW_WAKEUP_CTRL_DEAUTH_ENABLE(skb->data, enable); 4252 4253 RTW89_SET_WOW_WAKEUP_CTRL_MAC_ID(skb->data, macid); 4254 4255 rtw89_h2c_pkt_set_hdr(rtwdev, skb, FWCMD_TYPE_H2C, 4256 H2C_CAT_MAC, 4257 H2C_CL_MAC_WOW, 4258 H2C_FUNC_WAKEUP_CTRL, 0, 1, 4259 H2C_WAKEUP_CTRL_LEN); 4260 4261 ret = rtw89_h2c_tx(rtwdev, skb, false); 4262 if (ret) { 4263 rtw89_err(rtwdev, "failed to send h2c\n"); 4264 goto fail; 4265 } 4266 4267 return 0; 4268 4269 fail: 4270 dev_kfree_skb_any(skb); 4271 4272 return ret; 4273 } 4274 4275 #define H2C_WOW_CAM_UPD_LEN 24 4276 int rtw89_fw_wow_cam_update(struct rtw89_dev *rtwdev, 4277 struct rtw89_wow_cam_info *cam_info) 4278 { 4279 struct sk_buff *skb; 4280 int ret; 4281 4282 skb = rtw89_fw_h2c_alloc_skb_with_hdr(rtwdev, H2C_WOW_CAM_UPD_LEN); 4283 if (!skb) { 4284 rtw89_err(rtwdev, "failed to alloc skb for keep alive\n"); 4285 return -ENOMEM; 4286 } 4287 4288 skb_put(skb, H2C_WOW_CAM_UPD_LEN); 4289 4290 RTW89_SET_WOW_CAM_UPD_R_W(skb->data, cam_info->r_w); 4291 RTW89_SET_WOW_CAM_UPD_IDX(skb->data, cam_info->idx); 4292 if (cam_info->valid) { 4293 RTW89_SET_WOW_CAM_UPD_WKFM1(skb->data, cam_info->mask[0]); 4294 RTW89_SET_WOW_CAM_UPD_WKFM2(skb->data, cam_info->mask[1]); 4295 RTW89_SET_WOW_CAM_UPD_WKFM3(skb->data, cam_info->mask[2]); 4296 RTW89_SET_WOW_CAM_UPD_WKFM4(skb->data, cam_info->mask[3]); 4297 RTW89_SET_WOW_CAM_UPD_CRC(skb->data, cam_info->crc); 4298 RTW89_SET_WOW_CAM_UPD_NEGATIVE_PATTERN_MATCH(skb->data, 4299 cam_info->negative_pattern_match); 4300 RTW89_SET_WOW_CAM_UPD_SKIP_MAC_HDR(skb->data, 4301 cam_info->skip_mac_hdr); 4302 RTW89_SET_WOW_CAM_UPD_UC(skb->data, cam_info->uc); 4303 RTW89_SET_WOW_CAM_UPD_MC(skb->data, cam_info->mc); 4304 RTW89_SET_WOW_CAM_UPD_BC(skb->data, cam_info->bc); 4305 } 4306 RTW89_SET_WOW_CAM_UPD_VALID(skb->data, cam_info->valid); 4307 4308 rtw89_h2c_pkt_set_hdr(rtwdev, skb, FWCMD_TYPE_H2C, 4309 H2C_CAT_MAC, 4310 H2C_CL_MAC_WOW, 4311 H2C_FUNC_WOW_CAM_UPD, 0, 1, 4312 H2C_WOW_CAM_UPD_LEN); 4313 4314 ret = rtw89_h2c_tx(rtwdev, skb, false); 4315 if (ret) { 4316 rtw89_err(rtwdev, "failed to send h2c\n"); 4317 goto fail; 4318 } 4319 4320 return 0; 4321 fail: 4322 dev_kfree_skb_any(skb); 4323 4324 return ret; 4325 } 4326 4327 /* Return < 0, if failures happen during waiting for the condition. 4328 * Return 0, when waiting for the condition succeeds. 4329 * Return > 0, if the wait is considered unreachable due to driver/FW design, 4330 * where 1 means during SER. 4331 */ 4332 static int rtw89_h2c_tx_and_wait(struct rtw89_dev *rtwdev, struct sk_buff *skb, 4333 struct rtw89_wait_info *wait, unsigned int cond) 4334 { 4335 int ret; 4336 4337 ret = rtw89_h2c_tx(rtwdev, skb, false); 4338 if (ret) { 4339 rtw89_err(rtwdev, "failed to send h2c\n"); 4340 dev_kfree_skb_any(skb); 4341 return -EBUSY; 4342 } 4343 4344 if (test_bit(RTW89_FLAG_SER_HANDLING, rtwdev->flags)) 4345 return 1; 4346 4347 return rtw89_wait_for_cond(wait, cond); 4348 } 4349 4350 #define H2C_ADD_MCC_LEN 16 4351 int rtw89_fw_h2c_add_mcc(struct rtw89_dev *rtwdev, 4352 const struct rtw89_fw_mcc_add_req *p) 4353 { 4354 struct rtw89_wait_info *wait = &rtwdev->mcc.wait; 4355 struct sk_buff *skb; 4356 unsigned int cond; 4357 4358 skb = rtw89_fw_h2c_alloc_skb_with_hdr(rtwdev, H2C_ADD_MCC_LEN); 4359 if (!skb) { 4360 rtw89_err(rtwdev, 4361 "failed to alloc skb for add mcc\n"); 4362 return -ENOMEM; 4363 } 4364 4365 skb_put(skb, H2C_ADD_MCC_LEN); 4366 RTW89_SET_FWCMD_ADD_MCC_MACID(skb->data, p->macid); 4367 RTW89_SET_FWCMD_ADD_MCC_CENTRAL_CH_SEG0(skb->data, p->central_ch_seg0); 4368 RTW89_SET_FWCMD_ADD_MCC_CENTRAL_CH_SEG1(skb->data, p->central_ch_seg1); 4369 RTW89_SET_FWCMD_ADD_MCC_PRIMARY_CH(skb->data, p->primary_ch); 4370 RTW89_SET_FWCMD_ADD_MCC_BANDWIDTH(skb->data, p->bandwidth); 4371 RTW89_SET_FWCMD_ADD_MCC_GROUP(skb->data, p->group); 4372 RTW89_SET_FWCMD_ADD_MCC_C2H_RPT(skb->data, p->c2h_rpt); 4373 RTW89_SET_FWCMD_ADD_MCC_DIS_TX_NULL(skb->data, p->dis_tx_null); 4374 RTW89_SET_FWCMD_ADD_MCC_DIS_SW_RETRY(skb->data, p->dis_sw_retry); 4375 RTW89_SET_FWCMD_ADD_MCC_IN_CURR_CH(skb->data, p->in_curr_ch); 4376 RTW89_SET_FWCMD_ADD_MCC_SW_RETRY_COUNT(skb->data, p->sw_retry_count); 4377 RTW89_SET_FWCMD_ADD_MCC_TX_NULL_EARLY(skb->data, p->tx_null_early); 4378 RTW89_SET_FWCMD_ADD_MCC_BTC_IN_2G(skb->data, p->btc_in_2g); 4379 RTW89_SET_FWCMD_ADD_MCC_PTA_EN(skb->data, p->pta_en); 4380 RTW89_SET_FWCMD_ADD_MCC_RFK_BY_PASS(skb->data, p->rfk_by_pass); 4381 RTW89_SET_FWCMD_ADD_MCC_CH_BAND_TYPE(skb->data, p->ch_band_type); 4382 RTW89_SET_FWCMD_ADD_MCC_DURATION(skb->data, p->duration); 4383 RTW89_SET_FWCMD_ADD_MCC_COURTESY_EN(skb->data, p->courtesy_en); 4384 RTW89_SET_FWCMD_ADD_MCC_COURTESY_NUM(skb->data, p->courtesy_num); 4385 RTW89_SET_FWCMD_ADD_MCC_COURTESY_TARGET(skb->data, p->courtesy_target); 4386 4387 rtw89_h2c_pkt_set_hdr(rtwdev, skb, FWCMD_TYPE_H2C, 4388 H2C_CAT_MAC, 4389 H2C_CL_MCC, 4390 H2C_FUNC_ADD_MCC, 0, 0, 4391 H2C_ADD_MCC_LEN); 4392 4393 cond = RTW89_MCC_WAIT_COND(p->group, H2C_FUNC_ADD_MCC); 4394 return rtw89_h2c_tx_and_wait(rtwdev, skb, wait, cond); 4395 } 4396 4397 #define H2C_START_MCC_LEN 12 4398 int rtw89_fw_h2c_start_mcc(struct rtw89_dev *rtwdev, 4399 const struct rtw89_fw_mcc_start_req *p) 4400 { 4401 struct rtw89_wait_info *wait = &rtwdev->mcc.wait; 4402 struct sk_buff *skb; 4403 unsigned int cond; 4404 4405 skb = rtw89_fw_h2c_alloc_skb_with_hdr(rtwdev, H2C_START_MCC_LEN); 4406 if (!skb) { 4407 rtw89_err(rtwdev, 4408 "failed to alloc skb for start mcc\n"); 4409 return -ENOMEM; 4410 } 4411 4412 skb_put(skb, H2C_START_MCC_LEN); 4413 RTW89_SET_FWCMD_START_MCC_GROUP(skb->data, p->group); 4414 RTW89_SET_FWCMD_START_MCC_BTC_IN_GROUP(skb->data, p->btc_in_group); 4415 RTW89_SET_FWCMD_START_MCC_OLD_GROUP_ACTION(skb->data, p->old_group_action); 4416 RTW89_SET_FWCMD_START_MCC_OLD_GROUP(skb->data, p->old_group); 4417 RTW89_SET_FWCMD_START_MCC_NOTIFY_CNT(skb->data, p->notify_cnt); 4418 RTW89_SET_FWCMD_START_MCC_NOTIFY_RXDBG_EN(skb->data, p->notify_rxdbg_en); 4419 RTW89_SET_FWCMD_START_MCC_MACID(skb->data, p->macid); 4420 RTW89_SET_FWCMD_START_MCC_TSF_LOW(skb->data, p->tsf_low); 4421 RTW89_SET_FWCMD_START_MCC_TSF_HIGH(skb->data, p->tsf_high); 4422 4423 rtw89_h2c_pkt_set_hdr(rtwdev, skb, FWCMD_TYPE_H2C, 4424 H2C_CAT_MAC, 4425 H2C_CL_MCC, 4426 H2C_FUNC_START_MCC, 0, 0, 4427 H2C_START_MCC_LEN); 4428 4429 cond = RTW89_MCC_WAIT_COND(p->group, H2C_FUNC_START_MCC); 4430 return rtw89_h2c_tx_and_wait(rtwdev, skb, wait, cond); 4431 } 4432 4433 #define H2C_STOP_MCC_LEN 4 4434 int rtw89_fw_h2c_stop_mcc(struct rtw89_dev *rtwdev, u8 group, u8 macid, 4435 bool prev_groups) 4436 { 4437 struct rtw89_wait_info *wait = &rtwdev->mcc.wait; 4438 struct sk_buff *skb; 4439 unsigned int cond; 4440 4441 skb = rtw89_fw_h2c_alloc_skb_with_hdr(rtwdev, H2C_STOP_MCC_LEN); 4442 if (!skb) { 4443 rtw89_err(rtwdev, 4444 "failed to alloc skb for stop mcc\n"); 4445 return -ENOMEM; 4446 } 4447 4448 skb_put(skb, H2C_STOP_MCC_LEN); 4449 RTW89_SET_FWCMD_STOP_MCC_MACID(skb->data, macid); 4450 RTW89_SET_FWCMD_STOP_MCC_GROUP(skb->data, group); 4451 RTW89_SET_FWCMD_STOP_MCC_PREV_GROUPS(skb->data, prev_groups); 4452 4453 rtw89_h2c_pkt_set_hdr(rtwdev, skb, FWCMD_TYPE_H2C, 4454 H2C_CAT_MAC, 4455 H2C_CL_MCC, 4456 H2C_FUNC_STOP_MCC, 0, 0, 4457 H2C_STOP_MCC_LEN); 4458 4459 cond = RTW89_MCC_WAIT_COND(group, H2C_FUNC_STOP_MCC); 4460 return rtw89_h2c_tx_and_wait(rtwdev, skb, wait, cond); 4461 } 4462 4463 #define H2C_DEL_MCC_GROUP_LEN 4 4464 int rtw89_fw_h2c_del_mcc_group(struct rtw89_dev *rtwdev, u8 group, 4465 bool prev_groups) 4466 { 4467 struct rtw89_wait_info *wait = &rtwdev->mcc.wait; 4468 struct sk_buff *skb; 4469 unsigned int cond; 4470 4471 skb = rtw89_fw_h2c_alloc_skb_with_hdr(rtwdev, H2C_DEL_MCC_GROUP_LEN); 4472 if (!skb) { 4473 rtw89_err(rtwdev, 4474 "failed to alloc skb for del mcc group\n"); 4475 return -ENOMEM; 4476 } 4477 4478 skb_put(skb, H2C_DEL_MCC_GROUP_LEN); 4479 RTW89_SET_FWCMD_DEL_MCC_GROUP_GROUP(skb->data, group); 4480 RTW89_SET_FWCMD_DEL_MCC_GROUP_PREV_GROUPS(skb->data, prev_groups); 4481 4482 rtw89_h2c_pkt_set_hdr(rtwdev, skb, FWCMD_TYPE_H2C, 4483 H2C_CAT_MAC, 4484 H2C_CL_MCC, 4485 H2C_FUNC_DEL_MCC_GROUP, 0, 0, 4486 H2C_DEL_MCC_GROUP_LEN); 4487 4488 cond = RTW89_MCC_WAIT_COND(group, H2C_FUNC_DEL_MCC_GROUP); 4489 return rtw89_h2c_tx_and_wait(rtwdev, skb, wait, cond); 4490 } 4491 4492 #define H2C_RESET_MCC_GROUP_LEN 4 4493 int rtw89_fw_h2c_reset_mcc_group(struct rtw89_dev *rtwdev, u8 group) 4494 { 4495 struct rtw89_wait_info *wait = &rtwdev->mcc.wait; 4496 struct sk_buff *skb; 4497 unsigned int cond; 4498 4499 skb = rtw89_fw_h2c_alloc_skb_with_hdr(rtwdev, H2C_RESET_MCC_GROUP_LEN); 4500 if (!skb) { 4501 rtw89_err(rtwdev, 4502 "failed to alloc skb for reset mcc group\n"); 4503 return -ENOMEM; 4504 } 4505 4506 skb_put(skb, H2C_RESET_MCC_GROUP_LEN); 4507 RTW89_SET_FWCMD_RESET_MCC_GROUP_GROUP(skb->data, group); 4508 4509 rtw89_h2c_pkt_set_hdr(rtwdev, skb, FWCMD_TYPE_H2C, 4510 H2C_CAT_MAC, 4511 H2C_CL_MCC, 4512 H2C_FUNC_RESET_MCC_GROUP, 0, 0, 4513 H2C_RESET_MCC_GROUP_LEN); 4514 4515 cond = RTW89_MCC_WAIT_COND(group, H2C_FUNC_RESET_MCC_GROUP); 4516 return rtw89_h2c_tx_and_wait(rtwdev, skb, wait, cond); 4517 } 4518 4519 #define H2C_MCC_REQ_TSF_LEN 4 4520 int rtw89_fw_h2c_mcc_req_tsf(struct rtw89_dev *rtwdev, 4521 const struct rtw89_fw_mcc_tsf_req *req, 4522 struct rtw89_mac_mcc_tsf_rpt *rpt) 4523 { 4524 struct rtw89_wait_info *wait = &rtwdev->mcc.wait; 4525 struct rtw89_mac_mcc_tsf_rpt *tmp; 4526 struct sk_buff *skb; 4527 unsigned int cond; 4528 int ret; 4529 4530 skb = rtw89_fw_h2c_alloc_skb_with_hdr(rtwdev, H2C_MCC_REQ_TSF_LEN); 4531 if (!skb) { 4532 rtw89_err(rtwdev, 4533 "failed to alloc skb for mcc req tsf\n"); 4534 return -ENOMEM; 4535 } 4536 4537 skb_put(skb, H2C_MCC_REQ_TSF_LEN); 4538 RTW89_SET_FWCMD_MCC_REQ_TSF_GROUP(skb->data, req->group); 4539 RTW89_SET_FWCMD_MCC_REQ_TSF_MACID_X(skb->data, req->macid_x); 4540 RTW89_SET_FWCMD_MCC_REQ_TSF_MACID_Y(skb->data, req->macid_y); 4541 4542 rtw89_h2c_pkt_set_hdr(rtwdev, skb, FWCMD_TYPE_H2C, 4543 H2C_CAT_MAC, 4544 H2C_CL_MCC, 4545 H2C_FUNC_MCC_REQ_TSF, 0, 0, 4546 H2C_MCC_REQ_TSF_LEN); 4547 4548 cond = RTW89_MCC_WAIT_COND(req->group, H2C_FUNC_MCC_REQ_TSF); 4549 ret = rtw89_h2c_tx_and_wait(rtwdev, skb, wait, cond); 4550 if (ret) 4551 return ret; 4552 4553 tmp = (struct rtw89_mac_mcc_tsf_rpt *)wait->data.buf; 4554 *rpt = *tmp; 4555 4556 return 0; 4557 } 4558 4559 #define H2C_MCC_MACID_BITMAP_DSC_LEN 4 4560 int rtw89_fw_h2c_mcc_macid_bitamp(struct rtw89_dev *rtwdev, u8 group, u8 macid, 4561 u8 *bitmap) 4562 { 4563 struct rtw89_wait_info *wait = &rtwdev->mcc.wait; 4564 struct sk_buff *skb; 4565 unsigned int cond; 4566 u8 map_len; 4567 u8 h2c_len; 4568 4569 BUILD_BUG_ON(RTW89_MAX_MAC_ID_NUM % 8); 4570 map_len = RTW89_MAX_MAC_ID_NUM / 8; 4571 h2c_len = H2C_MCC_MACID_BITMAP_DSC_LEN + map_len; 4572 skb = rtw89_fw_h2c_alloc_skb_with_hdr(rtwdev, h2c_len); 4573 if (!skb) { 4574 rtw89_err(rtwdev, 4575 "failed to alloc skb for mcc macid bitmap\n"); 4576 return -ENOMEM; 4577 } 4578 4579 skb_put(skb, h2c_len); 4580 RTW89_SET_FWCMD_MCC_MACID_BITMAP_GROUP(skb->data, group); 4581 RTW89_SET_FWCMD_MCC_MACID_BITMAP_MACID(skb->data, macid); 4582 RTW89_SET_FWCMD_MCC_MACID_BITMAP_BITMAP_LENGTH(skb->data, map_len); 4583 RTW89_SET_FWCMD_MCC_MACID_BITMAP_BITMAP(skb->data, bitmap, map_len); 4584 4585 rtw89_h2c_pkt_set_hdr(rtwdev, skb, FWCMD_TYPE_H2C, 4586 H2C_CAT_MAC, 4587 H2C_CL_MCC, 4588 H2C_FUNC_MCC_MACID_BITMAP, 0, 0, 4589 h2c_len); 4590 4591 cond = RTW89_MCC_WAIT_COND(group, H2C_FUNC_MCC_MACID_BITMAP); 4592 return rtw89_h2c_tx_and_wait(rtwdev, skb, wait, cond); 4593 } 4594 4595 #define H2C_MCC_SYNC_LEN 4 4596 int rtw89_fw_h2c_mcc_sync(struct rtw89_dev *rtwdev, u8 group, u8 source, 4597 u8 target, u8 offset) 4598 { 4599 struct rtw89_wait_info *wait = &rtwdev->mcc.wait; 4600 struct sk_buff *skb; 4601 unsigned int cond; 4602 4603 skb = rtw89_fw_h2c_alloc_skb_with_hdr(rtwdev, H2C_MCC_SYNC_LEN); 4604 if (!skb) { 4605 rtw89_err(rtwdev, 4606 "failed to alloc skb for mcc sync\n"); 4607 return -ENOMEM; 4608 } 4609 4610 skb_put(skb, H2C_MCC_SYNC_LEN); 4611 RTW89_SET_FWCMD_MCC_SYNC_GROUP(skb->data, group); 4612 RTW89_SET_FWCMD_MCC_SYNC_MACID_SOURCE(skb->data, source); 4613 RTW89_SET_FWCMD_MCC_SYNC_MACID_TARGET(skb->data, target); 4614 RTW89_SET_FWCMD_MCC_SYNC_SYNC_OFFSET(skb->data, offset); 4615 4616 rtw89_h2c_pkt_set_hdr(rtwdev, skb, FWCMD_TYPE_H2C, 4617 H2C_CAT_MAC, 4618 H2C_CL_MCC, 4619 H2C_FUNC_MCC_SYNC, 0, 0, 4620 H2C_MCC_SYNC_LEN); 4621 4622 cond = RTW89_MCC_WAIT_COND(group, H2C_FUNC_MCC_SYNC); 4623 return rtw89_h2c_tx_and_wait(rtwdev, skb, wait, cond); 4624 } 4625 4626 #define H2C_MCC_SET_DURATION_LEN 20 4627 int rtw89_fw_h2c_mcc_set_duration(struct rtw89_dev *rtwdev, 4628 const struct rtw89_fw_mcc_duration *p) 4629 { 4630 struct rtw89_wait_info *wait = &rtwdev->mcc.wait; 4631 struct sk_buff *skb; 4632 unsigned int cond; 4633 4634 skb = rtw89_fw_h2c_alloc_skb_with_hdr(rtwdev, H2C_MCC_SET_DURATION_LEN); 4635 if (!skb) { 4636 rtw89_err(rtwdev, 4637 "failed to alloc skb for mcc set duration\n"); 4638 return -ENOMEM; 4639 } 4640 4641 skb_put(skb, H2C_MCC_SET_DURATION_LEN); 4642 RTW89_SET_FWCMD_MCC_SET_DURATION_GROUP(skb->data, p->group); 4643 RTW89_SET_FWCMD_MCC_SET_DURATION_BTC_IN_GROUP(skb->data, p->btc_in_group); 4644 RTW89_SET_FWCMD_MCC_SET_DURATION_START_MACID(skb->data, p->start_macid); 4645 RTW89_SET_FWCMD_MCC_SET_DURATION_MACID_X(skb->data, p->macid_x); 4646 RTW89_SET_FWCMD_MCC_SET_DURATION_MACID_Y(skb->data, p->macid_y); 4647 RTW89_SET_FWCMD_MCC_SET_DURATION_START_TSF_LOW(skb->data, 4648 p->start_tsf_low); 4649 RTW89_SET_FWCMD_MCC_SET_DURATION_START_TSF_HIGH(skb->data, 4650 p->start_tsf_high); 4651 RTW89_SET_FWCMD_MCC_SET_DURATION_DURATION_X(skb->data, p->duration_x); 4652 RTW89_SET_FWCMD_MCC_SET_DURATION_DURATION_Y(skb->data, p->duration_y); 4653 4654 rtw89_h2c_pkt_set_hdr(rtwdev, skb, FWCMD_TYPE_H2C, 4655 H2C_CAT_MAC, 4656 H2C_CL_MCC, 4657 H2C_FUNC_MCC_SET_DURATION, 0, 0, 4658 H2C_MCC_SET_DURATION_LEN); 4659 4660 cond = RTW89_MCC_WAIT_COND(p->group, H2C_FUNC_MCC_SET_DURATION); 4661 return rtw89_h2c_tx_and_wait(rtwdev, skb, wait, cond); 4662 } 4663