Commit 89590777 authored by Po Hao Huang's avatar Po Hao Huang Committed by Kalle Valo

rtw89: 8852a: add ieee80211_ops::hw_scan

Declare this function allows us to use customized scanning policy, so
each scan takes less time. This is a similar implementation to hw_scan
in rtw88, except that we offload more items to firmware and extend the
maximum IE length. For backward compatibility, we fallback to sw_scan
when firmware does not support this feature.
Signed-off-by: default avatarPo Hao Huang <phhuang@realtek.com>
Signed-off-by: default avatarPing-Ke Shih <pkshih@realtek.com>
Signed-off-by: default avatarKalle Valo <kvalo@kernel.org>
Link: https://lore.kernel.org/r/20220225030851.13327-2-pkshih@realtek.com
parent e715f10f
...@@ -374,6 +374,7 @@ void rtw89_set_channel(struct rtw89_dev *rtwdev) ...@@ -374,6 +374,7 @@ void rtw89_set_channel(struct rtw89_dev *rtwdev)
hal->current_channel = center_chan; hal->current_channel = center_chan;
hal->current_freq = ch_param.center_freq; hal->current_freq = ch_param.center_freq;
hal->prev_primary_channel = hal->current_primary_channel; hal->prev_primary_channel = hal->current_primary_channel;
hal->prev_band_type = hal->current_band_type;
hal->current_primary_channel = ch_param.primary_chan; hal->current_primary_channel = ch_param.primary_chan;
hal->current_band_type = ch_param.band_type; hal->current_band_type = ch_param.band_type;
hal->current_subband = ch_param.subband_type; hal->current_subband = ch_param.subband_type;
...@@ -1242,6 +1243,15 @@ static void rtw89_core_hw_to_sband_rate(struct ieee80211_rx_status *rx_status) ...@@ -1242,6 +1243,15 @@ static void rtw89_core_hw_to_sband_rate(struct ieee80211_rx_status *rx_status)
if (rx_status->band == NL80211_BAND_2GHZ || if (rx_status->band == NL80211_BAND_2GHZ ||
rx_status->encoding != RX_ENC_LEGACY) rx_status->encoding != RX_ENC_LEGACY)
return; return;
/* Some control frames' freq(ACKs in this case) are reported wrong due
* to FW notify timing, set to lowest rate to prevent overflow.
*/
if (rx_status->rate_idx < RTW89_HW_RATE_OFDM6) {
rx_status->rate_idx = 0;
return;
}
/* No 4 CCK rates for non-2G */ /* No 4 CCK rates for non-2G */
rx_status->rate_idx -= 4; rx_status->rate_idx -= 4;
} }
...@@ -1418,6 +1428,7 @@ static void rtw89_core_update_rx_status(struct rtw89_dev *rtwdev, ...@@ -1418,6 +1428,7 @@ static void rtw89_core_update_rx_status(struct rtw89_dev *rtwdev,
struct ieee80211_rx_status *rx_status) struct ieee80211_rx_status *rx_status)
{ {
struct ieee80211_hw *hw = rtwdev->hw; struct ieee80211_hw *hw = rtwdev->hw;
struct rtw89_hal *hal = &rtwdev->hal;
u16 data_rate; u16 data_rate;
u8 data_rate_mode; u8 data_rate_mode;
...@@ -1425,6 +1436,13 @@ static void rtw89_core_update_rx_status(struct rtw89_dev *rtwdev, ...@@ -1425,6 +1436,13 @@ static void rtw89_core_update_rx_status(struct rtw89_dev *rtwdev,
rx_status->freq = hw->conf.chandef.chan->center_freq; rx_status->freq = hw->conf.chandef.chan->center_freq;
rx_status->band = hw->conf.chandef.chan->band; rx_status->band = hw->conf.chandef.chan->band;
if (rtwdev->scanning && rtwdev->fw.scan_offload) {
rx_status->freq =
ieee80211_channel_to_frequency(hal->current_channel,
hal->current_band_type);
rx_status->band = rtwdev->hal.current_band_type;
}
if (desc_info->icv_err || desc_info->crc32_err) if (desc_info->icv_err || desc_info->crc32_err)
rx_status->flag |= RX_FLAG_FAILED_FCS_CRC; rx_status->flag |= RX_FLAG_FAILED_FCS_CRC;
...@@ -1757,6 +1775,16 @@ static void rtw89_core_txq_schedule(struct rtw89_dev *rtwdev, u8 ac, bool *reinv ...@@ -1757,6 +1775,16 @@ static void rtw89_core_txq_schedule(struct rtw89_dev *rtwdev, u8 ac, bool *reinv
ieee80211_txq_schedule_end(hw, ac); ieee80211_txq_schedule_end(hw, ac);
} }
static void rtw89_ips_work(struct work_struct *work)
{
struct rtw89_dev *rtwdev = container_of(work, struct rtw89_dev,
ips_work);
mutex_lock(&rtwdev->mutex);
rtw89_enter_ips(rtwdev);
mutex_unlock(&rtwdev->mutex);
}
static void rtw89_core_txq_work(struct work_struct *w) static void rtw89_core_txq_work(struct work_struct *w)
{ {
struct rtw89_dev *rtwdev = container_of(w, struct rtw89_dev, txq_work); struct rtw89_dev *rtwdev = container_of(w, struct rtw89_dev, txq_work);
...@@ -2570,10 +2598,16 @@ int rtw89_core_init(struct rtw89_dev *rtwdev) ...@@ -2570,10 +2598,16 @@ int rtw89_core_init(struct rtw89_dev *rtwdev)
{ {
struct rtw89_btc *btc = &rtwdev->btc; struct rtw89_btc *btc = &rtwdev->btc;
int ret; int ret;
u8 band;
INIT_LIST_HEAD(&rtwdev->ba_list); INIT_LIST_HEAD(&rtwdev->ba_list);
INIT_LIST_HEAD(&rtwdev->rtwvifs_list); INIT_LIST_HEAD(&rtwdev->rtwvifs_list);
INIT_LIST_HEAD(&rtwdev->early_h2c_list); INIT_LIST_HEAD(&rtwdev->early_h2c_list);
for (band = NL80211_BAND_2GHZ; band < NUM_NL80211_BANDS; band++) {
if (!(rtwdev->chip->support_bands & BIT(band)))
continue;
INIT_LIST_HEAD(&rtwdev->scan_info.pkt_list[band]);
}
INIT_WORK(&rtwdev->ba_work, rtw89_core_ba_work); INIT_WORK(&rtwdev->ba_work, rtw89_core_ba_work);
INIT_WORK(&rtwdev->txq_work, rtw89_core_txq_work); INIT_WORK(&rtwdev->txq_work, rtw89_core_txq_work);
INIT_DELAYED_WORK(&rtwdev->txq_reinvoke_work, rtw89_core_txq_reinvoke_work); INIT_DELAYED_WORK(&rtwdev->txq_reinvoke_work, rtw89_core_txq_reinvoke_work);
...@@ -2589,6 +2623,7 @@ int rtw89_core_init(struct rtw89_dev *rtwdev) ...@@ -2589,6 +2623,7 @@ int rtw89_core_init(struct rtw89_dev *rtwdev)
rtwdev->total_sta_assoc = 0; rtwdev->total_sta_assoc = 0;
INIT_WORK(&rtwdev->c2h_work, rtw89_fw_c2h_work); INIT_WORK(&rtwdev->c2h_work, rtw89_fw_c2h_work);
INIT_WORK(&rtwdev->ips_work, rtw89_ips_work);
skb_queue_head_init(&rtwdev->c2h_queue); skb_queue_head_init(&rtwdev->c2h_queue);
rtw89_core_ppdu_sts_init(rtwdev); rtw89_core_ppdu_sts_init(rtwdev);
rtw89_traffic_stats_init(rtwdev, &rtwdev->stats); rtw89_traffic_stats_init(rtwdev, &rtwdev->stats);
...@@ -2624,6 +2659,41 @@ void rtw89_core_deinit(struct rtw89_dev *rtwdev) ...@@ -2624,6 +2659,41 @@ void rtw89_core_deinit(struct rtw89_dev *rtwdev)
} }
EXPORT_SYMBOL(rtw89_core_deinit); EXPORT_SYMBOL(rtw89_core_deinit);
void rtw89_core_scan_start(struct rtw89_dev *rtwdev, struct rtw89_vif *rtwvif,
const u8 *mac_addr, bool hw_scan)
{
struct rtw89_hal *hal = &rtwdev->hal;
rtwdev->scanning = true;
rtw89_leave_lps(rtwdev);
if (hw_scan && rtwvif->net_type == RTW89_NET_TYPE_NO_LINK)
rtw89_leave_ips(rtwdev);
ether_addr_copy(rtwvif->mac_addr, mac_addr);
rtw89_btc_ntfy_scan_start(rtwdev, RTW89_PHY_0, hal->current_band_type);
rtw89_chip_rfk_scan(rtwdev, true);
rtw89_hci_recalc_int_mit(rtwdev);
rtw89_fw_h2c_cam(rtwdev, rtwvif, NULL, mac_addr);
}
void rtw89_core_scan_complete(struct rtw89_dev *rtwdev,
struct ieee80211_vif *vif, bool hw_scan)
{
struct rtw89_vif *rtwvif = (struct rtw89_vif *)vif->drv_priv;
ether_addr_copy(rtwvif->mac_addr, vif->addr);
rtw89_fw_h2c_cam(rtwdev, rtwvif, NULL, NULL);
rtw89_chip_rfk_scan(rtwdev, false);
rtw89_btc_ntfy_scan_finish(rtwdev, RTW89_PHY_0);
rtwdev->scanning = false;
rtwdev->dig.bypass_dig = true;
if (hw_scan && rtwvif->net_type == RTW89_NET_TYPE_NO_LINK)
ieee80211_queue_work(rtwdev->hw, &rtwdev->ips_work);
}
static void rtw89_read_chip_ver(struct rtw89_dev *rtwdev) static void rtw89_read_chip_ver(struct rtw89_dev *rtwdev)
{ {
u8 cv; u8 cv;
...@@ -2739,6 +2809,7 @@ static int rtw89_core_register_hw(struct rtw89_dev *rtwdev) ...@@ -2739,6 +2809,7 @@ static int rtw89_core_register_hw(struct rtw89_dev *rtwdev)
ieee80211_hw_set(hw, SUPPORTS_AMSDU_IN_AMPDU); ieee80211_hw_set(hw, SUPPORTS_AMSDU_IN_AMPDU);
ieee80211_hw_set(hw, SUPPORTS_PS); ieee80211_hw_set(hw, SUPPORTS_PS);
ieee80211_hw_set(hw, SUPPORTS_DYNAMIC_PS); ieee80211_hw_set(hw, SUPPORTS_DYNAMIC_PS);
ieee80211_hw_set(hw, SINGLE_SCAN_ON_ALL_BANDS);
hw->wiphy->interface_modes = BIT(NL80211_IFTYPE_STATION) | hw->wiphy->interface_modes = BIT(NL80211_IFTYPE_STATION) |
BIT(NL80211_IFTYPE_AP); BIT(NL80211_IFTYPE_AP);
...@@ -2747,6 +2818,9 @@ static int rtw89_core_register_hw(struct rtw89_dev *rtwdev) ...@@ -2747,6 +2818,9 @@ static int rtw89_core_register_hw(struct rtw89_dev *rtwdev)
hw->wiphy->features |= NL80211_FEATURE_SCAN_RANDOM_MAC_ADDR; hw->wiphy->features |= NL80211_FEATURE_SCAN_RANDOM_MAC_ADDR;
hw->wiphy->max_scan_ssids = RTW89_SCANOFLD_MAX_SSID;
hw->wiphy->max_scan_ie_len = RTW89_SCANOFLD_MAX_IE_LEN;
wiphy_ext_feature_set(hw->wiphy, NL80211_EXT_FEATURE_CAN_REPLACE_PTK0); wiphy_ext_feature_set(hw->wiphy, NL80211_EXT_FEATURE_CAN_REPLACE_PTK0);
ret = rtw89_core_set_supported_band(rtwdev); ret = rtw89_core_set_supported_band(rtwdev);
......
...@@ -1991,6 +1991,8 @@ struct rtw89_vif { ...@@ -1991,6 +1991,8 @@ struct rtw89_vif {
struct ieee80211_tx_queue_params tx_params[IEEE80211_NUM_ACS]; struct ieee80211_tx_queue_params tx_params[IEEE80211_NUM_ACS];
struct rtw89_traffic_stats stats; struct rtw89_traffic_stats stats;
struct rtw89_phy_rate_pattern rate_pattern; struct rtw89_phy_rate_pattern rate_pattern;
struct cfg80211_scan_request *scan_req;
struct ieee80211_scan_ies *scan_ies;
}; };
enum rtw89_lv1_rcvy_step { enum rtw89_lv1_rcvy_step {
...@@ -2373,6 +2375,7 @@ struct rtw89_fw_info { ...@@ -2373,6 +2375,7 @@ struct rtw89_fw_info {
struct rtw89_fw_suit wowlan; struct rtw89_fw_suit wowlan;
bool fw_log_enable; bool fw_log_enable;
bool old_ht_ra_format; bool old_ht_ra_format;
bool scan_offload;
}; };
struct rtw89_cam_info { struct rtw89_cam_info {
...@@ -2414,6 +2417,7 @@ struct rtw89_hal { ...@@ -2414,6 +2417,7 @@ struct rtw89_hal {
u8 current_primary_channel; u8 current_primary_channel;
enum rtw89_subband current_subband; enum rtw89_subband current_subband;
u8 current_band_width; u8 current_band_width;
u8 prev_band_type;
u8 current_band_type; u8 current_band_type;
u32 sw_amsdu_max_size; u32 sw_amsdu_max_size;
u32 antenna_tx; u32 antenna_tx;
...@@ -2424,6 +2428,7 @@ struct rtw89_hal { ...@@ -2424,6 +2428,7 @@ struct rtw89_hal {
}; };
#define RTW89_MAX_MAC_ID_NUM 128 #define RTW89_MAX_MAC_ID_NUM 128
#define RTW89_MAX_PKT_OFLD_NUM 255
enum rtw89_flags { enum rtw89_flags {
RTW89_FLAG_POWERON, RTW89_FLAG_POWERON,
...@@ -2836,11 +2841,21 @@ struct rtw89_early_h2c { ...@@ -2836,11 +2841,21 @@ struct rtw89_early_h2c {
u16 h2c_len; u16 h2c_len;
}; };
struct rtw89_hw_scan_info {
struct ieee80211_vif *scanning_vif;
struct list_head pkt_list[NUM_NL80211_BANDS];
u8 op_pri_ch;
u8 op_chan;
u8 op_bw;
u8 op_band;
};
struct rtw89_dev { struct rtw89_dev {
struct ieee80211_hw *hw; struct ieee80211_hw *hw;
struct device *dev; struct device *dev;
bool dbcc_en; bool dbcc_en;
struct rtw89_hw_scan_info scan_info;
const struct rtw89_chip_info *chip; const struct rtw89_chip_info *chip;
struct rtw89_hal hal; struct rtw89_hal hal;
struct rtw89_mac_info mac; struct rtw89_mac_info mac;
...@@ -2867,6 +2882,7 @@ struct rtw89_dev { ...@@ -2867,6 +2882,7 @@ struct rtw89_dev {
struct sk_buff_head c2h_queue; struct sk_buff_head c2h_queue;
struct work_struct c2h_work; struct work_struct c2h_work;
struct work_struct ips_work;
struct list_head early_h2c_list; struct list_head early_h2c_list;
...@@ -2875,6 +2891,7 @@ struct rtw89_dev { ...@@ -2875,6 +2891,7 @@ struct rtw89_dev {
DECLARE_BITMAP(hw_port, RTW89_PORT_NUM); DECLARE_BITMAP(hw_port, RTW89_PORT_NUM);
DECLARE_BITMAP(mac_id_map, RTW89_MAX_MAC_ID_NUM); DECLARE_BITMAP(mac_id_map, RTW89_MAX_MAC_ID_NUM);
DECLARE_BITMAP(flags, NUM_OF_RTW89_FLAGS); DECLARE_BITMAP(flags, NUM_OF_RTW89_FLAGS);
DECLARE_BITMAP(pkt_offload, RTW89_MAX_PKT_OFLD_NUM);
struct rtw89_phy_stat phystat; struct rtw89_phy_stat phystat;
struct rtw89_dack_info dack; struct rtw89_dack_info dack;
...@@ -3491,5 +3508,9 @@ void rtw89_traffic_stats_init(struct rtw89_dev *rtwdev, ...@@ -3491,5 +3508,9 @@ void rtw89_traffic_stats_init(struct rtw89_dev *rtwdev,
int rtw89_core_start(struct rtw89_dev *rtwdev); int rtw89_core_start(struct rtw89_dev *rtwdev);
void rtw89_core_stop(struct rtw89_dev *rtwdev); void rtw89_core_stop(struct rtw89_dev *rtwdev);
void rtw89_core_update_beacon_work(struct work_struct *work); void rtw89_core_update_beacon_work(struct work_struct *work);
void rtw89_core_scan_start(struct rtw89_dev *rtwdev, struct rtw89_vif *rtwvif,
const u8 *mac_addr, bool hw_scan);
void rtw89_core_scan_complete(struct rtw89_dev *rtwdev,
struct ieee80211_vif *vif, bool hw_scan);
#endif #endif
...@@ -23,6 +23,7 @@ enum rtw89_debug_mask { ...@@ -23,6 +23,7 @@ enum rtw89_debug_mask {
RTW89_DBG_FW = BIT(12), RTW89_DBG_FW = BIT(12),
RTW89_DBG_BTC = BIT(13), RTW89_DBG_BTC = BIT(13),
RTW89_DBG_BF = BIT(14), RTW89_DBG_BF = BIT(14),
RTW89_DBG_HW_SCAN = BIT(15),
}; };
enum rtw89_debug_mac_reg_sel { enum rtw89_debug_mac_reg_sel {
......
This diff is collapsed.
This diff is collapsed.
...@@ -3129,6 +3129,57 @@ rtw89_mac_c2h_macid_pause(struct rtw89_dev *rtwdev, struct sk_buff *c2h, u32 len ...@@ -3129,6 +3129,57 @@ rtw89_mac_c2h_macid_pause(struct rtw89_dev *rtwdev, struct sk_buff *c2h, u32 len
{ {
} }
static bool rtw89_is_op_chan(struct rtw89_dev *rtwdev, u8 band, u8 channel)
{
struct rtw89_hw_scan_info *scan_info = &rtwdev->scan_info;
return band == scan_info->op_band && channel == scan_info->op_pri_ch;
}
static void
rtw89_mac_c2h_scanofld_rsp(struct rtw89_dev *rtwdev, struct sk_buff *c2h,
u32 len)
{
struct ieee80211_vif *vif = rtwdev->scan_info.scanning_vif;
struct rtw89_hal *hal = &rtwdev->hal;
u8 reason, status, tx_fail, band;
u16 chan;
tx_fail = RTW89_GET_MAC_C2H_SCANOFLD_TX_FAIL(c2h->data);
status = RTW89_GET_MAC_C2H_SCANOFLD_STATUS(c2h->data);
chan = RTW89_GET_MAC_C2H_SCANOFLD_PRI_CH(c2h->data);
reason = RTW89_GET_MAC_C2H_SCANOFLD_RSP(c2h->data);
band = RTW89_GET_MAC_C2H_SCANOFLD_BAND(c2h->data);
if (!(rtwdev->chip->support_bands & BIT(NL80211_BAND_6GHZ)))
band = chan > 14 ? RTW89_BAND_5G : RTW89_BAND_2G;
rtw89_debug(rtwdev, RTW89_DBG_HW_SCAN,
"band: %d, chan: %d, reason: %d, status: %d, tx_fail: %d\n",
band, chan, reason, status, tx_fail);
switch (reason) {
case RTW89_SCAN_LEAVE_CH_NOTIFY:
if (rtw89_is_op_chan(rtwdev, band, chan))
ieee80211_stop_queues(rtwdev->hw);
return;
case RTW89_SCAN_END_SCAN_NOTIFY:
rtw89_hw_scan_complete(rtwdev, vif, false);
break;
case RTW89_SCAN_ENTER_CH_NOTIFY:
if (rtw89_is_op_chan(rtwdev, band, chan))
ieee80211_wake_queues(rtwdev->hw);
break;
default:
return;
}
hal->prev_band_type = hal->current_band_type;
hal->prev_primary_channel = hal->current_channel;
hal->current_channel = chan;
hal->current_band_type = band;
}
static void static void
rtw89_mac_c2h_rec_ack(struct rtw89_dev *rtwdev, struct sk_buff *c2h, u32 len) rtw89_mac_c2h_rec_ack(struct rtw89_dev *rtwdev, struct sk_buff *c2h, u32 len)
{ {
...@@ -3172,6 +3223,7 @@ void (* const rtw89_mac_c2h_ofld_handler[])(struct rtw89_dev *rtwdev, ...@@ -3172,6 +3223,7 @@ void (* const rtw89_mac_c2h_ofld_handler[])(struct rtw89_dev *rtwdev,
[RTW89_MAC_C2H_FUNC_PKT_OFLD_RSP] = NULL, [RTW89_MAC_C2H_FUNC_PKT_OFLD_RSP] = NULL,
[RTW89_MAC_C2H_FUNC_BCN_RESEND] = NULL, [RTW89_MAC_C2H_FUNC_BCN_RESEND] = NULL,
[RTW89_MAC_C2H_FUNC_MACID_PAUSE] = rtw89_mac_c2h_macid_pause, [RTW89_MAC_C2H_FUNC_MACID_PAUSE] = rtw89_mac_c2h_macid_pause,
[RTW89_MAC_C2H_FUNC_SCANOFLD_RSP] = rtw89_mac_c2h_scanofld_rsp,
}; };
static static
......
...@@ -301,6 +301,7 @@ enum rtw89_mac_c2h_ofld_func { ...@@ -301,6 +301,7 @@ enum rtw89_mac_c2h_ofld_func {
RTW89_MAC_C2H_FUNC_PKT_OFLD_RSP, RTW89_MAC_C2H_FUNC_PKT_OFLD_RSP,
RTW89_MAC_C2H_FUNC_BCN_RESEND, RTW89_MAC_C2H_FUNC_BCN_RESEND,
RTW89_MAC_C2H_FUNC_MACID_PAUSE, RTW89_MAC_C2H_FUNC_MACID_PAUSE,
RTW89_MAC_C2H_FUNC_SCANOFLD_RSP = 0x9,
RTW89_MAC_C2H_FUNC_OFLD_MAX, RTW89_MAC_C2H_FUNC_OFLD_MAX,
}; };
......
...@@ -66,6 +66,9 @@ static int rtw89_ops_config(struct ieee80211_hw *hw, u32 changed) ...@@ -66,6 +66,9 @@ static int rtw89_ops_config(struct ieee80211_hw *hw, u32 changed)
{ {
struct rtw89_dev *rtwdev = hw->priv; struct rtw89_dev *rtwdev = hw->priv;
/* let previous ips work finish to ensure we don't leave ips twice */
cancel_work_sync(&rtwdev->ips_work);
mutex_lock(&rtwdev->mutex); mutex_lock(&rtwdev->mutex);
rtw89_leave_ps_mode(rtwdev); rtw89_leave_ps_mode(rtwdev);
...@@ -347,6 +350,13 @@ static void rtw89_ops_bss_info_changed(struct ieee80211_hw *hw, ...@@ -347,6 +350,13 @@ static void rtw89_ops_bss_info_changed(struct ieee80211_hw *hw,
rtw89_phy_set_bss_color(rtwdev, vif); rtw89_phy_set_bss_color(rtwdev, vif);
rtw89_chip_cfg_txpwr_ul_tb_offset(rtwdev, vif); rtw89_chip_cfg_txpwr_ul_tb_offset(rtwdev, vif);
rtw89_mac_port_update(rtwdev, rtwvif); rtw89_mac_port_update(rtwdev, rtwvif);
rtw89_store_op_chan(rtwdev);
} else {
/* Abort ongoing scan if cancel_scan isn't issued
* when disconnected by peer
*/
if (rtwdev->scanning)
rtw89_hw_scan_abort(rtwdev, vif);
} }
} }
...@@ -684,15 +694,9 @@ static void rtw89_ops_sw_scan_start(struct ieee80211_hw *hw, ...@@ -684,15 +694,9 @@ static void rtw89_ops_sw_scan_start(struct ieee80211_hw *hw,
{ {
struct rtw89_dev *rtwdev = hw->priv; struct rtw89_dev *rtwdev = hw->priv;
struct rtw89_vif *rtwvif = (struct rtw89_vif *)vif->drv_priv; struct rtw89_vif *rtwvif = (struct rtw89_vif *)vif->drv_priv;
struct rtw89_hal *hal = &rtwdev->hal;
mutex_lock(&rtwdev->mutex); mutex_lock(&rtwdev->mutex);
rtwdev->scanning = true; rtw89_core_scan_start(rtwdev, rtwvif, mac_addr, false);
rtw89_leave_lps(rtwdev);
rtw89_btc_ntfy_scan_start(rtwdev, RTW89_PHY_0, hal->current_band_type);
rtw89_chip_rfk_scan(rtwdev, true);
rtw89_hci_recalc_int_mit(rtwdev);
rtw89_fw_h2c_cam(rtwdev, rtwvif, NULL, mac_addr);
mutex_unlock(&rtwdev->mutex); mutex_unlock(&rtwdev->mutex);
} }
...@@ -700,14 +704,9 @@ static void rtw89_ops_sw_scan_complete(struct ieee80211_hw *hw, ...@@ -700,14 +704,9 @@ static void rtw89_ops_sw_scan_complete(struct ieee80211_hw *hw,
struct ieee80211_vif *vif) struct ieee80211_vif *vif)
{ {
struct rtw89_dev *rtwdev = hw->priv; struct rtw89_dev *rtwdev = hw->priv;
struct rtw89_vif *rtwvif = (struct rtw89_vif *)vif->drv_priv;
mutex_lock(&rtwdev->mutex); mutex_lock(&rtwdev->mutex);
rtw89_fw_h2c_cam(rtwdev, rtwvif, NULL, NULL); rtw89_core_scan_complete(rtwdev, vif, false);
rtw89_chip_rfk_scan(rtwdev, false);
rtw89_btc_ntfy_scan_finish(rtwdev, RTW89_PHY_0);
rtwdev->scanning = false;
rtwdev->dig.bypass_dig = true;
mutex_unlock(&rtwdev->mutex); mutex_unlock(&rtwdev->mutex);
} }
...@@ -720,6 +719,46 @@ static void rtw89_ops_reconfig_complete(struct ieee80211_hw *hw, ...@@ -720,6 +719,46 @@ static void rtw89_ops_reconfig_complete(struct ieee80211_hw *hw,
rtw89_ser_recfg_done(rtwdev); rtw89_ser_recfg_done(rtwdev);
} }
static int rtw89_ops_hw_scan(struct ieee80211_hw *hw, struct ieee80211_vif *vif,
struct ieee80211_scan_request *req)
{
struct rtw89_dev *rtwdev = hw->priv;
int ret = 0;
if (!rtwdev->fw.scan_offload)
return 1;
if (rtwdev->scanning)
return -EBUSY;
mutex_lock(&rtwdev->mutex);
rtw89_hw_scan_start(rtwdev, vif, req);
ret = rtw89_hw_scan_offload(rtwdev, vif, true);
if (ret) {
rtw89_hw_scan_abort(rtwdev, vif);
rtw89_err(rtwdev, "HW scan failed with status: %d\n", ret);
}
mutex_unlock(&rtwdev->mutex);
return ret;
}
static void rtw89_ops_cancel_hw_scan(struct ieee80211_hw *hw,
struct ieee80211_vif *vif)
{
struct rtw89_dev *rtwdev = hw->priv;
if (!rtwdev->fw.scan_offload)
return;
if (!rtwdev->scanning)
return;
mutex_lock(&rtwdev->mutex);
rtw89_hw_scan_abort(rtwdev, vif);
mutex_unlock(&rtwdev->mutex);
}
const struct ieee80211_ops rtw89_ops = { const struct ieee80211_ops rtw89_ops = {
.tx = rtw89_ops_tx, .tx = rtw89_ops_tx,
.wake_tx_queue = rtw89_ops_wake_tx_queue, .wake_tx_queue = rtw89_ops_wake_tx_queue,
...@@ -746,6 +785,8 @@ const struct ieee80211_ops rtw89_ops = { ...@@ -746,6 +785,8 @@ const struct ieee80211_ops rtw89_ops = {
.sw_scan_start = rtw89_ops_sw_scan_start, .sw_scan_start = rtw89_ops_sw_scan_start,
.sw_scan_complete = rtw89_ops_sw_scan_complete, .sw_scan_complete = rtw89_ops_sw_scan_complete,
.reconfig_complete = rtw89_ops_reconfig_complete, .reconfig_complete = rtw89_ops_reconfig_complete,
.hw_scan = rtw89_ops_hw_scan,
.cancel_hw_scan = rtw89_ops_cancel_hw_scan,
.set_sar_specs = rtw89_ops_set_sar_specs, .set_sar_specs = rtw89_ops_set_sar_specs,
}; };
EXPORT_SYMBOL(rtw89_ops); EXPORT_SYMBOL(rtw89_ops);
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment