Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
freebsd
GitHub Repository: freebsd/freebsd-src
Path: blob/main/sys/contrib/dev/iwlwifi/fw/rs.c
48287 views
1
// SPDX-License-Identifier: GPL-2.0 OR BSD-3-Clause
2
/*
3
* Copyright (C) 2021-2022, 2025 Intel Corporation
4
*/
5
6
#include <net/mac80211.h>
7
#include "fw/api/rs.h"
8
#include "iwl-drv.h"
9
#include "iwl-config.h"
10
11
#define IWL_DECLARE_RATE_INFO(r) \
12
[IWL_RATE_##r##M_INDEX] = IWL_RATE_##r##M_PLCP
13
14
/*
15
* Translate from fw_rate_index (IWL_RATE_XXM_INDEX) to PLCP
16
* */
17
static const u8 fw_rate_idx_to_plcp[IWL_RATE_COUNT] = {
18
IWL_DECLARE_RATE_INFO(1),
19
IWL_DECLARE_RATE_INFO(2),
20
IWL_DECLARE_RATE_INFO(5),
21
IWL_DECLARE_RATE_INFO(11),
22
IWL_DECLARE_RATE_INFO(6),
23
IWL_DECLARE_RATE_INFO(9),
24
IWL_DECLARE_RATE_INFO(12),
25
IWL_DECLARE_RATE_INFO(18),
26
IWL_DECLARE_RATE_INFO(24),
27
IWL_DECLARE_RATE_INFO(36),
28
IWL_DECLARE_RATE_INFO(48),
29
IWL_DECLARE_RATE_INFO(54),
30
};
31
32
/* mbps, mcs */
33
static const struct iwl_rate_mcs_info rate_mcs[IWL_RATE_COUNT] = {
34
{ "1", "BPSK DSSS"},
35
{ "2", "QPSK DSSS"},
36
{"5.5", "BPSK CCK"},
37
{ "11", "QPSK CCK"},
38
{ "6", "BPSK 1/2"},
39
{ "9", "BPSK 1/2"},
40
{ "12", "QPSK 1/2"},
41
{ "18", "QPSK 3/4"},
42
{ "24", "16QAM 1/2"},
43
{ "36", "16QAM 3/4"},
44
{ "48", "64QAM 2/3"},
45
{ "54", "64QAM 3/4"},
46
{ "60", "64QAM 5/6"},
47
};
48
49
static const char * const ant_name[] = {
50
[ANT_NONE] = "None",
51
[ANT_A] = "A",
52
[ANT_B] = "B",
53
[ANT_AB] = "AB",
54
};
55
56
static const char * const pretty_bw[] = {
57
"20Mhz",
58
"40Mhz",
59
"80Mhz",
60
"160 Mhz",
61
"320Mhz",
62
};
63
64
u8 iwl_fw_rate_idx_to_plcp(int idx)
65
{
66
return fw_rate_idx_to_plcp[idx];
67
}
68
IWL_EXPORT_SYMBOL(iwl_fw_rate_idx_to_plcp);
69
70
const struct iwl_rate_mcs_info *iwl_rate_mcs(int idx)
71
{
72
return &rate_mcs[idx];
73
}
74
IWL_EXPORT_SYMBOL(iwl_rate_mcs);
75
76
const char *iwl_rs_pretty_ant(u8 ant)
77
{
78
if (ant >= ARRAY_SIZE(ant_name))
79
return "UNKNOWN";
80
81
return ant_name[ant];
82
}
83
IWL_EXPORT_SYMBOL(iwl_rs_pretty_ant);
84
85
const char *iwl_rs_pretty_bw(int bw)
86
{
87
if (bw >= ARRAY_SIZE(pretty_bw))
88
return "unknown bw";
89
90
return pretty_bw[bw];
91
}
92
IWL_EXPORT_SYMBOL(iwl_rs_pretty_bw);
93
94
int rs_pretty_print_rate(char *buf, int bufsz, const u32 rate)
95
{
96
char *type;
97
u8 mcs = 0, nss = 0;
98
u8 ant = (rate & RATE_MCS_ANT_AB_MSK) >> RATE_MCS_ANT_POS;
99
u32 bw = (rate & RATE_MCS_CHAN_WIDTH_MSK) >>
100
RATE_MCS_CHAN_WIDTH_POS;
101
u32 format = rate & RATE_MCS_MOD_TYPE_MSK;
102
int index = 0;
103
bool sgi;
104
105
switch (format) {
106
case RATE_MCS_MOD_TYPE_LEGACY_OFDM:
107
index = IWL_FIRST_OFDM_RATE;
108
fallthrough;
109
case RATE_MCS_MOD_TYPE_CCK:
110
index += rate & RATE_LEGACY_RATE_MSK;
111
112
return scnprintf(buf, bufsz, "Legacy | ANT: %s Rate: %s Mbps",
113
iwl_rs_pretty_ant(ant),
114
iwl_rate_mcs(index)->mbps);
115
case RATE_MCS_MOD_TYPE_VHT:
116
type = "VHT";
117
break;
118
case RATE_MCS_MOD_TYPE_HT:
119
type = "HT";
120
break;
121
case RATE_MCS_MOD_TYPE_HE:
122
type = "HE";
123
break;
124
case RATE_MCS_MOD_TYPE_EHT:
125
type = "EHT";
126
break;
127
default:
128
type = "Unknown"; /* shouldn't happen */
129
}
130
131
mcs = format == RATE_MCS_MOD_TYPE_HT ?
132
RATE_HT_MCS_INDEX(rate) :
133
rate & RATE_MCS_CODE_MSK;
134
nss = u32_get_bits(rate, RATE_MCS_NSS_MSK);
135
sgi = format == RATE_MCS_MOD_TYPE_HE ?
136
iwl_he_is_sgi(rate) :
137
rate & RATE_MCS_SGI_MSK;
138
139
return scnprintf(buf, bufsz,
140
"0x%x: %s | ANT: %s BW: %s MCS: %d NSS: %d %s%s%s%s%s",
141
rate, type, iwl_rs_pretty_ant(ant), iwl_rs_pretty_bw(bw), mcs, nss,
142
(sgi) ? "SGI " : "NGI ",
143
(rate & RATE_MCS_STBC_MSK) ? "STBC " : "",
144
(rate & RATE_MCS_LDPC_MSK) ? "LDPC " : "",
145
(rate & RATE_HE_DUAL_CARRIER_MODE_MSK) ? "DCM " : "",
146
(rate & RATE_MCS_BF_MSK) ? "BF " : "");
147
}
148
IWL_EXPORT_SYMBOL(rs_pretty_print_rate);
149
150
bool iwl_he_is_sgi(u32 rate_n_flags)
151
{
152
u32 type = rate_n_flags & RATE_MCS_HE_TYPE_MSK;
153
u32 ltf_gi = rate_n_flags & RATE_MCS_HE_GI_LTF_MSK;
154
155
if (type == RATE_MCS_HE_TYPE_SU ||
156
type == RATE_MCS_HE_TYPE_EXT_SU)
157
return ltf_gi == RATE_MCS_HE_SU_4_LTF_08_GI;
158
return false;
159
}
160
IWL_EXPORT_SYMBOL(iwl_he_is_sgi);
161
162
163