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