1 |
From b88ab464d4f0c21f1a15dc774ac552e11b875b06 Mon Sep 17 00:00:00 2001 |
2 |
From: Ping-Ke Shih <pkshih@realtek.com> |
3 |
Date: Fri, 8 Oct 2021 11:56:06 +0800 |
4 |
Subject: [PATCH 03/24] rtw89: add core and trx files |
5 |
|
6 |
Implement main flows that contains register/unregister mac80211 hw with |
7 |
hardware capability, power on/off sequence, STA state actions, and |
8 |
TX/RX path. |
9 |
|
10 |
The chip info is read from efuse while probing PCI, and then it can be |
11 |
used to induce supported channel, band, bitrate, ht/vht/he capability, |
12 |
and etc. Then, we register hardware with these capabilities. |
13 |
|
14 |
When network interface is up, driver does power-on sequence to enable MAC, |
15 |
BB and RF function blocks. Oppositely, do power-off sequence when |
16 |
interface is going to down. |
17 |
|
18 |
To maintain STA state, five callbacks are implemented -- add, assoc, |
19 |
disassoc, disconnect and remove. In which state, driver tells firmware STA |
20 |
info via H2C. |
21 |
|
22 |
TX flow: |
23 |
When a SKB is going to be transmitted, we must know its type first. If |
24 |
the type is mgmt or fwcmd made by driver, SKB is queued into corresponding |
25 |
DMA channel and PCI ring. The other type is data frame that is more |
26 |
complex, because it needs to establish BA session to have better throughput |
27 |
with AMPDU and AMSDU. |
28 |
In order to have better PCI DMA efficiency, we don't kick off DMA every |
29 |
SKB. With wake TX queue, kick off DMA after a bunch of SKBs are written. |
30 |
To achieve this, we have two HCI ops -- tx_write and tx_kick_off. |
31 |
|
32 |
BA establishment work: |
33 |
For data frames, we start to establish BA session if the STA is associated |
34 |
with APMDU capability and the TID session isn't established, and then the |
35 |
BA work is used to ask mac80211 to start AMPDU actions. Driver implements |
36 |
AMPDU action callbacks to know the session is established, so that we can |
37 |
set AGG_EN bit in TX descriptor to enable AMPDU. |
38 |
|
39 |
RX flow: |
40 |
When a RX SKB is delivered from PCI, rtw89_core_rx() process it depneds on |
41 |
its type -- WIFI, C2H or PPDU. If type is C2H, it's queued into a C2H |
42 |
queue, and wake a work to handle the C2H packet. If type is WIFI, it's a |
43 |
normal RX packet. When mgmt or data frame is received, it is queued |
44 |
into pending RX SKB queue to wait for corresponding PPDU packet (another |
45 |
RX packet with PPDU type) to fill its rx_status, like RSSI. And, then |
46 |
indicate this packet to mac80211. When control frame is received, indicate |
47 |
it to mac80211 immediately. |
48 |
|
49 |
Track work: |
50 |
Use track work to monitor PHY status to know the changes of environment, |
51 |
and then update RA status or do RFK accordingly. |
52 |
|
53 |
Signed-off-by: Ping-Ke Shih <pkshih@realtek.com> |
54 |
Signed-off-by: Kalle Valo <kvalo@codeaurora.org> |
55 |
Link: https://lore.kernel.org/r/20211008035627.19463-4-pkshih@realtek.com |
56 |
--- |
57 |
drivers/net/wireless/realtek/rtw89/core.c | 2502 +++++++++++++++ |
58 |
drivers/net/wireless/realtek/rtw89/core.h | 3384 +++++++++++++++++++++ |
59 |
drivers/net/wireless/realtek/rtw89/txrx.h | 358 +++ |
60 |
drivers/net/wireless/realtek/rtw89/util.h | 17 + |
61 |
4 files changed, 6261 insertions(+) |
62 |
create mode 100644 drivers/net/wireless/realtek/rtw89/core.c |
63 |
create mode 100644 drivers/net/wireless/realtek/rtw89/core.h |
64 |
create mode 100644 drivers/net/wireless/realtek/rtw89/txrx.h |
65 |
create mode 100644 drivers/net/wireless/realtek/rtw89/util.h |
66 |
|
67 |
diff --git a/drivers/net/wireless/realtek/rtw89/core.c b/drivers/net/wireless/realtek/rtw89/core.c |
68 |
new file mode 100644 |
69 |
index 000000000000..06fb6e5b1b37 |
70 |
--- /dev/null |
71 |
+++ b/drivers/net/wireless/realtek/rtw89/core.c |
72 |
@@ -0,0 +1,2502 @@ |
73 |
+// SPDX-License-Identifier: GPL-2.0 OR BSD-3-Clause |
74 |
+/* Copyright(c) 2019-2020 Realtek Corporation |
75 |
+ */ |
76 |
+ |
77 |
+#include "coex.h" |
78 |
+#include "core.h" |
79 |
+#include "efuse.h" |
80 |
+#include "fw.h" |
81 |
+#include "mac.h" |
82 |
+#include "phy.h" |
83 |
+#include "ps.h" |
84 |
+#include "reg.h" |
85 |
+#include "sar.h" |
86 |
+#include "ser.h" |
87 |
+#include "txrx.h" |
88 |
+#include "util.h" |
89 |
+ |
90 |
+static bool rtw89_disable_ps_mode; |
91 |
+module_param_named(disable_ps_mode, rtw89_disable_ps_mode, bool, 0644); |
92 |
+MODULE_PARM_DESC(disable_ps_mode, "Set Y to disable low power mode"); |
93 |
+ |
94 |
+static struct ieee80211_channel rtw89_channels_2ghz[] = { |
95 |
+ { .center_freq = 2412, .hw_value = 1, }, |
96 |
+ { .center_freq = 2417, .hw_value = 2, }, |
97 |
+ { .center_freq = 2422, .hw_value = 3, }, |
98 |
+ { .center_freq = 2427, .hw_value = 4, }, |
99 |
+ { .center_freq = 2432, .hw_value = 5, }, |
100 |
+ { .center_freq = 2437, .hw_value = 6, }, |
101 |
+ { .center_freq = 2442, .hw_value = 7, }, |
102 |
+ { .center_freq = 2447, .hw_value = 8, }, |
103 |
+ { .center_freq = 2452, .hw_value = 9, }, |
104 |
+ { .center_freq = 2457, .hw_value = 10, }, |
105 |
+ { .center_freq = 2462, .hw_value = 11, }, |
106 |
+ { .center_freq = 2467, .hw_value = 12, }, |
107 |
+ { .center_freq = 2472, .hw_value = 13, }, |
108 |
+ { .center_freq = 2484, .hw_value = 14, }, |
109 |
+}; |
110 |
+ |
111 |
+static struct ieee80211_channel rtw89_channels_5ghz[] = { |
112 |
+ {.center_freq = 5180, .hw_value = 36,}, |
113 |
+ {.center_freq = 5200, .hw_value = 40,}, |
114 |
+ {.center_freq = 5220, .hw_value = 44,}, |
115 |
+ {.center_freq = 5240, .hw_value = 48,}, |
116 |
+ {.center_freq = 5260, .hw_value = 52,}, |
117 |
+ {.center_freq = 5280, .hw_value = 56,}, |
118 |
+ {.center_freq = 5300, .hw_value = 60,}, |
119 |
+ {.center_freq = 5320, .hw_value = 64,}, |
120 |
+ {.center_freq = 5500, .hw_value = 100,}, |
121 |
+ {.center_freq = 5520, .hw_value = 104,}, |
122 |
+ {.center_freq = 5540, .hw_value = 108,}, |
123 |
+ {.center_freq = 5560, .hw_value = 112,}, |
124 |
+ {.center_freq = 5580, .hw_value = 116,}, |
125 |
+ {.center_freq = 5600, .hw_value = 120,}, |
126 |
+ {.center_freq = 5620, .hw_value = 124,}, |
127 |
+ {.center_freq = 5640, .hw_value = 128,}, |
128 |
+ {.center_freq = 5660, .hw_value = 132,}, |
129 |
+ {.center_freq = 5680, .hw_value = 136,}, |
130 |
+ {.center_freq = 5700, .hw_value = 140,}, |
131 |
+ {.center_freq = 5720, .hw_value = 144,}, |
132 |
+ {.center_freq = 5745, .hw_value = 149,}, |
133 |
+ {.center_freq = 5765, .hw_value = 153,}, |
134 |
+ {.center_freq = 5785, .hw_value = 157,}, |
135 |
+ {.center_freq = 5805, .hw_value = 161,}, |
136 |
+ {.center_freq = 5825, .hw_value = 165, |
137 |
+ .flags = IEEE80211_CHAN_NO_HT40MINUS}, |
138 |
+}; |
139 |
+ |
140 |
+static struct ieee80211_rate rtw89_bitrates[] = { |
141 |
+ { .bitrate = 10, .hw_value = 0x00, }, |
142 |
+ { .bitrate = 20, .hw_value = 0x01, }, |
143 |
+ { .bitrate = 55, .hw_value = 0x02, }, |
144 |
+ { .bitrate = 110, .hw_value = 0x03, }, |
145 |
+ { .bitrate = 60, .hw_value = 0x04, }, |
146 |
+ { .bitrate = 90, .hw_value = 0x05, }, |
147 |
+ { .bitrate = 120, .hw_value = 0x06, }, |
148 |
+ { .bitrate = 180, .hw_value = 0x07, }, |
149 |
+ { .bitrate = 240, .hw_value = 0x08, }, |
150 |
+ { .bitrate = 360, .hw_value = 0x09, }, |
151 |
+ { .bitrate = 480, .hw_value = 0x0a, }, |
152 |
+ { .bitrate = 540, .hw_value = 0x0b, }, |
153 |
+}; |
154 |
+ |
155 |
+u16 rtw89_ra_report_to_bitrate(struct rtw89_dev *rtwdev, u8 rpt_rate) |
156 |
+{ |
157 |
+ struct ieee80211_rate rate; |
158 |
+ |
159 |
+ if (unlikely(rpt_rate >= ARRAY_SIZE(rtw89_bitrates))) { |
160 |
+ rtw89_info(rtwdev, "invalid rpt rate %d\n", rpt_rate); |
161 |
+ return 0; |
162 |
+ } |
163 |
+ |
164 |
+ rate = rtw89_bitrates[rpt_rate]; |
165 |
+ |
166 |
+ return rate.bitrate; |
167 |
+} |
168 |
+ |
169 |
+static struct ieee80211_supported_band rtw89_sband_2ghz = { |
170 |
+ .band = NL80211_BAND_2GHZ, |
171 |
+ .channels = rtw89_channels_2ghz, |
172 |
+ .n_channels = ARRAY_SIZE(rtw89_channels_2ghz), |
173 |
+ .bitrates = rtw89_bitrates, |
174 |
+ .n_bitrates = ARRAY_SIZE(rtw89_bitrates), |
175 |
+ .ht_cap = {0}, |
176 |
+ .vht_cap = {0}, |
177 |
+}; |
178 |
+ |
179 |
+static struct ieee80211_supported_band rtw89_sband_5ghz = { |
180 |
+ .band = NL80211_BAND_5GHZ, |
181 |
+ .channels = rtw89_channels_5ghz, |
182 |
+ .n_channels = ARRAY_SIZE(rtw89_channels_5ghz), |
183 |
+ |
184 |
+ /* 5G has no CCK rates, 1M/2M/5.5M/11M */ |
185 |
+ .bitrates = rtw89_bitrates + 4, |
186 |
+ .n_bitrates = ARRAY_SIZE(rtw89_bitrates) - 4, |
187 |
+ .ht_cap = {0}, |
188 |
+ .vht_cap = {0}, |
189 |
+}; |
190 |
+ |
191 |
+static void rtw89_traffic_stats_accu(struct rtw89_dev *rtwdev, |
192 |
+ struct rtw89_traffic_stats *stats, |
193 |
+ struct sk_buff *skb, bool tx) |
194 |
+{ |
195 |
+ struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)skb->data; |
196 |
+ |
197 |
+ if (!ieee80211_is_data(hdr->frame_control)) |
198 |
+ return; |
199 |
+ |
200 |
+ if (is_broadcast_ether_addr(hdr->addr1) || |
201 |
+ is_multicast_ether_addr(hdr->addr1)) |
202 |
+ return; |
203 |
+ |
204 |
+ if (tx) { |
205 |
+ stats->tx_cnt++; |
206 |
+ stats->tx_unicast += skb->len; |
207 |
+ } else { |
208 |
+ stats->rx_cnt++; |
209 |
+ stats->rx_unicast += skb->len; |
210 |
+ } |
211 |
+} |
212 |
+ |
213 |
+static void rtw89_get_channel_params(struct cfg80211_chan_def *chandef, |
214 |
+ struct rtw89_channel_params *chan_param) |
215 |
+{ |
216 |
+ struct ieee80211_channel *channel = chandef->chan; |
217 |
+ enum nl80211_chan_width width = chandef->width; |
218 |
+ u8 *cch_by_bw = chan_param->cch_by_bw; |
219 |
+ u32 primary_freq, center_freq; |
220 |
+ u8 center_chan; |
221 |
+ u8 bandwidth = RTW89_CHANNEL_WIDTH_20; |
222 |
+ u8 primary_chan_idx = 0; |
223 |
+ u8 i; |
224 |
+ |
225 |
+ center_chan = channel->hw_value; |
226 |
+ primary_freq = channel->center_freq; |
227 |
+ center_freq = chandef->center_freq1; |
228 |
+ |
229 |
+ /* assign the center channel used while 20M bw is selected */ |
230 |
+ cch_by_bw[RTW89_CHANNEL_WIDTH_20] = channel->hw_value; |
231 |
+ |
232 |
+ switch (width) { |
233 |
+ case NL80211_CHAN_WIDTH_20_NOHT: |
234 |
+ case NL80211_CHAN_WIDTH_20: |
235 |
+ bandwidth = RTW89_CHANNEL_WIDTH_20; |
236 |
+ primary_chan_idx = RTW89_SC_DONT_CARE; |
237 |
+ break; |
238 |
+ case NL80211_CHAN_WIDTH_40: |
239 |
+ bandwidth = RTW89_CHANNEL_WIDTH_40; |
240 |
+ if (primary_freq > center_freq) { |
241 |
+ primary_chan_idx = RTW89_SC_20_UPPER; |
242 |
+ center_chan -= 2; |
243 |
+ } else { |
244 |
+ primary_chan_idx = RTW89_SC_20_LOWER; |
245 |
+ center_chan += 2; |
246 |
+ } |
247 |
+ break; |
248 |
+ case NL80211_CHAN_WIDTH_80: |
249 |
+ bandwidth = RTW89_CHANNEL_WIDTH_80; |
250 |
+ if (primary_freq > center_freq) { |
251 |
+ if (primary_freq - center_freq == 10) { |
252 |
+ primary_chan_idx = RTW89_SC_20_UPPER; |
253 |
+ center_chan -= 2; |
254 |
+ } else { |
255 |
+ primary_chan_idx = RTW89_SC_20_UPMOST; |
256 |
+ center_chan -= 6; |
257 |
+ } |
258 |
+ /* assign the center channel used |
259 |
+ * while 40M bw is selected |
260 |
+ */ |
261 |
+ cch_by_bw[RTW89_CHANNEL_WIDTH_40] = center_chan + 4; |
262 |
+ } else { |
263 |
+ if (center_freq - primary_freq == 10) { |
264 |
+ primary_chan_idx = RTW89_SC_20_LOWER; |
265 |
+ center_chan += 2; |
266 |
+ } else { |
267 |
+ primary_chan_idx = RTW89_SC_20_LOWEST; |
268 |
+ center_chan += 6; |
269 |
+ } |
270 |
+ /* assign the center channel used |
271 |
+ * while 40M bw is selected |
272 |
+ */ |
273 |
+ cch_by_bw[RTW89_CHANNEL_WIDTH_40] = center_chan - 4; |
274 |
+ } |
275 |
+ break; |
276 |
+ default: |
277 |
+ center_chan = 0; |
278 |
+ break; |
279 |
+ } |
280 |
+ |
281 |
+ chan_param->center_chan = center_chan; |
282 |
+ chan_param->primary_chan = channel->hw_value; |
283 |
+ chan_param->bandwidth = bandwidth; |
284 |
+ chan_param->pri_ch_idx = primary_chan_idx; |
285 |
+ |
286 |
+ /* assign the center channel used while current bw is selected */ |
287 |
+ cch_by_bw[bandwidth] = center_chan; |
288 |
+ |
289 |
+ for (i = bandwidth + 1; i <= RTW89_MAX_CHANNEL_WIDTH; i++) |
290 |
+ cch_by_bw[i] = 0; |
291 |
+} |
292 |
+ |
293 |
+void rtw89_set_channel(struct rtw89_dev *rtwdev) |
294 |
+{ |
295 |
+ struct ieee80211_hw *hw = rtwdev->hw; |
296 |
+ const struct rtw89_chip_info *chip = rtwdev->chip; |
297 |
+ struct rtw89_hal *hal = &rtwdev->hal; |
298 |
+ struct rtw89_channel_params ch_param; |
299 |
+ struct rtw89_channel_help_params bak; |
300 |
+ u8 center_chan, bandwidth; |
301 |
+ u8 band_type; |
302 |
+ bool band_changed; |
303 |
+ u8 i; |
304 |
+ |
305 |
+ rtw89_get_channel_params(&hw->conf.chandef, &ch_param); |
306 |
+ if (WARN(ch_param.center_chan == 0, "Invalid channel\n")) |
307 |
+ return; |
308 |
+ |
309 |
+ center_chan = ch_param.center_chan; |
310 |
+ bandwidth = ch_param.bandwidth; |
311 |
+ band_type = center_chan > 14 ? RTW89_BAND_5G : RTW89_BAND_2G; |
312 |
+ band_changed = hal->current_band_type != band_type || |
313 |
+ hal->current_channel == 0; |
314 |
+ |
315 |
+ hal->current_band_width = bandwidth; |
316 |
+ hal->current_channel = center_chan; |
317 |
+ hal->current_primary_channel = ch_param.primary_chan; |
318 |
+ hal->current_band_type = band_type; |
319 |
+ |
320 |
+ switch (center_chan) { |
321 |
+ case 1 ... 14: |
322 |
+ hal->current_subband = RTW89_CH_2G; |
323 |
+ break; |
324 |
+ case 36 ... 64: |
325 |
+ hal->current_subband = RTW89_CH_5G_BAND_1; |
326 |
+ break; |
327 |
+ case 100 ... 144: |
328 |
+ hal->current_subband = RTW89_CH_5G_BAND_3; |
329 |
+ break; |
330 |
+ case 149 ... 177: |
331 |
+ hal->current_subband = RTW89_CH_5G_BAND_4; |
332 |
+ break; |
333 |
+ } |
334 |
+ |
335 |
+ for (i = RTW89_CHANNEL_WIDTH_20; i <= RTW89_MAX_CHANNEL_WIDTH; i++) |
336 |
+ hal->cch_by_bw[i] = ch_param.cch_by_bw[i]; |
337 |
+ |
338 |
+ rtw89_chip_set_channel_prepare(rtwdev, &bak); |
339 |
+ |
340 |
+ chip->ops->set_channel(rtwdev, &ch_param); |
341 |
+ |
342 |
+ rtw89_chip_set_txpwr(rtwdev); |
343 |
+ |
344 |
+ rtw89_chip_set_channel_done(rtwdev, &bak); |
345 |
+ |
346 |
+ if (band_changed) { |
347 |
+ rtw89_btc_ntfy_switch_band(rtwdev, RTW89_PHY_0, hal->current_band_type); |
348 |
+ rtw89_chip_rfk_band_changed(rtwdev); |
349 |
+ } |
350 |
+} |
351 |
+ |
352 |
+static enum rtw89_core_tx_type |
353 |
+rtw89_core_get_tx_type(struct rtw89_dev *rtwdev, |
354 |
+ struct sk_buff *skb) |
355 |
+{ |
356 |
+ struct ieee80211_hdr *hdr = (void *)skb->data; |
357 |
+ __le16 fc = hdr->frame_control; |
358 |
+ |
359 |
+ if (ieee80211_is_mgmt(fc) || ieee80211_is_nullfunc(fc)) |
360 |
+ return RTW89_CORE_TX_TYPE_MGMT; |
361 |
+ |
362 |
+ return RTW89_CORE_TX_TYPE_DATA; |
363 |
+} |
364 |
+ |
365 |
+static void |
366 |
+rtw89_core_tx_update_ampdu_info(struct rtw89_dev *rtwdev, |
367 |
+ struct rtw89_core_tx_request *tx_req, u8 tid) |
368 |
+{ |
369 |
+ struct ieee80211_sta *sta = tx_req->sta; |
370 |
+ struct rtw89_tx_desc_info *desc_info = &tx_req->desc_info; |
371 |
+ struct rtw89_sta *rtwsta; |
372 |
+ u8 ampdu_num; |
373 |
+ |
374 |
+ if (!sta) { |
375 |
+ rtw89_warn(rtwdev, "cannot set ampdu info without sta\n"); |
376 |
+ return; |
377 |
+ } |
378 |
+ |
379 |
+ rtwsta = (struct rtw89_sta *)sta->drv_priv; |
380 |
+ |
381 |
+ ampdu_num = (u8)((rtwsta->ampdu_params[tid].agg_num ? |
382 |
+ rtwsta->ampdu_params[tid].agg_num : |
383 |
+ 4 << sta->ht_cap.ampdu_factor) - 1); |
384 |
+ |
385 |
+ desc_info->agg_en = true; |
386 |
+ desc_info->ampdu_density = sta->ht_cap.ampdu_density; |
387 |
+ desc_info->ampdu_num = ampdu_num; |
388 |
+} |
389 |
+ |
390 |
+static void |
391 |
+rtw89_core_tx_update_sec_key(struct rtw89_dev *rtwdev, |
392 |
+ struct rtw89_core_tx_request *tx_req) |
393 |
+{ |
394 |
+ struct ieee80211_vif *vif = tx_req->vif; |
395 |
+ struct ieee80211_tx_info *info; |
396 |
+ struct ieee80211_key_conf *key; |
397 |
+ struct rtw89_vif *rtwvif; |
398 |
+ struct rtw89_addr_cam_entry *addr_cam; |
399 |
+ struct rtw89_sec_cam_entry *sec_cam; |
400 |
+ struct rtw89_tx_desc_info *desc_info = &tx_req->desc_info; |
401 |
+ struct sk_buff *skb = tx_req->skb; |
402 |
+ u8 sec_type = RTW89_SEC_KEY_TYPE_NONE; |
403 |
+ |
404 |
+ if (!vif) { |
405 |
+ rtw89_warn(rtwdev, "cannot set sec key without vif\n"); |
406 |
+ return; |
407 |
+ } |
408 |
+ |
409 |
+ rtwvif = (struct rtw89_vif *)vif->drv_priv; |
410 |
+ addr_cam = &rtwvif->addr_cam; |
411 |
+ |
412 |
+ info = IEEE80211_SKB_CB(skb); |
413 |
+ key = info->control.hw_key; |
414 |
+ sec_cam = addr_cam->sec_entries[key->hw_key_idx]; |
415 |
+ if (!sec_cam) { |
416 |
+ rtw89_warn(rtwdev, "sec cam entry is empty\n"); |
417 |
+ return; |
418 |
+ } |
419 |
+ |
420 |
+ switch (key->cipher) { |
421 |
+ case WLAN_CIPHER_SUITE_WEP40: |
422 |
+ sec_type = RTW89_SEC_KEY_TYPE_WEP40; |
423 |
+ break; |
424 |
+ case WLAN_CIPHER_SUITE_WEP104: |
425 |
+ sec_type = RTW89_SEC_KEY_TYPE_WEP104; |
426 |
+ break; |
427 |
+ case WLAN_CIPHER_SUITE_TKIP: |
428 |
+ sec_type = RTW89_SEC_KEY_TYPE_TKIP; |
429 |
+ break; |
430 |
+ case WLAN_CIPHER_SUITE_CCMP: |
431 |
+ sec_type = RTW89_SEC_KEY_TYPE_CCMP128; |
432 |
+ break; |
433 |
+ case WLAN_CIPHER_SUITE_CCMP_256: |
434 |
+ sec_type = RTW89_SEC_KEY_TYPE_CCMP256; |
435 |
+ break; |
436 |
+ case WLAN_CIPHER_SUITE_GCMP: |
437 |
+ sec_type = RTW89_SEC_KEY_TYPE_GCMP128; |
438 |
+ break; |
439 |
+ case WLAN_CIPHER_SUITE_GCMP_256: |
440 |
+ sec_type = RTW89_SEC_KEY_TYPE_GCMP256; |
441 |
+ break; |
442 |
+ default: |
443 |
+ rtw89_warn(rtwdev, "key cipher not supported %d\n", key->cipher); |
444 |
+ return; |
445 |
+ } |
446 |
+ |
447 |
+ desc_info->sec_en = true; |
448 |
+ desc_info->sec_type = sec_type; |
449 |
+ desc_info->sec_cam_idx = sec_cam->sec_cam_idx; |
450 |
+} |
451 |
+ |
452 |
+static u16 rtw89_core_get_mgmt_rate(struct rtw89_dev *rtwdev, |
453 |
+ struct rtw89_core_tx_request *tx_req) |
454 |
+{ |
455 |
+ struct sk_buff *skb = tx_req->skb; |
456 |
+ struct ieee80211_tx_info *tx_info = IEEE80211_SKB_CB(skb); |
457 |
+ struct ieee80211_vif *vif = tx_info->control.vif; |
458 |
+ struct rtw89_hal *hal = &rtwdev->hal; |
459 |
+ u16 lowest_rate = hal->current_band_type == RTW89_BAND_2G ? |
460 |
+ RTW89_HW_RATE_CCK1 : RTW89_HW_RATE_OFDM6; |
461 |
+ |
462 |
+ if (!vif || !vif->bss_conf.basic_rates || !tx_req->sta) |
463 |
+ return lowest_rate; |
464 |
+ |
465 |
+ return __ffs(vif->bss_conf.basic_rates) + lowest_rate; |
466 |
+} |
467 |
+ |
468 |
+static void |
469 |
+rtw89_core_tx_update_mgmt_info(struct rtw89_dev *rtwdev, |
470 |
+ struct rtw89_core_tx_request *tx_req) |
471 |
+{ |
472 |
+ struct rtw89_tx_desc_info *desc_info = &tx_req->desc_info; |
473 |
+ u8 qsel, ch_dma; |
474 |
+ |
475 |
+ qsel = RTW89_TX_QSEL_B0_MGMT; |
476 |
+ ch_dma = rtw89_core_get_ch_dma(rtwdev, qsel); |
477 |
+ |
478 |
+ desc_info->qsel = RTW89_TX_QSEL_B0_MGMT; |
479 |
+ desc_info->ch_dma = ch_dma; |
480 |
+ |
481 |
+ /* fixed data rate for mgmt frames */ |
482 |
+ desc_info->en_wd_info = true; |
483 |
+ desc_info->use_rate = true; |
484 |
+ desc_info->dis_data_fb = true; |
485 |
+ desc_info->data_rate = rtw89_core_get_mgmt_rate(rtwdev, tx_req); |
486 |
+ |
487 |
+ rtw89_debug(rtwdev, RTW89_DBG_TXRX, |
488 |
+ "tx mgmt frame with rate 0x%x on channel %d (bw %d)\n", |
489 |
+ desc_info->data_rate, rtwdev->hal.current_channel, |
490 |
+ rtwdev->hal.current_band_width); |
491 |
+} |
492 |
+ |
493 |
+static void |
494 |
+rtw89_core_tx_update_h2c_info(struct rtw89_dev *rtwdev, |
495 |
+ struct rtw89_core_tx_request *tx_req) |
496 |
+{ |
497 |
+ struct rtw89_tx_desc_info *desc_info = &tx_req->desc_info; |
498 |
+ |
499 |
+ desc_info->is_bmc = false; |
500 |
+ desc_info->wd_page = false; |
501 |
+ desc_info->ch_dma = RTW89_DMA_H2C; |
502 |
+} |
503 |
+ |
504 |
+static void rtw89_core_get_no_ul_ofdma_htc(struct rtw89_dev *rtwdev, __le32 *htc) |
505 |
+{ |
506 |
+ static const u8 rtw89_bandwidth_to_om[] = { |
507 |
+ [RTW89_CHANNEL_WIDTH_20] = HTC_OM_CHANNEL_WIDTH_20, |
508 |
+ [RTW89_CHANNEL_WIDTH_40] = HTC_OM_CHANNEL_WIDTH_40, |
509 |
+ [RTW89_CHANNEL_WIDTH_80] = HTC_OM_CHANNEL_WIDTH_80, |
510 |
+ [RTW89_CHANNEL_WIDTH_160] = HTC_OM_CHANNEL_WIDTH_160_OR_80_80, |
511 |
+ [RTW89_CHANNEL_WIDTH_80_80] = HTC_OM_CHANNEL_WIDTH_160_OR_80_80, |
512 |
+ }; |
513 |
+ const struct rtw89_chip_info *chip = rtwdev->chip; |
514 |
+ struct rtw89_hal *hal = &rtwdev->hal; |
515 |
+ u8 om_bandwidth; |
516 |
+ |
517 |
+ if (!chip->dis_2g_40m_ul_ofdma || |
518 |
+ hal->current_band_type != RTW89_BAND_2G || |
519 |
+ hal->current_band_width != RTW89_CHANNEL_WIDTH_40) |
520 |
+ return; |
521 |
+ |
522 |
+ om_bandwidth = hal->current_band_width < ARRAY_SIZE(rtw89_bandwidth_to_om) ? |
523 |
+ rtw89_bandwidth_to_om[hal->current_band_width] : 0; |
524 |
+ *htc = le32_encode_bits(RTW89_HTC_VARIANT_HE, RTW89_HTC_MASK_VARIANT) | |
525 |
+ le32_encode_bits(RTW89_HTC_VARIANT_HE_CID_OM, RTW89_HTC_MASK_CTL_ID) | |
526 |
+ le32_encode_bits(hal->rx_nss - 1, RTW89_HTC_MASK_HTC_OM_RX_NSS) | |
527 |
+ le32_encode_bits(om_bandwidth, RTW89_HTC_MASK_HTC_OM_CH_WIDTH) | |
528 |
+ le32_encode_bits(1, RTW89_HTC_MASK_HTC_OM_UL_MU_DIS) | |
529 |
+ le32_encode_bits(hal->tx_nss - 1, RTW89_HTC_MASK_HTC_OM_TX_NSTS) | |
530 |
+ le32_encode_bits(0, RTW89_HTC_MASK_HTC_OM_ER_SU_DIS) | |
531 |
+ le32_encode_bits(0, RTW89_HTC_MASK_HTC_OM_DL_MU_MIMO_RR) | |
532 |
+ le32_encode_bits(0, RTW89_HTC_MASK_HTC_OM_UL_MU_DATA_DIS); |
533 |
+} |
534 |
+ |
535 |
+static bool |
536 |
+__rtw89_core_tx_check_he_qos_htc(struct rtw89_dev *rtwdev, |
537 |
+ struct rtw89_core_tx_request *tx_req, |
538 |
+ enum btc_pkt_type pkt_type) |
539 |
+{ |
540 |
+ struct ieee80211_sta *sta = tx_req->sta; |
541 |
+ struct sk_buff *skb = tx_req->skb; |
542 |
+ struct ieee80211_hdr *hdr = (void *)skb->data; |
543 |
+ __le16 fc = hdr->frame_control; |
544 |
+ |
545 |
+ /* AP IOT issue with EAPoL, ARP and DHCP */ |
546 |
+ if (pkt_type < PACKET_MAX) |
547 |
+ return false; |
548 |
+ |
549 |
+ if (!sta || !sta->he_cap.has_he) |
550 |
+ return false; |
551 |
+ |
552 |
+ if (!ieee80211_is_data_qos(fc)) |
553 |
+ return false; |
554 |
+ |
555 |
+ if (skb_headroom(skb) < IEEE80211_HT_CTL_LEN) |
556 |
+ return false; |
557 |
+ |
558 |
+ return true; |
559 |
+} |
560 |
+ |
561 |
+static void |
562 |
+__rtw89_core_tx_adjust_he_qos_htc(struct rtw89_dev *rtwdev, |
563 |
+ struct rtw89_core_tx_request *tx_req) |
564 |
+{ |
565 |
+ struct ieee80211_sta *sta = tx_req->sta; |
566 |
+ struct rtw89_sta *rtwsta = (struct rtw89_sta *)sta->drv_priv; |
567 |
+ struct sk_buff *skb = tx_req->skb; |
568 |
+ struct ieee80211_hdr *hdr = (void *)skb->data; |
569 |
+ __le16 fc = hdr->frame_control; |
570 |
+ void *data; |
571 |
+ __le32 *htc; |
572 |
+ u8 *qc; |
573 |
+ int hdr_len; |
574 |
+ |
575 |
+ hdr_len = ieee80211_has_a4(fc) ? 32 : 26; |
576 |
+ data = skb_push(skb, IEEE80211_HT_CTL_LEN); |
577 |
+ memmove(data, data + IEEE80211_HT_CTL_LEN, hdr_len); |
578 |
+ |
579 |
+ hdr = data; |
580 |
+ htc = data + hdr_len; |
581 |
+ hdr->frame_control |= cpu_to_le16(IEEE80211_FCTL_ORDER); |
582 |
+ *htc = rtwsta->htc_template ? rtwsta->htc_template : |
583 |
+ le32_encode_bits(RTW89_HTC_VARIANT_HE, RTW89_HTC_MASK_VARIANT) | |
584 |
+ le32_encode_bits(RTW89_HTC_VARIANT_HE_CID_CAS, RTW89_HTC_MASK_CTL_ID); |
585 |
+ |
586 |
+ qc = data + hdr_len - IEEE80211_QOS_CTL_LEN; |
587 |
+ qc[0] |= IEEE80211_QOS_CTL_EOSP; |
588 |
+} |
589 |
+ |
590 |
+static void |
591 |
+rtw89_core_tx_update_he_qos_htc(struct rtw89_dev *rtwdev, |
592 |
+ struct rtw89_core_tx_request *tx_req, |
593 |
+ enum btc_pkt_type pkt_type) |
594 |
+{ |
595 |
+ struct rtw89_tx_desc_info *desc_info = &tx_req->desc_info; |
596 |
+ struct ieee80211_vif *vif = tx_req->vif; |
597 |
+ struct rtw89_vif *rtwvif = (struct rtw89_vif *)vif->drv_priv; |
598 |
+ |
599 |
+ if (!__rtw89_core_tx_check_he_qos_htc(rtwdev, tx_req, pkt_type)) |
600 |
+ goto desc_bk; |
601 |
+ |
602 |
+ __rtw89_core_tx_adjust_he_qos_htc(rtwdev, tx_req); |
603 |
+ |
604 |
+ desc_info->pkt_size += IEEE80211_HT_CTL_LEN; |
605 |
+ desc_info->a_ctrl_bsr = true; |
606 |
+ |
607 |
+desc_bk: |
608 |
+ if (!rtwvif || rtwvif->last_a_ctrl == desc_info->a_ctrl_bsr) |
609 |
+ return; |
610 |
+ |
611 |
+ rtwvif->last_a_ctrl = desc_info->a_ctrl_bsr; |
612 |
+ desc_info->bk = true; |
613 |
+} |
614 |
+ |
615 |
+static void |
616 |
+rtw89_core_tx_update_data_info(struct rtw89_dev *rtwdev, |
617 |
+ struct rtw89_core_tx_request *tx_req) |
618 |
+{ |
619 |
+ struct ieee80211_vif *vif = tx_req->vif; |
620 |
+ struct rtw89_vif *rtwvif = (struct rtw89_vif *)vif->drv_priv; |
621 |
+ struct rtw89_phy_rate_pattern *rate_pattern = &rtwvif->rate_pattern; |
622 |
+ struct rtw89_hal *hal = &rtwdev->hal; |
623 |
+ struct rtw89_tx_desc_info *desc_info = &tx_req->desc_info; |
624 |
+ struct sk_buff *skb = tx_req->skb; |
625 |
+ u8 tid, tid_indicate; |
626 |
+ u8 qsel, ch_dma; |
627 |
+ |
628 |
+ tid = skb->priority & IEEE80211_QOS_CTL_TAG1D_MASK; |
629 |
+ tid_indicate = rtw89_core_get_tid_indicate(rtwdev, tid); |
630 |
+ qsel = rtw89_core_get_qsel(rtwdev, tid); |
631 |
+ ch_dma = rtw89_core_get_ch_dma(rtwdev, qsel); |
632 |
+ |
633 |
+ desc_info->ch_dma = ch_dma; |
634 |
+ desc_info->tid_indicate = tid_indicate; |
635 |
+ desc_info->qsel = qsel; |
636 |
+ |
637 |
+ /* enable wd_info for AMPDU */ |
638 |
+ desc_info->en_wd_info = true; |
639 |
+ |
640 |
+ if (IEEE80211_SKB_CB(skb)->flags & IEEE80211_TX_CTL_AMPDU) |
641 |
+ rtw89_core_tx_update_ampdu_info(rtwdev, tx_req, tid); |
642 |
+ if (IEEE80211_SKB_CB(skb)->control.hw_key) |
643 |
+ rtw89_core_tx_update_sec_key(rtwdev, tx_req); |
644 |
+ |
645 |
+ if (rate_pattern->enable) |
646 |
+ desc_info->data_retry_lowest_rate = rate_pattern->rate; |
647 |
+ else if (hal->current_band_type == RTW89_BAND_2G) |
648 |
+ desc_info->data_retry_lowest_rate = RTW89_HW_RATE_CCK1; |
649 |
+ else |
650 |
+ desc_info->data_retry_lowest_rate = RTW89_HW_RATE_OFDM6; |
651 |
+} |
652 |
+ |
653 |
+static enum btc_pkt_type |
654 |
+rtw89_core_tx_btc_spec_pkt_notify(struct rtw89_dev *rtwdev, |
655 |
+ struct rtw89_core_tx_request *tx_req) |
656 |
+{ |
657 |
+ struct sk_buff *skb = tx_req->skb; |
658 |
+ struct udphdr *udphdr; |
659 |
+ |
660 |
+ if (IEEE80211_SKB_CB(skb)->control.flags & IEEE80211_TX_CTRL_PORT_CTRL_PROTO) { |
661 |
+ ieee80211_queue_work(rtwdev->hw, &rtwdev->btc.eapol_notify_work); |
662 |
+ return PACKET_EAPOL; |
663 |
+ } |
664 |
+ |
665 |
+ if (skb->protocol == htons(ETH_P_ARP)) { |
666 |
+ ieee80211_queue_work(rtwdev->hw, &rtwdev->btc.arp_notify_work); |
667 |
+ return PACKET_ARP; |
668 |
+ } |
669 |
+ |
670 |
+ if (skb->protocol == htons(ETH_P_IP) && |
671 |
+ ip_hdr(skb)->protocol == IPPROTO_UDP) { |
672 |
+ udphdr = udp_hdr(skb); |
673 |
+ if (((udphdr->source == htons(67) && udphdr->dest == htons(68)) || |
674 |
+ (udphdr->source == htons(68) && udphdr->dest == htons(67))) && |
675 |
+ skb->len > 282) { |
676 |
+ ieee80211_queue_work(rtwdev->hw, &rtwdev->btc.dhcp_notify_work); |
677 |
+ return PACKET_DHCP; |
678 |
+ } |
679 |
+ } |
680 |
+ |
681 |
+ if (skb->protocol == htons(ETH_P_IP) && |
682 |
+ ip_hdr(skb)->protocol == IPPROTO_ICMP) { |
683 |
+ ieee80211_queue_work(rtwdev->hw, &rtwdev->btc.icmp_notify_work); |
684 |
+ return PACKET_ICMP; |
685 |
+ } |
686 |
+ |
687 |
+ return PACKET_MAX; |
688 |
+} |
689 |
+ |
690 |
+static void |
691 |
+rtw89_core_tx_update_desc_info(struct rtw89_dev *rtwdev, |
692 |
+ struct rtw89_core_tx_request *tx_req) |
693 |
+{ |
694 |
+ struct rtw89_tx_desc_info *desc_info = &tx_req->desc_info; |
695 |
+ struct sk_buff *skb = tx_req->skb; |
696 |
+ struct ieee80211_hdr *hdr = (void *)skb->data; |
697 |
+ enum rtw89_core_tx_type tx_type; |
698 |
+ enum btc_pkt_type pkt_type; |
699 |
+ bool is_bmc; |
700 |
+ u16 seq; |
701 |
+ |
702 |
+ seq = (le16_to_cpu(hdr->seq_ctrl) & IEEE80211_SCTL_SEQ) >> 4; |
703 |
+ if (tx_req->tx_type != RTW89_CORE_TX_TYPE_FWCMD) { |
704 |
+ tx_type = rtw89_core_get_tx_type(rtwdev, skb); |
705 |
+ tx_req->tx_type = tx_type; |
706 |
+ } |
707 |
+ is_bmc = (is_broadcast_ether_addr(hdr->addr1) || |
708 |
+ is_multicast_ether_addr(hdr->addr1)); |
709 |
+ |
710 |
+ desc_info->seq = seq; |
711 |
+ desc_info->pkt_size = skb->len; |
712 |
+ desc_info->is_bmc = is_bmc; |
713 |
+ desc_info->wd_page = true; |
714 |
+ |
715 |
+ switch (tx_req->tx_type) { |
716 |
+ case RTW89_CORE_TX_TYPE_MGMT: |
717 |
+ rtw89_core_tx_update_mgmt_info(rtwdev, tx_req); |
718 |
+ break; |
719 |
+ case RTW89_CORE_TX_TYPE_DATA: |
720 |
+ rtw89_core_tx_update_data_info(rtwdev, tx_req); |
721 |
+ pkt_type = rtw89_core_tx_btc_spec_pkt_notify(rtwdev, tx_req); |
722 |
+ rtw89_core_tx_update_he_qos_htc(rtwdev, tx_req, pkt_type); |
723 |
+ break; |
724 |
+ case RTW89_CORE_TX_TYPE_FWCMD: |
725 |
+ rtw89_core_tx_update_h2c_info(rtwdev, tx_req); |
726 |
+ break; |
727 |
+ } |
728 |
+} |
729 |
+ |
730 |
+void rtw89_core_tx_kick_off(struct rtw89_dev *rtwdev, u8 qsel) |
731 |
+{ |
732 |
+ u8 ch_dma; |
733 |
+ |
734 |
+ ch_dma = rtw89_core_get_ch_dma(rtwdev, qsel); |
735 |
+ |
736 |
+ rtw89_hci_tx_kick_off(rtwdev, ch_dma); |
737 |
+} |
738 |
+ |
739 |
+int rtw89_h2c_tx(struct rtw89_dev *rtwdev, |
740 |
+ struct sk_buff *skb, bool fwdl) |
741 |
+{ |
742 |
+ struct rtw89_core_tx_request tx_req = {0}; |
743 |
+ u32 cnt; |
744 |
+ int ret; |
745 |
+ |
746 |
+ tx_req.skb = skb; |
747 |
+ tx_req.tx_type = RTW89_CORE_TX_TYPE_FWCMD; |
748 |
+ if (fwdl) |
749 |
+ tx_req.desc_info.fw_dl = true; |
750 |
+ |
751 |
+ rtw89_core_tx_update_desc_info(rtwdev, &tx_req); |
752 |
+ |
753 |
+ if (!fwdl) |
754 |
+ rtw89_hex_dump(rtwdev, RTW89_DBG_FW, "H2C: ", skb->data, skb->len); |
755 |
+ |
756 |
+ cnt = rtw89_hci_check_and_reclaim_tx_resource(rtwdev, RTW89_TXCH_CH12); |
757 |
+ if (cnt == 0) { |
758 |
+ rtw89_err(rtwdev, "no tx fwcmd resource\n"); |
759 |
+ return -ENOSPC; |
760 |
+ } |
761 |
+ |
762 |
+ ret = rtw89_hci_tx_write(rtwdev, &tx_req); |
763 |
+ if (ret) { |
764 |
+ rtw89_err(rtwdev, "failed to transmit skb to HCI\n"); |
765 |
+ return ret; |
766 |
+ } |
767 |
+ rtw89_hci_tx_kick_off(rtwdev, RTW89_TXCH_CH12); |
768 |
+ |
769 |
+ return 0; |
770 |
+} |
771 |
+ |
772 |
+int rtw89_core_tx_write(struct rtw89_dev *rtwdev, struct ieee80211_vif *vif, |
773 |
+ struct ieee80211_sta *sta, struct sk_buff *skb, int *qsel) |
774 |
+{ |
775 |
+ struct rtw89_core_tx_request tx_req = {0}; |
776 |
+ struct rtw89_vif *rtwvif = (struct rtw89_vif *)vif->drv_priv; |
777 |
+ int ret; |
778 |
+ |
779 |
+ tx_req.skb = skb; |
780 |
+ tx_req.sta = sta; |
781 |
+ tx_req.vif = vif; |
782 |
+ |
783 |
+ rtw89_traffic_stats_accu(rtwdev, &rtwdev->stats, skb, true); |
784 |
+ rtw89_traffic_stats_accu(rtwdev, &rtwvif->stats, skb, true); |
785 |
+ rtw89_core_tx_update_desc_info(rtwdev, &tx_req); |
786 |
+ ret = rtw89_hci_tx_write(rtwdev, &tx_req); |
787 |
+ if (ret) { |
788 |
+ rtw89_err(rtwdev, "failed to transmit skb to HCI\n"); |
789 |
+ return ret; |
790 |
+ } |
791 |
+ |
792 |
+ if (qsel) |
793 |
+ *qsel = tx_req.desc_info.qsel; |
794 |
+ |
795 |
+ return 0; |
796 |
+} |
797 |
+ |
798 |
+static __le32 rtw89_build_txwd_body0(struct rtw89_tx_desc_info *desc_info) |
799 |
+{ |
800 |
+ u32 dword = FIELD_PREP(RTW89_TXWD_BODY0_WP_OFFSET, desc_info->wp_offset) | |
801 |
+ FIELD_PREP(RTW89_TXWD_BODY0_WD_INFO_EN, desc_info->en_wd_info) | |
802 |
+ FIELD_PREP(RTW89_TXWD_BODY0_CHANNEL_DMA, desc_info->ch_dma) | |
803 |
+ FIELD_PREP(RTW89_TXWD_BODY0_HDR_LLC_LEN, desc_info->hdr_llc_len) | |
804 |
+ FIELD_PREP(RTW89_TXWD_BODY0_WD_PAGE, desc_info->wd_page) | |
805 |
+ FIELD_PREP(RTW89_TXWD_BODY0_FW_DL, desc_info->fw_dl); |
806 |
+ |
807 |
+ return cpu_to_le32(dword); |
808 |
+} |
809 |
+ |
810 |
+static __le32 rtw89_build_txwd_body2(struct rtw89_tx_desc_info *desc_info) |
811 |
+{ |
812 |
+ u32 dword = FIELD_PREP(RTW89_TXWD_BODY2_TID_INDICATE, desc_info->tid_indicate) | |
813 |
+ FIELD_PREP(RTW89_TXWD_BODY2_QSEL, desc_info->qsel) | |
814 |
+ FIELD_PREP(RTW89_TXWD_BODY2_TXPKT_SIZE, desc_info->pkt_size); |
815 |
+ |
816 |
+ return cpu_to_le32(dword); |
817 |
+} |
818 |
+ |
819 |
+static __le32 rtw89_build_txwd_body3(struct rtw89_tx_desc_info *desc_info) |
820 |
+{ |
821 |
+ u32 dword = FIELD_PREP(RTW89_TXWD_BODY3_SW_SEQ, desc_info->seq) | |
822 |
+ FIELD_PREP(RTW89_TXWD_BODY3_AGG_EN, desc_info->agg_en) | |
823 |
+ FIELD_PREP(RTW89_TXWD_BODY3_BK, desc_info->bk); |
824 |
+ |
825 |
+ return cpu_to_le32(dword); |
826 |
+} |
827 |
+ |
828 |
+static __le32 rtw89_build_txwd_info0(struct rtw89_tx_desc_info *desc_info) |
829 |
+{ |
830 |
+ u32 dword = FIELD_PREP(RTW89_TXWD_INFO0_USE_RATE, desc_info->use_rate) | |
831 |
+ FIELD_PREP(RTW89_TXWD_INFO0_DATA_RATE, desc_info->data_rate) | |
832 |
+ FIELD_PREP(RTW89_TXWD_INFO0_DISDATAFB, desc_info->dis_data_fb); |
833 |
+ |
834 |
+ return cpu_to_le32(dword); |
835 |
+} |
836 |
+ |
837 |
+static __le32 rtw89_build_txwd_info1(struct rtw89_tx_desc_info *desc_info) |
838 |
+{ |
839 |
+ u32 dword = FIELD_PREP(RTW89_TXWD_INFO1_MAX_AGGNUM, desc_info->ampdu_num) | |
840 |
+ FIELD_PREP(RTW89_TXWD_INFO1_A_CTRL_BSR, desc_info->a_ctrl_bsr) | |
841 |
+ FIELD_PREP(RTW89_TXWD_INFO1_DATA_RTY_LOWEST_RATE, |
842 |
+ desc_info->data_retry_lowest_rate); |
843 |
+ |
844 |
+ return cpu_to_le32(dword); |
845 |
+} |
846 |
+ |
847 |
+static __le32 rtw89_build_txwd_info2(struct rtw89_tx_desc_info *desc_info) |
848 |
+{ |
849 |
+ u32 dword = FIELD_PREP(RTW89_TXWD_INFO2_AMPDU_DENSITY, desc_info->ampdu_density) | |
850 |
+ FIELD_PREP(RTW89_TXWD_INFO2_SEC_TYPE, desc_info->sec_type) | |
851 |
+ FIELD_PREP(RTW89_TXWD_INFO2_SEC_HW_ENC, desc_info->sec_en) | |
852 |
+ FIELD_PREP(RTW89_TXWD_INFO2_SEC_CAM_IDX, desc_info->sec_cam_idx); |
853 |
+ |
854 |
+ return cpu_to_le32(dword); |
855 |
+} |
856 |
+ |
857 |
+static __le32 rtw89_build_txwd_info4(struct rtw89_tx_desc_info *desc_info) |
858 |
+{ |
859 |
+ u32 dword = FIELD_PREP(RTW89_TXWD_INFO4_RTS_EN, 1) | |
860 |
+ FIELD_PREP(RTW89_TXWD_INFO4_HW_RTS_EN, 1); |
861 |
+ |
862 |
+ return cpu_to_le32(dword); |
863 |
+} |
864 |
+ |
865 |
+void rtw89_core_fill_txdesc(struct rtw89_dev *rtwdev, |
866 |
+ struct rtw89_tx_desc_info *desc_info, |
867 |
+ void *txdesc) |
868 |
+{ |
869 |
+ struct rtw89_txwd_body *txwd_body = (struct rtw89_txwd_body *)txdesc; |
870 |
+ struct rtw89_txwd_info *txwd_info; |
871 |
+ |
872 |
+ txwd_body->dword0 = rtw89_build_txwd_body0(desc_info); |
873 |
+ txwd_body->dword2 = rtw89_build_txwd_body2(desc_info); |
874 |
+ txwd_body->dword3 = rtw89_build_txwd_body3(desc_info); |
875 |
+ |
876 |
+ if (!desc_info->en_wd_info) |
877 |
+ return; |
878 |
+ |
879 |
+ txwd_info = (struct rtw89_txwd_info *)(txwd_body + 1); |
880 |
+ txwd_info->dword0 = rtw89_build_txwd_info0(desc_info); |
881 |
+ txwd_info->dword1 = rtw89_build_txwd_info1(desc_info); |
882 |
+ txwd_info->dword2 = rtw89_build_txwd_info2(desc_info); |
883 |
+ txwd_info->dword4 = rtw89_build_txwd_info4(desc_info); |
884 |
+ |
885 |
+} |
886 |
+EXPORT_SYMBOL(rtw89_core_fill_txdesc); |
887 |
+ |
888 |
+static int rtw89_core_rx_process_mac_ppdu(struct rtw89_dev *rtwdev, |
889 |
+ struct sk_buff *skb, |
890 |
+ struct rtw89_rx_phy_ppdu *phy_ppdu) |
891 |
+{ |
892 |
+ bool rx_cnt_valid = false; |
893 |
+ u8 plcp_size = 0; |
894 |
+ u8 usr_num = 0; |
895 |
+ u8 *phy_sts; |
896 |
+ |
897 |
+ rx_cnt_valid = RTW89_GET_RXINFO_RX_CNT_VLD(skb->data); |
898 |
+ plcp_size = RTW89_GET_RXINFO_PLCP_LEN(skb->data) << 3; |
899 |
+ usr_num = RTW89_GET_RXINFO_USR_NUM(skb->data); |
900 |
+ if (usr_num > RTW89_PPDU_MAX_USR) { |
901 |
+ rtw89_warn(rtwdev, "Invalid user number in mac info\n"); |
902 |
+ return -EINVAL; |
903 |
+ } |
904 |
+ |
905 |
+ phy_sts = skb->data + RTW89_PPDU_MAC_INFO_SIZE; |
906 |
+ phy_sts += usr_num * RTW89_PPDU_MAC_INFO_USR_SIZE; |
907 |
+ /* 8-byte alignment */ |
908 |
+ if (usr_num & BIT(0)) |
909 |
+ phy_sts += RTW89_PPDU_MAC_INFO_USR_SIZE; |
910 |
+ if (rx_cnt_valid) |
911 |
+ phy_sts += RTW89_PPDU_MAC_RX_CNT_SIZE; |
912 |
+ phy_sts += plcp_size; |
913 |
+ |
914 |
+ phy_ppdu->buf = phy_sts; |
915 |
+ phy_ppdu->len = skb->data + skb->len - phy_sts; |
916 |
+ |
917 |
+ return 0; |
918 |
+} |
919 |
+ |
920 |
+static void rtw89_core_rx_process_phy_ppdu_iter(void *data, |
921 |
+ struct ieee80211_sta *sta) |
922 |
+{ |
923 |
+ struct rtw89_sta *rtwsta = (struct rtw89_sta *)sta->drv_priv; |
924 |
+ struct rtw89_rx_phy_ppdu *phy_ppdu = (struct rtw89_rx_phy_ppdu *)data; |
925 |
+ |
926 |
+ if (rtwsta->mac_id == phy_ppdu->mac_id && phy_ppdu->to_self) |
927 |
+ ewma_rssi_add(&rtwsta->avg_rssi, phy_ppdu->rssi_avg); |
928 |
+} |
929 |
+ |
930 |
+#define VAR_LEN 0xff |
931 |
+#define VAR_LEN_UNIT 8 |
932 |
+static u16 rtw89_core_get_phy_status_ie_len(struct rtw89_dev *rtwdev, u8 *addr) |
933 |
+{ |
934 |
+ static const u8 physts_ie_len_tab[32] = { |
935 |
+ 16, 32, 24, 24, 8, 8, 8, 8, VAR_LEN, 8, VAR_LEN, 176, VAR_LEN, |
936 |
+ VAR_LEN, VAR_LEN, VAR_LEN, VAR_LEN, VAR_LEN, 16, 24, VAR_LEN, |
937 |
+ VAR_LEN, VAR_LEN, 0, 24, 24, 24, 24, 32, 32, 32, 32 |
938 |
+ }; |
939 |
+ u16 ie_len; |
940 |
+ u8 ie; |
941 |
+ |
942 |
+ ie = RTW89_GET_PHY_STS_IE_TYPE(addr); |
943 |
+ if (physts_ie_len_tab[ie] != VAR_LEN) |
944 |
+ ie_len = physts_ie_len_tab[ie]; |
945 |
+ else |
946 |
+ ie_len = RTW89_GET_PHY_STS_IE_LEN(addr) * VAR_LEN_UNIT; |
947 |
+ |
948 |
+ return ie_len; |
949 |
+} |
950 |
+ |
951 |
+static void rtw89_core_parse_phy_status_ie01(struct rtw89_dev *rtwdev, u8 *addr, |
952 |
+ struct rtw89_rx_phy_ppdu *phy_ppdu) |
953 |
+{ |
954 |
+ s16 cfo; |
955 |
+ |
956 |
+ /* sign conversion for S(12,2) */ |
957 |
+ cfo = sign_extend32(RTW89_GET_PHY_STS_IE0_CFO(addr), 11); |
958 |
+ rtw89_phy_cfo_parse(rtwdev, cfo, phy_ppdu); |
959 |
+} |
960 |
+ |
961 |
+static int rtw89_core_process_phy_status_ie(struct rtw89_dev *rtwdev, u8 *addr, |
962 |
+ struct rtw89_rx_phy_ppdu *phy_ppdu) |
963 |
+{ |
964 |
+ u8 ie; |
965 |
+ |
966 |
+ ie = RTW89_GET_PHY_STS_IE_TYPE(addr); |
967 |
+ switch (ie) { |
968 |
+ case RTW89_PHYSTS_IE01_CMN_OFDM: |
969 |
+ rtw89_core_parse_phy_status_ie01(rtwdev, addr, phy_ppdu); |
970 |
+ break; |
971 |
+ default: |
972 |
+ break; |
973 |
+ } |
974 |
+ |
975 |
+ return 0; |
976 |
+} |
977 |
+ |
978 |
+static void rtw89_core_update_phy_ppdu(struct rtw89_rx_phy_ppdu *phy_ppdu) |
979 |
+{ |
980 |
+ s8 *rssi = phy_ppdu->rssi; |
981 |
+ u8 *buf = phy_ppdu->buf; |
982 |
+ |
983 |
+ phy_ppdu->rssi_avg = RTW89_GET_PHY_STS_RSSI_AVG(buf); |
984 |
+ rssi[RF_PATH_A] = RTW89_RSSI_RAW_TO_DBM(RTW89_GET_PHY_STS_RSSI_A(buf)); |
985 |
+ rssi[RF_PATH_B] = RTW89_RSSI_RAW_TO_DBM(RTW89_GET_PHY_STS_RSSI_B(buf)); |
986 |
+ rssi[RF_PATH_C] = RTW89_RSSI_RAW_TO_DBM(RTW89_GET_PHY_STS_RSSI_C(buf)); |
987 |
+ rssi[RF_PATH_D] = RTW89_RSSI_RAW_TO_DBM(RTW89_GET_PHY_STS_RSSI_D(buf)); |
988 |
+} |
989 |
+ |
990 |
+static int rtw89_core_rx_process_phy_ppdu(struct rtw89_dev *rtwdev, |
991 |
+ struct rtw89_rx_phy_ppdu *phy_ppdu) |
992 |
+{ |
993 |
+ if (RTW89_GET_PHY_STS_LEN(phy_ppdu->buf) << 3 != phy_ppdu->len) { |
994 |
+ rtw89_warn(rtwdev, "phy ppdu len mismatch\n"); |
995 |
+ return -EINVAL; |
996 |
+ } |
997 |
+ rtw89_core_update_phy_ppdu(phy_ppdu); |
998 |
+ ieee80211_iterate_stations_atomic(rtwdev->hw, |
999 |
+ rtw89_core_rx_process_phy_ppdu_iter, |
1000 |
+ phy_ppdu); |
1001 |
+ |
1002 |
+ return 0; |
1003 |
+} |
1004 |
+ |
1005 |
+static int rtw89_core_rx_parse_phy_sts(struct rtw89_dev *rtwdev, |
1006 |
+ struct rtw89_rx_phy_ppdu *phy_ppdu) |
1007 |
+{ |
1008 |
+ u16 ie_len; |
1009 |
+ u8 *pos, *end; |
1010 |
+ |
1011 |
+ if (!phy_ppdu->to_self) |
1012 |
+ return 0; |
1013 |
+ |
1014 |
+ pos = (u8 *)phy_ppdu->buf + PHY_STS_HDR_LEN; |
1015 |
+ end = (u8 *)phy_ppdu->buf + phy_ppdu->len; |
1016 |
+ while (pos < end) { |
1017 |
+ ie_len = rtw89_core_get_phy_status_ie_len(rtwdev, pos); |
1018 |
+ rtw89_core_process_phy_status_ie(rtwdev, pos, phy_ppdu); |
1019 |
+ pos += ie_len; |
1020 |
+ if (pos > end || ie_len == 0) { |
1021 |
+ rtw89_debug(rtwdev, RTW89_DBG_TXRX, |
1022 |
+ "phy status parse failed\n"); |
1023 |
+ return -EINVAL; |
1024 |
+ } |
1025 |
+ } |
1026 |
+ |
1027 |
+ return 0; |
1028 |
+} |
1029 |
+ |
1030 |
+static void rtw89_core_rx_process_phy_sts(struct rtw89_dev *rtwdev, |
1031 |
+ struct rtw89_rx_phy_ppdu *phy_ppdu) |
1032 |
+{ |
1033 |
+ int ret; |
1034 |
+ |
1035 |
+ ret = rtw89_core_rx_parse_phy_sts(rtwdev, phy_ppdu); |
1036 |
+ if (ret) |
1037 |
+ rtw89_debug(rtwdev, RTW89_DBG_TXRX, "parse phy sts failed\n"); |
1038 |
+ else |
1039 |
+ phy_ppdu->valid = true; |
1040 |
+} |
1041 |
+ |
1042 |
+static u8 rtw89_rxdesc_to_nl_he_gi(struct rtw89_dev *rtwdev, |
1043 |
+ const struct rtw89_rx_desc_info *desc_info, |
1044 |
+ bool rx_status) |
1045 |
+{ |
1046 |
+ switch (desc_info->gi_ltf) { |
1047 |
+ case RTW89_GILTF_SGI_4XHE08: |
1048 |
+ case RTW89_GILTF_2XHE08: |
1049 |
+ case RTW89_GILTF_1XHE08: |
1050 |
+ return NL80211_RATE_INFO_HE_GI_0_8; |
1051 |
+ case RTW89_GILTF_2XHE16: |
1052 |
+ case RTW89_GILTF_1XHE16: |
1053 |
+ return NL80211_RATE_INFO_HE_GI_1_6; |
1054 |
+ case RTW89_GILTF_LGI_4XHE32: |
1055 |
+ return NL80211_RATE_INFO_HE_GI_3_2; |
1056 |
+ default: |
1057 |
+ rtw89_warn(rtwdev, "invalid gi_ltf=%d", desc_info->gi_ltf); |
1058 |
+ return rx_status ? NL80211_RATE_INFO_HE_GI_3_2 : U8_MAX; |
1059 |
+ } |
1060 |
+} |
1061 |
+ |
1062 |
+static bool rtw89_core_rx_ppdu_match(struct rtw89_dev *rtwdev, |
1063 |
+ struct rtw89_rx_desc_info *desc_info, |
1064 |
+ struct ieee80211_rx_status *status) |
1065 |
+{ |
1066 |
+ u8 band = desc_info->bb_sel ? RTW89_PHY_1 : RTW89_PHY_0; |
1067 |
+ u8 data_rate_mode, bw, rate_idx = MASKBYTE0, gi_ltf; |
1068 |
+ u16 data_rate; |
1069 |
+ bool ret; |
1070 |
+ |
1071 |
+ data_rate = desc_info->data_rate; |
1072 |
+ data_rate_mode = GET_DATA_RATE_MODE(data_rate); |
1073 |
+ if (data_rate_mode == DATA_RATE_MODE_NON_HT) { |
1074 |
+ rate_idx = GET_DATA_RATE_NOT_HT_IDX(data_rate); |
1075 |
+ /* No 4 CCK rates for 5G */ |
1076 |
+ if (status->band == NL80211_BAND_5GHZ) |
1077 |
+ rate_idx -= 4; |
1078 |
+ } else if (data_rate_mode == DATA_RATE_MODE_HT) { |
1079 |
+ rate_idx = GET_DATA_RATE_HT_IDX(data_rate); |
1080 |
+ } else if (data_rate_mode == DATA_RATE_MODE_VHT) { |
1081 |
+ rate_idx = GET_DATA_RATE_VHT_HE_IDX(data_rate); |
1082 |
+ } else if (data_rate_mode == DATA_RATE_MODE_HE) { |
1083 |
+ rate_idx = GET_DATA_RATE_VHT_HE_IDX(data_rate); |
1084 |
+ } else { |
1085 |
+ rtw89_warn(rtwdev, "invalid RX rate mode %d\n", data_rate_mode); |
1086 |
+ } |
1087 |
+ |
1088 |
+ if (desc_info->bw == RTW89_CHANNEL_WIDTH_80) |
1089 |
+ bw = RATE_INFO_BW_80; |
1090 |
+ else if (desc_info->bw == RTW89_CHANNEL_WIDTH_40) |
1091 |
+ bw = RATE_INFO_BW_40; |
1092 |
+ else |
1093 |
+ bw = RATE_INFO_BW_20; |
1094 |
+ |
1095 |
+ gi_ltf = rtw89_rxdesc_to_nl_he_gi(rtwdev, desc_info, false); |
1096 |
+ ret = rtwdev->ppdu_sts.curr_rx_ppdu_cnt[band] == desc_info->ppdu_cnt && |
1097 |
+ status->rate_idx == rate_idx && |
1098 |
+ status->he_gi == gi_ltf && |
1099 |
+ status->bw == bw; |
1100 |
+ |
1101 |
+ return ret; |
1102 |
+} |
1103 |
+ |
1104 |
+struct rtw89_vif_rx_stats_iter_data { |
1105 |
+ struct rtw89_dev *rtwdev; |
1106 |
+ struct rtw89_rx_phy_ppdu *phy_ppdu; |
1107 |
+ struct rtw89_rx_desc_info *desc_info; |
1108 |
+ struct sk_buff *skb; |
1109 |
+ const u8 *bssid; |
1110 |
+}; |
1111 |
+ |
1112 |
+static void rtw89_vif_rx_stats_iter(void *data, u8 *mac, |
1113 |
+ struct ieee80211_vif *vif) |
1114 |
+{ |
1115 |
+ struct rtw89_vif *rtwvif = (struct rtw89_vif *)vif->drv_priv; |
1116 |
+ struct rtw89_vif_rx_stats_iter_data *iter_data = data; |
1117 |
+ struct rtw89_dev *rtwdev = iter_data->rtwdev; |
1118 |
+ struct rtw89_pkt_stat *pkt_stat = &rtwdev->phystat.cur_pkt_stat; |
1119 |
+ struct rtw89_rx_desc_info *desc_info = iter_data->desc_info; |
1120 |
+ struct sk_buff *skb = iter_data->skb; |
1121 |
+ struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)skb->data; |
1122 |
+ const u8 *bssid = iter_data->bssid; |
1123 |
+ |
1124 |
+ if (!ether_addr_equal(vif->bss_conf.bssid, bssid)) |
1125 |
+ return; |
1126 |
+ |
1127 |
+ if (ieee80211_is_beacon(hdr->frame_control)) |
1128 |
+ pkt_stat->beacon_nr++; |
1129 |
+ |
1130 |
+ if (!ether_addr_equal(vif->addr, hdr->addr1)) |
1131 |
+ return; |
1132 |
+ |
1133 |
+ if (desc_info->data_rate < RTW89_HW_RATE_NR) |
1134 |
+ pkt_stat->rx_rate_cnt[desc_info->data_rate]++; |
1135 |
+ |
1136 |
+ rtw89_traffic_stats_accu(rtwdev, &rtwvif->stats, skb, false); |
1137 |
+} |
1138 |
+ |
1139 |
+static void rtw89_core_rx_stats(struct rtw89_dev *rtwdev, |
1140 |
+ struct rtw89_rx_phy_ppdu *phy_ppdu, |
1141 |
+ struct rtw89_rx_desc_info *desc_info, |
1142 |
+ struct sk_buff *skb) |
1143 |
+{ |
1144 |
+ struct rtw89_vif_rx_stats_iter_data iter_data; |
1145 |
+ |
1146 |
+ rtw89_traffic_stats_accu(rtwdev, &rtwdev->stats, skb, false); |
1147 |
+ |
1148 |
+ iter_data.rtwdev = rtwdev; |
1149 |
+ iter_data.phy_ppdu = phy_ppdu; |
1150 |
+ iter_data.desc_info = desc_info; |
1151 |
+ iter_data.skb = skb; |
1152 |
+ iter_data.bssid = get_hdr_bssid((struct ieee80211_hdr *)skb->data); |
1153 |
+ rtw89_iterate_vifs_bh(rtwdev, rtw89_vif_rx_stats_iter, &iter_data); |
1154 |
+} |
1155 |
+ |
1156 |
+static void rtw89_core_rx_pending_skb(struct rtw89_dev *rtwdev, |
1157 |
+ struct rtw89_rx_phy_ppdu *phy_ppdu, |
1158 |
+ struct rtw89_rx_desc_info *desc_info, |
1159 |
+ struct sk_buff *skb) |
1160 |
+{ |
1161 |
+ u8 band = desc_info->bb_sel ? RTW89_PHY_1 : RTW89_PHY_0; |
1162 |
+ int curr = rtwdev->ppdu_sts.curr_rx_ppdu_cnt[band]; |
1163 |
+ struct sk_buff *skb_ppdu = NULL, *tmp; |
1164 |
+ struct ieee80211_rx_status *rx_status; |
1165 |
+ |
1166 |
+ if (curr > RTW89_MAX_PPDU_CNT) |
1167 |
+ return; |
1168 |
+ |
1169 |
+ skb_queue_walk_safe(&rtwdev->ppdu_sts.rx_queue[band], skb_ppdu, tmp) { |
1170 |
+ skb_unlink(skb_ppdu, &rtwdev->ppdu_sts.rx_queue[band]); |
1171 |
+ rx_status = IEEE80211_SKB_RXCB(skb_ppdu); |
1172 |
+ if (rtw89_core_rx_ppdu_match(rtwdev, desc_info, rx_status)) |
1173 |
+ rtw89_chip_query_ppdu(rtwdev, phy_ppdu, rx_status); |
1174 |
+ rtw89_core_rx_stats(rtwdev, phy_ppdu, desc_info, skb_ppdu); |
1175 |
+ ieee80211_rx_napi(rtwdev->hw, NULL, skb_ppdu, &rtwdev->napi); |
1176 |
+ rtwdev->napi_budget_countdown--; |
1177 |
+ } |
1178 |
+} |
1179 |
+ |
1180 |
+static void rtw89_core_rx_process_ppdu_sts(struct rtw89_dev *rtwdev, |
1181 |
+ struct rtw89_rx_desc_info *desc_info, |
1182 |
+ struct sk_buff *skb) |
1183 |
+{ |
1184 |
+ struct rtw89_rx_phy_ppdu phy_ppdu = {.buf = skb->data, .valid = false, |
1185 |
+ .len = skb->len, |
1186 |
+ .to_self = desc_info->addr1_match, |
1187 |
+ .mac_id = desc_info->mac_id}; |
1188 |
+ int ret; |
1189 |
+ |
1190 |
+ if (desc_info->mac_info_valid) |
1191 |
+ rtw89_core_rx_process_mac_ppdu(rtwdev, skb, &phy_ppdu); |
1192 |
+ ret = rtw89_core_rx_process_phy_ppdu(rtwdev, &phy_ppdu); |
1193 |
+ if (ret) |
1194 |
+ rtw89_debug(rtwdev, RTW89_DBG_TXRX, "process ppdu failed\n"); |
1195 |
+ |
1196 |
+ rtw89_core_rx_process_phy_sts(rtwdev, &phy_ppdu); |
1197 |
+ rtw89_core_rx_pending_skb(rtwdev, &phy_ppdu, desc_info, skb); |
1198 |
+ dev_kfree_skb_any(skb); |
1199 |
+} |
1200 |
+ |
1201 |
+static void rtw89_core_rx_process_report(struct rtw89_dev *rtwdev, |
1202 |
+ struct rtw89_rx_desc_info *desc_info, |
1203 |
+ struct sk_buff *skb) |
1204 |
+{ |
1205 |
+ switch (desc_info->pkt_type) { |
1206 |
+ case RTW89_CORE_RX_TYPE_C2H: |
1207 |
+ rtw89_fw_c2h_irqsafe(rtwdev, skb); |
1208 |
+ break; |
1209 |
+ case RTW89_CORE_RX_TYPE_PPDU_STAT: |
1210 |
+ rtw89_core_rx_process_ppdu_sts(rtwdev, desc_info, skb); |
1211 |
+ break; |
1212 |
+ default: |
1213 |
+ rtw89_debug(rtwdev, RTW89_DBG_TXRX, "unhandled pkt_type=%d\n", |
1214 |
+ desc_info->pkt_type); |
1215 |
+ dev_kfree_skb_any(skb); |
1216 |
+ break; |
1217 |
+ } |
1218 |
+} |
1219 |
+ |
1220 |
+void rtw89_core_query_rxdesc(struct rtw89_dev *rtwdev, |
1221 |
+ struct rtw89_rx_desc_info *desc_info, |
1222 |
+ u8 *data, u32 data_offset) |
1223 |
+{ |
1224 |
+ struct rtw89_rxdesc_short *rxd_s; |
1225 |
+ struct rtw89_rxdesc_long *rxd_l; |
1226 |
+ u8 shift_len, drv_info_len; |
1227 |
+ |
1228 |
+ rxd_s = (struct rtw89_rxdesc_short *)(data + data_offset); |
1229 |
+ desc_info->pkt_size = RTW89_GET_RXWD_PKT_SIZE(rxd_s); |
1230 |
+ desc_info->drv_info_size = RTW89_GET_RXWD_DRV_INFO_SIZE(rxd_s); |
1231 |
+ desc_info->long_rxdesc = RTW89_GET_RXWD_LONG_RXD(rxd_s); |
1232 |
+ desc_info->pkt_type = RTW89_GET_RXWD_RPKT_TYPE(rxd_s); |
1233 |
+ desc_info->mac_info_valid = RTW89_GET_RXWD_MAC_INFO_VALID(rxd_s); |
1234 |
+ desc_info->bw = RTW89_GET_RXWD_BW(rxd_s); |
1235 |
+ desc_info->data_rate = RTW89_GET_RXWD_DATA_RATE(rxd_s); |
1236 |
+ desc_info->gi_ltf = RTW89_GET_RXWD_GI_LTF(rxd_s); |
1237 |
+ desc_info->user_id = RTW89_GET_RXWD_USER_ID(rxd_s); |
1238 |
+ desc_info->sr_en = RTW89_GET_RXWD_SR_EN(rxd_s); |
1239 |
+ desc_info->ppdu_cnt = RTW89_GET_RXWD_PPDU_CNT(rxd_s); |
1240 |
+ desc_info->ppdu_type = RTW89_GET_RXWD_PPDU_TYPE(rxd_s); |
1241 |
+ desc_info->free_run_cnt = RTW89_GET_RXWD_FREE_RUN_CNT(rxd_s); |
1242 |
+ desc_info->icv_err = RTW89_GET_RXWD_ICV_ERR(rxd_s); |
1243 |
+ desc_info->crc32_err = RTW89_GET_RXWD_CRC32_ERR(rxd_s); |
1244 |
+ desc_info->hw_dec = RTW89_GET_RXWD_HW_DEC(rxd_s); |
1245 |
+ desc_info->sw_dec = RTW89_GET_RXWD_SW_DEC(rxd_s); |
1246 |
+ desc_info->addr1_match = RTW89_GET_RXWD_A1_MATCH(rxd_s); |
1247 |
+ |
1248 |
+ shift_len = desc_info->shift << 1; /* 2-byte unit */ |
1249 |
+ drv_info_len = desc_info->drv_info_size << 3; /* 8-byte unit */ |
1250 |
+ desc_info->offset = data_offset + shift_len + drv_info_len; |
1251 |
+ desc_info->ready = true; |
1252 |
+ |
1253 |
+ if (!desc_info->long_rxdesc) |
1254 |
+ return; |
1255 |
+ |
1256 |
+ rxd_l = (struct rtw89_rxdesc_long *)(data + data_offset); |
1257 |
+ desc_info->frame_type = RTW89_GET_RXWD_TYPE(rxd_l); |
1258 |
+ desc_info->addr_cam_valid = RTW89_GET_RXWD_ADDR_CAM_VLD(rxd_l); |
1259 |
+ desc_info->addr_cam_id = RTW89_GET_RXWD_ADDR_CAM_ID(rxd_l); |
1260 |
+ desc_info->sec_cam_id = RTW89_GET_RXWD_SEC_CAM_ID(rxd_l); |
1261 |
+ desc_info->mac_id = RTW89_GET_RXWD_MAC_ID(rxd_l); |
1262 |
+ desc_info->rx_pl_id = RTW89_GET_RXWD_RX_PL_ID(rxd_l); |
1263 |
+} |
1264 |
+EXPORT_SYMBOL(rtw89_core_query_rxdesc); |
1265 |
+ |
1266 |
+struct rtw89_core_iter_rx_status { |
1267 |
+ struct rtw89_dev *rtwdev; |
1268 |
+ struct ieee80211_rx_status *rx_status; |
1269 |
+ struct rtw89_rx_desc_info *desc_info; |
1270 |
+ u8 mac_id; |
1271 |
+}; |
1272 |
+ |
1273 |
+static |
1274 |
+void rtw89_core_stats_sta_rx_status_iter(void *data, struct ieee80211_sta *sta) |
1275 |
+{ |
1276 |
+ struct rtw89_core_iter_rx_status *iter_data = |
1277 |
+ (struct rtw89_core_iter_rx_status *)data; |
1278 |
+ struct ieee80211_rx_status *rx_status = iter_data->rx_status; |
1279 |
+ struct rtw89_sta *rtwsta = (struct rtw89_sta *)sta->drv_priv; |
1280 |
+ struct rtw89_rx_desc_info *desc_info = iter_data->desc_info; |
1281 |
+ u8 mac_id = iter_data->mac_id; |
1282 |
+ |
1283 |
+ if (mac_id != rtwsta->mac_id) |
1284 |
+ return; |
1285 |
+ |
1286 |
+ rtwsta->rx_status = *rx_status; |
1287 |
+ rtwsta->rx_hw_rate = desc_info->data_rate; |
1288 |
+} |
1289 |
+ |
1290 |
+static void rtw89_core_stats_sta_rx_status(struct rtw89_dev *rtwdev, |
1291 |
+ struct rtw89_rx_desc_info *desc_info, |
1292 |
+ struct ieee80211_rx_status *rx_status) |
1293 |
+{ |
1294 |
+ struct rtw89_core_iter_rx_status iter_data; |
1295 |
+ |
1296 |
+ if (!desc_info->addr1_match || !desc_info->long_rxdesc) |
1297 |
+ return; |
1298 |
+ |
1299 |
+ if (desc_info->frame_type != RTW89_RX_TYPE_DATA) |
1300 |
+ return; |
1301 |
+ |
1302 |
+ iter_data.rtwdev = rtwdev; |
1303 |
+ iter_data.rx_status = rx_status; |
1304 |
+ iter_data.desc_info = desc_info; |
1305 |
+ iter_data.mac_id = desc_info->mac_id; |
1306 |
+ ieee80211_iterate_stations_atomic(rtwdev->hw, |
1307 |
+ rtw89_core_stats_sta_rx_status_iter, |
1308 |
+ &iter_data); |
1309 |
+} |
1310 |
+ |
1311 |
+static void rtw89_core_update_rx_status(struct rtw89_dev *rtwdev, |
1312 |
+ struct rtw89_rx_desc_info *desc_info, |
1313 |
+ struct ieee80211_rx_status *rx_status) |
1314 |
+{ |
1315 |
+ struct ieee80211_hw *hw = rtwdev->hw; |
1316 |
+ u16 data_rate; |
1317 |
+ u8 data_rate_mode; |
1318 |
+ |
1319 |
+ /* currently using single PHY */ |
1320 |
+ rx_status->freq = hw->conf.chandef.chan->center_freq; |
1321 |
+ rx_status->band = hw->conf.chandef.chan->band; |
1322 |
+ |
1323 |
+ if (desc_info->icv_err || desc_info->crc32_err) |
1324 |
+ rx_status->flag |= RX_FLAG_FAILED_FCS_CRC; |
1325 |
+ |
1326 |
+ if (desc_info->hw_dec && |
1327 |
+ !(desc_info->sw_dec || desc_info->icv_err)) |
1328 |
+ rx_status->flag |= RX_FLAG_DECRYPTED; |
1329 |
+ |
1330 |
+ if (desc_info->bw == RTW89_CHANNEL_WIDTH_80) |
1331 |
+ rx_status->bw = RATE_INFO_BW_80; |
1332 |
+ else if (desc_info->bw == RTW89_CHANNEL_WIDTH_40) |
1333 |
+ rx_status->bw = RATE_INFO_BW_40; |
1334 |
+ else |
1335 |
+ rx_status->bw = RATE_INFO_BW_20; |
1336 |
+ |
1337 |
+ data_rate = desc_info->data_rate; |
1338 |
+ data_rate_mode = GET_DATA_RATE_MODE(data_rate); |
1339 |
+ if (data_rate_mode == DATA_RATE_MODE_NON_HT) { |
1340 |
+ rx_status->encoding = RX_ENC_LEGACY; |
1341 |
+ rx_status->rate_idx = GET_DATA_RATE_NOT_HT_IDX(data_rate); |
1342 |
+ /* No 4 CCK rates for 5G */ |
1343 |
+ if (rx_status->band == NL80211_BAND_5GHZ) |
1344 |
+ rx_status->rate_idx -= 4; |
1345 |
+ if (rtwdev->scanning) |
1346 |
+ rx_status->rate_idx = min_t(u8, rx_status->rate_idx, |
1347 |
+ ARRAY_SIZE(rtw89_bitrates) - 5); |
1348 |
+ } else if (data_rate_mode == DATA_RATE_MODE_HT) { |
1349 |
+ rx_status->encoding = RX_ENC_HT; |
1350 |
+ rx_status->rate_idx = GET_DATA_RATE_HT_IDX(data_rate); |
1351 |
+ if (desc_info->gi_ltf) |
1352 |
+ rx_status->enc_flags |= RX_ENC_FLAG_SHORT_GI; |
1353 |
+ } else if (data_rate_mode == DATA_RATE_MODE_VHT) { |
1354 |
+ rx_status->encoding = RX_ENC_VHT; |
1355 |
+ rx_status->rate_idx = GET_DATA_RATE_VHT_HE_IDX(data_rate); |
1356 |
+ rx_status->nss = GET_DATA_RATE_NSS(data_rate) + 1; |
1357 |
+ if (desc_info->gi_ltf) |
1358 |
+ rx_status->enc_flags |= RX_ENC_FLAG_SHORT_GI; |
1359 |
+ } else if (data_rate_mode == DATA_RATE_MODE_HE) { |
1360 |
+ rx_status->encoding = RX_ENC_HE; |
1361 |
+ rx_status->rate_idx = GET_DATA_RATE_VHT_HE_IDX(data_rate); |
1362 |
+ rx_status->nss = GET_DATA_RATE_NSS(data_rate) + 1; |
1363 |
+ } else { |
1364 |
+ rtw89_warn(rtwdev, "invalid RX rate mode %d\n", data_rate_mode); |
1365 |
+ } |
1366 |
+ |
1367 |
+ /* he_gi is used to match ppdu, so we always fill it. */ |
1368 |
+ rx_status->he_gi = rtw89_rxdesc_to_nl_he_gi(rtwdev, desc_info, true); |
1369 |
+ rx_status->flag |= RX_FLAG_MACTIME_START; |
1370 |
+ rx_status->mactime = desc_info->free_run_cnt; |
1371 |
+ |
1372 |
+ rtw89_core_stats_sta_rx_status(rtwdev, desc_info, rx_status); |
1373 |
+} |
1374 |
+ |
1375 |
+static enum rtw89_ps_mode rtw89_update_ps_mode(struct rtw89_dev *rtwdev) |
1376 |
+{ |
1377 |
+ const struct rtw89_chip_info *chip = rtwdev->chip; |
1378 |
+ |
1379 |
+ if (rtw89_disable_ps_mode || !chip->ps_mode_supported) |
1380 |
+ return RTW89_PS_MODE_NONE; |
1381 |
+ |
1382 |
+ if (chip->ps_mode_supported & BIT(RTW89_PS_MODE_PWR_GATED)) |
1383 |
+ return RTW89_PS_MODE_PWR_GATED; |
1384 |
+ |
1385 |
+ if (chip->ps_mode_supported & BIT(RTW89_PS_MODE_CLK_GATED)) |
1386 |
+ return RTW89_PS_MODE_CLK_GATED; |
1387 |
+ |
1388 |
+ if (chip->ps_mode_supported & BIT(RTW89_PS_MODE_RFOFF)) |
1389 |
+ return RTW89_PS_MODE_RFOFF; |
1390 |
+ |
1391 |
+ return RTW89_PS_MODE_NONE; |
1392 |
+} |
1393 |
+ |
1394 |
+static void rtw89_core_flush_ppdu_rx_queue(struct rtw89_dev *rtwdev, |
1395 |
+ struct rtw89_rx_desc_info *desc_info) |
1396 |
+{ |
1397 |
+ struct rtw89_ppdu_sts_info *ppdu_sts = &rtwdev->ppdu_sts; |
1398 |
+ u8 band = desc_info->bb_sel ? RTW89_PHY_1 : RTW89_PHY_0; |
1399 |
+ struct sk_buff *skb_ppdu, *tmp; |
1400 |
+ |
1401 |
+ skb_queue_walk_safe(&ppdu_sts->rx_queue[band], skb_ppdu, tmp) { |
1402 |
+ skb_unlink(skb_ppdu, &ppdu_sts->rx_queue[band]); |
1403 |
+ rtw89_core_rx_stats(rtwdev, NULL, desc_info, skb_ppdu); |
1404 |
+ ieee80211_rx_napi(rtwdev->hw, NULL, skb_ppdu, &rtwdev->napi); |
1405 |
+ rtwdev->napi_budget_countdown--; |
1406 |
+ } |
1407 |
+} |
1408 |
+ |
1409 |
+void rtw89_core_rx(struct rtw89_dev *rtwdev, |
1410 |
+ struct rtw89_rx_desc_info *desc_info, |
1411 |
+ struct sk_buff *skb) |
1412 |
+{ |
1413 |
+ struct ieee80211_rx_status *rx_status; |
1414 |
+ struct rtw89_ppdu_sts_info *ppdu_sts = &rtwdev->ppdu_sts; |
1415 |
+ u8 ppdu_cnt = desc_info->ppdu_cnt; |
1416 |
+ u8 band = desc_info->bb_sel ? RTW89_PHY_1 : RTW89_PHY_0; |
1417 |
+ |
1418 |
+ if (desc_info->pkt_type != RTW89_CORE_RX_TYPE_WIFI) { |
1419 |
+ rtw89_core_rx_process_report(rtwdev, desc_info, skb); |
1420 |
+ return; |
1421 |
+ } |
1422 |
+ |
1423 |
+ if (ppdu_sts->curr_rx_ppdu_cnt[band] != ppdu_cnt) { |
1424 |
+ rtw89_core_flush_ppdu_rx_queue(rtwdev, desc_info); |
1425 |
+ ppdu_sts->curr_rx_ppdu_cnt[band] = ppdu_cnt; |
1426 |
+ } |
1427 |
+ |
1428 |
+ rx_status = IEEE80211_SKB_RXCB(skb); |
1429 |
+ memset(rx_status, 0, sizeof(*rx_status)); |
1430 |
+ rtw89_core_update_rx_status(rtwdev, desc_info, rx_status); |
1431 |
+ if (desc_info->long_rxdesc && |
1432 |
+ BIT(desc_info->frame_type) & PPDU_FILTER_BITMAP) { |
1433 |
+ skb_queue_tail(&ppdu_sts->rx_queue[band], skb); |
1434 |
+ } else { |
1435 |
+ rtw89_core_rx_stats(rtwdev, NULL, desc_info, skb); |
1436 |
+ ieee80211_rx_napi(rtwdev->hw, NULL, skb, &rtwdev->napi); |
1437 |
+ rtwdev->napi_budget_countdown--; |
1438 |
+ } |
1439 |
+} |
1440 |
+EXPORT_SYMBOL(rtw89_core_rx); |
1441 |
+ |
1442 |
+void rtw89_core_napi_start(struct rtw89_dev *rtwdev) |
1443 |
+{ |
1444 |
+ if (test_and_set_bit(RTW89_FLAG_NAPI_RUNNING, rtwdev->flags)) |
1445 |
+ return; |
1446 |
+ |
1447 |
+ napi_enable(&rtwdev->napi); |
1448 |
+} |
1449 |
+EXPORT_SYMBOL(rtw89_core_napi_start); |
1450 |
+ |
1451 |
+void rtw89_core_napi_stop(struct rtw89_dev *rtwdev) |
1452 |
+{ |
1453 |
+ if (!test_and_clear_bit(RTW89_FLAG_NAPI_RUNNING, rtwdev->flags)) |
1454 |
+ return; |
1455 |
+ |
1456 |
+ napi_synchronize(&rtwdev->napi); |
1457 |
+ napi_disable(&rtwdev->napi); |
1458 |
+} |
1459 |
+EXPORT_SYMBOL(rtw89_core_napi_stop); |
1460 |
+ |
1461 |
+void rtw89_core_napi_init(struct rtw89_dev *rtwdev) |
1462 |
+{ |
1463 |
+ init_dummy_netdev(&rtwdev->netdev); |
1464 |
+ netif_napi_add(&rtwdev->netdev, &rtwdev->napi, |
1465 |
+ rtwdev->hci.ops->napi_poll, NAPI_POLL_WEIGHT); |
1466 |
+} |
1467 |
+EXPORT_SYMBOL(rtw89_core_napi_init); |
1468 |
+ |
1469 |
+void rtw89_core_napi_deinit(struct rtw89_dev *rtwdev) |
1470 |
+{ |
1471 |
+ rtw89_core_napi_stop(rtwdev); |
1472 |
+ netif_napi_del(&rtwdev->napi); |
1473 |
+} |
1474 |
+EXPORT_SYMBOL(rtw89_core_napi_deinit); |
1475 |
+ |
1476 |
+static void rtw89_core_ba_work(struct work_struct *work) |
1477 |
+{ |
1478 |
+ struct rtw89_dev *rtwdev = |
1479 |
+ container_of(work, struct rtw89_dev, ba_work); |
1480 |
+ struct rtw89_txq *rtwtxq, *tmp; |
1481 |
+ int ret; |
1482 |
+ |
1483 |
+ spin_lock_bh(&rtwdev->ba_lock); |
1484 |
+ list_for_each_entry_safe(rtwtxq, tmp, &rtwdev->ba_list, list) { |
1485 |
+ struct ieee80211_txq *txq = rtw89_txq_to_txq(rtwtxq); |
1486 |
+ struct ieee80211_sta *sta = txq->sta; |
1487 |
+ struct rtw89_sta *rtwsta = (struct rtw89_sta *)sta->drv_priv; |
1488 |
+ u8 tid = txq->tid; |
1489 |
+ |
1490 |
+ if (!sta) { |
1491 |
+ rtw89_warn(rtwdev, "cannot start BA without sta\n"); |
1492 |
+ goto skip_ba_work; |
1493 |
+ } |
1494 |
+ |
1495 |
+ if (rtwsta->disassoc) { |
1496 |
+ rtw89_debug(rtwdev, RTW89_DBG_TXRX, |
1497 |
+ "cannot start BA with disassoc sta\n"); |
1498 |
+ goto skip_ba_work; |
1499 |
+ } |
1500 |
+ |
1501 |
+ ret = ieee80211_start_tx_ba_session(sta, tid, 0); |
1502 |
+ if (ret) { |
1503 |
+ rtw89_debug(rtwdev, RTW89_DBG_TXRX, |
1504 |
+ "failed to setup BA session for %pM:%2d: %d\n", |
1505 |
+ sta->addr, tid, ret); |
1506 |
+ if (ret == -EINVAL) |
1507 |
+ set_bit(RTW89_TXQ_F_BLOCK_BA, &rtwtxq->flags); |
1508 |
+ } |
1509 |
+skip_ba_work: |
1510 |
+ list_del_init(&rtwtxq->list); |
1511 |
+ } |
1512 |
+ spin_unlock_bh(&rtwdev->ba_lock); |
1513 |
+} |
1514 |
+ |
1515 |
+static void rtw89_core_free_sta_pending_ba(struct rtw89_dev *rtwdev, |
1516 |
+ struct ieee80211_sta *sta) |
1517 |
+{ |
1518 |
+ struct rtw89_txq *rtwtxq, *tmp; |
1519 |
+ |
1520 |
+ spin_lock_bh(&rtwdev->ba_lock); |
1521 |
+ list_for_each_entry_safe(rtwtxq, tmp, &rtwdev->ba_list, list) { |
1522 |
+ struct ieee80211_txq *txq = rtw89_txq_to_txq(rtwtxq); |
1523 |
+ |
1524 |
+ if (sta == txq->sta) |
1525 |
+ list_del_init(&rtwtxq->list); |
1526 |
+ } |
1527 |
+ spin_unlock_bh(&rtwdev->ba_lock); |
1528 |
+} |
1529 |
+ |
1530 |
+static void rtw89_core_txq_check_agg(struct rtw89_dev *rtwdev, |
1531 |
+ struct rtw89_txq *rtwtxq, |
1532 |
+ struct sk_buff *skb) |
1533 |
+{ |
1534 |
+ struct ieee80211_hw *hw = rtwdev->hw; |
1535 |
+ struct ieee80211_txq *txq = rtw89_txq_to_txq(rtwtxq); |
1536 |
+ struct ieee80211_sta *sta = txq->sta; |
1537 |
+ struct rtw89_sta *rtwsta = (struct rtw89_sta *)sta->drv_priv; |
1538 |
+ |
1539 |
+ if (unlikely(skb_get_queue_mapping(skb) == IEEE80211_AC_VO)) |
1540 |
+ return; |
1541 |
+ |
1542 |
+ if (unlikely(skb->protocol == cpu_to_be16(ETH_P_PAE))) |
1543 |
+ return; |
1544 |
+ |
1545 |
+ if (unlikely(!sta)) |
1546 |
+ return; |
1547 |
+ |
1548 |
+ if (unlikely(test_bit(RTW89_TXQ_F_BLOCK_BA, &rtwtxq->flags))) |
1549 |
+ return; |
1550 |
+ |
1551 |
+ if (test_bit(RTW89_TXQ_F_AMPDU, &rtwtxq->flags)) { |
1552 |
+ IEEE80211_SKB_CB(skb)->flags |= IEEE80211_TX_CTL_AMPDU; |
1553 |
+ return; |
1554 |
+ } |
1555 |
+ |
1556 |
+ spin_lock_bh(&rtwdev->ba_lock); |
1557 |
+ if (!rtwsta->disassoc && list_empty(&rtwtxq->list)) { |
1558 |
+ list_add_tail(&rtwtxq->list, &rtwdev->ba_list); |
1559 |
+ ieee80211_queue_work(hw, &rtwdev->ba_work); |
1560 |
+ } |
1561 |
+ spin_unlock_bh(&rtwdev->ba_lock); |
1562 |
+} |
1563 |
+ |
1564 |
+static void rtw89_core_txq_push(struct rtw89_dev *rtwdev, |
1565 |
+ struct rtw89_txq *rtwtxq, |
1566 |
+ unsigned long frame_cnt, |
1567 |
+ unsigned long byte_cnt) |
1568 |
+{ |
1569 |
+ struct ieee80211_txq *txq = rtw89_txq_to_txq(rtwtxq); |
1570 |
+ struct ieee80211_vif *vif = txq->vif; |
1571 |
+ struct ieee80211_sta *sta = txq->sta; |
1572 |
+ struct sk_buff *skb; |
1573 |
+ unsigned long i; |
1574 |
+ int ret; |
1575 |
+ |
1576 |
+ for (i = 0; i < frame_cnt; i++) { |
1577 |
+ skb = ieee80211_tx_dequeue_ni(rtwdev->hw, txq); |
1578 |
+ if (!skb) { |
1579 |
+ rtw89_debug(rtwdev, RTW89_DBG_TXRX, "dequeue a NULL skb\n"); |
1580 |
+ return; |
1581 |
+ } |
1582 |
+ rtw89_core_txq_check_agg(rtwdev, rtwtxq, skb); |
1583 |
+ ret = rtw89_core_tx_write(rtwdev, vif, sta, skb, NULL); |
1584 |
+ if (ret) { |
1585 |
+ rtw89_err(rtwdev, "failed to push txq: %d\n", ret); |
1586 |
+ ieee80211_free_txskb(rtwdev->hw, skb); |
1587 |
+ break; |
1588 |
+ } |
1589 |
+ } |
1590 |
+} |
1591 |
+ |
1592 |
+static u32 rtw89_check_and_reclaim_tx_resource(struct rtw89_dev *rtwdev, u8 tid) |
1593 |
+{ |
1594 |
+ u8 qsel, ch_dma; |
1595 |
+ |
1596 |
+ qsel = rtw89_core_get_qsel(rtwdev, tid); |
1597 |
+ ch_dma = rtw89_core_get_ch_dma(rtwdev, qsel); |
1598 |
+ |
1599 |
+ return rtw89_hci_check_and_reclaim_tx_resource(rtwdev, ch_dma); |
1600 |
+} |
1601 |
+ |
1602 |
+static bool rtw89_core_txq_agg_wait(struct rtw89_dev *rtwdev, |
1603 |
+ struct ieee80211_txq *txq, |
1604 |
+ unsigned long *frame_cnt, |
1605 |
+ bool *sched_txq, bool *reinvoke) |
1606 |
+{ |
1607 |
+ struct rtw89_txq *rtwtxq = (struct rtw89_txq *)txq->drv_priv; |
1608 |
+ struct ieee80211_sta *sta = txq->sta; |
1609 |
+ struct rtw89_sta *rtwsta = (struct rtw89_sta *)sta->drv_priv; |
1610 |
+ |
1611 |
+ if (!sta || rtwsta->max_agg_wait <= 0) |
1612 |
+ return false; |
1613 |
+ |
1614 |
+ if (rtwdev->stats.tx_tfc_lv <= RTW89_TFC_MID) |
1615 |
+ return false; |
1616 |
+ |
1617 |
+ if (*frame_cnt > 1) { |
1618 |
+ *frame_cnt -= 1; |
1619 |
+ *sched_txq = true; |
1620 |
+ *reinvoke = true; |
1621 |
+ rtwtxq->wait_cnt = 1; |
1622 |
+ return false; |
1623 |
+ } |
1624 |
+ |
1625 |
+ if (*frame_cnt == 1 && rtwtxq->wait_cnt < rtwsta->max_agg_wait) { |
1626 |
+ *reinvoke = true; |
1627 |
+ rtwtxq->wait_cnt++; |
1628 |
+ return true; |
1629 |
+ } |
1630 |
+ |
1631 |
+ rtwtxq->wait_cnt = 0; |
1632 |
+ return false; |
1633 |
+} |
1634 |
+ |
1635 |
+static void rtw89_core_txq_schedule(struct rtw89_dev *rtwdev, u8 ac, bool *reinvoke) |
1636 |
+{ |
1637 |
+ struct ieee80211_hw *hw = rtwdev->hw; |
1638 |
+ struct ieee80211_txq *txq; |
1639 |
+ struct rtw89_txq *rtwtxq; |
1640 |
+ unsigned long frame_cnt; |
1641 |
+ unsigned long byte_cnt; |
1642 |
+ u32 tx_resource; |
1643 |
+ bool sched_txq; |
1644 |
+ |
1645 |
+ ieee80211_txq_schedule_start(hw, ac); |
1646 |
+ while ((txq = ieee80211_next_txq(hw, ac))) { |
1647 |
+ rtwtxq = (struct rtw89_txq *)txq->drv_priv; |
1648 |
+ tx_resource = rtw89_check_and_reclaim_tx_resource(rtwdev, txq->tid); |
1649 |
+ sched_txq = false; |
1650 |
+ |
1651 |
+ ieee80211_txq_get_depth(txq, &frame_cnt, &byte_cnt); |
1652 |
+ if (rtw89_core_txq_agg_wait(rtwdev, txq, &frame_cnt, &sched_txq, reinvoke)) { |
1653 |
+ ieee80211_return_txq(hw, txq, true); |
1654 |
+ continue; |
1655 |
+ } |
1656 |
+ frame_cnt = min_t(unsigned long, frame_cnt, tx_resource); |
1657 |
+ rtw89_core_txq_push(rtwdev, rtwtxq, frame_cnt, byte_cnt); |
1658 |
+ ieee80211_return_txq(hw, txq, sched_txq); |
1659 |
+ if (frame_cnt != 0) |
1660 |
+ rtw89_core_tx_kick_off(rtwdev, rtw89_core_get_qsel(rtwdev, txq->tid)); |
1661 |
+ } |
1662 |
+ ieee80211_txq_schedule_end(hw, ac); |
1663 |
+} |
1664 |
+ |
1665 |
+static void rtw89_core_txq_work(struct work_struct *w) |
1666 |
+{ |
1667 |
+ struct rtw89_dev *rtwdev = container_of(w, struct rtw89_dev, txq_work); |
1668 |
+ bool reinvoke = false; |
1669 |
+ u8 ac; |
1670 |
+ |
1671 |
+ for (ac = 0; ac < IEEE80211_NUM_ACS; ac++) |
1672 |
+ rtw89_core_txq_schedule(rtwdev, ac, &reinvoke); |
1673 |
+ |
1674 |
+ if (reinvoke) { |
1675 |
+ /* reinvoke to process the last frame */ |
1676 |
+ mod_delayed_work(rtwdev->txq_wq, &rtwdev->txq_reinvoke_work, 1); |
1677 |
+ } |
1678 |
+} |
1679 |
+ |
1680 |
+static void rtw89_core_txq_reinvoke_work(struct work_struct *w) |
1681 |
+{ |
1682 |
+ struct rtw89_dev *rtwdev = container_of(w, struct rtw89_dev, |
1683 |
+ txq_reinvoke_work.work); |
1684 |
+ |
1685 |
+ queue_work(rtwdev->txq_wq, &rtwdev->txq_work); |
1686 |
+} |
1687 |
+ |
1688 |
+static enum rtw89_tfc_lv rtw89_get_traffic_level(struct rtw89_dev *rtwdev, |
1689 |
+ u32 throughput, u64 cnt) |
1690 |
+{ |
1691 |
+ if (cnt < 100) |
1692 |
+ return RTW89_TFC_IDLE; |
1693 |
+ if (throughput > 50) |
1694 |
+ return RTW89_TFC_HIGH; |
1695 |
+ if (throughput > 10) |
1696 |
+ return RTW89_TFC_MID; |
1697 |
+ if (throughput > 2) |
1698 |
+ return RTW89_TFC_LOW; |
1699 |
+ return RTW89_TFC_ULTRA_LOW; |
1700 |
+} |
1701 |
+ |
1702 |
+static bool rtw89_traffic_stats_calc(struct rtw89_dev *rtwdev, |
1703 |
+ struct rtw89_traffic_stats *stats) |
1704 |
+{ |
1705 |
+ enum rtw89_tfc_lv tx_tfc_lv = stats->tx_tfc_lv; |
1706 |
+ enum rtw89_tfc_lv rx_tfc_lv = stats->rx_tfc_lv; |
1707 |
+ |
1708 |
+ stats->tx_throughput_raw = (u32)(stats->tx_unicast >> RTW89_TP_SHIFT); |
1709 |
+ stats->rx_throughput_raw = (u32)(stats->rx_unicast >> RTW89_TP_SHIFT); |
1710 |
+ |
1711 |
+ ewma_tp_add(&stats->tx_ewma_tp, stats->tx_throughput_raw); |
1712 |
+ ewma_tp_add(&stats->rx_ewma_tp, stats->rx_throughput_raw); |
1713 |
+ |
1714 |
+ stats->tx_throughput = ewma_tp_read(&stats->tx_ewma_tp); |
1715 |
+ stats->rx_throughput = ewma_tp_read(&stats->rx_ewma_tp); |
1716 |
+ stats->tx_tfc_lv = rtw89_get_traffic_level(rtwdev, stats->tx_throughput, |
1717 |
+ stats->tx_cnt); |
1718 |
+ stats->rx_tfc_lv = rtw89_get_traffic_level(rtwdev, stats->rx_throughput, |
1719 |
+ stats->rx_cnt); |
1720 |
+ stats->tx_avg_len = stats->tx_cnt ? |
1721 |
+ DIV_ROUND_DOWN_ULL(stats->tx_unicast, stats->tx_cnt) : 0; |
1722 |
+ stats->rx_avg_len = stats->rx_cnt ? |
1723 |
+ DIV_ROUND_DOWN_ULL(stats->rx_unicast, stats->rx_cnt) : 0; |
1724 |
+ |
1725 |
+ stats->tx_unicast = 0; |
1726 |
+ stats->rx_unicast = 0; |
1727 |
+ stats->tx_cnt = 0; |
1728 |
+ stats->rx_cnt = 0; |
1729 |
+ |
1730 |
+ if (tx_tfc_lv != stats->tx_tfc_lv || rx_tfc_lv != stats->rx_tfc_lv) |
1731 |
+ return true; |
1732 |
+ |
1733 |
+ return false; |
1734 |
+} |
1735 |
+ |
1736 |
+static bool rtw89_traffic_stats_track(struct rtw89_dev *rtwdev) |
1737 |
+{ |
1738 |
+ struct rtw89_vif *rtwvif; |
1739 |
+ bool tfc_changed; |
1740 |
+ |
1741 |
+ tfc_changed = rtw89_traffic_stats_calc(rtwdev, &rtwdev->stats); |
1742 |
+ rtw89_for_each_rtwvif(rtwdev, rtwvif) |
1743 |
+ rtw89_traffic_stats_calc(rtwdev, &rtwvif->stats); |
1744 |
+ |
1745 |
+ return tfc_changed; |
1746 |
+} |
1747 |
+ |
1748 |
+static void rtw89_vif_enter_lps(struct rtw89_dev *rtwdev, struct rtw89_vif *rtwvif) |
1749 |
+{ |
1750 |
+ if (rtwvif->wifi_role != RTW89_WIFI_ROLE_STATION) |
1751 |
+ return; |
1752 |
+ |
1753 |
+ if (rtwvif->stats.tx_tfc_lv == RTW89_TFC_IDLE && |
1754 |
+ rtwvif->stats.rx_tfc_lv == RTW89_TFC_IDLE) |
1755 |
+ rtw89_enter_lps(rtwdev, rtwvif->mac_id); |
1756 |
+} |
1757 |
+ |
1758 |
+static void rtw89_enter_lps_track(struct rtw89_dev *rtwdev) |
1759 |
+{ |
1760 |
+ struct rtw89_vif *rtwvif; |
1761 |
+ |
1762 |
+ rtw89_for_each_rtwvif(rtwdev, rtwvif) |
1763 |
+ rtw89_vif_enter_lps(rtwdev, rtwvif); |
1764 |
+} |
1765 |
+ |
1766 |
+void rtw89_traffic_stats_init(struct rtw89_dev *rtwdev, |
1767 |
+ struct rtw89_traffic_stats *stats) |
1768 |
+{ |
1769 |
+ stats->tx_unicast = 0; |
1770 |
+ stats->rx_unicast = 0; |
1771 |
+ stats->tx_cnt = 0; |
1772 |
+ stats->rx_cnt = 0; |
1773 |
+ ewma_tp_init(&stats->tx_ewma_tp); |
1774 |
+ ewma_tp_init(&stats->rx_ewma_tp); |
1775 |
+} |
1776 |
+ |
1777 |
+static void rtw89_track_work(struct work_struct *work) |
1778 |
+{ |
1779 |
+ struct rtw89_dev *rtwdev = container_of(work, struct rtw89_dev, |
1780 |
+ track_work.work); |
1781 |
+ bool tfc_changed; |
1782 |
+ |
1783 |
+ mutex_lock(&rtwdev->mutex); |
1784 |
+ |
1785 |
+ if (!test_bit(RTW89_FLAG_RUNNING, rtwdev->flags)) |
1786 |
+ goto out; |
1787 |
+ |
1788 |
+ ieee80211_queue_delayed_work(rtwdev->hw, &rtwdev->track_work, |
1789 |
+ RTW89_TRACK_WORK_PERIOD); |
1790 |
+ |
1791 |
+ tfc_changed = rtw89_traffic_stats_track(rtwdev); |
1792 |
+ if (rtwdev->scanning) |
1793 |
+ goto out; |
1794 |
+ |
1795 |
+ rtw89_leave_lps(rtwdev); |
1796 |
+ |
1797 |
+ if (tfc_changed) { |
1798 |
+ rtw89_hci_recalc_int_mit(rtwdev); |
1799 |
+ rtw89_btc_ntfy_wl_sta(rtwdev); |
1800 |
+ } |
1801 |
+ rtw89_mac_bf_monitor_track(rtwdev); |
1802 |
+ rtw89_phy_stat_track(rtwdev); |
1803 |
+ rtw89_phy_env_monitor_track(rtwdev); |
1804 |
+ rtw89_phy_dig(rtwdev); |
1805 |
+ rtw89_chip_rfk_track(rtwdev); |
1806 |
+ rtw89_phy_ra_update(rtwdev); |
1807 |
+ rtw89_phy_cfo_track(rtwdev); |
1808 |
+ |
1809 |
+ if (rtwdev->lps_enabled && !rtwdev->btc.lps) |
1810 |
+ rtw89_enter_lps_track(rtwdev); |
1811 |
+ |
1812 |
+out: |
1813 |
+ mutex_unlock(&rtwdev->mutex); |
1814 |
+} |
1815 |
+ |
1816 |
+u8 rtw89_core_acquire_bit_map(unsigned long *addr, unsigned long size) |
1817 |
+{ |
1818 |
+ unsigned long bit; |
1819 |
+ |
1820 |
+ bit = find_first_zero_bit(addr, size); |
1821 |
+ if (bit < size) |
1822 |
+ set_bit(bit, addr); |
1823 |
+ |
1824 |
+ return bit; |
1825 |
+} |
1826 |
+ |
1827 |
+void rtw89_core_release_bit_map(unsigned long *addr, u8 bit) |
1828 |
+{ |
1829 |
+ clear_bit(bit, addr); |
1830 |
+} |
1831 |
+ |
1832 |
+void rtw89_core_release_all_bits_map(unsigned long *addr, unsigned int nbits) |
1833 |
+{ |
1834 |
+ bitmap_zero(addr, nbits); |
1835 |
+} |
1836 |
+ |
1837 |
+#define RTW89_TYPE_MAPPING(_type) \ |
1838 |
+ case NL80211_IFTYPE_ ## _type: \ |
1839 |
+ rtwvif->wifi_role = RTW89_WIFI_ROLE_ ## _type; \ |
1840 |
+ break |
1841 |
+void rtw89_vif_type_mapping(struct ieee80211_vif *vif, bool assoc) |
1842 |
+{ |
1843 |
+ struct rtw89_vif *rtwvif = (struct rtw89_vif *)vif->drv_priv; |
1844 |
+ |
1845 |
+ switch (vif->type) { |
1846 |
+ RTW89_TYPE_MAPPING(ADHOC); |
1847 |
+ RTW89_TYPE_MAPPING(STATION); |
1848 |
+ RTW89_TYPE_MAPPING(AP); |
1849 |
+ RTW89_TYPE_MAPPING(MONITOR); |
1850 |
+ RTW89_TYPE_MAPPING(MESH_POINT); |
1851 |
+ default: |
1852 |
+ WARN_ON(1); |
1853 |
+ break; |
1854 |
+ } |
1855 |
+ |
1856 |
+ switch (vif->type) { |
1857 |
+ case NL80211_IFTYPE_AP: |
1858 |
+ case NL80211_IFTYPE_MESH_POINT: |
1859 |
+ rtwvif->net_type = RTW89_NET_TYPE_AP_MODE; |
1860 |
+ rtwvif->self_role = RTW89_SELF_ROLE_AP; |
1861 |
+ break; |
1862 |
+ case NL80211_IFTYPE_ADHOC: |
1863 |
+ rtwvif->net_type = RTW89_NET_TYPE_AD_HOC; |
1864 |
+ rtwvif->self_role = RTW89_SELF_ROLE_CLIENT; |
1865 |
+ break; |
1866 |
+ case NL80211_IFTYPE_STATION: |
1867 |
+ if (assoc) { |
1868 |
+ rtwvif->net_type = RTW89_NET_TYPE_INFRA; |
1869 |
+ rtwvif->trigger = vif->bss_conf.he_support; |
1870 |
+ } else { |
1871 |
+ rtwvif->net_type = RTW89_NET_TYPE_NO_LINK; |
1872 |
+ rtwvif->trigger = false; |
1873 |
+ } |
1874 |
+ rtwvif->self_role = RTW89_SELF_ROLE_CLIENT; |
1875 |
+ rtwvif->addr_cam.sec_ent_mode = RTW89_ADDR_CAM_SEC_NORMAL; |
1876 |
+ break; |
1877 |
+ default: |
1878 |
+ WARN_ON(1); |
1879 |
+ break; |
1880 |
+ } |
1881 |
+} |
1882 |
+ |
1883 |
+int rtw89_core_sta_add(struct rtw89_dev *rtwdev, |
1884 |
+ struct ieee80211_vif *vif, |
1885 |
+ struct ieee80211_sta *sta) |
1886 |
+{ |
1887 |
+ struct rtw89_vif *rtwvif = (struct rtw89_vif *)vif->drv_priv; |
1888 |
+ struct rtw89_sta *rtwsta = (struct rtw89_sta *)sta->drv_priv; |
1889 |
+ int i; |
1890 |
+ |
1891 |
+ rtwsta->rtwvif = rtwvif; |
1892 |
+ rtwsta->prev_rssi = 0; |
1893 |
+ |
1894 |
+ for (i = 0; i < ARRAY_SIZE(sta->txq); i++) |
1895 |
+ rtw89_core_txq_init(rtwdev, sta->txq[i]); |
1896 |
+ |
1897 |
+ ewma_rssi_init(&rtwsta->avg_rssi); |
1898 |
+ |
1899 |
+ if (vif->type == NL80211_IFTYPE_STATION) { |
1900 |
+ rtwvif->mgd.ap = sta; |
1901 |
+ rtw89_btc_ntfy_role_info(rtwdev, rtwvif, rtwsta, |
1902 |
+ BTC_ROLE_MSTS_STA_CONN_START); |
1903 |
+ rtw89_chip_rfk_channel(rtwdev); |
1904 |
+ } |
1905 |
+ |
1906 |
+ return 0; |
1907 |
+} |
1908 |
+ |
1909 |
+int rtw89_core_sta_disassoc(struct rtw89_dev *rtwdev, |
1910 |
+ struct ieee80211_vif *vif, |
1911 |
+ struct ieee80211_sta *sta) |
1912 |
+{ |
1913 |
+ struct rtw89_sta *rtwsta = (struct rtw89_sta *)sta->drv_priv; |
1914 |
+ |
1915 |
+ rtwdev->total_sta_assoc--; |
1916 |
+ rtwsta->disassoc = true; |
1917 |
+ |
1918 |
+ return 0; |
1919 |
+} |
1920 |
+ |
1921 |
+int rtw89_core_sta_disconnect(struct rtw89_dev *rtwdev, |
1922 |
+ struct ieee80211_vif *vif, |
1923 |
+ struct ieee80211_sta *sta) |
1924 |
+{ |
1925 |
+ struct rtw89_vif *rtwvif = (struct rtw89_vif *)vif->drv_priv; |
1926 |
+ int ret; |
1927 |
+ |
1928 |
+ rtw89_mac_bf_monitor_calc(rtwdev, sta, true); |
1929 |
+ rtw89_mac_bf_disassoc(rtwdev, vif, sta); |
1930 |
+ rtw89_core_free_sta_pending_ba(rtwdev, sta); |
1931 |
+ |
1932 |
+ rtw89_vif_type_mapping(vif, false); |
1933 |
+ |
1934 |
+ ret = rtw89_fw_h2c_assoc_cmac_tbl(rtwdev, vif, sta); |
1935 |
+ if (ret) { |
1936 |
+ rtw89_warn(rtwdev, "failed to send h2c cmac table\n"); |
1937 |
+ return ret; |
1938 |
+ } |
1939 |
+ |
1940 |
+ ret = rtw89_fw_h2c_join_info(rtwdev, rtwvif, 1); |
1941 |
+ if (ret) { |
1942 |
+ rtw89_warn(rtwdev, "failed to send h2c join info\n"); |
1943 |
+ return ret; |
1944 |
+ } |
1945 |
+ |
1946 |
+ /* update cam aid mac_id net_type */ |
1947 |
+ rtw89_fw_h2c_cam(rtwdev, rtwvif); |
1948 |
+ if (ret) { |
1949 |
+ rtw89_warn(rtwdev, "failed to send h2c cam\n"); |
1950 |
+ return ret; |
1951 |
+ } |
1952 |
+ |
1953 |
+ return ret; |
1954 |
+} |
1955 |
+ |
1956 |
+int rtw89_core_sta_assoc(struct rtw89_dev *rtwdev, |
1957 |
+ struct ieee80211_vif *vif, |
1958 |
+ struct ieee80211_sta *sta) |
1959 |
+{ |
1960 |
+ struct rtw89_vif *rtwvif = (struct rtw89_vif *)vif->drv_priv; |
1961 |
+ struct rtw89_sta *rtwsta = (struct rtw89_sta *)sta->drv_priv; |
1962 |
+ int ret; |
1963 |
+ |
1964 |
+ rtw89_vif_type_mapping(vif, true); |
1965 |
+ |
1966 |
+ ret = rtw89_fw_h2c_assoc_cmac_tbl(rtwdev, vif, sta); |
1967 |
+ if (ret) { |
1968 |
+ rtw89_warn(rtwdev, "failed to send h2c cmac table\n"); |
1969 |
+ return ret; |
1970 |
+ } |
1971 |
+ |
1972 |
+ /* for station mode, assign the mac_id from itself */ |
1973 |
+ if (vif->type == NL80211_IFTYPE_STATION) |
1974 |
+ rtwsta->mac_id = rtwvif->mac_id; |
1975 |
+ |
1976 |
+ ret = rtw89_fw_h2c_join_info(rtwdev, rtwvif, 0); |
1977 |
+ if (ret) { |
1978 |
+ rtw89_warn(rtwdev, "failed to send h2c join info\n"); |
1979 |
+ return ret; |
1980 |
+ } |
1981 |
+ |
1982 |
+ /* update cam aid mac_id net_type */ |
1983 |
+ rtw89_fw_h2c_cam(rtwdev, rtwvif); |
1984 |
+ if (ret) { |
1985 |
+ rtw89_warn(rtwdev, "failed to send h2c cam\n"); |
1986 |
+ return ret; |
1987 |
+ } |
1988 |
+ |
1989 |
+ ret = rtw89_fw_h2c_general_pkt(rtwdev, rtwsta->mac_id); |
1990 |
+ if (ret) { |
1991 |
+ rtw89_warn(rtwdev, "failed to send h2c general packet\n"); |
1992 |
+ return ret; |
1993 |
+ } |
1994 |
+ |
1995 |
+ rtwdev->total_sta_assoc++; |
1996 |
+ rtw89_phy_ra_assoc(rtwdev, sta); |
1997 |
+ rtw89_mac_bf_assoc(rtwdev, vif, sta); |
1998 |
+ rtw89_mac_bf_monitor_calc(rtwdev, sta, false); |
1999 |
+ |
2000 |
+ if (vif->type == NL80211_IFTYPE_STATION) { |
2001 |
+ rtw89_btc_ntfy_role_info(rtwdev, rtwvif, rtwsta, |
2002 |
+ BTC_ROLE_MSTS_STA_CONN_END); |
2003 |
+ rtw89_core_get_no_ul_ofdma_htc(rtwdev, &rtwsta->htc_template); |
2004 |
+ } |
2005 |
+ |
2006 |
+ return ret; |
2007 |
+} |
2008 |
+ |
2009 |
+int rtw89_core_sta_remove(struct rtw89_dev *rtwdev, |
2010 |
+ struct ieee80211_vif *vif, |
2011 |
+ struct ieee80211_sta *sta) |
2012 |
+{ |
2013 |
+ struct rtw89_vif *rtwvif = (struct rtw89_vif *)vif->drv_priv; |
2014 |
+ struct rtw89_sta *rtwsta = (struct rtw89_sta *)sta->drv_priv; |
2015 |
+ |
2016 |
+ if (vif->type == NL80211_IFTYPE_STATION) |
2017 |
+ rtw89_btc_ntfy_role_info(rtwdev, rtwvif, rtwsta, |
2018 |
+ BTC_ROLE_MSTS_STA_DIS_CONN); |
2019 |
+ |
2020 |
+ return 0; |
2021 |
+} |
2022 |
+ |
2023 |
+static void rtw89_init_ht_cap(struct rtw89_dev *rtwdev, |
2024 |
+ struct ieee80211_sta_ht_cap *ht_cap) |
2025 |
+{ |
2026 |
+ static const __le16 highest[RF_PATH_MAX] = { |
2027 |
+ cpu_to_le16(150), cpu_to_le16(300), cpu_to_le16(450), cpu_to_le16(600), |
2028 |
+ }; |
2029 |
+ struct rtw89_hal *hal = &rtwdev->hal; |
2030 |
+ u8 nss = hal->rx_nss; |
2031 |
+ int i; |
2032 |
+ |
2033 |
+ ht_cap->ht_supported = true; |
2034 |
+ ht_cap->cap = 0; |
2035 |
+ ht_cap->cap |= IEEE80211_HT_CAP_SGI_20 | |
2036 |
+ IEEE80211_HT_CAP_MAX_AMSDU | |
2037 |
+ IEEE80211_HT_CAP_TX_STBC | |
2038 |
+ (1 << IEEE80211_HT_CAP_RX_STBC_SHIFT); |
2039 |
+ ht_cap->cap |= IEEE80211_HT_CAP_LDPC_CODING; |
2040 |
+ ht_cap->cap |= IEEE80211_HT_CAP_SUP_WIDTH_20_40 | |
2041 |
+ IEEE80211_HT_CAP_DSSSCCK40 | |
2042 |
+ IEEE80211_HT_CAP_SGI_40; |
2043 |
+ ht_cap->ampdu_factor = IEEE80211_HT_MAX_AMPDU_64K; |
2044 |
+ ht_cap->ampdu_density = IEEE80211_HT_MPDU_DENSITY_NONE; |
2045 |
+ ht_cap->mcs.tx_params = IEEE80211_HT_MCS_TX_DEFINED; |
2046 |
+ for (i = 0; i < nss; i++) |
2047 |
+ ht_cap->mcs.rx_mask[i] = 0xFF; |
2048 |
+ ht_cap->mcs.rx_mask[4] = 0x01; |
2049 |
+ ht_cap->mcs.rx_highest = highest[nss - 1]; |
2050 |
+} |
2051 |
+ |
2052 |
+static void rtw89_init_vht_cap(struct rtw89_dev *rtwdev, |
2053 |
+ struct ieee80211_sta_vht_cap *vht_cap) |
2054 |
+{ |
2055 |
+ static const __le16 highest[RF_PATH_MAX] = { |
2056 |
+ cpu_to_le16(433), cpu_to_le16(867), cpu_to_le16(1300), cpu_to_le16(1733), |
2057 |
+ }; |
2058 |
+ struct rtw89_hal *hal = &rtwdev->hal; |
2059 |
+ u16 tx_mcs_map = 0, rx_mcs_map = 0; |
2060 |
+ u8 sts_cap = 3; |
2061 |
+ int i; |
2062 |
+ |
2063 |
+ for (i = 0; i < 8; i++) { |
2064 |
+ if (i < hal->tx_nss) |
2065 |
+ tx_mcs_map |= IEEE80211_VHT_MCS_SUPPORT_0_9 << (i * 2); |
2066 |
+ else |
2067 |
+ tx_mcs_map |= IEEE80211_VHT_MCS_NOT_SUPPORTED << (i * 2); |
2068 |
+ if (i < hal->rx_nss) |
2069 |
+ rx_mcs_map |= IEEE80211_VHT_MCS_SUPPORT_0_9 << (i * 2); |
2070 |
+ else |
2071 |
+ rx_mcs_map |= IEEE80211_VHT_MCS_NOT_SUPPORTED << (i * 2); |
2072 |
+ } |
2073 |
+ |
2074 |
+ vht_cap->vht_supported = true; |
2075 |
+ vht_cap->cap = IEEE80211_VHT_CAP_MAX_MPDU_LENGTH_11454 | |
2076 |
+ IEEE80211_VHT_CAP_SHORT_GI_80 | |
2077 |
+ IEEE80211_VHT_CAP_RXSTBC_1 | |
2078 |
+ IEEE80211_VHT_CAP_HTC_VHT | |
2079 |
+ IEEE80211_VHT_CAP_MAX_A_MPDU_LENGTH_EXPONENT_MASK | |
2080 |
+ 0; |
2081 |
+ vht_cap->cap |= IEEE80211_VHT_CAP_TXSTBC; |
2082 |
+ vht_cap->cap |= IEEE80211_VHT_CAP_RXLDPC; |
2083 |
+ vht_cap->cap |= IEEE80211_VHT_CAP_MU_BEAMFORMEE_CAPABLE | |
2084 |
+ IEEE80211_VHT_CAP_SU_BEAMFORMEE_CAPABLE; |
2085 |
+ vht_cap->cap |= sts_cap << IEEE80211_VHT_CAP_BEAMFORMEE_STS_SHIFT; |
2086 |
+ vht_cap->vht_mcs.rx_mcs_map = cpu_to_le16(rx_mcs_map); |
2087 |
+ vht_cap->vht_mcs.tx_mcs_map = cpu_to_le16(tx_mcs_map); |
2088 |
+ vht_cap->vht_mcs.rx_highest = highest[hal->rx_nss - 1]; |
2089 |
+ vht_cap->vht_mcs.tx_highest = highest[hal->tx_nss - 1]; |
2090 |
+} |
2091 |
+ |
2092 |
+#define RTW89_SBAND_IFTYPES_NR 2 |
2093 |
+ |
2094 |
+static void rtw89_init_he_cap(struct rtw89_dev *rtwdev, |
2095 |
+ enum nl80211_band band, |
2096 |
+ struct ieee80211_supported_band *sband) |
2097 |
+{ |
2098 |
+ const struct rtw89_chip_info *chip = rtwdev->chip; |
2099 |
+ struct rtw89_hal *hal = &rtwdev->hal; |
2100 |
+ struct ieee80211_sband_iftype_data *iftype_data; |
2101 |
+ bool no_ng16 = (chip->chip_id == RTL8852A && hal->cv == CHIP_CBV) || |
2102 |
+ (chip->chip_id == RTL8852B && hal->cv == CHIP_CAV); |
2103 |
+ u16 mcs_map = 0; |
2104 |
+ int i; |
2105 |
+ int nss = hal->rx_nss; |
2106 |
+ int idx = 0; |
2107 |
+ |
2108 |
+ iftype_data = kcalloc(RTW89_SBAND_IFTYPES_NR, sizeof(*iftype_data), GFP_KERNEL); |
2109 |
+ if (!iftype_data) |
2110 |
+ return; |
2111 |
+ |
2112 |
+ for (i = 0; i < 8; i++) { |
2113 |
+ if (i < nss) |
2114 |
+ mcs_map |= IEEE80211_HE_MCS_SUPPORT_0_11 << (i * 2); |
2115 |
+ else |
2116 |
+ mcs_map |= IEEE80211_HE_MCS_NOT_SUPPORTED << (i * 2); |
2117 |
+ } |
2118 |
+ |
2119 |
+ for (i = 0; i < NUM_NL80211_IFTYPES; i++) { |
2120 |
+ struct ieee80211_sta_he_cap *he_cap; |
2121 |
+ u8 *mac_cap_info; |
2122 |
+ u8 *phy_cap_info; |
2123 |
+ |
2124 |
+ switch (i) { |
2125 |
+ case NL80211_IFTYPE_STATION: |
2126 |
+ case NL80211_IFTYPE_AP: |
2127 |
+ break; |
2128 |
+ default: |
2129 |
+ continue; |
2130 |
+ } |
2131 |
+ |
2132 |
+ if (idx >= RTW89_SBAND_IFTYPES_NR) { |
2133 |
+ rtw89_warn(rtwdev, "run out of iftype_data\n"); |
2134 |
+ break; |
2135 |
+ } |
2136 |
+ |
2137 |
+ iftype_data[idx].types_mask = BIT(i); |
2138 |
+ he_cap = &iftype_data[idx].he_cap; |
2139 |
+ mac_cap_info = he_cap->he_cap_elem.mac_cap_info; |
2140 |
+ phy_cap_info = he_cap->he_cap_elem.phy_cap_info; |
2141 |
+ |
2142 |
+ he_cap->has_he = true; |
2143 |
+ if (i == NL80211_IFTYPE_AP) |
2144 |
+ mac_cap_info[0] = IEEE80211_HE_MAC_CAP0_HTC_HE; |
2145 |
+ if (i == NL80211_IFTYPE_STATION) |
2146 |
+ mac_cap_info[1] = IEEE80211_HE_MAC_CAP1_TF_MAC_PAD_DUR_16US; |
2147 |
+ mac_cap_info[2] = IEEE80211_HE_MAC_CAP2_ALL_ACK | |
2148 |
+ IEEE80211_HE_MAC_CAP2_BSR; |
2149 |
+ mac_cap_info[3] = IEEE80211_HE_MAC_CAP3_MAX_AMPDU_LEN_EXP_EXT_2; |
2150 |
+ if (i == NL80211_IFTYPE_AP) |
2151 |
+ mac_cap_info[3] |= IEEE80211_HE_MAC_CAP3_OMI_CONTROL; |
2152 |
+ mac_cap_info[4] = IEEE80211_HE_MAC_CAP4_OPS | |
2153 |
+ IEEE80211_HE_MAC_CAP4_AMSDU_IN_AMPDU; |
2154 |
+ if (i == NL80211_IFTYPE_STATION) |
2155 |
+ mac_cap_info[5] = IEEE80211_HE_MAC_CAP5_HT_VHT_TRIG_FRAME_RX; |
2156 |
+ phy_cap_info[0] = IEEE80211_HE_PHY_CAP0_CHANNEL_WIDTH_SET_40MHZ_IN_2G | |
2157 |
+ IEEE80211_HE_PHY_CAP0_CHANNEL_WIDTH_SET_40MHZ_80MHZ_IN_5G; |
2158 |
+ phy_cap_info[1] = IEEE80211_HE_PHY_CAP1_DEVICE_CLASS_A | |
2159 |
+ IEEE80211_HE_PHY_CAP1_LDPC_CODING_IN_PAYLOAD | |
2160 |
+ IEEE80211_HE_PHY_CAP1_HE_LTF_AND_GI_FOR_HE_PPDUS_0_8US; |
2161 |
+ phy_cap_info[2] = IEEE80211_HE_PHY_CAP2_NDP_4x_LTF_AND_3_2US | |
2162 |
+ IEEE80211_HE_PHY_CAP2_STBC_TX_UNDER_80MHZ | |
2163 |
+ IEEE80211_HE_PHY_CAP2_STBC_RX_UNDER_80MHZ | |
2164 |
+ IEEE80211_HE_PHY_CAP2_DOPPLER_TX; |
2165 |
+ phy_cap_info[3] = IEEE80211_HE_PHY_CAP3_DCM_MAX_CONST_RX_16_QAM; |
2166 |
+ if (i == NL80211_IFTYPE_STATION) |
2167 |
+ phy_cap_info[3] |= IEEE80211_HE_PHY_CAP3_DCM_MAX_CONST_TX_16_QAM | |
2168 |
+ IEEE80211_HE_PHY_CAP3_DCM_MAX_TX_NSS_2; |
2169 |
+ if (i == NL80211_IFTYPE_AP) |
2170 |
+ phy_cap_info[3] |= IEEE80211_HE_PHY_CAP3_RX_PARTIAL_BW_SU_IN_20MHZ_MU; |
2171 |
+ phy_cap_info[4] = IEEE80211_HE_PHY_CAP4_SU_BEAMFORMEE | |
2172 |
+ IEEE80211_HE_PHY_CAP4_BEAMFORMEE_MAX_STS_UNDER_80MHZ_4; |
2173 |
+ phy_cap_info[5] = no_ng16 ? 0 : |
2174 |
+ IEEE80211_HE_PHY_CAP5_NG16_SU_FEEDBACK | |
2175 |
+ IEEE80211_HE_PHY_CAP5_NG16_MU_FEEDBACK; |
2176 |
+ phy_cap_info[6] = IEEE80211_HE_PHY_CAP6_CODEBOOK_SIZE_42_SU | |
2177 |
+ IEEE80211_HE_PHY_CAP6_CODEBOOK_SIZE_75_MU | |
2178 |
+ IEEE80211_HE_PHY_CAP6_TRIG_SU_BEAMFORMING_FB | |
2179 |
+ IEEE80211_HE_PHY_CAP6_PARTIAL_BW_EXT_RANGE; |
2180 |
+ phy_cap_info[7] = IEEE80211_HE_PHY_CAP7_POWER_BOOST_FACTOR_SUPP | |
2181 |
+ IEEE80211_HE_PHY_CAP7_HE_SU_MU_PPDU_4XLTF_AND_08_US_GI | |
2182 |
+ IEEE80211_HE_PHY_CAP7_MAX_NC_1; |
2183 |
+ phy_cap_info[8] = IEEE80211_HE_PHY_CAP8_HE_ER_SU_PPDU_4XLTF_AND_08_US_GI | |
2184 |
+ IEEE80211_HE_PHY_CAP8_HE_ER_SU_1XLTF_AND_08_US_GI | |
2185 |
+ IEEE80211_HE_PHY_CAP8_DCM_MAX_RU_996; |
2186 |
+ phy_cap_info[9] = IEEE80211_HE_PHY_CAP9_LONGER_THAN_16_SIGB_OFDM_SYM | |
2187 |
+ IEEE80211_HE_PHY_CAP9_RX_1024_QAM_LESS_THAN_242_TONE_RU | |
2188 |
+ IEEE80211_HE_PHY_CAP9_RX_FULL_BW_SU_USING_MU_WITH_COMP_SIGB | |
2189 |
+ IEEE80211_HE_PHY_CAP9_RX_FULL_BW_SU_USING_MU_WITH_NON_COMP_SIGB | |
2190 |
+ IEEE80211_HE_PHY_CAP9_NOMIMAL_PKT_PADDING_16US; |
2191 |
+ if (i == NL80211_IFTYPE_STATION) |
2192 |
+ phy_cap_info[9] |= IEEE80211_HE_PHY_CAP9_TX_1024_QAM_LESS_THAN_242_TONE_RU; |
2193 |
+ he_cap->he_mcs_nss_supp.rx_mcs_80 = cpu_to_le16(mcs_map); |
2194 |
+ he_cap->he_mcs_nss_supp.tx_mcs_80 = cpu_to_le16(mcs_map); |
2195 |
+ |
2196 |
+ idx++; |
2197 |
+ } |
2198 |
+ |
2199 |
+ sband->iftype_data = iftype_data; |
2200 |
+ sband->n_iftype_data = idx; |
2201 |
+} |
2202 |
+ |
2203 |
+static int rtw89_core_set_supported_band(struct rtw89_dev *rtwdev) |
2204 |
+{ |
2205 |
+ struct ieee80211_hw *hw = rtwdev->hw; |
2206 |
+ struct ieee80211_supported_band *sband_2ghz = NULL, *sband_5ghz = NULL; |
2207 |
+ u32 size = sizeof(struct ieee80211_supported_band); |
2208 |
+ |
2209 |
+ sband_2ghz = kmemdup(&rtw89_sband_2ghz, size, GFP_KERNEL); |
2210 |
+ if (!sband_2ghz) |
2211 |
+ goto err; |
2212 |
+ rtw89_init_ht_cap(rtwdev, &sband_2ghz->ht_cap); |
2213 |
+ rtw89_init_he_cap(rtwdev, NL80211_BAND_2GHZ, sband_2ghz); |
2214 |
+ hw->wiphy->bands[NL80211_BAND_2GHZ] = sband_2ghz; |
2215 |
+ |
2216 |
+ sband_5ghz = kmemdup(&rtw89_sband_5ghz, size, GFP_KERNEL); |
2217 |
+ if (!sband_5ghz) |
2218 |
+ goto err; |
2219 |
+ rtw89_init_ht_cap(rtwdev, &sband_5ghz->ht_cap); |
2220 |
+ rtw89_init_vht_cap(rtwdev, &sband_5ghz->vht_cap); |
2221 |
+ rtw89_init_he_cap(rtwdev, NL80211_BAND_5GHZ, sband_5ghz); |
2222 |
+ hw->wiphy->bands[NL80211_BAND_5GHZ] = sband_5ghz; |
2223 |
+ |
2224 |
+ return 0; |
2225 |
+ |
2226 |
+err: |
2227 |
+ hw->wiphy->bands[NL80211_BAND_2GHZ] = NULL; |
2228 |
+ hw->wiphy->bands[NL80211_BAND_5GHZ] = NULL; |
2229 |
+ if (sband_2ghz) |
2230 |
+ kfree(sband_2ghz->iftype_data); |
2231 |
+ if (sband_5ghz) |
2232 |
+ kfree(sband_5ghz->iftype_data); |
2233 |
+ kfree(sband_2ghz); |
2234 |
+ kfree(sband_5ghz); |
2235 |
+ return -ENOMEM; |
2236 |
+} |
2237 |
+ |
2238 |
+static void rtw89_core_clr_supported_band(struct rtw89_dev *rtwdev) |
2239 |
+{ |
2240 |
+ struct ieee80211_hw *hw = rtwdev->hw; |
2241 |
+ |
2242 |
+ kfree(hw->wiphy->bands[NL80211_BAND_2GHZ]->iftype_data); |
2243 |
+ kfree(hw->wiphy->bands[NL80211_BAND_5GHZ]->iftype_data); |
2244 |
+ kfree(hw->wiphy->bands[NL80211_BAND_2GHZ]); |
2245 |
+ kfree(hw->wiphy->bands[NL80211_BAND_5GHZ]); |
2246 |
+ hw->wiphy->bands[NL80211_BAND_2GHZ] = NULL; |
2247 |
+ hw->wiphy->bands[NL80211_BAND_5GHZ] = NULL; |
2248 |
+} |
2249 |
+ |
2250 |
+static void rtw89_core_ppdu_sts_init(struct rtw89_dev *rtwdev) |
2251 |
+{ |
2252 |
+ int i; |
2253 |
+ |
2254 |
+ for (i = 0; i < RTW89_PHY_MAX; i++) |
2255 |
+ skb_queue_head_init(&rtwdev->ppdu_sts.rx_queue[i]); |
2256 |
+ for (i = 0; i < RTW89_PHY_MAX; i++) |
2257 |
+ rtwdev->ppdu_sts.curr_rx_ppdu_cnt[i] = U8_MAX; |
2258 |
+} |
2259 |
+ |
2260 |
+int rtw89_core_start(struct rtw89_dev *rtwdev) |
2261 |
+{ |
2262 |
+ int ret; |
2263 |
+ |
2264 |
+ rtwdev->mac.qta_mode = RTW89_QTA_SCC; |
2265 |
+ ret = rtw89_mac_init(rtwdev); |
2266 |
+ if (ret) { |
2267 |
+ rtw89_err(rtwdev, "mac init fail, ret:%d\n", ret); |
2268 |
+ return ret; |
2269 |
+ } |
2270 |
+ |
2271 |
+ rtw89_btc_ntfy_poweron(rtwdev); |
2272 |
+ |
2273 |
+ /* efuse process */ |
2274 |
+ |
2275 |
+ /* pre-config BB/RF, BB reset/RFC reset */ |
2276 |
+ rtw89_mac_disable_bb_rf(rtwdev); |
2277 |
+ rtw89_mac_enable_bb_rf(rtwdev); |
2278 |
+ rtw89_phy_init_bb_reg(rtwdev); |
2279 |
+ rtw89_phy_init_rf_reg(rtwdev); |
2280 |
+ |
2281 |
+ rtw89_btc_ntfy_init(rtwdev, BTC_MODE_NORMAL); |
2282 |
+ |
2283 |
+ rtw89_phy_dm_init(rtwdev); |
2284 |
+ |
2285 |
+ rtw89_mac_cfg_ppdu_status(rtwdev, RTW89_MAC_0, true); |
2286 |
+ rtw89_mac_update_rts_threshold(rtwdev, RTW89_MAC_0); |
2287 |
+ |
2288 |
+ ret = rtw89_hci_start(rtwdev); |
2289 |
+ if (ret) { |
2290 |
+ rtw89_err(rtwdev, "failed to start hci\n"); |
2291 |
+ return ret; |
2292 |
+ } |
2293 |
+ |
2294 |
+ ieee80211_queue_delayed_work(rtwdev->hw, &rtwdev->track_work, |
2295 |
+ RTW89_TRACK_WORK_PERIOD); |
2296 |
+ |
2297 |
+ set_bit(RTW89_FLAG_RUNNING, rtwdev->flags); |
2298 |
+ |
2299 |
+ rtw89_btc_ntfy_radio_state(rtwdev, BTC_RFCTRL_WL_ON); |
2300 |
+ rtw89_fw_h2c_fw_log(rtwdev, rtwdev->fw.fw_log_enable); |
2301 |
+ |
2302 |
+ return 0; |
2303 |
+} |
2304 |
+ |
2305 |
+void rtw89_core_stop(struct rtw89_dev *rtwdev) |
2306 |
+{ |
2307 |
+ struct rtw89_btc *btc = &rtwdev->btc; |
2308 |
+ |
2309 |
+ /* Prvent to stop twice; enter_ips and ops_stop */ |
2310 |
+ if (!test_bit(RTW89_FLAG_RUNNING, rtwdev->flags)) |
2311 |
+ return; |
2312 |
+ |
2313 |
+ rtw89_btc_ntfy_radio_state(rtwdev, BTC_RFCTRL_WL_OFF); |
2314 |
+ |
2315 |
+ clear_bit(RTW89_FLAG_RUNNING, rtwdev->flags); |
2316 |
+ |
2317 |
+ mutex_unlock(&rtwdev->mutex); |
2318 |
+ |
2319 |
+ cancel_work_sync(&rtwdev->c2h_work); |
2320 |
+ cancel_work_sync(&btc->eapol_notify_work); |
2321 |
+ cancel_work_sync(&btc->arp_notify_work); |
2322 |
+ cancel_work_sync(&btc->dhcp_notify_work); |
2323 |
+ cancel_work_sync(&btc->icmp_notify_work); |
2324 |
+ cancel_delayed_work_sync(&rtwdev->txq_reinvoke_work); |
2325 |
+ cancel_delayed_work_sync(&rtwdev->track_work); |
2326 |
+ cancel_delayed_work_sync(&rtwdev->coex_act1_work); |
2327 |
+ cancel_delayed_work_sync(&rtwdev->coex_bt_devinfo_work); |
2328 |
+ cancel_delayed_work_sync(&rtwdev->coex_rfk_chk_work); |
2329 |
+ cancel_delayed_work_sync(&rtwdev->cfo_track_work); |
2330 |
+ |
2331 |
+ mutex_lock(&rtwdev->mutex); |
2332 |
+ |
2333 |
+ rtw89_btc_ntfy_poweroff(rtwdev); |
2334 |
+ rtw89_hci_flush_queues(rtwdev, BIT(rtwdev->hw->queues) - 1, true); |
2335 |
+ rtw89_mac_flush_txq(rtwdev, BIT(rtwdev->hw->queues) - 1, true); |
2336 |
+ rtw89_hci_stop(rtwdev); |
2337 |
+ rtw89_hci_deinit(rtwdev); |
2338 |
+ rtw89_mac_pwr_off(rtwdev); |
2339 |
+ rtw89_hci_reset(rtwdev); |
2340 |
+} |
2341 |
+ |
2342 |
+int rtw89_core_init(struct rtw89_dev *rtwdev) |
2343 |
+{ |
2344 |
+ struct rtw89_btc *btc = &rtwdev->btc; |
2345 |
+ int ret; |
2346 |
+ |
2347 |
+ INIT_LIST_HEAD(&rtwdev->ba_list); |
2348 |
+ INIT_LIST_HEAD(&rtwdev->rtwvifs_list); |
2349 |
+ INIT_LIST_HEAD(&rtwdev->early_h2c_list); |
2350 |
+ INIT_WORK(&rtwdev->ba_work, rtw89_core_ba_work); |
2351 |
+ INIT_WORK(&rtwdev->txq_work, rtw89_core_txq_work); |
2352 |
+ INIT_DELAYED_WORK(&rtwdev->txq_reinvoke_work, rtw89_core_txq_reinvoke_work); |
2353 |
+ INIT_DELAYED_WORK(&rtwdev->track_work, rtw89_track_work); |
2354 |
+ INIT_DELAYED_WORK(&rtwdev->coex_act1_work, rtw89_coex_act1_work); |
2355 |
+ INIT_DELAYED_WORK(&rtwdev->coex_bt_devinfo_work, rtw89_coex_bt_devinfo_work); |
2356 |
+ INIT_DELAYED_WORK(&rtwdev->coex_rfk_chk_work, rtw89_coex_rfk_chk_work); |
2357 |
+ INIT_DELAYED_WORK(&rtwdev->cfo_track_work, rtw89_phy_cfo_track_work); |
2358 |
+ rtwdev->txq_wq = alloc_workqueue("rtw89_tx_wq", WQ_UNBOUND | WQ_HIGHPRI, 0); |
2359 |
+ spin_lock_init(&rtwdev->ba_lock); |
2360 |
+ mutex_init(&rtwdev->mutex); |
2361 |
+ mutex_init(&rtwdev->rf_mutex); |
2362 |
+ rtwdev->total_sta_assoc = 0; |
2363 |
+ |
2364 |
+ INIT_WORK(&rtwdev->c2h_work, rtw89_fw_c2h_work); |
2365 |
+ skb_queue_head_init(&rtwdev->c2h_queue); |
2366 |
+ rtw89_core_ppdu_sts_init(rtwdev); |
2367 |
+ rtw89_traffic_stats_init(rtwdev, &rtwdev->stats); |
2368 |
+ |
2369 |
+ rtwdev->ps_mode = rtw89_update_ps_mode(rtwdev); |
2370 |
+ rtwdev->hal.rx_fltr = DEFAULT_AX_RX_FLTR; |
2371 |
+ |
2372 |
+ INIT_WORK(&btc->eapol_notify_work, rtw89_btc_ntfy_eapol_packet_work); |
2373 |
+ INIT_WORK(&btc->arp_notify_work, rtw89_btc_ntfy_arp_packet_work); |
2374 |
+ INIT_WORK(&btc->dhcp_notify_work, rtw89_btc_ntfy_dhcp_packet_work); |
2375 |
+ INIT_WORK(&btc->icmp_notify_work, rtw89_btc_ntfy_icmp_packet_work); |
2376 |
+ |
2377 |
+ ret = rtw89_load_firmware(rtwdev); |
2378 |
+ if (ret) { |
2379 |
+ rtw89_warn(rtwdev, "no firmware loaded\n"); |
2380 |
+ return ret; |
2381 |
+ } |
2382 |
+ rtw89_ser_init(rtwdev); |
2383 |
+ |
2384 |
+ return 0; |
2385 |
+} |
2386 |
+EXPORT_SYMBOL(rtw89_core_init); |
2387 |
+ |
2388 |
+void rtw89_core_deinit(struct rtw89_dev *rtwdev) |
2389 |
+{ |
2390 |
+ rtw89_ser_deinit(rtwdev); |
2391 |
+ rtw89_unload_firmware(rtwdev); |
2392 |
+ rtw89_fw_free_all_early_h2c(rtwdev); |
2393 |
+ |
2394 |
+ destroy_workqueue(rtwdev->txq_wq); |
2395 |
+ mutex_destroy(&rtwdev->rf_mutex); |
2396 |
+ mutex_destroy(&rtwdev->mutex); |
2397 |
+} |
2398 |
+EXPORT_SYMBOL(rtw89_core_deinit); |
2399 |
+ |
2400 |
+static void rtw89_read_chip_ver(struct rtw89_dev *rtwdev) |
2401 |
+{ |
2402 |
+ u8 cv; |
2403 |
+ |
2404 |
+ cv = rtw89_read32_mask(rtwdev, R_AX_SYS_CFG1, B_AX_CHIP_VER_MASK); |
2405 |
+ if (cv <= CHIP_CBV) { |
2406 |
+ if (rtw89_read32(rtwdev, R_AX_GPIO0_7_FUNC_SEL) == RTW89_R32_DEAD) |
2407 |
+ cv = CHIP_CAV; |
2408 |
+ else |
2409 |
+ cv = CHIP_CBV; |
2410 |
+ } |
2411 |
+ |
2412 |
+ rtwdev->hal.cv = cv; |
2413 |
+} |
2414 |
+ |
2415 |
+static int rtw89_chip_efuse_info_setup(struct rtw89_dev *rtwdev) |
2416 |
+{ |
2417 |
+ int ret; |
2418 |
+ |
2419 |
+ ret = rtw89_mac_partial_init(rtwdev); |
2420 |
+ if (ret) |
2421 |
+ return ret; |
2422 |
+ |
2423 |
+ ret = rtw89_parse_efuse_map(rtwdev); |
2424 |
+ if (ret) |
2425 |
+ return ret; |
2426 |
+ |
2427 |
+ ret = rtw89_parse_phycap_map(rtwdev); |
2428 |
+ if (ret) |
2429 |
+ return ret; |
2430 |
+ |
2431 |
+ ret = rtw89_mac_setup_phycap(rtwdev); |
2432 |
+ if (ret) |
2433 |
+ return ret; |
2434 |
+ |
2435 |
+ rtw89_mac_pwr_off(rtwdev); |
2436 |
+ |
2437 |
+ return 0; |
2438 |
+} |
2439 |
+ |
2440 |
+static int rtw89_chip_board_info_setup(struct rtw89_dev *rtwdev) |
2441 |
+{ |
2442 |
+ rtw89_chip_fem_setup(rtwdev); |
2443 |
+ |
2444 |
+ return 0; |
2445 |
+} |
2446 |
+ |
2447 |
+int rtw89_chip_info_setup(struct rtw89_dev *rtwdev) |
2448 |
+{ |
2449 |
+ int ret; |
2450 |
+ |
2451 |
+ rtw89_read_chip_ver(rtwdev); |
2452 |
+ |
2453 |
+ ret = rtw89_wait_firmware_completion(rtwdev); |
2454 |
+ if (ret) { |
2455 |
+ rtw89_err(rtwdev, "failed to wait firmware completion\n"); |
2456 |
+ return ret; |
2457 |
+ } |
2458 |
+ |
2459 |
+ ret = rtw89_fw_recognize(rtwdev); |
2460 |
+ if (ret) { |
2461 |
+ rtw89_err(rtwdev, "failed to recognize firmware\n"); |
2462 |
+ return ret; |
2463 |
+ } |
2464 |
+ |
2465 |
+ ret = rtw89_chip_efuse_info_setup(rtwdev); |
2466 |
+ if (ret) |
2467 |
+ return ret; |
2468 |
+ |
2469 |
+ ret = rtw89_chip_board_info_setup(rtwdev); |
2470 |
+ if (ret) |
2471 |
+ return ret; |
2472 |
+ |
2473 |
+ return 0; |
2474 |
+} |
2475 |
+EXPORT_SYMBOL(rtw89_chip_info_setup); |
2476 |
+ |
2477 |
+static int rtw89_core_register_hw(struct rtw89_dev *rtwdev) |
2478 |
+{ |
2479 |
+ struct ieee80211_hw *hw = rtwdev->hw; |
2480 |
+ struct rtw89_efuse *efuse = &rtwdev->efuse; |
2481 |
+ int ret; |
2482 |
+ int tx_headroom = IEEE80211_HT_CTL_LEN; |
2483 |
+ |
2484 |
+ hw->vif_data_size = sizeof(struct rtw89_vif); |
2485 |
+ hw->sta_data_size = sizeof(struct rtw89_sta); |
2486 |
+ hw->txq_data_size = sizeof(struct rtw89_txq); |
2487 |
+ |
2488 |
+ SET_IEEE80211_PERM_ADDR(hw, efuse->addr); |
2489 |
+ |
2490 |
+ hw->extra_tx_headroom = tx_headroom; |
2491 |
+ hw->queues = IEEE80211_NUM_ACS; |
2492 |
+ hw->max_rx_aggregation_subframes = RTW89_MAX_RX_AGG_NUM; |
2493 |
+ hw->max_tx_aggregation_subframes = RTW89_MAX_TX_AGG_NUM; |
2494 |
+ |
2495 |
+ ieee80211_hw_set(hw, SIGNAL_DBM); |
2496 |
+ ieee80211_hw_set(hw, HAS_RATE_CONTROL); |
2497 |
+ ieee80211_hw_set(hw, MFP_CAPABLE); |
2498 |
+ ieee80211_hw_set(hw, REPORTS_TX_ACK_STATUS); |
2499 |
+ ieee80211_hw_set(hw, AMPDU_AGGREGATION); |
2500 |
+ ieee80211_hw_set(hw, RX_INCLUDES_FCS); |
2501 |
+ ieee80211_hw_set(hw, TX_AMSDU); |
2502 |
+ ieee80211_hw_set(hw, SUPPORT_FAST_XMIT); |
2503 |
+ ieee80211_hw_set(hw, SUPPORTS_AMSDU_IN_AMPDU); |
2504 |
+ ieee80211_hw_set(hw, SUPPORTS_PS); |
2505 |
+ ieee80211_hw_set(hw, SUPPORTS_DYNAMIC_PS); |
2506 |
+ |
2507 |
+ hw->wiphy->interface_modes = BIT(NL80211_IFTYPE_STATION); |
2508 |
+ hw->wiphy->available_antennas_tx = BIT(rtwdev->chip->rf_path_num) - 1; |
2509 |
+ hw->wiphy->available_antennas_rx = BIT(rtwdev->chip->rf_path_num) - 1; |
2510 |
+ |
2511 |
+ hw->wiphy->features |= NL80211_FEATURE_SCAN_RANDOM_MAC_ADDR; |
2512 |
+ |
2513 |
+ wiphy_ext_feature_set(hw->wiphy, NL80211_EXT_FEATURE_CAN_REPLACE_PTK0); |
2514 |
+ |
2515 |
+ ret = rtw89_core_set_supported_band(rtwdev); |
2516 |
+ if (ret) { |
2517 |
+ rtw89_err(rtwdev, "failed to set supported band\n"); |
2518 |
+ return ret; |
2519 |
+ } |
2520 |
+ |
2521 |
+ hw->wiphy->reg_notifier = rtw89_regd_notifier; |
2522 |
+ hw->wiphy->sar_capa = &rtw89_sar_capa; |
2523 |
+ |
2524 |
+ ret = ieee80211_register_hw(hw); |
2525 |
+ if (ret) { |
2526 |
+ rtw89_err(rtwdev, "failed to register hw\n"); |
2527 |
+ goto err; |
2528 |
+ } |
2529 |
+ |
2530 |
+ ret = rtw89_regd_init(rtwdev, rtw89_regd_notifier); |
2531 |
+ if (ret) { |
2532 |
+ rtw89_err(rtwdev, "failed to init regd\n"); |
2533 |
+ goto err; |
2534 |
+ } |
2535 |
+ |
2536 |
+ return 0; |
2537 |
+ |
2538 |
+err: |
2539 |
+ return ret; |
2540 |
+} |
2541 |
+ |
2542 |
+static void rtw89_core_unregister_hw(struct rtw89_dev *rtwdev) |
2543 |
+{ |
2544 |
+ struct ieee80211_hw *hw = rtwdev->hw; |
2545 |
+ |
2546 |
+ ieee80211_unregister_hw(hw); |
2547 |
+ rtw89_core_clr_supported_band(rtwdev); |
2548 |
+} |
2549 |
+ |
2550 |
+int rtw89_core_register(struct rtw89_dev *rtwdev) |
2551 |
+{ |
2552 |
+ int ret; |
2553 |
+ |
2554 |
+ ret = rtw89_core_register_hw(rtwdev); |
2555 |
+ if (ret) { |
2556 |
+ rtw89_err(rtwdev, "failed to register core hw\n"); |
2557 |
+ return ret; |
2558 |
+ } |
2559 |
+ |
2560 |
+ rtw89_debugfs_init(rtwdev); |
2561 |
+ |
2562 |
+ return 0; |
2563 |
+} |
2564 |
+EXPORT_SYMBOL(rtw89_core_register); |
2565 |
+ |
2566 |
+void rtw89_core_unregister(struct rtw89_dev *rtwdev) |
2567 |
+{ |
2568 |
+ rtw89_core_unregister_hw(rtwdev); |
2569 |
+} |
2570 |
+EXPORT_SYMBOL(rtw89_core_unregister); |
2571 |
+ |
2572 |
+MODULE_AUTHOR("Realtek Corporation"); |
2573 |
+MODULE_DESCRIPTION("Realtek 802.11ax wireless core module"); |
2574 |
+MODULE_LICENSE("Dual BSD/GPL"); |
2575 |
diff --git a/drivers/net/wireless/realtek/rtw89/core.h b/drivers/net/wireless/realtek/rtw89/core.h |
2576 |
new file mode 100644 |
2577 |
index 000000000000..c2885e4dd882 |
2578 |
--- /dev/null |
2579 |
+++ b/drivers/net/wireless/realtek/rtw89/core.h |
2580 |
@@ -0,0 +1,3384 @@ |
2581 |
+/* SPDX-License-Identifier: GPL-2.0 OR BSD-3-Clause */ |
2582 |
+/* Copyright(c) 2019-2020 Realtek Corporation |
2583 |
+ */ |
2584 |
+ |
2585 |
+#ifndef __RTW89_CORE_H__ |
2586 |
+#define __RTW89_CORE_H__ |
2587 |
+ |
2588 |
+#include <linux/average.h> |
2589 |
+#include <linux/bitfield.h> |
2590 |
+#include <linux/firmware.h> |
2591 |
+#include <linux/iopoll.h> |
2592 |
+#include <linux/workqueue.h> |
2593 |
+#include <net/mac80211.h> |
2594 |
+ |
2595 |
+struct rtw89_dev; |
2596 |
+ |
2597 |
+extern const struct ieee80211_ops rtw89_ops; |
2598 |
+extern const struct rtw89_chip_info rtw8852a_chip_info; |
2599 |
+ |
2600 |
+#define MASKBYTE0 0xff |
2601 |
+#define MASKBYTE1 0xff00 |
2602 |
+#define MASKBYTE2 0xff0000 |
2603 |
+#define MASKBYTE3 0xff000000 |
2604 |
+#define MASKBYTE4 0xff00000000ULL |
2605 |
+#define MASKHWORD 0xffff0000 |
2606 |
+#define MASKLWORD 0x0000ffff |
2607 |
+#define MASKDWORD 0xffffffff |
2608 |
+#define RFREG_MASK 0xfffff |
2609 |
+#define INV_RF_DATA 0xffffffff |
2610 |
+ |
2611 |
+#define RTW89_TRACK_WORK_PERIOD round_jiffies_relative(HZ * 2) |
2612 |
+#define CFO_TRACK_MAX_USER 64 |
2613 |
+#define MAX_RSSI 110 |
2614 |
+#define RSSI_FACTOR 1 |
2615 |
+#define RTW89_RSSI_RAW_TO_DBM(rssi) ((s8)((rssi) >> RSSI_FACTOR) - MAX_RSSI) |
2616 |
+#define RTW89_MAX_HW_PORT_NUM 5 |
2617 |
+ |
2618 |
+#define RTW89_HTC_MASK_VARIANT GENMASK(1, 0) |
2619 |
+#define RTW89_HTC_VARIANT_HE 3 |
2620 |
+#define RTW89_HTC_MASK_CTL_ID GENMASK(5, 2) |
2621 |
+#define RTW89_HTC_VARIANT_HE_CID_OM 1 |
2622 |
+#define RTW89_HTC_VARIANT_HE_CID_CAS 6 |
2623 |
+#define RTW89_HTC_MASK_CTL_INFO GENMASK(31, 6) |
2624 |
+ |
2625 |
+#define RTW89_HTC_MASK_HTC_OM_RX_NSS GENMASK(8, 6) |
2626 |
+enum htc_om_channel_width { |
2627 |
+ HTC_OM_CHANNEL_WIDTH_20 = 0, |
2628 |
+ HTC_OM_CHANNEL_WIDTH_40 = 1, |
2629 |
+ HTC_OM_CHANNEL_WIDTH_80 = 2, |
2630 |
+ HTC_OM_CHANNEL_WIDTH_160_OR_80_80 = 3, |
2631 |
+}; |
2632 |
+#define RTW89_HTC_MASK_HTC_OM_CH_WIDTH GENMASK(10, 9) |
2633 |
+#define RTW89_HTC_MASK_HTC_OM_UL_MU_DIS BIT(11) |
2634 |
+#define RTW89_HTC_MASK_HTC_OM_TX_NSTS GENMASK(14, 12) |
2635 |
+#define RTW89_HTC_MASK_HTC_OM_ER_SU_DIS BIT(15) |
2636 |
+#define RTW89_HTC_MASK_HTC_OM_DL_MU_MIMO_RR BIT(16) |
2637 |
+#define RTW89_HTC_MASK_HTC_OM_UL_MU_DATA_DIS BIT(17) |
2638 |
+ |
2639 |
+enum rtw89_subband { |
2640 |
+ RTW89_CH_2G = 0, |
2641 |
+ RTW89_CH_5G_BAND_1 = 1, |
2642 |
+ /* RTW89_CH_5G_BAND_2 = 2, unused */ |
2643 |
+ RTW89_CH_5G_BAND_3 = 3, |
2644 |
+ RTW89_CH_5G_BAND_4 = 4, |
2645 |
+ |
2646 |
+ RTW89_SUBBAND_NR, |
2647 |
+}; |
2648 |
+ |
2649 |
+enum rtw89_hci_type { |
2650 |
+ RTW89_HCI_TYPE_PCIE, |
2651 |
+ RTW89_HCI_TYPE_USB, |
2652 |
+ RTW89_HCI_TYPE_SDIO, |
2653 |
+}; |
2654 |
+ |
2655 |
+enum rtw89_core_chip_id { |
2656 |
+ RTL8852A, |
2657 |
+ RTL8852B, |
2658 |
+ RTL8852C, |
2659 |
+}; |
2660 |
+ |
2661 |
+enum rtw89_cv { |
2662 |
+ CHIP_CAV, |
2663 |
+ CHIP_CBV, |
2664 |
+ CHIP_CCV, |
2665 |
+ CHIP_CDV, |
2666 |
+ CHIP_CEV, |
2667 |
+ CHIP_CFV, |
2668 |
+ CHIP_CV_MAX, |
2669 |
+ CHIP_CV_INVALID = CHIP_CV_MAX, |
2670 |
+}; |
2671 |
+ |
2672 |
+enum rtw89_core_tx_type { |
2673 |
+ RTW89_CORE_TX_TYPE_DATA, |
2674 |
+ RTW89_CORE_TX_TYPE_MGMT, |
2675 |
+ RTW89_CORE_TX_TYPE_FWCMD, |
2676 |
+}; |
2677 |
+ |
2678 |
+enum rtw89_core_rx_type { |
2679 |
+ RTW89_CORE_RX_TYPE_WIFI = 0, |
2680 |
+ RTW89_CORE_RX_TYPE_PPDU_STAT = 1, |
2681 |
+ RTW89_CORE_RX_TYPE_CHAN_INFO = 2, |
2682 |
+ RTW89_CORE_RX_TYPE_BB_SCOPE = 3, |
2683 |
+ RTW89_CORE_RX_TYPE_F2P_TXCMD = 4, |
2684 |
+ RTW89_CORE_RX_TYPE_SS2FW = 5, |
2685 |
+ RTW89_CORE_RX_TYPE_TX_REPORT = 6, |
2686 |
+ RTW89_CORE_RX_TYPE_TX_REL_HOST = 7, |
2687 |
+ RTW89_CORE_RX_TYPE_DFS_REPORT = 8, |
2688 |
+ RTW89_CORE_RX_TYPE_TX_REL_CPU = 9, |
2689 |
+ RTW89_CORE_RX_TYPE_C2H = 10, |
2690 |
+ RTW89_CORE_RX_TYPE_CSI = 11, |
2691 |
+ RTW89_CORE_RX_TYPE_CQI = 12, |
2692 |
+}; |
2693 |
+ |
2694 |
+enum rtw89_txq_flags { |
2695 |
+ RTW89_TXQ_F_AMPDU = 0, |
2696 |
+ RTW89_TXQ_F_BLOCK_BA = 1, |
2697 |
+}; |
2698 |
+ |
2699 |
+enum rtw89_net_type { |
2700 |
+ RTW89_NET_TYPE_NO_LINK = 0, |
2701 |
+ RTW89_NET_TYPE_AD_HOC = 1, |
2702 |
+ RTW89_NET_TYPE_INFRA = 2, |
2703 |
+ RTW89_NET_TYPE_AP_MODE = 3, |
2704 |
+}; |
2705 |
+ |
2706 |
+enum rtw89_wifi_role { |
2707 |
+ RTW89_WIFI_ROLE_NONE, |
2708 |
+ RTW89_WIFI_ROLE_STATION, |
2709 |
+ RTW89_WIFI_ROLE_AP, |
2710 |
+ RTW89_WIFI_ROLE_AP_VLAN, |
2711 |
+ RTW89_WIFI_ROLE_ADHOC, |
2712 |
+ RTW89_WIFI_ROLE_ADHOC_MASTER, |
2713 |
+ RTW89_WIFI_ROLE_MESH_POINT, |
2714 |
+ RTW89_WIFI_ROLE_MONITOR, |
2715 |
+ RTW89_WIFI_ROLE_P2P_DEVICE, |
2716 |
+ RTW89_WIFI_ROLE_P2P_CLIENT, |
2717 |
+ RTW89_WIFI_ROLE_P2P_GO, |
2718 |
+ RTW89_WIFI_ROLE_NAN, |
2719 |
+ RTW89_WIFI_ROLE_MLME_MAX |
2720 |
+}; |
2721 |
+ |
2722 |
+enum rtw89_upd_mode { |
2723 |
+ RTW89_VIF_CREATE, |
2724 |
+ RTW89_VIF_REMOVE, |
2725 |
+ RTW89_VIF_TYPE_CHANGE, |
2726 |
+ RTW89_VIF_INFO_CHANGE, |
2727 |
+ RTW89_VIF_CON_DISCONN |
2728 |
+}; |
2729 |
+ |
2730 |
+enum rtw89_self_role { |
2731 |
+ RTW89_SELF_ROLE_CLIENT, |
2732 |
+ RTW89_SELF_ROLE_AP, |
2733 |
+ RTW89_SELF_ROLE_AP_CLIENT |
2734 |
+}; |
2735 |
+ |
2736 |
+enum rtw89_msk_sO_el { |
2737 |
+ RTW89_NO_MSK, |
2738 |
+ RTW89_SMA, |
2739 |
+ RTW89_TMA, |
2740 |
+ RTW89_BSSID |
2741 |
+}; |
2742 |
+ |
2743 |
+enum rtw89_sch_tx_sel { |
2744 |
+ RTW89_SCH_TX_SEL_ALL, |
2745 |
+ RTW89_SCH_TX_SEL_HIQ, |
2746 |
+ RTW89_SCH_TX_SEL_MG0, |
2747 |
+ RTW89_SCH_TX_SEL_MACID, |
2748 |
+}; |
2749 |
+ |
2750 |
+/* RTW89_ADDR_CAM_SEC_NONE : not enabled |
2751 |
+ * RTW89_ADDR_CAM_SEC_ALL_UNI : 0 - 6 unicast |
2752 |
+ * RTW89_ADDR_CAM_SEC_NORMAL : 0 - 1 unicast, 2 - 4 group, 5 - 6 BIP |
2753 |
+ * RTW89_ADDR_CAM_SEC_4GROUP : 0 - 1 unicast, 2 - 5 group, 6 BIP |
2754 |
+ */ |
2755 |
+enum rtw89_add_cam_sec_mode { |
2756 |
+ RTW89_ADDR_CAM_SEC_NONE = 0, |
2757 |
+ RTW89_ADDR_CAM_SEC_ALL_UNI = 1, |
2758 |
+ RTW89_ADDR_CAM_SEC_NORMAL = 2, |
2759 |
+ RTW89_ADDR_CAM_SEC_4GROUP = 3, |
2760 |
+}; |
2761 |
+ |
2762 |
+enum rtw89_sec_key_type { |
2763 |
+ RTW89_SEC_KEY_TYPE_NONE = 0, |
2764 |
+ RTW89_SEC_KEY_TYPE_WEP40 = 1, |
2765 |
+ RTW89_SEC_KEY_TYPE_WEP104 = 2, |
2766 |
+ RTW89_SEC_KEY_TYPE_TKIP = 3, |
2767 |
+ RTW89_SEC_KEY_TYPE_WAPI = 4, |
2768 |
+ RTW89_SEC_KEY_TYPE_GCMSMS4 = 5, |
2769 |
+ RTW89_SEC_KEY_TYPE_CCMP128 = 6, |
2770 |
+ RTW89_SEC_KEY_TYPE_CCMP256 = 7, |
2771 |
+ RTW89_SEC_KEY_TYPE_GCMP128 = 8, |
2772 |
+ RTW89_SEC_KEY_TYPE_GCMP256 = 9, |
2773 |
+ RTW89_SEC_KEY_TYPE_BIP_CCMP128 = 10, |
2774 |
+}; |
2775 |
+ |
2776 |
+enum rtw89_port { |
2777 |
+ RTW89_PORT_0 = 0, |
2778 |
+ RTW89_PORT_1 = 1, |
2779 |
+ RTW89_PORT_2 = 2, |
2780 |
+ RTW89_PORT_3 = 3, |
2781 |
+ RTW89_PORT_4 = 4, |
2782 |
+ RTW89_PORT_NUM |
2783 |
+}; |
2784 |
+ |
2785 |
+enum rtw89_band { |
2786 |
+ RTW89_BAND_2G = 0, |
2787 |
+ RTW89_BAND_5G = 1, |
2788 |
+ RTW89_BAND_MAX, |
2789 |
+}; |
2790 |
+ |
2791 |
+enum rtw89_hw_rate { |
2792 |
+ RTW89_HW_RATE_CCK1 = 0x0, |
2793 |
+ RTW89_HW_RATE_CCK2 = 0x1, |
2794 |
+ RTW89_HW_RATE_CCK5_5 = 0x2, |
2795 |
+ RTW89_HW_RATE_CCK11 = 0x3, |
2796 |
+ RTW89_HW_RATE_OFDM6 = 0x4, |
2797 |
+ RTW89_HW_RATE_OFDM9 = 0x5, |
2798 |
+ RTW89_HW_RATE_OFDM12 = 0x6, |
2799 |
+ RTW89_HW_RATE_OFDM18 = 0x7, |
2800 |
+ RTW89_HW_RATE_OFDM24 = 0x8, |
2801 |
+ RTW89_HW_RATE_OFDM36 = 0x9, |
2802 |
+ RTW89_HW_RATE_OFDM48 = 0xA, |
2803 |
+ RTW89_HW_RATE_OFDM54 = 0xB, |
2804 |
+ RTW89_HW_RATE_MCS0 = 0x80, |
2805 |
+ RTW89_HW_RATE_MCS1 = 0x81, |
2806 |
+ RTW89_HW_RATE_MCS2 = 0x82, |
2807 |
+ RTW89_HW_RATE_MCS3 = 0x83, |
2808 |
+ RTW89_HW_RATE_MCS4 = 0x84, |
2809 |
+ RTW89_HW_RATE_MCS5 = 0x85, |
2810 |
+ RTW89_HW_RATE_MCS6 = 0x86, |
2811 |
+ RTW89_HW_RATE_MCS7 = 0x87, |
2812 |
+ RTW89_HW_RATE_MCS8 = 0x88, |
2813 |
+ RTW89_HW_RATE_MCS9 = 0x89, |
2814 |
+ RTW89_HW_RATE_MCS10 = 0x8A, |
2815 |
+ RTW89_HW_RATE_MCS11 = 0x8B, |
2816 |
+ RTW89_HW_RATE_MCS12 = 0x8C, |
2817 |
+ RTW89_HW_RATE_MCS13 = 0x8D, |
2818 |
+ RTW89_HW_RATE_MCS14 = 0x8E, |
2819 |
+ RTW89_HW_RATE_MCS15 = 0x8F, |
2820 |
+ RTW89_HW_RATE_MCS16 = 0x90, |
2821 |
+ RTW89_HW_RATE_MCS17 = 0x91, |
2822 |
+ RTW89_HW_RATE_MCS18 = 0x92, |
2823 |
+ RTW89_HW_RATE_MCS19 = 0x93, |
2824 |
+ RTW89_HW_RATE_MCS20 = 0x94, |
2825 |
+ RTW89_HW_RATE_MCS21 = 0x95, |
2826 |
+ RTW89_HW_RATE_MCS22 = 0x96, |
2827 |
+ RTW89_HW_RATE_MCS23 = 0x97, |
2828 |
+ RTW89_HW_RATE_MCS24 = 0x98, |
2829 |
+ RTW89_HW_RATE_MCS25 = 0x99, |
2830 |
+ RTW89_HW_RATE_MCS26 = 0x9A, |
2831 |
+ RTW89_HW_RATE_MCS27 = 0x9B, |
2832 |
+ RTW89_HW_RATE_MCS28 = 0x9C, |
2833 |
+ RTW89_HW_RATE_MCS29 = 0x9D, |
2834 |
+ RTW89_HW_RATE_MCS30 = 0x9E, |
2835 |
+ RTW89_HW_RATE_MCS31 = 0x9F, |
2836 |
+ RTW89_HW_RATE_VHT_NSS1_MCS0 = 0x100, |
2837 |
+ RTW89_HW_RATE_VHT_NSS1_MCS1 = 0x101, |
2838 |
+ RTW89_HW_RATE_VHT_NSS1_MCS2 = 0x102, |
2839 |
+ RTW89_HW_RATE_VHT_NSS1_MCS3 = 0x103, |
2840 |
+ RTW89_HW_RATE_VHT_NSS1_MCS4 = 0x104, |
2841 |
+ RTW89_HW_RATE_VHT_NSS1_MCS5 = 0x105, |
2842 |
+ RTW89_HW_RATE_VHT_NSS1_MCS6 = 0x106, |
2843 |
+ RTW89_HW_RATE_VHT_NSS1_MCS7 = 0x107, |
2844 |
+ RTW89_HW_RATE_VHT_NSS1_MCS8 = 0x108, |
2845 |
+ RTW89_HW_RATE_VHT_NSS1_MCS9 = 0x109, |
2846 |
+ RTW89_HW_RATE_VHT_NSS2_MCS0 = 0x110, |
2847 |
+ RTW89_HW_RATE_VHT_NSS2_MCS1 = 0x111, |
2848 |
+ RTW89_HW_RATE_VHT_NSS2_MCS2 = 0x112, |
2849 |
+ RTW89_HW_RATE_VHT_NSS2_MCS3 = 0x113, |
2850 |
+ RTW89_HW_RATE_VHT_NSS2_MCS4 = 0x114, |
2851 |
+ RTW89_HW_RATE_VHT_NSS2_MCS5 = 0x115, |
2852 |
+ RTW89_HW_RATE_VHT_NSS2_MCS6 = 0x116, |
2853 |
+ RTW89_HW_RATE_VHT_NSS2_MCS7 = 0x117, |
2854 |
+ RTW89_HW_RATE_VHT_NSS2_MCS8 = 0x118, |
2855 |
+ RTW89_HW_RATE_VHT_NSS2_MCS9 = 0x119, |
2856 |
+ RTW89_HW_RATE_VHT_NSS3_MCS0 = 0x120, |
2857 |
+ RTW89_HW_RATE_VHT_NSS3_MCS1 = 0x121, |
2858 |
+ RTW89_HW_RATE_VHT_NSS3_MCS2 = 0x122, |
2859 |
+ RTW89_HW_RATE_VHT_NSS3_MCS3 = 0x123, |
2860 |
+ RTW89_HW_RATE_VHT_NSS3_MCS4 = 0x124, |
2861 |
+ RTW89_HW_RATE_VHT_NSS3_MCS5 = 0x125, |
2862 |
+ RTW89_HW_RATE_VHT_NSS3_MCS6 = 0x126, |
2863 |
+ RTW89_HW_RATE_VHT_NSS3_MCS7 = 0x127, |
2864 |
+ RTW89_HW_RATE_VHT_NSS3_MCS8 = 0x128, |
2865 |
+ RTW89_HW_RATE_VHT_NSS3_MCS9 = 0x129, |
2866 |
+ RTW89_HW_RATE_VHT_NSS4_MCS0 = 0x130, |
2867 |
+ RTW89_HW_RATE_VHT_NSS4_MCS1 = 0x131, |
2868 |
+ RTW89_HW_RATE_VHT_NSS4_MCS2 = 0x132, |
2869 |
+ RTW89_HW_RATE_VHT_NSS4_MCS3 = 0x133, |
2870 |
+ RTW89_HW_RATE_VHT_NSS4_MCS4 = 0x134, |
2871 |
+ RTW89_HW_RATE_VHT_NSS4_MCS5 = 0x135, |
2872 |
+ RTW89_HW_RATE_VHT_NSS4_MCS6 = 0x136, |
2873 |
+ RTW89_HW_RATE_VHT_NSS4_MCS7 = 0x137, |
2874 |
+ RTW89_HW_RATE_VHT_NSS4_MCS8 = 0x138, |
2875 |
+ RTW89_HW_RATE_VHT_NSS4_MCS9 = 0x139, |
2876 |
+ RTW89_HW_RATE_HE_NSS1_MCS0 = 0x180, |
2877 |
+ RTW89_HW_RATE_HE_NSS1_MCS1 = 0x181, |
2878 |
+ RTW89_HW_RATE_HE_NSS1_MCS2 = 0x182, |
2879 |
+ RTW89_HW_RATE_HE_NSS1_MCS3 = 0x183, |
2880 |
+ RTW89_HW_RATE_HE_NSS1_MCS4 = 0x184, |
2881 |
+ RTW89_HW_RATE_HE_NSS1_MCS5 = 0x185, |
2882 |
+ RTW89_HW_RATE_HE_NSS1_MCS6 = 0x186, |
2883 |
+ RTW89_HW_RATE_HE_NSS1_MCS7 = 0x187, |
2884 |
+ RTW89_HW_RATE_HE_NSS1_MCS8 = 0x188, |
2885 |
+ RTW89_HW_RATE_HE_NSS1_MCS9 = 0x189, |
2886 |
+ RTW89_HW_RATE_HE_NSS1_MCS10 = 0x18A, |
2887 |
+ RTW89_HW_RATE_HE_NSS1_MCS11 = 0x18B, |
2888 |
+ RTW89_HW_RATE_HE_NSS2_MCS0 = 0x190, |
2889 |
+ RTW89_HW_RATE_HE_NSS2_MCS1 = 0x191, |
2890 |
+ RTW89_HW_RATE_HE_NSS2_MCS2 = 0x192, |
2891 |
+ RTW89_HW_RATE_HE_NSS2_MCS3 = 0x193, |
2892 |
+ RTW89_HW_RATE_HE_NSS2_MCS4 = 0x194, |
2893 |
+ RTW89_HW_RATE_HE_NSS2_MCS5 = 0x195, |
2894 |
+ RTW89_HW_RATE_HE_NSS2_MCS6 = 0x196, |
2895 |
+ RTW89_HW_RATE_HE_NSS2_MCS7 = 0x197, |
2896 |
+ RTW89_HW_RATE_HE_NSS2_MCS8 = 0x198, |
2897 |
+ RTW89_HW_RATE_HE_NSS2_MCS9 = 0x199, |
2898 |
+ RTW89_HW_RATE_HE_NSS2_MCS10 = 0x19A, |
2899 |
+ RTW89_HW_RATE_HE_NSS2_MCS11 = 0x19B, |
2900 |
+ RTW89_HW_RATE_HE_NSS3_MCS0 = 0x1A0, |
2901 |
+ RTW89_HW_RATE_HE_NSS3_MCS1 = 0x1A1, |
2902 |
+ RTW89_HW_RATE_HE_NSS3_MCS2 = 0x1A2, |
2903 |
+ RTW89_HW_RATE_HE_NSS3_MCS3 = 0x1A3, |
2904 |
+ RTW89_HW_RATE_HE_NSS3_MCS4 = 0x1A4, |
2905 |
+ RTW89_HW_RATE_HE_NSS3_MCS5 = 0x1A5, |
2906 |
+ RTW89_HW_RATE_HE_NSS3_MCS6 = 0x1A6, |
2907 |
+ RTW89_HW_RATE_HE_NSS3_MCS7 = 0x1A7, |
2908 |
+ RTW89_HW_RATE_HE_NSS3_MCS8 = 0x1A8, |
2909 |
+ RTW89_HW_RATE_HE_NSS3_MCS9 = 0x1A9, |
2910 |
+ RTW89_HW_RATE_HE_NSS3_MCS10 = 0x1AA, |
2911 |
+ RTW89_HW_RATE_HE_NSS3_MCS11 = 0x1AB, |
2912 |
+ RTW89_HW_RATE_HE_NSS4_MCS0 = 0x1B0, |
2913 |
+ RTW89_HW_RATE_HE_NSS4_MCS1 = 0x1B1, |
2914 |
+ RTW89_HW_RATE_HE_NSS4_MCS2 = 0x1B2, |
2915 |
+ RTW89_HW_RATE_HE_NSS4_MCS3 = 0x1B3, |
2916 |
+ RTW89_HW_RATE_HE_NSS4_MCS4 = 0x1B4, |
2917 |
+ RTW89_HW_RATE_HE_NSS4_MCS5 = 0x1B5, |
2918 |
+ RTW89_HW_RATE_HE_NSS4_MCS6 = 0x1B6, |
2919 |
+ RTW89_HW_RATE_HE_NSS4_MCS7 = 0x1B7, |
2920 |
+ RTW89_HW_RATE_HE_NSS4_MCS8 = 0x1B8, |
2921 |
+ RTW89_HW_RATE_HE_NSS4_MCS9 = 0x1B9, |
2922 |
+ RTW89_HW_RATE_HE_NSS4_MCS10 = 0x1BA, |
2923 |
+ RTW89_HW_RATE_HE_NSS4_MCS11 = 0x1BB, |
2924 |
+ RTW89_HW_RATE_NR, |
2925 |
+ |
2926 |
+ RTW89_HW_RATE_MASK_MOD = GENMASK(8, 7), |
2927 |
+ RTW89_HW_RATE_MASK_VAL = GENMASK(6, 0), |
2928 |
+}; |
2929 |
+ |
2930 |
+/* 2G channels, |
2931 |
+ * 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14 |
2932 |
+ */ |
2933 |
+#define RTW89_2G_CH_NUM 14 |
2934 |
+ |
2935 |
+/* 5G channels, |
2936 |
+ * 36, 38, 40, 42, 44, 46, 48, 50, |
2937 |
+ * 52, 54, 56, 58, 60, 62, 64, |
2938 |
+ * 100, 102, 104, 106, 108, 110, 112, 114, |
2939 |
+ * 116, 118, 120, 122, 124, 126, 128, 130, |
2940 |
+ * 132, 134, 136, 138, 140, 142, 144, |
2941 |
+ * 149, 151, 153, 155, 157, 159, 161, 163, |
2942 |
+ * 165, 167, 169, 171, 173, 175, 177 |
2943 |
+ */ |
2944 |
+#define RTW89_5G_CH_NUM 53 |
2945 |
+ |
2946 |
+enum rtw89_rate_section { |
2947 |
+ RTW89_RS_CCK, |
2948 |
+ RTW89_RS_OFDM, |
2949 |
+ RTW89_RS_MCS, /* for HT/VHT/HE */ |
2950 |
+ RTW89_RS_HEDCM, |
2951 |
+ RTW89_RS_OFFSET, |
2952 |
+ RTW89_RS_MAX, |
2953 |
+ RTW89_RS_LMT_NUM = RTW89_RS_MCS + 1, |
2954 |
+}; |
2955 |
+ |
2956 |
+enum rtw89_rate_max { |
2957 |
+ RTW89_RATE_CCK_MAX = 4, |
2958 |
+ RTW89_RATE_OFDM_MAX = 8, |
2959 |
+ RTW89_RATE_MCS_MAX = 12, |
2960 |
+ RTW89_RATE_HEDCM_MAX = 4, /* for HEDCM MCS0/1/3/4 */ |
2961 |
+ RTW89_RATE_OFFSET_MAX = 5, /* for HE(HEDCM)/VHT/HT/OFDM/CCK offset */ |
2962 |
+}; |
2963 |
+ |
2964 |
+enum rtw89_nss { |
2965 |
+ RTW89_NSS_1 = 0, |
2966 |
+ RTW89_NSS_2 = 1, |
2967 |
+ /* HE DCM only support 1ss and 2ss */ |
2968 |
+ RTW89_NSS_HEDCM_MAX = RTW89_NSS_2 + 1, |
2969 |
+ RTW89_NSS_3 = 2, |
2970 |
+ RTW89_NSS_4 = 3, |
2971 |
+ RTW89_NSS_MAX, |
2972 |
+}; |
2973 |
+ |
2974 |
+enum rtw89_ntx { |
2975 |
+ RTW89_1TX = 0, |
2976 |
+ RTW89_2TX = 1, |
2977 |
+ RTW89_NTX_NUM, |
2978 |
+}; |
2979 |
+ |
2980 |
+enum rtw89_beamforming_type { |
2981 |
+ RTW89_NONBF = 0, |
2982 |
+ RTW89_BF = 1, |
2983 |
+ RTW89_BF_NUM, |
2984 |
+}; |
2985 |
+ |
2986 |
+enum rtw89_regulation_type { |
2987 |
+ RTW89_WW = 0, |
2988 |
+ RTW89_ETSI = 1, |
2989 |
+ RTW89_FCC = 2, |
2990 |
+ RTW89_MKK = 3, |
2991 |
+ RTW89_NA = 4, |
2992 |
+ RTW89_IC = 5, |
2993 |
+ RTW89_KCC = 6, |
2994 |
+ RTW89_NCC = 7, |
2995 |
+ RTW89_CHILE = 8, |
2996 |
+ RTW89_ACMA = 9, |
2997 |
+ RTW89_MEXICO = 10, |
2998 |
+ RTW89_UKRAINE = 11, |
2999 |
+ RTW89_CN = 12, |
3000 |
+ RTW89_REGD_NUM, |
3001 |
+}; |
3002 |
+ |
3003 |
+extern const u8 rtw89_rs_idx_max[RTW89_RS_MAX]; |
3004 |
+extern const u8 rtw89_rs_nss_max[RTW89_RS_MAX]; |
3005 |
+ |
3006 |
+struct rtw89_txpwr_byrate { |
3007 |
+ s8 cck[RTW89_RATE_CCK_MAX]; |
3008 |
+ s8 ofdm[RTW89_RATE_OFDM_MAX]; |
3009 |
+ s8 mcs[RTW89_NSS_MAX][RTW89_RATE_MCS_MAX]; |
3010 |
+ s8 hedcm[RTW89_NSS_HEDCM_MAX][RTW89_RATE_HEDCM_MAX]; |
3011 |
+ s8 offset[RTW89_RATE_OFFSET_MAX]; |
3012 |
+}; |
3013 |
+ |
3014 |
+enum rtw89_bandwidth_section_num { |
3015 |
+ RTW89_BW20_SEC_NUM = 8, |
3016 |
+ RTW89_BW40_SEC_NUM = 4, |
3017 |
+ RTW89_BW80_SEC_NUM = 2, |
3018 |
+}; |
3019 |
+ |
3020 |
+struct rtw89_txpwr_limit { |
3021 |
+ s8 cck_20m[RTW89_BF_NUM]; |
3022 |
+ s8 cck_40m[RTW89_BF_NUM]; |
3023 |
+ s8 ofdm[RTW89_BF_NUM]; |
3024 |
+ s8 mcs_20m[RTW89_BW20_SEC_NUM][RTW89_BF_NUM]; |
3025 |
+ s8 mcs_40m[RTW89_BW40_SEC_NUM][RTW89_BF_NUM]; |
3026 |
+ s8 mcs_80m[RTW89_BW80_SEC_NUM][RTW89_BF_NUM]; |
3027 |
+ s8 mcs_160m[RTW89_BF_NUM]; |
3028 |
+ s8 mcs_40m_0p5[RTW89_BF_NUM]; |
3029 |
+ s8 mcs_40m_2p5[RTW89_BF_NUM]; |
3030 |
+}; |
3031 |
+ |
3032 |
+#define RTW89_RU_SEC_NUM 8 |
3033 |
+ |
3034 |
+struct rtw89_txpwr_limit_ru { |
3035 |
+ s8 ru26[RTW89_RU_SEC_NUM]; |
3036 |
+ s8 ru52[RTW89_RU_SEC_NUM]; |
3037 |
+ s8 ru106[RTW89_RU_SEC_NUM]; |
3038 |
+}; |
3039 |
+ |
3040 |
+struct rtw89_rate_desc { |
3041 |
+ enum rtw89_nss nss; |
3042 |
+ enum rtw89_rate_section rs; |
3043 |
+ u8 idx; |
3044 |
+}; |
3045 |
+ |
3046 |
+#define PHY_STS_HDR_LEN 8 |
3047 |
+#define RF_PATH_MAX 4 |
3048 |
+#define RTW89_MAX_PPDU_CNT 8 |
3049 |
+struct rtw89_rx_phy_ppdu { |
3050 |
+ u8 *buf; |
3051 |
+ u32 len; |
3052 |
+ u8 rssi_avg; |
3053 |
+ s8 rssi[RF_PATH_MAX]; |
3054 |
+ u8 mac_id; |
3055 |
+ bool to_self; |
3056 |
+ bool valid; |
3057 |
+}; |
3058 |
+ |
3059 |
+enum rtw89_mac_idx { |
3060 |
+ RTW89_MAC_0 = 0, |
3061 |
+ RTW89_MAC_1 = 1, |
3062 |
+}; |
3063 |
+ |
3064 |
+enum rtw89_phy_idx { |
3065 |
+ RTW89_PHY_0 = 0, |
3066 |
+ RTW89_PHY_1 = 1, |
3067 |
+ RTW89_PHY_MAX |
3068 |
+}; |
3069 |
+ |
3070 |
+enum rtw89_rf_path { |
3071 |
+ RF_PATH_A = 0, |
3072 |
+ RF_PATH_B = 1, |
3073 |
+ RF_PATH_C = 2, |
3074 |
+ RF_PATH_D = 3, |
3075 |
+ RF_PATH_AB, |
3076 |
+ RF_PATH_AC, |
3077 |
+ RF_PATH_AD, |
3078 |
+ RF_PATH_BC, |
3079 |
+ RF_PATH_BD, |
3080 |
+ RF_PATH_CD, |
3081 |
+ RF_PATH_ABC, |
3082 |
+ RF_PATH_ABD, |
3083 |
+ RF_PATH_ACD, |
3084 |
+ RF_PATH_BCD, |
3085 |
+ RF_PATH_ABCD, |
3086 |
+}; |
3087 |
+ |
3088 |
+enum rtw89_rf_path_bit { |
3089 |
+ RF_A = BIT(0), |
3090 |
+ RF_B = BIT(1), |
3091 |
+ RF_C = BIT(2), |
3092 |
+ RF_D = BIT(3), |
3093 |
+ |
3094 |
+ RF_AB = (RF_A | RF_B), |
3095 |
+ RF_AC = (RF_A | RF_C), |
3096 |
+ RF_AD = (RF_A | RF_D), |
3097 |
+ RF_BC = (RF_B | RF_C), |
3098 |
+ RF_BD = (RF_B | RF_D), |
3099 |
+ RF_CD = (RF_C | RF_D), |
3100 |
+ |
3101 |
+ RF_ABC = (RF_A | RF_B | RF_C), |
3102 |
+ RF_ABD = (RF_A | RF_B | RF_D), |
3103 |
+ RF_ACD = (RF_A | RF_C | RF_D), |
3104 |
+ RF_BCD = (RF_B | RF_C | RF_D), |
3105 |
+ |
3106 |
+ RF_ABCD = (RF_A | RF_B | RF_C | RF_D), |
3107 |
+}; |
3108 |
+ |
3109 |
+enum rtw89_bandwidth { |
3110 |
+ RTW89_CHANNEL_WIDTH_20 = 0, |
3111 |
+ RTW89_CHANNEL_WIDTH_40 = 1, |
3112 |
+ RTW89_CHANNEL_WIDTH_80 = 2, |
3113 |
+ RTW89_CHANNEL_WIDTH_160 = 3, |
3114 |
+ RTW89_CHANNEL_WIDTH_80_80 = 4, |
3115 |
+ RTW89_CHANNEL_WIDTH_5 = 5, |
3116 |
+ RTW89_CHANNEL_WIDTH_10 = 6, |
3117 |
+}; |
3118 |
+ |
3119 |
+enum rtw89_ps_mode { |
3120 |
+ RTW89_PS_MODE_NONE = 0, |
3121 |
+ RTW89_PS_MODE_RFOFF = 1, |
3122 |
+ RTW89_PS_MODE_CLK_GATED = 2, |
3123 |
+ RTW89_PS_MODE_PWR_GATED = 3, |
3124 |
+}; |
3125 |
+ |
3126 |
+#define RTW89_MAX_CHANNEL_WIDTH RTW89_CHANNEL_WIDTH_80 |
3127 |
+#define RTW89_2G_BW_NUM (RTW89_CHANNEL_WIDTH_40 + 1) |
3128 |
+#define RTW89_5G_BW_NUM (RTW89_CHANNEL_WIDTH_80 + 1) |
3129 |
+#define RTW89_PPE_BW_NUM (RTW89_CHANNEL_WIDTH_80 + 1) |
3130 |
+ |
3131 |
+enum rtw89_ru_bandwidth { |
3132 |
+ RTW89_RU26 = 0, |
3133 |
+ RTW89_RU52 = 1, |
3134 |
+ RTW89_RU106 = 2, |
3135 |
+ RTW89_RU_NUM, |
3136 |
+}; |
3137 |
+ |
3138 |
+enum rtw89_sc_offset { |
3139 |
+ RTW89_SC_DONT_CARE = 0, |
3140 |
+ RTW89_SC_20_UPPER = 1, |
3141 |
+ RTW89_SC_20_LOWER = 2, |
3142 |
+ RTW89_SC_20_UPMOST = 3, |
3143 |
+ RTW89_SC_20_LOWEST = 4, |
3144 |
+ RTW89_SC_40_UPPER = 9, |
3145 |
+ RTW89_SC_40_LOWER = 10, |
3146 |
+}; |
3147 |
+ |
3148 |
+struct rtw89_channel_params { |
3149 |
+ u8 center_chan; |
3150 |
+ u8 primary_chan; |
3151 |
+ u8 bandwidth; |
3152 |
+ u8 pri_ch_idx; |
3153 |
+ u8 cch_by_bw[RTW89_MAX_CHANNEL_WIDTH + 1]; |
3154 |
+}; |
3155 |
+ |
3156 |
+struct rtw89_channel_help_params { |
3157 |
+ u16 tx_en; |
3158 |
+}; |
3159 |
+ |
3160 |
+struct rtw89_port_reg { |
3161 |
+ u32 port_cfg; |
3162 |
+ u32 tbtt_prohib; |
3163 |
+ u32 bcn_area; |
3164 |
+ u32 bcn_early; |
3165 |
+ u32 tbtt_early; |
3166 |
+ u32 tbtt_agg; |
3167 |
+ u32 bcn_space; |
3168 |
+ u32 bcn_forcetx; |
3169 |
+ u32 bcn_err_cnt; |
3170 |
+ u32 bcn_err_flag; |
3171 |
+ u32 dtim_ctrl; |
3172 |
+ u32 tbtt_shift; |
3173 |
+ u32 bcn_cnt_tmr; |
3174 |
+ u32 tsftr_l; |
3175 |
+ u32 tsftr_h; |
3176 |
+}; |
3177 |
+ |
3178 |
+struct rtw89_txwd_body { |
3179 |
+ __le32 dword0; |
3180 |
+ __le32 dword1; |
3181 |
+ __le32 dword2; |
3182 |
+ __le32 dword3; |
3183 |
+ __le32 dword4; |
3184 |
+ __le32 dword5; |
3185 |
+} __packed; |
3186 |
+ |
3187 |
+struct rtw89_txwd_info { |
3188 |
+ __le32 dword0; |
3189 |
+ __le32 dword1; |
3190 |
+ __le32 dword2; |
3191 |
+ __le32 dword3; |
3192 |
+ __le32 dword4; |
3193 |
+ __le32 dword5; |
3194 |
+} __packed; |
3195 |
+ |
3196 |
+struct rtw89_rx_desc_info { |
3197 |
+ u16 pkt_size; |
3198 |
+ u8 pkt_type; |
3199 |
+ u8 drv_info_size; |
3200 |
+ u8 shift; |
3201 |
+ u8 wl_hd_iv_len; |
3202 |
+ bool long_rxdesc; |
3203 |
+ bool bb_sel; |
3204 |
+ bool mac_info_valid; |
3205 |
+ u16 data_rate; |
3206 |
+ u8 gi_ltf; |
3207 |
+ u8 bw; |
3208 |
+ u32 free_run_cnt; |
3209 |
+ u8 user_id; |
3210 |
+ bool sr_en; |
3211 |
+ u8 ppdu_cnt; |
3212 |
+ u8 ppdu_type; |
3213 |
+ bool icv_err; |
3214 |
+ bool crc32_err; |
3215 |
+ bool hw_dec; |
3216 |
+ bool sw_dec; |
3217 |
+ bool addr1_match; |
3218 |
+ u8 frag; |
3219 |
+ u16 seq; |
3220 |
+ u8 frame_type; |
3221 |
+ u8 rx_pl_id; |
3222 |
+ bool addr_cam_valid; |
3223 |
+ u8 addr_cam_id; |
3224 |
+ u8 sec_cam_id; |
3225 |
+ u8 mac_id; |
3226 |
+ u16 offset; |
3227 |
+ bool ready; |
3228 |
+}; |
3229 |
+ |
3230 |
+struct rtw89_rxdesc_short { |
3231 |
+ __le32 dword0; |
3232 |
+ __le32 dword1; |
3233 |
+ __le32 dword2; |
3234 |
+ __le32 dword3; |
3235 |
+} __packed; |
3236 |
+ |
3237 |
+struct rtw89_rxdesc_long { |
3238 |
+ __le32 dword0; |
3239 |
+ __le32 dword1; |
3240 |
+ __le32 dword2; |
3241 |
+ __le32 dword3; |
3242 |
+ __le32 dword4; |
3243 |
+ __le32 dword5; |
3244 |
+ __le32 dword6; |
3245 |
+ __le32 dword7; |
3246 |
+} __packed; |
3247 |
+ |
3248 |
+struct rtw89_tx_desc_info { |
3249 |
+ u16 pkt_size; |
3250 |
+ u8 wp_offset; |
3251 |
+ u8 qsel; |
3252 |
+ u8 ch_dma; |
3253 |
+ u8 hdr_llc_len; |
3254 |
+ bool is_bmc; |
3255 |
+ bool en_wd_info; |
3256 |
+ bool wd_page; |
3257 |
+ bool use_rate; |
3258 |
+ bool dis_data_fb; |
3259 |
+ bool tid_indicate; |
3260 |
+ bool agg_en; |
3261 |
+ bool bk; |
3262 |
+ u8 ampdu_density; |
3263 |
+ u8 ampdu_num; |
3264 |
+ bool sec_en; |
3265 |
+ u8 sec_type; |
3266 |
+ u8 sec_cam_idx; |
3267 |
+ u16 data_rate; |
3268 |
+ u16 data_retry_lowest_rate; |
3269 |
+ bool fw_dl; |
3270 |
+ u16 seq; |
3271 |
+ bool a_ctrl_bsr; |
3272 |
+}; |
3273 |
+ |
3274 |
+struct rtw89_core_tx_request { |
3275 |
+ enum rtw89_core_tx_type tx_type; |
3276 |
+ |
3277 |
+ struct sk_buff *skb; |
3278 |
+ struct ieee80211_vif *vif; |
3279 |
+ struct ieee80211_sta *sta; |
3280 |
+ struct rtw89_tx_desc_info desc_info; |
3281 |
+}; |
3282 |
+ |
3283 |
+struct rtw89_txq { |
3284 |
+ struct list_head list; |
3285 |
+ unsigned long flags; |
3286 |
+ int wait_cnt; |
3287 |
+}; |
3288 |
+ |
3289 |
+struct rtw89_mac_ax_gnt { |
3290 |
+ u8 gnt_bt_sw_en; |
3291 |
+ u8 gnt_bt; |
3292 |
+ u8 gnt_wl_sw_en; |
3293 |
+ u8 gnt_wl; |
3294 |
+}; |
3295 |
+ |
3296 |
+#define RTW89_MAC_AX_COEX_GNT_NR 2 |
3297 |
+struct rtw89_mac_ax_coex_gnt { |
3298 |
+ struct rtw89_mac_ax_gnt band[RTW89_MAC_AX_COEX_GNT_NR]; |
3299 |
+}; |
3300 |
+ |
3301 |
+enum rtw89_btc_ncnt { |
3302 |
+ BTC_NCNT_POWER_ON = 0x0, |
3303 |
+ BTC_NCNT_POWER_OFF, |
3304 |
+ BTC_NCNT_INIT_COEX, |
3305 |
+ BTC_NCNT_SCAN_START, |
3306 |
+ BTC_NCNT_SCAN_FINISH, |
3307 |
+ BTC_NCNT_SPECIAL_PACKET, |
3308 |
+ BTC_NCNT_SWITCH_BAND, |
3309 |
+ BTC_NCNT_RFK_TIMEOUT, |
3310 |
+ BTC_NCNT_SHOW_COEX_INFO, |
3311 |
+ BTC_NCNT_ROLE_INFO, |
3312 |
+ BTC_NCNT_CONTROL, |
3313 |
+ BTC_NCNT_RADIO_STATE, |
3314 |
+ BTC_NCNT_CUSTOMERIZE, |
3315 |
+ BTC_NCNT_WL_RFK, |
3316 |
+ BTC_NCNT_WL_STA, |
3317 |
+ BTC_NCNT_FWINFO, |
3318 |
+ BTC_NCNT_TIMER, |
3319 |
+ BTC_NCNT_NUM |
3320 |
+}; |
3321 |
+ |
3322 |
+enum rtw89_btc_btinfo { |
3323 |
+ BTC_BTINFO_L0 = 0, |
3324 |
+ BTC_BTINFO_L1, |
3325 |
+ BTC_BTINFO_L2, |
3326 |
+ BTC_BTINFO_L3, |
3327 |
+ BTC_BTINFO_H0, |
3328 |
+ BTC_BTINFO_H1, |
3329 |
+ BTC_BTINFO_H2, |
3330 |
+ BTC_BTINFO_H3, |
3331 |
+ BTC_BTINFO_MAX |
3332 |
+}; |
3333 |
+ |
3334 |
+enum rtw89_btc_dcnt { |
3335 |
+ BTC_DCNT_RUN = 0x0, |
3336 |
+ BTC_DCNT_CX_RUNINFO, |
3337 |
+ BTC_DCNT_RPT, |
3338 |
+ BTC_DCNT_RPT_FREEZE, |
3339 |
+ BTC_DCNT_CYCLE, |
3340 |
+ BTC_DCNT_CYCLE_FREEZE, |
3341 |
+ BTC_DCNT_W1, |
3342 |
+ BTC_DCNT_W1_FREEZE, |
3343 |
+ BTC_DCNT_B1, |
3344 |
+ BTC_DCNT_B1_FREEZE, |
3345 |
+ BTC_DCNT_TDMA_NONSYNC, |
3346 |
+ BTC_DCNT_SLOT_NONSYNC, |
3347 |
+ BTC_DCNT_BTCNT_FREEZE, |
3348 |
+ BTC_DCNT_WL_SLOT_DRIFT, |
3349 |
+ BTC_DCNT_WL_STA_LAST, |
3350 |
+ BTC_DCNT_NUM, |
3351 |
+}; |
3352 |
+ |
3353 |
+enum rtw89_btc_wl_state_cnt { |
3354 |
+ BTC_WCNT_SCANAP = 0x0, |
3355 |
+ BTC_WCNT_DHCP, |
3356 |
+ BTC_WCNT_EAPOL, |
3357 |
+ BTC_WCNT_ARP, |
3358 |
+ BTC_WCNT_SCBDUPDATE, |
3359 |
+ BTC_WCNT_RFK_REQ, |
3360 |
+ BTC_WCNT_RFK_GO, |
3361 |
+ BTC_WCNT_RFK_REJECT, |
3362 |
+ BTC_WCNT_RFK_TIMEOUT, |
3363 |
+ BTC_WCNT_CH_UPDATE, |
3364 |
+ BTC_WCNT_NUM |
3365 |
+}; |
3366 |
+ |
3367 |
+enum rtw89_btc_bt_state_cnt { |
3368 |
+ BTC_BCNT_RETRY = 0x0, |
3369 |
+ BTC_BCNT_REINIT, |
3370 |
+ BTC_BCNT_REENABLE, |
3371 |
+ BTC_BCNT_SCBDREAD, |
3372 |
+ BTC_BCNT_RELINK, |
3373 |
+ BTC_BCNT_IGNOWL, |
3374 |
+ BTC_BCNT_INQPAG, |
3375 |
+ BTC_BCNT_INQ, |
3376 |
+ BTC_BCNT_PAGE, |
3377 |
+ BTC_BCNT_ROLESW, |
3378 |
+ BTC_BCNT_AFH, |
3379 |
+ BTC_BCNT_INFOUPDATE, |
3380 |
+ BTC_BCNT_INFOSAME, |
3381 |
+ BTC_BCNT_SCBDUPDATE, |
3382 |
+ BTC_BCNT_HIPRI_TX, |
3383 |
+ BTC_BCNT_HIPRI_RX, |
3384 |
+ BTC_BCNT_LOPRI_TX, |
3385 |
+ BTC_BCNT_LOPRI_RX, |
3386 |
+ BTC_BCNT_RATECHG, |
3387 |
+ BTC_BCNT_NUM |
3388 |
+}; |
3389 |
+ |
3390 |
+enum rtw89_btc_bt_profile { |
3391 |
+ BTC_BT_NOPROFILE = 0, |
3392 |
+ BTC_BT_HFP = BIT(0), |
3393 |
+ BTC_BT_HID = BIT(1), |
3394 |
+ BTC_BT_A2DP = BIT(2), |
3395 |
+ BTC_BT_PAN = BIT(3), |
3396 |
+ BTC_PROFILE_MAX = 4, |
3397 |
+}; |
3398 |
+ |
3399 |
+struct rtw89_btc_ant_info { |
3400 |
+ u8 type; /* shared, dedicated */ |
3401 |
+ u8 num; |
3402 |
+ u8 isolation; |
3403 |
+ |
3404 |
+ u8 single_pos: 1;/* Single antenna at S0 or S1 */ |
3405 |
+ u8 diversity: 1; |
3406 |
+}; |
3407 |
+ |
3408 |
+enum rtw89_tfc_dir { |
3409 |
+ RTW89_TFC_UL, |
3410 |
+ RTW89_TFC_DL, |
3411 |
+}; |
3412 |
+ |
3413 |
+struct rtw89_btc_wl_smap { |
3414 |
+ u32 busy: 1; |
3415 |
+ u32 scan: 1; |
3416 |
+ u32 connecting: 1; |
3417 |
+ u32 roaming: 1; |
3418 |
+ u32 _4way: 1; |
3419 |
+ u32 rf_off: 1; |
3420 |
+ u32 lps: 1; |
3421 |
+ u32 ips: 1; |
3422 |
+ u32 init_ok: 1; |
3423 |
+ u32 traffic_dir : 2; |
3424 |
+ u32 rf_off_pre: 1; |
3425 |
+ u32 lps_pre: 1; |
3426 |
+}; |
3427 |
+ |
3428 |
+enum rtw89_tfc_lv { |
3429 |
+ RTW89_TFC_IDLE, |
3430 |
+ RTW89_TFC_ULTRA_LOW, |
3431 |
+ RTW89_TFC_LOW, |
3432 |
+ RTW89_TFC_MID, |
3433 |
+ RTW89_TFC_HIGH, |
3434 |
+}; |
3435 |
+ |
3436 |
+#define RTW89_TP_SHIFT 18 /* bytes/2s --> Mbps */ |
3437 |
+DECLARE_EWMA(tp, 10, 2); |
3438 |
+ |
3439 |
+struct rtw89_traffic_stats { |
3440 |
+ /* units in bytes */ |
3441 |
+ u64 tx_unicast; |
3442 |
+ u64 rx_unicast; |
3443 |
+ u32 tx_avg_len; |
3444 |
+ u32 rx_avg_len; |
3445 |
+ |
3446 |
+ /* count for packets */ |
3447 |
+ u64 tx_cnt; |
3448 |
+ u64 rx_cnt; |
3449 |
+ |
3450 |
+ /* units in Mbps */ |
3451 |
+ u32 tx_throughput; |
3452 |
+ u32 rx_throughput; |
3453 |
+ u32 tx_throughput_raw; |
3454 |
+ u32 rx_throughput_raw; |
3455 |
+ enum rtw89_tfc_lv tx_tfc_lv; |
3456 |
+ enum rtw89_tfc_lv rx_tfc_lv; |
3457 |
+ struct ewma_tp tx_ewma_tp; |
3458 |
+ struct ewma_tp rx_ewma_tp; |
3459 |
+ |
3460 |
+ u16 tx_rate; |
3461 |
+ u16 rx_rate; |
3462 |
+}; |
3463 |
+ |
3464 |
+struct rtw89_btc_statistic { |
3465 |
+ u8 rssi; /* 0%~110% (dBm = rssi -110) */ |
3466 |
+ struct rtw89_traffic_stats traffic; |
3467 |
+}; |
3468 |
+ |
3469 |
+#define BTC_WL_RSSI_THMAX 4 |
3470 |
+ |
3471 |
+struct rtw89_btc_wl_link_info { |
3472 |
+ struct rtw89_btc_statistic stat; |
3473 |
+ enum rtw89_tfc_dir dir; |
3474 |
+ u8 rssi_state[BTC_WL_RSSI_THMAX]; |
3475 |
+ u8 mac_addr[ETH_ALEN]; |
3476 |
+ u8 busy; |
3477 |
+ u8 ch; |
3478 |
+ u8 bw; |
3479 |
+ u8 band; |
3480 |
+ u8 role; |
3481 |
+ u8 pid; |
3482 |
+ u8 phy; |
3483 |
+ u8 dtim_period; |
3484 |
+ u8 mode; |
3485 |
+ |
3486 |
+ u8 mac_id; |
3487 |
+ u8 tx_retry; |
3488 |
+ |
3489 |
+ u32 bcn_period; |
3490 |
+ u32 busy_t; |
3491 |
+ u32 tx_time; |
3492 |
+ u32 client_cnt; |
3493 |
+ u32 rx_rate_drop_cnt; |
3494 |
+ |
3495 |
+ u32 active: 1; |
3496 |
+ u32 noa: 1; |
3497 |
+ u32 client_ps: 1; |
3498 |
+ u32 connected: 2; |
3499 |
+}; |
3500 |
+ |
3501 |
+union rtw89_btc_wl_state_map { |
3502 |
+ u32 val; |
3503 |
+ struct rtw89_btc_wl_smap map; |
3504 |
+}; |
3505 |
+ |
3506 |
+struct rtw89_btc_bt_hfp_desc { |
3507 |
+ u32 exist: 1; |
3508 |
+ u32 type: 2; |
3509 |
+ u32 rsvd: 29; |
3510 |
+}; |
3511 |
+ |
3512 |
+struct rtw89_btc_bt_hid_desc { |
3513 |
+ u32 exist: 1; |
3514 |
+ u32 slot_info: 2; |
3515 |
+ u32 pair_cnt: 2; |
3516 |
+ u32 type: 8; |
3517 |
+ u32 rsvd: 19; |
3518 |
+}; |
3519 |
+ |
3520 |
+struct rtw89_btc_bt_a2dp_desc { |
3521 |
+ u8 exist: 1; |
3522 |
+ u8 exist_last: 1; |
3523 |
+ u8 play_latency: 1; |
3524 |
+ u8 type: 3; |
3525 |
+ u8 active: 1; |
3526 |
+ u8 sink: 1; |
3527 |
+ |
3528 |
+ u8 bitpool; |
3529 |
+ u16 vendor_id; |
3530 |
+ u32 device_name; |
3531 |
+ u32 flush_time; |
3532 |
+}; |
3533 |
+ |
3534 |
+struct rtw89_btc_bt_pan_desc { |
3535 |
+ u32 exist: 1; |
3536 |
+ u32 type: 1; |
3537 |
+ u32 active: 1; |
3538 |
+ u32 rsvd: 29; |
3539 |
+}; |
3540 |
+ |
3541 |
+struct rtw89_btc_bt_rfk_info { |
3542 |
+ u32 run: 1; |
3543 |
+ u32 req: 1; |
3544 |
+ u32 timeout: 1; |
3545 |
+ u32 rsvd: 29; |
3546 |
+}; |
3547 |
+ |
3548 |
+union rtw89_btc_bt_rfk_info_map { |
3549 |
+ u32 val; |
3550 |
+ struct rtw89_btc_bt_rfk_info map; |
3551 |
+}; |
3552 |
+ |
3553 |
+struct rtw89_btc_bt_ver_info { |
3554 |
+ u32 fw_coex; /* match with which coex_ver */ |
3555 |
+ u32 fw; |
3556 |
+}; |
3557 |
+ |
3558 |
+struct rtw89_btc_bool_sta_chg { |
3559 |
+ u32 now: 1; |
3560 |
+ u32 last: 1; |
3561 |
+ u32 remain: 1; |
3562 |
+ u32 srvd: 29; |
3563 |
+}; |
3564 |
+ |
3565 |
+struct rtw89_btc_u8_sta_chg { |
3566 |
+ u8 now; |
3567 |
+ u8 last; |
3568 |
+ u8 remain; |
3569 |
+ u8 rsvd; |
3570 |
+}; |
3571 |
+ |
3572 |
+struct rtw89_btc_wl_scan_info { |
3573 |
+ u8 band[RTW89_PHY_MAX]; |
3574 |
+ u8 phy_map; |
3575 |
+ u8 rsvd; |
3576 |
+}; |
3577 |
+ |
3578 |
+struct rtw89_btc_wl_dbcc_info { |
3579 |
+ u8 op_band[RTW89_PHY_MAX]; /* op band in each phy */ |
3580 |
+ u8 scan_band[RTW89_PHY_MAX]; /* scan band in each phy */ |
3581 |
+ u8 real_band[RTW89_PHY_MAX]; |
3582 |
+ u8 role[RTW89_PHY_MAX]; /* role in each phy */ |
3583 |
+}; |
3584 |
+ |
3585 |
+struct rtw89_btc_wl_active_role { |
3586 |
+ u8 connected: 1; |
3587 |
+ u8 pid: 3; |
3588 |
+ u8 phy: 1; |
3589 |
+ u8 noa: 1; |
3590 |
+ u8 band: 2; |
3591 |
+ |
3592 |
+ u8 client_ps: 1; |
3593 |
+ u8 bw: 7; |
3594 |
+ |
3595 |
+ u8 role; |
3596 |
+ u8 ch; |
3597 |
+ |
3598 |
+ u16 tx_lvl; |
3599 |
+ u16 rx_lvl; |
3600 |
+ u16 tx_rate; |
3601 |
+ u16 rx_rate; |
3602 |
+}; |
3603 |
+ |
3604 |
+struct rtw89_btc_wl_role_info_bpos { |
3605 |
+ u16 none: 1; |
3606 |
+ u16 station: 1; |
3607 |
+ u16 ap: 1; |
3608 |
+ u16 vap: 1; |
3609 |
+ u16 adhoc: 1; |
3610 |
+ u16 adhoc_master: 1; |
3611 |
+ u16 mesh: 1; |
3612 |
+ u16 moniter: 1; |
3613 |
+ u16 p2p_device: 1; |
3614 |
+ u16 p2p_gc: 1; |
3615 |
+ u16 p2p_go: 1; |
3616 |
+ u16 nan: 1; |
3617 |
+}; |
3618 |
+ |
3619 |
+union rtw89_btc_wl_role_info_map { |
3620 |
+ u16 val; |
3621 |
+ struct rtw89_btc_wl_role_info_bpos role; |
3622 |
+}; |
3623 |
+ |
3624 |
+struct rtw89_btc_wl_role_info { /* struct size must be n*4 bytes */ |
3625 |
+ u8 connect_cnt; |
3626 |
+ u8 link_mode; |
3627 |
+ union rtw89_btc_wl_role_info_map role_map; |
3628 |
+ struct rtw89_btc_wl_active_role active_role[RTW89_MAX_HW_PORT_NUM]; |
3629 |
+}; |
3630 |
+ |
3631 |
+struct rtw89_btc_wl_ver_info { |
3632 |
+ u32 fw_coex; /* match with which coex_ver */ |
3633 |
+ u32 fw; |
3634 |
+ u32 mac; |
3635 |
+ u32 bb; |
3636 |
+ u32 rf; |
3637 |
+}; |
3638 |
+ |
3639 |
+struct rtw89_btc_wl_afh_info { |
3640 |
+ u8 en; |
3641 |
+ u8 ch; |
3642 |
+ u8 bw; |
3643 |
+ u8 rsvd; |
3644 |
+} __packed; |
3645 |
+ |
3646 |
+struct rtw89_btc_wl_rfk_info { |
3647 |
+ u32 state: 2; |
3648 |
+ u32 path_map: 4; |
3649 |
+ u32 phy_map: 2; |
3650 |
+ u32 band: 2; |
3651 |
+ u32 type: 8; |
3652 |
+ u32 rsvd: 14; |
3653 |
+}; |
3654 |
+ |
3655 |
+struct rtw89_btc_bt_smap { |
3656 |
+ u32 connect: 1; |
3657 |
+ u32 ble_connect: 1; |
3658 |
+ u32 acl_busy: 1; |
3659 |
+ u32 sco_busy: 1; |
3660 |
+ u32 mesh_busy: 1; |
3661 |
+ u32 inq_pag: 1; |
3662 |
+}; |
3663 |
+ |
3664 |
+union rtw89_btc_bt_state_map { |
3665 |
+ u32 val; |
3666 |
+ struct rtw89_btc_bt_smap map; |
3667 |
+}; |
3668 |
+ |
3669 |
+#define BTC_BT_RSSI_THMAX 4 |
3670 |
+#define BTC_BT_AFH_GROUP 12 |
3671 |
+ |
3672 |
+struct rtw89_btc_bt_link_info { |
3673 |
+ struct rtw89_btc_u8_sta_chg profile_cnt; |
3674 |
+ struct rtw89_btc_bool_sta_chg multi_link; |
3675 |
+ struct rtw89_btc_bool_sta_chg relink; |
3676 |
+ struct rtw89_btc_bt_hfp_desc hfp_desc; |
3677 |
+ struct rtw89_btc_bt_hid_desc hid_desc; |
3678 |
+ struct rtw89_btc_bt_a2dp_desc a2dp_desc; |
3679 |
+ struct rtw89_btc_bt_pan_desc pan_desc; |
3680 |
+ union rtw89_btc_bt_state_map status; |
3681 |
+ |
3682 |
+ u8 sut_pwr_level[BTC_PROFILE_MAX]; |
3683 |
+ u8 golden_rx_shift[BTC_PROFILE_MAX]; |
3684 |
+ u8 rssi_state[BTC_BT_RSSI_THMAX]; |
3685 |
+ u8 afh_map[BTC_BT_AFH_GROUP]; |
3686 |
+ |
3687 |
+ u32 role_sw: 1; |
3688 |
+ u32 slave_role: 1; |
3689 |
+ u32 afh_update: 1; |
3690 |
+ u32 cqddr: 1; |
3691 |
+ u32 rssi: 8; |
3692 |
+ u32 tx_3m: 1; |
3693 |
+ u32 rsvd: 19; |
3694 |
+}; |
3695 |
+ |
3696 |
+struct rtw89_btc_3rdcx_info { |
3697 |
+ u8 type; /* 0: none, 1:zigbee, 2:LTE */ |
3698 |
+ u8 hw_coex; |
3699 |
+ u16 rsvd; |
3700 |
+}; |
3701 |
+ |
3702 |
+struct rtw89_btc_dm_emap { |
3703 |
+ u32 init: 1; |
3704 |
+ u32 pta_owner: 1; |
3705 |
+ u32 wl_rfk_timeout: 1; |
3706 |
+ u32 bt_rfk_timeout: 1; |
3707 |
+ |
3708 |
+ u32 wl_fw_hang: 1; |
3709 |
+ u32 offload_mismatch: 1; |
3710 |
+ u32 cycle_hang: 1; |
3711 |
+ u32 w1_hang: 1; |
3712 |
+ |
3713 |
+ u32 b1_hang: 1; |
3714 |
+ u32 tdma_no_sync: 1; |
3715 |
+ u32 wl_slot_drift: 1; |
3716 |
+}; |
3717 |
+ |
3718 |
+union rtw89_btc_dm_error_map { |
3719 |
+ u32 val; |
3720 |
+ struct rtw89_btc_dm_emap map; |
3721 |
+}; |
3722 |
+ |
3723 |
+struct rtw89_btc_rf_para { |
3724 |
+ u32 tx_pwr_freerun; |
3725 |
+ u32 rx_gain_freerun; |
3726 |
+ u32 tx_pwr_perpkt; |
3727 |
+ u32 rx_gain_perpkt; |
3728 |
+}; |
3729 |
+ |
3730 |
+struct rtw89_btc_wl_info { |
3731 |
+ struct rtw89_btc_wl_link_info link_info[RTW89_MAX_HW_PORT_NUM]; |
3732 |
+ struct rtw89_btc_wl_rfk_info rfk_info; |
3733 |
+ struct rtw89_btc_wl_ver_info ver_info; |
3734 |
+ struct rtw89_btc_wl_afh_info afh_info; |
3735 |
+ struct rtw89_btc_wl_role_info role_info; |
3736 |
+ struct rtw89_btc_wl_scan_info scan_info; |
3737 |
+ struct rtw89_btc_wl_dbcc_info dbcc_info; |
3738 |
+ struct rtw89_btc_rf_para rf_para; |
3739 |
+ union rtw89_btc_wl_state_map status; |
3740 |
+ |
3741 |
+ u8 port_id[RTW89_WIFI_ROLE_MLME_MAX]; |
3742 |
+ u8 rssi_level; |
3743 |
+ |
3744 |
+ u32 scbd; |
3745 |
+}; |
3746 |
+ |
3747 |
+struct rtw89_btc_module { |
3748 |
+ struct rtw89_btc_ant_info ant; |
3749 |
+ u8 rfe_type; |
3750 |
+ u8 cv; |
3751 |
+ |
3752 |
+ u8 bt_solo: 1; |
3753 |
+ u8 bt_pos: 1; |
3754 |
+ u8 switch_type: 1; |
3755 |
+ |
3756 |
+ u8 rsvd; |
3757 |
+}; |
3758 |
+ |
3759 |
+#define RTW89_BTC_DM_MAXSTEP 30 |
3760 |
+#define RTW89_BTC_DM_CNT_MAX (RTW89_BTC_DM_MAXSTEP * 8) |
3761 |
+ |
3762 |
+struct rtw89_btc_dm_step { |
3763 |
+ u16 step[RTW89_BTC_DM_MAXSTEP]; |
3764 |
+ u8 step_pos; |
3765 |
+ bool step_ov; |
3766 |
+}; |
3767 |
+ |
3768 |
+struct rtw89_btc_init_info { |
3769 |
+ struct rtw89_btc_module module; |
3770 |
+ u8 wl_guard_ch; |
3771 |
+ |
3772 |
+ u8 wl_only: 1; |
3773 |
+ u8 wl_init_ok: 1; |
3774 |
+ u8 dbcc_en: 1; |
3775 |
+ u8 cx_other: 1; |
3776 |
+ u8 bt_only: 1; |
3777 |
+ |
3778 |
+ u16 rsvd; |
3779 |
+}; |
3780 |
+ |
3781 |
+struct rtw89_btc_wl_tx_limit_para { |
3782 |
+ u16 enable; |
3783 |
+ u32 tx_time; /* unit: us */ |
3784 |
+ u16 tx_retry; |
3785 |
+}; |
3786 |
+ |
3787 |
+struct rtw89_btc_bt_scan_info { |
3788 |
+ u16 win; |
3789 |
+ u16 intvl; |
3790 |
+ u32 enable: 1; |
3791 |
+ u32 interlace: 1; |
3792 |
+ u32 rsvd: 30; |
3793 |
+}; |
3794 |
+ |
3795 |
+enum rtw89_btc_bt_scan_type { |
3796 |
+ BTC_SCAN_INQ = 0, |
3797 |
+ BTC_SCAN_PAGE, |
3798 |
+ BTC_SCAN_BLE, |
3799 |
+ BTC_SCAN_INIT, |
3800 |
+ BTC_SCAN_TV, |
3801 |
+ BTC_SCAN_ADV, |
3802 |
+ BTC_SCAN_MAX1, |
3803 |
+}; |
3804 |
+ |
3805 |
+struct rtw89_btc_bt_info { |
3806 |
+ struct rtw89_btc_bt_link_info link_info; |
3807 |
+ struct rtw89_btc_bt_scan_info scan_info[BTC_SCAN_MAX1]; |
3808 |
+ struct rtw89_btc_bt_ver_info ver_info; |
3809 |
+ struct rtw89_btc_bool_sta_chg enable; |
3810 |
+ struct rtw89_btc_bool_sta_chg inq_pag; |
3811 |
+ struct rtw89_btc_rf_para rf_para; |
3812 |
+ union rtw89_btc_bt_rfk_info_map rfk_info; |
3813 |
+ |
3814 |
+ u8 raw_info[BTC_BTINFO_MAX]; /* raw bt info from mailbox */ |
3815 |
+ |
3816 |
+ u32 scbd; |
3817 |
+ u32 feature; |
3818 |
+ |
3819 |
+ u32 mbx_avl: 1; |
3820 |
+ u32 whql_test: 1; |
3821 |
+ u32 igno_wl: 1; |
3822 |
+ u32 reinit: 1; |
3823 |
+ u32 ble_scan_en: 1; |
3824 |
+ u32 btg_type: 1; |
3825 |
+ u32 inq: 1; |
3826 |
+ u32 pag: 1; |
3827 |
+ u32 run_patch_code: 1; |
3828 |
+ u32 hi_lna_rx: 1; |
3829 |
+ u32 rsvd: 22; |
3830 |
+}; |
3831 |
+ |
3832 |
+struct rtw89_btc_cx { |
3833 |
+ struct rtw89_btc_wl_info wl; |
3834 |
+ struct rtw89_btc_bt_info bt; |
3835 |
+ struct rtw89_btc_3rdcx_info other; |
3836 |
+ u32 state_map; |
3837 |
+ u32 cnt_bt[BTC_BCNT_NUM]; |
3838 |
+ u32 cnt_wl[BTC_WCNT_NUM]; |
3839 |
+}; |
3840 |
+ |
3841 |
+struct rtw89_btc_fbtc_tdma { |
3842 |
+ u8 type; |
3843 |
+ u8 rxflctrl; |
3844 |
+ u8 txpause; |
3845 |
+ u8 wtgle_n; |
3846 |
+ u8 leak_n; |
3847 |
+ u8 ext_ctrl; |
3848 |
+ u8 rsvd0; |
3849 |
+ u8 rsvd1; |
3850 |
+} __packed; |
3851 |
+ |
3852 |
+#define CXMREG_MAX 30 |
3853 |
+#define FCXMAX_STEP 255 /*STEP trace record cnt, Max:65535, default:255*/ |
3854 |
+#define BTCRPT_VER 1 |
3855 |
+#define BTC_CYCLE_SLOT_MAX 48 /* must be even number, non-zero */ |
3856 |
+ |
3857 |
+enum rtw89_btc_bt_rfk_counter { |
3858 |
+ BTC_BCNT_RFK_REQ = 0, |
3859 |
+ BTC_BCNT_RFK_GO = 1, |
3860 |
+ BTC_BCNT_RFK_REJECT = 2, |
3861 |
+ BTC_BCNT_RFK_FAIL = 3, |
3862 |
+ BTC_BCNT_RFK_TIMEOUT = 4, |
3863 |
+ BTC_BCNT_RFK_MAX |
3864 |
+}; |
3865 |
+ |
3866 |
+struct rtw89_btc_fbtc_rpt_ctrl { |
3867 |
+ u16 fver; |
3868 |
+ u16 rpt_cnt; /* tmr counters */ |
3869 |
+ u32 wl_fw_coex_ver; /* match which driver's coex version */ |
3870 |
+ u32 wl_fw_cx_offload; |
3871 |
+ u32 wl_fw_ver; |
3872 |
+ u32 rpt_enable; |
3873 |
+ u32 rpt_para; /* ms */ |
3874 |
+ u32 mb_send_fail_cnt; /* fw send mailbox fail counter */ |
3875 |
+ u32 mb_send_ok_cnt; /* fw send mailbox ok counter */ |
3876 |
+ u32 mb_recv_cnt; /* fw recv mailbox counter */ |
3877 |
+ u32 mb_a2dp_empty_cnt; /* a2dp empty count */ |
3878 |
+ u32 mb_a2dp_flct_cnt; /* a2dp empty flow control counter */ |
3879 |
+ u32 mb_a2dp_full_cnt; /* a2dp empty full counter */ |
3880 |
+ u32 bt_rfk_cnt[BTC_BCNT_RFK_MAX]; |
3881 |
+ u32 c2h_cnt; /* fw send c2h counter */ |
3882 |
+ u32 h2c_cnt; /* fw recv h2c counter */ |
3883 |
+} __packed; |
3884 |
+ |
3885 |
+enum rtw89_fbtc_ext_ctrl_type { |
3886 |
+ CXECTL_OFF = 0x0, /* tdma off */ |
3887 |
+ CXECTL_B2 = 0x1, /* allow B2 (beacon-early) */ |
3888 |
+ CXECTL_EXT = 0x2, |
3889 |
+ CXECTL_MAX |
3890 |
+}; |
3891 |
+ |
3892 |
+union rtw89_btc_fbtc_rxflct { |
3893 |
+ u8 val; |
3894 |
+ u8 type: 3; |
3895 |
+ u8 tgln_n: 5; |
3896 |
+}; |
3897 |
+ |
3898 |
+enum rtw89_btc_cxst_state { |
3899 |
+ CXST_OFF = 0x0, |
3900 |
+ CXST_B2W = 0x1, |
3901 |
+ CXST_W1 = 0x2, |
3902 |
+ CXST_W2 = 0x3, |
3903 |
+ CXST_W2B = 0x4, |
3904 |
+ CXST_B1 = 0x5, |
3905 |
+ CXST_B2 = 0x6, |
3906 |
+ CXST_B3 = 0x7, |
3907 |
+ CXST_B4 = 0x8, |
3908 |
+ CXST_LK = 0x9, |
3909 |
+ CXST_BLK = 0xa, |
3910 |
+ CXST_E2G = 0xb, |
3911 |
+ CXST_E5G = 0xc, |
3912 |
+ CXST_EBT = 0xd, |
3913 |
+ CXST_ENULL = 0xe, |
3914 |
+ CXST_WLK = 0xf, |
3915 |
+ CXST_W1FDD = 0x10, |
3916 |
+ CXST_B1FDD = 0x11, |
3917 |
+ CXST_MAX = 0x12, |
3918 |
+}; |
3919 |
+ |
3920 |
+enum { |
3921 |
+ CXBCN_ALL = 0x0, |
3922 |
+ CXBCN_ALL_OK, |
3923 |
+ CXBCN_BT_SLOT, |
3924 |
+ CXBCN_BT_OK, |
3925 |
+ CXBCN_MAX |
3926 |
+}; |
3927 |
+ |
3928 |
+enum btc_slot_type { |
3929 |
+ SLOT_MIX = 0x0, /* accept BT Lower-Pri Tx/Rx request 0x778 = 1 */ |
3930 |
+ SLOT_ISO = 0x1, /* no accept BT Lower-Pri Tx/Rx request 0x778 = d*/ |
3931 |
+ CXSTYPE_NUM, |
3932 |
+}; |
3933 |
+ |
3934 |
+enum { /* TIME */ |
3935 |
+ CXT_BT = 0x0, |
3936 |
+ CXT_WL = 0x1, |
3937 |
+ CXT_MAX |
3938 |
+}; |
3939 |
+ |
3940 |
+enum { /* TIME-A2DP */ |
3941 |
+ CXT_FLCTRL_OFF = 0x0, |
3942 |
+ CXT_FLCTRL_ON = 0x1, |
3943 |
+ CXT_FLCTRL_MAX |
3944 |
+}; |
3945 |
+ |
3946 |
+enum { /* STEP TYPE */ |
3947 |
+ CXSTEP_NONE = 0x0, |
3948 |
+ CXSTEP_EVNT = 0x1, |
3949 |
+ CXSTEP_SLOT = 0x2, |
3950 |
+ CXSTEP_MAX, |
3951 |
+}; |
3952 |
+ |
3953 |
+#define FCXGPIODBG_VER 1 |
3954 |
+#define BTC_DBG_MAX1 32 |
3955 |
+struct rtw89_btc_fbtc_gpio_dbg { |
3956 |
+ u8 fver; |
3957 |
+ u8 rsvd; |
3958 |
+ u16 rsvd2; |
3959 |
+ u32 en_map; /* which debug signal (see btc_wl_gpio_debug) is enable */ |
3960 |
+ u32 pre_state; /* the debug signal is 1 or 0 */ |
3961 |
+ u8 gpio_map[BTC_DBG_MAX1]; /*the debug signals to GPIO-Position */ |
3962 |
+} __packed; |
3963 |
+ |
3964 |
+#define FCXMREG_VER 1 |
3965 |
+struct rtw89_btc_fbtc_mreg_val { |
3966 |
+ u8 fver; |
3967 |
+ u8 reg_num; |
3968 |
+ __le16 rsvd; |
3969 |
+ __le32 mreg_val[CXMREG_MAX]; |
3970 |
+} __packed; |
3971 |
+ |
3972 |
+#define RTW89_DEF_FBTC_MREG(__type, __bytes, __offset) \ |
3973 |
+ { .type = cpu_to_le16(__type), .bytes = cpu_to_le16(__bytes), \ |
3974 |
+ .offset = cpu_to_le32(__offset), } |
3975 |
+ |
3976 |
+struct rtw89_btc_fbtc_mreg { |
3977 |
+ __le16 type; |
3978 |
+ __le16 bytes; |
3979 |
+ __le32 offset; |
3980 |
+} __packed; |
3981 |
+ |
3982 |
+struct rtw89_btc_fbtc_slot { |
3983 |
+ __le16 dur; |
3984 |
+ __le32 cxtbl; |
3985 |
+ __le16 cxtype; |
3986 |
+} __packed; |
3987 |
+ |
3988 |
+#define FCXSLOTS_VER 1 |
3989 |
+struct rtw89_btc_fbtc_slots { |
3990 |
+ u8 fver; |
3991 |
+ u8 tbl_num; |
3992 |
+ __le16 rsvd; |
3993 |
+ __le32 update_map; |
3994 |
+ struct rtw89_btc_fbtc_slot slot[CXST_MAX]; |
3995 |
+} __packed; |
3996 |
+ |
3997 |
+#define FCXSTEP_VER 2 |
3998 |
+struct rtw89_btc_fbtc_step { |
3999 |
+ u8 type; |
4000 |
+ u8 val; |
4001 |
+ __le16 difft; |
4002 |
+} __packed; |
4003 |
+ |
4004 |
+struct rtw89_btc_fbtc_steps { |
4005 |
+ u8 fver; |
4006 |
+ u8 rsvd; |
4007 |
+ __le16 cnt; |
4008 |
+ __le16 pos_old; |
4009 |
+ __le16 pos_new; |
4010 |
+ struct rtw89_btc_fbtc_step step[FCXMAX_STEP]; |
4011 |
+} __packed; |
4012 |
+ |
4013 |
+#define FCXCYSTA_VER 2 |
4014 |
+struct rtw89_btc_fbtc_cysta { /* statistics for cycles */ |
4015 |
+ u8 fver; |
4016 |
+ u8 rsvd; |
4017 |
+ __le16 cycles; /* total cycle number */ |
4018 |
+ __le16 cycles_a2dp[CXT_FLCTRL_MAX]; |
4019 |
+ __le16 a2dpept; /* a2dp empty cnt */ |
4020 |
+ __le16 a2dpeptto; /* a2dp empty timeout cnt*/ |
4021 |
+ __le16 tavg_cycle[CXT_MAX]; /* avg wl/bt cycle time */ |
4022 |
+ __le16 tmax_cycle[CXT_MAX]; /* max wl/bt cycle time */ |
4023 |
+ __le16 tmaxdiff_cycle[CXT_MAX]; /* max wl-wl bt-bt cycle diff time */ |
4024 |
+ __le16 tavg_a2dp[CXT_FLCTRL_MAX]; /* avg a2dp PSTDMA/TDMA time */ |
4025 |
+ __le16 tmax_a2dp[CXT_FLCTRL_MAX]; /* max a2dp PSTDMA/TDMA time */ |
4026 |
+ __le16 tavg_a2dpept; /* avg a2dp empty time */ |
4027 |
+ __le16 tmax_a2dpept; /* max a2dp empty time */ |
4028 |
+ __le16 tavg_lk; /* avg leak-slot time */ |
4029 |
+ __le16 tmax_lk; /* max leak-slot time */ |
4030 |
+ __le32 slot_cnt[CXST_MAX]; /* slot count */ |
4031 |
+ __le32 bcn_cnt[CXBCN_MAX]; |
4032 |
+ __le32 leakrx_cnt; /* the rximr occur at leak slot */ |
4033 |
+ __le32 collision_cnt; /* counter for event/timer occur at same time */ |
4034 |
+ __le32 skip_cnt; |
4035 |
+ __le32 exception; |
4036 |
+ __le32 except_cnt; |
4037 |
+ __le16 tslot_cycle[BTC_CYCLE_SLOT_MAX]; |
4038 |
+} __packed; |
4039 |
+ |
4040 |
+#define FCXNULLSTA_VER 1 |
4041 |
+struct rtw89_btc_fbtc_cynullsta { /* cycle null statistics */ |
4042 |
+ u8 fver; |
4043 |
+ u8 rsvd; |
4044 |
+ __le16 rsvd2; |
4045 |
+ __le32 max_t[2]; /* max_t for 0:null0/1:null1 */ |
4046 |
+ __le32 avg_t[2]; /* avg_t for 0:null0/1:null1 */ |
4047 |
+ __le32 result[2][4]; /* 0:fail, 1:ok, 2:on_time, 3:retry */ |
4048 |
+} __packed; |
4049 |
+ |
4050 |
+#define FCX_BTVER_VER 1 |
4051 |
+struct rtw89_btc_fbtc_btver { |
4052 |
+ u8 fver; |
4053 |
+ u8 rsvd; |
4054 |
+ __le16 rsvd2; |
4055 |
+ __le32 coex_ver; /*bit[15:8]->shared, bit[7:0]->non-shared */ |
4056 |
+ __le32 fw_ver; |
4057 |
+ __le32 feature; |
4058 |
+} __packed; |
4059 |
+ |
4060 |
+#define FCX_BTSCAN_VER 1 |
4061 |
+struct rtw89_btc_fbtc_btscan { |
4062 |
+ u8 fver; |
4063 |
+ u8 rsvd; |
4064 |
+ __le16 rsvd2; |
4065 |
+ u8 scan[6]; |
4066 |
+} __packed; |
4067 |
+ |
4068 |
+#define FCX_BTAFH_VER 1 |
4069 |
+struct rtw89_btc_fbtc_btafh { |
4070 |
+ u8 fver; |
4071 |
+ u8 rsvd; |
4072 |
+ __le16 rsvd2; |
4073 |
+ u8 afh_l[4]; /*bit0:2402, bit1: 2403.... bit31:2433 */ |
4074 |
+ u8 afh_m[4]; /*bit0:2434, bit1: 2435.... bit31:2465 */ |
4075 |
+ u8 afh_h[4]; /*bit0:2466, bit1:2467......bit14:2480 */ |
4076 |
+} __packed; |
4077 |
+ |
4078 |
+#define FCX_BTDEVINFO_VER 1 |
4079 |
+struct rtw89_btc_fbtc_btdevinfo { |
4080 |
+ u8 fver; |
4081 |
+ u8 rsvd; |
4082 |
+ __le16 vendor_id; |
4083 |
+ __le32 dev_name; /* only 24 bits valid */ |
4084 |
+ __le32 flush_time; |
4085 |
+} __packed; |
4086 |
+ |
4087 |
+#define RTW89_BTC_WL_DEF_TX_PWR GENMASK(7, 0) |
4088 |
+struct rtw89_btc_rf_trx_para { |
4089 |
+ u32 wl_tx_power; /* absolute Tx power (dBm), 0xff-> no BTC control */ |
4090 |
+ u32 wl_rx_gain; /* rx gain table index (TBD.) */ |
4091 |
+ u8 bt_tx_power; /* decrease Tx power (dB) */ |
4092 |
+ u8 bt_rx_gain; /* LNA constrain level */ |
4093 |
+}; |
4094 |
+ |
4095 |
+struct rtw89_btc_dm { |
4096 |
+ struct rtw89_btc_fbtc_slot slot[CXST_MAX]; |
4097 |
+ struct rtw89_btc_fbtc_slot slot_now[CXST_MAX]; |
4098 |
+ struct rtw89_btc_fbtc_tdma tdma; |
4099 |
+ struct rtw89_btc_fbtc_tdma tdma_now; |
4100 |
+ struct rtw89_mac_ax_coex_gnt gnt; |
4101 |
+ struct rtw89_btc_init_info init_info; /* pass to wl_fw if offload */ |
4102 |
+ struct rtw89_btc_rf_trx_para rf_trx_para; |
4103 |
+ struct rtw89_btc_wl_tx_limit_para wl_tx_limit; |
4104 |
+ struct rtw89_btc_dm_step dm_step; |
4105 |
+ union rtw89_btc_dm_error_map error; |
4106 |
+ u32 cnt_dm[BTC_DCNT_NUM]; |
4107 |
+ u32 cnt_notify[BTC_NCNT_NUM]; |
4108 |
+ |
4109 |
+ u32 update_slot_map; |
4110 |
+ u32 set_ant_path; |
4111 |
+ |
4112 |
+ u32 wl_only: 1; |
4113 |
+ u32 wl_fw_cx_offload: 1; |
4114 |
+ u32 freerun: 1; |
4115 |
+ u32 wl_ps_ctrl: 2; |
4116 |
+ u32 wl_mimo_ps: 1; |
4117 |
+ u32 leak_ap: 1; |
4118 |
+ u32 noisy_level: 3; |
4119 |
+ u32 coex_info_map: 8; |
4120 |
+ u32 bt_only: 1; |
4121 |
+ u32 wl_btg_rx: 1; |
4122 |
+ u32 trx_para_level: 8; |
4123 |
+ u32 wl_stb_chg: 1; |
4124 |
+ u32 rsvd: 3; |
4125 |
+ |
4126 |
+ u16 slot_dur[CXST_MAX]; |
4127 |
+ |
4128 |
+ u8 run_reason; |
4129 |
+ u8 run_action; |
4130 |
+}; |
4131 |
+ |
4132 |
+struct rtw89_btc_ctrl { |
4133 |
+ u32 manual: 1; |
4134 |
+ u32 igno_bt: 1; |
4135 |
+ u32 always_freerun: 1; |
4136 |
+ u32 trace_step: 16; |
4137 |
+ u32 rsvd: 12; |
4138 |
+}; |
4139 |
+ |
4140 |
+struct rtw89_btc_dbg { |
4141 |
+ /* cmd "rb" */ |
4142 |
+ bool rb_done; |
4143 |
+ u32 rb_val; |
4144 |
+}; |
4145 |
+ |
4146 |
+#define FCXTDMA_VER 1 |
4147 |
+ |
4148 |
+enum rtw89_btc_btf_fw_event { |
4149 |
+ BTF_EVNT_RPT = 0, |
4150 |
+ BTF_EVNT_BT_INFO = 1, |
4151 |
+ BTF_EVNT_BT_SCBD = 2, |
4152 |
+ BTF_EVNT_BT_REG = 3, |
4153 |
+ BTF_EVNT_CX_RUNINFO = 4, |
4154 |
+ BTF_EVNT_BT_PSD = 5, |
4155 |
+ BTF_EVNT_BUF_OVERFLOW, |
4156 |
+ BTF_EVNT_C2H_LOOPBACK, |
4157 |
+ BTF_EVNT_MAX, |
4158 |
+}; |
4159 |
+ |
4160 |
+enum btf_fw_event_report { |
4161 |
+ BTC_RPT_TYPE_CTRL = 0x0, |
4162 |
+ BTC_RPT_TYPE_TDMA, |
4163 |
+ BTC_RPT_TYPE_SLOT, |
4164 |
+ BTC_RPT_TYPE_CYSTA, |
4165 |
+ BTC_RPT_TYPE_STEP, |
4166 |
+ BTC_RPT_TYPE_NULLSTA, |
4167 |
+ BTC_RPT_TYPE_MREG, |
4168 |
+ BTC_RPT_TYPE_GPIO_DBG, |
4169 |
+ BTC_RPT_TYPE_BT_VER, |
4170 |
+ BTC_RPT_TYPE_BT_SCAN, |
4171 |
+ BTC_RPT_TYPE_BT_AFH, |
4172 |
+ BTC_RPT_TYPE_BT_DEVICE, |
4173 |
+ BTC_RPT_TYPE_TEST, |
4174 |
+ BTC_RPT_TYPE_MAX = 31 |
4175 |
+}; |
4176 |
+ |
4177 |
+enum rtw_btc_btf_reg_type { |
4178 |
+ REG_MAC = 0x0, |
4179 |
+ REG_BB = 0x1, |
4180 |
+ REG_RF = 0x2, |
4181 |
+ REG_BT_RF = 0x3, |
4182 |
+ REG_BT_MODEM = 0x4, |
4183 |
+ REG_BT_BLUEWIZE = 0x5, |
4184 |
+ REG_BT_VENDOR = 0x6, |
4185 |
+ REG_BT_LE = 0x7, |
4186 |
+ REG_MAX_TYPE, |
4187 |
+}; |
4188 |
+ |
4189 |
+struct rtw89_btc_rpt_cmn_info { |
4190 |
+ u32 rx_cnt; |
4191 |
+ u32 rx_len; |
4192 |
+ u32 req_len; /* expected rsp len */ |
4193 |
+ u8 req_fver; /* expected rsp fver */ |
4194 |
+ u8 rsp_fver; /* fver from fw */ |
4195 |
+ u8 valid; |
4196 |
+} __packed; |
4197 |
+ |
4198 |
+struct rtw89_btc_report_ctrl_state { |
4199 |
+ struct rtw89_btc_rpt_cmn_info cinfo; /* common info, by driver */ |
4200 |
+ struct rtw89_btc_fbtc_rpt_ctrl finfo; /* info from fw */ |
4201 |
+}; |
4202 |
+ |
4203 |
+struct rtw89_btc_rpt_fbtc_tdma { |
4204 |
+ struct rtw89_btc_rpt_cmn_info cinfo; /* common info, by driver */ |
4205 |
+ struct rtw89_btc_fbtc_tdma finfo; /* info from fw */ |
4206 |
+}; |
4207 |
+ |
4208 |
+struct rtw89_btc_rpt_fbtc_slots { |
4209 |
+ struct rtw89_btc_rpt_cmn_info cinfo; /* common info, by driver */ |
4210 |
+ struct rtw89_btc_fbtc_slots finfo; /* info from fw */ |
4211 |
+}; |
4212 |
+ |
4213 |
+struct rtw89_btc_rpt_fbtc_cysta { |
4214 |
+ struct rtw89_btc_rpt_cmn_info cinfo; /* common info, by driver */ |
4215 |
+ struct rtw89_btc_fbtc_cysta finfo; /* info from fw */ |
4216 |
+}; |
4217 |
+ |
4218 |
+struct rtw89_btc_rpt_fbtc_step { |
4219 |
+ struct rtw89_btc_rpt_cmn_info cinfo; /* common info, by driver */ |
4220 |
+ struct rtw89_btc_fbtc_steps finfo; /* info from fw */ |
4221 |
+}; |
4222 |
+ |
4223 |
+struct rtw89_btc_rpt_fbtc_nullsta { |
4224 |
+ struct rtw89_btc_rpt_cmn_info cinfo; /* common info, by driver */ |
4225 |
+ struct rtw89_btc_fbtc_cynullsta finfo; /* info from fw */ |
4226 |
+}; |
4227 |
+ |
4228 |
+struct rtw89_btc_rpt_fbtc_mreg { |
4229 |
+ struct rtw89_btc_rpt_cmn_info cinfo; /* common info, by driver */ |
4230 |
+ struct rtw89_btc_fbtc_mreg_val finfo; /* info from fw */ |
4231 |
+}; |
4232 |
+ |
4233 |
+struct rtw89_btc_rpt_fbtc_gpio_dbg { |
4234 |
+ struct rtw89_btc_rpt_cmn_info cinfo; /* common info, by driver */ |
4235 |
+ struct rtw89_btc_fbtc_gpio_dbg finfo; /* info from fw */ |
4236 |
+}; |
4237 |
+ |
4238 |
+struct rtw89_btc_rpt_fbtc_btver { |
4239 |
+ struct rtw89_btc_rpt_cmn_info cinfo; /* common info, by driver */ |
4240 |
+ struct rtw89_btc_fbtc_btver finfo; /* info from fw */ |
4241 |
+}; |
4242 |
+ |
4243 |
+struct rtw89_btc_rpt_fbtc_btscan { |
4244 |
+ struct rtw89_btc_rpt_cmn_info cinfo; /* common info, by driver */ |
4245 |
+ struct rtw89_btc_fbtc_btscan finfo; /* info from fw */ |
4246 |
+}; |
4247 |
+ |
4248 |
+struct rtw89_btc_rpt_fbtc_btafh { |
4249 |
+ struct rtw89_btc_rpt_cmn_info cinfo; /* common info, by driver */ |
4250 |
+ struct rtw89_btc_fbtc_btafh finfo; /* info from fw */ |
4251 |
+}; |
4252 |
+ |
4253 |
+struct rtw89_btc_rpt_fbtc_btdev { |
4254 |
+ struct rtw89_btc_rpt_cmn_info cinfo; /* common info, by driver */ |
4255 |
+ struct rtw89_btc_fbtc_btdevinfo finfo; /* info from fw */ |
4256 |
+}; |
4257 |
+ |
4258 |
+enum rtw89_btc_btfre_type { |
4259 |
+ BTFRE_INVALID_INPUT = 0x0, /* invalid input parameters */ |
4260 |
+ BTFRE_UNDEF_TYPE, |
4261 |
+ BTFRE_EXCEPTION, |
4262 |
+ BTFRE_MAX, |
4263 |
+}; |
4264 |
+ |
4265 |
+struct rtw89_btc_btf_fwinfo { |
4266 |
+ u32 cnt_c2h; |
4267 |
+ u32 cnt_h2c; |
4268 |
+ u32 cnt_h2c_fail; |
4269 |
+ u32 event[BTF_EVNT_MAX]; |
4270 |
+ |
4271 |
+ u32 err[BTFRE_MAX]; |
4272 |
+ u32 len_mismch; |
4273 |
+ u32 fver_mismch; |
4274 |
+ u32 rpt_en_map; |
4275 |
+ |
4276 |
+ struct rtw89_btc_report_ctrl_state rpt_ctrl; |
4277 |
+ struct rtw89_btc_rpt_fbtc_tdma rpt_fbtc_tdma; |
4278 |
+ struct rtw89_btc_rpt_fbtc_slots rpt_fbtc_slots; |
4279 |
+ struct rtw89_btc_rpt_fbtc_cysta rpt_fbtc_cysta; |
4280 |
+ struct rtw89_btc_rpt_fbtc_step rpt_fbtc_step; |
4281 |
+ struct rtw89_btc_rpt_fbtc_nullsta rpt_fbtc_nullsta; |
4282 |
+ struct rtw89_btc_rpt_fbtc_mreg rpt_fbtc_mregval; |
4283 |
+ struct rtw89_btc_rpt_fbtc_gpio_dbg rpt_fbtc_gpio_dbg; |
4284 |
+ struct rtw89_btc_rpt_fbtc_btver rpt_fbtc_btver; |
4285 |
+ struct rtw89_btc_rpt_fbtc_btscan rpt_fbtc_btscan; |
4286 |
+ struct rtw89_btc_rpt_fbtc_btafh rpt_fbtc_btafh; |
4287 |
+ struct rtw89_btc_rpt_fbtc_btdev rpt_fbtc_btdev; |
4288 |
+}; |
4289 |
+ |
4290 |
+#define RTW89_BTC_POLICY_MAXLEN 512 |
4291 |
+ |
4292 |
+struct rtw89_btc { |
4293 |
+ struct rtw89_btc_cx cx; |
4294 |
+ struct rtw89_btc_dm dm; |
4295 |
+ struct rtw89_btc_ctrl ctrl; |
4296 |
+ struct rtw89_btc_module mdinfo; |
4297 |
+ struct rtw89_btc_btf_fwinfo fwinfo; |
4298 |
+ struct rtw89_btc_dbg dbg; |
4299 |
+ |
4300 |
+ struct work_struct eapol_notify_work; |
4301 |
+ struct work_struct arp_notify_work; |
4302 |
+ struct work_struct dhcp_notify_work; |
4303 |
+ struct work_struct icmp_notify_work; |
4304 |
+ |
4305 |
+ u32 bt_req_len; |
4306 |
+ |
4307 |
+ u8 policy[RTW89_BTC_POLICY_MAXLEN]; |
4308 |
+ u16 policy_len; |
4309 |
+ u16 policy_type; |
4310 |
+ bool bt_req_en; |
4311 |
+ bool update_policy_force; |
4312 |
+ bool lps; |
4313 |
+}; |
4314 |
+ |
4315 |
+enum rtw89_ra_mode { |
4316 |
+ RTW89_RA_MODE_CCK = BIT(0), |
4317 |
+ RTW89_RA_MODE_OFDM = BIT(1), |
4318 |
+ RTW89_RA_MODE_HT = BIT(2), |
4319 |
+ RTW89_RA_MODE_VHT = BIT(3), |
4320 |
+ RTW89_RA_MODE_HE = BIT(4), |
4321 |
+}; |
4322 |
+ |
4323 |
+enum rtw89_ra_report_mode { |
4324 |
+ RTW89_RA_RPT_MODE_LEGACY, |
4325 |
+ RTW89_RA_RPT_MODE_HT, |
4326 |
+ RTW89_RA_RPT_MODE_VHT, |
4327 |
+ RTW89_RA_RPT_MODE_HE, |
4328 |
+}; |
4329 |
+ |
4330 |
+enum rtw89_dig_noisy_level { |
4331 |
+ RTW89_DIG_NOISY_LEVEL0 = -1, |
4332 |
+ RTW89_DIG_NOISY_LEVEL1 = 0, |
4333 |
+ RTW89_DIG_NOISY_LEVEL2 = 1, |
4334 |
+ RTW89_DIG_NOISY_LEVEL3 = 2, |
4335 |
+ RTW89_DIG_NOISY_LEVEL_MAX = 3, |
4336 |
+}; |
4337 |
+ |
4338 |
+enum rtw89_gi_ltf { |
4339 |
+ RTW89_GILTF_LGI_4XHE32 = 0, |
4340 |
+ RTW89_GILTF_SGI_4XHE08 = 1, |
4341 |
+ RTW89_GILTF_2XHE16 = 2, |
4342 |
+ RTW89_GILTF_2XHE08 = 3, |
4343 |
+ RTW89_GILTF_1XHE16 = 4, |
4344 |
+ RTW89_GILTF_1XHE08 = 5, |
4345 |
+ RTW89_GILTF_MAX |
4346 |
+}; |
4347 |
+ |
4348 |
+enum rtw89_rx_frame_type { |
4349 |
+ RTW89_RX_TYPE_MGNT = 0, |
4350 |
+ RTW89_RX_TYPE_CTRL = 1, |
4351 |
+ RTW89_RX_TYPE_DATA = 2, |
4352 |
+ RTW89_RX_TYPE_RSVD = 3, |
4353 |
+}; |
4354 |
+ |
4355 |
+struct rtw89_ra_info { |
4356 |
+ u8 is_dis_ra:1; |
4357 |
+ /* Bit0 : CCK |
4358 |
+ * Bit1 : OFDM |
4359 |
+ * Bit2 : HT |
4360 |
+ * Bit3 : VHT |
4361 |
+ * Bit4 : HE |
4362 |
+ */ |
4363 |
+ u8 mode_ctrl:5; |
4364 |
+ u8 bw_cap:2; |
4365 |
+ u8 macid; |
4366 |
+ u8 dcm_cap:1; |
4367 |
+ u8 er_cap:1; |
4368 |
+ u8 init_rate_lv:2; |
4369 |
+ u8 upd_all:1; |
4370 |
+ u8 en_sgi:1; |
4371 |
+ u8 ldpc_cap:1; |
4372 |
+ u8 stbc_cap:1; |
4373 |
+ u8 ss_num:3; |
4374 |
+ u8 giltf:3; |
4375 |
+ u8 upd_bw_nss_mask:1; |
4376 |
+ u8 upd_mask:1; |
4377 |
+ u64 ra_mask; /* 63 bits ra_mask + 1 bit CSI ctrl */ |
4378 |
+ /* BFee CSI */ |
4379 |
+ u8 band_num; |
4380 |
+ u8 ra_csi_rate_en:1; |
4381 |
+ u8 fixed_csi_rate_en:1; |
4382 |
+ u8 cr_tbl_sel:1; |
4383 |
+ u8 rsvd2:5; |
4384 |
+ u8 csi_mcs_ss_idx; |
4385 |
+ u8 csi_mode:2; |
4386 |
+ u8 csi_gi_ltf:3; |
4387 |
+ u8 csi_bw:3; |
4388 |
+}; |
4389 |
+ |
4390 |
+#define RTW89_PPDU_MAX_USR 4 |
4391 |
+#define RTW89_PPDU_MAC_INFO_USR_SIZE 4 |
4392 |
+#define RTW89_PPDU_MAC_INFO_SIZE 8 |
4393 |
+#define RTW89_PPDU_MAC_RX_CNT_SIZE 96 |
4394 |
+ |
4395 |
+#define RTW89_MAX_RX_AGG_NUM 64 |
4396 |
+#define RTW89_MAX_TX_AGG_NUM 128 |
4397 |
+ |
4398 |
+struct rtw89_ampdu_params { |
4399 |
+ u16 agg_num; |
4400 |
+ bool amsdu; |
4401 |
+}; |
4402 |
+ |
4403 |
+struct rtw89_ra_report { |
4404 |
+ struct rate_info txrate; |
4405 |
+ u32 bit_rate; |
4406 |
+ u16 hw_rate; |
4407 |
+}; |
4408 |
+ |
4409 |
+DECLARE_EWMA(rssi, 10, 16); |
4410 |
+ |
4411 |
+struct rtw89_sta { |
4412 |
+ u8 mac_id; |
4413 |
+ bool disassoc; |
4414 |
+ struct rtw89_vif *rtwvif; |
4415 |
+ struct rtw89_ra_info ra; |
4416 |
+ struct rtw89_ra_report ra_report; |
4417 |
+ int max_agg_wait; |
4418 |
+ u8 prev_rssi; |
4419 |
+ struct ewma_rssi avg_rssi; |
4420 |
+ struct rtw89_ampdu_params ampdu_params[IEEE80211_NUM_TIDS]; |
4421 |
+ struct ieee80211_rx_status rx_status; |
4422 |
+ u16 rx_hw_rate; |
4423 |
+ __le32 htc_template; |
4424 |
+ |
4425 |
+ bool use_cfg_mask; |
4426 |
+ struct cfg80211_bitrate_mask mask; |
4427 |
+ |
4428 |
+ bool cctl_tx_time; |
4429 |
+ u32 ampdu_max_time:4; |
4430 |
+ bool cctl_tx_retry_limit; |
4431 |
+ u32 data_tx_cnt_lmt:6; |
4432 |
+}; |
4433 |
+ |
4434 |
+#define RTW89_MAX_ADDR_CAM_NUM 128 |
4435 |
+#define RTW89_MAX_BSSID_CAM_NUM 20 |
4436 |
+#define RTW89_MAX_SEC_CAM_NUM 128 |
4437 |
+#define RTW89_SEC_CAM_IN_ADDR_CAM 7 |
4438 |
+ |
4439 |
+struct rtw89_addr_cam_entry { |
4440 |
+ u8 addr_cam_idx; |
4441 |
+ u8 offset; |
4442 |
+ u8 len; |
4443 |
+ u8 valid : 1; |
4444 |
+ u8 addr_mask : 6; |
4445 |
+ u8 wapi : 1; |
4446 |
+ u8 mask_sel : 2; |
4447 |
+ u8 bssid_cam_idx: 6; |
4448 |
+ u8 tma[ETH_ALEN]; |
4449 |
+ u8 sma[ETH_ALEN]; |
4450 |
+ |
4451 |
+ u8 sec_ent_mode; |
4452 |
+ DECLARE_BITMAP(sec_cam_map, RTW89_SEC_CAM_IN_ADDR_CAM); |
4453 |
+ u8 sec_ent_keyid[RTW89_SEC_CAM_IN_ADDR_CAM]; |
4454 |
+ u8 sec_ent[RTW89_SEC_CAM_IN_ADDR_CAM]; |
4455 |
+ struct rtw89_sec_cam_entry *sec_entries[RTW89_SEC_CAM_IN_ADDR_CAM]; |
4456 |
+}; |
4457 |
+ |
4458 |
+struct rtw89_bssid_cam_entry { |
4459 |
+ u8 bssid[ETH_ALEN]; |
4460 |
+ u8 phy_idx; |
4461 |
+ u8 bssid_cam_idx; |
4462 |
+ u8 offset; |
4463 |
+ u8 len; |
4464 |
+ u8 valid : 1; |
4465 |
+ u8 num; |
4466 |
+}; |
4467 |
+ |
4468 |
+struct rtw89_sec_cam_entry { |
4469 |
+ u8 sec_cam_idx; |
4470 |
+ u8 offset; |
4471 |
+ u8 len; |
4472 |
+ u8 type : 4; |
4473 |
+ u8 ext_key : 1; |
4474 |
+ u8 spp_mode : 1; |
4475 |
+ /* 256 bits */ |
4476 |
+ u8 key[32]; |
4477 |
+}; |
4478 |
+ |
4479 |
+struct rtw89_efuse { |
4480 |
+ bool valid; |
4481 |
+ u8 xtal_cap; |
4482 |
+ u8 addr[ETH_ALEN]; |
4483 |
+ u8 rfe_type; |
4484 |
+ char country_code[2]; |
4485 |
+}; |
4486 |
+ |
4487 |
+struct rtw89_phy_rate_pattern { |
4488 |
+ u64 ra_mask; |
4489 |
+ u16 rate; |
4490 |
+ u8 ra_mode; |
4491 |
+ bool enable; |
4492 |
+}; |
4493 |
+ |
4494 |
+struct rtw89_vif { |
4495 |
+ struct list_head list; |
4496 |
+ u8 mac_id; |
4497 |
+ u8 port; |
4498 |
+ u8 mac_addr[ETH_ALEN]; |
4499 |
+ u8 bssid[ETH_ALEN]; |
4500 |
+ u8 phy_idx; |
4501 |
+ u8 mac_idx; |
4502 |
+ u8 net_type; |
4503 |
+ u8 wifi_role; |
4504 |
+ u8 self_role; |
4505 |
+ u8 wmm; |
4506 |
+ u8 bcn_hit_cond; |
4507 |
+ u8 hit_rule; |
4508 |
+ bool trigger; |
4509 |
+ bool lsig_txop; |
4510 |
+ u8 tgt_ind; |
4511 |
+ u8 frm_tgt_ind; |
4512 |
+ bool wowlan_pattern; |
4513 |
+ bool wowlan_uc; |
4514 |
+ bool wowlan_magic; |
4515 |
+ bool is_hesta; |
4516 |
+ bool last_a_ctrl; |
4517 |
+ union { |
4518 |
+ struct { |
4519 |
+ struct ieee80211_sta *ap; |
4520 |
+ } mgd; |
4521 |
+ struct { |
4522 |
+ struct list_head sta_list; |
4523 |
+ } ap; |
4524 |
+ }; |
4525 |
+ struct rtw89_addr_cam_entry addr_cam; |
4526 |
+ struct rtw89_bssid_cam_entry bssid_cam; |
4527 |
+ struct ieee80211_tx_queue_params tx_params[IEEE80211_NUM_ACS]; |
4528 |
+ struct rtw89_traffic_stats stats; |
4529 |
+ struct rtw89_phy_rate_pattern rate_pattern; |
4530 |
+}; |
4531 |
+ |
4532 |
+enum rtw89_lv1_rcvy_step { |
4533 |
+ RTW89_LV1_RCVY_STEP_1, |
4534 |
+ RTW89_LV1_RCVY_STEP_2, |
4535 |
+}; |
4536 |
+ |
4537 |
+struct rtw89_hci_ops { |
4538 |
+ int (*tx_write)(struct rtw89_dev *rtwdev, struct rtw89_core_tx_request *tx_req); |
4539 |
+ void (*tx_kick_off)(struct rtw89_dev *rtwdev, u8 txch); |
4540 |
+ void (*flush_queues)(struct rtw89_dev *rtwdev, u32 queues, bool drop); |
4541 |
+ void (*reset)(struct rtw89_dev *rtwdev); |
4542 |
+ int (*start)(struct rtw89_dev *rtwdev); |
4543 |
+ void (*stop)(struct rtw89_dev *rtwdev); |
4544 |
+ void (*recalc_int_mit)(struct rtw89_dev *rtwdev); |
4545 |
+ |
4546 |
+ u8 (*read8)(struct rtw89_dev *rtwdev, u32 addr); |
4547 |
+ u16 (*read16)(struct rtw89_dev *rtwdev, u32 addr); |
4548 |
+ u32 (*read32)(struct rtw89_dev *rtwdev, u32 addr); |
4549 |
+ void (*write8)(struct rtw89_dev *rtwdev, u32 addr, u8 data); |
4550 |
+ void (*write16)(struct rtw89_dev *rtwdev, u32 addr, u16 data); |
4551 |
+ void (*write32)(struct rtw89_dev *rtwdev, u32 addr, u32 data); |
4552 |
+ |
4553 |
+ int (*mac_pre_init)(struct rtw89_dev *rtwdev); |
4554 |
+ int (*mac_post_init)(struct rtw89_dev *rtwdev); |
4555 |
+ int (*deinit)(struct rtw89_dev *rtwdev); |
4556 |
+ |
4557 |
+ u32 (*check_and_reclaim_tx_resource)(struct rtw89_dev *rtwdev, u8 txch); |
4558 |
+ int (*mac_lv1_rcvy)(struct rtw89_dev *rtwdev, enum rtw89_lv1_rcvy_step step); |
4559 |
+ void (*dump_err_status)(struct rtw89_dev *rtwdev); |
4560 |
+ int (*napi_poll)(struct napi_struct *napi, int budget); |
4561 |
+}; |
4562 |
+ |
4563 |
+struct rtw89_hci_info { |
4564 |
+ const struct rtw89_hci_ops *ops; |
4565 |
+ enum rtw89_hci_type type; |
4566 |
+ u32 rpwm_addr; |
4567 |
+ u32 cpwm_addr; |
4568 |
+}; |
4569 |
+ |
4570 |
+struct rtw89_chip_ops { |
4571 |
+ void (*bb_reset)(struct rtw89_dev *rtwdev, |
4572 |
+ enum rtw89_phy_idx phy_idx); |
4573 |
+ void (*bb_sethw)(struct rtw89_dev *rtwdev); |
4574 |
+ u32 (*read_rf)(struct rtw89_dev *rtwdev, enum rtw89_rf_path rf_path, |
4575 |
+ u32 addr, u32 mask); |
4576 |
+ bool (*write_rf)(struct rtw89_dev *rtwdev, enum rtw89_rf_path rf_path, |
4577 |
+ u32 addr, u32 mask, u32 data); |
4578 |
+ void (*set_channel)(struct rtw89_dev *rtwdev, |
4579 |
+ struct rtw89_channel_params *param); |
4580 |
+ void (*set_channel_help)(struct rtw89_dev *rtwdev, bool enter, |
4581 |
+ struct rtw89_channel_help_params *p); |
4582 |
+ int (*read_efuse)(struct rtw89_dev *rtwdev, u8 *log_map); |
4583 |
+ int (*read_phycap)(struct rtw89_dev *rtwdev, u8 *phycap_map); |
4584 |
+ void (*fem_setup)(struct rtw89_dev *rtwdev); |
4585 |
+ void (*rfk_init)(struct rtw89_dev *rtwdev); |
4586 |
+ void (*rfk_channel)(struct rtw89_dev *rtwdev); |
4587 |
+ void (*rfk_band_changed)(struct rtw89_dev *rtwdev); |
4588 |
+ void (*rfk_scan)(struct rtw89_dev *rtwdev, bool start); |
4589 |
+ void (*rfk_track)(struct rtw89_dev *rtwdev); |
4590 |
+ void (*power_trim)(struct rtw89_dev *rtwdev); |
4591 |
+ void (*set_txpwr)(struct rtw89_dev *rtwdev); |
4592 |
+ void (*set_txpwr_ctrl)(struct rtw89_dev *rtwdev); |
4593 |
+ int (*init_txpwr_unit)(struct rtw89_dev *rtwdev, enum rtw89_phy_idx phy_idx); |
4594 |
+ u8 (*get_thermal)(struct rtw89_dev *rtwdev, enum rtw89_rf_path rf_path); |
4595 |
+ void (*ctrl_btg)(struct rtw89_dev *rtwdev, bool btg); |
4596 |
+ void (*query_ppdu)(struct rtw89_dev *rtwdev, |
4597 |
+ struct rtw89_rx_phy_ppdu *phy_ppdu, |
4598 |
+ struct ieee80211_rx_status *status); |
4599 |
+ void (*bb_ctrl_btc_preagc)(struct rtw89_dev *rtwdev, bool bt_en); |
4600 |
+ void (*set_txpwr_ul_tb_offset)(struct rtw89_dev *rtwdev, |
4601 |
+ s16 pw_ofst, enum rtw89_mac_idx mac_idx); |
4602 |
+ |
4603 |
+ void (*btc_set_rfe)(struct rtw89_dev *rtwdev); |
4604 |
+ void (*btc_init_cfg)(struct rtw89_dev *rtwdev); |
4605 |
+ void (*btc_set_wl_pri)(struct rtw89_dev *rtwdev, u8 map, bool state); |
4606 |
+ void (*btc_set_wl_txpwr_ctrl)(struct rtw89_dev *rtwdev, u32 txpwr_val); |
4607 |
+ s8 (*btc_get_bt_rssi)(struct rtw89_dev *rtwdev, s8 val); |
4608 |
+ void (*btc_bt_aci_imp)(struct rtw89_dev *rtwdev); |
4609 |
+ void (*btc_update_bt_cnt)(struct rtw89_dev *rtwdev); |
4610 |
+ void (*btc_wl_s1_standby)(struct rtw89_dev *rtwdev, bool state); |
4611 |
+}; |
4612 |
+ |
4613 |
+enum rtw89_dma_ch { |
4614 |
+ RTW89_DMA_ACH0 = 0, |
4615 |
+ RTW89_DMA_ACH1 = 1, |
4616 |
+ RTW89_DMA_ACH2 = 2, |
4617 |
+ RTW89_DMA_ACH3 = 3, |
4618 |
+ RTW89_DMA_ACH4 = 4, |
4619 |
+ RTW89_DMA_ACH5 = 5, |
4620 |
+ RTW89_DMA_ACH6 = 6, |
4621 |
+ RTW89_DMA_ACH7 = 7, |
4622 |
+ RTW89_DMA_B0MG = 8, |
4623 |
+ RTW89_DMA_B0HI = 9, |
4624 |
+ RTW89_DMA_B1MG = 10, |
4625 |
+ RTW89_DMA_B1HI = 11, |
4626 |
+ RTW89_DMA_H2C = 12, |
4627 |
+ RTW89_DMA_CH_NUM = 13 |
4628 |
+}; |
4629 |
+ |
4630 |
+enum rtw89_qta_mode { |
4631 |
+ RTW89_QTA_SCC, |
4632 |
+ RTW89_QTA_DLFW, |
4633 |
+ |
4634 |
+ /* keep last */ |
4635 |
+ RTW89_QTA_INVALID, |
4636 |
+}; |
4637 |
+ |
4638 |
+struct rtw89_hfc_ch_cfg { |
4639 |
+ u16 min; |
4640 |
+ u16 max; |
4641 |
+#define grp_0 0 |
4642 |
+#define grp_1 1 |
4643 |
+#define grp_num 2 |
4644 |
+ u8 grp; |
4645 |
+}; |
4646 |
+ |
4647 |
+struct rtw89_hfc_ch_info { |
4648 |
+ u16 aval; |
4649 |
+ u16 used; |
4650 |
+}; |
4651 |
+ |
4652 |
+struct rtw89_hfc_pub_cfg { |
4653 |
+ u16 grp0; |
4654 |
+ u16 grp1; |
4655 |
+ u16 pub_max; |
4656 |
+ u16 wp_thrd; |
4657 |
+}; |
4658 |
+ |
4659 |
+struct rtw89_hfc_pub_info { |
4660 |
+ u16 g0_used; |
4661 |
+ u16 g1_used; |
4662 |
+ u16 g0_aval; |
4663 |
+ u16 g1_aval; |
4664 |
+ u16 pub_aval; |
4665 |
+ u16 wp_aval; |
4666 |
+}; |
4667 |
+ |
4668 |
+struct rtw89_hfc_prec_cfg { |
4669 |
+ u16 ch011_prec; |
4670 |
+ u16 h2c_prec; |
4671 |
+ u16 wp_ch07_prec; |
4672 |
+ u16 wp_ch811_prec; |
4673 |
+ u8 ch011_full_cond; |
4674 |
+ u8 h2c_full_cond; |
4675 |
+ u8 wp_ch07_full_cond; |
4676 |
+ u8 wp_ch811_full_cond; |
4677 |
+}; |
4678 |
+ |
4679 |
+struct rtw89_hfc_param { |
4680 |
+ bool en; |
4681 |
+ bool h2c_en; |
4682 |
+ u8 mode; |
4683 |
+ const struct rtw89_hfc_ch_cfg *ch_cfg; |
4684 |
+ struct rtw89_hfc_ch_info ch_info[RTW89_DMA_CH_NUM]; |
4685 |
+ struct rtw89_hfc_pub_cfg pub_cfg; |
4686 |
+ struct rtw89_hfc_pub_info pub_info; |
4687 |
+ struct rtw89_hfc_prec_cfg prec_cfg; |
4688 |
+}; |
4689 |
+ |
4690 |
+struct rtw89_hfc_param_ini { |
4691 |
+ const struct rtw89_hfc_ch_cfg *ch_cfg; |
4692 |
+ const struct rtw89_hfc_pub_cfg *pub_cfg; |
4693 |
+ const struct rtw89_hfc_prec_cfg *prec_cfg; |
4694 |
+ u8 mode; |
4695 |
+}; |
4696 |
+ |
4697 |
+struct rtw89_dle_size { |
4698 |
+ u16 pge_size; |
4699 |
+ u16 lnk_pge_num; |
4700 |
+ u16 unlnk_pge_num; |
4701 |
+}; |
4702 |
+ |
4703 |
+struct rtw89_wde_quota { |
4704 |
+ u16 hif; |
4705 |
+ u16 wcpu; |
4706 |
+ u16 pkt_in; |
4707 |
+ u16 cpu_io; |
4708 |
+}; |
4709 |
+ |
4710 |
+struct rtw89_ple_quota { |
4711 |
+ u16 cma0_tx; |
4712 |
+ u16 cma1_tx; |
4713 |
+ u16 c2h; |
4714 |
+ u16 h2c; |
4715 |
+ u16 wcpu; |
4716 |
+ u16 mpdu_proc; |
4717 |
+ u16 cma0_dma; |
4718 |
+ u16 cma1_dma; |
4719 |
+ u16 bb_rpt; |
4720 |
+ u16 wd_rel; |
4721 |
+ u16 cpu_io; |
4722 |
+}; |
4723 |
+ |
4724 |
+struct rtw89_dle_mem { |
4725 |
+ enum rtw89_qta_mode mode; |
4726 |
+ const struct rtw89_dle_size *wde_size; |
4727 |
+ const struct rtw89_dle_size *ple_size; |
4728 |
+ const struct rtw89_wde_quota *wde_min_qt; |
4729 |
+ const struct rtw89_wde_quota *wde_max_qt; |
4730 |
+ const struct rtw89_ple_quota *ple_min_qt; |
4731 |
+ const struct rtw89_ple_quota *ple_max_qt; |
4732 |
+}; |
4733 |
+ |
4734 |
+struct rtw89_reg_def { |
4735 |
+ u32 addr; |
4736 |
+ u32 mask; |
4737 |
+}; |
4738 |
+ |
4739 |
+struct rtw89_reg2_def { |
4740 |
+ u32 addr; |
4741 |
+ u32 data; |
4742 |
+}; |
4743 |
+ |
4744 |
+struct rtw89_reg3_def { |
4745 |
+ u32 addr; |
4746 |
+ u32 mask; |
4747 |
+ u32 data; |
4748 |
+}; |
4749 |
+ |
4750 |
+struct rtw89_reg5_def { |
4751 |
+ u8 flag; /* recognized by parsers */ |
4752 |
+ u8 path; |
4753 |
+ u32 addr; |
4754 |
+ u32 mask; |
4755 |
+ u32 data; |
4756 |
+}; |
4757 |
+ |
4758 |
+struct rtw89_phy_table { |
4759 |
+ const struct rtw89_reg2_def *regs; |
4760 |
+ u32 n_regs; |
4761 |
+ enum rtw89_rf_path rf_path; |
4762 |
+}; |
4763 |
+ |
4764 |
+struct rtw89_txpwr_table { |
4765 |
+ const void *data; |
4766 |
+ u32 size; |
4767 |
+ void (*load)(struct rtw89_dev *rtwdev, |
4768 |
+ const struct rtw89_txpwr_table *tbl); |
4769 |
+}; |
4770 |
+ |
4771 |
+struct rtw89_chip_info { |
4772 |
+ enum rtw89_core_chip_id chip_id; |
4773 |
+ const struct rtw89_chip_ops *ops; |
4774 |
+ const char *fw_name; |
4775 |
+ u32 fifo_size; |
4776 |
+ u16 max_amsdu_limit; |
4777 |
+ bool dis_2g_40m_ul_ofdma; |
4778 |
+ const struct rtw89_hfc_param_ini *hfc_param_ini; |
4779 |
+ const struct rtw89_dle_mem *dle_mem; |
4780 |
+ u32 rf_base_addr[2]; |
4781 |
+ u8 rf_path_num; |
4782 |
+ u8 tx_nss; |
4783 |
+ u8 rx_nss; |
4784 |
+ u8 acam_num; |
4785 |
+ u8 bcam_num; |
4786 |
+ u8 scam_num; |
4787 |
+ |
4788 |
+ u8 sec_ctrl_efuse_size; |
4789 |
+ u32 physical_efuse_size; |
4790 |
+ u32 logical_efuse_size; |
4791 |
+ u32 limit_efuse_size; |
4792 |
+ u32 phycap_addr; |
4793 |
+ u32 phycap_size; |
4794 |
+ |
4795 |
+ const struct rtw89_pwr_cfg * const *pwr_on_seq; |
4796 |
+ const struct rtw89_pwr_cfg * const *pwr_off_seq; |
4797 |
+ const struct rtw89_phy_table *bb_table; |
4798 |
+ const struct rtw89_phy_table *rf_table[RF_PATH_MAX]; |
4799 |
+ const struct rtw89_phy_table *nctl_table; |
4800 |
+ const struct rtw89_txpwr_table *byr_table; |
4801 |
+ const struct rtw89_phy_dig_gain_table *dig_table; |
4802 |
+ const s8 (*txpwr_lmt_2g)[RTW89_2G_BW_NUM][RTW89_NTX_NUM] |
4803 |
+ [RTW89_RS_LMT_NUM][RTW89_BF_NUM] |
4804 |
+ [RTW89_REGD_NUM][RTW89_2G_CH_NUM]; |
4805 |
+ const s8 (*txpwr_lmt_5g)[RTW89_5G_BW_NUM][RTW89_NTX_NUM] |
4806 |
+ [RTW89_RS_LMT_NUM][RTW89_BF_NUM] |
4807 |
+ [RTW89_REGD_NUM][RTW89_5G_CH_NUM]; |
4808 |
+ const s8 (*txpwr_lmt_ru_2g)[RTW89_RU_NUM][RTW89_NTX_NUM] |
4809 |
+ [RTW89_REGD_NUM][RTW89_2G_CH_NUM]; |
4810 |
+ const s8 (*txpwr_lmt_ru_5g)[RTW89_RU_NUM][RTW89_NTX_NUM] |
4811 |
+ [RTW89_REGD_NUM][RTW89_5G_CH_NUM]; |
4812 |
+ |
4813 |
+ u8 txpwr_factor_rf; |
4814 |
+ u8 txpwr_factor_mac; |
4815 |
+ |
4816 |
+ u32 para_ver; |
4817 |
+ u32 wlcx_desired; |
4818 |
+ u8 btcx_desired; |
4819 |
+ u8 scbd; |
4820 |
+ u8 mailbox; |
4821 |
+ |
4822 |
+ u8 afh_guard_ch; |
4823 |
+ const u8 *wl_rssi_thres; |
4824 |
+ const u8 *bt_rssi_thres; |
4825 |
+ u8 rssi_tol; |
4826 |
+ |
4827 |
+ u8 mon_reg_num; |
4828 |
+ const struct rtw89_btc_fbtc_mreg *mon_reg; |
4829 |
+ u8 rf_para_ulink_num; |
4830 |
+ const struct rtw89_btc_rf_trx_para *rf_para_ulink; |
4831 |
+ u8 rf_para_dlink_num; |
4832 |
+ const struct rtw89_btc_rf_trx_para *rf_para_dlink; |
4833 |
+ u8 ps_mode_supported; |
4834 |
+}; |
4835 |
+ |
4836 |
+enum rtw89_hcifc_mode { |
4837 |
+ RTW89_HCIFC_POH = 0, |
4838 |
+ RTW89_HCIFC_STF = 1, |
4839 |
+ RTW89_HCIFC_SDIO = 2, |
4840 |
+ |
4841 |
+ /* keep last */ |
4842 |
+ RTW89_HCIFC_MODE_INVALID, |
4843 |
+}; |
4844 |
+ |
4845 |
+struct rtw89_dle_info { |
4846 |
+ enum rtw89_qta_mode qta_mode; |
4847 |
+ u16 wde_pg_size; |
4848 |
+ u16 ple_pg_size; |
4849 |
+ u16 c0_rx_qta; |
4850 |
+ u16 c1_rx_qta; |
4851 |
+}; |
4852 |
+ |
4853 |
+enum rtw89_host_rpr_mode { |
4854 |
+ RTW89_RPR_MODE_POH = 0, |
4855 |
+ RTW89_RPR_MODE_STF |
4856 |
+}; |
4857 |
+ |
4858 |
+struct rtw89_mac_info { |
4859 |
+ struct rtw89_dle_info dle_info; |
4860 |
+ struct rtw89_hfc_param hfc_param; |
4861 |
+ enum rtw89_qta_mode qta_mode; |
4862 |
+ u8 rpwm_seq_num; |
4863 |
+ u8 cpwm_seq_num; |
4864 |
+}; |
4865 |
+ |
4866 |
+enum rtw89_fw_type { |
4867 |
+ RTW89_FW_NORMAL = 1, |
4868 |
+ RTW89_FW_WOWLAN = 3, |
4869 |
+}; |
4870 |
+ |
4871 |
+struct rtw89_fw_suit { |
4872 |
+ const u8 *data; |
4873 |
+ u32 size; |
4874 |
+ u8 major_ver; |
4875 |
+ u8 minor_ver; |
4876 |
+ u8 sub_ver; |
4877 |
+ u8 sub_idex; |
4878 |
+ u16 build_year; |
4879 |
+ u16 build_mon; |
4880 |
+ u16 build_date; |
4881 |
+ u16 build_hour; |
4882 |
+ u16 build_min; |
4883 |
+ u8 cmd_ver; |
4884 |
+}; |
4885 |
+ |
4886 |
+#define RTW89_FW_VER_CODE(major, minor, sub, idx) \ |
4887 |
+ (((major) << 24) | ((minor) << 16) | ((sub) << 8) | (idx)) |
4888 |
+#define RTW89_FW_SUIT_VER_CODE(s) \ |
4889 |
+ RTW89_FW_VER_CODE((s)->major_ver, (s)->minor_ver, (s)->sub_ver, (s)->sub_idex) |
4890 |
+ |
4891 |
+struct rtw89_fw_info { |
4892 |
+ const struct firmware *firmware; |
4893 |
+ struct rtw89_dev *rtwdev; |
4894 |
+ struct completion completion; |
4895 |
+ u8 h2c_seq; |
4896 |
+ u8 rec_seq; |
4897 |
+ struct rtw89_fw_suit normal; |
4898 |
+ struct rtw89_fw_suit wowlan; |
4899 |
+ bool fw_log_enable; |
4900 |
+ bool old_ht_ra_format; |
4901 |
+}; |
4902 |
+ |
4903 |
+struct rtw89_cam_info { |
4904 |
+ DECLARE_BITMAP(addr_cam_map, RTW89_MAX_ADDR_CAM_NUM); |
4905 |
+ DECLARE_BITMAP(bssid_cam_map, RTW89_MAX_BSSID_CAM_NUM); |
4906 |
+ DECLARE_BITMAP(sec_cam_map, RTW89_MAX_SEC_CAM_NUM); |
4907 |
+}; |
4908 |
+ |
4909 |
+enum rtw89_sar_sources { |
4910 |
+ RTW89_SAR_SOURCE_NONE, |
4911 |
+ RTW89_SAR_SOURCE_COMMON, |
4912 |
+ |
4913 |
+ RTW89_SAR_SOURCE_NR, |
4914 |
+}; |
4915 |
+ |
4916 |
+struct rtw89_sar_cfg_common { |
4917 |
+ bool set[RTW89_SUBBAND_NR]; |
4918 |
+ s32 cfg[RTW89_SUBBAND_NR]; |
4919 |
+}; |
4920 |
+ |
4921 |
+struct rtw89_sar_info { |
4922 |
+ /* used to decide how to acces SAR cfg union */ |
4923 |
+ enum rtw89_sar_sources src; |
4924 |
+ |
4925 |
+ /* reserved for different knids of SAR cfg struct. |
4926 |
+ * supposed that a single cfg struct cannot handle various SAR sources. |
4927 |
+ */ |
4928 |
+ union { |
4929 |
+ struct rtw89_sar_cfg_common cfg_common; |
4930 |
+ }; |
4931 |
+}; |
4932 |
+ |
4933 |
+struct rtw89_hal { |
4934 |
+ u32 rx_fltr; |
4935 |
+ u8 cv; |
4936 |
+ u8 current_channel; |
4937 |
+ u8 current_primary_channel; |
4938 |
+ enum rtw89_subband current_subband; |
4939 |
+ u8 current_band_width; |
4940 |
+ u8 current_band_type; |
4941 |
+ /* center channel for different available bandwidth, |
4942 |
+ * val of (bw > current_band_width) is invalid |
4943 |
+ */ |
4944 |
+ u8 cch_by_bw[RTW89_MAX_CHANNEL_WIDTH + 1]; |
4945 |
+ u32 sw_amsdu_max_size; |
4946 |
+ u32 antenna_tx; |
4947 |
+ u32 antenna_rx; |
4948 |
+ u8 tx_nss; |
4949 |
+ u8 rx_nss; |
4950 |
+}; |
4951 |
+ |
4952 |
+#define RTW89_MAX_MAC_ID_NUM 128 |
4953 |
+ |
4954 |
+enum rtw89_flags { |
4955 |
+ RTW89_FLAG_POWERON, |
4956 |
+ RTW89_FLAG_FW_RDY, |
4957 |
+ RTW89_FLAG_RUNNING, |
4958 |
+ RTW89_FLAG_BFEE_MON, |
4959 |
+ RTW89_FLAG_BFEE_EN, |
4960 |
+ RTW89_FLAG_NAPI_RUNNING, |
4961 |
+ RTW89_FLAG_LEISURE_PS, |
4962 |
+ RTW89_FLAG_LOW_POWER_MODE, |
4963 |
+ RTW89_FLAG_INACTIVE_PS, |
4964 |
+ |
4965 |
+ NUM_OF_RTW89_FLAGS, |
4966 |
+}; |
4967 |
+ |
4968 |
+struct rtw89_pkt_stat { |
4969 |
+ u16 beacon_nr; |
4970 |
+ u32 rx_rate_cnt[RTW89_HW_RATE_NR]; |
4971 |
+}; |
4972 |
+ |
4973 |
+DECLARE_EWMA(thermal, 4, 4); |
4974 |
+ |
4975 |
+struct rtw89_phy_stat { |
4976 |
+ struct ewma_thermal avg_thermal[RF_PATH_MAX]; |
4977 |
+ struct rtw89_pkt_stat cur_pkt_stat; |
4978 |
+ struct rtw89_pkt_stat last_pkt_stat; |
4979 |
+}; |
4980 |
+ |
4981 |
+#define RTW89_DACK_PATH_NR 2 |
4982 |
+#define RTW89_DACK_IDX_NR 2 |
4983 |
+#define RTW89_DACK_MSBK_NR 16 |
4984 |
+struct rtw89_dack_info { |
4985 |
+ bool dack_done; |
4986 |
+ u8 msbk_d[RTW89_DACK_PATH_NR][RTW89_DACK_IDX_NR][RTW89_DACK_MSBK_NR]; |
4987 |
+ u8 dadck_d[RTW89_DACK_PATH_NR][RTW89_DACK_IDX_NR]; |
4988 |
+ u16 addck_d[RTW89_DACK_PATH_NR][RTW89_DACK_IDX_NR]; |
4989 |
+ u16 biask_d[RTW89_DACK_PATH_NR][RTW89_DACK_IDX_NR]; |
4990 |
+ u32 dack_cnt; |
4991 |
+ bool addck_timeout[RTW89_DACK_PATH_NR]; |
4992 |
+ bool dadck_timeout[RTW89_DACK_PATH_NR]; |
4993 |
+ bool msbk_timeout[RTW89_DACK_PATH_NR]; |
4994 |
+}; |
4995 |
+ |
4996 |
+#define RTW89_IQK_CHS_NR 2 |
4997 |
+#define RTW89_IQK_PATH_NR 4 |
4998 |
+struct rtw89_iqk_info { |
4999 |
+ bool lok_cor_fail[RTW89_IQK_CHS_NR][RTW89_IQK_PATH_NR]; |
5000 |
+ bool lok_fin_fail[RTW89_IQK_CHS_NR][RTW89_IQK_PATH_NR]; |
5001 |
+ bool iqk_tx_fail[RTW89_IQK_CHS_NR][RTW89_IQK_PATH_NR]; |
5002 |
+ bool iqk_rx_fail[RTW89_IQK_CHS_NR][RTW89_IQK_PATH_NR]; |
5003 |
+ u32 iqk_fail_cnt; |
5004 |
+ bool is_iqk_init; |
5005 |
+ u32 iqk_channel[RTW89_IQK_CHS_NR]; |
5006 |
+ u8 iqk_band[RTW89_IQK_PATH_NR]; |
5007 |
+ u8 iqk_ch[RTW89_IQK_PATH_NR]; |
5008 |
+ u8 iqk_bw[RTW89_IQK_PATH_NR]; |
5009 |
+ u8 kcount; |
5010 |
+ u8 iqk_times; |
5011 |
+ u8 version; |
5012 |
+ u32 nb_txcfir[RTW89_IQK_PATH_NR]; |
5013 |
+ u32 nb_rxcfir[RTW89_IQK_PATH_NR]; |
5014 |
+ u32 bp_txkresult[RTW89_IQK_PATH_NR]; |
5015 |
+ u32 bp_rxkresult[RTW89_IQK_PATH_NR]; |
5016 |
+ u32 bp_iqkenable[RTW89_IQK_PATH_NR]; |
5017 |
+ bool is_wb_txiqk[RTW89_IQK_PATH_NR]; |
5018 |
+ bool is_wb_rxiqk[RTW89_IQK_PATH_NR]; |
5019 |
+ bool is_nbiqk; |
5020 |
+ bool iqk_fft_en; |
5021 |
+ bool iqk_xym_en; |
5022 |
+ bool iqk_sram_en; |
5023 |
+ bool iqk_cfir_en; |
5024 |
+ u8 thermal[RTW89_IQK_PATH_NR]; |
5025 |
+ bool thermal_rek_en; |
5026 |
+ u32 syn1to2; |
5027 |
+ u8 iqk_mcc_ch[RTW89_IQK_CHS_NR][RTW89_IQK_PATH_NR]; |
5028 |
+ u8 iqk_table_idx[RTW89_IQK_PATH_NR]; |
5029 |
+}; |
5030 |
+ |
5031 |
+#define RTW89_DPK_RF_PATH 2 |
5032 |
+#define RTW89_DPK_AVG_THERMAL_NUM 8 |
5033 |
+#define RTW89_DPK_BKUP_NUM 2 |
5034 |
+struct rtw89_dpk_bkup_para { |
5035 |
+ enum rtw89_band band; |
5036 |
+ enum rtw89_bandwidth bw; |
5037 |
+ u8 ch; |
5038 |
+ bool path_ok; |
5039 |
+ u8 txagc_dpk; |
5040 |
+ u8 ther_dpk; |
5041 |
+ u8 gs; |
5042 |
+ u16 pwsf; |
5043 |
+}; |
5044 |
+ |
5045 |
+struct rtw89_dpk_info { |
5046 |
+ bool is_dpk_enable; |
5047 |
+ bool is_dpk_reload_en; |
5048 |
+ u16 dc_i[RTW89_DPK_RF_PATH]; |
5049 |
+ u16 dc_q[RTW89_DPK_RF_PATH]; |
5050 |
+ u8 corr_val[RTW89_DPK_RF_PATH]; |
5051 |
+ u8 corr_idx[RTW89_DPK_RF_PATH]; |
5052 |
+ u8 cur_idx[RTW89_DPK_RF_PATH]; |
5053 |
+ struct rtw89_dpk_bkup_para bp[RTW89_DPK_RF_PATH][RTW89_DPK_BKUP_NUM]; |
5054 |
+}; |
5055 |
+ |
5056 |
+struct rtw89_fem_info { |
5057 |
+ bool elna_2g; |
5058 |
+ bool elna_5g; |
5059 |
+ bool epa_2g; |
5060 |
+ bool epa_5g; |
5061 |
+}; |
5062 |
+ |
5063 |
+struct rtw89_phy_ch_info { |
5064 |
+ u8 rssi_min; |
5065 |
+ u16 rssi_min_macid; |
5066 |
+ u8 pre_rssi_min; |
5067 |
+ u8 rssi_max; |
5068 |
+ u16 rssi_max_macid; |
5069 |
+ u8 rxsc_160; |
5070 |
+ u8 rxsc_80; |
5071 |
+ u8 rxsc_40; |
5072 |
+ u8 rxsc_20; |
5073 |
+ u8 rxsc_l; |
5074 |
+ u8 is_noisy; |
5075 |
+}; |
5076 |
+ |
5077 |
+struct rtw89_agc_gaincode_set { |
5078 |
+ u8 lna_idx; |
5079 |
+ u8 tia_idx; |
5080 |
+ u8 rxb_idx; |
5081 |
+}; |
5082 |
+ |
5083 |
+#define IGI_RSSI_TH_NUM 5 |
5084 |
+#define FA_TH_NUM 4 |
5085 |
+#define LNA_GAIN_NUM 7 |
5086 |
+#define TIA_GAIN_NUM 2 |
5087 |
+struct rtw89_dig_info { |
5088 |
+ struct rtw89_agc_gaincode_set cur_gaincode; |
5089 |
+ bool force_gaincode_idx_en; |
5090 |
+ struct rtw89_agc_gaincode_set force_gaincode; |
5091 |
+ u8 igi_rssi_th[IGI_RSSI_TH_NUM]; |
5092 |
+ u16 fa_th[FA_TH_NUM]; |
5093 |
+ u8 igi_rssi; |
5094 |
+ u8 igi_fa_rssi; |
5095 |
+ u8 fa_rssi_ofst; |
5096 |
+ u8 dyn_igi_max; |
5097 |
+ u8 dyn_igi_min; |
5098 |
+ bool dyn_pd_th_en; |
5099 |
+ u8 dyn_pd_th_max; |
5100 |
+ u8 pd_low_th_ofst; |
5101 |
+ u8 ib_pbk; |
5102 |
+ s8 ib_pkpwr; |
5103 |
+ s8 lna_gain_a[LNA_GAIN_NUM]; |
5104 |
+ s8 lna_gain_g[LNA_GAIN_NUM]; |
5105 |
+ s8 *lna_gain; |
5106 |
+ s8 tia_gain_a[TIA_GAIN_NUM]; |
5107 |
+ s8 tia_gain_g[TIA_GAIN_NUM]; |
5108 |
+ s8 *tia_gain; |
5109 |
+ bool is_linked_pre; |
5110 |
+ bool bypass_dig; |
5111 |
+}; |
5112 |
+ |
5113 |
+enum rtw89_multi_cfo_mode { |
5114 |
+ RTW89_PKT_BASED_AVG_MODE = 0, |
5115 |
+ RTW89_ENTRY_BASED_AVG_MODE = 1, |
5116 |
+ RTW89_TP_BASED_AVG_MODE = 2, |
5117 |
+}; |
5118 |
+ |
5119 |
+enum rtw89_phy_cfo_status { |
5120 |
+ RTW89_PHY_DCFO_STATE_NORMAL = 0, |
5121 |
+ RTW89_PHY_DCFO_STATE_ENHANCE = 1, |
5122 |
+ RTW89_PHY_DCFO_STATE_MAX |
5123 |
+}; |
5124 |
+ |
5125 |
+struct rtw89_cfo_tracking_info { |
5126 |
+ u16 cfo_timer_ms; |
5127 |
+ bool cfo_trig_by_timer_en; |
5128 |
+ enum rtw89_phy_cfo_status phy_cfo_status; |
5129 |
+ u8 phy_cfo_trk_cnt; |
5130 |
+ bool is_adjust; |
5131 |
+ enum rtw89_multi_cfo_mode rtw89_multi_cfo_mode; |
5132 |
+ bool apply_compensation; |
5133 |
+ u8 crystal_cap; |
5134 |
+ u8 crystal_cap_default; |
5135 |
+ u8 def_x_cap; |
5136 |
+ s8 x_cap_ofst; |
5137 |
+ u32 sta_cfo_tolerance; |
5138 |
+ s32 cfo_tail[CFO_TRACK_MAX_USER]; |
5139 |
+ u16 cfo_cnt[CFO_TRACK_MAX_USER]; |
5140 |
+ s32 cfo_avg_pre; |
5141 |
+ s32 cfo_avg[CFO_TRACK_MAX_USER]; |
5142 |
+ s32 pre_cfo_avg[CFO_TRACK_MAX_USER]; |
5143 |
+ u32 packet_count; |
5144 |
+ u32 packet_count_pre; |
5145 |
+ s32 residual_cfo_acc; |
5146 |
+ u8 phy_cfotrk_state; |
5147 |
+ u8 phy_cfotrk_cnt; |
5148 |
+}; |
5149 |
+ |
5150 |
+/* 2GL, 2GH, 5GL1, 5GH1, 5GM1, 5GM2, 5GH1, 5GH2 */ |
5151 |
+#define TSSI_TRIM_CH_GROUP_NUM 8 |
5152 |
+ |
5153 |
+#define TSSI_CCK_CH_GROUP_NUM 6 |
5154 |
+#define TSSI_MCS_2G_CH_GROUP_NUM 5 |
5155 |
+#define TSSI_MCS_5G_CH_GROUP_NUM 14 |
5156 |
+#define TSSI_MCS_CH_GROUP_NUM \ |
5157 |
+ (TSSI_MCS_2G_CH_GROUP_NUM + TSSI_MCS_5G_CH_GROUP_NUM) |
5158 |
+ |
5159 |
+struct rtw89_tssi_info { |
5160 |
+ u8 thermal[RF_PATH_MAX]; |
5161 |
+ s8 tssi_trim[RF_PATH_MAX][TSSI_TRIM_CH_GROUP_NUM]; |
5162 |
+ s8 tssi_cck[RF_PATH_MAX][TSSI_CCK_CH_GROUP_NUM]; |
5163 |
+ s8 tssi_mcs[RF_PATH_MAX][TSSI_MCS_CH_GROUP_NUM]; |
5164 |
+ s8 extra_ofst[RF_PATH_MAX]; |
5165 |
+ bool tssi_tracking_check[RF_PATH_MAX]; |
5166 |
+ u8 default_txagc_offset[RF_PATH_MAX]; |
5167 |
+ u32 base_thermal[RF_PATH_MAX]; |
5168 |
+}; |
5169 |
+ |
5170 |
+struct rtw89_power_trim_info { |
5171 |
+ bool pg_thermal_trim; |
5172 |
+ bool pg_pa_bias_trim; |
5173 |
+ u8 thermal_trim[RF_PATH_MAX]; |
5174 |
+ u8 pa_bias_trim[RF_PATH_MAX]; |
5175 |
+}; |
5176 |
+ |
5177 |
+struct rtw89_regulatory { |
5178 |
+ char alpha2[3]; |
5179 |
+ u8 txpwr_regd[RTW89_BAND_MAX]; |
5180 |
+}; |
5181 |
+ |
5182 |
+enum rtw89_ifs_clm_application { |
5183 |
+ RTW89_IFS_CLM_INIT = 0, |
5184 |
+ RTW89_IFS_CLM_BACKGROUND = 1, |
5185 |
+ RTW89_IFS_CLM_ACS = 2, |
5186 |
+ RTW89_IFS_CLM_DIG = 3, |
5187 |
+ RTW89_IFS_CLM_TDMA_DIG = 4, |
5188 |
+ RTW89_IFS_CLM_DBG = 5, |
5189 |
+ RTW89_IFS_CLM_DBG_MANUAL = 6 |
5190 |
+}; |
5191 |
+ |
5192 |
+enum rtw89_env_racing_lv { |
5193 |
+ RTW89_RAC_RELEASE = 0, |
5194 |
+ RTW89_RAC_LV_1 = 1, |
5195 |
+ RTW89_RAC_LV_2 = 2, |
5196 |
+ RTW89_RAC_LV_3 = 3, |
5197 |
+ RTW89_RAC_LV_4 = 4, |
5198 |
+ RTW89_RAC_MAX_NUM = 5 |
5199 |
+}; |
5200 |
+ |
5201 |
+struct rtw89_ccx_para_info { |
5202 |
+ enum rtw89_env_racing_lv rac_lv; |
5203 |
+ u16 mntr_time; |
5204 |
+ u8 nhm_manual_th_ofst; |
5205 |
+ u8 nhm_manual_th0; |
5206 |
+ enum rtw89_ifs_clm_application ifs_clm_app; |
5207 |
+ u32 ifs_clm_manual_th_times; |
5208 |
+ u32 ifs_clm_manual_th0; |
5209 |
+ u8 fahm_manual_th_ofst; |
5210 |
+ u8 fahm_manual_th0; |
5211 |
+ u8 fahm_numer_opt; |
5212 |
+ u8 fahm_denom_opt; |
5213 |
+}; |
5214 |
+ |
5215 |
+enum rtw89_ccx_edcca_opt_sc_idx { |
5216 |
+ RTW89_CCX_EDCCA_SEG0_P0 = 0, |
5217 |
+ RTW89_CCX_EDCCA_SEG0_S1 = 1, |
5218 |
+ RTW89_CCX_EDCCA_SEG0_S2 = 2, |
5219 |
+ RTW89_CCX_EDCCA_SEG0_S3 = 3, |
5220 |
+ RTW89_CCX_EDCCA_SEG1_P0 = 4, |
5221 |
+ RTW89_CCX_EDCCA_SEG1_S1 = 5, |
5222 |
+ RTW89_CCX_EDCCA_SEG1_S2 = 6, |
5223 |
+ RTW89_CCX_EDCCA_SEG1_S3 = 7 |
5224 |
+}; |
5225 |
+ |
5226 |
+enum rtw89_ccx_edcca_opt_bw_idx { |
5227 |
+ RTW89_CCX_EDCCA_BW20_0 = 0, |
5228 |
+ RTW89_CCX_EDCCA_BW20_1 = 1, |
5229 |
+ RTW89_CCX_EDCCA_BW20_2 = 2, |
5230 |
+ RTW89_CCX_EDCCA_BW20_3 = 3, |
5231 |
+ RTW89_CCX_EDCCA_BW20_4 = 4, |
5232 |
+ RTW89_CCX_EDCCA_BW20_5 = 5, |
5233 |
+ RTW89_CCX_EDCCA_BW20_6 = 6, |
5234 |
+ RTW89_CCX_EDCCA_BW20_7 = 7 |
5235 |
+}; |
5236 |
+ |
5237 |
+#define RTW89_NHM_TH_NUM 11 |
5238 |
+#define RTW89_FAHM_TH_NUM 11 |
5239 |
+#define RTW89_NHM_RPT_NUM 12 |
5240 |
+#define RTW89_FAHM_RPT_NUM 12 |
5241 |
+#define RTW89_IFS_CLM_NUM 4 |
5242 |
+struct rtw89_env_monitor_info { |
5243 |
+ u32 ccx_trigger_time; |
5244 |
+ u64 start_time; |
5245 |
+ u8 ccx_rpt_stamp; |
5246 |
+ u8 ccx_watchdog_result; |
5247 |
+ bool ccx_ongoing; |
5248 |
+ u8 ccx_rac_lv; |
5249 |
+ bool ccx_manual_ctrl; |
5250 |
+ u8 ccx_pre_rssi; |
5251 |
+ u16 clm_mntr_time; |
5252 |
+ u16 nhm_mntr_time; |
5253 |
+ u16 ifs_clm_mntr_time; |
5254 |
+ enum rtw89_ifs_clm_application ifs_clm_app; |
5255 |
+ u16 fahm_mntr_time; |
5256 |
+ u16 edcca_clm_mntr_time; |
5257 |
+ u16 ccx_period; |
5258 |
+ u8 ccx_unit_idx; |
5259 |
+ enum rtw89_ccx_edcca_opt_bw_idx ccx_edcca_opt_bw_idx; |
5260 |
+ u8 nhm_th[RTW89_NHM_TH_NUM]; |
5261 |
+ u16 ifs_clm_th_l[RTW89_IFS_CLM_NUM]; |
5262 |
+ u16 ifs_clm_th_h[RTW89_IFS_CLM_NUM]; |
5263 |
+ u8 fahm_numer_opt; |
5264 |
+ u8 fahm_denom_opt; |
5265 |
+ u8 fahm_th[RTW89_FAHM_TH_NUM]; |
5266 |
+ u16 clm_result; |
5267 |
+ u16 nhm_result[RTW89_NHM_RPT_NUM]; |
5268 |
+ u8 nhm_wgt[RTW89_NHM_RPT_NUM]; |
5269 |
+ u16 nhm_tx_cnt; |
5270 |
+ u16 nhm_cca_cnt; |
5271 |
+ u16 nhm_idle_cnt; |
5272 |
+ u16 ifs_clm_tx; |
5273 |
+ u16 ifs_clm_edcca_excl_cca; |
5274 |
+ u16 ifs_clm_ofdmfa; |
5275 |
+ u16 ifs_clm_ofdmcca_excl_fa; |
5276 |
+ u16 ifs_clm_cckfa; |
5277 |
+ u16 ifs_clm_cckcca_excl_fa; |
5278 |
+ u16 ifs_clm_total_ifs; |
5279 |
+ u8 ifs_clm_his[RTW89_IFS_CLM_NUM]; |
5280 |
+ u16 ifs_clm_avg[RTW89_IFS_CLM_NUM]; |
5281 |
+ u16 ifs_clm_cca[RTW89_IFS_CLM_NUM]; |
5282 |
+ u16 fahm_result[RTW89_FAHM_RPT_NUM]; |
5283 |
+ u16 fahm_denom_result; |
5284 |
+ u16 edcca_clm_result; |
5285 |
+ u8 clm_ratio; |
5286 |
+ u8 nhm_rpt[RTW89_NHM_RPT_NUM]; |
5287 |
+ u8 nhm_tx_ratio; |
5288 |
+ u8 nhm_cca_ratio; |
5289 |
+ u8 nhm_idle_ratio; |
5290 |
+ u8 nhm_ratio; |
5291 |
+ u16 nhm_result_sum; |
5292 |
+ u8 nhm_pwr; |
5293 |
+ u8 ifs_clm_tx_ratio; |
5294 |
+ u8 ifs_clm_edcca_excl_cca_ratio; |
5295 |
+ u8 ifs_clm_cck_fa_ratio; |
5296 |
+ u8 ifs_clm_ofdm_fa_ratio; |
5297 |
+ u8 ifs_clm_cck_cca_excl_fa_ratio; |
5298 |
+ u8 ifs_clm_ofdm_cca_excl_fa_ratio; |
5299 |
+ u16 ifs_clm_cck_fa_permil; |
5300 |
+ u16 ifs_clm_ofdm_fa_permil; |
5301 |
+ u32 ifs_clm_ifs_avg[RTW89_IFS_CLM_NUM]; |
5302 |
+ u32 ifs_clm_cca_avg[RTW89_IFS_CLM_NUM]; |
5303 |
+ u8 fahm_rpt[RTW89_FAHM_RPT_NUM]; |
5304 |
+ u16 fahm_result_sum; |
5305 |
+ u8 fahm_ratio; |
5306 |
+ u8 fahm_denom_ratio; |
5307 |
+ u8 fahm_pwr; |
5308 |
+ u8 edcca_clm_ratio; |
5309 |
+}; |
5310 |
+ |
5311 |
+enum rtw89_ser_rcvy_step { |
5312 |
+ RTW89_SER_DRV_STOP_TX, |
5313 |
+ RTW89_SER_DRV_STOP_RX, |
5314 |
+ RTW89_SER_DRV_STOP_RUN, |
5315 |
+ RTW89_SER_HAL_STOP_DMA, |
5316 |
+ RTW89_NUM_OF_SER_FLAGS |
5317 |
+}; |
5318 |
+ |
5319 |
+struct rtw89_ser { |
5320 |
+ u8 state; |
5321 |
+ u8 alarm_event; |
5322 |
+ |
5323 |
+ struct work_struct ser_hdl_work; |
5324 |
+ struct delayed_work ser_alarm_work; |
5325 |
+ struct state_ent *st_tbl; |
5326 |
+ struct event_ent *ev_tbl; |
5327 |
+ struct list_head msg_q; |
5328 |
+ spinlock_t msg_q_lock; /* lock when read/write ser msg */ |
5329 |
+ DECLARE_BITMAP(flags, RTW89_NUM_OF_SER_FLAGS); |
5330 |
+}; |
5331 |
+ |
5332 |
+enum rtw89_mac_ax_ps_mode { |
5333 |
+ RTW89_MAC_AX_PS_MODE_ACTIVE = 0, |
5334 |
+ RTW89_MAC_AX_PS_MODE_LEGACY = 1, |
5335 |
+ RTW89_MAC_AX_PS_MODE_WMMPS = 2, |
5336 |
+ RTW89_MAC_AX_PS_MODE_MAX = 3, |
5337 |
+}; |
5338 |
+ |
5339 |
+enum rtw89_last_rpwm_mode { |
5340 |
+ RTW89_LAST_RPWM_PS = 0x0, |
5341 |
+ RTW89_LAST_RPWM_ACTIVE = 0x6, |
5342 |
+}; |
5343 |
+ |
5344 |
+struct rtw89_lps_parm { |
5345 |
+ u8 macid; |
5346 |
+ u8 psmode; /* enum rtw89_mac_ax_ps_mode */ |
5347 |
+ u8 lastrpwm; /* enum rtw89_last_rpwm_mode */ |
5348 |
+}; |
5349 |
+ |
5350 |
+struct rtw89_ppdu_sts_info { |
5351 |
+ struct sk_buff_head rx_queue[RTW89_PHY_MAX]; |
5352 |
+ u8 curr_rx_ppdu_cnt[RTW89_PHY_MAX]; |
5353 |
+}; |
5354 |
+ |
5355 |
+struct rtw89_early_h2c { |
5356 |
+ struct list_head list; |
5357 |
+ u8 *h2c; |
5358 |
+ u16 h2c_len; |
5359 |
+}; |
5360 |
+ |
5361 |
+struct rtw89_dev { |
5362 |
+ struct ieee80211_hw *hw; |
5363 |
+ struct device *dev; |
5364 |
+ |
5365 |
+ bool dbcc_en; |
5366 |
+ const struct rtw89_chip_info *chip; |
5367 |
+ struct rtw89_hal hal; |
5368 |
+ struct rtw89_mac_info mac; |
5369 |
+ struct rtw89_fw_info fw; |
5370 |
+ struct rtw89_hci_info hci; |
5371 |
+ struct rtw89_efuse efuse; |
5372 |
+ struct rtw89_traffic_stats stats; |
5373 |
+ |
5374 |
+ /* ensures exclusive access from mac80211 callbacks */ |
5375 |
+ struct mutex mutex; |
5376 |
+ struct list_head rtwvifs_list; |
5377 |
+ /* used to protect rf read write */ |
5378 |
+ struct mutex rf_mutex; |
5379 |
+ struct workqueue_struct *txq_wq; |
5380 |
+ struct work_struct txq_work; |
5381 |
+ struct delayed_work txq_reinvoke_work; |
5382 |
+ /* used to protect ba_list */ |
5383 |
+ spinlock_t ba_lock; |
5384 |
+ /* txqs to setup ba session */ |
5385 |
+ struct list_head ba_list; |
5386 |
+ struct work_struct ba_work; |
5387 |
+ |
5388 |
+ struct rtw89_cam_info cam_info; |
5389 |
+ |
5390 |
+ struct sk_buff_head c2h_queue; |
5391 |
+ struct work_struct c2h_work; |
5392 |
+ |
5393 |
+ struct list_head early_h2c_list; |
5394 |
+ |
5395 |
+ struct rtw89_ser ser; |
5396 |
+ |
5397 |
+ DECLARE_BITMAP(hw_port, RTW89_MAX_HW_PORT_NUM); |
5398 |
+ DECLARE_BITMAP(mac_id_map, RTW89_MAX_MAC_ID_NUM); |
5399 |
+ DECLARE_BITMAP(flags, NUM_OF_RTW89_FLAGS); |
5400 |
+ |
5401 |
+ struct rtw89_phy_stat phystat; |
5402 |
+ struct rtw89_dack_info dack; |
5403 |
+ struct rtw89_iqk_info iqk; |
5404 |
+ struct rtw89_dpk_info dpk; |
5405 |
+ bool is_tssi_mode[RF_PATH_MAX]; |
5406 |
+ bool is_bt_iqk_timeout; |
5407 |
+ |
5408 |
+ struct rtw89_fem_info fem; |
5409 |
+ struct rtw89_txpwr_byrate byr[RTW89_BAND_MAX]; |
5410 |
+ struct rtw89_tssi_info tssi; |
5411 |
+ struct rtw89_power_trim_info pwr_trim; |
5412 |
+ |
5413 |
+ struct rtw89_cfo_tracking_info cfo_tracking; |
5414 |
+ struct rtw89_env_monitor_info env_monitor; |
5415 |
+ struct rtw89_dig_info dig; |
5416 |
+ struct rtw89_phy_ch_info ch_info; |
5417 |
+ struct delayed_work track_work; |
5418 |
+ struct delayed_work coex_act1_work; |
5419 |
+ struct delayed_work coex_bt_devinfo_work; |
5420 |
+ struct delayed_work coex_rfk_chk_work; |
5421 |
+ struct delayed_work cfo_track_work; |
5422 |
+ struct rtw89_ppdu_sts_info ppdu_sts; |
5423 |
+ u8 total_sta_assoc; |
5424 |
+ bool scanning; |
5425 |
+ |
5426 |
+ const struct rtw89_regulatory *regd; |
5427 |
+ struct rtw89_sar_info sar; |
5428 |
+ |
5429 |
+ struct rtw89_btc btc; |
5430 |
+ enum rtw89_ps_mode ps_mode; |
5431 |
+ bool lps_enabled; |
5432 |
+ |
5433 |
+ /* napi structure */ |
5434 |
+ struct net_device netdev; |
5435 |
+ struct napi_struct napi; |
5436 |
+ int napi_budget_countdown; |
5437 |
+ |
5438 |
+ /* HCI related data, keep last */ |
5439 |
+ u8 priv[0] __aligned(sizeof(void *)); |
5440 |
+}; |
5441 |
+ |
5442 |
+static inline int rtw89_hci_tx_write(struct rtw89_dev *rtwdev, |
5443 |
+ struct rtw89_core_tx_request *tx_req) |
5444 |
+{ |
5445 |
+ return rtwdev->hci.ops->tx_write(rtwdev, tx_req); |
5446 |
+} |
5447 |
+ |
5448 |
+static inline void rtw89_hci_reset(struct rtw89_dev *rtwdev) |
5449 |
+{ |
5450 |
+ rtwdev->hci.ops->reset(rtwdev); |
5451 |
+} |
5452 |
+ |
5453 |
+static inline int rtw89_hci_start(struct rtw89_dev *rtwdev) |
5454 |
+{ |
5455 |
+ return rtwdev->hci.ops->start(rtwdev); |
5456 |
+} |
5457 |
+ |
5458 |
+static inline void rtw89_hci_stop(struct rtw89_dev *rtwdev) |
5459 |
+{ |
5460 |
+ rtwdev->hci.ops->stop(rtwdev); |
5461 |
+} |
5462 |
+ |
5463 |
+static inline int rtw89_hci_deinit(struct rtw89_dev *rtwdev) |
5464 |
+{ |
5465 |
+ return rtwdev->hci.ops->deinit(rtwdev); |
5466 |
+} |
5467 |
+ |
5468 |
+static inline void rtw89_hci_recalc_int_mit(struct rtw89_dev *rtwdev) |
5469 |
+{ |
5470 |
+ rtwdev->hci.ops->recalc_int_mit(rtwdev); |
5471 |
+} |
5472 |
+ |
5473 |
+static inline u32 rtw89_hci_check_and_reclaim_tx_resource(struct rtw89_dev *rtwdev, u8 txch) |
5474 |
+{ |
5475 |
+ return rtwdev->hci.ops->check_and_reclaim_tx_resource(rtwdev, txch); |
5476 |
+} |
5477 |
+ |
5478 |
+static inline void rtw89_hci_tx_kick_off(struct rtw89_dev *rtwdev, u8 txch) |
5479 |
+{ |
5480 |
+ return rtwdev->hci.ops->tx_kick_off(rtwdev, txch); |
5481 |
+} |
5482 |
+ |
5483 |
+static inline void rtw89_hci_flush_queues(struct rtw89_dev *rtwdev, u32 queues, |
5484 |
+ bool drop) |
5485 |
+{ |
5486 |
+ if (rtwdev->hci.ops->flush_queues) |
5487 |
+ return rtwdev->hci.ops->flush_queues(rtwdev, queues, drop); |
5488 |
+} |
5489 |
+ |
5490 |
+static inline u8 rtw89_read8(struct rtw89_dev *rtwdev, u32 addr) |
5491 |
+{ |
5492 |
+ return rtwdev->hci.ops->read8(rtwdev, addr); |
5493 |
+} |
5494 |
+ |
5495 |
+static inline u16 rtw89_read16(struct rtw89_dev *rtwdev, u32 addr) |
5496 |
+{ |
5497 |
+ return rtwdev->hci.ops->read16(rtwdev, addr); |
5498 |
+} |
5499 |
+ |
5500 |
+static inline u32 rtw89_read32(struct rtw89_dev *rtwdev, u32 addr) |
5501 |
+{ |
5502 |
+ return rtwdev->hci.ops->read32(rtwdev, addr); |
5503 |
+} |
5504 |
+ |
5505 |
+static inline void rtw89_write8(struct rtw89_dev *rtwdev, u32 addr, u8 data) |
5506 |
+{ |
5507 |
+ rtwdev->hci.ops->write8(rtwdev, addr, data); |
5508 |
+} |
5509 |
+ |
5510 |
+static inline void rtw89_write16(struct rtw89_dev *rtwdev, u32 addr, u16 data) |
5511 |
+{ |
5512 |
+ rtwdev->hci.ops->write16(rtwdev, addr, data); |
5513 |
+} |
5514 |
+ |
5515 |
+static inline void rtw89_write32(struct rtw89_dev *rtwdev, u32 addr, u32 data) |
5516 |
+{ |
5517 |
+ rtwdev->hci.ops->write32(rtwdev, addr, data); |
5518 |
+} |
5519 |
+ |
5520 |
+static inline void |
5521 |
+rtw89_write8_set(struct rtw89_dev *rtwdev, u32 addr, u8 bit) |
5522 |
+{ |
5523 |
+ u8 val; |
5524 |
+ |
5525 |
+ val = rtw89_read8(rtwdev, addr); |
5526 |
+ rtw89_write8(rtwdev, addr, val | bit); |
5527 |
+} |
5528 |
+ |
5529 |
+static inline void |
5530 |
+rtw89_write16_set(struct rtw89_dev *rtwdev, u32 addr, u16 bit) |
5531 |
+{ |
5532 |
+ u16 val; |
5533 |
+ |
5534 |
+ val = rtw89_read16(rtwdev, addr); |
5535 |
+ rtw89_write16(rtwdev, addr, val | bit); |
5536 |
+} |
5537 |
+ |
5538 |
+static inline void |
5539 |
+rtw89_write32_set(struct rtw89_dev *rtwdev, u32 addr, u32 bit) |
5540 |
+{ |
5541 |
+ u32 val; |
5542 |
+ |
5543 |
+ val = rtw89_read32(rtwdev, addr); |
5544 |
+ rtw89_write32(rtwdev, addr, val | bit); |
5545 |
+} |
5546 |
+ |
5547 |
+static inline void |
5548 |
+rtw89_write8_clr(struct rtw89_dev *rtwdev, u32 addr, u8 bit) |
5549 |
+{ |
5550 |
+ u8 val; |
5551 |
+ |
5552 |
+ val = rtw89_read8(rtwdev, addr); |
5553 |
+ rtw89_write8(rtwdev, addr, val & ~bit); |
5554 |
+} |
5555 |
+ |
5556 |
+static inline void |
5557 |
+rtw89_write16_clr(struct rtw89_dev *rtwdev, u32 addr, u16 bit) |
5558 |
+{ |
5559 |
+ u16 val; |
5560 |
+ |
5561 |
+ val = rtw89_read16(rtwdev, addr); |
5562 |
+ rtw89_write16(rtwdev, addr, val & ~bit); |
5563 |
+} |
5564 |
+ |
5565 |
+static inline void |
5566 |
+rtw89_write32_clr(struct rtw89_dev *rtwdev, u32 addr, u32 bit) |
5567 |
+{ |
5568 |
+ u32 val; |
5569 |
+ |
5570 |
+ val = rtw89_read32(rtwdev, addr); |
5571 |
+ rtw89_write32(rtwdev, addr, val & ~bit); |
5572 |
+} |
5573 |
+ |
5574 |
+static inline u32 |
5575 |
+rtw89_read32_mask(struct rtw89_dev *rtwdev, u32 addr, u32 mask) |
5576 |
+{ |
5577 |
+ u32 shift = __ffs(mask); |
5578 |
+ u32 orig; |
5579 |
+ u32 ret; |
5580 |
+ |
5581 |
+ orig = rtw89_read32(rtwdev, addr); |
5582 |
+ ret = (orig & mask) >> shift; |
5583 |
+ |
5584 |
+ return ret; |
5585 |
+} |
5586 |
+ |
5587 |
+static inline u16 |
5588 |
+rtw89_read16_mask(struct rtw89_dev *rtwdev, u32 addr, u32 mask) |
5589 |
+{ |
5590 |
+ u32 shift = __ffs(mask); |
5591 |
+ u32 orig; |
5592 |
+ u32 ret; |
5593 |
+ |
5594 |
+ orig = rtw89_read16(rtwdev, addr); |
5595 |
+ ret = (orig & mask) >> shift; |
5596 |
+ |
5597 |
+ return ret; |
5598 |
+} |
5599 |
+ |
5600 |
+static inline u8 |
5601 |
+rtw89_read8_mask(struct rtw89_dev *rtwdev, u32 addr, u32 mask) |
5602 |
+{ |
5603 |
+ u32 shift = __ffs(mask); |
5604 |
+ u32 orig; |
5605 |
+ u32 ret; |
5606 |
+ |
5607 |
+ orig = rtw89_read8(rtwdev, addr); |
5608 |
+ ret = (orig & mask) >> shift; |
5609 |
+ |
5610 |
+ return ret; |
5611 |
+} |
5612 |
+ |
5613 |
+static inline void |
5614 |
+rtw89_write32_mask(struct rtw89_dev *rtwdev, u32 addr, u32 mask, u32 data) |
5615 |
+{ |
5616 |
+ u32 shift = __ffs(mask); |
5617 |
+ u32 orig; |
5618 |
+ u32 set; |
5619 |
+ |
5620 |
+ WARN(addr & 0x3, "should be 4-byte aligned, addr = 0x%08x\n", addr); |
5621 |
+ |
5622 |
+ orig = rtw89_read32(rtwdev, addr); |
5623 |
+ set = (orig & ~mask) | ((data << shift) & mask); |
5624 |
+ rtw89_write32(rtwdev, addr, set); |
5625 |
+} |
5626 |
+ |
5627 |
+static inline void |
5628 |
+rtw89_write16_mask(struct rtw89_dev *rtwdev, u32 addr, u32 mask, u16 data) |
5629 |
+{ |
5630 |
+ u32 shift; |
5631 |
+ u16 orig, set; |
5632 |
+ |
5633 |
+ mask &= 0xffff; |
5634 |
+ shift = __ffs(mask); |
5635 |
+ |
5636 |
+ orig = rtw89_read16(rtwdev, addr); |
5637 |
+ set = (orig & ~mask) | ((data << shift) & mask); |
5638 |
+ rtw89_write16(rtwdev, addr, set); |
5639 |
+} |
5640 |
+ |
5641 |
+static inline void |
5642 |
+rtw89_write8_mask(struct rtw89_dev *rtwdev, u32 addr, u32 mask, u8 data) |
5643 |
+{ |
5644 |
+ u32 shift; |
5645 |
+ u8 orig, set; |
5646 |
+ |
5647 |
+ mask &= 0xff; |
5648 |
+ shift = __ffs(mask); |
5649 |
+ |
5650 |
+ orig = rtw89_read8(rtwdev, addr); |
5651 |
+ set = (orig & ~mask) | ((data << shift) & mask); |
5652 |
+ rtw89_write8(rtwdev, addr, set); |
5653 |
+} |
5654 |
+ |
5655 |
+static inline u32 |
5656 |
+rtw89_read_rf(struct rtw89_dev *rtwdev, enum rtw89_rf_path rf_path, |
5657 |
+ u32 addr, u32 mask) |
5658 |
+{ |
5659 |
+ u32 val; |
5660 |
+ |
5661 |
+ mutex_lock(&rtwdev->rf_mutex); |
5662 |
+ val = rtwdev->chip->ops->read_rf(rtwdev, rf_path, addr, mask); |
5663 |
+ mutex_unlock(&rtwdev->rf_mutex); |
5664 |
+ |
5665 |
+ return val; |
5666 |
+} |
5667 |
+ |
5668 |
+static inline void |
5669 |
+rtw89_write_rf(struct rtw89_dev *rtwdev, enum rtw89_rf_path rf_path, |
5670 |
+ u32 addr, u32 mask, u32 data) |
5671 |
+{ |
5672 |
+ mutex_lock(&rtwdev->rf_mutex); |
5673 |
+ rtwdev->chip->ops->write_rf(rtwdev, rf_path, addr, mask, data); |
5674 |
+ mutex_unlock(&rtwdev->rf_mutex); |
5675 |
+} |
5676 |
+ |
5677 |
+static inline struct ieee80211_txq *rtw89_txq_to_txq(struct rtw89_txq *rtwtxq) |
5678 |
+{ |
5679 |
+ void *p = rtwtxq; |
5680 |
+ |
5681 |
+ return container_of(p, struct ieee80211_txq, drv_priv); |
5682 |
+} |
5683 |
+ |
5684 |
+static inline void rtw89_core_txq_init(struct rtw89_dev *rtwdev, |
5685 |
+ struct ieee80211_txq *txq) |
5686 |
+{ |
5687 |
+ struct rtw89_txq *rtwtxq; |
5688 |
+ |
5689 |
+ if (!txq) |
5690 |
+ return; |
5691 |
+ |
5692 |
+ rtwtxq = (struct rtw89_txq *)txq->drv_priv; |
5693 |
+ INIT_LIST_HEAD(&rtwtxq->list); |
5694 |
+} |
5695 |
+ |
5696 |
+static inline struct ieee80211_vif *rtwvif_to_vif(struct rtw89_vif *rtwvif) |
5697 |
+{ |
5698 |
+ void *p = rtwvif; |
5699 |
+ |
5700 |
+ return container_of(p, struct ieee80211_vif, drv_priv); |
5701 |
+} |
5702 |
+ |
5703 |
+static inline struct ieee80211_sta *rtwsta_to_sta(struct rtw89_sta *rtwsta) |
5704 |
+{ |
5705 |
+ void *p = rtwsta; |
5706 |
+ |
5707 |
+ return container_of(p, struct ieee80211_sta, drv_priv); |
5708 |
+} |
5709 |
+ |
5710 |
+static inline |
5711 |
+void rtw89_chip_set_channel_prepare(struct rtw89_dev *rtwdev, |
5712 |
+ struct rtw89_channel_help_params *p) |
5713 |
+{ |
5714 |
+ rtwdev->chip->ops->set_channel_help(rtwdev, true, p); |
5715 |
+} |
5716 |
+ |
5717 |
+static inline |
5718 |
+void rtw89_chip_set_channel_done(struct rtw89_dev *rtwdev, |
5719 |
+ struct rtw89_channel_help_params *p) |
5720 |
+{ |
5721 |
+ rtwdev->chip->ops->set_channel_help(rtwdev, false, p); |
5722 |
+} |
5723 |
+ |
5724 |
+static inline void rtw89_chip_fem_setup(struct rtw89_dev *rtwdev) |
5725 |
+{ |
5726 |
+ const struct rtw89_chip_info *chip = rtwdev->chip; |
5727 |
+ |
5728 |
+ if (chip->ops->fem_setup) |
5729 |
+ chip->ops->fem_setup(rtwdev); |
5730 |
+} |
5731 |
+ |
5732 |
+static inline void rtw89_chip_bb_sethw(struct rtw89_dev *rtwdev) |
5733 |
+{ |
5734 |
+ const struct rtw89_chip_info *chip = rtwdev->chip; |
5735 |
+ |
5736 |
+ if (chip->ops->bb_sethw) |
5737 |
+ chip->ops->bb_sethw(rtwdev); |
5738 |
+} |
5739 |
+ |
5740 |
+static inline void rtw89_chip_rfk_init(struct rtw89_dev *rtwdev) |
5741 |
+{ |
5742 |
+ const struct rtw89_chip_info *chip = rtwdev->chip; |
5743 |
+ |
5744 |
+ if (chip->ops->rfk_init) |
5745 |
+ chip->ops->rfk_init(rtwdev); |
5746 |
+} |
5747 |
+ |
5748 |
+static inline void rtw89_chip_rfk_channel(struct rtw89_dev *rtwdev) |
5749 |
+{ |
5750 |
+ const struct rtw89_chip_info *chip = rtwdev->chip; |
5751 |
+ |
5752 |
+ if (chip->ops->rfk_channel) |
5753 |
+ chip->ops->rfk_channel(rtwdev); |
5754 |
+} |
5755 |
+ |
5756 |
+static inline void rtw89_chip_rfk_band_changed(struct rtw89_dev *rtwdev) |
5757 |
+{ |
5758 |
+ const struct rtw89_chip_info *chip = rtwdev->chip; |
5759 |
+ |
5760 |
+ if (chip->ops->rfk_band_changed) |
5761 |
+ chip->ops->rfk_band_changed(rtwdev); |
5762 |
+} |
5763 |
+ |
5764 |
+static inline void rtw89_chip_rfk_scan(struct rtw89_dev *rtwdev, bool start) |
5765 |
+{ |
5766 |
+ const struct rtw89_chip_info *chip = rtwdev->chip; |
5767 |
+ |
5768 |
+ if (chip->ops->rfk_scan) |
5769 |
+ chip->ops->rfk_scan(rtwdev, start); |
5770 |
+} |
5771 |
+ |
5772 |
+static inline void rtw89_chip_rfk_track(struct rtw89_dev *rtwdev) |
5773 |
+{ |
5774 |
+ const struct rtw89_chip_info *chip = rtwdev->chip; |
5775 |
+ |
5776 |
+ if (chip->ops->rfk_track) |
5777 |
+ chip->ops->rfk_track(rtwdev); |
5778 |
+} |
5779 |
+ |
5780 |
+static inline void rtw89_chip_set_txpwr_ctrl(struct rtw89_dev *rtwdev) |
5781 |
+{ |
5782 |
+ const struct rtw89_chip_info *chip = rtwdev->chip; |
5783 |
+ |
5784 |
+ if (chip->ops->set_txpwr_ctrl) |
5785 |
+ chip->ops->set_txpwr_ctrl(rtwdev); |
5786 |
+} |
5787 |
+ |
5788 |
+static inline void rtw89_chip_set_txpwr(struct rtw89_dev *rtwdev) |
5789 |
+{ |
5790 |
+ const struct rtw89_chip_info *chip = rtwdev->chip; |
5791 |
+ u8 ch = rtwdev->hal.current_channel; |
5792 |
+ |
5793 |
+ if (!ch) |
5794 |
+ return; |
5795 |
+ |
5796 |
+ if (chip->ops->set_txpwr) |
5797 |
+ chip->ops->set_txpwr(rtwdev); |
5798 |
+} |
5799 |
+ |
5800 |
+static inline void rtw89_chip_power_trim(struct rtw89_dev *rtwdev) |
5801 |
+{ |
5802 |
+ const struct rtw89_chip_info *chip = rtwdev->chip; |
5803 |
+ |
5804 |
+ if (chip->ops->power_trim) |
5805 |
+ chip->ops->power_trim(rtwdev); |
5806 |
+} |
5807 |
+ |
5808 |
+static inline void rtw89_chip_init_txpwr_unit(struct rtw89_dev *rtwdev, |
5809 |
+ enum rtw89_phy_idx phy_idx) |
5810 |
+{ |
5811 |
+ const struct rtw89_chip_info *chip = rtwdev->chip; |
5812 |
+ |
5813 |
+ if (chip->ops->init_txpwr_unit) |
5814 |
+ chip->ops->init_txpwr_unit(rtwdev, phy_idx); |
5815 |
+} |
5816 |
+ |
5817 |
+static inline u8 rtw89_chip_get_thermal(struct rtw89_dev *rtwdev, |
5818 |
+ enum rtw89_rf_path rf_path) |
5819 |
+{ |
5820 |
+ const struct rtw89_chip_info *chip = rtwdev->chip; |
5821 |
+ |
5822 |
+ if (!chip->ops->get_thermal) |
5823 |
+ return 0x10; |
5824 |
+ |
5825 |
+ return chip->ops->get_thermal(rtwdev, rf_path); |
5826 |
+} |
5827 |
+ |
5828 |
+static inline void rtw89_chip_query_ppdu(struct rtw89_dev *rtwdev, |
5829 |
+ struct rtw89_rx_phy_ppdu *phy_ppdu, |
5830 |
+ struct ieee80211_rx_status *status) |
5831 |
+{ |
5832 |
+ const struct rtw89_chip_info *chip = rtwdev->chip; |
5833 |
+ |
5834 |
+ if (chip->ops->query_ppdu) |
5835 |
+ chip->ops->query_ppdu(rtwdev, phy_ppdu, status); |
5836 |
+} |
5837 |
+ |
5838 |
+static inline void rtw89_chip_bb_ctrl_btc_preagc(struct rtw89_dev *rtwdev, |
5839 |
+ bool bt_en) |
5840 |
+{ |
5841 |
+ const struct rtw89_chip_info *chip = rtwdev->chip; |
5842 |
+ |
5843 |
+ if (chip->ops->bb_ctrl_btc_preagc) |
5844 |
+ chip->ops->bb_ctrl_btc_preagc(rtwdev, bt_en); |
5845 |
+} |
5846 |
+ |
5847 |
+static inline |
5848 |
+void rtw89_chip_cfg_txpwr_ul_tb_offset(struct rtw89_dev *rtwdev, |
5849 |
+ struct ieee80211_vif *vif) |
5850 |
+{ |
5851 |
+ struct rtw89_vif *rtwvif = (struct rtw89_vif *)vif->drv_priv; |
5852 |
+ const struct rtw89_chip_info *chip = rtwdev->chip; |
5853 |
+ |
5854 |
+ if (!vif->bss_conf.he_support || !vif->bss_conf.assoc) |
5855 |
+ return; |
5856 |
+ |
5857 |
+ if (chip->ops->set_txpwr_ul_tb_offset) |
5858 |
+ chip->ops->set_txpwr_ul_tb_offset(rtwdev, 0, rtwvif->mac_idx); |
5859 |
+} |
5860 |
+ |
5861 |
+static inline void rtw89_load_txpwr_table(struct rtw89_dev *rtwdev, |
5862 |
+ const struct rtw89_txpwr_table *tbl) |
5863 |
+{ |
5864 |
+ tbl->load(rtwdev, tbl); |
5865 |
+} |
5866 |
+ |
5867 |
+static inline u8 rtw89_regd_get(struct rtw89_dev *rtwdev, u8 band) |
5868 |
+{ |
5869 |
+ return rtwdev->regd->txpwr_regd[band]; |
5870 |
+} |
5871 |
+ |
5872 |
+static inline void rtw89_ctrl_btg(struct rtw89_dev *rtwdev, bool btg) |
5873 |
+{ |
5874 |
+ const struct rtw89_chip_info *chip = rtwdev->chip; |
5875 |
+ |
5876 |
+ if (chip->ops->ctrl_btg) |
5877 |
+ chip->ops->ctrl_btg(rtwdev, btg); |
5878 |
+} |
5879 |
+ |
5880 |
+static inline u8 *get_hdr_bssid(struct ieee80211_hdr *hdr) |
5881 |
+{ |
5882 |
+ __le16 fc = hdr->frame_control; |
5883 |
+ |
5884 |
+ if (ieee80211_has_tods(fc)) |
5885 |
+ return hdr->addr1; |
5886 |
+ else if (ieee80211_has_fromds(fc)) |
5887 |
+ return hdr->addr2; |
5888 |
+ else |
5889 |
+ return hdr->addr3; |
5890 |
+} |
5891 |
+ |
5892 |
+static inline bool rtw89_sta_has_beamformer_cap(struct ieee80211_sta *sta) |
5893 |
+{ |
5894 |
+ if ((sta->vht_cap.cap & IEEE80211_VHT_CAP_MU_BEAMFORMER_CAPABLE) || |
5895 |
+ (sta->vht_cap.cap & IEEE80211_VHT_CAP_SU_BEAMFORMER_CAPABLE) || |
5896 |
+ (sta->he_cap.he_cap_elem.phy_cap_info[3] & IEEE80211_HE_PHY_CAP3_SU_BEAMFORMER) || |
5897 |
+ (sta->he_cap.he_cap_elem.phy_cap_info[4] & IEEE80211_HE_PHY_CAP4_MU_BEAMFORMER)) |
5898 |
+ return true; |
5899 |
+ return false; |
5900 |
+} |
5901 |
+ |
5902 |
+static inline struct rtw89_fw_suit *rtw89_fw_suit_get(struct rtw89_dev *rtwdev, |
5903 |
+ enum rtw89_fw_type type) |
5904 |
+{ |
5905 |
+ struct rtw89_fw_info *fw_info = &rtwdev->fw; |
5906 |
+ |
5907 |
+ if (type == RTW89_FW_WOWLAN) |
5908 |
+ return &fw_info->wowlan; |
5909 |
+ return &fw_info->normal; |
5910 |
+} |
5911 |
+ |
5912 |
+int rtw89_core_tx_write(struct rtw89_dev *rtwdev, struct ieee80211_vif *vif, |
5913 |
+ struct ieee80211_sta *sta, struct sk_buff *skb, int *qsel); |
5914 |
+int rtw89_h2c_tx(struct rtw89_dev *rtwdev, |
5915 |
+ struct sk_buff *skb, bool fwdl); |
5916 |
+void rtw89_core_tx_kick_off(struct rtw89_dev *rtwdev, u8 qsel); |
5917 |
+void rtw89_core_fill_txdesc(struct rtw89_dev *rtwdev, |
5918 |
+ struct rtw89_tx_desc_info *desc_info, |
5919 |
+ void *txdesc); |
5920 |
+void rtw89_core_rx(struct rtw89_dev *rtwdev, |
5921 |
+ struct rtw89_rx_desc_info *desc_info, |
5922 |
+ struct sk_buff *skb); |
5923 |
+void rtw89_core_query_rxdesc(struct rtw89_dev *rtwdev, |
5924 |
+ struct rtw89_rx_desc_info *desc_info, |
5925 |
+ u8 *data, u32 data_offset); |
5926 |
+void rtw89_core_napi_start(struct rtw89_dev *rtwdev); |
5927 |
+void rtw89_core_napi_stop(struct rtw89_dev *rtwdev); |
5928 |
+void rtw89_core_napi_init(struct rtw89_dev *rtwdev); |
5929 |
+void rtw89_core_napi_deinit(struct rtw89_dev *rtwdev); |
5930 |
+int rtw89_core_sta_add(struct rtw89_dev *rtwdev, |
5931 |
+ struct ieee80211_vif *vif, |
5932 |
+ struct ieee80211_sta *sta); |
5933 |
+int rtw89_core_sta_assoc(struct rtw89_dev *rtwdev, |
5934 |
+ struct ieee80211_vif *vif, |
5935 |
+ struct ieee80211_sta *sta); |
5936 |
+int rtw89_core_sta_disassoc(struct rtw89_dev *rtwdev, |
5937 |
+ struct ieee80211_vif *vif, |
5938 |
+ struct ieee80211_sta *sta); |
5939 |
+int rtw89_core_sta_disconnect(struct rtw89_dev *rtwdev, |
5940 |
+ struct ieee80211_vif *vif, |
5941 |
+ struct ieee80211_sta *sta); |
5942 |
+int rtw89_core_sta_remove(struct rtw89_dev *rtwdev, |
5943 |
+ struct ieee80211_vif *vif, |
5944 |
+ struct ieee80211_sta *sta); |
5945 |
+int rtw89_core_init(struct rtw89_dev *rtwdev); |
5946 |
+void rtw89_core_deinit(struct rtw89_dev *rtwdev); |
5947 |
+int rtw89_core_register(struct rtw89_dev *rtwdev); |
5948 |
+void rtw89_core_unregister(struct rtw89_dev *rtwdev); |
5949 |
+void rtw89_set_channel(struct rtw89_dev *rtwdev); |
5950 |
+u8 rtw89_core_acquire_bit_map(unsigned long *addr, unsigned long size); |
5951 |
+void rtw89_core_release_bit_map(unsigned long *addr, u8 bit); |
5952 |
+void rtw89_core_release_all_bits_map(unsigned long *addr, unsigned int nbits); |
5953 |
+void rtw89_vif_type_mapping(struct ieee80211_vif *vif, bool assoc); |
5954 |
+int rtw89_chip_info_setup(struct rtw89_dev *rtwdev); |
5955 |
+u16 rtw89_ra_report_to_bitrate(struct rtw89_dev *rtwdev, u8 rpt_rate); |
5956 |
+int rtw89_regd_init(struct rtw89_dev *rtwdev, |
5957 |
+ void (*reg_notifier)(struct wiphy *wiphy, struct regulatory_request *request)); |
5958 |
+void rtw89_regd_notifier(struct wiphy *wiphy, struct regulatory_request *request); |
5959 |
+void rtw89_traffic_stats_init(struct rtw89_dev *rtwdev, |
5960 |
+ struct rtw89_traffic_stats *stats); |
5961 |
+int rtw89_core_start(struct rtw89_dev *rtwdev); |
5962 |
+void rtw89_core_stop(struct rtw89_dev *rtwdev); |
5963 |
+ |
5964 |
+#endif |
5965 |
diff --git a/drivers/net/wireless/realtek/rtw89/txrx.h b/drivers/net/wireless/realtek/rtw89/txrx.h |
5966 |
new file mode 100644 |
5967 |
index 000000000000..f1e0fe36107d |
5968 |
--- /dev/null |
5969 |
+++ b/drivers/net/wireless/realtek/rtw89/txrx.h |
5970 |
@@ -0,0 +1,358 @@ |
5971 |
+/* SPDX-License-Identifier: GPL-2.0 OR BSD-3-Clause */ |
5972 |
+/* Copyright(c) 2020 Realtek Corporation |
5973 |
+ */ |
5974 |
+ |
5975 |
+#ifndef __RTW89_TXRX_H__ |
5976 |
+#define __RTW89_TXRX_H__ |
5977 |
+ |
5978 |
+#include "debug.h" |
5979 |
+ |
5980 |
+#define DATA_RATE_MODE_CTRL_MASK GENMASK(8, 7) |
5981 |
+#define DATA_RATE_NOT_HT_IDX_MASK GENMASK(3, 0) |
5982 |
+#define DATA_RATE_MODE_NON_HT 0x0 |
5983 |
+#define DATA_RATE_HT_IDX_MASK GENMASK(4, 0) |
5984 |
+#define DATA_RATE_MODE_HT 0x1 |
5985 |
+#define DATA_RATE_VHT_HE_NSS_MASK GENMASK(6, 4) |
5986 |
+#define DATA_RATE_VHT_HE_IDX_MASK GENMASK(3, 0) |
5987 |
+#define DATA_RATE_MODE_VHT 0x2 |
5988 |
+#define DATA_RATE_MODE_HE 0x3 |
5989 |
+#define GET_DATA_RATE_MODE(r) FIELD_GET(DATA_RATE_MODE_CTRL_MASK, r) |
5990 |
+#define GET_DATA_RATE_NOT_HT_IDX(r) FIELD_GET(DATA_RATE_NOT_HT_IDX_MASK, r) |
5991 |
+#define GET_DATA_RATE_HT_IDX(r) FIELD_GET(DATA_RATE_HT_IDX_MASK, r) |
5992 |
+#define GET_DATA_RATE_VHT_HE_IDX(r) FIELD_GET(DATA_RATE_VHT_HE_IDX_MASK, r) |
5993 |
+#define GET_DATA_RATE_NSS(r) FIELD_GET(DATA_RATE_VHT_HE_NSS_MASK, r) |
5994 |
+ |
5995 |
+/* TX WD BODY DWORD 0 */ |
5996 |
+#define RTW89_TXWD_BODY0_WP_OFFSET GENMASK(31, 24) |
5997 |
+#define RTW89_TXWD_BODY0_MORE_DATA BIT(23) |
5998 |
+#define RTW89_TXWD_BODY0_WD_INFO_EN BIT(22) |
5999 |
+#define RTW89_TXWD_BODY0_FW_DL BIT(20) |
6000 |
+#define RTW89_TXWD_BODY0_CHANNEL_DMA GENMASK(19, 16) |
6001 |
+#define RTW89_TXWD_BODY0_HDR_LLC_LEN GENMASK(15, 11) |
6002 |
+#define RTW89_TXWD_BODY0_WD_PAGE BIT(7) |
6003 |
+#define RTW89_TXWD_BODY0_HW_AMSDU BIT(5) |
6004 |
+ |
6005 |
+/* TX WD BODY DWORD 1 */ |
6006 |
+#define RTW89_TXWD_BODY1_PAYLOAD_ID GENMASK(31, 16) |
6007 |
+ |
6008 |
+/* TX WD BODY DWORD 2 */ |
6009 |
+#define RTW89_TXWD_BODY2_MACID GENMASK(30, 24) |
6010 |
+#define RTW89_TXWD_BODY2_TID_INDICATE BIT(23) |
6011 |
+#define RTW89_TXWD_BODY2_QSEL GENMASK(22, 17) |
6012 |
+#define RTW89_TXWD_BODY2_TXPKT_SIZE GENMASK(13, 0) |
6013 |
+ |
6014 |
+/* TX WD BODY DWORD 3 */ |
6015 |
+#define RTW89_TXWD_BODY3_BK BIT(13) |
6016 |
+#define RTW89_TXWD_BODY3_AGG_EN BIT(12) |
6017 |
+#define RTW89_TXWD_BODY3_SW_SEQ GENMASK(11, 0) |
6018 |
+ |
6019 |
+/* TX WD BODY DWORD 4 */ |
6020 |
+ |
6021 |
+/* TX WD BODY DWORD 5 */ |
6022 |
+ |
6023 |
+/* TX WD INFO DWORD 0 */ |
6024 |
+#define RTW89_TXWD_INFO0_USE_RATE BIT(30) |
6025 |
+#define RTW89_TXWD_INFO0_DATA_BW GENMASK(29, 28) |
6026 |
+#define RTW89_TXWD_INFO0_GI_LTF GENMASK(27, 25) |
6027 |
+#define RTW89_TXWD_INFO0_DATA_RATE GENMASK(24, 16) |
6028 |
+#define RTW89_TXWD_INFO0_DISDATAFB BIT(10) |
6029 |
+ |
6030 |
+/* TX WD INFO DWORD 1 */ |
6031 |
+#define RTW89_TXWD_INFO1_DATA_RTY_LOWEST_RATE GENMASK(24, 16) |
6032 |
+#define RTW89_TXWD_INFO1_A_CTRL_BSR BIT(14) |
6033 |
+#define RTW89_TXWD_INFO1_MAX_AGGNUM GENMASK(7, 0) |
6034 |
+ |
6035 |
+/* TX WD INFO DWORD 2 */ |
6036 |
+#define RTW89_TXWD_INFO2_AMPDU_DENSITY GENMASK(20, 18) |
6037 |
+#define RTW89_TXWD_INFO2_SEC_TYPE GENMASK(12, 9) |
6038 |
+#define RTW89_TXWD_INFO2_SEC_HW_ENC BIT(8) |
6039 |
+#define RTW89_TXWD_INFO2_SEC_CAM_IDX GENMASK(7, 0) |
6040 |
+ |
6041 |
+/* TX WD INFO DWORD 3 */ |
6042 |
+ |
6043 |
+/* TX WD INFO DWORD 4 */ |
6044 |
+#define RTW89_TXWD_INFO4_RTS_EN BIT(27) |
6045 |
+#define RTW89_TXWD_INFO4_HW_RTS_EN BIT(31) |
6046 |
+ |
6047 |
+/* TX WD INFO DWORD 5 */ |
6048 |
+ |
6049 |
+/* RX DESC helpers */ |
6050 |
+/* Short Descriptor */ |
6051 |
+#define RTW89_GET_RXWD_LONG_RXD(rxdesc) \ |
6052 |
+ le32_get_bits((rxdesc)->dword0, BIT(31)) |
6053 |
+#define RTW89_GET_RXWD_DRV_INFO_SIZE(rxdesc) \ |
6054 |
+ le32_get_bits((rxdesc)->dword0, GENMASK(30, 28)) |
6055 |
+#define RTW89_GET_RXWD_RPKT_TYPE(rxdesc) \ |
6056 |
+ le32_get_bits((rxdesc)->dword0, GENMASK(27, 24)) |
6057 |
+#define RTW89_GET_RXWD_MAC_INFO_VALID(rxdesc) \ |
6058 |
+ le32_get_bits((rxdesc)->dword0, BIT(23)) |
6059 |
+#define RTW89_GET_RXWD_BB_SEL(rxdesc) \ |
6060 |
+ le32_get_bits((rxdesc)->dword0, BIT(22)) |
6061 |
+#define RTW89_GET_RXWD_HD_IV_LEN(rxdesc) \ |
6062 |
+ le32_get_bits((rxdesc)->dword0, GENMASK(21, 16)) |
6063 |
+#define RTW89_GET_RXWD_SHIFT(rxdesc) \ |
6064 |
+ le32_get_bits((rxdesc)->dword0, GENMASK(15, 14)) |
6065 |
+#define RTW89_GET_RXWD_PKT_SIZE(rxdesc) \ |
6066 |
+ le32_get_bits((rxdesc)->dword0, GENMASK(13, 0)) |
6067 |
+#define RTW89_GET_RXWD_BW(rxdesc) \ |
6068 |
+ le32_get_bits((rxdesc)->dword1, GENMASK(31, 30)) |
6069 |
+#define RTW89_GET_RXWD_GI_LTF(rxdesc) \ |
6070 |
+ le32_get_bits((rxdesc)->dword1, GENMASK(27, 25)) |
6071 |
+#define RTW89_GET_RXWD_DATA_RATE(rxdesc) \ |
6072 |
+ le32_get_bits((rxdesc)->dword1, GENMASK(24, 16)) |
6073 |
+#define RTW89_GET_RXWD_USER_ID(rxdesc) \ |
6074 |
+ le32_get_bits((rxdesc)->dword1, GENMASK(15, 8)) |
6075 |
+#define RTW89_GET_RXWD_SR_EN(rxdesc) \ |
6076 |
+ le32_get_bits((rxdesc)->dword1, BIT(7)) |
6077 |
+#define RTW89_GET_RXWD_PPDU_CNT(rxdesc) \ |
6078 |
+ le32_get_bits((rxdesc)->dword1, GENMASK(6, 4)) |
6079 |
+#define RTW89_GET_RXWD_PPDU_TYPE(rxdesc) \ |
6080 |
+ le32_get_bits((rxdesc)->dword1, GENMASK(3, 0)) |
6081 |
+#define RTW89_GET_RXWD_FREE_RUN_CNT(rxdesc) \ |
6082 |
+ le32_get_bits((rxdesc)->dword2, GENMASK(31, 0)) |
6083 |
+#define RTW89_GET_RXWD_ICV_ERR(rxdesc) \ |
6084 |
+ le32_get_bits((rxdesc)->dword3, BIT(10)) |
6085 |
+#define RTW89_GET_RXWD_CRC32_ERR(rxdesc) \ |
6086 |
+ le32_get_bits((rxdesc)->dword3, BIT(9)) |
6087 |
+#define RTW89_GET_RXWD_HW_DEC(rxdesc) \ |
6088 |
+ le32_get_bits((rxdesc)->dword3, BIT(2)) |
6089 |
+#define RTW89_GET_RXWD_SW_DEC(rxdesc) \ |
6090 |
+ le32_get_bits((rxdesc)->dword3, BIT(1)) |
6091 |
+#define RTW89_GET_RXWD_A1_MATCH(rxdesc) \ |
6092 |
+ le32_get_bits((rxdesc)->dword3, BIT(0)) |
6093 |
+ |
6094 |
+/* Long Descriptor */ |
6095 |
+#define RTW89_GET_RXWD_FRAG(rxdesc) \ |
6096 |
+ le32_get_bits((rxdesc)->dword4, GENMASK(31, 28)) |
6097 |
+#define RTW89_GET_RXWD_SEQ(rxdesc) \ |
6098 |
+ le32_get_bits((rxdesc)->dword4, GENMASK(27, 16)) |
6099 |
+#define RTW89_GET_RXWD_TYPE(rxdesc) \ |
6100 |
+ le32_get_bits((rxdesc)->dword4, GENMASK(1, 0)) |
6101 |
+#define RTW89_GET_RXWD_ADDR_CAM_VLD(rxdesc) \ |
6102 |
+ le32_get_bits((rxdesc)->dword5, BIT(28)) |
6103 |
+#define RTW89_GET_RXWD_RX_PL_ID(rxdesc) \ |
6104 |
+ le32_get_bits((rxdesc)->dword5, GENMASK(27, 24)) |
6105 |
+#define RTW89_GET_RXWD_MAC_ID(rxdesc) \ |
6106 |
+ le32_get_bits((rxdesc)->dword5, GENMASK(23, 16)) |
6107 |
+#define RTW89_GET_RXWD_ADDR_CAM_ID(rxdesc) \ |
6108 |
+ le32_get_bits((rxdesc)->dword5, GENMASK(15, 8)) |
6109 |
+#define RTW89_GET_RXWD_SEC_CAM_ID(rxdesc) \ |
6110 |
+ le32_get_bits((rxdesc)->dword5, GENMASK(7, 0)) |
6111 |
+ |
6112 |
+#define RTW89_GET_RXINFO_USR_NUM(rpt) \ |
6113 |
+ le32_get_bits(*((__le32 *)rpt), GENMASK(3, 0)) |
6114 |
+#define RTW89_GET_RXINFO_FW_DEFINE(rpt) \ |
6115 |
+ le32_get_bits(*((__le32 *)rpt), GENMASK(15, 8)) |
6116 |
+#define RTW89_GET_RXINFO_LSIG_LEN(rpt) \ |
6117 |
+ le32_get_bits(*((__le32 *)rpt), GENMASK(27, 16)) |
6118 |
+#define RTW89_GET_RXINFO_IS_TO_SELF(rpt) \ |
6119 |
+ le32_get_bits(*((__le32 *)rpt), BIT(28)) |
6120 |
+#define RTW89_GET_RXINFO_RX_CNT_VLD(rpt) \ |
6121 |
+ le32_get_bits(*((__le32 *)rpt), BIT(29)) |
6122 |
+#define RTW89_GET_RXINFO_LONG_RXD(rpt) \ |
6123 |
+ le32_get_bits(*((__le32 *)rpt), GENMASK(31, 30)) |
6124 |
+#define RTW89_GET_RXINFO_SERVICE(rpt) \ |
6125 |
+ le32_get_bits(*((__le32 *)(rpt) + 1), GENMASK(15, 0)) |
6126 |
+#define RTW89_GET_RXINFO_PLCP_LEN(rpt) \ |
6127 |
+ le32_get_bits(*((__le32 *)(rpt) + 1), GENMASK(23, 16)) |
6128 |
+#define RTW89_GET_RXINFO_MAC_ID_VALID(rpt, usr) \ |
6129 |
+ le32_get_bits(*((__le32 *)(rpt) + (usr) + 2), BIT(0)) |
6130 |
+#define RTW89_GET_RXINFO_DATA(rpt, usr) \ |
6131 |
+ le32_get_bits(*((__le32 *)(rpt) + (usr) + 2), BIT(1)) |
6132 |
+#define RTW89_GET_RXINFO_CTRL(rpt, usr) \ |
6133 |
+ le32_get_bits(*((__le32 *)(rpt) + (usr) + 2), BIT(2)) |
6134 |
+#define RTW89_GET_RXINFO_MGMT(rpt, usr) \ |
6135 |
+ le32_get_bits(*((__le32 *)(rpt) + (usr) + 2), BIT(3)) |
6136 |
+#define RTW89_GET_RXINFO_BCM(rpt, usr) \ |
6137 |
+ le32_get_bits(*((__le32 *)(rpt) + (usr) + 2), BIT(4)) |
6138 |
+#define RTW89_GET_RXINFO_MACID(rpt, usr) \ |
6139 |
+ le32_get_bits(*((__le32 *)(rpt) + (usr) + 2), GENMASK(15, 8)) |
6140 |
+ |
6141 |
+#define RTW89_GET_PHY_STS_RSSI_A(sts) \ |
6142 |
+ le32_get_bits(*((__le32 *)(sts) + 1), GENMASK(7, 0)) |
6143 |
+#define RTW89_GET_PHY_STS_RSSI_B(sts) \ |
6144 |
+ le32_get_bits(*((__le32 *)(sts) + 1), GENMASK(15, 8)) |
6145 |
+#define RTW89_GET_PHY_STS_RSSI_C(sts) \ |
6146 |
+ le32_get_bits(*((__le32 *)(sts) + 1), GENMASK(23, 16)) |
6147 |
+#define RTW89_GET_PHY_STS_RSSI_D(sts) \ |
6148 |
+ le32_get_bits(*((__le32 *)(sts) + 1), GENMASK(31, 24)) |
6149 |
+#define RTW89_GET_PHY_STS_LEN(sts) \ |
6150 |
+ le32_get_bits(*((__le32 *)sts), GENMASK(15, 8)) |
6151 |
+#define RTW89_GET_PHY_STS_RSSI_AVG(sts) \ |
6152 |
+ le32_get_bits(*((__le32 *)sts), GENMASK(31, 24)) |
6153 |
+#define RTW89_GET_PHY_STS_IE_TYPE(ie) \ |
6154 |
+ le32_get_bits(*((__le32 *)ie), GENMASK(4, 0)) |
6155 |
+#define RTW89_GET_PHY_STS_IE_LEN(ie) \ |
6156 |
+ le32_get_bits(*((__le32 *)ie), GENMASK(11, 5)) |
6157 |
+#define RTW89_GET_PHY_STS_IE0_CFO(ie) \ |
6158 |
+ le32_get_bits(*((__le32 *)(ie) + 1), GENMASK(31, 20)) |
6159 |
+ |
6160 |
+enum rtw89_tx_channel { |
6161 |
+ RTW89_TXCH_ACH0 = 0, |
6162 |
+ RTW89_TXCH_ACH1 = 1, |
6163 |
+ RTW89_TXCH_ACH2 = 2, |
6164 |
+ RTW89_TXCH_ACH3 = 3, |
6165 |
+ RTW89_TXCH_ACH4 = 4, |
6166 |
+ RTW89_TXCH_ACH5 = 5, |
6167 |
+ RTW89_TXCH_ACH6 = 6, |
6168 |
+ RTW89_TXCH_ACH7 = 7, |
6169 |
+ RTW89_TXCH_CH8 = 8, /* MGMT Band 0 */ |
6170 |
+ RTW89_TXCH_CH9 = 9, /* HI Band 0 */ |
6171 |
+ RTW89_TXCH_CH10 = 10, /* MGMT Band 1 */ |
6172 |
+ RTW89_TXCH_CH11 = 11, /* HI Band 1 */ |
6173 |
+ RTW89_TXCH_CH12 = 12, /* FW CMD */ |
6174 |
+ |
6175 |
+ /* keep last */ |
6176 |
+ RTW89_TXCH_NUM, |
6177 |
+ RTW89_TXCH_MAX = RTW89_TXCH_NUM - 1 |
6178 |
+}; |
6179 |
+ |
6180 |
+enum rtw89_rx_channel { |
6181 |
+ RTW89_RXCH_RXQ = 0, |
6182 |
+ RTW89_RXCH_RPQ = 1, |
6183 |
+ |
6184 |
+ /* keep last */ |
6185 |
+ RTW89_RXCH_NUM, |
6186 |
+ RTW89_RXCH_MAX = RTW89_RXCH_NUM - 1 |
6187 |
+}; |
6188 |
+ |
6189 |
+enum rtw89_tx_qsel { |
6190 |
+ RTW89_TX_QSEL_BE_0 = 0x00, |
6191 |
+ RTW89_TX_QSEL_BK_0 = 0x01, |
6192 |
+ RTW89_TX_QSEL_VI_0 = 0x02, |
6193 |
+ RTW89_TX_QSEL_VO_0 = 0x03, |
6194 |
+ RTW89_TX_QSEL_BE_1 = 0x04, |
6195 |
+ RTW89_TX_QSEL_BK_1 = 0x05, |
6196 |
+ RTW89_TX_QSEL_VI_1 = 0x06, |
6197 |
+ RTW89_TX_QSEL_VO_1 = 0x07, |
6198 |
+ RTW89_TX_QSEL_BE_2 = 0x08, |
6199 |
+ RTW89_TX_QSEL_BK_2 = 0x09, |
6200 |
+ RTW89_TX_QSEL_VI_2 = 0x0a, |
6201 |
+ RTW89_TX_QSEL_VO_2 = 0x0b, |
6202 |
+ RTW89_TX_QSEL_BE_3 = 0x0c, |
6203 |
+ RTW89_TX_QSEL_BK_3 = 0x0d, |
6204 |
+ RTW89_TX_QSEL_VI_3 = 0x0e, |
6205 |
+ RTW89_TX_QSEL_VO_3 = 0x0f, |
6206 |
+ RTW89_TX_QSEL_B0_BCN = 0x10, |
6207 |
+ RTW89_TX_QSEL_B0_HI = 0x11, |
6208 |
+ RTW89_TX_QSEL_B0_MGMT = 0x12, |
6209 |
+ RTW89_TX_QSEL_B0_NOPS = 0x13, |
6210 |
+ RTW89_TX_QSEL_B0_MGMT_FAST = 0x14, |
6211 |
+ /* reserved */ |
6212 |
+ /* reserved */ |
6213 |
+ /* reserved */ |
6214 |
+ RTW89_TX_QSEL_B1_BCN = 0x18, |
6215 |
+ RTW89_TX_QSEL_B1_HI = 0x19, |
6216 |
+ RTW89_TX_QSEL_B1_MGMT = 0x1a, |
6217 |
+ RTW89_TX_QSEL_B1_NOPS = 0x1b, |
6218 |
+ RTW89_TX_QSEL_B1_MGMT_FAST = 0x1c, |
6219 |
+ /* reserved */ |
6220 |
+ /* reserved */ |
6221 |
+ /* reserved */ |
6222 |
+}; |
6223 |
+ |
6224 |
+enum rtw89_phy_status_ie_type { |
6225 |
+ RTW89_PHYSTS_IE00_CMN_CCK = 0, |
6226 |
+ RTW89_PHYSTS_IE01_CMN_OFDM = 1, |
6227 |
+ RTW89_PHYSTS_IE02_CMN_EXT_AX = 2, |
6228 |
+ RTW89_PHYSTS_IE03_CMN_EXT_SEG_1 = 3, |
6229 |
+ RTW89_PHYSTS_IE04_CMN_EXT_PATH_A = 4, |
6230 |
+ RTW89_PHYSTS_IE05_CMN_EXT_PATH_B = 5, |
6231 |
+ RTW89_PHYSTS_IE06_CMN_EXT_PATH_C = 6, |
6232 |
+ RTW89_PHYSTS_IE07_CMN_EXT_PATH_D = 7, |
6233 |
+ RTW89_PHYSTS_IE08_FTR_CH = 8, |
6234 |
+ RTW89_PHYSTS_IE09_FTR_PLCP_0 = 9, |
6235 |
+ RTW89_PHYSTS_IE10_FTR_PLCP_EXT = 10, |
6236 |
+ RTW89_PHYSTS_IE11_FTR_PLCP_HISTOGRAM = 11, |
6237 |
+ RTW89_PHYSTS_IE12_MU_EIGEN_INFO = 12, |
6238 |
+ RTW89_PHYSTS_IE13_DL_MU_DEF = 13, |
6239 |
+ RTW89_PHYSTS_IE14_TB_UL_CQI = 14, |
6240 |
+ RTW89_PHYSTS_IE15_TB_UL_DEF = 15, |
6241 |
+ RTW89_PHYSTS_IE16_RSVD16 = 16, |
6242 |
+ RTW89_PHYSTS_IE17_TB_UL_CTRL = 17, |
6243 |
+ RTW89_PHYSTS_IE18_DBG_OFDM_FD_CMN = 18, |
6244 |
+ RTW89_PHYSTS_IE19_DBG_OFDM_TD_CMN = 19, |
6245 |
+ RTW89_PHYSTS_IE20_DBG_OFDM_FD_USER_SEG_0 = 20, |
6246 |
+ RTW89_PHYSTS_IE21_DBG_OFDM_FD_USER_SEG_1 = 21, |
6247 |
+ RTW89_PHYSTS_IE22_DBG_OFDM_FD_USER_AGC = 22, |
6248 |
+ RTW89_PHYSTS_IE23_RSVD23 = 23, |
6249 |
+ RTW89_PHYSTS_IE24_DBG_OFDM_TD_PATH_A = 24, |
6250 |
+ RTW89_PHYSTS_IE25_DBG_OFDM_TD_PATH_B = 25, |
6251 |
+ RTW89_PHYSTS_IE26_DBG_OFDM_TD_PATH_C = 26, |
6252 |
+ RTW89_PHYSTS_IE27_DBG_OFDM_TD_PATH_D = 27, |
6253 |
+ RTW89_PHYSTS_IE28_DBG_CCK_PATH_A = 28, |
6254 |
+ RTW89_PHYSTS_IE29_DBG_CCK_PATH_B = 29, |
6255 |
+ RTW89_PHYSTS_IE30_DBG_CCK_PATH_C = 30, |
6256 |
+ RTW89_PHYSTS_IE31_DBG_CCK_PATH_D = 31, |
6257 |
+ |
6258 |
+ /* keep last */ |
6259 |
+ RTW89_PHYSTS_IE_NUM, |
6260 |
+ RTW89_PHYSTS_IE_MAX = RTW89_PHYSTS_IE_NUM - 1 |
6261 |
+}; |
6262 |
+ |
6263 |
+static inline u8 rtw89_core_get_qsel(struct rtw89_dev *rtwdev, u8 tid) |
6264 |
+{ |
6265 |
+ switch (tid) { |
6266 |
+ default: |
6267 |
+ rtw89_warn(rtwdev, "Should use tag 1d: %d\n", tid); |
6268 |
+ fallthrough; |
6269 |
+ case 0: |
6270 |
+ case 3: |
6271 |
+ return RTW89_TX_QSEL_BE_0; |
6272 |
+ case 1: |
6273 |
+ case 2: |
6274 |
+ return RTW89_TX_QSEL_BK_0; |
6275 |
+ case 4: |
6276 |
+ case 5: |
6277 |
+ return RTW89_TX_QSEL_VI_0; |
6278 |
+ case 6: |
6279 |
+ case 7: |
6280 |
+ return RTW89_TX_QSEL_VO_0; |
6281 |
+ } |
6282 |
+} |
6283 |
+ |
6284 |
+static inline u8 rtw89_core_get_ch_dma(struct rtw89_dev *rtwdev, u8 qsel) |
6285 |
+{ |
6286 |
+ switch (qsel) { |
6287 |
+ default: |
6288 |
+ rtw89_warn(rtwdev, "Cannot map qsel to dma: %d\n", qsel); |
6289 |
+ fallthrough; |
6290 |
+ case RTW89_TX_QSEL_BE_0: |
6291 |
+ return RTW89_TXCH_ACH0; |
6292 |
+ case RTW89_TX_QSEL_BK_0: |
6293 |
+ return RTW89_TXCH_ACH1; |
6294 |
+ case RTW89_TX_QSEL_VI_0: |
6295 |
+ return RTW89_TXCH_ACH2; |
6296 |
+ case RTW89_TX_QSEL_VO_0: |
6297 |
+ return RTW89_TXCH_ACH3; |
6298 |
+ case RTW89_TX_QSEL_B0_MGMT: |
6299 |
+ return RTW89_TXCH_CH8; |
6300 |
+ case RTW89_TX_QSEL_B0_HI: |
6301 |
+ return RTW89_TXCH_CH9; |
6302 |
+ case RTW89_TX_QSEL_B1_MGMT: |
6303 |
+ return RTW89_TXCH_CH10; |
6304 |
+ case RTW89_TX_QSEL_B1_HI: |
6305 |
+ return RTW89_TXCH_CH11; |
6306 |
+ } |
6307 |
+} |
6308 |
+ |
6309 |
+static inline u8 rtw89_core_get_tid_indicate(struct rtw89_dev *rtwdev, u8 tid) |
6310 |
+{ |
6311 |
+ switch (tid) { |
6312 |
+ case 3: |
6313 |
+ case 2: |
6314 |
+ case 5: |
6315 |
+ case 7: |
6316 |
+ return 1; |
6317 |
+ default: |
6318 |
+ rtw89_warn(rtwdev, "Should use tag 1d: %d\n", tid); |
6319 |
+ fallthrough; |
6320 |
+ case 0: |
6321 |
+ case 1: |
6322 |
+ case 4: |
6323 |
+ case 6: |
6324 |
+ return 0; |
6325 |
+ } |
6326 |
+} |
6327 |
+ |
6328 |
+#endif |
6329 |
diff --git a/drivers/net/wireless/realtek/rtw89/util.h b/drivers/net/wireless/realtek/rtw89/util.h |
6330 |
new file mode 100644 |
6331 |
index 000000000000..229e81009de6 |
6332 |
--- /dev/null |
6333 |
+++ b/drivers/net/wireless/realtek/rtw89/util.h |
6334 |
@@ -0,0 +1,17 @@ |
6335 |
+/* SPDX-License-Identifier: GPL-2.0 OR BSD-3-Clause |
6336 |
+ * Copyright(c) 2019-2020 Realtek Corporation |
6337 |
+ */ |
6338 |
+#ifndef __RTW89_UTIL_H__ |
6339 |
+#define __RTW89_UTIL_H__ |
6340 |
+ |
6341 |
+#include "core.h" |
6342 |
+ |
6343 |
+#define rtw89_iterate_vifs_bh(rtwdev, iterator, data) \ |
6344 |
+ ieee80211_iterate_active_interfaces_atomic((rtwdev)->hw, \ |
6345 |
+ IEEE80211_IFACE_ITER_NORMAL, iterator, data) |
6346 |
+ |
6347 |
+/* call this function with rtwdev->mutex is held */ |
6348 |
+#define rtw89_for_each_rtwvif(rtwdev, rtwvif) \ |
6349 |
+ list_for_each_entry(rtwvif, &(rtwdev)->rtwvifs_list, list) |
6350 |
+ |
6351 |
+#endif |
6352 |
-- |
6353 |
2.33.0 |
6354 |
|