]> git.ipfire.org Git - thirdparty/kernel/stable.git/commitdiff
wifi: rtw89: refactor flow that hw scan handles channel list
authorZong-Zhe Yang <kevin_yang@realtek.com>
Tue, 22 Apr 2025 01:46:12 +0000 (09:46 +0800)
committerPing-Ke Shih <pkshih@realtek.com>
Mon, 28 Apr 2025 06:34:12 +0000 (14:34 +0800)
FW has a limited amount of channels that can be dealt with by one HW scan
H2C command. Based on the limit, channels in scan request might be parsed
into SW structure piece by piece along with multiple HW scan H2C commands.
But, in order to estimate things of entire HW scan process, it's required
to have the whole parsed channel list when HW scan is going to start. So,
tweak HW scan flow to prepare the whole channel list ahead. Still, each HW
scan H2C command takes allowed amount of channels from the list according
to the limit.

Signed-off-by: Zong-Zhe Yang <kevin_yang@realtek.com>
Signed-off-by: Ping-Ke Shih <pkshih@realtek.com>
Link: https://patch.msgid.link/20250422014620.18421-5-pkshih@realtek.com
drivers/net/wireless/realtek/rtw89/core.c
drivers/net/wireless/realtek/rtw89/core.h
drivers/net/wireless/realtek/rtw89/fw.c
drivers/net/wireless/realtek/rtw89/fw.h
drivers/net/wireless/realtek/rtw89/mac.c
drivers/net/wireless/realtek/rtw89/mac.h
drivers/net/wireless/realtek/rtw89/mac80211.c
drivers/net/wireless/realtek/rtw89/mac_be.c

index 25510946251781f013243b60d9ae9650677fbd83..a6e67e22349e2ad651eb4b886005ea5d262b2ec4 100644 (file)
@@ -4873,6 +4873,7 @@ int rtw89_core_init(struct rtw89_dev *rtwdev)
                        continue;
                INIT_LIST_HEAD(&rtwdev->scan_info.pkt_list[band]);
        }
+       INIT_LIST_HEAD(&rtwdev->scan_info.chan_list);
        INIT_WORK(&rtwdev->ba_work, rtw89_core_ba_work);
        INIT_WORK(&rtwdev->txq_work, rtw89_core_txq_work);
        INIT_DELAYED_WORK(&rtwdev->txq_reinvoke_work, rtw89_core_txq_reinvoke_work);
