aboutsummaryrefslogtreecommitdiffstats
path: root/package/kernel/mac80211/patches/357-0007-brcmfmac-split-up-brcmf_pno_config-function.patch
blob: f81523aa01a8ffa40f923ddacf3a80cb1e74a098 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
From fca6cb2f059e51dec3fcf3589a5abbbcce5b4043 Mon Sep 17 00:00:00 2001
From: Arend Van Spriel <arend.vanspriel@broadcom.com>
Date: Wed, 23 Nov 2016 10:25:26 +0000
Subject: [PATCH] brcmfmac: split up brcmf_pno_config() function

The brcmf_pno_config() function handles two configurations in
firmware. Split it and have caller sort out what is needed.

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         | 11 +++-
 .../net/wireless/broadcom/brcm80211/brcmfmac/pno.c | 60 ++++++++++++++++------
 .../net/wireless/broadcom/brcm80211/brcmfmac/pno.h | 17 ++++--
 3 files changed, 68 insertions(+), 20 deletions(-)

--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.c
+++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.c
@@ -42,6 +42,7 @@
 #include "common.h"
 
 #define BRCMF_SCAN_IE_LEN_MAX		2048
+#define BRCMF_SCHED_SCAN_PERIOD		30
 
 #define WPA_OUI				"\x00\x50\xF2"	/* WPA OUI */
 #define WPA_OUI_TYPE			1
@@ -3396,10 +3397,18 @@ brcmf_cfg80211_sched_scan_start(struct w
 	}
 
 	/* configure pno */
-	ret = brcmf_pno_config(ifp, req);
+	ret = brcmf_pno_config(ifp, BRCMF_SCHED_SCAN_PERIOD, 0, 0);
 	if (ret < 0)
 		return ret;
 
