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