@@ -4958,9 +4959,6 @@ void rtw89_core_scan_start(struct rtw89_dev *rtwdev, struct rtw89_vif_link *rtwv
        struct rtw89_bb_ctx *bb = rtw89_get_bb_ctx(rtwdev, rtwvif_link->phy_idx);
 
        rtwdev->scanning = true;
-       rtw89_leave_lps(rtwdev);
-       if (hw_scan)
-               rtw89_leave_ips_by_hwflags(rtwdev);
 
        ether_addr_copy(rtwvif_link->mac_addr, mac_addr);
        rtw89_btc_ntfy_scan_start(rtwdev, rtwvif_link->phy_idx, chan->band_type);
index b1fff57a748858925c5b93013cffac08c2efd124..52ee3dfc011b4f244da91e9b190c017487a71f5a 100644 (file)
@@ -5424,9 +5424,10 @@ struct rtw89_early_h2c {
 struct rtw89_hw_scan_info {
        struct rtw89_vif_link *scanning_vif;
        struct list_head pkt_list[NUM_NL80211_BANDS];
+       struct list_head chan_list;
        struct rtw89_chan op_chan;
+       bool connected;
        bool abort;
-       u32 last_chan_idx;
 };
 
 enum rtw89_phy_bb_gain_band {
index 5cf4b3cba047b2d4422a2cffe682115dd5e5f9a4..ae402d4c3773cefeecd74920c4997db9072450c5 100644 (file)
@@ -15,6 +15,8 @@
 #include "util.h"
 #include "wow.h"
 
+static bool rtw89_is_any_vif_connected_or_connecting(struct rtw89_dev *rtwdev);
+
 struct rtw89_eapol_2_of_2 {
        u8 gtkbody[14];
        u8 key_des_ver;
@@ -6535,7 +6537,7 @@ void rtw89_fw_st_dbg_dump(struct rtw89_dev *rtwdev)
        rtw89_fw_prog_cnt_dump(rtwdev);
 }
 
-static void rtw89_release_pkt_list(struct rtw89_dev *rtwdev)
+static void rtw89_hw_scan_release_pkt_list(struct rtw89_dev *rtwdev)
 {
        struct list_head *pkt_list = rtwdev->scan_info.pkt_list;
        struct rtw89_pktofld_info *info, *tmp;
@@ -6554,6 +6556,23 @@ static void rtw89_release_pkt_list(struct rtw89_dev *rtwdev)
        }
 }
 
+static void rtw89_hw_scan_cleanup(struct rtw89_dev *rtwdev,
+                                 struct rtw89_vif_link *rtwvif_link)
+{
+       const struct rtw89_mac_gen_def *mac = rtwdev->chip->mac_def;
+       struct rtw89_hw_scan_info *scan_info = &rtwdev->scan_info;
+       struct rtw89_vif *rtwvif = rtwvif_link->rtwvif;
+
+       mac->free_chan_list(rtwdev);
+       rtw89_hw_scan_release_pkt_list(rtwdev);
+
+       rtwvif->scan_req = NULL;
+       rtwvif->scan_ies = NULL;
+       scan_info->scanning_vif = NULL;
+       scan_info->abort = false;
+       scan_info->connected = false;
+}
+
 static bool rtw89_is_6ghz_wildcard_probe_req(struct rtw89_dev *rtwdev,
                                             struct cfg80211_scan_request *req,
                                             struct rtw89_pktofld_info *info,
@@ -6622,7 +6641,8 @@ out:
 }
 
 static int rtw89_hw_scan_update_probe_req(struct rtw89_dev *rtwdev,
-                                         struct rtw89_vif_link *rtwvif_link)
+                                         struct rtw89_vif_link *rtwvif_link,
+                                         const u8 *mac_addr)
 {
        struct rtw89_vif *rtwvif = rtwvif_link->rtwvif;
        struct cfg80211_scan_request *req = rtwvif->scan_req;
@@ -6631,7 +6651,7 @@ static int rtw89_hw_scan_update_probe_req(struct rtw89_dev *rtwdev,
        int ret;
 
        for (i = 0; i < num; i++) {
-               skb = ieee80211_probereq_get(rtwdev->hw, rtwvif_link->mac_addr,
+               skb = ieee80211_probereq_get(rtwdev->hw, mac_addr,
                                             req->ssids[i].ssid,
                                             req->ssids[i].ssid_len,
                                             req->ie_len);
@@ -7005,24 +7025,24 @@ out:
        return ret;
 }
 
-int rtw89_hw_scan_add_chan_list_ax(struct rtw89_dev *rtwdev,
-                                  struct rtw89_vif_link *rtwvif_link, bool connected)
+int rtw89_hw_scan_prep_chan_list_ax(struct rtw89_dev *rtwdev,
+                                   struct rtw89_vif_link *rtwvif_link)
 {
+       struct rtw89_hw_scan_info *scan_info = &rtwdev->scan_info;
        struct rtw89_vif *rtwvif = rtwvif_link->rtwvif;
        struct cfg80211_scan_request *req = rtwvif->scan_req;
        struct rtw89_mac_chinfo_ax *ch_info, *tmp;
        struct ieee80211_channel *channel;
        struct list_head chan_list;
        bool random_seq = req->flags & NL80211_SCAN_FLAG_RANDOM_SN;
-       int list_len, off_chan_time = 0;
        enum rtw89_chan_type type;
-       int ret = 0;
+       int off_chan_time = 0;
+       int ret;
        u32 idx;
 
        INIT_LIST_HEAD(&chan_list);
-       for (idx = rtwdev->scan_info.last_chan_idx, list_len = 0;
-            idx < req->n_channels && list_len < RTW89_SCAN_LIST_LIMIT_AX;
-            idx++, list_len++) {
+
+       for (idx = 0; idx < req->n_channels; idx++) {
                channel = req->channels[idx];
                ch_info = kzalloc(sizeof(*ch_info), GFP_KERNEL);
                if (!ch_info) {
@@ -7051,7 +7071,7 @@ int rtw89_hw_scan_add_chan_list_ax(struct rtw89_dev *rtwdev,
                        type = RTW89_CHAN_ACTIVE;
                rtw89_hw_scan_add_chan_ax(rtwdev, type, req->n_ssids, ch_info);
 
-               if (connected &&
+               if (scan_info->connected &&
                    off_chan_time + ch_info->period > RTW89_OFF_CHAN_TIME) {
                        tmp = kzalloc(sizeof(*tmp), GFP_KERNEL);
                        if (!tmp) {
@@ -7066,13 +7086,13 @@ int rtw89_hw_scan_add_chan_list_ax(struct rtw89_dev *rtwdev,
                        rtw89_hw_scan_add_chan_ax(rtwdev, type, 0, tmp);
                        list_add_tail(&tmp->list, &chan_list);
                        off_chan_time = 0;
-                       list_len++;
                }
                list_add_tail(&ch_info->list, &chan_list);
                off_chan_time += ch_info->period;
        }
-       rtwdev->scan_info.last_chan_idx = idx;
-       ret = rtw89_fw_h2c_scan_list_offload_ax(rtwdev, list_len, &chan_list);
+
+       list_splice_tail(&chan_list, &scan_info->chan_list);
+       return 0;
 
 out:
        list_for_each_entry_safe(ch_info, tmp, &chan_list, list) {
@@ -7083,6 +7103,46 @@ out:
        return ret;
 }
 
+void rtw89_hw_scan_free_chan_list_ax(struct rtw89_dev *rtwdev)
+{
+       struct rtw89_hw_scan_info *scan_info = &rtwdev->scan_info;
+       struct rtw89_mac_chinfo_ax *ch_info, *tmp;
+
+       list_for_each_entry_safe(ch_info, tmp, &scan_info->chan_list, list) {
+               list_del(&ch_info->list);
+               kfree(ch_info);
+       }
+}
+
+int rtw89_hw_scan_add_chan_list_ax(struct rtw89_dev *rtwdev,
+                                  struct rtw89_vif_link *rtwvif_link)
+{
+       struct rtw89_hw_scan_info *scan_info = &rtwdev->scan_info;
+       struct rtw89_mac_chinfo_ax *ch_info, *tmp;
+       unsigned int list_len = 0;
+       struct list_head list;
+       int ret;
+
+       INIT_LIST_HEAD(&list);
+
+       list_for_each_entry_safe(ch_info, tmp, &scan_info->chan_list, list) {
+               list_move_tail(&ch_info->list, &list);
+
+               list_len++;
+               if (list_len == RTW89_SCAN_LIST_LIMIT_AX)
+                       break;
+       }
+
+       ret = rtw89_fw_h2c_scan_list_offload_ax(rtwdev, list_len, &list);
+
+       list_for_each_entry_safe(ch_info, tmp, &list, list) {
+               list_del(&ch_info->list);
+               kfree(ch_info);
+       }
+
+       return ret;
+}
+
 int rtw89_pno_scan_add_chan_list_be(struct rtw89_dev *rtwdev,
                                    struct rtw89_vif_link *rtwvif_link)
 {
@@ -7136,25 +7196,24 @@ out:
        return ret;
 }
 
-int rtw89_hw_scan_add_chan_list_be(struct rtw89_dev *rtwdev,
-                                  struct rtw89_vif_link *rtwvif_link, bool connected)
+int rtw89_hw_scan_prep_chan_list_be(struct rtw89_dev *rtwdev,
+                                   struct rtw89_vif_link *rtwvif_link)
 {
+       struct rtw89_hw_scan_info *scan_info = &rtwdev->scan_info;
        struct rtw89_vif *rtwvif = rtwvif_link->rtwvif;
        struct cfg80211_scan_request *req = rtwvif->scan_req;
        struct rtw89_mac_chinfo_be *ch_info, *tmp;
        struct ieee80211_channel *channel;
        struct list_head chan_list;
        enum rtw89_chan_type type;
-       int list_len, ret;
        bool random_seq;
+       int ret;
        u32 idx;
 
        random_seq = !!(req->flags & NL80211_SCAN_FLAG_RANDOM_SN);
        INIT_LIST_HEAD(&chan_list);
 
-       for (idx = rtwdev->scan_info.last_chan_idx, list_len = 0;
-            idx < req->n_channels && list_len < RTW89_SCAN_LIST_LIMIT_BE;
-            idx++, list_len++) {
+       for (idx = 0; idx < req->n_channels; idx++) {
                channel = req->channels[idx];
                ch_info = kzalloc(sizeof(*ch_info), GFP_KERNEL);
                if (!ch_info) {
@@ -7184,9 +7243,8 @@ int rtw89_hw_scan_add_chan_list_be(struct rtw89_dev *rtwdev,
                list_add_tail(&ch_info->list, &chan_list);
        }
 
-       rtwdev->scan_info.last_chan_idx = idx;
-       ret = rtw89_fw_h2c_scan_list_offload_be(rtwdev, list_len, &chan_list,
-                                               rtwvif_link);
+       list_splice_tail(&chan_list, &scan_info->chan_list);
+       return 0;
 
 out:
        list_for_each_entry_safe(ch_info, tmp, &chan_list, list) {
@@ -7197,25 +7255,67 @@ out:
        return ret;
 }
 
+void rtw89_hw_scan_free_chan_list_be(struct rtw89_dev *rtwdev)
+{
+       struct rtw89_hw_scan_info *scan_info = &rtwdev->scan_info;
+       struct rtw89_mac_chinfo_be *ch_info, *tmp;
+
+       list_for_each_entry_safe(ch_info, tmp, &scan_info->chan_list, list) {
+               list_del(&ch_info->list);
+               kfree(ch_info);
+       }
+}
+
+int rtw89_hw_scan_add_chan_list_be(struct rtw89_dev *rtwdev,
+                                  struct rtw89_vif_link *rtwvif_link)
+{
+       struct rtw89_hw_scan_info *scan_info = &rtwdev->scan_info;
+       struct rtw89_mac_chinfo_be *ch_info, *tmp;
+       unsigned int list_len = 0;
+       struct list_head list;
+       int ret;
+
+       INIT_LIST_HEAD(&list);
+
+       list_for_each_entry_safe(ch_info, tmp, &scan_info->chan_list, list) {
+               list_move_tail(&ch_info->list, &list);
+
+               list_len++;
+               if (list_len == RTW89_SCAN_LIST_LIMIT_BE)
+                       break;
+       }
+
+       ret = rtw89_fw_h2c_scan_list_offload_be(rtwdev, list_len, &list,
+                                               rtwvif_link);
+
+       list_for_each_entry_safe(ch_info, tmp, &list, list) {
+               list_del(&ch_info->list);
+               kfree(ch_info);
+       }
+
+       return ret;
+}
+
 static int rtw89_hw_scan_prehandle(struct rtw89_dev *rtwdev,
-                                  struct rtw89_vif_link *rtwvif_link, bool connected)
+                                  struct rtw89_vif_link *rtwvif_link,
+                                  const u8 *mac_addr)
 {
        const struct rtw89_mac_gen_def *mac = rtwdev->chip->mac_def;
        int ret;
 
-       ret = rtw89_hw_scan_update_probe_req(rtwdev, rtwvif_link);
+       ret = rtw89_hw_scan_update_probe_req(rtwdev, rtwvif_link, mac_addr);
        if (ret) {
                rtw89_err(rtwdev, "Update probe request failed\n");
                goto out;
        }
-       ret = mac->add_chan_list(rtwdev, rtwvif_link, connected);
+       ret = mac->prep_chan_list(rtwdev, rtwvif_link);
 out:
        return ret;
 }
 
-void rtw89_hw_scan_start(struct rtw89_dev *rtwdev,
-                        struct rtw89_vif_link *rtwvif_link,
-                        struct ieee80211_scan_request *scan_req)
+int rtw89_hw_scan_start(struct rtw89_dev *rtwdev,
+                       struct rtw89_vif_link *rtwvif_link,
+                       struct ieee80211_scan_request *scan_req)
 {
        const struct rtw89_mac_gen_def *mac = rtwdev->chip->mac_def;
        struct cfg80211_scan_request *req = &scan_req->req;
@@ -7225,23 +7325,32 @@ void rtw89_hw_scan_start(struct rtw89_dev *rtwdev,
        u32 rx_fltr = rtwdev->hal.rx_fltr;
        u8 mac_addr[ETH_ALEN];
        u32 reg;
+       int ret;
 
        /* clone op and keep it during scan */
        rtwdev->scan_info.op_chan = *chan;
 
+       rtwdev->scan_info.connected = rtw89_is_any_vif_connected_or_connecting(rtwdev);
        rtwdev->scan_info.scanning_vif = rtwvif_link;
-       rtwdev->scan_info.last_chan_idx = 0;
        rtwdev->scan_info.abort = false;
        rtwvif->scan_ies = &scan_req->ies;
        rtwvif->scan_req = req;
-       ieee80211_stop_queues(rtwdev->hw);
-       rtw89_mac_port_cfg_rx_sync(rtwdev, rtwvif_link, false);
 
        if (req->flags & NL80211_SCAN_FLAG_RANDOM_ADDR)
                get_random_mask_addr(mac_addr, req->mac_addr,
                                     req->mac_addr_mask);
        else
                ether_addr_copy(mac_addr, rtwvif_link->mac_addr);
+
+       ret = rtw89_hw_scan_prehandle(rtwdev, rtwvif_link, mac_addr);
+       if (ret) {
+               rtw89_hw_scan_cleanup(rtwdev, rtwvif_link);
+               return ret;
+       }
+
+       ieee80211_stop_queues(rtwdev->hw);
+       rtw89_mac_port_cfg_rx_sync(rtwdev, rtwvif_link, false);
+
        rtw89_core_scan_start(rtwdev, rtwvif_link, mac_addr, true);
 
        rx_fltr &= ~B_AX_A_BCN_CHK_EN;
@@ -7252,6 +7361,8 @@ void rtw89_hw_scan_start(struct rtw89_dev *rtwdev,
        rtw89_write32_mask(rtwdev, reg, B_AX_RX_FLTR_CFG_MASK, rx_fltr);
 
        rtw89_chanctx_pause(rtwdev, RTW89_CHANCTX_PAUSE_REASON_HW_SCAN);
+
+       return 0;
 }
 
 struct rtw89_hw_scan_complete_cb_data {
@@ -7262,20 +7373,16 @@ struct rtw89_hw_scan_complete_cb_data {
 static int rtw89_hw_scan_complete_cb(struct rtw89_dev *rtwdev, void *data)
 {
        const struct rtw89_mac_gen_def *mac = rtwdev->chip->mac_def;
-       struct rtw89_hw_scan_info *scan_info = &rtwdev->scan_info;
        struct rtw89_hw_scan_complete_cb_data *cb_data = data;
        struct rtw89_vif_link *rtwvif_link = cb_data->rtwvif_link;
        struct cfg80211_scan_info info = {
                .aborted = cb_data->aborted,
        };
-       struct rtw89_vif *rtwvif;
        u32 reg;
 
        if (!rtwvif_link)
                return -EINVAL;
 
-       rtwvif = rtwvif_link->rtwvif;
-
        reg = rtw89_mac_reg_by_idx(rtwdev, mac->rx_fltr, rtwvif_link->mac_idx);
        rtw89_write32_mask(rtwdev, reg, B_AX_RX_FLTR_CFG_MASK, rtwdev->hal.rx_fltr);
 
@@ -7285,12 +7392,7 @@ static int rtw89_hw_scan_complete_cb(struct rtw89_dev *rtwdev, void *data)
        rtw89_mac_port_cfg_rx_sync(rtwdev, rtwvif_link, true);
        rtw89_mac_enable_beacon_for_ap_vifs(rtwdev, true);
 
-       rtw89_release_pkt_list(rtwdev);
-       rtwvif->scan_req = NULL;
-       rtwvif->scan_ies = NULL;
-       scan_info->last_chan_idx = 0;
-       scan_info->scanning_vif = NULL;
-       scan_info->abort = false;
+       rtw89_hw_scan_cleanup(rtwdev, rtwvif_link);
 
        return 0;
 }
@@ -7365,11 +7467,11 @@ int rtw89_hw_scan_offload(struct rtw89_dev *rtwdev,
        if (!rtwvif_link)
                return -EINVAL;
 
-       connected = rtw89_is_any_vif_connected_or_connecting(rtwdev);
+       connected = rtwdev->scan_info.connected;
        opt.enable = enable;
        opt.target_ch_mode = connected;
        if (enable) {
-               ret = rtw89_hw_scan_prehandle(rtwdev, rtwvif_link, connected);
+               ret = mac->add_chan_list(rtwdev, rtwvif_link);
                if (ret)
                        goto out;
        }
index 1395ac9d6b782c075428771f2e8cb615fada8bc3..0d89083df49ad672bc75f202ea55cb0737e56f9b 100644 (file)
@@ -4716,9 +4716,9 @@ int rtw89_fw_msg_reg(struct rtw89_dev *rtwdev,
                     struct rtw89_mac_c2h_info *c2h_info);
 int rtw89_fw_h2c_fw_log(struct rtw89_dev *rtwdev, bool enable);
 void rtw89_fw_st_dbg_dump(struct rtw89_dev *rtwdev);
-void rtw89_hw_scan_start(struct rtw89_dev *rtwdev,
-                        struct rtw89_vif_link *rtwvif_link,
-                        struct ieee80211_scan_request *scan_req);
+int rtw89_hw_scan_start(struct rtw89_dev *rtwdev,
+                       struct rtw89_vif_link *rtwvif_link,
+                       struct ieee80211_scan_request *scan_req);
 void rtw89_hw_scan_complete(struct rtw89_dev *rtwdev,
                            struct rtw89_vif_link *rtwvif_link,
                            bool aborted);
@@ -4727,12 +4727,18 @@ int rtw89_hw_scan_offload(struct rtw89_dev *rtwdev,
                          bool enable);
 void rtw89_hw_scan_abort(struct rtw89_dev *rtwdev,
                         struct rtw89_vif_link *rtwvif_link);
+int rtw89_hw_scan_prep_chan_list_ax(struct rtw89_dev *rtwdev,
+                                   struct rtw89_vif_link *rtwvif_link);
+void rtw89_hw_scan_free_chan_list_ax(struct rtw89_dev *rtwdev);
 int rtw89_hw_scan_add_chan_list_ax(struct rtw89_dev *rtwdev,
-                                  struct rtw89_vif_link *rtwvif_link, bool connected);
+                                  struct rtw89_vif_link *rtwvif_link);
 int rtw89_pno_scan_add_chan_list_ax(struct rtw89_dev *rtwdev,
                                    struct rtw89_vif_link *rtwvif_link);
+int rtw89_hw_scan_prep_chan_list_be(struct rtw89_dev *rtwdev,
+                                   struct rtw89_vif_link *rtwvif_link);
+void rtw89_hw_scan_free_chan_list_be(struct rtw89_dev *rtwdev);
 int rtw89_hw_scan_add_chan_list_be(struct rtw89_dev *rtwdev,
-                                  struct rtw89_vif_link *rtwvif_link, bool connected);
+                                  struct rtw89_vif_link *rtwvif_link);
 int rtw89_pno_scan_add_chan_list_be(struct rtw89_dev *rtwdev,
                                    struct rtw89_vif_link *rtwvif_link);
 int rtw89_fw_h2c_trigger_cpu_exception(struct rtw89_dev *rtwdev);
index b4841f948ec1c70492e19c1ae4c8abe62827e0e0..650e25f11fe432a18d6beb5fa3fb0da1b5dc822b 100644 (file)
@@ -4899,11 +4899,11 @@ rtw89_mac_c2h_scanofld_rsp(struct rtw89_dev *rtwdev, struct sk_buff *skb,
        struct rtw89_vif_link *rtwvif_link = rtwdev->scan_info.scanning_vif;
        struct rtw89_vif *rtwvif;
        struct rtw89_chan new;
-       u32 last_chan = rtwdev->scan_info.last_chan_idx, report_tsf;
        u16 actual_period, expect_period;
        u8 reason, status, tx_fail, band;
        u8 mac_idx, sw_def, fw_def;
        u8 ver = U8_MAX;
+       u32 report_tsf;
        u16 chan;
        int ret;
 
@@ -4962,7 +4962,7 @@ rtw89_mac_c2h_scanofld_rsp(struct rtw89_dev *rtwdev, struct sk_buff *skb,
                        return;
 
                if (rtwvif_link && rtwvif->scan_req &&
-                   last_chan < rtwvif->scan_req->n_channels) {
+                   !list_empty(&rtwdev->scan_info.chan_list)) {
                        ret = rtw89_hw_scan_offload(rtwdev, rtwvif_link, true);
                        if (ret) {
                                rtw89_hw_scan_abort(rtwdev, rtwvif_link);
@@ -6889,6 +6889,8 @@ const struct rtw89_mac_gen_def rtw89_mac_gen_ax = {
 
        .is_txq_empty = mac_is_txq_empty_ax,
 
+       .prep_chan_list = rtw89_hw_scan_prep_chan_list_ax,
+       .free_chan_list = rtw89_hw_scan_free_chan_list_ax,
        .add_chan_list = rtw89_hw_scan_add_chan_list_ax,
        .add_chan_list_pno = rtw89_pno_scan_add_chan_list_ax,
        .scan_offload = rtw89_fw_h2c_scan_offload_ax,
index fd7935d245019f2af6e488f2d105a42854716411..47d655fbf2ca43c1d766a71aa48531e60087c5e0 100644 (file)
@@ -1031,8 +1031,11 @@ struct rtw89_mac_gen_def {
 
        bool (*is_txq_empty)(struct rtw89_dev *rtwdev);
 
+       int (*prep_chan_list)(struct rtw89_dev *rtwdev,
+                             struct rtw89_vif_link *rtwvif_link);
+       void (*free_chan_list)(struct rtw89_dev *rtwdev);
        int (*add_chan_list)(struct rtw89_dev *rtwdev,
-                            struct rtw89_vif_link *rtwvif_link, bool connected);
+                            struct rtw89_vif_link *rtwvif_link);
        int (*add_chan_list_pno)(struct rtw89_dev *rtwdev,
                                 struct rtw89_vif_link *rtwvif_link);
        int (*scan_offload)(struct rtw89_dev *rtwdev,
index 4fded07d0beebf7e38bcddf69fbda2effd90074b..d51e3267ab6c7e43a7c557ca05a287caa21d6287 100644 (file)
@@ -1159,6 +1159,8 @@ static void rtw89_ops_sw_scan_start(struct ieee80211_hw *hw,
                return;
        }
 
+       rtw89_leave_lps(rtwdev);
+
        rtw89_core_scan_start(rtwdev, rtwvif_link, mac_addr, false);
 }
 
@@ -1211,7 +1213,13 @@ static int rtw89_ops_hw_scan(struct ieee80211_hw *hw, struct ieee80211_vif *vif,
                return -ENOLINK;
        }
 
-       rtw89_hw_scan_start(rtwdev, rtwvif_link, req);
+       rtw89_leave_lps(rtwdev);
+       rtw89_leave_ips_by_hwflags(rtwdev);
+
+       ret = rtw89_hw_scan_start(rtwdev, rtwvif_link, req);
+       if (ret)
+               return ret;
+
        ret = rtw89_hw_scan_offload(rtwdev, rtwvif_link, true);
        if (ret) {
                rtw89_hw_scan_abort(rtwdev, rtwvif_link);
index 99b82dc85ea3893b35fcd3d93953cc6b8ee72a0e..a1ba6ca431d7489830e16be2b12a37c11550ba0d 100644 (file)
@@ -2636,6 +2636,8 @@ const struct rtw89_mac_gen_def rtw89_mac_gen_be = {
 
        .is_txq_empty = mac_is_txq_empty_be,
 
+       .prep_chan_list = rtw89_hw_scan_prep_chan_list_be,
+       .free_chan_list = rtw89_hw_scan_free_chan_list_be,
        .add_chan_list = rtw89_hw_scan_add_chan_list_be,
        .add_chan_list_pno = rtw89_pno_scan_add_chan_list_be,
        .scan_offload = rtw89_fw_h2c_scan_offload_be,