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