From: Igor Mitsyanko <igor.mitsyanko.os@xxxxxxxxxxxxx> 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@xxxxxxxxxxxxx> --- drivers/net/wireless/quantenna/qtnfmac/commands.c | 130 +++++++++------------ drivers/net/wireless/quantenna/qtnfmac/qlink.h | 51 ++++++-- .../net/wireless/quantenna/qtnfmac/qlink_util.h | 8 -- 3 files changed, 96 insertions(+), 93 deletions(-) diff --git a/drivers/net/wireless/quantenna/qtnfmac/commands.c b/drivers/net/wireless/quantenna/qtnfmac/commands.c index 31286699a5b7..ccc1e06dfcf6 100644 --- a/drivers/net/wireless/quantenna/qtnfmac/commands.c +++ b/drivers/net/wireless/quantenna/qtnfmac/commands.c @@ -11,11 +11,11 @@ #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; diff --git a/drivers/net/wireless/quantenna/qtnfmac/qlink.h b/drivers/net/wireless/quantenna/qtnfmac/qlink.h index ab2bfae7ff3e..7ee1070f985f 100644 --- a/drivers/net/wireless/quantenna/qtnfmac/qlink.h +++ b/drivers/net/wireless/quantenna/qtnfmac/qlink.h @@ -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, }; diff --git a/drivers/net/wireless/quantenna/qtnfmac/qlink_util.h b/drivers/net/wireless/quantenna/qtnfmac/qlink_util.h index 9164b750396c..230a10a41c7a 100644 --- a/drivers/net/wireless/quantenna/qtnfmac/qlink_util.h +++ b/drivers/net/wireless/quantenna/qtnfmac/qlink_util.h @@ -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) { -- 2.11.0