wifi: mac80211: change QoS settings API to take link into account
[linux-block.git] / drivers / net / wireless / realtek / rtw89 / mac80211.c
CommitLineData
e3ec7017
PKS
1// SPDX-License-Identifier: GPL-2.0 OR BSD-3-Clause
2/* Copyright(c) 2019-2020 Realtek Corporation
3 */
4
5#include "cam.h"
6#include "coex.h"
7#include "debug.h"
8#include "fw.h"
9#include "mac.h"
10#include "phy.h"
11#include "ps.h"
12#include "reg.h"
13#include "sar.h"
14#include "ser.h"
15
16static void rtw89_ops_tx(struct ieee80211_hw *hw,
17 struct ieee80211_tx_control *control,
18 struct sk_buff *skb)
19{
20 struct rtw89_dev *rtwdev = hw->priv;
21 struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb);
22 struct ieee80211_vif *vif = info->control.vif;
23 struct ieee80211_sta *sta = control->sta;
24 int ret, qsel;
25
26 ret = rtw89_core_tx_write(rtwdev, vif, sta, skb, &qsel);
27 if (ret) {
28 rtw89_err(rtwdev, "failed to transmit skb: %d\n", ret);
29 ieee80211_free_txskb(hw, skb);
a58fdb7c 30 return;
e3ec7017
PKS
31 }
32 rtw89_core_tx_kick_off(rtwdev, qsel);
33}
34
35static void rtw89_ops_wake_tx_queue(struct ieee80211_hw *hw,
36 struct ieee80211_txq *txq)
37{
38 struct rtw89_dev *rtwdev = hw->priv;
39
40 ieee80211_schedule_txq(hw, txq);
41 queue_work(rtwdev->txq_wq, &rtwdev->txq_work);
42}
43
44static int rtw89_ops_start(struct ieee80211_hw *hw)
45{
46 struct rtw89_dev *rtwdev = hw->priv;
47 int ret;
48
49 mutex_lock(&rtwdev->mutex);
50 ret = rtw89_core_start(rtwdev);
51 mutex_unlock(&rtwdev->mutex);
52
53 return ret;
54}
55
56static void rtw89_ops_stop(struct ieee80211_hw *hw)
57{
58 struct rtw89_dev *rtwdev = hw->priv;
59
60 mutex_lock(&rtwdev->mutex);
61 rtw89_core_stop(rtwdev);
62 mutex_unlock(&rtwdev->mutex);
63}
64
65static int rtw89_ops_config(struct ieee80211_hw *hw, u32 changed)
66{
67 struct rtw89_dev *rtwdev = hw->priv;
68
89590777
PHH
69 /* let previous ips work finish to ensure we don't leave ips twice */
70 cancel_work_sync(&rtwdev->ips_work);
71
e3ec7017
PKS
72 mutex_lock(&rtwdev->mutex);
73 rtw89_leave_ps_mode(rtwdev);
74
75 if ((changed & IEEE80211_CONF_CHANGE_IDLE) &&
76 !(hw->conf.flags & IEEE80211_CONF_IDLE))
77 rtw89_leave_ips(rtwdev);
78
79 if (changed & IEEE80211_CONF_CHANGE_PS) {
80 if (hw->conf.flags & IEEE80211_CONF_PS) {
81 rtwdev->lps_enabled = true;
82 } else {
83 rtw89_leave_lps(rtwdev);
84 rtwdev->lps_enabled = false;
85 }
86 }
87
88 if (changed & IEEE80211_CONF_CHANGE_CHANNEL)
89 rtw89_set_channel(rtwdev);
90
91 if ((changed & IEEE80211_CONF_CHANGE_IDLE) &&
92 (hw->conf.flags & IEEE80211_CONF_IDLE))
93 rtw89_enter_ips(rtwdev);
94
95 mutex_unlock(&rtwdev->mutex);
96
97 return 0;
98}
99
100static int rtw89_ops_add_interface(struct ieee80211_hw *hw,
101 struct ieee80211_vif *vif)
102{
103 struct rtw89_dev *rtwdev = hw->priv;
104 struct rtw89_vif *rtwvif = (struct rtw89_vif *)vif->drv_priv;
105 int ret = 0;
106
107 mutex_lock(&rtwdev->mutex);
d62816b4 108 rtwvif->rtwdev = rtwdev;
e3ec7017 109 list_add_tail(&rtwvif->list, &rtwdev->rtwvifs_list);
d62816b4 110 INIT_WORK(&rtwvif->update_beacon_work, rtw89_core_update_beacon_work);
e3ec7017
PKS
111 rtw89_leave_ps_mode(rtwdev);
112
113 rtw89_traffic_stats_init(rtwdev, &rtwvif->stats);
114 rtw89_vif_type_mapping(vif, false);
115 rtwvif->port = rtw89_core_acquire_bit_map(rtwdev->hw_port,
20d9fc88
PKS
116 RTW89_PORT_NUM);
117 if (rtwvif->port == RTW89_PORT_NUM) {
e3ec7017
PKS
118 ret = -ENOSPC;
119 goto out;
120 }
121
122 rtwvif->bcn_hit_cond = 0;
123 rtwvif->mac_idx = RTW89_MAC_0;
124 rtwvif->phy_idx = RTW89_PHY_0;
125 rtwvif->hit_rule = 0;
126 ether_addr_copy(rtwvif->mac_addr, vif->addr);
127
128 ret = rtw89_mac_add_vif(rtwdev, rtwvif);
129 if (ret) {
130 rtw89_core_release_bit_map(rtwdev->hw_port, rtwvif->port);
131 goto out;
132 }
133
134 rtw89_core_txq_init(rtwdev, vif->txq);
135
136 rtw89_btc_ntfy_role_info(rtwdev, rtwvif, NULL, BTC_ROLE_START);
137out:
138 mutex_unlock(&rtwdev->mutex);
139
140 return ret;
141}
142
143static void rtw89_ops_remove_interface(struct ieee80211_hw *hw,
144 struct ieee80211_vif *vif)
145{
146 struct rtw89_dev *rtwdev = hw->priv;
147 struct rtw89_vif *rtwvif = (struct rtw89_vif *)vif->drv_priv;
148
d62816b4
PKS
149 cancel_work_sync(&rtwvif->update_beacon_work);
150
e3ec7017
PKS
151 mutex_lock(&rtwdev->mutex);
152 rtw89_leave_ps_mode(rtwdev);
153 rtw89_btc_ntfy_role_info(rtwdev, rtwvif, NULL, BTC_ROLE_STOP);
154 rtw89_mac_remove_vif(rtwdev, rtwvif);
155 rtw89_core_release_bit_map(rtwdev->hw_port, rtwvif->port);
156 list_del_init(&rtwvif->list);
157 mutex_unlock(&rtwdev->mutex);
158}
159
160static void rtw89_ops_configure_filter(struct ieee80211_hw *hw,
161 unsigned int changed_flags,
162 unsigned int *new_flags,
163 u64 multicast)
164{
165 struct rtw89_dev *rtwdev = hw->priv;
166
167 mutex_lock(&rtwdev->mutex);
168 rtw89_leave_ps_mode(rtwdev);
169
170 *new_flags &= FIF_ALLMULTI | FIF_OTHER_BSS | FIF_FCSFAIL |
6629dc56 171 FIF_BCN_PRBRESP_PROMISC | FIF_PROBE_REQ;
e3ec7017
PKS
172
173 if (changed_flags & FIF_ALLMULTI) {
174 if (*new_flags & FIF_ALLMULTI)
175 rtwdev->hal.rx_fltr &= ~B_AX_A_MC;
176 else
177 rtwdev->hal.rx_fltr |= B_AX_A_MC;
178 }
179 if (changed_flags & FIF_FCSFAIL) {
180 if (*new_flags & FIF_FCSFAIL)
181 rtwdev->hal.rx_fltr |= B_AX_A_CRC32_ERR;
182 else
183 rtwdev->hal.rx_fltr &= ~B_AX_A_CRC32_ERR;
184 }
185 if (changed_flags & FIF_OTHER_BSS) {
186 if (*new_flags & FIF_OTHER_BSS)
187 rtwdev->hal.rx_fltr &= ~B_AX_A_A1_MATCH;
188 else
189 rtwdev->hal.rx_fltr |= B_AX_A_A1_MATCH;
190 }
191 if (changed_flags & FIF_BCN_PRBRESP_PROMISC) {
192 if (*new_flags & FIF_BCN_PRBRESP_PROMISC) {
193 rtwdev->hal.rx_fltr &= ~B_AX_A_BCN_CHK_EN;
194 rtwdev->hal.rx_fltr &= ~B_AX_A_BC;
195 rtwdev->hal.rx_fltr &= ~B_AX_A_A1_MATCH;
196 } else {
197 rtwdev->hal.rx_fltr |= B_AX_A_BCN_CHK_EN;
198 rtwdev->hal.rx_fltr |= B_AX_A_BC;
199 rtwdev->hal.rx_fltr |= B_AX_A_A1_MATCH;
200 }
201 }
6629dc56
PKS
202 if (changed_flags & FIF_PROBE_REQ) {
203 if (*new_flags & FIF_PROBE_REQ) {
204 rtwdev->hal.rx_fltr &= ~B_AX_A_BC_CAM_MATCH;
205 rtwdev->hal.rx_fltr &= ~B_AX_A_UC_CAM_MATCH;
206 } else {
207 rtwdev->hal.rx_fltr |= B_AX_A_BC_CAM_MATCH;
208 rtwdev->hal.rx_fltr |= B_AX_A_UC_CAM_MATCH;
209 }
210 }
e3ec7017
PKS
211
212 rtw89_write32_mask(rtwdev,
213 rtw89_mac_reg_by_idx(R_AX_RX_FLTR_OPT, RTW89_MAC_0),
214 B_AX_RX_FLTR_CFG_MASK,
215 rtwdev->hal.rx_fltr);
216 if (!rtwdev->dbcc_en)
217 goto out;
218 rtw89_write32_mask(rtwdev,
219 rtw89_mac_reg_by_idx(R_AX_RX_FLTR_OPT, RTW89_MAC_1),
220 B_AX_RX_FLTR_CFG_MASK,
221 rtwdev->hal.rx_fltr);
222
223out:
224 mutex_unlock(&rtwdev->mutex);
225}
226
227static const u8 ac_to_fw_idx[IEEE80211_NUM_ACS] = {
228 [IEEE80211_AC_VO] = 3,
229 [IEEE80211_AC_VI] = 2,
230 [IEEE80211_AC_BE] = 0,
231 [IEEE80211_AC_BK] = 1,
232};
233
234static u8 rtw89_aifsn_to_aifs(struct rtw89_dev *rtwdev,
235 struct rtw89_vif *rtwvif, u8 aifsn)
236{
237 struct ieee80211_vif *vif = rtwvif_to_vif(rtwvif);
238 u8 slot_time;
239 u8 sifs;
240
241 slot_time = vif->bss_conf.use_short_slot ? 9 : 20;
242 sifs = rtwdev->hal.current_band_type == RTW89_BAND_5G ? 16 : 10;
243
244 return aifsn * slot_time + sifs;
245}
246
247static void ____rtw89_conf_tx_edca(struct rtw89_dev *rtwdev,
248 struct rtw89_vif *rtwvif, u16 ac)
249{
250 struct ieee80211_tx_queue_params *params = &rtwvif->tx_params[ac];
251 u32 val;
252 u8 ecw_max, ecw_min;
253 u8 aifs;
254
255 /* 2^ecw - 1 = cw; ecw = log2(cw + 1) */
256 ecw_max = ilog2(params->cw_max + 1);
257 ecw_min = ilog2(params->cw_min + 1);
258 aifs = rtw89_aifsn_to_aifs(rtwdev, rtwvif, params->aifs);
259 val = FIELD_PREP(FW_EDCA_PARAM_TXOPLMT_MSK, params->txop) |
260 FIELD_PREP(FW_EDCA_PARAM_CWMAX_MSK, ecw_max) |
261 FIELD_PREP(FW_EDCA_PARAM_CWMIN_MSK, ecw_min) |
262 FIELD_PREP(FW_EDCA_PARAM_AIFS_MSK, aifs);
263 rtw89_fw_h2c_set_edca(rtwdev, rtwvif, ac_to_fw_idx[ac], val);
264}
265
266static const u32 ac_to_mu_edca_param[IEEE80211_NUM_ACS] = {
267 [IEEE80211_AC_VO] = R_AX_MUEDCA_VO_PARAM_0,
268 [IEEE80211_AC_VI] = R_AX_MUEDCA_VI_PARAM_0,
269 [IEEE80211_AC_BE] = R_AX_MUEDCA_BE_PARAM_0,
270 [IEEE80211_AC_BK] = R_AX_MUEDCA_BK_PARAM_0,
271};
272
273static void ____rtw89_conf_tx_mu_edca(struct rtw89_dev *rtwdev,
274 struct rtw89_vif *rtwvif, u16 ac)
275{
276 struct ieee80211_tx_queue_params *params = &rtwvif->tx_params[ac];
277 struct ieee80211_he_mu_edca_param_ac_rec *mu_edca;
278 u8 aifs, aifsn;
279 u16 timer_32us;
280 u32 reg;
281 u32 val;
282
283 if (!params->mu_edca)
284 return;
285
286 mu_edca = &params->mu_edca_param_rec;
287 aifsn = FIELD_GET(GENMASK(3, 0), mu_edca->aifsn);
288 aifs = aifsn ? rtw89_aifsn_to_aifs(rtwdev, rtwvif, aifsn) : 0;
289 timer_32us = mu_edca->mu_edca_timer << 8;
290
291 val = FIELD_PREP(B_AX_MUEDCA_BE_PARAM_0_TIMER_MASK, timer_32us) |
292 FIELD_PREP(B_AX_MUEDCA_BE_PARAM_0_CW_MASK, mu_edca->ecw_min_max) |
293 FIELD_PREP(B_AX_MUEDCA_BE_PARAM_0_AIFS_MASK, aifs);
294 reg = rtw89_mac_reg_by_idx(ac_to_mu_edca_param[ac], rtwvif->mac_idx);
295 rtw89_write32(rtwdev, reg, val);
296
297 rtw89_mac_set_hw_muedca_ctrl(rtwdev, rtwvif, true);
298}
299
300static void __rtw89_conf_tx(struct rtw89_dev *rtwdev,
301 struct rtw89_vif *rtwvif, u16 ac)
302{
303 ____rtw89_conf_tx_edca(rtwdev, rtwvif, ac);
304 ____rtw89_conf_tx_mu_edca(rtwdev, rtwvif, ac);
305}
306
307static void rtw89_conf_tx(struct rtw89_dev *rtwdev,
308 struct rtw89_vif *rtwvif)
309{
310 u16 ac;
311
312 for (ac = 0; ac < IEEE80211_NUM_ACS; ac++)
313 __rtw89_conf_tx(rtwdev, rtwvif, ac);
314}
315
316static void rtw89_station_mode_sta_assoc(struct rtw89_dev *rtwdev,
317 struct ieee80211_vif *vif,
318 struct ieee80211_bss_conf *conf)
319{
320 struct ieee80211_sta *sta;
321
322 if (vif->type != NL80211_IFTYPE_STATION)
323 return;
324
325 sta = ieee80211_find_sta(vif, conf->bssid);
326 if (!sta) {
327 rtw89_err(rtwdev, "can't find sta to set sta_assoc state\n");
328 return;
329 }
fd7ee4c8
PKS
330
331 rtw89_vif_type_mapping(vif, true);
332
e3ec7017
PKS
333 rtw89_core_sta_assoc(rtwdev, vif, sta);
334}
335
336static void rtw89_ops_bss_info_changed(struct ieee80211_hw *hw,
337 struct ieee80211_vif *vif,
338 struct ieee80211_bss_conf *conf,
7b7090b4 339 u64 changed)
e3ec7017
PKS
340{
341 struct rtw89_dev *rtwdev = hw->priv;
342 struct rtw89_vif *rtwvif = (struct rtw89_vif *)vif->drv_priv;
343
344 mutex_lock(&rtwdev->mutex);
345 rtw89_leave_ps_mode(rtwdev);
346
347 if (changed & BSS_CHANGED_ASSOC) {
f276e20b 348 if (vif->cfg.assoc) {
e3ec7017
PKS
349 rtw89_station_mode_sta_assoc(rtwdev, vif, conf);
350 rtw89_phy_set_bss_color(rtwdev, vif);
351 rtw89_chip_cfg_txpwr_ul_tb_offset(rtwdev, vif);
352 rtw89_mac_port_update(rtwdev, rtwvif);
28000f7b 353 rtw89_store_op_chan(rtwdev, true);
89590777
PHH
354 } else {
355 /* Abort ongoing scan if cancel_scan isn't issued
356 * when disconnected by peer
357 */
358 if (rtwdev->scanning)
359 rtw89_hw_scan_abort(rtwdev, vif);
e3ec7017
PKS
360 }
361 }
362
363 if (changed & BSS_CHANGED_BSSID) {
364 ether_addr_copy(rtwvif->bssid, conf->bssid);
365 rtw89_cam_bssid_changed(rtwdev, rtwvif);
40822e07 366 rtw89_fw_h2c_cam(rtwdev, rtwvif, NULL, NULL);
e3ec7017
PKS
367 }
368
f7e76d13
PKS
369 if (changed & BSS_CHANGED_BEACON)
370 rtw89_fw_h2c_update_beacon(rtwdev, rtwvif);
371
e3ec7017
PKS
372 if (changed & BSS_CHANGED_ERP_SLOT)
373 rtw89_conf_tx(rtwdev, rtwvif);
374
375 if (changed & BSS_CHANGED_HE_BSS_COLOR)
376 rtw89_phy_set_bss_color(rtwdev, vif);
377
378 if (changed & BSS_CHANGED_MU_GROUPS)
379 rtw89_mac_bf_set_gid_table(rtwdev, vif, conf);
380
381 mutex_unlock(&rtwdev->mutex);
382}
383
ae7ba17b
ST
384static int rtw89_ops_start_ap(struct ieee80211_hw *hw,
385 struct ieee80211_vif *vif, unsigned int link_id)
a52e4f2c
PKS
386{
387 struct rtw89_dev *rtwdev = hw->priv;
388 struct rtw89_vif *rtwvif = (struct rtw89_vif *)vif->drv_priv;
389
390 mutex_lock(&rtwdev->mutex);
391 ether_addr_copy(rtwvif->bssid, vif->bss_conf.bssid);
392 rtw89_cam_bssid_changed(rtwdev, rtwvif);
393 rtw89_mac_port_update(rtwdev, rtwvif);
394 rtw89_fw_h2c_assoc_cmac_tbl(rtwdev, vif, NULL);
395 rtw89_fw_h2c_role_maintain(rtwdev, rtwvif, NULL, RTW89_ROLE_TYPE_CHANGE);
396 rtw89_fw_h2c_join_info(rtwdev, rtwvif, NULL, true);
397 rtw89_fw_h2c_cam(rtwdev, rtwvif, NULL, NULL);
398 rtw89_chip_rfk_channel(rtwdev);
399 mutex_unlock(&rtwdev->mutex);
400
401 return 0;
402}
403
404static
ae7ba17b
ST
405void rtw89_ops_stop_ap(struct ieee80211_hw *hw, struct ieee80211_vif *vif,
406 unsigned int link_id)
a52e4f2c
PKS
407{
408 struct rtw89_dev *rtwdev = hw->priv;
409 struct rtw89_vif *rtwvif = (struct rtw89_vif *)vif->drv_priv;
410
411 mutex_lock(&rtwdev->mutex);
412 rtw89_fw_h2c_assoc_cmac_tbl(rtwdev, vif, NULL);
413 rtw89_fw_h2c_join_info(rtwdev, rtwvif, NULL, true);
414 mutex_unlock(&rtwdev->mutex);
415}
416
d62816b4
PKS
417static int rtw89_ops_set_tim(struct ieee80211_hw *hw, struct ieee80211_sta *sta,
418 bool set)
419{
420 struct rtw89_dev *rtwdev = hw->priv;
421 struct rtw89_sta *rtwsta = (struct rtw89_sta *)sta->drv_priv;
422 struct rtw89_vif *rtwvif = rtwsta->rtwvif;
423
424 ieee80211_queue_work(rtwdev->hw, &rtwvif->update_beacon_work);
425
426 return 0;
427}
428
e3ec7017 429static int rtw89_ops_conf_tx(struct ieee80211_hw *hw,
b3e2130b
JB
430 struct ieee80211_vif *vif,
431 unsigned int link_id, u16 ac,
e3ec7017
PKS
432 const struct ieee80211_tx_queue_params *params)
433{
434 struct rtw89_dev *rtwdev = hw->priv;
435 struct rtw89_vif *rtwvif = (struct rtw89_vif *)vif->drv_priv;
436
437 mutex_lock(&rtwdev->mutex);
438 rtw89_leave_ps_mode(rtwdev);
439 rtwvif->tx_params[ac] = *params;
440 __rtw89_conf_tx(rtwdev, rtwvif, ac);
441 mutex_unlock(&rtwdev->mutex);
442
443 return 0;
444}
445
446static int __rtw89_ops_sta_state(struct ieee80211_hw *hw,
447 struct ieee80211_vif *vif,
448 struct ieee80211_sta *sta,
449 enum ieee80211_sta_state old_state,
450 enum ieee80211_sta_state new_state)
451{
452 struct rtw89_dev *rtwdev = hw->priv;
453
454 if (old_state == IEEE80211_STA_NOTEXIST &&
455 new_state == IEEE80211_STA_NONE)
456 return rtw89_core_sta_add(rtwdev, vif, sta);
457
458 if (old_state == IEEE80211_STA_AUTH &&
459 new_state == IEEE80211_STA_ASSOC) {
7312100d 460 if (vif->type == NL80211_IFTYPE_STATION && !sta->tdls)
e3ec7017
PKS
461 return 0; /* defer to bss_info_changed to have vif info */
462 return rtw89_core_sta_assoc(rtwdev, vif, sta);
463 }
464
465 if (old_state == IEEE80211_STA_ASSOC &&
466 new_state == IEEE80211_STA_AUTH)
467 return rtw89_core_sta_disassoc(rtwdev, vif, sta);
468
469 if (old_state == IEEE80211_STA_AUTH &&
470 new_state == IEEE80211_STA_NONE)
471 return rtw89_core_sta_disconnect(rtwdev, vif, sta);
472
473 if (old_state == IEEE80211_STA_NONE &&
474 new_state == IEEE80211_STA_NOTEXIST)
475 return rtw89_core_sta_remove(rtwdev, vif, sta);
476
477 return 0;
478}
479
480static int rtw89_ops_sta_state(struct ieee80211_hw *hw,
481 struct ieee80211_vif *vif,
482 struct ieee80211_sta *sta,
483 enum ieee80211_sta_state old_state,
484 enum ieee80211_sta_state new_state)
485{
486 struct rtw89_dev *rtwdev = hw->priv;
487 int ret;
488
489 mutex_lock(&rtwdev->mutex);
490 rtw89_leave_ps_mode(rtwdev);
491 ret = __rtw89_ops_sta_state(hw, vif, sta, old_state, new_state);
492 mutex_unlock(&rtwdev->mutex);
493
494 return ret;
495}
496
497static int rtw89_ops_set_key(struct ieee80211_hw *hw, enum set_key_cmd cmd,
498 struct ieee80211_vif *vif,
499 struct ieee80211_sta *sta,
500 struct ieee80211_key_conf *key)
501{
502 struct rtw89_dev *rtwdev = hw->priv;
503 int ret = 0;
504
505 mutex_lock(&rtwdev->mutex);
506 rtw89_leave_ps_mode(rtwdev);
507
508 switch (cmd) {
509 case SET_KEY:
510 rtw89_btc_ntfy_specific_packet(rtwdev, PACKET_EAPOL_END);
511 ret = rtw89_cam_sec_key_add(rtwdev, vif, sta, key);
512 if (ret && ret != -EOPNOTSUPP) {
513 rtw89_err(rtwdev, "failed to add key to sec cam\n");
514 goto out;
515 }
516 break;
517 case DISABLE_KEY:
518 rtw89_hci_flush_queues(rtwdev, BIT(rtwdev->hw->queues) - 1,
519 false);
520 rtw89_mac_flush_txq(rtwdev, BIT(rtwdev->hw->queues) - 1, false);
521 ret = rtw89_cam_sec_key_del(rtwdev, vif, sta, key, true);
522 if (ret) {
523 rtw89_err(rtwdev, "failed to remove key from sec cam\n");
524 goto out;
525 }
526 break;
527 }
528
529out:
530 mutex_unlock(&rtwdev->mutex);
531
532 return ret;
533}
534
535static int rtw89_ops_ampdu_action(struct ieee80211_hw *hw,
536 struct ieee80211_vif *vif,
537 struct ieee80211_ampdu_params *params)
538{
539 struct rtw89_dev *rtwdev = hw->priv;
540 struct ieee80211_sta *sta = params->sta;
541 struct rtw89_sta *rtwsta = (struct rtw89_sta *)sta->drv_priv;
542 u16 tid = params->tid;
543 struct ieee80211_txq *txq = sta->txq[tid];
544 struct rtw89_txq *rtwtxq = (struct rtw89_txq *)txq->drv_priv;
545
546 switch (params->action) {
547 case IEEE80211_AMPDU_TX_START:
548 return IEEE80211_AMPDU_TX_START_IMMEDIATE;
549 case IEEE80211_AMPDU_TX_STOP_CONT:
550 case IEEE80211_AMPDU_TX_STOP_FLUSH:
551 case IEEE80211_AMPDU_TX_STOP_FLUSH_CONT:
552 mutex_lock(&rtwdev->mutex);
553 clear_bit(RTW89_TXQ_F_AMPDU, &rtwtxq->flags);
e3ec7017
PKS
554 mutex_unlock(&rtwdev->mutex);
555 ieee80211_stop_tx_ba_cb_irqsafe(vif, sta->addr, tid);
556 break;
557 case IEEE80211_AMPDU_TX_OPERATIONAL:
558 mutex_lock(&rtwdev->mutex);
559 set_bit(RTW89_TXQ_F_AMPDU, &rtwtxq->flags);
560 rtwsta->ampdu_params[tid].agg_num = params->buf_size;
561 rtwsta->ampdu_params[tid].amsdu = params->amsdu;
562 rtw89_leave_ps_mode(rtwdev);
e3ec7017
PKS
563 mutex_unlock(&rtwdev->mutex);
564 break;
565 case IEEE80211_AMPDU_RX_START:
3ffbb5a8
PKS
566 mutex_lock(&rtwdev->mutex);
567 rtw89_fw_h2c_ba_cam(rtwdev, rtwsta, true, params);
568 mutex_unlock(&rtwdev->mutex);
569 break;
e3ec7017 570 case IEEE80211_AMPDU_RX_STOP:
3ffbb5a8
PKS
571 mutex_lock(&rtwdev->mutex);
572 rtw89_fw_h2c_ba_cam(rtwdev, rtwsta, false, params);
573 mutex_unlock(&rtwdev->mutex);
e3ec7017
PKS
574 break;
575 default:
576 WARN_ON(1);
577 return -ENOTSUPP;
578 }
579
580 return 0;
581}
582
583static int rtw89_ops_set_rts_threshold(struct ieee80211_hw *hw, u32 value)
584{
585 struct rtw89_dev *rtwdev = hw->priv;
586
587 mutex_lock(&rtwdev->mutex);
588 rtw89_leave_ps_mode(rtwdev);
589 if (test_bit(RTW89_FLAG_POWERON, rtwdev->flags))
590 rtw89_mac_update_rts_threshold(rtwdev, RTW89_MAC_0);
591 mutex_unlock(&rtwdev->mutex);
592
593 return 0;
594}
595
596static void rtw89_ops_sta_statistics(struct ieee80211_hw *hw,
597 struct ieee80211_vif *vif,
598 struct ieee80211_sta *sta,
599 struct station_info *sinfo)
600{
601 struct rtw89_sta *rtwsta = (struct rtw89_sta *)sta->drv_priv;
602
603 sinfo->txrate = rtwsta->ra_report.txrate;
604 sinfo->filled |= BIT_ULL(NL80211_STA_INFO_TX_BITRATE);
605}
606
607static void rtw89_ops_flush(struct ieee80211_hw *hw, struct ieee80211_vif *vif,
608 u32 queues, bool drop)
609{
610 struct rtw89_dev *rtwdev = hw->priv;
611
612 mutex_lock(&rtwdev->mutex);
613 rtw89_leave_lps(rtwdev);
614 rtw89_hci_flush_queues(rtwdev, queues, drop);
615 rtw89_mac_flush_txq(rtwdev, queues, drop);
616 mutex_unlock(&rtwdev->mutex);
617}
618
619struct rtw89_iter_bitrate_mask_data {
620 struct rtw89_dev *rtwdev;
621 struct ieee80211_vif *vif;
622 const struct cfg80211_bitrate_mask *mask;
623};
624
625static void rtw89_ra_mask_info_update_iter(void *data, struct ieee80211_sta *sta)
626{
627 struct rtw89_iter_bitrate_mask_data *br_data = data;
628 struct rtw89_sta *rtwsta = (struct rtw89_sta *)sta->drv_priv;
629 struct ieee80211_vif *vif = rtwvif_to_vif(rtwsta->rtwvif);
630
631 if (vif != br_data->vif)
632 return;
633
634 rtwsta->use_cfg_mask = true;
635 rtwsta->mask = *br_data->mask;
9d9a9edc 636 rtw89_phy_ra_updata_sta(br_data->rtwdev, sta, IEEE80211_RC_SUPP_RATES_CHANGED);
e3ec7017
PKS
637}
638
639static void rtw89_ra_mask_info_update(struct rtw89_dev *rtwdev,
640 struct ieee80211_vif *vif,
641 const struct cfg80211_bitrate_mask *mask)
642{
643 struct rtw89_iter_bitrate_mask_data br_data = { .rtwdev = rtwdev,
644 .vif = vif,
645 .mask = mask};
646
647 ieee80211_iterate_stations_atomic(rtwdev->hw, rtw89_ra_mask_info_update_iter,
648 &br_data);
649}
650
651static int rtw89_ops_set_bitrate_mask(struct ieee80211_hw *hw,
652 struct ieee80211_vif *vif,
653 const struct cfg80211_bitrate_mask *mask)
654{
655 struct rtw89_dev *rtwdev = hw->priv;
656
657 mutex_lock(&rtwdev->mutex);
658 rtw89_phy_rate_pattern_vif(rtwdev, vif, mask);
659 rtw89_ra_mask_info_update(rtwdev, vif, mask);
660 mutex_unlock(&rtwdev->mutex);
661
662 return 0;
663}
664
665static
666int rtw89_ops_set_antenna(struct ieee80211_hw *hw, u32 tx_ant, u32 rx_ant)
667{
668 struct rtw89_dev *rtwdev = hw->priv;
669 struct rtw89_hal *hal = &rtwdev->hal;
670
671 if (rx_ant != hw->wiphy->available_antennas_rx)
672 return -EINVAL;
673
674 mutex_lock(&rtwdev->mutex);
675 hal->antenna_tx = tx_ant;
676 hal->antenna_rx = rx_ant;
677 mutex_unlock(&rtwdev->mutex);
678
679 return 0;
680}
681
682static
683int rtw89_ops_get_antenna(struct ieee80211_hw *hw, u32 *tx_ant, u32 *rx_ant)
684{
685 struct rtw89_dev *rtwdev = hw->priv;
686 struct rtw89_hal *hal = &rtwdev->hal;
687
688 *tx_ant = hal->antenna_tx;
689 *rx_ant = hal->antenna_rx;
690
691 return 0;
692}
693
694static void rtw89_ops_sw_scan_start(struct ieee80211_hw *hw,
695 struct ieee80211_vif *vif,
696 const u8 *mac_addr)
697{
698 struct rtw89_dev *rtwdev = hw->priv;
e45a9e62 699 struct rtw89_vif *rtwvif = (struct rtw89_vif *)vif->drv_priv;
e3ec7017
PKS
700
701 mutex_lock(&rtwdev->mutex);
89590777 702 rtw89_core_scan_start(rtwdev, rtwvif, mac_addr, false);
e3ec7017
PKS
703 mutex_unlock(&rtwdev->mutex);
704}
705
706static void rtw89_ops_sw_scan_complete(struct ieee80211_hw *hw,
707 struct ieee80211_vif *vif)
708{
709 struct rtw89_dev *rtwdev = hw->priv;
710
711 mutex_lock(&rtwdev->mutex);
89590777 712 rtw89_core_scan_complete(rtwdev, vif, false);
e3ec7017
PKS
713 mutex_unlock(&rtwdev->mutex);
714}
715
716static void rtw89_ops_reconfig_complete(struct ieee80211_hw *hw,
717 enum ieee80211_reconfig_type reconfig_type)
718{
719 struct rtw89_dev *rtwdev = hw->priv;
720
721 if (reconfig_type == IEEE80211_RECONFIG_TYPE_RESTART)
722 rtw89_ser_recfg_done(rtwdev);
723}
724
89590777
PHH
725static int rtw89_ops_hw_scan(struct ieee80211_hw *hw, struct ieee80211_vif *vif,
726 struct ieee80211_scan_request *req)
727{
728 struct rtw89_dev *rtwdev = hw->priv;
729 int ret = 0;
730
11fe4ccd 731 if (!RTW89_CHK_FW_FEATURE(SCAN_OFFLOAD, &rtwdev->fw))
89590777
PHH
732 return 1;
733
734 if (rtwdev->scanning)
735 return -EBUSY;
736
737 mutex_lock(&rtwdev->mutex);
738 rtw89_hw_scan_start(rtwdev, vif, req);
739 ret = rtw89_hw_scan_offload(rtwdev, vif, true);
740 if (ret) {
741 rtw89_hw_scan_abort(rtwdev, vif);
742 rtw89_err(rtwdev, "HW scan failed with status: %d\n", ret);
743 }
744 mutex_unlock(&rtwdev->mutex);
745
746 return ret;
747}
748
749static void rtw89_ops_cancel_hw_scan(struct ieee80211_hw *hw,
750 struct ieee80211_vif *vif)
751{
752 struct rtw89_dev *rtwdev = hw->priv;
753
11fe4ccd 754 if (!RTW89_CHK_FW_FEATURE(SCAN_OFFLOAD, &rtwdev->fw))
89590777
PHH
755 return;
756
757 if (!rtwdev->scanning)
758 return;
759
760 mutex_lock(&rtwdev->mutex);
761 rtw89_hw_scan_abort(rtwdev, vif);
762 mutex_unlock(&rtwdev->mutex);
763}
764
9d9a9edc
PKS
765static void rtw89_ops_sta_rc_update(struct ieee80211_hw *hw,
766 struct ieee80211_vif *vif,
767 struct ieee80211_sta *sta, u32 changed)
768{
769 struct rtw89_dev *rtwdev = hw->priv;
770
771 rtw89_phy_ra_updata_sta(rtwdev, sta, changed);
772}
773
e3ec7017
PKS
774const struct ieee80211_ops rtw89_ops = {
775 .tx = rtw89_ops_tx,
776 .wake_tx_queue = rtw89_ops_wake_tx_queue,
777 .start = rtw89_ops_start,
778 .stop = rtw89_ops_stop,
779 .config = rtw89_ops_config,
780 .add_interface = rtw89_ops_add_interface,
781 .remove_interface = rtw89_ops_remove_interface,
782 .configure_filter = rtw89_ops_configure_filter,
783 .bss_info_changed = rtw89_ops_bss_info_changed,
a52e4f2c
PKS
784 .start_ap = rtw89_ops_start_ap,
785 .stop_ap = rtw89_ops_stop_ap,
d62816b4 786 .set_tim = rtw89_ops_set_tim,
e3ec7017
PKS
787 .conf_tx = rtw89_ops_conf_tx,
788 .sta_state = rtw89_ops_sta_state,
789 .set_key = rtw89_ops_set_key,
790 .ampdu_action = rtw89_ops_ampdu_action,
791 .set_rts_threshold = rtw89_ops_set_rts_threshold,
792 .sta_statistics = rtw89_ops_sta_statistics,
793 .flush = rtw89_ops_flush,
794 .set_bitrate_mask = rtw89_ops_set_bitrate_mask,
795 .set_antenna = rtw89_ops_set_antenna,
796 .get_antenna = rtw89_ops_get_antenna,
797 .sw_scan_start = rtw89_ops_sw_scan_start,
798 .sw_scan_complete = rtw89_ops_sw_scan_complete,
799 .reconfig_complete = rtw89_ops_reconfig_complete,
89590777
PHH
800 .hw_scan = rtw89_ops_hw_scan,
801 .cancel_hw_scan = rtw89_ops_cancel_hw_scan,
e3ec7017 802 .set_sar_specs = rtw89_ops_set_sar_specs,
9d9a9edc 803 .sta_rc_update = rtw89_ops_sta_rc_update,
e3ec7017
PKS
804};
805EXPORT_SYMBOL(rtw89_ops);