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