The Design and Implementation of the FreeBSD Operating System, Second Edition
Now available: The Design and Implementation of the FreeBSD Operating System (Second Edition)


[ source navigation ] [ diff markup ] [ identifier search ] [ freetext search ] [ file search ] [ list types ] [ track identifier ]

FreeBSD/Linux Kernel Cross Reference
sys/contrib/dev/rtw89/fw.c

Version: -  FREEBSD  -  FREEBSD-13-STABLE  -  FREEBSD-13-0  -  FREEBSD-12-STABLE  -  FREEBSD-12-0  -  FREEBSD-11-STABLE  -  FREEBSD-11-0  -  FREEBSD-10-STABLE  -  FREEBSD-10-0  -  FREEBSD-9-STABLE  -  FREEBSD-9-0  -  FREEBSD-8-STABLE  -  FREEBSD-8-0  -  FREEBSD-7-STABLE  -  FREEBSD-7-0  -  FREEBSD-6-STABLE  -  FREEBSD-6-0  -  FREEBSD-5-STABLE  -  FREEBSD-5-0  -  FREEBSD-4-STABLE  -  FREEBSD-3-STABLE  -  FREEBSD22  -  l41  -  OPENBSD  -  linux-2.6  -  MK84  -  PLAN9  -  xnu-8792 
SearchContext: -  none  -  3  -  10 

    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 
   14 static struct sk_buff *rtw89_fw_h2c_alloc_skb(struct rtw89_dev *rtwdev, u32 len,
   15                                               bool header)
   16 {
   17         struct sk_buff *skb;
   18         u32 header_len = 0;
   19         u32 h2c_desc_size = rtwdev->chip->h2c_desc_size;
   20 
   21         if (header)
   22                 header_len = H2C_HEADER_LEN;
   23 
   24         skb = dev_alloc_skb(len + header_len + h2c_desc_size);
   25         if (!skb)
   26                 return NULL;
   27         skb_reserve(skb, header_len + h2c_desc_size);
   28         memset(skb->data, 0, len);
   29 
   30         return skb;
   31 }
   32 
   33 struct sk_buff *rtw89_fw_h2c_alloc_skb_with_hdr(struct rtw89_dev *rtwdev, u32 len)
   34 {
   35         return rtw89_fw_h2c_alloc_skb(rtwdev, len, true);
   36 }
   37 
   38 struct sk_buff *rtw89_fw_h2c_alloc_skb_no_hdr(struct rtw89_dev *rtwdev, u32 len)
   39 {
   40         return rtw89_fw_h2c_alloc_skb(rtwdev, len, false);
   41 }
   42 
   43 static u8 _fw_get_rdy(struct rtw89_dev *rtwdev)
   44 {
   45         u8 val = rtw89_read8(rtwdev, R_AX_WCPU_FW_CTRL);
   46 
   47         return FIELD_GET(B_AX_WCPU_FWDL_STS_MASK, val);
   48 }
   49 
   50 #define FWDL_WAIT_CNT 400000
   51 int rtw89_fw_check_rdy(struct rtw89_dev *rtwdev)
   52 {
   53         u8 val;
   54         int ret;
   55 
   56         ret = read_poll_timeout_atomic(_fw_get_rdy, val,
   57                                        val == RTW89_FWDL_WCPU_FW_INIT_RDY,
   58                                        1, FWDL_WAIT_CNT, false, rtwdev);
   59         if (ret) {
   60                 switch (val) {
   61                 case RTW89_FWDL_CHECKSUM_FAIL:
   62                         rtw89_err(rtwdev, "fw checksum fail\n");
   63                         return -EINVAL;
   64 
   65                 case RTW89_FWDL_SECURITY_FAIL:
   66                         rtw89_err(rtwdev, "fw security fail\n");
   67                         return -EINVAL;
   68 
   69                 case RTW89_FWDL_CV_NOT_MATCH:
   70                         rtw89_err(rtwdev, "fw cv not match\n");
   71                         return -EINVAL;
   72 
   73                 default:
   74                         return -EBUSY;
   75                 }
   76         }
   77 
   78         set_bit(RTW89_FLAG_FW_RDY, rtwdev->flags);
   79 
   80         return 0;
   81 }
   82 
   83 static int rtw89_fw_hdr_parser(struct rtw89_dev *rtwdev, const u8 *fw, u32 len,
   84                                struct rtw89_fw_bin_info *info)
   85 {
   86         struct rtw89_fw_hdr_section_info *section_info;
   87         const u8 *fw_end = fw + len;
   88         const u8 *bin;
   89         u32 i;
   90 
   91         if (!info)
   92                 return -EINVAL;
   93 
   94         info->section_num = GET_FW_HDR_SEC_NUM(fw);
   95         info->hdr_len = RTW89_FW_HDR_SIZE +
   96                         info->section_num * RTW89_FW_SECTION_HDR_SIZE;
   97 
   98         bin = fw + info->hdr_len;
   99 
  100         /* jump to section header */
  101         fw += RTW89_FW_HDR_SIZE;
  102         section_info = info->section_info;
  103         for (i = 0; i < info->section_num; i++) {
  104                 section_info->len = GET_FWSECTION_HDR_SEC_SIZE(fw);
  105                 if (GET_FWSECTION_HDR_CHECKSUM(fw))
  106                         section_info->len += FWDL_SECTION_CHKSUM_LEN;
  107                 section_info->redl = GET_FWSECTION_HDR_REDL(fw);
  108                 section_info->dladdr =
  109                                 GET_FWSECTION_HDR_DL_ADDR(fw) & 0x1fffffff;
  110                 section_info->addr = bin;
  111                 bin += section_info->len;
  112                 fw += RTW89_FW_SECTION_HDR_SIZE;
  113                 section_info++;
  114         }
  115 
  116         if (fw_end != bin) {
  117                 rtw89_err(rtwdev, "[ERR]fw bin size\n");
  118                 return -EINVAL;
  119         }
  120 
  121         return 0;
  122 }
  123 
  124 static
  125 int rtw89_mfw_recognize(struct rtw89_dev *rtwdev, enum rtw89_fw_type type,
  126                         struct rtw89_fw_suit *fw_suit)
  127 {
  128         struct rtw89_fw_info *fw_info = &rtwdev->fw;
  129         const u8 *mfw = fw_info->firmware->data;
  130         u32 mfw_len = fw_info->firmware->size;
  131         const struct rtw89_mfw_hdr *mfw_hdr = (const struct rtw89_mfw_hdr *)mfw;
  132         const struct rtw89_mfw_info *mfw_info;
  133         int i;
  134 
  135         if (mfw_hdr->sig != RTW89_MFW_SIG) {
  136                 rtw89_debug(rtwdev, RTW89_DBG_FW, "use legacy firmware\n");
  137                 /* legacy firmware support normal type only */
  138                 if (type != RTW89_FW_NORMAL)
  139                         return -EINVAL;
  140                 fw_suit->data = mfw;
  141                 fw_suit->size = mfw_len;
  142                 return 0;
  143         }
  144 
  145         for (i = 0; i < mfw_hdr->fw_nr; i++) {
  146                 mfw_info = &mfw_hdr->info[i];
  147                 if (mfw_info->cv != rtwdev->hal.cv ||
  148                     mfw_info->type != type ||
  149                     mfw_info->mp)
  150                         continue;
  151 
  152                 fw_suit->data = mfw + le32_to_cpu(mfw_info->shift);
  153                 fw_suit->size = le32_to_cpu(mfw_info->size);
  154                 return 0;
  155         }
  156 
  157         rtw89_err(rtwdev, "no suitable firmware found\n");
  158         return -ENOENT;
  159 }
  160 
  161 static void rtw89_fw_update_ver(struct rtw89_dev *rtwdev,
  162                                 enum rtw89_fw_type type,
  163                                 struct rtw89_fw_suit *fw_suit)
  164 {
  165         const u8 *hdr = fw_suit->data;
  166 
  167         fw_suit->major_ver = GET_FW_HDR_MAJOR_VERSION(hdr);
  168         fw_suit->minor_ver = GET_FW_HDR_MINOR_VERSION(hdr);
  169         fw_suit->sub_ver = GET_FW_HDR_SUBVERSION(hdr);
  170         fw_suit->sub_idex = GET_FW_HDR_SUBINDEX(hdr);
  171         fw_suit->build_year = GET_FW_HDR_YEAR(hdr);
  172         fw_suit->build_mon = GET_FW_HDR_MONTH(hdr);
  173         fw_suit->build_date = GET_FW_HDR_DATE(hdr);
  174         fw_suit->build_hour = GET_FW_HDR_HOUR(hdr);
  175         fw_suit->build_min = GET_FW_HDR_MIN(hdr);
  176         fw_suit->cmd_ver = GET_FW_HDR_CMD_VERSERION(hdr);
  177 
  178         rtw89_info(rtwdev,
  179                    "Firmware version %u.%u.%u.%u, cmd version %u, type %u\n",
  180                    fw_suit->major_ver, fw_suit->minor_ver, fw_suit->sub_ver,
  181                    fw_suit->sub_idex, fw_suit->cmd_ver, type);
  182 }
  183 
  184 static
  185 int __rtw89_fw_recognize(struct rtw89_dev *rtwdev, enum rtw89_fw_type type)
  186 {
  187         struct rtw89_fw_suit *fw_suit = rtw89_fw_suit_get(rtwdev, type);
  188         int ret;
  189 
  190         ret = rtw89_mfw_recognize(rtwdev, type, fw_suit);
  191         if (ret)
  192                 return ret;
  193 
  194         rtw89_fw_update_ver(rtwdev, type, fw_suit);
  195 
  196         return 0;
  197 }
  198 
  199 #define __DEF_FW_FEAT_COND(__cond, __op) \
  200 static bool __fw_feat_cond_ ## __cond(u32 suit_ver_code, u32 comp_ver_code) \
  201 { \
  202         return suit_ver_code __op comp_ver_code; \
  203 }
  204 
  205 __DEF_FW_FEAT_COND(ge, >=); /* greater or equal */
  206 __DEF_FW_FEAT_COND(le, <=); /* less or equal */
  207 
  208 struct __fw_feat_cfg {
  209         enum rtw89_core_chip_id chip_id;
  210         enum rtw89_fw_feature feature;
  211         u32 ver_code;
  212         bool (*cond)(u32 suit_ver_code, u32 comp_ver_code);
  213 };
  214 
  215 #define __CFG_FW_FEAT(_chip, _cond, _maj, _min, _sub, _idx, _feat) \
  216         { \
  217                 .chip_id = _chip, \
  218                 .feature = RTW89_FW_FEATURE_ ## _feat, \
  219                 .ver_code = RTW89_FW_VER_CODE(_maj, _min, _sub, _idx), \
  220                 .cond = __fw_feat_cond_ ## _cond, \
  221         }
  222 
  223 static const struct __fw_feat_cfg fw_feat_tbl[] = {
  224         __CFG_FW_FEAT(RTL8852A, le, 0, 13, 29, 0, OLD_HT_RA_FORMAT),
  225         __CFG_FW_FEAT(RTL8852A, ge, 0, 13, 35, 0, SCAN_OFFLOAD),
  226         __CFG_FW_FEAT(RTL8852A, ge, 0, 13, 35, 0, TX_WAKE),
  227         __CFG_FW_FEAT(RTL8852A, ge, 0, 13, 36, 0, CRASH_TRIGGER),
  228 };
  229 
  230 static void rtw89_fw_recognize_features(struct rtw89_dev *rtwdev)
  231 {
  232         const struct rtw89_chip_info *chip = rtwdev->chip;
  233         const struct __fw_feat_cfg *ent;
  234         const struct rtw89_fw_suit *fw_suit;
  235         u32 suit_ver_code;
  236         int i;
  237 
  238         fw_suit = rtw89_fw_suit_get(rtwdev, RTW89_FW_NORMAL);
  239         suit_ver_code = RTW89_FW_SUIT_VER_CODE(fw_suit);
  240 
  241         for (i = 0; i < ARRAY_SIZE(fw_feat_tbl); i++) {
  242                 ent = &fw_feat_tbl[i];
  243                 if (chip->chip_id != ent->chip_id)
  244                         continue;
  245 
  246                 if (ent->cond(suit_ver_code, ent->ver_code))
  247                         RTW89_SET_FW_FEATURE(ent->feature, &rtwdev->fw);
  248         }
  249 }
  250 
  251 void rtw89_early_fw_feature_recognize(struct device *device,
  252                                       const struct rtw89_chip_info *chip,
  253                                       u32 *early_feat_map)
  254 {
  255         union {
  256                 struct rtw89_mfw_hdr mfw_hdr;
  257                 u8 fw_hdr[RTW89_FW_HDR_SIZE];
  258         } buf = {};
  259         const struct firmware *firmware;
  260         u32 ver_code;
  261         int ret;
  262         int i;
  263 
  264         ret = request_partial_firmware_into_buf(&firmware, chip->fw_name,
  265                                                 device, &buf, sizeof(buf), 0);
  266         if (ret) {
  267                 dev_err(device, "failed to early request firmware: %d\n", ret);
  268                 goto out;
  269         }
  270 
  271         ver_code = buf.mfw_hdr.sig != RTW89_MFW_SIG ?
  272                    RTW89_FW_HDR_VER_CODE(&buf.fw_hdr) :
  273                    RTW89_MFW_HDR_VER_CODE(&buf.mfw_hdr);
  274         if (!ver_code)
  275                 goto out;
  276 
  277         for (i = 0; i < ARRAY_SIZE(fw_feat_tbl); i++) {
  278                 const struct __fw_feat_cfg *ent = &fw_feat_tbl[i];
  279 
  280                 if (chip->chip_id != ent->chip_id)
  281                         continue;
  282 
  283                 if (ent->cond(ver_code, ent->ver_code))
  284                         *early_feat_map |= BIT(ent->feature);
  285         }
  286 
  287 out:
  288         release_firmware(firmware);
  289 }
  290 
  291 int rtw89_fw_recognize(struct rtw89_dev *rtwdev)
  292 {
  293         int ret;
  294 
  295         ret = __rtw89_fw_recognize(rtwdev, RTW89_FW_NORMAL);
  296         if (ret)
  297                 return ret;
  298 
  299         /* It still works if wowlan firmware isn't existing. */
  300         __rtw89_fw_recognize(rtwdev, RTW89_FW_WOWLAN);
  301 
  302         rtw89_fw_recognize_features(rtwdev);
  303 
  304         return 0;
  305 }
  306 
  307 void rtw89_h2c_pkt_set_hdr(struct rtw89_dev *rtwdev, struct sk_buff *skb,
  308                            u8 type, u8 cat, u8 class, u8 func,
  309                            bool rack, bool dack, u32 len)
  310 {
  311         struct fwcmd_hdr *hdr;
  312 
  313         hdr = (struct fwcmd_hdr *)skb_push(skb, 8);
  314 
  315         if (!(rtwdev->fw.h2c_seq % 4))
  316                 rack = true;
  317         hdr->hdr0 = cpu_to_le32(FIELD_PREP(H2C_HDR_DEL_TYPE, type) |
  318                                 FIELD_PREP(H2C_HDR_CAT, cat) |
  319                                 FIELD_PREP(H2C_HDR_CLASS, class) |
  320                                 FIELD_PREP(H2C_HDR_FUNC, func) |
  321                                 FIELD_PREP(H2C_HDR_H2C_SEQ, rtwdev->fw.h2c_seq));
  322 
  323         hdr->hdr1 = cpu_to_le32(FIELD_PREP(H2C_HDR_TOTAL_LEN,
  324                                            len + H2C_HEADER_LEN) |
  325                                 (rack ? H2C_HDR_REC_ACK : 0) |
  326                                 (dack ? H2C_HDR_DONE_ACK : 0));
  327 
  328         rtwdev->fw.h2c_seq++;
  329 }
  330 
  331 static void rtw89_h2c_pkt_set_hdr_fwdl(struct rtw89_dev *rtwdev,
  332                                        struct sk_buff *skb,
  333                                        u8 type, u8 cat, u8 class, u8 func,
  334                                        u32 len)
  335 {
  336         struct fwcmd_hdr *hdr;
  337 
  338         hdr = (struct fwcmd_hdr *)skb_push(skb, 8);
  339 
  340         hdr->hdr0 = cpu_to_le32(FIELD_PREP(H2C_HDR_DEL_TYPE, type) |
  341                                 FIELD_PREP(H2C_HDR_CAT, cat) |
  342                                 FIELD_PREP(H2C_HDR_CLASS, class) |
  343                                 FIELD_PREP(H2C_HDR_FUNC, func) |
  344                                 FIELD_PREP(H2C_HDR_H2C_SEQ, rtwdev->fw.h2c_seq));
  345 
  346         hdr->hdr1 = cpu_to_le32(FIELD_PREP(H2C_HDR_TOTAL_LEN,
  347                                            len + H2C_HEADER_LEN));
  348 }
  349 
  350 static int __rtw89_fw_download_hdr(struct rtw89_dev *rtwdev, const u8 *fw, u32 len)
  351 {
  352         struct sk_buff *skb;
  353         u32 ret = 0;
  354 
  355         skb = rtw89_fw_h2c_alloc_skb_with_hdr(rtwdev, len);
  356         if (!skb) {
  357                 rtw89_err(rtwdev, "failed to alloc skb for fw hdr dl\n");
  358                 return -ENOMEM;
  359         }
  360 
  361         skb_put_data(skb, fw, len);
  362         SET_FW_HDR_PART_SIZE(skb->data, FWDL_SECTION_PER_PKT_LEN);
  363         rtw89_h2c_pkt_set_hdr_fwdl(rtwdev, skb, FWCMD_TYPE_H2C,
  364                                    H2C_CAT_MAC, H2C_CL_MAC_FWDL,
  365                                    H2C_FUNC_MAC_FWHDR_DL, len);
  366 
  367         ret = rtw89_h2c_tx(rtwdev, skb, false);
  368         if (ret) {
  369                 rtw89_err(rtwdev, "failed to send h2c\n");
  370                 ret = -1;
  371                 goto fail;
  372         }
  373 
  374         return 0;
  375 fail:
  376         dev_kfree_skb_any(skb);
  377 
  378         return ret;
  379 }
  380 
  381 static int rtw89_fw_download_hdr(struct rtw89_dev *rtwdev, const u8 *fw, u32 len)
  382 {
  383         u8 val;
  384         int ret;
  385 
  386         ret = __rtw89_fw_download_hdr(rtwdev, fw, len);
  387         if (ret) {
  388                 rtw89_err(rtwdev, "[ERR]FW header download\n");
  389                 return ret;
  390         }
  391 
  392         ret = read_poll_timeout_atomic(rtw89_read8, val, val & B_AX_FWDL_PATH_RDY,
  393                                        1, FWDL_WAIT_CNT, false,
  394                                        rtwdev, R_AX_WCPU_FW_CTRL);
  395         if (ret) {
  396                 rtw89_err(rtwdev, "[ERR]FWDL path ready\n");
  397                 return ret;
  398         }
  399 
  400         rtw89_write32(rtwdev, R_AX_HALT_H2C_CTRL, 0);
  401         rtw89_write32(rtwdev, R_AX_HALT_C2H_CTRL, 0);
  402 
  403         return 0;
  404 }
  405 
  406 static int __rtw89_fw_download_main(struct rtw89_dev *rtwdev,
  407                                     struct rtw89_fw_hdr_section_info *info)
  408 {
  409         struct sk_buff *skb;
  410         const u8 *section = info->addr;
  411         u32 residue_len = info->len;
  412         u32 pkt_len;
  413         int ret;
  414 
  415         while (residue_len) {
  416                 if (residue_len >= FWDL_SECTION_PER_PKT_LEN)
  417                         pkt_len = FWDL_SECTION_PER_PKT_LEN;
  418                 else
  419                         pkt_len = residue_len;
  420 
  421                 skb = rtw89_fw_h2c_alloc_skb_no_hdr(rtwdev, pkt_len);
  422                 if (!skb) {
  423                         rtw89_err(rtwdev, "failed to alloc skb for fw dl\n");
  424                         return -ENOMEM;
  425                 }
  426                 skb_put_data(skb, section, pkt_len);
  427 
  428                 ret = rtw89_h2c_tx(rtwdev, skb, true);
  429                 if (ret) {
  430                         rtw89_err(rtwdev, "failed to send h2c\n");
  431                         ret = -1;
  432                         goto fail;
  433                 }
  434 
  435                 section += pkt_len;
  436                 residue_len -= pkt_len;
  437         }
  438 
  439         return 0;
  440 fail:
  441         dev_kfree_skb_any(skb);
  442 
  443         return ret;
  444 }
  445 
  446 static int rtw89_fw_download_main(struct rtw89_dev *rtwdev, const u8 *fw,
  447                                   struct rtw89_fw_bin_info *info)
  448 {
  449         struct rtw89_fw_hdr_section_info *section_info = info->section_info;
  450         u8 section_num = info->section_num;
  451         int ret;
  452 
  453         while (section_num--) {
  454                 ret = __rtw89_fw_download_main(rtwdev, section_info);
  455                 if (ret)
  456                         return ret;
  457                 section_info++;
  458         }
  459 
  460         mdelay(5);
  461 
  462         ret = rtw89_fw_check_rdy(rtwdev);
  463         if (ret) {
  464                 rtw89_warn(rtwdev, "download firmware fail\n");
  465                 return ret;
  466         }
  467 
  468         return 0;
  469 }
  470 
  471 static void rtw89_fw_prog_cnt_dump(struct rtw89_dev *rtwdev)
  472 {
  473         u32 val32;
  474         u16 index;
  475 
  476         rtw89_write32(rtwdev, R_AX_DBG_CTRL,
  477                       FIELD_PREP(B_AX_DBG_SEL0, FW_PROG_CNTR_DBG_SEL) |
  478                       FIELD_PREP(B_AX_DBG_SEL1, FW_PROG_CNTR_DBG_SEL));
  479         rtw89_write32_mask(rtwdev, R_AX_SYS_STATUS1, B_AX_SEL_0XC0_MASK, MAC_DBG_SEL);
  480 
  481         for (index = 0; index < 15; index++) {
  482                 val32 = rtw89_read32(rtwdev, R_AX_DBG_PORT_SEL);
  483                 rtw89_err(rtwdev, "[ERR]fw PC = 0x%x\n", val32);
  484                 fsleep(10);
  485         }
  486 }
  487 
  488 static void rtw89_fw_dl_fail_dump(struct rtw89_dev *rtwdev)
  489 {
  490         u32 val32;
  491         u16 val16;
  492 
  493         val32 = rtw89_read32(rtwdev, R_AX_WCPU_FW_CTRL);
  494         rtw89_err(rtwdev, "[ERR]fwdl 0x1E0 = 0x%x\n", val32);
  495 
  496         val16 = rtw89_read16(rtwdev, R_AX_BOOT_DBG + 2);
  497         rtw89_err(rtwdev, "[ERR]fwdl 0x83F2 = 0x%x\n", val16);
  498 
  499         rtw89_fw_prog_cnt_dump(rtwdev);
  500 }
  501 
  502 int rtw89_fw_download(struct rtw89_dev *rtwdev, enum rtw89_fw_type type)
  503 {
  504         struct rtw89_fw_info *fw_info = &rtwdev->fw;
  505         struct rtw89_fw_suit *fw_suit = rtw89_fw_suit_get(rtwdev, type);
  506         struct rtw89_fw_bin_info info;
  507         const u8 *fw = fw_suit->data;
  508         u32 len = fw_suit->size;
  509         u8 val;
  510         int ret;
  511 
  512         if (!fw || !len) {
  513                 rtw89_err(rtwdev, "fw type %d isn't recognized\n", type);
  514                 return -ENOENT;
  515         }
  516 
  517         ret = rtw89_fw_hdr_parser(rtwdev, fw, len, &info);
  518         if (ret) {
  519                 rtw89_err(rtwdev, "parse fw header fail\n");
  520                 goto fwdl_err;
  521         }
  522 
  523         ret = read_poll_timeout_atomic(rtw89_read8, val, val & B_AX_H2C_PATH_RDY,
  524                                        1, FWDL_WAIT_CNT, false,
  525                                        rtwdev, R_AX_WCPU_FW_CTRL);
  526         if (ret) {
  527                 rtw89_err(rtwdev, "[ERR]H2C path ready\n");
  528                 goto fwdl_err;
  529         }
  530 
  531         ret = rtw89_fw_download_hdr(rtwdev, fw, info.hdr_len);
  532         if (ret) {
  533                 ret = -EBUSY;
  534                 goto fwdl_err;
  535         }
  536 
  537         ret = rtw89_fw_download_main(rtwdev, fw, &info);
  538         if (ret) {
  539                 ret = -EBUSY;
  540                 goto fwdl_err;
  541         }
  542 
  543         fw_info->h2c_seq = 0;
  544         fw_info->rec_seq = 0;
  545         rtwdev->mac.rpwm_seq_num = RPWM_SEQ_NUM_MAX;
  546         rtwdev->mac.cpwm_seq_num = CPWM_SEQ_NUM_MAX;
  547 
  548         return ret;
  549 
  550 fwdl_err:
  551         rtw89_fw_dl_fail_dump(rtwdev);
  552         return ret;
  553 }
  554 
  555 int rtw89_wait_firmware_completion(struct rtw89_dev *rtwdev)
  556 {
  557         struct rtw89_fw_info *fw = &rtwdev->fw;
  558 
  559         wait_for_completion(&fw->completion);
  560         if (!fw->firmware)
  561                 return -EINVAL;
  562 
  563         return 0;
  564 }
  565 
  566 static void rtw89_load_firmware_cb(const struct firmware *firmware, void *context)
  567 {
  568         struct rtw89_fw_info *fw = context;
  569         struct rtw89_dev *rtwdev = fw->rtwdev;
  570 
  571         if (!firmware || !firmware->data) {
  572                 rtw89_err(rtwdev, "failed to request firmware\n");
  573                 complete_all(&fw->completion);
  574                 return;
  575         }
  576 
  577         fw->firmware = firmware;
  578         complete_all(&fw->completion);
  579 }
  580 
  581 int rtw89_load_firmware(struct rtw89_dev *rtwdev)
  582 {
  583         struct rtw89_fw_info *fw = &rtwdev->fw;
  584         const char *fw_name = rtwdev->chip->fw_name;
  585         int ret;
  586 
  587         fw->rtwdev = rtwdev;
  588         init_completion(&fw->completion);
  589 
  590         ret = request_firmware_nowait(THIS_MODULE, true, fw_name, rtwdev->dev,
  591                                       GFP_KERNEL, fw, rtw89_load_firmware_cb);
  592         if (ret) {
  593                 rtw89_err(rtwdev, "failed to async firmware request\n");
  594                 return ret;
  595         }
  596 
  597         return 0;
  598 }
  599 
  600 void rtw89_unload_firmware(struct rtw89_dev *rtwdev)
  601 {
  602         struct rtw89_fw_info *fw = &rtwdev->fw;
  603 
  604         rtw89_wait_firmware_completion(rtwdev);
  605 
  606         if (fw->firmware)
  607                 release_firmware(fw->firmware);
  608 }
  609 
  610 #define H2C_CAM_LEN 60
  611 int rtw89_fw_h2c_cam(struct rtw89_dev *rtwdev, struct rtw89_vif *rtwvif,
  612                      struct rtw89_sta *rtwsta, const u8 *scan_mac_addr)
  613 {
  614         struct sk_buff *skb;
  615 
  616         skb = rtw89_fw_h2c_alloc_skb_with_hdr(rtwdev, H2C_CAM_LEN);
  617         if (!skb) {
  618                 rtw89_err(rtwdev, "failed to alloc skb for fw dl\n");
  619                 return -ENOMEM;
  620         }
  621         skb_put(skb, H2C_CAM_LEN);
  622         rtw89_cam_fill_addr_cam_info(rtwdev, rtwvif, rtwsta, scan_mac_addr, skb->data);
  623         rtw89_cam_fill_bssid_cam_info(rtwdev, rtwvif, rtwsta, skb->data);
  624 
  625         rtw89_h2c_pkt_set_hdr(rtwdev, skb, FWCMD_TYPE_H2C,
  626                               H2C_CAT_MAC,
  627                               H2C_CL_MAC_ADDR_CAM_UPDATE,
  628                               H2C_FUNC_MAC_ADDR_CAM_UPD, 0, 1,
  629                               H2C_CAM_LEN);
  630 
  631         if (rtw89_h2c_tx(rtwdev, skb, false)) {
  632                 rtw89_err(rtwdev, "failed to send h2c\n");
  633                 goto fail;
  634         }
  635 
  636         return 0;
  637 fail:
  638         dev_kfree_skb_any(skb);
  639 
  640         return -EBUSY;
  641 }
  642 
  643 #define H2C_DCTL_SEC_CAM_LEN 68
  644 int rtw89_fw_h2c_dctl_sec_cam_v1(struct rtw89_dev *rtwdev,
  645                                  struct rtw89_vif *rtwvif,
  646                                  struct rtw89_sta *rtwsta)
  647 {
  648         struct sk_buff *skb;
  649 
  650         skb = rtw89_fw_h2c_alloc_skb_with_hdr(rtwdev, H2C_DCTL_SEC_CAM_LEN);
  651         if (!skb) {
  652                 rtw89_err(rtwdev, "failed to alloc skb for dctl sec cam\n");
  653                 return -ENOMEM;
  654         }
  655         skb_put(skb, H2C_DCTL_SEC_CAM_LEN);
  656 
  657         rtw89_cam_fill_dctl_sec_cam_info_v1(rtwdev, rtwvif, rtwsta, skb->data);
  658 
  659         rtw89_h2c_pkt_set_hdr(rtwdev, skb, FWCMD_TYPE_H2C,
  660                               H2C_CAT_MAC,
  661                               H2C_CL_MAC_FR_EXCHG,
  662                               H2C_FUNC_MAC_DCTLINFO_UD_V1, 0, 0,
  663                               H2C_DCTL_SEC_CAM_LEN);
  664 
  665         if (rtw89_h2c_tx(rtwdev, skb, false)) {
  666                 rtw89_err(rtwdev, "failed to send h2c\n");
  667                 goto fail;
  668         }
  669 
  670         return 0;
  671 fail:
  672         dev_kfree_skb_any(skb);
  673 
  674         return -EBUSY;
  675 }
  676 EXPORT_SYMBOL(rtw89_fw_h2c_dctl_sec_cam_v1);
  677 
  678 #define H2C_BA_CAM_LEN 8
  679 int rtw89_fw_h2c_ba_cam(struct rtw89_dev *rtwdev, struct rtw89_sta *rtwsta,
  680                         bool valid, struct ieee80211_ampdu_params *params)
  681 {
  682         const struct rtw89_chip_info *chip = rtwdev->chip;
  683         struct rtw89_vif *rtwvif = rtwsta->rtwvif;
  684         u8 macid = rtwsta->mac_id;
  685         struct sk_buff *skb;
  686         u8 entry_idx;
  687         int ret;
  688 
  689         ret = valid ?
  690               rtw89_core_acquire_sta_ba_entry(rtwdev, rtwsta, params->tid, &entry_idx) :
  691               rtw89_core_release_sta_ba_entry(rtwdev, rtwsta, params->tid, &entry_idx);
  692         if (ret) {
  693                 /* it still works even if we don't have static BA CAM, because
  694                  * hardware can create dynamic BA CAM automatically.
  695                  */
  696                 rtw89_debug(rtwdev, RTW89_DBG_TXRX,
  697                             "failed to %s entry tid=%d for h2c ba cam\n",
  698                             valid ? "alloc" : "free", params->tid);
  699                 return 0;
  700         }
  701 
  702         skb = rtw89_fw_h2c_alloc_skb_with_hdr(rtwdev, H2C_BA_CAM_LEN);
  703         if (!skb) {
  704                 rtw89_err(rtwdev, "failed to alloc skb for h2c ba cam\n");
  705                 return -ENOMEM;
  706         }
  707         skb_put(skb, H2C_BA_CAM_LEN);
  708         SET_BA_CAM_MACID(skb->data, macid);
  709         if (chip->bacam_v1)
  710                 SET_BA_CAM_ENTRY_IDX_V1(skb->data, entry_idx);
  711         else
  712                 SET_BA_CAM_ENTRY_IDX(skb->data, entry_idx);
  713         if (!valid)
  714                 goto end;
  715         SET_BA_CAM_VALID(skb->data, valid);
  716         SET_BA_CAM_TID(skb->data, params->tid);
  717         if (params->buf_size > 64)
  718                 SET_BA_CAM_BMAP_SIZE(skb->data, 4);
  719         else
  720                 SET_BA_CAM_BMAP_SIZE(skb->data, 0);
  721         /* If init req is set, hw will set the ssn */
  722         SET_BA_CAM_INIT_REQ(skb->data, 1);
  723         SET_BA_CAM_SSN(skb->data, params->ssn);
  724 
  725         if (chip->bacam_v1) {
  726                 SET_BA_CAM_STD_EN(skb->data, 1);
  727                 SET_BA_CAM_BAND(skb->data, rtwvif->mac_idx);
  728         }
  729 
  730 end:
  731         rtw89_h2c_pkt_set_hdr(rtwdev, skb, FWCMD_TYPE_H2C,
  732                               H2C_CAT_MAC,
  733                               H2C_CL_BA_CAM,
  734                               H2C_FUNC_MAC_BA_CAM, 0, 1,
  735                               H2C_BA_CAM_LEN);
  736 
  737         if (rtw89_h2c_tx(rtwdev, skb, false)) {
  738                 rtw89_err(rtwdev, "failed to send h2c\n");
  739                 goto fail;
  740         }
  741 
  742         return 0;
  743 fail:
  744         dev_kfree_skb_any(skb);
  745 
  746         return -EBUSY;
  747 }
  748 
  749 static int rtw89_fw_h2c_init_dynamic_ba_cam_v1(struct rtw89_dev *rtwdev,
  750                                                u8 entry_idx, u8 uid)
  751 {
  752         struct sk_buff *skb;
  753 
  754         skb = rtw89_fw_h2c_alloc_skb_with_hdr(rtwdev, H2C_BA_CAM_LEN);
  755         if (!skb) {
  756                 rtw89_err(rtwdev, "failed to alloc skb for dynamic h2c ba cam\n");
  757                 return -ENOMEM;
  758         }
  759         skb_put(skb, H2C_BA_CAM_LEN);
  760 
  761         SET_BA_CAM_VALID(skb->data, 1);
  762         SET_BA_CAM_ENTRY_IDX_V1(skb->data, entry_idx);
  763         SET_BA_CAM_UID(skb->data, uid);
  764         SET_BA_CAM_BAND(skb->data, 0);
  765         SET_BA_CAM_STD_EN(skb->data, 0);
  766 
  767         rtw89_h2c_pkt_set_hdr(rtwdev, skb, FWCMD_TYPE_H2C,
  768                               H2C_CAT_MAC,
  769                               H2C_CL_BA_CAM,
  770                               H2C_FUNC_MAC_BA_CAM, 0, 1,
  771                               H2C_BA_CAM_LEN);
  772 
  773         if (rtw89_h2c_tx(rtwdev, skb, false)) {
  774                 rtw89_err(rtwdev, "failed to send h2c\n");
  775                 goto fail;
  776         }
  777 
  778         return 0;
  779 fail:
  780         dev_kfree_skb_any(skb);
  781 
  782         return -EBUSY;
  783 }
  784 
  785 void rtw89_fw_h2c_init_ba_cam_v1(struct rtw89_dev *rtwdev)
  786 {
  787         const struct rtw89_chip_info *chip = rtwdev->chip;
  788         u8 entry_idx = chip->bacam_num;
  789         u8 uid = 0;
  790         int i;
  791 
  792         for (i = 0; i < chip->bacam_dynamic_num; i++) {
  793                 rtw89_fw_h2c_init_dynamic_ba_cam_v1(rtwdev, entry_idx, uid);
  794                 entry_idx++;
  795                 uid++;
  796         }
  797 }
  798 
  799 #define H2C_LOG_CFG_LEN 12
  800 int rtw89_fw_h2c_fw_log(struct rtw89_dev *rtwdev, bool enable)
  801 {
  802         struct sk_buff *skb;
  803         u32 comp = enable ? BIT(RTW89_FW_LOG_COMP_INIT) | BIT(RTW89_FW_LOG_COMP_TASK) |
  804                             BIT(RTW89_FW_LOG_COMP_PS) | BIT(RTW89_FW_LOG_COMP_ERROR) : 0;
  805 
  806         skb = rtw89_fw_h2c_alloc_skb_with_hdr(rtwdev, H2C_LOG_CFG_LEN);
  807         if (!skb) {
  808                 rtw89_err(rtwdev, "failed to alloc skb for fw log cfg\n");
  809                 return -ENOMEM;
  810         }
  811 
  812         skb_put(skb, H2C_LOG_CFG_LEN);
  813         SET_LOG_CFG_LEVEL(skb->data, RTW89_FW_LOG_LEVEL_SER);
  814         SET_LOG_CFG_PATH(skb->data, BIT(RTW89_FW_LOG_LEVEL_C2H));
  815         SET_LOG_CFG_COMP(skb->data, comp);
  816         SET_LOG_CFG_COMP_EXT(skb->data, 0);
  817 
  818         rtw89_h2c_pkt_set_hdr(rtwdev, skb, FWCMD_TYPE_H2C,
  819                               H2C_CAT_MAC,
  820                               H2C_CL_FW_INFO,
  821                               H2C_FUNC_LOG_CFG, 0, 0,
  822                               H2C_LOG_CFG_LEN);
  823 
  824         if (rtw89_h2c_tx(rtwdev, skb, false)) {
  825                 rtw89_err(rtwdev, "failed to send h2c\n");
  826                 goto fail;
  827         }
  828 
  829         return 0;
  830 fail:
  831         dev_kfree_skb_any(skb);
  832 
  833         return -EBUSY;
  834 }
  835 
  836 #define H2C_GENERAL_PKT_LEN 6
  837 #define H2C_GENERAL_PKT_ID_UND 0xff
  838 int rtw89_fw_h2c_general_pkt(struct rtw89_dev *rtwdev, u8 macid)
  839 {
  840         struct sk_buff *skb;
  841 
  842         skb = rtw89_fw_h2c_alloc_skb_with_hdr(rtwdev, H2C_GENERAL_PKT_LEN);
  843         if (!skb) {
  844                 rtw89_err(rtwdev, "failed to alloc skb for fw dl\n");
  845                 return -ENOMEM;
  846         }
  847         skb_put(skb, H2C_GENERAL_PKT_LEN);
  848         SET_GENERAL_PKT_MACID(skb->data, macid);
  849         SET_GENERAL_PKT_PROBRSP_ID(skb->data, H2C_GENERAL_PKT_ID_UND);
  850         SET_GENERAL_PKT_PSPOLL_ID(skb->data, H2C_GENERAL_PKT_ID_UND);
  851         SET_GENERAL_PKT_NULL_ID(skb->data, H2C_GENERAL_PKT_ID_UND);
  852         SET_GENERAL_PKT_QOS_NULL_ID(skb->data, H2C_GENERAL_PKT_ID_UND);
  853         SET_GENERAL_PKT_CTS2SELF_ID(skb->data, H2C_GENERAL_PKT_ID_UND);
  854 
  855         rtw89_h2c_pkt_set_hdr(rtwdev, skb, FWCMD_TYPE_H2C,
  856                               H2C_CAT_MAC,
  857                               H2C_CL_FW_INFO,
  858                               H2C_FUNC_MAC_GENERAL_PKT, 0, 1,
  859                               H2C_GENERAL_PKT_LEN);
  860 
  861         if (rtw89_h2c_tx(rtwdev, skb, false)) {
  862                 rtw89_err(rtwdev, "failed to send h2c\n");
  863                 goto fail;
  864         }
  865 
  866         return 0;
  867 fail:
  868         dev_kfree_skb_any(skb);
  869 
  870         return -EBUSY;
  871 }
  872 
  873 #define H2C_LPS_PARM_LEN 8
  874 int rtw89_fw_h2c_lps_parm(struct rtw89_dev *rtwdev,
  875                           struct rtw89_lps_parm *lps_param)
  876 {
  877         struct sk_buff *skb;
  878 
  879         skb = rtw89_fw_h2c_alloc_skb_with_hdr(rtwdev, H2C_LPS_PARM_LEN);
  880         if (!skb) {
  881                 rtw89_err(rtwdev, "failed to alloc skb for fw dl\n");
  882                 return -ENOMEM;
  883         }
  884         skb_put(skb, H2C_LPS_PARM_LEN);
  885 
  886         SET_LPS_PARM_MACID(skb->data, lps_param->macid);
  887         SET_LPS_PARM_PSMODE(skb->data, lps_param->psmode);
  888         SET_LPS_PARM_LASTRPWM(skb->data, lps_param->lastrpwm);
  889         SET_LPS_PARM_RLBM(skb->data, 1);
  890         SET_LPS_PARM_SMARTPS(skb->data, 1);
  891         SET_LPS_PARM_AWAKEINTERVAL(skb->data, 1);
  892         SET_LPS_PARM_VOUAPSD(skb->data, 0);
  893         SET_LPS_PARM_VIUAPSD(skb->data, 0);
  894         SET_LPS_PARM_BEUAPSD(skb->data, 0);
  895         SET_LPS_PARM_BKUAPSD(skb->data, 0);
  896 
  897         rtw89_h2c_pkt_set_hdr(rtwdev, skb, FWCMD_TYPE_H2C,
  898                               H2C_CAT_MAC,
  899                               H2C_CL_MAC_PS,
  900                               H2C_FUNC_MAC_LPS_PARM, 0, 1,
  901                               H2C_LPS_PARM_LEN);
  902 
  903         if (rtw89_h2c_tx(rtwdev, skb, false)) {
  904                 rtw89_err(rtwdev, "failed to send h2c\n");
  905                 goto fail;
  906         }
  907 
  908         return 0;
  909 fail:
  910         dev_kfree_skb_any(skb);
  911 
  912         return -EBUSY;
  913 }
  914 
  915 #define H2C_CMC_TBL_LEN 68
  916 int rtw89_fw_h2c_default_cmac_tbl(struct rtw89_dev *rtwdev,
  917                                   struct rtw89_vif *rtwvif)
  918 {
  919         const struct rtw89_chip_info *chip = rtwdev->chip;
  920         struct rtw89_hal *hal = &rtwdev->hal;
  921         struct sk_buff *skb;
  922         u8 ntx_path = hal->antenna_tx ? hal->antenna_tx : RF_B;
  923         u8 map_b = hal->antenna_tx == RF_AB ? 1 : 0;
  924         u8 macid = rtwvif->mac_id;
  925 
  926         skb = rtw89_fw_h2c_alloc_skb_with_hdr(rtwdev, H2C_CMC_TBL_LEN);
  927         if (!skb) {
  928                 rtw89_err(rtwdev, "failed to alloc skb for fw dl\n");
  929                 return -ENOMEM;
  930         }
  931         skb_put(skb, H2C_CMC_TBL_LEN);
  932         SET_CTRL_INFO_MACID(skb->data, macid);
  933         SET_CTRL_INFO_OPERATION(skb->data, 1);
  934         if (chip->h2c_cctl_func_id == H2C_FUNC_MAC_CCTLINFO_UD) {
  935                 SET_CMC_TBL_TXPWR_MODE(skb->data, 0);
  936                 SET_CMC_TBL_NTX_PATH_EN(skb->data, ntx_path);
  937                 SET_CMC_TBL_PATH_MAP_A(skb->data, 0);
  938                 SET_CMC_TBL_PATH_MAP_B(skb->data, map_b);
  939                 SET_CMC_TBL_PATH_MAP_C(skb->data, 0);
  940                 SET_CMC_TBL_PATH_MAP_D(skb->data, 0);
  941                 SET_CMC_TBL_ANTSEL_A(skb->data, 0);
  942                 SET_CMC_TBL_ANTSEL_B(skb->data, 0);
  943                 SET_CMC_TBL_ANTSEL_C(skb->data, 0);
  944                 SET_CMC_TBL_ANTSEL_D(skb->data, 0);
  945         }
  946         SET_CMC_TBL_DOPPLER_CTRL(skb->data, 0);
  947         SET_CMC_TBL_TXPWR_TOLERENCE(skb->data, 0);
  948         if (rtwvif->net_type == RTW89_NET_TYPE_AP_MODE)
  949                 SET_CMC_TBL_DATA_DCM(skb->data, 0);
  950 
  951         rtw89_h2c_pkt_set_hdr(rtwdev, skb, FWCMD_TYPE_H2C,
  952                               H2C_CAT_MAC, H2C_CL_MAC_FR_EXCHG,
  953                               chip->h2c_cctl_func_id, 0, 1,
  954                               H2C_CMC_TBL_LEN);
  955 
  956         if (rtw89_h2c_tx(rtwdev, skb, false)) {
  957                 rtw89_err(rtwdev, "failed to send h2c\n");
  958                 goto fail;
  959         }
  960 
  961         return 0;
  962 fail:
  963         dev_kfree_skb_any(skb);
  964 
  965         return -EBUSY;
  966 }
  967 
  968 static void __get_sta_he_pkt_padding(struct rtw89_dev *rtwdev,
  969                                      struct ieee80211_sta *sta, u8 *pads)
  970 {
  971         bool ppe_th;
  972         u8 ppe16, ppe8;
  973         u8 nss = min(sta->deflink.rx_nss, rtwdev->hal.tx_nss) - 1;
  974         u8 ppe_thres_hdr = sta->deflink.he_cap.ppe_thres[0];
  975         u8 ru_bitmap;
  976         u8 n, idx, sh;
  977         u16 ppe;
  978         int i;
  979 
  980         if (!sta->deflink.he_cap.has_he)
  981                 return;
  982 
  983         ppe_th = FIELD_GET(IEEE80211_HE_PHY_CAP6_PPE_THRESHOLD_PRESENT,
  984                            sta->deflink.he_cap.he_cap_elem.phy_cap_info[6]);
  985         if (!ppe_th) {
  986                 u8 pad;
  987 
  988                 pad = FIELD_GET(IEEE80211_HE_PHY_CAP9_NOMINAL_PKT_PADDING_MASK,
  989                                 sta->deflink.he_cap.he_cap_elem.phy_cap_info[9]);
  990 
  991                 for (i = 0; i < RTW89_PPE_BW_NUM; i++)
  992                         pads[i] = pad;
  993 
  994                 return;
  995         }
  996 
  997         ru_bitmap = FIELD_GET(IEEE80211_PPE_THRES_RU_INDEX_BITMASK_MASK, ppe_thres_hdr);
  998         n = hweight8(ru_bitmap);
  999         n = 7 + (n * IEEE80211_PPE_THRES_INFO_PPET_SIZE * 2) * nss;
 1000 
 1001         for (i = 0; i < RTW89_PPE_BW_NUM; i++) {
 1002                 if (!(ru_bitmap & BIT(i))) {
 1003                         pads[i] = 1;
 1004                         continue;
 1005                 }
 1006 
 1007                 idx = n >> 3;
 1008                 sh = n & 7;
 1009                 n += IEEE80211_PPE_THRES_INFO_PPET_SIZE * 2;
 1010 
 1011                 ppe = le16_to_cpu(*((__le16 *)&sta->deflink.he_cap.ppe_thres[idx]));
 1012                 ppe16 = (ppe >> sh) & IEEE80211_PPE_THRES_NSS_MASK;
 1013                 sh += IEEE80211_PPE_THRES_INFO_PPET_SIZE;
 1014                 ppe8 = (ppe >> sh) & IEEE80211_PPE_THRES_NSS_MASK;
 1015 
 1016                 if (ppe16 != 7 && ppe8 == 7)
 1017                         pads[i] = 2;
 1018                 else if (ppe8 != 7)
 1019                         pads[i] = 1;
 1020                 else
 1021                         pads[i] = 0;
 1022         }
 1023 }
 1024 
 1025 int rtw89_fw_h2c_assoc_cmac_tbl(struct rtw89_dev *rtwdev,
 1026                                 struct ieee80211_vif *vif,
 1027                                 struct ieee80211_sta *sta)
 1028 {
 1029         const struct rtw89_chip_info *chip = rtwdev->chip;
 1030         struct rtw89_sta *rtwsta = sta_to_rtwsta_safe(sta);
 1031         struct rtw89_vif *rtwvif = (struct rtw89_vif *)vif->drv_priv;
 1032         const struct rtw89_chan *chan = rtw89_chan_get(rtwdev, RTW89_SUB_ENTITY_0);
 1033         struct sk_buff *skb;
 1034         u8 pads[RTW89_PPE_BW_NUM];
 1035         u8 mac_id = rtwsta ? rtwsta->mac_id : rtwvif->mac_id;
 1036 
 1037         memset(pads, 0, sizeof(pads));
 1038         if (sta)
 1039                 __get_sta_he_pkt_padding(rtwdev, sta, pads);
 1040 
 1041         skb = rtw89_fw_h2c_alloc_skb_with_hdr(rtwdev, H2C_CMC_TBL_LEN);
 1042         if (!skb) {
 1043                 rtw89_err(rtwdev, "failed to alloc skb for fw dl\n");
 1044                 return -ENOMEM;
 1045         }
 1046         skb_put(skb, H2C_CMC_TBL_LEN);
 1047         SET_CTRL_INFO_MACID(skb->data, mac_id);
 1048         SET_CTRL_INFO_OPERATION(skb->data, 1);
 1049         SET_CMC_TBL_DISRTSFB(skb->data, 1);
 1050         SET_CMC_TBL_DISDATAFB(skb->data, 1);
 1051         if (chan->band_type == RTW89_BAND_2G)
 1052                 SET_CMC_TBL_RTS_RTY_LOWEST_RATE(skb->data, RTW89_HW_RATE_CCK1);
 1053         else
 1054                 SET_CMC_TBL_RTS_RTY_LOWEST_RATE(skb->data, RTW89_HW_RATE_OFDM6);
 1055         SET_CMC_TBL_RTS_TXCNT_LMT_SEL(skb->data, 0);
 1056         SET_CMC_TBL_DATA_TXCNT_LMT_SEL(skb->data, 0);
 1057         if (vif->type == NL80211_IFTYPE_STATION)
 1058                 SET_CMC_TBL_ULDL(skb->data, 1);
 1059         else
 1060                 SET_CMC_TBL_ULDL(skb->data, 0);
 1061         SET_CMC_TBL_MULTI_PORT_ID(skb->data, rtwvif->port);
 1062         if (chip->h2c_cctl_func_id == H2C_FUNC_MAC_CCTLINFO_UD_V1) {
 1063                 SET_CMC_TBL_NOMINAL_PKT_PADDING_V1(skb->data, pads[RTW89_CHANNEL_WIDTH_20]);
 1064                 SET_CMC_TBL_NOMINAL_PKT_PADDING40_V1(skb->data, pads[RTW89_CHANNEL_WIDTH_40]);
 1065                 SET_CMC_TBL_NOMINAL_PKT_PADDING80_V1(skb->data, pads[RTW89_CHANNEL_WIDTH_80]);
 1066                 SET_CMC_TBL_NOMINAL_PKT_PADDING160_V1(skb->data, pads[RTW89_CHANNEL_WIDTH_160]);
 1067         } else if (chip->h2c_cctl_func_id == H2C_FUNC_MAC_CCTLINFO_UD) {
 1068                 SET_CMC_TBL_NOMINAL_PKT_PADDING(skb->data, pads[RTW89_CHANNEL_WIDTH_20]);
 1069                 SET_CMC_TBL_NOMINAL_PKT_PADDING40(skb->data, pads[RTW89_CHANNEL_WIDTH_40]);
 1070                 SET_CMC_TBL_NOMINAL_PKT_PADDING80(skb->data, pads[RTW89_CHANNEL_WIDTH_80]);
 1071                 SET_CMC_TBL_NOMINAL_PKT_PADDING160(skb->data, pads[RTW89_CHANNEL_WIDTH_160]);
 1072         }
 1073         if (sta)
 1074                 SET_CMC_TBL_BSR_QUEUE_SIZE_FORMAT(skb->data,
 1075                                                   sta->deflink.he_cap.has_he);
 1076         if (rtwvif->net_type == RTW89_NET_TYPE_AP_MODE)
 1077                 SET_CMC_TBL_DATA_DCM(skb->data, 0);
 1078 
 1079         rtw89_h2c_pkt_set_hdr(rtwdev, skb, FWCMD_TYPE_H2C,
 1080                               H2C_CAT_MAC, H2C_CL_MAC_FR_EXCHG,
 1081                               chip->h2c_cctl_func_id, 0, 1,
 1082                               H2C_CMC_TBL_LEN);
 1083 
 1084         if (rtw89_h2c_tx(rtwdev, skb, false)) {
 1085                 rtw89_err(rtwdev, "failed to send h2c\n");
 1086                 goto fail;
 1087         }
 1088 
 1089         return 0;
 1090 fail:
 1091         dev_kfree_skb_any(skb);
 1092 
 1093         return -EBUSY;
 1094 }
 1095 
 1096 int rtw89_fw_h2c_txtime_cmac_tbl(struct rtw89_dev *rtwdev,
 1097                                  struct rtw89_sta *rtwsta)
 1098 {
 1099         const struct rtw89_chip_info *chip = rtwdev->chip;
 1100         struct sk_buff *skb;
 1101 
 1102         skb = rtw89_fw_h2c_alloc_skb_with_hdr(rtwdev, H2C_CMC_TBL_LEN);
 1103         if (!skb) {
 1104                 rtw89_err(rtwdev, "failed to alloc skb for fw dl\n");
 1105                 return -ENOMEM;
 1106         }
 1107         skb_put(skb, H2C_CMC_TBL_LEN);
 1108         SET_CTRL_INFO_MACID(skb->data, rtwsta->mac_id);
 1109         SET_CTRL_INFO_OPERATION(skb->data, 1);
 1110         if (rtwsta->cctl_tx_time) {
 1111                 SET_CMC_TBL_AMPDU_TIME_SEL(skb->data, 1);
 1112                 SET_CMC_TBL_AMPDU_MAX_TIME(skb->data, rtwsta->ampdu_max_time);
 1113         }
 1114         if (rtwsta->cctl_tx_retry_limit) {
 1115                 SET_CMC_TBL_DATA_TXCNT_LMT_SEL(skb->data, 1);
 1116                 SET_CMC_TBL_DATA_TX_CNT_LMT(skb->data, rtwsta->data_tx_cnt_lmt);
 1117         }
 1118 
 1119         rtw89_h2c_pkt_set_hdr(rtwdev, skb, FWCMD_TYPE_H2C,
 1120                               H2C_CAT_MAC, H2C_CL_MAC_FR_EXCHG,
 1121                               chip->h2c_cctl_func_id, 0, 1,
 1122                               H2C_CMC_TBL_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_BCN_BASE_LEN 12
 1137 int rtw89_fw_h2c_update_beacon(struct rtw89_dev *rtwdev,
 1138                                struct rtw89_vif *rtwvif)
 1139 {
 1140         struct ieee80211_vif *vif = rtwvif_to_vif(rtwvif);
 1141         const struct rtw89_chan *chan = rtw89_chan_get(rtwdev, RTW89_SUB_ENTITY_0);
 1142         struct sk_buff *skb;
 1143         struct sk_buff *skb_beacon;
 1144         u16 tim_offset;
 1145         int bcn_total_len;
 1146 
 1147         skb_beacon = ieee80211_beacon_get_tim(rtwdev->hw, vif, &tim_offset,
 1148                                               NULL, 0);
 1149         if (!skb_beacon) {
 1150                 rtw89_err(rtwdev, "failed to get beacon skb\n");
 1151                 return -ENOMEM;
 1152         }
 1153 
 1154         bcn_total_len = H2C_BCN_BASE_LEN + skb_beacon->len;
 1155         skb = rtw89_fw_h2c_alloc_skb_with_hdr(rtwdev, bcn_total_len);
 1156         if (!skb) {
 1157                 rtw89_err(rtwdev, "failed to alloc skb for fw dl\n");
 1158                 dev_kfree_skb_any(skb_beacon);
 1159                 return -ENOMEM;
 1160         }
 1161         skb_put(skb, H2C_BCN_BASE_LEN);
 1162 
 1163         SET_BCN_UPD_PORT(skb->data, rtwvif->port);
 1164         SET_BCN_UPD_MBSSID(skb->data, 0);
 1165         SET_BCN_UPD_BAND(skb->data, rtwvif->mac_idx);
 1166         SET_BCN_UPD_GRP_IE_OFST(skb->data, tim_offset);
 1167         SET_BCN_UPD_MACID(skb->data, rtwvif->mac_id);
 1168         SET_BCN_UPD_SSN_SEL(skb->data, RTW89_MGMT_HW_SSN_SEL);
 1169         SET_BCN_UPD_SSN_MODE(skb->data, RTW89_MGMT_HW_SEQ_MODE);
 1170         SET_BCN_UPD_RATE(skb->data, chan->band_type == RTW89_BAND_2G ?
 1171                                     RTW89_HW_RATE_CCK1 : RTW89_HW_RATE_OFDM6);
 1172 
 1173         skb_put_data(skb, skb_beacon->data, skb_beacon->len);
 1174         dev_kfree_skb_any(skb_beacon);
 1175 
 1176         rtw89_h2c_pkt_set_hdr(rtwdev, skb, FWCMD_TYPE_H2C,
 1177                               H2C_CAT_MAC, H2C_CL_MAC_FR_EXCHG,
 1178                               H2C_FUNC_MAC_BCN_UPD, 0, 1,
 1179                               bcn_total_len);
 1180 
 1181         if (rtw89_h2c_tx(rtwdev, skb, false)) {
 1182                 rtw89_err(rtwdev, "failed to send h2c\n");
 1183                 dev_kfree_skb_any(skb);
 1184                 return -EBUSY;
 1185         }
 1186 
 1187         return 0;
 1188 }
 1189 
 1190 #define H2C_ROLE_MAINTAIN_LEN 4
 1191 int rtw89_fw_h2c_role_maintain(struct rtw89_dev *rtwdev,
 1192                                struct rtw89_vif *rtwvif,
 1193                                struct rtw89_sta *rtwsta,
 1194                                enum rtw89_upd_mode upd_mode)
 1195 {
 1196         struct sk_buff *skb;
 1197         u8 mac_id = rtwsta ? rtwsta->mac_id : rtwvif->mac_id;
 1198         u8 self_role;
 1199 
 1200         if (rtwvif->net_type == RTW89_NET_TYPE_AP_MODE) {
 1201                 if (rtwsta)
 1202                         self_role = RTW89_SELF_ROLE_AP_CLIENT;
 1203                 else
 1204                         self_role = rtwvif->self_role;
 1205         } else {
 1206                 self_role = rtwvif->self_role;
 1207         }
 1208 
 1209         skb = rtw89_fw_h2c_alloc_skb_with_hdr(rtwdev, H2C_ROLE_MAINTAIN_LEN);
 1210         if (!skb) {
 1211                 rtw89_err(rtwdev, "failed to alloc skb for h2c join\n");
 1212                 return -ENOMEM;
 1213         }
 1214         skb_put(skb, H2C_ROLE_MAINTAIN_LEN);
 1215         SET_FWROLE_MAINTAIN_MACID(skb->data, mac_id);
 1216         SET_FWROLE_MAINTAIN_SELF_ROLE(skb->data, self_role);
 1217         SET_FWROLE_MAINTAIN_UPD_MODE(skb->data, upd_mode);
 1218         SET_FWROLE_MAINTAIN_WIFI_ROLE(skb->data, rtwvif->wifi_role);
 1219 
 1220         rtw89_h2c_pkt_set_hdr(rtwdev, skb, FWCMD_TYPE_H2C,
 1221                               H2C_CAT_MAC, H2C_CL_MAC_MEDIA_RPT,
 1222                               H2C_FUNC_MAC_FWROLE_MAINTAIN, 0, 1,
 1223                               H2C_ROLE_MAINTAIN_LEN);
 1224 
 1225         if (rtw89_h2c_tx(rtwdev, skb, false)) {
 1226                 rtw89_err(rtwdev, "failed to send h2c\n");
 1227                 goto fail;
 1228         }
 1229 
 1230         return 0;
 1231 fail:
 1232         dev_kfree_skb_any(skb);
 1233 
 1234         return -EBUSY;
 1235 }
 1236 
 1237 #define H2C_JOIN_INFO_LEN 4
 1238 int rtw89_fw_h2c_join_info(struct rtw89_dev *rtwdev, struct rtw89_vif *rtwvif,
 1239                            struct rtw89_sta *rtwsta, bool dis_conn)
 1240 {
 1241         struct sk_buff *skb;
 1242         u8 mac_id = rtwsta ? rtwsta->mac_id : rtwvif->mac_id;
 1243         u8 self_role = rtwvif->self_role;
 1244         u8 net_type = rtwvif->net_type;
 1245 
 1246         if (net_type == RTW89_NET_TYPE_AP_MODE && rtwsta) {
 1247                 self_role = RTW89_SELF_ROLE_AP_CLIENT;
 1248                 net_type = dis_conn ? RTW89_NET_TYPE_NO_LINK : net_type;
 1249         }
 1250 
 1251         skb = rtw89_fw_h2c_alloc_skb_with_hdr(rtwdev, H2C_JOIN_INFO_LEN);
 1252         if (!skb) {
 1253                 rtw89_err(rtwdev, "failed to alloc skb for h2c join\n");
 1254                 return -ENOMEM;
 1255         }
 1256         skb_put(skb, H2C_JOIN_INFO_LEN);
 1257         SET_JOININFO_MACID(skb->data, mac_id);
 1258         SET_JOININFO_OP(skb->data, dis_conn);
 1259         SET_JOININFO_BAND(skb->data, rtwvif->mac_idx);
 1260         SET_JOININFO_WMM(skb->data, rtwvif->wmm);
 1261         SET_JOININFO_TGR(skb->data, rtwvif->trigger);
 1262         SET_JOININFO_ISHESTA(skb->data, 0);
 1263         SET_JOININFO_DLBW(skb->data, 0);
 1264         SET_JOININFO_TF_MAC_PAD(skb->data, 0);
 1265         SET_JOININFO_DL_T_PE(skb->data, 0);
 1266         SET_JOININFO_PORT_ID(skb->data, rtwvif->port);
 1267         SET_JOININFO_NET_TYPE(skb->data, net_type);
 1268         SET_JOININFO_WIFI_ROLE(skb->data, rtwvif->wifi_role);
 1269         SET_JOININFO_SELF_ROLE(skb->data, self_role);
 1270 
 1271         rtw89_h2c_pkt_set_hdr(rtwdev, skb, FWCMD_TYPE_H2C,
 1272                               H2C_CAT_MAC, H2C_CL_MAC_MEDIA_RPT,
 1273                               H2C_FUNC_MAC_JOININFO, 0, 1,
 1274                               H2C_JOIN_INFO_LEN);
 1275 
 1276         if (rtw89_h2c_tx(rtwdev, skb, false)) {
 1277                 rtw89_err(rtwdev, "failed to send h2c\n");
 1278                 goto fail;
 1279         }
 1280 
 1281         return 0;
 1282 fail:
 1283         dev_kfree_skb_any(skb);
 1284 
 1285         return -EBUSY;
 1286 }
 1287 
 1288 int rtw89_fw_h2c_macid_pause(struct rtw89_dev *rtwdev, u8 sh, u8 grp,
 1289                              bool pause)
 1290 {
 1291         struct rtw89_fw_macid_pause_grp h2c = {{0}};
 1292         u8 len = sizeof(struct rtw89_fw_macid_pause_grp);
 1293         struct sk_buff *skb;
 1294 
 1295 #if defined(__linux__)
 1296         skb = rtw89_fw_h2c_alloc_skb_with_hdr(rtwdev, H2C_JOIN_INFO_LEN);
 1297 #elif defined(__FreeBSD__)
 1298         skb = rtw89_fw_h2c_alloc_skb_with_hdr(rtwdev, len);
 1299 #endif
 1300         if (!skb) {
 1301                 rtw89_err(rtwdev, "failed to alloc skb for h2c join\n");
 1302                 return -ENOMEM;
 1303         }
 1304         h2c.mask_grp[grp] = cpu_to_le32(BIT(sh));
 1305         if (pause)
 1306                 h2c.pause_grp[grp] = cpu_to_le32(BIT(sh));
 1307         skb_put_data(skb, &h2c, len);
 1308 
 1309         rtw89_h2c_pkt_set_hdr(rtwdev, skb, FWCMD_TYPE_H2C,
 1310                               H2C_CAT_MAC, H2C_CL_MAC_FW_OFLD,
 1311                               H2C_FUNC_MAC_MACID_PAUSE, 1, 0,
 1312                               len);
 1313 
 1314         if (rtw89_h2c_tx(rtwdev, skb, false)) {
 1315                 rtw89_err(rtwdev, "failed to send h2c\n");
 1316                 goto fail;
 1317         }
 1318 
 1319         return 0;
 1320 fail:
 1321         dev_kfree_skb_any(skb);
 1322 
 1323         return -EBUSY;
 1324 }
 1325 
 1326 #define H2C_EDCA_LEN 12
 1327 int rtw89_fw_h2c_set_edca(struct rtw89_dev *rtwdev, struct rtw89_vif *rtwvif,
 1328                           u8 ac, u32 val)
 1329 {
 1330         struct sk_buff *skb;
 1331 
 1332         skb = rtw89_fw_h2c_alloc_skb_with_hdr(rtwdev, H2C_EDCA_LEN);
 1333         if (!skb) {
 1334                 rtw89_err(rtwdev, "failed to alloc skb for h2c edca\n");
 1335                 return -ENOMEM;
 1336         }
 1337         skb_put(skb, H2C_EDCA_LEN);
 1338         RTW89_SET_EDCA_SEL(skb->data, 0);
 1339         RTW89_SET_EDCA_BAND(skb->data, rtwvif->mac_idx);
 1340         RTW89_SET_EDCA_WMM(skb->data, 0);
 1341         RTW89_SET_EDCA_AC(skb->data, ac);
 1342         RTW89_SET_EDCA_PARAM(skb->data, val);
 1343 
 1344         rtw89_h2c_pkt_set_hdr(rtwdev, skb, FWCMD_TYPE_H2C,
 1345                               H2C_CAT_MAC, H2C_CL_MAC_FW_OFLD,
 1346                               H2C_FUNC_USR_EDCA, 0, 1,
 1347                               H2C_EDCA_LEN);
 1348 
 1349         if (rtw89_h2c_tx(rtwdev, skb, false)) {
 1350                 rtw89_err(rtwdev, "failed to send h2c\n");
 1351                 goto fail;
 1352         }
 1353 
 1354         return 0;
 1355 fail:
 1356         dev_kfree_skb_any(skb);
 1357 
 1358         return -EBUSY;
 1359 }
 1360 
 1361 #define H2C_OFLD_CFG_LEN 8
 1362 int rtw89_fw_h2c_set_ofld_cfg(struct rtw89_dev *rtwdev)
 1363 {
 1364         static const u8 cfg[] = {0x09, 0x00, 0x00, 0x00, 0x5e, 0x00, 0x00, 0x00};
 1365         struct sk_buff *skb;
 1366 
 1367         skb = rtw89_fw_h2c_alloc_skb_with_hdr(rtwdev, H2C_OFLD_CFG_LEN);
 1368         if (!skb) {
 1369                 rtw89_err(rtwdev, "failed to alloc skb for h2c ofld\n");
 1370                 return -ENOMEM;
 1371         }
 1372         skb_put_data(skb, cfg, H2C_OFLD_CFG_LEN);
 1373 
 1374         rtw89_h2c_pkt_set_hdr(rtwdev, skb, FWCMD_TYPE_H2C,
 1375                               H2C_CAT_MAC, H2C_CL_MAC_FW_OFLD,
 1376                               H2C_FUNC_OFLD_CFG, 0, 1,
 1377                               H2C_OFLD_CFG_LEN);
 1378 
 1379         if (rtw89_h2c_tx(rtwdev, skb, false)) {
 1380                 rtw89_err(rtwdev, "failed to send h2c\n");
 1381                 goto fail;
 1382         }
 1383 
 1384         return 0;
 1385 fail:
 1386         dev_kfree_skb_any(skb);
 1387 
 1388         return -EBUSY;
 1389 }
 1390 
 1391 #define H2C_RA_LEN 16
 1392 int rtw89_fw_h2c_ra(struct rtw89_dev *rtwdev, struct rtw89_ra_info *ra, bool csi)
 1393 {
 1394         struct sk_buff *skb;
 1395         u8 *cmd;
 1396 
 1397         skb = rtw89_fw_h2c_alloc_skb_with_hdr(rtwdev, H2C_RA_LEN);
 1398         if (!skb) {
 1399                 rtw89_err(rtwdev, "failed to alloc skb for h2c join\n");
 1400                 return -ENOMEM;
 1401         }
 1402         skb_put(skb, H2C_RA_LEN);
 1403         cmd = skb->data;
 1404         rtw89_debug(rtwdev, RTW89_DBG_RA,
 1405 #if defined(__linux__)
 1406                     "ra cmd msk: %llx ", ra->ra_mask);
 1407 #elif defined(__FreeBSD__)
 1408                     "ra cmd msk: %jx ", (uintmax_t)ra->ra_mask);
 1409 #endif
 1410 
 1411         RTW89_SET_FWCMD_RA_MODE(cmd, ra->mode_ctrl);
 1412         RTW89_SET_FWCMD_RA_BW_CAP(cmd, ra->bw_cap);
 1413         RTW89_SET_FWCMD_RA_MACID(cmd, ra->macid);
 1414         RTW89_SET_FWCMD_RA_DCM(cmd, ra->dcm_cap);
 1415         RTW89_SET_FWCMD_RA_ER(cmd, ra->er_cap);
 1416         RTW89_SET_FWCMD_RA_INIT_RATE_LV(cmd, ra->init_rate_lv);
 1417         RTW89_SET_FWCMD_RA_UPD_ALL(cmd, ra->upd_all);
 1418         RTW89_SET_FWCMD_RA_SGI(cmd, ra->en_sgi);
 1419         RTW89_SET_FWCMD_RA_LDPC(cmd, ra->ldpc_cap);
 1420         RTW89_SET_FWCMD_RA_STBC(cmd, ra->stbc_cap);
 1421         RTW89_SET_FWCMD_RA_SS_NUM(cmd, ra->ss_num);
 1422         RTW89_SET_FWCMD_RA_GILTF(cmd, ra->giltf);
 1423         RTW89_SET_FWCMD_RA_UPD_BW_NSS_MASK(cmd, ra->upd_bw_nss_mask);
 1424         RTW89_SET_FWCMD_RA_UPD_MASK(cmd, ra->upd_mask);
 1425         RTW89_SET_FWCMD_RA_MASK_0(cmd, FIELD_GET(MASKBYTE0, ra->ra_mask));
 1426         RTW89_SET_FWCMD_RA_MASK_1(cmd, FIELD_GET(MASKBYTE1, ra->ra_mask));
 1427         RTW89_SET_FWCMD_RA_MASK_2(cmd, FIELD_GET(MASKBYTE2, ra->ra_mask));
 1428         RTW89_SET_FWCMD_RA_MASK_3(cmd, FIELD_GET(MASKBYTE3, ra->ra_mask));
 1429         RTW89_SET_FWCMD_RA_MASK_4(cmd, FIELD_GET(MASKBYTE4, ra->ra_mask));
 1430 
 1431         if (csi) {
 1432                 RTW89_SET_FWCMD_RA_BFEE_CSI_CTL(cmd, 1);
 1433                 RTW89_SET_FWCMD_RA_BAND_NUM(cmd, ra->band_num);
 1434                 RTW89_SET_FWCMD_RA_CR_TBL_SEL(cmd, ra->cr_tbl_sel);
 1435                 RTW89_SET_FWCMD_RA_FIXED_CSI_RATE_EN(cmd, ra->fixed_csi_rate_en);
 1436                 RTW89_SET_FWCMD_RA_RA_CSI_RATE_EN(cmd, ra->ra_csi_rate_en);
 1437                 RTW89_SET_FWCMD_RA_FIXED_CSI_MCS_SS_IDX(cmd, ra->csi_mcs_ss_idx);
 1438                 RTW89_SET_FWCMD_RA_FIXED_CSI_MODE(cmd, ra->csi_mode);
 1439                 RTW89_SET_FWCMD_RA_FIXED_CSI_GI_LTF(cmd, ra->csi_gi_ltf);
 1440                 RTW89_SET_FWCMD_RA_FIXED_CSI_BW(cmd, ra->csi_bw);
 1441         }
 1442 
 1443         rtw89_h2c_pkt_set_hdr(rtwdev, skb, FWCMD_TYPE_H2C,
 1444                               H2C_CAT_OUTSRC, H2C_CL_OUTSRC_RA,
 1445                               H2C_FUNC_OUTSRC_RA_MACIDCFG, 0, 0,
 1446                               H2C_RA_LEN);
 1447 
 1448         if (rtw89_h2c_tx(rtwdev, skb, false)) {
 1449                 rtw89_err(rtwdev, "failed to send h2c\n");
 1450                 goto fail;
 1451         }
 1452 
 1453         return 0;
 1454 fail:
 1455         dev_kfree_skb_any(skb);
 1456 
 1457         return -EBUSY;
 1458 }
 1459 
 1460 #define H2C_LEN_CXDRVHDR 2
 1461 #define H2C_LEN_CXDRVINFO_INIT (12 + H2C_LEN_CXDRVHDR)
 1462 int rtw89_fw_h2c_cxdrv_init(struct rtw89_dev *rtwdev)
 1463 {
 1464         struct rtw89_btc *btc = &rtwdev->btc;
 1465         struct rtw89_btc_dm *dm = &btc->dm;
 1466         struct rtw89_btc_init_info *init_info = &dm->init_info;
 1467         struct rtw89_btc_module *module = &init_info->module;
 1468         struct rtw89_btc_ant_info *ant = &module->ant;
 1469         struct sk_buff *skb;
 1470         u8 *cmd;
 1471 
 1472         skb = rtw89_fw_h2c_alloc_skb_with_hdr(rtwdev, H2C_LEN_CXDRVINFO_INIT);
 1473         if (!skb) {
 1474                 rtw89_err(rtwdev, "failed to alloc skb for h2c cxdrv_init\n");
 1475                 return -ENOMEM;
 1476         }
 1477         skb_put(skb, H2C_LEN_CXDRVINFO_INIT);
 1478         cmd = skb->data;
 1479 
 1480         RTW89_SET_FWCMD_CXHDR_TYPE(cmd, CXDRVINFO_INIT);
 1481         RTW89_SET_FWCMD_CXHDR_LEN(cmd, H2C_LEN_CXDRVINFO_INIT - H2C_LEN_CXDRVHDR);
 1482 
 1483         RTW89_SET_FWCMD_CXINIT_ANT_TYPE(cmd, ant->type);
 1484         RTW89_SET_FWCMD_CXINIT_ANT_NUM(cmd, ant->num);
 1485         RTW89_SET_FWCMD_CXINIT_ANT_ISO(cmd, ant->isolation);
 1486         RTW89_SET_FWCMD_CXINIT_ANT_POS(cmd, ant->single_pos);
 1487         RTW89_SET_FWCMD_CXINIT_ANT_DIVERSITY(cmd, ant->diversity);
 1488 
 1489         RTW89_SET_FWCMD_CXINIT_MOD_RFE(cmd, module->rfe_type);
 1490         RTW89_SET_FWCMD_CXINIT_MOD_CV(cmd, module->cv);
 1491         RTW89_SET_FWCMD_CXINIT_MOD_BT_SOLO(cmd, module->bt_solo);
 1492         RTW89_SET_FWCMD_CXINIT_MOD_BT_POS(cmd, module->bt_pos);
 1493         RTW89_SET_FWCMD_CXINIT_MOD_SW_TYPE(cmd, module->switch_type);
 1494 
 1495         RTW89_SET_FWCMD_CXINIT_WL_GCH(cmd, init_info->wl_guard_ch);
 1496         RTW89_SET_FWCMD_CXINIT_WL_ONLY(cmd, init_info->wl_only);
 1497         RTW89_SET_FWCMD_CXINIT_WL_INITOK(cmd, init_info->wl_init_ok);
 1498         RTW89_SET_FWCMD_CXINIT_DBCC_EN(cmd, init_info->dbcc_en);
 1499         RTW89_SET_FWCMD_CXINIT_CX_OTHER(cmd, init_info->cx_other);
 1500         RTW89_SET_FWCMD_CXINIT_BT_ONLY(cmd, init_info->bt_only);
 1501 
 1502         rtw89_h2c_pkt_set_hdr(rtwdev, skb, FWCMD_TYPE_H2C,
 1503                               H2C_CAT_OUTSRC, BTFC_SET,
 1504                               SET_DRV_INFO, 0, 0,
 1505                               H2C_LEN_CXDRVINFO_INIT);
 1506 
 1507         if (rtw89_h2c_tx(rtwdev, skb, false)) {
 1508                 rtw89_err(rtwdev, "failed to send h2c\n");
 1509                 goto fail;
 1510         }
 1511 
 1512         return 0;
 1513 fail:
 1514         dev_kfree_skb_any(skb);
 1515 
 1516         return -EBUSY;
 1517 }
 1518 
 1519 #define PORT_DATA_OFFSET 4
 1520 #define H2C_LEN_CXDRVINFO_ROLE_DBCC_LEN 12
 1521 #define H2C_LEN_CXDRVINFO_ROLE (4 + 12 * RTW89_PORT_NUM + H2C_LEN_CXDRVHDR)
 1522 #define H2C_LEN_CXDRVINFO_ROLE_V1 (4 + 16 * RTW89_PORT_NUM + \
 1523                                    H2C_LEN_CXDRVINFO_ROLE_DBCC_LEN + \
 1524                                    H2C_LEN_CXDRVHDR)
 1525 int rtw89_fw_h2c_cxdrv_role(struct rtw89_dev *rtwdev)
 1526 {
 1527         struct rtw89_btc *btc = &rtwdev->btc;
 1528         struct rtw89_btc_wl_info *wl = &btc->cx.wl;
 1529         struct rtw89_btc_wl_role_info *role_info = &wl->role_info;
 1530         struct rtw89_btc_wl_role_info_bpos *bpos = &role_info->role_map.role;
 1531         struct rtw89_btc_wl_active_role *active = role_info->active_role;
 1532         struct sk_buff *skb;
 1533         u8 offset = 0;
 1534         u8 *cmd;
 1535         int i;
 1536 
 1537         skb = rtw89_fw_h2c_alloc_skb_with_hdr(rtwdev, H2C_LEN_CXDRVINFO_ROLE);
 1538         if (!skb) {
 1539                 rtw89_err(rtwdev, "failed to alloc skb for h2c cxdrv_role\n");
 1540                 return -ENOMEM;
 1541         }
 1542         skb_put(skb, H2C_LEN_CXDRVINFO_ROLE);
 1543         cmd = skb->data;
 1544 
 1545         RTW89_SET_FWCMD_CXHDR_TYPE(cmd, CXDRVINFO_ROLE);
 1546         RTW89_SET_FWCMD_CXHDR_LEN(cmd, H2C_LEN_CXDRVINFO_ROLE - H2C_LEN_CXDRVHDR);
 1547 
 1548         RTW89_SET_FWCMD_CXROLE_CONNECT_CNT(cmd, role_info->connect_cnt);
 1549         RTW89_SET_FWCMD_CXROLE_LINK_MODE(cmd, role_info->link_mode);
 1550 
 1551         RTW89_SET_FWCMD_CXROLE_ROLE_NONE(cmd, bpos->none);
 1552         RTW89_SET_FWCMD_CXROLE_ROLE_STA(cmd, bpos->station);
 1553         RTW89_SET_FWCMD_CXROLE_ROLE_AP(cmd, bpos->ap);
 1554         RTW89_SET_FWCMD_CXROLE_ROLE_VAP(cmd, bpos->vap);
 1555         RTW89_SET_FWCMD_CXROLE_ROLE_ADHOC(cmd, bpos->adhoc);
 1556         RTW89_SET_FWCMD_CXROLE_ROLE_ADHOC_MASTER(cmd, bpos->adhoc_master);
 1557         RTW89_SET_FWCMD_CXROLE_ROLE_MESH(cmd, bpos->mesh);
 1558         RTW89_SET_FWCMD_CXROLE_ROLE_MONITOR(cmd, bpos->moniter);
 1559         RTW89_SET_FWCMD_CXROLE_ROLE_P2P_DEV(cmd, bpos->p2p_device);
 1560         RTW89_SET_FWCMD_CXROLE_ROLE_P2P_GC(cmd, bpos->p2p_gc);
 1561         RTW89_SET_FWCMD_CXROLE_ROLE_P2P_GO(cmd, bpos->p2p_go);
 1562         RTW89_SET_FWCMD_CXROLE_ROLE_NAN(cmd, bpos->nan);
 1563 
 1564         for (i = 0; i < RTW89_PORT_NUM; i++, active++) {
 1565                 RTW89_SET_FWCMD_CXROLE_ACT_CONNECTED(cmd, active->connected, i, offset);
 1566                 RTW89_SET_FWCMD_CXROLE_ACT_PID(cmd, active->pid, i, offset);
 1567                 RTW89_SET_FWCMD_CXROLE_ACT_PHY(cmd, active->phy, i, offset);
 1568                 RTW89_SET_FWCMD_CXROLE_ACT_NOA(cmd, active->noa, i, offset);
 1569                 RTW89_SET_FWCMD_CXROLE_ACT_BAND(cmd, active->band, i, offset);
 1570                 RTW89_SET_FWCMD_CXROLE_ACT_CLIENT_PS(cmd, active->client_ps, i, offset);
 1571                 RTW89_SET_FWCMD_CXROLE_ACT_BW(cmd, active->bw, i, offset);
 1572                 RTW89_SET_FWCMD_CXROLE_ACT_ROLE(cmd, active->role, i, offset);
 1573                 RTW89_SET_FWCMD_CXROLE_ACT_CH(cmd, active->ch, i, offset);
 1574                 RTW89_SET_FWCMD_CXROLE_ACT_TX_LVL(cmd, active->tx_lvl, i, offset);
 1575                 RTW89_SET_FWCMD_CXROLE_ACT_RX_LVL(cmd, active->rx_lvl, i, offset);
 1576                 RTW89_SET_FWCMD_CXROLE_ACT_TX_RATE(cmd, active->tx_rate, i, offset);
 1577                 RTW89_SET_FWCMD_CXROLE_ACT_RX_RATE(cmd, active->rx_rate, i, offset);
 1578         }
 1579 
 1580         rtw89_h2c_pkt_set_hdr(rtwdev, skb, FWCMD_TYPE_H2C,
 1581                               H2C_CAT_OUTSRC, BTFC_SET,
 1582                               SET_DRV_INFO, 0, 0,
 1583                               H2C_LEN_CXDRVINFO_ROLE);
 1584 
 1585         if (rtw89_h2c_tx(rtwdev, skb, false)) {
 1586                 rtw89_err(rtwdev, "failed to send h2c\n");
 1587                 goto fail;
 1588         }
 1589 
 1590         return 0;
 1591 fail:
 1592         dev_kfree_skb_any(skb);
 1593 
 1594         return -EBUSY;
 1595 }
 1596 
 1597 int rtw89_fw_h2c_cxdrv_role_v1(struct rtw89_dev *rtwdev)
 1598 {
 1599         struct rtw89_btc *btc = &rtwdev->btc;
 1600         struct rtw89_btc_wl_info *wl = &btc->cx.wl;
 1601         struct rtw89_btc_wl_role_info_v1 *role_info = &wl->role_info_v1;
 1602         struct rtw89_btc_wl_role_info_bpos *bpos = &role_info->role_map.role;
 1603         struct rtw89_btc_wl_active_role_v1 *active = role_info->active_role_v1;
 1604         struct sk_buff *skb;
 1605         u8 *cmd, offset;
 1606         int i;
 1607 
 1608         skb = rtw89_fw_h2c_alloc_skb_with_hdr(rtwdev, H2C_LEN_CXDRVINFO_ROLE_V1);
 1609         if (!skb) {
 1610                 rtw89_err(rtwdev, "failed to alloc skb for h2c cxdrv_role\n");
 1611                 return -ENOMEM;
 1612         }
 1613         skb_put(skb, H2C_LEN_CXDRVINFO_ROLE_V1);
 1614         cmd = skb->data;
 1615 
 1616         RTW89_SET_FWCMD_CXHDR_TYPE(cmd, CXDRVINFO_ROLE);
 1617         RTW89_SET_FWCMD_CXHDR_LEN(cmd, H2C_LEN_CXDRVINFO_ROLE_V1 - H2C_LEN_CXDRVHDR);
 1618 
 1619         RTW89_SET_FWCMD_CXROLE_CONNECT_CNT(cmd, role_info->connect_cnt);
 1620         RTW89_SET_FWCMD_CXROLE_LINK_MODE(cmd, role_info->link_mode);
 1621 
 1622         RTW89_SET_FWCMD_CXROLE_ROLE_NONE(cmd, bpos->none);
 1623         RTW89_SET_FWCMD_CXROLE_ROLE_STA(cmd, bpos->station);
 1624         RTW89_SET_FWCMD_CXROLE_ROLE_AP(cmd, bpos->ap);
 1625         RTW89_SET_FWCMD_CXROLE_ROLE_VAP(cmd, bpos->vap);
 1626         RTW89_SET_FWCMD_CXROLE_ROLE_ADHOC(cmd, bpos->adhoc);
 1627         RTW89_SET_FWCMD_CXROLE_ROLE_ADHOC_MASTER(cmd, bpos->adhoc_master);
 1628         RTW89_SET_FWCMD_CXROLE_ROLE_MESH(cmd, bpos->mesh);
 1629         RTW89_SET_FWCMD_CXROLE_ROLE_MONITOR(cmd, bpos->moniter);
 1630         RTW89_SET_FWCMD_CXROLE_ROLE_P2P_DEV(cmd, bpos->p2p_device);
 1631         RTW89_SET_FWCMD_CXROLE_ROLE_P2P_GC(cmd, bpos->p2p_gc);
 1632         RTW89_SET_FWCMD_CXROLE_ROLE_P2P_GO(cmd, bpos->p2p_go);
 1633         RTW89_SET_FWCMD_CXROLE_ROLE_NAN(cmd, bpos->nan);
 1634 
 1635         offset = PORT_DATA_OFFSET;
 1636         for (i = 0; i < RTW89_PORT_NUM; i++, active++) {
 1637                 RTW89_SET_FWCMD_CXROLE_ACT_CONNECTED(cmd, active->connected, i, offset);
 1638                 RTW89_SET_FWCMD_CXROLE_ACT_PID(cmd, active->pid, i, offset);
 1639                 RTW89_SET_FWCMD_CXROLE_ACT_PHY(cmd, active->phy, i, offset);
 1640                 RTW89_SET_FWCMD_CXROLE_ACT_NOA(cmd, active->noa, i, offset);
 1641                 RTW89_SET_FWCMD_CXROLE_ACT_BAND(cmd, active->band, i, offset);
 1642                 RTW89_SET_FWCMD_CXROLE_ACT_CLIENT_PS(cmd, active->client_ps, i, offset);
 1643                 RTW89_SET_FWCMD_CXROLE_ACT_BW(cmd, active->bw, i, offset);
 1644                 RTW89_SET_FWCMD_CXROLE_ACT_ROLE(cmd, active->role, i, offset);
 1645                 RTW89_SET_FWCMD_CXROLE_ACT_CH(cmd, active->ch, i, offset);
 1646                 RTW89_SET_FWCMD_CXROLE_ACT_TX_LVL(cmd, active->tx_lvl, i, offset);
 1647                 RTW89_SET_FWCMD_CXROLE_ACT_RX_LVL(cmd, active->rx_lvl, i, offset);
 1648                 RTW89_SET_FWCMD_CXROLE_ACT_TX_RATE(cmd, active->tx_rate, i, offset);
 1649                 RTW89_SET_FWCMD_CXROLE_ACT_RX_RATE(cmd, active->rx_rate, i, offset);
 1650                 RTW89_SET_FWCMD_CXROLE_ACT_NOA_DUR(cmd, active->noa_duration, i, offset);
 1651         }
 1652 
 1653         offset = H2C_LEN_CXDRVINFO_ROLE_V1 - H2C_LEN_CXDRVINFO_ROLE_DBCC_LEN;
 1654         RTW89_SET_FWCMD_CXROLE_MROLE_TYPE(cmd, role_info->mrole_type, offset);
 1655         RTW89_SET_FWCMD_CXROLE_MROLE_NOA(cmd, role_info->mrole_noa_duration, offset);
 1656         RTW89_SET_FWCMD_CXROLE_DBCC_EN(cmd, role_info->dbcc_en, offset);
 1657         RTW89_SET_FWCMD_CXROLE_DBCC_CHG(cmd, role_info->dbcc_chg, offset);
 1658         RTW89_SET_FWCMD_CXROLE_DBCC_2G_PHY(cmd, role_info->dbcc_2g_phy, offset);
 1659         RTW89_SET_FWCMD_CXROLE_LINK_MODE_CHG(cmd, role_info->link_mode_chg, offset);
 1660 
 1661         rtw89_h2c_pkt_set_hdr(rtwdev, skb, FWCMD_TYPE_H2C,
 1662                               H2C_CAT_OUTSRC, BTFC_SET,
 1663                               SET_DRV_INFO, 0, 0,
 1664                               H2C_LEN_CXDRVINFO_ROLE_V1);
 1665 
 1666         if (rtw89_h2c_tx(rtwdev, skb, false)) {
 1667                 rtw89_err(rtwdev, "failed to send h2c\n");
 1668                 goto fail;
 1669         }
 1670 
 1671         return 0;
 1672 fail:
 1673         dev_kfree_skb_any(skb);
 1674 
 1675         return -EBUSY;
 1676 }
 1677 
 1678 #define H2C_LEN_CXDRVINFO_CTRL (4 + H2C_LEN_CXDRVHDR)
 1679 int rtw89_fw_h2c_cxdrv_ctrl(struct rtw89_dev *rtwdev)
 1680 {
 1681         struct rtw89_btc *btc = &rtwdev->btc;
 1682         struct rtw89_btc_ctrl *ctrl = &btc->ctrl;
 1683         struct sk_buff *skb;
 1684         u8 *cmd;
 1685 
 1686         skb = rtw89_fw_h2c_alloc_skb_with_hdr(rtwdev, H2C_LEN_CXDRVINFO_CTRL);
 1687         if (!skb) {
 1688                 rtw89_err(rtwdev, "failed to alloc skb for h2c cxdrv_ctrl\n");
 1689                 return -ENOMEM;
 1690         }
 1691         skb_put(skb, H2C_LEN_CXDRVINFO_CTRL);
 1692         cmd = skb->data;
 1693 
 1694         RTW89_SET_FWCMD_CXHDR_TYPE(cmd, CXDRVINFO_CTRL);
 1695         RTW89_SET_FWCMD_CXHDR_LEN(cmd, H2C_LEN_CXDRVINFO_CTRL - H2C_LEN_CXDRVHDR);
 1696 
 1697         RTW89_SET_FWCMD_CXCTRL_MANUAL(cmd, ctrl->manual);
 1698         RTW89_SET_FWCMD_CXCTRL_IGNORE_BT(cmd, ctrl->igno_bt);
 1699         RTW89_SET_FWCMD_CXCTRL_ALWAYS_FREERUN(cmd, ctrl->always_freerun);
 1700         RTW89_SET_FWCMD_CXCTRL_TRACE_STEP(cmd, ctrl->trace_step);
 1701 
 1702         rtw89_h2c_pkt_set_hdr(rtwdev, skb, FWCMD_TYPE_H2C,
 1703                               H2C_CAT_OUTSRC, BTFC_SET,
 1704                               SET_DRV_INFO, 0, 0,
 1705                               H2C_LEN_CXDRVINFO_CTRL);
 1706 
 1707         if (rtw89_h2c_tx(rtwdev, skb, false)) {
 1708                 rtw89_err(rtwdev, "failed to send h2c\n");
 1709                 goto fail;
 1710         }
 1711 
 1712         return 0;
 1713 fail:
 1714         dev_kfree_skb_any(skb);
 1715 
 1716         return -EBUSY;
 1717 }
 1718 
 1719 #define H2C_LEN_CXDRVINFO_RFK (4 + H2C_LEN_CXDRVHDR)
 1720 int rtw89_fw_h2c_cxdrv_rfk(struct rtw89_dev *rtwdev)
 1721 {
 1722         struct rtw89_btc *btc = &rtwdev->btc;
 1723         struct rtw89_btc_wl_info *wl = &btc->cx.wl;
 1724         struct rtw89_btc_wl_rfk_info *rfk_info = &wl->rfk_info;
 1725         struct sk_buff *skb;
 1726         u8 *cmd;
 1727 
 1728         skb = rtw89_fw_h2c_alloc_skb_with_hdr(rtwdev, H2C_LEN_CXDRVINFO_RFK);
 1729         if (!skb) {
 1730                 rtw89_err(rtwdev, "failed to alloc skb for h2c cxdrv_ctrl\n");
 1731                 return -ENOMEM;
 1732         }
 1733         skb_put(skb, H2C_LEN_CXDRVINFO_RFK);
 1734         cmd = skb->data;
 1735 
 1736         RTW89_SET_FWCMD_CXHDR_TYPE(cmd, CXDRVINFO_RFK);
 1737         RTW89_SET_FWCMD_CXHDR_LEN(cmd, H2C_LEN_CXDRVINFO_RFK - H2C_LEN_CXDRVHDR);
 1738 
 1739         RTW89_SET_FWCMD_CXRFK_STATE(cmd, rfk_info->state);
 1740         RTW89_SET_FWCMD_CXRFK_PATH_MAP(cmd, rfk_info->path_map);
 1741         RTW89_SET_FWCMD_CXRFK_PHY_MAP(cmd, rfk_info->phy_map);
 1742         RTW89_SET_FWCMD_CXRFK_BAND(cmd, rfk_info->band);
 1743         RTW89_SET_FWCMD_CXRFK_TYPE(cmd, rfk_info->type);
 1744 
 1745         rtw89_h2c_pkt_set_hdr(rtwdev, skb, FWCMD_TYPE_H2C,
 1746                               H2C_CAT_OUTSRC, BTFC_SET,
 1747                               SET_DRV_INFO, 0, 0,
 1748                               H2C_LEN_CXDRVINFO_RFK);
 1749 
 1750         if (rtw89_h2c_tx(rtwdev, skb, false)) {
 1751                 rtw89_err(rtwdev, "failed to send h2c\n");
 1752                 goto fail;
 1753         }
 1754 
 1755         return 0;
 1756 fail:
 1757         dev_kfree_skb_any(skb);
 1758 
 1759         return -EBUSY;
 1760 }
 1761 
 1762 #define H2C_LEN_PKT_OFLD 4
 1763 int rtw89_fw_h2c_del_pkt_offload(struct rtw89_dev *rtwdev, u8 id)
 1764 {
 1765         struct sk_buff *skb;
 1766         u8 *cmd;
 1767 
 1768         skb = rtw89_fw_h2c_alloc_skb_with_hdr(rtwdev, H2C_LEN_PKT_OFLD);
 1769         if (!skb) {
 1770                 rtw89_err(rtwdev, "failed to alloc skb for h2c pkt offload\n");
 1771                 return -ENOMEM;
 1772         }
 1773         skb_put(skb, H2C_LEN_PKT_OFLD);
 1774         cmd = skb->data;
 1775 
 1776         RTW89_SET_FWCMD_PACKET_OFLD_PKT_IDX(cmd, id);
 1777         RTW89_SET_FWCMD_PACKET_OFLD_PKT_OP(cmd, RTW89_PKT_OFLD_OP_DEL);
 1778 
 1779         rtw89_h2c_pkt_set_hdr(rtwdev, skb, FWCMD_TYPE_H2C,
 1780                               H2C_CAT_MAC, H2C_CL_MAC_FW_OFLD,
 1781                               H2C_FUNC_PACKET_OFLD, 1, 1,
 1782                               H2C_LEN_PKT_OFLD);
 1783 
 1784         if (rtw89_h2c_tx(rtwdev, skb, false)) {
 1785                 rtw89_err(rtwdev, "failed to send h2c\n");
 1786                 goto fail;
 1787         }
 1788 
 1789         return 0;
 1790 fail:
 1791         dev_kfree_skb_any(skb);
 1792 
 1793         return -EBUSY;
 1794 }
 1795 
 1796 int rtw89_fw_h2c_add_pkt_offload(struct rtw89_dev *rtwdev, u8 *id,
 1797                                  struct sk_buff *skb_ofld)
 1798 {
 1799         struct sk_buff *skb;
 1800         u8 *cmd;
 1801         u8 alloc_id;
 1802 
 1803         alloc_id = rtw89_core_acquire_bit_map(rtwdev->pkt_offload,
 1804                                               RTW89_MAX_PKT_OFLD_NUM);
 1805         if (alloc_id == RTW89_MAX_PKT_OFLD_NUM)
 1806                 return -ENOSPC;
 1807 
 1808         *id = alloc_id;
 1809 
 1810         skb = rtw89_fw_h2c_alloc_skb_with_hdr(rtwdev, H2C_LEN_PKT_OFLD + skb_ofld->len);
 1811         if (!skb) {
 1812                 rtw89_err(rtwdev, "failed to alloc skb for h2c pkt offload\n");
 1813                 return -ENOMEM;
 1814         }
 1815         skb_put(skb, H2C_LEN_PKT_OFLD);
 1816         cmd = skb->data;
 1817 
 1818         RTW89_SET_FWCMD_PACKET_OFLD_PKT_IDX(cmd, alloc_id);
 1819         RTW89_SET_FWCMD_PACKET_OFLD_PKT_OP(cmd, RTW89_PKT_OFLD_OP_ADD);
 1820         RTW89_SET_FWCMD_PACKET_OFLD_PKT_LENGTH(cmd, skb_ofld->len);
 1821         skb_put_data(skb, skb_ofld->data, skb_ofld->len);
 1822 
 1823         rtw89_h2c_pkt_set_hdr(rtwdev, skb, FWCMD_TYPE_H2C,
 1824                               H2C_CAT_MAC, H2C_CL_MAC_FW_OFLD,
 1825                               H2C_FUNC_PACKET_OFLD, 1, 1,
 1826                               H2C_LEN_PKT_OFLD + skb_ofld->len);
 1827 
 1828         if (rtw89_h2c_tx(rtwdev, skb, false)) {
 1829                 rtw89_err(rtwdev, "failed to send h2c\n");
 1830                 goto fail;
 1831         }
 1832 
 1833         return 0;
 1834 fail:
 1835         dev_kfree_skb_any(skb);
 1836 
 1837         return -EBUSY;
 1838 }
 1839 
 1840 #define H2C_LEN_SCAN_LIST_OFFLOAD 4
 1841 int rtw89_fw_h2c_scan_list_offload(struct rtw89_dev *rtwdev, int len,
 1842                                    struct list_head *chan_list)
 1843 {
 1844         struct rtw89_mac_chinfo *ch_info;
 1845         struct sk_buff *skb;
 1846         int skb_len = H2C_LEN_SCAN_LIST_OFFLOAD + len * RTW89_MAC_CHINFO_SIZE;
 1847         u8 *cmd;
 1848 
 1849         skb = rtw89_fw_h2c_alloc_skb_with_hdr(rtwdev, skb_len);
 1850         if (!skb) {
 1851                 rtw89_err(rtwdev, "failed to alloc skb for h2c scan list\n");
 1852                 return -ENOMEM;
 1853         }
 1854         skb_put(skb, H2C_LEN_SCAN_LIST_OFFLOAD);
 1855         cmd = skb->data;
 1856 
 1857         RTW89_SET_FWCMD_SCANOFLD_CH_NUM(cmd, len);
 1858         /* in unit of 4 bytes */
 1859         RTW89_SET_FWCMD_SCANOFLD_CH_SIZE(cmd, RTW89_MAC_CHINFO_SIZE / 4);
 1860 
 1861         list_for_each_entry(ch_info, chan_list, list) {
 1862                 cmd = skb_put(skb, RTW89_MAC_CHINFO_SIZE);
 1863 
 1864                 RTW89_SET_FWCMD_CHINFO_PERIOD(cmd, ch_info->period);
 1865                 RTW89_SET_FWCMD_CHINFO_DWELL(cmd, ch_info->dwell_time);
 1866                 RTW89_SET_FWCMD_CHINFO_CENTER_CH(cmd, ch_info->central_ch);
 1867                 RTW89_SET_FWCMD_CHINFO_PRI_CH(cmd, ch_info->pri_ch);
 1868                 RTW89_SET_FWCMD_CHINFO_BW(cmd, ch_info->bw);
 1869                 RTW89_SET_FWCMD_CHINFO_ACTION(cmd, ch_info->notify_action);
 1870                 RTW89_SET_FWCMD_CHINFO_NUM_PKT(cmd, ch_info->num_pkt);
 1871                 RTW89_SET_FWCMD_CHINFO_TX(cmd, ch_info->tx_pkt);
 1872                 RTW89_SET_FWCMD_CHINFO_PAUSE_DATA(cmd, ch_info->pause_data);
 1873                 RTW89_SET_FWCMD_CHINFO_BAND(cmd, ch_info->ch_band);
 1874                 RTW89_SET_FWCMD_CHINFO_PKT_ID(cmd, ch_info->probe_id);
 1875                 RTW89_SET_FWCMD_CHINFO_DFS(cmd, ch_info->dfs_ch);
 1876                 RTW89_SET_FWCMD_CHINFO_TX_NULL(cmd, ch_info->tx_null);
 1877                 RTW89_SET_FWCMD_CHINFO_RANDOM(cmd, ch_info->rand_seq_num);
 1878                 RTW89_SET_FWCMD_CHINFO_PKT0(cmd, ch_info->pkt_id[0]);
 1879                 RTW89_SET_FWCMD_CHINFO_PKT1(cmd, ch_info->pkt_id[1]);
 1880                 RTW89_SET_FWCMD_CHINFO_PKT2(cmd, ch_info->pkt_id[2]);
 1881                 RTW89_SET_FWCMD_CHINFO_PKT3(cmd, ch_info->pkt_id[3]);
 1882                 RTW89_SET_FWCMD_CHINFO_PKT4(cmd, ch_info->pkt_id[4]);
 1883                 RTW89_SET_FWCMD_CHINFO_PKT5(cmd, ch_info->pkt_id[5]);
 1884                 RTW89_SET_FWCMD_CHINFO_PKT6(cmd, ch_info->pkt_id[6]);
 1885                 RTW89_SET_FWCMD_CHINFO_PKT7(cmd, ch_info->pkt_id[7]);
 1886         }
 1887 
 1888         rtw89_h2c_pkt_set_hdr(rtwdev, skb, FWCMD_TYPE_H2C,
 1889                               H2C_CAT_MAC, H2C_CL_MAC_FW_OFLD,
 1890                               H2C_FUNC_ADD_SCANOFLD_CH, 1, 1, skb_len);
 1891 
 1892         if (rtw89_h2c_tx(rtwdev, skb, false)) {
 1893                 rtw89_err(rtwdev, "failed to send h2c\n");
 1894                 goto fail;
 1895         }
 1896 
 1897         return 0;
 1898 fail:
 1899         dev_kfree_skb_any(skb);
 1900 
 1901         return -EBUSY;
 1902 }
 1903 
 1904 #define H2C_LEN_SCAN_OFFLOAD 20
 1905 int rtw89_fw_h2c_scan_offload(struct rtw89_dev *rtwdev,
 1906                               struct rtw89_scan_option *option,
 1907                               struct rtw89_vif *rtwvif)
 1908 {
 1909         struct rtw89_hw_scan_info *scan_info = &rtwdev->scan_info;
 1910         struct sk_buff *skb;
 1911         u8 *cmd;
 1912 
 1913         skb = rtw89_fw_h2c_alloc_skb_with_hdr(rtwdev, H2C_LEN_SCAN_OFFLOAD);
 1914         if (!skb) {
 1915                 rtw89_err(rtwdev, "failed to alloc skb for h2c scan offload\n");
 1916                 return -ENOMEM;
 1917         }
 1918         skb_put(skb, H2C_LEN_SCAN_OFFLOAD);
 1919         cmd = skb->data;
 1920 
 1921         RTW89_SET_FWCMD_SCANOFLD_MACID(cmd, rtwvif->mac_id);
 1922         RTW89_SET_FWCMD_SCANOFLD_PORT_ID(cmd, rtwvif->port);
 1923         RTW89_SET_FWCMD_SCANOFLD_BAND(cmd, RTW89_PHY_0);
 1924         RTW89_SET_FWCMD_SCANOFLD_OPERATION(cmd, option->enable);
 1925         RTW89_SET_FWCMD_SCANOFLD_NOTIFY_END(cmd, true);
 1926         RTW89_SET_FWCMD_SCANOFLD_TARGET_CH_MODE(cmd, option->target_ch_mode);
 1927         RTW89_SET_FWCMD_SCANOFLD_START_MODE(cmd, RTW89_SCAN_IMMEDIATE);
 1928         RTW89_SET_FWCMD_SCANOFLD_SCAN_TYPE(cmd, RTW89_SCAN_ONCE);
 1929         if (option->target_ch_mode) {
 1930                 RTW89_SET_FWCMD_SCANOFLD_TARGET_CH_BW(cmd, scan_info->op_bw);
 1931                 RTW89_SET_FWCMD_SCANOFLD_TARGET_PRI_CH(cmd,
 1932                                                        scan_info->op_pri_ch);
 1933                 RTW89_SET_FWCMD_SCANOFLD_TARGET_CENTRAL_CH(cmd,
 1934                                                            scan_info->op_chan);
 1935         }
 1936 
 1937         rtw89_h2c_pkt_set_hdr(rtwdev, skb, FWCMD_TYPE_H2C,
 1938                               H2C_CAT_MAC, H2C_CL_MAC_FW_OFLD,
 1939                               H2C_FUNC_SCANOFLD, 1, 1,
 1940                               H2C_LEN_SCAN_OFFLOAD);
 1941 
 1942         if (rtw89_h2c_tx(rtwdev, skb, false)) {
 1943                 rtw89_err(rtwdev, "failed to send h2c\n");
 1944                 goto fail;
 1945         }
 1946 
 1947         return 0;
 1948 fail:
 1949         dev_kfree_skb_any(skb);
 1950 
 1951         return -EBUSY;
 1952 }
 1953 
 1954 int rtw89_fw_h2c_rf_reg(struct rtw89_dev *rtwdev,
 1955                         struct rtw89_fw_h2c_rf_reg_info *info,
 1956                         u16 len, u8 page)
 1957 {
 1958         struct sk_buff *skb;
 1959         u8 class = info->rf_path == RF_PATH_A ?
 1960                    H2C_CL_OUTSRC_RF_REG_A : H2C_CL_OUTSRC_RF_REG_B;
 1961 
 1962         skb = rtw89_fw_h2c_alloc_skb_with_hdr(rtwdev, len);
 1963         if (!skb) {
 1964                 rtw89_err(rtwdev, "failed to alloc skb for h2c rf reg\n");
 1965                 return -ENOMEM;
 1966         }
 1967         skb_put_data(skb, info->rtw89_phy_config_rf_h2c[page], len);
 1968 
 1969         rtw89_h2c_pkt_set_hdr(rtwdev, skb, FWCMD_TYPE_H2C,
 1970                               H2C_CAT_OUTSRC, class, page, 0, 0,
 1971                               len);
 1972 
 1973         if (rtw89_h2c_tx(rtwdev, skb, false)) {
 1974                 rtw89_err(rtwdev, "failed to send h2c\n");
 1975                 goto fail;
 1976         }
 1977 
 1978         return 0;
 1979 fail:
 1980         dev_kfree_skb_any(skb);
 1981 
 1982         return -EBUSY;
 1983 }
 1984 
 1985 int rtw89_fw_h2c_rf_ntfy_mcc(struct rtw89_dev *rtwdev)
 1986 {
 1987         const struct rtw89_chan *chan = rtw89_chan_get(rtwdev, RTW89_SUB_ENTITY_0);
 1988         struct rtw89_mcc_info *mcc_info = &rtwdev->mcc;
 1989         struct rtw89_fw_h2c_rf_get_mccch *mccch;
 1990         struct sk_buff *skb;
 1991 
 1992         skb = rtw89_fw_h2c_alloc_skb_with_hdr(rtwdev, sizeof(*mccch));
 1993         if (!skb) {
 1994                 rtw89_err(rtwdev, "failed to alloc skb for h2c cxdrv_ctrl\n");
 1995                 return -ENOMEM;
 1996         }
 1997         skb_put(skb, sizeof(*mccch));
 1998         mccch = (struct rtw89_fw_h2c_rf_get_mccch *)skb->data;
 1999 
 2000         mccch->ch_0 = cpu_to_le32(mcc_info->ch[0]);
 2001         mccch->ch_1 = cpu_to_le32(mcc_info->ch[1]);
 2002         mccch->band_0 = cpu_to_le32(mcc_info->band[0]);
 2003         mccch->band_1 = cpu_to_le32(mcc_info->band[1]);
 2004         mccch->current_channel = cpu_to_le32(chan->channel);
 2005         mccch->current_band_type = cpu_to_le32(chan->band_type);
 2006 
 2007         rtw89_h2c_pkt_set_hdr(rtwdev, skb, FWCMD_TYPE_H2C,
 2008                               H2C_CAT_OUTSRC, H2C_CL_OUTSRC_RF_FW_NOTIFY,
 2009                               H2C_FUNC_OUTSRC_RF_GET_MCCCH, 0, 0,
 2010                               sizeof(*mccch));
 2011 
 2012         if (rtw89_h2c_tx(rtwdev, skb, false)) {
 2013                 rtw89_err(rtwdev, "failed to send h2c\n");
 2014                 goto fail;
 2015         }
 2016 
 2017         return 0;
 2018 fail:
 2019         dev_kfree_skb_any(skb);
 2020 
 2021         return -EBUSY;
 2022 }
 2023 EXPORT_SYMBOL(rtw89_fw_h2c_rf_ntfy_mcc);
 2024 
 2025 int rtw89_fw_h2c_raw_with_hdr(struct rtw89_dev *rtwdev,
 2026                               u8 h2c_class, u8 h2c_func, u8 *buf, u16 len,
 2027                               bool rack, bool dack)
 2028 {
 2029         struct sk_buff *skb;
 2030 
 2031         skb = rtw89_fw_h2c_alloc_skb_with_hdr(rtwdev, len);
 2032         if (!skb) {
 2033                 rtw89_err(rtwdev, "failed to alloc skb for raw with hdr\n");
 2034                 return -ENOMEM;
 2035         }
 2036         skb_put_data(skb, buf, len);
 2037 
 2038         rtw89_h2c_pkt_set_hdr(rtwdev, skb, FWCMD_TYPE_H2C,
 2039                               H2C_CAT_OUTSRC, h2c_class, h2c_func, rack, dack,
 2040                               len);
 2041 
 2042         if (rtw89_h2c_tx(rtwdev, skb, false)) {
 2043                 rtw89_err(rtwdev, "failed to send h2c\n");
 2044                 goto fail;
 2045         }
 2046 
 2047         return 0;
 2048 fail:
 2049         dev_kfree_skb_any(skb);
 2050 
 2051         return -EBUSY;
 2052 }
 2053 
 2054 int rtw89_fw_h2c_raw(struct rtw89_dev *rtwdev, const u8 *buf, u16 len)
 2055 {
 2056         struct sk_buff *skb;
 2057 
 2058         skb = rtw89_fw_h2c_alloc_skb_no_hdr(rtwdev, len);
 2059         if (!skb) {
 2060                 rtw89_err(rtwdev, "failed to alloc skb for h2c raw\n");
 2061                 return -ENOMEM;
 2062         }
 2063         skb_put_data(skb, buf, len);
 2064 
 2065         if (rtw89_h2c_tx(rtwdev, skb, false)) {
 2066                 rtw89_err(rtwdev, "failed to send h2c\n");
 2067                 goto fail;
 2068         }
 2069 
 2070         return 0;
 2071 fail:
 2072         dev_kfree_skb_any(skb);
 2073 
 2074         return -EBUSY;
 2075 }
 2076 
 2077 void rtw89_fw_send_all_early_h2c(struct rtw89_dev *rtwdev)
 2078 {
 2079         struct rtw89_early_h2c *early_h2c;
 2080 
 2081         lockdep_assert_held(&rtwdev->mutex);
 2082 
 2083         list_for_each_entry(early_h2c, &rtwdev->early_h2c_list, list) {
 2084                 rtw89_fw_h2c_raw(rtwdev, early_h2c->h2c, early_h2c->h2c_len);
 2085         }
 2086 }
 2087 
 2088 void rtw89_fw_free_all_early_h2c(struct rtw89_dev *rtwdev)
 2089 {
 2090         struct rtw89_early_h2c *early_h2c, *tmp;
 2091 
 2092         mutex_lock(&rtwdev->mutex);
 2093         list_for_each_entry_safe(early_h2c, tmp, &rtwdev->early_h2c_list, list) {
 2094                 list_del(&early_h2c->list);
 2095                 kfree(early_h2c->h2c);
 2096                 kfree(early_h2c);
 2097         }
 2098         mutex_unlock(&rtwdev->mutex);
 2099 }
 2100 
 2101 void rtw89_fw_c2h_irqsafe(struct rtw89_dev *rtwdev, struct sk_buff *c2h)
 2102 {
 2103         skb_queue_tail(&rtwdev->c2h_queue, c2h);
 2104         ieee80211_queue_work(rtwdev->hw, &rtwdev->c2h_work);
 2105 }
 2106 
 2107 static void rtw89_fw_c2h_cmd_handle(struct rtw89_dev *rtwdev,
 2108                                     struct sk_buff *skb)
 2109 {
 2110         u8 category = RTW89_GET_C2H_CATEGORY(skb->data);
 2111         u8 class = RTW89_GET_C2H_CLASS(skb->data);
 2112         u8 func = RTW89_GET_C2H_FUNC(skb->data);
 2113         u16 len = RTW89_GET_C2H_LEN(skb->data);
 2114         bool dump = true;
 2115 
 2116         if (!test_bit(RTW89_FLAG_RUNNING, rtwdev->flags))
 2117                 return;
 2118 
 2119         switch (category) {
 2120         case RTW89_C2H_CAT_TEST:
 2121                 break;
 2122         case RTW89_C2H_CAT_MAC:
 2123                 rtw89_mac_c2h_handle(rtwdev, skb, len, class, func);
 2124                 if (class == RTW89_MAC_C2H_CLASS_INFO &&
 2125                     func == RTW89_MAC_C2H_FUNC_C2H_LOG)
 2126                         dump = false;
 2127                 break;
 2128         case RTW89_C2H_CAT_OUTSRC:
 2129                 if (class >= RTW89_PHY_C2H_CLASS_BTC_MIN &&
 2130                     class <= RTW89_PHY_C2H_CLASS_BTC_MAX)
 2131                         rtw89_btc_c2h_handle(rtwdev, skb, len, class, func);
 2132                 else
 2133                         rtw89_phy_c2h_handle(rtwdev, skb, len, class, func);
 2134                 break;
 2135         }
 2136 
 2137         if (dump)
 2138                 rtw89_hex_dump(rtwdev, RTW89_DBG_FW, "C2H: ", skb->data, skb->len);
 2139 }
 2140 
 2141 void rtw89_fw_c2h_work(struct work_struct *work)
 2142 {
 2143         struct rtw89_dev *rtwdev = container_of(work, struct rtw89_dev,
 2144                                                 c2h_work);
 2145         struct sk_buff *skb, *tmp;
 2146 
 2147         skb_queue_walk_safe(&rtwdev->c2h_queue, skb, tmp) {
 2148                 skb_unlink(skb, &rtwdev->c2h_queue);
 2149                 mutex_lock(&rtwdev->mutex);
 2150                 rtw89_fw_c2h_cmd_handle(rtwdev, skb);
 2151                 mutex_unlock(&rtwdev->mutex);
 2152                 dev_kfree_skb_any(skb);
 2153         }
 2154 }
 2155 
 2156 static int rtw89_fw_write_h2c_reg(struct rtw89_dev *rtwdev,
 2157                                   struct rtw89_mac_h2c_info *info)
 2158 {
 2159         const struct rtw89_chip_info *chip = rtwdev->chip;
 2160         const u32 *h2c_reg = chip->h2c_regs;
 2161         u8 i, val, len;
 2162         int ret;
 2163 
 2164         ret = read_poll_timeout(rtw89_read8, val, val == 0, 1000, 5000, false,
 2165                                 rtwdev, chip->h2c_ctrl_reg);
 2166         if (ret) {
 2167                 rtw89_warn(rtwdev, "FW does not process h2c registers\n");
 2168                 return ret;
 2169         }
 2170 
 2171         len = DIV_ROUND_UP(info->content_len + RTW89_H2CREG_HDR_LEN,
 2172                            sizeof(info->h2creg[0]));
 2173 
 2174         RTW89_SET_H2CREG_HDR_FUNC(&info->h2creg[0], info->id);
 2175         RTW89_SET_H2CREG_HDR_LEN(&info->h2creg[0], len);
 2176         for (i = 0; i < RTW89_H2CREG_MAX; i++)
 2177                 rtw89_write32(rtwdev, h2c_reg[i], info->h2creg[i]);
 2178 
 2179         rtw89_write8(rtwdev, chip->h2c_ctrl_reg, B_AX_H2CREG_TRIGGER);
 2180 
 2181         return 0;
 2182 }
 2183 
 2184 static int rtw89_fw_read_c2h_reg(struct rtw89_dev *rtwdev,
 2185                                  struct rtw89_mac_c2h_info *info)
 2186 {
 2187         const struct rtw89_chip_info *chip = rtwdev->chip;
 2188         const u32 *c2h_reg = chip->c2h_regs;
 2189         u32 ret;
 2190         u8 i, val;
 2191 
 2192         info->id = RTW89_FWCMD_C2HREG_FUNC_NULL;
 2193 
 2194         ret = read_poll_timeout_atomic(rtw89_read8, val, val, 1,
 2195                                        RTW89_C2H_TIMEOUT, false, rtwdev,
 2196                                        chip->c2h_ctrl_reg);
 2197         if (ret) {
 2198                 rtw89_warn(rtwdev, "c2h reg timeout\n");
 2199                 return ret;
 2200         }
 2201 
 2202         for (i = 0; i < RTW89_C2HREG_MAX; i++)
 2203                 info->c2hreg[i] = rtw89_read32(rtwdev, c2h_reg[i]);
 2204 
 2205         rtw89_write8(rtwdev, chip->c2h_ctrl_reg, 0);
 2206 
 2207         info->id = RTW89_GET_C2H_HDR_FUNC(*info->c2hreg);
 2208         info->content_len = (RTW89_GET_C2H_HDR_LEN(*info->c2hreg) << 2) -
 2209                                 RTW89_C2HREG_HDR_LEN;
 2210 
 2211         return 0;
 2212 }
 2213 
 2214 int rtw89_fw_msg_reg(struct rtw89_dev *rtwdev,
 2215                      struct rtw89_mac_h2c_info *h2c_info,
 2216                      struct rtw89_mac_c2h_info *c2h_info)
 2217 {
 2218         u32 ret;
 2219 
 2220         if (h2c_info && h2c_info->id != RTW89_FWCMD_H2CREG_FUNC_GET_FEATURE)
 2221                 lockdep_assert_held(&rtwdev->mutex);
 2222 
 2223         if (!h2c_info && !c2h_info)
 2224                 return -EINVAL;
 2225 
 2226         if (!h2c_info)
 2227                 goto recv_c2h;
 2228 
 2229         ret = rtw89_fw_write_h2c_reg(rtwdev, h2c_info);
 2230         if (ret)
 2231                 return ret;
 2232 
 2233 recv_c2h:
 2234         if (!c2h_info)
 2235                 return 0;
 2236 
 2237         ret = rtw89_fw_read_c2h_reg(rtwdev, c2h_info);
 2238         if (ret)
 2239                 return ret;
 2240 
 2241         return 0;
 2242 }
 2243 
 2244 void rtw89_fw_st_dbg_dump(struct rtw89_dev *rtwdev)
 2245 {
 2246         if (!test_bit(RTW89_FLAG_POWERON, rtwdev->flags)) {
 2247                 rtw89_err(rtwdev, "[ERR]pwr is off\n");
 2248                 return;
 2249         }
 2250 
 2251         rtw89_info(rtwdev, "FW status = 0x%x\n", rtw89_read32(rtwdev, R_AX_UDM0));
 2252         rtw89_info(rtwdev, "FW BADADDR = 0x%x\n", rtw89_read32(rtwdev, R_AX_UDM1));
 2253         rtw89_info(rtwdev, "FW EPC/RA = 0x%x\n", rtw89_read32(rtwdev, R_AX_UDM2));
 2254         rtw89_info(rtwdev, "FW MISC = 0x%x\n", rtw89_read32(rtwdev, R_AX_UDM3));
 2255         rtw89_info(rtwdev, "R_AX_HALT_C2H = 0x%x\n",
 2256                    rtw89_read32(rtwdev, R_AX_HALT_C2H));
 2257         rtw89_info(rtwdev, "R_AX_SER_DBG_INFO = 0x%x\n",
 2258                    rtw89_read32(rtwdev, R_AX_SER_DBG_INFO));
 2259 
 2260         rtw89_fw_prog_cnt_dump(rtwdev);
 2261 }
 2262 
 2263 static void rtw89_release_pkt_list(struct rtw89_dev *rtwdev)
 2264 {
 2265         struct list_head *pkt_list = rtwdev->scan_info.pkt_list;
 2266         struct rtw89_pktofld_info *info, *tmp;
 2267         u8 idx;
 2268 
 2269         for (idx = NL80211_BAND_2GHZ; idx < NUM_NL80211_BANDS; idx++) {
 2270                 if (!(rtwdev->chip->support_bands & BIT(idx)))
 2271                         continue;
 2272 
 2273                 list_for_each_entry_safe(info, tmp, &pkt_list[idx], list) {
 2274                         rtw89_fw_h2c_del_pkt_offload(rtwdev, info->id);
 2275                         rtw89_core_release_bit_map(rtwdev->pkt_offload,
 2276                                                    info->id);
 2277                         list_del(&info->list);
 2278                         kfree(info);
 2279                 }
 2280         }
 2281 }
 2282 
 2283 static int rtw89_append_probe_req_ie(struct rtw89_dev *rtwdev,
 2284                                      struct rtw89_vif *rtwvif,
 2285                                      struct sk_buff *skb)
 2286 {
 2287         struct rtw89_hw_scan_info *scan_info = &rtwdev->scan_info;
 2288         struct ieee80211_scan_ies *ies = rtwvif->scan_ies;
 2289         struct rtw89_pktofld_info *info;
 2290         struct sk_buff *new;
 2291         int ret = 0;
 2292         u8 band;
 2293 
 2294         for (band = NL80211_BAND_2GHZ; band < NUM_NL80211_BANDS; band++) {
 2295                 if (!(rtwdev->chip->support_bands & BIT(band)))
 2296                         continue;
 2297 
 2298                 new = skb_copy(skb, GFP_KERNEL);
 2299                 if (!new) {
 2300                         ret = -ENOMEM;
 2301                         goto out;
 2302                 }
 2303                 skb_put_data(new, ies->ies[band], ies->len[band]);
 2304                 skb_put_data(new, ies->common_ies, ies->common_ie_len);
 2305 
 2306                 info = kzalloc(sizeof(*info), GFP_KERNEL);
 2307                 if (!info) {
 2308                         ret = -ENOMEM;
 2309                         kfree_skb(new);
 2310                         goto out;
 2311                 }
 2312 
 2313                 list_add_tail(&info->list, &scan_info->pkt_list[band]);
 2314                 ret = rtw89_fw_h2c_add_pkt_offload(rtwdev, &info->id, new);
 2315                 if (ret)
 2316                         goto out;
 2317 
 2318                 kfree_skb(new);
 2319         }
 2320 out:
 2321         return ret;
 2322 }
 2323 
 2324 static int rtw89_hw_scan_update_probe_req(struct rtw89_dev *rtwdev,
 2325                                           struct rtw89_vif *rtwvif)
 2326 {
 2327         struct cfg80211_scan_request *req = rtwvif->scan_req;
 2328         struct sk_buff *skb;
 2329         u8 num = req->n_ssids, i;
 2330         int ret;
 2331 
 2332         for (i = 0; i < num; i++) {
 2333                 skb = ieee80211_probereq_get(rtwdev->hw, rtwvif->mac_addr,
 2334                                              req->ssids[i].ssid,
 2335                                              req->ssids[i].ssid_len,
 2336                                              req->ie_len);
 2337                 if (!skb)
 2338                         return -ENOMEM;
 2339 
 2340                 ret = rtw89_append_probe_req_ie(rtwdev, rtwvif, skb);
 2341                 kfree_skb(skb);
 2342 
 2343                 if (ret)
 2344                         return ret;
 2345         }
 2346 
 2347         return 0;
 2348 }
 2349 
 2350 static void rtw89_hw_scan_add_chan(struct rtw89_dev *rtwdev, int chan_type,
 2351                                    int ssid_num,
 2352                                    struct rtw89_mac_chinfo *ch_info)
 2353 {
 2354         struct rtw89_hw_scan_info *scan_info = &rtwdev->scan_info;
 2355         struct rtw89_pktofld_info *info;
 2356         u8 band, probe_count = 0;
 2357 
 2358         ch_info->notify_action = RTW89_SCANOFLD_DEBUG_MASK;
 2359         ch_info->dfs_ch = chan_type == RTW89_CHAN_DFS;
 2360         ch_info->bw = RTW89_SCAN_WIDTH;
 2361         ch_info->tx_pkt = true;
 2362         ch_info->cfg_tx_pwr = false;
 2363         ch_info->tx_pwr_idx = 0;
 2364         ch_info->tx_null = false;
 2365         ch_info->pause_data = false;
 2366 
 2367         if (ssid_num) {
 2368                 ch_info->num_pkt = ssid_num;
 2369                 band = ch_info->ch_band;
 2370 
 2371                 list_for_each_entry(info, &scan_info->pkt_list[band], list) {
 2372                         ch_info->probe_id = info->id;
 2373                         ch_info->pkt_id[probe_count] = info->id;
 2374                         if (++probe_count >= ssid_num)
 2375                                 break;
 2376                 }
 2377                 if (probe_count != ssid_num)
 2378                         rtw89_err(rtwdev, "SSID num differs from list len\n");
 2379         }
 2380 
 2381         switch (chan_type) {
 2382         case RTW89_CHAN_OPERATE:
 2383                 ch_info->probe_id = RTW89_SCANOFLD_PKT_NONE;
 2384                 ch_info->central_ch = scan_info->op_chan;
 2385                 ch_info->pri_ch = scan_info->op_pri_ch;
 2386                 ch_info->ch_band = scan_info->op_band;
 2387                 ch_info->bw = scan_info->op_bw;
 2388                 ch_info->tx_null = true;
 2389                 ch_info->num_pkt = 0;
 2390                 break;
 2391         case RTW89_CHAN_DFS:
 2392                 ch_info->period = max_t(u8, ch_info->period,
 2393                                         RTW89_DFS_CHAN_TIME);
 2394                 ch_info->dwell_time = RTW89_DWELL_TIME;
 2395                 break;
 2396         case RTW89_CHAN_ACTIVE:
 2397                 break;
 2398         default:
 2399                 rtw89_err(rtwdev, "Channel type out of bound\n");
 2400         }
 2401 }
 2402 
 2403 static int rtw89_hw_scan_add_chan_list(struct rtw89_dev *rtwdev,
 2404                                        struct rtw89_vif *rtwvif)
 2405 {
 2406         struct cfg80211_scan_request *req = rtwvif->scan_req;
 2407         struct rtw89_mac_chinfo *ch_info, *tmp;
 2408         struct ieee80211_channel *channel;
 2409         struct list_head chan_list;
 2410         bool random_seq = req->flags & NL80211_SCAN_FLAG_RANDOM_SN;
 2411         int list_len = req->n_channels, off_chan_time = 0;
 2412         enum rtw89_chan_type type;
 2413         int ret = 0, i;
 2414 
 2415         INIT_LIST_HEAD(&chan_list);
 2416         for (i = 0; i < req->n_channels; i++) {
 2417                 channel = req->channels[i];
 2418                 ch_info = kzalloc(sizeof(*ch_info), GFP_KERNEL);
 2419                 if (!ch_info) {
 2420                         ret = -ENOMEM;
 2421                         goto out;
 2422                 }
 2423 
 2424                 ch_info->period = req->duration_mandatory ?
 2425                                   req->duration : RTW89_CHANNEL_TIME;
 2426                 ch_info->ch_band = channel->band;
 2427                 ch_info->central_ch = channel->hw_value;
 2428                 ch_info->pri_ch = channel->hw_value;
 2429                 ch_info->rand_seq_num = random_seq;
 2430 
 2431                 if (channel->flags &
 2432                     (IEEE80211_CHAN_RADAR | IEEE80211_CHAN_NO_IR))
 2433                         type = RTW89_CHAN_DFS;
 2434                 else
 2435                         type = RTW89_CHAN_ACTIVE;
 2436                 rtw89_hw_scan_add_chan(rtwdev, type, req->n_ssids, ch_info);
 2437 
 2438                 if (rtwvif->net_type != RTW89_NET_TYPE_NO_LINK &&
 2439                     off_chan_time + ch_info->period > RTW89_OFF_CHAN_TIME) {
 2440                         tmp = kzalloc(sizeof(*tmp), GFP_KERNEL);
 2441                         if (!tmp) {
 2442                                 ret = -ENOMEM;
 2443                                 kfree(ch_info);
 2444                                 goto out;
 2445                         }
 2446 
 2447                         type = RTW89_CHAN_OPERATE;
 2448                         tmp->period = req->duration_mandatory ?
 2449                                       req->duration : RTW89_CHANNEL_TIME;
 2450                         rtw89_hw_scan_add_chan(rtwdev, type, 0, tmp);
 2451                         list_add_tail(&tmp->list, &chan_list);
 2452                         off_chan_time = 0;
 2453                         list_len++;
 2454                 }
 2455                 list_add_tail(&ch_info->list, &chan_list);
 2456                 off_chan_time += ch_info->period;
 2457         }
 2458         ret = rtw89_fw_h2c_scan_list_offload(rtwdev, list_len, &chan_list);
 2459 
 2460 out:
 2461         list_for_each_entry_safe(ch_info, tmp, &chan_list, list) {
 2462                 list_del(&ch_info->list);
 2463                 kfree(ch_info);
 2464         }
 2465 
 2466         return ret;
 2467 }
 2468 
 2469 static int rtw89_hw_scan_prehandle(struct rtw89_dev *rtwdev,
 2470                                    struct rtw89_vif *rtwvif)
 2471 {
 2472         int ret;
 2473 
 2474         ret = rtw89_hw_scan_update_probe_req(rtwdev, rtwvif);
 2475         if (ret) {
 2476                 rtw89_err(rtwdev, "Update probe request failed\n");
 2477                 goto out;
 2478         }
 2479         ret = rtw89_hw_scan_add_chan_list(rtwdev, rtwvif);
 2480 out:
 2481         return ret;
 2482 }
 2483 
 2484 void rtw89_hw_scan_start(struct rtw89_dev *rtwdev, struct ieee80211_vif *vif,
 2485                          struct ieee80211_scan_request *scan_req)
 2486 {
 2487         struct rtw89_vif *rtwvif = (struct rtw89_vif *)vif->drv_priv;
 2488         struct cfg80211_scan_request *req = &scan_req->req;
 2489         u8 mac_addr[ETH_ALEN];
 2490 
 2491         rtwdev->scan_info.scanning_vif = vif;
 2492         rtwvif->scan_ies = &scan_req->ies;
 2493         rtwvif->scan_req = req;
 2494         ieee80211_stop_queues(rtwdev->hw);
 2495 
 2496         if (req->flags & NL80211_SCAN_FLAG_RANDOM_ADDR)
 2497                 get_random_mask_addr(mac_addr, req->mac_addr,
 2498                                      req->mac_addr_mask);
 2499         else
 2500                 ether_addr_copy(mac_addr, vif->addr);
 2501         rtw89_core_scan_start(rtwdev, rtwvif, mac_addr, true);
 2502 
 2503         rtwdev->hal.rx_fltr &= ~B_AX_A_BCN_CHK_EN;
 2504         rtwdev->hal.rx_fltr &= ~B_AX_A_BC;
 2505         rtwdev->hal.rx_fltr &= ~B_AX_A_A1_MATCH;
 2506         rtw89_write32_mask(rtwdev,
 2507                            rtw89_mac_reg_by_idx(R_AX_RX_FLTR_OPT, RTW89_MAC_0),
 2508                            B_AX_RX_FLTR_CFG_MASK,
 2509                            rtwdev->hal.rx_fltr);
 2510 }
 2511 
 2512 void rtw89_hw_scan_complete(struct rtw89_dev *rtwdev, struct ieee80211_vif *vif,
 2513                             bool aborted)
 2514 {
 2515         struct cfg80211_scan_info info = {
 2516                 .aborted = aborted,
 2517         };
 2518         struct rtw89_vif *rtwvif;
 2519 
 2520         if (!vif)
 2521                 return;
 2522 
 2523         rtwdev->hal.rx_fltr |= B_AX_A_BCN_CHK_EN;
 2524         rtwdev->hal.rx_fltr |= B_AX_A_BC;
 2525         rtwdev->hal.rx_fltr |= B_AX_A_A1_MATCH;
 2526         rtw89_write32_mask(rtwdev,
 2527                            rtw89_mac_reg_by_idx(R_AX_RX_FLTR_OPT, RTW89_MAC_0),
 2528                            B_AX_RX_FLTR_CFG_MASK,
 2529                            rtwdev->hal.rx_fltr);
 2530 
 2531         rtw89_core_scan_complete(rtwdev, vif, true);
 2532         ieee80211_scan_completed(rtwdev->hw, &info);
 2533         ieee80211_wake_queues(rtwdev->hw);
 2534 
 2535         rtw89_release_pkt_list(rtwdev);
 2536         rtwvif = (struct rtw89_vif *)vif->drv_priv;
 2537         rtwvif->scan_req = NULL;
 2538         rtwvif->scan_ies = NULL;
 2539         rtwdev->scan_info.scanning_vif = NULL;
 2540 
 2541         if (rtwvif->net_type != RTW89_NET_TYPE_NO_LINK)
 2542                 rtw89_store_op_chan(rtwdev, false);
 2543 }
 2544 
 2545 void rtw89_hw_scan_abort(struct rtw89_dev *rtwdev, struct ieee80211_vif *vif)
 2546 {
 2547         rtw89_hw_scan_offload(rtwdev, vif, false);
 2548         rtw89_hw_scan_complete(rtwdev, vif, true);
 2549 }
 2550 
 2551 int rtw89_hw_scan_offload(struct rtw89_dev *rtwdev, struct ieee80211_vif *vif,
 2552                           bool enable)
 2553 {
 2554         struct rtw89_scan_option opt = {0};
 2555         struct rtw89_vif *rtwvif;
 2556         int ret = 0;
 2557 
 2558         rtwvif = vif ? (struct rtw89_vif *)vif->drv_priv : NULL;
 2559         if (!rtwvif)
 2560                 return -EINVAL;
 2561 
 2562         opt.enable = enable;
 2563         opt.target_ch_mode = rtwvif->net_type != RTW89_NET_TYPE_NO_LINK;
 2564         if (enable) {
 2565                 ret = rtw89_hw_scan_prehandle(rtwdev, rtwvif);
 2566                 if (ret)
 2567                         goto out;
 2568         }
 2569         ret = rtw89_fw_h2c_scan_offload(rtwdev, &opt, rtwvif);
 2570 out:
 2571         return ret;
 2572 }
 2573 
 2574 void rtw89_store_op_chan(struct rtw89_dev *rtwdev, bool backup)
 2575 {
 2576         struct rtw89_hw_scan_info *scan_info = &rtwdev->scan_info;
 2577         const struct rtw89_chan *cur = rtw89_chan_get(rtwdev, RTW89_SUB_ENTITY_0);
 2578         struct rtw89_chan new;
 2579 
 2580         if (backup) {
 2581                 scan_info->op_pri_ch = cur->primary_channel;
 2582                 scan_info->op_chan = cur->channel;
 2583                 scan_info->op_bw = cur->band_width;
 2584                 scan_info->op_band = cur->band_type;
 2585         } else {
 2586                 rtw89_chan_create(&new, scan_info->op_chan, scan_info->op_pri_ch,
 2587                                   scan_info->op_band, scan_info->op_bw);
 2588                 rtw89_assign_entity_chan(rtwdev, RTW89_SUB_ENTITY_0, &new);
 2589         }
 2590 }
 2591 
 2592 #define H2C_FW_CPU_EXCEPTION_LEN 4
 2593 #define H2C_FW_CPU_EXCEPTION_TYPE_DEF 0x5566
 2594 int rtw89_fw_h2c_trigger_cpu_exception(struct rtw89_dev *rtwdev)
 2595 {
 2596         struct sk_buff *skb;
 2597 
 2598         skb = rtw89_fw_h2c_alloc_skb_with_hdr(rtwdev, H2C_FW_CPU_EXCEPTION_LEN);
 2599         if (!skb) {
 2600                 rtw89_err(rtwdev,
 2601                           "failed to alloc skb for fw cpu exception\n");
 2602                 return -ENOMEM;
 2603         }
 2604 
 2605         skb_put(skb, H2C_FW_CPU_EXCEPTION_LEN);
 2606         RTW89_SET_FWCMD_CPU_EXCEPTION_TYPE(skb->data,
 2607                                            H2C_FW_CPU_EXCEPTION_TYPE_DEF);
 2608 
 2609         rtw89_h2c_pkt_set_hdr(rtwdev, skb, FWCMD_TYPE_H2C,
 2610                               H2C_CAT_TEST,
 2611                               H2C_CL_FW_STATUS_TEST,
 2612                               H2C_FUNC_CPU_EXCEPTION, 0, 0,
 2613                               H2C_FW_CPU_EXCEPTION_LEN);
 2614 
 2615         if (rtw89_h2c_tx(rtwdev, skb, false)) {
 2616                 rtw89_err(rtwdev, "failed to send h2c\n");
 2617                 goto fail;
 2618         }
 2619 
 2620         return 0;
 2621 
 2622 fail:
 2623         dev_kfree_skb_any(skb);
 2624         return -EBUSY;
 2625 }

Cache object: ffe4a66825591a6c948ec855ccf4691e


[ source navigation ] [ diff markup ] [ identifier search ] [ freetext search ] [ file search ] [ list types ] [ track identifier ]


This page is part of the FreeBSD/Linux Linux Kernel Cross-Reference, and was automatically generated using a modified version of the LXR engine.