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