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