treewide: remove redundant IS_ERR() before error code check
[linux/fpc-iii.git] / drivers / net / wireless / realtek / rtw88 / mac80211.c
blob6fc33e11d08cd74be357ffc9b8761e7d5f4a27c4
1 // SPDX-License-Identifier: GPL-2.0 OR BSD-3-Clause
2 /* Copyright(c) 2018-2019 Realtek Corporation
3 */
5 #include "main.h"
6 #include "sec.h"
7 #include "tx.h"
8 #include "fw.h"
9 #include "mac.h"
10 #include "coex.h"
11 #include "ps.h"
12 #include "reg.h"
13 #include "bf.h"
14 #include "debug.h"
15 #include "wow.h"
17 static void rtw_ops_tx(struct ieee80211_hw *hw,
18 struct ieee80211_tx_control *control,
19 struct sk_buff *skb)
21 struct rtw_dev *rtwdev = hw->priv;
23 if (!test_bit(RTW_FLAG_RUNNING, rtwdev->flags)) {
24 ieee80211_free_txskb(hw, skb);
25 return;
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))
38 return;
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;
51 int ret;
53 mutex_lock(&rtwdev->mutex);
54 ret = rtw_core_start(rtwdev);
55 mutex_unlock(&rtwdev->mutex);
57 return ret;
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;
72 int ret = 0;
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);
81 } else {
82 ret = rtw_leave_ips(rtwdev);
83 if (ret) {
84 rtw_err(rtwdev, "failed to leave idle state\n");
85 goto out;
90 if (changed & IEEE80211_CONF_CHANGE_PS) {
91 if (hw->conf.flags & IEEE80211_CONF_PS) {
92 rtwdev->ps_enabled = true;
93 } else {
94 rtwdev->ps_enabled = false;
95 rtw_leave_lps(rtwdev);
99 if (changed & IEEE80211_CONF_CHANGE_CHANNEL)
100 rtw_set_channel(rtwdev);
102 out:
103 mutex_unlock(&rtwdev->mutex);
104 return ret;
107 static const struct rtw_vif_port rtw_vif_port[] = {
108 [0] = {
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},
115 [1] = {
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},
122 [2] = {
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},
129 [3] = {
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},
136 [4] = {
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;
151 u32 config = 0;
152 u8 port = 0;
153 u8 bcn_ctrl = 0;
155 rtwvif->port = port;
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);
168 switch (vif->type) {
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;
173 break;
174 case NL80211_IFTYPE_ADHOC:
175 net_type = RTW_NET_AD_HOC;
176 bcn_ctrl = BIT_EN_BCN_FUNCTION | BIT_DIS_TSF_UDT;
177 break;
178 case NL80211_IFTYPE_STATION:
179 default:
180 net_type = RTW_NET_NO_LINK;
181 bcn_ctrl = BIT_EN_BCN_FUNCTION;
182 break;
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);
196 return 0;
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;
204 u32 config = 0;
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,
228 u64 multicast)
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;
242 else
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;
248 else
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;
254 else
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);
260 else
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);
285 u8 slot_time;
286 u8 sifs;
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];
299 u8 ecw_max, ecw_min;
300 u8 aifs;
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)
315 u16 ac;
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,
324 u32 changed)
326 struct rtw_dev *rtwdev = hw->priv;
327 struct rtw_vif *rtwvif = (struct rtw_vif *)vif->drv_priv;
328 u32 config = 0;
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;
338 if (conf->assoc) {
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);
352 if (rtw_bf_support)
353 rtw_bf_assoc(rtwdev, vif, conf);
354 } else {
355 rtw_leave_lps(rtwdev);
356 net_type = RTW_NET_NO_LINK;
357 rtwvif->aid = 0;
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);
405 return 0;
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);
416 return mac_id;
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;
430 int i;
431 int ret = 0;
433 mutex_lock(&rtwdev->mutex);
435 si->mac_id = rtw_acquire_macid(rtwdev);
436 if (si->mac_id >= RTW_MAX_MAC_ID_NUM) {
437 ret = -ENOSPC;
438 goto out;
441 si->sta = sta;
442 si->vif = vif;
443 si->init_ra_lv = 1;
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);
451 rtwdev->sta_cnt++;
453 rtw_info(rtwdev, "sta %pM joined with macid %d\n",
454 sta->addr, si->mac_id);
456 out:
457 mutex_unlock(&rtwdev->mutex);
458 return ret;
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;
467 int i;
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]);
477 kfree(si->mask);
479 rtwdev->sta_cnt--;
481 rtw_info(rtwdev, "sta %pM with macid %d left\n",
482 sta->addr, si->mac_id);
484 mutex_unlock(&rtwdev->mutex);
485 return 0;
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;
494 u8 hw_key_type;
495 u8 hw_key_idx;
496 int ret = 0;
498 switch (key->cipher) {
499 case WLAN_CIPHER_SUITE_WEP40:
500 hw_key_type = RTW_CAM_WEP40;
501 break;
502 case WLAN_CIPHER_SUITE_WEP104:
503 hw_key_type = RTW_CAM_WEP104;
504 break;
505 case WLAN_CIPHER_SUITE_TKIP:
506 hw_key_type = RTW_CAM_TKIP;
507 key->flags |= IEEE80211_KEY_FLAG_GENERATE_MMIC;
508 break;
509 case WLAN_CIPHER_SUITE_CCMP:
510 hw_key_type = RTW_CAM_AES;
511 key->flags |= IEEE80211_KEY_FLAG_SW_MGMT_TX;
512 break;
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 */
518 return -EOPNOTSUPP;
519 default:
520 return -ENOTSUPP;
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);
529 } else {
530 /* multiple interfaces? */
531 hw_key_idx = key->keyidx;
534 if (hw_key_idx > sec->total_cam_num) {
535 ret = -ENOSPC;
536 goto out;
539 switch (cmd) {
540 case SET_KEY:
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);
546 break;
547 case DISABLE_KEY:
548 rtw_mac_flush_all_queues(rtwdev, false);
549 rtw_sec_clear_cam(rtwdev, sec, key->hw_key_idx);
550 break;
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);
557 out:
558 mutex_unlock(&rtwdev->mutex);
560 return ret;
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);
580 break;
581 case IEEE80211_AMPDU_TX_OPERATIONAL:
582 set_bit(RTW_TXQ_AMPDU, &rtwtxq->flags);
583 break;
584 case IEEE80211_AMPDU_RX_START:
585 case IEEE80211_AMPDU_RX_STOP:
586 break;
587 default:
588 WARN_ON(1);
589 return -ENOTSUPP;
592 return 0;
595 static void rtw_ops_sw_scan_start(struct ieee80211_hw *hw,
596 struct ieee80211_vif *vif,
597 const u8 *mac_addr)
599 struct rtw_dev *rtwdev = hw->priv;
600 struct rtw_vif *rtwvif = (struct rtw_vif *)vif->drv_priv;
601 u32 config = 0;
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;
624 u32 config = 0;
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,
642 u16 duration)
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);
660 return 0;
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)
699 return;
701 /* free previous mask setting */
702 kfree(si->mask);
703 si->mask = kmemdup(br_data->mask, sizeof(struct cfg80211_bitrate_mask),
704 GFP_ATOMIC);
705 if (!si->mask) {
706 si->use_cfg_mask = false;
707 return;
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;
721 br_data.vif = vif;
722 br_data.mask = mask;
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);
734 return 0;
737 #ifdef CONFIG_PM
738 static int rtw_ops_suspend(struct ieee80211_hw *hw,
739 struct cfg80211_wowlan *wowlan)
741 struct rtw_dev *rtwdev = hw->priv;
742 int ret;
744 mutex_lock(&rtwdev->mutex);
745 ret = rtw_wow_suspend(rtwdev, wowlan);
746 if (ret)
747 rtw_err(rtwdev, "failed to suspend for wow %d\n", ret);
748 mutex_unlock(&rtwdev->mutex);
750 return ret ? 1 : 0;
753 static int rtw_ops_resume(struct ieee80211_hw *hw)
755 struct rtw_dev *rtwdev = hw->priv;
756 int ret;
758 mutex_lock(&rtwdev->mutex);
759 ret = rtw_wow_resume(rtwdev);
760 if (ret)
761 rtw_err(rtwdev, "failed to resume for wow %d\n", ret);
762 mutex_unlock(&rtwdev->mutex);
764 return ret ? 1 : 0;
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);
773 #endif
775 const struct ieee80211_ops rtw_ops = {
776 .tx = rtw_ops_tx,
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,
797 #ifdef CONFIG_PM
798 .suspend = rtw_ops_suspend,
799 .resume = rtw_ops_resume,
800 .set_wakeup = rtw_ops_set_wakeup,
801 #endif
803 EXPORT_SYMBOL(rtw_ops);