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