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