qtnfmac: drop unnecessary TLVs from scan command
authorIgor Mitsyanko <igor.mitsyanko.os@quantenna.com>
Mon, 27 Jan 2020 10:46:56 +0000 (10:46 +0000)
committerKalle Valo <kvalo@codeaurora.org>
Wed, 12 Feb 2020 16:16:48 +0000 (18:16 +0200)
Most part of scan command data is always present, so no need
to keep it in TLV. Simplify scan command processing moving
most part of its parameters into a fixed part of
qlink_cmd_scan message.

Use fixed dwell time values for normal scan when device is not
connected, and allow wireless card decide on dwell times by
itself if it's operating as a STA and is connected. When
connected, card can select dwell times dynamically based on
traffic conditions to get best results.

Signed-off-by: Igor Mitsyanko <igor.mitsyanko.os@quantenna.com>
Signed-off-by: Kalle Valo <kvalo@codeaurora.org>
drivers/net/wireless/quantenna/qtnfmac/commands.c
drivers/net/wireless/quantenna/qtnfmac/qlink.h
drivers/net/wireless/quantenna/qtnfmac/qlink_util.h

index 3128669..ccc1e06 100644 (file)
 #include "bus.h"
 #include "commands.h"
 
+/* Let device itself to select best values for current conditions */
 #define QTNF_SCAN_TIME_AUTO    0
 
