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