[NEUS7920-133][9610] wlbt: Unset channel is sent at work expiry of 600ms delay
authorKavitha Velayutham <k.velayutham@samsung.com>
Thu, 14 Feb 2019 06:06:28 +0000 (11:36 +0530)
committerYoungmin Nam <youngmin.nam@samsung.com>
Tue, 21 May 2019 10:45:21 +0000 (19:45 +0900)
This may increase the time duration of listen by 600ms in that channel which would help in p2p discovery
to find the devices faster.

Change-Id: I8b16e32aa25e6b406bc48f0cf842df2495c15a50
SCSC-Bug-Id: SSB-49471
Signed-off-by: Kavitha Velayutham <k.velayutham@samsung.com>
drivers/net/wireless/scsc/cfg80211_ops.c
drivers/net/wireless/scsc/dev.h
drivers/net/wireless/scsc/mgt.c
drivers/net/wireless/scsc/mgt.h

index 1704f7b99d9f9af07e8c3887fd787eb0c9a97b5d..cab34ef00256ab9ca7c5817abe73060b489a11c0 100755 (executable)
@@ -486,11 +486,13 @@ int slsi_scan(struct wiphy *wiphy, struct net_device *dev,
                channels[i] = request->channels[i];
        chan_count = request->n_channels;
 
-       if (SLSI_IS_VIF_INDEX_WLAN(ndev_vif))
+       if (SLSI_IS_VIF_INDEX_WLAN(ndev_vif)) {
                if (sdev->initial_scan) {
                        sdev->initial_scan = false;
                        scan_type = FAPI_SCANTYPE_INITIAL_SCAN;
                }
+               ndev_vif->unsync.slsi_p2p_continuous_fullscan = false;
+       }
 
        /* Update scan timing for P2P social channels scan. */
        if ((request->ie) &&
@@ -500,11 +502,35 @@ int slsi_scan(struct wiphy *wiphy, struct net_device *dev,
                 * with GO's operating channel comes on P2P device. Hence added the
                 * check for n_channels as 1
                 */
+               if (!ndev_vif->drv_in_p2p_procedure) {
+                       if (delayed_work_pending(&ndev_vif->unsync.unset_channel_expiry_work)) {
+                               cancel_delayed_work(&ndev_vif->unsync.unset_channel_expiry_work);
+                               slsi_mlme_spare_signal_1(sdev, dev);
+                               ndev_vif->driver_channel = 0;
+                               }
+               }
                if (request->n_channels == SLSI_P2P_SOCIAL_CHAN_COUNT || request->n_channels == 1) {
                        p2p_state = P2P_SCANNING;
                        scan_type = FAPI_SCANTYPE_P2P_SCAN_SOCIAL;
+                       ndev_vif->unsync.slsi_p2p_continuous_fullscan = false;
                } else if (request->n_channels > SLSI_P2P_SOCIAL_CHAN_COUNT) {
-                       scan_type = FAPI_SCANTYPE_P2P_SCAN_FULL;
+                       if (!ndev_vif->unsync.slsi_p2p_continuous_fullscan) {
+                               scan_type = FAPI_SCANTYPE_P2P_SCAN_FULL;
+                               ndev_vif->unsync.slsi_p2p_continuous_fullscan = true;
+                       } else {
+                               int count = 0, chann = 0;
+
+                               scan_type = FAPI_SCANTYPE_P2P_SCAN_SOCIAL;
+                               ndev_vif->unsync.slsi_p2p_continuous_fullscan = false;
+                               for (i = 0; i < request->n_channels; i++) {
+                                       chann = channels[i]->hw_value & 0xFF;
+                                       if (chann == 1 || chann == 6 || chann == 11) {
+                                               channels[count] = request->channels[i];
+                                               count++;
+                                       }
+                               }
+                               chan_count = count;
+                       }
                }
        }
 
@@ -1656,6 +1682,9 @@ int slsi_remain_on_channel(struct wiphy              *wiphy,
         */
        cancel_delayed_work(&ndev_vif->unsync.roc_expiry_work);
 
+       if (delayed_work_pending(&ndev_vif->unsync.unset_channel_expiry_work))
+               cancel_delayed_work(&ndev_vif->unsync.unset_channel_expiry_work);
+
        /* If action frame tx is in progress and ROC comes, then it would mean action frame tx was done in ROC and
         * frame tx ind is awaited, don't change state. Also allow back to back ROC in case it comes.
         */
@@ -1700,8 +1729,13 @@ int slsi_remain_on_channel(struct wiphy              *wiphy,
        SLSI_P2P_STATE_CHANGE(sdev, P2P_LISTENING);
 
 exit_with_roc:
+       /* Cancel remain on channel is sent to the supplicant 10ms before the duration
+        *This is to avoid the race condition of supplicant sending cancel remain on channel and
+        *drv sending cancel_remain on channel because of roc expiry.
+        *This race condition causes delay to the next p2p search
+        */
        queue_delayed_work(sdev->device_wq, &ndev_vif->unsync.roc_expiry_work,
-                          msecs_to_jiffies(duration + SLSI_P2P_ROC_EXTRA_MSEC));
+                          msecs_to_jiffies(duration - SLSI_P2P_ROC_EXTRA_MSEC));
 
        slsi_assign_cookie_id(cookie, &ndev_vif->unsync.roc_cookie);
        SLSI_NET_DBG2(dev, SLSI_CFG80211, "Cookie = 0x%llx\n", *cookie);
@@ -1766,23 +1800,18 @@ int slsi_cancel_remain_on_channel(struct wiphy      *wiphy,
 
        cancel_delayed_work(&ndev_vif->unsync.roc_expiry_work);
 
-       /* Supplicant has stopped FIND/LISTEN. Clear Probe Response IEs in firmware and driver */
-       if (slsi_mlme_add_info_elements(sdev, dev, FAPI_PURPOSE_PROBE_RESPONSE, NULL, 0) != 0)
-               SLSI_NET_ERR(dev, "Clearing Probe Response IEs failed for unsync vif\n");
-       slsi_unsync_vif_set_probe_rsp_ie(ndev_vif, NULL, 0);
-
 #if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 10, 9))
        cfg80211_remain_on_channel_expired(&ndev_vif->wdev, ndev_vif->unsync.roc_cookie, ndev_vif->chan, GFP_KERNEL);
 #else
        cfg80211_remain_on_channel_expired(ndev_vif->wdev.netdev, ndev_vif->unsync.roc_cookie,
                                           ndev_vif->chan, ndev_vif->channel_type, GFP_KERNEL);
 #endif
-
-       if (!ndev_vif->drv_in_p2p_procedure) {
-               slsi_mlme_spare_signal_1(sdev, dev);
-               ndev_vif->driver_channel = 0;
-       }
-
+               if (!ndev_vif->drv_in_p2p_procedure) {
+                       if (delayed_work_pending(&ndev_vif->unsync.unset_channel_expiry_work))
+                               cancel_delayed_work(&ndev_vif->unsync.unset_channel_expiry_work);
+                       queue_delayed_work(sdev->device_wq, &ndev_vif->unsync.unset_channel_expiry_work,
+                                          msecs_to_jiffies(SLSI_P2P_UNSET_CHANNEL_EXTRA_MSEC));
+               }
        /* Queue work to delete unsync vif */
        slsi_p2p_queue_unsync_vif_del_work(ndev_vif, SLSI_P2P_UNSYNC_VIF_EXTRA_MSEC);
        SLSI_P2P_STATE_CHANGE(sdev, P2P_IDLE_VIF_ACTIVE);
index a73754f19a397f574f4ba8fde8f86eccb7ee031b..f4c5e0a0abe7ccd265896c3539a8a491026176bf 100755 (executable)
@@ -551,11 +551,13 @@ struct slsi_vif_unsync {
        struct delayed_work roc_expiry_work;   /* Work on ROC duration expiry */
        struct delayed_work del_vif_work;      /* Work on unsync vif retention timeout */
        struct delayed_work hs2_del_vif_work;  /* Work on HS2 unsync vif retention timeout */
+       struct delayed_work unset_channel_expiry_work;  /*unset channel after a timer */
        u64                 roc_cookie;        /* Cookie id for ROC */
        u8                  *probe_rsp_ies;    /* Probe response IEs to be configured in firmware */
        size_t              probe_rsp_ies_len; /* Probe response IE length */
        bool                ies_changed;       /* To indicate if Probe Response IEs have changed from that previously stored */
        bool                listen_offload;    /* To indicate if Listen Offload is started */
+       bool                slsi_p2p_continuous_fullscan;
 };
 
 struct slsi_last_disconnected_sta {
index 65e5248e23d4d94d13423cd6fc01b89d2273fe19..befb8164ae2acb6b97ffd603da39d2f1a76b6946 100755 (executable)
@@ -3439,9 +3439,11 @@ static void slsi_p2p_roc_duration_expiry_work(struct work_struct *work)
                /* After sucessful frame transmission,  we will move to LISTENING or VIF ACTIVE state.
                 * Unset channel should not be sent down during p2p procedure.
                 */
-               if (ndev_vif->drv_in_p2p_procedure == 0) {
-                       slsi_mlme_spare_signal_1(ndev_vif->sdev, ndev_vif->wdev.netdev);
-                       ndev_vif->driver_channel = 0;
+               if (!ndev_vif->drv_in_p2p_procedure) {
+                       if (delayed_work_pending(&ndev_vif->unsync.unset_channel_expiry_work))
+                               cancel_delayed_work(&ndev_vif->unsync.unset_channel_expiry_work);
+                       queue_delayed_work(ndev_vif->sdev->device_wq, &ndev_vif->unsync.unset_channel_expiry_work,
+                                          msecs_to_jiffies(SLSI_P2P_UNSET_CHANNEL_EXTRA_MSEC));
                }
                slsi_p2p_queue_unsync_vif_del_work(ndev_vif, SLSI_P2P_UNSYNC_VIF_EXTRA_MSEC);
                SLSI_P2P_STATE_CHANGE(ndev_vif->sdev, P2P_IDLE_VIF_ACTIVE);
@@ -3472,6 +3474,35 @@ static void slsi_p2p_unsync_vif_delete_work(struct work_struct *work)
        SLSI_MUTEX_UNLOCK(ndev_vif->vif_mutex);
 }
 
+/**
+ * Work to be done after roc expiry or cancel remain on channel:
+ * Unset channel to be sent to Fw.
+ */
+static void slsi_p2p_unset_channel_expiry_work(struct work_struct *work)
+{
+       struct netdev_vif *ndev_vif = container_of((struct delayed_work *)work, struct netdev_vif,
+                                                  unsync.unset_channel_expiry_work);
+       struct slsi_dev           *sdev = ndev_vif->sdev;
+       struct net_device *dev = ndev_vif->wdev.netdev;
+
+       SLSI_MUTEX_LOCK(ndev_vif->vif_mutex);
+       SLSI_NET_DBG1(ndev_vif->wdev.netdev, SLSI_CFG80211, "Unset channel expiry work-Send Unset Channel\n");
+
+       if (!ndev_vif->drv_in_p2p_procedure) {
+               /* Supplicant has stopped FIND/LISTEN. Clear Probe Response IEs in firmware and driver */
+               if (slsi_mlme_add_info_elements(sdev, dev, FAPI_PURPOSE_PROBE_RESPONSE, NULL, 0) != 0)
+                       SLSI_NET_ERR(dev, "Clearing Probe Response IEs failed for unsync vif\n");
+               slsi_unsync_vif_set_probe_rsp_ie(ndev_vif, NULL, 0);
+
+               /* Send Unset Channel */
+               if (ndev_vif->driver_channel != 0) {
+                       slsi_mlme_spare_signal_1(sdev, dev);
+                       ndev_vif->driver_channel = 0;
+               }
+       }
+       SLSI_MUTEX_UNLOCK(ndev_vif->vif_mutex);
+}
+
 /* Initializations for P2P - Change vif type to unsync, create workqueue and init work */
 int slsi_p2p_init(struct slsi_dev *sdev, struct netdev_vif *ndev_vif)
 {
@@ -3480,10 +3511,12 @@ int slsi_p2p_init(struct slsi_dev *sdev, struct netdev_vif *ndev_vif)
        sdev->p2p_group_exp_frame = SLSI_P2P_PA_INVALID;
 
        ndev_vif->vif_type = FAPI_VIFTYPE_UNSYNCHRONISED;
+       ndev_vif->unsync.slsi_p2p_continuous_fullscan = false;
+
 
        INIT_DELAYED_WORK(&ndev_vif->unsync.roc_expiry_work, slsi_p2p_roc_duration_expiry_work);
        INIT_DELAYED_WORK(&ndev_vif->unsync.del_vif_work, slsi_p2p_unsync_vif_delete_work);
-
+       INIT_DELAYED_WORK(&ndev_vif->unsync.unset_channel_expiry_work, slsi_p2p_unset_channel_expiry_work);
        return 0;
 }
 
index ba0a5c7ada735728adbf63fbf190c892a5d7f1c3..694ebfcfc6d28037a1180c9eb6c0236888b71d00 100755 (executable)
@@ -94,8 +94,7 @@
 #define SLSI_P2P_ROC_EXTRA_MSEC 10
 
 /* Extra duration to retain unsync vif even after ROC/mgmt_tx completes */
-#define SLSI_P2P_UNSYNC_VIF_EXTRA_MSEC  1000
-
+#define SLSI_P2P_UNSYNC_VIF_EXTRA_MSEC  2000
 /* Extra duration to retain HS2 unsync vif even after mgmt_tx completes */
 #define SLSI_HS2_UNSYNC_VIF_EXTRA_MSEC  1000
 
  */
 #define SLSI_P2P_NEG_PROC_UNSYNC_VIF_RETAIN_DURATION 3000
 
+/* Increased wait duration to send unset channel to Fw.
+ * This would increase the listen time.
+ */
+#define SLSI_P2P_UNSET_CHANNEL_EXTRA_MSEC 600
 /* Extra duration in addition to mgmt tx wait */
 #define SLSI_P2P_MGMT_TX_EXTRA_MSEC  100