xref: /linux/drivers/net/wireless/realtek/rtw89/fw.c (revision 57f273adbcd44172cbe0bd10b8b7408dd255699f)
1 // SPDX-License-Identifier: GPL-2.0 OR BSD-3-Clause
2 /* Copyright(c) 2019-2020  Realtek Corporation
3  */
4 
5 #include "cam.h"
6 #include "chan.h"
7 #include "coex.h"
8 #include "debug.h"
9 #include "fw.h"
10 #include "mac.h"
11 #include "phy.h"
12 #include "reg.h"
13 
14 static struct sk_buff *rtw89_fw_h2c_alloc_skb(struct rtw89_dev *rtwdev, u32 len,
15 					      bool header)
16 {
17 	struct sk_buff *skb;
18 	u32 header_len = 0;
19 	u32 h2c_desc_size = rtwdev->chip->h2c_desc_size;
20 
21 	if (header)
22 		header_len = H2C_HEADER_LEN;
23 
24 	skb = dev_alloc_skb(len + header_len + h2c_desc_size);
25 	if (!skb)
26 		return NULL;
27 	skb_reserve(skb, header_len + h2c_desc_size);
28 	memset(skb->data, 0, len);
29 
30 	return skb;
31 }
32 
33 struct sk_buff *rtw89_fw_h2c_alloc_skb_with_hdr(struct rtw89_dev *rtwdev, u32 len)
34 {
35 	return rtw89_fw_h2c_alloc_skb(rtwdev, len, true);
36 }
37 
38 struct sk_buff *rtw89_fw_h2c_alloc_skb_no_hdr(struct rtw89_dev *rtwdev, u32 len)
39 {
40 	return rtw89_fw_h2c_alloc_skb(rtwdev, len, false);
41 }
42 
43 static u8 _fw_get_rdy(struct rtw89_dev *rtwdev)
44 {
45 	u8 val = rtw89_read8(rtwdev, R_AX_WCPU_FW_CTRL);
46 
47 	return FIELD_GET(B_AX_WCPU_FWDL_STS_MASK, val);
48 }
49 
50 #define FWDL_WAIT_CNT 400000
51 int rtw89_fw_check_rdy(struct rtw89_dev *rtwdev)
52 {
53 	u8 val;
54 	int ret;
55 
56 	ret = read_poll_timeout_atomic(_fw_get_rdy, val,
57 				       val == RTW89_FWDL_WCPU_FW_INIT_RDY,
58 				       1, FWDL_WAIT_CNT, false, rtwdev);
59 	if (ret) {
60 		switch (val) {
61 		case RTW89_FWDL_CHECKSUM_FAIL:
62 			rtw89_err(rtwdev, "fw checksum fail\n");
63 			return -EINVAL;
64 
65 		case RTW89_FWDL_SECURITY_FAIL:
66 			rtw89_err(rtwdev, "fw security fail\n");
67 			return -EINVAL;
68 
69 		case RTW89_FWDL_CV_NOT_MATCH:
70 			rtw89_err(rtwdev, "fw cv not match\n");
71 			return -EINVAL;
72 
73 		default:
74 			return -EBUSY;
75 		}
76 	}
77 
78 	set_bit(RTW89_FLAG_FW_RDY, rtwdev->flags);
79 
80 	return 0;
81 }
82 
83 static int rtw89_fw_hdr_parser(struct rtw89_dev *rtwdev, const u8 *fw, u32 len,
84 			       struct rtw89_fw_bin_info *info)
85 {
86 	struct rtw89_fw_hdr_section_info *section_info;
87 	const u8 *fw_end = fw + len;
88 	const u8 *fwdynhdr;
89 	const u8 *bin;
90 	u32 base_hdr_len;
91 	u32 i;
92 
93 	if (!info)
94 		return -EINVAL;
95 
96 	info->section_num = GET_FW_HDR_SEC_NUM(fw);
97 	base_hdr_len = RTW89_FW_HDR_SIZE +
98 		       info->section_num * RTW89_FW_SECTION_HDR_SIZE;
99 	info->dynamic_hdr_en = GET_FW_HDR_DYN_HDR(fw);
100 
101 	if (info->dynamic_hdr_en) {
102 		info->hdr_len = GET_FW_HDR_LEN(fw);
103 		info->dynamic_hdr_len = info->hdr_len - base_hdr_len;
104 		fwdynhdr = fw + base_hdr_len;
105 		if (GET_FW_DYNHDR_LEN(fwdynhdr) != info->dynamic_hdr_len) {
106 			rtw89_err(rtwdev, "[ERR]invalid fw dynamic header len\n");
107 			return -EINVAL;
108 		}
109 	} else {
110 		info->hdr_len = base_hdr_len;
111 		info->dynamic_hdr_len = 0;
112 	}
113 
114 	bin = fw + info->hdr_len;
115 
116 	/* jump to section header */
117 	fw += RTW89_FW_HDR_SIZE;
118 	section_info = info->section_info;
119 	for (i = 0; i < info->section_num; i++) {
120 		section_info->len = GET_FWSECTION_HDR_SEC_SIZE(fw);
121 		if (GET_FWSECTION_HDR_CHECKSUM(fw))
122 			section_info->len += FWDL_SECTION_CHKSUM_LEN;
123 		section_info->redl = GET_FWSECTION_HDR_REDL(fw);
124 		section_info->dladdr =
125 				GET_FWSECTION_HDR_DL_ADDR(fw) & 0x1fffffff;
126 		section_info->addr = bin;
127 		bin += section_info->len;
128 		fw += RTW89_FW_SECTION_HDR_SIZE;
129 		section_info++;
130 	}
131 
132 	if (fw_end != bin) {
133 		rtw89_err(rtwdev, "[ERR]fw bin size\n");
134 		return -EINVAL;
135 	}
136 
137 	return 0;
138 }
139 
140 static
141 int rtw89_mfw_recognize(struct rtw89_dev *rtwdev, enum rtw89_fw_type type,
142 			struct rtw89_fw_suit *fw_suit)
143 {
144 	struct rtw89_fw_info *fw_info = &rtwdev->fw;
145 	const u8 *mfw = fw_info->firmware->data;
146 	u32 mfw_len = fw_info->firmware->size;
147 	const struct rtw89_mfw_hdr *mfw_hdr = (const struct rtw89_mfw_hdr *)mfw;
148 	const struct rtw89_mfw_info *mfw_info;
149 	int i;
150 
151 	if (mfw_hdr->sig != RTW89_MFW_SIG) {
152 		rtw89_debug(rtwdev, RTW89_DBG_FW, "use legacy firmware\n");
153 		/* legacy firmware support normal type only */
154 		if (type != RTW89_FW_NORMAL)
155 			return -EINVAL;
156 		fw_suit->data = mfw;
157 		fw_suit->size = mfw_len;
158 		return 0;
159 	}
160 
161 	for (i = 0; i < mfw_hdr->fw_nr; i++) {
162 		mfw_info = &mfw_hdr->info[i];
163 		if (mfw_info->cv != rtwdev->hal.cv ||
164 		    mfw_info->type != type ||
165 		    mfw_info->mp)
166 			continue;
167 
168 		fw_suit->data = mfw + le32_to_cpu(mfw_info->shift);
169 		fw_suit->size = le32_to_cpu(mfw_info->size);
170 		return 0;
171 	}
172 
173 	rtw89_err(rtwdev, "no suitable firmware found\n");
174 	return -ENOENT;
175 }
176 
177 static void rtw89_fw_update_ver(struct rtw89_dev *rtwdev,
178 				enum rtw89_fw_type type,
179 				struct rtw89_fw_suit *fw_suit)
180 {
181 	const u8 *hdr = fw_suit->data;
182 
183 	fw_suit->major_ver = GET_FW_HDR_MAJOR_VERSION(hdr);
184 	fw_suit->minor_ver = GET_FW_HDR_MINOR_VERSION(hdr);
185 	fw_suit->sub_ver = GET_FW_HDR_SUBVERSION(hdr);
186 	fw_suit->sub_idex = GET_FW_HDR_SUBINDEX(hdr);
187 	fw_suit->build_year = GET_FW_HDR_YEAR(hdr);
188 	fw_suit->build_mon = GET_FW_HDR_MONTH(hdr);
189 	fw_suit->build_date = GET_FW_HDR_DATE(hdr);
190 	fw_suit->build_hour = GET_FW_HDR_HOUR(hdr);
191 	fw_suit->build_min = GET_FW_HDR_MIN(hdr);
192 	fw_suit->cmd_ver = GET_FW_HDR_CMD_VERSERION(hdr);
193 
194 	rtw89_info(rtwdev,
195 		   "Firmware version %u.%u.%u.%u, cmd version %u, type %u\n",
196 		   fw_suit->major_ver, fw_suit->minor_ver, fw_suit->sub_ver,
197 		   fw_suit->sub_idex, fw_suit->cmd_ver, type);
198 }
199 
200 static
201 int __rtw89_fw_recognize(struct rtw89_dev *rtwdev, enum rtw89_fw_type type)
202 {
203 	struct rtw89_fw_suit *fw_suit = rtw89_fw_suit_get(rtwdev, type);
204 	int ret;
205 
206 	ret = rtw89_mfw_recognize(rtwdev, type, fw_suit);
207 	if (ret)
208 		return ret;
209 
210 	rtw89_fw_update_ver(rtwdev, type, fw_suit);
211 
212 	return 0;
213 }
214 
215 #define __DEF_FW_FEAT_COND(__cond, __op) \
216 static bool __fw_feat_cond_ ## __cond(u32 suit_ver_code, u32 comp_ver_code) \
217 { \
218 	return suit_ver_code __op comp_ver_code; \
219 }
220 
221 __DEF_FW_FEAT_COND(ge, >=); /* greater or equal */
222 __DEF_FW_FEAT_COND(le, <=); /* less or equal */
223 
224 struct __fw_feat_cfg {
225 	enum rtw89_core_chip_id chip_id;
226 	enum rtw89_fw_feature feature;
227 	u32 ver_code;
228 	bool (*cond)(u32 suit_ver_code, u32 comp_ver_code);
229 };
230 
231 #define __CFG_FW_FEAT(_chip, _cond, _maj, _min, _sub, _idx, _feat) \
232 	{ \
233 		.chip_id = _chip, \
234 		.feature = RTW89_FW_FEATURE_ ## _feat, \
235 		.ver_code = RTW89_FW_VER_CODE(_maj, _min, _sub, _idx), \
236 		.cond = __fw_feat_cond_ ## _cond, \
237 	}
238 
239 static const struct __fw_feat_cfg fw_feat_tbl[] = {
240 	__CFG_FW_FEAT(RTL8852A, le, 0, 13, 29, 0, OLD_HT_RA_FORMAT),
241 	__CFG_FW_FEAT(RTL8852A, ge, 0, 13, 35, 0, SCAN_OFFLOAD),
242 	__CFG_FW_FEAT(RTL8852A, ge, 0, 13, 35, 0, TX_WAKE),
243 	__CFG_FW_FEAT(RTL8852A, ge, 0, 13, 36, 0, CRASH_TRIGGER),
244 	__CFG_FW_FEAT(RTL8852A, ge, 0, 13, 38, 0, PACKET_DROP),
245 	__CFG_FW_FEAT(RTL8852C, ge, 0, 27, 20, 0, PACKET_DROP),
246 	__CFG_FW_FEAT(RTL8852C, le, 0, 27, 33, 0, NO_DEEP_PS),
247 	__CFG_FW_FEAT(RTL8852C, ge, 0, 27, 34, 0, TX_WAKE),
248 	__CFG_FW_FEAT(RTL8852C, ge, 0, 27, 36, 0, SCAN_OFFLOAD),
249 	__CFG_FW_FEAT(RTL8852C, ge, 0, 27, 40, 0, CRASH_TRIGGER),
250 };
251 
252 static void rtw89_fw_recognize_features(struct rtw89_dev *rtwdev)
253 {
254 	const struct rtw89_chip_info *chip = rtwdev->chip;
255 	const struct __fw_feat_cfg *ent;
256 	const struct rtw89_fw_suit *fw_suit;
257 	u32 suit_ver_code;
258 	int i;
259 
260 	fw_suit = rtw89_fw_suit_get(rtwdev, RTW89_FW_NORMAL);
261 	suit_ver_code = RTW89_FW_SUIT_VER_CODE(fw_suit);
262 
263 	for (i = 0; i < ARRAY_SIZE(fw_feat_tbl); i++) {
264 		ent = &fw_feat_tbl[i];
265 		if (chip->chip_id != ent->chip_id)
266 			continue;
267 
268 		if (ent->cond(suit_ver_code, ent->ver_code))
269 			RTW89_SET_FW_FEATURE(ent->feature, &rtwdev->fw);
270 	}
271 }
272 
273 void rtw89_early_fw_feature_recognize(struct device *device,
274 				      const struct rtw89_chip_info *chip,
275 				      u32 *early_feat_map)
276 {
277 	union {
278 		struct rtw89_mfw_hdr mfw_hdr;
279 		u8 fw_hdr[RTW89_FW_HDR_SIZE];
280 	} buf = {};
281 	const struct firmware *firmware;
282 	u32 ver_code;
283 	int ret;
284 	int i;
285 
286 	ret = request_partial_firmware_into_buf(&firmware, chip->fw_name,
287 						device, &buf, sizeof(buf), 0);
288 	if (ret) {
289 		dev_err(device, "failed to early request firmware: %d\n", ret);
290 		return;
291 	}
292 
293 	ver_code = buf.mfw_hdr.sig != RTW89_MFW_SIG ?
294 		   RTW89_FW_HDR_VER_CODE(&buf.fw_hdr) :
295 		   RTW89_MFW_HDR_VER_CODE(&buf.mfw_hdr);
296 	if (!ver_code)
297 		goto out;
298 
299 	for (i = 0; i < ARRAY_SIZE(fw_feat_tbl); i++) {
300 		const struct __fw_feat_cfg *ent = &fw_feat_tbl[i];
301 
302 		if (chip->chip_id != ent->chip_id)
303 			continue;
304 
305 		if (ent->cond(ver_code, ent->ver_code))
306 			*early_feat_map |= BIT(ent->feature);
307 	}
308 
309 out:
310 	release_firmware(firmware);
311 }
312 
313 int rtw89_fw_recognize(struct rtw89_dev *rtwdev)
314 {
315 	int ret;
316 
317 	ret = __rtw89_fw_recognize(rtwdev, RTW89_FW_NORMAL);
318 	if (ret)
319 		return ret;
320 
321 	/* It still works if wowlan firmware isn't existing. */
322 	__rtw89_fw_recognize(rtwdev, RTW89_FW_WOWLAN);
323 
324 	rtw89_fw_recognize_features(rtwdev);
325 
326 	return 0;
327 }
328 
329 void rtw89_h2c_pkt_set_hdr(struct rtw89_dev *rtwdev, struct sk_buff *skb,
330 			   u8 type, u8 cat, u8 class, u8 func,
331 			   bool rack, bool dack, u32 len)
332 {
333 	struct fwcmd_hdr *hdr;
334 
335 	hdr = (struct fwcmd_hdr *)skb_push(skb, 8);
336 
337 	if (!(rtwdev->fw.h2c_seq % 4))
338 		rack = true;
339 	hdr->hdr0 = cpu_to_le32(FIELD_PREP(H2C_HDR_DEL_TYPE, type) |
340 				FIELD_PREP(H2C_HDR_CAT, cat) |
341 				FIELD_PREP(H2C_HDR_CLASS, class) |
342 				FIELD_PREP(H2C_HDR_FUNC, func) |
343 				FIELD_PREP(H2C_HDR_H2C_SEQ, rtwdev->fw.h2c_seq));
344 
345 	hdr->hdr1 = cpu_to_le32(FIELD_PREP(H2C_HDR_TOTAL_LEN,
346 					   len + H2C_HEADER_LEN) |
347 				(rack ? H2C_HDR_REC_ACK : 0) |
348 				(dack ? H2C_HDR_DONE_ACK : 0));
349 
350 	rtwdev->fw.h2c_seq++;
351 }
352 
353 static void rtw89_h2c_pkt_set_hdr_fwdl(struct rtw89_dev *rtwdev,
354 				       struct sk_buff *skb,
355 				       u8 type, u8 cat, u8 class, u8 func,
356 				       u32 len)
357 {
358 	struct fwcmd_hdr *hdr;
359 
360 	hdr = (struct fwcmd_hdr *)skb_push(skb, 8);
361 
362 	hdr->hdr0 = cpu_to_le32(FIELD_PREP(H2C_HDR_DEL_TYPE, type) |
363 				FIELD_PREP(H2C_HDR_CAT, cat) |
364 				FIELD_PREP(H2C_HDR_CLASS, class) |
365 				FIELD_PREP(H2C_HDR_FUNC, func) |
366 				FIELD_PREP(H2C_HDR_H2C_SEQ, rtwdev->fw.h2c_seq));
367 
368 	hdr->hdr1 = cpu_to_le32(FIELD_PREP(H2C_HDR_TOTAL_LEN,
369 					   len + H2C_HEADER_LEN));
370 }
371 
372 static int __rtw89_fw_download_hdr(struct rtw89_dev *rtwdev, const u8 *fw, u32 len)
373 {
374 	struct sk_buff *skb;
375 	u32 ret = 0;
376 
377 	skb = rtw89_fw_h2c_alloc_skb_with_hdr(rtwdev, len);
378 	if (!skb) {
379 		rtw89_err(rtwdev, "failed to alloc skb for fw hdr dl\n");
380 		return -ENOMEM;
381 	}
382 
383 	skb_put_data(skb, fw, len);
384 	SET_FW_HDR_PART_SIZE(skb->data, FWDL_SECTION_PER_PKT_LEN);
385 	rtw89_h2c_pkt_set_hdr_fwdl(rtwdev, skb, FWCMD_TYPE_H2C,
386 				   H2C_CAT_MAC, H2C_CL_MAC_FWDL,
387 				   H2C_FUNC_MAC_FWHDR_DL, len);
388 
389 	ret = rtw89_h2c_tx(rtwdev, skb, false);
390 	if (ret) {
391 		rtw89_err(rtwdev, "failed to send h2c\n");
392 		ret = -1;
393 		goto fail;
394 	}
395 
396 	return 0;
397 fail:
398 	dev_kfree_skb_any(skb);
399 
400 	return ret;
401 }
402 
403 static int rtw89_fw_download_hdr(struct rtw89_dev *rtwdev, const u8 *fw, u32 len)
404 {
405 	u8 val;
406 	int ret;
407 
408 	ret = __rtw89_fw_download_hdr(rtwdev, fw, len);
409 	if (ret) {
410 		rtw89_err(rtwdev, "[ERR]FW header download\n");
411 		return ret;
412 	}
413 
414 	ret = read_poll_timeout_atomic(rtw89_read8, val, val & B_AX_FWDL_PATH_RDY,
415 				       1, FWDL_WAIT_CNT, false,
416 				       rtwdev, R_AX_WCPU_FW_CTRL);
417 	if (ret) {
418 		rtw89_err(rtwdev, "[ERR]FWDL path ready\n");
419 		return ret;
420 	}
421 
422 	rtw89_write32(rtwdev, R_AX_HALT_H2C_CTRL, 0);
423 	rtw89_write32(rtwdev, R_AX_HALT_C2H_CTRL, 0);
424 
425 	return 0;
426 }
427 
428 static int __rtw89_fw_download_main(struct rtw89_dev *rtwdev,
429 				    struct rtw89_fw_hdr_section_info *info)
430 {
431 	struct sk_buff *skb;
432 	const u8 *section = info->addr;
433 	u32 residue_len = info->len;
434 	u32 pkt_len;
435 	int ret;
436 
437 	while (residue_len) {
438 		if (residue_len >= FWDL_SECTION_PER_PKT_LEN)
439 			pkt_len = FWDL_SECTION_PER_PKT_LEN;
440 		else
441 			pkt_len = residue_len;
442 
443 		skb = rtw89_fw_h2c_alloc_skb_no_hdr(rtwdev, pkt_len);
444 		if (!skb) {
445 			rtw89_err(rtwdev, "failed to alloc skb for fw dl\n");
446 			return -ENOMEM;
447 		}
448 		skb_put_data(skb, section, pkt_len);
449 
450 		ret = rtw89_h2c_tx(rtwdev, skb, true);
451 		if (ret) {
452 			rtw89_err(rtwdev, "failed to send h2c\n");
453 			ret = -1;
454 			goto fail;
455 		}
456 
457 		section += pkt_len;
458 		residue_len -= pkt_len;
459 	}
460 
461 	return 0;
462 fail:
463 	dev_kfree_skb_any(skb);
464 
465 	return ret;
466 }
467 
468 static int rtw89_fw_download_main(struct rtw89_dev *rtwdev, const u8 *fw,
469 				  struct rtw89_fw_bin_info *info)
470 {
471 	struct rtw89_fw_hdr_section_info *section_info = info->section_info;
472 	u8 section_num = info->section_num;
473 	int ret;
474 
475 	while (section_num--) {
476 		ret = __rtw89_fw_download_main(rtwdev, section_info);
477 		if (ret)
478 			return ret;
479 		section_info++;
480 	}
481 
482 	mdelay(5);
483 
484 	ret = rtw89_fw_check_rdy(rtwdev);
485 	if (ret) {
486 		rtw89_warn(rtwdev, "download firmware fail\n");
487 		return ret;
488 	}
489 
490 	return 0;
491 }
492 
493 static void rtw89_fw_prog_cnt_dump(struct rtw89_dev *rtwdev)
494 {
495 	u32 val32;
496 	u16 index;
497 
498 	rtw89_write32(rtwdev, R_AX_DBG_CTRL,
499 		      FIELD_PREP(B_AX_DBG_SEL0, FW_PROG_CNTR_DBG_SEL) |
500 		      FIELD_PREP(B_AX_DBG_SEL1, FW_PROG_CNTR_DBG_SEL));
501 	rtw89_write32_mask(rtwdev, R_AX_SYS_STATUS1, B_AX_SEL_0XC0_MASK, MAC_DBG_SEL);
502 
503 	for (index = 0; index < 15; index++) {
504 		val32 = rtw89_read32(rtwdev, R_AX_DBG_PORT_SEL);
505 		rtw89_err(rtwdev, "[ERR]fw PC = 0x%x\n", val32);
506 		fsleep(10);
507 	}
508 }
509 
510 static void rtw89_fw_dl_fail_dump(struct rtw89_dev *rtwdev)
511 {
512 	u32 val32;
513 	u16 val16;
514 
515 	val32 = rtw89_read32(rtwdev, R_AX_WCPU_FW_CTRL);
516 	rtw89_err(rtwdev, "[ERR]fwdl 0x1E0 = 0x%x\n", val32);
517 
518 	val16 = rtw89_read16(rtwdev, R_AX_BOOT_DBG + 2);
519 	rtw89_err(rtwdev, "[ERR]fwdl 0x83F2 = 0x%x\n", val16);
520 
521 	rtw89_fw_prog_cnt_dump(rtwdev);
522 }
523 
524 int rtw89_fw_download(struct rtw89_dev *rtwdev, enum rtw89_fw_type type)
525 {
526 	struct rtw89_fw_info *fw_info = &rtwdev->fw;
527 	struct rtw89_fw_suit *fw_suit = rtw89_fw_suit_get(rtwdev, type);
528 	struct rtw89_fw_bin_info info;
529 	const u8 *fw = fw_suit->data;
530 	u32 len = fw_suit->size;
531 	u8 val;
532 	int ret;
533 
534 	rtw89_mac_disable_cpu(rtwdev);
535 	ret = rtw89_mac_enable_cpu(rtwdev, 0, true);
536 	if (ret)
537 		return ret;
538 
539 	if (!fw || !len) {
540 		rtw89_err(rtwdev, "fw type %d isn't recognized\n", type);
541 		return -ENOENT;
542 	}
543 
544 	ret = rtw89_fw_hdr_parser(rtwdev, fw, len, &info);
545 	if (ret) {
546 		rtw89_err(rtwdev, "parse fw header fail\n");
547 		goto fwdl_err;
548 	}
549 
550 	ret = read_poll_timeout_atomic(rtw89_read8, val, val & B_AX_H2C_PATH_RDY,
551 				       1, FWDL_WAIT_CNT, false,
552 				       rtwdev, R_AX_WCPU_FW_CTRL);
553 	if (ret) {
554 		rtw89_err(rtwdev, "[ERR]H2C path ready\n");
555 		goto fwdl_err;
556 	}
557 
558 	ret = rtw89_fw_download_hdr(rtwdev, fw, info.hdr_len - info.dynamic_hdr_len);
559 	if (ret) {
560 		ret = -EBUSY;
561 		goto fwdl_err;
562 	}
563 
564 	ret = rtw89_fw_download_main(rtwdev, fw, &info);
565 	if (ret) {
566 		ret = -EBUSY;
567 		goto fwdl_err;
568 	}
569 
570 	fw_info->h2c_seq = 0;
571 	fw_info->rec_seq = 0;
572 	rtwdev->mac.rpwm_seq_num = RPWM_SEQ_NUM_MAX;
573 	rtwdev->mac.cpwm_seq_num = CPWM_SEQ_NUM_MAX;
574 
575 	return ret;
576 
577 fwdl_err:
578 	rtw89_fw_dl_fail_dump(rtwdev);
579 	return ret;
580 }
581 
582 int rtw89_wait_firmware_completion(struct rtw89_dev *rtwdev)
583 {
584 	struct rtw89_fw_info *fw = &rtwdev->fw;
585 
586 	wait_for_completion(&fw->completion);
587 	if (!fw->firmware)
588 		return -EINVAL;
589 
590 	return 0;
591 }
592 
593 static void rtw89_load_firmware_cb(const struct firmware *firmware, void *context)
594 {
595 	struct rtw89_fw_info *fw = context;
596 	struct rtw89_dev *rtwdev = fw->rtwdev;
597 
598 	if (!firmware || !firmware->data) {
599 		rtw89_err(rtwdev, "failed to request firmware\n");
600 		complete_all(&fw->completion);
601 		return;
602 	}
603 
604 	fw->firmware = firmware;
605 	complete_all(&fw->completion);
606 }
607 
608 int rtw89_load_firmware(struct rtw89_dev *rtwdev)
609 {
610 	struct rtw89_fw_info *fw = &rtwdev->fw;
611 	const char *fw_name = rtwdev->chip->fw_name;
612 	int ret;
613 
614 	fw->rtwdev = rtwdev;
615 	init_completion(&fw->completion);
616 
617 	ret = request_firmware_nowait(THIS_MODULE, true, fw_name, rtwdev->dev,
618 				      GFP_KERNEL, fw, rtw89_load_firmware_cb);
619 	if (ret) {
620 		rtw89_err(rtwdev, "failed to async firmware request\n");
621 		return ret;
622 	}
623 
624 	return 0;
625 }
626 
627 void rtw89_unload_firmware(struct rtw89_dev *rtwdev)
628 {
629 	struct rtw89_fw_info *fw = &rtwdev->fw;
630 
631 	rtw89_wait_firmware_completion(rtwdev);
632 
633 	if (fw->firmware)
634 		release_firmware(fw->firmware);
635 }
636 
637 #define H2C_CAM_LEN 60
638 int rtw89_fw_h2c_cam(struct rtw89_dev *rtwdev, struct rtw89_vif *rtwvif,
639 		     struct rtw89_sta *rtwsta, const u8 *scan_mac_addr)
640 {
641 	struct sk_buff *skb;
642 	int ret;
643 
644 	skb = rtw89_fw_h2c_alloc_skb_with_hdr(rtwdev, H2C_CAM_LEN);
645 	if (!skb) {
646 		rtw89_err(rtwdev, "failed to alloc skb for fw dl\n");
647 		return -ENOMEM;
648 	}
649 	skb_put(skb, H2C_CAM_LEN);
650 	rtw89_cam_fill_addr_cam_info(rtwdev, rtwvif, rtwsta, scan_mac_addr, skb->data);
651 	rtw89_cam_fill_bssid_cam_info(rtwdev, rtwvif, rtwsta, skb->data);
652 
653 	rtw89_h2c_pkt_set_hdr(rtwdev, skb, FWCMD_TYPE_H2C,
654 			      H2C_CAT_MAC,
655 			      H2C_CL_MAC_ADDR_CAM_UPDATE,
656 			      H2C_FUNC_MAC_ADDR_CAM_UPD, 0, 1,
657 			      H2C_CAM_LEN);
658 
659 	ret = rtw89_h2c_tx(rtwdev, skb, false);
660 	if (ret) {
661 		rtw89_err(rtwdev, "failed to send h2c\n");
662 		goto fail;
663 	}
664 
665 	return 0;
666 fail:
667 	dev_kfree_skb_any(skb);
668 
669 	return ret;
670 }
671 
672 #define H2C_DCTL_SEC_CAM_LEN 68
673 int rtw89_fw_h2c_dctl_sec_cam_v1(struct rtw89_dev *rtwdev,
674 				 struct rtw89_vif *rtwvif,
675 				 struct rtw89_sta *rtwsta)
676 {
677 	struct sk_buff *skb;
678 	int ret;
679 
680 	skb = rtw89_fw_h2c_alloc_skb_with_hdr(rtwdev, H2C_DCTL_SEC_CAM_LEN);
681 	if (!skb) {
682 		rtw89_err(rtwdev, "failed to alloc skb for dctl sec cam\n");
683 		return -ENOMEM;
684 	}
685 	skb_put(skb, H2C_DCTL_SEC_CAM_LEN);
686 
687 	rtw89_cam_fill_dctl_sec_cam_info_v1(rtwdev, rtwvif, rtwsta, skb->data);
688 
689 	rtw89_h2c_pkt_set_hdr(rtwdev, skb, FWCMD_TYPE_H2C,
690 			      H2C_CAT_MAC,
691 			      H2C_CL_MAC_FR_EXCHG,
692 			      H2C_FUNC_MAC_DCTLINFO_UD_V1, 0, 0,
693 			      H2C_DCTL_SEC_CAM_LEN);
694 
695 	ret = rtw89_h2c_tx(rtwdev, skb, false);
696 	if (ret) {
697 		rtw89_err(rtwdev, "failed to send h2c\n");
698 		goto fail;
699 	}
700 
701 	return 0;
702 fail:
703 	dev_kfree_skb_any(skb);
704 
705 	return ret;
706 }
707 EXPORT_SYMBOL(rtw89_fw_h2c_dctl_sec_cam_v1);
708 
709 #define H2C_BA_CAM_LEN 8
710 int rtw89_fw_h2c_ba_cam(struct rtw89_dev *rtwdev, struct rtw89_sta *rtwsta,
711 			bool valid, struct ieee80211_ampdu_params *params)
712 {
713 	const struct rtw89_chip_info *chip = rtwdev->chip;
714 	struct rtw89_vif *rtwvif = rtwsta->rtwvif;
715 	u8 macid = rtwsta->mac_id;
716 	struct sk_buff *skb;
717 	u8 entry_idx;
718 	int ret;
719 
720 	ret = valid ?
721 	      rtw89_core_acquire_sta_ba_entry(rtwdev, rtwsta, params->tid, &entry_idx) :
722 	      rtw89_core_release_sta_ba_entry(rtwdev, rtwsta, params->tid, &entry_idx);
723 	if (ret) {
724 		/* it still works even if we don't have static BA CAM, because
725 		 * hardware can create dynamic BA CAM automatically.
726 		 */
727 		rtw89_debug(rtwdev, RTW89_DBG_TXRX,
728 			    "failed to %s entry tid=%d for h2c ba cam\n",
729 			    valid ? "alloc" : "free", params->tid);
730 		return 0;
731 	}
732 
733 	skb = rtw89_fw_h2c_alloc_skb_with_hdr(rtwdev, H2C_BA_CAM_LEN);
734 	if (!skb) {
735 		rtw89_err(rtwdev, "failed to alloc skb for h2c ba cam\n");
736 		return -ENOMEM;
737 	}
738 	skb_put(skb, H2C_BA_CAM_LEN);
739 	SET_BA_CAM_MACID(skb->data, macid);
740 	if (chip->bacam_v1)
741 		SET_BA_CAM_ENTRY_IDX_V1(skb->data, entry_idx);
742 	else
743 		SET_BA_CAM_ENTRY_IDX(skb->data, entry_idx);
744 	if (!valid)
745 		goto end;
746 	SET_BA_CAM_VALID(skb->data, valid);
747 	SET_BA_CAM_TID(skb->data, params->tid);
748 	if (params->buf_size > 64)
749 		SET_BA_CAM_BMAP_SIZE(skb->data, 4);
750 	else
751 		SET_BA_CAM_BMAP_SIZE(skb->data, 0);
752 	/* If init req is set, hw will set the ssn */
753 	SET_BA_CAM_INIT_REQ(skb->data, 1);
754 	SET_BA_CAM_SSN(skb->data, params->ssn);
755 
756 	if (chip->bacam_v1) {
757 		SET_BA_CAM_STD_EN(skb->data, 1);
758 		SET_BA_CAM_BAND(skb->data, rtwvif->mac_idx);
759 	}
760 
761 end:
762 	rtw89_h2c_pkt_set_hdr(rtwdev, skb, FWCMD_TYPE_H2C,
763 			      H2C_CAT_MAC,
764 			      H2C_CL_BA_CAM,
765 			      H2C_FUNC_MAC_BA_CAM, 0, 1,
766 			      H2C_BA_CAM_LEN);
767 
768 	ret = rtw89_h2c_tx(rtwdev, skb, false);
769 	if (ret) {
770 		rtw89_err(rtwdev, "failed to send h2c\n");
771 		goto fail;
772 	}
773 
774 	return 0;
775 fail:
776 	dev_kfree_skb_any(skb);
777 
778 	return ret;
779 }
780 
781 static int rtw89_fw_h2c_init_dynamic_ba_cam_v1(struct rtw89_dev *rtwdev,
782 					       u8 entry_idx, u8 uid)
783 {
784 	struct sk_buff *skb;
785 	int ret;
786 
787 	skb = rtw89_fw_h2c_alloc_skb_with_hdr(rtwdev, H2C_BA_CAM_LEN);
788 	if (!skb) {
789 		rtw89_err(rtwdev, "failed to alloc skb for dynamic h2c ba cam\n");
790 		return -ENOMEM;
791 	}
792 	skb_put(skb, H2C_BA_CAM_LEN);
793 
794 	SET_BA_CAM_VALID(skb->data, 1);
795 	SET_BA_CAM_ENTRY_IDX_V1(skb->data, entry_idx);
796 	SET_BA_CAM_UID(skb->data, uid);
797 	SET_BA_CAM_BAND(skb->data, 0);
798 	SET_BA_CAM_STD_EN(skb->data, 0);
799 
800 	rtw89_h2c_pkt_set_hdr(rtwdev, skb, FWCMD_TYPE_H2C,
801 			      H2C_CAT_MAC,
802 			      H2C_CL_BA_CAM,
803 			      H2C_FUNC_MAC_BA_CAM, 0, 1,
804 			      H2C_BA_CAM_LEN);
805 
806 	ret = rtw89_h2c_tx(rtwdev, skb, false);
807 	if (ret) {
808 		rtw89_err(rtwdev, "failed to send h2c\n");
809 		goto fail;
810 	}
811 
812 	return 0;
813 fail:
814 	dev_kfree_skb_any(skb);
815 
816 	return ret;
817 }
818 
819 void rtw89_fw_h2c_init_ba_cam_v1(struct rtw89_dev *rtwdev)
820 {
821 	const struct rtw89_chip_info *chip = rtwdev->chip;
822 	u8 entry_idx = chip->bacam_num;
823 	u8 uid = 0;
824 	int i;
825 
826 	for (i = 0; i < chip->bacam_dynamic_num; i++) {
827 		rtw89_fw_h2c_init_dynamic_ba_cam_v1(rtwdev, entry_idx, uid);
828 		entry_idx++;
829 		uid++;
830 	}
831 }
832 
833 #define H2C_LOG_CFG_LEN 12
834 int rtw89_fw_h2c_fw_log(struct rtw89_dev *rtwdev, bool enable)
835 {
836 	struct sk_buff *skb;
837 	u32 comp = enable ? BIT(RTW89_FW_LOG_COMP_INIT) | BIT(RTW89_FW_LOG_COMP_TASK) |
838 			    BIT(RTW89_FW_LOG_COMP_PS) | BIT(RTW89_FW_LOG_COMP_ERROR) : 0;
839 	int ret;
840 
841 	skb = rtw89_fw_h2c_alloc_skb_with_hdr(rtwdev, H2C_LOG_CFG_LEN);
842 	if (!skb) {
843 		rtw89_err(rtwdev, "failed to alloc skb for fw log cfg\n");
844 		return -ENOMEM;
845 	}
846 
847 	skb_put(skb, H2C_LOG_CFG_LEN);
848 	SET_LOG_CFG_LEVEL(skb->data, RTW89_FW_LOG_LEVEL_SER);
849 	SET_LOG_CFG_PATH(skb->data, BIT(RTW89_FW_LOG_LEVEL_C2H));
850 	SET_LOG_CFG_COMP(skb->data, comp);
851 	SET_LOG_CFG_COMP_EXT(skb->data, 0);
852 
853 	rtw89_h2c_pkt_set_hdr(rtwdev, skb, FWCMD_TYPE_H2C,
854 			      H2C_CAT_MAC,
855 			      H2C_CL_FW_INFO,
856 			      H2C_FUNC_LOG_CFG, 0, 0,
857 			      H2C_LOG_CFG_LEN);
858 
859 	ret = rtw89_h2c_tx(rtwdev, skb, false);
860 	if (ret) {
861 		rtw89_err(rtwdev, "failed to send h2c\n");
862 		goto fail;
863 	}
864 
865 	return 0;
866 fail:
867 	dev_kfree_skb_any(skb);
868 
869 	return ret;
870 }
871 
872 static int rtw89_fw_h2c_add_wow_fw_ofld(struct rtw89_dev *rtwdev,
873 					struct rtw89_vif *rtwvif,
874 					enum rtw89_fw_pkt_ofld_type type,
875 					u8 *id)
876 {
877 	struct ieee80211_vif *vif = rtwvif_to_vif(rtwvif);
878 	struct rtw89_wow_param *rtw_wow = &rtwdev->wow;
879 	struct rtw89_pktofld_info *info;
880 	struct sk_buff *skb;
881 	int ret;
882 
883 	info = kzalloc(sizeof(*info), GFP_KERNEL);
884 	if (!info)
885 		return -ENOMEM;
886 
887 	switch (type) {
888 	case RTW89_PKT_OFLD_TYPE_PS_POLL:
889 		skb = ieee80211_pspoll_get(rtwdev->hw, vif);
890 		break;
891 	case RTW89_PKT_OFLD_TYPE_PROBE_RSP:
892 		skb = ieee80211_proberesp_get(rtwdev->hw, vif);
893 		break;
894 	case RTW89_PKT_OFLD_TYPE_NULL_DATA:
895 		skb = ieee80211_nullfunc_get(rtwdev->hw, vif, -1, false);
896 		break;
897 	case RTW89_PKT_OFLD_TYPE_QOS_NULL:
898 		skb = ieee80211_nullfunc_get(rtwdev->hw, vif, -1, true);
899 		break;
900 	default:
901 		goto err;
902 	}
903 
904 	if (!skb)
905 		goto err;
906 
907 	list_add_tail(&info->list, &rtw_wow->pkt_list);
908 	ret = rtw89_fw_h2c_add_pkt_offload(rtwdev, &info->id, skb);
909 	kfree_skb(skb);
910 
911 	if (ret)
912 		return ret;
913 
914 	*id = info->id;
915 	return 0;
916 
917 err:
918 	kfree(info);
919 	return -ENOMEM;
920 }
921 
922 #define H2C_GENERAL_PKT_LEN 6
923 #define H2C_GENERAL_PKT_ID_UND 0xff
924 int rtw89_fw_h2c_general_pkt(struct rtw89_dev *rtwdev, u8 macid)
925 {
926 	struct sk_buff *skb;
927 	int ret;
928 
929 	skb = rtw89_fw_h2c_alloc_skb_with_hdr(rtwdev, H2C_GENERAL_PKT_LEN);
930 	if (!skb) {
931 		rtw89_err(rtwdev, "failed to alloc skb for fw dl\n");
932 		return -ENOMEM;
933 	}
934 	skb_put(skb, H2C_GENERAL_PKT_LEN);
935 	SET_GENERAL_PKT_MACID(skb->data, macid);
936 	SET_GENERAL_PKT_PROBRSP_ID(skb->data, H2C_GENERAL_PKT_ID_UND);
937 	SET_GENERAL_PKT_PSPOLL_ID(skb->data, H2C_GENERAL_PKT_ID_UND);
938 	SET_GENERAL_PKT_NULL_ID(skb->data, H2C_GENERAL_PKT_ID_UND);
939 	SET_GENERAL_PKT_QOS_NULL_ID(skb->data, H2C_GENERAL_PKT_ID_UND);
940 	SET_GENERAL_PKT_CTS2SELF_ID(skb->data, H2C_GENERAL_PKT_ID_UND);
941 
942 	rtw89_h2c_pkt_set_hdr(rtwdev, skb, FWCMD_TYPE_H2C,
943 			      H2C_CAT_MAC,
944 			      H2C_CL_FW_INFO,
945 			      H2C_FUNC_MAC_GENERAL_PKT, 0, 1,
946 			      H2C_GENERAL_PKT_LEN);
947 
948 	ret = rtw89_h2c_tx(rtwdev, skb, false);
949 	if (ret) {
950 		rtw89_err(rtwdev, "failed to send h2c\n");
951 		goto fail;
952 	}
953 
954 	return 0;
955 fail:
956 	dev_kfree_skb_any(skb);
957 
958 	return ret;
959 }
960 
961 #define H2C_LPS_PARM_LEN 8
962 int rtw89_fw_h2c_lps_parm(struct rtw89_dev *rtwdev,
963 			  struct rtw89_lps_parm *lps_param)
964 {
965 	struct sk_buff *skb;
966 	int ret;
967 
968 	skb = rtw89_fw_h2c_alloc_skb_with_hdr(rtwdev, H2C_LPS_PARM_LEN);
969 	if (!skb) {
970 		rtw89_err(rtwdev, "failed to alloc skb for fw dl\n");
971 		return -ENOMEM;
972 	}
973 	skb_put(skb, H2C_LPS_PARM_LEN);
974 
975 	SET_LPS_PARM_MACID(skb->data, lps_param->macid);
976 	SET_LPS_PARM_PSMODE(skb->data, lps_param->psmode);
977 	SET_LPS_PARM_LASTRPWM(skb->data, lps_param->lastrpwm);
978 	SET_LPS_PARM_RLBM(skb->data, 1);
979 	SET_LPS_PARM_SMARTPS(skb->data, 1);
980 	SET_LPS_PARM_AWAKEINTERVAL(skb->data, 1);
981 	SET_LPS_PARM_VOUAPSD(skb->data, 0);
982 	SET_LPS_PARM_VIUAPSD(skb->data, 0);
983 	SET_LPS_PARM_BEUAPSD(skb->data, 0);
984 	SET_LPS_PARM_BKUAPSD(skb->data, 0);
985 
986 	rtw89_h2c_pkt_set_hdr(rtwdev, skb, FWCMD_TYPE_H2C,
987 			      H2C_CAT_MAC,
988 			      H2C_CL_MAC_PS,
989 			      H2C_FUNC_MAC_LPS_PARM, 0, 1,
990 			      H2C_LPS_PARM_LEN);
991 
992 	ret = rtw89_h2c_tx(rtwdev, skb, false);
993 	if (ret) {
994 		rtw89_err(rtwdev, "failed to send h2c\n");
995 		goto fail;
996 	}
997 
998 	return 0;
999 fail:
1000 	dev_kfree_skb_any(skb);
1001 
1002 	return ret;
1003 }
1004 
1005 #define H2C_P2P_ACT_LEN 20
1006 int rtw89_fw_h2c_p2p_act(struct rtw89_dev *rtwdev, struct ieee80211_vif *vif,
1007 			 struct ieee80211_p2p_noa_desc *desc,
1008 			 u8 act, u8 noa_id)
1009 {
1010 	struct rtw89_vif *rtwvif = (struct rtw89_vif *)vif->drv_priv;
1011 	bool p2p_type_gc = rtwvif->wifi_role == RTW89_WIFI_ROLE_P2P_CLIENT;
1012 	u8 ctwindow_oppps = vif->bss_conf.p2p_noa_attr.oppps_ctwindow;
1013 	struct sk_buff *skb;
1014 	u8 *cmd;
1015 	int ret;
1016 
1017 	skb = rtw89_fw_h2c_alloc_skb_with_hdr(rtwdev, H2C_P2P_ACT_LEN);
1018 	if (!skb) {
1019 		rtw89_err(rtwdev, "failed to alloc skb for h2c p2p act\n");
1020 		return -ENOMEM;
1021 	}
1022 	skb_put(skb, H2C_P2P_ACT_LEN);
1023 	cmd = skb->data;
1024 
1025 	RTW89_SET_FWCMD_P2P_MACID(cmd, rtwvif->mac_id);
1026 	RTW89_SET_FWCMD_P2P_P2PID(cmd, 0);
1027 	RTW89_SET_FWCMD_P2P_NOAID(cmd, noa_id);
1028 	RTW89_SET_FWCMD_P2P_ACT(cmd, act);
1029 	RTW89_SET_FWCMD_P2P_TYPE(cmd, p2p_type_gc);
1030 	RTW89_SET_FWCMD_P2P_ALL_SLEP(cmd, 0);
1031 	if (desc) {
1032 		RTW89_SET_FWCMD_NOA_START_TIME(cmd, desc->start_time);
1033 		RTW89_SET_FWCMD_NOA_INTERVAL(cmd, desc->interval);
1034 		RTW89_SET_FWCMD_NOA_DURATION(cmd, desc->duration);
1035 		RTW89_SET_FWCMD_NOA_COUNT(cmd, desc->count);
1036 		RTW89_SET_FWCMD_NOA_CTWINDOW(cmd, ctwindow_oppps);
1037 	}
1038 
1039 	rtw89_h2c_pkt_set_hdr(rtwdev, skb, FWCMD_TYPE_H2C,
1040 			      H2C_CAT_MAC, H2C_CL_MAC_PS,
1041 			      H2C_FUNC_P2P_ACT, 0, 0,
1042 			      H2C_P2P_ACT_LEN);
1043 
1044 	ret = rtw89_h2c_tx(rtwdev, skb, false);
1045 	if (ret) {
1046 		rtw89_err(rtwdev, "failed to send h2c\n");
1047 		goto fail;
1048 	}
1049 
1050 	return 0;
1051 fail:
1052 	dev_kfree_skb_any(skb);
1053 
1054 	return ret;
1055 }
1056 
1057 static void __rtw89_fw_h2c_set_tx_path(struct rtw89_dev *rtwdev,
1058 				       struct sk_buff *skb)
1059 {
1060 	struct rtw89_hal *hal = &rtwdev->hal;
1061 	u8 ntx_path = hal->antenna_tx ? hal->antenna_tx : RF_B;
1062 	u8 map_b = hal->antenna_tx == RF_AB ? 1 : 0;
1063 
1064 	SET_CMC_TBL_NTX_PATH_EN(skb->data, ntx_path);
1065 	SET_CMC_TBL_PATH_MAP_A(skb->data, 0);
1066 	SET_CMC_TBL_PATH_MAP_B(skb->data, map_b);
1067 	SET_CMC_TBL_PATH_MAP_C(skb->data, 0);
1068 	SET_CMC_TBL_PATH_MAP_D(skb->data, 0);
1069 }
1070 
1071 #define H2C_CMC_TBL_LEN 68
1072 int rtw89_fw_h2c_default_cmac_tbl(struct rtw89_dev *rtwdev,
1073 				  struct rtw89_vif *rtwvif)
1074 {
1075 	const struct rtw89_chip_info *chip = rtwdev->chip;
1076 	struct sk_buff *skb;
1077 	u8 macid = rtwvif->mac_id;
1078 	int ret;
1079 
1080 	skb = rtw89_fw_h2c_alloc_skb_with_hdr(rtwdev, H2C_CMC_TBL_LEN);
1081 	if (!skb) {
1082 		rtw89_err(rtwdev, "failed to alloc skb for fw dl\n");
1083 		return -ENOMEM;
1084 	}
1085 	skb_put(skb, H2C_CMC_TBL_LEN);
1086 	SET_CTRL_INFO_MACID(skb->data, macid);
1087 	SET_CTRL_INFO_OPERATION(skb->data, 1);
1088 	if (chip->h2c_cctl_func_id == H2C_FUNC_MAC_CCTLINFO_UD) {
1089 		SET_CMC_TBL_TXPWR_MODE(skb->data, 0);
1090 		__rtw89_fw_h2c_set_tx_path(rtwdev, skb);
1091 		SET_CMC_TBL_ANTSEL_A(skb->data, 0);
1092 		SET_CMC_TBL_ANTSEL_B(skb->data, 0);
1093 		SET_CMC_TBL_ANTSEL_C(skb->data, 0);
1094 		SET_CMC_TBL_ANTSEL_D(skb->data, 0);
1095 	}
1096 	SET_CMC_TBL_DOPPLER_CTRL(skb->data, 0);
1097 	SET_CMC_TBL_TXPWR_TOLERENCE(skb->data, 0);
1098 	if (rtwvif->net_type == RTW89_NET_TYPE_AP_MODE)
1099 		SET_CMC_TBL_DATA_DCM(skb->data, 0);
1100 
1101 	rtw89_h2c_pkt_set_hdr(rtwdev, skb, FWCMD_TYPE_H2C,
1102 			      H2C_CAT_MAC, H2C_CL_MAC_FR_EXCHG,
1103 			      chip->h2c_cctl_func_id, 0, 1,
1104 			      H2C_CMC_TBL_LEN);
1105 
1106 	ret = rtw89_h2c_tx(rtwdev, skb, false);
1107 	if (ret) {
1108 		rtw89_err(rtwdev, "failed to send h2c\n");
1109 		goto fail;
1110 	}
1111 
1112 	return 0;
1113 fail:
1114 	dev_kfree_skb_any(skb);
1115 
1116 	return ret;
1117 }
1118 
1119 static void __get_sta_he_pkt_padding(struct rtw89_dev *rtwdev,
1120 				     struct ieee80211_sta *sta, u8 *pads)
1121 {
1122 	bool ppe_th;
1123 	u8 ppe16, ppe8;
1124 	u8 nss = min(sta->deflink.rx_nss, rtwdev->hal.tx_nss) - 1;
1125 	u8 ppe_thres_hdr = sta->deflink.he_cap.ppe_thres[0];
1126 	u8 ru_bitmap;
1127 	u8 n, idx, sh;
1128 	u16 ppe;
1129 	int i;
1130 
1131 	if (!sta->deflink.he_cap.has_he)
1132 		return;
1133 
1134 	ppe_th = FIELD_GET(IEEE80211_HE_PHY_CAP6_PPE_THRESHOLD_PRESENT,
1135 			   sta->deflink.he_cap.he_cap_elem.phy_cap_info[6]);
1136 	if (!ppe_th) {
1137 		u8 pad;
1138 
1139 		pad = FIELD_GET(IEEE80211_HE_PHY_CAP9_NOMINAL_PKT_PADDING_MASK,
1140 				sta->deflink.he_cap.he_cap_elem.phy_cap_info[9]);
1141 
1142 		for (i = 0; i < RTW89_PPE_BW_NUM; i++)
1143 			pads[i] = pad;
1144 
1145 		return;
1146 	}
1147 
1148 	ru_bitmap = FIELD_GET(IEEE80211_PPE_THRES_RU_INDEX_BITMASK_MASK, ppe_thres_hdr);
1149 	n = hweight8(ru_bitmap);
1150 	n = 7 + (n * IEEE80211_PPE_THRES_INFO_PPET_SIZE * 2) * nss;
1151 
1152 	for (i = 0; i < RTW89_PPE_BW_NUM; i++) {
1153 		if (!(ru_bitmap & BIT(i))) {
1154 			pads[i] = 1;
1155 			continue;
1156 		}
1157 
1158 		idx = n >> 3;
1159 		sh = n & 7;
1160 		n += IEEE80211_PPE_THRES_INFO_PPET_SIZE * 2;
1161 
1162 		ppe = le16_to_cpu(*((__le16 *)&sta->deflink.he_cap.ppe_thres[idx]));
1163 		ppe16 = (ppe >> sh) & IEEE80211_PPE_THRES_NSS_MASK;
1164 		sh += IEEE80211_PPE_THRES_INFO_PPET_SIZE;
1165 		ppe8 = (ppe >> sh) & IEEE80211_PPE_THRES_NSS_MASK;
1166 
1167 		if (ppe16 != 7 && ppe8 == 7)
1168 			pads[i] = 2;
1169 		else if (ppe8 != 7)
1170 			pads[i] = 1;
1171 		else
1172 			pads[i] = 0;
1173 	}
1174 }
1175 
1176 int rtw89_fw_h2c_assoc_cmac_tbl(struct rtw89_dev *rtwdev,
1177 				struct ieee80211_vif *vif,
1178 				struct ieee80211_sta *sta)
1179 {
1180 	const struct rtw89_chip_info *chip = rtwdev->chip;
1181 	struct rtw89_sta *rtwsta = sta_to_rtwsta_safe(sta);
1182 	struct rtw89_vif *rtwvif = (struct rtw89_vif *)vif->drv_priv;
1183 	const struct rtw89_chan *chan = rtw89_chan_get(rtwdev, RTW89_SUB_ENTITY_0);
1184 	struct sk_buff *skb;
1185 	u8 pads[RTW89_PPE_BW_NUM];
1186 	u8 mac_id = rtwsta ? rtwsta->mac_id : rtwvif->mac_id;
1187 	u16 lowest_rate;
1188 	int ret;
1189 
1190 	memset(pads, 0, sizeof(pads));
1191 	if (sta)
1192 		__get_sta_he_pkt_padding(rtwdev, sta, pads);
1193 
1194 	if (vif->p2p)
1195 		lowest_rate = RTW89_HW_RATE_OFDM6;
1196 	else if (chan->band_type == RTW89_BAND_2G)
1197 		lowest_rate = RTW89_HW_RATE_CCK1;
1198 	else
1199 		lowest_rate = RTW89_HW_RATE_OFDM6;
1200 
1201 	skb = rtw89_fw_h2c_alloc_skb_with_hdr(rtwdev, H2C_CMC_TBL_LEN);
1202 	if (!skb) {
1203 		rtw89_err(rtwdev, "failed to alloc skb for fw dl\n");
1204 		return -ENOMEM;
1205 	}
1206 	skb_put(skb, H2C_CMC_TBL_LEN);
1207 	SET_CTRL_INFO_MACID(skb->data, mac_id);
1208 	SET_CTRL_INFO_OPERATION(skb->data, 1);
1209 	SET_CMC_TBL_DISRTSFB(skb->data, 1);
1210 	SET_CMC_TBL_DISDATAFB(skb->data, 1);
1211 	SET_CMC_TBL_RTS_RTY_LOWEST_RATE(skb->data, lowest_rate);
1212 	SET_CMC_TBL_RTS_TXCNT_LMT_SEL(skb->data, 0);
1213 	SET_CMC_TBL_DATA_TXCNT_LMT_SEL(skb->data, 0);
1214 	if (vif->type == NL80211_IFTYPE_STATION)
1215 		SET_CMC_TBL_ULDL(skb->data, 1);
1216 	else
1217 		SET_CMC_TBL_ULDL(skb->data, 0);
1218 	SET_CMC_TBL_MULTI_PORT_ID(skb->data, rtwvif->port);
1219 	if (chip->h2c_cctl_func_id == H2C_FUNC_MAC_CCTLINFO_UD_V1) {
1220 		SET_CMC_TBL_NOMINAL_PKT_PADDING_V1(skb->data, pads[RTW89_CHANNEL_WIDTH_20]);
1221 		SET_CMC_TBL_NOMINAL_PKT_PADDING40_V1(skb->data, pads[RTW89_CHANNEL_WIDTH_40]);
1222 		SET_CMC_TBL_NOMINAL_PKT_PADDING80_V1(skb->data, pads[RTW89_CHANNEL_WIDTH_80]);
1223 		SET_CMC_TBL_NOMINAL_PKT_PADDING160_V1(skb->data, pads[RTW89_CHANNEL_WIDTH_160]);
1224 	} else if (chip->h2c_cctl_func_id == H2C_FUNC_MAC_CCTLINFO_UD) {
1225 		SET_CMC_TBL_NOMINAL_PKT_PADDING(skb->data, pads[RTW89_CHANNEL_WIDTH_20]);
1226 		SET_CMC_TBL_NOMINAL_PKT_PADDING40(skb->data, pads[RTW89_CHANNEL_WIDTH_40]);
1227 		SET_CMC_TBL_NOMINAL_PKT_PADDING80(skb->data, pads[RTW89_CHANNEL_WIDTH_80]);
1228 		SET_CMC_TBL_NOMINAL_PKT_PADDING160(skb->data, pads[RTW89_CHANNEL_WIDTH_160]);
1229 	}
1230 	if (sta)
1231 		SET_CMC_TBL_BSR_QUEUE_SIZE_FORMAT(skb->data,
1232 						  sta->deflink.he_cap.has_he);
1233 	if (rtwvif->net_type == RTW89_NET_TYPE_AP_MODE)
1234 		SET_CMC_TBL_DATA_DCM(skb->data, 0);
1235 
1236 	rtw89_h2c_pkt_set_hdr(rtwdev, skb, FWCMD_TYPE_H2C,
1237 			      H2C_CAT_MAC, H2C_CL_MAC_FR_EXCHG,
1238 			      chip->h2c_cctl_func_id, 0, 1,
1239 			      H2C_CMC_TBL_LEN);
1240 
1241 	ret = rtw89_h2c_tx(rtwdev, skb, false);
1242 	if (ret) {
1243 		rtw89_err(rtwdev, "failed to send h2c\n");
1244 		goto fail;
1245 	}
1246 
1247 	return 0;
1248 fail:
1249 	dev_kfree_skb_any(skb);
1250 
1251 	return ret;
1252 }
1253 
1254 int rtw89_fw_h2c_txtime_cmac_tbl(struct rtw89_dev *rtwdev,
1255 				 struct rtw89_sta *rtwsta)
1256 {
1257 	const struct rtw89_chip_info *chip = rtwdev->chip;
1258 	struct sk_buff *skb;
1259 	int ret;
1260 
1261 	skb = rtw89_fw_h2c_alloc_skb_with_hdr(rtwdev, H2C_CMC_TBL_LEN);
1262 	if (!skb) {
1263 		rtw89_err(rtwdev, "failed to alloc skb for fw dl\n");
1264 		return -ENOMEM;
1265 	}
1266 	skb_put(skb, H2C_CMC_TBL_LEN);
1267 	SET_CTRL_INFO_MACID(skb->data, rtwsta->mac_id);
1268 	SET_CTRL_INFO_OPERATION(skb->data, 1);
1269 	if (rtwsta->cctl_tx_time) {
1270 		SET_CMC_TBL_AMPDU_TIME_SEL(skb->data, 1);
1271 		SET_CMC_TBL_AMPDU_MAX_TIME(skb->data, rtwsta->ampdu_max_time);
1272 	}
1273 	if (rtwsta->cctl_tx_retry_limit) {
1274 		SET_CMC_TBL_DATA_TXCNT_LMT_SEL(skb->data, 1);
1275 		SET_CMC_TBL_DATA_TX_CNT_LMT(skb->data, rtwsta->data_tx_cnt_lmt);
1276 	}
1277 
1278 	rtw89_h2c_pkt_set_hdr(rtwdev, skb, FWCMD_TYPE_H2C,
1279 			      H2C_CAT_MAC, H2C_CL_MAC_FR_EXCHG,
1280 			      chip->h2c_cctl_func_id, 0, 1,
1281 			      H2C_CMC_TBL_LEN);
1282 
1283 	ret = rtw89_h2c_tx(rtwdev, skb, false);
1284 	if (ret) {
1285 		rtw89_err(rtwdev, "failed to send h2c\n");
1286 		goto fail;
1287 	}
1288 
1289 	return 0;
1290 fail:
1291 	dev_kfree_skb_any(skb);
1292 
1293 	return ret;
1294 }
1295 
1296 int rtw89_fw_h2c_txpath_cmac_tbl(struct rtw89_dev *rtwdev,
1297 				 struct rtw89_sta *rtwsta)
1298 {
1299 	const struct rtw89_chip_info *chip = rtwdev->chip;
1300 	struct sk_buff *skb;
1301 	int ret;
1302 
1303 	if (chip->h2c_cctl_func_id != H2C_FUNC_MAC_CCTLINFO_UD)
1304 		return 0;
1305 
1306 	skb = rtw89_fw_h2c_alloc_skb_with_hdr(rtwdev, H2C_CMC_TBL_LEN);
1307 	if (!skb) {
1308 		rtw89_err(rtwdev, "failed to alloc skb for fw dl\n");
1309 		return -ENOMEM;
1310 	}
1311 	skb_put(skb, H2C_CMC_TBL_LEN);
1312 	SET_CTRL_INFO_MACID(skb->data, rtwsta->mac_id);
1313 	SET_CTRL_INFO_OPERATION(skb->data, 1);
1314 
1315 	__rtw89_fw_h2c_set_tx_path(rtwdev, skb);
1316 
1317 	rtw89_h2c_pkt_set_hdr(rtwdev, skb, FWCMD_TYPE_H2C,
1318 			      H2C_CAT_MAC, H2C_CL_MAC_FR_EXCHG,
1319 			      H2C_FUNC_MAC_CCTLINFO_UD, 0, 1,
1320 			      H2C_CMC_TBL_LEN);
1321 
1322 	ret = rtw89_h2c_tx(rtwdev, skb, false);
1323 	if (ret) {
1324 		rtw89_err(rtwdev, "failed to send h2c\n");
1325 		goto fail;
1326 	}
1327 
1328 	return 0;
1329 fail:
1330 	dev_kfree_skb_any(skb);
1331 
1332 	return ret;
1333 }
1334 
1335 #define H2C_BCN_BASE_LEN 12
1336 int rtw89_fw_h2c_update_beacon(struct rtw89_dev *rtwdev,
1337 			       struct rtw89_vif *rtwvif)
1338 {
1339 	struct ieee80211_vif *vif = rtwvif_to_vif(rtwvif);
1340 	const struct rtw89_chan *chan = rtw89_chan_get(rtwdev, RTW89_SUB_ENTITY_0);
1341 	struct sk_buff *skb;
1342 	struct sk_buff *skb_beacon;
1343 	u16 tim_offset;
1344 	int bcn_total_len;
1345 	u16 beacon_rate;
1346 	int ret;
1347 
1348 	if (vif->p2p)
1349 		beacon_rate = RTW89_HW_RATE_OFDM6;
1350 	else if (chan->band_type == RTW89_BAND_2G)
1351 		beacon_rate = RTW89_HW_RATE_CCK1;
1352 	else
1353 		beacon_rate = RTW89_HW_RATE_OFDM6;
1354 
1355 	skb_beacon = ieee80211_beacon_get_tim(rtwdev->hw, vif, &tim_offset,
1356 					      NULL, 0);
1357 	if (!skb_beacon) {
1358 		rtw89_err(rtwdev, "failed to get beacon skb\n");
1359 		return -ENOMEM;
1360 	}
1361 
1362 	bcn_total_len = H2C_BCN_BASE_LEN + skb_beacon->len;
1363 	skb = rtw89_fw_h2c_alloc_skb_with_hdr(rtwdev, bcn_total_len);
1364 	if (!skb) {
1365 		rtw89_err(rtwdev, "failed to alloc skb for fw dl\n");
1366 		dev_kfree_skb_any(skb_beacon);
1367 		return -ENOMEM;
1368 	}
1369 	skb_put(skb, H2C_BCN_BASE_LEN);
1370 
1371 	SET_BCN_UPD_PORT(skb->data, rtwvif->port);
1372 	SET_BCN_UPD_MBSSID(skb->data, 0);
1373 	SET_BCN_UPD_BAND(skb->data, rtwvif->mac_idx);
1374 	SET_BCN_UPD_GRP_IE_OFST(skb->data, tim_offset);
1375 	SET_BCN_UPD_MACID(skb->data, rtwvif->mac_id);
1376 	SET_BCN_UPD_SSN_SEL(skb->data, RTW89_MGMT_HW_SSN_SEL);
1377 	SET_BCN_UPD_SSN_MODE(skb->data, RTW89_MGMT_HW_SEQ_MODE);
1378 	SET_BCN_UPD_RATE(skb->data, beacon_rate);
1379 
1380 	skb_put_data(skb, skb_beacon->data, skb_beacon->len);
1381 	dev_kfree_skb_any(skb_beacon);
1382 
1383 	rtw89_h2c_pkt_set_hdr(rtwdev, skb, FWCMD_TYPE_H2C,
1384 			      H2C_CAT_MAC, H2C_CL_MAC_FR_EXCHG,
1385 			      H2C_FUNC_MAC_BCN_UPD, 0, 1,
1386 			      bcn_total_len);
1387 
1388 	ret = rtw89_h2c_tx(rtwdev, skb, false);
1389 	if (ret) {
1390 		rtw89_err(rtwdev, "failed to send h2c\n");
1391 		dev_kfree_skb_any(skb);
1392 		return ret;
1393 	}
1394 
1395 	return 0;
1396 }
1397 
1398 #define H2C_ROLE_MAINTAIN_LEN 4
1399 int rtw89_fw_h2c_role_maintain(struct rtw89_dev *rtwdev,
1400 			       struct rtw89_vif *rtwvif,
1401 			       struct rtw89_sta *rtwsta,
1402 			       enum rtw89_upd_mode upd_mode)
1403 {
1404 	struct sk_buff *skb;
1405 	u8 mac_id = rtwsta ? rtwsta->mac_id : rtwvif->mac_id;
1406 	u8 self_role;
1407 	int ret;
1408 
1409 	if (rtwvif->net_type == RTW89_NET_TYPE_AP_MODE) {
1410 		if (rtwsta)
1411 			self_role = RTW89_SELF_ROLE_AP_CLIENT;
1412 		else
1413 			self_role = rtwvif->self_role;
1414 	} else {
1415 		self_role = rtwvif->self_role;
1416 	}
1417 
1418 	skb = rtw89_fw_h2c_alloc_skb_with_hdr(rtwdev, H2C_ROLE_MAINTAIN_LEN);
1419 	if (!skb) {
1420 		rtw89_err(rtwdev, "failed to alloc skb for h2c join\n");
1421 		return -ENOMEM;
1422 	}
1423 	skb_put(skb, H2C_ROLE_MAINTAIN_LEN);
1424 	SET_FWROLE_MAINTAIN_MACID(skb->data, mac_id);
1425 	SET_FWROLE_MAINTAIN_SELF_ROLE(skb->data, self_role);
1426 	SET_FWROLE_MAINTAIN_UPD_MODE(skb->data, upd_mode);
1427 	SET_FWROLE_MAINTAIN_WIFI_ROLE(skb->data, rtwvif->wifi_role);
1428 
1429 	rtw89_h2c_pkt_set_hdr(rtwdev, skb, FWCMD_TYPE_H2C,
1430 			      H2C_CAT_MAC, H2C_CL_MAC_MEDIA_RPT,
1431 			      H2C_FUNC_MAC_FWROLE_MAINTAIN, 0, 1,
1432 			      H2C_ROLE_MAINTAIN_LEN);
1433 
1434 	ret = rtw89_h2c_tx(rtwdev, skb, false);
1435 	if (ret) {
1436 		rtw89_err(rtwdev, "failed to send h2c\n");
1437 		goto fail;
1438 	}
1439 
1440 	return 0;
1441 fail:
1442 	dev_kfree_skb_any(skb);
1443 
1444 	return ret;
1445 }
1446 
1447 #define H2C_JOIN_INFO_LEN 4
1448 int rtw89_fw_h2c_join_info(struct rtw89_dev *rtwdev, struct rtw89_vif *rtwvif,
1449 			   struct rtw89_sta *rtwsta, bool dis_conn)
1450 {
1451 	struct sk_buff *skb;
1452 	u8 mac_id = rtwsta ? rtwsta->mac_id : rtwvif->mac_id;
1453 	u8 self_role = rtwvif->self_role;
1454 	u8 net_type = rtwvif->net_type;
1455 	int ret;
1456 
1457 	if (net_type == RTW89_NET_TYPE_AP_MODE && rtwsta) {
1458 		self_role = RTW89_SELF_ROLE_AP_CLIENT;
1459 		net_type = dis_conn ? RTW89_NET_TYPE_NO_LINK : net_type;
1460 	}
1461 
1462 	skb = rtw89_fw_h2c_alloc_skb_with_hdr(rtwdev, H2C_JOIN_INFO_LEN);
1463 	if (!skb) {
1464 		rtw89_err(rtwdev, "failed to alloc skb for h2c join\n");
1465 		return -ENOMEM;
1466 	}
1467 	skb_put(skb, H2C_JOIN_INFO_LEN);
1468 	SET_JOININFO_MACID(skb->data, mac_id);
1469 	SET_JOININFO_OP(skb->data, dis_conn);
1470 	SET_JOININFO_BAND(skb->data, rtwvif->mac_idx);
1471 	SET_JOININFO_WMM(skb->data, rtwvif->wmm);
1472 	SET_JOININFO_TGR(skb->data, rtwvif->trigger);
1473 	SET_JOININFO_ISHESTA(skb->data, 0);
1474 	SET_JOININFO_DLBW(skb->data, 0);
1475 	SET_JOININFO_TF_MAC_PAD(skb->data, 0);
1476 	SET_JOININFO_DL_T_PE(skb->data, 0);
1477 	SET_JOININFO_PORT_ID(skb->data, rtwvif->port);
1478 	SET_JOININFO_NET_TYPE(skb->data, net_type);
1479 	SET_JOININFO_WIFI_ROLE(skb->data, rtwvif->wifi_role);
1480 	SET_JOININFO_SELF_ROLE(skb->data, self_role);
1481 
1482 	rtw89_h2c_pkt_set_hdr(rtwdev, skb, FWCMD_TYPE_H2C,
1483 			      H2C_CAT_MAC, H2C_CL_MAC_MEDIA_RPT,
1484 			      H2C_FUNC_MAC_JOININFO, 0, 1,
1485 			      H2C_JOIN_INFO_LEN);
1486 
1487 	ret = rtw89_h2c_tx(rtwdev, skb, false);
1488 	if (ret) {
1489 		rtw89_err(rtwdev, "failed to send h2c\n");
1490 		goto fail;
1491 	}
1492 
1493 	return 0;
1494 fail:
1495 	dev_kfree_skb_any(skb);
1496 
1497 	return ret;
1498 }
1499 
1500 int rtw89_fw_h2c_macid_pause(struct rtw89_dev *rtwdev, u8 sh, u8 grp,
1501 			     bool pause)
1502 {
1503 	struct rtw89_fw_macid_pause_grp h2c = {{0}};
1504 	u8 len = sizeof(struct rtw89_fw_macid_pause_grp);
1505 	struct sk_buff *skb;
1506 	int ret;
1507 
1508 	skb = rtw89_fw_h2c_alloc_skb_with_hdr(rtwdev, H2C_JOIN_INFO_LEN);
1509 	if (!skb) {
1510 		rtw89_err(rtwdev, "failed to alloc skb for h2c join\n");
1511 		return -ENOMEM;
1512 	}
1513 	h2c.mask_grp[grp] = cpu_to_le32(BIT(sh));
1514 	if (pause)
1515 		h2c.pause_grp[grp] = cpu_to_le32(BIT(sh));
1516 	skb_put_data(skb, &h2c, len);
1517 
1518 	rtw89_h2c_pkt_set_hdr(rtwdev, skb, FWCMD_TYPE_H2C,
1519 			      H2C_CAT_MAC, H2C_CL_MAC_FW_OFLD,
1520 			      H2C_FUNC_MAC_MACID_PAUSE, 1, 0,
1521 			      len);
1522 
1523 	ret = rtw89_h2c_tx(rtwdev, skb, false);
1524 	if (ret) {
1525 		rtw89_err(rtwdev, "failed to send h2c\n");
1526 		goto fail;
1527 	}
1528 
1529 	return 0;
1530 fail:
1531 	dev_kfree_skb_any(skb);
1532 
1533 	return ret;
1534 }
1535 
1536 #define H2C_EDCA_LEN 12
1537 int rtw89_fw_h2c_set_edca(struct rtw89_dev *rtwdev, struct rtw89_vif *rtwvif,
1538 			  u8 ac, u32 val)
1539 {
1540 	struct sk_buff *skb;
1541 	int ret;
1542 
1543 	skb = rtw89_fw_h2c_alloc_skb_with_hdr(rtwdev, H2C_EDCA_LEN);
1544 	if (!skb) {
1545 		rtw89_err(rtwdev, "failed to alloc skb for h2c edca\n");
1546 		return -ENOMEM;
1547 	}
1548 	skb_put(skb, H2C_EDCA_LEN);
1549 	RTW89_SET_EDCA_SEL(skb->data, 0);
1550 	RTW89_SET_EDCA_BAND(skb->data, rtwvif->mac_idx);
1551 	RTW89_SET_EDCA_WMM(skb->data, 0);
1552 	RTW89_SET_EDCA_AC(skb->data, ac);
1553 	RTW89_SET_EDCA_PARAM(skb->data, val);
1554 
1555 	rtw89_h2c_pkt_set_hdr(rtwdev, skb, FWCMD_TYPE_H2C,
1556 			      H2C_CAT_MAC, H2C_CL_MAC_FW_OFLD,
1557 			      H2C_FUNC_USR_EDCA, 0, 1,
1558 			      H2C_EDCA_LEN);
1559 
1560 	ret = rtw89_h2c_tx(rtwdev, skb, false);
1561 	if (ret) {
1562 		rtw89_err(rtwdev, "failed to send h2c\n");
1563 		goto fail;
1564 	}
1565 
1566 	return 0;
1567 fail:
1568 	dev_kfree_skb_any(skb);
1569 
1570 	return ret;
1571 }
1572 
1573 #define H2C_TSF32_TOGL_LEN 4
1574 int rtw89_fw_h2c_tsf32_toggle(struct rtw89_dev *rtwdev, struct rtw89_vif *rtwvif,
1575 			      bool en)
1576 {
1577 	struct sk_buff *skb;
1578 	u16 early_us = en ? 2000 : 0;
1579 	u8 *cmd;
1580 	int ret;
1581 
1582 	skb = rtw89_fw_h2c_alloc_skb_with_hdr(rtwdev, H2C_TSF32_TOGL_LEN);
1583 	if (!skb) {
1584 		rtw89_err(rtwdev, "failed to alloc skb for h2c p2p act\n");
1585 		return -ENOMEM;
1586 	}
1587 	skb_put(skb, H2C_TSF32_TOGL_LEN);
1588 	cmd = skb->data;
1589 
1590 	RTW89_SET_FWCMD_TSF32_TOGL_BAND(cmd, rtwvif->mac_idx);
1591 	RTW89_SET_FWCMD_TSF32_TOGL_EN(cmd, en);
1592 	RTW89_SET_FWCMD_TSF32_TOGL_PORT(cmd, rtwvif->port);
1593 	RTW89_SET_FWCMD_TSF32_TOGL_EARLY(cmd, early_us);
1594 
1595 	rtw89_h2c_pkt_set_hdr(rtwdev, skb, FWCMD_TYPE_H2C,
1596 			      H2C_CAT_MAC, H2C_CL_MAC_FW_OFLD,
1597 			      H2C_FUNC_TSF32_TOGL, 0, 0,
1598 			      H2C_TSF32_TOGL_LEN);
1599 
1600 	ret = rtw89_h2c_tx(rtwdev, skb, false);
1601 	if (ret) {
1602 		rtw89_err(rtwdev, "failed to send h2c\n");
1603 		goto fail;
1604 	}
1605 
1606 	return 0;
1607 fail:
1608 	dev_kfree_skb_any(skb);
1609 
1610 	return ret;
1611 }
1612 
1613 #define H2C_OFLD_CFG_LEN 8
1614 int rtw89_fw_h2c_set_ofld_cfg(struct rtw89_dev *rtwdev)
1615 {
1616 	static const u8 cfg[] = {0x09, 0x00, 0x00, 0x00, 0x5e, 0x00, 0x00, 0x00};
1617 	struct sk_buff *skb;
1618 	int ret;
1619 
1620 	skb = rtw89_fw_h2c_alloc_skb_with_hdr(rtwdev, H2C_OFLD_CFG_LEN);
1621 	if (!skb) {
1622 		rtw89_err(rtwdev, "failed to alloc skb for h2c ofld\n");
1623 		return -ENOMEM;
1624 	}
1625 	skb_put_data(skb, cfg, H2C_OFLD_CFG_LEN);
1626 
1627 	rtw89_h2c_pkt_set_hdr(rtwdev, skb, FWCMD_TYPE_H2C,
1628 			      H2C_CAT_MAC, H2C_CL_MAC_FW_OFLD,
1629 			      H2C_FUNC_OFLD_CFG, 0, 1,
1630 			      H2C_OFLD_CFG_LEN);
1631 
1632 	ret = rtw89_h2c_tx(rtwdev, skb, false);
1633 	if (ret) {
1634 		rtw89_err(rtwdev, "failed to send h2c\n");
1635 		goto fail;
1636 	}
1637 
1638 	return 0;
1639 fail:
1640 	dev_kfree_skb_any(skb);
1641 
1642 	return ret;
1643 }
1644 
1645 #define H2C_RA_LEN 16
1646 int rtw89_fw_h2c_ra(struct rtw89_dev *rtwdev, struct rtw89_ra_info *ra, bool csi)
1647 {
1648 	struct sk_buff *skb;
1649 	u8 *cmd;
1650 	int ret;
1651 
1652 	skb = rtw89_fw_h2c_alloc_skb_with_hdr(rtwdev, H2C_RA_LEN);
1653 	if (!skb) {
1654 		rtw89_err(rtwdev, "failed to alloc skb for h2c join\n");
1655 		return -ENOMEM;
1656 	}
1657 	skb_put(skb, H2C_RA_LEN);
1658 	cmd = skb->data;
1659 	rtw89_debug(rtwdev, RTW89_DBG_RA,
1660 		    "ra cmd msk: %llx ", ra->ra_mask);
1661 
1662 	RTW89_SET_FWCMD_RA_MODE(cmd, ra->mode_ctrl);
1663 	RTW89_SET_FWCMD_RA_BW_CAP(cmd, ra->bw_cap);
1664 	RTW89_SET_FWCMD_RA_MACID(cmd, ra->macid);
1665 	RTW89_SET_FWCMD_RA_DCM(cmd, ra->dcm_cap);
1666 	RTW89_SET_FWCMD_RA_ER(cmd, ra->er_cap);
1667 	RTW89_SET_FWCMD_RA_INIT_RATE_LV(cmd, ra->init_rate_lv);
1668 	RTW89_SET_FWCMD_RA_UPD_ALL(cmd, ra->upd_all);
1669 	RTW89_SET_FWCMD_RA_SGI(cmd, ra->en_sgi);
1670 	RTW89_SET_FWCMD_RA_LDPC(cmd, ra->ldpc_cap);
1671 	RTW89_SET_FWCMD_RA_STBC(cmd, ra->stbc_cap);
1672 	RTW89_SET_FWCMD_RA_SS_NUM(cmd, ra->ss_num);
1673 	RTW89_SET_FWCMD_RA_GILTF(cmd, ra->giltf);
1674 	RTW89_SET_FWCMD_RA_UPD_BW_NSS_MASK(cmd, ra->upd_bw_nss_mask);
1675 	RTW89_SET_FWCMD_RA_UPD_MASK(cmd, ra->upd_mask);
1676 	RTW89_SET_FWCMD_RA_MASK_0(cmd, FIELD_GET(MASKBYTE0, ra->ra_mask));
1677 	RTW89_SET_FWCMD_RA_MASK_1(cmd, FIELD_GET(MASKBYTE1, ra->ra_mask));
1678 	RTW89_SET_FWCMD_RA_MASK_2(cmd, FIELD_GET(MASKBYTE2, ra->ra_mask));
1679 	RTW89_SET_FWCMD_RA_MASK_3(cmd, FIELD_GET(MASKBYTE3, ra->ra_mask));
1680 	RTW89_SET_FWCMD_RA_MASK_4(cmd, FIELD_GET(MASKBYTE4, ra->ra_mask));
1681 	RTW89_SET_FWCMD_RA_FIX_GILTF_EN(cmd, ra->fix_giltf_en);
1682 	RTW89_SET_FWCMD_RA_FIX_GILTF(cmd, ra->fix_giltf);
1683 
1684 	if (csi) {
1685 		RTW89_SET_FWCMD_RA_BFEE_CSI_CTL(cmd, 1);
1686 		RTW89_SET_FWCMD_RA_BAND_NUM(cmd, ra->band_num);
1687 		RTW89_SET_FWCMD_RA_CR_TBL_SEL(cmd, ra->cr_tbl_sel);
1688 		RTW89_SET_FWCMD_RA_FIXED_CSI_RATE_EN(cmd, ra->fixed_csi_rate_en);
1689 		RTW89_SET_FWCMD_RA_RA_CSI_RATE_EN(cmd, ra->ra_csi_rate_en);
1690 		RTW89_SET_FWCMD_RA_FIXED_CSI_MCS_SS_IDX(cmd, ra->csi_mcs_ss_idx);
1691 		RTW89_SET_FWCMD_RA_FIXED_CSI_MODE(cmd, ra->csi_mode);
1692 		RTW89_SET_FWCMD_RA_FIXED_CSI_GI_LTF(cmd, ra->csi_gi_ltf);
1693 		RTW89_SET_FWCMD_RA_FIXED_CSI_BW(cmd, ra->csi_bw);
1694 	}
1695 
1696 	rtw89_h2c_pkt_set_hdr(rtwdev, skb, FWCMD_TYPE_H2C,
1697 			      H2C_CAT_OUTSRC, H2C_CL_OUTSRC_RA,
1698 			      H2C_FUNC_OUTSRC_RA_MACIDCFG, 0, 0,
1699 			      H2C_RA_LEN);
1700 
1701 	ret = rtw89_h2c_tx(rtwdev, skb, false);
1702 	if (ret) {
1703 		rtw89_err(rtwdev, "failed to send h2c\n");
1704 		goto fail;
1705 	}
1706 
1707 	return 0;
1708 fail:
1709 	dev_kfree_skb_any(skb);
1710 
1711 	return ret;
1712 }
1713 
1714 #define H2C_LEN_CXDRVHDR 2
1715 #define H2C_LEN_CXDRVINFO_INIT (12 + H2C_LEN_CXDRVHDR)
1716 int rtw89_fw_h2c_cxdrv_init(struct rtw89_dev *rtwdev)
1717 {
1718 	struct rtw89_btc *btc = &rtwdev->btc;
1719 	struct rtw89_btc_dm *dm = &btc->dm;
1720 	struct rtw89_btc_init_info *init_info = &dm->init_info;
1721 	struct rtw89_btc_module *module = &init_info->module;
1722 	struct rtw89_btc_ant_info *ant = &module->ant;
1723 	struct sk_buff *skb;
1724 	u8 *cmd;
1725 	int ret;
1726 
1727 	skb = rtw89_fw_h2c_alloc_skb_with_hdr(rtwdev, H2C_LEN_CXDRVINFO_INIT);
1728 	if (!skb) {
1729 		rtw89_err(rtwdev, "failed to alloc skb for h2c cxdrv_init\n");
1730 		return -ENOMEM;
1731 	}
1732 	skb_put(skb, H2C_LEN_CXDRVINFO_INIT);
1733 	cmd = skb->data;
1734 
1735 	RTW89_SET_FWCMD_CXHDR_TYPE(cmd, CXDRVINFO_INIT);
1736 	RTW89_SET_FWCMD_CXHDR_LEN(cmd, H2C_LEN_CXDRVINFO_INIT - H2C_LEN_CXDRVHDR);
1737 
1738 	RTW89_SET_FWCMD_CXINIT_ANT_TYPE(cmd, ant->type);
1739 	RTW89_SET_FWCMD_CXINIT_ANT_NUM(cmd, ant->num);
1740 	RTW89_SET_FWCMD_CXINIT_ANT_ISO(cmd, ant->isolation);
1741 	RTW89_SET_FWCMD_CXINIT_ANT_POS(cmd, ant->single_pos);
1742 	RTW89_SET_FWCMD_CXINIT_ANT_DIVERSITY(cmd, ant->diversity);
1743 
1744 	RTW89_SET_FWCMD_CXINIT_MOD_RFE(cmd, module->rfe_type);
1745 	RTW89_SET_FWCMD_CXINIT_MOD_CV(cmd, module->cv);
1746 	RTW89_SET_FWCMD_CXINIT_MOD_BT_SOLO(cmd, module->bt_solo);
1747 	RTW89_SET_FWCMD_CXINIT_MOD_BT_POS(cmd, module->bt_pos);
1748 	RTW89_SET_FWCMD_CXINIT_MOD_SW_TYPE(cmd, module->switch_type);
1749 
1750 	RTW89_SET_FWCMD_CXINIT_WL_GCH(cmd, init_info->wl_guard_ch);
1751 	RTW89_SET_FWCMD_CXINIT_WL_ONLY(cmd, init_info->wl_only);
1752 	RTW89_SET_FWCMD_CXINIT_WL_INITOK(cmd, init_info->wl_init_ok);
1753 	RTW89_SET_FWCMD_CXINIT_DBCC_EN(cmd, init_info->dbcc_en);
1754 	RTW89_SET_FWCMD_CXINIT_CX_OTHER(cmd, init_info->cx_other);
1755 	RTW89_SET_FWCMD_CXINIT_BT_ONLY(cmd, init_info->bt_only);
1756 
1757 	rtw89_h2c_pkt_set_hdr(rtwdev, skb, FWCMD_TYPE_H2C,
1758 			      H2C_CAT_OUTSRC, BTFC_SET,
1759 			      SET_DRV_INFO, 0, 0,
1760 			      H2C_LEN_CXDRVINFO_INIT);
1761 
1762 	ret = rtw89_h2c_tx(rtwdev, skb, false);
1763 	if (ret) {
1764 		rtw89_err(rtwdev, "failed to send h2c\n");
1765 		goto fail;
1766 	}
1767 
1768 	return 0;
1769 fail:
1770 	dev_kfree_skb_any(skb);
1771 
1772 	return ret;
1773 }
1774 
1775 #define PORT_DATA_OFFSET 4
1776 #define H2C_LEN_CXDRVINFO_ROLE_DBCC_LEN 12
1777 #define H2C_LEN_CXDRVINFO_ROLE (4 + 12 * RTW89_PORT_NUM + H2C_LEN_CXDRVHDR)
1778 #define H2C_LEN_CXDRVINFO_ROLE_V1 (4 + 16 * RTW89_PORT_NUM + \
1779 				   H2C_LEN_CXDRVINFO_ROLE_DBCC_LEN + \
1780 				   H2C_LEN_CXDRVHDR)
1781 int rtw89_fw_h2c_cxdrv_role(struct rtw89_dev *rtwdev)
1782 {
1783 	struct rtw89_btc *btc = &rtwdev->btc;
1784 	struct rtw89_btc_wl_info *wl = &btc->cx.wl;
1785 	struct rtw89_btc_wl_role_info *role_info = &wl->role_info;
1786 	struct rtw89_btc_wl_role_info_bpos *bpos = &role_info->role_map.role;
1787 	struct rtw89_btc_wl_active_role *active = role_info->active_role;
1788 	struct sk_buff *skb;
1789 	u8 offset = 0;
1790 	u8 *cmd;
1791 	int ret;
1792 	int i;
1793 
1794 	skb = rtw89_fw_h2c_alloc_skb_with_hdr(rtwdev, H2C_LEN_CXDRVINFO_ROLE);
1795 	if (!skb) {
1796 		rtw89_err(rtwdev, "failed to alloc skb for h2c cxdrv_role\n");
1797 		return -ENOMEM;
1798 	}
1799 	skb_put(skb, H2C_LEN_CXDRVINFO_ROLE);
1800 	cmd = skb->data;
1801 
1802 	RTW89_SET_FWCMD_CXHDR_TYPE(cmd, CXDRVINFO_ROLE);
1803 	RTW89_SET_FWCMD_CXHDR_LEN(cmd, H2C_LEN_CXDRVINFO_ROLE - H2C_LEN_CXDRVHDR);
1804 
1805 	RTW89_SET_FWCMD_CXROLE_CONNECT_CNT(cmd, role_info->connect_cnt);
1806 	RTW89_SET_FWCMD_CXROLE_LINK_MODE(cmd, role_info->link_mode);
1807 
1808 	RTW89_SET_FWCMD_CXROLE_ROLE_NONE(cmd, bpos->none);
1809 	RTW89_SET_FWCMD_CXROLE_ROLE_STA(cmd, bpos->station);
1810 	RTW89_SET_FWCMD_CXROLE_ROLE_AP(cmd, bpos->ap);
1811 	RTW89_SET_FWCMD_CXROLE_ROLE_VAP(cmd, bpos->vap);
1812 	RTW89_SET_FWCMD_CXROLE_ROLE_ADHOC(cmd, bpos->adhoc);
1813 	RTW89_SET_FWCMD_CXROLE_ROLE_ADHOC_MASTER(cmd, bpos->adhoc_master);
1814 	RTW89_SET_FWCMD_CXROLE_ROLE_MESH(cmd, bpos->mesh);
1815 	RTW89_SET_FWCMD_CXROLE_ROLE_MONITOR(cmd, bpos->moniter);
1816 	RTW89_SET_FWCMD_CXROLE_ROLE_P2P_DEV(cmd, bpos->p2p_device);
1817 	RTW89_SET_FWCMD_CXROLE_ROLE_P2P_GC(cmd, bpos->p2p_gc);
1818 	RTW89_SET_FWCMD_CXROLE_ROLE_P2P_GO(cmd, bpos->p2p_go);
1819 	RTW89_SET_FWCMD_CXROLE_ROLE_NAN(cmd, bpos->nan);
1820 
1821 	for (i = 0; i < RTW89_PORT_NUM; i++, active++) {
1822 		RTW89_SET_FWCMD_CXROLE_ACT_CONNECTED(cmd, active->connected, i, offset);
1823 		RTW89_SET_FWCMD_CXROLE_ACT_PID(cmd, active->pid, i, offset);
1824 		RTW89_SET_FWCMD_CXROLE_ACT_PHY(cmd, active->phy, i, offset);
1825 		RTW89_SET_FWCMD_CXROLE_ACT_NOA(cmd, active->noa, i, offset);
1826 		RTW89_SET_FWCMD_CXROLE_ACT_BAND(cmd, active->band, i, offset);
1827 		RTW89_SET_FWCMD_CXROLE_ACT_CLIENT_PS(cmd, active->client_ps, i, offset);
1828 		RTW89_SET_FWCMD_CXROLE_ACT_BW(cmd, active->bw, i, offset);
1829 		RTW89_SET_FWCMD_CXROLE_ACT_ROLE(cmd, active->role, i, offset);
1830 		RTW89_SET_FWCMD_CXROLE_ACT_CH(cmd, active->ch, i, offset);
1831 		RTW89_SET_FWCMD_CXROLE_ACT_TX_LVL(cmd, active->tx_lvl, i, offset);
1832 		RTW89_SET_FWCMD_CXROLE_ACT_RX_LVL(cmd, active->rx_lvl, i, offset);
1833 		RTW89_SET_FWCMD_CXROLE_ACT_TX_RATE(cmd, active->tx_rate, i, offset);
1834 		RTW89_SET_FWCMD_CXROLE_ACT_RX_RATE(cmd, active->rx_rate, i, offset);
1835 	}
1836 
1837 	rtw89_h2c_pkt_set_hdr(rtwdev, skb, FWCMD_TYPE_H2C,
1838 			      H2C_CAT_OUTSRC, BTFC_SET,
1839 			      SET_DRV_INFO, 0, 0,
1840 			      H2C_LEN_CXDRVINFO_ROLE);
1841 
1842 	ret = rtw89_h2c_tx(rtwdev, skb, false);
1843 	if (ret) {
1844 		rtw89_err(rtwdev, "failed to send h2c\n");
1845 		goto fail;
1846 	}
1847 
1848 	return 0;
1849 fail:
1850 	dev_kfree_skb_any(skb);
1851 
1852 	return ret;
1853 }
1854 
1855 int rtw89_fw_h2c_cxdrv_role_v1(struct rtw89_dev *rtwdev)
1856 {
1857 	struct rtw89_btc *btc = &rtwdev->btc;
1858 	struct rtw89_btc_wl_info *wl = &btc->cx.wl;
1859 	struct rtw89_btc_wl_role_info_v1 *role_info = &wl->role_info_v1;
1860 	struct rtw89_btc_wl_role_info_bpos *bpos = &role_info->role_map.role;
1861 	struct rtw89_btc_wl_active_role_v1 *active = role_info->active_role_v1;
1862 	struct sk_buff *skb;
1863 	u8 *cmd, offset;
1864 	int ret;
1865 	int i;
1866 
1867 	skb = rtw89_fw_h2c_alloc_skb_with_hdr(rtwdev, H2C_LEN_CXDRVINFO_ROLE_V1);
1868 	if (!skb) {
1869 		rtw89_err(rtwdev, "failed to alloc skb for h2c cxdrv_role\n");
1870 		return -ENOMEM;
1871 	}
1872 	skb_put(skb, H2C_LEN_CXDRVINFO_ROLE_V1);
1873 	cmd = skb->data;
1874 
1875 	RTW89_SET_FWCMD_CXHDR_TYPE(cmd, CXDRVINFO_ROLE);
1876 	RTW89_SET_FWCMD_CXHDR_LEN(cmd, H2C_LEN_CXDRVINFO_ROLE_V1 - H2C_LEN_CXDRVHDR);
1877 
1878 	RTW89_SET_FWCMD_CXROLE_CONNECT_CNT(cmd, role_info->connect_cnt);
1879 	RTW89_SET_FWCMD_CXROLE_LINK_MODE(cmd, role_info->link_mode);
1880 
1881 	RTW89_SET_FWCMD_CXROLE_ROLE_NONE(cmd, bpos->none);
1882 	RTW89_SET_FWCMD_CXROLE_ROLE_STA(cmd, bpos->station);
1883 	RTW89_SET_FWCMD_CXROLE_ROLE_AP(cmd, bpos->ap);
1884 	RTW89_SET_FWCMD_CXROLE_ROLE_VAP(cmd, bpos->vap);
1885 	RTW89_SET_FWCMD_CXROLE_ROLE_ADHOC(cmd, bpos->adhoc);
1886 	RTW89_SET_FWCMD_CXROLE_ROLE_ADHOC_MASTER(cmd, bpos->adhoc_master);
1887 	RTW89_SET_FWCMD_CXROLE_ROLE_MESH(cmd, bpos->mesh);
1888 	RTW89_SET_FWCMD_CXROLE_ROLE_MONITOR(cmd, bpos->moniter);
1889 	RTW89_SET_FWCMD_CXROLE_ROLE_P2P_DEV(cmd, bpos->p2p_device);
1890 	RTW89_SET_FWCMD_CXROLE_ROLE_P2P_GC(cmd, bpos->p2p_gc);
1891 	RTW89_SET_FWCMD_CXROLE_ROLE_P2P_GO(cmd, bpos->p2p_go);
1892 	RTW89_SET_FWCMD_CXROLE_ROLE_NAN(cmd, bpos->nan);
1893 
1894 	offset = PORT_DATA_OFFSET;
1895 	for (i = 0; i < RTW89_PORT_NUM; i++, active++) {
1896 		RTW89_SET_FWCMD_CXROLE_ACT_CONNECTED(cmd, active->connected, i, offset);
1897 		RTW89_SET_FWCMD_CXROLE_ACT_PID(cmd, active->pid, i, offset);
1898 		RTW89_SET_FWCMD_CXROLE_ACT_PHY(cmd, active->phy, i, offset);
1899 		RTW89_SET_FWCMD_CXROLE_ACT_NOA(cmd, active->noa, i, offset);
1900 		RTW89_SET_FWCMD_CXROLE_ACT_BAND(cmd, active->band, i, offset);
1901 		RTW89_SET_FWCMD_CXROLE_ACT_CLIENT_PS(cmd, active->client_ps, i, offset);
1902 		RTW89_SET_FWCMD_CXROLE_ACT_BW(cmd, active->bw, i, offset);
1903 		RTW89_SET_FWCMD_CXROLE_ACT_ROLE(cmd, active->role, i, offset);
1904 		RTW89_SET_FWCMD_CXROLE_ACT_CH(cmd, active->ch, i, offset);
1905 		RTW89_SET_FWCMD_CXROLE_ACT_TX_LVL(cmd, active->tx_lvl, i, offset);
1906 		RTW89_SET_FWCMD_CXROLE_ACT_RX_LVL(cmd, active->rx_lvl, i, offset);
1907 		RTW89_SET_FWCMD_CXROLE_ACT_TX_RATE(cmd, active->tx_rate, i, offset);
1908 		RTW89_SET_FWCMD_CXROLE_ACT_RX_RATE(cmd, active->rx_rate, i, offset);
1909 		RTW89_SET_FWCMD_CXROLE_ACT_NOA_DUR(cmd, active->noa_duration, i, offset);
1910 	}
1911 
1912 	offset = H2C_LEN_CXDRVINFO_ROLE_V1 - H2C_LEN_CXDRVINFO_ROLE_DBCC_LEN;
1913 	RTW89_SET_FWCMD_CXROLE_MROLE_TYPE(cmd, role_info->mrole_type, offset);
1914 	RTW89_SET_FWCMD_CXROLE_MROLE_NOA(cmd, role_info->mrole_noa_duration, offset);
1915 	RTW89_SET_FWCMD_CXROLE_DBCC_EN(cmd, role_info->dbcc_en, offset);
1916 	RTW89_SET_FWCMD_CXROLE_DBCC_CHG(cmd, role_info->dbcc_chg, offset);
1917 	RTW89_SET_FWCMD_CXROLE_DBCC_2G_PHY(cmd, role_info->dbcc_2g_phy, offset);
1918 	RTW89_SET_FWCMD_CXROLE_LINK_MODE_CHG(cmd, role_info->link_mode_chg, offset);
1919 
1920 	rtw89_h2c_pkt_set_hdr(rtwdev, skb, FWCMD_TYPE_H2C,
1921 			      H2C_CAT_OUTSRC, BTFC_SET,
1922 			      SET_DRV_INFO, 0, 0,
1923 			      H2C_LEN_CXDRVINFO_ROLE_V1);
1924 
1925 	ret = rtw89_h2c_tx(rtwdev, skb, false);
1926 	if (ret) {
1927 		rtw89_err(rtwdev, "failed to send h2c\n");
1928 		goto fail;
1929 	}
1930 
1931 	return 0;
1932 fail:
1933 	dev_kfree_skb_any(skb);
1934 
1935 	return ret;
1936 }
1937 
1938 #define H2C_LEN_CXDRVINFO_CTRL (4 + H2C_LEN_CXDRVHDR)
1939 int rtw89_fw_h2c_cxdrv_ctrl(struct rtw89_dev *rtwdev)
1940 {
1941 	const struct rtw89_chip_info *chip = rtwdev->chip;
1942 	struct rtw89_btc *btc = &rtwdev->btc;
1943 	struct rtw89_btc_ctrl *ctrl = &btc->ctrl;
1944 	struct sk_buff *skb;
1945 	u8 *cmd;
1946 	int ret;
1947 
1948 	skb = rtw89_fw_h2c_alloc_skb_with_hdr(rtwdev, H2C_LEN_CXDRVINFO_CTRL);
1949 	if (!skb) {
1950 		rtw89_err(rtwdev, "failed to alloc skb for h2c cxdrv_ctrl\n");
1951 		return -ENOMEM;
1952 	}
1953 	skb_put(skb, H2C_LEN_CXDRVINFO_CTRL);
1954 	cmd = skb->data;
1955 
1956 	RTW89_SET_FWCMD_CXHDR_TYPE(cmd, CXDRVINFO_CTRL);
1957 	RTW89_SET_FWCMD_CXHDR_LEN(cmd, H2C_LEN_CXDRVINFO_CTRL - H2C_LEN_CXDRVHDR);
1958 
1959 	RTW89_SET_FWCMD_CXCTRL_MANUAL(cmd, ctrl->manual);
1960 	RTW89_SET_FWCMD_CXCTRL_IGNORE_BT(cmd, ctrl->igno_bt);
1961 	RTW89_SET_FWCMD_CXCTRL_ALWAYS_FREERUN(cmd, ctrl->always_freerun);
1962 	if (chip->chip_id == RTL8852A)
1963 		RTW89_SET_FWCMD_CXCTRL_TRACE_STEP(cmd, ctrl->trace_step);
1964 
1965 	rtw89_h2c_pkt_set_hdr(rtwdev, skb, FWCMD_TYPE_H2C,
1966 			      H2C_CAT_OUTSRC, BTFC_SET,
1967 			      SET_DRV_INFO, 0, 0,
1968 			      H2C_LEN_CXDRVINFO_CTRL);
1969 
1970 	ret = rtw89_h2c_tx(rtwdev, skb, false);
1971 	if (ret) {
1972 		rtw89_err(rtwdev, "failed to send h2c\n");
1973 		goto fail;
1974 	}
1975 
1976 	return 0;
1977 fail:
1978 	dev_kfree_skb_any(skb);
1979 
1980 	return ret;
1981 }
1982 
1983 #define H2C_LEN_CXDRVINFO_RFK (4 + H2C_LEN_CXDRVHDR)
1984 int rtw89_fw_h2c_cxdrv_rfk(struct rtw89_dev *rtwdev)
1985 {
1986 	struct rtw89_btc *btc = &rtwdev->btc;
1987 	struct rtw89_btc_wl_info *wl = &btc->cx.wl;
1988 	struct rtw89_btc_wl_rfk_info *rfk_info = &wl->rfk_info;
1989 	struct sk_buff *skb;
1990 	u8 *cmd;
1991 	int ret;
1992 
1993 	skb = rtw89_fw_h2c_alloc_skb_with_hdr(rtwdev, H2C_LEN_CXDRVINFO_RFK);
1994 	if (!skb) {
1995 		rtw89_err(rtwdev, "failed to alloc skb for h2c cxdrv_ctrl\n");
1996 		return -ENOMEM;
1997 	}
1998 	skb_put(skb, H2C_LEN_CXDRVINFO_RFK);
1999 	cmd = skb->data;
2000 
2001 	RTW89_SET_FWCMD_CXHDR_TYPE(cmd, CXDRVINFO_RFK);
2002 	RTW89_SET_FWCMD_CXHDR_LEN(cmd, H2C_LEN_CXDRVINFO_RFK - H2C_LEN_CXDRVHDR);
2003 
2004 	RTW89_SET_FWCMD_CXRFK_STATE(cmd, rfk_info->state);
2005 	RTW89_SET_FWCMD_CXRFK_PATH_MAP(cmd, rfk_info->path_map);
2006 	RTW89_SET_FWCMD_CXRFK_PHY_MAP(cmd, rfk_info->phy_map);
2007 	RTW89_SET_FWCMD_CXRFK_BAND(cmd, rfk_info->band);
2008 	RTW89_SET_FWCMD_CXRFK_TYPE(cmd, rfk_info->type);
2009 
2010 	rtw89_h2c_pkt_set_hdr(rtwdev, skb, FWCMD_TYPE_H2C,
2011 			      H2C_CAT_OUTSRC, BTFC_SET,
2012 			      SET_DRV_INFO, 0, 0,
2013 			      H2C_LEN_CXDRVINFO_RFK);
2014 
2015 	ret = rtw89_h2c_tx(rtwdev, skb, false);
2016 	if (ret) {
2017 		rtw89_err(rtwdev, "failed to send h2c\n");
2018 		goto fail;
2019 	}
2020 
2021 	return 0;
2022 fail:
2023 	dev_kfree_skb_any(skb);
2024 
2025 	return ret;
2026 }
2027 
2028 #define H2C_LEN_PKT_OFLD 4
2029 int rtw89_fw_h2c_del_pkt_offload(struct rtw89_dev *rtwdev, u8 id)
2030 {
2031 	struct sk_buff *skb;
2032 	u8 *cmd;
2033 	int ret;
2034 
2035 	skb = rtw89_fw_h2c_alloc_skb_with_hdr(rtwdev, H2C_LEN_PKT_OFLD);
2036 	if (!skb) {
2037 		rtw89_err(rtwdev, "failed to alloc skb for h2c pkt offload\n");
2038 		return -ENOMEM;
2039 	}
2040 	skb_put(skb, H2C_LEN_PKT_OFLD);
2041 	cmd = skb->data;
2042 
2043 	RTW89_SET_FWCMD_PACKET_OFLD_PKT_IDX(cmd, id);
2044 	RTW89_SET_FWCMD_PACKET_OFLD_PKT_OP(cmd, RTW89_PKT_OFLD_OP_DEL);
2045 
2046 	rtw89_h2c_pkt_set_hdr(rtwdev, skb, FWCMD_TYPE_H2C,
2047 			      H2C_CAT_MAC, H2C_CL_MAC_FW_OFLD,
2048 			      H2C_FUNC_PACKET_OFLD, 1, 1,
2049 			      H2C_LEN_PKT_OFLD);
2050 
2051 	ret = rtw89_h2c_tx(rtwdev, skb, false);
2052 	if (ret) {
2053 		rtw89_err(rtwdev, "failed to send h2c\n");
2054 		goto fail;
2055 	}
2056 
2057 	return 0;
2058 fail:
2059 	dev_kfree_skb_any(skb);
2060 
2061 	return ret;
2062 }
2063 
2064 int rtw89_fw_h2c_add_pkt_offload(struct rtw89_dev *rtwdev, u8 *id,
2065 				 struct sk_buff *skb_ofld)
2066 {
2067 	struct sk_buff *skb;
2068 	u8 *cmd;
2069 	u8 alloc_id;
2070 	int ret;
2071 
2072 	alloc_id = rtw89_core_acquire_bit_map(rtwdev->pkt_offload,
2073 					      RTW89_MAX_PKT_OFLD_NUM);
2074 	if (alloc_id == RTW89_MAX_PKT_OFLD_NUM)
2075 		return -ENOSPC;
2076 
2077 	*id = alloc_id;
2078 
2079 	skb = rtw89_fw_h2c_alloc_skb_with_hdr(rtwdev, H2C_LEN_PKT_OFLD + skb_ofld->len);
2080 	if (!skb) {
2081 		rtw89_err(rtwdev, "failed to alloc skb for h2c pkt offload\n");
2082 		return -ENOMEM;
2083 	}
2084 	skb_put(skb, H2C_LEN_PKT_OFLD);
2085 	cmd = skb->data;
2086 
2087 	RTW89_SET_FWCMD_PACKET_OFLD_PKT_IDX(cmd, alloc_id);
2088 	RTW89_SET_FWCMD_PACKET_OFLD_PKT_OP(cmd, RTW89_PKT_OFLD_OP_ADD);
2089 	RTW89_SET_FWCMD_PACKET_OFLD_PKT_LENGTH(cmd, skb_ofld->len);
2090 	skb_put_data(skb, skb_ofld->data, skb_ofld->len);
2091 
2092 	rtw89_h2c_pkt_set_hdr(rtwdev, skb, FWCMD_TYPE_H2C,
2093 			      H2C_CAT_MAC, H2C_CL_MAC_FW_OFLD,
2094 			      H2C_FUNC_PACKET_OFLD, 1, 1,
2095 			      H2C_LEN_PKT_OFLD + skb_ofld->len);
2096 
2097 	ret = rtw89_h2c_tx(rtwdev, skb, false);
2098 	if (ret) {
2099 		rtw89_err(rtwdev, "failed to send h2c\n");
2100 		goto fail;
2101 	}
2102 
2103 	return 0;
2104 fail:
2105 	dev_kfree_skb_any(skb);
2106 
2107 	return ret;
2108 }
2109 
2110 #define H2C_LEN_SCAN_LIST_OFFLOAD 4
2111 int rtw89_fw_h2c_scan_list_offload(struct rtw89_dev *rtwdev, int len,
2112 				   struct list_head *chan_list)
2113 {
2114 	struct rtw89_mac_chinfo *ch_info;
2115 	struct sk_buff *skb;
2116 	int skb_len = H2C_LEN_SCAN_LIST_OFFLOAD + len * RTW89_MAC_CHINFO_SIZE;
2117 	u8 *cmd;
2118 	int ret;
2119 
2120 	skb = rtw89_fw_h2c_alloc_skb_with_hdr(rtwdev, skb_len);
2121 	if (!skb) {
2122 		rtw89_err(rtwdev, "failed to alloc skb for h2c scan list\n");
2123 		return -ENOMEM;
2124 	}
2125 	skb_put(skb, H2C_LEN_SCAN_LIST_OFFLOAD);
2126 	cmd = skb->data;
2127 
2128 	RTW89_SET_FWCMD_SCANOFLD_CH_NUM(cmd, len);
2129 	/* in unit of 4 bytes */
2130 	RTW89_SET_FWCMD_SCANOFLD_CH_SIZE(cmd, RTW89_MAC_CHINFO_SIZE / 4);
2131 
2132 	list_for_each_entry(ch_info, chan_list, list) {
2133 		cmd = skb_put(skb, RTW89_MAC_CHINFO_SIZE);
2134 
2135 		RTW89_SET_FWCMD_CHINFO_PERIOD(cmd, ch_info->period);
2136 		RTW89_SET_FWCMD_CHINFO_DWELL(cmd, ch_info->dwell_time);
2137 		RTW89_SET_FWCMD_CHINFO_CENTER_CH(cmd, ch_info->central_ch);
2138 		RTW89_SET_FWCMD_CHINFO_PRI_CH(cmd, ch_info->pri_ch);
2139 		RTW89_SET_FWCMD_CHINFO_BW(cmd, ch_info->bw);
2140 		RTW89_SET_FWCMD_CHINFO_ACTION(cmd, ch_info->notify_action);
2141 		RTW89_SET_FWCMD_CHINFO_NUM_PKT(cmd, ch_info->num_pkt);
2142 		RTW89_SET_FWCMD_CHINFO_TX(cmd, ch_info->tx_pkt);
2143 		RTW89_SET_FWCMD_CHINFO_PAUSE_DATA(cmd, ch_info->pause_data);
2144 		RTW89_SET_FWCMD_CHINFO_BAND(cmd, ch_info->ch_band);
2145 		RTW89_SET_FWCMD_CHINFO_PKT_ID(cmd, ch_info->probe_id);
2146 		RTW89_SET_FWCMD_CHINFO_DFS(cmd, ch_info->dfs_ch);
2147 		RTW89_SET_FWCMD_CHINFO_TX_NULL(cmd, ch_info->tx_null);
2148 		RTW89_SET_FWCMD_CHINFO_RANDOM(cmd, ch_info->rand_seq_num);
2149 		RTW89_SET_FWCMD_CHINFO_PKT0(cmd, ch_info->pkt_id[0]);
2150 		RTW89_SET_FWCMD_CHINFO_PKT1(cmd, ch_info->pkt_id[1]);
2151 		RTW89_SET_FWCMD_CHINFO_PKT2(cmd, ch_info->pkt_id[2]);
2152 		RTW89_SET_FWCMD_CHINFO_PKT3(cmd, ch_info->pkt_id[3]);
2153 		RTW89_SET_FWCMD_CHINFO_PKT4(cmd, ch_info->pkt_id[4]);
2154 		RTW89_SET_FWCMD_CHINFO_PKT5(cmd, ch_info->pkt_id[5]);
2155 		RTW89_SET_FWCMD_CHINFO_PKT6(cmd, ch_info->pkt_id[6]);
2156 		RTW89_SET_FWCMD_CHINFO_PKT7(cmd, ch_info->pkt_id[7]);
2157 	}
2158 
2159 	rtw89_h2c_pkt_set_hdr(rtwdev, skb, FWCMD_TYPE_H2C,
2160 			      H2C_CAT_MAC, H2C_CL_MAC_FW_OFLD,
2161 			      H2C_FUNC_ADD_SCANOFLD_CH, 1, 1, skb_len);
2162 
2163 	ret = rtw89_h2c_tx(rtwdev, skb, false);
2164 	if (ret) {
2165 		rtw89_err(rtwdev, "failed to send h2c\n");
2166 		goto fail;
2167 	}
2168 
2169 	return 0;
2170 fail:
2171 	dev_kfree_skb_any(skb);
2172 
2173 	return ret;
2174 }
2175 
2176 #define H2C_LEN_SCAN_OFFLOAD 28
2177 int rtw89_fw_h2c_scan_offload(struct rtw89_dev *rtwdev,
2178 			      struct rtw89_scan_option *option,
2179 			      struct rtw89_vif *rtwvif)
2180 {
2181 	struct rtw89_hw_scan_info *scan_info = &rtwdev->scan_info;
2182 	struct sk_buff *skb;
2183 	u8 *cmd;
2184 	int ret;
2185 
2186 	skb = rtw89_fw_h2c_alloc_skb_with_hdr(rtwdev, H2C_LEN_SCAN_OFFLOAD);
2187 	if (!skb) {
2188 		rtw89_err(rtwdev, "failed to alloc skb for h2c scan offload\n");
2189 		return -ENOMEM;
2190 	}
2191 	skb_put(skb, H2C_LEN_SCAN_OFFLOAD);
2192 	cmd = skb->data;
2193 
2194 	RTW89_SET_FWCMD_SCANOFLD_MACID(cmd, rtwvif->mac_id);
2195 	RTW89_SET_FWCMD_SCANOFLD_PORT_ID(cmd, rtwvif->port);
2196 	RTW89_SET_FWCMD_SCANOFLD_BAND(cmd, RTW89_PHY_0);
2197 	RTW89_SET_FWCMD_SCANOFLD_OPERATION(cmd, option->enable);
2198 	RTW89_SET_FWCMD_SCANOFLD_NOTIFY_END(cmd, true);
2199 	RTW89_SET_FWCMD_SCANOFLD_TARGET_CH_MODE(cmd, option->target_ch_mode);
2200 	RTW89_SET_FWCMD_SCANOFLD_START_MODE(cmd, RTW89_SCAN_IMMEDIATE);
2201 	RTW89_SET_FWCMD_SCANOFLD_SCAN_TYPE(cmd, RTW89_SCAN_ONCE);
2202 	if (option->target_ch_mode) {
2203 		RTW89_SET_FWCMD_SCANOFLD_TARGET_CH_BW(cmd, scan_info->op_bw);
2204 		RTW89_SET_FWCMD_SCANOFLD_TARGET_PRI_CH(cmd,
2205 						       scan_info->op_pri_ch);
2206 		RTW89_SET_FWCMD_SCANOFLD_TARGET_CENTRAL_CH(cmd,
2207 							   scan_info->op_chan);
2208 		RTW89_SET_FWCMD_SCANOFLD_TARGET_CH_BAND(cmd,
2209 							scan_info->op_band);
2210 	}
2211 
2212 	rtw89_h2c_pkt_set_hdr(rtwdev, skb, FWCMD_TYPE_H2C,
2213 			      H2C_CAT_MAC, H2C_CL_MAC_FW_OFLD,
2214 			      H2C_FUNC_SCANOFLD, 1, 1,
2215 			      H2C_LEN_SCAN_OFFLOAD);
2216 
2217 	ret = rtw89_h2c_tx(rtwdev, skb, false);
2218 	if (ret) {
2219 		rtw89_err(rtwdev, "failed to send h2c\n");
2220 		goto fail;
2221 	}
2222 
2223 	return 0;
2224 fail:
2225 	dev_kfree_skb_any(skb);
2226 
2227 	return ret;
2228 }
2229 
2230 int rtw89_fw_h2c_rf_reg(struct rtw89_dev *rtwdev,
2231 			struct rtw89_fw_h2c_rf_reg_info *info,
2232 			u16 len, u8 page)
2233 {
2234 	struct sk_buff *skb;
2235 	u8 class = info->rf_path == RF_PATH_A ?
2236 		   H2C_CL_OUTSRC_RF_REG_A : H2C_CL_OUTSRC_RF_REG_B;
2237 	int ret;
2238 
2239 	skb = rtw89_fw_h2c_alloc_skb_with_hdr(rtwdev, len);
2240 	if (!skb) {
2241 		rtw89_err(rtwdev, "failed to alloc skb for h2c rf reg\n");
2242 		return -ENOMEM;
2243 	}
2244 	skb_put_data(skb, info->rtw89_phy_config_rf_h2c[page], len);
2245 
2246 	rtw89_h2c_pkt_set_hdr(rtwdev, skb, FWCMD_TYPE_H2C,
2247 			      H2C_CAT_OUTSRC, class, page, 0, 0,
2248 			      len);
2249 
2250 	ret = rtw89_h2c_tx(rtwdev, skb, false);
2251 	if (ret) {
2252 		rtw89_err(rtwdev, "failed to send h2c\n");
2253 		goto fail;
2254 	}
2255 
2256 	return 0;
2257 fail:
2258 	dev_kfree_skb_any(skb);
2259 
2260 	return ret;
2261 }
2262 
2263 int rtw89_fw_h2c_rf_ntfy_mcc(struct rtw89_dev *rtwdev)
2264 {
2265 	const struct rtw89_chan *chan = rtw89_chan_get(rtwdev, RTW89_SUB_ENTITY_0);
2266 	struct rtw89_mcc_info *mcc_info = &rtwdev->mcc;
2267 	struct rtw89_fw_h2c_rf_get_mccch *mccch;
2268 	struct sk_buff *skb;
2269 	int ret;
2270 
2271 	skb = rtw89_fw_h2c_alloc_skb_with_hdr(rtwdev, sizeof(*mccch));
2272 	if (!skb) {
2273 		rtw89_err(rtwdev, "failed to alloc skb for h2c cxdrv_ctrl\n");
2274 		return -ENOMEM;
2275 	}
2276 	skb_put(skb, sizeof(*mccch));
2277 	mccch = (struct rtw89_fw_h2c_rf_get_mccch *)skb->data;
2278 
2279 	mccch->ch_0 = cpu_to_le32(mcc_info->ch[0]);
2280 	mccch->ch_1 = cpu_to_le32(mcc_info->ch[1]);
2281 	mccch->band_0 = cpu_to_le32(mcc_info->band[0]);
2282 	mccch->band_1 = cpu_to_le32(mcc_info->band[1]);
2283 	mccch->current_channel = cpu_to_le32(chan->channel);
2284 	mccch->current_band_type = cpu_to_le32(chan->band_type);
2285 
2286 	rtw89_h2c_pkt_set_hdr(rtwdev, skb, FWCMD_TYPE_H2C,
2287 			      H2C_CAT_OUTSRC, H2C_CL_OUTSRC_RF_FW_NOTIFY,
2288 			      H2C_FUNC_OUTSRC_RF_GET_MCCCH, 0, 0,
2289 			      sizeof(*mccch));
2290 
2291 	ret = rtw89_h2c_tx(rtwdev, skb, false);
2292 	if (ret) {
2293 		rtw89_err(rtwdev, "failed to send h2c\n");
2294 		goto fail;
2295 	}
2296 
2297 	return 0;
2298 fail:
2299 	dev_kfree_skb_any(skb);
2300 
2301 	return ret;
2302 }
2303 EXPORT_SYMBOL(rtw89_fw_h2c_rf_ntfy_mcc);
2304 
2305 int rtw89_fw_h2c_raw_with_hdr(struct rtw89_dev *rtwdev,
2306 			      u8 h2c_class, u8 h2c_func, u8 *buf, u16 len,
2307 			      bool rack, bool dack)
2308 {
2309 	struct sk_buff *skb;
2310 	int ret;
2311 
2312 	skb = rtw89_fw_h2c_alloc_skb_with_hdr(rtwdev, len);
2313 	if (!skb) {
2314 		rtw89_err(rtwdev, "failed to alloc skb for raw with hdr\n");
2315 		return -ENOMEM;
2316 	}
2317 	skb_put_data(skb, buf, len);
2318 
2319 	rtw89_h2c_pkt_set_hdr(rtwdev, skb, FWCMD_TYPE_H2C,
2320 			      H2C_CAT_OUTSRC, h2c_class, h2c_func, rack, dack,
2321 			      len);
2322 
2323 	ret = rtw89_h2c_tx(rtwdev, skb, false);
2324 	if (ret) {
2325 		rtw89_err(rtwdev, "failed to send h2c\n");
2326 		goto fail;
2327 	}
2328 
2329 	return 0;
2330 fail:
2331 	dev_kfree_skb_any(skb);
2332 
2333 	return ret;
2334 }
2335 
2336 int rtw89_fw_h2c_raw(struct rtw89_dev *rtwdev, const u8 *buf, u16 len)
2337 {
2338 	struct sk_buff *skb;
2339 	int ret;
2340 
2341 	skb = rtw89_fw_h2c_alloc_skb_no_hdr(rtwdev, len);
2342 	if (!skb) {
2343 		rtw89_err(rtwdev, "failed to alloc skb for h2c raw\n");
2344 		return -ENOMEM;
2345 	}
2346 	skb_put_data(skb, buf, len);
2347 
2348 	ret = rtw89_h2c_tx(rtwdev, skb, false);
2349 	if (ret) {
2350 		rtw89_err(rtwdev, "failed to send h2c\n");
2351 		goto fail;
2352 	}
2353 
2354 	return 0;
2355 fail:
2356 	dev_kfree_skb_any(skb);
2357 
2358 	return ret;
2359 }
2360 
2361 void rtw89_fw_send_all_early_h2c(struct rtw89_dev *rtwdev)
2362 {
2363 	struct rtw89_early_h2c *early_h2c;
2364 
2365 	lockdep_assert_held(&rtwdev->mutex);
2366 
2367 	list_for_each_entry(early_h2c, &rtwdev->early_h2c_list, list) {
2368 		rtw89_fw_h2c_raw(rtwdev, early_h2c->h2c, early_h2c->h2c_len);
2369 	}
2370 }
2371 
2372 void rtw89_fw_free_all_early_h2c(struct rtw89_dev *rtwdev)
2373 {
2374 	struct rtw89_early_h2c *early_h2c, *tmp;
2375 
2376 	mutex_lock(&rtwdev->mutex);
2377 	list_for_each_entry_safe(early_h2c, tmp, &rtwdev->early_h2c_list, list) {
2378 		list_del(&early_h2c->list);
2379 		kfree(early_h2c->h2c);
2380 		kfree(early_h2c);
2381 	}
2382 	mutex_unlock(&rtwdev->mutex);
2383 }
2384 
2385 void rtw89_fw_c2h_irqsafe(struct rtw89_dev *rtwdev, struct sk_buff *c2h)
2386 {
2387 	skb_queue_tail(&rtwdev->c2h_queue, c2h);
2388 	ieee80211_queue_work(rtwdev->hw, &rtwdev->c2h_work);
2389 }
2390 
2391 static void rtw89_fw_c2h_cmd_handle(struct rtw89_dev *rtwdev,
2392 				    struct sk_buff *skb)
2393 {
2394 	u8 category = RTW89_GET_C2H_CATEGORY(skb->data);
2395 	u8 class = RTW89_GET_C2H_CLASS(skb->data);
2396 	u8 func = RTW89_GET_C2H_FUNC(skb->data);
2397 	u16 len = RTW89_GET_C2H_LEN(skb->data);
2398 	bool dump = true;
2399 
2400 	if (!test_bit(RTW89_FLAG_RUNNING, rtwdev->flags))
2401 		return;
2402 
2403 	switch (category) {
2404 	case RTW89_C2H_CAT_TEST:
2405 		break;
2406 	case RTW89_C2H_CAT_MAC:
2407 		rtw89_mac_c2h_handle(rtwdev, skb, len, class, func);
2408 		if (class == RTW89_MAC_C2H_CLASS_INFO &&
2409 		    func == RTW89_MAC_C2H_FUNC_C2H_LOG)
2410 			dump = false;
2411 		break;
2412 	case RTW89_C2H_CAT_OUTSRC:
2413 		if (class >= RTW89_PHY_C2H_CLASS_BTC_MIN &&
2414 		    class <= RTW89_PHY_C2H_CLASS_BTC_MAX)
2415 			rtw89_btc_c2h_handle(rtwdev, skb, len, class, func);
2416 		else
2417 			rtw89_phy_c2h_handle(rtwdev, skb, len, class, func);
2418 		break;
2419 	}
2420 
2421 	if (dump)
2422 		rtw89_hex_dump(rtwdev, RTW89_DBG_FW, "C2H: ", skb->data, skb->len);
2423 }
2424 
2425 void rtw89_fw_c2h_work(struct work_struct *work)
2426 {
2427 	struct rtw89_dev *rtwdev = container_of(work, struct rtw89_dev,
2428 						c2h_work);
2429 	struct sk_buff *skb, *tmp;
2430 
2431 	skb_queue_walk_safe(&rtwdev->c2h_queue, skb, tmp) {
2432 		skb_unlink(skb, &rtwdev->c2h_queue);
2433 		mutex_lock(&rtwdev->mutex);
2434 		rtw89_fw_c2h_cmd_handle(rtwdev, skb);
2435 		mutex_unlock(&rtwdev->mutex);
2436 		dev_kfree_skb_any(skb);
2437 	}
2438 }
2439 
2440 static int rtw89_fw_write_h2c_reg(struct rtw89_dev *rtwdev,
2441 				  struct rtw89_mac_h2c_info *info)
2442 {
2443 	const struct rtw89_chip_info *chip = rtwdev->chip;
2444 	const u32 *h2c_reg = chip->h2c_regs;
2445 	u8 i, val, len;
2446 	int ret;
2447 
2448 	ret = read_poll_timeout(rtw89_read8, val, val == 0, 1000, 5000, false,
2449 				rtwdev, chip->h2c_ctrl_reg);
2450 	if (ret) {
2451 		rtw89_warn(rtwdev, "FW does not process h2c registers\n");
2452 		return ret;
2453 	}
2454 
2455 	len = DIV_ROUND_UP(info->content_len + RTW89_H2CREG_HDR_LEN,
2456 			   sizeof(info->h2creg[0]));
2457 
2458 	RTW89_SET_H2CREG_HDR_FUNC(&info->h2creg[0], info->id);
2459 	RTW89_SET_H2CREG_HDR_LEN(&info->h2creg[0], len);
2460 	for (i = 0; i < RTW89_H2CREG_MAX; i++)
2461 		rtw89_write32(rtwdev, h2c_reg[i], info->h2creg[i]);
2462 
2463 	rtw89_write8(rtwdev, chip->h2c_ctrl_reg, B_AX_H2CREG_TRIGGER);
2464 
2465 	return 0;
2466 }
2467 
2468 static int rtw89_fw_read_c2h_reg(struct rtw89_dev *rtwdev,
2469 				 struct rtw89_mac_c2h_info *info)
2470 {
2471 	const struct rtw89_chip_info *chip = rtwdev->chip;
2472 	const u32 *c2h_reg = chip->c2h_regs;
2473 	u32 ret;
2474 	u8 i, val;
2475 
2476 	info->id = RTW89_FWCMD_C2HREG_FUNC_NULL;
2477 
2478 	ret = read_poll_timeout_atomic(rtw89_read8, val, val, 1,
2479 				       RTW89_C2H_TIMEOUT, false, rtwdev,
2480 				       chip->c2h_ctrl_reg);
2481 	if (ret) {
2482 		rtw89_warn(rtwdev, "c2h reg timeout\n");
2483 		return ret;
2484 	}
2485 
2486 	for (i = 0; i < RTW89_C2HREG_MAX; i++)
2487 		info->c2hreg[i] = rtw89_read32(rtwdev, c2h_reg[i]);
2488 
2489 	rtw89_write8(rtwdev, chip->c2h_ctrl_reg, 0);
2490 
2491 	info->id = RTW89_GET_C2H_HDR_FUNC(*info->c2hreg);
2492 	info->content_len = (RTW89_GET_C2H_HDR_LEN(*info->c2hreg) << 2) -
2493 				RTW89_C2HREG_HDR_LEN;
2494 
2495 	return 0;
2496 }
2497 
2498 int rtw89_fw_msg_reg(struct rtw89_dev *rtwdev,
2499 		     struct rtw89_mac_h2c_info *h2c_info,
2500 		     struct rtw89_mac_c2h_info *c2h_info)
2501 {
2502 	u32 ret;
2503 
2504 	if (h2c_info && h2c_info->id != RTW89_FWCMD_H2CREG_FUNC_GET_FEATURE)
2505 		lockdep_assert_held(&rtwdev->mutex);
2506 
2507 	if (!h2c_info && !c2h_info)
2508 		return -EINVAL;
2509 
2510 	if (!h2c_info)
2511 		goto recv_c2h;
2512 
2513 	ret = rtw89_fw_write_h2c_reg(rtwdev, h2c_info);
2514 	if (ret)
2515 		return ret;
2516 
2517 recv_c2h:
2518 	if (!c2h_info)
2519 		return 0;
2520 
2521 	ret = rtw89_fw_read_c2h_reg(rtwdev, c2h_info);
2522 	if (ret)
2523 		return ret;
2524 
2525 	return 0;
2526 }
2527 
2528 void rtw89_fw_st_dbg_dump(struct rtw89_dev *rtwdev)
2529 {
2530 	if (!test_bit(RTW89_FLAG_POWERON, rtwdev->flags)) {
2531 		rtw89_err(rtwdev, "[ERR]pwr is off\n");
2532 		return;
2533 	}
2534 
2535 	rtw89_info(rtwdev, "FW status = 0x%x\n", rtw89_read32(rtwdev, R_AX_UDM0));
2536 	rtw89_info(rtwdev, "FW BADADDR = 0x%x\n", rtw89_read32(rtwdev, R_AX_UDM1));
2537 	rtw89_info(rtwdev, "FW EPC/RA = 0x%x\n", rtw89_read32(rtwdev, R_AX_UDM2));
2538 	rtw89_info(rtwdev, "FW MISC = 0x%x\n", rtw89_read32(rtwdev, R_AX_UDM3));
2539 	rtw89_info(rtwdev, "R_AX_HALT_C2H = 0x%x\n",
2540 		   rtw89_read32(rtwdev, R_AX_HALT_C2H));
2541 	rtw89_info(rtwdev, "R_AX_SER_DBG_INFO = 0x%x\n",
2542 		   rtw89_read32(rtwdev, R_AX_SER_DBG_INFO));
2543 
2544 	rtw89_fw_prog_cnt_dump(rtwdev);
2545 }
2546 
2547 static void rtw89_release_pkt_list(struct rtw89_dev *rtwdev)
2548 {
2549 	struct list_head *pkt_list = rtwdev->scan_info.pkt_list;
2550 	struct rtw89_pktofld_info *info, *tmp;
2551 	u8 idx;
2552 
2553 	for (idx = NL80211_BAND_2GHZ; idx < NUM_NL80211_BANDS; idx++) {
2554 		if (!(rtwdev->chip->support_bands & BIT(idx)))
2555 			continue;
2556 
2557 		list_for_each_entry_safe(info, tmp, &pkt_list[idx], list) {
2558 			rtw89_fw_h2c_del_pkt_offload(rtwdev, info->id);
2559 			rtw89_core_release_bit_map(rtwdev->pkt_offload,
2560 						   info->id);
2561 			list_del(&info->list);
2562 			kfree(info);
2563 		}
2564 	}
2565 }
2566 
2567 static int rtw89_append_probe_req_ie(struct rtw89_dev *rtwdev,
2568 				     struct rtw89_vif *rtwvif,
2569 				     struct sk_buff *skb)
2570 {
2571 	struct rtw89_hw_scan_info *scan_info = &rtwdev->scan_info;
2572 	struct ieee80211_scan_ies *ies = rtwvif->scan_ies;
2573 	struct rtw89_pktofld_info *info;
2574 	struct sk_buff *new;
2575 	int ret = 0;
2576 	u8 band;
2577 
2578 	for (band = NL80211_BAND_2GHZ; band < NUM_NL80211_BANDS; band++) {
2579 		if (!(rtwdev->chip->support_bands & BIT(band)))
2580 			continue;
2581 
2582 		new = skb_copy(skb, GFP_KERNEL);
2583 		if (!new) {
2584 			ret = -ENOMEM;
2585 			goto out;
2586 		}
2587 		skb_put_data(new, ies->ies[band], ies->len[band]);
2588 		skb_put_data(new, ies->common_ies, ies->common_ie_len);
2589 
2590 		info = kzalloc(sizeof(*info), GFP_KERNEL);
2591 		if (!info) {
2592 			ret = -ENOMEM;
2593 			kfree_skb(new);
2594 			goto out;
2595 		}
2596 
2597 		list_add_tail(&info->list, &scan_info->pkt_list[band]);
2598 		ret = rtw89_fw_h2c_add_pkt_offload(rtwdev, &info->id, new);
2599 		if (ret)
2600 			goto out;
2601 
2602 		kfree_skb(new);
2603 	}
2604 out:
2605 	return ret;
2606 }
2607 
2608 static int rtw89_hw_scan_update_probe_req(struct rtw89_dev *rtwdev,
2609 					  struct rtw89_vif *rtwvif)
2610 {
2611 	struct cfg80211_scan_request *req = rtwvif->scan_req;
2612 	struct sk_buff *skb;
2613 	u8 num = req->n_ssids, i;
2614 	int ret;
2615 
2616 	for (i = 0; i < num; i++) {
2617 		skb = ieee80211_probereq_get(rtwdev->hw, rtwvif->mac_addr,
2618 					     req->ssids[i].ssid,
2619 					     req->ssids[i].ssid_len,
2620 					     req->ie_len);
2621 		if (!skb)
2622 			return -ENOMEM;
2623 
2624 		ret = rtw89_append_probe_req_ie(rtwdev, rtwvif, skb);
2625 		kfree_skb(skb);
2626 
2627 		if (ret)
2628 			return ret;
2629 	}
2630 
2631 	return 0;
2632 }
2633 
2634 static void rtw89_hw_scan_add_chan(struct rtw89_dev *rtwdev, int chan_type,
2635 				   int ssid_num,
2636 				   struct rtw89_mac_chinfo *ch_info)
2637 {
2638 	struct rtw89_hw_scan_info *scan_info = &rtwdev->scan_info;
2639 	struct ieee80211_vif *vif = rtwdev->scan_info.scanning_vif;
2640 	struct rtw89_vif *rtwvif = (struct rtw89_vif *)vif->drv_priv;
2641 	struct cfg80211_scan_request *req = rtwvif->scan_req;
2642 	struct rtw89_pktofld_info *info;
2643 	u8 band, probe_count = 0;
2644 
2645 	ch_info->notify_action = RTW89_SCANOFLD_DEBUG_MASK;
2646 	ch_info->dfs_ch = chan_type == RTW89_CHAN_DFS;
2647 	ch_info->bw = RTW89_SCAN_WIDTH;
2648 	ch_info->tx_pkt = true;
2649 	ch_info->cfg_tx_pwr = false;
2650 	ch_info->tx_pwr_idx = 0;
2651 	ch_info->tx_null = false;
2652 	ch_info->pause_data = false;
2653 	ch_info->probe_id = RTW89_SCANOFLD_PKT_NONE;
2654 
2655 	if (ssid_num) {
2656 		ch_info->num_pkt = ssid_num;
2657 		band = rtw89_hw_to_nl80211_band(ch_info->ch_band);
2658 
2659 		list_for_each_entry(info, &scan_info->pkt_list[band], list) {
2660 			ch_info->pkt_id[probe_count] = info->id;
2661 			if (++probe_count >= ssid_num)
2662 				break;
2663 		}
2664 		if (probe_count != ssid_num)
2665 			rtw89_err(rtwdev, "SSID num differs from list len\n");
2666 	}
2667 
2668 	if (ch_info->ch_band == RTW89_BAND_6G) {
2669 		if (ssid_num == 1 && req->ssids[0].ssid_len == 0) {
2670 			ch_info->tx_pkt = false;
2671 			if (!req->duration_mandatory)
2672 				ch_info->period -= RTW89_DWELL_TIME;
2673 		}
2674 	}
2675 
2676 	switch (chan_type) {
2677 	case RTW89_CHAN_OPERATE:
2678 		ch_info->central_ch = scan_info->op_chan;
2679 		ch_info->pri_ch = scan_info->op_pri_ch;
2680 		ch_info->ch_band = scan_info->op_band;
2681 		ch_info->bw = scan_info->op_bw;
2682 		ch_info->tx_null = true;
2683 		ch_info->num_pkt = 0;
2684 		break;
2685 	case RTW89_CHAN_DFS:
2686 		if (ch_info->ch_band != RTW89_BAND_6G)
2687 			ch_info->period = max_t(u8, ch_info->period,
2688 						RTW89_DFS_CHAN_TIME);
2689 		ch_info->dwell_time = RTW89_DWELL_TIME;
2690 		break;
2691 	case RTW89_CHAN_ACTIVE:
2692 		break;
2693 	default:
2694 		rtw89_err(rtwdev, "Channel type out of bound\n");
2695 	}
2696 }
2697 
2698 static int rtw89_hw_scan_add_chan_list(struct rtw89_dev *rtwdev,
2699 				       struct rtw89_vif *rtwvif)
2700 {
2701 	struct cfg80211_scan_request *req = rtwvif->scan_req;
2702 	struct rtw89_mac_chinfo	*ch_info, *tmp;
2703 	struct ieee80211_channel *channel;
2704 	struct list_head chan_list;
2705 	bool random_seq = req->flags & NL80211_SCAN_FLAG_RANDOM_SN;
2706 	int list_len, off_chan_time = 0;
2707 	enum rtw89_chan_type type;
2708 	int ret = 0;
2709 	u32 idx;
2710 
2711 	INIT_LIST_HEAD(&chan_list);
2712 	for (idx = rtwdev->scan_info.last_chan_idx, list_len = 0;
2713 	     idx < req->n_channels && list_len < RTW89_SCAN_LIST_LIMIT;
2714 	     idx++, list_len++) {
2715 		channel = req->channels[idx];
2716 		ch_info = kzalloc(sizeof(*ch_info), GFP_KERNEL);
2717 		if (!ch_info) {
2718 			ret = -ENOMEM;
2719 			goto out;
2720 		}
2721 
2722 		if (req->duration_mandatory)
2723 			ch_info->period = req->duration;
2724 		else if (channel->band == NL80211_BAND_6GHZ)
2725 			ch_info->period = RTW89_CHANNEL_TIME_6G + RTW89_DWELL_TIME;
2726 		else
2727 			ch_info->period = RTW89_CHANNEL_TIME;
2728 
2729 		ch_info->ch_band = rtw89_nl80211_to_hw_band(channel->band);
2730 		ch_info->central_ch = channel->hw_value;
2731 		ch_info->pri_ch = channel->hw_value;
2732 		ch_info->rand_seq_num = random_seq;
2733 
2734 		if (channel->flags &
2735 		    (IEEE80211_CHAN_RADAR | IEEE80211_CHAN_NO_IR))
2736 			type = RTW89_CHAN_DFS;
2737 		else
2738 			type = RTW89_CHAN_ACTIVE;
2739 		rtw89_hw_scan_add_chan(rtwdev, type, req->n_ssids, ch_info);
2740 
2741 		if (rtwvif->net_type != RTW89_NET_TYPE_NO_LINK &&
2742 		    off_chan_time + ch_info->period > RTW89_OFF_CHAN_TIME) {
2743 			tmp = kzalloc(sizeof(*tmp), GFP_KERNEL);
2744 			if (!tmp) {
2745 				ret = -ENOMEM;
2746 				kfree(ch_info);
2747 				goto out;
2748 			}
2749 
2750 			type = RTW89_CHAN_OPERATE;
2751 			tmp->period = req->duration_mandatory ?
2752 				      req->duration : RTW89_CHANNEL_TIME;
2753 			rtw89_hw_scan_add_chan(rtwdev, type, 0, tmp);
2754 			list_add_tail(&tmp->list, &chan_list);
2755 			off_chan_time = 0;
2756 			list_len++;
2757 		}
2758 		list_add_tail(&ch_info->list, &chan_list);
2759 		off_chan_time += ch_info->period;
2760 	}
2761 	rtwdev->scan_info.last_chan_idx = idx;
2762 	ret = rtw89_fw_h2c_scan_list_offload(rtwdev, list_len, &chan_list);
2763 
2764 out:
2765 	list_for_each_entry_safe(ch_info, tmp, &chan_list, list) {
2766 		list_del(&ch_info->list);
2767 		kfree(ch_info);
2768 	}
2769 
2770 	return ret;
2771 }
2772 
2773 static int rtw89_hw_scan_prehandle(struct rtw89_dev *rtwdev,
2774 				   struct rtw89_vif *rtwvif)
2775 {
2776 	int ret;
2777 
2778 	ret = rtw89_hw_scan_update_probe_req(rtwdev, rtwvif);
2779 	if (ret) {
2780 		rtw89_err(rtwdev, "Update probe request failed\n");
2781 		goto out;
2782 	}
2783 	ret = rtw89_hw_scan_add_chan_list(rtwdev, rtwvif);
2784 out:
2785 	return ret;
2786 }
2787 
2788 void rtw89_hw_scan_start(struct rtw89_dev *rtwdev, struct ieee80211_vif *vif,
2789 			 struct ieee80211_scan_request *scan_req)
2790 {
2791 	struct rtw89_vif *rtwvif = (struct rtw89_vif *)vif->drv_priv;
2792 	struct cfg80211_scan_request *req = &scan_req->req;
2793 	u32 rx_fltr = rtwdev->hal.rx_fltr;
2794 	u8 mac_addr[ETH_ALEN];
2795 
2796 	rtwdev->scan_info.scanning_vif = vif;
2797 	rtwdev->scan_info.last_chan_idx = 0;
2798 	rtwvif->scan_ies = &scan_req->ies;
2799 	rtwvif->scan_req = req;
2800 	ieee80211_stop_queues(rtwdev->hw);
2801 
2802 	if (req->flags & NL80211_SCAN_FLAG_RANDOM_ADDR)
2803 		get_random_mask_addr(mac_addr, req->mac_addr,
2804 				     req->mac_addr_mask);
2805 	else
2806 		ether_addr_copy(mac_addr, vif->addr);
2807 	rtw89_core_scan_start(rtwdev, rtwvif, mac_addr, true);
2808 
2809 	rx_fltr &= ~B_AX_A_BCN_CHK_EN;
2810 	rx_fltr &= ~B_AX_A_BC;
2811 	rx_fltr &= ~B_AX_A_A1_MATCH;
2812 	rtw89_write32_mask(rtwdev,
2813 			   rtw89_mac_reg_by_idx(R_AX_RX_FLTR_OPT, RTW89_MAC_0),
2814 			   B_AX_RX_FLTR_CFG_MASK,
2815 			   rx_fltr);
2816 }
2817 
2818 void rtw89_hw_scan_complete(struct rtw89_dev *rtwdev, struct ieee80211_vif *vif,
2819 			    bool aborted)
2820 {
2821 	struct cfg80211_scan_info info = {
2822 		.aborted = aborted,
2823 	};
2824 	struct rtw89_vif *rtwvif;
2825 
2826 	if (!vif)
2827 		return;
2828 
2829 	rtw89_write32_mask(rtwdev,
2830 			   rtw89_mac_reg_by_idx(R_AX_RX_FLTR_OPT, RTW89_MAC_0),
2831 			   B_AX_RX_FLTR_CFG_MASK,
2832 			   rtwdev->hal.rx_fltr);
2833 
2834 	rtw89_core_scan_complete(rtwdev, vif, true);
2835 	ieee80211_scan_completed(rtwdev->hw, &info);
2836 	ieee80211_wake_queues(rtwdev->hw);
2837 
2838 	rtw89_release_pkt_list(rtwdev);
2839 	rtwvif = (struct rtw89_vif *)vif->drv_priv;
2840 	rtwvif->scan_req = NULL;
2841 	rtwvif->scan_ies = NULL;
2842 	rtwdev->scan_info.last_chan_idx = 0;
2843 	rtwdev->scan_info.scanning_vif = NULL;
2844 
2845 	if (rtwvif->net_type != RTW89_NET_TYPE_NO_LINK)
2846 		rtw89_store_op_chan(rtwdev, false);
2847 	rtw89_set_channel(rtwdev);
2848 }
2849 
2850 void rtw89_hw_scan_abort(struct rtw89_dev *rtwdev, struct ieee80211_vif *vif)
2851 {
2852 	rtw89_hw_scan_offload(rtwdev, vif, false);
2853 	rtw89_hw_scan_complete(rtwdev, vif, true);
2854 }
2855 
2856 int rtw89_hw_scan_offload(struct rtw89_dev *rtwdev, struct ieee80211_vif *vif,
2857 			  bool enable)
2858 {
2859 	struct rtw89_scan_option opt = {0};
2860 	struct rtw89_vif *rtwvif;
2861 	int ret = 0;
2862 
2863 	rtwvif = vif ? (struct rtw89_vif *)vif->drv_priv : NULL;
2864 	if (!rtwvif)
2865 		return -EINVAL;
2866 
2867 	opt.enable = enable;
2868 	opt.target_ch_mode = rtwvif->net_type != RTW89_NET_TYPE_NO_LINK;
2869 	if (enable) {
2870 		ret = rtw89_hw_scan_prehandle(rtwdev, rtwvif);
2871 		if (ret)
2872 			goto out;
2873 	}
2874 	ret = rtw89_fw_h2c_scan_offload(rtwdev, &opt, rtwvif);
2875 out:
2876 	return ret;
2877 }
2878 
2879 void rtw89_store_op_chan(struct rtw89_dev *rtwdev, bool backup)
2880 {
2881 	struct rtw89_hw_scan_info *scan_info = &rtwdev->scan_info;
2882 	const struct rtw89_chan *cur = rtw89_chan_get(rtwdev, RTW89_SUB_ENTITY_0);
2883 	struct rtw89_chan new;
2884 
2885 	if (backup) {
2886 		scan_info->op_pri_ch = cur->primary_channel;
2887 		scan_info->op_chan = cur->channel;
2888 		scan_info->op_bw = cur->band_width;
2889 		scan_info->op_band = cur->band_type;
2890 	} else {
2891 		rtw89_chan_create(&new, scan_info->op_chan, scan_info->op_pri_ch,
2892 				  scan_info->op_band, scan_info->op_bw);
2893 		rtw89_assign_entity_chan(rtwdev, RTW89_SUB_ENTITY_0, &new);
2894 	}
2895 }
2896 
2897 #define H2C_FW_CPU_EXCEPTION_LEN 4
2898 #define H2C_FW_CPU_EXCEPTION_TYPE_DEF 0x5566
2899 int rtw89_fw_h2c_trigger_cpu_exception(struct rtw89_dev *rtwdev)
2900 {
2901 	struct sk_buff *skb;
2902 	int ret;
2903 
2904 	skb = rtw89_fw_h2c_alloc_skb_with_hdr(rtwdev, H2C_FW_CPU_EXCEPTION_LEN);
2905 	if (!skb) {
2906 		rtw89_err(rtwdev,
2907 			  "failed to alloc skb for fw cpu exception\n");
2908 		return -ENOMEM;
2909 	}
2910 
2911 	skb_put(skb, H2C_FW_CPU_EXCEPTION_LEN);
2912 	RTW89_SET_FWCMD_CPU_EXCEPTION_TYPE(skb->data,
2913 					   H2C_FW_CPU_EXCEPTION_TYPE_DEF);
2914 
2915 	rtw89_h2c_pkt_set_hdr(rtwdev, skb, FWCMD_TYPE_H2C,
2916 			      H2C_CAT_TEST,
2917 			      H2C_CL_FW_STATUS_TEST,
2918 			      H2C_FUNC_CPU_EXCEPTION, 0, 0,
2919 			      H2C_FW_CPU_EXCEPTION_LEN);
2920 
2921 	ret = rtw89_h2c_tx(rtwdev, skb, false);
2922 	if (ret) {
2923 		rtw89_err(rtwdev, "failed to send h2c\n");
2924 		goto fail;
2925 	}
2926 
2927 	return 0;
2928 
2929 fail:
2930 	dev_kfree_skb_any(skb);
2931 	return ret;
2932 }
2933 
2934 #define H2C_PKT_DROP_LEN 24
2935 int rtw89_fw_h2c_pkt_drop(struct rtw89_dev *rtwdev,
2936 			  const struct rtw89_pkt_drop_params *params)
2937 {
2938 	struct sk_buff *skb;
2939 	int ret;
2940 
2941 	skb = rtw89_fw_h2c_alloc_skb_with_hdr(rtwdev, H2C_PKT_DROP_LEN);
2942 	if (!skb) {
2943 		rtw89_err(rtwdev,
2944 			  "failed to alloc skb for packet drop\n");
2945 		return -ENOMEM;
2946 	}
2947 
2948 	switch (params->sel) {
2949 	case RTW89_PKT_DROP_SEL_MACID_BE_ONCE:
2950 	case RTW89_PKT_DROP_SEL_MACID_BK_ONCE:
2951 	case RTW89_PKT_DROP_SEL_MACID_VI_ONCE:
2952 	case RTW89_PKT_DROP_SEL_MACID_VO_ONCE:
2953 	case RTW89_PKT_DROP_SEL_BAND_ONCE:
2954 		break;
2955 	default:
2956 		rtw89_debug(rtwdev, RTW89_DBG_FW,
2957 			    "H2C of pkt drop might not fully support sel: %d yet\n",
2958 			    params->sel);
2959 		break;
2960 	}
2961 
2962 	skb_put(skb, H2C_PKT_DROP_LEN);
2963 	RTW89_SET_FWCMD_PKT_DROP_SEL(skb->data, params->sel);
2964 	RTW89_SET_FWCMD_PKT_DROP_MACID(skb->data, params->macid);
2965 	RTW89_SET_FWCMD_PKT_DROP_BAND(skb->data, params->mac_band);
2966 	RTW89_SET_FWCMD_PKT_DROP_PORT(skb->data, params->port);
2967 	RTW89_SET_FWCMD_PKT_DROP_MBSSID(skb->data, params->mbssid);
2968 	RTW89_SET_FWCMD_PKT_DROP_ROLE_A_INFO_TF_TRS(skb->data, params->tf_trs);
2969 	RTW89_SET_FWCMD_PKT_DROP_MACID_BAND_SEL_0(skb->data,
2970 						  params->macid_band_sel[0]);
2971 	RTW89_SET_FWCMD_PKT_DROP_MACID_BAND_SEL_1(skb->data,
2972 						  params->macid_band_sel[1]);
2973 	RTW89_SET_FWCMD_PKT_DROP_MACID_BAND_SEL_2(skb->data,
2974 						  params->macid_band_sel[2]);
2975 	RTW89_SET_FWCMD_PKT_DROP_MACID_BAND_SEL_3(skb->data,
2976 						  params->macid_band_sel[3]);
2977 
2978 	rtw89_h2c_pkt_set_hdr(rtwdev, skb, FWCMD_TYPE_H2C,
2979 			      H2C_CAT_MAC,
2980 			      H2C_CL_MAC_FW_OFLD,
2981 			      H2C_FUNC_PKT_DROP, 0, 0,
2982 			      H2C_PKT_DROP_LEN);
2983 
2984 	ret = rtw89_h2c_tx(rtwdev, skb, false);
2985 	if (ret) {
2986 		rtw89_err(rtwdev, "failed to send h2c\n");
2987 		goto fail;
2988 	}
2989 
2990 	return 0;
2991 
2992 fail:
2993 	dev_kfree_skb_any(skb);
2994 	return ret;
2995 }
2996 
2997 #define H2C_KEEP_ALIVE_LEN 4
2998 int rtw89_fw_h2c_keep_alive(struct rtw89_dev *rtwdev, struct rtw89_vif *rtwvif,
2999 			    bool enable)
3000 {
3001 	struct sk_buff *skb;
3002 	u8 pkt_id = 0;
3003 	int ret;
3004 
3005 	if (enable) {
3006 		ret = rtw89_fw_h2c_add_wow_fw_ofld(rtwdev, rtwvif,
3007 						   RTW89_PKT_OFLD_TYPE_NULL_DATA, &pkt_id);
3008 		if (ret)
3009 			return -EPERM;
3010 	}
3011 
3012 	skb = rtw89_fw_h2c_alloc_skb_with_hdr(rtwdev, H2C_KEEP_ALIVE_LEN);
3013 	if (!skb) {
3014 		rtw89_err(rtwdev, "failed to alloc skb for keep alive\n");
3015 		return -ENOMEM;
3016 	}
3017 
3018 	skb_put(skb, H2C_KEEP_ALIVE_LEN);
3019 
3020 	RTW89_SET_KEEP_ALIVE_ENABLE(skb->data, enable);
3021 	RTW89_SET_KEEP_ALIVE_PKT_NULL_ID(skb->data, pkt_id);
3022 	RTW89_SET_KEEP_ALIVE_PERIOD(skb->data, 5);
3023 	RTW89_SET_KEEP_ALIVE_MACID(skb->data, rtwvif->mac_id);
3024 
3025 	rtw89_h2c_pkt_set_hdr(rtwdev, skb, FWCMD_TYPE_H2C,
3026 			      H2C_CAT_MAC,
3027 			      H2C_CL_MAC_WOW,
3028 			      H2C_FUNC_KEEP_ALIVE, 0, 1,
3029 			      H2C_KEEP_ALIVE_LEN);
3030 
3031 	ret = rtw89_h2c_tx(rtwdev, skb, false);
3032 	if (ret) {
3033 		rtw89_err(rtwdev, "failed to send h2c\n");
3034 		goto fail;
3035 	}
3036 
3037 	return 0;
3038 
3039 fail:
3040 	dev_kfree_skb_any(skb);
3041 
3042 	return ret;
3043 }
3044 
3045 #define H2C_DISCONNECT_DETECT_LEN 8
3046 int rtw89_fw_h2c_disconnect_detect(struct rtw89_dev *rtwdev,
3047 				   struct rtw89_vif *rtwvif, bool enable)
3048 {
3049 	struct rtw89_wow_param *rtw_wow = &rtwdev->wow;
3050 	struct sk_buff *skb;
3051 	u8 macid = rtwvif->mac_id;
3052 	int ret;
3053 
3054 	skb = rtw89_fw_h2c_alloc_skb_with_hdr(rtwdev, H2C_DISCONNECT_DETECT_LEN);
3055 	if (!skb) {
3056 		rtw89_err(rtwdev, "failed to alloc skb for keep alive\n");
3057 		return -ENOMEM;
3058 	}
3059 
3060 	skb_put(skb, H2C_DISCONNECT_DETECT_LEN);
3061 
3062 	if (test_bit(RTW89_WOW_FLAG_EN_DISCONNECT, rtw_wow->flags)) {
3063 		RTW89_SET_DISCONNECT_DETECT_ENABLE(skb->data, enable);
3064 		RTW89_SET_DISCONNECT_DETECT_DISCONNECT(skb->data, !enable);
3065 		RTW89_SET_DISCONNECT_DETECT_MAC_ID(skb->data, macid);
3066 		RTW89_SET_DISCONNECT_DETECT_CHECK_PERIOD(skb->data, 100);
3067 		RTW89_SET_DISCONNECT_DETECT_TRY_PKT_COUNT(skb->data, 5);
3068 	}
3069 
3070 	rtw89_h2c_pkt_set_hdr(rtwdev, skb, FWCMD_TYPE_H2C,
3071 			      H2C_CAT_MAC,
3072 			      H2C_CL_MAC_WOW,
3073 			      H2C_FUNC_DISCONNECT_DETECT, 0, 1,
3074 			      H2C_DISCONNECT_DETECT_LEN);
3075 
3076 	ret = rtw89_h2c_tx(rtwdev, skb, false);
3077 	if (ret) {
3078 		rtw89_err(rtwdev, "failed to send h2c\n");
3079 		goto fail;
3080 	}
3081 
3082 	return 0;
3083 
3084 fail:
3085 	dev_kfree_skb_any(skb);
3086 
3087 	return ret;
3088 }
3089 
3090 #define H2C_WOW_GLOBAL_LEN 8
3091 int rtw89_fw_h2c_wow_global(struct rtw89_dev *rtwdev, struct rtw89_vif *rtwvif,
3092 			    bool enable)
3093 {
3094 	struct sk_buff *skb;
3095 	u8 macid = rtwvif->mac_id;
3096 	int ret;
3097 
3098 	skb = rtw89_fw_h2c_alloc_skb_with_hdr(rtwdev, H2C_WOW_GLOBAL_LEN);
3099 	if (!skb) {
3100 		rtw89_err(rtwdev, "failed to alloc skb for keep alive\n");
3101 		return -ENOMEM;
3102 	}
3103 
3104 	skb_put(skb, H2C_WOW_GLOBAL_LEN);
3105 
3106 	RTW89_SET_WOW_GLOBAL_ENABLE(skb->data, enable);
3107 	RTW89_SET_WOW_GLOBAL_MAC_ID(skb->data, macid);
3108 
3109 	rtw89_h2c_pkt_set_hdr(rtwdev, skb, FWCMD_TYPE_H2C,
3110 			      H2C_CAT_MAC,
3111 			      H2C_CL_MAC_WOW,
3112 			      H2C_FUNC_WOW_GLOBAL, 0, 1,
3113 			      H2C_WOW_GLOBAL_LEN);
3114 
3115 	ret = rtw89_h2c_tx(rtwdev, skb, false);
3116 	if (ret) {
3117 		rtw89_err(rtwdev, "failed to send h2c\n");
3118 		goto fail;
3119 	}
3120 
3121 	return 0;
3122 
3123 fail:
3124 	dev_kfree_skb_any(skb);
3125 
3126 	return ret;
3127 }
3128 
3129 #define H2C_WAKEUP_CTRL_LEN 4
3130 int rtw89_fw_h2c_wow_wakeup_ctrl(struct rtw89_dev *rtwdev,
3131 				 struct rtw89_vif *rtwvif,
3132 				 bool enable)
3133 {
3134 	struct rtw89_wow_param *rtw_wow = &rtwdev->wow;
3135 	struct sk_buff *skb;
3136 	u8 macid = rtwvif->mac_id;
3137 	int ret;
3138 
3139 	skb = rtw89_fw_h2c_alloc_skb_with_hdr(rtwdev, H2C_WAKEUP_CTRL_LEN);
3140 	if (!skb) {
3141 		rtw89_err(rtwdev, "failed to alloc skb for keep alive\n");
3142 		return -ENOMEM;
3143 	}
3144 
3145 	skb_put(skb, H2C_WAKEUP_CTRL_LEN);
3146 
3147 	if (rtw_wow->pattern_cnt)
3148 		RTW89_SET_WOW_WAKEUP_CTRL_PATTERN_MATCH_ENABLE(skb->data, enable);
3149 	if (test_bit(RTW89_WOW_FLAG_EN_MAGIC_PKT, rtw_wow->flags))
3150 		RTW89_SET_WOW_WAKEUP_CTRL_MAGIC_ENABLE(skb->data, enable);
3151 	if (test_bit(RTW89_WOW_FLAG_EN_DISCONNECT, rtw_wow->flags))
3152 		RTW89_SET_WOW_WAKEUP_CTRL_DEAUTH_ENABLE(skb->data, enable);
3153 
3154 	RTW89_SET_WOW_WAKEUP_CTRL_MAC_ID(skb->data, macid);
3155 
3156 	rtw89_h2c_pkt_set_hdr(rtwdev, skb, FWCMD_TYPE_H2C,
3157 			      H2C_CAT_MAC,
3158 			      H2C_CL_MAC_WOW,
3159 			      H2C_FUNC_WAKEUP_CTRL, 0, 1,
3160 			      H2C_WAKEUP_CTRL_LEN);
3161 
3162 	ret = rtw89_h2c_tx(rtwdev, skb, false);
3163 	if (ret) {
3164 		rtw89_err(rtwdev, "failed to send h2c\n");
3165 		goto fail;
3166 	}
3167 
3168 	return 0;
3169 
3170 fail:
3171 	dev_kfree_skb_any(skb);
3172 
3173 	return ret;
3174 }
3175 
3176 #define H2C_WOW_CAM_UPD_LEN 24
3177 int rtw89_fw_wow_cam_update(struct rtw89_dev *rtwdev,
3178 			    struct rtw89_wow_cam_info *cam_info)
3179 {
3180 	struct sk_buff *skb;
3181 	int ret;
3182 
3183 	skb = rtw89_fw_h2c_alloc_skb_with_hdr(rtwdev, H2C_WOW_CAM_UPD_LEN);
3184 	if (!skb) {
3185 		rtw89_err(rtwdev, "failed to alloc skb for keep alive\n");
3186 		return -ENOMEM;
3187 	}
3188 
3189 	skb_put(skb, H2C_WOW_CAM_UPD_LEN);
3190 
3191 	RTW89_SET_WOW_CAM_UPD_R_W(skb->data, cam_info->r_w);
3192 	RTW89_SET_WOW_CAM_UPD_IDX(skb->data, cam_info->idx);
3193 	if (cam_info->valid) {
3194 		RTW89_SET_WOW_CAM_UPD_WKFM1(skb->data, cam_info->mask[0]);
3195 		RTW89_SET_WOW_CAM_UPD_WKFM2(skb->data, cam_info->mask[1]);
3196 		RTW89_SET_WOW_CAM_UPD_WKFM3(skb->data, cam_info->mask[2]);
3197 		RTW89_SET_WOW_CAM_UPD_WKFM4(skb->data, cam_info->mask[3]);
3198 		RTW89_SET_WOW_CAM_UPD_CRC(skb->data, cam_info->crc);
3199 		RTW89_SET_WOW_CAM_UPD_NEGATIVE_PATTERN_MATCH(skb->data,
3200 							     cam_info->negative_pattern_match);
3201 		RTW89_SET_WOW_CAM_UPD_SKIP_MAC_HDR(skb->data,
3202 						   cam_info->skip_mac_hdr);
3203 		RTW89_SET_WOW_CAM_UPD_UC(skb->data, cam_info->uc);
3204 		RTW89_SET_WOW_CAM_UPD_MC(skb->data, cam_info->mc);
3205 		RTW89_SET_WOW_CAM_UPD_BC(skb->data, cam_info->bc);
3206 	}
3207 	RTW89_SET_WOW_CAM_UPD_VALID(skb->data, cam_info->valid);
3208 
3209 	rtw89_h2c_pkt_set_hdr(rtwdev, skb, FWCMD_TYPE_H2C,
3210 			      H2C_CAT_MAC,
3211 			      H2C_CL_MAC_WOW,
3212 			      H2C_FUNC_WOW_CAM_UPD, 0, 1,
3213 			      H2C_WOW_CAM_UPD_LEN);
3214 
3215 	ret = rtw89_h2c_tx(rtwdev, skb, false);
3216 	if (ret) {
3217 		rtw89_err(rtwdev, "failed to send h2c\n");
3218 		goto fail;
3219 	}
3220 
3221 	return 0;
3222 fail:
3223 	dev_kfree_skb_any(skb);
3224 
3225 	return ret;
3226 }
3227