qtnfmac: implement scan timeout
authorSergey Matyukevich <sergey.matyukevich.os@quantenna.com>
Thu, 27 Jul 2017 23:06:51 +0000 (02:06 +0300)
committerKalle Valo <kvalo@codeaurora.org>
Thu, 3 Aug 2017 09:58:13 +0000 (12:58 +0300)
Userspace tools may hang on scan in the case when scan completion event
is not returned by firmware. This patch implements the scan timeout
to avoid such situation.

Signed-off-by: Igor Mitsyanko <igor.mitsyanko.os@quantenna.com>
Signed-off-by: Sergey Matyukevich <sergey.matyukevich.os@quantenna.com>
Signed-off-by: Avinash Patil <avinashp@quantenna.com>
Signed-off-by: Kalle Valo <kvalo@codeaurora.org>
drivers/net/wireless/quantenna/qtnfmac/cfg80211.c
drivers/net/wireless/quantenna/qtnfmac/cfg80211.h
drivers/net/wireless/quantenna/qtnfmac/core.c
drivers/net/wireless/quantenna/qtnfmac/core.h
drivers/net/wireless/quantenna/qtnfmac/event.c

index ac8fdc1db48228d93e24455125e736a4df1c040b..856fa6e8327ed4d6d2a3b9148c9aa3445ffb775c 100644 (file)
@@ -579,19 +579,33 @@ qtnf_del_station(struct wiphy *wiphy, struct net_device *dev,
        return ret;
 }
 
+static void qtnf_scan_timeout(unsigned long data)
+{
+       struct qtnf_wmac *mac = (struct qtnf_wmac *)data;
+
+       pr_warn("mac%d scan timed out\n", mac->macid);
+       qtnf_scan_done(mac, true);
+}
+
 static int
 qtnf_scan(struct wiphy *wiphy, struct cfg80211_scan_request *request)
 {
        struct qtnf_wmac *mac = wiphy_priv(wiphy);
-       int ret;
 
        mac->scan_req = request;
 
-       ret = qtnf_cmd_send_scan(mac);
-       if (ret)
+       if (qtnf_cmd_send_scan(mac)) {
                pr_err("MAC%u: failed to start scan\n", mac->macid);
+               mac->scan_req = NULL;
+               return -EFAULT;
+       }
 
-       return ret;
+       mac->scan_timeout.data = (unsigned long)mac;
+       mac->scan_timeout.function = qtnf_scan_timeout;
+       mod_timer(&mac->scan_timeout,
+                 jiffies + QTNF_SCAN_TIMEOUT_SEC * HZ);
+
+       return 0;
 }
 
 static int
index 5bd33124a7c84827ff8c2e36acff4e6538141669..6a4af52522b8d526e0f4cfad6dcfeb0cede83efc 100644 (file)
@@ -34,10 +34,14 @@ static inline void qtnf_scan_done(struct qtnf_wmac *mac, bool aborted)
                .aborted = aborted,
        };
 
+       mutex_lock(&mac->mac_lock);
+
        if (mac->scan_req) {
                cfg80211_scan_done(mac->scan_req, &info);
                mac->scan_req = NULL;
        }
+
+       mutex_unlock(&mac->mac_lock);
 }
 
 #endif /* _QTN_FMAC_CFG80211_H_ */
index 17d17e332a8b67480dc423346991361e3735b492..5e60180482d11c889ca3f400307cc367b6dda33c 100644 (file)
@@ -288,6 +288,8 @@ static struct qtnf_wmac *qtnf_core_mac_alloc(struct qtnf_bus *bus,
                mac->iflist[i].mac = mac;
                mac->iflist[i].vifid = i;
                qtnf_sta_list_init(&mac->iflist[i].sta_list);
+               mutex_init(&mac->mac_lock);
+               init_timer(&mac->scan_timeout);
        }
 
        qtnf_mac_init_primary_intf(mac);
index 099aad76afeb20e6b8129bed41f235b57b486a3a..066fcd1095a0b6d2a41fb21b1898a055964a0657 100644 (file)
@@ -46,6 +46,7 @@
 #define QTNF_MAX_EVENT_QUEUE_LEN       255
 #define QTNF_DEFAULT_BG_SCAN_PERIOD    300
 #define QTNF_MAX_BG_SCAN_PERIOD                0xffff
+#define QTNF_SCAN_TIMEOUT_SEC          15
 
 #define QTNF_DEF_BSS_PRIORITY          0
 #define QTNF_DEF_WDOG_TIMEOUT          5
@@ -147,6 +148,8 @@ struct qtnf_wmac {
        struct cfg80211_scan_request *scan_req;
        struct cfg80211_chan_def chandef;
        struct cfg80211_chan_def csa_chandef;
+       struct mutex mac_lock;  /* lock during wmac speicific ops */
+       struct timer_list scan_timeout;
 };
 
 struct qtnf_hw_info {
index 43d2e7fd6e0211766d4140841a2450f74c1a0788..0fc2814eafad255dfa7ee1074f084fd4016840e5 100644 (file)
@@ -345,6 +345,8 @@ qtnf_event_handle_scan_complete(struct qtnf_wmac *mac,
                return -EINVAL;
        }
 
+       if (timer_pending(&mac->scan_timeout))
+               del_timer_sync(&mac->scan_timeout);
        qtnf_scan_done(mac, le32_to_cpu(status->flags) & QLINK_SCAN_ABORTED);
 
        return 0;