aboutsummaryrefslogtreecommitdiffstats
path: root/package/kernel/mac80211/patches/357-0004-brcmfmac-fix-handling-ssids-in-.sched_scan_start-cal.patch
diff options
context:
space:
mode:
Diffstat (limited to 'package/kernel/mac80211/patches/357-0004-brcmfmac-fix-handling-ssids-in-.sched_scan_start-cal.patch')
-rw-r--r--package/kernel/mac80211/patches/357-0004-brcmfmac-fix-handling-ssids-in-.sched_scan_start-cal.patch221
1 files changed, 221 insertions, 0 deletions
diff --git a/package/kernel/mac80211/patches/357-0004-brcmfmac-fix-handling-ssids-in-.sched_scan_start-cal.patch b/package/kernel/mac80211/patches/357-0004-brcmfmac-fix-handling-ssids-in-.sched_scan_start-cal.patch
new file mode 100644
index 0000000000..f1934af71c
--- /dev/null
+++ b/package/kernel/mac80211/patches/357-0004-brcmfmac-fix-handling-ssids-in-.sched_scan_start-cal.patch
@@ -0,0 +1,221 @@
+From 3e2e86ab19c2a43953de30089c5411c580ddb5f7 Mon Sep 17 00:00:00 2001
+From: Arend Van Spriel <arend.vanspriel@broadcom.com>
+Date: Wed, 23 Nov 2016 10:25:23 +0000
+Subject: [PATCH] brcmfmac: fix handling ssids in .sched_scan_start() callback
+
+The ssids list in the scheduled scan request were not properly taken
+into account when configuring in firmware. The hidden bit was set for
+any ssid resulting in active scanning for all. Only set it for ssids
+that are in the ssids list.
+
+Reviewed-by: Hante Meuleman <hante.meuleman@broadcom.com>
+Reviewed-by: Pieter-Paul Giesberts <pieter-paul.giesberts@broadcom.com>
+Reviewed-by: Franky Lin <franky.lin@broadcom.com>
+Signed-off-by: Arend van Spriel <arend.vanspriel@broadcom.com>
+Signed-off-by: Kalle Valo <kvalo@codeaurora.org>
+---
+ .../broadcom/brcm80211/brcmfmac/cfg80211.c | 103 ++++++++++-----------
+ .../net/wireless/broadcom/brcm80211/brcmfmac/pno.c | 18 ++++
+ .../net/wireless/broadcom/brcm80211/brcmfmac/pno.h | 12 ++-
+ 3 files changed, 76 insertions(+), 57 deletions(-)
+
+--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.c
++++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.c
+@@ -3314,19 +3314,37 @@ out_err:
+ return err;
+ }
+
++static bool brcmf_is_ssid_active(struct cfg80211_ssid *ssid,
++ struct cfg80211_sched_scan_request *req)
++{
++ int i;
++
++ if (!ssid || !req->ssids || !req->n_ssids)
++ return false;
++
++ for (i = 0; i < req->n_ssids; i++) {
++ if (ssid->ssid_len == req->ssids[i].ssid_len) {
++ if (!strncmp(ssid->ssid, req->ssids[i].ssid,
++ ssid->ssid_len))
++ return true;
++ }
++ }
++ return false;
++}
++
+ static int
+ brcmf_cfg80211_sched_scan_start(struct wiphy *wiphy,
+ struct net_device *ndev,
+- struct cfg80211_sched_scan_request *request)
++ struct cfg80211_sched_scan_request *req)
+ {
+ struct brcmf_if *ifp = netdev_priv(ndev);
+ struct brcmf_cfg80211_info *cfg = wiphy_priv(wiphy);
+- struct brcmf_pno_net_param_le pfn;
++ struct cfg80211_ssid *ssid;
+ int i;
+ int ret = 0;
+
+ brcmf_dbg(SCAN, "Enter n_match_sets:%d n_ssids:%d\n",
+- request->n_match_sets, request->n_ssids);
++ req->n_match_sets, req->n_ssids);
+ if (test_bit(BRCMF_SCAN_STATUS_BUSY, &cfg->scan_status)) {
+ brcmf_err("Scanning already: status (%lu)\n", cfg->scan_status);
+ return -EAGAIN;
+@@ -3337,71 +3355,46 @@ brcmf_cfg80211_sched_scan_start(struct w
+ return -EAGAIN;
+ }
+
+- if (!request->n_ssids || !request->n_match_sets) {
+- brcmf_dbg(SCAN, "Invalid sched scan req!! n_ssids:%d\n",
+- request->n_ssids);
++ if (req->n_match_sets <= 0) {
++ brcmf_dbg(SCAN, "invalid number of matchsets specified: %d\n",
++ req->n_match_sets);
+ return -EINVAL;
+ }
+
+- if (request->n_ssids > 0) {
+- for (i = 0; i < request->n_ssids; i++) {
+- /* Active scan req for ssids */
+- brcmf_dbg(SCAN, ">>> Active scan req for ssid (%s)\n",
+- request->ssids[i].ssid);
+-
+- /* match_set ssids is a supert set of n_ssid list,
+- * so we need not add these set separately.
+- */
+- }
++ /* clean up everything */
++ ret = brcmf_pno_clean(ifp);
++ if (ret < 0) {
++ brcmf_err("failed error=%d\n", ret);
++ return ret;
+ }
+
+- if (request->n_match_sets > 0) {
+- /* clean up everything */
+- ret = brcmf_pno_clean(ifp);
+- if (ret < 0) {
+- brcmf_err("failed error=%d\n", ret);
+- return ret;
++ /* configure pno */
++ ret = brcmf_pno_config(ifp, req);
++ if (ret < 0)
++ return ret;
++
++ /* configure each match set */
++ for (i = 0; i < req->n_match_sets; i++) {
++
++ ssid = &req->match_sets[i].ssid;
++
++ if (!ssid->ssid_len) {
++ brcmf_err("skip broadcast ssid\n");
++ continue;
+ }
+
+- /* configure pno */
+- ret = brcmf_pno_config(ifp, request);
++ ret = brcmf_pno_add_ssid(ifp, ssid,
++ brcmf_is_ssid_active(ssid, req));
+ if (ret < 0)
+- return ret;
+-
+- /* configure each match set */
+- for (i = 0; i < request->n_match_sets; i++) {
+- struct cfg80211_ssid *ssid;
+- u32 ssid_len;
+-
+- ssid = &request->match_sets[i].ssid;
+- ssid_len = ssid->ssid_len;
+-
+- if (!ssid_len) {
+- brcmf_err("skip broadcast ssid\n");
+- continue;
+- }
+- pfn.auth = cpu_to_le32(WLAN_AUTH_OPEN);
+- pfn.wpa_auth = cpu_to_le32(BRCMF_PNO_WPA_AUTH_ANY);
+- pfn.wsec = cpu_to_le32(0);
+- pfn.infra = cpu_to_le32(1);
+- pfn.flags = cpu_to_le32(1 << BRCMF_PNO_HIDDEN_BIT);
+- pfn.ssid.SSID_len = cpu_to_le32(ssid_len);
+- memcpy(pfn.ssid.SSID, ssid->ssid, ssid_len);
+- ret = brcmf_fil_iovar_data_set(ifp, "pfn_add", &pfn,
+- sizeof(pfn));
+ brcmf_dbg(SCAN, ">>> PNO filter %s for ssid (%s)\n",
+ ret == 0 ? "set" : "failed", ssid->ssid);
+- }
+- /* Enable the PNO */
+- if (brcmf_fil_iovar_int_set(ifp, "pfn", 1) < 0) {
+- brcmf_err("PNO enable failed!! ret=%d\n", ret);
+- return -EINVAL;
+- }
+- } else {
+- return -EINVAL;
+ }
++ /* Enable the PNO */
++ ret = brcmf_fil_iovar_int_set(ifp, "pfn", 1);
++ if (ret < 0)
++ brcmf_err("PNO enable failed!! ret=%d\n", ret);
+
+- return 0;
++ return ret;
+ }
+
+ static int brcmf_cfg80211_sched_scan_stop(struct wiphy *wiphy,
+--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/pno.c
++++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/pno.c
+@@ -28,6 +28,8 @@
+ #define BRCMF_PNO_FREQ_EXPO_MAX 3
+ #define BRCMF_PNO_ENABLE_ADAPTSCAN_BIT 6
+ #define BRCMF_PNO_SCAN_INCOMPLETE 0
++#define BRCMF_PNO_WPA_AUTH_ANY 0xFFFFFFFF
++#define BRCMF_PNO_HIDDEN_BIT 2
+
+ int brcmf_pno_clean(struct brcmf_if *ifp)
+ {
+@@ -98,3 +100,19 @@ int brcmf_pno_config(struct brcmf_if *if
+ return err;
+ }
+
++int brcmf_pno_add_ssid(struct brcmf_if *ifp, struct cfg80211_ssid *ssid,
++ bool active)
++{
++ struct brcmf_pno_net_param_le pfn;
++
++ pfn.auth = cpu_to_le32(WLAN_AUTH_OPEN);
++ pfn.wpa_auth = cpu_to_le32(BRCMF_PNO_WPA_AUTH_ANY);
++ pfn.wsec = cpu_to_le32(0);
++ pfn.infra = cpu_to_le32(1);
++ if (active)
++ pfn.flags = cpu_to_le32(1 << BRCMF_PNO_HIDDEN_BIT);
++ pfn.ssid.SSID_len = cpu_to_le32(ssid->ssid_len);
++ memcpy(pfn.ssid.SSID, ssid->ssid, ssid->ssid_len);
++ return brcmf_fil_iovar_data_set(ifp, "pfn_add", &pfn, sizeof(pfn));
++}
++
+--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/pno.h
++++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/pno.h
+@@ -17,8 +17,6 @@
+ #define _BRCMF_PNO_H
+
+ #define BRCMF_PNO_SCAN_COMPLETE 1
+-#define BRCMF_PNO_WPA_AUTH_ANY 0xFFFFFFFF
+-#define BRCMF_PNO_HIDDEN_BIT 2
+ #define BRCMF_PNO_MAX_PFN_COUNT 16
+
+ /**
+@@ -37,4 +35,14 @@ int brcmf_pno_clean(struct brcmf_if *ifp
+ int brcmf_pno_config(struct brcmf_if *ifp,
+ struct cfg80211_sched_scan_request *request);
+
++/**
++ * brcmf_pno_add_ssid - add ssid for pno in firmware.
++ *
++ * @ifp: interface object used.
++ * @ssid: ssid information.
++ * @active: indicate this ssid needs to be actively probed.
++ */
++int brcmf_pno_add_ssid(struct brcmf_if *ifp, struct cfg80211_ssid *ssid,
++ bool active);
++
+ #endif /* _BRCMF_PNO_H */