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