From 863a06b0a4ed3939d81fb49d3b8a88db9e807d41 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Rafa=C5=82=20Mi=C5=82ecki?= Date: Thu, 2 Feb 2017 09:27:20 +0100 Subject: mac80211: brcmfmac: backport scheduled scan cleanup and chip support MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Rafał Miłecki --- ...x-handling-ssids-in-.sched_scan_start-cal.patch | 221 +++++++++++++++++++++ 1 file changed, 221 insertions(+) create mode 100644 package/kernel/mac80211/patches/357-0004-brcmfmac-fix-handling-ssids-in-.sched_scan_start-cal.patch (limited to 'package/kernel/mac80211/patches/357-0004-brcmfmac-fix-handling-ssids-in-.sched_scan_start-cal.patch') 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 +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 +Reviewed-by: Pieter-Paul Giesberts +Reviewed-by: Franky Lin +Signed-off-by: Arend van Spriel +Signed-off-by: Kalle Valo +--- + .../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 */ -- cgit v1.2.3