-/* Let device itself to select best values for current conditions */
-#define QTNF_SCAN_DWELL_ACTIVE_DEFAULT         QTNF_SCAN_TIME_AUTO
-#define QTNF_SCAN_DWELL_PASSIVE_DEFAULT                QTNF_SCAN_TIME_AUTO
+#define QTNF_SCAN_DWELL_ACTIVE_DEFAULT         90
+#define QTNF_SCAN_DWELL_PASSIVE_DEFAULT                100
 #define QTNF_SCAN_SAMPLE_DURATION_DEFAULT      QTNF_SCAN_TIME_AUTO
 
 static int qtnf_cmd_check_reply_header(const struct qlink_resp *resp,
@@ -2011,108 +2011,90 @@ static void qtnf_cmd_randmac_tlv_add(struct sk_buff *cmd_skb,
        memcpy(randmac->mac_addr_mask, mac_addr_mask, ETH_ALEN);
 }
 
-static void qtnf_cmd_scan_set_dwell(struct qtnf_wmac *mac,
-                                   struct sk_buff *cmd_skb)
+int qtnf_cmd_send_scan(struct qtnf_wmac *mac)
 {
        struct cfg80211_scan_request *scan_req = mac->scan_req;
-       u16 dwell_active = QTNF_SCAN_DWELL_ACTIVE_DEFAULT;
        u16 dwell_passive = QTNF_SCAN_DWELL_PASSIVE_DEFAULT;
-       u16 duration = QTNF_SCAN_SAMPLE_DURATION_DEFAULT;
-
-       if (scan_req->duration) {
-               dwell_active = scan_req->duration;
-               dwell_passive = scan_req->duration;
-       }
-
-       pr_debug("MAC%u: %s scan dwell active=%u, passive=%u, duration=%u\n",
-                mac->macid,
-                scan_req->duration_mandatory ? "mandatory" : "max",
-                dwell_active, dwell_passive, duration);
-
-       qtnf_cmd_skb_put_tlv_u32(cmd_skb,
-                                QTN_TLV_ID_SCAN_DWELL_ACTIVE,
-                                dwell_active);
-       qtnf_cmd_skb_put_tlv_u32(cmd_skb,
-                                QTN_TLV_ID_SCAN_DWELL_PASSIVE,
-                                dwell_passive);
-       qtnf_cmd_skb_put_tlv_u32(cmd_skb,
-                                QTN_TLV_ID_SCAN_SAMPLE_DURATION,
-                                duration);
-}
-
-int qtnf_cmd_send_scan(struct qtnf_wmac *mac)
-{
-       struct sk_buff *cmd_skb;
+       u16 dwell_active = QTNF_SCAN_DWELL_ACTIVE_DEFAULT;
+       struct wireless_dev *wdev = scan_req->wdev;
        struct ieee80211_channel *sc;
-       struct cfg80211_scan_request *scan_req = mac->scan_req;
-       int n_channels;
-       int count = 0;
+       struct qlink_cmd_scan *cmd;
+       struct sk_buff *cmd_skb;
+       int n_channels = 0;
+       u64 flags = 0;
+       int count;
        int ret;
 
        cmd_skb = qtnf_cmd_alloc_new_cmdskb(mac->macid, QLINK_VIFID_RSVD,
                                            QLINK_CMD_SCAN,
-                                           sizeof(struct qlink_cmd));
+                                           sizeof(*cmd));
        if (!cmd_skb)
                return -ENOMEM;
 
-       qtnf_bus_lock(mac->bus);
+       cmd = (struct qlink_cmd_scan *)cmd_skb->data;
 
-       if (scan_req->n_ssids != 0) {
-               while (count < scan_req->n_ssids) {
-                       qtnf_cmd_skb_put_tlv_arr(cmd_skb, WLAN_EID_SSID,
-                               scan_req->ssids[count].ssid,
-                               scan_req->ssids[count].ssid_len);
-                       count++;
-               }
+       if (scan_req->duration) {
+               dwell_active = scan_req->duration;
+               dwell_passive = scan_req->duration;
+       } else if (wdev->iftype == NL80211_IFTYPE_STATION &&
+                  wdev->current_bss) {
+               /* let device select dwell based on traffic conditions */
+               dwell_active = QTNF_SCAN_TIME_AUTO;
+               dwell_passive = QTNF_SCAN_TIME_AUTO;
+       }
+
+       cmd->n_ssids = cpu_to_le16(scan_req->n_ssids);
+       for (count = 0; count < scan_req->n_ssids; ++count) {
+               qtnf_cmd_skb_put_tlv_arr(cmd_skb, WLAN_EID_SSID,
+                                        scan_req->ssids[count].ssid,
+                                        scan_req->ssids[count].ssid_len);
        }
 
        if (scan_req->ie_len != 0)
                qtnf_cmd_tlv_ie_set_add(cmd_skb, QLINK_IE_SET_PROBE_REQ,
                                        scan_req->ie, scan_req->ie_len);
 
-       if (scan_req->n_channels) {
-               n_channels = scan_req->n_channels;
-               count = 0;
-
-               while (n_channels != 0) {
-                       sc = scan_req->channels[count];
-                       if (sc->flags & IEEE80211_CHAN_DISABLED) {
-                               n_channels--;
-                               continue;
-                       }
+       for (count = 0; count < scan_req->n_channels; ++count) {
+               sc = scan_req->channels[count];
+               if (sc->flags & IEEE80211_CHAN_DISABLED)
+                       continue;
 
-                       pr_debug("MAC%u: scan chan=%d, freq=%d, flags=%#x\n",
-                                mac->macid, sc->hw_value, sc->center_freq,
-                                sc->flags);
+               pr_debug("[MAC%u] scan chan=%d, freq=%d, flags=%#x\n",
+                        mac->macid, sc->hw_value, sc->center_freq,
+                        sc->flags);
 
-                       qtnf_cmd_channel_tlv_add(cmd_skb, sc);
-                       n_channels--;
-                       count++;
-               }
+               qtnf_cmd_channel_tlv_add(cmd_skb, sc);
+               ++n_channels;
        }
 
-       qtnf_cmd_scan_set_dwell(mac, cmd_skb);
+       if (scan_req->flags & NL80211_SCAN_FLAG_FLUSH)
+               flags |= QLINK_SCAN_FLAG_FLUSH;
+
+       if (scan_req->duration_mandatory)
+               flags |= QLINK_SCAN_FLAG_DURATION_MANDATORY;
+
+       cmd->n_channels = cpu_to_le16(n_channels);
+       cmd->active_dwell = cpu_to_le16(dwell_active);
+       cmd->passive_dwell = cpu_to_le16(dwell_passive);
+       cmd->sample_duration = cpu_to_le16(QTNF_SCAN_SAMPLE_DURATION_DEFAULT);
+       cmd->flags = cpu_to_le64(flags);
+
+       pr_debug("[MAC%u] %s scan dwell active=%u passive=%u duration=%u\n",
+                mac->macid,
+                scan_req->duration_mandatory ? "mandatory" : "max",
+                dwell_active, dwell_passive,
+                QTNF_SCAN_SAMPLE_DURATION_DEFAULT);
 
        if (scan_req->flags & NL80211_SCAN_FLAG_RANDOM_ADDR) {
-               pr_debug("MAC%u: scan with random addr=%pM, mask=%pM\n",
+               pr_debug("[MAC%u] scan with random addr=%pM, mask=%pM\n",
                         mac->macid,
                         scan_req->mac_addr, scan_req->mac_addr_mask);
-
                qtnf_cmd_randmac_tlv_add(cmd_skb, scan_req->mac_addr,
                                         scan_req->mac_addr_mask);
        }
 
-       if (scan_req->flags & NL80211_SCAN_FLAG_FLUSH) {
-               pr_debug("MAC%u: flush cache before scan\n", mac->macid);
-
-               qtnf_cmd_skb_put_tlv_tag(cmd_skb, QTN_TLV_ID_SCAN_FLUSH);
-       }
-
+       qtnf_bus_lock(mac->bus);
        ret = qtnf_cmd_send(mac->bus, cmd_skb);
-       if (ret)
-               goto out;
-
-out:
        qtnf_bus_unlock(mac->bus);
 
        return ret;
index ab2bfae..7ee1070 100644 (file)
@@ -920,6 +920,46 @@ struct qlink_cmd_ndev_changeupper {
        u8 rsvd[1];
 } __packed;
 
+/**
+ * enum qlink_scan_flags -  scan request control flags
+ *
+ * Scan flags are used to control QLINK_CMD_SCAN behavior.
+ *
+ * @QLINK_SCAN_FLAG_FLUSH: flush cache before scanning.
+ */
+enum qlink_scan_flags {
+       QLINK_SCAN_FLAG_FLUSH = BIT(0),
+       QLINK_SCAN_FLAG_DURATION_MANDATORY = BIT(1),
+};
+
+/**
+ * struct qlink_cmd_scan - data for QLINK_CMD_SCAN command
+ *
+ * @flags: scan flags, a bitmap of &enum qlink_scan_flags.
+ * @n_ssids: number of WLAN_EID_SSID TLVs expected in variable portion of the
+ *     command.
+ * @n_channels: number of QTN_TLV_ID_CHANNEL TLVs expected in variable payload.
+ * @active_dwell: time spent on a single channel for an active scan.
+ * @passive_dwell: time spent on a single channel for a passive scan.
+ * @sample_duration: total duration of sampling a single channel during a scan
+ *     including off-channel dwell time and operating channel time.
+ * @bssid: specific BSSID to scan for or a broadcast BSSID.
+ * @scan_width: channel width to use, one of &enum qlink_channel_width.
+ */
+struct qlink_cmd_scan {
+       struct qlink_cmd chdr;
+       __le64 flags;
+       __le16 n_ssids;
+       __le16 n_channels;
+       __le16 active_dwell;
+       __le16 passive_dwell;
+       __le16 sample_duration;
+       u8 bssid[ETH_ALEN];
+       u8 scan_width;
+       u8 rsvd[3];
+       u8 var_info[0];
+} __packed;
+
 /* QLINK Command Responses messages related definitions
  */
 
@@ -1407,13 +1447,6 @@ struct qlink_event_mic_failure {
  * @QTN_TLV_ID_STA_STATS: per-STA statistics as defined by
  *     &struct qlink_sta_stats. Valid values are marked as such in a bitmap
  *     carried by QTN_TLV_ID_BITMAP.
- * @QTN_TLV_ID_SCAN_DWELL_ACTIVE: time spent on a single channel for an active
- *     scan.
- * @QTN_TLV_ID_SCAN_DWELL_PASSIVE: time spent on a single channel for a passive
- *     scan.
- * @QTN_TLV_ID_SCAN_SAMPLE_DURATION: total duration of sampling a single channel
- *     during a scan including off-channel dwell time and operating channel
- *     time.
  * @QTN_TLV_ID_IFTYPE_DATA: supported band data.
  */
 enum qlink_tlv_id {
@@ -1444,10 +1477,6 @@ enum qlink_tlv_id {
        QTN_TLV_ID_RANDOM_MAC_ADDR      = 0x0408,
        QTN_TLV_ID_WOWLAN_CAPAB         = 0x0410,
        QTN_TLV_ID_WOWLAN_PATTERN       = 0x0411,
-       QTN_TLV_ID_SCAN_FLUSH           = 0x0412,
-       QTN_TLV_ID_SCAN_DWELL_ACTIVE    = 0x0413,
-       QTN_TLV_ID_SCAN_DWELL_PASSIVE   = 0x0416,
-       QTN_TLV_ID_SCAN_SAMPLE_DURATION = 0x0417,
        QTN_TLV_ID_IFTYPE_DATA          = 0x0418,
 };
 
index 9164b75..230a10a 100644 (file)
@@ -28,14 +28,6 @@ static inline void qtnf_cmd_skb_put_tlv_arr(struct sk_buff *skb,
        memcpy(hdr->val, arr, arr_len);
 }
 
-static inline void qtnf_cmd_skb_put_tlv_tag(struct sk_buff *skb, u16 tlv_id)
-{
-       struct qlink_tlv_hdr *hdr = skb_put(skb, sizeof(*hdr));
-
-       hdr->type = cpu_to_le16(tlv_id);
-       hdr->len = cpu_to_le16(0);
-}
-
 static inline void qtnf_cmd_skb_put_tlv_u32(struct sk_buff *skb,
                                            u16 tlv_id, u32 value)
 {