Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
freebsd
GitHub Repository: freebsd/freebsd-src
Path: blob/main/sys/contrib/dev/iwlwifi/mvm/rs.c
48287 views
1
/*-
2
* Copyright (c) 2020-2025 The FreeBSD Foundation
3
*
4
* This software was developed by Björn Zeeb under sponsorship from
5
* the FreeBSD Foundation.
6
*
7
* Redistribution and use in source and binary forms, with or without
8
* modification, are permitted provided that the following conditions
9
* are met:
10
* 1. Redistributions of source code must retain the above copyright
11
* notice, this list of conditions and the following disclaimer.
12
* 2. Redistributions in binary form must reproduce the above copyright
13
* notice, this list of conditions and the following disclaimer in the
14
* documentation and/or other materials provided with the distribution.
15
*
16
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
17
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
18
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
19
* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
20
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
21
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
22
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
23
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
24
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
25
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
26
* SUCH DAMAGE.
27
*
28
* $FreeBSD$
29
*/
30
31
/*
32
* XXX-BZ:
33
* This file is left as a wrapper to make mvm compile and we will only
34
* deal with it on a need basis. Most newer chipsets do this in firmware.
35
*/
36
#include <sys/param.h>
37
#include <net/cfg80211.h> /* LinuxKPI 802.11 TODO() calls. */
38
39
#include "rs.h"
40
#include "mvm.h"
41
42
#ifdef CONFIG_IWLWIFI_DEBUGFS
43
/*
44
* Fill struct iwl_mvm_frame_stats.
45
* Deal with various RATE_MCS_*_MSK. See rx.c, fw/api/rs.h, et al.
46
* XXX-BZ consider calling iwl_new_rate_from_v1() in rx.c so we can also
47
* use this in rxmq.c.
48
*/
49
void
50
iwl_mvm_update_frame_stats(struct iwl_mvm *mvm, u32 rate, bool agg)
51
{
52
uint8_t nss;
53
54
spin_lock_bh(&mvm->drv_stats_lock);
55
mvm->drv_rx_stats.success_frames++;
56
57
if (rate & RATE_MCS_HT_MSK_V1) {
58
mvm->drv_rx_stats.ht_frames++;
59
nss = 1 + ((rate & RATE_HT_MCS_NSS_MSK_V1) >> RATE_HT_MCS_NSS_POS_V1);
60
} else if (rate & RATE_MCS_VHT_MSK_V1) {
61
mvm->drv_rx_stats.vht_frames++;
62
nss = 1 + FIELD_GET(RATE_MCS_NSS_MSK, rate);
63
} else {
64
mvm->drv_rx_stats.legacy_frames++;
65
nss = 0;
66
}
67
68
switch (rate & RATE_MCS_CHAN_WIDTH_MSK_V1) {
69
case RATE_MCS_CHAN_WIDTH_20:
70
mvm->drv_rx_stats.bw_20_frames++;
71
break;
72
case RATE_MCS_CHAN_WIDTH_40:
73
mvm->drv_rx_stats.bw_40_frames++;
74
break;
75
case RATE_MCS_CHAN_WIDTH_80:
76
mvm->drv_rx_stats.bw_80_frames++;
77
break;
78
case RATE_MCS_CHAN_WIDTH_160:
79
mvm->drv_rx_stats.bw_160_frames++;
80
break;
81
}
82
83
if ((rate & RATE_MCS_CCK_MSK_V1) == 0 &&
84
(rate & RATE_MCS_SGI_MSK_V1) != 0)
85
mvm->drv_rx_stats.sgi_frames++;
86
else
87
mvm->drv_rx_stats.ngi_frames++;
88
89
switch (nss) {
90
case 1:
91
mvm->drv_rx_stats.siso_frames++;
92
break;
93
case 2:
94
mvm->drv_rx_stats.mimo2_frames++;
95
break;
96
}
97
98
if (agg)
99
mvm->drv_rx_stats.agg_frames++;
100
101
/* ampdu_count? */
102
/* fail_frames? */
103
104
mvm->drv_rx_stats.last_rates[mvm->drv_rx_stats.last_frame_idx] = rate;
105
mvm->drv_rx_stats.last_frame_idx++;
106
mvm->drv_rx_stats.last_frame_idx %=
107
ARRAY_SIZE(mvm->drv_rx_stats.last_rates);
108
109
spin_unlock_bh(&mvm->drv_stats_lock);
110
}
111
112
void
113
iwl_mvm_reset_frame_stats(struct iwl_mvm *mvm)
114
{
115
/* Apply same locking rx.c does; debugfs seems to read unloked? */
116
spin_lock_bh(&mvm->drv_stats_lock);
117
memset(&mvm->drv_rx_stats, 0, sizeof(mvm->drv_rx_stats));
118
spin_unlock_bh(&mvm->drv_stats_lock);
119
}
120
#endif
121
122
int
123
iwl_mvm_rate_control_register(void)
124
{
125
TODO("This likely has to call into net80211 unless we gain compat code in LinuxKPI");
126
return (0);
127
}
128
129
void
130
iwl_mvm_rate_control_unregister(void)
131
{
132
TODO("This likely has to call into net80211 unless we gain compat code in LinuxKPI");
133
}
134
135
int
136
iwl_mvm_tx_protection(struct iwl_mvm *mvm, struct iwl_mvm_sta *mvmsta, bool enable)
137
{
138
if (iwl_mvm_has_tlc_offload(mvm))
139
return (rs_fw_tx_protection(mvm, mvmsta, enable));
140
else {
141
TODO();
142
return (0);
143
}
144
}
145
146
static void
147
iwl_mvm_rs_sw_rate_init(struct iwl_mvm *mvm, struct ieee80211_vif *vif,
148
struct ieee80211_sta *sta,
149
struct ieee80211_bss_conf *link_conf, struct ieee80211_link_sta *link_sta,
150
enum nl80211_band band)
151
{
152
TODO();
153
}
154
155
void
156
iwl_mvm_rs_rate_init(struct iwl_mvm *mvm, struct ieee80211_vif *vif,
157
struct ieee80211_sta *sta,
158
struct ieee80211_bss_conf *link_conf, struct ieee80211_link_sta *link_sta,
159
enum nl80211_band band)
160
{
161
if (iwl_mvm_has_tlc_offload(mvm))
162
iwl_mvm_rs_fw_rate_init(mvm, vif, sta, link_conf, link_sta, band);
163
else
164
iwl_mvm_rs_sw_rate_init(mvm, vif, sta, link_conf, link_sta, band);
165
}
166
167
void
168
iwl_mvm_rs_tx_status(struct iwl_mvm *mvm, struct ieee80211_sta *sta, int tid,
169
struct ieee80211_tx_info *ba_info, bool t)
170
{
171
TODO();
172
}
173
174
void
175
rs_update_last_rssi(struct iwl_mvm *mvm __unused, struct iwl_mvm_sta *mvmsta,
176
struct ieee80211_rx_status *rx_status)
177
{
178
struct iwl_lq_sta *lq_sta;
179
int i;
180
181
if (mvmsta == NULL || rx_status == NULL)
182
return;
183
184
/*
185
* Assumption based on mvm/sta.h is that this should update
186
* mvmsta->lq_sta.rs_drv but so far we only saw a iwl_lq_cmd (lq)
187
* access in that struct so nowhere to put rssi information.
188
* So the only thing would be if this is required internally
189
* to functions in this file.
190
* The "FW" version accesses more fields. We assume they
191
* are the same for now.
192
*/
193
194
lq_sta = &mvmsta->deflink.lq_sta.rs_drv;
195
196
lq_sta->pers.last_rssi = S8_MIN;
197
lq_sta->pers.chains = rx_status->chains;
198
199
for (i = 0; i < nitems(lq_sta->pers.chain_signal); i++) {
200
if ((rx_status->chains & BIT(i)) == 0)
201
continue;
202
203
lq_sta->pers.chain_signal[i] = rx_status->chain_signal[i];
204
if (rx_status->chain_signal[i] > lq_sta->pers.last_rssi)
205
lq_sta->pers.last_rssi = rx_status->chain_signal[i];
206
}
207
}
208
209
int
210
rs_pretty_print_rate_v1(char *buf, int bufsz, const u32 rate)
211
{
212
TODO();
213
return (0);
214
}
215
216