/[packages]/backports/8/kernel/current/SOURCES/net-wireless-rtw89-implement-mac80211-ops.patch
ViewVC logotype

Contents of /backports/8/kernel/current/SOURCES/net-wireless-rtw89-implement-mac80211-ops.patch

Parent Directory Parent Directory | Revision Log Revision Log


Revision 1751299 - (show annotations) (download)
Wed Oct 13 18:02:55 2021 UTC (2 years, 6 months ago) by tmb
File size: 20304 byte(s)
- update to 5.14.12
  * drop merged/obsolete patches
- add current -stable queue
- fs/ntfs3: Fix integer overflow in ni_fiemap with fiemap_prep()
- fs/ntfs3: Remove unnecessary condition checking from ntfs_file_read_iter
- fs/ntfs3: Remove GPL boilerplates from decompress lib files
- fs/ntfs3: Change how module init/info messages are displayed
- kvm: fix null pointer dereference in page_is_secretmem()
- staging: replace old rtl8188eu with new r8188eu wifi driver from upcoming 5.15
- update rtw89 patchset to v7


1 From 91ea99070aba39173f56281703b885d0c86f76d9 Mon Sep 17 00:00:00 2001
2 From: Ping-Ke Shih <pkshih@realtek.com>
3 Date: Fri, 8 Oct 2021 11:56:11 +0800
4 Subject: [PATCH 08/24] rtw89: implement mac80211 ops
5
6 Implement ops to interactive with mac80211. The ops contain start/stop,
7 TX, add/remove vif, config, sta state, key, ampdu action,
8 sw_scan_start/complete, and so on. To avoid racing between ieee80211
9 delayed work and ioctl, all of them are protected by rtwdev->mutex.
10 To yield better TX performance, wake TX queue is implemented.
11
12 Signed-off-by: Ping-Ke Shih <pkshih@realtek.com>
13 Signed-off-by: Kalle Valo <kvalo@codeaurora.org>
14 Link: https://lore.kernel.org/r/20211008035627.19463-9-pkshih@realtek.com
15 ---
16 drivers/net/wireless/realtek/rtw89/mac80211.c | 676 ++++++++++++++++++
17 1 file changed, 676 insertions(+)
18 create mode 100644 drivers/net/wireless/realtek/rtw89/mac80211.c
19
20 diff --git a/drivers/net/wireless/realtek/rtw89/mac80211.c b/drivers/net/wireless/realtek/rtw89/mac80211.c
21 new file mode 100644
22 index 000000000000..16dc6fb7dbb0
23 --- /dev/null
24 +++ b/drivers/net/wireless/realtek/rtw89/mac80211.c
25 @@ -0,0 +1,676 @@
26 +// SPDX-License-Identifier: GPL-2.0 OR BSD-3-Clause
27 +/* Copyright(c) 2019-2020 Realtek Corporation
28 + */
29 +
30 +#include "cam.h"
31 +#include "coex.h"
32 +#include "debug.h"
33 +#include "fw.h"
34 +#include "mac.h"
35 +#include "phy.h"
36 +#include "ps.h"
37 +#include "reg.h"
38 +#include "sar.h"
39 +#include "ser.h"
40 +
41 +static void rtw89_ops_tx(struct ieee80211_hw *hw,
42 + struct ieee80211_tx_control *control,
43 + struct sk_buff *skb)
44 +{
45 + struct rtw89_dev *rtwdev = hw->priv;
46 + struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb);
47 + struct ieee80211_vif *vif = info->control.vif;
48 + struct ieee80211_sta *sta = control->sta;
49 + int ret, qsel;
50 +
51 + ret = rtw89_core_tx_write(rtwdev, vif, sta, skb, &qsel);
52 + if (ret) {
53 + rtw89_err(rtwdev, "failed to transmit skb: %d\n", ret);
54 + ieee80211_free_txskb(hw, skb);
55 + }
56 + rtw89_core_tx_kick_off(rtwdev, qsel);
57 +}
58 +
59 +static void rtw89_ops_wake_tx_queue(struct ieee80211_hw *hw,
60 + struct ieee80211_txq *txq)
61 +{
62 + struct rtw89_dev *rtwdev = hw->priv;
63 +
64 + ieee80211_schedule_txq(hw, txq);
65 + queue_work(rtwdev->txq_wq, &rtwdev->txq_work);
66 +}
67 +
68 +static int rtw89_ops_start(struct ieee80211_hw *hw)
69 +{
70 + struct rtw89_dev *rtwdev = hw->priv;
71 + int ret;
72 +
73 + mutex_lock(&rtwdev->mutex);
74 + ret = rtw89_core_start(rtwdev);
75 + mutex_unlock(&rtwdev->mutex);
76 +
77 + return ret;
78 +}
79 +
80 +static void rtw89_ops_stop(struct ieee80211_hw *hw)
81 +{
82 + struct rtw89_dev *rtwdev = hw->priv;
83 +
84 + mutex_lock(&rtwdev->mutex);
85 + rtw89_core_stop(rtwdev);
86 + mutex_unlock(&rtwdev->mutex);
87 +}
88 +
89 +static int rtw89_ops_config(struct ieee80211_hw *hw, u32 changed)
90 +{
91 + struct rtw89_dev *rtwdev = hw->priv;
92 +
93 + mutex_lock(&rtwdev->mutex);
94 + rtw89_leave_ps_mode(rtwdev);
95 +
96 + if ((changed & IEEE80211_CONF_CHANGE_IDLE) &&
97 + !(hw->conf.flags & IEEE80211_CONF_IDLE))
98 + rtw89_leave_ips(rtwdev);
99 +
100 + if (changed & IEEE80211_CONF_CHANGE_PS) {
101 + if (hw->conf.flags & IEEE80211_CONF_PS) {
102 + rtwdev->lps_enabled = true;
103 + } else {
104 + rtw89_leave_lps(rtwdev);
105 + rtwdev->lps_enabled = false;
106 + }
107 + }
108 +
109 + if (changed & IEEE80211_CONF_CHANGE_CHANNEL)
110 + rtw89_set_channel(rtwdev);
111 +
112 + if ((changed & IEEE80211_CONF_CHANGE_IDLE) &&
113 + (hw->conf.flags & IEEE80211_CONF_IDLE))
114 + rtw89_enter_ips(rtwdev);
115 +
116 + mutex_unlock(&rtwdev->mutex);
117 +
118 + return 0;
119 +}
120 +
121 +static int rtw89_ops_add_interface(struct ieee80211_hw *hw,
122 + struct ieee80211_vif *vif)
123 +{
124 + struct rtw89_dev *rtwdev = hw->priv;
125 + struct rtw89_vif *rtwvif = (struct rtw89_vif *)vif->drv_priv;
126 + int ret = 0;
127 +
128 + mutex_lock(&rtwdev->mutex);
129 + list_add_tail(&rtwvif->list, &rtwdev->rtwvifs_list);
130 + rtw89_leave_ps_mode(rtwdev);
131 +
132 + rtw89_traffic_stats_init(rtwdev, &rtwvif->stats);
133 + rtw89_vif_type_mapping(vif, false);
134 + rtwvif->port = rtw89_core_acquire_bit_map(rtwdev->hw_port,
135 + RTW89_MAX_HW_PORT_NUM);
136 + if (rtwvif->port == RTW89_MAX_HW_PORT_NUM) {
137 + ret = -ENOSPC;
138 + goto out;
139 + }
140 +
141 + rtwvif->bcn_hit_cond = 0;
142 + rtwvif->mac_idx = RTW89_MAC_0;
143 + rtwvif->phy_idx = RTW89_PHY_0;
144 + rtwvif->hit_rule = 0;
145 + ether_addr_copy(rtwvif->mac_addr, vif->addr);
146 +
147 + ret = rtw89_mac_add_vif(rtwdev, rtwvif);
148 + if (ret) {
149 + rtw89_core_release_bit_map(rtwdev->hw_port, rtwvif->port);
150 + goto out;
151 + }
152 +
153 + rtw89_core_txq_init(rtwdev, vif->txq);
154 +
155 + rtw89_btc_ntfy_role_info(rtwdev, rtwvif, NULL, BTC_ROLE_START);
156 +out:
157 + mutex_unlock(&rtwdev->mutex);
158 +
159 + return ret;
160 +}
161 +
162 +static void rtw89_ops_remove_interface(struct ieee80211_hw *hw,
163 + struct ieee80211_vif *vif)
164 +{
165 + struct rtw89_dev *rtwdev = hw->priv;
166 + struct rtw89_vif *rtwvif = (struct rtw89_vif *)vif->drv_priv;
167 +
168 + mutex_lock(&rtwdev->mutex);
169 + rtw89_leave_ps_mode(rtwdev);
170 + rtw89_btc_ntfy_role_info(rtwdev, rtwvif, NULL, BTC_ROLE_STOP);
171 + rtw89_mac_remove_vif(rtwdev, rtwvif);
172 + rtw89_core_release_bit_map(rtwdev->hw_port, rtwvif->port);
173 + list_del_init(&rtwvif->list);
174 + mutex_unlock(&rtwdev->mutex);
175 +}
176 +
177 +static void rtw89_ops_configure_filter(struct ieee80211_hw *hw,
178 + unsigned int changed_flags,
179 + unsigned int *new_flags,
180 + u64 multicast)
181 +{
182 + struct rtw89_dev *rtwdev = hw->priv;
183 +
184 + mutex_lock(&rtwdev->mutex);
185 + rtw89_leave_ps_mode(rtwdev);
186 +
187 + *new_flags &= FIF_ALLMULTI | FIF_OTHER_BSS | FIF_FCSFAIL |
188 + FIF_BCN_PRBRESP_PROMISC;
189 +
190 + if (changed_flags & FIF_ALLMULTI) {
191 + if (*new_flags & FIF_ALLMULTI)
192 + rtwdev->hal.rx_fltr &= ~B_AX_A_MC;
193 + else
194 + rtwdev->hal.rx_fltr |= B_AX_A_MC;
195 + }
196 + if (changed_flags & FIF_FCSFAIL) {
197 + if (*new_flags & FIF_FCSFAIL)
198 + rtwdev->hal.rx_fltr |= B_AX_A_CRC32_ERR;
199 + else
200 + rtwdev->hal.rx_fltr &= ~B_AX_A_CRC32_ERR;
201 + }
202 + if (changed_flags & FIF_OTHER_BSS) {
203 + if (*new_flags & FIF_OTHER_BSS)
204 + rtwdev->hal.rx_fltr &= ~B_AX_A_A1_MATCH;
205 + else
206 + rtwdev->hal.rx_fltr |= B_AX_A_A1_MATCH;
207 + }
208 + if (changed_flags & FIF_BCN_PRBRESP_PROMISC) {
209 + if (*new_flags & FIF_BCN_PRBRESP_PROMISC) {
210 + rtwdev->hal.rx_fltr &= ~B_AX_A_BCN_CHK_EN;
211 + rtwdev->hal.rx_fltr &= ~B_AX_A_BC;
212 + rtwdev->hal.rx_fltr &= ~B_AX_A_A1_MATCH;
213 + } else {
214 + rtwdev->hal.rx_fltr |= B_AX_A_BCN_CHK_EN;
215 + rtwdev->hal.rx_fltr |= B_AX_A_BC;
216 + rtwdev->hal.rx_fltr |= B_AX_A_A1_MATCH;
217 + }
218 + }
219 +
220 + rtw89_write32_mask(rtwdev,
221 + rtw89_mac_reg_by_idx(R_AX_RX_FLTR_OPT, RTW89_MAC_0),
222 + B_AX_RX_FLTR_CFG_MASK,
223 + rtwdev->hal.rx_fltr);
224 + if (!rtwdev->dbcc_en)
225 + goto out;
226 + rtw89_write32_mask(rtwdev,
227 + rtw89_mac_reg_by_idx(R_AX_RX_FLTR_OPT, RTW89_MAC_1),
228 + B_AX_RX_FLTR_CFG_MASK,
229 + rtwdev->hal.rx_fltr);
230 +
231 +out:
232 + mutex_unlock(&rtwdev->mutex);
233 +}
234 +
235 +static const u8 ac_to_fw_idx[IEEE80211_NUM_ACS] = {
236 + [IEEE80211_AC_VO] = 3,
237 + [IEEE80211_AC_VI] = 2,
238 + [IEEE80211_AC_BE] = 0,
239 + [IEEE80211_AC_BK] = 1,
240 +};
241 +
242 +static u8 rtw89_aifsn_to_aifs(struct rtw89_dev *rtwdev,
243 + struct rtw89_vif *rtwvif, u8 aifsn)
244 +{
245 + struct ieee80211_vif *vif = rtwvif_to_vif(rtwvif);
246 + u8 slot_time;
247 + u8 sifs;
248 +
249 + slot_time = vif->bss_conf.use_short_slot ? 9 : 20;
250 + sifs = rtwdev->hal.current_band_type == RTW89_BAND_5G ? 16 : 10;
251 +
252 + return aifsn * slot_time + sifs;
253 +}
254 +
255 +static void ____rtw89_conf_tx_edca(struct rtw89_dev *rtwdev,
256 + struct rtw89_vif *rtwvif, u16 ac)
257 +{
258 + struct ieee80211_tx_queue_params *params = &rtwvif->tx_params[ac];
259 + u32 val;
260 + u8 ecw_max, ecw_min;
261 + u8 aifs;
262 +
263 + /* 2^ecw - 1 = cw; ecw = log2(cw + 1) */
264 + ecw_max = ilog2(params->cw_max + 1);
265 + ecw_min = ilog2(params->cw_min + 1);
266 + aifs = rtw89_aifsn_to_aifs(rtwdev, rtwvif, params->aifs);
267 + val = FIELD_PREP(FW_EDCA_PARAM_TXOPLMT_MSK, params->txop) |
268 + FIELD_PREP(FW_EDCA_PARAM_CWMAX_MSK, ecw_max) |
269 + FIELD_PREP(FW_EDCA_PARAM_CWMIN_MSK, ecw_min) |
270 + FIELD_PREP(FW_EDCA_PARAM_AIFS_MSK, aifs);
271 + rtw89_fw_h2c_set_edca(rtwdev, rtwvif, ac_to_fw_idx[ac], val);
272 +}
273 +
274 +static const u32 ac_to_mu_edca_param[IEEE80211_NUM_ACS] = {
275 + [IEEE80211_AC_VO] = R_AX_MUEDCA_VO_PARAM_0,
276 + [IEEE80211_AC_VI] = R_AX_MUEDCA_VI_PARAM_0,
277 + [IEEE80211_AC_BE] = R_AX_MUEDCA_BE_PARAM_0,
278 + [IEEE80211_AC_BK] = R_AX_MUEDCA_BK_PARAM_0,
279 +};
280 +
281 +static void ____rtw89_conf_tx_mu_edca(struct rtw89_dev *rtwdev,
282 + struct rtw89_vif *rtwvif, u16 ac)
283 +{
284 + struct ieee80211_tx_queue_params *params = &rtwvif->tx_params[ac];
285 + struct ieee80211_he_mu_edca_param_ac_rec *mu_edca;
286 + u8 aifs, aifsn;
287 + u16 timer_32us;
288 + u32 reg;
289 + u32 val;
290 +
291 + if (!params->mu_edca)
292 + return;
293 +
294 + mu_edca = &params->mu_edca_param_rec;
295 + aifsn = FIELD_GET(GENMASK(3, 0), mu_edca->aifsn);
296 + aifs = aifsn ? rtw89_aifsn_to_aifs(rtwdev, rtwvif, aifsn) : 0;
297 + timer_32us = mu_edca->mu_edca_timer << 8;
298 +
299 + val = FIELD_PREP(B_AX_MUEDCA_BE_PARAM_0_TIMER_MASK, timer_32us) |
300 + FIELD_PREP(B_AX_MUEDCA_BE_PARAM_0_CW_MASK, mu_edca->ecw_min_max) |
301 + FIELD_PREP(B_AX_MUEDCA_BE_PARAM_0_AIFS_MASK, aifs);
302 + reg = rtw89_mac_reg_by_idx(ac_to_mu_edca_param[ac], rtwvif->mac_idx);
303 + rtw89_write32(rtwdev, reg, val);
304 +
305 + rtw89_mac_set_hw_muedca_ctrl(rtwdev, rtwvif, true);
306 +}
307 +
308 +static void __rtw89_conf_tx(struct rtw89_dev *rtwdev,
309 + struct rtw89_vif *rtwvif, u16 ac)
310 +{
311 + ____rtw89_conf_tx_edca(rtwdev, rtwvif, ac);
312 + ____rtw89_conf_tx_mu_edca(rtwdev, rtwvif, ac);
313 +}
314 +
315 +static void rtw89_conf_tx(struct rtw89_dev *rtwdev,
316 + struct rtw89_vif *rtwvif)
317 +{
318 + u16 ac;
319 +
320 + for (ac = 0; ac < IEEE80211_NUM_ACS; ac++)
321 + __rtw89_conf_tx(rtwdev, rtwvif, ac);
322 +}
323 +
324 +static void rtw89_station_mode_sta_assoc(struct rtw89_dev *rtwdev,
325 + struct ieee80211_vif *vif,
326 + struct ieee80211_bss_conf *conf)
327 +{
328 + struct ieee80211_sta *sta;
329 +
330 + if (vif->type != NL80211_IFTYPE_STATION)
331 + return;
332 +
333 + sta = ieee80211_find_sta(vif, conf->bssid);
334 + if (!sta) {
335 + rtw89_err(rtwdev, "can't find sta to set sta_assoc state\n");
336 + return;
337 + }
338 + rtw89_core_sta_assoc(rtwdev, vif, sta);
339 +}
340 +
341 +static void rtw89_ops_bss_info_changed(struct ieee80211_hw *hw,
342 + struct ieee80211_vif *vif,
343 + struct ieee80211_bss_conf *conf,
344 + u32 changed)
345 +{
346 + struct rtw89_dev *rtwdev = hw->priv;
347 + struct rtw89_vif *rtwvif = (struct rtw89_vif *)vif->drv_priv;
348 +
349 + mutex_lock(&rtwdev->mutex);
350 + rtw89_leave_ps_mode(rtwdev);
351 +
352 + if (changed & BSS_CHANGED_ASSOC) {
353 + if (conf->assoc) {
354 + rtw89_station_mode_sta_assoc(rtwdev, vif, conf);
355 + rtw89_phy_set_bss_color(rtwdev, vif);
356 + rtw89_chip_cfg_txpwr_ul_tb_offset(rtwdev, vif);
357 + rtw89_mac_port_update(rtwdev, rtwvif);
358 + }
359 + }
360 +
361 + if (changed & BSS_CHANGED_BSSID) {
362 + ether_addr_copy(rtwvif->bssid, conf->bssid);
363 + rtw89_cam_bssid_changed(rtwdev, rtwvif);
364 + rtw89_fw_h2c_cam(rtwdev, rtwvif);
365 + }
366 +
367 + if (changed & BSS_CHANGED_ERP_SLOT)
368 + rtw89_conf_tx(rtwdev, rtwvif);
369 +
370 + if (changed & BSS_CHANGED_HE_BSS_COLOR)
371 + rtw89_phy_set_bss_color(rtwdev, vif);
372 +
373 + if (changed & BSS_CHANGED_MU_GROUPS)
374 + rtw89_mac_bf_set_gid_table(rtwdev, vif, conf);
375 +
376 + mutex_unlock(&rtwdev->mutex);
377 +}
378 +
379 +static int rtw89_ops_conf_tx(struct ieee80211_hw *hw,
380 + struct ieee80211_vif *vif, u16 ac,
381 + const struct ieee80211_tx_queue_params *params)
382 +{
383 + struct rtw89_dev *rtwdev = hw->priv;
384 + struct rtw89_vif *rtwvif = (struct rtw89_vif *)vif->drv_priv;
385 +
386 + mutex_lock(&rtwdev->mutex);
387 + rtw89_leave_ps_mode(rtwdev);
388 + rtwvif->tx_params[ac] = *params;
389 + __rtw89_conf_tx(rtwdev, rtwvif, ac);
390 + mutex_unlock(&rtwdev->mutex);
391 +
392 + return 0;
393 +}
394 +
395 +static int __rtw89_ops_sta_state(struct ieee80211_hw *hw,
396 + struct ieee80211_vif *vif,
397 + struct ieee80211_sta *sta,
398 + enum ieee80211_sta_state old_state,
399 + enum ieee80211_sta_state new_state)
400 +{
401 + struct rtw89_dev *rtwdev = hw->priv;
402 +
403 + if (old_state == IEEE80211_STA_NOTEXIST &&
404 + new_state == IEEE80211_STA_NONE)
405 + return rtw89_core_sta_add(rtwdev, vif, sta);
406 +
407 + if (old_state == IEEE80211_STA_AUTH &&
408 + new_state == IEEE80211_STA_ASSOC) {
409 + if (vif->type == NL80211_IFTYPE_STATION)
410 + return 0; /* defer to bss_info_changed to have vif info */
411 + return rtw89_core_sta_assoc(rtwdev, vif, sta);
412 + }
413 +
414 + if (old_state == IEEE80211_STA_ASSOC &&
415 + new_state == IEEE80211_STA_AUTH)
416 + return rtw89_core_sta_disassoc(rtwdev, vif, sta);
417 +
418 + if (old_state == IEEE80211_STA_AUTH &&
419 + new_state == IEEE80211_STA_NONE)
420 + return rtw89_core_sta_disconnect(rtwdev, vif, sta);
421 +
422 + if (old_state == IEEE80211_STA_NONE &&
423 + new_state == IEEE80211_STA_NOTEXIST)
424 + return rtw89_core_sta_remove(rtwdev, vif, sta);
425 +
426 + return 0;
427 +}
428 +
429 +static int rtw89_ops_sta_state(struct ieee80211_hw *hw,
430 + struct ieee80211_vif *vif,
431 + struct ieee80211_sta *sta,
432 + enum ieee80211_sta_state old_state,
433 + enum ieee80211_sta_state new_state)
434 +{
435 + struct rtw89_dev *rtwdev = hw->priv;
436 + int ret;
437 +
438 + mutex_lock(&rtwdev->mutex);
439 + rtw89_leave_ps_mode(rtwdev);
440 + ret = __rtw89_ops_sta_state(hw, vif, sta, old_state, new_state);
441 + mutex_unlock(&rtwdev->mutex);
442 +
443 + return ret;
444 +}
445 +
446 +static int rtw89_ops_set_key(struct ieee80211_hw *hw, enum set_key_cmd cmd,
447 + struct ieee80211_vif *vif,
448 + struct ieee80211_sta *sta,
449 + struct ieee80211_key_conf *key)
450 +{
451 + struct rtw89_dev *rtwdev = hw->priv;
452 + int ret = 0;
453 +
454 + mutex_lock(&rtwdev->mutex);
455 + rtw89_leave_ps_mode(rtwdev);
456 +
457 + switch (cmd) {
458 + case SET_KEY:
459 + rtw89_btc_ntfy_specific_packet(rtwdev, PACKET_EAPOL_END);
460 + ret = rtw89_cam_sec_key_add(rtwdev, vif, sta, key);
461 + if (ret && ret != -EOPNOTSUPP) {
462 + rtw89_err(rtwdev, "failed to add key to sec cam\n");
463 + goto out;
464 + }
465 + break;
466 + case DISABLE_KEY:
467 + rtw89_hci_flush_queues(rtwdev, BIT(rtwdev->hw->queues) - 1,
468 + false);
469 + rtw89_mac_flush_txq(rtwdev, BIT(rtwdev->hw->queues) - 1, false);
470 + ret = rtw89_cam_sec_key_del(rtwdev, vif, sta, key, true);
471 + if (ret) {
472 + rtw89_err(rtwdev, "failed to remove key from sec cam\n");
473 + goto out;
474 + }
475 + break;
476 + }
477 +
478 +out:
479 + mutex_unlock(&rtwdev->mutex);
480 +
481 + return ret;
482 +}
483 +
484 +static int rtw89_ops_ampdu_action(struct ieee80211_hw *hw,
485 + struct ieee80211_vif *vif,
486 + struct ieee80211_ampdu_params *params)
487 +{
488 + struct rtw89_dev *rtwdev = hw->priv;
489 + struct ieee80211_sta *sta = params->sta;
490 + struct rtw89_sta *rtwsta = (struct rtw89_sta *)sta->drv_priv;
491 + u16 tid = params->tid;
492 + struct ieee80211_txq *txq = sta->txq[tid];
493 + struct rtw89_txq *rtwtxq = (struct rtw89_txq *)txq->drv_priv;
494 +
495 + switch (params->action) {
496 + case IEEE80211_AMPDU_TX_START:
497 + return IEEE80211_AMPDU_TX_START_IMMEDIATE;
498 + case IEEE80211_AMPDU_TX_STOP_CONT:
499 + case IEEE80211_AMPDU_TX_STOP_FLUSH:
500 + case IEEE80211_AMPDU_TX_STOP_FLUSH_CONT:
501 + mutex_lock(&rtwdev->mutex);
502 + clear_bit(RTW89_TXQ_F_AMPDU, &rtwtxq->flags);
503 + rtw89_fw_h2c_ba_cam(rtwdev, false, rtwsta->mac_id, params);
504 + mutex_unlock(&rtwdev->mutex);
505 + ieee80211_stop_tx_ba_cb_irqsafe(vif, sta->addr, tid);
506 + break;
507 + case IEEE80211_AMPDU_TX_OPERATIONAL:
508 + mutex_lock(&rtwdev->mutex);
509 + set_bit(RTW89_TXQ_F_AMPDU, &rtwtxq->flags);
510 + rtwsta->ampdu_params[tid].agg_num = params->buf_size;
511 + rtwsta->ampdu_params[tid].amsdu = params->amsdu;
512 + rtw89_leave_ps_mode(rtwdev);
513 + rtw89_fw_h2c_ba_cam(rtwdev, true, rtwsta->mac_id, params);
514 + mutex_unlock(&rtwdev->mutex);
515 + break;
516 + case IEEE80211_AMPDU_RX_START:
517 + case IEEE80211_AMPDU_RX_STOP:
518 + break;
519 + default:
520 + WARN_ON(1);
521 + return -ENOTSUPP;
522 + }
523 +
524 + return 0;
525 +}
526 +
527 +static int rtw89_ops_set_rts_threshold(struct ieee80211_hw *hw, u32 value)
528 +{
529 + struct rtw89_dev *rtwdev = hw->priv;
530 +
531 + mutex_lock(&rtwdev->mutex);
532 + rtw89_leave_ps_mode(rtwdev);
533 + if (test_bit(RTW89_FLAG_POWERON, rtwdev->flags))
534 + rtw89_mac_update_rts_threshold(rtwdev, RTW89_MAC_0);
535 + mutex_unlock(&rtwdev->mutex);
536 +
537 + return 0;
538 +}
539 +
540 +static void rtw89_ops_sta_statistics(struct ieee80211_hw *hw,
541 + struct ieee80211_vif *vif,
542 + struct ieee80211_sta *sta,
543 + struct station_info *sinfo)
544 +{
545 + struct rtw89_sta *rtwsta = (struct rtw89_sta *)sta->drv_priv;
546 +
547 + sinfo->txrate = rtwsta->ra_report.txrate;
548 + sinfo->filled |= BIT_ULL(NL80211_STA_INFO_TX_BITRATE);
549 +}
550 +
551 +static void rtw89_ops_flush(struct ieee80211_hw *hw, struct ieee80211_vif *vif,
552 + u32 queues, bool drop)
553 +{
554 + struct rtw89_dev *rtwdev = hw->priv;
555 +
556 + mutex_lock(&rtwdev->mutex);
557 + rtw89_leave_lps(rtwdev);
558 + rtw89_hci_flush_queues(rtwdev, queues, drop);
559 + rtw89_mac_flush_txq(rtwdev, queues, drop);
560 + mutex_unlock(&rtwdev->mutex);
561 +}
562 +
563 +struct rtw89_iter_bitrate_mask_data {
564 + struct rtw89_dev *rtwdev;
565 + struct ieee80211_vif *vif;
566 + const struct cfg80211_bitrate_mask *mask;
567 +};
568 +
569 +static void rtw89_ra_mask_info_update_iter(void *data, struct ieee80211_sta *sta)
570 +{
571 + struct rtw89_iter_bitrate_mask_data *br_data = data;
572 + struct rtw89_sta *rtwsta = (struct rtw89_sta *)sta->drv_priv;
573 + struct ieee80211_vif *vif = rtwvif_to_vif(rtwsta->rtwvif);
574 +
575 + if (vif != br_data->vif)
576 + return;
577 +
578 + rtwsta->use_cfg_mask = true;
579 + rtwsta->mask = *br_data->mask;
580 + rtw89_phy_ra_updata_sta(br_data->rtwdev, sta);
581 +}
582 +
583 +static void rtw89_ra_mask_info_update(struct rtw89_dev *rtwdev,
584 + struct ieee80211_vif *vif,
585 + const struct cfg80211_bitrate_mask *mask)
586 +{
587 + struct rtw89_iter_bitrate_mask_data br_data = { .rtwdev = rtwdev,
588 + .vif = vif,
589 + .mask = mask};
590 +
591 + ieee80211_iterate_stations_atomic(rtwdev->hw, rtw89_ra_mask_info_update_iter,
592 + &br_data);
593 +}
594 +
595 +static int rtw89_ops_set_bitrate_mask(struct ieee80211_hw *hw,
596 + struct ieee80211_vif *vif,
597 + const struct cfg80211_bitrate_mask *mask)
598 +{
599 + struct rtw89_dev *rtwdev = hw->priv;
600 +
601 + mutex_lock(&rtwdev->mutex);
602 + rtw89_phy_rate_pattern_vif(rtwdev, vif, mask);
603 + rtw89_ra_mask_info_update(rtwdev, vif, mask);
604 + mutex_unlock(&rtwdev->mutex);
605 +
606 + return 0;
607 +}
608 +
609 +static
610 +int rtw89_ops_set_antenna(struct ieee80211_hw *hw, u32 tx_ant, u32 rx_ant)
611 +{
612 + struct rtw89_dev *rtwdev = hw->priv;
613 + struct rtw89_hal *hal = &rtwdev->hal;
614 +
615 + if (rx_ant != hw->wiphy->available_antennas_rx)
616 + return -EINVAL;
617 +
618 + mutex_lock(&rtwdev->mutex);
619 + hal->antenna_tx = tx_ant;
620 + hal->antenna_rx = rx_ant;
621 + mutex_unlock(&rtwdev->mutex);
622 +
623 + return 0;
624 +}
625 +
626 +static
627 +int rtw89_ops_get_antenna(struct ieee80211_hw *hw, u32 *tx_ant, u32 *rx_ant)
628 +{
629 + struct rtw89_dev *rtwdev = hw->priv;
630 + struct rtw89_hal *hal = &rtwdev->hal;
631 +
632 + *tx_ant = hal->antenna_tx;
633 + *rx_ant = hal->antenna_rx;
634 +
635 + return 0;
636 +}
637 +
638 +static void rtw89_ops_sw_scan_start(struct ieee80211_hw *hw,
639 + struct ieee80211_vif *vif,
640 + const u8 *mac_addr)
641 +{
642 + struct rtw89_dev *rtwdev = hw->priv;
643 + struct rtw89_hal *hal = &rtwdev->hal;
644 +
645 + mutex_lock(&rtwdev->mutex);
646 + rtwdev->scanning = true;
647 + rtw89_leave_lps(rtwdev);
648 + rtw89_btc_ntfy_scan_start(rtwdev, RTW89_PHY_0, hal->current_band_type);
649 + rtw89_chip_rfk_scan(rtwdev, true);
650 + rtw89_hci_recalc_int_mit(rtwdev);
651 + mutex_unlock(&rtwdev->mutex);
652 +}
653 +
654 +static void rtw89_ops_sw_scan_complete(struct ieee80211_hw *hw,
655 + struct ieee80211_vif *vif)
656 +{
657 + struct rtw89_dev *rtwdev = hw->priv;
658 +
659 + mutex_lock(&rtwdev->mutex);
660 + rtw89_chip_rfk_scan(rtwdev, false);
661 + rtw89_btc_ntfy_scan_finish(rtwdev, RTW89_PHY_0);
662 + rtwdev->scanning = false;
663 + rtwdev->dig.bypass_dig = true;
664 + mutex_unlock(&rtwdev->mutex);
665 +}
666 +
667 +static void rtw89_ops_reconfig_complete(struct ieee80211_hw *hw,
668 + enum ieee80211_reconfig_type reconfig_type)
669 +{
670 + struct rtw89_dev *rtwdev = hw->priv;
671 +
672 + if (reconfig_type == IEEE80211_RECONFIG_TYPE_RESTART)
673 + rtw89_ser_recfg_done(rtwdev);
674 +}
675 +
676 +const struct ieee80211_ops rtw89_ops = {
677 + .tx = rtw89_ops_tx,
678 + .wake_tx_queue = rtw89_ops_wake_tx_queue,
679 + .start = rtw89_ops_start,
680 + .stop = rtw89_ops_stop,
681 + .config = rtw89_ops_config,
682 + .add_interface = rtw89_ops_add_interface,
683 + .remove_interface = rtw89_ops_remove_interface,
684 + .configure_filter = rtw89_ops_configure_filter,
685 + .bss_info_changed = rtw89_ops_bss_info_changed,
686 + .conf_tx = rtw89_ops_conf_tx,
687 + .sta_state = rtw89_ops_sta_state,
688 + .set_key = rtw89_ops_set_key,
689 + .ampdu_action = rtw89_ops_ampdu_action,
690 + .set_rts_threshold = rtw89_ops_set_rts_threshold,
691 + .sta_statistics = rtw89_ops_sta_statistics,
692 + .flush = rtw89_ops_flush,
693 + .set_bitrate_mask = rtw89_ops_set_bitrate_mask,
694 + .set_antenna = rtw89_ops_set_antenna,
695 + .get_antenna = rtw89_ops_get_antenna,
696 + .sw_scan_start = rtw89_ops_sw_scan_start,
697 + .sw_scan_complete = rtw89_ops_sw_scan_complete,
698 + .reconfig_complete = rtw89_ops_reconfig_complete,
699 + .set_sar_specs = rtw89_ops_set_sar_specs,
700 +};
701 +EXPORT_SYMBOL(rtw89_ops);
702 --
703 2.33.0
704

  ViewVC Help
Powered by ViewVC 1.1.30