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
17 struct rtw89_eapol_2_of_2 {
18 struct ieee80211_hdr_3addr hdr;
19 u8 gtkbody[14];
20 u8 key_des_ver;
21 u8 rsvd[92];
22 } __packed __aligned(2);
23
24 struct rtw89_sa_query {
25 struct ieee80211_hdr_3addr hdr;
26 u8 category;
27 u8 action;
28 } __packed __aligned(2);
29
30 struct rtw89_arp_rsp {
31 struct ieee80211_hdr_3addr addr;
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 __aligned(2);
40
41 static const u8 mss_signature[] = {0x4D, 0x53, 0x53, 0x4B, 0x50, 0x4F, 0x4F, 0x4C};
42
43 union rtw89_fw_element_arg {
44 size_t offset;
45 enum rtw89_rf_path rf_path;
46 enum rtw89_fw_type fw_type;
47 };
48
49 struct rtw89_fw_element_handler {
50 int (*fn)(struct rtw89_dev *rtwdev,
51 const struct rtw89_fw_element_hdr *elm,
52 const union rtw89_fw_element_arg arg);
53 const union rtw89_fw_element_arg arg;
54 const char *name;
55 };
56
57 static void rtw89_fw_c2h_cmd_handle(struct rtw89_dev *rtwdev,
58 struct sk_buff *skb);
59 static int rtw89_h2c_tx_and_wait(struct rtw89_dev *rtwdev, struct sk_buff *skb,
60 struct rtw89_wait_info *wait, unsigned int cond);
61
rtw89_fw_h2c_alloc_skb(struct rtw89_dev * rtwdev,u32 len,bool header)62 static struct sk_buff *rtw89_fw_h2c_alloc_skb(struct rtw89_dev *rtwdev, u32 len,
63 bool header)
64 {
65 struct sk_buff *skb;
66 u32 header_len = 0;
67 u32 h2c_desc_size = rtwdev->chip->h2c_desc_size;
68
69 if (header)
70 header_len = H2C_HEADER_LEN;
71
72 skb = dev_alloc_skb(len + header_len + h2c_desc_size);
73 if (!skb)
74 return NULL;
75 skb_reserve(skb, header_len + h2c_desc_size);
76 memset(skb->data, 0, len);
77
78 return skb;
79 }
80
rtw89_fw_h2c_alloc_skb_with_hdr(struct rtw89_dev * rtwdev,u32 len)81 struct sk_buff *rtw89_fw_h2c_alloc_skb_with_hdr(struct rtw89_dev *rtwdev, u32 len)
82 {
83 return rtw89_fw_h2c_alloc_skb(rtwdev, len, true);
84 }
85
rtw89_fw_h2c_alloc_skb_no_hdr(struct rtw89_dev * rtwdev,u32 len)86 struct sk_buff *rtw89_fw_h2c_alloc_skb_no_hdr(struct rtw89_dev *rtwdev, u32 len)
87 {
88 return rtw89_fw_h2c_alloc_skb(rtwdev, len, false);
89 }
90
rtw89_fw_check_rdy(struct rtw89_dev * rtwdev,enum rtw89_fwdl_check_type type)91 int rtw89_fw_check_rdy(struct rtw89_dev *rtwdev, enum rtw89_fwdl_check_type type)
92 {
93 const struct rtw89_mac_gen_def *mac = rtwdev->chip->mac_def;
94 u8 val;
95 int ret;
96
97 ret = read_poll_timeout_atomic(mac->fwdl_get_status, val,
98 val == RTW89_FWDL_WCPU_FW_INIT_RDY,
99 1, FWDL_WAIT_CNT, false, rtwdev, type);
100 if (ret) {
101 switch (val) {
102 case RTW89_FWDL_CHECKSUM_FAIL:
103 rtw89_err(rtwdev, "fw checksum fail\n");
104 return -EINVAL;
105
106 case RTW89_FWDL_SECURITY_FAIL:
107 rtw89_err(rtwdev, "fw security fail\n");
108 return -EINVAL;
109
110 case RTW89_FWDL_CV_NOT_MATCH:
111 rtw89_err(rtwdev, "fw cv not match\n");
112 return -EINVAL;
113
114 default:
115 rtw89_err(rtwdev, "fw unexpected status %d\n", val);
116 return -EBUSY;
117 }
118 }
119
120 set_bit(RTW89_FLAG_FW_RDY, rtwdev->flags);
121
122 return 0;
123 }
124
rtw89_fw_hdr_parser_v0(struct rtw89_dev * rtwdev,const u8 * fw,u32 len,struct rtw89_fw_bin_info * info)125 static int rtw89_fw_hdr_parser_v0(struct rtw89_dev *rtwdev, const u8 *fw, u32 len,
126 struct rtw89_fw_bin_info *info)
127 {
128 const struct rtw89_fw_hdr *fw_hdr = (const struct rtw89_fw_hdr *)fw;
129 struct rtw89_fw_hdr_section_info *section_info;
130 const struct rtw89_fw_dynhdr_hdr *fwdynhdr;
131 const struct rtw89_fw_hdr_section *section;
132 const u8 *fw_end = fw + len;
133 const u8 *bin;
134 u32 base_hdr_len;
135 u32 mssc_len = 0;
136 u32 i;
137
138 if (!info)
139 return -EINVAL;
140
141 info->section_num = le32_get_bits(fw_hdr->w6, FW_HDR_W6_SEC_NUM);
142 base_hdr_len = struct_size(fw_hdr, sections, info->section_num);
143 info->dynamic_hdr_en = le32_get_bits(fw_hdr->w7, FW_HDR_W7_DYN_HDR);
144
145 if (info->dynamic_hdr_en) {
146 info->hdr_len = le32_get_bits(fw_hdr->w3, FW_HDR_W3_LEN);
147 info->dynamic_hdr_len = info->hdr_len - base_hdr_len;
148 fwdynhdr = (const struct rtw89_fw_dynhdr_hdr *)(fw + base_hdr_len);
149 if (le32_to_cpu(fwdynhdr->hdr_len) != info->dynamic_hdr_len) {
150 rtw89_err(rtwdev, "[ERR]invalid fw dynamic header len\n");
151 return -EINVAL;
152 }
153 } else {
154 info->hdr_len = base_hdr_len;
155 info->dynamic_hdr_len = 0;
156 }
157
158 bin = fw + info->hdr_len;
159
160 /* jump to section header */
161 section_info = info->section_info;
162 for (i = 0; i < info->section_num; i++) {
163 section = &fw_hdr->sections[i];
164 section_info->type =
165 le32_get_bits(section->w1, FWSECTION_HDR_W1_SECTIONTYPE);
166 if (section_info->type == FWDL_SECURITY_SECTION_TYPE) {
167 section_info->mssc =
168 le32_get_bits(section->w2, FWSECTION_HDR_W2_MSSC);
169 mssc_len += section_info->mssc * FWDL_SECURITY_SIGLEN;
170 } else {
171 section_info->mssc = 0;
172 }
173
174 section_info->len = le32_get_bits(section->w1, FWSECTION_HDR_W1_SEC_SIZE);
175 if (le32_get_bits(section->w1, FWSECTION_HDR_W1_CHECKSUM))
176 section_info->len += FWDL_SECTION_CHKSUM_LEN;
177 section_info->redl = le32_get_bits(section->w1, FWSECTION_HDR_W1_REDL);
178 section_info->dladdr =
179 le32_get_bits(section->w0, FWSECTION_HDR_W0_DL_ADDR) & 0x1fffffff;
180 section_info->addr = bin;
181 bin += section_info->len;
182 section_info++;
183 }
184
185 if (fw_end != bin + mssc_len) {
186 rtw89_err(rtwdev, "[ERR]fw bin size\n");
187 return -EINVAL;
188 }
189
190 return 0;
191 }
192
__get_mssc_key_idx(struct rtw89_dev * rtwdev,const struct rtw89_fw_mss_pool_hdr * mss_hdr,u32 rmp_tbl_size,u32 * key_idx)193 static int __get_mssc_key_idx(struct rtw89_dev *rtwdev,
194 const struct rtw89_fw_mss_pool_hdr *mss_hdr,
195 u32 rmp_tbl_size, u32 *key_idx)
196 {
197 struct rtw89_fw_secure *sec = &rtwdev->fw.sec;
198 u32 sel_byte_idx;
199 u32 mss_sel_idx;
200 u8 sel_bit_idx;
201 int i;
202
203 if (sec->mss_dev_type == RTW89_FW_MSS_DEV_TYPE_FWSEC_DEF) {
204 if (!mss_hdr->defen)
205 return -ENOENT;
206
207 mss_sel_idx = sec->mss_cust_idx * le16_to_cpu(mss_hdr->msskey_num_max) +
208 sec->mss_key_num;
209 } else {
210 if (mss_hdr->defen)
211 mss_sel_idx = FWDL_MSS_POOL_DEFKEYSETS_SIZE << 3;
212 else
213 mss_sel_idx = 0;
214 mss_sel_idx += sec->mss_dev_type * le16_to_cpu(mss_hdr->msskey_num_max) *
215 le16_to_cpu(mss_hdr->msscust_max) +
216 sec->mss_cust_idx * le16_to_cpu(mss_hdr->msskey_num_max) +
217 sec->mss_key_num;
218 }
219
220 sel_byte_idx = mss_sel_idx >> 3;
221 sel_bit_idx = mss_sel_idx & 0x7;
222
223 if (sel_byte_idx >= rmp_tbl_size)
224 return -EFAULT;
225
226 if (!(mss_hdr->rmp_tbl[sel_byte_idx] & BIT(sel_bit_idx)))
227 return -ENOENT;
228
229 *key_idx = hweight8(mss_hdr->rmp_tbl[sel_byte_idx] & (BIT(sel_bit_idx) - 1));
230
231 for (i = 0; i < sel_byte_idx; i++)
232 *key_idx += hweight8(mss_hdr->rmp_tbl[i]);
233
234 return 0;
235 }
236
__parse_formatted_mssc(struct rtw89_dev * rtwdev,struct rtw89_fw_bin_info * info,struct rtw89_fw_hdr_section_info * section_info,const struct rtw89_fw_hdr_section_v1 * section,const void * content,u32 * mssc_len)237 static int __parse_formatted_mssc(struct rtw89_dev *rtwdev,
238 struct rtw89_fw_bin_info *info,
239 struct rtw89_fw_hdr_section_info *section_info,
240 const struct rtw89_fw_hdr_section_v1 *section,
241 const void *content,
242 u32 *mssc_len)
243 {
244 const struct rtw89_fw_mss_pool_hdr *mss_hdr = content + section_info->len;
245 const union rtw89_fw_section_mssc_content *section_content = content;
246 struct rtw89_fw_secure *sec = &rtwdev->fw.sec;
247 u32 rmp_tbl_size;
248 u32 key_sign_len;
249 u32 real_key_idx;
250 u32 sb_sel_ver;
251 int ret;
252
253 if (memcmp(mss_signature, mss_hdr->signature, sizeof(mss_signature)) != 0) {
254 rtw89_err(rtwdev, "[ERR] wrong MSS signature\n");
255 return -ENOENT;
256 }
257
258 if (mss_hdr->rmpfmt == MSS_POOL_RMP_TBL_BITMASK) {
259 rmp_tbl_size = (le16_to_cpu(mss_hdr->msskey_num_max) *
260 le16_to_cpu(mss_hdr->msscust_max) *
261 mss_hdr->mssdev_max) >> 3;
262 if (mss_hdr->defen)
263 rmp_tbl_size += FWDL_MSS_POOL_DEFKEYSETS_SIZE;
264 } else {
265 rtw89_err(rtwdev, "[ERR] MSS Key Pool Remap Table Format Unsupport:%X\n",
266 mss_hdr->rmpfmt);
267 return -EINVAL;
268 }
269
270 if (rmp_tbl_size + sizeof(*mss_hdr) != le32_to_cpu(mss_hdr->key_raw_offset)) {
271 rtw89_err(rtwdev, "[ERR] MSS Key Pool Format Error:0x%X + 0x%X != 0x%X\n",
272 rmp_tbl_size, (int)sizeof(*mss_hdr),
273 le32_to_cpu(mss_hdr->key_raw_offset));
274 return -EINVAL;
275 }
276
277 key_sign_len = le16_to_cpu(section_content->key_sign_len.v) >> 2;
278 if (!key_sign_len)
279 key_sign_len = 512;
280
281 if (info->dsp_checksum)
282 key_sign_len += FWDL_SECURITY_CHKSUM_LEN;
283
284 *mssc_len = sizeof(*mss_hdr) + rmp_tbl_size +
285 le16_to_cpu(mss_hdr->keypair_num) * key_sign_len;
286
287 if (!sec->secure_boot)
288 goto out;
289
290 sb_sel_ver = le32_to_cpu(section_content->sb_sel_ver.v);
291 if (sb_sel_ver && sb_sel_ver != sec->sb_sel_mgn)
292 goto ignore;
293
294 ret = __get_mssc_key_idx(rtwdev, mss_hdr, rmp_tbl_size, &real_key_idx);
295 if (ret)
296 goto ignore;
297
298 section_info->key_addr = content + section_info->len +
299 le32_to_cpu(mss_hdr->key_raw_offset) +
300 key_sign_len * real_key_idx;
301 section_info->key_len = key_sign_len;
302 section_info->key_idx = real_key_idx;
303
304 out:
305 if (info->secure_section_exist) {
306 section_info->ignore = true;
307 return 0;
308 }
309
310 info->secure_section_exist = true;
311
312 return 0;
313
314 ignore:
315 section_info->ignore = true;
316
317 return 0;
318 }
319
__parse_security_section(struct rtw89_dev * rtwdev,struct rtw89_fw_bin_info * info,struct rtw89_fw_hdr_section_info * section_info,const struct rtw89_fw_hdr_section_v1 * section,const void * content,u32 * mssc_len)320 static int __parse_security_section(struct rtw89_dev *rtwdev,
321 struct rtw89_fw_bin_info *info,
322 struct rtw89_fw_hdr_section_info *section_info,
323 const struct rtw89_fw_hdr_section_v1 *section,
324 const void *content,
325 u32 *mssc_len)
326 {
327 int ret;
328
329 section_info->mssc =
330 le32_get_bits(section->w2, FWSECTION_HDR_V1_W2_MSSC);
331
332 if (section_info->mssc == FORMATTED_MSSC) {
333 ret = __parse_formatted_mssc(rtwdev, info, section_info,
334 section, content, mssc_len);
335 if (ret)
336 return -EINVAL;
337 } else {
338 *mssc_len = section_info->mssc * FWDL_SECURITY_SIGLEN;
339 if (info->dsp_checksum)
340 *mssc_len += section_info->mssc * FWDL_SECURITY_CHKSUM_LEN;
341
342 info->secure_section_exist = true;
343 }
344
345 return 0;
346 }
347
rtw89_fw_hdr_parser_v1(struct rtw89_dev * rtwdev,const u8 * fw,u32 len,struct rtw89_fw_bin_info * info)348 static int rtw89_fw_hdr_parser_v1(struct rtw89_dev *rtwdev, const u8 *fw, u32 len,
349 struct rtw89_fw_bin_info *info)
350 {
351 const struct rtw89_fw_hdr_v1 *fw_hdr = (const struct rtw89_fw_hdr_v1 *)fw;
352 struct rtw89_fw_hdr_section_info *section_info;
353 const struct rtw89_fw_dynhdr_hdr *fwdynhdr;
354 const struct rtw89_fw_hdr_section_v1 *section;
355 const u8 *fw_end = fw + len;
356 const u8 *bin;
357 u32 base_hdr_len;
358 u32 mssc_len;
359 int ret;
360 u32 i;
361
362 info->section_num = le32_get_bits(fw_hdr->w6, FW_HDR_V1_W6_SEC_NUM);
363 info->dsp_checksum = le32_get_bits(fw_hdr->w6, FW_HDR_V1_W6_DSP_CHKSUM);
364 base_hdr_len = struct_size(fw_hdr, sections, info->section_num);
365 info->dynamic_hdr_en = le32_get_bits(fw_hdr->w7, FW_HDR_V1_W7_DYN_HDR);
366
367 if (info->dynamic_hdr_en) {
368 info->hdr_len = le32_get_bits(fw_hdr->w5, FW_HDR_V1_W5_HDR_SIZE);
369 info->dynamic_hdr_len = info->hdr_len - base_hdr_len;
370 fwdynhdr = (const struct rtw89_fw_dynhdr_hdr *)(fw + base_hdr_len);
371 if (le32_to_cpu(fwdynhdr->hdr_len) != info->dynamic_hdr_len) {
372 rtw89_err(rtwdev, "[ERR]invalid fw dynamic header len\n");
373 return -EINVAL;
374 }
375 } else {
376 info->hdr_len = base_hdr_len;
377 info->dynamic_hdr_len = 0;
378 }
379
380 bin = fw + info->hdr_len;
381
382 /* jump to section header */
383 section_info = info->section_info;
384 for (i = 0; i < info->section_num; i++) {
385 section = &fw_hdr->sections[i];
386
387 section_info->type =
388 le32_get_bits(section->w1, FWSECTION_HDR_V1_W1_SECTIONTYPE);
389 section_info->len =
390 le32_get_bits(section->w1, FWSECTION_HDR_V1_W1_SEC_SIZE);
391 if (le32_get_bits(section->w1, FWSECTION_HDR_V1_W1_CHECKSUM))
392 section_info->len += FWDL_SECTION_CHKSUM_LEN;
393 section_info->redl = le32_get_bits(section->w1, FWSECTION_HDR_V1_W1_REDL);
394 section_info->dladdr =
395 le32_get_bits(section->w0, FWSECTION_HDR_V1_W0_DL_ADDR);
396 section_info->addr = bin;
397
398 if (section_info->type == FWDL_SECURITY_SECTION_TYPE) {
399 ret = __parse_security_section(rtwdev, info, section_info,
400 section, bin, &mssc_len);
401 if (ret)
402 return ret;
403 } else {
404 section_info->mssc = 0;
405 mssc_len = 0;
406 }
407
408 rtw89_debug(rtwdev, RTW89_DBG_FW,
409 "section[%d] type=%d len=0x%-6x mssc=%d mssc_len=%d addr=%tx\n",
410 i, section_info->type, section_info->len,
411 section_info->mssc, mssc_len, bin - fw);
412 rtw89_debug(rtwdev, RTW89_DBG_FW,
413 " ignore=%d key_addr=%p (0x%tx) key_len=%d key_idx=%d\n",
414 section_info->ignore, section_info->key_addr,
415 section_info->key_addr ?
416 section_info->key_addr - section_info->addr : 0,
417 section_info->key_len, section_info->key_idx);
418
419 bin += section_info->len + mssc_len;
420 section_info++;
421 }
422
423 if (fw_end != bin) {
424 rtw89_err(rtwdev, "[ERR]fw bin size\n");
425 return -EINVAL;
426 }
427
428 if (!info->secure_section_exist)
429 rtw89_warn(rtwdev, "no firmware secure section\n");
430
431 return 0;
432 }
433
rtw89_fw_hdr_parser(struct rtw89_dev * rtwdev,const struct rtw89_fw_suit * fw_suit,struct rtw89_fw_bin_info * info)434 static int rtw89_fw_hdr_parser(struct rtw89_dev *rtwdev,
435 const struct rtw89_fw_suit *fw_suit,
436 struct rtw89_fw_bin_info *info)
437 {
438 const u8 *fw = fw_suit->data;
439 u32 len = fw_suit->size;
440
441 if (!fw || !len) {
442 rtw89_err(rtwdev, "fw type %d isn't recognized\n", fw_suit->type);
443 return -ENOENT;
444 }
445
446 switch (fw_suit->hdr_ver) {
447 case 0:
448 return rtw89_fw_hdr_parser_v0(rtwdev, fw, len, info);
449 case 1:
450 return rtw89_fw_hdr_parser_v1(rtwdev, fw, len, info);
451 default:
452 return -ENOENT;
453 }
454 }
455
456 static
rtw89_mfw_recognize(struct rtw89_dev * rtwdev,enum rtw89_fw_type type,struct rtw89_fw_suit * fw_suit,bool nowarn)457 int rtw89_mfw_recognize(struct rtw89_dev *rtwdev, enum rtw89_fw_type type,
458 struct rtw89_fw_suit *fw_suit, bool nowarn)
459 {
460 struct rtw89_fw_info *fw_info = &rtwdev->fw;
461 const struct firmware *firmware = fw_info->req.firmware;
462 const u8 *mfw = firmware->data;
463 u32 mfw_len = firmware->size;
464 const struct rtw89_mfw_hdr *mfw_hdr = (const struct rtw89_mfw_hdr *)mfw;
465 const struct rtw89_mfw_info *mfw_info;
466 int i;
467
468 if (mfw_hdr->sig != RTW89_MFW_SIG) {
469 rtw89_debug(rtwdev, RTW89_DBG_FW, "use legacy firmware\n");
470 /* legacy firmware support normal type only */
471 if (type != RTW89_FW_NORMAL)
472 return -EINVAL;
473 fw_suit->data = mfw;
474 fw_suit->size = mfw_len;
475 return 0;
476 }
477
478 for (i = 0; i < mfw_hdr->fw_nr; i++) {
479 mfw_info = &mfw_hdr->info[i];
480 if (mfw_info->type == type) {
481 if (mfw_info->cv == rtwdev->hal.cv && !mfw_info->mp)
482 goto found;
483 if (type == RTW89_FW_LOGFMT)
484 goto found;
485 }
486 }
487
488 if (!nowarn)
489 rtw89_err(rtwdev, "no suitable firmware found\n");
490 return -ENOENT;
491
492 found:
493 fw_suit->data = mfw + le32_to_cpu(mfw_info->shift);
494 fw_suit->size = le32_to_cpu(mfw_info->size);
495 return 0;
496 }
497
rtw89_mfw_get_size(struct rtw89_dev * rtwdev)498 static u32 rtw89_mfw_get_size(struct rtw89_dev *rtwdev)
499 {
500 struct rtw89_fw_info *fw_info = &rtwdev->fw;
501 const struct firmware *firmware = fw_info->req.firmware;
502 const struct rtw89_mfw_hdr *mfw_hdr =
503 (const struct rtw89_mfw_hdr *)firmware->data;
504 const struct rtw89_mfw_info *mfw_info;
505 u32 size;
506
507 if (mfw_hdr->sig != RTW89_MFW_SIG) {
508 rtw89_warn(rtwdev, "not mfw format\n");
509 return 0;
510 }
511
512 mfw_info = &mfw_hdr->info[mfw_hdr->fw_nr - 1];
513 size = le32_to_cpu(mfw_info->shift) + le32_to_cpu(mfw_info->size);
514
515 return size;
516 }
517
rtw89_fw_update_ver_v0(struct rtw89_dev * rtwdev,struct rtw89_fw_suit * fw_suit,const struct rtw89_fw_hdr * hdr)518 static void rtw89_fw_update_ver_v0(struct rtw89_dev *rtwdev,
519 struct rtw89_fw_suit *fw_suit,
520 const struct rtw89_fw_hdr *hdr)
521 {
522 fw_suit->major_ver = le32_get_bits(hdr->w1, FW_HDR_W1_MAJOR_VERSION);
523 fw_suit->minor_ver = le32_get_bits(hdr->w1, FW_HDR_W1_MINOR_VERSION);
524 fw_suit->sub_ver = le32_get_bits(hdr->w1, FW_HDR_W1_SUBVERSION);
525 fw_suit->sub_idex = le32_get_bits(hdr->w1, FW_HDR_W1_SUBINDEX);
526 fw_suit->commitid = le32_get_bits(hdr->w2, FW_HDR_W2_COMMITID);
527 fw_suit->build_year = le32_get_bits(hdr->w5, FW_HDR_W5_YEAR);
528 fw_suit->build_mon = le32_get_bits(hdr->w4, FW_HDR_W4_MONTH);
529 fw_suit->build_date = le32_get_bits(hdr->w4, FW_HDR_W4_DATE);
530 fw_suit->build_hour = le32_get_bits(hdr->w4, FW_HDR_W4_HOUR);
531 fw_suit->build_min = le32_get_bits(hdr->w4, FW_HDR_W4_MIN);
532 fw_suit->cmd_ver = le32_get_bits(hdr->w7, FW_HDR_W7_CMD_VERSERION);
533 }
534
rtw89_fw_update_ver_v1(struct rtw89_dev * rtwdev,struct rtw89_fw_suit * fw_suit,const struct rtw89_fw_hdr_v1 * hdr)535 static void rtw89_fw_update_ver_v1(struct rtw89_dev *rtwdev,
536 struct rtw89_fw_suit *fw_suit,
537 const struct rtw89_fw_hdr_v1 *hdr)
538 {
539 fw_suit->major_ver = le32_get_bits(hdr->w1, FW_HDR_V1_W1_MAJOR_VERSION);
540 fw_suit->minor_ver = le32_get_bits(hdr->w1, FW_HDR_V1_W1_MINOR_VERSION);
541 fw_suit->sub_ver = le32_get_bits(hdr->w1, FW_HDR_V1_W1_SUBVERSION);
542 fw_suit->sub_idex = le32_get_bits(hdr->w1, FW_HDR_V1_W1_SUBINDEX);
543 fw_suit->commitid = le32_get_bits(hdr->w2, FW_HDR_V1_W2_COMMITID);
544 fw_suit->build_year = le32_get_bits(hdr->w5, FW_HDR_V1_W5_YEAR);
545 fw_suit->build_mon = le32_get_bits(hdr->w4, FW_HDR_V1_W4_MONTH);
546 fw_suit->build_date = le32_get_bits(hdr->w4, FW_HDR_V1_W4_DATE);
547 fw_suit->build_hour = le32_get_bits(hdr->w4, FW_HDR_V1_W4_HOUR);
548 fw_suit->build_min = le32_get_bits(hdr->w4, FW_HDR_V1_W4_MIN);
549 fw_suit->cmd_ver = le32_get_bits(hdr->w7, FW_HDR_V1_W3_CMD_VERSERION);
550 }
551
rtw89_fw_update_ver(struct rtw89_dev * rtwdev,enum rtw89_fw_type type,struct rtw89_fw_suit * fw_suit)552 static int rtw89_fw_update_ver(struct rtw89_dev *rtwdev,
553 enum rtw89_fw_type type,
554 struct rtw89_fw_suit *fw_suit)
555 {
556 const struct rtw89_fw_hdr *v0 = (const struct rtw89_fw_hdr *)fw_suit->data;
557 const struct rtw89_fw_hdr_v1 *v1 = (const struct rtw89_fw_hdr_v1 *)fw_suit->data;
558
559 if (type == RTW89_FW_LOGFMT)
560 return 0;
561
562 fw_suit->type = type;
563 fw_suit->hdr_ver = le32_get_bits(v0->w3, FW_HDR_W3_HDR_VER);
564
565 switch (fw_suit->hdr_ver) {
566 case 0:
567 rtw89_fw_update_ver_v0(rtwdev, fw_suit, v0);
568 break;
569 case 1:
570 rtw89_fw_update_ver_v1(rtwdev, fw_suit, v1);
571 break;
572 default:
573 rtw89_err(rtwdev, "Unknown firmware header version %u\n",
574 fw_suit->hdr_ver);
575 return -ENOENT;
576 }
577
578 rtw89_info(rtwdev,
579 "Firmware version %u.%u.%u.%u (%08x), cmd version %u, type %u\n",
580 fw_suit->major_ver, fw_suit->minor_ver, fw_suit->sub_ver,
581 fw_suit->sub_idex, fw_suit->commitid, fw_suit->cmd_ver, type);
582
583 return 0;
584 }
585
586 static
__rtw89_fw_recognize(struct rtw89_dev * rtwdev,enum rtw89_fw_type type,bool nowarn)587 int __rtw89_fw_recognize(struct rtw89_dev *rtwdev, enum rtw89_fw_type type,
588 bool nowarn)
589 {
590 struct rtw89_fw_suit *fw_suit = rtw89_fw_suit_get(rtwdev, type);
591 int ret;
592
593 ret = rtw89_mfw_recognize(rtwdev, type, fw_suit, nowarn);
594 if (ret)
595 return ret;
596
597 return rtw89_fw_update_ver(rtwdev, type, fw_suit);
598 }
599
600 static
__rtw89_fw_recognize_from_elm(struct rtw89_dev * rtwdev,const struct rtw89_fw_element_hdr * elm,const union rtw89_fw_element_arg arg)601 int __rtw89_fw_recognize_from_elm(struct rtw89_dev *rtwdev,
602 const struct rtw89_fw_element_hdr *elm,
603 const union rtw89_fw_element_arg arg)
604 {
605 enum rtw89_fw_type type = arg.fw_type;
606 struct rtw89_hal *hal = &rtwdev->hal;
607 struct rtw89_fw_suit *fw_suit;
608
609 if (hal->cv != elm->u.bbmcu.cv)
610 return 1; /* ignore this element */
611
612 fw_suit = rtw89_fw_suit_get(rtwdev, type);
613 fw_suit->data = elm->u.bbmcu.contents;
614 fw_suit->size = le32_to_cpu(elm->size);
615
616 return rtw89_fw_update_ver(rtwdev, type, fw_suit);
617 }
618
619 #define __DEF_FW_FEAT_COND(__cond, __op) \
620 static bool __fw_feat_cond_ ## __cond(u32 suit_ver_code, u32 comp_ver_code) \
621 { \
622 return suit_ver_code __op comp_ver_code; \
623 }
624
625 __DEF_FW_FEAT_COND(ge, >=); /* greater or equal */
626 __DEF_FW_FEAT_COND(le, <=); /* less or equal */
627 __DEF_FW_FEAT_COND(lt, <); /* less than */
628
629 struct __fw_feat_cfg {
630 enum rtw89_core_chip_id chip_id;
631 enum rtw89_fw_feature feature;
632 u32 ver_code;
633 bool (*cond)(u32 suit_ver_code, u32 comp_ver_code);
634 };
635
636 #define __CFG_FW_FEAT(_chip, _cond, _maj, _min, _sub, _idx, _feat) \
637 { \
638 .chip_id = _chip, \
639 .feature = RTW89_FW_FEATURE_ ## _feat, \
640 .ver_code = RTW89_FW_VER_CODE(_maj, _min, _sub, _idx), \
641 .cond = __fw_feat_cond_ ## _cond, \
642 }
643
644 static const struct __fw_feat_cfg fw_feat_tbl[] = {
645 __CFG_FW_FEAT(RTL8851B, ge, 0, 29, 37, 1, TX_WAKE),
646 __CFG_FW_FEAT(RTL8851B, ge, 0, 29, 37, 1, SCAN_OFFLOAD),
647 __CFG_FW_FEAT(RTL8851B, ge, 0, 29, 41, 0, CRASH_TRIGGER),
648 __CFG_FW_FEAT(RTL8852A, le, 0, 13, 29, 0, OLD_HT_RA_FORMAT),
649 __CFG_FW_FEAT(RTL8852A, ge, 0, 13, 35, 0, SCAN_OFFLOAD),
650 __CFG_FW_FEAT(RTL8852A, ge, 0, 13, 35, 0, TX_WAKE),
651 __CFG_FW_FEAT(RTL8852A, ge, 0, 13, 36, 0, CRASH_TRIGGER),
652 __CFG_FW_FEAT(RTL8852A, lt, 0, 13, 38, 0, NO_PACKET_DROP),
653 __CFG_FW_FEAT(RTL8852B, ge, 0, 29, 26, 0, NO_LPS_PG),
654 __CFG_FW_FEAT(RTL8852B, ge, 0, 29, 26, 0, TX_WAKE),
655 __CFG_FW_FEAT(RTL8852B, ge, 0, 29, 29, 0, CRASH_TRIGGER),
656 __CFG_FW_FEAT(RTL8852B, ge, 0, 29, 29, 0, SCAN_OFFLOAD),
657 __CFG_FW_FEAT(RTL8852C, le, 0, 27, 33, 0, NO_DEEP_PS),
658 __CFG_FW_FEAT(RTL8852C, ge, 0, 27, 34, 0, TX_WAKE),
659 __CFG_FW_FEAT(RTL8852C, ge, 0, 27, 36, 0, SCAN_OFFLOAD),
660 __CFG_FW_FEAT(RTL8852C, ge, 0, 27, 40, 0, CRASH_TRIGGER),
661 __CFG_FW_FEAT(RTL8852C, ge, 0, 27, 56, 10, BEACON_FILTER),
662 __CFG_FW_FEAT(RTL8922A, ge, 0, 34, 30, 0, CRASH_TRIGGER),
663 __CFG_FW_FEAT(RTL8922A, ge, 0, 34, 11, 0, MACID_PAUSE_SLEEP),
664 __CFG_FW_FEAT(RTL8922A, ge, 0, 34, 35, 0, SCAN_OFFLOAD),
665 __CFG_FW_FEAT(RTL8922A, ge, 0, 35, 12, 0, BEACON_FILTER),
666 };
667
rtw89_fw_iterate_feature_cfg(struct rtw89_fw_info * fw,const struct rtw89_chip_info * chip,u32 ver_code)668 static void rtw89_fw_iterate_feature_cfg(struct rtw89_fw_info *fw,
669 const struct rtw89_chip_info *chip,
670 u32 ver_code)
671 {
672 int i;
673
674 for (i = 0; i < ARRAY_SIZE(fw_feat_tbl); i++) {
675 const struct __fw_feat_cfg *ent = &fw_feat_tbl[i];
676
677 if (chip->chip_id != ent->chip_id)
678 continue;
679
680 if (ent->cond(ver_code, ent->ver_code))
681 RTW89_SET_FW_FEATURE(ent->feature, fw);
682 }
683 }
684
rtw89_fw_recognize_features(struct rtw89_dev * rtwdev)685 static void rtw89_fw_recognize_features(struct rtw89_dev *rtwdev)
686 {
687 const struct rtw89_chip_info *chip = rtwdev->chip;
688 const struct rtw89_fw_suit *fw_suit;
689 u32 suit_ver_code;
690
691 fw_suit = rtw89_fw_suit_get(rtwdev, RTW89_FW_NORMAL);
692 suit_ver_code = RTW89_FW_SUIT_VER_CODE(fw_suit);
693
694 rtw89_fw_iterate_feature_cfg(&rtwdev->fw, chip, suit_ver_code);
695 }
696
697 const struct firmware *
rtw89_early_fw_feature_recognize(struct device * device,const struct rtw89_chip_info * chip,struct rtw89_fw_info * early_fw,int * used_fw_format)698 rtw89_early_fw_feature_recognize(struct device *device,
699 const struct rtw89_chip_info *chip,
700 struct rtw89_fw_info *early_fw,
701 int *used_fw_format)
702 {
703 const struct firmware *firmware;
704 char fw_name[64];
705 int fw_format;
706 u32 ver_code;
707 int ret;
708
709 for (fw_format = chip->fw_format_max; fw_format >= 0; fw_format--) {
710 rtw89_fw_get_filename(fw_name, sizeof(fw_name),
711 chip->fw_basename, fw_format);
712
713 ret = request_firmware(&firmware, fw_name, device);
714 if (!ret) {
715 dev_info(device, "loaded firmware %s\n", fw_name);
716 *used_fw_format = fw_format;
717 break;
718 }
719 }
720
721 if (ret) {
722 dev_err(device, "failed to early request firmware: %d\n", ret);
723 return NULL;
724 }
725
726 ver_code = rtw89_compat_fw_hdr_ver_code(firmware->data);
727
728 if (!ver_code)
729 goto out;
730
731 rtw89_fw_iterate_feature_cfg(early_fw, chip, ver_code);
732
733 out:
734 return firmware;
735 }
736
rtw89_fw_recognize(struct rtw89_dev * rtwdev)737 int rtw89_fw_recognize(struct rtw89_dev *rtwdev)
738 {
739 const struct rtw89_chip_info *chip = rtwdev->chip;
740 int ret;
741
742 if (chip->try_ce_fw) {
743 ret = __rtw89_fw_recognize(rtwdev, RTW89_FW_NORMAL_CE, true);
744 if (!ret)
745 goto normal_done;
746 }
747
748 ret = __rtw89_fw_recognize(rtwdev, RTW89_FW_NORMAL, false);
749 if (ret)
750 return ret;
751
752 normal_done:
753 /* It still works if wowlan firmware isn't existing. */
754 __rtw89_fw_recognize(rtwdev, RTW89_FW_WOWLAN, false);
755
756 /* It still works if log format file isn't existing. */
757 __rtw89_fw_recognize(rtwdev, RTW89_FW_LOGFMT, true);
758
759 rtw89_fw_recognize_features(rtwdev);
760
761 rtw89_coex_recognize_ver(rtwdev);
762
763 return 0;
764 }
765
766 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)767 int rtw89_build_phy_tbl_from_elm(struct rtw89_dev *rtwdev,
768 const struct rtw89_fw_element_hdr *elm,
769 const union rtw89_fw_element_arg arg)
770 {
771 struct rtw89_fw_elm_info *elm_info = &rtwdev->fw.elm_info;
772 struct rtw89_phy_table *tbl;
773 struct rtw89_reg2_def *regs;
774 enum rtw89_rf_path rf_path;
775 u32 n_regs, i;
776 u8 idx;
777
778 tbl = kzalloc(sizeof(*tbl), GFP_KERNEL);
779 if (!tbl)
780 return -ENOMEM;
781
782 switch (le32_to_cpu(elm->id)) {
783 case RTW89_FW_ELEMENT_ID_BB_REG:
784 elm_info->bb_tbl = tbl;
785 break;
786 case RTW89_FW_ELEMENT_ID_BB_GAIN:
787 elm_info->bb_gain = tbl;
788 break;
789 case RTW89_FW_ELEMENT_ID_RADIO_A:
790 case RTW89_FW_ELEMENT_ID_RADIO_B:
791 case RTW89_FW_ELEMENT_ID_RADIO_C:
792 case RTW89_FW_ELEMENT_ID_RADIO_D:
793 rf_path = arg.rf_path;
794 idx = elm->u.reg2.idx;
795
796 elm_info->rf_radio[idx] = tbl;
797 tbl->rf_path = rf_path;
798 tbl->config = rtw89_phy_config_rf_reg_v1;
799 break;
800 case RTW89_FW_ELEMENT_ID_RF_NCTL:
801 elm_info->rf_nctl = tbl;
802 break;
803 default:
804 kfree(tbl);
805 return -ENOENT;
806 }
807
808 n_regs = le32_to_cpu(elm->size) / sizeof(tbl->regs[0]);
809 regs = kcalloc(n_regs, sizeof(tbl->regs[0]), GFP_KERNEL);
810 if (!regs)
811 goto out;
812
813 for (i = 0; i < n_regs; i++) {
814 regs[i].addr = le32_to_cpu(elm->u.reg2.regs[i].addr);
815 regs[i].data = le32_to_cpu(elm->u.reg2.regs[i].data);
816 }
817
818 tbl->n_regs = n_regs;
819 tbl->regs = regs;
820
821 return 0;
822
823 out:
824 kfree(tbl);
825 return -ENOMEM;
826 }
827
828 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)829 int rtw89_fw_recognize_txpwr_from_elm(struct rtw89_dev *rtwdev,
830 const struct rtw89_fw_element_hdr *elm,
831 const union rtw89_fw_element_arg arg)
832 {
833 const struct __rtw89_fw_txpwr_element *txpwr_elm = &elm->u.txpwr;
834 const unsigned long offset = arg.offset;
835 struct rtw89_efuse *efuse = &rtwdev->efuse;
836 struct rtw89_txpwr_conf *conf;
837
838 if (!rtwdev->rfe_data) {
839 rtwdev->rfe_data = kzalloc(sizeof(*rtwdev->rfe_data), GFP_KERNEL);
840 if (!rtwdev->rfe_data)
841 return -ENOMEM;
842 }
843
844 conf = (void *)rtwdev->rfe_data + offset;
845
846 /* if multiple matched, take the last eventually */
847 if (txpwr_elm->rfe_type == efuse->rfe_type)
848 goto setup;
849
850 /* without one is matched, accept default */
851 if (txpwr_elm->rfe_type == RTW89_TXPWR_CONF_DFLT_RFE_TYPE &&
852 (!rtw89_txpwr_conf_valid(conf) ||
853 conf->rfe_type == RTW89_TXPWR_CONF_DFLT_RFE_TYPE))
854 goto setup;
855
856 rtw89_debug(rtwdev, RTW89_DBG_FW, "skip txpwr element ID %u RFE %u\n",
857 elm->id, txpwr_elm->rfe_type);
858 return 0;
859
860 setup:
861 rtw89_debug(rtwdev, RTW89_DBG_FW, "take txpwr element ID %u RFE %u\n",
862 elm->id, txpwr_elm->rfe_type);
863
864 conf->rfe_type = txpwr_elm->rfe_type;
865 conf->ent_sz = txpwr_elm->ent_sz;
866 conf->num_ents = le32_to_cpu(txpwr_elm->num_ents);
867 conf->data = txpwr_elm->content;
868 return 0;
869 }
870
871 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)872 int rtw89_build_txpwr_trk_tbl_from_elm(struct rtw89_dev *rtwdev,
873 const struct rtw89_fw_element_hdr *elm,
874 const union rtw89_fw_element_arg arg)
875 {
876 struct rtw89_fw_elm_info *elm_info = &rtwdev->fw.elm_info;
877 const struct rtw89_chip_info *chip = rtwdev->chip;
878 u32 needed_bitmap = 0;
879 u32 offset = 0;
880 int subband;
881 u32 bitmap;
882 int type;
883
884 if (chip->support_bands & BIT(NL80211_BAND_6GHZ))
885 needed_bitmap |= RTW89_DEFAULT_NEEDED_FW_TXPWR_TRK_6GHZ;
886 if (chip->support_bands & BIT(NL80211_BAND_5GHZ))
887 needed_bitmap |= RTW89_DEFAULT_NEEDED_FW_TXPWR_TRK_5GHZ;
888 if (chip->support_bands & BIT(NL80211_BAND_2GHZ))
889 needed_bitmap |= RTW89_DEFAULT_NEEDED_FW_TXPWR_TRK_2GHZ;
890
891 bitmap = le32_to_cpu(elm->u.txpwr_trk.bitmap);
892
893 if ((bitmap & needed_bitmap) != needed_bitmap) {
894 rtw89_warn(rtwdev, "needed txpwr trk bitmap %08x but %0x8x\n",
895 needed_bitmap, bitmap);
896 return -ENOENT;
897 }
898
899 elm_info->txpwr_trk = kzalloc(sizeof(*elm_info->txpwr_trk), GFP_KERNEL);
900 if (!elm_info->txpwr_trk)
901 return -ENOMEM;
902
903 for (type = 0; bitmap; type++, bitmap >>= 1) {
904 if (!(bitmap & BIT(0)))
905 continue;
906
907 if (type >= __RTW89_FW_TXPWR_TRK_TYPE_6GHZ_START &&
908 type <= __RTW89_FW_TXPWR_TRK_TYPE_6GHZ_MAX)
909 subband = 4;
910 else if (type >= __RTW89_FW_TXPWR_TRK_TYPE_5GHZ_START &&
911 type <= __RTW89_FW_TXPWR_TRK_TYPE_5GHZ_MAX)
912 subband = 3;
913 else if (type >= __RTW89_FW_TXPWR_TRK_TYPE_2GHZ_START &&
914 type <= __RTW89_FW_TXPWR_TRK_TYPE_2GHZ_MAX)
915 subband = 1;
916 else
917 break;
918
919 elm_info->txpwr_trk->delta[type] = &elm->u.txpwr_trk.contents[offset];
920
921 offset += subband;
922 if (offset * DELTA_SWINGIDX_SIZE > le32_to_cpu(elm->size))
923 goto err;
924 }
925
926 return 0;
927
928 err:
929 rtw89_warn(rtwdev, "unexpected txpwr trk offset %d over size %d\n",
930 offset, le32_to_cpu(elm->size));
931 kfree(elm_info->txpwr_trk);
932 elm_info->txpwr_trk = NULL;
933
934 return -EFAULT;
935 }
936
937 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)938 int rtw89_build_rfk_log_fmt_from_elm(struct rtw89_dev *rtwdev,
939 const struct rtw89_fw_element_hdr *elm,
940 const union rtw89_fw_element_arg arg)
941 {
942 struct rtw89_fw_elm_info *elm_info = &rtwdev->fw.elm_info;
943 u8 rfk_id;
944
945 if (elm_info->rfk_log_fmt)
946 goto allocated;
947
948 elm_info->rfk_log_fmt = kzalloc(sizeof(*elm_info->rfk_log_fmt), GFP_KERNEL);
949 if (!elm_info->rfk_log_fmt)
950 return 1; /* this is an optional element, so just ignore this */
951
952 allocated:
953 rfk_id = elm->u.rfk_log_fmt.rfk_id;
954 if (rfk_id >= RTW89_PHY_C2H_RFK_LOG_FUNC_NUM)
955 return 1;
956
957 elm_info->rfk_log_fmt->elm[rfk_id] = elm;
958
959 return 0;
960 }
961
962 static const struct rtw89_fw_element_handler __fw_element_handlers[] = {
963 [RTW89_FW_ELEMENT_ID_BBMCU0] = {__rtw89_fw_recognize_from_elm,
964 { .fw_type = RTW89_FW_BBMCU0 }, NULL},
965 [RTW89_FW_ELEMENT_ID_BBMCU1] = {__rtw89_fw_recognize_from_elm,
966 { .fw_type = RTW89_FW_BBMCU1 }, NULL},
967 [RTW89_FW_ELEMENT_ID_BB_REG] = {rtw89_build_phy_tbl_from_elm, {}, "BB"},
968 [RTW89_FW_ELEMENT_ID_BB_GAIN] = {rtw89_build_phy_tbl_from_elm, {}, NULL},
969 [RTW89_FW_ELEMENT_ID_RADIO_A] = {rtw89_build_phy_tbl_from_elm,
970 { .rf_path = RF_PATH_A }, "radio A"},
971 [RTW89_FW_ELEMENT_ID_RADIO_B] = {rtw89_build_phy_tbl_from_elm,
972 { .rf_path = RF_PATH_B }, NULL},
973 [RTW89_FW_ELEMENT_ID_RADIO_C] = {rtw89_build_phy_tbl_from_elm,
974 { .rf_path = RF_PATH_C }, NULL},
975 [RTW89_FW_ELEMENT_ID_RADIO_D] = {rtw89_build_phy_tbl_from_elm,
976 { .rf_path = RF_PATH_D }, NULL},
977 [RTW89_FW_ELEMENT_ID_RF_NCTL] = {rtw89_build_phy_tbl_from_elm, {}, "NCTL"},
978 [RTW89_FW_ELEMENT_ID_TXPWR_BYRATE] = {
979 rtw89_fw_recognize_txpwr_from_elm,
980 { .offset = offsetof(struct rtw89_rfe_data, byrate.conf) }, "TXPWR",
981 },
982 [RTW89_FW_ELEMENT_ID_TXPWR_LMT_2GHZ] = {
983 rtw89_fw_recognize_txpwr_from_elm,
984 { .offset = offsetof(struct rtw89_rfe_data, lmt_2ghz.conf) }, NULL,
985 },
986 [RTW89_FW_ELEMENT_ID_TXPWR_LMT_5GHZ] = {
987 rtw89_fw_recognize_txpwr_from_elm,
988 { .offset = offsetof(struct rtw89_rfe_data, lmt_5ghz.conf) }, NULL,
989 },
990 [RTW89_FW_ELEMENT_ID_TXPWR_LMT_6GHZ] = {
991 rtw89_fw_recognize_txpwr_from_elm,
992 { .offset = offsetof(struct rtw89_rfe_data, lmt_6ghz.conf) }, NULL,
993 },
994 [RTW89_FW_ELEMENT_ID_TXPWR_LMT_RU_2GHZ] = {
995 rtw89_fw_recognize_txpwr_from_elm,
996 { .offset = offsetof(struct rtw89_rfe_data, lmt_ru_2ghz.conf) }, NULL,
997 },
998 [RTW89_FW_ELEMENT_ID_TXPWR_LMT_RU_5GHZ] = {
999 rtw89_fw_recognize_txpwr_from_elm,
1000 { .offset = offsetof(struct rtw89_rfe_data, lmt_ru_5ghz.conf) }, NULL,
1001 },
1002 [RTW89_FW_ELEMENT_ID_TXPWR_LMT_RU_6GHZ] = {
1003 rtw89_fw_recognize_txpwr_from_elm,
1004 { .offset = offsetof(struct rtw89_rfe_data, lmt_ru_6ghz.conf) }, NULL,
1005 },
1006 [RTW89_FW_ELEMENT_ID_TX_SHAPE_LMT] = {
1007 rtw89_fw_recognize_txpwr_from_elm,
1008 { .offset = offsetof(struct rtw89_rfe_data, tx_shape_lmt.conf) }, NULL,
1009 },
1010 [RTW89_FW_ELEMENT_ID_TX_SHAPE_LMT_RU] = {
1011 rtw89_fw_recognize_txpwr_from_elm,
1012 { .offset = offsetof(struct rtw89_rfe_data, tx_shape_lmt_ru.conf) }, NULL,
1013 },
1014 [RTW89_FW_ELEMENT_ID_TXPWR_TRK] = {
1015 rtw89_build_txpwr_trk_tbl_from_elm, {}, "PWR_TRK",
1016 },
1017 [RTW89_FW_ELEMENT_ID_RFKLOG_FMT] = {
1018 rtw89_build_rfk_log_fmt_from_elm, {}, NULL,
1019 },
1020 };
1021
rtw89_fw_recognize_elements(struct rtw89_dev * rtwdev)1022 int rtw89_fw_recognize_elements(struct rtw89_dev *rtwdev)
1023 {
1024 struct rtw89_fw_info *fw_info = &rtwdev->fw;
1025 const struct firmware *firmware = fw_info->req.firmware;
1026 const struct rtw89_chip_info *chip = rtwdev->chip;
1027 u32 unrecognized_elements = chip->needed_fw_elms;
1028 const struct rtw89_fw_element_handler *handler;
1029 const struct rtw89_fw_element_hdr *hdr;
1030 u32 elm_size;
1031 u32 elem_id;
1032 u32 offset;
1033 int ret;
1034
1035 BUILD_BUG_ON(sizeof(chip->needed_fw_elms) * 8 < RTW89_FW_ELEMENT_ID_NUM);
1036
1037 offset = rtw89_mfw_get_size(rtwdev);
1038 offset = ALIGN(offset, RTW89_FW_ELEMENT_ALIGN);
1039 if (offset == 0)
1040 return -EINVAL;
1041
1042 while (offset + sizeof(*hdr) < firmware->size) {
1043 hdr = (const struct rtw89_fw_element_hdr *)(firmware->data + offset);
1044
1045 elm_size = le32_to_cpu(hdr->size);
1046 if (offset + elm_size >= firmware->size) {
1047 rtw89_warn(rtwdev, "firmware element size exceeds\n");
1048 break;
1049 }
1050
1051 elem_id = le32_to_cpu(hdr->id);
1052 if (elem_id >= ARRAY_SIZE(__fw_element_handlers))
1053 goto next;
1054
1055 handler = &__fw_element_handlers[elem_id];
1056 if (!handler->fn)
1057 goto next;
1058
1059 ret = handler->fn(rtwdev, hdr, handler->arg);
1060 if (ret == 1) /* ignore this element */
1061 goto next;
1062 if (ret)
1063 return ret;
1064
1065 if (handler->name)
1066 rtw89_info(rtwdev, "Firmware element %s version: %4ph\n",
1067 handler->name, hdr->ver);
1068
1069 unrecognized_elements &= ~BIT(elem_id);
1070 next:
1071 offset += sizeof(*hdr) + elm_size;
1072 offset = ALIGN(offset, RTW89_FW_ELEMENT_ALIGN);
1073 }
1074
1075 if (unrecognized_elements) {
1076 rtw89_err(rtwdev, "Firmware elements 0x%08x are unrecognized\n",
1077 unrecognized_elements);
1078 return -ENOENT;
1079 }
1080
1081 return 0;
1082 }
1083
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)1084 void rtw89_h2c_pkt_set_hdr(struct rtw89_dev *rtwdev, struct sk_buff *skb,
1085 u8 type, u8 cat, u8 class, u8 func,
1086 bool rack, bool dack, u32 len)
1087 {
1088 struct fwcmd_hdr *hdr;
1089
1090 hdr = (struct fwcmd_hdr *)skb_push(skb, 8);
1091
1092 if (!(rtwdev->fw.h2c_seq % 4))
1093 rack = true;
1094 hdr->hdr0 = cpu_to_le32(FIELD_PREP(H2C_HDR_DEL_TYPE, type) |
1095 FIELD_PREP(H2C_HDR_CAT, cat) |
1096 FIELD_PREP(H2C_HDR_CLASS, class) |
1097 FIELD_PREP(H2C_HDR_FUNC, func) |
1098 FIELD_PREP(H2C_HDR_H2C_SEQ, rtwdev->fw.h2c_seq));
1099
1100 hdr->hdr1 = cpu_to_le32(FIELD_PREP(H2C_HDR_TOTAL_LEN,
1101 len + H2C_HEADER_LEN) |
1102 (rack ? H2C_HDR_REC_ACK : 0) |
1103 (dack ? H2C_HDR_DONE_ACK : 0));
1104
1105 rtwdev->fw.h2c_seq++;
1106 }
1107
rtw89_h2c_pkt_set_hdr_fwdl(struct rtw89_dev * rtwdev,struct sk_buff * skb,u8 type,u8 cat,u8 class,u8 func,u32 len)1108 static void rtw89_h2c_pkt_set_hdr_fwdl(struct rtw89_dev *rtwdev,
1109 struct sk_buff *skb,
1110 u8 type, u8 cat, u8 class, u8 func,
1111 u32 len)
1112 {
1113 struct fwcmd_hdr *hdr;
1114
1115 hdr = (struct fwcmd_hdr *)skb_push(skb, 8);
1116
1117 hdr->hdr0 = cpu_to_le32(FIELD_PREP(H2C_HDR_DEL_TYPE, type) |
1118 FIELD_PREP(H2C_HDR_CAT, cat) |
1119 FIELD_PREP(H2C_HDR_CLASS, class) |
1120 FIELD_PREP(H2C_HDR_FUNC, func) |
1121 FIELD_PREP(H2C_HDR_H2C_SEQ, rtwdev->fw.h2c_seq));
1122
1123 hdr->hdr1 = cpu_to_le32(FIELD_PREP(H2C_HDR_TOTAL_LEN,
1124 len + H2C_HEADER_LEN));
1125 }
1126
__rtw89_fw_download_tweak_hdr_v0(struct rtw89_dev * rtwdev,struct rtw89_fw_bin_info * info,struct rtw89_fw_hdr * fw_hdr)1127 static u32 __rtw89_fw_download_tweak_hdr_v0(struct rtw89_dev *rtwdev,
1128 struct rtw89_fw_bin_info *info,
1129 struct rtw89_fw_hdr *fw_hdr)
1130 {
1131 le32p_replace_bits(&fw_hdr->w7, FWDL_SECTION_PER_PKT_LEN,
1132 FW_HDR_W7_PART_SIZE);
1133
1134 return 0;
1135 }
1136
__rtw89_fw_download_tweak_hdr_v1(struct rtw89_dev * rtwdev,struct rtw89_fw_bin_info * info,struct rtw89_fw_hdr_v1 * fw_hdr)1137 static u32 __rtw89_fw_download_tweak_hdr_v1(struct rtw89_dev *rtwdev,
1138 struct rtw89_fw_bin_info *info,
1139 struct rtw89_fw_hdr_v1 *fw_hdr)
1140 {
1141 struct rtw89_fw_hdr_section_info *section_info;
1142 struct rtw89_fw_hdr_section_v1 *section;
1143 u8 dst_sec_idx = 0;
1144 u8 sec_idx;
1145
1146 le32p_replace_bits(&fw_hdr->w7, FWDL_SECTION_PER_PKT_LEN,
1147 FW_HDR_V1_W7_PART_SIZE);
1148
1149 for (sec_idx = 0; sec_idx < info->section_num; sec_idx++) {
1150 section_info = &info->section_info[sec_idx];
1151 section = &fw_hdr->sections[sec_idx];
1152
1153 if (section_info->ignore)
1154 continue;
1155
1156 if (dst_sec_idx != sec_idx)
1157 fw_hdr->sections[dst_sec_idx] = *section;
1158
1159 dst_sec_idx++;
1160 }
1161
1162 le32p_replace_bits(&fw_hdr->w6, dst_sec_idx, FW_HDR_V1_W6_SEC_NUM);
1163
1164 return (info->section_num - dst_sec_idx) * sizeof(*section);
1165 }
1166
__rtw89_fw_download_hdr(struct rtw89_dev * rtwdev,const struct rtw89_fw_suit * fw_suit,struct rtw89_fw_bin_info * info)1167 static int __rtw89_fw_download_hdr(struct rtw89_dev *rtwdev,
1168 const struct rtw89_fw_suit *fw_suit,
1169 struct rtw89_fw_bin_info *info)
1170 {
1171 u32 len = info->hdr_len - info->dynamic_hdr_len;
1172 struct rtw89_fw_hdr_v1 *fw_hdr_v1;
1173 const u8 *fw = fw_suit->data;
1174 struct rtw89_fw_hdr *fw_hdr;
1175 struct sk_buff *skb;
1176 u32 truncated;
1177 u32 ret = 0;
1178
1179 skb = rtw89_fw_h2c_alloc_skb_with_hdr(rtwdev, len);
1180 if (!skb) {
1181 rtw89_err(rtwdev, "failed to alloc skb for fw hdr dl\n");
1182 return -ENOMEM;
1183 }
1184
1185 skb_put_data(skb, fw, len);
1186
1187 switch (fw_suit->hdr_ver) {
1188 case 0:
1189 fw_hdr = (struct rtw89_fw_hdr *)skb->data;
1190 truncated = __rtw89_fw_download_tweak_hdr_v0(rtwdev, info, fw_hdr);
1191 break;
1192 case 1:
1193 fw_hdr_v1 = (struct rtw89_fw_hdr_v1 *)skb->data;
1194 truncated = __rtw89_fw_download_tweak_hdr_v1(rtwdev, info, fw_hdr_v1);
1195 break;
1196 default:
1197 ret = -EOPNOTSUPP;
1198 goto fail;
1199 }
1200
1201 if (truncated) {
1202 len -= truncated;
1203 skb_trim(skb, len);
1204 }
1205
1206 rtw89_h2c_pkt_set_hdr_fwdl(rtwdev, skb, FWCMD_TYPE_H2C,
1207 H2C_CAT_MAC, H2C_CL_MAC_FWDL,
1208 H2C_FUNC_MAC_FWHDR_DL, len);
1209
1210 ret = rtw89_h2c_tx(rtwdev, skb, false);
1211 if (ret) {
1212 rtw89_err(rtwdev, "failed to send h2c\n");
1213 ret = -1;
1214 goto fail;
1215 }
1216
1217 return 0;
1218 fail:
1219 dev_kfree_skb_any(skb);
1220
1221 return ret;
1222 }
1223
rtw89_fw_download_hdr(struct rtw89_dev * rtwdev,const struct rtw89_fw_suit * fw_suit,struct rtw89_fw_bin_info * info)1224 static int rtw89_fw_download_hdr(struct rtw89_dev *rtwdev,
1225 const struct rtw89_fw_suit *fw_suit,
1226 struct rtw89_fw_bin_info *info)
1227 {
1228 const struct rtw89_mac_gen_def *mac = rtwdev->chip->mac_def;
1229 int ret;
1230
1231 ret = __rtw89_fw_download_hdr(rtwdev, fw_suit, info);
1232 if (ret) {
1233 rtw89_err(rtwdev, "[ERR]FW header download\n");
1234 return ret;
1235 }
1236
1237 ret = mac->fwdl_check_path_ready(rtwdev, false);
1238 if (ret) {
1239 rtw89_err(rtwdev, "[ERR]FWDL path ready\n");
1240 return ret;
1241 }
1242
1243 rtw89_write32(rtwdev, R_AX_HALT_H2C_CTRL, 0);
1244 rtw89_write32(rtwdev, R_AX_HALT_C2H_CTRL, 0);
1245
1246 return 0;
1247 }
1248
__rtw89_fw_download_main(struct rtw89_dev * rtwdev,struct rtw89_fw_hdr_section_info * info)1249 static int __rtw89_fw_download_main(struct rtw89_dev *rtwdev,
1250 struct rtw89_fw_hdr_section_info *info)
1251 {
1252 struct sk_buff *skb;
1253 const u8 *section = info->addr;
1254 u32 residue_len = info->len;
1255 bool copy_key = false;
1256 u32 pkt_len;
1257 int ret;
1258
1259 if (info->ignore)
1260 return 0;
1261
1262 if (info->key_addr && info->key_len) {
1263 if (info->len > FWDL_SECTION_PER_PKT_LEN || info->len < info->key_len)
1264 rtw89_warn(rtwdev, "ignore to copy key data because of len %d, %d, %d\n",
1265 info->len, FWDL_SECTION_PER_PKT_LEN, info->key_len);
1266 else
1267 copy_key = true;
1268 }
1269
1270 while (residue_len) {
1271 if (residue_len >= FWDL_SECTION_PER_PKT_LEN)
1272 pkt_len = FWDL_SECTION_PER_PKT_LEN;
1273 else
1274 pkt_len = residue_len;
1275
1276 skb = rtw89_fw_h2c_alloc_skb_no_hdr(rtwdev, pkt_len);
1277 if (!skb) {
1278 rtw89_err(rtwdev, "failed to alloc skb for fw dl\n");
1279 return -ENOMEM;
1280 }
1281 skb_put_data(skb, section, pkt_len);
1282
1283 if (copy_key)
1284 memcpy(skb->data + pkt_len - info->key_len,
1285 info->key_addr, info->key_len);
1286
1287 ret = rtw89_h2c_tx(rtwdev, skb, true);
1288 if (ret) {
1289 rtw89_err(rtwdev, "failed to send h2c\n");
1290 ret = -1;
1291 goto fail;
1292 }
1293
1294 section += pkt_len;
1295 residue_len -= pkt_len;
1296 }
1297
1298 return 0;
1299 fail:
1300 dev_kfree_skb_any(skb);
1301
1302 return ret;
1303 }
1304
1305 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)1306 rtw89_fw_get_fwdl_chk_type_from_suit(struct rtw89_dev *rtwdev,
1307 const struct rtw89_fw_suit *fw_suit)
1308 {
1309 switch (fw_suit->type) {
1310 case RTW89_FW_BBMCU0:
1311 return RTW89_FWDL_CHECK_BB0_FWDL_DONE;
1312 case RTW89_FW_BBMCU1:
1313 return RTW89_FWDL_CHECK_BB1_FWDL_DONE;
1314 default:
1315 return RTW89_FWDL_CHECK_WCPU_FWDL_DONE;
1316 }
1317 }
1318
rtw89_fw_download_main(struct rtw89_dev * rtwdev,const struct rtw89_fw_suit * fw_suit,struct rtw89_fw_bin_info * info)1319 static int rtw89_fw_download_main(struct rtw89_dev *rtwdev,
1320 const struct rtw89_fw_suit *fw_suit,
1321 struct rtw89_fw_bin_info *info)
1322 {
1323 struct rtw89_fw_hdr_section_info *section_info = info->section_info;
1324 const struct rtw89_chip_info *chip = rtwdev->chip;
1325 enum rtw89_fwdl_check_type chk_type;
1326 u8 section_num = info->section_num;
1327 int ret;
1328
1329 while (section_num--) {
1330 ret = __rtw89_fw_download_main(rtwdev, section_info);
1331 if (ret)
1332 return ret;
1333 section_info++;
1334 }
1335
1336 if (chip->chip_gen == RTW89_CHIP_AX)
1337 return 0;
1338
1339 chk_type = rtw89_fw_get_fwdl_chk_type_from_suit(rtwdev, fw_suit);
1340 ret = rtw89_fw_check_rdy(rtwdev, chk_type);
1341 if (ret) {
1342 rtw89_warn(rtwdev, "failed to download firmware type %u\n",
1343 fw_suit->type);
1344 return ret;
1345 }
1346
1347 return 0;
1348 }
1349
rtw89_fw_prog_cnt_dump(struct rtw89_dev * rtwdev)1350 static void rtw89_fw_prog_cnt_dump(struct rtw89_dev *rtwdev)
1351 {
1352 enum rtw89_chip_gen chip_gen = rtwdev->chip->chip_gen;
1353 u32 addr = R_AX_DBG_PORT_SEL;
1354 u32 val32;
1355 u16 index;
1356
1357 if (chip_gen == RTW89_CHIP_BE) {
1358 addr = R_BE_WLCPU_PORT_PC;
1359 goto dump;
1360 }
1361
1362 rtw89_write32(rtwdev, R_AX_DBG_CTRL,
1363 FIELD_PREP(B_AX_DBG_SEL0, FW_PROG_CNTR_DBG_SEL) |
1364 FIELD_PREP(B_AX_DBG_SEL1, FW_PROG_CNTR_DBG_SEL));
1365 rtw89_write32_mask(rtwdev, R_AX_SYS_STATUS1, B_AX_SEL_0XC0_MASK, MAC_DBG_SEL);
1366
1367 dump:
1368 for (index = 0; index < 15; index++) {
1369 val32 = rtw89_read32(rtwdev, addr);
1370 rtw89_err(rtwdev, "[ERR]fw PC = 0x%x\n", val32);
1371 fsleep(10);
1372 }
1373 }
1374
rtw89_fw_dl_fail_dump(struct rtw89_dev * rtwdev)1375 static void rtw89_fw_dl_fail_dump(struct rtw89_dev *rtwdev)
1376 {
1377 u32 val32;
1378
1379 val32 = rtw89_read32(rtwdev, R_AX_WCPU_FW_CTRL);
1380 rtw89_err(rtwdev, "[ERR]fwdl 0x1E0 = 0x%x\n", val32);
1381
1382 val32 = rtw89_read32(rtwdev, R_AX_BOOT_DBG);
1383 rtw89_err(rtwdev, "[ERR]fwdl 0x83F0 = 0x%x\n", val32);
1384
1385 rtw89_fw_prog_cnt_dump(rtwdev);
1386 }
1387
rtw89_fw_download_suit(struct rtw89_dev * rtwdev,struct rtw89_fw_suit * fw_suit)1388 static int rtw89_fw_download_suit(struct rtw89_dev *rtwdev,
1389 struct rtw89_fw_suit *fw_suit)
1390 {
1391 const struct rtw89_mac_gen_def *mac = rtwdev->chip->mac_def;
1392 struct rtw89_fw_bin_info info = {};
1393 int ret;
1394
1395 ret = rtw89_fw_hdr_parser(rtwdev, fw_suit, &info);
1396 if (ret) {
1397 rtw89_err(rtwdev, "parse fw header fail\n");
1398 return ret;
1399 }
1400
1401 if (rtwdev->chip->chip_id == RTL8922A &&
1402 (fw_suit->type == RTW89_FW_NORMAL || fw_suit->type == RTW89_FW_WOWLAN))
1403 rtw89_write32(rtwdev, R_BE_SECURE_BOOT_MALLOC_INFO, 0x20248000);
1404
1405 ret = mac->fwdl_check_path_ready(rtwdev, true);
1406 if (ret) {
1407 rtw89_err(rtwdev, "[ERR]H2C path ready\n");
1408 return ret;
1409 }
1410
1411 ret = rtw89_fw_download_hdr(rtwdev, fw_suit, &info);
1412 if (ret)
1413 return ret;
1414
1415 ret = rtw89_fw_download_main(rtwdev, fw_suit, &info);
1416 if (ret)
1417 return ret;
1418
1419 return 0;
1420 }
1421
1422 static
__rtw89_fw_download(struct rtw89_dev * rtwdev,enum rtw89_fw_type type,bool include_bb)1423 int __rtw89_fw_download(struct rtw89_dev *rtwdev, enum rtw89_fw_type type,
1424 bool include_bb)
1425 {
1426 const struct rtw89_mac_gen_def *mac = rtwdev->chip->mac_def;
1427 struct rtw89_fw_info *fw_info = &rtwdev->fw;
1428 struct rtw89_fw_suit *fw_suit = rtw89_fw_suit_get(rtwdev, type);
1429 u8 bbmcu_nr = rtwdev->chip->bbmcu_nr;
1430 int ret;
1431 int i;
1432
1433 mac->disable_cpu(rtwdev);
1434 ret = mac->fwdl_enable_wcpu(rtwdev, 0, true, include_bb);
1435 if (ret)
1436 return ret;
1437
1438 ret = rtw89_fw_download_suit(rtwdev, fw_suit);
1439 if (ret)
1440 goto fwdl_err;
1441
1442 for (i = 0; i < bbmcu_nr && include_bb; i++) {
1443 fw_suit = rtw89_fw_suit_get(rtwdev, RTW89_FW_BBMCU0 + i);
1444
1445 ret = rtw89_fw_download_suit(rtwdev, fw_suit);
1446 if (ret)
1447 goto fwdl_err;
1448 }
1449
1450 fw_info->h2c_seq = 0;
1451 fw_info->rec_seq = 0;
1452 fw_info->h2c_counter = 0;
1453 fw_info->c2h_counter = 0;
1454 rtwdev->mac.rpwm_seq_num = RPWM_SEQ_NUM_MAX;
1455 rtwdev->mac.cpwm_seq_num = CPWM_SEQ_NUM_MAX;
1456
1457 mdelay(5);
1458
1459 ret = rtw89_fw_check_rdy(rtwdev, RTW89_FWDL_CHECK_FREERTOS_DONE);
1460 if (ret) {
1461 rtw89_warn(rtwdev, "download firmware fail\n");
1462 goto fwdl_err;
1463 }
1464
1465 return ret;
1466
1467 fwdl_err:
1468 rtw89_fw_dl_fail_dump(rtwdev);
1469 return ret;
1470 }
1471
rtw89_fw_download(struct rtw89_dev * rtwdev,enum rtw89_fw_type type,bool include_bb)1472 int rtw89_fw_download(struct rtw89_dev *rtwdev, enum rtw89_fw_type type,
1473 bool include_bb)
1474 {
1475 int retry;
1476 int ret;
1477
1478 for (retry = 0; retry < 5; retry++) {
1479 ret = __rtw89_fw_download(rtwdev, type, include_bb);
1480 if (!ret)
1481 return 0;
1482 }
1483
1484 return ret;
1485 }
1486
rtw89_wait_firmware_completion(struct rtw89_dev * rtwdev)1487 int rtw89_wait_firmware_completion(struct rtw89_dev *rtwdev)
1488 {
1489 struct rtw89_fw_info *fw = &rtwdev->fw;
1490
1491 wait_for_completion(&fw->req.completion);
1492 if (!fw->req.firmware)
1493 return -EINVAL;
1494
1495 return 0;
1496 }
1497
rtw89_load_firmware_req(struct rtw89_dev * rtwdev,struct rtw89_fw_req_info * req,const char * fw_name,bool nowarn)1498 static int rtw89_load_firmware_req(struct rtw89_dev *rtwdev,
1499 struct rtw89_fw_req_info *req,
1500 const char *fw_name, bool nowarn)
1501 {
1502 int ret;
1503
1504 if (req->firmware) {
1505 rtw89_debug(rtwdev, RTW89_DBG_FW,
1506 "full firmware has been early requested\n");
1507 complete_all(&req->completion);
1508 return 0;
1509 }
1510
1511 if (nowarn)
1512 ret = firmware_request_nowarn(&req->firmware, fw_name, rtwdev->dev);
1513 else
1514 ret = request_firmware(&req->firmware, fw_name, rtwdev->dev);
1515
1516 complete_all(&req->completion);
1517
1518 return ret;
1519 }
1520
rtw89_load_firmware_work(struct work_struct * work)1521 void rtw89_load_firmware_work(struct work_struct *work)
1522 {
1523 struct rtw89_dev *rtwdev =
1524 container_of(work, struct rtw89_dev, load_firmware_work);
1525 const struct rtw89_chip_info *chip = rtwdev->chip;
1526 char fw_name[64];
1527
1528 rtw89_fw_get_filename(fw_name, sizeof(fw_name),
1529 chip->fw_basename, rtwdev->fw.fw_format);
1530
1531 rtw89_load_firmware_req(rtwdev, &rtwdev->fw.req, fw_name, false);
1532 }
1533
rtw89_free_phy_tbl_from_elm(struct rtw89_phy_table * tbl)1534 static void rtw89_free_phy_tbl_from_elm(struct rtw89_phy_table *tbl)
1535 {
1536 if (!tbl)
1537 return;
1538
1539 kfree(tbl->regs);
1540 kfree(tbl);
1541 }
1542
rtw89_unload_firmware_elements(struct rtw89_dev * rtwdev)1543 static void rtw89_unload_firmware_elements(struct rtw89_dev *rtwdev)
1544 {
1545 struct rtw89_fw_elm_info *elm_info = &rtwdev->fw.elm_info;
1546 int i;
1547
1548 rtw89_free_phy_tbl_from_elm(elm_info->bb_tbl);
1549 rtw89_free_phy_tbl_from_elm(elm_info->bb_gain);
1550 for (i = 0; i < ARRAY_SIZE(elm_info->rf_radio); i++)
1551 rtw89_free_phy_tbl_from_elm(elm_info->rf_radio[i]);
1552 rtw89_free_phy_tbl_from_elm(elm_info->rf_nctl);
1553
1554 kfree(elm_info->txpwr_trk);
1555 kfree(elm_info->rfk_log_fmt);
1556 }
1557
rtw89_unload_firmware(struct rtw89_dev * rtwdev)1558 void rtw89_unload_firmware(struct rtw89_dev *rtwdev)
1559 {
1560 struct rtw89_fw_info *fw = &rtwdev->fw;
1561
1562 cancel_work_sync(&rtwdev->load_firmware_work);
1563
1564 if (fw->req.firmware) {
1565 release_firmware(fw->req.firmware);
1566
1567 /* assign NULL back in case rtw89_free_ieee80211_hw()
1568 * try to release the same one again.
1569 */
1570 fw->req.firmware = NULL;
1571 }
1572
1573 kfree(fw->log.fmts);
1574 rtw89_unload_firmware_elements(rtwdev);
1575 }
1576
rtw89_fw_log_get_fmt_idx(struct rtw89_dev * rtwdev,u32 fmt_id)1577 static u32 rtw89_fw_log_get_fmt_idx(struct rtw89_dev *rtwdev, u32 fmt_id)
1578 {
1579 struct rtw89_fw_log *fw_log = &rtwdev->fw.log;
1580 u32 i;
1581
1582 if (fmt_id > fw_log->last_fmt_id)
1583 return 0;
1584
1585 for (i = 0; i < fw_log->fmt_count; i++) {
1586 if (le32_to_cpu(fw_log->fmt_ids[i]) == fmt_id)
1587 return i;
1588 }
1589 return 0;
1590 }
1591
rtw89_fw_log_create_fmts_dict(struct rtw89_dev * rtwdev)1592 static int rtw89_fw_log_create_fmts_dict(struct rtw89_dev *rtwdev)
1593 {
1594 struct rtw89_fw_log *log = &rtwdev->fw.log;
1595 const struct rtw89_fw_logsuit_hdr *suit_hdr;
1596 struct rtw89_fw_suit *suit = &log->suit;
1597 const void *fmts_ptr, *fmts_end_ptr;
1598 u32 fmt_count;
1599 int i;
1600
1601 suit_hdr = (const struct rtw89_fw_logsuit_hdr *)suit->data;
1602 fmt_count = le32_to_cpu(suit_hdr->count);
1603 log->fmt_ids = suit_hdr->ids;
1604 fmts_ptr = &suit_hdr->ids[fmt_count];
1605 fmts_end_ptr = suit->data + suit->size;
1606 log->fmts = kcalloc(fmt_count, sizeof(char *), GFP_KERNEL);
1607 if (!log->fmts)
1608 return -ENOMEM;
1609
1610 for (i = 0; i < fmt_count; i++) {
1611 fmts_ptr = memchr_inv(fmts_ptr, 0, fmts_end_ptr - fmts_ptr);
1612 if (!fmts_ptr)
1613 break;
1614
1615 (*log->fmts)[i] = fmts_ptr;
1616 log->last_fmt_id = le32_to_cpu(log->fmt_ids[i]);
1617 log->fmt_count++;
1618 fmts_ptr += strlen(fmts_ptr);
1619 }
1620
1621 return 0;
1622 }
1623
rtw89_fw_log_prepare(struct rtw89_dev * rtwdev)1624 int rtw89_fw_log_prepare(struct rtw89_dev *rtwdev)
1625 {
1626 struct rtw89_fw_log *log = &rtwdev->fw.log;
1627 struct rtw89_fw_suit *suit = &log->suit;
1628
1629 if (!suit || !suit->data) {
1630 rtw89_debug(rtwdev, RTW89_DBG_FW, "no log format file\n");
1631 return -EINVAL;
1632 }
1633 if (log->fmts)
1634 return 0;
1635
1636 return rtw89_fw_log_create_fmts_dict(rtwdev);
1637 }
1638
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)1639 static void rtw89_fw_log_dump_data(struct rtw89_dev *rtwdev,
1640 const struct rtw89_fw_c2h_log_fmt *log_fmt,
1641 u32 fmt_idx, u8 para_int, bool raw_data)
1642 {
1643 const char *(*fmts)[] = rtwdev->fw.log.fmts;
1644 char str_buf[RTW89_C2H_FW_LOG_STR_BUF_SIZE];
1645 u32 args[RTW89_C2H_FW_LOG_MAX_PARA_NUM] = {0};
1646 int i;
1647
1648 if (log_fmt->argc > RTW89_C2H_FW_LOG_MAX_PARA_NUM) {
1649 rtw89_warn(rtwdev, "C2H log: Arg count is unexpected %d\n",
1650 log_fmt->argc);
1651 return;
1652 }
1653
1654 if (para_int)
1655 for (i = 0 ; i < log_fmt->argc; i++)
1656 args[i] = le32_to_cpu(log_fmt->u.argv[i]);
1657
1658 if (raw_data) {
1659 if (para_int)
1660 snprintf(str_buf, RTW89_C2H_FW_LOG_STR_BUF_SIZE,
1661 "fw_enc(%d, %d, %d) %*ph", le32_to_cpu(log_fmt->fmt_id),
1662 para_int, log_fmt->argc, (int)sizeof(args), args);
1663 else
1664 snprintf(str_buf, RTW89_C2H_FW_LOG_STR_BUF_SIZE,
1665 "fw_enc(%d, %d, %d, %s)", le32_to_cpu(log_fmt->fmt_id),
1666 para_int, log_fmt->argc, log_fmt->u.raw);
1667 } else {
1668 snprintf(str_buf, RTW89_C2H_FW_LOG_STR_BUF_SIZE, (*fmts)[fmt_idx],
1669 args[0x0], args[0x1], args[0x2], args[0x3], args[0x4],
1670 args[0x5], args[0x6], args[0x7], args[0x8], args[0x9],
1671 args[0xa], args[0xb], args[0xc], args[0xd], args[0xe],
1672 args[0xf]);
1673 }
1674
1675 rtw89_info(rtwdev, "C2H log: %s", str_buf);
1676 }
1677
rtw89_fw_log_dump(struct rtw89_dev * rtwdev,u8 * buf,u32 len)1678 void rtw89_fw_log_dump(struct rtw89_dev *rtwdev, u8 *buf, u32 len)
1679 {
1680 const struct rtw89_fw_c2h_log_fmt *log_fmt;
1681 u8 para_int;
1682 u32 fmt_idx;
1683
1684 if (len < RTW89_C2H_HEADER_LEN) {
1685 rtw89_err(rtwdev, "c2h log length is wrong!\n");
1686 return;
1687 }
1688
1689 buf += RTW89_C2H_HEADER_LEN;
1690 len -= RTW89_C2H_HEADER_LEN;
1691 log_fmt = (const struct rtw89_fw_c2h_log_fmt *)buf;
1692
1693 if (len < RTW89_C2H_FW_FORMATTED_LOG_MIN_LEN)
1694 goto plain_log;
1695
1696 if (log_fmt->signature != cpu_to_le16(RTW89_C2H_FW_LOG_SIGNATURE))
1697 goto plain_log;
1698
1699 if (!rtwdev->fw.log.fmts)
1700 return;
1701
1702 para_int = u8_get_bits(log_fmt->feature, RTW89_C2H_FW_LOG_FEATURE_PARA_INT);
1703 fmt_idx = rtw89_fw_log_get_fmt_idx(rtwdev, le32_to_cpu(log_fmt->fmt_id));
1704
1705 if (!para_int && log_fmt->argc != 0 && fmt_idx != 0)
1706 rtw89_info(rtwdev, "C2H log: %s%s",
1707 (*rtwdev->fw.log.fmts)[fmt_idx], log_fmt->u.raw);
1708 else if (fmt_idx != 0 && para_int)
1709 rtw89_fw_log_dump_data(rtwdev, log_fmt, fmt_idx, para_int, false);
1710 else
1711 rtw89_fw_log_dump_data(rtwdev, log_fmt, fmt_idx, para_int, true);
1712 return;
1713
1714 plain_log:
1715 rtw89_info(rtwdev, "C2H log: %.*s", len, buf);
1716
1717 }
1718
1719 #define H2C_CAM_LEN 60
rtw89_fw_h2c_cam(struct rtw89_dev * rtwdev,struct rtw89_vif * rtwvif,struct rtw89_sta * rtwsta,const u8 * scan_mac_addr)1720 int rtw89_fw_h2c_cam(struct rtw89_dev *rtwdev, struct rtw89_vif *rtwvif,
1721 struct rtw89_sta *rtwsta, const u8 *scan_mac_addr)
1722 {
1723 struct sk_buff *skb;
1724 int ret;
1725
1726 skb = rtw89_fw_h2c_alloc_skb_with_hdr(rtwdev, H2C_CAM_LEN);
1727 if (!skb) {
1728 rtw89_err(rtwdev, "failed to alloc skb for fw dl\n");
1729 return -ENOMEM;
1730 }
1731 skb_put(skb, H2C_CAM_LEN);
1732 rtw89_cam_fill_addr_cam_info(rtwdev, rtwvif, rtwsta, scan_mac_addr, skb->data);
1733 rtw89_cam_fill_bssid_cam_info(rtwdev, rtwvif, rtwsta, skb->data);
1734
1735 rtw89_h2c_pkt_set_hdr(rtwdev, skb, FWCMD_TYPE_H2C,
1736 H2C_CAT_MAC,
1737 H2C_CL_MAC_ADDR_CAM_UPDATE,
1738 H2C_FUNC_MAC_ADDR_CAM_UPD, 0, 1,
1739 H2C_CAM_LEN);
1740
1741 ret = rtw89_h2c_tx(rtwdev, skb, false);
1742 if (ret) {
1743 rtw89_err(rtwdev, "failed to send h2c\n");
1744 goto fail;
1745 }
1746
1747 return 0;
1748 fail:
1749 dev_kfree_skb_any(skb);
1750
1751 return ret;
1752 }
1753
rtw89_fw_h2c_dctl_sec_cam_v1(struct rtw89_dev * rtwdev,struct rtw89_vif * rtwvif,struct rtw89_sta * rtwsta)1754 int rtw89_fw_h2c_dctl_sec_cam_v1(struct rtw89_dev *rtwdev,
1755 struct rtw89_vif *rtwvif,
1756 struct rtw89_sta *rtwsta)
1757 {
1758 struct rtw89_h2c_dctlinfo_ud_v1 *h2c;
1759 u32 len = sizeof(*h2c);
1760 struct sk_buff *skb;
1761 int ret;
1762
1763 skb = rtw89_fw_h2c_alloc_skb_with_hdr(rtwdev, len);
1764 if (!skb) {
1765 rtw89_err(rtwdev, "failed to alloc skb for dctl sec cam\n");
1766 return -ENOMEM;
1767 }
1768 skb_put(skb, len);
1769 h2c = (struct rtw89_h2c_dctlinfo_ud_v1 *)skb->data;
1770
1771 rtw89_cam_fill_dctl_sec_cam_info_v1(rtwdev, rtwvif, rtwsta, h2c);
1772
1773 rtw89_h2c_pkt_set_hdr(rtwdev, skb, FWCMD_TYPE_H2C,
1774 H2C_CAT_MAC,
1775 H2C_CL_MAC_FR_EXCHG,
1776 H2C_FUNC_MAC_DCTLINFO_UD_V1, 0, 0,
1777 len);
1778
1779 ret = rtw89_h2c_tx(rtwdev, skb, false);
1780 if (ret) {
1781 rtw89_err(rtwdev, "failed to send h2c\n");
1782 goto fail;
1783 }
1784
1785 return 0;
1786 fail:
1787 dev_kfree_skb_any(skb);
1788
1789 return ret;
1790 }
1791 EXPORT_SYMBOL(rtw89_fw_h2c_dctl_sec_cam_v1);
1792
rtw89_fw_h2c_dctl_sec_cam_v2(struct rtw89_dev * rtwdev,struct rtw89_vif * rtwvif,struct rtw89_sta * rtwsta)1793 int rtw89_fw_h2c_dctl_sec_cam_v2(struct rtw89_dev *rtwdev,
1794 struct rtw89_vif *rtwvif,
1795 struct rtw89_sta *rtwsta)
1796 {
1797 struct rtw89_h2c_dctlinfo_ud_v2 *h2c;
1798 u32 len = sizeof(*h2c);
1799 struct sk_buff *skb;
1800 int ret;
1801
1802 skb = rtw89_fw_h2c_alloc_skb_with_hdr(rtwdev, len);
1803 if (!skb) {
1804 rtw89_err(rtwdev, "failed to alloc skb for dctl sec cam\n");
1805 return -ENOMEM;
1806 }
1807 skb_put(skb, len);
1808 h2c = (struct rtw89_h2c_dctlinfo_ud_v2 *)skb->data;
1809
1810 rtw89_cam_fill_dctl_sec_cam_info_v2(rtwdev, rtwvif, rtwsta, h2c);
1811
1812 rtw89_h2c_pkt_set_hdr(rtwdev, skb, FWCMD_TYPE_H2C,
1813 H2C_CAT_MAC,
1814 H2C_CL_MAC_FR_EXCHG,
1815 H2C_FUNC_MAC_DCTLINFO_UD_V2, 0, 0,
1816 len);
1817
1818 ret = rtw89_h2c_tx(rtwdev, skb, false);
1819 if (ret) {
1820 rtw89_err(rtwdev, "failed to send h2c\n");
1821 goto fail;
1822 }
1823
1824 return 0;
1825 fail:
1826 dev_kfree_skb_any(skb);
1827
1828 return ret;
1829 }
1830 EXPORT_SYMBOL(rtw89_fw_h2c_dctl_sec_cam_v2);
1831
rtw89_fw_h2c_default_dmac_tbl_v2(struct rtw89_dev * rtwdev,struct rtw89_vif * rtwvif,struct rtw89_sta * rtwsta)1832 int rtw89_fw_h2c_default_dmac_tbl_v2(struct rtw89_dev *rtwdev,
1833 struct rtw89_vif *rtwvif,
1834 struct rtw89_sta *rtwsta)
1835 {
1836 u8 mac_id = rtwsta ? rtwsta->mac_id : rtwvif->mac_id;
1837 struct rtw89_h2c_dctlinfo_ud_v2 *h2c;
1838 u32 len = sizeof(*h2c);
1839 struct sk_buff *skb;
1840 int ret;
1841
1842 skb = rtw89_fw_h2c_alloc_skb_with_hdr(rtwdev, len);
1843 if (!skb) {
1844 rtw89_err(rtwdev, "failed to alloc skb for dctl v2\n");
1845 return -ENOMEM;
1846 }
1847 skb_put(skb, len);
1848 h2c = (struct rtw89_h2c_dctlinfo_ud_v2 *)skb->data;
1849
1850 h2c->c0 = le32_encode_bits(mac_id, DCTLINFO_V2_C0_MACID) |
1851 le32_encode_bits(1, DCTLINFO_V2_C0_OP);
1852
1853 h2c->m0 = cpu_to_le32(DCTLINFO_V2_W0_ALL);
1854 h2c->m1 = cpu_to_le32(DCTLINFO_V2_W1_ALL);
1855 h2c->m2 = cpu_to_le32(DCTLINFO_V2_W2_ALL);
1856 h2c->m3 = cpu_to_le32(DCTLINFO_V2_W3_ALL);
1857 h2c->m4 = cpu_to_le32(DCTLINFO_V2_W4_ALL);
1858 h2c->m5 = cpu_to_le32(DCTLINFO_V2_W5_ALL);
1859 h2c->m6 = cpu_to_le32(DCTLINFO_V2_W6_ALL);
1860 h2c->m7 = cpu_to_le32(DCTLINFO_V2_W7_ALL);
1861 h2c->m8 = cpu_to_le32(DCTLINFO_V2_W8_ALL);
1862 h2c->m9 = cpu_to_le32(DCTLINFO_V2_W9_ALL);
1863 h2c->m10 = cpu_to_le32(DCTLINFO_V2_W10_ALL);
1864 h2c->m11 = cpu_to_le32(DCTLINFO_V2_W11_ALL);
1865 h2c->m12 = cpu_to_le32(DCTLINFO_V2_W12_ALL);
1866
1867 rtw89_h2c_pkt_set_hdr(rtwdev, skb, FWCMD_TYPE_H2C,
1868 H2C_CAT_MAC,
1869 H2C_CL_MAC_FR_EXCHG,
1870 H2C_FUNC_MAC_DCTLINFO_UD_V2, 0, 0,
1871 len);
1872
1873 ret = rtw89_h2c_tx(rtwdev, skb, false);
1874 if (ret) {
1875 rtw89_err(rtwdev, "failed to send h2c\n");
1876 goto fail;
1877 }
1878
1879 return 0;
1880 fail:
1881 dev_kfree_skb_any(skb);
1882
1883 return ret;
1884 }
1885 EXPORT_SYMBOL(rtw89_fw_h2c_default_dmac_tbl_v2);
1886
rtw89_fw_h2c_ba_cam(struct rtw89_dev * rtwdev,struct rtw89_sta * rtwsta,bool valid,struct ieee80211_ampdu_params * params)1887 int rtw89_fw_h2c_ba_cam(struct rtw89_dev *rtwdev, struct rtw89_sta *rtwsta,
1888 bool valid, struct ieee80211_ampdu_params *params)
1889 {
1890 const struct rtw89_chip_info *chip = rtwdev->chip;
1891 struct rtw89_vif *rtwvif = rtwsta->rtwvif;
1892 struct rtw89_h2c_ba_cam *h2c;
1893 u8 macid = rtwsta->mac_id;
1894 u32 len = sizeof(*h2c);
1895 struct sk_buff *skb;
1896 u8 entry_idx;
1897 int ret;
1898
1899 ret = valid ?
1900 rtw89_core_acquire_sta_ba_entry(rtwdev, rtwsta, params->tid, &entry_idx) :
1901 rtw89_core_release_sta_ba_entry(rtwdev, rtwsta, params->tid, &entry_idx);
1902 if (ret) {
1903 /* it still works even if we don't have static BA CAM, because
1904 * hardware can create dynamic BA CAM automatically.
1905 */
1906 rtw89_debug(rtwdev, RTW89_DBG_TXRX,
1907 "failed to %s entry tid=%d for h2c ba cam\n",
1908 valid ? "alloc" : "free", params->tid);
1909 return 0;
1910 }
1911
1912 skb = rtw89_fw_h2c_alloc_skb_with_hdr(rtwdev, len);
1913 if (!skb) {
1914 rtw89_err(rtwdev, "failed to alloc skb for h2c ba cam\n");
1915 return -ENOMEM;
1916 }
1917 skb_put(skb, len);
1918 h2c = (struct rtw89_h2c_ba_cam *)skb->data;
1919
1920 h2c->w0 = le32_encode_bits(macid, RTW89_H2C_BA_CAM_W0_MACID);
1921 if (chip->bacam_ver == RTW89_BACAM_V0_EXT)
1922 h2c->w1 |= le32_encode_bits(entry_idx, RTW89_H2C_BA_CAM_W1_ENTRY_IDX_V1);
1923 else
1924 h2c->w0 |= le32_encode_bits(entry_idx, RTW89_H2C_BA_CAM_W0_ENTRY_IDX);
1925 if (!valid)
1926 goto end;
1927 h2c->w0 |= le32_encode_bits(valid, RTW89_H2C_BA_CAM_W0_VALID) |
1928 le32_encode_bits(params->tid, RTW89_H2C_BA_CAM_W0_TID);
1929 if (params->buf_size > 64)
1930 h2c->w0 |= le32_encode_bits(4, RTW89_H2C_BA_CAM_W0_BMAP_SIZE);
1931 else
1932 h2c->w0 |= le32_encode_bits(0, RTW89_H2C_BA_CAM_W0_BMAP_SIZE);
1933 /* If init req is set, hw will set the ssn */
1934 h2c->w0 |= le32_encode_bits(1, RTW89_H2C_BA_CAM_W0_INIT_REQ) |
1935 le32_encode_bits(params->ssn, RTW89_H2C_BA_CAM_W0_SSN);
1936
1937 if (chip->bacam_ver == RTW89_BACAM_V0_EXT) {
1938 h2c->w1 |= le32_encode_bits(1, RTW89_H2C_BA_CAM_W1_STD_EN) |
1939 le32_encode_bits(rtwvif->mac_idx, RTW89_H2C_BA_CAM_W1_BAND);
1940 }
1941
1942 end:
1943 rtw89_h2c_pkt_set_hdr(rtwdev, skb, FWCMD_TYPE_H2C,
1944 H2C_CAT_MAC,
1945 H2C_CL_BA_CAM,
1946 H2C_FUNC_MAC_BA_CAM, 0, 1,
1947 len);
1948
1949 ret = rtw89_h2c_tx(rtwdev, skb, false);
1950 if (ret) {
1951 rtw89_err(rtwdev, "failed to send h2c\n");
1952 goto fail;
1953 }
1954
1955 return 0;
1956 fail:
1957 dev_kfree_skb_any(skb);
1958
1959 return ret;
1960 }
1961 EXPORT_SYMBOL(rtw89_fw_h2c_ba_cam);
1962
rtw89_fw_h2c_init_ba_cam_v0_ext(struct rtw89_dev * rtwdev,u8 entry_idx,u8 uid)1963 static int rtw89_fw_h2c_init_ba_cam_v0_ext(struct rtw89_dev *rtwdev,
1964 u8 entry_idx, u8 uid)
1965 {
1966 struct rtw89_h2c_ba_cam *h2c;
1967 u32 len = sizeof(*h2c);
1968 struct sk_buff *skb;
1969 int ret;
1970
1971 skb = rtw89_fw_h2c_alloc_skb_with_hdr(rtwdev, len);
1972 if (!skb) {
1973 rtw89_err(rtwdev, "failed to alloc skb for dynamic h2c ba cam\n");
1974 return -ENOMEM;
1975 }
1976 skb_put(skb, len);
1977 h2c = (struct rtw89_h2c_ba_cam *)skb->data;
1978
1979 h2c->w0 = le32_encode_bits(1, RTW89_H2C_BA_CAM_W0_VALID);
1980 h2c->w1 = le32_encode_bits(entry_idx, RTW89_H2C_BA_CAM_W1_ENTRY_IDX_V1) |
1981 le32_encode_bits(uid, RTW89_H2C_BA_CAM_W1_UID) |
1982 le32_encode_bits(0, RTW89_H2C_BA_CAM_W1_BAND) |
1983 le32_encode_bits(0, RTW89_H2C_BA_CAM_W1_STD_EN);
1984
1985 rtw89_h2c_pkt_set_hdr(rtwdev, skb, FWCMD_TYPE_H2C,
1986 H2C_CAT_MAC,
1987 H2C_CL_BA_CAM,
1988 H2C_FUNC_MAC_BA_CAM, 0, 1,
1989 len);
1990
1991 ret = rtw89_h2c_tx(rtwdev, skb, false);
1992 if (ret) {
1993 rtw89_err(rtwdev, "failed to send h2c\n");
1994 goto fail;
1995 }
1996
1997 return 0;
1998 fail:
1999 dev_kfree_skb_any(skb);
2000
2001 return ret;
2002 }
2003
rtw89_fw_h2c_init_dynamic_ba_cam_v0_ext(struct rtw89_dev * rtwdev)2004 void rtw89_fw_h2c_init_dynamic_ba_cam_v0_ext(struct rtw89_dev *rtwdev)
2005 {
2006 const struct rtw89_chip_info *chip = rtwdev->chip;
2007 u8 entry_idx = chip->bacam_num;
2008 u8 uid = 0;
2009 int i;
2010
2011 for (i = 0; i < chip->bacam_dynamic_num; i++) {
2012 rtw89_fw_h2c_init_ba_cam_v0_ext(rtwdev, entry_idx, uid);
2013 entry_idx++;
2014 uid++;
2015 }
2016 }
2017
rtw89_fw_h2c_ba_cam_v1(struct rtw89_dev * rtwdev,struct rtw89_sta * rtwsta,bool valid,struct ieee80211_ampdu_params * params)2018 int rtw89_fw_h2c_ba_cam_v1(struct rtw89_dev *rtwdev, struct rtw89_sta *rtwsta,
2019 bool valid, struct ieee80211_ampdu_params *params)
2020 {
2021 const struct rtw89_chip_info *chip = rtwdev->chip;
2022 struct rtw89_vif *rtwvif = rtwsta->rtwvif;
2023 struct rtw89_h2c_ba_cam_v1 *h2c;
2024 u8 macid = rtwsta->mac_id;
2025 u32 len = sizeof(*h2c);
2026 struct sk_buff *skb;
2027 u8 entry_idx;
2028 u8 bmap_size;
2029 int ret;
2030
2031 ret = valid ?
2032 rtw89_core_acquire_sta_ba_entry(rtwdev, rtwsta, params->tid, &entry_idx) :
2033 rtw89_core_release_sta_ba_entry(rtwdev, rtwsta, params->tid, &entry_idx);
2034 if (ret) {
2035 /* it still works even if we don't have static BA CAM, because
2036 * hardware can create dynamic BA CAM automatically.
2037 */
2038 rtw89_debug(rtwdev, RTW89_DBG_TXRX,
2039 "failed to %s entry tid=%d for h2c ba cam\n",
2040 valid ? "alloc" : "free", params->tid);
2041 return 0;
2042 }
2043
2044 skb = rtw89_fw_h2c_alloc_skb_with_hdr(rtwdev, len);
2045 if (!skb) {
2046 rtw89_err(rtwdev, "failed to alloc skb for h2c ba cam\n");
2047 return -ENOMEM;
2048 }
2049 skb_put(skb, len);
2050 h2c = (struct rtw89_h2c_ba_cam_v1 *)skb->data;
2051
2052 if (params->buf_size > 512)
2053 bmap_size = 10;
2054 else if (params->buf_size > 256)
2055 bmap_size = 8;
2056 else if (params->buf_size > 64)
2057 bmap_size = 4;
2058 else
2059 bmap_size = 0;
2060
2061 h2c->w0 = le32_encode_bits(valid, RTW89_H2C_BA_CAM_V1_W0_VALID) |
2062 le32_encode_bits(1, RTW89_H2C_BA_CAM_V1_W0_INIT_REQ) |
2063 le32_encode_bits(macid, RTW89_H2C_BA_CAM_V1_W0_MACID_MASK) |
2064 le32_encode_bits(params->tid, RTW89_H2C_BA_CAM_V1_W0_TID_MASK) |
2065 le32_encode_bits(bmap_size, RTW89_H2C_BA_CAM_V1_W0_BMAP_SIZE_MASK) |
2066 le32_encode_bits(params->ssn, RTW89_H2C_BA_CAM_V1_W0_SSN_MASK);
2067
2068 entry_idx += chip->bacam_dynamic_num; /* std entry right after dynamic ones */
2069 h2c->w1 = le32_encode_bits(entry_idx, RTW89_H2C_BA_CAM_V1_W1_ENTRY_IDX_MASK) |
2070 le32_encode_bits(1, RTW89_H2C_BA_CAM_V1_W1_STD_ENTRY_EN) |
2071 le32_encode_bits(!!rtwvif->mac_idx, RTW89_H2C_BA_CAM_V1_W1_BAND_SEL);
2072
2073 rtw89_h2c_pkt_set_hdr(rtwdev, skb, FWCMD_TYPE_H2C,
2074 H2C_CAT_MAC,
2075 H2C_CL_BA_CAM,
2076 H2C_FUNC_MAC_BA_CAM_V1, 0, 1,
2077 len);
2078
2079 ret = rtw89_h2c_tx(rtwdev, skb, false);
2080 if (ret) {
2081 rtw89_err(rtwdev, "failed to send h2c\n");
2082 goto fail;
2083 }
2084
2085 return 0;
2086 fail:
2087 dev_kfree_skb_any(skb);
2088
2089 return ret;
2090 }
2091 EXPORT_SYMBOL(rtw89_fw_h2c_ba_cam_v1);
2092
rtw89_fw_h2c_init_ba_cam_users(struct rtw89_dev * rtwdev,u8 users,u8 offset,u8 mac_idx)2093 int rtw89_fw_h2c_init_ba_cam_users(struct rtw89_dev *rtwdev, u8 users,
2094 u8 offset, u8 mac_idx)
2095 {
2096 struct rtw89_h2c_ba_cam_init *h2c;
2097 u32 len = sizeof(*h2c);
2098 struct sk_buff *skb;
2099 int ret;
2100
2101 skb = rtw89_fw_h2c_alloc_skb_with_hdr(rtwdev, len);
2102 if (!skb) {
2103 rtw89_err(rtwdev, "failed to alloc skb for h2c ba cam init\n");
2104 return -ENOMEM;
2105 }
2106 skb_put(skb, len);
2107 h2c = (struct rtw89_h2c_ba_cam_init *)skb->data;
2108
2109 h2c->w0 = le32_encode_bits(users, RTW89_H2C_BA_CAM_INIT_USERS_MASK) |
2110 le32_encode_bits(offset, RTW89_H2C_BA_CAM_INIT_OFFSET_MASK) |
2111 le32_encode_bits(mac_idx, RTW89_H2C_BA_CAM_INIT_BAND_SEL);
2112
2113 rtw89_h2c_pkt_set_hdr(rtwdev, skb, FWCMD_TYPE_H2C,
2114 H2C_CAT_MAC,
2115 H2C_CL_BA_CAM,
2116 H2C_FUNC_MAC_BA_CAM_INIT, 0, 1,
2117 len);
2118
2119 ret = rtw89_h2c_tx(rtwdev, skb, false);
2120 if (ret) {
2121 rtw89_err(rtwdev, "failed to send h2c\n");
2122 goto fail;
2123 }
2124
2125 return 0;
2126 fail:
2127 dev_kfree_skb_any(skb);
2128
2129 return ret;
2130 }
2131
2132 #define H2C_LOG_CFG_LEN 12
rtw89_fw_h2c_fw_log(struct rtw89_dev * rtwdev,bool enable)2133 int rtw89_fw_h2c_fw_log(struct rtw89_dev *rtwdev, bool enable)
2134 {
2135 struct sk_buff *skb;
2136 u32 comp = 0;
2137 int ret;
2138
2139 if (enable)
2140 comp = BIT(RTW89_FW_LOG_COMP_INIT) | BIT(RTW89_FW_LOG_COMP_TASK) |
2141 BIT(RTW89_FW_LOG_COMP_PS) | BIT(RTW89_FW_LOG_COMP_ERROR) |
2142 BIT(RTW89_FW_LOG_COMP_SCAN);
2143
2144 skb = rtw89_fw_h2c_alloc_skb_with_hdr(rtwdev, H2C_LOG_CFG_LEN);
2145 if (!skb) {
2146 rtw89_err(rtwdev, "failed to alloc skb for fw log cfg\n");
2147 return -ENOMEM;
2148 }
2149
2150 skb_put(skb, H2C_LOG_CFG_LEN);
2151 SET_LOG_CFG_LEVEL(skb->data, RTW89_FW_LOG_LEVEL_LOUD);
2152 SET_LOG_CFG_PATH(skb->data, BIT(RTW89_FW_LOG_LEVEL_C2H));
2153 SET_LOG_CFG_COMP(skb->data, comp);
2154 SET_LOG_CFG_COMP_EXT(skb->data, 0);
2155
2156 rtw89_h2c_pkt_set_hdr(rtwdev, skb, FWCMD_TYPE_H2C,
2157 H2C_CAT_MAC,
2158 H2C_CL_FW_INFO,
2159 H2C_FUNC_LOG_CFG, 0, 0,
2160 H2C_LOG_CFG_LEN);
2161
2162 ret = rtw89_h2c_tx(rtwdev, skb, false);
2163 if (ret) {
2164 rtw89_err(rtwdev, "failed to send h2c\n");
2165 goto fail;
2166 }
2167
2168 return 0;
2169 fail:
2170 dev_kfree_skb_any(skb);
2171
2172 return ret;
2173 }
2174
rtw89_eapol_get(struct rtw89_dev * rtwdev,struct rtw89_vif * rtwvif)2175 static struct sk_buff *rtw89_eapol_get(struct rtw89_dev *rtwdev,
2176 struct rtw89_vif *rtwvif)
2177 {
2178 static const u8 gtkbody[] = {0xAA, 0xAA, 0x03, 0x00, 0x00, 0x00, 0x88,
2179 0x8E, 0x01, 0x03, 0x00, 0x5F, 0x02, 0x03};
2180 struct ieee80211_vif *vif = rtwvif_to_vif(rtwvif);
2181 struct ieee80211_bss_conf *bss_conf = &vif->bss_conf;
2182 struct rtw89_wow_param *rtw_wow = &rtwdev->wow;
2183 struct rtw89_eapol_2_of_2 *eapol_pkt;
2184 struct sk_buff *skb;
2185 u8 key_des_ver;
2186
2187 if (rtw_wow->ptk_alg == 3)
2188 key_des_ver = 1;
2189 else if (rtw_wow->akm == 1 || rtw_wow->akm == 2)
2190 key_des_ver = 2;
2191 else if (rtw_wow->akm > 2 && rtw_wow->akm < 7)
2192 key_des_ver = 3;
2193 else
2194 key_des_ver = 0;
2195
2196 skb = dev_alloc_skb(sizeof(*eapol_pkt));
2197 if (!skb)
2198 return NULL;
2199
2200 eapol_pkt = skb_put_zero(skb, sizeof(*eapol_pkt));
2201 eapol_pkt->hdr.frame_control = cpu_to_le16(IEEE80211_FTYPE_DATA |
2202 IEEE80211_FCTL_TODS |
2203 IEEE80211_FCTL_PROTECTED);
2204 ether_addr_copy(eapol_pkt->hdr.addr1, bss_conf->bssid);
2205 ether_addr_copy(eapol_pkt->hdr.addr2, vif->addr);
2206 ether_addr_copy(eapol_pkt->hdr.addr3, bss_conf->bssid);
2207 memcpy(eapol_pkt->gtkbody, gtkbody, sizeof(gtkbody));
2208 eapol_pkt->key_des_ver = key_des_ver;
2209
2210 return skb;
2211 }
2212
rtw89_sa_query_get(struct rtw89_dev * rtwdev,struct rtw89_vif * rtwvif)2213 static struct sk_buff *rtw89_sa_query_get(struct rtw89_dev *rtwdev,
2214 struct rtw89_vif *rtwvif)
2215 {
2216 struct ieee80211_vif *vif = rtwvif_to_vif(rtwvif);
2217 struct ieee80211_bss_conf *bss_conf = &vif->bss_conf;
2218 struct rtw89_sa_query *sa_query;
2219 struct sk_buff *skb;
2220
2221 skb = dev_alloc_skb(sizeof(*sa_query));
2222 if (!skb)
2223 return NULL;
2224
2225 sa_query = skb_put_zero(skb, sizeof(*sa_query));
2226 sa_query->hdr.frame_control = cpu_to_le16(IEEE80211_FTYPE_MGMT |
2227 IEEE80211_STYPE_ACTION |
2228 IEEE80211_FCTL_PROTECTED);
2229 ether_addr_copy(sa_query->hdr.addr1, bss_conf->bssid);
2230 ether_addr_copy(sa_query->hdr.addr2, vif->addr);
2231 ether_addr_copy(sa_query->hdr.addr3, bss_conf->bssid);
2232 sa_query->category = WLAN_CATEGORY_SA_QUERY;
2233 sa_query->action = WLAN_ACTION_SA_QUERY_RESPONSE;
2234
2235 return skb;
2236 }
2237
rtw89_arp_response_get(struct rtw89_dev * rtwdev,struct rtw89_vif * rtwvif)2238 static struct sk_buff *rtw89_arp_response_get(struct rtw89_dev *rtwdev,
2239 struct rtw89_vif *rtwvif)
2240 {
2241 struct rtw89_wow_param *rtw_wow = &rtwdev->wow;
2242 struct rtw89_arp_rsp *arp_skb;
2243 struct arphdr *arp_hdr;
2244 struct sk_buff *skb;
2245 __le16 fc;
2246
2247 skb = dev_alloc_skb(sizeof(struct rtw89_arp_rsp));
2248 if (!skb)
2249 return NULL;
2250
2251 arp_skb = skb_put_zero(skb, sizeof(*arp_skb));
2252
2253 if (rtw_wow->ptk_alg)
2254 fc = cpu_to_le16(IEEE80211_FTYPE_DATA | IEEE80211_FCTL_TODS |
2255 IEEE80211_FCTL_PROTECTED);
2256 else
2257 fc = cpu_to_le16(IEEE80211_FTYPE_DATA | IEEE80211_FCTL_TODS);
2258
2259 arp_skb->addr.frame_control = fc;
2260 ether_addr_copy(arp_skb->addr.addr1, rtwvif->bssid);
2261 ether_addr_copy(arp_skb->addr.addr2, rtwvif->mac_addr);
2262 ether_addr_copy(arp_skb->addr.addr3, rtwvif->bssid);
2263
2264 memcpy(arp_skb->llc_hdr, rfc1042_header, sizeof(rfc1042_header));
2265 arp_skb->llc_type = htons(ETH_P_ARP);
2266
2267 arp_hdr = &arp_skb->arp_hdr;
2268 arp_hdr->ar_hrd = htons(ARPHRD_ETHER);
2269 arp_hdr->ar_pro = htons(ETH_P_IP);
2270 arp_hdr->ar_hln = ETH_ALEN;
2271 arp_hdr->ar_pln = 4;
2272 arp_hdr->ar_op = htons(ARPOP_REPLY);
2273
2274 ether_addr_copy(arp_skb->sender_hw, rtwvif->mac_addr);
2275 arp_skb->sender_ip = rtwvif->ip_addr;
2276
2277 return skb;
2278 }
2279
rtw89_fw_h2c_add_general_pkt(struct rtw89_dev * rtwdev,struct rtw89_vif * rtwvif,enum rtw89_fw_pkt_ofld_type type,u8 * id)2280 static int rtw89_fw_h2c_add_general_pkt(struct rtw89_dev *rtwdev,
2281 struct rtw89_vif *rtwvif,
2282 enum rtw89_fw_pkt_ofld_type type,
2283 u8 *id)
2284 {
2285 struct ieee80211_vif *vif = rtwvif_to_vif(rtwvif);
2286 struct rtw89_pktofld_info *info;
2287 struct sk_buff *skb;
2288 int ret;
2289
2290 info = kzalloc(sizeof(*info), GFP_KERNEL);
2291 if (!info)
2292 return -ENOMEM;
2293
2294 switch (type) {
2295 case RTW89_PKT_OFLD_TYPE_PS_POLL:
2296 skb = ieee80211_pspoll_get(rtwdev->hw, vif);
2297 break;
2298 case RTW89_PKT_OFLD_TYPE_PROBE_RSP:
2299 skb = ieee80211_proberesp_get(rtwdev->hw, vif);
2300 break;
2301 case RTW89_PKT_OFLD_TYPE_NULL_DATA:
2302 skb = ieee80211_nullfunc_get(rtwdev->hw, vif, -1, false);
2303 break;
2304 case RTW89_PKT_OFLD_TYPE_QOS_NULL:
2305 skb = ieee80211_nullfunc_get(rtwdev->hw, vif, -1, true);
2306 break;
2307 case RTW89_PKT_OFLD_TYPE_EAPOL_KEY:
2308 skb = rtw89_eapol_get(rtwdev, rtwvif);
2309 break;
2310 case RTW89_PKT_OFLD_TYPE_SA_QUERY:
2311 skb = rtw89_sa_query_get(rtwdev, rtwvif);
2312 break;
2313 case RTW89_PKT_OFLD_TYPE_ARP_RSP:
2314 skb = rtw89_arp_response_get(rtwdev, rtwvif);
2315 break;
2316 default:
2317 goto err;
2318 }
2319
2320 if (!skb)
2321 goto err;
2322
2323 ret = rtw89_fw_h2c_add_pkt_offload(rtwdev, &info->id, skb);
2324 kfree_skb(skb);
2325
2326 if (ret)
2327 goto err;
2328
2329 list_add_tail(&info->list, &rtwvif->general_pkt_list);
2330 *id = info->id;
2331 return 0;
2332
2333 err:
2334 kfree(info);
2335 return -ENOMEM;
2336 }
2337
rtw89_fw_release_general_pkt_list_vif(struct rtw89_dev * rtwdev,struct rtw89_vif * rtwvif,bool notify_fw)2338 void rtw89_fw_release_general_pkt_list_vif(struct rtw89_dev *rtwdev,
2339 struct rtw89_vif *rtwvif, bool notify_fw)
2340 {
2341 struct list_head *pkt_list = &rtwvif->general_pkt_list;
2342 struct rtw89_pktofld_info *info, *tmp;
2343
2344 list_for_each_entry_safe(info, tmp, pkt_list, list) {
2345 if (notify_fw)
2346 rtw89_fw_h2c_del_pkt_offload(rtwdev, info->id);
2347 else
2348 rtw89_core_release_bit_map(rtwdev->pkt_offload, info->id);
2349 list_del(&info->list);
2350 kfree(info);
2351 }
2352 }
2353
rtw89_fw_release_general_pkt_list(struct rtw89_dev * rtwdev,bool notify_fw)2354 void rtw89_fw_release_general_pkt_list(struct rtw89_dev *rtwdev, bool notify_fw)
2355 {
2356 struct rtw89_vif *rtwvif;
2357
2358 rtw89_for_each_rtwvif(rtwdev, rtwvif)
2359 rtw89_fw_release_general_pkt_list_vif(rtwdev, rtwvif, notify_fw);
2360 }
2361
2362 #define H2C_GENERAL_PKT_LEN 6
2363 #define H2C_GENERAL_PKT_ID_UND 0xff
rtw89_fw_h2c_general_pkt(struct rtw89_dev * rtwdev,struct rtw89_vif * rtwvif,u8 macid)2364 int rtw89_fw_h2c_general_pkt(struct rtw89_dev *rtwdev,
2365 struct rtw89_vif *rtwvif, u8 macid)
2366 {
2367 u8 pkt_id_ps_poll = H2C_GENERAL_PKT_ID_UND;
2368 u8 pkt_id_null = H2C_GENERAL_PKT_ID_UND;
2369 u8 pkt_id_qos_null = H2C_GENERAL_PKT_ID_UND;
2370 struct sk_buff *skb;
2371 int ret;
2372
2373 rtw89_fw_h2c_add_general_pkt(rtwdev, rtwvif,
2374 RTW89_PKT_OFLD_TYPE_PS_POLL, &pkt_id_ps_poll);
2375 rtw89_fw_h2c_add_general_pkt(rtwdev, rtwvif,
2376 RTW89_PKT_OFLD_TYPE_NULL_DATA, &pkt_id_null);
2377 rtw89_fw_h2c_add_general_pkt(rtwdev, rtwvif,
2378 RTW89_PKT_OFLD_TYPE_QOS_NULL, &pkt_id_qos_null);
2379
2380 skb = rtw89_fw_h2c_alloc_skb_with_hdr(rtwdev, H2C_GENERAL_PKT_LEN);
2381 if (!skb) {
2382 rtw89_err(rtwdev, "failed to alloc skb for fw dl\n");
2383 return -ENOMEM;
2384 }
2385 skb_put(skb, H2C_GENERAL_PKT_LEN);
2386 SET_GENERAL_PKT_MACID(skb->data, macid);
2387 SET_GENERAL_PKT_PROBRSP_ID(skb->data, H2C_GENERAL_PKT_ID_UND);
2388 SET_GENERAL_PKT_PSPOLL_ID(skb->data, pkt_id_ps_poll);
2389 SET_GENERAL_PKT_NULL_ID(skb->data, pkt_id_null);
2390 SET_GENERAL_PKT_QOS_NULL_ID(skb->data, pkt_id_qos_null);
2391 SET_GENERAL_PKT_CTS2SELF_ID(skb->data, H2C_GENERAL_PKT_ID_UND);
2392
2393 rtw89_h2c_pkt_set_hdr(rtwdev, skb, FWCMD_TYPE_H2C,
2394 H2C_CAT_MAC,
2395 H2C_CL_FW_INFO,
2396 H2C_FUNC_MAC_GENERAL_PKT, 0, 1,
2397 H2C_GENERAL_PKT_LEN);
2398
2399 ret = rtw89_h2c_tx(rtwdev, skb, false);
2400 if (ret) {
2401 rtw89_err(rtwdev, "failed to send h2c\n");
2402 goto fail;
2403 }
2404
2405 return 0;
2406 fail:
2407 dev_kfree_skb_any(skb);
2408
2409 return ret;
2410 }
2411
2412 #define H2C_LPS_PARM_LEN 8
rtw89_fw_h2c_lps_parm(struct rtw89_dev * rtwdev,struct rtw89_lps_parm * lps_param)2413 int rtw89_fw_h2c_lps_parm(struct rtw89_dev *rtwdev,
2414 struct rtw89_lps_parm *lps_param)
2415 {
2416 struct sk_buff *skb;
2417 int ret;
2418
2419 skb = rtw89_fw_h2c_alloc_skb_with_hdr(rtwdev, H2C_LPS_PARM_LEN);
2420 if (!skb) {
2421 rtw89_err(rtwdev, "failed to alloc skb for fw dl\n");
2422 return -ENOMEM;
2423 }
2424 skb_put(skb, H2C_LPS_PARM_LEN);
2425
2426 SET_LPS_PARM_MACID(skb->data, lps_param->macid);
2427 SET_LPS_PARM_PSMODE(skb->data, lps_param->psmode);
2428 SET_LPS_PARM_LASTRPWM(skb->data, lps_param->lastrpwm);
2429 SET_LPS_PARM_RLBM(skb->data, 1);
2430 SET_LPS_PARM_SMARTPS(skb->data, 1);
2431 SET_LPS_PARM_AWAKEINTERVAL(skb->data, 1);
2432 SET_LPS_PARM_VOUAPSD(skb->data, 0);
2433 SET_LPS_PARM_VIUAPSD(skb->data, 0);
2434 SET_LPS_PARM_BEUAPSD(skb->data, 0);
2435 SET_LPS_PARM_BKUAPSD(skb->data, 0);
2436
2437 rtw89_h2c_pkt_set_hdr(rtwdev, skb, FWCMD_TYPE_H2C,
2438 H2C_CAT_MAC,
2439 H2C_CL_MAC_PS,
2440 H2C_FUNC_MAC_LPS_PARM, 0, 1,
2441 H2C_LPS_PARM_LEN);
2442
2443 ret = rtw89_h2c_tx(rtwdev, skb, false);
2444 if (ret) {
2445 rtw89_err(rtwdev, "failed to send h2c\n");
2446 goto fail;
2447 }
2448
2449 return 0;
2450 fail:
2451 dev_kfree_skb_any(skb);
2452
2453 return ret;
2454 }
2455
rtw89_fw_h2c_lps_ch_info(struct rtw89_dev * rtwdev,struct rtw89_vif * rtwvif)2456 int rtw89_fw_h2c_lps_ch_info(struct rtw89_dev *rtwdev, struct rtw89_vif *rtwvif)
2457 {
2458 const struct rtw89_chan *chan = rtw89_chan_get(rtwdev,
2459 rtwvif->sub_entity_idx);
2460 const struct rtw89_chip_info *chip = rtwdev->chip;
2461 struct rtw89_h2c_lps_ch_info *h2c;
2462 u32 len = sizeof(*h2c);
2463 struct sk_buff *skb;
2464 int ret;
2465
2466 if (chip->chip_gen != RTW89_CHIP_BE)
2467 return 0;
2468
2469 skb = rtw89_fw_h2c_alloc_skb_with_hdr(rtwdev, len);
2470 if (!skb) {
2471 rtw89_err(rtwdev, "failed to alloc skb for h2c lps_ch_info\n");
2472 return -ENOMEM;
2473 }
2474 skb_put(skb, len);
2475 h2c = (struct rtw89_h2c_lps_ch_info *)skb->data;
2476
2477 h2c->info[0].central_ch = chan->channel;
2478 h2c->info[0].pri_ch = chan->primary_channel;
2479 h2c->info[0].band = chan->band_type;
2480 h2c->info[0].bw = chan->band_width;
2481 h2c->mlo_dbcc_mode_lps = cpu_to_le32(MLO_2_PLUS_0_1RF);
2482
2483 rtw89_h2c_pkt_set_hdr(rtwdev, skb, FWCMD_TYPE_H2C,
2484 H2C_CAT_OUTSRC, H2C_CL_OUTSRC_DM,
2485 H2C_FUNC_FW_LPS_CH_INFO, 0, 0, len);
2486
2487 ret = rtw89_h2c_tx(rtwdev, skb, false);
2488 if (ret) {
2489 rtw89_err(rtwdev, "failed to send h2c\n");
2490 goto fail;
2491 }
2492
2493 return 0;
2494 fail:
2495 dev_kfree_skb_any(skb);
2496
2497 return ret;
2498 }
2499
2500 #define H2C_P2P_ACT_LEN 20
rtw89_fw_h2c_p2p_act(struct rtw89_dev * rtwdev,struct ieee80211_vif * vif,struct ieee80211_p2p_noa_desc * desc,u8 act,u8 noa_id)2501 int rtw89_fw_h2c_p2p_act(struct rtw89_dev *rtwdev, struct ieee80211_vif *vif,
2502 struct ieee80211_p2p_noa_desc *desc,
2503 u8 act, u8 noa_id)
2504 {
2505 struct rtw89_vif *rtwvif = (struct rtw89_vif *)vif->drv_priv;
2506 bool p2p_type_gc = rtwvif->wifi_role == RTW89_WIFI_ROLE_P2P_CLIENT;
2507 u8 ctwindow_oppps = vif->bss_conf.p2p_noa_attr.oppps_ctwindow;
2508 struct sk_buff *skb;
2509 u8 *cmd;
2510 int ret;
2511
2512 skb = rtw89_fw_h2c_alloc_skb_with_hdr(rtwdev, H2C_P2P_ACT_LEN);
2513 if (!skb) {
2514 rtw89_err(rtwdev, "failed to alloc skb for h2c p2p act\n");
2515 return -ENOMEM;
2516 }
2517 skb_put(skb, H2C_P2P_ACT_LEN);
2518 cmd = skb->data;
2519
2520 RTW89_SET_FWCMD_P2P_MACID(cmd, rtwvif->mac_id);
2521 RTW89_SET_FWCMD_P2P_P2PID(cmd, 0);
2522 RTW89_SET_FWCMD_P2P_NOAID(cmd, noa_id);
2523 RTW89_SET_FWCMD_P2P_ACT(cmd, act);
2524 RTW89_SET_FWCMD_P2P_TYPE(cmd, p2p_type_gc);
2525 RTW89_SET_FWCMD_P2P_ALL_SLEP(cmd, 0);
2526 if (desc) {
2527 RTW89_SET_FWCMD_NOA_START_TIME(cmd, desc->start_time);
2528 RTW89_SET_FWCMD_NOA_INTERVAL(cmd, desc->interval);
2529 RTW89_SET_FWCMD_NOA_DURATION(cmd, desc->duration);
2530 RTW89_SET_FWCMD_NOA_COUNT(cmd, desc->count);
2531 RTW89_SET_FWCMD_NOA_CTWINDOW(cmd, ctwindow_oppps);
2532 }
2533
2534 rtw89_h2c_pkt_set_hdr(rtwdev, skb, FWCMD_TYPE_H2C,
2535 H2C_CAT_MAC, H2C_CL_MAC_PS,
2536 H2C_FUNC_P2P_ACT, 0, 0,
2537 H2C_P2P_ACT_LEN);
2538
2539 ret = rtw89_h2c_tx(rtwdev, skb, false);
2540 if (ret) {
2541 rtw89_err(rtwdev, "failed to send h2c\n");
2542 goto fail;
2543 }
2544
2545 return 0;
2546 fail:
2547 dev_kfree_skb_any(skb);
2548
2549 return ret;
2550 }
2551
__rtw89_fw_h2c_set_tx_path(struct rtw89_dev * rtwdev,struct sk_buff * skb)2552 static void __rtw89_fw_h2c_set_tx_path(struct rtw89_dev *rtwdev,
2553 struct sk_buff *skb)
2554 {
2555 const struct rtw89_chip_info *chip = rtwdev->chip;
2556 struct rtw89_hal *hal = &rtwdev->hal;
2557 u8 ntx_path;
2558 u8 map_b;
2559
2560 if (chip->rf_path_num == 1) {
2561 ntx_path = RF_A;
2562 map_b = 0;
2563 } else {
2564 ntx_path = hal->antenna_tx ? hal->antenna_tx : RF_B;
2565 map_b = hal->antenna_tx == RF_AB ? 1 : 0;
2566 }
2567
2568 SET_CMC_TBL_NTX_PATH_EN(skb->data, ntx_path);
2569 SET_CMC_TBL_PATH_MAP_A(skb->data, 0);
2570 SET_CMC_TBL_PATH_MAP_B(skb->data, map_b);
2571 SET_CMC_TBL_PATH_MAP_C(skb->data, 0);
2572 SET_CMC_TBL_PATH_MAP_D(skb->data, 0);
2573 }
2574
2575 #define H2C_CMC_TBL_LEN 68
rtw89_fw_h2c_default_cmac_tbl(struct rtw89_dev * rtwdev,struct rtw89_vif * rtwvif,struct rtw89_sta * rtwsta)2576 int rtw89_fw_h2c_default_cmac_tbl(struct rtw89_dev *rtwdev,
2577 struct rtw89_vif *rtwvif,
2578 struct rtw89_sta *rtwsta)
2579 {
2580 const struct rtw89_chip_info *chip = rtwdev->chip;
2581 u8 macid = rtwsta ? rtwsta->mac_id : rtwvif->mac_id;
2582 struct sk_buff *skb;
2583 int ret;
2584
2585 skb = rtw89_fw_h2c_alloc_skb_with_hdr(rtwdev, H2C_CMC_TBL_LEN);
2586 if (!skb) {
2587 rtw89_err(rtwdev, "failed to alloc skb for fw dl\n");
2588 return -ENOMEM;
2589 }
2590 skb_put(skb, H2C_CMC_TBL_LEN);
2591 SET_CTRL_INFO_MACID(skb->data, macid);
2592 SET_CTRL_INFO_OPERATION(skb->data, 1);
2593 if (chip->h2c_cctl_func_id == H2C_FUNC_MAC_CCTLINFO_UD) {
2594 SET_CMC_TBL_TXPWR_MODE(skb->data, 0);
2595 __rtw89_fw_h2c_set_tx_path(rtwdev, skb);
2596 SET_CMC_TBL_ANTSEL_A(skb->data, 0);
2597 SET_CMC_TBL_ANTSEL_B(skb->data, 0);
2598 SET_CMC_TBL_ANTSEL_C(skb->data, 0);
2599 SET_CMC_TBL_ANTSEL_D(skb->data, 0);
2600 }
2601 SET_CMC_TBL_DOPPLER_CTRL(skb->data, 0);
2602 SET_CMC_TBL_TXPWR_TOLERENCE(skb->data, 0);
2603 if (rtwvif->net_type == RTW89_NET_TYPE_AP_MODE)
2604 SET_CMC_TBL_DATA_DCM(skb->data, 0);
2605
2606 rtw89_h2c_pkt_set_hdr(rtwdev, skb, FWCMD_TYPE_H2C,
2607 H2C_CAT_MAC, H2C_CL_MAC_FR_EXCHG,
2608 chip->h2c_cctl_func_id, 0, 1,
2609 H2C_CMC_TBL_LEN);
2610
2611 ret = rtw89_h2c_tx(rtwdev, skb, false);
2612 if (ret) {
2613 rtw89_err(rtwdev, "failed to send h2c\n");
2614 goto fail;
2615 }
2616
2617 return 0;
2618 fail:
2619 dev_kfree_skb_any(skb);
2620
2621 return ret;
2622 }
2623 EXPORT_SYMBOL(rtw89_fw_h2c_default_cmac_tbl);
2624
rtw89_fw_h2c_default_cmac_tbl_g7(struct rtw89_dev * rtwdev,struct rtw89_vif * rtwvif,struct rtw89_sta * rtwsta)2625 int rtw89_fw_h2c_default_cmac_tbl_g7(struct rtw89_dev *rtwdev,
2626 struct rtw89_vif *rtwvif,
2627 struct rtw89_sta *rtwsta)
2628 {
2629 u8 mac_id = rtwsta ? rtwsta->mac_id : rtwvif->mac_id;
2630 struct rtw89_h2c_cctlinfo_ud_g7 *h2c;
2631 u32 len = sizeof(*h2c);
2632 struct sk_buff *skb;
2633 int ret;
2634
2635 skb = rtw89_fw_h2c_alloc_skb_with_hdr(rtwdev, len);
2636 if (!skb) {
2637 rtw89_err(rtwdev, "failed to alloc skb for cmac g7\n");
2638 return -ENOMEM;
2639 }
2640 skb_put(skb, len);
2641 h2c = (struct rtw89_h2c_cctlinfo_ud_g7 *)skb->data;
2642
2643 h2c->c0 = le32_encode_bits(mac_id, CCTLINFO_G7_C0_MACID) |
2644 le32_encode_bits(1, CCTLINFO_G7_C0_OP);
2645
2646 h2c->w0 = le32_encode_bits(4, CCTLINFO_G7_W0_DATARATE);
2647 h2c->m0 = cpu_to_le32(CCTLINFO_G7_W0_ALL);
2648
2649 h2c->w1 = le32_encode_bits(4, CCTLINFO_G7_W1_DATA_RTY_LOWEST_RATE) |
2650 le32_encode_bits(0xa, CCTLINFO_G7_W1_RTSRATE) |
2651 le32_encode_bits(4, CCTLINFO_G7_W1_RTS_RTY_LOWEST_RATE);
2652 h2c->m1 = cpu_to_le32(CCTLINFO_G7_W1_ALL);
2653
2654 h2c->m2 = cpu_to_le32(CCTLINFO_G7_W2_ALL);
2655
2656 h2c->m3 = cpu_to_le32(CCTLINFO_G7_W3_ALL);
2657
2658 h2c->w4 = le32_encode_bits(0xFFFF, CCTLINFO_G7_W4_ACT_SUBCH_CBW);
2659 h2c->m4 = cpu_to_le32(CCTLINFO_G7_W4_ALL);
2660
2661 h2c->w5 = le32_encode_bits(2, CCTLINFO_G7_W5_NOMINAL_PKT_PADDING0) |
2662 le32_encode_bits(2, CCTLINFO_G7_W5_NOMINAL_PKT_PADDING1) |
2663 le32_encode_bits(2, CCTLINFO_G7_W5_NOMINAL_PKT_PADDING2) |
2664 le32_encode_bits(2, CCTLINFO_G7_W5_NOMINAL_PKT_PADDING3) |
2665 le32_encode_bits(2, CCTLINFO_G7_W5_NOMINAL_PKT_PADDING4);
2666 h2c->m5 = cpu_to_le32(CCTLINFO_G7_W5_ALL);
2667
2668 h2c->w6 = le32_encode_bits(0xb, CCTLINFO_G7_W6_RESP_REF_RATE);
2669 h2c->m6 = cpu_to_le32(CCTLINFO_G7_W6_ALL);
2670
2671 h2c->w7 = le32_encode_bits(1, CCTLINFO_G7_W7_NC) |
2672 le32_encode_bits(1, CCTLINFO_G7_W7_NR) |
2673 le32_encode_bits(1, CCTLINFO_G7_W7_CB) |
2674 le32_encode_bits(0x1, CCTLINFO_G7_W7_CSI_PARA_EN) |
2675 le32_encode_bits(0xb, CCTLINFO_G7_W7_CSI_FIX_RATE);
2676 h2c->m7 = cpu_to_le32(CCTLINFO_G7_W7_ALL);
2677
2678 h2c->m8 = cpu_to_le32(CCTLINFO_G7_W8_ALL);
2679
2680 h2c->w14 = le32_encode_bits(0, CCTLINFO_G7_W14_VO_CURR_RATE) |
2681 le32_encode_bits(0, CCTLINFO_G7_W14_VI_CURR_RATE) |
2682 le32_encode_bits(0, CCTLINFO_G7_W14_BE_CURR_RATE_L);
2683 h2c->m14 = cpu_to_le32(CCTLINFO_G7_W14_ALL);
2684
2685 h2c->w15 = le32_encode_bits(0, CCTLINFO_G7_W15_BE_CURR_RATE_H) |
2686 le32_encode_bits(0, CCTLINFO_G7_W15_BK_CURR_RATE) |
2687 le32_encode_bits(0, CCTLINFO_G7_W15_MGNT_CURR_RATE);
2688 h2c->m15 = cpu_to_le32(CCTLINFO_G7_W15_ALL);
2689
2690 rtw89_h2c_pkt_set_hdr(rtwdev, skb, FWCMD_TYPE_H2C,
2691 H2C_CAT_MAC, H2C_CL_MAC_FR_EXCHG,
2692 H2C_FUNC_MAC_CCTLINFO_UD_G7, 0, 1,
2693 len);
2694
2695 ret = rtw89_h2c_tx(rtwdev, skb, false);
2696 if (ret) {
2697 rtw89_err(rtwdev, "failed to send h2c\n");
2698 goto fail;
2699 }
2700
2701 return 0;
2702 fail:
2703 dev_kfree_skb_any(skb);
2704
2705 return ret;
2706 }
2707 EXPORT_SYMBOL(rtw89_fw_h2c_default_cmac_tbl_g7);
2708
__get_sta_he_pkt_padding(struct rtw89_dev * rtwdev,struct ieee80211_sta * sta,u8 * pads)2709 static void __get_sta_he_pkt_padding(struct rtw89_dev *rtwdev,
2710 struct ieee80211_sta *sta, u8 *pads)
2711 {
2712 bool ppe_th;
2713 u8 ppe16, ppe8;
2714 u8 nss = min(sta->deflink.rx_nss, rtwdev->hal.tx_nss) - 1;
2715 u8 ppe_thres_hdr = sta->deflink.he_cap.ppe_thres[0];
2716 u8 ru_bitmap;
2717 u8 n, idx, sh;
2718 u16 ppe;
2719 int i;
2720
2721 ppe_th = FIELD_GET(IEEE80211_HE_PHY_CAP6_PPE_THRESHOLD_PRESENT,
2722 sta->deflink.he_cap.he_cap_elem.phy_cap_info[6]);
2723 if (!ppe_th) {
2724 u8 pad;
2725
2726 pad = FIELD_GET(IEEE80211_HE_PHY_CAP9_NOMINAL_PKT_PADDING_MASK,
2727 sta->deflink.he_cap.he_cap_elem.phy_cap_info[9]);
2728
2729 for (i = 0; i < RTW89_PPE_BW_NUM; i++)
2730 pads[i] = pad;
2731
2732 return;
2733 }
2734
2735 ru_bitmap = FIELD_GET(IEEE80211_PPE_THRES_RU_INDEX_BITMASK_MASK, ppe_thres_hdr);
2736 n = hweight8(ru_bitmap);
2737 n = 7 + (n * IEEE80211_PPE_THRES_INFO_PPET_SIZE * 2) * nss;
2738
2739 for (i = 0; i < RTW89_PPE_BW_NUM; i++) {
2740 if (!(ru_bitmap & BIT(i))) {
2741 pads[i] = 1;
2742 continue;
2743 }
2744
2745 idx = n >> 3;
2746 sh = n & 7;
2747 n += IEEE80211_PPE_THRES_INFO_PPET_SIZE * 2;
2748
2749 ppe = le16_to_cpu(*((__le16 *)&sta->deflink.he_cap.ppe_thres[idx]));
2750 ppe16 = (ppe >> sh) & IEEE80211_PPE_THRES_NSS_MASK;
2751 sh += IEEE80211_PPE_THRES_INFO_PPET_SIZE;
2752 ppe8 = (ppe >> sh) & IEEE80211_PPE_THRES_NSS_MASK;
2753
2754 if (ppe16 != 7 && ppe8 == 7)
2755 pads[i] = 2;
2756 else if (ppe8 != 7)
2757 pads[i] = 1;
2758 else
2759 pads[i] = 0;
2760 }
2761 }
2762
rtw89_fw_h2c_assoc_cmac_tbl(struct rtw89_dev * rtwdev,struct ieee80211_vif * vif,struct ieee80211_sta * sta)2763 int rtw89_fw_h2c_assoc_cmac_tbl(struct rtw89_dev *rtwdev,
2764 struct ieee80211_vif *vif,
2765 struct ieee80211_sta *sta)
2766 {
2767 const struct rtw89_chip_info *chip = rtwdev->chip;
2768 struct rtw89_sta *rtwsta = sta_to_rtwsta_safe(sta);
2769 struct rtw89_vif *rtwvif = (struct rtw89_vif *)vif->drv_priv;
2770 const struct rtw89_chan *chan = rtw89_chan_get(rtwdev,
2771 rtwvif->sub_entity_idx);
2772 struct sk_buff *skb;
2773 u8 pads[RTW89_PPE_BW_NUM];
2774 u8 mac_id = rtwsta ? rtwsta->mac_id : rtwvif->mac_id;
2775 u16 lowest_rate;
2776 int ret;
2777
2778 memset(pads, 0, sizeof(pads));
2779 if (sta && sta->deflink.he_cap.has_he)
2780 __get_sta_he_pkt_padding(rtwdev, sta, pads);
2781
2782 if (vif->p2p)
2783 lowest_rate = RTW89_HW_RATE_OFDM6;
2784 else if (chan->band_type == RTW89_BAND_2G)
2785 lowest_rate = RTW89_HW_RATE_CCK1;
2786 else
2787 lowest_rate = RTW89_HW_RATE_OFDM6;
2788
2789 skb = rtw89_fw_h2c_alloc_skb_with_hdr(rtwdev, H2C_CMC_TBL_LEN);
2790 if (!skb) {
2791 rtw89_err(rtwdev, "failed to alloc skb for fw dl\n");
2792 return -ENOMEM;
2793 }
2794 skb_put(skb, H2C_CMC_TBL_LEN);
2795 SET_CTRL_INFO_MACID(skb->data, mac_id);
2796 SET_CTRL_INFO_OPERATION(skb->data, 1);
2797 SET_CMC_TBL_DISRTSFB(skb->data, 1);
2798 SET_CMC_TBL_DISDATAFB(skb->data, 1);
2799 SET_CMC_TBL_RTS_RTY_LOWEST_RATE(skb->data, lowest_rate);
2800 SET_CMC_TBL_RTS_TXCNT_LMT_SEL(skb->data, 0);
2801 SET_CMC_TBL_DATA_TXCNT_LMT_SEL(skb->data, 0);
2802 if (vif->type == NL80211_IFTYPE_STATION)
2803 SET_CMC_TBL_ULDL(skb->data, 1);
2804 else
2805 SET_CMC_TBL_ULDL(skb->data, 0);
2806 SET_CMC_TBL_MULTI_PORT_ID(skb->data, rtwvif->port);
2807 if (chip->h2c_cctl_func_id == H2C_FUNC_MAC_CCTLINFO_UD_V1) {
2808 SET_CMC_TBL_NOMINAL_PKT_PADDING_V1(skb->data, pads[RTW89_CHANNEL_WIDTH_20]);
2809 SET_CMC_TBL_NOMINAL_PKT_PADDING40_V1(skb->data, pads[RTW89_CHANNEL_WIDTH_40]);
2810 SET_CMC_TBL_NOMINAL_PKT_PADDING80_V1(skb->data, pads[RTW89_CHANNEL_WIDTH_80]);
2811 SET_CMC_TBL_NOMINAL_PKT_PADDING160_V1(skb->data, pads[RTW89_CHANNEL_WIDTH_160]);
2812 } else if (chip->h2c_cctl_func_id == H2C_FUNC_MAC_CCTLINFO_UD) {
2813 SET_CMC_TBL_NOMINAL_PKT_PADDING(skb->data, pads[RTW89_CHANNEL_WIDTH_20]);
2814 SET_CMC_TBL_NOMINAL_PKT_PADDING40(skb->data, pads[RTW89_CHANNEL_WIDTH_40]);
2815 SET_CMC_TBL_NOMINAL_PKT_PADDING80(skb->data, pads[RTW89_CHANNEL_WIDTH_80]);
2816 SET_CMC_TBL_NOMINAL_PKT_PADDING160(skb->data, pads[RTW89_CHANNEL_WIDTH_160]);
2817 }
2818 if (sta)
2819 SET_CMC_TBL_BSR_QUEUE_SIZE_FORMAT(skb->data,
2820 sta->deflink.he_cap.has_he);
2821 if (rtwvif->net_type == RTW89_NET_TYPE_AP_MODE)
2822 SET_CMC_TBL_DATA_DCM(skb->data, 0);
2823
2824 rtw89_h2c_pkt_set_hdr(rtwdev, skb, FWCMD_TYPE_H2C,
2825 H2C_CAT_MAC, H2C_CL_MAC_FR_EXCHG,
2826 chip->h2c_cctl_func_id, 0, 1,
2827 H2C_CMC_TBL_LEN);
2828
2829 ret = rtw89_h2c_tx(rtwdev, skb, false);
2830 if (ret) {
2831 rtw89_err(rtwdev, "failed to send h2c\n");
2832 goto fail;
2833 }
2834
2835 return 0;
2836 fail:
2837 dev_kfree_skb_any(skb);
2838
2839 return ret;
2840 }
2841 EXPORT_SYMBOL(rtw89_fw_h2c_assoc_cmac_tbl);
2842
__get_sta_eht_pkt_padding(struct rtw89_dev * rtwdev,struct ieee80211_sta * sta,u8 * pads)2843 static void __get_sta_eht_pkt_padding(struct rtw89_dev *rtwdev,
2844 struct ieee80211_sta *sta, u8 *pads)
2845 {
2846 u8 nss = min(sta->deflink.rx_nss, rtwdev->hal.tx_nss) - 1;
2847 u16 ppe_thres_hdr;
2848 u8 ppe16, ppe8;
2849 u8 n, idx, sh;
2850 u8 ru_bitmap;
2851 bool ppe_th;
2852 u16 ppe;
2853 int i;
2854
2855 ppe_th = !!u8_get_bits(sta->deflink.eht_cap.eht_cap_elem.phy_cap_info[5],
2856 IEEE80211_EHT_PHY_CAP5_PPE_THRESHOLD_PRESENT);
2857 if (!ppe_th) {
2858 u8 pad;
2859
2860 pad = u8_get_bits(sta->deflink.eht_cap.eht_cap_elem.phy_cap_info[5],
2861 IEEE80211_EHT_PHY_CAP5_COMMON_NOMINAL_PKT_PAD_MASK);
2862
2863 for (i = 0; i < RTW89_PPE_BW_NUM; i++)
2864 pads[i] = pad;
2865
2866 return;
2867 }
2868
2869 ppe_thres_hdr = get_unaligned_le16(sta->deflink.eht_cap.eht_ppe_thres);
2870 ru_bitmap = u16_get_bits(ppe_thres_hdr,
2871 IEEE80211_EHT_PPE_THRES_RU_INDEX_BITMASK_MASK);
2872 n = hweight8(ru_bitmap);
2873 n = IEEE80211_EHT_PPE_THRES_INFO_HEADER_SIZE +
2874 (n * IEEE80211_EHT_PPE_THRES_INFO_PPET_SIZE * 2) * nss;
2875
2876 for (i = 0; i < RTW89_PPE_BW_NUM; i++) {
2877 if (!(ru_bitmap & BIT(i))) {
2878 pads[i] = 1;
2879 continue;
2880 }
2881
2882 idx = n >> 3;
2883 sh = n & 7;
2884 n += IEEE80211_EHT_PPE_THRES_INFO_PPET_SIZE * 2;
2885
2886 ppe = get_unaligned_le16(sta->deflink.eht_cap.eht_ppe_thres + idx);
2887 ppe16 = (ppe >> sh) & IEEE80211_PPE_THRES_NSS_MASK;
2888 sh += IEEE80211_EHT_PPE_THRES_INFO_PPET_SIZE;
2889 ppe8 = (ppe >> sh) & IEEE80211_PPE_THRES_NSS_MASK;
2890
2891 if (ppe16 != 7 && ppe8 == 7)
2892 pads[i] = 2;
2893 else if (ppe8 != 7)
2894 pads[i] = 1;
2895 else
2896 pads[i] = 0;
2897 }
2898 }
2899
rtw89_fw_h2c_assoc_cmac_tbl_g7(struct rtw89_dev * rtwdev,struct ieee80211_vif * vif,struct ieee80211_sta * sta)2900 int rtw89_fw_h2c_assoc_cmac_tbl_g7(struct rtw89_dev *rtwdev,
2901 struct ieee80211_vif *vif,
2902 struct ieee80211_sta *sta)
2903 {
2904 const struct rtw89_chan *chan = rtw89_chan_get(rtwdev, RTW89_SUB_ENTITY_0);
2905 struct rtw89_vif *rtwvif = (struct rtw89_vif *)vif->drv_priv;
2906 struct rtw89_sta *rtwsta = sta_to_rtwsta_safe(sta);
2907 u8 mac_id = rtwsta ? rtwsta->mac_id : rtwvif->mac_id;
2908 struct rtw89_h2c_cctlinfo_ud_g7 *h2c;
2909 u8 pads[RTW89_PPE_BW_NUM];
2910 u32 len = sizeof(*h2c);
2911 struct sk_buff *skb;
2912 u16 lowest_rate;
2913 int ret;
2914
2915 memset(pads, 0, sizeof(pads));
2916 if (sta) {
2917 if (sta->deflink.eht_cap.has_eht)
2918 __get_sta_eht_pkt_padding(rtwdev, sta, pads);
2919 else if (sta->deflink.he_cap.has_he)
2920 __get_sta_he_pkt_padding(rtwdev, sta, pads);
2921 }
2922
2923 if (vif->p2p)
2924 lowest_rate = RTW89_HW_RATE_OFDM6;
2925 else if (chan->band_type == RTW89_BAND_2G)
2926 lowest_rate = RTW89_HW_RATE_CCK1;
2927 else
2928 lowest_rate = RTW89_HW_RATE_OFDM6;
2929
2930 skb = rtw89_fw_h2c_alloc_skb_with_hdr(rtwdev, len);
2931 if (!skb) {
2932 rtw89_err(rtwdev, "failed to alloc skb for cmac g7\n");
2933 return -ENOMEM;
2934 }
2935 skb_put(skb, len);
2936 h2c = (struct rtw89_h2c_cctlinfo_ud_g7 *)skb->data;
2937
2938 h2c->c0 = le32_encode_bits(mac_id, CCTLINFO_G7_C0_MACID) |
2939 le32_encode_bits(1, CCTLINFO_G7_C0_OP);
2940
2941 h2c->w0 = le32_encode_bits(1, CCTLINFO_G7_W0_DISRTSFB) |
2942 le32_encode_bits(1, CCTLINFO_G7_W0_DISDATAFB);
2943 h2c->m0 = cpu_to_le32(CCTLINFO_G7_W0_DISRTSFB |
2944 CCTLINFO_G7_W0_DISDATAFB);
2945
2946 h2c->w1 = le32_encode_bits(lowest_rate, CCTLINFO_G7_W1_RTS_RTY_LOWEST_RATE);
2947 h2c->m1 = cpu_to_le32(CCTLINFO_G7_W1_RTS_RTY_LOWEST_RATE);
2948
2949 h2c->w2 = le32_encode_bits(0, CCTLINFO_G7_W2_DATA_TXCNT_LMT_SEL);
2950 h2c->m2 = cpu_to_le32(CCTLINFO_G7_W2_DATA_TXCNT_LMT_SEL);
2951
2952 h2c->w3 = le32_encode_bits(0, CCTLINFO_G7_W3_RTS_TXCNT_LMT_SEL);
2953 h2c->m3 = cpu_to_le32(CCTLINFO_G7_W3_RTS_TXCNT_LMT_SEL);
2954
2955 h2c->w4 = le32_encode_bits(rtwvif->port, CCTLINFO_G7_W4_MULTI_PORT_ID);
2956 h2c->m4 = cpu_to_le32(CCTLINFO_G7_W4_MULTI_PORT_ID);
2957
2958 if (rtwvif->net_type == RTW89_NET_TYPE_AP_MODE) {
2959 h2c->w4 |= le32_encode_bits(0, CCTLINFO_G7_W4_DATA_DCM);
2960 h2c->m4 |= cpu_to_le32(CCTLINFO_G7_W4_DATA_DCM);
2961 }
2962
2963 if (vif->bss_conf.eht_support) {
2964 u16 punct = vif->bss_conf.chanreq.oper.punctured;
2965
2966 h2c->w4 |= le32_encode_bits(~punct,
2967 CCTLINFO_G7_W4_ACT_SUBCH_CBW);
2968 h2c->m4 |= cpu_to_le32(CCTLINFO_G7_W4_ACT_SUBCH_CBW);
2969 }
2970
2971 h2c->w5 = le32_encode_bits(pads[RTW89_CHANNEL_WIDTH_20],
2972 CCTLINFO_G7_W5_NOMINAL_PKT_PADDING0) |
2973 le32_encode_bits(pads[RTW89_CHANNEL_WIDTH_40],
2974 CCTLINFO_G7_W5_NOMINAL_PKT_PADDING1) |
2975 le32_encode_bits(pads[RTW89_CHANNEL_WIDTH_80],
2976 CCTLINFO_G7_W5_NOMINAL_PKT_PADDING2) |
2977 le32_encode_bits(pads[RTW89_CHANNEL_WIDTH_160],
2978 CCTLINFO_G7_W5_NOMINAL_PKT_PADDING3) |
2979 le32_encode_bits(pads[RTW89_CHANNEL_WIDTH_320],
2980 CCTLINFO_G7_W5_NOMINAL_PKT_PADDING4);
2981 h2c->m5 = cpu_to_le32(CCTLINFO_G7_W5_NOMINAL_PKT_PADDING0 |
2982 CCTLINFO_G7_W5_NOMINAL_PKT_PADDING1 |
2983 CCTLINFO_G7_W5_NOMINAL_PKT_PADDING2 |
2984 CCTLINFO_G7_W5_NOMINAL_PKT_PADDING3 |
2985 CCTLINFO_G7_W5_NOMINAL_PKT_PADDING4);
2986
2987 h2c->w6 = le32_encode_bits(vif->type == NL80211_IFTYPE_STATION ? 1 : 0,
2988 CCTLINFO_G7_W6_ULDL);
2989 h2c->m6 = cpu_to_le32(CCTLINFO_G7_W6_ULDL);
2990
2991 if (sta) {
2992 h2c->w8 = le32_encode_bits(sta->deflink.he_cap.has_he,
2993 CCTLINFO_G7_W8_BSR_QUEUE_SIZE_FORMAT);
2994 h2c->m8 = cpu_to_le32(CCTLINFO_G7_W8_BSR_QUEUE_SIZE_FORMAT);
2995 }
2996
2997 rtw89_h2c_pkt_set_hdr(rtwdev, skb, FWCMD_TYPE_H2C,
2998 H2C_CAT_MAC, H2C_CL_MAC_FR_EXCHG,
2999 H2C_FUNC_MAC_CCTLINFO_UD_G7, 0, 1,
3000 len);
3001
3002 ret = rtw89_h2c_tx(rtwdev, skb, false);
3003 if (ret) {
3004 rtw89_err(rtwdev, "failed to send h2c\n");
3005 goto fail;
3006 }
3007
3008 return 0;
3009 fail:
3010 dev_kfree_skb_any(skb);
3011
3012 return ret;
3013 }
3014 EXPORT_SYMBOL(rtw89_fw_h2c_assoc_cmac_tbl_g7);
3015
rtw89_fw_h2c_ampdu_cmac_tbl_g7(struct rtw89_dev * rtwdev,struct ieee80211_vif * vif,struct ieee80211_sta * sta)3016 int rtw89_fw_h2c_ampdu_cmac_tbl_g7(struct rtw89_dev *rtwdev,
3017 struct ieee80211_vif *vif,
3018 struct ieee80211_sta *sta)
3019 {
3020 struct rtw89_sta *rtwsta = (struct rtw89_sta *)sta->drv_priv;
3021 struct rtw89_h2c_cctlinfo_ud_g7 *h2c;
3022 u32 len = sizeof(*h2c);
3023 struct sk_buff *skb;
3024 u16 agg_num = 0;
3025 u8 ba_bmap = 0;
3026 int ret;
3027 u8 tid;
3028
3029 skb = rtw89_fw_h2c_alloc_skb_with_hdr(rtwdev, len);
3030 if (!skb) {
3031 rtw89_err(rtwdev, "failed to alloc skb for ampdu cmac g7\n");
3032 return -ENOMEM;
3033 }
3034 skb_put(skb, len);
3035 h2c = (struct rtw89_h2c_cctlinfo_ud_g7 *)skb->data;
3036
3037 for_each_set_bit(tid, rtwsta->ampdu_map, IEEE80211_NUM_TIDS) {
3038 if (agg_num == 0)
3039 agg_num = rtwsta->ampdu_params[tid].agg_num;
3040 else
3041 agg_num = min(agg_num, rtwsta->ampdu_params[tid].agg_num);
3042 }
3043
3044 if (agg_num <= 0x20)
3045 ba_bmap = 3;
3046 else if (agg_num > 0x20 && agg_num <= 0x40)
3047 ba_bmap = 0;
3048 else if (agg_num > 0x40 && agg_num <= 0x80)
3049 ba_bmap = 1;
3050 else if (agg_num > 0x80 && agg_num <= 0x100)
3051 ba_bmap = 2;
3052 else if (agg_num > 0x100 && agg_num <= 0x200)
3053 ba_bmap = 4;
3054 else if (agg_num > 0x200 && agg_num <= 0x400)
3055 ba_bmap = 5;
3056
3057 h2c->c0 = le32_encode_bits(rtwsta->mac_id, CCTLINFO_G7_C0_MACID) |
3058 le32_encode_bits(1, CCTLINFO_G7_C0_OP);
3059
3060 h2c->w3 = le32_encode_bits(ba_bmap, CCTLINFO_G7_W3_BA_BMAP);
3061 h2c->m3 = cpu_to_le32(CCTLINFO_G7_W3_BA_BMAP);
3062
3063 rtw89_h2c_pkt_set_hdr(rtwdev, skb, FWCMD_TYPE_H2C,
3064 H2C_CAT_MAC, H2C_CL_MAC_FR_EXCHG,
3065 H2C_FUNC_MAC_CCTLINFO_UD_G7, 0, 0,
3066 len);
3067
3068 ret = rtw89_h2c_tx(rtwdev, skb, false);
3069 if (ret) {
3070 rtw89_err(rtwdev, "failed to send h2c\n");
3071 goto fail;
3072 }
3073
3074 return 0;
3075 fail:
3076 dev_kfree_skb_any(skb);
3077
3078 return ret;
3079 }
3080 EXPORT_SYMBOL(rtw89_fw_h2c_ampdu_cmac_tbl_g7);
3081
rtw89_fw_h2c_txtime_cmac_tbl(struct rtw89_dev * rtwdev,struct rtw89_sta * rtwsta)3082 int rtw89_fw_h2c_txtime_cmac_tbl(struct rtw89_dev *rtwdev,
3083 struct rtw89_sta *rtwsta)
3084 {
3085 const struct rtw89_chip_info *chip = rtwdev->chip;
3086 struct sk_buff *skb;
3087 int ret;
3088
3089 skb = rtw89_fw_h2c_alloc_skb_with_hdr(rtwdev, H2C_CMC_TBL_LEN);
3090 if (!skb) {
3091 rtw89_err(rtwdev, "failed to alloc skb for fw dl\n");
3092 return -ENOMEM;
3093 }
3094 skb_put(skb, H2C_CMC_TBL_LEN);
3095 SET_CTRL_INFO_MACID(skb->data, rtwsta->mac_id);
3096 SET_CTRL_INFO_OPERATION(skb->data, 1);
3097 if (rtwsta->cctl_tx_time) {
3098 SET_CMC_TBL_AMPDU_TIME_SEL(skb->data, 1);
3099 SET_CMC_TBL_AMPDU_MAX_TIME(skb->data, rtwsta->ampdu_max_time);
3100 }
3101 if (rtwsta->cctl_tx_retry_limit) {
3102 SET_CMC_TBL_DATA_TXCNT_LMT_SEL(skb->data, 1);
3103 SET_CMC_TBL_DATA_TX_CNT_LMT(skb->data, rtwsta->data_tx_cnt_lmt);
3104 }
3105
3106 rtw89_h2c_pkt_set_hdr(rtwdev, skb, FWCMD_TYPE_H2C,
3107 H2C_CAT_MAC, H2C_CL_MAC_FR_EXCHG,
3108 chip->h2c_cctl_func_id, 0, 1,
3109 H2C_CMC_TBL_LEN);
3110
3111 ret = rtw89_h2c_tx(rtwdev, skb, false);
3112 if (ret) {
3113 rtw89_err(rtwdev, "failed to send h2c\n");
3114 goto fail;
3115 }
3116
3117 return 0;
3118 fail:
3119 dev_kfree_skb_any(skb);
3120
3121 return ret;
3122 }
3123
rtw89_fw_h2c_txpath_cmac_tbl(struct rtw89_dev * rtwdev,struct rtw89_sta * rtwsta)3124 int rtw89_fw_h2c_txpath_cmac_tbl(struct rtw89_dev *rtwdev,
3125 struct rtw89_sta *rtwsta)
3126 {
3127 const struct rtw89_chip_info *chip = rtwdev->chip;
3128 struct sk_buff *skb;
3129 int ret;
3130
3131 if (chip->h2c_cctl_func_id != H2C_FUNC_MAC_CCTLINFO_UD)
3132 return 0;
3133
3134 skb = rtw89_fw_h2c_alloc_skb_with_hdr(rtwdev, H2C_CMC_TBL_LEN);
3135 if (!skb) {
3136 rtw89_err(rtwdev, "failed to alloc skb for fw dl\n");
3137 return -ENOMEM;
3138 }
3139 skb_put(skb, H2C_CMC_TBL_LEN);
3140 SET_CTRL_INFO_MACID(skb->data, rtwsta->mac_id);
3141 SET_CTRL_INFO_OPERATION(skb->data, 1);
3142
3143 __rtw89_fw_h2c_set_tx_path(rtwdev, skb);
3144
3145 rtw89_h2c_pkt_set_hdr(rtwdev, skb, FWCMD_TYPE_H2C,
3146 H2C_CAT_MAC, H2C_CL_MAC_FR_EXCHG,
3147 H2C_FUNC_MAC_CCTLINFO_UD, 0, 1,
3148 H2C_CMC_TBL_LEN);
3149
3150 ret = rtw89_h2c_tx(rtwdev, skb, false);
3151 if (ret) {
3152 rtw89_err(rtwdev, "failed to send h2c\n");
3153 goto fail;
3154 }
3155
3156 return 0;
3157 fail:
3158 dev_kfree_skb_any(skb);
3159
3160 return ret;
3161 }
3162
rtw89_fw_h2c_update_beacon(struct rtw89_dev * rtwdev,struct rtw89_vif * rtwvif)3163 int rtw89_fw_h2c_update_beacon(struct rtw89_dev *rtwdev,
3164 struct rtw89_vif *rtwvif)
3165 {
3166 const struct rtw89_chan *chan = rtw89_chan_get(rtwdev,
3167 rtwvif->sub_entity_idx);
3168 struct ieee80211_vif *vif = rtwvif_to_vif(rtwvif);
3169 struct rtw89_h2c_bcn_upd *h2c;
3170 struct sk_buff *skb_beacon;
3171 struct ieee80211_hdr *hdr;
3172 u32 len = sizeof(*h2c);
3173 struct sk_buff *skb;
3174 int bcn_total_len;
3175 u16 beacon_rate;
3176 u16 tim_offset;
3177 void *noa_data;
3178 u8 noa_len;
3179 int ret;
3180
3181 if (vif->p2p)
3182 beacon_rate = RTW89_HW_RATE_OFDM6;
3183 else if (chan->band_type == RTW89_BAND_2G)
3184 beacon_rate = RTW89_HW_RATE_CCK1;
3185 else
3186 beacon_rate = RTW89_HW_RATE_OFDM6;
3187
3188 skb_beacon = ieee80211_beacon_get_tim(rtwdev->hw, vif, &tim_offset,
3189 NULL, 0);
3190 if (!skb_beacon) {
3191 rtw89_err(rtwdev, "failed to get beacon skb\n");
3192 return -ENOMEM;
3193 }
3194
3195 noa_len = rtw89_p2p_noa_fetch(rtwvif, &noa_data);
3196 if (noa_len &&
3197 (noa_len <= skb_tailroom(skb_beacon) ||
3198 pskb_expand_head(skb_beacon, 0, noa_len, GFP_KERNEL) == 0)) {
3199 skb_put_data(skb_beacon, noa_data, noa_len);
3200 }
3201
3202 hdr = (struct ieee80211_hdr *)skb_beacon;
3203 tim_offset -= ieee80211_hdrlen(hdr->frame_control);
3204
3205 bcn_total_len = len + skb_beacon->len;
3206 skb = rtw89_fw_h2c_alloc_skb_with_hdr(rtwdev, bcn_total_len);
3207 if (!skb) {
3208 rtw89_err(rtwdev, "failed to alloc skb for fw dl\n");
3209 dev_kfree_skb_any(skb_beacon);
3210 return -ENOMEM;
3211 }
3212 skb_put(skb, len);
3213 h2c = (struct rtw89_h2c_bcn_upd *)skb->data;
3214
3215 h2c->w0 = le32_encode_bits(rtwvif->port, RTW89_H2C_BCN_UPD_W0_PORT) |
3216 le32_encode_bits(0, RTW89_H2C_BCN_UPD_W0_MBSSID) |
3217 le32_encode_bits(rtwvif->mac_idx, RTW89_H2C_BCN_UPD_W0_BAND) |
3218 le32_encode_bits(tim_offset | BIT(7), RTW89_H2C_BCN_UPD_W0_GRP_IE_OFST);
3219 h2c->w1 = le32_encode_bits(rtwvif->mac_id, RTW89_H2C_BCN_UPD_W1_MACID) |
3220 le32_encode_bits(RTW89_MGMT_HW_SSN_SEL, RTW89_H2C_BCN_UPD_W1_SSN_SEL) |
3221 le32_encode_bits(RTW89_MGMT_HW_SEQ_MODE, RTW89_H2C_BCN_UPD_W1_SSN_MODE) |
3222 le32_encode_bits(beacon_rate, RTW89_H2C_BCN_UPD_W1_RATE);
3223
3224 skb_put_data(skb, skb_beacon->data, skb_beacon->len);
3225 dev_kfree_skb_any(skb_beacon);
3226
3227 rtw89_h2c_pkt_set_hdr(rtwdev, skb, FWCMD_TYPE_H2C,
3228 H2C_CAT_MAC, H2C_CL_MAC_FR_EXCHG,
3229 H2C_FUNC_MAC_BCN_UPD, 0, 1,
3230 bcn_total_len);
3231
3232 ret = rtw89_h2c_tx(rtwdev, skb, false);
3233 if (ret) {
3234 rtw89_err(rtwdev, "failed to send h2c\n");
3235 dev_kfree_skb_any(skb);
3236 return ret;
3237 }
3238
3239 return 0;
3240 }
3241 EXPORT_SYMBOL(rtw89_fw_h2c_update_beacon);
3242
rtw89_fw_h2c_update_beacon_be(struct rtw89_dev * rtwdev,struct rtw89_vif * rtwvif)3243 int rtw89_fw_h2c_update_beacon_be(struct rtw89_dev *rtwdev,
3244 struct rtw89_vif *rtwvif)
3245 {
3246 const struct rtw89_chan *chan = rtw89_chan_get(rtwdev, RTW89_SUB_ENTITY_0);
3247 struct ieee80211_vif *vif = rtwvif_to_vif(rtwvif);
3248 struct rtw89_h2c_bcn_upd_be *h2c;
3249 struct sk_buff *skb_beacon;
3250 struct ieee80211_hdr *hdr;
3251 u32 len = sizeof(*h2c);
3252 struct sk_buff *skb;
3253 int bcn_total_len;
3254 u16 beacon_rate;
3255 u16 tim_offset;
3256 void *noa_data;
3257 u8 noa_len;
3258 int ret;
3259
3260 if (vif->p2p)
3261 beacon_rate = RTW89_HW_RATE_OFDM6;
3262 else if (chan->band_type == RTW89_BAND_2G)
3263 beacon_rate = RTW89_HW_RATE_CCK1;
3264 else
3265 beacon_rate = RTW89_HW_RATE_OFDM6;
3266
3267 skb_beacon = ieee80211_beacon_get_tim(rtwdev->hw, vif, &tim_offset,
3268 NULL, 0);
3269 if (!skb_beacon) {
3270 rtw89_err(rtwdev, "failed to get beacon skb\n");
3271 return -ENOMEM;
3272 }
3273
3274 noa_len = rtw89_p2p_noa_fetch(rtwvif, &noa_data);
3275 if (noa_len &&
3276 (noa_len <= skb_tailroom(skb_beacon) ||
3277 pskb_expand_head(skb_beacon, 0, noa_len, GFP_KERNEL) == 0)) {
3278 skb_put_data(skb_beacon, noa_data, noa_len);
3279 }
3280
3281 hdr = (struct ieee80211_hdr *)skb_beacon;
3282 tim_offset -= ieee80211_hdrlen(hdr->frame_control);
3283
3284 bcn_total_len = len + skb_beacon->len;
3285 skb = rtw89_fw_h2c_alloc_skb_with_hdr(rtwdev, bcn_total_len);
3286 if (!skb) {
3287 rtw89_err(rtwdev, "failed to alloc skb for fw dl\n");
3288 dev_kfree_skb_any(skb_beacon);
3289 return -ENOMEM;
3290 }
3291 skb_put(skb, len);
3292 h2c = (struct rtw89_h2c_bcn_upd_be *)skb->data;
3293
3294 h2c->w0 = le32_encode_bits(rtwvif->port, RTW89_H2C_BCN_UPD_BE_W0_PORT) |
3295 le32_encode_bits(0, RTW89_H2C_BCN_UPD_BE_W0_MBSSID) |
3296 le32_encode_bits(rtwvif->mac_idx, RTW89_H2C_BCN_UPD_BE_W0_BAND) |
3297 le32_encode_bits(tim_offset | BIT(7), RTW89_H2C_BCN_UPD_BE_W0_GRP_IE_OFST);
3298 h2c->w1 = le32_encode_bits(rtwvif->mac_id, RTW89_H2C_BCN_UPD_BE_W1_MACID) |
3299 le32_encode_bits(RTW89_MGMT_HW_SSN_SEL, RTW89_H2C_BCN_UPD_BE_W1_SSN_SEL) |
3300 le32_encode_bits(RTW89_MGMT_HW_SEQ_MODE, RTW89_H2C_BCN_UPD_BE_W1_SSN_MODE) |
3301 le32_encode_bits(beacon_rate, RTW89_H2C_BCN_UPD_BE_W1_RATE);
3302
3303 skb_put_data(skb, skb_beacon->data, skb_beacon->len);
3304 dev_kfree_skb_any(skb_beacon);
3305
3306 rtw89_h2c_pkt_set_hdr(rtwdev, skb, FWCMD_TYPE_H2C,
3307 H2C_CAT_MAC, H2C_CL_MAC_FR_EXCHG,
3308 H2C_FUNC_MAC_BCN_UPD_BE, 0, 1,
3309 bcn_total_len);
3310
3311 ret = rtw89_h2c_tx(rtwdev, skb, false);
3312 if (ret) {
3313 rtw89_err(rtwdev, "failed to send h2c\n");
3314 goto fail;
3315 }
3316
3317 return 0;
3318
3319 fail:
3320 dev_kfree_skb_any(skb);
3321
3322 return ret;
3323 }
3324 EXPORT_SYMBOL(rtw89_fw_h2c_update_beacon_be);
3325
3326 #define H2C_ROLE_MAINTAIN_LEN 4
rtw89_fw_h2c_role_maintain(struct rtw89_dev * rtwdev,struct rtw89_vif * rtwvif,struct rtw89_sta * rtwsta,enum rtw89_upd_mode upd_mode)3327 int rtw89_fw_h2c_role_maintain(struct rtw89_dev *rtwdev,
3328 struct rtw89_vif *rtwvif,
3329 struct rtw89_sta *rtwsta,
3330 enum rtw89_upd_mode upd_mode)
3331 {
3332 struct sk_buff *skb;
3333 u8 mac_id = rtwsta ? rtwsta->mac_id : rtwvif->mac_id;
3334 u8 self_role;
3335 int ret;
3336
3337 if (rtwvif->net_type == RTW89_NET_TYPE_AP_MODE) {
3338 if (rtwsta)
3339 self_role = RTW89_SELF_ROLE_AP_CLIENT;
3340 else
3341 self_role = rtwvif->self_role;
3342 } else {
3343 self_role = rtwvif->self_role;
3344 }
3345
3346 skb = rtw89_fw_h2c_alloc_skb_with_hdr(rtwdev, H2C_ROLE_MAINTAIN_LEN);
3347 if (!skb) {
3348 rtw89_err(rtwdev, "failed to alloc skb for h2c join\n");
3349 return -ENOMEM;
3350 }
3351 skb_put(skb, H2C_ROLE_MAINTAIN_LEN);
3352 SET_FWROLE_MAINTAIN_MACID(skb->data, mac_id);
3353 SET_FWROLE_MAINTAIN_SELF_ROLE(skb->data, self_role);
3354 SET_FWROLE_MAINTAIN_UPD_MODE(skb->data, upd_mode);
3355 SET_FWROLE_MAINTAIN_WIFI_ROLE(skb->data, rtwvif->wifi_role);
3356
3357 rtw89_h2c_pkt_set_hdr(rtwdev, skb, FWCMD_TYPE_H2C,
3358 H2C_CAT_MAC, H2C_CL_MAC_MEDIA_RPT,
3359 H2C_FUNC_MAC_FWROLE_MAINTAIN, 0, 1,
3360 H2C_ROLE_MAINTAIN_LEN);
3361
3362 ret = rtw89_h2c_tx(rtwdev, skb, false);
3363 if (ret) {
3364 rtw89_err(rtwdev, "failed to send h2c\n");
3365 goto fail;
3366 }
3367
3368 return 0;
3369 fail:
3370 dev_kfree_skb_any(skb);
3371
3372 return ret;
3373 }
3374
3375 static enum rtw89_fw_sta_type
rtw89_fw_get_sta_type(struct rtw89_dev * rtwdev,struct rtw89_vif * rtwvif,struct rtw89_sta * rtwsta)3376 rtw89_fw_get_sta_type(struct rtw89_dev *rtwdev, struct rtw89_vif *rtwvif,
3377 struct rtw89_sta *rtwsta)
3378 {
3379 struct ieee80211_sta *sta = rtwsta_to_sta_safe(rtwsta);
3380 struct ieee80211_vif *vif = rtwvif_to_vif(rtwvif);
3381
3382 if (!sta)
3383 goto by_vif;
3384
3385 if (sta->deflink.eht_cap.has_eht)
3386 return RTW89_FW_BE_STA;
3387 else if (sta->deflink.he_cap.has_he)
3388 return RTW89_FW_AX_STA;
3389 else
3390 return RTW89_FW_N_AC_STA;
3391
3392 by_vif:
3393 if (vif->bss_conf.eht_support)
3394 return RTW89_FW_BE_STA;
3395 else if (vif->bss_conf.he_support)
3396 return RTW89_FW_AX_STA;
3397 else
3398 return RTW89_FW_N_AC_STA;
3399 }
3400
rtw89_fw_h2c_join_info(struct rtw89_dev * rtwdev,struct rtw89_vif * rtwvif,struct rtw89_sta * rtwsta,bool dis_conn)3401 int rtw89_fw_h2c_join_info(struct rtw89_dev *rtwdev, struct rtw89_vif *rtwvif,
3402 struct rtw89_sta *rtwsta, bool dis_conn)
3403 {
3404 struct sk_buff *skb;
3405 u8 mac_id = rtwsta ? rtwsta->mac_id : rtwvif->mac_id;
3406 u8 self_role = rtwvif->self_role;
3407 enum rtw89_fw_sta_type sta_type;
3408 u8 net_type = rtwvif->net_type;
3409 struct rtw89_h2c_join_v1 *h2c_v1;
3410 struct rtw89_h2c_join *h2c;
3411 u32 len = sizeof(*h2c);
3412 bool format_v1 = false;
3413 int ret;
3414
3415 if (rtwdev->chip->chip_gen == RTW89_CHIP_BE) {
3416 len = sizeof(*h2c_v1);
3417 format_v1 = true;
3418 }
3419
3420 if (net_type == RTW89_NET_TYPE_AP_MODE && rtwsta) {
3421 self_role = RTW89_SELF_ROLE_AP_CLIENT;
3422 net_type = dis_conn ? RTW89_NET_TYPE_NO_LINK : net_type;
3423 }
3424
3425 skb = rtw89_fw_h2c_alloc_skb_with_hdr(rtwdev, len);
3426 if (!skb) {
3427 rtw89_err(rtwdev, "failed to alloc skb for h2c join\n");
3428 return -ENOMEM;
3429 }
3430 skb_put(skb, len);
3431 h2c = (struct rtw89_h2c_join *)skb->data;
3432
3433 h2c->w0 = le32_encode_bits(mac_id, RTW89_H2C_JOININFO_W0_MACID) |
3434 le32_encode_bits(dis_conn, RTW89_H2C_JOININFO_W0_OP) |
3435 le32_encode_bits(rtwvif->mac_idx, RTW89_H2C_JOININFO_W0_BAND) |
3436 le32_encode_bits(rtwvif->wmm, RTW89_H2C_JOININFO_W0_WMM) |
3437 le32_encode_bits(rtwvif->trigger, RTW89_H2C_JOININFO_W0_TGR) |
3438 le32_encode_bits(0, RTW89_H2C_JOININFO_W0_ISHESTA) |
3439 le32_encode_bits(0, RTW89_H2C_JOININFO_W0_DLBW) |
3440 le32_encode_bits(0, RTW89_H2C_JOININFO_W0_TF_MAC_PAD) |
3441 le32_encode_bits(0, RTW89_H2C_JOININFO_W0_DL_T_PE) |
3442 le32_encode_bits(rtwvif->port, RTW89_H2C_JOININFO_W0_PORT_ID) |
3443 le32_encode_bits(net_type, RTW89_H2C_JOININFO_W0_NET_TYPE) |
3444 le32_encode_bits(rtwvif->wifi_role, RTW89_H2C_JOININFO_W0_WIFI_ROLE) |
3445 le32_encode_bits(self_role, RTW89_H2C_JOININFO_W0_SELF_ROLE);
3446
3447 if (!format_v1)
3448 goto done;
3449
3450 h2c_v1 = (struct rtw89_h2c_join_v1 *)skb->data;
3451
3452 sta_type = rtw89_fw_get_sta_type(rtwdev, rtwvif, rtwsta);
3453
3454 h2c_v1->w1 = le32_encode_bits(sta_type, RTW89_H2C_JOININFO_W1_STA_TYPE);
3455 h2c_v1->w2 = 0;
3456
3457 done:
3458 rtw89_h2c_pkt_set_hdr(rtwdev, skb, FWCMD_TYPE_H2C,
3459 H2C_CAT_MAC, H2C_CL_MAC_MEDIA_RPT,
3460 H2C_FUNC_MAC_JOININFO, 0, 1,
3461 len);
3462
3463 ret = rtw89_h2c_tx(rtwdev, skb, false);
3464 if (ret) {
3465 rtw89_err(rtwdev, "failed to send h2c\n");
3466 goto fail;
3467 }
3468
3469 return 0;
3470 fail:
3471 dev_kfree_skb_any(skb);
3472
3473 return ret;
3474 }
3475
rtw89_fw_h2c_notify_dbcc(struct rtw89_dev * rtwdev,bool en)3476 int rtw89_fw_h2c_notify_dbcc(struct rtw89_dev *rtwdev, bool en)
3477 {
3478 struct rtw89_h2c_notify_dbcc *h2c;
3479 u32 len = sizeof(*h2c);
3480 struct sk_buff *skb;
3481 int ret;
3482
3483 skb = rtw89_fw_h2c_alloc_skb_with_hdr(rtwdev, len);
3484 if (!skb) {
3485 rtw89_err(rtwdev, "failed to alloc skb for h2c notify dbcc\n");
3486 return -ENOMEM;
3487 }
3488 skb_put(skb, len);
3489 h2c = (struct rtw89_h2c_notify_dbcc *)skb->data;
3490
3491 h2c->w0 = le32_encode_bits(en, RTW89_H2C_NOTIFY_DBCC_EN);
3492
3493 rtw89_h2c_pkt_set_hdr(rtwdev, skb, FWCMD_TYPE_H2C,
3494 H2C_CAT_MAC, H2C_CL_MAC_MEDIA_RPT,
3495 H2C_FUNC_NOTIFY_DBCC, 0, 1,
3496 len);
3497
3498 ret = rtw89_h2c_tx(rtwdev, skb, false);
3499 if (ret) {
3500 rtw89_err(rtwdev, "failed to send h2c\n");
3501 goto fail;
3502 }
3503
3504 return 0;
3505 fail:
3506 dev_kfree_skb_any(skb);
3507
3508 return ret;
3509 }
3510
rtw89_fw_h2c_macid_pause(struct rtw89_dev * rtwdev,u8 sh,u8 grp,bool pause)3511 int rtw89_fw_h2c_macid_pause(struct rtw89_dev *rtwdev, u8 sh, u8 grp,
3512 bool pause)
3513 {
3514 struct rtw89_fw_macid_pause_sleep_grp *h2c_new;
3515 struct rtw89_fw_macid_pause_grp *h2c;
3516 __le32 set = cpu_to_le32(BIT(sh));
3517 u8 h2c_macid_pause_id;
3518 struct sk_buff *skb;
3519 u32 len;
3520 int ret;
3521
3522 if (RTW89_CHK_FW_FEATURE(MACID_PAUSE_SLEEP, &rtwdev->fw)) {
3523 h2c_macid_pause_id = H2C_FUNC_MAC_MACID_PAUSE_SLEEP;
3524 len = sizeof(*h2c_new);
3525 } else {
3526 h2c_macid_pause_id = H2C_FUNC_MAC_MACID_PAUSE;
3527 len = sizeof(*h2c);
3528 }
3529
3530 skb = rtw89_fw_h2c_alloc_skb_with_hdr(rtwdev, len);
3531 if (!skb) {
3532 rtw89_err(rtwdev, "failed to alloc skb for h2c macid pause\n");
3533 return -ENOMEM;
3534 }
3535 skb_put(skb, len);
3536
3537 if (h2c_macid_pause_id == H2C_FUNC_MAC_MACID_PAUSE_SLEEP) {
3538 h2c_new = (struct rtw89_fw_macid_pause_sleep_grp *)skb->data;
3539
3540 h2c_new->n[0].pause_mask_grp[grp] = set;
3541 h2c_new->n[0].sleep_mask_grp[grp] = set;
3542 if (pause) {
3543 h2c_new->n[0].pause_grp[grp] = set;
3544 h2c_new->n[0].sleep_grp[grp] = set;
3545 }
3546 } else {
3547 h2c = (struct rtw89_fw_macid_pause_grp *)skb->data;
3548
3549 h2c->mask_grp[grp] = set;
3550 if (pause)
3551 h2c->pause_grp[grp] = set;
3552 }
3553
3554 rtw89_h2c_pkt_set_hdr(rtwdev, skb, FWCMD_TYPE_H2C,
3555 H2C_CAT_MAC, H2C_CL_MAC_FW_OFLD,
3556 h2c_macid_pause_id, 1, 0,
3557 len);
3558
3559 ret = rtw89_h2c_tx(rtwdev, skb, false);
3560 if (ret) {
3561 rtw89_err(rtwdev, "failed to send h2c\n");
3562 goto fail;
3563 }
3564
3565 return 0;
3566 fail:
3567 dev_kfree_skb_any(skb);
3568
3569 return ret;
3570 }
3571
3572 #define H2C_EDCA_LEN 12
rtw89_fw_h2c_set_edca(struct rtw89_dev * rtwdev,struct rtw89_vif * rtwvif,u8 ac,u32 val)3573 int rtw89_fw_h2c_set_edca(struct rtw89_dev *rtwdev, struct rtw89_vif *rtwvif,
3574 u8 ac, u32 val)
3575 {
3576 struct sk_buff *skb;
3577 int ret;
3578
3579 skb = rtw89_fw_h2c_alloc_skb_with_hdr(rtwdev, H2C_EDCA_LEN);
3580 if (!skb) {
3581 rtw89_err(rtwdev, "failed to alloc skb for h2c edca\n");
3582 return -ENOMEM;
3583 }
3584 skb_put(skb, H2C_EDCA_LEN);
3585 RTW89_SET_EDCA_SEL(skb->data, 0);
3586 RTW89_SET_EDCA_BAND(skb->data, rtwvif->mac_idx);
3587 RTW89_SET_EDCA_WMM(skb->data, 0);
3588 RTW89_SET_EDCA_AC(skb->data, ac);
3589 RTW89_SET_EDCA_PARAM(skb->data, val);
3590
3591 rtw89_h2c_pkt_set_hdr(rtwdev, skb, FWCMD_TYPE_H2C,
3592 H2C_CAT_MAC, H2C_CL_MAC_FW_OFLD,
3593 H2C_FUNC_USR_EDCA, 0, 1,
3594 H2C_EDCA_LEN);
3595
3596 ret = rtw89_h2c_tx(rtwdev, skb, false);
3597 if (ret) {
3598 rtw89_err(rtwdev, "failed to send h2c\n");
3599 goto fail;
3600 }
3601
3602 return 0;
3603 fail:
3604 dev_kfree_skb_any(skb);
3605
3606 return ret;
3607 }
3608
3609 #define H2C_TSF32_TOGL_LEN 4
rtw89_fw_h2c_tsf32_toggle(struct rtw89_dev * rtwdev,struct rtw89_vif * rtwvif,bool en)3610 int rtw89_fw_h2c_tsf32_toggle(struct rtw89_dev *rtwdev, struct rtw89_vif *rtwvif,
3611 bool en)
3612 {
3613 struct sk_buff *skb;
3614 u16 early_us = en ? 2000 : 0;
3615 u8 *cmd;
3616 int ret;
3617
3618 skb = rtw89_fw_h2c_alloc_skb_with_hdr(rtwdev, H2C_TSF32_TOGL_LEN);
3619 if (!skb) {
3620 rtw89_err(rtwdev, "failed to alloc skb for h2c p2p act\n");
3621 return -ENOMEM;
3622 }
3623 skb_put(skb, H2C_TSF32_TOGL_LEN);
3624 cmd = skb->data;
3625
3626 RTW89_SET_FWCMD_TSF32_TOGL_BAND(cmd, rtwvif->mac_idx);
3627 RTW89_SET_FWCMD_TSF32_TOGL_EN(cmd, en);
3628 RTW89_SET_FWCMD_TSF32_TOGL_PORT(cmd, rtwvif->port);
3629 RTW89_SET_FWCMD_TSF32_TOGL_EARLY(cmd, early_us);
3630
3631 rtw89_h2c_pkt_set_hdr(rtwdev, skb, FWCMD_TYPE_H2C,
3632 H2C_CAT_MAC, H2C_CL_MAC_FW_OFLD,
3633 H2C_FUNC_TSF32_TOGL, 0, 0,
3634 H2C_TSF32_TOGL_LEN);
3635
3636 ret = rtw89_h2c_tx(rtwdev, skb, false);
3637 if (ret) {
3638 rtw89_err(rtwdev, "failed to send h2c\n");
3639 goto fail;
3640 }
3641
3642 return 0;
3643 fail:
3644 dev_kfree_skb_any(skb);
3645
3646 return ret;
3647 }
3648
3649 #define H2C_OFLD_CFG_LEN 8
rtw89_fw_h2c_set_ofld_cfg(struct rtw89_dev * rtwdev)3650 int rtw89_fw_h2c_set_ofld_cfg(struct rtw89_dev *rtwdev)
3651 {
3652 static const u8 cfg[] = {0x09, 0x00, 0x00, 0x00, 0x5e, 0x00, 0x00, 0x00};
3653 struct sk_buff *skb;
3654 int ret;
3655
3656 skb = rtw89_fw_h2c_alloc_skb_with_hdr(rtwdev, H2C_OFLD_CFG_LEN);
3657 if (!skb) {
3658 rtw89_err(rtwdev, "failed to alloc skb for h2c ofld\n");
3659 return -ENOMEM;
3660 }
3661 skb_put_data(skb, cfg, H2C_OFLD_CFG_LEN);
3662
3663 rtw89_h2c_pkt_set_hdr(rtwdev, skb, FWCMD_TYPE_H2C,
3664 H2C_CAT_MAC, H2C_CL_MAC_FW_OFLD,
3665 H2C_FUNC_OFLD_CFG, 0, 1,
3666 H2C_OFLD_CFG_LEN);
3667
3668 ret = rtw89_h2c_tx(rtwdev, skb, false);
3669 if (ret) {
3670 rtw89_err(rtwdev, "failed to send h2c\n");
3671 goto fail;
3672 }
3673
3674 return 0;
3675 fail:
3676 dev_kfree_skb_any(skb);
3677
3678 return ret;
3679 }
3680
rtw89_fw_h2c_set_bcn_fltr_cfg(struct rtw89_dev * rtwdev,struct ieee80211_vif * vif,bool connect)3681 int rtw89_fw_h2c_set_bcn_fltr_cfg(struct rtw89_dev *rtwdev,
3682 struct ieee80211_vif *vif,
3683 bool connect)
3684 {
3685 struct rtw89_vif *rtwvif = vif_to_rtwvif_safe(vif);
3686 struct ieee80211_bss_conf *bss_conf = vif ? &vif->bss_conf : NULL;
3687 s32 thold = RTW89_DEFAULT_CQM_THOLD;
3688 u32 hyst = RTW89_DEFAULT_CQM_HYST;
3689 struct rtw89_h2c_bcnfltr *h2c;
3690 u32 len = sizeof(*h2c);
3691 struct sk_buff *skb;
3692 int ret;
3693
3694 if (!RTW89_CHK_FW_FEATURE(BEACON_FILTER, &rtwdev->fw))
3695 return -EINVAL;
3696
3697 if (!rtwvif || !bss_conf || rtwvif->net_type != RTW89_NET_TYPE_INFRA)
3698 return -EINVAL;
3699
3700 skb = rtw89_fw_h2c_alloc_skb_with_hdr(rtwdev, len);
3701 if (!skb) {
3702 rtw89_err(rtwdev, "failed to alloc skb for h2c bcn filter\n");
3703 return -ENOMEM;
3704 }
3705
3706 skb_put(skb, len);
3707 h2c = (struct rtw89_h2c_bcnfltr *)skb->data;
3708
3709 if (bss_conf->cqm_rssi_hyst)
3710 hyst = bss_conf->cqm_rssi_hyst;
3711 if (bss_conf->cqm_rssi_thold)
3712 thold = bss_conf->cqm_rssi_thold;
3713
3714 h2c->w0 = le32_encode_bits(connect, RTW89_H2C_BCNFLTR_W0_MON_RSSI) |
3715 le32_encode_bits(connect, RTW89_H2C_BCNFLTR_W0_MON_BCN) |
3716 le32_encode_bits(connect, RTW89_H2C_BCNFLTR_W0_MON_EN) |
3717 le32_encode_bits(RTW89_BCN_FLTR_OFFLOAD_MODE_DEFAULT,
3718 RTW89_H2C_BCNFLTR_W0_MODE) |
3719 le32_encode_bits(RTW89_BCN_LOSS_CNT, RTW89_H2C_BCNFLTR_W0_BCN_LOSS_CNT) |
3720 le32_encode_bits(hyst, RTW89_H2C_BCNFLTR_W0_RSSI_HYST) |
3721 le32_encode_bits(thold + MAX_RSSI,
3722 RTW89_H2C_BCNFLTR_W0_RSSI_THRESHOLD) |
3723 le32_encode_bits(rtwvif->mac_id, RTW89_H2C_BCNFLTR_W0_MAC_ID);
3724
3725 rtw89_h2c_pkt_set_hdr(rtwdev, skb, FWCMD_TYPE_H2C,
3726 H2C_CAT_MAC, H2C_CL_MAC_FW_OFLD,
3727 H2C_FUNC_CFG_BCNFLTR, 0, 1, len);
3728
3729 ret = rtw89_h2c_tx(rtwdev, skb, false);
3730 if (ret) {
3731 rtw89_err(rtwdev, "failed to send h2c\n");
3732 goto fail;
3733 }
3734
3735 return 0;
3736 fail:
3737 dev_kfree_skb_any(skb);
3738
3739 return ret;
3740 }
3741
rtw89_fw_h2c_rssi_offload(struct rtw89_dev * rtwdev,struct rtw89_rx_phy_ppdu * phy_ppdu)3742 int rtw89_fw_h2c_rssi_offload(struct rtw89_dev *rtwdev,
3743 struct rtw89_rx_phy_ppdu *phy_ppdu)
3744 {
3745 struct rtw89_h2c_ofld_rssi *h2c;
3746 u32 len = sizeof(*h2c);
3747 struct sk_buff *skb;
3748 s8 rssi;
3749 int ret;
3750
3751 if (!RTW89_CHK_FW_FEATURE(BEACON_FILTER, &rtwdev->fw))
3752 return -EINVAL;
3753
3754 if (!phy_ppdu)
3755 return -EINVAL;
3756
3757 skb = rtw89_fw_h2c_alloc_skb_with_hdr(rtwdev, len);
3758 if (!skb) {
3759 rtw89_err(rtwdev, "failed to alloc skb for h2c rssi\n");
3760 return -ENOMEM;
3761 }
3762
3763 rssi = phy_ppdu->rssi_avg >> RSSI_FACTOR;
3764 skb_put(skb, len);
3765 h2c = (struct rtw89_h2c_ofld_rssi *)skb->data;
3766
3767 h2c->w0 = le32_encode_bits(phy_ppdu->mac_id, RTW89_H2C_OFLD_RSSI_W0_MACID) |
3768 le32_encode_bits(1, RTW89_H2C_OFLD_RSSI_W0_NUM);
3769 h2c->w1 = le32_encode_bits(rssi, RTW89_H2C_OFLD_RSSI_W1_VAL);
3770
3771 rtw89_h2c_pkt_set_hdr(rtwdev, skb, FWCMD_TYPE_H2C,
3772 H2C_CAT_MAC, H2C_CL_MAC_FW_OFLD,
3773 H2C_FUNC_OFLD_RSSI, 0, 1, len);
3774
3775 ret = rtw89_h2c_tx(rtwdev, skb, false);
3776 if (ret) {
3777 rtw89_err(rtwdev, "failed to send h2c\n");
3778 goto fail;
3779 }
3780
3781 return 0;
3782 fail:
3783 dev_kfree_skb_any(skb);
3784
3785 return ret;
3786 }
3787
rtw89_fw_h2c_tp_offload(struct rtw89_dev * rtwdev,struct rtw89_vif * rtwvif)3788 int rtw89_fw_h2c_tp_offload(struct rtw89_dev *rtwdev, struct rtw89_vif *rtwvif)
3789 {
3790 struct rtw89_traffic_stats *stats = &rtwvif->stats;
3791 struct rtw89_h2c_ofld *h2c;
3792 u32 len = sizeof(*h2c);
3793 struct sk_buff *skb;
3794 int ret;
3795
3796 if (rtwvif->net_type != RTW89_NET_TYPE_INFRA)
3797 return -EINVAL;
3798
3799 skb = rtw89_fw_h2c_alloc_skb_with_hdr(rtwdev, len);
3800 if (!skb) {
3801 rtw89_err(rtwdev, "failed to alloc skb for h2c tp\n");
3802 return -ENOMEM;
3803 }
3804
3805 skb_put(skb, len);
3806 h2c = (struct rtw89_h2c_ofld *)skb->data;
3807
3808 h2c->w0 = le32_encode_bits(rtwvif->mac_id, RTW89_H2C_OFLD_W0_MAC_ID) |
3809 le32_encode_bits(stats->tx_throughput, RTW89_H2C_OFLD_W0_TX_TP) |
3810 le32_encode_bits(stats->rx_throughput, RTW89_H2C_OFLD_W0_RX_TP);
3811
3812 rtw89_h2c_pkt_set_hdr(rtwdev, skb, FWCMD_TYPE_H2C,
3813 H2C_CAT_MAC, H2C_CL_MAC_FW_OFLD,
3814 H2C_FUNC_OFLD_TP, 0, 1, len);
3815
3816 ret = rtw89_h2c_tx(rtwdev, skb, false);
3817 if (ret) {
3818 rtw89_err(rtwdev, "failed to send h2c\n");
3819 goto fail;
3820 }
3821
3822 return 0;
3823 fail:
3824 dev_kfree_skb_any(skb);
3825
3826 return ret;
3827 }
3828
rtw89_fw_h2c_ra(struct rtw89_dev * rtwdev,struct rtw89_ra_info * ra,bool csi)3829 int rtw89_fw_h2c_ra(struct rtw89_dev *rtwdev, struct rtw89_ra_info *ra, bool csi)
3830 {
3831 const struct rtw89_chip_info *chip = rtwdev->chip;
3832 struct rtw89_h2c_ra_v1 *h2c_v1;
3833 struct rtw89_h2c_ra *h2c;
3834 u32 len = sizeof(*h2c);
3835 bool format_v1 = false;
3836 struct sk_buff *skb;
3837 int ret;
3838
3839 if (chip->chip_gen == RTW89_CHIP_BE) {
3840 len = sizeof(*h2c_v1);
3841 format_v1 = true;
3842 }
3843
3844 skb = rtw89_fw_h2c_alloc_skb_with_hdr(rtwdev, len);
3845 if (!skb) {
3846 rtw89_err(rtwdev, "failed to alloc skb for h2c join\n");
3847 return -ENOMEM;
3848 }
3849 skb_put(skb, len);
3850 h2c = (struct rtw89_h2c_ra *)skb->data;
3851 rtw89_debug(rtwdev, RTW89_DBG_RA,
3852 "ra cmd msk: %llx ", ra->ra_mask);
3853
3854 h2c->w0 = le32_encode_bits(ra->mode_ctrl, RTW89_H2C_RA_W0_MODE) |
3855 le32_encode_bits(ra->bw_cap, RTW89_H2C_RA_W0_BW_CAP) |
3856 le32_encode_bits(ra->macid, RTW89_H2C_RA_W0_MACID) |
3857 le32_encode_bits(ra->dcm_cap, RTW89_H2C_RA_W0_DCM) |
3858 le32_encode_bits(ra->er_cap, RTW89_H2C_RA_W0_ER) |
3859 le32_encode_bits(ra->init_rate_lv, RTW89_H2C_RA_W0_INIT_RATE_LV) |
3860 le32_encode_bits(ra->upd_all, RTW89_H2C_RA_W0_UPD_ALL) |
3861 le32_encode_bits(ra->en_sgi, RTW89_H2C_RA_W0_SGI) |
3862 le32_encode_bits(ra->ldpc_cap, RTW89_H2C_RA_W0_LDPC) |
3863 le32_encode_bits(ra->stbc_cap, RTW89_H2C_RA_W0_STBC) |
3864 le32_encode_bits(ra->ss_num, RTW89_H2C_RA_W0_SS_NUM) |
3865 le32_encode_bits(ra->giltf, RTW89_H2C_RA_W0_GILTF) |
3866 le32_encode_bits(ra->upd_bw_nss_mask, RTW89_H2C_RA_W0_UPD_BW_NSS_MASK) |
3867 le32_encode_bits(ra->upd_mask, RTW89_H2C_RA_W0_UPD_MASK);
3868 h2c->w1 = le32_encode_bits(ra->ra_mask, RTW89_H2C_RA_W1_RAMASK_LO32);
3869 h2c->w2 = le32_encode_bits(ra->ra_mask >> 32, RTW89_H2C_RA_W2_RAMASK_HI32);
3870 h2c->w3 = le32_encode_bits(ra->fix_giltf_en, RTW89_H2C_RA_W3_FIX_GILTF_EN) |
3871 le32_encode_bits(ra->fix_giltf, RTW89_H2C_RA_W3_FIX_GILTF);
3872
3873 if (!format_v1)
3874 goto csi;
3875
3876 h2c_v1 = (struct rtw89_h2c_ra_v1 *)h2c;
3877 h2c_v1->w4 = le32_encode_bits(ra->mode_ctrl, RTW89_H2C_RA_V1_W4_MODE_EHT) |
3878 le32_encode_bits(ra->bw_cap, RTW89_H2C_RA_V1_W4_BW_EHT);
3879
3880 csi:
3881 if (!csi)
3882 goto done;
3883
3884 h2c->w2 |= le32_encode_bits(1, RTW89_H2C_RA_W2_BFEE_CSI_CTL);
3885 h2c->w3 |= le32_encode_bits(ra->band_num, RTW89_H2C_RA_W3_BAND_NUM) |
3886 le32_encode_bits(ra->cr_tbl_sel, RTW89_H2C_RA_W3_CR_TBL_SEL) |
3887 le32_encode_bits(ra->fixed_csi_rate_en, RTW89_H2C_RA_W3_FIXED_CSI_RATE_EN) |
3888 le32_encode_bits(ra->ra_csi_rate_en, RTW89_H2C_RA_W3_RA_CSI_RATE_EN) |
3889 le32_encode_bits(ra->csi_mcs_ss_idx, RTW89_H2C_RA_W3_FIXED_CSI_MCS_SS_IDX) |
3890 le32_encode_bits(ra->csi_mode, RTW89_H2C_RA_W3_FIXED_CSI_MODE) |
3891 le32_encode_bits(ra->csi_gi_ltf, RTW89_H2C_RA_W3_FIXED_CSI_GI_LTF) |
3892 le32_encode_bits(ra->csi_bw, RTW89_H2C_RA_W3_FIXED_CSI_BW);
3893
3894 done:
3895 rtw89_h2c_pkt_set_hdr(rtwdev, skb, FWCMD_TYPE_H2C,
3896 H2C_CAT_OUTSRC, H2C_CL_OUTSRC_RA,
3897 H2C_FUNC_OUTSRC_RA_MACIDCFG, 0, 0,
3898 len);
3899
3900 ret = rtw89_h2c_tx(rtwdev, skb, false);
3901 if (ret) {
3902 rtw89_err(rtwdev, "failed to send h2c\n");
3903 goto fail;
3904 }
3905
3906 return 0;
3907 fail:
3908 dev_kfree_skb_any(skb);
3909
3910 return ret;
3911 }
3912
rtw89_fw_h2c_cxdrv_init(struct rtw89_dev * rtwdev,u8 type)3913 int rtw89_fw_h2c_cxdrv_init(struct rtw89_dev *rtwdev, u8 type)
3914 {
3915 struct rtw89_btc *btc = &rtwdev->btc;
3916 struct rtw89_btc_dm *dm = &btc->dm;
3917 struct rtw89_btc_init_info *init_info = &dm->init_info.init;
3918 struct rtw89_btc_module *module = &init_info->module;
3919 struct rtw89_btc_ant_info *ant = &module->ant;
3920 struct rtw89_h2c_cxinit *h2c;
3921 u32 len = sizeof(*h2c);
3922 struct sk_buff *skb;
3923 int ret;
3924
3925 skb = rtw89_fw_h2c_alloc_skb_with_hdr(rtwdev, len);
3926 if (!skb) {
3927 rtw89_err(rtwdev, "failed to alloc skb for h2c cxdrv_init\n");
3928 return -ENOMEM;
3929 }
3930 skb_put(skb, len);
3931 h2c = (struct rtw89_h2c_cxinit *)skb->data;
3932
3933 h2c->hdr.type = type;
3934 h2c->hdr.len = len - H2C_LEN_CXDRVHDR;
3935
3936 h2c->ant_type = ant->type;
3937 h2c->ant_num = ant->num;
3938 h2c->ant_iso = ant->isolation;
3939 h2c->ant_info =
3940 u8_encode_bits(ant->single_pos, RTW89_H2C_CXINIT_ANT_INFO_POS) |
3941 u8_encode_bits(ant->diversity, RTW89_H2C_CXINIT_ANT_INFO_DIVERSITY) |
3942 u8_encode_bits(ant->btg_pos, RTW89_H2C_CXINIT_ANT_INFO_BTG_POS) |
3943 u8_encode_bits(ant->stream_cnt, RTW89_H2C_CXINIT_ANT_INFO_STREAM_CNT);
3944
3945 h2c->mod_rfe = module->rfe_type;
3946 h2c->mod_cv = module->cv;
3947 h2c->mod_info =
3948 u8_encode_bits(module->bt_solo, RTW89_H2C_CXINIT_MOD_INFO_BT_SOLO) |
3949 u8_encode_bits(module->bt_pos, RTW89_H2C_CXINIT_MOD_INFO_BT_POS) |
3950 u8_encode_bits(module->switch_type, RTW89_H2C_CXINIT_MOD_INFO_SW_TYPE) |
3951 u8_encode_bits(module->wa_type, RTW89_H2C_CXINIT_MOD_INFO_WA_TYPE);
3952 h2c->mod_adie_kt = module->kt_ver_adie;
3953 h2c->wl_gch = init_info->wl_guard_ch;
3954
3955 h2c->info =
3956 u8_encode_bits(init_info->wl_only, RTW89_H2C_CXINIT_INFO_WL_ONLY) |
3957 u8_encode_bits(init_info->wl_init_ok, RTW89_H2C_CXINIT_INFO_WL_INITOK) |
3958 u8_encode_bits(init_info->dbcc_en, RTW89_H2C_CXINIT_INFO_DBCC_EN) |
3959 u8_encode_bits(init_info->cx_other, RTW89_H2C_CXINIT_INFO_CX_OTHER) |
3960 u8_encode_bits(init_info->bt_only, RTW89_H2C_CXINIT_INFO_BT_ONLY);
3961
3962 rtw89_h2c_pkt_set_hdr(rtwdev, skb, FWCMD_TYPE_H2C,
3963 H2C_CAT_OUTSRC, BTFC_SET,
3964 SET_DRV_INFO, 0, 0,
3965 len);
3966
3967 ret = rtw89_h2c_tx(rtwdev, skb, false);
3968 if (ret) {
3969 rtw89_err(rtwdev, "failed to send h2c\n");
3970 goto fail;
3971 }
3972
3973 return 0;
3974 fail:
3975 dev_kfree_skb_any(skb);
3976
3977 return ret;
3978 }
3979
rtw89_fw_h2c_cxdrv_init_v7(struct rtw89_dev * rtwdev,u8 type)3980 int rtw89_fw_h2c_cxdrv_init_v7(struct rtw89_dev *rtwdev, u8 type)
3981 {
3982 struct rtw89_btc *btc = &rtwdev->btc;
3983 struct rtw89_btc_dm *dm = &btc->dm;
3984 struct rtw89_btc_init_info_v7 *init_info = &dm->init_info.init_v7;
3985 struct rtw89_h2c_cxinit_v7 *h2c;
3986 u32 len = sizeof(*h2c);
3987 struct sk_buff *skb;
3988 int ret;
3989
3990 skb = rtw89_fw_h2c_alloc_skb_with_hdr(rtwdev, len);
3991 if (!skb) {
3992 rtw89_err(rtwdev, "failed to alloc skb for h2c cxdrv_init_v7\n");
3993 return -ENOMEM;
3994 }
3995 skb_put(skb, len);
3996 h2c = (struct rtw89_h2c_cxinit_v7 *)skb->data;
3997
3998 h2c->hdr.type = type;
3999 h2c->hdr.ver = btc->ver->fcxinit;
4000 h2c->hdr.len = len - H2C_LEN_CXDRVHDR_V7;
4001 h2c->init = *init_info;
4002
4003 rtw89_h2c_pkt_set_hdr(rtwdev, skb, FWCMD_TYPE_H2C,
4004 H2C_CAT_OUTSRC, BTFC_SET,
4005 SET_DRV_INFO, 0, 0,
4006 len);
4007
4008 ret = rtw89_h2c_tx(rtwdev, skb, false);
4009 if (ret) {
4010 rtw89_err(rtwdev, "failed to send h2c\n");
4011 goto fail;
4012 }
4013
4014 return 0;
4015 fail:
4016 dev_kfree_skb_any(skb);
4017
4018 return ret;
4019 }
4020
4021 #define PORT_DATA_OFFSET 4
4022 #define H2C_LEN_CXDRVINFO_ROLE_DBCC_LEN 12
4023 #define H2C_LEN_CXDRVINFO_ROLE_SIZE(max_role_num) \
4024 (4 + 12 * (max_role_num) + H2C_LEN_CXDRVHDR)
4025
rtw89_fw_h2c_cxdrv_role(struct rtw89_dev * rtwdev,u8 type)4026 int rtw89_fw_h2c_cxdrv_role(struct rtw89_dev *rtwdev, u8 type)
4027 {
4028 struct rtw89_btc *btc = &rtwdev->btc;
4029 const struct rtw89_btc_ver *ver = btc->ver;
4030 struct rtw89_btc_wl_info *wl = &btc->cx.wl;
4031 struct rtw89_btc_wl_role_info *role_info = &wl->role_info;
4032 struct rtw89_btc_wl_role_info_bpos *bpos = &role_info->role_map.role;
4033 struct rtw89_btc_wl_active_role *active = role_info->active_role;
4034 struct sk_buff *skb;
4035 u32 len;
4036 u8 offset = 0;
4037 u8 *cmd;
4038 int ret;
4039 int i;
4040
4041 len = H2C_LEN_CXDRVINFO_ROLE_SIZE(ver->max_role_num);
4042
4043 skb = rtw89_fw_h2c_alloc_skb_with_hdr(rtwdev, len);
4044 if (!skb) {
4045 rtw89_err(rtwdev, "failed to alloc skb for h2c cxdrv_role\n");
4046 return -ENOMEM;
4047 }
4048 skb_put(skb, len);
4049 cmd = skb->data;
4050
4051 RTW89_SET_FWCMD_CXHDR_TYPE(cmd, type);
4052 RTW89_SET_FWCMD_CXHDR_LEN(cmd, len - H2C_LEN_CXDRVHDR);
4053
4054 RTW89_SET_FWCMD_CXROLE_CONNECT_CNT(cmd, role_info->connect_cnt);
4055 RTW89_SET_FWCMD_CXROLE_LINK_MODE(cmd, role_info->link_mode);
4056
4057 RTW89_SET_FWCMD_CXROLE_ROLE_NONE(cmd, bpos->none);
4058 RTW89_SET_FWCMD_CXROLE_ROLE_STA(cmd, bpos->station);
4059 RTW89_SET_FWCMD_CXROLE_ROLE_AP(cmd, bpos->ap);
4060 RTW89_SET_FWCMD_CXROLE_ROLE_VAP(cmd, bpos->vap);
4061 RTW89_SET_FWCMD_CXROLE_ROLE_ADHOC(cmd, bpos->adhoc);
4062 RTW89_SET_FWCMD_CXROLE_ROLE_ADHOC_MASTER(cmd, bpos->adhoc_master);
4063 RTW89_SET_FWCMD_CXROLE_ROLE_MESH(cmd, bpos->mesh);
4064 RTW89_SET_FWCMD_CXROLE_ROLE_MONITOR(cmd, bpos->moniter);
4065 RTW89_SET_FWCMD_CXROLE_ROLE_P2P_DEV(cmd, bpos->p2p_device);
4066 RTW89_SET_FWCMD_CXROLE_ROLE_P2P_GC(cmd, bpos->p2p_gc);
4067 RTW89_SET_FWCMD_CXROLE_ROLE_P2P_GO(cmd, bpos->p2p_go);
4068 RTW89_SET_FWCMD_CXROLE_ROLE_NAN(cmd, bpos->nan);
4069
4070 for (i = 0; i < RTW89_PORT_NUM; i++, active++) {
4071 RTW89_SET_FWCMD_CXROLE_ACT_CONNECTED(cmd, active->connected, i, offset);
4072 RTW89_SET_FWCMD_CXROLE_ACT_PID(cmd, active->pid, i, offset);
4073 RTW89_SET_FWCMD_CXROLE_ACT_PHY(cmd, active->phy, i, offset);
4074 RTW89_SET_FWCMD_CXROLE_ACT_NOA(cmd, active->noa, i, offset);
4075 RTW89_SET_FWCMD_CXROLE_ACT_BAND(cmd, active->band, i, offset);
4076 RTW89_SET_FWCMD_CXROLE_ACT_CLIENT_PS(cmd, active->client_ps, i, offset);
4077 RTW89_SET_FWCMD_CXROLE_ACT_BW(cmd, active->bw, i, offset);
4078 RTW89_SET_FWCMD_CXROLE_ACT_ROLE(cmd, active->role, i, offset);
4079 RTW89_SET_FWCMD_CXROLE_ACT_CH(cmd, active->ch, i, offset);
4080 RTW89_SET_FWCMD_CXROLE_ACT_TX_LVL(cmd, active->tx_lvl, i, offset);
4081 RTW89_SET_FWCMD_CXROLE_ACT_RX_LVL(cmd, active->rx_lvl, i, offset);
4082 RTW89_SET_FWCMD_CXROLE_ACT_TX_RATE(cmd, active->tx_rate, i, offset);
4083 RTW89_SET_FWCMD_CXROLE_ACT_RX_RATE(cmd, active->rx_rate, i, offset);
4084 }
4085
4086 rtw89_h2c_pkt_set_hdr(rtwdev, skb, FWCMD_TYPE_H2C,
4087 H2C_CAT_OUTSRC, BTFC_SET,
4088 SET_DRV_INFO, 0, 0,
4089 len);
4090
4091 ret = rtw89_h2c_tx(rtwdev, skb, false);
4092 if (ret) {
4093 rtw89_err(rtwdev, "failed to send h2c\n");
4094 goto fail;
4095 }
4096
4097 return 0;
4098 fail:
4099 dev_kfree_skb_any(skb);
4100
4101 return ret;
4102 }
4103
4104 #define H2C_LEN_CXDRVINFO_ROLE_SIZE_V1(max_role_num) \
4105 (4 + 16 * (max_role_num) + H2C_LEN_CXDRVINFO_ROLE_DBCC_LEN + H2C_LEN_CXDRVHDR)
4106
rtw89_fw_h2c_cxdrv_role_v1(struct rtw89_dev * rtwdev,u8 type)4107 int rtw89_fw_h2c_cxdrv_role_v1(struct rtw89_dev *rtwdev, u8 type)
4108 {
4109 struct rtw89_btc *btc = &rtwdev->btc;
4110 const struct rtw89_btc_ver *ver = btc->ver;
4111 struct rtw89_btc_wl_info *wl = &btc->cx.wl;
4112 struct rtw89_btc_wl_role_info_v1 *role_info = &wl->role_info_v1;
4113 struct rtw89_btc_wl_role_info_bpos *bpos = &role_info->role_map.role;
4114 struct rtw89_btc_wl_active_role_v1 *active = role_info->active_role_v1;
4115 struct sk_buff *skb;
4116 u32 len;
4117 u8 *cmd, offset;
4118 int ret;
4119 int i;
4120
4121 len = H2C_LEN_CXDRVINFO_ROLE_SIZE_V1(ver->max_role_num);
4122
4123 skb = rtw89_fw_h2c_alloc_skb_with_hdr(rtwdev, len);
4124 if (!skb) {
4125 rtw89_err(rtwdev, "failed to alloc skb for h2c cxdrv_role\n");
4126 return -ENOMEM;
4127 }
4128 skb_put(skb, len);
4129 cmd = skb->data;
4130
4131 RTW89_SET_FWCMD_CXHDR_TYPE(cmd, type);
4132 RTW89_SET_FWCMD_CXHDR_LEN(cmd, len - H2C_LEN_CXDRVHDR);
4133
4134 RTW89_SET_FWCMD_CXROLE_CONNECT_CNT(cmd, role_info->connect_cnt);
4135 RTW89_SET_FWCMD_CXROLE_LINK_MODE(cmd, role_info->link_mode);
4136
4137 RTW89_SET_FWCMD_CXROLE_ROLE_NONE(cmd, bpos->none);
4138 RTW89_SET_FWCMD_CXROLE_ROLE_STA(cmd, bpos->station);
4139 RTW89_SET_FWCMD_CXROLE_ROLE_AP(cmd, bpos->ap);
4140 RTW89_SET_FWCMD_CXROLE_ROLE_VAP(cmd, bpos->vap);
4141 RTW89_SET_FWCMD_CXROLE_ROLE_ADHOC(cmd, bpos->adhoc);
4142 RTW89_SET_FWCMD_CXROLE_ROLE_ADHOC_MASTER(cmd, bpos->adhoc_master);
4143 RTW89_SET_FWCMD_CXROLE_ROLE_MESH(cmd, bpos->mesh);
4144 RTW89_SET_FWCMD_CXROLE_ROLE_MONITOR(cmd, bpos->moniter);
4145 RTW89_SET_FWCMD_CXROLE_ROLE_P2P_DEV(cmd, bpos->p2p_device);
4146 RTW89_SET_FWCMD_CXROLE_ROLE_P2P_GC(cmd, bpos->p2p_gc);
4147 RTW89_SET_FWCMD_CXROLE_ROLE_P2P_GO(cmd, bpos->p2p_go);
4148 RTW89_SET_FWCMD_CXROLE_ROLE_NAN(cmd, bpos->nan);
4149
4150 offset = PORT_DATA_OFFSET;
4151 for (i = 0; i < RTW89_PORT_NUM; i++, active++) {
4152 RTW89_SET_FWCMD_CXROLE_ACT_CONNECTED(cmd, active->connected, i, offset);
4153 RTW89_SET_FWCMD_CXROLE_ACT_PID(cmd, active->pid, i, offset);
4154 RTW89_SET_FWCMD_CXROLE_ACT_PHY(cmd, active->phy, i, offset);
4155 RTW89_SET_FWCMD_CXROLE_ACT_NOA(cmd, active->noa, i, offset);
4156 RTW89_SET_FWCMD_CXROLE_ACT_BAND(cmd, active->band, i, offset);
4157 RTW89_SET_FWCMD_CXROLE_ACT_CLIENT_PS(cmd, active->client_ps, i, offset);
4158 RTW89_SET_FWCMD_CXROLE_ACT_BW(cmd, active->bw, i, offset);
4159 RTW89_SET_FWCMD_CXROLE_ACT_ROLE(cmd, active->role, i, offset);
4160 RTW89_SET_FWCMD_CXROLE_ACT_CH(cmd, active->ch, i, offset);
4161 RTW89_SET_FWCMD_CXROLE_ACT_TX_LVL(cmd, active->tx_lvl, i, offset);
4162 RTW89_SET_FWCMD_CXROLE_ACT_RX_LVL(cmd, active->rx_lvl, i, offset);
4163 RTW89_SET_FWCMD_CXROLE_ACT_TX_RATE(cmd, active->tx_rate, i, offset);
4164 RTW89_SET_FWCMD_CXROLE_ACT_RX_RATE(cmd, active->rx_rate, i, offset);
4165 RTW89_SET_FWCMD_CXROLE_ACT_NOA_DUR(cmd, active->noa_duration, i, offset);
4166 }
4167
4168 offset = len - H2C_LEN_CXDRVINFO_ROLE_DBCC_LEN;
4169 RTW89_SET_FWCMD_CXROLE_MROLE_TYPE(cmd, role_info->mrole_type, offset);
4170 RTW89_SET_FWCMD_CXROLE_MROLE_NOA(cmd, role_info->mrole_noa_duration, offset);
4171 RTW89_SET_FWCMD_CXROLE_DBCC_EN(cmd, role_info->dbcc_en, offset);
4172 RTW89_SET_FWCMD_CXROLE_DBCC_CHG(cmd, role_info->dbcc_chg, offset);
4173 RTW89_SET_FWCMD_CXROLE_DBCC_2G_PHY(cmd, role_info->dbcc_2g_phy, offset);
4174 RTW89_SET_FWCMD_CXROLE_LINK_MODE_CHG(cmd, role_info->link_mode_chg, offset);
4175
4176 rtw89_h2c_pkt_set_hdr(rtwdev, skb, FWCMD_TYPE_H2C,
4177 H2C_CAT_OUTSRC, BTFC_SET,
4178 SET_DRV_INFO, 0, 0,
4179 len);
4180
4181 ret = rtw89_h2c_tx(rtwdev, skb, false);
4182 if (ret) {
4183 rtw89_err(rtwdev, "failed to send h2c\n");
4184 goto fail;
4185 }
4186
4187 return 0;
4188 fail:
4189 dev_kfree_skb_any(skb);
4190
4191 return ret;
4192 }
4193
4194 #define H2C_LEN_CXDRVINFO_ROLE_SIZE_V2(max_role_num) \
4195 (4 + 8 * (max_role_num) + H2C_LEN_CXDRVINFO_ROLE_DBCC_LEN + H2C_LEN_CXDRVHDR)
4196
rtw89_fw_h2c_cxdrv_role_v2(struct rtw89_dev * rtwdev,u8 type)4197 int rtw89_fw_h2c_cxdrv_role_v2(struct rtw89_dev *rtwdev, u8 type)
4198 {
4199 struct rtw89_btc *btc = &rtwdev->btc;
4200 const struct rtw89_btc_ver *ver = btc->ver;
4201 struct rtw89_btc_wl_info *wl = &btc->cx.wl;
4202 struct rtw89_btc_wl_role_info_v2 *role_info = &wl->role_info_v2;
4203 struct rtw89_btc_wl_role_info_bpos *bpos = &role_info->role_map.role;
4204 struct rtw89_btc_wl_active_role_v2 *active = role_info->active_role_v2;
4205 struct sk_buff *skb;
4206 u32 len;
4207 u8 *cmd, offset;
4208 int ret;
4209 int i;
4210
4211 len = H2C_LEN_CXDRVINFO_ROLE_SIZE_V2(ver->max_role_num);
4212
4213 skb = rtw89_fw_h2c_alloc_skb_with_hdr(rtwdev, len);
4214 if (!skb) {
4215 rtw89_err(rtwdev, "failed to alloc skb for h2c cxdrv_role\n");
4216 return -ENOMEM;
4217 }
4218 skb_put(skb, len);
4219 cmd = skb->data;
4220
4221 RTW89_SET_FWCMD_CXHDR_TYPE(cmd, type);
4222 RTW89_SET_FWCMD_CXHDR_LEN(cmd, len - H2C_LEN_CXDRVHDR);
4223
4224 RTW89_SET_FWCMD_CXROLE_CONNECT_CNT(cmd, role_info->connect_cnt);
4225 RTW89_SET_FWCMD_CXROLE_LINK_MODE(cmd, role_info->link_mode);
4226
4227 RTW89_SET_FWCMD_CXROLE_ROLE_NONE(cmd, bpos->none);
4228 RTW89_SET_FWCMD_CXROLE_ROLE_STA(cmd, bpos->station);
4229 RTW89_SET_FWCMD_CXROLE_ROLE_AP(cmd, bpos->ap);
4230 RTW89_SET_FWCMD_CXROLE_ROLE_VAP(cmd, bpos->vap);
4231 RTW89_SET_FWCMD_CXROLE_ROLE_ADHOC(cmd, bpos->adhoc);
4232 RTW89_SET_FWCMD_CXROLE_ROLE_ADHOC_MASTER(cmd, bpos->adhoc_master);
4233 RTW89_SET_FWCMD_CXROLE_ROLE_MESH(cmd, bpos->mesh);
4234 RTW89_SET_FWCMD_CXROLE_ROLE_MONITOR(cmd, bpos->moniter);
4235 RTW89_SET_FWCMD_CXROLE_ROLE_P2P_DEV(cmd, bpos->p2p_device);
4236 RTW89_SET_FWCMD_CXROLE_ROLE_P2P_GC(cmd, bpos->p2p_gc);
4237 RTW89_SET_FWCMD_CXROLE_ROLE_P2P_GO(cmd, bpos->p2p_go);
4238 RTW89_SET_FWCMD_CXROLE_ROLE_NAN(cmd, bpos->nan);
4239
4240 offset = PORT_DATA_OFFSET;
4241 for (i = 0; i < RTW89_PORT_NUM; i++, active++) {
4242 RTW89_SET_FWCMD_CXROLE_ACT_CONNECTED_V2(cmd, active->connected, i, offset);
4243 RTW89_SET_FWCMD_CXROLE_ACT_PID_V2(cmd, active->pid, i, offset);
4244 RTW89_SET_FWCMD_CXROLE_ACT_PHY_V2(cmd, active->phy, i, offset);
4245 RTW89_SET_FWCMD_CXROLE_ACT_NOA_V2(cmd, active->noa, i, offset);
4246 RTW89_SET_FWCMD_CXROLE_ACT_BAND_V2(cmd, active->band, i, offset);
4247 RTW89_SET_FWCMD_CXROLE_ACT_CLIENT_PS_V2(cmd, active->client_ps, i, offset);
4248 RTW89_SET_FWCMD_CXROLE_ACT_BW_V2(cmd, active->bw, i, offset);
4249 RTW89_SET_FWCMD_CXROLE_ACT_ROLE_V2(cmd, active->role, i, offset);
4250 RTW89_SET_FWCMD_CXROLE_ACT_CH_V2(cmd, active->ch, i, offset);
4251 RTW89_SET_FWCMD_CXROLE_ACT_NOA_DUR_V2(cmd, active->noa_duration, i, offset);
4252 }
4253
4254 offset = len - H2C_LEN_CXDRVINFO_ROLE_DBCC_LEN;
4255 RTW89_SET_FWCMD_CXROLE_MROLE_TYPE(cmd, role_info->mrole_type, offset);
4256 RTW89_SET_FWCMD_CXROLE_MROLE_NOA(cmd, role_info->mrole_noa_duration, offset);
4257 RTW89_SET_FWCMD_CXROLE_DBCC_EN(cmd, role_info->dbcc_en, offset);
4258 RTW89_SET_FWCMD_CXROLE_DBCC_CHG(cmd, role_info->dbcc_chg, offset);
4259 RTW89_SET_FWCMD_CXROLE_DBCC_2G_PHY(cmd, role_info->dbcc_2g_phy, offset);
4260 RTW89_SET_FWCMD_CXROLE_LINK_MODE_CHG(cmd, role_info->link_mode_chg, offset);
4261
4262 rtw89_h2c_pkt_set_hdr(rtwdev, skb, FWCMD_TYPE_H2C,
4263 H2C_CAT_OUTSRC, BTFC_SET,
4264 SET_DRV_INFO, 0, 0,
4265 len);
4266
4267 ret = rtw89_h2c_tx(rtwdev, skb, false);
4268 if (ret) {
4269 rtw89_err(rtwdev, "failed to send h2c\n");
4270 goto fail;
4271 }
4272
4273 return 0;
4274 fail:
4275 dev_kfree_skb_any(skb);
4276
4277 return ret;
4278 }
4279
rtw89_fw_h2c_cxdrv_role_v8(struct rtw89_dev * rtwdev,u8 type)4280 int rtw89_fw_h2c_cxdrv_role_v8(struct rtw89_dev *rtwdev, u8 type)
4281 {
4282 struct rtw89_btc *btc = &rtwdev->btc;
4283 struct rtw89_btc_wl_role_info_v8 *role = &btc->cx.wl.role_info_v8;
4284 struct rtw89_h2c_cxrole_v8 *h2c;
4285 u32 len = sizeof(*h2c);
4286 struct sk_buff *skb;
4287 int ret;
4288
4289 skb = rtw89_fw_h2c_alloc_skb_with_hdr(rtwdev, len);
4290 if (!skb) {
4291 rtw89_err(rtwdev, "failed to alloc skb for h2c cxdrv_ctrl\n");
4292 return -ENOMEM;
4293 }
4294 skb_put(skb, len);
4295 h2c = (struct rtw89_h2c_cxrole_v8 *)skb->data;
4296
4297 h2c->hdr.type = type;
4298 h2c->hdr.len = len - H2C_LEN_CXDRVHDR_V7;
4299 memcpy(&h2c->_u8, role, sizeof(h2c->_u8));
4300 h2c->_u32.role_map = cpu_to_le32(role->role_map);
4301 h2c->_u32.mrole_type = cpu_to_le32(role->mrole_type);
4302 h2c->_u32.mrole_noa_duration = cpu_to_le32(role->mrole_noa_duration);
4303
4304 rtw89_h2c_pkt_set_hdr(rtwdev, skb, FWCMD_TYPE_H2C,
4305 H2C_CAT_OUTSRC, BTFC_SET,
4306 SET_DRV_INFO, 0, 0,
4307 len);
4308
4309 ret = rtw89_h2c_tx(rtwdev, skb, false);
4310 if (ret) {
4311 rtw89_err(rtwdev, "failed to send h2c\n");
4312 goto fail;
4313 }
4314
4315 return 0;
4316 fail:
4317 dev_kfree_skb_any(skb);
4318
4319 return ret;
4320 }
4321
4322 #define H2C_LEN_CXDRVINFO_CTRL (4 + H2C_LEN_CXDRVHDR)
rtw89_fw_h2c_cxdrv_ctrl(struct rtw89_dev * rtwdev,u8 type)4323 int rtw89_fw_h2c_cxdrv_ctrl(struct rtw89_dev *rtwdev, u8 type)
4324 {
4325 struct rtw89_btc *btc = &rtwdev->btc;
4326 const struct rtw89_btc_ver *ver = btc->ver;
4327 struct rtw89_btc_ctrl *ctrl = &btc->ctrl.ctrl;
4328 struct sk_buff *skb;
4329 u8 *cmd;
4330 int ret;
4331
4332 skb = rtw89_fw_h2c_alloc_skb_with_hdr(rtwdev, H2C_LEN_CXDRVINFO_CTRL);
4333 if (!skb) {
4334 rtw89_err(rtwdev, "failed to alloc skb for h2c cxdrv_ctrl\n");
4335 return -ENOMEM;
4336 }
4337 skb_put(skb, H2C_LEN_CXDRVINFO_CTRL);
4338 cmd = skb->data;
4339
4340 RTW89_SET_FWCMD_CXHDR_TYPE(cmd, type);
4341 RTW89_SET_FWCMD_CXHDR_LEN(cmd, H2C_LEN_CXDRVINFO_CTRL - H2C_LEN_CXDRVHDR);
4342
4343 RTW89_SET_FWCMD_CXCTRL_MANUAL(cmd, ctrl->manual);
4344 RTW89_SET_FWCMD_CXCTRL_IGNORE_BT(cmd, ctrl->igno_bt);
4345 RTW89_SET_FWCMD_CXCTRL_ALWAYS_FREERUN(cmd, ctrl->always_freerun);
4346 if (ver->fcxctrl == 0)
4347 RTW89_SET_FWCMD_CXCTRL_TRACE_STEP(cmd, ctrl->trace_step);
4348
4349 rtw89_h2c_pkt_set_hdr(rtwdev, skb, FWCMD_TYPE_H2C,
4350 H2C_CAT_OUTSRC, BTFC_SET,
4351 SET_DRV_INFO, 0, 0,
4352 H2C_LEN_CXDRVINFO_CTRL);
4353
4354 ret = rtw89_h2c_tx(rtwdev, skb, false);
4355 if (ret) {
4356 rtw89_err(rtwdev, "failed to send h2c\n");
4357 goto fail;
4358 }
4359
4360 return 0;
4361 fail:
4362 dev_kfree_skb_any(skb);
4363
4364 return ret;
4365 }
4366
rtw89_fw_h2c_cxdrv_ctrl_v7(struct rtw89_dev * rtwdev,u8 type)4367 int rtw89_fw_h2c_cxdrv_ctrl_v7(struct rtw89_dev *rtwdev, u8 type)
4368 {
4369 struct rtw89_btc *btc = &rtwdev->btc;
4370 struct rtw89_btc_ctrl_v7 *ctrl = &btc->ctrl.ctrl_v7;
4371 struct rtw89_h2c_cxctrl_v7 *h2c;
4372 u32 len = sizeof(*h2c);
4373 struct sk_buff *skb;
4374 int ret;
4375
4376 skb = rtw89_fw_h2c_alloc_skb_with_hdr(rtwdev, len);
4377 if (!skb) {
4378 rtw89_err(rtwdev, "failed to alloc skb for h2c cxdrv_ctrl\n");
4379 return -ENOMEM;
4380 }
4381 skb_put(skb, len);
4382 h2c = (struct rtw89_h2c_cxctrl_v7 *)skb->data;
4383
4384 h2c->hdr.type = type;
4385 h2c->hdr.ver = btc->ver->fcxctrl;
4386 h2c->hdr.len = sizeof(*h2c) - H2C_LEN_CXDRVHDR_V7;
4387 h2c->ctrl = *ctrl;
4388
4389 rtw89_h2c_pkt_set_hdr(rtwdev, skb, FWCMD_TYPE_H2C,
4390 H2C_CAT_OUTSRC, BTFC_SET,
4391 SET_DRV_INFO, 0, 0, len);
4392
4393 ret = rtw89_h2c_tx(rtwdev, skb, false);
4394 if (ret) {
4395 rtw89_err(rtwdev, "failed to send h2c\n");
4396 goto fail;
4397 }
4398
4399 return 0;
4400 fail:
4401 dev_kfree_skb_any(skb);
4402
4403 return ret;
4404 }
4405
4406 #define H2C_LEN_CXDRVINFO_TRX (28 + H2C_LEN_CXDRVHDR)
rtw89_fw_h2c_cxdrv_trx(struct rtw89_dev * rtwdev,u8 type)4407 int rtw89_fw_h2c_cxdrv_trx(struct rtw89_dev *rtwdev, u8 type)
4408 {
4409 struct rtw89_btc *btc = &rtwdev->btc;
4410 struct rtw89_btc_trx_info *trx = &btc->dm.trx_info;
4411 struct sk_buff *skb;
4412 u8 *cmd;
4413 int ret;
4414
4415 skb = rtw89_fw_h2c_alloc_skb_with_hdr(rtwdev, H2C_LEN_CXDRVINFO_TRX);
4416 if (!skb) {
4417 rtw89_err(rtwdev, "failed to alloc skb for h2c cxdrv_trx\n");
4418 return -ENOMEM;
4419 }
4420 skb_put(skb, H2C_LEN_CXDRVINFO_TRX);
4421 cmd = skb->data;
4422
4423 RTW89_SET_FWCMD_CXHDR_TYPE(cmd, type);
4424 RTW89_SET_FWCMD_CXHDR_LEN(cmd, H2C_LEN_CXDRVINFO_TRX - H2C_LEN_CXDRVHDR);
4425
4426 RTW89_SET_FWCMD_CXTRX_TXLV(cmd, trx->tx_lvl);
4427 RTW89_SET_FWCMD_CXTRX_RXLV(cmd, trx->rx_lvl);
4428 RTW89_SET_FWCMD_CXTRX_WLRSSI(cmd, trx->wl_rssi);
4429 RTW89_SET_FWCMD_CXTRX_BTRSSI(cmd, trx->bt_rssi);
4430 RTW89_SET_FWCMD_CXTRX_TXPWR(cmd, trx->tx_power);
4431 RTW89_SET_FWCMD_CXTRX_RXGAIN(cmd, trx->rx_gain);
4432 RTW89_SET_FWCMD_CXTRX_BTTXPWR(cmd, trx->bt_tx_power);
4433 RTW89_SET_FWCMD_CXTRX_BTRXGAIN(cmd, trx->bt_rx_gain);
4434 RTW89_SET_FWCMD_CXTRX_CN(cmd, trx->cn);
4435 RTW89_SET_FWCMD_CXTRX_NHM(cmd, trx->nhm);
4436 RTW89_SET_FWCMD_CXTRX_BTPROFILE(cmd, trx->bt_profile);
4437 RTW89_SET_FWCMD_CXTRX_RSVD2(cmd, trx->rsvd2);
4438 RTW89_SET_FWCMD_CXTRX_TXRATE(cmd, trx->tx_rate);
4439 RTW89_SET_FWCMD_CXTRX_RXRATE(cmd, trx->rx_rate);
4440 RTW89_SET_FWCMD_CXTRX_TXTP(cmd, trx->tx_tp);
4441 RTW89_SET_FWCMD_CXTRX_RXTP(cmd, trx->rx_tp);
4442 RTW89_SET_FWCMD_CXTRX_RXERRRA(cmd, trx->rx_err_ratio);
4443
4444 rtw89_h2c_pkt_set_hdr(rtwdev, skb, FWCMD_TYPE_H2C,
4445 H2C_CAT_OUTSRC, BTFC_SET,
4446 SET_DRV_INFO, 0, 0,
4447 H2C_LEN_CXDRVINFO_TRX);
4448
4449 ret = rtw89_h2c_tx(rtwdev, skb, false);
4450 if (ret) {
4451 rtw89_err(rtwdev, "failed to send h2c\n");
4452 goto fail;
4453 }
4454
4455 return 0;
4456 fail:
4457 dev_kfree_skb_any(skb);
4458
4459 return ret;
4460 }
4461
4462 #define H2C_LEN_CXDRVINFO_RFK (4 + H2C_LEN_CXDRVHDR)
rtw89_fw_h2c_cxdrv_rfk(struct rtw89_dev * rtwdev,u8 type)4463 int rtw89_fw_h2c_cxdrv_rfk(struct rtw89_dev *rtwdev, u8 type)
4464 {
4465 struct rtw89_btc *btc = &rtwdev->btc;
4466 struct rtw89_btc_wl_info *wl = &btc->cx.wl;
4467 struct rtw89_btc_wl_rfk_info *rfk_info = &wl->rfk_info;
4468 struct sk_buff *skb;
4469 u8 *cmd;
4470 int ret;
4471
4472 skb = rtw89_fw_h2c_alloc_skb_with_hdr(rtwdev, H2C_LEN_CXDRVINFO_RFK);
4473 if (!skb) {
4474 rtw89_err(rtwdev, "failed to alloc skb for h2c cxdrv_ctrl\n");
4475 return -ENOMEM;
4476 }
4477 skb_put(skb, H2C_LEN_CXDRVINFO_RFK);
4478 cmd = skb->data;
4479
4480 RTW89_SET_FWCMD_CXHDR_TYPE(cmd, type);
4481 RTW89_SET_FWCMD_CXHDR_LEN(cmd, H2C_LEN_CXDRVINFO_RFK - H2C_LEN_CXDRVHDR);
4482
4483 RTW89_SET_FWCMD_CXRFK_STATE(cmd, rfk_info->state);
4484 RTW89_SET_FWCMD_CXRFK_PATH_MAP(cmd, rfk_info->path_map);
4485 RTW89_SET_FWCMD_CXRFK_PHY_MAP(cmd, rfk_info->phy_map);
4486 RTW89_SET_FWCMD_CXRFK_BAND(cmd, rfk_info->band);
4487 RTW89_SET_FWCMD_CXRFK_TYPE(cmd, rfk_info->type);
4488
4489 rtw89_h2c_pkt_set_hdr(rtwdev, skb, FWCMD_TYPE_H2C,
4490 H2C_CAT_OUTSRC, BTFC_SET,
4491 SET_DRV_INFO, 0, 0,
4492 H2C_LEN_CXDRVINFO_RFK);
4493
4494 ret = rtw89_h2c_tx(rtwdev, skb, false);
4495 if (ret) {
4496 rtw89_err(rtwdev, "failed to send h2c\n");
4497 goto fail;
4498 }
4499
4500 return 0;
4501 fail:
4502 dev_kfree_skb_any(skb);
4503
4504 return ret;
4505 }
4506
4507 #define H2C_LEN_PKT_OFLD 4
rtw89_fw_h2c_del_pkt_offload(struct rtw89_dev * rtwdev,u8 id)4508 int rtw89_fw_h2c_del_pkt_offload(struct rtw89_dev *rtwdev, u8 id)
4509 {
4510 struct rtw89_wait_info *wait = &rtwdev->mac.fw_ofld_wait;
4511 struct sk_buff *skb;
4512 unsigned int cond;
4513 u8 *cmd;
4514 int ret;
4515
4516 skb = rtw89_fw_h2c_alloc_skb_with_hdr(rtwdev, H2C_LEN_PKT_OFLD);
4517 if (!skb) {
4518 rtw89_err(rtwdev, "failed to alloc skb for h2c pkt offload\n");
4519 return -ENOMEM;
4520 }
4521 skb_put(skb, H2C_LEN_PKT_OFLD);
4522 cmd = skb->data;
4523
4524 RTW89_SET_FWCMD_PACKET_OFLD_PKT_IDX(cmd, id);
4525 RTW89_SET_FWCMD_PACKET_OFLD_PKT_OP(cmd, RTW89_PKT_OFLD_OP_DEL);
4526
4527 rtw89_h2c_pkt_set_hdr(rtwdev, skb, FWCMD_TYPE_H2C,
4528 H2C_CAT_MAC, H2C_CL_MAC_FW_OFLD,
4529 H2C_FUNC_PACKET_OFLD, 1, 1,
4530 H2C_LEN_PKT_OFLD);
4531
4532 cond = RTW89_FW_OFLD_WAIT_COND_PKT_OFLD(id, RTW89_PKT_OFLD_OP_DEL);
4533
4534 ret = rtw89_h2c_tx_and_wait(rtwdev, skb, wait, cond);
4535 if (ret < 0) {
4536 rtw89_debug(rtwdev, RTW89_DBG_FW,
4537 "failed to del pkt ofld: id %d, ret %d\n",
4538 id, ret);
4539 return ret;
4540 }
4541
4542 rtw89_core_release_bit_map(rtwdev->pkt_offload, id);
4543 return 0;
4544 }
4545
rtw89_fw_h2c_add_pkt_offload(struct rtw89_dev * rtwdev,u8 * id,struct sk_buff * skb_ofld)4546 int rtw89_fw_h2c_add_pkt_offload(struct rtw89_dev *rtwdev, u8 *id,
4547 struct sk_buff *skb_ofld)
4548 {
4549 struct rtw89_wait_info *wait = &rtwdev->mac.fw_ofld_wait;
4550 struct sk_buff *skb;
4551 unsigned int cond;
4552 u8 *cmd;
4553 u8 alloc_id;
4554 int ret;
4555
4556 alloc_id = rtw89_core_acquire_bit_map(rtwdev->pkt_offload,
4557 RTW89_MAX_PKT_OFLD_NUM);
4558 if (alloc_id == RTW89_MAX_PKT_OFLD_NUM)
4559 return -ENOSPC;
4560
4561 *id = alloc_id;
4562
4563 skb = rtw89_fw_h2c_alloc_skb_with_hdr(rtwdev, H2C_LEN_PKT_OFLD + skb_ofld->len);
4564 if (!skb) {
4565 rtw89_err(rtwdev, "failed to alloc skb for h2c pkt offload\n");
4566 rtw89_core_release_bit_map(rtwdev->pkt_offload, alloc_id);
4567 return -ENOMEM;
4568 }
4569 skb_put(skb, H2C_LEN_PKT_OFLD);
4570 cmd = skb->data;
4571
4572 RTW89_SET_FWCMD_PACKET_OFLD_PKT_IDX(cmd, alloc_id);
4573 RTW89_SET_FWCMD_PACKET_OFLD_PKT_OP(cmd, RTW89_PKT_OFLD_OP_ADD);
4574 RTW89_SET_FWCMD_PACKET_OFLD_PKT_LENGTH(cmd, skb_ofld->len);
4575 skb_put_data(skb, skb_ofld->data, skb_ofld->len);
4576
4577 rtw89_h2c_pkt_set_hdr(rtwdev, skb, FWCMD_TYPE_H2C,
4578 H2C_CAT_MAC, H2C_CL_MAC_FW_OFLD,
4579 H2C_FUNC_PACKET_OFLD, 1, 1,
4580 H2C_LEN_PKT_OFLD + skb_ofld->len);
4581
4582 cond = RTW89_FW_OFLD_WAIT_COND_PKT_OFLD(alloc_id, RTW89_PKT_OFLD_OP_ADD);
4583
4584 ret = rtw89_h2c_tx_and_wait(rtwdev, skb, wait, cond);
4585 if (ret < 0) {
4586 rtw89_debug(rtwdev, RTW89_DBG_FW,
4587 "failed to add pkt ofld: id %d, ret %d\n",
4588 alloc_id, ret);
4589 rtw89_core_release_bit_map(rtwdev->pkt_offload, alloc_id);
4590 return ret;
4591 }
4592
4593 return 0;
4594 }
4595
rtw89_fw_h2c_scan_list_offload(struct rtw89_dev * rtwdev,int ch_num,struct list_head * chan_list)4596 int rtw89_fw_h2c_scan_list_offload(struct rtw89_dev *rtwdev, int ch_num,
4597 struct list_head *chan_list)
4598 {
4599 struct rtw89_wait_info *wait = &rtwdev->mac.fw_ofld_wait;
4600 struct rtw89_h2c_chinfo_elem *elem;
4601 struct rtw89_mac_chinfo *ch_info;
4602 struct rtw89_h2c_chinfo *h2c;
4603 struct sk_buff *skb;
4604 unsigned int cond;
4605 int skb_len;
4606 int ret;
4607
4608 static_assert(sizeof(*elem) == RTW89_MAC_CHINFO_SIZE);
4609
4610 skb_len = struct_size(h2c, elem, ch_num);
4611 skb = rtw89_fw_h2c_alloc_skb_with_hdr(rtwdev, skb_len);
4612 if (!skb) {
4613 rtw89_err(rtwdev, "failed to alloc skb for h2c scan list\n");
4614 return -ENOMEM;
4615 }
4616 skb_put(skb, sizeof(*h2c));
4617 h2c = (struct rtw89_h2c_chinfo *)skb->data;
4618
4619 h2c->ch_num = ch_num;
4620 h2c->elem_size = sizeof(*elem) / 4; /* in unit of 4 bytes */
4621
4622 list_for_each_entry(ch_info, chan_list, list) {
4623 elem = (struct rtw89_h2c_chinfo_elem *)skb_put(skb, sizeof(*elem));
4624
4625 elem->w0 = le32_encode_bits(ch_info->period, RTW89_H2C_CHINFO_W0_PERIOD) |
4626 le32_encode_bits(ch_info->dwell_time, RTW89_H2C_CHINFO_W0_DWELL) |
4627 le32_encode_bits(ch_info->central_ch, RTW89_H2C_CHINFO_W0_CENTER_CH) |
4628 le32_encode_bits(ch_info->pri_ch, RTW89_H2C_CHINFO_W0_PRI_CH);
4629
4630 elem->w1 = le32_encode_bits(ch_info->bw, RTW89_H2C_CHINFO_W1_BW) |
4631 le32_encode_bits(ch_info->notify_action, RTW89_H2C_CHINFO_W1_ACTION) |
4632 le32_encode_bits(ch_info->num_pkt, RTW89_H2C_CHINFO_W1_NUM_PKT) |
4633 le32_encode_bits(ch_info->tx_pkt, RTW89_H2C_CHINFO_W1_TX) |
4634 le32_encode_bits(ch_info->pause_data, RTW89_H2C_CHINFO_W1_PAUSE_DATA) |
4635 le32_encode_bits(ch_info->ch_band, RTW89_H2C_CHINFO_W1_BAND) |
4636 le32_encode_bits(ch_info->probe_id, RTW89_H2C_CHINFO_W1_PKT_ID) |
4637 le32_encode_bits(ch_info->dfs_ch, RTW89_H2C_CHINFO_W1_DFS) |
4638 le32_encode_bits(ch_info->tx_null, RTW89_H2C_CHINFO_W1_TX_NULL) |
4639 le32_encode_bits(ch_info->rand_seq_num, RTW89_H2C_CHINFO_W1_RANDOM);
4640
4641 elem->w2 = le32_encode_bits(ch_info->pkt_id[0], RTW89_H2C_CHINFO_W2_PKT0) |
4642 le32_encode_bits(ch_info->pkt_id[1], RTW89_H2C_CHINFO_W2_PKT1) |
4643 le32_encode_bits(ch_info->pkt_id[2], RTW89_H2C_CHINFO_W2_PKT2) |
4644 le32_encode_bits(ch_info->pkt_id[3], RTW89_H2C_CHINFO_W2_PKT3);
4645
4646 elem->w3 = le32_encode_bits(ch_info->pkt_id[4], RTW89_H2C_CHINFO_W3_PKT4) |
4647 le32_encode_bits(ch_info->pkt_id[5], RTW89_H2C_CHINFO_W3_PKT5) |
4648 le32_encode_bits(ch_info->pkt_id[6], RTW89_H2C_CHINFO_W3_PKT6) |
4649 le32_encode_bits(ch_info->pkt_id[7], RTW89_H2C_CHINFO_W3_PKT7);
4650 }
4651
4652 rtw89_h2c_pkt_set_hdr(rtwdev, skb, FWCMD_TYPE_H2C,
4653 H2C_CAT_MAC, H2C_CL_MAC_FW_OFLD,
4654 H2C_FUNC_ADD_SCANOFLD_CH, 1, 1, skb_len);
4655
4656 cond = RTW89_SCANOFLD_WAIT_COND_ADD_CH;
4657
4658 ret = rtw89_h2c_tx_and_wait(rtwdev, skb, wait, cond);
4659 if (ret) {
4660 rtw89_debug(rtwdev, RTW89_DBG_FW, "failed to add scan ofld ch\n");
4661 return ret;
4662 }
4663
4664 return 0;
4665 }
4666
rtw89_fw_h2c_scan_list_offload_be(struct rtw89_dev * rtwdev,int ch_num,struct list_head * chan_list)4667 int rtw89_fw_h2c_scan_list_offload_be(struct rtw89_dev *rtwdev, int ch_num,
4668 struct list_head *chan_list)
4669 {
4670 struct rtw89_wait_info *wait = &rtwdev->mac.fw_ofld_wait;
4671 struct rtw89_h2c_chinfo_elem_be *elem;
4672 struct rtw89_mac_chinfo_be *ch_info;
4673 struct rtw89_h2c_chinfo *h2c;
4674 struct sk_buff *skb;
4675 unsigned int cond;
4676 int skb_len;
4677 int ret;
4678
4679 static_assert(sizeof(*elem) == RTW89_MAC_CHINFO_SIZE);
4680
4681 skb_len = struct_size(h2c, elem, ch_num);
4682 skb = rtw89_fw_h2c_alloc_skb_with_hdr(rtwdev, skb_len);
4683 if (!skb) {
4684 rtw89_err(rtwdev, "failed to alloc skb for h2c scan list\n");
4685 return -ENOMEM;
4686 }
4687
4688 skb_put(skb, sizeof(*h2c));
4689 h2c = (struct rtw89_h2c_chinfo *)skb->data;
4690
4691 h2c->ch_num = ch_num;
4692 h2c->elem_size = sizeof(*elem) / 4; /* in unit of 4 bytes */
4693 h2c->arg = u8_encode_bits(RTW89_PHY_0, RTW89_H2C_CHINFO_ARG_MAC_IDX_MASK);
4694
4695 list_for_each_entry(ch_info, chan_list, list) {
4696 elem = (struct rtw89_h2c_chinfo_elem_be *)skb_put(skb, sizeof(*elem));
4697
4698 elem->w0 = le32_encode_bits(ch_info->period, RTW89_H2C_CHINFO_BE_W0_PERIOD) |
4699 le32_encode_bits(ch_info->dwell_time, RTW89_H2C_CHINFO_BE_W0_DWELL) |
4700 le32_encode_bits(ch_info->central_ch,
4701 RTW89_H2C_CHINFO_BE_W0_CENTER_CH) |
4702 le32_encode_bits(ch_info->pri_ch, RTW89_H2C_CHINFO_BE_W0_PRI_CH);
4703
4704 elem->w1 = le32_encode_bits(ch_info->bw, RTW89_H2C_CHINFO_BE_W1_BW) |
4705 le32_encode_bits(ch_info->ch_band, RTW89_H2C_CHINFO_BE_W1_CH_BAND) |
4706 le32_encode_bits(ch_info->dfs_ch, RTW89_H2C_CHINFO_BE_W1_DFS) |
4707 le32_encode_bits(ch_info->pause_data,
4708 RTW89_H2C_CHINFO_BE_W1_PAUSE_DATA) |
4709 le32_encode_bits(ch_info->tx_null, RTW89_H2C_CHINFO_BE_W1_TX_NULL) |
4710 le32_encode_bits(ch_info->rand_seq_num,
4711 RTW89_H2C_CHINFO_BE_W1_RANDOM) |
4712 le32_encode_bits(ch_info->notify_action,
4713 RTW89_H2C_CHINFO_BE_W1_NOTIFY) |
4714 le32_encode_bits(ch_info->probe_id != 0xff ? 1 : 0,
4715 RTW89_H2C_CHINFO_BE_W1_PROBE) |
4716 le32_encode_bits(ch_info->leave_crit,
4717 RTW89_H2C_CHINFO_BE_W1_EARLY_LEAVE_CRIT) |
4718 le32_encode_bits(ch_info->chkpt_timer,
4719 RTW89_H2C_CHINFO_BE_W1_CHKPT_TIMER);
4720
4721 elem->w2 = le32_encode_bits(ch_info->leave_time,
4722 RTW89_H2C_CHINFO_BE_W2_EARLY_LEAVE_TIME) |
4723 le32_encode_bits(ch_info->leave_th,
4724 RTW89_H2C_CHINFO_BE_W2_EARLY_LEAVE_TH) |
4725 le32_encode_bits(ch_info->tx_pkt_ctrl,
4726 RTW89_H2C_CHINFO_BE_W2_TX_PKT_CTRL);
4727
4728 elem->w3 = le32_encode_bits(ch_info->pkt_id[0], RTW89_H2C_CHINFO_BE_W3_PKT0) |
4729 le32_encode_bits(ch_info->pkt_id[1], RTW89_H2C_CHINFO_BE_W3_PKT1) |
4730 le32_encode_bits(ch_info->pkt_id[2], RTW89_H2C_CHINFO_BE_W3_PKT2) |
4731 le32_encode_bits(ch_info->pkt_id[3], RTW89_H2C_CHINFO_BE_W3_PKT3);
4732
4733 elem->w4 = le32_encode_bits(ch_info->pkt_id[4], RTW89_H2C_CHINFO_BE_W4_PKT4) |
4734 le32_encode_bits(ch_info->pkt_id[5], RTW89_H2C_CHINFO_BE_W4_PKT5) |
4735 le32_encode_bits(ch_info->pkt_id[6], RTW89_H2C_CHINFO_BE_W4_PKT6) |
4736 le32_encode_bits(ch_info->pkt_id[7], RTW89_H2C_CHINFO_BE_W4_PKT7);
4737
4738 elem->w5 = le32_encode_bits(ch_info->sw_def, RTW89_H2C_CHINFO_BE_W5_SW_DEF) |
4739 le32_encode_bits(ch_info->fw_probe0_ssids,
4740 RTW89_H2C_CHINFO_BE_W5_FW_PROBE0_SSIDS);
4741
4742 elem->w6 = le32_encode_bits(ch_info->fw_probe0_shortssids,
4743 RTW89_H2C_CHINFO_BE_W6_FW_PROBE0_SHORTSSIDS) |
4744 le32_encode_bits(ch_info->fw_probe0_bssids,
4745 RTW89_H2C_CHINFO_BE_W6_FW_PROBE0_BSSIDS);
4746 }
4747
4748 rtw89_h2c_pkt_set_hdr(rtwdev, skb, FWCMD_TYPE_H2C,
4749 H2C_CAT_MAC, H2C_CL_MAC_FW_OFLD,
4750 H2C_FUNC_ADD_SCANOFLD_CH, 1, 1, skb_len);
4751
4752 cond = RTW89_SCANOFLD_WAIT_COND_ADD_CH;
4753
4754 ret = rtw89_h2c_tx_and_wait(rtwdev, skb, wait, cond);
4755 if (ret) {
4756 rtw89_debug(rtwdev, RTW89_DBG_FW, "failed to add scan ofld ch\n");
4757 return ret;
4758 }
4759
4760 return 0;
4761 }
4762
rtw89_fw_h2c_scan_offload(struct rtw89_dev * rtwdev,struct rtw89_scan_option * option,struct rtw89_vif * rtwvif)4763 int rtw89_fw_h2c_scan_offload(struct rtw89_dev *rtwdev,
4764 struct rtw89_scan_option *option,
4765 struct rtw89_vif *rtwvif)
4766 {
4767 struct rtw89_wait_info *wait = &rtwdev->mac.fw_ofld_wait;
4768 struct rtw89_chan *op = &rtwdev->scan_info.op_chan;
4769 struct rtw89_h2c_scanofld *h2c;
4770 u32 len = sizeof(*h2c);
4771 struct sk_buff *skb;
4772 unsigned int cond;
4773 int ret;
4774
4775 skb = rtw89_fw_h2c_alloc_skb_with_hdr(rtwdev, len);
4776 if (!skb) {
4777 rtw89_err(rtwdev, "failed to alloc skb for h2c scan offload\n");
4778 return -ENOMEM;
4779 }
4780 skb_put(skb, len);
4781 h2c = (struct rtw89_h2c_scanofld *)skb->data;
4782
4783 h2c->w0 = le32_encode_bits(rtwvif->mac_id, RTW89_H2C_SCANOFLD_W0_MACID) |
4784 le32_encode_bits(rtwvif->port, RTW89_H2C_SCANOFLD_W0_PORT_ID) |
4785 le32_encode_bits(RTW89_PHY_0, RTW89_H2C_SCANOFLD_W0_BAND) |
4786 le32_encode_bits(option->enable, RTW89_H2C_SCANOFLD_W0_OPERATION);
4787
4788 h2c->w1 = le32_encode_bits(true, RTW89_H2C_SCANOFLD_W1_NOTIFY_END) |
4789 le32_encode_bits(option->target_ch_mode,
4790 RTW89_H2C_SCANOFLD_W1_TARGET_CH_MODE) |
4791 le32_encode_bits(RTW89_SCAN_IMMEDIATE,
4792 RTW89_H2C_SCANOFLD_W1_START_MODE) |
4793 le32_encode_bits(RTW89_SCAN_ONCE, RTW89_H2C_SCANOFLD_W1_SCAN_TYPE);
4794
4795 if (option->target_ch_mode) {
4796 h2c->w1 |= le32_encode_bits(op->band_width,
4797 RTW89_H2C_SCANOFLD_W1_TARGET_CH_BW) |
4798 le32_encode_bits(op->primary_channel,
4799 RTW89_H2C_SCANOFLD_W1_TARGET_PRI_CH) |
4800 le32_encode_bits(op->channel,
4801 RTW89_H2C_SCANOFLD_W1_TARGET_CENTRAL_CH);
4802 h2c->w0 |= le32_encode_bits(op->band_type,
4803 RTW89_H2C_SCANOFLD_W0_TARGET_CH_BAND);
4804 }
4805
4806 rtw89_h2c_pkt_set_hdr(rtwdev, skb, FWCMD_TYPE_H2C,
4807 H2C_CAT_MAC, H2C_CL_MAC_FW_OFLD,
4808 H2C_FUNC_SCANOFLD, 1, 1,
4809 len);
4810
4811 if (option->enable)
4812 cond = RTW89_SCANOFLD_WAIT_COND_START;
4813 else
4814 cond = RTW89_SCANOFLD_WAIT_COND_STOP;
4815
4816 ret = rtw89_h2c_tx_and_wait(rtwdev, skb, wait, cond);
4817 if (ret) {
4818 rtw89_debug(rtwdev, RTW89_DBG_FW, "failed to scan ofld\n");
4819 return ret;
4820 }
4821
4822 return 0;
4823 }
4824
rtw89_scan_get_6g_disabled_chan(struct rtw89_dev * rtwdev,struct rtw89_scan_option * option)4825 static void rtw89_scan_get_6g_disabled_chan(struct rtw89_dev *rtwdev,
4826 struct rtw89_scan_option *option)
4827 {
4828 struct ieee80211_supported_band *sband;
4829 struct ieee80211_channel *chan;
4830 u8 i, idx;
4831
4832 sband = rtwdev->hw->wiphy->bands[NL80211_BAND_6GHZ];
4833 if (!sband) {
4834 option->prohib_chan = U64_MAX;
4835 return;
4836 }
4837
4838 for (i = 0; i < sband->n_channels; i++) {
4839 chan = &sband->channels[i];
4840 if (chan->flags & IEEE80211_CHAN_DISABLED) {
4841 idx = (chan->hw_value - 1) / 4;
4842 option->prohib_chan |= BIT(idx);
4843 }
4844 }
4845 }
4846
rtw89_fw_h2c_scan_offload_be(struct rtw89_dev * rtwdev,struct rtw89_scan_option * option,struct rtw89_vif * rtwvif)4847 int rtw89_fw_h2c_scan_offload_be(struct rtw89_dev *rtwdev,
4848 struct rtw89_scan_option *option,
4849 struct rtw89_vif *rtwvif)
4850 {
4851 struct rtw89_hw_scan_info *scan_info = &rtwdev->scan_info;
4852 struct rtw89_wait_info *wait = &rtwdev->mac.fw_ofld_wait;
4853 struct rtw89_h2c_scanofld_be_macc_role *macc_role;
4854 struct rtw89_chan *op = &scan_info->op_chan;
4855 struct rtw89_h2c_scanofld_be_opch *opch;
4856 struct rtw89_pktofld_info *pkt_info;
4857 struct rtw89_h2c_scanofld_be *h2c;
4858 struct sk_buff *skb;
4859 u8 macc_role_size = sizeof(*macc_role) * option->num_macc_role;
4860 u8 opch_size = sizeof(*opch) * option->num_opch;
4861 u8 probe_id[NUM_NL80211_BANDS];
4862 unsigned int cond;
4863 void *ptr;
4864 int ret;
4865 u32 len;
4866 u8 i;
4867
4868 rtw89_scan_get_6g_disabled_chan(rtwdev, option);
4869
4870 len = sizeof(*h2c) + macc_role_size + opch_size;
4871 skb = rtw89_fw_h2c_alloc_skb_with_hdr(rtwdev, len);
4872 if (!skb) {
4873 rtw89_err(rtwdev, "failed to alloc skb for h2c scan offload\n");
4874 return -ENOMEM;
4875 }
4876
4877 skb_put(skb, len);
4878 h2c = (struct rtw89_h2c_scanofld_be *)skb->data;
4879 ptr = skb->data;
4880
4881 memset(probe_id, RTW89_SCANOFLD_PKT_NONE, sizeof(probe_id));
4882
4883 list_for_each_entry(pkt_info, &scan_info->pkt_list[NL80211_BAND_6GHZ], list) {
4884 if (pkt_info->wildcard_6ghz) {
4885 /* Provide wildcard as template */
4886 probe_id[NL80211_BAND_6GHZ] = pkt_info->id;
4887 break;
4888 }
4889 }
4890
4891 h2c->w0 = le32_encode_bits(option->operation, RTW89_H2C_SCANOFLD_BE_W0_OP) |
4892 le32_encode_bits(option->scan_mode,
4893 RTW89_H2C_SCANOFLD_BE_W0_SCAN_MODE) |
4894 le32_encode_bits(option->repeat, RTW89_H2C_SCANOFLD_BE_W0_REPEAT) |
4895 le32_encode_bits(true, RTW89_H2C_SCANOFLD_BE_W0_NOTIFY_END) |
4896 le32_encode_bits(true, RTW89_H2C_SCANOFLD_BE_W0_LEARN_CH) |
4897 le32_encode_bits(rtwvif->mac_id, RTW89_H2C_SCANOFLD_BE_W0_MACID) |
4898 le32_encode_bits(rtwvif->port, RTW89_H2C_SCANOFLD_BE_W0_PORT) |
4899 le32_encode_bits(option->band, RTW89_H2C_SCANOFLD_BE_W0_BAND);
4900
4901 h2c->w1 = le32_encode_bits(option->num_macc_role, RTW89_H2C_SCANOFLD_BE_W1_NUM_MACC_ROLE) |
4902 le32_encode_bits(option->num_opch, RTW89_H2C_SCANOFLD_BE_W1_NUM_OP) |
4903 le32_encode_bits(option->norm_pd, RTW89_H2C_SCANOFLD_BE_W1_NORM_PD);
4904
4905 h2c->w2 = le32_encode_bits(option->slow_pd, RTW89_H2C_SCANOFLD_BE_W2_SLOW_PD) |
4906 le32_encode_bits(option->norm_cy, RTW89_H2C_SCANOFLD_BE_W2_NORM_CY) |
4907 le32_encode_bits(option->opch_end, RTW89_H2C_SCANOFLD_BE_W2_OPCH_END);
4908
4909 h2c->w3 = le32_encode_bits(0, RTW89_H2C_SCANOFLD_BE_W3_NUM_SSID) |
4910 le32_encode_bits(0, RTW89_H2C_SCANOFLD_BE_W3_NUM_SHORT_SSID) |
4911 le32_encode_bits(0, RTW89_H2C_SCANOFLD_BE_W3_NUM_BSSID) |
4912 le32_encode_bits(probe_id[NL80211_BAND_2GHZ], RTW89_H2C_SCANOFLD_BE_W3_PROBEID);
4913
4914 h2c->w4 = le32_encode_bits(probe_id[NL80211_BAND_5GHZ],
4915 RTW89_H2C_SCANOFLD_BE_W4_PROBE_5G) |
4916 le32_encode_bits(probe_id[NL80211_BAND_6GHZ],
4917 RTW89_H2C_SCANOFLD_BE_W4_PROBE_6G) |
4918 le32_encode_bits(0, RTW89_H2C_SCANOFLD_BE_W4_DELAY_START);
4919
4920 h2c->w5 = le32_encode_bits(option->mlo_mode, RTW89_H2C_SCANOFLD_BE_W5_MLO_MODE);
4921
4922 h2c->w6 = le32_encode_bits(option->prohib_chan,
4923 RTW89_H2C_SCANOFLD_BE_W6_CHAN_PROHIB_LOW);
4924 h2c->w7 = le32_encode_bits(option->prohib_chan >> 32,
4925 RTW89_H2C_SCANOFLD_BE_W7_CHAN_PROHIB_HIGH);
4926 ptr += sizeof(*h2c);
4927
4928 for (i = 0; i < option->num_macc_role; i++) {
4929 macc_role = (struct rtw89_h2c_scanofld_be_macc_role *)&h2c->role[i];
4930 macc_role->w0 =
4931 le32_encode_bits(0, RTW89_H2C_SCANOFLD_BE_MACC_ROLE_W0_BAND) |
4932 le32_encode_bits(0, RTW89_H2C_SCANOFLD_BE_MACC_ROLE_W0_PORT) |
4933 le32_encode_bits(0, RTW89_H2C_SCANOFLD_BE_MACC_ROLE_W0_MACID) |
4934 le32_encode_bits(0, RTW89_H2C_SCANOFLD_BE_MACC_ROLE_W0_OPCH_END);
4935 ptr += sizeof(*macc_role);
4936 }
4937
4938 for (i = 0; i < option->num_opch; i++) {
4939 opch = ptr;
4940 opch->w0 = le32_encode_bits(rtwvif->mac_id,
4941 RTW89_H2C_SCANOFLD_BE_OPCH_W0_MACID) |
4942 le32_encode_bits(option->band,
4943 RTW89_H2C_SCANOFLD_BE_OPCH_W0_BAND) |
4944 le32_encode_bits(rtwvif->port,
4945 RTW89_H2C_SCANOFLD_BE_OPCH_W0_PORT) |
4946 le32_encode_bits(RTW89_SCAN_OPMODE_INTV,
4947 RTW89_H2C_SCANOFLD_BE_OPCH_W0_POLICY) |
4948 le32_encode_bits(true,
4949 RTW89_H2C_SCANOFLD_BE_OPCH_W0_TXNULL) |
4950 le32_encode_bits(RTW89_OFF_CHAN_TIME / 10,
4951 RTW89_H2C_SCANOFLD_BE_OPCH_W0_POLICY_VAL);
4952
4953 opch->w1 = le32_encode_bits(RTW89_CHANNEL_TIME,
4954 RTW89_H2C_SCANOFLD_BE_OPCH_W1_DURATION) |
4955 le32_encode_bits(op->band_type,
4956 RTW89_H2C_SCANOFLD_BE_OPCH_W1_CH_BAND) |
4957 le32_encode_bits(op->band_width,
4958 RTW89_H2C_SCANOFLD_BE_OPCH_W1_BW) |
4959 le32_encode_bits(0x3,
4960 RTW89_H2C_SCANOFLD_BE_OPCH_W1_NOTIFY) |
4961 le32_encode_bits(op->primary_channel,
4962 RTW89_H2C_SCANOFLD_BE_OPCH_W1_PRI_CH) |
4963 le32_encode_bits(op->channel,
4964 RTW89_H2C_SCANOFLD_BE_OPCH_W1_CENTRAL_CH);
4965
4966 opch->w2 = le32_encode_bits(0,
4967 RTW89_H2C_SCANOFLD_BE_OPCH_W2_PKTS_CTRL) |
4968 le32_encode_bits(0,
4969 RTW89_H2C_SCANOFLD_BE_OPCH_W2_SW_DEF) |
4970 le32_encode_bits(2,
4971 RTW89_H2C_SCANOFLD_BE_OPCH_W2_SS);
4972
4973 opch->w3 = le32_encode_bits(RTW89_SCANOFLD_PKT_NONE,
4974 RTW89_H2C_SCANOFLD_BE_OPCH_W3_PKT0) |
4975 le32_encode_bits(RTW89_SCANOFLD_PKT_NONE,
4976 RTW89_H2C_SCANOFLD_BE_OPCH_W3_PKT1) |
4977 le32_encode_bits(RTW89_SCANOFLD_PKT_NONE,
4978 RTW89_H2C_SCANOFLD_BE_OPCH_W3_PKT2) |
4979 le32_encode_bits(RTW89_SCANOFLD_PKT_NONE,
4980 RTW89_H2C_SCANOFLD_BE_OPCH_W3_PKT3);
4981 ptr += sizeof(*opch);
4982 }
4983
4984 rtw89_h2c_pkt_set_hdr(rtwdev, skb, FWCMD_TYPE_H2C,
4985 H2C_CAT_MAC, H2C_CL_MAC_FW_OFLD,
4986 H2C_FUNC_SCANOFLD_BE, 1, 1,
4987 len);
4988
4989 if (option->enable)
4990 cond = RTW89_SCANOFLD_BE_WAIT_COND_START;
4991 else
4992 cond = RTW89_SCANOFLD_BE_WAIT_COND_STOP;
4993
4994 ret = rtw89_h2c_tx_and_wait(rtwdev, skb, wait, cond);
4995 if (ret) {
4996 rtw89_debug(rtwdev, RTW89_DBG_FW, "failed to scan be ofld\n");
4997 return ret;
4998 }
4999
5000 return 0;
5001 }
5002
rtw89_fw_h2c_rf_reg(struct rtw89_dev * rtwdev,struct rtw89_fw_h2c_rf_reg_info * info,u16 len,u8 page)5003 int rtw89_fw_h2c_rf_reg(struct rtw89_dev *rtwdev,
5004 struct rtw89_fw_h2c_rf_reg_info *info,
5005 u16 len, u8 page)
5006 {
5007 struct sk_buff *skb;
5008 u8 class = info->rf_path == RF_PATH_A ?
5009 H2C_CL_OUTSRC_RF_REG_A : H2C_CL_OUTSRC_RF_REG_B;
5010 int ret;
5011
5012 skb = rtw89_fw_h2c_alloc_skb_with_hdr(rtwdev, len);
5013 if (!skb) {
5014 rtw89_err(rtwdev, "failed to alloc skb for h2c rf reg\n");
5015 return -ENOMEM;
5016 }
5017 skb_put_data(skb, info->rtw89_phy_config_rf_h2c[page], len);
5018
5019 rtw89_h2c_pkt_set_hdr(rtwdev, skb, FWCMD_TYPE_H2C,
5020 H2C_CAT_OUTSRC, class, page, 0, 0,
5021 len);
5022
5023 ret = rtw89_h2c_tx(rtwdev, skb, false);
5024 if (ret) {
5025 rtw89_err(rtwdev, "failed to send h2c\n");
5026 goto fail;
5027 }
5028
5029 return 0;
5030 fail:
5031 dev_kfree_skb_any(skb);
5032
5033 return ret;
5034 }
5035
rtw89_fw_h2c_rf_ntfy_mcc(struct rtw89_dev * rtwdev)5036 int rtw89_fw_h2c_rf_ntfy_mcc(struct rtw89_dev *rtwdev)
5037 {
5038 struct rtw89_rfk_mcc_info *rfk_mcc = &rtwdev->rfk_mcc;
5039 struct rtw89_fw_h2c_rf_get_mccch *mccch;
5040 struct sk_buff *skb;
5041 int ret;
5042 u8 idx;
5043
5044 skb = rtw89_fw_h2c_alloc_skb_with_hdr(rtwdev, sizeof(*mccch));
5045 if (!skb) {
5046 rtw89_err(rtwdev, "failed to alloc skb for h2c cxdrv_ctrl\n");
5047 return -ENOMEM;
5048 }
5049 skb_put(skb, sizeof(*mccch));
5050 mccch = (struct rtw89_fw_h2c_rf_get_mccch *)skb->data;
5051
5052 idx = rfk_mcc->table_idx;
5053 mccch->ch_0 = cpu_to_le32(rfk_mcc->ch[0]);
5054 mccch->ch_1 = cpu_to_le32(rfk_mcc->ch[1]);
5055 mccch->band_0 = cpu_to_le32(rfk_mcc->band[0]);
5056 mccch->band_1 = cpu_to_le32(rfk_mcc->band[1]);
5057 mccch->current_channel = cpu_to_le32(rfk_mcc->ch[idx]);
5058 mccch->current_band_type = cpu_to_le32(rfk_mcc->band[idx]);
5059
5060 rtw89_h2c_pkt_set_hdr(rtwdev, skb, FWCMD_TYPE_H2C,
5061 H2C_CAT_OUTSRC, H2C_CL_OUTSRC_RF_FW_NOTIFY,
5062 H2C_FUNC_OUTSRC_RF_GET_MCCCH, 0, 0,
5063 sizeof(*mccch));
5064
5065 ret = rtw89_h2c_tx(rtwdev, skb, false);
5066 if (ret) {
5067 rtw89_err(rtwdev, "failed to send h2c\n");
5068 goto fail;
5069 }
5070
5071 return 0;
5072 fail:
5073 dev_kfree_skb_any(skb);
5074
5075 return ret;
5076 }
5077 EXPORT_SYMBOL(rtw89_fw_h2c_rf_ntfy_mcc);
5078
rtw89_fw_h2c_rf_pre_ntfy(struct rtw89_dev * rtwdev,enum rtw89_phy_idx phy_idx)5079 int rtw89_fw_h2c_rf_pre_ntfy(struct rtw89_dev *rtwdev,
5080 enum rtw89_phy_idx phy_idx)
5081 {
5082 struct rtw89_rfk_mcc_info *rfk_mcc = &rtwdev->rfk_mcc;
5083 struct rtw89_fw_h2c_rfk_pre_info *h2c;
5084 u8 tbl_sel = rfk_mcc->table_idx;
5085 u32 len = sizeof(*h2c);
5086 struct sk_buff *skb;
5087 u8 tbl, path;
5088 u32 val32;
5089 int ret;
5090
5091 skb = rtw89_fw_h2c_alloc_skb_with_hdr(rtwdev, len);
5092 if (!skb) {
5093 rtw89_err(rtwdev, "failed to alloc skb for h2c rfk_pre_ntfy\n");
5094 return -ENOMEM;
5095 }
5096 skb_put(skb, len);
5097 h2c = (struct rtw89_fw_h2c_rfk_pre_info *)skb->data;
5098
5099 h2c->mlo_mode = cpu_to_le32(rtwdev->mlo_dbcc_mode);
5100
5101 BUILD_BUG_ON(NUM_OF_RTW89_FW_RFK_TBL > RTW89_RFK_CHS_NR);
5102
5103 for (tbl = 0; tbl < NUM_OF_RTW89_FW_RFK_TBL; tbl++) {
5104 for (path = 0; path < NUM_OF_RTW89_FW_RFK_PATH; path++) {
5105 h2c->dbcc.ch[path][tbl] = cpu_to_le32(rfk_mcc->ch[tbl]);
5106 h2c->dbcc.band[path][tbl] = cpu_to_le32(rfk_mcc->band[tbl]);
5107 }
5108 }
5109
5110 for (path = 0; path < NUM_OF_RTW89_FW_RFK_PATH; path++) {
5111 h2c->tbl.cur_ch[path] = cpu_to_le32(rfk_mcc->ch[tbl_sel]);
5112 h2c->tbl.cur_band[path] = cpu_to_le32(rfk_mcc->band[tbl_sel]);
5113 }
5114
5115 h2c->phy_idx = cpu_to_le32(phy_idx);
5116 h2c->cur_band = cpu_to_le32(rfk_mcc->band[tbl_sel]);
5117 h2c->cur_bw = cpu_to_le32(rfk_mcc->bw[tbl_sel]);
5118 h2c->cur_center_ch = cpu_to_le32(rfk_mcc->ch[tbl_sel]);
5119
5120 val32 = rtw89_phy_read32_mask(rtwdev, R_COEF_SEL, B_COEF_SEL_IQC_V1);
5121 h2c->ktbl_sel0 = cpu_to_le32(val32);
5122 val32 = rtw89_phy_read32_mask(rtwdev, R_COEF_SEL_C1, B_COEF_SEL_IQC_V1);
5123 h2c->ktbl_sel1 = cpu_to_le32(val32);
5124 val32 = rtw89_read_rf(rtwdev, RF_PATH_A, RR_CFGCH, RFREG_MASK);
5125 h2c->rfmod0 = cpu_to_le32(val32);
5126 val32 = rtw89_read_rf(rtwdev, RF_PATH_B, RR_CFGCH, RFREG_MASK);
5127 h2c->rfmod1 = cpu_to_le32(val32);
5128
5129 if (rtw89_is_mlo_1_1(rtwdev))
5130 h2c->mlo_1_1 = cpu_to_le32(1);
5131
5132 h2c->rfe_type = cpu_to_le32(rtwdev->efuse.rfe_type);
5133
5134 rtw89_h2c_pkt_set_hdr(rtwdev, skb, FWCMD_TYPE_H2C,
5135 H2C_CAT_OUTSRC, H2C_CL_OUTSRC_RF_FW_RFK,
5136 H2C_FUNC_RFK_PRE_NOTIFY, 0, 0,
5137 len);
5138
5139 ret = rtw89_h2c_tx(rtwdev, skb, false);
5140 if (ret) {
5141 rtw89_err(rtwdev, "failed to send h2c\n");
5142 goto fail;
5143 }
5144
5145 return 0;
5146 fail:
5147 dev_kfree_skb_any(skb);
5148
5149 return ret;
5150 }
5151
rtw89_fw_h2c_rf_tssi(struct rtw89_dev * rtwdev,enum rtw89_phy_idx phy_idx,enum rtw89_tssi_mode tssi_mode)5152 int rtw89_fw_h2c_rf_tssi(struct rtw89_dev *rtwdev, enum rtw89_phy_idx phy_idx,
5153 enum rtw89_tssi_mode tssi_mode)
5154 {
5155 const struct rtw89_chan *chan = rtw89_chan_get(rtwdev,
5156 RTW89_SUB_ENTITY_0);
5157 struct rtw89_hal *hal = &rtwdev->hal;
5158 struct rtw89_h2c_rf_tssi *h2c;
5159 u32 len = sizeof(*h2c);
5160 struct sk_buff *skb;
5161 int ret;
5162
5163 skb = rtw89_fw_h2c_alloc_skb_with_hdr(rtwdev, len);
5164 if (!skb) {
5165 rtw89_err(rtwdev, "failed to alloc skb for h2c RF TSSI\n");
5166 return -ENOMEM;
5167 }
5168 skb_put(skb, len);
5169 h2c = (struct rtw89_h2c_rf_tssi *)skb->data;
5170
5171 h2c->len = cpu_to_le16(len);
5172 h2c->phy = phy_idx;
5173 h2c->ch = chan->channel;
5174 h2c->bw = chan->band_width;
5175 h2c->band = chan->band_type;
5176 h2c->hwtx_en = true;
5177 h2c->cv = hal->cv;
5178 h2c->tssi_mode = tssi_mode;
5179
5180 rtw89_phy_rfk_tssi_fill_fwcmd_efuse_to_de(rtwdev, phy_idx, chan, h2c);
5181 rtw89_phy_rfk_tssi_fill_fwcmd_tmeter_tbl(rtwdev, phy_idx, chan, h2c);
5182
5183 rtw89_h2c_pkt_set_hdr(rtwdev, skb, FWCMD_TYPE_H2C,
5184 H2C_CAT_OUTSRC, H2C_CL_OUTSRC_RF_FW_RFK,
5185 H2C_FUNC_RFK_TSSI_OFFLOAD, 0, 0, len);
5186
5187 ret = rtw89_h2c_tx(rtwdev, skb, false);
5188 if (ret) {
5189 rtw89_err(rtwdev, "failed to send h2c\n");
5190 goto fail;
5191 }
5192
5193 return 0;
5194 fail:
5195 dev_kfree_skb_any(skb);
5196
5197 return ret;
5198 }
5199
rtw89_fw_h2c_rf_iqk(struct rtw89_dev * rtwdev,enum rtw89_phy_idx phy_idx)5200 int rtw89_fw_h2c_rf_iqk(struct rtw89_dev *rtwdev, enum rtw89_phy_idx phy_idx)
5201 {
5202 struct rtw89_h2c_rf_iqk *h2c;
5203 u32 len = sizeof(*h2c);
5204 struct sk_buff *skb;
5205 int ret;
5206
5207 skb = rtw89_fw_h2c_alloc_skb_with_hdr(rtwdev, len);
5208 if (!skb) {
5209 rtw89_err(rtwdev, "failed to alloc skb for h2c RF IQK\n");
5210 return -ENOMEM;
5211 }
5212 skb_put(skb, len);
5213 h2c = (struct rtw89_h2c_rf_iqk *)skb->data;
5214
5215 h2c->phy_idx = cpu_to_le32(phy_idx);
5216 h2c->dbcc = cpu_to_le32(rtwdev->dbcc_en);
5217
5218 rtw89_h2c_pkt_set_hdr(rtwdev, skb, FWCMD_TYPE_H2C,
5219 H2C_CAT_OUTSRC, H2C_CL_OUTSRC_RF_FW_RFK,
5220 H2C_FUNC_RFK_IQK_OFFLOAD, 0, 0, len);
5221
5222 ret = rtw89_h2c_tx(rtwdev, skb, false);
5223 if (ret) {
5224 rtw89_err(rtwdev, "failed to send h2c\n");
5225 goto fail;
5226 }
5227
5228 return 0;
5229 fail:
5230 dev_kfree_skb_any(skb);
5231
5232 return ret;
5233 }
5234
rtw89_fw_h2c_rf_dpk(struct rtw89_dev * rtwdev,enum rtw89_phy_idx phy_idx)5235 int rtw89_fw_h2c_rf_dpk(struct rtw89_dev *rtwdev, enum rtw89_phy_idx phy_idx)
5236 {
5237 const struct rtw89_chan *chan = rtw89_chan_get(rtwdev,
5238 RTW89_SUB_ENTITY_0);
5239 struct rtw89_h2c_rf_dpk *h2c;
5240 u32 len = sizeof(*h2c);
5241 struct sk_buff *skb;
5242 int ret;
5243
5244 skb = rtw89_fw_h2c_alloc_skb_with_hdr(rtwdev, len);
5245 if (!skb) {
5246 rtw89_err(rtwdev, "failed to alloc skb for h2c RF DPK\n");
5247 return -ENOMEM;
5248 }
5249 skb_put(skb, len);
5250 h2c = (struct rtw89_h2c_rf_dpk *)skb->data;
5251
5252 h2c->len = len;
5253 h2c->phy = phy_idx;
5254 h2c->dpk_enable = true;
5255 h2c->kpath = RF_AB;
5256 h2c->cur_band = chan->band_type;
5257 h2c->cur_bw = chan->band_width;
5258 h2c->cur_ch = chan->channel;
5259 h2c->dpk_dbg_en = rtw89_debug_is_enabled(rtwdev, RTW89_DBG_RFK);
5260
5261 rtw89_h2c_pkt_set_hdr(rtwdev, skb, FWCMD_TYPE_H2C,
5262 H2C_CAT_OUTSRC, H2C_CL_OUTSRC_RF_FW_RFK,
5263 H2C_FUNC_RFK_DPK_OFFLOAD, 0, 0, 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
rtw89_fw_h2c_rf_txgapk(struct rtw89_dev * rtwdev,enum rtw89_phy_idx phy_idx)5278 int rtw89_fw_h2c_rf_txgapk(struct rtw89_dev *rtwdev, enum rtw89_phy_idx phy_idx)
5279 {
5280 const struct rtw89_chan *chan = rtw89_chan_get(rtwdev,
5281 RTW89_SUB_ENTITY_0);
5282 struct rtw89_hal *hal = &rtwdev->hal;
5283 struct rtw89_h2c_rf_txgapk *h2c;
5284 u32 len = sizeof(*h2c);
5285 struct sk_buff *skb;
5286 int ret;
5287
5288 skb = rtw89_fw_h2c_alloc_skb_with_hdr(rtwdev, len);
5289 if (!skb) {
5290 rtw89_err(rtwdev, "failed to alloc skb for h2c RF TXGAPK\n");
5291 return -ENOMEM;
5292 }
5293 skb_put(skb, len);
5294 h2c = (struct rtw89_h2c_rf_txgapk *)skb->data;
5295
5296 h2c->len = len;
5297 h2c->ktype = 2;
5298 h2c->phy = phy_idx;
5299 h2c->kpath = RF_AB;
5300 h2c->band = chan->band_type;
5301 h2c->bw = chan->band_width;
5302 h2c->ch = chan->channel;
5303 h2c->cv = hal->cv;
5304
5305 rtw89_h2c_pkt_set_hdr(rtwdev, skb, FWCMD_TYPE_H2C,
5306 H2C_CAT_OUTSRC, H2C_CL_OUTSRC_RF_FW_RFK,
5307 H2C_FUNC_RFK_TXGAPK_OFFLOAD, 0, 0, len);
5308
5309 ret = rtw89_h2c_tx(rtwdev, skb, false);
5310 if (ret) {
5311 rtw89_err(rtwdev, "failed to send h2c\n");
5312 goto fail;
5313 }
5314
5315 return 0;
5316 fail:
5317 dev_kfree_skb_any(skb);
5318
5319 return ret;
5320 }
5321
rtw89_fw_h2c_rf_dack(struct rtw89_dev * rtwdev,enum rtw89_phy_idx phy_idx)5322 int rtw89_fw_h2c_rf_dack(struct rtw89_dev *rtwdev, enum rtw89_phy_idx phy_idx)
5323 {
5324 struct rtw89_h2c_rf_dack *h2c;
5325 u32 len = sizeof(*h2c);
5326 struct sk_buff *skb;
5327 int ret;
5328
5329 skb = rtw89_fw_h2c_alloc_skb_with_hdr(rtwdev, len);
5330 if (!skb) {
5331 rtw89_err(rtwdev, "failed to alloc skb for h2c RF DACK\n");
5332 return -ENOMEM;
5333 }
5334 skb_put(skb, len);
5335 h2c = (struct rtw89_h2c_rf_dack *)skb->data;
5336
5337 h2c->len = cpu_to_le32(len);
5338 h2c->phy = cpu_to_le32(phy_idx);
5339 h2c->type = cpu_to_le32(0);
5340
5341 rtw89_h2c_pkt_set_hdr(rtwdev, skb, FWCMD_TYPE_H2C,
5342 H2C_CAT_OUTSRC, H2C_CL_OUTSRC_RF_FW_RFK,
5343 H2C_FUNC_RFK_DACK_OFFLOAD, 0, 0, len);
5344
5345 ret = rtw89_h2c_tx(rtwdev, skb, false);
5346 if (ret) {
5347 rtw89_err(rtwdev, "failed to send h2c\n");
5348 goto fail;
5349 }
5350
5351 return 0;
5352 fail:
5353 dev_kfree_skb_any(skb);
5354
5355 return ret;
5356 }
5357
rtw89_fw_h2c_rf_rxdck(struct rtw89_dev * rtwdev,enum rtw89_phy_idx phy_idx)5358 int rtw89_fw_h2c_rf_rxdck(struct rtw89_dev *rtwdev, enum rtw89_phy_idx phy_idx)
5359 {
5360 const struct rtw89_chan *chan = rtw89_chan_get(rtwdev,
5361 RTW89_SUB_ENTITY_0);
5362 struct rtw89_h2c_rf_rxdck *h2c;
5363 u32 len = sizeof(*h2c);
5364 struct sk_buff *skb;
5365 int ret;
5366
5367 skb = rtw89_fw_h2c_alloc_skb_with_hdr(rtwdev, len);
5368 if (!skb) {
5369 rtw89_err(rtwdev, "failed to alloc skb for h2c RF RXDCK\n");
5370 return -ENOMEM;
5371 }
5372 skb_put(skb, len);
5373 h2c = (struct rtw89_h2c_rf_rxdck *)skb->data;
5374
5375 h2c->len = len;
5376 h2c->phy = phy_idx;
5377 h2c->is_afe = false;
5378 h2c->kpath = RF_AB;
5379 h2c->cur_band = chan->band_type;
5380 h2c->cur_bw = chan->band_width;
5381 h2c->cur_ch = chan->channel;
5382 h2c->rxdck_dbg_en = rtw89_debug_is_enabled(rtwdev, RTW89_DBG_RFK);
5383
5384 rtw89_h2c_pkt_set_hdr(rtwdev, skb, FWCMD_TYPE_H2C,
5385 H2C_CAT_OUTSRC, H2C_CL_OUTSRC_RF_FW_RFK,
5386 H2C_FUNC_RFK_RXDCK_OFFLOAD, 0, 0, len);
5387
5388 ret = rtw89_h2c_tx(rtwdev, skb, false);
5389 if (ret) {
5390 rtw89_err(rtwdev, "failed to send h2c\n");
5391 goto fail;
5392 }
5393
5394 return 0;
5395 fail:
5396 dev_kfree_skb_any(skb);
5397
5398 return ret;
5399 }
5400
rtw89_fw_h2c_raw_with_hdr(struct rtw89_dev * rtwdev,u8 h2c_class,u8 h2c_func,u8 * buf,u16 len,bool rack,bool dack)5401 int rtw89_fw_h2c_raw_with_hdr(struct rtw89_dev *rtwdev,
5402 u8 h2c_class, u8 h2c_func, u8 *buf, u16 len,
5403 bool rack, bool dack)
5404 {
5405 struct sk_buff *skb;
5406 int ret;
5407
5408 skb = rtw89_fw_h2c_alloc_skb_with_hdr(rtwdev, len);
5409 if (!skb) {
5410 rtw89_err(rtwdev, "failed to alloc skb for raw with hdr\n");
5411 return -ENOMEM;
5412 }
5413 skb_put_data(skb, buf, len);
5414
5415 rtw89_h2c_pkt_set_hdr(rtwdev, skb, FWCMD_TYPE_H2C,
5416 H2C_CAT_OUTSRC, h2c_class, h2c_func, rack, dack,
5417 len);
5418
5419 ret = rtw89_h2c_tx(rtwdev, skb, false);
5420 if (ret) {
5421 rtw89_err(rtwdev, "failed to send h2c\n");
5422 goto fail;
5423 }
5424
5425 return 0;
5426 fail:
5427 dev_kfree_skb_any(skb);
5428
5429 return ret;
5430 }
5431
rtw89_fw_h2c_raw(struct rtw89_dev * rtwdev,const u8 * buf,u16 len)5432 int rtw89_fw_h2c_raw(struct rtw89_dev *rtwdev, const u8 *buf, u16 len)
5433 {
5434 struct sk_buff *skb;
5435 int ret;
5436
5437 skb = rtw89_fw_h2c_alloc_skb_no_hdr(rtwdev, len);
5438 if (!skb) {
5439 rtw89_err(rtwdev, "failed to alloc skb for h2c raw\n");
5440 return -ENOMEM;
5441 }
5442 skb_put_data(skb, buf, len);
5443
5444 ret = rtw89_h2c_tx(rtwdev, skb, false);
5445 if (ret) {
5446 rtw89_err(rtwdev, "failed to send h2c\n");
5447 goto fail;
5448 }
5449
5450 return 0;
5451 fail:
5452 dev_kfree_skb_any(skb);
5453
5454 return ret;
5455 }
5456
rtw89_fw_send_all_early_h2c(struct rtw89_dev * rtwdev)5457 void rtw89_fw_send_all_early_h2c(struct rtw89_dev *rtwdev)
5458 {
5459 struct rtw89_early_h2c *early_h2c;
5460
5461 lockdep_assert_held(&rtwdev->mutex);
5462
5463 list_for_each_entry(early_h2c, &rtwdev->early_h2c_list, list) {
5464 rtw89_fw_h2c_raw(rtwdev, early_h2c->h2c, early_h2c->h2c_len);
5465 }
5466 }
5467
rtw89_fw_free_all_early_h2c(struct rtw89_dev * rtwdev)5468 void rtw89_fw_free_all_early_h2c(struct rtw89_dev *rtwdev)
5469 {
5470 struct rtw89_early_h2c *early_h2c, *tmp;
5471
5472 mutex_lock(&rtwdev->mutex);
5473 list_for_each_entry_safe(early_h2c, tmp, &rtwdev->early_h2c_list, list) {
5474 list_del(&early_h2c->list);
5475 kfree(early_h2c->h2c);
5476 kfree(early_h2c);
5477 }
5478 mutex_unlock(&rtwdev->mutex);
5479 }
5480
rtw89_fw_c2h_parse_attr(struct sk_buff * c2h)5481 static void rtw89_fw_c2h_parse_attr(struct sk_buff *c2h)
5482 {
5483 const struct rtw89_c2h_hdr *hdr = (const struct rtw89_c2h_hdr *)c2h->data;
5484 struct rtw89_fw_c2h_attr *attr = RTW89_SKB_C2H_CB(c2h);
5485
5486 attr->category = le32_get_bits(hdr->w0, RTW89_C2H_HDR_W0_CATEGORY);
5487 attr->class = le32_get_bits(hdr->w0, RTW89_C2H_HDR_W0_CLASS);
5488 attr->func = le32_get_bits(hdr->w0, RTW89_C2H_HDR_W0_FUNC);
5489 attr->len = le32_get_bits(hdr->w1, RTW89_C2H_HDR_W1_LEN);
5490 }
5491
rtw89_fw_c2h_chk_atomic(struct rtw89_dev * rtwdev,struct sk_buff * c2h)5492 static bool rtw89_fw_c2h_chk_atomic(struct rtw89_dev *rtwdev,
5493 struct sk_buff *c2h)
5494 {
5495 struct rtw89_fw_c2h_attr *attr = RTW89_SKB_C2H_CB(c2h);
5496 u8 category = attr->category;
5497 u8 class = attr->class;
5498 u8 func = attr->func;
5499
5500 switch (category) {
5501 default:
5502 return false;
5503 case RTW89_C2H_CAT_MAC:
5504 return rtw89_mac_c2h_chk_atomic(rtwdev, c2h, class, func);
5505 case RTW89_C2H_CAT_OUTSRC:
5506 return rtw89_phy_c2h_chk_atomic(rtwdev, class, func);
5507 }
5508 }
5509
rtw89_fw_c2h_irqsafe(struct rtw89_dev * rtwdev,struct sk_buff * c2h)5510 void rtw89_fw_c2h_irqsafe(struct rtw89_dev *rtwdev, struct sk_buff *c2h)
5511 {
5512 rtw89_fw_c2h_parse_attr(c2h);
5513 if (!rtw89_fw_c2h_chk_atomic(rtwdev, c2h))
5514 goto enqueue;
5515
5516 rtw89_fw_c2h_cmd_handle(rtwdev, c2h);
5517 dev_kfree_skb_any(c2h);
5518 return;
5519
5520 enqueue:
5521 skb_queue_tail(&rtwdev->c2h_queue, c2h);
5522 ieee80211_queue_work(rtwdev->hw, &rtwdev->c2h_work);
5523 }
5524
rtw89_fw_c2h_cmd_handle(struct rtw89_dev * rtwdev,struct sk_buff * skb)5525 static void rtw89_fw_c2h_cmd_handle(struct rtw89_dev *rtwdev,
5526 struct sk_buff *skb)
5527 {
5528 struct rtw89_fw_c2h_attr *attr = RTW89_SKB_C2H_CB(skb);
5529 u8 category = attr->category;
5530 u8 class = attr->class;
5531 u8 func = attr->func;
5532 u16 len = attr->len;
5533 bool dump = true;
5534
5535 if (!test_bit(RTW89_FLAG_RUNNING, rtwdev->flags))
5536 return;
5537
5538 switch (category) {
5539 case RTW89_C2H_CAT_TEST:
5540 break;
5541 case RTW89_C2H_CAT_MAC:
5542 rtw89_mac_c2h_handle(rtwdev, skb, len, class, func);
5543 if (class == RTW89_MAC_C2H_CLASS_INFO &&
5544 func == RTW89_MAC_C2H_FUNC_C2H_LOG)
5545 dump = false;
5546 break;
5547 case RTW89_C2H_CAT_OUTSRC:
5548 if (class >= RTW89_PHY_C2H_CLASS_BTC_MIN &&
5549 class <= RTW89_PHY_C2H_CLASS_BTC_MAX)
5550 rtw89_btc_c2h_handle(rtwdev, skb, len, class, func);
5551 else
5552 rtw89_phy_c2h_handle(rtwdev, skb, len, class, func);
5553 break;
5554 }
5555
5556 if (dump)
5557 rtw89_hex_dump(rtwdev, RTW89_DBG_FW, "C2H: ", skb->data, skb->len);
5558 }
5559
rtw89_fw_c2h_work(struct work_struct * work)5560 void rtw89_fw_c2h_work(struct work_struct *work)
5561 {
5562 struct rtw89_dev *rtwdev = container_of(work, struct rtw89_dev,
5563 c2h_work);
5564 struct sk_buff *skb, *tmp;
5565
5566 skb_queue_walk_safe(&rtwdev->c2h_queue, skb, tmp) {
5567 skb_unlink(skb, &rtwdev->c2h_queue);
5568 mutex_lock(&rtwdev->mutex);
5569 rtw89_fw_c2h_cmd_handle(rtwdev, skb);
5570 mutex_unlock(&rtwdev->mutex);
5571 dev_kfree_skb_any(skb);
5572 }
5573 }
5574
rtw89_fw_write_h2c_reg(struct rtw89_dev * rtwdev,struct rtw89_mac_h2c_info * info)5575 static int rtw89_fw_write_h2c_reg(struct rtw89_dev *rtwdev,
5576 struct rtw89_mac_h2c_info *info)
5577 {
5578 const struct rtw89_chip_info *chip = rtwdev->chip;
5579 struct rtw89_fw_info *fw_info = &rtwdev->fw;
5580 const u32 *h2c_reg = chip->h2c_regs;
5581 u8 i, val, len;
5582 int ret;
5583
5584 ret = read_poll_timeout(rtw89_read8, val, val == 0, 1000, 5000, false,
5585 rtwdev, chip->h2c_ctrl_reg);
5586 if (ret) {
5587 rtw89_warn(rtwdev, "FW does not process h2c registers\n");
5588 return ret;
5589 }
5590
5591 len = DIV_ROUND_UP(info->content_len + RTW89_H2CREG_HDR_LEN,
5592 sizeof(info->u.h2creg[0]));
5593
5594 u32p_replace_bits(&info->u.hdr.w0, info->id, RTW89_H2CREG_HDR_FUNC_MASK);
5595 u32p_replace_bits(&info->u.hdr.w0, len, RTW89_H2CREG_HDR_LEN_MASK);
5596
5597 for (i = 0; i < RTW89_H2CREG_MAX; i++)
5598 rtw89_write32(rtwdev, h2c_reg[i], info->u.h2creg[i]);
5599
5600 fw_info->h2c_counter++;
5601 rtw89_write8_mask(rtwdev, chip->h2c_counter_reg.addr,
5602 chip->h2c_counter_reg.mask, fw_info->h2c_counter);
5603 rtw89_write8(rtwdev, chip->h2c_ctrl_reg, B_AX_H2CREG_TRIGGER);
5604
5605 return 0;
5606 }
5607
rtw89_fw_read_c2h_reg(struct rtw89_dev * rtwdev,struct rtw89_mac_c2h_info * info)5608 static int rtw89_fw_read_c2h_reg(struct rtw89_dev *rtwdev,
5609 struct rtw89_mac_c2h_info *info)
5610 {
5611 const struct rtw89_chip_info *chip = rtwdev->chip;
5612 struct rtw89_fw_info *fw_info = &rtwdev->fw;
5613 const u32 *c2h_reg = chip->c2h_regs;
5614 u32 ret;
5615 u8 i, val;
5616
5617 info->id = RTW89_FWCMD_C2HREG_FUNC_NULL;
5618
5619 ret = read_poll_timeout_atomic(rtw89_read8, val, val, 1,
5620 RTW89_C2H_TIMEOUT, false, rtwdev,
5621 chip->c2h_ctrl_reg);
5622 if (ret) {
5623 rtw89_warn(rtwdev, "c2h reg timeout\n");
5624 return ret;
5625 }
5626
5627 for (i = 0; i < RTW89_C2HREG_MAX; i++)
5628 info->u.c2hreg[i] = rtw89_read32(rtwdev, c2h_reg[i]);
5629
5630 rtw89_write8(rtwdev, chip->c2h_ctrl_reg, 0);
5631
5632 info->id = u32_get_bits(info->u.hdr.w0, RTW89_C2HREG_HDR_FUNC_MASK);
5633 info->content_len =
5634 (u32_get_bits(info->u.hdr.w0, RTW89_C2HREG_HDR_LEN_MASK) << 2) -
5635 RTW89_C2HREG_HDR_LEN;
5636
5637 fw_info->c2h_counter++;
5638 rtw89_write8_mask(rtwdev, chip->c2h_counter_reg.addr,
5639 chip->c2h_counter_reg.mask, fw_info->c2h_counter);
5640
5641 return 0;
5642 }
5643
rtw89_fw_msg_reg(struct rtw89_dev * rtwdev,struct rtw89_mac_h2c_info * h2c_info,struct rtw89_mac_c2h_info * c2h_info)5644 int rtw89_fw_msg_reg(struct rtw89_dev *rtwdev,
5645 struct rtw89_mac_h2c_info *h2c_info,
5646 struct rtw89_mac_c2h_info *c2h_info)
5647 {
5648 u32 ret;
5649
5650 if (h2c_info && h2c_info->id != RTW89_FWCMD_H2CREG_FUNC_GET_FEATURE)
5651 lockdep_assert_held(&rtwdev->mutex);
5652
5653 if (!h2c_info && !c2h_info)
5654 return -EINVAL;
5655
5656 if (!h2c_info)
5657 goto recv_c2h;
5658
5659 ret = rtw89_fw_write_h2c_reg(rtwdev, h2c_info);
5660 if (ret)
5661 return ret;
5662
5663 recv_c2h:
5664 if (!c2h_info)
5665 return 0;
5666
5667 ret = rtw89_fw_read_c2h_reg(rtwdev, c2h_info);
5668 if (ret)
5669 return ret;
5670
5671 return 0;
5672 }
5673
rtw89_fw_st_dbg_dump(struct rtw89_dev * rtwdev)5674 void rtw89_fw_st_dbg_dump(struct rtw89_dev *rtwdev)
5675 {
5676 if (!test_bit(RTW89_FLAG_POWERON, rtwdev->flags)) {
5677 rtw89_err(rtwdev, "[ERR]pwr is off\n");
5678 return;
5679 }
5680
5681 rtw89_info(rtwdev, "FW status = 0x%x\n", rtw89_read32(rtwdev, R_AX_UDM0));
5682 rtw89_info(rtwdev, "FW BADADDR = 0x%x\n", rtw89_read32(rtwdev, R_AX_UDM1));
5683 rtw89_info(rtwdev, "FW EPC/RA = 0x%x\n", rtw89_read32(rtwdev, R_AX_UDM2));
5684 rtw89_info(rtwdev, "FW MISC = 0x%x\n", rtw89_read32(rtwdev, R_AX_UDM3));
5685 rtw89_info(rtwdev, "R_AX_HALT_C2H = 0x%x\n",
5686 rtw89_read32(rtwdev, R_AX_HALT_C2H));
5687 rtw89_info(rtwdev, "R_AX_SER_DBG_INFO = 0x%x\n",
5688 rtw89_read32(rtwdev, R_AX_SER_DBG_INFO));
5689
5690 rtw89_fw_prog_cnt_dump(rtwdev);
5691 }
5692
rtw89_release_pkt_list(struct rtw89_dev * rtwdev)5693 static void rtw89_release_pkt_list(struct rtw89_dev *rtwdev)
5694 {
5695 struct list_head *pkt_list = rtwdev->scan_info.pkt_list;
5696 struct rtw89_pktofld_info *info, *tmp;
5697 u8 idx;
5698
5699 for (idx = NL80211_BAND_2GHZ; idx < NUM_NL80211_BANDS; idx++) {
5700 if (!(rtwdev->chip->support_bands & BIT(idx)))
5701 continue;
5702
5703 list_for_each_entry_safe(info, tmp, &pkt_list[idx], list) {
5704 if (test_bit(info->id, rtwdev->pkt_offload))
5705 rtw89_fw_h2c_del_pkt_offload(rtwdev, info->id);
5706 list_del(&info->list);
5707 kfree(info);
5708 }
5709 }
5710 }
5711
rtw89_is_6ghz_wildcard_probe_req(struct rtw89_dev * rtwdev,struct rtw89_vif * rtwvif,struct rtw89_pktofld_info * info,enum nl80211_band band,u8 ssid_idx)5712 static bool rtw89_is_6ghz_wildcard_probe_req(struct rtw89_dev *rtwdev,
5713 struct rtw89_vif *rtwvif,
5714 struct rtw89_pktofld_info *info,
5715 enum nl80211_band band, u8 ssid_idx)
5716 {
5717 struct cfg80211_scan_request *req = rtwvif->scan_req;
5718
5719 if (band != NL80211_BAND_6GHZ)
5720 return false;
5721
5722 if (req->ssids[ssid_idx].ssid_len) {
5723 memcpy(info->ssid, req->ssids[ssid_idx].ssid,
5724 req->ssids[ssid_idx].ssid_len);
5725 info->ssid_len = req->ssids[ssid_idx].ssid_len;
5726 return false;
5727 } else {
5728 info->wildcard_6ghz = true;
5729 return true;
5730 }
5731 }
5732
rtw89_append_probe_req_ie(struct rtw89_dev * rtwdev,struct rtw89_vif * rtwvif,struct sk_buff * skb,u8 ssid_idx)5733 static int rtw89_append_probe_req_ie(struct rtw89_dev *rtwdev,
5734 struct rtw89_vif *rtwvif,
5735 struct sk_buff *skb, u8 ssid_idx)
5736 {
5737 struct rtw89_hw_scan_info *scan_info = &rtwdev->scan_info;
5738 struct ieee80211_scan_ies *ies = rtwvif->scan_ies;
5739 struct rtw89_pktofld_info *info;
5740 struct sk_buff *new;
5741 int ret = 0;
5742 u8 band;
5743
5744 for (band = NL80211_BAND_2GHZ; band < NUM_NL80211_BANDS; band++) {
5745 if (!(rtwdev->chip->support_bands & BIT(band)))
5746 continue;
5747
5748 new = skb_copy(skb, GFP_KERNEL);
5749 if (!new) {
5750 ret = -ENOMEM;
5751 goto out;
5752 }
5753 skb_put_data(new, ies->ies[band], ies->len[band]);
5754 skb_put_data(new, ies->common_ies, ies->common_ie_len);
5755
5756 info = kzalloc(sizeof(*info), GFP_KERNEL);
5757 if (!info) {
5758 ret = -ENOMEM;
5759 kfree_skb(new);
5760 goto out;
5761 }
5762
5763 rtw89_is_6ghz_wildcard_probe_req(rtwdev, rtwvif, info, band,
5764 ssid_idx);
5765
5766 ret = rtw89_fw_h2c_add_pkt_offload(rtwdev, &info->id, new);
5767 if (ret) {
5768 kfree_skb(new);
5769 kfree(info);
5770 goto out;
5771 }
5772
5773 list_add_tail(&info->list, &scan_info->pkt_list[band]);
5774 kfree_skb(new);
5775 }
5776 out:
5777 return ret;
5778 }
5779
rtw89_hw_scan_update_probe_req(struct rtw89_dev * rtwdev,struct rtw89_vif * rtwvif)5780 static int rtw89_hw_scan_update_probe_req(struct rtw89_dev *rtwdev,
5781 struct rtw89_vif *rtwvif)
5782 {
5783 struct cfg80211_scan_request *req = rtwvif->scan_req;
5784 struct sk_buff *skb;
5785 u8 num = req->n_ssids, i;
5786 int ret;
5787
5788 for (i = 0; i < num; i++) {
5789 skb = ieee80211_probereq_get(rtwdev->hw, rtwvif->mac_addr,
5790 req->ssids[i].ssid,
5791 req->ssids[i].ssid_len,
5792 req->ie_len);
5793 if (!skb)
5794 return -ENOMEM;
5795
5796 ret = rtw89_append_probe_req_ie(rtwdev, rtwvif, skb, i);
5797 kfree_skb(skb);
5798
5799 if (ret)
5800 return ret;
5801 }
5802
5803 return 0;
5804 }
5805
rtw89_update_6ghz_rnr_chan(struct rtw89_dev * rtwdev,struct cfg80211_scan_request * req,struct rtw89_mac_chinfo * ch_info)5806 static int rtw89_update_6ghz_rnr_chan(struct rtw89_dev *rtwdev,
5807 struct cfg80211_scan_request *req,
5808 struct rtw89_mac_chinfo *ch_info)
5809 {
5810 struct ieee80211_vif *vif = rtwdev->scan_info.scanning_vif;
5811 struct list_head *pkt_list = rtwdev->scan_info.pkt_list;
5812 struct rtw89_vif *rtwvif = vif_to_rtwvif_safe(vif);
5813 struct ieee80211_scan_ies *ies = rtwvif->scan_ies;
5814 struct cfg80211_scan_6ghz_params *params;
5815 struct rtw89_pktofld_info *info, *tmp;
5816 struct ieee80211_hdr *hdr;
5817 struct sk_buff *skb;
5818 bool found;
5819 int ret = 0;
5820 u8 i;
5821
5822 if (!req->n_6ghz_params)
5823 return 0;
5824
5825 for (i = 0; i < req->n_6ghz_params; i++) {
5826 params = &req->scan_6ghz_params[i];
5827
5828 if (req->channels[params->channel_idx]->hw_value !=
5829 ch_info->pri_ch)
5830 continue;
5831
5832 found = false;
5833 list_for_each_entry(tmp, &pkt_list[NL80211_BAND_6GHZ], list) {
5834 if (ether_addr_equal(tmp->bssid, params->bssid)) {
5835 found = true;
5836 break;
5837 }
5838 }
5839 if (found)
5840 continue;
5841
5842 skb = ieee80211_probereq_get(rtwdev->hw, rtwvif->mac_addr,
5843 NULL, 0, req->ie_len);
5844 skb_put_data(skb, ies->ies[NL80211_BAND_6GHZ], ies->len[NL80211_BAND_6GHZ]);
5845 skb_put_data(skb, ies->common_ies, ies->common_ie_len);
5846 hdr = (struct ieee80211_hdr *)skb->data;
5847 ether_addr_copy(hdr->addr3, params->bssid);
5848
5849 info = kzalloc(sizeof(*info), GFP_KERNEL);
5850 if (!info) {
5851 ret = -ENOMEM;
5852 kfree_skb(skb);
5853 goto out;
5854 }
5855
5856 ret = rtw89_fw_h2c_add_pkt_offload(rtwdev, &info->id, skb);
5857 if (ret) {
5858 kfree_skb(skb);
5859 kfree(info);
5860 goto out;
5861 }
5862
5863 ether_addr_copy(info->bssid, params->bssid);
5864 info->channel_6ghz = req->channels[params->channel_idx]->hw_value;
5865 list_add_tail(&info->list, &rtwdev->scan_info.pkt_list[NL80211_BAND_6GHZ]);
5866
5867 ch_info->tx_pkt = true;
5868 ch_info->period = RTW89_CHANNEL_TIME_6G + RTW89_DWELL_TIME_6G;
5869
5870 kfree_skb(skb);
5871 }
5872
5873 out:
5874 return ret;
5875 }
5876
rtw89_hw_scan_add_chan(struct rtw89_dev * rtwdev,int chan_type,int ssid_num,struct rtw89_mac_chinfo * ch_info)5877 static void rtw89_hw_scan_add_chan(struct rtw89_dev *rtwdev, int chan_type,
5878 int ssid_num,
5879 struct rtw89_mac_chinfo *ch_info)
5880 {
5881 struct rtw89_hw_scan_info *scan_info = &rtwdev->scan_info;
5882 struct ieee80211_vif *vif = rtwdev->scan_info.scanning_vif;
5883 struct rtw89_vif *rtwvif = (struct rtw89_vif *)vif->drv_priv;
5884 struct cfg80211_scan_request *req = rtwvif->scan_req;
5885 struct rtw89_chan *op = &rtwdev->scan_info.op_chan;
5886 struct rtw89_pktofld_info *info;
5887 u8 band, probe_count = 0;
5888 int ret;
5889
5890 ch_info->notify_action = RTW89_SCANOFLD_DEBUG_MASK;
5891 ch_info->dfs_ch = chan_type == RTW89_CHAN_DFS;
5892 ch_info->bw = RTW89_SCAN_WIDTH;
5893 ch_info->tx_pkt = true;
5894 ch_info->cfg_tx_pwr = false;
5895 ch_info->tx_pwr_idx = 0;
5896 ch_info->tx_null = false;
5897 ch_info->pause_data = false;
5898 ch_info->probe_id = RTW89_SCANOFLD_PKT_NONE;
5899
5900 if (ch_info->ch_band == RTW89_BAND_6G) {
5901 if ((ssid_num == 1 && req->ssids[0].ssid_len == 0) ||
5902 !ch_info->is_psc) {
5903 ch_info->tx_pkt = false;
5904 if (!req->duration_mandatory)
5905 ch_info->period -= RTW89_DWELL_TIME_6G;
5906 }
5907 }
5908
5909 ret = rtw89_update_6ghz_rnr_chan(rtwdev, req, ch_info);
5910 if (ret)
5911 rtw89_warn(rtwdev, "RNR fails: %d\n", ret);
5912
5913 if (ssid_num) {
5914 band = rtw89_hw_to_nl80211_band(ch_info->ch_band);
5915
5916 list_for_each_entry(info, &scan_info->pkt_list[band], list) {
5917 if (info->channel_6ghz &&
5918 ch_info->pri_ch != info->channel_6ghz)
5919 continue;
5920 else if (info->channel_6ghz && probe_count != 0)
5921 ch_info->period += RTW89_CHANNEL_TIME_6G;
5922
5923 if (info->wildcard_6ghz)
5924 continue;
5925
5926 ch_info->pkt_id[probe_count++] = info->id;
5927 if (probe_count >= RTW89_SCANOFLD_MAX_SSID)
5928 break;
5929 }
5930 ch_info->num_pkt = probe_count;
5931 }
5932
5933 switch (chan_type) {
5934 case RTW89_CHAN_OPERATE:
5935 ch_info->central_ch = op->channel;
5936 ch_info->pri_ch = op->primary_channel;
5937 ch_info->ch_band = op->band_type;
5938 ch_info->bw = op->band_width;
5939 ch_info->tx_null = true;
5940 ch_info->num_pkt = 0;
5941 break;
5942 case RTW89_CHAN_DFS:
5943 if (ch_info->ch_band != RTW89_BAND_6G)
5944 ch_info->period = max_t(u8, ch_info->period,
5945 RTW89_DFS_CHAN_TIME);
5946 ch_info->dwell_time = RTW89_DWELL_TIME;
5947 break;
5948 case RTW89_CHAN_ACTIVE:
5949 break;
5950 default:
5951 rtw89_err(rtwdev, "Channel type out of bound\n");
5952 }
5953 }
5954
rtw89_hw_scan_add_chan_be(struct rtw89_dev * rtwdev,int chan_type,int ssid_num,struct rtw89_mac_chinfo_be * ch_info)5955 static void rtw89_hw_scan_add_chan_be(struct rtw89_dev *rtwdev, int chan_type,
5956 int ssid_num,
5957 struct rtw89_mac_chinfo_be *ch_info)
5958 {
5959 struct rtw89_hw_scan_info *scan_info = &rtwdev->scan_info;
5960 struct ieee80211_vif *vif = rtwdev->scan_info.scanning_vif;
5961 struct rtw89_vif *rtwvif = (struct rtw89_vif *)vif->drv_priv;
5962 struct cfg80211_scan_request *req = rtwvif->scan_req;
5963 struct rtw89_pktofld_info *info;
5964 u8 band, probe_count = 0, i;
5965
5966 ch_info->notify_action = RTW89_SCANOFLD_DEBUG_MASK;
5967 ch_info->dfs_ch = chan_type == RTW89_CHAN_DFS;
5968 ch_info->bw = RTW89_SCAN_WIDTH;
5969 ch_info->tx_null = false;
5970 ch_info->pause_data = false;
5971 ch_info->probe_id = RTW89_SCANOFLD_PKT_NONE;
5972
5973 if (ssid_num) {
5974 band = rtw89_hw_to_nl80211_band(ch_info->ch_band);
5975
5976 list_for_each_entry(info, &scan_info->pkt_list[band], list) {
5977 if (info->channel_6ghz &&
5978 ch_info->pri_ch != info->channel_6ghz)
5979 continue;
5980
5981 if (info->wildcard_6ghz)
5982 continue;
5983
5984 ch_info->pkt_id[probe_count++] = info->id;
5985 if (probe_count >= RTW89_SCANOFLD_MAX_SSID)
5986 break;
5987 }
5988 }
5989
5990 if (ch_info->ch_band == RTW89_BAND_6G) {
5991 if ((ssid_num == 1 && req->ssids[0].ssid_len == 0) ||
5992 !ch_info->is_psc) {
5993 ch_info->probe_id = RTW89_SCANOFLD_PKT_NONE;
5994 if (!req->duration_mandatory)
5995 ch_info->period -= RTW89_DWELL_TIME_6G;
5996 }
5997 }
5998
5999 for (i = probe_count; i < RTW89_SCANOFLD_MAX_SSID; i++)
6000 ch_info->pkt_id[i] = RTW89_SCANOFLD_PKT_NONE;
6001
6002 switch (chan_type) {
6003 case RTW89_CHAN_DFS:
6004 if (ch_info->ch_band != RTW89_BAND_6G)
6005 ch_info->period =
6006 max_t(u8, ch_info->period, RTW89_DFS_CHAN_TIME);
6007 ch_info->dwell_time = RTW89_DWELL_TIME;
6008 break;
6009 case RTW89_CHAN_ACTIVE:
6010 break;
6011 default:
6012 rtw89_warn(rtwdev, "Channel type out of bound\n");
6013 break;
6014 }
6015 }
6016
rtw89_hw_scan_add_chan_list(struct rtw89_dev * rtwdev,struct rtw89_vif * rtwvif,bool connected)6017 int rtw89_hw_scan_add_chan_list(struct rtw89_dev *rtwdev,
6018 struct rtw89_vif *rtwvif, bool connected)
6019 {
6020 struct cfg80211_scan_request *req = rtwvif->scan_req;
6021 struct rtw89_mac_chinfo *ch_info, *tmp;
6022 struct ieee80211_channel *channel;
6023 struct list_head chan_list;
6024 bool random_seq = req->flags & NL80211_SCAN_FLAG_RANDOM_SN;
6025 int list_len, off_chan_time = 0;
6026 enum rtw89_chan_type type;
6027 int ret = 0;
6028 u32 idx;
6029
6030 INIT_LIST_HEAD(&chan_list);
6031 for (idx = rtwdev->scan_info.last_chan_idx, list_len = 0;
6032 idx < req->n_channels && list_len < RTW89_SCAN_LIST_LIMIT;
6033 idx++, list_len++) {
6034 channel = req->channels[idx];
6035 ch_info = kzalloc(sizeof(*ch_info), GFP_KERNEL);
6036 if (!ch_info) {
6037 ret = -ENOMEM;
6038 goto out;
6039 }
6040
6041 if (req->duration)
6042 ch_info->period = req->duration;
6043 else if (channel->band == NL80211_BAND_6GHZ)
6044 ch_info->period = RTW89_CHANNEL_TIME_6G +
6045 RTW89_DWELL_TIME_6G;
6046 else
6047 ch_info->period = RTW89_CHANNEL_TIME;
6048
6049 ch_info->ch_band = rtw89_nl80211_to_hw_band(channel->band);
6050 ch_info->central_ch = channel->hw_value;
6051 ch_info->pri_ch = channel->hw_value;
6052 ch_info->rand_seq_num = random_seq;
6053 ch_info->is_psc = cfg80211_channel_is_psc(channel);
6054
6055 if (channel->flags &
6056 (IEEE80211_CHAN_RADAR | IEEE80211_CHAN_NO_IR))
6057 type = RTW89_CHAN_DFS;
6058 else
6059 type = RTW89_CHAN_ACTIVE;
6060 rtw89_hw_scan_add_chan(rtwdev, type, req->n_ssids, ch_info);
6061
6062 if (connected &&
6063 off_chan_time + ch_info->period > RTW89_OFF_CHAN_TIME) {
6064 tmp = kzalloc(sizeof(*tmp), GFP_KERNEL);
6065 if (!tmp) {
6066 ret = -ENOMEM;
6067 kfree(ch_info);
6068 goto out;
6069 }
6070
6071 type = RTW89_CHAN_OPERATE;
6072 tmp->period = req->duration_mandatory ?
6073 req->duration : RTW89_CHANNEL_TIME;
6074 rtw89_hw_scan_add_chan(rtwdev, type, 0, tmp);
6075 list_add_tail(&tmp->list, &chan_list);
6076 off_chan_time = 0;
6077 list_len++;
6078 }
6079 list_add_tail(&ch_info->list, &chan_list);
6080 off_chan_time += ch_info->period;
6081 }
6082 rtwdev->scan_info.last_chan_idx = idx;
6083 ret = rtw89_fw_h2c_scan_list_offload(rtwdev, list_len, &chan_list);
6084
6085 out:
6086 list_for_each_entry_safe(ch_info, tmp, &chan_list, list) {
6087 list_del(&ch_info->list);
6088 kfree(ch_info);
6089 }
6090
6091 return ret;
6092 }
6093
rtw89_hw_scan_add_chan_list_be(struct rtw89_dev * rtwdev,struct rtw89_vif * rtwvif,bool connected)6094 int rtw89_hw_scan_add_chan_list_be(struct rtw89_dev *rtwdev,
6095 struct rtw89_vif *rtwvif, bool connected)
6096 {
6097 struct cfg80211_scan_request *req = rtwvif->scan_req;
6098 struct rtw89_mac_chinfo_be *ch_info, *tmp;
6099 struct ieee80211_channel *channel;
6100 struct list_head chan_list;
6101 enum rtw89_chan_type type;
6102 int list_len, ret;
6103 bool random_seq;
6104 u32 idx;
6105
6106 random_seq = !!(req->flags & NL80211_SCAN_FLAG_RANDOM_SN);
6107 INIT_LIST_HEAD(&chan_list);
6108
6109 for (idx = rtwdev->scan_info.last_chan_idx, list_len = 0;
6110 idx < req->n_channels && list_len < RTW89_SCAN_LIST_LIMIT;
6111 idx++, list_len++) {
6112 channel = req->channels[idx];
6113 ch_info = kzalloc(sizeof(*ch_info), GFP_KERNEL);
6114 if (!ch_info) {
6115 ret = -ENOMEM;
6116 goto out;
6117 }
6118
6119 if (req->duration)
6120 ch_info->period = req->duration;
6121 else if (channel->band == NL80211_BAND_6GHZ)
6122 ch_info->period = RTW89_CHANNEL_TIME_6G + RTW89_DWELL_TIME_6G;
6123 else
6124 ch_info->period = RTW89_CHANNEL_TIME;
6125
6126 ch_info->ch_band = rtw89_nl80211_to_hw_band(channel->band);
6127 ch_info->central_ch = channel->hw_value;
6128 ch_info->pri_ch = channel->hw_value;
6129 ch_info->rand_seq_num = random_seq;
6130 ch_info->is_psc = cfg80211_channel_is_psc(channel);
6131
6132 if (channel->flags & (IEEE80211_CHAN_RADAR | IEEE80211_CHAN_NO_IR))
6133 type = RTW89_CHAN_DFS;
6134 else
6135 type = RTW89_CHAN_ACTIVE;
6136 rtw89_hw_scan_add_chan_be(rtwdev, type, req->n_ssids, ch_info);
6137
6138 list_add_tail(&ch_info->list, &chan_list);
6139 }
6140
6141 rtwdev->scan_info.last_chan_idx = idx;
6142 ret = rtw89_fw_h2c_scan_list_offload_be(rtwdev, list_len, &chan_list);
6143
6144 out:
6145 list_for_each_entry_safe(ch_info, tmp, &chan_list, list) {
6146 list_del(&ch_info->list);
6147 kfree(ch_info);
6148 }
6149
6150 return ret;
6151 }
6152
rtw89_hw_scan_prehandle(struct rtw89_dev * rtwdev,struct rtw89_vif * rtwvif,bool connected)6153 static int rtw89_hw_scan_prehandle(struct rtw89_dev *rtwdev,
6154 struct rtw89_vif *rtwvif, bool connected)
6155 {
6156 const struct rtw89_mac_gen_def *mac = rtwdev->chip->mac_def;
6157 int ret;
6158
6159 ret = rtw89_hw_scan_update_probe_req(rtwdev, rtwvif);
6160 if (ret) {
6161 rtw89_err(rtwdev, "Update probe request failed\n");
6162 goto out;
6163 }
6164 ret = mac->add_chan_list(rtwdev, rtwvif, connected);
6165 out:
6166 return ret;
6167 }
6168
rtw89_hw_scan_start(struct rtw89_dev * rtwdev,struct ieee80211_vif * vif,struct ieee80211_scan_request * scan_req)6169 void rtw89_hw_scan_start(struct rtw89_dev *rtwdev, struct ieee80211_vif *vif,
6170 struct ieee80211_scan_request *scan_req)
6171 {
6172 struct rtw89_vif *rtwvif = (struct rtw89_vif *)vif->drv_priv;
6173 const struct rtw89_mac_gen_def *mac = rtwdev->chip->mac_def;
6174 struct cfg80211_scan_request *req = &scan_req->req;
6175 u32 rx_fltr = rtwdev->hal.rx_fltr;
6176 u8 mac_addr[ETH_ALEN];
6177
6178 rtw89_get_channel(rtwdev, rtwvif, &rtwdev->scan_info.op_chan);
6179 rtwdev->scan_info.scanning_vif = vif;
6180 rtwdev->scan_info.last_chan_idx = 0;
6181 rtwdev->scan_info.abort = false;
6182 rtwvif->scan_ies = &scan_req->ies;
6183 rtwvif->scan_req = req;
6184 ieee80211_stop_queues(rtwdev->hw);
6185 rtw89_mac_port_cfg_rx_sync(rtwdev, rtwvif, false);
6186
6187 if (req->flags & NL80211_SCAN_FLAG_RANDOM_ADDR)
6188 get_random_mask_addr(mac_addr, req->mac_addr,
6189 req->mac_addr_mask);
6190 else
6191 ether_addr_copy(mac_addr, vif->addr);
6192 rtw89_core_scan_start(rtwdev, rtwvif, mac_addr, true);
6193
6194 rx_fltr &= ~B_AX_A_BCN_CHK_EN;
6195 rx_fltr &= ~B_AX_A_BC;
6196 rx_fltr &= ~B_AX_A_A1_MATCH;
6197 rtw89_write32_mask(rtwdev,
6198 rtw89_mac_reg_by_idx(rtwdev, mac->rx_fltr, RTW89_MAC_0),
6199 B_AX_RX_FLTR_CFG_MASK,
6200 rx_fltr);
6201
6202 rtw89_chanctx_pause(rtwdev, RTW89_CHANCTX_PAUSE_REASON_HW_SCAN);
6203 }
6204
rtw89_hw_scan_complete(struct rtw89_dev * rtwdev,struct ieee80211_vif * vif,bool aborted)6205 void rtw89_hw_scan_complete(struct rtw89_dev *rtwdev, struct ieee80211_vif *vif,
6206 bool aborted)
6207 {
6208 const struct rtw89_mac_gen_def *mac = rtwdev->chip->mac_def;
6209 struct rtw89_hw_scan_info *scan_info = &rtwdev->scan_info;
6210 struct rtw89_vif *rtwvif = vif_to_rtwvif_safe(vif);
6211 struct cfg80211_scan_info info = {
6212 .aborted = aborted,
6213 };
6214
6215 if (!vif)
6216 return;
6217
6218 rtw89_write32_mask(rtwdev,
6219 rtw89_mac_reg_by_idx(rtwdev, mac->rx_fltr, RTW89_MAC_0),
6220 B_AX_RX_FLTR_CFG_MASK,
6221 rtwdev->hal.rx_fltr);
6222
6223 rtw89_core_scan_complete(rtwdev, vif, true);
6224 ieee80211_scan_completed(rtwdev->hw, &info);
6225 ieee80211_wake_queues(rtwdev->hw);
6226 rtw89_mac_port_cfg_rx_sync(rtwdev, rtwvif, true);
6227 rtw89_mac_enable_beacon_for_ap_vifs(rtwdev, true);
6228
6229 rtw89_release_pkt_list(rtwdev);
6230 rtwvif->scan_req = NULL;
6231 rtwvif->scan_ies = NULL;
6232 scan_info->last_chan_idx = 0;
6233 scan_info->scanning_vif = NULL;
6234 scan_info->abort = false;
6235
6236 rtw89_chanctx_proceed(rtwdev);
6237 }
6238
rtw89_hw_scan_abort(struct rtw89_dev * rtwdev,struct ieee80211_vif * vif)6239 void rtw89_hw_scan_abort(struct rtw89_dev *rtwdev, struct ieee80211_vif *vif)
6240 {
6241 struct rtw89_hw_scan_info *scan_info = &rtwdev->scan_info;
6242 int ret;
6243
6244 scan_info->abort = true;
6245
6246 ret = rtw89_hw_scan_offload(rtwdev, vif, false);
6247 if (ret)
6248 rtw89_hw_scan_complete(rtwdev, vif, true);
6249 }
6250
rtw89_is_any_vif_connected_or_connecting(struct rtw89_dev * rtwdev)6251 static bool rtw89_is_any_vif_connected_or_connecting(struct rtw89_dev *rtwdev)
6252 {
6253 struct rtw89_vif *rtwvif;
6254
6255 rtw89_for_each_rtwvif(rtwdev, rtwvif) {
6256 /* This variable implies connected or during attempt to connect */
6257 if (!is_zero_ether_addr(rtwvif->bssid))
6258 return true;
6259 }
6260
6261 return false;
6262 }
6263
rtw89_hw_scan_offload(struct rtw89_dev * rtwdev,struct ieee80211_vif * vif,bool enable)6264 int rtw89_hw_scan_offload(struct rtw89_dev *rtwdev, struct ieee80211_vif *vif,
6265 bool enable)
6266 {
6267 const struct rtw89_mac_gen_def *mac = rtwdev->chip->mac_def;
6268 struct rtw89_scan_option opt = {0};
6269 struct rtw89_vif *rtwvif;
6270 bool connected;
6271 int ret = 0;
6272
6273 rtwvif = vif ? (struct rtw89_vif *)vif->drv_priv : NULL;
6274 if (!rtwvif)
6275 return -EINVAL;
6276
6277 connected = rtw89_is_any_vif_connected_or_connecting(rtwdev);
6278 opt.enable = enable;
6279 opt.target_ch_mode = connected;
6280 if (enable) {
6281 ret = rtw89_hw_scan_prehandle(rtwdev, rtwvif, connected);
6282 if (ret)
6283 goto out;
6284 }
6285
6286 if (rtwdev->chip->chip_gen == RTW89_CHIP_BE) {
6287 opt.operation = enable ? RTW89_SCAN_OP_START : RTW89_SCAN_OP_STOP;
6288 opt.scan_mode = RTW89_SCAN_MODE_SA;
6289 opt.band = RTW89_PHY_0;
6290 opt.num_macc_role = 0;
6291 opt.mlo_mode = rtwdev->mlo_dbcc_mode;
6292 opt.num_opch = connected ? 1 : 0;
6293 opt.opch_end = connected ? 0 : RTW89_CHAN_INVALID;
6294 }
6295
6296 ret = mac->scan_offload(rtwdev, &opt, rtwvif);
6297 out:
6298 return ret;
6299 }
6300
6301 #define H2C_FW_CPU_EXCEPTION_LEN 4
6302 #define H2C_FW_CPU_EXCEPTION_TYPE_DEF 0x5566
rtw89_fw_h2c_trigger_cpu_exception(struct rtw89_dev * rtwdev)6303 int rtw89_fw_h2c_trigger_cpu_exception(struct rtw89_dev *rtwdev)
6304 {
6305 struct sk_buff *skb;
6306 int ret;
6307
6308 skb = rtw89_fw_h2c_alloc_skb_with_hdr(rtwdev, H2C_FW_CPU_EXCEPTION_LEN);
6309 if (!skb) {
6310 rtw89_err(rtwdev,
6311 "failed to alloc skb for fw cpu exception\n");
6312 return -ENOMEM;
6313 }
6314
6315 skb_put(skb, H2C_FW_CPU_EXCEPTION_LEN);
6316 RTW89_SET_FWCMD_CPU_EXCEPTION_TYPE(skb->data,
6317 H2C_FW_CPU_EXCEPTION_TYPE_DEF);
6318
6319 rtw89_h2c_pkt_set_hdr(rtwdev, skb, FWCMD_TYPE_H2C,
6320 H2C_CAT_TEST,
6321 H2C_CL_FW_STATUS_TEST,
6322 H2C_FUNC_CPU_EXCEPTION, 0, 0,
6323 H2C_FW_CPU_EXCEPTION_LEN);
6324
6325 ret = rtw89_h2c_tx(rtwdev, skb, false);
6326 if (ret) {
6327 rtw89_err(rtwdev, "failed to send h2c\n");
6328 goto fail;
6329 }
6330
6331 return 0;
6332
6333 fail:
6334 dev_kfree_skb_any(skb);
6335 return ret;
6336 }
6337
6338 #define H2C_PKT_DROP_LEN 24
rtw89_fw_h2c_pkt_drop(struct rtw89_dev * rtwdev,const struct rtw89_pkt_drop_params * params)6339 int rtw89_fw_h2c_pkt_drop(struct rtw89_dev *rtwdev,
6340 const struct rtw89_pkt_drop_params *params)
6341 {
6342 struct sk_buff *skb;
6343 int ret;
6344
6345 skb = rtw89_fw_h2c_alloc_skb_with_hdr(rtwdev, H2C_PKT_DROP_LEN);
6346 if (!skb) {
6347 rtw89_err(rtwdev,
6348 "failed to alloc skb for packet drop\n");
6349 return -ENOMEM;
6350 }
6351
6352 switch (params->sel) {
6353 case RTW89_PKT_DROP_SEL_MACID_BE_ONCE:
6354 case RTW89_PKT_DROP_SEL_MACID_BK_ONCE:
6355 case RTW89_PKT_DROP_SEL_MACID_VI_ONCE:
6356 case RTW89_PKT_DROP_SEL_MACID_VO_ONCE:
6357 case RTW89_PKT_DROP_SEL_BAND_ONCE:
6358 break;
6359 default:
6360 rtw89_debug(rtwdev, RTW89_DBG_FW,
6361 "H2C of pkt drop might not fully support sel: %d yet\n",
6362 params->sel);
6363 break;
6364 }
6365
6366 skb_put(skb, H2C_PKT_DROP_LEN);
6367 RTW89_SET_FWCMD_PKT_DROP_SEL(skb->data, params->sel);
6368 RTW89_SET_FWCMD_PKT_DROP_MACID(skb->data, params->macid);
6369 RTW89_SET_FWCMD_PKT_DROP_BAND(skb->data, params->mac_band);
6370 RTW89_SET_FWCMD_PKT_DROP_PORT(skb->data, params->port);
6371 RTW89_SET_FWCMD_PKT_DROP_MBSSID(skb->data, params->mbssid);
6372 RTW89_SET_FWCMD_PKT_DROP_ROLE_A_INFO_TF_TRS(skb->data, params->tf_trs);
6373 RTW89_SET_FWCMD_PKT_DROP_MACID_BAND_SEL_0(skb->data,
6374 params->macid_band_sel[0]);
6375 RTW89_SET_FWCMD_PKT_DROP_MACID_BAND_SEL_1(skb->data,
6376 params->macid_band_sel[1]);
6377 RTW89_SET_FWCMD_PKT_DROP_MACID_BAND_SEL_2(skb->data,
6378 params->macid_band_sel[2]);
6379 RTW89_SET_FWCMD_PKT_DROP_MACID_BAND_SEL_3(skb->data,
6380 params->macid_band_sel[3]);
6381
6382 rtw89_h2c_pkt_set_hdr(rtwdev, skb, FWCMD_TYPE_H2C,
6383 H2C_CAT_MAC,
6384 H2C_CL_MAC_FW_OFLD,
6385 H2C_FUNC_PKT_DROP, 0, 0,
6386 H2C_PKT_DROP_LEN);
6387
6388 ret = rtw89_h2c_tx(rtwdev, skb, false);
6389 if (ret) {
6390 rtw89_err(rtwdev, "failed to send h2c\n");
6391 goto fail;
6392 }
6393
6394 return 0;
6395
6396 fail:
6397 dev_kfree_skb_any(skb);
6398 return ret;
6399 }
6400
6401 #define H2C_KEEP_ALIVE_LEN 4
rtw89_fw_h2c_keep_alive(struct rtw89_dev * rtwdev,struct rtw89_vif * rtwvif,bool enable)6402 int rtw89_fw_h2c_keep_alive(struct rtw89_dev *rtwdev, struct rtw89_vif *rtwvif,
6403 bool enable)
6404 {
6405 struct sk_buff *skb;
6406 u8 pkt_id = 0;
6407 int ret;
6408
6409 if (enable) {
6410 ret = rtw89_fw_h2c_add_general_pkt(rtwdev, rtwvif,
6411 RTW89_PKT_OFLD_TYPE_NULL_DATA,
6412 &pkt_id);
6413 if (ret)
6414 return -EPERM;
6415 }
6416
6417 skb = rtw89_fw_h2c_alloc_skb_with_hdr(rtwdev, H2C_KEEP_ALIVE_LEN);
6418 if (!skb) {
6419 rtw89_err(rtwdev, "failed to alloc skb for keep alive\n");
6420 return -ENOMEM;
6421 }
6422
6423 skb_put(skb, H2C_KEEP_ALIVE_LEN);
6424
6425 RTW89_SET_KEEP_ALIVE_ENABLE(skb->data, enable);
6426 RTW89_SET_KEEP_ALIVE_PKT_NULL_ID(skb->data, pkt_id);
6427 RTW89_SET_KEEP_ALIVE_PERIOD(skb->data, 5);
6428 RTW89_SET_KEEP_ALIVE_MACID(skb->data, rtwvif->mac_id);
6429
6430 rtw89_h2c_pkt_set_hdr(rtwdev, skb, FWCMD_TYPE_H2C,
6431 H2C_CAT_MAC,
6432 H2C_CL_MAC_WOW,
6433 H2C_FUNC_KEEP_ALIVE, 0, 1,
6434 H2C_KEEP_ALIVE_LEN);
6435
6436 ret = rtw89_h2c_tx(rtwdev, skb, false);
6437 if (ret) {
6438 rtw89_err(rtwdev, "failed to send h2c\n");
6439 goto fail;
6440 }
6441
6442 return 0;
6443
6444 fail:
6445 dev_kfree_skb_any(skb);
6446
6447 return ret;
6448 }
6449
rtw89_fw_h2c_arp_offload(struct rtw89_dev * rtwdev,struct rtw89_vif * rtwvif,bool enable)6450 int rtw89_fw_h2c_arp_offload(struct rtw89_dev *rtwdev, struct rtw89_vif *rtwvif,
6451 bool enable)
6452 {
6453 struct rtw89_h2c_arp_offload *h2c;
6454 u32 len = sizeof(*h2c);
6455 struct sk_buff *skb;
6456 u8 pkt_id = 0;
6457 int ret;
6458
6459 if (enable) {
6460 ret = rtw89_fw_h2c_add_general_pkt(rtwdev, rtwvif,
6461 RTW89_PKT_OFLD_TYPE_ARP_RSP,
6462 &pkt_id);
6463 if (ret)
6464 return ret;
6465 }
6466
6467 skb = rtw89_fw_h2c_alloc_skb_with_hdr(rtwdev, len);
6468 if (!skb) {
6469 rtw89_err(rtwdev, "failed to alloc skb for arp offload\n");
6470 return -ENOMEM;
6471 }
6472
6473 skb_put(skb, len);
6474 h2c = (struct rtw89_h2c_arp_offload *)skb->data;
6475
6476 h2c->w0 = le32_encode_bits(enable, RTW89_H2C_ARP_OFFLOAD_W0_ENABLE) |
6477 le32_encode_bits(0, RTW89_H2C_ARP_OFFLOAD_W0_ACTION) |
6478 le32_encode_bits(rtwvif->mac_id, RTW89_H2C_ARP_OFFLOAD_W0_MACID) |
6479 le32_encode_bits(pkt_id, RTW89_H2C_ARP_OFFLOAD_W0_PKT_ID);
6480
6481 rtw89_h2c_pkt_set_hdr(rtwdev, skb, FWCMD_TYPE_H2C,
6482 H2C_CAT_MAC,
6483 H2C_CL_MAC_WOW,
6484 H2C_FUNC_ARP_OFLD, 0, 1,
6485 len);
6486
6487 ret = rtw89_h2c_tx(rtwdev, skb, false);
6488 if (ret) {
6489 rtw89_err(rtwdev, "failed to send h2c\n");
6490 goto fail;
6491 }
6492
6493 return 0;
6494
6495 fail:
6496 dev_kfree_skb_any(skb);
6497
6498 return ret;
6499 }
6500
6501 #define H2C_DISCONNECT_DETECT_LEN 8
rtw89_fw_h2c_disconnect_detect(struct rtw89_dev * rtwdev,struct rtw89_vif * rtwvif,bool enable)6502 int rtw89_fw_h2c_disconnect_detect(struct rtw89_dev *rtwdev,
6503 struct rtw89_vif *rtwvif, bool enable)
6504 {
6505 struct rtw89_wow_param *rtw_wow = &rtwdev->wow;
6506 struct sk_buff *skb;
6507 u8 macid = rtwvif->mac_id;
6508 int ret;
6509
6510 skb = rtw89_fw_h2c_alloc_skb_with_hdr(rtwdev, H2C_DISCONNECT_DETECT_LEN);
6511 if (!skb) {
6512 rtw89_err(rtwdev, "failed to alloc skb for keep alive\n");
6513 return -ENOMEM;
6514 }
6515
6516 skb_put(skb, H2C_DISCONNECT_DETECT_LEN);
6517
6518 if (test_bit(RTW89_WOW_FLAG_EN_DISCONNECT, rtw_wow->flags)) {
6519 RTW89_SET_DISCONNECT_DETECT_ENABLE(skb->data, enable);
6520 RTW89_SET_DISCONNECT_DETECT_DISCONNECT(skb->data, !enable);
6521 RTW89_SET_DISCONNECT_DETECT_MAC_ID(skb->data, macid);
6522 RTW89_SET_DISCONNECT_DETECT_CHECK_PERIOD(skb->data, 100);
6523 RTW89_SET_DISCONNECT_DETECT_TRY_PKT_COUNT(skb->data, 5);
6524 }
6525
6526 rtw89_h2c_pkt_set_hdr(rtwdev, skb, FWCMD_TYPE_H2C,
6527 H2C_CAT_MAC,
6528 H2C_CL_MAC_WOW,
6529 H2C_FUNC_DISCONNECT_DETECT, 0, 1,
6530 H2C_DISCONNECT_DETECT_LEN);
6531
6532 ret = rtw89_h2c_tx(rtwdev, skb, false);
6533 if (ret) {
6534 rtw89_err(rtwdev, "failed to send h2c\n");
6535 goto fail;
6536 }
6537
6538 return 0;
6539
6540 fail:
6541 dev_kfree_skb_any(skb);
6542
6543 return ret;
6544 }
6545
rtw89_fw_h2c_wow_global(struct rtw89_dev * rtwdev,struct rtw89_vif * rtwvif,bool enable)6546 int rtw89_fw_h2c_wow_global(struct rtw89_dev *rtwdev, struct rtw89_vif *rtwvif,
6547 bool enable)
6548 {
6549 struct rtw89_wow_param *rtw_wow = &rtwdev->wow;
6550 struct rtw89_h2c_wow_global *h2c;
6551 u8 macid = rtwvif->mac_id;
6552 u32 len = sizeof(*h2c);
6553 struct sk_buff *skb;
6554 int ret;
6555
6556 skb = rtw89_fw_h2c_alloc_skb_with_hdr(rtwdev, len);
6557 if (!skb) {
6558 rtw89_err(rtwdev, "failed to alloc skb for wow global\n");
6559 return -ENOMEM;
6560 }
6561
6562 skb_put(skb, len);
6563 h2c = (struct rtw89_h2c_wow_global *)skb->data;
6564
6565 h2c->w0 = le32_encode_bits(enable, RTW89_H2C_WOW_GLOBAL_W0_ENABLE) |
6566 le32_encode_bits(macid, RTW89_H2C_WOW_GLOBAL_W0_MAC_ID) |
6567 le32_encode_bits(rtw_wow->ptk_alg,
6568 RTW89_H2C_WOW_GLOBAL_W0_PAIRWISE_SEC_ALGO) |
6569 le32_encode_bits(rtw_wow->gtk_alg,
6570 RTW89_H2C_WOW_GLOBAL_W0_GROUP_SEC_ALGO);
6571 h2c->key_info = rtw_wow->key_info;
6572
6573 rtw89_h2c_pkt_set_hdr(rtwdev, skb, FWCMD_TYPE_H2C,
6574 H2C_CAT_MAC,
6575 H2C_CL_MAC_WOW,
6576 H2C_FUNC_WOW_GLOBAL, 0, 1,
6577 len);
6578
6579 ret = rtw89_h2c_tx(rtwdev, skb, false);
6580 if (ret) {
6581 rtw89_err(rtwdev, "failed to send h2c\n");
6582 goto fail;
6583 }
6584
6585 return 0;
6586
6587 fail:
6588 dev_kfree_skb_any(skb);
6589
6590 return ret;
6591 }
6592
6593 #define H2C_WAKEUP_CTRL_LEN 4
rtw89_fw_h2c_wow_wakeup_ctrl(struct rtw89_dev * rtwdev,struct rtw89_vif * rtwvif,bool enable)6594 int rtw89_fw_h2c_wow_wakeup_ctrl(struct rtw89_dev *rtwdev,
6595 struct rtw89_vif *rtwvif,
6596 bool enable)
6597 {
6598 struct rtw89_wow_param *rtw_wow = &rtwdev->wow;
6599 struct sk_buff *skb;
6600 u8 macid = rtwvif->mac_id;
6601 int ret;
6602
6603 skb = rtw89_fw_h2c_alloc_skb_with_hdr(rtwdev, H2C_WAKEUP_CTRL_LEN);
6604 if (!skb) {
6605 rtw89_err(rtwdev, "failed to alloc skb for wakeup ctrl\n");
6606 return -ENOMEM;
6607 }
6608
6609 skb_put(skb, H2C_WAKEUP_CTRL_LEN);
6610
6611 if (rtw_wow->pattern_cnt)
6612 RTW89_SET_WOW_WAKEUP_CTRL_PATTERN_MATCH_ENABLE(skb->data, enable);
6613 if (test_bit(RTW89_WOW_FLAG_EN_MAGIC_PKT, rtw_wow->flags))
6614 RTW89_SET_WOW_WAKEUP_CTRL_MAGIC_ENABLE(skb->data, enable);
6615 if (test_bit(RTW89_WOW_FLAG_EN_DISCONNECT, rtw_wow->flags))
6616 RTW89_SET_WOW_WAKEUP_CTRL_DEAUTH_ENABLE(skb->data, enable);
6617
6618 RTW89_SET_WOW_WAKEUP_CTRL_MAC_ID(skb->data, macid);
6619
6620 rtw89_h2c_pkt_set_hdr(rtwdev, skb, FWCMD_TYPE_H2C,
6621 H2C_CAT_MAC,
6622 H2C_CL_MAC_WOW,
6623 H2C_FUNC_WAKEUP_CTRL, 0, 1,
6624 H2C_WAKEUP_CTRL_LEN);
6625
6626 ret = rtw89_h2c_tx(rtwdev, skb, false);
6627 if (ret) {
6628 rtw89_err(rtwdev, "failed to send h2c\n");
6629 goto fail;
6630 }
6631
6632 return 0;
6633
6634 fail:
6635 dev_kfree_skb_any(skb);
6636
6637 return ret;
6638 }
6639
6640 #define H2C_WOW_CAM_UPD_LEN 24
rtw89_fw_wow_cam_update(struct rtw89_dev * rtwdev,struct rtw89_wow_cam_info * cam_info)6641 int rtw89_fw_wow_cam_update(struct rtw89_dev *rtwdev,
6642 struct rtw89_wow_cam_info *cam_info)
6643 {
6644 struct sk_buff *skb;
6645 int ret;
6646
6647 skb = rtw89_fw_h2c_alloc_skb_with_hdr(rtwdev, H2C_WOW_CAM_UPD_LEN);
6648 if (!skb) {
6649 rtw89_err(rtwdev, "failed to alloc skb for keep alive\n");
6650 return -ENOMEM;
6651 }
6652
6653 skb_put(skb, H2C_WOW_CAM_UPD_LEN);
6654
6655 RTW89_SET_WOW_CAM_UPD_R_W(skb->data, cam_info->r_w);
6656 RTW89_SET_WOW_CAM_UPD_IDX(skb->data, cam_info->idx);
6657 if (cam_info->valid) {
6658 RTW89_SET_WOW_CAM_UPD_WKFM1(skb->data, cam_info->mask[0]);
6659 RTW89_SET_WOW_CAM_UPD_WKFM2(skb->data, cam_info->mask[1]);
6660 RTW89_SET_WOW_CAM_UPD_WKFM3(skb->data, cam_info->mask[2]);
6661 RTW89_SET_WOW_CAM_UPD_WKFM4(skb->data, cam_info->mask[3]);
6662 RTW89_SET_WOW_CAM_UPD_CRC(skb->data, cam_info->crc);
6663 RTW89_SET_WOW_CAM_UPD_NEGATIVE_PATTERN_MATCH(skb->data,
6664 cam_info->negative_pattern_match);
6665 RTW89_SET_WOW_CAM_UPD_SKIP_MAC_HDR(skb->data,
6666 cam_info->skip_mac_hdr);
6667 RTW89_SET_WOW_CAM_UPD_UC(skb->data, cam_info->uc);
6668 RTW89_SET_WOW_CAM_UPD_MC(skb->data, cam_info->mc);
6669 RTW89_SET_WOW_CAM_UPD_BC(skb->data, cam_info->bc);
6670 }
6671 RTW89_SET_WOW_CAM_UPD_VALID(skb->data, cam_info->valid);
6672
6673 rtw89_h2c_pkt_set_hdr(rtwdev, skb, FWCMD_TYPE_H2C,
6674 H2C_CAT_MAC,
6675 H2C_CL_MAC_WOW,
6676 H2C_FUNC_WOW_CAM_UPD, 0, 1,
6677 H2C_WOW_CAM_UPD_LEN);
6678
6679 ret = rtw89_h2c_tx(rtwdev, skb, false);
6680 if (ret) {
6681 rtw89_err(rtwdev, "failed to send h2c\n");
6682 goto fail;
6683 }
6684
6685 return 0;
6686 fail:
6687 dev_kfree_skb_any(skb);
6688
6689 return ret;
6690 }
6691
rtw89_fw_h2c_wow_gtk_ofld(struct rtw89_dev * rtwdev,struct rtw89_vif * rtwvif,bool enable)6692 int rtw89_fw_h2c_wow_gtk_ofld(struct rtw89_dev *rtwdev,
6693 struct rtw89_vif *rtwvif,
6694 bool enable)
6695 {
6696 struct rtw89_wow_param *rtw_wow = &rtwdev->wow;
6697 struct rtw89_wow_gtk_info *gtk_info = &rtw_wow->gtk_info;
6698 struct rtw89_h2c_wow_gtk_ofld *h2c;
6699 u8 macid = rtwvif->mac_id;
6700 u32 len = sizeof(*h2c);
6701 u8 pkt_id_sa_query = 0;
6702 struct sk_buff *skb;
6703 u8 pkt_id_eapol = 0;
6704 int ret;
6705
6706 if (!rtw_wow->gtk_alg)
6707 return 0;
6708
6709 skb = rtw89_fw_h2c_alloc_skb_with_hdr(rtwdev, len);
6710 if (!skb) {
6711 rtw89_err(rtwdev, "failed to alloc skb for gtk ofld\n");
6712 return -ENOMEM;
6713 }
6714
6715 skb_put(skb, len);
6716 h2c = (struct rtw89_h2c_wow_gtk_ofld *)skb->data;
6717
6718 if (!enable) {
6719 skb_put_zero(skb, sizeof(*gtk_info));
6720 goto hdr;
6721 }
6722
6723 ret = rtw89_fw_h2c_add_general_pkt(rtwdev, rtwvif,
6724 RTW89_PKT_OFLD_TYPE_EAPOL_KEY,
6725 &pkt_id_eapol);
6726 if (ret)
6727 goto fail;
6728
6729 if (gtk_info->igtk_keyid) {
6730 ret = rtw89_fw_h2c_add_general_pkt(rtwdev, rtwvif,
6731 RTW89_PKT_OFLD_TYPE_SA_QUERY,
6732 &pkt_id_sa_query);
6733 if (ret)
6734 goto fail;
6735 }
6736
6737 /* not support TKIP yet */
6738 h2c->w0 = le32_encode_bits(enable, RTW89_H2C_WOW_GTK_OFLD_W0_EN) |
6739 le32_encode_bits(0, RTW89_H2C_WOW_GTK_OFLD_W0_TKIP_EN) |
6740 le32_encode_bits(gtk_info->igtk_keyid ? 1 : 0,
6741 RTW89_H2C_WOW_GTK_OFLD_W0_IEEE80211W_EN) |
6742 le32_encode_bits(macid, RTW89_H2C_WOW_GTK_OFLD_W0_MAC_ID) |
6743 le32_encode_bits(pkt_id_eapol, RTW89_H2C_WOW_GTK_OFLD_W0_GTK_RSP_ID);
6744 h2c->w1 = le32_encode_bits(gtk_info->igtk_keyid ? pkt_id_sa_query : 0,
6745 RTW89_H2C_WOW_GTK_OFLD_W1_PMF_SA_QUERY_ID) |
6746 le32_encode_bits(rtw_wow->akm, RTW89_H2C_WOW_GTK_OFLD_W1_ALGO_AKM_SUIT);
6747 h2c->gtk_info = rtw_wow->gtk_info;
6748
6749 hdr:
6750 rtw89_h2c_pkt_set_hdr(rtwdev, skb, FWCMD_TYPE_H2C,
6751 H2C_CAT_MAC,
6752 H2C_CL_MAC_WOW,
6753 H2C_FUNC_GTK_OFLD, 0, 1,
6754 len);
6755
6756 ret = rtw89_h2c_tx(rtwdev, skb, false);
6757 if (ret) {
6758 rtw89_err(rtwdev, "failed to send h2c\n");
6759 goto fail;
6760 }
6761 return 0;
6762
6763 fail:
6764 dev_kfree_skb_any(skb);
6765
6766 return ret;
6767 }
6768
rtw89_fw_h2c_wow_request_aoac(struct rtw89_dev * rtwdev)6769 int rtw89_fw_h2c_wow_request_aoac(struct rtw89_dev *rtwdev)
6770 {
6771 struct rtw89_wait_info *wait = &rtwdev->mac.fw_ofld_wait;
6772 struct rtw89_h2c_wow_aoac *h2c;
6773 u32 len = sizeof(*h2c);
6774 struct sk_buff *skb;
6775 unsigned int cond;
6776
6777 skb = rtw89_fw_h2c_alloc_skb_with_hdr(rtwdev, len);
6778 if (!skb) {
6779 rtw89_err(rtwdev, "failed to alloc skb for aoac\n");
6780 return -ENOMEM;
6781 }
6782
6783 skb_put(skb, len);
6784
6785 /* This H2C only nofity firmware to generate AOAC report C2H,
6786 * no need any parameter.
6787 */
6788 rtw89_h2c_pkt_set_hdr(rtwdev, skb, FWCMD_TYPE_H2C,
6789 H2C_CAT_MAC,
6790 H2C_CL_MAC_WOW,
6791 H2C_FUNC_AOAC_REPORT_REQ, 1, 0,
6792 len);
6793
6794 cond = RTW89_WOW_WAIT_COND(H2C_FUNC_AOAC_REPORT_REQ);
6795 return rtw89_h2c_tx_and_wait(rtwdev, skb, wait, cond);
6796 }
6797
6798 /* Return < 0, if failures happen during waiting for the condition.
6799 * Return 0, when waiting for the condition succeeds.
6800 * Return > 0, if the wait is considered unreachable due to driver/FW design,
6801 * where 1 means during SER.
6802 */
rtw89_h2c_tx_and_wait(struct rtw89_dev * rtwdev,struct sk_buff * skb,struct rtw89_wait_info * wait,unsigned int cond)6803 static int rtw89_h2c_tx_and_wait(struct rtw89_dev *rtwdev, struct sk_buff *skb,
6804 struct rtw89_wait_info *wait, unsigned int cond)
6805 {
6806 int ret;
6807
6808 ret = rtw89_h2c_tx(rtwdev, skb, false);
6809 if (ret) {
6810 rtw89_err(rtwdev, "failed to send h2c\n");
6811 dev_kfree_skb_any(skb);
6812 return -EBUSY;
6813 }
6814
6815 if (test_bit(RTW89_FLAG_SER_HANDLING, rtwdev->flags))
6816 return 1;
6817
6818 return rtw89_wait_for_cond(wait, cond);
6819 }
6820
6821 #define H2C_ADD_MCC_LEN 16
rtw89_fw_h2c_add_mcc(struct rtw89_dev * rtwdev,const struct rtw89_fw_mcc_add_req * p)6822 int rtw89_fw_h2c_add_mcc(struct rtw89_dev *rtwdev,
6823 const struct rtw89_fw_mcc_add_req *p)
6824 {
6825 struct rtw89_wait_info *wait = &rtwdev->mcc.wait;
6826 struct sk_buff *skb;
6827 unsigned int cond;
6828
6829 skb = rtw89_fw_h2c_alloc_skb_with_hdr(rtwdev, H2C_ADD_MCC_LEN);
6830 if (!skb) {
6831 rtw89_err(rtwdev,
6832 "failed to alloc skb for add mcc\n");
6833 return -ENOMEM;
6834 }
6835
6836 skb_put(skb, H2C_ADD_MCC_LEN);
6837 RTW89_SET_FWCMD_ADD_MCC_MACID(skb->data, p->macid);
6838 RTW89_SET_FWCMD_ADD_MCC_CENTRAL_CH_SEG0(skb->data, p->central_ch_seg0);
6839 RTW89_SET_FWCMD_ADD_MCC_CENTRAL_CH_SEG1(skb->data, p->central_ch_seg1);
6840 RTW89_SET_FWCMD_ADD_MCC_PRIMARY_CH(skb->data, p->primary_ch);
6841 RTW89_SET_FWCMD_ADD_MCC_BANDWIDTH(skb->data, p->bandwidth);
6842 RTW89_SET_FWCMD_ADD_MCC_GROUP(skb->data, p->group);
6843 RTW89_SET_FWCMD_ADD_MCC_C2H_RPT(skb->data, p->c2h_rpt);
6844 RTW89_SET_FWCMD_ADD_MCC_DIS_TX_NULL(skb->data, p->dis_tx_null);
6845 RTW89_SET_FWCMD_ADD_MCC_DIS_SW_RETRY(skb->data, p->dis_sw_retry);
6846 RTW89_SET_FWCMD_ADD_MCC_IN_CURR_CH(skb->data, p->in_curr_ch);
6847 RTW89_SET_FWCMD_ADD_MCC_SW_RETRY_COUNT(skb->data, p->sw_retry_count);
6848 RTW89_SET_FWCMD_ADD_MCC_TX_NULL_EARLY(skb->data, p->tx_null_early);
6849 RTW89_SET_FWCMD_ADD_MCC_BTC_IN_2G(skb->data, p->btc_in_2g);
6850 RTW89_SET_FWCMD_ADD_MCC_PTA_EN(skb->data, p->pta_en);
6851 RTW89_SET_FWCMD_ADD_MCC_RFK_BY_PASS(skb->data, p->rfk_by_pass);
6852 RTW89_SET_FWCMD_ADD_MCC_CH_BAND_TYPE(skb->data, p->ch_band_type);
6853 RTW89_SET_FWCMD_ADD_MCC_DURATION(skb->data, p->duration);
6854 RTW89_SET_FWCMD_ADD_MCC_COURTESY_EN(skb->data, p->courtesy_en);
6855 RTW89_SET_FWCMD_ADD_MCC_COURTESY_NUM(skb->data, p->courtesy_num);
6856 RTW89_SET_FWCMD_ADD_MCC_COURTESY_TARGET(skb->data, p->courtesy_target);
6857
6858 rtw89_h2c_pkt_set_hdr(rtwdev, skb, FWCMD_TYPE_H2C,
6859 H2C_CAT_MAC,
6860 H2C_CL_MCC,
6861 H2C_FUNC_ADD_MCC, 0, 0,
6862 H2C_ADD_MCC_LEN);
6863
6864 cond = RTW89_MCC_WAIT_COND(p->group, H2C_FUNC_ADD_MCC);
6865 return rtw89_h2c_tx_and_wait(rtwdev, skb, wait, cond);
6866 }
6867
6868 #define H2C_START_MCC_LEN 12
rtw89_fw_h2c_start_mcc(struct rtw89_dev * rtwdev,const struct rtw89_fw_mcc_start_req * p)6869 int rtw89_fw_h2c_start_mcc(struct rtw89_dev *rtwdev,
6870 const struct rtw89_fw_mcc_start_req *p)
6871 {
6872 struct rtw89_wait_info *wait = &rtwdev->mcc.wait;
6873 struct sk_buff *skb;
6874 unsigned int cond;
6875
6876 skb = rtw89_fw_h2c_alloc_skb_with_hdr(rtwdev, H2C_START_MCC_LEN);
6877 if (!skb) {
6878 rtw89_err(rtwdev,
6879 "failed to alloc skb for start mcc\n");
6880 return -ENOMEM;
6881 }
6882
6883 skb_put(skb, H2C_START_MCC_LEN);
6884 RTW89_SET_FWCMD_START_MCC_GROUP(skb->data, p->group);
6885 RTW89_SET_FWCMD_START_MCC_BTC_IN_GROUP(skb->data, p->btc_in_group);
6886 RTW89_SET_FWCMD_START_MCC_OLD_GROUP_ACTION(skb->data, p->old_group_action);
6887 RTW89_SET_FWCMD_START_MCC_OLD_GROUP(skb->data, p->old_group);
6888 RTW89_SET_FWCMD_START_MCC_NOTIFY_CNT(skb->data, p->notify_cnt);
6889 RTW89_SET_FWCMD_START_MCC_NOTIFY_RXDBG_EN(skb->data, p->notify_rxdbg_en);
6890 RTW89_SET_FWCMD_START_MCC_MACID(skb->data, p->macid);
6891 RTW89_SET_FWCMD_START_MCC_TSF_LOW(skb->data, p->tsf_low);
6892 RTW89_SET_FWCMD_START_MCC_TSF_HIGH(skb->data, p->tsf_high);
6893
6894 rtw89_h2c_pkt_set_hdr(rtwdev, skb, FWCMD_TYPE_H2C,
6895 H2C_CAT_MAC,
6896 H2C_CL_MCC,
6897 H2C_FUNC_START_MCC, 0, 0,
6898 H2C_START_MCC_LEN);
6899
6900 cond = RTW89_MCC_WAIT_COND(p->group, H2C_FUNC_START_MCC);
6901 return rtw89_h2c_tx_and_wait(rtwdev, skb, wait, cond);
6902 }
6903
6904 #define H2C_STOP_MCC_LEN 4
rtw89_fw_h2c_stop_mcc(struct rtw89_dev * rtwdev,u8 group,u8 macid,bool prev_groups)6905 int rtw89_fw_h2c_stop_mcc(struct rtw89_dev *rtwdev, u8 group, u8 macid,
6906 bool prev_groups)
6907 {
6908 struct rtw89_wait_info *wait = &rtwdev->mcc.wait;
6909 struct sk_buff *skb;
6910 unsigned int cond;
6911
6912 skb = rtw89_fw_h2c_alloc_skb_with_hdr(rtwdev, H2C_STOP_MCC_LEN);
6913 if (!skb) {
6914 rtw89_err(rtwdev,
6915 "failed to alloc skb for stop mcc\n");
6916 return -ENOMEM;
6917 }
6918
6919 skb_put(skb, H2C_STOP_MCC_LEN);
6920 RTW89_SET_FWCMD_STOP_MCC_MACID(skb->data, macid);
6921 RTW89_SET_FWCMD_STOP_MCC_GROUP(skb->data, group);
6922 RTW89_SET_FWCMD_STOP_MCC_PREV_GROUPS(skb->data, prev_groups);
6923
6924 rtw89_h2c_pkt_set_hdr(rtwdev, skb, FWCMD_TYPE_H2C,
6925 H2C_CAT_MAC,
6926 H2C_CL_MCC,
6927 H2C_FUNC_STOP_MCC, 0, 0,
6928 H2C_STOP_MCC_LEN);
6929
6930 cond = RTW89_MCC_WAIT_COND(group, H2C_FUNC_STOP_MCC);
6931 return rtw89_h2c_tx_and_wait(rtwdev, skb, wait, cond);
6932 }
6933
6934 #define H2C_DEL_MCC_GROUP_LEN 4
rtw89_fw_h2c_del_mcc_group(struct rtw89_dev * rtwdev,u8 group,bool prev_groups)6935 int rtw89_fw_h2c_del_mcc_group(struct rtw89_dev *rtwdev, u8 group,
6936 bool prev_groups)
6937 {
6938 struct rtw89_wait_info *wait = &rtwdev->mcc.wait;
6939 struct sk_buff *skb;
6940 unsigned int cond;
6941
6942 skb = rtw89_fw_h2c_alloc_skb_with_hdr(rtwdev, H2C_DEL_MCC_GROUP_LEN);
6943 if (!skb) {
6944 rtw89_err(rtwdev,
6945 "failed to alloc skb for del mcc group\n");
6946 return -ENOMEM;
6947 }
6948
6949 skb_put(skb, H2C_DEL_MCC_GROUP_LEN);
6950 RTW89_SET_FWCMD_DEL_MCC_GROUP_GROUP(skb->data, group);
6951 RTW89_SET_FWCMD_DEL_MCC_GROUP_PREV_GROUPS(skb->data, prev_groups);
6952
6953 rtw89_h2c_pkt_set_hdr(rtwdev, skb, FWCMD_TYPE_H2C,
6954 H2C_CAT_MAC,
6955 H2C_CL_MCC,
6956 H2C_FUNC_DEL_MCC_GROUP, 0, 0,
6957 H2C_DEL_MCC_GROUP_LEN);
6958
6959 cond = RTW89_MCC_WAIT_COND(group, H2C_FUNC_DEL_MCC_GROUP);
6960 return rtw89_h2c_tx_and_wait(rtwdev, skb, wait, cond);
6961 }
6962
6963 #define H2C_RESET_MCC_GROUP_LEN 4
rtw89_fw_h2c_reset_mcc_group(struct rtw89_dev * rtwdev,u8 group)6964 int rtw89_fw_h2c_reset_mcc_group(struct rtw89_dev *rtwdev, u8 group)
6965 {
6966 struct rtw89_wait_info *wait = &rtwdev->mcc.wait;
6967 struct sk_buff *skb;
6968 unsigned int cond;
6969
6970 skb = rtw89_fw_h2c_alloc_skb_with_hdr(rtwdev, H2C_RESET_MCC_GROUP_LEN);
6971 if (!skb) {
6972 rtw89_err(rtwdev,
6973 "failed to alloc skb for reset mcc group\n");
6974 return -ENOMEM;
6975 }
6976
6977 skb_put(skb, H2C_RESET_MCC_GROUP_LEN);
6978 RTW89_SET_FWCMD_RESET_MCC_GROUP_GROUP(skb->data, group);
6979
6980 rtw89_h2c_pkt_set_hdr(rtwdev, skb, FWCMD_TYPE_H2C,
6981 H2C_CAT_MAC,
6982 H2C_CL_MCC,
6983 H2C_FUNC_RESET_MCC_GROUP, 0, 0,
6984 H2C_RESET_MCC_GROUP_LEN);
6985
6986 cond = RTW89_MCC_WAIT_COND(group, H2C_FUNC_RESET_MCC_GROUP);
6987 return rtw89_h2c_tx_and_wait(rtwdev, skb, wait, cond);
6988 }
6989
6990 #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)6991 int rtw89_fw_h2c_mcc_req_tsf(struct rtw89_dev *rtwdev,
6992 const struct rtw89_fw_mcc_tsf_req *req,
6993 struct rtw89_mac_mcc_tsf_rpt *rpt)
6994 {
6995 struct rtw89_wait_info *wait = &rtwdev->mcc.wait;
6996 struct rtw89_mac_mcc_tsf_rpt *tmp;
6997 struct sk_buff *skb;
6998 unsigned int cond;
6999 int ret;
7000
7001 skb = rtw89_fw_h2c_alloc_skb_with_hdr(rtwdev, H2C_MCC_REQ_TSF_LEN);
7002 if (!skb) {
7003 rtw89_err(rtwdev,
7004 "failed to alloc skb for mcc req tsf\n");
7005 return -ENOMEM;
7006 }
7007
7008 skb_put(skb, H2C_MCC_REQ_TSF_LEN);
7009 RTW89_SET_FWCMD_MCC_REQ_TSF_GROUP(skb->data, req->group);
7010 RTW89_SET_FWCMD_MCC_REQ_TSF_MACID_X(skb->data, req->macid_x);
7011 RTW89_SET_FWCMD_MCC_REQ_TSF_MACID_Y(skb->data, req->macid_y);
7012
7013 rtw89_h2c_pkt_set_hdr(rtwdev, skb, FWCMD_TYPE_H2C,
7014 H2C_CAT_MAC,
7015 H2C_CL_MCC,
7016 H2C_FUNC_MCC_REQ_TSF, 0, 0,
7017 H2C_MCC_REQ_TSF_LEN);
7018
7019 cond = RTW89_MCC_WAIT_COND(req->group, H2C_FUNC_MCC_REQ_TSF);
7020 ret = rtw89_h2c_tx_and_wait(rtwdev, skb, wait, cond);
7021 if (ret)
7022 return ret;
7023
7024 tmp = (struct rtw89_mac_mcc_tsf_rpt *)wait->data.buf;
7025 *rpt = *tmp;
7026
7027 return 0;
7028 }
7029
7030 #define H2C_MCC_MACID_BITMAP_DSC_LEN 4
rtw89_fw_h2c_mcc_macid_bitmap(struct rtw89_dev * rtwdev,u8 group,u8 macid,u8 * bitmap)7031 int rtw89_fw_h2c_mcc_macid_bitmap(struct rtw89_dev *rtwdev, u8 group, u8 macid,
7032 u8 *bitmap)
7033 {
7034 struct rtw89_wait_info *wait = &rtwdev->mcc.wait;
7035 struct sk_buff *skb;
7036 unsigned int cond;
7037 u8 map_len;
7038 u8 h2c_len;
7039
7040 BUILD_BUG_ON(RTW89_MAX_MAC_ID_NUM % 8);
7041 map_len = RTW89_MAX_MAC_ID_NUM / 8;
7042 h2c_len = H2C_MCC_MACID_BITMAP_DSC_LEN + map_len;
7043 skb = rtw89_fw_h2c_alloc_skb_with_hdr(rtwdev, h2c_len);
7044 if (!skb) {
7045 rtw89_err(rtwdev,
7046 "failed to alloc skb for mcc macid bitmap\n");
7047 return -ENOMEM;
7048 }
7049
7050 skb_put(skb, h2c_len);
7051 RTW89_SET_FWCMD_MCC_MACID_BITMAP_GROUP(skb->data, group);
7052 RTW89_SET_FWCMD_MCC_MACID_BITMAP_MACID(skb->data, macid);
7053 RTW89_SET_FWCMD_MCC_MACID_BITMAP_BITMAP_LENGTH(skb->data, map_len);
7054 RTW89_SET_FWCMD_MCC_MACID_BITMAP_BITMAP(skb->data, bitmap, map_len);
7055
7056 rtw89_h2c_pkt_set_hdr(rtwdev, skb, FWCMD_TYPE_H2C,
7057 H2C_CAT_MAC,
7058 H2C_CL_MCC,
7059 H2C_FUNC_MCC_MACID_BITMAP, 0, 0,
7060 h2c_len);
7061
7062 cond = RTW89_MCC_WAIT_COND(group, H2C_FUNC_MCC_MACID_BITMAP);
7063 return rtw89_h2c_tx_and_wait(rtwdev, skb, wait, cond);
7064 }
7065
7066 #define H2C_MCC_SYNC_LEN 4
rtw89_fw_h2c_mcc_sync(struct rtw89_dev * rtwdev,u8 group,u8 source,u8 target,u8 offset)7067 int rtw89_fw_h2c_mcc_sync(struct rtw89_dev *rtwdev, u8 group, u8 source,
7068 u8 target, u8 offset)
7069 {
7070 struct rtw89_wait_info *wait = &rtwdev->mcc.wait;
7071 struct sk_buff *skb;
7072 unsigned int cond;
7073
7074 skb = rtw89_fw_h2c_alloc_skb_with_hdr(rtwdev, H2C_MCC_SYNC_LEN);
7075 if (!skb) {
7076 rtw89_err(rtwdev,
7077 "failed to alloc skb for mcc sync\n");
7078 return -ENOMEM;
7079 }
7080
7081 skb_put(skb, H2C_MCC_SYNC_LEN);
7082 RTW89_SET_FWCMD_MCC_SYNC_GROUP(skb->data, group);
7083 RTW89_SET_FWCMD_MCC_SYNC_MACID_SOURCE(skb->data, source);
7084 RTW89_SET_FWCMD_MCC_SYNC_MACID_TARGET(skb->data, target);
7085 RTW89_SET_FWCMD_MCC_SYNC_SYNC_OFFSET(skb->data, offset);
7086
7087 rtw89_h2c_pkt_set_hdr(rtwdev, skb, FWCMD_TYPE_H2C,
7088 H2C_CAT_MAC,
7089 H2C_CL_MCC,
7090 H2C_FUNC_MCC_SYNC, 0, 0,
7091 H2C_MCC_SYNC_LEN);
7092
7093 cond = RTW89_MCC_WAIT_COND(group, H2C_FUNC_MCC_SYNC);
7094 return rtw89_h2c_tx_and_wait(rtwdev, skb, wait, cond);
7095 }
7096
7097 #define H2C_MCC_SET_DURATION_LEN 20
rtw89_fw_h2c_mcc_set_duration(struct rtw89_dev * rtwdev,const struct rtw89_fw_mcc_duration * p)7098 int rtw89_fw_h2c_mcc_set_duration(struct rtw89_dev *rtwdev,
7099 const struct rtw89_fw_mcc_duration *p)
7100 {
7101 struct rtw89_wait_info *wait = &rtwdev->mcc.wait;
7102 struct sk_buff *skb;
7103 unsigned int cond;
7104
7105 skb = rtw89_fw_h2c_alloc_skb_with_hdr(rtwdev, H2C_MCC_SET_DURATION_LEN);
7106 if (!skb) {
7107 rtw89_err(rtwdev,
7108 "failed to alloc skb for mcc set duration\n");
7109 return -ENOMEM;
7110 }
7111
7112 skb_put(skb, H2C_MCC_SET_DURATION_LEN);
7113 RTW89_SET_FWCMD_MCC_SET_DURATION_GROUP(skb->data, p->group);
7114 RTW89_SET_FWCMD_MCC_SET_DURATION_BTC_IN_GROUP(skb->data, p->btc_in_group);
7115 RTW89_SET_FWCMD_MCC_SET_DURATION_START_MACID(skb->data, p->start_macid);
7116 RTW89_SET_FWCMD_MCC_SET_DURATION_MACID_X(skb->data, p->macid_x);
7117 RTW89_SET_FWCMD_MCC_SET_DURATION_MACID_Y(skb->data, p->macid_y);
7118 RTW89_SET_FWCMD_MCC_SET_DURATION_START_TSF_LOW(skb->data,
7119 p->start_tsf_low);
7120 RTW89_SET_FWCMD_MCC_SET_DURATION_START_TSF_HIGH(skb->data,
7121 p->start_tsf_high);
7122 RTW89_SET_FWCMD_MCC_SET_DURATION_DURATION_X(skb->data, p->duration_x);
7123 RTW89_SET_FWCMD_MCC_SET_DURATION_DURATION_Y(skb->data, p->duration_y);
7124
7125 rtw89_h2c_pkt_set_hdr(rtwdev, skb, FWCMD_TYPE_H2C,
7126 H2C_CAT_MAC,
7127 H2C_CL_MCC,
7128 H2C_FUNC_MCC_SET_DURATION, 0, 0,
7129 H2C_MCC_SET_DURATION_LEN);
7130
7131 cond = RTW89_MCC_WAIT_COND(p->group, H2C_FUNC_MCC_SET_DURATION);
7132 return rtw89_h2c_tx_and_wait(rtwdev, skb, wait, cond);
7133 }
7134
7135 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)7136 u32 rtw89_fw_h2c_mrc_add_slot(struct rtw89_dev *rtwdev,
7137 const struct rtw89_fw_mrc_add_slot_arg *slot_arg,
7138 struct rtw89_h2c_mrc_add_slot *slot_h2c)
7139 {
7140 bool fill_h2c = !!slot_h2c;
7141 unsigned int i;
7142
7143 if (!fill_h2c)
7144 goto calc_len;
7145
7146 slot_h2c->w0 = le32_encode_bits(slot_arg->duration,
7147 RTW89_H2C_MRC_ADD_SLOT_W0_DURATION) |
7148 le32_encode_bits(slot_arg->courtesy_en,
7149 RTW89_H2C_MRC_ADD_SLOT_W0_COURTESY_EN) |
7150 le32_encode_bits(slot_arg->role_num,
7151 RTW89_H2C_MRC_ADD_SLOT_W0_ROLE_NUM);
7152 slot_h2c->w1 = le32_encode_bits(slot_arg->courtesy_period,
7153 RTW89_H2C_MRC_ADD_SLOT_W1_COURTESY_PERIOD) |
7154 le32_encode_bits(slot_arg->courtesy_target,
7155 RTW89_H2C_MRC_ADD_SLOT_W1_COURTESY_TARGET);
7156
7157 for (i = 0; i < slot_arg->role_num; i++) {
7158 slot_h2c->roles[i].w0 =
7159 le32_encode_bits(slot_arg->roles[i].macid,
7160 RTW89_H2C_MRC_ADD_ROLE_W0_MACID) |
7161 le32_encode_bits(slot_arg->roles[i].role_type,
7162 RTW89_H2C_MRC_ADD_ROLE_W0_ROLE_TYPE) |
7163 le32_encode_bits(slot_arg->roles[i].is_master,
7164 RTW89_H2C_MRC_ADD_ROLE_W0_IS_MASTER) |
7165 le32_encode_bits(slot_arg->roles[i].en_tx_null,
7166 RTW89_H2C_MRC_ADD_ROLE_W0_TX_NULL_EN) |
7167 le32_encode_bits(false,
7168 RTW89_H2C_MRC_ADD_ROLE_W0_IS_ALT_ROLE) |
7169 le32_encode_bits(false,
7170 RTW89_H2C_MRC_ADD_ROLE_W0_ROLE_ALT_EN);
7171 slot_h2c->roles[i].w1 =
7172 le32_encode_bits(slot_arg->roles[i].central_ch,
7173 RTW89_H2C_MRC_ADD_ROLE_W1_CENTRAL_CH_SEG) |
7174 le32_encode_bits(slot_arg->roles[i].primary_ch,
7175 RTW89_H2C_MRC_ADD_ROLE_W1_PRI_CH) |
7176 le32_encode_bits(slot_arg->roles[i].bw,
7177 RTW89_H2C_MRC_ADD_ROLE_W1_BW) |
7178 le32_encode_bits(slot_arg->roles[i].band,
7179 RTW89_H2C_MRC_ADD_ROLE_W1_CH_BAND_TYPE) |
7180 le32_encode_bits(slot_arg->roles[i].null_early,
7181 RTW89_H2C_MRC_ADD_ROLE_W1_NULL_EARLY) |
7182 le32_encode_bits(false,
7183 RTW89_H2C_MRC_ADD_ROLE_W1_RFK_BY_PASS) |
7184 le32_encode_bits(true,
7185 RTW89_H2C_MRC_ADD_ROLE_W1_CAN_BTC);
7186 slot_h2c->roles[i].macid_main_bitmap =
7187 cpu_to_le32(slot_arg->roles[i].macid_main_bitmap);
7188 slot_h2c->roles[i].macid_paired_bitmap =
7189 cpu_to_le32(slot_arg->roles[i].macid_paired_bitmap);
7190 }
7191
7192 calc_len:
7193 return struct_size(slot_h2c, roles, slot_arg->role_num);
7194 }
7195
rtw89_fw_h2c_mrc_add(struct rtw89_dev * rtwdev,const struct rtw89_fw_mrc_add_arg * arg)7196 int rtw89_fw_h2c_mrc_add(struct rtw89_dev *rtwdev,
7197 const struct rtw89_fw_mrc_add_arg *arg)
7198 {
7199 struct rtw89_h2c_mrc_add *h2c_head;
7200 struct sk_buff *skb;
7201 unsigned int i;
7202 void *tmp;
7203 u32 len;
7204 int ret;
7205
7206 len = sizeof(*h2c_head);
7207 for (i = 0; i < arg->slot_num; i++)
7208 len += rtw89_fw_h2c_mrc_add_slot(rtwdev, &arg->slots[i], NULL);
7209
7210 skb = rtw89_fw_h2c_alloc_skb_with_hdr(rtwdev, len);
7211 if (!skb) {
7212 rtw89_err(rtwdev, "failed to alloc skb for mrc add\n");
7213 return -ENOMEM;
7214 }
7215
7216 skb_put(skb, len);
7217 tmp = skb->data;
7218
7219 h2c_head = tmp;
7220 h2c_head->w0 = le32_encode_bits(arg->sch_idx,
7221 RTW89_H2C_MRC_ADD_W0_SCH_IDX) |
7222 le32_encode_bits(arg->sch_type,
7223 RTW89_H2C_MRC_ADD_W0_SCH_TYPE) |
7224 le32_encode_bits(arg->slot_num,
7225 RTW89_H2C_MRC_ADD_W0_SLOT_NUM) |
7226 le32_encode_bits(arg->btc_in_sch,
7227 RTW89_H2C_MRC_ADD_W0_BTC_IN_SCH);
7228
7229 tmp += sizeof(*h2c_head);
7230 for (i = 0; i < arg->slot_num; i++)
7231 tmp += rtw89_fw_h2c_mrc_add_slot(rtwdev, &arg->slots[i], tmp);
7232
7233 rtw89_h2c_pkt_set_hdr(rtwdev, skb, FWCMD_TYPE_H2C,
7234 H2C_CAT_MAC,
7235 H2C_CL_MRC,
7236 H2C_FUNC_ADD_MRC, 0, 0,
7237 len);
7238
7239 ret = rtw89_h2c_tx(rtwdev, skb, false);
7240 if (ret) {
7241 rtw89_err(rtwdev, "failed to send h2c\n");
7242 dev_kfree_skb_any(skb);
7243 return -EBUSY;
7244 }
7245
7246 return 0;
7247 }
7248
rtw89_fw_h2c_mrc_start(struct rtw89_dev * rtwdev,const struct rtw89_fw_mrc_start_arg * arg)7249 int rtw89_fw_h2c_mrc_start(struct rtw89_dev *rtwdev,
7250 const struct rtw89_fw_mrc_start_arg *arg)
7251 {
7252 struct rtw89_wait_info *wait = &rtwdev->mcc.wait;
7253 struct rtw89_h2c_mrc_start *h2c;
7254 u32 len = sizeof(*h2c);
7255 struct sk_buff *skb;
7256 unsigned int cond;
7257
7258 skb = rtw89_fw_h2c_alloc_skb_with_hdr(rtwdev, len);
7259 if (!skb) {
7260 rtw89_err(rtwdev, "failed to alloc skb for mrc start\n");
7261 return -ENOMEM;
7262 }
7263
7264 skb_put(skb, len);
7265 h2c = (struct rtw89_h2c_mrc_start *)skb->data;
7266
7267 h2c->w0 = le32_encode_bits(arg->sch_idx,
7268 RTW89_H2C_MRC_START_W0_SCH_IDX) |
7269 le32_encode_bits(arg->old_sch_idx,
7270 RTW89_H2C_MRC_START_W0_OLD_SCH_IDX) |
7271 le32_encode_bits(arg->action,
7272 RTW89_H2C_MRC_START_W0_ACTION);
7273
7274 h2c->start_tsf_high = cpu_to_le32(arg->start_tsf >> 32);
7275 h2c->start_tsf_low = cpu_to_le32(arg->start_tsf);
7276
7277 rtw89_h2c_pkt_set_hdr(rtwdev, skb, FWCMD_TYPE_H2C,
7278 H2C_CAT_MAC,
7279 H2C_CL_MRC,
7280 H2C_FUNC_START_MRC, 0, 0,
7281 len);
7282
7283 cond = RTW89_MRC_WAIT_COND(arg->sch_idx, H2C_FUNC_START_MRC);
7284 return rtw89_h2c_tx_and_wait(rtwdev, skb, wait, cond);
7285 }
7286
rtw89_fw_h2c_mrc_del(struct rtw89_dev * rtwdev,u8 sch_idx)7287 int rtw89_fw_h2c_mrc_del(struct rtw89_dev *rtwdev, u8 sch_idx)
7288 {
7289 struct rtw89_wait_info *wait = &rtwdev->mcc.wait;
7290 struct rtw89_h2c_mrc_del *h2c;
7291 u32 len = sizeof(*h2c);
7292 struct sk_buff *skb;
7293 unsigned int cond;
7294
7295 skb = rtw89_fw_h2c_alloc_skb_with_hdr(rtwdev, len);
7296 if (!skb) {
7297 rtw89_err(rtwdev, "failed to alloc skb for mrc del\n");
7298 return -ENOMEM;
7299 }
7300
7301 skb_put(skb, len);
7302 h2c = (struct rtw89_h2c_mrc_del *)skb->data;
7303
7304 h2c->w0 = le32_encode_bits(sch_idx, RTW89_H2C_MRC_DEL_W0_SCH_IDX);
7305
7306 rtw89_h2c_pkt_set_hdr(rtwdev, skb, FWCMD_TYPE_H2C,
7307 H2C_CAT_MAC,
7308 H2C_CL_MRC,
7309 H2C_FUNC_DEL_MRC, 0, 0,
7310 len);
7311
7312 cond = RTW89_MRC_WAIT_COND(sch_idx, H2C_FUNC_DEL_MRC);
7313 return rtw89_h2c_tx_and_wait(rtwdev, skb, wait, cond);
7314 }
7315
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)7316 int rtw89_fw_h2c_mrc_req_tsf(struct rtw89_dev *rtwdev,
7317 const struct rtw89_fw_mrc_req_tsf_arg *arg,
7318 struct rtw89_mac_mrc_tsf_rpt *rpt)
7319 {
7320 struct rtw89_wait_info *wait = &rtwdev->mcc.wait;
7321 struct rtw89_h2c_mrc_req_tsf *h2c;
7322 struct rtw89_mac_mrc_tsf_rpt *tmp;
7323 struct sk_buff *skb;
7324 unsigned int i;
7325 u32 len;
7326 int ret;
7327
7328 len = struct_size(h2c, infos, arg->num);
7329 skb = rtw89_fw_h2c_alloc_skb_with_hdr(rtwdev, len);
7330 if (!skb) {
7331 rtw89_err(rtwdev, "failed to alloc skb for mrc req tsf\n");
7332 return -ENOMEM;
7333 }
7334
7335 skb_put(skb, len);
7336 h2c = (struct rtw89_h2c_mrc_req_tsf *)skb->data;
7337
7338 h2c->req_tsf_num = arg->num;
7339 for (i = 0; i < arg->num; i++)
7340 h2c->infos[i] =
7341 u8_encode_bits(arg->infos[i].band,
7342 RTW89_H2C_MRC_REQ_TSF_INFO_BAND) |
7343 u8_encode_bits(arg->infos[i].port,
7344 RTW89_H2C_MRC_REQ_TSF_INFO_PORT);
7345
7346 rtw89_h2c_pkt_set_hdr(rtwdev, skb, FWCMD_TYPE_H2C,
7347 H2C_CAT_MAC,
7348 H2C_CL_MRC,
7349 H2C_FUNC_MRC_REQ_TSF, 0, 0,
7350 len);
7351
7352 ret = rtw89_h2c_tx_and_wait(rtwdev, skb, wait, RTW89_MRC_WAIT_COND_REQ_TSF);
7353 if (ret)
7354 return ret;
7355
7356 tmp = (struct rtw89_mac_mrc_tsf_rpt *)wait->data.buf;
7357 *rpt = *tmp;
7358
7359 return 0;
7360 }
7361
rtw89_fw_h2c_mrc_upd_bitmap(struct rtw89_dev * rtwdev,const struct rtw89_fw_mrc_upd_bitmap_arg * arg)7362 int rtw89_fw_h2c_mrc_upd_bitmap(struct rtw89_dev *rtwdev,
7363 const struct rtw89_fw_mrc_upd_bitmap_arg *arg)
7364 {
7365 struct rtw89_h2c_mrc_upd_bitmap *h2c;
7366 u32 len = sizeof(*h2c);
7367 struct sk_buff *skb;
7368 int ret;
7369
7370 skb = rtw89_fw_h2c_alloc_skb_with_hdr(rtwdev, len);
7371 if (!skb) {
7372 rtw89_err(rtwdev, "failed to alloc skb for mrc upd bitmap\n");
7373 return -ENOMEM;
7374 }
7375
7376 skb_put(skb, len);
7377 h2c = (struct rtw89_h2c_mrc_upd_bitmap *)skb->data;
7378
7379 h2c->w0 = le32_encode_bits(arg->sch_idx,
7380 RTW89_H2C_MRC_UPD_BITMAP_W0_SCH_IDX) |
7381 le32_encode_bits(arg->action,
7382 RTW89_H2C_MRC_UPD_BITMAP_W0_ACTION) |
7383 le32_encode_bits(arg->macid,
7384 RTW89_H2C_MRC_UPD_BITMAP_W0_MACID);
7385 h2c->w1 = le32_encode_bits(arg->client_macid,
7386 RTW89_H2C_MRC_UPD_BITMAP_W1_CLIENT_MACID);
7387
7388 rtw89_h2c_pkt_set_hdr(rtwdev, skb, FWCMD_TYPE_H2C,
7389 H2C_CAT_MAC,
7390 H2C_CL_MRC,
7391 H2C_FUNC_MRC_UPD_BITMAP, 0, 0,
7392 len);
7393
7394 ret = rtw89_h2c_tx(rtwdev, skb, false);
7395 if (ret) {
7396 rtw89_err(rtwdev, "failed to send h2c\n");
7397 dev_kfree_skb_any(skb);
7398 return -EBUSY;
7399 }
7400
7401 return 0;
7402 }
7403
rtw89_fw_h2c_mrc_sync(struct rtw89_dev * rtwdev,const struct rtw89_fw_mrc_sync_arg * arg)7404 int rtw89_fw_h2c_mrc_sync(struct rtw89_dev *rtwdev,
7405 const struct rtw89_fw_mrc_sync_arg *arg)
7406 {
7407 struct rtw89_h2c_mrc_sync *h2c;
7408 u32 len = sizeof(*h2c);
7409 struct sk_buff *skb;
7410 int ret;
7411
7412 skb = rtw89_fw_h2c_alloc_skb_with_hdr(rtwdev, len);
7413 if (!skb) {
7414 rtw89_err(rtwdev, "failed to alloc skb for mrc sync\n");
7415 return -ENOMEM;
7416 }
7417
7418 skb_put(skb, len);
7419 h2c = (struct rtw89_h2c_mrc_sync *)skb->data;
7420
7421 h2c->w0 = le32_encode_bits(true, RTW89_H2C_MRC_SYNC_W0_SYNC_EN) |
7422 le32_encode_bits(arg->src.port,
7423 RTW89_H2C_MRC_SYNC_W0_SRC_PORT) |
7424 le32_encode_bits(arg->src.band,
7425 RTW89_H2C_MRC_SYNC_W0_SRC_BAND) |
7426 le32_encode_bits(arg->dest.port,
7427 RTW89_H2C_MRC_SYNC_W0_DEST_PORT) |
7428 le32_encode_bits(arg->dest.band,
7429 RTW89_H2C_MRC_SYNC_W0_DEST_BAND);
7430 h2c->w1 = le32_encode_bits(arg->offset, RTW89_H2C_MRC_SYNC_W1_OFFSET);
7431
7432 rtw89_h2c_pkt_set_hdr(rtwdev, skb, FWCMD_TYPE_H2C,
7433 H2C_CAT_MAC,
7434 H2C_CL_MRC,
7435 H2C_FUNC_MRC_SYNC, 0, 0,
7436 len);
7437
7438 ret = rtw89_h2c_tx(rtwdev, skb, false);
7439 if (ret) {
7440 rtw89_err(rtwdev, "failed to send h2c\n");
7441 dev_kfree_skb_any(skb);
7442 return -EBUSY;
7443 }
7444
7445 return 0;
7446 }
7447
rtw89_fw_h2c_mrc_upd_duration(struct rtw89_dev * rtwdev,const struct rtw89_fw_mrc_upd_duration_arg * arg)7448 int rtw89_fw_h2c_mrc_upd_duration(struct rtw89_dev *rtwdev,
7449 const struct rtw89_fw_mrc_upd_duration_arg *arg)
7450 {
7451 struct rtw89_h2c_mrc_upd_duration *h2c;
7452 struct sk_buff *skb;
7453 unsigned int i;
7454 u32 len;
7455 int ret;
7456
7457 len = struct_size(h2c, slots, arg->slot_num);
7458 skb = rtw89_fw_h2c_alloc_skb_with_hdr(rtwdev, len);
7459 if (!skb) {
7460 rtw89_err(rtwdev, "failed to alloc skb for mrc upd duration\n");
7461 return -ENOMEM;
7462 }
7463
7464 skb_put(skb, len);
7465 h2c = (struct rtw89_h2c_mrc_upd_duration *)skb->data;
7466
7467 h2c->w0 = le32_encode_bits(arg->sch_idx,
7468 RTW89_H2C_MRC_UPD_DURATION_W0_SCH_IDX) |
7469 le32_encode_bits(arg->slot_num,
7470 RTW89_H2C_MRC_UPD_DURATION_W0_SLOT_NUM) |
7471 le32_encode_bits(false,
7472 RTW89_H2C_MRC_UPD_DURATION_W0_BTC_IN_SCH);
7473
7474 h2c->start_tsf_high = cpu_to_le32(arg->start_tsf >> 32);
7475 h2c->start_tsf_low = cpu_to_le32(arg->start_tsf);
7476
7477 for (i = 0; i < arg->slot_num; i++) {
7478 h2c->slots[i] =
7479 le32_encode_bits(arg->slots[i].slot_idx,
7480 RTW89_H2C_MRC_UPD_DURATION_SLOT_SLOT_IDX) |
7481 le32_encode_bits(arg->slots[i].duration,
7482 RTW89_H2C_MRC_UPD_DURATION_SLOT_DURATION);
7483 }
7484
7485 rtw89_h2c_pkt_set_hdr(rtwdev, skb, FWCMD_TYPE_H2C,
7486 H2C_CAT_MAC,
7487 H2C_CL_MRC,
7488 H2C_FUNC_MRC_UPD_DURATION, 0, 0,
7489 len);
7490
7491 ret = rtw89_h2c_tx(rtwdev, skb, false);
7492 if (ret) {
7493 rtw89_err(rtwdev, "failed to send h2c\n");
7494 dev_kfree_skb_any(skb);
7495 return -EBUSY;
7496 }
7497
7498 return 0;
7499 }
7500
__fw_txpwr_entry_zero_ext(const void * ext_ptr,u8 ext_len)7501 static bool __fw_txpwr_entry_zero_ext(const void *ext_ptr, u8 ext_len)
7502 {
7503 static const u8 zeros[U8_MAX] = {};
7504
7505 return memcmp(ext_ptr, zeros, ext_len) == 0;
7506 }
7507
7508 #define __fw_txpwr_entry_acceptable(e, cursor, ent_sz) \
7509 ({ \
7510 u8 __var_sz = sizeof(*(e)); \
7511 bool __accept; \
7512 if (__var_sz >= (ent_sz)) \
7513 __accept = true; \
7514 else \
7515 __accept = __fw_txpwr_entry_zero_ext((cursor) + __var_sz,\
7516 (ent_sz) - __var_sz);\
7517 __accept; \
7518 })
7519
7520 static bool
fw_txpwr_byrate_entry_valid(const struct rtw89_fw_txpwr_byrate_entry * e,const void * cursor,const struct rtw89_txpwr_conf * conf)7521 fw_txpwr_byrate_entry_valid(const struct rtw89_fw_txpwr_byrate_entry *e,
7522 const void *cursor,
7523 const struct rtw89_txpwr_conf *conf)
7524 {
7525 if (!__fw_txpwr_entry_acceptable(e, cursor, conf->ent_sz))
7526 return false;
7527
7528 if (e->band >= RTW89_BAND_NUM || e->bw >= RTW89_BYR_BW_NUM)
7529 return false;
7530
7531 switch (e->rs) {
7532 case RTW89_RS_CCK:
7533 if (e->shf + e->len > RTW89_RATE_CCK_NUM)
7534 return false;
7535 break;
7536 case RTW89_RS_OFDM:
7537 if (e->shf + e->len > RTW89_RATE_OFDM_NUM)
7538 return false;
7539 break;
7540 case RTW89_RS_MCS:
7541 if (e->shf + e->len > __RTW89_RATE_MCS_NUM ||
7542 e->nss >= RTW89_NSS_NUM ||
7543 e->ofdma >= RTW89_OFDMA_NUM)
7544 return false;
7545 break;
7546 case RTW89_RS_HEDCM:
7547 if (e->shf + e->len > RTW89_RATE_HEDCM_NUM ||
7548 e->nss >= RTW89_NSS_HEDCM_NUM ||
7549 e->ofdma >= RTW89_OFDMA_NUM)
7550 return false;
7551 break;
7552 case RTW89_RS_OFFSET:
7553 if (e->shf + e->len > __RTW89_RATE_OFFSET_NUM)
7554 return false;
7555 break;
7556 default:
7557 return false;
7558 }
7559
7560 return true;
7561 }
7562
7563 static
rtw89_fw_load_txpwr_byrate(struct rtw89_dev * rtwdev,const struct rtw89_txpwr_table * tbl)7564 void rtw89_fw_load_txpwr_byrate(struct rtw89_dev *rtwdev,
7565 const struct rtw89_txpwr_table *tbl)
7566 {
7567 const struct rtw89_txpwr_conf *conf = tbl->data;
7568 struct rtw89_fw_txpwr_byrate_entry entry = {};
7569 struct rtw89_txpwr_byrate *byr_head;
7570 struct rtw89_rate_desc desc = {};
7571 const void *cursor;
7572 u32 data;
7573 s8 *byr;
7574 int i;
7575
7576 rtw89_for_each_in_txpwr_conf(entry, cursor, conf) {
7577 if (!fw_txpwr_byrate_entry_valid(&entry, cursor, conf))
7578 continue;
7579
7580 byr_head = &rtwdev->byr[entry.band][entry.bw];
7581 data = le32_to_cpu(entry.data);
7582 desc.ofdma = entry.ofdma;
7583 desc.nss = entry.nss;
7584 desc.rs = entry.rs;
7585
7586 for (i = 0; i < entry.len; i++, data >>= 8) {
7587 desc.idx = entry.shf + i;
7588 byr = rtw89_phy_raw_byr_seek(rtwdev, byr_head, &desc);
7589 *byr = data & 0xff;
7590 }
7591 }
7592 }
7593
7594 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)7595 fw_txpwr_lmt_2ghz_entry_valid(const struct rtw89_fw_txpwr_lmt_2ghz_entry *e,
7596 const void *cursor,
7597 const struct rtw89_txpwr_conf *conf)
7598 {
7599 if (!__fw_txpwr_entry_acceptable(e, cursor, conf->ent_sz))
7600 return false;
7601
7602 if (e->bw >= RTW89_2G_BW_NUM)
7603 return false;
7604 if (e->nt >= RTW89_NTX_NUM)
7605 return false;
7606 if (e->rs >= RTW89_RS_LMT_NUM)
7607 return false;
7608 if (e->bf >= RTW89_BF_NUM)
7609 return false;
7610 if (e->regd >= RTW89_REGD_NUM)
7611 return false;
7612 if (e->ch_idx >= RTW89_2G_CH_NUM)
7613 return false;
7614
7615 return true;
7616 }
7617
7618 static
rtw89_fw_load_txpwr_lmt_2ghz(struct rtw89_txpwr_lmt_2ghz_data * data)7619 void rtw89_fw_load_txpwr_lmt_2ghz(struct rtw89_txpwr_lmt_2ghz_data *data)
7620 {
7621 const struct rtw89_txpwr_conf *conf = &data->conf;
7622 struct rtw89_fw_txpwr_lmt_2ghz_entry entry = {};
7623 const void *cursor;
7624
7625 rtw89_for_each_in_txpwr_conf(entry, cursor, conf) {
7626 if (!fw_txpwr_lmt_2ghz_entry_valid(&entry, cursor, conf))
7627 continue;
7628
7629 data->v[entry.bw][entry.nt][entry.rs][entry.bf][entry.regd]
7630 [entry.ch_idx] = entry.v;
7631 }
7632 }
7633
7634 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)7635 fw_txpwr_lmt_5ghz_entry_valid(const struct rtw89_fw_txpwr_lmt_5ghz_entry *e,
7636 const void *cursor,
7637 const struct rtw89_txpwr_conf *conf)
7638 {
7639 if (!__fw_txpwr_entry_acceptable(e, cursor, conf->ent_sz))
7640 return false;
7641
7642 if (e->bw >= RTW89_5G_BW_NUM)
7643 return false;
7644 if (e->nt >= RTW89_NTX_NUM)
7645 return false;
7646 if (e->rs >= RTW89_RS_LMT_NUM)
7647 return false;
7648 if (e->bf >= RTW89_BF_NUM)
7649 return false;
7650 if (e->regd >= RTW89_REGD_NUM)
7651 return false;
7652 if (e->ch_idx >= RTW89_5G_CH_NUM)
7653 return false;
7654
7655 return true;
7656 }
7657
7658 static
rtw89_fw_load_txpwr_lmt_5ghz(struct rtw89_txpwr_lmt_5ghz_data * data)7659 void rtw89_fw_load_txpwr_lmt_5ghz(struct rtw89_txpwr_lmt_5ghz_data *data)
7660 {
7661 const struct rtw89_txpwr_conf *conf = &data->conf;
7662 struct rtw89_fw_txpwr_lmt_5ghz_entry entry = {};
7663 const void *cursor;
7664
7665 rtw89_for_each_in_txpwr_conf(entry, cursor, conf) {
7666 if (!fw_txpwr_lmt_5ghz_entry_valid(&entry, cursor, conf))
7667 continue;
7668
7669 data->v[entry.bw][entry.nt][entry.rs][entry.bf][entry.regd]
7670 [entry.ch_idx] = entry.v;
7671 }
7672 }
7673
7674 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)7675 fw_txpwr_lmt_6ghz_entry_valid(const struct rtw89_fw_txpwr_lmt_6ghz_entry *e,
7676 const void *cursor,
7677 const struct rtw89_txpwr_conf *conf)
7678 {
7679 if (!__fw_txpwr_entry_acceptable(e, cursor, conf->ent_sz))
7680 return false;
7681
7682 if (e->bw >= RTW89_6G_BW_NUM)
7683 return false;
7684 if (e->nt >= RTW89_NTX_NUM)
7685 return false;
7686 if (e->rs >= RTW89_RS_LMT_NUM)
7687 return false;
7688 if (e->bf >= RTW89_BF_NUM)
7689 return false;
7690 if (e->regd >= RTW89_REGD_NUM)
7691 return false;
7692 if (e->reg_6ghz_power >= NUM_OF_RTW89_REG_6GHZ_POWER)
7693 return false;
7694 if (e->ch_idx >= RTW89_6G_CH_NUM)
7695 return false;
7696
7697 return true;
7698 }
7699
7700 static
rtw89_fw_load_txpwr_lmt_6ghz(struct rtw89_txpwr_lmt_6ghz_data * data)7701 void rtw89_fw_load_txpwr_lmt_6ghz(struct rtw89_txpwr_lmt_6ghz_data *data)
7702 {
7703 const struct rtw89_txpwr_conf *conf = &data->conf;
7704 struct rtw89_fw_txpwr_lmt_6ghz_entry entry = {};
7705 const void *cursor;
7706
7707 rtw89_for_each_in_txpwr_conf(entry, cursor, conf) {
7708 if (!fw_txpwr_lmt_6ghz_entry_valid(&entry, cursor, conf))
7709 continue;
7710
7711 data->v[entry.bw][entry.nt][entry.rs][entry.bf][entry.regd]
7712 [entry.reg_6ghz_power][entry.ch_idx] = entry.v;
7713 }
7714 }
7715
7716 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)7717 fw_txpwr_lmt_ru_2ghz_entry_valid(const struct rtw89_fw_txpwr_lmt_ru_2ghz_entry *e,
7718 const void *cursor,
7719 const struct rtw89_txpwr_conf *conf)
7720 {
7721 if (!__fw_txpwr_entry_acceptable(e, cursor, conf->ent_sz))
7722 return false;
7723
7724 if (e->ru >= RTW89_RU_NUM)
7725 return false;
7726 if (e->nt >= RTW89_NTX_NUM)
7727 return false;
7728 if (e->regd >= RTW89_REGD_NUM)
7729 return false;
7730 if (e->ch_idx >= RTW89_2G_CH_NUM)
7731 return false;
7732
7733 return true;
7734 }
7735
7736 static
rtw89_fw_load_txpwr_lmt_ru_2ghz(struct rtw89_txpwr_lmt_ru_2ghz_data * data)7737 void rtw89_fw_load_txpwr_lmt_ru_2ghz(struct rtw89_txpwr_lmt_ru_2ghz_data *data)
7738 {
7739 const struct rtw89_txpwr_conf *conf = &data->conf;
7740 struct rtw89_fw_txpwr_lmt_ru_2ghz_entry entry = {};
7741 const void *cursor;
7742
7743 rtw89_for_each_in_txpwr_conf(entry, cursor, conf) {
7744 if (!fw_txpwr_lmt_ru_2ghz_entry_valid(&entry, cursor, conf))
7745 continue;
7746
7747 data->v[entry.ru][entry.nt][entry.regd][entry.ch_idx] = entry.v;
7748 }
7749 }
7750
7751 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)7752 fw_txpwr_lmt_ru_5ghz_entry_valid(const struct rtw89_fw_txpwr_lmt_ru_5ghz_entry *e,
7753 const void *cursor,
7754 const struct rtw89_txpwr_conf *conf)
7755 {
7756 if (!__fw_txpwr_entry_acceptable(e, cursor, conf->ent_sz))
7757 return false;
7758
7759 if (e->ru >= RTW89_RU_NUM)
7760 return false;
7761 if (e->nt >= RTW89_NTX_NUM)
7762 return false;
7763 if (e->regd >= RTW89_REGD_NUM)
7764 return false;
7765 if (e->ch_idx >= RTW89_5G_CH_NUM)
7766 return false;
7767
7768 return true;
7769 }
7770
7771 static
rtw89_fw_load_txpwr_lmt_ru_5ghz(struct rtw89_txpwr_lmt_ru_5ghz_data * data)7772 void rtw89_fw_load_txpwr_lmt_ru_5ghz(struct rtw89_txpwr_lmt_ru_5ghz_data *data)
7773 {
7774 const struct rtw89_txpwr_conf *conf = &data->conf;
7775 struct rtw89_fw_txpwr_lmt_ru_5ghz_entry entry = {};
7776 const void *cursor;
7777
7778 rtw89_for_each_in_txpwr_conf(entry, cursor, conf) {
7779 if (!fw_txpwr_lmt_ru_5ghz_entry_valid(&entry, cursor, conf))
7780 continue;
7781
7782 data->v[entry.ru][entry.nt][entry.regd][entry.ch_idx] = entry.v;
7783 }
7784 }
7785
7786 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)7787 fw_txpwr_lmt_ru_6ghz_entry_valid(const struct rtw89_fw_txpwr_lmt_ru_6ghz_entry *e,
7788 const void *cursor,
7789 const struct rtw89_txpwr_conf *conf)
7790 {
7791 if (!__fw_txpwr_entry_acceptable(e, cursor, conf->ent_sz))
7792 return false;
7793
7794 if (e->ru >= RTW89_RU_NUM)
7795 return false;
7796 if (e->nt >= RTW89_NTX_NUM)
7797 return false;
7798 if (e->regd >= RTW89_REGD_NUM)
7799 return false;
7800 if (e->reg_6ghz_power >= NUM_OF_RTW89_REG_6GHZ_POWER)
7801 return false;
7802 if (e->ch_idx >= RTW89_6G_CH_NUM)
7803 return false;
7804
7805 return true;
7806 }
7807
7808 static
rtw89_fw_load_txpwr_lmt_ru_6ghz(struct rtw89_txpwr_lmt_ru_6ghz_data * data)7809 void rtw89_fw_load_txpwr_lmt_ru_6ghz(struct rtw89_txpwr_lmt_ru_6ghz_data *data)
7810 {
7811 const struct rtw89_txpwr_conf *conf = &data->conf;
7812 struct rtw89_fw_txpwr_lmt_ru_6ghz_entry entry = {};
7813 const void *cursor;
7814
7815 rtw89_for_each_in_txpwr_conf(entry, cursor, conf) {
7816 if (!fw_txpwr_lmt_ru_6ghz_entry_valid(&entry, cursor, conf))
7817 continue;
7818
7819 data->v[entry.ru][entry.nt][entry.regd][entry.reg_6ghz_power]
7820 [entry.ch_idx] = entry.v;
7821 }
7822 }
7823
7824 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)7825 fw_tx_shape_lmt_entry_valid(const struct rtw89_fw_tx_shape_lmt_entry *e,
7826 const void *cursor,
7827 const struct rtw89_txpwr_conf *conf)
7828 {
7829 if (!__fw_txpwr_entry_acceptable(e, cursor, conf->ent_sz))
7830 return false;
7831
7832 if (e->band >= RTW89_BAND_NUM)
7833 return false;
7834 if (e->tx_shape_rs >= RTW89_RS_TX_SHAPE_NUM)
7835 return false;
7836 if (e->regd >= RTW89_REGD_NUM)
7837 return false;
7838
7839 return true;
7840 }
7841
7842 static
rtw89_fw_load_tx_shape_lmt(struct rtw89_tx_shape_lmt_data * data)7843 void rtw89_fw_load_tx_shape_lmt(struct rtw89_tx_shape_lmt_data *data)
7844 {
7845 const struct rtw89_txpwr_conf *conf = &data->conf;
7846 struct rtw89_fw_tx_shape_lmt_entry entry = {};
7847 const void *cursor;
7848
7849 rtw89_for_each_in_txpwr_conf(entry, cursor, conf) {
7850 if (!fw_tx_shape_lmt_entry_valid(&entry, cursor, conf))
7851 continue;
7852
7853 data->v[entry.band][entry.tx_shape_rs][entry.regd] = entry.v;
7854 }
7855 }
7856
7857 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)7858 fw_tx_shape_lmt_ru_entry_valid(const struct rtw89_fw_tx_shape_lmt_ru_entry *e,
7859 const void *cursor,
7860 const struct rtw89_txpwr_conf *conf)
7861 {
7862 if (!__fw_txpwr_entry_acceptable(e, cursor, conf->ent_sz))
7863 return false;
7864
7865 if (e->band >= RTW89_BAND_NUM)
7866 return false;
7867 if (e->regd >= RTW89_REGD_NUM)
7868 return false;
7869
7870 return true;
7871 }
7872
7873 static
rtw89_fw_load_tx_shape_lmt_ru(struct rtw89_tx_shape_lmt_ru_data * data)7874 void rtw89_fw_load_tx_shape_lmt_ru(struct rtw89_tx_shape_lmt_ru_data *data)
7875 {
7876 const struct rtw89_txpwr_conf *conf = &data->conf;
7877 struct rtw89_fw_tx_shape_lmt_ru_entry entry = {};
7878 const void *cursor;
7879
7880 rtw89_for_each_in_txpwr_conf(entry, cursor, conf) {
7881 if (!fw_tx_shape_lmt_ru_entry_valid(&entry, cursor, conf))
7882 continue;
7883
7884 data->v[entry.band][entry.regd] = entry.v;
7885 }
7886 }
7887
7888 const struct rtw89_rfe_parms *
rtw89_load_rfe_data_from_fw(struct rtw89_dev * rtwdev,const struct rtw89_rfe_parms * init)7889 rtw89_load_rfe_data_from_fw(struct rtw89_dev *rtwdev,
7890 const struct rtw89_rfe_parms *init)
7891 {
7892 struct rtw89_rfe_data *rfe_data = rtwdev->rfe_data;
7893 struct rtw89_rfe_parms *parms;
7894
7895 if (!rfe_data)
7896 return init;
7897
7898 parms = &rfe_data->rfe_parms;
7899 if (init)
7900 *parms = *init;
7901
7902 if (rtw89_txpwr_conf_valid(&rfe_data->byrate.conf)) {
7903 rfe_data->byrate.tbl.data = &rfe_data->byrate.conf;
7904 rfe_data->byrate.tbl.size = 0; /* don't care here */
7905 rfe_data->byrate.tbl.load = rtw89_fw_load_txpwr_byrate;
7906 parms->byr_tbl = &rfe_data->byrate.tbl;
7907 }
7908
7909 if (rtw89_txpwr_conf_valid(&rfe_data->lmt_2ghz.conf)) {
7910 rtw89_fw_load_txpwr_lmt_2ghz(&rfe_data->lmt_2ghz);
7911 parms->rule_2ghz.lmt = &rfe_data->lmt_2ghz.v;
7912 }
7913
7914 if (rtw89_txpwr_conf_valid(&rfe_data->lmt_5ghz.conf)) {
7915 rtw89_fw_load_txpwr_lmt_5ghz(&rfe_data->lmt_5ghz);
7916 parms->rule_5ghz.lmt = &rfe_data->lmt_5ghz.v;
7917 }
7918
7919 if (rtw89_txpwr_conf_valid(&rfe_data->lmt_6ghz.conf)) {
7920 rtw89_fw_load_txpwr_lmt_6ghz(&rfe_data->lmt_6ghz);
7921 parms->rule_6ghz.lmt = &rfe_data->lmt_6ghz.v;
7922 }
7923
7924 if (rtw89_txpwr_conf_valid(&rfe_data->lmt_ru_2ghz.conf)) {
7925 rtw89_fw_load_txpwr_lmt_ru_2ghz(&rfe_data->lmt_ru_2ghz);
7926 parms->rule_2ghz.lmt_ru = &rfe_data->lmt_ru_2ghz.v;
7927 }
7928
7929 if (rtw89_txpwr_conf_valid(&rfe_data->lmt_ru_5ghz.conf)) {
7930 rtw89_fw_load_txpwr_lmt_ru_5ghz(&rfe_data->lmt_ru_5ghz);
7931 parms->rule_5ghz.lmt_ru = &rfe_data->lmt_ru_5ghz.v;
7932 }
7933
7934 if (rtw89_txpwr_conf_valid(&rfe_data->lmt_ru_6ghz.conf)) {
7935 rtw89_fw_load_txpwr_lmt_ru_6ghz(&rfe_data->lmt_ru_6ghz);
7936 parms->rule_6ghz.lmt_ru = &rfe_data->lmt_ru_6ghz.v;
7937 }
7938
7939 if (rtw89_txpwr_conf_valid(&rfe_data->tx_shape_lmt.conf)) {
7940 rtw89_fw_load_tx_shape_lmt(&rfe_data->tx_shape_lmt);
7941 parms->tx_shape.lmt = &rfe_data->tx_shape_lmt.v;
7942 }
7943
7944 if (rtw89_txpwr_conf_valid(&rfe_data->tx_shape_lmt_ru.conf)) {
7945 rtw89_fw_load_tx_shape_lmt_ru(&rfe_data->tx_shape_lmt_ru);
7946 parms->tx_shape.lmt_ru = &rfe_data->tx_shape_lmt_ru.v;
7947 }
7948
7949 return parms;
7950 }
7951