1 From 3e2e86ab19c2a43953de30089c5411c580ddb5f7 Mon Sep 17 00:00:00 2001
2 From: Arend Van Spriel <arend.vanspriel@broadcom.com>
3 Date: Wed, 23 Nov 2016 10:25:23 +0000
4 Subject: [PATCH] brcmfmac: fix handling ssids in .sched_scan_start() callback
6 The ssids list in the scheduled scan request were not properly taken
7 into account when configuring in firmware. The hidden bit was set for
8 any ssid resulting in active scanning for all. Only set it for ssids
9 that are in the ssids list.
11 Reviewed-by: Hante Meuleman <hante.meuleman@broadcom.com>
12 Reviewed-by: Pieter-Paul Giesberts <pieter-paul.giesberts@broadcom.com>
13 Reviewed-by: Franky Lin <franky.lin@broadcom.com>
14 Signed-off-by: Arend van Spriel <arend.vanspriel@broadcom.com>
15 Signed-off-by: Kalle Valo <kvalo@codeaurora.org>
17 .../broadcom/brcm80211/brcmfmac/cfg80211.c | 103 ++++++++++-----------
18 .../net/wireless/broadcom/brcm80211/brcmfmac/pno.c | 18 ++++
19 .../net/wireless/broadcom/brcm80211/brcmfmac/pno.h | 12 ++-
20 3 files changed, 76 insertions(+), 57 deletions(-)
22 --- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.c
23 +++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.c
24 @@ -3314,19 +3314,37 @@ out_err:
28 +static bool brcmf_is_ssid_active(struct cfg80211_ssid *ssid,
29 + struct cfg80211_sched_scan_request *req)
33 + if (!ssid || !req->ssids || !req->n_ssids)
36 + for (i = 0; i < req->n_ssids; i++) {
37 + if (ssid->ssid_len == req->ssids[i].ssid_len) {
38 + if (!strncmp(ssid->ssid, req->ssids[i].ssid,
47 brcmf_cfg80211_sched_scan_start(struct wiphy *wiphy,
48 struct net_device *ndev,
49 - struct cfg80211_sched_scan_request *request)
50 + struct cfg80211_sched_scan_request *req)
52 struct brcmf_if *ifp = netdev_priv(ndev);
53 struct brcmf_cfg80211_info *cfg = wiphy_priv(wiphy);
54 - struct brcmf_pno_net_param_le pfn;
55 + struct cfg80211_ssid *ssid;
59 brcmf_dbg(SCAN, "Enter n_match_sets:%d n_ssids:%d\n",
60 - request->n_match_sets, request->n_ssids);
61 + req->n_match_sets, req->n_ssids);
62 if (test_bit(BRCMF_SCAN_STATUS_BUSY, &cfg->scan_status)) {
63 brcmf_err("Scanning already: status (%lu)\n", cfg->scan_status);
65 @@ -3337,71 +3355,46 @@ brcmf_cfg80211_sched_scan_start(struct w
69 - if (!request->n_ssids || !request->n_match_sets) {
70 - brcmf_dbg(SCAN, "Invalid sched scan req!! n_ssids:%d\n",
72 + if (req->n_match_sets <= 0) {
73 + brcmf_dbg(SCAN, "invalid number of matchsets specified: %d\n",
78 - if (request->n_ssids > 0) {
79 - for (i = 0; i < request->n_ssids; i++) {
80 - /* Active scan req for ssids */
81 - brcmf_dbg(SCAN, ">>> Active scan req for ssid (%s)\n",
82 - request->ssids[i].ssid);
84 - /* match_set ssids is a supert set of n_ssid list,
85 - * so we need not add these set separately.
88 + /* clean up everything */
89 + ret = brcmf_pno_clean(ifp);
91 + brcmf_err("failed error=%d\n", ret);
95 - if (request->n_match_sets > 0) {
96 - /* clean up everything */
97 - ret = brcmf_pno_clean(ifp);
99 - brcmf_err("failed error=%d\n", ret);
101 + /* configure pno */
102 + ret = brcmf_pno_config(ifp, req);
106 + /* configure each match set */
107 + for (i = 0; i < req->n_match_sets; i++) {
109 + ssid = &req->match_sets[i].ssid;
111 + if (!ssid->ssid_len) {
112 + brcmf_err("skip broadcast ssid\n");
116 - /* configure pno */
117 - ret = brcmf_pno_config(ifp, request);
118 + ret = brcmf_pno_add_ssid(ifp, ssid,
119 + brcmf_is_ssid_active(ssid, req));
123 - /* configure each match set */
124 - for (i = 0; i < request->n_match_sets; i++) {
125 - struct cfg80211_ssid *ssid;
128 - ssid = &request->match_sets[i].ssid;
129 - ssid_len = ssid->ssid_len;
132 - brcmf_err("skip broadcast ssid\n");
135 - pfn.auth = cpu_to_le32(WLAN_AUTH_OPEN);
136 - pfn.wpa_auth = cpu_to_le32(BRCMF_PNO_WPA_AUTH_ANY);
137 - pfn.wsec = cpu_to_le32(0);
138 - pfn.infra = cpu_to_le32(1);
139 - pfn.flags = cpu_to_le32(1 << BRCMF_PNO_HIDDEN_BIT);
140 - pfn.ssid.SSID_len = cpu_to_le32(ssid_len);
141 - memcpy(pfn.ssid.SSID, ssid->ssid, ssid_len);
142 - ret = brcmf_fil_iovar_data_set(ifp, "pfn_add", &pfn,
144 brcmf_dbg(SCAN, ">>> PNO filter %s for ssid (%s)\n",
145 ret == 0 ? "set" : "failed", ssid->ssid);
147 - /* Enable the PNO */
148 - if (brcmf_fil_iovar_int_set(ifp, "pfn", 1) < 0) {
149 - brcmf_err("PNO enable failed!! ret=%d\n", ret);
155 + /* Enable the PNO */
156 + ret = brcmf_fil_iovar_int_set(ifp, "pfn", 1);
158 + brcmf_err("PNO enable failed!! ret=%d\n", ret);
164 static int brcmf_cfg80211_sched_scan_stop(struct wiphy *wiphy,
165 --- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/pno.c
166 +++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/pno.c
168 #define BRCMF_PNO_FREQ_EXPO_MAX 3
169 #define BRCMF_PNO_ENABLE_ADAPTSCAN_BIT 6
170 #define BRCMF_PNO_SCAN_INCOMPLETE 0
171 +#define BRCMF_PNO_WPA_AUTH_ANY 0xFFFFFFFF
172 +#define BRCMF_PNO_HIDDEN_BIT 2
174 int brcmf_pno_clean(struct brcmf_if *ifp)
176 @@ -98,3 +100,19 @@ int brcmf_pno_config(struct brcmf_if *if
180 +int brcmf_pno_add_ssid(struct brcmf_if *ifp, struct cfg80211_ssid *ssid,
183 + struct brcmf_pno_net_param_le pfn;
185 + pfn.auth = cpu_to_le32(WLAN_AUTH_OPEN);
186 + pfn.wpa_auth = cpu_to_le32(BRCMF_PNO_WPA_AUTH_ANY);
187 + pfn.wsec = cpu_to_le32(0);
188 + pfn.infra = cpu_to_le32(1);
190 + pfn.flags = cpu_to_le32(1 << BRCMF_PNO_HIDDEN_BIT);
191 + pfn.ssid.SSID_len = cpu_to_le32(ssid->ssid_len);
192 + memcpy(pfn.ssid.SSID, ssid->ssid, ssid->ssid_len);
193 + return brcmf_fil_iovar_data_set(ifp, "pfn_add", &pfn, sizeof(pfn));
196 --- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/pno.h
197 +++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/pno.h
201 #define BRCMF_PNO_SCAN_COMPLETE 1
202 -#define BRCMF_PNO_WPA_AUTH_ANY 0xFFFFFFFF
203 -#define BRCMF_PNO_HIDDEN_BIT 2
204 #define BRCMF_PNO_MAX_PFN_COUNT 16
207 @@ -37,4 +35,14 @@ int brcmf_pno_clean(struct brcmf_if *ifp
208 int brcmf_pno_config(struct brcmf_if *ifp,
209 struct cfg80211_sched_scan_request *request);
212 + * brcmf_pno_add_ssid - add ssid for pno in firmware.
214 + * @ifp: interface object used.
215 + * @ssid: ssid information.
216 + * @active: indicate this ssid needs to be actively probed.
218 +int brcmf_pno_add_ssid(struct brcmf_if *ifp, struct cfg80211_ssid *ssid,
221 #endif /* _BRCMF_PNO_H */