1 // SPDX-License-Identifier: GPL-2.0 OR BSD-3-Clause
2 /* Copyright(c) 2018-2019 Realtek Corporation
17 static void rtw_ops_tx(struct ieee80211_hw
*hw
,
18 struct ieee80211_tx_control
*control
,
21 struct rtw_dev
*rtwdev
= hw
->priv
;
23 if (!test_bit(RTW_FLAG_RUNNING
, rtwdev
->flags
)) {
24 ieee80211_free_txskb(hw
, skb
);
28 rtw_tx(rtwdev
, control
, skb
);
31 static void rtw_ops_wake_tx_queue(struct ieee80211_hw
*hw
,
32 struct ieee80211_txq
*txq
)
34 struct rtw_dev
*rtwdev
= hw
->priv
;
35 struct rtw_txq
*rtwtxq
= (struct rtw_txq
*)txq
->drv_priv
;
37 if (!test_bit(RTW_FLAG_RUNNING
, rtwdev
->flags
))
40 spin_lock_bh(&rtwdev
->txq_lock
);
41 if (list_empty(&rtwtxq
->list
))
42 list_add_tail(&rtwtxq
->list
, &rtwdev
->txqs
);
43 spin_unlock_bh(&rtwdev
->txq_lock
);
45 tasklet_schedule(&rtwdev
->tx_tasklet
);
48 static int rtw_ops_start(struct ieee80211_hw
*hw
)
50 struct rtw_dev
*rtwdev
= hw
->priv
;
53 mutex_lock(&rtwdev
->mutex
);
54 ret
= rtw_core_start(rtwdev
);
55 mutex_unlock(&rtwdev
->mutex
);
60 static void rtw_ops_stop(struct ieee80211_hw
*hw
)
62 struct rtw_dev
*rtwdev
= hw
->priv
;
64 mutex_lock(&rtwdev
->mutex
);
65 rtw_core_stop(rtwdev
);
66 mutex_unlock(&rtwdev
->mutex
);
69 static int rtw_ops_config(struct ieee80211_hw
*hw
, u32 changed
)
71 struct rtw_dev
*rtwdev
= hw
->priv
;
74 mutex_lock(&rtwdev
->mutex
);
76 rtw_leave_lps_deep(rtwdev
);
78 if (changed
& IEEE80211_CONF_CHANGE_IDLE
) {
79 if (hw
->conf
.flags
& IEEE80211_CONF_IDLE
) {
80 rtw_enter_ips(rtwdev
);
82 ret
= rtw_leave_ips(rtwdev
);
84 rtw_err(rtwdev
, "failed to leave idle state\n");
90 if (changed
& IEEE80211_CONF_CHANGE_PS
) {
91 if (hw
->conf
.flags
& IEEE80211_CONF_PS
) {
92 rtwdev
->ps_enabled
= true;
94 rtwdev
->ps_enabled
= false;
95 rtw_leave_lps(rtwdev
);
99 if (changed
& IEEE80211_CONF_CHANGE_CHANNEL
)
100 rtw_set_channel(rtwdev
);
103 mutex_unlock(&rtwdev
->mutex
);
107 static const struct rtw_vif_port rtw_vif_port
[] = {
109 .mac_addr
= {.addr
= 0x0610},
110 .bssid
= {.addr
= 0x0618},
111 .net_type
= {.addr
= 0x0100, .mask
= 0x30000},
112 .aid
= {.addr
= 0x06a8, .mask
= 0x7ff},
113 .bcn_ctrl
= {.addr
= 0x0550, .mask
= 0xff},
116 .mac_addr
= {.addr
= 0x0700},
117 .bssid
= {.addr
= 0x0708},
118 .net_type
= {.addr
= 0x0100, .mask
= 0xc0000},
119 .aid
= {.addr
= 0x0710, .mask
= 0x7ff},
120 .bcn_ctrl
= {.addr
= 0x0551, .mask
= 0xff},
123 .mac_addr
= {.addr
= 0x1620},
124 .bssid
= {.addr
= 0x1628},
125 .net_type
= {.addr
= 0x1100, .mask
= 0x3},
126 .aid
= {.addr
= 0x1600, .mask
= 0x7ff},
127 .bcn_ctrl
= {.addr
= 0x0578, .mask
= 0xff},
130 .mac_addr
= {.addr
= 0x1630},
131 .bssid
= {.addr
= 0x1638},
132 .net_type
= {.addr
= 0x1100, .mask
= 0xc},
133 .aid
= {.addr
= 0x1604, .mask
= 0x7ff},
134 .bcn_ctrl
= {.addr
= 0x0579, .mask
= 0xff},
137 .mac_addr
= {.addr
= 0x1640},
138 .bssid
= {.addr
= 0x1648},
139 .net_type
= {.addr
= 0x1100, .mask
= 0x30},
140 .aid
= {.addr
= 0x1608, .mask
= 0x7ff},
141 .bcn_ctrl
= {.addr
= 0x057a, .mask
= 0xff},
145 static int rtw_ops_add_interface(struct ieee80211_hw
*hw
,
146 struct ieee80211_vif
*vif
)
148 struct rtw_dev
*rtwdev
= hw
->priv
;
149 struct rtw_vif
*rtwvif
= (struct rtw_vif
*)vif
->drv_priv
;
150 enum rtw_net_type net_type
;
156 rtwvif
->stats
.tx_unicast
= 0;
157 rtwvif
->stats
.rx_unicast
= 0;
158 rtwvif
->stats
.tx_cnt
= 0;
159 rtwvif
->stats
.rx_cnt
= 0;
160 memset(&rtwvif
->bfee
, 0, sizeof(struct rtw_bfee
));
161 rtwvif
->conf
= &rtw_vif_port
[port
];
162 rtw_txq_init(rtwdev
, vif
->txq
);
164 mutex_lock(&rtwdev
->mutex
);
166 rtw_leave_lps_deep(rtwdev
);
169 case NL80211_IFTYPE_AP
:
170 case NL80211_IFTYPE_MESH_POINT
:
171 net_type
= RTW_NET_AP_MODE
;
172 bcn_ctrl
= BIT_EN_BCN_FUNCTION
| BIT_DIS_TSF_UDT
;
174 case NL80211_IFTYPE_ADHOC
:
175 net_type
= RTW_NET_AD_HOC
;
176 bcn_ctrl
= BIT_EN_BCN_FUNCTION
| BIT_DIS_TSF_UDT
;
178 case NL80211_IFTYPE_STATION
:
180 net_type
= RTW_NET_NO_LINK
;
181 bcn_ctrl
= BIT_EN_BCN_FUNCTION
;
185 ether_addr_copy(rtwvif
->mac_addr
, vif
->addr
);
186 config
|= PORT_SET_MAC_ADDR
;
187 rtwvif
->net_type
= net_type
;
188 config
|= PORT_SET_NET_TYPE
;
189 rtwvif
->bcn_ctrl
= bcn_ctrl
;
190 config
|= PORT_SET_BCN_CTRL
;
191 rtw_vif_port_config(rtwdev
, rtwvif
, config
);
193 mutex_unlock(&rtwdev
->mutex
);
195 rtw_info(rtwdev
, "start vif %pM on port %d\n", vif
->addr
, rtwvif
->port
);
199 static void rtw_ops_remove_interface(struct ieee80211_hw
*hw
,
200 struct ieee80211_vif
*vif
)
202 struct rtw_dev
*rtwdev
= hw
->priv
;
203 struct rtw_vif
*rtwvif
= (struct rtw_vif
*)vif
->drv_priv
;
206 rtw_info(rtwdev
, "stop vif %pM on port %d\n", vif
->addr
, rtwvif
->port
);
208 mutex_lock(&rtwdev
->mutex
);
210 rtw_leave_lps_deep(rtwdev
);
212 rtw_txq_cleanup(rtwdev
, vif
->txq
);
214 eth_zero_addr(rtwvif
->mac_addr
);
215 config
|= PORT_SET_MAC_ADDR
;
216 rtwvif
->net_type
= RTW_NET_NO_LINK
;
217 config
|= PORT_SET_NET_TYPE
;
218 rtwvif
->bcn_ctrl
= 0;
219 config
|= PORT_SET_BCN_CTRL
;
220 rtw_vif_port_config(rtwdev
, rtwvif
, config
);
222 mutex_unlock(&rtwdev
->mutex
);
225 static void rtw_ops_configure_filter(struct ieee80211_hw
*hw
,
226 unsigned int changed_flags
,
227 unsigned int *new_flags
,
230 struct rtw_dev
*rtwdev
= hw
->priv
;
232 *new_flags
&= FIF_ALLMULTI
| FIF_OTHER_BSS
| FIF_FCSFAIL
|
233 FIF_BCN_PRBRESP_PROMISC
;
235 mutex_lock(&rtwdev
->mutex
);
237 rtw_leave_lps_deep(rtwdev
);
239 if (changed_flags
& FIF_ALLMULTI
) {
240 if (*new_flags
& FIF_ALLMULTI
)
241 rtwdev
->hal
.rcr
|= BIT_AM
| BIT_AB
;
243 rtwdev
->hal
.rcr
&= ~(BIT_AM
| BIT_AB
);
245 if (changed_flags
& FIF_FCSFAIL
) {
246 if (*new_flags
& FIF_FCSFAIL
)
247 rtwdev
->hal
.rcr
|= BIT_ACRC32
;
249 rtwdev
->hal
.rcr
&= ~(BIT_ACRC32
);
251 if (changed_flags
& FIF_OTHER_BSS
) {
252 if (*new_flags
& FIF_OTHER_BSS
)
253 rtwdev
->hal
.rcr
|= BIT_AAP
;
255 rtwdev
->hal
.rcr
&= ~(BIT_AAP
);
257 if (changed_flags
& FIF_BCN_PRBRESP_PROMISC
) {
258 if (*new_flags
& FIF_BCN_PRBRESP_PROMISC
)
259 rtwdev
->hal
.rcr
&= ~(BIT_CBSSID_BCN
| BIT_CBSSID_DATA
);
261 rtwdev
->hal
.rcr
|= BIT_CBSSID_BCN
;
264 rtw_dbg(rtwdev
, RTW_DBG_RX
,
265 "config rx filter, changed=0x%08x, new=0x%08x, rcr=0x%08x\n",
266 changed_flags
, *new_flags
, rtwdev
->hal
.rcr
);
268 rtw_write32(rtwdev
, REG_RCR
, rtwdev
->hal
.rcr
);
270 mutex_unlock(&rtwdev
->mutex
);
273 /* Only have one group of EDCA parameters now */
274 static const u32 ac_to_edca_param
[IEEE80211_NUM_ACS
] = {
275 [IEEE80211_AC_VO
] = REG_EDCA_VO_PARAM
,
276 [IEEE80211_AC_VI
] = REG_EDCA_VI_PARAM
,
277 [IEEE80211_AC_BE
] = REG_EDCA_BE_PARAM
,
278 [IEEE80211_AC_BK
] = REG_EDCA_BK_PARAM
,
281 static u8
rtw_aifsn_to_aifs(struct rtw_dev
*rtwdev
,
282 struct rtw_vif
*rtwvif
, u8 aifsn
)
284 struct ieee80211_vif
*vif
= rtwvif_to_vif(rtwvif
);
288 slot_time
= vif
->bss_conf
.use_short_slot
? 9 : 20;
289 sifs
= rtwdev
->hal
.current_band_type
== RTW_BAND_5G
? 16 : 10;
291 return aifsn
* slot_time
+ sifs
;
294 static void __rtw_conf_tx(struct rtw_dev
*rtwdev
,
295 struct rtw_vif
*rtwvif
, u16 ac
)
297 struct ieee80211_tx_queue_params
*params
= &rtwvif
->tx_params
[ac
];
298 u32 edca_param
= ac_to_edca_param
[ac
];
302 /* 2^ecw - 1 = cw; ecw = log2(cw + 1) */
303 ecw_max
= ilog2(params
->cw_max
+ 1);
304 ecw_min
= ilog2(params
->cw_min
+ 1);
305 aifs
= rtw_aifsn_to_aifs(rtwdev
, rtwvif
, params
->aifs
);
306 rtw_write32_mask(rtwdev
, edca_param
, BIT_MASK_TXOP_LMT
, params
->txop
);
307 rtw_write32_mask(rtwdev
, edca_param
, BIT_MASK_CWMAX
, ecw_max
);
308 rtw_write32_mask(rtwdev
, edca_param
, BIT_MASK_CWMIN
, ecw_min
);
309 rtw_write32_mask(rtwdev
, edca_param
, BIT_MASK_AIFS
, aifs
);
312 static void rtw_conf_tx(struct rtw_dev
*rtwdev
,
313 struct rtw_vif
*rtwvif
)
317 for (ac
= 0; ac
< IEEE80211_NUM_ACS
; ac
++)
318 __rtw_conf_tx(rtwdev
, rtwvif
, ac
);
321 static void rtw_ops_bss_info_changed(struct ieee80211_hw
*hw
,
322 struct ieee80211_vif
*vif
,
323 struct ieee80211_bss_conf
*conf
,
326 struct rtw_dev
*rtwdev
= hw
->priv
;
327 struct rtw_vif
*rtwvif
= (struct rtw_vif
*)vif
->drv_priv
;
330 mutex_lock(&rtwdev
->mutex
);
332 rtw_leave_lps_deep(rtwdev
);
334 if (changed
& BSS_CHANGED_ASSOC
) {
335 struct rtw_chip_info
*chip
= rtwdev
->chip
;
336 enum rtw_net_type net_type
;
339 rtw_coex_connect_notify(rtwdev
, COEX_ASSOCIATE_FINISH
);
340 net_type
= RTW_NET_MGD_LINKED
;
341 chip
->ops
->phy_calibration(rtwdev
);
343 rtwvif
->aid
= conf
->aid
;
344 rtw_add_rsvd_page(rtwdev
, RSVD_PS_POLL
, true);
345 rtw_add_rsvd_page(rtwdev
, RSVD_QOS_NULL
, true);
346 rtw_add_rsvd_page(rtwdev
, RSVD_NULL
, true);
347 rtw_add_rsvd_page(rtwdev
, RSVD_LPS_PG_DPK
, true);
348 rtw_add_rsvd_page(rtwdev
, RSVD_LPS_PG_INFO
, true);
349 rtw_fw_download_rsvd_page(rtwdev
, vif
);
350 rtw_send_rsvd_page_h2c(rtwdev
);
351 rtw_coex_media_status_notify(rtwdev
, conf
->assoc
);
353 rtw_bf_assoc(rtwdev
, vif
, conf
);
355 rtw_leave_lps(rtwdev
);
356 net_type
= RTW_NET_NO_LINK
;
358 rtw_reset_rsvd_page(rtwdev
);
359 rtw_bf_disassoc(rtwdev
, vif
, conf
);
362 rtwvif
->net_type
= net_type
;
363 config
|= PORT_SET_NET_TYPE
;
364 config
|= PORT_SET_AID
;
367 if (changed
& BSS_CHANGED_BSSID
) {
368 ether_addr_copy(rtwvif
->bssid
, conf
->bssid
);
369 config
|= PORT_SET_BSSID
;
372 if (changed
& BSS_CHANGED_BEACON
)
373 rtw_fw_download_rsvd_page(rtwdev
, vif
);
375 if (changed
& BSS_CHANGED_MU_GROUPS
) {
376 struct rtw_chip_info
*chip
= rtwdev
->chip
;
378 chip
->ops
->set_gid_table(rtwdev
, vif
, conf
);
381 if (changed
& BSS_CHANGED_ERP_SLOT
)
382 rtw_conf_tx(rtwdev
, rtwvif
);
384 rtw_vif_port_config(rtwdev
, rtwvif
, config
);
386 mutex_unlock(&rtwdev
->mutex
);
389 static int rtw_ops_conf_tx(struct ieee80211_hw
*hw
,
390 struct ieee80211_vif
*vif
, u16 ac
,
391 const struct ieee80211_tx_queue_params
*params
)
393 struct rtw_dev
*rtwdev
= hw
->priv
;
394 struct rtw_vif
*rtwvif
= (struct rtw_vif
*)vif
->drv_priv
;
396 mutex_lock(&rtwdev
->mutex
);
398 rtw_leave_lps_deep(rtwdev
);
400 rtwvif
->tx_params
[ac
] = *params
;
401 __rtw_conf_tx(rtwdev
, rtwvif
, ac
);
403 mutex_unlock(&rtwdev
->mutex
);
408 static u8
rtw_acquire_macid(struct rtw_dev
*rtwdev
)
410 unsigned long mac_id
;
412 mac_id
= find_first_zero_bit(rtwdev
->mac_id_map
, RTW_MAX_MAC_ID_NUM
);
413 if (mac_id
< RTW_MAX_MAC_ID_NUM
)
414 set_bit(mac_id
, rtwdev
->mac_id_map
);
419 static void rtw_release_macid(struct rtw_dev
*rtwdev
, u8 mac_id
)
421 clear_bit(mac_id
, rtwdev
->mac_id_map
);
424 static int rtw_ops_sta_add(struct ieee80211_hw
*hw
,
425 struct ieee80211_vif
*vif
,
426 struct ieee80211_sta
*sta
)
428 struct rtw_dev
*rtwdev
= hw
->priv
;
429 struct rtw_sta_info
*si
= (struct rtw_sta_info
*)sta
->drv_priv
;
433 mutex_lock(&rtwdev
->mutex
);
435 si
->mac_id
= rtw_acquire_macid(rtwdev
);
436 if (si
->mac_id
>= RTW_MAX_MAC_ID_NUM
) {
444 ewma_rssi_init(&si
->avg_rssi
);
445 for (i
= 0; i
< ARRAY_SIZE(sta
->txq
); i
++)
446 rtw_txq_init(rtwdev
, sta
->txq
[i
]);
448 rtw_update_sta_info(rtwdev
, si
);
449 rtw_fw_media_status_report(rtwdev
, si
->mac_id
, true);
453 rtw_info(rtwdev
, "sta %pM joined with macid %d\n",
454 sta
->addr
, si
->mac_id
);
457 mutex_unlock(&rtwdev
->mutex
);
461 static int rtw_ops_sta_remove(struct ieee80211_hw
*hw
,
462 struct ieee80211_vif
*vif
,
463 struct ieee80211_sta
*sta
)
465 struct rtw_dev
*rtwdev
= hw
->priv
;
466 struct rtw_sta_info
*si
= (struct rtw_sta_info
*)sta
->drv_priv
;
469 mutex_lock(&rtwdev
->mutex
);
471 rtw_release_macid(rtwdev
, si
->mac_id
);
472 rtw_fw_media_status_report(rtwdev
, si
->mac_id
, false);
474 for (i
= 0; i
< ARRAY_SIZE(sta
->txq
); i
++)
475 rtw_txq_cleanup(rtwdev
, sta
->txq
[i
]);
481 rtw_info(rtwdev
, "sta %pM with macid %d left\n",
482 sta
->addr
, si
->mac_id
);
484 mutex_unlock(&rtwdev
->mutex
);
488 static int rtw_ops_set_key(struct ieee80211_hw
*hw
, enum set_key_cmd cmd
,
489 struct ieee80211_vif
*vif
, struct ieee80211_sta
*sta
,
490 struct ieee80211_key_conf
*key
)
492 struct rtw_dev
*rtwdev
= hw
->priv
;
493 struct rtw_sec_desc
*sec
= &rtwdev
->sec
;
498 switch (key
->cipher
) {
499 case WLAN_CIPHER_SUITE_WEP40
:
500 hw_key_type
= RTW_CAM_WEP40
;
502 case WLAN_CIPHER_SUITE_WEP104
:
503 hw_key_type
= RTW_CAM_WEP104
;
505 case WLAN_CIPHER_SUITE_TKIP
:
506 hw_key_type
= RTW_CAM_TKIP
;
507 key
->flags
|= IEEE80211_KEY_FLAG_GENERATE_MMIC
;
509 case WLAN_CIPHER_SUITE_CCMP
:
510 hw_key_type
= RTW_CAM_AES
;
511 key
->flags
|= IEEE80211_KEY_FLAG_SW_MGMT_TX
;
513 case WLAN_CIPHER_SUITE_AES_CMAC
:
514 case WLAN_CIPHER_SUITE_BIP_CMAC_256
:
515 case WLAN_CIPHER_SUITE_BIP_GMAC_128
:
516 case WLAN_CIPHER_SUITE_BIP_GMAC_256
:
517 /* suppress error messages */
523 mutex_lock(&rtwdev
->mutex
);
525 rtw_leave_lps_deep(rtwdev
);
527 if (key
->flags
& IEEE80211_KEY_FLAG_PAIRWISE
) {
528 hw_key_idx
= rtw_sec_get_free_cam(sec
);
530 /* multiple interfaces? */
531 hw_key_idx
= key
->keyidx
;
534 if (hw_key_idx
> sec
->total_cam_num
) {
541 /* need sw generated IV */
542 key
->flags
|= IEEE80211_KEY_FLAG_GENERATE_IV
;
543 key
->hw_key_idx
= hw_key_idx
;
544 rtw_sec_write_cam(rtwdev
, sec
, sta
, key
,
545 hw_key_type
, hw_key_idx
);
548 rtw_mac_flush_all_queues(rtwdev
, false);
549 rtw_sec_clear_cam(rtwdev
, sec
, key
->hw_key_idx
);
553 /* download new cam settings for PG to backup */
554 if (rtw_fw_lps_deep_mode
== LPS_DEEP_MODE_PG
)
555 rtw_fw_download_rsvd_page(rtwdev
, vif
);
558 mutex_unlock(&rtwdev
->mutex
);
563 static int rtw_ops_ampdu_action(struct ieee80211_hw
*hw
,
564 struct ieee80211_vif
*vif
,
565 struct ieee80211_ampdu_params
*params
)
567 struct ieee80211_sta
*sta
= params
->sta
;
568 u16 tid
= params
->tid
;
569 struct ieee80211_txq
*txq
= sta
->txq
[tid
];
570 struct rtw_txq
*rtwtxq
= (struct rtw_txq
*)txq
->drv_priv
;
572 switch (params
->action
) {
573 case IEEE80211_AMPDU_TX_START
:
574 return IEEE80211_AMPDU_TX_START_IMMEDIATE
;
575 case IEEE80211_AMPDU_TX_STOP_CONT
:
576 case IEEE80211_AMPDU_TX_STOP_FLUSH
:
577 case IEEE80211_AMPDU_TX_STOP_FLUSH_CONT
:
578 clear_bit(RTW_TXQ_AMPDU
, &rtwtxq
->flags
);
579 ieee80211_stop_tx_ba_cb_irqsafe(vif
, sta
->addr
, tid
);
581 case IEEE80211_AMPDU_TX_OPERATIONAL
:
582 set_bit(RTW_TXQ_AMPDU
, &rtwtxq
->flags
);
584 case IEEE80211_AMPDU_RX_START
:
585 case IEEE80211_AMPDU_RX_STOP
:
595 static void rtw_ops_sw_scan_start(struct ieee80211_hw
*hw
,
596 struct ieee80211_vif
*vif
,
599 struct rtw_dev
*rtwdev
= hw
->priv
;
600 struct rtw_vif
*rtwvif
= (struct rtw_vif
*)vif
->drv_priv
;
603 mutex_lock(&rtwdev
->mutex
);
605 rtw_leave_lps(rtwdev
);
607 ether_addr_copy(rtwvif
->mac_addr
, mac_addr
);
608 config
|= PORT_SET_MAC_ADDR
;
609 rtw_vif_port_config(rtwdev
, rtwvif
, config
);
611 rtw_coex_scan_notify(rtwdev
, COEX_SCAN_START
);
613 set_bit(RTW_FLAG_DIG_DISABLE
, rtwdev
->flags
);
614 set_bit(RTW_FLAG_SCANNING
, rtwdev
->flags
);
616 mutex_unlock(&rtwdev
->mutex
);
619 static void rtw_ops_sw_scan_complete(struct ieee80211_hw
*hw
,
620 struct ieee80211_vif
*vif
)
622 struct rtw_dev
*rtwdev
= hw
->priv
;
623 struct rtw_vif
*rtwvif
= (struct rtw_vif
*)vif
->drv_priv
;
626 mutex_lock(&rtwdev
->mutex
);
628 clear_bit(RTW_FLAG_SCANNING
, rtwdev
->flags
);
629 clear_bit(RTW_FLAG_DIG_DISABLE
, rtwdev
->flags
);
631 ether_addr_copy(rtwvif
->mac_addr
, vif
->addr
);
632 config
|= PORT_SET_MAC_ADDR
;
633 rtw_vif_port_config(rtwdev
, rtwvif
, config
);
635 rtw_coex_scan_notify(rtwdev
, COEX_SCAN_FINISH
);
637 mutex_unlock(&rtwdev
->mutex
);
640 static void rtw_ops_mgd_prepare_tx(struct ieee80211_hw
*hw
,
641 struct ieee80211_vif
*vif
,
644 struct rtw_dev
*rtwdev
= hw
->priv
;
646 mutex_lock(&rtwdev
->mutex
);
647 rtw_leave_lps_deep(rtwdev
);
648 rtw_coex_connect_notify(rtwdev
, COEX_ASSOCIATE_START
);
649 mutex_unlock(&rtwdev
->mutex
);
652 static int rtw_ops_set_rts_threshold(struct ieee80211_hw
*hw
, u32 value
)
654 struct rtw_dev
*rtwdev
= hw
->priv
;
656 mutex_lock(&rtwdev
->mutex
);
657 rtwdev
->rts_threshold
= value
;
658 mutex_unlock(&rtwdev
->mutex
);
663 static void rtw_ops_sta_statistics(struct ieee80211_hw
*hw
,
664 struct ieee80211_vif
*vif
,
665 struct ieee80211_sta
*sta
,
666 struct station_info
*sinfo
)
668 struct rtw_sta_info
*si
= (struct rtw_sta_info
*)sta
->drv_priv
;
670 sinfo
->txrate
= si
->ra_report
.txrate
;
671 sinfo
->filled
|= BIT_ULL(NL80211_STA_INFO_TX_BITRATE
);
674 static void rtw_ops_flush(struct ieee80211_hw
*hw
,
675 struct ieee80211_vif
*vif
,
676 u32 queues
, bool drop
)
678 struct rtw_dev
*rtwdev
= hw
->priv
;
680 mutex_lock(&rtwdev
->mutex
);
681 rtw_leave_lps_deep(rtwdev
);
683 rtw_mac_flush_queues(rtwdev
, queues
, drop
);
684 mutex_unlock(&rtwdev
->mutex
);
687 struct rtw_iter_bitrate_mask_data
{
688 struct rtw_dev
*rtwdev
;
689 struct ieee80211_vif
*vif
;
690 const struct cfg80211_bitrate_mask
*mask
;
693 static void rtw_ra_mask_info_update_iter(void *data
, struct ieee80211_sta
*sta
)
695 struct rtw_iter_bitrate_mask_data
*br_data
= data
;
696 struct rtw_sta_info
*si
= (struct rtw_sta_info
*)sta
->drv_priv
;
698 if (si
->vif
!= br_data
->vif
)
701 /* free previous mask setting */
703 si
->mask
= kmemdup(br_data
->mask
, sizeof(struct cfg80211_bitrate_mask
),
706 si
->use_cfg_mask
= false;
710 si
->use_cfg_mask
= true;
711 rtw_update_sta_info(br_data
->rtwdev
, si
);
714 static void rtw_ra_mask_info_update(struct rtw_dev
*rtwdev
,
715 struct ieee80211_vif
*vif
,
716 const struct cfg80211_bitrate_mask
*mask
)
718 struct rtw_iter_bitrate_mask_data br_data
;
720 br_data
.rtwdev
= rtwdev
;
723 rtw_iterate_stas_atomic(rtwdev
, rtw_ra_mask_info_update_iter
, &br_data
);
726 static int rtw_ops_set_bitrate_mask(struct ieee80211_hw
*hw
,
727 struct ieee80211_vif
*vif
,
728 const struct cfg80211_bitrate_mask
*mask
)
730 struct rtw_dev
*rtwdev
= hw
->priv
;
732 rtw_ra_mask_info_update(rtwdev
, vif
, mask
);
738 static int rtw_ops_suspend(struct ieee80211_hw
*hw
,
739 struct cfg80211_wowlan
*wowlan
)
741 struct rtw_dev
*rtwdev
= hw
->priv
;
744 mutex_lock(&rtwdev
->mutex
);
745 ret
= rtw_wow_suspend(rtwdev
, wowlan
);
747 rtw_err(rtwdev
, "failed to suspend for wow %d\n", ret
);
748 mutex_unlock(&rtwdev
->mutex
);
753 static int rtw_ops_resume(struct ieee80211_hw
*hw
)
755 struct rtw_dev
*rtwdev
= hw
->priv
;
758 mutex_lock(&rtwdev
->mutex
);
759 ret
= rtw_wow_resume(rtwdev
);
761 rtw_err(rtwdev
, "failed to resume for wow %d\n", ret
);
762 mutex_unlock(&rtwdev
->mutex
);
767 static void rtw_ops_set_wakeup(struct ieee80211_hw
*hw
, bool enabled
)
769 struct rtw_dev
*rtwdev
= hw
->priv
;
771 device_set_wakeup_enable(rtwdev
->dev
, enabled
);
775 const struct ieee80211_ops rtw_ops
= {
777 .wake_tx_queue
= rtw_ops_wake_tx_queue
,
778 .start
= rtw_ops_start
,
779 .stop
= rtw_ops_stop
,
780 .config
= rtw_ops_config
,
781 .add_interface
= rtw_ops_add_interface
,
782 .remove_interface
= rtw_ops_remove_interface
,
783 .configure_filter
= rtw_ops_configure_filter
,
784 .bss_info_changed
= rtw_ops_bss_info_changed
,
785 .conf_tx
= rtw_ops_conf_tx
,
786 .sta_add
= rtw_ops_sta_add
,
787 .sta_remove
= rtw_ops_sta_remove
,
788 .set_key
= rtw_ops_set_key
,
789 .ampdu_action
= rtw_ops_ampdu_action
,
790 .sw_scan_start
= rtw_ops_sw_scan_start
,
791 .sw_scan_complete
= rtw_ops_sw_scan_complete
,
792 .mgd_prepare_tx
= rtw_ops_mgd_prepare_tx
,
793 .set_rts_threshold
= rtw_ops_set_rts_threshold
,
794 .sta_statistics
= rtw_ops_sta_statistics
,
795 .flush
= rtw_ops_flush
,
796 .set_bitrate_mask
= rtw_ops_set_bitrate_mask
,
798 .suspend
= rtw_ops_suspend
,
799 .resume
= rtw_ops_resume
,
800 .set_wakeup
= rtw_ops_set_wakeup
,
803 EXPORT_SYMBOL(rtw_ops
);