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