1 // SPDX-License-Identifier: GPL-2.0 OR BSD-3-Clause
2 /* Copyright(c) 2019-2020 Realtek Corporation
3 */
4
5 #include <linux/if_arp.h>
6 #include "cam.h"
7 #include "chan.h"
8 #include "coex.h"
9 #include "debug.h"
10 #include "fw.h"
11 #include "mac.h"
12 #include "phy.h"
13 #include "ps.h"
14 #include "reg.h"
15 #include "util.h"
16 #include "wow.h"
17
18 static bool rtw89_is_any_vif_connected_or_connecting(struct rtw89_dev *rtwdev);
19
20 struct rtw89_eapol_2_of_2 {
21 u8 gtkbody[14];
22 u8 key_des_ver;
23 u8 rsvd[92];
24 } __packed;
25
26 struct rtw89_sa_query {
27 u8 category;
28 u8 action;
29 } __packed;
30
31 struct rtw89_arp_rsp {
32 u8 llc_hdr[sizeof(rfc1042_header)];
33 __be16 llc_type;
34 struct arphdr arp_hdr;
35 u8 sender_hw[ETH_ALEN];
36 __be32 sender_ip;
37 u8 target_hw[ETH_ALEN];
38 __be32 target_ip;
39 } __packed;
40
41 static const u8 mss_signature[] = {0x4D, 0x53, 0x53, 0x4B, 0x50, 0x4F, 0x4F, 0x4C};
42
43 const struct rtw89_fw_blacklist rtw89_fw_blacklist_default = {
44 .ver = 0x00,
45 .list = {0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
46 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
47 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
48 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
49 },
50 };
51 EXPORT_SYMBOL(rtw89_fw_blacklist_default);
52
53 union rtw89_fw_element_arg {
54 size_t offset;
55 enum rtw89_rf_path rf_path;
56 enum rtw89_fw_type fw_type;
57 };
58
59 struct rtw89_fw_element_handler {
60 int (*fn)(struct rtw89_dev *rtwdev,
61 const struct rtw89_fw_element_hdr *elm,
62 const union rtw89_fw_element_arg arg);
63 const union rtw89_fw_element_arg arg;
64 const char *name;
65 };
66
67 static void rtw89_fw_c2h_cmd_handle(struct rtw89_dev *rtwdev,
68 struct sk_buff *skb);
69 static int rtw89_h2c_tx_and_wait(struct rtw89_dev *rtwdev, struct sk_buff *skb,
70 struct rtw89_wait_info *wait, unsigned int cond);
71 static int __parse_security_section(struct rtw89_dev *rtwdev,
72 struct rtw89_fw_bin_info *info,
73 struct rtw89_fw_hdr_section_info *section_info,
74 #if defined(__linux__)
75 const void *content,
76 #elif defined(__FreeBSD__)
77 const u8 *content,
78 #endif
79 u32 *mssc_len);
80
rtw89_fw_h2c_alloc_skb(struct rtw89_dev * rtwdev,u32 len,bool header)81 static struct sk_buff *rtw89_fw_h2c_alloc_skb(struct rtw89_dev *rtwdev, u32 len,
82 bool header)
83 {
84 struct sk_buff *skb;
85 u32 header_len = 0;
86 u32 h2c_desc_size = rtwdev->chip->h2c_desc_size;
87
88 if (header)
89 header_len = H2C_HEADER_LEN;
90
91 skb = dev_alloc_skb(len + header_len + h2c_desc_size);
92 if (!skb)
93 return NULL;
94 skb_reserve(skb, header_len + h2c_desc_size);
95 memset(skb->data, 0, len);
96
97 return skb;
98 }
99
rtw89_fw_h2c_alloc_skb_with_hdr(struct rtw89_dev * rtwdev,u32 len)100 struct sk_buff *rtw89_fw_h2c_alloc_skb_with_hdr(struct rtw89_dev *rtwdev, u32 len)
101 {
102 return rtw89_fw_h2c_alloc_skb(rtwdev, len, true);
103 }
104
rtw89_fw_h2c_alloc_skb_no_hdr(struct rtw89_dev * rtwdev,u32 len)105 struct sk_buff *rtw89_fw_h2c_alloc_skb_no_hdr(struct rtw89_dev *rtwdev, u32 len)
106 {
107 return rtw89_fw_h2c_alloc_skb(rtwdev, len, false);
108 }
109
rtw89_fw_check_rdy(struct rtw89_dev * rtwdev,enum rtw89_fwdl_check_type type)110 int rtw89_fw_check_rdy(struct rtw89_dev *rtwdev, enum rtw89_fwdl_check_type type)
111 {
112 const struct rtw89_mac_gen_def *mac = rtwdev->chip->mac_def;
113 u8 val;
114 int ret;
115
116 ret = read_poll_timeout_atomic(mac->fwdl_get_status, val,
117 val == RTW89_FWDL_WCPU_FW_INIT_RDY,
118 1, FWDL_WAIT_CNT, false, rtwdev, type);
119 if (ret) {
120 switch (val) {
121 case RTW89_FWDL_CHECKSUM_FAIL:
122 rtw89_err(rtwdev, "fw checksum fail\n");
123 return -EINVAL;
124
125 case RTW89_FWDL_SECURITY_FAIL:
126 rtw89_err(rtwdev, "fw security fail\n");
127 return -EINVAL;
128
129 case RTW89_FWDL_CV_NOT_MATCH:
130 rtw89_err(rtwdev, "fw cv not match\n");
131 return -EINVAL;
132
133 default:
134 rtw89_err(rtwdev, "fw unexpected status %d\n", val);
135 return -EBUSY;
136 }
137 }
138
139 set_bit(RTW89_FLAG_FW_RDY, rtwdev->flags);
140
141 return 0;
142 }
143
rtw89_fw_hdr_parser_v0(struct rtw89_dev * rtwdev,const u8 * fw,u32 len,struct rtw89_fw_bin_info * info)144 static int rtw89_fw_hdr_parser_v0(struct rtw89_dev *rtwdev, const u8 *fw, u32 len,
145 struct rtw89_fw_bin_info *info)
146 {
147 const struct rtw89_fw_hdr *fw_hdr = (const struct rtw89_fw_hdr *)fw;
148 const struct rtw89_chip_info *chip = rtwdev->chip;
149 struct rtw89_fw_hdr_section_info *section_info;
150 struct rtw89_fw_secure *sec = &rtwdev->fw.sec;
151 const struct rtw89_fw_dynhdr_hdr *fwdynhdr;
152 const struct rtw89_fw_hdr_section *section;
153 const u8 *fw_end = fw + len;
154 const u8 *bin;
155 u32 base_hdr_len;
156 u32 mssc_len;
157 int ret;
158 u32 i;
159
160 if (!info)
161 return -EINVAL;
162
163 info->section_num = le32_get_bits(fw_hdr->w6, FW_HDR_W6_SEC_NUM);
164 base_hdr_len = struct_size(fw_hdr, sections, info->section_num);
165 info->dynamic_hdr_en = le32_get_bits(fw_hdr->w7, FW_HDR_W7_DYN_HDR);
166 info->idmem_share_mode = le32_get_bits(fw_hdr->w7, FW_HDR_W7_IDMEM_SHARE_MODE);
167
168 if (info->dynamic_hdr_en) {
169 info->hdr_len = le32_get_bits(fw_hdr->w3, FW_HDR_W3_LEN);
170 info->dynamic_hdr_len = info->hdr_len - base_hdr_len;
171 fwdynhdr = (const struct rtw89_fw_dynhdr_hdr *)(fw + base_hdr_len);
172 if (le32_to_cpu(fwdynhdr->hdr_len) != info->dynamic_hdr_len) {
173 rtw89_err(rtwdev, "[ERR]invalid fw dynamic header len\n");
174 return -EINVAL;
175 }
176 } else {
177 info->hdr_len = base_hdr_len;
178 info->dynamic_hdr_len = 0;
179 }
180
181 bin = fw + info->hdr_len;
182
183 /* jump to section header */
184 section_info = info->section_info;
185 for (i = 0; i < info->section_num; i++) {
186 section = &fw_hdr->sections[i];
187 section_info->type =
188 le32_get_bits(section->w1, FWSECTION_HDR_W1_SECTIONTYPE);
189 section_info->len = le32_get_bits(section->w1, FWSECTION_HDR_W1_SEC_SIZE);
190
191 if (le32_get_bits(section->w1, FWSECTION_HDR_W1_CHECKSUM))
192 section_info->len += FWDL_SECTION_CHKSUM_LEN;
193 section_info->redl = le32_get_bits(section->w1, FWSECTION_HDR_W1_REDL);
194 section_info->dladdr =
195 le32_get_bits(section->w0, FWSECTION_HDR_W0_DL_ADDR) & 0x1fffffff;
196 section_info->addr = bin;
197
198 if (section_info->type == FWDL_SECURITY_SECTION_TYPE) {
199 section_info->mssc =
200 le32_get_bits(section->w2, FWSECTION_HDR_W2_MSSC);
201
202 ret = __parse_security_section(rtwdev, info, section_info,
203 bin, &mssc_len);
204 if (ret)
205 return ret;
206
207 if (sec->secure_boot && chip->chip_id == RTL8852B)
208 section_info->len_override = 960;
209 } else {
210 section_info->mssc = 0;
211 mssc_len = 0;
212 }
213
214 rtw89_debug(rtwdev, RTW89_DBG_FW,
215 "section[%d] type=%d len=0x%-6x mssc=%d mssc_len=%d addr=%tx\n",
216 i, section_info->type, section_info->len,
217 section_info->mssc, mssc_len, bin - fw);
218 rtw89_debug(rtwdev, RTW89_DBG_FW,
219 " ignore=%d key_addr=%p (0x%tx) key_len=%d key_idx=%d\n",
220 section_info->ignore, section_info->key_addr,
221 section_info->key_addr ?
222 section_info->key_addr - section_info->addr : 0,
223 section_info->key_len, section_info->key_idx);
224
225 bin += section_info->len + mssc_len;
226 section_info++;
227 }
228
229 if (fw_end != bin) {
230 rtw89_err(rtwdev, "[ERR]fw bin size\n");
231 return -EINVAL;
232 }
233
234 return 0;
235 }
236
__get_mssc_key_idx(struct rtw89_dev * rtwdev,const struct rtw89_fw_mss_pool_hdr * mss_hdr,u32 rmp_tbl_size,u32 * key_idx)237 static int __get_mssc_key_idx(struct rtw89_dev *rtwdev,
238 const struct rtw89_fw_mss_pool_hdr *mss_hdr,
239 u32 rmp_tbl_size, u32 *key_idx)
240 {
241 struct rtw89_fw_secure *sec = &rtwdev->fw.sec;
242 u32 sel_byte_idx;
243 u32 mss_sel_idx;
244 u8 sel_bit_idx;
245 int i;
246
247 if (sec->mss_dev_type == RTW89_FW_MSS_DEV_TYPE_FWSEC_DEF) {
248 if (!mss_hdr->defen)
249 return -ENOENT;
250
251 mss_sel_idx = sec->mss_cust_idx * le16_to_cpu(mss_hdr->msskey_num_max) +
252 sec->mss_key_num;
253 } else {
254 if (mss_hdr->defen)
255 mss_sel_idx = FWDL_MSS_POOL_DEFKEYSETS_SIZE << 3;
256 else
257 mss_sel_idx = 0;
258 mss_sel_idx += sec->mss_dev_type * le16_to_cpu(mss_hdr->msskey_num_max) *
259 le16_to_cpu(mss_hdr->msscust_max) +
260 sec->mss_cust_idx * le16_to_cpu(mss_hdr->msskey_num_max) +
261 sec->mss_key_num;
262 }
263
264 sel_byte_idx = mss_sel_idx >> 3;
265 sel_bit_idx = mss_sel_idx & 0x7;
266
267 if (sel_byte_idx >= rmp_tbl_size)
268 return -EFAULT;
269
270 if (!(mss_hdr->rmp_tbl[sel_byte_idx] & BIT(sel_bit_idx)))
271 return -ENOENT;
272
273 *key_idx = hweight8(mss_hdr->rmp_tbl[sel_byte_idx] & (BIT(sel_bit_idx) - 1));
274
275 for (i = 0; i < sel_byte_idx; i++)
276 *key_idx += hweight8(mss_hdr->rmp_tbl[i]);
277
278 return 0;
279 }
280
__parse_formatted_mssc(struct rtw89_dev * rtwdev,struct rtw89_fw_bin_info * info,struct rtw89_fw_hdr_section_info * section_info,const void * content,u32 * mssc_len)281 static int __parse_formatted_mssc(struct rtw89_dev *rtwdev,
282 struct rtw89_fw_bin_info *info,
283 struct rtw89_fw_hdr_section_info *section_info,
284 #if defined(__linux__)
285 const void *content,
286 #elif defined(__FreeBSD__)
287 const u8 *content,
288 #endif
289 u32 *mssc_len)
290 {
291 #if defined(__linux__)
292 const struct rtw89_fw_mss_pool_hdr *mss_hdr = content + section_info->len;
293 const union rtw89_fw_section_mssc_content *section_content = content;
294 #elif defined(__FreeBSD__)
295 const struct rtw89_fw_mss_pool_hdr *mss_hdr = (const void *)(content + section_info->len);
296 const union rtw89_fw_section_mssc_content *section_content = (const void *)content;
297 #endif
298 struct rtw89_fw_secure *sec = &rtwdev->fw.sec;
299 u32 rmp_tbl_size;
300 u32 key_sign_len;
301 u32 real_key_idx;
302 u32 sb_sel_ver;
303 int ret;
304
305 if (memcmp(mss_signature, mss_hdr->signature, sizeof(mss_signature)) != 0) {
306 rtw89_err(rtwdev, "[ERR] wrong MSS signature\n");
307 return -ENOENT;
308 }
309
310 if (mss_hdr->rmpfmt == MSS_POOL_RMP_TBL_BITMASK) {
311 rmp_tbl_size = (le16_to_cpu(mss_hdr->msskey_num_max) *
312 le16_to_cpu(mss_hdr->msscust_max) *
313 mss_hdr->mssdev_max) >> 3;
314 if (mss_hdr->defen)
315 rmp_tbl_size += FWDL_MSS_POOL_DEFKEYSETS_SIZE;
316 } else {
317 rtw89_err(rtwdev, "[ERR] MSS Key Pool Remap Table Format Unsupport:%X\n",
318 mss_hdr->rmpfmt);
319 return -EINVAL;
320 }
321
322 if (rmp_tbl_size + sizeof(*mss_hdr) != le32_to_cpu(mss_hdr->key_raw_offset)) {
323 rtw89_err(rtwdev, "[ERR] MSS Key Pool Format Error:0x%X + 0x%X != 0x%X\n",
324 rmp_tbl_size, (int)sizeof(*mss_hdr),
325 le32_to_cpu(mss_hdr->key_raw_offset));
326 return -EINVAL;
327 }
328
329 key_sign_len = le16_to_cpu(section_content->key_sign_len.v) >> 2;
330 if (!key_sign_len)
331 key_sign_len = 512;
332
333 if (info->dsp_checksum)
334 key_sign_len += FWDL_SECURITY_CHKSUM_LEN;
335
336 *mssc_len = sizeof(*mss_hdr) + rmp_tbl_size +
337 le16_to_cpu(mss_hdr->keypair_num) * key_sign_len;
338
339 if (!sec->secure_boot)
340 goto out;
341
342 sb_sel_ver = get_unaligned_le32(§ion_content->sb_sel_ver.v);
343 if (sb_sel_ver && sb_sel_ver != sec->sb_sel_mgn)
344 goto ignore;
345
346 ret = __get_mssc_key_idx(rtwdev, mss_hdr, rmp_tbl_size, &real_key_idx);
347 if (ret)
348 goto ignore;
349
350 section_info->key_addr = content + section_info->len +
351 le32_to_cpu(mss_hdr->key_raw_offset) +
352 key_sign_len * real_key_idx;
353 section_info->key_len = key_sign_len;
354 section_info->key_idx = real_key_idx;
355
356 out:
357 if (info->secure_section_exist) {
358 section_info->ignore = true;
359 return 0;
360 }
361
362 info->secure_section_exist = true;
363
364 return 0;
365
366 ignore:
367 section_info->ignore = true;
368
369 return 0;
370 }
371
__check_secure_blacklist(struct rtw89_dev * rtwdev,struct rtw89_fw_bin_info * info,struct rtw89_fw_hdr_section_info * section_info,const void * content)372 static int __check_secure_blacklist(struct rtw89_dev *rtwdev,
373 struct rtw89_fw_bin_info *info,
374 struct rtw89_fw_hdr_section_info *section_info,
375 const void *content)
376 {
377 const struct rtw89_fw_blacklist *chip_blacklist = rtwdev->chip->fw_blacklist;
378 const union rtw89_fw_section_mssc_content *section_content = content;
379 struct rtw89_fw_secure *sec = &rtwdev->fw.sec;
380 u8 byte_idx;
381 u8 bit_mask;
382
383 if (!sec->secure_boot)
384 return 0;
385
386 if (!info->secure_section_exist || section_info->ignore)
387 return 0;
388
389 if (!chip_blacklist) {
390 rtw89_warn(rtwdev, "chip no blacklist for secure firmware\n");
391 return -ENOENT;
392 }
393
394 byte_idx = section_content->blacklist.bit_in_chip_list >> 3;
395 bit_mask = BIT(section_content->blacklist.bit_in_chip_list & 0x7);
396
397 if (section_content->blacklist.ver > chip_blacklist->ver) {
398 rtw89_warn(rtwdev, "chip blacklist out of date (%u, %u)\n",
399 section_content->blacklist.ver, chip_blacklist->ver);
400 return -EINVAL;
401 }
402
403 if (chip_blacklist->list[byte_idx] & bit_mask) {
404 rtw89_warn(rtwdev, "firmware %u in chip blacklist\n",
405 section_content->blacklist.ver);
406 return -EPERM;
407 }
408
409 return 0;
410 }
411
__parse_security_section(struct rtw89_dev * rtwdev,struct rtw89_fw_bin_info * info,struct rtw89_fw_hdr_section_info * section_info,const void * content,u32 * mssc_len)412 static int __parse_security_section(struct rtw89_dev *rtwdev,
413 struct rtw89_fw_bin_info *info,
414 struct rtw89_fw_hdr_section_info *section_info,
415 #if defined(__linux__)
416 const void *content,
417 #elif defined(__FreeBSD__)
418 const u8 *content,
419 #endif
420 u32 *mssc_len)
421 {
422 struct rtw89_fw_secure *sec = &rtwdev->fw.sec;
423 int ret;
424
425 if ((section_info->mssc & FORMATTED_MSSC_MASK) == FORMATTED_MSSC) {
426 ret = __parse_formatted_mssc(rtwdev, info, section_info,
427 content, mssc_len);
428 if (ret)
429 return -EINVAL;
430 } else {
431 *mssc_len = section_info->mssc * FWDL_SECURITY_SIGLEN;
432 if (info->dsp_checksum)
433 *mssc_len += section_info->mssc * FWDL_SECURITY_CHKSUM_LEN;
434
435 if (sec->secure_boot) {
436 if (sec->mss_idx >= section_info->mssc) {
437 rtw89_err(rtwdev, "unexpected MSS %d >= %d\n",
438 sec->mss_idx, section_info->mssc);
439 return -EFAULT;
440 }
441 section_info->key_addr = content + section_info->len +
442 sec->mss_idx * FWDL_SECURITY_SIGLEN;
443 section_info->key_len = FWDL_SECURITY_SIGLEN;
444 }
445
446 info->secure_section_exist = true;
447 }
448
449 ret = __check_secure_blacklist(rtwdev, info, section_info, content);
450 WARN_ONCE(ret, "Current firmware in blacklist. Please update firmware.\n");
451
452 return 0;
453 }
454
rtw89_fw_hdr_parser_v1(struct rtw89_dev * rtwdev,const u8 * fw,u32 len,struct rtw89_fw_bin_info * info)455 static int rtw89_fw_hdr_parser_v1(struct rtw89_dev *rtwdev, const u8 *fw, u32 len,
456 struct rtw89_fw_bin_info *info)
457 {
458 const struct rtw89_fw_hdr_v1 *fw_hdr = (const struct rtw89_fw_hdr_v1 *)fw;
459 struct rtw89_fw_hdr_section_info *section_info;
460 const struct rtw89_fw_dynhdr_hdr *fwdynhdr;
461 const struct rtw89_fw_hdr_section_v1 *section;
462 const u8 *fw_end = fw + len;
463 const u8 *bin;
464 u32 base_hdr_len;
465 u32 mssc_len;
466 int ret;
467 u32 i;
468
469 info->section_num = le32_get_bits(fw_hdr->w6, FW_HDR_V1_W6_SEC_NUM);
470 info->dsp_checksum = le32_get_bits(fw_hdr->w6, FW_HDR_V1_W6_DSP_CHKSUM);
471 base_hdr_len = struct_size(fw_hdr, sections, info->section_num);
472 info->dynamic_hdr_en = le32_get_bits(fw_hdr->w7, FW_HDR_V1_W7_DYN_HDR);
473 info->idmem_share_mode = le32_get_bits(fw_hdr->w7, FW_HDR_V1_W7_IDMEM_SHARE_MODE);
474
475 if (info->dynamic_hdr_en) {
476 info->hdr_len = le32_get_bits(fw_hdr->w5, FW_HDR_V1_W5_HDR_SIZE);
477 info->dynamic_hdr_len = info->hdr_len - base_hdr_len;
478 fwdynhdr = (const struct rtw89_fw_dynhdr_hdr *)(fw + base_hdr_len);
479 if (le32_to_cpu(fwdynhdr->hdr_len) != info->dynamic_hdr_len) {
480 rtw89_err(rtwdev, "[ERR]invalid fw dynamic header len\n");
481 return -EINVAL;
482 }
483 } else {
484 info->hdr_len = base_hdr_len;
485 info->dynamic_hdr_len = 0;
486 }
487
488 bin = fw + info->hdr_len;
489
490 /* jump to section header */
491 section_info = info->section_info;
492 for (i = 0; i < info->section_num; i++) {
493 section = &fw_hdr->sections[i];
494
495 section_info->type =
496 le32_get_bits(section->w1, FWSECTION_HDR_V1_W1_SECTIONTYPE);
497 section_info->len =
498 le32_get_bits(section->w1, FWSECTION_HDR_V1_W1_SEC_SIZE);
499 if (le32_get_bits(section->w1, FWSECTION_HDR_V1_W1_CHECKSUM))
500 section_info->len += FWDL_SECTION_CHKSUM_LEN;
501 section_info->redl = le32_get_bits(section->w1, FWSECTION_HDR_V1_W1_REDL);
502 section_info->dladdr =
503 le32_get_bits(section->w0, FWSECTION_HDR_V1_W0_DL_ADDR);
504 section_info->addr = bin;
505
506 if (section_info->type == FWDL_SECURITY_SECTION_TYPE) {
507 section_info->mssc =
508 le32_get_bits(section->w2, FWSECTION_HDR_V1_W2_MSSC);
509
510 ret = __parse_security_section(rtwdev, info, section_info,
511 bin, &mssc_len);
512 if (ret)
513 return ret;
514 } else {
515 section_info->mssc = 0;
516 mssc_len = 0;
517 }
518
519 rtw89_debug(rtwdev, RTW89_DBG_FW,
520 "section[%d] type=%d len=0x%-6x mssc=%d mssc_len=%d addr=%tx\n",
521 i, section_info->type, section_info->len,
522 section_info->mssc, mssc_len, bin - fw);
523 rtw89_debug(rtwdev, RTW89_DBG_FW,
524 " ignore=%d key_addr=%p (0x%tx) key_len=%d key_idx=%d\n",
525 section_info->ignore, section_info->key_addr,
526 section_info->key_addr ?
527 section_info->key_addr - section_info->addr : 0,
528 section_info->key_len, section_info->key_idx);
529
530 bin += section_info->len + mssc_len;
531 section_info++;
532 }
533
534 if (fw_end != bin) {
535 rtw89_err(rtwdev, "[ERR]fw bin size\n");
536 return -EINVAL;
537 }
538
539 if (!info->secure_section_exist)
540 rtw89_warn(rtwdev, "no firmware secure section\n");
541
542 return 0;
543 }
544
rtw89_fw_hdr_parser(struct rtw89_dev * rtwdev,const struct rtw89_fw_suit * fw_suit,struct rtw89_fw_bin_info * info)545 static int rtw89_fw_hdr_parser(struct rtw89_dev *rtwdev,
546 const struct rtw89_fw_suit *fw_suit,
547 struct rtw89_fw_bin_info *info)
548 {
549 const u8 *fw = fw_suit->data;
550 u32 len = fw_suit->size;
551
552 if (!fw || !len) {
553 rtw89_err(rtwdev, "fw type %d isn't recognized\n", fw_suit->type);
554 return -ENOENT;
555 }
556
557 switch (fw_suit->hdr_ver) {
558 case 0:
559 return rtw89_fw_hdr_parser_v0(rtwdev, fw, len, info);
560 case 1:
561 return rtw89_fw_hdr_parser_v1(rtwdev, fw, len, info);
562 default:
563 return -ENOENT;
564 }
565 }
566
567 static
rtw89_mfw_get_hdr_ptr(struct rtw89_dev * rtwdev,const struct firmware * firmware)568 const struct rtw89_mfw_hdr *rtw89_mfw_get_hdr_ptr(struct rtw89_dev *rtwdev,
569 const struct firmware *firmware)
570 {
571 const struct rtw89_mfw_hdr *mfw_hdr;
572
573 if (sizeof(*mfw_hdr) > firmware->size)
574 return NULL;
575
576 mfw_hdr = (const struct rtw89_mfw_hdr *)&firmware->data[0];
577
578 if (mfw_hdr->sig != RTW89_MFW_SIG)
579 return NULL;
580
581 return mfw_hdr;
582 }
583
rtw89_mfw_validate_hdr(struct rtw89_dev * rtwdev,const struct firmware * firmware,const struct rtw89_mfw_hdr * mfw_hdr)584 static int rtw89_mfw_validate_hdr(struct rtw89_dev *rtwdev,
585 const struct firmware *firmware,
586 const struct rtw89_mfw_hdr *mfw_hdr)
587 {
588 #if defined(__linux__)
589 const void *mfw = firmware->data;
590 #elif defined(__FreeBSD__)
591 const u8 *mfw = firmware->data;
592 #endif
593 u32 mfw_len = firmware->size;
594 u8 fw_nr = mfw_hdr->fw_nr;
595 const void *ptr;
596
597 if (fw_nr == 0) {
598 rtw89_err(rtwdev, "mfw header has no fw entry\n");
599 return -ENOENT;
600 }
601
602 ptr = &mfw_hdr->info[fw_nr];
603
604 #if defined(__linux__)
605 if (ptr > mfw + mfw_len) {
606 #elif defined(__FreeBSD__)
607 if ((const u8 *)ptr > mfw + mfw_len) {
608 #endif
609 rtw89_err(rtwdev, "mfw header out of address\n");
610 return -EFAULT;
611 }
612
613 return 0;
614 }
615
616 static
617 int rtw89_mfw_recognize(struct rtw89_dev *rtwdev, enum rtw89_fw_type type,
618 struct rtw89_fw_suit *fw_suit, bool nowarn)
619 {
620 struct rtw89_fw_info *fw_info = &rtwdev->fw;
621 const struct firmware *firmware = fw_info->req.firmware;
622 const struct rtw89_mfw_info *mfw_info = NULL, *tmp;
623 const struct rtw89_mfw_hdr *mfw_hdr;
624 const u8 *mfw = firmware->data;
625 u32 mfw_len = firmware->size;
626 int ret;
627 int i;
628
629 mfw_hdr = rtw89_mfw_get_hdr_ptr(rtwdev, firmware);
630 if (!mfw_hdr) {
631 rtw89_debug(rtwdev, RTW89_DBG_FW, "use legacy firmware\n");
632 /* legacy firmware support normal type only */
633 if (type != RTW89_FW_NORMAL)
634 return -EINVAL;
635 fw_suit->data = mfw;
636 fw_suit->size = mfw_len;
637 return 0;
638 }
639
640 ret = rtw89_mfw_validate_hdr(rtwdev, firmware, mfw_hdr);
641 if (ret)
642 return ret;
643
644 for (i = 0; i < mfw_hdr->fw_nr; i++) {
645 tmp = &mfw_hdr->info[i];
646 if (tmp->type != type)
647 continue;
648
649 if (type == RTW89_FW_LOGFMT) {
650 mfw_info = tmp;
651 goto found;
652 }
653
654 /* Version order of WiFi firmware in firmware file are not in order,
655 * pass all firmware to find the equal or less but closest version.
656 */
657 if (tmp->cv <= rtwdev->hal.cv && !tmp->mp) {
658 if (!mfw_info || mfw_info->cv < tmp->cv)
659 mfw_info = tmp;
660 }
661 }
662
663 if (mfw_info)
664 goto found;
665
666 if (!nowarn)
667 rtw89_err(rtwdev, "no suitable firmware found\n");
668 return -ENOENT;
669
670 found:
671 fw_suit->data = mfw + le32_to_cpu(mfw_info->shift);
672 fw_suit->size = le32_to_cpu(mfw_info->size);
673
674 if (fw_suit->data + fw_suit->size > mfw + mfw_len) {
675 rtw89_err(rtwdev, "fw_suit %d out of address\n", type);
676 return -EFAULT;
677 }
678
679 return 0;
680 }
681
682 static u32 rtw89_mfw_get_size(struct rtw89_dev *rtwdev)
683 {
684 struct rtw89_fw_info *fw_info = &rtwdev->fw;
685 const struct firmware *firmware = fw_info->req.firmware;
686 const struct rtw89_mfw_info *mfw_info;
687 const struct rtw89_mfw_hdr *mfw_hdr;
688 u32 size;
689 int ret;
690
691 mfw_hdr = rtw89_mfw_get_hdr_ptr(rtwdev, firmware);
692 if (!mfw_hdr) {
693 rtw89_warn(rtwdev, "not mfw format\n");
694 return 0;
695 }
696
697 ret = rtw89_mfw_validate_hdr(rtwdev, firmware, mfw_hdr);
698 if (ret)
699 return ret;
700
701 mfw_info = &mfw_hdr->info[mfw_hdr->fw_nr - 1];
702 size = le32_to_cpu(mfw_info->shift) + le32_to_cpu(mfw_info->size);
703
704 return size;
705 }
706
707 static void rtw89_fw_update_ver_v0(struct rtw89_dev *rtwdev,
708 struct rtw89_fw_suit *fw_suit,
709 const struct rtw89_fw_hdr *hdr)
710 {
711 fw_suit->major_ver = le32_get_bits(hdr->w1, FW_HDR_W1_MAJOR_VERSION);
712 fw_suit->minor_ver = le32_get_bits(hdr->w1, FW_HDR_W1_MINOR_VERSION);
713 fw_suit->sub_ver = le32_get_bits(hdr->w1, FW_HDR_W1_SUBVERSION);
714 fw_suit->sub_idex = le32_get_bits(hdr->w1, FW_HDR_W1_SUBINDEX);
715 fw_suit->commitid = le32_get_bits(hdr->w2, FW_HDR_W2_COMMITID);
716 fw_suit->build_year = le32_get_bits(hdr->w5, FW_HDR_W5_YEAR);
717 fw_suit->build_mon = le32_get_bits(hdr->w4, FW_HDR_W4_MONTH);
718 fw_suit->build_date = le32_get_bits(hdr->w4, FW_HDR_W4_DATE);
719 fw_suit->build_hour = le32_get_bits(hdr->w4, FW_HDR_W4_HOUR);
720 fw_suit->build_min = le32_get_bits(hdr->w4, FW_HDR_W4_MIN);
721 fw_suit->cmd_ver = le32_get_bits(hdr->w7, FW_HDR_W7_CMD_VERSERION);
722 }
723
724 static void rtw89_fw_update_ver_v1(struct rtw89_dev *rtwdev,
725 struct rtw89_fw_suit *fw_suit,
726 const struct rtw89_fw_hdr_v1 *hdr)
727 {
728 fw_suit->major_ver = le32_get_bits(hdr->w1, FW_HDR_V1_W1_MAJOR_VERSION);
729 fw_suit->minor_ver = le32_get_bits(hdr->w1, FW_HDR_V1_W1_MINOR_VERSION);
730 fw_suit->sub_ver = le32_get_bits(hdr->w1, FW_HDR_V1_W1_SUBVERSION);
731 fw_suit->sub_idex = le32_get_bits(hdr->w1, FW_HDR_V1_W1_SUBINDEX);
732 fw_suit->commitid = le32_get_bits(hdr->w2, FW_HDR_V1_W2_COMMITID);
733 fw_suit->build_year = le32_get_bits(hdr->w5, FW_HDR_V1_W5_YEAR);
734 fw_suit->build_mon = le32_get_bits(hdr->w4, FW_HDR_V1_W4_MONTH);
735 fw_suit->build_date = le32_get_bits(hdr->w4, FW_HDR_V1_W4_DATE);
736 fw_suit->build_hour = le32_get_bits(hdr->w4, FW_HDR_V1_W4_HOUR);
737 fw_suit->build_min = le32_get_bits(hdr->w4, FW_HDR_V1_W4_MIN);
738 fw_suit->cmd_ver = le32_get_bits(hdr->w7, FW_HDR_V1_W3_CMD_VERSERION);
739 }
740
741 static int rtw89_fw_update_ver(struct rtw89_dev *rtwdev,
742 enum rtw89_fw_type type,
743 struct rtw89_fw_suit *fw_suit)
744 {
745 const struct rtw89_fw_hdr *v0 = (const struct rtw89_fw_hdr *)fw_suit->data;
746 const struct rtw89_fw_hdr_v1 *v1 = (const struct rtw89_fw_hdr_v1 *)fw_suit->data;
747
748 if (type == RTW89_FW_LOGFMT)
749 return 0;
750
751 fw_suit->type = type;
752 fw_suit->hdr_ver = le32_get_bits(v0->w3, FW_HDR_W3_HDR_VER);
753
754 switch (fw_suit->hdr_ver) {
755 case 0:
756 rtw89_fw_update_ver_v0(rtwdev, fw_suit, v0);
757 break;
758 case 1:
759 rtw89_fw_update_ver_v1(rtwdev, fw_suit, v1);
760 break;
761 default:
762 rtw89_err(rtwdev, "Unknown firmware header version %u\n",
763 fw_suit->hdr_ver);
764 return -ENOENT;
765 }
766
767 rtw89_info(rtwdev,
768 "Firmware version %u.%u.%u.%u (%08x), cmd version %u, type %u\n",
769 fw_suit->major_ver, fw_suit->minor_ver, fw_suit->sub_ver,
770 fw_suit->sub_idex, fw_suit->commitid, fw_suit->cmd_ver, type);
771
772 return 0;
773 }
774
775 static
776 int __rtw89_fw_recognize(struct rtw89_dev *rtwdev, enum rtw89_fw_type type,
777 bool nowarn)
778 {
779 struct rtw89_fw_suit *fw_suit = rtw89_fw_suit_get(rtwdev, type);
780 int ret;
781
782 ret = rtw89_mfw_recognize(rtwdev, type, fw_suit, nowarn);
783 if (ret)
784 return ret;
785
786 return rtw89_fw_update_ver(rtwdev, type, fw_suit);
787 }
788
789 static
790 int __rtw89_fw_recognize_from_elm(struct rtw89_dev *rtwdev,
791 const struct rtw89_fw_element_hdr *elm,
792 const union rtw89_fw_element_arg arg)
793 {
794 #if defined(__linux__)
795 enum rtw89_fw_type type = arg.fw_type;
796 #elif defined(__FreeBSD__)
797 const enum rtw89_fw_type type = arg.fw_type;
798 #endif
799 struct rtw89_hal *hal = &rtwdev->hal;
800 struct rtw89_fw_suit *fw_suit;
801
802 /* Version of BB MCU is in decreasing order in firmware file, so take
803 * first equal or less version, which is equal or less but closest version.
804 */
805 if (hal->cv < elm->u.bbmcu.cv)
806 return 1; /* ignore this element */
807
808 fw_suit = rtw89_fw_suit_get(rtwdev, type);
809 if (fw_suit->data)
810 return 1; /* ignore this element (a firmware is taken already) */
811
812 fw_suit->data = elm->u.bbmcu.contents;
813 fw_suit->size = le32_to_cpu(elm->size);
814
815 return rtw89_fw_update_ver(rtwdev, type, fw_suit);
816 }
817
818 #define __DEF_FW_FEAT_COND(__cond, __op) \
819 static bool __fw_feat_cond_ ## __cond(u32 suit_ver_code, u32 comp_ver_code) \
820 { \
821 return suit_ver_code __op comp_ver_code; \
822 }
823
824 __DEF_FW_FEAT_COND(ge, >=); /* greater or equal */
825 __DEF_FW_FEAT_COND(le, <=); /* less or equal */
826 __DEF_FW_FEAT_COND(lt, <); /* less than */
827
828 struct __fw_feat_cfg {
829 enum rtw89_core_chip_id chip_id;
830 enum rtw89_fw_feature feature;
831 u32 ver_code;
832 bool (*cond)(u32 suit_ver_code, u32 comp_ver_code);
833 };
834
835 #define __CFG_FW_FEAT(_chip, _cond, _maj, _min, _sub, _idx, _feat) \
836 { \
837 .chip_id = _chip, \
838 .feature = RTW89_FW_FEATURE_ ## _feat, \
839 .ver_code = RTW89_FW_VER_CODE(_maj, _min, _sub, _idx), \
840 .cond = __fw_feat_cond_ ## _cond, \
841 }
842
843 static const struct __fw_feat_cfg fw_feat_tbl[] = {
844 __CFG_FW_FEAT(RTL8851B, ge, 0, 29, 37, 1, TX_WAKE),
845 __CFG_FW_FEAT(RTL8851B, ge, 0, 29, 37, 1, SCAN_OFFLOAD),
846 __CFG_FW_FEAT(RTL8851B, ge, 0, 29, 41, 0, CRASH_TRIGGER_TYPE_0),
847 __CFG_FW_FEAT(RTL8852A, le, 0, 13, 29, 0, OLD_HT_RA_FORMAT),
848 __CFG_FW_FEAT(RTL8852A, ge, 0, 13, 35, 0, SCAN_OFFLOAD),
849 __CFG_FW_FEAT(RTL8852A, ge, 0, 13, 35, 0, TX_WAKE),
850 __CFG_FW_FEAT(RTL8852A, ge, 0, 13, 36, 0, CRASH_TRIGGER_TYPE_0),
851 __CFG_FW_FEAT(RTL8852A, lt, 0, 13, 37, 0, NO_WOW_CPU_IO_RX),
852 __CFG_FW_FEAT(RTL8852A, lt, 0, 13, 38, 0, NO_PACKET_DROP),
853 __CFG_FW_FEAT(RTL8852B, ge, 0, 29, 26, 0, NO_LPS_PG),
854 __CFG_FW_FEAT(RTL8852B, ge, 0, 29, 26, 0, TX_WAKE),
855 __CFG_FW_FEAT(RTL8852B, ge, 0, 29, 29, 0, CRASH_TRIGGER_TYPE_0),
856 __CFG_FW_FEAT(RTL8852B, ge, 0, 29, 29, 0, SCAN_OFFLOAD),
857 __CFG_FW_FEAT(RTL8852B, ge, 0, 29, 29, 7, BEACON_FILTER),
858 __CFG_FW_FEAT(RTL8852B, lt, 0, 29, 30, 0, NO_WOW_CPU_IO_RX),
859 __CFG_FW_FEAT(RTL8852B, ge, 0, 29, 127, 0, LPS_DACK_BY_C2H_REG),
860 __CFG_FW_FEAT(RTL8852B, ge, 0, 29, 128, 0, CRASH_TRIGGER_TYPE_1),
861 __CFG_FW_FEAT(RTL8852B, ge, 0, 29, 128, 0, SCAN_OFFLOAD_EXTRA_OP),
862 __CFG_FW_FEAT(RTL8852BT, ge, 0, 29, 74, 0, NO_LPS_PG),
863 __CFG_FW_FEAT(RTL8852BT, ge, 0, 29, 74, 0, TX_WAKE),
864 __CFG_FW_FEAT(RTL8852BT, ge, 0, 29, 90, 0, CRASH_TRIGGER_TYPE_0),
865 __CFG_FW_FEAT(RTL8852BT, ge, 0, 29, 91, 0, SCAN_OFFLOAD),
866 __CFG_FW_FEAT(RTL8852BT, ge, 0, 29, 110, 0, BEACON_FILTER),
867 __CFG_FW_FEAT(RTL8852BT, ge, 0, 29, 127, 0, SCAN_OFFLOAD_EXTRA_OP),
868 __CFG_FW_FEAT(RTL8852BT, ge, 0, 29, 127, 0, LPS_DACK_BY_C2H_REG),
869 __CFG_FW_FEAT(RTL8852BT, ge, 0, 29, 127, 0, CRASH_TRIGGER_TYPE_1),
870 __CFG_FW_FEAT(RTL8852C, le, 0, 27, 33, 0, NO_DEEP_PS),
871 __CFG_FW_FEAT(RTL8852C, ge, 0, 0, 0, 0, RFK_NTFY_MCC_V0),
872 __CFG_FW_FEAT(RTL8852C, ge, 0, 27, 34, 0, TX_WAKE),
873 __CFG_FW_FEAT(RTL8852C, ge, 0, 27, 36, 0, SCAN_OFFLOAD),
874 __CFG_FW_FEAT(RTL8852C, ge, 0, 27, 40, 0, CRASH_TRIGGER_TYPE_0),
875 __CFG_FW_FEAT(RTL8852C, ge, 0, 27, 56, 10, BEACON_FILTER),
876 __CFG_FW_FEAT(RTL8852C, ge, 0, 27, 80, 0, WOW_REASON_V1),
877 __CFG_FW_FEAT(RTL8852C, ge, 0, 27, 128, 0, BEACON_LOSS_COUNT_V1),
878 __CFG_FW_FEAT(RTL8922A, ge, 0, 34, 30, 0, CRASH_TRIGGER_TYPE_0),
879 __CFG_FW_FEAT(RTL8922A, ge, 0, 34, 11, 0, MACID_PAUSE_SLEEP),
880 __CFG_FW_FEAT(RTL8922A, ge, 0, 34, 35, 0, SCAN_OFFLOAD),
881 __CFG_FW_FEAT(RTL8922A, lt, 0, 35, 21, 0, SCAN_OFFLOAD_BE_V0),
882 __CFG_FW_FEAT(RTL8922A, ge, 0, 35, 12, 0, BEACON_FILTER),
883 __CFG_FW_FEAT(RTL8922A, ge, 0, 35, 22, 0, WOW_REASON_V1),
884 __CFG_FW_FEAT(RTL8922A, lt, 0, 35, 28, 0, RFK_IQK_V0),
885 __CFG_FW_FEAT(RTL8922A, lt, 0, 35, 31, 0, RFK_PRE_NOTIFY_V0),
886 __CFG_FW_FEAT(RTL8922A, lt, 0, 35, 31, 0, LPS_CH_INFO),
887 __CFG_FW_FEAT(RTL8922A, lt, 0, 35, 42, 0, RFK_RXDCK_V0),
888 __CFG_FW_FEAT(RTL8922A, ge, 0, 35, 46, 0, NOTIFY_AP_INFO),
889 __CFG_FW_FEAT(RTL8922A, lt, 0, 35, 47, 0, CH_INFO_BE_V0),
890 __CFG_FW_FEAT(RTL8922A, lt, 0, 35, 49, 0, RFK_PRE_NOTIFY_V1),
891 __CFG_FW_FEAT(RTL8922A, lt, 0, 35, 51, 0, NO_PHYCAP_P1),
892 __CFG_FW_FEAT(RTL8922A, lt, 0, 35, 64, 0, NO_POWER_DIFFERENCE),
893 __CFG_FW_FEAT(RTL8922A, ge, 0, 35, 71, 0, BEACON_LOSS_COUNT_V1),
894 __CFG_FW_FEAT(RTL8922A, ge, 0, 35, 76, 0, LPS_DACK_BY_C2H_REG),
895 __CFG_FW_FEAT(RTL8922A, ge, 0, 35, 79, 0, CRASH_TRIGGER_TYPE_1),
896 };
897
898 static void rtw89_fw_iterate_feature_cfg(struct rtw89_fw_info *fw,
899 const struct rtw89_chip_info *chip,
900 u32 ver_code)
901 {
902 int i;
903
904 for (i = 0; i < ARRAY_SIZE(fw_feat_tbl); i++) {
905 const struct __fw_feat_cfg *ent = &fw_feat_tbl[i];
906
907 if (chip->chip_id != ent->chip_id)
908 continue;
909
910 if (ent->cond(ver_code, ent->ver_code))
911 RTW89_SET_FW_FEATURE(ent->feature, fw);
912 }
913 }
914
915 static void rtw89_fw_recognize_features(struct rtw89_dev *rtwdev)
916 {
917 const struct rtw89_chip_info *chip = rtwdev->chip;
918 const struct rtw89_fw_suit *fw_suit;
919 u32 suit_ver_code;
920
921 fw_suit = rtw89_fw_suit_get(rtwdev, RTW89_FW_NORMAL);
922 suit_ver_code = RTW89_FW_SUIT_VER_CODE(fw_suit);
923
924 rtw89_fw_iterate_feature_cfg(&rtwdev->fw, chip, suit_ver_code);
925 }
926
927 const struct firmware *
928 rtw89_early_fw_feature_recognize(struct device *device,
929 const struct rtw89_chip_info *chip,
930 struct rtw89_fw_info *early_fw,
931 int *used_fw_format)
932 {
933 const struct firmware *firmware;
934 char fw_name[64];
935 int fw_format;
936 u32 ver_code;
937 int ret;
938
939 for (fw_format = chip->fw_format_max; fw_format >= 0; fw_format--) {
940 rtw89_fw_get_filename(fw_name, sizeof(fw_name),
941 chip->fw_basename, fw_format);
942
943 ret = request_firmware(&firmware, fw_name, device);
944 if (!ret) {
945 dev_info(device, "loaded firmware %s\n", fw_name);
946 *used_fw_format = fw_format;
947 break;
948 }
949 }
950
951 if (ret) {
952 dev_err(device, "failed to early request firmware: %d\n", ret);
953 return NULL;
954 }
955
956 ver_code = rtw89_compat_fw_hdr_ver_code(firmware->data);
957
958 if (!ver_code)
959 goto out;
960
961 rtw89_fw_iterate_feature_cfg(early_fw, chip, ver_code);
962
963 out:
964 return firmware;
965 }
966
967 static int rtw89_fw_validate_ver_required(struct rtw89_dev *rtwdev)
968 {
969 const struct rtw89_chip_variant *variant = rtwdev->variant;
970 const struct rtw89_fw_suit *fw_suit;
971 u32 suit_ver_code;
972
973 if (!variant)
974 return 0;
975
976 fw_suit = rtw89_fw_suit_get(rtwdev, RTW89_FW_NORMAL);
977 suit_ver_code = RTW89_FW_SUIT_VER_CODE(fw_suit);
978
979 if (variant->fw_min_ver_code > suit_ver_code) {
980 rtw89_err(rtwdev, "minimum required firmware version is 0x%x\n",
981 variant->fw_min_ver_code);
982 return -ENOENT;
983 }
984
985 return 0;
986 }
987
988 int rtw89_fw_recognize(struct rtw89_dev *rtwdev)
989 {
990 const struct rtw89_chip_info *chip = rtwdev->chip;
991 int ret;
992
993 if (chip->try_ce_fw) {
994 ret = __rtw89_fw_recognize(rtwdev, RTW89_FW_NORMAL_CE, true);
995 if (!ret)
996 goto normal_done;
997 }
998
999 ret = __rtw89_fw_recognize(rtwdev, RTW89_FW_NORMAL, false);
1000 if (ret)
1001 return ret;
1002
1003 normal_done:
1004 ret = rtw89_fw_validate_ver_required(rtwdev);
1005 if (ret)
1006 return ret;
1007
1008 /* It still works if wowlan firmware isn't existing. */
1009 __rtw89_fw_recognize(rtwdev, RTW89_FW_WOWLAN, false);
1010
1011 /* It still works if log format file isn't existing. */
1012 __rtw89_fw_recognize(rtwdev, RTW89_FW_LOGFMT, true);
1013
1014 rtw89_fw_recognize_features(rtwdev);
1015
1016 rtw89_coex_recognize_ver(rtwdev);
1017
1018 return 0;
1019 }
1020
1021 static
1022 int rtw89_build_phy_tbl_from_elm(struct rtw89_dev *rtwdev,
1023 const struct rtw89_fw_element_hdr *elm,
1024 const union rtw89_fw_element_arg arg)
1025 {
1026 struct rtw89_fw_elm_info *elm_info = &rtwdev->fw.elm_info;
1027 struct rtw89_phy_table *tbl;
1028 struct rtw89_reg2_def *regs;
1029 enum rtw89_rf_path rf_path;
1030 u32 n_regs, i;
1031 u8 idx;
1032
1033 tbl = kzalloc(sizeof(*tbl), GFP_KERNEL);
1034 if (!tbl)
1035 return -ENOMEM;
1036
1037 switch (le32_to_cpu(elm->id)) {
1038 case RTW89_FW_ELEMENT_ID_BB_REG:
1039 elm_info->bb_tbl = tbl;
1040 break;
1041 case RTW89_FW_ELEMENT_ID_BB_GAIN:
1042 elm_info->bb_gain = tbl;
1043 break;
1044 case RTW89_FW_ELEMENT_ID_RADIO_A:
1045 case RTW89_FW_ELEMENT_ID_RADIO_B:
1046 case RTW89_FW_ELEMENT_ID_RADIO_C:
1047 case RTW89_FW_ELEMENT_ID_RADIO_D:
1048 rf_path = arg.rf_path;
1049 idx = elm->u.reg2.idx;
1050
1051 elm_info->rf_radio[idx] = tbl;
1052 tbl->rf_path = rf_path;
1053 tbl->config = rtw89_phy_config_rf_reg_v1;
1054 break;
1055 case RTW89_FW_ELEMENT_ID_RF_NCTL:
1056 elm_info->rf_nctl = tbl;
1057 break;
1058 default:
1059 kfree(tbl);
1060 return -ENOENT;
1061 }
1062
1063 n_regs = le32_to_cpu(elm->size) / sizeof(tbl->regs[0]);
1064 regs = kcalloc(n_regs, sizeof(*regs), GFP_KERNEL);
1065 if (!regs)
1066 goto out;
1067
1068 for (i = 0; i < n_regs; i++) {
1069 regs[i].addr = le32_to_cpu(elm->u.reg2.regs[i].addr);
1070 regs[i].data = le32_to_cpu(elm->u.reg2.regs[i].data);
1071 }
1072
1073 tbl->n_regs = n_regs;
1074 tbl->regs = regs;
1075
1076 return 0;
1077
1078 out:
1079 kfree(tbl);
1080 return -ENOMEM;
1081 }
1082
1083 static
1084 int rtw89_fw_recognize_txpwr_from_elm(struct rtw89_dev *rtwdev,
1085 const struct rtw89_fw_element_hdr *elm,
1086 const union rtw89_fw_element_arg arg)
1087 {
1088 const struct __rtw89_fw_txpwr_element *txpwr_elm = &elm->u.txpwr;
1089 const unsigned long offset = arg.offset;
1090 struct rtw89_efuse *efuse = &rtwdev->efuse;
1091 struct rtw89_txpwr_conf *conf;
1092
1093 if (!rtwdev->rfe_data) {
1094 rtwdev->rfe_data = kzalloc(sizeof(*rtwdev->rfe_data), GFP_KERNEL);
1095 if (!rtwdev->rfe_data)
1096 return -ENOMEM;
1097 }
1098
1099 #if defined(__linux__)
1100 conf = (void *)rtwdev->rfe_data + offset;
1101 #elif defined(__FreeBSD__)
1102 conf = (void *)((u8 *)rtwdev->rfe_data + offset);
1103 #endif
1104
1105 /* if multiple matched, take the last eventually */
1106 if (txpwr_elm->rfe_type == efuse->rfe_type)
1107 goto setup;
1108
1109 /* without one is matched, accept default */
1110 if (txpwr_elm->rfe_type == RTW89_TXPWR_CONF_DFLT_RFE_TYPE &&
1111 (!rtw89_txpwr_conf_valid(conf) ||
1112 conf->rfe_type == RTW89_TXPWR_CONF_DFLT_RFE_TYPE))
1113 goto setup;
1114
1115 rtw89_debug(rtwdev, RTW89_DBG_FW, "skip txpwr element ID %u RFE %u\n",
1116 elm->id, txpwr_elm->rfe_type);
1117 return 0;
1118
1119 setup:
1120 rtw89_debug(rtwdev, RTW89_DBG_FW, "take txpwr element ID %u RFE %u\n",
1121 elm->id, txpwr_elm->rfe_type);
1122
1123 conf->rfe_type = txpwr_elm->rfe_type;
1124 conf->ent_sz = txpwr_elm->ent_sz;
1125 conf->num_ents = le32_to_cpu(txpwr_elm->num_ents);
1126 conf->data = txpwr_elm->content;
1127 return 0;
1128 }
1129
1130 static
1131 int rtw89_build_txpwr_trk_tbl_from_elm(struct rtw89_dev *rtwdev,
1132 const struct rtw89_fw_element_hdr *elm,
1133 const union rtw89_fw_element_arg arg)
1134 {
1135 struct rtw89_fw_elm_info *elm_info = &rtwdev->fw.elm_info;
1136 const struct rtw89_chip_info *chip = rtwdev->chip;
1137 u32 needed_bitmap = 0;
1138 u32 offset = 0;
1139 int subband;
1140 u32 bitmap;
1141 int type;
1142
1143 if (chip->support_bands & BIT(NL80211_BAND_6GHZ))
1144 needed_bitmap |= RTW89_DEFAULT_NEEDED_FW_TXPWR_TRK_6GHZ;
1145 if (chip->support_bands & BIT(NL80211_BAND_5GHZ))
1146 needed_bitmap |= RTW89_DEFAULT_NEEDED_FW_TXPWR_TRK_5GHZ;
1147 if (chip->support_bands & BIT(NL80211_BAND_2GHZ))
1148 needed_bitmap |= RTW89_DEFAULT_NEEDED_FW_TXPWR_TRK_2GHZ;
1149
1150 bitmap = le32_to_cpu(elm->u.txpwr_trk.bitmap);
1151
1152 if ((bitmap & needed_bitmap) != needed_bitmap) {
1153 rtw89_warn(rtwdev, "needed txpwr trk bitmap %08x but %08x\n",
1154 needed_bitmap, bitmap);
1155 return -ENOENT;
1156 }
1157
1158 elm_info->txpwr_trk = kzalloc(sizeof(*elm_info->txpwr_trk), GFP_KERNEL);
1159 if (!elm_info->txpwr_trk)
1160 return -ENOMEM;
1161
1162 for (type = 0; bitmap; type++, bitmap >>= 1) {
1163 if (!(bitmap & BIT(0)))
1164 continue;
1165
1166 if (type >= __RTW89_FW_TXPWR_TRK_TYPE_6GHZ_START &&
1167 type <= __RTW89_FW_TXPWR_TRK_TYPE_6GHZ_MAX)
1168 subband = 4;
1169 else if (type >= __RTW89_FW_TXPWR_TRK_TYPE_5GHZ_START &&
1170 type <= __RTW89_FW_TXPWR_TRK_TYPE_5GHZ_MAX)
1171 subband = 3;
1172 else if (type >= __RTW89_FW_TXPWR_TRK_TYPE_2GHZ_START &&
1173 type <= __RTW89_FW_TXPWR_TRK_TYPE_2GHZ_MAX)
1174 subband = 1;
1175 else
1176 break;
1177
1178 elm_info->txpwr_trk->delta[type] = &elm->u.txpwr_trk.contents[offset];
1179
1180 offset += subband;
1181 if (offset * DELTA_SWINGIDX_SIZE > le32_to_cpu(elm->size))
1182 goto err;
1183 }
1184
1185 return 0;
1186
1187 err:
1188 rtw89_warn(rtwdev, "unexpected txpwr trk offset %d over size %d\n",
1189 offset, le32_to_cpu(elm->size));
1190 kfree(elm_info->txpwr_trk);
1191 elm_info->txpwr_trk = NULL;
1192
1193 return -EFAULT;
1194 }
1195
1196 static
1197 int rtw89_build_rfk_log_fmt_from_elm(struct rtw89_dev *rtwdev,
1198 const struct rtw89_fw_element_hdr *elm,
1199 const union rtw89_fw_element_arg arg)
1200 {
1201 struct rtw89_fw_elm_info *elm_info = &rtwdev->fw.elm_info;
1202 u8 rfk_id;
1203
1204 if (elm_info->rfk_log_fmt)
1205 goto allocated;
1206
1207 elm_info->rfk_log_fmt = kzalloc(sizeof(*elm_info->rfk_log_fmt), GFP_KERNEL);
1208 if (!elm_info->rfk_log_fmt)
1209 return 1; /* this is an optional element, so just ignore this */
1210
1211 allocated:
1212 rfk_id = elm->u.rfk_log_fmt.rfk_id;
1213 if (rfk_id >= RTW89_PHY_C2H_RFK_LOG_FUNC_NUM)
1214 return 1;
1215
1216 elm_info->rfk_log_fmt->elm[rfk_id] = elm;
1217
1218 return 0;
1219 }
1220
1221 static bool rtw89_regd_entcpy(struct rtw89_regd *regd, const void *cursor,
1222 u8 cursor_size)
1223 {
1224 /* fill default values if needed for backward compatibility */
1225 struct rtw89_fw_regd_entry entry = {
1226 .rule_2ghz = RTW89_NA,
1227 .rule_5ghz = RTW89_NA,
1228 .rule_6ghz = RTW89_NA,
1229 .fmap = cpu_to_le32(0x0),
1230 };
1231 u8 valid_size = min_t(u8, sizeof(entry), cursor_size);
1232 unsigned int i;
1233 u32 fmap;
1234
1235 memcpy(&entry, cursor, valid_size);
1236 memset(regd, 0, sizeof(*regd));
1237
1238 regd->alpha2[0] = entry.alpha2_0;
1239 regd->alpha2[1] = entry.alpha2_1;
1240 regd->alpha2[2] = '\0';
1241
1242 /* also need to consider forward compatibility */
1243 regd->txpwr_regd[RTW89_BAND_2G] = entry.rule_2ghz < RTW89_REGD_NUM ?
1244 entry.rule_2ghz : RTW89_NA;
1245 regd->txpwr_regd[RTW89_BAND_5G] = entry.rule_5ghz < RTW89_REGD_NUM ?
1246 entry.rule_5ghz : RTW89_NA;
1247 regd->txpwr_regd[RTW89_BAND_6G] = entry.rule_6ghz < RTW89_REGD_NUM ?
1248 entry.rule_6ghz : RTW89_NA;
1249
1250 BUILD_BUG_ON(sizeof(fmap) != sizeof(entry.fmap));
1251 BUILD_BUG_ON(sizeof(fmap) * 8 < NUM_OF_RTW89_REGD_FUNC);
1252
1253 fmap = le32_to_cpu(entry.fmap);
1254 for (i = 0; i < NUM_OF_RTW89_REGD_FUNC; i++) {
1255 if (fmap & BIT(i))
1256 set_bit(i, regd->func_bitmap);
1257 }
1258
1259 return true;
1260 }
1261
1262 #if defined(__linux__)
1263 #define rtw89_for_each_in_regd_element(regd, element) \
1264 for (const void *cursor = (element)->content, \
1265 *end = (element)->content + \
1266 le32_to_cpu((element)->num_ents) * (element)->ent_sz; \
1267 cursor < end; cursor += (element)->ent_sz) \
1268 if (rtw89_regd_entcpy(regd, cursor, (element)->ent_sz))
1269 #elif defined(__FreeBSD__)
1270 #define rtw89_for_each_in_regd_element(regd, element) \
1271 for (const u8 *cursor = (element)->content, \
1272 *end = (element)->content + \
1273 le32_to_cpu((element)->num_ents) * (element)->ent_sz; \
1274 cursor < end; cursor += (element)->ent_sz) \
1275 if (rtw89_regd_entcpy(regd, cursor, (element)->ent_sz))
1276 #endif
1277
1278 static
1279 int rtw89_recognize_regd_from_elm(struct rtw89_dev *rtwdev,
1280 const struct rtw89_fw_element_hdr *elm,
1281 const union rtw89_fw_element_arg arg)
1282 {
1283 const struct __rtw89_fw_regd_element *regd_elm = &elm->u.regd;
1284 struct rtw89_fw_elm_info *elm_info = &rtwdev->fw.elm_info;
1285 u32 num_ents = le32_to_cpu(regd_elm->num_ents);
1286 struct rtw89_regd_data *p;
1287 struct rtw89_regd regd;
1288 u32 i = 0;
1289
1290 if (num_ents > RTW89_REGD_MAX_COUNTRY_NUM) {
1291 rtw89_warn(rtwdev,
1292 "regd element ents (%d) are over max num (%d)\n",
1293 num_ents, RTW89_REGD_MAX_COUNTRY_NUM);
1294 rtw89_warn(rtwdev,
1295 "regd element ignore and take another/common\n");
1296 return 1;
1297 }
1298
1299 if (elm_info->regd) {
1300 rtw89_debug(rtwdev, RTW89_DBG_REGD,
1301 "regd element take the latter\n");
1302 devm_kfree(rtwdev->dev, elm_info->regd);
1303 elm_info->regd = NULL;
1304 }
1305
1306 p = devm_kzalloc(rtwdev->dev, struct_size(p, map, num_ents), GFP_KERNEL);
1307 if (!p)
1308 return -ENOMEM;
1309
1310 p->nr = num_ents;
1311 rtw89_for_each_in_regd_element(®d, regd_elm)
1312 p->map[i++] = regd;
1313
1314 if (i != num_ents) {
1315 rtw89_err(rtwdev, "regd element has %d invalid ents\n",
1316 num_ents - i);
1317 devm_kfree(rtwdev->dev, p);
1318 return -EINVAL;
1319 }
1320
1321 elm_info->regd = p;
1322 return 0;
1323 }
1324
1325 static const struct rtw89_fw_element_handler __fw_element_handlers[] = {
1326 [RTW89_FW_ELEMENT_ID_BBMCU0] = {__rtw89_fw_recognize_from_elm,
1327 { .fw_type = RTW89_FW_BBMCU0 }, NULL},
1328 [RTW89_FW_ELEMENT_ID_BBMCU1] = {__rtw89_fw_recognize_from_elm,
1329 { .fw_type = RTW89_FW_BBMCU1 }, NULL},
1330 [RTW89_FW_ELEMENT_ID_BB_REG] = {rtw89_build_phy_tbl_from_elm, {}, "BB"},
1331 [RTW89_FW_ELEMENT_ID_BB_GAIN] = {rtw89_build_phy_tbl_from_elm, {}, NULL},
1332 [RTW89_FW_ELEMENT_ID_RADIO_A] = {rtw89_build_phy_tbl_from_elm,
1333 { .rf_path = RF_PATH_A }, "radio A"},
1334 [RTW89_FW_ELEMENT_ID_RADIO_B] = {rtw89_build_phy_tbl_from_elm,
1335 { .rf_path = RF_PATH_B }, NULL},
1336 [RTW89_FW_ELEMENT_ID_RADIO_C] = {rtw89_build_phy_tbl_from_elm,
1337 { .rf_path = RF_PATH_C }, NULL},
1338 [RTW89_FW_ELEMENT_ID_RADIO_D] = {rtw89_build_phy_tbl_from_elm,
1339 { .rf_path = RF_PATH_D }, NULL},
1340 [RTW89_FW_ELEMENT_ID_RF_NCTL] = {rtw89_build_phy_tbl_from_elm, {}, "NCTL"},
1341 [RTW89_FW_ELEMENT_ID_TXPWR_BYRATE] = {
1342 rtw89_fw_recognize_txpwr_from_elm,
1343 { .offset = offsetof(struct rtw89_rfe_data, byrate.conf) }, "TXPWR",
1344 },
1345 [RTW89_FW_ELEMENT_ID_TXPWR_LMT_2GHZ] = {
1346 rtw89_fw_recognize_txpwr_from_elm,
1347 { .offset = offsetof(struct rtw89_rfe_data, lmt_2ghz.conf) }, NULL,
1348 },
1349 [RTW89_FW_ELEMENT_ID_TXPWR_LMT_5GHZ] = {
1350 rtw89_fw_recognize_txpwr_from_elm,
1351 { .offset = offsetof(struct rtw89_rfe_data, lmt_5ghz.conf) }, NULL,
1352 },
1353 [RTW89_FW_ELEMENT_ID_TXPWR_LMT_6GHZ] = {
1354 rtw89_fw_recognize_txpwr_from_elm,
1355 { .offset = offsetof(struct rtw89_rfe_data, lmt_6ghz.conf) }, NULL,
1356 },
1357 [RTW89_FW_ELEMENT_ID_TXPWR_DA_LMT_2GHZ] = {
1358 rtw89_fw_recognize_txpwr_from_elm,
1359 { .offset = offsetof(struct rtw89_rfe_data, da_lmt_2ghz.conf) }, NULL,
1360 },
1361 [RTW89_FW_ELEMENT_ID_TXPWR_DA_LMT_5GHZ] = {
1362 rtw89_fw_recognize_txpwr_from_elm,
1363 { .offset = offsetof(struct rtw89_rfe_data, da_lmt_5ghz.conf) }, NULL,
1364 },
1365 [RTW89_FW_ELEMENT_ID_TXPWR_DA_LMT_6GHZ] = {
1366 rtw89_fw_recognize_txpwr_from_elm,
1367 { .offset = offsetof(struct rtw89_rfe_data, da_lmt_6ghz.conf) }, NULL,
1368 },
1369 [RTW89_FW_ELEMENT_ID_TXPWR_LMT_RU_2GHZ] = {
1370 rtw89_fw_recognize_txpwr_from_elm,
1371 { .offset = offsetof(struct rtw89_rfe_data, lmt_ru_2ghz.conf) }, NULL,
1372 },
1373 [RTW89_FW_ELEMENT_ID_TXPWR_LMT_RU_5GHZ] = {
1374 rtw89_fw_recognize_txpwr_from_elm,
1375 { .offset = offsetof(struct rtw89_rfe_data, lmt_ru_5ghz.conf) }, NULL,
1376 },
1377 [RTW89_FW_ELEMENT_ID_TXPWR_LMT_RU_6GHZ] = {
1378 rtw89_fw_recognize_txpwr_from_elm,
1379 { .offset = offsetof(struct rtw89_rfe_data, lmt_ru_6ghz.conf) }, NULL,
1380 },
1381 [RTW89_FW_ELEMENT_ID_TXPWR_DA_LMT_RU_2GHZ] = {
1382 rtw89_fw_recognize_txpwr_from_elm,
1383 { .offset = offsetof(struct rtw89_rfe_data, da_lmt_ru_2ghz.conf) }, NULL,
1384 },
1385 [RTW89_FW_ELEMENT_ID_TXPWR_DA_LMT_RU_5GHZ] = {
1386 rtw89_fw_recognize_txpwr_from_elm,
1387 { .offset = offsetof(struct rtw89_rfe_data, da_lmt_ru_5ghz.conf) }, NULL,
1388 },
1389 [RTW89_FW_ELEMENT_ID_TXPWR_DA_LMT_RU_6GHZ] = {
1390 rtw89_fw_recognize_txpwr_from_elm,
1391 { .offset = offsetof(struct rtw89_rfe_data, da_lmt_ru_6ghz.conf) }, NULL,
1392 },
1393 [RTW89_FW_ELEMENT_ID_TX_SHAPE_LMT] = {
1394 rtw89_fw_recognize_txpwr_from_elm,
1395 { .offset = offsetof(struct rtw89_rfe_data, tx_shape_lmt.conf) }, NULL,
1396 },
1397 [RTW89_FW_ELEMENT_ID_TX_SHAPE_LMT_RU] = {
1398 rtw89_fw_recognize_txpwr_from_elm,
1399 { .offset = offsetof(struct rtw89_rfe_data, tx_shape_lmt_ru.conf) }, NULL,
1400 },
1401 [RTW89_FW_ELEMENT_ID_TXPWR_TRK] = {
1402 rtw89_build_txpwr_trk_tbl_from_elm, {}, "PWR_TRK",
1403 },
1404 [RTW89_FW_ELEMENT_ID_RFKLOG_FMT] = {
1405 rtw89_build_rfk_log_fmt_from_elm, {}, NULL,
1406 },
1407 [RTW89_FW_ELEMENT_ID_REGD] = {
1408 rtw89_recognize_regd_from_elm, {}, "REGD",
1409 },
1410 };
1411
1412 int rtw89_fw_recognize_elements(struct rtw89_dev *rtwdev)
1413 {
1414 struct rtw89_fw_info *fw_info = &rtwdev->fw;
1415 const struct firmware *firmware = fw_info->req.firmware;
1416 const struct rtw89_chip_info *chip = rtwdev->chip;
1417 u32 unrecognized_elements = chip->needed_fw_elms;
1418 const struct rtw89_fw_element_handler *handler;
1419 const struct rtw89_fw_element_hdr *hdr;
1420 u32 elm_size;
1421 u32 elem_id;
1422 u32 offset;
1423 int ret;
1424
1425 BUILD_BUG_ON(sizeof(chip->needed_fw_elms) * 8 < RTW89_FW_ELEMENT_ID_NUM);
1426
1427 offset = rtw89_mfw_get_size(rtwdev);
1428 offset = ALIGN(offset, RTW89_FW_ELEMENT_ALIGN);
1429 if (offset == 0)
1430 return -EINVAL;
1431
1432 while (offset + sizeof(*hdr) < firmware->size) {
1433 hdr = (const struct rtw89_fw_element_hdr *)(firmware->data + offset);
1434
1435 elm_size = le32_to_cpu(hdr->size);
1436 if (offset + elm_size >= firmware->size) {
1437 rtw89_warn(rtwdev, "firmware element size exceeds\n");
1438 break;
1439 }
1440
1441 elem_id = le32_to_cpu(hdr->id);
1442 if (elem_id >= ARRAY_SIZE(__fw_element_handlers))
1443 goto next;
1444
1445 handler = &__fw_element_handlers[elem_id];
1446 if (!handler->fn)
1447 goto next;
1448
1449 ret = handler->fn(rtwdev, hdr, handler->arg);
1450 if (ret == 1) /* ignore this element */
1451 goto next;
1452 if (ret)
1453 return ret;
1454
1455 if (handler->name)
1456 rtw89_info(rtwdev, "Firmware element %s version: %4ph\n",
1457 handler->name, hdr->ver);
1458
1459 unrecognized_elements &= ~BIT(elem_id);
1460 next:
1461 offset += sizeof(*hdr) + elm_size;
1462 offset = ALIGN(offset, RTW89_FW_ELEMENT_ALIGN);
1463 }
1464
1465 if (unrecognized_elements) {
1466 rtw89_err(rtwdev, "Firmware elements 0x%08x are unrecognized\n",
1467 unrecognized_elements);
1468 return -ENOENT;
1469 }
1470
1471 return 0;
1472 }
1473
1474 void rtw89_h2c_pkt_set_hdr(struct rtw89_dev *rtwdev, struct sk_buff *skb,
1475 u8 type, u8 cat, u8 class, u8 func,
1476 bool rack, bool dack, u32 len)
1477 {
1478 struct fwcmd_hdr *hdr;
1479
1480 hdr = (struct fwcmd_hdr *)skb_push(skb, 8);
1481
1482 if (!(rtwdev->fw.h2c_seq % 4))
1483 rack = true;
1484 hdr->hdr0 = cpu_to_le32(FIELD_PREP(H2C_HDR_DEL_TYPE, type) |
1485 FIELD_PREP(H2C_HDR_CAT, cat) |
1486 FIELD_PREP(H2C_HDR_CLASS, class) |
1487 FIELD_PREP(H2C_HDR_FUNC, func) |
1488 FIELD_PREP(H2C_HDR_H2C_SEQ, rtwdev->fw.h2c_seq));
1489
1490 hdr->hdr1 = cpu_to_le32(FIELD_PREP(H2C_HDR_TOTAL_LEN,
1491 len + H2C_HEADER_LEN) |
1492 (rack ? H2C_HDR_REC_ACK : 0) |
1493 (dack ? H2C_HDR_DONE_ACK : 0));
1494
1495 rtwdev->fw.h2c_seq++;
1496 }
1497
1498 static void rtw89_h2c_pkt_set_hdr_fwdl(struct rtw89_dev *rtwdev,
1499 struct sk_buff *skb,
1500 u8 type, u8 cat, u8 class, u8 func,
1501 u32 len)
1502 {
1503 struct fwcmd_hdr *hdr;
1504
1505 hdr = (struct fwcmd_hdr *)skb_push(skb, 8);
1506
1507 hdr->hdr0 = cpu_to_le32(FIELD_PREP(H2C_HDR_DEL_TYPE, type) |
1508 FIELD_PREP(H2C_HDR_CAT, cat) |
1509 FIELD_PREP(H2C_HDR_CLASS, class) |
1510 FIELD_PREP(H2C_HDR_FUNC, func) |
1511 FIELD_PREP(H2C_HDR_H2C_SEQ, rtwdev->fw.h2c_seq));
1512
1513 hdr->hdr1 = cpu_to_le32(FIELD_PREP(H2C_HDR_TOTAL_LEN,
1514 len + H2C_HEADER_LEN));
1515 }
1516
1517 static u32 __rtw89_fw_download_tweak_hdr_v0(struct rtw89_dev *rtwdev,
1518 struct rtw89_fw_bin_info *info,
1519 struct rtw89_fw_hdr *fw_hdr)
1520 {
1521 struct rtw89_fw_hdr_section_info *section_info;
1522 struct rtw89_fw_hdr_section *section;
1523 int i;
1524
1525 le32p_replace_bits(&fw_hdr->w7, FWDL_SECTION_PER_PKT_LEN,
1526 FW_HDR_W7_PART_SIZE);
1527
1528 for (i = 0; i < info->section_num; i++) {
1529 section_info = &info->section_info[i];
1530
1531 if (!section_info->len_override)
1532 continue;
1533
1534 section = &fw_hdr->sections[i];
1535 le32p_replace_bits(§ion->w1, section_info->len_override,
1536 FWSECTION_HDR_W1_SEC_SIZE);
1537 }
1538
1539 return 0;
1540 }
1541
1542 static u32 __rtw89_fw_download_tweak_hdr_v1(struct rtw89_dev *rtwdev,
1543 struct rtw89_fw_bin_info *info,
1544 struct rtw89_fw_hdr_v1 *fw_hdr)
1545 {
1546 struct rtw89_fw_hdr_section_info *section_info;
1547 struct rtw89_fw_hdr_section_v1 *section;
1548 u8 dst_sec_idx = 0;
1549 u8 sec_idx;
1550
1551 le32p_replace_bits(&fw_hdr->w7, FWDL_SECTION_PER_PKT_LEN,
1552 FW_HDR_V1_W7_PART_SIZE);
1553
1554 for (sec_idx = 0; sec_idx < info->section_num; sec_idx++) {
1555 section_info = &info->section_info[sec_idx];
1556 section = &fw_hdr->sections[sec_idx];
1557
1558 if (section_info->ignore)
1559 continue;
1560
1561 if (dst_sec_idx != sec_idx)
1562 fw_hdr->sections[dst_sec_idx] = *section;
1563
1564 dst_sec_idx++;
1565 }
1566
1567 le32p_replace_bits(&fw_hdr->w6, dst_sec_idx, FW_HDR_V1_W6_SEC_NUM);
1568
1569 return (info->section_num - dst_sec_idx) * sizeof(*section);
1570 }
1571
1572 static int __rtw89_fw_download_hdr(struct rtw89_dev *rtwdev,
1573 const struct rtw89_fw_suit *fw_suit,
1574 struct rtw89_fw_bin_info *info)
1575 {
1576 u32 len = info->hdr_len - info->dynamic_hdr_len;
1577 struct rtw89_fw_hdr_v1 *fw_hdr_v1;
1578 const u8 *fw = fw_suit->data;
1579 struct rtw89_fw_hdr *fw_hdr;
1580 struct sk_buff *skb;
1581 u32 truncated;
1582 u32 ret = 0;
1583
1584 skb = rtw89_fw_h2c_alloc_skb_with_hdr(rtwdev, len);
1585 if (!skb) {
1586 rtw89_err(rtwdev, "failed to alloc skb for fw hdr dl\n");
1587 return -ENOMEM;
1588 }
1589
1590 skb_put_data(skb, fw, len);
1591
1592 switch (fw_suit->hdr_ver) {
1593 case 0:
1594 fw_hdr = (struct rtw89_fw_hdr *)skb->data;
1595 truncated = __rtw89_fw_download_tweak_hdr_v0(rtwdev, info, fw_hdr);
1596 break;
1597 case 1:
1598 fw_hdr_v1 = (struct rtw89_fw_hdr_v1 *)skb->data;
1599 truncated = __rtw89_fw_download_tweak_hdr_v1(rtwdev, info, fw_hdr_v1);
1600 break;
1601 default:
1602 ret = -EOPNOTSUPP;
1603 goto fail;
1604 }
1605
1606 if (truncated) {
1607 len -= truncated;
1608 skb_trim(skb, len);
1609 }
1610
1611 rtw89_h2c_pkt_set_hdr_fwdl(rtwdev, skb, FWCMD_TYPE_H2C,
1612 H2C_CAT_MAC, H2C_CL_MAC_FWDL,
1613 H2C_FUNC_MAC_FWHDR_DL, len);
1614
1615 ret = rtw89_h2c_tx(rtwdev, skb, false);
1616 if (ret) {
1617 rtw89_err(rtwdev, "failed to send h2c\n");
1618 goto fail;
1619 }
1620
1621 return 0;
1622 fail:
1623 dev_kfree_skb_any(skb);
1624
1625 return ret;
1626 }
1627
1628 static int rtw89_fw_download_hdr(struct rtw89_dev *rtwdev,
1629 const struct rtw89_fw_suit *fw_suit,
1630 struct rtw89_fw_bin_info *info)
1631 {
1632 const struct rtw89_mac_gen_def *mac = rtwdev->chip->mac_def;
1633 int ret;
1634
1635 ret = __rtw89_fw_download_hdr(rtwdev, fw_suit, info);
1636 if (ret) {
1637 rtw89_err(rtwdev, "[ERR]FW header download\n");
1638 return ret;
1639 }
1640
1641 ret = mac->fwdl_check_path_ready(rtwdev, false);
1642 if (ret) {
1643 rtw89_err(rtwdev, "[ERR]FWDL path ready\n");
1644 return ret;
1645 }
1646
1647 rtw89_write32(rtwdev, R_AX_HALT_H2C_CTRL, 0);
1648 rtw89_write32(rtwdev, R_AX_HALT_C2H_CTRL, 0);
1649
1650 return 0;
1651 }
1652
1653 static int __rtw89_fw_download_main(struct rtw89_dev *rtwdev,
1654 struct rtw89_fw_hdr_section_info *info)
1655 {
1656 struct sk_buff *skb;
1657 const u8 *section = info->addr;
1658 u32 residue_len = info->len;
1659 bool copy_key = false;
1660 u32 pkt_len;
1661 int ret;
1662
1663 if (info->ignore)
1664 return 0;
1665
1666 if (info->len_override) {
1667 if (info->len_override > info->len)
1668 rtw89_warn(rtwdev, "override length %u larger than original %u\n",
1669 info->len_override, info->len);
1670 else
1671 residue_len = info->len_override;
1672 }
1673
1674 if (info->key_addr && info->key_len) {
1675 if (residue_len > FWDL_SECTION_PER_PKT_LEN || info->len < info->key_len)
1676 rtw89_warn(rtwdev,
1677 "ignore to copy key data because of len %d, %d, %d, %d\n",
1678 info->len, FWDL_SECTION_PER_PKT_LEN,
1679 info->key_len, residue_len);
1680 else
1681 copy_key = true;
1682 }
1683
1684 while (residue_len) {
1685 if (residue_len >= FWDL_SECTION_PER_PKT_LEN)
1686 pkt_len = FWDL_SECTION_PER_PKT_LEN;
1687 else
1688 pkt_len = residue_len;
1689
1690 skb = rtw89_fw_h2c_alloc_skb_no_hdr(rtwdev, pkt_len);
1691 if (!skb) {
1692 rtw89_err(rtwdev, "failed to alloc skb for fw dl\n");
1693 return -ENOMEM;
1694 }
1695 skb_put_data(skb, section, pkt_len);
1696
1697 if (copy_key)
1698 memcpy(skb->data + pkt_len - info->key_len,
1699 info->key_addr, info->key_len);
1700
1701 ret = rtw89_h2c_tx(rtwdev, skb, true);
1702 if (ret) {
1703 rtw89_err(rtwdev, "failed to send h2c\n");
1704 goto fail;
1705 }
1706
1707 section += pkt_len;
1708 residue_len -= pkt_len;
1709 }
1710
1711 return 0;
1712 fail:
1713 dev_kfree_skb_any(skb);
1714
1715 return ret;
1716 }
1717
1718 static enum rtw89_fwdl_check_type
1719 rtw89_fw_get_fwdl_chk_type_from_suit(struct rtw89_dev *rtwdev,
1720 const struct rtw89_fw_suit *fw_suit)
1721 {
1722 switch (fw_suit->type) {
1723 case RTW89_FW_BBMCU0:
1724 return RTW89_FWDL_CHECK_BB0_FWDL_DONE;
1725 case RTW89_FW_BBMCU1:
1726 return RTW89_FWDL_CHECK_BB1_FWDL_DONE;
1727 default:
1728 return RTW89_FWDL_CHECK_WCPU_FWDL_DONE;
1729 }
1730 }
1731
1732 static int rtw89_fw_download_main(struct rtw89_dev *rtwdev,
1733 const struct rtw89_fw_suit *fw_suit,
1734 struct rtw89_fw_bin_info *info)
1735 {
1736 struct rtw89_fw_hdr_section_info *section_info = info->section_info;
1737 const struct rtw89_chip_info *chip = rtwdev->chip;
1738 enum rtw89_fwdl_check_type chk_type;
1739 u8 section_num = info->section_num;
1740 int ret;
1741
1742 while (section_num--) {
1743 ret = __rtw89_fw_download_main(rtwdev, section_info);
1744 if (ret)
1745 return ret;
1746 section_info++;
1747 }
1748
1749 if (chip->chip_gen == RTW89_CHIP_AX)
1750 return 0;
1751
1752 chk_type = rtw89_fw_get_fwdl_chk_type_from_suit(rtwdev, fw_suit);
1753 ret = rtw89_fw_check_rdy(rtwdev, chk_type);
1754 if (ret) {
1755 rtw89_warn(rtwdev, "failed to download firmware type %u\n",
1756 fw_suit->type);
1757 return ret;
1758 }
1759
1760 return 0;
1761 }
1762
1763 static void rtw89_fw_prog_cnt_dump(struct rtw89_dev *rtwdev)
1764 {
1765 enum rtw89_chip_gen chip_gen = rtwdev->chip->chip_gen;
1766 u32 addr = R_AX_DBG_PORT_SEL;
1767 u32 val32;
1768 u16 index;
1769
1770 if (chip_gen == RTW89_CHIP_BE) {
1771 addr = R_BE_WLCPU_PORT_PC;
1772 goto dump;
1773 }
1774
1775 rtw89_write32(rtwdev, R_AX_DBG_CTRL,
1776 FIELD_PREP(B_AX_DBG_SEL0, FW_PROG_CNTR_DBG_SEL) |
1777 FIELD_PREP(B_AX_DBG_SEL1, FW_PROG_CNTR_DBG_SEL));
1778 rtw89_write32_mask(rtwdev, R_AX_SYS_STATUS1, B_AX_SEL_0XC0_MASK, MAC_DBG_SEL);
1779
1780 dump:
1781 for (index = 0; index < 15; index++) {
1782 val32 = rtw89_read32(rtwdev, addr);
1783 rtw89_err(rtwdev, "[ERR]fw PC = 0x%x\n", val32);
1784 #if defined(__linux__)
1785 fsleep(10);
1786 #elif defined(__FreeBSD__)
1787 /* Seems we are called from a context we cannot sleep. */
1788 udelay(10);
1789 #endif
1790 }
1791 }
1792
1793 static void rtw89_fw_dl_fail_dump(struct rtw89_dev *rtwdev)
1794 {
1795 u32 val32;
1796
1797 val32 = rtw89_read32(rtwdev, R_AX_WCPU_FW_CTRL);
1798 rtw89_err(rtwdev, "[ERR]fwdl 0x1E0 = 0x%x\n", val32);
1799
1800 val32 = rtw89_read32(rtwdev, R_AX_BOOT_DBG);
1801 rtw89_err(rtwdev, "[ERR]fwdl 0x83F0 = 0x%x\n", val32);
1802
1803 rtw89_fw_prog_cnt_dump(rtwdev);
1804 }
1805
1806 static int rtw89_fw_download_suit(struct rtw89_dev *rtwdev,
1807 struct rtw89_fw_suit *fw_suit)
1808 {
1809 const struct rtw89_mac_gen_def *mac = rtwdev->chip->mac_def;
1810 struct rtw89_fw_bin_info info = {};
1811 int ret;
1812
1813 ret = rtw89_fw_hdr_parser(rtwdev, fw_suit, &info);
1814 if (ret) {
1815 rtw89_err(rtwdev, "parse fw header fail\n");
1816 return ret;
1817 }
1818
1819 rtw89_fwdl_secure_idmem_share_mode(rtwdev, info.idmem_share_mode);
1820
1821 if (rtwdev->chip->chip_id == RTL8922A &&
1822 (fw_suit->type == RTW89_FW_NORMAL || fw_suit->type == RTW89_FW_WOWLAN))
1823 rtw89_write32(rtwdev, R_BE_SECURE_BOOT_MALLOC_INFO, 0x20248000);
1824
1825 ret = mac->fwdl_check_path_ready(rtwdev, true);
1826 if (ret) {
1827 rtw89_err(rtwdev, "[ERR]H2C path ready\n");
1828 return ret;
1829 }
1830
1831 ret = rtw89_fw_download_hdr(rtwdev, fw_suit, &info);
1832 if (ret)
1833 return ret;
1834
1835 ret = rtw89_fw_download_main(rtwdev, fw_suit, &info);
1836 if (ret)
1837 return ret;
1838
1839 return 0;
1840 }
1841
1842 static
1843 int __rtw89_fw_download(struct rtw89_dev *rtwdev, enum rtw89_fw_type type,
1844 bool include_bb)
1845 {
1846 const struct rtw89_mac_gen_def *mac = rtwdev->chip->mac_def;
1847 struct rtw89_fw_info *fw_info = &rtwdev->fw;
1848 struct rtw89_fw_suit *fw_suit = rtw89_fw_suit_get(rtwdev, type);
1849 u8 bbmcu_nr = rtwdev->chip->bbmcu_nr;
1850 int ret;
1851 int i;
1852
1853 mac->disable_cpu(rtwdev);
1854 ret = mac->fwdl_enable_wcpu(rtwdev, 0, true, include_bb);
1855 if (ret)
1856 return ret;
1857
1858 ret = rtw89_fw_download_suit(rtwdev, fw_suit);
1859 if (ret)
1860 goto fwdl_err;
1861
1862 for (i = 0; i < bbmcu_nr && include_bb; i++) {
1863 fw_suit = rtw89_fw_suit_get(rtwdev, RTW89_FW_BBMCU0 + i);
1864
1865 ret = rtw89_fw_download_suit(rtwdev, fw_suit);
1866 if (ret)
1867 goto fwdl_err;
1868 }
1869
1870 fw_info->h2c_seq = 0;
1871 fw_info->rec_seq = 0;
1872 fw_info->h2c_counter = 0;
1873 fw_info->c2h_counter = 0;
1874 rtwdev->mac.rpwm_seq_num = RPWM_SEQ_NUM_MAX;
1875 rtwdev->mac.cpwm_seq_num = CPWM_SEQ_NUM_MAX;
1876
1877 mdelay(5);
1878
1879 ret = rtw89_fw_check_rdy(rtwdev, RTW89_FWDL_CHECK_FREERTOS_DONE);
1880 if (ret) {
1881 rtw89_warn(rtwdev, "download firmware fail\n");
1882 goto fwdl_err;
1883 }
1884
1885 return ret;
1886
1887 fwdl_err:
1888 rtw89_fw_dl_fail_dump(rtwdev);
1889 return ret;
1890 }
1891
1892 int rtw89_fw_download(struct rtw89_dev *rtwdev, enum rtw89_fw_type type,
1893 bool include_bb)
1894 {
1895 int retry;
1896 int ret;
1897
1898 for (retry = 0; retry < 5; retry++) {
1899 ret = __rtw89_fw_download(rtwdev, type, include_bb);
1900 if (!ret)
1901 return 0;
1902 }
1903
1904 return ret;
1905 }
1906
1907 int rtw89_wait_firmware_completion(struct rtw89_dev *rtwdev)
1908 {
1909 struct rtw89_fw_info *fw = &rtwdev->fw;
1910
1911 wait_for_completion(&fw->req.completion);
1912 if (!fw->req.firmware)
1913 return -EINVAL;
1914
1915 return 0;
1916 }
1917
1918 static int rtw89_load_firmware_req(struct rtw89_dev *rtwdev,
1919 struct rtw89_fw_req_info *req,
1920 const char *fw_name, bool nowarn)
1921 {
1922 int ret;
1923
1924 if (req->firmware) {
1925 rtw89_debug(rtwdev, RTW89_DBG_FW,
1926 "full firmware has been early requested\n");
1927 complete_all(&req->completion);
1928 return 0;
1929 }
1930
1931 if (nowarn)
1932 ret = firmware_request_nowarn(&req->firmware, fw_name, rtwdev->dev);
1933 else
1934 ret = request_firmware(&req->firmware, fw_name, rtwdev->dev);
1935
1936 complete_all(&req->completion);
1937
1938 return ret;
1939 }
1940
1941 void rtw89_load_firmware_work(struct work_struct *work)
1942 {
1943 struct rtw89_dev *rtwdev =
1944 container_of(work, struct rtw89_dev, load_firmware_work);
1945 const struct rtw89_chip_info *chip = rtwdev->chip;
1946 char fw_name[64];
1947
1948 rtw89_fw_get_filename(fw_name, sizeof(fw_name),
1949 chip->fw_basename, rtwdev->fw.fw_format);
1950
1951 rtw89_load_firmware_req(rtwdev, &rtwdev->fw.req, fw_name, false);
1952 }
1953
1954 static void rtw89_free_phy_tbl_from_elm(struct rtw89_phy_table *tbl)
1955 {
1956 if (!tbl)
1957 return;
1958
1959 kfree(tbl->regs);
1960 kfree(tbl);
1961 }
1962
1963 static void rtw89_unload_firmware_elements(struct rtw89_dev *rtwdev)
1964 {
1965 struct rtw89_fw_elm_info *elm_info = &rtwdev->fw.elm_info;
1966 int i;
1967
1968 rtw89_free_phy_tbl_from_elm(elm_info->bb_tbl);
1969 rtw89_free_phy_tbl_from_elm(elm_info->bb_gain);
1970 for (i = 0; i < ARRAY_SIZE(elm_info->rf_radio); i++)
1971 rtw89_free_phy_tbl_from_elm(elm_info->rf_radio[i]);
1972 rtw89_free_phy_tbl_from_elm(elm_info->rf_nctl);
1973
1974 kfree(elm_info->txpwr_trk);
1975 kfree(elm_info->rfk_log_fmt);
1976 }
1977
1978 void rtw89_unload_firmware(struct rtw89_dev *rtwdev)
1979 {
1980 struct rtw89_fw_info *fw = &rtwdev->fw;
1981
1982 cancel_work_sync(&rtwdev->load_firmware_work);
1983
1984 if (fw->req.firmware) {
1985 release_firmware(fw->req.firmware);
1986
1987 /* assign NULL back in case rtw89_free_ieee80211_hw()
1988 * try to release the same one again.
1989 */
1990 fw->req.firmware = NULL;
1991 }
1992
1993 kfree(fw->log.fmts);
1994 rtw89_unload_firmware_elements(rtwdev);
1995 }
1996
1997 static u32 rtw89_fw_log_get_fmt_idx(struct rtw89_dev *rtwdev, u32 fmt_id)
1998 {
1999 struct rtw89_fw_log *fw_log = &rtwdev->fw.log;
2000 u32 i;
2001
2002 if (fmt_id > fw_log->last_fmt_id)
2003 return 0;
2004
2005 for (i = 0; i < fw_log->fmt_count; i++) {
2006 if (le32_to_cpu(fw_log->fmt_ids[i]) == fmt_id)
2007 return i;
2008 }
2009 return 0;
2010 }
2011
2012 static int rtw89_fw_log_create_fmts_dict(struct rtw89_dev *rtwdev)
2013 {
2014 struct rtw89_fw_log *log = &rtwdev->fw.log;
2015 const struct rtw89_fw_logsuit_hdr *suit_hdr;
2016 struct rtw89_fw_suit *suit = &log->suit;
2017 #if defined(__linux__)
2018 const void *fmts_ptr, *fmts_end_ptr;
2019 #elif defined(__FreeBSD__)
2020 const u8 *fmts_ptr, *fmts_end_ptr;
2021 #endif
2022 u32 fmt_count;
2023 int i;
2024
2025 suit_hdr = (const struct rtw89_fw_logsuit_hdr *)suit->data;
2026 fmt_count = le32_to_cpu(suit_hdr->count);
2027 log->fmt_ids = suit_hdr->ids;
2028 #if defined(__linux__)
2029 fmts_ptr = &suit_hdr->ids[fmt_count];
2030 #elif defined(__FreeBSD__)
2031 fmts_ptr = (const u8 *)&suit_hdr->ids[fmt_count];
2032 #endif
2033 fmts_end_ptr = suit->data + suit->size;
2034 log->fmts = kcalloc(fmt_count, sizeof(char *), GFP_KERNEL);
2035 if (!log->fmts)
2036 return -ENOMEM;
2037
2038 for (i = 0; i < fmt_count; i++) {
2039 fmts_ptr = memchr_inv(fmts_ptr, 0, fmts_end_ptr - fmts_ptr);
2040 if (!fmts_ptr)
2041 break;
2042
2043 (*log->fmts)[i] = fmts_ptr;
2044 log->last_fmt_id = le32_to_cpu(log->fmt_ids[i]);
2045 log->fmt_count++;
2046 fmts_ptr += strlen(fmts_ptr);
2047 }
2048
2049 return 0;
2050 }
2051
2052 int rtw89_fw_log_prepare(struct rtw89_dev *rtwdev)
2053 {
2054 struct rtw89_fw_log *log = &rtwdev->fw.log;
2055 struct rtw89_fw_suit *suit = &log->suit;
2056
2057 if (!suit || !suit->data) {
2058 rtw89_debug(rtwdev, RTW89_DBG_FW, "no log format file\n");
2059 return -EINVAL;
2060 }
2061 if (log->fmts)
2062 return 0;
2063
2064 return rtw89_fw_log_create_fmts_dict(rtwdev);
2065 }
2066
2067 static void rtw89_fw_log_dump_data(struct rtw89_dev *rtwdev,
2068 const struct rtw89_fw_c2h_log_fmt *log_fmt,
2069 u32 fmt_idx, u8 para_int, bool raw_data)
2070 {
2071 const char *(*fmts)[] = rtwdev->fw.log.fmts;
2072 char str_buf[RTW89_C2H_FW_LOG_STR_BUF_SIZE];
2073 u32 args[RTW89_C2H_FW_LOG_MAX_PARA_NUM] = {0};
2074 int i;
2075
2076 if (log_fmt->argc > RTW89_C2H_FW_LOG_MAX_PARA_NUM) {
2077 rtw89_warn(rtwdev, "C2H log: Arg count is unexpected %d\n",
2078 log_fmt->argc);
2079 return;
2080 }
2081
2082 if (para_int)
2083 for (i = 0 ; i < log_fmt->argc; i++)
2084 args[i] = le32_to_cpu(log_fmt->u.argv[i]);
2085
2086 if (raw_data) {
2087 if (para_int)
2088 snprintf(str_buf, RTW89_C2H_FW_LOG_STR_BUF_SIZE,
2089 "fw_enc(%d, %d, %d) %*ph", le32_to_cpu(log_fmt->fmt_id),
2090 para_int, log_fmt->argc, (int)sizeof(args), args);
2091 else
2092 snprintf(str_buf, RTW89_C2H_FW_LOG_STR_BUF_SIZE,
2093 "fw_enc(%d, %d, %d, %s)", le32_to_cpu(log_fmt->fmt_id),
2094 para_int, log_fmt->argc, log_fmt->u.raw);
2095 } else {
2096 snprintf(str_buf, RTW89_C2H_FW_LOG_STR_BUF_SIZE, (*fmts)[fmt_idx],
2097 args[0x0], args[0x1], args[0x2], args[0x3], args[0x4],
2098 args[0x5], args[0x6], args[0x7], args[0x8], args[0x9],
2099 args[0xa], args[0xb], args[0xc], args[0xd], args[0xe],
2100 args[0xf]);
2101 }
2102
2103 rtw89_info(rtwdev, "C2H log: %s", str_buf);
2104 }
2105
2106 void rtw89_fw_log_dump(struct rtw89_dev *rtwdev, u8 *buf, u32 len)
2107 {
2108 const struct rtw89_fw_c2h_log_fmt *log_fmt;
2109 u8 para_int;
2110 u32 fmt_idx;
2111
2112 if (len < RTW89_C2H_HEADER_LEN) {
2113 rtw89_err(rtwdev, "c2h log length is wrong!\n");
2114 return;
2115 }
2116
2117 buf += RTW89_C2H_HEADER_LEN;
2118 len -= RTW89_C2H_HEADER_LEN;
2119 log_fmt = (const struct rtw89_fw_c2h_log_fmt *)buf;
2120
2121 if (len < RTW89_C2H_FW_FORMATTED_LOG_MIN_LEN)
2122 goto plain_log;
2123
2124 if (log_fmt->signature != cpu_to_le16(RTW89_C2H_FW_LOG_SIGNATURE))
2125 goto plain_log;
2126
2127 if (!rtwdev->fw.log.fmts)
2128 return;
2129
2130 para_int = u8_get_bits(log_fmt->feature, RTW89_C2H_FW_LOG_FEATURE_PARA_INT);
2131 fmt_idx = rtw89_fw_log_get_fmt_idx(rtwdev, le32_to_cpu(log_fmt->fmt_id));
2132
2133 if (!para_int && log_fmt->argc != 0 && fmt_idx != 0)
2134 rtw89_info(rtwdev, "C2H log: %s%s",
2135 (*rtwdev->fw.log.fmts)[fmt_idx], log_fmt->u.raw);
2136 else if (fmt_idx != 0 && para_int)
2137 rtw89_fw_log_dump_data(rtwdev, log_fmt, fmt_idx, para_int, false);
2138 else
2139 rtw89_fw_log_dump_data(rtwdev, log_fmt, fmt_idx, para_int, true);
2140 return;
2141
2142 plain_log:
2143 rtw89_info(rtwdev, "C2H log: %.*s", len, buf);
2144
2145 }
2146
2147 #define H2C_CAM_LEN 60
2148 int rtw89_fw_h2c_cam(struct rtw89_dev *rtwdev, struct rtw89_vif_link *rtwvif_link,
2149 struct rtw89_sta_link *rtwsta_link, const u8 *scan_mac_addr)
2150 {
2151 struct sk_buff *skb;
2152 int ret;
2153
2154 skb = rtw89_fw_h2c_alloc_skb_with_hdr(rtwdev, H2C_CAM_LEN);
2155 if (!skb) {
2156 rtw89_err(rtwdev, "failed to alloc skb for fw dl\n");
2157 return -ENOMEM;
2158 }
2159 skb_put(skb, H2C_CAM_LEN);
2160 rtw89_cam_fill_addr_cam_info(rtwdev, rtwvif_link, rtwsta_link, scan_mac_addr,
2161 skb->data);
2162 rtw89_cam_fill_bssid_cam_info(rtwdev, rtwvif_link, rtwsta_link, skb->data);
2163
2164 rtw89_h2c_pkt_set_hdr(rtwdev, skb, FWCMD_TYPE_H2C,
2165 H2C_CAT_MAC,
2166 H2C_CL_MAC_ADDR_CAM_UPDATE,
2167 H2C_FUNC_MAC_ADDR_CAM_UPD, 0, 1,
2168 H2C_CAM_LEN);
2169
2170 ret = rtw89_h2c_tx(rtwdev, skb, false);
2171 if (ret) {
2172 rtw89_err(rtwdev, "failed to send h2c\n");
2173 goto fail;
2174 }
2175
2176 return 0;
2177 fail:
2178 dev_kfree_skb_any(skb);
2179
2180 return ret;
2181 }
2182
2183 int rtw89_fw_h2c_dctl_sec_cam_v1(struct rtw89_dev *rtwdev,
2184 struct rtw89_vif_link *rtwvif_link,
2185 struct rtw89_sta_link *rtwsta_link)
2186 {
2187 struct rtw89_h2c_dctlinfo_ud_v1 *h2c;
2188 u32 len = sizeof(*h2c);
2189 struct sk_buff *skb;
2190 int ret;
2191
2192 skb = rtw89_fw_h2c_alloc_skb_with_hdr(rtwdev, len);
2193 if (!skb) {
2194 rtw89_err(rtwdev, "failed to alloc skb for dctl sec cam\n");
2195 return -ENOMEM;
2196 }
2197 skb_put(skb, len);
2198 h2c = (struct rtw89_h2c_dctlinfo_ud_v1 *)skb->data;
2199
2200 rtw89_cam_fill_dctl_sec_cam_info_v1(rtwdev, rtwvif_link, rtwsta_link, h2c);
2201
2202 rtw89_h2c_pkt_set_hdr(rtwdev, skb, FWCMD_TYPE_H2C,
2203 H2C_CAT_MAC,
2204 H2C_CL_MAC_FR_EXCHG,
2205 H2C_FUNC_MAC_DCTLINFO_UD_V1, 0, 0,
2206 len);
2207
2208 ret = rtw89_h2c_tx(rtwdev, skb, false);
2209 if (ret) {
2210 rtw89_err(rtwdev, "failed to send h2c\n");
2211 goto fail;
2212 }
2213
2214 return 0;
2215 fail:
2216 dev_kfree_skb_any(skb);
2217
2218 return ret;
2219 }
2220 EXPORT_SYMBOL(rtw89_fw_h2c_dctl_sec_cam_v1);
2221
2222 int rtw89_fw_h2c_dctl_sec_cam_v2(struct rtw89_dev *rtwdev,
2223 struct rtw89_vif_link *rtwvif_link,
2224 struct rtw89_sta_link *rtwsta_link)
2225 {
2226 struct rtw89_h2c_dctlinfo_ud_v2 *h2c;
2227 u32 len = sizeof(*h2c);
2228 struct sk_buff *skb;
2229 int ret;
2230
2231 skb = rtw89_fw_h2c_alloc_skb_with_hdr(rtwdev, len);
2232 if (!skb) {
2233 rtw89_err(rtwdev, "failed to alloc skb for dctl sec cam\n");
2234 return -ENOMEM;
2235 }
2236 skb_put(skb, len);
2237 h2c = (struct rtw89_h2c_dctlinfo_ud_v2 *)skb->data;
2238
2239 rtw89_cam_fill_dctl_sec_cam_info_v2(rtwdev, rtwvif_link, rtwsta_link, h2c);
2240
2241 rtw89_h2c_pkt_set_hdr(rtwdev, skb, FWCMD_TYPE_H2C,
2242 H2C_CAT_MAC,
2243 H2C_CL_MAC_FR_EXCHG,
2244 H2C_FUNC_MAC_DCTLINFO_UD_V2, 0, 0,
2245 len);
2246
2247 ret = rtw89_h2c_tx(rtwdev, skb, false);
2248 if (ret) {
2249 rtw89_err(rtwdev, "failed to send h2c\n");
2250 goto fail;
2251 }
2252
2253 return 0;
2254 fail:
2255 dev_kfree_skb_any(skb);
2256
2257 return ret;
2258 }
2259 EXPORT_SYMBOL(rtw89_fw_h2c_dctl_sec_cam_v2);
2260
2261 int rtw89_fw_h2c_default_dmac_tbl_v2(struct rtw89_dev *rtwdev,
2262 struct rtw89_vif_link *rtwvif_link,
2263 struct rtw89_sta_link *rtwsta_link)
2264 {
2265 u8 mac_id = rtwsta_link ? rtwsta_link->mac_id : rtwvif_link->mac_id;
2266 struct rtw89_h2c_dctlinfo_ud_v2 *h2c;
2267 u32 len = sizeof(*h2c);
2268 struct sk_buff *skb;
2269 int ret;
2270
2271 skb = rtw89_fw_h2c_alloc_skb_with_hdr(rtwdev, len);
2272 if (!skb) {
2273 rtw89_err(rtwdev, "failed to alloc skb for dctl v2\n");
2274 return -ENOMEM;
2275 }
2276 skb_put(skb, len);
2277 h2c = (struct rtw89_h2c_dctlinfo_ud_v2 *)skb->data;
2278
2279 h2c->c0 = le32_encode_bits(mac_id, DCTLINFO_V2_C0_MACID) |
2280 le32_encode_bits(1, DCTLINFO_V2_C0_OP);
2281
2282 h2c->m0 = cpu_to_le32(DCTLINFO_V2_W0_ALL);
2283 h2c->m1 = cpu_to_le32(DCTLINFO_V2_W1_ALL);
2284 h2c->m2 = cpu_to_le32(DCTLINFO_V2_W2_ALL);
2285 h2c->m3 = cpu_to_le32(DCTLINFO_V2_W3_ALL);
2286 h2c->m4 = cpu_to_le32(DCTLINFO_V2_W4_ALL);
2287 h2c->m5 = cpu_to_le32(DCTLINFO_V2_W5_ALL);
2288 h2c->m6 = cpu_to_le32(DCTLINFO_V2_W6_ALL);
2289 h2c->m7 = cpu_to_le32(DCTLINFO_V2_W7_ALL);
2290 h2c->m8 = cpu_to_le32(DCTLINFO_V2_W8_ALL);
2291 h2c->m9 = cpu_to_le32(DCTLINFO_V2_W9_ALL);
2292 h2c->m10 = cpu_to_le32(DCTLINFO_V2_W10_ALL);
2293 h2c->m11 = cpu_to_le32(DCTLINFO_V2_W11_ALL);
2294 h2c->m12 = cpu_to_le32(DCTLINFO_V2_W12_ALL);
2295
2296 rtw89_h2c_pkt_set_hdr(rtwdev, skb, FWCMD_TYPE_H2C,
2297 H2C_CAT_MAC,
2298 H2C_CL_MAC_FR_EXCHG,
2299 H2C_FUNC_MAC_DCTLINFO_UD_V2, 0, 0,
2300 len);
2301
2302 ret = rtw89_h2c_tx(rtwdev, skb, false);
2303 if (ret) {
2304 rtw89_err(rtwdev, "failed to send h2c\n");
2305 goto fail;
2306 }
2307
2308 return 0;
2309 fail:
2310 dev_kfree_skb_any(skb);
2311
2312 return ret;
2313 }
2314 EXPORT_SYMBOL(rtw89_fw_h2c_default_dmac_tbl_v2);
2315
2316 int rtw89_fw_h2c_ba_cam(struct rtw89_dev *rtwdev,
2317 struct rtw89_vif_link *rtwvif_link,
2318 struct rtw89_sta_link *rtwsta_link,
2319 bool valid, struct ieee80211_ampdu_params *params)
2320 {
2321 const struct rtw89_chip_info *chip = rtwdev->chip;
2322 struct rtw89_h2c_ba_cam *h2c;
2323 u8 macid = rtwsta_link->mac_id;
2324 u32 len = sizeof(*h2c);
2325 struct sk_buff *skb;
2326 u8 entry_idx;
2327 int ret;
2328
2329 ret = valid ?
2330 rtw89_core_acquire_sta_ba_entry(rtwdev, rtwsta_link, params->tid,
2331 &entry_idx) :
2332 rtw89_core_release_sta_ba_entry(rtwdev, rtwsta_link, params->tid,
2333 &entry_idx);
2334 if (ret) {
2335 /* it still works even if we don't have static BA CAM, because
2336 * hardware can create dynamic BA CAM automatically.
2337 */
2338 rtw89_debug(rtwdev, RTW89_DBG_TXRX,
2339 "failed to %s entry tid=%d for h2c ba cam\n",
2340 valid ? "alloc" : "free", params->tid);
2341 return 0;
2342 }
2343
2344 skb = rtw89_fw_h2c_alloc_skb_with_hdr(rtwdev, len);
2345 if (!skb) {
2346 rtw89_err(rtwdev, "failed to alloc skb for h2c ba cam\n");
2347 return -ENOMEM;
2348 }
2349 skb_put(skb, len);
2350 h2c = (struct rtw89_h2c_ba_cam *)skb->data;
2351
2352 h2c->w0 = le32_encode_bits(macid, RTW89_H2C_BA_CAM_W0_MACID);
2353 if (chip->bacam_ver == RTW89_BACAM_V0_EXT)
2354 h2c->w1 |= le32_encode_bits(entry_idx, RTW89_H2C_BA_CAM_W1_ENTRY_IDX_V1);
2355 else
2356 h2c->w0 |= le32_encode_bits(entry_idx, RTW89_H2C_BA_CAM_W0_ENTRY_IDX);
2357 if (!valid)
2358 goto end;
2359 h2c->w0 |= le32_encode_bits(valid, RTW89_H2C_BA_CAM_W0_VALID) |
2360 le32_encode_bits(params->tid, RTW89_H2C_BA_CAM_W0_TID);
2361 if (params->buf_size > 64)
2362 h2c->w0 |= le32_encode_bits(4, RTW89_H2C_BA_CAM_W0_BMAP_SIZE);
2363 else
2364 h2c->w0 |= le32_encode_bits(0, RTW89_H2C_BA_CAM_W0_BMAP_SIZE);
2365 /* If init req is set, hw will set the ssn */
2366 h2c->w0 |= le32_encode_bits(1, RTW89_H2C_BA_CAM_W0_INIT_REQ) |
2367 le32_encode_bits(params->ssn, RTW89_H2C_BA_CAM_W0_SSN);
2368
2369 if (chip->bacam_ver == RTW89_BACAM_V0_EXT) {
2370 h2c->w1 |= le32_encode_bits(1, RTW89_H2C_BA_CAM_W1_STD_EN) |
2371 le32_encode_bits(rtwvif_link->mac_idx,
2372 RTW89_H2C_BA_CAM_W1_BAND);
2373 }
2374
2375 end:
2376 rtw89_h2c_pkt_set_hdr(rtwdev, skb, FWCMD_TYPE_H2C,
2377 H2C_CAT_MAC,
2378 H2C_CL_BA_CAM,
2379 H2C_FUNC_MAC_BA_CAM, 0, 1,
2380 len);
2381
2382 ret = rtw89_h2c_tx(rtwdev, skb, false);
2383 if (ret) {
2384 rtw89_err(rtwdev, "failed to send h2c\n");
2385 goto fail;
2386 }
2387
2388 return 0;
2389 fail:
2390 dev_kfree_skb_any(skb);
2391
2392 return ret;
2393 }
2394 EXPORT_SYMBOL(rtw89_fw_h2c_ba_cam);
2395
2396 static int rtw89_fw_h2c_init_ba_cam_v0_ext(struct rtw89_dev *rtwdev,
2397 u8 entry_idx, u8 uid)
2398 {
2399 struct rtw89_h2c_ba_cam *h2c;
2400 u32 len = sizeof(*h2c);
2401 struct sk_buff *skb;
2402 int ret;
2403
2404 skb = rtw89_fw_h2c_alloc_skb_with_hdr(rtwdev, len);
2405 if (!skb) {
2406 rtw89_err(rtwdev, "failed to alloc skb for dynamic h2c ba cam\n");
2407 return -ENOMEM;
2408 }
2409 skb_put(skb, len);
2410 h2c = (struct rtw89_h2c_ba_cam *)skb->data;
2411
2412 h2c->w0 = le32_encode_bits(1, RTW89_H2C_BA_CAM_W0_VALID);
2413 h2c->w1 = le32_encode_bits(entry_idx, RTW89_H2C_BA_CAM_W1_ENTRY_IDX_V1) |
2414 le32_encode_bits(uid, RTW89_H2C_BA_CAM_W1_UID) |
2415 le32_encode_bits(0, RTW89_H2C_BA_CAM_W1_BAND) |
2416 le32_encode_bits(0, RTW89_H2C_BA_CAM_W1_STD_EN);
2417
2418 rtw89_h2c_pkt_set_hdr(rtwdev, skb, FWCMD_TYPE_H2C,
2419 H2C_CAT_MAC,
2420 H2C_CL_BA_CAM,
2421 H2C_FUNC_MAC_BA_CAM, 0, 1,
2422 len);
2423
2424 ret = rtw89_h2c_tx(rtwdev, skb, false);
2425 if (ret) {
2426 rtw89_err(rtwdev, "failed to send h2c\n");
2427 goto fail;
2428 }
2429
2430 return 0;
2431 fail:
2432 dev_kfree_skb_any(skb);
2433
2434 return ret;
2435 }
2436
2437 void rtw89_fw_h2c_init_dynamic_ba_cam_v0_ext(struct rtw89_dev *rtwdev)
2438 {
2439 const struct rtw89_chip_info *chip = rtwdev->chip;
2440 u8 entry_idx = chip->bacam_num;
2441 u8 uid = 0;
2442 int i;
2443
2444 for (i = 0; i < chip->bacam_dynamic_num; i++) {
2445 rtw89_fw_h2c_init_ba_cam_v0_ext(rtwdev, entry_idx, uid);
2446 entry_idx++;
2447 uid++;
2448 }
2449 }
2450
2451 int rtw89_fw_h2c_ba_cam_v1(struct rtw89_dev *rtwdev,
2452 struct rtw89_vif_link *rtwvif_link,
2453 struct rtw89_sta_link *rtwsta_link,
2454 bool valid, struct ieee80211_ampdu_params *params)
2455 {
2456 const struct rtw89_chip_info *chip = rtwdev->chip;
2457 struct rtw89_h2c_ba_cam_v1 *h2c;
2458 u8 macid = rtwsta_link->mac_id;
2459 u32 len = sizeof(*h2c);
2460 struct sk_buff *skb;
2461 u8 entry_idx;
2462 u8 bmap_size;
2463 int ret;
2464
2465 ret = valid ?
2466 rtw89_core_acquire_sta_ba_entry(rtwdev, rtwsta_link, params->tid,
2467 &entry_idx) :
2468 rtw89_core_release_sta_ba_entry(rtwdev, rtwsta_link, params->tid,
2469 &entry_idx);
2470 if (ret) {
2471 /* it still works even if we don't have static BA CAM, because
2472 * hardware can create dynamic BA CAM automatically.
2473 */
2474 rtw89_debug(rtwdev, RTW89_DBG_TXRX,
2475 "failed to %s entry tid=%d for h2c ba cam\n",
2476 valid ? "alloc" : "free", params->tid);
2477 return 0;
2478 }
2479
2480 skb = rtw89_fw_h2c_alloc_skb_with_hdr(rtwdev, len);
2481 if (!skb) {
2482 rtw89_err(rtwdev, "failed to alloc skb for h2c ba cam\n");
2483 return -ENOMEM;
2484 }
2485 skb_put(skb, len);
2486 h2c = (struct rtw89_h2c_ba_cam_v1 *)skb->data;
2487
2488 if (params->buf_size > 512)
2489 bmap_size = 10;
2490 else if (params->buf_size > 256)
2491 bmap_size = 8;
2492 else if (params->buf_size > 64)
2493 bmap_size = 4;
2494 else
2495 bmap_size = 0;
2496
2497 h2c->w0 = le32_encode_bits(valid, RTW89_H2C_BA_CAM_V1_W0_VALID) |
2498 le32_encode_bits(1, RTW89_H2C_BA_CAM_V1_W0_INIT_REQ) |
2499 le32_encode_bits(macid, RTW89_H2C_BA_CAM_V1_W0_MACID_MASK) |
2500 le32_encode_bits(params->tid, RTW89_H2C_BA_CAM_V1_W0_TID_MASK) |
2501 le32_encode_bits(bmap_size, RTW89_H2C_BA_CAM_V1_W0_BMAP_SIZE_MASK) |
2502 le32_encode_bits(params->ssn, RTW89_H2C_BA_CAM_V1_W0_SSN_MASK);
2503
2504 entry_idx += chip->bacam_dynamic_num; /* std entry right after dynamic ones */
2505 h2c->w1 = le32_encode_bits(entry_idx, RTW89_H2C_BA_CAM_V1_W1_ENTRY_IDX_MASK) |
2506 le32_encode_bits(1, RTW89_H2C_BA_CAM_V1_W1_STD_ENTRY_EN) |
2507 le32_encode_bits(!!rtwvif_link->mac_idx,
2508 RTW89_H2C_BA_CAM_V1_W1_BAND_SEL);
2509
2510 rtw89_h2c_pkt_set_hdr(rtwdev, skb, FWCMD_TYPE_H2C,
2511 H2C_CAT_MAC,
2512 H2C_CL_BA_CAM,
2513 H2C_FUNC_MAC_BA_CAM_V1, 0, 1,
2514 len);
2515
2516 ret = rtw89_h2c_tx(rtwdev, skb, false);
2517 if (ret) {
2518 rtw89_err(rtwdev, "failed to send h2c\n");
2519 goto fail;
2520 }
2521
2522 return 0;
2523 fail:
2524 dev_kfree_skb_any(skb);
2525
2526 return ret;
2527 }
2528 EXPORT_SYMBOL(rtw89_fw_h2c_ba_cam_v1);
2529
2530 int rtw89_fw_h2c_init_ba_cam_users(struct rtw89_dev *rtwdev, u8 users,
2531 u8 offset, u8 mac_idx)
2532 {
2533 struct rtw89_h2c_ba_cam_init *h2c;
2534 u32 len = sizeof(*h2c);
2535 struct sk_buff *skb;
2536 int ret;
2537
2538 skb = rtw89_fw_h2c_alloc_skb_with_hdr(rtwdev, len);
2539 if (!skb) {
2540 rtw89_err(rtwdev, "failed to alloc skb for h2c ba cam init\n");
2541 return -ENOMEM;
2542 }
2543 skb_put(skb, len);
2544 h2c = (struct rtw89_h2c_ba_cam_init *)skb->data;
2545
2546 h2c->w0 = le32_encode_bits(users, RTW89_H2C_BA_CAM_INIT_USERS_MASK) |
2547 le32_encode_bits(offset, RTW89_H2C_BA_CAM_INIT_OFFSET_MASK) |
2548 le32_encode_bits(mac_idx, RTW89_H2C_BA_CAM_INIT_BAND_SEL);
2549
2550 rtw89_h2c_pkt_set_hdr(rtwdev, skb, FWCMD_TYPE_H2C,
2551 H2C_CAT_MAC,
2552 H2C_CL_BA_CAM,
2553 H2C_FUNC_MAC_BA_CAM_INIT, 0, 1,
2554 len);
2555
2556 ret = rtw89_h2c_tx(rtwdev, skb, false);
2557 if (ret) {
2558 rtw89_err(rtwdev, "failed to send h2c\n");
2559 goto fail;
2560 }
2561
2562 return 0;
2563 fail:
2564 dev_kfree_skb_any(skb);
2565
2566 return ret;
2567 }
2568
2569 #define H2C_LOG_CFG_LEN 12
2570 int rtw89_fw_h2c_fw_log(struct rtw89_dev *rtwdev, bool enable)
2571 {
2572 struct sk_buff *skb;
2573 u32 comp = 0;
2574 int ret;
2575
2576 if (enable)
2577 comp = BIT(RTW89_FW_LOG_COMP_INIT) | BIT(RTW89_FW_LOG_COMP_TASK) |
2578 BIT(RTW89_FW_LOG_COMP_PS) | BIT(RTW89_FW_LOG_COMP_ERROR) |
2579 BIT(RTW89_FW_LOG_COMP_MLO) | BIT(RTW89_FW_LOG_COMP_SCAN);
2580
2581 skb = rtw89_fw_h2c_alloc_skb_with_hdr(rtwdev, H2C_LOG_CFG_LEN);
2582 if (!skb) {
2583 rtw89_err(rtwdev, "failed to alloc skb for fw log cfg\n");
2584 return -ENOMEM;
2585 }
2586
2587 skb_put(skb, H2C_LOG_CFG_LEN);
2588 SET_LOG_CFG_LEVEL(skb->data, RTW89_FW_LOG_LEVEL_LOUD);
2589 SET_LOG_CFG_PATH(skb->data, BIT(RTW89_FW_LOG_LEVEL_C2H));
2590 SET_LOG_CFG_COMP(skb->data, comp);
2591 SET_LOG_CFG_COMP_EXT(skb->data, 0);
2592
2593 rtw89_h2c_pkt_set_hdr(rtwdev, skb, FWCMD_TYPE_H2C,
2594 H2C_CAT_MAC,
2595 H2C_CL_FW_INFO,
2596 H2C_FUNC_LOG_CFG, 0, 0,
2597 H2C_LOG_CFG_LEN);
2598
2599 ret = rtw89_h2c_tx(rtwdev, skb, false);
2600 if (ret) {
2601 rtw89_err(rtwdev, "failed to send h2c\n");
2602 goto fail;
2603 }
2604
2605 return 0;
2606 fail:
2607 dev_kfree_skb_any(skb);
2608
2609 return ret;
2610 }
2611
2612 static struct sk_buff *rtw89_eapol_get(struct rtw89_dev *rtwdev,
2613 struct rtw89_vif_link *rtwvif_link)
2614 {
2615 static const u8 gtkbody[] = {0xAA, 0xAA, 0x03, 0x00, 0x00, 0x00, 0x88,
2616 0x8E, 0x01, 0x03, 0x00, 0x5F, 0x02, 0x03};
2617 u8 sec_hdr_len = rtw89_wow_get_sec_hdr_len(rtwdev);
2618 struct rtw89_wow_param *rtw_wow = &rtwdev->wow;
2619 struct rtw89_eapol_2_of_2 *eapol_pkt;
2620 struct ieee80211_bss_conf *bss_conf;
2621 struct ieee80211_hdr_3addr *hdr;
2622 struct sk_buff *skb;
2623 u8 key_des_ver;
2624
2625 if (rtw_wow->ptk_alg == 3)
2626 key_des_ver = 1;
2627 else if (rtw_wow->akm == 1 || rtw_wow->akm == 2)
2628 key_des_ver = 2;
2629 else if (rtw_wow->akm > 2 && rtw_wow->akm < 7)
2630 key_des_ver = 3;
2631 else
2632 key_des_ver = 0;
2633
2634 skb = dev_alloc_skb(sizeof(*hdr) + sec_hdr_len + sizeof(*eapol_pkt));
2635 if (!skb)
2636 return NULL;
2637
2638 hdr = skb_put_zero(skb, sizeof(*hdr));
2639 hdr->frame_control = cpu_to_le16(IEEE80211_FTYPE_DATA |
2640 IEEE80211_FCTL_TODS |
2641 IEEE80211_FCTL_PROTECTED);
2642
2643 rcu_read_lock();
2644
2645 bss_conf = rtw89_vif_rcu_dereference_link(rtwvif_link, true);
2646
2647 ether_addr_copy(hdr->addr1, bss_conf->bssid);
2648 ether_addr_copy(hdr->addr2, bss_conf->addr);
2649 ether_addr_copy(hdr->addr3, bss_conf->bssid);
2650
2651 rcu_read_unlock();
2652
2653 skb_put_zero(skb, sec_hdr_len);
2654
2655 eapol_pkt = skb_put_zero(skb, sizeof(*eapol_pkt));
2656 memcpy(eapol_pkt->gtkbody, gtkbody, sizeof(gtkbody));
2657 eapol_pkt->key_des_ver = key_des_ver;
2658
2659 return skb;
2660 }
2661
2662 static struct sk_buff *rtw89_sa_query_get(struct rtw89_dev *rtwdev,
2663 struct rtw89_vif_link *rtwvif_link)
2664 {
2665 u8 sec_hdr_len = rtw89_wow_get_sec_hdr_len(rtwdev);
2666 struct ieee80211_bss_conf *bss_conf;
2667 struct ieee80211_hdr_3addr *hdr;
2668 struct rtw89_sa_query *sa_query;
2669 struct sk_buff *skb;
2670
2671 skb = dev_alloc_skb(sizeof(*hdr) + sec_hdr_len + sizeof(*sa_query));
2672 if (!skb)
2673 return NULL;
2674
2675 hdr = skb_put_zero(skb, sizeof(*hdr));
2676 hdr->frame_control = cpu_to_le16(IEEE80211_FTYPE_MGMT |
2677 IEEE80211_STYPE_ACTION |
2678 IEEE80211_FCTL_PROTECTED);
2679
2680 rcu_read_lock();
2681
2682 bss_conf = rtw89_vif_rcu_dereference_link(rtwvif_link, true);
2683
2684 ether_addr_copy(hdr->addr1, bss_conf->bssid);
2685 ether_addr_copy(hdr->addr2, bss_conf->addr);
2686 ether_addr_copy(hdr->addr3, bss_conf->bssid);
2687
2688 rcu_read_unlock();
2689
2690 skb_put_zero(skb, sec_hdr_len);
2691
2692 sa_query = skb_put_zero(skb, sizeof(*sa_query));
2693 sa_query->category = WLAN_CATEGORY_SA_QUERY;
2694 sa_query->action = WLAN_ACTION_SA_QUERY_RESPONSE;
2695
2696 return skb;
2697 }
2698
2699 static struct sk_buff *rtw89_arp_response_get(struct rtw89_dev *rtwdev,
2700 struct rtw89_vif_link *rtwvif_link)
2701 {
2702 struct rtw89_vif *rtwvif = rtwvif_link->rtwvif;
2703 u8 sec_hdr_len = rtw89_wow_get_sec_hdr_len(rtwdev);
2704 struct rtw89_wow_param *rtw_wow = &rtwdev->wow;
2705 struct ieee80211_hdr_3addr *hdr;
2706 struct rtw89_arp_rsp *arp_skb;
2707 struct arphdr *arp_hdr;
2708 struct sk_buff *skb;
2709 __le16 fc;
2710
2711 skb = dev_alloc_skb(sizeof(*hdr) + sec_hdr_len + sizeof(*arp_skb));
2712 if (!skb)
2713 return NULL;
2714
2715 hdr = skb_put_zero(skb, sizeof(*hdr));
2716
2717 if (rtw_wow->ptk_alg)
2718 fc = cpu_to_le16(IEEE80211_FTYPE_DATA | IEEE80211_FCTL_TODS |
2719 IEEE80211_FCTL_PROTECTED);
2720 else
2721 fc = cpu_to_le16(IEEE80211_FTYPE_DATA | IEEE80211_FCTL_TODS);
2722
2723 hdr->frame_control = fc;
2724 ether_addr_copy(hdr->addr1, rtwvif_link->bssid);
2725 ether_addr_copy(hdr->addr2, rtwvif_link->mac_addr);
2726 ether_addr_copy(hdr->addr3, rtwvif_link->bssid);
2727
2728 skb_put_zero(skb, sec_hdr_len);
2729
2730 arp_skb = skb_put_zero(skb, sizeof(*arp_skb));
2731 memcpy(arp_skb->llc_hdr, rfc1042_header, sizeof(rfc1042_header));
2732 arp_skb->llc_type = htons(ETH_P_ARP);
2733
2734 arp_hdr = &arp_skb->arp_hdr;
2735 arp_hdr->ar_hrd = htons(ARPHRD_ETHER);
2736 arp_hdr->ar_pro = htons(ETH_P_IP);
2737 arp_hdr->ar_hln = ETH_ALEN;
2738 arp_hdr->ar_pln = 4;
2739 arp_hdr->ar_op = htons(ARPOP_REPLY);
2740
2741 ether_addr_copy(arp_skb->sender_hw, rtwvif_link->mac_addr);
2742 arp_skb->sender_ip = rtwvif->ip_addr;
2743
2744 return skb;
2745 }
2746
2747 static int rtw89_fw_h2c_add_general_pkt(struct rtw89_dev *rtwdev,
2748 struct rtw89_vif_link *rtwvif_link,
2749 enum rtw89_fw_pkt_ofld_type type,
2750 u8 *id)
2751 {
2752 struct ieee80211_vif *vif = rtwvif_link_to_vif(rtwvif_link);
2753 int link_id = ieee80211_vif_is_mld(vif) ? rtwvif_link->link_id : -1;
2754 struct rtw89_pktofld_info *info;
2755 struct sk_buff *skb;
2756 int ret;
2757
2758 info = kzalloc(sizeof(*info), GFP_KERNEL);
2759 if (!info)
2760 return -ENOMEM;
2761
2762 switch (type) {
2763 case RTW89_PKT_OFLD_TYPE_PS_POLL:
2764 skb = ieee80211_pspoll_get(rtwdev->hw, vif);
2765 break;
2766 case RTW89_PKT_OFLD_TYPE_PROBE_RSP:
2767 skb = ieee80211_proberesp_get(rtwdev->hw, vif);
2768 break;
2769 case RTW89_PKT_OFLD_TYPE_NULL_DATA:
2770 skb = ieee80211_nullfunc_get(rtwdev->hw, vif, link_id, false);
2771 break;
2772 case RTW89_PKT_OFLD_TYPE_QOS_NULL:
2773 skb = ieee80211_nullfunc_get(rtwdev->hw, vif, link_id, true);
2774 break;
2775 case RTW89_PKT_OFLD_TYPE_EAPOL_KEY:
2776 skb = rtw89_eapol_get(rtwdev, rtwvif_link);
2777 break;
2778 case RTW89_PKT_OFLD_TYPE_SA_QUERY:
2779 skb = rtw89_sa_query_get(rtwdev, rtwvif_link);
2780 break;
2781 case RTW89_PKT_OFLD_TYPE_ARP_RSP:
2782 skb = rtw89_arp_response_get(rtwdev, rtwvif_link);
2783 break;
2784 default:
2785 goto err;
2786 }
2787
2788 if (!skb)
2789 goto err;
2790
2791 ret = rtw89_fw_h2c_add_pkt_offload(rtwdev, &info->id, skb);
2792 kfree_skb(skb);
2793
2794 if (ret)
2795 goto err;
2796
2797 list_add_tail(&info->list, &rtwvif_link->general_pkt_list);
2798 *id = info->id;
2799 return 0;
2800
2801 err:
2802 kfree(info);
2803 return -ENOMEM;
2804 }
2805
2806 void rtw89_fw_release_general_pkt_list_vif(struct rtw89_dev *rtwdev,
2807 struct rtw89_vif_link *rtwvif_link,
2808 bool notify_fw)
2809 {
2810 struct list_head *pkt_list = &rtwvif_link->general_pkt_list;
2811 struct rtw89_pktofld_info *info, *tmp;
2812
2813 list_for_each_entry_safe(info, tmp, pkt_list, list) {
2814 if (notify_fw)
2815 rtw89_fw_h2c_del_pkt_offload(rtwdev, info->id);
2816 else
2817 rtw89_core_release_bit_map(rtwdev->pkt_offload, info->id);
2818 list_del(&info->list);
2819 kfree(info);
2820 }
2821 }
2822
2823 void rtw89_fw_release_general_pkt_list(struct rtw89_dev *rtwdev, bool notify_fw)
2824 {
2825 struct rtw89_vif_link *rtwvif_link;
2826 struct rtw89_vif *rtwvif;
2827 unsigned int link_id;
2828
2829 rtw89_for_each_rtwvif(rtwdev, rtwvif)
2830 rtw89_vif_for_each_link(rtwvif, rtwvif_link, link_id)
2831 rtw89_fw_release_general_pkt_list_vif(rtwdev, rtwvif_link,
2832 notify_fw);
2833 }
2834
2835 #define H2C_GENERAL_PKT_LEN 6
2836 #define H2C_GENERAL_PKT_ID_UND 0xff
2837 int rtw89_fw_h2c_general_pkt(struct rtw89_dev *rtwdev,
2838 struct rtw89_vif_link *rtwvif_link, u8 macid)
2839 {
2840 u8 pkt_id_ps_poll = H2C_GENERAL_PKT_ID_UND;
2841 u8 pkt_id_null = H2C_GENERAL_PKT_ID_UND;
2842 u8 pkt_id_qos_null = H2C_GENERAL_PKT_ID_UND;
2843 struct sk_buff *skb;
2844 int ret;
2845
2846 rtw89_fw_h2c_add_general_pkt(rtwdev, rtwvif_link,
2847 RTW89_PKT_OFLD_TYPE_PS_POLL, &pkt_id_ps_poll);
2848 rtw89_fw_h2c_add_general_pkt(rtwdev, rtwvif_link,
2849 RTW89_PKT_OFLD_TYPE_NULL_DATA, &pkt_id_null);
2850 rtw89_fw_h2c_add_general_pkt(rtwdev, rtwvif_link,
2851 RTW89_PKT_OFLD_TYPE_QOS_NULL, &pkt_id_qos_null);
2852
2853 skb = rtw89_fw_h2c_alloc_skb_with_hdr(rtwdev, H2C_GENERAL_PKT_LEN);
2854 if (!skb) {
2855 rtw89_err(rtwdev, "failed to alloc skb for fw dl\n");
2856 return -ENOMEM;
2857 }
2858 skb_put(skb, H2C_GENERAL_PKT_LEN);
2859 SET_GENERAL_PKT_MACID(skb->data, macid);
2860 SET_GENERAL_PKT_PROBRSP_ID(skb->data, H2C_GENERAL_PKT_ID_UND);
2861 SET_GENERAL_PKT_PSPOLL_ID(skb->data, pkt_id_ps_poll);
2862 SET_GENERAL_PKT_NULL_ID(skb->data, pkt_id_null);
2863 SET_GENERAL_PKT_QOS_NULL_ID(skb->data, pkt_id_qos_null);
2864 SET_GENERAL_PKT_CTS2SELF_ID(skb->data, H2C_GENERAL_PKT_ID_UND);
2865
2866 rtw89_h2c_pkt_set_hdr(rtwdev, skb, FWCMD_TYPE_H2C,
2867 H2C_CAT_MAC,
2868 H2C_CL_FW_INFO,
2869 H2C_FUNC_MAC_GENERAL_PKT, 0, 1,
2870 H2C_GENERAL_PKT_LEN);
2871
2872 ret = rtw89_h2c_tx(rtwdev, skb, false);
2873 if (ret) {
2874 rtw89_err(rtwdev, "failed to send h2c\n");
2875 goto fail;
2876 }
2877
2878 return 0;
2879 fail:
2880 dev_kfree_skb_any(skb);
2881
2882 return ret;
2883 }
2884
2885 #define H2C_LPS_PARM_LEN 8
2886 int rtw89_fw_h2c_lps_parm(struct rtw89_dev *rtwdev,
2887 struct rtw89_lps_parm *lps_param)
2888 {
2889 struct sk_buff *skb;
2890 bool done_ack;
2891 int ret;
2892
2893 if (RTW89_CHK_FW_FEATURE(LPS_DACK_BY_C2H_REG, &rtwdev->fw))
2894 done_ack = false;
2895 else
2896 done_ack = !lps_param->psmode;
2897
2898 skb = rtw89_fw_h2c_alloc_skb_with_hdr(rtwdev, H2C_LPS_PARM_LEN);
2899 if (!skb) {
2900 rtw89_err(rtwdev, "failed to alloc skb for fw dl\n");
2901 return -ENOMEM;
2902 }
2903 skb_put(skb, H2C_LPS_PARM_LEN);
2904
2905 SET_LPS_PARM_MACID(skb->data, lps_param->macid);
2906 SET_LPS_PARM_PSMODE(skb->data, lps_param->psmode);
2907 SET_LPS_PARM_LASTRPWM(skb->data, lps_param->lastrpwm);
2908 SET_LPS_PARM_RLBM(skb->data, 1);
2909 SET_LPS_PARM_SMARTPS(skb->data, 1);
2910 SET_LPS_PARM_AWAKEINTERVAL(skb->data, 1);
2911 SET_LPS_PARM_VOUAPSD(skb->data, 0);
2912 SET_LPS_PARM_VIUAPSD(skb->data, 0);
2913 SET_LPS_PARM_BEUAPSD(skb->data, 0);
2914 SET_LPS_PARM_BKUAPSD(skb->data, 0);
2915
2916 rtw89_h2c_pkt_set_hdr(rtwdev, skb, FWCMD_TYPE_H2C,
2917 H2C_CAT_MAC,
2918 H2C_CL_MAC_PS,
2919 H2C_FUNC_MAC_LPS_PARM, 0, done_ack,
2920 H2C_LPS_PARM_LEN);
2921
2922 ret = rtw89_h2c_tx(rtwdev, skb, false);
2923 if (ret) {
2924 rtw89_err(rtwdev, "failed to send h2c\n");
2925 goto fail;
2926 }
2927
2928 return 0;
2929 fail:
2930 dev_kfree_skb_any(skb);
2931
2932 return ret;
2933 }
2934
2935 int rtw89_fw_h2c_lps_ch_info(struct rtw89_dev *rtwdev, struct rtw89_vif *rtwvif)
2936 {
2937 const struct rtw89_chip_info *chip = rtwdev->chip;
2938 const struct rtw89_chan *chan;
2939 struct rtw89_vif_link *rtwvif_link;
2940 struct rtw89_h2c_lps_ch_info *h2c;
2941 u32 len = sizeof(*h2c);
2942 unsigned int link_id;
2943 struct sk_buff *skb;
2944 bool no_chan = true;
2945 u8 phy_idx;
2946 u32 done;
2947 int ret;
2948
2949 if (chip->chip_gen != RTW89_CHIP_BE)
2950 return 0;
2951
2952 skb = rtw89_fw_h2c_alloc_skb_with_hdr(rtwdev, len);
2953 if (!skb) {
2954 rtw89_err(rtwdev, "failed to alloc skb for h2c lps_ch_info\n");
2955 return -ENOMEM;
2956 }
2957 skb_put(skb, len);
2958 h2c = (struct rtw89_h2c_lps_ch_info *)skb->data;
2959
2960 rtw89_vif_for_each_link(rtwvif, rtwvif_link, link_id) {
2961 phy_idx = rtwvif_link->phy_idx;
2962 if (phy_idx >= ARRAY_SIZE(h2c->info))
2963 continue;
2964
2965 chan = rtw89_chan_get(rtwdev, rtwvif_link->chanctx_idx);
2966 no_chan = false;
2967
2968 h2c->info[phy_idx].central_ch = chan->channel;
2969 h2c->info[phy_idx].pri_ch = chan->primary_channel;
2970 h2c->info[phy_idx].band = chan->band_type;
2971 h2c->info[phy_idx].bw = chan->band_width;
2972 }
2973
2974 if (no_chan) {
2975 rtw89_err(rtwdev, "no chan for h2c lps_ch_info\n");
2976 ret = -ENOENT;
2977 goto fail;
2978 }
2979
2980 h2c->mlo_dbcc_mode_lps = cpu_to_le32(rtwdev->mlo_dbcc_mode);
2981
2982 rtw89_h2c_pkt_set_hdr(rtwdev, skb, FWCMD_TYPE_H2C,
2983 H2C_CAT_OUTSRC, H2C_CL_OUTSRC_DM,
2984 H2C_FUNC_FW_LPS_CH_INFO, 0, 0, len);
2985
2986 rtw89_phy_write32_mask(rtwdev, R_CHK_LPS_STAT, B_CHK_LPS_STAT, 0);
2987 ret = rtw89_h2c_tx(rtwdev, skb, false);
2988 if (ret) {
2989 rtw89_err(rtwdev, "failed to send h2c\n");
2990 goto fail;
2991 }
2992
2993 ret = read_poll_timeout(rtw89_phy_read32_mask, done, done, 50, 5000,
2994 true, rtwdev, R_CHK_LPS_STAT, B_CHK_LPS_STAT);
2995 if (ret)
2996 rtw89_warn(rtwdev, "h2c_lps_ch_info done polling timeout\n");
2997
2998 return 0;
2999 fail:
3000 dev_kfree_skb_any(skb);
3001
3002 return ret;
3003 }
3004
3005 int rtw89_fw_h2c_lps_ml_cmn_info(struct rtw89_dev *rtwdev,
3006 struct rtw89_vif *rtwvif)
3007 {
3008 const struct rtw89_phy_bb_gain_info_be *gain = &rtwdev->bb_gain.be;
3009 struct rtw89_pkt_stat *pkt_stat = &rtwdev->phystat.cur_pkt_stat;
3010 static const u8 bcn_bw_ofst[] = {0, 0, 0, 3, 6, 9, 0, 12};
3011 const struct rtw89_chip_info *chip = rtwdev->chip;
3012 struct rtw89_efuse *efuse = &rtwdev->efuse;
3013 struct rtw89_h2c_lps_ml_cmn_info *h2c;
3014 struct rtw89_vif_link *rtwvif_link;
3015 const struct rtw89_chan *chan;
3016 u8 bw_idx = RTW89_BB_BW_20_40;
3017 u32 len = sizeof(*h2c);
3018 unsigned int link_id;
3019 struct sk_buff *skb;
3020 u8 beacon_bw_ofst;
3021 u8 gain_band;
3022 u32 done;
3023 u8 path;
3024 int ret;
3025 int i;
3026
3027 if (chip->chip_gen != RTW89_CHIP_BE)
3028 return 0;
3029
3030 skb = rtw89_fw_h2c_alloc_skb_with_hdr(rtwdev, len);
3031 if (!skb) {
3032 rtw89_err(rtwdev, "failed to alloc skb for h2c lps_ml_cmn_info\n");
3033 return -ENOMEM;
3034 }
3035 skb_put(skb, len);
3036 h2c = (struct rtw89_h2c_lps_ml_cmn_info *)skb->data;
3037
3038 h2c->fmt_id = 0x3;
3039
3040 h2c->mlo_dbcc_mode = cpu_to_le32(rtwdev->mlo_dbcc_mode);
3041 h2c->rfe_type = efuse->rfe_type;
3042
3043 rtw89_vif_for_each_link(rtwvif, rtwvif_link, link_id) {
3044 path = rtwvif_link->phy_idx == RTW89_PHY_1 ? RF_PATH_B : RF_PATH_A;
3045 chan = rtw89_chan_get(rtwdev, rtwvif_link->chanctx_idx);
3046 gain_band = rtw89_subband_to_gain_band_be(chan->subband_type);
3047
3048 h2c->central_ch[rtwvif_link->phy_idx] = chan->channel;
3049 h2c->pri_ch[rtwvif_link->phy_idx] = chan->primary_channel;
3050 h2c->band[rtwvif_link->phy_idx] = chan->band_type;
3051 h2c->bw[rtwvif_link->phy_idx] = chan->band_width;
3052 if (pkt_stat->beacon_rate < RTW89_HW_RATE_OFDM6)
3053 h2c->bcn_rate_type[rtwvif_link->phy_idx] = 0x1;
3054 else
3055 h2c->bcn_rate_type[rtwvif_link->phy_idx] = 0x2;
3056
3057 /* Fill BW20 RX gain table for beacon mode */
3058 for (i = 0; i < TIA_GAIN_NUM; i++) {
3059 h2c->tia_gain[rtwvif_link->phy_idx][i] =
3060 cpu_to_le16(gain->tia_gain[gain_band][bw_idx][path][i]);
3061 }
3062
3063 if (rtwvif_link->bcn_bw_idx < ARRAY_SIZE(bcn_bw_ofst)) {
3064 beacon_bw_ofst = bcn_bw_ofst[rtwvif_link->bcn_bw_idx];
3065 h2c->dup_bcn_ofst[rtwvif_link->phy_idx] = beacon_bw_ofst;
3066 }
3067
3068 memcpy(h2c->lna_gain[rtwvif_link->phy_idx],
3069 gain->lna_gain[gain_band][bw_idx][path],
3070 LNA_GAIN_NUM);
3071 memcpy(h2c->tia_lna_op1db[rtwvif_link->phy_idx],
3072 gain->tia_lna_op1db[gain_band][bw_idx][path],
3073 LNA_GAIN_NUM + 1);
3074 memcpy(h2c->lna_op1db[rtwvif_link->phy_idx],
3075 gain->lna_op1db[gain_band][bw_idx][path],
3076 LNA_GAIN_NUM);
3077 }
3078
3079 rtw89_h2c_pkt_set_hdr(rtwdev, skb, FWCMD_TYPE_H2C,
3080 H2C_CAT_OUTSRC, H2C_CL_OUTSRC_DM,
3081 H2C_FUNC_FW_LPS_ML_CMN_INFO, 0, 0, len);
3082
3083 rtw89_phy_write32_mask(rtwdev, R_CHK_LPS_STAT, B_CHK_LPS_STAT, 0);
3084 ret = rtw89_h2c_tx(rtwdev, skb, false);
3085 if (ret) {
3086 rtw89_err(rtwdev, "failed to send h2c\n");
3087 goto fail;
3088 }
3089
3090 ret = read_poll_timeout(rtw89_phy_read32_mask, done, done, 50, 5000,
3091 true, rtwdev, R_CHK_LPS_STAT, B_CHK_LPS_STAT);
3092 if (ret)
3093 rtw89_warn(rtwdev, "h2c_lps_ml_cmn_info done polling timeout\n");
3094
3095 return 0;
3096 fail:
3097 dev_kfree_skb_any(skb);
3098
3099 return ret;
3100 }
3101
3102 #define H2C_P2P_ACT_LEN 20
3103 int rtw89_fw_h2c_p2p_act(struct rtw89_dev *rtwdev,
3104 struct rtw89_vif_link *rtwvif_link,
3105 struct ieee80211_p2p_noa_desc *desc,
3106 u8 act, u8 noa_id, u8 ctwindow_oppps)
3107 {
3108 bool p2p_type_gc = rtwvif_link->wifi_role == RTW89_WIFI_ROLE_P2P_CLIENT;
3109 struct sk_buff *skb;
3110 u8 *cmd;
3111 int ret;
3112
3113 skb = rtw89_fw_h2c_alloc_skb_with_hdr(rtwdev, H2C_P2P_ACT_LEN);
3114 if (!skb) {
3115 rtw89_err(rtwdev, "failed to alloc skb for h2c p2p act\n");
3116 return -ENOMEM;
3117 }
3118 skb_put(skb, H2C_P2P_ACT_LEN);
3119 cmd = skb->data;
3120
3121 RTW89_SET_FWCMD_P2P_MACID(cmd, rtwvif_link->mac_id);
3122 RTW89_SET_FWCMD_P2P_P2PID(cmd, 0);
3123 RTW89_SET_FWCMD_P2P_NOAID(cmd, noa_id);
3124 RTW89_SET_FWCMD_P2P_ACT(cmd, act);
3125 RTW89_SET_FWCMD_P2P_TYPE(cmd, p2p_type_gc);
3126 RTW89_SET_FWCMD_P2P_ALL_SLEP(cmd, 0);
3127 if (desc) {
3128 RTW89_SET_FWCMD_NOA_START_TIME(cmd, desc->start_time);
3129 RTW89_SET_FWCMD_NOA_INTERVAL(cmd, desc->interval);
3130 RTW89_SET_FWCMD_NOA_DURATION(cmd, desc->duration);
3131 RTW89_SET_FWCMD_NOA_COUNT(cmd, desc->count);
3132 RTW89_SET_FWCMD_NOA_CTWINDOW(cmd, ctwindow_oppps);
3133 }
3134
3135 rtw89_h2c_pkt_set_hdr(rtwdev, skb, FWCMD_TYPE_H2C,
3136 H2C_CAT_MAC, H2C_CL_MAC_PS,
3137 H2C_FUNC_P2P_ACT, 0, 0,
3138 H2C_P2P_ACT_LEN);
3139
3140 ret = rtw89_h2c_tx(rtwdev, skb, false);
3141 if (ret) {
3142 rtw89_err(rtwdev, "failed to send h2c\n");
3143 goto fail;
3144 }
3145
3146 return 0;
3147 fail:
3148 dev_kfree_skb_any(skb);
3149
3150 return ret;
3151 }
3152
3153 static void __rtw89_fw_h2c_set_tx_path(struct rtw89_dev *rtwdev,
3154 struct sk_buff *skb)
3155 {
3156 const struct rtw89_chip_info *chip = rtwdev->chip;
3157 struct rtw89_hal *hal = &rtwdev->hal;
3158 u8 ntx_path;
3159 u8 map_b;
3160
3161 if (chip->rf_path_num == 1) {
3162 ntx_path = RF_A;
3163 map_b = 0;
3164 } else {
3165 ntx_path = hal->antenna_tx ? hal->antenna_tx : RF_AB;
3166 map_b = ntx_path == RF_AB ? 1 : 0;
3167 }
3168
3169 SET_CMC_TBL_NTX_PATH_EN(skb->data, ntx_path);
3170 SET_CMC_TBL_PATH_MAP_A(skb->data, 0);
3171 SET_CMC_TBL_PATH_MAP_B(skb->data, map_b);
3172 SET_CMC_TBL_PATH_MAP_C(skb->data, 0);
3173 SET_CMC_TBL_PATH_MAP_D(skb->data, 0);
3174 }
3175
3176 #define H2C_CMC_TBL_LEN 68
3177 int rtw89_fw_h2c_default_cmac_tbl(struct rtw89_dev *rtwdev,
3178 struct rtw89_vif_link *rtwvif_link,
3179 struct rtw89_sta_link *rtwsta_link)
3180 {
3181 const struct rtw89_chip_info *chip = rtwdev->chip;
3182 u8 macid = rtwsta_link ? rtwsta_link->mac_id : rtwvif_link->mac_id;
3183 struct sk_buff *skb;
3184 int ret;
3185
3186 skb = rtw89_fw_h2c_alloc_skb_with_hdr(rtwdev, H2C_CMC_TBL_LEN);
3187 if (!skb) {
3188 rtw89_err(rtwdev, "failed to alloc skb for fw dl\n");
3189 return -ENOMEM;
3190 }
3191 skb_put(skb, H2C_CMC_TBL_LEN);
3192 SET_CTRL_INFO_MACID(skb->data, macid);
3193 SET_CTRL_INFO_OPERATION(skb->data, 1);
3194 if (chip->h2c_cctl_func_id == H2C_FUNC_MAC_CCTLINFO_UD) {
3195 SET_CMC_TBL_TXPWR_MODE(skb->data, 0);
3196 __rtw89_fw_h2c_set_tx_path(rtwdev, skb);
3197 SET_CMC_TBL_ANTSEL_A(skb->data, 0);
3198 SET_CMC_TBL_ANTSEL_B(skb->data, 0);
3199 SET_CMC_TBL_ANTSEL_C(skb->data, 0);
3200 SET_CMC_TBL_ANTSEL_D(skb->data, 0);
3201 }
3202 SET_CMC_TBL_DOPPLER_CTRL(skb->data, 0);
3203 SET_CMC_TBL_TXPWR_TOLERENCE(skb->data, 0);
3204 if (rtwvif_link->net_type == RTW89_NET_TYPE_AP_MODE)
3205 SET_CMC_TBL_DATA_DCM(skb->data, 0);
3206
3207 rtw89_h2c_pkt_set_hdr(rtwdev, skb, FWCMD_TYPE_H2C,
3208 H2C_CAT_MAC, H2C_CL_MAC_FR_EXCHG,
3209 chip->h2c_cctl_func_id, 0, 1,
3210 H2C_CMC_TBL_LEN);
3211
3212 ret = rtw89_h2c_tx(rtwdev, skb, false);
3213 if (ret) {
3214 rtw89_err(rtwdev, "failed to send h2c\n");
3215 goto fail;
3216 }
3217
3218 return 0;
3219 fail:
3220 dev_kfree_skb_any(skb);
3221
3222 return ret;
3223 }
3224 EXPORT_SYMBOL(rtw89_fw_h2c_default_cmac_tbl);
3225
3226 int rtw89_fw_h2c_default_cmac_tbl_g7(struct rtw89_dev *rtwdev,
3227 struct rtw89_vif_link *rtwvif_link,
3228 struct rtw89_sta_link *rtwsta_link)
3229 {
3230 u8 mac_id = rtwsta_link ? rtwsta_link->mac_id : rtwvif_link->mac_id;
3231 struct rtw89_h2c_cctlinfo_ud_g7 *h2c;
3232 u32 len = sizeof(*h2c);
3233 struct sk_buff *skb;
3234 int ret;
3235
3236 skb = rtw89_fw_h2c_alloc_skb_with_hdr(rtwdev, len);
3237 if (!skb) {
3238 rtw89_err(rtwdev, "failed to alloc skb for cmac g7\n");
3239 return -ENOMEM;
3240 }
3241 skb_put(skb, len);
3242 h2c = (struct rtw89_h2c_cctlinfo_ud_g7 *)skb->data;
3243
3244 h2c->c0 = le32_encode_bits(mac_id, CCTLINFO_G7_C0_MACID) |
3245 le32_encode_bits(1, CCTLINFO_G7_C0_OP);
3246
3247 h2c->w0 = le32_encode_bits(4, CCTLINFO_G7_W0_DATARATE);
3248 h2c->m0 = cpu_to_le32(CCTLINFO_G7_W0_ALL);
3249
3250 h2c->w1 = le32_encode_bits(4, CCTLINFO_G7_W1_DATA_RTY_LOWEST_RATE) |
3251 le32_encode_bits(0xa, CCTLINFO_G7_W1_RTSRATE) |
3252 le32_encode_bits(4, CCTLINFO_G7_W1_RTS_RTY_LOWEST_RATE);
3253 h2c->m1 = cpu_to_le32(CCTLINFO_G7_W1_ALL);
3254
3255 h2c->m2 = cpu_to_le32(CCTLINFO_G7_W2_ALL);
3256
3257 h2c->m3 = cpu_to_le32(CCTLINFO_G7_W3_ALL);
3258
3259 h2c->w4 = le32_encode_bits(0xFFFF, CCTLINFO_G7_W4_ACT_SUBCH_CBW);
3260 h2c->m4 = cpu_to_le32(CCTLINFO_G7_W4_ALL);
3261
3262 h2c->w5 = le32_encode_bits(2, CCTLINFO_G7_W5_NOMINAL_PKT_PADDING0) |
3263 le32_encode_bits(2, CCTLINFO_G7_W5_NOMINAL_PKT_PADDING1) |
3264 le32_encode_bits(2, CCTLINFO_G7_W5_NOMINAL_PKT_PADDING2) |
3265 le32_encode_bits(2, CCTLINFO_G7_W5_NOMINAL_PKT_PADDING3) |
3266 le32_encode_bits(2, CCTLINFO_G7_W5_NOMINAL_PKT_PADDING4);
3267 h2c->m5 = cpu_to_le32(CCTLINFO_G7_W5_ALL);
3268
3269 h2c->w6 = le32_encode_bits(0xb, CCTLINFO_G7_W6_RESP_REF_RATE);
3270 h2c->m6 = cpu_to_le32(CCTLINFO_G7_W6_ALL);
3271
3272 h2c->w7 = le32_encode_bits(1, CCTLINFO_G7_W7_NC) |
3273 le32_encode_bits(1, CCTLINFO_G7_W7_NR) |
3274 le32_encode_bits(1, CCTLINFO_G7_W7_CB) |
3275 le32_encode_bits(0x1, CCTLINFO_G7_W7_CSI_PARA_EN) |
3276 le32_encode_bits(0xb, CCTLINFO_G7_W7_CSI_FIX_RATE);
3277 h2c->m7 = cpu_to_le32(CCTLINFO_G7_W7_ALL);
3278
3279 h2c->m8 = cpu_to_le32(CCTLINFO_G7_W8_ALL);
3280
3281 h2c->w14 = le32_encode_bits(0, CCTLINFO_G7_W14_VO_CURR_RATE) |
3282 le32_encode_bits(0, CCTLINFO_G7_W14_VI_CURR_RATE) |
3283 le32_encode_bits(0, CCTLINFO_G7_W14_BE_CURR_RATE_L);
3284 h2c->m14 = cpu_to_le32(CCTLINFO_G7_W14_ALL);
3285
3286 h2c->w15 = le32_encode_bits(0, CCTLINFO_G7_W15_BE_CURR_RATE_H) |
3287 le32_encode_bits(0, CCTLINFO_G7_W15_BK_CURR_RATE) |
3288 le32_encode_bits(0, CCTLINFO_G7_W15_MGNT_CURR_RATE);
3289 h2c->m15 = cpu_to_le32(CCTLINFO_G7_W15_ALL);
3290
3291 rtw89_h2c_pkt_set_hdr(rtwdev, skb, FWCMD_TYPE_H2C,
3292 H2C_CAT_MAC, H2C_CL_MAC_FR_EXCHG,
3293 H2C_FUNC_MAC_CCTLINFO_UD_G7, 0, 1,
3294 len);
3295
3296 ret = rtw89_h2c_tx(rtwdev, skb, false);
3297 if (ret) {
3298 rtw89_err(rtwdev, "failed to send h2c\n");
3299 goto fail;
3300 }
3301
3302 return 0;
3303 fail:
3304 dev_kfree_skb_any(skb);
3305
3306 return ret;
3307 }
3308 EXPORT_SYMBOL(rtw89_fw_h2c_default_cmac_tbl_g7);
3309
3310 static void __get_sta_he_pkt_padding(struct rtw89_dev *rtwdev,
3311 struct ieee80211_link_sta *link_sta,
3312 u8 *pads)
3313 {
3314 bool ppe_th;
3315 u8 ppe16, ppe8;
3316 u8 nss = min(link_sta->rx_nss, rtwdev->hal.tx_nss) - 1;
3317 u8 ppe_thres_hdr = link_sta->he_cap.ppe_thres[0];
3318 u8 ru_bitmap;
3319 u8 n, idx, sh;
3320 u16 ppe;
3321 int i;
3322
3323 ppe_th = FIELD_GET(IEEE80211_HE_PHY_CAP6_PPE_THRESHOLD_PRESENT,
3324 link_sta->he_cap.he_cap_elem.phy_cap_info[6]);
3325 if (!ppe_th) {
3326 u8 pad;
3327
3328 pad = FIELD_GET(IEEE80211_HE_PHY_CAP9_NOMINAL_PKT_PADDING_MASK,
3329 link_sta->he_cap.he_cap_elem.phy_cap_info[9]);
3330
3331 for (i = 0; i < RTW89_PPE_BW_NUM; i++)
3332 pads[i] = pad;
3333
3334 return;
3335 }
3336
3337 ru_bitmap = FIELD_GET(IEEE80211_PPE_THRES_RU_INDEX_BITMASK_MASK, ppe_thres_hdr);
3338 n = hweight8(ru_bitmap);
3339 n = 7 + (n * IEEE80211_PPE_THRES_INFO_PPET_SIZE * 2) * nss;
3340
3341 for (i = 0; i < RTW89_PPE_BW_NUM; i++) {
3342 if (!(ru_bitmap & BIT(i))) {
3343 pads[i] = 1;
3344 continue;
3345 }
3346
3347 idx = n >> 3;
3348 sh = n & 7;
3349 n += IEEE80211_PPE_THRES_INFO_PPET_SIZE * 2;
3350
3351 ppe = le16_to_cpu(*((__le16 *)&link_sta->he_cap.ppe_thres[idx]));
3352 ppe16 = (ppe >> sh) & IEEE80211_PPE_THRES_NSS_MASK;
3353 sh += IEEE80211_PPE_THRES_INFO_PPET_SIZE;
3354 ppe8 = (ppe >> sh) & IEEE80211_PPE_THRES_NSS_MASK;
3355
3356 if (ppe16 != 7 && ppe8 == 7)
3357 pads[i] = RTW89_PE_DURATION_16;
3358 else if (ppe8 != 7)
3359 pads[i] = RTW89_PE_DURATION_8;
3360 else
3361 pads[i] = RTW89_PE_DURATION_0;
3362 }
3363 }
3364
3365 int rtw89_fw_h2c_assoc_cmac_tbl(struct rtw89_dev *rtwdev,
3366 struct rtw89_vif_link *rtwvif_link,
3367 struct rtw89_sta_link *rtwsta_link)
3368 {
3369 struct ieee80211_vif *vif = rtwvif_link_to_vif(rtwvif_link);
3370 const struct rtw89_chip_info *chip = rtwdev->chip;
3371 const struct rtw89_chan *chan = rtw89_chan_get(rtwdev,
3372 rtwvif_link->chanctx_idx);
3373 struct ieee80211_link_sta *link_sta;
3374 struct sk_buff *skb;
3375 u8 pads[RTW89_PPE_BW_NUM];
3376 u8 mac_id = rtwsta_link ? rtwsta_link->mac_id : rtwvif_link->mac_id;
3377 u16 lowest_rate;
3378 int ret;
3379
3380 memset(pads, 0, sizeof(pads));
3381
3382 skb = rtw89_fw_h2c_alloc_skb_with_hdr(rtwdev, H2C_CMC_TBL_LEN);
3383 if (!skb) {
3384 rtw89_err(rtwdev, "failed to alloc skb for fw dl\n");
3385 return -ENOMEM;
3386 }
3387
3388 rcu_read_lock();
3389
3390 if (rtwsta_link)
3391 link_sta = rtw89_sta_rcu_dereference_link(rtwsta_link, true);
3392
3393 if (rtwsta_link && link_sta->he_cap.has_he)
3394 __get_sta_he_pkt_padding(rtwdev, link_sta, pads);
3395
3396 if (vif->p2p)
3397 lowest_rate = RTW89_HW_RATE_OFDM6;
3398 else if (chan->band_type == RTW89_BAND_2G)
3399 lowest_rate = RTW89_HW_RATE_CCK1;
3400 else
3401 lowest_rate = RTW89_HW_RATE_OFDM6;
3402
3403 skb_put(skb, H2C_CMC_TBL_LEN);
3404 SET_CTRL_INFO_MACID(skb->data, mac_id);
3405 SET_CTRL_INFO_OPERATION(skb->data, 1);
3406 SET_CMC_TBL_DISRTSFB(skb->data, 1);
3407 SET_CMC_TBL_DISDATAFB(skb->data, 1);
3408 SET_CMC_TBL_RTS_RTY_LOWEST_RATE(skb->data, lowest_rate);
3409 SET_CMC_TBL_RTS_TXCNT_LMT_SEL(skb->data, 0);
3410 SET_CMC_TBL_DATA_TXCNT_LMT_SEL(skb->data, 0);
3411 if (vif->type == NL80211_IFTYPE_STATION)
3412 SET_CMC_TBL_ULDL(skb->data, 1);
3413 else
3414 SET_CMC_TBL_ULDL(skb->data, 0);
3415 SET_CMC_TBL_MULTI_PORT_ID(skb->data, rtwvif_link->port);
3416 if (chip->h2c_cctl_func_id == H2C_FUNC_MAC_CCTLINFO_UD_V1) {
3417 SET_CMC_TBL_NOMINAL_PKT_PADDING_V1(skb->data, pads[RTW89_CHANNEL_WIDTH_20]);
3418 SET_CMC_TBL_NOMINAL_PKT_PADDING40_V1(skb->data, pads[RTW89_CHANNEL_WIDTH_40]);
3419 SET_CMC_TBL_NOMINAL_PKT_PADDING80_V1(skb->data, pads[RTW89_CHANNEL_WIDTH_80]);
3420 SET_CMC_TBL_NOMINAL_PKT_PADDING160_V1(skb->data, pads[RTW89_CHANNEL_WIDTH_160]);
3421 } else if (chip->h2c_cctl_func_id == H2C_FUNC_MAC_CCTLINFO_UD) {
3422 SET_CMC_TBL_NOMINAL_PKT_PADDING(skb->data, pads[RTW89_CHANNEL_WIDTH_20]);
3423 SET_CMC_TBL_NOMINAL_PKT_PADDING40(skb->data, pads[RTW89_CHANNEL_WIDTH_40]);
3424 SET_CMC_TBL_NOMINAL_PKT_PADDING80(skb->data, pads[RTW89_CHANNEL_WIDTH_80]);
3425 SET_CMC_TBL_NOMINAL_PKT_PADDING160(skb->data, pads[RTW89_CHANNEL_WIDTH_160]);
3426 }
3427 if (rtwsta_link)
3428 SET_CMC_TBL_BSR_QUEUE_SIZE_FORMAT(skb->data,
3429 link_sta->he_cap.has_he);
3430 if (rtwvif_link->net_type == RTW89_NET_TYPE_AP_MODE)
3431 SET_CMC_TBL_DATA_DCM(skb->data, 0);
3432
3433 rcu_read_unlock();
3434
3435 rtw89_h2c_pkt_set_hdr(rtwdev, skb, FWCMD_TYPE_H2C,
3436 H2C_CAT_MAC, H2C_CL_MAC_FR_EXCHG,
3437 chip->h2c_cctl_func_id, 0, 1,
3438 H2C_CMC_TBL_LEN);
3439
3440 ret = rtw89_h2c_tx(rtwdev, skb, false);
3441 if (ret) {
3442 rtw89_err(rtwdev, "failed to send h2c\n");
3443 goto fail;
3444 }
3445
3446 return 0;
3447 fail:
3448 dev_kfree_skb_any(skb);
3449
3450 return ret;
3451 }
3452 EXPORT_SYMBOL(rtw89_fw_h2c_assoc_cmac_tbl);
3453
3454 static void __get_sta_eht_pkt_padding(struct rtw89_dev *rtwdev,
3455 struct ieee80211_link_sta *link_sta,
3456 u8 *pads)
3457 {
3458 u8 nss = min(link_sta->rx_nss, rtwdev->hal.tx_nss) - 1;
3459 u16 ppe_thres_hdr;
3460 u8 ppe16, ppe8;
3461 u8 n, idx, sh;
3462 u8 ru_bitmap;
3463 bool ppe_th;
3464 u16 ppe;
3465 int i;
3466
3467 ppe_th = !!u8_get_bits(link_sta->eht_cap.eht_cap_elem.phy_cap_info[5],
3468 IEEE80211_EHT_PHY_CAP5_PPE_THRESHOLD_PRESENT);
3469 if (!ppe_th) {
3470 u8 pad;
3471
3472 pad = u8_get_bits(link_sta->eht_cap.eht_cap_elem.phy_cap_info[5],
3473 IEEE80211_EHT_PHY_CAP5_COMMON_NOMINAL_PKT_PAD_MASK);
3474
3475 for (i = 0; i < RTW89_PPE_BW_NUM; i++)
3476 pads[i] = pad;
3477
3478 return;
3479 }
3480
3481 ppe_thres_hdr = get_unaligned_le16(link_sta->eht_cap.eht_ppe_thres);
3482 ru_bitmap = u16_get_bits(ppe_thres_hdr,
3483 IEEE80211_EHT_PPE_THRES_RU_INDEX_BITMASK_MASK);
3484 n = hweight8(ru_bitmap);
3485 n = IEEE80211_EHT_PPE_THRES_INFO_HEADER_SIZE +
3486 (n * IEEE80211_EHT_PPE_THRES_INFO_PPET_SIZE * 2) * nss;
3487
3488 for (i = 0; i < RTW89_PPE_BW_NUM; i++) {
3489 if (!(ru_bitmap & BIT(i))) {
3490 pads[i] = 1;
3491 continue;
3492 }
3493
3494 idx = n >> 3;
3495 sh = n & 7;
3496 n += IEEE80211_EHT_PPE_THRES_INFO_PPET_SIZE * 2;
3497
3498 ppe = get_unaligned_le16(link_sta->eht_cap.eht_ppe_thres + idx);
3499 ppe16 = (ppe >> sh) & IEEE80211_PPE_THRES_NSS_MASK;
3500 sh += IEEE80211_EHT_PPE_THRES_INFO_PPET_SIZE;
3501 ppe8 = (ppe >> sh) & IEEE80211_PPE_THRES_NSS_MASK;
3502
3503 if (ppe16 != 7 && ppe8 == 7)
3504 pads[i] = RTW89_PE_DURATION_16_20;
3505 else if (ppe8 != 7)
3506 pads[i] = RTW89_PE_DURATION_8;
3507 else
3508 pads[i] = RTW89_PE_DURATION_0;
3509 }
3510 }
3511
3512 int rtw89_fw_h2c_assoc_cmac_tbl_g7(struct rtw89_dev *rtwdev,
3513 struct rtw89_vif_link *rtwvif_link,
3514 struct rtw89_sta_link *rtwsta_link)
3515 {
3516 struct ieee80211_vif *vif = rtwvif_link_to_vif(rtwvif_link);
3517 const struct rtw89_chan *chan = rtw89_chan_get(rtwdev, rtwvif_link->chanctx_idx);
3518 u8 mac_id = rtwsta_link ? rtwsta_link->mac_id : rtwvif_link->mac_id;
3519 struct rtw89_h2c_cctlinfo_ud_g7 *h2c;
3520 struct ieee80211_bss_conf *bss_conf;
3521 struct ieee80211_link_sta *link_sta;
3522 u8 pads[RTW89_PPE_BW_NUM];
3523 u32 len = sizeof(*h2c);
3524 struct sk_buff *skb;
3525 u16 lowest_rate;
3526 int ret;
3527
3528 memset(pads, 0, sizeof(pads));
3529
3530 skb = rtw89_fw_h2c_alloc_skb_with_hdr(rtwdev, len);
3531 if (!skb) {
3532 rtw89_err(rtwdev, "failed to alloc skb for cmac g7\n");
3533 return -ENOMEM;
3534 }
3535
3536 rcu_read_lock();
3537
3538 bss_conf = rtw89_vif_rcu_dereference_link(rtwvif_link, true);
3539
3540 if (rtwsta_link) {
3541 link_sta = rtw89_sta_rcu_dereference_link(rtwsta_link, true);
3542
3543 if (link_sta->eht_cap.has_eht)
3544 __get_sta_eht_pkt_padding(rtwdev, link_sta, pads);
3545 else if (link_sta->he_cap.has_he)
3546 __get_sta_he_pkt_padding(rtwdev, link_sta, pads);
3547 }
3548
3549 if (vif->p2p)
3550 lowest_rate = RTW89_HW_RATE_OFDM6;
3551 else if (chan->band_type == RTW89_BAND_2G)
3552 lowest_rate = RTW89_HW_RATE_CCK1;
3553 else
3554 lowest_rate = RTW89_HW_RATE_OFDM6;
3555
3556 skb_put(skb, len);
3557 h2c = (struct rtw89_h2c_cctlinfo_ud_g7 *)skb->data;
3558
3559 h2c->c0 = le32_encode_bits(mac_id, CCTLINFO_G7_C0_MACID) |
3560 le32_encode_bits(1, CCTLINFO_G7_C0_OP);
3561
3562 h2c->w0 = le32_encode_bits(1, CCTLINFO_G7_W0_DISRTSFB) |
3563 le32_encode_bits(1, CCTLINFO_G7_W0_DISDATAFB);
3564 h2c->m0 = cpu_to_le32(CCTLINFO_G7_W0_DISRTSFB |
3565 CCTLINFO_G7_W0_DISDATAFB);
3566
3567 h2c->w1 = le32_encode_bits(lowest_rate, CCTLINFO_G7_W1_RTS_RTY_LOWEST_RATE);
3568 h2c->m1 = cpu_to_le32(CCTLINFO_G7_W1_RTS_RTY_LOWEST_RATE);
3569
3570 h2c->w2 = le32_encode_bits(0, CCTLINFO_G7_W2_DATA_TXCNT_LMT_SEL);
3571 h2c->m2 = cpu_to_le32(CCTLINFO_G7_W2_DATA_TXCNT_LMT_SEL);
3572
3573 h2c->w3 = le32_encode_bits(0, CCTLINFO_G7_W3_RTS_TXCNT_LMT_SEL);
3574 h2c->m3 = cpu_to_le32(CCTLINFO_G7_W3_RTS_TXCNT_LMT_SEL);
3575
3576 h2c->w4 = le32_encode_bits(rtwvif_link->port, CCTLINFO_G7_W4_MULTI_PORT_ID);
3577 h2c->m4 = cpu_to_le32(CCTLINFO_G7_W4_MULTI_PORT_ID);
3578
3579 if (rtwvif_link->net_type == RTW89_NET_TYPE_AP_MODE) {
3580 h2c->w4 |= le32_encode_bits(0, CCTLINFO_G7_W4_DATA_DCM);
3581 h2c->m4 |= cpu_to_le32(CCTLINFO_G7_W4_DATA_DCM);
3582 }
3583
3584 if (bss_conf->eht_support) {
3585 u16 punct = bss_conf->chanreq.oper.punctured;
3586
3587 h2c->w4 |= le32_encode_bits(~punct,
3588 CCTLINFO_G7_W4_ACT_SUBCH_CBW);
3589 h2c->m4 |= cpu_to_le32(CCTLINFO_G7_W4_ACT_SUBCH_CBW);
3590 }
3591
3592 h2c->w5 = le32_encode_bits(pads[RTW89_CHANNEL_WIDTH_20],
3593 CCTLINFO_G7_W5_NOMINAL_PKT_PADDING0) |
3594 le32_encode_bits(pads[RTW89_CHANNEL_WIDTH_40],
3595 CCTLINFO_G7_W5_NOMINAL_PKT_PADDING1) |
3596 le32_encode_bits(pads[RTW89_CHANNEL_WIDTH_80],
3597 CCTLINFO_G7_W5_NOMINAL_PKT_PADDING2) |
3598 le32_encode_bits(pads[RTW89_CHANNEL_WIDTH_160],
3599 CCTLINFO_G7_W5_NOMINAL_PKT_PADDING3) |
3600 le32_encode_bits(pads[RTW89_CHANNEL_WIDTH_320],
3601 CCTLINFO_G7_W5_NOMINAL_PKT_PADDING4);
3602 h2c->m5 = cpu_to_le32(CCTLINFO_G7_W5_NOMINAL_PKT_PADDING0 |
3603 CCTLINFO_G7_W5_NOMINAL_PKT_PADDING1 |
3604 CCTLINFO_G7_W5_NOMINAL_PKT_PADDING2 |
3605 CCTLINFO_G7_W5_NOMINAL_PKT_PADDING3 |
3606 CCTLINFO_G7_W5_NOMINAL_PKT_PADDING4);
3607
3608 h2c->w6 = le32_encode_bits(vif->cfg.aid, CCTLINFO_G7_W6_AID12_PAID) |
3609 le32_encode_bits(vif->type == NL80211_IFTYPE_STATION ? 1 : 0,
3610 CCTLINFO_G7_W6_ULDL);
3611 h2c->m6 = cpu_to_le32(CCTLINFO_G7_W6_AID12_PAID | CCTLINFO_G7_W6_ULDL);
3612
3613 if (rtwsta_link) {
3614 h2c->w8 = le32_encode_bits(link_sta->he_cap.has_he,
3615 CCTLINFO_G7_W8_BSR_QUEUE_SIZE_FORMAT);
3616 h2c->m8 = cpu_to_le32(CCTLINFO_G7_W8_BSR_QUEUE_SIZE_FORMAT);
3617 }
3618
3619 rcu_read_unlock();
3620
3621 rtw89_h2c_pkt_set_hdr(rtwdev, skb, FWCMD_TYPE_H2C,
3622 H2C_CAT_MAC, H2C_CL_MAC_FR_EXCHG,
3623 H2C_FUNC_MAC_CCTLINFO_UD_G7, 0, 1,
3624 len);
3625
3626 ret = rtw89_h2c_tx(rtwdev, skb, false);
3627 if (ret) {
3628 rtw89_err(rtwdev, "failed to send h2c\n");
3629 goto fail;
3630 }
3631
3632 return 0;
3633 fail:
3634 dev_kfree_skb_any(skb);
3635
3636 return ret;
3637 }
3638 EXPORT_SYMBOL(rtw89_fw_h2c_assoc_cmac_tbl_g7);
3639
3640 int rtw89_fw_h2c_ampdu_cmac_tbl_g7(struct rtw89_dev *rtwdev,
3641 struct rtw89_vif_link *rtwvif_link,
3642 struct rtw89_sta_link *rtwsta_link)
3643 {
3644 struct rtw89_sta *rtwsta = rtwsta_link->rtwsta;
3645 struct rtw89_h2c_cctlinfo_ud_g7 *h2c;
3646 u32 len = sizeof(*h2c);
3647 struct sk_buff *skb;
3648 u16 agg_num = 0;
3649 u8 ba_bmap = 0;
3650 int ret;
3651 u8 tid;
3652
3653 skb = rtw89_fw_h2c_alloc_skb_with_hdr(rtwdev, len);
3654 if (!skb) {
3655 rtw89_err(rtwdev, "failed to alloc skb for ampdu cmac g7\n");
3656 return -ENOMEM;
3657 }
3658 skb_put(skb, len);
3659 h2c = (struct rtw89_h2c_cctlinfo_ud_g7 *)skb->data;
3660
3661 for_each_set_bit(tid, rtwsta->ampdu_map, IEEE80211_NUM_TIDS) {
3662 if (agg_num == 0)
3663 agg_num = rtwsta->ampdu_params[tid].agg_num;
3664 else
3665 agg_num = min(agg_num, rtwsta->ampdu_params[tid].agg_num);
3666 }
3667
3668 if (agg_num <= 0x20)
3669 ba_bmap = 3;
3670 else if (agg_num > 0x20 && agg_num <= 0x40)
3671 ba_bmap = 0;
3672 else if (agg_num > 0x40 && agg_num <= 0x80)
3673 ba_bmap = 1;
3674 else if (agg_num > 0x80 && agg_num <= 0x100)
3675 ba_bmap = 2;
3676 else if (agg_num > 0x100 && agg_num <= 0x200)
3677 ba_bmap = 4;
3678 else if (agg_num > 0x200 && agg_num <= 0x400)
3679 ba_bmap = 5;
3680
3681 h2c->c0 = le32_encode_bits(rtwsta_link->mac_id, CCTLINFO_G7_C0_MACID) |
3682 le32_encode_bits(1, CCTLINFO_G7_C0_OP);
3683
3684 h2c->w3 = le32_encode_bits(ba_bmap, CCTLINFO_G7_W3_BA_BMAP);
3685 h2c->m3 = cpu_to_le32(CCTLINFO_G7_W3_BA_BMAP);
3686
3687 rtw89_h2c_pkt_set_hdr(rtwdev, skb, FWCMD_TYPE_H2C,
3688 H2C_CAT_MAC, H2C_CL_MAC_FR_EXCHG,
3689 H2C_FUNC_MAC_CCTLINFO_UD_G7, 0, 0,
3690 len);
3691
3692 ret = rtw89_h2c_tx(rtwdev, skb, false);
3693 if (ret) {
3694 rtw89_err(rtwdev, "failed to send h2c\n");
3695 goto fail;
3696 }
3697
3698 return 0;
3699 fail:
3700 dev_kfree_skb_any(skb);
3701
3702 return ret;
3703 }
3704 EXPORT_SYMBOL(rtw89_fw_h2c_ampdu_cmac_tbl_g7);
3705
3706 int rtw89_fw_h2c_txtime_cmac_tbl(struct rtw89_dev *rtwdev,
3707 struct rtw89_sta_link *rtwsta_link)
3708 {
3709 const struct rtw89_chip_info *chip = rtwdev->chip;
3710 struct sk_buff *skb;
3711 int ret;
3712
3713 skb = rtw89_fw_h2c_alloc_skb_with_hdr(rtwdev, H2C_CMC_TBL_LEN);
3714 if (!skb) {
3715 rtw89_err(rtwdev, "failed to alloc skb for fw dl\n");
3716 return -ENOMEM;
3717 }
3718 skb_put(skb, H2C_CMC_TBL_LEN);
3719 SET_CTRL_INFO_MACID(skb->data, rtwsta_link->mac_id);
3720 SET_CTRL_INFO_OPERATION(skb->data, 1);
3721 if (rtwsta_link->cctl_tx_time) {
3722 SET_CMC_TBL_AMPDU_TIME_SEL(skb->data, 1);
3723 SET_CMC_TBL_AMPDU_MAX_TIME(skb->data, rtwsta_link->ampdu_max_time);
3724 }
3725 if (rtwsta_link->cctl_tx_retry_limit) {
3726 SET_CMC_TBL_DATA_TXCNT_LMT_SEL(skb->data, 1);
3727 SET_CMC_TBL_DATA_TX_CNT_LMT(skb->data, rtwsta_link->data_tx_cnt_lmt);
3728 }
3729
3730 rtw89_h2c_pkt_set_hdr(rtwdev, skb, FWCMD_TYPE_H2C,
3731 H2C_CAT_MAC, H2C_CL_MAC_FR_EXCHG,
3732 chip->h2c_cctl_func_id, 0, 1,
3733 H2C_CMC_TBL_LEN);
3734
3735 ret = rtw89_h2c_tx(rtwdev, skb, false);
3736 if (ret) {
3737 rtw89_err(rtwdev, "failed to send h2c\n");
3738 goto fail;
3739 }
3740
3741 return 0;
3742 fail:
3743 dev_kfree_skb_any(skb);
3744
3745 return ret;
3746 }
3747 EXPORT_SYMBOL(rtw89_fw_h2c_txtime_cmac_tbl);
3748
3749 int rtw89_fw_h2c_txtime_cmac_tbl_g7(struct rtw89_dev *rtwdev,
3750 struct rtw89_sta_link *rtwsta_link)
3751 {
3752 struct rtw89_h2c_cctlinfo_ud_g7 *h2c;
3753 u32 len = sizeof(*h2c);
3754 struct sk_buff *skb;
3755 int ret;
3756
3757 skb = rtw89_fw_h2c_alloc_skb_with_hdr(rtwdev, len);
3758 if (!skb) {
3759 rtw89_err(rtwdev, "failed to alloc skb for txtime_cmac_g7\n");
3760 return -ENOMEM;
3761 }
3762 skb_put(skb, len);
3763 h2c = (struct rtw89_h2c_cctlinfo_ud_g7 *)skb->data;
3764
3765 h2c->c0 = le32_encode_bits(rtwsta_link->mac_id, CCTLINFO_G7_C0_MACID) |
3766 le32_encode_bits(1, CCTLINFO_G7_C0_OP);
3767
3768 if (rtwsta_link->cctl_tx_time) {
3769 h2c->w3 |= le32_encode_bits(1, CCTLINFO_G7_W3_AMPDU_TIME_SEL);
3770 h2c->m3 |= cpu_to_le32(CCTLINFO_G7_W3_AMPDU_TIME_SEL);
3771
3772 h2c->w2 |= le32_encode_bits(rtwsta_link->ampdu_max_time,
3773 CCTLINFO_G7_W2_AMPDU_MAX_TIME);
3774 h2c->m2 |= cpu_to_le32(CCTLINFO_G7_W2_AMPDU_MAX_TIME);
3775 }
3776 if (rtwsta_link->cctl_tx_retry_limit) {
3777 h2c->w2 |= le32_encode_bits(1, CCTLINFO_G7_W2_DATA_TXCNT_LMT_SEL) |
3778 le32_encode_bits(rtwsta_link->data_tx_cnt_lmt,
3779 CCTLINFO_G7_W2_DATA_TX_CNT_LMT);
3780 h2c->m2 |= cpu_to_le32(CCTLINFO_G7_W2_DATA_TXCNT_LMT_SEL |
3781 CCTLINFO_G7_W2_DATA_TX_CNT_LMT);
3782 }
3783
3784 rtw89_h2c_pkt_set_hdr(rtwdev, skb, FWCMD_TYPE_H2C,
3785 H2C_CAT_MAC, H2C_CL_MAC_FR_EXCHG,
3786 H2C_FUNC_MAC_CCTLINFO_UD_G7, 0, 1,
3787 len);
3788
3789 ret = rtw89_h2c_tx(rtwdev, skb, false);
3790 if (ret) {
3791 rtw89_err(rtwdev, "failed to send h2c\n");
3792 goto fail;
3793 }
3794
3795 return 0;
3796 fail:
3797 dev_kfree_skb_any(skb);
3798
3799 return ret;
3800 }
3801 EXPORT_SYMBOL(rtw89_fw_h2c_txtime_cmac_tbl_g7);
3802
3803 int rtw89_fw_h2c_punctured_cmac_tbl_g7(struct rtw89_dev *rtwdev,
3804 struct rtw89_vif_link *rtwvif_link,
3805 u16 punctured)
3806 {
3807 struct rtw89_h2c_cctlinfo_ud_g7 *h2c;
3808 u32 len = sizeof(*h2c);
3809 struct sk_buff *skb;
3810 int ret;
3811
3812 skb = rtw89_fw_h2c_alloc_skb_with_hdr(rtwdev, len);
3813 if (!skb) {
3814 rtw89_err(rtwdev, "failed to alloc skb for punctured cmac g7\n");
3815 return -ENOMEM;
3816 }
3817
3818 skb_put(skb, len);
3819 h2c = (struct rtw89_h2c_cctlinfo_ud_g7 *)skb->data;
3820
3821 h2c->c0 = le32_encode_bits(rtwvif_link->mac_id, CCTLINFO_G7_C0_MACID) |
3822 le32_encode_bits(1, CCTLINFO_G7_C0_OP);
3823
3824 h2c->w4 = le32_encode_bits(~punctured, CCTLINFO_G7_W4_ACT_SUBCH_CBW);
3825 h2c->m4 = cpu_to_le32(CCTLINFO_G7_W4_ACT_SUBCH_CBW);
3826
3827 rtw89_h2c_pkt_set_hdr(rtwdev, skb, FWCMD_TYPE_H2C,
3828 H2C_CAT_MAC, H2C_CL_MAC_FR_EXCHG,
3829 H2C_FUNC_MAC_CCTLINFO_UD_G7, 0, 1,
3830 len);
3831
3832 ret = rtw89_h2c_tx(rtwdev, skb, false);
3833 if (ret) {
3834 rtw89_err(rtwdev, "failed to send h2c\n");
3835 goto fail;
3836 }
3837
3838 return 0;
3839 fail:
3840 dev_kfree_skb_any(skb);
3841
3842 return ret;
3843 }
3844 EXPORT_SYMBOL(rtw89_fw_h2c_punctured_cmac_tbl_g7);
3845
3846 int rtw89_fw_h2c_txpath_cmac_tbl(struct rtw89_dev *rtwdev,
3847 struct rtw89_sta_link *rtwsta_link)
3848 {
3849 const struct rtw89_chip_info *chip = rtwdev->chip;
3850 struct sk_buff *skb;
3851 int ret;
3852
3853 if (chip->h2c_cctl_func_id != H2C_FUNC_MAC_CCTLINFO_UD)
3854 return 0;
3855
3856 skb = rtw89_fw_h2c_alloc_skb_with_hdr(rtwdev, H2C_CMC_TBL_LEN);
3857 if (!skb) {
3858 rtw89_err(rtwdev, "failed to alloc skb for fw dl\n");
3859 return -ENOMEM;
3860 }
3861 skb_put(skb, H2C_CMC_TBL_LEN);
3862 SET_CTRL_INFO_MACID(skb->data, rtwsta_link->mac_id);
3863 SET_CTRL_INFO_OPERATION(skb->data, 1);
3864
3865 __rtw89_fw_h2c_set_tx_path(rtwdev, skb);
3866
3867 rtw89_h2c_pkt_set_hdr(rtwdev, skb, FWCMD_TYPE_H2C,
3868 H2C_CAT_MAC, H2C_CL_MAC_FR_EXCHG,
3869 H2C_FUNC_MAC_CCTLINFO_UD, 0, 1,
3870 H2C_CMC_TBL_LEN);
3871
3872 ret = rtw89_h2c_tx(rtwdev, skb, false);
3873 if (ret) {
3874 rtw89_err(rtwdev, "failed to send h2c\n");
3875 goto fail;
3876 }
3877
3878 return 0;
3879 fail:
3880 dev_kfree_skb_any(skb);
3881
3882 return ret;
3883 }
3884
3885 int rtw89_fw_h2c_update_beacon(struct rtw89_dev *rtwdev,
3886 struct rtw89_vif_link *rtwvif_link)
3887 {
3888 const struct rtw89_chan *chan = rtw89_chan_get(rtwdev,
3889 rtwvif_link->chanctx_idx);
3890 struct ieee80211_vif *vif = rtwvif_link_to_vif(rtwvif_link);
3891 struct rtw89_h2c_bcn_upd *h2c;
3892 struct sk_buff *skb_beacon;
3893 struct ieee80211_hdr *hdr;
3894 u32 len = sizeof(*h2c);
3895 struct sk_buff *skb;
3896 int bcn_total_len;
3897 u16 beacon_rate;
3898 u16 tim_offset;
3899 void *noa_data;
3900 u8 noa_len;
3901 int ret;
3902
3903 if (vif->p2p)
3904 beacon_rate = RTW89_HW_RATE_OFDM6;
3905 else if (chan->band_type == RTW89_BAND_2G)
3906 beacon_rate = RTW89_HW_RATE_CCK1;
3907 else
3908 beacon_rate = RTW89_HW_RATE_OFDM6;
3909
3910 skb_beacon = ieee80211_beacon_get_tim(rtwdev->hw, vif, &tim_offset,
3911 NULL, 0);
3912 if (!skb_beacon) {
3913 rtw89_err(rtwdev, "failed to get beacon skb\n");
3914 return -ENOMEM;
3915 }
3916
3917 noa_len = rtw89_p2p_noa_fetch(rtwvif_link, &noa_data);
3918 if (noa_len &&
3919 (noa_len <= skb_tailroom(skb_beacon) ||
3920 pskb_expand_head(skb_beacon, 0, noa_len, GFP_KERNEL) == 0)) {
3921 skb_put_data(skb_beacon, noa_data, noa_len);
3922 }
3923
3924 hdr = (struct ieee80211_hdr *)skb_beacon;
3925 tim_offset -= ieee80211_hdrlen(hdr->frame_control);
3926
3927 bcn_total_len = len + skb_beacon->len;
3928 skb = rtw89_fw_h2c_alloc_skb_with_hdr(rtwdev, bcn_total_len);
3929 if (!skb) {
3930 rtw89_err(rtwdev, "failed to alloc skb for fw dl\n");
3931 dev_kfree_skb_any(skb_beacon);
3932 return -ENOMEM;
3933 }
3934 skb_put(skb, len);
3935 h2c = (struct rtw89_h2c_bcn_upd *)skb->data;
3936
3937 h2c->w0 = le32_encode_bits(rtwvif_link->port, RTW89_H2C_BCN_UPD_W0_PORT) |
3938 le32_encode_bits(0, RTW89_H2C_BCN_UPD_W0_MBSSID) |
3939 le32_encode_bits(rtwvif_link->mac_idx, RTW89_H2C_BCN_UPD_W0_BAND) |
3940 le32_encode_bits(tim_offset | BIT(7), RTW89_H2C_BCN_UPD_W0_GRP_IE_OFST);
3941 h2c->w1 = le32_encode_bits(rtwvif_link->mac_id, RTW89_H2C_BCN_UPD_W1_MACID) |
3942 le32_encode_bits(RTW89_MGMT_HW_SSN_SEL, RTW89_H2C_BCN_UPD_W1_SSN_SEL) |
3943 le32_encode_bits(RTW89_MGMT_HW_SEQ_MODE, RTW89_H2C_BCN_UPD_W1_SSN_MODE) |
3944 le32_encode_bits(beacon_rate, RTW89_H2C_BCN_UPD_W1_RATE);
3945
3946 skb_put_data(skb, skb_beacon->data, skb_beacon->len);
3947 dev_kfree_skb_any(skb_beacon);
3948
3949 rtw89_h2c_pkt_set_hdr(rtwdev, skb, FWCMD_TYPE_H2C,
3950 H2C_CAT_MAC, H2C_CL_MAC_FR_EXCHG,
3951 H2C_FUNC_MAC_BCN_UPD, 0, 1,
3952 bcn_total_len);
3953
3954 ret = rtw89_h2c_tx(rtwdev, skb, false);
3955 if (ret) {
3956 rtw89_err(rtwdev, "failed to send h2c\n");
3957 dev_kfree_skb_any(skb);
3958 return ret;
3959 }
3960
3961 return 0;
3962 }
3963 EXPORT_SYMBOL(rtw89_fw_h2c_update_beacon);
3964
3965 int rtw89_fw_h2c_update_beacon_be(struct rtw89_dev *rtwdev,
3966 struct rtw89_vif_link *rtwvif_link)
3967 {
3968 const struct rtw89_chan *chan = rtw89_chan_get(rtwdev, rtwvif_link->chanctx_idx);
3969 struct ieee80211_vif *vif = rtwvif_link_to_vif(rtwvif_link);
3970 struct rtw89_h2c_bcn_upd_be *h2c;
3971 struct sk_buff *skb_beacon;
3972 struct ieee80211_hdr *hdr;
3973 u32 len = sizeof(*h2c);
3974 struct sk_buff *skb;
3975 int bcn_total_len;
3976 u16 beacon_rate;
3977 u16 tim_offset;
3978 void *noa_data;
3979 u8 noa_len;
3980 int ret;
3981
3982 if (vif->p2p)
3983 beacon_rate = RTW89_HW_RATE_OFDM6;
3984 else if (chan->band_type == RTW89_BAND_2G)
3985 beacon_rate = RTW89_HW_RATE_CCK1;
3986 else
3987 beacon_rate = RTW89_HW_RATE_OFDM6;
3988
3989 skb_beacon = ieee80211_beacon_get_tim(rtwdev->hw, vif, &tim_offset,
3990 NULL, 0);
3991 if (!skb_beacon) {
3992 rtw89_err(rtwdev, "failed to get beacon skb\n");
3993 return -ENOMEM;
3994 }
3995
3996 noa_len = rtw89_p2p_noa_fetch(rtwvif_link, &noa_data);
3997 if (noa_len &&
3998 (noa_len <= skb_tailroom(skb_beacon) ||
3999 pskb_expand_head(skb_beacon, 0, noa_len, GFP_KERNEL) == 0)) {
4000 skb_put_data(skb_beacon, noa_data, noa_len);
4001 }
4002
4003 hdr = (struct ieee80211_hdr *)skb_beacon;
4004 tim_offset -= ieee80211_hdrlen(hdr->frame_control);
4005
4006 bcn_total_len = len + skb_beacon->len;
4007 skb = rtw89_fw_h2c_alloc_skb_with_hdr(rtwdev, bcn_total_len);
4008 if (!skb) {
4009 rtw89_err(rtwdev, "failed to alloc skb for fw dl\n");
4010 dev_kfree_skb_any(skb_beacon);
4011 return -ENOMEM;
4012 }
4013 skb_put(skb, len);
4014 h2c = (struct rtw89_h2c_bcn_upd_be *)skb->data;
4015
4016 h2c->w0 = le32_encode_bits(rtwvif_link->port, RTW89_H2C_BCN_UPD_BE_W0_PORT) |
4017 le32_encode_bits(0, RTW89_H2C_BCN_UPD_BE_W0_MBSSID) |
4018 le32_encode_bits(rtwvif_link->mac_idx, RTW89_H2C_BCN_UPD_BE_W0_BAND) |
4019 le32_encode_bits(tim_offset | BIT(7), RTW89_H2C_BCN_UPD_BE_W0_GRP_IE_OFST);
4020 h2c->w1 = le32_encode_bits(rtwvif_link->mac_id, RTW89_H2C_BCN_UPD_BE_W1_MACID) |
4021 le32_encode_bits(RTW89_MGMT_HW_SSN_SEL, RTW89_H2C_BCN_UPD_BE_W1_SSN_SEL) |
4022 le32_encode_bits(RTW89_MGMT_HW_SEQ_MODE, RTW89_H2C_BCN_UPD_BE_W1_SSN_MODE) |
4023 le32_encode_bits(beacon_rate, RTW89_H2C_BCN_UPD_BE_W1_RATE);
4024
4025 skb_put_data(skb, skb_beacon->data, skb_beacon->len);
4026 dev_kfree_skb_any(skb_beacon);
4027
4028 rtw89_h2c_pkt_set_hdr(rtwdev, skb, FWCMD_TYPE_H2C,
4029 H2C_CAT_MAC, H2C_CL_MAC_FR_EXCHG,
4030 H2C_FUNC_MAC_BCN_UPD_BE, 0, 1,
4031 bcn_total_len);
4032
4033 ret = rtw89_h2c_tx(rtwdev, skb, false);
4034 if (ret) {
4035 rtw89_err(rtwdev, "failed to send h2c\n");
4036 goto fail;
4037 }
4038
4039 return 0;
4040
4041 fail:
4042 dev_kfree_skb_any(skb);
4043
4044 return ret;
4045 }
4046 EXPORT_SYMBOL(rtw89_fw_h2c_update_beacon_be);
4047
4048 int rtw89_fw_h2c_role_maintain(struct rtw89_dev *rtwdev,
4049 struct rtw89_vif_link *rtwvif_link,
4050 struct rtw89_sta_link *rtwsta_link,
4051 enum rtw89_upd_mode upd_mode)
4052 {
4053 u8 mac_id = rtwsta_link ? rtwsta_link->mac_id : rtwvif_link->mac_id;
4054 struct rtw89_h2c_role_maintain *h2c;
4055 u32 len = sizeof(*h2c);
4056 struct sk_buff *skb;
4057 u8 self_role;
4058 int ret;
4059
4060 if (rtwvif_link->net_type == RTW89_NET_TYPE_AP_MODE) {
4061 if (rtwsta_link)
4062 self_role = RTW89_SELF_ROLE_AP_CLIENT;
4063 else
4064 self_role = rtwvif_link->self_role;
4065 } else {
4066 self_role = rtwvif_link->self_role;
4067 }
4068
4069 skb = rtw89_fw_h2c_alloc_skb_with_hdr(rtwdev, len);
4070 if (!skb) {
4071 rtw89_err(rtwdev, "failed to alloc skb for h2c join\n");
4072 return -ENOMEM;
4073 }
4074 skb_put(skb, len);
4075 h2c = (struct rtw89_h2c_role_maintain *)skb->data;
4076
4077 h2c->w0 = le32_encode_bits(mac_id, RTW89_H2C_ROLE_MAINTAIN_W0_MACID) |
4078 le32_encode_bits(self_role, RTW89_H2C_ROLE_MAINTAIN_W0_SELF_ROLE) |
4079 le32_encode_bits(upd_mode, RTW89_H2C_ROLE_MAINTAIN_W0_UPD_MODE) |
4080 le32_encode_bits(rtwvif_link->wifi_role,
4081 RTW89_H2C_ROLE_MAINTAIN_W0_WIFI_ROLE) |
4082 le32_encode_bits(rtwvif_link->mac_idx,
4083 RTW89_H2C_ROLE_MAINTAIN_W0_BAND) |
4084 le32_encode_bits(rtwvif_link->port, RTW89_H2C_ROLE_MAINTAIN_W0_PORT);
4085
4086 rtw89_h2c_pkt_set_hdr(rtwdev, skb, FWCMD_TYPE_H2C,
4087 H2C_CAT_MAC, H2C_CL_MAC_MEDIA_RPT,
4088 H2C_FUNC_MAC_FWROLE_MAINTAIN, 0, 1,
4089 len);
4090
4091 ret = rtw89_h2c_tx(rtwdev, skb, false);
4092 if (ret) {
4093 rtw89_err(rtwdev, "failed to send h2c\n");
4094 goto fail;
4095 }
4096
4097 return 0;
4098 fail:
4099 dev_kfree_skb_any(skb);
4100
4101 return ret;
4102 }
4103
4104 static enum rtw89_fw_sta_type
4105 rtw89_fw_get_sta_type(struct rtw89_dev *rtwdev, struct rtw89_vif_link *rtwvif_link,
4106 struct rtw89_sta_link *rtwsta_link)
4107 {
4108 struct ieee80211_bss_conf *bss_conf;
4109 struct ieee80211_link_sta *link_sta;
4110 enum rtw89_fw_sta_type type;
4111
4112 rcu_read_lock();
4113
4114 if (!rtwsta_link)
4115 goto by_vif;
4116
4117 link_sta = rtw89_sta_rcu_dereference_link(rtwsta_link, true);
4118
4119 if (link_sta->eht_cap.has_eht)
4120 type = RTW89_FW_BE_STA;
4121 else if (link_sta->he_cap.has_he)
4122 type = RTW89_FW_AX_STA;
4123 else
4124 type = RTW89_FW_N_AC_STA;
4125
4126 goto out;
4127
4128 by_vif:
4129 bss_conf = rtw89_vif_rcu_dereference_link(rtwvif_link, true);
4130
4131 if (bss_conf->eht_support)
4132 type = RTW89_FW_BE_STA;
4133 else if (bss_conf->he_support)
4134 type = RTW89_FW_AX_STA;
4135 else
4136 type = RTW89_FW_N_AC_STA;
4137
4138 out:
4139 rcu_read_unlock();
4140
4141 return type;
4142 }
4143
4144 int rtw89_fw_h2c_join_info(struct rtw89_dev *rtwdev, struct rtw89_vif_link *rtwvif_link,
4145 struct rtw89_sta_link *rtwsta_link, bool dis_conn)
4146 {
4147 u8 mac_id = rtwsta_link ? rtwsta_link->mac_id : rtwvif_link->mac_id;
4148 struct ieee80211_vif *vif = rtwvif_link_to_vif(rtwvif_link);
4149 bool is_mld = ieee80211_vif_is_mld(vif);
4150 u8 self_role = rtwvif_link->self_role;
4151 enum rtw89_fw_sta_type sta_type;
4152 u8 net_type = rtwvif_link->net_type;
4153 struct rtw89_h2c_join_v1 *h2c_v1;
4154 struct rtw89_h2c_join *h2c;
4155 u32 len = sizeof(*h2c);
4156 bool format_v1 = false;
4157 struct sk_buff *skb;
4158 u8 main_mac_id;
4159 bool init_ps;
4160 int ret;
4161
4162 if (rtwdev->chip->chip_gen == RTW89_CHIP_BE) {
4163 len = sizeof(*h2c_v1);
4164 format_v1 = true;
4165 }
4166
4167 if (net_type == RTW89_NET_TYPE_AP_MODE && rtwsta_link) {
4168 self_role = RTW89_SELF_ROLE_AP_CLIENT;
4169 net_type = dis_conn ? RTW89_NET_TYPE_NO_LINK : net_type;
4170 }
4171
4172 skb = rtw89_fw_h2c_alloc_skb_with_hdr(rtwdev, len);
4173 if (!skb) {
4174 rtw89_err(rtwdev, "failed to alloc skb for h2c join\n");
4175 return -ENOMEM;
4176 }
4177 skb_put(skb, len);
4178 h2c = (struct rtw89_h2c_join *)skb->data;
4179
4180 h2c->w0 = le32_encode_bits(mac_id, RTW89_H2C_JOININFO_W0_MACID) |
4181 le32_encode_bits(dis_conn, RTW89_H2C_JOININFO_W0_OP) |
4182 le32_encode_bits(rtwvif_link->mac_idx, RTW89_H2C_JOININFO_W0_BAND) |
4183 le32_encode_bits(rtwvif_link->wmm, RTW89_H2C_JOININFO_W0_WMM) |
4184 le32_encode_bits(rtwvif_link->trigger, RTW89_H2C_JOININFO_W0_TGR) |
4185 le32_encode_bits(0, RTW89_H2C_JOININFO_W0_ISHESTA) |
4186 le32_encode_bits(0, RTW89_H2C_JOININFO_W0_DLBW) |
4187 le32_encode_bits(0, RTW89_H2C_JOININFO_W0_TF_MAC_PAD) |
4188 le32_encode_bits(0, RTW89_H2C_JOININFO_W0_DL_T_PE) |
4189 le32_encode_bits(rtwvif_link->port, RTW89_H2C_JOININFO_W0_PORT_ID) |
4190 le32_encode_bits(net_type, RTW89_H2C_JOININFO_W0_NET_TYPE) |
4191 le32_encode_bits(rtwvif_link->wifi_role,
4192 RTW89_H2C_JOININFO_W0_WIFI_ROLE) |
4193 le32_encode_bits(self_role, RTW89_H2C_JOININFO_W0_SELF_ROLE);
4194
4195 if (!format_v1)
4196 goto done;
4197
4198 h2c_v1 = (struct rtw89_h2c_join_v1 *)skb->data;
4199
4200 sta_type = rtw89_fw_get_sta_type(rtwdev, rtwvif_link, rtwsta_link);
4201 init_ps = rtwvif_link != rtw89_get_designated_link(rtwvif_link->rtwvif);
4202
4203 if (rtwsta_link)
4204 main_mac_id = rtw89_sta_get_main_macid(rtwsta_link->rtwsta);
4205 else
4206 main_mac_id = rtw89_vif_get_main_macid(rtwvif_link->rtwvif);
4207
4208 h2c_v1->w1 = le32_encode_bits(sta_type, RTW89_H2C_JOININFO_W1_STA_TYPE) |
4209 le32_encode_bits(is_mld, RTW89_H2C_JOININFO_W1_IS_MLD) |
4210 le32_encode_bits(main_mac_id, RTW89_H2C_JOININFO_W1_MAIN_MACID) |
4211 le32_encode_bits(RTW89_H2C_JOININFO_MLO_MODE_MLSR,
4212 RTW89_H2C_JOININFO_W1_MLO_MODE) |
4213 le32_encode_bits(0, RTW89_H2C_JOININFO_W1_EMLSR_CAB) |
4214 le32_encode_bits(0, RTW89_H2C_JOININFO_W1_NSTR_EN) |
4215 le32_encode_bits(init_ps, RTW89_H2C_JOININFO_W1_INIT_PWR_STATE) |
4216 le32_encode_bits(IEEE80211_EML_CAP_EMLSR_PADDING_DELAY_256US,
4217 RTW89_H2C_JOININFO_W1_EMLSR_PADDING) |
4218 le32_encode_bits(IEEE80211_EML_CAP_EMLSR_TRANSITION_DELAY_256US,
4219 RTW89_H2C_JOININFO_W1_EMLSR_TRANS_DELAY) |
4220 le32_encode_bits(0, RTW89_H2C_JOININFO_W2_MACID_EXT) |
4221 le32_encode_bits(0, RTW89_H2C_JOININFO_W2_MAIN_MACID_EXT);
4222
4223 h2c_v1->w2 = 0;
4224
4225 done:
4226 rtw89_h2c_pkt_set_hdr(rtwdev, skb, FWCMD_TYPE_H2C,
4227 H2C_CAT_MAC, H2C_CL_MAC_MEDIA_RPT,
4228 H2C_FUNC_MAC_JOININFO, 0, 1,
4229 len);
4230
4231 ret = rtw89_h2c_tx(rtwdev, skb, false);
4232 if (ret) {
4233 rtw89_err(rtwdev, "failed to send h2c\n");
4234 goto fail;
4235 }
4236
4237 return 0;
4238 fail:
4239 dev_kfree_skb_any(skb);
4240
4241 return ret;
4242 }
4243
4244 int rtw89_fw_h2c_notify_dbcc(struct rtw89_dev *rtwdev, bool en)
4245 {
4246 struct rtw89_h2c_notify_dbcc *h2c;
4247 u32 len = sizeof(*h2c);
4248 struct sk_buff *skb;
4249 int ret;
4250
4251 skb = rtw89_fw_h2c_alloc_skb_with_hdr(rtwdev, len);
4252 if (!skb) {
4253 rtw89_err(rtwdev, "failed to alloc skb for h2c notify dbcc\n");
4254 return -ENOMEM;
4255 }
4256 skb_put(skb, len);
4257 h2c = (struct rtw89_h2c_notify_dbcc *)skb->data;
4258
4259 h2c->w0 = le32_encode_bits(en, RTW89_H2C_NOTIFY_DBCC_EN);
4260
4261 rtw89_h2c_pkt_set_hdr(rtwdev, skb, FWCMD_TYPE_H2C,
4262 H2C_CAT_MAC, H2C_CL_MAC_MEDIA_RPT,
4263 H2C_FUNC_NOTIFY_DBCC, 0, 1,
4264 len);
4265
4266 ret = rtw89_h2c_tx(rtwdev, skb, false);
4267 if (ret) {
4268 rtw89_err(rtwdev, "failed to send h2c\n");
4269 goto fail;
4270 }
4271
4272 return 0;
4273 fail:
4274 dev_kfree_skb_any(skb);
4275
4276 return ret;
4277 }
4278
4279 int rtw89_fw_h2c_macid_pause(struct rtw89_dev *rtwdev, u8 sh, u8 grp,
4280 bool pause)
4281 {
4282 struct rtw89_fw_macid_pause_sleep_grp *h2c_new;
4283 struct rtw89_fw_macid_pause_grp *h2c;
4284 __le32 set = cpu_to_le32(BIT(sh));
4285 u8 h2c_macid_pause_id;
4286 struct sk_buff *skb;
4287 u32 len;
4288 int ret;
4289
4290 if (RTW89_CHK_FW_FEATURE(MACID_PAUSE_SLEEP, &rtwdev->fw)) {
4291 h2c_macid_pause_id = H2C_FUNC_MAC_MACID_PAUSE_SLEEP;
4292 len = sizeof(*h2c_new);
4293 } else {
4294 h2c_macid_pause_id = H2C_FUNC_MAC_MACID_PAUSE;
4295 len = sizeof(*h2c);
4296 }
4297
4298 skb = rtw89_fw_h2c_alloc_skb_with_hdr(rtwdev, len);
4299 if (!skb) {
4300 rtw89_err(rtwdev, "failed to alloc skb for h2c macid pause\n");
4301 return -ENOMEM;
4302 }
4303 skb_put(skb, len);
4304
4305 if (h2c_macid_pause_id == H2C_FUNC_MAC_MACID_PAUSE_SLEEP) {
4306 h2c_new = (struct rtw89_fw_macid_pause_sleep_grp *)skb->data;
4307
4308 h2c_new->n[0].pause_mask_grp[grp] = set;
4309 h2c_new->n[0].sleep_mask_grp[grp] = set;
4310 if (pause) {
4311 h2c_new->n[0].pause_grp[grp] = set;
4312 h2c_new->n[0].sleep_grp[grp] = set;
4313 }
4314 } else {
4315 h2c = (struct rtw89_fw_macid_pause_grp *)skb->data;
4316
4317 h2c->mask_grp[grp] = set;
4318 if (pause)
4319 h2c->pause_grp[grp] = set;
4320 }
4321
4322 rtw89_h2c_pkt_set_hdr(rtwdev, skb, FWCMD_TYPE_H2C,
4323 H2C_CAT_MAC, H2C_CL_MAC_FW_OFLD,
4324 h2c_macid_pause_id, 1, 0,
4325 len);
4326
4327 ret = rtw89_h2c_tx(rtwdev, skb, false);
4328 if (ret) {
4329 rtw89_err(rtwdev, "failed to send h2c\n");
4330 goto fail;
4331 }
4332
4333 return 0;
4334 fail:
4335 dev_kfree_skb_any(skb);
4336
4337 return ret;
4338 }
4339
4340 #define H2C_EDCA_LEN 12
4341 int rtw89_fw_h2c_set_edca(struct rtw89_dev *rtwdev, struct rtw89_vif_link *rtwvif_link,
4342 u8 ac, u32 val)
4343 {
4344 struct sk_buff *skb;
4345 int ret;
4346
4347 skb = rtw89_fw_h2c_alloc_skb_with_hdr(rtwdev, H2C_EDCA_LEN);
4348 if (!skb) {
4349 rtw89_err(rtwdev, "failed to alloc skb for h2c edca\n");
4350 return -ENOMEM;
4351 }
4352 skb_put(skb, H2C_EDCA_LEN);
4353 RTW89_SET_EDCA_SEL(skb->data, 0);
4354 RTW89_SET_EDCA_BAND(skb->data, rtwvif_link->mac_idx);
4355 RTW89_SET_EDCA_WMM(skb->data, 0);
4356 RTW89_SET_EDCA_AC(skb->data, ac);
4357 RTW89_SET_EDCA_PARAM(skb->data, val);
4358
4359 rtw89_h2c_pkt_set_hdr(rtwdev, skb, FWCMD_TYPE_H2C,
4360 H2C_CAT_MAC, H2C_CL_MAC_FW_OFLD,
4361 H2C_FUNC_USR_EDCA, 0, 1,
4362 H2C_EDCA_LEN);
4363
4364 ret = rtw89_h2c_tx(rtwdev, skb, false);
4365 if (ret) {
4366 rtw89_err(rtwdev, "failed to send h2c\n");
4367 goto fail;
4368 }
4369
4370 return 0;
4371 fail:
4372 dev_kfree_skb_any(skb);
4373
4374 return ret;
4375 }
4376
4377 #define H2C_TSF32_TOGL_LEN 4
4378 int rtw89_fw_h2c_tsf32_toggle(struct rtw89_dev *rtwdev,
4379 struct rtw89_vif_link *rtwvif_link,
4380 bool en)
4381 {
4382 struct sk_buff *skb;
4383 u16 early_us = en ? 2000 : 0;
4384 u8 *cmd;
4385 int ret;
4386
4387 skb = rtw89_fw_h2c_alloc_skb_with_hdr(rtwdev, H2C_TSF32_TOGL_LEN);
4388 if (!skb) {
4389 rtw89_err(rtwdev, "failed to alloc skb for h2c p2p act\n");
4390 return -ENOMEM;
4391 }
4392 skb_put(skb, H2C_TSF32_TOGL_LEN);
4393 cmd = skb->data;
4394
4395 RTW89_SET_FWCMD_TSF32_TOGL_BAND(cmd, rtwvif_link->mac_idx);
4396 RTW89_SET_FWCMD_TSF32_TOGL_EN(cmd, en);
4397 RTW89_SET_FWCMD_TSF32_TOGL_PORT(cmd, rtwvif_link->port);
4398 RTW89_SET_FWCMD_TSF32_TOGL_EARLY(cmd, early_us);
4399
4400 rtw89_h2c_pkt_set_hdr(rtwdev, skb, FWCMD_TYPE_H2C,
4401 H2C_CAT_MAC, H2C_CL_MAC_FW_OFLD,
4402 H2C_FUNC_TSF32_TOGL, 0, 0,
4403 H2C_TSF32_TOGL_LEN);
4404
4405 ret = rtw89_h2c_tx(rtwdev, skb, false);
4406 if (ret) {
4407 rtw89_err(rtwdev, "failed to send h2c\n");
4408 goto fail;
4409 }
4410
4411 return 0;
4412 fail:
4413 dev_kfree_skb_any(skb);
4414
4415 return ret;
4416 }
4417
4418 #define H2C_OFLD_CFG_LEN 8
4419 int rtw89_fw_h2c_set_ofld_cfg(struct rtw89_dev *rtwdev)
4420 {
4421 static const u8 cfg[] = {0x09, 0x00, 0x00, 0x00, 0x5e, 0x00, 0x00, 0x00};
4422 struct sk_buff *skb;
4423 int ret;
4424
4425 skb = rtw89_fw_h2c_alloc_skb_with_hdr(rtwdev, H2C_OFLD_CFG_LEN);
4426 if (!skb) {
4427 rtw89_err(rtwdev, "failed to alloc skb for h2c ofld\n");
4428 return -ENOMEM;
4429 }
4430 skb_put_data(skb, cfg, H2C_OFLD_CFG_LEN);
4431
4432 rtw89_h2c_pkt_set_hdr(rtwdev, skb, FWCMD_TYPE_H2C,
4433 H2C_CAT_MAC, H2C_CL_MAC_FW_OFLD,
4434 H2C_FUNC_OFLD_CFG, 0, 1,
4435 H2C_OFLD_CFG_LEN);
4436
4437 ret = rtw89_h2c_tx(rtwdev, skb, false);
4438 if (ret) {
4439 rtw89_err(rtwdev, "failed to send h2c\n");
4440 goto fail;
4441 }
4442
4443 return 0;
4444 fail:
4445 dev_kfree_skb_any(skb);
4446
4447 return ret;
4448 }
4449
4450 int rtw89_fw_h2c_tx_duty(struct rtw89_dev *rtwdev, u8 lv)
4451 {
4452 struct rtw89_h2c_tx_duty *h2c;
4453 u32 len = sizeof(*h2c);
4454 struct sk_buff *skb;
4455 u16 pause, active;
4456 int ret;
4457
4458 skb = rtw89_fw_h2c_alloc_skb_with_hdr(rtwdev, len);
4459 if (!skb) {
4460 rtw89_err(rtwdev, "failed to alloc skb for h2c tx duty\n");
4461 return -ENOMEM;
4462 }
4463
4464 skb_put(skb, len);
4465 h2c = (struct rtw89_h2c_tx_duty *)skb->data;
4466
4467 static_assert(RTW89_THERMAL_PROT_LV_MAX * RTW89_THERMAL_PROT_STEP < 100);
4468
4469 if (lv == 0 || lv > RTW89_THERMAL_PROT_LV_MAX) {
4470 h2c->w1 = le32_encode_bits(1, RTW89_H2C_TX_DUTY_W1_STOP);
4471 } else {
4472 active = 100 - lv * RTW89_THERMAL_PROT_STEP;
4473 pause = 100 - active;
4474
4475 h2c->w0 = le32_encode_bits(pause, RTW89_H2C_TX_DUTY_W0_PAUSE_INTVL_MASK) |
4476 le32_encode_bits(active, RTW89_H2C_TX_DUTY_W0_TX_INTVL_MASK);
4477 }
4478
4479 rtw89_h2c_pkt_set_hdr(rtwdev, skb, FWCMD_TYPE_H2C,
4480 H2C_CAT_MAC, H2C_CL_MAC_FW_OFLD,
4481 H2C_FUNC_TX_DUTY, 0, 0, len);
4482
4483 ret = rtw89_h2c_tx(rtwdev, skb, false);
4484 if (ret) {
4485 rtw89_err(rtwdev, "failed to send h2c\n");
4486 goto fail;
4487 }
4488
4489 return 0;
4490 fail:
4491 dev_kfree_skb_any(skb);
4492
4493 return ret;
4494 }
4495
4496 int rtw89_fw_h2c_set_bcn_fltr_cfg(struct rtw89_dev *rtwdev,
4497 struct rtw89_vif_link *rtwvif_link,
4498 bool connect)
4499 {
4500 struct ieee80211_bss_conf *bss_conf;
4501 s32 thold = RTW89_DEFAULT_CQM_THOLD;
4502 u32 hyst = RTW89_DEFAULT_CQM_HYST;
4503 struct rtw89_h2c_bcnfltr *h2c;
4504 u32 len = sizeof(*h2c);
4505 struct sk_buff *skb;
4506 u8 max_cnt, cnt;
4507 int ret;
4508
4509 if (!RTW89_CHK_FW_FEATURE(BEACON_FILTER, &rtwdev->fw))
4510 return -EINVAL;
4511
4512 if (!rtwvif_link || rtwvif_link->net_type != RTW89_NET_TYPE_INFRA)
4513 return -EINVAL;
4514
4515 rcu_read_lock();
4516
4517 bss_conf = rtw89_vif_rcu_dereference_link(rtwvif_link, false);
4518
4519 if (bss_conf->cqm_rssi_hyst)
4520 hyst = bss_conf->cqm_rssi_hyst;
4521 if (bss_conf->cqm_rssi_thold)
4522 thold = bss_conf->cqm_rssi_thold;
4523
4524 rcu_read_unlock();
4525
4526 skb = rtw89_fw_h2c_alloc_skb_with_hdr(rtwdev, len);
4527 if (!skb) {
4528 rtw89_err(rtwdev, "failed to alloc skb for h2c bcn filter\n");
4529 return -ENOMEM;
4530 }
4531
4532 skb_put(skb, len);
4533 h2c = (struct rtw89_h2c_bcnfltr *)skb->data;
4534
4535 if (RTW89_CHK_FW_FEATURE(BEACON_LOSS_COUNT_V1, &rtwdev->fw))
4536 max_cnt = BIT(7) - 1;
4537 else
4538 max_cnt = BIT(4) - 1;
4539
4540 cnt = min(RTW89_BCN_LOSS_CNT, max_cnt);
4541
4542 h2c->w0 = le32_encode_bits(connect, RTW89_H2C_BCNFLTR_W0_MON_RSSI) |
4543 le32_encode_bits(connect, RTW89_H2C_BCNFLTR_W0_MON_BCN) |
4544 le32_encode_bits(connect, RTW89_H2C_BCNFLTR_W0_MON_EN) |
4545 le32_encode_bits(RTW89_BCN_FLTR_OFFLOAD_MODE_DEFAULT,
4546 RTW89_H2C_BCNFLTR_W0_MODE) |
4547 le32_encode_bits(cnt >> 4, RTW89_H2C_BCNFLTR_W0_BCN_LOSS_CNT_H3) |
4548 le32_encode_bits(cnt & 0xf, RTW89_H2C_BCNFLTR_W0_BCN_LOSS_CNT_L4) |
4549 le32_encode_bits(hyst, RTW89_H2C_BCNFLTR_W0_RSSI_HYST) |
4550 le32_encode_bits(thold + MAX_RSSI,
4551 RTW89_H2C_BCNFLTR_W0_RSSI_THRESHOLD) |
4552 le32_encode_bits(rtwvif_link->mac_id, RTW89_H2C_BCNFLTR_W0_MAC_ID);
4553
4554 rtw89_h2c_pkt_set_hdr(rtwdev, skb, FWCMD_TYPE_H2C,
4555 H2C_CAT_MAC, H2C_CL_MAC_FW_OFLD,
4556 H2C_FUNC_CFG_BCNFLTR, 0, 1, len);
4557
4558 ret = rtw89_h2c_tx(rtwdev, skb, false);
4559 if (ret) {
4560 rtw89_err(rtwdev, "failed to send h2c\n");
4561 goto fail;
4562 }
4563
4564 return 0;
4565 fail:
4566 dev_kfree_skb_any(skb);
4567
4568 return ret;
4569 }
4570
4571 int rtw89_fw_h2c_rssi_offload(struct rtw89_dev *rtwdev,
4572 struct rtw89_rx_phy_ppdu *phy_ppdu)
4573 {
4574 struct rtw89_h2c_ofld_rssi *h2c;
4575 u32 len = sizeof(*h2c);
4576 struct sk_buff *skb;
4577 s8 rssi;
4578 int ret;
4579
4580 if (!RTW89_CHK_FW_FEATURE(BEACON_FILTER, &rtwdev->fw))
4581 return -EINVAL;
4582
4583 if (!phy_ppdu)
4584 return -EINVAL;
4585
4586 skb = rtw89_fw_h2c_alloc_skb_with_hdr(rtwdev, len);
4587 if (!skb) {
4588 rtw89_err(rtwdev, "failed to alloc skb for h2c rssi\n");
4589 return -ENOMEM;
4590 }
4591
4592 rssi = phy_ppdu->rssi_avg >> RSSI_FACTOR;
4593 skb_put(skb, len);
4594 h2c = (struct rtw89_h2c_ofld_rssi *)skb->data;
4595
4596 h2c->w0 = le32_encode_bits(phy_ppdu->mac_id, RTW89_H2C_OFLD_RSSI_W0_MACID) |
4597 le32_encode_bits(1, RTW89_H2C_OFLD_RSSI_W0_NUM);
4598 h2c->w1 = le32_encode_bits(rssi, RTW89_H2C_OFLD_RSSI_W1_VAL);
4599
4600 rtw89_h2c_pkt_set_hdr(rtwdev, skb, FWCMD_TYPE_H2C,
4601 H2C_CAT_MAC, H2C_CL_MAC_FW_OFLD,
4602 H2C_FUNC_OFLD_RSSI, 0, 1, len);
4603
4604 ret = rtw89_h2c_tx(rtwdev, skb, false);
4605 if (ret) {
4606 rtw89_err(rtwdev, "failed to send h2c\n");
4607 goto fail;
4608 }
4609
4610 return 0;
4611 fail:
4612 dev_kfree_skb_any(skb);
4613
4614 return ret;
4615 }
4616
4617 int rtw89_fw_h2c_tp_offload(struct rtw89_dev *rtwdev, struct rtw89_vif_link *rtwvif_link)
4618 {
4619 struct rtw89_vif *rtwvif = rtwvif_link->rtwvif;
4620 struct rtw89_traffic_stats *stats = &rtwvif->stats;
4621 struct rtw89_h2c_ofld *h2c;
4622 u32 len = sizeof(*h2c);
4623 struct sk_buff *skb;
4624 int ret;
4625
4626 if (rtwvif_link->net_type != RTW89_NET_TYPE_INFRA)
4627 return -EINVAL;
4628
4629 skb = rtw89_fw_h2c_alloc_skb_with_hdr(rtwdev, len);
4630 if (!skb) {
4631 rtw89_err(rtwdev, "failed to alloc skb for h2c tp\n");
4632 return -ENOMEM;
4633 }
4634
4635 skb_put(skb, len);
4636 h2c = (struct rtw89_h2c_ofld *)skb->data;
4637
4638 h2c->w0 = le32_encode_bits(rtwvif_link->mac_id, RTW89_H2C_OFLD_W0_MAC_ID) |
4639 le32_encode_bits(stats->tx_throughput, RTW89_H2C_OFLD_W0_TX_TP) |
4640 le32_encode_bits(stats->rx_throughput, RTW89_H2C_OFLD_W0_RX_TP);
4641
4642 rtw89_h2c_pkt_set_hdr(rtwdev, skb, FWCMD_TYPE_H2C,
4643 H2C_CAT_MAC, H2C_CL_MAC_FW_OFLD,
4644 H2C_FUNC_OFLD_TP, 0, 1, len);
4645
4646 ret = rtw89_h2c_tx(rtwdev, skb, false);
4647 if (ret) {
4648 rtw89_err(rtwdev, "failed to send h2c\n");
4649 goto fail;
4650 }
4651
4652 return 0;
4653 fail:
4654 dev_kfree_skb_any(skb);
4655
4656 return ret;
4657 }
4658
4659 int rtw89_fw_h2c_ra(struct rtw89_dev *rtwdev, struct rtw89_ra_info *ra, bool csi)
4660 {
4661 const struct rtw89_chip_info *chip = rtwdev->chip;
4662 struct rtw89_h2c_ra_v1 *h2c_v1;
4663 struct rtw89_h2c_ra *h2c;
4664 u32 len = sizeof(*h2c);
4665 bool format_v1 = false;
4666 struct sk_buff *skb;
4667 int ret;
4668
4669 if (chip->chip_gen == RTW89_CHIP_BE) {
4670 len = sizeof(*h2c_v1);
4671 format_v1 = true;
4672 }
4673
4674 skb = rtw89_fw_h2c_alloc_skb_with_hdr(rtwdev, len);
4675 if (!skb) {
4676 rtw89_err(rtwdev, "failed to alloc skb for h2c join\n");
4677 return -ENOMEM;
4678 }
4679 skb_put(skb, len);
4680 h2c = (struct rtw89_h2c_ra *)skb->data;
4681 rtw89_debug(rtwdev, RTW89_DBG_RA,
4682 #if defined(__linux__)
4683 "ra cmd msk: %llx ", ra->ra_mask);
4684 #elif defined(__FreeBSD__)
4685 "ra cmd msk: %jx ", (uintmax_t)ra->ra_mask);
4686 #endif
4687
4688 h2c->w0 = le32_encode_bits(ra->mode_ctrl, RTW89_H2C_RA_W0_MODE) |
4689 le32_encode_bits(ra->bw_cap, RTW89_H2C_RA_W0_BW_CAP) |
4690 le32_encode_bits(ra->macid, RTW89_H2C_RA_W0_MACID) |
4691 le32_encode_bits(ra->dcm_cap, RTW89_H2C_RA_W0_DCM) |
4692 le32_encode_bits(ra->er_cap, RTW89_H2C_RA_W0_ER) |
4693 le32_encode_bits(ra->init_rate_lv, RTW89_H2C_RA_W0_INIT_RATE_LV) |
4694 le32_encode_bits(ra->upd_all, RTW89_H2C_RA_W0_UPD_ALL) |
4695 le32_encode_bits(ra->en_sgi, RTW89_H2C_RA_W0_SGI) |
4696 le32_encode_bits(ra->ldpc_cap, RTW89_H2C_RA_W0_LDPC) |
4697 le32_encode_bits(ra->stbc_cap, RTW89_H2C_RA_W0_STBC) |
4698 le32_encode_bits(ra->ss_num, RTW89_H2C_RA_W0_SS_NUM) |
4699 le32_encode_bits(ra->giltf, RTW89_H2C_RA_W0_GILTF) |
4700 le32_encode_bits(ra->upd_bw_nss_mask, RTW89_H2C_RA_W0_UPD_BW_NSS_MASK) |
4701 le32_encode_bits(ra->upd_mask, RTW89_H2C_RA_W0_UPD_MASK);
4702 h2c->w1 = le32_encode_bits(ra->ra_mask, RTW89_H2C_RA_W1_RAMASK_LO32);
4703 h2c->w2 = le32_encode_bits(ra->ra_mask >> 32, RTW89_H2C_RA_W2_RAMASK_HI32);
4704 h2c->w3 = le32_encode_bits(ra->fix_giltf_en, RTW89_H2C_RA_W3_FIX_GILTF_EN) |
4705 le32_encode_bits(ra->fix_giltf, RTW89_H2C_RA_W3_FIX_GILTF);
4706
4707 if (!format_v1)
4708 goto csi;
4709
4710 h2c_v1 = (struct rtw89_h2c_ra_v1 *)h2c;
4711 h2c_v1->w4 = le32_encode_bits(ra->mode_ctrl, RTW89_H2C_RA_V1_W4_MODE_EHT) |
4712 le32_encode_bits(ra->bw_cap, RTW89_H2C_RA_V1_W4_BW_EHT);
4713
4714 csi:
4715 if (!csi)
4716 goto done;
4717
4718 h2c->w2 |= le32_encode_bits(1, RTW89_H2C_RA_W2_BFEE_CSI_CTL);
4719 h2c->w3 |= le32_encode_bits(ra->band_num, RTW89_H2C_RA_W3_BAND_NUM) |
4720 le32_encode_bits(ra->cr_tbl_sel, RTW89_H2C_RA_W3_CR_TBL_SEL) |
4721 le32_encode_bits(ra->fixed_csi_rate_en, RTW89_H2C_RA_W3_FIXED_CSI_RATE_EN) |
4722 le32_encode_bits(ra->ra_csi_rate_en, RTW89_H2C_RA_W3_RA_CSI_RATE_EN) |
4723 le32_encode_bits(ra->csi_mcs_ss_idx, RTW89_H2C_RA_W3_FIXED_CSI_MCS_SS_IDX) |
4724 le32_encode_bits(ra->csi_mode, RTW89_H2C_RA_W3_FIXED_CSI_MODE) |
4725 le32_encode_bits(ra->csi_gi_ltf, RTW89_H2C_RA_W3_FIXED_CSI_GI_LTF) |
4726 le32_encode_bits(ra->csi_bw, RTW89_H2C_RA_W3_FIXED_CSI_BW);
4727
4728 done:
4729 rtw89_h2c_pkt_set_hdr(rtwdev, skb, FWCMD_TYPE_H2C,
4730 H2C_CAT_OUTSRC, H2C_CL_OUTSRC_RA,
4731 H2C_FUNC_OUTSRC_RA_MACIDCFG, 0, 0,
4732 len);
4733
4734 ret = rtw89_h2c_tx(rtwdev, skb, false);
4735 if (ret) {
4736 rtw89_err(rtwdev, "failed to send h2c\n");
4737 goto fail;
4738 }
4739
4740 return 0;
4741 fail:
4742 dev_kfree_skb_any(skb);
4743
4744 return ret;
4745 }
4746
4747 int rtw89_fw_h2c_cxdrv_init(struct rtw89_dev *rtwdev, u8 type)
4748 {
4749 struct rtw89_btc *btc = &rtwdev->btc;
4750 struct rtw89_btc_dm *dm = &btc->dm;
4751 struct rtw89_btc_init_info *init_info = &dm->init_info.init;
4752 struct rtw89_btc_module *module = &init_info->module;
4753 struct rtw89_btc_ant_info *ant = &module->ant;
4754 struct rtw89_h2c_cxinit *h2c;
4755 u32 len = sizeof(*h2c);
4756 struct sk_buff *skb;
4757 int ret;
4758
4759 skb = rtw89_fw_h2c_alloc_skb_with_hdr(rtwdev, len);
4760 if (!skb) {
4761 rtw89_err(rtwdev, "failed to alloc skb for h2c cxdrv_init\n");
4762 return -ENOMEM;
4763 }
4764 skb_put(skb, len);
4765 h2c = (struct rtw89_h2c_cxinit *)skb->data;
4766
4767 h2c->hdr.type = type;
4768 h2c->hdr.len = len - H2C_LEN_CXDRVHDR;
4769
4770 h2c->ant_type = ant->type;
4771 h2c->ant_num = ant->num;
4772 h2c->ant_iso = ant->isolation;
4773 h2c->ant_info =
4774 u8_encode_bits(ant->single_pos, RTW89_H2C_CXINIT_ANT_INFO_POS) |
4775 u8_encode_bits(ant->diversity, RTW89_H2C_CXINIT_ANT_INFO_DIVERSITY) |
4776 u8_encode_bits(ant->btg_pos, RTW89_H2C_CXINIT_ANT_INFO_BTG_POS) |
4777 u8_encode_bits(ant->stream_cnt, RTW89_H2C_CXINIT_ANT_INFO_STREAM_CNT);
4778
4779 h2c->mod_rfe = module->rfe_type;
4780 h2c->mod_cv = module->cv;
4781 h2c->mod_info =
4782 u8_encode_bits(module->bt_solo, RTW89_H2C_CXINIT_MOD_INFO_BT_SOLO) |
4783 u8_encode_bits(module->bt_pos, RTW89_H2C_CXINIT_MOD_INFO_BT_POS) |
4784 u8_encode_bits(module->switch_type, RTW89_H2C_CXINIT_MOD_INFO_SW_TYPE) |
4785 u8_encode_bits(module->wa_type, RTW89_H2C_CXINIT_MOD_INFO_WA_TYPE);
4786 h2c->mod_adie_kt = module->kt_ver_adie;
4787 h2c->wl_gch = init_info->wl_guard_ch;
4788
4789 h2c->info =
4790 u8_encode_bits(init_info->wl_only, RTW89_H2C_CXINIT_INFO_WL_ONLY) |
4791 u8_encode_bits(init_info->wl_init_ok, RTW89_H2C_CXINIT_INFO_WL_INITOK) |
4792 u8_encode_bits(init_info->dbcc_en, RTW89_H2C_CXINIT_INFO_DBCC_EN) |
4793 u8_encode_bits(init_info->cx_other, RTW89_H2C_CXINIT_INFO_CX_OTHER) |
4794 u8_encode_bits(init_info->bt_only, RTW89_H2C_CXINIT_INFO_BT_ONLY);
4795
4796 rtw89_h2c_pkt_set_hdr(rtwdev, skb, FWCMD_TYPE_H2C,
4797 H2C_CAT_OUTSRC, BTFC_SET,
4798 SET_DRV_INFO, 0, 0,
4799 len);
4800
4801 ret = rtw89_h2c_tx(rtwdev, skb, false);
4802 if (ret) {
4803 rtw89_err(rtwdev, "failed to send h2c\n");
4804 goto fail;
4805 }
4806
4807 return 0;
4808 fail:
4809 dev_kfree_skb_any(skb);
4810
4811 return ret;
4812 }
4813
4814 int rtw89_fw_h2c_cxdrv_init_v7(struct rtw89_dev *rtwdev, u8 type)
4815 {
4816 struct rtw89_btc *btc = &rtwdev->btc;
4817 struct rtw89_btc_dm *dm = &btc->dm;
4818 struct rtw89_btc_init_info_v7 *init_info = &dm->init_info.init_v7;
4819 struct rtw89_h2c_cxinit_v7 *h2c;
4820 u32 len = sizeof(*h2c);
4821 struct sk_buff *skb;
4822 int ret;
4823
4824 skb = rtw89_fw_h2c_alloc_skb_with_hdr(rtwdev, len);
4825 if (!skb) {
4826 rtw89_err(rtwdev, "failed to alloc skb for h2c cxdrv_init_v7\n");
4827 return -ENOMEM;
4828 }
4829 skb_put(skb, len);
4830 h2c = (struct rtw89_h2c_cxinit_v7 *)skb->data;
4831
4832 h2c->hdr.type = type;
4833 h2c->hdr.ver = btc->ver->fcxinit;
4834 h2c->hdr.len = len - H2C_LEN_CXDRVHDR_V7;
4835 h2c->init = *init_info;
4836
4837 rtw89_h2c_pkt_set_hdr(rtwdev, skb, FWCMD_TYPE_H2C,
4838 H2C_CAT_OUTSRC, BTFC_SET,
4839 SET_DRV_INFO, 0, 0,
4840 len);
4841
4842 ret = rtw89_h2c_tx(rtwdev, skb, false);
4843 if (ret) {
4844 rtw89_err(rtwdev, "failed to send h2c\n");
4845 goto fail;
4846 }
4847
4848 return 0;
4849 fail:
4850 dev_kfree_skb_any(skb);
4851
4852 return ret;
4853 }
4854
4855 #define PORT_DATA_OFFSET 4
4856 #define H2C_LEN_CXDRVINFO_ROLE_DBCC_LEN 12
4857 #define H2C_LEN_CXDRVINFO_ROLE_SIZE(max_role_num) \
4858 (4 + 12 * (max_role_num) + H2C_LEN_CXDRVHDR)
4859
4860 int rtw89_fw_h2c_cxdrv_role(struct rtw89_dev *rtwdev, u8 type)
4861 {
4862 struct rtw89_btc *btc = &rtwdev->btc;
4863 const struct rtw89_btc_ver *ver = btc->ver;
4864 struct rtw89_btc_wl_info *wl = &btc->cx.wl;
4865 struct rtw89_btc_wl_role_info *role_info = &wl->role_info;
4866 struct rtw89_btc_wl_role_info_bpos *bpos = &role_info->role_map.role;
4867 struct rtw89_btc_wl_active_role *active = role_info->active_role;
4868 struct sk_buff *skb;
4869 u32 len;
4870 u8 offset = 0;
4871 u8 *cmd;
4872 int ret;
4873 int i;
4874
4875 len = H2C_LEN_CXDRVINFO_ROLE_SIZE(ver->max_role_num);
4876
4877 skb = rtw89_fw_h2c_alloc_skb_with_hdr(rtwdev, len);
4878 if (!skb) {
4879 rtw89_err(rtwdev, "failed to alloc skb for h2c cxdrv_role\n");
4880 return -ENOMEM;
4881 }
4882 skb_put(skb, len);
4883 cmd = skb->data;
4884
4885 RTW89_SET_FWCMD_CXHDR_TYPE(cmd, type);
4886 RTW89_SET_FWCMD_CXHDR_LEN(cmd, len - H2C_LEN_CXDRVHDR);
4887
4888 RTW89_SET_FWCMD_CXROLE_CONNECT_CNT(cmd, role_info->connect_cnt);
4889 RTW89_SET_FWCMD_CXROLE_LINK_MODE(cmd, role_info->link_mode);
4890
4891 RTW89_SET_FWCMD_CXROLE_ROLE_NONE(cmd, bpos->none);
4892 RTW89_SET_FWCMD_CXROLE_ROLE_STA(cmd, bpos->station);
4893 RTW89_SET_FWCMD_CXROLE_ROLE_AP(cmd, bpos->ap);
4894 RTW89_SET_FWCMD_CXROLE_ROLE_VAP(cmd, bpos->vap);
4895 RTW89_SET_FWCMD_CXROLE_ROLE_ADHOC(cmd, bpos->adhoc);
4896 RTW89_SET_FWCMD_CXROLE_ROLE_ADHOC_MASTER(cmd, bpos->adhoc_master);
4897 RTW89_SET_FWCMD_CXROLE_ROLE_MESH(cmd, bpos->mesh);
4898 RTW89_SET_FWCMD_CXROLE_ROLE_MONITOR(cmd, bpos->moniter);
4899 RTW89_SET_FWCMD_CXROLE_ROLE_P2P_DEV(cmd, bpos->p2p_device);
4900 RTW89_SET_FWCMD_CXROLE_ROLE_P2P_GC(cmd, bpos->p2p_gc);
4901 RTW89_SET_FWCMD_CXROLE_ROLE_P2P_GO(cmd, bpos->p2p_go);
4902 RTW89_SET_FWCMD_CXROLE_ROLE_NAN(cmd, bpos->nan);
4903
4904 for (i = 0; i < RTW89_PORT_NUM; i++, active++) {
4905 RTW89_SET_FWCMD_CXROLE_ACT_CONNECTED(cmd, active->connected, i, offset);
4906 RTW89_SET_FWCMD_CXROLE_ACT_PID(cmd, active->pid, i, offset);
4907 RTW89_SET_FWCMD_CXROLE_ACT_PHY(cmd, active->phy, i, offset);
4908 RTW89_SET_FWCMD_CXROLE_ACT_NOA(cmd, active->noa, i, offset);
4909 RTW89_SET_FWCMD_CXROLE_ACT_BAND(cmd, active->band, i, offset);
4910 RTW89_SET_FWCMD_CXROLE_ACT_CLIENT_PS(cmd, active->client_ps, i, offset);
4911 RTW89_SET_FWCMD_CXROLE_ACT_BW(cmd, active->bw, i, offset);
4912 RTW89_SET_FWCMD_CXROLE_ACT_ROLE(cmd, active->role, i, offset);
4913 RTW89_SET_FWCMD_CXROLE_ACT_CH(cmd, active->ch, i, offset);
4914 RTW89_SET_FWCMD_CXROLE_ACT_TX_LVL(cmd, active->tx_lvl, i, offset);
4915 RTW89_SET_FWCMD_CXROLE_ACT_RX_LVL(cmd, active->rx_lvl, i, offset);
4916 RTW89_SET_FWCMD_CXROLE_ACT_TX_RATE(cmd, active->tx_rate, i, offset);
4917 RTW89_SET_FWCMD_CXROLE_ACT_RX_RATE(cmd, active->rx_rate, i, offset);
4918 }
4919
4920 rtw89_h2c_pkt_set_hdr(rtwdev, skb, FWCMD_TYPE_H2C,
4921 H2C_CAT_OUTSRC, BTFC_SET,
4922 SET_DRV_INFO, 0, 0,
4923 len);
4924
4925 ret = rtw89_h2c_tx(rtwdev, skb, false);
4926 if (ret) {
4927 rtw89_err(rtwdev, "failed to send h2c\n");
4928 goto fail;
4929 }
4930
4931 return 0;
4932 fail:
4933 dev_kfree_skb_any(skb);
4934
4935 return ret;
4936 }
4937
4938 #define H2C_LEN_CXDRVINFO_ROLE_SIZE_V1(max_role_num) \
4939 (4 + 16 * (max_role_num) + H2C_LEN_CXDRVINFO_ROLE_DBCC_LEN + H2C_LEN_CXDRVHDR)
4940
4941 int rtw89_fw_h2c_cxdrv_role_v1(struct rtw89_dev *rtwdev, u8 type)
4942 {
4943 struct rtw89_btc *btc = &rtwdev->btc;
4944 const struct rtw89_btc_ver *ver = btc->ver;
4945 struct rtw89_btc_wl_info *wl = &btc->cx.wl;
4946 struct rtw89_btc_wl_role_info_v1 *role_info = &wl->role_info_v1;
4947 struct rtw89_btc_wl_role_info_bpos *bpos = &role_info->role_map.role;
4948 struct rtw89_btc_wl_active_role_v1 *active = role_info->active_role_v1;
4949 struct sk_buff *skb;
4950 u32 len;
4951 u8 *cmd, offset;
4952 int ret;
4953 int i;
4954
4955 len = H2C_LEN_CXDRVINFO_ROLE_SIZE_V1(ver->max_role_num);
4956
4957 skb = rtw89_fw_h2c_alloc_skb_with_hdr(rtwdev, len);
4958 if (!skb) {
4959 rtw89_err(rtwdev, "failed to alloc skb for h2c cxdrv_role\n");
4960 return -ENOMEM;
4961 }
4962 skb_put(skb, len);
4963 cmd = skb->data;
4964
4965 RTW89_SET_FWCMD_CXHDR_TYPE(cmd, type);
4966 RTW89_SET_FWCMD_CXHDR_LEN(cmd, len - H2C_LEN_CXDRVHDR);
4967
4968 RTW89_SET_FWCMD_CXROLE_CONNECT_CNT(cmd, role_info->connect_cnt);
4969 RTW89_SET_FWCMD_CXROLE_LINK_MODE(cmd, role_info->link_mode);
4970
4971 RTW89_SET_FWCMD_CXROLE_ROLE_NONE(cmd, bpos->none);
4972 RTW89_SET_FWCMD_CXROLE_ROLE_STA(cmd, bpos->station);
4973 RTW89_SET_FWCMD_CXROLE_ROLE_AP(cmd, bpos->ap);
4974 RTW89_SET_FWCMD_CXROLE_ROLE_VAP(cmd, bpos->vap);
4975 RTW89_SET_FWCMD_CXROLE_ROLE_ADHOC(cmd, bpos->adhoc);
4976 RTW89_SET_FWCMD_CXROLE_ROLE_ADHOC_MASTER(cmd, bpos->adhoc_master);
4977 RTW89_SET_FWCMD_CXROLE_ROLE_MESH(cmd, bpos->mesh);
4978 RTW89_SET_FWCMD_CXROLE_ROLE_MONITOR(cmd, bpos->moniter);
4979 RTW89_SET_FWCMD_CXROLE_ROLE_P2P_DEV(cmd, bpos->p2p_device);
4980 RTW89_SET_FWCMD_CXROLE_ROLE_P2P_GC(cmd, bpos->p2p_gc);
4981 RTW89_SET_FWCMD_CXROLE_ROLE_P2P_GO(cmd, bpos->p2p_go);
4982 RTW89_SET_FWCMD_CXROLE_ROLE_NAN(cmd, bpos->nan);
4983
4984 offset = PORT_DATA_OFFSET;
4985 for (i = 0; i < RTW89_PORT_NUM; i++, active++) {
4986 RTW89_SET_FWCMD_CXROLE_ACT_CONNECTED(cmd, active->connected, i, offset);
4987 RTW89_SET_FWCMD_CXROLE_ACT_PID(cmd, active->pid, i, offset);
4988 RTW89_SET_FWCMD_CXROLE_ACT_PHY(cmd, active->phy, i, offset);
4989 RTW89_SET_FWCMD_CXROLE_ACT_NOA(cmd, active->noa, i, offset);
4990 RTW89_SET_FWCMD_CXROLE_ACT_BAND(cmd, active->band, i, offset);
4991 RTW89_SET_FWCMD_CXROLE_ACT_CLIENT_PS(cmd, active->client_ps, i, offset);
4992 RTW89_SET_FWCMD_CXROLE_ACT_BW(cmd, active->bw, i, offset);
4993 RTW89_SET_FWCMD_CXROLE_ACT_ROLE(cmd, active->role, i, offset);
4994 RTW89_SET_FWCMD_CXROLE_ACT_CH(cmd, active->ch, i, offset);
4995 RTW89_SET_FWCMD_CXROLE_ACT_TX_LVL(cmd, active->tx_lvl, i, offset);
4996 RTW89_SET_FWCMD_CXROLE_ACT_RX_LVL(cmd, active->rx_lvl, i, offset);
4997 RTW89_SET_FWCMD_CXROLE_ACT_TX_RATE(cmd, active->tx_rate, i, offset);
4998 RTW89_SET_FWCMD_CXROLE_ACT_RX_RATE(cmd, active->rx_rate, i, offset);
4999 RTW89_SET_FWCMD_CXROLE_ACT_NOA_DUR(cmd, active->noa_duration, i, offset);
5000 }
5001
5002 offset = len - H2C_LEN_CXDRVINFO_ROLE_DBCC_LEN;
5003 RTW89_SET_FWCMD_CXROLE_MROLE_TYPE(cmd, role_info->mrole_type, offset);
5004 RTW89_SET_FWCMD_CXROLE_MROLE_NOA(cmd, role_info->mrole_noa_duration, offset);
5005 RTW89_SET_FWCMD_CXROLE_DBCC_EN(cmd, role_info->dbcc_en, offset);
5006 RTW89_SET_FWCMD_CXROLE_DBCC_CHG(cmd, role_info->dbcc_chg, offset);
5007 RTW89_SET_FWCMD_CXROLE_DBCC_2G_PHY(cmd, role_info->dbcc_2g_phy, offset);
5008 RTW89_SET_FWCMD_CXROLE_LINK_MODE_CHG(cmd, role_info->link_mode_chg, offset);
5009
5010 rtw89_h2c_pkt_set_hdr(rtwdev, skb, FWCMD_TYPE_H2C,
5011 H2C_CAT_OUTSRC, BTFC_SET,
5012 SET_DRV_INFO, 0, 0,
5013 len);
5014
5015 ret = rtw89_h2c_tx(rtwdev, skb, false);
5016 if (ret) {
5017 rtw89_err(rtwdev, "failed to send h2c\n");
5018 goto fail;
5019 }
5020
5021 return 0;
5022 fail:
5023 dev_kfree_skb_any(skb);
5024
5025 return ret;
5026 }
5027
5028 #define H2C_LEN_CXDRVINFO_ROLE_SIZE_V2(max_role_num) \
5029 (4 + 8 * (max_role_num) + H2C_LEN_CXDRVINFO_ROLE_DBCC_LEN + H2C_LEN_CXDRVHDR)
5030
5031 int rtw89_fw_h2c_cxdrv_role_v2(struct rtw89_dev *rtwdev, u8 type)
5032 {
5033 struct rtw89_btc *btc = &rtwdev->btc;
5034 const struct rtw89_btc_ver *ver = btc->ver;
5035 struct rtw89_btc_wl_info *wl = &btc->cx.wl;
5036 struct rtw89_btc_wl_role_info_v2 *role_info = &wl->role_info_v2;
5037 struct rtw89_btc_wl_role_info_bpos *bpos = &role_info->role_map.role;
5038 struct rtw89_btc_wl_active_role_v2 *active = role_info->active_role_v2;
5039 struct sk_buff *skb;
5040 u32 len;
5041 u8 *cmd, offset;
5042 int ret;
5043 int i;
5044
5045 len = H2C_LEN_CXDRVINFO_ROLE_SIZE_V2(ver->max_role_num);
5046
5047 skb = rtw89_fw_h2c_alloc_skb_with_hdr(rtwdev, len);
5048 if (!skb) {
5049 rtw89_err(rtwdev, "failed to alloc skb for h2c cxdrv_role\n");
5050 return -ENOMEM;
5051 }
5052 skb_put(skb, len);
5053 cmd = skb->data;
5054
5055 RTW89_SET_FWCMD_CXHDR_TYPE(cmd, type);
5056 RTW89_SET_FWCMD_CXHDR_LEN(cmd, len - H2C_LEN_CXDRVHDR);
5057
5058 RTW89_SET_FWCMD_CXROLE_CONNECT_CNT(cmd, role_info->connect_cnt);
5059 RTW89_SET_FWCMD_CXROLE_LINK_MODE(cmd, role_info->link_mode);
5060
5061 RTW89_SET_FWCMD_CXROLE_ROLE_NONE(cmd, bpos->none);
5062 RTW89_SET_FWCMD_CXROLE_ROLE_STA(cmd, bpos->station);
5063 RTW89_SET_FWCMD_CXROLE_ROLE_AP(cmd, bpos->ap);
5064 RTW89_SET_FWCMD_CXROLE_ROLE_VAP(cmd, bpos->vap);
5065 RTW89_SET_FWCMD_CXROLE_ROLE_ADHOC(cmd, bpos->adhoc);
5066 RTW89_SET_FWCMD_CXROLE_ROLE_ADHOC_MASTER(cmd, bpos->adhoc_master);
5067 RTW89_SET_FWCMD_CXROLE_ROLE_MESH(cmd, bpos->mesh);
5068 RTW89_SET_FWCMD_CXROLE_ROLE_MONITOR(cmd, bpos->moniter);
5069 RTW89_SET_FWCMD_CXROLE_ROLE_P2P_DEV(cmd, bpos->p2p_device);
5070 RTW89_SET_FWCMD_CXROLE_ROLE_P2P_GC(cmd, bpos->p2p_gc);
5071 RTW89_SET_FWCMD_CXROLE_ROLE_P2P_GO(cmd, bpos->p2p_go);
5072 RTW89_SET_FWCMD_CXROLE_ROLE_NAN(cmd, bpos->nan);
5073
5074 offset = PORT_DATA_OFFSET;
5075 for (i = 0; i < RTW89_PORT_NUM; i++, active++) {
5076 RTW89_SET_FWCMD_CXROLE_ACT_CONNECTED_V2(cmd, active->connected, i, offset);
5077 RTW89_SET_FWCMD_CXROLE_ACT_PID_V2(cmd, active->pid, i, offset);
5078 RTW89_SET_FWCMD_CXROLE_ACT_PHY_V2(cmd, active->phy, i, offset);
5079 RTW89_SET_FWCMD_CXROLE_ACT_NOA_V2(cmd, active->noa, i, offset);
5080 RTW89_SET_FWCMD_CXROLE_ACT_BAND_V2(cmd, active->band, i, offset);
5081 RTW89_SET_FWCMD_CXROLE_ACT_CLIENT_PS_V2(cmd, active->client_ps, i, offset);
5082 RTW89_SET_FWCMD_CXROLE_ACT_BW_V2(cmd, active->bw, i, offset);
5083 RTW89_SET_FWCMD_CXROLE_ACT_ROLE_V2(cmd, active->role, i, offset);
5084 RTW89_SET_FWCMD_CXROLE_ACT_CH_V2(cmd, active->ch, i, offset);
5085 RTW89_SET_FWCMD_CXROLE_ACT_NOA_DUR_V2(cmd, active->noa_duration, i, offset);
5086 }
5087
5088 offset = len - H2C_LEN_CXDRVINFO_ROLE_DBCC_LEN;
5089 RTW89_SET_FWCMD_CXROLE_MROLE_TYPE(cmd, role_info->mrole_type, offset);
5090 RTW89_SET_FWCMD_CXROLE_MROLE_NOA(cmd, role_info->mrole_noa_duration, offset);
5091 RTW89_SET_FWCMD_CXROLE_DBCC_EN(cmd, role_info->dbcc_en, offset);
5092 RTW89_SET_FWCMD_CXROLE_DBCC_CHG(cmd, role_info->dbcc_chg, offset);
5093 RTW89_SET_FWCMD_CXROLE_DBCC_2G_PHY(cmd, role_info->dbcc_2g_phy, offset);
5094 RTW89_SET_FWCMD_CXROLE_LINK_MODE_CHG(cmd, role_info->link_mode_chg, offset);
5095
5096 rtw89_h2c_pkt_set_hdr(rtwdev, skb, FWCMD_TYPE_H2C,
5097 H2C_CAT_OUTSRC, BTFC_SET,
5098 SET_DRV_INFO, 0, 0,
5099 len);
5100
5101 ret = rtw89_h2c_tx(rtwdev, skb, false);
5102 if (ret) {
5103 rtw89_err(rtwdev, "failed to send h2c\n");
5104 goto fail;
5105 }
5106
5107 return 0;
5108 fail:
5109 dev_kfree_skb_any(skb);
5110
5111 return ret;
5112 }
5113
5114 int rtw89_fw_h2c_cxdrv_role_v7(struct rtw89_dev *rtwdev, u8 type)
5115 {
5116 struct rtw89_btc *btc = &rtwdev->btc;
5117 struct rtw89_btc_wl_role_info_v7 *role = &btc->cx.wl.role_info_v7;
5118 struct rtw89_h2c_cxrole_v7 *h2c;
5119 u32 len = sizeof(*h2c);
5120 struct sk_buff *skb;
5121 int ret;
5122
5123 skb = rtw89_fw_h2c_alloc_skb_with_hdr(rtwdev, len);
5124 if (!skb) {
5125 rtw89_err(rtwdev, "failed to alloc skb for h2c cxdrv_ctrl\n");
5126 return -ENOMEM;
5127 }
5128 skb_put(skb, len);
5129 h2c = (struct rtw89_h2c_cxrole_v7 *)skb->data;
5130
5131 h2c->hdr.type = type;
5132 h2c->hdr.ver = btc->ver->fwlrole;
5133 h2c->hdr.len = len - H2C_LEN_CXDRVHDR_V7;
5134 memcpy(&h2c->_u8, role, sizeof(h2c->_u8));
5135 h2c->_u32.role_map = cpu_to_le32(role->role_map);
5136 h2c->_u32.mrole_type = cpu_to_le32(role->mrole_type);
5137 h2c->_u32.mrole_noa_duration = cpu_to_le32(role->mrole_noa_duration);
5138 h2c->_u32.dbcc_en = cpu_to_le32(role->dbcc_en);
5139 h2c->_u32.dbcc_chg = cpu_to_le32(role->dbcc_chg);
5140 h2c->_u32.dbcc_2g_phy = cpu_to_le32(role->dbcc_2g_phy);
5141
5142 rtw89_h2c_pkt_set_hdr(rtwdev, skb, FWCMD_TYPE_H2C,
5143 H2C_CAT_OUTSRC, BTFC_SET,
5144 SET_DRV_INFO, 0, 0,
5145 len);
5146
5147 ret = rtw89_h2c_tx(rtwdev, skb, false);
5148 if (ret) {
5149 rtw89_err(rtwdev, "failed to send h2c\n");
5150 goto fail;
5151 }
5152
5153 return 0;
5154 fail:
5155 dev_kfree_skb_any(skb);
5156
5157 return ret;
5158 }
5159
5160 int rtw89_fw_h2c_cxdrv_role_v8(struct rtw89_dev *rtwdev, u8 type)
5161 {
5162 struct rtw89_btc *btc = &rtwdev->btc;
5163 struct rtw89_btc_wl_role_info_v8 *role = &btc->cx.wl.role_info_v8;
5164 struct rtw89_h2c_cxrole_v8 *h2c;
5165 u32 len = sizeof(*h2c);
5166 struct sk_buff *skb;
5167 int ret;
5168
5169 skb = rtw89_fw_h2c_alloc_skb_with_hdr(rtwdev, len);
5170 if (!skb) {
5171 rtw89_err(rtwdev, "failed to alloc skb for h2c cxdrv_ctrl\n");
5172 return -ENOMEM;
5173 }
5174 skb_put(skb, len);
5175 h2c = (struct rtw89_h2c_cxrole_v8 *)skb->data;
5176
5177 h2c->hdr.type = type;
5178 h2c->hdr.ver = btc->ver->fwlrole;
5179 h2c->hdr.len = len - H2C_LEN_CXDRVHDR_V7;
5180 memcpy(&h2c->_u8, role, sizeof(h2c->_u8));
5181 h2c->_u32.role_map = cpu_to_le32(role->role_map);
5182 h2c->_u32.mrole_type = cpu_to_le32(role->mrole_type);
5183 h2c->_u32.mrole_noa_duration = cpu_to_le32(role->mrole_noa_duration);
5184
5185 rtw89_h2c_pkt_set_hdr(rtwdev, skb, FWCMD_TYPE_H2C,
5186 H2C_CAT_OUTSRC, BTFC_SET,
5187 SET_DRV_INFO, 0, 0,
5188 len);
5189
5190 ret = rtw89_h2c_tx(rtwdev, skb, false);
5191 if (ret) {
5192 rtw89_err(rtwdev, "failed to send h2c\n");
5193 goto fail;
5194 }
5195
5196 return 0;
5197 fail:
5198 dev_kfree_skb_any(skb);
5199
5200 return ret;
5201 }
5202
5203 int rtw89_fw_h2c_cxdrv_osi_info(struct rtw89_dev *rtwdev, u8 type)
5204 {
5205 struct rtw89_btc *btc = &rtwdev->btc;
5206 struct rtw89_btc_fbtc_outsrc_set_info *osi = &btc->dm.ost_info;
5207 struct rtw89_h2c_cxosi *h2c;
5208 u32 len = sizeof(*h2c);
5209 struct sk_buff *skb;
5210 int ret;
5211
5212 skb = rtw89_fw_h2c_alloc_skb_with_hdr(rtwdev, len);
5213 if (!skb) {
5214 rtw89_err(rtwdev, "failed to alloc skb for h2c cxdrv_osi\n");
5215 return -ENOMEM;
5216 }
5217 skb_put(skb, len);
5218 h2c = (struct rtw89_h2c_cxosi *)skb->data;
5219
5220 h2c->hdr.type = type;
5221 h2c->hdr.ver = btc->ver->fcxosi;
5222 h2c->hdr.len = len - H2C_LEN_CXDRVHDR_V7;
5223 h2c->osi = *osi;
5224
5225 rtw89_h2c_pkt_set_hdr(rtwdev, skb, FWCMD_TYPE_H2C,
5226 H2C_CAT_OUTSRC, BTFC_SET,
5227 SET_DRV_INFO, 0, 0,
5228 len);
5229
5230 ret = rtw89_h2c_tx(rtwdev, skb, false);
5231 if (ret) {
5232 rtw89_err(rtwdev, "failed to send h2c\n");
5233 goto fail;
5234 }
5235
5236 return 0;
5237 fail:
5238 dev_kfree_skb_any(skb);
5239
5240 return ret;
5241 }
5242
5243 #define H2C_LEN_CXDRVINFO_CTRL (4 + H2C_LEN_CXDRVHDR)
5244 int rtw89_fw_h2c_cxdrv_ctrl(struct rtw89_dev *rtwdev, u8 type)
5245 {
5246 struct rtw89_btc *btc = &rtwdev->btc;
5247 const struct rtw89_btc_ver *ver = btc->ver;
5248 struct rtw89_btc_ctrl *ctrl = &btc->ctrl.ctrl;
5249 struct sk_buff *skb;
5250 u8 *cmd;
5251 int ret;
5252
5253 skb = rtw89_fw_h2c_alloc_skb_with_hdr(rtwdev, H2C_LEN_CXDRVINFO_CTRL);
5254 if (!skb) {
5255 rtw89_err(rtwdev, "failed to alloc skb for h2c cxdrv_ctrl\n");
5256 return -ENOMEM;
5257 }
5258 skb_put(skb, H2C_LEN_CXDRVINFO_CTRL);
5259 cmd = skb->data;
5260
5261 RTW89_SET_FWCMD_CXHDR_TYPE(cmd, type);
5262 RTW89_SET_FWCMD_CXHDR_LEN(cmd, H2C_LEN_CXDRVINFO_CTRL - H2C_LEN_CXDRVHDR);
5263
5264 RTW89_SET_FWCMD_CXCTRL_MANUAL(cmd, ctrl->manual);
5265 RTW89_SET_FWCMD_CXCTRL_IGNORE_BT(cmd, ctrl->igno_bt);
5266 RTW89_SET_FWCMD_CXCTRL_ALWAYS_FREERUN(cmd, ctrl->always_freerun);
5267 if (ver->fcxctrl == 0)
5268 RTW89_SET_FWCMD_CXCTRL_TRACE_STEP(cmd, ctrl->trace_step);
5269
5270 rtw89_h2c_pkt_set_hdr(rtwdev, skb, FWCMD_TYPE_H2C,
5271 H2C_CAT_OUTSRC, BTFC_SET,
5272 SET_DRV_INFO, 0, 0,
5273 H2C_LEN_CXDRVINFO_CTRL);
5274
5275 ret = rtw89_h2c_tx(rtwdev, skb, false);
5276 if (ret) {
5277 rtw89_err(rtwdev, "failed to send h2c\n");
5278 goto fail;
5279 }
5280
5281 return 0;
5282 fail:
5283 dev_kfree_skb_any(skb);
5284
5285 return ret;
5286 }
5287
5288 int rtw89_fw_h2c_cxdrv_ctrl_v7(struct rtw89_dev *rtwdev, u8 type)
5289 {
5290 struct rtw89_btc *btc = &rtwdev->btc;
5291 struct rtw89_btc_ctrl_v7 *ctrl = &btc->ctrl.ctrl_v7;
5292 struct rtw89_h2c_cxctrl_v7 *h2c;
5293 u32 len = sizeof(*h2c);
5294 struct sk_buff *skb;
5295 int ret;
5296
5297 skb = rtw89_fw_h2c_alloc_skb_with_hdr(rtwdev, len);
5298 if (!skb) {
5299 rtw89_err(rtwdev, "failed to alloc skb for h2c cxdrv_ctrl_v7\n");
5300 return -ENOMEM;
5301 }
5302 skb_put(skb, len);
5303 h2c = (struct rtw89_h2c_cxctrl_v7 *)skb->data;
5304
5305 h2c->hdr.type = type;
5306 h2c->hdr.ver = btc->ver->fcxctrl;
5307 h2c->hdr.len = sizeof(*h2c) - H2C_LEN_CXDRVHDR_V7;
5308 h2c->ctrl = *ctrl;
5309
5310 rtw89_h2c_pkt_set_hdr(rtwdev, skb, FWCMD_TYPE_H2C,
5311 H2C_CAT_OUTSRC, BTFC_SET,
5312 SET_DRV_INFO, 0, 0, len);
5313
5314 ret = rtw89_h2c_tx(rtwdev, skb, false);
5315 if (ret) {
5316 rtw89_err(rtwdev, "failed to send h2c\n");
5317 goto fail;
5318 }
5319
5320 return 0;
5321 fail:
5322 dev_kfree_skb_any(skb);
5323
5324 return ret;
5325 }
5326
5327 #define H2C_LEN_CXDRVINFO_TRX (28 + H2C_LEN_CXDRVHDR)
5328 int rtw89_fw_h2c_cxdrv_trx(struct rtw89_dev *rtwdev, u8 type)
5329 {
5330 struct rtw89_btc *btc = &rtwdev->btc;
5331 struct rtw89_btc_trx_info *trx = &btc->dm.trx_info;
5332 struct sk_buff *skb;
5333 u8 *cmd;
5334 int ret;
5335
5336 skb = rtw89_fw_h2c_alloc_skb_with_hdr(rtwdev, H2C_LEN_CXDRVINFO_TRX);
5337 if (!skb) {
5338 rtw89_err(rtwdev, "failed to alloc skb for h2c cxdrv_trx\n");
5339 return -ENOMEM;
5340 }
5341 skb_put(skb, H2C_LEN_CXDRVINFO_TRX);
5342 cmd = skb->data;
5343
5344 RTW89_SET_FWCMD_CXHDR_TYPE(cmd, type);
5345 RTW89_SET_FWCMD_CXHDR_LEN(cmd, H2C_LEN_CXDRVINFO_TRX - H2C_LEN_CXDRVHDR);
5346
5347 RTW89_SET_FWCMD_CXTRX_TXLV(cmd, trx->tx_lvl);
5348 RTW89_SET_FWCMD_CXTRX_RXLV(cmd, trx->rx_lvl);
5349 RTW89_SET_FWCMD_CXTRX_WLRSSI(cmd, trx->wl_rssi);
5350 RTW89_SET_FWCMD_CXTRX_BTRSSI(cmd, trx->bt_rssi);
5351 RTW89_SET_FWCMD_CXTRX_TXPWR(cmd, trx->tx_power);
5352 RTW89_SET_FWCMD_CXTRX_RXGAIN(cmd, trx->rx_gain);
5353 RTW89_SET_FWCMD_CXTRX_BTTXPWR(cmd, trx->bt_tx_power);
5354 RTW89_SET_FWCMD_CXTRX_BTRXGAIN(cmd, trx->bt_rx_gain);
5355 RTW89_SET_FWCMD_CXTRX_CN(cmd, trx->cn);
5356 RTW89_SET_FWCMD_CXTRX_NHM(cmd, trx->nhm);
5357 RTW89_SET_FWCMD_CXTRX_BTPROFILE(cmd, trx->bt_profile);
5358 RTW89_SET_FWCMD_CXTRX_RSVD2(cmd, trx->rsvd2);
5359 RTW89_SET_FWCMD_CXTRX_TXRATE(cmd, trx->tx_rate);
5360 RTW89_SET_FWCMD_CXTRX_RXRATE(cmd, trx->rx_rate);
5361 RTW89_SET_FWCMD_CXTRX_TXTP(cmd, trx->tx_tp);
5362 RTW89_SET_FWCMD_CXTRX_RXTP(cmd, trx->rx_tp);
5363 RTW89_SET_FWCMD_CXTRX_RXERRRA(cmd, trx->rx_err_ratio);
5364
5365 rtw89_h2c_pkt_set_hdr(rtwdev, skb, FWCMD_TYPE_H2C,
5366 H2C_CAT_OUTSRC, BTFC_SET,
5367 SET_DRV_INFO, 0, 0,
5368 H2C_LEN_CXDRVINFO_TRX);
5369
5370 ret = rtw89_h2c_tx(rtwdev, skb, false);
5371 if (ret) {
5372 rtw89_err(rtwdev, "failed to send h2c\n");
5373 goto fail;
5374 }
5375
5376 return 0;
5377 fail:
5378 dev_kfree_skb_any(skb);
5379
5380 return ret;
5381 }
5382
5383 #define H2C_LEN_CXDRVINFO_RFK (4 + H2C_LEN_CXDRVHDR)
5384 int rtw89_fw_h2c_cxdrv_rfk(struct rtw89_dev *rtwdev, u8 type)
5385 {
5386 struct rtw89_btc *btc = &rtwdev->btc;
5387 struct rtw89_btc_wl_info *wl = &btc->cx.wl;
5388 struct rtw89_btc_wl_rfk_info *rfk_info = &wl->rfk_info;
5389 struct sk_buff *skb;
5390 u8 *cmd;
5391 int ret;
5392
5393 skb = rtw89_fw_h2c_alloc_skb_with_hdr(rtwdev, H2C_LEN_CXDRVINFO_RFK);
5394 if (!skb) {
5395 rtw89_err(rtwdev, "failed to alloc skb for h2c cxdrv_ctrl\n");
5396 return -ENOMEM;
5397 }
5398 skb_put(skb, H2C_LEN_CXDRVINFO_RFK);
5399 cmd = skb->data;
5400
5401 RTW89_SET_FWCMD_CXHDR_TYPE(cmd, type);
5402 RTW89_SET_FWCMD_CXHDR_LEN(cmd, H2C_LEN_CXDRVINFO_RFK - H2C_LEN_CXDRVHDR);
5403
5404 RTW89_SET_FWCMD_CXRFK_STATE(cmd, rfk_info->state);
5405 RTW89_SET_FWCMD_CXRFK_PATH_MAP(cmd, rfk_info->path_map);
5406 RTW89_SET_FWCMD_CXRFK_PHY_MAP(cmd, rfk_info->phy_map);
5407 RTW89_SET_FWCMD_CXRFK_BAND(cmd, rfk_info->band);
5408 RTW89_SET_FWCMD_CXRFK_TYPE(cmd, rfk_info->type);
5409
5410 rtw89_h2c_pkt_set_hdr(rtwdev, skb, FWCMD_TYPE_H2C,
5411 H2C_CAT_OUTSRC, BTFC_SET,
5412 SET_DRV_INFO, 0, 0,
5413 H2C_LEN_CXDRVINFO_RFK);
5414
5415 ret = rtw89_h2c_tx(rtwdev, skb, false);
5416 if (ret) {
5417 rtw89_err(rtwdev, "failed to send h2c\n");
5418 goto fail;
5419 }
5420
5421 return 0;
5422 fail:
5423 dev_kfree_skb_any(skb);
5424
5425 return ret;
5426 }
5427
5428 #define H2C_LEN_PKT_OFLD 4
5429 int rtw89_fw_h2c_del_pkt_offload(struct rtw89_dev *rtwdev, u8 id)
5430 {
5431 struct rtw89_wait_info *wait = &rtwdev->mac.fw_ofld_wait;
5432 struct sk_buff *skb;
5433 unsigned int cond;
5434 u8 *cmd;
5435 int ret;
5436
5437 skb = rtw89_fw_h2c_alloc_skb_with_hdr(rtwdev, H2C_LEN_PKT_OFLD);
5438 if (!skb) {
5439 rtw89_err(rtwdev, "failed to alloc skb for h2c pkt offload\n");
5440 return -ENOMEM;
5441 }
5442 skb_put(skb, H2C_LEN_PKT_OFLD);
5443 cmd = skb->data;
5444
5445 RTW89_SET_FWCMD_PACKET_OFLD_PKT_IDX(cmd, id);
5446 RTW89_SET_FWCMD_PACKET_OFLD_PKT_OP(cmd, RTW89_PKT_OFLD_OP_DEL);
5447
5448 rtw89_h2c_pkt_set_hdr(rtwdev, skb, FWCMD_TYPE_H2C,
5449 H2C_CAT_MAC, H2C_CL_MAC_FW_OFLD,
5450 H2C_FUNC_PACKET_OFLD, 1, 1,
5451 H2C_LEN_PKT_OFLD);
5452
5453 cond = RTW89_FW_OFLD_WAIT_COND_PKT_OFLD(id, RTW89_PKT_OFLD_OP_DEL);
5454
5455 ret = rtw89_h2c_tx_and_wait(rtwdev, skb, wait, cond);
5456 if (ret < 0) {
5457 rtw89_debug(rtwdev, RTW89_DBG_FW,
5458 "failed to del pkt ofld: id %d, ret %d\n",
5459 id, ret);
5460 return ret;
5461 }
5462
5463 rtw89_core_release_bit_map(rtwdev->pkt_offload, id);
5464 return 0;
5465 }
5466
5467 int rtw89_fw_h2c_add_pkt_offload(struct rtw89_dev *rtwdev, u8 *id,
5468 struct sk_buff *skb_ofld)
5469 {
5470 struct rtw89_wait_info *wait = &rtwdev->mac.fw_ofld_wait;
5471 struct sk_buff *skb;
5472 unsigned int cond;
5473 u8 *cmd;
5474 u8 alloc_id;
5475 int ret;
5476
5477 alloc_id = rtw89_core_acquire_bit_map(rtwdev->pkt_offload,
5478 RTW89_MAX_PKT_OFLD_NUM);
5479 if (alloc_id == RTW89_MAX_PKT_OFLD_NUM)
5480 return -ENOSPC;
5481
5482 *id = alloc_id;
5483
5484 skb = rtw89_fw_h2c_alloc_skb_with_hdr(rtwdev, H2C_LEN_PKT_OFLD + skb_ofld->len);
5485 if (!skb) {
5486 rtw89_err(rtwdev, "failed to alloc skb for h2c pkt offload\n");
5487 rtw89_core_release_bit_map(rtwdev->pkt_offload, alloc_id);
5488 return -ENOMEM;
5489 }
5490 skb_put(skb, H2C_LEN_PKT_OFLD);
5491 cmd = skb->data;
5492
5493 RTW89_SET_FWCMD_PACKET_OFLD_PKT_IDX(cmd, alloc_id);
5494 RTW89_SET_FWCMD_PACKET_OFLD_PKT_OP(cmd, RTW89_PKT_OFLD_OP_ADD);
5495 RTW89_SET_FWCMD_PACKET_OFLD_PKT_LENGTH(cmd, skb_ofld->len);
5496 skb_put_data(skb, skb_ofld->data, skb_ofld->len);
5497
5498 rtw89_h2c_pkt_set_hdr(rtwdev, skb, FWCMD_TYPE_H2C,
5499 H2C_CAT_MAC, H2C_CL_MAC_FW_OFLD,
5500 H2C_FUNC_PACKET_OFLD, 1, 1,
5501 H2C_LEN_PKT_OFLD + skb_ofld->len);
5502
5503 cond = RTW89_FW_OFLD_WAIT_COND_PKT_OFLD(alloc_id, RTW89_PKT_OFLD_OP_ADD);
5504
5505 ret = rtw89_h2c_tx_and_wait(rtwdev, skb, wait, cond);
5506 if (ret < 0) {
5507 rtw89_debug(rtwdev, RTW89_DBG_FW,
5508 "failed to add pkt ofld: id %d, ret %d\n",
5509 alloc_id, ret);
5510 rtw89_core_release_bit_map(rtwdev->pkt_offload, alloc_id);
5511 return ret;
5512 }
5513
5514 return 0;
5515 }
5516
5517 static
5518 int rtw89_fw_h2c_scan_list_offload_ax(struct rtw89_dev *rtwdev, int ch_num,
5519 struct list_head *chan_list)
5520 {
5521 struct rtw89_hw_scan_info *scan_info = &rtwdev->scan_info;
5522 struct rtw89_wait_info *wait = &rtwdev->mac.fw_ofld_wait;
5523 struct rtw89_h2c_chinfo_elem *elem;
5524 struct rtw89_mac_chinfo_ax *ch_info;
5525 struct rtw89_h2c_chinfo *h2c;
5526 struct sk_buff *skb;
5527 unsigned int cond;
5528 int skb_len;
5529 int ret;
5530
5531 static_assert(sizeof(*elem) == RTW89_MAC_CHINFO_SIZE);
5532
5533 skb_len = struct_size(h2c, elem, ch_num);
5534 skb = rtw89_fw_h2c_alloc_skb_with_hdr(rtwdev, skb_len);
5535 if (!skb) {
5536 rtw89_err(rtwdev, "failed to alloc skb for h2c scan list\n");
5537 return -ENOMEM;
5538 }
5539 skb_put(skb, sizeof(*h2c));
5540 h2c = (struct rtw89_h2c_chinfo *)skb->data;
5541
5542 h2c->ch_num = ch_num;
5543 h2c->elem_size = sizeof(*elem) / 4; /* in unit of 4 bytes */
5544
5545 list_for_each_entry(ch_info, chan_list, list) {
5546 elem = (struct rtw89_h2c_chinfo_elem *)skb_put(skb, sizeof(*elem));
5547
5548 elem->w0 = le32_encode_bits(ch_info->period, RTW89_H2C_CHINFO_W0_PERIOD) |
5549 le32_encode_bits(ch_info->dwell_time, RTW89_H2C_CHINFO_W0_DWELL) |
5550 le32_encode_bits(ch_info->central_ch, RTW89_H2C_CHINFO_W0_CENTER_CH) |
5551 le32_encode_bits(ch_info->pri_ch, RTW89_H2C_CHINFO_W0_PRI_CH);
5552
5553 elem->w1 = le32_encode_bits(ch_info->bw, RTW89_H2C_CHINFO_W1_BW) |
5554 le32_encode_bits(ch_info->notify_action, RTW89_H2C_CHINFO_W1_ACTION) |
5555 le32_encode_bits(ch_info->num_pkt, RTW89_H2C_CHINFO_W1_NUM_PKT) |
5556 le32_encode_bits(ch_info->tx_pkt, RTW89_H2C_CHINFO_W1_TX) |
5557 le32_encode_bits(ch_info->pause_data, RTW89_H2C_CHINFO_W1_PAUSE_DATA) |
5558 le32_encode_bits(ch_info->ch_band, RTW89_H2C_CHINFO_W1_BAND) |
5559 le32_encode_bits(ch_info->probe_id, RTW89_H2C_CHINFO_W1_PKT_ID) |
5560 le32_encode_bits(ch_info->dfs_ch, RTW89_H2C_CHINFO_W1_DFS) |
5561 le32_encode_bits(ch_info->tx_null, RTW89_H2C_CHINFO_W1_TX_NULL) |
5562 le32_encode_bits(ch_info->rand_seq_num, RTW89_H2C_CHINFO_W1_RANDOM);
5563
5564 if (scan_info->extra_op.set)
5565 elem->w1 |= le32_encode_bits(ch_info->macid_tx,
5566 RTW89_H2C_CHINFO_W1_MACID_TX);
5567
5568 elem->w2 = le32_encode_bits(ch_info->pkt_id[0], RTW89_H2C_CHINFO_W2_PKT0) |
5569 le32_encode_bits(ch_info->pkt_id[1], RTW89_H2C_CHINFO_W2_PKT1) |
5570 le32_encode_bits(ch_info->pkt_id[2], RTW89_H2C_CHINFO_W2_PKT2) |
5571 le32_encode_bits(ch_info->pkt_id[3], RTW89_H2C_CHINFO_W2_PKT3);
5572
5573 elem->w3 = le32_encode_bits(ch_info->pkt_id[4], RTW89_H2C_CHINFO_W3_PKT4) |
5574 le32_encode_bits(ch_info->pkt_id[5], RTW89_H2C_CHINFO_W3_PKT5) |
5575 le32_encode_bits(ch_info->pkt_id[6], RTW89_H2C_CHINFO_W3_PKT6) |
5576 le32_encode_bits(ch_info->pkt_id[7], RTW89_H2C_CHINFO_W3_PKT7);
5577 }
5578
5579 rtw89_h2c_pkt_set_hdr(rtwdev, skb, FWCMD_TYPE_H2C,
5580 H2C_CAT_MAC, H2C_CL_MAC_FW_OFLD,
5581 H2C_FUNC_ADD_SCANOFLD_CH, 1, 1, skb_len);
5582
5583 cond = RTW89_SCANOFLD_WAIT_COND_ADD_CH;
5584
5585 ret = rtw89_h2c_tx_and_wait(rtwdev, skb, wait, cond);
5586 if (ret) {
5587 rtw89_debug(rtwdev, RTW89_DBG_FW, "failed to add scan ofld ch\n");
5588 return ret;
5589 }
5590
5591 return 0;
5592 }
5593
5594 static
5595 int rtw89_fw_h2c_scan_list_offload_be(struct rtw89_dev *rtwdev, int ch_num,
5596 struct list_head *chan_list,
5597 struct rtw89_vif_link *rtwvif_link)
5598 {
5599 struct rtw89_wait_info *wait = &rtwdev->mac.fw_ofld_wait;
5600 struct rtw89_h2c_chinfo_elem_be *elem;
5601 struct rtw89_mac_chinfo_be *ch_info;
5602 struct rtw89_h2c_chinfo_be *h2c;
5603 struct sk_buff *skb;
5604 unsigned int cond;
5605 u8 ver = U8_MAX;
5606 int skb_len;
5607 int ret;
5608
5609 static_assert(sizeof(*elem) == RTW89_MAC_CHINFO_SIZE_BE);
5610
5611 skb_len = struct_size(h2c, elem, ch_num);
5612 skb = rtw89_fw_h2c_alloc_skb_with_hdr(rtwdev, skb_len);
5613 if (!skb) {
5614 rtw89_err(rtwdev, "failed to alloc skb for h2c scan list\n");
5615 return -ENOMEM;
5616 }
5617
5618 if (RTW89_CHK_FW_FEATURE(CH_INFO_BE_V0, &rtwdev->fw))
5619 ver = 0;
5620
5621 skb_put(skb, sizeof(*h2c));
5622 h2c = (struct rtw89_h2c_chinfo_be *)skb->data;
5623
5624 h2c->ch_num = ch_num;
5625 h2c->elem_size = sizeof(*elem) / 4; /* in unit of 4 bytes */
5626 h2c->arg = u8_encode_bits(rtwvif_link->mac_idx,
5627 RTW89_H2C_CHINFO_ARG_MAC_IDX_MASK);
5628
5629 list_for_each_entry(ch_info, chan_list, list) {
5630 elem = (struct rtw89_h2c_chinfo_elem_be *)skb_put(skb, sizeof(*elem));
5631
5632 elem->w0 = le32_encode_bits(ch_info->dwell_time, RTW89_H2C_CHINFO_BE_W0_DWELL) |
5633 le32_encode_bits(ch_info->central_ch,
5634 RTW89_H2C_CHINFO_BE_W0_CENTER_CH) |
5635 le32_encode_bits(ch_info->pri_ch, RTW89_H2C_CHINFO_BE_W0_PRI_CH);
5636
5637 elem->w1 = le32_encode_bits(ch_info->bw, RTW89_H2C_CHINFO_BE_W1_BW) |
5638 le32_encode_bits(ch_info->ch_band, RTW89_H2C_CHINFO_BE_W1_CH_BAND) |
5639 le32_encode_bits(ch_info->dfs_ch, RTW89_H2C_CHINFO_BE_W1_DFS) |
5640 le32_encode_bits(ch_info->pause_data,
5641 RTW89_H2C_CHINFO_BE_W1_PAUSE_DATA) |
5642 le32_encode_bits(ch_info->tx_null, RTW89_H2C_CHINFO_BE_W1_TX_NULL) |
5643 le32_encode_bits(ch_info->rand_seq_num,
5644 RTW89_H2C_CHINFO_BE_W1_RANDOM) |
5645 le32_encode_bits(ch_info->notify_action,
5646 RTW89_H2C_CHINFO_BE_W1_NOTIFY) |
5647 le32_encode_bits(ch_info->probe_id != 0xff ? 1 : 0,
5648 RTW89_H2C_CHINFO_BE_W1_PROBE) |
5649 le32_encode_bits(ch_info->leave_crit,
5650 RTW89_H2C_CHINFO_BE_W1_EARLY_LEAVE_CRIT) |
5651 le32_encode_bits(ch_info->chkpt_timer,
5652 RTW89_H2C_CHINFO_BE_W1_CHKPT_TIMER);
5653
5654 elem->w2 = le32_encode_bits(ch_info->leave_time,
5655 RTW89_H2C_CHINFO_BE_W2_EARLY_LEAVE_TIME) |
5656 le32_encode_bits(ch_info->leave_th,
5657 RTW89_H2C_CHINFO_BE_W2_EARLY_LEAVE_TH) |
5658 le32_encode_bits(ch_info->tx_pkt_ctrl,
5659 RTW89_H2C_CHINFO_BE_W2_TX_PKT_CTRL);
5660
5661 elem->w3 = le32_encode_bits(ch_info->pkt_id[0], RTW89_H2C_CHINFO_BE_W3_PKT0) |
5662 le32_encode_bits(ch_info->pkt_id[1], RTW89_H2C_CHINFO_BE_W3_PKT1) |
5663 le32_encode_bits(ch_info->pkt_id[2], RTW89_H2C_CHINFO_BE_W3_PKT2) |
5664 le32_encode_bits(ch_info->pkt_id[3], RTW89_H2C_CHINFO_BE_W3_PKT3);
5665
5666 elem->w4 = le32_encode_bits(ch_info->pkt_id[4], RTW89_H2C_CHINFO_BE_W4_PKT4) |
5667 le32_encode_bits(ch_info->pkt_id[5], RTW89_H2C_CHINFO_BE_W4_PKT5) |
5668 le32_encode_bits(ch_info->pkt_id[6], RTW89_H2C_CHINFO_BE_W4_PKT6) |
5669 le32_encode_bits(ch_info->pkt_id[7], RTW89_H2C_CHINFO_BE_W4_PKT7);
5670
5671 elem->w5 = le32_encode_bits(ch_info->sw_def, RTW89_H2C_CHINFO_BE_W5_SW_DEF) |
5672 le32_encode_bits(ch_info->fw_probe0_ssids,
5673 RTW89_H2C_CHINFO_BE_W5_FW_PROBE0_SSIDS);
5674
5675 elem->w6 = le32_encode_bits(ch_info->fw_probe0_shortssids,
5676 RTW89_H2C_CHINFO_BE_W6_FW_PROBE0_SHORTSSIDS) |
5677 le32_encode_bits(ch_info->fw_probe0_bssids,
5678 RTW89_H2C_CHINFO_BE_W6_FW_PROBE0_BSSIDS);
5679 if (ver == 0)
5680 elem->w0 |=
5681 le32_encode_bits(ch_info->period, RTW89_H2C_CHINFO_BE_W0_PERIOD);
5682 else
5683 elem->w7 = le32_encode_bits(ch_info->period,
5684 RTW89_H2C_CHINFO_BE_W7_PERIOD_V1);
5685 }
5686
5687 rtw89_h2c_pkt_set_hdr(rtwdev, skb, FWCMD_TYPE_H2C,
5688 H2C_CAT_MAC, H2C_CL_MAC_FW_OFLD,
5689 H2C_FUNC_ADD_SCANOFLD_CH, 1, 1, skb_len);
5690
5691 cond = RTW89_SCANOFLD_WAIT_COND_ADD_CH;
5692
5693 ret = rtw89_h2c_tx_and_wait(rtwdev, skb, wait, cond);
5694 if (ret) {
5695 rtw89_debug(rtwdev, RTW89_DBG_FW, "failed to add scan ofld ch\n");
5696 return ret;
5697 }
5698
5699 return 0;
5700 }
5701
5702 int rtw89_fw_h2c_scan_offload_ax(struct rtw89_dev *rtwdev,
5703 struct rtw89_scan_option *option,
5704 struct rtw89_vif_link *rtwvif_link,
5705 bool wowlan)
5706 {
5707 struct rtw89_hw_scan_info *scan_info = &rtwdev->scan_info;
5708 struct rtw89_wait_info *wait = &rtwdev->mac.fw_ofld_wait;
5709 struct rtw89_chan *op = &rtwdev->scan_info.op_chan;
5710 enum rtw89_scan_mode scan_mode = RTW89_SCAN_IMMEDIATE;
5711 struct rtw89_h2c_scanofld *h2c;
5712 u32 len = sizeof(*h2c);
5713 struct sk_buff *skb;
5714 unsigned int cond;
5715 u64 tsf = 0;
5716 int ret;
5717
5718 skb = rtw89_fw_h2c_alloc_skb_with_hdr(rtwdev, len);
5719 if (!skb) {
5720 rtw89_err(rtwdev, "failed to alloc skb for h2c scan offload\n");
5721 return -ENOMEM;
5722 }
5723 skb_put(skb, len);
5724 h2c = (struct rtw89_h2c_scanofld *)skb->data;
5725
5726 if (option->delay) {
5727 ret = rtw89_mac_port_get_tsf(rtwdev, rtwvif_link, &tsf);
5728 if (ret) {
5729 rtw89_warn(rtwdev, "NLO failed to get port tsf: %d\n", ret);
5730 scan_mode = RTW89_SCAN_IMMEDIATE;
5731 } else {
5732 scan_mode = RTW89_SCAN_DELAY;
5733 tsf += (u64)option->delay * 1000;
5734 }
5735 }
5736
5737 h2c->w0 = le32_encode_bits(rtwvif_link->mac_id, RTW89_H2C_SCANOFLD_W0_MACID) |
5738 le32_encode_bits(rtwvif_link->port, RTW89_H2C_SCANOFLD_W0_PORT_ID) |
5739 le32_encode_bits(rtwvif_link->mac_idx, RTW89_H2C_SCANOFLD_W0_BAND) |
5740 le32_encode_bits(option->enable, RTW89_H2C_SCANOFLD_W0_OPERATION);
5741
5742 h2c->w1 = le32_encode_bits(true, RTW89_H2C_SCANOFLD_W1_NOTIFY_END) |
5743 le32_encode_bits(option->target_ch_mode,
5744 RTW89_H2C_SCANOFLD_W1_TARGET_CH_MODE) |
5745 le32_encode_bits(scan_mode, RTW89_H2C_SCANOFLD_W1_START_MODE) |
5746 le32_encode_bits(option->repeat, RTW89_H2C_SCANOFLD_W1_SCAN_TYPE);
5747
5748 h2c->w2 = le32_encode_bits(option->norm_pd, RTW89_H2C_SCANOFLD_W2_NORM_PD) |
5749 le32_encode_bits(option->slow_pd, RTW89_H2C_SCANOFLD_W2_SLOW_PD);
5750
5751 if (option->target_ch_mode) {
5752 h2c->w1 |= le32_encode_bits(op->band_width,
5753 RTW89_H2C_SCANOFLD_W1_TARGET_CH_BW) |
5754 le32_encode_bits(op->primary_channel,
5755 RTW89_H2C_SCANOFLD_W1_TARGET_PRI_CH) |
5756 le32_encode_bits(op->channel,
5757 RTW89_H2C_SCANOFLD_W1_TARGET_CENTRAL_CH);
5758 h2c->w0 |= le32_encode_bits(op->band_type,
5759 RTW89_H2C_SCANOFLD_W0_TARGET_CH_BAND);
5760 }
5761
5762 h2c->tsf_high = le32_encode_bits(upper_32_bits(tsf),
5763 RTW89_H2C_SCANOFLD_W3_TSF_HIGH);
5764 h2c->tsf_low = le32_encode_bits(lower_32_bits(tsf),
5765 RTW89_H2C_SCANOFLD_W4_TSF_LOW);
5766
5767 if (scan_info->extra_op.set)
5768 h2c->w6 = le32_encode_bits(scan_info->extra_op.macid,
5769 RTW89_H2C_SCANOFLD_W6_SECOND_MACID);
5770
5771 rtw89_h2c_pkt_set_hdr(rtwdev, skb, FWCMD_TYPE_H2C,
5772 H2C_CAT_MAC, H2C_CL_MAC_FW_OFLD,
5773 H2C_FUNC_SCANOFLD, 1, 1,
5774 len);
5775
5776 if (option->enable)
5777 cond = RTW89_SCANOFLD_WAIT_COND_START;
5778 else
5779 cond = RTW89_SCANOFLD_WAIT_COND_STOP;
5780
5781 ret = rtw89_h2c_tx_and_wait(rtwdev, skb, wait, cond);
5782 if (ret) {
5783 rtw89_debug(rtwdev, RTW89_DBG_FW, "failed to scan ofld\n");
5784 return ret;
5785 }
5786
5787 return 0;
5788 }
5789
5790 static void rtw89_scan_get_6g_disabled_chan(struct rtw89_dev *rtwdev,
5791 struct rtw89_scan_option *option)
5792 {
5793 struct ieee80211_supported_band *sband;
5794 struct ieee80211_channel *chan;
5795 u8 i, idx;
5796
5797 sband = rtwdev->hw->wiphy->bands[NL80211_BAND_6GHZ];
5798 if (!sband) {
5799 option->prohib_chan = U64_MAX;
5800 return;
5801 }
5802
5803 for (i = 0; i < sband->n_channels; i++) {
5804 chan = &sband->channels[i];
5805 if (chan->flags & IEEE80211_CHAN_DISABLED) {
5806 idx = (chan->hw_value - 1) / 4;
5807 option->prohib_chan |= BIT(idx);
5808 }
5809 }
5810 }
5811
5812 int rtw89_fw_h2c_scan_offload_be(struct rtw89_dev *rtwdev,
5813 struct rtw89_scan_option *option,
5814 struct rtw89_vif_link *rtwvif_link,
5815 bool wowlan)
5816 {
5817 struct rtw89_vif *rtwvif = rtwvif_link->rtwvif;
5818 struct rtw89_hw_scan_info *scan_info = &rtwdev->scan_info;
5819 const struct rtw89_hw_scan_extra_op *ext = &scan_info->extra_op;
5820 struct rtw89_wait_info *wait = &rtwdev->mac.fw_ofld_wait;
5821 struct cfg80211_scan_request *req = rtwvif->scan_req;
5822 struct rtw89_h2c_scanofld_be_macc_role *macc_role;
5823 struct rtw89_hw_scan_extra_op scan_op[2] = {};
5824 struct rtw89_chan *op = &scan_info->op_chan;
5825 struct rtw89_h2c_scanofld_be_opch *opch;
5826 struct rtw89_pktofld_info *pkt_info;
5827 struct rtw89_h2c_scanofld_be *h2c;
5828 struct ieee80211_vif *vif;
5829 struct sk_buff *skb;
5830 u8 macc_role_size = sizeof(*macc_role) * option->num_macc_role;
5831 u8 opch_size = sizeof(*opch) * option->num_opch;
5832 enum rtw89_scan_be_opmode opmode;
5833 u8 probe_id[NUM_NL80211_BANDS];
5834 u8 scan_offload_ver = U8_MAX;
5835 u8 cfg_len = sizeof(*h2c);
5836 unsigned int cond;
5837 u8 ap_idx = U8_MAX;
5838 u8 ver = U8_MAX;
5839 u8 policy_val;
5840 #if defined(__linux__)
5841 void *ptr;
5842 #elif defined(__FreeBSD__)
5843 u8 *ptr;
5844 #endif
5845 u8 txbcn;
5846 int ret;
5847 u32 len;
5848 u8 i;
5849
5850 scan_op[0].macid = rtwvif_link->mac_id;
5851 scan_op[0].port = rtwvif_link->port;
5852 scan_op[0].chan = *op;
5853 vif = rtwvif_to_vif(rtwvif_link->rtwvif);
5854 if (vif->type == NL80211_IFTYPE_AP)
5855 ap_idx = 0;
5856
5857 if (ext->set) {
5858 scan_op[1] = *ext;
5859 vif = rtwvif_to_vif(ext->rtwvif_link->rtwvif);
5860 if (vif->type == NL80211_IFTYPE_AP)
5861 ap_idx = 1;
5862 }
5863
5864 rtw89_scan_get_6g_disabled_chan(rtwdev, option);
5865
5866 if (RTW89_CHK_FW_FEATURE(SCAN_OFFLOAD_BE_V0, &rtwdev->fw)) {
5867 cfg_len = offsetofend(typeof(*h2c), w8);
5868 scan_offload_ver = 0;
5869 }
5870
5871 len = cfg_len + macc_role_size + opch_size;
5872 skb = rtw89_fw_h2c_alloc_skb_with_hdr(rtwdev, len);
5873 if (!skb) {
5874 rtw89_err(rtwdev, "failed to alloc skb for h2c scan offload\n");
5875 return -ENOMEM;
5876 }
5877
5878 skb_put(skb, len);
5879 h2c = (struct rtw89_h2c_scanofld_be *)skb->data;
5880 ptr = skb->data;
5881
5882 memset(probe_id, RTW89_SCANOFLD_PKT_NONE, sizeof(probe_id));
5883
5884 if (RTW89_CHK_FW_FEATURE(CH_INFO_BE_V0, &rtwdev->fw))
5885 ver = 0;
5886
5887 if (!wowlan) {
5888 list_for_each_entry(pkt_info, &scan_info->pkt_list[NL80211_BAND_6GHZ], list) {
5889 if (pkt_info->wildcard_6ghz) {
5890 /* Provide wildcard as template */
5891 probe_id[NL80211_BAND_6GHZ] = pkt_info->id;
5892 break;
5893 }
5894 }
5895 }
5896
5897 h2c->w0 = le32_encode_bits(option->operation, RTW89_H2C_SCANOFLD_BE_W0_OP) |
5898 le32_encode_bits(option->scan_mode,
5899 RTW89_H2C_SCANOFLD_BE_W0_SCAN_MODE) |
5900 le32_encode_bits(option->repeat, RTW89_H2C_SCANOFLD_BE_W0_REPEAT) |
5901 le32_encode_bits(true, RTW89_H2C_SCANOFLD_BE_W0_NOTIFY_END) |
5902 le32_encode_bits(true, RTW89_H2C_SCANOFLD_BE_W0_LEARN_CH) |
5903 le32_encode_bits(rtwvif_link->mac_id, RTW89_H2C_SCANOFLD_BE_W0_MACID) |
5904 le32_encode_bits(rtwvif_link->port, RTW89_H2C_SCANOFLD_BE_W0_PORT) |
5905 le32_encode_bits(option->band, RTW89_H2C_SCANOFLD_BE_W0_BAND);
5906
5907 h2c->w1 = le32_encode_bits(option->num_macc_role, RTW89_H2C_SCANOFLD_BE_W1_NUM_MACC_ROLE) |
5908 le32_encode_bits(option->num_opch, RTW89_H2C_SCANOFLD_BE_W1_NUM_OP) |
5909 le32_encode_bits(option->norm_pd, RTW89_H2C_SCANOFLD_BE_W1_NORM_PD);
5910
5911 h2c->w2 = le32_encode_bits(option->slow_pd, RTW89_H2C_SCANOFLD_BE_W2_SLOW_PD) |
5912 le32_encode_bits(option->norm_cy, RTW89_H2C_SCANOFLD_BE_W2_NORM_CY) |
5913 le32_encode_bits(option->opch_end, RTW89_H2C_SCANOFLD_BE_W2_OPCH_END);
5914
5915 h2c->w3 = le32_encode_bits(0, RTW89_H2C_SCANOFLD_BE_W3_NUM_SSID) |
5916 le32_encode_bits(0, RTW89_H2C_SCANOFLD_BE_W3_NUM_SHORT_SSID) |
5917 le32_encode_bits(0, RTW89_H2C_SCANOFLD_BE_W3_NUM_BSSID) |
5918 le32_encode_bits(probe_id[NL80211_BAND_2GHZ], RTW89_H2C_SCANOFLD_BE_W3_PROBEID);
5919
5920 h2c->w4 = le32_encode_bits(probe_id[NL80211_BAND_5GHZ],
5921 RTW89_H2C_SCANOFLD_BE_W4_PROBE_5G) |
5922 le32_encode_bits(probe_id[NL80211_BAND_6GHZ],
5923 RTW89_H2C_SCANOFLD_BE_W4_PROBE_6G) |
5924 le32_encode_bits(option->delay / 1000, RTW89_H2C_SCANOFLD_BE_W4_DELAY_START);
5925
5926 h2c->w5 = le32_encode_bits(option->mlo_mode, RTW89_H2C_SCANOFLD_BE_W5_MLO_MODE);
5927
5928 h2c->w6 = le32_encode_bits(option->prohib_chan,
5929 RTW89_H2C_SCANOFLD_BE_W6_CHAN_PROHIB_LOW);
5930 h2c->w7 = le32_encode_bits(option->prohib_chan >> 32,
5931 RTW89_H2C_SCANOFLD_BE_W7_CHAN_PROHIB_HIGH);
5932 if (!wowlan && req->no_cck) {
5933 h2c->w0 |= le32_encode_bits(true, RTW89_H2C_SCANOFLD_BE_W0_PROBE_WITH_RATE);
5934 h2c->w8 = le32_encode_bits(RTW89_HW_RATE_OFDM6,
5935 RTW89_H2C_SCANOFLD_BE_W8_PROBE_RATE_2GHZ) |
5936 le32_encode_bits(RTW89_HW_RATE_OFDM6,
5937 RTW89_H2C_SCANOFLD_BE_W8_PROBE_RATE_5GHZ) |
5938 le32_encode_bits(RTW89_HW_RATE_OFDM6,
5939 RTW89_H2C_SCANOFLD_BE_W8_PROBE_RATE_6GHZ);
5940 }
5941
5942 if (scan_offload_ver == 0)
5943 goto flex_member;
5944
5945 h2c->w9 = le32_encode_bits(sizeof(*h2c) / sizeof(h2c->w0),
5946 RTW89_H2C_SCANOFLD_BE_W9_SIZE_CFG) |
5947 le32_encode_bits(sizeof(*macc_role) / sizeof(macc_role->w0),
5948 RTW89_H2C_SCANOFLD_BE_W9_SIZE_MACC) |
5949 le32_encode_bits(sizeof(*opch) / sizeof(opch->w0),
5950 RTW89_H2C_SCANOFLD_BE_W9_SIZE_OP);
5951
5952 flex_member:
5953 ptr += cfg_len;
5954
5955 for (i = 0; i < option->num_macc_role; i++) {
5956 #if defined(__linux__)
5957 macc_role = ptr;
5958 #elif defined(__FreeBSD__)
5959 macc_role = (void *)ptr;
5960 #endif
5961 macc_role->w0 =
5962 le32_encode_bits(0, RTW89_H2C_SCANOFLD_BE_MACC_ROLE_W0_BAND) |
5963 le32_encode_bits(0, RTW89_H2C_SCANOFLD_BE_MACC_ROLE_W0_PORT) |
5964 le32_encode_bits(0, RTW89_H2C_SCANOFLD_BE_MACC_ROLE_W0_MACID) |
5965 le32_encode_bits(0, RTW89_H2C_SCANOFLD_BE_MACC_ROLE_W0_OPCH_END);
5966 ptr += sizeof(*macc_role);
5967 }
5968
5969 for (i = 0; i < option->num_opch; i++) {
5970 bool is_ap_idx = i == ap_idx;
5971
5972 opmode = is_ap_idx ? RTW89_SCAN_OPMODE_TBTT : RTW89_SCAN_OPMODE_INTV;
5973 policy_val = is_ap_idx ? 2 : RTW89_OFF_CHAN_TIME / 10;
5974 txbcn = is_ap_idx ? 1 : 0;
5975
5976 #if defined(__linux__)
5977 opch = ptr;
5978 #elif defined(__FreeBSD__)
5979 opch = (void *)ptr;
5980 #endif
5981 opch->w0 = le32_encode_bits(scan_op[i].macid,
5982 RTW89_H2C_SCANOFLD_BE_OPCH_W0_MACID) |
5983 le32_encode_bits(option->band,
5984 RTW89_H2C_SCANOFLD_BE_OPCH_W0_BAND) |
5985 le32_encode_bits(scan_op[i].port,
5986 RTW89_H2C_SCANOFLD_BE_OPCH_W0_PORT) |
5987 le32_encode_bits(opmode,
5988 RTW89_H2C_SCANOFLD_BE_OPCH_W0_POLICY) |
5989 le32_encode_bits(true,
5990 RTW89_H2C_SCANOFLD_BE_OPCH_W0_TXNULL) |
5991 le32_encode_bits(policy_val,
5992 RTW89_H2C_SCANOFLD_BE_OPCH_W0_POLICY_VAL);
5993
5994 opch->w1 = le32_encode_bits(scan_op[i].chan.band_type,
5995 RTW89_H2C_SCANOFLD_BE_OPCH_W1_CH_BAND) |
5996 le32_encode_bits(scan_op[i].chan.band_width,
5997 RTW89_H2C_SCANOFLD_BE_OPCH_W1_BW) |
5998 le32_encode_bits(0x3,
5999 RTW89_H2C_SCANOFLD_BE_OPCH_W1_NOTIFY) |
6000 le32_encode_bits(scan_op[i].chan.primary_channel,
6001 RTW89_H2C_SCANOFLD_BE_OPCH_W1_PRI_CH) |
6002 le32_encode_bits(scan_op[i].chan.channel,
6003 RTW89_H2C_SCANOFLD_BE_OPCH_W1_CENTRAL_CH);
6004
6005 opch->w2 = le32_encode_bits(0,
6006 RTW89_H2C_SCANOFLD_BE_OPCH_W2_PKTS_CTRL) |
6007 le32_encode_bits(0,
6008 RTW89_H2C_SCANOFLD_BE_OPCH_W2_SW_DEF) |
6009 le32_encode_bits(rtw89_is_mlo_1_1(rtwdev) ? 1 : 2,
6010 RTW89_H2C_SCANOFLD_BE_OPCH_W2_SS) |
6011 le32_encode_bits(txbcn,
6012 RTW89_H2C_SCANOFLD_BE_OPCH_W2_TXBCN);
6013
6014 opch->w3 = le32_encode_bits(RTW89_SCANOFLD_PKT_NONE,
6015 RTW89_H2C_SCANOFLD_BE_OPCH_W3_PKT0) |
6016 le32_encode_bits(RTW89_SCANOFLD_PKT_NONE,
6017 RTW89_H2C_SCANOFLD_BE_OPCH_W3_PKT1) |
6018 le32_encode_bits(RTW89_SCANOFLD_PKT_NONE,
6019 RTW89_H2C_SCANOFLD_BE_OPCH_W3_PKT2) |
6020 le32_encode_bits(RTW89_SCANOFLD_PKT_NONE,
6021 RTW89_H2C_SCANOFLD_BE_OPCH_W3_PKT3);
6022
6023 if (ver == 0)
6024 opch->w1 |= le32_encode_bits(RTW89_CHANNEL_TIME,
6025 RTW89_H2C_SCANOFLD_BE_OPCH_W1_DURATION);
6026 else
6027 opch->w4 = le32_encode_bits(RTW89_CHANNEL_TIME,
6028 RTW89_H2C_SCANOFLD_BE_OPCH_W4_DURATION_V1);
6029 ptr += sizeof(*opch);
6030 }
6031
6032 rtw89_h2c_pkt_set_hdr(rtwdev, skb, FWCMD_TYPE_H2C,
6033 H2C_CAT_MAC, H2C_CL_MAC_FW_OFLD,
6034 H2C_FUNC_SCANOFLD_BE, 1, 1,
6035 len);
6036
6037 if (option->enable)
6038 cond = RTW89_SCANOFLD_BE_WAIT_COND_START;
6039 else
6040 cond = RTW89_SCANOFLD_BE_WAIT_COND_STOP;
6041
6042 ret = rtw89_h2c_tx_and_wait(rtwdev, skb, wait, cond);
6043 if (ret) {
6044 rtw89_debug(rtwdev, RTW89_DBG_FW, "failed to scan be ofld\n");
6045 return ret;
6046 }
6047
6048 return 0;
6049 }
6050
6051 int rtw89_fw_h2c_rf_reg(struct rtw89_dev *rtwdev,
6052 struct rtw89_fw_h2c_rf_reg_info *info,
6053 u16 len, u8 page)
6054 {
6055 struct sk_buff *skb;
6056 u8 class = info->rf_path == RF_PATH_A ?
6057 H2C_CL_OUTSRC_RF_REG_A : H2C_CL_OUTSRC_RF_REG_B;
6058 int ret;
6059
6060 skb = rtw89_fw_h2c_alloc_skb_with_hdr(rtwdev, len);
6061 if (!skb) {
6062 rtw89_err(rtwdev, "failed to alloc skb for h2c rf reg\n");
6063 return -ENOMEM;
6064 }
6065 skb_put_data(skb, info->rtw89_phy_config_rf_h2c[page], len);
6066
6067 rtw89_h2c_pkt_set_hdr(rtwdev, skb, FWCMD_TYPE_H2C,
6068 H2C_CAT_OUTSRC, class, page, 0, 0,
6069 len);
6070
6071 ret = rtw89_h2c_tx(rtwdev, skb, false);
6072 if (ret) {
6073 rtw89_err(rtwdev, "failed to send h2c\n");
6074 goto fail;
6075 }
6076
6077 return 0;
6078 fail:
6079 dev_kfree_skb_any(skb);
6080
6081 return ret;
6082 }
6083
6084 int rtw89_fw_h2c_rf_ntfy_mcc(struct rtw89_dev *rtwdev)
6085 {
6086 struct rtw89_rfk_mcc_info_data *rfk_mcc = rtwdev->rfk_mcc.data;
6087 struct rtw89_fw_h2c_rf_get_mccch_v0 *mccch_v0;
6088 struct rtw89_fw_h2c_rf_get_mccch *mccch;
6089 u32 len = sizeof(*mccch);
6090 struct sk_buff *skb;
6091 u8 ver = U8_MAX;
6092 int ret;
6093 u8 idx;
6094
6095 if (RTW89_CHK_FW_FEATURE(RFK_NTFY_MCC_V0, &rtwdev->fw)) {
6096 len = sizeof(*mccch_v0);
6097 ver = 0;
6098 }
6099
6100 skb = rtw89_fw_h2c_alloc_skb_with_hdr(rtwdev, len);
6101 if (!skb) {
6102 rtw89_err(rtwdev, "failed to alloc skb for h2c cxdrv_ctrl\n");
6103 return -ENOMEM;
6104 }
6105 skb_put(skb, len);
6106
6107 idx = rfk_mcc->table_idx;
6108 if (ver == 0) {
6109 mccch_v0 = (struct rtw89_fw_h2c_rf_get_mccch_v0 *)skb->data;
6110 mccch_v0->ch_0 = cpu_to_le32(rfk_mcc->ch[0]);
6111 mccch_v0->ch_1 = cpu_to_le32(rfk_mcc->ch[1]);
6112 mccch_v0->band_0 = cpu_to_le32(rfk_mcc->band[0]);
6113 mccch_v0->band_1 = cpu_to_le32(rfk_mcc->band[1]);
6114 mccch_v0->current_band_type = cpu_to_le32(rfk_mcc->band[idx]);
6115 mccch_v0->current_channel = cpu_to_le32(rfk_mcc->ch[idx]);
6116 } else {
6117 mccch = (struct rtw89_fw_h2c_rf_get_mccch *)skb->data;
6118 mccch->ch_0_0 = cpu_to_le32(rfk_mcc->ch[0]);
6119 mccch->ch_0_1 = cpu_to_le32(rfk_mcc->ch[0]);
6120 mccch->ch_1_0 = cpu_to_le32(rfk_mcc->ch[1]);
6121 mccch->ch_1_1 = cpu_to_le32(rfk_mcc->ch[1]);
6122 mccch->current_channel = cpu_to_le32(rfk_mcc->ch[idx]);
6123 }
6124
6125 rtw89_h2c_pkt_set_hdr(rtwdev, skb, FWCMD_TYPE_H2C,
6126 H2C_CAT_OUTSRC, H2C_CL_OUTSRC_RF_FW_NOTIFY,
6127 H2C_FUNC_OUTSRC_RF_GET_MCCCH, 0, 0,
6128 len);
6129
6130 ret = rtw89_h2c_tx(rtwdev, skb, false);
6131 if (ret) {
6132 rtw89_err(rtwdev, "failed to send h2c\n");
6133 goto fail;
6134 }
6135
6136 return 0;
6137 fail:
6138 dev_kfree_skb_any(skb);
6139
6140 return ret;
6141 }
6142 EXPORT_SYMBOL(rtw89_fw_h2c_rf_ntfy_mcc);
6143
6144 int rtw89_fw_h2c_mcc_dig(struct rtw89_dev *rtwdev,
6145 enum rtw89_chanctx_idx chanctx_idx,
6146 u8 mcc_role_idx, u8 pd_val, bool en)
6147 {
6148 const struct rtw89_chan *chan = rtw89_chan_get(rtwdev, chanctx_idx);
6149 const struct rtw89_dig_regs *dig_regs = rtwdev->chip->dig_regs;
6150 struct rtw89_h2c_mcc_dig *h2c;
6151 u32 len = sizeof(*h2c);
6152 struct sk_buff *skb;
6153 int ret;
6154
6155 skb = rtw89_fw_h2c_alloc_skb_with_hdr(rtwdev, len);
6156 if (!skb) {
6157 rtw89_err(rtwdev, "failed to alloc skb for h2c mcc_dig\n");
6158 return -ENOMEM;
6159 }
6160 skb_put(skb, len);
6161 h2c = (struct rtw89_h2c_mcc_dig *)skb->data;
6162
6163 h2c->w0 = le32_encode_bits(1, RTW89_H2C_MCC_DIG_W0_REG_CNT) |
6164 le32_encode_bits(en, RTW89_H2C_MCC_DIG_W0_DM_EN) |
6165 le32_encode_bits(mcc_role_idx, RTW89_H2C_MCC_DIG_W0_IDX) |
6166 le32_encode_bits(1, RTW89_H2C_MCC_DIG_W0_SET) |
6167 le32_encode_bits(1, RTW89_H2C_MCC_DIG_W0_PHY0_EN) |
6168 le32_encode_bits(chan->channel, RTW89_H2C_MCC_DIG_W0_CENTER_CH) |
6169 le32_encode_bits(chan->band_type, RTW89_H2C_MCC_DIG_W0_BAND_TYPE);
6170 h2c->w1 = le32_encode_bits(dig_regs->seg0_pd_reg,
6171 RTW89_H2C_MCC_DIG_W1_ADDR_LSB) |
6172 le32_encode_bits(dig_regs->seg0_pd_reg >> 8,
6173 RTW89_H2C_MCC_DIG_W1_ADDR_MSB) |
6174 le32_encode_bits(dig_regs->pd_lower_bound_mask,
6175 RTW89_H2C_MCC_DIG_W1_BMASK_LSB) |
6176 le32_encode_bits(dig_regs->pd_lower_bound_mask >> 8,
6177 RTW89_H2C_MCC_DIG_W1_BMASK_MSB);
6178 h2c->w2 = le32_encode_bits(pd_val, RTW89_H2C_MCC_DIG_W2_VAL_LSB);
6179
6180 rtw89_h2c_pkt_set_hdr(rtwdev, skb, FWCMD_TYPE_H2C,
6181 H2C_CAT_OUTSRC, H2C_CL_OUTSRC_DM,
6182 H2C_FUNC_FW_MCC_DIG, 0, 0, len);
6183
6184 ret = rtw89_h2c_tx(rtwdev, skb, false);
6185 if (ret) {
6186 rtw89_err(rtwdev, "failed to send h2c\n");
6187 goto fail;
6188 }
6189
6190 return 0;
6191 fail:
6192 dev_kfree_skb_any(skb);
6193
6194 return ret;
6195 }
6196
6197 int rtw89_fw_h2c_rf_ps_info(struct rtw89_dev *rtwdev, struct rtw89_vif *rtwvif)
6198 {
6199 const struct rtw89_chip_info *chip = rtwdev->chip;
6200 struct rtw89_vif_link *rtwvif_link;
6201 struct rtw89_h2c_rf_ps_info *h2c;
6202 const struct rtw89_chan *chan;
6203 u32 len = sizeof(*h2c);
6204 unsigned int link_id;
6205 struct sk_buff *skb;
6206 int ret;
6207 u8 path;
6208 u32 val;
6209
6210 if (chip->chip_gen != RTW89_CHIP_BE)
6211 return 0;
6212
6213 skb = rtw89_fw_h2c_alloc_skb_with_hdr(rtwdev, len);
6214 if (!skb) {
6215 rtw89_err(rtwdev, "failed to alloc skb for h2c rf ps info\n");
6216 return -ENOMEM;
6217 }
6218 skb_put(skb, len);
6219 h2c = (struct rtw89_h2c_rf_ps_info *)skb->data;
6220 h2c->mlo_mode = cpu_to_le32(rtwdev->mlo_dbcc_mode);
6221
6222 rtw89_vif_for_each_link(rtwvif, rtwvif_link, link_id) {
6223 chan = rtw89_chan_get(rtwdev, rtwvif_link->chanctx_idx);
6224 path = rtw89_phy_get_syn_sel(rtwdev, rtwvif_link->phy_idx);
6225 val = rtw89_chip_chan_to_rf18_val(rtwdev, chan);
6226
6227 if (path >= chip->rf_path_num || path >= NUM_OF_RTW89_FW_RFK_PATH) {
6228 rtw89_err(rtwdev, "unsupported rf path (%d)\n", path);
6229 ret = -ENOENT;
6230 goto fail;
6231 }
6232
6233 h2c->rf18[path] = cpu_to_le32(val);
6234 h2c->pri_ch[path] = chan->primary_channel;
6235 }
6236
6237 rtw89_h2c_pkt_set_hdr(rtwdev, skb, FWCMD_TYPE_H2C,
6238 H2C_CAT_OUTSRC, H2C_CL_OUTSRC_RF_FW_NOTIFY,
6239 H2C_FUNC_OUTSRC_RF_PS_INFO, 0, 0,
6240 sizeof(*h2c));
6241
6242 ret = rtw89_h2c_tx(rtwdev, skb, false);
6243 if (ret) {
6244 rtw89_err(rtwdev, "failed to send h2c\n");
6245 goto fail;
6246 }
6247
6248 return 0;
6249 fail:
6250 dev_kfree_skb_any(skb);
6251
6252 return ret;
6253 }
6254 EXPORT_SYMBOL(rtw89_fw_h2c_rf_ps_info);
6255
6256 int rtw89_fw_h2c_rf_pre_ntfy(struct rtw89_dev *rtwdev,
6257 enum rtw89_phy_idx phy_idx)
6258 {
6259 struct rtw89_rfk_mcc_info *rfk_mcc = &rtwdev->rfk_mcc;
6260 struct rtw89_fw_h2c_rfk_pre_info_common *common;
6261 struct rtw89_fw_h2c_rfk_pre_info_v0 *h2c_v0;
6262 struct rtw89_fw_h2c_rfk_pre_info_v1 *h2c_v1;
6263 struct rtw89_fw_h2c_rfk_pre_info *h2c;
6264 u8 tbl_sel[NUM_OF_RTW89_FW_RFK_PATH];
6265 u32 len = sizeof(*h2c);
6266 struct sk_buff *skb;
6267 u8 ver = U8_MAX;
6268 u8 tbl, path;
6269 u32 val32;
6270 int ret;
6271
6272 if (RTW89_CHK_FW_FEATURE(RFK_PRE_NOTIFY_V1, &rtwdev->fw)) {
6273 len = sizeof(*h2c_v1);
6274 ver = 1;
6275 } else if (RTW89_CHK_FW_FEATURE(RFK_PRE_NOTIFY_V0, &rtwdev->fw)) {
6276 len = sizeof(*h2c_v0);
6277 ver = 0;
6278 }
6279
6280 skb = rtw89_fw_h2c_alloc_skb_with_hdr(rtwdev, len);
6281 if (!skb) {
6282 rtw89_err(rtwdev, "failed to alloc skb for h2c rfk_pre_ntfy\n");
6283 return -ENOMEM;
6284 }
6285 skb_put(skb, len);
6286 h2c = (struct rtw89_fw_h2c_rfk_pre_info *)skb->data;
6287 common = &h2c->base_v1.common;
6288
6289 common->mlo_mode = cpu_to_le32(rtwdev->mlo_dbcc_mode);
6290
6291 BUILD_BUG_ON(NUM_OF_RTW89_FW_RFK_TBL > RTW89_RFK_CHS_NR);
6292 BUILD_BUG_ON(ARRAY_SIZE(rfk_mcc->data) < NUM_OF_RTW89_FW_RFK_PATH);
6293
6294 for (tbl = 0; tbl < NUM_OF_RTW89_FW_RFK_TBL; tbl++) {
6295 for (path = 0; path < NUM_OF_RTW89_FW_RFK_PATH; path++) {
6296 common->dbcc.ch[path][tbl] =
6297 cpu_to_le32(rfk_mcc->data[path].ch[tbl]);
6298 common->dbcc.band[path][tbl] =
6299 cpu_to_le32(rfk_mcc->data[path].band[tbl]);
6300 }
6301 }
6302
6303 for (path = 0; path < NUM_OF_RTW89_FW_RFK_PATH; path++) {
6304 tbl_sel[path] = rfk_mcc->data[path].table_idx;
6305
6306 common->tbl.cur_ch[path] =
6307 cpu_to_le32(rfk_mcc->data[path].ch[tbl_sel[path]]);
6308 common->tbl.cur_band[path] =
6309 cpu_to_le32(rfk_mcc->data[path].band[tbl_sel[path]]);
6310
6311 if (ver <= 1)
6312 continue;
6313
6314 h2c->cur_bandwidth[path] =
6315 cpu_to_le32(rfk_mcc->data[path].bw[tbl_sel[path]]);
6316 }
6317
6318 common->phy_idx = cpu_to_le32(phy_idx);
6319
6320 if (ver == 0) { /* RFK_PRE_NOTIFY_V0 */
6321 h2c_v0 = (struct rtw89_fw_h2c_rfk_pre_info_v0 *)skb->data;
6322
6323 h2c_v0->cur_band = cpu_to_le32(rfk_mcc->data[0].band[tbl_sel[0]]);
6324 h2c_v0->cur_bw = cpu_to_le32(rfk_mcc->data[0].bw[tbl_sel[0]]);
6325 h2c_v0->cur_center_ch = cpu_to_le32(rfk_mcc->data[0].ch[tbl_sel[0]]);
6326
6327 val32 = rtw89_phy_read32_mask(rtwdev, R_COEF_SEL, B_COEF_SEL_IQC_V1);
6328 h2c_v0->ktbl_sel0 = cpu_to_le32(val32);
6329 val32 = rtw89_phy_read32_mask(rtwdev, R_COEF_SEL_C1, B_COEF_SEL_IQC_V1);
6330 h2c_v0->ktbl_sel1 = cpu_to_le32(val32);
6331 val32 = rtw89_read_rf(rtwdev, RF_PATH_A, RR_CFGCH, RFREG_MASK);
6332 h2c_v0->rfmod0 = cpu_to_le32(val32);
6333 val32 = rtw89_read_rf(rtwdev, RF_PATH_B, RR_CFGCH, RFREG_MASK);
6334 h2c_v0->rfmod1 = cpu_to_le32(val32);
6335
6336 if (rtw89_is_mlo_1_1(rtwdev))
6337 h2c_v0->mlo_1_1 = cpu_to_le32(1);
6338
6339 h2c_v0->rfe_type = cpu_to_le32(rtwdev->efuse.rfe_type);
6340
6341 goto done;
6342 }
6343
6344 if (rtw89_is_mlo_1_1(rtwdev)) {
6345 h2c_v1 = &h2c->base_v1;
6346 h2c_v1->mlo_1_1 = cpu_to_le32(1);
6347 }
6348 done:
6349 rtw89_h2c_pkt_set_hdr(rtwdev, skb, FWCMD_TYPE_H2C,
6350 H2C_CAT_OUTSRC, H2C_CL_OUTSRC_RF_FW_RFK,
6351 H2C_FUNC_RFK_PRE_NOTIFY, 0, 0,
6352 len);
6353
6354 ret = rtw89_h2c_tx(rtwdev, skb, false);
6355 if (ret) {
6356 rtw89_err(rtwdev, "failed to send h2c\n");
6357 goto fail;
6358 }
6359
6360 return 0;
6361 fail:
6362 dev_kfree_skb_any(skb);
6363
6364 return ret;
6365 }
6366
6367 int rtw89_fw_h2c_rf_tssi(struct rtw89_dev *rtwdev, enum rtw89_phy_idx phy_idx,
6368 const struct rtw89_chan *chan, enum rtw89_tssi_mode tssi_mode)
6369 {
6370 struct rtw89_efuse *efuse = &rtwdev->efuse;
6371 struct rtw89_hal *hal = &rtwdev->hal;
6372 struct rtw89_h2c_rf_tssi *h2c;
6373 u32 len = sizeof(*h2c);
6374 struct sk_buff *skb;
6375 int ret;
6376
6377 skb = rtw89_fw_h2c_alloc_skb_with_hdr(rtwdev, len);
6378 if (!skb) {
6379 rtw89_err(rtwdev, "failed to alloc skb for h2c RF TSSI\n");
6380 return -ENOMEM;
6381 }
6382 skb_put(skb, len);
6383 h2c = (struct rtw89_h2c_rf_tssi *)skb->data;
6384
6385 h2c->len = cpu_to_le16(len);
6386 h2c->phy = phy_idx;
6387 h2c->ch = chan->channel;
6388 h2c->bw = chan->band_width;
6389 h2c->band = chan->band_type;
6390 h2c->hwtx_en = true;
6391 h2c->cv = hal->cv;
6392 h2c->tssi_mode = tssi_mode;
6393 h2c->rfe_type = efuse->rfe_type;
6394
6395 rtw89_phy_rfk_tssi_fill_fwcmd_efuse_to_de(rtwdev, phy_idx, chan, h2c);
6396 rtw89_phy_rfk_tssi_fill_fwcmd_tmeter_tbl(rtwdev, phy_idx, chan, h2c);
6397
6398 rtw89_h2c_pkt_set_hdr(rtwdev, skb, FWCMD_TYPE_H2C,
6399 H2C_CAT_OUTSRC, H2C_CL_OUTSRC_RF_FW_RFK,
6400 H2C_FUNC_RFK_TSSI_OFFLOAD, 0, 0, len);
6401
6402 ret = rtw89_h2c_tx(rtwdev, skb, false);
6403 if (ret) {
6404 rtw89_err(rtwdev, "failed to send h2c\n");
6405 goto fail;
6406 }
6407
6408 return 0;
6409 fail:
6410 dev_kfree_skb_any(skb);
6411
6412 return ret;
6413 }
6414
6415 int rtw89_fw_h2c_rf_iqk(struct rtw89_dev *rtwdev, enum rtw89_phy_idx phy_idx,
6416 const struct rtw89_chan *chan)
6417 {
6418 struct rtw89_hal *hal = &rtwdev->hal;
6419 struct rtw89_h2c_rf_iqk_v0 *h2c_v0;
6420 struct rtw89_h2c_rf_iqk *h2c;
6421 u32 len = sizeof(*h2c);
6422 struct sk_buff *skb;
6423 u8 ver = U8_MAX;
6424 int ret;
6425
6426 if (RTW89_CHK_FW_FEATURE(RFK_IQK_V0, &rtwdev->fw)) {
6427 len = sizeof(*h2c_v0);
6428 ver = 0;
6429 }
6430
6431 skb = rtw89_fw_h2c_alloc_skb_with_hdr(rtwdev, len);
6432 if (!skb) {
6433 rtw89_err(rtwdev, "failed to alloc skb for h2c RF IQK\n");
6434 return -ENOMEM;
6435 }
6436 skb_put(skb, len);
6437
6438 if (ver == 0) {
6439 h2c_v0 = (struct rtw89_h2c_rf_iqk_v0 *)skb->data;
6440
6441 h2c_v0->phy_idx = cpu_to_le32(phy_idx);
6442 h2c_v0->dbcc = cpu_to_le32(rtwdev->dbcc_en);
6443
6444 goto done;
6445 }
6446
6447 h2c = (struct rtw89_h2c_rf_iqk *)skb->data;
6448
6449 h2c->len = sizeof(*h2c);
6450 h2c->ktype = 0;
6451 h2c->phy = phy_idx;
6452 h2c->kpath = rtw89_phy_get_kpath(rtwdev, phy_idx);
6453 h2c->band = chan->band_type;
6454 h2c->bw = chan->band_width;
6455 h2c->ch = chan->channel;
6456 h2c->cv = hal->cv;
6457
6458 done:
6459 rtw89_h2c_pkt_set_hdr(rtwdev, skb, FWCMD_TYPE_H2C,
6460 H2C_CAT_OUTSRC, H2C_CL_OUTSRC_RF_FW_RFK,
6461 H2C_FUNC_RFK_IQK_OFFLOAD, 0, 0, len);
6462
6463 ret = rtw89_h2c_tx(rtwdev, skb, false);
6464 if (ret) {
6465 rtw89_err(rtwdev, "failed to send h2c\n");
6466 goto fail;
6467 }
6468
6469 return 0;
6470 fail:
6471 dev_kfree_skb_any(skb);
6472
6473 return ret;
6474 }
6475
6476 int rtw89_fw_h2c_rf_dpk(struct rtw89_dev *rtwdev, enum rtw89_phy_idx phy_idx,
6477 const struct rtw89_chan *chan)
6478 {
6479 struct rtw89_h2c_rf_dpk *h2c;
6480 u32 len = sizeof(*h2c);
6481 struct sk_buff *skb;
6482 int ret;
6483
6484 skb = rtw89_fw_h2c_alloc_skb_with_hdr(rtwdev, len);
6485 if (!skb) {
6486 rtw89_err(rtwdev, "failed to alloc skb for h2c RF DPK\n");
6487 return -ENOMEM;
6488 }
6489 skb_put(skb, len);
6490 h2c = (struct rtw89_h2c_rf_dpk *)skb->data;
6491
6492 h2c->len = len;
6493 h2c->phy = phy_idx;
6494 h2c->dpk_enable = true;
6495 h2c->kpath = RF_AB;
6496 h2c->cur_band = chan->band_type;
6497 h2c->cur_bw = chan->band_width;
6498 h2c->cur_ch = chan->channel;
6499 h2c->dpk_dbg_en = rtw89_debug_is_enabled(rtwdev, RTW89_DBG_RFK);
6500
6501 rtw89_h2c_pkt_set_hdr(rtwdev, skb, FWCMD_TYPE_H2C,
6502 H2C_CAT_OUTSRC, H2C_CL_OUTSRC_RF_FW_RFK,
6503 H2C_FUNC_RFK_DPK_OFFLOAD, 0, 0, len);
6504
6505 ret = rtw89_h2c_tx(rtwdev, skb, false);
6506 if (ret) {
6507 rtw89_err(rtwdev, "failed to send h2c\n");
6508 goto fail;
6509 }
6510
6511 return 0;
6512 fail:
6513 dev_kfree_skb_any(skb);
6514
6515 return ret;
6516 }
6517
6518 int rtw89_fw_h2c_rf_txgapk(struct rtw89_dev *rtwdev, enum rtw89_phy_idx phy_idx,
6519 const struct rtw89_chan *chan)
6520 {
6521 struct rtw89_hal *hal = &rtwdev->hal;
6522 struct rtw89_h2c_rf_txgapk *h2c;
6523 u32 len = sizeof(*h2c);
6524 struct sk_buff *skb;
6525 int ret;
6526
6527 skb = rtw89_fw_h2c_alloc_skb_with_hdr(rtwdev, len);
6528 if (!skb) {
6529 rtw89_err(rtwdev, "failed to alloc skb for h2c RF TXGAPK\n");
6530 return -ENOMEM;
6531 }
6532 skb_put(skb, len);
6533 h2c = (struct rtw89_h2c_rf_txgapk *)skb->data;
6534
6535 h2c->len = len;
6536 h2c->ktype = 2;
6537 h2c->phy = phy_idx;
6538 h2c->kpath = RF_AB;
6539 h2c->band = chan->band_type;
6540 h2c->bw = chan->band_width;
6541 h2c->ch = chan->channel;
6542 h2c->cv = hal->cv;
6543
6544 rtw89_h2c_pkt_set_hdr(rtwdev, skb, FWCMD_TYPE_H2C,
6545 H2C_CAT_OUTSRC, H2C_CL_OUTSRC_RF_FW_RFK,
6546 H2C_FUNC_RFK_TXGAPK_OFFLOAD, 0, 0, len);
6547
6548 ret = rtw89_h2c_tx(rtwdev, skb, false);
6549 if (ret) {
6550 rtw89_err(rtwdev, "failed to send h2c\n");
6551 goto fail;
6552 }
6553
6554 return 0;
6555 fail:
6556 dev_kfree_skb_any(skb);
6557
6558 return ret;
6559 }
6560
6561 int rtw89_fw_h2c_rf_dack(struct rtw89_dev *rtwdev, enum rtw89_phy_idx phy_idx,
6562 const struct rtw89_chan *chan)
6563 {
6564 struct rtw89_h2c_rf_dack *h2c;
6565 u32 len = sizeof(*h2c);
6566 struct sk_buff *skb;
6567 int ret;
6568
6569 skb = rtw89_fw_h2c_alloc_skb_with_hdr(rtwdev, len);
6570 if (!skb) {
6571 rtw89_err(rtwdev, "failed to alloc skb for h2c RF DACK\n");
6572 return -ENOMEM;
6573 }
6574 skb_put(skb, len);
6575 h2c = (struct rtw89_h2c_rf_dack *)skb->data;
6576
6577 h2c->len = cpu_to_le32(len);
6578 h2c->phy = cpu_to_le32(phy_idx);
6579 h2c->type = cpu_to_le32(0);
6580
6581 rtw89_h2c_pkt_set_hdr(rtwdev, skb, FWCMD_TYPE_H2C,
6582 H2C_CAT_OUTSRC, H2C_CL_OUTSRC_RF_FW_RFK,
6583 H2C_FUNC_RFK_DACK_OFFLOAD, 0, 0, len);
6584
6585 ret = rtw89_h2c_tx(rtwdev, skb, false);
6586 if (ret) {
6587 rtw89_err(rtwdev, "failed to send h2c\n");
6588 goto fail;
6589 }
6590
6591 return 0;
6592 fail:
6593 dev_kfree_skb_any(skb);
6594
6595 return ret;
6596 }
6597
6598 int rtw89_fw_h2c_rf_rxdck(struct rtw89_dev *rtwdev, enum rtw89_phy_idx phy_idx,
6599 const struct rtw89_chan *chan, bool is_chl_k)
6600 {
6601 struct rtw89_h2c_rf_rxdck_v0 *v0;
6602 struct rtw89_h2c_rf_rxdck *h2c;
6603 u32 len = sizeof(*h2c);
6604 struct sk_buff *skb;
6605 int ver = -1;
6606 int ret;
6607
6608 if (RTW89_CHK_FW_FEATURE(RFK_RXDCK_V0, &rtwdev->fw)) {
6609 len = sizeof(*v0);
6610 ver = 0;
6611 }
6612
6613 skb = rtw89_fw_h2c_alloc_skb_with_hdr(rtwdev, len);
6614 if (!skb) {
6615 rtw89_err(rtwdev, "failed to alloc skb for h2c RF RXDCK\n");
6616 return -ENOMEM;
6617 }
6618 skb_put(skb, len);
6619 v0 = (struct rtw89_h2c_rf_rxdck_v0 *)skb->data;
6620
6621 v0->len = len;
6622 v0->phy = phy_idx;
6623 v0->is_afe = false;
6624 v0->kpath = RF_AB;
6625 v0->cur_band = chan->band_type;
6626 v0->cur_bw = chan->band_width;
6627 v0->cur_ch = chan->channel;
6628 v0->rxdck_dbg_en = rtw89_debug_is_enabled(rtwdev, RTW89_DBG_RFK);
6629
6630 if (ver == 0)
6631 goto hdr;
6632
6633 h2c = (struct rtw89_h2c_rf_rxdck *)skb->data;
6634 h2c->is_chl_k = is_chl_k;
6635
6636 hdr:
6637 rtw89_h2c_pkt_set_hdr(rtwdev, skb, FWCMD_TYPE_H2C,
6638 H2C_CAT_OUTSRC, H2C_CL_OUTSRC_RF_FW_RFK,
6639 H2C_FUNC_RFK_RXDCK_OFFLOAD, 0, 0, len);
6640
6641 ret = rtw89_h2c_tx(rtwdev, skb, false);
6642 if (ret) {
6643 rtw89_err(rtwdev, "failed to send h2c\n");
6644 goto fail;
6645 }
6646
6647 return 0;
6648 fail:
6649 dev_kfree_skb_any(skb);
6650
6651 return ret;
6652 }
6653
6654 int rtw89_fw_h2c_raw_with_hdr(struct rtw89_dev *rtwdev,
6655 u8 h2c_class, u8 h2c_func, u8 *buf, u16 len,
6656 bool rack, bool dack)
6657 {
6658 struct sk_buff *skb;
6659 int ret;
6660
6661 skb = rtw89_fw_h2c_alloc_skb_with_hdr(rtwdev, len);
6662 if (!skb) {
6663 rtw89_err(rtwdev, "failed to alloc skb for raw with hdr\n");
6664 return -ENOMEM;
6665 }
6666 skb_put_data(skb, buf, len);
6667
6668 rtw89_h2c_pkt_set_hdr(rtwdev, skb, FWCMD_TYPE_H2C,
6669 H2C_CAT_OUTSRC, h2c_class, h2c_func, rack, dack,
6670 len);
6671
6672 ret = rtw89_h2c_tx(rtwdev, skb, false);
6673 if (ret) {
6674 rtw89_err(rtwdev, "failed to send h2c\n");
6675 goto fail;
6676 }
6677
6678 return 0;
6679 fail:
6680 dev_kfree_skb_any(skb);
6681
6682 return ret;
6683 }
6684
6685 int rtw89_fw_h2c_raw(struct rtw89_dev *rtwdev, const u8 *buf, u16 len)
6686 {
6687 struct sk_buff *skb;
6688 int ret;
6689
6690 skb = rtw89_fw_h2c_alloc_skb_no_hdr(rtwdev, len);
6691 if (!skb) {
6692 rtw89_err(rtwdev, "failed to alloc skb for h2c raw\n");
6693 return -ENOMEM;
6694 }
6695 skb_put_data(skb, buf, len);
6696
6697 ret = rtw89_h2c_tx(rtwdev, skb, false);
6698 if (ret) {
6699 rtw89_err(rtwdev, "failed to send h2c\n");
6700 goto fail;
6701 }
6702
6703 return 0;
6704 fail:
6705 dev_kfree_skb_any(skb);
6706
6707 return ret;
6708 }
6709
6710 void rtw89_fw_send_all_early_h2c(struct rtw89_dev *rtwdev)
6711 {
6712 struct rtw89_early_h2c *early_h2c;
6713
6714 lockdep_assert_wiphy(rtwdev->hw->wiphy);
6715
6716 list_for_each_entry(early_h2c, &rtwdev->early_h2c_list, list) {
6717 rtw89_fw_h2c_raw(rtwdev, early_h2c->h2c, early_h2c->h2c_len);
6718 }
6719 }
6720
6721 void __rtw89_fw_free_all_early_h2c(struct rtw89_dev *rtwdev)
6722 {
6723 struct rtw89_early_h2c *early_h2c, *tmp;
6724
6725 list_for_each_entry_safe(early_h2c, tmp, &rtwdev->early_h2c_list, list) {
6726 list_del(&early_h2c->list);
6727 kfree(early_h2c->h2c);
6728 kfree(early_h2c);
6729 }
6730 }
6731
6732 void rtw89_fw_free_all_early_h2c(struct rtw89_dev *rtwdev)
6733 {
6734 lockdep_assert_wiphy(rtwdev->hw->wiphy);
6735
6736 __rtw89_fw_free_all_early_h2c(rtwdev);
6737 }
6738
6739 static void rtw89_fw_c2h_parse_attr(struct sk_buff *c2h)
6740 {
6741 const struct rtw89_c2h_hdr *hdr = (const struct rtw89_c2h_hdr *)c2h->data;
6742 struct rtw89_fw_c2h_attr *attr = RTW89_SKB_C2H_CB(c2h);
6743
6744 attr->category = le32_get_bits(hdr->w0, RTW89_C2H_HDR_W0_CATEGORY);
6745 attr->class = le32_get_bits(hdr->w0, RTW89_C2H_HDR_W0_CLASS);
6746 attr->func = le32_get_bits(hdr->w0, RTW89_C2H_HDR_W0_FUNC);
6747 attr->len = le32_get_bits(hdr->w1, RTW89_C2H_HDR_W1_LEN);
6748 }
6749
6750 static bool rtw89_fw_c2h_chk_atomic(struct rtw89_dev *rtwdev,
6751 struct sk_buff *c2h)
6752 {
6753 struct rtw89_fw_c2h_attr *attr = RTW89_SKB_C2H_CB(c2h);
6754 u8 category = attr->category;
6755 u8 class = attr->class;
6756 u8 func = attr->func;
6757
6758 switch (category) {
6759 default:
6760 return false;
6761 case RTW89_C2H_CAT_MAC:
6762 return rtw89_mac_c2h_chk_atomic(rtwdev, c2h, class, func);
6763 case RTW89_C2H_CAT_OUTSRC:
6764 return rtw89_phy_c2h_chk_atomic(rtwdev, class, func);
6765 }
6766 }
6767
6768 void rtw89_fw_c2h_irqsafe(struct rtw89_dev *rtwdev, struct sk_buff *c2h)
6769 {
6770 rtw89_fw_c2h_parse_attr(c2h);
6771 if (!rtw89_fw_c2h_chk_atomic(rtwdev, c2h))
6772 goto enqueue;
6773
6774 rtw89_fw_c2h_cmd_handle(rtwdev, c2h);
6775 dev_kfree_skb_any(c2h);
6776 return;
6777
6778 enqueue:
6779 skb_queue_tail(&rtwdev->c2h_queue, c2h);
6780 wiphy_work_queue(rtwdev->hw->wiphy, &rtwdev->c2h_work);
6781 }
6782
6783 static void rtw89_fw_c2h_cmd_handle(struct rtw89_dev *rtwdev,
6784 struct sk_buff *skb)
6785 {
6786 struct rtw89_fw_c2h_attr *attr = RTW89_SKB_C2H_CB(skb);
6787 u8 category = attr->category;
6788 u8 class = attr->class;
6789 u8 func = attr->func;
6790 u16 len = attr->len;
6791 bool dump = true;
6792
6793 if (!test_bit(RTW89_FLAG_RUNNING, rtwdev->flags))
6794 return;
6795
6796 switch (category) {
6797 case RTW89_C2H_CAT_TEST:
6798 break;
6799 case RTW89_C2H_CAT_MAC:
6800 rtw89_mac_c2h_handle(rtwdev, skb, len, class, func);
6801 if (class == RTW89_MAC_C2H_CLASS_INFO &&
6802 func == RTW89_MAC_C2H_FUNC_C2H_LOG)
6803 dump = false;
6804 break;
6805 case RTW89_C2H_CAT_OUTSRC:
6806 if (class >= RTW89_PHY_C2H_CLASS_BTC_MIN &&
6807 class <= RTW89_PHY_C2H_CLASS_BTC_MAX)
6808 rtw89_btc_c2h_handle(rtwdev, skb, len, class, func);
6809 else
6810 rtw89_phy_c2h_handle(rtwdev, skb, len, class, func);
6811 break;
6812 }
6813
6814 if (dump)
6815 rtw89_hex_dump(rtwdev, RTW89_DBG_FW, "C2H: ", skb->data, skb->len);
6816 }
6817
6818 void rtw89_fw_c2h_work(struct wiphy *wiphy, struct wiphy_work *work)
6819 {
6820 struct rtw89_dev *rtwdev = container_of(work, struct rtw89_dev,
6821 c2h_work);
6822 struct sk_buff *skb, *tmp;
6823
6824 lockdep_assert_wiphy(rtwdev->hw->wiphy);
6825
6826 skb_queue_walk_safe(&rtwdev->c2h_queue, skb, tmp) {
6827 skb_unlink(skb, &rtwdev->c2h_queue);
6828 rtw89_fw_c2h_cmd_handle(rtwdev, skb);
6829 dev_kfree_skb_any(skb);
6830 }
6831 }
6832
6833 void rtw89_fw_c2h_purge_obsoleted_scan_events(struct rtw89_dev *rtwdev)
6834 {
6835 struct rtw89_hw_scan_info *scan_info = &rtwdev->scan_info;
6836 struct sk_buff *skb, *tmp;
6837 int limit;
6838
6839 lockdep_assert_wiphy(rtwdev->hw->wiphy);
6840
6841 limit = skb_queue_len(&rtwdev->c2h_queue);
6842
6843 skb_queue_walk_safe(&rtwdev->c2h_queue, skb, tmp) {
6844 struct rtw89_fw_c2h_attr *attr = RTW89_SKB_C2H_CB(skb);
6845
6846 if (--limit < 0)
6847 return;
6848
6849 if (!attr->is_scan_event || attr->scan_seq == scan_info->seq)
6850 continue;
6851
6852 rtw89_debug(rtwdev, RTW89_DBG_HW_SCAN,
6853 "purge obsoleted scan event with seq=%d (cur=%d)\n",
6854 attr->scan_seq, scan_info->seq);
6855
6856 skb_unlink(skb, &rtwdev->c2h_queue);
6857 dev_kfree_skb_any(skb);
6858 }
6859 }
6860
6861 static int rtw89_fw_write_h2c_reg(struct rtw89_dev *rtwdev,
6862 struct rtw89_mac_h2c_info *info)
6863 {
6864 const struct rtw89_chip_info *chip = rtwdev->chip;
6865 struct rtw89_fw_info *fw_info = &rtwdev->fw;
6866 const u32 *h2c_reg = chip->h2c_regs;
6867 u8 i, val, len;
6868 int ret;
6869
6870 ret = read_poll_timeout(rtw89_read8, val, val == 0, 1000, 5000, false,
6871 rtwdev, chip->h2c_ctrl_reg);
6872 if (ret) {
6873 rtw89_warn(rtwdev, "FW does not process h2c registers\n");
6874 return ret;
6875 }
6876
6877 len = DIV_ROUND_UP(info->content_len + RTW89_H2CREG_HDR_LEN,
6878 sizeof(info->u.h2creg[0]));
6879
6880 u32p_replace_bits(&info->u.hdr.w0, info->id, RTW89_H2CREG_HDR_FUNC_MASK);
6881 u32p_replace_bits(&info->u.hdr.w0, len, RTW89_H2CREG_HDR_LEN_MASK);
6882
6883 for (i = 0; i < RTW89_H2CREG_MAX; i++)
6884 rtw89_write32(rtwdev, h2c_reg[i], info->u.h2creg[i]);
6885
6886 fw_info->h2c_counter++;
6887 rtw89_write8_mask(rtwdev, chip->h2c_counter_reg.addr,
6888 chip->h2c_counter_reg.mask, fw_info->h2c_counter);
6889 rtw89_write8(rtwdev, chip->h2c_ctrl_reg, B_AX_H2CREG_TRIGGER);
6890
6891 return 0;
6892 }
6893
6894 static int rtw89_fw_read_c2h_reg(struct rtw89_dev *rtwdev,
6895 struct rtw89_mac_c2h_info *info)
6896 {
6897 const struct rtw89_chip_info *chip = rtwdev->chip;
6898 struct rtw89_fw_info *fw_info = &rtwdev->fw;
6899 const u32 *c2h_reg = chip->c2h_regs;
6900 u32 ret, timeout;
6901 u8 i, val;
6902
6903 info->id = RTW89_FWCMD_C2HREG_FUNC_NULL;
6904
6905 if (rtwdev->hci.type == RTW89_HCI_TYPE_USB)
6906 timeout = RTW89_C2H_TIMEOUT_USB;
6907 else
6908 timeout = RTW89_C2H_TIMEOUT;
6909
6910 ret = read_poll_timeout_atomic(rtw89_read8, val, val, 1,
6911 timeout, false, rtwdev,
6912 chip->c2h_ctrl_reg);
6913 if (ret) {
6914 rtw89_warn(rtwdev, "c2h reg timeout\n");
6915 return ret;
6916 }
6917
6918 for (i = 0; i < RTW89_C2HREG_MAX; i++)
6919 info->u.c2hreg[i] = rtw89_read32(rtwdev, c2h_reg[i]);
6920
6921 rtw89_write8(rtwdev, chip->c2h_ctrl_reg, 0);
6922
6923 info->id = u32_get_bits(info->u.hdr.w0, RTW89_C2HREG_HDR_FUNC_MASK);
6924 info->content_len =
6925 (u32_get_bits(info->u.hdr.w0, RTW89_C2HREG_HDR_LEN_MASK) << 2) -
6926 RTW89_C2HREG_HDR_LEN;
6927
6928 fw_info->c2h_counter++;
6929 rtw89_write8_mask(rtwdev, chip->c2h_counter_reg.addr,
6930 chip->c2h_counter_reg.mask, fw_info->c2h_counter);
6931
6932 return 0;
6933 }
6934
6935 int rtw89_fw_msg_reg(struct rtw89_dev *rtwdev,
6936 struct rtw89_mac_h2c_info *h2c_info,
6937 struct rtw89_mac_c2h_info *c2h_info)
6938 {
6939 u32 ret;
6940
6941 if (h2c_info && h2c_info->id != RTW89_FWCMD_H2CREG_FUNC_GET_FEATURE)
6942 lockdep_assert_wiphy(rtwdev->hw->wiphy);
6943
6944 if (!h2c_info && !c2h_info)
6945 return -EINVAL;
6946
6947 if (!h2c_info)
6948 goto recv_c2h;
6949
6950 ret = rtw89_fw_write_h2c_reg(rtwdev, h2c_info);
6951 if (ret)
6952 return ret;
6953
6954 recv_c2h:
6955 if (!c2h_info)
6956 return 0;
6957
6958 ret = rtw89_fw_read_c2h_reg(rtwdev, c2h_info);
6959 if (ret)
6960 return ret;
6961
6962 return 0;
6963 }
6964
6965 void rtw89_fw_st_dbg_dump(struct rtw89_dev *rtwdev)
6966 {
6967 if (!test_bit(RTW89_FLAG_POWERON, rtwdev->flags)) {
6968 rtw89_err(rtwdev, "[ERR]pwr is off\n");
6969 return;
6970 }
6971
6972 rtw89_info(rtwdev, "FW status = 0x%x\n", rtw89_read32(rtwdev, R_AX_UDM0));
6973 rtw89_info(rtwdev, "FW BADADDR = 0x%x\n", rtw89_read32(rtwdev, R_AX_UDM1));
6974 rtw89_info(rtwdev, "FW EPC/RA = 0x%x\n", rtw89_read32(rtwdev, R_AX_UDM2));
6975 rtw89_info(rtwdev, "FW MISC = 0x%x\n", rtw89_read32(rtwdev, R_AX_UDM3));
6976 rtw89_info(rtwdev, "R_AX_HALT_C2H = 0x%x\n",
6977 rtw89_read32(rtwdev, R_AX_HALT_C2H));
6978 rtw89_info(rtwdev, "R_AX_SER_DBG_INFO = 0x%x\n",
6979 rtw89_read32(rtwdev, R_AX_SER_DBG_INFO));
6980
6981 rtw89_fw_prog_cnt_dump(rtwdev);
6982 }
6983
6984 static void rtw89_hw_scan_release_pkt_list(struct rtw89_dev *rtwdev)
6985 {
6986 struct list_head *pkt_list = rtwdev->scan_info.pkt_list;
6987 struct rtw89_pktofld_info *info, *tmp;
6988 u8 idx;
6989
6990 for (idx = NL80211_BAND_2GHZ; idx < NUM_NL80211_BANDS; idx++) {
6991 if (!(rtwdev->chip->support_bands & BIT(idx)))
6992 continue;
6993
6994 list_for_each_entry_safe(info, tmp, &pkt_list[idx], list) {
6995 if (test_bit(info->id, rtwdev->pkt_offload))
6996 rtw89_fw_h2c_del_pkt_offload(rtwdev, info->id);
6997 list_del(&info->list);
6998 kfree(info);
6999 }
7000 }
7001 }
7002
7003 static void rtw89_hw_scan_cleanup(struct rtw89_dev *rtwdev,
7004 struct rtw89_vif_link *rtwvif_link)
7005 {
7006 const struct rtw89_mac_gen_def *mac = rtwdev->chip->mac_def;
7007 struct rtw89_hw_scan_info *scan_info = &rtwdev->scan_info;
7008 struct rtw89_vif *rtwvif = rtwvif_link->rtwvif;
7009
7010 mac->free_chan_list(rtwdev);
7011 rtw89_hw_scan_release_pkt_list(rtwdev);
7012
7013 rtwvif->scan_req = NULL;
7014 rtwvif->scan_ies = NULL;
7015 scan_info->scanning_vif = NULL;
7016 scan_info->abort = false;
7017 scan_info->connected = false;
7018 scan_info->delay = 0;
7019 }
7020
7021 static bool rtw89_is_6ghz_wildcard_probe_req(struct rtw89_dev *rtwdev,
7022 struct cfg80211_scan_request *req,
7023 struct rtw89_pktofld_info *info,
7024 enum nl80211_band band, u8 ssid_idx)
7025 {
7026 if (band != NL80211_BAND_6GHZ)
7027 return false;
7028
7029 if (req->ssids[ssid_idx].ssid_len) {
7030 memcpy(info->ssid, req->ssids[ssid_idx].ssid,
7031 req->ssids[ssid_idx].ssid_len);
7032 info->ssid_len = req->ssids[ssid_idx].ssid_len;
7033 return false;
7034 } else {
7035 info->wildcard_6ghz = true;
7036 return true;
7037 }
7038 }
7039
7040 static int rtw89_append_probe_req_ie(struct rtw89_dev *rtwdev,
7041 struct rtw89_vif_link *rtwvif_link,
7042 struct sk_buff *skb, u8 ssid_idx)
7043 {
7044 struct rtw89_hw_scan_info *scan_info = &rtwdev->scan_info;
7045 struct rtw89_vif *rtwvif = rtwvif_link->rtwvif;
7046 struct ieee80211_scan_ies *ies = rtwvif->scan_ies;
7047 struct cfg80211_scan_request *req = rtwvif->scan_req;
7048 struct rtw89_pktofld_info *info;
7049 struct sk_buff *new;
7050 int ret = 0;
7051 u8 band;
7052
7053 for (band = NL80211_BAND_2GHZ; band < NUM_NL80211_BANDS; band++) {
7054 if (!(rtwdev->chip->support_bands & BIT(band)))
7055 continue;
7056
7057 new = skb_copy(skb, GFP_KERNEL);
7058 if (!new) {
7059 ret = -ENOMEM;
7060 goto out;
7061 }
7062 skb_put_data(new, ies->ies[band], ies->len[band]);
7063 skb_put_data(new, ies->common_ies, ies->common_ie_len);
7064
7065 info = kzalloc(sizeof(*info), GFP_KERNEL);
7066 if (!info) {
7067 ret = -ENOMEM;
7068 kfree_skb(new);
7069 goto out;
7070 }
7071
7072 rtw89_is_6ghz_wildcard_probe_req(rtwdev, req, info, band, ssid_idx);
7073
7074 ret = rtw89_fw_h2c_add_pkt_offload(rtwdev, &info->id, new);
7075 if (ret) {
7076 kfree_skb(new);
7077 kfree(info);
7078 goto out;
7079 }
7080
7081 list_add_tail(&info->list, &scan_info->pkt_list[band]);
7082 kfree_skb(new);
7083 }
7084 out:
7085 return ret;
7086 }
7087
7088 static int rtw89_hw_scan_update_probe_req(struct rtw89_dev *rtwdev,
7089 struct rtw89_vif_link *rtwvif_link,
7090 const u8 *mac_addr)
7091 {
7092 struct rtw89_vif *rtwvif = rtwvif_link->rtwvif;
7093 struct cfg80211_scan_request *req = rtwvif->scan_req;
7094 struct sk_buff *skb;
7095 u8 num = req->n_ssids, i;
7096 int ret;
7097
7098 for (i = 0; i < num; i++) {
7099 skb = ieee80211_probereq_get(rtwdev->hw, mac_addr,
7100 req->ssids[i].ssid,
7101 req->ssids[i].ssid_len,
7102 req->ie_len);
7103 if (!skb)
7104 return -ENOMEM;
7105
7106 ret = rtw89_append_probe_req_ie(rtwdev, rtwvif_link, skb, i);
7107 kfree_skb(skb);
7108
7109 if (ret)
7110 return ret;
7111 }
7112
7113 return 0;
7114 }
7115
7116 static int rtw89_update_6ghz_rnr_chan_ax(struct rtw89_dev *rtwdev,
7117 struct ieee80211_scan_ies *ies,
7118 struct cfg80211_scan_request *req,
7119 struct rtw89_mac_chinfo_ax *ch_info)
7120 {
7121 struct rtw89_vif_link *rtwvif_link = rtwdev->scan_info.scanning_vif;
7122 struct list_head *pkt_list = rtwdev->scan_info.pkt_list;
7123 struct cfg80211_scan_6ghz_params *params;
7124 struct rtw89_pktofld_info *info, *tmp;
7125 struct ieee80211_hdr *hdr;
7126 struct sk_buff *skb;
7127 bool found;
7128 int ret = 0;
7129 u8 i;
7130
7131 if (!req->n_6ghz_params)
7132 return 0;
7133
7134 for (i = 0; i < req->n_6ghz_params; i++) {
7135 params = &req->scan_6ghz_params[i];
7136
7137 if (req->channels[params->channel_idx]->hw_value !=
7138 ch_info->pri_ch)
7139 continue;
7140
7141 found = false;
7142 list_for_each_entry(tmp, &pkt_list[NL80211_BAND_6GHZ], list) {
7143 if (ether_addr_equal(tmp->bssid, params->bssid)) {
7144 found = true;
7145 break;
7146 }
7147 }
7148 if (found)
7149 continue;
7150
7151 skb = ieee80211_probereq_get(rtwdev->hw, rtwvif_link->mac_addr,
7152 NULL, 0, req->ie_len);
7153 if (!skb)
7154 return -ENOMEM;
7155
7156 skb_put_data(skb, ies->ies[NL80211_BAND_6GHZ], ies->len[NL80211_BAND_6GHZ]);
7157 skb_put_data(skb, ies->common_ies, ies->common_ie_len);
7158 hdr = (struct ieee80211_hdr *)skb->data;
7159 ether_addr_copy(hdr->addr3, params->bssid);
7160
7161 info = kzalloc(sizeof(*info), GFP_KERNEL);
7162 if (!info) {
7163 ret = -ENOMEM;
7164 kfree_skb(skb);
7165 goto out;
7166 }
7167
7168 ret = rtw89_fw_h2c_add_pkt_offload(rtwdev, &info->id, skb);
7169 if (ret) {
7170 kfree_skb(skb);
7171 kfree(info);
7172 goto out;
7173 }
7174
7175 ether_addr_copy(info->bssid, params->bssid);
7176 info->channel_6ghz = req->channels[params->channel_idx]->hw_value;
7177 list_add_tail(&info->list, &rtwdev->scan_info.pkt_list[NL80211_BAND_6GHZ]);
7178
7179 ch_info->tx_pkt = true;
7180 ch_info->period = RTW89_CHANNEL_TIME_6G + RTW89_DWELL_TIME_6G;
7181
7182 kfree_skb(skb);
7183 }
7184
7185 out:
7186 return ret;
7187 }
7188
7189 static void rtw89_pno_scan_add_chan_ax(struct rtw89_dev *rtwdev,
7190 int chan_type, int ssid_num,
7191 struct rtw89_mac_chinfo_ax *ch_info)
7192 {
7193 struct rtw89_wow_param *rtw_wow = &rtwdev->wow;
7194 struct rtw89_pktofld_info *info;
7195 u8 probe_count = 0;
7196
7197 ch_info->notify_action = RTW89_SCANOFLD_DEBUG_MASK;
7198 ch_info->dfs_ch = chan_type == RTW89_CHAN_DFS;
7199 ch_info->bw = RTW89_SCAN_WIDTH;
7200 ch_info->tx_pkt = true;
7201 ch_info->cfg_tx_pwr = false;
7202 ch_info->tx_pwr_idx = 0;
7203 ch_info->tx_null = false;
7204 ch_info->pause_data = false;
7205 ch_info->probe_id = RTW89_SCANOFLD_PKT_NONE;
7206
7207 if (ssid_num) {
7208 list_for_each_entry(info, &rtw_wow->pno_pkt_list, list) {
7209 if (info->channel_6ghz &&
7210 ch_info->pri_ch != info->channel_6ghz)
7211 continue;
7212 else if (info->channel_6ghz && probe_count != 0)
7213 ch_info->period += RTW89_CHANNEL_TIME_6G;
7214
7215 if (info->wildcard_6ghz)
7216 continue;
7217
7218 ch_info->pkt_id[probe_count++] = info->id;
7219 if (probe_count >= RTW89_SCANOFLD_MAX_SSID)
7220 break;
7221 }
7222 ch_info->num_pkt = probe_count;
7223 }
7224
7225 switch (chan_type) {
7226 case RTW89_CHAN_DFS:
7227 if (ch_info->ch_band != RTW89_BAND_6G)
7228 ch_info->period = max_t(u8, ch_info->period,
7229 RTW89_DFS_CHAN_TIME);
7230 ch_info->dwell_time = RTW89_DWELL_TIME;
7231 break;
7232 case RTW89_CHAN_ACTIVE:
7233 break;
7234 default:
7235 rtw89_err(rtwdev, "Channel type out of bound\n");
7236 }
7237 }
7238
7239 static void rtw89_hw_scan_add_chan_ax(struct rtw89_dev *rtwdev, int chan_type,
7240 int ssid_num,
7241 struct rtw89_mac_chinfo_ax *ch_info)
7242 {
7243 struct rtw89_hw_scan_info *scan_info = &rtwdev->scan_info;
7244 struct rtw89_vif_link *rtwvif_link = rtwdev->scan_info.scanning_vif;
7245 const struct rtw89_hw_scan_extra_op *ext = &scan_info->extra_op;
7246 struct rtw89_vif *rtwvif = rtwvif_link->rtwvif;
7247 struct ieee80211_scan_ies *ies = rtwvif->scan_ies;
7248 struct cfg80211_scan_request *req = rtwvif->scan_req;
7249 struct rtw89_chan *op = &rtwdev->scan_info.op_chan;
7250 struct rtw89_pktofld_info *info;
7251 u8 band, probe_count = 0;
7252 int ret;
7253
7254 ch_info->notify_action = RTW89_SCANOFLD_DEBUG_MASK;
7255 ch_info->dfs_ch = chan_type == RTW89_CHAN_DFS;
7256 ch_info->bw = RTW89_SCAN_WIDTH;
7257 ch_info->tx_pkt = true;
7258 ch_info->cfg_tx_pwr = false;
7259 ch_info->tx_pwr_idx = 0;
7260 ch_info->tx_null = false;
7261 ch_info->pause_data = false;
7262 ch_info->probe_id = RTW89_SCANOFLD_PKT_NONE;
7263
7264 if (ch_info->ch_band == RTW89_BAND_6G) {
7265 if ((ssid_num == 1 && req->ssids[0].ssid_len == 0) ||
7266 !ch_info->is_psc) {
7267 ch_info->tx_pkt = false;
7268 if (!req->duration_mandatory)
7269 ch_info->period -= RTW89_DWELL_TIME_6G;
7270 }
7271 }
7272
7273 ret = rtw89_update_6ghz_rnr_chan_ax(rtwdev, ies, req, ch_info);
7274 if (ret)
7275 rtw89_warn(rtwdev, "RNR fails: %d\n", ret);
7276
7277 if (ssid_num) {
7278 band = rtw89_hw_to_nl80211_band(ch_info->ch_band);
7279
7280 list_for_each_entry(info, &scan_info->pkt_list[band], list) {
7281 if (info->channel_6ghz &&
7282 ch_info->pri_ch != info->channel_6ghz)
7283 continue;
7284 else if (info->channel_6ghz && probe_count != 0)
7285 ch_info->period += RTW89_CHANNEL_TIME_6G;
7286
7287 if (info->wildcard_6ghz)
7288 continue;
7289
7290 ch_info->pkt_id[probe_count++] = info->id;
7291 if (probe_count >= RTW89_SCANOFLD_MAX_SSID)
7292 break;
7293 }
7294 ch_info->num_pkt = probe_count;
7295 }
7296
7297 switch (chan_type) {
7298 case RTW89_CHAN_OPERATE:
7299 ch_info->central_ch = op->channel;
7300 ch_info->pri_ch = op->primary_channel;
7301 ch_info->ch_band = op->band_type;
7302 ch_info->bw = op->band_width;
7303 ch_info->tx_null = true;
7304 ch_info->num_pkt = 0;
7305 break;
7306 case RTW89_CHAN_DFS:
7307 if (ch_info->ch_band != RTW89_BAND_6G)
7308 ch_info->period = max_t(u8, ch_info->period,
7309 RTW89_DFS_CHAN_TIME);
7310 ch_info->dwell_time = RTW89_DWELL_TIME;
7311 ch_info->pause_data = true;
7312 break;
7313 case RTW89_CHAN_ACTIVE:
7314 ch_info->pause_data = true;
7315 break;
7316 case RTW89_CHAN_EXTRA_OP:
7317 ch_info->central_ch = ext->chan.channel;
7318 ch_info->pri_ch = ext->chan.primary_channel;
7319 ch_info->ch_band = ext->chan.band_type;
7320 ch_info->bw = ext->chan.band_width;
7321 ch_info->tx_null = true;
7322 ch_info->num_pkt = 0;
7323 ch_info->macid_tx = true;
7324 break;
7325 default:
7326 rtw89_err(rtwdev, "Channel type out of bound\n");
7327 }
7328 }
7329
7330 static void rtw89_pno_scan_add_chan_be(struct rtw89_dev *rtwdev, int chan_type,
7331 int ssid_num,
7332 struct rtw89_mac_chinfo_be *ch_info)
7333 {
7334 struct rtw89_wow_param *rtw_wow = &rtwdev->wow;
7335 struct rtw89_pktofld_info *info;
7336 u8 probe_count = 0, i;
7337
7338 ch_info->notify_action = RTW89_SCANOFLD_DEBUG_MASK;
7339 ch_info->dfs_ch = chan_type == RTW89_CHAN_DFS;
7340 ch_info->bw = RTW89_SCAN_WIDTH;
7341 ch_info->tx_null = false;
7342 ch_info->pause_data = false;
7343 ch_info->probe_id = RTW89_SCANOFLD_PKT_NONE;
7344
7345 if (ssid_num) {
7346 list_for_each_entry(info, &rtw_wow->pno_pkt_list, list) {
7347 ch_info->pkt_id[probe_count++] = info->id;
7348 if (probe_count >= RTW89_SCANOFLD_MAX_SSID)
7349 break;
7350 }
7351 }
7352
7353 for (i = probe_count; i < RTW89_SCANOFLD_MAX_SSID; i++)
7354 ch_info->pkt_id[i] = RTW89_SCANOFLD_PKT_NONE;
7355
7356 switch (chan_type) {
7357 case RTW89_CHAN_DFS:
7358 ch_info->period = max_t(u8, ch_info->period, RTW89_DFS_CHAN_TIME);
7359 ch_info->dwell_time = RTW89_DWELL_TIME;
7360 break;
7361 case RTW89_CHAN_ACTIVE:
7362 break;
7363 default:
7364 rtw89_warn(rtwdev, "Channel type out of bound\n");
7365 break;
7366 }
7367 }
7368
7369 static void rtw89_hw_scan_add_chan_be(struct rtw89_dev *rtwdev, int chan_type,
7370 int ssid_num,
7371 struct rtw89_mac_chinfo_be *ch_info)
7372 {
7373 struct rtw89_hw_scan_info *scan_info = &rtwdev->scan_info;
7374 struct rtw89_vif_link *rtwvif_link = rtwdev->scan_info.scanning_vif;
7375 struct rtw89_vif *rtwvif = rtwvif_link->rtwvif;
7376 struct cfg80211_scan_request *req = rtwvif->scan_req;
7377 struct rtw89_pktofld_info *info;
7378 u8 band, probe_count = 0, i;
7379
7380 ch_info->notify_action = RTW89_SCANOFLD_DEBUG_MASK;
7381 ch_info->dfs_ch = chan_type == RTW89_CHAN_DFS;
7382 ch_info->bw = RTW89_SCAN_WIDTH;
7383 ch_info->tx_null = false;
7384 ch_info->pause_data = false;
7385 ch_info->probe_id = RTW89_SCANOFLD_PKT_NONE;
7386
7387 if (ssid_num) {
7388 band = rtw89_hw_to_nl80211_band(ch_info->ch_band);
7389
7390 list_for_each_entry(info, &scan_info->pkt_list[band], list) {
7391 if (info->channel_6ghz &&
7392 ch_info->pri_ch != info->channel_6ghz)
7393 continue;
7394
7395 if (info->wildcard_6ghz)
7396 continue;
7397
7398 ch_info->pkt_id[probe_count++] = info->id;
7399 if (probe_count >= RTW89_SCANOFLD_MAX_SSID)
7400 break;
7401 }
7402 }
7403
7404 if (ch_info->ch_band == RTW89_BAND_6G) {
7405 if ((ssid_num == 1 && req->ssids[0].ssid_len == 0) ||
7406 !ch_info->is_psc) {
7407 ch_info->probe_id = RTW89_SCANOFLD_PKT_NONE;
7408 if (!req->duration_mandatory)
7409 ch_info->period -= RTW89_DWELL_TIME_6G;
7410 }
7411 }
7412
7413 for (i = probe_count; i < RTW89_SCANOFLD_MAX_SSID; i++)
7414 ch_info->pkt_id[i] = RTW89_SCANOFLD_PKT_NONE;
7415
7416 switch (chan_type) {
7417 case RTW89_CHAN_DFS:
7418 if (ch_info->ch_band != RTW89_BAND_6G)
7419 ch_info->period =
7420 max_t(u8, ch_info->period, RTW89_DFS_CHAN_TIME);
7421 ch_info->dwell_time = RTW89_DWELL_TIME;
7422 ch_info->pause_data = true;
7423 break;
7424 case RTW89_CHAN_ACTIVE:
7425 ch_info->pause_data = true;
7426 break;
7427 default:
7428 rtw89_warn(rtwdev, "Channel type out of bound\n");
7429 break;
7430 }
7431 }
7432
7433 int rtw89_pno_scan_add_chan_list_ax(struct rtw89_dev *rtwdev,
7434 struct rtw89_vif_link *rtwvif_link)
7435 {
7436 struct rtw89_wow_param *rtw_wow = &rtwdev->wow;
7437 struct cfg80211_sched_scan_request *nd_config = rtw_wow->nd_config;
7438 struct rtw89_mac_chinfo_ax *ch_info, *tmp;
7439 struct ieee80211_channel *channel;
7440 struct list_head chan_list;
7441 int list_len;
7442 enum rtw89_chan_type type;
7443 int ret = 0;
7444 u32 idx;
7445
7446 INIT_LIST_HEAD(&chan_list);
7447 for (idx = 0, list_len = 0;
7448 idx < nd_config->n_channels && list_len < RTW89_SCAN_LIST_LIMIT_AX;
7449 idx++, list_len++) {
7450 channel = nd_config->channels[idx];
7451 ch_info = kzalloc(sizeof(*ch_info), GFP_KERNEL);
7452 if (!ch_info) {
7453 ret = -ENOMEM;
7454 goto out;
7455 }
7456
7457 ch_info->period = RTW89_CHANNEL_TIME;
7458 ch_info->ch_band = rtw89_nl80211_to_hw_band(channel->band);
7459 ch_info->central_ch = channel->hw_value;
7460 ch_info->pri_ch = channel->hw_value;
7461 ch_info->is_psc = cfg80211_channel_is_psc(channel);
7462
7463 if (channel->flags &
7464 (IEEE80211_CHAN_RADAR | IEEE80211_CHAN_NO_IR))
7465 type = RTW89_CHAN_DFS;
7466 else
7467 type = RTW89_CHAN_ACTIVE;
7468
7469 rtw89_pno_scan_add_chan_ax(rtwdev, type, nd_config->n_match_sets, ch_info);
7470 list_add_tail(&ch_info->list, &chan_list);
7471 }
7472 ret = rtw89_fw_h2c_scan_list_offload_ax(rtwdev, list_len, &chan_list);
7473
7474 out:
7475 list_for_each_entry_safe(ch_info, tmp, &chan_list, list) {
7476 list_del(&ch_info->list);
7477 kfree(ch_info);
7478 }
7479
7480 return ret;
7481 }
7482
7483 static int rtw89_hw_scan_add_op_types_ax(struct rtw89_dev *rtwdev,
7484 enum rtw89_chan_type type,
7485 struct list_head *chan_list,
7486 struct cfg80211_scan_request *req,
7487 int *off_chan_time)
7488 {
7489 struct rtw89_mac_chinfo_ax *tmp;
7490
7491 tmp = kzalloc(sizeof(*tmp), GFP_KERNEL);
7492 if (!tmp)
7493 return -ENOMEM;
7494
7495 switch (type) {
7496 case RTW89_CHAN_OPERATE:
7497 tmp->period = req->duration_mandatory ?
7498 req->duration : RTW89_CHANNEL_TIME;
7499 *off_chan_time = 0;
7500 break;
7501 case RTW89_CHAN_EXTRA_OP:
7502 tmp->period = RTW89_CHANNEL_TIME_EXTRA_OP;
7503 /* still calc @off_chan_time for scan op */
7504 *off_chan_time += tmp->period;
7505 break;
7506 default:
7507 kfree(tmp);
7508 return -EINVAL;
7509 }
7510
7511 rtw89_hw_scan_add_chan_ax(rtwdev, type, 0, tmp);
7512 list_add_tail(&tmp->list, chan_list);
7513
7514 return 0;
7515 }
7516
7517 int rtw89_hw_scan_prep_chan_list_ax(struct rtw89_dev *rtwdev,
7518 struct rtw89_vif_link *rtwvif_link)
7519 {
7520 struct rtw89_hw_scan_info *scan_info = &rtwdev->scan_info;
7521 const struct rtw89_hw_scan_extra_op *ext = &scan_info->extra_op;
7522 struct rtw89_vif *rtwvif = rtwvif_link->rtwvif;
7523 struct cfg80211_scan_request *req = rtwvif->scan_req;
7524 struct rtw89_mac_chinfo_ax *ch_info, *tmp;
7525 struct ieee80211_channel *channel;
7526 struct list_head chan_list;
7527 bool random_seq = req->flags & NL80211_SCAN_FLAG_RANDOM_SN;
7528 enum rtw89_chan_type type;
7529 int off_chan_time = 0;
7530 int ret;
7531 u32 idx;
7532
7533 INIT_LIST_HEAD(&chan_list);
7534
7535 for (idx = 0; idx < req->n_channels; idx++) {
7536 channel = req->channels[idx];
7537 ch_info = kzalloc(sizeof(*ch_info), GFP_KERNEL);
7538 if (!ch_info) {
7539 ret = -ENOMEM;
7540 goto out;
7541 }
7542
7543 if (req->duration)
7544 ch_info->period = req->duration;
7545 else if (channel->band == NL80211_BAND_6GHZ)
7546 ch_info->period = RTW89_CHANNEL_TIME_6G +
7547 RTW89_DWELL_TIME_6G;
7548 else if (rtwvif_link->wifi_role == RTW89_WIFI_ROLE_P2P_CLIENT)
7549 ch_info->period = RTW89_P2P_CHAN_TIME;
7550 else
7551 ch_info->period = RTW89_CHANNEL_TIME;
7552
7553 ch_info->ch_band = rtw89_nl80211_to_hw_band(channel->band);
7554 ch_info->central_ch = channel->hw_value;
7555 ch_info->pri_ch = channel->hw_value;
7556 ch_info->rand_seq_num = random_seq;
7557 ch_info->is_psc = cfg80211_channel_is_psc(channel);
7558
7559 if (channel->flags &
7560 (IEEE80211_CHAN_RADAR | IEEE80211_CHAN_NO_IR))
7561 type = RTW89_CHAN_DFS;
7562 else
7563 type = RTW89_CHAN_ACTIVE;
7564 rtw89_hw_scan_add_chan_ax(rtwdev, type, req->n_ssids, ch_info);
7565
7566 if (!(scan_info->connected &&
7567 off_chan_time + ch_info->period > RTW89_OFF_CHAN_TIME))
7568 goto next;
7569
7570 ret = rtw89_hw_scan_add_op_types_ax(rtwdev, RTW89_CHAN_OPERATE,
7571 &chan_list, req, &off_chan_time);
7572 if (ret) {
7573 kfree(ch_info);
7574 goto out;
7575 }
7576
7577 if (!ext->set)
7578 goto next;
7579
7580 ret = rtw89_hw_scan_add_op_types_ax(rtwdev, RTW89_CHAN_EXTRA_OP,
7581 &chan_list, req, &off_chan_time);
7582 if (ret) {
7583 kfree(ch_info);
7584 goto out;
7585 }
7586
7587 next:
7588 list_add_tail(&ch_info->list, &chan_list);
7589 off_chan_time += ch_info->period;
7590 }
7591
7592 list_splice_tail(&chan_list, &scan_info->chan_list);
7593 return 0;
7594
7595 out:
7596 list_for_each_entry_safe(ch_info, tmp, &chan_list, list) {
7597 list_del(&ch_info->list);
7598 kfree(ch_info);
7599 }
7600
7601 return ret;
7602 }
7603
7604 void rtw89_hw_scan_free_chan_list_ax(struct rtw89_dev *rtwdev)
7605 {
7606 struct rtw89_hw_scan_info *scan_info = &rtwdev->scan_info;
7607 struct rtw89_mac_chinfo_ax *ch_info, *tmp;
7608
7609 list_for_each_entry_safe(ch_info, tmp, &scan_info->chan_list, list) {
7610 list_del(&ch_info->list);
7611 kfree(ch_info);
7612 }
7613 }
7614
7615 int rtw89_hw_scan_add_chan_list_ax(struct rtw89_dev *rtwdev,
7616 struct rtw89_vif_link *rtwvif_link)
7617 {
7618 struct rtw89_hw_scan_info *scan_info = &rtwdev->scan_info;
7619 struct rtw89_mac_chinfo_ax *ch_info, *tmp;
7620 unsigned int list_len = 0;
7621 struct list_head list;
7622 int ret;
7623
7624 INIT_LIST_HEAD(&list);
7625
7626 list_for_each_entry_safe(ch_info, tmp, &scan_info->chan_list, list) {
7627 list_move_tail(&ch_info->list, &list);
7628
7629 list_len++;
7630 if (list_len == RTW89_SCAN_LIST_LIMIT_AX)
7631 break;
7632 }
7633
7634 ret = rtw89_fw_h2c_scan_list_offload_ax(rtwdev, list_len, &list);
7635
7636 list_for_each_entry_safe(ch_info, tmp, &list, list) {
7637 list_del(&ch_info->list);
7638 kfree(ch_info);
7639 }
7640
7641 return ret;
7642 }
7643
7644 int rtw89_pno_scan_add_chan_list_be(struct rtw89_dev *rtwdev,
7645 struct rtw89_vif_link *rtwvif_link)
7646 {
7647 struct rtw89_wow_param *rtw_wow = &rtwdev->wow;
7648 struct cfg80211_sched_scan_request *nd_config = rtw_wow->nd_config;
7649 struct rtw89_mac_chinfo_be *ch_info, *tmp;
7650 struct ieee80211_channel *channel;
7651 struct list_head chan_list;
7652 enum rtw89_chan_type type;
7653 int list_len, ret;
7654 u32 idx;
7655
7656 INIT_LIST_HEAD(&chan_list);
7657
7658 for (idx = 0, list_len = 0;
7659 idx < nd_config->n_channels && list_len < RTW89_SCAN_LIST_LIMIT_BE;
7660 idx++, list_len++) {
7661 channel = nd_config->channels[idx];
7662 ch_info = kzalloc(sizeof(*ch_info), GFP_KERNEL);
7663 if (!ch_info) {
7664 ret = -ENOMEM;
7665 goto out;
7666 }
7667
7668 ch_info->period = RTW89_CHANNEL_TIME;
7669 ch_info->ch_band = rtw89_nl80211_to_hw_band(channel->band);
7670 ch_info->central_ch = channel->hw_value;
7671 ch_info->pri_ch = channel->hw_value;
7672 ch_info->is_psc = cfg80211_channel_is_psc(channel);
7673
7674 if (channel->flags &
7675 (IEEE80211_CHAN_RADAR | IEEE80211_CHAN_NO_IR))
7676 type = RTW89_CHAN_DFS;
7677 else
7678 type = RTW89_CHAN_ACTIVE;
7679
7680 rtw89_pno_scan_add_chan_be(rtwdev, type,
7681 nd_config->n_match_sets, ch_info);
7682 list_add_tail(&ch_info->list, &chan_list);
7683 }
7684
7685 ret = rtw89_fw_h2c_scan_list_offload_be(rtwdev, list_len, &chan_list,
7686 rtwvif_link);
7687
7688 out:
7689 list_for_each_entry_safe(ch_info, tmp, &chan_list, list) {
7690 list_del(&ch_info->list);
7691 kfree(ch_info);
7692 }
7693
7694 return ret;
7695 }
7696
7697 int rtw89_hw_scan_prep_chan_list_be(struct rtw89_dev *rtwdev,
7698 struct rtw89_vif_link *rtwvif_link)
7699 {
7700 struct rtw89_hw_scan_info *scan_info = &rtwdev->scan_info;
7701 struct rtw89_vif *rtwvif = rtwvif_link->rtwvif;
7702 struct cfg80211_scan_request *req = rtwvif->scan_req;
7703 struct rtw89_mac_chinfo_be *ch_info, *tmp;
7704 struct ieee80211_channel *channel;
7705 struct list_head chan_list;
7706 enum rtw89_chan_type type;
7707 bool random_seq;
7708 int ret;
7709 u32 idx;
7710
7711 random_seq = !!(req->flags & NL80211_SCAN_FLAG_RANDOM_SN);
7712 INIT_LIST_HEAD(&chan_list);
7713
7714 for (idx = 0; idx < req->n_channels; idx++) {
7715 channel = req->channels[idx];
7716 ch_info = kzalloc(sizeof(*ch_info), GFP_KERNEL);
7717 if (!ch_info) {
7718 ret = -ENOMEM;
7719 goto out;
7720 }
7721
7722 if (req->duration)
7723 ch_info->period = req->duration;
7724 else if (channel->band == NL80211_BAND_6GHZ)
7725 ch_info->period = RTW89_CHANNEL_TIME_6G + RTW89_DWELL_TIME_6G;
7726 else if (rtwvif_link->wifi_role == RTW89_WIFI_ROLE_P2P_CLIENT)
7727 ch_info->period = RTW89_P2P_CHAN_TIME;
7728 else
7729 ch_info->period = RTW89_CHANNEL_TIME;
7730
7731 ch_info->ch_band = rtw89_nl80211_to_hw_band(channel->band);
7732 ch_info->central_ch = channel->hw_value;
7733 ch_info->pri_ch = channel->hw_value;
7734 ch_info->rand_seq_num = random_seq;
7735 ch_info->is_psc = cfg80211_channel_is_psc(channel);
7736
7737 if (channel->flags & (IEEE80211_CHAN_RADAR | IEEE80211_CHAN_NO_IR))
7738 type = RTW89_CHAN_DFS;
7739 else
7740 type = RTW89_CHAN_ACTIVE;
7741 rtw89_hw_scan_add_chan_be(rtwdev, type, req->n_ssids, ch_info);
7742
7743 list_add_tail(&ch_info->list, &chan_list);
7744 }
7745
7746 list_splice_tail(&chan_list, &scan_info->chan_list);
7747 return 0;
7748
7749 out:
7750 list_for_each_entry_safe(ch_info, tmp, &chan_list, list) {
7751 list_del(&ch_info->list);
7752 kfree(ch_info);
7753 }
7754
7755 return ret;
7756 }
7757
7758 void rtw89_hw_scan_free_chan_list_be(struct rtw89_dev *rtwdev)
7759 {
7760 struct rtw89_hw_scan_info *scan_info = &rtwdev->scan_info;
7761 struct rtw89_mac_chinfo_be *ch_info, *tmp;
7762
7763 list_for_each_entry_safe(ch_info, tmp, &scan_info->chan_list, list) {
7764 list_del(&ch_info->list);
7765 kfree(ch_info);
7766 }
7767 }
7768
7769 int rtw89_hw_scan_add_chan_list_be(struct rtw89_dev *rtwdev,
7770 struct rtw89_vif_link *rtwvif_link)
7771 {
7772 struct rtw89_hw_scan_info *scan_info = &rtwdev->scan_info;
7773 struct rtw89_mac_chinfo_be *ch_info, *tmp;
7774 unsigned int list_len = 0;
7775 struct list_head list;
7776 int ret;
7777
7778 INIT_LIST_HEAD(&list);
7779
7780 list_for_each_entry_safe(ch_info, tmp, &scan_info->chan_list, list) {
7781 list_move_tail(&ch_info->list, &list);
7782
7783 list_len++;
7784 if (list_len == RTW89_SCAN_LIST_LIMIT_BE)
7785 break;
7786 }
7787
7788 ret = rtw89_fw_h2c_scan_list_offload_be(rtwdev, list_len, &list,
7789 rtwvif_link);
7790
7791 list_for_each_entry_safe(ch_info, tmp, &list, list) {
7792 list_del(&ch_info->list);
7793 kfree(ch_info);
7794 }
7795
7796 return ret;
7797 }
7798
7799 static int rtw89_hw_scan_prehandle(struct rtw89_dev *rtwdev,
7800 struct rtw89_vif_link *rtwvif_link,
7801 const u8 *mac_addr)
7802 {
7803 const struct rtw89_mac_gen_def *mac = rtwdev->chip->mac_def;
7804 int ret;
7805
7806 ret = rtw89_hw_scan_update_probe_req(rtwdev, rtwvif_link, mac_addr);
7807 if (ret) {
7808 #if defined(__linux__)
7809 rtw89_err(rtwdev, "Update probe request failed\n");
7810 #elif defined(__FreeBSD__)
7811 rtw89_err(rtwdev, "Update probe request failed: ret %d\n", ret);
7812 #endif
7813 goto out;
7814 }
7815 ret = mac->prep_chan_list(rtwdev, rtwvif_link);
7816 out:
7817 return ret;
7818 }
7819
7820 static void rtw89_hw_scan_update_link_beacon_noa(struct rtw89_dev *rtwdev,
7821 struct rtw89_vif_link *rtwvif_link,
7822 u16 tu, bool scan)
7823 {
7824 struct ieee80211_p2p_noa_desc noa_desc = {};
7825 struct ieee80211_bss_conf *bss_conf;
7826 u16 beacon_int;
7827 u64 tsf;
7828 int ret;
7829
7830 rcu_read_lock();
7831
7832 bss_conf = rtw89_vif_rcu_dereference_link(rtwvif_link, true);
7833 beacon_int = bss_conf->beacon_int;
7834
7835 rcu_read_unlock();
7836
7837 tu += beacon_int * 3;
7838 if (rtwdev->chip->chip_gen == RTW89_CHIP_AX)
7839 rtwdev->scan_info.delay = ieee80211_tu_to_usec(beacon_int * 3) / 1000;
7840
7841 ret = rtw89_mac_port_get_tsf(rtwdev, rtwvif_link, &tsf);
7842 if (ret) {
7843 rtw89_warn(rtwdev, "%s: failed to get tsf\n", __func__);
7844 return;
7845 }
7846
7847 noa_desc.start_time = cpu_to_le32(tsf);
7848 if (rtwdev->chip->chip_gen == RTW89_CHIP_AX) {
7849 noa_desc.interval = cpu_to_le32(ieee80211_tu_to_usec(tu));
7850 noa_desc.duration = cpu_to_le32(ieee80211_tu_to_usec(tu));
7851 noa_desc.count = 1;
7852 } else {
7853 noa_desc.duration = cpu_to_le32(ieee80211_tu_to_usec(20000));
7854 noa_desc.interval = cpu_to_le32(ieee80211_tu_to_usec(20000));
7855 noa_desc.count = 255;
7856 }
7857
7858 rtw89_p2p_noa_renew(rtwvif_link);
7859 if (scan)
7860 rtw89_p2p_noa_append(rtwvif_link, &noa_desc);
7861
7862 rtw89_chip_h2c_update_beacon(rtwdev, rtwvif_link);
7863 }
7864
7865 static void rtw89_hw_scan_update_beacon_noa(struct rtw89_dev *rtwdev, bool scan)
7866 {
7867 const struct rtw89_entity_mgnt *mgnt = &rtwdev->hal.entity_mgnt;
7868 const struct rtw89_hw_scan_info *scan_info = &rtwdev->scan_info;
7869 const struct rtw89_chip_info *chip = rtwdev->chip;
7870 struct rtw89_mac_chinfo_ax *chinfo_ax;
7871 struct rtw89_mac_chinfo_be *chinfo_be;
7872 struct rtw89_vif_link *rtwvif_link;
7873 struct list_head *pos, *tmp;
7874 struct ieee80211_vif *vif;
7875 struct rtw89_vif *rtwvif;
7876 u16 tu = 0;
7877
7878 lockdep_assert_wiphy(rtwdev->hw->wiphy);
7879
7880 if (!scan)
7881 goto update;
7882
7883 list_for_each_safe(pos, tmp, &scan_info->chan_list) {
7884 switch (chip->chip_gen) {
7885 case RTW89_CHIP_AX:
7886 chinfo_ax = list_entry(pos, typeof(*chinfo_ax), list);
7887 tu += chinfo_ax->period;
7888 break;
7889 case RTW89_CHIP_BE:
7890 chinfo_be = list_entry(pos, typeof(*chinfo_be), list);
7891 tu += chinfo_be->period;
7892 break;
7893 default:
7894 rtw89_warn(rtwdev, "%s: invalid chip gen %d\n",
7895 __func__, chip->chip_gen);
7896 return;
7897 }
7898 }
7899
7900 if (unlikely(tu == 0)) {
7901 rtw89_debug(rtwdev, RTW89_DBG_HW_SCAN,
7902 "%s: cannot estimate needed TU\n", __func__);
7903 return;
7904 }
7905
7906 update:
7907 list_for_each_entry(rtwvif, &mgnt->active_list, mgnt_entry) {
7908 unsigned int link_id;
7909
7910 vif = rtwvif_to_vif(rtwvif);
7911 if (vif->type != NL80211_IFTYPE_AP || !vif->p2p)
7912 continue;
7913
7914 rtw89_vif_for_each_link(rtwvif, rtwvif_link, link_id)
7915 rtw89_hw_scan_update_link_beacon_noa(rtwdev, rtwvif_link,
7916 tu, scan);
7917 }
7918 }
7919
7920 static void rtw89_hw_scan_set_extra_op_info(struct rtw89_dev *rtwdev,
7921 struct rtw89_vif *scan_rtwvif,
7922 const struct rtw89_chan *scan_op)
7923 {
7924 struct rtw89_entity_mgnt *mgnt = &rtwdev->hal.entity_mgnt;
7925 struct rtw89_hw_scan_info *scan_info = &rtwdev->scan_info;
7926 struct rtw89_hw_scan_extra_op *ext = &scan_info->extra_op;
7927 struct rtw89_vif *tmp;
7928
7929 ext->set = false;
7930 if (!RTW89_CHK_FW_FEATURE(SCAN_OFFLOAD_EXTRA_OP, &rtwdev->fw))
7931 return;
7932
7933 list_for_each_entry(tmp, &mgnt->active_list, mgnt_entry) {
7934 const struct rtw89_chan *tmp_chan;
7935 struct rtw89_vif_link *tmp_link;
7936
7937 if (tmp == scan_rtwvif)
7938 continue;
7939
7940 tmp_link = rtw89_vif_get_link_inst(tmp, 0);
7941 if (unlikely(!tmp_link)) {
7942 rtw89_debug(rtwdev, RTW89_DBG_HW_SCAN,
7943 "hw scan: no HW-0 link for extra op\n");
7944 continue;
7945 }
7946
7947 tmp_chan = rtw89_chan_get(rtwdev, tmp_link->chanctx_idx);
7948 *ext = (struct rtw89_hw_scan_extra_op){
7949 .set = true,
7950 .macid = tmp_link->mac_id,
7951 .port = tmp_link->port,
7952 .chan = *tmp_chan,
7953 .rtwvif_link = tmp_link,
7954 };
7955
7956 rtw89_debug(rtwdev, RTW89_DBG_HW_SCAN,
7957 "hw scan: extra op: center %d primary %d\n",
7958 ext->chan.channel, ext->chan.primary_channel);
7959 break;
7960 }
7961 }
7962
7963 int rtw89_hw_scan_start(struct rtw89_dev *rtwdev,
7964 struct rtw89_vif_link *rtwvif_link,
7965 struct ieee80211_scan_request *scan_req)
7966 {
7967 const struct rtw89_mac_gen_def *mac = rtwdev->chip->mac_def;
7968 enum rtw89_entity_mode mode = rtw89_get_entity_mode(rtwdev);
7969 struct cfg80211_scan_request *req = &scan_req->req;
7970 const struct rtw89_chan *chan = rtw89_chan_get(rtwdev,
7971 rtwvif_link->chanctx_idx);
7972 struct rtw89_vif *rtwvif = rtwvif_link->rtwvif;
7973 struct rtw89_chanctx_pause_parm pause_parm = {
7974 .rsn = RTW89_CHANCTX_PAUSE_REASON_HW_SCAN,
7975 .trigger = rtwvif_link,
7976 };
7977 u32 rx_fltr = rtwdev->hal.rx_fltr;
7978 u8 mac_addr[ETH_ALEN];
7979 u32 reg;
7980 int ret;
7981
7982 /* clone op and keep it during scan */
7983 rtwdev->scan_info.op_chan = *chan;
7984
7985 rtw89_debug(rtwdev, RTW89_DBG_HW_SCAN,
7986 "hw scan: op: center %d primary %d\n",
7987 chan->channel, chan->primary_channel);
7988
7989 rtw89_hw_scan_set_extra_op_info(rtwdev, rtwvif, chan);
7990
7991 rtwdev->scan_info.connected = rtw89_is_any_vif_connected_or_connecting(rtwdev);
7992 rtwdev->scan_info.scanning_vif = rtwvif_link;
7993 rtwdev->scan_info.abort = false;
7994 rtwdev->scan_info.delay = 0;
7995 rtwvif->scan_ies = &scan_req->ies;
7996 rtwvif->scan_req = req;
7997
7998 if (req->flags & NL80211_SCAN_FLAG_RANDOM_ADDR)
7999 get_random_mask_addr(mac_addr, req->mac_addr,
8000 req->mac_addr_mask);
8001 else
8002 ether_addr_copy(mac_addr, rtwvif_link->mac_addr);
8003
8004 ret = rtw89_hw_scan_prehandle(rtwdev, rtwvif_link, mac_addr);
8005 if (ret) {
8006 rtw89_hw_scan_cleanup(rtwdev, rtwvif_link);
8007 return ret;
8008 }
8009
8010 ieee80211_stop_queues(rtwdev->hw);
8011 rtw89_mac_port_cfg_rx_sync(rtwdev, rtwvif_link, false);
8012
8013 rtw89_core_scan_start(rtwdev, rtwvif_link, mac_addr, true);
8014
8015 rx_fltr &= ~B_AX_A_BCN_CHK_EN;
8016 rx_fltr &= ~B_AX_A_BC;
8017 rx_fltr &= ~B_AX_A_A1_MATCH;
8018
8019 reg = rtw89_mac_reg_by_idx(rtwdev, mac->rx_fltr, rtwvif_link->mac_idx);
8020 rtw89_write32_mask(rtwdev, reg, B_AX_RX_FLTR_CFG_MASK, rx_fltr);
8021
8022 rtw89_chanctx_pause(rtwdev, &pause_parm);
8023 rtw89_phy_dig_suspend(rtwdev);
8024
8025 if (mode == RTW89_ENTITY_MODE_MCC)
8026 rtw89_hw_scan_update_beacon_noa(rtwdev, true);
8027
8028 return 0;
8029 }
8030
8031 struct rtw89_hw_scan_complete_cb_data {
8032 struct rtw89_vif_link *rtwvif_link;
8033 bool aborted;
8034 };
8035
8036 static int rtw89_hw_scan_complete_cb(struct rtw89_dev *rtwdev, void *data)
8037 {
8038 const struct rtw89_mac_gen_def *mac = rtwdev->chip->mac_def;
8039 enum rtw89_entity_mode mode = rtw89_get_entity_mode(rtwdev);
8040 struct rtw89_hw_scan_complete_cb_data *cb_data = data;
8041 struct rtw89_vif_link *rtwvif_link = cb_data->rtwvif_link;
8042 struct cfg80211_scan_info info = {
8043 .aborted = cb_data->aborted,
8044 };
8045 u32 reg;
8046
8047 if (!rtwvif_link)
8048 return -EINVAL;
8049
8050 reg = rtw89_mac_reg_by_idx(rtwdev, mac->rx_fltr, rtwvif_link->mac_idx);
8051 rtw89_write32_mask(rtwdev, reg, B_AX_RX_FLTR_CFG_MASK, rtwdev->hal.rx_fltr);
8052
8053 rtw89_core_scan_complete(rtwdev, rtwvif_link, true);
8054 ieee80211_scan_completed(rtwdev->hw, &info);
8055 ieee80211_wake_queues(rtwdev->hw);
8056 rtw89_mac_port_cfg_rx_sync(rtwdev, rtwvif_link, true);
8057 rtw89_mac_enable_beacon_for_ap_vifs(rtwdev, true);
8058 rtw89_phy_dig_resume(rtwdev, true);
8059
8060 rtw89_hw_scan_cleanup(rtwdev, rtwvif_link);
8061
8062 if (mode == RTW89_ENTITY_MODE_MCC)
8063 rtw89_hw_scan_update_beacon_noa(rtwdev, false);
8064
8065 return 0;
8066 }
8067
8068 void rtw89_hw_scan_complete(struct rtw89_dev *rtwdev,
8069 struct rtw89_vif_link *rtwvif_link,
8070 bool aborted)
8071 {
8072 struct rtw89_hw_scan_complete_cb_data cb_data = {
8073 .rtwvif_link = rtwvif_link,
8074 .aborted = aborted,
8075 };
8076 const struct rtw89_chanctx_cb_parm cb_parm = {
8077 .cb = rtw89_hw_scan_complete_cb,
8078 .data = &cb_data,
8079 .caller = __func__,
8080 };
8081
8082 /* The things here needs to be done after setting channel (for coex)
8083 * and before proceeding entity mode (for MCC). So, pass a callback
8084 * of them for the right sequence rather than doing them directly.
8085 */
8086 rtw89_chanctx_proceed(rtwdev, &cb_parm);
8087 }
8088
8089 void rtw89_hw_scan_abort(struct rtw89_dev *rtwdev,
8090 struct rtw89_vif_link *rtwvif_link)
8091 {
8092 struct rtw89_hw_scan_info *scan_info = &rtwdev->scan_info;
8093 int ret;
8094
8095 scan_info->abort = true;
8096
8097 ret = rtw89_hw_scan_offload(rtwdev, rtwvif_link, false);
8098 if (ret)
8099 rtw89_warn(rtwdev, "rtw89_hw_scan_offload failed ret %d\n", ret);
8100
8101 /* Indicate ieee80211_scan_completed() before returning, which is safe
8102 * because scan abort command always waits for completion of
8103 * RTW89_SCAN_END_SCAN_NOTIFY, so that ieee80211_stop() can flush scan
8104 * work properly.
8105 */
8106 rtw89_hw_scan_complete(rtwdev, rtwvif_link, true);
8107 }
8108
8109 static bool rtw89_is_any_vif_connected_or_connecting(struct rtw89_dev *rtwdev)
8110 {
8111 struct rtw89_vif_link *rtwvif_link;
8112 struct rtw89_vif *rtwvif;
8113 unsigned int link_id;
8114
8115 rtw89_for_each_rtwvif(rtwdev, rtwvif) {
8116 rtw89_vif_for_each_link(rtwvif, rtwvif_link, link_id) {
8117 /* This variable implies connected or during attempt to connect */
8118 if (!is_zero_ether_addr(rtwvif_link->bssid))
8119 return true;
8120 }
8121 }
8122
8123 return false;
8124 }
8125
8126 int rtw89_hw_scan_offload(struct rtw89_dev *rtwdev,
8127 struct rtw89_vif_link *rtwvif_link,
8128 bool enable)
8129 {
8130 const struct rtw89_mac_gen_def *mac = rtwdev->chip->mac_def;
8131 struct rtw89_hw_scan_info *scan_info = &rtwdev->scan_info;
8132 const struct rtw89_hw_scan_extra_op *ext = &scan_info->extra_op;
8133 struct rtw89_scan_option opt = {0};
8134 bool connected;
8135 int ret = 0;
8136
8137 if (!rtwvif_link)
8138 return -EINVAL;
8139
8140 connected = rtwdev->scan_info.connected;
8141 opt.enable = enable;
8142 opt.target_ch_mode = connected;
8143 opt.delay = rtwdev->scan_info.delay;
8144 if (enable) {
8145 ret = mac->add_chan_list(rtwdev, rtwvif_link);
8146 if (ret)
8147 goto out;
8148 }
8149
8150 if (rtwdev->chip->chip_gen == RTW89_CHIP_BE) {
8151 opt.operation = enable ? RTW89_SCAN_OP_START : RTW89_SCAN_OP_STOP;
8152 opt.scan_mode = RTW89_SCAN_MODE_SA;
8153 opt.band = rtwvif_link->mac_idx;
8154 opt.num_macc_role = 0;
8155 opt.mlo_mode = rtwdev->mlo_dbcc_mode;
8156 opt.num_opch = connected ? 1 : 0;
8157 if (connected && ext->set)
8158 opt.num_opch++;
8159
8160 opt.opch_end = connected ? 0 : RTW89_CHAN_INVALID;
8161 }
8162
8163 ret = rtw89_mac_scan_offload(rtwdev, &opt, rtwvif_link, false);
8164
8165 out:
8166 return ret;
8167 }
8168
8169 #define H2C_FW_CPU_EXCEPTION_TYPE_0 0x5566
8170 #define H2C_FW_CPU_EXCEPTION_TYPE_1 0x0
8171 int rtw89_fw_h2c_trigger_cpu_exception(struct rtw89_dev *rtwdev)
8172 {
8173 struct rtw89_h2c_trig_cpu_except *h2c;
8174 u32 cpu_exception_type_def;
8175 u32 len = sizeof(*h2c);
8176 struct sk_buff *skb;
8177 int ret;
8178
8179 if (RTW89_CHK_FW_FEATURE(CRASH_TRIGGER_TYPE_1, &rtwdev->fw))
8180 cpu_exception_type_def = H2C_FW_CPU_EXCEPTION_TYPE_1;
8181 else if (RTW89_CHK_FW_FEATURE(CRASH_TRIGGER_TYPE_0, &rtwdev->fw))
8182 cpu_exception_type_def = H2C_FW_CPU_EXCEPTION_TYPE_0;
8183 else
8184 return -EOPNOTSUPP;
8185
8186 skb = rtw89_fw_h2c_alloc_skb_with_hdr(rtwdev, len);
8187 if (!skb) {
8188 rtw89_err(rtwdev,
8189 "failed to alloc skb for fw cpu exception\n");
8190 return -ENOMEM;
8191 }
8192
8193 skb_put(skb, len);
8194 h2c = (struct rtw89_h2c_trig_cpu_except *)skb->data;
8195
8196 h2c->w0 = le32_encode_bits(cpu_exception_type_def,
8197 RTW89_H2C_CPU_EXCEPTION_TYPE);
8198
8199 rtw89_h2c_pkt_set_hdr(rtwdev, skb, FWCMD_TYPE_H2C,
8200 H2C_CAT_TEST,
8201 H2C_CL_FW_STATUS_TEST,
8202 H2C_FUNC_CPU_EXCEPTION, 0, 0,
8203 len);
8204
8205 ret = rtw89_h2c_tx(rtwdev, skb, false);
8206 if (ret) {
8207 rtw89_err(rtwdev, "failed to send h2c\n");
8208 dev_kfree_skb_any(skb);
8209 return ret;
8210 }
8211
8212 return 0;
8213 }
8214
8215 #define H2C_PKT_DROP_LEN 24
8216 int rtw89_fw_h2c_pkt_drop(struct rtw89_dev *rtwdev,
8217 const struct rtw89_pkt_drop_params *params)
8218 {
8219 struct sk_buff *skb;
8220 int ret;
8221
8222 skb = rtw89_fw_h2c_alloc_skb_with_hdr(rtwdev, H2C_PKT_DROP_LEN);
8223 if (!skb) {
8224 rtw89_err(rtwdev,
8225 "failed to alloc skb for packet drop\n");
8226 return -ENOMEM;
8227 }
8228
8229 switch (params->sel) {
8230 case RTW89_PKT_DROP_SEL_MACID_BE_ONCE:
8231 case RTW89_PKT_DROP_SEL_MACID_BK_ONCE:
8232 case RTW89_PKT_DROP_SEL_MACID_VI_ONCE:
8233 case RTW89_PKT_DROP_SEL_MACID_VO_ONCE:
8234 case RTW89_PKT_DROP_SEL_BAND_ONCE:
8235 break;
8236 default:
8237 rtw89_debug(rtwdev, RTW89_DBG_FW,
8238 "H2C of pkt drop might not fully support sel: %d yet\n",
8239 params->sel);
8240 break;
8241 }
8242
8243 skb_put(skb, H2C_PKT_DROP_LEN);
8244 RTW89_SET_FWCMD_PKT_DROP_SEL(skb->data, params->sel);
8245 RTW89_SET_FWCMD_PKT_DROP_MACID(skb->data, params->macid);
8246 RTW89_SET_FWCMD_PKT_DROP_BAND(skb->data, params->mac_band);
8247 RTW89_SET_FWCMD_PKT_DROP_PORT(skb->data, params->port);
8248 RTW89_SET_FWCMD_PKT_DROP_MBSSID(skb->data, params->mbssid);
8249 RTW89_SET_FWCMD_PKT_DROP_ROLE_A_INFO_TF_TRS(skb->data, params->tf_trs);
8250 RTW89_SET_FWCMD_PKT_DROP_MACID_BAND_SEL_0(skb->data,
8251 params->macid_band_sel[0]);
8252 RTW89_SET_FWCMD_PKT_DROP_MACID_BAND_SEL_1(skb->data,
8253 params->macid_band_sel[1]);
8254 RTW89_SET_FWCMD_PKT_DROP_MACID_BAND_SEL_2(skb->data,
8255 params->macid_band_sel[2]);
8256 RTW89_SET_FWCMD_PKT_DROP_MACID_BAND_SEL_3(skb->data,
8257 params->macid_band_sel[3]);
8258
8259 rtw89_h2c_pkt_set_hdr(rtwdev, skb, FWCMD_TYPE_H2C,
8260 H2C_CAT_MAC,
8261 H2C_CL_MAC_FW_OFLD,
8262 H2C_FUNC_PKT_DROP, 0, 0,
8263 H2C_PKT_DROP_LEN);
8264
8265 ret = rtw89_h2c_tx(rtwdev, skb, false);
8266 if (ret) {
8267 rtw89_err(rtwdev, "failed to send h2c\n");
8268 goto fail;
8269 }
8270
8271 return 0;
8272
8273 fail:
8274 dev_kfree_skb_any(skb);
8275 return ret;
8276 }
8277
8278 #define H2C_KEEP_ALIVE_LEN 4
8279 int rtw89_fw_h2c_keep_alive(struct rtw89_dev *rtwdev, struct rtw89_vif_link *rtwvif_link,
8280 bool enable)
8281 {
8282 struct sk_buff *skb;
8283 u8 pkt_id = 0;
8284 int ret;
8285
8286 if (enable) {
8287 ret = rtw89_fw_h2c_add_general_pkt(rtwdev, rtwvif_link,
8288 RTW89_PKT_OFLD_TYPE_NULL_DATA,
8289 &pkt_id);
8290 if (ret)
8291 return -EPERM;
8292 }
8293
8294 skb = rtw89_fw_h2c_alloc_skb_with_hdr(rtwdev, H2C_KEEP_ALIVE_LEN);
8295 if (!skb) {
8296 rtw89_err(rtwdev, "failed to alloc skb for keep alive\n");
8297 return -ENOMEM;
8298 }
8299
8300 skb_put(skb, H2C_KEEP_ALIVE_LEN);
8301
8302 RTW89_SET_KEEP_ALIVE_ENABLE(skb->data, enable);
8303 RTW89_SET_KEEP_ALIVE_PKT_NULL_ID(skb->data, pkt_id);
8304 RTW89_SET_KEEP_ALIVE_PERIOD(skb->data, 5);
8305 RTW89_SET_KEEP_ALIVE_MACID(skb->data, rtwvif_link->mac_id);
8306
8307 rtw89_h2c_pkt_set_hdr(rtwdev, skb, FWCMD_TYPE_H2C,
8308 H2C_CAT_MAC,
8309 H2C_CL_MAC_WOW,
8310 H2C_FUNC_KEEP_ALIVE, 0, 1,
8311 H2C_KEEP_ALIVE_LEN);
8312
8313 ret = rtw89_h2c_tx(rtwdev, skb, false);
8314 if (ret) {
8315 rtw89_err(rtwdev, "failed to send h2c\n");
8316 goto fail;
8317 }
8318
8319 return 0;
8320
8321 fail:
8322 dev_kfree_skb_any(skb);
8323
8324 return ret;
8325 }
8326
8327 int rtw89_fw_h2c_arp_offload(struct rtw89_dev *rtwdev, struct rtw89_vif_link *rtwvif_link,
8328 bool enable)
8329 {
8330 struct rtw89_h2c_arp_offload *h2c;
8331 u32 len = sizeof(*h2c);
8332 struct sk_buff *skb;
8333 u8 pkt_id = 0;
8334 int ret;
8335
8336 if (enable) {
8337 ret = rtw89_fw_h2c_add_general_pkt(rtwdev, rtwvif_link,
8338 RTW89_PKT_OFLD_TYPE_ARP_RSP,
8339 &pkt_id);
8340 if (ret)
8341 return ret;
8342 }
8343
8344 skb = rtw89_fw_h2c_alloc_skb_with_hdr(rtwdev, len);
8345 if (!skb) {
8346 rtw89_err(rtwdev, "failed to alloc skb for arp offload\n");
8347 return -ENOMEM;
8348 }
8349
8350 skb_put(skb, len);
8351 h2c = (struct rtw89_h2c_arp_offload *)skb->data;
8352
8353 h2c->w0 = le32_encode_bits(enable, RTW89_H2C_ARP_OFFLOAD_W0_ENABLE) |
8354 le32_encode_bits(0, RTW89_H2C_ARP_OFFLOAD_W0_ACTION) |
8355 le32_encode_bits(rtwvif_link->mac_id, RTW89_H2C_ARP_OFFLOAD_W0_MACID) |
8356 le32_encode_bits(pkt_id, RTW89_H2C_ARP_OFFLOAD_W0_PKT_ID);
8357
8358 rtw89_h2c_pkt_set_hdr(rtwdev, skb, FWCMD_TYPE_H2C,
8359 H2C_CAT_MAC,
8360 H2C_CL_MAC_WOW,
8361 H2C_FUNC_ARP_OFLD, 0, 1,
8362 len);
8363
8364 ret = rtw89_h2c_tx(rtwdev, skb, false);
8365 if (ret) {
8366 rtw89_err(rtwdev, "failed to send h2c\n");
8367 goto fail;
8368 }
8369
8370 return 0;
8371
8372 fail:
8373 dev_kfree_skb_any(skb);
8374
8375 return ret;
8376 }
8377
8378 #define H2C_DISCONNECT_DETECT_LEN 8
8379 int rtw89_fw_h2c_disconnect_detect(struct rtw89_dev *rtwdev,
8380 struct rtw89_vif_link *rtwvif_link, bool enable)
8381 {
8382 struct rtw89_wow_param *rtw_wow = &rtwdev->wow;
8383 struct sk_buff *skb;
8384 u8 macid = rtwvif_link->mac_id;
8385 int ret;
8386
8387 skb = rtw89_fw_h2c_alloc_skb_with_hdr(rtwdev, H2C_DISCONNECT_DETECT_LEN);
8388 if (!skb) {
8389 rtw89_err(rtwdev, "failed to alloc skb for keep alive\n");
8390 return -ENOMEM;
8391 }
8392
8393 skb_put(skb, H2C_DISCONNECT_DETECT_LEN);
8394
8395 if (test_bit(RTW89_WOW_FLAG_EN_DISCONNECT, rtw_wow->flags)) {
8396 RTW89_SET_DISCONNECT_DETECT_ENABLE(skb->data, enable);
8397 RTW89_SET_DISCONNECT_DETECT_DISCONNECT(skb->data, !enable);
8398 RTW89_SET_DISCONNECT_DETECT_MAC_ID(skb->data, macid);
8399 RTW89_SET_DISCONNECT_DETECT_CHECK_PERIOD(skb->data, 100);
8400 RTW89_SET_DISCONNECT_DETECT_TRY_PKT_COUNT(skb->data, 5);
8401 }
8402
8403 rtw89_h2c_pkt_set_hdr(rtwdev, skb, FWCMD_TYPE_H2C,
8404 H2C_CAT_MAC,
8405 H2C_CL_MAC_WOW,
8406 H2C_FUNC_DISCONNECT_DETECT, 0, 1,
8407 H2C_DISCONNECT_DETECT_LEN);
8408
8409 ret = rtw89_h2c_tx(rtwdev, skb, false);
8410 if (ret) {
8411 rtw89_err(rtwdev, "failed to send h2c\n");
8412 goto fail;
8413 }
8414
8415 return 0;
8416
8417 fail:
8418 dev_kfree_skb_any(skb);
8419
8420 return ret;
8421 }
8422
8423 int rtw89_fw_h2c_cfg_pno(struct rtw89_dev *rtwdev, struct rtw89_vif_link *rtwvif_link,
8424 bool enable)
8425 {
8426 struct rtw89_wow_param *rtw_wow = &rtwdev->wow;
8427 struct cfg80211_sched_scan_request *nd_config = rtw_wow->nd_config;
8428 struct rtw89_h2c_cfg_nlo *h2c;
8429 u32 len = sizeof(*h2c);
8430 struct sk_buff *skb;
8431 int ret, i;
8432
8433 skb = rtw89_fw_h2c_alloc_skb_with_hdr(rtwdev, len);
8434 if (!skb) {
8435 rtw89_err(rtwdev, "failed to alloc skb for nlo\n");
8436 return -ENOMEM;
8437 }
8438
8439 skb_put(skb, len);
8440 h2c = (struct rtw89_h2c_cfg_nlo *)skb->data;
8441
8442 h2c->w0 = le32_encode_bits(enable, RTW89_H2C_NLO_W0_ENABLE) |
8443 le32_encode_bits(enable, RTW89_H2C_NLO_W0_IGNORE_CIPHER) |
8444 le32_encode_bits(rtwvif_link->mac_id, RTW89_H2C_NLO_W0_MACID);
8445
8446 if (enable) {
8447 h2c->nlo_cnt = nd_config->n_match_sets;
8448 for (i = 0 ; i < nd_config->n_match_sets; i++) {
8449 h2c->ssid_len[i] = nd_config->match_sets[i].ssid.ssid_len;
8450 memcpy(h2c->ssid[i], nd_config->match_sets[i].ssid.ssid,
8451 nd_config->match_sets[i].ssid.ssid_len);
8452 }
8453 }
8454
8455 rtw89_h2c_pkt_set_hdr(rtwdev, skb, FWCMD_TYPE_H2C,
8456 H2C_CAT_MAC,
8457 H2C_CL_MAC_WOW,
8458 H2C_FUNC_NLO, 0, 1,
8459 len);
8460
8461 ret = rtw89_h2c_tx(rtwdev, skb, false);
8462 if (ret) {
8463 rtw89_err(rtwdev, "failed to send h2c\n");
8464 goto fail;
8465 }
8466
8467 return 0;
8468
8469 fail:
8470 dev_kfree_skb_any(skb);
8471 return ret;
8472 }
8473
8474 int rtw89_fw_h2c_wow_global(struct rtw89_dev *rtwdev, struct rtw89_vif_link *rtwvif_link,
8475 bool enable)
8476 {
8477 struct rtw89_wow_param *rtw_wow = &rtwdev->wow;
8478 struct rtw89_h2c_wow_global *h2c;
8479 u8 macid = rtwvif_link->mac_id;
8480 u32 len = sizeof(*h2c);
8481 struct sk_buff *skb;
8482 int ret;
8483
8484 skb = rtw89_fw_h2c_alloc_skb_with_hdr(rtwdev, len);
8485 if (!skb) {
8486 rtw89_err(rtwdev, "failed to alloc skb for wow global\n");
8487 return -ENOMEM;
8488 }
8489
8490 skb_put(skb, len);
8491 h2c = (struct rtw89_h2c_wow_global *)skb->data;
8492
8493 h2c->w0 = le32_encode_bits(enable, RTW89_H2C_WOW_GLOBAL_W0_ENABLE) |
8494 le32_encode_bits(macid, RTW89_H2C_WOW_GLOBAL_W0_MAC_ID) |
8495 le32_encode_bits(rtw_wow->ptk_alg,
8496 RTW89_H2C_WOW_GLOBAL_W0_PAIRWISE_SEC_ALGO) |
8497 le32_encode_bits(rtw_wow->gtk_alg,
8498 RTW89_H2C_WOW_GLOBAL_W0_GROUP_SEC_ALGO);
8499 h2c->key_info = rtw_wow->key_info;
8500
8501 rtw89_h2c_pkt_set_hdr(rtwdev, skb, FWCMD_TYPE_H2C,
8502 H2C_CAT_MAC,
8503 H2C_CL_MAC_WOW,
8504 H2C_FUNC_WOW_GLOBAL, 0, 1,
8505 len);
8506
8507 ret = rtw89_h2c_tx(rtwdev, skb, false);
8508 if (ret) {
8509 rtw89_err(rtwdev, "failed to send h2c\n");
8510 goto fail;
8511 }
8512
8513 return 0;
8514
8515 fail:
8516 dev_kfree_skb_any(skb);
8517
8518 return ret;
8519 }
8520
8521 #define H2C_WAKEUP_CTRL_LEN 4
8522 int rtw89_fw_h2c_wow_wakeup_ctrl(struct rtw89_dev *rtwdev,
8523 struct rtw89_vif_link *rtwvif_link,
8524 bool enable)
8525 {
8526 struct rtw89_wow_param *rtw_wow = &rtwdev->wow;
8527 struct sk_buff *skb;
8528 u8 macid = rtwvif_link->mac_id;
8529 int ret;
8530
8531 skb = rtw89_fw_h2c_alloc_skb_with_hdr(rtwdev, H2C_WAKEUP_CTRL_LEN);
8532 if (!skb) {
8533 rtw89_err(rtwdev, "failed to alloc skb for wakeup ctrl\n");
8534 return -ENOMEM;
8535 }
8536
8537 skb_put(skb, H2C_WAKEUP_CTRL_LEN);
8538
8539 if (rtw_wow->pattern_cnt)
8540 RTW89_SET_WOW_WAKEUP_CTRL_PATTERN_MATCH_ENABLE(skb->data, enable);
8541 if (test_bit(RTW89_WOW_FLAG_EN_MAGIC_PKT, rtw_wow->flags))
8542 RTW89_SET_WOW_WAKEUP_CTRL_MAGIC_ENABLE(skb->data, enable);
8543 if (test_bit(RTW89_WOW_FLAG_EN_DISCONNECT, rtw_wow->flags))
8544 RTW89_SET_WOW_WAKEUP_CTRL_DEAUTH_ENABLE(skb->data, enable);
8545
8546 RTW89_SET_WOW_WAKEUP_CTRL_MAC_ID(skb->data, macid);
8547
8548 rtw89_h2c_pkt_set_hdr(rtwdev, skb, FWCMD_TYPE_H2C,
8549 H2C_CAT_MAC,
8550 H2C_CL_MAC_WOW,
8551 H2C_FUNC_WAKEUP_CTRL, 0, 1,
8552 H2C_WAKEUP_CTRL_LEN);
8553
8554 ret = rtw89_h2c_tx(rtwdev, skb, false);
8555 if (ret) {
8556 rtw89_err(rtwdev, "failed to send h2c\n");
8557 goto fail;
8558 }
8559
8560 return 0;
8561
8562 fail:
8563 dev_kfree_skb_any(skb);
8564
8565 return ret;
8566 }
8567
8568 #define H2C_WOW_CAM_UPD_LEN 24
8569 int rtw89_fw_wow_cam_update(struct rtw89_dev *rtwdev,
8570 struct rtw89_wow_cam_info *cam_info)
8571 {
8572 struct sk_buff *skb;
8573 int ret;
8574
8575 skb = rtw89_fw_h2c_alloc_skb_with_hdr(rtwdev, H2C_WOW_CAM_UPD_LEN);
8576 if (!skb) {
8577 rtw89_err(rtwdev, "failed to alloc skb for keep alive\n");
8578 return -ENOMEM;
8579 }
8580
8581 skb_put(skb, H2C_WOW_CAM_UPD_LEN);
8582
8583 RTW89_SET_WOW_CAM_UPD_R_W(skb->data, cam_info->r_w);
8584 RTW89_SET_WOW_CAM_UPD_IDX(skb->data, cam_info->idx);
8585 if (cam_info->valid) {
8586 RTW89_SET_WOW_CAM_UPD_WKFM1(skb->data, cam_info->mask[0]);
8587 RTW89_SET_WOW_CAM_UPD_WKFM2(skb->data, cam_info->mask[1]);
8588 RTW89_SET_WOW_CAM_UPD_WKFM3(skb->data, cam_info->mask[2]);
8589 RTW89_SET_WOW_CAM_UPD_WKFM4(skb->data, cam_info->mask[3]);
8590 RTW89_SET_WOW_CAM_UPD_CRC(skb->data, cam_info->crc);
8591 RTW89_SET_WOW_CAM_UPD_NEGATIVE_PATTERN_MATCH(skb->data,
8592 cam_info->negative_pattern_match);
8593 RTW89_SET_WOW_CAM_UPD_SKIP_MAC_HDR(skb->data,
8594 cam_info->skip_mac_hdr);
8595 RTW89_SET_WOW_CAM_UPD_UC(skb->data, cam_info->uc);
8596 RTW89_SET_WOW_CAM_UPD_MC(skb->data, cam_info->mc);
8597 RTW89_SET_WOW_CAM_UPD_BC(skb->data, cam_info->bc);
8598 }
8599 RTW89_SET_WOW_CAM_UPD_VALID(skb->data, cam_info->valid);
8600
8601 rtw89_h2c_pkt_set_hdr(rtwdev, skb, FWCMD_TYPE_H2C,
8602 H2C_CAT_MAC,
8603 H2C_CL_MAC_WOW,
8604 H2C_FUNC_WOW_CAM_UPD, 0, 1,
8605 H2C_WOW_CAM_UPD_LEN);
8606
8607 ret = rtw89_h2c_tx(rtwdev, skb, false);
8608 if (ret) {
8609 rtw89_err(rtwdev, "failed to send h2c\n");
8610 goto fail;
8611 }
8612
8613 return 0;
8614 fail:
8615 dev_kfree_skb_any(skb);
8616
8617 return ret;
8618 }
8619
8620 int rtw89_fw_h2c_wow_gtk_ofld(struct rtw89_dev *rtwdev,
8621 struct rtw89_vif_link *rtwvif_link,
8622 bool enable)
8623 {
8624 struct rtw89_wow_param *rtw_wow = &rtwdev->wow;
8625 struct rtw89_wow_gtk_info *gtk_info = &rtw_wow->gtk_info;
8626 struct rtw89_h2c_wow_gtk_ofld *h2c;
8627 u8 macid = rtwvif_link->mac_id;
8628 u32 len = sizeof(*h2c);
8629 u8 pkt_id_sa_query = 0;
8630 struct sk_buff *skb;
8631 u8 pkt_id_eapol = 0;
8632 int ret;
8633
8634 if (!rtw_wow->gtk_alg)
8635 return 0;
8636
8637 skb = rtw89_fw_h2c_alloc_skb_with_hdr(rtwdev, len);
8638 if (!skb) {
8639 rtw89_err(rtwdev, "failed to alloc skb for gtk ofld\n");
8640 return -ENOMEM;
8641 }
8642
8643 skb_put(skb, len);
8644 h2c = (struct rtw89_h2c_wow_gtk_ofld *)skb->data;
8645
8646 if (!enable)
8647 goto hdr;
8648
8649 ret = rtw89_fw_h2c_add_general_pkt(rtwdev, rtwvif_link,
8650 RTW89_PKT_OFLD_TYPE_EAPOL_KEY,
8651 &pkt_id_eapol);
8652 if (ret)
8653 goto fail;
8654
8655 if (gtk_info->igtk_keyid) {
8656 ret = rtw89_fw_h2c_add_general_pkt(rtwdev, rtwvif_link,
8657 RTW89_PKT_OFLD_TYPE_SA_QUERY,
8658 &pkt_id_sa_query);
8659 if (ret)
8660 goto fail;
8661 }
8662
8663 /* not support TKIP yet */
8664 h2c->w0 = le32_encode_bits(enable, RTW89_H2C_WOW_GTK_OFLD_W0_EN) |
8665 le32_encode_bits(0, RTW89_H2C_WOW_GTK_OFLD_W0_TKIP_EN) |
8666 le32_encode_bits(gtk_info->igtk_keyid ? 1 : 0,
8667 RTW89_H2C_WOW_GTK_OFLD_W0_IEEE80211W_EN) |
8668 le32_encode_bits(macid, RTW89_H2C_WOW_GTK_OFLD_W0_MAC_ID) |
8669 le32_encode_bits(pkt_id_eapol, RTW89_H2C_WOW_GTK_OFLD_W0_GTK_RSP_ID);
8670 h2c->w1 = le32_encode_bits(gtk_info->igtk_keyid ? pkt_id_sa_query : 0,
8671 RTW89_H2C_WOW_GTK_OFLD_W1_PMF_SA_QUERY_ID) |
8672 le32_encode_bits(rtw_wow->akm, RTW89_H2C_WOW_GTK_OFLD_W1_ALGO_AKM_SUIT);
8673 h2c->gtk_info = rtw_wow->gtk_info;
8674
8675 hdr:
8676 rtw89_h2c_pkt_set_hdr(rtwdev, skb, FWCMD_TYPE_H2C,
8677 H2C_CAT_MAC,
8678 H2C_CL_MAC_WOW,
8679 H2C_FUNC_GTK_OFLD, 0, 1,
8680 len);
8681
8682 ret = rtw89_h2c_tx(rtwdev, skb, false);
8683 if (ret) {
8684 rtw89_err(rtwdev, "failed to send h2c\n");
8685 goto fail;
8686 }
8687 return 0;
8688 fail:
8689 dev_kfree_skb_any(skb);
8690
8691 return ret;
8692 }
8693
8694 int rtw89_fw_h2c_fwips(struct rtw89_dev *rtwdev, struct rtw89_vif_link *rtwvif_link,
8695 bool enable)
8696 {
8697 struct rtw89_wait_info *wait = &rtwdev->mac.ps_wait;
8698 struct rtw89_h2c_fwips *h2c;
8699 u32 len = sizeof(*h2c);
8700 struct sk_buff *skb;
8701
8702 skb = rtw89_fw_h2c_alloc_skb_with_hdr(rtwdev, len);
8703 if (!skb) {
8704 rtw89_err(rtwdev, "failed to alloc skb for fw ips\n");
8705 return -ENOMEM;
8706 }
8707 skb_put(skb, len);
8708 h2c = (struct rtw89_h2c_fwips *)skb->data;
8709
8710 h2c->w0 = le32_encode_bits(rtwvif_link->mac_id, RTW89_H2C_FW_IPS_W0_MACID) |
8711 le32_encode_bits(enable, RTW89_H2C_FW_IPS_W0_ENABLE);
8712
8713 rtw89_h2c_pkt_set_hdr(rtwdev, skb, FWCMD_TYPE_H2C,
8714 H2C_CAT_MAC,
8715 H2C_CL_MAC_PS,
8716 H2C_FUNC_IPS_CFG, 0, 1,
8717 len);
8718
8719 return rtw89_h2c_tx_and_wait(rtwdev, skb, wait, RTW89_PS_WAIT_COND_IPS_CFG);
8720 }
8721
8722 int rtw89_fw_h2c_wow_request_aoac(struct rtw89_dev *rtwdev)
8723 {
8724 struct rtw89_wait_info *wait = &rtwdev->wow.wait;
8725 struct rtw89_h2c_wow_aoac *h2c;
8726 u32 len = sizeof(*h2c);
8727 struct sk_buff *skb;
8728
8729 skb = rtw89_fw_h2c_alloc_skb_with_hdr(rtwdev, len);
8730 if (!skb) {
8731 rtw89_err(rtwdev, "failed to alloc skb for aoac\n");
8732 return -ENOMEM;
8733 }
8734
8735 skb_put(skb, len);
8736
8737 /* This H2C only nofity firmware to generate AOAC report C2H,
8738 * no need any parameter.
8739 */
8740 rtw89_h2c_pkt_set_hdr(rtwdev, skb, FWCMD_TYPE_H2C,
8741 H2C_CAT_MAC,
8742 H2C_CL_MAC_WOW,
8743 H2C_FUNC_AOAC_REPORT_REQ, 1, 0,
8744 len);
8745
8746 return rtw89_h2c_tx_and_wait(rtwdev, skb, wait, RTW89_WOW_WAIT_COND_AOAC);
8747 }
8748
8749 /* Return < 0, if failures happen during waiting for the condition.
8750 * Return 0, when waiting for the condition succeeds.
8751 * Return > 0, if the wait is considered unreachable due to driver/FW design,
8752 * where 1 means during SER.
8753 */
8754 static int rtw89_h2c_tx_and_wait(struct rtw89_dev *rtwdev, struct sk_buff *skb,
8755 struct rtw89_wait_info *wait, unsigned int cond)
8756 {
8757 int ret;
8758
8759 ret = rtw89_h2c_tx(rtwdev, skb, false);
8760 if (ret) {
8761 rtw89_err(rtwdev, "failed to send h2c\n");
8762 dev_kfree_skb_any(skb);
8763 return -EBUSY;
8764 }
8765
8766 if (test_bit(RTW89_FLAG_SER_HANDLING, rtwdev->flags))
8767 return 1;
8768
8769 return rtw89_wait_for_cond(wait, cond);
8770 }
8771
8772 #define H2C_ADD_MCC_LEN 16
8773 int rtw89_fw_h2c_add_mcc(struct rtw89_dev *rtwdev,
8774 const struct rtw89_fw_mcc_add_req *p)
8775 {
8776 struct rtw89_wait_info *wait = &rtwdev->mcc.wait;
8777 struct sk_buff *skb;
8778 unsigned int cond;
8779
8780 skb = rtw89_fw_h2c_alloc_skb_with_hdr(rtwdev, H2C_ADD_MCC_LEN);
8781 if (!skb) {
8782 rtw89_err(rtwdev,
8783 "failed to alloc skb for add mcc\n");
8784 return -ENOMEM;
8785 }
8786
8787 skb_put(skb, H2C_ADD_MCC_LEN);
8788 RTW89_SET_FWCMD_ADD_MCC_MACID(skb->data, p->macid);
8789 RTW89_SET_FWCMD_ADD_MCC_CENTRAL_CH_SEG0(skb->data, p->central_ch_seg0);
8790 RTW89_SET_FWCMD_ADD_MCC_CENTRAL_CH_SEG1(skb->data, p->central_ch_seg1);
8791 RTW89_SET_FWCMD_ADD_MCC_PRIMARY_CH(skb->data, p->primary_ch);
8792 RTW89_SET_FWCMD_ADD_MCC_BANDWIDTH(skb->data, p->bandwidth);
8793 RTW89_SET_FWCMD_ADD_MCC_GROUP(skb->data, p->group);
8794 RTW89_SET_FWCMD_ADD_MCC_C2H_RPT(skb->data, p->c2h_rpt);
8795 RTW89_SET_FWCMD_ADD_MCC_DIS_TX_NULL(skb->data, p->dis_tx_null);
8796 RTW89_SET_FWCMD_ADD_MCC_DIS_SW_RETRY(skb->data, p->dis_sw_retry);
8797 RTW89_SET_FWCMD_ADD_MCC_IN_CURR_CH(skb->data, p->in_curr_ch);
8798 RTW89_SET_FWCMD_ADD_MCC_SW_RETRY_COUNT(skb->data, p->sw_retry_count);
8799 RTW89_SET_FWCMD_ADD_MCC_TX_NULL_EARLY(skb->data, p->tx_null_early);
8800 RTW89_SET_FWCMD_ADD_MCC_BTC_IN_2G(skb->data, p->btc_in_2g);
8801 RTW89_SET_FWCMD_ADD_MCC_PTA_EN(skb->data, p->pta_en);
8802 RTW89_SET_FWCMD_ADD_MCC_RFK_BY_PASS(skb->data, p->rfk_by_pass);
8803 RTW89_SET_FWCMD_ADD_MCC_CH_BAND_TYPE(skb->data, p->ch_band_type);
8804 RTW89_SET_FWCMD_ADD_MCC_DURATION(skb->data, p->duration);
8805 RTW89_SET_FWCMD_ADD_MCC_COURTESY_EN(skb->data, p->courtesy_en);
8806 RTW89_SET_FWCMD_ADD_MCC_COURTESY_NUM(skb->data, p->courtesy_num);
8807 RTW89_SET_FWCMD_ADD_MCC_COURTESY_TARGET(skb->data, p->courtesy_target);
8808
8809 rtw89_h2c_pkt_set_hdr(rtwdev, skb, FWCMD_TYPE_H2C,
8810 H2C_CAT_MAC,
8811 H2C_CL_MCC,
8812 H2C_FUNC_ADD_MCC, 0, 0,
8813 H2C_ADD_MCC_LEN);
8814
8815 cond = RTW89_MCC_WAIT_COND(p->group, H2C_FUNC_ADD_MCC);
8816 return rtw89_h2c_tx_and_wait(rtwdev, skb, wait, cond);
8817 }
8818
8819 #define H2C_START_MCC_LEN 12
8820 int rtw89_fw_h2c_start_mcc(struct rtw89_dev *rtwdev,
8821 const struct rtw89_fw_mcc_start_req *p)
8822 {
8823 struct rtw89_wait_info *wait = &rtwdev->mcc.wait;
8824 struct sk_buff *skb;
8825 unsigned int cond;
8826
8827 skb = rtw89_fw_h2c_alloc_skb_with_hdr(rtwdev, H2C_START_MCC_LEN);
8828 if (!skb) {
8829 rtw89_err(rtwdev,
8830 "failed to alloc skb for start mcc\n");
8831 return -ENOMEM;
8832 }
8833
8834 skb_put(skb, H2C_START_MCC_LEN);
8835 RTW89_SET_FWCMD_START_MCC_GROUP(skb->data, p->group);
8836 RTW89_SET_FWCMD_START_MCC_BTC_IN_GROUP(skb->data, p->btc_in_group);
8837 RTW89_SET_FWCMD_START_MCC_OLD_GROUP_ACTION(skb->data, p->old_group_action);
8838 RTW89_SET_FWCMD_START_MCC_OLD_GROUP(skb->data, p->old_group);
8839 RTW89_SET_FWCMD_START_MCC_NOTIFY_CNT(skb->data, p->notify_cnt);
8840 RTW89_SET_FWCMD_START_MCC_NOTIFY_RXDBG_EN(skb->data, p->notify_rxdbg_en);
8841 RTW89_SET_FWCMD_START_MCC_MACID(skb->data, p->macid);
8842 RTW89_SET_FWCMD_START_MCC_TSF_LOW(skb->data, p->tsf_low);
8843 RTW89_SET_FWCMD_START_MCC_TSF_HIGH(skb->data, p->tsf_high);
8844
8845 rtw89_h2c_pkt_set_hdr(rtwdev, skb, FWCMD_TYPE_H2C,
8846 H2C_CAT_MAC,
8847 H2C_CL_MCC,
8848 H2C_FUNC_START_MCC, 0, 0,
8849 H2C_START_MCC_LEN);
8850
8851 cond = RTW89_MCC_WAIT_COND(p->group, H2C_FUNC_START_MCC);
8852 return rtw89_h2c_tx_and_wait(rtwdev, skb, wait, cond);
8853 }
8854
8855 #define H2C_STOP_MCC_LEN 4
8856 int rtw89_fw_h2c_stop_mcc(struct rtw89_dev *rtwdev, u8 group, u8 macid,
8857 bool prev_groups)
8858 {
8859 struct rtw89_wait_info *wait = &rtwdev->mcc.wait;
8860 struct sk_buff *skb;
8861 unsigned int cond;
8862
8863 skb = rtw89_fw_h2c_alloc_skb_with_hdr(rtwdev, H2C_STOP_MCC_LEN);
8864 if (!skb) {
8865 rtw89_err(rtwdev,
8866 "failed to alloc skb for stop mcc\n");
8867 return -ENOMEM;
8868 }
8869
8870 skb_put(skb, H2C_STOP_MCC_LEN);
8871 RTW89_SET_FWCMD_STOP_MCC_MACID(skb->data, macid);
8872 RTW89_SET_FWCMD_STOP_MCC_GROUP(skb->data, group);
8873 RTW89_SET_FWCMD_STOP_MCC_PREV_GROUPS(skb->data, prev_groups);
8874
8875 rtw89_h2c_pkt_set_hdr(rtwdev, skb, FWCMD_TYPE_H2C,
8876 H2C_CAT_MAC,
8877 H2C_CL_MCC,
8878 H2C_FUNC_STOP_MCC, 0, 0,
8879 H2C_STOP_MCC_LEN);
8880
8881 cond = RTW89_MCC_WAIT_COND(group, H2C_FUNC_STOP_MCC);
8882 return rtw89_h2c_tx_and_wait(rtwdev, skb, wait, cond);
8883 }
8884
8885 #define H2C_DEL_MCC_GROUP_LEN 4
8886 int rtw89_fw_h2c_del_mcc_group(struct rtw89_dev *rtwdev, u8 group,
8887 bool prev_groups)
8888 {
8889 struct rtw89_wait_info *wait = &rtwdev->mcc.wait;
8890 struct sk_buff *skb;
8891 unsigned int cond;
8892
8893 skb = rtw89_fw_h2c_alloc_skb_with_hdr(rtwdev, H2C_DEL_MCC_GROUP_LEN);
8894 if (!skb) {
8895 rtw89_err(rtwdev,
8896 "failed to alloc skb for del mcc group\n");
8897 return -ENOMEM;
8898 }
8899
8900 skb_put(skb, H2C_DEL_MCC_GROUP_LEN);
8901 RTW89_SET_FWCMD_DEL_MCC_GROUP_GROUP(skb->data, group);
8902 RTW89_SET_FWCMD_DEL_MCC_GROUP_PREV_GROUPS(skb->data, prev_groups);
8903
8904 rtw89_h2c_pkt_set_hdr(rtwdev, skb, FWCMD_TYPE_H2C,
8905 H2C_CAT_MAC,
8906 H2C_CL_MCC,
8907 H2C_FUNC_DEL_MCC_GROUP, 0, 0,
8908 H2C_DEL_MCC_GROUP_LEN);
8909
8910 cond = RTW89_MCC_WAIT_COND(group, H2C_FUNC_DEL_MCC_GROUP);
8911 return rtw89_h2c_tx_and_wait(rtwdev, skb, wait, cond);
8912 }
8913
8914 #define H2C_RESET_MCC_GROUP_LEN 4
8915 int rtw89_fw_h2c_reset_mcc_group(struct rtw89_dev *rtwdev, u8 group)
8916 {
8917 struct rtw89_wait_info *wait = &rtwdev->mcc.wait;
8918 struct sk_buff *skb;
8919 unsigned int cond;
8920
8921 skb = rtw89_fw_h2c_alloc_skb_with_hdr(rtwdev, H2C_RESET_MCC_GROUP_LEN);
8922 if (!skb) {
8923 rtw89_err(rtwdev,
8924 "failed to alloc skb for reset mcc group\n");
8925 return -ENOMEM;
8926 }
8927
8928 skb_put(skb, H2C_RESET_MCC_GROUP_LEN);
8929 RTW89_SET_FWCMD_RESET_MCC_GROUP_GROUP(skb->data, group);
8930
8931 rtw89_h2c_pkt_set_hdr(rtwdev, skb, FWCMD_TYPE_H2C,
8932 H2C_CAT_MAC,
8933 H2C_CL_MCC,
8934 H2C_FUNC_RESET_MCC_GROUP, 0, 0,
8935 H2C_RESET_MCC_GROUP_LEN);
8936
8937 cond = RTW89_MCC_WAIT_COND(group, H2C_FUNC_RESET_MCC_GROUP);
8938 return rtw89_h2c_tx_and_wait(rtwdev, skb, wait, cond);
8939 }
8940
8941 #define H2C_MCC_REQ_TSF_LEN 4
8942 int rtw89_fw_h2c_mcc_req_tsf(struct rtw89_dev *rtwdev,
8943 const struct rtw89_fw_mcc_tsf_req *req,
8944 struct rtw89_mac_mcc_tsf_rpt *rpt)
8945 {
8946 struct rtw89_wait_info *wait = &rtwdev->mcc.wait;
8947 struct rtw89_mac_mcc_tsf_rpt *tmp;
8948 struct sk_buff *skb;
8949 unsigned int cond;
8950 int ret;
8951
8952 skb = rtw89_fw_h2c_alloc_skb_with_hdr(rtwdev, H2C_MCC_REQ_TSF_LEN);
8953 if (!skb) {
8954 rtw89_err(rtwdev,
8955 "failed to alloc skb for mcc req tsf\n");
8956 return -ENOMEM;
8957 }
8958
8959 skb_put(skb, H2C_MCC_REQ_TSF_LEN);
8960 RTW89_SET_FWCMD_MCC_REQ_TSF_GROUP(skb->data, req->group);
8961 RTW89_SET_FWCMD_MCC_REQ_TSF_MACID_X(skb->data, req->macid_x);
8962 RTW89_SET_FWCMD_MCC_REQ_TSF_MACID_Y(skb->data, req->macid_y);
8963
8964 rtw89_h2c_pkt_set_hdr(rtwdev, skb, FWCMD_TYPE_H2C,
8965 H2C_CAT_MAC,
8966 H2C_CL_MCC,
8967 H2C_FUNC_MCC_REQ_TSF, 0, 0,
8968 H2C_MCC_REQ_TSF_LEN);
8969
8970 cond = RTW89_MCC_WAIT_COND(req->group, H2C_FUNC_MCC_REQ_TSF);
8971 ret = rtw89_h2c_tx_and_wait(rtwdev, skb, wait, cond);
8972 if (ret)
8973 return ret;
8974
8975 tmp = (struct rtw89_mac_mcc_tsf_rpt *)wait->data.buf;
8976 *rpt = *tmp;
8977
8978 return 0;
8979 }
8980
8981 #define H2C_MCC_MACID_BITMAP_DSC_LEN 4
8982 int rtw89_fw_h2c_mcc_macid_bitmap(struct rtw89_dev *rtwdev, u8 group, u8 macid,
8983 u8 *bitmap)
8984 {
8985 struct rtw89_wait_info *wait = &rtwdev->mcc.wait;
8986 struct sk_buff *skb;
8987 unsigned int cond;
8988 u8 map_len;
8989 u8 h2c_len;
8990
8991 BUILD_BUG_ON(RTW89_MAX_MAC_ID_NUM % 8);
8992 map_len = RTW89_MAX_MAC_ID_NUM / 8;
8993 h2c_len = H2C_MCC_MACID_BITMAP_DSC_LEN + map_len;
8994 skb = rtw89_fw_h2c_alloc_skb_with_hdr(rtwdev, h2c_len);
8995 if (!skb) {
8996 rtw89_err(rtwdev,
8997 "failed to alloc skb for mcc macid bitmap\n");
8998 return -ENOMEM;
8999 }
9000
9001 skb_put(skb, h2c_len);
9002 RTW89_SET_FWCMD_MCC_MACID_BITMAP_GROUP(skb->data, group);
9003 RTW89_SET_FWCMD_MCC_MACID_BITMAP_MACID(skb->data, macid);
9004 RTW89_SET_FWCMD_MCC_MACID_BITMAP_BITMAP_LENGTH(skb->data, map_len);
9005 RTW89_SET_FWCMD_MCC_MACID_BITMAP_BITMAP(skb->data, bitmap, map_len);
9006
9007 rtw89_h2c_pkt_set_hdr(rtwdev, skb, FWCMD_TYPE_H2C,
9008 H2C_CAT_MAC,
9009 H2C_CL_MCC,
9010 H2C_FUNC_MCC_MACID_BITMAP, 0, 0,
9011 h2c_len);
9012
9013 cond = RTW89_MCC_WAIT_COND(group, H2C_FUNC_MCC_MACID_BITMAP);
9014 return rtw89_h2c_tx_and_wait(rtwdev, skb, wait, cond);
9015 }
9016
9017 #define H2C_MCC_SYNC_LEN 4
9018 int rtw89_fw_h2c_mcc_sync(struct rtw89_dev *rtwdev, u8 group, u8 source,
9019 u8 target, u8 offset)
9020 {
9021 struct rtw89_wait_info *wait = &rtwdev->mcc.wait;
9022 struct sk_buff *skb;
9023 unsigned int cond;
9024
9025 skb = rtw89_fw_h2c_alloc_skb_with_hdr(rtwdev, H2C_MCC_SYNC_LEN);
9026 if (!skb) {
9027 rtw89_err(rtwdev,
9028 "failed to alloc skb for mcc sync\n");
9029 return -ENOMEM;
9030 }
9031
9032 skb_put(skb, H2C_MCC_SYNC_LEN);
9033 RTW89_SET_FWCMD_MCC_SYNC_GROUP(skb->data, group);
9034 RTW89_SET_FWCMD_MCC_SYNC_MACID_SOURCE(skb->data, source);
9035 RTW89_SET_FWCMD_MCC_SYNC_MACID_TARGET(skb->data, target);
9036 RTW89_SET_FWCMD_MCC_SYNC_SYNC_OFFSET(skb->data, offset);
9037
9038 rtw89_h2c_pkt_set_hdr(rtwdev, skb, FWCMD_TYPE_H2C,
9039 H2C_CAT_MAC,
9040 H2C_CL_MCC,
9041 H2C_FUNC_MCC_SYNC, 0, 0,
9042 H2C_MCC_SYNC_LEN);
9043
9044 cond = RTW89_MCC_WAIT_COND(group, H2C_FUNC_MCC_SYNC);
9045 return rtw89_h2c_tx_and_wait(rtwdev, skb, wait, cond);
9046 }
9047
9048 #define H2C_MCC_SET_DURATION_LEN 20
9049 int rtw89_fw_h2c_mcc_set_duration(struct rtw89_dev *rtwdev,
9050 const struct rtw89_fw_mcc_duration *p)
9051 {
9052 struct rtw89_wait_info *wait = &rtwdev->mcc.wait;
9053 struct sk_buff *skb;
9054 unsigned int cond;
9055
9056 skb = rtw89_fw_h2c_alloc_skb_with_hdr(rtwdev, H2C_MCC_SET_DURATION_LEN);
9057 if (!skb) {
9058 rtw89_err(rtwdev,
9059 "failed to alloc skb for mcc set duration\n");
9060 return -ENOMEM;
9061 }
9062
9063 skb_put(skb, H2C_MCC_SET_DURATION_LEN);
9064 RTW89_SET_FWCMD_MCC_SET_DURATION_GROUP(skb->data, p->group);
9065 RTW89_SET_FWCMD_MCC_SET_DURATION_BTC_IN_GROUP(skb->data, p->btc_in_group);
9066 RTW89_SET_FWCMD_MCC_SET_DURATION_START_MACID(skb->data, p->start_macid);
9067 RTW89_SET_FWCMD_MCC_SET_DURATION_MACID_X(skb->data, p->macid_x);
9068 RTW89_SET_FWCMD_MCC_SET_DURATION_MACID_Y(skb->data, p->macid_y);
9069 RTW89_SET_FWCMD_MCC_SET_DURATION_START_TSF_LOW(skb->data,
9070 p->start_tsf_low);
9071 RTW89_SET_FWCMD_MCC_SET_DURATION_START_TSF_HIGH(skb->data,
9072 p->start_tsf_high);
9073 RTW89_SET_FWCMD_MCC_SET_DURATION_DURATION_X(skb->data, p->duration_x);
9074 RTW89_SET_FWCMD_MCC_SET_DURATION_DURATION_Y(skb->data, p->duration_y);
9075
9076 rtw89_h2c_pkt_set_hdr(rtwdev, skb, FWCMD_TYPE_H2C,
9077 H2C_CAT_MAC,
9078 H2C_CL_MCC,
9079 H2C_FUNC_MCC_SET_DURATION, 0, 0,
9080 H2C_MCC_SET_DURATION_LEN);
9081
9082 cond = RTW89_MCC_WAIT_COND(p->group, H2C_FUNC_MCC_SET_DURATION);
9083 return rtw89_h2c_tx_and_wait(rtwdev, skb, wait, cond);
9084 }
9085
9086 static
9087 u32 rtw89_fw_h2c_mrc_add_slot(struct rtw89_dev *rtwdev,
9088 const struct rtw89_fw_mrc_add_slot_arg *slot_arg,
9089 struct rtw89_h2c_mrc_add_slot *slot_h2c)
9090 {
9091 bool fill_h2c = !!slot_h2c;
9092 unsigned int i;
9093
9094 if (!fill_h2c)
9095 goto calc_len;
9096
9097 slot_h2c->w0 = le32_encode_bits(slot_arg->duration,
9098 RTW89_H2C_MRC_ADD_SLOT_W0_DURATION) |
9099 le32_encode_bits(slot_arg->courtesy_en,
9100 RTW89_H2C_MRC_ADD_SLOT_W0_COURTESY_EN) |
9101 le32_encode_bits(slot_arg->role_num,
9102 RTW89_H2C_MRC_ADD_SLOT_W0_ROLE_NUM);
9103 slot_h2c->w1 = le32_encode_bits(slot_arg->courtesy_period,
9104 RTW89_H2C_MRC_ADD_SLOT_W1_COURTESY_PERIOD) |
9105 le32_encode_bits(slot_arg->courtesy_target,
9106 RTW89_H2C_MRC_ADD_SLOT_W1_COURTESY_TARGET);
9107
9108 for (i = 0; i < slot_arg->role_num; i++) {
9109 slot_h2c->roles[i].w0 =
9110 le32_encode_bits(slot_arg->roles[i].macid,
9111 RTW89_H2C_MRC_ADD_ROLE_W0_MACID) |
9112 le32_encode_bits(slot_arg->roles[i].role_type,
9113 RTW89_H2C_MRC_ADD_ROLE_W0_ROLE_TYPE) |
9114 le32_encode_bits(slot_arg->roles[i].is_master,
9115 RTW89_H2C_MRC_ADD_ROLE_W0_IS_MASTER) |
9116 le32_encode_bits(slot_arg->roles[i].en_tx_null,
9117 RTW89_H2C_MRC_ADD_ROLE_W0_TX_NULL_EN) |
9118 le32_encode_bits(false,
9119 RTW89_H2C_MRC_ADD_ROLE_W0_IS_ALT_ROLE) |
9120 le32_encode_bits(false,
9121 RTW89_H2C_MRC_ADD_ROLE_W0_ROLE_ALT_EN);
9122 slot_h2c->roles[i].w1 =
9123 le32_encode_bits(slot_arg->roles[i].central_ch,
9124 RTW89_H2C_MRC_ADD_ROLE_W1_CENTRAL_CH_SEG) |
9125 le32_encode_bits(slot_arg->roles[i].primary_ch,
9126 RTW89_H2C_MRC_ADD_ROLE_W1_PRI_CH) |
9127 le32_encode_bits(slot_arg->roles[i].bw,
9128 RTW89_H2C_MRC_ADD_ROLE_W1_BW) |
9129 le32_encode_bits(slot_arg->roles[i].band,
9130 RTW89_H2C_MRC_ADD_ROLE_W1_CH_BAND_TYPE) |
9131 le32_encode_bits(slot_arg->roles[i].null_early,
9132 RTW89_H2C_MRC_ADD_ROLE_W1_NULL_EARLY) |
9133 le32_encode_bits(false,
9134 RTW89_H2C_MRC_ADD_ROLE_W1_RFK_BY_PASS) |
9135 le32_encode_bits(true,
9136 RTW89_H2C_MRC_ADD_ROLE_W1_CAN_BTC);
9137 slot_h2c->roles[i].macid_main_bitmap =
9138 cpu_to_le32(slot_arg->roles[i].macid_main_bitmap);
9139 slot_h2c->roles[i].macid_paired_bitmap =
9140 cpu_to_le32(slot_arg->roles[i].macid_paired_bitmap);
9141 }
9142
9143 calc_len:
9144 return struct_size(slot_h2c, roles, slot_arg->role_num);
9145 }
9146
9147 int rtw89_fw_h2c_mrc_add(struct rtw89_dev *rtwdev,
9148 const struct rtw89_fw_mrc_add_arg *arg)
9149 {
9150 struct rtw89_h2c_mrc_add *h2c_head;
9151 struct sk_buff *skb;
9152 unsigned int i;
9153 #if defined(__linux__)
9154 void *tmp;
9155 #elif defined(__FreeBSD__)
9156 u8 *tmp;
9157 #endif
9158 u32 len;
9159 int ret;
9160
9161 len = sizeof(*h2c_head);
9162 for (i = 0; i < arg->slot_num; i++)
9163 len += rtw89_fw_h2c_mrc_add_slot(rtwdev, &arg->slots[i], NULL);
9164
9165 skb = rtw89_fw_h2c_alloc_skb_with_hdr(rtwdev, len);
9166 if (!skb) {
9167 rtw89_err(rtwdev, "failed to alloc skb for mrc add\n");
9168 return -ENOMEM;
9169 }
9170
9171 skb_put(skb, len);
9172 tmp = skb->data;
9173
9174 #if defined(__linux__)
9175 h2c_head = tmp;
9176 #elif defined(__FreeBSD__)
9177 h2c_head = (void *)tmp;
9178 #endif
9179 h2c_head->w0 = le32_encode_bits(arg->sch_idx,
9180 RTW89_H2C_MRC_ADD_W0_SCH_IDX) |
9181 le32_encode_bits(arg->sch_type,
9182 RTW89_H2C_MRC_ADD_W0_SCH_TYPE) |
9183 le32_encode_bits(arg->slot_num,
9184 RTW89_H2C_MRC_ADD_W0_SLOT_NUM) |
9185 le32_encode_bits(arg->btc_in_sch,
9186 RTW89_H2C_MRC_ADD_W0_BTC_IN_SCH);
9187
9188 tmp += sizeof(*h2c_head);
9189 for (i = 0; i < arg->slot_num; i++)
9190 #if defined(__linux__)
9191 tmp += rtw89_fw_h2c_mrc_add_slot(rtwdev, &arg->slots[i], tmp);
9192 #elif defined(__FreeBSD__)
9193 tmp += rtw89_fw_h2c_mrc_add_slot(rtwdev, &arg->slots[i], (void *)tmp);
9194 #endif
9195
9196 rtw89_h2c_pkt_set_hdr(rtwdev, skb, FWCMD_TYPE_H2C,
9197 H2C_CAT_MAC,
9198 H2C_CL_MRC,
9199 H2C_FUNC_ADD_MRC, 0, 0,
9200 len);
9201
9202 ret = rtw89_h2c_tx(rtwdev, skb, false);
9203 if (ret) {
9204 rtw89_err(rtwdev, "failed to send h2c\n");
9205 dev_kfree_skb_any(skb);
9206 return -EBUSY;
9207 }
9208
9209 return 0;
9210 }
9211
9212 int rtw89_fw_h2c_mrc_start(struct rtw89_dev *rtwdev,
9213 const struct rtw89_fw_mrc_start_arg *arg)
9214 {
9215 struct rtw89_wait_info *wait = &rtwdev->mcc.wait;
9216 struct rtw89_h2c_mrc_start *h2c;
9217 u32 len = sizeof(*h2c);
9218 struct sk_buff *skb;
9219 unsigned int cond;
9220
9221 skb = rtw89_fw_h2c_alloc_skb_with_hdr(rtwdev, len);
9222 if (!skb) {
9223 rtw89_err(rtwdev, "failed to alloc skb for mrc start\n");
9224 return -ENOMEM;
9225 }
9226
9227 skb_put(skb, len);
9228 h2c = (struct rtw89_h2c_mrc_start *)skb->data;
9229
9230 h2c->w0 = le32_encode_bits(arg->sch_idx,
9231 RTW89_H2C_MRC_START_W0_SCH_IDX) |
9232 le32_encode_bits(arg->old_sch_idx,
9233 RTW89_H2C_MRC_START_W0_OLD_SCH_IDX) |
9234 le32_encode_bits(arg->action,
9235 RTW89_H2C_MRC_START_W0_ACTION);
9236
9237 h2c->start_tsf_high = cpu_to_le32(arg->start_tsf >> 32);
9238 h2c->start_tsf_low = cpu_to_le32(arg->start_tsf);
9239
9240 rtw89_h2c_pkt_set_hdr(rtwdev, skb, FWCMD_TYPE_H2C,
9241 H2C_CAT_MAC,
9242 H2C_CL_MRC,
9243 H2C_FUNC_START_MRC, 0, 0,
9244 len);
9245
9246 cond = RTW89_MRC_WAIT_COND(arg->sch_idx, H2C_FUNC_START_MRC);
9247 return rtw89_h2c_tx_and_wait(rtwdev, skb, wait, cond);
9248 }
9249
9250 int rtw89_fw_h2c_mrc_del(struct rtw89_dev *rtwdev, u8 sch_idx, u8 slot_idx)
9251 {
9252 struct rtw89_wait_info *wait = &rtwdev->mcc.wait;
9253 struct rtw89_h2c_mrc_del *h2c;
9254 u32 len = sizeof(*h2c);
9255 struct sk_buff *skb;
9256 unsigned int cond;
9257
9258 skb = rtw89_fw_h2c_alloc_skb_with_hdr(rtwdev, len);
9259 if (!skb) {
9260 rtw89_err(rtwdev, "failed to alloc skb for mrc del\n");
9261 return -ENOMEM;
9262 }
9263
9264 skb_put(skb, len);
9265 h2c = (struct rtw89_h2c_mrc_del *)skb->data;
9266
9267 h2c->w0 = le32_encode_bits(sch_idx, RTW89_H2C_MRC_DEL_W0_SCH_IDX) |
9268 le32_encode_bits(slot_idx, RTW89_H2C_MRC_DEL_W0_STOP_SLOT_IDX);
9269
9270 rtw89_h2c_pkt_set_hdr(rtwdev, skb, FWCMD_TYPE_H2C,
9271 H2C_CAT_MAC,
9272 H2C_CL_MRC,
9273 H2C_FUNC_DEL_MRC, 0, 0,
9274 len);
9275
9276 cond = RTW89_MRC_WAIT_COND(sch_idx, H2C_FUNC_DEL_MRC);
9277 return rtw89_h2c_tx_and_wait(rtwdev, skb, wait, cond);
9278 }
9279
9280 int rtw89_fw_h2c_mrc_req_tsf(struct rtw89_dev *rtwdev,
9281 const struct rtw89_fw_mrc_req_tsf_arg *arg,
9282 struct rtw89_mac_mrc_tsf_rpt *rpt)
9283 {
9284 struct rtw89_wait_info *wait = &rtwdev->mcc.wait;
9285 struct rtw89_h2c_mrc_req_tsf *h2c;
9286 struct rtw89_mac_mrc_tsf_rpt *tmp;
9287 struct sk_buff *skb;
9288 unsigned int i;
9289 u32 len;
9290 int ret;
9291
9292 len = struct_size(h2c, infos, arg->num);
9293 skb = rtw89_fw_h2c_alloc_skb_with_hdr(rtwdev, len);
9294 if (!skb) {
9295 rtw89_err(rtwdev, "failed to alloc skb for mrc req tsf\n");
9296 return -ENOMEM;
9297 }
9298
9299 skb_put(skb, len);
9300 h2c = (struct rtw89_h2c_mrc_req_tsf *)skb->data;
9301
9302 h2c->req_tsf_num = arg->num;
9303 for (i = 0; i < arg->num; i++)
9304 h2c->infos[i] =
9305 u8_encode_bits(arg->infos[i].band,
9306 RTW89_H2C_MRC_REQ_TSF_INFO_BAND) |
9307 u8_encode_bits(arg->infos[i].port,
9308 RTW89_H2C_MRC_REQ_TSF_INFO_PORT);
9309
9310 rtw89_h2c_pkt_set_hdr(rtwdev, skb, FWCMD_TYPE_H2C,
9311 H2C_CAT_MAC,
9312 H2C_CL_MRC,
9313 H2C_FUNC_MRC_REQ_TSF, 0, 0,
9314 len);
9315
9316 ret = rtw89_h2c_tx_and_wait(rtwdev, skb, wait, RTW89_MRC_WAIT_COND_REQ_TSF);
9317 if (ret)
9318 return ret;
9319
9320 tmp = (struct rtw89_mac_mrc_tsf_rpt *)wait->data.buf;
9321 *rpt = *tmp;
9322
9323 return 0;
9324 }
9325
9326 int rtw89_fw_h2c_mrc_upd_bitmap(struct rtw89_dev *rtwdev,
9327 const struct rtw89_fw_mrc_upd_bitmap_arg *arg)
9328 {
9329 struct rtw89_h2c_mrc_upd_bitmap *h2c;
9330 u32 len = sizeof(*h2c);
9331 struct sk_buff *skb;
9332 int ret;
9333
9334 skb = rtw89_fw_h2c_alloc_skb_with_hdr(rtwdev, len);
9335 if (!skb) {
9336 rtw89_err(rtwdev, "failed to alloc skb for mrc upd bitmap\n");
9337 return -ENOMEM;
9338 }
9339
9340 skb_put(skb, len);
9341 h2c = (struct rtw89_h2c_mrc_upd_bitmap *)skb->data;
9342
9343 h2c->w0 = le32_encode_bits(arg->sch_idx,
9344 RTW89_H2C_MRC_UPD_BITMAP_W0_SCH_IDX) |
9345 le32_encode_bits(arg->action,
9346 RTW89_H2C_MRC_UPD_BITMAP_W0_ACTION) |
9347 le32_encode_bits(arg->macid,
9348 RTW89_H2C_MRC_UPD_BITMAP_W0_MACID);
9349 h2c->w1 = le32_encode_bits(arg->client_macid,
9350 RTW89_H2C_MRC_UPD_BITMAP_W1_CLIENT_MACID);
9351
9352 rtw89_h2c_pkt_set_hdr(rtwdev, skb, FWCMD_TYPE_H2C,
9353 H2C_CAT_MAC,
9354 H2C_CL_MRC,
9355 H2C_FUNC_MRC_UPD_BITMAP, 0, 0,
9356 len);
9357
9358 ret = rtw89_h2c_tx(rtwdev, skb, false);
9359 if (ret) {
9360 rtw89_err(rtwdev, "failed to send h2c\n");
9361 dev_kfree_skb_any(skb);
9362 return -EBUSY;
9363 }
9364
9365 return 0;
9366 }
9367
9368 int rtw89_fw_h2c_mrc_sync(struct rtw89_dev *rtwdev,
9369 const struct rtw89_fw_mrc_sync_arg *arg)
9370 {
9371 struct rtw89_h2c_mrc_sync *h2c;
9372 u32 len = sizeof(*h2c);
9373 struct sk_buff *skb;
9374 int ret;
9375
9376 skb = rtw89_fw_h2c_alloc_skb_with_hdr(rtwdev, len);
9377 if (!skb) {
9378 rtw89_err(rtwdev, "failed to alloc skb for mrc sync\n");
9379 return -ENOMEM;
9380 }
9381
9382 skb_put(skb, len);
9383 h2c = (struct rtw89_h2c_mrc_sync *)skb->data;
9384
9385 h2c->w0 = le32_encode_bits(true, RTW89_H2C_MRC_SYNC_W0_SYNC_EN) |
9386 le32_encode_bits(arg->src.port,
9387 RTW89_H2C_MRC_SYNC_W0_SRC_PORT) |
9388 le32_encode_bits(arg->src.band,
9389 RTW89_H2C_MRC_SYNC_W0_SRC_BAND) |
9390 le32_encode_bits(arg->dest.port,
9391 RTW89_H2C_MRC_SYNC_W0_DEST_PORT) |
9392 le32_encode_bits(arg->dest.band,
9393 RTW89_H2C_MRC_SYNC_W0_DEST_BAND);
9394 h2c->w1 = le32_encode_bits(arg->offset, RTW89_H2C_MRC_SYNC_W1_OFFSET);
9395
9396 rtw89_h2c_pkt_set_hdr(rtwdev, skb, FWCMD_TYPE_H2C,
9397 H2C_CAT_MAC,
9398 H2C_CL_MRC,
9399 H2C_FUNC_MRC_SYNC, 0, 0,
9400 len);
9401
9402 ret = rtw89_h2c_tx(rtwdev, skb, false);
9403 if (ret) {
9404 rtw89_err(rtwdev, "failed to send h2c\n");
9405 dev_kfree_skb_any(skb);
9406 return -EBUSY;
9407 }
9408
9409 return 0;
9410 }
9411
9412 int rtw89_fw_h2c_mrc_upd_duration(struct rtw89_dev *rtwdev,
9413 const struct rtw89_fw_mrc_upd_duration_arg *arg)
9414 {
9415 struct rtw89_h2c_mrc_upd_duration *h2c;
9416 struct sk_buff *skb;
9417 unsigned int i;
9418 u32 len;
9419 int ret;
9420
9421 len = struct_size(h2c, slots, arg->slot_num);
9422 skb = rtw89_fw_h2c_alloc_skb_with_hdr(rtwdev, len);
9423 if (!skb) {
9424 rtw89_err(rtwdev, "failed to alloc skb for mrc upd duration\n");
9425 return -ENOMEM;
9426 }
9427
9428 skb_put(skb, len);
9429 h2c = (struct rtw89_h2c_mrc_upd_duration *)skb->data;
9430
9431 h2c->w0 = le32_encode_bits(arg->sch_idx,
9432 RTW89_H2C_MRC_UPD_DURATION_W0_SCH_IDX) |
9433 le32_encode_bits(arg->slot_num,
9434 RTW89_H2C_MRC_UPD_DURATION_W0_SLOT_NUM) |
9435 le32_encode_bits(false,
9436 RTW89_H2C_MRC_UPD_DURATION_W0_BTC_IN_SCH);
9437
9438 h2c->start_tsf_high = cpu_to_le32(arg->start_tsf >> 32);
9439 h2c->start_tsf_low = cpu_to_le32(arg->start_tsf);
9440
9441 for (i = 0; i < arg->slot_num; i++) {
9442 h2c->slots[i] =
9443 le32_encode_bits(arg->slots[i].slot_idx,
9444 RTW89_H2C_MRC_UPD_DURATION_SLOT_SLOT_IDX) |
9445 le32_encode_bits(arg->slots[i].duration,
9446 RTW89_H2C_MRC_UPD_DURATION_SLOT_DURATION);
9447 }
9448
9449 rtw89_h2c_pkt_set_hdr(rtwdev, skb, FWCMD_TYPE_H2C,
9450 H2C_CAT_MAC,
9451 H2C_CL_MRC,
9452 H2C_FUNC_MRC_UPD_DURATION, 0, 0,
9453 len);
9454
9455 ret = rtw89_h2c_tx(rtwdev, skb, false);
9456 if (ret) {
9457 rtw89_err(rtwdev, "failed to send h2c\n");
9458 dev_kfree_skb_any(skb);
9459 return -EBUSY;
9460 }
9461
9462 return 0;
9463 }
9464
9465 static int rtw89_fw_h2c_ap_info(struct rtw89_dev *rtwdev, bool en)
9466 {
9467 struct rtw89_h2c_ap_info *h2c;
9468 u32 len = sizeof(*h2c);
9469 struct sk_buff *skb;
9470 int ret;
9471
9472 skb = rtw89_fw_h2c_alloc_skb_with_hdr(rtwdev, len);
9473 if (!skb) {
9474 rtw89_err(rtwdev, "failed to alloc skb for ap info\n");
9475 return -ENOMEM;
9476 }
9477
9478 skb_put(skb, len);
9479 h2c = (struct rtw89_h2c_ap_info *)skb->data;
9480
9481 h2c->w0 = le32_encode_bits(en, RTW89_H2C_AP_INFO_W0_PWR_INT_EN);
9482
9483 rtw89_h2c_pkt_set_hdr(rtwdev, skb, FWCMD_TYPE_H2C,
9484 H2C_CAT_MAC,
9485 H2C_CL_AP,
9486 H2C_FUNC_AP_INFO, 0, 0,
9487 len);
9488
9489 ret = rtw89_h2c_tx(rtwdev, skb, false);
9490 if (ret) {
9491 rtw89_err(rtwdev, "failed to send h2c\n");
9492 dev_kfree_skb_any(skb);
9493 return -EBUSY;
9494 }
9495
9496 return 0;
9497 }
9498
9499 int rtw89_fw_h2c_ap_info_refcount(struct rtw89_dev *rtwdev, bool en)
9500 {
9501 int ret;
9502
9503 if (en) {
9504 if (refcount_inc_not_zero(&rtwdev->refcount_ap_info))
9505 return 0;
9506 } else {
9507 if (!refcount_dec_and_test(&rtwdev->refcount_ap_info))
9508 return 0;
9509 }
9510
9511 ret = rtw89_fw_h2c_ap_info(rtwdev, en);
9512 if (ret) {
9513 if (!test_bit(RTW89_FLAG_SER_HANDLING, rtwdev->flags))
9514 return ret;
9515
9516 /* During recovery, neither driver nor stack has full error
9517 * handling, so show a warning, but return 0 with refcount
9518 * increased normally. It can avoid underflow when calling
9519 * with @en == false later.
9520 */
9521 rtw89_warn(rtwdev, "h2c ap_info failed during SER\n");
9522 }
9523
9524 if (en)
9525 refcount_set(&rtwdev->refcount_ap_info, 1);
9526
9527 return 0;
9528 }
9529
9530 int rtw89_fw_h2c_mlo_link_cfg(struct rtw89_dev *rtwdev, struct rtw89_vif_link *rtwvif_link,
9531 bool enable)
9532 {
9533 struct rtw89_wait_info *wait = &rtwdev->mlo.wait;
9534 struct rtw89_h2c_mlo_link_cfg *h2c;
9535 u8 mac_id = rtwvif_link->mac_id;
9536 u32 len = sizeof(*h2c);
9537 struct sk_buff *skb;
9538 unsigned int cond;
9539 int ret;
9540
9541 skb = rtw89_fw_h2c_alloc_skb_with_hdr(rtwdev, len);
9542 if (!skb) {
9543 rtw89_err(rtwdev, "failed to alloc skb for mlo link cfg\n");
9544 return -ENOMEM;
9545 }
9546
9547 skb_put(skb, len);
9548 h2c = (struct rtw89_h2c_mlo_link_cfg *)skb->data;
9549
9550 h2c->w0 = le32_encode_bits(mac_id, RTW89_H2C_MLO_LINK_CFG_W0_MACID) |
9551 le32_encode_bits(enable, RTW89_H2C_MLO_LINK_CFG_W0_OPTION);
9552
9553 rtw89_h2c_pkt_set_hdr(rtwdev, skb, FWCMD_TYPE_H2C,
9554 H2C_CAT_MAC,
9555 H2C_CL_MLO,
9556 H2C_FUNC_MLO_LINK_CFG, 0, 0,
9557 len);
9558
9559 cond = RTW89_MLO_WAIT_COND(mac_id, H2C_FUNC_MLO_LINK_CFG);
9560
9561 ret = rtw89_h2c_tx_and_wait(rtwdev, skb, wait, cond);
9562 if (ret) {
9563 rtw89_err(rtwdev, "mlo link cfg (%s link id %u) failed: %d\n",
9564 str_enable_disable(enable), rtwvif_link->link_id, ret);
9565 return ret;
9566 }
9567
9568 return 0;
9569 }
9570
9571 static bool __fw_txpwr_entry_zero_ext(const void *ext_ptr, u8 ext_len)
9572 {
9573 static const u8 zeros[U8_MAX] = {};
9574
9575 return memcmp(ext_ptr, zeros, ext_len) == 0;
9576 }
9577
9578 #if defined(__linux__)
9579 #define __fw_txpwr_entry_acceptable(e, cursor, ent_sz) \
9580 ({ \
9581 u8 __var_sz = sizeof(*(e)); \
9582 bool __accept; \
9583 if (__var_sz >= (ent_sz)) \
9584 __accept = true; \
9585 else \
9586 __accept = __fw_txpwr_entry_zero_ext((cursor) + __var_sz,\
9587 (ent_sz) - __var_sz);\
9588 __accept; \
9589 })
9590 #elif defined(__FreeBSD__)
9591 #define __fw_txpwr_entry_acceptable(e, cursor, ent_sz) \
9592 ({ \
9593 u8 __var_sz = sizeof(*(e)); \
9594 bool __accept; \
9595 if (__var_sz >= (ent_sz)) \
9596 __accept = true; \
9597 else \
9598 __accept = __fw_txpwr_entry_zero_ext((const u8 *)(cursor) + __var_sz,\
9599 (ent_sz) - __var_sz);\
9600 __accept; \
9601 })
9602 #endif
9603
9604 static bool
9605 fw_txpwr_byrate_entry_valid(const struct rtw89_fw_txpwr_byrate_entry *e,
9606 const void *cursor,
9607 const struct rtw89_txpwr_conf *conf)
9608 {
9609 if (!__fw_txpwr_entry_acceptable(e, cursor, conf->ent_sz))
9610 return false;
9611
9612 if (e->band >= RTW89_BAND_NUM || e->bw >= RTW89_BYR_BW_NUM)
9613 return false;
9614
9615 switch (e->rs) {
9616 case RTW89_RS_CCK:
9617 if (e->shf + e->len > RTW89_RATE_CCK_NUM)
9618 return false;
9619 break;
9620 case RTW89_RS_OFDM:
9621 if (e->shf + e->len > RTW89_RATE_OFDM_NUM)
9622 return false;
9623 break;
9624 case RTW89_RS_MCS:
9625 if (e->shf + e->len > __RTW89_RATE_MCS_NUM ||
9626 e->nss >= RTW89_NSS_NUM ||
9627 e->ofdma >= RTW89_OFDMA_NUM)
9628 return false;
9629 break;
9630 case RTW89_RS_HEDCM:
9631 if (e->shf + e->len > RTW89_RATE_HEDCM_NUM ||
9632 e->nss >= RTW89_NSS_HEDCM_NUM ||
9633 e->ofdma >= RTW89_OFDMA_NUM)
9634 return false;
9635 break;
9636 case RTW89_RS_OFFSET:
9637 if (e->shf + e->len > __RTW89_RATE_OFFSET_NUM)
9638 return false;
9639 break;
9640 default:
9641 return false;
9642 }
9643
9644 return true;
9645 }
9646
9647 static
9648 void rtw89_fw_load_txpwr_byrate(struct rtw89_dev *rtwdev,
9649 const struct rtw89_txpwr_table *tbl)
9650 {
9651 const struct rtw89_txpwr_conf *conf = tbl->data;
9652 struct rtw89_fw_txpwr_byrate_entry entry = {};
9653 struct rtw89_txpwr_byrate *byr_head;
9654 struct rtw89_rate_desc desc = {};
9655 #if defined(__linux__)
9656 const void *cursor;
9657 #elif defined(__FreeBSD__)
9658 const u8 *cursor;
9659 #endif
9660 u32 data;
9661 s8 *byr;
9662 int i;
9663
9664 rtw89_for_each_in_txpwr_conf(entry, cursor, conf) {
9665 if (!fw_txpwr_byrate_entry_valid(&entry, cursor, conf))
9666 continue;
9667
9668 byr_head = &rtwdev->byr[entry.band][entry.bw];
9669 data = le32_to_cpu(entry.data);
9670 desc.ofdma = entry.ofdma;
9671 desc.nss = entry.nss;
9672 desc.rs = entry.rs;
9673
9674 for (i = 0; i < entry.len; i++, data >>= 8) {
9675 desc.idx = entry.shf + i;
9676 byr = rtw89_phy_raw_byr_seek(rtwdev, byr_head, &desc);
9677 *byr = data & 0xff;
9678 }
9679 }
9680 }
9681
9682 static bool
9683 fw_txpwr_lmt_2ghz_entry_valid(const struct rtw89_fw_txpwr_lmt_2ghz_entry *e,
9684 const void *cursor,
9685 const struct rtw89_txpwr_conf *conf)
9686 {
9687 if (!__fw_txpwr_entry_acceptable(e, cursor, conf->ent_sz))
9688 return false;
9689
9690 if (e->bw >= RTW89_2G_BW_NUM)
9691 return false;
9692 if (e->nt >= RTW89_NTX_NUM)
9693 return false;
9694 if (e->rs >= RTW89_RS_LMT_NUM)
9695 return false;
9696 if (e->bf >= RTW89_BF_NUM)
9697 return false;
9698 if (e->regd >= RTW89_REGD_NUM)
9699 return false;
9700 if (e->ch_idx >= RTW89_2G_CH_NUM)
9701 return false;
9702
9703 return true;
9704 }
9705
9706 static
9707 void rtw89_fw_load_txpwr_lmt_2ghz(struct rtw89_txpwr_lmt_2ghz_data *data)
9708 {
9709 const struct rtw89_txpwr_conf *conf = &data->conf;
9710 struct rtw89_fw_txpwr_lmt_2ghz_entry entry = {};
9711 #if defined(__linux__)
9712 const void *cursor;
9713 #elif defined(__FreeBSD__)
9714 const u8 *cursor;
9715 #endif
9716
9717 rtw89_for_each_in_txpwr_conf(entry, cursor, conf) {
9718 if (!fw_txpwr_lmt_2ghz_entry_valid(&entry, cursor, conf))
9719 continue;
9720
9721 data->v[entry.bw][entry.nt][entry.rs][entry.bf][entry.regd]
9722 [entry.ch_idx] = entry.v;
9723 }
9724 }
9725
9726 static bool
9727 fw_txpwr_lmt_5ghz_entry_valid(const struct rtw89_fw_txpwr_lmt_5ghz_entry *e,
9728 const void *cursor,
9729 const struct rtw89_txpwr_conf *conf)
9730 {
9731 if (!__fw_txpwr_entry_acceptable(e, cursor, conf->ent_sz))
9732 return false;
9733
9734 if (e->bw >= RTW89_5G_BW_NUM)
9735 return false;
9736 if (e->nt >= RTW89_NTX_NUM)
9737 return false;
9738 if (e->rs >= RTW89_RS_LMT_NUM)
9739 return false;
9740 if (e->bf >= RTW89_BF_NUM)
9741 return false;
9742 if (e->regd >= RTW89_REGD_NUM)
9743 return false;
9744 if (e->ch_idx >= RTW89_5G_CH_NUM)
9745 return false;
9746
9747 return true;
9748 }
9749
9750 static
9751 void rtw89_fw_load_txpwr_lmt_5ghz(struct rtw89_txpwr_lmt_5ghz_data *data)
9752 {
9753 const struct rtw89_txpwr_conf *conf = &data->conf;
9754 struct rtw89_fw_txpwr_lmt_5ghz_entry entry = {};
9755 #if defined(__linux__)
9756 const void *cursor;
9757 #elif defined(__FreeBSD__)
9758 const u8 *cursor;
9759 #endif
9760
9761 rtw89_for_each_in_txpwr_conf(entry, cursor, conf) {
9762 if (!fw_txpwr_lmt_5ghz_entry_valid(&entry, cursor, conf))
9763 continue;
9764
9765 data->v[entry.bw][entry.nt][entry.rs][entry.bf][entry.regd]
9766 [entry.ch_idx] = entry.v;
9767 }
9768 }
9769
9770 static bool
9771 fw_txpwr_lmt_6ghz_entry_valid(const struct rtw89_fw_txpwr_lmt_6ghz_entry *e,
9772 const void *cursor,
9773 const struct rtw89_txpwr_conf *conf)
9774 {
9775 if (!__fw_txpwr_entry_acceptable(e, cursor, conf->ent_sz))
9776 return false;
9777
9778 if (e->bw >= RTW89_6G_BW_NUM)
9779 return false;
9780 if (e->nt >= RTW89_NTX_NUM)
9781 return false;
9782 if (e->rs >= RTW89_RS_LMT_NUM)
9783 return false;
9784 if (e->bf >= RTW89_BF_NUM)
9785 return false;
9786 if (e->regd >= RTW89_REGD_NUM)
9787 return false;
9788 if (e->reg_6ghz_power >= NUM_OF_RTW89_REG_6GHZ_POWER)
9789 return false;
9790 if (e->ch_idx >= RTW89_6G_CH_NUM)
9791 return false;
9792
9793 return true;
9794 }
9795
9796 static
9797 void rtw89_fw_load_txpwr_lmt_6ghz(struct rtw89_txpwr_lmt_6ghz_data *data)
9798 {
9799 const struct rtw89_txpwr_conf *conf = &data->conf;
9800 struct rtw89_fw_txpwr_lmt_6ghz_entry entry = {};
9801 #if defined(__linux__)
9802 const void *cursor;
9803 #elif defined(__FreeBSD__)
9804 const u8 *cursor;
9805 #endif
9806
9807 rtw89_for_each_in_txpwr_conf(entry, cursor, conf) {
9808 if (!fw_txpwr_lmt_6ghz_entry_valid(&entry, cursor, conf))
9809 continue;
9810
9811 data->v[entry.bw][entry.nt][entry.rs][entry.bf][entry.regd]
9812 [entry.reg_6ghz_power][entry.ch_idx] = entry.v;
9813 }
9814 }
9815
9816 static bool
9817 fw_txpwr_lmt_ru_2ghz_entry_valid(const struct rtw89_fw_txpwr_lmt_ru_2ghz_entry *e,
9818 const void *cursor,
9819 const struct rtw89_txpwr_conf *conf)
9820 {
9821 if (!__fw_txpwr_entry_acceptable(e, cursor, conf->ent_sz))
9822 return false;
9823
9824 if (e->ru >= RTW89_RU_NUM)
9825 return false;
9826 if (e->nt >= RTW89_NTX_NUM)
9827 return false;
9828 if (e->regd >= RTW89_REGD_NUM)
9829 return false;
9830 if (e->ch_idx >= RTW89_2G_CH_NUM)
9831 return false;
9832
9833 return true;
9834 }
9835
9836 static
9837 void rtw89_fw_load_txpwr_lmt_ru_2ghz(struct rtw89_txpwr_lmt_ru_2ghz_data *data)
9838 {
9839 const struct rtw89_txpwr_conf *conf = &data->conf;
9840 struct rtw89_fw_txpwr_lmt_ru_2ghz_entry entry = {};
9841 #if defined(__linux__)
9842 const void *cursor;
9843 #elif defined(__FreeBSD__)
9844 const u8 *cursor;
9845 #endif
9846
9847 rtw89_for_each_in_txpwr_conf(entry, cursor, conf) {
9848 if (!fw_txpwr_lmt_ru_2ghz_entry_valid(&entry, cursor, conf))
9849 continue;
9850
9851 data->v[entry.ru][entry.nt][entry.regd][entry.ch_idx] = entry.v;
9852 }
9853 }
9854
9855 static bool
9856 fw_txpwr_lmt_ru_5ghz_entry_valid(const struct rtw89_fw_txpwr_lmt_ru_5ghz_entry *e,
9857 const void *cursor,
9858 const struct rtw89_txpwr_conf *conf)
9859 {
9860 if (!__fw_txpwr_entry_acceptable(e, cursor, conf->ent_sz))
9861 return false;
9862
9863 if (e->ru >= RTW89_RU_NUM)
9864 return false;
9865 if (e->nt >= RTW89_NTX_NUM)
9866 return false;
9867 if (e->regd >= RTW89_REGD_NUM)
9868 return false;
9869 if (e->ch_idx >= RTW89_5G_CH_NUM)
9870 return false;
9871
9872 return true;
9873 }
9874
9875 static
9876 void rtw89_fw_load_txpwr_lmt_ru_5ghz(struct rtw89_txpwr_lmt_ru_5ghz_data *data)
9877 {
9878 const struct rtw89_txpwr_conf *conf = &data->conf;
9879 struct rtw89_fw_txpwr_lmt_ru_5ghz_entry entry = {};
9880 #if defined(__linux__)
9881 const void *cursor;
9882 #elif defined(__FreeBSD__)
9883 const u8 *cursor;
9884 #endif
9885
9886 rtw89_for_each_in_txpwr_conf(entry, cursor, conf) {
9887 if (!fw_txpwr_lmt_ru_5ghz_entry_valid(&entry, cursor, conf))
9888 continue;
9889
9890 data->v[entry.ru][entry.nt][entry.regd][entry.ch_idx] = entry.v;
9891 }
9892 }
9893
9894 static bool
9895 fw_txpwr_lmt_ru_6ghz_entry_valid(const struct rtw89_fw_txpwr_lmt_ru_6ghz_entry *e,
9896 const void *cursor,
9897 const struct rtw89_txpwr_conf *conf)
9898 {
9899 if (!__fw_txpwr_entry_acceptable(e, cursor, conf->ent_sz))
9900 return false;
9901
9902 if (e->ru >= RTW89_RU_NUM)
9903 return false;
9904 if (e->nt >= RTW89_NTX_NUM)
9905 return false;
9906 if (e->regd >= RTW89_REGD_NUM)
9907 return false;
9908 if (e->reg_6ghz_power >= NUM_OF_RTW89_REG_6GHZ_POWER)
9909 return false;
9910 if (e->ch_idx >= RTW89_6G_CH_NUM)
9911 return false;
9912
9913 return true;
9914 }
9915
9916 static
9917 void rtw89_fw_load_txpwr_lmt_ru_6ghz(struct rtw89_txpwr_lmt_ru_6ghz_data *data)
9918 {
9919 const struct rtw89_txpwr_conf *conf = &data->conf;
9920 struct rtw89_fw_txpwr_lmt_ru_6ghz_entry entry = {};
9921 #if defined(__linux__)
9922 const void *cursor;
9923 #elif defined(__FreeBSD__)
9924 const u8 *cursor;
9925 #endif
9926
9927 rtw89_for_each_in_txpwr_conf(entry, cursor, conf) {
9928 if (!fw_txpwr_lmt_ru_6ghz_entry_valid(&entry, cursor, conf))
9929 continue;
9930
9931 data->v[entry.ru][entry.nt][entry.regd][entry.reg_6ghz_power]
9932 [entry.ch_idx] = entry.v;
9933 }
9934 }
9935
9936 static bool
9937 fw_tx_shape_lmt_entry_valid(const struct rtw89_fw_tx_shape_lmt_entry *e,
9938 const void *cursor,
9939 const struct rtw89_txpwr_conf *conf)
9940 {
9941 if (!__fw_txpwr_entry_acceptable(e, cursor, conf->ent_sz))
9942 return false;
9943
9944 if (e->band >= RTW89_BAND_NUM)
9945 return false;
9946 if (e->tx_shape_rs >= RTW89_RS_TX_SHAPE_NUM)
9947 return false;
9948 if (e->regd >= RTW89_REGD_NUM)
9949 return false;
9950
9951 return true;
9952 }
9953
9954 static
9955 void rtw89_fw_load_tx_shape_lmt(struct rtw89_tx_shape_lmt_data *data)
9956 {
9957 const struct rtw89_txpwr_conf *conf = &data->conf;
9958 struct rtw89_fw_tx_shape_lmt_entry entry = {};
9959 #if defined(__linux__)
9960 const void *cursor;
9961 #elif defined(__FreeBSD__)
9962 const u8 *cursor;
9963 #endif
9964
9965 rtw89_for_each_in_txpwr_conf(entry, cursor, conf) {
9966 if (!fw_tx_shape_lmt_entry_valid(&entry, cursor, conf))
9967 continue;
9968
9969 data->v[entry.band][entry.tx_shape_rs][entry.regd] = entry.v;
9970 }
9971 }
9972
9973 static bool
9974 fw_tx_shape_lmt_ru_entry_valid(const struct rtw89_fw_tx_shape_lmt_ru_entry *e,
9975 const void *cursor,
9976 const struct rtw89_txpwr_conf *conf)
9977 {
9978 if (!__fw_txpwr_entry_acceptable(e, cursor, conf->ent_sz))
9979 return false;
9980
9981 if (e->band >= RTW89_BAND_NUM)
9982 return false;
9983 if (e->regd >= RTW89_REGD_NUM)
9984 return false;
9985
9986 return true;
9987 }
9988
9989 static
9990 void rtw89_fw_load_tx_shape_lmt_ru(struct rtw89_tx_shape_lmt_ru_data *data)
9991 {
9992 const struct rtw89_txpwr_conf *conf = &data->conf;
9993 struct rtw89_fw_tx_shape_lmt_ru_entry entry = {};
9994 #if defined(__linux__)
9995 const void *cursor;
9996 #elif defined(__FreeBSD__)
9997 const u8 *cursor;
9998 #endif
9999
10000 rtw89_for_each_in_txpwr_conf(entry, cursor, conf) {
10001 if (!fw_tx_shape_lmt_ru_entry_valid(&entry, cursor, conf))
10002 continue;
10003
10004 data->v[entry.band][entry.regd] = entry.v;
10005 }
10006 }
10007
10008 static bool rtw89_fw_has_da_txpwr_table(struct rtw89_dev *rtwdev,
10009 const struct rtw89_rfe_parms *parms)
10010 {
10011 const struct rtw89_chip_info *chip = rtwdev->chip;
10012
10013 if (chip->support_bands & BIT(NL80211_BAND_2GHZ) &&
10014 !(parms->rule_da_2ghz.lmt && parms->rule_da_2ghz.lmt_ru))
10015 return false;
10016
10017 if (chip->support_bands & BIT(NL80211_BAND_5GHZ) &&
10018 !(parms->rule_da_5ghz.lmt && parms->rule_da_5ghz.lmt_ru))
10019 return false;
10020
10021 if (chip->support_bands & BIT(NL80211_BAND_6GHZ) &&
10022 !(parms->rule_da_6ghz.lmt && parms->rule_da_6ghz.lmt_ru))
10023 return false;
10024
10025 return true;
10026 }
10027
10028 const struct rtw89_rfe_parms *
10029 rtw89_load_rfe_data_from_fw(struct rtw89_dev *rtwdev,
10030 const struct rtw89_rfe_parms *init)
10031 {
10032 struct rtw89_rfe_data *rfe_data = rtwdev->rfe_data;
10033 struct rtw89_rfe_parms *parms;
10034
10035 if (!rfe_data)
10036 return init;
10037
10038 parms = &rfe_data->rfe_parms;
10039 if (init)
10040 *parms = *init;
10041
10042 if (rtw89_txpwr_conf_valid(&rfe_data->byrate.conf)) {
10043 rfe_data->byrate.tbl.data = &rfe_data->byrate.conf;
10044 rfe_data->byrate.tbl.size = 0; /* don't care here */
10045 rfe_data->byrate.tbl.load = rtw89_fw_load_txpwr_byrate;
10046 parms->byr_tbl = &rfe_data->byrate.tbl;
10047 }
10048
10049 if (rtw89_txpwr_conf_valid(&rfe_data->lmt_2ghz.conf)) {
10050 rtw89_fw_load_txpwr_lmt_2ghz(&rfe_data->lmt_2ghz);
10051 parms->rule_2ghz.lmt = &rfe_data->lmt_2ghz.v;
10052 }
10053
10054 if (rtw89_txpwr_conf_valid(&rfe_data->lmt_5ghz.conf)) {
10055 rtw89_fw_load_txpwr_lmt_5ghz(&rfe_data->lmt_5ghz);
10056 parms->rule_5ghz.lmt = &rfe_data->lmt_5ghz.v;
10057 }
10058
10059 if (rtw89_txpwr_conf_valid(&rfe_data->lmt_6ghz.conf)) {
10060 rtw89_fw_load_txpwr_lmt_6ghz(&rfe_data->lmt_6ghz);
10061 parms->rule_6ghz.lmt = &rfe_data->lmt_6ghz.v;
10062 }
10063
10064 if (rtw89_txpwr_conf_valid(&rfe_data->da_lmt_2ghz.conf)) {
10065 rtw89_fw_load_txpwr_lmt_2ghz(&rfe_data->da_lmt_2ghz);
10066 parms->rule_da_2ghz.lmt = &rfe_data->da_lmt_2ghz.v;
10067 }
10068
10069 if (rtw89_txpwr_conf_valid(&rfe_data->da_lmt_5ghz.conf)) {
10070 rtw89_fw_load_txpwr_lmt_5ghz(&rfe_data->da_lmt_5ghz);
10071 parms->rule_da_5ghz.lmt = &rfe_data->da_lmt_5ghz.v;
10072 }
10073
10074 if (rtw89_txpwr_conf_valid(&rfe_data->da_lmt_6ghz.conf)) {
10075 rtw89_fw_load_txpwr_lmt_6ghz(&rfe_data->da_lmt_6ghz);
10076 parms->rule_da_6ghz.lmt = &rfe_data->da_lmt_6ghz.v;
10077 }
10078
10079 if (rtw89_txpwr_conf_valid(&rfe_data->lmt_ru_2ghz.conf)) {
10080 rtw89_fw_load_txpwr_lmt_ru_2ghz(&rfe_data->lmt_ru_2ghz);
10081 parms->rule_2ghz.lmt_ru = &rfe_data->lmt_ru_2ghz.v;
10082 }
10083
10084 if (rtw89_txpwr_conf_valid(&rfe_data->lmt_ru_5ghz.conf)) {
10085 rtw89_fw_load_txpwr_lmt_ru_5ghz(&rfe_data->lmt_ru_5ghz);
10086 parms->rule_5ghz.lmt_ru = &rfe_data->lmt_ru_5ghz.v;
10087 }
10088
10089 if (rtw89_txpwr_conf_valid(&rfe_data->lmt_ru_6ghz.conf)) {
10090 rtw89_fw_load_txpwr_lmt_ru_6ghz(&rfe_data->lmt_ru_6ghz);
10091 parms->rule_6ghz.lmt_ru = &rfe_data->lmt_ru_6ghz.v;
10092 }
10093
10094 if (rtw89_txpwr_conf_valid(&rfe_data->da_lmt_ru_2ghz.conf)) {
10095 rtw89_fw_load_txpwr_lmt_ru_2ghz(&rfe_data->da_lmt_ru_2ghz);
10096 parms->rule_da_2ghz.lmt_ru = &rfe_data->da_lmt_ru_2ghz.v;
10097 }
10098
10099 if (rtw89_txpwr_conf_valid(&rfe_data->da_lmt_ru_5ghz.conf)) {
10100 rtw89_fw_load_txpwr_lmt_ru_5ghz(&rfe_data->da_lmt_ru_5ghz);
10101 parms->rule_da_5ghz.lmt_ru = &rfe_data->da_lmt_ru_5ghz.v;
10102 }
10103
10104 if (rtw89_txpwr_conf_valid(&rfe_data->da_lmt_ru_6ghz.conf)) {
10105 rtw89_fw_load_txpwr_lmt_ru_6ghz(&rfe_data->da_lmt_ru_6ghz);
10106 parms->rule_da_6ghz.lmt_ru = &rfe_data->da_lmt_ru_6ghz.v;
10107 }
10108
10109 if (rtw89_txpwr_conf_valid(&rfe_data->tx_shape_lmt.conf)) {
10110 rtw89_fw_load_tx_shape_lmt(&rfe_data->tx_shape_lmt);
10111 parms->tx_shape.lmt = &rfe_data->tx_shape_lmt.v;
10112 }
10113
10114 if (rtw89_txpwr_conf_valid(&rfe_data->tx_shape_lmt_ru.conf)) {
10115 rtw89_fw_load_tx_shape_lmt_ru(&rfe_data->tx_shape_lmt_ru);
10116 parms->tx_shape.lmt_ru = &rfe_data->tx_shape_lmt_ru.v;
10117 }
10118
10119 parms->has_da = rtw89_fw_has_da_txpwr_table(rtwdev, parms);
10120
10121 return parms;
10122 }
10123