0001
0002
0003
0004
0005 #include "cam.h"
0006 #include "coex.h"
0007 #include "debug.h"
0008 #include "fw.h"
0009 #include "mac.h"
0010 #include "phy.h"
0011 #include "reg.h"
0012
0013 static struct sk_buff *rtw89_fw_h2c_alloc_skb(struct rtw89_dev *rtwdev, u32 len,
0014 bool header)
0015 {
0016 struct sk_buff *skb;
0017 u32 header_len = 0;
0018 u32 h2c_desc_size = rtwdev->chip->h2c_desc_size;
0019
0020 if (header)
0021 header_len = H2C_HEADER_LEN;
0022
0023 skb = dev_alloc_skb(len + header_len + h2c_desc_size);
0024 if (!skb)
0025 return NULL;
0026 skb_reserve(skb, header_len + h2c_desc_size);
0027 memset(skb->data, 0, len);
0028
0029 return skb;
0030 }
0031
0032 struct sk_buff *rtw89_fw_h2c_alloc_skb_with_hdr(struct rtw89_dev *rtwdev, u32 len)
0033 {
0034 return rtw89_fw_h2c_alloc_skb(rtwdev, len, true);
0035 }
0036
0037 struct sk_buff *rtw89_fw_h2c_alloc_skb_no_hdr(struct rtw89_dev *rtwdev, u32 len)
0038 {
0039 return rtw89_fw_h2c_alloc_skb(rtwdev, len, false);
0040 }
0041
0042 static u8 _fw_get_rdy(struct rtw89_dev *rtwdev)
0043 {
0044 u8 val = rtw89_read8(rtwdev, R_AX_WCPU_FW_CTRL);
0045
0046 return FIELD_GET(B_AX_WCPU_FWDL_STS_MASK, val);
0047 }
0048
0049 #define FWDL_WAIT_CNT 400000
0050 int rtw89_fw_check_rdy(struct rtw89_dev *rtwdev)
0051 {
0052 u8 val;
0053 int ret;
0054
0055 ret = read_poll_timeout_atomic(_fw_get_rdy, val,
0056 val == RTW89_FWDL_WCPU_FW_INIT_RDY,
0057 1, FWDL_WAIT_CNT, false, rtwdev);
0058 if (ret) {
0059 switch (val) {
0060 case RTW89_FWDL_CHECKSUM_FAIL:
0061 rtw89_err(rtwdev, "fw checksum fail\n");
0062 return -EINVAL;
0063
0064 case RTW89_FWDL_SECURITY_FAIL:
0065 rtw89_err(rtwdev, "fw security fail\n");
0066 return -EINVAL;
0067
0068 case RTW89_FWDL_CV_NOT_MATCH:
0069 rtw89_err(rtwdev, "fw cv not match\n");
0070 return -EINVAL;
0071
0072 default:
0073 return -EBUSY;
0074 }
0075 }
0076
0077 set_bit(RTW89_FLAG_FW_RDY, rtwdev->flags);
0078
0079 return 0;
0080 }
0081
0082 static int rtw89_fw_hdr_parser(struct rtw89_dev *rtwdev, const u8 *fw, u32 len,
0083 struct rtw89_fw_bin_info *info)
0084 {
0085 struct rtw89_fw_hdr_section_info *section_info;
0086 const u8 *fw_end = fw + len;
0087 const u8 *bin;
0088 u32 i;
0089
0090 if (!info)
0091 return -EINVAL;
0092
0093 info->section_num = GET_FW_HDR_SEC_NUM(fw);
0094 info->hdr_len = RTW89_FW_HDR_SIZE +
0095 info->section_num * RTW89_FW_SECTION_HDR_SIZE;
0096
0097 bin = fw + info->hdr_len;
0098
0099
0100 fw += RTW89_FW_HDR_SIZE;
0101 section_info = info->section_info;
0102 for (i = 0; i < info->section_num; i++) {
0103 section_info->len = GET_FWSECTION_HDR_SEC_SIZE(fw);
0104 if (GET_FWSECTION_HDR_CHECKSUM(fw))
0105 section_info->len += FWDL_SECTION_CHKSUM_LEN;
0106 section_info->redl = GET_FWSECTION_HDR_REDL(fw);
0107 section_info->dladdr =
0108 GET_FWSECTION_HDR_DL_ADDR(fw) & 0x1fffffff;
0109 section_info->addr = bin;
0110 bin += section_info->len;
0111 fw += RTW89_FW_SECTION_HDR_SIZE;
0112 section_info++;
0113 }
0114
0115 if (fw_end != bin) {
0116 rtw89_err(rtwdev, "[ERR]fw bin size\n");
0117 return -EINVAL;
0118 }
0119
0120 return 0;
0121 }
0122
0123 static
0124 int rtw89_mfw_recognize(struct rtw89_dev *rtwdev, enum rtw89_fw_type type,
0125 struct rtw89_fw_suit *fw_suit)
0126 {
0127 struct rtw89_fw_info *fw_info = &rtwdev->fw;
0128 const u8 *mfw = fw_info->firmware->data;
0129 u32 mfw_len = fw_info->firmware->size;
0130 const struct rtw89_mfw_hdr *mfw_hdr = (const struct rtw89_mfw_hdr *)mfw;
0131 const struct rtw89_mfw_info *mfw_info;
0132 int i;
0133
0134 if (mfw_hdr->sig != RTW89_MFW_SIG) {
0135 rtw89_debug(rtwdev, RTW89_DBG_FW, "use legacy firmware\n");
0136
0137 if (type != RTW89_FW_NORMAL)
0138 return -EINVAL;
0139 fw_suit->data = mfw;
0140 fw_suit->size = mfw_len;
0141 return 0;
0142 }
0143
0144 for (i = 0; i < mfw_hdr->fw_nr; i++) {
0145 mfw_info = &mfw_hdr->info[i];
0146 if (mfw_info->cv != rtwdev->hal.cv ||
0147 mfw_info->type != type ||
0148 mfw_info->mp)
0149 continue;
0150
0151 fw_suit->data = mfw + le32_to_cpu(mfw_info->shift);
0152 fw_suit->size = le32_to_cpu(mfw_info->size);
0153 return 0;
0154 }
0155
0156 rtw89_err(rtwdev, "no suitable firmware found\n");
0157 return -ENOENT;
0158 }
0159
0160 static void rtw89_fw_update_ver(struct rtw89_dev *rtwdev,
0161 enum rtw89_fw_type type,
0162 struct rtw89_fw_suit *fw_suit)
0163 {
0164 const u8 *hdr = fw_suit->data;
0165
0166 fw_suit->major_ver = GET_FW_HDR_MAJOR_VERSION(hdr);
0167 fw_suit->minor_ver = GET_FW_HDR_MINOR_VERSION(hdr);
0168 fw_suit->sub_ver = GET_FW_HDR_SUBVERSION(hdr);
0169 fw_suit->sub_idex = GET_FW_HDR_SUBINDEX(hdr);
0170 fw_suit->build_year = GET_FW_HDR_YEAR(hdr);
0171 fw_suit->build_mon = GET_FW_HDR_MONTH(hdr);
0172 fw_suit->build_date = GET_FW_HDR_DATE(hdr);
0173 fw_suit->build_hour = GET_FW_HDR_HOUR(hdr);
0174 fw_suit->build_min = GET_FW_HDR_MIN(hdr);
0175 fw_suit->cmd_ver = GET_FW_HDR_CMD_VERSERION(hdr);
0176
0177 rtw89_info(rtwdev,
0178 "Firmware version %u.%u.%u.%u, cmd version %u, type %u\n",
0179 fw_suit->major_ver, fw_suit->minor_ver, fw_suit->sub_ver,
0180 fw_suit->sub_idex, fw_suit->cmd_ver, type);
0181 }
0182
0183 static
0184 int __rtw89_fw_recognize(struct rtw89_dev *rtwdev, enum rtw89_fw_type type)
0185 {
0186 struct rtw89_fw_suit *fw_suit = rtw89_fw_suit_get(rtwdev, type);
0187 int ret;
0188
0189 ret = rtw89_mfw_recognize(rtwdev, type, fw_suit);
0190 if (ret)
0191 return ret;
0192
0193 rtw89_fw_update_ver(rtwdev, type, fw_suit);
0194
0195 return 0;
0196 }
0197
0198 #define __DEF_FW_FEAT_COND(__cond, __op) \
0199 static bool __fw_feat_cond_ ## __cond(u32 suit_ver_code, u32 comp_ver_code) \
0200 { \
0201 return suit_ver_code __op comp_ver_code; \
0202 }
0203
0204 __DEF_FW_FEAT_COND(ge, >=);
0205 __DEF_FW_FEAT_COND(le, <=);
0206
0207 struct __fw_feat_cfg {
0208 enum rtw89_core_chip_id chip_id;
0209 enum rtw89_fw_feature feature;
0210 u32 ver_code;
0211 bool (*cond)(u32 suit_ver_code, u32 comp_ver_code);
0212 };
0213
0214 #define __CFG_FW_FEAT(_chip, _cond, _maj, _min, _sub, _idx, _feat) \
0215 { \
0216 .chip_id = _chip, \
0217 .feature = RTW89_FW_FEATURE_ ## _feat, \
0218 .ver_code = RTW89_FW_VER_CODE(_maj, _min, _sub, _idx), \
0219 .cond = __fw_feat_cond_ ## _cond, \
0220 }
0221
0222 static const struct __fw_feat_cfg fw_feat_tbl[] = {
0223 __CFG_FW_FEAT(RTL8852A, le, 0, 13, 29, 0, OLD_HT_RA_FORMAT),
0224 __CFG_FW_FEAT(RTL8852A, ge, 0, 13, 35, 0, SCAN_OFFLOAD),
0225 __CFG_FW_FEAT(RTL8852A, ge, 0, 13, 35, 0, TX_WAKE),
0226 __CFG_FW_FEAT(RTL8852A, ge, 0, 13, 36, 0, CRASH_TRIGGER),
0227 };
0228
0229 static void rtw89_fw_recognize_features(struct rtw89_dev *rtwdev)
0230 {
0231 const struct rtw89_chip_info *chip = rtwdev->chip;
0232 const struct __fw_feat_cfg *ent;
0233 const struct rtw89_fw_suit *fw_suit;
0234 u32 suit_ver_code;
0235 int i;
0236
0237 fw_suit = rtw89_fw_suit_get(rtwdev, RTW89_FW_NORMAL);
0238 suit_ver_code = RTW89_FW_SUIT_VER_CODE(fw_suit);
0239
0240 for (i = 0; i < ARRAY_SIZE(fw_feat_tbl); i++) {
0241 ent = &fw_feat_tbl[i];
0242 if (chip->chip_id != ent->chip_id)
0243 continue;
0244
0245 if (ent->cond(suit_ver_code, ent->ver_code))
0246 RTW89_SET_FW_FEATURE(ent->feature, &rtwdev->fw);
0247 }
0248 }
0249
0250 int rtw89_fw_recognize(struct rtw89_dev *rtwdev)
0251 {
0252 int ret;
0253
0254 ret = __rtw89_fw_recognize(rtwdev, RTW89_FW_NORMAL);
0255 if (ret)
0256 return ret;
0257
0258
0259 __rtw89_fw_recognize(rtwdev, RTW89_FW_WOWLAN);
0260
0261 rtw89_fw_recognize_features(rtwdev);
0262
0263 return 0;
0264 }
0265
0266 void rtw89_h2c_pkt_set_hdr(struct rtw89_dev *rtwdev, struct sk_buff *skb,
0267 u8 type, u8 cat, u8 class, u8 func,
0268 bool rack, bool dack, u32 len)
0269 {
0270 struct fwcmd_hdr *hdr;
0271
0272 hdr = (struct fwcmd_hdr *)skb_push(skb, 8);
0273
0274 if (!(rtwdev->fw.h2c_seq % 4))
0275 rack = true;
0276 hdr->hdr0 = cpu_to_le32(FIELD_PREP(H2C_HDR_DEL_TYPE, type) |
0277 FIELD_PREP(H2C_HDR_CAT, cat) |
0278 FIELD_PREP(H2C_HDR_CLASS, class) |
0279 FIELD_PREP(H2C_HDR_FUNC, func) |
0280 FIELD_PREP(H2C_HDR_H2C_SEQ, rtwdev->fw.h2c_seq));
0281
0282 hdr->hdr1 = cpu_to_le32(FIELD_PREP(H2C_HDR_TOTAL_LEN,
0283 len + H2C_HEADER_LEN) |
0284 (rack ? H2C_HDR_REC_ACK : 0) |
0285 (dack ? H2C_HDR_DONE_ACK : 0));
0286
0287 rtwdev->fw.h2c_seq++;
0288 }
0289
0290 static void rtw89_h2c_pkt_set_hdr_fwdl(struct rtw89_dev *rtwdev,
0291 struct sk_buff *skb,
0292 u8 type, u8 cat, u8 class, u8 func,
0293 u32 len)
0294 {
0295 struct fwcmd_hdr *hdr;
0296
0297 hdr = (struct fwcmd_hdr *)skb_push(skb, 8);
0298
0299 hdr->hdr0 = cpu_to_le32(FIELD_PREP(H2C_HDR_DEL_TYPE, type) |
0300 FIELD_PREP(H2C_HDR_CAT, cat) |
0301 FIELD_PREP(H2C_HDR_CLASS, class) |
0302 FIELD_PREP(H2C_HDR_FUNC, func) |
0303 FIELD_PREP(H2C_HDR_H2C_SEQ, rtwdev->fw.h2c_seq));
0304
0305 hdr->hdr1 = cpu_to_le32(FIELD_PREP(H2C_HDR_TOTAL_LEN,
0306 len + H2C_HEADER_LEN));
0307 }
0308
0309 static int __rtw89_fw_download_hdr(struct rtw89_dev *rtwdev, const u8 *fw, u32 len)
0310 {
0311 struct sk_buff *skb;
0312 u32 ret = 0;
0313
0314 skb = rtw89_fw_h2c_alloc_skb_with_hdr(rtwdev, len);
0315 if (!skb) {
0316 rtw89_err(rtwdev, "failed to alloc skb for fw hdr dl\n");
0317 return -ENOMEM;
0318 }
0319
0320 skb_put_data(skb, fw, len);
0321 SET_FW_HDR_PART_SIZE(skb->data, FWDL_SECTION_PER_PKT_LEN);
0322 rtw89_h2c_pkt_set_hdr_fwdl(rtwdev, skb, FWCMD_TYPE_H2C,
0323 H2C_CAT_MAC, H2C_CL_MAC_FWDL,
0324 H2C_FUNC_MAC_FWHDR_DL, len);
0325
0326 ret = rtw89_h2c_tx(rtwdev, skb, false);
0327 if (ret) {
0328 rtw89_err(rtwdev, "failed to send h2c\n");
0329 ret = -1;
0330 goto fail;
0331 }
0332
0333 return 0;
0334 fail:
0335 dev_kfree_skb_any(skb);
0336
0337 return ret;
0338 }
0339
0340 static int rtw89_fw_download_hdr(struct rtw89_dev *rtwdev, const u8 *fw, u32 len)
0341 {
0342 u8 val;
0343 int ret;
0344
0345 ret = __rtw89_fw_download_hdr(rtwdev, fw, len);
0346 if (ret) {
0347 rtw89_err(rtwdev, "[ERR]FW header download\n");
0348 return ret;
0349 }
0350
0351 ret = read_poll_timeout_atomic(rtw89_read8, val, val & B_AX_FWDL_PATH_RDY,
0352 1, FWDL_WAIT_CNT, false,
0353 rtwdev, R_AX_WCPU_FW_CTRL);
0354 if (ret) {
0355 rtw89_err(rtwdev, "[ERR]FWDL path ready\n");
0356 return ret;
0357 }
0358
0359 rtw89_write32(rtwdev, R_AX_HALT_H2C_CTRL, 0);
0360 rtw89_write32(rtwdev, R_AX_HALT_C2H_CTRL, 0);
0361
0362 return 0;
0363 }
0364
0365 static int __rtw89_fw_download_main(struct rtw89_dev *rtwdev,
0366 struct rtw89_fw_hdr_section_info *info)
0367 {
0368 struct sk_buff *skb;
0369 const u8 *section = info->addr;
0370 u32 residue_len = info->len;
0371 u32 pkt_len;
0372 int ret;
0373
0374 while (residue_len) {
0375 if (residue_len >= FWDL_SECTION_PER_PKT_LEN)
0376 pkt_len = FWDL_SECTION_PER_PKT_LEN;
0377 else
0378 pkt_len = residue_len;
0379
0380 skb = rtw89_fw_h2c_alloc_skb_no_hdr(rtwdev, pkt_len);
0381 if (!skb) {
0382 rtw89_err(rtwdev, "failed to alloc skb for fw dl\n");
0383 return -ENOMEM;
0384 }
0385 skb_put_data(skb, section, pkt_len);
0386
0387 ret = rtw89_h2c_tx(rtwdev, skb, true);
0388 if (ret) {
0389 rtw89_err(rtwdev, "failed to send h2c\n");
0390 ret = -1;
0391 goto fail;
0392 }
0393
0394 section += pkt_len;
0395 residue_len -= pkt_len;
0396 }
0397
0398 return 0;
0399 fail:
0400 dev_kfree_skb_any(skb);
0401
0402 return ret;
0403 }
0404
0405 static int rtw89_fw_download_main(struct rtw89_dev *rtwdev, const u8 *fw,
0406 struct rtw89_fw_bin_info *info)
0407 {
0408 struct rtw89_fw_hdr_section_info *section_info = info->section_info;
0409 u8 section_num = info->section_num;
0410 int ret;
0411
0412 while (section_num--) {
0413 ret = __rtw89_fw_download_main(rtwdev, section_info);
0414 if (ret)
0415 return ret;
0416 section_info++;
0417 }
0418
0419 mdelay(5);
0420
0421 ret = rtw89_fw_check_rdy(rtwdev);
0422 if (ret) {
0423 rtw89_warn(rtwdev, "download firmware fail\n");
0424 return ret;
0425 }
0426
0427 return 0;
0428 }
0429
0430 static void rtw89_fw_prog_cnt_dump(struct rtw89_dev *rtwdev)
0431 {
0432 u32 val32;
0433 u16 index;
0434
0435 rtw89_write32(rtwdev, R_AX_DBG_CTRL,
0436 FIELD_PREP(B_AX_DBG_SEL0, FW_PROG_CNTR_DBG_SEL) |
0437 FIELD_PREP(B_AX_DBG_SEL1, FW_PROG_CNTR_DBG_SEL));
0438 rtw89_write32_mask(rtwdev, R_AX_SYS_STATUS1, B_AX_SEL_0XC0_MASK, MAC_DBG_SEL);
0439
0440 for (index = 0; index < 15; index++) {
0441 val32 = rtw89_read32(rtwdev, R_AX_DBG_PORT_SEL);
0442 rtw89_err(rtwdev, "[ERR]fw PC = 0x%x\n", val32);
0443 fsleep(10);
0444 }
0445 }
0446
0447 static void rtw89_fw_dl_fail_dump(struct rtw89_dev *rtwdev)
0448 {
0449 u32 val32;
0450 u16 val16;
0451
0452 val32 = rtw89_read32(rtwdev, R_AX_WCPU_FW_CTRL);
0453 rtw89_err(rtwdev, "[ERR]fwdl 0x1E0 = 0x%x\n", val32);
0454
0455 val16 = rtw89_read16(rtwdev, R_AX_BOOT_DBG + 2);
0456 rtw89_err(rtwdev, "[ERR]fwdl 0x83F2 = 0x%x\n", val16);
0457
0458 rtw89_fw_prog_cnt_dump(rtwdev);
0459 }
0460
0461 int rtw89_fw_download(struct rtw89_dev *rtwdev, enum rtw89_fw_type type)
0462 {
0463 struct rtw89_fw_info *fw_info = &rtwdev->fw;
0464 struct rtw89_fw_suit *fw_suit = rtw89_fw_suit_get(rtwdev, type);
0465 struct rtw89_fw_bin_info info;
0466 const u8 *fw = fw_suit->data;
0467 u32 len = fw_suit->size;
0468 u8 val;
0469 int ret;
0470
0471 if (!fw || !len) {
0472 rtw89_err(rtwdev, "fw type %d isn't recognized\n", type);
0473 return -ENOENT;
0474 }
0475
0476 ret = rtw89_fw_hdr_parser(rtwdev, fw, len, &info);
0477 if (ret) {
0478 rtw89_err(rtwdev, "parse fw header fail\n");
0479 goto fwdl_err;
0480 }
0481
0482 ret = read_poll_timeout_atomic(rtw89_read8, val, val & B_AX_H2C_PATH_RDY,
0483 1, FWDL_WAIT_CNT, false,
0484 rtwdev, R_AX_WCPU_FW_CTRL);
0485 if (ret) {
0486 rtw89_err(rtwdev, "[ERR]H2C path ready\n");
0487 goto fwdl_err;
0488 }
0489
0490 ret = rtw89_fw_download_hdr(rtwdev, fw, info.hdr_len);
0491 if (ret) {
0492 ret = -EBUSY;
0493 goto fwdl_err;
0494 }
0495
0496 ret = rtw89_fw_download_main(rtwdev, fw, &info);
0497 if (ret) {
0498 ret = -EBUSY;
0499 goto fwdl_err;
0500 }
0501
0502 fw_info->h2c_seq = 0;
0503 fw_info->rec_seq = 0;
0504 rtwdev->mac.rpwm_seq_num = RPWM_SEQ_NUM_MAX;
0505 rtwdev->mac.cpwm_seq_num = CPWM_SEQ_NUM_MAX;
0506
0507 return ret;
0508
0509 fwdl_err:
0510 rtw89_fw_dl_fail_dump(rtwdev);
0511 return ret;
0512 }
0513
0514 int rtw89_wait_firmware_completion(struct rtw89_dev *rtwdev)
0515 {
0516 struct rtw89_fw_info *fw = &rtwdev->fw;
0517
0518 wait_for_completion(&fw->completion);
0519 if (!fw->firmware)
0520 return -EINVAL;
0521
0522 return 0;
0523 }
0524
0525 static void rtw89_load_firmware_cb(const struct firmware *firmware, void *context)
0526 {
0527 struct rtw89_fw_info *fw = context;
0528 struct rtw89_dev *rtwdev = fw->rtwdev;
0529
0530 if (!firmware || !firmware->data) {
0531 rtw89_err(rtwdev, "failed to request firmware\n");
0532 complete_all(&fw->completion);
0533 return;
0534 }
0535
0536 fw->firmware = firmware;
0537 complete_all(&fw->completion);
0538 }
0539
0540 int rtw89_load_firmware(struct rtw89_dev *rtwdev)
0541 {
0542 struct rtw89_fw_info *fw = &rtwdev->fw;
0543 const char *fw_name = rtwdev->chip->fw_name;
0544 int ret;
0545
0546 fw->rtwdev = rtwdev;
0547 init_completion(&fw->completion);
0548
0549 ret = request_firmware_nowait(THIS_MODULE, true, fw_name, rtwdev->dev,
0550 GFP_KERNEL, fw, rtw89_load_firmware_cb);
0551 if (ret) {
0552 rtw89_err(rtwdev, "failed to async firmware request\n");
0553 return ret;
0554 }
0555
0556 return 0;
0557 }
0558
0559 void rtw89_unload_firmware(struct rtw89_dev *rtwdev)
0560 {
0561 struct rtw89_fw_info *fw = &rtwdev->fw;
0562
0563 rtw89_wait_firmware_completion(rtwdev);
0564
0565 if (fw->firmware)
0566 release_firmware(fw->firmware);
0567 }
0568
0569 #define H2C_CAM_LEN 60
0570 int rtw89_fw_h2c_cam(struct rtw89_dev *rtwdev, struct rtw89_vif *rtwvif,
0571 struct rtw89_sta *rtwsta, const u8 *scan_mac_addr)
0572 {
0573 struct sk_buff *skb;
0574
0575 skb = rtw89_fw_h2c_alloc_skb_with_hdr(rtwdev, H2C_CAM_LEN);
0576 if (!skb) {
0577 rtw89_err(rtwdev, "failed to alloc skb for fw dl\n");
0578 return -ENOMEM;
0579 }
0580 skb_put(skb, H2C_CAM_LEN);
0581 rtw89_cam_fill_addr_cam_info(rtwdev, rtwvif, rtwsta, scan_mac_addr, skb->data);
0582 rtw89_cam_fill_bssid_cam_info(rtwdev, rtwvif, rtwsta, skb->data);
0583
0584 rtw89_h2c_pkt_set_hdr(rtwdev, skb, FWCMD_TYPE_H2C,
0585 H2C_CAT_MAC,
0586 H2C_CL_MAC_ADDR_CAM_UPDATE,
0587 H2C_FUNC_MAC_ADDR_CAM_UPD, 0, 1,
0588 H2C_CAM_LEN);
0589
0590 if (rtw89_h2c_tx(rtwdev, skb, false)) {
0591 rtw89_err(rtwdev, "failed to send h2c\n");
0592 goto fail;
0593 }
0594
0595 return 0;
0596 fail:
0597 dev_kfree_skb_any(skb);
0598
0599 return -EBUSY;
0600 }
0601
0602 #define H2C_DCTL_SEC_CAM_LEN 68
0603 int rtw89_fw_h2c_dctl_sec_cam_v1(struct rtw89_dev *rtwdev,
0604 struct rtw89_vif *rtwvif,
0605 struct rtw89_sta *rtwsta)
0606 {
0607 struct sk_buff *skb;
0608
0609 skb = rtw89_fw_h2c_alloc_skb_with_hdr(rtwdev, H2C_DCTL_SEC_CAM_LEN);
0610 if (!skb) {
0611 rtw89_err(rtwdev, "failed to alloc skb for dctl sec cam\n");
0612 return -ENOMEM;
0613 }
0614 skb_put(skb, H2C_DCTL_SEC_CAM_LEN);
0615
0616 rtw89_cam_fill_dctl_sec_cam_info_v1(rtwdev, rtwvif, rtwsta, skb->data);
0617
0618 rtw89_h2c_pkt_set_hdr(rtwdev, skb, FWCMD_TYPE_H2C,
0619 H2C_CAT_MAC,
0620 H2C_CL_MAC_FR_EXCHG,
0621 H2C_FUNC_MAC_DCTLINFO_UD_V1, 0, 0,
0622 H2C_DCTL_SEC_CAM_LEN);
0623
0624 if (rtw89_h2c_tx(rtwdev, skb, false)) {
0625 rtw89_err(rtwdev, "failed to send h2c\n");
0626 goto fail;
0627 }
0628
0629 return 0;
0630 fail:
0631 dev_kfree_skb_any(skb);
0632
0633 return -EBUSY;
0634 }
0635 EXPORT_SYMBOL(rtw89_fw_h2c_dctl_sec_cam_v1);
0636
0637 #define H2C_BA_CAM_LEN 8
0638 int rtw89_fw_h2c_ba_cam(struct rtw89_dev *rtwdev, struct rtw89_sta *rtwsta,
0639 bool valid, struct ieee80211_ampdu_params *params)
0640 {
0641 u8 macid = rtwsta->mac_id;
0642 struct sk_buff *skb;
0643 u8 entry_idx;
0644 int ret;
0645
0646 ret = valid ?
0647 rtw89_core_acquire_sta_ba_entry(rtwsta, params->tid, &entry_idx) :
0648 rtw89_core_release_sta_ba_entry(rtwsta, params->tid, &entry_idx);
0649 if (ret) {
0650
0651
0652
0653 rtw89_debug(rtwdev, RTW89_DBG_TXRX,
0654 "failed to %s entry tid=%d for h2c ba cam\n",
0655 valid ? "alloc" : "free", params->tid);
0656 return 0;
0657 }
0658
0659 skb = rtw89_fw_h2c_alloc_skb_with_hdr(rtwdev, H2C_BA_CAM_LEN);
0660 if (!skb) {
0661 rtw89_err(rtwdev, "failed to alloc skb for h2c ba cam\n");
0662 return -ENOMEM;
0663 }
0664 skb_put(skb, H2C_BA_CAM_LEN);
0665 SET_BA_CAM_MACID(skb->data, macid);
0666 SET_BA_CAM_ENTRY_IDX(skb->data, entry_idx);
0667 if (!valid)
0668 goto end;
0669 SET_BA_CAM_VALID(skb->data, valid);
0670 SET_BA_CAM_TID(skb->data, params->tid);
0671 if (params->buf_size > 64)
0672 SET_BA_CAM_BMAP_SIZE(skb->data, 4);
0673 else
0674 SET_BA_CAM_BMAP_SIZE(skb->data, 0);
0675
0676 SET_BA_CAM_INIT_REQ(skb->data, 1);
0677 SET_BA_CAM_SSN(skb->data, params->ssn);
0678
0679 end:
0680 rtw89_h2c_pkt_set_hdr(rtwdev, skb, FWCMD_TYPE_H2C,
0681 H2C_CAT_MAC,
0682 H2C_CL_BA_CAM,
0683 H2C_FUNC_MAC_BA_CAM, 0, 1,
0684 H2C_BA_CAM_LEN);
0685
0686 if (rtw89_h2c_tx(rtwdev, skb, false)) {
0687 rtw89_err(rtwdev, "failed to send h2c\n");
0688 goto fail;
0689 }
0690
0691 return 0;
0692 fail:
0693 dev_kfree_skb_any(skb);
0694
0695 return -EBUSY;
0696 }
0697
0698 #define H2C_LOG_CFG_LEN 12
0699 int rtw89_fw_h2c_fw_log(struct rtw89_dev *rtwdev, bool enable)
0700 {
0701 struct sk_buff *skb;
0702 u32 comp = enable ? BIT(RTW89_FW_LOG_COMP_INIT) | BIT(RTW89_FW_LOG_COMP_TASK) |
0703 BIT(RTW89_FW_LOG_COMP_PS) | BIT(RTW89_FW_LOG_COMP_ERROR) : 0;
0704
0705 skb = rtw89_fw_h2c_alloc_skb_with_hdr(rtwdev, H2C_LOG_CFG_LEN);
0706 if (!skb) {
0707 rtw89_err(rtwdev, "failed to alloc skb for fw log cfg\n");
0708 return -ENOMEM;
0709 }
0710
0711 skb_put(skb, H2C_LOG_CFG_LEN);
0712 SET_LOG_CFG_LEVEL(skb->data, RTW89_FW_LOG_LEVEL_SER);
0713 SET_LOG_CFG_PATH(skb->data, BIT(RTW89_FW_LOG_LEVEL_C2H));
0714 SET_LOG_CFG_COMP(skb->data, comp);
0715 SET_LOG_CFG_COMP_EXT(skb->data, 0);
0716
0717 rtw89_h2c_pkt_set_hdr(rtwdev, skb, FWCMD_TYPE_H2C,
0718 H2C_CAT_MAC,
0719 H2C_CL_FW_INFO,
0720 H2C_FUNC_LOG_CFG, 0, 0,
0721 H2C_LOG_CFG_LEN);
0722
0723 if (rtw89_h2c_tx(rtwdev, skb, false)) {
0724 rtw89_err(rtwdev, "failed to send h2c\n");
0725 goto fail;
0726 }
0727
0728 return 0;
0729 fail:
0730 dev_kfree_skb_any(skb);
0731
0732 return -EBUSY;
0733 }
0734
0735 #define H2C_GENERAL_PKT_LEN 6
0736 #define H2C_GENERAL_PKT_ID_UND 0xff
0737 int rtw89_fw_h2c_general_pkt(struct rtw89_dev *rtwdev, u8 macid)
0738 {
0739 struct sk_buff *skb;
0740
0741 skb = rtw89_fw_h2c_alloc_skb_with_hdr(rtwdev, H2C_GENERAL_PKT_LEN);
0742 if (!skb) {
0743 rtw89_err(rtwdev, "failed to alloc skb for fw dl\n");
0744 return -ENOMEM;
0745 }
0746 skb_put(skb, H2C_GENERAL_PKT_LEN);
0747 SET_GENERAL_PKT_MACID(skb->data, macid);
0748 SET_GENERAL_PKT_PROBRSP_ID(skb->data, H2C_GENERAL_PKT_ID_UND);
0749 SET_GENERAL_PKT_PSPOLL_ID(skb->data, H2C_GENERAL_PKT_ID_UND);
0750 SET_GENERAL_PKT_NULL_ID(skb->data, H2C_GENERAL_PKT_ID_UND);
0751 SET_GENERAL_PKT_QOS_NULL_ID(skb->data, H2C_GENERAL_PKT_ID_UND);
0752 SET_GENERAL_PKT_CTS2SELF_ID(skb->data, H2C_GENERAL_PKT_ID_UND);
0753
0754 rtw89_h2c_pkt_set_hdr(rtwdev, skb, FWCMD_TYPE_H2C,
0755 H2C_CAT_MAC,
0756 H2C_CL_FW_INFO,
0757 H2C_FUNC_MAC_GENERAL_PKT, 0, 1,
0758 H2C_GENERAL_PKT_LEN);
0759
0760 if (rtw89_h2c_tx(rtwdev, skb, false)) {
0761 rtw89_err(rtwdev, "failed to send h2c\n");
0762 goto fail;
0763 }
0764
0765 return 0;
0766 fail:
0767 dev_kfree_skb_any(skb);
0768
0769 return -EBUSY;
0770 }
0771
0772 #define H2C_LPS_PARM_LEN 8
0773 int rtw89_fw_h2c_lps_parm(struct rtw89_dev *rtwdev,
0774 struct rtw89_lps_parm *lps_param)
0775 {
0776 struct sk_buff *skb;
0777
0778 skb = rtw89_fw_h2c_alloc_skb_with_hdr(rtwdev, H2C_LPS_PARM_LEN);
0779 if (!skb) {
0780 rtw89_err(rtwdev, "failed to alloc skb for fw dl\n");
0781 return -ENOMEM;
0782 }
0783 skb_put(skb, H2C_LPS_PARM_LEN);
0784
0785 SET_LPS_PARM_MACID(skb->data, lps_param->macid);
0786 SET_LPS_PARM_PSMODE(skb->data, lps_param->psmode);
0787 SET_LPS_PARM_LASTRPWM(skb->data, lps_param->lastrpwm);
0788 SET_LPS_PARM_RLBM(skb->data, 1);
0789 SET_LPS_PARM_SMARTPS(skb->data, 1);
0790 SET_LPS_PARM_AWAKEINTERVAL(skb->data, 1);
0791 SET_LPS_PARM_VOUAPSD(skb->data, 0);
0792 SET_LPS_PARM_VIUAPSD(skb->data, 0);
0793 SET_LPS_PARM_BEUAPSD(skb->data, 0);
0794 SET_LPS_PARM_BKUAPSD(skb->data, 0);
0795
0796 rtw89_h2c_pkt_set_hdr(rtwdev, skb, FWCMD_TYPE_H2C,
0797 H2C_CAT_MAC,
0798 H2C_CL_MAC_PS,
0799 H2C_FUNC_MAC_LPS_PARM, 0, 1,
0800 H2C_LPS_PARM_LEN);
0801
0802 if (rtw89_h2c_tx(rtwdev, skb, false)) {
0803 rtw89_err(rtwdev, "failed to send h2c\n");
0804 goto fail;
0805 }
0806
0807 return 0;
0808 fail:
0809 dev_kfree_skb_any(skb);
0810
0811 return -EBUSY;
0812 }
0813
0814 #define H2C_CMC_TBL_LEN 68
0815 int rtw89_fw_h2c_default_cmac_tbl(struct rtw89_dev *rtwdev,
0816 struct rtw89_vif *rtwvif)
0817 {
0818 const struct rtw89_chip_info *chip = rtwdev->chip;
0819 struct rtw89_hal *hal = &rtwdev->hal;
0820 struct sk_buff *skb;
0821 u8 ntx_path = hal->antenna_tx ? hal->antenna_tx : RF_B;
0822 u8 map_b = hal->antenna_tx == RF_AB ? 1 : 0;
0823 u8 macid = rtwvif->mac_id;
0824
0825 skb = rtw89_fw_h2c_alloc_skb_with_hdr(rtwdev, H2C_CMC_TBL_LEN);
0826 if (!skb) {
0827 rtw89_err(rtwdev, "failed to alloc skb for fw dl\n");
0828 return -ENOMEM;
0829 }
0830 skb_put(skb, H2C_CMC_TBL_LEN);
0831 SET_CTRL_INFO_MACID(skb->data, macid);
0832 SET_CTRL_INFO_OPERATION(skb->data, 1);
0833 if (chip->h2c_cctl_func_id == H2C_FUNC_MAC_CCTLINFO_UD) {
0834 SET_CMC_TBL_TXPWR_MODE(skb->data, 0);
0835 SET_CMC_TBL_NTX_PATH_EN(skb->data, ntx_path);
0836 SET_CMC_TBL_PATH_MAP_A(skb->data, 0);
0837 SET_CMC_TBL_PATH_MAP_B(skb->data, map_b);
0838 SET_CMC_TBL_PATH_MAP_C(skb->data, 0);
0839 SET_CMC_TBL_PATH_MAP_D(skb->data, 0);
0840 SET_CMC_TBL_ANTSEL_A(skb->data, 0);
0841 SET_CMC_TBL_ANTSEL_B(skb->data, 0);
0842 SET_CMC_TBL_ANTSEL_C(skb->data, 0);
0843 SET_CMC_TBL_ANTSEL_D(skb->data, 0);
0844 }
0845 SET_CMC_TBL_DOPPLER_CTRL(skb->data, 0);
0846 SET_CMC_TBL_TXPWR_TOLERENCE(skb->data, 0);
0847 if (rtwvif->net_type == RTW89_NET_TYPE_AP_MODE)
0848 SET_CMC_TBL_DATA_DCM(skb->data, 0);
0849
0850 rtw89_h2c_pkt_set_hdr(rtwdev, skb, FWCMD_TYPE_H2C,
0851 H2C_CAT_MAC, H2C_CL_MAC_FR_EXCHG,
0852 chip->h2c_cctl_func_id, 0, 1,
0853 H2C_CMC_TBL_LEN);
0854
0855 if (rtw89_h2c_tx(rtwdev, skb, false)) {
0856 rtw89_err(rtwdev, "failed to send h2c\n");
0857 goto fail;
0858 }
0859
0860 return 0;
0861 fail:
0862 dev_kfree_skb_any(skb);
0863
0864 return -EBUSY;
0865 }
0866
0867 static void __get_sta_he_pkt_padding(struct rtw89_dev *rtwdev,
0868 struct ieee80211_sta *sta, u8 *pads)
0869 {
0870 bool ppe_th;
0871 u8 ppe16, ppe8;
0872 u8 nss = min(sta->deflink.rx_nss, rtwdev->hal.tx_nss) - 1;
0873 u8 ppe_thres_hdr = sta->deflink.he_cap.ppe_thres[0];
0874 u8 ru_bitmap;
0875 u8 n, idx, sh;
0876 u16 ppe;
0877 int i;
0878
0879 if (!sta->deflink.he_cap.has_he)
0880 return;
0881
0882 ppe_th = FIELD_GET(IEEE80211_HE_PHY_CAP6_PPE_THRESHOLD_PRESENT,
0883 sta->deflink.he_cap.he_cap_elem.phy_cap_info[6]);
0884 if (!ppe_th) {
0885 u8 pad;
0886
0887 pad = FIELD_GET(IEEE80211_HE_PHY_CAP9_NOMINAL_PKT_PADDING_MASK,
0888 sta->deflink.he_cap.he_cap_elem.phy_cap_info[9]);
0889
0890 for (i = 0; i < RTW89_PPE_BW_NUM; i++)
0891 pads[i] = pad;
0892
0893 return;
0894 }
0895
0896 ru_bitmap = FIELD_GET(IEEE80211_PPE_THRES_RU_INDEX_BITMASK_MASK, ppe_thres_hdr);
0897 n = hweight8(ru_bitmap);
0898 n = 7 + (n * IEEE80211_PPE_THRES_INFO_PPET_SIZE * 2) * nss;
0899
0900 for (i = 0; i < RTW89_PPE_BW_NUM; i++) {
0901 if (!(ru_bitmap & BIT(i))) {
0902 pads[i] = 1;
0903 continue;
0904 }
0905
0906 idx = n >> 3;
0907 sh = n & 7;
0908 n += IEEE80211_PPE_THRES_INFO_PPET_SIZE * 2;
0909
0910 ppe = le16_to_cpu(*((__le16 *)&sta->deflink.he_cap.ppe_thres[idx]));
0911 ppe16 = (ppe >> sh) & IEEE80211_PPE_THRES_NSS_MASK;
0912 sh += IEEE80211_PPE_THRES_INFO_PPET_SIZE;
0913 ppe8 = (ppe >> sh) & IEEE80211_PPE_THRES_NSS_MASK;
0914
0915 if (ppe16 != 7 && ppe8 == 7)
0916 pads[i] = 2;
0917 else if (ppe8 != 7)
0918 pads[i] = 1;
0919 else
0920 pads[i] = 0;
0921 }
0922 }
0923
0924 int rtw89_fw_h2c_assoc_cmac_tbl(struct rtw89_dev *rtwdev,
0925 struct ieee80211_vif *vif,
0926 struct ieee80211_sta *sta)
0927 {
0928 const struct rtw89_chip_info *chip = rtwdev->chip;
0929 struct rtw89_hal *hal = &rtwdev->hal;
0930 struct rtw89_sta *rtwsta = sta_to_rtwsta_safe(sta);
0931 struct rtw89_vif *rtwvif = (struct rtw89_vif *)vif->drv_priv;
0932 struct sk_buff *skb;
0933 u8 pads[RTW89_PPE_BW_NUM];
0934 u8 mac_id = rtwsta ? rtwsta->mac_id : rtwvif->mac_id;
0935
0936 memset(pads, 0, sizeof(pads));
0937 if (sta)
0938 __get_sta_he_pkt_padding(rtwdev, sta, pads);
0939
0940 skb = rtw89_fw_h2c_alloc_skb_with_hdr(rtwdev, H2C_CMC_TBL_LEN);
0941 if (!skb) {
0942 rtw89_err(rtwdev, "failed to alloc skb for fw dl\n");
0943 return -ENOMEM;
0944 }
0945 skb_put(skb, H2C_CMC_TBL_LEN);
0946 SET_CTRL_INFO_MACID(skb->data, mac_id);
0947 SET_CTRL_INFO_OPERATION(skb->data, 1);
0948 SET_CMC_TBL_DISRTSFB(skb->data, 1);
0949 SET_CMC_TBL_DISDATAFB(skb->data, 1);
0950 if (hal->current_band_type == RTW89_BAND_2G)
0951 SET_CMC_TBL_RTS_RTY_LOWEST_RATE(skb->data, RTW89_HW_RATE_CCK1);
0952 else
0953 SET_CMC_TBL_RTS_RTY_LOWEST_RATE(skb->data, RTW89_HW_RATE_OFDM6);
0954 SET_CMC_TBL_RTS_TXCNT_LMT_SEL(skb->data, 0);
0955 SET_CMC_TBL_DATA_TXCNT_LMT_SEL(skb->data, 0);
0956 if (vif->type == NL80211_IFTYPE_STATION)
0957 SET_CMC_TBL_ULDL(skb->data, 1);
0958 else
0959 SET_CMC_TBL_ULDL(skb->data, 0);
0960 SET_CMC_TBL_MULTI_PORT_ID(skb->data, rtwvif->port);
0961 if (chip->h2c_cctl_func_id == H2C_FUNC_MAC_CCTLINFO_UD_V1) {
0962 SET_CMC_TBL_NOMINAL_PKT_PADDING_V1(skb->data, pads[RTW89_CHANNEL_WIDTH_20]);
0963 SET_CMC_TBL_NOMINAL_PKT_PADDING40_V1(skb->data, pads[RTW89_CHANNEL_WIDTH_40]);
0964 SET_CMC_TBL_NOMINAL_PKT_PADDING80_V1(skb->data, pads[RTW89_CHANNEL_WIDTH_80]);
0965 SET_CMC_TBL_NOMINAL_PKT_PADDING160_V1(skb->data, pads[RTW89_CHANNEL_WIDTH_160]);
0966 } else if (chip->h2c_cctl_func_id == H2C_FUNC_MAC_CCTLINFO_UD) {
0967 SET_CMC_TBL_NOMINAL_PKT_PADDING(skb->data, pads[RTW89_CHANNEL_WIDTH_20]);
0968 SET_CMC_TBL_NOMINAL_PKT_PADDING40(skb->data, pads[RTW89_CHANNEL_WIDTH_40]);
0969 SET_CMC_TBL_NOMINAL_PKT_PADDING80(skb->data, pads[RTW89_CHANNEL_WIDTH_80]);
0970 SET_CMC_TBL_NOMINAL_PKT_PADDING160(skb->data, pads[RTW89_CHANNEL_WIDTH_160]);
0971 }
0972 if (sta)
0973 SET_CMC_TBL_BSR_QUEUE_SIZE_FORMAT(skb->data,
0974 sta->deflink.he_cap.has_he);
0975 if (rtwvif->net_type == RTW89_NET_TYPE_AP_MODE)
0976 SET_CMC_TBL_DATA_DCM(skb->data, 0);
0977
0978 rtw89_h2c_pkt_set_hdr(rtwdev, skb, FWCMD_TYPE_H2C,
0979 H2C_CAT_MAC, H2C_CL_MAC_FR_EXCHG,
0980 chip->h2c_cctl_func_id, 0, 1,
0981 H2C_CMC_TBL_LEN);
0982
0983 if (rtw89_h2c_tx(rtwdev, skb, false)) {
0984 rtw89_err(rtwdev, "failed to send h2c\n");
0985 goto fail;
0986 }
0987
0988 return 0;
0989 fail:
0990 dev_kfree_skb_any(skb);
0991
0992 return -EBUSY;
0993 }
0994
0995 int rtw89_fw_h2c_txtime_cmac_tbl(struct rtw89_dev *rtwdev,
0996 struct rtw89_sta *rtwsta)
0997 {
0998 const struct rtw89_chip_info *chip = rtwdev->chip;
0999 struct sk_buff *skb;
1000
1001 skb = rtw89_fw_h2c_alloc_skb_with_hdr(rtwdev, H2C_CMC_TBL_LEN);
1002 if (!skb) {
1003 rtw89_err(rtwdev, "failed to alloc skb for fw dl\n");
1004 return -ENOMEM;
1005 }
1006 skb_put(skb, H2C_CMC_TBL_LEN);
1007 SET_CTRL_INFO_MACID(skb->data, rtwsta->mac_id);
1008 SET_CTRL_INFO_OPERATION(skb->data, 1);
1009 if (rtwsta->cctl_tx_time) {
1010 SET_CMC_TBL_AMPDU_TIME_SEL(skb->data, 1);
1011 SET_CMC_TBL_AMPDU_MAX_TIME(skb->data, rtwsta->ampdu_max_time);
1012 }
1013 if (rtwsta->cctl_tx_retry_limit) {
1014 SET_CMC_TBL_DATA_TXCNT_LMT_SEL(skb->data, 1);
1015 SET_CMC_TBL_DATA_TX_CNT_LMT(skb->data, rtwsta->data_tx_cnt_lmt);
1016 }
1017
1018 rtw89_h2c_pkt_set_hdr(rtwdev, skb, FWCMD_TYPE_H2C,
1019 H2C_CAT_MAC, H2C_CL_MAC_FR_EXCHG,
1020 chip->h2c_cctl_func_id, 0, 1,
1021 H2C_CMC_TBL_LEN);
1022
1023 if (rtw89_h2c_tx(rtwdev, skb, false)) {
1024 rtw89_err(rtwdev, "failed to send h2c\n");
1025 goto fail;
1026 }
1027
1028 return 0;
1029 fail:
1030 dev_kfree_skb_any(skb);
1031
1032 return -EBUSY;
1033 }
1034
1035 #define H2C_BCN_BASE_LEN 12
1036 int rtw89_fw_h2c_update_beacon(struct rtw89_dev *rtwdev,
1037 struct rtw89_vif *rtwvif)
1038 {
1039 struct rtw89_hal *hal = &rtwdev->hal;
1040 struct ieee80211_vif *vif = rtwvif_to_vif(rtwvif);
1041 struct sk_buff *skb;
1042 struct sk_buff *skb_beacon;
1043 u16 tim_offset;
1044 int bcn_total_len;
1045
1046 skb_beacon = ieee80211_beacon_get_tim(rtwdev->hw, vif, &tim_offset,
1047 NULL, 0);
1048 if (!skb_beacon) {
1049 rtw89_err(rtwdev, "failed to get beacon skb\n");
1050 return -ENOMEM;
1051 }
1052
1053 bcn_total_len = H2C_BCN_BASE_LEN + skb_beacon->len;
1054 skb = rtw89_fw_h2c_alloc_skb_with_hdr(rtwdev, bcn_total_len);
1055 if (!skb) {
1056 rtw89_err(rtwdev, "failed to alloc skb for fw dl\n");
1057 dev_kfree_skb_any(skb_beacon);
1058 return -ENOMEM;
1059 }
1060 skb_put(skb, H2C_BCN_BASE_LEN);
1061
1062 SET_BCN_UPD_PORT(skb->data, rtwvif->port);
1063 SET_BCN_UPD_MBSSID(skb->data, 0);
1064 SET_BCN_UPD_BAND(skb->data, rtwvif->mac_idx);
1065 SET_BCN_UPD_GRP_IE_OFST(skb->data, tim_offset);
1066 SET_BCN_UPD_MACID(skb->data, rtwvif->mac_id);
1067 SET_BCN_UPD_SSN_SEL(skb->data, RTW89_MGMT_HW_SSN_SEL);
1068 SET_BCN_UPD_SSN_MODE(skb->data, RTW89_MGMT_HW_SEQ_MODE);
1069 SET_BCN_UPD_RATE(skb->data, hal->current_band_type == RTW89_BAND_2G ?
1070 RTW89_HW_RATE_CCK1 : RTW89_HW_RATE_OFDM6);
1071
1072 skb_put_data(skb, skb_beacon->data, skb_beacon->len);
1073 dev_kfree_skb_any(skb_beacon);
1074
1075 rtw89_h2c_pkt_set_hdr(rtwdev, skb, FWCMD_TYPE_H2C,
1076 H2C_CAT_MAC, H2C_CL_MAC_FR_EXCHG,
1077 H2C_FUNC_MAC_BCN_UPD, 0, 1,
1078 bcn_total_len);
1079
1080 if (rtw89_h2c_tx(rtwdev, skb, false)) {
1081 rtw89_err(rtwdev, "failed to send h2c\n");
1082 dev_kfree_skb_any(skb);
1083 return -EBUSY;
1084 }
1085
1086 return 0;
1087 }
1088
1089 #define H2C_ROLE_MAINTAIN_LEN 4
1090 int rtw89_fw_h2c_role_maintain(struct rtw89_dev *rtwdev,
1091 struct rtw89_vif *rtwvif,
1092 struct rtw89_sta *rtwsta,
1093 enum rtw89_upd_mode upd_mode)
1094 {
1095 struct sk_buff *skb;
1096 u8 mac_id = rtwsta ? rtwsta->mac_id : rtwvif->mac_id;
1097 u8 self_role;
1098
1099 if (rtwvif->net_type == RTW89_NET_TYPE_AP_MODE) {
1100 if (rtwsta)
1101 self_role = RTW89_SELF_ROLE_AP_CLIENT;
1102 else
1103 self_role = rtwvif->self_role;
1104 } else {
1105 self_role = rtwvif->self_role;
1106 }
1107
1108 skb = rtw89_fw_h2c_alloc_skb_with_hdr(rtwdev, H2C_ROLE_MAINTAIN_LEN);
1109 if (!skb) {
1110 rtw89_err(rtwdev, "failed to alloc skb for h2c join\n");
1111 return -ENOMEM;
1112 }
1113 skb_put(skb, H2C_ROLE_MAINTAIN_LEN);
1114 SET_FWROLE_MAINTAIN_MACID(skb->data, mac_id);
1115 SET_FWROLE_MAINTAIN_SELF_ROLE(skb->data, self_role);
1116 SET_FWROLE_MAINTAIN_UPD_MODE(skb->data, upd_mode);
1117 SET_FWROLE_MAINTAIN_WIFI_ROLE(skb->data, rtwvif->wifi_role);
1118
1119 rtw89_h2c_pkt_set_hdr(rtwdev, skb, FWCMD_TYPE_H2C,
1120 H2C_CAT_MAC, H2C_CL_MAC_MEDIA_RPT,
1121 H2C_FUNC_MAC_FWROLE_MAINTAIN, 0, 1,
1122 H2C_ROLE_MAINTAIN_LEN);
1123
1124 if (rtw89_h2c_tx(rtwdev, skb, false)) {
1125 rtw89_err(rtwdev, "failed to send h2c\n");
1126 goto fail;
1127 }
1128
1129 return 0;
1130 fail:
1131 dev_kfree_skb_any(skb);
1132
1133 return -EBUSY;
1134 }
1135
1136 #define H2C_JOIN_INFO_LEN 4
1137 int rtw89_fw_h2c_join_info(struct rtw89_dev *rtwdev, struct rtw89_vif *rtwvif,
1138 struct rtw89_sta *rtwsta, bool dis_conn)
1139 {
1140 struct sk_buff *skb;
1141 u8 mac_id = rtwsta ? rtwsta->mac_id : rtwvif->mac_id;
1142 u8 self_role = rtwvif->self_role;
1143 u8 net_type = rtwvif->net_type;
1144
1145 if (net_type == RTW89_NET_TYPE_AP_MODE && rtwsta) {
1146 self_role = RTW89_SELF_ROLE_AP_CLIENT;
1147 net_type = dis_conn ? RTW89_NET_TYPE_NO_LINK : net_type;
1148 }
1149
1150 skb = rtw89_fw_h2c_alloc_skb_with_hdr(rtwdev, H2C_JOIN_INFO_LEN);
1151 if (!skb) {
1152 rtw89_err(rtwdev, "failed to alloc skb for h2c join\n");
1153 return -ENOMEM;
1154 }
1155 skb_put(skb, H2C_JOIN_INFO_LEN);
1156 SET_JOININFO_MACID(skb->data, mac_id);
1157 SET_JOININFO_OP(skb->data, dis_conn);
1158 SET_JOININFO_BAND(skb->data, rtwvif->mac_idx);
1159 SET_JOININFO_WMM(skb->data, rtwvif->wmm);
1160 SET_JOININFO_TGR(skb->data, rtwvif->trigger);
1161 SET_JOININFO_ISHESTA(skb->data, 0);
1162 SET_JOININFO_DLBW(skb->data, 0);
1163 SET_JOININFO_TF_MAC_PAD(skb->data, 0);
1164 SET_JOININFO_DL_T_PE(skb->data, 0);
1165 SET_JOININFO_PORT_ID(skb->data, rtwvif->port);
1166 SET_JOININFO_NET_TYPE(skb->data, net_type);
1167 SET_JOININFO_WIFI_ROLE(skb->data, rtwvif->wifi_role);
1168 SET_JOININFO_SELF_ROLE(skb->data, self_role);
1169
1170 rtw89_h2c_pkt_set_hdr(rtwdev, skb, FWCMD_TYPE_H2C,
1171 H2C_CAT_MAC, H2C_CL_MAC_MEDIA_RPT,
1172 H2C_FUNC_MAC_JOININFO, 0, 1,
1173 H2C_JOIN_INFO_LEN);
1174
1175 if (rtw89_h2c_tx(rtwdev, skb, false)) {
1176 rtw89_err(rtwdev, "failed to send h2c\n");
1177 goto fail;
1178 }
1179
1180 return 0;
1181 fail:
1182 dev_kfree_skb_any(skb);
1183
1184 return -EBUSY;
1185 }
1186
1187 int rtw89_fw_h2c_macid_pause(struct rtw89_dev *rtwdev, u8 sh, u8 grp,
1188 bool pause)
1189 {
1190 struct rtw89_fw_macid_pause_grp h2c = {{0}};
1191 u8 len = sizeof(struct rtw89_fw_macid_pause_grp);
1192 struct sk_buff *skb;
1193
1194 skb = rtw89_fw_h2c_alloc_skb_with_hdr(rtwdev, H2C_JOIN_INFO_LEN);
1195 if (!skb) {
1196 rtw89_err(rtwdev, "failed to alloc skb for h2c join\n");
1197 return -ENOMEM;
1198 }
1199 h2c.mask_grp[grp] = cpu_to_le32(BIT(sh));
1200 if (pause)
1201 h2c.pause_grp[grp] = cpu_to_le32(BIT(sh));
1202 skb_put_data(skb, &h2c, len);
1203
1204 rtw89_h2c_pkt_set_hdr(rtwdev, skb, FWCMD_TYPE_H2C,
1205 H2C_CAT_MAC, H2C_CL_MAC_FW_OFLD,
1206 H2C_FUNC_MAC_MACID_PAUSE, 1, 0,
1207 len);
1208
1209 if (rtw89_h2c_tx(rtwdev, skb, false)) {
1210 rtw89_err(rtwdev, "failed to send h2c\n");
1211 goto fail;
1212 }
1213
1214 return 0;
1215 fail:
1216 dev_kfree_skb_any(skb);
1217
1218 return -EBUSY;
1219 }
1220
1221 #define H2C_EDCA_LEN 12
1222 int rtw89_fw_h2c_set_edca(struct rtw89_dev *rtwdev, struct rtw89_vif *rtwvif,
1223 u8 ac, u32 val)
1224 {
1225 struct sk_buff *skb;
1226
1227 skb = rtw89_fw_h2c_alloc_skb_with_hdr(rtwdev, H2C_EDCA_LEN);
1228 if (!skb) {
1229 rtw89_err(rtwdev, "failed to alloc skb for h2c edca\n");
1230 return -ENOMEM;
1231 }
1232 skb_put(skb, H2C_EDCA_LEN);
1233 RTW89_SET_EDCA_SEL(skb->data, 0);
1234 RTW89_SET_EDCA_BAND(skb->data, rtwvif->mac_idx);
1235 RTW89_SET_EDCA_WMM(skb->data, 0);
1236 RTW89_SET_EDCA_AC(skb->data, ac);
1237 RTW89_SET_EDCA_PARAM(skb->data, val);
1238
1239 rtw89_h2c_pkt_set_hdr(rtwdev, skb, FWCMD_TYPE_H2C,
1240 H2C_CAT_MAC, H2C_CL_MAC_FW_OFLD,
1241 H2C_FUNC_USR_EDCA, 0, 1,
1242 H2C_EDCA_LEN);
1243
1244 if (rtw89_h2c_tx(rtwdev, skb, false)) {
1245 rtw89_err(rtwdev, "failed to send h2c\n");
1246 goto fail;
1247 }
1248
1249 return 0;
1250 fail:
1251 dev_kfree_skb_any(skb);
1252
1253 return -EBUSY;
1254 }
1255
1256 #define H2C_OFLD_CFG_LEN 8
1257 int rtw89_fw_h2c_set_ofld_cfg(struct rtw89_dev *rtwdev)
1258 {
1259 static const u8 cfg[] = {0x09, 0x00, 0x00, 0x00, 0x5e, 0x00, 0x00, 0x00};
1260 struct sk_buff *skb;
1261
1262 skb = rtw89_fw_h2c_alloc_skb_with_hdr(rtwdev, H2C_OFLD_CFG_LEN);
1263 if (!skb) {
1264 rtw89_err(rtwdev, "failed to alloc skb for h2c ofld\n");
1265 return -ENOMEM;
1266 }
1267 skb_put_data(skb, cfg, H2C_OFLD_CFG_LEN);
1268
1269 rtw89_h2c_pkt_set_hdr(rtwdev, skb, FWCMD_TYPE_H2C,
1270 H2C_CAT_MAC, H2C_CL_MAC_FW_OFLD,
1271 H2C_FUNC_OFLD_CFG, 0, 1,
1272 H2C_OFLD_CFG_LEN);
1273
1274 if (rtw89_h2c_tx(rtwdev, skb, false)) {
1275 rtw89_err(rtwdev, "failed to send h2c\n");
1276 goto fail;
1277 }
1278
1279 return 0;
1280 fail:
1281 dev_kfree_skb_any(skb);
1282
1283 return -EBUSY;
1284 }
1285
1286 #define H2C_RA_LEN 16
1287 int rtw89_fw_h2c_ra(struct rtw89_dev *rtwdev, struct rtw89_ra_info *ra, bool csi)
1288 {
1289 struct sk_buff *skb;
1290 u8 *cmd;
1291
1292 skb = rtw89_fw_h2c_alloc_skb_with_hdr(rtwdev, H2C_RA_LEN);
1293 if (!skb) {
1294 rtw89_err(rtwdev, "failed to alloc skb for h2c join\n");
1295 return -ENOMEM;
1296 }
1297 skb_put(skb, H2C_RA_LEN);
1298 cmd = skb->data;
1299 rtw89_debug(rtwdev, RTW89_DBG_RA,
1300 "ra cmd msk: %llx ", ra->ra_mask);
1301
1302 RTW89_SET_FWCMD_RA_MODE(cmd, ra->mode_ctrl);
1303 RTW89_SET_FWCMD_RA_BW_CAP(cmd, ra->bw_cap);
1304 RTW89_SET_FWCMD_RA_MACID(cmd, ra->macid);
1305 RTW89_SET_FWCMD_RA_DCM(cmd, ra->dcm_cap);
1306 RTW89_SET_FWCMD_RA_ER(cmd, ra->er_cap);
1307 RTW89_SET_FWCMD_RA_INIT_RATE_LV(cmd, ra->init_rate_lv);
1308 RTW89_SET_FWCMD_RA_UPD_ALL(cmd, ra->upd_all);
1309 RTW89_SET_FWCMD_RA_SGI(cmd, ra->en_sgi);
1310 RTW89_SET_FWCMD_RA_LDPC(cmd, ra->ldpc_cap);
1311 RTW89_SET_FWCMD_RA_STBC(cmd, ra->stbc_cap);
1312 RTW89_SET_FWCMD_RA_SS_NUM(cmd, ra->ss_num);
1313 RTW89_SET_FWCMD_RA_GILTF(cmd, ra->giltf);
1314 RTW89_SET_FWCMD_RA_UPD_BW_NSS_MASK(cmd, ra->upd_bw_nss_mask);
1315 RTW89_SET_FWCMD_RA_UPD_MASK(cmd, ra->upd_mask);
1316 RTW89_SET_FWCMD_RA_MASK_0(cmd, FIELD_GET(MASKBYTE0, ra->ra_mask));
1317 RTW89_SET_FWCMD_RA_MASK_1(cmd, FIELD_GET(MASKBYTE1, ra->ra_mask));
1318 RTW89_SET_FWCMD_RA_MASK_2(cmd, FIELD_GET(MASKBYTE2, ra->ra_mask));
1319 RTW89_SET_FWCMD_RA_MASK_3(cmd, FIELD_GET(MASKBYTE3, ra->ra_mask));
1320 RTW89_SET_FWCMD_RA_MASK_4(cmd, FIELD_GET(MASKBYTE4, ra->ra_mask));
1321
1322 if (csi) {
1323 RTW89_SET_FWCMD_RA_BFEE_CSI_CTL(cmd, 1);
1324 RTW89_SET_FWCMD_RA_BAND_NUM(cmd, ra->band_num);
1325 RTW89_SET_FWCMD_RA_CR_TBL_SEL(cmd, ra->cr_tbl_sel);
1326 RTW89_SET_FWCMD_RA_FIXED_CSI_RATE_EN(cmd, ra->fixed_csi_rate_en);
1327 RTW89_SET_FWCMD_RA_RA_CSI_RATE_EN(cmd, ra->ra_csi_rate_en);
1328 RTW89_SET_FWCMD_RA_FIXED_CSI_MCS_SS_IDX(cmd, ra->csi_mcs_ss_idx);
1329 RTW89_SET_FWCMD_RA_FIXED_CSI_MODE(cmd, ra->csi_mode);
1330 RTW89_SET_FWCMD_RA_FIXED_CSI_GI_LTF(cmd, ra->csi_gi_ltf);
1331 RTW89_SET_FWCMD_RA_FIXED_CSI_BW(cmd, ra->csi_bw);
1332 }
1333
1334 rtw89_h2c_pkt_set_hdr(rtwdev, skb, FWCMD_TYPE_H2C,
1335 H2C_CAT_OUTSRC, H2C_CL_OUTSRC_RA,
1336 H2C_FUNC_OUTSRC_RA_MACIDCFG, 0, 0,
1337 H2C_RA_LEN);
1338
1339 if (rtw89_h2c_tx(rtwdev, skb, false)) {
1340 rtw89_err(rtwdev, "failed to send h2c\n");
1341 goto fail;
1342 }
1343
1344 return 0;
1345 fail:
1346 dev_kfree_skb_any(skb);
1347
1348 return -EBUSY;
1349 }
1350
1351 #define H2C_LEN_CXDRVHDR 2
1352 #define H2C_LEN_CXDRVINFO_INIT (12 + H2C_LEN_CXDRVHDR)
1353 int rtw89_fw_h2c_cxdrv_init(struct rtw89_dev *rtwdev)
1354 {
1355 struct rtw89_btc *btc = &rtwdev->btc;
1356 struct rtw89_btc_dm *dm = &btc->dm;
1357 struct rtw89_btc_init_info *init_info = &dm->init_info;
1358 struct rtw89_btc_module *module = &init_info->module;
1359 struct rtw89_btc_ant_info *ant = &module->ant;
1360 struct sk_buff *skb;
1361 u8 *cmd;
1362
1363 skb = rtw89_fw_h2c_alloc_skb_with_hdr(rtwdev, H2C_LEN_CXDRVINFO_INIT);
1364 if (!skb) {
1365 rtw89_err(rtwdev, "failed to alloc skb for h2c cxdrv_init\n");
1366 return -ENOMEM;
1367 }
1368 skb_put(skb, H2C_LEN_CXDRVINFO_INIT);
1369 cmd = skb->data;
1370
1371 RTW89_SET_FWCMD_CXHDR_TYPE(cmd, CXDRVINFO_INIT);
1372 RTW89_SET_FWCMD_CXHDR_LEN(cmd, H2C_LEN_CXDRVINFO_INIT - H2C_LEN_CXDRVHDR);
1373
1374 RTW89_SET_FWCMD_CXINIT_ANT_TYPE(cmd, ant->type);
1375 RTW89_SET_FWCMD_CXINIT_ANT_NUM(cmd, ant->num);
1376 RTW89_SET_FWCMD_CXINIT_ANT_ISO(cmd, ant->isolation);
1377 RTW89_SET_FWCMD_CXINIT_ANT_POS(cmd, ant->single_pos);
1378 RTW89_SET_FWCMD_CXINIT_ANT_DIVERSITY(cmd, ant->diversity);
1379
1380 RTW89_SET_FWCMD_CXINIT_MOD_RFE(cmd, module->rfe_type);
1381 RTW89_SET_FWCMD_CXINIT_MOD_CV(cmd, module->cv);
1382 RTW89_SET_FWCMD_CXINIT_MOD_BT_SOLO(cmd, module->bt_solo);
1383 RTW89_SET_FWCMD_CXINIT_MOD_BT_POS(cmd, module->bt_pos);
1384 RTW89_SET_FWCMD_CXINIT_MOD_SW_TYPE(cmd, module->switch_type);
1385
1386 RTW89_SET_FWCMD_CXINIT_WL_GCH(cmd, init_info->wl_guard_ch);
1387 RTW89_SET_FWCMD_CXINIT_WL_ONLY(cmd, init_info->wl_only);
1388 RTW89_SET_FWCMD_CXINIT_WL_INITOK(cmd, init_info->wl_init_ok);
1389 RTW89_SET_FWCMD_CXINIT_DBCC_EN(cmd, init_info->dbcc_en);
1390 RTW89_SET_FWCMD_CXINIT_CX_OTHER(cmd, init_info->cx_other);
1391 RTW89_SET_FWCMD_CXINIT_BT_ONLY(cmd, init_info->bt_only);
1392
1393 rtw89_h2c_pkt_set_hdr(rtwdev, skb, FWCMD_TYPE_H2C,
1394 H2C_CAT_OUTSRC, BTFC_SET,
1395 SET_DRV_INFO, 0, 0,
1396 H2C_LEN_CXDRVINFO_INIT);
1397
1398 if (rtw89_h2c_tx(rtwdev, skb, false)) {
1399 rtw89_err(rtwdev, "failed to send h2c\n");
1400 goto fail;
1401 }
1402
1403 return 0;
1404 fail:
1405 dev_kfree_skb_any(skb);
1406
1407 return -EBUSY;
1408 }
1409
1410 #define H2C_LEN_CXDRVINFO_ROLE (4 + 12 * RTW89_PORT_NUM + H2C_LEN_CXDRVHDR)
1411 int rtw89_fw_h2c_cxdrv_role(struct rtw89_dev *rtwdev)
1412 {
1413 struct rtw89_btc *btc = &rtwdev->btc;
1414 struct rtw89_btc_wl_info *wl = &btc->cx.wl;
1415 struct rtw89_btc_wl_role_info *role_info = &wl->role_info;
1416 struct rtw89_btc_wl_role_info_bpos *bpos = &role_info->role_map.role;
1417 struct rtw89_btc_wl_active_role *active = role_info->active_role;
1418 struct sk_buff *skb;
1419 u8 *cmd;
1420 int i;
1421
1422 skb = rtw89_fw_h2c_alloc_skb_with_hdr(rtwdev, H2C_LEN_CXDRVINFO_ROLE);
1423 if (!skb) {
1424 rtw89_err(rtwdev, "failed to alloc skb for h2c cxdrv_role\n");
1425 return -ENOMEM;
1426 }
1427 skb_put(skb, H2C_LEN_CXDRVINFO_ROLE);
1428 cmd = skb->data;
1429
1430 RTW89_SET_FWCMD_CXHDR_TYPE(cmd, CXDRVINFO_ROLE);
1431 RTW89_SET_FWCMD_CXHDR_LEN(cmd, H2C_LEN_CXDRVINFO_ROLE - H2C_LEN_CXDRVHDR);
1432
1433 RTW89_SET_FWCMD_CXROLE_CONNECT_CNT(cmd, role_info->connect_cnt);
1434 RTW89_SET_FWCMD_CXROLE_LINK_MODE(cmd, role_info->link_mode);
1435
1436 RTW89_SET_FWCMD_CXROLE_ROLE_NONE(cmd, bpos->none);
1437 RTW89_SET_FWCMD_CXROLE_ROLE_STA(cmd, bpos->station);
1438 RTW89_SET_FWCMD_CXROLE_ROLE_AP(cmd, bpos->ap);
1439 RTW89_SET_FWCMD_CXROLE_ROLE_VAP(cmd, bpos->vap);
1440 RTW89_SET_FWCMD_CXROLE_ROLE_ADHOC(cmd, bpos->adhoc);
1441 RTW89_SET_FWCMD_CXROLE_ROLE_ADHOC_MASTER(cmd, bpos->adhoc_master);
1442 RTW89_SET_FWCMD_CXROLE_ROLE_MESH(cmd, bpos->mesh);
1443 RTW89_SET_FWCMD_CXROLE_ROLE_MONITOR(cmd, bpos->moniter);
1444 RTW89_SET_FWCMD_CXROLE_ROLE_P2P_DEV(cmd, bpos->p2p_device);
1445 RTW89_SET_FWCMD_CXROLE_ROLE_P2P_GC(cmd, bpos->p2p_gc);
1446 RTW89_SET_FWCMD_CXROLE_ROLE_P2P_GO(cmd, bpos->p2p_go);
1447 RTW89_SET_FWCMD_CXROLE_ROLE_NAN(cmd, bpos->nan);
1448
1449 for (i = 0; i < RTW89_PORT_NUM; i++, active++) {
1450 RTW89_SET_FWCMD_CXROLE_ACT_CONNECTED(cmd, active->connected, i);
1451 RTW89_SET_FWCMD_CXROLE_ACT_PID(cmd, active->pid, i);
1452 RTW89_SET_FWCMD_CXROLE_ACT_PHY(cmd, active->phy, i);
1453 RTW89_SET_FWCMD_CXROLE_ACT_NOA(cmd, active->noa, i);
1454 RTW89_SET_FWCMD_CXROLE_ACT_BAND(cmd, active->band, i);
1455 RTW89_SET_FWCMD_CXROLE_ACT_CLIENT_PS(cmd, active->client_ps, i);
1456 RTW89_SET_FWCMD_CXROLE_ACT_BW(cmd, active->bw, i);
1457 RTW89_SET_FWCMD_CXROLE_ACT_ROLE(cmd, active->role, i);
1458 RTW89_SET_FWCMD_CXROLE_ACT_CH(cmd, active->ch, i);
1459 RTW89_SET_FWCMD_CXROLE_ACT_TX_LVL(cmd, active->tx_lvl, i);
1460 RTW89_SET_FWCMD_CXROLE_ACT_RX_LVL(cmd, active->rx_lvl, i);
1461 RTW89_SET_FWCMD_CXROLE_ACT_TX_RATE(cmd, active->tx_rate, i);
1462 RTW89_SET_FWCMD_CXROLE_ACT_RX_RATE(cmd, active->rx_rate, i);
1463 }
1464
1465 rtw89_h2c_pkt_set_hdr(rtwdev, skb, FWCMD_TYPE_H2C,
1466 H2C_CAT_OUTSRC, BTFC_SET,
1467 SET_DRV_INFO, 0, 0,
1468 H2C_LEN_CXDRVINFO_ROLE);
1469
1470 if (rtw89_h2c_tx(rtwdev, skb, false)) {
1471 rtw89_err(rtwdev, "failed to send h2c\n");
1472 goto fail;
1473 }
1474
1475 return 0;
1476 fail:
1477 dev_kfree_skb_any(skb);
1478
1479 return -EBUSY;
1480 }
1481
1482 #define H2C_LEN_CXDRVINFO_CTRL (4 + H2C_LEN_CXDRVHDR)
1483 int rtw89_fw_h2c_cxdrv_ctrl(struct rtw89_dev *rtwdev)
1484 {
1485 struct rtw89_btc *btc = &rtwdev->btc;
1486 struct rtw89_btc_ctrl *ctrl = &btc->ctrl;
1487 struct sk_buff *skb;
1488 u8 *cmd;
1489
1490 skb = rtw89_fw_h2c_alloc_skb_with_hdr(rtwdev, H2C_LEN_CXDRVINFO_CTRL);
1491 if (!skb) {
1492 rtw89_err(rtwdev, "failed to alloc skb for h2c cxdrv_ctrl\n");
1493 return -ENOMEM;
1494 }
1495 skb_put(skb, H2C_LEN_CXDRVINFO_CTRL);
1496 cmd = skb->data;
1497
1498 RTW89_SET_FWCMD_CXHDR_TYPE(cmd, CXDRVINFO_CTRL);
1499 RTW89_SET_FWCMD_CXHDR_LEN(cmd, H2C_LEN_CXDRVINFO_CTRL - H2C_LEN_CXDRVHDR);
1500
1501 RTW89_SET_FWCMD_CXCTRL_MANUAL(cmd, ctrl->manual);
1502 RTW89_SET_FWCMD_CXCTRL_IGNORE_BT(cmd, ctrl->igno_bt);
1503 RTW89_SET_FWCMD_CXCTRL_ALWAYS_FREERUN(cmd, ctrl->always_freerun);
1504 RTW89_SET_FWCMD_CXCTRL_TRACE_STEP(cmd, ctrl->trace_step);
1505
1506 rtw89_h2c_pkt_set_hdr(rtwdev, skb, FWCMD_TYPE_H2C,
1507 H2C_CAT_OUTSRC, BTFC_SET,
1508 SET_DRV_INFO, 0, 0,
1509 H2C_LEN_CXDRVINFO_CTRL);
1510
1511 if (rtw89_h2c_tx(rtwdev, skb, false)) {
1512 rtw89_err(rtwdev, "failed to send h2c\n");
1513 goto fail;
1514 }
1515
1516 return 0;
1517 fail:
1518 dev_kfree_skb_any(skb);
1519
1520 return -EBUSY;
1521 }
1522
1523 #define H2C_LEN_CXDRVINFO_RFK (4 + H2C_LEN_CXDRVHDR)
1524 int rtw89_fw_h2c_cxdrv_rfk(struct rtw89_dev *rtwdev)
1525 {
1526 struct rtw89_btc *btc = &rtwdev->btc;
1527 struct rtw89_btc_wl_info *wl = &btc->cx.wl;
1528 struct rtw89_btc_wl_rfk_info *rfk_info = &wl->rfk_info;
1529 struct sk_buff *skb;
1530 u8 *cmd;
1531
1532 skb = rtw89_fw_h2c_alloc_skb_with_hdr(rtwdev, H2C_LEN_CXDRVINFO_RFK);
1533 if (!skb) {
1534 rtw89_err(rtwdev, "failed to alloc skb for h2c cxdrv_ctrl\n");
1535 return -ENOMEM;
1536 }
1537 skb_put(skb, H2C_LEN_CXDRVINFO_RFK);
1538 cmd = skb->data;
1539
1540 RTW89_SET_FWCMD_CXHDR_TYPE(cmd, CXDRVINFO_RFK);
1541 RTW89_SET_FWCMD_CXHDR_LEN(cmd, H2C_LEN_CXDRVINFO_RFK - H2C_LEN_CXDRVHDR);
1542
1543 RTW89_SET_FWCMD_CXRFK_STATE(cmd, rfk_info->state);
1544 RTW89_SET_FWCMD_CXRFK_PATH_MAP(cmd, rfk_info->path_map);
1545 RTW89_SET_FWCMD_CXRFK_PHY_MAP(cmd, rfk_info->phy_map);
1546 RTW89_SET_FWCMD_CXRFK_BAND(cmd, rfk_info->band);
1547 RTW89_SET_FWCMD_CXRFK_TYPE(cmd, rfk_info->type);
1548
1549 rtw89_h2c_pkt_set_hdr(rtwdev, skb, FWCMD_TYPE_H2C,
1550 H2C_CAT_OUTSRC, BTFC_SET,
1551 SET_DRV_INFO, 0, 0,
1552 H2C_LEN_CXDRVINFO_RFK);
1553
1554 if (rtw89_h2c_tx(rtwdev, skb, false)) {
1555 rtw89_err(rtwdev, "failed to send h2c\n");
1556 goto fail;
1557 }
1558
1559 return 0;
1560 fail:
1561 dev_kfree_skb_any(skb);
1562
1563 return -EBUSY;
1564 }
1565
1566 #define H2C_LEN_PKT_OFLD 4
1567 int rtw89_fw_h2c_del_pkt_offload(struct rtw89_dev *rtwdev, u8 id)
1568 {
1569 struct sk_buff *skb;
1570 u8 *cmd;
1571
1572 skb = rtw89_fw_h2c_alloc_skb_with_hdr(rtwdev, H2C_LEN_PKT_OFLD);
1573 if (!skb) {
1574 rtw89_err(rtwdev, "failed to alloc skb for h2c pkt offload\n");
1575 return -ENOMEM;
1576 }
1577 skb_put(skb, H2C_LEN_PKT_OFLD);
1578 cmd = skb->data;
1579
1580 RTW89_SET_FWCMD_PACKET_OFLD_PKT_IDX(cmd, id);
1581 RTW89_SET_FWCMD_PACKET_OFLD_PKT_OP(cmd, RTW89_PKT_OFLD_OP_DEL);
1582
1583 rtw89_h2c_pkt_set_hdr(rtwdev, skb, FWCMD_TYPE_H2C,
1584 H2C_CAT_MAC, H2C_CL_MAC_FW_OFLD,
1585 H2C_FUNC_PACKET_OFLD, 1, 1,
1586 H2C_LEN_PKT_OFLD);
1587
1588 if (rtw89_h2c_tx(rtwdev, skb, false)) {
1589 rtw89_err(rtwdev, "failed to send h2c\n");
1590 goto fail;
1591 }
1592
1593 return 0;
1594 fail:
1595 dev_kfree_skb_any(skb);
1596
1597 return -EBUSY;
1598 }
1599
1600 int rtw89_fw_h2c_add_pkt_offload(struct rtw89_dev *rtwdev, u8 *id,
1601 struct sk_buff *skb_ofld)
1602 {
1603 struct sk_buff *skb;
1604 u8 *cmd;
1605 u8 alloc_id;
1606
1607 alloc_id = rtw89_core_acquire_bit_map(rtwdev->pkt_offload,
1608 RTW89_MAX_PKT_OFLD_NUM);
1609 if (alloc_id == RTW89_MAX_PKT_OFLD_NUM)
1610 return -ENOSPC;
1611
1612 *id = alloc_id;
1613
1614 skb = rtw89_fw_h2c_alloc_skb_with_hdr(rtwdev, H2C_LEN_PKT_OFLD + skb_ofld->len);
1615 if (!skb) {
1616 rtw89_err(rtwdev, "failed to alloc skb for h2c pkt offload\n");
1617 return -ENOMEM;
1618 }
1619 skb_put(skb, H2C_LEN_PKT_OFLD);
1620 cmd = skb->data;
1621
1622 RTW89_SET_FWCMD_PACKET_OFLD_PKT_IDX(cmd, alloc_id);
1623 RTW89_SET_FWCMD_PACKET_OFLD_PKT_OP(cmd, RTW89_PKT_OFLD_OP_ADD);
1624 RTW89_SET_FWCMD_PACKET_OFLD_PKT_LENGTH(cmd, skb_ofld->len);
1625 skb_put_data(skb, skb_ofld->data, skb_ofld->len);
1626
1627 rtw89_h2c_pkt_set_hdr(rtwdev, skb, FWCMD_TYPE_H2C,
1628 H2C_CAT_MAC, H2C_CL_MAC_FW_OFLD,
1629 H2C_FUNC_PACKET_OFLD, 1, 1,
1630 H2C_LEN_PKT_OFLD + skb_ofld->len);
1631
1632 if (rtw89_h2c_tx(rtwdev, skb, false)) {
1633 rtw89_err(rtwdev, "failed to send h2c\n");
1634 goto fail;
1635 }
1636
1637 return 0;
1638 fail:
1639 dev_kfree_skb_any(skb);
1640
1641 return -EBUSY;
1642 }
1643
1644 #define H2C_LEN_SCAN_LIST_OFFLOAD 4
1645 int rtw89_fw_h2c_scan_list_offload(struct rtw89_dev *rtwdev, int len,
1646 struct list_head *chan_list)
1647 {
1648 struct rtw89_mac_chinfo *ch_info;
1649 struct sk_buff *skb;
1650 int skb_len = H2C_LEN_SCAN_LIST_OFFLOAD + len * RTW89_MAC_CHINFO_SIZE;
1651 u8 *cmd;
1652
1653 skb = rtw89_fw_h2c_alloc_skb_with_hdr(rtwdev, skb_len);
1654 if (!skb) {
1655 rtw89_err(rtwdev, "failed to alloc skb for h2c scan list\n");
1656 return -ENOMEM;
1657 }
1658 skb_put(skb, H2C_LEN_SCAN_LIST_OFFLOAD);
1659 cmd = skb->data;
1660
1661 RTW89_SET_FWCMD_SCANOFLD_CH_NUM(cmd, len);
1662
1663 RTW89_SET_FWCMD_SCANOFLD_CH_SIZE(cmd, RTW89_MAC_CHINFO_SIZE / 4);
1664
1665 list_for_each_entry(ch_info, chan_list, list) {
1666 cmd = skb_put(skb, RTW89_MAC_CHINFO_SIZE);
1667
1668 RTW89_SET_FWCMD_CHINFO_PERIOD(cmd, ch_info->period);
1669 RTW89_SET_FWCMD_CHINFO_DWELL(cmd, ch_info->dwell_time);
1670 RTW89_SET_FWCMD_CHINFO_CENTER_CH(cmd, ch_info->central_ch);
1671 RTW89_SET_FWCMD_CHINFO_PRI_CH(cmd, ch_info->pri_ch);
1672 RTW89_SET_FWCMD_CHINFO_BW(cmd, ch_info->bw);
1673 RTW89_SET_FWCMD_CHINFO_ACTION(cmd, ch_info->notify_action);
1674 RTW89_SET_FWCMD_CHINFO_NUM_PKT(cmd, ch_info->num_pkt);
1675 RTW89_SET_FWCMD_CHINFO_TX(cmd, ch_info->tx_pkt);
1676 RTW89_SET_FWCMD_CHINFO_PAUSE_DATA(cmd, ch_info->pause_data);
1677 RTW89_SET_FWCMD_CHINFO_BAND(cmd, ch_info->ch_band);
1678 RTW89_SET_FWCMD_CHINFO_PKT_ID(cmd, ch_info->probe_id);
1679 RTW89_SET_FWCMD_CHINFO_DFS(cmd, ch_info->dfs_ch);
1680 RTW89_SET_FWCMD_CHINFO_TX_NULL(cmd, ch_info->tx_null);
1681 RTW89_SET_FWCMD_CHINFO_RANDOM(cmd, ch_info->rand_seq_num);
1682 RTW89_SET_FWCMD_CHINFO_PKT0(cmd, ch_info->pkt_id[0]);
1683 RTW89_SET_FWCMD_CHINFO_PKT1(cmd, ch_info->pkt_id[1]);
1684 RTW89_SET_FWCMD_CHINFO_PKT2(cmd, ch_info->pkt_id[2]);
1685 RTW89_SET_FWCMD_CHINFO_PKT3(cmd, ch_info->pkt_id[3]);
1686 RTW89_SET_FWCMD_CHINFO_PKT4(cmd, ch_info->pkt_id[4]);
1687 RTW89_SET_FWCMD_CHINFO_PKT5(cmd, ch_info->pkt_id[5]);
1688 RTW89_SET_FWCMD_CHINFO_PKT6(cmd, ch_info->pkt_id[6]);
1689 RTW89_SET_FWCMD_CHINFO_PKT7(cmd, ch_info->pkt_id[7]);
1690 }
1691
1692 rtw89_h2c_pkt_set_hdr(rtwdev, skb, FWCMD_TYPE_H2C,
1693 H2C_CAT_MAC, H2C_CL_MAC_FW_OFLD,
1694 H2C_FUNC_ADD_SCANOFLD_CH, 1, 1, skb_len);
1695
1696 if (rtw89_h2c_tx(rtwdev, skb, false)) {
1697 rtw89_err(rtwdev, "failed to send h2c\n");
1698 goto fail;
1699 }
1700
1701 return 0;
1702 fail:
1703 dev_kfree_skb_any(skb);
1704
1705 return -EBUSY;
1706 }
1707
1708 #define H2C_LEN_SCAN_OFFLOAD 20
1709 int rtw89_fw_h2c_scan_offload(struct rtw89_dev *rtwdev,
1710 struct rtw89_scan_option *option,
1711 struct rtw89_vif *rtwvif)
1712 {
1713 struct rtw89_hw_scan_info *scan_info = &rtwdev->scan_info;
1714 struct sk_buff *skb;
1715 u8 *cmd;
1716
1717 skb = rtw89_fw_h2c_alloc_skb_with_hdr(rtwdev, H2C_LEN_SCAN_OFFLOAD);
1718 if (!skb) {
1719 rtw89_err(rtwdev, "failed to alloc skb for h2c scan offload\n");
1720 return -ENOMEM;
1721 }
1722 skb_put(skb, H2C_LEN_SCAN_OFFLOAD);
1723 cmd = skb->data;
1724
1725 RTW89_SET_FWCMD_SCANOFLD_MACID(cmd, rtwvif->mac_id);
1726 RTW89_SET_FWCMD_SCANOFLD_PORT_ID(cmd, rtwvif->port);
1727 RTW89_SET_FWCMD_SCANOFLD_BAND(cmd, RTW89_PHY_0);
1728 RTW89_SET_FWCMD_SCANOFLD_OPERATION(cmd, option->enable);
1729 RTW89_SET_FWCMD_SCANOFLD_NOTIFY_END(cmd, true);
1730 RTW89_SET_FWCMD_SCANOFLD_TARGET_CH_MODE(cmd, option->target_ch_mode);
1731 RTW89_SET_FWCMD_SCANOFLD_START_MODE(cmd, RTW89_SCAN_IMMEDIATE);
1732 RTW89_SET_FWCMD_SCANOFLD_SCAN_TYPE(cmd, RTW89_SCAN_ONCE);
1733 if (option->target_ch_mode) {
1734 RTW89_SET_FWCMD_SCANOFLD_TARGET_CH_BW(cmd, scan_info->op_bw);
1735 RTW89_SET_FWCMD_SCANOFLD_TARGET_PRI_CH(cmd,
1736 scan_info->op_pri_ch);
1737 RTW89_SET_FWCMD_SCANOFLD_TARGET_CENTRAL_CH(cmd,
1738 scan_info->op_chan);
1739 }
1740
1741 rtw89_h2c_pkt_set_hdr(rtwdev, skb, FWCMD_TYPE_H2C,
1742 H2C_CAT_MAC, H2C_CL_MAC_FW_OFLD,
1743 H2C_FUNC_SCANOFLD, 1, 1,
1744 H2C_LEN_SCAN_OFFLOAD);
1745
1746 if (rtw89_h2c_tx(rtwdev, skb, false)) {
1747 rtw89_err(rtwdev, "failed to send h2c\n");
1748 goto fail;
1749 }
1750
1751 return 0;
1752 fail:
1753 dev_kfree_skb_any(skb);
1754
1755 return -EBUSY;
1756 }
1757
1758 int rtw89_fw_h2c_rf_reg(struct rtw89_dev *rtwdev,
1759 struct rtw89_fw_h2c_rf_reg_info *info,
1760 u16 len, u8 page)
1761 {
1762 struct sk_buff *skb;
1763 u8 class = info->rf_path == RF_PATH_A ?
1764 H2C_CL_OUTSRC_RF_REG_A : H2C_CL_OUTSRC_RF_REG_B;
1765
1766 skb = rtw89_fw_h2c_alloc_skb_with_hdr(rtwdev, len);
1767 if (!skb) {
1768 rtw89_err(rtwdev, "failed to alloc skb for h2c rf reg\n");
1769 return -ENOMEM;
1770 }
1771 skb_put_data(skb, info->rtw89_phy_config_rf_h2c[page], len);
1772
1773 rtw89_h2c_pkt_set_hdr(rtwdev, skb, FWCMD_TYPE_H2C,
1774 H2C_CAT_OUTSRC, class, page, 0, 0,
1775 len);
1776
1777 if (rtw89_h2c_tx(rtwdev, skb, false)) {
1778 rtw89_err(rtwdev, "failed to send h2c\n");
1779 goto fail;
1780 }
1781
1782 return 0;
1783 fail:
1784 dev_kfree_skb_any(skb);
1785
1786 return -EBUSY;
1787 }
1788
1789 int rtw89_fw_h2c_rf_ntfy_mcc(struct rtw89_dev *rtwdev)
1790 {
1791 struct rtw89_mcc_info *mcc_info = &rtwdev->mcc;
1792 struct rtw89_fw_h2c_rf_get_mccch *mccch;
1793 struct sk_buff *skb;
1794
1795 skb = rtw89_fw_h2c_alloc_skb_with_hdr(rtwdev, sizeof(*mccch));
1796 if (!skb) {
1797 rtw89_err(rtwdev, "failed to alloc skb for h2c cxdrv_ctrl\n");
1798 return -ENOMEM;
1799 }
1800 skb_put(skb, sizeof(*mccch));
1801 mccch = (struct rtw89_fw_h2c_rf_get_mccch *)skb->data;
1802
1803 mccch->ch_0 = cpu_to_le32(mcc_info->ch[0]);
1804 mccch->ch_1 = cpu_to_le32(mcc_info->ch[1]);
1805 mccch->band_0 = cpu_to_le32(mcc_info->band[0]);
1806 mccch->band_1 = cpu_to_le32(mcc_info->band[1]);
1807 mccch->current_channel = cpu_to_le32(rtwdev->hal.current_channel);
1808 mccch->current_band_type = cpu_to_le32(rtwdev->hal.current_band_type);
1809
1810 rtw89_h2c_pkt_set_hdr(rtwdev, skb, FWCMD_TYPE_H2C,
1811 H2C_CAT_OUTSRC, H2C_CL_OUTSRC_RF_FW_NOTIFY,
1812 H2C_FUNC_OUTSRC_RF_GET_MCCCH, 0, 0,
1813 sizeof(*mccch));
1814
1815 if (rtw89_h2c_tx(rtwdev, skb, false)) {
1816 rtw89_err(rtwdev, "failed to send h2c\n");
1817 goto fail;
1818 }
1819
1820 return 0;
1821 fail:
1822 dev_kfree_skb_any(skb);
1823
1824 return -EBUSY;
1825 }
1826 EXPORT_SYMBOL(rtw89_fw_h2c_rf_ntfy_mcc);
1827
1828 int rtw89_fw_h2c_raw_with_hdr(struct rtw89_dev *rtwdev,
1829 u8 h2c_class, u8 h2c_func, u8 *buf, u16 len,
1830 bool rack, bool dack)
1831 {
1832 struct sk_buff *skb;
1833
1834 skb = rtw89_fw_h2c_alloc_skb_with_hdr(rtwdev, len);
1835 if (!skb) {
1836 rtw89_err(rtwdev, "failed to alloc skb for raw with hdr\n");
1837 return -ENOMEM;
1838 }
1839 skb_put_data(skb, buf, len);
1840
1841 rtw89_h2c_pkt_set_hdr(rtwdev, skb, FWCMD_TYPE_H2C,
1842 H2C_CAT_OUTSRC, h2c_class, h2c_func, rack, dack,
1843 len);
1844
1845 if (rtw89_h2c_tx(rtwdev, skb, false)) {
1846 rtw89_err(rtwdev, "failed to send h2c\n");
1847 goto fail;
1848 }
1849
1850 return 0;
1851 fail:
1852 dev_kfree_skb_any(skb);
1853
1854 return -EBUSY;
1855 }
1856
1857 int rtw89_fw_h2c_raw(struct rtw89_dev *rtwdev, const u8 *buf, u16 len)
1858 {
1859 struct sk_buff *skb;
1860
1861 skb = rtw89_fw_h2c_alloc_skb_no_hdr(rtwdev, len);
1862 if (!skb) {
1863 rtw89_err(rtwdev, "failed to alloc skb for h2c raw\n");
1864 return -ENOMEM;
1865 }
1866 skb_put_data(skb, buf, len);
1867
1868 if (rtw89_h2c_tx(rtwdev, skb, false)) {
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 -EBUSY;
1878 }
1879
1880 void rtw89_fw_send_all_early_h2c(struct rtw89_dev *rtwdev)
1881 {
1882 struct rtw89_early_h2c *early_h2c;
1883
1884 lockdep_assert_held(&rtwdev->mutex);
1885
1886 list_for_each_entry(early_h2c, &rtwdev->early_h2c_list, list) {
1887 rtw89_fw_h2c_raw(rtwdev, early_h2c->h2c, early_h2c->h2c_len);
1888 }
1889 }
1890
1891 void rtw89_fw_free_all_early_h2c(struct rtw89_dev *rtwdev)
1892 {
1893 struct rtw89_early_h2c *early_h2c, *tmp;
1894
1895 mutex_lock(&rtwdev->mutex);
1896 list_for_each_entry_safe(early_h2c, tmp, &rtwdev->early_h2c_list, list) {
1897 list_del(&early_h2c->list);
1898 kfree(early_h2c->h2c);
1899 kfree(early_h2c);
1900 }
1901 mutex_unlock(&rtwdev->mutex);
1902 }
1903
1904 void rtw89_fw_c2h_irqsafe(struct rtw89_dev *rtwdev, struct sk_buff *c2h)
1905 {
1906 skb_queue_tail(&rtwdev->c2h_queue, c2h);
1907 ieee80211_queue_work(rtwdev->hw, &rtwdev->c2h_work);
1908 }
1909
1910 static void rtw89_fw_c2h_cmd_handle(struct rtw89_dev *rtwdev,
1911 struct sk_buff *skb)
1912 {
1913 u8 category = RTW89_GET_C2H_CATEGORY(skb->data);
1914 u8 class = RTW89_GET_C2H_CLASS(skb->data);
1915 u8 func = RTW89_GET_C2H_FUNC(skb->data);
1916 u16 len = RTW89_GET_C2H_LEN(skb->data);
1917 bool dump = true;
1918
1919 if (!test_bit(RTW89_FLAG_RUNNING, rtwdev->flags))
1920 return;
1921
1922 switch (category) {
1923 case RTW89_C2H_CAT_TEST:
1924 break;
1925 case RTW89_C2H_CAT_MAC:
1926 rtw89_mac_c2h_handle(rtwdev, skb, len, class, func);
1927 if (class == RTW89_MAC_C2H_CLASS_INFO &&
1928 func == RTW89_MAC_C2H_FUNC_C2H_LOG)
1929 dump = false;
1930 break;
1931 case RTW89_C2H_CAT_OUTSRC:
1932 if (class >= RTW89_PHY_C2H_CLASS_BTC_MIN &&
1933 class <= RTW89_PHY_C2H_CLASS_BTC_MAX)
1934 rtw89_btc_c2h_handle(rtwdev, skb, len, class, func);
1935 else
1936 rtw89_phy_c2h_handle(rtwdev, skb, len, class, func);
1937 break;
1938 }
1939
1940 if (dump)
1941 rtw89_hex_dump(rtwdev, RTW89_DBG_FW, "C2H: ", skb->data, skb->len);
1942 }
1943
1944 void rtw89_fw_c2h_work(struct work_struct *work)
1945 {
1946 struct rtw89_dev *rtwdev = container_of(work, struct rtw89_dev,
1947 c2h_work);
1948 struct sk_buff *skb, *tmp;
1949
1950 skb_queue_walk_safe(&rtwdev->c2h_queue, skb, tmp) {
1951 skb_unlink(skb, &rtwdev->c2h_queue);
1952 mutex_lock(&rtwdev->mutex);
1953 rtw89_fw_c2h_cmd_handle(rtwdev, skb);
1954 mutex_unlock(&rtwdev->mutex);
1955 dev_kfree_skb_any(skb);
1956 }
1957 }
1958
1959 static int rtw89_fw_write_h2c_reg(struct rtw89_dev *rtwdev,
1960 struct rtw89_mac_h2c_info *info)
1961 {
1962 const struct rtw89_chip_info *chip = rtwdev->chip;
1963 const u32 *h2c_reg = chip->h2c_regs;
1964 u8 i, val, len;
1965 int ret;
1966
1967 ret = read_poll_timeout(rtw89_read8, val, val == 0, 1000, 5000, false,
1968 rtwdev, chip->h2c_ctrl_reg);
1969 if (ret) {
1970 rtw89_warn(rtwdev, "FW does not process h2c registers\n");
1971 return ret;
1972 }
1973
1974 len = DIV_ROUND_UP(info->content_len + RTW89_H2CREG_HDR_LEN,
1975 sizeof(info->h2creg[0]));
1976
1977 RTW89_SET_H2CREG_HDR_FUNC(&info->h2creg[0], info->id);
1978 RTW89_SET_H2CREG_HDR_LEN(&info->h2creg[0], len);
1979 for (i = 0; i < RTW89_H2CREG_MAX; i++)
1980 rtw89_write32(rtwdev, h2c_reg[i], info->h2creg[i]);
1981
1982 rtw89_write8(rtwdev, chip->h2c_ctrl_reg, B_AX_H2CREG_TRIGGER);
1983
1984 return 0;
1985 }
1986
1987 static int rtw89_fw_read_c2h_reg(struct rtw89_dev *rtwdev,
1988 struct rtw89_mac_c2h_info *info)
1989 {
1990 const struct rtw89_chip_info *chip = rtwdev->chip;
1991 const u32 *c2h_reg = chip->c2h_regs;
1992 u32 ret;
1993 u8 i, val;
1994
1995 info->id = RTW89_FWCMD_C2HREG_FUNC_NULL;
1996
1997 ret = read_poll_timeout_atomic(rtw89_read8, val, val, 1,
1998 RTW89_C2H_TIMEOUT, false, rtwdev,
1999 chip->c2h_ctrl_reg);
2000 if (ret) {
2001 rtw89_warn(rtwdev, "c2h reg timeout\n");
2002 return ret;
2003 }
2004
2005 for (i = 0; i < RTW89_C2HREG_MAX; i++)
2006 info->c2hreg[i] = rtw89_read32(rtwdev, c2h_reg[i]);
2007
2008 rtw89_write8(rtwdev, chip->c2h_ctrl_reg, 0);
2009
2010 info->id = RTW89_GET_C2H_HDR_FUNC(*info->c2hreg);
2011 info->content_len = (RTW89_GET_C2H_HDR_LEN(*info->c2hreg) << 2) -
2012 RTW89_C2HREG_HDR_LEN;
2013
2014 return 0;
2015 }
2016
2017 int rtw89_fw_msg_reg(struct rtw89_dev *rtwdev,
2018 struct rtw89_mac_h2c_info *h2c_info,
2019 struct rtw89_mac_c2h_info *c2h_info)
2020 {
2021 u32 ret;
2022
2023 if (h2c_info && h2c_info->id != RTW89_FWCMD_H2CREG_FUNC_GET_FEATURE)
2024 lockdep_assert_held(&rtwdev->mutex);
2025
2026 if (!h2c_info && !c2h_info)
2027 return -EINVAL;
2028
2029 if (!h2c_info)
2030 goto recv_c2h;
2031
2032 ret = rtw89_fw_write_h2c_reg(rtwdev, h2c_info);
2033 if (ret)
2034 return ret;
2035
2036 recv_c2h:
2037 if (!c2h_info)
2038 return 0;
2039
2040 ret = rtw89_fw_read_c2h_reg(rtwdev, c2h_info);
2041 if (ret)
2042 return ret;
2043
2044 return 0;
2045 }
2046
2047 void rtw89_fw_st_dbg_dump(struct rtw89_dev *rtwdev)
2048 {
2049 if (!test_bit(RTW89_FLAG_POWERON, rtwdev->flags)) {
2050 rtw89_err(rtwdev, "[ERR]pwr is off\n");
2051 return;
2052 }
2053
2054 rtw89_info(rtwdev, "FW status = 0x%x\n", rtw89_read32(rtwdev, R_AX_UDM0));
2055 rtw89_info(rtwdev, "FW BADADDR = 0x%x\n", rtw89_read32(rtwdev, R_AX_UDM1));
2056 rtw89_info(rtwdev, "FW EPC/RA = 0x%x\n", rtw89_read32(rtwdev, R_AX_UDM2));
2057 rtw89_info(rtwdev, "FW MISC = 0x%x\n", rtw89_read32(rtwdev, R_AX_UDM3));
2058 rtw89_info(rtwdev, "R_AX_HALT_C2H = 0x%x\n",
2059 rtw89_read32(rtwdev, R_AX_HALT_C2H));
2060 rtw89_info(rtwdev, "R_AX_SER_DBG_INFO = 0x%x\n",
2061 rtw89_read32(rtwdev, R_AX_SER_DBG_INFO));
2062
2063 rtw89_fw_prog_cnt_dump(rtwdev);
2064 }
2065
2066 static void rtw89_release_pkt_list(struct rtw89_dev *rtwdev)
2067 {
2068 struct list_head *pkt_list = rtwdev->scan_info.pkt_list;
2069 struct rtw89_pktofld_info *info, *tmp;
2070 u8 idx;
2071
2072 for (idx = NL80211_BAND_2GHZ; idx < NUM_NL80211_BANDS; idx++) {
2073 if (!(rtwdev->chip->support_bands & BIT(idx)))
2074 continue;
2075
2076 list_for_each_entry_safe(info, tmp, &pkt_list[idx], list) {
2077 rtw89_fw_h2c_del_pkt_offload(rtwdev, info->id);
2078 rtw89_core_release_bit_map(rtwdev->pkt_offload,
2079 info->id);
2080 list_del(&info->list);
2081 kfree(info);
2082 }
2083 }
2084 }
2085
2086 static int rtw89_append_probe_req_ie(struct rtw89_dev *rtwdev,
2087 struct rtw89_vif *rtwvif,
2088 struct sk_buff *skb)
2089 {
2090 struct rtw89_hw_scan_info *scan_info = &rtwdev->scan_info;
2091 struct ieee80211_scan_ies *ies = rtwvif->scan_ies;
2092 struct rtw89_pktofld_info *info;
2093 struct sk_buff *new;
2094 int ret = 0;
2095 u8 band;
2096
2097 for (band = NL80211_BAND_2GHZ; band < NUM_NL80211_BANDS; band++) {
2098 if (!(rtwdev->chip->support_bands & BIT(band)))
2099 continue;
2100
2101 new = skb_copy(skb, GFP_KERNEL);
2102 if (!new) {
2103 ret = -ENOMEM;
2104 goto out;
2105 }
2106 skb_put_data(new, ies->ies[band], ies->len[band]);
2107 skb_put_data(new, ies->common_ies, ies->common_ie_len);
2108
2109 info = kzalloc(sizeof(*info), GFP_KERNEL);
2110 if (!info) {
2111 ret = -ENOMEM;
2112 kfree_skb(new);
2113 goto out;
2114 }
2115
2116 list_add_tail(&info->list, &scan_info->pkt_list[band]);
2117 ret = rtw89_fw_h2c_add_pkt_offload(rtwdev, &info->id, new);
2118 if (ret)
2119 goto out;
2120
2121 kfree_skb(new);
2122 }
2123 out:
2124 return ret;
2125 }
2126
2127 static int rtw89_hw_scan_update_probe_req(struct rtw89_dev *rtwdev,
2128 struct rtw89_vif *rtwvif)
2129 {
2130 struct cfg80211_scan_request *req = rtwvif->scan_req;
2131 struct sk_buff *skb;
2132 u8 num = req->n_ssids, i;
2133 int ret;
2134
2135 for (i = 0; i < num; i++) {
2136 skb = ieee80211_probereq_get(rtwdev->hw, rtwvif->mac_addr,
2137 req->ssids[i].ssid,
2138 req->ssids[i].ssid_len,
2139 req->ie_len);
2140 if (!skb)
2141 return -ENOMEM;
2142
2143 ret = rtw89_append_probe_req_ie(rtwdev, rtwvif, skb);
2144 kfree_skb(skb);
2145
2146 if (ret)
2147 return ret;
2148 }
2149
2150 return 0;
2151 }
2152
2153 static void rtw89_hw_scan_add_chan(struct rtw89_dev *rtwdev, int chan_type,
2154 int ssid_num,
2155 struct rtw89_mac_chinfo *ch_info)
2156 {
2157 struct rtw89_hw_scan_info *scan_info = &rtwdev->scan_info;
2158 struct rtw89_pktofld_info *info;
2159 u8 band, probe_count = 0;
2160
2161 ch_info->notify_action = RTW89_SCANOFLD_DEBUG_MASK;
2162 ch_info->dfs_ch = chan_type == RTW89_CHAN_DFS;
2163 ch_info->bw = RTW89_SCAN_WIDTH;
2164 ch_info->tx_pkt = true;
2165 ch_info->cfg_tx_pwr = false;
2166 ch_info->tx_pwr_idx = 0;
2167 ch_info->tx_null = false;
2168 ch_info->pause_data = false;
2169
2170 if (ssid_num) {
2171 ch_info->num_pkt = ssid_num;
2172 band = ch_info->ch_band;
2173
2174 list_for_each_entry(info, &scan_info->pkt_list[band], list) {
2175 ch_info->probe_id = info->id;
2176 ch_info->pkt_id[probe_count] = info->id;
2177 if (++probe_count >= ssid_num)
2178 break;
2179 }
2180 if (probe_count != ssid_num)
2181 rtw89_err(rtwdev, "SSID num differs from list len\n");
2182 }
2183
2184 switch (chan_type) {
2185 case RTW89_CHAN_OPERATE:
2186 ch_info->probe_id = RTW89_SCANOFLD_PKT_NONE;
2187 ch_info->central_ch = scan_info->op_chan;
2188 ch_info->pri_ch = scan_info->op_pri_ch;
2189 ch_info->ch_band = scan_info->op_band;
2190 ch_info->bw = scan_info->op_bw;
2191 ch_info->tx_null = true;
2192 ch_info->num_pkt = 0;
2193 break;
2194 case RTW89_CHAN_DFS:
2195 ch_info->period = max_t(u8, ch_info->period,
2196 RTW89_DFS_CHAN_TIME);
2197 ch_info->dwell_time = RTW89_DWELL_TIME;
2198 break;
2199 case RTW89_CHAN_ACTIVE:
2200 break;
2201 default:
2202 rtw89_err(rtwdev, "Channel type out of bound\n");
2203 }
2204 }
2205
2206 static int rtw89_hw_scan_add_chan_list(struct rtw89_dev *rtwdev,
2207 struct rtw89_vif *rtwvif)
2208 {
2209 struct cfg80211_scan_request *req = rtwvif->scan_req;
2210 struct rtw89_mac_chinfo *ch_info, *tmp;
2211 struct ieee80211_channel *channel;
2212 struct list_head chan_list;
2213 bool random_seq = req->flags & NL80211_SCAN_FLAG_RANDOM_SN;
2214 int list_len = req->n_channels, off_chan_time = 0;
2215 enum rtw89_chan_type type;
2216 int ret = 0, i;
2217
2218 INIT_LIST_HEAD(&chan_list);
2219 for (i = 0; i < req->n_channels; i++) {
2220 channel = req->channels[i];
2221 ch_info = kzalloc(sizeof(*ch_info), GFP_KERNEL);
2222 if (!ch_info) {
2223 ret = -ENOMEM;
2224 goto out;
2225 }
2226
2227 ch_info->period = req->duration_mandatory ?
2228 req->duration : RTW89_CHANNEL_TIME;
2229 ch_info->ch_band = channel->band;
2230 ch_info->central_ch = channel->hw_value;
2231 ch_info->pri_ch = channel->hw_value;
2232 ch_info->rand_seq_num = random_seq;
2233
2234 if (channel->flags &
2235 (IEEE80211_CHAN_RADAR | IEEE80211_CHAN_NO_IR))
2236 type = RTW89_CHAN_DFS;
2237 else
2238 type = RTW89_CHAN_ACTIVE;
2239 rtw89_hw_scan_add_chan(rtwdev, type, req->n_ssids, ch_info);
2240
2241 if (rtwvif->net_type != RTW89_NET_TYPE_NO_LINK &&
2242 off_chan_time + ch_info->period > RTW89_OFF_CHAN_TIME) {
2243 tmp = kzalloc(sizeof(*tmp), GFP_KERNEL);
2244 if (!tmp) {
2245 ret = -ENOMEM;
2246 kfree(ch_info);
2247 goto out;
2248 }
2249
2250 type = RTW89_CHAN_OPERATE;
2251 tmp->period = req->duration_mandatory ?
2252 req->duration : RTW89_CHANNEL_TIME;
2253 rtw89_hw_scan_add_chan(rtwdev, type, 0, tmp);
2254 list_add_tail(&tmp->list, &chan_list);
2255 off_chan_time = 0;
2256 list_len++;
2257 }
2258 list_add_tail(&ch_info->list, &chan_list);
2259 off_chan_time += ch_info->period;
2260 }
2261 ret = rtw89_fw_h2c_scan_list_offload(rtwdev, list_len, &chan_list);
2262
2263 out:
2264 list_for_each_entry_safe(ch_info, tmp, &chan_list, list) {
2265 list_del(&ch_info->list);
2266 kfree(ch_info);
2267 }
2268
2269 return ret;
2270 }
2271
2272 static int rtw89_hw_scan_prehandle(struct rtw89_dev *rtwdev,
2273 struct rtw89_vif *rtwvif)
2274 {
2275 int ret;
2276
2277 ret = rtw89_hw_scan_update_probe_req(rtwdev, rtwvif);
2278 if (ret) {
2279 rtw89_err(rtwdev, "Update probe request failed\n");
2280 goto out;
2281 }
2282 ret = rtw89_hw_scan_add_chan_list(rtwdev, rtwvif);
2283 out:
2284 return ret;
2285 }
2286
2287 void rtw89_hw_scan_start(struct rtw89_dev *rtwdev, struct ieee80211_vif *vif,
2288 struct ieee80211_scan_request *scan_req)
2289 {
2290 struct rtw89_vif *rtwvif = (struct rtw89_vif *)vif->drv_priv;
2291 struct cfg80211_scan_request *req = &scan_req->req;
2292 u8 mac_addr[ETH_ALEN];
2293
2294 rtwdev->scan_info.scanning_vif = vif;
2295 rtwvif->scan_ies = &scan_req->ies;
2296 rtwvif->scan_req = req;
2297 ieee80211_stop_queues(rtwdev->hw);
2298
2299 if (req->flags & NL80211_SCAN_FLAG_RANDOM_ADDR)
2300 get_random_mask_addr(mac_addr, req->mac_addr,
2301 req->mac_addr_mask);
2302 else
2303 ether_addr_copy(mac_addr, vif->addr);
2304 rtw89_core_scan_start(rtwdev, rtwvif, mac_addr, true);
2305
2306 rtwdev->hal.rx_fltr &= ~B_AX_A_BCN_CHK_EN;
2307 rtwdev->hal.rx_fltr &= ~B_AX_A_BC;
2308 rtwdev->hal.rx_fltr &= ~B_AX_A_A1_MATCH;
2309 rtw89_write32_mask(rtwdev,
2310 rtw89_mac_reg_by_idx(R_AX_RX_FLTR_OPT, RTW89_MAC_0),
2311 B_AX_RX_FLTR_CFG_MASK,
2312 rtwdev->hal.rx_fltr);
2313 }
2314
2315 void rtw89_hw_scan_complete(struct rtw89_dev *rtwdev, struct ieee80211_vif *vif,
2316 bool aborted)
2317 {
2318 struct cfg80211_scan_info info = {
2319 .aborted = aborted,
2320 };
2321 struct rtw89_vif *rtwvif;
2322
2323 if (!vif)
2324 return;
2325
2326 rtwdev->hal.rx_fltr |= B_AX_A_BCN_CHK_EN;
2327 rtwdev->hal.rx_fltr |= B_AX_A_BC;
2328 rtwdev->hal.rx_fltr |= B_AX_A_A1_MATCH;
2329 rtw89_write32_mask(rtwdev,
2330 rtw89_mac_reg_by_idx(R_AX_RX_FLTR_OPT, RTW89_MAC_0),
2331 B_AX_RX_FLTR_CFG_MASK,
2332 rtwdev->hal.rx_fltr);
2333
2334 rtw89_core_scan_complete(rtwdev, vif, true);
2335 ieee80211_scan_completed(rtwdev->hw, &info);
2336 ieee80211_wake_queues(rtwdev->hw);
2337
2338 rtw89_release_pkt_list(rtwdev);
2339 rtwvif = (struct rtw89_vif *)vif->drv_priv;
2340 rtwvif->scan_req = NULL;
2341 rtwvif->scan_ies = NULL;
2342 rtwdev->scan_info.scanning_vif = NULL;
2343
2344 if (rtwvif->net_type != RTW89_NET_TYPE_NO_LINK)
2345 rtw89_store_op_chan(rtwdev, false);
2346 }
2347
2348 void rtw89_hw_scan_abort(struct rtw89_dev *rtwdev, struct ieee80211_vif *vif)
2349 {
2350 rtw89_hw_scan_offload(rtwdev, vif, false);
2351 rtw89_hw_scan_complete(rtwdev, vif, true);
2352 }
2353
2354 int rtw89_hw_scan_offload(struct rtw89_dev *rtwdev, struct ieee80211_vif *vif,
2355 bool enable)
2356 {
2357 struct rtw89_scan_option opt = {0};
2358 struct rtw89_vif *rtwvif;
2359 int ret = 0;
2360
2361 rtwvif = vif ? (struct rtw89_vif *)vif->drv_priv : NULL;
2362 if (!rtwvif)
2363 return -EINVAL;
2364
2365 opt.enable = enable;
2366 opt.target_ch_mode = rtwvif->net_type != RTW89_NET_TYPE_NO_LINK;
2367 if (enable) {
2368 ret = rtw89_hw_scan_prehandle(rtwdev, rtwvif);
2369 if (ret)
2370 goto out;
2371 }
2372 ret = rtw89_fw_h2c_scan_offload(rtwdev, &opt, rtwvif);
2373 out:
2374 return ret;
2375 }
2376
2377 void rtw89_store_op_chan(struct rtw89_dev *rtwdev, bool backup)
2378 {
2379 struct rtw89_hw_scan_info *scan_info = &rtwdev->scan_info;
2380 struct rtw89_hal *hal = &rtwdev->hal;
2381
2382 if (backup) {
2383 scan_info->op_pri_ch = hal->current_primary_channel;
2384 scan_info->op_chan = hal->current_channel;
2385 scan_info->op_bw = hal->current_band_width;
2386 scan_info->op_band = hal->current_band_type;
2387 } else {
2388 hal->current_primary_channel = scan_info->op_pri_ch;
2389 hal->current_channel = scan_info->op_chan;
2390 hal->current_band_width = scan_info->op_bw;
2391 hal->current_band_type = scan_info->op_band;
2392 }
2393 }
2394
2395 #define H2C_FW_CPU_EXCEPTION_LEN 4
2396 #define H2C_FW_CPU_EXCEPTION_TYPE_DEF 0x5566
2397 int rtw89_fw_h2c_trigger_cpu_exception(struct rtw89_dev *rtwdev)
2398 {
2399 struct sk_buff *skb;
2400
2401 skb = rtw89_fw_h2c_alloc_skb_with_hdr(rtwdev, H2C_FW_CPU_EXCEPTION_LEN);
2402 if (!skb) {
2403 rtw89_err(rtwdev,
2404 "failed to alloc skb for fw cpu exception\n");
2405 return -ENOMEM;
2406 }
2407
2408 skb_put(skb, H2C_FW_CPU_EXCEPTION_LEN);
2409 RTW89_SET_FWCMD_CPU_EXCEPTION_TYPE(skb->data,
2410 H2C_FW_CPU_EXCEPTION_TYPE_DEF);
2411
2412 rtw89_h2c_pkt_set_hdr(rtwdev, skb, FWCMD_TYPE_H2C,
2413 H2C_CAT_TEST,
2414 H2C_CL_FW_STATUS_TEST,
2415 H2C_FUNC_CPU_EXCEPTION, 0, 0,
2416 H2C_FW_CPU_EXCEPTION_LEN);
2417
2418 if (rtw89_h2c_tx(rtwdev, skb, false)) {
2419 rtw89_err(rtwdev, "failed to send h2c\n");
2420 goto fail;
2421 }
2422
2423 return 0;
2424
2425 fail:
2426 dev_kfree_skb_any(skb);
2427 return -EBUSY;
2428 }