[issue #5] Hidden SSID connection in Linaro - 18.01

Hi @Loic,

We are working on a custom board based on Linaro-18.01 and facing issue regarding connecting hidden SSID. We have used WCN3660B WiFi chip on our board.

  1. Earlier we were only able to scan 2.4 GHZ with Linaro -18.01 release with the offload scan.
  2. Then, we have changed the code as below to enable SW scan and that is why we can see 2.4 GHz and 5GHZ both channels.
-- a/drivers/net/wireless/ath/wcn36xx/main.c
+++ b/drivers/net/wireless/ath/wcn36xx/main.c
@@ -652,7 +652,7 @@ static int wcn36xx_hw_scan(struct ieee80211_hw *hw,

        mutex_unlock(&wcn->scan_lock);

-       if (!get_feat_caps(wcn->fw_feat_caps, SCAN_OFFLOAD)) {
+       if (get_feat_caps(wcn->fw_feat_caps, SCAN_OFFLOAD)) {
                /* legacy manual/sw scan */
                schedule_work(&wcn->scan_work);
                return 0;
-- 

In 1) we are able to connect to 2.4 GHz hidden SSID but in 2) we are not able to connect to 2.4/5GHZ hidden SSID.

Now, we have changed code as below in Linaro-18.01 , so that we are able to see both 2.4 (with HW scan) and 5 GHZ (with SW scan) and also able to connect to hidden SSID of both (still testing more times and with more APs).

@@ -649,6 +650,8 @@ static int wcn36xx_hw_scan(struct ieee80211_hw *hw,
                           struct ieee80211_scan_request *hw_req)
 {
        struct wcn36xx *wcn = hw->priv;
+       int ret = 0, i;
+
        mutex_lock(&wcn->scan_lock);
        if (wcn->scan_req) {
                mutex_unlock(&wcn->scan_lock);
@@ -660,13 +663,22 @@ static int wcn36xx_hw_scan(struct ieee80211_hw *hw,
 
        mutex_unlock(&wcn->scan_lock);
 
-       if (get_feat_caps(wcn->fw_feat_caps, SCAN_OFFLOAD)) {
-               /* legacy manual/sw scan */
-               schedule_work(&wcn->scan_work);
-               return 0;
+       ret = wcn36xx_smd_start_hw_scan(wcn, vif, &hw_req->req);
+       printk("%s: HW scan called\n", __func__);
+
+       /* For unknown reason, the hardware offloaded scan only works with
+        * 2.4Ghz channels, fallback to software scan in other cases.
+        */
+       for (i = 0; i < hw_req->req.n_channels; i++) {
+               if (hw_req->req.channels[i]->band != NL80211_BAND_2GHZ) {
+                       /* legacy manual/sw scan */
+                       schedule_work(&wcn->scan_work);
+                       printk("%s: scheduled for SW scan - 5 GHz\n", __func__);
+                       return 0;
+               }
        }
 
-       return wcn36xx_smd_start_hw_scan(wcn, vif, &hw_req->req);
+       return ret;

Here while doing scan we are facing below warning from the driver.

root@linaro-alip:~# wpa_cli scan
Selected interface ‘wlan0’
OK
[ 3492.428055] wcn36xx_hw_scan: HW scan called
[ 3492.428080] wcn36xx_hw_scan: scheduled for SW scan - 5 GHz
root@linaro-alip:~#
root@linaro-alip:~# [ 3494.120000] wcn36xx_hw_scan_worker: ieee80211_scan_completed CALLED -----
[ 3494.120237] __ieee80211_scan_completed: --------- aborted = 0, scanning = 2
[ 3494.125896] __ieee80211_scan_completed: WARN ON finished
[ 3494.133125] __ieee80211_scan_completed: After scan IF condition
[ 3497.422454] __ieee80211_scan_completed: --------- aborted = 0, scanning = 0
[ 3497.422711] ------------[ cut here ]------------
[ 3497.429070] WARNING: CPU: 0 PID: 2693 at …/net/mac80211/scan.c:347 __ieee80211_scan_completed+0x4c/0x208 [mac80211]
[ 3497.433195] Modules linked in: ccm aes_neon_blk rfcomm bnep arc4 wcn36xx btqcomsmd mac80211 btqca bluetooth ecdh_generic cfg80211 venus_enc venus_dec videobuf2_dma_sg videobuf2_memops crc32_ce qcom_wcs
[ 3497.453505] CPU: 0 PID: 2693 Comm: kworker/u8:1 Tainted: G W 4.14.0-qcomlt-arm64 #90
[ 3497.475730] Hardware name: Qualcomm Technologies, Inc. APQ 8016 SBC (DT)
[ 3497.484935] Workqueue: phy0 ieee80211_scan_work [mac80211]
[ 3497.491264] task: ffff8000292b8000 task.stack: ffff000009b40000
[ 3497.497012] PC is at __ieee80211_scan_completed+0x4c/0x208 [mac80211]
[ 3497.502831] LR is at __ieee80211_scan_completed+0x40/0x208 [mac80211]
[ 3497.508977] pc : [] lr : [] pstate: 40000145
[ 3497.515395] sp : ffff000009b43d20
[ 3497.522854] x29: ffff000009b43d20 x28: 0000000000000000
[ 3497.526070] x27: ffff80003b42bfb8 x26: ffff80003d4047a0
[ 3497.531451] x25: ffff0000080e1318 x24: 0000000000000002
[ 3497.536747] x23: 0000000000000000 x22: ffff000000ded550
[ 3497.542042] x21: ffff000000d99818 x20: 0000000000000000
[ 3497.547337] x19: ffff80003d4047a0 x18: 0000000000000000
[ 3497.552633] x17: ffff000008ac07c8 x16: 0000000000000052
[ 3497.557927] x15: 0000000000000010 x14: ffffffffffffffff
[ 3497.563222] x13: ffff0000894b255f x12: ffff0000094b2567
[ 3497.568517] x11: 6261202d2d2d2d2d x10: 0000000000000004
[ 3497.573813] x9 : 0000000000000051 x8 : 000000000000000d
[ 3497.579107] x7 : ffff000009b43acc x6 : 00000000000010f0
[ 3497.584403] x5 : 0000000000000000 x4 : 0000000000000000
[ 3497.589698] x3 : 0000000000000000 x2 : ffff8000292b8000
[ 3497.594993] x1 : ffff8000292b8000 x0 : 0000000000000000
[ 3497.600287] Call trace:
[ 3497.605587] Exception stack(0xffff000009b43be0 to 0xffff000009b43d20)
[ 3497.607770] 3be0: 0000000000000000 ffff8000292b8000 ffff8000292b8000 0000000000000000
[ 3497.614368] 3c00: 0000000000000000 0000000000000000 00000000000010f0 ffff000009b43acc
[ 3497.622179] 3c20: 000000000000000d 0000000000000051 0000000000000004 6261202d2d2d2d2d
[ 3497.629995] 3c40: ffff0000094b2567 ffff0000894b255f ffffffffffffffff 0000000000000010
[ 3497.637806] 3c60: 0000000000000052 ffff000008ac07c8 0000000000000000 ffff80003d4047a0
[ 3497.645618] 3c80: 0000000000000000 ffff000000d99818 ffff000000ded550 0000000000000000
[ 3497.653432] 3ca0: 0000000000000002 ffff0000080e1318 ffff80003d4047a0 ffff80003b42bfb8
[ 3497.661243] 3cc0: 0000000000000000 ffff000009b43d20 ffff000000d983e0 ffff000009b43d20
[ 3497.669054] 3ce0: ffff000000d983ec 0000000040000145 0000000000000000 0000000000000000
[ 3497.676869] 3d00: ffffffffffffffff 0000000000000000 ffff000009b43d20 ffff000000d983ec
[ 3497.685131] [] __ieee80211_scan_completed+0x4c/0x208 [mac80211]
[ 3497.692916] [] ieee80211_scan_work+0x1e8/0x4b8 [mac80211]
[ 3497.699965] [] process_one_work+0x1c8/0x328
[ 3497.706727] [] worker_thread+0x44/0x450
[ 3497.712625] [] kthread+0x128/0x130
[ 3497.718012] [] ret_from_fork+0x10/0x18
[ 3497.723035] —[ end trace a01f2291381f9cad ]—
[ 3497.728548] __ieee80211_scan_completed: WARN ON finished
[ 3497.733016] ------------[ cut here ]------------
[ 3497.738304] WARNING: CPU: 0 PID: 2693 at …/net/mac80211/scan.c:351 __ieee80211_scan_completed+0x68/0x208 [mac80211]
[ 3497.742817] Modules linked in: ccm aes_neon_blk rfcomm bnep arc4 wcn36xx btqcomsmd mac80211 btqca bluetooth ecdh_generic cfg80211 venus_enc venus_dec videobuf2_dma_sg videobuf2_memops crc32_ce qcom_wcs
[ 3497.763119] CPU: 0 PID: 2693 Comm: kworker/u8:1 Tainted: G W 4.14.0-qcomlt-arm64 #90
[ 3497.785350] Hardware name: Qualcomm Technologies, Inc. APQ 8016 SBC (DT)
[ 3497.794201] Workqueue: phy0 ieee80211_scan_work [mac80211]
[ 3497.800884] task: ffff8000292b8000 task.stack: ffff000009b40000
[ 3497.806257] PC is at __ieee80211_scan_completed+0x68/0x208 [mac80211]
[ 3497.812073] LR is at __ieee80211_scan_completed+0x60/0x208 [mac80211]
[ 3497.818595] pc : [] lr : [] pstate: 40000145
[ 3497.825017] sp : ffff000009b43d20
[ 3497.832478] x29: ffff000009b43d20 x28: 0000000000000000
[ 3497.835693] x27: ffff80003b42bfb8 x26: ffff80003d4047a0
[ 3497.841074] x25: ffff0000080e1318 x24: 0000000000000002
[ 3497.846370] x23: 0000000000000000 x22: ffff000000ded550
[ 3497.851664] x21: ffff000000d99818 x20: 0000000000000001
[ 3497.856960] x19: ffff80003d4047a0 x18: 0000000000000000
[ 3497.862255] x17: ffff000008ac07c8 x16: 0000000000000052
[ 3497.867550] x15: 0000000000000010 x14: ffffffffffffffff
[ 3497.872844] x13: ffff0000894b255f x12: ffff0000094b2567
[ 3497.878140] x11: ffff000009334000 x10: 0000000000000004
[ 3497.883435] x9 : 000000000000003d x8 : 000000000000000d
[ 3497.888730] x7 : ffff000009b43acc x6 : 000000000000111e
[ 3497.894025] x5 : 0000000000000000 x4 : 0000000000000000
[ 3497.899320] x3 : 0000000000000000 x2 : ffff8000292b8000
[ 3497.904617] x1 : ffff8000292b8000 x0 : 0000000000000000
[ 3497.909912] Call trace:
[ 3497.915204] Exception stack(0xffff000009b43be0 to 0xffff000009b43d20)
[ 3497.917381] 3be0: 0000000000000000 ffff8000292b8000 ffff8000292b8000 0000000000000000
[ 3497.923979] 3c00: 0000000000000000 0000000000000000 000000000000111e ffff000009b43acc
[ 3497.931792] 3c20: 000000000000000d 000000000000003d 0000000000000004 ffff000009334000
[ 3497.939604] 3c40: ffff0000094b2567 ffff0000894b255f ffffffffffffffff 0000000000000010
[ 3497.947417] 3c60: 0000000000000052 ffff000008ac07c8 0000000000000000 ffff80003d4047a0
[ 3497.955229] 3c80: 0000000000000001 ffff000000d99818 ffff000000ded550 0000000000000000
[ 3497.963041] 3ca0: 0000000000000002 ffff0000080e1318 ffff80003d4047a0 ffff80003b42bfb8
[ 3497.970855] 3cc0: 0000000000000000 ffff000009b43d20 ffff000000d98400 ffff000009b43d20
[ 3497.978667] 3ce0: ffff000000d98408 0000000040000145 ffff8000292b8000 0000000000000000
[ 3497.986479] 3d00: ffffffffffffffff 0000000000000000 ffff000009b43d20 ffff000000d98408
[ 3497.994367] [] __ieee80211_scan_completed+0x68/0x208 [mac80211]
[ 3498.002175] [] ieee80211_scan_work+0x1e8/0x4b8 [mac80211]
[ 3498.009571] [] process_one_work+0x1c8/0x328
[ 3498.016338] [] worker_thread+0x44/0x450
[ 3498.022240] [] kthread+0x128/0x130
[ 3498.027622] [] ret_from_fork+0x10/0x18
[ 3498.032656] —[ end trace a01f2291381f9cae ]—

Can you please suggest how we can resolve this?

Regards,
Parth Y Shah

I suppose issue is that you use both software and hardware scan, but hardware scan is completed before your software scan finish. I would suggest to align with the wcn36xx driver available at: loic.poulain/linux.git - [no description]
(especially the [wcn36xx: Fix software-driven scan] patch).

Thanks for your quick reply @Loic

We had also tried earlier to apply your latest patch (loic.poulain/linux.git - [no description]) on our Linaro-18.01 codebase as below.

    From 4ec012ad6b2642f06a5fd93112495258ef588829 Mon Sep 17 00:00:00 2001
    From: Arjun Salariya <arjun.salariya@einfochips.com>
    Date: Tue, 14 Jul 2020 19:21:08 +0530
    Subject: [PATCH 2/5] wcn36xx: Fix software-driven scan

    For software-driven scan, rely on mac80211 software scan instead
    of internal driver implementation. The internal implementation
    cause connection trouble since it keep the antenna busy during
    the entire scan duration, moreover it's only a passive scanning
    (no probe request). Therefore, let mac80211 manages sw scan.

    Note: we fallback to software scan if firmware does not report
    scan offload support or if we need to scan the 5Ghz band (currently
    not supported by the offload scan...).
    ---
     drivers/net/wireless/ath/wcn36xx/main.c    | 165 ++++++++++++++++-------------
     drivers/net/wireless/ath/wcn36xx/smd.c     |  23 +++-
     drivers/net/wireless/ath/wcn36xx/smd.h     |   8 +-
     drivers/net/wireless/ath/wcn36xx/txrx.c    |  11 +-
     drivers/net/wireless/ath/wcn36xx/wcn36xx.h |   7 +-
     5 files changed, 126 insertions(+), 88 deletions(-)

    diff --git a/drivers/net/wireless/ath/wcn36xx/main.c b/drivers/net/wireless/ath/wcn36xx/main.c
    index 5761638..a7e1052 100644
    --- a/drivers/net/wireless/ath/wcn36xx/main.c
    +++ b/drivers/net/wireless/ath/wcn36xx/main.c
    @@ -365,12 +365,37 @@ static void wcn36xx_stop(struct ieee80211_hw *hw)
            kfree(wcn->hal_buf);
     }

    -static int wcn36xx_config(struct ieee80211_hw *hw, u32 changed)
    +static void wcn36xx_change_ps(struct wcn36xx *wcn, bool enable)
    +{
    +       struct ieee80211_vif *vif = NULL;
    +       struct wcn36xx_vif *tmp;
    + 
    +       list_for_each_entry(tmp, &wcn->vif_list, list) {
    +               vif = wcn36xx_priv_to_vif(tmp);
    +               if (enable && !wcn->sw_scan) {
    +                       if (vif->bss_conf.ps) /* ps allowed ? */
    +                               wcn36xx_pmc_enter_bmps_state(wcn, vif);
    +               } else {
    +                       wcn36xx_pmc_exit_bmps_state(wcn, vif);
    +               }
    +       }
    +}
    +
    +static void wcn36xx_change_opchannel(struct wcn36xx *wcn, int ch)
     {
    -       struct wcn36xx *wcn = hw->priv;
            struct ieee80211_vif *vif = NULL;
            struct wcn36xx_vif *tmp;

    +       list_for_each_entry(tmp, &wcn->vif_list, list) {
    +               vif = wcn36xx_priv_to_vif(tmp);
    +               wcn36xx_smd_switch_channel(wcn, vif, ch);
    +       }
    +}
    +
    +static int wcn36xx_config(struct ieee80211_hw *hw, u32 changed)
    +{
    +       struct wcn36xx *wcn = hw->priv;
    +
            wcn36xx_dbg(WCN36XX_DBG_MAC, "mac config changed 0x%08x\n", changed);

            mutex_lock(&wcn->conf_mutex);
    @@ -379,23 +404,27 @@ static int wcn36xx_config(struct ieee80211_hw *hw, u32 changed)
                    int ch = WCN36XX_HW_CHANNEL(wcn);
                    wcn36xx_dbg(WCN36XX_DBG_MAC, "wcn36xx_config channel switch=%d\n",
                                ch);
    -               list_for_each_entry(tmp, &wcn->vif_list, list) {
    -                       vif = wcn36xx_priv_to_vif(tmp);
    -                       wcn36xx_smd_switch_channel(wcn, vif, ch);
    +               if (wcn->sw_scan_opchannel == ch) {
    +                       /* If channel is the initial operating channel, we may
    +                        * want to receive/transmit regular data packets, then
    +                        * simply stop the scan session and exit PS mode.
    +                        */
    +                       wcn36xx_smd_finish_scan(wcn, HAL_SYS_MODE_SCAN,
    +                                               wcn->sw_scan_vif, ch);
    +               } else if (wcn->sw_scan) {
    +                       /* A scan is ongoing, do not change the operating
    +                        * channel, but start a scan session on the channel.
    +                        */
    +                       wcn36xx_smd_init_scan(wcn, HAL_SYS_MODE_SCAN,
    +                                             wcn->sw_scan_vif);
    +                       wcn36xx_smd_start_scan(wcn, ch);
    +               } else {
    +                       wcn36xx_change_opchannel(wcn, ch);
                    }
            }

    -       if (changed & IEEE80211_CONF_CHANGE_PS) {
    -               list_for_each_entry(tmp, &wcn->vif_list, list) {
    -                       vif = wcn36xx_priv_to_vif(tmp);
    -                       if (hw->conf.flags & IEEE80211_CONF_PS) {
    -                               if (vif->bss_conf.ps) /* ps allowed ? */
    -                                       wcn36xx_pmc_enter_bmps_state(wcn, vif);
    -                       } else {
    -                               wcn36xx_pmc_exit_bmps_state(wcn, vif);
    -                       }
    -               }
    -       }
    +       if (changed & IEEE80211_CONF_CHANGE_PS)
    +               wcn36xx_change_ps(wcn, hw->conf.flags & IEEE80211_CONF_PS);
     
            mutex_unlock(&wcn->conf_mutex);

    @@ -600,57 +629,30 @@ static int wcn36xx_set_key(struct ieee80211_hw *hw, enum set_key_cmd cmd,
            return ret;
     }
     
    -static void wcn36xx_hw_scan_worker(struct work_struct *work)
    -{
    -       struct wcn36xx *wcn = container_of(work, struct wcn36xx, scan_work);
    -       struct cfg80211_scan_request *req = wcn->scan_req;
    -       u8 channels[WCN36XX_HAL_PNO_MAX_NETW_CHANNELS_EX];
    -       struct cfg80211_scan_info scan_info = {};
    -       bool aborted = false;
    -       int i;
    -
    -       wcn36xx_dbg(WCN36XX_DBG_MAC, "mac80211 scan %d channels worker\n", req->n_channels);
    -
    -       for (i = 0; i < req->n_channels; i++)
    -               channels[i] = req->channels[i]->hw_value;
    -
    -       wcn36xx_smd_update_scan_params(wcn, channels, req->n_channels);
    -
    -       wcn36xx_smd_init_scan(wcn, HAL_SYS_MODE_SCAN);
    -       for (i = 0; i < req->n_channels; i++) {
    -               mutex_lock(&wcn->scan_lock);
    -               aborted = wcn->scan_aborted;
    -               mutex_unlock(&wcn->scan_lock);
    -
    -               if (aborted)
    -                       break;
    -
    -               wcn->scan_freq = req->channels[i]->center_freq;
    -               wcn->scan_band = req->channels[i]->band;
    -
    -               wcn36xx_smd_start_scan(wcn, req->channels[i]->hw_value);
    -               msleep(30);
    -               wcn36xx_smd_end_scan(wcn, req->channels[i]->hw_value);
    -
    -               wcn->scan_freq = 0;
-       }
-       wcn36xx_smd_finish_scan(wcn, HAL_SYS_MODE_SCAN);
-
-       scan_info.aborted = aborted;
-       ieee80211_scan_completed(wcn->hw, &scan_info);
-
-       mutex_lock(&wcn->scan_lock);
-       wcn->scan_req = NULL;
-       mutex_unlock(&wcn->scan_lock);
-}
-
 static int wcn36xx_hw_scan(struct ieee80211_hw *hw,
                           struct ieee80211_vif *vif,
                           struct ieee80211_scan_request *hw_req)
 {
        struct wcn36xx *wcn = hw->priv;
+       int i;
+
+       if (!get_feat_caps(wcn->fw_feat_caps, SCAN_OFFLOAD)) {
+               wcn36xx_dbg(WCN36XX_DBG_SCAN, "%s fallback SW scan\n", __func__);
+               /* fallback to mac80211 software scan */
+               return 1;
+       }
+
+       /* For unknown reason, the hardware offloaded scan only works with
+        * 2.4Ghz channels, fallback to software scan in other cases.
+        */
+       for (i = 0; i < hw_req->req.n_channels; i++) {
+               if (hw_req->req.channels[i]->band != NL80211_BAND_2GHZ)
+                       return 1;
+       }
+ 
        mutex_lock(&wcn->scan_lock);
        if (wcn->scan_req) {
+               wcn36xx_dbg(WCN36XX_DBG_SCAN, "%s scan already in progress\n", __func__);
                mutex_unlock(&wcn->scan_lock);
                return -EBUSY;
        }
@@ -660,12 +662,6 @@ static int wcn36xx_hw_scan(struct ieee80211_hw *hw,

        mutex_unlock(&wcn->scan_lock);

-       if (get_feat_caps(wcn->fw_feat_caps, SCAN_OFFLOAD)) {
-               /* legacy manual/sw scan */
-               schedule_work(&wcn->scan_work);
-               return 0;
-       }
-
        return wcn36xx_smd_start_hw_scan(wcn, vif, &hw_req->req);
 }

@@ -674,17 +670,44 @@ static void wcn36xx_cancel_hw_scan(struct ieee80211_hw *hw,
 {
        struct wcn36xx *wcn = hw->priv;

-       if (!wcn36xx_smd_stop_hw_scan(wcn)) {
+       /*if (!wcn36xx_smd_stop_hw_scan(wcn)) {
                struct cfg80211_scan_info scan_info = { .aborted = true };

                ieee80211_scan_completed(wcn->hw, &scan_info);
-       }
+       }*/

        mutex_lock(&wcn->scan_lock);
        wcn->scan_aborted = true;
        mutex_unlock(&wcn->scan_lock);

-       cancel_work_sync(&wcn->scan_work);
+       if (get_feat_caps(wcn->fw_feat_caps, SCAN_OFFLOAD)) {
+               /* ieee80211_scan_completed will be called on FW scan
+                * indication */
+               wcn36xx_smd_stop_hw_scan(wcn);
+       }
+}
+
+static void wcn36xx_sw_scan_start(struct ieee80211_hw *hw,
+                                 struct ieee80211_vif *vif,
+                                 const u8 *mac_addr)
+{
+       struct wcn36xx *wcn = hw->priv;
+
+       wcn->sw_scan = true;
+       wcn->sw_scan_vif = vif;
+       wcn->sw_scan_opchannel = WCN36XX_HW_CHANNEL(wcn);
+}
+
+static void wcn36xx_sw_scan_complete(struct ieee80211_hw *hw,
+                                    struct ieee80211_vif *vif)
+{
+       struct wcn36xx *wcn = hw->priv;
+
+       /* ensure that any scan session is finished */
+       wcn36xx_smd_finish_scan(wcn, HAL_SYS_MODE_SCAN, wcn->sw_scan_vif,
+                               wcn->sw_scan_opchannel);
+       wcn->sw_scan = false;
+       wcn->sw_scan_opchannel = 0;
 }

 static void wcn36xx_update_allowed_rates(struct ieee80211_sta *sta,
@@ -1127,6 +1150,8 @@ static const struct ieee80211_ops wcn36xx_ops = {
        .set_key                = wcn36xx_set_key,
        .hw_scan                = wcn36xx_hw_scan,
        .cancel_hw_scan         = wcn36xx_cancel_hw_scan,
+       .sw_scan_start          = wcn36xx_sw_scan_start,
+       .sw_scan_complete       = wcn36xx_sw_scan_complete,
        .bss_info_changed       = wcn36xx_bss_info_changed,
        .set_rts_threshold      = wcn36xx_set_rts_threshold,
        .sta_add                = wcn36xx_sta_add,
@@ -1301,8 +1326,6 @@ static int wcn36xx_probe(struct platform_device *pdev)
        mutex_init(&wcn->hal_mutex);
        mutex_init(&wcn->scan_lock);

-       INIT_WORK(&wcn->scan_work, wcn36xx_hw_scan_worker);
-
        wcn->smd_channel = qcom_wcnss_open_channel(wcnss, "WLAN_CTRL", wcn36xx_smd_rsp_process, hw);
        if (IS_ERR(wcn->smd_channel)) {
                wcn36xx_err("failed to open WLAN_CTRL channel\n");
diff --git a/drivers/net/wireless/ath/wcn36xx/smd.c b/drivers/net/wireless/ath/wcn36xx/smd.c
index 175e0cf..c4f776a 100644
--- a/drivers/net/wireless/ath/wcn36xx/smd.c
+++ b/drivers/net/wireless/ath/wcn36xx/smd.c
@@ -495,8 +495,10 @@ int wcn36xx_smd_stop(struct wcn36xx *wcn)
        return ret;
 }

-int wcn36xx_smd_init_scan(struct wcn36xx *wcn, enum wcn36xx_hal_sys_mode mode)
+int wcn36xx_smd_init_scan(struct wcn36xx *wcn, enum wcn36xx_hal_sys_mode mode,
+                         struct ieee80211_vif *vif)
 {
+       struct wcn36xx_vif *vif_priv = wcn36xx_vif_to_priv(vif);
        struct wcn36xx_hal_init_scan_req_msg msg_body;
        int ret = 0;

@@ -504,6 +506,13 @@ int wcn36xx_smd_init_scan(struct wcn36xx *wcn, enum wcn36xx_hal_sys_mode mode)
        INIT_HAL_MSG(msg_body, WCN36XX_HAL_INIT_SCAN_REQ);

        msg_body.mode = mode;
+       if (vif_priv->bss_index != WCN36XX_HAL_BSS_INVALID_IDX) {
+               /* Notify BSSID with null DATA packet */
+               msg_body.frame_type = 2;
+               msg_body.notify = 1;
+               msg_body.scan_entry.bss_index[0] = vif_priv->bss_index;
+               msg_body.scan_entry.active_bss_count = 1;
+       }

        PREPARE_HAL_BUF(wcn->hal_buf, msg_body);

@@ -585,8 +594,10 @@ int wcn36xx_smd_end_scan(struct wcn36xx *wcn, u8 scan_channel)
 }

 int wcn36xx_smd_finish_scan(struct wcn36xx *wcn,
-                           enum wcn36xx_hal_sys_mode mode)
+                           enum wcn36xx_hal_sys_mode mode,
+                           struct ieee80211_vif *vif, u8 channel)
 {
+       struct wcn36xx_vif *vif_priv = wcn36xx_vif_to_priv(vif);
        struct wcn36xx_hal_finish_scan_req_msg msg_body;
        int ret = 0;

@@ -594,6 +605,14 @@ int wcn36xx_smd_finish_scan(struct wcn36xx *wcn,
        INIT_HAL_MSG(msg_body, WCN36XX_HAL_FINISH_SCAN_REQ);

        msg_body.mode = mode;
+       if (vif_priv->bss_index != WCN36XX_HAL_BSS_INVALID_IDX) {
+               /* Notify BSSID with null data packet */
+               msg_body.notify = 1;
+               msg_body.frame_type = 2;
+               msg_body.oper_channel = channel;
+               msg_body.scan_entry.bss_index[0] = vif_priv->bss_index;
+               msg_body.scan_entry.active_bss_count = 1;
+       }

        PREPARE_HAL_BUF(wcn->hal_buf, msg_body);

diff --git a/drivers/net/wireless/ath/wcn36xx/smd.h b/drivers/net/wireless/ath/wcn36xx/smd.h
index ddf656b..4a2a2dd 100644
--- a/drivers/net/wireless/ath/wcn36xx/smd.h
+++ b/drivers/net/wireless/ath/wcn36xx/smd.h
@@ -59,11 +59,13 @@ void wcn36xx_smd_close(struct wcn36xx *wcn);
 int wcn36xx_smd_load_nv(struct wcn36xx *wcn);
 int wcn36xx_smd_start(struct wcn36xx *wcn);
 int wcn36xx_smd_stop(struct wcn36xx *wcn);
-int wcn36xx_smd_init_scan(struct wcn36xx *wcn, enum wcn36xx_hal_sys_mode mode);
 int wcn36xx_smd_start_scan(struct wcn36xx *wcn, u8 scan_channel);
 int wcn36xx_smd_end_scan(struct wcn36xx *wcn, u8 scan_channel);
-int wcn36xx_smd_finish_scan(struct wcn36xx *wcn,
-                           enum wcn36xx_hal_sys_mode mode);
+int wcn36xx_smd_finish_scan(struct wcn36xx *wcn, enum wcn36xx_hal_sys_mode mode,
+                           struct ieee80211_vif *vif, u8 channel);
+int wcn36xx_smd_init_scan(struct wcn36xx *wcn, enum wcn36xx_hal_sys_mode mode,
+                         struct ieee80211_vif *vif);
+
 int wcn36xx_smd_update_scan_params(struct wcn36xx *wcn, u8 *channels, size_t channel_count);
 int wcn36xx_smd_start_hw_scan(struct wcn36xx *wcn, struct ieee80211_vif *vif,
                              struct cfg80211_scan_request *req);
diff --git a/drivers/net/wireless/ath/wcn36xx/txrx.c b/drivers/net/wireless/ath/wcn36xx/txrx.c
index b1768ed..1e3abfd 100644
--- a/drivers/net/wireless/ath/wcn36xx/txrx.c
+++ b/drivers/net/wireless/ath/wcn36xx/txrx.c
@@ -49,15 +49,8 @@ int wcn36xx_rx_skb(struct wcn36xx *wcn, struct sk_buff *skb)
        fc = __le16_to_cpu(hdr->frame_control);
        sn = IEEE80211_SEQ_TO_SN(__le16_to_cpu(hdr->seq_ctrl));

-       /* When scanning associate beacons to this */
-       if (ieee80211_is_beacon(hdr->frame_control) && wcn->scan_freq) {
-               status.freq = wcn->scan_freq;
-               status.band = wcn->scan_band;
-       } else {
-               status.freq = WCN36XX_CENTER_FREQ(wcn);
-               status.band = WCN36XX_BAND(wcn);
-       }
-
+       status.freq = WCN36XX_CENTER_FREQ(wcn);
+       status.band = WCN36XX_BAND(wcn);
        status.mactime = 10;
        status.signal = -get_rssi0(bd);
        status.antenna = 1;
diff --git a/drivers/net/wireless/ath/wcn36xx/wcn36xx.h b/drivers/net/wireless/ath/wcn36xx/wcn36xx.h
index 4c888a6..734af2e 100644
--- a/drivers/net/wireless/ath/wcn36xx/wcn36xx.h
+++ b/drivers/net/wireless/ath/wcn36xx/wcn36xx.h
@@ -56,6 +56,7 @@ enum wcn36xx_debug_mask {
        WCN36XX_DBG_BEACON_DUMP = 0x00001000,
        WCN36XX_DBG_PMC         = 0x00002000,
        WCN36XX_DBG_PMC_DUMP    = 0x00004000,
+       WCN36XX_DBG_SCAN        = 0x00020000,
        WCN36XX_DBG_ANY         = 0xffffffff,
 };

@@ -224,10 +225,10 @@ struct wcn36xx {
        spinlock_t              hal_ind_lock;
        struct list_head        hal_ind_queue;

-       struct work_struct      scan_work;
        struct cfg80211_scan_request *scan_req;
-       int                     scan_freq;
-       int                     scan_band;
+       bool                    sw_scan;
+       u8                      sw_scan_opchannel;
+       struct ieee80211_vif    *sw_scan_vif;
        struct mutex            scan_lock;
        bool                    scan_aborted;

-- 
2.7.4

After we have applied this patch, we are not able to scan any 2.4/5 Ghz channels on our custom board.

Can you please suggest what is missing here or what are the other dependent patches we can add here?

Regards,
Parth Y Shah

Have you tried with Linux kernel 5.7?

Hi @Loic,

Yes, we have tried the same Hidden SSID issue with latest 5.7 kernel and below are the observations:

  1. 5G Hidden SSID - Able to connect 1/2 times after bootup. Then not able to connect. If we do ifconfig down/up, then also not able to connect.

  2. 2.4G Hidden SSID - Able to connect most of the times but sometimes we have also seen that after few attempts it also not able to connect. Compared to 5GHz, 2.4GHz has better performance in the hidden SSID case.

Regards,
Parth Y Shah

Hi @Loic

Any update here?

Regards,
Parth Y Shah

Do you perform scanning while connecting?
I can not really comment or test 5Ghz since it’s not supported on 410c, but 5Ghz can be subject to passive scanning depending country code.

Hi @Loic

We use wpa_supplicant to connect hidden SSID and follow below commands.

#wpa_cli
>add_network
0
> set_network 0 ssid “MYSSID”
> set_network 0 psk “passphrase”
> set_network 0 scan_ssid 1
> enable_network 0

By following this method, we can connect to hidden SSID 5G for 1/2 times only. After that we are not able to connect to the same hidden 5G SSID.

To disconnect the connected SSID, we use “disable_network 0” command.

Do you mean here like country code needs to be checked or changed in the NV file?

Regards,
Parth Y Shah

Could you please:

  • share output of iw phy0 info

  • Enable debugging:

    echo 0x400 > /sys/module/wcn36xx/parameters/debug_mask
    dmesg -n 8

  • Sniff for probe request/response on which the AP is

  • Try to connect/disconnect

On my side I do not observe any issue with software scanning on 2.4ghz APs.

@Loic,

We have check the sniffer with Linaro18_01 with support the SCAN_OFFLOAD support and see the probe request/response. Quick connect 2.4G Hidden SSID [In Active Scan, STA broadcasts Probe Request and receives Probe Response from APs]

And check with Linaro20 latest release , Not seen the probe req/res in the sniffer. Scan Mode look like as Passive scan.Not able to connect 2.4G quickly. After long time, continues scan run suddenly connect with AP. [Passive Scan receives Beacon frame from APs]

**iw phy0 info**
Wiphy phy0
        max # scan SSIDs: 9
        max scan IEs length: 453 bytes
        max # sched scan SSIDs: 0
        max # match sets: 0
        max # scan plans: 1
        max scan plan interval: -1
        max scan plan iterations: 0
        Retry short limit: 7
        Retry long limit: 4
        Coverage class: 0 (up to 0m)
        Supported Ciphers:
                * WEP40 (00-0f-ac:1)
                * WEP104 (00-0f-ac:5)
                * TKIP (00-0f-ac:2)
                * CCMP-128 (00-0f-ac:4)
        Available Antennas: TX 0 RX 0
        Supported interface modes:
                 * IBSS
                 * managed
                 * AP
                 * AP/VLAN
                 * monitor
        Band 1:
                Capabilities: 0x903c
                        HT20
                        SM Power Save disabled
                        RX Greenfield
                        RX HT20 SGI
                        No RX STBC
                        Max AMSDU length: 3839 bytes
                        DSSS/CCK HT40
                        L-SIG TXOP protection
                Maximum RX AMPDU length 65535 bytes (exponent: 0x003)
                Minimum RX AMPDU time spacing: 16 usec (0x07)
                HT Max RX data rate: 72 Mbps
                HT TX/RX MCS rate indexes supported: 0-7
                Bitrates (non-HT):
                        * 1.0 Mbps
                        * 2.0 Mbps (short preamble supported)
                        * 5.5 Mbps (short preamble supported)
                        * 11.0 Mbps (short preamble supported)
                        * 6.0 Mbps
                        * 9.0 Mbps
                        * 12.0 Mbps
                        * 18.0 Mbps
                        * 24.0 Mbps
                        * 36.0 Mbps
                        * 48.0 Mbps
                        * 54.0 Mbps
                Frequencies:
                        * 2412 MHz [1] (20.0 dBm)
                        * 2417 MHz [2] (20.0 dBm)
                        * 2422 MHz [3] (20.0 dBm)
                        * 2427 MHz [4] (20.0 dBm)
                        * 2432 MHz [5] (20.0 dBm)
                        * 2437 MHz [6] (20.0 dBm)
                        * 2442 MHz [7] (20.0 dBm)
                        * 2447 MHz [8] (20.0 dBm)
                        * 2452 MHz [9] (20.0 dBm)
                        * 2457 MHz [10] (20.0 dBm)
                        * 2462 MHz [11] (20.0 dBm)
                        * 2467 MHz [12] (20.0 dBm) (no IR)
                        * 2472 MHz [13] (20.0 dBm) (no IR)
                        * 2484 MHz [14] (20.0 dBm) (no IR)
        Band 2:
                Capabilities: 0x907e
                        HT20/HT40
                        SM Power Save disabled
                        RX Greenfield
                        RX HT20 SGI
                        RX HT40 SGI
                        No RX STBC
                        Max AMSDU length: 3839 bytes
                        DSSS/CCK HT40
                        L-SIG TXOP protection
                Maximum RX AMPDU length 65535 bytes (exponent: 0x003)
                Minimum RX AMPDU time spacing: 16 usec (0x07)
                HT Max RX data rate: 72 Mbps
                HT TX/RX MCS rate indexes supported: 0-7
                Bitrates (non-HT):
                        * 6.0 Mbps
                        * 9.0 Mbps
                        * 12.0 Mbps
                        * 18.0 Mbps
                        * 24.0 Mbps
                        * 36.0 Mbps
                        * 48.0 Mbps
                        * 54.0 Mbps
                Frequencies:
                        * 5180 MHz [36] (20.0 dBm)
                        * 5200 MHz [40] (20.0 dBm) (no IR)
                        * 5220 MHz [44] (20.0 dBm)
                        * 5240 MHz [48] (20.0 dBm) (no IR)
                        * 5260 MHz [52] (20.0 dBm) (no IR, radar detection)
                        * 5280 MHz [56] (20.0 dBm) (no IR, radar detection)
                        * 5300 MHz [60] (20.0 dBm) (no IR, radar detection)
                        * 5320 MHz [64] (20.0 dBm) (no IR, radar detection)
                        * 5500 MHz [100] (20.0 dBm) (no IR, radar detection)
                        * 5520 MHz [104] (20.0 dBm) (no IR, radar detection)
                        * 5540 MHz [108] (20.0 dBm) (no IR, radar detection)
                        * 5560 MHz [112] (20.0 dBm) (no IR, radar detection)
                        * 5580 MHz [116] (20.0 dBm) (no IR, radar detection)
                        * 5600 MHz [120] (20.0 dBm) (no IR, radar detection)
                        * 5620 MHz [124] (20.0 dBm) (no IR, radar detection)
                        * 5640 MHz [128] (20.0 dBm) (no IR, radar detection)
                        * 5660 MHz [132] (20.0 dBm) (no IR, radar detection)
                        * 5700 MHz [140] (20.0 dBm) (no IR, radar detection)
                        * 5745 MHz [149] (20.0 dBm) (no IR)
                        * 5765 MHz [153] (20.0 dBm) (no IR)
                        * 5785 MHz [157] (20.0 dBm) (no IR)
                        * 5805 MHz [161] (20.0 dBm) (no IR)
                        * 5825 MHz [165] (20.0 dBm) (no IR)
        Supported commands:
                 * new_interface
                 * set_interface
                 * new_key
                 * start_ap
                 * new_station
                 * set_bss
                 * authenticate
                 * associate
                 * deauthenticate
                 * disassociate
                 * join_ibss
                 * remain_on_channel
                 * set_tx_bitrate_mask
                 * frame
                 * frame_wait_cancel
                 * set_wiphy_netns
                 * set_channel
                 * set_wds_peer
                 * probe_client
                 * set_noack_map
                 * register_beacons
                 * start_p2p_device
                 * set_mcast_rate
                 * connect
                 * disconnect
                 * set_qos_map
                 * set_multicast_to_unicast
        Supported TX frame types:
                 * IBSS: 0x00 0x10 0x20 0x30 0x40 0x50 0x60 0x70 0x80 0x90 0xa0 0xb0 0xc0 0xd0 0xe0 0xf0
                 * managed: 0x00 0x10 0x20 0x30 0x40 0x50 0x60 0x70 0x80 0x90 0xa0 0xb0 0xc0 0xd0 0xe0 0xf0
                 * AP: 0x00 0x10 0x20 0x30 0x40 0x50 0x60 0x70 0x80 0x90 0xa0 0xb0 0xc0 0xd0 0xe0 0xf0
                 * AP/VLAN: 0x00 0x10 0x20 0x30 0x40 0x50 0x60 0x70 0x80 0x90 0xa0 0xb0 0xc0 0xd0 0xe0 0xf0
                 * mesh point: 0x00 0x10 0x20 0x30 0x40 0x50 0x60 0x70 0x80 0x90 0xa0 0xb0 0xc0 0xd0 0xe0 0xf0
                 * P2P-client: 0x00 0x10 0x20 0x30 0x40 0x50 0x60 0x70 0x80 0x90 0xa0 0xb0 0xc0 0xd0 0xe0 0xf0
                 * P2P-GO: 0x00 0x10 0x20 0x30 0x40 0x50 0x60 0x70 0x80 0x90 0xa0 0xb0 0xc0 0xd0 0xe0 0xf0
                 * P2P-device: 0x00 0x10 0x20 0x30 0x40 0x50 0x60 0x70 0x80 0x90 0xa0 0xb0 0xc0 0xd0 0xe0 0xf0
        Supported RX frame types:
                 * IBSS: 0x40 0xb0 0xc0 0xd0
                 * managed: 0x40 0xb0 0xd0
                 * AP: 0x00 0x20 0x40 0xa0 0xb0 0xc0 0xd0
                 * AP/VLAN: 0x00 0x20 0x40 0xa0 0xb0 0xc0 0xd0
                 * mesh point: 0xb0 0xc0 0xd0
                 * P2P-client: 0x40 0xd0
                 * P2P-GO: 0x00 0x20 0x40 0xa0 0xb0 0xc0 0xd0
                 * P2P-device: 0x40 0xd0
        WoWLAN support:
                 * wake up on anything (device continues operating normally)
        software interface modes (can always be added):
                 * AP/VLAN
                 * monitor
        interface combinations are not supported
        HT Capability overrides:
                 * MCS: ff ff ff ff ff ff ff ff ff ff
                 * maximum A-MSDU length
                 * supported channel width
                 * short GI for 40 MHz
                 * max A-MPDU length exponent
                 * min MPDU start spacing
        Device supports TX status socket option.
        Device supports HT-IBSS.
        Device supports SAE with AUTHENTICATE command
        Device supports scan flush.
        Device supports per-vif TX power setting
        Driver supports full state transitions for AP/GO clients
        Driver supports a userspace MPM
        Device supports configuring vdev MAC-addr on create.
        Supported extended features:
                * [ RRM ]: RRM
                * [ FILS_STA ]: STA FILS (Fast Initial Link Setup)
                * [ CQM_RSSI_LIST ]: multiple CQM_RSSI_THOLD records
                * [ CONTROL_PORT_OVER_NL80211 ]: control port over nl80211
root@linaro-developer:~#

Do you have comments here @Loic ?

Do you have dmesg ouput with debugging enabled? on which channel is the AP you want to connect to?

Hi @Loic

Dmesg logs are uploaded at below link:
https://arrowelectronics-my.sharepoint.com/:f:/r/personal/parth_y_shah_einfochips_com/Documents/Attachments/issue-5-hidden-ssid-dmesg-logs?csf=1&web=1&e=4OX3nD
2.4 GHZ hidden SSID fail case
5 GHz hidden SSID fail case
2.4 GHZ open SSID pass case

Channels on which we are trying to connect: 2.4GHz - #6, 5GHz - #40

In your log I see

WARNING: CPU: 0 PID: 0 at net/mac80211/rx.c:4663 ieee80211_rx_napi

Does it always precede the connection issue?

Maybe try this patch (at least to fix the warning): loic.poulain/linux.git - [no description]

We are still facing the same WARNING after applying the suggested patch.

It comes randomly. Currently seen while doing iperf transfers on 2.4 GHz channel.

@darshak, you should try [PATCH] wcn36xx: Set sw-scan chan to 0 when not associated (Linux Wireless)

1 Like

This patch is working fine, able to connect with 2.4G and 5G Hidden SSID.

Appreciated for your support.

-Darshak

Hi @Loic,

We have a scenario here.

We use Linaro 18.01 as we have been developing this product since last 1.5 years and so any issue resolved in 20.02, we need to backport it to 18.01.

When we applied the fix to 18.01 from 20.02, we ended up in a scenario that the scan stopped working.

May we know from your perspective, if we have to backport from 20.02 to 18.01, to resolve the hidden SSID case, what would be that patch that we need to pick.

We look for your humble response here as we are looking at this as a humungous task to backport it to 18.01.

Regards,
Darshak

Hi @Loic,

WiFi scan is now working after backporting (related to wcn36xx) in Linaro-18.01. I can see the scan list with “nmcli dev wifi list”.

I have done change in the mac80211 “net/mac80211/scan.c” to enable the scan.

@@ -680,6 +684,19 @@ static int __ieee80211_start_scan(struct ieee80211_sub_if_data *sdata,
 		RCU_INIT_POINTER(local->scan_sdata, NULL);
 	}
 
+	if (hw_scan && rc == 1) {
+		/*
+		 * we can't fall back to software for P2P-GO
+		 * as it must update NoA etc.
+		 */
+		if (ieee80211_vif_type_p2p(&sdata->vif) ==
+				NL80211_IFTYPE_P2P_GO)
+			return -EOPNOTSUPP;
+		hw_scan = false;
+		goto again;
+	}
+

But I am facing auth timed out error continuously after the scan worked and not able to connect to any of the network.

root@linaro-alip:~# nmcli dev wifi con "ASUS_B8_2G" password "12345678"
[ 9033.455109] wcn36xx_hw_scan: start
[ 9033.455129] __ieee80211_start_scan:HW_SCAN start
[ 9033.457390] __ieee80211_start_scan: Go to again ADDED......
[ 9033.462211] wcn36xx_sw_scan_start: start
[ 9036.908384] wlan0: authenticate with 04:d9:f5:c2:de:b8
[ 9036.947967] wlan0: send auth to 04:d9:f5:c2:de:b8 (try 1/3)
[ 9037.795121] wlan0: send auth to 04:d9:f5:c2:de:b8 (try 2/3)
[ 9038.787276] wlan0: send auth to 04:d9:f5:c2:de:b8 (try 3/3)
[ 9039.806328] wlan0: authentication with 04:d9:f5:c2:de:b8 timed out
[ 9049.843389] wcn36xx_hw_scan: start
[ 9049.843413] __ieee80211_start_scan:HW_SCAN start
[ 9049.845750] __ieee80211_start_scan: Go to again ADDED......
[ 9049.850549] wcn36xx_sw_scan_start: start
[ 9053.305357] wlan0: authenticate with 04:d9:f5:c2:de:b8
[ 9053.344814] wlan0: send auth to 04:d9:f5:c2:de:b8 (try 1/3)
[ 9054.818997] wlan0: send auth to 04:d9:f5:c2:de:b8 (try 2/3)
[ 9055.810994] wlan0: send auth to 04:d9:f5:c2:de:b8 (try 3/3)
[ 9056.802906] wlan0: authentication with 04:d9:f5:c2:de:b8 timed out

Can you please suggest any mac80211/wcn36xx related change that can help here?

Regards,
Parth Y Shah

Any update, @loic?

Regards,
Parth Y Shah