+	/* configure random mac */
+	if (req->flags & NL80211_SCAN_FLAG_RANDOM_ADDR) {
+		ret = brcmf_pno_set_random(ifp, req->mac_addr,
+					   req->mac_addr_mask);
+		if (ret < 0)
+			return ret;
+	}
+
 	/* configure each match set */
 	for (i = 0; i < req->n_match_sets; i++) {
 
--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/pno.c
+++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/pno.c
@@ -23,10 +23,12 @@
 #include "fwil_types.h"
 
 #define BRCMF_PNO_VERSION		2
-#define BRCMF_PNO_TIME			30
 #define BRCMF_PNO_REPEAT		4
 #define BRCMF_PNO_FREQ_EXPO_MAX		3
+#define BRCMF_PNO_IMMEDIATE_SCAN_BIT	3
+#define BRCMF_PNO_ENABLE_BD_SCAN_BIT	5
 #define BRCMF_PNO_ENABLE_ADAPTSCAN_BIT	6
+#define BRCMF_PNO_REPORT_SEPARATELY_BIT	11
 #define BRCMF_PNO_SCAN_INCOMPLETE	0
 #define BRCMF_PNO_WPA_AUTH_ANY		0xFFFFFFFF
 #define BRCMF_PNO_HIDDEN_BIT		2
@@ -47,42 +49,68 @@ int brcmf_pno_clean(struct brcmf_if *ifp
 	return ret;
 }
 
-int brcmf_pno_config(struct brcmf_if *ifp,
-		     struct cfg80211_sched_scan_request *request)
+int brcmf_pno_config(struct brcmf_if *ifp, u32 scan_freq,
+		     u32 mscan, u32 bestn)
 {
 	struct brcmf_pno_param_le pfn_param;
-	struct brcmf_pno_macaddr_le pfn_mac;
+	u16 flags;
+	u32 pfnmem;
 	s32 err;
-	u8 *mac_mask;
-	int i;
 
 	memset(&pfn_param, 0, sizeof(pfn_param));
 	pfn_param.version = cpu_to_le32(BRCMF_PNO_VERSION);
 
 	/* set extra pno params */
-	pfn_param.flags = cpu_to_le16(1 << BRCMF_PNO_ENABLE_ADAPTSCAN_BIT);
+	flags = BIT(BRCMF_PNO_IMMEDIATE_SCAN_BIT) |
+		BIT(BRCMF_PNO_REPORT_SEPARATELY_BIT) |
+		BIT(BRCMF_PNO_ENABLE_ADAPTSCAN_BIT);
 	pfn_param.repeat = BRCMF_PNO_REPEAT;
 	pfn_param.exp = BRCMF_PNO_FREQ_EXPO_MAX;
 
 	/* set up pno scan fr */
-	pfn_param.scan_freq = cpu_to_le32(BRCMF_PNO_TIME);
+	pfn_param.scan_freq = cpu_to_le32(scan_freq);
+
+	if (mscan) {
+		pfnmem = bestn;
 
+		/* set bestn in firmware */
+		err = brcmf_fil_iovar_int_set(ifp, "pfnmem", pfnmem);
+		if (err < 0) {
+			brcmf_err("failed to set pfnmem\n");
+			goto exit;
+		}
+		/* get max mscan which the firmware supports */
+		err = brcmf_fil_iovar_int_get(ifp, "pfnmem", &pfnmem);
+		if (err < 0) {
+			brcmf_err("failed to get pfnmem\n");
+			goto exit;
+		}
+		mscan = min_t(u32, mscan, pfnmem);
+		pfn_param.mscan = mscan;
+		pfn_param.bestn = bestn;
+		flags |= BIT(BRCMF_PNO_ENABLE_BD_SCAN_BIT);
+		brcmf_dbg(INFO, "mscan=%d, bestn=%d\n", mscan, bestn);
+	}
+
+	pfn_param.flags = cpu_to_le16(flags);
 	err = brcmf_fil_iovar_data_set(ifp, "pfn_set", &pfn_param,
 				       sizeof(pfn_param));
-	if (err) {
+	if (err)
 		brcmf_err("pfn_set failed, err=%d\n", err);
-		return err;
-	}
 
-	/* Find out if mac randomization should be turned on */
-	if (!(request->flags & NL80211_SCAN_FLAG_RANDOM_ADDR))
-		return 0;
+exit:
+	return err;
+}
+
+int brcmf_pno_set_random(struct brcmf_if *ifp, u8 *mac_addr, u8 *mac_mask)
+{
+	struct brcmf_pno_macaddr_le pfn_mac;
+	int err, i;
 
 	pfn_mac.version = BRCMF_PFN_MACADDR_CFG_VER;
 	pfn_mac.flags = BRCMF_PFN_MAC_OUI_ONLY | BRCMF_PFN_SET_MAC_UNASSOC;
 
-	memcpy(pfn_mac.mac, request->mac_addr, ETH_ALEN);
-	mac_mask = request->mac_addr_mask;
+	memcpy(pfn_mac.mac, mac_addr, ETH_ALEN);
 	for (i = 0; i < ETH_ALEN; i++) {
 		pfn_mac.mac[i] &= mac_mask[i];
 		pfn_mac.mac[i] |= get_random_int() & ~(mac_mask[i]);
--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/pno.h
+++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/pno.h
@@ -30,10 +30,21 @@ int brcmf_pno_clean(struct brcmf_if *ifp
  * brcmf_pno_config - configure pno parameters.
  *
  * @ifp: interface object used.
- * @request: scheduled scan parameters.
+ * @scan_freq: scan frequency period in seconds.
+ * @mscan: maximum number of scans stored in firmware.
+ * @bestn: maximum number of APs per scan stored in firmware.
  */
-int brcmf_pno_config(struct brcmf_if *ifp,
-		     struct cfg80211_sched_scan_request *request);
+int brcmf_pno_config(struct brcmf_if *ifp, u32 scan_freq,
+		     u32 mscan, u32 bestn);
+
+/**
+ * brcmf_pno_set_random - setup randomisation mac address for pno.
+ *
+ * @ifp: interface object used.
+ * @mac_addr: MAC address used with randomisation.
+ * @mac_mask: MAC address mask used for randomisation.
+ */
+int brcmf_pno_set_random(struct brcmf_if *ifp, u8 *mac_addr, u8 *mac_mask);
 
 /**
  * brcmf_pno_add_ssid - add ssid for pno in firmware.