Back to home page

OSCL-LXR

 
 

    


0001 // SPDX-License-Identifier: GPL-2.0 OR BSD-3-Clause
0002 /* Copyright(c) 2019-2020  Realtek Corporation
0003  */
0004 
0005 #include "cam.h"
0006 #include "coex.h"
0007 #include "debug.h"
0008 #include "fw.h"
0009 #include "mac.h"
0010 #include "phy.h"
0011 #include "ps.h"
0012 #include "reg.h"
0013 #include "sar.h"
0014 #include "ser.h"
0015 
0016 static void rtw89_ops_tx(struct ieee80211_hw *hw,
0017              struct ieee80211_tx_control *control,
0018              struct sk_buff *skb)
0019 {
0020     struct rtw89_dev *rtwdev = hw->priv;
0021     struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb);
0022     struct ieee80211_vif *vif = info->control.vif;
0023     struct ieee80211_sta *sta = control->sta;
0024     int ret, qsel;
0025 
0026     ret = rtw89_core_tx_write(rtwdev, vif, sta, skb, &qsel);
0027     if (ret) {
0028         rtw89_err(rtwdev, "failed to transmit skb: %d\n", ret);
0029         ieee80211_free_txskb(hw, skb);
0030         return;
0031     }
0032     rtw89_core_tx_kick_off(rtwdev, qsel);
0033 }
0034 
0035 static void rtw89_ops_wake_tx_queue(struct ieee80211_hw *hw,
0036                     struct ieee80211_txq *txq)
0037 {
0038     struct rtw89_dev *rtwdev = hw->priv;
0039 
0040     ieee80211_schedule_txq(hw, txq);
0041     queue_work(rtwdev->txq_wq, &rtwdev->txq_work);
0042 }
0043 
0044 static int rtw89_ops_start(struct ieee80211_hw *hw)
0045 {
0046     struct rtw89_dev *rtwdev = hw->priv;
0047     int ret;
0048 
0049     mutex_lock(&rtwdev->mutex);
0050     ret = rtw89_core_start(rtwdev);
0051     mutex_unlock(&rtwdev->mutex);
0052 
0053     return ret;
0054 }
0055 
0056 static void rtw89_ops_stop(struct ieee80211_hw *hw)
0057 {
0058     struct rtw89_dev *rtwdev = hw->priv;
0059 
0060     mutex_lock(&rtwdev->mutex);
0061     rtw89_core_stop(rtwdev);
0062     mutex_unlock(&rtwdev->mutex);
0063 }
0064 
0065 static int rtw89_ops_config(struct ieee80211_hw *hw, u32 changed)
0066 {
0067     struct rtw89_dev *rtwdev = hw->priv;
0068 
0069     /* let previous ips work finish to ensure we don't leave ips twice */
0070     cancel_work_sync(&rtwdev->ips_work);
0071 
0072     mutex_lock(&rtwdev->mutex);
0073     rtw89_leave_ps_mode(rtwdev);
0074 
0075     if ((changed & IEEE80211_CONF_CHANGE_IDLE) &&
0076         !(hw->conf.flags & IEEE80211_CONF_IDLE))
0077         rtw89_leave_ips(rtwdev);
0078 
0079     if (changed & IEEE80211_CONF_CHANGE_PS) {
0080         if (hw->conf.flags & IEEE80211_CONF_PS) {
0081             rtwdev->lps_enabled = true;
0082         } else {
0083             rtw89_leave_lps(rtwdev);
0084             rtwdev->lps_enabled = false;
0085         }
0086     }
0087 
0088     if (changed & IEEE80211_CONF_CHANGE_CHANNEL)
0089         rtw89_set_channel(rtwdev);
0090 
0091     if ((changed & IEEE80211_CONF_CHANGE_IDLE) &&
0092         (hw->conf.flags & IEEE80211_CONF_IDLE))
0093         rtw89_enter_ips(rtwdev);
0094 
0095     mutex_unlock(&rtwdev->mutex);
0096 
0097     return 0;
0098 }
0099 
0100 static int rtw89_ops_add_interface(struct ieee80211_hw *hw,
0101                    struct ieee80211_vif *vif)
0102 {
0103     struct rtw89_dev *rtwdev = hw->priv;
0104     struct rtw89_vif *rtwvif = (struct rtw89_vif *)vif->drv_priv;
0105     int ret = 0;
0106 
0107     mutex_lock(&rtwdev->mutex);
0108     rtwvif->rtwdev = rtwdev;
0109     list_add_tail(&rtwvif->list, &rtwdev->rtwvifs_list);
0110     INIT_WORK(&rtwvif->update_beacon_work, rtw89_core_update_beacon_work);
0111     rtw89_leave_ps_mode(rtwdev);
0112 
0113     rtw89_traffic_stats_init(rtwdev, &rtwvif->stats);
0114     rtw89_vif_type_mapping(vif, false);
0115     rtwvif->port = rtw89_core_acquire_bit_map(rtwdev->hw_port,
0116                           RTW89_PORT_NUM);
0117     if (rtwvif->port == RTW89_PORT_NUM) {
0118         ret = -ENOSPC;
0119         goto out;
0120     }
0121 
0122     rtwvif->bcn_hit_cond = 0;
0123     rtwvif->mac_idx = RTW89_MAC_0;
0124     rtwvif->phy_idx = RTW89_PHY_0;
0125     rtwvif->hit_rule = 0;
0126     ether_addr_copy(rtwvif->mac_addr, vif->addr);
0127 
0128     ret = rtw89_mac_add_vif(rtwdev, rtwvif);
0129     if (ret) {
0130         rtw89_core_release_bit_map(rtwdev->hw_port, rtwvif->port);
0131         goto out;
0132     }
0133 
0134     rtw89_core_txq_init(rtwdev, vif->txq);
0135 
0136     rtw89_btc_ntfy_role_info(rtwdev, rtwvif, NULL, BTC_ROLE_START);
0137 out:
0138     mutex_unlock(&rtwdev->mutex);
0139 
0140     return ret;
0141 }
0142 
0143 static void rtw89_ops_remove_interface(struct ieee80211_hw *hw,
0144                        struct ieee80211_vif *vif)
0145 {
0146     struct rtw89_dev *rtwdev = hw->priv;
0147     struct rtw89_vif *rtwvif = (struct rtw89_vif *)vif->drv_priv;
0148 
0149     cancel_work_sync(&rtwvif->update_beacon_work);
0150 
0151     mutex_lock(&rtwdev->mutex);
0152     rtw89_leave_ps_mode(rtwdev);
0153     rtw89_btc_ntfy_role_info(rtwdev, rtwvif, NULL, BTC_ROLE_STOP);
0154     rtw89_mac_remove_vif(rtwdev, rtwvif);
0155     rtw89_core_release_bit_map(rtwdev->hw_port, rtwvif->port);
0156     list_del_init(&rtwvif->list);
0157     mutex_unlock(&rtwdev->mutex);
0158 }
0159 
0160 static void rtw89_ops_configure_filter(struct ieee80211_hw *hw,
0161                        unsigned int changed_flags,
0162                        unsigned int *new_flags,
0163                        u64 multicast)
0164 {
0165     struct rtw89_dev *rtwdev = hw->priv;
0166 
0167     mutex_lock(&rtwdev->mutex);
0168     rtw89_leave_ps_mode(rtwdev);
0169 
0170     *new_flags &= FIF_ALLMULTI | FIF_OTHER_BSS | FIF_FCSFAIL |
0171               FIF_BCN_PRBRESP_PROMISC | FIF_PROBE_REQ;
0172 
0173     if (changed_flags & FIF_ALLMULTI) {
0174         if (*new_flags & FIF_ALLMULTI)
0175             rtwdev->hal.rx_fltr &= ~B_AX_A_MC;
0176         else
0177             rtwdev->hal.rx_fltr |= B_AX_A_MC;
0178     }
0179     if (changed_flags & FIF_FCSFAIL) {
0180         if (*new_flags & FIF_FCSFAIL)
0181             rtwdev->hal.rx_fltr |= B_AX_A_CRC32_ERR;
0182         else
0183             rtwdev->hal.rx_fltr &= ~B_AX_A_CRC32_ERR;
0184     }
0185     if (changed_flags & FIF_OTHER_BSS) {
0186         if (*new_flags & FIF_OTHER_BSS)
0187             rtwdev->hal.rx_fltr &= ~B_AX_A_A1_MATCH;
0188         else
0189             rtwdev->hal.rx_fltr |= B_AX_A_A1_MATCH;
0190     }
0191     if (changed_flags & FIF_BCN_PRBRESP_PROMISC) {
0192         if (*new_flags & FIF_BCN_PRBRESP_PROMISC) {
0193             rtwdev->hal.rx_fltr &= ~B_AX_A_BCN_CHK_EN;
0194             rtwdev->hal.rx_fltr &= ~B_AX_A_BC;
0195             rtwdev->hal.rx_fltr &= ~B_AX_A_A1_MATCH;
0196         } else {
0197             rtwdev->hal.rx_fltr |= B_AX_A_BCN_CHK_EN;
0198             rtwdev->hal.rx_fltr |= B_AX_A_BC;
0199             rtwdev->hal.rx_fltr |= B_AX_A_A1_MATCH;
0200         }
0201     }
0202     if (changed_flags & FIF_PROBE_REQ) {
0203         if (*new_flags & FIF_PROBE_REQ) {
0204             rtwdev->hal.rx_fltr &= ~B_AX_A_BC_CAM_MATCH;
0205             rtwdev->hal.rx_fltr &= ~B_AX_A_UC_CAM_MATCH;
0206         } else {
0207             rtwdev->hal.rx_fltr |= B_AX_A_BC_CAM_MATCH;
0208             rtwdev->hal.rx_fltr |= B_AX_A_UC_CAM_MATCH;
0209         }
0210     }
0211 
0212     rtw89_write32_mask(rtwdev,
0213                rtw89_mac_reg_by_idx(R_AX_RX_FLTR_OPT, RTW89_MAC_0),
0214                B_AX_RX_FLTR_CFG_MASK,
0215                rtwdev->hal.rx_fltr);
0216     if (!rtwdev->dbcc_en)
0217         goto out;
0218     rtw89_write32_mask(rtwdev,
0219                rtw89_mac_reg_by_idx(R_AX_RX_FLTR_OPT, RTW89_MAC_1),
0220                B_AX_RX_FLTR_CFG_MASK,
0221                rtwdev->hal.rx_fltr);
0222 
0223 out:
0224     mutex_unlock(&rtwdev->mutex);
0225 }
0226 
0227 static const u8 ac_to_fw_idx[IEEE80211_NUM_ACS] = {
0228     [IEEE80211_AC_VO] = 3,
0229     [IEEE80211_AC_VI] = 2,
0230     [IEEE80211_AC_BE] = 0,
0231     [IEEE80211_AC_BK] = 1,
0232 };
0233 
0234 static u8 rtw89_aifsn_to_aifs(struct rtw89_dev *rtwdev,
0235                   struct rtw89_vif *rtwvif, u8 aifsn)
0236 {
0237     struct ieee80211_vif *vif = rtwvif_to_vif(rtwvif);
0238     u8 slot_time;
0239     u8 sifs;
0240 
0241     slot_time = vif->bss_conf.use_short_slot ? 9 : 20;
0242     sifs = rtwdev->hal.current_band_type == RTW89_BAND_5G ? 16 : 10;
0243 
0244     return aifsn * slot_time + sifs;
0245 }
0246 
0247 static void ____rtw89_conf_tx_edca(struct rtw89_dev *rtwdev,
0248                    struct rtw89_vif *rtwvif, u16 ac)
0249 {
0250     struct ieee80211_tx_queue_params *params = &rtwvif->tx_params[ac];
0251     u32 val;
0252     u8 ecw_max, ecw_min;
0253     u8 aifs;
0254 
0255     /* 2^ecw - 1 = cw; ecw = log2(cw + 1) */
0256     ecw_max = ilog2(params->cw_max + 1);
0257     ecw_min = ilog2(params->cw_min + 1);
0258     aifs = rtw89_aifsn_to_aifs(rtwdev, rtwvif, params->aifs);
0259     val = FIELD_PREP(FW_EDCA_PARAM_TXOPLMT_MSK, params->txop) |
0260           FIELD_PREP(FW_EDCA_PARAM_CWMAX_MSK, ecw_max) |
0261           FIELD_PREP(FW_EDCA_PARAM_CWMIN_MSK, ecw_min) |
0262           FIELD_PREP(FW_EDCA_PARAM_AIFS_MSK, aifs);
0263     rtw89_fw_h2c_set_edca(rtwdev, rtwvif, ac_to_fw_idx[ac], val);
0264 }
0265 
0266 static const u32 ac_to_mu_edca_param[IEEE80211_NUM_ACS] = {
0267     [IEEE80211_AC_VO] = R_AX_MUEDCA_VO_PARAM_0,
0268     [IEEE80211_AC_VI] = R_AX_MUEDCA_VI_PARAM_0,
0269     [IEEE80211_AC_BE] = R_AX_MUEDCA_BE_PARAM_0,
0270     [IEEE80211_AC_BK] = R_AX_MUEDCA_BK_PARAM_0,
0271 };
0272 
0273 static void ____rtw89_conf_tx_mu_edca(struct rtw89_dev *rtwdev,
0274                       struct rtw89_vif *rtwvif, u16 ac)
0275 {
0276     struct ieee80211_tx_queue_params *params = &rtwvif->tx_params[ac];
0277     struct ieee80211_he_mu_edca_param_ac_rec *mu_edca;
0278     u8 aifs, aifsn;
0279     u16 timer_32us;
0280     u32 reg;
0281     u32 val;
0282 
0283     if (!params->mu_edca)
0284         return;
0285 
0286     mu_edca = &params->mu_edca_param_rec;
0287     aifsn = FIELD_GET(GENMASK(3, 0), mu_edca->aifsn);
0288     aifs = aifsn ? rtw89_aifsn_to_aifs(rtwdev, rtwvif, aifsn) : 0;
0289     timer_32us = mu_edca->mu_edca_timer << 8;
0290 
0291     val = FIELD_PREP(B_AX_MUEDCA_BE_PARAM_0_TIMER_MASK, timer_32us) |
0292           FIELD_PREP(B_AX_MUEDCA_BE_PARAM_0_CW_MASK, mu_edca->ecw_min_max) |
0293           FIELD_PREP(B_AX_MUEDCA_BE_PARAM_0_AIFS_MASK, aifs);
0294     reg = rtw89_mac_reg_by_idx(ac_to_mu_edca_param[ac], rtwvif->mac_idx);
0295     rtw89_write32(rtwdev, reg, val);
0296 
0297     rtw89_mac_set_hw_muedca_ctrl(rtwdev, rtwvif, true);
0298 }
0299 
0300 static void __rtw89_conf_tx(struct rtw89_dev *rtwdev,
0301                 struct rtw89_vif *rtwvif, u16 ac)
0302 {
0303     ____rtw89_conf_tx_edca(rtwdev, rtwvif, ac);
0304     ____rtw89_conf_tx_mu_edca(rtwdev, rtwvif, ac);
0305 }
0306 
0307 static void rtw89_conf_tx(struct rtw89_dev *rtwdev,
0308               struct rtw89_vif *rtwvif)
0309 {
0310     u16 ac;
0311 
0312     for (ac = 0; ac < IEEE80211_NUM_ACS; ac++)
0313         __rtw89_conf_tx(rtwdev, rtwvif, ac);
0314 }
0315 
0316 static void rtw89_station_mode_sta_assoc(struct rtw89_dev *rtwdev,
0317                      struct ieee80211_vif *vif,
0318                      struct ieee80211_bss_conf *conf)
0319 {
0320     struct ieee80211_sta *sta;
0321 
0322     if (vif->type != NL80211_IFTYPE_STATION)
0323         return;
0324 
0325     sta = ieee80211_find_sta(vif, conf->bssid);
0326     if (!sta) {
0327         rtw89_err(rtwdev, "can't find sta to set sta_assoc state\n");
0328         return;
0329     }
0330 
0331     rtw89_vif_type_mapping(vif, true);
0332 
0333     rtw89_core_sta_assoc(rtwdev, vif, sta);
0334 }
0335 
0336 static void rtw89_ops_bss_info_changed(struct ieee80211_hw *hw,
0337                        struct ieee80211_vif *vif,
0338                        struct ieee80211_bss_conf *conf,
0339                        u64 changed)
0340 {
0341     struct rtw89_dev *rtwdev = hw->priv;
0342     struct rtw89_vif *rtwvif = (struct rtw89_vif *)vif->drv_priv;
0343 
0344     mutex_lock(&rtwdev->mutex);
0345     rtw89_leave_ps_mode(rtwdev);
0346 
0347     if (changed & BSS_CHANGED_ASSOC) {
0348         if (vif->cfg.assoc) {
0349             rtw89_station_mode_sta_assoc(rtwdev, vif, conf);
0350             rtw89_phy_set_bss_color(rtwdev, vif);
0351             rtw89_chip_cfg_txpwr_ul_tb_offset(rtwdev, vif);
0352             rtw89_mac_port_update(rtwdev, rtwvif);
0353             rtw89_store_op_chan(rtwdev, true);
0354         } else {
0355             /* Abort ongoing scan if cancel_scan isn't issued
0356              * when disconnected by peer
0357              */
0358             if (rtwdev->scanning)
0359                 rtw89_hw_scan_abort(rtwdev, vif);
0360         }
0361     }
0362 
0363     if (changed & BSS_CHANGED_BSSID) {
0364         ether_addr_copy(rtwvif->bssid, conf->bssid);
0365         rtw89_cam_bssid_changed(rtwdev, rtwvif);
0366         rtw89_fw_h2c_cam(rtwdev, rtwvif, NULL, NULL);
0367     }
0368 
0369     if (changed & BSS_CHANGED_BEACON)
0370         rtw89_fw_h2c_update_beacon(rtwdev, rtwvif);
0371 
0372     if (changed & BSS_CHANGED_ERP_SLOT)
0373         rtw89_conf_tx(rtwdev, rtwvif);
0374 
0375     if (changed & BSS_CHANGED_HE_BSS_COLOR)
0376         rtw89_phy_set_bss_color(rtwdev, vif);
0377 
0378     if (changed & BSS_CHANGED_MU_GROUPS)
0379         rtw89_mac_bf_set_gid_table(rtwdev, vif, conf);
0380 
0381     mutex_unlock(&rtwdev->mutex);
0382 }
0383 
0384 static int rtw89_ops_start_ap(struct ieee80211_hw *hw,
0385                   struct ieee80211_vif *vif,
0386                   struct ieee80211_bss_conf *link_conf)
0387 {
0388     struct rtw89_dev *rtwdev = hw->priv;
0389     struct rtw89_vif *rtwvif = (struct rtw89_vif *)vif->drv_priv;
0390 
0391     mutex_lock(&rtwdev->mutex);
0392     ether_addr_copy(rtwvif->bssid, vif->bss_conf.bssid);
0393     rtw89_cam_bssid_changed(rtwdev, rtwvif);
0394     rtw89_mac_port_update(rtwdev, rtwvif);
0395     rtw89_fw_h2c_assoc_cmac_tbl(rtwdev, vif, NULL);
0396     rtw89_fw_h2c_role_maintain(rtwdev, rtwvif, NULL, RTW89_ROLE_TYPE_CHANGE);
0397     rtw89_fw_h2c_join_info(rtwdev, rtwvif, NULL, true);
0398     rtw89_fw_h2c_cam(rtwdev, rtwvif, NULL, NULL);
0399     rtw89_chip_rfk_channel(rtwdev);
0400     mutex_unlock(&rtwdev->mutex);
0401 
0402     return 0;
0403 }
0404 
0405 static
0406 void rtw89_ops_stop_ap(struct ieee80211_hw *hw, struct ieee80211_vif *vif,
0407                struct ieee80211_bss_conf *link_conf)
0408 {
0409     struct rtw89_dev *rtwdev = hw->priv;
0410     struct rtw89_vif *rtwvif = (struct rtw89_vif *)vif->drv_priv;
0411 
0412     mutex_lock(&rtwdev->mutex);
0413     rtw89_fw_h2c_assoc_cmac_tbl(rtwdev, vif, NULL);
0414     rtw89_fw_h2c_join_info(rtwdev, rtwvif, NULL, true);
0415     mutex_unlock(&rtwdev->mutex);
0416 }
0417 
0418 static int rtw89_ops_set_tim(struct ieee80211_hw *hw, struct ieee80211_sta *sta,
0419                  bool set)
0420 {
0421     struct rtw89_dev *rtwdev = hw->priv;
0422     struct rtw89_sta *rtwsta = (struct rtw89_sta *)sta->drv_priv;
0423     struct rtw89_vif *rtwvif = rtwsta->rtwvif;
0424 
0425     ieee80211_queue_work(rtwdev->hw, &rtwvif->update_beacon_work);
0426 
0427     return 0;
0428 }
0429 
0430 static int rtw89_ops_conf_tx(struct ieee80211_hw *hw,
0431                  struct ieee80211_vif *vif,
0432                  unsigned int link_id, u16 ac,
0433                  const struct ieee80211_tx_queue_params *params)
0434 {
0435     struct rtw89_dev *rtwdev = hw->priv;
0436     struct rtw89_vif *rtwvif = (struct rtw89_vif *)vif->drv_priv;
0437 
0438     mutex_lock(&rtwdev->mutex);
0439     rtw89_leave_ps_mode(rtwdev);
0440     rtwvif->tx_params[ac] = *params;
0441     __rtw89_conf_tx(rtwdev, rtwvif, ac);
0442     mutex_unlock(&rtwdev->mutex);
0443 
0444     return 0;
0445 }
0446 
0447 static int __rtw89_ops_sta_state(struct ieee80211_hw *hw,
0448                  struct ieee80211_vif *vif,
0449                  struct ieee80211_sta *sta,
0450                  enum ieee80211_sta_state old_state,
0451                  enum ieee80211_sta_state new_state)
0452 {
0453     struct rtw89_dev *rtwdev = hw->priv;
0454 
0455     if (old_state == IEEE80211_STA_NOTEXIST &&
0456         new_state == IEEE80211_STA_NONE)
0457         return rtw89_core_sta_add(rtwdev, vif, sta);
0458 
0459     if (old_state == IEEE80211_STA_AUTH &&
0460         new_state == IEEE80211_STA_ASSOC) {
0461         if (vif->type == NL80211_IFTYPE_STATION && !sta->tdls)
0462             return 0; /* defer to bss_info_changed to have vif info */
0463         return rtw89_core_sta_assoc(rtwdev, vif, sta);
0464     }
0465 
0466     if (old_state == IEEE80211_STA_ASSOC &&
0467         new_state == IEEE80211_STA_AUTH)
0468         return rtw89_core_sta_disassoc(rtwdev, vif, sta);
0469 
0470     if (old_state == IEEE80211_STA_AUTH &&
0471         new_state == IEEE80211_STA_NONE)
0472         return rtw89_core_sta_disconnect(rtwdev, vif, sta);
0473 
0474     if (old_state == IEEE80211_STA_NONE &&
0475         new_state == IEEE80211_STA_NOTEXIST)
0476         return rtw89_core_sta_remove(rtwdev, vif, sta);
0477 
0478     return 0;
0479 }
0480 
0481 static int rtw89_ops_sta_state(struct ieee80211_hw *hw,
0482                    struct ieee80211_vif *vif,
0483                    struct ieee80211_sta *sta,
0484                    enum ieee80211_sta_state old_state,
0485                    enum ieee80211_sta_state new_state)
0486 {
0487     struct rtw89_dev *rtwdev = hw->priv;
0488     int ret;
0489 
0490     mutex_lock(&rtwdev->mutex);
0491     rtw89_leave_ps_mode(rtwdev);
0492     ret = __rtw89_ops_sta_state(hw, vif, sta, old_state, new_state);
0493     mutex_unlock(&rtwdev->mutex);
0494 
0495     return ret;
0496 }
0497 
0498 static int rtw89_ops_set_key(struct ieee80211_hw *hw, enum set_key_cmd cmd,
0499                  struct ieee80211_vif *vif,
0500                  struct ieee80211_sta *sta,
0501                  struct ieee80211_key_conf *key)
0502 {
0503     struct rtw89_dev *rtwdev = hw->priv;
0504     int ret = 0;
0505 
0506     mutex_lock(&rtwdev->mutex);
0507     rtw89_leave_ps_mode(rtwdev);
0508 
0509     switch (cmd) {
0510     case SET_KEY:
0511         rtw89_btc_ntfy_specific_packet(rtwdev, PACKET_EAPOL_END);
0512         ret = rtw89_cam_sec_key_add(rtwdev, vif, sta, key);
0513         if (ret && ret != -EOPNOTSUPP) {
0514             rtw89_err(rtwdev, "failed to add key to sec cam\n");
0515             goto out;
0516         }
0517         break;
0518     case DISABLE_KEY:
0519         rtw89_hci_flush_queues(rtwdev, BIT(rtwdev->hw->queues) - 1,
0520                        false);
0521         rtw89_mac_flush_txq(rtwdev, BIT(rtwdev->hw->queues) - 1, false);
0522         ret = rtw89_cam_sec_key_del(rtwdev, vif, sta, key, true);
0523         if (ret) {
0524             rtw89_err(rtwdev, "failed to remove key from sec cam\n");
0525             goto out;
0526         }
0527         break;
0528     }
0529 
0530 out:
0531     mutex_unlock(&rtwdev->mutex);
0532 
0533     return ret;
0534 }
0535 
0536 static int rtw89_ops_ampdu_action(struct ieee80211_hw *hw,
0537                   struct ieee80211_vif *vif,
0538                   struct ieee80211_ampdu_params *params)
0539 {
0540     struct rtw89_dev *rtwdev = hw->priv;
0541     struct ieee80211_sta *sta = params->sta;
0542     struct rtw89_sta *rtwsta = (struct rtw89_sta *)sta->drv_priv;
0543     u16 tid = params->tid;
0544     struct ieee80211_txq *txq = sta->txq[tid];
0545     struct rtw89_txq *rtwtxq = (struct rtw89_txq *)txq->drv_priv;
0546 
0547     switch (params->action) {
0548     case IEEE80211_AMPDU_TX_START:
0549         return IEEE80211_AMPDU_TX_START_IMMEDIATE;
0550     case IEEE80211_AMPDU_TX_STOP_CONT:
0551     case IEEE80211_AMPDU_TX_STOP_FLUSH:
0552     case IEEE80211_AMPDU_TX_STOP_FLUSH_CONT:
0553         mutex_lock(&rtwdev->mutex);
0554         clear_bit(RTW89_TXQ_F_AMPDU, &rtwtxq->flags);
0555         mutex_unlock(&rtwdev->mutex);
0556         ieee80211_stop_tx_ba_cb_irqsafe(vif, sta->addr, tid);
0557         break;
0558     case IEEE80211_AMPDU_TX_OPERATIONAL:
0559         mutex_lock(&rtwdev->mutex);
0560         set_bit(RTW89_TXQ_F_AMPDU, &rtwtxq->flags);
0561         rtwsta->ampdu_params[tid].agg_num = params->buf_size;
0562         rtwsta->ampdu_params[tid].amsdu = params->amsdu;
0563         rtw89_leave_ps_mode(rtwdev);
0564         mutex_unlock(&rtwdev->mutex);
0565         break;
0566     case IEEE80211_AMPDU_RX_START:
0567         mutex_lock(&rtwdev->mutex);
0568         rtw89_fw_h2c_ba_cam(rtwdev, rtwsta, true, params);
0569         mutex_unlock(&rtwdev->mutex);
0570         break;
0571     case IEEE80211_AMPDU_RX_STOP:
0572         mutex_lock(&rtwdev->mutex);
0573         rtw89_fw_h2c_ba_cam(rtwdev, rtwsta, false, params);
0574         mutex_unlock(&rtwdev->mutex);
0575         break;
0576     default:
0577         WARN_ON(1);
0578         return -ENOTSUPP;
0579     }
0580 
0581     return 0;
0582 }
0583 
0584 static int rtw89_ops_set_rts_threshold(struct ieee80211_hw *hw, u32 value)
0585 {
0586     struct rtw89_dev *rtwdev = hw->priv;
0587 
0588     mutex_lock(&rtwdev->mutex);
0589     rtw89_leave_ps_mode(rtwdev);
0590     if (test_bit(RTW89_FLAG_POWERON, rtwdev->flags))
0591         rtw89_mac_update_rts_threshold(rtwdev, RTW89_MAC_0);
0592     mutex_unlock(&rtwdev->mutex);
0593 
0594     return 0;
0595 }
0596 
0597 static void rtw89_ops_sta_statistics(struct ieee80211_hw *hw,
0598                      struct ieee80211_vif *vif,
0599                      struct ieee80211_sta *sta,
0600                      struct station_info *sinfo)
0601 {
0602     struct rtw89_sta *rtwsta = (struct rtw89_sta *)sta->drv_priv;
0603 
0604     sinfo->txrate = rtwsta->ra_report.txrate;
0605     sinfo->filled |= BIT_ULL(NL80211_STA_INFO_TX_BITRATE);
0606 }
0607 
0608 static void rtw89_ops_flush(struct ieee80211_hw *hw, struct ieee80211_vif *vif,
0609                 u32 queues, bool drop)
0610 {
0611     struct rtw89_dev *rtwdev = hw->priv;
0612 
0613     mutex_lock(&rtwdev->mutex);
0614     rtw89_leave_lps(rtwdev);
0615     rtw89_hci_flush_queues(rtwdev, queues, drop);
0616     rtw89_mac_flush_txq(rtwdev, queues, drop);
0617     mutex_unlock(&rtwdev->mutex);
0618 }
0619 
0620 struct rtw89_iter_bitrate_mask_data {
0621     struct rtw89_dev *rtwdev;
0622     struct ieee80211_vif *vif;
0623     const struct cfg80211_bitrate_mask *mask;
0624 };
0625 
0626 static void rtw89_ra_mask_info_update_iter(void *data, struct ieee80211_sta *sta)
0627 {
0628     struct rtw89_iter_bitrate_mask_data *br_data = data;
0629     struct rtw89_sta *rtwsta = (struct rtw89_sta *)sta->drv_priv;
0630     struct ieee80211_vif *vif = rtwvif_to_vif(rtwsta->rtwvif);
0631 
0632     if (vif != br_data->vif)
0633         return;
0634 
0635     rtwsta->use_cfg_mask = true;
0636     rtwsta->mask = *br_data->mask;
0637     rtw89_phy_ra_updata_sta(br_data->rtwdev, sta, IEEE80211_RC_SUPP_RATES_CHANGED);
0638 }
0639 
0640 static void rtw89_ra_mask_info_update(struct rtw89_dev *rtwdev,
0641                       struct ieee80211_vif *vif,
0642                       const struct cfg80211_bitrate_mask *mask)
0643 {
0644     struct rtw89_iter_bitrate_mask_data br_data = { .rtwdev = rtwdev,
0645                             .vif = vif,
0646                             .mask = mask};
0647 
0648     ieee80211_iterate_stations_atomic(rtwdev->hw, rtw89_ra_mask_info_update_iter,
0649                       &br_data);
0650 }
0651 
0652 static int rtw89_ops_set_bitrate_mask(struct ieee80211_hw *hw,
0653                       struct ieee80211_vif *vif,
0654                       const struct cfg80211_bitrate_mask *mask)
0655 {
0656     struct rtw89_dev *rtwdev = hw->priv;
0657 
0658     mutex_lock(&rtwdev->mutex);
0659     rtw89_phy_rate_pattern_vif(rtwdev, vif, mask);
0660     rtw89_ra_mask_info_update(rtwdev, vif, mask);
0661     mutex_unlock(&rtwdev->mutex);
0662 
0663     return 0;
0664 }
0665 
0666 static
0667 int rtw89_ops_set_antenna(struct ieee80211_hw *hw, u32 tx_ant, u32 rx_ant)
0668 {
0669     struct rtw89_dev *rtwdev = hw->priv;
0670     struct rtw89_hal *hal = &rtwdev->hal;
0671 
0672     if (rx_ant != hw->wiphy->available_antennas_rx)
0673         return -EINVAL;
0674 
0675     mutex_lock(&rtwdev->mutex);
0676     hal->antenna_tx = tx_ant;
0677     hal->antenna_rx = rx_ant;
0678     mutex_unlock(&rtwdev->mutex);
0679 
0680     return 0;
0681 }
0682 
0683 static
0684 int rtw89_ops_get_antenna(struct ieee80211_hw *hw,  u32 *tx_ant, u32 *rx_ant)
0685 {
0686     struct rtw89_dev *rtwdev = hw->priv;
0687     struct rtw89_hal *hal = &rtwdev->hal;
0688 
0689     *tx_ant = hal->antenna_tx;
0690     *rx_ant = hal->antenna_rx;
0691 
0692     return 0;
0693 }
0694 
0695 static void rtw89_ops_sw_scan_start(struct ieee80211_hw *hw,
0696                     struct ieee80211_vif *vif,
0697                     const u8 *mac_addr)
0698 {
0699     struct rtw89_dev *rtwdev = hw->priv;
0700     struct rtw89_vif *rtwvif = (struct rtw89_vif *)vif->drv_priv;
0701 
0702     mutex_lock(&rtwdev->mutex);
0703     rtw89_core_scan_start(rtwdev, rtwvif, mac_addr, false);
0704     mutex_unlock(&rtwdev->mutex);
0705 }
0706 
0707 static void rtw89_ops_sw_scan_complete(struct ieee80211_hw *hw,
0708                        struct ieee80211_vif *vif)
0709 {
0710     struct rtw89_dev *rtwdev = hw->priv;
0711 
0712     mutex_lock(&rtwdev->mutex);
0713     rtw89_core_scan_complete(rtwdev, vif, false);
0714     mutex_unlock(&rtwdev->mutex);
0715 }
0716 
0717 static void rtw89_ops_reconfig_complete(struct ieee80211_hw *hw,
0718                     enum ieee80211_reconfig_type reconfig_type)
0719 {
0720     struct rtw89_dev *rtwdev = hw->priv;
0721 
0722     if (reconfig_type == IEEE80211_RECONFIG_TYPE_RESTART)
0723         rtw89_ser_recfg_done(rtwdev);
0724 }
0725 
0726 static int rtw89_ops_hw_scan(struct ieee80211_hw *hw, struct ieee80211_vif *vif,
0727                  struct ieee80211_scan_request *req)
0728 {
0729     struct rtw89_dev *rtwdev = hw->priv;
0730     int ret = 0;
0731 
0732     if (!RTW89_CHK_FW_FEATURE(SCAN_OFFLOAD, &rtwdev->fw))
0733         return 1;
0734 
0735     if (rtwdev->scanning)
0736         return -EBUSY;
0737 
0738     mutex_lock(&rtwdev->mutex);
0739     rtw89_hw_scan_start(rtwdev, vif, req);
0740     ret = rtw89_hw_scan_offload(rtwdev, vif, true);
0741     if (ret) {
0742         rtw89_hw_scan_abort(rtwdev, vif);
0743         rtw89_err(rtwdev, "HW scan failed with status: %d\n", ret);
0744     }
0745     mutex_unlock(&rtwdev->mutex);
0746 
0747     return ret;
0748 }
0749 
0750 static void rtw89_ops_cancel_hw_scan(struct ieee80211_hw *hw,
0751                      struct ieee80211_vif *vif)
0752 {
0753     struct rtw89_dev *rtwdev = hw->priv;
0754 
0755     if (!RTW89_CHK_FW_FEATURE(SCAN_OFFLOAD, &rtwdev->fw))
0756         return;
0757 
0758     if (!rtwdev->scanning)
0759         return;
0760 
0761     mutex_lock(&rtwdev->mutex);
0762     rtw89_hw_scan_abort(rtwdev, vif);
0763     mutex_unlock(&rtwdev->mutex);
0764 }
0765 
0766 static void rtw89_ops_sta_rc_update(struct ieee80211_hw *hw,
0767                     struct ieee80211_vif *vif,
0768                     struct ieee80211_sta *sta, u32 changed)
0769 {
0770     struct rtw89_dev *rtwdev = hw->priv;
0771 
0772     rtw89_phy_ra_updata_sta(rtwdev, sta, changed);
0773 }
0774 
0775 const struct ieee80211_ops rtw89_ops = {
0776     .tx         = rtw89_ops_tx,
0777     .wake_tx_queue      = rtw89_ops_wake_tx_queue,
0778     .start          = rtw89_ops_start,
0779     .stop           = rtw89_ops_stop,
0780     .config         = rtw89_ops_config,
0781     .add_interface      = rtw89_ops_add_interface,
0782     .remove_interface   = rtw89_ops_remove_interface,
0783     .configure_filter   = rtw89_ops_configure_filter,
0784     .bss_info_changed   = rtw89_ops_bss_info_changed,
0785     .start_ap       = rtw89_ops_start_ap,
0786     .stop_ap        = rtw89_ops_stop_ap,
0787     .set_tim        = rtw89_ops_set_tim,
0788     .conf_tx        = rtw89_ops_conf_tx,
0789     .sta_state      = rtw89_ops_sta_state,
0790     .set_key        = rtw89_ops_set_key,
0791     .ampdu_action       = rtw89_ops_ampdu_action,
0792     .set_rts_threshold  = rtw89_ops_set_rts_threshold,
0793     .sta_statistics     = rtw89_ops_sta_statistics,
0794     .flush          = rtw89_ops_flush,
0795     .set_bitrate_mask   = rtw89_ops_set_bitrate_mask,
0796     .set_antenna        = rtw89_ops_set_antenna,
0797     .get_antenna        = rtw89_ops_get_antenna,
0798     .sw_scan_start      = rtw89_ops_sw_scan_start,
0799     .sw_scan_complete   = rtw89_ops_sw_scan_complete,
0800     .reconfig_complete  = rtw89_ops_reconfig_complete,
0801     .hw_scan        = rtw89_ops_hw_scan,
0802     .cancel_hw_scan     = rtw89_ops_cancel_hw_scan,
0803     .set_sar_specs      = rtw89_ops_set_sar_specs,
0804     .sta_rc_update      = rtw89_ops_sta_rc_update,
0805 };
0806 EXPORT_SYMBOL(rtw89_ops);