blob: c3b29814c64814be47193b9d488675fa1e6012c7 [file] [log] [blame]
Jeff Johnson295189b2012-06-20 16:38:30 -07001/*
Edhar, Mahesh Kumar59129f52015-01-14 14:26:04 +05302 * Copyright (c) 2012-2015 The Linux Foundation. All rights reserved.
Kiet Lam842dad02014-02-18 18:44:02 -08003 *
4 * Previously licensed under the ISC license by Qualcomm Atheros, Inc.
5 *
6 *
7 * Permission to use, copy, modify, and/or distribute this software for
8 * any purpose with or without fee is hereby granted, provided that the
9 * above copyright notice and this permission notice appear in all
10 * copies.
11 *
12 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL
13 * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED
14 * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE
15 * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL
16 * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
17 * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
18 * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
19 * PERFORMANCE OF THIS SOFTWARE.
20 */
21
22/*
Kiet Lama7f454d2014-07-24 12:04:06 -070023 * This file was originally distributed by Qualcomm Atheros, Inc.
24 * under proprietary terms before Copyright ownership was assigned
25 * to the Linux Foundation.
Edhar, Mahesh Kumar59129f52015-01-14 14:26:04 +053026 *
Kiet Lamaa8e15a2014-02-11 23:30:06 -080027 */
Kiet Lam842dad02014-02-18 18:44:02 -080028
29
Kiet Lama7f454d2014-07-24 12:04:06 -070030
31
Jeff Johnson295189b2012-06-20 16:38:30 -070032/**========================================================================
33
34 \file wlan_hdd_cfg80211.c
35
36 \brief WLAN Host Device Driver implementation
37
Jeff Johnson295189b2012-06-20 16:38:30 -070038 ========================================================================*/
39
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -070040/**=========================================================================
Jeff Johnson295189b2012-06-20 16:38:30 -070041
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -070042 EDIT HISTORY FOR FILE
Jeff Johnson295189b2012-06-20 16:38:30 -070043
44
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -070045 This section contains comments describing changes made to the module.
46 Notice that changes are listed in reverse chronological order.
Jeff Johnson295189b2012-06-20 16:38:30 -070047
48
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -070049 $Header:$ $DateTime: $ $Author: $
Jeff Johnson295189b2012-06-20 16:38:30 -070050
51
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -070052 when who what, where, why
Jeff Johnson295189b2012-06-20 16:38:30 -070053 -------- --- --------------------------------------------------------
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -070054 21/12/09 Ashwani Created module.
Jeff Johnson295189b2012-06-20 16:38:30 -070055
56 07/06/10 Kumar Deepak Implemented cfg80211 callbacks for ANDROID
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -070057 Ganesh K
Jeff Johnson295189b2012-06-20 16:38:30 -070058 ==========================================================================*/
59
Jeff Johnson295189b2012-06-20 16:38:30 -070060
61#include <linux/version.h>
62#include <linux/module.h>
63#include <linux/kernel.h>
64#include <linux/init.h>
65#include <linux/wireless.h>
66#include <wlan_hdd_includes.h>
67#include <net/arp.h>
68#include <net/cfg80211.h>
69#include <linux/wireless.h>
70#include <wlan_hdd_wowl.h>
71#include <aniGlobal.h>
72#include "ccmApi.h"
73#include "sirParams.h"
74#include "dot11f.h"
75#include "wlan_hdd_assoc.h"
76#include "wlan_hdd_wext.h"
77#include "sme_Api.h"
78#include "wlan_hdd_p2p.h"
79#include "wlan_hdd_cfg80211.h"
80#include "wlan_hdd_hostapd.h"
81#include "sapInternal.h"
82#include "wlan_hdd_softap_tx_rx.h"
83#include "wlan_hdd_main.h"
Madan Mohan Koyyalamudid5acbf52012-11-28 01:45:08 +053084#include "wlan_hdd_assoc.h"
Gopichand Nakkala20c4c042013-04-19 22:08:55 +053085#include "wlan_hdd_power.h"
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053086#include "wlan_hdd_trace.h"
87#include "vos_types.h"
88#include "vos_trace.h"
Jeff Johnson295189b2012-06-20 16:38:30 -070089#ifdef WLAN_BTAMP_FEATURE
90#include "bap_hdd_misc.h"
91#endif
92#include <qc_sap_ioctl.h>
Mohit Khanna698ba2a2012-12-04 15:08:18 -080093#include "wlan_hdd_tdls.h"
Gopichand Nakkala79ff85d2013-05-27 17:05:29 +053094#include "wlan_hdd_wmm.h"
Madan Mohan Koyyalamudice419872013-09-13 19:36:52 +053095#include "wlan_qct_wda.h"
Madan Mohan Koyylamudi64267f72013-02-05 14:07:08 +053096#include "wlan_nv.h"
Leo Chang6fe1f922013-06-07 19:21:24 -070097#include "wlan_hdd_dev_pwr.h"
Sushant Kaushik084f6592015-09-10 13:11:56 +053098#include "qwlan_version.h"
c_manjeecfd1efb2015-09-25 19:32:34 +053099#include "wlan_logging_sock_svc.h"
Sushant Kaushik084f6592015-09-10 13:11:56 +0530100
Jeff Johnson295189b2012-06-20 16:38:30 -0700101
102#define g_mode_rates_size (12)
103#define a_mode_rates_size (8)
104#define FREQ_BASE_80211G (2407)
105#define FREQ_BAND_DIFF_80211G (5)
Jeff Johnson04dd8a82012-06-29 20:41:40 -0700106#define MAX_SCAN_SSID 9
Kiet Lamac06e2c2013-10-23 16:25:07 +0530107#define MAX_PENDING_LOG 5
Jeff Johnson295189b2012-06-20 16:38:30 -0700108#define GET_IE_LEN_IN_BSS_DESC(lenInBss) ( lenInBss + sizeof(lenInBss) - \
krunal soni2a6a9062014-02-11 14:14:23 -0800109 ((uintptr_t)OFFSET_OF( tSirBssDescription, ieFields)))
Jeff Johnson295189b2012-06-20 16:38:30 -0700110
111#define HDD2GHZCHAN(freq, chan, flag) { \
112 .band = IEEE80211_BAND_2GHZ, \
113 .center_freq = (freq), \
114 .hw_value = (chan),\
115 .flags = (flag), \
116 .max_antenna_gain = 0 ,\
117 .max_power = 30, \
118}
119
120#define HDD5GHZCHAN(freq, chan, flag) { \
121 .band = IEEE80211_BAND_5GHZ, \
122 .center_freq = (freq), \
123 .hw_value = (chan),\
124 .flags = (flag), \
125 .max_antenna_gain = 0 ,\
126 .max_power = 30, \
127}
128
129#define HDD_G_MODE_RATETAB(rate, rate_id, flag)\
130{\
131 .bitrate = rate, \
132 .hw_value = rate_id, \
133 .flags = flag, \
134}
135
Gopichand Nakkala356fb102013-03-06 12:34:04 +0530136#ifdef WLAN_FEATURE_VOWIFI_11R
137#define WLAN_AKM_SUITE_FT_8021X 0x000FAC03
138#define WLAN_AKM_SUITE_FT_PSK 0x000FAC04
139#endif
140
Naresh Jayaram3180aa42014-02-12 21:47:26 +0530141#define HDD_CHANNEL_14 14
Dasari Srinivase18b2cf2014-10-28 17:09:42 +0530142#define WLAN_HDD_MAX_FEATURE_SET 8
Naresh Jayaram3180aa42014-02-12 21:47:26 +0530143
Sunil Duttc69bccb2014-05-26 21:30:20 +0530144#ifdef WLAN_FEATURE_LINK_LAYER_STATS
145/*
146 * Used to allocate the size of 4096 for the link layer stats.
147 * The size of 4096 is considered assuming that all data per
148 * respective event fit with in the limit.Please take a call
149 * on the limit based on the data requirements on link layer
150 * statistics.
151 */
152#define LL_STATS_EVENT_BUF_SIZE 4096
153#endif
Dino Mycle6fb96c12014-06-10 11:52:40 +0530154#ifdef WLAN_FEATURE_EXTSCAN
155/*
156 * Used to allocate the size of 4096 for the EXTScan NL data.
157 * The size of 4096 is considered assuming that all data per
158 * respective event fit with in the limit.Please take a call
159 * on the limit based on the data requirements.
160 */
161
162#define EXTSCAN_EVENT_BUF_SIZE 4096
163#define EXTSCAN_MAX_CACHED_RESULTS_PER_IND 32
164#endif
Sunil Duttc69bccb2014-05-26 21:30:20 +0530165
Atul Mittal115287b2014-07-08 13:26:33 +0530166/*EXT TDLS*/
167/*
168 * Used to allocate the size of 4096 for the TDLS.
169 * The size of 4096 is considered assuming that all data per
170 * respective event fit with in the limit.Please take a call
171 * on the limit based on the data requirements on link layer
172 * statistics.
173 */
174#define EXTTDLS_EVENT_BUF_SIZE 4096
175
Hanumantha Reddy Pothulaca1d1cc2015-10-26 15:37:35 +0530176/*
177 * Values for Mac spoofing feature
178 *
179 */
180#define MAC_ADDR_SPOOFING_FW_HOST_DISABLE 0
181#define MAC_ADDR_SPOOFING_FW_HOST_ENABLE 1
182#define MAC_ADDR_SPOOFING_FW_ENABLE_HOST_DISABLE 2
183
Gopichand Nakkala747461f2013-04-24 19:24:45 +0530184static const u32 hdd_cipher_suites[] =
Jeff Johnson295189b2012-06-20 16:38:30 -0700185{
186 WLAN_CIPHER_SUITE_WEP40,
187 WLAN_CIPHER_SUITE_WEP104,
188 WLAN_CIPHER_SUITE_TKIP,
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -0800189#ifdef FEATURE_WLAN_ESE
Jeff Johnson295189b2012-06-20 16:38:30 -0700190#define WLAN_CIPHER_SUITE_KRK 0x004096ff /* use for KRK */
191 WLAN_CIPHER_SUITE_KRK,
192 WLAN_CIPHER_SUITE_CCMP,
193#else
194 WLAN_CIPHER_SUITE_CCMP,
195#endif
196#ifdef FEATURE_WLAN_WAPI
197 WLAN_CIPHER_SUITE_SMS4,
198#endif
Chet Lanctot186b5732013-03-18 10:26:30 -0700199#ifdef WLAN_FEATURE_11W
200 WLAN_CIPHER_SUITE_AES_CMAC,
201#endif
Jeff Johnson295189b2012-06-20 16:38:30 -0700202};
203
204static inline int is_broadcast_ether_addr(const u8 *addr)
205{
206 return ((addr[0] == 0xff) && (addr[1] == 0xff) && (addr[2] == 0xff) &&
207 (addr[3] == 0xff) && (addr[4] == 0xff) && (addr[5] == 0xff));
208}
209
Agrawal Ashish97dec502015-11-26 20:20:58 +0530210const static struct ieee80211_channel hdd_channels_2_4_GHZ[] =
Gopichand Nakkala747461f2013-04-24 19:24:45 +0530211{
Jeff Johnson295189b2012-06-20 16:38:30 -0700212 HDD2GHZCHAN(2412, 1, 0) ,
213 HDD2GHZCHAN(2417, 2, 0) ,
214 HDD2GHZCHAN(2422, 3, 0) ,
215 HDD2GHZCHAN(2427, 4, 0) ,
216 HDD2GHZCHAN(2432, 5, 0) ,
217 HDD2GHZCHAN(2437, 6, 0) ,
218 HDD2GHZCHAN(2442, 7, 0) ,
219 HDD2GHZCHAN(2447, 8, 0) ,
220 HDD2GHZCHAN(2452, 9, 0) ,
221 HDD2GHZCHAN(2457, 10, 0) ,
222 HDD2GHZCHAN(2462, 11, 0) ,
223 HDD2GHZCHAN(2467, 12, 0) ,
224 HDD2GHZCHAN(2472, 13, 0) ,
225 HDD2GHZCHAN(2484, 14, 0) ,
226};
227
Agrawal Ashish97dec502015-11-26 20:20:58 +0530228const static struct ieee80211_channel hdd_channels_5_GHZ[] =
Jeff Johnson295189b2012-06-20 16:38:30 -0700229{
Madan Mohan Koyyalamudic3a240c2012-09-28 15:34:08 -0700230 HDD5GHZCHAN(4920, 240, 0) ,
231 HDD5GHZCHAN(4940, 244, 0) ,
232 HDD5GHZCHAN(4960, 248, 0) ,
233 HDD5GHZCHAN(4980, 252, 0) ,
234 HDD5GHZCHAN(5040, 208, 0) ,
235 HDD5GHZCHAN(5060, 212, 0) ,
236 HDD5GHZCHAN(5080, 216, 0) ,
Jeff Johnson295189b2012-06-20 16:38:30 -0700237 HDD5GHZCHAN(5180, 36, 0) ,
238 HDD5GHZCHAN(5200, 40, 0) ,
239 HDD5GHZCHAN(5220, 44, 0) ,
240 HDD5GHZCHAN(5240, 48, 0) ,
241 HDD5GHZCHAN(5260, 52, 0) ,
242 HDD5GHZCHAN(5280, 56, 0) ,
243 HDD5GHZCHAN(5300, 60, 0) ,
244 HDD5GHZCHAN(5320, 64, 0) ,
245 HDD5GHZCHAN(5500,100, 0) ,
246 HDD5GHZCHAN(5520,104, 0) ,
247 HDD5GHZCHAN(5540,108, 0) ,
248 HDD5GHZCHAN(5560,112, 0) ,
249 HDD5GHZCHAN(5580,116, 0) ,
250 HDD5GHZCHAN(5600,120, 0) ,
251 HDD5GHZCHAN(5620,124, 0) ,
252 HDD5GHZCHAN(5640,128, 0) ,
253 HDD5GHZCHAN(5660,132, 0) ,
254 HDD5GHZCHAN(5680,136, 0) ,
255 HDD5GHZCHAN(5700,140, 0) ,
Leo Chang80de3c22013-11-26 10:52:12 -0800256#ifdef FEATURE_WLAN_CH144
257 HDD5GHZCHAN(5720,144, 0) ,
258#endif /* FEATURE_WLAN_CH144 */
Jeff Johnson295189b2012-06-20 16:38:30 -0700259 HDD5GHZCHAN(5745,149, 0) ,
260 HDD5GHZCHAN(5765,153, 0) ,
261 HDD5GHZCHAN(5785,157, 0) ,
262 HDD5GHZCHAN(5805,161, 0) ,
263 HDD5GHZCHAN(5825,165, 0) ,
264};
265
266static struct ieee80211_rate g_mode_rates[] =
267{
Gopichand Nakkala747461f2013-04-24 19:24:45 +0530268 HDD_G_MODE_RATETAB(10, 0x1, 0),
269 HDD_G_MODE_RATETAB(20, 0x2, 0),
270 HDD_G_MODE_RATETAB(55, 0x4, 0),
271 HDD_G_MODE_RATETAB(110, 0x8, 0),
272 HDD_G_MODE_RATETAB(60, 0x10, 0),
273 HDD_G_MODE_RATETAB(90, 0x20, 0),
274 HDD_G_MODE_RATETAB(120, 0x40, 0),
275 HDD_G_MODE_RATETAB(180, 0x80, 0),
276 HDD_G_MODE_RATETAB(240, 0x100, 0),
277 HDD_G_MODE_RATETAB(360, 0x200, 0),
278 HDD_G_MODE_RATETAB(480, 0x400, 0),
Jeff Johnson295189b2012-06-20 16:38:30 -0700279 HDD_G_MODE_RATETAB(540, 0x800, 0),
Gopichand Nakkala747461f2013-04-24 19:24:45 +0530280};
Jeff Johnson295189b2012-06-20 16:38:30 -0700281
282static struct ieee80211_rate a_mode_rates[] =
283{
Gopichand Nakkala747461f2013-04-24 19:24:45 +0530284 HDD_G_MODE_RATETAB(60, 0x10, 0),
285 HDD_G_MODE_RATETAB(90, 0x20, 0),
286 HDD_G_MODE_RATETAB(120, 0x40, 0),
287 HDD_G_MODE_RATETAB(180, 0x80, 0),
288 HDD_G_MODE_RATETAB(240, 0x100, 0),
289 HDD_G_MODE_RATETAB(360, 0x200, 0),
290 HDD_G_MODE_RATETAB(480, 0x400, 0),
Jeff Johnson295189b2012-06-20 16:38:30 -0700291 HDD_G_MODE_RATETAB(540, 0x800, 0),
292};
293
294static struct ieee80211_supported_band wlan_hdd_band_2_4_GHZ =
295{
Agrawal Ashish97dec502015-11-26 20:20:58 +0530296 .channels = NULL,
Jeff Johnson295189b2012-06-20 16:38:30 -0700297 .n_channels = ARRAY_SIZE(hdd_channels_2_4_GHZ),
298 .band = IEEE80211_BAND_2GHZ,
299 .bitrates = g_mode_rates,
300 .n_bitrates = g_mode_rates_size,
301 .ht_cap.ht_supported = 1,
302 .ht_cap.cap = IEEE80211_HT_CAP_SGI_20
303 | IEEE80211_HT_CAP_GRN_FLD
304 | IEEE80211_HT_CAP_DSSSCCK40
305 | IEEE80211_HT_CAP_LSIG_TXOP_PROT,
306 .ht_cap.ampdu_factor = IEEE80211_HT_MAX_AMPDU_64K,
307 .ht_cap.ampdu_density = IEEE80211_HT_MPDU_DENSITY_16,
308 .ht_cap.mcs.rx_mask = { 0xff, 0, 0, 0, 0, 0, 0, 0, 0, 0, },
309 .ht_cap.mcs.rx_highest = cpu_to_le16( 72 ),
310 .ht_cap.mcs.tx_params = IEEE80211_HT_MCS_TX_DEFINED,
311};
312
Jeff Johnson295189b2012-06-20 16:38:30 -0700313static struct ieee80211_supported_band wlan_hdd_band_5_GHZ =
314{
Agrawal Ashish97dec502015-11-26 20:20:58 +0530315 .channels = NULL,
Jeff Johnson295189b2012-06-20 16:38:30 -0700316 .n_channels = ARRAY_SIZE(hdd_channels_5_GHZ),
317 .band = IEEE80211_BAND_5GHZ,
318 .bitrates = a_mode_rates,
319 .n_bitrates = a_mode_rates_size,
320 .ht_cap.ht_supported = 1,
321 .ht_cap.cap = IEEE80211_HT_CAP_SGI_20
322 | IEEE80211_HT_CAP_GRN_FLD
323 | IEEE80211_HT_CAP_DSSSCCK40
324 | IEEE80211_HT_CAP_LSIG_TXOP_PROT
325 | IEEE80211_HT_CAP_SGI_40
326 | IEEE80211_HT_CAP_SUP_WIDTH_20_40,
327 .ht_cap.ampdu_factor = IEEE80211_HT_MAX_AMPDU_64K,
328 .ht_cap.ampdu_density = IEEE80211_HT_MPDU_DENSITY_16,
329 .ht_cap.mcs.rx_mask = { 0xff, 0, 0, 0, 0, 0, 0, 0, 0, 0, },
330 .ht_cap.mcs.rx_highest = cpu_to_le16( 72 ),
331 .ht_cap.mcs.tx_params = IEEE80211_HT_MCS_TX_DEFINED,
332};
333
Gopichand Nakkala747461f2013-04-24 19:24:45 +0530334/* This structure contain information what kind of frame are expected in
Jeff Johnson295189b2012-06-20 16:38:30 -0700335 TX/RX direction for each kind of interface */
336static const struct ieee80211_txrx_stypes
337wlan_hdd_txrx_stypes[NUM_NL80211_IFTYPES] = {
338 [NL80211_IFTYPE_STATION] = {
339 .tx = 0xffff,
340 .rx = BIT(SIR_MAC_MGMT_ACTION) |
341 BIT(SIR_MAC_MGMT_PROBE_REQ),
342 },
343 [NL80211_IFTYPE_AP] = {
344 .tx = 0xffff,
345 .rx = BIT(SIR_MAC_MGMT_ASSOC_REQ) |
346 BIT(SIR_MAC_MGMT_REASSOC_REQ) |
347 BIT(SIR_MAC_MGMT_PROBE_REQ) |
348 BIT(SIR_MAC_MGMT_DISASSOC) |
349 BIT(SIR_MAC_MGMT_AUTH) |
350 BIT(SIR_MAC_MGMT_DEAUTH) |
351 BIT(SIR_MAC_MGMT_ACTION),
352 },
Jeff Johnsonbc006202013-04-29 14:05:30 -0700353 [NL80211_IFTYPE_ADHOC] = {
354 .tx = 0xffff,
355 .rx = BIT(SIR_MAC_MGMT_ASSOC_REQ) |
356 BIT(SIR_MAC_MGMT_REASSOC_REQ) |
357 BIT(SIR_MAC_MGMT_PROBE_REQ) |
358 BIT(SIR_MAC_MGMT_DISASSOC) |
359 BIT(SIR_MAC_MGMT_AUTH) |
360 BIT(SIR_MAC_MGMT_DEAUTH) |
361 BIT(SIR_MAC_MGMT_ACTION),
362 },
Jeff Johnson295189b2012-06-20 16:38:30 -0700363 [NL80211_IFTYPE_P2P_CLIENT] = {
364 .tx = 0xffff,
365 .rx = BIT(SIR_MAC_MGMT_ACTION) |
366 BIT(SIR_MAC_MGMT_PROBE_REQ),
367 },
368 [NL80211_IFTYPE_P2P_GO] = {
369 /* This is also same as for SoftAP */
370 .tx = 0xffff,
371 .rx = BIT(SIR_MAC_MGMT_ASSOC_REQ) |
372 BIT(SIR_MAC_MGMT_REASSOC_REQ) |
373 BIT(SIR_MAC_MGMT_PROBE_REQ) |
374 BIT(SIR_MAC_MGMT_DISASSOC) |
375 BIT(SIR_MAC_MGMT_AUTH) |
376 BIT(SIR_MAC_MGMT_DEAUTH) |
377 BIT(SIR_MAC_MGMT_ACTION),
378 },
Jeff Johnson295189b2012-06-20 16:38:30 -0700379};
380
Sudhir Sattayappa Kohalli278eee52013-01-16 17:35:13 -0800381#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,4,0))
Sudhir Sattayappa Kohalli278eee52013-01-16 17:35:13 -0800382static const struct ieee80211_iface_limit
383wlan_hdd_iface_limit[] = {
384 {
Sunil Ravia72c3992013-01-31 06:12:22 -0800385 /* max = 3 ; Our driver create two interfaces during driver init
386 * wlan0 and p2p0 interfaces. p2p0 is considered as station
387 * interface until a group is formed. In JB architecture, once the
388 * group is formed, interface type of p2p0 is changed to P2P GO or
389 * Client.
390 * When supplicant remove the group, it first issue a set interface
391 * cmd to change the mode back to Station. In JB this works fine as
392 * we advertize two station type interface during driver init.
393 * Some vendors create separate interface for P2P GO/Client,
394 * after group formation(Third one). But while group remove
395 * supplicant first tries to change the mode(3rd interface) to STATION
396 * But as we advertized only two sta type interfaces nl80211 was
397 * returning error for the third one which was leading to failure in
398 * delete interface. Ideally while removing the group, supplicant
399 * should not try to change the 3rd interface mode to Station type.
400 * Till we get a fix in wpa_supplicant, we advertize max STA
401 * interface type to 3
402 */
403 .max = 3,
Sudhir Sattayappa Kohalli278eee52013-01-16 17:35:13 -0800404 .types = BIT(NL80211_IFTYPE_STATION),
405 },
406 {
407 .max = 1,
Jeff Johnsonbc006202013-04-29 14:05:30 -0700408 .types = BIT(NL80211_IFTYPE_ADHOC) | BIT(NL80211_IFTYPE_AP),
Sudhir Sattayappa Kohalli278eee52013-01-16 17:35:13 -0800409 },
410 {
411 .max = 1,
412 .types = BIT(NL80211_IFTYPE_P2P_GO) |
413 BIT(NL80211_IFTYPE_P2P_CLIENT),
414 },
415};
416
417/* By default, only single channel concurrency is allowed */
418static struct ieee80211_iface_combination
419wlan_hdd_iface_combination = {
420 .limits = wlan_hdd_iface_limit,
421 .num_different_channels = 1,
Sunil Ravia72c3992013-01-31 06:12:22 -0800422 /*
423 * max = WLAN_MAX_INTERFACES ; JellyBean architecture creates wlan0
424 * and p2p0 interfaces during driver init
425 * Some vendors create separate interface for P2P operations.
426 * wlan0: STA interface
427 * p2p0: P2P Device interface, action frames goes
428 * through this interface.
429 * p2p-xx: P2P interface, After GO negotiation this interface is
430 * created for p2p operations(GO/CLIENT interface).
431 */
432 .max_interfaces = WLAN_MAX_INTERFACES,
Sudhir Sattayappa Kohalli278eee52013-01-16 17:35:13 -0800433 .n_limits = ARRAY_SIZE(wlan_hdd_iface_limit),
434 .beacon_int_infra_match = false,
435};
436#endif
Sudhir Sattayappa Kohalli278eee52013-01-16 17:35:13 -0800437
Jeff Johnson295189b2012-06-20 16:38:30 -0700438static struct cfg80211_ops wlan_hdd_cfg80211_ops;
439
440/* Data rate 100KBPS based on IE Index */
441struct index_data_rate_type
442{
443 v_U8_t beacon_rate_index;
444 v_U16_t supported_rate[4];
445};
446
447/* 11B, 11G Rate table include Basic rate and Extended rate
448 The IDX field is the rate index
449 The HI field is the rate when RSSI is strong or being ignored
450 (in this case we report actual rate)
451 The MID field is the rate when RSSI is moderate
452 (in this case we cap 11b rates at 5.5 and 11g rates at 24)
453 The LO field is the rate when RSSI is low
454 (in this case we don't report rates, actual current rate used)
455 */
456static const struct
457{
458 v_U8_t beacon_rate_index;
Madan Mohan Koyyalamudi8df78d52012-11-02 12:30:06 -0700459 v_U16_t supported_rate[4];
Jeff Johnson295189b2012-06-20 16:38:30 -0700460} supported_data_rate[] =
461{
Madan Mohan Koyyalamudi8df78d52012-11-02 12:30:06 -0700462/* IDX HI HM LM LO (RSSI-based index */
463 {2, { 10, 10, 10, 0}},
464 {4, { 20, 20, 10, 0}},
465 {11, { 55, 20, 10, 0}},
466 {12, { 60, 55, 20, 0}},
467 {18, { 90, 55, 20, 0}},
468 {22, {110, 55, 20, 0}},
469 {24, {120, 90, 60, 0}},
470 {36, {180, 120, 60, 0}},
471 {44, {220, 180, 60, 0}},
472 {48, {240, 180, 90, 0}},
473 {66, {330, 180, 90, 0}},
474 {72, {360, 240, 90, 0}},
475 {96, {480, 240, 120, 0}},
476 {108, {540, 240, 120, 0}}
Jeff Johnson295189b2012-06-20 16:38:30 -0700477};
478
479/* MCS Based rate table */
480static struct index_data_rate_type supported_mcs_rate[] =
481{
482/* MCS L20 L40 S20 S40 */
483 {0, {65, 135, 72, 150}},
484 {1, {130, 270, 144, 300}},
485 {2, {195, 405, 217, 450}},
486 {3, {260, 540, 289, 600}},
487 {4, {390, 810, 433, 900}},
488 {5, {520, 1080, 578, 1200}},
489 {6, {585, 1215, 650, 1350}},
490 {7, {650, 1350, 722, 1500}}
491};
492
Leo Chang6f8870f2013-03-26 18:11:36 -0700493#ifdef WLAN_FEATURE_11AC
494
Gopichand Nakkala4c705372013-04-24 13:20:33 +0530495#define DATA_RATE_11AC_MCS_MASK 0x03
Leo Chang6f8870f2013-03-26 18:11:36 -0700496
497struct index_vht_data_rate_type
498{
499 v_U8_t beacon_rate_index;
Gopichand Nakkala4c705372013-04-24 13:20:33 +0530500 v_U16_t supported_VHT80_rate[2];
501 v_U16_t supported_VHT40_rate[2];
502 v_U16_t supported_VHT20_rate[2];
Leo Chang6f8870f2013-03-26 18:11:36 -0700503};
504
505typedef enum
506{
507 DATA_RATE_11AC_MAX_MCS_7,
508 DATA_RATE_11AC_MAX_MCS_8,
509 DATA_RATE_11AC_MAX_MCS_9,
510 DATA_RATE_11AC_MAX_MCS_NA
511} eDataRate11ACMaxMcs;
512
Mahesh A Saptasagar7bd6ad42014-07-21 18:56:33 +0530513/* SSID broadcast type */
514typedef enum eSSIDBcastType
515{
516 eBCAST_UNKNOWN = 0,
517 eBCAST_NORMAL = 1,
518 eBCAST_HIDDEN = 2,
519} tSSIDBcastType;
520
Leo Chang6f8870f2013-03-26 18:11:36 -0700521/* MCS Based VHT rate table */
522static struct index_vht_data_rate_type supported_vht_mcs_rate[] =
523{
Gopichand Nakkala4c705372013-04-24 13:20:33 +0530524/* MCS L80 S80 L40 S40 L20 S40*/
525 {0, {293, 325}, {135, 150}, {65, 72}},
526 {1, {585, 650}, {270, 300}, {130, 144}},
527 {2, {878, 975}, {405, 450}, {195, 217}},
528 {3, {1170, 1300}, {540, 600}, {260, 289}},
529 {4, {1755, 1950}, {810, 900}, {390, 433}},
530 {5, {2340, 2600}, {1080, 1200}, {520, 578}},
531 {6, {2633, 2925}, {1215, 1350}, {585, 650}},
532 {7, {2925, 3250}, {1350, 1500}, {650, 722}},
533 {8, {3510, 3900}, {1620, 1800}, {780, 867}},
534 {9, {3900, 4333}, {1800, 2000}, {780, 867}}
Leo Chang6f8870f2013-03-26 18:11:36 -0700535};
536#endif /* WLAN_FEATURE_11AC */
537
c_hpothu79aab322014-07-14 21:11:01 +0530538/*array index points to MCS and array value points respective rssi*/
539static int rssiMcsTbl[][10] =
540{
541/*MCS 0 1 2 3 4 5 6 7 8 9*/
542 {-82, -79, -77, -74, -70, -66, -65, -64, -59, -57}, //20
543 {-79, -76, -74, -71, -67, -63, -62, -61, -56, -54}, //40
544 {-76, -73, -71, -68, -64, -60, -59, -58, -53, -51} //80
545};
546
Jeff Johnson295189b2012-06-20 16:38:30 -0700547extern struct net_device_ops net_ops_struct;
Dasari Srinivas7875a302014-09-26 17:50:57 +0530548#ifdef FEATURE_WLAN_SCAN_PNO
549static eHalStatus wlan_hdd_is_pno_allowed(hdd_adapter_t *pAdapter);
550#endif
Jeff Johnson295189b2012-06-20 16:38:30 -0700551
Leo Chang9056f462013-08-01 19:21:11 -0700552#ifdef WLAN_NL80211_TESTMODE
553enum wlan_hdd_tm_attr
554{
555 WLAN_HDD_TM_ATTR_INVALID = 0,
556 WLAN_HDD_TM_ATTR_CMD = 1,
557 WLAN_HDD_TM_ATTR_DATA = 2,
558 WLAN_HDD_TM_ATTR_TYPE = 3,
559 /* keep last */
560 WLAN_HDD_TM_ATTR_AFTER_LAST,
561 WLAN_HDD_TM_ATTR_MAX = WLAN_HDD_TM_ATTR_AFTER_LAST - 1,
562};
563
564enum wlan_hdd_tm_cmd
565{
566 WLAN_HDD_TM_CMD_WLAN_HB = 1,
567};
568
569#define WLAN_HDD_TM_DATA_MAX_LEN 5000
570
571static const struct nla_policy wlan_hdd_tm_policy[WLAN_HDD_TM_ATTR_MAX + 1] =
572{
573 [WLAN_HDD_TM_ATTR_CMD] = { .type = NLA_U32 },
574 [WLAN_HDD_TM_ATTR_DATA] = { .type = NLA_BINARY,
575 .len = WLAN_HDD_TM_DATA_MAX_LEN },
576};
577#endif /* WLAN_NL80211_TESTMODE */
578
Rajesh Chauhan98a31f82014-01-06 20:15:25 -0800579#ifdef FEATURE_WLAN_CH_AVOID
580/*
581 * FUNCTION: wlan_hdd_send_avoid_freq_event
582 * This is called when wlan driver needs to send vendor specific
583 * avoid frequency range event to userspace
584 */
585int wlan_hdd_send_avoid_freq_event(hdd_context_t *pHddCtx,
586 tHddAvoidFreqList *pAvoidFreqList)
587{
588 struct sk_buff *vendor_event;
589
590 ENTER();
591
592 if (!pHddCtx)
593 {
594 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
595 "%s: HDD context is null", __func__);
596 return -1;
597 }
598
599 if (!pAvoidFreqList)
600 {
601 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
602 "%s: pAvoidFreqList is null", __func__);
603 return -1;
604 }
605
606 vendor_event = cfg80211_vendor_event_alloc(pHddCtx->wiphy,
Anand N Sunkad26ca6cc2015-07-29 09:54:52 +0530607#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 18, 0))
608 NULL,
609#endif
Rajesh Chauhan98a31f82014-01-06 20:15:25 -0800610 sizeof(tHddAvoidFreqList),
Sunil Duttc69bccb2014-05-26 21:30:20 +0530611 QCA_NL80211_VENDOR_SUBCMD_AVOID_FREQUENCY_INDEX,
Rajesh Chauhan98a31f82014-01-06 20:15:25 -0800612 GFP_KERNEL);
613 if (!vendor_event)
614 {
615 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
616 "%s: cfg80211_vendor_event_alloc failed", __func__);
617 return -1;
618 }
619
620 memcpy(skb_put(vendor_event, sizeof(tHddAvoidFreqList)),
621 (void *)pAvoidFreqList, sizeof(tHddAvoidFreqList));
622
623 cfg80211_vendor_event(vendor_event, GFP_KERNEL);
624
625 EXIT();
626 return 0;
627}
628#endif /* FEATURE_WLAN_CH_AVOID */
629
Srinivas Dasari030bad32015-02-18 23:23:54 +0530630/*
631 * FUNCTION: __wlan_hdd_cfg80211_nan_request
632 * This is called when wlan driver needs to send vendor specific
633 * nan request event.
634 */
635static int __wlan_hdd_cfg80211_nan_request(struct wiphy *wiphy,
636 struct wireless_dev *wdev,
637 const void *data, int data_len)
638{
639 tNanRequestReq nan_req;
640 VOS_STATUS status;
641 int ret_val = -1;
Srinivas Dasaria3f11c02015-03-20 13:15:20 +0530642 struct net_device *dev = wdev->netdev;
643 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
644 tHalHandle hHal = WLAN_HDD_GET_HAL_CTX(pAdapter);
Srinivas Dasari030bad32015-02-18 23:23:54 +0530645 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
646
647 if (0 == data_len)
648 {
649 hddLog(VOS_TRACE_LEVEL_ERROR,
650 FL("NAN - Invalid Request, length = 0"));
651 return ret_val;
652 }
653
654 if (NULL == data)
655 {
656 hddLog(VOS_TRACE_LEVEL_ERROR,
657 FL("NAN - Invalid Request, data is NULL"));
658 return ret_val;
659 }
660
661 status = wlan_hdd_validate_context(pHddCtx);
662 if (0 != status)
663 {
664 hddLog(VOS_TRACE_LEVEL_ERROR,
665 FL("HDD context is not valid"));
666 return -EINVAL;
667 }
668
669 hddLog(LOG1, FL("Received NAN command"));
670 vos_trace_hex_dump( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
671 (tANI_U8 *)data, data_len);
672
673 /* check the NAN Capability */
674 if (TRUE != sme_IsFeatureSupportedByFW(NAN))
675 {
676 hddLog(VOS_TRACE_LEVEL_ERROR,
677 FL("NAN is not supported by Firmware"));
678 return -EINVAL;
679 }
680
681 nan_req.request_data_len = data_len;
682 nan_req.request_data = data;
683
Srinivas Dasaria3f11c02015-03-20 13:15:20 +0530684 status = sme_NanRequest(hHal, &nan_req, pAdapter->sessionId);
Srinivas Dasari030bad32015-02-18 23:23:54 +0530685 if (VOS_STATUS_SUCCESS == status)
686 {
687 ret_val = 0;
688 }
689 return ret_val;
690}
691
692/*
693 * FUNCTION: wlan_hdd_cfg80211_nan_request
694 * Wrapper to protect the nan vendor command from ssr
695 */
696static int wlan_hdd_cfg80211_nan_request(struct wiphy *wiphy,
697 struct wireless_dev *wdev,
698 const void *data, int data_len)
699{
700 int ret;
701
702 vos_ssr_protect(__func__);
703 ret = __wlan_hdd_cfg80211_nan_request(wiphy, wdev, data, data_len);
704 vos_ssr_unprotect(__func__);
705
706 return ret;
707}
708
709/*
710 * FUNCTION: wlan_hdd_cfg80211_nan_callback
711 * This is a callback function and it gets called
712 * when we need to report nan response event to
713 * upper layers.
714 */
715static void wlan_hdd_cfg80211_nan_callback(void* ctx, tSirNanEvent* msg)
716{
717 hdd_context_t *pHddCtx = (hdd_context_t *)ctx;
718 struct sk_buff *vendor_event;
719 int status;
720 tSirNanEvent *data;
721
722 ENTER();
723 if (NULL == msg)
724 {
725 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
726 FL(" msg received here is null"));
727 return;
728 }
729 data = msg;
730
731 status = wlan_hdd_validate_context(pHddCtx);
732
733 if (0 != status)
734 {
735 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
736 FL("HDD context is not valid"));
737 return;
738 }
739
740 vendor_event = cfg80211_vendor_event_alloc(pHddCtx->wiphy,
Anand N Sunkad26ca6cc2015-07-29 09:54:52 +0530741#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 18, 0))
742 NULL,
743#endif
Srinivas Dasari030bad32015-02-18 23:23:54 +0530744 data->event_data_len +
745 NLMSG_HDRLEN,
746 QCA_NL80211_VENDOR_SUBCMD_NAN_INDEX,
747 GFP_KERNEL);
748
749 if (!vendor_event)
750 {
751 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
752 FL("cfg80211_vendor_event_alloc failed"));
753 return;
754 }
755 if (nla_put(vendor_event, QCA_WLAN_VENDOR_ATTR_NAN,
756 data->event_data_len, data->event_data))
757 {
758 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
759 FL("QCA_WLAN_VENDOR_ATTR_NAN put fail"));
760 kfree_skb(vendor_event);
761 return;
762 }
763 cfg80211_vendor_event(vendor_event, GFP_KERNEL);
764 EXIT();
765}
766
767/*
768 * FUNCTION: wlan_hdd_cfg80211_nan_init
769 * This function is called to register the callback to sme layer
770 */
771inline void wlan_hdd_cfg80211_nan_init(hdd_context_t *pHddCtx)
772{
773 sme_NanRegisterCallback(pHddCtx->hHal, wlan_hdd_cfg80211_nan_callback);
774}
775
776
Sunil Duttc69bccb2014-05-26 21:30:20 +0530777#ifdef WLAN_FEATURE_LINK_LAYER_STATS
778
779static v_BOOL_t put_wifi_rate_stat( tpSirWifiRateStat stats,
780 struct sk_buff *vendor_event)
781{
782 if (nla_put_u8(vendor_event,
783 QCA_WLAN_VENDOR_ATTR_LL_STATS_RATE_PREAMBLE,
784 stats->rate.preamble) ||
785 nla_put_u8(vendor_event,
786 QCA_WLAN_VENDOR_ATTR_LL_STATS_RATE_NSS,
787 stats->rate.nss) ||
788 nla_put_u8(vendor_event,
789 QCA_WLAN_VENDOR_ATTR_LL_STATS_RATE_BW,
790 stats->rate.bw) ||
791 nla_put_u8(vendor_event,
792 QCA_WLAN_VENDOR_ATTR_LL_STATS_RATE_MCS_INDEX,
793 stats->rate.rateMcsIdx) ||
794 nla_put_u32(vendor_event, QCA_WLAN_VENDOR_ATTR_LL_STATS_RATE_BIT_RATE,
795 stats->rate.bitrate ) ||
796 nla_put_u32(vendor_event, QCA_WLAN_VENDOR_ATTR_LL_STATS_RATE_TX_MPDU,
797 stats->txMpdu ) ||
798 nla_put_u32(vendor_event, QCA_WLAN_VENDOR_ATTR_LL_STATS_RATE_RX_MPDU,
799 stats->rxMpdu ) ||
800 nla_put_u32(vendor_event, QCA_WLAN_VENDOR_ATTR_LL_STATS_RATE_MPDU_LOST,
801 stats->mpduLost ) ||
802 nla_put_u32(vendor_event, QCA_WLAN_VENDOR_ATTR_LL_STATS_RATE_RETRIES,
803 stats->retries) ||
804 nla_put_u32(vendor_event,
805 QCA_WLAN_VENDOR_ATTR_LL_STATS_RATE_RETRIES_SHORT,
806 stats->retriesShort ) ||
807 nla_put_u32(vendor_event,
808 QCA_WLAN_VENDOR_ATTR_LL_STATS_RATE_RETRIES_LONG,
809 stats->retriesLong))
810 {
811 hddLog(VOS_TRACE_LEVEL_ERROR,
812 FL("QCA_WLAN_VENDOR_ATTR put fail"));
813 return FALSE;
814 }
815 return TRUE;
816}
817
818static v_BOOL_t put_wifi_peer_info( tpSirWifiPeerInfo stats,
819 struct sk_buff *vendor_event)
820{
821 u32 i = 0;
822 struct nlattr *rateInfo;
823 if (nla_put_u32(vendor_event, QCA_WLAN_VENDOR_ATTR_LL_STATS_PEER_INFO_TYPE,
824 stats->type) ||
825 nla_put(vendor_event,
826 QCA_WLAN_VENDOR_ATTR_LL_STATS_PEER_INFO_MAC_ADDRESS,
827 VOS_MAC_ADDR_SIZE, &stats->peerMacAddress[0]) ||
828 nla_put_u32(vendor_event,
829 QCA_WLAN_VENDOR_ATTR_LL_STATS_PEER_INFO_CAPABILITIES,
830 stats->capabilities) ||
831 nla_put_u32(vendor_event,
832 QCA_WLAN_VENDOR_ATTR_LL_STATS_PEER_INFO_NUM_RATES,
833 stats->numRate))
834 {
835 hddLog(VOS_TRACE_LEVEL_ERROR,
836 FL("QCA_WLAN_VENDOR_ATTR put fail"));
837 goto error;
838 }
839
840 rateInfo = nla_nest_start(vendor_event,
841 QCA_WLAN_VENDOR_ATTR_LL_STATS_PEER_INFO_RATE_INFO);
Sushant Kaushikee1f55e2015-01-22 11:27:01 +0530842 if(!rateInfo)
843 return FALSE;
Sunil Duttc69bccb2014-05-26 21:30:20 +0530844 for (i = 0; i < stats->numRate; i++)
845 {
846 struct nlattr *rates;
847 tpSirWifiRateStat pRateStats = (tpSirWifiRateStat )((uint8 *)
848 stats->rateStats +
849 (i * sizeof(tSirWifiRateStat)));
850 rates = nla_nest_start(vendor_event, i);
Sushant Kaushikee1f55e2015-01-22 11:27:01 +0530851 if(!rates)
852 return FALSE;
Sunil Duttc69bccb2014-05-26 21:30:20 +0530853
854 if (FALSE == put_wifi_rate_stat(pRateStats, vendor_event))
855 {
856 hddLog(VOS_TRACE_LEVEL_ERROR,
857 FL("QCA_WLAN_VENDOR_ATTR put fail"));
858 return FALSE;
859 }
860 nla_nest_end(vendor_event, rates);
861 }
862 nla_nest_end(vendor_event, rateInfo);
863
864 return TRUE;
865error:
866 return FALSE;
867}
868
869static v_BOOL_t put_wifi_wmm_ac_stat( tpSirWifiWmmAcStat stats,
870 struct sk_buff *vendor_event)
871{
872 if (nla_put_u32(vendor_event, QCA_WLAN_VENDOR_ATTR_LL_STATS_WMM_AC_AC,
873 stats->ac ) ||
874 nla_put_u32(vendor_event,
875 QCA_WLAN_VENDOR_ATTR_LL_STATS_WMM_AC_TX_MPDU,
876 stats->txMpdu ) ||
877 nla_put_u32(vendor_event,
878 QCA_WLAN_VENDOR_ATTR_LL_STATS_WMM_AC_RX_MPDU,
879 stats->rxMpdu ) ||
880 nla_put_u32(vendor_event,
881 QCA_WLAN_VENDOR_ATTR_LL_STATS_WMM_AC_TX_MCAST,
882 stats->txMcast ) ||
883 nla_put_u32(vendor_event,
884 QCA_WLAN_VENDOR_ATTR_LL_STATS_WMM_AC_RX_MCAST,
885 stats->rxMcast ) ||
886 nla_put_u32(vendor_event,
887 QCA_WLAN_VENDOR_ATTR_LL_STATS_WMM_AC_RX_AMPDU,
888 stats->rxAmpdu ) ||
889 nla_put_u32(vendor_event,
890 QCA_WLAN_VENDOR_ATTR_LL_STATS_WMM_AC_TX_AMPDU,
891 stats->txAmpdu ) ||
892 nla_put_u32(vendor_event,
893 QCA_WLAN_VENDOR_ATTR_LL_STATS_WMM_AC_MPDU_LOST,
894 stats->mpduLost )||
895 nla_put_u32(vendor_event,
896 QCA_WLAN_VENDOR_ATTR_LL_STATS_WMM_AC_RETRIES,
897 stats->retries ) ||
898 nla_put_u32(vendor_event,
899 QCA_WLAN_VENDOR_ATTR_LL_STATS_WMM_AC_RETRIES_SHORT,
900 stats->retriesShort ) ||
901 nla_put_u32(vendor_event,
902 QCA_WLAN_VENDOR_ATTR_LL_STATS_WMM_AC_RETRIES_LONG,
903 stats->retriesLong ) ||
904 nla_put_u32(vendor_event,
905 QCA_WLAN_VENDOR_ATTR_LL_STATS_WMM_AC_CONTENTION_TIME_MIN,
906 stats->contentionTimeMin ) ||
907 nla_put_u32(vendor_event,
908 QCA_WLAN_VENDOR_ATTR_LL_STATS_WMM_AC_CONTENTION_TIME_MAX,
909 stats->contentionTimeMax ) ||
910 nla_put_u32(vendor_event,
911 QCA_WLAN_VENDOR_ATTR_LL_STATS_WMM_AC_CONTENTION_TIME_AVG,
912 stats->contentionTimeAvg ) ||
913 nla_put_u32(vendor_event,
914 QCA_WLAN_VENDOR_ATTR_LL_STATS_WMM_AC_CONTENTION_NUM_SAMPLES,
915 stats->contentionNumSamples ))
916 {
917 hddLog(VOS_TRACE_LEVEL_ERROR,
918 FL("QCA_WLAN_VENDOR_ATTR put fail") );
919 return FALSE;
920 }
921 return TRUE;
922}
923
924static v_BOOL_t put_wifi_interface_info(tpSirWifiInterfaceInfo stats,
925 struct sk_buff *vendor_event)
926{
Dino Myclec8f3f332014-07-21 16:48:27 +0530927 if (nla_put_s32(vendor_event,
Sunil Duttc69bccb2014-05-26 21:30:20 +0530928 QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_INFO_MODE, stats->mode ) ||
929 nla_put(vendor_event,
930 QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_INFO_MAC_ADDR,
931 VOS_MAC_ADDR_SIZE, stats->macAddr) ||
932 nla_put_u32(vendor_event,
933 QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_INFO_STATE,
934 stats->state ) ||
935 nla_put_u32(vendor_event,
936 QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_INFO_ROAMING,
937 stats->roaming ) ||
938 nla_put_u32(vendor_event,
939 QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_INFO_CAPABILITIES,
940 stats->capabilities ) ||
941 nla_put(vendor_event,
942 QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_INFO_SSID,
943 strlen(stats->ssid), stats->ssid) ||
944 nla_put(vendor_event,
945 QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_INFO_BSSID,
946 WNI_CFG_BSSID_LEN, stats->bssid) ||
947 nla_put(vendor_event,
948 QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_INFO_AP_COUNTRY_STR,
949 WNI_CFG_COUNTRY_CODE_LEN, stats->apCountryStr) ||
950 nla_put(vendor_event,
951 QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_INFO_COUNTRY_STR,
952 WNI_CFG_COUNTRY_CODE_LEN, stats->countryStr)
953 )
954 {
955 hddLog(VOS_TRACE_LEVEL_ERROR,
956 FL("QCA_WLAN_VENDOR_ATTR put fail") );
957 return FALSE;
958 }
959 return TRUE;
960}
961
Dino Mycle3b9536d2014-07-09 22:05:24 +0530962static v_BOOL_t put_wifi_iface_stats(hdd_adapter_t *pAdapter,
963 tpSirWifiIfaceStat pWifiIfaceStat,
Sunil Duttc69bccb2014-05-26 21:30:20 +0530964 struct sk_buff *vendor_event)
965{
966 int i = 0;
967 struct nlattr *wmmInfo;
Dino Mycle3b9536d2014-07-09 22:05:24 +0530968 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
969 WLANTL_InterfaceStatsType *pWifiIfaceStatTL = NULL;
Srinivas Dasaria8a304f2014-11-15 16:13:37 +0530970 tSirWifiWmmAcStat accessclassStats;
Dino Mycle3b9536d2014-07-09 22:05:24 +0530971
Sunil Duttc69bccb2014-05-26 21:30:20 +0530972 if (FALSE == put_wifi_interface_info(
973 &pWifiIfaceStat->info,
974 vendor_event))
975 {
976 hddLog(VOS_TRACE_LEVEL_ERROR,
977 FL("QCA_WLAN_VENDOR_ATTR put fail") );
978 return FALSE;
979
980 }
Dino Mycle3b9536d2014-07-09 22:05:24 +0530981 pWifiIfaceStatTL = (WLANTL_InterfaceStatsType *)
982 vos_mem_malloc(sizeof(WLANTL_InterfaceStatsType));
983 if (NULL == pWifiIfaceStatTL)
984 {
985 hddLog(VOS_TRACE_LEVEL_ERROR, FL("vos_mem_malloc failed"));
986 return FALSE;
987 }
988
Srinivas Dasaria8a304f2014-11-15 16:13:37 +0530989 accessclassStats = pWifiIfaceStat->AccessclassStats[WIFI_AC_BK];
990 pWifiIfaceStat->AccessclassStats[WIFI_AC_BK] =
991 pWifiIfaceStat->AccessclassStats[WIFI_AC_BE];
992 pWifiIfaceStat->AccessclassStats[WIFI_AC_BE] = accessclassStats;
993
994 accessclassStats.ac = pWifiIfaceStat->AccessclassStats[WIFI_AC_BK].ac;
995 pWifiIfaceStat->AccessclassStats[WIFI_AC_BK].ac =
996 pWifiIfaceStat->AccessclassStats[WIFI_AC_BE].ac;
997 pWifiIfaceStat->AccessclassStats[WIFI_AC_BE].ac = accessclassStats.ac;
Dino Mycle3b9536d2014-07-09 22:05:24 +0530998
999 if ( pWifiIfaceStat->info.state == WIFI_ASSOCIATED)
1000 {
1001 if (VOS_STATUS_SUCCESS ==
1002 WLANTL_CollectInterfaceStats((WLAN_HDD_GET_CTX(pAdapter))->pvosContext,
1003 pHddStaCtx->conn_info.staId[0], pWifiIfaceStatTL))
1004 {
1005 /* mgmtRx, MgmtActionRx, rxMcast, rxMpdu, rxAmpdu, rssiData are
1006 * obtained from TL structure
1007 */
1008
1009 pWifiIfaceStat->mgmtRx = pWifiIfaceStat->beaconRx +
1010 pWifiIfaceStatTL->mgmtRx;
Dino Mycle3b9536d2014-07-09 22:05:24 +05301011 pWifiIfaceStat->rssiData = pWifiIfaceStatTL->rssiData;
1012
Srinivas Dasari98947432014-11-07 19:41:24 +05301013 pWifiIfaceStat->AccessclassStats[WIFI_AC_VO].rxMcast
1014 = pWifiIfaceStatTL->accessCategoryStats[WLANTL_AC_VO].rxMcast;
1015 pWifiIfaceStat->AccessclassStats[WIFI_AC_VI].rxMcast
1016 = pWifiIfaceStatTL->accessCategoryStats[WLANTL_AC_VI].rxMcast;
1017 pWifiIfaceStat->AccessclassStats[WIFI_AC_BE].rxMcast
1018 = pWifiIfaceStatTL->accessCategoryStats[WLANTL_AC_BE].rxMcast;
1019 pWifiIfaceStat->AccessclassStats[WIFI_AC_BK].rxMcast
1020 = pWifiIfaceStatTL->accessCategoryStats[WLANTL_AC_BK].rxMcast;
Dino Mycle3b9536d2014-07-09 22:05:24 +05301021
Srinivas Dasari98947432014-11-07 19:41:24 +05301022 pWifiIfaceStat->AccessclassStats[WIFI_AC_VO].rxMpdu
1023 = pWifiIfaceStatTL->accessCategoryStats[WLANTL_AC_VO].rxMpdu;
1024 pWifiIfaceStat->AccessclassStats[WIFI_AC_VI].rxMpdu
1025 = pWifiIfaceStatTL->accessCategoryStats[WLANTL_AC_VI].rxMpdu;
1026 pWifiIfaceStat->AccessclassStats[WIFI_AC_BE].rxMpdu
1027 = pWifiIfaceStatTL->accessCategoryStats[WLANTL_AC_BE].rxMpdu;
1028 pWifiIfaceStat->AccessclassStats[WIFI_AC_BK].rxMpdu
1029 = pWifiIfaceStatTL->accessCategoryStats[WLANTL_AC_BK].rxMpdu;
Dino Mycle3b9536d2014-07-09 22:05:24 +05301030
Srinivas Dasari98947432014-11-07 19:41:24 +05301031 pWifiIfaceStat->AccessclassStats[WIFI_AC_VO].rxAmpdu
1032 = pWifiIfaceStatTL->accessCategoryStats[WLANTL_AC_VO].rxAmpdu;
1033 pWifiIfaceStat->AccessclassStats[WIFI_AC_VI].rxAmpdu
1034 = pWifiIfaceStatTL->accessCategoryStats[WLANTL_AC_VI].rxAmpdu;
1035 pWifiIfaceStat->AccessclassStats[WIFI_AC_BE].rxAmpdu
1036 = pWifiIfaceStatTL->accessCategoryStats[WLANTL_AC_BE].rxAmpdu;
1037 pWifiIfaceStat->AccessclassStats[WIFI_AC_BK].rxAmpdu
1038 = pWifiIfaceStatTL->accessCategoryStats[WLANTL_AC_BK].rxAmpdu;
Dino Mycle3b9536d2014-07-09 22:05:24 +05301039 }
1040 else
1041 {
1042 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Error in getting stats from TL"));
1043 }
1044
Dino Mycle3b9536d2014-07-09 22:05:24 +05301045 pWifiIfaceStat->AccessclassStats[WIFI_AC_VO].txMcast =
1046 pAdapter->hdd_stats.hddTxRxStats.txMcast[WLANTL_AC_VO];
1047 pWifiIfaceStat->AccessclassStats[WIFI_AC_VI].txMcast =
1048 pAdapter->hdd_stats.hddTxRxStats.txMcast[WLANTL_AC_VI];
1049 pWifiIfaceStat->AccessclassStats[WIFI_AC_BE].txMcast =
1050 pAdapter->hdd_stats.hddTxRxStats.txMcast[WLANTL_AC_BE];
1051 pWifiIfaceStat->AccessclassStats[WIFI_AC_BK].txMcast =
1052 pAdapter->hdd_stats.hddTxRxStats.txMcast[WLANTL_AC_BK];
1053 }
1054 else
1055 {
1056 hddLog(VOS_TRACE_LEVEL_INFO, FL("Interface not Associated"));
1057 }
1058
1059
Sunil Duttc69bccb2014-05-26 21:30:20 +05301060
1061 if (nla_put_u32(vendor_event,
mukul sharma4bd8d2e2015-08-13 20:33:25 +05301062 QCA_WLAN_VENDOR_ATTR_LL_STATS_TYPE,
1063 QCA_WLAN_VENDOR_ATTR_LL_STATS_TYPE_IFACE) ||
1064 nla_put_u32(vendor_event,
Sunil Duttc69bccb2014-05-26 21:30:20 +05301065 QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_BEACON_RX,
1066 pWifiIfaceStat->beaconRx) ||
1067 nla_put_u32(vendor_event,
1068 QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_MGMT_RX,
1069 pWifiIfaceStat->mgmtRx) ||
1070 nla_put_u32(vendor_event,
1071 QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_MGMT_ACTION_RX,
1072 pWifiIfaceStat->mgmtActionRx) ||
1073 nla_put_u32(vendor_event,
1074 QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_MGMT_ACTION_TX,
1075 pWifiIfaceStat->mgmtActionTx) ||
Dino Mycle3b9536d2014-07-09 22:05:24 +05301076 nla_put_s32(vendor_event,
Sunil Duttc69bccb2014-05-26 21:30:20 +05301077 QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_RSSI_MGMT,
1078 pWifiIfaceStat->rssiMgmt) ||
Dino Mycle3b9536d2014-07-09 22:05:24 +05301079 nla_put_s32(vendor_event,
Sunil Duttc69bccb2014-05-26 21:30:20 +05301080 QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_RSSI_DATA,
1081 pWifiIfaceStat->rssiData) ||
Dino Mycle3b9536d2014-07-09 22:05:24 +05301082 nla_put_s32(vendor_event,
Sunil Duttc69bccb2014-05-26 21:30:20 +05301083 QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_RSSI_ACK,
1084 pWifiIfaceStat->rssiAck))
1085 {
1086 hddLog(VOS_TRACE_LEVEL_ERROR,
Mukul Sharmaf1bd9322015-10-20 16:03:42 +05301087 FL("QCA_WLAN_VENDOR_ATTR put fail"));
1088 vos_mem_free(pWifiIfaceStatTL);
Sunil Duttc69bccb2014-05-26 21:30:20 +05301089 return FALSE;
1090 }
1091
Mukul Sharmaf1bd9322015-10-20 16:03:42 +05301092#ifdef FEATURE_EXT_LL_STAT
1093 /*
1094 * Ensure when EXT_LL_STAT is supported by both host and fwr,
1095 * then host should send Leaky AP stats to upper layer,
1096 * otherwise no need to send these stats.
1097 */
1098 if(sme_IsFeatureSupportedByFW(EXT_LL_STAT) &&
1099 sme_IsFeatureSupportedByDriver(EXT_LL_STAT)
1100 )
1101 {
1102 hddLog(VOS_TRACE_LEVEL_INFO,
1103 FL("EXT_LL_STAT is supported by fwr and host %u %u %u %llu"),
1104 pWifiIfaceStat->leakyApStat.is_leaky_ap,
1105 pWifiIfaceStat->leakyApStat.avg_rx_frms_leaked,
1106 pWifiIfaceStat->leakyApStat.rx_leak_window,
1107 pWifiIfaceStat->leakyApStat.avg_bcn_spread);
1108 if (nla_put_u32(vendor_event,
1109 QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_LEAKY_AP_DETECTED,
1110 pWifiIfaceStat->leakyApStat.is_leaky_ap) ||
1111 nla_put_u32(vendor_event,
1112 QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_LEAKY_AP_AVG_NUM_FRAMES_LEAKED,
1113 pWifiIfaceStat->leakyApStat.avg_rx_frms_leaked) ||
1114 nla_put_u32(vendor_event,
1115 QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_LEAKY_AP_GUARD_TIME,
1116 pWifiIfaceStat->leakyApStat.rx_leak_window) ||
1117 nla_put_u64(vendor_event,
1118 QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_AVERAGE_TSF_OFFSET,
1119 pWifiIfaceStat->leakyApStat.avg_bcn_spread))
1120 {
1121 hddLog(VOS_TRACE_LEVEL_ERROR,
1122 FL("EXT_LL_STAT put fail"));
1123 vos_mem_free(pWifiIfaceStatTL);
1124 return FALSE;
1125 }
1126 }
1127#endif
Sunil Duttc69bccb2014-05-26 21:30:20 +05301128 wmmInfo = nla_nest_start(vendor_event,
1129 QCA_WLAN_VENDOR_ATTR_LL_STATS_WMM_INFO);
Sushant Kaushikee1f55e2015-01-22 11:27:01 +05301130 if(!wmmInfo)
1131 {
1132 vos_mem_free(pWifiIfaceStatTL);
1133 return FALSE;
1134 }
Sunil Duttc69bccb2014-05-26 21:30:20 +05301135 for (i = 0; i < WIFI_AC_MAX; i++)
1136 {
1137 struct nlattr *wmmStats;
1138 wmmStats = nla_nest_start(vendor_event, i);
Sushant Kaushikee1f55e2015-01-22 11:27:01 +05301139 if(!wmmStats)
1140 {
1141 vos_mem_free(pWifiIfaceStatTL);
1142 return FALSE;
1143 }
Sunil Duttc69bccb2014-05-26 21:30:20 +05301144 if (FALSE == put_wifi_wmm_ac_stat(
1145 &pWifiIfaceStat->AccessclassStats[i],
1146 vendor_event))
1147 {
1148 hddLog(VOS_TRACE_LEVEL_ERROR,
1149 FL("QCA_WLAN_VENDOR_ATTR put Fail"));
Dino Mycle3b9536d2014-07-09 22:05:24 +05301150 vos_mem_free(pWifiIfaceStatTL);
Sunil Duttc69bccb2014-05-26 21:30:20 +05301151 return FALSE;
1152 }
1153
1154 nla_nest_end(vendor_event, wmmStats);
1155 }
1156 nla_nest_end(vendor_event, wmmInfo);
Dino Mycle3b9536d2014-07-09 22:05:24 +05301157 vos_mem_free(pWifiIfaceStatTL);
Sunil Duttc69bccb2014-05-26 21:30:20 +05301158 return TRUE;
1159}
1160
1161static tSirWifiInterfaceMode
1162 hdd_map_device_to_ll_iface_mode ( int deviceMode )
1163{
1164 switch (deviceMode)
1165 {
1166 case WLAN_HDD_INFRA_STATION:
1167 return WIFI_INTERFACE_STA;
1168 case WLAN_HDD_SOFTAP:
1169 return WIFI_INTERFACE_SOFTAP;
1170 case WLAN_HDD_P2P_CLIENT:
1171 return WIFI_INTERFACE_P2P_CLIENT;
1172 case WLAN_HDD_P2P_GO:
1173 return WIFI_INTERFACE_P2P_GO;
1174 case WLAN_HDD_IBSS:
1175 return WIFI_INTERFACE_IBSS;
1176 default:
Dino Myclec8f3f332014-07-21 16:48:27 +05301177 return WIFI_INTERFACE_UNKNOWN;
Sunil Duttc69bccb2014-05-26 21:30:20 +05301178 }
1179}
1180
1181static v_BOOL_t hdd_get_interface_info(hdd_adapter_t *pAdapter,
1182 tpSirWifiInterfaceInfo pInfo)
1183{
1184 v_U8_t *staMac = NULL;
1185 hdd_station_ctx_t *pHddStaCtx;
1186 tHalHandle hHal = WLAN_HDD_GET_HAL_CTX(pAdapter);
1187 tpAniSirGlobal pMac = PMAC_STRUCT( hHal );
1188
1189 pInfo->mode = hdd_map_device_to_ll_iface_mode(pAdapter->device_mode);
1190
1191 vos_mem_copy(pInfo->macAddr,
1192 pAdapter->macAddressCurrent.bytes, sizeof(v_MACADDR_t));
1193
1194 if (((WLAN_HDD_INFRA_STATION == pAdapter->device_mode) ||
1195 (WLAN_HDD_P2P_CLIENT == pAdapter->device_mode) ||
1196 (WLAN_HDD_P2P_DEVICE == pAdapter->device_mode)))
1197 {
1198 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
1199 if (eConnectionState_NotConnected == pHddStaCtx->conn_info.connState)
1200 {
1201 pInfo->state = WIFI_DISCONNECTED;
1202 }
1203 if (eConnectionState_Connecting == pHddStaCtx->conn_info.connState)
1204 {
1205 hddLog(VOS_TRACE_LEVEL_ERROR,
1206 "%s: Session ID %d, Connection is in progress", __func__,
1207 pAdapter->sessionId);
1208 pInfo->state = WIFI_ASSOCIATING;
1209 }
1210 if ((eConnectionState_Associated == pHddStaCtx->conn_info.connState) &&
1211 (VOS_FALSE == pHddStaCtx->conn_info.uIsAuthenticated))
1212 {
1213 staMac = (v_U8_t *) &(pAdapter->macAddressCurrent.bytes[0]);
1214 hddLog(VOS_TRACE_LEVEL_ERROR,
1215 "%s: client " MAC_ADDRESS_STR
1216 " is in the middle of WPS/EAPOL exchange.", __func__,
1217 MAC_ADDR_ARRAY(staMac));
1218 pInfo->state = WIFI_AUTHENTICATING;
1219 }
1220 if (eConnectionState_Associated == pHddStaCtx->conn_info.connState)
1221 {
1222 pInfo->state = WIFI_ASSOCIATED;
1223 vos_mem_copy(pInfo->bssid,
1224 &pHddStaCtx->conn_info.bssId, WNI_CFG_BSSID_LEN);
1225 vos_mem_copy(pInfo->ssid,
1226 pHddStaCtx->conn_info.SSID.SSID.ssId,
1227 pHddStaCtx->conn_info.SSID.SSID.length);
1228 //NULL Terminate the string.
1229 pInfo->ssid[pHddStaCtx->conn_info.SSID.SSID.length] = 0;
1230 }
1231 }
1232 vos_mem_copy(pInfo->countryStr,
1233 pMac->scan.countryCodeCurrent, WNI_CFG_COUNTRY_CODE_LEN);
1234
1235 vos_mem_copy(pInfo->apCountryStr,
1236 pMac->scan.countryCodeCurrent, WNI_CFG_COUNTRY_CODE_LEN);
1237
1238 return TRUE;
1239}
1240
1241/*
1242 * hdd_link_layer_process_peer_stats () - This function is called after
1243 * receiving Link Layer Peer statistics from FW.This function converts
1244 * the firmware data to the NL data and sends the same to the kernel/upper
1245 * layers.
1246 */
1247static v_VOID_t hdd_link_layer_process_peer_stats(hdd_adapter_t *pAdapter,
1248 v_VOID_t *pData)
1249{
1250 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Sunil Duttc69bccb2014-05-26 21:30:20 +05301251 tpSirWifiPeerStat pWifiPeerStat;
1252 tpSirWifiPeerInfo pWifiPeerInfo;
1253 struct nlattr *peerInfo;
1254 struct sk_buff *vendor_event;
1255 int status, i;
1256
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05301257 ENTER();
1258
Sunil Duttc69bccb2014-05-26 21:30:20 +05301259 status = wlan_hdd_validate_context(pHddCtx);
1260 if (0 != status)
1261 {
Sunil Duttc69bccb2014-05-26 21:30:20 +05301262 return;
1263 }
1264
1265 pWifiPeerStat = (tpSirWifiPeerStat) pData;
1266
1267 hddLog(VOS_TRACE_LEVEL_INFO,
1268 "LL_STATS_PEER_ALL : numPeers %u",
1269 pWifiPeerStat->numPeers);
Sunil Duttc69bccb2014-05-26 21:30:20 +05301270 /*
1271 * Allocate a size of 4096 for the peer stats comprising
1272 * each of size = sizeof (tSirWifiPeerInfo) + numRate *
1273 * sizeof (tSirWifiRateStat).Each field is put with an
1274 * NL attribute.The size of 4096 is considered assuming
1275 * that number of rates shall not exceed beyond 50 with
1276 * the sizeof (tSirWifiRateStat) being 32.
1277 */
mukul sharma4bd8d2e2015-08-13 20:33:25 +05301278 vendor_event = cfg80211_vendor_cmd_alloc_reply_skb(pHddCtx->wiphy,
1279 LL_STATS_EVENT_BUF_SIZE);
Sunil Duttc69bccb2014-05-26 21:30:20 +05301280 if (!vendor_event)
1281 {
1282 hddLog(VOS_TRACE_LEVEL_ERROR,
mukul sharma4bd8d2e2015-08-13 20:33:25 +05301283 "%s: cfg80211_vendor_cmd_alloc_reply_skb failed",
Sunil Duttc69bccb2014-05-26 21:30:20 +05301284 __func__);
1285 return;
1286 }
1287 if (nla_put_u32(vendor_event,
mukul sharma4bd8d2e2015-08-13 20:33:25 +05301288 QCA_WLAN_VENDOR_ATTR_LL_STATS_TYPE,
1289 QCA_WLAN_VENDOR_ATTR_LL_STATS_TYPE_PEER) ||
1290 nla_put_u32(vendor_event,
Sunil Duttc69bccb2014-05-26 21:30:20 +05301291 QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_NUM_PEERS,
1292 pWifiPeerStat->numPeers))
1293 {
1294 hddLog(VOS_TRACE_LEVEL_ERROR,
1295 "%s: QCA_WLAN_VENDOR_ATTR put fail", __func__);
1296 kfree_skb(vendor_event);
1297 return;
1298 }
1299
1300 peerInfo = nla_nest_start(vendor_event,
1301 QCA_WLAN_VENDOR_ATTR_LL_STATS_PEER_INFO);
Sushant Kaushikee1f55e2015-01-22 11:27:01 +05301302 if(!peerInfo)
1303 {
1304 hddLog(VOS_TRACE_LEVEL_ERROR,
1305 "%s: QCA_WLAN_VENDOR_ATTR_LL_STATS_PEER_INFO put fail",
1306 __func__);
1307 kfree_skb(vendor_event);
1308 return;
1309 }
Sunil Duttc69bccb2014-05-26 21:30:20 +05301310
1311 pWifiPeerInfo = (tpSirWifiPeerInfo) ((uint8 *)
1312 pWifiPeerStat->peerInfo);
1313
1314 for (i = 1; i <= pWifiPeerStat->numPeers; i++)
1315 {
Sunil Duttc69bccb2014-05-26 21:30:20 +05301316 int numRate = pWifiPeerInfo->numRate;
Sushant Kaushikee1f55e2015-01-22 11:27:01 +05301317 struct nlattr *peers = nla_nest_start(vendor_event, i);
Sunil Duttc69bccb2014-05-26 21:30:20 +05301318
Sushant Kaushikee1f55e2015-01-22 11:27:01 +05301319 if(!peers)
1320 {
1321 hddLog(VOS_TRACE_LEVEL_ERROR,
1322 "%s: peer stats put fail",
1323 __func__);
1324 kfree_skb(vendor_event);
1325 return;
1326 }
Sunil Duttc69bccb2014-05-26 21:30:20 +05301327 if (FALSE == put_wifi_peer_info(
1328 pWifiPeerInfo, vendor_event))
1329 {
1330 hddLog(VOS_TRACE_LEVEL_ERROR,
1331 "%s: put_wifi_peer_info put fail", __func__);
1332 kfree_skb(vendor_event);
1333 return;
1334 }
1335
1336 pWifiPeerInfo = (tpSirWifiPeerInfo) ((uint8 *)
1337 pWifiPeerStat->peerInfo +
1338 (i * sizeof(tSirWifiPeerInfo)) +
1339 (numRate * sizeof (tSirWifiRateStat)));
1340 nla_nest_end(vendor_event, peers);
1341 }
1342 nla_nest_end(vendor_event, peerInfo);
mukul sharma4bd8d2e2015-08-13 20:33:25 +05301343 cfg80211_vendor_cmd_reply(vendor_event);
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05301344 EXIT();
Sunil Duttc69bccb2014-05-26 21:30:20 +05301345}
1346
1347/*
1348 * hdd_link_layer_process_iface_stats () - This function is called after
1349 * receiving Link Layer Interface statistics from FW.This function converts
1350 * the firmware data to the NL data and sends the same to the kernel/upper
1351 * layers.
1352 */
1353static v_VOID_t hdd_link_layer_process_iface_stats(hdd_adapter_t *pAdapter,
1354 v_VOID_t *pData)
1355{
1356 tpSirWifiIfaceStat pWifiIfaceStat;
1357 struct sk_buff *vendor_event;
1358 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
1359 int status;
1360
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05301361 ENTER();
1362
Sunil Duttc69bccb2014-05-26 21:30:20 +05301363 status = wlan_hdd_validate_context(pHddCtx);
1364 if (0 != status)
1365 {
Sunil Duttc69bccb2014-05-26 21:30:20 +05301366 return;
1367 }
1368 /*
1369 * Allocate a size of 4096 for the interface stats comprising
1370 * sizeof (tpSirWifiIfaceStat).The size of 4096 is considered
1371 * assuming that all these fit with in the limit.Please take
1372 * a call on the limit based on the data requirements on
1373 * interface statistics.
1374 */
mukul sharma4bd8d2e2015-08-13 20:33:25 +05301375 vendor_event = cfg80211_vendor_cmd_alloc_reply_skb(pHddCtx->wiphy,
1376 LL_STATS_EVENT_BUF_SIZE);
Sunil Duttc69bccb2014-05-26 21:30:20 +05301377 if (!vendor_event)
1378 {
1379 hddLog(VOS_TRACE_LEVEL_ERROR,
mukul sharma4bd8d2e2015-08-13 20:33:25 +05301380 FL("cfg80211_vendor_cmd_alloc_reply_skb failed") );
Sunil Duttc69bccb2014-05-26 21:30:20 +05301381 return;
1382 }
1383
1384 pWifiIfaceStat = (tpSirWifiIfaceStat) pData;
1385
Dino Mycle3b9536d2014-07-09 22:05:24 +05301386
1387 if (FALSE == hdd_get_interface_info( pAdapter,
1388 &pWifiIfaceStat->info))
1389 {
1390 hddLog(VOS_TRACE_LEVEL_ERROR,
1391 FL("hdd_get_interface_info get fail") );
1392 kfree_skb(vendor_event);
1393 return;
1394 }
1395
1396 if (FALSE == put_wifi_iface_stats( pAdapter, pWifiIfaceStat,
1397 vendor_event))
1398 {
1399 hddLog(VOS_TRACE_LEVEL_ERROR,
1400 FL("put_wifi_iface_stats fail") );
1401 kfree_skb(vendor_event);
1402 return;
1403 }
1404
Sunil Duttc69bccb2014-05-26 21:30:20 +05301405 hddLog(VOS_TRACE_LEVEL_INFO,
1406 "WMI_LINK_STATS_IFACE Data");
1407
mukul sharma4bd8d2e2015-08-13 20:33:25 +05301408 cfg80211_vendor_cmd_reply(vendor_event);
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05301409
1410 EXIT();
Sunil Duttc69bccb2014-05-26 21:30:20 +05301411}
1412
1413/*
1414 * hdd_link_layer_process_radio_stats () - This function is called after
1415 * receiving Link Layer Radio statistics from FW.This function converts
1416 * the firmware data to the NL data and sends the same to the kernel/upper
1417 * layers.
1418 */
1419static v_VOID_t hdd_link_layer_process_radio_stats(hdd_adapter_t *pAdapter,
1420 v_VOID_t *pData)
1421{
1422 int status, i;
1423 tpSirWifiRadioStat pWifiRadioStat;
1424 tpSirWifiChannelStats pWifiChannelStats;
1425 struct sk_buff *vendor_event;
1426 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
1427 struct nlattr *chList;
1428
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05301429 ENTER();
1430
Sunil Duttc69bccb2014-05-26 21:30:20 +05301431 status = wlan_hdd_validate_context(pHddCtx);
1432 if (0 != status)
1433 {
Sunil Duttc69bccb2014-05-26 21:30:20 +05301434 return;
1435 }
1436 pWifiRadioStat = (tpSirWifiRadioStat) pData;
1437
1438 hddLog(VOS_TRACE_LEVEL_INFO,
1439 "LL_STATS_RADIO"
1440 " radio is %d onTime is %u "
1441 " txTime is %u rxTime is %u "
1442 " onTimeScan is %u onTimeNbd is %u "
Dino Mycle6fb96c12014-06-10 11:52:40 +05301443 " onTimeEXTScan is %u onTimeRoamScan is %u "
Sunil Duttc69bccb2014-05-26 21:30:20 +05301444 " onTimePnoScan is %u onTimeHs20 is %u "
1445 " numChannels is %u",
1446 pWifiRadioStat->radio, pWifiRadioStat->onTime,
1447 pWifiRadioStat->txTime, pWifiRadioStat->rxTime,
1448 pWifiRadioStat->onTimeScan, pWifiRadioStat->onTimeNbd,
Dino Mycle6fb96c12014-06-10 11:52:40 +05301449 pWifiRadioStat->onTimeEXTScan,
Sunil Duttc69bccb2014-05-26 21:30:20 +05301450 pWifiRadioStat->onTimeRoamScan,
1451 pWifiRadioStat->onTimePnoScan,
1452 pWifiRadioStat->onTimeHs20,
1453 pWifiRadioStat->numChannels);
1454 /*
1455 * Allocate a size of 4096 for the Radio stats comprising
1456 * sizeof (tSirWifiRadioStat) + numChannels * sizeof
1457 * (tSirWifiChannelStats).Each channel data is put with an
1458 * NL attribute.The size of 4096 is considered assuming that
1459 * number of channels shall not exceed beyond 60 with the
1460 * sizeof (tSirWifiChannelStats) being 24 bytes.
1461 */
1462
mukul sharma4bd8d2e2015-08-13 20:33:25 +05301463 vendor_event = cfg80211_vendor_cmd_alloc_reply_skb(pHddCtx->wiphy,
1464 LL_STATS_EVENT_BUF_SIZE);
Sunil Duttc69bccb2014-05-26 21:30:20 +05301465 if (!vendor_event)
1466 {
1467 hddLog(VOS_TRACE_LEVEL_ERROR,
mukul sharma4bd8d2e2015-08-13 20:33:25 +05301468 FL("cfg80211_vendor_cmd_alloc_reply_skb failed") );
Sunil Duttc69bccb2014-05-26 21:30:20 +05301469 return;
1470 }
1471
1472 if (nla_put_u32(vendor_event,
mukul sharma4bd8d2e2015-08-13 20:33:25 +05301473 QCA_WLAN_VENDOR_ATTR_LL_STATS_TYPE,
1474 QCA_WLAN_VENDOR_ATTR_LL_STATS_TYPE_RADIO) ||
1475 nla_put_u32(vendor_event,
Sunil Duttc69bccb2014-05-26 21:30:20 +05301476 QCA_WLAN_VENDOR_ATTR_LL_STATS_RADIO_ID,
1477 pWifiRadioStat->radio) ||
1478 nla_put_u32(vendor_event,
1479 QCA_WLAN_VENDOR_ATTR_LL_STATS_RADIO_ON_TIME,
1480 pWifiRadioStat->onTime) ||
1481 nla_put_u32(vendor_event,
1482 QCA_WLAN_VENDOR_ATTR_LL_STATS_RADIO_TX_TIME,
1483 pWifiRadioStat->txTime) ||
1484 nla_put_u32(vendor_event,
1485 QCA_WLAN_VENDOR_ATTR_LL_STATS_RADIO_RX_TIME,
1486 pWifiRadioStat->rxTime) ||
1487 nla_put_u32(vendor_event,
1488 QCA_WLAN_VENDOR_ATTR_LL_STATS_RADIO_ON_TIME_SCAN,
1489 pWifiRadioStat->onTimeScan) ||
1490 nla_put_u32(vendor_event,
1491 QCA_WLAN_VENDOR_ATTR_LL_STATS_RADIO_ON_TIME_NBD,
1492 pWifiRadioStat->onTimeNbd) ||
1493 nla_put_u32(vendor_event,
Dino Mycle6fb96c12014-06-10 11:52:40 +05301494 QCA_WLAN_VENDOR_ATTR_LL_STATS_RADIO_ON_TIME_EXTSCAN,
1495 pWifiRadioStat->onTimeEXTScan)||
Sunil Duttc69bccb2014-05-26 21:30:20 +05301496 nla_put_u32(vendor_event,
1497 QCA_WLAN_VENDOR_ATTR_LL_STATS_RADIO_ON_TIME_ROAM_SCAN,
1498 pWifiRadioStat->onTimeRoamScan) ||
1499 nla_put_u32(vendor_event,
1500 QCA_WLAN_VENDOR_ATTR_LL_STATS_RADIO_ON_TIME_PNO_SCAN,
1501 pWifiRadioStat->onTimePnoScan) ||
1502 nla_put_u32(vendor_event,
1503 QCA_WLAN_VENDOR_ATTR_LL_STATS_RADIO_ON_TIME_HS20,
1504 pWifiRadioStat->onTimeHs20) ||
1505 nla_put_u32(vendor_event,
1506 QCA_WLAN_VENDOR_ATTR_LL_STATS_RADIO_NUM_CHANNELS,
1507 pWifiRadioStat->numChannels))
1508 {
1509 hddLog(VOS_TRACE_LEVEL_ERROR,
1510 FL("QCA_WLAN_VENDOR_ATTR put fail"));
1511 kfree_skb(vendor_event);
1512 return ;
1513 }
1514
1515 chList = nla_nest_start(vendor_event,
1516 QCA_WLAN_VENDOR_ATTR_LL_STATS_CH_INFO);
Sushant Kaushikee1f55e2015-01-22 11:27:01 +05301517 if(!chList)
1518 {
1519 hddLog(VOS_TRACE_LEVEL_ERROR,
1520 "%s: QCA_WLAN_VENDOR_ATTR_LL_STATS_CH_INFO put fail",
1521 __func__);
1522 kfree_skb(vendor_event);
1523 return;
1524 }
Sunil Duttc69bccb2014-05-26 21:30:20 +05301525 for (i = 0; i < pWifiRadioStat->numChannels; i++)
1526 {
1527 struct nlattr *chInfo;
1528
1529 pWifiChannelStats = (tpSirWifiChannelStats) ((uint8*)
1530 pWifiRadioStat->channels +
1531 (i * sizeof(tSirWifiChannelStats)));
1532
Sunil Duttc69bccb2014-05-26 21:30:20 +05301533 chInfo = nla_nest_start(vendor_event, i);
Sushant Kaushikee1f55e2015-01-22 11:27:01 +05301534 if(!chInfo)
1535 {
1536 hddLog(VOS_TRACE_LEVEL_ERROR,
1537 "%s: failed to put chInfo",
1538 __func__);
1539 kfree_skb(vendor_event);
1540 return;
1541 }
Sunil Duttc69bccb2014-05-26 21:30:20 +05301542
1543 if (nla_put_u32(vendor_event,
1544 QCA_WLAN_VENDOR_ATTR_LL_STATS_CHANNEL_INFO_WIDTH,
1545 pWifiChannelStats->channel.width) ||
1546 nla_put_u32(vendor_event,
1547 QCA_WLAN_VENDOR_ATTR_LL_STATS_CHANNEL_INFO_CENTER_FREQ,
1548 pWifiChannelStats->channel.centerFreq) ||
1549 nla_put_u32(vendor_event,
1550 QCA_WLAN_VENDOR_ATTR_LL_STATS_CHANNEL_INFO_CENTER_FREQ0,
1551 pWifiChannelStats->channel.centerFreq0) ||
1552 nla_put_u32(vendor_event,
1553 QCA_WLAN_VENDOR_ATTR_LL_STATS_CHANNEL_INFO_CENTER_FREQ1,
1554 pWifiChannelStats->channel.centerFreq1) ||
1555 nla_put_u32(vendor_event,
1556 QCA_WLAN_VENDOR_ATTR_LL_STATS_CHANNEL_ON_TIME,
1557 pWifiChannelStats->onTime) ||
1558 nla_put_u32(vendor_event,
1559 QCA_WLAN_VENDOR_ATTR_LL_STATS_CHANNEL_CCA_BUSY_TIME,
1560 pWifiChannelStats->ccaBusyTime))
1561 {
1562 hddLog(VOS_TRACE_LEVEL_ERROR,
1563 FL("cfg80211_vendor_event_alloc failed") );
1564 kfree_skb(vendor_event);
1565 return ;
1566 }
1567 nla_nest_end(vendor_event, chInfo);
1568 }
1569 nla_nest_end(vendor_event, chList);
1570
mukul sharma4bd8d2e2015-08-13 20:33:25 +05301571 cfg80211_vendor_cmd_reply(vendor_event);
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05301572
1573 EXIT();
Sunil Duttc69bccb2014-05-26 21:30:20 +05301574 return;
1575}
1576
1577/*
1578 * hdd_link_layer_stats_ind_callback () - This function is called after
1579 * receiving Link Layer indications from FW.This callback converts the firmware
1580 * data to the NL data and send the same to the kernel/upper layers.
1581 */
1582static void hdd_link_layer_stats_ind_callback ( void *pCtx,
1583 int indType,
Dino Mycled3d50022014-07-07 12:58:25 +05301584 void *pRsp, u8 *macAddr)
Sunil Duttc69bccb2014-05-26 21:30:20 +05301585{
Dino Mycled3d50022014-07-07 12:58:25 +05301586 hdd_context_t *pHddCtx = (hdd_context_t *)pCtx;
1587 hdd_adapter_t *pAdapter = NULL;
mukul sharma4bd8d2e2015-08-13 20:33:25 +05301588 struct hdd_ll_stats_context *context;
Dino Mycled3d50022014-07-07 12:58:25 +05301589 tpSirLLStatsResults linkLayerStatsResults = (tpSirLLStatsResults)pRsp;
Sunil Duttc69bccb2014-05-26 21:30:20 +05301590 int status;
1591
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05301592 ENTER();
Sunil Duttc69bccb2014-05-26 21:30:20 +05301593
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05301594 status = wlan_hdd_validate_context(pHddCtx);
Sunil Duttc69bccb2014-05-26 21:30:20 +05301595 if (0 != status)
1596 {
Sunil Duttc69bccb2014-05-26 21:30:20 +05301597 return;
1598 }
1599
Dino Mycled3d50022014-07-07 12:58:25 +05301600 pAdapter = hdd_get_adapter_by_macaddr(pHddCtx, macAddr);
1601 if (NULL == pAdapter)
1602 {
1603 hddLog(VOS_TRACE_LEVEL_ERROR,
1604 FL(" MAC address %pM does not exist with host"),
1605 macAddr);
1606 return;
1607 }
1608
Sunil Duttc69bccb2014-05-26 21:30:20 +05301609 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Dino Mycled3d50022014-07-07 12:58:25 +05301610 "%s: Interface: %s LLStats indType: %d", __func__,
1611 pAdapter->dev->name, indType);
1612
Sunil Duttc69bccb2014-05-26 21:30:20 +05301613 switch (indType)
1614 {
1615 case SIR_HAL_LL_STATS_RESULTS_RSP:
1616 {
Sunil Duttc69bccb2014-05-26 21:30:20 +05301617 hddLog(VOS_TRACE_LEVEL_INFO,
Sushant Kaushik81a730c2015-09-14 14:49:52 +05301618 "LL_STATS RESP paramID = 0x%x, ifaceId = %u MAC: %pM "
1619 "respId = %u, moreResultToFollow = %u",
1620 linkLayerStatsResults->paramId, linkLayerStatsResults->ifaceId,
1621 macAddr, linkLayerStatsResults->respId,
1622 linkLayerStatsResults->moreResultToFollow);
1623
mukul sharma4bd8d2e2015-08-13 20:33:25 +05301624 spin_lock(&hdd_context_lock);
1625 context = &pHddCtx->ll_stats_context;
1626 /* validate response received from target */
1627 if ((context->request_id != linkLayerStatsResults->respId) ||
1628 !(context->request_bitmap & linkLayerStatsResults->paramId))
1629 {
1630 spin_unlock(&hdd_context_lock);
1631 hddLog(LOGE,
1632 FL("Error : Request id %d response id %d request bitmap 0x%x"
1633 "response bitmap 0x%x"),
1634 context->request_id, linkLayerStatsResults->respId,
1635 context->request_bitmap, linkLayerStatsResults->paramId);
1636 return;
1637 }
1638 spin_unlock(&hdd_context_lock);
1639
Sunil Duttc69bccb2014-05-26 21:30:20 +05301640 if ( linkLayerStatsResults->paramId & WMI_LINK_STATS_RADIO )
1641 {
1642 hdd_link_layer_process_radio_stats(pAdapter,
1643 (v_VOID_t *)linkLayerStatsResults->result);
mukul sharma4bd8d2e2015-08-13 20:33:25 +05301644 spin_lock(&hdd_context_lock);
1645 context->request_bitmap &= ~(WMI_LINK_STATS_RADIO);
1646 spin_unlock(&hdd_context_lock);
Sunil Duttc69bccb2014-05-26 21:30:20 +05301647 }
1648 else if ( linkLayerStatsResults->paramId & WMI_LINK_STATS_IFACE )
1649 {
1650 hdd_link_layer_process_iface_stats(pAdapter,
1651 (v_VOID_t *)linkLayerStatsResults->result);
mukul sharma4bd8d2e2015-08-13 20:33:25 +05301652 spin_lock(&hdd_context_lock);
1653 context->request_bitmap &= ~(WMI_LINK_STATS_IFACE);
1654 spin_unlock(&hdd_context_lock);
Sunil Duttc69bccb2014-05-26 21:30:20 +05301655 }
1656 else if ( linkLayerStatsResults->paramId &
1657 WMI_LINK_STATS_ALL_PEER )
1658 {
1659 hdd_link_layer_process_peer_stats(pAdapter,
1660 (v_VOID_t *)linkLayerStatsResults->result);
mukul sharma4bd8d2e2015-08-13 20:33:25 +05301661 spin_lock(&hdd_context_lock);
1662 context->request_bitmap &= ~(WMI_LINK_STATS_ALL_PEER);
1663 spin_unlock(&hdd_context_lock);
Sunil Duttc69bccb2014-05-26 21:30:20 +05301664 } /* WMI_LINK_STATS_ALL_PEER */
1665 else
1666 {
1667 hddLog(VOS_TRACE_LEVEL_ERROR,
1668 FL("INVALID LL_STATS_NOTIFY RESPONSE ***********"));
1669 }
1670
mukul sharma4bd8d2e2015-08-13 20:33:25 +05301671 spin_lock(&hdd_context_lock);
1672 /* complete response event if all requests are completed */
1673 if (0 == context->request_bitmap)
1674 complete(&context->response_event);
1675 spin_unlock(&hdd_context_lock);
1676
Sunil Duttc69bccb2014-05-26 21:30:20 +05301677 break;
1678 }
1679 default:
1680 hddLog(VOS_TRACE_LEVEL_ERROR, "invalid event type %d", indType);
1681 break;
1682 }
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05301683
1684 EXIT();
Sunil Duttc69bccb2014-05-26 21:30:20 +05301685 return;
1686}
1687
1688const struct
1689nla_policy
1690qca_wlan_vendor_ll_set_policy[QCA_WLAN_VENDOR_ATTR_LL_STATS_SET_MAX +1] =
1691{
1692 [QCA_WLAN_VENDOR_ATTR_LL_STATS_SET_CONFIG_MPDU_SIZE_THRESHOLD] =
1693 { .type = NLA_U32 },
1694 [QCA_WLAN_VENDOR_ATTR_LL_STATS_SET_CONFIG_AGGRESSIVE_STATS_GATHERING] =
1695 { .type = NLA_U32 },
1696};
1697
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05301698static int __wlan_hdd_cfg80211_ll_stats_set(struct wiphy *wiphy,
1699 struct wireless_dev *wdev,
1700 const void *data,
1701 int data_len)
Sunil Duttc69bccb2014-05-26 21:30:20 +05301702{
1703 int status;
1704 struct nlattr *tb_vendor[QCA_WLAN_VENDOR_ATTR_LL_STATS_SET_MAX + 1];
Dino Mycledf0a5d92014-07-04 09:41:55 +05301705 tSirLLStatsSetReq linkLayerStatsSetReq;
Sunil Duttc69bccb2014-05-26 21:30:20 +05301706 struct net_device *dev = wdev->netdev;
1707 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
1708 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
1709
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05301710 ENTER();
1711
Sunil Duttc69bccb2014-05-26 21:30:20 +05301712 status = wlan_hdd_validate_context(pHddCtx);
1713 if (0 != status)
1714 {
Sunil Duttc69bccb2014-05-26 21:30:20 +05301715 return -EINVAL;
1716 }
1717
1718 if (NULL == pAdapter)
1719 {
1720 hddLog(VOS_TRACE_LEVEL_ERROR,
1721 FL("HDD adapter is Null"));
1722 return -ENODEV;
1723 }
Dino Mycledf0a5d92014-07-04 09:41:55 +05301724 /* check the LLStats Capability */
1725 if ( (TRUE != pHddCtx->cfg_ini->fEnableLLStats) ||
1726 (TRUE != sme_IsFeatureSupportedByFW(LINK_LAYER_STATS_MEAS)))
1727 {
1728 hddLog(VOS_TRACE_LEVEL_ERROR,
1729 FL("Link Layer Statistics not supported by Firmware"));
1730 return -EINVAL;
1731 }
Sunil Duttc69bccb2014-05-26 21:30:20 +05301732
1733 if (nla_parse(tb_vendor, QCA_WLAN_VENDOR_ATTR_LL_STATS_SET_MAX,
1734 (struct nlattr *)data,
1735 data_len, qca_wlan_vendor_ll_set_policy))
1736 {
1737 hddLog(VOS_TRACE_LEVEL_ERROR, FL() );
1738 return -EINVAL;
1739 }
1740 if (!tb_vendor
1741 [QCA_WLAN_VENDOR_ATTR_LL_STATS_SET_CONFIG_MPDU_SIZE_THRESHOLD])
1742 {
1743 hddLog(VOS_TRACE_LEVEL_ERROR, FL("MPDU size Not present"));
1744 return -EINVAL;
1745 }
1746 if (!tb_vendor[
1747 QCA_WLAN_VENDOR_ATTR_LL_STATS_SET_CONFIG_AGGRESSIVE_STATS_GATHERING])
1748 {
1749 hddLog(VOS_TRACE_LEVEL_ERROR, FL(" Stats Gathering Not Present"));
1750 return -EINVAL;
1751 }
Sunil Duttc69bccb2014-05-26 21:30:20 +05301752 // Shall take the request Id if the Upper layers pass. 1 For now.
Dino Mycledf0a5d92014-07-04 09:41:55 +05301753 linkLayerStatsSetReq.reqId = 1;
Sunil Duttc69bccb2014-05-26 21:30:20 +05301754
Dino Mycledf0a5d92014-07-04 09:41:55 +05301755 linkLayerStatsSetReq.mpduSizeThreshold =
Sunil Duttc69bccb2014-05-26 21:30:20 +05301756 nla_get_u32(
1757 tb_vendor[QCA_WLAN_VENDOR_ATTR_LL_STATS_SET_CONFIG_MPDU_SIZE_THRESHOLD]);
1758
Dino Mycledf0a5d92014-07-04 09:41:55 +05301759 linkLayerStatsSetReq.aggressiveStatisticsGathering =
Sunil Duttc69bccb2014-05-26 21:30:20 +05301760 nla_get_u32(
1761 tb_vendor[QCA_WLAN_VENDOR_ATTR_LL_STATS_SET_CONFIG_AGGRESSIVE_STATS_GATHERING]);
1762
Dino Mycled3d50022014-07-07 12:58:25 +05301763 vos_mem_copy(linkLayerStatsSetReq.macAddr,
1764 pAdapter->macAddressCurrent.bytes, sizeof(v_MACADDR_t));
Sunil Duttc69bccb2014-05-26 21:30:20 +05301765
1766
1767 hddLog(VOS_TRACE_LEVEL_INFO,
Sushant Kaushik81a730c2015-09-14 14:49:52 +05301768 "LL_STATS_SET reqId = %d, MAC = %pM, mpduSizeThreshold = %d "
1769 "Statistics Gathering = %d ",
1770 linkLayerStatsSetReq.reqId, linkLayerStatsSetReq.macAddr,
1771 linkLayerStatsSetReq.mpduSizeThreshold,
1772 linkLayerStatsSetReq.aggressiveStatisticsGathering);
Sunil Duttc69bccb2014-05-26 21:30:20 +05301773
1774 if (eHAL_STATUS_SUCCESS != sme_SetLinkLayerStatsIndCB(
1775 pHddCtx->hHal,
Dino Mycled3d50022014-07-07 12:58:25 +05301776 hdd_link_layer_stats_ind_callback))
Sunil Duttc69bccb2014-05-26 21:30:20 +05301777 {
1778 hddLog(VOS_TRACE_LEVEL_ERROR, "%s:"
1779 "sme_SetLinkLayerStatsIndCB Failed", __func__);
Sunil Duttc69bccb2014-05-26 21:30:20 +05301780 return -EINVAL;
1781
1782 }
Srinivas Dasari98947432014-11-07 19:41:24 +05301783
Sunil Duttc69bccb2014-05-26 21:30:20 +05301784 if (eHAL_STATUS_SUCCESS != sme_LLStatsSetReq( pHddCtx->hHal,
Dino Mycledf0a5d92014-07-04 09:41:55 +05301785 &linkLayerStatsSetReq))
Sunil Duttc69bccb2014-05-26 21:30:20 +05301786 {
1787 hddLog(VOS_TRACE_LEVEL_ERROR, "%s:"
1788 "sme_LLStatsSetReq Failed", __func__);
Sunil Duttc69bccb2014-05-26 21:30:20 +05301789 return -EINVAL;
1790 }
1791
1792 pAdapter->isLinkLayerStatsSet = 1;
1793
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05301794 EXIT();
Sunil Duttc69bccb2014-05-26 21:30:20 +05301795 return 0;
1796}
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05301797static int wlan_hdd_cfg80211_ll_stats_set(struct wiphy *wiphy,
1798 struct wireless_dev *wdev,
1799 const void *data,
1800 int data_len)
1801{
1802 int ret = 0;
1803
1804 vos_ssr_protect(__func__);
1805 ret = __wlan_hdd_cfg80211_ll_stats_set(wiphy, wdev, data, data_len);
1806 vos_ssr_unprotect(__func__);
1807
1808 return ret;
1809}
Sunil Duttc69bccb2014-05-26 21:30:20 +05301810
1811const struct
1812nla_policy
1813qca_wlan_vendor_ll_get_policy[QCA_WLAN_VENDOR_ATTR_LL_STATS_GET_MAX +1] =
1814{
1815 /* Unsigned 32bit value provided by the caller issuing the GET stats
1816 * command. When reporting
1817 * the stats results, the driver uses the same value to indicate
1818 * which GET request the results
1819 * correspond to.
1820 */
1821 [QCA_WLAN_VENDOR_ATTR_LL_STATS_GET_CONFIG_REQ_ID] = { .type = NLA_U32 },
1822
1823 /* Unsigned 32bit value . bit mask to identify what statistics are
1824 requested for retrieval */
1825 [QCA_WLAN_VENDOR_ATTR_LL_STATS_GET_CONFIG_REQ_MASK] = { .type = NLA_U32 },
1826};
1827
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05301828static int __wlan_hdd_cfg80211_ll_stats_get(struct wiphy *wiphy,
1829 struct wireless_dev *wdev,
1830 const void *data,
1831 int data_len)
Sunil Duttc69bccb2014-05-26 21:30:20 +05301832{
mukul sharma4bd8d2e2015-08-13 20:33:25 +05301833 unsigned long rc;
1834 struct hdd_ll_stats_context *context;
Sunil Duttc69bccb2014-05-26 21:30:20 +05301835 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
1836 struct nlattr *tb_vendor[QCA_WLAN_VENDOR_ATTR_LL_STATS_GET_MAX + 1];
Dino Mycledf0a5d92014-07-04 09:41:55 +05301837 tSirLLStatsGetReq linkLayerStatsGetReq;
Sunil Duttc69bccb2014-05-26 21:30:20 +05301838 struct net_device *dev = wdev->netdev;
1839 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
Mukul Sharma10313ba2015-07-29 19:14:39 +05301840 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
Sunil Duttc69bccb2014-05-26 21:30:20 +05301841 int status;
1842
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05301843 ENTER();
1844
Sunil Duttc69bccb2014-05-26 21:30:20 +05301845 status = wlan_hdd_validate_context(pHddCtx);
1846 if (0 != status)
1847 {
Sunil Duttc69bccb2014-05-26 21:30:20 +05301848 return -EINVAL ;
1849 }
1850
1851 if (NULL == pAdapter)
1852 {
1853 hddLog(VOS_TRACE_LEVEL_FATAL,
1854 "%s: HDD adapter is Null", __func__);
1855 return -ENODEV;
1856 }
Mukul Sharma10313ba2015-07-29 19:14:39 +05301857
1858 if (pHddStaCtx == NULL)
1859 {
1860 hddLog(VOS_TRACE_LEVEL_FATAL,
1861 "%s: HddStaCtx is Null", __func__);
1862 return -ENODEV;
1863 }
1864
Dino Mycledf0a5d92014-07-04 09:41:55 +05301865 /* check the LLStats Capability */
1866 if ( (TRUE != pHddCtx->cfg_ini->fEnableLLStats) ||
1867 (TRUE != sme_IsFeatureSupportedByFW(LINK_LAYER_STATS_MEAS)))
1868 {
1869 hddLog(VOS_TRACE_LEVEL_ERROR,
1870 FL("Link Layer Statistics not supported by Firmware"));
1871 return -EINVAL;
1872 }
1873
Sunil Duttc69bccb2014-05-26 21:30:20 +05301874
1875 if (!pAdapter->isLinkLayerStatsSet)
1876 {
Sushant Kaushikdc3184b2015-10-09 12:00:21 +05301877 hddLog(VOS_TRACE_LEVEL_ERROR,
Sunil Duttc69bccb2014-05-26 21:30:20 +05301878 "%s: isLinkLayerStatsSet : %d",
1879 __func__, pAdapter->isLinkLayerStatsSet);
1880 return -EINVAL;
1881 }
1882
Mukul Sharma10313ba2015-07-29 19:14:39 +05301883 if (VOS_TRUE == pHddStaCtx->hdd_ReassocScenario)
1884 {
1885 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
1886 "%s: Roaming in progress, so unable to proceed this request", __func__);
1887 return -EBUSY;
1888 }
1889
Sunil Duttc69bccb2014-05-26 21:30:20 +05301890 if (nla_parse(tb_vendor, QCA_WLAN_VENDOR_ATTR_LL_STATS_GET_MAX,
1891 (struct nlattr *)data,
1892 data_len, qca_wlan_vendor_ll_get_policy))
1893 {
1894 hddLog(VOS_TRACE_LEVEL_ERROR, FL() );
1895 return -EINVAL;
1896 }
1897
1898 if (!tb_vendor
1899 [QCA_WLAN_VENDOR_ATTR_LL_STATS_GET_CONFIG_REQ_ID])
1900 {
1901 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Request Id Not present"));
1902 return -EINVAL;
1903 }
1904
1905 if (!tb_vendor
1906 [QCA_WLAN_VENDOR_ATTR_LL_STATS_GET_CONFIG_REQ_MASK])
1907 {
1908 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Req Mask Not present"));
1909 return -EINVAL;
1910 }
1911
Sunil Duttc69bccb2014-05-26 21:30:20 +05301912
Dino Mycledf0a5d92014-07-04 09:41:55 +05301913 linkLayerStatsGetReq.reqId =
Sunil Duttc69bccb2014-05-26 21:30:20 +05301914 nla_get_u32( tb_vendor[
1915 QCA_WLAN_VENDOR_ATTR_LL_STATS_GET_CONFIG_REQ_ID]);
Dino Mycledf0a5d92014-07-04 09:41:55 +05301916 linkLayerStatsGetReq.paramIdMask =
Sunil Duttc69bccb2014-05-26 21:30:20 +05301917 nla_get_u32( tb_vendor[
1918 QCA_WLAN_VENDOR_ATTR_LL_STATS_GET_CONFIG_REQ_MASK]);
1919
Dino Mycled3d50022014-07-07 12:58:25 +05301920 vos_mem_copy(linkLayerStatsGetReq.macAddr,
1921 pAdapter->macAddressCurrent.bytes, sizeof(v_MACADDR_t));
Sunil Duttc69bccb2014-05-26 21:30:20 +05301922
1923 hddLog(VOS_TRACE_LEVEL_INFO,
Sushant Kaushik81a730c2015-09-14 14:49:52 +05301924 "LL_STATS_GET reqId = %d, MAC = %pM, paramIdMask = %d",
1925 linkLayerStatsGetReq.reqId, linkLayerStatsGetReq.macAddr,
Dino Mycledf0a5d92014-07-04 09:41:55 +05301926 linkLayerStatsGetReq.paramIdMask);
Sunil Duttc69bccb2014-05-26 21:30:20 +05301927
mukul sharma4bd8d2e2015-08-13 20:33:25 +05301928 spin_lock(&hdd_context_lock);
1929 context = &pHddCtx->ll_stats_context;
1930 context->request_id = linkLayerStatsGetReq.reqId;
1931 context->request_bitmap = linkLayerStatsGetReq.paramIdMask;
1932 INIT_COMPLETION(context->response_event);
1933 spin_unlock(&hdd_context_lock);
1934
Sunil Duttc69bccb2014-05-26 21:30:20 +05301935 if (eHAL_STATUS_SUCCESS != sme_LLStatsGetReq( pHddCtx->hHal,
Dino Mycledf0a5d92014-07-04 09:41:55 +05301936 &linkLayerStatsGetReq))
Sunil Duttc69bccb2014-05-26 21:30:20 +05301937 {
1938 hddLog(VOS_TRACE_LEVEL_ERROR, "%s:"
1939 "sme_LLStatsGetReq Failed", __func__);
Sunil Duttc69bccb2014-05-26 21:30:20 +05301940 return -EINVAL;
1941 }
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05301942
mukul sharma4bd8d2e2015-08-13 20:33:25 +05301943 rc = wait_for_completion_timeout(&context->response_event,
1944 msecs_to_jiffies(WLAN_WAIT_TIME_LL_STATS));
1945 if (!rc)
1946 {
1947 hddLog(LOGE,
1948 FL("Target response timed out request id %d request bitmap 0x%x"),
1949 context->request_id, context->request_bitmap);
1950 return -ETIMEDOUT;
1951 }
1952
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05301953 EXIT();
Sunil Duttc69bccb2014-05-26 21:30:20 +05301954 return 0;
1955}
1956
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05301957static int wlan_hdd_cfg80211_ll_stats_get(struct wiphy *wiphy,
1958 struct wireless_dev *wdev,
1959 const void *data,
1960 int data_len)
1961{
1962 int ret = 0;
1963
1964 vos_ssr_protect(__func__);
1965 ret = __wlan_hdd_cfg80211_ll_stats_get(wiphy, wdev, data, data_len);
1966 vos_ssr_unprotect(__func__);
1967
1968 return ret;
1969}
1970
Sunil Duttc69bccb2014-05-26 21:30:20 +05301971const struct
1972nla_policy
1973qca_wlan_vendor_ll_clr_policy[QCA_WLAN_VENDOR_ATTR_LL_STATS_CLR_MAX +1] =
1974{
1975 [QCA_WLAN_VENDOR_ATTR_LL_STATS_CLR_CONFIG_REQ_MASK] = {.type = NLA_U32 },
1976 [QCA_WLAN_VENDOR_ATTR_LL_STATS_CLR_CONFIG_STOP_REQ] = {.type = NLA_U8 },
1977 [QCA_WLAN_VENDOR_ATTR_LL_STATS_CLR_CONFIG_RSP_MASK] = {.type = NLA_U32 },
1978 [QCA_WLAN_VENDOR_ATTR_LL_STATS_CLR_CONFIG_STOP_RSP] = {.type = NLA_U8 },
1979};
1980
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05301981static int __wlan_hdd_cfg80211_ll_stats_clear(struct wiphy *wiphy,
1982 struct wireless_dev *wdev,
1983 const void *data,
1984 int data_len)
Sunil Duttc69bccb2014-05-26 21:30:20 +05301985{
1986 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
1987 struct nlattr *tb_vendor[QCA_WLAN_VENDOR_ATTR_LL_STATS_CLR_MAX + 1];
Dino Mycledf0a5d92014-07-04 09:41:55 +05301988 tSirLLStatsClearReq linkLayerStatsClearReq;
Sunil Duttc69bccb2014-05-26 21:30:20 +05301989 struct net_device *dev = wdev->netdev;
1990 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
1991 u32 statsClearReqMask;
1992 u8 stopReq;
1993 int status;
1994
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05301995 ENTER();
1996
Sunil Duttc69bccb2014-05-26 21:30:20 +05301997 status = wlan_hdd_validate_context(pHddCtx);
1998 if (0 != status)
1999 {
Sunil Duttc69bccb2014-05-26 21:30:20 +05302000 return -EINVAL;
2001 }
2002
2003 if (NULL == pAdapter)
2004 {
2005 hddLog(VOS_TRACE_LEVEL_FATAL,
2006 "%s: HDD adapter is Null", __func__);
2007 return -ENODEV;
2008 }
Dino Mycledf0a5d92014-07-04 09:41:55 +05302009 /* check the LLStats Capability */
2010 if ( (TRUE != pHddCtx->cfg_ini->fEnableLLStats) ||
2011 (TRUE != sme_IsFeatureSupportedByFW(LINK_LAYER_STATS_MEAS)))
2012 {
2013 hddLog(VOS_TRACE_LEVEL_ERROR,
2014 FL("Enable LLStats Capability"));
2015 return -EINVAL;
2016 }
Sunil Duttc69bccb2014-05-26 21:30:20 +05302017
2018 if (!pAdapter->isLinkLayerStatsSet)
2019 {
2020 hddLog(VOS_TRACE_LEVEL_FATAL,
2021 "%s: isLinkLayerStatsSet : %d",
2022 __func__, pAdapter->isLinkLayerStatsSet);
2023 return -EINVAL;
2024 }
2025
2026 if (nla_parse(tb_vendor, QCA_WLAN_VENDOR_ATTR_LL_STATS_CLR_MAX,
2027 (struct nlattr *)data,
2028 data_len, qca_wlan_vendor_ll_clr_policy))
2029 {
2030 hddLog(VOS_TRACE_LEVEL_ERROR, FL() );
2031 return -EINVAL;
2032 }
2033
2034 if (!tb_vendor[QCA_WLAN_VENDOR_ATTR_LL_STATS_CLR_CONFIG_REQ_MASK] ||
2035
2036 !tb_vendor[QCA_WLAN_VENDOR_ATTR_LL_STATS_CLR_CONFIG_STOP_REQ])
2037 {
2038 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Error in LL_STATS CLR CONFIG PARA") );
2039 return -EINVAL;
2040
2041 }
2042
Sunil Duttc69bccb2014-05-26 21:30:20 +05302043
Dino Mycledf0a5d92014-07-04 09:41:55 +05302044 statsClearReqMask = linkLayerStatsClearReq.statsClearReqMask =
Sunil Duttc69bccb2014-05-26 21:30:20 +05302045 nla_get_u32(
2046 tb_vendor[QCA_WLAN_VENDOR_ATTR_LL_STATS_CLR_CONFIG_REQ_MASK]);
2047
Dino Mycledf0a5d92014-07-04 09:41:55 +05302048 stopReq = linkLayerStatsClearReq.stopReq =
Sunil Duttc69bccb2014-05-26 21:30:20 +05302049 nla_get_u8(
2050 tb_vendor[QCA_WLAN_VENDOR_ATTR_LL_STATS_CLR_CONFIG_STOP_REQ]);
2051
2052 // Shall take the request Id if the Upper layers pass. 1 For now.
Dino Mycledf0a5d92014-07-04 09:41:55 +05302053 linkLayerStatsClearReq.reqId = 1;
Sunil Duttc69bccb2014-05-26 21:30:20 +05302054
Dino Mycled3d50022014-07-07 12:58:25 +05302055 vos_mem_copy(linkLayerStatsClearReq.macAddr,
2056 pAdapter->macAddressCurrent.bytes, sizeof(v_MACADDR_t));
Sunil Duttc69bccb2014-05-26 21:30:20 +05302057
2058 hddLog(VOS_TRACE_LEVEL_INFO,
Sushant Kaushik81a730c2015-09-14 14:49:52 +05302059 "LL_STATS_CLEAR reqId = %d, MAC = %pM,"
2060 "statsClearReqMask = 0x%X, stopReq = %d",
2061 linkLayerStatsClearReq.reqId,
2062 linkLayerStatsClearReq.macAddr,
2063 linkLayerStatsClearReq.statsClearReqMask,
Dino Mycledf0a5d92014-07-04 09:41:55 +05302064 linkLayerStatsClearReq.stopReq);
Sunil Duttc69bccb2014-05-26 21:30:20 +05302065
2066 if (eHAL_STATUS_SUCCESS == sme_LLStatsClearReq(pHddCtx->hHal,
Dino Mycledf0a5d92014-07-04 09:41:55 +05302067 &linkLayerStatsClearReq))
Sunil Duttc69bccb2014-05-26 21:30:20 +05302068 {
2069 struct sk_buff *temp_skbuff;
Srinivas Dasari98947432014-11-07 19:41:24 +05302070 hdd_station_ctx_t *pHddStaCtx;
2071
2072 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
2073 if (VOS_STATUS_SUCCESS !=
2074 WLANTL_ClearInterfaceStats((WLAN_HDD_GET_CTX(pAdapter))->pvosContext,
2075 pHddStaCtx->conn_info.staId[0], statsClearReqMask))
2076 {
2077 hddLog(VOS_TRACE_LEVEL_ERROR, "%s:"
2078 "WLANTL_ClearInterfaceStats Failed", __func__);
2079 return -EINVAL;
2080 }
2081 if ((statsClearReqMask & WIFI_STATS_IFACE_AC) ||
2082 (statsClearReqMask & WIFI_STATS_IFACE)) {
2083 pAdapter->hdd_stats.hddTxRxStats.txMcast[WLANTL_AC_VO] = 0;
2084 pAdapter->hdd_stats.hddTxRxStats.txMcast[WLANTL_AC_VI] = 0;
2085 pAdapter->hdd_stats.hddTxRxStats.txMcast[WLANTL_AC_BE] = 0;
2086 pAdapter->hdd_stats.hddTxRxStats.txMcast[WLANTL_AC_BK] = 0;
2087 }
2088
Sunil Duttc69bccb2014-05-26 21:30:20 +05302089 temp_skbuff = cfg80211_vendor_cmd_alloc_reply_skb(wiphy,
2090 2 * sizeof(u32) +
2091 NLMSG_HDRLEN);
2092
2093 if (temp_skbuff != NULL)
2094 {
2095
2096 if (nla_put_u32(temp_skbuff,
2097 QCA_WLAN_VENDOR_ATTR_LL_STATS_CLR_CONFIG_RSP_MASK,
2098 statsClearReqMask) ||
2099 nla_put_u32(temp_skbuff,
2100 QCA_WLAN_VENDOR_ATTR_LL_STATS_CLR_CONFIG_STOP_RSP,
2101 stopReq))
2102 {
2103 hddLog(VOS_TRACE_LEVEL_ERROR, FL("LL_STATS_CLR put fail"));
2104 kfree_skb(temp_skbuff);
2105 return -EINVAL;
2106 }
2107 /* If the ask is to stop the stats collection as part of clear
2108 * (stopReq = 1) , ensure that no further requests of get
2109 * go to the firmware by having isLinkLayerStatsSet set to 0.
2110 * However it the stopReq as part of the clear request is 0 ,
Dino Mycledf0a5d92014-07-04 09:41:55 +05302111 * the request to get the statistics are honoured as in this
Sunil Duttc69bccb2014-05-26 21:30:20 +05302112 * case the firmware is just asked to clear the statistics.
2113 */
Dino Mycledf0a5d92014-07-04 09:41:55 +05302114 if (linkLayerStatsClearReq.stopReq == 1)
Sunil Duttc69bccb2014-05-26 21:30:20 +05302115 pAdapter->isLinkLayerStatsSet = 0;
2116 return cfg80211_vendor_cmd_reply(temp_skbuff);
2117 }
2118 return -ENOMEM;
2119 }
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05302120
2121 EXIT();
Sunil Duttc69bccb2014-05-26 21:30:20 +05302122 return -EINVAL;
2123}
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05302124static int wlan_hdd_cfg80211_ll_stats_clear(struct wiphy *wiphy,
2125 struct wireless_dev *wdev,
2126 const void *data,
2127 int data_len)
2128{
2129 int ret = 0;
2130
2131 vos_ssr_protect(__func__);
2132 ret = __wlan_hdd_cfg80211_ll_stats_clear(wiphy, wdev, data, data_len);
2133 vos_ssr_unprotect(__func__);
2134
2135 return ret;
2136
2137
2138}
Sunil Duttc69bccb2014-05-26 21:30:20 +05302139#endif /* WLAN_FEATURE_LINK_LAYER_STATS */
2140
Dino Mycle6fb96c12014-06-10 11:52:40 +05302141#ifdef WLAN_FEATURE_EXTSCAN
2142static const struct nla_policy
2143wlan_hdd_extscan_config_policy
2144 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX + 1] =
2145{
2146 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_REQUEST_ID] =
2147 { .type = NLA_U32 },
2148 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_GET_VALID_CHANNELS_CONFIG_PARAM_WIFI_BAND] =
2149 { .type = NLA_U32 },
2150 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_CHANNEL_SPEC_CHANNEL] = { .type = NLA_U32 },
2151 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_CHANNEL_SPEC_DWELL_TIME] =
2152 { .type = NLA_U32 },
2153 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_CHANNEL_SPEC_PASSIVE] = { .type = NLA_U8 },
2154 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_CHANNEL_SPEC_CLASS] = { .type = NLA_U8 },
2155
2156 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_INDEX] = { .type = NLA_U8 },
2157 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_BAND] = { .type = NLA_U8 },
2158 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_PERIOD] = { .type = NLA_U32 },
2159 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_REPORT_EVENTS] =
2160 { .type = NLA_U8 },
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05302161 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_MAX_PERIOD] =
2162 { .type = NLA_U32 },
2163 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_EXPONENT] =
2164 { .type = NLA_U32 },
2165 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_STEP_COUNT] =
2166 { .type = NLA_U32 },
Dino Mycle6fb96c12014-06-10 11:52:40 +05302167 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_NUM_CHANNEL_SPECS] =
2168 { .type = NLA_U32 },
2169 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_SCAN_CMD_PARAMS_BASE_PERIOD] =
2170 { .type = NLA_U32 },
2171 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_SCAN_CMD_PARAMS_MAX_AP_PER_SCAN] =
2172 { .type = NLA_U32 },
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05302173 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_SCAN_CMD_PARAMS_REPORT_THRESHOLD_PERCENT] =
2174 { .type = NLA_U8 },
2175 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_SCAN_CMD_PARAMS_REPORT_THRESHOLD_NUM_SCANS] =
Dino Mycle6fb96c12014-06-10 11:52:40 +05302176 { .type = NLA_U8 },
2177 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_SCAN_CMD_PARAMS_NUM_BUCKETS] =
2178 { .type = NLA_U8 },
2179 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_GET_CACHED_SCAN_RESULTS_CONFIG_PARAM_FLUSH] =
2180 { .type = NLA_U8 },
2181
2182 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_GET_CACHED_SCAN_RESULTS_CONFIG_PARAM_MAX] =
2183 { .type = NLA_U32 },
2184 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_AP_THRESHOLD_PARAM_BSSID] =
2185 { .type = NLA_UNSPEC },
2186 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_AP_THRESHOLD_PARAM_RSSI_LOW] =
2187 { .type = NLA_S32 },
2188 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_AP_THRESHOLD_PARAM_RSSI_HIGH] =
2189 { .type = NLA_S32 },
2190 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_AP_THRESHOLD_PARAM_CHANNEL] =
2191 { .type = NLA_U32 },
2192 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_BSSID_HOTLIST_PARAMS_NUM_AP] =
2193 { .type = NLA_U32 },
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05302194 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_BSSID_HOTLIST_PARAMS_LOST_AP_SAMPLE_SIZE] =
2195 { .type = NLA_U32 },
2196 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_SSID_THRESHOLD_PARAM_SSID] =
2197 { .type = NLA_BINARY,
2198 .len = IEEE80211_MAX_SSID_LEN + 1 },
2199 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_SSID_HOTLIST_PARAMS_LOST_SSID_SAMPLE_SIZE] =
Dino Mycle6fb96c12014-06-10 11:52:40 +05302200 { .type = NLA_U32 },
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05302201 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_SSID_HOTLIST_PARAMS_NUM_SSID] =
2202 { .type = NLA_U32 },
2203 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_SSID_THRESHOLD_PARAM_BAND] =
2204 { .type = NLA_U8 },
2205 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_SSID_THRESHOLD_PARAM_RSSI_LOW] =
2206 { .type = NLA_S32 },
2207 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_SSID_THRESHOLD_PARAM_RSSI_HIGH] =
2208 { .type = NLA_S32 },
2209 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_CONFIGURATION_FLAGS] =
2210 { .type = NLA_U32 },
Dino Mycle6fb96c12014-06-10 11:52:40 +05302211};
2212
Padma, Santhosh Kumara1aa4a32015-06-19 19:00:46 +05302213/**
2214 * wlan_hdd_cfg80211_extscan_get_capabilities_rsp() - response from target
2215 * @ctx: hdd global context
2216 * @data: capabilities data
2217 *
2218 * Return: none
2219 */
2220static void
2221wlan_hdd_cfg80211_extscan_get_capabilities_rsp(void *ctx, void *pMsg)
Dino Mycle6fb96c12014-06-10 11:52:40 +05302222{
Padma, Santhosh Kumara1aa4a32015-06-19 19:00:46 +05302223 struct hdd_ext_scan_context *context;
Dino Mycle6fb96c12014-06-10 11:52:40 +05302224 hdd_context_t *pHddCtx = (hdd_context_t *)ctx;
Padma, Santhosh Kumara1aa4a32015-06-19 19:00:46 +05302225 tSirEXTScanCapabilitiesEvent *data =
2226 (tSirEXTScanCapabilitiesEvent *) pMsg;
Dino Mycle6fb96c12014-06-10 11:52:40 +05302227
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05302228 ENTER();
2229
2230 if (wlan_hdd_validate_context(pHddCtx))
2231 {
Dino Mycle6fb96c12014-06-10 11:52:40 +05302232 return;
2233 }
2234
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05302235 if (!pMsg)
2236 {
2237 hddLog(VOS_TRACE_LEVEL_ERROR, FL("pMsg is null"));
2238 return;
2239 }
Dino Mycle6fb96c12014-06-10 11:52:40 +05302240
Padma, Santhosh Kumara1aa4a32015-06-19 19:00:46 +05302241 vos_spin_lock_acquire(&hdd_context_lock);
2242
2243 context = &pHddCtx->ext_scan_context;
2244 /* validate response received from target*/
2245 if (context->request_id != data->requestId)
2246 {
2247 vos_spin_lock_release(&hdd_context_lock);
2248 hddLog(LOGE,
2249 FL("Target response id did not match: request_id %d resposne_id %d"),
2250 context->request_id, data->requestId);
Dino Mycle6fb96c12014-06-10 11:52:40 +05302251 return;
2252 }
Padma, Santhosh Kumara1aa4a32015-06-19 19:00:46 +05302253 else
2254 {
2255 context->capability_response = *data;
2256 complete(&context->response_event);
Dino Mycle6fb96c12014-06-10 11:52:40 +05302257 }
2258
Padma, Santhosh Kumara1aa4a32015-06-19 19:00:46 +05302259 vos_spin_lock_release(&hdd_context_lock);
Dino Mycle6fb96c12014-06-10 11:52:40 +05302260
Dino Mycle6fb96c12014-06-10 11:52:40 +05302261 return;
2262}
2263
Padma, Santhosh Kumara1aa4a32015-06-19 19:00:46 +05302264/*
2265 * define short names for the global vendor params
2266 * used by wlan_hdd_send_ext_scan_capability()
2267 */
2268#define PARAM_REQUEST_ID \
2269 QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_REQUEST_ID
2270#define PARAM_STATUS \
2271 QCA_WLAN_VENDOR_ATTR_EXTSCAN_STATUS
2272#define MAX_SCAN_CACHE_SIZE \
2273 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_CAPABILITIES_MAX_SCAN_CACHE_SIZE
2274#define MAX_SCAN_BUCKETS \
2275 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_CAPABILITIES_MAX_SCAN_BUCKETS
2276#define MAX_AP_CACHE_PER_SCAN \
2277 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_CAPABILITIES_MAX_AP_CACHE_PER_SCAN
2278#define MAX_RSSI_SAMPLE_SIZE \
2279 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_CAPABILITIES_MAX_RSSI_SAMPLE_SIZE
2280#define MAX_SCAN_RPT_THRHOLD \
2281 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_CAPABILITIES_MAX_SCAN_REPORTING_THRESHOLD
2282#define MAX_HOTLIST_BSSIDS \
2283 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_CAPABILITIES_MAX_HOTLIST_BSSIDS
2284#define MAX_BSSID_HISTORY_ENTRIES \
2285 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_CAPABILITIES_MAX_BSSID_HISTORY_ENTRIES
2286#define MAX_HOTLIST_SSIDS \
2287 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_CAPABILITIES_MAX_HOTLIST_SSIDS
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05302288#define MAX_SIGNIFICANT_WIFI_CHANGE_APS \
2289 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_CAPABILITIES_MAX_SIGNIFICANT_WIFI_CHANGE_APS
Padma, Santhosh Kumara1aa4a32015-06-19 19:00:46 +05302290
2291static int wlan_hdd_send_ext_scan_capability(void *ctx)
2292{
2293 hdd_context_t *pHddCtx = (hdd_context_t *)ctx;
2294 struct sk_buff *skb = NULL;
2295 int ret;
2296 tSirEXTScanCapabilitiesEvent *data;
2297 tANI_U32 nl_buf_len;
2298
2299 ret = wlan_hdd_validate_context(pHddCtx);
2300 if (0 != ret)
2301 {
2302 return ret;
2303 }
2304
2305 data = &(pHddCtx->ext_scan_context.capability_response);
2306
2307 nl_buf_len = NLMSG_HDRLEN;
2308 nl_buf_len += (sizeof(data->requestId) + NLA_HDRLEN) +
2309 (sizeof(data->status) + NLA_HDRLEN) +
2310 (sizeof(data->scanCacheSize) + NLA_HDRLEN) +
2311 (sizeof(data->scanBuckets) + NLA_HDRLEN) +
2312 (sizeof(data->maxApPerScan) + NLA_HDRLEN) +
2313 (sizeof(data->maxRssiSampleSize) + NLA_HDRLEN) +
2314 (sizeof(data->maxScanReportingThreshold) + NLA_HDRLEN) +
2315 (sizeof(data->maxHotlistAPs) + NLA_HDRLEN) +
2316 (sizeof(data->maxBsidHistoryEntries) + NLA_HDRLEN) +
2317 (sizeof(data->maxHotlistSSIDs) + NLA_HDRLEN);
2318
2319 skb = cfg80211_vendor_cmd_alloc_reply_skb(pHddCtx->wiphy, nl_buf_len);
2320
2321 if (!skb)
2322 {
2323 hddLog(LOGE, FL("cfg80211_vendor_cmd_alloc_reply_skb failed"));
2324 return -ENOMEM;
2325 }
2326
2327 hddLog(LOG1, "Req Id (%u) Status (%u)", data->requestId, data->status);
2328 hddLog(LOG1, "Scan cache size (%u) Scan buckets (%u) Max AP per scan (%u)",
2329 data->scanCacheSize, data->scanBuckets, data->maxApPerScan);
2330 hddLog(LOG1, "max_rssi_sample_size (%u) max_scan_reporting_threshold (%u)",
2331 data->maxRssiSampleSize, data->maxScanReportingThreshold);
2332 hddLog(LOG1, "max_hotlist_bssids (%u) max_bssid_history_entries (%u)"
2333 "max_hotlist_ssids (%u)", data->maxHotlistAPs,
2334 data->maxBsidHistoryEntries, data->maxHotlistSSIDs);
2335
2336 if (nla_put_u32(skb, PARAM_REQUEST_ID, data->requestId) ||
2337 nla_put_u32(skb, PARAM_STATUS, data->status) ||
2338 nla_put_u32(skb, MAX_SCAN_CACHE_SIZE, data->scanCacheSize) ||
2339 nla_put_u32(skb, MAX_SCAN_BUCKETS, data->scanBuckets) ||
2340 nla_put_u32(skb, MAX_AP_CACHE_PER_SCAN,
2341 data->maxApPerScan) ||
2342 nla_put_u32(skb, MAX_RSSI_SAMPLE_SIZE,
2343 data->maxRssiSampleSize) ||
2344 nla_put_u32(skb, MAX_SCAN_RPT_THRHOLD,
2345 data->maxScanReportingThreshold) ||
2346 nla_put_u32(skb, MAX_HOTLIST_BSSIDS, data->maxHotlistAPs) ||
2347 nla_put_u32(skb, MAX_BSSID_HISTORY_ENTRIES,
2348 data->maxBsidHistoryEntries) ||
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05302349 nla_put_u32(skb, MAX_HOTLIST_SSIDS, data->maxHotlistSSIDs) ||
2350 nla_put_u32(skb, MAX_SIGNIFICANT_WIFI_CHANGE_APS, 0))
Padma, Santhosh Kumara1aa4a32015-06-19 19:00:46 +05302351 {
2352 hddLog(LOGE, FL("nla put fail"));
2353 goto nla_put_failure;
2354 }
2355
2356 cfg80211_vendor_cmd_reply(skb);
2357 return 0;
2358
2359nla_put_failure:
2360 kfree_skb(skb);
2361 return -EINVAL;;
2362}
2363
2364/*
2365 * done with short names for the global vendor params
2366 * used by wlan_hdd_send_ext_scan_capability()
2367 */
2368#undef PARAM_REQUEST_ID
2369#undef PARAM_STATUS
2370#undef MAX_SCAN_CACHE_SIZE
2371#undef MAX_SCAN_BUCKETS
2372#undef MAX_AP_CACHE_PER_SCAN
2373#undef MAX_RSSI_SAMPLE_SIZE
2374#undef MAX_SCAN_RPT_THRHOLD
2375#undef MAX_HOTLIST_BSSIDS
Padma, Santhosh Kumara1aa4a32015-06-19 19:00:46 +05302376#undef MAX_BSSID_HISTORY_ENTRIES
2377#undef MAX_HOTLIST_SSIDS
Dino Mycle6fb96c12014-06-10 11:52:40 +05302378
2379static void wlan_hdd_cfg80211_extscan_start_rsp(void *ctx, void *pMsg)
2380{
2381 tpSirEXTScanStartRspParams pData = (tpSirEXTScanStartRspParams) pMsg;
2382 hdd_context_t *pHddCtx = (hdd_context_t *)ctx;
Dino Mycle6fb96c12014-06-10 11:52:40 +05302383 tpAniSirGlobal pMac = PMAC_STRUCT( pHddCtx->hHal );
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05302384 struct hdd_ext_scan_context *context;
Dino Mycle6fb96c12014-06-10 11:52:40 +05302385
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05302386 ENTER();
Dino Mycle6fb96c12014-06-10 11:52:40 +05302387
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05302388 if (wlan_hdd_validate_context(pHddCtx))
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05302389 return;
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05302390
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05302391 if (!pMsg)
2392 {
2393 hddLog(VOS_TRACE_LEVEL_ERROR, FL("pMsg is null"));
Dino Mycle6fb96c12014-06-10 11:52:40 +05302394 return;
2395 }
2396
Dino Mycle6fb96c12014-06-10 11:52:40 +05302397 hddLog(VOS_TRACE_LEVEL_INFO, "Req Id (%u)", pData->requestId);
2398 hddLog(VOS_TRACE_LEVEL_INFO, "Status (%u)", pData->status);
2399
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05302400 context = &pHddCtx->ext_scan_context;
2401 spin_lock(&hdd_context_lock);
2402 if (context->request_id == pData->requestId) {
2403 context->response_status = pData->status ? -EINVAL : 0;
2404 complete(&context->response_event);
Dino Mycle6fb96c12014-06-10 11:52:40 +05302405 }
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05302406 spin_unlock(&hdd_context_lock);
Dino Mycle6fb96c12014-06-10 11:52:40 +05302407
2408 /*
2409 * Store the Request ID for comparing with the requestID obtained
2410 * in other requests.HDD shall return a failure is the extscan_stop
2411 * request is issued with a different requestId as that of the
2412 * extscan_start request. Also, This requestId shall be used while
2413 * indicating the full scan results to the upper layers.
2414 * The requestId is stored with the assumption that the firmware
2415 * shall return the ext scan start request's requestId in ext scan
2416 * start response.
2417 */
2418 if (pData->status == 0)
2419 pMac->sme.extScanStartReqId = pData->requestId;
2420
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05302421 EXIT();
Dino Mycle6fb96c12014-06-10 11:52:40 +05302422 return;
Dino Mycle6fb96c12014-06-10 11:52:40 +05302423}
2424
2425
2426static void wlan_hdd_cfg80211_extscan_stop_rsp(void *ctx, void *pMsg)
2427{
2428 tpSirEXTScanStopRspParams pData = (tpSirEXTScanStopRspParams) pMsg;
2429 hdd_context_t *pHddCtx = (hdd_context_t *)ctx;
Padma, Santhosh Kumar57cff7f2015-08-17 18:33:14 +05302430 struct hdd_ext_scan_context *context;
Dino Mycle6fb96c12014-06-10 11:52:40 +05302431
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05302432 ENTER();
2433
2434 if (wlan_hdd_validate_context(pHddCtx)){
2435 return;
2436 }
Padma, Santhosh Kumar57cff7f2015-08-17 18:33:14 +05302437
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05302438 if (!pMsg)
2439 {
2440 hddLog(VOS_TRACE_LEVEL_ERROR, FL("pMsg is null"));
Dino Mycle6fb96c12014-06-10 11:52:40 +05302441 return;
2442 }
2443
Padma, Santhosh Kumar57cff7f2015-08-17 18:33:14 +05302444 hddLog(VOS_TRACE_LEVEL_INFO, "Req Id %u Status %u", pData->requestId,
2445 pData->status);
Dino Mycle6fb96c12014-06-10 11:52:40 +05302446
Padma, Santhosh Kumar57cff7f2015-08-17 18:33:14 +05302447 context = &pHddCtx->ext_scan_context;
2448 spin_lock(&hdd_context_lock);
2449 if (context->request_id == pData->requestId) {
2450 context->response_status = pData->status ? -EINVAL : 0;
2451 complete(&context->response_event);
Dino Mycle6fb96c12014-06-10 11:52:40 +05302452 }
Padma, Santhosh Kumar57cff7f2015-08-17 18:33:14 +05302453 spin_unlock(&hdd_context_lock);
Dino Mycle6fb96c12014-06-10 11:52:40 +05302454
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05302455 EXIT();
Dino Mycle6fb96c12014-06-10 11:52:40 +05302456 return;
Dino Mycle6fb96c12014-06-10 11:52:40 +05302457}
2458
Dino Mycle6fb96c12014-06-10 11:52:40 +05302459static void wlan_hdd_cfg80211_extscan_set_bss_hotlist_rsp(void *ctx,
2460 void *pMsg)
2461{
2462 hdd_context_t *pHddCtx = (hdd_context_t *)ctx;
Dino Mycle6fb96c12014-06-10 11:52:40 +05302463 tpSirEXTScanSetBssidHotListRspParams pData =
2464 (tpSirEXTScanSetBssidHotListRspParams) pMsg;
Padma, Santhosh Kumar37f4fd12015-08-19 14:37:37 +05302465 struct hdd_ext_scan_context *context;
Dino Mycle6fb96c12014-06-10 11:52:40 +05302466
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05302467 ENTER();
2468
2469 if (wlan_hdd_validate_context(pHddCtx)){
Dino Mycle6fb96c12014-06-10 11:52:40 +05302470 return;
2471 }
Padma, Santhosh Kumar37f4fd12015-08-19 14:37:37 +05302472
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05302473 if (!pMsg)
2474 {
2475 hddLog(VOS_TRACE_LEVEL_ERROR, FL("pMsg is null"));
2476 return;
2477 }
2478
Padma, Santhosh Kumar37f4fd12015-08-19 14:37:37 +05302479 hddLog(VOS_TRACE_LEVEL_INFO, "Req Id %u Status %u", pData->requestId,
2480 pData->status);
Dino Mycle6fb96c12014-06-10 11:52:40 +05302481
Padma, Santhosh Kumar37f4fd12015-08-19 14:37:37 +05302482 context = &pHddCtx->ext_scan_context;
2483 spin_lock(&hdd_context_lock);
2484 if (context->request_id == pData->requestId) {
2485 context->response_status = pData->status ? -EINVAL : 0;
2486 complete(&context->response_event);
Dino Mycle6fb96c12014-06-10 11:52:40 +05302487 }
Padma, Santhosh Kumar37f4fd12015-08-19 14:37:37 +05302488 spin_unlock(&hdd_context_lock);
Dino Mycle6fb96c12014-06-10 11:52:40 +05302489
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05302490 EXIT();
Dino Mycle6fb96c12014-06-10 11:52:40 +05302491 return;
Dino Mycle6fb96c12014-06-10 11:52:40 +05302492}
2493
2494static void wlan_hdd_cfg80211_extscan_reset_bss_hotlist_rsp(void *ctx,
2495 void *pMsg)
2496{
2497 hdd_context_t *pHddCtx = (hdd_context_t *)ctx;
Dino Mycle6fb96c12014-06-10 11:52:40 +05302498 tpSirEXTScanResetBssidHotlistRspParams pData =
2499 (tpSirEXTScanResetBssidHotlistRspParams) pMsg;
Padma, Santhosh Kumar04a3bab2015-08-20 13:09:35 +05302500 struct hdd_ext_scan_context *context;
Dino Mycle6fb96c12014-06-10 11:52:40 +05302501
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05302502 ENTER();
2503
2504 if (wlan_hdd_validate_context(pHddCtx)) {
2505 return;
2506 }
2507 if (!pMsg)
2508 {
2509 hddLog(VOS_TRACE_LEVEL_ERROR, FL("pMsg is null"));
Dino Mycle6fb96c12014-06-10 11:52:40 +05302510 return;
2511 }
2512
Padma, Santhosh Kumar04a3bab2015-08-20 13:09:35 +05302513 hddLog(VOS_TRACE_LEVEL_INFO, "Req Id %u Status %u", pData->requestId,
2514 pData->status);
Dino Mycle6fb96c12014-06-10 11:52:40 +05302515
Padma, Santhosh Kumar04a3bab2015-08-20 13:09:35 +05302516 context = &pHddCtx->ext_scan_context;
2517 spin_lock(&hdd_context_lock);
2518 if (context->request_id == pData->requestId) {
2519 context->response_status = pData->status ? -EINVAL : 0;
2520 complete(&context->response_event);
Dino Mycle6fb96c12014-06-10 11:52:40 +05302521 }
Padma, Santhosh Kumar04a3bab2015-08-20 13:09:35 +05302522 spin_unlock(&hdd_context_lock);
Dino Mycle6fb96c12014-06-10 11:52:40 +05302523
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05302524 EXIT();
Dino Mycle6fb96c12014-06-10 11:52:40 +05302525 return;
Dino Mycle6fb96c12014-06-10 11:52:40 +05302526}
2527
Padma, Santhosh Kumar9acee012015-08-21 19:58:01 +05302528static void wlan_hdd_cfg80211_extscan_set_ssid_hotlist_rsp(void *ctx,
2529 void *pMsg)
2530{
2531 hdd_context_t *pHddCtx = (hdd_context_t *)ctx;
2532 tpSirEXTScanSetSsidHotListRspParams pData =
2533 (tpSirEXTScanSetSsidHotListRspParams) pMsg;
2534 struct hdd_ext_scan_context *context;
2535
2536 if (wlan_hdd_validate_context(pHddCtx)){
2537 return;
2538 }
2539
2540 if (!pMsg)
2541 {
2542 hddLog(VOS_TRACE_LEVEL_ERROR, FL("pMsg is null"));
2543 return;
2544 }
2545
2546 hddLog(VOS_TRACE_LEVEL_INFO, "Req Id %u Status %u", pData->requestId,
2547 pData->status);
2548
2549 context = &pHddCtx->ext_scan_context;
2550 spin_lock(&hdd_context_lock);
2551 if (context->request_id == pData->requestId) {
2552 context->response_status = pData->status ? -EINVAL : 0;
2553 complete(&context->response_event);
2554 }
2555 spin_unlock(&hdd_context_lock);
2556
2557 return;
2558}
2559
2560static void wlan_hdd_cfg80211_extscan_reset_ssid_hotlist_rsp(void *ctx,
2561 void *pMsg)
2562{
2563 hdd_context_t *pHddCtx = (hdd_context_t *)ctx;
2564 tpSirEXTScanResetSsidHotlistRspParams pData =
2565 (tpSirEXTScanResetSsidHotlistRspParams) pMsg;
2566 struct hdd_ext_scan_context *context;
2567
2568 if (wlan_hdd_validate_context(pHddCtx)) {
2569 return;
2570 }
2571 if (!pMsg)
2572 {
2573 hddLog(VOS_TRACE_LEVEL_ERROR, FL("pMsg is null"));
2574 return;
2575 }
2576
2577 hddLog(VOS_TRACE_LEVEL_INFO, "Req Id %u Status %u", pData->requestId,
2578 pData->status);
2579
2580 context = &pHddCtx->ext_scan_context;
2581 spin_lock(&hdd_context_lock);
2582 if (context->request_id == pData->requestId) {
2583 context->response_status = pData->status ? -EINVAL : 0;
2584 complete(&context->response_event);
2585 }
2586 spin_unlock(&hdd_context_lock);
2587
2588 return;
2589}
2590
2591
Dino Mycle6fb96c12014-06-10 11:52:40 +05302592static void wlan_hdd_cfg80211_extscan_cached_results_ind(void *ctx,
2593 void *pMsg)
2594{
2595 hdd_context_t *pHddCtx = (hdd_context_t *)ctx;
2596 struct sk_buff *skb = NULL;
Padma, Santhosh Kumare1b8a942015-08-25 12:44:24 +05302597 tANI_U32 i = 0, j, resultsPerEvent, scan_id_index;
Dino Mycle6fb96c12014-06-10 11:52:40 +05302598 tANI_S32 totalResults;
2599 tpSirWifiScanResultEvent pData = (tpSirWifiScanResultEvent) pMsg;
Padma, Santhosh Kumare1b8a942015-08-25 12:44:24 +05302600 tpSirWifiScanResult pSirWifiScanResult, head_ptr;
2601 struct hdd_ext_scan_context *context;
2602 bool ignore_cached_results = false;
2603 tExtscanCachedScanResult *result;
2604 struct nlattr *nla_results;
2605 tANI_U16 ieLength= 0;
2606 tANI_U8 *ie = NULL;
Dino Mycle6fb96c12014-06-10 11:52:40 +05302607
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05302608 ENTER();
2609
Padma, Santhosh Kumare1b8a942015-08-25 12:44:24 +05302610 if (wlan_hdd_validate_context(pHddCtx))
Dino Mycle6fb96c12014-06-10 11:52:40 +05302611 return;
Padma, Santhosh Kumare1b8a942015-08-25 12:44:24 +05302612
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05302613 if (!pMsg)
2614 {
2615 hddLog(VOS_TRACE_LEVEL_ERROR, FL("pMsg is null"));
2616 return;
2617 }
2618
Padma, Santhosh Kumare1b8a942015-08-25 12:44:24 +05302619 spin_lock(&hdd_context_lock);
2620 context = &pHddCtx->ext_scan_context;
2621 ignore_cached_results = context->ignore_cached_results;
2622 spin_unlock(&hdd_context_lock);
Dino Mycle6fb96c12014-06-10 11:52:40 +05302623
Padma, Santhosh Kumare1b8a942015-08-25 12:44:24 +05302624 if (ignore_cached_results) {
2625 hddLog(LOGE,
2626 FL("Ignore the cached results received after timeout"));
2627 return;
2628 }
Dino Mycle6fb96c12014-06-10 11:52:40 +05302629
Padma, Santhosh Kumare1b8a942015-08-25 12:44:24 +05302630 hddLog(VOS_TRACE_LEVEL_INFO, "Req Id %u More Data %u No of scan ids %u",
2631 pData->requestId, pData->moreData, pData->scanResultSize);
Dino Mycle6fb96c12014-06-10 11:52:40 +05302632
Padma, Santhosh Kumare1b8a942015-08-25 12:44:24 +05302633 result = (tExtscanCachedScanResult *)&(pData->result);
Dino Mycle6fb96c12014-06-10 11:52:40 +05302634
Padma, Santhosh Kumare1b8a942015-08-25 12:44:24 +05302635 for (scan_id_index = 0; scan_id_index < pData->scanResultSize;
2636 scan_id_index++) {
2637 result+= scan_id_index;
Dino Mycle6fb96c12014-06-10 11:52:40 +05302638
Padma, Santhosh Kumare1b8a942015-08-25 12:44:24 +05302639 totalResults = result->num_results;
2640 hddLog(VOS_TRACE_LEVEL_INFO, "scan_id %u flags %u Num results %u",
2641 result->scan_id, result->flags, totalResults);
2642 i = 0;
Dino Mycle6fb96c12014-06-10 11:52:40 +05302643
Padma, Santhosh Kumare1b8a942015-08-25 12:44:24 +05302644 do{
2645 resultsPerEvent = ((totalResults >= EXTSCAN_MAX_CACHED_RESULTS_PER_IND) ?
2646 EXTSCAN_MAX_CACHED_RESULTS_PER_IND : totalResults);
2647 totalResults -= EXTSCAN_MAX_CACHED_RESULTS_PER_IND;
Dino Mycle6fb96c12014-06-10 11:52:40 +05302648
Padma, Santhosh Kumare1b8a942015-08-25 12:44:24 +05302649 skb = cfg80211_vendor_cmd_alloc_reply_skb(pHddCtx->wiphy,
2650 EXTSCAN_EVENT_BUF_SIZE + NLMSG_HDRLEN);
2651
2652 if (!skb) {
2653 hddLog(VOS_TRACE_LEVEL_ERROR,
2654 FL("cfg80211_vendor_event_alloc failed"));
2655 return;
2656 }
2657
2658 hddLog(VOS_TRACE_LEVEL_INFO, "resultsPerEvent (%u)", resultsPerEvent);
2659
2660 if (nla_put_u32(skb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_REQUEST_ID,
2661 pData->requestId) ||
2662 nla_put_u32(skb,
2663 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_NUM_RESULTS_AVAILABLE,
2664 resultsPerEvent)) {
2665 hddLog(VOS_TRACE_LEVEL_ERROR, FL("put fail"));
2666 goto fail;
2667 }
2668 if (nla_put_u8(skb,
2669 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_MORE_DATA,
2670 pData->moreData ? 1 : (totalResults > 0 ? 1 : 0 )))
Dino Mycle6fb96c12014-06-10 11:52:40 +05302671 {
2672 hddLog(VOS_TRACE_LEVEL_ERROR, FL("put fail"));
2673 goto fail;
2674 }
2675
Padma, Santhosh Kumare1b8a942015-08-25 12:44:24 +05302676 if (nla_put_u32(skb,
2677 QCA_WLAN_VENDOR_ATTR_EXTSCAN_CACHED_RESULTS_SCAN_ID,
2678 result->scan_id)) {
2679 hddLog(LOGE, FL("put fail"));
2680 goto fail;
Dino Mycle6fb96c12014-06-10 11:52:40 +05302681 }
Dino Mycle6fb96c12014-06-10 11:52:40 +05302682
Padma, Santhosh Kumare1b8a942015-08-25 12:44:24 +05302683 nla_results = nla_nest_start(skb,
2684 QCA_WLAN_VENDOR_ATTR_EXTSCAN_CACHED_RESULTS_LIST);
2685 if (!nla_results)
2686 goto fail;
2687
2688 if (resultsPerEvent) {
2689 struct nlattr *aps;
2690 struct nlattr *nla_result;
2691
2692 nla_result = nla_nest_start(skb, scan_id_index);
2693 if(!nla_result)
2694 goto fail;
2695
2696 if (nla_put_u32(skb,
2697 QCA_WLAN_VENDOR_ATTR_EXTSCAN_CACHED_RESULTS_SCAN_ID,
2698 result->scan_id) ||
2699 nla_put_u32(skb,
2700 QCA_WLAN_VENDOR_ATTR_EXTSCAN_CACHED_RESULTS_FLAGS,
2701 result->flags) ||
2702 nla_put_u32(skb,
2703 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_NUM_RESULTS_AVAILABLE,
2704 totalResults)) {
2705 hddLog(LOGE, FL("put fail"));
2706 goto fail;
2707 }
2708
2709 aps = nla_nest_start(skb,
2710 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_LIST);
2711 if (!aps)
2712 {
2713 hddLog(VOS_TRACE_LEVEL_ERROR, FL("put fail"));
2714 goto fail;
2715 }
2716
2717 head_ptr = (tpSirWifiScanResult) &(result->ap);
2718
2719 for (j = 0; j < resultsPerEvent; j++, i++) {
2720 struct nlattr *ap;
2721 pSirWifiScanResult = head_ptr + i;
2722
2723 /*
2724 * Firmware returns timestamp from WiFi turn ON till
2725 * BSSID was cached (in seconds). Add this with
2726 * time gap between system boot up to WiFi turn ON
2727 * to derive the time since boot when the
2728 * BSSID was cached.
2729 */
2730 pSirWifiScanResult->ts += pHddCtx->wifi_turn_on_time_since_boot;
2731 hddLog(VOS_TRACE_LEVEL_INFO, "[index=%u] Timestamp(%llu) "
2732 "Ssid (%s)"
2733 "Bssid: %pM "
2734 "Channel (%u)"
2735 "Rssi (%d)"
2736 "RTT (%u)"
2737 "RTT_SD (%u)"
2738 "Beacon Period %u"
2739 "Capability 0x%x "
2740 "Ie length %d",
2741 i,
2742 pSirWifiScanResult->ts,
2743 pSirWifiScanResult->ssid,
2744 pSirWifiScanResult->bssid,
2745 pSirWifiScanResult->channel,
2746 pSirWifiScanResult->rssi,
2747 pSirWifiScanResult->rtt,
2748 pSirWifiScanResult->rtt_sd,
2749 pSirWifiScanResult->beaconPeriod,
2750 pSirWifiScanResult->capability,
2751 ieLength);
2752
2753 ap = nla_nest_start(skb, j + 1);
2754 if (!ap)
2755 {
2756 hddLog(VOS_TRACE_LEVEL_ERROR, FL("put fail"));
2757 goto fail;
2758 }
2759
2760 if (nla_put_u64(skb,
2761 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_TIME_STAMP,
2762 pSirWifiScanResult->ts) )
2763 {
2764 hddLog(VOS_TRACE_LEVEL_ERROR, FL("put fail"));
2765 goto fail;
2766 }
2767 if (nla_put(skb,
2768 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_SSID,
2769 sizeof(pSirWifiScanResult->ssid),
2770 pSirWifiScanResult->ssid) )
2771 {
2772 hddLog(VOS_TRACE_LEVEL_ERROR, FL("put fail"));
2773 goto fail;
2774 }
2775 if (nla_put(skb,
2776 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_BSSID,
2777 sizeof(pSirWifiScanResult->bssid),
2778 pSirWifiScanResult->bssid) )
2779 {
2780 hddLog(VOS_TRACE_LEVEL_ERROR, FL("put fail"));
2781 goto fail;
2782 }
2783 if (nla_put_u32(skb,
2784 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_CHANNEL,
2785 pSirWifiScanResult->channel) )
2786 {
2787 hddLog(VOS_TRACE_LEVEL_ERROR, FL("put fail"));
2788 goto fail;
2789 }
2790 if (nla_put_s32(skb,
2791 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_RSSI,
2792 pSirWifiScanResult->rssi) )
2793 {
2794 hddLog(VOS_TRACE_LEVEL_ERROR, FL("put fail"));
2795 goto fail;
2796 }
2797 if (nla_put_u32(skb,
2798 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_RTT,
2799 pSirWifiScanResult->rtt) )
2800 {
2801 hddLog(VOS_TRACE_LEVEL_ERROR, FL("put fail"));
2802 goto fail;
2803 }
2804 if (nla_put_u32(skb,
2805 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_RTT_SD,
2806 pSirWifiScanResult->rtt_sd))
2807 {
2808 hddLog(VOS_TRACE_LEVEL_ERROR, FL("put fail"));
2809 goto fail;
2810 }
2811 if (nla_put_u32(skb,
2812 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_BEACON_PERIOD,
2813 pSirWifiScanResult->beaconPeriod))
2814 {
2815 hddLog(VOS_TRACE_LEVEL_ERROR, FL("put fail"));
2816 goto fail;
2817 }
2818 if (nla_put_u32(skb,
2819 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_CAPABILITY,
2820 pSirWifiScanResult->capability))
2821 {
2822 hddLog(VOS_TRACE_LEVEL_ERROR, FL("put fail"));
2823 goto fail;
2824 }
2825 if (nla_put_u32(skb,
2826 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_IE_LENGTH,
2827 ieLength))
2828 {
2829 hddLog(VOS_TRACE_LEVEL_ERROR, FL("put fail"));
2830 goto fail;
2831 }
2832
2833 if (ieLength)
2834 if (nla_put(skb,
2835 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_IE_DATA,
2836 ieLength, ie)) {
2837 hddLog(VOS_TRACE_LEVEL_ERROR, FL("put fail"));
2838 goto fail;
2839 }
2840
2841 nla_nest_end(skb, ap);
2842 }
2843 nla_nest_end(skb, aps);
2844 nla_nest_end(skb, nla_result);
2845 }
2846
2847 nla_nest_end(skb, nla_results);
2848
2849 cfg80211_vendor_cmd_reply(skb);
2850
2851 } while (totalResults > 0);
2852 }
2853
2854 if (!pData->moreData) {
2855 spin_lock(&hdd_context_lock);
2856 context->response_status = 0;
2857 complete(&context->response_event);
2858 spin_unlock(&hdd_context_lock);
2859 }
Dino Mycle6fb96c12014-06-10 11:52:40 +05302860
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05302861 EXIT();
Dino Mycle6fb96c12014-06-10 11:52:40 +05302862 return;
2863fail:
2864 kfree_skb(skb);
2865 return;
2866}
2867
2868static void wlan_hdd_cfg80211_extscan_hotlist_match_ind(void *ctx,
2869 void *pMsg)
2870{
Padma, Santhosh Kumar37f4fd12015-08-19 14:37:37 +05302871 tpSirEXTScanHotlistMatch pData = (tpSirEXTScanHotlistMatch) pMsg;
Dino Mycle6fb96c12014-06-10 11:52:40 +05302872 hdd_context_t *pHddCtx = (hdd_context_t *)ctx;
2873 struct sk_buff *skb = NULL;
Padma, Santhosh Kumar37f4fd12015-08-19 14:37:37 +05302874 tANI_U32 i, index;
Dino Mycle6fb96c12014-06-10 11:52:40 +05302875
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05302876 ENTER();
2877
2878 if (wlan_hdd_validate_context(pHddCtx)) {
Padma, Santhosh Kumar37f4fd12015-08-19 14:37:37 +05302879 hddLog(LOGE,
2880 FL("HDD context is not valid or response"));
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05302881 return;
2882 }
2883 if (!pMsg)
2884 {
2885 hddLog(VOS_TRACE_LEVEL_ERROR, FL("pMsg is null"));
Dino Mycle6fb96c12014-06-10 11:52:40 +05302886 return;
2887 }
2888
Padma, Santhosh Kumar37f4fd12015-08-19 14:37:37 +05302889 if (pData->bss_found)
2890 index = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_HOTLIST_AP_FOUND_INDEX;
2891 else
2892 index = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_HOTLIST_AP_LOST_INDEX;
2893
Dino Mycle6fb96c12014-06-10 11:52:40 +05302894 skb = cfg80211_vendor_event_alloc(pHddCtx->wiphy,
Anand N Sunkad26ca6cc2015-07-29 09:54:52 +05302895#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 18, 0))
2896 NULL,
2897#endif
Dino Mycle6fb96c12014-06-10 11:52:40 +05302898 EXTSCAN_EVENT_BUF_SIZE + NLMSG_HDRLEN,
Padma, Santhosh Kumar37f4fd12015-08-19 14:37:37 +05302899 index, GFP_KERNEL);
Dino Mycle6fb96c12014-06-10 11:52:40 +05302900
2901 if (!skb) {
2902 hddLog(VOS_TRACE_LEVEL_ERROR,
2903 FL("cfg80211_vendor_event_alloc failed"));
2904 return;
2905 }
Dino Mycle6fb96c12014-06-10 11:52:40 +05302906
Padma, Santhosh Kumar37f4fd12015-08-19 14:37:37 +05302907 hddLog(VOS_TRACE_LEVEL_INFO, "Req Id (%u)", pData->requestId);
2908 hddLog(VOS_TRACE_LEVEL_INFO, "Num results (%u)", pData->numHotlistBss);
2909 hddLog(VOS_TRACE_LEVEL_INFO, "More Data (%u)", pData->moreData);
2910 hddLog(VOS_TRACE_LEVEL_INFO, "ap_found %u", pData->bss_found);
2911
2912 for (i = 0; i < pData->numHotlistBss; i++) {
Dino Mycle6fb96c12014-06-10 11:52:40 +05302913 hddLog(VOS_TRACE_LEVEL_INFO, "[index=%u] Timestamp(0x%lld) "
2914 "Ssid (%s) "
2915 "Bssid (" MAC_ADDRESS_STR ") "
2916 "Channel (%u) "
2917 "Rssi (%d) "
2918 "RTT (%u) "
2919 "RTT_SD (%u) ",
2920 i,
Padma, Santhosh Kumar37f4fd12015-08-19 14:37:37 +05302921 pData->bssHotlist[i].ts,
2922 pData->bssHotlist[i].ssid,
2923 MAC_ADDR_ARRAY(pData->bssHotlist[i].bssid),
2924 pData->bssHotlist[i].channel,
2925 pData->bssHotlist[i].rssi,
2926 pData->bssHotlist[i].rtt,
2927 pData->bssHotlist[i].rtt_sd);
Dino Mycle6fb96c12014-06-10 11:52:40 +05302928 }
2929
2930 if (nla_put_u32(skb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_REQUEST_ID,
2931 pData->requestId) ||
2932 nla_put_u32(skb,
2933 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_NUM_RESULTS_AVAILABLE,
Padma, Santhosh Kumar37f4fd12015-08-19 14:37:37 +05302934 pData->numHotlistBss)) {
Dino Mycle6fb96c12014-06-10 11:52:40 +05302935 hddLog(VOS_TRACE_LEVEL_ERROR, FL("put fail"));
2936 goto fail;
2937 }
Padma, Santhosh Kumar37f4fd12015-08-19 14:37:37 +05302938 if (pData->numHotlistBss) {
Dino Mycle6fb96c12014-06-10 11:52:40 +05302939 struct nlattr *aps;
2940
2941 aps = nla_nest_start(skb,
2942 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_LIST);
2943 if (!aps)
2944 goto fail;
2945
Padma, Santhosh Kumar37f4fd12015-08-19 14:37:37 +05302946 for (i = 0; i < pData->numHotlistBss; i++) {
Dino Mycle6fb96c12014-06-10 11:52:40 +05302947 struct nlattr *ap;
2948
2949 ap = nla_nest_start(skb, i + 1);
2950 if (!ap)
2951 goto fail;
2952
2953 if (nla_put_u64(skb,
2954 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_TIME_STAMP,
Padma, Santhosh Kumar37f4fd12015-08-19 14:37:37 +05302955 pData->bssHotlist[i].ts) ||
Dino Mycle6fb96c12014-06-10 11:52:40 +05302956 nla_put(skb,
2957 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_SSID,
Padma, Santhosh Kumar37f4fd12015-08-19 14:37:37 +05302958 sizeof(pData->bssHotlist[i].ssid),
2959 pData->bssHotlist[i].ssid) ||
Dino Mycle6fb96c12014-06-10 11:52:40 +05302960 nla_put(skb,
2961 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_BSSID,
Padma, Santhosh Kumar37f4fd12015-08-19 14:37:37 +05302962 sizeof(pData->bssHotlist[i].bssid),
2963 pData->bssHotlist[i].bssid) ||
Dino Mycle6fb96c12014-06-10 11:52:40 +05302964 nla_put_u32(skb,
2965 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_CHANNEL,
Padma, Santhosh Kumar37f4fd12015-08-19 14:37:37 +05302966 pData->bssHotlist[i].channel) ||
Dino Mycle6fb96c12014-06-10 11:52:40 +05302967 nla_put_s32(skb,
2968 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_RSSI,
Padma, Santhosh Kumar37f4fd12015-08-19 14:37:37 +05302969 pData->bssHotlist[i].rssi) ||
Dino Mycle6fb96c12014-06-10 11:52:40 +05302970 nla_put_u32(skb,
2971 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_RTT,
Padma, Santhosh Kumar37f4fd12015-08-19 14:37:37 +05302972 pData->bssHotlist[i].rtt) ||
Dino Mycle6fb96c12014-06-10 11:52:40 +05302973 nla_put_u32(skb,
2974 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_RTT_SD,
Padma, Santhosh Kumar37f4fd12015-08-19 14:37:37 +05302975 pData->bssHotlist[i].rtt_sd))
Dino Mycle6fb96c12014-06-10 11:52:40 +05302976 goto fail;
2977
2978 nla_nest_end(skb, ap);
2979 }
2980 nla_nest_end(skb, aps);
2981
2982 if (nla_put_u8(skb,
2983 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_MORE_DATA,
2984 pData->moreData))
2985 goto fail;
2986 }
2987
2988 cfg80211_vendor_event(skb, GFP_KERNEL);
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05302989 EXIT();
Dino Mycle6fb96c12014-06-10 11:52:40 +05302990 return;
2991
2992fail:
2993 kfree_skb(skb);
2994 return;
2995
2996}
Dino Mycle6fb96c12014-06-10 11:52:40 +05302997
Padma, Santhosh Kumar9acee012015-08-21 19:58:01 +05302998/**
2999 * wlan_hdd_cfg80211_extscan_hotlist_ssid_match_ind() -
3000 * Handle an SSID hotlist match event
3001 * @ctx: HDD context registered with SME
3002 * @event: The SSID hotlist match event
3003 *
3004 * This function will take an SSID match event that was generated by
3005 * firmware and will convert it into a cfg80211 vendor event which is
3006 * sent to userspace.
3007 *
3008 * Return: none
3009 */
3010static void
3011wlan_hdd_cfg80211_extscan_hotlist_ssid_match_ind(void *ctx,
3012 void *pMsg)
3013{
3014 hdd_context_t *hdd_ctx = ctx;
3015 struct sk_buff *skb;
3016 tANI_U32 i, index;
3017 tpSirEXTScanSsidHotlistMatch pData = (tpSirEXTScanSsidHotlistMatch) pMsg;
3018
3019 ENTER();
3020
3021 if (wlan_hdd_validate_context(hdd_ctx)) {
3022 hddLog(LOGE,
3023 FL("HDD context is not valid or response"));
3024 return;
3025 }
3026 if (!pMsg)
3027 {
3028 hddLog(VOS_TRACE_LEVEL_ERROR, FL("pMsg is null"));
3029 return;
3030 }
3031
3032 if (pData->ssid_found) {
3033 index = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_HOTLIST_SSID_FOUND_INDEX;
3034 hddLog(LOG1, "SSID hotlist found");
3035 } else {
3036 index = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_HOTLIST_SSID_LOST_INDEX;
3037 hddLog(LOG1, "SSID hotlist lost");
3038 }
3039
3040 skb = cfg80211_vendor_event_alloc(hdd_ctx->wiphy,
3041#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 18, 0))
3042 NULL,
3043#endif
3044 EXTSCAN_EVENT_BUF_SIZE + NLMSG_HDRLEN,
3045 index, GFP_KERNEL);
3046
3047 if (!skb) {
3048 hddLog(LOGE, FL("cfg80211_vendor_event_alloc failed"));
3049 return;
3050 }
3051 hddLog(LOG1, "Req Id %u, Num of SSIDs %u, More Data (%u)",
3052 pData->requestId, pData->numHotlistSsid, pData->moreData);
3053
3054 for (i = 0; i < pData->numHotlistSsid; i++) {
3055 hddLog(LOG1, "[i=%d] Timestamp %llu "
3056 "Ssid: %s "
3057 "Bssid (" MAC_ADDRESS_STR ") "
3058 "Channel %u "
3059 "Rssi %d "
3060 "RTT %u "
3061 "RTT_SD %u",
3062 i,
3063 pData->ssidHotlist[i].ts,
3064 pData->ssidHotlist[i].ssid,
3065 MAC_ADDR_ARRAY(pData->ssidHotlist[i].bssid),
3066 pData->ssidHotlist[i].channel,
3067 pData->ssidHotlist[i].rssi,
3068 pData->ssidHotlist[i].rtt,
3069 pData->ssidHotlist[i].rtt_sd);
3070 }
3071
3072 if (nla_put_u32(skb,
3073 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_REQUEST_ID,
3074 pData->requestId) ||
3075 nla_put_u32(skb,
3076 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_NUM_RESULTS_AVAILABLE,
3077 pData->numHotlistSsid)) {
3078 hddLog(LOGE, FL("put fail"));
3079 goto fail;
3080 }
3081
3082 if (pData->numHotlistSsid) {
3083 struct nlattr *aps;
3084 aps = nla_nest_start(skb,
3085 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_LIST);
3086 if (!aps) {
3087 hddLog(LOGE, FL("nest fail"));
3088 goto fail;
3089 }
3090
3091 for (i = 0; i < pData->numHotlistSsid; i++) {
3092 struct nlattr *ap;
3093
3094 ap = nla_nest_start(skb, i);
3095 if (!ap) {
3096 hddLog(LOGE, FL("nest fail"));
3097 goto fail;
3098 }
3099
3100 if (nla_put_u64(skb,
3101 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_TIME_STAMP,
3102 pData->ssidHotlist[i].ts) ||
3103 nla_put(skb,
3104 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_SSID,
3105 sizeof(pData->ssidHotlist[i].ssid),
3106 pData->ssidHotlist[i].ssid) ||
3107 nla_put(skb,
3108 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_BSSID,
3109 sizeof(pData->ssidHotlist[i].bssid),
3110 pData->ssidHotlist[i].bssid) ||
3111 nla_put_u32(skb,
3112 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_CHANNEL,
3113 pData->ssidHotlist[i].channel) ||
3114 nla_put_s32(skb,
3115 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_RSSI,
3116 pData->ssidHotlist[i].rssi) ||
3117 nla_put_u32(skb,
3118 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_RTT,
3119 pData->ssidHotlist[i].rtt) ||
3120 nla_put_u32(skb,
3121 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_RTT_SD,
3122 pData->ssidHotlist[i].rtt_sd)) {
3123 hddLog(LOGE, FL("put fail"));
3124 goto fail;
3125 }
3126 nla_nest_end(skb, ap);
3127 }
3128 nla_nest_end(skb, aps);
3129
3130 if (nla_put_u8(skb,
3131 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_MORE_DATA,
3132 pData->moreData)) {
3133 hddLog(LOGE, FL("put fail"));
3134 goto fail;
3135 }
3136 }
3137
3138 cfg80211_vendor_event(skb, GFP_KERNEL);
3139 return;
3140
3141fail:
3142 kfree_skb(skb);
3143 return;
3144
3145}
3146
3147
Dino Mycle6fb96c12014-06-10 11:52:40 +05303148static void wlan_hdd_cfg80211_extscan_full_scan_result_event(void *ctx,
3149 void *pMsg)
3150{
3151 struct sk_buff *skb;
3152 hdd_context_t *pHddCtx = (hdd_context_t *)ctx;
3153 tpSirWifiFullScanResultEvent pData =
3154 (tpSirWifiFullScanResultEvent) (pMsg);
3155
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05303156 ENTER();
3157
3158 if (wlan_hdd_validate_context(pHddCtx)) {
Padma, Santhosh Kumare1b8a942015-08-25 12:44:24 +05303159 hddLog(LOGE,
3160 FL("HDD context is not valid or response"));
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05303161 return;
3162 }
3163 if (!pMsg)
3164 {
3165 hddLog(VOS_TRACE_LEVEL_ERROR, FL("pMsg is null"));
Dino Mycle6fb96c12014-06-10 11:52:40 +05303166 return;
3167 }
3168
Padma, Santhosh Kumare1b8a942015-08-25 12:44:24 +05303169 /*
3170 * If the full scan result including IE data exceeds NL 4K size
3171 * limitation, drop that beacon/probe rsp frame.
3172 */
3173 if ((sizeof(*pData) + pData->ieLength) >= EXTSCAN_EVENT_BUF_SIZE) {
3174 hddLog(LOGE, FL("Frame exceeded NL size limilation, drop it!"));
3175 return;
3176 }
3177
Dino Mycle6fb96c12014-06-10 11:52:40 +05303178 skb = cfg80211_vendor_event_alloc(pHddCtx->wiphy,
Anand N Sunkad26ca6cc2015-07-29 09:54:52 +05303179#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 18, 0))
3180 NULL,
3181#endif
Dino Mycle6fb96c12014-06-10 11:52:40 +05303182 EXTSCAN_EVENT_BUF_SIZE + NLMSG_HDRLEN,
3183 QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_FULL_SCAN_RESULT_INDEX,
3184 GFP_KERNEL);
3185
3186 if (!skb) {
3187 hddLog(VOS_TRACE_LEVEL_ERROR,
3188 FL("cfg80211_vendor_event_alloc failed"));
3189 return;
3190 }
3191
Dino Mycle6fb96c12014-06-10 11:52:40 +05303192 hddLog(VOS_TRACE_LEVEL_INFO, FL("Req Id (%u)"), pData->requestId);
3193 hddLog(VOS_TRACE_LEVEL_INFO, FL("More Data (%u)"), pData->moreData);
3194 hddLog(VOS_TRACE_LEVEL_INFO, FL("AP Info: Timestamp(0x%llX) "
3195 "Ssid (%s)"
3196 "Bssid (" MAC_ADDRESS_STR ")"
3197 "Channel (%u)"
3198 "Rssi (%d)"
3199 "RTT (%u)"
Padma, Santhosh Kumare1b8a942015-08-25 12:44:24 +05303200 "RTT_SD (%u)"
3201 "Bcn Period %d"
3202 "Capability 0x%X "),
Dino Mycle6fb96c12014-06-10 11:52:40 +05303203 pData->ap.ts,
3204 pData->ap.ssid,
3205 MAC_ADDR_ARRAY(pData->ap.bssid),
3206 pData->ap.channel,
3207 pData->ap.rssi,
3208 pData->ap.rtt,
Padma, Santhosh Kumare1b8a942015-08-25 12:44:24 +05303209 pData->ap.rtt_sd,
3210 pData->ap.beaconPeriod,
3211 pData->ap.capability);
3212
Dino Mycle6fb96c12014-06-10 11:52:40 +05303213 hddLog(VOS_TRACE_LEVEL_INFO, "IE Length (%u)", pData->ieLength);
3214 if (nla_put_u32(skb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_REQUEST_ID,
3215 pData->requestId) ||
3216 nla_put_u64(skb,
3217 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_TIME_STAMP,
3218 pData->ap.ts) ||
3219 nla_put(skb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_SSID,
3220 sizeof(pData->ap.ssid),
3221 pData->ap.ssid) ||
3222 nla_put(skb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_BSSID,
3223 WNI_CFG_BSSID_LEN,
3224 pData->ap.bssid) ||
3225 nla_put_u32(skb,
3226 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_CHANNEL,
3227 pData->ap.channel) ||
Dasari Srinivas90747d72014-10-08 12:16:15 +05303228 nla_put_s32(skb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_RSSI,
Dino Mycle6fb96c12014-06-10 11:52:40 +05303229 pData->ap.rssi) ||
3230 nla_put_u32(skb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_RTT,
3231 pData->ap.rtt) ||
3232 nla_put_u32(skb,
3233 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_RTT_SD,
3234 pData->ap.rtt_sd) ||
3235 nla_put_u16(skb,
3236 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_BEACON_PERIOD,
3237 pData->ap.beaconPeriod) ||
3238 nla_put_u16(skb,
3239 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_CAPABILITY,
3240 pData->ap.capability) ||
3241 nla_put_u32(skb,
3242 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_IE_LENGTH,
Padma, Santhosh Kumare1b8a942015-08-25 12:44:24 +05303243 pData->ieLength) ||
3244 nla_put_u8(skb,
3245 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_MORE_DATA,
3246 pData->moreData))
Dino Mycle6fb96c12014-06-10 11:52:40 +05303247 {
3248 hddLog(VOS_TRACE_LEVEL_ERROR, FL("nla put fail"));
3249 goto nla_put_failure;
3250 }
Padma, Santhosh Kumare1b8a942015-08-25 12:44:24 +05303251
3252 if (pData->ieLength) {
3253 if (nla_put(skb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_IE_DATA,
3254 pData->ieLength,
3255 pData->ie))
3256 {
3257 hddLog(VOS_TRACE_LEVEL_ERROR, FL("nla put fail"));
3258 goto nla_put_failure;
3259 }
Dino Mycle6fb96c12014-06-10 11:52:40 +05303260 }
3261
3262 cfg80211_vendor_event(skb, GFP_KERNEL);
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05303263 EXIT();
Dino Mycle6fb96c12014-06-10 11:52:40 +05303264 return;
3265
3266nla_put_failure:
3267 kfree_skb(skb);
3268 return;
3269}
3270
3271static void wlan_hdd_cfg80211_extscan_scan_res_available_event(void *ctx,
3272 void *pMsg)
3273{
3274 hdd_context_t *pHddCtx = (hdd_context_t *)ctx;
3275 struct sk_buff *skb = NULL;
3276 tpSirEXTScanResultsAvailableIndParams pData =
3277 (tpSirEXTScanResultsAvailableIndParams) pMsg;
3278
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05303279 ENTER();
3280
3281 if (wlan_hdd_validate_context(pHddCtx)){
Padma, Santhosh Kumare1b8a942015-08-25 12:44:24 +05303282 hddLog(LOGE,
3283 FL("HDD context is not valid or response"));
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05303284 return;
3285 }
3286 if (!pMsg)
3287 {
3288 hddLog(VOS_TRACE_LEVEL_ERROR, FL("pMsg is null"));
Dino Mycle6fb96c12014-06-10 11:52:40 +05303289 return;
3290 }
3291
3292 skb = cfg80211_vendor_event_alloc(pHddCtx->wiphy,
Anand N Sunkad26ca6cc2015-07-29 09:54:52 +05303293#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 18, 0))
3294 NULL,
3295#endif
Dino Mycle6fb96c12014-06-10 11:52:40 +05303296 EXTSCAN_EVENT_BUF_SIZE + NLMSG_HDRLEN,
3297 QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_SCAN_RESULTS_AVAILABLE_INDEX,
3298 GFP_KERNEL);
3299
3300 if (!skb) {
3301 hddLog(VOS_TRACE_LEVEL_ERROR,
3302 FL("cfg80211_vendor_event_alloc failed"));
3303 return;
3304 }
3305
Dino Mycle6fb96c12014-06-10 11:52:40 +05303306 hddLog(VOS_TRACE_LEVEL_INFO, "Req Id (%u)", pData->requestId);
3307 hddLog(VOS_TRACE_LEVEL_INFO, "Num results (%u)",
3308 pData->numResultsAvailable);
3309 if (nla_put_u32(skb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_REQUEST_ID,
3310 pData->requestId) ||
3311 nla_put_u32(skb,
3312 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_NUM_RESULTS_AVAILABLE,
3313 pData->numResultsAvailable)) {
3314 hddLog(VOS_TRACE_LEVEL_ERROR, FL("nla put fail"));
3315 goto nla_put_failure;
3316 }
3317
3318 cfg80211_vendor_event(skb, GFP_KERNEL);
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05303319 EXIT();
Dino Mycle6fb96c12014-06-10 11:52:40 +05303320 return;
3321
3322nla_put_failure:
3323 kfree_skb(skb);
3324 return;
3325}
3326
3327static void wlan_hdd_cfg80211_extscan_scan_progress_event(void *ctx, void *pMsg)
3328{
3329 hdd_context_t *pHddCtx = (hdd_context_t *)ctx;
3330 struct sk_buff *skb = NULL;
3331 tpSirEXTScanProgressIndParams pData =
3332 (tpSirEXTScanProgressIndParams) pMsg;
3333
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05303334 ENTER();
3335
3336 if (wlan_hdd_validate_context(pHddCtx)){
Padma, Santhosh Kumare1b8a942015-08-25 12:44:24 +05303337 hddLog(LOGE,
3338 FL("HDD context is not valid or response"));
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05303339 return;
3340 }
3341 if (!pMsg)
3342 {
3343 hddLog(VOS_TRACE_LEVEL_ERROR, FL("pMsg is null"));
Dino Mycle6fb96c12014-06-10 11:52:40 +05303344 return;
3345 }
3346
3347 skb = cfg80211_vendor_event_alloc(pHddCtx->wiphy,
Anand N Sunkad26ca6cc2015-07-29 09:54:52 +05303348#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 18, 0))
3349 NULL,
3350#endif
Dino Mycle6fb96c12014-06-10 11:52:40 +05303351 EXTSCAN_EVENT_BUF_SIZE + NLMSG_HDRLEN,
3352 QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_SCAN_EVENT_INDEX,
3353 GFP_KERNEL);
3354
3355 if (!skb) {
3356 hddLog(VOS_TRACE_LEVEL_ERROR,
3357 FL("cfg80211_vendor_event_alloc failed"));
3358 return;
3359 }
Padma, Santhosh Kumare1b8a942015-08-25 12:44:24 +05303360 hddLog(VOS_TRACE_LEVEL_INFO, FL("Request Id (%u) "), pData->requestId);
Dino Mycle6fb96c12014-06-10 11:52:40 +05303361 hddLog(VOS_TRACE_LEVEL_INFO, "Scan event type (%u)",
3362 pData->extScanEventType);
3363 hddLog(VOS_TRACE_LEVEL_INFO, "Scan event status (%u)",
3364 pData->status);
3365
3366 if (nla_put_u8(skb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_EVENT_TYPE,
3367 pData->extScanEventType) ||
3368 nla_put_u32(skb,
Dasari Srinivas5a288652014-06-30 17:13:22 +05303369 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_REQUEST_ID,
3370 pData->requestId) ||
3371 nla_put_u32(skb,
Dino Mycle6fb96c12014-06-10 11:52:40 +05303372 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_EVENT_STATUS,
3373 pData->status)) {
3374 hddLog(VOS_TRACE_LEVEL_ERROR, FL("nla put fail"));
3375 goto nla_put_failure;
3376 }
3377
3378 cfg80211_vendor_event(skb, GFP_KERNEL);
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05303379 EXIT();
Dino Mycle6fb96c12014-06-10 11:52:40 +05303380 return;
3381
3382nla_put_failure:
3383 kfree_skb(skb);
3384 return;
3385}
3386
3387void wlan_hdd_cfg80211_extscan_callback(void *ctx, const tANI_U16 evType,
3388 void *pMsg)
3389{
3390 hdd_context_t *pHddCtx = (hdd_context_t *)ctx;
3391
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05303392 ENTER();
3393
Dino Mycle6fb96c12014-06-10 11:52:40 +05303394 if (wlan_hdd_validate_context(pHddCtx)) {
Dino Mycle6fb96c12014-06-10 11:52:40 +05303395 return;
3396 }
3397
3398 hddLog(VOS_TRACE_LEVEL_INFO, FL("Rcvd Event (%d)"), evType);
3399
3400
3401 switch(evType) {
3402 case SIR_HAL_EXTSCAN_START_RSP:
3403 wlan_hdd_cfg80211_extscan_start_rsp(ctx, pMsg);
3404 break;
3405
3406 case SIR_HAL_EXTSCAN_STOP_RSP:
3407 wlan_hdd_cfg80211_extscan_stop_rsp(ctx, pMsg);
3408 break;
3409 case SIR_HAL_EXTSCAN_GET_CACHED_RESULTS_RSP:
3410 /* There is no need to send this response to upper layer
3411 Just log the message */
3412 hddLog(VOS_TRACE_LEVEL_INFO,
3413 FL("Rcvd SIR_HAL_EXTSCAN_CACHED_RESULTS_RSP"));
3414 break;
3415 case SIR_HAL_EXTSCAN_SET_BSS_HOTLIST_RSP:
3416 wlan_hdd_cfg80211_extscan_set_bss_hotlist_rsp(ctx, pMsg);
3417 break;
3418
3419 case SIR_HAL_EXTSCAN_RESET_BSS_HOTLIST_RSP:
3420 wlan_hdd_cfg80211_extscan_reset_bss_hotlist_rsp(ctx, pMsg);
3421 break;
3422
Padma, Santhosh Kumar9acee012015-08-21 19:58:01 +05303423 case SIR_HAL_EXTSCAN_SET_SSID_HOTLIST_RSP:
3424 wlan_hdd_cfg80211_extscan_set_ssid_hotlist_rsp(ctx, pMsg);
3425 break;
3426
3427 case SIR_HAL_EXTSCAN_RESET_SSID_HOTLIST_RSP:
3428 wlan_hdd_cfg80211_extscan_reset_ssid_hotlist_rsp(ctx, pMsg);
3429 break;
3430
Dino Mycle6fb96c12014-06-10 11:52:40 +05303431 case SIR_HAL_EXTSCAN_GET_CAPABILITIES_RSP:
Padma, Santhosh Kumara1aa4a32015-06-19 19:00:46 +05303432 wlan_hdd_cfg80211_extscan_get_capabilities_rsp(ctx, pMsg);
Dino Mycle6fb96c12014-06-10 11:52:40 +05303433 break;
3434 case SIR_HAL_EXTSCAN_PROGRESS_IND:
3435 wlan_hdd_cfg80211_extscan_scan_progress_event(ctx, pMsg);
3436 break;
3437 case SIR_HAL_EXTSCAN_SCAN_AVAILABLE_IND:
3438 wlan_hdd_cfg80211_extscan_scan_res_available_event(ctx, pMsg);
3439 break;
3440 case SIR_HAL_EXTSCAN_SCAN_RESULT_IND:
3441 wlan_hdd_cfg80211_extscan_cached_results_ind(ctx, pMsg);
3442 break;
3443 case SIR_HAL_EXTSCAN_HOTLIST_MATCH_IND:
3444 wlan_hdd_cfg80211_extscan_hotlist_match_ind(ctx, pMsg);
3445 break;
Padma, Santhosh Kumar9acee012015-08-21 19:58:01 +05303446 case SIR_HAL_EXTSCAN_SSID_HOTLIST_MATCH_IND:
3447 wlan_hdd_cfg80211_extscan_hotlist_ssid_match_ind(ctx, pMsg);
3448 break;
Dino Mycle6fb96c12014-06-10 11:52:40 +05303449 case SIR_HAL_EXTSCAN_FULL_SCAN_RESULT_IND:
3450 wlan_hdd_cfg80211_extscan_full_scan_result_event(ctx, pMsg);
3451 break;
3452 default:
3453 hddLog(VOS_TRACE_LEVEL_ERROR, FL("invalid event type %d "), evType);
3454 break;
3455 }
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05303456 EXIT();
Dino Mycle6fb96c12014-06-10 11:52:40 +05303457}
3458
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05303459static int __wlan_hdd_cfg80211_extscan_get_capabilities(struct wiphy *wiphy,
3460 struct wireless_dev *wdev,
3461 const void *data, int dataLen)
Dino Mycle6fb96c12014-06-10 11:52:40 +05303462{
Dino Myclee8843b32014-07-04 14:21:45 +05303463 tSirGetEXTScanCapabilitiesReqParams reqMsg;
Dino Mycle6fb96c12014-06-10 11:52:40 +05303464 struct net_device *dev = wdev->netdev;
3465 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
3466 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
3467 struct nlattr
3468 *tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX + 1];
3469 eHalStatus status;
Padma, Santhosh Kumara1aa4a32015-06-19 19:00:46 +05303470 struct hdd_ext_scan_context *context;
3471 unsigned long rc;
3472 int ret;
Dino Mycle6fb96c12014-06-10 11:52:40 +05303473
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05303474 ENTER();
3475
Dino Mycle6fb96c12014-06-10 11:52:40 +05303476 status = wlan_hdd_validate_context(pHddCtx);
3477 if (0 != status)
3478 {
Dino Mycle6fb96c12014-06-10 11:52:40 +05303479 return -EINVAL;
3480 }
Dino Myclee8843b32014-07-04 14:21:45 +05303481 /* check the EXTScan Capability */
3482 if ( (TRUE != pHddCtx->cfg_ini->fEnableEXTScan) ||
Padma, Santhosh Kumar2ac54992015-10-12 18:20:58 +05303483 (TRUE != sme_IsFeatureSupportedByFW(EXTENDED_SCAN)) ||
3484 (TRUE != sme_IsFeatureSupportedByFW(EXT_SCAN_ENHANCED)))
Dino Myclee8843b32014-07-04 14:21:45 +05303485 {
3486 hddLog(VOS_TRACE_LEVEL_ERROR,
3487 FL("EXTScan not enabled/supported by Firmware"));
3488 return -EINVAL;
3489 }
3490
Dino Mycle6fb96c12014-06-10 11:52:40 +05303491 if (nla_parse(tb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX,
3492 data, dataLen,
3493 wlan_hdd_extscan_config_policy)) {
3494 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Invalid ATTR"));
3495 return -EINVAL;
3496 }
3497
3498 /* Parse and fetch request Id */
3499 if (!tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_REQUEST_ID]) {
3500 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr request id failed"));
3501 return -EINVAL;
3502 }
3503
Dino Myclee8843b32014-07-04 14:21:45 +05303504 reqMsg.requestId = nla_get_u32(
Dino Mycle6fb96c12014-06-10 11:52:40 +05303505 tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_REQUEST_ID]);
Dino Myclee8843b32014-07-04 14:21:45 +05303506 hddLog(VOS_TRACE_LEVEL_INFO, FL("Req Id (%d)"), reqMsg.requestId);
Dino Mycle6fb96c12014-06-10 11:52:40 +05303507
Dino Myclee8843b32014-07-04 14:21:45 +05303508 reqMsg.sessionId = pAdapter->sessionId;
3509 hddLog(VOS_TRACE_LEVEL_INFO, FL("Session Id (%d)"), reqMsg.sessionId);
Dino Mycle6fb96c12014-06-10 11:52:40 +05303510
Padma, Santhosh Kumara1aa4a32015-06-19 19:00:46 +05303511 vos_spin_lock_acquire(&hdd_context_lock);
3512 context = &pHddCtx->ext_scan_context;
3513 context->request_id = reqMsg.requestId;
3514 INIT_COMPLETION(context->response_event);
3515 vos_spin_lock_release(&hdd_context_lock);
3516
Dino Myclee8843b32014-07-04 14:21:45 +05303517 status = sme_EXTScanGetCapabilities(pHddCtx->hHal, &reqMsg);
Dino Mycle6fb96c12014-06-10 11:52:40 +05303518 if (!HAL_STATUS_SUCCESS(status)) {
3519 hddLog(VOS_TRACE_LEVEL_ERROR,
3520 FL("sme_EXTScanGetCapabilities failed(err=%d)"), status);
Dino Mycle6fb96c12014-06-10 11:52:40 +05303521 return -EINVAL;
3522 }
Padma, Santhosh Kumara1aa4a32015-06-19 19:00:46 +05303523
3524 rc = wait_for_completion_timeout(&context->response_event,
3525 msecs_to_jiffies(WLAN_WAIT_TIME_EXTSCAN));
3526 if (!rc) {
3527 hddLog(LOGE, FL("Target response timed out"));
3528 return -ETIMEDOUT;
3529 }
3530
3531 ret = wlan_hdd_send_ext_scan_capability(pHddCtx);
3532 if (ret)
3533 hddLog(LOGE, FL("Failed to send ext scan capability to user space"));
3534
3535 return ret;
3536
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05303537 EXIT();
Dino Mycle6fb96c12014-06-10 11:52:40 +05303538 return 0;
3539}
3540
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05303541static int wlan_hdd_cfg80211_extscan_get_capabilities(struct wiphy *wiphy,
3542 struct wireless_dev *wdev,
3543 const void *data, int dataLen)
3544{
3545 int ret = 0;
Dino Mycle6fb96c12014-06-10 11:52:40 +05303546
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05303547 vos_ssr_protect(__func__);
3548 ret = __wlan_hdd_cfg80211_extscan_get_capabilities(wiphy, wdev, data, dataLen);
3549 vos_ssr_unprotect(__func__);
3550
3551 return ret;
3552}
3553
3554static int __wlan_hdd_cfg80211_extscan_get_cached_results(struct wiphy *wiphy,
3555 struct wireless_dev *wdev,
3556 const void *data, int dataLen)
Dino Mycle6fb96c12014-06-10 11:52:40 +05303557{
Dino Myclee8843b32014-07-04 14:21:45 +05303558 tSirEXTScanGetCachedResultsReqParams reqMsg;
Dino Mycle6fb96c12014-06-10 11:52:40 +05303559 struct net_device *dev = wdev->netdev;
3560 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
3561 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
3562 struct nlattr
3563 *tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX + 1];
3564 eHalStatus status;
Padma, Santhosh Kumare1b8a942015-08-25 12:44:24 +05303565 struct hdd_ext_scan_context *context;
3566 unsigned long rc;
3567 int retval;
Dino Mycle6fb96c12014-06-10 11:52:40 +05303568
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05303569 ENTER();
3570
Padma, Santhosh Kumare1b8a942015-08-25 12:44:24 +05303571 if (VOS_FTM_MODE == hdd_get_conparam()) {
3572 hddLog(LOGE, FL("Command not allowed in FTM mode"));
3573 return -EINVAL;
3574 }
3575
Dino Mycle6fb96c12014-06-10 11:52:40 +05303576 status = wlan_hdd_validate_context(pHddCtx);
3577 if (0 != status)
3578 {
Dino Mycle6fb96c12014-06-10 11:52:40 +05303579 return -EINVAL;
3580 }
Dino Myclee8843b32014-07-04 14:21:45 +05303581 /* check the EXTScan Capability */
3582 if ( (TRUE != pHddCtx->cfg_ini->fEnableEXTScan) ||
Padma, Santhosh Kumar2ac54992015-10-12 18:20:58 +05303583 (TRUE != sme_IsFeatureSupportedByFW(EXTENDED_SCAN)) ||
3584 (TRUE != sme_IsFeatureSupportedByFW(EXT_SCAN_ENHANCED)))
Dino Myclee8843b32014-07-04 14:21:45 +05303585 {
3586 hddLog(VOS_TRACE_LEVEL_ERROR,
3587 FL("EXTScan not enabled/supported by Firmware"));
3588 return -EINVAL;
3589 }
3590
Dino Mycle6fb96c12014-06-10 11:52:40 +05303591 if (nla_parse(tb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX,
3592 data, dataLen,
3593 wlan_hdd_extscan_config_policy)) {
3594 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Invalid ATTR"));
3595 return -EINVAL;
3596 }
3597 /* Parse and fetch request Id */
3598 if (!tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_REQUEST_ID]) {
3599 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr request id failed"));
3600 return -EINVAL;
3601 }
Dino Mycle6fb96c12014-06-10 11:52:40 +05303602
Dino Myclee8843b32014-07-04 14:21:45 +05303603 reqMsg.requestId = nla_get_u32(
Dino Mycle6fb96c12014-06-10 11:52:40 +05303604 tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_REQUEST_ID]);
3605
Dino Myclee8843b32014-07-04 14:21:45 +05303606 hddLog(VOS_TRACE_LEVEL_INFO, FL("Req Id (%d)"), reqMsg.requestId);
Dino Mycle6fb96c12014-06-10 11:52:40 +05303607
Dino Myclee8843b32014-07-04 14:21:45 +05303608 reqMsg.sessionId = pAdapter->sessionId;
3609 hddLog(VOS_TRACE_LEVEL_INFO, FL("Session Id (%d)"), reqMsg.sessionId);
Dino Mycle6fb96c12014-06-10 11:52:40 +05303610
3611 /* Parse and fetch flush parameter */
3612 if (!tb
3613 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_GET_CACHED_SCAN_RESULTS_CONFIG_PARAM_FLUSH])
3614 {
3615 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr flush failed"));
3616 goto failed;
3617 }
Dino Myclee8843b32014-07-04 14:21:45 +05303618 reqMsg.flush = nla_get_u8(
Dino Mycle6fb96c12014-06-10 11:52:40 +05303619 tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_GET_CACHED_SCAN_RESULTS_CONFIG_PARAM_FLUSH]);
3620
Dino Myclee8843b32014-07-04 14:21:45 +05303621 hddLog(VOS_TRACE_LEVEL_INFO, FL("Flush (%d)"), reqMsg.flush);
Dino Mycle6fb96c12014-06-10 11:52:40 +05303622
Padma, Santhosh Kumare1b8a942015-08-25 12:44:24 +05303623 spin_lock(&hdd_context_lock);
3624 context = &pHddCtx->ext_scan_context;
3625 context->request_id = reqMsg.requestId;
3626 context->ignore_cached_results = false;
3627 INIT_COMPLETION(context->response_event);
3628 spin_unlock(&hdd_context_lock);
3629
Dino Myclee8843b32014-07-04 14:21:45 +05303630 status = sme_getCachedResults(pHddCtx->hHal, &reqMsg);
Dino Mycle6fb96c12014-06-10 11:52:40 +05303631 if (!HAL_STATUS_SUCCESS(status)) {
3632 hddLog(VOS_TRACE_LEVEL_ERROR,
3633 FL("sme_getCachedResults failed(err=%d)"), status);
Dino Mycle6fb96c12014-06-10 11:52:40 +05303634 return -EINVAL;
3635 }
Padma, Santhosh Kumare1b8a942015-08-25 12:44:24 +05303636
3637 rc = wait_for_completion_timeout(&context->response_event,
3638 msecs_to_jiffies(WLAN_WAIT_TIME_EXTSCAN));
3639 if (!rc) {
3640 hddLog(LOGE, FL("Target response timed out"));
3641 retval = -ETIMEDOUT;
3642 spin_lock(&hdd_context_lock);
3643 context->ignore_cached_results = true;
3644 spin_unlock(&hdd_context_lock);
3645 } else {
3646 spin_lock(&hdd_context_lock);
3647 retval = context->response_status;
3648 spin_unlock(&hdd_context_lock);
3649 }
3650
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05303651 EXIT();
Padma, Santhosh Kumare1b8a942015-08-25 12:44:24 +05303652 return retval;
Dino Mycle6fb96c12014-06-10 11:52:40 +05303653
3654failed:
Dino Mycle6fb96c12014-06-10 11:52:40 +05303655 return -EINVAL;
3656}
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05303657static int wlan_hdd_cfg80211_extscan_get_cached_results(struct wiphy *wiphy,
3658 struct wireless_dev *wdev,
3659 const void *data, int dataLen)
3660{
3661 int ret = 0;
Dino Mycle6fb96c12014-06-10 11:52:40 +05303662
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05303663 vos_ssr_protect(__func__);
3664 ret = __wlan_hdd_cfg80211_extscan_get_cached_results(wiphy, wdev, data, dataLen);
3665 vos_ssr_unprotect(__func__);
3666
3667 return ret;
3668}
3669
3670static int __wlan_hdd_cfg80211_extscan_set_bssid_hotlist(struct wiphy *wiphy,
Dino Mycle6fb96c12014-06-10 11:52:40 +05303671 struct wireless_dev *wdev,
Edhar, Mahesh Kumared8631f2015-01-20 14:31:47 +05303672 const void *data, int dataLen)
Dino Mycle6fb96c12014-06-10 11:52:40 +05303673{
3674 tpSirEXTScanSetBssidHotListReqParams pReqMsg = NULL;
3675 struct net_device *dev = wdev->netdev;
3676 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
3677 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
3678 struct nlattr
3679 *tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX + 1];
3680 struct nlattr
3681 *tb2[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX + 1];
3682 struct nlattr *apTh;
3683 eHalStatus status;
3684 tANI_U8 i = 0;
3685 int rem;
Padma, Santhosh Kumar37f4fd12015-08-19 14:37:37 +05303686 struct hdd_ext_scan_context *context;
3687 tANI_U32 request_id;
3688 unsigned long rc;
3689 int retval;
Dino Mycle6fb96c12014-06-10 11:52:40 +05303690
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05303691 ENTER();
3692
Padma, Santhosh Kumar37f4fd12015-08-19 14:37:37 +05303693 if (VOS_FTM_MODE == hdd_get_conparam()) {
3694 hddLog(LOGE, FL("Command not allowed in FTM mode"));
3695 return -EINVAL;
3696 }
3697
Dino Mycle6fb96c12014-06-10 11:52:40 +05303698 status = wlan_hdd_validate_context(pHddCtx);
3699 if (0 != status)
3700 {
Dino Mycle6fb96c12014-06-10 11:52:40 +05303701 return -EINVAL;
3702 }
Dino Myclee8843b32014-07-04 14:21:45 +05303703 /* check the EXTScan Capability */
3704 if ( (TRUE != pHddCtx->cfg_ini->fEnableEXTScan) ||
Padma, Santhosh Kumar2ac54992015-10-12 18:20:58 +05303705 (TRUE != sme_IsFeatureSupportedByFW(EXTENDED_SCAN)) ||
3706 (TRUE != sme_IsFeatureSupportedByFW(EXT_SCAN_ENHANCED)))
Dino Myclee8843b32014-07-04 14:21:45 +05303707 {
3708 hddLog(VOS_TRACE_LEVEL_ERROR,
3709 FL("EXTScan not enabled/supported by Firmware"));
3710 return -EINVAL;
3711 }
3712
Dino Mycle6fb96c12014-06-10 11:52:40 +05303713 if (nla_parse(tb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX,
3714 data, dataLen,
3715 wlan_hdd_extscan_config_policy)) {
3716 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Invalid ATTR"));
3717 return -EINVAL;
3718 }
3719
3720 /* Parse and fetch request Id */
3721 if (!tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_REQUEST_ID]) {
3722 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr request id failed"));
3723 return -EINVAL;
3724 }
Dino Mycle6fb96c12014-06-10 11:52:40 +05303725 pReqMsg = (tpSirEXTScanSetBssidHotListReqParams)
3726 vos_mem_malloc(sizeof(*pReqMsg));
3727 if (!pReqMsg) {
3728 hddLog(VOS_TRACE_LEVEL_ERROR, FL("vos_mem_malloc failed"));
3729 return -ENOMEM;
3730 }
3731
Dino Myclee8843b32014-07-04 14:21:45 +05303732
Dino Mycle6fb96c12014-06-10 11:52:40 +05303733 pReqMsg->requestId = nla_get_u32(
3734 tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_REQUEST_ID]);
3735 hddLog(VOS_TRACE_LEVEL_INFO, FL("Req Id (%d)"), pReqMsg->requestId);
3736
3737 /* Parse and fetch number of APs */
3738 if (!tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_BSSID_HOTLIST_PARAMS_NUM_AP]) {
3739 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr number of AP failed"));
3740 goto fail;
3741 }
3742
Padma, Santhosh Kumar37f4fd12015-08-19 14:37:37 +05303743 /* Parse and fetch lost ap sample size */
3744 if (!tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_BSSID_HOTLIST_PARAMS_LOST_AP_SAMPLE_SIZE]) {
3745 hddLog(LOGE, FL("attr lost ap sample size failed"));
3746 goto fail;
3747 }
3748
3749 pReqMsg->lostBssidSampleSize = nla_get_u32(
3750 tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_BSSID_HOTLIST_PARAMS_LOST_AP_SAMPLE_SIZE]);
3751 hddLog(LOG1, FL("Lost ap sample size %d"), pReqMsg->lostBssidSampleSize);
3752
Dino Mycle6fb96c12014-06-10 11:52:40 +05303753 pReqMsg->sessionId = pAdapter->sessionId;
3754 hddLog(VOS_TRACE_LEVEL_INFO, FL("Session Id (%d)"), pReqMsg->sessionId);
3755
Padma, Santhosh Kumar37f4fd12015-08-19 14:37:37 +05303756 pReqMsg->numBssid = nla_get_u32(
Dino Mycle6fb96c12014-06-10 11:52:40 +05303757 tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_BSSID_HOTLIST_PARAMS_NUM_AP]);
Padma, Santhosh Kumar37f4fd12015-08-19 14:37:37 +05303758 hddLog(VOS_TRACE_LEVEL_INFO, FL("Number of AP (%d)"), pReqMsg->numBssid);
Dino Mycle6fb96c12014-06-10 11:52:40 +05303759
3760 nla_for_each_nested(apTh,
3761 tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_AP_THRESHOLD_PARAM], rem) {
3762 if(nla_parse(tb2, QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX,
3763 nla_data(apTh), nla_len(apTh),
3764 NULL)) {
3765 hddLog(VOS_TRACE_LEVEL_ERROR, FL("nla_parse failed"));
3766 goto fail;
3767 }
3768
3769 /* Parse and fetch MAC address */
3770 if (!tb2[QCA_WLAN_VENDOR_ATTR_EXTSCAN_AP_THRESHOLD_PARAM_BSSID]) {
3771 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr mac address failed"));
3772 goto fail;
3773 }
3774 memcpy(pReqMsg->ap[i].bssid, nla_data(
3775 tb2[QCA_WLAN_VENDOR_ATTR_EXTSCAN_AP_THRESHOLD_PARAM_BSSID]),
3776 sizeof(tSirMacAddr));
3777 hddLog(VOS_TRACE_LEVEL_INFO, FL("BSSID: %pM "), pReqMsg->ap[i].bssid);
3778
3779 /* Parse and fetch low RSSI */
3780 if (!tb2[QCA_WLAN_VENDOR_ATTR_EXTSCAN_AP_THRESHOLD_PARAM_RSSI_LOW]) {
3781 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr low RSSI failed"));
3782 goto fail;
3783 }
3784 pReqMsg->ap[i].low = nla_get_s32(
3785 tb2[QCA_WLAN_VENDOR_ATTR_EXTSCAN_AP_THRESHOLD_PARAM_RSSI_LOW]);
3786 hddLog(VOS_TRACE_LEVEL_INFO, FL("RSSI low (%d)"), pReqMsg->ap[i].low);
3787
3788 /* Parse and fetch high RSSI */
3789 if (!tb2[QCA_WLAN_VENDOR_ATTR_EXTSCAN_AP_THRESHOLD_PARAM_RSSI_HIGH]) {
3790 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr high RSSI failed"));
3791 goto fail;
3792 }
3793 pReqMsg->ap[i].high = nla_get_s32(
3794 tb2[QCA_WLAN_VENDOR_ATTR_EXTSCAN_AP_THRESHOLD_PARAM_RSSI_HIGH]);
3795 hddLog(VOS_TRACE_LEVEL_INFO, FL("RSSI High (%d)"),
3796 pReqMsg->ap[i].high);
Dino Mycle6fb96c12014-06-10 11:52:40 +05303797 i++;
3798 }
Padma, Santhosh Kumar37f4fd12015-08-19 14:37:37 +05303799
3800 context = &pHddCtx->ext_scan_context;
3801 spin_lock(&hdd_context_lock);
3802 INIT_COMPLETION(context->response_event);
3803 context->request_id = request_id = pReqMsg->requestId;
3804 spin_unlock(&hdd_context_lock);
3805
Dino Mycle6fb96c12014-06-10 11:52:40 +05303806 status = sme_SetBssHotlist(pHddCtx->hHal, pReqMsg);
3807 if (!HAL_STATUS_SUCCESS(status)) {
3808 hddLog(VOS_TRACE_LEVEL_ERROR,
3809 FL("sme_SetBssHotlist failed(err=%d)"), status);
3810 vos_mem_free(pReqMsg);
3811 return -EINVAL;
3812 }
3813
Padma, Santhosh Kumar37f4fd12015-08-19 14:37:37 +05303814 /* request was sent -- wait for the response */
3815 rc = wait_for_completion_timeout(&context->response_event,
3816 msecs_to_jiffies(WLAN_WAIT_TIME_EXTSCAN));
3817
3818 if (!rc) {
3819 hddLog(LOGE, FL("sme_SetBssHotlist timed out"));
3820 retval = -ETIMEDOUT;
3821 } else {
3822 spin_lock(&hdd_context_lock);
3823 if (context->request_id == request_id)
3824 retval = context->response_status;
3825 else
3826 retval = -EINVAL;
3827 spin_unlock(&hdd_context_lock);
3828 }
3829
Dino Myclee8843b32014-07-04 14:21:45 +05303830 vos_mem_free(pReqMsg);
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05303831 EXIT();
Padma, Santhosh Kumar37f4fd12015-08-19 14:37:37 +05303832 return retval;
Dino Mycle6fb96c12014-06-10 11:52:40 +05303833
3834fail:
3835 vos_mem_free(pReqMsg);
3836 return -EINVAL;
3837}
3838
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05303839static int wlan_hdd_cfg80211_extscan_set_bssid_hotlist(struct wiphy *wiphy,
3840 struct wireless_dev *wdev,
3841 const void *data, int dataLen)
3842{
3843 int ret = 0;
3844
3845 vos_ssr_protect(__func__);
3846 ret = __wlan_hdd_cfg80211_extscan_set_bssid_hotlist(wiphy, wdev, data,
3847 dataLen);
3848 vos_ssr_unprotect(__func__);
3849
3850 return ret;
3851}
3852
Padma, Santhosh Kumar9acee012015-08-21 19:58:01 +05303853/*
3854 * define short names for the global vendor params
3855 * used by wlan_hdd_cfg80211_extscan_set_ssid_hotlist()
3856 */
3857#define PARAM_MAX \
3858QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX
3859#define PARAM_REQUEST_ID \
3860QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_REQUEST_ID
3861#define PARAMS_LOST_SSID_SAMPLE_SIZE \
3862QCA_WLAN_VENDOR_ATTR_EXTSCAN_SSID_HOTLIST_PARAMS_LOST_SSID_SAMPLE_SIZE
3863#define PARAMS_NUM_SSID \
3864QCA_WLAN_VENDOR_ATTR_EXTSCAN_SSID_HOTLIST_PARAMS_NUM_SSID
3865#define THRESHOLD_PARAM \
3866QCA_WLAN_VENDOR_ATTR_EXTSCAN_SSID_THRESHOLD_PARAM
3867#define PARAM_SSID \
3868QCA_WLAN_VENDOR_ATTR_EXTSCAN_SSID_THRESHOLD_PARAM_SSID
3869#define PARAM_BAND \
3870QCA_WLAN_VENDOR_ATTR_EXTSCAN_SSID_THRESHOLD_PARAM_BAND
3871#define PARAM_RSSI_LOW \
3872QCA_WLAN_VENDOR_ATTR_EXTSCAN_SSID_THRESHOLD_PARAM_RSSI_LOW
3873#define PARAM_RSSI_HIGH \
3874QCA_WLAN_VENDOR_ATTR_EXTSCAN_SSID_THRESHOLD_PARAM_RSSI_HIGH
3875
3876/**
3877 * __wlan_hdd_cfg80211_extscan_set_ssid_hotlist() - set ssid hot list
3878 * @wiphy: Pointer to wireless phy
3879 * @wdev: Pointer to wireless device
3880 * @data: Pointer to data
3881 * @data_len: Data length
3882 *
3883 * Return: 0 on success, negative errno on failure
3884 */
3885static int
3886__wlan_hdd_cfg80211_extscan_set_ssid_hotlist(struct wiphy *wiphy,
3887 struct wireless_dev *wdev,
3888 const void *data,
3889 int data_len)
3890{
3891 tSirEXTScanSetSsidHotListReqParams *request;
3892 struct net_device *dev = wdev->netdev;
3893 hdd_adapter_t *adapter = WLAN_HDD_GET_PRIV_PTR(dev);
3894 hdd_context_t *hdd_ctx = wiphy_priv(wiphy);
3895 struct nlattr *tb[PARAM_MAX + 1];
3896 struct nlattr *tb2[PARAM_MAX + 1];
3897 struct nlattr *ssids;
3898 struct hdd_ext_scan_context *context;
3899 uint32_t request_id;
3900 char ssid_string[SIR_MAC_MAX_SSID_LENGTH + 1] = {'\0'};
3901 int ssid_len;
3902 eHalStatus status;
3903 int i, rem, retval;
3904 unsigned long rc;
3905
3906 ENTER();
3907
3908 if (VOS_FTM_MODE == hdd_get_conparam()) {
3909 hddLog(LOGE, FL("Command not allowed in FTM mode"));
3910 return -EINVAL;
3911 }
3912
3913 retval = wlan_hdd_validate_context(hdd_ctx);
3914 if (0 != retval) {
3915 hddLog(LOGE, FL("HDD context is not valid"));
3916 return -EINVAL;
3917 }
3918
3919 /* check the EXTScan Capability */
3920 if ( (TRUE != hdd_ctx->cfg_ini->fEnableEXTScan) ||
Padma, Santhosh Kumar2ac54992015-10-12 18:20:58 +05303921 (TRUE != sme_IsFeatureSupportedByFW(EXTENDED_SCAN)) ||
3922 (TRUE != sme_IsFeatureSupportedByFW(EXT_SCAN_ENHANCED)))
Padma, Santhosh Kumar9acee012015-08-21 19:58:01 +05303923 {
3924 hddLog(VOS_TRACE_LEVEL_ERROR,
3925 FL("EXTScan not enabled/supported by Firmware"));
3926 return -EINVAL;
3927 }
3928
3929 if (nla_parse(tb, PARAM_MAX,
3930 data, data_len,
3931 wlan_hdd_extscan_config_policy)) {
3932 hddLog(LOGE, FL("Invalid ATTR"));
3933 return -EINVAL;
3934 }
3935
3936 request = vos_mem_malloc(sizeof(*request));
3937 if (!request) {
3938 hddLog(LOGE, FL("vos_mem_malloc failed"));
3939 return -ENOMEM;
3940 }
3941
3942 /* Parse and fetch request Id */
3943 if (!tb[PARAM_REQUEST_ID]) {
3944 hddLog(LOGE, FL("attr request id failed"));
3945 goto fail;
3946 }
3947
3948 request->request_id = nla_get_u32(tb[PARAM_REQUEST_ID]);
3949 hddLog(LOG1, FL("Request Id %d"), request->request_id);
3950
3951 /* Parse and fetch lost SSID sample size */
3952 if (!tb[PARAMS_LOST_SSID_SAMPLE_SIZE]) {
3953 hddLog(LOGE, FL("attr number of Ssid failed"));
3954 goto fail;
3955 }
3956 request->lost_ssid_sample_size =
3957 nla_get_u32(tb[PARAMS_LOST_SSID_SAMPLE_SIZE]);
3958 hddLog(LOG1, FL("Lost SSID Sample Size %d"),
3959 request->lost_ssid_sample_size);
3960
3961 /* Parse and fetch number of hotlist SSID */
3962 if (!tb[PARAMS_NUM_SSID]) {
3963 hddLog(LOGE, FL("attr number of Ssid failed"));
3964 goto fail;
3965 }
3966 request->ssid_count = nla_get_u32(tb[PARAMS_NUM_SSID]);
3967 hddLog(LOG1, FL("Number of SSID %d"), request->ssid_count);
3968
3969 request->session_id = adapter->sessionId;
3970 hddLog(LOG1, FL("Session Id (%d)"), request->session_id);
3971
3972 i = 0;
3973 nla_for_each_nested(ssids, tb[THRESHOLD_PARAM], rem) {
3974 if (i >= WLAN_EXTSCAN_MAX_HOTLIST_SSIDS) {
3975 hddLog(LOGE,
3976 FL("Too Many SSIDs, %d exceeds %d"),
3977 i, WLAN_EXTSCAN_MAX_HOTLIST_SSIDS);
3978 break;
3979 }
3980 if (nla_parse(tb2, PARAM_MAX,
3981 nla_data(ssids), nla_len(ssids),
3982 wlan_hdd_extscan_config_policy)) {
3983 hddLog(LOGE, FL("nla_parse failed"));
3984 goto fail;
3985 }
3986
3987 /* Parse and fetch SSID */
3988 if (!tb2[PARAM_SSID]) {
3989 hddLog(LOGE, FL("attr ssid failed"));
3990 goto fail;
3991 }
3992 nla_memcpy(ssid_string,
3993 tb2[PARAM_SSID],
3994 sizeof(ssid_string));
3995 hddLog(LOG1, FL("SSID %s"),
3996 ssid_string);
3997 ssid_len = strlen(ssid_string);
3998 memcpy(request->ssid[i].ssid.ssId, ssid_string, ssid_len);
3999 request->ssid[i].ssid.length = ssid_len;
4000 request->ssid[i].ssid.ssId[ssid_len] = '\0';
4001 hddLog(LOG1, FL("After copying SSID %s"),
4002 request->ssid[i].ssid.ssId);
4003 hddLog(LOG1, FL("After copying length: %d"),
4004 ssid_len);
4005
4006 /* Parse and fetch low RSSI */
4007 if (!tb2[PARAM_BAND]) {
4008 hddLog(LOGE, FL("attr band failed"));
4009 goto fail;
4010 }
4011 request->ssid[i].band = nla_get_u8(tb2[PARAM_BAND]);
4012 hddLog(LOG1, FL("band %d"), request->ssid[i].band);
4013
4014 /* Parse and fetch low RSSI */
4015 if (!tb2[PARAM_RSSI_LOW]) {
4016 hddLog(LOGE, FL("attr low RSSI failed"));
4017 goto fail;
4018 }
4019 request->ssid[i].rssi_low = nla_get_s32(tb2[PARAM_RSSI_LOW]);
4020 hddLog(LOG1, FL("RSSI low %d"), request->ssid[i].rssi_low);
4021
4022 /* Parse and fetch high RSSI */
4023 if (!tb2[PARAM_RSSI_HIGH]) {
4024 hddLog(LOGE, FL("attr high RSSI failed"));
4025 goto fail;
4026 }
4027 request->ssid[i].rssi_high = nla_get_u32(tb2[PARAM_RSSI_HIGH]);
4028 hddLog(LOG1, FL("RSSI high %d"), request->ssid[i].rssi_high);
4029 i++;
4030 }
4031
4032 context = &hdd_ctx->ext_scan_context;
4033 spin_lock(&hdd_context_lock);
4034 INIT_COMPLETION(context->response_event);
4035 context->request_id = request_id = request->request_id;
4036 spin_unlock(&hdd_context_lock);
4037
4038 status = sme_set_ssid_hotlist(hdd_ctx->hHal, request);
4039 if (!HAL_STATUS_SUCCESS(status)) {
4040 hddLog(LOGE,
4041 FL("sme_set_ssid_hotlist failed(err=%d)"), status);
4042 goto fail;
4043 }
4044
4045 vos_mem_free(request);
4046
4047 /* request was sent -- wait for the response */
4048 rc = wait_for_completion_timeout(&context->response_event,
4049 msecs_to_jiffies
4050 (WLAN_WAIT_TIME_EXTSCAN));
4051 if (!rc) {
4052 hddLog(LOGE, FL("sme_set_ssid_hotlist timed out"));
4053 retval = -ETIMEDOUT;
4054 } else {
4055 spin_lock(&hdd_context_lock);
4056 if (context->request_id == request_id)
4057 retval = context->response_status;
4058 else
4059 retval = -EINVAL;
4060 spin_unlock(&hdd_context_lock);
4061 }
4062
4063 return retval;
4064
4065fail:
4066 vos_mem_free(request);
4067 return -EINVAL;
4068}
4069
4070/*
4071 * done with short names for the global vendor params
4072 * used by wlan_hdd_cfg80211_extscan_set_ssid_hotlist()
4073 */
4074#undef PARAM_MAX
4075#undef PARAM_REQUEST_ID
4076#undef PARAMS_NUM_SSID
4077#undef THRESHOLD_PARAM
4078#undef PARAM_SSID
4079#undef PARAM_BAND
4080#undef PARAM_RSSI_LOW
4081#undef PARAM_RSSI_HIGH
4082
4083static int wlan_hdd_cfg80211_extscan_set_ssid_hotlist(struct wiphy *wiphy,
4084 struct wireless_dev *wdev,
4085 const void *data, int dataLen)
4086{
4087 int ret = 0;
4088
4089 vos_ssr_protect(__func__);
4090 ret = __wlan_hdd_cfg80211_extscan_set_ssid_hotlist(wiphy, wdev, data,
4091 dataLen);
4092 vos_ssr_unprotect(__func__);
4093
4094 return ret;
4095}
4096
4097static int
4098__wlan_hdd_cfg80211_extscan_reset_ssid_hotlist(struct wiphy *wiphy,
4099 struct wireless_dev *wdev,
4100 const void *data,
4101 int data_len)
4102{
4103 tSirEXTScanResetSsidHotlistReqParams request;
4104 struct net_device *dev = wdev->netdev;
4105 hdd_adapter_t *adapter = WLAN_HDD_GET_PRIV_PTR(dev);
4106 hdd_context_t *hdd_ctx = wiphy_priv(wiphy);
4107 struct nlattr *tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX + 1];
4108 struct hdd_ext_scan_context *context;
4109 uint32_t request_id;
4110 eHalStatus status;
4111 int retval;
4112 unsigned long rc;
4113
4114 ENTER();
4115
4116 if (VOS_FTM_MODE == hdd_get_conparam()) {
4117 hddLog(LOGE, FL("Command not allowed in FTM mode"));
4118 return -EINVAL;
4119 }
4120
4121 retval = wlan_hdd_validate_context(hdd_ctx);
4122 if (0 != retval) {
4123 hddLog(LOGE, FL("HDD context is not valid"));
4124 return -EINVAL;
4125 }
4126
4127 /* check the EXTScan Capability */
4128 if ( (TRUE != hdd_ctx->cfg_ini->fEnableEXTScan) ||
Padma, Santhosh Kumar2ac54992015-10-12 18:20:58 +05304129 (TRUE != sme_IsFeatureSupportedByFW(EXTENDED_SCAN)) ||
4130 (TRUE != sme_IsFeatureSupportedByFW(EXT_SCAN_ENHANCED)))
Padma, Santhosh Kumar9acee012015-08-21 19:58:01 +05304131 {
4132 hddLog(LOGE,
4133 FL("EXTScan not enabled/supported by Firmware"));
4134 return -EINVAL;
4135 }
4136
4137 if (nla_parse(tb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX,
4138 data, data_len,
4139 wlan_hdd_extscan_config_policy)) {
4140 hddLog(LOGE, FL("Invalid ATTR"));
4141 return -EINVAL;
4142 }
4143
4144 /* Parse and fetch request Id */
4145 if (!tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_REQUEST_ID]) {
4146 hddLog(LOGE, FL("attr request id failed"));
4147 return -EINVAL;
4148 }
4149
4150 request.requestId = nla_get_u32(
4151 tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_REQUEST_ID]);
4152 request.sessionId = adapter->sessionId;
4153 hddLog(LOG1, FL("Request Id %d Session Id %d"), request.requestId,
4154 request.sessionId);
4155
4156 context = &hdd_ctx->ext_scan_context;
4157 spin_lock(&hdd_context_lock);
4158 INIT_COMPLETION(context->response_event);
4159 context->request_id = request_id = request.requestId;
4160 spin_unlock(&hdd_context_lock);
4161
4162 status = sme_reset_ssid_hotlist(hdd_ctx->hHal, &request);
4163 if (!HAL_STATUS_SUCCESS(status)) {
4164 hddLog(LOGE,
4165 FL("sme_reset_ssid_hotlist failed(err=%d)"), status);
4166 return -EINVAL;
4167 }
4168
4169 /* request was sent -- wait for the response */
4170 rc = wait_for_completion_timeout(&context->response_event,
4171 msecs_to_jiffies
4172 (WLAN_WAIT_TIME_EXTSCAN));
4173 if (!rc) {
4174 hddLog(LOGE, FL("sme_reset_ssid_hotlist timed out"));
4175 retval = -ETIMEDOUT;
4176 } else {
4177 spin_lock(&hdd_context_lock);
4178 if (context->request_id == request_id)
4179 retval = context->response_status;
4180 else
4181 retval = -EINVAL;
4182 spin_unlock(&hdd_context_lock);
4183 }
4184
4185 return retval;
4186}
4187
4188static int
4189wlan_hdd_cfg80211_extscan_reset_ssid_hotlist(struct wiphy *wiphy,
4190 struct wireless_dev *wdev,
4191 const void *data,
4192 int data_len)
4193{
4194 int ret;
4195
4196 vos_ssr_protect(__func__);
4197 ret = __wlan_hdd_cfg80211_extscan_reset_ssid_hotlist(wiphy, wdev,
4198 data, data_len);
4199 vos_ssr_unprotect(__func__);
4200
4201 return ret;
4202}
4203
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05304204static int __wlan_hdd_cfg80211_extscan_get_valid_channels(struct wiphy *wiphy,
Dino Mycle6fb96c12014-06-10 11:52:40 +05304205 struct wireless_dev *wdev,
Jeff Johnson393c2702014-12-16 11:09:35 +05304206 const void *data, int dataLen)
Dino Mycle6fb96c12014-06-10 11:52:40 +05304207{
4208 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
4209 tANI_U32 ChannelList[WNI_CFG_VALID_CHANNEL_LIST_LEN] = {0};
4210 tANI_U8 numChannels = 0;
4211 struct nlattr *tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX + 1];
Padma, Santhosh Kumar387aa9c2015-06-19 15:39:37 +05304212 tANI_U32 requestId, maxChannels;
Dino Mycle6fb96c12014-06-10 11:52:40 +05304213 tWifiBand wifiBand;
4214 eHalStatus status;
4215 struct sk_buff *replySkb;
4216 tANI_U8 i;
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05304217 int ret;
Dino Mycle6fb96c12014-06-10 11:52:40 +05304218
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05304219 ENTER();
4220
Dino Mycle6fb96c12014-06-10 11:52:40 +05304221 status = wlan_hdd_validate_context(pHddCtx);
4222 if (0 != status)
4223 {
Dino Mycle6fb96c12014-06-10 11:52:40 +05304224 return -EINVAL;
4225 }
Dino Myclee8843b32014-07-04 14:21:45 +05304226
Dino Mycle6fb96c12014-06-10 11:52:40 +05304227 if (nla_parse(tb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX,
4228 data, dataLen,
4229 wlan_hdd_extscan_config_policy)) {
4230 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Invalid ATTR"));
4231 return -EINVAL;
4232 }
4233
4234 /* Parse and fetch request Id */
4235 if (!tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_REQUEST_ID]) {
4236 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr request id failed"));
4237 return -EINVAL;
4238 }
4239 requestId = nla_get_u32(
4240 tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_REQUEST_ID]);
4241 hddLog(VOS_TRACE_LEVEL_INFO, FL("Req Id (%d)"), requestId);
4242
4243 /* Parse and fetch wifi band */
4244 if (!tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_GET_VALID_CHANNELS_CONFIG_PARAM_WIFI_BAND])
4245 {
4246 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr wifi band failed"));
4247 return -EINVAL;
4248 }
4249 wifiBand = nla_get_u32(
4250 tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_GET_VALID_CHANNELS_CONFIG_PARAM_WIFI_BAND]);
4251 hddLog(VOS_TRACE_LEVEL_INFO, FL("Wifi band (%d)"), wifiBand);
4252
Padma, Santhosh Kumar387aa9c2015-06-19 15:39:37 +05304253 /* Parse and fetch max channels */
4254 if (!tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_GET_VALID_CHANNELS_CONFIG_PARAM_MAX_CHANNELS])
4255 {
4256 hddLog(LOGE, FL("attr max channels failed"));
4257 return -EINVAL;
4258 }
4259 maxChannels = nla_get_u32(
4260 tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_GET_VALID_CHANNELS_CONFIG_PARAM_MAX_CHANNELS]);
4261 hddLog(VOS_TRACE_LEVEL_INFO, FL("Max channels %d"), maxChannels);
4262
Dino Mycle6fb96c12014-06-10 11:52:40 +05304263 status = sme_GetValidChannelsByBand((tHalHandle)(pHddCtx->hHal),
4264 wifiBand, ChannelList,
4265 &numChannels);
4266 if (eHAL_STATUS_SUCCESS != status) {
4267 hddLog(VOS_TRACE_LEVEL_ERROR,
4268 FL("sme_GetValidChannelsByBand failed (err=%d)"), status);
4269 return -EINVAL;
4270 }
Padma, Santhosh Kumar387aa9c2015-06-19 15:39:37 +05304271
4272 numChannels = VOS_MIN(numChannels, maxChannels);
Dino Mycle6fb96c12014-06-10 11:52:40 +05304273 hddLog(VOS_TRACE_LEVEL_INFO, FL("Number of channels (%d)"), numChannels);
Padma, Santhosh Kumar387aa9c2015-06-19 15:39:37 +05304274
Dino Mycle6fb96c12014-06-10 11:52:40 +05304275 for (i = 0; i < numChannels; i++)
4276 hddLog(VOS_TRACE_LEVEL_INFO, "Channel: %u ", ChannelList[i]);
4277
4278 replySkb = cfg80211_vendor_cmd_alloc_reply_skb(wiphy, sizeof(u32) +
4279 sizeof(u32) * numChannels +
4280 NLMSG_HDRLEN);
4281
4282 if (!replySkb) {
4283 hddLog(VOS_TRACE_LEVEL_ERROR,
4284 FL("valid channels: buffer alloc fail"));
4285 return -EINVAL;
4286 }
4287 if (nla_put_u32(replySkb,
4288 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_NUM_CHANNELS,
4289 numChannels) ||
4290 nla_put(replySkb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_CHANNELS,
4291 sizeof(u32) * numChannels, ChannelList)) {
4292
4293 hddLog(VOS_TRACE_LEVEL_ERROR, FL("nla put fail"));
4294 kfree_skb(replySkb);
4295 return -EINVAL;
4296 }
4297
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05304298 ret = cfg80211_vendor_cmd_reply(replySkb);
4299
4300 EXIT();
4301 return ret;
Dino Mycle6fb96c12014-06-10 11:52:40 +05304302}
4303
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05304304static int wlan_hdd_cfg80211_extscan_get_valid_channels(struct wiphy *wiphy,
4305 struct wireless_dev *wdev,
4306 const void *data, int dataLen)
4307{
4308 int ret = 0;
4309
4310 vos_ssr_protect(__func__);
4311 ret = __wlan_hdd_cfg80211_extscan_get_valid_channels(wiphy, wdev, data,
4312 dataLen);
4313 vos_ssr_unprotect(__func__);
4314
4315 return ret;
4316}
4317
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05304318static int hdd_extscan_start_fill_bucket_channel_spec(
4319 hdd_context_t *pHddCtx,
4320 tpSirEXTScanStartReqParams pReqMsg,
4321 struct nlattr **tb)
4322{
4323 struct nlattr *bucket[
4324 QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX + 1];
4325 struct nlattr *channel[
4326 QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX + 1];
4327 struct nlattr *buckets;
4328 struct nlattr *channels;
4329 int rem1, rem2;
4330 eHalStatus status;
4331 tANI_U8 bktIndex, j, numChannels;
4332 tANI_U32 chanList[WNI_CFG_VALID_CHANNEL_LIST_LEN] = {0};
4333 tANI_U32 passive_max_chn_time, active_max_chn_time;
4334
4335 bktIndex = 0;
4336
4337 nla_for_each_nested(buckets,
4338 tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC], rem1) {
4339 if (nla_parse(bucket,
4340 QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX,
4341 nla_data(buckets), nla_len(buckets), NULL)) {
4342 hddLog(LOGE, FL("nla_parse failed"));
4343 return -EINVAL;
4344 }
4345
4346 /* Parse and fetch bucket spec */
4347 if (!bucket[QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_INDEX]) {
4348 hddLog(LOGE, FL("attr bucket index failed"));
4349 return -EINVAL;
4350 }
4351 pReqMsg->buckets[bktIndex].bucket = nla_get_u8(
4352 bucket[QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_INDEX]);
4353 hddLog(LOG1, FL("Bucket spec Index %d"),
4354 pReqMsg->buckets[bktIndex].bucket);
4355
4356 /* Parse and fetch wifi band */
4357 if (!bucket[QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_BAND]) {
4358 hddLog(LOGE, FL("attr wifi band failed"));
4359 return -EINVAL;
4360 }
4361 pReqMsg->buckets[bktIndex].band = nla_get_u8(
4362 bucket[QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_BAND]);
4363 hddLog(LOG1, FL("Wifi band %d"),
4364 pReqMsg->buckets[bktIndex].band);
4365
4366 /* Parse and fetch period */
4367 if (!bucket[QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_PERIOD]) {
4368 hddLog(LOGE, FL("attr period failed"));
4369 return -EINVAL;
4370 }
4371 pReqMsg->buckets[bktIndex].period = nla_get_u32(
4372 bucket[QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_PERIOD]);
4373 hddLog(LOG1, FL("period %d"),
4374 pReqMsg->buckets[bktIndex].period);
4375
4376 /* Parse and fetch report events */
4377 if (!bucket[
4378 QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_REPORT_EVENTS]) {
4379 hddLog(LOGE, FL("attr report events failed"));
4380 return -EINVAL;
4381 }
4382 pReqMsg->buckets[bktIndex].reportEvents = nla_get_u8(
4383 bucket[
4384 QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_REPORT_EVENTS]);
4385 hddLog(LOG1, FL("report events %d"),
4386 pReqMsg->buckets[bktIndex].reportEvents);
4387
4388 /* Parse and fetch max period */
4389 if (!bucket[QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_MAX_PERIOD]) {
4390 hddLog(LOGE, FL("attr max period failed"));
4391 return -EINVAL;
4392 }
4393 pReqMsg->buckets[bktIndex].max_period = nla_get_u32(
4394 bucket[QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_MAX_PERIOD]);
4395 hddLog(LOG1, FL("max period %u"),
4396 pReqMsg->buckets[bktIndex].max_period);
4397
4398 /* Parse and fetch exponent */
4399 if (!bucket[QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_EXPONENT]) {
4400 hddLog(LOGE, FL("attr exponent failed"));
4401 return -EINVAL;
4402 }
4403 pReqMsg->buckets[bktIndex].exponent = nla_get_u32(
4404 bucket[QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_EXPONENT]);
4405 hddLog(LOG1, FL("exponent %u"),
4406 pReqMsg->buckets[bktIndex].exponent);
4407
4408 /* Parse and fetch step count */
4409 if (!bucket[QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_STEP_COUNT]) {
4410 hddLog(LOGE, FL("attr step count failed"));
4411 return -EINVAL;
4412 }
4413 pReqMsg->buckets[bktIndex].step_count = nla_get_u32(
4414 bucket[QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_STEP_COUNT]);
4415 hddLog(LOG1, FL("Step count %u"),
4416 pReqMsg->buckets[bktIndex].step_count);
4417
4418 ccmCfgGetInt(pHddCtx->hHal, WNI_CFG_PASSIVE_MAXIMUM_CHANNEL_TIME, &passive_max_chn_time);
4419 ccmCfgGetInt(pHddCtx->hHal, WNI_CFG_PASSIVE_MAXIMUM_CHANNEL_TIME, &active_max_chn_time);
4420
4421 /* Framework shall pass the channel list if the input WiFi band is
4422 * WIFI_BAND_UNSPECIFIED.
4423 * If the input WiFi band is specified (any value other than
4424 * WIFI_BAND_UNSPECIFIED) then driver populates the channel list
4425 */
4426 if (pReqMsg->buckets[bktIndex].band != WIFI_BAND_UNSPECIFIED) {
4427 numChannels = 0;
4428 hddLog(LOG1, "WiFi band is specified, driver to fill channel list");
4429 status = sme_GetValidChannelsByBand(pHddCtx->hHal,
4430 pReqMsg->buckets[bktIndex].band,
4431 chanList, &numChannels);
4432 if (!HAL_STATUS_SUCCESS(status)) {
4433 hddLog(LOGE,
4434 FL("sme_GetValidChannelsByBand failed (err=%d)"),
4435 status);
4436 return -EINVAL;
4437 }
4438
4439 pReqMsg->buckets[bktIndex].numChannels =
4440 VOS_MIN(numChannels, WLAN_EXTSCAN_MAX_CHANNELS);
4441 hddLog(LOG1, FL("Num channels %d"),
4442 pReqMsg->buckets[bktIndex].numChannels);
4443
4444 for (j = 0; j < pReqMsg->buckets[bktIndex].numChannels;
4445 j++) {
4446 pReqMsg->buckets[bktIndex].channels[j].channel =
4447 chanList[j];
4448 pReqMsg->buckets[bktIndex].channels[j].
4449 chnlClass = 0;
4450 if (CSR_IS_CHANNEL_DFS(
4451 vos_freq_to_chan(chanList[j]))) {
4452 pReqMsg->buckets[bktIndex].channels[j].
4453 passive = 1;
4454 pReqMsg->buckets[bktIndex].channels[j].
4455 dwellTimeMs = passive_max_chn_time;
4456 } else {
4457 pReqMsg->buckets[bktIndex].channels[j].
4458 passive = 0;
4459 pReqMsg->buckets[bktIndex].channels[j].
4460 dwellTimeMs = active_max_chn_time;
4461 }
4462
4463 hddLog(LOG1,
4464 "Channel %u Passive %u Dwell time %u ms",
4465 pReqMsg->buckets[bktIndex].channels[j].channel,
4466 pReqMsg->buckets[bktIndex].channels[j].passive,
4467 pReqMsg->buckets[bktIndex].channels[j].dwellTimeMs);
4468 }
4469
4470 bktIndex++;
4471 continue;
4472 }
4473
4474 /* Parse and fetch number of channels */
4475 if (!bucket[
4476 QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_NUM_CHANNEL_SPECS]) {
4477 hddLog(LOGE, FL("attr num channels failed"));
4478 return -EINVAL;
4479 }
4480
4481 pReqMsg->buckets[bktIndex].numChannels =
4482 nla_get_u32(bucket[
4483 QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_NUM_CHANNEL_SPECS]);
4484 hddLog(LOG1, FL("num channels %d"),
4485 pReqMsg->buckets[bktIndex].numChannels);
4486
4487 if (!bucket[QCA_WLAN_VENDOR_ATTR_EXTSCAN_CHANNEL_SPEC]) {
4488 hddLog(LOGE, FL("attr channel spec failed"));
4489 return -EINVAL;
4490 }
4491
4492 j = 0;
4493 nla_for_each_nested(channels,
4494 bucket[QCA_WLAN_VENDOR_ATTR_EXTSCAN_CHANNEL_SPEC], rem2) {
4495 if (nla_parse(channel,
4496 QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX,
4497 nla_data(channels), nla_len(channels),
4498 wlan_hdd_extscan_config_policy)) {
4499 hddLog(LOGE, FL("nla_parse failed"));
4500 return -EINVAL;
4501 }
4502
4503 /* Parse and fetch channel */
4504 if (!channel[
4505 QCA_WLAN_VENDOR_ATTR_EXTSCAN_CHANNEL_SPEC_CHANNEL]) {
4506 hddLog(LOGE, FL("attr channel failed"));
4507 return -EINVAL;
4508 }
4509 pReqMsg->buckets[bktIndex].channels[j].channel =
4510 nla_get_u32(channel[
4511 QCA_WLAN_VENDOR_ATTR_EXTSCAN_CHANNEL_SPEC_CHANNEL]);
4512 hddLog(LOG1, FL("channel %u"),
4513 pReqMsg->buckets[bktIndex].channels[j].channel);
4514
4515 /* Parse and fetch dwell time */
4516 if (!channel[
4517 QCA_WLAN_VENDOR_ATTR_EXTSCAN_CHANNEL_SPEC_DWELL_TIME]) {
4518 hddLog(LOGE, FL("attr dwelltime failed"));
4519 return -EINVAL;
4520 }
4521 pReqMsg->buckets[bktIndex].channels[j].dwellTimeMs =
4522 nla_get_u32(channel[
4523 QCA_WLAN_VENDOR_ATTR_EXTSCAN_CHANNEL_SPEC_DWELL_TIME]);
4524
4525 hddLog(LOG1, FL("Dwell time (%u ms)"),
4526 pReqMsg->buckets[bktIndex].channels[j].dwellTimeMs);
4527
4528
4529 /* Parse and fetch channel spec passive */
4530 if (!channel[
4531 QCA_WLAN_VENDOR_ATTR_EXTSCAN_CHANNEL_SPEC_PASSIVE]) {
4532 hddLog(LOGE,
4533 FL("attr channel spec passive failed"));
4534 return -EINVAL;
4535 }
4536 pReqMsg->buckets[bktIndex].channels[j].passive =
4537 nla_get_u8(channel[
4538 QCA_WLAN_VENDOR_ATTR_EXTSCAN_CHANNEL_SPEC_PASSIVE]);
4539 hddLog(LOG1, FL("Chnl spec passive %u"),
4540 pReqMsg->buckets[bktIndex].channels[j].passive);
4541
4542 j++;
4543 }
4544
4545 bktIndex++;
4546 }
4547
4548 return 0;
4549}
4550
4551
4552/*
4553 * define short names for the global vendor params
4554 * used by wlan_hdd_cfg80211_extscan_start()
4555 */
4556#define PARAM_MAX \
4557QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX
4558#define PARAM_REQUEST_ID \
4559QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_REQUEST_ID
4560#define PARAM_BASE_PERIOD \
4561QCA_WLAN_VENDOR_ATTR_EXTSCAN_SCAN_CMD_PARAMS_BASE_PERIOD
4562#define PARAM_MAX_AP_PER_SCAN \
4563QCA_WLAN_VENDOR_ATTR_EXTSCAN_SCAN_CMD_PARAMS_MAX_AP_PER_SCAN
4564#define PARAM_RPT_THRHLD_PERCENT \
4565QCA_WLAN_VENDOR_ATTR_EXTSCAN_SCAN_CMD_PARAMS_REPORT_THRESHOLD_PERCENT
4566#define PARAM_RPT_THRHLD_NUM_SCANS \
4567QCA_WLAN_VENDOR_ATTR_EXTSCAN_SCAN_CMD_PARAMS_REPORT_THRESHOLD_NUM_SCANS
4568#define PARAM_NUM_BUCKETS \
4569QCA_WLAN_VENDOR_ATTR_EXTSCAN_SCAN_CMD_PARAMS_NUM_BUCKETS
4570
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05304571static int __wlan_hdd_cfg80211_extscan_start(struct wiphy *wiphy,
Dino Mycle6fb96c12014-06-10 11:52:40 +05304572 struct wireless_dev *wdev,
Jeff Johnson393c2702014-12-16 11:09:35 +05304573 const void *data, int dataLen)
Dino Mycle6fb96c12014-06-10 11:52:40 +05304574{
Dino Myclee8843b32014-07-04 14:21:45 +05304575 tpSirEXTScanStartReqParams pReqMsg = NULL;
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05304576 struct net_device *dev = wdev->netdev;
4577 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
4578 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
4579 struct nlattr *tb[PARAM_MAX + 1];
4580 int retval;
Dino Mycle6fb96c12014-06-10 11:52:40 +05304581 eHalStatus status;
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05304582 tANI_U32 request_id;
4583 struct hdd_ext_scan_context *context;
4584 unsigned long rc;
Dino Mycle6fb96c12014-06-10 11:52:40 +05304585
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05304586 ENTER();
4587
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05304588 if (VOS_FTM_MODE == hdd_get_conparam()) {
4589 hddLog(LOGE, FL("Command not allowed in FTM mode"));
4590 return -EINVAL;
4591 }
4592
Dino Mycle6fb96c12014-06-10 11:52:40 +05304593 status = wlan_hdd_validate_context(pHddCtx);
4594 if (0 != status)
4595 {
Dino Mycle6fb96c12014-06-10 11:52:40 +05304596 return -EINVAL;
4597 }
Dino Myclee8843b32014-07-04 14:21:45 +05304598 /* check the EXTScan Capability */
4599 if ( (TRUE != pHddCtx->cfg_ini->fEnableEXTScan) ||
Padma, Santhosh Kumar2ac54992015-10-12 18:20:58 +05304600 (TRUE != sme_IsFeatureSupportedByFW(EXTENDED_SCAN)) ||
4601 (TRUE != sme_IsFeatureSupportedByFW(EXT_SCAN_ENHANCED)))
Dino Myclee8843b32014-07-04 14:21:45 +05304602 {
4603 hddLog(VOS_TRACE_LEVEL_ERROR,
4604 FL("EXTScan not enabled/supported by Firmware"));
4605 return -EINVAL;
4606 }
4607
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05304608 if (nla_parse(tb, PARAM_MAX,
Dino Mycle6fb96c12014-06-10 11:52:40 +05304609 data, dataLen,
4610 wlan_hdd_extscan_config_policy)) {
4611 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Invalid ATTR"));
4612 return -EINVAL;
4613 }
4614
4615 /* Parse and fetch request Id */
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05304616 if (!tb[PARAM_REQUEST_ID]) {
Dino Mycle6fb96c12014-06-10 11:52:40 +05304617 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr request id failed"));
4618 return -EINVAL;
4619 }
4620
Dino Myclee8843b32014-07-04 14:21:45 +05304621 pReqMsg = (tpSirEXTScanStartReqParams)
4622 vos_mem_malloc(sizeof(*pReqMsg));
Dino Mycle6fb96c12014-06-10 11:52:40 +05304623 if (!pReqMsg) {
Dino Myclee8843b32014-07-04 14:21:45 +05304624 hddLog(VOS_TRACE_LEVEL_ERROR, FL("vos_mem_malloc failed"));
4625 return -ENOMEM;
Dino Mycle6fb96c12014-06-10 11:52:40 +05304626 }
4627
4628 pReqMsg->requestId = nla_get_u32(
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05304629 tb[PARAM_REQUEST_ID]);
Dino Mycle6fb96c12014-06-10 11:52:40 +05304630 hddLog(VOS_TRACE_LEVEL_INFO, FL("Req Id (%d)"), pReqMsg->requestId);
4631
4632 pReqMsg->sessionId = pAdapter->sessionId;
4633 hddLog(VOS_TRACE_LEVEL_INFO, FL("Session Id (%d)"), pReqMsg->sessionId);
4634
4635 /* Parse and fetch base period */
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05304636 if (!tb[PARAM_BASE_PERIOD]) {
Dino Mycle6fb96c12014-06-10 11:52:40 +05304637 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr base period failed"));
4638 goto fail;
4639 }
4640 pReqMsg->basePeriod = nla_get_u32(
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05304641 tb[PARAM_BASE_PERIOD]);
Dino Mycle6fb96c12014-06-10 11:52:40 +05304642 hddLog(VOS_TRACE_LEVEL_INFO, FL("Base Period (%d)"),
4643 pReqMsg->basePeriod);
4644
4645 /* Parse and fetch max AP per scan */
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05304646 if (!tb[PARAM_MAX_AP_PER_SCAN]) {
Dino Mycle6fb96c12014-06-10 11:52:40 +05304647 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr max_ap_per_scan failed"));
4648 goto fail;
4649 }
4650 pReqMsg->maxAPperScan = nla_get_u32(
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05304651 tb[PARAM_MAX_AP_PER_SCAN]);
Dino Mycle6fb96c12014-06-10 11:52:40 +05304652 hddLog(VOS_TRACE_LEVEL_INFO, FL("Max AP per Scan (%d)"),
4653 pReqMsg->maxAPperScan);
4654
4655 /* Parse and fetch report threshold */
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05304656 if (!tb[PARAM_RPT_THRHLD_PERCENT]) {
Dino Mycle6fb96c12014-06-10 11:52:40 +05304657 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr report_threshold failed"));
4658 goto fail;
4659 }
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05304660 pReqMsg->reportThresholdPercent = nla_get_u8(
4661 tb[PARAM_RPT_THRHLD_PERCENT]);
Dino Mycle6fb96c12014-06-10 11:52:40 +05304662 hddLog(VOS_TRACE_LEVEL_INFO, FL("Report Threshold (%d)"),
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05304663 pReqMsg->reportThresholdPercent);
4664
4665 /* Parse and fetch report threshold num scans */
4666 if (!tb[PARAM_RPT_THRHLD_NUM_SCANS]) {
4667 hddLog(LOGE, FL("attr report_threshold num scans failed"));
4668 goto fail;
4669 }
4670 pReqMsg->reportThresholdNumScans = nla_get_u8(
4671 tb[PARAM_RPT_THRHLD_NUM_SCANS]);
4672 hddLog(LOG1, FL("Report Threshold num scans %d"),
4673 pReqMsg->reportThresholdNumScans);
Dino Mycle6fb96c12014-06-10 11:52:40 +05304674
4675 /* Parse and fetch number of buckets */
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05304676 if (!tb[PARAM_NUM_BUCKETS]) {
Dino Mycle6fb96c12014-06-10 11:52:40 +05304677 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr number of buckets failed"));
4678 goto fail;
4679 }
4680 pReqMsg->numBuckets = nla_get_u8(
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05304681 tb[PARAM_NUM_BUCKETS]);
Dino Mycle6fb96c12014-06-10 11:52:40 +05304682 if (pReqMsg->numBuckets > WLAN_EXTSCAN_MAX_BUCKETS) {
4683 hddLog(VOS_TRACE_LEVEL_WARN, FL("Exceeded MAX number of buckets "
4684 "Setting numBuckets to %u"), WLAN_EXTSCAN_MAX_BUCKETS);
4685 pReqMsg->numBuckets = WLAN_EXTSCAN_MAX_BUCKETS;
4686 }
4687 hddLog(VOS_TRACE_LEVEL_INFO, FL("Number of Buckets (%d)"),
4688 pReqMsg->numBuckets);
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05304689
Dino Mycle6fb96c12014-06-10 11:52:40 +05304690 if (!tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC]) {
4691 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr bucket spec failed"));
4692 goto fail;
4693 }
4694
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05304695 pReqMsg->homeAwayTime = pHddCtx->cfg_ini->nRestTimeConc;
Dino Mycle6fb96c12014-06-10 11:52:40 +05304696
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05304697 if (hdd_extscan_start_fill_bucket_channel_spec(pHddCtx, pReqMsg, tb))
4698 goto fail;
Dasari Srinivas8b2ce272014-09-16 16:57:30 +05304699
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05304700 context = &pHddCtx->ext_scan_context;
4701 spin_lock(&hdd_context_lock);
4702 INIT_COMPLETION(context->response_event);
4703 context->request_id = request_id = pReqMsg->requestId;
4704 spin_unlock(&hdd_context_lock);
Dasari Srinivas8b2ce272014-09-16 16:57:30 +05304705
Dino Mycle6fb96c12014-06-10 11:52:40 +05304706 status = sme_EXTScanStart(pHddCtx->hHal, pReqMsg);
4707 if (!HAL_STATUS_SUCCESS(status)) {
4708 hddLog(VOS_TRACE_LEVEL_ERROR,
4709 FL("sme_EXTScanStart failed(err=%d)"), status);
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05304710 goto fail;
4711 }
4712
4713 /* request was sent -- wait for the response */
4714 rc = wait_for_completion_timeout(&context->response_event,
4715 msecs_to_jiffies(WLAN_WAIT_TIME_EXTSCAN));
4716
4717 if (!rc) {
4718 hddLog(LOGE, FL("sme_ExtScanStart timed out"));
4719 retval = -ETIMEDOUT;
4720 } else {
4721 spin_lock(&hdd_context_lock);
4722 if (context->request_id == request_id)
4723 retval = context->response_status;
4724 else
4725 retval = -EINVAL;
4726 spin_unlock(&hdd_context_lock);
Dino Mycle6fb96c12014-06-10 11:52:40 +05304727 }
4728
Dino Myclee8843b32014-07-04 14:21:45 +05304729 vos_mem_free(pReqMsg);
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05304730 EXIT();
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05304731 return retval;
Dino Mycle6fb96c12014-06-10 11:52:40 +05304732
4733fail:
4734 vos_mem_free(pReqMsg);
4735 return -EINVAL;
4736}
4737
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05304738/*
4739 * done with short names for the global vendor params
4740 * used by wlan_hdd_cfg80211_extscan_start()
4741 */
4742#undef PARAM_MAX
4743#undef PARAM_REQUEST_ID
4744#undef PARAM_BASE_PERIOD
4745#undef PARAMS_MAX_AP_PER_SCAN
4746#undef PARAMS_RPT_THRHLD_PERCENT
4747#undef PARAMS_RPT_THRHLD_NUM_SCANS
4748#undef PARAMS_NUM_BUCKETS
4749
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05304750static int wlan_hdd_cfg80211_extscan_start(struct wiphy *wiphy,
4751 struct wireless_dev *wdev,
4752 const void *data, int dataLen)
4753{
4754 int ret = 0;
4755
4756 vos_ssr_protect(__func__);
4757 ret = __wlan_hdd_cfg80211_extscan_start(wiphy, wdev, data, dataLen);
4758 vos_ssr_unprotect(__func__);
4759
4760 return ret;
4761}
4762
4763static int __wlan_hdd_cfg80211_extscan_stop(struct wiphy *wiphy,
Dino Mycle6fb96c12014-06-10 11:52:40 +05304764 struct wireless_dev *wdev,
Jeff Johnson393c2702014-12-16 11:09:35 +05304765 const void *data, int dataLen)
Dino Mycle6fb96c12014-06-10 11:52:40 +05304766{
Dino Myclee8843b32014-07-04 14:21:45 +05304767 tSirEXTScanStopReqParams reqMsg;
Dino Mycle6fb96c12014-06-10 11:52:40 +05304768 struct net_device *dev = wdev->netdev;
4769 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
4770 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
4771 struct nlattr *tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX + 1];
4772 eHalStatus status;
Padma, Santhosh Kumar57cff7f2015-08-17 18:33:14 +05304773 int retval;
4774 unsigned long rc;
4775 struct hdd_ext_scan_context *context;
4776 tANI_U32 request_id;
Dino Mycle6fb96c12014-06-10 11:52:40 +05304777
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05304778 ENTER();
4779
Padma, Santhosh Kumar57cff7f2015-08-17 18:33:14 +05304780 if (VOS_FTM_MODE == hdd_get_conparam()) {
4781 hddLog(LOGE, FL("Command not allowed in FTM mode"));
4782 return -EINVAL;
4783 }
4784
Dino Mycle6fb96c12014-06-10 11:52:40 +05304785 status = wlan_hdd_validate_context(pHddCtx);
4786 if (0 != status)
4787 {
Dino Mycle6fb96c12014-06-10 11:52:40 +05304788 return -EINVAL;
4789 }
Dino Myclee8843b32014-07-04 14:21:45 +05304790 /* check the EXTScan Capability */
4791 if ( (TRUE != pHddCtx->cfg_ini->fEnableEXTScan) ||
Padma, Santhosh Kumar2ac54992015-10-12 18:20:58 +05304792 (TRUE != sme_IsFeatureSupportedByFW(EXTENDED_SCAN)) ||
4793 (TRUE != sme_IsFeatureSupportedByFW(EXT_SCAN_ENHANCED)))
Dino Myclee8843b32014-07-04 14:21:45 +05304794 {
4795 hddLog(VOS_TRACE_LEVEL_ERROR,
4796 FL("EXTScan not enabled/supported by Firmware"));
4797 return -EINVAL;
4798 }
4799
Dino Mycle6fb96c12014-06-10 11:52:40 +05304800 if (nla_parse(tb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX,
4801 data, dataLen,
4802 wlan_hdd_extscan_config_policy)) {
4803 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Invalid ATTR"));
4804 return -EINVAL;
4805 }
4806
4807 /* Parse and fetch request Id */
4808 if (!tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_REQUEST_ID]) {
4809 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr request id failed"));
4810 return -EINVAL;
4811 }
4812
Dino Myclee8843b32014-07-04 14:21:45 +05304813 reqMsg.requestId = nla_get_u32(
Dino Mycle6fb96c12014-06-10 11:52:40 +05304814 tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_REQUEST_ID]);
Dino Myclee8843b32014-07-04 14:21:45 +05304815 hddLog(VOS_TRACE_LEVEL_INFO, FL("Req Id (%d)"), reqMsg.requestId);
Dino Mycle6fb96c12014-06-10 11:52:40 +05304816
Dino Myclee8843b32014-07-04 14:21:45 +05304817 reqMsg.sessionId = pAdapter->sessionId;
4818 hddLog(VOS_TRACE_LEVEL_INFO, FL("Session Id (%d)"), reqMsg.sessionId);
Dino Mycle6fb96c12014-06-10 11:52:40 +05304819
Padma, Santhosh Kumar57cff7f2015-08-17 18:33:14 +05304820 context = &pHddCtx->ext_scan_context;
4821 spin_lock(&hdd_context_lock);
4822 INIT_COMPLETION(context->response_event);
4823 context->request_id = request_id = reqMsg.sessionId;
4824 spin_unlock(&hdd_context_lock);
4825
Dino Myclee8843b32014-07-04 14:21:45 +05304826 status = sme_EXTScanStop(pHddCtx->hHal, &reqMsg);
Dino Mycle6fb96c12014-06-10 11:52:40 +05304827 if (!HAL_STATUS_SUCCESS(status)) {
4828 hddLog(VOS_TRACE_LEVEL_ERROR,
4829 FL("sme_EXTScanStop failed(err=%d)"), status);
Dino Mycle6fb96c12014-06-10 11:52:40 +05304830 return -EINVAL;
4831 }
4832
Padma, Santhosh Kumar57cff7f2015-08-17 18:33:14 +05304833 /* request was sent -- wait for the response */
4834 rc = wait_for_completion_timeout(&context->response_event,
4835 msecs_to_jiffies(WLAN_WAIT_TIME_EXTSCAN));
4836
4837 if (!rc) {
4838 hddLog(LOGE, FL("sme_ExtScanStop timed out"));
4839 retval = -ETIMEDOUT;
4840 } else {
4841 spin_lock(&hdd_context_lock);
4842 if (context->request_id == request_id)
4843 retval = context->response_status;
4844 else
4845 retval = -EINVAL;
4846 spin_unlock(&hdd_context_lock);
4847 }
4848
4849 return retval;
4850
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05304851 EXIT();
Dino Mycle6fb96c12014-06-10 11:52:40 +05304852 return 0;
4853}
4854
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05304855static int wlan_hdd_cfg80211_extscan_stop(struct wiphy *wiphy,
4856 struct wireless_dev *wdev,
4857 const void *data, int dataLen)
4858{
4859 int ret = 0;
4860
4861 vos_ssr_protect(__func__);
4862 ret = __wlan_hdd_cfg80211_extscan_stop(wiphy, wdev, data, dataLen);
4863 vos_ssr_unprotect(__func__);
4864
4865 return ret;
4866}
4867
4868static int __wlan_hdd_cfg80211_extscan_reset_bssid_hotlist(struct wiphy *wiphy,
Dino Mycle6fb96c12014-06-10 11:52:40 +05304869 struct wireless_dev *wdev,
Jeff Johnson393c2702014-12-16 11:09:35 +05304870 const void *data, int dataLen)
Dino Mycle6fb96c12014-06-10 11:52:40 +05304871{
Dino Myclee8843b32014-07-04 14:21:45 +05304872 tSirEXTScanResetBssidHotlistReqParams reqMsg;
Dino Mycle6fb96c12014-06-10 11:52:40 +05304873 struct net_device *dev = wdev->netdev;
4874 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
4875 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
4876 struct nlattr *tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX + 1];
4877 eHalStatus status;
Padma, Santhosh Kumar04a3bab2015-08-20 13:09:35 +05304878 struct hdd_ext_scan_context *context;
4879 tANI_U32 request_id;
4880 unsigned long rc;
4881 int retval;
Dino Mycle6fb96c12014-06-10 11:52:40 +05304882
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05304883 ENTER();
4884
Padma, Santhosh Kumar04a3bab2015-08-20 13:09:35 +05304885 if (VOS_FTM_MODE == hdd_get_conparam()) {
4886 hddLog(LOGE, FL("Command not allowed in FTM mode"));
4887 return -EINVAL;
4888 }
4889
Dino Mycle6fb96c12014-06-10 11:52:40 +05304890 status = wlan_hdd_validate_context(pHddCtx);
4891 if (0 != status)
4892 {
Padma, Santhosh Kumar04a3bab2015-08-20 13:09:35 +05304893 hddLog(LOGE, FL("HDD context is not valid"));
Dino Mycle6fb96c12014-06-10 11:52:40 +05304894 return -EINVAL;
4895 }
Dino Myclee8843b32014-07-04 14:21:45 +05304896 /* check the EXTScan Capability */
4897 if ( (TRUE != pHddCtx->cfg_ini->fEnableEXTScan) ||
Padma, Santhosh Kumar2ac54992015-10-12 18:20:58 +05304898 (TRUE != sme_IsFeatureSupportedByFW(EXTENDED_SCAN)) ||
4899 (TRUE != sme_IsFeatureSupportedByFW(EXT_SCAN_ENHANCED)))
Dino Myclee8843b32014-07-04 14:21:45 +05304900 {
4901 hddLog(VOS_TRACE_LEVEL_ERROR,
4902 FL("EXTScan not enabled/supported by Firmware"));
4903 return -EINVAL;
4904 }
4905
Dino Mycle6fb96c12014-06-10 11:52:40 +05304906 if (nla_parse(tb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX,
4907 data, dataLen,
4908 wlan_hdd_extscan_config_policy)) {
4909 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Invalid ATTR"));
4910 return -EINVAL;
4911 }
4912
4913 /* Parse and fetch request Id */
4914 if (!tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_REQUEST_ID]) {
4915 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr request id failed"));
4916 return -EINVAL;
4917 }
4918
Dino Myclee8843b32014-07-04 14:21:45 +05304919 reqMsg.requestId = nla_get_u32(
Dino Mycle6fb96c12014-06-10 11:52:40 +05304920 tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_REQUEST_ID]);
Dino Myclee8843b32014-07-04 14:21:45 +05304921 hddLog(VOS_TRACE_LEVEL_INFO, FL("Req Id (%d)"), reqMsg.requestId);
Dino Mycle6fb96c12014-06-10 11:52:40 +05304922
Dino Myclee8843b32014-07-04 14:21:45 +05304923 reqMsg.sessionId = pAdapter->sessionId;
4924 hddLog(VOS_TRACE_LEVEL_INFO, FL("Session Id (%d)"), reqMsg.sessionId);
Dino Mycle6fb96c12014-06-10 11:52:40 +05304925
Padma, Santhosh Kumar04a3bab2015-08-20 13:09:35 +05304926 context = &pHddCtx->ext_scan_context;
4927 spin_lock(&hdd_context_lock);
4928 INIT_COMPLETION(context->response_event);
4929 context->request_id = request_id = reqMsg.requestId;
4930 spin_unlock(&hdd_context_lock);
4931
Dino Myclee8843b32014-07-04 14:21:45 +05304932 status = sme_ResetBssHotlist(pHddCtx->hHal, &reqMsg);
Dino Mycle6fb96c12014-06-10 11:52:40 +05304933 if (!HAL_STATUS_SUCCESS(status)) {
4934 hddLog(VOS_TRACE_LEVEL_ERROR,
4935 FL("sme_ResetBssHotlist failed(err=%d)"), status);
Dino Mycle6fb96c12014-06-10 11:52:40 +05304936 return -EINVAL;
4937 }
Padma, Santhosh Kumar04a3bab2015-08-20 13:09:35 +05304938
4939 /* request was sent -- wait for the response */
4940 rc = wait_for_completion_timeout(&context->response_event,
4941 msecs_to_jiffies(WLAN_WAIT_TIME_EXTSCAN));
4942 if (!rc) {
4943 hddLog(LOGE, FL("sme_ResetBssHotlist timed out"));
4944 retval = -ETIMEDOUT;
4945 } else {
4946 spin_lock(&hdd_context_lock);
4947 if (context->request_id == request_id)
4948 retval = context->response_status;
4949 else
4950 retval = -EINVAL;
4951 spin_unlock(&hdd_context_lock);
4952 }
4953
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05304954 EXIT();
Padma, Santhosh Kumar04a3bab2015-08-20 13:09:35 +05304955 return retval;
Dino Mycle6fb96c12014-06-10 11:52:40 +05304956}
4957
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05304958static int wlan_hdd_cfg80211_extscan_reset_bssid_hotlist(struct wiphy *wiphy,
4959 struct wireless_dev *wdev,
4960 const void *data, int dataLen)
4961{
4962 int ret = 0;
4963
4964 vos_ssr_protect(__func__);
4965 ret = __wlan_hdd_cfg80211_extscan_reset_bssid_hotlist(wiphy, wdev, data, dataLen);
4966 vos_ssr_unprotect(__func__);
4967
4968 return ret;
4969}
Dino Mycle6fb96c12014-06-10 11:52:40 +05304970#endif /* WLAN_FEATURE_EXTSCAN */
4971
Atul Mittal115287b2014-07-08 13:26:33 +05304972/*EXT TDLS*/
4973static const struct nla_policy
4974wlan_hdd_tdls_config_enable_policy[QCA_WLAN_VENDOR_ATTR_TDLS_ENABLE_MAX +1] =
4975{
4976 [QCA_WLAN_VENDOR_ATTR_TDLS_ENABLE_MAC_ADDR] = {.type = NLA_UNSPEC },
4977 [QCA_WLAN_VENDOR_ATTR_TDLS_ENABLE_CHANNEL] = {.type = NLA_S32 },
4978 [QCA_WLAN_VENDOR_ATTR_TDLS_ENABLE_GLOBAL_OPERATING_CLASS] =
4979 {.type = NLA_S32 },
4980 [QCA_WLAN_VENDOR_ATTR_TDLS_ENABLE_MAX_LATENCY_MS] = {.type = NLA_S32 },
4981 [QCA_WLAN_VENDOR_ATTR_TDLS_ENABLE_MIN_BANDWIDTH_KBPS] = {.type = NLA_S32 },
4982
4983};
4984
4985static const struct nla_policy
4986wlan_hdd_tdls_config_disable_policy[QCA_WLAN_VENDOR_ATTR_TDLS_DISABLE_MAX +1] =
4987{
4988 [QCA_WLAN_VENDOR_ATTR_TDLS_DISABLE_MAC_ADDR] = {.type = NLA_UNSPEC },
4989
4990};
4991
4992static const struct nla_policy
4993wlan_hdd_tdls_config_state_change_policy[
4994 QCA_WLAN_VENDOR_ATTR_TDLS_STATE_MAX +1] =
4995{
4996 [QCA_WLAN_VENDOR_ATTR_TDLS_STATE_MAC_ADDR] = {.type = NLA_UNSPEC },
4997 [QCA_WLAN_VENDOR_ATTR_TDLS_NEW_STATE] = {.type = NLA_S32 },
4998 [QCA_WLAN_VENDOR_ATTR_TDLS_STATE_REASON] = {.type = NLA_S32 },
Atul Mittal0a9f68d2014-10-16 15:26:38 +05304999 [QCA_WLAN_VENDOR_ATTR_TDLS_STATE_CHANNEL] = {.type = NLA_S32 },
5000 [QCA_WLAN_VENDOR_ATTR_TDLS_STATE_GLOBAL_OPERATING_CLASS] =
5001 {.type = NLA_S32 },
Atul Mittal115287b2014-07-08 13:26:33 +05305002
5003};
5004
5005static const struct nla_policy
5006wlan_hdd_tdls_config_get_status_policy[
5007 QCA_WLAN_VENDOR_ATTR_TDLS_GET_STATUS_MAX +1] =
5008{
5009 [QCA_WLAN_VENDOR_ATTR_TDLS_GET_STATUS_MAC_ADDR] = {.type = NLA_UNSPEC },
5010 [QCA_WLAN_VENDOR_ATTR_TDLS_GET_STATUS_STATE] = {.type = NLA_S32 },
5011 [QCA_WLAN_VENDOR_ATTR_TDLS_GET_STATUS_REASON] = {.type = NLA_S32 },
Atul Mittal0a9f68d2014-10-16 15:26:38 +05305012 [QCA_WLAN_VENDOR_ATTR_TDLS_GET_STATUS_CHANNEL] = {.type = NLA_S32 },
5013 [QCA_WLAN_VENDOR_ATTR_TDLS_GET_STATUS_GLOBAL_OPERATING_CLASS]
5014 = {.type = NLA_S32 },
Atul Mittal115287b2014-07-08 13:26:33 +05305015
5016};
Siddharth Bhala3a5cb42014-09-29 21:13:13 +05305017
5018static const struct nla_policy
5019wlan_hdd_mac_config[QCA_WLAN_VENDOR_ATTR_SET_SCANNING_MAC_OUI_MAX+1] =
5020{
5021 [QCA_WLAN_VENDOR_ATTR_SET_SCANNING_MAC_OUI] = {.type = NLA_UNSPEC },
5022};
5023
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05305024static int __wlan_hdd_cfg80211_set_spoofed_mac_oui(struct wiphy *wiphy,
Siddharth Bhala3a5cb42014-09-29 21:13:13 +05305025 struct wireless_dev *wdev,
Jeff Johnson393c2702014-12-16 11:09:35 +05305026 const void *data,
Siddharth Bhala3a5cb42014-09-29 21:13:13 +05305027 int data_len)
5028{
5029
5030 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
5031 struct nlattr *tb[QCA_WLAN_VENDOR_ATTR_SET_SCANNING_MAC_OUI_MAX + 1];
5032
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05305033 ENTER();
5034
Siddharth Bhala3a5cb42014-09-29 21:13:13 +05305035 if (0 != wlan_hdd_validate_context(pHddCtx)){
Siddharth Bhala3a5cb42014-09-29 21:13:13 +05305036 return -EINVAL;
5037 }
Hanumantha Reddy Pothulaca1d1cc2015-10-26 15:37:35 +05305038 if (0 == pHddCtx->cfg_ini->enableMacSpoofing) {
Ratheesh S P36dbc932015-08-07 14:28:57 +05305039 hddLog(VOS_TRACE_LEVEL_INFO, FL("MAC_SPOOFED_SCAN disabled in ini"));
Siddharth Bhala3a5cb42014-09-29 21:13:13 +05305040 return -ENOTSUPP;
Siddharth Bhal76972212014-10-15 16:22:51 +05305041 }
Siddharth Bhala3a5cb42014-09-29 21:13:13 +05305042 if (TRUE != sme_IsFeatureSupportedByFW(MAC_SPOOFED_SCAN)){
Ratheesh S P36dbc932015-08-07 14:28:57 +05305043 hddLog(VOS_TRACE_LEVEL_INFO, FL("MAC_SPOOFED_SCAN not supported by FW"));
Siddharth Bhala3a5cb42014-09-29 21:13:13 +05305044 return -ENOTSUPP;
5045 }
5046
5047 if (nla_parse(tb, QCA_WLAN_VENDOR_ATTR_SET_SCANNING_MAC_OUI_MAX,
5048 data, data_len, wlan_hdd_mac_config)) {
5049 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Invalid ATTR"));
5050 return -EINVAL;
5051 }
5052
5053 /* Parse and fetch mac address */
5054 if (!tb[QCA_WLAN_VENDOR_ATTR_SET_SCANNING_MAC_OUI]) {
5055 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr mac addr failed"));
5056 return -EINVAL;
5057 }
5058
5059 memcpy(pHddCtx->spoofMacAddr.randomMacAddr.bytes, nla_data(
5060 tb[QCA_WLAN_VENDOR_ATTR_SET_SCANNING_MAC_OUI]),
5061 VOS_MAC_ADDR_LAST_3_BYTES);
5062
Siddharth Bhal76972212014-10-15 16:22:51 +05305063 pHddCtx->spoofMacAddr.isEnabled = TRUE;
5064
5065 vos_trace_hex_dump( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO, nla_data(
Siddharth Bhala3a5cb42014-09-29 21:13:13 +05305066 tb[QCA_WLAN_VENDOR_ATTR_SET_SCANNING_MAC_OUI]),
5067 VOS_MAC_ADDR_FIRST_3_BYTES);
Siddharth Bhal76972212014-10-15 16:22:51 +05305068 if ((pHddCtx->spoofMacAddr.randomMacAddr.bytes[0] == 0) &&
5069 (pHddCtx->spoofMacAddr.randomMacAddr.bytes[1] == 0) &&
5070 (pHddCtx->spoofMacAddr.randomMacAddr.bytes[2] == 0))
5071 {
5072 hddLog(LOG1, FL("ZERO MAC OUI Recieved. Disabling Spoofing"));
5073 vos_mem_zero(pHddCtx->spoofMacAddr.randomMacAddr.bytes,
5074 VOS_MAC_ADDRESS_LEN);
5075 pHddCtx->spoofMacAddr.isEnabled = FALSE;
Siddharth Bhala3a5cb42014-09-29 21:13:13 +05305076 }
Siddharth Bhala3a5cb42014-09-29 21:13:13 +05305077
Siddharth Bhal76972212014-10-15 16:22:51 +05305078 if (VOS_STATUS_SUCCESS != hdd_processSpoofMacAddrRequest(pHddCtx))
5079 {
Siddharth Bhala3a5cb42014-09-29 21:13:13 +05305080 hddLog(LOGE, FL("Failed to send Spoof Mac Addr to FW"));
5081 }
5082
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05305083 EXIT();
Siddharth Bhala3a5cb42014-09-29 21:13:13 +05305084 return 0;
5085}
5086
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05305087static int wlan_hdd_cfg80211_set_spoofed_mac_oui(struct wiphy *wiphy,
5088 struct wireless_dev *wdev,
5089 const void *data,
5090 int data_len)
5091{
5092 int ret = 0;
5093
5094 vos_ssr_protect(__func__);
5095 ret = __wlan_hdd_cfg80211_set_spoofed_mac_oui(wiphy, wdev, data, data_len);
5096 vos_ssr_unprotect(__func__);
5097
5098 return ret;
5099}
5100
5101static int __wlan_hdd_cfg80211_exttdls_get_status(struct wiphy *wiphy,
Atul Mittal115287b2014-07-08 13:26:33 +05305102 struct wireless_dev *wdev,
Jeff Johnson393c2702014-12-16 11:09:35 +05305103 const void *data,
Atul Mittal115287b2014-07-08 13:26:33 +05305104 int data_len)
5105{
5106 u8 peer[6] = {0};
5107 struct net_device *dev = wdev->netdev;
5108 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
5109 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
5110 struct nlattr *tb[QCA_WLAN_VENDOR_ATTR_TDLS_GET_STATUS_MAX + 1];
5111 eHalStatus ret;
5112 tANI_S32 state;
5113 tANI_S32 reason;
Atul Mittal0a9f68d2014-10-16 15:26:38 +05305114 tANI_S32 global_operating_class = 0;
5115 tANI_S32 channel = 0;
Atul Mittal115287b2014-07-08 13:26:33 +05305116 struct sk_buff *skb = NULL;
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05305117 int retVal;
5118
5119 ENTER();
Atul Mittal115287b2014-07-08 13:26:33 +05305120
Chandrasekaran, Manishekar41b8e1f2015-03-10 13:30:28 +05305121 if (!pAdapter) {
5122 hddLog(VOS_TRACE_LEVEL_ERROR, FL("HDD adpater is NULL"));
5123 return -EINVAL;
5124 }
5125
Atul Mittal115287b2014-07-08 13:26:33 +05305126 ret = wlan_hdd_validate_context(pHddCtx);
5127 if (0 != ret) {
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +05305128 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Invalid HDD context"));
Atul Mittal115287b2014-07-08 13:26:33 +05305129 return -EINVAL;
5130 }
5131 if (pHddCtx->cfg_ini->fTDLSExternalControl == FALSE) {
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +05305132 hddLog(VOS_TRACE_LEVEL_ERROR, FL("TDLS external control is disabled"));
Atul Mittal115287b2014-07-08 13:26:33 +05305133 return -ENOTSUPP;
5134 }
5135 if (nla_parse(tb, QCA_WLAN_VENDOR_ATTR_TDLS_GET_STATUS_MAX,
5136 data, data_len,
5137 wlan_hdd_tdls_config_get_status_policy)) {
5138 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Invalid ATTR"));
5139 return -EINVAL;
5140 }
5141
5142 /* Parse and fetch mac address */
5143 if (!tb[QCA_WLAN_VENDOR_ATTR_TDLS_GET_STATUS_MAC_ADDR]) {
5144 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr mac addr failed"));
5145 return -EINVAL;
5146 }
5147
5148 memcpy(peer, nla_data(
5149 tb[QCA_WLAN_VENDOR_ATTR_TDLS_GET_STATUS_MAC_ADDR]),
5150 sizeof(peer));
5151 hddLog(VOS_TRACE_LEVEL_INFO, FL(MAC_ADDRESS_STR),MAC_ADDR_ARRAY(peer));
5152
Konamki, Sreelakshmiabb59ed2015-06-12 12:13:23 +05305153 wlan_hdd_tdls_get_status(pAdapter, peer, &state, &reason);
Atul Mittal115287b2014-07-08 13:26:33 +05305154
Atul Mittal115287b2014-07-08 13:26:33 +05305155 skb = cfg80211_vendor_cmd_alloc_reply_skb(wiphy,
Atul Mittal0a9f68d2014-10-16 15:26:38 +05305156 4 * sizeof(s32) +
Atul Mittal115287b2014-07-08 13:26:33 +05305157 NLMSG_HDRLEN);
5158
5159 if (!skb) {
5160 hddLog(VOS_TRACE_LEVEL_ERROR,
5161 FL("cfg80211_vendor_cmd_alloc_reply_skb failed"));
5162 return -EINVAL;
5163 }
Atul Mittal0a9f68d2014-10-16 15:26:38 +05305164 hddLog(VOS_TRACE_LEVEL_INFO, FL("Reason (%d) Status (%d) class (%d) channel (%d) peer" MAC_ADDRESS_STR),
Atul Mittal115287b2014-07-08 13:26:33 +05305165 reason,
5166 state,
Atul Mittal0a9f68d2014-10-16 15:26:38 +05305167 global_operating_class,
5168 channel,
Atul Mittal115287b2014-07-08 13:26:33 +05305169 MAC_ADDR_ARRAY(peer));
Atul Mittal0a9f68d2014-10-16 15:26:38 +05305170 if (nla_put_s32(skb,
5171 QCA_WLAN_VENDOR_ATTR_TDLS_GET_STATUS_STATE,
5172 state) ||
5173 nla_put_s32(skb,
5174 QCA_WLAN_VENDOR_ATTR_TDLS_GET_STATUS_REASON,
5175 reason) ||
5176 nla_put_s32(skb,
5177 QCA_WLAN_VENDOR_ATTR_TDLS_GET_STATUS_GLOBAL_OPERATING_CLASS,
5178 global_operating_class) ||
5179 nla_put_s32(skb,
5180 QCA_WLAN_VENDOR_ATTR_TDLS_GET_STATUS_CHANNEL,
5181 channel)) {
Atul Mittal115287b2014-07-08 13:26:33 +05305182
5183 hddLog(VOS_TRACE_LEVEL_ERROR, FL("nla put fail"));
5184 goto nla_put_failure;
5185 }
5186
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05305187 retVal = cfg80211_vendor_cmd_reply(skb);
5188 EXIT();
5189 return retVal;
Atul Mittal115287b2014-07-08 13:26:33 +05305190
5191nla_put_failure:
5192 kfree_skb(skb);
5193 return -EINVAL;
5194}
5195
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05305196static int wlan_hdd_cfg80211_exttdls_get_status(struct wiphy *wiphy,
5197 struct wireless_dev *wdev,
5198 const void *data,
5199 int data_len)
5200{
5201 int ret = 0;
5202
5203 vos_ssr_protect(__func__);
5204 ret = __wlan_hdd_cfg80211_exttdls_get_status(wiphy, wdev, data, data_len);
5205 vos_ssr_unprotect(__func__);
5206
5207 return ret;
5208}
5209
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +05305210static int wlan_hdd_cfg80211_exttdls_callback(
5211#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,18,0))
5212 const tANI_U8* mac,
5213#else
5214 tANI_U8* mac,
5215#endif
Atul Mittal115287b2014-07-08 13:26:33 +05305216 tANI_S32 state,
5217 tANI_S32 reason,
5218 void *ctx)
5219{
5220 hdd_adapter_t* pAdapter = (hdd_adapter_t*)ctx;
Atul Mittal115287b2014-07-08 13:26:33 +05305221 struct sk_buff *skb = NULL;
Atul Mittal0a9f68d2014-10-16 15:26:38 +05305222 tANI_S32 global_operating_class = 0;
5223 tANI_S32 channel = 0;
Chandrasekaran, Manishekar41b8e1f2015-03-10 13:30:28 +05305224 hdd_context_t *pHddCtx;
Atul Mittal115287b2014-07-08 13:26:33 +05305225
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05305226 ENTER();
5227
Chandrasekaran, Manishekar41b8e1f2015-03-10 13:30:28 +05305228 if (!pAdapter) {
5229 hddLog(VOS_TRACE_LEVEL_ERROR, FL("HDD adpater is NULL"));
5230 return -EINVAL;
5231 }
5232
5233 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Atul Mittal115287b2014-07-08 13:26:33 +05305234 if (wlan_hdd_validate_context(pHddCtx)) {
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +05305235 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Invalid HDD context"));
Atul Mittal115287b2014-07-08 13:26:33 +05305236 return -EINVAL;
5237 }
5238
5239 if (pHddCtx->cfg_ini->fTDLSExternalControl == FALSE) {
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +05305240 hddLog(VOS_TRACE_LEVEL_ERROR, FL("TDLS external control is disabled"));
Atul Mittal115287b2014-07-08 13:26:33 +05305241 return -ENOTSUPP;
5242 }
Anand N Sunkad26ca6cc2015-07-29 09:54:52 +05305243 skb = cfg80211_vendor_event_alloc(pHddCtx->wiphy,
5244#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 18, 0))
5245 NULL,
5246#endif
Atul Mittal115287b2014-07-08 13:26:33 +05305247 EXTTDLS_EVENT_BUF_SIZE + NLMSG_HDRLEN,
5248 QCA_NL80211_VENDOR_SUBCMD_TDLS_STATE_CHANGE_INDEX,
5249 GFP_KERNEL);
5250
5251 if (!skb) {
5252 hddLog(VOS_TRACE_LEVEL_ERROR,
5253 FL("cfg80211_vendor_event_alloc failed"));
5254 return -EINVAL;
5255 }
5256 hddLog(VOS_TRACE_LEVEL_INFO, FL("Entering "));
Atul Mittal0a9f68d2014-10-16 15:26:38 +05305257 hddLog(VOS_TRACE_LEVEL_INFO, "Reason: (%d) Status: (%d) Class: (%d) Channel: (%d)",
5258 reason,
5259 state,
5260 global_operating_class,
5261 channel);
Atul Mittal115287b2014-07-08 13:26:33 +05305262 hddLog(VOS_TRACE_LEVEL_WARN, "tdls peer " MAC_ADDRESS_STR,
5263 MAC_ADDR_ARRAY(mac));
5264
Atul Mittal0a9f68d2014-10-16 15:26:38 +05305265 if (nla_put(skb,
5266 QCA_WLAN_VENDOR_ATTR_TDLS_STATE_MAC_ADDR,
5267 VOS_MAC_ADDR_SIZE, mac) ||
5268 nla_put_s32(skb,
5269 QCA_WLAN_VENDOR_ATTR_TDLS_NEW_STATE,
5270 state) ||
5271 nla_put_s32(skb,
5272 QCA_WLAN_VENDOR_ATTR_TDLS_STATE_REASON,
5273 reason) ||
5274 nla_put_s32(skb,
5275 QCA_WLAN_VENDOR_ATTR_TDLS_STATE_CHANNEL,
5276 channel) ||
5277 nla_put_s32(skb,
5278 QCA_WLAN_VENDOR_ATTR_TDLS_STATE_GLOBAL_OPERATING_CLASS,
5279 global_operating_class)
5280 ) {
Atul Mittal115287b2014-07-08 13:26:33 +05305281 hddLog(VOS_TRACE_LEVEL_ERROR, FL("nla put fail"));
5282 goto nla_put_failure;
5283 }
5284
5285 cfg80211_vendor_event(skb, GFP_KERNEL);
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05305286 EXIT();
Atul Mittal115287b2014-07-08 13:26:33 +05305287 return (0);
5288
5289nla_put_failure:
5290 kfree_skb(skb);
5291 return -EINVAL;
5292}
5293
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05305294static int __wlan_hdd_cfg80211_exttdls_enable(struct wiphy *wiphy,
Atul Mittal115287b2014-07-08 13:26:33 +05305295 struct wireless_dev *wdev,
Jeff Johnson393c2702014-12-16 11:09:35 +05305296 const void *data,
Atul Mittal115287b2014-07-08 13:26:33 +05305297 int data_len)
5298{
5299 u8 peer[6] = {0};
5300 struct net_device *dev = wdev->netdev;
Atul Mittal115287b2014-07-08 13:26:33 +05305301 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
5302 struct nlattr *tb[QCA_WLAN_VENDOR_ATTR_TDLS_ENABLE_MAX + 1];
5303 eHalStatus status;
5304 tdls_req_params_t pReqMsg = {0};
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05305305 int ret;
Chandrasekaran, Manishekar41b8e1f2015-03-10 13:30:28 +05305306 hdd_adapter_t *pAdapter;
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05305307
5308 ENTER();
Atul Mittal115287b2014-07-08 13:26:33 +05305309
Chandrasekaran, Manishekar41b8e1f2015-03-10 13:30:28 +05305310 if (!dev) {
5311 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Dev pointer is NULL"));
5312 return -EINVAL;
5313 }
5314
5315 pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
5316 if (!pAdapter) {
5317 hddLog(VOS_TRACE_LEVEL_ERROR, FL("HDD adpater is NULL"));
5318 return -EINVAL;
5319 }
5320
Atul Mittal115287b2014-07-08 13:26:33 +05305321 status = wlan_hdd_validate_context(pHddCtx);
5322 if (0 != status) {
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +05305323 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Invalid HDD context"));
Atul Mittal115287b2014-07-08 13:26:33 +05305324 return -EINVAL;
5325 }
5326 if (pHddCtx->cfg_ini->fTDLSExternalControl == FALSE) {
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +05305327 hddLog(VOS_TRACE_LEVEL_ERROR, FL("TDLS external control is disabled"));
Atul Mittal115287b2014-07-08 13:26:33 +05305328 return -ENOTSUPP;
5329 }
5330 if (nla_parse(tb, QCA_WLAN_VENDOR_ATTR_TDLS_ENABLE_MAX,
5331 data, data_len,
5332 wlan_hdd_tdls_config_enable_policy)) {
5333 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Invalid ATTR"));
5334 return -EINVAL;
5335 }
5336
5337 /* Parse and fetch mac address */
5338 if (!tb[QCA_WLAN_VENDOR_ATTR_TDLS_ENABLE_MAC_ADDR]) {
5339 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr mac addr failed"));
5340 return -EINVAL;
5341 }
5342
5343 memcpy(peer, nla_data(
5344 tb[QCA_WLAN_VENDOR_ATTR_TDLS_ENABLE_MAC_ADDR]),
5345 sizeof(peer));
5346 hddLog(VOS_TRACE_LEVEL_INFO, FL(MAC_ADDRESS_STR),MAC_ADDR_ARRAY(peer));
5347
5348 /* Parse and fetch channel */
5349 if (!tb[QCA_WLAN_VENDOR_ATTR_TDLS_ENABLE_CHANNEL]) {
5350 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr channel failed"));
5351 return -EINVAL;
5352 }
5353 pReqMsg.channel = nla_get_s32(
5354 tb[QCA_WLAN_VENDOR_ATTR_TDLS_ENABLE_CHANNEL]);
5355 hddLog(VOS_TRACE_LEVEL_INFO, FL("Channel Num (%d)"), pReqMsg.channel);
5356
5357 /* Parse and fetch global operating class */
5358 if (!tb[QCA_WLAN_VENDOR_ATTR_TDLS_ENABLE_GLOBAL_OPERATING_CLASS]) {
5359 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr operating class failed"));
5360 return -EINVAL;
5361 }
5362 pReqMsg.global_operating_class = nla_get_s32(
5363 tb[QCA_WLAN_VENDOR_ATTR_TDLS_ENABLE_GLOBAL_OPERATING_CLASS]);
5364 hddLog(VOS_TRACE_LEVEL_INFO, FL("Operating class (%d)"),
5365 pReqMsg.global_operating_class);
5366
5367 /* Parse and fetch latency ms */
5368 if (!tb[QCA_WLAN_VENDOR_ATTR_TDLS_ENABLE_MAX_LATENCY_MS]) {
5369 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr latency failed"));
5370 return -EINVAL;
5371 }
5372 pReqMsg.max_latency_ms = nla_get_s32(
5373 tb[QCA_WLAN_VENDOR_ATTR_TDLS_ENABLE_MAX_LATENCY_MS]);
5374 hddLog(VOS_TRACE_LEVEL_INFO, FL("Latency (%d)"),
5375 pReqMsg.max_latency_ms);
5376
5377 /* Parse and fetch required bandwidth kbps */
5378 if (!tb[QCA_WLAN_VENDOR_ATTR_TDLS_ENABLE_MIN_BANDWIDTH_KBPS]) {
5379 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr bandwidth failed"));
5380 return -EINVAL;
5381 }
5382
5383 pReqMsg.min_bandwidth_kbps = nla_get_s32(
5384 tb[QCA_WLAN_VENDOR_ATTR_TDLS_ENABLE_MIN_BANDWIDTH_KBPS]);
5385 hddLog(VOS_TRACE_LEVEL_INFO, FL("Bandwidth (%d)"),
5386 pReqMsg.min_bandwidth_kbps);
5387
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05305388 ret = wlan_hdd_tdls_extctrl_config_peer(pAdapter,
Atul Mittal115287b2014-07-08 13:26:33 +05305389 peer,
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +05305390 &pReqMsg,
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05305391 wlan_hdd_cfg80211_exttdls_callback);
5392
5393 EXIT();
5394 return ret;
Atul Mittal115287b2014-07-08 13:26:33 +05305395}
5396
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05305397static int wlan_hdd_cfg80211_exttdls_enable(struct wiphy *wiphy,
5398 struct wireless_dev *wdev,
5399 const void *data,
5400 int data_len)
5401{
5402 int ret = 0;
5403
5404 vos_ssr_protect(__func__);
5405 ret = __wlan_hdd_cfg80211_exttdls_enable(wiphy, wdev, data, data_len);
5406 vos_ssr_unprotect(__func__);
5407
5408 return ret;
5409}
5410
5411static int __wlan_hdd_cfg80211_exttdls_disable(struct wiphy *wiphy,
Atul Mittal115287b2014-07-08 13:26:33 +05305412 struct wireless_dev *wdev,
Jeff Johnson393c2702014-12-16 11:09:35 +05305413 const void *data,
Atul Mittal115287b2014-07-08 13:26:33 +05305414 int data_len)
5415{
5416 u8 peer[6] = {0};
5417 struct net_device *dev = wdev->netdev;
Atul Mittal115287b2014-07-08 13:26:33 +05305418 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
5419 struct nlattr *tb[QCA_WLAN_VENDOR_ATTR_TDLS_DISABLE_MAX + 1];
5420 eHalStatus status;
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05305421 int ret;
Chandrasekaran, Manishekar41b8e1f2015-03-10 13:30:28 +05305422 hdd_adapter_t *pAdapter;
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05305423
5424 ENTER();
Atul Mittal115287b2014-07-08 13:26:33 +05305425
Chandrasekaran, Manishekar41b8e1f2015-03-10 13:30:28 +05305426 if (!dev) {
5427 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Dev pointer is NULL"));
5428 return -EINVAL;
5429 }
5430
5431 pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
5432 if (!pAdapter) {
5433 hddLog(VOS_TRACE_LEVEL_ERROR, FL("HDD adapter is NULL"));
5434 return -EINVAL;
5435 }
5436
Atul Mittal115287b2014-07-08 13:26:33 +05305437 status = wlan_hdd_validate_context(pHddCtx);
5438 if (0 != status) {
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +05305439 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Invalid HDD context"));
Atul Mittal115287b2014-07-08 13:26:33 +05305440 return -EINVAL;
5441 }
5442 if (pHddCtx->cfg_ini->fTDLSExternalControl == FALSE) {
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +05305443 hddLog(VOS_TRACE_LEVEL_ERROR, FL("TDLS external control is disabled"));
Atul Mittal115287b2014-07-08 13:26:33 +05305444 return -ENOTSUPP;
5445 }
5446 if (nla_parse(tb, QCA_WLAN_VENDOR_ATTR_TDLS_DISABLE_MAX,
5447 data, data_len,
5448 wlan_hdd_tdls_config_disable_policy)) {
5449 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Invalid ATTR"));
5450 return -EINVAL;
5451 }
5452 /* Parse and fetch mac address */
5453 if (!tb[QCA_WLAN_VENDOR_ATTR_TDLS_DISABLE_MAC_ADDR]) {
5454 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr mac addr failed"));
5455 return -EINVAL;
5456 }
5457
5458 memcpy(peer, nla_data(
5459 tb[QCA_WLAN_VENDOR_ATTR_TDLS_DISABLE_MAC_ADDR]),
5460 sizeof(peer));
5461 hddLog(VOS_TRACE_LEVEL_INFO, FL(MAC_ADDRESS_STR),MAC_ADDR_ARRAY(peer));
5462
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05305463 ret = wlan_hdd_tdls_extctrl_deconfig_peer(pAdapter, peer);
5464
5465 EXIT();
5466 return ret;
Atul Mittal115287b2014-07-08 13:26:33 +05305467}
5468
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05305469static int wlan_hdd_cfg80211_exttdls_disable(struct wiphy *wiphy,
5470 struct wireless_dev *wdev,
5471 const void *data,
5472 int data_len)
5473{
5474 int ret = 0;
5475
5476 vos_ssr_protect(__func__);
5477 ret = __wlan_hdd_cfg80211_exttdls_disable(wiphy, wdev, data, data_len);
5478 vos_ssr_unprotect(__func__);
5479
5480 return ret;
5481}
5482
Dasari Srinivas7875a302014-09-26 17:50:57 +05305483static int
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05305484__wlan_hdd_cfg80211_get_supported_features(struct wiphy *wiphy,
Dasari Srinivas7875a302014-09-26 17:50:57 +05305485 struct wireless_dev *wdev,
Jeff Johnson393c2702014-12-16 11:09:35 +05305486 const void *data, int data_len)
Dasari Srinivas7875a302014-09-26 17:50:57 +05305487{
5488 struct net_device *dev = wdev->netdev;
5489 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
5490 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
5491 struct sk_buff *skb = NULL;
5492 tANI_U32 fset = 0;
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05305493 int ret = 0;
Dasari Srinivas7875a302014-09-26 17:50:57 +05305494
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05305495 ENTER();
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05305496
5497 ret = wlan_hdd_validate_context(pHddCtx);
5498 if (0 != ret)
5499 {
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05305500 return ret;
5501 }
Dasari Srinivas7875a302014-09-26 17:50:57 +05305502 if (wiphy->interface_modes & BIT(NL80211_IFTYPE_STATION)) {
5503 hddLog(LOG1, FL("Infra Station mode is supported by driver"));
5504 fset |= WIFI_FEATURE_INFRA;
5505 }
5506
5507 if (TRUE == hdd_is_5g_supported(pHddCtx)) {
5508 hddLog(LOG1, FL("INFRA_5G is supported by firmware"));
5509 fset |= WIFI_FEATURE_INFRA_5G;
5510 }
5511
5512#ifdef WLAN_FEATURE_P2P
5513 if ((wiphy->interface_modes & BIT(NL80211_IFTYPE_P2P_CLIENT)) &&
5514 (wiphy->interface_modes & BIT(NL80211_IFTYPE_P2P_GO))) {
5515 hddLog(LOG1, FL("WiFi-Direct is supported by driver"));
5516 fset |= WIFI_FEATURE_P2P;
5517 }
5518#endif
5519
5520 /* Soft-AP is supported currently by default */
5521 fset |= WIFI_FEATURE_SOFT_AP;
5522
Kanchanapally, Vidyullatha683aed02015-03-24 16:58:38 +05305523 /* HOTSPOT is a supplicant feature, enable it by default */
5524 fset |= WIFI_FEATURE_HOTSPOT;
5525
Dasari Srinivas7875a302014-09-26 17:50:57 +05305526#ifdef WLAN_FEATURE_EXTSCAN
5527 if ((TRUE == pHddCtx->cfg_ini->fEnableEXTScan) &&
Padma, Santhosh Kumar2ac54992015-10-12 18:20:58 +05305528 sme_IsFeatureSupportedByFW(EXTENDED_SCAN) &&
5529 sme_IsFeatureSupportedByFW(EXT_SCAN_ENHANCED)) {
5530 hddLog(LOG1, FL("Enhanced EXTScan is supported by firmware"));
Dasari Srinivas7875a302014-09-26 17:50:57 +05305531 fset |= WIFI_FEATURE_EXTSCAN;
5532 }
5533#endif
5534
Dasari Srinivas7875a302014-09-26 17:50:57 +05305535 if (sme_IsFeatureSupportedByFW(NAN)) {
5536 hddLog(LOG1, FL("NAN is supported by firmware"));
5537 fset |= WIFI_FEATURE_NAN;
5538 }
Dasari Srinivas7875a302014-09-26 17:50:57 +05305539
5540 /* D2D RTT is not supported currently by default */
5541 if (sme_IsFeatureSupportedByFW(RTT)) {
5542 hddLog(LOG1, FL("RTT is supported by firmware"));
5543 fset |= WIFI_FEATURE_D2AP_RTT;
5544 }
5545
5546#ifdef FEATURE_WLAN_BATCH_SCAN
5547 if (fset & WIFI_FEATURE_EXTSCAN) {
5548 hddLog(LOG1, FL("Batch scan is supported as extscan is supported"));
5549 fset &= ~WIFI_FEATURE_BATCH_SCAN;
5550 } else if (sme_IsFeatureSupportedByFW(BATCH_SCAN)) {
5551 hddLog(LOG1, FL("Batch scan is supported by firmware"));
5552 fset |= WIFI_FEATURE_BATCH_SCAN;
5553 }
5554#endif
5555
5556#ifdef FEATURE_WLAN_SCAN_PNO
5557 if (pHddCtx->cfg_ini->configPNOScanSupport &&
5558 (eHAL_STATUS_SUCCESS == wlan_hdd_is_pno_allowed(pAdapter))) {
5559 hddLog(LOG1, FL("PNO is supported by firmware"));
5560 fset |= WIFI_FEATURE_PNO;
5561 }
5562#endif
5563
5564 /* STA+STA is supported currently by default */
5565 fset |= WIFI_FEATURE_ADDITIONAL_STA;
5566
5567#ifdef FEATURE_WLAN_TDLS
5568 if ((TRUE == pHddCtx->cfg_ini->fEnableTDLSSupport) &&
5569 sme_IsFeatureSupportedByFW(TDLS)) {
5570 hddLog(LOG1, FL("TDLS is supported by firmware"));
5571 fset |= WIFI_FEATURE_TDLS;
5572 }
5573
5574 /* TDLS_OFFCHANNEL is not supported currently by default */
5575#endif
5576
5577#ifdef WLAN_AP_STA_CONCURRENCY
5578 /* AP+STA concurrency is supported currently by default */
5579 fset |= WIFI_FEATURE_AP_STA;
5580#endif
5581
Mukul Sharma5add0532015-08-17 15:57:47 +05305582#ifdef WLAN_FEATURE_LINK_LAYER_STATS
5583 fset |= WIFI_FEATURE_LINK_LAYER_STATS;
5584 hddLog(LOG1, FL("Link layer stats is supported by driver"));
5585#endif
5586
Dasari Srinivas7875a302014-09-26 17:50:57 +05305587 skb = cfg80211_vendor_cmd_alloc_reply_skb(wiphy, sizeof(fset) +
5588 NLMSG_HDRLEN);
5589
5590 if (!skb) {
5591 hddLog(LOGE, FL("cfg80211_vendor_cmd_alloc_reply_skb failed"));
5592 return -EINVAL;
5593 }
5594 hddLog(LOG1, FL("Supported Features : 0x%x"), fset);
5595
5596 if (nla_put_u32(skb, QCA_WLAN_VENDOR_ATTR_FEATURE_SET, fset)) {
5597 hddLog(LOGE, FL("nla put fail"));
5598 goto nla_put_failure;
5599 }
5600
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05305601 ret = cfg80211_vendor_cmd_reply(skb);
5602 EXIT();
5603 return ret;
Dasari Srinivas7875a302014-09-26 17:50:57 +05305604
5605nla_put_failure:
5606 kfree_skb(skb);
5607 return -EINVAL;
5608}
5609
Dasari Srinivase18b2cf2014-10-28 17:09:42 +05305610static int
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05305611wlan_hdd_cfg80211_get_supported_features(struct wiphy *wiphy,
5612 struct wireless_dev *wdev,
5613 const void *data, int data_len)
5614{
5615 int ret = 0;
5616
5617 vos_ssr_protect(__func__);
5618 ret = __wlan_hdd_cfg80211_get_supported_features(wiphy, wdev, data, data_len);
5619 vos_ssr_unprotect(__func__);
5620
5621 return ret;
5622}
5623
Sachin Ahujac08f72a2015-09-22 15:25:47 +05305624
5625static const struct
5626nla_policy
5627qca_wlan_vendor_wifi_logger_get_ring_data_policy
5628[QCA_WLAN_VENDOR_ATTR_WIFI_LOGGER_GET_RING_DATA_MAX + 1] = {
5629 [QCA_WLAN_VENDOR_ATTR_WIFI_LOGGER_GET_RING_DATA_ID]
5630 = {.type = NLA_U32 },
5631};
5632
5633static int
5634 __wlan_hdd_cfg80211_wifi_logger_get_ring_data(struct wiphy *wiphy,
5635 struct wireless_dev *wdev,
5636 const void *data,
5637 int data_len)
5638{
5639 int ret;
5640 VOS_STATUS status;
5641 uint32_t ring_id;
5642 hdd_context_t *hdd_ctx = wiphy_priv(wiphy);
5643 struct nlattr *tb
5644 [QCA_WLAN_VENDOR_ATTR_WIFI_LOGGER_GET_RING_DATA_MAX + 1];
5645
5646 ENTER();
5647
5648 ret = wlan_hdd_validate_context(hdd_ctx);
5649 if (0 != ret) {
5650 return ret;
5651 }
5652
5653 if (nla_parse(tb, QCA_WLAN_VENDOR_ATTR_WIFI_LOGGER_GET_RING_DATA_MAX,
5654 data, data_len,
5655 qca_wlan_vendor_wifi_logger_get_ring_data_policy)) {
5656 hddLog(LOGE, FL("Invalid attribute"));
5657 return -EINVAL;
5658 }
5659
5660 /* Parse and fetch ring id */
5661 if (!tb[QCA_WLAN_VENDOR_ATTR_WIFI_LOGGER_GET_RING_DATA_ID]) {
5662 hddLog(LOGE, FL("attr ATTR failed"));
5663 return -EINVAL;
5664 }
5665
5666 ring_id = nla_get_u32(
5667 tb[QCA_WLAN_VENDOR_ATTR_WIFI_LOGGER_GET_RING_DATA_ID]);
5668
5669 hddLog(LOG1, FL("Bug report triggered by framework"));
5670
5671 status = vos_fatal_event_logs_req(WLAN_LOG_TYPE_NON_FATAL,
5672 WLAN_LOG_INDICATOR_FRAMEWORK,
5673 WLAN_LOG_REASON_CODE_FRAMEWORK,
Abhishek Singh837adf22015-10-01 17:37:37 +05305674 TRUE, TRUE
Sachin Ahujac08f72a2015-09-22 15:25:47 +05305675 );
5676 if (VOS_STATUS_SUCCESS != status) {
5677 hddLog(LOGE, FL("Failed to trigger bug report"));
5678
5679 return -EINVAL;
5680 }
5681
5682 return 0;
5683
5684
5685}
5686
5687
5688static int
5689 wlan_hdd_cfg80211_wifi_logger_get_ring_data(struct wiphy *wiphy,
5690 struct wireless_dev *wdev,
5691 const void *data,
5692 int data_len)
5693{
5694 int ret = 0;
5695
5696 vos_ssr_protect(__func__);
5697 ret = __wlan_hdd_cfg80211_wifi_logger_get_ring_data(wiphy,
5698 wdev, data, data_len);
5699 vos_ssr_unprotect(__func__);
5700
5701 return ret;
5702
5703}
5704
5705
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05305706static int
5707__wlan_hdd_cfg80211_get_concurrency_matrix(struct wiphy *wiphy,
Dasari Srinivase18b2cf2014-10-28 17:09:42 +05305708 struct wireless_dev *wdev,
Jeff Johnson393c2702014-12-16 11:09:35 +05305709 const void *data, int data_len)
Dasari Srinivase18b2cf2014-10-28 17:09:42 +05305710{
5711 uint32_t feature_set_matrix[WLAN_HDD_MAX_FEATURE_SET] = {0};
5712 uint8_t i, feature_sets, max_feature_sets;
5713 struct nlattr *tb[QCA_WLAN_VENDOR_ATTR_GET_CONCURRENCY_MATRIX_MAX + 1];
5714 struct sk_buff *reply_skb;
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05305715 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
5716 int ret;
Dasari Srinivase18b2cf2014-10-28 17:09:42 +05305717
5718 ENTER();
5719
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05305720 ret = wlan_hdd_validate_context(pHddCtx);
5721 if (0 != ret)
5722 {
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05305723 return ret;
5724 }
5725
Dasari Srinivase18b2cf2014-10-28 17:09:42 +05305726 if (nla_parse(tb, QCA_WLAN_VENDOR_ATTR_GET_CONCURRENCY_MATRIX_MAX,
5727 data, data_len, NULL)) {
5728 hddLog(LOGE, FL("Invalid ATTR"));
5729 return -EINVAL;
5730 }
5731
5732 /* Parse and fetch max feature set */
5733 if (!tb[QCA_WLAN_VENDOR_ATTR_GET_CONCURRENCY_MATRIX_CONFIG_PARAM_SET_SIZE_MAX]) {
5734 hddLog(LOGE, FL("Attr max feature set size failed"));
5735 return -EINVAL;
5736 }
5737 max_feature_sets = nla_get_u32(
5738 tb[QCA_WLAN_VENDOR_ATTR_GET_CONCURRENCY_MATRIX_CONFIG_PARAM_SET_SIZE_MAX]);
5739 hddLog(LOG1, FL("Max feature set size (%d)"), max_feature_sets);
5740
5741 /* Fill feature combination matrix */
5742 feature_sets = 0;
Dasari Srinivase18b2cf2014-10-28 17:09:42 +05305743 feature_set_matrix[feature_sets++] = WIFI_FEATURE_INFRA |
5744 WIFI_FEATURE_P2P;
5745
Dasari Srinivase18b2cf2014-10-28 17:09:42 +05305746 feature_set_matrix[feature_sets++] = WIFI_FEATURE_INFRA |
5747 WIFI_FEATURE_SOFT_AP;
5748
Dasari Srinivase18b2cf2014-10-28 17:09:42 +05305749 feature_set_matrix[feature_sets++] = WIFI_FEATURE_P2P |
5750 WIFI_FEATURE_SOFT_AP;
5751
Dasari Srinivase18b2cf2014-10-28 17:09:42 +05305752 feature_set_matrix[feature_sets++] = WIFI_FEATURE_INFRA |
5753 WIFI_FEATURE_SOFT_AP |
5754 WIFI_FEATURE_P2P;
5755
5756 /* Add more feature combinations here */
5757
5758 feature_sets = VOS_MIN(feature_sets, max_feature_sets);
5759 hddLog(LOG1, FL("Number of feature sets (%d)"), feature_sets);
5760 hddLog(LOG1, "Feature set matrix");
5761 for (i = 0; i < feature_sets; i++)
5762 hddLog(LOG1, "[%d] 0x%02X", i, feature_set_matrix[i]);
5763
5764 reply_skb = cfg80211_vendor_cmd_alloc_reply_skb(wiphy, sizeof(u32) +
5765 sizeof(u32) * feature_sets +
5766 NLMSG_HDRLEN);
5767
5768 if (reply_skb) {
5769 if (nla_put_u32(reply_skb,
5770 QCA_WLAN_VENDOR_ATTR_GET_CONCURRENCY_MATRIX_RESULTS_SET_SIZE,
5771 feature_sets) ||
5772 nla_put(reply_skb,
5773 QCA_WLAN_VENDOR_ATTR_GET_CONCURRENCY_MATRIX_RESULTS_SET,
5774 sizeof(u32) * feature_sets, feature_set_matrix)) {
5775 hddLog(LOGE, FL("nla put fail"));
5776 kfree_skb(reply_skb);
5777 return -EINVAL;
5778 }
5779
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05305780 ret = cfg80211_vendor_cmd_reply(reply_skb);
5781 EXIT();
5782 return ret;
Dasari Srinivase18b2cf2014-10-28 17:09:42 +05305783 }
5784 hddLog(LOGE, FL("Feature set matrix: buffer alloc fail"));
5785 return -ENOMEM;
5786
Dasari Srinivase18b2cf2014-10-28 17:09:42 +05305787}
5788
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05305789static int
5790wlan_hdd_cfg80211_get_concurrency_matrix(struct wiphy *wiphy,
5791 struct wireless_dev *wdev,
5792 const void *data, int data_len)
5793{
5794 int ret = 0;
5795
5796 vos_ssr_protect(__func__);
5797 ret = __wlan_hdd_cfg80211_get_concurrency_matrix(wiphy, wdev, data,
5798 data_len);
5799 vos_ssr_unprotect(__func__);
5800
5801 return ret;
5802}
5803
c_manjeecfd1efb2015-09-25 19:32:34 +05305804
5805static int
5806__wlan_hdd_cfg80211_get_fw_mem_dump(struct wiphy *wiphy,
5807 struct wireless_dev *wdev,
5808 const void *data, int data_len)
5809{
5810 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
5811 int ret;
5812 ENTER();
5813
5814 ret = wlan_hdd_validate_context(pHddCtx);
5815 if (0 != ret)
5816 {
5817 return ret;
5818 }
5819
5820 if( !pHddCtx->cfg_ini->enableFwrMemDump ||
5821 (FALSE == sme_IsFeatureSupportedByFW(MEMORY_DUMP_SUPPORTED)))
5822 {
5823 hddLog(VOS_TRACE_LEVEL_INFO, FL("FW dump Logging not supported"));
5824 return -EINVAL;
5825 }
5826 /*call common API for FW mem dump req*/
5827 ret = wlan_hdd_fw_mem_dump_req(pHddCtx);
5828
c_manjee04b4c5c2015-10-13 18:35:01 +05305829 if (true == ret)
5830 {
5831 /*indicate to userspace the status of fw mem dump */
5832 wlan_indicate_mem_dump_complete(true);
5833 }
5834 else
5835 {
5836 /*else send failure to userspace */
5837 wlan_indicate_mem_dump_complete(false);
5838 }
c_manjeecfd1efb2015-09-25 19:32:34 +05305839 EXIT();
5840 return ret;
5841}
5842
5843/**
5844 * wlan_hdd_cfg80211_get_fw_mem_dump() - Get FW memory dump
5845 * @wiphy: pointer to wireless wiphy structure.
5846 * @wdev: pointer to wireless_dev structure.
5847 * @data: Pointer to the NL data.
5848 * @data_len:Length of @data
5849 *
5850 * This is called when wlan driver needs to get the firmware memory dump
5851 * via vendor specific command.
5852 *
5853 * Return: 0 on success, error number otherwise.
5854 */
5855
5856static int
5857wlan_hdd_cfg80211_get_fw_mem_dump(struct wiphy *wiphy,
5858 struct wireless_dev *wdev,
5859 const void *data, int data_len)
Sushant Kaushik8e644982015-09-23 12:18:54 +05305860{
5861 int ret = 0;
5862 vos_ssr_protect(__func__);
5863 ret = __wlan_hdd_cfg80211_get_fw_mem_dump(wiphy, wdev, data,
5864 data_len);
5865 vos_ssr_unprotect(__func__);
5866 return ret;
5867}
c_manjeecfd1efb2015-09-25 19:32:34 +05305868
Sushant Kaushik8e644982015-09-23 12:18:54 +05305869static const struct
5870nla_policy
5871qca_wlan_vendor_wifi_logger_start_policy
5872[QCA_WLAN_VENDOR_ATTR_WIFI_LOGGER_START_MAX + 1] = {
5873 [QCA_WLAN_VENDOR_ATTR_WIFI_LOGGER_RING_ID]
5874 = {.type = NLA_U32 },
5875 [QCA_WLAN_VENDOR_ATTR_WIFI_LOGGER_VERBOSE_LEVEL]
5876 = {.type = NLA_U32 },
5877 [QCA_WLAN_VENDOR_ATTR_WIFI_LOGGER_FLAGS]
5878 = {.type = NLA_U32 },
5879};
5880
5881/**
5882 * __wlan_hdd_cfg80211_wifi_logger_start() - This function is used to enable
5883 * or disable the collection of packet statistics from the firmware
5884 * @wiphy: WIPHY structure pointer
5885 * @wdev: Wireless device structure pointer
5886 * @data: Pointer to the data received
5887 * @data_len: Length of the data received
5888 *
5889 * This function is used to enable or disable the collection of packet
5890 * statistics from the firmware
5891 *
5892 * Return: 0 on success and errno on failure
5893 */
5894static int __wlan_hdd_cfg80211_wifi_logger_start(struct wiphy *wiphy,
5895 struct wireless_dev *wdev,
5896 const void *data,
5897 int data_len)
5898{
5899 eHalStatus status;
5900 hdd_context_t *hdd_ctx = wiphy_priv(wiphy);
5901 struct nlattr *tb[QCA_WLAN_VENDOR_ATTR_WIFI_LOGGER_START_MAX + 1];
5902 tAniWifiStartLog start_log;
5903
5904 status = wlan_hdd_validate_context(hdd_ctx);
5905 if (0 != status) {
5906 return -EINVAL;
5907 }
5908
5909 if (nla_parse(tb, QCA_WLAN_VENDOR_ATTR_WIFI_LOGGER_START_MAX,
5910 data, data_len,
5911 qca_wlan_vendor_wifi_logger_start_policy)) {
5912 hddLog(LOGE, FL("Invalid attribute"));
5913 return -EINVAL;
5914 }
5915
5916 /* Parse and fetch ring id */
5917 if (!tb[QCA_WLAN_VENDOR_ATTR_WIFI_LOGGER_RING_ID]) {
5918 hddLog(LOGE, FL("attr ATTR failed"));
5919 return -EINVAL;
5920 }
5921 start_log.ringId = nla_get_u32(
5922 tb[QCA_WLAN_VENDOR_ATTR_WIFI_LOGGER_RING_ID]);
5923 hddLog(LOG1, FL("Ring ID=%d"), start_log.ringId);
5924
5925 /* Parse and fetch verbose level */
5926 if (!tb[QCA_WLAN_VENDOR_ATTR_WIFI_LOGGER_VERBOSE_LEVEL]) {
5927 hddLog(LOGE, FL("attr verbose_level failed"));
5928 return -EINVAL;
5929 }
5930 start_log.verboseLevel = nla_get_u32(
5931 tb[QCA_WLAN_VENDOR_ATTR_WIFI_LOGGER_VERBOSE_LEVEL]);
5932 hddLog(LOG1, FL("verbose_level=%d"), start_log.verboseLevel);
5933
5934 /* Parse and fetch flag */
5935 if (!tb[QCA_WLAN_VENDOR_ATTR_WIFI_LOGGER_FLAGS]) {
5936 hddLog(LOGE, FL("attr flag failed"));
5937 return -EINVAL;
5938 }
5939 start_log.flag = nla_get_u32(
5940 tb[QCA_WLAN_VENDOR_ATTR_WIFI_LOGGER_FLAGS]);
5941 hddLog(LOG1, FL("flag=%d"), start_log.flag);
5942
5943 if ((RING_ID_PER_PACKET_STATS == start_log.ringId) &&
Sushant Kaushik33200572015-08-05 16:46:20 +05305944 (!hdd_ctx->cfg_ini->wlanPerPktStatsLogEnable ||
5945 !vos_isPktStatsEnabled()))
5946
Sushant Kaushik8e644982015-09-23 12:18:54 +05305947 {
5948 hddLog(LOGE, FL("per pkt stats not enabled"));
5949 return -EINVAL;
5950 }
Sushant Kaushik8e644982015-09-23 12:18:54 +05305951
Sushant Kaushik33200572015-08-05 16:46:20 +05305952 vos_set_ring_log_level(start_log.ringId, start_log.verboseLevel);
Sushant Kaushik8e644982015-09-23 12:18:54 +05305953 return 0;
5954}
5955
5956/**
5957 * wlan_hdd_cfg80211_wifi_logger_start() - Wrapper function used to enable
5958 * or disable the collection of packet statistics from the firmware
5959 * @wiphy: WIPHY structure pointer
5960 * @wdev: Wireless device structure pointer
5961 * @data: Pointer to the data received
5962 * @data_len: Length of the data received
5963 *
5964 * This function is used to enable or disable the collection of packet
5965 * statistics from the firmware
5966 *
5967 * Return: 0 on success and errno on failure
5968 */
5969static int wlan_hdd_cfg80211_wifi_logger_start(struct wiphy *wiphy,
5970 struct wireless_dev *wdev,
5971 const void *data,
5972 int data_len)
c_manjeecfd1efb2015-09-25 19:32:34 +05305973{
5974 int ret = 0;
5975
5976 vos_ssr_protect(__func__);
Sushant Kaushik8e644982015-09-23 12:18:54 +05305977
5978 ret = __wlan_hdd_cfg80211_wifi_logger_start(wiphy,
5979 wdev, data, data_len);
c_manjeecfd1efb2015-09-25 19:32:34 +05305980 vos_ssr_unprotect(__func__);
5981
5982 return ret;
c_manjeecfd1efb2015-09-25 19:32:34 +05305983}
5984
5985
Agarwal Ashish738843c2014-09-25 12:27:56 +05305986static const struct nla_policy
5987wlan_hdd_set_no_dfs_flag_config_policy[QCA_WLAN_VENDOR_ATTR_SET_NO_DFS_FLAG_MAX
5988 +1] =
5989{
5990 [QCA_WLAN_VENDOR_ATTR_SET_NO_DFS_FLAG] = {.type = NLA_U32 },
5991};
5992
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05305993static int __wlan_hdd_cfg80211_disable_dfs_channels(struct wiphy *wiphy,
Agarwal Ashish738843c2014-09-25 12:27:56 +05305994 struct wireless_dev *wdev,
Jeff Johnson393c2702014-12-16 11:09:35 +05305995 const void *data,
Agarwal Ashish738843c2014-09-25 12:27:56 +05305996 int data_len)
5997{
5998 struct net_device *dev = wdev->netdev;
5999 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
6000 tHalHandle hHal = WLAN_HDD_GET_HAL_CTX(pAdapter);
6001 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
6002 struct nlattr *tb[QCA_WLAN_VENDOR_ATTR_SET_NO_DFS_FLAG_MAX + 1];
6003 eHalStatus status;
6004 u32 dfsFlag = 0;
6005
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05306006 ENTER();
6007
Agarwal Ashish738843c2014-09-25 12:27:56 +05306008 status = wlan_hdd_validate_context(pHddCtx);
6009 if (0 != status) {
Agarwal Ashish738843c2014-09-25 12:27:56 +05306010 return -EINVAL;
6011 }
6012 if (nla_parse(tb, QCA_WLAN_VENDOR_ATTR_SET_NO_DFS_FLAG_MAX,
6013 data, data_len,
6014 wlan_hdd_set_no_dfs_flag_config_policy)) {
6015 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Invalid ATTR"));
6016 return -EINVAL;
6017 }
6018
6019 /* Parse and fetch required bandwidth kbps */
6020 if (!tb[QCA_WLAN_VENDOR_ATTR_SET_NO_DFS_FLAG]) {
6021 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr dfs flag failed"));
6022 return -EINVAL;
6023 }
6024
6025 dfsFlag = nla_get_u32(
6026 tb[QCA_WLAN_VENDOR_ATTR_SET_NO_DFS_FLAG]);
6027 hddLog(VOS_TRACE_LEVEL_INFO, FL(" DFS flag (%d)"),
6028 dfsFlag);
6029
6030 pHddCtx->disable_dfs_flag = dfsFlag;
6031
6032 sme_disable_dfs_channel(hHal, dfsFlag);
6033 sme_FilterScanResults(hHal, pAdapter->sessionId);
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05306034
6035 EXIT();
Agarwal Ashish738843c2014-09-25 12:27:56 +05306036 return 0;
6037}
Atul Mittal115287b2014-07-08 13:26:33 +05306038
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05306039static int wlan_hdd_cfg80211_disable_dfs_channels(struct wiphy *wiphy,
6040 struct wireless_dev *wdev,
6041 const void *data,
6042 int data_len)
6043{
6044 int ret = 0;
6045
6046 vos_ssr_protect(__func__);
6047 ret = __wlan_hdd_cfg80211_disable_dfs_channels(wiphy, wdev, data, data_len);
6048 vos_ssr_unprotect(__func__);
6049
6050 return ret;
6051
6052}
6053
Mukul Sharma2a271632014-10-13 14:59:01 +05306054const struct
6055nla_policy qca_wlan_vendor_attr[QCA_WLAN_VENDOR_ATTR_MAX+1] =
6056{
6057 [QCA_WLAN_VENDOR_ATTR_ROAMING_POLICY] = { .type = NLA_U32 },
6058 [QCA_WLAN_VENDOR_ATTR_MAC_ADDR] = { .type = NLA_UNSPEC },
6059};
6060
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05306061static int __wlan_hdd_cfg80211_firmware_roaming(struct wiphy *wiphy,
Jeff Johnson393c2702014-12-16 11:09:35 +05306062 struct wireless_dev *wdev, const void *data, int data_len)
Mukul Sharma2a271632014-10-13 14:59:01 +05306063{
6064
6065 u8 bssid[6] = {0};
6066 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
6067 struct nlattr *tb[QCA_WLAN_VENDOR_ATTR_MAX + 1];
6068 eHalStatus status = eHAL_STATUS_SUCCESS;
6069 v_U32_t isFwrRoamEnabled = FALSE;
6070 int ret;
6071
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05306072 ENTER();
6073
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05306074 ret = wlan_hdd_validate_context(pHddCtx);
6075 if (0 != ret) {
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05306076 return ret;
Mukul Sharma2a271632014-10-13 14:59:01 +05306077 }
6078
6079 ret = nla_parse(tb, QCA_WLAN_VENDOR_ATTR_MAX,
6080 data, data_len,
6081 qca_wlan_vendor_attr);
6082 if (ret){
6083 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Invalid ATTR"));
6084 return -EINVAL;
6085 }
6086
6087 /* Parse and fetch Enable flag */
6088 if (!tb[QCA_WLAN_VENDOR_ATTR_ROAMING_POLICY]) {
6089 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr enable failed"));
6090 return -EINVAL;
6091 }
6092
6093 isFwrRoamEnabled = nla_get_u32(
6094 tb[QCA_WLAN_VENDOR_ATTR_ROAMING_POLICY]);
6095
6096 hddLog(VOS_TRACE_LEVEL_INFO, FL("isFwrRoamEnabled (%d)"), isFwrRoamEnabled);
6097
6098 /* Parse and fetch bssid */
6099 if (!tb[QCA_WLAN_VENDOR_ATTR_MAC_ADDR]) {
6100 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr bss id failed"));
6101 return -EINVAL;
6102 }
6103
6104 memcpy(bssid, nla_data(
6105 tb[QCA_WLAN_VENDOR_ATTR_MAC_ADDR]),
6106 sizeof(bssid));
6107 hddLog(VOS_TRACE_LEVEL_INFO, FL(MAC_ADDRESS_STR),MAC_ADDR_ARRAY(bssid));
6108
6109 //Update roaming
6110 status = sme_ConfigFwrRoaming((tHalHandle)(pHddCtx->hHal), isFwrRoamEnabled);
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05306111 EXIT();
Mukul Sharma2a271632014-10-13 14:59:01 +05306112 return status;
6113}
6114
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05306115static int wlan_hdd_cfg80211_firmware_roaming(struct wiphy *wiphy,
6116 struct wireless_dev *wdev, const void *data, int data_len)
6117{
6118 int ret = 0;
6119
6120 vos_ssr_protect(__func__);
6121 ret = __wlan_hdd_cfg80211_firmware_roaming(wiphy, wdev, data, data_len);
6122 vos_ssr_unprotect(__func__);
6123
6124 return ret;
6125}
6126
Sushant Kaushik847890c2015-09-28 16:05:17 +05306127static const struct
6128nla_policy
6129qca_wlan_vendor_get_wifi_info_policy[
6130 QCA_WLAN_VENDOR_ATTR_WIFI_INFO_GET_MAX +1] = {
6131 [QCA_WLAN_VENDOR_ATTR_WIFI_INFO_DRIVER_VERSION] = {.type = NLA_U8 },
6132 [QCA_WLAN_VENDOR_ATTR_WIFI_INFO_FIRMWARE_VERSION] = {.type = NLA_U8 },
6133};
6134
6135
6136/**
6137 * __wlan_hdd_cfg80211_get_wifi_info() - Get the wifi driver related info
6138 * @wiphy: pointer to wireless wiphy structure.
6139 * @wdev: pointer to wireless_dev structure.
6140 * @data: Pointer to the data to be passed via vendor interface
6141 * @data_len:Length of the data to be passed
6142 *
6143 * This is called when wlan driver needs to send wifi driver related info
6144 * (driver/fw version) to the user space application upon request.
6145 *
6146 * Return: Return the Success or Failure code.
6147 */
6148static int __wlan_hdd_cfg80211_get_wifi_info(struct wiphy *wiphy,
6149 struct wireless_dev *wdev,
6150 const void *data, int data_len)
6151{
6152 hdd_context_t *hdd_ctx = wiphy_priv(wiphy);
6153 struct nlattr *tb_vendor[QCA_WLAN_VENDOR_ATTR_WIFI_INFO_GET_MAX + 1];
6154 tSirVersionString version;
6155 uint32 version_len;
6156 uint8 attr;
6157 int status;
6158 struct sk_buff *reply_skb = NULL;
6159
6160 if (VOS_FTM_MODE == hdd_get_conparam()) {
6161 hddLog(LOGE, FL("Command not allowed in FTM mode"));
6162 return -EINVAL;
6163 }
6164
6165 status = wlan_hdd_validate_context(hdd_ctx);
6166 if (0 != status) {
6167 hddLog(LOGE, FL("HDD context is not valid"));
6168 return -EINVAL;
6169 }
6170
6171 if (nla_parse(tb_vendor, QCA_WLAN_VENDOR_ATTR_WIFI_INFO_GET_MAX, data,
6172 data_len, qca_wlan_vendor_get_wifi_info_policy)) {
6173 hddLog(LOGE, FL("WIFI_INFO_GET NL CMD parsing failed"));
6174 return -EINVAL;
6175 }
6176
6177 if (tb_vendor[QCA_WLAN_VENDOR_ATTR_WIFI_INFO_DRIVER_VERSION]) {
6178 hddLog(LOG1, FL("Rcvd req for Driver version Driver version is %s"),
6179 QWLAN_VERSIONSTR);
6180 strlcpy(version, QWLAN_VERSIONSTR, sizeof(version));
6181 attr = QCA_WLAN_VENDOR_ATTR_WIFI_INFO_DRIVER_VERSION;
6182 } else if (tb_vendor[QCA_WLAN_VENDOR_ATTR_WIFI_INFO_FIRMWARE_VERSION]) {
6183 hddLog(LOG1, FL("Rcvd req for FW version FW version is %s"),
6184 hdd_ctx->fw_Version);
6185 strlcpy(version, hdd_ctx->fw_Version, sizeof(version));
6186 attr = QCA_WLAN_VENDOR_ATTR_WIFI_INFO_FIRMWARE_VERSION;
6187 } else {
6188 hddLog(LOGE, FL("Invalid attribute in get wifi info request"));
6189 return -EINVAL;
6190 }
6191
6192 version_len = strlen(version);
6193 reply_skb = cfg80211_vendor_cmd_alloc_reply_skb(wiphy,
6194 version_len + NLA_HDRLEN + NLMSG_HDRLEN);
6195 if (!reply_skb) {
6196 hddLog(LOGE, FL("cfg80211_vendor_cmd_alloc_reply_skb failed"));
6197 return -ENOMEM;
6198 }
6199
6200 if (nla_put(reply_skb, attr, version_len, version)) {
6201 hddLog(LOGE, FL("nla put fail"));
6202 kfree_skb(reply_skb);
6203 return -EINVAL;
6204 }
6205
6206 return cfg80211_vendor_cmd_reply(reply_skb);
6207}
6208
6209/**
6210 * __wlan_hdd_cfg80211_get_wifi_info() - Get the wifi driver related info
6211 * @wiphy: pointer to wireless wiphy structure.
6212 * @wdev: pointer to wireless_dev structure.
6213 * @data: Pointer to the data to be passed via vendor interface
6214 * @data_len:Length of the data to be passed
6215 * @data_len: Length of the data received
6216 *
6217 * This function is used to enable or disable the collection of packet
6218 * statistics from the firmware
6219 *
6220 * Return: 0 on success and errno on failure
6221 */
6222
6223static int
6224wlan_hdd_cfg80211_get_wifi_info(struct wiphy *wiphy,
6225 struct wireless_dev *wdev,
6226 const void *data, int data_len)
6227
6228
6229{
6230 int ret = 0;
6231
6232 vos_ssr_protect(__func__);
6233 ret = __wlan_hdd_cfg80211_get_wifi_info(wiphy,
6234 wdev, data, data_len);
6235 vos_ssr_unprotect(__func__);
6236
6237 return ret;
6238}
6239
6240
Gupta, Kapil7c34b322015-09-30 13:12:35 +05306241/*
6242 * define short names for the global vendor params
6243 * used by __wlan_hdd_cfg80211_monitor_rssi()
6244 */
6245#define PARAM_MAX QCA_WLAN_VENDOR_ATTR_RSSI_MONITORING_MAX
6246#define PARAM_REQUEST_ID QCA_WLAN_VENDOR_ATTR_RSSI_MONITORING_REQUEST_ID
6247#define PARAM_CONTROL QCA_WLAN_VENDOR_ATTR_RSSI_MONITORING_CONTROL
6248#define PARAM_MIN_RSSI QCA_WLAN_VENDOR_ATTR_RSSI_MONITORING_MIN_RSSI
6249#define PARAM_MAX_RSSI QCA_WLAN_VENDOR_ATTR_RSSI_MONITORING_MAX_RSSI
6250
6251/**---------------------------------------------------------------------------
6252
6253 \brief hdd_rssi_monitor_start_done - callback to be executed when rssi
6254 monitor start is completed successfully.
6255
6256 \return - None
6257
6258 --------------------------------------------------------------------------*/
6259void hdd_rssi_monitor_start_done(void *fwRssiMonitorCbContext, VOS_STATUS status)
6260{
6261 hdd_context_t* pHddCtx = (hdd_context_t*)fwRssiMonitorCbContext;
6262
6263 if (NULL == pHddCtx)
6264 {
6265 hddLog(VOS_TRACE_LEVEL_ERROR,
6266 "%s: HDD context is NULL",__func__);
6267 return;
6268 }
6269
6270 if (VOS_STATUS_SUCCESS == status)
6271 {
6272 hddLog(VOS_TRACE_LEVEL_INFO, FL("Rssi Monitor start successful"));
6273 }
6274 else
6275 {
6276 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Rssi Monitor start not successful"));
6277 }
6278
6279 return;
6280}
6281
6282/**---------------------------------------------------------------------------
6283
6284 \brief hdd_rssi_monitor_stop_done - callback to be executed when rssi monitor
6285 stop is completed successfully.
6286
6287 \return - None
6288
6289 --------------------------------------------------------------------------*/
6290void hdd_rssi_monitor_stop_done(void *fwRssiMonitorCbContext, VOS_STATUS status)
6291{
6292 hdd_context_t* pHddCtx = (hdd_context_t*)fwRssiMonitorCbContext;
6293
6294 if (NULL == pHddCtx)
6295 {
6296 hddLog(VOS_TRACE_LEVEL_ERROR,
6297 "%s: HDD context is NULL",__func__);
6298 return;
6299 }
6300
6301 if (VOS_STATUS_SUCCESS == status)
6302 {
6303 hddLog(VOS_TRACE_LEVEL_INFO, FL("Rssi Monitor stop successful"));
6304 }
6305 else
6306 {
6307 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Rssi Monitor stop not successful"));
6308 }
6309
6310 return;
6311}
6312
6313/**
6314 * __wlan_hdd_cfg80211_monitor_rssi() - monitor rssi
6315 * @wiphy: Pointer to wireless phy
6316 * @wdev: Pointer to wireless device
6317 * @data: Pointer to data
6318 * @data_len: Data length
6319 *
6320 * Return: 0 on success, negative errno on failure
6321 */
6322
6323static int
6324__wlan_hdd_cfg80211_monitor_rssi(struct wiphy *wiphy,
6325 struct wireless_dev *wdev,
6326 const void *data,
6327 int data_len)
6328{
6329 struct net_device *dev = wdev->netdev;
6330 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
6331 hdd_context_t *hdd_ctx = wiphy_priv(wiphy);
6332 hdd_station_ctx_t *pHddStaCtx;
6333 struct nlattr *tb[PARAM_MAX + 1];
6334 tpSirRssiMonitorReq pReq;
6335 eHalStatus status;
6336 int ret;
6337 uint32_t control;
6338 static const struct nla_policy policy[PARAM_MAX + 1] = {
6339 [PARAM_REQUEST_ID] = { .type = NLA_U32 },
6340 [PARAM_CONTROL] = { .type = NLA_U32 },
6341 [PARAM_MIN_RSSI] = { .type = NLA_S8 },
6342 [PARAM_MAX_RSSI] = { .type = NLA_S8 },
6343 };
6344
6345 ENTER();
6346
6347 ret = wlan_hdd_validate_context(hdd_ctx);
6348 if (0 != ret) {
6349 return -EINVAL;
6350 }
6351
6352 if (!hdd_connIsConnected(WLAN_HDD_GET_STATION_CTX_PTR(pAdapter))) {
6353 hddLog(LOGE, FL("Not in Connected state!"));
6354 return -ENOTSUPP;
6355 }
6356
6357 if (nla_parse(tb, PARAM_MAX, data, data_len, policy)) {
6358 hddLog(LOGE, FL("Invalid ATTR"));
6359 return -EINVAL;
6360 }
6361
6362 if (!tb[PARAM_REQUEST_ID]) {
6363 hddLog(LOGE, FL("attr request id failed"));
6364 return -EINVAL;
6365 }
6366
6367 if (!tb[PARAM_CONTROL]) {
6368 hddLog(LOGE, FL("attr control failed"));
6369 return -EINVAL;
6370 }
6371
6372 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
6373
6374 pReq = vos_mem_malloc(sizeof(tSirRssiMonitorReq));
6375 if(NULL == pReq)
6376 {
6377 hddLog(LOGE,
6378 FL("vos_mem_alloc failed "));
6379 return eHAL_STATUS_FAILED_ALLOC;
6380 }
6381 vos_mem_set(pReq, sizeof(tSirRssiMonitorReq), 0);
6382
6383 pReq->requestId = nla_get_u32(tb[PARAM_REQUEST_ID]);
6384 pReq->sessionId = pAdapter->sessionId;
6385 pReq->rssiMonitorCbContext = hdd_ctx;
6386 control = nla_get_u32(tb[PARAM_CONTROL]);
6387 vos_mem_copy( &pReq->currentBssId, pHddStaCtx->conn_info.bssId, WNI_CFG_BSSID_LEN);
6388
6389 hddLog(LOG1, FL("Request Id: %u Session_id: %d Control: %d"),
6390 pReq->requestId, pReq->sessionId, control);
6391
6392 if (control == QCA_WLAN_RSSI_MONITORING_START) {
6393 if (!tb[PARAM_MIN_RSSI]) {
6394 hddLog(LOGE, FL("attr min rssi failed"));
6395 return -EINVAL;
6396 }
6397
6398 if (!tb[PARAM_MAX_RSSI]) {
6399 hddLog(LOGE, FL("attr max rssi failed"));
6400 return -EINVAL;
6401 }
6402
6403 pReq->minRssi = nla_get_s8(tb[PARAM_MIN_RSSI]);
6404 pReq->maxRssi = nla_get_s8(tb[PARAM_MAX_RSSI]);
6405 pReq->rssiMonitorCallback = hdd_rssi_monitor_start_done;
6406
6407 if (!(pReq->minRssi < pReq->maxRssi)) {
6408 hddLog(LOGW, FL("min_rssi: %d must be less than max_rssi: %d"),
6409 pReq->minRssi, pReq->maxRssi);
6410 return -EINVAL;
6411 }
6412 hddLog(LOG1, FL("Min_rssi: %d Max_rssi: %d"),
6413 pReq->minRssi, pReq->maxRssi);
6414 status = sme_StartRssiMonitoring(hdd_ctx->hHal, pReq);
6415
6416 }
6417 else if (control == QCA_WLAN_RSSI_MONITORING_STOP) {
6418 pReq->rssiMonitorCallback = hdd_rssi_monitor_stop_done;
6419 status = sme_StopRssiMonitoring(hdd_ctx->hHal, pReq);
6420 }
6421 else {
6422 hddLog(LOGE, FL("Invalid control cmd: %d"), control);
6423 return -EINVAL;
6424 }
6425
6426 if (!HAL_STATUS_SUCCESS(status)) {
6427 hddLog(LOGE,
6428 FL("sme_set_rssi_monitoring failed(err=%d)"), status);
6429 return -EINVAL;
6430 }
6431
6432 return 0;
6433}
6434
6435/*
6436 * done with short names for the global vendor params
6437 * used by __wlan_hdd_cfg80211_monitor_rssi()
6438 */
6439#undef PARAM_MAX
6440#undef PARAM_CONTROL
6441#undef PARAM_REQUEST_ID
6442#undef PARAM_MAX_RSSI
6443#undef PARAM_MIN_RSSI
6444
6445/**
6446 * wlan_hdd_cfg80211_monitor_rssi() - SSR wrapper to rssi monitoring
6447 * @wiphy: wiphy structure pointer
6448 * @wdev: Wireless device structure pointer
6449 * @data: Pointer to the data received
6450 * @data_len: Length of @data
6451 *
6452 * Return: 0 on success; errno on failure
6453 */
6454static int
6455wlan_hdd_cfg80211_monitor_rssi(struct wiphy *wiphy, struct wireless_dev *wdev,
6456 const void *data, int data_len)
6457{
6458 int ret;
6459
6460 vos_ssr_protect(__func__);
6461 ret = __wlan_hdd_cfg80211_monitor_rssi(wiphy, wdev, data, data_len);
6462 vos_ssr_unprotect(__func__);
6463
6464 return ret;
6465}
6466
6467/**
6468 * hdd_rssi_threshold_breached_cb() - rssi breached NL event
6469 * @hddctx: HDD context
6470 * @data: rssi breached event data
6471 *
6472 * This function reads the rssi breached event %data and fill in the skb with
6473 * NL attributes and send up the NL event.
6474 * This callback execute in atomic context and must not invoke any
6475 * blocking calls.
6476 *
6477 * Return: none
6478 */
6479void hdd_rssi_threshold_breached_cb(void *hddctx,
6480 struct rssi_breach_event *data)
6481{
6482 hdd_context_t *pHddCtx = (hdd_context_t *)hddctx;
6483 int status;
6484 struct sk_buff *skb;
6485
6486 ENTER();
6487 status = wlan_hdd_validate_context(pHddCtx);
6488
6489 if (0 != status) {
6490 return;
6491 }
6492
6493 if (!data) {
6494 hddLog(LOGE, FL("data is null"));
6495 return;
6496 }
6497
6498 skb = cfg80211_vendor_event_alloc(pHddCtx->wiphy,
6499#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 18, 0))
6500 NULL,
6501#endif
6502 EXTSCAN_EVENT_BUF_SIZE + NLMSG_HDRLEN,
6503 QCA_NL80211_VENDOR_SUBCMD_MONITOR_RSSI_INDEX,
6504 GFP_KERNEL);
6505
6506 if (!skb) {
6507 hddLog(LOGE, FL("cfg80211_vendor_event_alloc failed"));
6508 return;
6509 }
6510
6511 hddLog(LOG1, "Req Id: %u Current rssi: %d",
6512 data->request_id, data->curr_rssi);
6513 hddLog(LOG1, "Current BSSID: "MAC_ADDRESS_STR,
6514 MAC_ADDR_ARRAY(data->curr_bssid.bytes));
6515
6516 if (nla_put_u32(skb, QCA_WLAN_VENDOR_ATTR_RSSI_MONITORING_REQUEST_ID,
6517 data->request_id) ||
6518 nla_put(skb, QCA_WLAN_VENDOR_ATTR_RSSI_MONITORING_CUR_BSSID,
6519 sizeof(data->curr_bssid), data->curr_bssid.bytes) ||
6520 nla_put_s8(skb, QCA_WLAN_VENDOR_ATTR_RSSI_MONITORING_CUR_RSSI,
6521 data->curr_rssi)) {
6522 hddLog(LOGE, FL("nla put fail"));
6523 goto fail;
6524 }
6525
6526 cfg80211_vendor_event(skb, GFP_KERNEL);
6527 return;
6528
6529fail:
6530 kfree_skb(skb);
6531 return;
6532}
6533
6534
6535
Srinivas Dasari41d97c92015-07-29 13:09:39 +05306536/**
6537 * __wlan_hdd_cfg80211_setband() - set band
6538 * @wiphy: Pointer to wireless phy
6539 * @wdev: Pointer to wireless device
6540 * @data: Pointer to data
6541 * @data_len: Data length
6542 *
6543 * Return: 0 on success, negative errno on failure
6544 */
6545static int
6546__wlan_hdd_cfg80211_setband(struct wiphy *wiphy,
6547 struct wireless_dev *wdev,
6548 const void *data,
6549 int data_len)
6550{
6551 struct net_device *dev = wdev->netdev;
6552 hdd_context_t *hdd_ctx = wiphy_priv(wiphy);
6553 struct nlattr *tb[QCA_WLAN_VENDOR_ATTR_MAX + 1];
6554 int ret;
6555 static const struct nla_policy policy[QCA_WLAN_VENDOR_ATTR_MAX + 1]
6556 = {[QCA_WLAN_VENDOR_ATTR_SETBAND_VALUE] = { .type = NLA_U32 }};
6557
6558 ENTER();
6559
6560 ret = wlan_hdd_validate_context(hdd_ctx);
6561 if (0 != ret) {
6562 hddLog(LOGE, FL("HDD context is not valid"));
6563 return ret;
6564 }
6565
6566 if (nla_parse(tb, QCA_WLAN_VENDOR_ATTR_MAX, data, data_len,
6567 policy)) {
6568 hddLog(LOGE, FL("Invalid ATTR"));
6569 return -EINVAL;
6570 }
6571
6572 if (!tb[QCA_WLAN_VENDOR_ATTR_SETBAND_VALUE]) {
6573 hddLog(LOGE, FL("attr QCA_WLAN_VENDOR_ATTR_SETBAND_VALUE failed"));
6574 return -EINVAL;
6575 }
6576
Hanumantha Reddy Pothula1347e432015-08-05 09:53:44 +05306577 hdd_ctx->isSetBandByNL = TRUE;
6578 ret = hdd_setBand(dev,
Srinivas Dasari41d97c92015-07-29 13:09:39 +05306579 nla_get_u32(tb[QCA_WLAN_VENDOR_ATTR_SETBAND_VALUE]));
Hanumantha Reddy Pothula1347e432015-08-05 09:53:44 +05306580 hdd_ctx->isSetBandByNL = FALSE;
6581
6582 EXIT();
6583 return ret;
Srinivas Dasari41d97c92015-07-29 13:09:39 +05306584}
6585
6586/**
6587 * wlan_hdd_cfg80211_setband() - Wrapper to offload packets
6588 * @wiphy: wiphy structure pointer
6589 * @wdev: Wireless device structure pointer
6590 * @data: Pointer to the data received
6591 * @data_len: Length of @data
6592 *
6593 * Return: 0 on success; errno on failure
6594 */
6595static int wlan_hdd_cfg80211_setband(struct wiphy *wiphy,
6596 struct wireless_dev *wdev,
6597 const void *data,
6598 int data_len)
6599{
6600 int ret = 0;
6601
6602 vos_ssr_protect(__func__);
6603 ret = __wlan_hdd_cfg80211_setband(wiphy,
6604 wdev, data, data_len);
6605 vos_ssr_unprotect(__func__);
6606
6607 return ret;
6608}
6609
Srinivas Girigowda8bf64cb2015-09-30 19:50:09 +05306610#ifdef WLAN_FEATURE_OFFLOAD_PACKETS
6611/**
6612 * hdd_map_req_id_to_pattern_id() - map request id to pattern id
6613 * @hdd_ctx: HDD context
6614 * @request_id: [input] request id
6615 * @pattern_id: [output] pattern id
6616 *
6617 * This function loops through request id to pattern id array
6618 * if the slot is available, store the request id and return pattern id
6619 * if entry exists, return the pattern id
6620 *
6621 * Return: 0 on success and errno on failure
6622 */
6623static int hdd_map_req_id_to_pattern_id(hdd_context_t *hdd_ctx,
6624 uint32_t request_id,
6625 uint8_t *pattern_id)
6626{
6627 uint32_t i;
6628
6629 mutex_lock(&hdd_ctx->op_ctx.op_lock);
6630 for (i = 0; i < MAXNUM_PERIODIC_TX_PTRNS; i++)
6631 {
6632 if (hdd_ctx->op_ctx.op_table[i].request_id == 0)
6633 {
6634 hdd_ctx->op_ctx.op_table[i].request_id = request_id;
6635 *pattern_id = hdd_ctx->op_ctx.op_table[i].pattern_id;
6636 mutex_unlock(&hdd_ctx->op_ctx.op_lock);
6637 return 0;
6638 } else if (hdd_ctx->op_ctx.op_table[i].request_id ==
6639 request_id) {
6640 *pattern_id = hdd_ctx->op_ctx.op_table[i].pattern_id;
6641 mutex_unlock(&hdd_ctx->op_ctx.op_lock);
6642 return 0;
6643 }
6644 }
6645 mutex_unlock(&hdd_ctx->op_ctx.op_lock);
6646 return -EINVAL;
6647}
6648
6649/**
6650 * hdd_unmap_req_id_to_pattern_id() - unmap request id to pattern id
6651 * @hdd_ctx: HDD context
6652 * @request_id: [input] request id
6653 * @pattern_id: [output] pattern id
6654 *
6655 * This function loops through request id to pattern id array
6656 * reset request id to 0 (slot available again) and
6657 * return pattern id
6658 *
6659 * Return: 0 on success and errno on failure
6660 */
6661static int hdd_unmap_req_id_to_pattern_id(hdd_context_t *hdd_ctx,
6662 uint32_t request_id,
6663 uint8_t *pattern_id)
6664{
6665 uint32_t i;
6666
6667 mutex_lock(&hdd_ctx->op_ctx.op_lock);
6668 for (i = 0; i < MAXNUM_PERIODIC_TX_PTRNS; i++)
6669 {
6670 if (hdd_ctx->op_ctx.op_table[i].request_id == request_id)
6671 {
6672 hdd_ctx->op_ctx.op_table[i].request_id = 0;
6673 *pattern_id = hdd_ctx->op_ctx.op_table[i].pattern_id;
6674 mutex_unlock(&hdd_ctx->op_ctx.op_lock);
6675 return 0;
6676 }
6677 }
6678 mutex_unlock(&hdd_ctx->op_ctx.op_lock);
6679 return -EINVAL;
6680}
6681
6682
6683/*
6684 * define short names for the global vendor params
6685 * used by __wlan_hdd_cfg80211_offloaded_packets()
6686 */
6687#define PARAM_MAX QCA_WLAN_VENDOR_ATTR_OFFLOADED_PACKETS_MAX
6688#define PARAM_REQUEST_ID \
6689 QCA_WLAN_VENDOR_ATTR_OFFLOADED_PACKETS_REQUEST_ID
6690#define PARAM_CONTROL \
6691 QCA_WLAN_VENDOR_ATTR_OFFLOADED_PACKETS_SENDING_CONTROL
6692#define PARAM_IP_PACKET \
6693 QCA_WLAN_VENDOR_ATTR_OFFLOADED_PACKETS_IP_PACKET_DATA
6694#define PARAM_SRC_MAC_ADDR \
6695 QCA_WLAN_VENDOR_ATTR_OFFLOADED_PACKETS_SRC_MAC_ADDR
6696#define PARAM_DST_MAC_ADDR \
6697 QCA_WLAN_VENDOR_ATTR_OFFLOADED_PACKETS_DST_MAC_ADDR
6698#define PARAM_PERIOD QCA_WLAN_VENDOR_ATTR_OFFLOADED_PACKETS_PERIOD
6699
6700/**
6701 * wlan_hdd_add_tx_ptrn() - add tx pattern
6702 * @adapter: adapter pointer
6703 * @hdd_ctx: hdd context
6704 * @tb: nl attributes
6705 *
6706 * This function reads the NL attributes and forms a AddTxPtrn message
6707 * posts it to SME.
6708 *
6709 */
6710static int
6711wlan_hdd_add_tx_ptrn(hdd_adapter_t *adapter, hdd_context_t *hdd_ctx,
6712 struct nlattr **tb)
6713{
6714 struct sSirAddPeriodicTxPtrn *add_req;
6715 eHalStatus status;
6716 uint32_t request_id, ret, len;
6717 uint8_t pattern_id = 0;
6718 v_MACADDR_t dst_addr;
6719 uint16_t eth_type = htons(ETH_P_IP);
6720
6721 if (!hdd_connIsConnected(WLAN_HDD_GET_STATION_CTX_PTR(adapter)))
6722 {
6723 hddLog(LOGE, FL("Not in Connected state!"));
6724 return -ENOTSUPP;
6725 }
6726
6727 add_req = vos_mem_malloc(sizeof(*add_req));
6728 if (!add_req)
6729 {
6730 hddLog(LOGE, FL("memory allocation failed"));
6731 return -ENOMEM;
6732 }
6733
6734 /* Parse and fetch request Id */
6735 if (!tb[PARAM_REQUEST_ID])
6736 {
6737 hddLog(LOGE, FL("attr request id failed"));
6738 goto fail;
6739 }
6740
6741 request_id = nla_get_u32(tb[PARAM_REQUEST_ID]);
6742 hddLog(LOG1, FL("Request Id: %u"), request_id);
6743 if (request_id == 0)
6744 {
6745 hddLog(LOGE, FL("request_id cannot be zero"));
6746 return -EINVAL;
6747 }
6748
6749 if (!tb[PARAM_PERIOD])
6750 {
6751 hddLog(LOGE, FL("attr period failed"));
6752 goto fail;
6753 }
6754 add_req->usPtrnIntervalMs = nla_get_u32(tb[PARAM_PERIOD]);
6755 hddLog(LOG1, FL("Period: %u ms"), add_req->usPtrnIntervalMs);
6756 if (add_req->usPtrnIntervalMs == 0)
6757 {
6758 hddLog(LOGE, FL("Invalid interval zero, return failure"));
6759 goto fail;
6760 }
6761
6762 if (!tb[PARAM_SRC_MAC_ADDR])
6763 {
6764 hddLog(LOGE, FL("attr source mac address failed"));
6765 goto fail;
6766 }
6767 nla_memcpy(add_req->macAddress, tb[PARAM_SRC_MAC_ADDR],
6768 VOS_MAC_ADDR_SIZE);
6769 hddLog(LOG1, "input src mac address: "MAC_ADDRESS_STR,
6770 MAC_ADDR_ARRAY(add_req->macAddress));
6771
6772 if (memcmp(add_req->macAddress, adapter->macAddressCurrent.bytes,
6773 VOS_MAC_ADDR_SIZE))
6774 {
6775 hddLog(LOGE,
6776 FL("input src mac address and connected ap bssid are different"));
6777 goto fail;
6778 }
6779
6780 if (!tb[PARAM_DST_MAC_ADDR])
6781 {
6782 hddLog(LOGE, FL("attr dst mac address failed"));
6783 goto fail;
6784 }
6785 nla_memcpy(dst_addr.bytes, tb[PARAM_DST_MAC_ADDR], VOS_MAC_ADDR_SIZE);
6786 hddLog(LOG1, "input dst mac address: "MAC_ADDRESS_STR,
6787 MAC_ADDR_ARRAY(dst_addr.bytes));
6788
6789 if (!tb[PARAM_IP_PACKET])
6790 {
6791 hddLog(LOGE, FL("attr ip packet failed"));
6792 goto fail;
6793 }
6794 add_req->ucPtrnSize = nla_len(tb[PARAM_IP_PACKET]);
6795 hddLog(LOG1, FL("IP packet len: %u"), add_req->ucPtrnSize);
6796
6797 if (add_req->ucPtrnSize < 0 ||
6798 add_req->ucPtrnSize > (PERIODIC_TX_PTRN_MAX_SIZE -
6799 HDD_ETH_HEADER_LEN))
6800 {
6801 hddLog(LOGE, FL("Invalid IP packet len: %d"),
6802 add_req->ucPtrnSize);
6803 goto fail;
6804 }
6805
6806 len = 0;
6807 vos_mem_copy(&add_req->ucPattern[0], dst_addr.bytes, VOS_MAC_ADDR_SIZE);
6808 len += VOS_MAC_ADDR_SIZE;
6809 vos_mem_copy(&add_req->ucPattern[len], add_req->macAddress,
6810 VOS_MAC_ADDR_SIZE);
6811 len += VOS_MAC_ADDR_SIZE;
6812 vos_mem_copy(&add_req->ucPattern[len], &eth_type, 2);
6813 len += 2;
6814
6815 /*
6816 * This is the IP packet, add 14 bytes Ethernet (802.3) header
6817 * ------------------------------------------------------------
6818 * | 14 bytes Ethernet (802.3) header | IP header and payload |
6819 * ------------------------------------------------------------
6820 */
6821 vos_mem_copy(&add_req->ucPattern[len],
6822 nla_data(tb[PARAM_IP_PACKET]),
6823 add_req->ucPtrnSize);
6824 add_req->ucPtrnSize += len;
6825
6826 VOS_TRACE_HEX_DUMP(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
6827 add_req->ucPattern, add_req->ucPtrnSize);
6828
6829 ret = hdd_map_req_id_to_pattern_id(hdd_ctx, request_id, &pattern_id);
6830 if (ret)
6831 {
6832 hddLog(LOGW, FL("req id to pattern id failed (ret=%d)"), ret);
6833 goto fail;
6834 }
6835 add_req->ucPtrnId = pattern_id;
6836 hddLog(LOG1, FL("pattern id: %d"), add_req->ucPtrnId);
6837
6838 status = sme_AddPeriodicTxPtrn(hdd_ctx->hHal, add_req);
6839 if (!HAL_STATUS_SUCCESS(status))
6840 {
6841 hddLog(LOGE,
6842 FL("sme_AddPeriodicTxPtrn failed (err=%d)"), status);
6843 goto fail;
6844 }
6845
6846 EXIT();
6847 vos_mem_free(add_req);
6848 return 0;
6849
6850fail:
6851 vos_mem_free(add_req);
6852 return -EINVAL;
6853}
6854
6855/**
6856 * wlan_hdd_del_tx_ptrn() - delete tx pattern
6857 * @adapter: adapter pointer
6858 * @hdd_ctx: hdd context
6859 * @tb: nl attributes
6860 *
6861 * This function reads the NL attributes and forms a DelTxPtrn message
6862 * posts it to SME.
6863 *
6864 */
6865static int
6866wlan_hdd_del_tx_ptrn(hdd_adapter_t *adapter, hdd_context_t *hdd_ctx,
6867 struct nlattr **tb)
6868{
6869 struct sSirDelPeriodicTxPtrn *del_req;
6870 eHalStatus status;
6871 uint32_t request_id, ret;
6872 uint8_t pattern_id = 0;
6873
6874 /* Parse and fetch request Id */
6875 if (!tb[PARAM_REQUEST_ID])
6876 {
6877 hddLog(LOGE, FL("attr request id failed"));
6878 return -EINVAL;
6879 }
6880 request_id = nla_get_u32(tb[PARAM_REQUEST_ID]);
6881 if (request_id == 0)
6882 {
6883 hddLog(LOGE, FL("request_id cannot be zero"));
6884 return -EINVAL;
6885 }
6886
6887 ret = hdd_unmap_req_id_to_pattern_id(hdd_ctx, request_id, &pattern_id);
6888 if (ret)
6889 {
6890 hddLog(LOGW, FL("req id to pattern id failed (ret=%d)"), ret);
6891 return -EINVAL;
6892 }
6893
6894 del_req = vos_mem_malloc(sizeof(*del_req));
6895 if (!del_req)
6896 {
6897 hddLog(LOGE, FL("memory allocation failed"));
6898 return -ENOMEM;
6899 }
6900
6901 vos_mem_set(del_req, sizeof(*del_req), 0);
6902 vos_mem_copy(del_req->macAddress, adapter->macAddressCurrent.bytes,
6903 VOS_MAC_ADDR_SIZE);
6904 hddLog(LOG1, MAC_ADDRESS_STR, MAC_ADDR_ARRAY(del_req->macAddress));
6905 del_req->ucPatternIdBitmap |= (0x1 << pattern_id);
6906 hddLog(LOG1, FL("Request Id: %u Pattern id: %d, bitmap %04x"),
6907 request_id, pattern_id, del_req->ucPatternIdBitmap);
6908
6909 status = sme_DelPeriodicTxPtrn(hdd_ctx->hHal, del_req);
6910 if (!HAL_STATUS_SUCCESS(status))
6911 {
6912 hddLog(LOGE,
6913 FL("sme_DelPeriodicTxPtrn failed (err=%d)"), status);
6914 goto fail;
6915 }
6916
6917 EXIT();
6918 vos_mem_free(del_req);
6919 return 0;
6920
6921fail:
6922 vos_mem_free(del_req);
6923 return -EINVAL;
6924}
6925
6926
6927/**
6928 * __wlan_hdd_cfg80211_offloaded_packets() - send offloaded packets
6929 * @wiphy: Pointer to wireless phy
6930 * @wdev: Pointer to wireless device
6931 * @data: Pointer to data
6932 * @data_len: Data length
6933 *
6934 * Return: 0 on success, negative errno on failure
6935 */
6936static int
6937__wlan_hdd_cfg80211_offloaded_packets(struct wiphy *wiphy,
6938 struct wireless_dev *wdev,
6939 const void *data,
6940 int data_len)
6941{
6942 struct net_device *dev = wdev->netdev;
6943 hdd_adapter_t *adapter = WLAN_HDD_GET_PRIV_PTR(dev);
6944 hdd_context_t *hdd_ctx = wiphy_priv(wiphy);
6945 struct nlattr *tb[PARAM_MAX + 1];
6946 uint8_t control;
6947 int ret;
6948 static const struct nla_policy policy[PARAM_MAX + 1] =
6949 {
6950 [PARAM_REQUEST_ID] = { .type = NLA_U32 },
6951 [PARAM_CONTROL] = { .type = NLA_U32 },
6952 [PARAM_SRC_MAC_ADDR] = { .type = NLA_BINARY,
6953 .len = VOS_MAC_ADDR_SIZE },
6954 [PARAM_DST_MAC_ADDR] = { .type = NLA_BINARY,
6955 .len = VOS_MAC_ADDR_SIZE },
6956 [PARAM_PERIOD] = { .type = NLA_U32 },
6957 };
6958
6959 ENTER();
6960
6961 ret = wlan_hdd_validate_context(hdd_ctx);
6962 if (0 != ret)
6963 {
6964 hddLog(LOGE, FL("HDD context is not valid"));
6965 return ret;
6966 }
6967
6968 if (!sme_IsFeatureSupportedByFW(WLAN_PERIODIC_TX_PTRN))
6969 {
6970 hddLog(LOGE,
6971 FL("Periodic Tx Pattern Offload feature is not supported in FW!"));
6972 return -ENOTSUPP;
6973 }
6974
6975 if (nla_parse(tb, PARAM_MAX, data, data_len, policy))
6976 {
6977 hddLog(LOGE, FL("Invalid ATTR"));
6978 return -EINVAL;
6979 }
6980
6981 if (!tb[PARAM_CONTROL])
6982 {
6983 hddLog(LOGE, FL("attr control failed"));
6984 return -EINVAL;
6985 }
6986 control = nla_get_u32(tb[PARAM_CONTROL]);
6987 hddLog(LOG1, FL("Control: %d"), control);
6988
6989 if (control == WLAN_START_OFFLOADED_PACKETS)
6990 return wlan_hdd_add_tx_ptrn(adapter, hdd_ctx, tb);
6991 else if (control == WLAN_STOP_OFFLOADED_PACKETS)
6992 return wlan_hdd_del_tx_ptrn(adapter, hdd_ctx, tb);
6993 else
6994 {
6995 hddLog(LOGE, FL("Invalid control: %d"), control);
6996 return -EINVAL;
6997 }
6998}
6999
7000/*
7001 * done with short names for the global vendor params
7002 * used by __wlan_hdd_cfg80211_offloaded_packets()
7003 */
7004#undef PARAM_MAX
7005#undef PARAM_REQUEST_ID
7006#undef PARAM_CONTROL
7007#undef PARAM_IP_PACKET
7008#undef PARAM_SRC_MAC_ADDR
7009#undef PARAM_DST_MAC_ADDR
7010#undef PARAM_PERIOD
7011
7012/**
7013 * wlan_hdd_cfg80211_offloaded_packets() - Wrapper to offload packets
7014 * @wiphy: wiphy structure pointer
7015 * @wdev: Wireless device structure pointer
7016 * @data: Pointer to the data received
7017 * @data_len: Length of @data
7018 *
7019 * Return: 0 on success; errno on failure
7020 */
7021static int wlan_hdd_cfg80211_offloaded_packets(struct wiphy *wiphy,
7022 struct wireless_dev *wdev,
7023 const void *data,
7024 int data_len)
7025{
7026 int ret = 0;
7027
7028 vos_ssr_protect(__func__);
7029 ret = __wlan_hdd_cfg80211_offloaded_packets(wiphy,
7030 wdev, data, data_len);
7031 vos_ssr_unprotect(__func__);
7032
7033 return ret;
7034}
7035#endif
7036
Deepthi Gowriae6a1662015-10-12 12:59:37 +05307037static const struct
7038nla_policy
7039qca_wlan_vendor_attr_policy[QCA_WLAN_VENDOR_ATTR_MAX+1] = {
7040 [QCA_WLAN_VENDOR_ATTR_MAC_ADDR] = { .type = NLA_UNSPEC },
7041};
7042
7043/**
7044 * wlan_hdd_cfg80211_get_link_properties() - This function is used to
7045 * get link properties like nss, rate flags and operating frequency for
7046 * the connection with the given peer.
7047 * @wiphy: WIPHY structure pointer
7048 * @wdev: Wireless device structure pointer
7049 * @data: Pointer to the data received
7050 * @data_len: Length of the data received
7051 *
7052 * This function return the above link properties on success.
7053 *
7054 * Return: 0 on success and errno on failure
7055 */
7056static int wlan_hdd_cfg80211_get_link_properties(struct wiphy *wiphy,
7057 struct wireless_dev *wdev,
7058 const void *data,
7059 int data_len)
7060{
7061 hdd_context_t *hdd_ctx = wiphy_priv(wiphy);
7062 struct net_device *dev = wdev->netdev;
7063 hdd_adapter_t *adapter = WLAN_HDD_GET_PRIV_PTR(dev);
7064 hdd_station_ctx_t *hdd_sta_ctx;
7065 struct nlattr *tb[QCA_WLAN_VENDOR_ATTR_MAX+1];
7066 uint8_t peer_mac[VOS_MAC_ADDR_SIZE];
7067 uint32_t sta_id;
7068 struct sk_buff *reply_skb;
7069 uint32_t rate_flags = 0;
7070 uint8_t nss;
7071 uint8_t final_rate_flags = 0;
7072 uint32_t freq;
7073 v_CONTEXT_t pVosContext = NULL;
7074 ptSapContext pSapCtx = NULL;
7075
7076 if (0 != wlan_hdd_validate_context(hdd_ctx)) {
7077 hddLog(VOS_TRACE_LEVEL_ERROR, FL("HDD context is not valid"));
7078 return -EINVAL;
7079 }
7080
7081 if (nla_parse(tb, QCA_WLAN_VENDOR_ATTR_MAX, data, data_len,
7082 qca_wlan_vendor_attr_policy)) {
7083 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Invalid attribute"));
7084 return -EINVAL;
7085 }
7086
7087 if (!tb[QCA_WLAN_VENDOR_ATTR_MAC_ADDR]) {
7088 hddLog(VOS_TRACE_LEVEL_ERROR,
7089 FL("Attribute peerMac not provided for mode=%d"),
7090 adapter->device_mode);
7091 return -EINVAL;
7092 }
7093
7094 memcpy(peer_mac, nla_data(tb[QCA_WLAN_VENDOR_ATTR_MAC_ADDR]),
7095 sizeof(peer_mac));
7096 hddLog(VOS_TRACE_LEVEL_INFO,
7097 FL("peerMac="MAC_ADDRESS_STR" for device_mode:%d"),
7098 MAC_ADDR_ARRAY(peer_mac), adapter->device_mode);
7099
7100 if (adapter->device_mode == WLAN_HDD_INFRA_STATION ||
7101 adapter->device_mode == WLAN_HDD_P2P_CLIENT) {
7102 hdd_sta_ctx = WLAN_HDD_GET_STATION_CTX_PTR(adapter);
7103 if ((hdd_sta_ctx->conn_info.connState !=
7104 eConnectionState_Associated) ||
7105 !vos_mem_compare(hdd_sta_ctx->conn_info.bssId, peer_mac,
7106 VOS_MAC_ADDRESS_LEN)) {
7107 hddLog(VOS_TRACE_LEVEL_ERROR,
7108 FL("Not Associated to mac "MAC_ADDRESS_STR),
7109 MAC_ADDR_ARRAY(peer_mac));
7110 return -EINVAL;
7111 }
7112
7113 nss = 1; //pronto supports only one spatial stream
7114 freq = vos_chan_to_freq(
7115 hdd_sta_ctx->conn_info.operationChannel);
7116 rate_flags = hdd_sta_ctx->conn_info.rate_flags;
7117
7118 } else if (adapter->device_mode == WLAN_HDD_P2P_GO ||
7119 adapter->device_mode == WLAN_HDD_SOFTAP) {
7120
7121 pVosContext = ( WLAN_HDD_GET_CTX(adapter))->pvosContext;
7122 pSapCtx = VOS_GET_SAP_CB(pVosContext);
7123 if(pSapCtx == NULL){
7124 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
7125 FL("psapCtx is NULL"));
7126 return -ENOENT;
7127 }
7128
7129
7130 for (sta_id = 0; sta_id < WLAN_MAX_STA_COUNT; sta_id++) {
7131 if (pSapCtx->aStaInfo[sta_id].isUsed &&
7132 !vos_is_macaddr_broadcast(
7133 &pSapCtx->aStaInfo[sta_id].macAddrSTA) &&
7134 vos_mem_compare(
7135 &pSapCtx->aStaInfo[sta_id].macAddrSTA,
7136 peer_mac, VOS_MAC_ADDRESS_LEN))
7137 break;
7138 }
7139
7140 if (WLAN_MAX_STA_COUNT == sta_id) {
7141 hddLog(VOS_TRACE_LEVEL_ERROR,
7142 FL("No active peer with mac="MAC_ADDRESS_STR),
7143 MAC_ADDR_ARRAY(peer_mac));
7144 return -EINVAL;
7145 }
7146
7147 nss = 1; //pronto supports only one spatial stream
7148 freq = vos_chan_to_freq(
7149 (WLAN_HDD_GET_AP_CTX_PTR(adapter))->operatingChannel);
7150 rate_flags = pSapCtx->aStaInfo[sta_id].rate_flags;
7151 } else {
7152 hddLog(VOS_TRACE_LEVEL_ERROR,
7153 FL("Not Associated! with mac"MAC_ADDRESS_STR),
7154 MAC_ADDR_ARRAY(peer_mac));
7155 return -EINVAL;
7156 }
7157
7158 if (!(rate_flags & eHAL_TX_RATE_LEGACY)) {
7159 if (rate_flags & eHAL_TX_RATE_VHT80) {
7160 final_rate_flags |= RATE_INFO_FLAGS_VHT_MCS;
7161 final_rate_flags |= RATE_INFO_FLAGS_80_MHZ_WIDTH;
7162 } else if (rate_flags & eHAL_TX_RATE_VHT40) {
7163 final_rate_flags |= RATE_INFO_FLAGS_VHT_MCS;
7164 final_rate_flags |= RATE_INFO_FLAGS_40_MHZ_WIDTH;
7165 } else if (rate_flags & eHAL_TX_RATE_VHT20) {
7166 final_rate_flags |= RATE_INFO_FLAGS_VHT_MCS;
7167 } else if (rate_flags & (eHAL_TX_RATE_HT20 | eHAL_TX_RATE_HT40)) {
7168 final_rate_flags |= RATE_INFO_FLAGS_MCS;
7169 if (rate_flags & eHAL_TX_RATE_HT40)
7170 final_rate_flags |= RATE_INFO_FLAGS_40_MHZ_WIDTH;
7171 }
7172
7173 if (rate_flags & eHAL_TX_RATE_SGI) {
7174 if (!(final_rate_flags & RATE_INFO_FLAGS_VHT_MCS))
7175 final_rate_flags |= RATE_INFO_FLAGS_MCS;
7176 final_rate_flags |= RATE_INFO_FLAGS_SHORT_GI;
7177 }
7178 }
7179
7180 reply_skb = cfg80211_vendor_cmd_alloc_reply_skb(wiphy,
7181 sizeof(u8) + sizeof(u8) + sizeof(u32) + NLMSG_HDRLEN);
7182
7183 if (NULL == reply_skb) {
7184 hddLog(VOS_TRACE_LEVEL_ERROR,
7185 FL("getLinkProperties: skb alloc failed"));
7186 return -EINVAL;
7187 }
7188
7189 if (nla_put_u8(reply_skb,
7190 QCA_WLAN_VENDOR_ATTR_LINK_PROPERTIES_NSS,
7191 nss) ||
7192 nla_put_u8(reply_skb,
7193 QCA_WLAN_VENDOR_ATTR_LINK_PROPERTIES_RATE_FLAGS,
7194 final_rate_flags) ||
7195 nla_put_u32(reply_skb,
7196 QCA_WLAN_VENDOR_ATTR_LINK_PROPERTIES_FREQ,
7197 freq)) {
7198 hddLog(VOS_TRACE_LEVEL_ERROR, FL("nla_put failed"));
7199 kfree_skb(reply_skb);
7200 return -EINVAL;
7201 }
7202
7203 return cfg80211_vendor_cmd_reply(reply_skb);
7204}
7205
Arun Khandavalli7eeb1592015-10-19 21:36:57 +05307206#define PARAM_WIFICONFIG_MAX QCA_WLAN_VENDOR_ATTR_CONFIG_MAX
7207#define PARAM_MODULATED_DTIM QCA_WLAN_VENDOR_ATTR_CONFIG_MODULATED_DTIM
7208#define PARAM_STATS_AVG_FACTOR QCA_WLAN_VENDOR_ATTR_CONFIG_STATS_AVG_FACTOR
7209#define PARAM_GUARD_TIME QCA_WLAN_VENDOR_ATTR_CONFIG_GUARD_TIME
7210
7211/**
7212 * __wlan_hdd_cfg80211_wifi_configuration_set() - Wifi configuration
7213 * vendor command
7214 *
7215 * @wiphy: wiphy device pointer
7216 * @wdev: wireless device pointer
7217 * @data: Vendor command data buffer
7218 * @data_len: Buffer length
7219 *
7220 * Handles QCA_WLAN_VENDOR_ATTR_CONFIG_MAX.
7221 *
7222 * Return: EOK or other error codes.
7223 */
7224
7225static int __wlan_hdd_cfg80211_wifi_configuration_set(struct wiphy *wiphy,
7226 struct wireless_dev *wdev,
7227 const void *data,
7228 int data_len)
7229{
7230 struct net_device *dev = wdev->netdev;
7231 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
7232 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
7233 hdd_station_ctx_t *pHddStaCtx;
7234 struct nlattr *tb[PARAM_WIFICONFIG_MAX + 1];
7235 tpSetWifiConfigParams pReq;
7236 eHalStatus status;
7237 int ret_val;
7238 static const struct nla_policy policy[PARAM_WIFICONFIG_MAX + 1] = {
7239 [PARAM_STATS_AVG_FACTOR] = { .type = NLA_U16 },
7240 [PARAM_MODULATED_DTIM] = { .type = NLA_U32 },
7241 [PARAM_GUARD_TIME] = { .type = NLA_U32},
7242 };
7243
7244 ENTER();
7245
7246 if (VOS_FTM_MODE == hdd_get_conparam()) {
7247 hddLog(LOGE, FL("Command not allowed in FTM mode"));
7248 return -EINVAL;
7249 }
7250
7251 ret_val = wlan_hdd_validate_context(pHddCtx);
7252 if (ret_val) {
7253 return ret_val;
7254 }
7255
7256 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
7257
7258 if (!hdd_connIsConnected(WLAN_HDD_GET_STATION_CTX_PTR(pAdapter))) {
7259 hddLog(LOGE, FL("Not in Connected state!"));
7260 return -ENOTSUPP;
7261 }
7262
7263 if (nla_parse(tb, PARAM_WIFICONFIG_MAX, data, data_len, policy)) {
7264 hddLog(LOGE, FL("Invalid ATTR"));
7265 return -EINVAL;
7266 }
7267
7268 /* check the Wifi Capability */
7269 if ( (TRUE != pHddCtx->cfg_ini->fEnableWifiConfig) &&
7270 (TRUE != sme_IsFeatureSupportedByFW(WIFI_CONFIG)))
7271 {
7272 hddLog(VOS_TRACE_LEVEL_ERROR,
7273 FL("WIFICONFIG not supported by Firmware"));
7274 return -EINVAL;
7275 }
7276
7277 pReq = vos_mem_malloc(sizeof(tSetWifiConfigParams));
7278
7279 if (!pReq) {
7280 VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR,
7281 "%s: Not able to allocate memory for tSetWifiConfigParams",
7282 __func__);
7283 return eHAL_STATUS_E_MALLOC_FAILED;
7284 }
7285
7286 vos_mem_set(pReq, sizeof(tSetWifiConfigParams), 0);
7287
7288 pReq->sessionId = pAdapter->sessionId;
7289 vos_mem_copy( &pReq->bssId, pHddStaCtx->conn_info.bssId, WNI_CFG_BSSID_LEN);
7290
7291 if (tb[PARAM_MODULATED_DTIM]) {
7292 pReq->paramValue = nla_get_u32(
7293 tb[PARAM_MODULATED_DTIM]);
7294 hddLog(LOG1, FL("Modulated DTIM: pReq->paramValue:%d "),
7295 pReq->paramValue);
7296 pHddCtx->cfg_ini->fMaxLIModulatedDTIM = pReq->paramValue;
7297 hdd_set_pwrparams(pHddCtx);
7298 if (BMPS == pmcGetPmcState(pHddCtx->hHal)) {
7299 hddLog( LOG1, FL("WifiConfig: Requesting FullPower!"));
7300
7301 sme_RequestFullPower(WLAN_HDD_GET_HAL_CTX(pAdapter),
7302 iw_full_power_cbfn, pAdapter,
7303 eSME_FULL_PWR_NEEDED_BY_HDD);
7304 }
7305 else
7306 {
7307 hddLog( LOG1, FL("WifiConfig Not in BMPS state"));
7308 }
7309 }
7310
7311 if (tb[PARAM_STATS_AVG_FACTOR]) {
7312 pReq->paramType = WIFI_CONFIG_SET_AVG_STATS_FACTOR;
7313 pReq->paramValue = nla_get_u16(
7314 tb[PARAM_STATS_AVG_FACTOR]);
7315 hddLog(LOG1, FL("AVG_STATS_FACTOR pReq->paramType:%d,pReq->paramValue:%d "),
7316 pReq->paramType, pReq->paramValue);
7317 status = sme_set_wificonfig_params(pHddCtx->hHal, pReq);
7318
7319 if (eHAL_STATUS_SUCCESS != status)
7320 {
7321 vos_mem_free(pReq);
7322 pReq = NULL;
7323 ret_val = -EPERM;
7324 return ret_val;
7325 }
7326 }
7327
7328
7329 if (tb[PARAM_GUARD_TIME]) {
7330 pReq->paramType = WIFI_CONFIG_SET_GUARD_TIME;
7331 pReq->paramValue = nla_get_u32(
7332 tb[PARAM_GUARD_TIME]);
7333 hddLog(LOG1, FL("GUARD_TIME pReq->paramType:%d,pReq->paramValue:%d "),
7334 pReq->paramType, pReq->paramValue);
7335 status = sme_set_wificonfig_params(pHddCtx->hHal, pReq);
7336
7337 if (eHAL_STATUS_SUCCESS != status)
7338 {
7339 vos_mem_free(pReq);
7340 pReq = NULL;
7341 ret_val = -EPERM;
7342 return ret_val;
7343 }
7344
7345 }
7346
7347 EXIT();
7348 return ret_val;
7349}
7350
7351/**
7352 * wlan_hdd_cfg80211_wifi_configuration_set() - Wifi configuration
7353 * vendor command
7354 *
7355 * @wiphy: wiphy device pointer
7356 * @wdev: wireless device pointer
7357 * @data: Vendor command data buffer
7358 * @data_len: Buffer length
7359 *
7360 * Handles QCA_WLAN_VENDOR_ATTR_CONFIG_MAX.
7361 *
7362 * Return: EOK or other error codes.
7363 */
7364static int wlan_hdd_cfg80211_wifi_configuration_set(struct wiphy *wiphy,
7365 struct wireless_dev *wdev,
7366 const void *data,
7367 int data_len)
7368{
7369 int ret;
7370
7371 vos_ssr_protect(__func__);
7372 ret = __wlan_hdd_cfg80211_wifi_configuration_set(wiphy, wdev,
7373 data, data_len);
7374 vos_ssr_unprotect(__func__);
7375
7376 return ret;
7377}
Sunil Duttc69bccb2014-05-26 21:30:20 +05307378const struct wiphy_vendor_command hdd_wiphy_vendor_commands[] =
7379{
Mukul Sharma2a271632014-10-13 14:59:01 +05307380 {
7381 .info.vendor_id = QCA_NL80211_VENDOR_ID,
7382 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_ROAMING,
7383 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
7384 WIPHY_VENDOR_CMD_NEED_NETDEV |
7385 WIPHY_VENDOR_CMD_NEED_RUNNING,
Edhar, Mahesh Kumar59129f52015-01-14 14:26:04 +05307386 .doit = wlan_hdd_cfg80211_firmware_roaming
Mukul Sharma2a271632014-10-13 14:59:01 +05307387 },
Srinivas Dasari030bad32015-02-18 23:23:54 +05307388
7389 {
7390 .info.vendor_id = QCA_NL80211_VENDOR_ID,
7391 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_NAN,
7392 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
7393 WIPHY_VENDOR_CMD_NEED_NETDEV |
7394 WIPHY_VENDOR_CMD_NEED_RUNNING,
7395 .doit = wlan_hdd_cfg80211_nan_request
7396 },
7397
Sunil Duttc69bccb2014-05-26 21:30:20 +05307398#ifdef WLAN_FEATURE_LINK_LAYER_STATS
7399 {
7400 .info.vendor_id = QCA_NL80211_VENDOR_ID,
7401 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_LL_STATS_CLR,
7402 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
7403 WIPHY_VENDOR_CMD_NEED_NETDEV |
7404 WIPHY_VENDOR_CMD_NEED_RUNNING,
Edhar, Mahesh Kumar59129f52015-01-14 14:26:04 +05307405 .doit = wlan_hdd_cfg80211_ll_stats_clear
Sunil Duttc69bccb2014-05-26 21:30:20 +05307406 },
7407
7408 {
7409 .info.vendor_id = QCA_NL80211_VENDOR_ID,
7410 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_LL_STATS_SET,
7411 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
7412 WIPHY_VENDOR_CMD_NEED_NETDEV |
7413 WIPHY_VENDOR_CMD_NEED_RUNNING,
Edhar, Mahesh Kumar59129f52015-01-14 14:26:04 +05307414 .doit = wlan_hdd_cfg80211_ll_stats_set
Sunil Duttc69bccb2014-05-26 21:30:20 +05307415 },
7416
7417 {
7418 .info.vendor_id = QCA_NL80211_VENDOR_ID,
7419 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_LL_STATS_GET,
7420 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
7421 WIPHY_VENDOR_CMD_NEED_NETDEV |
7422 WIPHY_VENDOR_CMD_NEED_RUNNING,
Edhar, Mahesh Kumar59129f52015-01-14 14:26:04 +05307423 .doit = wlan_hdd_cfg80211_ll_stats_get
Dino Mycle6fb96c12014-06-10 11:52:40 +05307424 },
Sunil Duttc69bccb2014-05-26 21:30:20 +05307425#endif /* WLAN_FEATURE_LINK_LAYER_STATS */
Dino Mycle6fb96c12014-06-10 11:52:40 +05307426#ifdef WLAN_FEATURE_EXTSCAN
7427 {
7428 .info.vendor_id = QCA_NL80211_VENDOR_ID,
7429 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_START,
7430 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
7431 WIPHY_VENDOR_CMD_NEED_NETDEV |
7432 WIPHY_VENDOR_CMD_NEED_RUNNING,
Edhar, Mahesh Kumar59129f52015-01-14 14:26:04 +05307433 .doit = wlan_hdd_cfg80211_extscan_start
Dino Mycle6fb96c12014-06-10 11:52:40 +05307434 },
7435 {
7436 .info.vendor_id = QCA_NL80211_VENDOR_ID,
7437 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_STOP,
7438 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
7439 WIPHY_VENDOR_CMD_NEED_NETDEV |
7440 WIPHY_VENDOR_CMD_NEED_RUNNING,
Edhar, Mahesh Kumar59129f52015-01-14 14:26:04 +05307441 .doit = wlan_hdd_cfg80211_extscan_stop
Dino Mycle6fb96c12014-06-10 11:52:40 +05307442 },
7443 {
7444 .info.vendor_id = QCA_NL80211_VENDOR_ID,
7445 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_GET_VALID_CHANNELS,
7446 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
7447 WIPHY_VENDOR_CMD_NEED_NETDEV,
Edhar, Mahesh Kumar59129f52015-01-14 14:26:04 +05307448 .doit = wlan_hdd_cfg80211_extscan_get_valid_channels
Dino Mycle6fb96c12014-06-10 11:52:40 +05307449 },
7450 {
7451 .info.vendor_id = QCA_NL80211_VENDOR_ID,
7452 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_GET_CAPABILITIES,
7453 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
7454 WIPHY_VENDOR_CMD_NEED_NETDEV |
7455 WIPHY_VENDOR_CMD_NEED_RUNNING,
Edhar, Mahesh Kumar59129f52015-01-14 14:26:04 +05307456 .doit = wlan_hdd_cfg80211_extscan_get_capabilities
Dino Mycle6fb96c12014-06-10 11:52:40 +05307457 },
7458 {
7459 .info.vendor_id = QCA_NL80211_VENDOR_ID,
7460 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_GET_CACHED_RESULTS,
7461 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
7462 WIPHY_VENDOR_CMD_NEED_NETDEV |
7463 WIPHY_VENDOR_CMD_NEED_RUNNING,
Edhar, Mahesh Kumar59129f52015-01-14 14:26:04 +05307464 .doit = wlan_hdd_cfg80211_extscan_get_cached_results
Dino Mycle6fb96c12014-06-10 11:52:40 +05307465 },
7466 {
7467 .info.vendor_id = QCA_NL80211_VENDOR_ID,
7468 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_SET_BSSID_HOTLIST,
7469 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
7470 WIPHY_VENDOR_CMD_NEED_NETDEV |
7471 WIPHY_VENDOR_CMD_NEED_RUNNING,
Edhar, Mahesh Kumar59129f52015-01-14 14:26:04 +05307472 .doit = wlan_hdd_cfg80211_extscan_set_bssid_hotlist
Dino Mycle6fb96c12014-06-10 11:52:40 +05307473 },
7474 {
7475 .info.vendor_id = QCA_NL80211_VENDOR_ID,
7476 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_RESET_BSSID_HOTLIST,
7477 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
7478 WIPHY_VENDOR_CMD_NEED_NETDEV |
7479 WIPHY_VENDOR_CMD_NEED_RUNNING,
Edhar, Mahesh Kumar59129f52015-01-14 14:26:04 +05307480 .doit = wlan_hdd_cfg80211_extscan_reset_bssid_hotlist
Dino Mycle6fb96c12014-06-10 11:52:40 +05307481 },
Padma, Santhosh Kumar9acee012015-08-21 19:58:01 +05307482 {
7483 .info.vendor_id = QCA_NL80211_VENDOR_ID,
7484 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_SET_SSID_HOTLIST,
7485 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
7486 WIPHY_VENDOR_CMD_NEED_NETDEV |
7487 WIPHY_VENDOR_CMD_NEED_RUNNING,
7488 .doit = wlan_hdd_cfg80211_extscan_set_ssid_hotlist
7489 },
7490 {
7491 .info.vendor_id = QCA_NL80211_VENDOR_ID,
7492 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_RESET_SSID_HOTLIST,
7493 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
7494 WIPHY_VENDOR_CMD_NEED_NETDEV |
7495 WIPHY_VENDOR_CMD_NEED_RUNNING,
7496 .doit = wlan_hdd_cfg80211_extscan_reset_ssid_hotlist
7497 },
Dino Mycle6fb96c12014-06-10 11:52:40 +05307498#endif /* WLAN_FEATURE_EXTSCAN */
Atul Mittal115287b2014-07-08 13:26:33 +05307499/*EXT TDLS*/
7500 {
7501 .info.vendor_id = QCA_NL80211_VENDOR_ID,
7502 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_TDLS_ENABLE,
7503 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
7504 WIPHY_VENDOR_CMD_NEED_NETDEV |
7505 WIPHY_VENDOR_CMD_NEED_RUNNING,
Edhar, Mahesh Kumar59129f52015-01-14 14:26:04 +05307506 .doit = wlan_hdd_cfg80211_exttdls_enable
Atul Mittal115287b2014-07-08 13:26:33 +05307507 },
7508 {
7509 .info.vendor_id = QCA_NL80211_VENDOR_ID,
7510 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_TDLS_DISABLE,
7511 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
7512 WIPHY_VENDOR_CMD_NEED_NETDEV |
7513 WIPHY_VENDOR_CMD_NEED_RUNNING,
Edhar, Mahesh Kumar59129f52015-01-14 14:26:04 +05307514 .doit = wlan_hdd_cfg80211_exttdls_disable
Atul Mittal115287b2014-07-08 13:26:33 +05307515 },
7516 {
7517 .info.vendor_id = QCA_NL80211_VENDOR_ID,
7518 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_TDLS_GET_STATUS,
7519 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
7520 WIPHY_VENDOR_CMD_NEED_NETDEV,
Edhar, Mahesh Kumar59129f52015-01-14 14:26:04 +05307521 .doit = wlan_hdd_cfg80211_exttdls_get_status
Atul Mittal115287b2014-07-08 13:26:33 +05307522 },
Dasari Srinivas7875a302014-09-26 17:50:57 +05307523 {
7524 .info.vendor_id = QCA_NL80211_VENDOR_ID,
7525 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_GET_SUPPORTED_FEATURES,
7526 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
7527 WIPHY_VENDOR_CMD_NEED_NETDEV,
Edhar, Mahesh Kumar59129f52015-01-14 14:26:04 +05307528 .doit = wlan_hdd_cfg80211_get_supported_features
Dasari Srinivas7875a302014-09-26 17:50:57 +05307529 },
Agarwal Ashish738843c2014-09-25 12:27:56 +05307530 {
7531 .info.vendor_id = QCA_NL80211_VENDOR_ID,
7532 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_NO_DFS_FLAG,
7533 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
7534 WIPHY_VENDOR_CMD_NEED_NETDEV,
Edhar, Mahesh Kumar59129f52015-01-14 14:26:04 +05307535 .doit = wlan_hdd_cfg80211_disable_dfs_channels
Agarwal Ashish738843c2014-09-25 12:27:56 +05307536 },
Siddharth Bhala3a5cb42014-09-29 21:13:13 +05307537 {
7538 .info.vendor_id = QCA_NL80211_VENDOR_ID,
7539 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_MAC_OUI,
7540 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
7541 WIPHY_VENDOR_CMD_NEED_NETDEV,
Edhar, Mahesh Kumar59129f52015-01-14 14:26:04 +05307542 .doit = wlan_hdd_cfg80211_set_spoofed_mac_oui
Siddharth Bhala3a5cb42014-09-29 21:13:13 +05307543 },
Dasari Srinivase18b2cf2014-10-28 17:09:42 +05307544 {
7545 .info.vendor_id = QCA_NL80211_VENDOR_ID,
7546 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_GET_CONCURRENCY_MATRIX,
7547 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
7548 WIPHY_VENDOR_CMD_NEED_NETDEV,
Edhar, Mahesh Kumar59129f52015-01-14 14:26:04 +05307549 .doit = wlan_hdd_cfg80211_get_concurrency_matrix
Dasari Srinivase18b2cf2014-10-28 17:09:42 +05307550 },
Srinivas Dasari41d97c92015-07-29 13:09:39 +05307551 {
7552 .info.vendor_id = QCA_NL80211_VENDOR_ID,
c_manjeecfd1efb2015-09-25 19:32:34 +05307553 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_WIFI_LOGGER_MEMORY_DUMP,
7554 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
7555 WIPHY_VENDOR_CMD_NEED_NETDEV |
7556 WIPHY_VENDOR_CMD_NEED_RUNNING,
7557 .doit = wlan_hdd_cfg80211_get_fw_mem_dump
7558 },
7559 {
7560 .info.vendor_id = QCA_NL80211_VENDOR_ID,
Srinivas Dasari41d97c92015-07-29 13:09:39 +05307561 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_SETBAND,
7562 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
7563 WIPHY_VENDOR_CMD_NEED_NETDEV |
7564 WIPHY_VENDOR_CMD_NEED_RUNNING,
7565 .doit = wlan_hdd_cfg80211_setband
Sushant Kaushik8e644982015-09-23 12:18:54 +05307566 },
7567 {
7568 .info.vendor_id = QCA_NL80211_VENDOR_ID,
7569 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_WIFI_LOGGER_START,
7570 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
7571 WIPHY_VENDOR_CMD_NEED_NETDEV,
7572 .doit = wlan_hdd_cfg80211_wifi_logger_start
7573 },
Sushant Kaushik847890c2015-09-28 16:05:17 +05307574 {
7575 .info.vendor_id = QCA_NL80211_VENDOR_ID,
7576 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_GET_WIFI_INFO,
7577 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
7578 WIPHY_VENDOR_CMD_NEED_NETDEV|
7579 WIPHY_VENDOR_CMD_NEED_RUNNING,
7580 .doit = wlan_hdd_cfg80211_get_wifi_info
Sachin Ahujac08f72a2015-09-22 15:25:47 +05307581 },
7582 {
7583 .info.vendor_id = QCA_NL80211_VENDOR_ID,
7584 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_GET_RING_DATA,
7585 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
7586 WIPHY_VENDOR_CMD_NEED_NETDEV |
7587 WIPHY_VENDOR_CMD_NEED_RUNNING,
7588 .doit = wlan_hdd_cfg80211_wifi_logger_get_ring_data
Gupta, Kapil7c34b322015-09-30 13:12:35 +05307589 },
7590 {
7591 .info.vendor_id = QCA_NL80211_VENDOR_ID,
7592 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_MONITOR_RSSI,
7593 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
7594 WIPHY_VENDOR_CMD_NEED_NETDEV |
7595 WIPHY_VENDOR_CMD_NEED_RUNNING,
7596 .doit = wlan_hdd_cfg80211_monitor_rssi
Srinivas Girigowda8bf64cb2015-09-30 19:50:09 +05307597 },
7598#ifdef WLAN_FEATURE_OFFLOAD_PACKETS
7599 {
7600 .info.vendor_id = QCA_NL80211_VENDOR_ID,
7601 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_OFFLOADED_PACKETS,
7602 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
7603 WIPHY_VENDOR_CMD_NEED_NETDEV |
7604 WIPHY_VENDOR_CMD_NEED_RUNNING,
7605 .doit = wlan_hdd_cfg80211_offloaded_packets
Deepthi Gowriae6a1662015-10-12 12:59:37 +05307606 },
Srinivas Girigowda8bf64cb2015-09-30 19:50:09 +05307607#endif
Deepthi Gowriae6a1662015-10-12 12:59:37 +05307608 {
7609 .info.vendor_id = QCA_NL80211_VENDOR_ID,
7610 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_LINK_PROPERTIES,
7611 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
7612 WIPHY_VENDOR_CMD_NEED_NETDEV |
7613 WIPHY_VENDOR_CMD_NEED_RUNNING,
7614 .doit = wlan_hdd_cfg80211_get_link_properties
Arun Khandavalli7eeb1592015-10-19 21:36:57 +05307615 },
7616 {
7617 .info.vendor_id = QCA_NL80211_VENDOR_ID,
7618 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_SET_WIFI_CONFIGURATION,
7619 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
7620 WIPHY_VENDOR_CMD_NEED_NETDEV |
7621 WIPHY_VENDOR_CMD_NEED_RUNNING,
7622 .doit = wlan_hdd_cfg80211_wifi_configuration_set
Deepthi Gowriae6a1662015-10-12 12:59:37 +05307623 }
Sunil Duttc69bccb2014-05-26 21:30:20 +05307624};
7625
Rajesh Chauhan98a31f82014-01-06 20:15:25 -08007626/* vendor specific events */
Sunil Duttc69bccb2014-05-26 21:30:20 +05307627static const
7628struct nl80211_vendor_cmd_info wlan_hdd_cfg80211_vendor_events[] =
Rajesh Chauhan98a31f82014-01-06 20:15:25 -08007629{
7630#ifdef FEATURE_WLAN_CH_AVOID
7631 {
Sunil Duttc69bccb2014-05-26 21:30:20 +05307632 .vendor_id = QCA_NL80211_VENDOR_ID,
7633 .subcmd = QCA_NL80211_VENDOR_SUBCMD_AVOID_FREQUENCY
Rajesh Chauhan98a31f82014-01-06 20:15:25 -08007634 },
Sunil Duttc69bccb2014-05-26 21:30:20 +05307635#endif /* FEATURE_WLAN_CH_AVOID Index = 0*/
7636#ifdef WLAN_FEATURE_LINK_LAYER_STATS
7637 {
7638 /* Index = 1*/
7639 .vendor_id = QCA_NL80211_VENDOR_ID,
7640 .subcmd = QCA_NL80211_VENDOR_SUBCMD_LL_STATS_SET
7641 },
7642 {
7643 /* Index = 2*/
7644 .vendor_id = QCA_NL80211_VENDOR_ID,
7645 .subcmd = QCA_NL80211_VENDOR_SUBCMD_LL_STATS_GET
7646 },
7647 {
7648 /* Index = 3*/
7649 .vendor_id = QCA_NL80211_VENDOR_ID,
7650 .subcmd = QCA_NL80211_VENDOR_SUBCMD_LL_STATS_CLR
7651 },
7652 {
7653 /* Index = 4*/
7654 .vendor_id = QCA_NL80211_VENDOR_ID,
7655 .subcmd = QCA_NL80211_VENDOR_SUBCMD_LL_STATS_RADIO_RESULTS
7656 },
7657 {
7658 /* Index = 5*/
7659 .vendor_id = QCA_NL80211_VENDOR_ID,
7660 .subcmd = QCA_NL80211_VENDOR_SUBCMD_LL_STATS_IFACE_RESULTS
7661 },
7662 {
7663 /* Index = 6*/
7664 .vendor_id = QCA_NL80211_VENDOR_ID,
7665 .subcmd = QCA_NL80211_VENDOR_SUBCMD_LL_STATS_PEERS_RESULTS
7666 },
7667#endif /* WLAN_FEATURE_LINK_LAYER_STATS */
Dino Mycle6fb96c12014-06-10 11:52:40 +05307668#ifdef WLAN_FEATURE_EXTSCAN
7669 {
7670 .vendor_id = QCA_NL80211_VENDOR_ID,
7671 .subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_START
7672 },
7673 {
7674 .vendor_id = QCA_NL80211_VENDOR_ID,
7675 .subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_STOP
7676 },
7677 {
7678 .vendor_id = QCA_NL80211_VENDOR_ID,
7679 .subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_GET_CAPABILITIES
7680 },
7681 {
7682 .vendor_id = QCA_NL80211_VENDOR_ID,
7683 .subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_GET_CACHED_RESULTS
7684 },
7685 {
7686 .vendor_id = QCA_NL80211_VENDOR_ID,
7687 .subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_SCAN_RESULTS_AVAILABLE
7688 },
7689 {
7690 .vendor_id = QCA_NL80211_VENDOR_ID,
7691 .subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_FULL_SCAN_RESULT
7692 },
7693 {
7694 .vendor_id = QCA_NL80211_VENDOR_ID,
7695 .subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_SCAN_EVENT
7696 },
7697 {
7698 .vendor_id = QCA_NL80211_VENDOR_ID,
7699 .subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_HOTLIST_AP_FOUND
7700 },
7701 {
7702 .vendor_id = QCA_NL80211_VENDOR_ID,
7703 .subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_SET_BSSID_HOTLIST
7704 },
7705 {
7706 .vendor_id = QCA_NL80211_VENDOR_ID,
7707 .subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_RESET_BSSID_HOTLIST
7708 },
Padma, Santhosh Kumar9acee012015-08-21 19:58:01 +05307709 {
7710 .vendor_id = QCA_NL80211_VENDOR_ID,
7711 .subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_SET_SSID_HOTLIST
7712 },
7713 {
7714 .vendor_id = QCA_NL80211_VENDOR_ID,
7715 .subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_RESET_SSID_HOTLIST
7716 },
7717 [QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_HOTLIST_SSID_FOUND_INDEX] = {
7718 .vendor_id = QCA_NL80211_VENDOR_ID,
7719 .subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_HOTLIST_SSID_FOUND
7720 },
7721 [QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_HOTLIST_SSID_LOST_INDEX] = {
7722 .vendor_id = QCA_NL80211_VENDOR_ID,
7723 .subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_HOTLIST_SSID_LOST
7724 },
Dino Mycle6fb96c12014-06-10 11:52:40 +05307725#endif /* WLAN_FEATURE_EXTSCAN */
Atul Mittal115287b2014-07-08 13:26:33 +05307726/*EXT TDLS*/
7727 {
7728 .vendor_id = QCA_NL80211_VENDOR_ID,
7729 .subcmd = QCA_NL80211_VENDOR_SUBCMD_TDLS_STATE
7730 },
c_manjeecfd1efb2015-09-25 19:32:34 +05307731 [QCA_NL80211_VENDOR_SUBCMD_WIFI_LOGGER_MEMORY_DUMP_INDEX] = {
7732 .vendor_id = QCA_NL80211_VENDOR_ID,
7733 .subcmd = QCA_NL80211_VENDOR_SUBCMD_WIFI_LOGGER_MEMORY_DUMP
7734 },
7735
Srinivas Dasari030bad32015-02-18 23:23:54 +05307736
7737 {
7738 .vendor_id = QCA_NL80211_VENDOR_ID,
7739 .subcmd = QCA_NL80211_VENDOR_SUBCMD_NAN
7740 },
7741
Sushant Kaushik084f6592015-09-10 13:11:56 +05307742 {
7743 .vendor_id = QCA_NL80211_VENDOR_ID,
7744 .subcmd = QCA_NL80211_VENDOR_SUBCMD_GET_WIFI_INFO,
Gupta, Kapil7c34b322015-09-30 13:12:35 +05307745 },
7746 [QCA_NL80211_VENDOR_SUBCMD_MONITOR_RSSI_INDEX] = {
7747 .vendor_id = QCA_NL80211_VENDOR_ID,
7748 .subcmd = QCA_NL80211_VENDOR_SUBCMD_MONITOR_RSSI
7749 },
Sushant Kaushik084f6592015-09-10 13:11:56 +05307750
Rajesh Chauhan98a31f82014-01-06 20:15:25 -08007751};
7752
Jeff Johnson295189b2012-06-20 16:38:30 -07007753/*
Madan Mohan Koyyalamudi71278262013-04-12 22:00:48 +05307754 * FUNCTION: wlan_hdd_cfg80211_wiphy_alloc
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307755 * This function is called by hdd_wlan_startup()
7756 * during initialization.
Madan Mohan Koyyalamudi71278262013-04-12 22:00:48 +05307757 * This function is used to allocate wiphy structure.
Jeff Johnson295189b2012-06-20 16:38:30 -07007758 */
Madan Mohan Koyyalamudi71278262013-04-12 22:00:48 +05307759struct wiphy *wlan_hdd_cfg80211_wiphy_alloc(int priv_size)
Jeff Johnson295189b2012-06-20 16:38:30 -07007760{
7761 struct wiphy *wiphy;
7762 ENTER();
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307763 /*
7764 * Create wiphy device
Jeff Johnson295189b2012-06-20 16:38:30 -07007765 */
7766 wiphy = wiphy_new(&wlan_hdd_cfg80211_ops, priv_size);
7767
7768 if (!wiphy)
7769 {
7770 /* Print error and jump into err label and free the memory */
7771 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: wiphy init failed", __func__);
7772 return NULL;
7773 }
7774
Sunil Duttc69bccb2014-05-26 21:30:20 +05307775
Jeff Johnson295189b2012-06-20 16:38:30 -07007776 return wiphy;
7777}
7778
7779/*
7780 * FUNCTION: wlan_hdd_cfg80211_update_band
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307781 * This function is called from the supplicant through a
Jeff Johnson295189b2012-06-20 16:38:30 -07007782 * private ioctl to change the band value
7783 */
7784int wlan_hdd_cfg80211_update_band(struct wiphy *wiphy, eCsrBand eBand)
7785{
Gopichand Nakkala1f7a64f2013-04-01 18:37:17 +05307786 int i, j;
7787 eNVChannelEnabledType channelEnabledState;
7788
Jeff Johnsone7245742012-09-05 17:12:55 -07007789 ENTER();
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05307790
Gopichand Nakkala1f7a64f2013-04-01 18:37:17 +05307791 for (i = 0; i < IEEE80211_NUM_BANDS; i++)
Jeff Johnson295189b2012-06-20 16:38:30 -07007792 {
Gopichand Nakkala1f7a64f2013-04-01 18:37:17 +05307793
7794 if (NULL == wiphy->bands[i])
7795 {
7796 hddLog(VOS_TRACE_LEVEL_ERROR,"%s: wiphy->bands[i] is NULL, i = %d",
7797 __func__, i);
7798 continue;
7799 }
7800
7801 for (j = 0; j < wiphy->bands[i]->n_channels; j++)
7802 {
7803 struct ieee80211_supported_band *band = wiphy->bands[i];
7804
7805 channelEnabledState = vos_nv_getChannelEnabledState(
7806 band->channels[j].hw_value);
7807
7808 if (IEEE80211_BAND_2GHZ == i && eCSR_BAND_5G == eBand) // 5G only
7809 {
Abhishek Singh678227a2014-11-04 10:52:38 +05307810 band->channels[j].flags |= IEEE80211_CHAN_DISABLED;
Gopichand Nakkala1f7a64f2013-04-01 18:37:17 +05307811 continue;
7812 }
7813 else if (IEEE80211_BAND_5GHZ == i && eCSR_BAND_24 == eBand) // 2G only
7814 {
7815 band->channels[j].flags |= IEEE80211_CHAN_DISABLED;
7816 continue;
7817 }
7818
7819 if (NV_CHANNEL_DISABLE == channelEnabledState ||
7820 NV_CHANNEL_INVALID == channelEnabledState)
7821 {
7822 band->channels[j].flags |= IEEE80211_CHAN_DISABLED;
7823 }
7824 else if (NV_CHANNEL_DFS == channelEnabledState)
7825 {
7826 band->channels[j].flags &= ~IEEE80211_CHAN_DISABLED;
7827 band->channels[j].flags |= IEEE80211_CHAN_RADAR;
7828 }
7829 else
7830 {
7831 band->channels[j].flags &= ~(IEEE80211_CHAN_DISABLED
7832 |IEEE80211_CHAN_RADAR);
7833 }
7834 }
Jeff Johnson295189b2012-06-20 16:38:30 -07007835 }
7836 return 0;
7837}
7838/*
7839 * FUNCTION: wlan_hdd_cfg80211_init
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307840 * This function is called by hdd_wlan_startup()
7841 * during initialization.
Jeff Johnson295189b2012-06-20 16:38:30 -07007842 * This function is used to initialize and register wiphy structure.
7843 */
Madan Mohan Koyyalamudi71278262013-04-12 22:00:48 +05307844int wlan_hdd_cfg80211_init(struct device *dev,
Jeff Johnson295189b2012-06-20 16:38:30 -07007845 struct wiphy *wiphy,
7846 hdd_config_t *pCfg
7847 )
7848{
Gopichand Nakkala1f7a64f2013-04-01 18:37:17 +05307849 int i, j;
Vinay Krishna Erannafacf5e22014-02-24 13:16:25 +05307850 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
7851
Jeff Johnsone7245742012-09-05 17:12:55 -07007852 ENTER();
7853
Jeff Johnson295189b2012-06-20 16:38:30 -07007854 /* Now bind the underlying wlan device with wiphy */
7855 set_wiphy_dev(wiphy, dev);
7856
7857 wiphy->mgmt_stypes = wlan_hdd_txrx_stypes;
Amar Singhalfddc28c2013-09-05 13:03:40 -07007858
Kiet Lam6c583332013-10-14 05:37:09 +05307859#ifndef CONFIG_ENABLE_LINUX_REG
Amar Singhal0a402232013-10-11 20:57:16 -07007860 /* the flag for the other case would be initialzed in
7861 vos_init_wiphy_from_nv_bin */
Amar Singhal0a402232013-10-11 20:57:16 -07007862 wiphy->flags |= WIPHY_FLAG_STRICT_REGULATORY;
Kiet Lam6c583332013-10-14 05:37:09 +05307863#endif
Amar Singhala49cbc52013-10-08 18:37:44 -07007864
Amar Singhalfddc28c2013-09-05 13:03:40 -07007865 /* This will disable updating of NL channels from passive to
7866 * active if a beacon is received on passive channel. */
Anand N Sunkade9adb1b2015-07-29 09:56:45 +05307867#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,14,0))
7868 wiphy->regulatory_flags |= REGULATORY_DISABLE_BEACON_HINTS;
7869#else
Amar Singhalfddc28c2013-09-05 13:03:40 -07007870 wiphy->flags |= WIPHY_FLAG_DISABLE_BEACON_HINTS;
Anand N Sunkade9adb1b2015-07-29 09:56:45 +05307871#endif
Amar Singhalfddc28c2013-09-05 13:03:40 -07007872
Amar Singhala49cbc52013-10-08 18:37:44 -07007873
Jeff Johnson04dd8a82012-06-29 20:41:40 -07007874#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,4,0))
Madan Mohan Koyyalamudi1b4afb02012-10-22 15:25:16 -07007875 wiphy->flags |= WIPHY_FLAG_HAVE_AP_SME
7876 | WIPHY_FLAG_AP_PROBE_RESP_OFFLOAD
7877 | WIPHY_FLAG_HAS_REMAIN_ON_CHANNEL
Jeff Johnsone7245742012-09-05 17:12:55 -07007878 | WIPHY_FLAG_OFFCHAN_TX;
Anand N Sunkade9adb1b2015-07-29 09:56:45 +05307879#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,14,0))
7880 wiphy->regulatory_flags = REGULATORY_COUNTRY_IE_IGNORE;
7881#else
7882 wiphy->country_ie_pref = NL80211_COUNTRY_IE_IGNORE_CORE;
7883#endif
Jeff Johnson04dd8a82012-06-29 20:41:40 -07007884#endif
Amar Singhala49cbc52013-10-08 18:37:44 -07007885
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08007886#if defined (WLAN_FEATURE_VOWIFI_11R) || defined (FEATURE_WLAN_ESE) || defined(FEATURE_WLAN_LFR)
Srinivas Girigowda640728a2013-03-28 12:21:54 -07007887 if (pCfg->isFastTransitionEnabled
James Zmuda77fb5ae2013-01-29 08:00:17 -08007888#ifdef FEATURE_WLAN_LFR
Srinivas Girigowda640728a2013-03-28 12:21:54 -07007889 || pCfg->isFastRoamIniFeatureEnabled
7890#endif
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08007891#ifdef FEATURE_WLAN_ESE
7892 || pCfg->isEseIniFeatureEnabled
Srinivas Girigowda640728a2013-03-28 12:21:54 -07007893#endif
7894 )
7895 {
7896 wiphy->flags |= WIPHY_FLAG_SUPPORTS_FW_ROAM;
7897 }
James Zmuda77fb5ae2013-01-29 08:00:17 -08007898#endif
Mohit Khanna698ba2a2012-12-04 15:08:18 -08007899#ifdef FEATURE_WLAN_TDLS
7900 wiphy->flags |= WIPHY_FLAG_SUPPORTS_TDLS
7901 | WIPHY_FLAG_TDLS_EXTERNAL_SETUP;
7902#endif
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +05307903#ifdef FEATURE_WLAN_SCAN_PNO
Hardik Kantilal Patel3dfd8792013-11-13 20:34:57 +05307904 if (pCfg->configPNOScanSupport)
7905 {
7906 wiphy->flags |= WIPHY_FLAG_SUPPORTS_SCHED_SCAN;
7907 wiphy->max_sched_scan_ssids = SIR_PNO_MAX_SUPP_NETWORKS;
7908 wiphy->max_match_sets = SIR_PNO_MAX_SUPP_NETWORKS;
7909 wiphy->max_sched_scan_ie_len = SIR_MAC_MAX_IE_LENGTH;
7910 }
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +05307911#endif/*FEATURE_WLAN_SCAN_PNO*/
Mohit Khanna698ba2a2012-12-04 15:08:18 -08007912
Abhishek Singh10d85972015-04-17 10:27:23 +05307913#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,4,0))
7914 wiphy->features |= NL80211_FEATURE_HT_IBSS;
7915#endif
7916
Amar Singhalfddc28c2013-09-05 13:03:40 -07007917#ifdef CONFIG_ENABLE_LINUX_REG
Madan Mohan Koyyalamudic3a240c2012-09-28 15:34:08 -07007918 /* even with WIPHY_FLAG_CUSTOM_REGULATORY,
7919 driver can still register regulatory callback and
Amar Singhalfddc28c2013-09-05 13:03:40 -07007920 it will get regulatory settings in wiphy->band[], but
Madan Mohan Koyyalamudic3a240c2012-09-28 15:34:08 -07007921 driver need to determine what to do with both
7922 regulatory settings */
Amar Singhalfddc28c2013-09-05 13:03:40 -07007923
7924 wiphy->reg_notifier = wlan_hdd_linux_reg_notifier;
Amar Singhala49cbc52013-10-08 18:37:44 -07007925#else
7926 wiphy->reg_notifier = wlan_hdd_crda_reg_notifier;
Amar Singhalfddc28c2013-09-05 13:03:40 -07007927#endif
Jeff Johnson04dd8a82012-06-29 20:41:40 -07007928
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307929 wiphy->max_scan_ssids = MAX_SCAN_SSID;
7930
Ganesh Kondabattini7500fb32015-04-10 14:50:32 +05307931 wiphy->max_scan_ie_len = SIR_MAC_MAX_ADD_IE_LENGTH;
Jeff Johnson295189b2012-06-20 16:38:30 -07007932
Gopichand Nakkalac005b7c2013-05-14 16:04:14 +05307933 wiphy->max_acl_mac_addrs = MAX_ACL_MAC_ADDRESS;
7934
Jeff Johnson295189b2012-06-20 16:38:30 -07007935 /* Supports STATION & AD-HOC modes right now */
Bhargav Shah0d2e3e52015-07-24 16:51:01 +05307936 wiphy->interface_modes = BIT(NL80211_IFTYPE_STATION)
7937 | BIT(NL80211_IFTYPE_ADHOC)
7938 | BIT(NL80211_IFTYPE_P2P_CLIENT)
7939 | BIT(NL80211_IFTYPE_P2P_GO)
7940 | BIT(NL80211_IFTYPE_AP);
7941
7942 if (VOS_MONITOR_MODE == hdd_get_conparam())
7943 {
7944 wiphy->interface_modes |= BIT(NL80211_IFTYPE_MONITOR);
7945 }
Jeff Johnson295189b2012-06-20 16:38:30 -07007946
Rashmi Ramannabd3feb72014-02-25 16:14:48 +05307947 if( pCfg->advertiseConcurrentOperation )
Sudhir Sattayappa Kohalli278eee52013-01-16 17:35:13 -08007948 {
Rashmi Ramannabd3feb72014-02-25 16:14:48 +05307949#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,4,0))
7950 if( pCfg->enableMCC )
7951 {
7952 /* Currently, supports up to two channels */
7953 wlan_hdd_iface_combination.num_different_channels = 2;
Sudhir Sattayappa Kohalli278eee52013-01-16 17:35:13 -08007954
Rashmi Ramannabd3feb72014-02-25 16:14:48 +05307955 if( !pCfg->allowMCCGODiffBI )
7956 wlan_hdd_iface_combination.beacon_int_infra_match = true;
Sudhir Sattayappa Kohalli278eee52013-01-16 17:35:13 -08007957
Rashmi Ramannabd3feb72014-02-25 16:14:48 +05307958 }
7959 wiphy->iface_combinations = &wlan_hdd_iface_combination;
7960 wiphy->n_iface_combinations = 1;
Sudhir Sattayappa Kohalli278eee52013-01-16 17:35:13 -08007961#endif
Rashmi Ramannabd3feb72014-02-25 16:14:48 +05307962 }
Sudhir Sattayappa Kohalli278eee52013-01-16 17:35:13 -08007963
Jeff Johnson295189b2012-06-20 16:38:30 -07007964 /* Before registering we need to update the ht capabilitied based
7965 * on ini values*/
7966 if( !pCfg->ShortGI20MhzEnable )
7967 {
7968 wlan_hdd_band_2_4_GHZ.ht_cap.cap &= ~IEEE80211_HT_CAP_SGI_20;
7969 wlan_hdd_band_5_GHZ.ht_cap.cap &= ~IEEE80211_HT_CAP_SGI_20;
Jeff Johnson295189b2012-06-20 16:38:30 -07007970 }
7971
7972 if( !pCfg->ShortGI40MhzEnable )
7973 {
7974 wlan_hdd_band_5_GHZ.ht_cap.cap &= ~IEEE80211_HT_CAP_SGI_40;
7975 }
7976
7977 if( !pCfg->nChannelBondingMode5GHz )
7978 {
7979 wlan_hdd_band_5_GHZ.ht_cap.cap &= ~IEEE80211_HT_CAP_SUP_WIDTH_20_40;
7980 }
Agrawal Ashish97dec502015-11-26 20:20:58 +05307981 /*
7982 * In case of static linked driver at the time of driver unload,
7983 * module exit doesn't happens. Module cleanup helps in cleaning
7984 * of static memory.
7985 * If driver load happens statically, at the time of driver unload,
7986 * wiphy flags don't get reset because of static memory.
7987 * It's better not to store channel in static memory.
7988 */
7989 wiphy->bands[IEEE80211_BAND_2GHZ] = &wlan_hdd_band_2_4_GHZ;
7990 wiphy->bands[IEEE80211_BAND_2GHZ]->channels =
7991 (struct ieee80211_channel *)vos_mem_malloc(sizeof(hdd_channels_2_4_GHZ));
7992 if (wiphy->bands[IEEE80211_BAND_2GHZ]->channels == NULL)
7993 {
7994 hddLog(VOS_TRACE_LEVEL_ERROR,
7995 FL("Not enough memory to allocate channels"));
7996 return -ENOMEM;
7997 }
7998 vos_mem_copy(wiphy->bands[IEEE80211_BAND_2GHZ]->channels,
7999 &hdd_channels_2_4_GHZ[0],
8000 sizeof(hdd_channels_2_4_GHZ));
Jeff Johnson295189b2012-06-20 16:38:30 -07008001
Agrawal Ashish97dec502015-11-26 20:20:58 +05308002 if (true == hdd_is_5g_supported(pHddCtx))
8003 {
8004 wiphy->bands[IEEE80211_BAND_5GHZ] = &wlan_hdd_band_5_GHZ;
8005 wiphy->bands[IEEE80211_BAND_5GHZ]->channels =
8006 (struct ieee80211_channel *)vos_mem_malloc(sizeof(hdd_channels_5_GHZ));
8007 if (wiphy->bands[IEEE80211_BAND_5GHZ]->channels == NULL)
8008 {
8009 hddLog(VOS_TRACE_LEVEL_ERROR,
8010 FL("Not enough memory to allocate channels"));
8011 vos_mem_free(wiphy->bands[IEEE80211_BAND_2GHZ]->channels);
8012 wiphy->bands[IEEE80211_BAND_2GHZ]->channels = NULL;
8013 return -ENOMEM;
8014 }
8015 vos_mem_copy(wiphy->bands[IEEE80211_BAND_5GHZ]->channels,
8016 &hdd_channels_5_GHZ[0],
8017 sizeof(hdd_channels_5_GHZ));
8018 }
Gopichand Nakkala1f7a64f2013-04-01 18:37:17 +05308019
8020 for (i = 0; i < IEEE80211_NUM_BANDS; i++)
8021 {
8022
8023 if (NULL == wiphy->bands[i])
8024 {
Ratheesh S P36dbc932015-08-07 14:28:57 +05308025 hddLog(VOS_TRACE_LEVEL_INFO,"%s: wiphy->bands[i] is NULL, i = %d",
Gopichand Nakkala1f7a64f2013-04-01 18:37:17 +05308026 __func__, i);
8027 continue;
8028 }
8029
8030 for (j = 0; j < wiphy->bands[i]->n_channels; j++)
8031 {
8032 struct ieee80211_supported_band *band = wiphy->bands[i];
8033
8034 if (IEEE80211_BAND_2GHZ == i && eCSR_BAND_5G == pCfg->nBandCapability) // 5G only
8035 {
8036 // Enable social channels for P2P
8037 if (WLAN_HDD_IS_SOCIAL_CHANNEL(band->channels[j].center_freq))
8038 band->channels[j].flags &= ~IEEE80211_CHAN_DISABLED;
8039 else
8040 band->channels[j].flags |= IEEE80211_CHAN_DISABLED;
8041 continue;
8042 }
8043 else if (IEEE80211_BAND_5GHZ == i && eCSR_BAND_24 == pCfg->nBandCapability) // 2G only
8044 {
8045 band->channels[j].flags |= IEEE80211_CHAN_DISABLED;
8046 continue;
8047 }
8048 }
Jeff Johnson295189b2012-06-20 16:38:30 -07008049 }
8050 /*Initialise the supported cipher suite details*/
8051 wiphy->cipher_suites = hdd_cipher_suites;
8052 wiphy->n_cipher_suites = ARRAY_SIZE(hdd_cipher_suites);
8053
8054 /*signal strength in mBm (100*dBm) */
8055 wiphy->signal_type = CFG80211_SIGNAL_TYPE_MBM;
8056
8057#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
Sushant Kaushik4f640e42014-07-08 12:27:09 +05308058 wiphy->max_remain_on_channel_duration = 5000;
Jeff Johnson295189b2012-06-20 16:38:30 -07008059#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07008060
Sunil Duttc69bccb2014-05-26 21:30:20 +05308061 wiphy->n_vendor_commands = ARRAY_SIZE(hdd_wiphy_vendor_commands);
8062 wiphy->vendor_commands = hdd_wiphy_vendor_commands;
Rajesh Chauhan98a31f82014-01-06 20:15:25 -08008063 wiphy->vendor_events = wlan_hdd_cfg80211_vendor_events;
8064 wiphy->n_vendor_events = ARRAY_SIZE(wlan_hdd_cfg80211_vendor_events);
8065
Madan Mohan Koyyalamudi71278262013-04-12 22:00:48 +05308066 EXIT();
8067 return 0;
8068}
8069
8070/* In this function we are registering wiphy. */
8071int wlan_hdd_cfg80211_register(struct wiphy *wiphy)
8072{
8073 ENTER();
8074 /* Register our wiphy dev with cfg80211 */
Jeff Johnson295189b2012-06-20 16:38:30 -07008075 if (0 > wiphy_register(wiphy))
8076 {
Madan Mohan Koyyalamudi71278262013-04-12 22:00:48 +05308077 /* print error */
Jeff Johnson295189b2012-06-20 16:38:30 -07008078 hddLog(VOS_TRACE_LEVEL_ERROR,"%s: wiphy register failed", __func__);
8079 return -EIO;
8080 }
8081
8082 EXIT();
8083 return 0;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308084}
Jeff Johnson295189b2012-06-20 16:38:30 -07008085
Madan Mohan Koyyalamudi71278262013-04-12 22:00:48 +05308086/* In this function we are updating channel list when,
8087 regulatory domain is FCC and country code is US.
8088 Here In FCC standard 5GHz UNII-1 Bands are indoor only.
8089 As per FCC smart phone is not a indoor device.
8090 GO should not opeate on indoor channels */
8091void wlan_hdd_cfg80211_update_reg_info(struct wiphy *wiphy)
8092{
8093 int j;
8094 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
8095 tANI_U8 defaultCountryCode[3] = SME_INVALID_COUNTRY_CODE;
8096 //Default counrtycode from NV at the time of wiphy initialization.
8097 if (eHAL_STATUS_SUCCESS != sme_GetDefaultCountryCodeFrmNv(pHddCtx->hHal,
8098 &defaultCountryCode[0]))
8099 {
Jeff Johnson0299d0a2013-10-30 12:37:43 -07008100 hddLog(LOGE, FL("Failed to get default country code from NV"));
Madan Mohan Koyyalamudi71278262013-04-12 22:00:48 +05308101 }
8102 if ((defaultCountryCode[0]== 'U') && (defaultCountryCode[1]=='S'))
8103 {
Madan Mohan Koyyalamudi71278262013-04-12 22:00:48 +05308104 if (NULL == wiphy->bands[IEEE80211_BAND_5GHZ])
8105 {
8106 hddLog(VOS_TRACE_LEVEL_ERROR,"%s: wiphy->bands[IEEE80211_BAND_5GHZ] is NULL",__func__ );
8107 return;
8108 }
8109 for (j = 0; j < wiphy->bands[IEEE80211_BAND_5GHZ]->n_channels; j++)
8110 {
8111 struct ieee80211_supported_band *band = wiphy->bands[IEEE80211_BAND_5GHZ];
8112 // Mark UNII -1 band channel as passive
8113 if (WLAN_HDD_CHANNEL_IN_UNII_1_BAND(band->channels[j].center_freq))
8114 band->channels[j].flags |= IEEE80211_CHAN_PASSIVE_SCAN;
8115 }
8116 }
8117}
8118
Agarwal Ashish8fa0e9a2014-05-23 00:40:12 +05308119/* This function registers for all frame which supplicant is interested in */
8120void wlan_hdd_cfg80211_register_frames(hdd_adapter_t* pAdapter)
Jeff Johnson295189b2012-06-20 16:38:30 -07008121{
Jeff Johnson295189b2012-06-20 16:38:30 -07008122 tHalHandle hHal = WLAN_HDD_GET_HAL_CTX(pAdapter);
8123 /* Register for all P2P action, public action etc frames */
8124 v_U16_t type = (SIR_MAC_MGMT_FRAME << 2) | ( SIR_MAC_MGMT_ACTION << 4);
8125
Jeff Johnsone7245742012-09-05 17:12:55 -07008126 ENTER();
8127
Jeff Johnson295189b2012-06-20 16:38:30 -07008128 /* Right now we are registering these frame when driver is getting
8129 initialized. Once we will move to 2.6.37 kernel, in which we have
8130 frame register ops, we will move this code as a part of that */
8131 /* GAS Initial Request */
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308132 sme_RegisterMgmtFrame(hHal, pAdapter->sessionId, type,
Jeff Johnson295189b2012-06-20 16:38:30 -07008133 (v_U8_t*)GAS_INITIAL_REQ, GAS_INITIAL_REQ_SIZE );
8134
8135 /* GAS Initial Response */
8136 sme_RegisterMgmtFrame(hHal, pAdapter->sessionId, type,
8137 (v_U8_t*)GAS_INITIAL_RSP, GAS_INITIAL_RSP_SIZE );
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308138
Jeff Johnson295189b2012-06-20 16:38:30 -07008139 /* GAS Comeback Request */
8140 sme_RegisterMgmtFrame(hHal, pAdapter->sessionId, type,
8141 (v_U8_t*)GAS_COMEBACK_REQ, GAS_COMEBACK_REQ_SIZE );
8142
8143 /* GAS Comeback Response */
8144 sme_RegisterMgmtFrame(hHal, pAdapter->sessionId, type,
8145 (v_U8_t*)GAS_COMEBACK_RSP, GAS_COMEBACK_RSP_SIZE );
8146
8147 /* P2P Public Action */
8148 sme_RegisterMgmtFrame(hHal, pAdapter->sessionId, type,
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308149 (v_U8_t*)P2P_PUBLIC_ACTION_FRAME,
Jeff Johnson295189b2012-06-20 16:38:30 -07008150 P2P_PUBLIC_ACTION_FRAME_SIZE );
8151
8152 /* P2P Action */
8153 sme_RegisterMgmtFrame(hHal, pAdapter->sessionId, type,
8154 (v_U8_t*)P2P_ACTION_FRAME,
8155 P2P_ACTION_FRAME_SIZE );
Chet Lanctot186b5732013-03-18 10:26:30 -07008156
Gopichand Nakkalae3d56e72013-04-21 23:33:32 +05308157 /* WNM BSS Transition Request frame */
8158 sme_RegisterMgmtFrame(hHal, pAdapter->sessionId, type,
8159 (v_U8_t*)WNM_BSS_ACTION_FRAME,
8160 WNM_BSS_ACTION_FRAME_SIZE );
Leela Venkata Kiran Kumar Reddy Chiralae8e62c82013-10-29 18:23:26 -07008161
8162 /* WNM-Notification */
8163 sme_RegisterMgmtFrame(hHal, pAdapter->sessionId, type,
8164 (v_U8_t*)WNM_NOTIFICATION_FRAME,
8165 WNM_NOTIFICATION_FRAME_SIZE );
Jeff Johnson295189b2012-06-20 16:38:30 -07008166}
8167
Agarwal Ashish8fa0e9a2014-05-23 00:40:12 +05308168void wlan_hdd_cfg80211_deregister_frames(hdd_adapter_t* pAdapter)
Jeff Johnson295189b2012-06-20 16:38:30 -07008169{
Jeff Johnson295189b2012-06-20 16:38:30 -07008170 tHalHandle hHal = WLAN_HDD_GET_HAL_CTX(pAdapter);
8171 /* Register for all P2P action, public action etc frames */
8172 v_U16_t type = (SIR_MAC_MGMT_FRAME << 2) | ( SIR_MAC_MGMT_ACTION << 4);
8173
Jeff Johnsone7245742012-09-05 17:12:55 -07008174 ENTER();
8175
Jeff Johnson295189b2012-06-20 16:38:30 -07008176 /* Right now we are registering these frame when driver is getting
8177 initialized. Once we will move to 2.6.37 kernel, in which we have
8178 frame register ops, we will move this code as a part of that */
8179 /* GAS Initial Request */
8180
8181 sme_DeregisterMgmtFrame(hHal, pAdapter->sessionId, type,
8182 (v_U8_t*)GAS_INITIAL_REQ, GAS_INITIAL_REQ_SIZE );
8183
8184 /* GAS Initial Response */
8185 sme_DeregisterMgmtFrame(hHal, pAdapter->sessionId, type,
8186 (v_U8_t*)GAS_INITIAL_RSP, GAS_INITIAL_RSP_SIZE );
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308187
Jeff Johnson295189b2012-06-20 16:38:30 -07008188 /* GAS Comeback Request */
8189 sme_DeregisterMgmtFrame(hHal, pAdapter->sessionId, type,
8190 (v_U8_t*)GAS_COMEBACK_REQ, GAS_COMEBACK_REQ_SIZE );
8191
8192 /* GAS Comeback Response */
8193 sme_DeregisterMgmtFrame(hHal, pAdapter->sessionId, type,
8194 (v_U8_t*)GAS_COMEBACK_RSP, GAS_COMEBACK_RSP_SIZE );
8195
8196 /* P2P Public Action */
8197 sme_DeregisterMgmtFrame(hHal, pAdapter->sessionId, type,
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308198 (v_U8_t*)P2P_PUBLIC_ACTION_FRAME,
Jeff Johnson295189b2012-06-20 16:38:30 -07008199 P2P_PUBLIC_ACTION_FRAME_SIZE );
8200
8201 /* P2P Action */
8202 sme_DeregisterMgmtFrame(hHal, pAdapter->sessionId, type,
8203 (v_U8_t*)P2P_ACTION_FRAME,
8204 P2P_ACTION_FRAME_SIZE );
Leela Venkata Kiran Kumar Reddy Chiralae8e62c82013-10-29 18:23:26 -07008205 /* WNM-Notification */
8206 sme_DeregisterMgmtFrame(hHal, pAdapter->sessionId, type,
8207 (v_U8_t*)WNM_NOTIFICATION_FRAME,
8208 WNM_NOTIFICATION_FRAME_SIZE );
Jeff Johnson295189b2012-06-20 16:38:30 -07008209}
8210
8211#ifdef FEATURE_WLAN_WAPI
8212void wlan_hdd_cfg80211_set_key_wapi(hdd_adapter_t* pAdapter, u8 key_index,
Anand N Sunkad9bfc2622015-07-30 15:18:54 +05308213 const u8 *mac_addr, const u8 *key , int key_Len)
Jeff Johnson295189b2012-06-20 16:38:30 -07008214{
8215 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
8216 tCsrRoamSetKey setKey;
8217 v_BOOL_t isConnected = TRUE;
8218 int status = 0;
8219 v_U32_t roamId= 0xFF;
8220 tANI_U8 *pKeyPtr = NULL;
8221 int n = 0;
8222
Sushant Kaushik8bc7df22014-04-09 17:55:29 +05308223 hddLog(VOS_TRACE_LEVEL_INFO, "%s: device_mode = %s(%d)",
8224 __func__, hdd_device_modetoString(pAdapter->device_mode),
8225 pAdapter->device_mode);
Jeff Johnson295189b2012-06-20 16:38:30 -07008226
Gopichand Nakkalae7480202013-02-11 15:24:22 +05308227 vos_mem_zero(&setKey, sizeof(tCsrRoamSetKey));
Jeff Johnson295189b2012-06-20 16:38:30 -07008228 setKey.keyId = key_index; // Store Key ID
8229 setKey.encType = eCSR_ENCRYPT_TYPE_WPI; // SET WAPI Encryption
8230 setKey.keyDirection = eSIR_TX_RX; // Key Directionn both TX and RX
8231 setKey.paeRole = 0 ; // the PAE role
8232 if (!mac_addr || is_broadcast_ether_addr(mac_addr))
8233 {
8234 vos_set_macaddr_broadcast( (v_MACADDR_t *)setKey.peerMac );
8235 }
8236 else
8237 {
8238 isConnected = hdd_connIsConnected(pHddStaCtx);
8239 vos_mem_copy(setKey.peerMac,&pHddStaCtx->conn_info.bssId,WNI_CFG_BSSID_LEN);
8240 }
8241 setKey.keyLength = key_Len;
8242 pKeyPtr = setKey.Key;
8243 memcpy( pKeyPtr, key, key_Len);
8244
Arif Hussain6d2a3322013-11-17 19:50:10 -08008245 hddLog(VOS_TRACE_LEVEL_INFO,"%s: WAPI KEY LENGTH:0x%04x",
Jeff Johnson295189b2012-06-20 16:38:30 -07008246 __func__, key_Len);
8247 for (n = 0 ; n < key_Len; n++)
8248 hddLog(VOS_TRACE_LEVEL_INFO, "%s WAPI KEY Data[%d]:%02x ",
8249 __func__,n,setKey.Key[n]);
8250
8251 pHddStaCtx->roam_info.roamingState = HDD_ROAM_STATE_SETTING_KEY;
8252 if ( isConnected )
8253 {
8254 status= sme_RoamSetKey( WLAN_HDD_GET_HAL_CTX(pAdapter),
8255 pAdapter->sessionId, &setKey, &roamId );
8256 }
8257 if ( status != 0 )
8258 {
8259 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
8260 "[%4d] sme_RoamSetKey returned ERROR status= %d",
8261 __LINE__, status );
8262 pHddStaCtx->roam_info.roamingState = HDD_ROAM_STATE_NONE;
8263 }
Vinay Krishna Eranna6f22c1f2014-10-13 16:03:06 +05308264 /* Need to clear any trace of key value in the memory.
8265 * Thus zero out the memory even though it is local
8266 * variable.
8267 */
8268 vos_mem_zero(&setKey, sizeof(setKey));
Jeff Johnson295189b2012-06-20 16:38:30 -07008269}
8270#endif /* FEATURE_WLAN_WAPI*/
8271
8272#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,4,0))
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308273int wlan_hdd_cfg80211_alloc_new_beacon(hdd_adapter_t *pAdapter,
Jeff Johnson295189b2012-06-20 16:38:30 -07008274 beacon_data_t **ppBeacon,
8275 struct beacon_parameters *params)
Jeff Johnson04dd8a82012-06-29 20:41:40 -07008276#else
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308277int wlan_hdd_cfg80211_alloc_new_beacon(hdd_adapter_t *pAdapter,
Jeff Johnson04dd8a82012-06-29 20:41:40 -07008278 beacon_data_t **ppBeacon,
8279 struct cfg80211_beacon_data *params,
8280 int dtim_period)
8281#endif
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308282{
Jeff Johnson295189b2012-06-20 16:38:30 -07008283 int size;
8284 beacon_data_t *beacon = NULL;
8285 beacon_data_t *old = NULL;
8286 int head_len,tail_len;
8287
Jeff Johnsone7245742012-09-05 17:12:55 -07008288 ENTER();
Jeff Johnson295189b2012-06-20 16:38:30 -07008289 if (params->head && !params->head_len)
c_hpothu6ff1c3c2013-10-01 19:01:57 +05308290 {
8291 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
8292 FL("head_len is NULL"));
Jeff Johnson295189b2012-06-20 16:38:30 -07008293 return -EINVAL;
c_hpothu6ff1c3c2013-10-01 19:01:57 +05308294 }
Jeff Johnson295189b2012-06-20 16:38:30 -07008295
8296 old = pAdapter->sessionCtx.ap.beacon;
8297
8298 if (!params->head && !old)
c_hpothu6ff1c3c2013-10-01 19:01:57 +05308299 {
8300 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
8301 FL("session(%d) old and new heads points to NULL"),
8302 pAdapter->sessionId);
Jeff Johnson295189b2012-06-20 16:38:30 -07008303 return -EINVAL;
c_hpothu6ff1c3c2013-10-01 19:01:57 +05308304 }
8305
8306 if (params->tail && !params->tail_len)
8307 {
8308 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
8309 FL("tail_len is zero but tail is not NULL"));
8310 return -EINVAL;
8311 }
Jeff Johnson295189b2012-06-20 16:38:30 -07008312
Jeff Johnson295189b2012-06-20 16:38:30 -07008313#if (LINUX_VERSION_CODE <= KERNEL_VERSION(2,6,38))
8314 /* Kernel 3.0 is not updating dtim_period for set beacon */
8315 if (!params->dtim_period)
c_hpothu6ff1c3c2013-10-01 19:01:57 +05308316 {
8317 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
8318 FL("dtim period is 0"));
Jeff Johnson295189b2012-06-20 16:38:30 -07008319 return -EINVAL;
c_hpothu6ff1c3c2013-10-01 19:01:57 +05308320 }
Jeff Johnson295189b2012-06-20 16:38:30 -07008321#endif
8322
8323 if(params->head)
8324 head_len = params->head_len;
8325 else
8326 head_len = old->head_len;
8327
8328 if(params->tail || !old)
8329 tail_len = params->tail_len;
8330 else
8331 tail_len = old->tail_len;
8332
8333 size = sizeof(beacon_data_t) + head_len + tail_len;
8334
8335 beacon = kzalloc(size, GFP_KERNEL);
8336
8337 if( beacon == NULL )
c_hpothu6ff1c3c2013-10-01 19:01:57 +05308338 {
8339 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
8340 FL("Mem allocation for beacon failed"));
Jeff Johnson295189b2012-06-20 16:38:30 -07008341 return -ENOMEM;
c_hpothu6ff1c3c2013-10-01 19:01:57 +05308342 }
Jeff Johnson295189b2012-06-20 16:38:30 -07008343
Jeff Johnson04dd8a82012-06-29 20:41:40 -07008344#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,4,0))
Jeff Johnson295189b2012-06-20 16:38:30 -07008345 if(params->dtim_period || !old )
8346 beacon->dtim_period = params->dtim_period;
8347 else
8348 beacon->dtim_period = old->dtim_period;
Jeff Johnson04dd8a82012-06-29 20:41:40 -07008349#else
8350 if(dtim_period || !old )
8351 beacon->dtim_period = dtim_period;
8352 else
8353 beacon->dtim_period = old->dtim_period;
8354#endif
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308355
Jeff Johnson295189b2012-06-20 16:38:30 -07008356 beacon->head = ((u8 *) beacon) + sizeof(beacon_data_t);
8357 beacon->tail = beacon->head + head_len;
8358 beacon->head_len = head_len;
8359 beacon->tail_len = tail_len;
8360
8361 if(params->head) {
8362 memcpy (beacon->head,params->head,beacon->head_len);
8363 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308364 else {
Jeff Johnson295189b2012-06-20 16:38:30 -07008365 if(old)
8366 memcpy (beacon->head,old->head,beacon->head_len);
8367 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308368
Jeff Johnson295189b2012-06-20 16:38:30 -07008369 if(params->tail) {
8370 memcpy (beacon->tail,params->tail,beacon->tail_len);
8371 }
8372 else {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308373 if(old)
Jeff Johnson295189b2012-06-20 16:38:30 -07008374 memcpy (beacon->tail,old->tail,beacon->tail_len);
8375 }
8376
8377 *ppBeacon = beacon;
8378
8379 kfree(old);
8380
8381 return 0;
8382
8383}
Jeff Johnson295189b2012-06-20 16:38:30 -07008384
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +05308385v_U8_t* wlan_hdd_cfg80211_get_ie_ptr(
8386#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 18, 0))
8387 const v_U8_t *pIes,
8388#else
8389 v_U8_t *pIes,
8390#endif
8391 int length, v_U8_t eid)
Jeff Johnson295189b2012-06-20 16:38:30 -07008392{
8393 int left = length;
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +05308394 v_U8_t *ptr = (v_U8_t *)pIes;
Jeff Johnson295189b2012-06-20 16:38:30 -07008395 v_U8_t elem_id,elem_len;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308396
Jeff Johnson295189b2012-06-20 16:38:30 -07008397 while(left >= 2)
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308398 {
Jeff Johnson295189b2012-06-20 16:38:30 -07008399 elem_id = ptr[0];
8400 elem_len = ptr[1];
8401 left -= 2;
8402 if(elem_len > left)
8403 {
8404 hddLog(VOS_TRACE_LEVEL_FATAL,
Madan Mohan Koyyalamudi8bdd3112012-09-24 13:55:14 -07008405 FL("****Invalid IEs eid = %d elem_len=%d left=%d*****"),
Jeff Johnson295189b2012-06-20 16:38:30 -07008406 eid,elem_len,left);
8407 return NULL;
8408 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308409 if (elem_id == eid)
Jeff Johnson295189b2012-06-20 16:38:30 -07008410 {
8411 return ptr;
8412 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308413
Jeff Johnson295189b2012-06-20 16:38:30 -07008414 left -= elem_len;
8415 ptr += (elem_len + 2);
8416 }
8417 return NULL;
8418}
8419
Jeff Johnson295189b2012-06-20 16:38:30 -07008420/* Check if rate is 11g rate or not */
8421static int wlan_hdd_rate_is_11g(u8 rate)
8422{
Sanjay Devnani28322e22013-06-21 16:13:40 -07008423 static const u8 gRateArray[8] = {12, 18, 24, 36, 48, 72, 96, 108}; /* actual rate * 2 */
Jeff Johnson295189b2012-06-20 16:38:30 -07008424 u8 i;
8425 for (i = 0; i < 8; i++)
8426 {
8427 if(rate == gRateArray[i])
8428 return TRUE;
8429 }
8430 return FALSE;
8431}
8432
8433/* Check for 11g rate and set proper 11g only mode */
8434static void wlan_hdd_check_11gmode(u8 *pIe, u8* require_ht,
8435 u8* pCheckRatesfor11g, eSapPhyMode* pSapHw_mode)
8436{
8437 u8 i, num_rates = pIe[0];
8438
8439 pIe += 1;
8440 for ( i = 0; i < num_rates; i++)
8441 {
8442 if( *pCheckRatesfor11g && (TRUE == wlan_hdd_rate_is_11g(pIe[i] & RATE_MASK)))
8443 {
8444 /* If rate set have 11g rate than change the mode to 11G */
8445 *pSapHw_mode = eSAP_DOT11_MODE_11g;
8446 if (pIe[i] & BASIC_RATE_MASK)
8447 {
8448 /* If we have 11g rate as basic rate, it means mode
8449 is 11g only mode.
8450 */
8451 *pSapHw_mode = eSAP_DOT11_MODE_11g_ONLY;
8452 *pCheckRatesfor11g = FALSE;
8453 }
8454 }
8455 else if((BASIC_RATE_MASK | WLAN_BSS_MEMBERSHIP_SELECTOR_HT_PHY) == pIe[i])
8456 {
8457 *require_ht = TRUE;
8458 }
8459 }
8460 return;
8461}
8462
8463static void wlan_hdd_set_sapHwmode(hdd_adapter_t *pHostapdAdapter)
8464{
8465 tsap_Config_t *pConfig = &pHostapdAdapter->sessionCtx.ap.sapConfig;
8466 beacon_data_t *pBeacon = pHostapdAdapter->sessionCtx.ap.beacon;
8467 struct ieee80211_mgmt *pMgmt_frame = (struct ieee80211_mgmt*)pBeacon->head;
8468 u8 checkRatesfor11g = TRUE;
8469 u8 require_ht = FALSE;
8470 u8 *pIe=NULL;
8471
8472 pConfig->SapHw_mode= eSAP_DOT11_MODE_11b;
8473
8474 pIe = wlan_hdd_cfg80211_get_ie_ptr(&pMgmt_frame->u.beacon.variable[0],
8475 pBeacon->head_len, WLAN_EID_SUPP_RATES);
8476 if (pIe != NULL)
8477 {
8478 pIe += 1;
8479 wlan_hdd_check_11gmode(pIe, &require_ht, &checkRatesfor11g,
8480 &pConfig->SapHw_mode);
8481 }
8482
8483 pIe = wlan_hdd_cfg80211_get_ie_ptr(pBeacon->tail, pBeacon->tail_len,
8484 WLAN_EID_EXT_SUPP_RATES);
8485 if (pIe != NULL)
8486 {
8487
8488 pIe += 1;
8489 wlan_hdd_check_11gmode(pIe, &require_ht, &checkRatesfor11g,
8490 &pConfig->SapHw_mode);
8491 }
8492
8493 if( pConfig->channel > 14 )
8494 {
8495 pConfig->SapHw_mode= eSAP_DOT11_MODE_11a;
8496 }
8497
8498 pIe = wlan_hdd_cfg80211_get_ie_ptr(pBeacon->tail, pBeacon->tail_len,
8499 WLAN_EID_HT_CAPABILITY);
8500
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308501 if(pIe)
Jeff Johnson295189b2012-06-20 16:38:30 -07008502 {
8503 pConfig->SapHw_mode= eSAP_DOT11_MODE_11n;
8504 if(require_ht)
8505 pConfig->SapHw_mode= eSAP_DOT11_MODE_11n_ONLY;
8506 }
8507}
8508
Gopichand Nakkala2b25f4e2013-03-21 19:14:07 +05308509static int wlan_hdd_add_ie(hdd_adapter_t* pHostapdAdapter, v_U8_t *genie,
8510 v_U8_t *total_ielen, v_U8_t *oui, v_U8_t oui_size)
8511{
Arif Hussaine7f3ea52013-09-12 21:56:36 -07008512 v_U16_t ielen = 0;
Gopichand Nakkala2b25f4e2013-03-21 19:14:07 +05308513 v_U8_t *pIe = NULL;
8514 beacon_data_t *pBeacon = pHostapdAdapter->sessionCtx.ap.beacon;
8515
8516 pIe = wlan_hdd_get_vendor_oui_ie_ptr(oui, oui_size,
8517 pBeacon->tail, pBeacon->tail_len);
8518
8519 if (pIe)
8520 {
8521 ielen = pIe[1] + 2;
8522 if ((*total_ielen + ielen) <= MAX_GENIE_LEN)
8523 {
8524 vos_mem_copy(&genie[*total_ielen], pIe, ielen);
8525 }
8526 else
8527 {
8528 hddLog( VOS_TRACE_LEVEL_ERROR, "**Ie Length is too big***");
8529 return -EINVAL;
8530 }
8531 *total_ielen += ielen;
8532 }
8533 return 0;
8534}
8535
Arif Hussaine7f3ea52013-09-12 21:56:36 -07008536static void wlan_hdd_add_hostapd_conf_vsie(hdd_adapter_t* pHostapdAdapter,
8537 v_U8_t *genie, v_U8_t *total_ielen)
8538{
8539 beacon_data_t *pBeacon = pHostapdAdapter->sessionCtx.ap.beacon;
8540 int left = pBeacon->tail_len;
8541 v_U8_t *ptr = pBeacon->tail;
8542 v_U8_t elem_id, elem_len;
8543 v_U16_t ielen = 0;
8544
8545 if ( NULL == ptr || 0 == left )
8546 return;
8547
8548 while (left >= 2)
8549 {
8550 elem_id = ptr[0];
8551 elem_len = ptr[1];
8552 left -= 2;
8553 if (elem_len > left)
8554 {
8555 hddLog( VOS_TRACE_LEVEL_ERROR,
8556 "****Invalid IEs eid = %d elem_len=%d left=%d*****",
8557 elem_id, elem_len, left);
8558 return;
8559 }
8560 if (IE_EID_VENDOR == elem_id)
8561 {
8562 /* skipping the VSIE's which we don't want to include or
8563 * it will be included by existing code
8564 */
8565 if ((memcmp( &ptr[2], WPS_OUI_TYPE, WPS_OUI_TYPE_SIZE) != 0 ) &&
8566#ifdef WLAN_FEATURE_WFD
8567 (memcmp( &ptr[2], WFD_OUI_TYPE, WFD_OUI_TYPE_SIZE) != 0) &&
8568#endif
8569 (memcmp( &ptr[2], WHITELIST_OUI_TYPE, WPA_OUI_TYPE_SIZE) != 0) &&
8570 (memcmp( &ptr[2], BLACKLIST_OUI_TYPE, WPA_OUI_TYPE_SIZE) != 0) &&
8571 (memcmp( &ptr[2], "\x00\x50\xf2\x02", WPA_OUI_TYPE_SIZE) != 0) &&
8572 (memcmp( &ptr[2], WPA_OUI_TYPE, WPA_OUI_TYPE_SIZE) != 0) &&
8573 (memcmp( &ptr[2], P2P_OUI_TYPE, P2P_OUI_TYPE_SIZE) != 0))
8574 {
8575 ielen = ptr[1] + 2;
8576 if ((*total_ielen + ielen) <= MAX_GENIE_LEN)
8577 {
8578 vos_mem_copy(&genie[*total_ielen], ptr, ielen);
8579 *total_ielen += ielen;
8580 }
8581 else
8582 {
8583 hddLog( VOS_TRACE_LEVEL_ERROR,
8584 "IE Length is too big "
8585 "IEs eid=%d elem_len=%d total_ie_lent=%d",
8586 elem_id, elem_len, *total_ielen);
8587 }
8588 }
8589 }
8590
8591 left -= elem_len;
8592 ptr += (elem_len + 2);
8593 }
8594 return;
8595}
8596
Jeff Johnson04dd8a82012-06-29 20:41:40 -07008597#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,4,0))
Jeff Johnson295189b2012-06-20 16:38:30 -07008598static int wlan_hdd_cfg80211_update_apies(hdd_adapter_t* pHostapdAdapter,
8599 struct beacon_parameters *params)
Jeff Johnson04dd8a82012-06-29 20:41:40 -07008600#else
8601static int wlan_hdd_cfg80211_update_apies(hdd_adapter_t* pHostapdAdapter,
8602 struct cfg80211_beacon_data *params)
8603#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07008604{
8605 v_U8_t *genie;
Gopichand Nakkala2b25f4e2013-03-21 19:14:07 +05308606 v_U8_t total_ielen = 0;
Jeff Johnson295189b2012-06-20 16:38:30 -07008607 v_U8_t addIE[1] = {0};
Jeff Johnsone7245742012-09-05 17:12:55 -07008608 int ret = 0;
Jeff Johnson295189b2012-06-20 16:38:30 -07008609
8610 genie = vos_mem_malloc(MAX_GENIE_LEN);
8611
8612 if(genie == NULL) {
8613
8614 return -ENOMEM;
8615 }
8616
Gopichand Nakkala2b25f4e2013-03-21 19:14:07 +05308617 if (0 != wlan_hdd_add_ie(pHostapdAdapter, genie,
8618 &total_ielen, WPS_OUI_TYPE, WPS_OUI_TYPE_SIZE))
Jeff Johnson295189b2012-06-20 16:38:30 -07008619 {
c_hpothu6ff1c3c2013-10-01 19:01:57 +05308620 hddLog(LOGE,
8621 FL("Adding WPS IE failed"));
Gopichand Nakkala2b25f4e2013-03-21 19:14:07 +05308622 ret = -EINVAL;
8623 goto done;
Jeff Johnson295189b2012-06-20 16:38:30 -07008624 }
8625
8626#ifdef WLAN_FEATURE_WFD
Gopichand Nakkala2b25f4e2013-03-21 19:14:07 +05308627 if (0 != wlan_hdd_add_ie(pHostapdAdapter, genie,
8628 &total_ielen, WFD_OUI_TYPE, WFD_OUI_TYPE_SIZE))
8629 {
c_hpothu6ff1c3c2013-10-01 19:01:57 +05308630 hddLog(LOGE,
8631 FL("Adding WFD IE failed"));
Gopichand Nakkala2b25f4e2013-03-21 19:14:07 +05308632 ret = -EINVAL;
8633 goto done;
Jeff Johnson295189b2012-06-20 16:38:30 -07008634 }
8635#endif
8636
Gopichand Nakkala2b25f4e2013-03-21 19:14:07 +05308637 if (0 != wlan_hdd_add_ie(pHostapdAdapter, genie,
8638 &total_ielen, P2P_OUI_TYPE, P2P_OUI_TYPE_SIZE))
Jeff Johnson295189b2012-06-20 16:38:30 -07008639 {
c_hpothu6ff1c3c2013-10-01 19:01:57 +05308640 hddLog(LOGE,
8641 FL("Adding P2P IE failed"));
Gopichand Nakkala2b25f4e2013-03-21 19:14:07 +05308642 ret = -EINVAL;
8643 goto done;
8644 }
8645
8646 if (WLAN_HDD_SOFTAP == pHostapdAdapter->device_mode)
8647 {
Arif Hussaine7f3ea52013-09-12 21:56:36 -07008648 wlan_hdd_add_hostapd_conf_vsie(pHostapdAdapter, genie, &total_ielen);
Jeff Johnson295189b2012-06-20 16:38:30 -07008649 }
Jeff Johnson295189b2012-06-20 16:38:30 -07008650
8651 if (ccmCfgSetStr((WLAN_HDD_GET_CTX(pHostapdAdapter))->hHal,
8652 WNI_CFG_PROBE_RSP_BCN_ADDNIE_DATA, genie, total_ielen, NULL,
8653 eANI_BOOLEAN_FALSE)==eHAL_STATUS_FAILURE)
8654 {
8655 hddLog(LOGE,
8656 "Could not pass on WNI_CFG_PROBE_RSP_BCN_ADDNIE_DATA to CCM");
Jeff Johnsone7245742012-09-05 17:12:55 -07008657 ret = -EINVAL;
8658 goto done;
Jeff Johnson295189b2012-06-20 16:38:30 -07008659 }
8660
8661 if (ccmCfgSetInt((WLAN_HDD_GET_CTX(pHostapdAdapter))->hHal,
8662 WNI_CFG_PROBE_RSP_BCN_ADDNIE_FLAG, 1,NULL,
8663 test_bit(SOFTAP_BSS_STARTED, &pHostapdAdapter->event_flags) ?
8664 eANI_BOOLEAN_TRUE : eANI_BOOLEAN_FALSE)
8665 ==eHAL_STATUS_FAILURE)
8666 {
8667 hddLog(LOGE,
8668 "Could not pass on WNI_CFG_PROBE_RSP_BCN_ADDNIE_FLAG to CCM");
Jeff Johnsone7245742012-09-05 17:12:55 -07008669 ret = -EINVAL;
8670 goto done;
Jeff Johnson295189b2012-06-20 16:38:30 -07008671 }
8672
8673 // Added for ProResp IE
8674 if ( (params->proberesp_ies != NULL) && (params->proberesp_ies_len != 0) )
8675 {
8676 u16 rem_probe_resp_ie_len = params->proberesp_ies_len;
8677 u8 probe_rsp_ie_len[3] = {0};
8678 u8 counter = 0;
8679 /* Check Probe Resp Length if it is greater then 255 then Store
8680 Probe Resp IEs into WNI_CFG_PROBE_RSP_ADDNIE_DATA1 &
8681 WNI_CFG_PROBE_RSP_ADDNIE_DATA2 CFG Variable As We are not able
8682 Store More then 255 bytes into One Variable.
8683 */
8684 while ((rem_probe_resp_ie_len > 0) && (counter < 3))
8685 {
8686 if (rem_probe_resp_ie_len > MAX_CFG_STRING_LEN)
8687 {
8688 probe_rsp_ie_len[counter++] = MAX_CFG_STRING_LEN;
8689 rem_probe_resp_ie_len -= MAX_CFG_STRING_LEN;
8690 }
8691 else
8692 {
8693 probe_rsp_ie_len[counter++] = rem_probe_resp_ie_len;
8694 rem_probe_resp_ie_len = 0;
8695 }
8696 }
8697
8698 rem_probe_resp_ie_len = 0;
8699
8700 if (probe_rsp_ie_len[0] > 0)
8701 {
8702 if (ccmCfgSetStr((WLAN_HDD_GET_CTX(pHostapdAdapter))->hHal,
8703 WNI_CFG_PROBE_RSP_ADDNIE_DATA1,
8704 (tANI_U8*)&params->proberesp_ies[rem_probe_resp_ie_len],
8705 probe_rsp_ie_len[0], NULL,
8706 eANI_BOOLEAN_FALSE) == eHAL_STATUS_FAILURE)
8707 {
8708 hddLog(LOGE,
8709 "Could not pass on WNI_CFG_PROBE_RSP_ADDNIE_DATA1 to CCM");
Jeff Johnsone7245742012-09-05 17:12:55 -07008710 ret = -EINVAL;
8711 goto done;
Jeff Johnson295189b2012-06-20 16:38:30 -07008712 }
8713 rem_probe_resp_ie_len += probe_rsp_ie_len[0];
8714 }
8715
8716 if (probe_rsp_ie_len[1] > 0)
8717 {
8718 if (ccmCfgSetStr((WLAN_HDD_GET_CTX(pHostapdAdapter))->hHal,
8719 WNI_CFG_PROBE_RSP_ADDNIE_DATA2,
8720 (tANI_U8*)&params->proberesp_ies[rem_probe_resp_ie_len],
8721 probe_rsp_ie_len[1], NULL,
8722 eANI_BOOLEAN_FALSE) == eHAL_STATUS_FAILURE)
8723 {
8724 hddLog(LOGE,
8725 "Could not pass on WNI_CFG_PROBE_RSP_ADDNIE_DATA2 to CCM");
Jeff Johnsone7245742012-09-05 17:12:55 -07008726 ret = -EINVAL;
8727 goto done;
Jeff Johnson295189b2012-06-20 16:38:30 -07008728 }
8729 rem_probe_resp_ie_len += probe_rsp_ie_len[1];
8730 }
8731
8732 if (probe_rsp_ie_len[2] > 0)
8733 {
8734 if (ccmCfgSetStr((WLAN_HDD_GET_CTX(pHostapdAdapter))->hHal,
8735 WNI_CFG_PROBE_RSP_ADDNIE_DATA3,
8736 (tANI_U8*)&params->proberesp_ies[rem_probe_resp_ie_len],
8737 probe_rsp_ie_len[2], NULL,
8738 eANI_BOOLEAN_FALSE) == eHAL_STATUS_FAILURE)
8739 {
8740 hddLog(LOGE,
8741 "Could not pass on WNI_CFG_PROBE_RSP_ADDNIE_DATA3 to CCM");
Jeff Johnsone7245742012-09-05 17:12:55 -07008742 ret = -EINVAL;
8743 goto done;
Jeff Johnson295189b2012-06-20 16:38:30 -07008744 }
8745 rem_probe_resp_ie_len += probe_rsp_ie_len[2];
8746 }
8747
8748 if (probe_rsp_ie_len[1] == 0 )
8749 {
8750 if ( eHAL_STATUS_FAILURE == ccmCfgSetStr((WLAN_HDD_GET_CTX(pHostapdAdapter))->hHal,
8751 WNI_CFG_PROBE_RSP_ADDNIE_DATA2, (tANI_U8*)addIE, 0, NULL,
8752 eANI_BOOLEAN_FALSE) )
8753 {
8754 hddLog(LOGE,
Arif Hussain6d2a3322013-11-17 19:50:10 -08008755 "Could not pass on WNI_CFG_PROBE_RSP_ADDNIE_DATA2 to CCM");
Jeff Johnson295189b2012-06-20 16:38:30 -07008756 }
8757 }
8758
8759 if (probe_rsp_ie_len[2] == 0 )
8760 {
8761 if ( eHAL_STATUS_FAILURE == ccmCfgSetStr((WLAN_HDD_GET_CTX(pHostapdAdapter))->hHal,
8762 WNI_CFG_PROBE_RSP_ADDNIE_DATA3, (tANI_U8*)addIE, 0, NULL,
8763 eANI_BOOLEAN_FALSE) )
8764 {
8765 hddLog(LOGE,
Arif Hussain6d2a3322013-11-17 19:50:10 -08008766 "Could not pass on WNI_CFG_PROBE_RSP_ADDNIE_DATA3 to CCM");
Jeff Johnson295189b2012-06-20 16:38:30 -07008767 }
8768 }
8769
8770 if (ccmCfgSetInt((WLAN_HDD_GET_CTX(pHostapdAdapter))->hHal,
8771 WNI_CFG_PROBE_RSP_ADDNIE_FLAG, 1,NULL,
8772 test_bit(SOFTAP_BSS_STARTED, &pHostapdAdapter->event_flags) ?
8773 eANI_BOOLEAN_TRUE : eANI_BOOLEAN_FALSE)
8774 == eHAL_STATUS_FAILURE)
8775 {
8776 hddLog(LOGE,
8777 "Could not pass on WNI_CFG_PROBE_RSP_ADDNIE_FLAG to CCM");
Jeff Johnsone7245742012-09-05 17:12:55 -07008778 ret = -EINVAL;
8779 goto done;
Jeff Johnson295189b2012-06-20 16:38:30 -07008780 }
8781 }
8782 else
8783 {
8784 // Reset WNI_CFG_PROBE_RSP Flags
8785 wlan_hdd_reset_prob_rspies(pHostapdAdapter);
8786
8787 hddLog(VOS_TRACE_LEVEL_INFO,
8788 "%s: No Probe Response IE received in set beacon",
8789 __func__);
8790 }
8791
8792 // Added for AssocResp IE
8793 if ( (params->assocresp_ies != NULL) && (params->assocresp_ies_len != 0) )
8794 {
8795 if (ccmCfgSetStr((WLAN_HDD_GET_CTX(pHostapdAdapter))->hHal,
8796 WNI_CFG_ASSOC_RSP_ADDNIE_DATA, (tANI_U8*)params->assocresp_ies,
8797 params->assocresp_ies_len, NULL,
8798 eANI_BOOLEAN_FALSE) == eHAL_STATUS_FAILURE)
8799 {
8800 hddLog(LOGE,
8801 "Could not pass on WNI_CFG_ASSOC_RSP_ADDNIE_DATA to CCM");
Jeff Johnsone7245742012-09-05 17:12:55 -07008802 ret = -EINVAL;
8803 goto done;
Jeff Johnson295189b2012-06-20 16:38:30 -07008804 }
8805
8806 if (ccmCfgSetInt((WLAN_HDD_GET_CTX(pHostapdAdapter))->hHal,
8807 WNI_CFG_ASSOC_RSP_ADDNIE_FLAG, 1, NULL,
8808 test_bit(SOFTAP_BSS_STARTED, &pHostapdAdapter->event_flags) ?
8809 eANI_BOOLEAN_TRUE : eANI_BOOLEAN_FALSE)
8810 == eHAL_STATUS_FAILURE)
8811 {
8812 hddLog(LOGE,
8813 "Could not pass on WNI_CFG_ASSOC_RSP_ADDNIE_FLAG to CCM");
Jeff Johnsone7245742012-09-05 17:12:55 -07008814 ret = -EINVAL;
8815 goto done;
Jeff Johnson295189b2012-06-20 16:38:30 -07008816 }
8817 }
8818 else
8819 {
8820 hddLog(VOS_TRACE_LEVEL_INFO,
8821 "%s: No Assoc Response IE received in set beacon",
8822 __func__);
8823
8824 if ( eHAL_STATUS_FAILURE == ccmCfgSetInt((WLAN_HDD_GET_CTX(pHostapdAdapter))->hHal,
8825 WNI_CFG_ASSOC_RSP_ADDNIE_FLAG, 0, NULL,
8826 eANI_BOOLEAN_FALSE) )
8827 {
8828 hddLog(LOGE,
Arif Hussain6d2a3322013-11-17 19:50:10 -08008829 "Could not pass on WNI_CFG_ASSOC_RSP_ADDNIE_FLAG to CCM");
Jeff Johnson295189b2012-06-20 16:38:30 -07008830 }
8831 }
8832
Jeff Johnsone7245742012-09-05 17:12:55 -07008833done:
Jeff Johnson295189b2012-06-20 16:38:30 -07008834 vos_mem_free(genie);
Gopichand Nakkala2b25f4e2013-03-21 19:14:07 +05308835 return ret;
Jeff Johnson295189b2012-06-20 16:38:30 -07008836}
Jeff Johnson295189b2012-06-20 16:38:30 -07008837
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308838/*
Jeff Johnson295189b2012-06-20 16:38:30 -07008839 * FUNCTION: wlan_hdd_validate_operation_channel
8840 * called by wlan_hdd_cfg80211_start_bss() and
8841 * wlan_hdd_cfg80211_set_channel()
8842 * This function validates whether given channel is part of valid
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308843 * channel list.
8844 */
Varun Reddy Yeturu920df212013-05-22 08:07:23 -07008845VOS_STATUS wlan_hdd_validate_operation_channel(hdd_adapter_t *pAdapter,int channel)
Jeff Johnson295189b2012-06-20 16:38:30 -07008846{
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308847
Jeff Johnson295189b2012-06-20 16:38:30 -07008848 v_U32_t num_ch = 0;
8849 u8 valid_ch[WNI_CFG_VALID_CHANNEL_LIST_LEN];
8850 u32 indx = 0;
8851 tHalHandle hHal = WLAN_HDD_GET_HAL_CTX(pAdapter);
Madan Mohan Koyylamudi64267f72013-02-05 14:07:08 +05308852 v_U8_t fValidChannel = FALSE, count = 0;
8853 hdd_config_t *hdd_pConfig_ini= (WLAN_HDD_GET_CTX(pAdapter))->cfg_ini;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308854
Jeff Johnson295189b2012-06-20 16:38:30 -07008855 num_ch = WNI_CFG_VALID_CHANNEL_LIST_LEN;
8856
Madan Mohan Koyylamudi64267f72013-02-05 14:07:08 +05308857 if ( hdd_pConfig_ini->sapAllowAllChannel)
Jeff Johnson295189b2012-06-20 16:38:30 -07008858 {
Madan Mohan Koyylamudi64267f72013-02-05 14:07:08 +05308859 /* Validate the channel */
8860 for (count = RF_CHAN_1 ; count <= RF_CHAN_165 ; count++)
Jeff Johnson295189b2012-06-20 16:38:30 -07008861 {
Madan Mohan Koyylamudi64267f72013-02-05 14:07:08 +05308862 if ( channel == rfChannels[count].channelNum )
8863 {
8864 fValidChannel = TRUE;
8865 break;
8866 }
8867 }
8868 if (fValidChannel != TRUE)
8869 {
8870 hddLog(VOS_TRACE_LEVEL_ERROR,
8871 "%s: Invalid Channel [%d]", __func__, channel);
8872 return VOS_STATUS_E_FAILURE;
Jeff Johnson295189b2012-06-20 16:38:30 -07008873 }
8874 }
Madan Mohan Koyylamudi64267f72013-02-05 14:07:08 +05308875 else
Jeff Johnson295189b2012-06-20 16:38:30 -07008876 {
Madan Mohan Koyylamudi64267f72013-02-05 14:07:08 +05308877 if (0 != ccmCfgGetStr(hHal, WNI_CFG_VALID_CHANNEL_LIST,
8878 valid_ch, &num_ch))
8879 {
8880 hddLog(VOS_TRACE_LEVEL_ERROR,
8881 "%s: failed to get valid channel list", __func__);
8882 return VOS_STATUS_E_FAILURE;
8883 }
8884 for (indx = 0; indx < num_ch; indx++)
8885 {
8886 if (channel == valid_ch[indx])
8887 {
8888 break;
8889 }
8890 }
8891
Rashmi Ramanna3b59e122014-04-10 14:45:13 +05308892 if (indx >= num_ch)
8893 {
8894 if (WLAN_HDD_P2P_GO == pAdapter->device_mode)
8895 {
8896 eCsrBand band;
8897 unsigned int freq;
8898
8899 sme_GetFreqBand(hHal, &band);
8900
8901 if (eCSR_BAND_5G == band)
8902 {
8903#if (LINUX_VERSION_CODE > KERNEL_VERSION(2,6,38))
8904 if (channel <= ARRAY_SIZE(hdd_channels_2_4_GHZ))
8905 {
8906 freq = ieee80211_channel_to_frequency(channel,
8907 IEEE80211_BAND_2GHZ);
8908 }
8909 else
8910 {
8911 freq = ieee80211_channel_to_frequency(channel,
8912 IEEE80211_BAND_5GHZ);
8913 }
8914#else
8915 freq = ieee80211_channel_to_frequency(channel);
8916#endif
8917 if(WLAN_HDD_IS_SOCIAL_CHANNEL(freq))
8918 return VOS_STATUS_SUCCESS;
8919 }
8920 }
8921
8922 hddLog(VOS_TRACE_LEVEL_ERROR,
8923 "%s: Invalid Channel [%d]", __func__, channel);
8924 return VOS_STATUS_E_FAILURE;
8925 }
Jeff Johnson295189b2012-06-20 16:38:30 -07008926 }
Rashmi Ramanna3b59e122014-04-10 14:45:13 +05308927
Jeff Johnson295189b2012-06-20 16:38:30 -07008928 return VOS_STATUS_SUCCESS;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308929
Jeff Johnson295189b2012-06-20 16:38:30 -07008930}
8931
Viral Modi3a32cc52013-02-08 11:14:52 -08008932/**
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +05308933 * FUNCTION: __wlan_hdd_cfg80211_set_channel
Viral Modi3a32cc52013-02-08 11:14:52 -08008934 * This function is used to set the channel number
8935 */
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +05308936static int __wlan_hdd_cfg80211_set_channel( struct wiphy *wiphy, struct net_device *dev,
Viral Modi3a32cc52013-02-08 11:14:52 -08008937 struct ieee80211_channel *chan,
8938 enum nl80211_channel_type channel_type
8939 )
8940{
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05308941 hdd_adapter_t *pAdapter = NULL;
Viral Modi3a32cc52013-02-08 11:14:52 -08008942 v_U32_t num_ch = 0;
Jeff Johnson4416a782013-03-25 14:17:50 -07008943 int channel = 0;
Viral Modi3a32cc52013-02-08 11:14:52 -08008944 int freq = chan->center_freq; /* freq is in MHZ */
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05308945 hdd_context_t *pHddCtx;
8946 int status;
Viral Modi3a32cc52013-02-08 11:14:52 -08008947
8948 ENTER();
8949
8950 if( NULL == dev )
8951 {
8952 hddLog(VOS_TRACE_LEVEL_ERROR,
Arif Hussain6d2a3322013-11-17 19:50:10 -08008953 "%s: Called with dev = NULL.", __func__);
Viral Modi3a32cc52013-02-08 11:14:52 -08008954 return -ENODEV;
8955 }
8956 pAdapter = WLAN_HDD_GET_PRIV_PTR( dev );
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +05308957
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05308958 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
8959 TRACE_CODE_HDD_CFG80211_SET_CHANNEL, pAdapter->sessionId,
8960 channel_type ));
Viral Modi3a32cc52013-02-08 11:14:52 -08008961 hddLog(VOS_TRACE_LEVEL_INFO,
Sushant Kaushik8bc7df22014-04-09 17:55:29 +05308962 "%s: device_mode = %s (%d) freq = %d", __func__,
8963 hdd_device_modetoString(pAdapter->device_mode),
8964 pAdapter->device_mode, chan->center_freq);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05308965
8966 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
8967 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05308968 if (0 != status)
Viral Modi3a32cc52013-02-08 11:14:52 -08008969 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05308970 return status;
Viral Modi3a32cc52013-02-08 11:14:52 -08008971 }
8972
8973 /*
8974 * Do freq to chan conversion
8975 * TODO: for 11a
8976 */
8977
8978 channel = ieee80211_frequency_to_channel(freq);
8979
8980 /* Check freq range */
8981 if ((WNI_CFG_CURRENT_CHANNEL_STAMIN > channel) ||
8982 (WNI_CFG_CURRENT_CHANNEL_STAMAX < channel))
8983 {
8984 hddLog(VOS_TRACE_LEVEL_ERROR,
Arif Hussain6d2a3322013-11-17 19:50:10 -08008985 "%s: Channel [%d] is outside valid range from %d to %d",
Viral Modi3a32cc52013-02-08 11:14:52 -08008986 __func__, channel, WNI_CFG_CURRENT_CHANNEL_STAMIN,
8987 WNI_CFG_CURRENT_CHANNEL_STAMAX);
8988 return -EINVAL;
8989 }
8990
8991 num_ch = WNI_CFG_VALID_CHANNEL_LIST_LEN;
8992
Gopichand Nakkala6ab19562013-03-07 13:59:42 +05308993 if ((WLAN_HDD_SOFTAP != pAdapter->device_mode) &&
8994 (WLAN_HDD_P2P_GO != pAdapter->device_mode))
Viral Modi3a32cc52013-02-08 11:14:52 -08008995 {
8996 if(VOS_STATUS_SUCCESS != wlan_hdd_validate_operation_channel(pAdapter,channel))
8997 {
8998 hddLog(VOS_TRACE_LEVEL_ERROR,
Arif Hussain6d2a3322013-11-17 19:50:10 -08008999 "%s: Invalid Channel [%d]", __func__, channel);
Viral Modi3a32cc52013-02-08 11:14:52 -08009000 return -EINVAL;
9001 }
9002 hddLog(VOS_TRACE_LEVEL_INFO_HIGH,
9003 "%s: set channel to [%d] for device mode =%d",
9004 __func__, channel,pAdapter->device_mode);
9005 }
9006 if( (pAdapter->device_mode == WLAN_HDD_INFRA_STATION)
Viral Modi3a32cc52013-02-08 11:14:52 -08009007 || (pAdapter->device_mode == WLAN_HDD_P2P_CLIENT)
Viral Modi3a32cc52013-02-08 11:14:52 -08009008 )
9009 {
9010 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
9011 tCsrRoamProfile * pRoamProfile = &pWextState->roamProfile;
9012 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
9013
9014 if (eConnectionState_IbssConnected == pHddStaCtx->conn_info.connState)
9015 {
9016 /* Link is up then return cant set channel*/
9017 hddLog( VOS_TRACE_LEVEL_ERROR,
Arif Hussain6d2a3322013-11-17 19:50:10 -08009018 "%s: IBSS Associated, can't set the channel", __func__);
Viral Modi3a32cc52013-02-08 11:14:52 -08009019 return -EINVAL;
9020 }
9021
9022 num_ch = pRoamProfile->ChannelInfo.numOfChannels = 1;
9023 pHddStaCtx->conn_info.operationChannel = channel;
9024 pRoamProfile->ChannelInfo.ChannelList =
9025 &pHddStaCtx->conn_info.operationChannel;
9026 }
9027 else if ((pAdapter->device_mode == WLAN_HDD_SOFTAP)
Viral Modi3a32cc52013-02-08 11:14:52 -08009028 || (pAdapter->device_mode == WLAN_HDD_P2P_GO)
Viral Modi3a32cc52013-02-08 11:14:52 -08009029 )
9030 {
Gopichand Nakkalac8fa7b62013-03-11 13:56:41 +05309031 if (WLAN_HDD_P2P_GO == pAdapter->device_mode)
9032 {
9033 if(VOS_STATUS_SUCCESS !=
9034 wlan_hdd_validate_operation_channel(pAdapter,channel))
9035 {
9036 hddLog(VOS_TRACE_LEVEL_ERROR,
Arif Hussain6d2a3322013-11-17 19:50:10 -08009037 "%s: Invalid Channel [%d]", __func__, channel);
Gopichand Nakkalac8fa7b62013-03-11 13:56:41 +05309038 return -EINVAL;
9039 }
9040 (WLAN_HDD_GET_AP_CTX_PTR(pAdapter))->sapConfig.channel = channel;
9041 }
9042 else if ( WLAN_HDD_SOFTAP == pAdapter->device_mode )
Viral Modi3a32cc52013-02-08 11:14:52 -08009043 {
9044 hdd_config_t *cfg_param = (WLAN_HDD_GET_CTX(pAdapter))->cfg_ini;
9045
9046 /* If auto channel selection is configured as enable/ 1 then ignore
9047 channel set by supplicant
9048 */
9049 if ( cfg_param->apAutoChannelSelection )
9050 {
Gopichand Nakkalac8fa7b62013-03-11 13:56:41 +05309051 (WLAN_HDD_GET_AP_CTX_PTR(pAdapter))->sapConfig.channel =
9052 AUTO_CHANNEL_SELECT;
Viral Modi3a32cc52013-02-08 11:14:52 -08009053 hddLog(VOS_TRACE_LEVEL_INFO_HIGH,
Sushant Kaushik8bc7df22014-04-09 17:55:29 +05309054 "%s: set channel to auto channel (0) for device mode =%s (%d)",
9055 __func__, hdd_device_modetoString(pAdapter->device_mode),
9056 pAdapter->device_mode);
Viral Modi3a32cc52013-02-08 11:14:52 -08009057 }
Gopichand Nakkalac8fa7b62013-03-11 13:56:41 +05309058 else
9059 {
9060 if(VOS_STATUS_SUCCESS !=
9061 wlan_hdd_validate_operation_channel(pAdapter,channel))
9062 {
9063 hddLog(VOS_TRACE_LEVEL_ERROR,
Arif Hussain6d2a3322013-11-17 19:50:10 -08009064 "%s: Invalid Channel [%d]", __func__, channel);
Gopichand Nakkalac8fa7b62013-03-11 13:56:41 +05309065 return -EINVAL;
9066 }
9067 (WLAN_HDD_GET_AP_CTX_PTR(pAdapter))->sapConfig.channel = channel;
9068 }
Viral Modi3a32cc52013-02-08 11:14:52 -08009069 }
9070 }
9071 else
9072 {
9073 hddLog(VOS_TRACE_LEVEL_FATAL,
9074 "%s: Invalid device mode failed to set valid channel", __func__);
9075 return -EINVAL;
9076 }
9077 EXIT();
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05309078 return status;
Viral Modi3a32cc52013-02-08 11:14:52 -08009079}
9080
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +05309081static int wlan_hdd_cfg80211_set_channel( struct wiphy *wiphy,
9082 struct net_device *dev,
9083 struct ieee80211_channel *chan,
9084 enum nl80211_channel_type channel_type
9085 )
9086{
9087 int ret;
9088
9089 vos_ssr_protect(__func__);
9090 ret = __wlan_hdd_cfg80211_set_channel(wiphy, dev, chan, channel_type);
9091 vos_ssr_unprotect(__func__);
9092
9093 return ret;
9094}
9095
Jeff Johnson295189b2012-06-20 16:38:30 -07009096#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,4,0))
9097static int wlan_hdd_cfg80211_start_bss(hdd_adapter_t *pHostapdAdapter,
9098 struct beacon_parameters *params)
Jeff Johnson04dd8a82012-06-29 20:41:40 -07009099#else
9100static int wlan_hdd_cfg80211_start_bss(hdd_adapter_t *pHostapdAdapter,
9101 struct cfg80211_beacon_data *params,
9102 const u8 *ssid, size_t ssid_len,
Kanchanapally, Vidyullathaacc59252015-05-20 16:49:07 +05309103 enum nl80211_hidden_ssid hidden_ssid,
9104 v_U8_t auth_type)
Jeff Johnson04dd8a82012-06-29 20:41:40 -07009105#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07009106{
9107 tsap_Config_t *pConfig;
9108 beacon_data_t *pBeacon = NULL;
9109 struct ieee80211_mgmt *pMgmt_frame;
9110 v_U8_t *pIe=NULL;
9111 v_U16_t capab_info;
9112 eCsrAuthType RSNAuthType;
9113 eCsrEncryptionType RSNEncryptType;
9114 eCsrEncryptionType mcRSNEncryptType;
9115 int status = VOS_STATUS_SUCCESS;
9116 tpWLAN_SAPEventCB pSapEventCallback;
9117 hdd_hostapd_state_t *pHostapdState;
9118 v_U8_t wpaRsnIEdata[(SIR_MAC_MAX_IE_LENGTH * 2)+4]; //Max ie length 255 * 2(WPA+RSN) + 2 bytes (vendor specific ID) * 2
9119 v_CONTEXT_t pVosContext = (WLAN_HDD_GET_CTX(pHostapdAdapter))->pvosContext;
Madan Mohan Koyylamudia16d0202013-02-01 11:05:57 +05309120 tHalHandle hHal = WLAN_HDD_GET_HAL_CTX(pHostapdAdapter);
Jeff Johnson295189b2012-06-20 16:38:30 -07009121 struct qc_mac_acl_entry *acl_entry = NULL;
Siddharth Bhal5cba24e2014-05-08 18:59:39 +05309122 hdd_config_t *iniConfig;
Jeff Johnson295189b2012-06-20 16:38:30 -07009123 v_SINT_t i;
Madan Mohan Koyyalamudi543172b2012-12-05 16:40:18 -08009124 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pHostapdAdapter);
Peng Xu2446a892014-09-05 17:21:18 +05309125 tSmeConfigParams *psmeConfig;
Chet Lanctot40142442014-05-20 13:39:25 -07009126 v_BOOL_t MFPCapable = VOS_FALSE;
9127 v_BOOL_t MFPRequired = VOS_FALSE;
Sushant Kaushik7dc03272015-02-18 11:25:12 +05309128 v_BOOL_t sapEnable11AC =
9129 (WLAN_HDD_GET_CTX(pHostapdAdapter))->cfg_ini->sapEnable11AC;
Jeff Johnson295189b2012-06-20 16:38:30 -07009130 ENTER();
9131
Siddharth Bhal5cba24e2014-05-08 18:59:39 +05309132 iniConfig = pHddCtx->cfg_ini;
9133
Jeff Johnson295189b2012-06-20 16:38:30 -07009134 pHostapdState = WLAN_HDD_GET_HOSTAP_STATE_PTR(pHostapdAdapter);
9135
9136 pConfig = &pHostapdAdapter->sessionCtx.ap.sapConfig;
9137
9138 pBeacon = pHostapdAdapter->sessionCtx.ap.beacon;
9139
9140 pMgmt_frame = (struct ieee80211_mgmt*)pBeacon->head;
9141
9142 pConfig->beacon_int = pMgmt_frame->u.beacon.beacon_int;
9143
9144 //channel is already set in the set_channel Call back
9145 //pConfig->channel = pCommitConfig->channel;
9146
9147 /*Protection parameter to enable or disable*/
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309148 pConfig->protEnabled =
Jeff Johnson295189b2012-06-20 16:38:30 -07009149 (WLAN_HDD_GET_CTX(pHostapdAdapter))->cfg_ini->apProtEnabled;
9150
9151 pConfig->dtim_period = pBeacon->dtim_period;
9152
Arif Hussain6d2a3322013-11-17 19:50:10 -08009153 hddLog(VOS_TRACE_LEVEL_INFO_HIGH,"****pConfig->dtim_period=%d***",
Jeff Johnson295189b2012-06-20 16:38:30 -07009154 pConfig->dtim_period);
9155
Madan Mohan Koyyalamudie0ca11f2012-11-27 15:57:52 -08009156 if (pHostapdAdapter->device_mode == WLAN_HDD_SOFTAP)
Jeff Johnson32d95a32012-09-10 13:15:23 -07009157 {
9158 pIe = wlan_hdd_cfg80211_get_ie_ptr(pBeacon->tail, pBeacon->tail_len,
Jeff Johnson295189b2012-06-20 16:38:30 -07009159 WLAN_EID_COUNTRY);
Kiet Lam083504c2013-11-25 14:17:45 +05309160 if(memcmp(pHddCtx->cfg_ini->apCntryCode, CFG_AP_COUNTRY_CODE_DEFAULT, 3) != 0)
9161 {
9162 tANI_BOOLEAN restartNeeded;
9163 pConfig->ieee80211d = 1;
9164 vos_mem_copy(pConfig->countryCode, pHddCtx->cfg_ini->apCntryCode, 3);
9165 sme_setRegInfo(hHal, pConfig->countryCode);
9166 sme_ResetCountryCodeInformation(hHal, &restartNeeded);
9167 }
9168 else if(pIe)
Jeff Johnson295189b2012-06-20 16:38:30 -07009169 {
Jeff Johnson32d95a32012-09-10 13:15:23 -07009170 tANI_BOOLEAN restartNeeded;
Jeff Johnson32d95a32012-09-10 13:15:23 -07009171 pConfig->ieee80211d = 1;
9172 vos_mem_copy(pConfig->countryCode, &pIe[2], 3);
9173 sme_setRegInfo(hHal, pConfig->countryCode);
9174 sme_ResetCountryCodeInformation(hHal, &restartNeeded);
Jeff Johnson295189b2012-06-20 16:38:30 -07009175 }
Jeff Johnson32d95a32012-09-10 13:15:23 -07009176 else
9177 {
9178 pConfig->ieee80211d = 0;
9179 }
Madan Mohan Koyylamudia16d0202013-02-01 11:05:57 +05309180 /*
9181 * If auto channel is configured i.e. channel is 0,
9182 * so skip channel validation.
9183 */
9184 if( AUTO_CHANNEL_SELECT != pConfig->channel )
9185 {
9186 if(VOS_STATUS_SUCCESS != wlan_hdd_validate_operation_channel(pHostapdAdapter,pConfig->channel))
9187 {
9188 hddLog(VOS_TRACE_LEVEL_ERROR,
Arif Hussain6d2a3322013-11-17 19:50:10 -08009189 "%s: Invalid Channel [%d]", __func__, pConfig->channel);
Madan Mohan Koyylamudia16d0202013-02-01 11:05:57 +05309190 return -EINVAL;
9191 }
9192 }
9193 else
9194 {
9195 if(1 != pHddCtx->is_dynamic_channel_range_set)
9196 {
9197 hdd_config_t *hdd_pConfig= (WLAN_HDD_GET_CTX(pHostapdAdapter))->cfg_ini;
9198 WLANSAP_SetChannelRange(hHal, hdd_pConfig->apStartChannelNum,
9199 hdd_pConfig->apEndChannelNum,hdd_pConfig->apOperatingBand);
9200 }
9201 pHddCtx->is_dynamic_channel_range_set = 0;
9202 }
Jeff Johnson295189b2012-06-20 16:38:30 -07009203 }
Jeff Johnson32d95a32012-09-10 13:15:23 -07009204 else
Jeff Johnson295189b2012-06-20 16:38:30 -07009205 {
9206 pConfig->ieee80211d = 0;
9207 }
Kanchanapally, Vidyullathaacc59252015-05-20 16:49:07 +05309208
9209#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,4,0))
9210 if (params->auth_type == NL80211_AUTHTYPE_OPEN_SYSTEM)
9211 pConfig->authType = eSAP_OPEN_SYSTEM;
9212 else if (params->auth_type == NL80211_AUTHTYPE_SHARED_KEY)
9213 pConfig->authType = eSAP_SHARED_KEY;
9214 else
9215 pConfig->authType = eSAP_AUTO_SWITCH;
9216#else
9217 if (auth_type == NL80211_AUTHTYPE_OPEN_SYSTEM)
9218 pConfig->authType = eSAP_OPEN_SYSTEM;
9219 else if (auth_type == NL80211_AUTHTYPE_SHARED_KEY)
9220 pConfig->authType = eSAP_SHARED_KEY;
9221 else
9222 pConfig->authType = eSAP_AUTO_SWITCH;
9223#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07009224
9225 capab_info = pMgmt_frame->u.beacon.capab_info;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309226
9227 pConfig->privacy = (pMgmt_frame->u.beacon.capab_info &
Jeff Johnson295189b2012-06-20 16:38:30 -07009228 WLAN_CAPABILITY_PRIVACY) ? VOS_TRUE : VOS_FALSE;
9229
9230 (WLAN_HDD_GET_AP_CTX_PTR(pHostapdAdapter))->uPrivacy = pConfig->privacy;
9231
9232 /*Set wps station to configured*/
9233 pIe = wlan_hdd_get_wps_ie_ptr(pBeacon->tail, pBeacon->tail_len);
9234
9235 if(pIe)
9236 {
9237 if(pIe[1] < (2 + WPS_OUI_TYPE_SIZE))
9238 {
Arif Hussain6d2a3322013-11-17 19:50:10 -08009239 hddLog( VOS_TRACE_LEVEL_ERROR, "**Wps Ie Length is too small***");
Jeff Johnson295189b2012-06-20 16:38:30 -07009240 return -EINVAL;
9241 }
9242 else if(memcmp(&pIe[2], WPS_OUI_TYPE, WPS_OUI_TYPE_SIZE) == 0)
9243 {
Madan Mohan Koyyalamudi8bdd3112012-09-24 13:55:14 -07009244 hddLog( VOS_TRACE_LEVEL_INFO, "** WPS IE(len %d) ***", (pIe[1]+2));
Jeff Johnson295189b2012-06-20 16:38:30 -07009245 /* Check 15 bit of WPS IE as it contain information for wps state
9246 * WPS state
9247 */
9248 if(SAP_WPS_ENABLED_UNCONFIGURED == pIe[15])
9249 {
9250 pConfig->wps_state = SAP_WPS_ENABLED_UNCONFIGURED;
9251 } else if(SAP_WPS_ENABLED_CONFIGURED == pIe[15])
9252 {
9253 pConfig->wps_state = SAP_WPS_ENABLED_CONFIGURED;
9254 }
9255 }
9256 }
9257 else
9258 {
9259 pConfig->wps_state = SAP_WPS_DISABLED;
9260 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309261 pConfig->fwdWPSPBCProbeReq = 1; // Forward WPS PBC probe request frame up
Jeff Johnson295189b2012-06-20 16:38:30 -07009262
c_hpothufe599e92014-06-16 11:38:55 +05309263 pConfig->RSNEncryptType = eCSR_ENCRYPT_TYPE_NONE;
9264 pConfig->mcRSNEncryptType = eCSR_ENCRYPT_TYPE_NONE;
9265 (WLAN_HDD_GET_AP_CTX_PTR(pHostapdAdapter))->ucEncryptType =
9266 eCSR_ENCRYPT_TYPE_NONE;
9267
Jeff Johnson295189b2012-06-20 16:38:30 -07009268 pConfig->RSNWPAReqIELength = 0;
9269 pConfig->pRSNWPAReqIE = NULL;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309270 pIe = wlan_hdd_cfg80211_get_ie_ptr(pBeacon->tail, pBeacon->tail_len,
Jeff Johnson295189b2012-06-20 16:38:30 -07009271 WLAN_EID_RSN);
9272 if(pIe && pIe[1])
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309273 {
Jeff Johnson295189b2012-06-20 16:38:30 -07009274 pConfig->RSNWPAReqIELength = pIe[1] + 2;
9275 memcpy(&wpaRsnIEdata[0], pIe, pConfig->RSNWPAReqIELength);
9276 pConfig->pRSNWPAReqIE = &wpaRsnIEdata[0];
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309277 /* The actual processing may eventually be more extensive than
9278 * this. Right now, just consume any PMKIDs that are sent in
Jeff Johnson295189b2012-06-20 16:38:30 -07009279 * by the app.
9280 * */
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309281 status = hdd_softap_unpackIE(
Jeff Johnson295189b2012-06-20 16:38:30 -07009282 vos_get_context( VOS_MODULE_ID_SME, pVosContext),
9283 &RSNEncryptType,
9284 &mcRSNEncryptType,
9285 &RSNAuthType,
Chet Lanctot8cecea22014-02-11 19:09:36 -08009286 &MFPCapable,
9287 &MFPRequired,
Jeff Johnson295189b2012-06-20 16:38:30 -07009288 pConfig->pRSNWPAReqIE[1]+2,
9289 pConfig->pRSNWPAReqIE );
9290
9291 if( VOS_STATUS_SUCCESS == status )
9292 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309293 /* Now copy over all the security attributes you have
9294 * parsed out
Jeff Johnson295189b2012-06-20 16:38:30 -07009295 * */
9296 pConfig->RSNEncryptType = RSNEncryptType; // Use the cipher type in the RSN IE
9297 pConfig->mcRSNEncryptType = mcRSNEncryptType;
9298 (WLAN_HDD_GET_AP_CTX_PTR(pHostapdAdapter))->ucEncryptType
9299 = RSNEncryptType;
Gopichand Nakkala66c0bd02013-04-10 11:36:29 +05309300 hddLog( LOG1, FL("CSR AuthType = %d, "
Arif Hussain6d2a3322013-11-17 19:50:10 -08009301 "EncryptionType = %d mcEncryptionType = %d"),
Jeff Johnson295189b2012-06-20 16:38:30 -07009302 RSNAuthType, RSNEncryptType, mcRSNEncryptType);
9303 }
9304 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309305
Jeff Johnson295189b2012-06-20 16:38:30 -07009306 pIe = wlan_hdd_get_vendor_oui_ie_ptr(WPA_OUI_TYPE, WPA_OUI_TYPE_SIZE,
9307 pBeacon->tail, pBeacon->tail_len);
9308
9309 if(pIe && pIe[1] && (pIe[0] == DOT11F_EID_WPA))
9310 {
9311 if (pConfig->pRSNWPAReqIE)
9312 {
9313 /*Mixed mode WPA/WPA2*/
9314 memcpy((&wpaRsnIEdata[0] + pConfig->RSNWPAReqIELength), pIe, pIe[1] + 2);
9315 pConfig->RSNWPAReqIELength += pIe[1] + 2;
9316 }
9317 else
9318 {
9319 pConfig->RSNWPAReqIELength = pIe[1] + 2;
9320 memcpy(&wpaRsnIEdata[0], pIe, pConfig->RSNWPAReqIELength);
9321 pConfig->pRSNWPAReqIE = &wpaRsnIEdata[0];
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309322 status = hdd_softap_unpackIE(
Jeff Johnson295189b2012-06-20 16:38:30 -07009323 vos_get_context( VOS_MODULE_ID_SME, pVosContext),
9324 &RSNEncryptType,
9325 &mcRSNEncryptType,
9326 &RSNAuthType,
Chet Lanctot8cecea22014-02-11 19:09:36 -08009327 &MFPCapable,
9328 &MFPRequired,
Jeff Johnson295189b2012-06-20 16:38:30 -07009329 pConfig->pRSNWPAReqIE[1]+2,
9330 pConfig->pRSNWPAReqIE );
9331
9332 if( VOS_STATUS_SUCCESS == status )
9333 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309334 /* Now copy over all the security attributes you have
9335 * parsed out
Jeff Johnson295189b2012-06-20 16:38:30 -07009336 * */
9337 pConfig->RSNEncryptType = RSNEncryptType; // Use the cipher type in the RSN IE
9338 pConfig->mcRSNEncryptType = mcRSNEncryptType;
9339 (WLAN_HDD_GET_AP_CTX_PTR(pHostapdAdapter))->ucEncryptType
9340 = RSNEncryptType;
Gopichand Nakkala66c0bd02013-04-10 11:36:29 +05309341 hddLog( LOG1, FL("CSR AuthType = %d, "
Arif Hussain6d2a3322013-11-17 19:50:10 -08009342 "EncryptionType = %d mcEncryptionType = %d"),
Jeff Johnson295189b2012-06-20 16:38:30 -07009343 RSNAuthType, RSNEncryptType, mcRSNEncryptType);
9344 }
9345 }
9346 }
9347
Jeff Johnson4416a782013-03-25 14:17:50 -07009348 if (pConfig->RSNWPAReqIELength > sizeof wpaRsnIEdata) {
9349 hddLog( VOS_TRACE_LEVEL_ERROR, "**RSNWPAReqIELength is too large***");
9350 return -EINVAL;
9351 }
9352
Jeff Johnson295189b2012-06-20 16:38:30 -07009353 pConfig->SSIDinfo.ssidHidden = VOS_FALSE;
9354
Jeff Johnson04dd8a82012-06-29 20:41:40 -07009355#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,4,0))
Jeff Johnson295189b2012-06-20 16:38:30 -07009356 if (params->ssid != NULL)
9357 {
9358 memcpy(pConfig->SSIDinfo.ssid.ssId, params->ssid, params->ssid_len);
9359 pConfig->SSIDinfo.ssid.length = params->ssid_len;
9360 if (params->hidden_ssid != NL80211_HIDDEN_SSID_NOT_IN_USE)
9361 pConfig->SSIDinfo.ssidHidden = VOS_TRUE;
9362 }
Jeff Johnson04dd8a82012-06-29 20:41:40 -07009363#else
9364 if (ssid != NULL)
9365 {
9366 memcpy(pConfig->SSIDinfo.ssid.ssId, ssid, ssid_len);
9367 pConfig->SSIDinfo.ssid.length = ssid_len;
9368 if (hidden_ssid != NL80211_HIDDEN_SSID_NOT_IN_USE)
9369 pConfig->SSIDinfo.ssidHidden = VOS_TRUE;
9370 }
9371#endif
9372
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309373 vos_mem_copy(pConfig->self_macaddr.bytes,
Jeff Johnson295189b2012-06-20 16:38:30 -07009374 pHostapdAdapter->macAddressCurrent.bytes, sizeof(v_MACADDR_t));
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309375
Jeff Johnson295189b2012-06-20 16:38:30 -07009376 /* default value */
9377 pConfig->SapMacaddr_acl = eSAP_ACCEPT_UNLESS_DENIED;
9378 pConfig->num_accept_mac = 0;
9379 pConfig->num_deny_mac = 0;
9380
9381 pIe = wlan_hdd_get_vendor_oui_ie_ptr(BLACKLIST_OUI_TYPE, WPA_OUI_TYPE_SIZE,
9382 pBeacon->tail, pBeacon->tail_len);
9383
9384 /* pIe for black list is following form:
9385 type : 1 byte
9386 length : 1 byte
9387 OUI : 4 bytes
9388 acl type : 1 byte
9389 no of mac addr in black list: 1 byte
9390 list of mac_acl_entries: variable, 6 bytes per mac address + sizeof(int) for vlan id
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309391 */
9392 if ((pIe != NULL) && (pIe[1] != 0))
Jeff Johnson295189b2012-06-20 16:38:30 -07009393 {
9394 pConfig->SapMacaddr_acl = pIe[6];
9395 pConfig->num_deny_mac = pIe[7];
Arif Hussain6d2a3322013-11-17 19:50:10 -08009396 hddLog(VOS_TRACE_LEVEL_INFO,"acl type = %d no deny mac = %d",
Jeff Johnson295189b2012-06-20 16:38:30 -07009397 pIe[6], pIe[7]);
Gopichand Nakkalac005b7c2013-05-14 16:04:14 +05309398 if (pConfig->num_deny_mac > MAX_ACL_MAC_ADDRESS)
9399 pConfig->num_deny_mac = MAX_ACL_MAC_ADDRESS;
Jeff Johnson295189b2012-06-20 16:38:30 -07009400 acl_entry = (struct qc_mac_acl_entry *)(pIe + 8);
9401 for (i = 0; i < pConfig->num_deny_mac; i++)
9402 {
9403 vos_mem_copy(&pConfig->deny_mac[i], acl_entry->addr, sizeof(qcmacaddr));
9404 acl_entry++;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309405 }
Jeff Johnson295189b2012-06-20 16:38:30 -07009406 }
9407 pIe = wlan_hdd_get_vendor_oui_ie_ptr(WHITELIST_OUI_TYPE, WPA_OUI_TYPE_SIZE,
9408 pBeacon->tail, pBeacon->tail_len);
9409
9410 /* pIe for white list is following form:
9411 type : 1 byte
9412 length : 1 byte
9413 OUI : 4 bytes
9414 acl type : 1 byte
9415 no of mac addr in white list: 1 byte
9416 list of mac_acl_entries: variable, 6 bytes per mac address + sizeof(int) for vlan id
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309417 */
9418 if ((pIe != NULL) && (pIe[1] != 0))
Jeff Johnson295189b2012-06-20 16:38:30 -07009419 {
9420 pConfig->SapMacaddr_acl = pIe[6];
9421 pConfig->num_accept_mac = pIe[7];
Arif Hussain6d2a3322013-11-17 19:50:10 -08009422 hddLog(VOS_TRACE_LEVEL_INFO,"acl type = %d no accept mac = %d",
Jeff Johnson295189b2012-06-20 16:38:30 -07009423 pIe[6], pIe[7]);
Gopichand Nakkalac005b7c2013-05-14 16:04:14 +05309424 if (pConfig->num_accept_mac > MAX_ACL_MAC_ADDRESS)
9425 pConfig->num_accept_mac = MAX_ACL_MAC_ADDRESS;
Jeff Johnson295189b2012-06-20 16:38:30 -07009426 acl_entry = (struct qc_mac_acl_entry *)(pIe + 8);
9427 for (i = 0; i < pConfig->num_accept_mac; i++)
9428 {
9429 vos_mem_copy(&pConfig->accept_mac[i], acl_entry->addr, sizeof(qcmacaddr));
9430 acl_entry++;
9431 }
9432 }
Gopichand Nakkalac005b7c2013-05-14 16:04:14 +05309433
Jeff Johnson295189b2012-06-20 16:38:30 -07009434 wlan_hdd_set_sapHwmode(pHostapdAdapter);
9435
Jeff Johnsone7245742012-09-05 17:12:55 -07009436#ifdef WLAN_FEATURE_11AC
Ravi Kumar Vaishnavbbaebbe2013-01-15 17:09:48 -08009437 /* Overwrite the hostapd setting for HW mode only for 11ac.
Sushant Kaushik7dc03272015-02-18 11:25:12 +05309438 * This is valid only if mode is set to 11n in hostapd, sapEnable11AC
9439 * is set in .ini and 11ac is supported by both host and firmware.
Kiet Lam0f320422013-11-21 19:29:17 +05309440 * Otherwise, leave whatever is set in hostapd (a OR b OR g OR n mode)
9441 */
Ravi Kumar Vaishnavbbaebbe2013-01-15 17:09:48 -08009442 if( ((pConfig->SapHw_mode == eSAP_DOT11_MODE_11n) ||
9443 (pConfig->SapHw_mode == eSAP_DOT11_MODE_11n_ONLY)) &&
Sushant Kaushik7dc03272015-02-18 11:25:12 +05309444 (sapEnable11AC) && (sme_IsFeatureSupportedByDriver(DOT11AC)) &&
9445 (sme_IsFeatureSupportedByFW(DOT11AC)) )
Jeff Johnsone7245742012-09-05 17:12:55 -07009446 {
Siddharth Bhalf42f8592014-05-15 13:39:07 +05309447 v_U32_t operatingBand = 0;
Jeff Johnsone7245742012-09-05 17:12:55 -07009448 pConfig->SapHw_mode = eSAP_DOT11_MODE_11ac;
Siddharth Bhalf42f8592014-05-15 13:39:07 +05309449 ccmCfgGetInt(hHal, WNI_CFG_SAP_CHANNEL_SELECT_OPERATING_BAND, &operatingBand);
Ravi Joshi83bfaa12013-05-28 22:12:08 -07009450
Siddharth Bhal5cba24e2014-05-08 18:59:39 +05309451 /* If ACS disable and selected channel <= 14
9452 * OR
9453 * ACS enabled and ACS operating band is choosen as 2.4
9454 * AND
9455 * VHT in 2.4G Disabled
9456 * THEN
9457 * Fallback to 11N mode
9458 */
9459 if (((AUTO_CHANNEL_SELECT != pConfig->channel && pConfig->channel <= SIR_11B_CHANNEL_END)
9460 || (AUTO_CHANNEL_SELECT == pConfig->channel &&
Deepthi Gowri7db41f32014-10-13 17:02:29 +05309461 operatingBand == eSAP_RF_SUBBAND_2_4_GHZ)) &&
Siddharth Bhal5cba24e2014-05-08 18:59:39 +05309462 iniConfig->enableVhtFor24GHzBand == FALSE)
Ravi Joshi83bfaa12013-05-28 22:12:08 -07009463 {
Siddharth Bhalf42f8592014-05-15 13:39:07 +05309464 hddLog(LOGW, FL("Setting hwmode to 11n, operatingBand = %d, Channel = %d"),
9465 operatingBand, pConfig->channel);
Ravi Joshi83bfaa12013-05-28 22:12:08 -07009466 pConfig->SapHw_mode = eSAP_DOT11_MODE_11n;
9467 }
Jeff Johnsone7245742012-09-05 17:12:55 -07009468 }
9469#endif
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309470
Jeff Johnson295189b2012-06-20 16:38:30 -07009471 // ht_capab is not what the name conveys,this is used for protection bitmap
9472 pConfig->ht_capab =
9473 (WLAN_HDD_GET_CTX(pHostapdAdapter))->cfg_ini->apProtection;
9474
9475 if ( 0 != wlan_hdd_cfg80211_update_apies(pHostapdAdapter, params) )
9476 {
9477 hddLog(LOGE, FL("SAP Not able to set AP IEs"));
9478 return -EINVAL;
9479 }
9480
9481 //Uapsd Enabled Bit
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309482 pConfig->UapsdEnable =
Jeff Johnson295189b2012-06-20 16:38:30 -07009483 (WLAN_HDD_GET_CTX(pHostapdAdapter))->cfg_ini->apUapsdEnabled;
9484 //Enable OBSS protection
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309485 pConfig->obssProtEnabled =
9486 (WLAN_HDD_GET_CTX(pHostapdAdapter))->cfg_ini->apOBSSProtEnabled;
Jeff Johnson295189b2012-06-20 16:38:30 -07009487
Chet Lanctot8cecea22014-02-11 19:09:36 -08009488#ifdef WLAN_FEATURE_11W
9489 pConfig->mfpCapable = MFPCapable;
9490 pConfig->mfpRequired = MFPRequired;
9491 hddLog(LOGW, FL("Soft AP MFP capable %d, MFP required %d\n"),
9492 pConfig->mfpCapable, pConfig->mfpRequired);
9493#endif
9494
Arif Hussain6d2a3322013-11-17 19:50:10 -08009495 hddLog(LOGW, FL("SOftAP macaddress : "MAC_ADDRESS_STR),
Jeff Johnson295189b2012-06-20 16:38:30 -07009496 MAC_ADDR_ARRAY(pHostapdAdapter->macAddressCurrent.bytes));
Arif Hussain6d2a3322013-11-17 19:50:10 -08009497 hddLog(LOGW,FL("ssid =%s, beaconint=%d, channel=%d"),
9498 pConfig->SSIDinfo.ssid.ssId, (int)pConfig->beacon_int,
9499 (int)pConfig->channel);
9500 hddLog(LOGW,FL("hw_mode=%x, privacy=%d, authType=%d"),
9501 pConfig->SapHw_mode, pConfig->privacy,
9502 pConfig->authType);
9503 hddLog(LOGW,FL("RSN/WPALen=%d, Uapsd = %d"),
9504 (int)pConfig->RSNWPAReqIELength, pConfig->UapsdEnable);
9505 hddLog(LOGW,FL("ProtEnabled = %d, OBSSProtEnabled = %d"),
9506 pConfig->protEnabled, pConfig->obssProtEnabled);
Jeff Johnson295189b2012-06-20 16:38:30 -07009507
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309508 if(test_bit(SOFTAP_BSS_STARTED, &pHostapdAdapter->event_flags))
Jeff Johnson295189b2012-06-20 16:38:30 -07009509 {
9510 //Bss already started. just return.
9511 //TODO Probably it should update some beacon params.
9512 hddLog( LOGE, "Bss Already started...Ignore the request");
9513 EXIT();
9514 return 0;
9515 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309516
Agarwal Ashish51325b52014-06-16 16:50:49 +05309517 if (vos_max_concurrent_connections_reached()) {
9518 hddLog(VOS_TRACE_LEVEL_INFO, FL("Reached max concurrent connections"));
9519 return -EINVAL;
9520 }
9521
Jeff Johnson295189b2012-06-20 16:38:30 -07009522 pConfig->persona = pHostapdAdapter->device_mode;
9523
Peng Xu2446a892014-09-05 17:21:18 +05309524 psmeConfig = (tSmeConfigParams*) vos_mem_malloc(sizeof(tSmeConfigParams));
9525 if ( NULL != psmeConfig)
9526 {
Hardik Kantilal Patel086e0a32014-11-20 14:56:26 +05309527 vos_mem_zero(psmeConfig, sizeof (tSmeConfigParams));
Peng Xu2446a892014-09-05 17:21:18 +05309528 sme_GetConfigParam(hHal, psmeConfig);
9529 pConfig->scanBandPreference = psmeConfig->csrConfig.scanBandPreference;
Hardik Kantilal Patel086e0a32014-11-20 14:56:26 +05309530#ifdef WLAN_FEATURE_AP_HT40_24G
9531 if (((pHostapdAdapter->device_mode == WLAN_HDD_SOFTAP)
9532 || (pHostapdAdapter->device_mode == WLAN_HDD_P2P_GO))
9533 && pHddCtx->cfg_ini->apHT40_24GEnabled)
9534 {
9535 psmeConfig->csrConfig.apHT40_24GEnabled = 1;
9536 sme_UpdateConfig (hHal, psmeConfig);
9537 }
9538#endif
Peng Xu2446a892014-09-05 17:21:18 +05309539 vos_mem_free(psmeConfig);
9540 }
Peng Xuafc34e32014-09-25 13:23:55 +05309541 pConfig->acsBandSwitchThreshold = iniConfig->acsBandSwitchThreshold;
Peng Xu2446a892014-09-05 17:21:18 +05309542
Jeff Johnson295189b2012-06-20 16:38:30 -07009543 pSapEventCallback = hdd_hostapd_SAPEventCB;
9544 if(WLANSAP_StartBss(pVosContext, pSapEventCallback, pConfig,
9545 (v_PVOID_t)pHostapdAdapter->dev) != VOS_STATUS_SUCCESS)
9546 {
Arif Hussain6d2a3322013-11-17 19:50:10 -08009547 hddLog(LOGE,FL("SAP Start Bss fail"));
Jeff Johnson295189b2012-06-20 16:38:30 -07009548 return -EINVAL;
9549 }
9550
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309551 hddLog(LOG1,
Jeff Johnson295189b2012-06-20 16:38:30 -07009552 FL("Waiting for Scan to complete(auto mode) and BSS to start"));
9553
9554 status = vos_wait_single_event(&pHostapdState->vosEvent, 10000);
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309555
Jeff Johnson295189b2012-06-20 16:38:30 -07009556 if (!VOS_IS_STATUS_SUCCESS(status))
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309557 {
9558 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Arif Hussain6d2a3322013-11-17 19:50:10 -08009559 ("ERROR: HDD vos wait for single_event failed!!"));
Tushnim Bhattacharyyaad37df12013-10-02 12:01:33 -07009560 smeGetCommandQStatus(hHal);
Jeff Johnson295189b2012-06-20 16:38:30 -07009561 VOS_ASSERT(0);
9562 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309563
Jeff Johnson295189b2012-06-20 16:38:30 -07009564 set_bit(SOFTAP_BSS_STARTED, &pHostapdAdapter->event_flags);
Kaushik, Sushantf6070802014-10-15 15:09:23 +05309565 /* Initialize WMM configuation */
9566 hdd_wmm_init(pHostapdAdapter);
Agarwal Ashish51325b52014-06-16 16:50:49 +05309567 wlan_hdd_incr_active_session(pHddCtx, pHostapdAdapter->device_mode);
Jeff Johnson295189b2012-06-20 16:38:30 -07009568
Madan Mohan Koyyalamudi26bd7142012-10-30 18:14:19 -07009569#ifdef WLAN_FEATURE_P2P_DEBUG
9570 if (pHostapdAdapter->device_mode == WLAN_HDD_P2P_GO)
9571 {
9572 if(globalP2PConnectionStatus == P2P_GO_NEG_COMPLETED)
9573 {
9574 globalP2PConnectionStatus = P2P_GO_COMPLETED_STATE;
9575 hddLog(LOGE,"[P2P State] From Go nego completed to "
Jeff Johnson1250df42012-12-10 14:31:52 -08009576 "Non-autonomous Group started");
Madan Mohan Koyyalamudi26bd7142012-10-30 18:14:19 -07009577 }
9578 else if(globalP2PConnectionStatus == P2P_NOT_ACTIVE)
9579 {
9580 globalP2PConnectionStatus = P2P_GO_COMPLETED_STATE;
9581 hddLog(LOGE,"[P2P State] From Inactive to "
Jeff Johnson1250df42012-12-10 14:31:52 -08009582 "Autonomous Group started");
Madan Mohan Koyyalamudi26bd7142012-10-30 18:14:19 -07009583 }
9584 }
9585#endif
9586
Jeff Johnson295189b2012-06-20 16:38:30 -07009587 pHostapdState->bCommit = TRUE;
9588 EXIT();
9589
9590 return 0;
9591}
9592
Jeff Johnson04dd8a82012-06-29 20:41:40 -07009593#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,4,0))
Mukul Sharmab0e0a982014-12-15 18:58:53 +05309594static int __wlan_hdd_cfg80211_add_beacon(struct wiphy *wiphy,
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309595 struct net_device *dev,
Jeff Johnson295189b2012-06-20 16:38:30 -07009596 struct beacon_parameters *params)
9597{
9598 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +05309599 hdd_context_t *pHddCtx;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05309600 int status;
Jeff Johnson295189b2012-06-20 16:38:30 -07009601
9602 ENTER();
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +05309603
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05309604 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
9605 TRACE_CODE_HDD_CFG80211_ADD_BEACON,
9606 pAdapter->sessionId, params->interval));
Sushant Kaushik8bc7df22014-04-09 17:55:29 +05309607 hddLog(VOS_TRACE_LEVEL_INFO_HIGH, "device mode=%s (%d)",
9608 hdd_device_modetoString(pAdapter->device_mode),
9609 pAdapter->device_mode);
Jeff Johnson295189b2012-06-20 16:38:30 -07009610
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05309611 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
9612 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05309613 if (0 != status)
Jeff Johnson04dd8a82012-06-29 20:41:40 -07009614 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05309615 return status;
Jeff Johnson04dd8a82012-06-29 20:41:40 -07009616 }
9617
Agarwal Ashish51325b52014-06-16 16:50:49 +05309618 if (vos_max_concurrent_connections_reached()) {
9619 hddLog(VOS_TRACE_LEVEL_INFO, FL("Reached max concurrent connections"));
9620 return -EINVAL;
9621 }
9622
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309623 if ( (pAdapter->device_mode == WLAN_HDD_SOFTAP)
Jeff Johnson295189b2012-06-20 16:38:30 -07009624 || (pAdapter->device_mode == WLAN_HDD_P2P_GO)
Jeff Johnson295189b2012-06-20 16:38:30 -07009625 )
9626 {
9627 beacon_data_t *old,*new;
9628
9629 old = pAdapter->sessionCtx.ap.beacon;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309630
Jeff Johnson295189b2012-06-20 16:38:30 -07009631 if (old)
c_hpothu6ff1c3c2013-10-01 19:01:57 +05309632 {
9633 hddLog(VOS_TRACE_LEVEL_WARN,
9634 FL("already beacon info added to session(%d)"),
9635 pAdapter->sessionId);
Jeff Johnson295189b2012-06-20 16:38:30 -07009636 return -EALREADY;
c_hpothu6ff1c3c2013-10-01 19:01:57 +05309637 }
Jeff Johnson295189b2012-06-20 16:38:30 -07009638
9639 status = wlan_hdd_cfg80211_alloc_new_beacon(pAdapter,&new,params);
9640
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309641 if(status != VOS_STATUS_SUCCESS)
Jeff Johnson295189b2012-06-20 16:38:30 -07009642 {
9643 hddLog(VOS_TRACE_LEVEL_FATAL,
Arif Hussain6d2a3322013-11-17 19:50:10 -08009644 "%s:Error!!! Allocating the new beacon",__func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07009645 return -EINVAL;
9646 }
9647
9648 pAdapter->sessionCtx.ap.beacon = new;
9649
9650 status = wlan_hdd_cfg80211_start_bss(pAdapter, params);
9651 }
9652
9653 EXIT();
9654 return status;
9655}
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309656
Mukul Sharmab0e0a982014-12-15 18:58:53 +05309657static int wlan_hdd_cfg80211_add_beacon(struct wiphy *wiphy,
9658 struct net_device *dev,
9659 struct beacon_parameters *params)
9660{
9661 int ret;
9662
9663 vos_ssr_protect(__func__);
9664 ret = __wlan_hdd_cfg80211_add_beacon(wiphy, dev, params);
9665 vos_ssr_unprotect(__func__);
9666
9667 return ret;
9668}
9669
9670static int __wlan_hdd_cfg80211_set_beacon(struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -07009671 struct net_device *dev,
9672 struct beacon_parameters *params)
9673{
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309674 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +05309675 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
9676 hdd_context_t *pHddCtx;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05309677 int status;
Jeff Johnson295189b2012-06-20 16:38:30 -07009678
9679 ENTER();
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05309680
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +05309681 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
9682 TRACE_CODE_HDD_CFG80211_SET_BEACON,
9683 pAdapter->sessionId, pHddStaCtx->conn_info.authType));
9684 hddLog(VOS_TRACE_LEVEL_INFO, "%s: device_mode = %s (%d)",
9685 __func__, hdd_device_modetoString(pAdapter->device_mode),
9686 pAdapter->device_mode);
9687
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05309688 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
9689 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05309690 if (0 != status)
Jeff Johnson04dd8a82012-06-29 20:41:40 -07009691 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05309692 return status;
Jeff Johnson04dd8a82012-06-29 20:41:40 -07009693 }
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +05309694
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309695 if ((pAdapter->device_mode == WLAN_HDD_SOFTAP)
Jeff Johnson295189b2012-06-20 16:38:30 -07009696 || (pAdapter->device_mode == WLAN_HDD_P2P_GO)
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309697 )
Jeff Johnson295189b2012-06-20 16:38:30 -07009698 {
9699 beacon_data_t *old,*new;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309700
Jeff Johnson295189b2012-06-20 16:38:30 -07009701 old = pAdapter->sessionCtx.ap.beacon;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309702
Jeff Johnson295189b2012-06-20 16:38:30 -07009703 if (!old)
c_hpothu6ff1c3c2013-10-01 19:01:57 +05309704 {
9705 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
9706 FL("session(%d) old and new heads points to NULL"),
9707 pAdapter->sessionId);
Jeff Johnson295189b2012-06-20 16:38:30 -07009708 return -ENOENT;
c_hpothu6ff1c3c2013-10-01 19:01:57 +05309709 }
Jeff Johnson295189b2012-06-20 16:38:30 -07009710
9711 status = wlan_hdd_cfg80211_alloc_new_beacon(pAdapter,&new,params);
9712
9713 if(status != VOS_STATUS_SUCCESS) {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309714 hddLog(VOS_TRACE_LEVEL_FATAL,
Arif Hussain6d2a3322013-11-17 19:50:10 -08009715 "%s: Error!!! Allocating the new beacon",__func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07009716 return -EINVAL;
9717 }
9718
9719 pAdapter->sessionCtx.ap.beacon = new;
9720
9721 status = wlan_hdd_cfg80211_start_bss(pAdapter, params);
9722 }
9723
9724 EXIT();
9725 return status;
9726}
9727
Mukul Sharmab0e0a982014-12-15 18:58:53 +05309728static int wlan_hdd_cfg80211_set_beacon(struct wiphy *wiphy,
9729 struct net_device *dev,
9730 struct beacon_parameters *params)
9731{
9732 int ret;
9733
9734 vos_ssr_protect(__func__);
9735 ret = __wlan_hdd_cfg80211_set_beacon(wiphy, dev, params);
9736 vos_ssr_unprotect(__func__);
9737
9738 return ret;
9739}
9740
Jeff Johnson04dd8a82012-06-29 20:41:40 -07009741#endif //(LINUX_VERSION_CODE < KERNEL_VERSION(3,4,0))
9742
9743#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,4,0))
Mukul Sharmab0e0a982014-12-15 18:58:53 +05309744static int __wlan_hdd_cfg80211_del_beacon(struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -07009745 struct net_device *dev)
Jeff Johnson04dd8a82012-06-29 20:41:40 -07009746#else
Mukul Sharmab0e0a982014-12-15 18:58:53 +05309747static int __wlan_hdd_cfg80211_stop_ap (struct wiphy *wiphy,
Jeff Johnson04dd8a82012-06-29 20:41:40 -07009748 struct net_device *dev)
9749#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07009750{
9751 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
Jeff Johnsone7245742012-09-05 17:12:55 -07009752 hdd_context_t *pHddCtx = NULL;
9753 hdd_scaninfo_t *pScanInfo = NULL;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05309754 VOS_STATUS status;
Mahesh A Saptasagar2395ee62014-05-21 19:12:21 +05309755 long ret;
Jeff Johnson295189b2012-06-20 16:38:30 -07009756
9757 ENTER();
9758
9759 if (NULL == pAdapter)
9760 {
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +05309761 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07009762 "%s: HDD adapter context is Null", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07009763 return -ENODEV;
9764 }
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -07009765
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05309766 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
9767 TRACE_CODE_HDD_CFG80211_STOP_AP,
9768 pAdapter->sessionId, pAdapter->device_mode));
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05309769 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
9770 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05309771 if (0 != status)
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -07009772 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05309773 return status;
Jeff Johnson4416a782013-03-25 14:17:50 -07009774 }
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -07009775
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -07009776 pScanInfo = &pHddCtx->scan_info;
9777
Sushant Kaushik8bc7df22014-04-09 17:55:29 +05309778 hddLog(VOS_TRACE_LEVEL_INFO, "%s: device_mode = %s (%d)",
9779 __func__, hdd_device_modetoString(pAdapter->device_mode),
9780 pAdapter->device_mode);
Jeff Johnson295189b2012-06-20 16:38:30 -07009781
Mahesh A Saptasagar2395ee62014-05-21 19:12:21 +05309782 ret = wlan_hdd_scan_abort(pAdapter);
9783
Girish Gowli4bf7a632014-06-12 13:42:11 +05309784 if (ret < 0)
Jeff Johnsone7245742012-09-05 17:12:55 -07009785 {
Mahesh A Saptasagar2395ee62014-05-21 19:12:21 +05309786 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
9787 FL("Timeout occurred while waiting for abortscan %ld"), ret);
c_hpothu6ff1c3c2013-10-01 19:01:57 +05309788
Mahesh A Saptasagar2395ee62014-05-21 19:12:21 +05309789 if (pHddCtx->isLogpInProgress)
Jeff Johnsone7245742012-09-05 17:12:55 -07009790 {
Mahesh A Saptasagar2395ee62014-05-21 19:12:21 +05309791 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
9792 "%s: LOGP in Progress. Ignore!!!", __func__);
Yue Ma4f55ef32014-01-23 16:45:33 -08009793
Jeff Johnsone7245742012-09-05 17:12:55 -07009794 VOS_ASSERT(pScanInfo->mScanPending);
Mahesh A Saptasagar2395ee62014-05-21 19:12:21 +05309795 return -EAGAIN;
Jeff Johnsone7245742012-09-05 17:12:55 -07009796 }
Mahesh A Saptasagar2395ee62014-05-21 19:12:21 +05309797 VOS_ASSERT(pScanInfo->mScanPending);
Jeff Johnsone7245742012-09-05 17:12:55 -07009798 }
9799
Rashmi Ramanna1f0948d2014-08-28 15:33:48 +05309800 /* Delete all associated STAs before stopping AP/P2P GO */
9801 hdd_del_all_sta(pAdapter);
Arun Kumar Khandavallia3bd8002014-01-17 16:21:19 +05309802 hdd_hostapd_stop(dev);
9803
Jeff Johnson295189b2012-06-20 16:38:30 -07009804 if ((pAdapter->device_mode == WLAN_HDD_SOFTAP)
Jeff Johnson295189b2012-06-20 16:38:30 -07009805 || (pAdapter->device_mode == WLAN_HDD_P2P_GO)
Jeff Johnson295189b2012-06-20 16:38:30 -07009806 )
9807 {
9808 beacon_data_t *old;
9809
9810 old = pAdapter->sessionCtx.ap.beacon;
9811
9812 if (!old)
c_hpothu6ff1c3c2013-10-01 19:01:57 +05309813 {
9814 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
9815 FL("session(%d) beacon data points to NULL"),
9816 pAdapter->sessionId);
Jeff Johnson295189b2012-06-20 16:38:30 -07009817 return -ENOENT;
c_hpothu6ff1c3c2013-10-01 19:01:57 +05309818 }
Jeff Johnson295189b2012-06-20 16:38:30 -07009819
Jeff Johnson295189b2012-06-20 16:38:30 -07009820 hdd_cleanup_actionframe(pHddCtx, pAdapter);
Jeff Johnson295189b2012-06-20 16:38:30 -07009821
9822 mutex_lock(&pHddCtx->sap_lock);
9823 if(test_bit(SOFTAP_BSS_STARTED, &pAdapter->event_flags))
9824 {
Jeff Johnson4416a782013-03-25 14:17:50 -07009825 if ( VOS_STATUS_SUCCESS == (status = WLANSAP_StopBss(pHddCtx->pvosContext) ) )
Jeff Johnson295189b2012-06-20 16:38:30 -07009826 {
9827 hdd_hostapd_state_t *pHostapdState = WLAN_HDD_GET_HOSTAP_STATE_PTR(pAdapter);
9828
9829 status = vos_wait_single_event(&pHostapdState->vosEvent, 10000);
9830
9831 if (!VOS_IS_STATUS_SUCCESS(status))
9832 {
9833 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Arif Hussain6d2a3322013-11-17 19:50:10 -08009834 ("ERROR: HDD vos wait for single_event failed!!"));
Jeff Johnson295189b2012-06-20 16:38:30 -07009835 VOS_ASSERT(0);
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05309836 }
9837 }
Jeff Johnson295189b2012-06-20 16:38:30 -07009838 clear_bit(SOFTAP_BSS_STARTED, &pAdapter->event_flags);
Agarwal Ashish51325b52014-06-16 16:50:49 +05309839 /* BSS stopped, clear the active sessions for this device mode */
9840 wlan_hdd_decr_active_session(pHddCtx, pAdapter->device_mode);
Jeff Johnson295189b2012-06-20 16:38:30 -07009841 }
9842 mutex_unlock(&pHddCtx->sap_lock);
9843
9844 if(status != VOS_STATUS_SUCCESS)
9845 {
9846 hddLog(VOS_TRACE_LEVEL_FATAL,
Arif Hussain6d2a3322013-11-17 19:50:10 -08009847 "%s:Error!!! Stopping the BSS",__func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07009848 return -EINVAL;
9849 }
9850
Jeff Johnson4416a782013-03-25 14:17:50 -07009851 if (ccmCfgSetInt(pHddCtx->hHal,
Jeff Johnson295189b2012-06-20 16:38:30 -07009852 WNI_CFG_PROBE_RSP_BCN_ADDNIE_FLAG, 0,NULL, eANI_BOOLEAN_FALSE)
9853 ==eHAL_STATUS_FAILURE)
9854 {
9855 hddLog(LOGE,
Arif Hussain6d2a3322013-11-17 19:50:10 -08009856 "Could not pass on WNI_CFG_PROBE_RSP_BCN_ADDNIE_FLAG to CCM");
Jeff Johnson295189b2012-06-20 16:38:30 -07009857 }
9858
Jeff Johnson4416a782013-03-25 14:17:50 -07009859 if ( eHAL_STATUS_FAILURE == ccmCfgSetInt(pHddCtx->hHal,
Jeff Johnson295189b2012-06-20 16:38:30 -07009860 WNI_CFG_ASSOC_RSP_ADDNIE_FLAG, 0, NULL,
9861 eANI_BOOLEAN_FALSE) )
9862 {
9863 hddLog(LOGE,
Arif Hussain6d2a3322013-11-17 19:50:10 -08009864 "Could not pass on WNI_CFG_ASSOC_RSP_ADDNIE_FLAG to CCM");
Jeff Johnson295189b2012-06-20 16:38:30 -07009865 }
9866
9867 // Reset WNI_CFG_PROBE_RSP Flags
9868 wlan_hdd_reset_prob_rspies(pAdapter);
9869
9870 pAdapter->sessionCtx.ap.beacon = NULL;
9871 kfree(old);
Madan Mohan Koyyalamudi26bd7142012-10-30 18:14:19 -07009872#ifdef WLAN_FEATURE_P2P_DEBUG
9873 if((pAdapter->device_mode == WLAN_HDD_P2P_GO) &&
9874 (globalP2PConnectionStatus == P2P_GO_COMPLETED_STATE))
9875 {
9876 hddLog(LOGE,"[P2P State] From GO completed to Inactive state "
9877 "GO got removed");
9878 globalP2PConnectionStatus = P2P_NOT_ACTIVE;
9879 }
9880#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07009881 }
9882 EXIT();
9883 return status;
9884}
Jeff Johnson04dd8a82012-06-29 20:41:40 -07009885
Mukul Sharmab0e0a982014-12-15 18:58:53 +05309886#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,4,0))
9887static int wlan_hdd_cfg80211_del_beacon(struct wiphy *wiphy,
9888 struct net_device *dev)
9889{
9890 int ret;
9891
9892 vos_ssr_protect(__func__);
9893 ret = __wlan_hdd_cfg80211_del_beacon(wiphy, dev);
9894 vos_ssr_unprotect(__func__);
9895
9896 return ret;
9897}
9898#else
9899static int wlan_hdd_cfg80211_stop_ap(struct wiphy *wiphy,
9900 struct net_device *dev)
9901{
9902 int ret;
9903
9904 vos_ssr_protect(__func__);
9905 ret = __wlan_hdd_cfg80211_stop_ap(wiphy, dev);
9906 vos_ssr_unprotect(__func__);
9907
9908 return ret;
9909}
9910#endif
9911
Jeff Johnson04dd8a82012-06-29 20:41:40 -07009912#if (LINUX_VERSION_CODE > KERNEL_VERSION(3,3,0))
9913
Mukul Sharmab0e0a982014-12-15 18:58:53 +05309914static int __wlan_hdd_cfg80211_start_ap(struct wiphy *wiphy,
Pratik Bhalgata0c7f262012-11-22 17:40:24 +05309915 struct net_device *dev,
Jeff Johnson04dd8a82012-06-29 20:41:40 -07009916 struct cfg80211_ap_settings *params)
9917{
Pratik Bhalgata0c7f262012-11-22 17:40:24 +05309918 hdd_adapter_t *pAdapter;
9919 hdd_context_t *pHddCtx;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05309920 int status;
Jeff Johnson04dd8a82012-06-29 20:41:40 -07009921
9922 ENTER();
9923
Girish Gowlib143d7a2015-02-18 19:39:55 +05309924 if (NULL == dev || NULL == params)
Madan Mohan Koyyalamudib2c36892012-10-18 20:52:38 -07009925 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05309926 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Girish Gowlib143d7a2015-02-18 19:39:55 +05309927 "%s: Device or params is Null", __func__);
Pratik Bhalgata0c7f262012-11-22 17:40:24 +05309928 return -ENODEV;
9929 }
9930
9931 pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
9932 if (NULL == pAdapter)
9933 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05309934 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Pratik Bhalgata0c7f262012-11-22 17:40:24 +05309935 "%s: HDD adapter is Null", __func__);
9936 return -ENODEV;
9937 }
9938
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05309939 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
9940 TRACE_CODE_HDD_CFG80211_START_AP, pAdapter->sessionId,
9941 params-> beacon_interval));
Pratik Bhalgata0c7f262012-11-22 17:40:24 +05309942 if (WLAN_HDD_ADAPTER_MAGIC != pAdapter->magic)
9943 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05309944 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Pratik Bhalgata0c7f262012-11-22 17:40:24 +05309945 "%s: HDD adapter magic is invalid", __func__);
9946 return -ENODEV;
9947 }
9948
9949 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05309950 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05309951 if (0 != status)
Pratik Bhalgata0c7f262012-11-22 17:40:24 +05309952 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05309953 return status;
Pratik Bhalgata0c7f262012-11-22 17:40:24 +05309954 }
9955
Sushant Kaushik8bc7df22014-04-09 17:55:29 +05309956 hddLog(VOS_TRACE_LEVEL_INFO_HIGH, "%s: device mode = %s (%d)",
9957 __func__, hdd_device_modetoString(pAdapter->device_mode),
9958 pAdapter->device_mode);
Pratik Bhalgata0c7f262012-11-22 17:40:24 +05309959
9960 if ((pAdapter->device_mode == WLAN_HDD_SOFTAP)
Jeff Johnson04dd8a82012-06-29 20:41:40 -07009961 || (pAdapter->device_mode == WLAN_HDD_P2P_GO)
Jeff Johnson04dd8a82012-06-29 20:41:40 -07009962 )
9963 {
Pratik Bhalgata0c7f262012-11-22 17:40:24 +05309964 beacon_data_t *old, *new;
Jeff Johnson04dd8a82012-06-29 20:41:40 -07009965
9966 old = pAdapter->sessionCtx.ap.beacon;
Pratik Bhalgata0c7f262012-11-22 17:40:24 +05309967
Jeff Johnson04dd8a82012-06-29 20:41:40 -07009968 if (old)
c_hpothu6ff1c3c2013-10-01 19:01:57 +05309969 {
9970 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_WARN,
9971 FL("already beacon info added to session(%d)"),
9972 pAdapter->sessionId);
Jeff Johnson04dd8a82012-06-29 20:41:40 -07009973 return -EALREADY;
c_hpothu6ff1c3c2013-10-01 19:01:57 +05309974 }
Jeff Johnson04dd8a82012-06-29 20:41:40 -07009975
Girish Gowlib143d7a2015-02-18 19:39:55 +05309976#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,4,0))
9977 status = wlan_hdd_cfg80211_alloc_new_beacon(pAdapter,
9978 &new,
9979 &params->beacon);
9980#else
9981 status = wlan_hdd_cfg80211_alloc_new_beacon(pAdapter,
9982 &new,
9983 &params->beacon,
9984 params->dtim_period);
9985#endif
Jeff Johnson04dd8a82012-06-29 20:41:40 -07009986
Pratik Bhalgata0c7f262012-11-22 17:40:24 +05309987 if (status != 0)
Jeff Johnson04dd8a82012-06-29 20:41:40 -07009988 {
9989 hddLog(VOS_TRACE_LEVEL_FATAL,
Pratik Bhalgata0c7f262012-11-22 17:40:24 +05309990 "%s:Error!!! Allocating the new beacon", __func__);
Jeff Johnson04dd8a82012-06-29 20:41:40 -07009991 return -EINVAL;
9992 }
9993 pAdapter->sessionCtx.ap.beacon = new;
Viral Modi3a32cc52013-02-08 11:14:52 -08009994#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,6,0))
Yue Maf49ba872013-08-19 12:04:25 -07009995 wlan_hdd_cfg80211_set_channel(wiphy, dev,
9996#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,8,0))
9997 params->channel, params->channel_type);
9998#else
9999 params->chandef.chan, cfg80211_get_chandef_type(&(params->chandef)));
10000#endif
Viral Modi3a32cc52013-02-08 11:14:52 -080010001#endif
Jeff Johnson04dd8a82012-06-29 20:41:40 -070010002 status = wlan_hdd_cfg80211_start_bss(pAdapter, &params->beacon, params->ssid,
Kanchanapally, Vidyullathaacc59252015-05-20 16:49:07 +053010003 params->ssid_len, params->hidden_ssid,
10004 params->auth_type);
Jeff Johnson04dd8a82012-06-29 20:41:40 -070010005 }
10006
10007 EXIT();
10008 return status;
10009}
10010
Mukul Sharmab0e0a982014-12-15 18:58:53 +053010011static int wlan_hdd_cfg80211_start_ap(struct wiphy *wiphy,
10012 struct net_device *dev,
10013 struct cfg80211_ap_settings *params)
10014{
10015 int ret;
Jeff Johnson04dd8a82012-06-29 20:41:40 -070010016
Mukul Sharmab0e0a982014-12-15 18:58:53 +053010017 vos_ssr_protect(__func__);
10018 ret = __wlan_hdd_cfg80211_start_ap(wiphy, dev, params);
10019 vos_ssr_unprotect(__func__);
10020
10021 return ret;
10022}
10023
10024static int __wlan_hdd_cfg80211_change_beacon(struct wiphy *wiphy,
Jeff Johnson04dd8a82012-06-29 20:41:40 -070010025 struct net_device *dev,
10026 struct cfg80211_beacon_data *params)
10027{
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010028 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053010029 hdd_context_t *pHddCtx;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053010030 int status;
Jeff Johnson04dd8a82012-06-29 20:41:40 -070010031
10032 ENTER();
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053010033
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053010034 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
10035 TRACE_CODE_HDD_CFG80211_CHANGE_BEACON,
10036 pAdapter->sessionId, pAdapter->device_mode));
Arif Hussain6d2a3322013-11-17 19:50:10 -080010037 hddLog(VOS_TRACE_LEVEL_INFO, "%s: device_mode = %d",
Jeff Johnson04dd8a82012-06-29 20:41:40 -070010038 __func__, pAdapter->device_mode);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053010039
10040 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
10041 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053010042 if (0 != status)
Madan Mohan Koyyalamudib2c36892012-10-18 20:52:38 -070010043 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053010044 return status;
Madan Mohan Koyyalamudib2c36892012-10-18 20:52:38 -070010045 }
Jeff Johnson04dd8a82012-06-29 20:41:40 -070010046
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010047 if ((pAdapter->device_mode == WLAN_HDD_SOFTAP)
Jeff Johnson04dd8a82012-06-29 20:41:40 -070010048 || (pAdapter->device_mode == WLAN_HDD_P2P_GO)
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010049 )
Jeff Johnson04dd8a82012-06-29 20:41:40 -070010050 {
10051 beacon_data_t *old,*new;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010052
Jeff Johnson04dd8a82012-06-29 20:41:40 -070010053 old = pAdapter->sessionCtx.ap.beacon;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010054
Jeff Johnson04dd8a82012-06-29 20:41:40 -070010055 if (!old)
c_hpothu6ff1c3c2013-10-01 19:01:57 +053010056 {
10057 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
10058 FL("session(%d) beacon data points to NULL"),
10059 pAdapter->sessionId);
Jeff Johnson04dd8a82012-06-29 20:41:40 -070010060 return -ENOENT;
c_hpothu6ff1c3c2013-10-01 19:01:57 +053010061 }
Jeff Johnson04dd8a82012-06-29 20:41:40 -070010062
10063 status = wlan_hdd_cfg80211_alloc_new_beacon(pAdapter, &new, params, 0);
10064
10065 if(status != VOS_STATUS_SUCCESS) {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010066 hddLog(VOS_TRACE_LEVEL_FATAL,
Arif Hussain6d2a3322013-11-17 19:50:10 -080010067 "%s: Error!!! Allocating the new beacon",__func__);
Jeff Johnson04dd8a82012-06-29 20:41:40 -070010068 return -EINVAL;
10069 }
10070
10071 pAdapter->sessionCtx.ap.beacon = new;
10072
Kanchanapally, Vidyullathaacc59252015-05-20 16:49:07 +053010073 status = wlan_hdd_cfg80211_start_bss(pAdapter, params, NULL, 0, 0,
10074 pAdapter->sessionCtx.ap.sapConfig.authType);
Jeff Johnson04dd8a82012-06-29 20:41:40 -070010075 }
10076
10077 EXIT();
10078 return status;
10079}
10080
Mukul Sharmab0e0a982014-12-15 18:58:53 +053010081static int wlan_hdd_cfg80211_change_beacon(struct wiphy *wiphy,
10082 struct net_device *dev,
10083 struct cfg80211_beacon_data *params)
10084{
10085 int ret;
Jeff Johnson04dd8a82012-06-29 20:41:40 -070010086
Mukul Sharmab0e0a982014-12-15 18:58:53 +053010087 vos_ssr_protect(__func__);
10088 ret = __wlan_hdd_cfg80211_change_beacon(wiphy, dev, params);
10089 vos_ssr_unprotect(__func__);
10090
10091 return ret;
10092}
10093
10094#endif //(LINUX_VERSION_CODE > KERNEL_VERSION(3,3,0))
Jeff Johnson295189b2012-06-20 16:38:30 -070010095
Mahesh A Saptasagar179d2252014-06-02 21:32:21 +053010096static int __wlan_hdd_cfg80211_change_bss (struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -070010097 struct net_device *dev,
10098 struct bss_parameters *params)
10099{
10100 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +053010101 hdd_context_t *pHddCtx;
10102 int ret = 0;
Jeff Johnson295189b2012-06-20 16:38:30 -070010103
10104 ENTER();
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053010105
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +053010106 if (NULL == pAdapter)
10107 {
10108 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
10109 "%s: HDD adapter is Null", __func__);
10110 return -ENODEV;
10111 }
10112 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +053010113 ret = wlan_hdd_validate_context(pHddCtx);
10114 if (0 != ret)
10115 {
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +053010116 return ret;
10117 }
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053010118 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
10119 TRACE_CODE_HDD_CFG80211_CHANGE_BSS,
10120 pAdapter->sessionId, params->ap_isolate));
Sushant Kaushik8bc7df22014-04-09 17:55:29 +053010121 hddLog(VOS_TRACE_LEVEL_INFO, "%s: device_mode = %s (%d)",
10122 __func__, hdd_device_modetoString(pAdapter->device_mode),
10123 pAdapter->device_mode);
Jeff Johnson295189b2012-06-20 16:38:30 -070010124
10125 if((pAdapter->device_mode == WLAN_HDD_SOFTAP)
Jeff Johnson295189b2012-06-20 16:38:30 -070010126 || (pAdapter->device_mode == WLAN_HDD_P2P_GO)
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010127 )
Jeff Johnson295189b2012-06-20 16:38:30 -070010128 {
10129 /* ap_isolate == -1 means that in change bss, upper layer doesn't
10130 * want to update this parameter */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010131 if (-1 != params->ap_isolate)
Jeff Johnson295189b2012-06-20 16:38:30 -070010132 {
10133 pAdapter->sessionCtx.ap.apDisableIntraBssFwd = !!params->ap_isolate;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010134 }
Jeff Johnson295189b2012-06-20 16:38:30 -070010135 }
10136
10137 EXIT();
10138 return 0;
10139}
10140
Mahesh A Saptasagar179d2252014-06-02 21:32:21 +053010141static int wlan_hdd_cfg80211_change_bss (struct wiphy *wiphy,
10142 struct net_device *dev,
10143 struct bss_parameters *params)
10144{
10145 int ret;
10146
10147 vos_ssr_protect(__func__);
10148 ret = __wlan_hdd_cfg80211_change_bss(wiphy, dev, params);
10149 vos_ssr_unprotect(__func__);
10150
10151 return ret;
10152}
Kiet Lam10841362013-11-01 11:36:50 +053010153/* FUNCTION: wlan_hdd_change_country_code_cd
10154* to wait for contry code completion
10155*/
10156void* wlan_hdd_change_country_code_cb(void *pAdapter)
10157{
10158 hdd_adapter_t *call_back_pAdapter = pAdapter;
10159 complete(&call_back_pAdapter->change_country_code);
10160 return NULL;
10161}
10162
Jeff Johnson295189b2012-06-20 16:38:30 -070010163/*
Mahesh A Saptasagar0e59c472014-04-14 19:17:41 +053010164 * FUNCTION: __wlan_hdd_cfg80211_change_iface
Jeff Johnson295189b2012-06-20 16:38:30 -070010165 * This function is used to set the interface type (INFRASTRUCTURE/ADHOC)
10166 */
Mahesh A Saptasagar0e59c472014-04-14 19:17:41 +053010167int __wlan_hdd_cfg80211_change_iface( struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -070010168 struct net_device *ndev,
10169 enum nl80211_iftype type,
10170 u32 *flags,
10171 struct vif_params *params
10172 )
10173{
10174 struct wireless_dev *wdev;
10175 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( ndev );
Rajesh Chauhana0516c62014-01-30 16:11:18 -080010176 hdd_context_t *pHddCtx;
Mohit Khanna0f232092012-09-11 14:46:08 -070010177 hdd_adapter_t *pP2pAdapter = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -070010178 tCsrRoamProfile *pRoamProfile = NULL;
10179 eCsrRoamBssType LastBSSType;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053010180 hdd_config_t *pConfig = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -070010181 eMib_dot11DesiredBssType connectedBssType;
10182 VOS_STATUS status;
c_hpothu6ff1c3c2013-10-01 19:01:57 +053010183 long ret;
Jeff Johnson295189b2012-06-20 16:38:30 -070010184
10185 ENTER();
10186
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053010187 if (!pAdapter)
Rajesh Chauhana0516c62014-01-30 16:11:18 -080010188 {
10189 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
10190 "%s: Adapter context is null", __func__);
10191 return VOS_STATUS_E_FAILURE;
10192 }
10193
10194 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
10195 if (!pHddCtx)
10196 {
10197 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
10198 "%s: HDD context is null", __func__);
10199 return VOS_STATUS_E_FAILURE;
10200 }
10201
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053010202 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
10203 TRACE_CODE_HDD_CFG80211_CHANGE_IFACE,
10204 pAdapter->sessionId, type));
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053010205 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053010206 if (0 != status)
Jeff Johnson295189b2012-06-20 16:38:30 -070010207 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053010208 return status;
Jeff Johnson295189b2012-06-20 16:38:30 -070010209 }
10210
Sushant Kaushik8bc7df22014-04-09 17:55:29 +053010211 hddLog(VOS_TRACE_LEVEL_INFO, "%s: device_mode = %s (%d)",
10212 __func__, hdd_device_modetoString(pAdapter->device_mode),
10213 pAdapter->device_mode);
Jeff Johnson295189b2012-06-20 16:38:30 -070010214
Agarwal Ashish51325b52014-06-16 16:50:49 +053010215 if (vos_max_concurrent_connections_reached()) {
10216 hddLog(VOS_TRACE_LEVEL_INFO, FL("Reached max concurrent connections"));
10217 return -EINVAL;
10218 }
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053010219 pConfig = pHddCtx->cfg_ini;
Jeff Johnson295189b2012-06-20 16:38:30 -070010220 wdev = ndev->ieee80211_ptr;
10221
10222#ifdef WLAN_BTAMP_FEATURE
10223 if((NL80211_IFTYPE_P2P_CLIENT == type)||
10224 (NL80211_IFTYPE_ADHOC == type)||
10225 (NL80211_IFTYPE_AP == type)||
10226 (NL80211_IFTYPE_P2P_GO == type))
10227 {
10228 pHddCtx->isAmpAllowed = VOS_FALSE;
10229 // stop AMP traffic
10230 status = WLANBAP_StopAmp();
10231 if(VOS_STATUS_SUCCESS != status )
10232 {
10233 pHddCtx->isAmpAllowed = VOS_TRUE;
10234 hddLog(VOS_TRACE_LEVEL_FATAL,
10235 "%s: Failed to stop AMP", __func__);
10236 return -EINVAL;
10237 }
10238 }
10239#endif //WLAN_BTAMP_FEATURE
10240 /* Reset the current device mode bit mask*/
10241 wlan_hdd_clear_concurrency_mode(pHddCtx, pAdapter->device_mode);
10242
Masti, Narayanraddi575ccc72015-08-17 18:04:57 +053010243 if ((pAdapter->device_mode == WLAN_HDD_P2P_DEVICE) &&
10244 ((type == NL80211_IFTYPE_P2P_CLIENT) ||
10245 (type == NL80211_IFTYPE_P2P_GO)))
10246 {
10247 /* Notify Mode change in case of concurrency.
10248 * Below function invokes TDLS teardown Functionality Since TDLS is
10249 * not Supported in case of concurrency i.e Once P2P session
10250 * is detected disable offchannel and teardown TDLS links
10251 */
10252 hddLog(LOG1,
10253 FL("Device mode = %d Interface type = %d"),
10254 pAdapter->device_mode, type);
10255 hdd_tdls_notify_mode_change(pAdapter, pHddCtx);
10256 }
Masti, Narayanraddifdde4d02015-04-16 14:41:51 +053010257
Jeff Johnson295189b2012-06-20 16:38:30 -070010258 if( (pAdapter->device_mode == WLAN_HDD_INFRA_STATION)
Jeff Johnson295189b2012-06-20 16:38:30 -070010259 || (pAdapter->device_mode == WLAN_HDD_P2P_CLIENT)
Jeff Johnsone7245742012-09-05 17:12:55 -070010260 || (pAdapter->device_mode == WLAN_HDD_P2P_DEVICE)
Jeff Johnson295189b2012-06-20 16:38:30 -070010261 )
10262 {
10263 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
Rajesh Chauhana0516c62014-01-30 16:11:18 -080010264 if (!pWextState)
10265 {
10266 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
10267 "%s: pWextState is null", __func__);
10268 return VOS_STATUS_E_FAILURE;
10269 }
Jeff Johnson295189b2012-06-20 16:38:30 -070010270 pRoamProfile = &pWextState->roamProfile;
10271 LastBSSType = pRoamProfile->BSSType;
10272
10273 switch (type)
10274 {
10275 case NL80211_IFTYPE_STATION:
Jeff Johnson295189b2012-06-20 16:38:30 -070010276 case NL80211_IFTYPE_P2P_CLIENT:
Jeff Johnson295189b2012-06-20 16:38:30 -070010277 hddLog(VOS_TRACE_LEVEL_INFO,
10278 "%s: setting interface Type to INFRASTRUCTURE", __func__);
10279 pRoamProfile->BSSType = eCSR_BSS_TYPE_INFRASTRUCTURE;
Jeff Johnsone7245742012-09-05 17:12:55 -070010280#ifdef WLAN_FEATURE_11AC
10281 if(pConfig->dot11Mode == eHDD_DOT11_MODE_AUTO)
10282 {
10283 pConfig->dot11Mode = eHDD_DOT11_MODE_11ac;
10284 }
10285#endif
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010286 pRoamProfile->phyMode =
Jeff Johnsone7245742012-09-05 17:12:55 -070010287 hdd_cfg_xlate_to_csr_phy_mode(pConfig->dot11Mode);
Jeff Johnson295189b2012-06-20 16:38:30 -070010288 wdev->iftype = type;
Gopichand Nakkalaf527dc62012-12-31 16:35:10 -080010289 //Check for sub-string p2p to confirm its a p2p interface
10290 if (NULL != strstr(ndev->name,"p2p"))
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010291 {
Mahesh A Saptasagarc48ae8a2015-08-09 00:04:35 +053010292#ifdef FEATURE_WLAN_TDLS
10293 mutex_lock(&pHddCtx->tdls_lock);
10294 wlan_hdd_tdls_exit(pAdapter, TRUE);
10295 mutex_unlock(&pHddCtx->tdls_lock);
10296#endif
Gopichand Nakkala864d3552012-12-31 16:08:51 -080010297 pAdapter->device_mode = (type == NL80211_IFTYPE_STATION) ?
10298 WLAN_HDD_P2P_DEVICE : WLAN_HDD_P2P_CLIENT;
10299 }
10300 else
10301 {
10302 pAdapter->device_mode = (type == NL80211_IFTYPE_STATION) ?
Jeff Johnson295189b2012-06-20 16:38:30 -070010303 WLAN_HDD_INFRA_STATION: WLAN_HDD_P2P_CLIENT;
Gopichand Nakkala864d3552012-12-31 16:08:51 -080010304 }
Jeff Johnson295189b2012-06-20 16:38:30 -070010305 break;
Mahesh A Saptasagar36cdc802015-01-07 18:41:17 +053010306
Jeff Johnson295189b2012-06-20 16:38:30 -070010307 case NL80211_IFTYPE_ADHOC:
10308 hddLog(VOS_TRACE_LEVEL_INFO,
10309 "%s: setting interface Type to ADHOC", __func__);
10310 pRoamProfile->BSSType = eCSR_BSS_TYPE_START_IBSS;
10311 pRoamProfile->phyMode =
10312 hdd_cfg_xlate_to_csr_phy_mode(pConfig->dot11Mode);
Shailender Karmuchia734f332013-04-19 14:02:48 -070010313 pAdapter->device_mode = WLAN_HDD_IBSS;
Jeff Johnson295189b2012-06-20 16:38:30 -070010314 wdev->iftype = type;
Katya Nigam1fd24402015-02-16 14:52:19 +053010315 hdd_set_ibss_ops( pAdapter );
10316 hdd_ibss_init_tx_rx( pAdapter );
Nirav Shah7e3c8132015-06-22 23:51:42 +053010317
10318 status = hdd_sta_id_hash_attach(pAdapter);
10319 if (VOS_STATUS_SUCCESS != status) {
10320 hddLog(VOS_TRACE_LEVEL_ERROR,
10321 FL("Failed to initialize hash for IBSS"));
10322 }
Jeff Johnson295189b2012-06-20 16:38:30 -070010323 break;
10324
10325 case NL80211_IFTYPE_AP:
Jeff Johnson295189b2012-06-20 16:38:30 -070010326 case NL80211_IFTYPE_P2P_GO:
Jeff Johnson295189b2012-06-20 16:38:30 -070010327 {
10328 hddLog(VOS_TRACE_LEVEL_INFO_HIGH,
10329 "%s: setting interface Type to %s", __func__,
10330 (type == NL80211_IFTYPE_AP) ? "SoftAP" : "P2pGo");
10331
Gopichand Nakkalaf527dc62012-12-31 16:35:10 -080010332 //Cancel any remain on channel for GO mode
10333 if (NL80211_IFTYPE_P2P_GO == type)
10334 {
10335 wlan_hdd_cancel_existing_remain_on_channel(pAdapter);
10336 }
Mohit Khanna0f232092012-09-11 14:46:08 -070010337 if (NL80211_IFTYPE_AP == type)
10338 {
10339 /* As Loading WLAN Driver one interface being created for p2p device
10340 * address. This will take one HW STA and the max number of clients
10341 * that can connect to softAP will be reduced by one. so while changing
10342 * the interface type to NL80211_IFTYPE_AP (SoftAP) remove p2p0
10343 * interface as it is not required in SoftAP mode.
10344 */
10345
10346 // Get P2P Adapter
10347 pP2pAdapter = hdd_get_adapter(pHddCtx, WLAN_HDD_P2P_DEVICE);
10348
10349 if (pP2pAdapter)
10350 {
Agarwal Ashish3a38bd12014-06-12 15:16:52 +053010351 hdd_stop_adapter(pHddCtx, pP2pAdapter, VOS_TRUE);
c_hpothu002231a2015-02-05 14:58:51 +053010352 hdd_deinit_adapter(pHddCtx, pP2pAdapter, TRUE);
Mohit Khanna0f232092012-09-11 14:46:08 -070010353 hdd_close_adapter(pHddCtx, pP2pAdapter, VOS_TRUE);
10354 }
10355 }
Swaroop Goltia2e32212014-04-09 23:37:33 +053010356 //Disable IMPS & BMPS for SAP/GO
10357 if(VOS_STATUS_E_FAILURE ==
10358 hdd_disable_bmps_imps(pHddCtx, WLAN_HDD_P2P_GO))
10359 {
10360 //Fail to Exit BMPS
10361 VOS_ASSERT(0);
10362 }
Deepthi Gowri500fc472014-08-11 19:53:10 +053010363
10364 hdd_stop_adapter( pHddCtx, pAdapter, VOS_TRUE );
10365
Madan Mohan Koyyalamudi96797442013-10-08 16:04:42 +053010366#ifdef FEATURE_WLAN_TDLS
Mohit Khanna0f232092012-09-11 14:46:08 -070010367
Madan Mohan Koyyalamudi96797442013-10-08 16:04:42 +053010368 /* A Mutex Lock is introduced while changing the mode to
10369 * protect the concurrent access for the Adapters by TDLS
10370 * module.
10371 */
Rajesh Chauhana34c6e62014-03-25 16:37:58 +053010372 mutex_lock(&pHddCtx->tdls_lock);
Madan Mohan Koyyalamudi96797442013-10-08 16:04:42 +053010373#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070010374 //De-init the adapter.
c_hpothu002231a2015-02-05 14:58:51 +053010375 hdd_deinit_adapter( pHddCtx, pAdapter, TRUE);
Jeff Johnson295189b2012-06-20 16:38:30 -070010376 memset(&pAdapter->sessionCtx, 0, sizeof(pAdapter->sessionCtx));
Jeff Johnson295189b2012-06-20 16:38:30 -070010377 pAdapter->device_mode = (type == NL80211_IFTYPE_AP) ?
10378 WLAN_HDD_SOFTAP : WLAN_HDD_P2P_GO;
Madan Mohan Koyyalamudi96797442013-10-08 16:04:42 +053010379#ifdef FEATURE_WLAN_TDLS
10380 mutex_unlock(&pHddCtx->tdls_lock);
10381#endif
Madan Mohan Koyyalamudi3ff2a0b2012-10-15 14:33:46 -070010382 if ((WLAN_HDD_SOFTAP == pAdapter->device_mode) &&
10383 (pConfig->apRandomBssidEnabled))
10384 {
10385 /* To meet Android requirements create a randomized
10386 MAC address of the form 02:1A:11:Fx:xx:xx */
10387 get_random_bytes(&ndev->dev_addr[3], 3);
10388 ndev->dev_addr[0] = 0x02;
10389 ndev->dev_addr[1] = 0x1A;
10390 ndev->dev_addr[2] = 0x11;
10391 ndev->dev_addr[3] |= 0xF0;
10392 memcpy(pAdapter->macAddressCurrent.bytes, ndev->dev_addr,
10393 VOS_MAC_ADDR_SIZE);
Arif Hussain24bafea2013-11-15 15:10:03 -080010394 pr_info("wlan: Generated HotSpot BSSID " MAC_ADDRESS_STR"\n",
10395 MAC_ADDR_ARRAY(ndev->dev_addr));
Madan Mohan Koyyalamudi3ff2a0b2012-10-15 14:33:46 -070010396 }
10397
Jeff Johnson295189b2012-06-20 16:38:30 -070010398 hdd_set_ap_ops( pAdapter->dev );
10399
Kiet Lam10841362013-11-01 11:36:50 +053010400 /* This is for only SAP mode where users can
10401 * control country through ini.
10402 * P2P GO follows station country code
10403 * acquired during the STA scanning. */
10404 if((NL80211_IFTYPE_AP == type) &&
10405 (memcmp(pConfig->apCntryCode, CFG_AP_COUNTRY_CODE_DEFAULT, 3) != 0))
10406 {
10407 int status = 0;
10408 VOS_TRACE(VOS_MODULE_ID_HDD,VOS_TRACE_LEVEL_INFO,
10409 "%s: setting country code from INI ", __func__);
10410 init_completion(&pAdapter->change_country_code);
10411 status = (int)sme_ChangeCountryCode(pHddCtx->hHal,
10412 (void *)(tSmeChangeCountryCallback)
10413 wlan_hdd_change_country_code_cb,
10414 pConfig->apCntryCode, pAdapter,
10415 pHddCtx->pvosContext,
Abhishek Singha306a442013-11-07 18:39:01 +053010416 eSIR_FALSE,
10417 eSIR_TRUE);
Kiet Lam10841362013-11-01 11:36:50 +053010418 if (eHAL_STATUS_SUCCESS == status)
10419 {
10420 /* Wait for completion */
c_hpothu6ff1c3c2013-10-01 19:01:57 +053010421 ret = wait_for_completion_interruptible_timeout(
Kiet Lam10841362013-11-01 11:36:50 +053010422 &pAdapter->change_country_code,
10423 msecs_to_jiffies(WLAN_WAIT_TIME_COUNTRY));
c_hpothu6ff1c3c2013-10-01 19:01:57 +053010424 if (ret <= 0)
Kiet Lam10841362013-11-01 11:36:50 +053010425 {
10426 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
c_hpothu6ff1c3c2013-10-01 19:01:57 +053010427 FL("SME Timed out while setting country code %ld"),
10428 ret);
Yue Ma4f55ef32014-01-23 16:45:33 -080010429
10430 if (pHddCtx->isLogpInProgress)
10431 {
10432 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
10433 "%s: LOGP in Progress. Ignore!!!", __func__);
10434 return -EAGAIN;
10435 }
Kiet Lam10841362013-11-01 11:36:50 +053010436 }
10437 }
10438 else
10439 {
10440 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Arif Hussain6d2a3322013-11-17 19:50:10 -080010441 "%s: SME Change Country code failed",__func__);
Kiet Lam10841362013-11-01 11:36:50 +053010442 return -EINVAL;
10443 }
10444 }
Jeff Johnson295189b2012-06-20 16:38:30 -070010445 status = hdd_init_ap_mode(pAdapter);
10446 if(status != VOS_STATUS_SUCCESS)
10447 {
10448 hddLog(VOS_TRACE_LEVEL_FATAL,
10449 "%s: Error initializing the ap mode", __func__);
10450 return -EINVAL;
10451 }
10452 hdd_set_conparam(1);
10453
Nirav Shah7e3c8132015-06-22 23:51:42 +053010454 status = hdd_sta_id_hash_attach(pAdapter);
10455 if (VOS_STATUS_SUCCESS != status)
10456 {
10457 hddLog(VOS_TRACE_LEVEL_ERROR,
10458 FL("Failed to initialize hash for AP"));
10459 return -EINVAL;
10460 }
10461
Jeff Johnson295189b2012-06-20 16:38:30 -070010462 /*interface type changed update in wiphy structure*/
10463 if(wdev)
10464 {
10465 wdev->iftype = type;
10466 pHddCtx->change_iface = type;
10467 }
10468 else
10469 {
10470 hddLog(VOS_TRACE_LEVEL_ERROR,
10471 "%s: ERROR !!!! Wireless dev is NULL", __func__);
10472 return -EINVAL;
10473 }
10474 goto done;
10475 }
10476
10477 default:
10478 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Unsupported interface Type",
10479 __func__);
10480 return -EOPNOTSUPP;
10481 }
10482 }
10483 else if ( (pAdapter->device_mode == WLAN_HDD_SOFTAP)
Jeff Johnson295189b2012-06-20 16:38:30 -070010484 || (pAdapter->device_mode == WLAN_HDD_P2P_GO)
Jeff Johnson295189b2012-06-20 16:38:30 -070010485 )
10486 {
10487 switch(type)
10488 {
10489 case NL80211_IFTYPE_STATION:
Jeff Johnson295189b2012-06-20 16:38:30 -070010490 case NL80211_IFTYPE_P2P_CLIENT:
Jeff Johnson295189b2012-06-20 16:38:30 -070010491 case NL80211_IFTYPE_ADHOC:
Deepthi Gowri500fc472014-08-11 19:53:10 +053010492
10493 hdd_stop_adapter( pHddCtx, pAdapter, VOS_TRUE );
Madan Mohan Koyyalamudi96797442013-10-08 16:04:42 +053010494#ifdef FEATURE_WLAN_TDLS
10495
10496 /* A Mutex Lock is introduced while changing the mode to
10497 * protect the concurrent access for the Adapters by TDLS
10498 * module.
10499 */
Rajesh Chauhana34c6e62014-03-25 16:37:58 +053010500 mutex_lock(&pHddCtx->tdls_lock);
Madan Mohan Koyyalamudi96797442013-10-08 16:04:42 +053010501#endif
c_hpothu002231a2015-02-05 14:58:51 +053010502 hdd_deinit_adapter( pHddCtx, pAdapter, TRUE);
Jeff Johnson295189b2012-06-20 16:38:30 -070010503 wdev->iftype = type;
Gopichand Nakkalaf527dc62012-12-31 16:35:10 -080010504 //Check for sub-string p2p to confirm its a p2p interface
10505 if (NULL != strstr(ndev->name,"p2p"))
Gopichand Nakkala864d3552012-12-31 16:08:51 -080010506 {
10507 pAdapter->device_mode = (type == NL80211_IFTYPE_STATION) ?
10508 WLAN_HDD_P2P_DEVICE : WLAN_HDD_P2P_CLIENT;
10509 }
10510 else
10511 {
10512 pAdapter->device_mode = (type == NL80211_IFTYPE_STATION) ?
Jeff Johnson295189b2012-06-20 16:38:30 -070010513 WLAN_HDD_INFRA_STATION: WLAN_HDD_P2P_CLIENT;
Gopichand Nakkala864d3552012-12-31 16:08:51 -080010514 }
Jeff Johnson295189b2012-06-20 16:38:30 -070010515 hdd_set_conparam(0);
10516 pHddCtx->change_iface = type;
Jeff Johnson295189b2012-06-20 16:38:30 -070010517 memset(&pAdapter->sessionCtx, 0, sizeof(pAdapter->sessionCtx));
10518 hdd_set_station_ops( pAdapter->dev );
Madan Mohan Koyyalamudi96797442013-10-08 16:04:42 +053010519#ifdef FEATURE_WLAN_TDLS
10520 mutex_unlock(&pHddCtx->tdls_lock);
10521#endif
Sunil Dutt66485cb2013-12-19 19:05:03 +053010522 status = hdd_init_station_mode( pAdapter );
Jeff Johnson295189b2012-06-20 16:38:30 -070010523 if( VOS_STATUS_SUCCESS != status )
10524 return -EOPNOTSUPP;
Jeff Johnsone7245742012-09-05 17:12:55 -070010525 /* In case of JB, for P2P-GO, only change interface will be called,
10526 * This is the right place to enable back bmps_imps()
10527 */
Gopichand Nakkalaa2fe5b02013-06-06 16:32:28 +053010528 if (pHddCtx->hdd_wlan_suspended)
10529 {
10530 hdd_set_pwrparams(pHddCtx);
10531 }
Jeff Johnsone7245742012-09-05 17:12:55 -070010532 hdd_enable_bmps_imps(pHddCtx);
Jeff Johnson295189b2012-06-20 16:38:30 -070010533 goto done;
10534 case NL80211_IFTYPE_AP:
Jeff Johnson295189b2012-06-20 16:38:30 -070010535 case NL80211_IFTYPE_P2P_GO:
Jeff Johnson295189b2012-06-20 16:38:30 -070010536 wdev->iftype = type;
Jeff Johnson295189b2012-06-20 16:38:30 -070010537 pAdapter->device_mode = (type == NL80211_IFTYPE_AP) ?
10538 WLAN_HDD_SOFTAP : WLAN_HDD_P2P_GO;
Jeff Johnson295189b2012-06-20 16:38:30 -070010539 goto done;
10540 default:
10541 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Unsupported interface Type",
10542 __func__);
10543 return -EOPNOTSUPP;
10544
10545 }
10546
10547 }
10548 else
10549 {
Sushant Kaushik8bc7df22014-04-09 17:55:29 +053010550 hddLog(VOS_TRACE_LEVEL_ERROR,"%s: unsupported device mode(%s (%d))",
10551 __func__, hdd_device_modetoString(pAdapter->device_mode),
10552 pAdapter->device_mode);
Jeff Johnson295189b2012-06-20 16:38:30 -070010553 return -EOPNOTSUPP;
10554 }
10555
10556
10557 if(pRoamProfile)
10558 {
10559 if ( LastBSSType != pRoamProfile->BSSType )
10560 {
10561 /*interface type changed update in wiphy structure*/
10562 wdev->iftype = type;
10563
10564 /*the BSS mode changed, We need to issue disconnect
10565 if connected or in IBSS disconnect state*/
10566 if ( hdd_connGetConnectedBssType(
10567 WLAN_HDD_GET_STATION_CTX_PTR(pAdapter), &connectedBssType ) ||
10568 ( eCSR_BSS_TYPE_START_IBSS == LastBSSType ) )
10569 {
10570 /*need to issue a disconnect to CSR.*/
10571 INIT_COMPLETION(pAdapter->disconnect_comp_var);
10572 if( eHAL_STATUS_SUCCESS ==
10573 sme_RoamDisconnect( WLAN_HDD_GET_HAL_CTX(pAdapter),
10574 pAdapter->sessionId,
10575 eCSR_DISCONNECT_REASON_UNSPECIFIED ) )
10576 {
c_hpothu6ff1c3c2013-10-01 19:01:57 +053010577 ret = wait_for_completion_interruptible_timeout(
10578 &pAdapter->disconnect_comp_var,
10579 msecs_to_jiffies(WLAN_WAIT_TIME_DISCONNECT));
10580 if (ret <= 0)
10581 {
10582 hddLog(VOS_TRACE_LEVEL_ERROR,
10583 FL("wait on disconnect_comp_var failed %ld"), ret);
10584 }
Jeff Johnson295189b2012-06-20 16:38:30 -070010585 }
10586 }
10587 }
10588 }
10589
10590done:
10591 /*set bitmask based on updated value*/
10592 wlan_hdd_set_concurrency_mode(pHddCtx, pAdapter->device_mode);
Leo Chang6fe1f922013-06-07 19:21:24 -070010593
10594 /* Only STA mode support TM now
10595 * all other mode, TM feature should be disabled */
10596 if ( (pHddCtx->cfg_ini->thermalMitigationEnable) &&
10597 (~VOS_STA & pHddCtx->concurrency_mode) )
10598 {
10599 hddDevTmLevelChangedHandler(pHddCtx->parent_dev, 0);
10600 }
10601
Jeff Johnson295189b2012-06-20 16:38:30 -070010602#ifdef WLAN_BTAMP_FEATURE
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010603 if((NL80211_IFTYPE_STATION == type) && (pHddCtx->concurrency_mode <= 1) &&
Agarwal Ashish51325b52014-06-16 16:50:49 +053010604 (pHddCtx->no_of_open_sessions[WLAN_HDD_INFRA_STATION] <=1))
Jeff Johnson295189b2012-06-20 16:38:30 -070010605 {
10606 //we are ok to do AMP
10607 pHddCtx->isAmpAllowed = VOS_TRUE;
10608 }
10609#endif //WLAN_BTAMP_FEATURE
10610 EXIT();
10611 return 0;
10612}
10613
Mahesh A Saptasagar0e59c472014-04-14 19:17:41 +053010614/*
10615 * FUNCTION: wlan_hdd_cfg80211_change_iface
10616 * wrapper function to protect the actual implementation from SSR.
10617 */
10618int wlan_hdd_cfg80211_change_iface( struct wiphy *wiphy,
10619 struct net_device *ndev,
10620 enum nl80211_iftype type,
10621 u32 *flags,
10622 struct vif_params *params
10623 )
10624{
10625 int ret;
10626
10627 vos_ssr_protect(__func__);
10628 ret = __wlan_hdd_cfg80211_change_iface(wiphy, ndev, type, flags, params);
10629 vos_ssr_unprotect(__func__);
10630
10631 return ret;
10632}
10633
Gopichand Nakkala681989c2013-03-06 22:27:48 -080010634#ifdef FEATURE_WLAN_TDLS
10635static int wlan_hdd_tdls_add_station(struct wiphy *wiphy,
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053010636 struct net_device *dev,
10637#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,18,0))
10638 const u8 *mac,
10639#else
10640 u8 *mac,
10641#endif
10642 bool update, tCsrStaParams *StaParams)
Gopichand Nakkala681989c2013-03-06 22:27:48 -080010643{
Gopichand Nakkala681989c2013-03-06 22:27:48 -080010644 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
Hoonki Lee5305c3a2013-04-29 23:28:59 -070010645 hddTdlsPeer_t *pTdlsPeer;
c_hpothu6ff1c3c2013-10-01 19:01:57 +053010646 long ret;
Rajesh Chauhana34c6e62014-03-25 16:37:58 +053010647 tANI_U16 numCurrTdlsPeers;
Chandrasekaran, Manishekar41b8e1f2015-03-10 13:30:28 +053010648 hdd_adapter_t *pAdapter;
Ganesh Kondabattinif065c1f2015-08-05 23:05:23 +053010649 VOS_STATUS status;
Gopichand Nakkala681989c2013-03-06 22:27:48 -080010650
10651 ENTER();
10652
Chandrasekaran, Manishekar41b8e1f2015-03-10 13:30:28 +053010653 if (!dev) {
10654 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Dev pointer is NULL"));
10655 return -EINVAL;
10656 }
10657
10658 pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
10659 if (!pAdapter) {
10660 hddLog(VOS_TRACE_LEVEL_ERROR, FL("HDD adapter is NULL"));
10661 return -EINVAL;
10662 }
10663
Gopichand Nakkala838be5d2013-04-10 22:41:51 +053010664 if (NULL == pHddCtx || NULL == pHddCtx->cfg_ini)
Gopichand Nakkala681989c2013-03-06 22:27:48 -080010665 {
10666 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
10667 "Invalid arguments");
10668 return -EINVAL;
10669 }
Hoonki Lee27511902013-03-14 18:19:06 -070010670
10671 if ((eTDLS_SUPPORT_NOT_ENABLED == pHddCtx->tdls_mode) ||
10672 (eTDLS_SUPPORT_DISABLED == pHddCtx->tdls_mode))
10673 {
Masti, Narayanraddi34e0e562015-03-05 18:23:03 +053010674 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Hoonki Lee27511902013-03-14 18:19:06 -070010675 "%s: TDLS mode is disabled OR not enabled in FW."
10676 MAC_ADDRESS_STR " Request declined.",
10677 __func__, MAC_ADDR_ARRAY(mac));
10678 return -ENOTSUPP;
10679 }
10680
Gopichand Nakkala681989c2013-03-06 22:27:48 -080010681 if (pHddCtx->isLogpInProgress)
10682 {
10683 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
10684 "%s:LOGP in Progress. Ignore!!!", __func__);
Atul Mittal115287b2014-07-08 13:26:33 +053010685 wlan_hdd_tdls_set_link_status(pAdapter,
10686 mac,
10687 eTDLS_LINK_IDLE,
10688 eTDLS_LINK_UNSPECIFIED);
Gopichand Nakkala681989c2013-03-06 22:27:48 -080010689 return -EBUSY;
10690 }
10691
Masti, Narayanraddi6dbcdbb2015-05-13 10:28:06 +053010692 mutex_lock(&pHddCtx->tdls_lock);
Naresh Jayaram9c6f4462014-02-13 12:20:31 +053010693 pTdlsPeer = wlan_hdd_tdls_get_peer(pAdapter, mac);
Hoonki Lee5305c3a2013-04-29 23:28:59 -070010694
10695 if ( NULL == pTdlsPeer ) {
Masti, Narayanraddi34e0e562015-03-05 18:23:03 +053010696 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Hoonki Lee5305c3a2013-04-29 23:28:59 -070010697 "%s: " MAC_ADDRESS_STR " (update %d) not exist. return invalid",
10698 __func__, MAC_ADDR_ARRAY(mac), update);
Masti, Narayanraddi6dbcdbb2015-05-13 10:28:06 +053010699 mutex_unlock(&pHddCtx->tdls_lock);
Hoonki Lee5305c3a2013-04-29 23:28:59 -070010700 return -EINVAL;
Gopichand Nakkala34d1b062013-03-19 15:28:33 -070010701 }
Hoonki Lee5305c3a2013-04-29 23:28:59 -070010702
10703 /* in add station, we accept existing valid staId if there is */
10704 if ((0 == update) &&
10705 ((pTdlsPeer->link_status >= eTDLS_LINK_CONNECTING) ||
10706 (TDLS_STA_INDEX_VALID(pTdlsPeer->staId))))
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -070010707 {
Masti, Narayanraddi34e0e562015-03-05 18:23:03 +053010708 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -070010709 "%s: " MAC_ADDRESS_STR
Hoonki Lee5305c3a2013-04-29 23:28:59 -070010710 " link_status %d. staId %d. add station ignored.",
10711 __func__, MAC_ADDR_ARRAY(mac), pTdlsPeer->link_status, pTdlsPeer->staId);
Masti, Narayanraddi6b93b472015-09-04 17:48:11 +053010712 mutex_unlock(&pHddCtx->tdls_lock);
Hoonki Lee5305c3a2013-04-29 23:28:59 -070010713 return 0;
10714 }
10715 /* in change station, we accept only when staId is valid */
10716 if ((1 == update) &&
10717 ((pTdlsPeer->link_status > eTDLS_LINK_CONNECTING) ||
10718 (!TDLS_STA_INDEX_VALID(pTdlsPeer->staId))))
10719 {
Masti, Narayanraddi6b93b472015-09-04 17:48:11 +053010720 tANI_U16 staId = pTdlsPeer->staId;
Masti, Narayanraddi34e0e562015-03-05 18:23:03 +053010721 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Hoonki Lee5305c3a2013-04-29 23:28:59 -070010722 "%s: " MAC_ADDRESS_STR
10723 " link status %d. staId %d. change station %s.",
Masti, Narayanraddi6b93b472015-09-04 17:48:11 +053010724 __func__, MAC_ADDR_ARRAY(mac), pTdlsPeer->link_status, staId,
10725 (TDLS_STA_INDEX_VALID(staId)) ? "ignored" : "declined");
10726 mutex_unlock(&pHddCtx->tdls_lock);
10727 return (TDLS_STA_INDEX_VALID(staId)) ? 0 : -EPERM;
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -070010728 }
Masti, Narayanraddi6b93b472015-09-04 17:48:11 +053010729 mutex_unlock(&pHddCtx->tdls_lock);
Gopichand Nakkala34d1b062013-03-19 15:28:33 -070010730
10731 /* when others are on-going, we want to change link_status to idle */
Pradeep Reddy POTTETI9db32f02015-01-29 15:22:54 +053010732 if (NULL != wlan_hdd_tdls_is_progress(pHddCtx, mac, TRUE, TRUE))
Gopichand Nakkala681989c2013-03-06 22:27:48 -080010733 {
Gopichand Nakkalac87400e2013-03-13 18:51:00 -070010734 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
10735 "%s: " MAC_ADDRESS_STR
10736 " TDLS setup is ongoing. Request declined.",
10737 __func__, MAC_ADDR_ARRAY(mac));
Gopichand Nakkala05922802013-03-14 12:23:19 -070010738 goto error;
Gopichand Nakkala681989c2013-03-06 22:27:48 -080010739 }
10740
10741 /* first to check if we reached to maximum supported TDLS peer.
10742 TODO: for now, return -EPERM looks working fine,
10743 but need to check if any other errno fit into this category.*/
Rajesh Chauhana34c6e62014-03-25 16:37:58 +053010744 numCurrTdlsPeers = wlan_hdd_tdlsConnectedPeers(pAdapter);
10745 if (HDD_MAX_NUM_TDLS_STA <= numCurrTdlsPeers)
Gopichand Nakkala681989c2013-03-06 22:27:48 -080010746 {
Gopichand Nakkalac87400e2013-03-13 18:51:00 -070010747 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
10748 "%s: " MAC_ADDRESS_STR
Rajesh Chauhana34c6e62014-03-25 16:37:58 +053010749 " TDLS Max peer already connected. Request declined."
10750 " Num of peers (%d), Max allowed (%d).",
10751 __func__, MAC_ADDR_ARRAY(mac), numCurrTdlsPeers,
10752 HDD_MAX_NUM_TDLS_STA);
Gopichand Nakkala05922802013-03-14 12:23:19 -070010753 goto error;
Gopichand Nakkala681989c2013-03-06 22:27:48 -080010754 }
10755 else
10756 {
10757 hddTdlsPeer_t *pTdlsPeer;
Masti, Narayanraddi6b93b472015-09-04 17:48:11 +053010758 mutex_lock(&pHddCtx->tdls_lock);
10759 pTdlsPeer = wlan_hdd_tdls_find_peer(pAdapter, mac, FALSE);
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -070010760 if (pTdlsPeer && TDLS_IS_CONNECTED(pTdlsPeer))
Gopichand Nakkala681989c2013-03-06 22:27:48 -080010761 {
Masti, Narayanraddi6b93b472015-09-04 17:48:11 +053010762 mutex_unlock(&pHddCtx->tdls_lock);
Gopichand Nakkalac87400e2013-03-13 18:51:00 -070010763 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
10764 "%s: " MAC_ADDRESS_STR " already connected. Request declined.",
10765 __func__, MAC_ADDR_ARRAY(mac));
Gopichand Nakkala681989c2013-03-06 22:27:48 -080010766 return -EPERM;
10767 }
Masti, Narayanraddi6b93b472015-09-04 17:48:11 +053010768 mutex_unlock(&pHddCtx->tdls_lock);
Gopichand Nakkala681989c2013-03-06 22:27:48 -080010769 }
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -070010770 if (0 == update)
Atul Mittal115287b2014-07-08 13:26:33 +053010771 wlan_hdd_tdls_set_link_status(pAdapter,
10772 mac,
10773 eTDLS_LINK_CONNECTING,
10774 eTDLS_LINK_SUCCESS);
Gopichand Nakkala681989c2013-03-06 22:27:48 -080010775
Jeff Johnsond75fe012013-04-06 10:53:06 -070010776 /* debug code */
Gopichand Nakkala838be5d2013-04-10 22:41:51 +053010777 if (NULL != StaParams)
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -070010778 {
Masti, Narayanraddi34e0e562015-03-05 18:23:03 +053010779 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -070010780 "%s: TDLS Peer Parameters.", __func__);
Hoonki Lee66b75f32013-04-16 18:30:07 -070010781 if(StaParams->htcap_present)
10782 {
Masti, Narayanraddi34e0e562015-03-05 18:23:03 +053010783 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Hoonki Lee66b75f32013-04-16 18:30:07 -070010784 "ht_capa->cap_info: %0x", StaParams->HTCap.capInfo);
Masti, Narayanraddi34e0e562015-03-05 18:23:03 +053010785 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Hoonki Lee66b75f32013-04-16 18:30:07 -070010786 "ht_capa->extended_capabilities: %0x",
10787 StaParams->HTCap.extendedHtCapInfo);
10788 }
Masti, Narayanraddi34e0e562015-03-05 18:23:03 +053010789 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -070010790 "params->capability: %0x",StaParams->capability);
Masti, Narayanraddi34e0e562015-03-05 18:23:03 +053010791 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Jeff Johnson0299d0a2013-10-30 12:37:43 -070010792 "params->ext_capab_len: %0x",StaParams->extn_capability[0]);
Hoonki Lee66b75f32013-04-16 18:30:07 -070010793 if(StaParams->vhtcap_present)
10794 {
Masti, Narayanraddi34e0e562015-03-05 18:23:03 +053010795 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Hoonki Lee66b75f32013-04-16 18:30:07 -070010796 "rxMcsMap %x rxHighest %x txMcsMap %x txHighest %x",
10797 StaParams->VHTCap.suppMcs.rxMcsMap, StaParams->VHTCap.suppMcs.rxHighest,
10798 StaParams->VHTCap.suppMcs.txMcsMap, StaParams->VHTCap.suppMcs.txHighest);
10799 }
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -070010800 {
10801 int i = 0;
Hoonki Lee5305c3a2013-04-29 23:28:59 -070010802 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO, "Supported rates:");
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -070010803 for (i = 0; i < sizeof(StaParams->supported_rates); i++)
Masti, Narayanraddi34e0e562015-03-05 18:23:03 +053010804 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -070010805 "[%d]: %x ", i, StaParams->supported_rates[i]);
10806 }
Jeff Johnsond75fe012013-04-06 10:53:06 -070010807 } /* end debug code */
Gopichand Nakkala838be5d2013-04-10 22:41:51 +053010808 else if ((1 == update) && (NULL == StaParams))
10809 {
10810 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
10811 "%s : update is true, but staParams is NULL. Error!", __func__);
10812 return -EPERM;
10813 }
Gopichand Nakkala681989c2013-03-06 22:27:48 -080010814
10815 INIT_COMPLETION(pAdapter->tdls_add_station_comp);
10816
10817 if (!update)
10818 {
Ganesh Kondabattinif065c1f2015-08-05 23:05:23 +053010819 /*Before adding sta make sure that device exited from BMPS*/
10820 if (TRUE == sme_IsPmcBmps(WLAN_HDD_GET_HAL_CTX(pAdapter)))
10821 {
10822 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
10823 "%s: Adding tdls peer sta. Disable BMPS", __func__);
10824 status = hdd_disable_bmps_imps(pHddCtx, WLAN_HDD_INFRA_STATION);
10825 if (status != VOS_STATUS_SUCCESS) {
10826 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Failed to set BMPS/IMPS"));
10827 }
10828 }
10829
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053010830 ret = sme_AddTdlsPeerSta(WLAN_HDD_GET_HAL_CTX(pAdapter),
Gopichand Nakkala681989c2013-03-06 22:27:48 -080010831 pAdapter->sessionId, mac);
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053010832 if (ret != eHAL_STATUS_SUCCESS) {
Ganesh Kondabattinif065c1f2015-08-05 23:05:23 +053010833 hddLog(VOS_TRACE_LEVEL_ERROR,
10834 FL("Failed to add TDLS peer STA. Enable Bmps"));
10835 wlan_hdd_tdls_check_bmps(pAdapter);
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053010836 return -EPERM;
10837 }
Gopichand Nakkala681989c2013-03-06 22:27:48 -080010838 }
10839 else
10840 {
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053010841 ret = sme_ChangeTdlsPeerSta(WLAN_HDD_GET_HAL_CTX(pAdapter),
Gopichand Nakkala681989c2013-03-06 22:27:48 -080010842 pAdapter->sessionId, mac, StaParams);
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053010843 if (ret != eHAL_STATUS_SUCCESS) {
10844 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Failed to change TDLS peer STA params"));
10845 return -EPERM;
10846 }
Gopichand Nakkala681989c2013-03-06 22:27:48 -080010847 }
10848
c_hpothu6ff1c3c2013-10-01 19:01:57 +053010849 ret = wait_for_completion_interruptible_timeout(&pAdapter->tdls_add_station_comp,
Gopichand Nakkala681989c2013-03-06 22:27:48 -080010850 msecs_to_jiffies(WAIT_TIME_TDLS_ADD_STA));
10851
c_hpothu6ff1c3c2013-10-01 19:01:57 +053010852 if (ret <= 0)
Gopichand Nakkala681989c2013-03-06 22:27:48 -080010853 {
Gopichand Nakkalac87400e2013-03-13 18:51:00 -070010854 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
c_hpothu6ff1c3c2013-10-01 19:01:57 +053010855 "%s: timeout waiting for tdls add station indication %ld",
10856 __func__, ret);
Gopichand Nakkala34d1b062013-03-19 15:28:33 -070010857 return -EPERM;
Gopichand Nakkala681989c2013-03-06 22:27:48 -080010858 }
c_hpothu6ff1c3c2013-10-01 19:01:57 +053010859
Gopichand Nakkala681989c2013-03-06 22:27:48 -080010860 if ( eHAL_STATUS_SUCCESS != pAdapter->tdlsAddStaStatus)
10861 {
Gopichand Nakkalac87400e2013-03-13 18:51:00 -070010862 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Gopichand Nakkala681989c2013-03-06 22:27:48 -080010863 "%s: Add Station is unsucessful", __func__);
Gopichand Nakkala34d1b062013-03-19 15:28:33 -070010864 return -EPERM;
Gopichand Nakkala681989c2013-03-06 22:27:48 -080010865 }
10866
10867 return 0;
Gopichand Nakkala05922802013-03-14 12:23:19 -070010868
10869error:
Atul Mittal115287b2014-07-08 13:26:33 +053010870 wlan_hdd_tdls_set_link_status(pAdapter,
10871 mac,
10872 eTDLS_LINK_IDLE,
10873 eTDLS_LINK_UNSPECIFIED);
Gopichand Nakkala05922802013-03-14 12:23:19 -070010874 return -EPERM;
10875
Gopichand Nakkala681989c2013-03-06 22:27:48 -080010876}
10877#endif
10878
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053010879static int __wlan_hdd_change_station(struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -070010880 struct net_device *dev,
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053010881#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,18,0))
10882 const u8 *mac,
10883#else
Jeff Johnson295189b2012-06-20 16:38:30 -070010884 u8 *mac,
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053010885#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070010886 struct station_parameters *params)
10887{
10888 VOS_STATUS status = VOS_STATUS_SUCCESS;
Mahesh A Saptasagar74088392015-02-05 17:22:09 +053010889 hdd_adapter_t *pAdapter;
Gopichand Nakkala29149562013-05-10 21:43:41 +053010890 hdd_context_t *pHddCtx;
10891 hdd_station_ctx_t *pHddStaCtx;
Jeff Johnson295189b2012-06-20 16:38:30 -070010892 v_MACADDR_t STAMacAddress;
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +053010893 int ret = 0;
Gopichand Nakkalab0856222013-03-12 22:39:05 -070010894#ifdef FEATURE_WLAN_TDLS
Gopichand Nakkala681989c2013-03-06 22:27:48 -080010895 tCsrStaParams StaParams = {0};
Gopichand Nakkala681989c2013-03-06 22:27:48 -080010896 tANI_U8 isBufSta = 0;
Naresh Jayaram3180aa42014-02-12 21:47:26 +053010897 tANI_U8 isOffChannelSupported = 0;
Gopichand Nakkalab0856222013-03-12 22:39:05 -070010898#endif
Jeff Johnsone7245742012-09-05 17:12:55 -070010899
Mahesh A Saptasagar74088392015-02-05 17:22:09 +053010900 ENTER();
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053010901
Mahesh A Saptasagar74088392015-02-05 17:22:09 +053010902 pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
Gopichand Nakkala29149562013-05-10 21:43:41 +053010903 if ((NULL == pAdapter))
10904 {
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053010905 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
Gopichand Nakkala29149562013-05-10 21:43:41 +053010906 "invalid adapter ");
10907 return -EINVAL;
10908 }
10909
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053010910 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
10911 TRACE_CODE_HDD_CHANGE_STATION,
10912 pAdapter->sessionId, params->listen_interval));
Gopichand Nakkala29149562013-05-10 21:43:41 +053010913 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Gopichand Nakkala29149562013-05-10 21:43:41 +053010914
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +053010915 ret = wlan_hdd_validate_context(pHddCtx);
10916 if (0 != ret)
Gopichand Nakkala29149562013-05-10 21:43:41 +053010917 {
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +053010918 return ret;
Gopichand Nakkala29149562013-05-10 21:43:41 +053010919 }
10920
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +053010921 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
10922
10923 if (NULL == pHddStaCtx)
Jeff Johnson04dd8a82012-06-29 20:41:40 -070010924 {
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +053010925 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
10926 "invalid HDD station context");
10927 return -EINVAL;
Jeff Johnson04dd8a82012-06-29 20:41:40 -070010928 }
Jeff Johnson295189b2012-06-20 16:38:30 -070010929 vos_mem_copy(STAMacAddress.bytes, mac, sizeof(v_MACADDR_t));
10930
Gopichand Nakkala681989c2013-03-06 22:27:48 -080010931 if ((pAdapter->device_mode == WLAN_HDD_SOFTAP)
10932 || (pAdapter->device_mode == WLAN_HDD_P2P_GO))
Jeff Johnson295189b2012-06-20 16:38:30 -070010933 {
Gopichand Nakkala681989c2013-03-06 22:27:48 -080010934 if (params->sta_flags_set & BIT(NL80211_STA_FLAG_AUTHORIZED))
Jeff Johnson295189b2012-06-20 16:38:30 -070010935 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010936 status = hdd_softap_change_STA_state( pAdapter, &STAMacAddress,
Jeff Johnson295189b2012-06-20 16:38:30 -070010937 WLANTL_STA_AUTHENTICATED);
10938
Gopichand Nakkala29149562013-05-10 21:43:41 +053010939 if (status != VOS_STATUS_SUCCESS)
10940 {
10941 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
10942 "%s: Not able to change TL state to AUTHENTICATED", __func__);
10943 return -EINVAL;
10944 }
Jeff Johnson295189b2012-06-20 16:38:30 -070010945 }
10946 }
Hoonki Leea6d49be2013-04-05 09:43:25 -070010947 else if ((pAdapter->device_mode == WLAN_HDD_INFRA_STATION)
10948 || (pAdapter->device_mode == WLAN_HDD_P2P_CLIENT)) {
Gopichand Nakkala29149562013-05-10 21:43:41 +053010949#ifdef FEATURE_WLAN_TDLS
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -070010950 if (params->sta_flags_set & BIT(NL80211_STA_FLAG_TDLS_PEER)) {
10951 StaParams.capability = params->capability;
10952 StaParams.uapsd_queues = params->uapsd_queues;
10953 StaParams.max_sp = params->max_sp;
10954
Naresh Jayaram3180aa42014-02-12 21:47:26 +053010955 /* Convert (first channel , number of channels) tuple to
10956 * the total list of channels. This goes with the assumption
10957 * that if the first channel is < 14, then the next channels
10958 * are an incremental of 1 else an incremental of 4 till the number
10959 * of channels.
10960 */
10961 if (0 != params->supported_channels_len) {
10962 int i = 0,j = 0,k = 0, no_of_channels = 0 ;
10963 for ( i = 0 ; i < params->supported_channels_len ; i+=2)
10964 {
10965 int wifi_chan_index;
10966 StaParams.supported_channels[j] = params->supported_channels[i];
10967 wifi_chan_index =
10968 ((StaParams.supported_channels[j] <= HDD_CHANNEL_14 ) ? 1 : 4 );
10969 no_of_channels = params->supported_channels[i+1];
10970 for(k=1; k <= no_of_channels; k++)
10971 {
10972 StaParams.supported_channels[j+1] =
10973 StaParams.supported_channels[j] + wifi_chan_index;
10974 j+=1;
10975 }
10976 }
10977 StaParams.supported_channels_len = j;
10978 }
10979 vos_mem_copy(StaParams.supported_oper_classes,
10980 params->supported_oper_classes,
10981 params->supported_oper_classes_len);
10982 StaParams.supported_oper_classes_len =
10983 params->supported_oper_classes_len;
10984
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -070010985 if (0 != params->ext_capab_len)
10986 vos_mem_copy(StaParams.extn_capability, params->ext_capab,
10987 sizeof(StaParams.extn_capability));
10988
10989 if (NULL != params->ht_capa)
Hoonki Lee66b75f32013-04-16 18:30:07 -070010990 {
10991 StaParams.htcap_present = 1;
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -070010992 vos_mem_copy(&StaParams.HTCap, params->ht_capa, sizeof(tSirHTCap));
Hoonki Lee66b75f32013-04-16 18:30:07 -070010993 }
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -070010994
10995 StaParams.supported_rates_len = params->supported_rates_len;
10996
10997 /* Note : The Maximum sizeof supported_rates sent by the Supplicant is 32.
10998 * The supported_rates array , for all the structures propogating till Add Sta
10999 * to the firmware has to be modified , if the supplicant (ieee80211) is
11000 * modified to send more rates.
11001 */
11002
11003 /* To avoid Data Currption , set to max length to SIR_MAC_MAX_SUPP_RATES
11004 */
11005 if (StaParams.supported_rates_len > SIR_MAC_MAX_SUPP_RATES)
11006 StaParams.supported_rates_len = SIR_MAC_MAX_SUPP_RATES;
11007
11008 if (0 != StaParams.supported_rates_len) {
11009 int i = 0;
11010 vos_mem_copy(StaParams.supported_rates, params->supported_rates,
11011 StaParams.supported_rates_len);
Hoonki Lee5305c3a2013-04-29 23:28:59 -070011012 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -070011013 "Supported Rates with Length %d", StaParams.supported_rates_len);
11014 for (i=0; i < StaParams.supported_rates_len; i++)
Hoonki Lee5305c3a2013-04-29 23:28:59 -070011015 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -070011016 "[%d]: %0x", i, StaParams.supported_rates[i]);
11017 }
11018
11019 if (NULL != params->vht_capa)
Hoonki Lee66b75f32013-04-16 18:30:07 -070011020 {
11021 StaParams.vhtcap_present = 1;
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -070011022 vos_mem_copy(&StaParams.VHTCap, params->vht_capa, sizeof(tSirVHTCap));
Hoonki Lee66b75f32013-04-16 18:30:07 -070011023 }
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -070011024
Gopichand Nakkala681989c2013-03-06 22:27:48 -080011025 if (0 != params->ext_capab_len ) {
11026 /*Define A Macro : TODO Sunil*/
11027 if ((1<<4) & StaParams.extn_capability[3]) {
11028 isBufSta = 1;
11029 }
Naresh Jayaram3180aa42014-02-12 21:47:26 +053011030 /* TDLS Channel Switching Support */
11031 if ((1<<6) & StaParams.extn_capability[3]) {
11032 isOffChannelSupported = 1;
11033 }
Gopichand Nakkala681989c2013-03-06 22:27:48 -080011034 }
Naresh Jayaram3180aa42014-02-12 21:47:26 +053011035 status = wlan_hdd_tdls_set_peer_caps( pAdapter, mac,
11036 &StaParams, isBufSta,
11037 isOffChannelSupported);
11038
Gopichand Nakkala79ff85d2013-05-27 17:05:29 +053011039 if (VOS_STATUS_SUCCESS != status) {
11040 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
11041 "%s: wlan_hdd_tdls_set_peer_caps failed!", __func__);
11042 return -EINVAL;
11043 }
Gopichand Nakkala681989c2013-03-06 22:27:48 -080011044 status = wlan_hdd_tdls_add_station(wiphy, dev, mac, 1, &StaParams);
11045
11046 if (VOS_STATUS_SUCCESS != status) {
11047 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
11048 "%s: sme_ChangeTdlsPeerSta failed!", __func__);
11049 return -EINVAL;
11050 }
11051 }
Gopichand Nakkalab0856222013-03-12 22:39:05 -070011052#endif
Gopichand Nakkala6239acd2013-06-14 14:48:00 +053011053 }
Jeff Johnsone7245742012-09-05 17:12:55 -070011054 EXIT();
Jeff Johnson295189b2012-06-20 16:38:30 -070011055 return status;
11056}
11057
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053011058#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,16,0))
11059static int wlan_hdd_change_station(struct wiphy *wiphy,
11060 struct net_device *dev,
11061 const u8 *mac,
11062 struct station_parameters *params)
11063#else
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053011064static int wlan_hdd_change_station(struct wiphy *wiphy,
11065 struct net_device *dev,
11066 u8 *mac,
11067 struct station_parameters *params)
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053011068#endif
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053011069{
11070 int ret;
11071
11072 vos_ssr_protect(__func__);
11073 ret = __wlan_hdd_change_station(wiphy, dev, mac, params);
11074 vos_ssr_unprotect(__func__);
11075
11076 return ret;
11077}
11078
Jeff Johnson295189b2012-06-20 16:38:30 -070011079/*
Mahesh A Saptasagar1a51bc02014-06-02 18:28:08 +053011080 * FUNCTION: __wlan_hdd_cfg80211_add_key
Jeff Johnson295189b2012-06-20 16:38:30 -070011081 * This function is used to initialize the key information
11082 */
11083#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
Mahesh A Saptasagar1a51bc02014-06-02 18:28:08 +053011084static int __wlan_hdd_cfg80211_add_key( struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -070011085 struct net_device *ndev,
11086 u8 key_index, bool pairwise,
11087 const u8 *mac_addr,
11088 struct key_params *params
11089 )
11090#else
Mahesh A Saptasagar1a51bc02014-06-02 18:28:08 +053011091static int __wlan_hdd_cfg80211_add_key( struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -070011092 struct net_device *ndev,
11093 u8 key_index, const u8 *mac_addr,
11094 struct key_params *params
11095 )
11096#endif
11097{
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -070011098 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( ndev );
Jeff Johnson295189b2012-06-20 16:38:30 -070011099 tCsrRoamSetKey setKey;
11100 u8 groupmacaddr[WNI_CFG_BSSID_LEN] = {0xFF,0xFF,0xFF,0xFF,0xFF,0xFF};
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053011101 int status;
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -070011102 v_U32_t roamId= 0xFF;
11103 v_CONTEXT_t pVosContext = (WLAN_HDD_GET_CTX(pAdapter))->pvosContext;
Jeff Johnson295189b2012-06-20 16:38:30 -070011104 hdd_hostapd_state_t *pHostapdState;
11105 VOS_STATUS vos_status;
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070011106 eHalStatus halStatus;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053011107 hdd_context_t *pHddCtx;
Jeff Johnson295189b2012-06-20 16:38:30 -070011108
11109 ENTER();
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053011110
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053011111 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
11112 TRACE_CODE_HDD_CFG80211_ADD_KEY,
11113 pAdapter->sessionId, params->key_len));
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053011114 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
11115 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053011116 if (0 != status)
Jeff Johnson04dd8a82012-06-29 20:41:40 -070011117 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053011118 return status;
Jeff Johnson04dd8a82012-06-29 20:41:40 -070011119 }
11120
Sushant Kaushik8bc7df22014-04-09 17:55:29 +053011121 hddLog(VOS_TRACE_LEVEL_INFO, "%s: device_mode = %s (%d)",
11122 __func__, hdd_device_modetoString(pAdapter->device_mode),
11123 pAdapter->device_mode);
Jeff Johnson295189b2012-06-20 16:38:30 -070011124
11125 if (CSR_MAX_NUM_KEY <= key_index)
11126 {
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -070011127 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Invalid key index %d", __func__,
Jeff Johnson295189b2012-06-20 16:38:30 -070011128 key_index);
11129
11130 return -EINVAL;
11131 }
11132
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -070011133 if (CSR_MAX_KEY_LEN < params->key_len)
11134 {
11135 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Invalid key length %d", __func__,
11136 params->key_len);
11137
11138 return -EINVAL;
11139 }
11140
11141 hddLog(VOS_TRACE_LEVEL_INFO,
11142 "%s: called with key index = %d & key length %d",
11143 __func__, key_index, params->key_len);
Jeff Johnson295189b2012-06-20 16:38:30 -070011144
11145 /*extract key idx, key len and key*/
11146 vos_mem_zero(&setKey,sizeof(tCsrRoamSetKey));
11147 setKey.keyId = key_index;
11148 setKey.keyLength = params->key_len;
11149 vos_mem_copy(&setKey.Key[0],params->key, params->key_len);
11150
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -070011151 switch (params->cipher)
Jeff Johnson295189b2012-06-20 16:38:30 -070011152 {
11153 case WLAN_CIPHER_SUITE_WEP40:
11154 setKey.encType = eCSR_ENCRYPT_TYPE_WEP40_STATICKEY;
11155 break;
11156
11157 case WLAN_CIPHER_SUITE_WEP104:
11158 setKey.encType = eCSR_ENCRYPT_TYPE_WEP104_STATICKEY;
11159 break;
11160
11161 case WLAN_CIPHER_SUITE_TKIP:
11162 {
11163 u8 *pKey = &setKey.Key[0];
11164 setKey.encType = eCSR_ENCRYPT_TYPE_TKIP;
11165
11166 vos_mem_zero(pKey, CSR_MAX_KEY_LEN);
11167
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -070011168 /*Supplicant sends the 32bytes key in this order
Jeff Johnson295189b2012-06-20 16:38:30 -070011169
11170 |--------------|----------|----------|
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -070011171 | Tk1 |TX-MIC | RX Mic |
Jeff Johnson295189b2012-06-20 16:38:30 -070011172 |--------------|----------|----------|
11173 <---16bytes---><--8bytes--><--8bytes-->
11174
11175 */
11176 /*Sme expects the 32 bytes key to be in the below order
11177
11178 |--------------|----------|----------|
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -070011179 | Tk1 |RX-MIC | TX Mic |
Jeff Johnson295189b2012-06-20 16:38:30 -070011180 |--------------|----------|----------|
11181 <---16bytes---><--8bytes--><--8bytes-->
11182 */
11183 /* Copy the Temporal Key 1 (TK1) */
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -070011184 vos_mem_copy(pKey, params->key, 16);
Jeff Johnson295189b2012-06-20 16:38:30 -070011185
11186 /*Copy the rx mic first*/
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -070011187 vos_mem_copy(&pKey[16], &params->key[24], 8);
Jeff Johnson295189b2012-06-20 16:38:30 -070011188
11189 /*Copy the tx mic */
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -070011190 vos_mem_copy(&pKey[24], &params->key[16], 8);
Jeff Johnson295189b2012-06-20 16:38:30 -070011191
11192
11193 break;
11194 }
11195
11196 case WLAN_CIPHER_SUITE_CCMP:
11197 setKey.encType = eCSR_ENCRYPT_TYPE_AES;
11198 break;
11199
11200#ifdef FEATURE_WLAN_WAPI
11201 case WLAN_CIPHER_SUITE_SMS4:
11202 {
11203 vos_mem_zero(&setKey,sizeof(tCsrRoamSetKey));
11204 wlan_hdd_cfg80211_set_key_wapi(pAdapter, key_index, mac_addr,
11205 params->key, params->key_len);
11206 return 0;
11207 }
11208#endif
Chet Lanctot186b5732013-03-18 10:26:30 -070011209
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -080011210#ifdef FEATURE_WLAN_ESE
Jeff Johnson295189b2012-06-20 16:38:30 -070011211 case WLAN_CIPHER_SUITE_KRK:
11212 setKey.encType = eCSR_ENCRYPT_TYPE_KRK;
11213 break;
11214#endif
Chet Lanctot186b5732013-03-18 10:26:30 -070011215
11216#ifdef WLAN_FEATURE_11W
11217 case WLAN_CIPHER_SUITE_AES_CMAC:
11218 setKey.encType = eCSR_ENCRYPT_TYPE_AES_CMAC;
Chet Lanctot3b5158a2013-03-31 16:45:21 -070011219 break;
Chet Lanctot186b5732013-03-18 10:26:30 -070011220#endif
11221
Jeff Johnson295189b2012-06-20 16:38:30 -070011222 default:
Jeff Johnson0299d0a2013-10-30 12:37:43 -070011223 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: unsupported cipher type %u",
Jeff Johnson295189b2012-06-20 16:38:30 -070011224 __func__, params->cipher);
Vinay Krishna Eranna6f22c1f2014-10-13 16:03:06 +053011225 status = -EOPNOTSUPP;
11226 goto end;
Jeff Johnson295189b2012-06-20 16:38:30 -070011227 }
11228
11229 hddLog(VOS_TRACE_LEVEL_INFO_MED, "%s: encryption type %d",
11230 __func__, setKey.encType);
11231
Shailender Karmuchi642e9812013-05-30 14:34:49 -070011232 if (
Jeff Johnson295189b2012-06-20 16:38:30 -070011233#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
11234 (!pairwise)
11235#else
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -070011236 (!mac_addr || is_broadcast_ether_addr(mac_addr))
Jeff Johnson295189b2012-06-20 16:38:30 -070011237#endif
Shailender Karmuchi642e9812013-05-30 14:34:49 -070011238 )
11239 {
11240 /* set group key*/
11241 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
11242 "%s- %d: setting Broadcast key",
11243 __func__, __LINE__);
11244 setKey.keyDirection = eSIR_RX_ONLY;
11245 vos_mem_copy(setKey.peerMac,groupmacaddr,WNI_CFG_BSSID_LEN);
11246 }
11247 else
11248 {
11249 /* set pairwise key*/
11250 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
11251 "%s- %d: setting pairwise key",
11252 __func__, __LINE__);
11253 setKey.keyDirection = eSIR_TX_RX;
11254 vos_mem_copy(setKey.peerMac, mac_addr,WNI_CFG_BSSID_LEN);
11255 }
11256 if ((WLAN_HDD_IBSS == pAdapter->device_mode) && !pairwise)
11257 {
11258 setKey.keyDirection = eSIR_TX_RX;
11259 /*Set the group key*/
11260 status = sme_RoamSetKey( WLAN_HDD_GET_HAL_CTX(pAdapter),
11261 pAdapter->sessionId, &setKey, &roamId );
Jeff Johnson295189b2012-06-20 16:38:30 -070011262
Shailender Karmuchi642e9812013-05-30 14:34:49 -070011263 if ( 0 != status )
11264 {
11265 hddLog(VOS_TRACE_LEVEL_ERROR,
11266 "%s: sme_RoamSetKey failed, returned %d", __func__, status);
Vinay Krishna Eranna6f22c1f2014-10-13 16:03:06 +053011267 status = -EINVAL;
11268 goto end;
Shailender Karmuchi642e9812013-05-30 14:34:49 -070011269 }
11270 /*Save the keys here and call sme_RoamSetKey for setting
11271 the PTK after peer joins the IBSS network*/
11272 vos_mem_copy(&pAdapter->sessionCtx.station.ibss_enc_key,
11273 &setKey, sizeof(tCsrRoamSetKey));
Vinay Krishna Eranna6f22c1f2014-10-13 16:03:06 +053011274 goto end;
Shailender Karmuchi642e9812013-05-30 14:34:49 -070011275 }
Gopichand Nakkala29149562013-05-10 21:43:41 +053011276 if ((pAdapter->device_mode == WLAN_HDD_SOFTAP) ||
11277 (pAdapter->device_mode == WLAN_HDD_P2P_GO))
11278 {
Jeff Johnson295189b2012-06-20 16:38:30 -070011279 pHostapdState = WLAN_HDD_GET_HOSTAP_STATE_PTR(pAdapter);
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -070011280 if( pHostapdState->bssState == BSS_START )
11281 {
Nirav Shah4b53d4b2015-05-08 05:35:00 -070011282 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
11283 vos_status = wlan_hdd_check_ula_done(pAdapter);
11284
11285 if ( vos_status != VOS_STATUS_SUCCESS )
11286 {
11287 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
11288 "[%4d] wlan_hdd_check_ula_done returned ERROR status= %d",
11289 __LINE__, vos_status );
11290
11291 pHddStaCtx->roam_info.roamingState = HDD_ROAM_STATE_NONE;
11292
11293 status = -EINVAL;
11294 goto end;
11295 }
11296
Jeff Johnson295189b2012-06-20 16:38:30 -070011297 status = WLANSAP_SetKeySta( pVosContext, &setKey);
11298
11299 if ( status != eHAL_STATUS_SUCCESS )
11300 {
11301 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
11302 "[%4d] WLANSAP_SetKeySta returned ERROR status= %d",
11303 __LINE__, status );
Vinay Krishna Eranna6f22c1f2014-10-13 16:03:06 +053011304 status = -EINVAL;
11305 goto end;
Jeff Johnson295189b2012-06-20 16:38:30 -070011306 }
11307 }
11308
11309 /* Saving WEP keys */
11310 else if( eCSR_ENCRYPT_TYPE_WEP40_STATICKEY == setKey.encType ||
11311 eCSR_ENCRYPT_TYPE_WEP104_STATICKEY == setKey.encType )
11312 {
11313 //Save the wep key in ap context. Issue setkey after the BSS is started.
11314 hdd_ap_ctx_t *pAPCtx = WLAN_HDD_GET_AP_CTX_PTR(pAdapter);
11315 vos_mem_copy(&pAPCtx->wepKey[key_index], &setKey, sizeof(tCsrRoamSetKey));
11316 }
11317 else
11318 {
11319 //Save the key in ap context. Issue setkey after the BSS is started.
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -070011320 hdd_ap_ctx_t *pAPCtx = WLAN_HDD_GET_AP_CTX_PTR(pAdapter);
Jeff Johnson295189b2012-06-20 16:38:30 -070011321 vos_mem_copy(&pAPCtx->groupKey, &setKey, sizeof(tCsrRoamSetKey));
11322 }
11323 }
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -070011324 else if ( (pAdapter->device_mode == WLAN_HDD_INFRA_STATION) ||
11325 (pAdapter->device_mode == WLAN_HDD_P2P_CLIENT) )
Jeff Johnson295189b2012-06-20 16:38:30 -070011326 {
11327 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
11328 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
11329
Gopichand Nakkala3d295922013-05-07 16:19:14 +053011330#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
11331 if (!pairwise)
11332#else
11333 if (!mac_addr || is_broadcast_ether_addr(mac_addr))
11334#endif
11335 {
11336 /* set group key*/
11337 if (pHddStaCtx->roam_info.deferKeyComplete)
11338 {
11339 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
11340 "%s- %d: Perform Set key Complete",
11341 __func__, __LINE__);
11342 hdd_PerformRoamSetKeyComplete(pAdapter);
11343 }
11344 }
11345
Jeff Johnson295189b2012-06-20 16:38:30 -070011346 pWextState->roamProfile.Keys.KeyLength[key_index] = (u8)params->key_len;
11347
Venkata Prathyusha Kuntupalliee2ce712013-01-17 14:09:24 -080011348 pWextState->roamProfile.Keys.defaultIndex = key_index;
11349
11350
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -070011351 vos_mem_copy(&pWextState->roamProfile.Keys.KeyMaterial[key_index][0],
Jeff Johnson295189b2012-06-20 16:38:30 -070011352 params->key, params->key_len);
11353
Gopichand Nakkala3d295922013-05-07 16:19:14 +053011354
Jeff Johnson295189b2012-06-20 16:38:30 -070011355 pHddStaCtx->roam_info.roamingState = HDD_ROAM_STATE_SETTING_KEY;
11356
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011357 hddLog(VOS_TRACE_LEVEL_INFO_MED,
Jeff Johnson295189b2012-06-20 16:38:30 -070011358 "%s: set key for peerMac %2x:%2x:%2x:%2x:%2x:%2x, direction %d",
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011359 __func__, setKey.peerMac[0], setKey.peerMac[1],
11360 setKey.peerMac[2], setKey.peerMac[3],
11361 setKey.peerMac[4], setKey.peerMac[5],
Jeff Johnson295189b2012-06-20 16:38:30 -070011362 setKey.keyDirection);
11363
Nirav Shah4b53d4b2015-05-08 05:35:00 -070011364 vos_status = wlan_hdd_check_ula_done(pAdapter);
Nirav Shah4f765af2015-01-21 19:51:30 +053011365
Nirav Shah4b53d4b2015-05-08 05:35:00 -070011366 if ( vos_status != VOS_STATUS_SUCCESS )
11367 {
11368 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Jeff Johnson295189b2012-06-20 16:38:30 -070011369 "[%4d] wlan_hdd_check_ula_done returned ERROR status= %d",
11370 __LINE__, vos_status );
11371
Nirav Shah4b53d4b2015-05-08 05:35:00 -070011372 pHddStaCtx->roam_info.roamingState = HDD_ROAM_STATE_NONE;
Jeff Johnson295189b2012-06-20 16:38:30 -070011373
Nirav Shah4b53d4b2015-05-08 05:35:00 -070011374 status = -EINVAL;
11375 goto end;
Jeff Johnson295189b2012-06-20 16:38:30 -070011376
11377 }
11378
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070011379#ifdef WLAN_FEATURE_VOWIFI_11R
Gopichand Nakkala3d295922013-05-07 16:19:14 +053011380 /* The supplicant may attempt to set the PTK once pre-authentication
11381 is done. Save the key in the UMAC and include it in the ADD BSS
11382 request */
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070011383 halStatus = sme_FTUpdateKey( WLAN_HDD_GET_HAL_CTX(pAdapter), &setKey);
Gopichand Nakkala3d295922013-05-07 16:19:14 +053011384 if ( halStatus == eHAL_STATUS_FT_PREAUTH_KEY_SUCCESS )
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070011385 {
Gopichand Nakkala3d295922013-05-07 16:19:14 +053011386 hddLog(VOS_TRACE_LEVEL_INFO_MED,
11387 "%s: Update PreAuth Key success", __func__);
Vinay Krishna Eranna6f22c1f2014-10-13 16:03:06 +053011388 status = 0;
11389 goto end;
Gopichand Nakkala3d295922013-05-07 16:19:14 +053011390 }
11391 else if ( halStatus == eHAL_STATUS_FT_PREAUTH_KEY_FAILED )
11392 {
11393 hddLog(VOS_TRACE_LEVEL_ERROR,
11394 "%s: Update PreAuth Key failed", __func__);
Vinay Krishna Eranna6f22c1f2014-10-13 16:03:06 +053011395 status = -EINVAL;
11396 goto end;
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070011397 }
11398#endif /* WLAN_FEATURE_VOWIFI_11R */
Jeff Johnson295189b2012-06-20 16:38:30 -070011399
11400 /* issue set key request to SME*/
11401 status = sme_RoamSetKey( WLAN_HDD_GET_HAL_CTX(pAdapter),
11402 pAdapter->sessionId, &setKey, &roamId );
11403
11404 if ( 0 != status )
11405 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011406 hddLog(VOS_TRACE_LEVEL_ERROR,
Jeff Johnson295189b2012-06-20 16:38:30 -070011407 "%s: sme_RoamSetKey failed, returned %d", __func__, status);
11408 pHddStaCtx->roam_info.roamingState = HDD_ROAM_STATE_NONE;
Vinay Krishna Eranna6f22c1f2014-10-13 16:03:06 +053011409 status = -EINVAL;
11410 goto end;
Jeff Johnson295189b2012-06-20 16:38:30 -070011411 }
11412
11413
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011414 /* in case of IBSS as there was no information available about WEP keys during
11415 * IBSS join, group key intialized with NULL key, so re-initialize group key
Jeff Johnson295189b2012-06-20 16:38:30 -070011416 * with correct value*/
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011417 if ( (eCSR_BSS_TYPE_START_IBSS == pWextState->roamProfile.BSSType) &&
11418 !( ( IW_AUTH_KEY_MGMT_802_1X
11419 == (pWextState->authKeyMgmt & IW_AUTH_KEY_MGMT_802_1X))
Jeff Johnson295189b2012-06-20 16:38:30 -070011420 && (eCSR_AUTH_TYPE_OPEN_SYSTEM == pHddStaCtx->conn_info.authType)
11421 )
11422 &&
11423 ( (WLAN_CIPHER_SUITE_WEP40 == params->cipher)
11424 || (WLAN_CIPHER_SUITE_WEP104 == params->cipher)
11425 )
11426 )
11427 {
11428 setKey.keyDirection = eSIR_RX_ONLY;
11429 vos_mem_copy(setKey.peerMac,groupmacaddr,WNI_CFG_BSSID_LEN);
11430
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011431 hddLog(VOS_TRACE_LEVEL_INFO_MED,
Jeff Johnson295189b2012-06-20 16:38:30 -070011432 "%s: set key peerMac %2x:%2x:%2x:%2x:%2x:%2x, direction %d",
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011433 __func__, setKey.peerMac[0], setKey.peerMac[1],
11434 setKey.peerMac[2], setKey.peerMac[3],
11435 setKey.peerMac[4], setKey.peerMac[5],
Jeff Johnson295189b2012-06-20 16:38:30 -070011436 setKey.keyDirection);
11437
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011438 status = sme_RoamSetKey( WLAN_HDD_GET_HAL_CTX(pAdapter),
Jeff Johnson295189b2012-06-20 16:38:30 -070011439 pAdapter->sessionId, &setKey, &roamId );
11440
11441 if ( 0 != status )
11442 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011443 hddLog(VOS_TRACE_LEVEL_ERROR,
11444 "%s: sme_RoamSetKey failed for group key (IBSS), returned %d",
Jeff Johnson295189b2012-06-20 16:38:30 -070011445 __func__, status);
11446 pHddStaCtx->roam_info.roamingState = HDD_ROAM_STATE_NONE;
Vinay Krishna Eranna6f22c1f2014-10-13 16:03:06 +053011447 status = -EINVAL;
11448 goto end;
Jeff Johnson295189b2012-06-20 16:38:30 -070011449 }
11450 }
11451 }
11452
Vinay Krishna Eranna6f22c1f2014-10-13 16:03:06 +053011453end:
11454 /* Need to clear any trace of key value in the memory.
11455 * Thus zero out the memory even though it is local
11456 * variable.
11457 */
11458 vos_mem_zero(&setKey, sizeof(setKey));
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053011459 EXIT();
Vinay Krishna Eranna6f22c1f2014-10-13 16:03:06 +053011460 return status;
Jeff Johnson295189b2012-06-20 16:38:30 -070011461}
11462
Mahesh A Saptasagar1a51bc02014-06-02 18:28:08 +053011463#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
11464static int wlan_hdd_cfg80211_add_key( struct wiphy *wiphy,
11465 struct net_device *ndev,
11466 u8 key_index, bool pairwise,
11467 const u8 *mac_addr,
11468 struct key_params *params
11469 )
11470#else
11471static int wlan_hdd_cfg80211_add_key( struct wiphy *wiphy,
11472 struct net_device *ndev,
11473 u8 key_index, const u8 *mac_addr,
11474 struct key_params *params
11475 )
11476#endif
11477{
11478 int ret;
11479 vos_ssr_protect(__func__);
11480#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
11481 ret = __wlan_hdd_cfg80211_add_key(wiphy, ndev, key_index, pairwise,
11482 mac_addr, params);
11483#else
11484 ret = __wlan_hdd_cfg80211_add_key(wiphy, ndev, key_index, mac_addr,
11485 params);
11486#endif
11487 vos_ssr_unprotect(__func__);
11488
11489 return ret;
11490}
11491
Jeff Johnson295189b2012-06-20 16:38:30 -070011492/*
Mahesh A Saptasagar1a51bc02014-06-02 18:28:08 +053011493 * FUNCTION: __wlan_hdd_cfg80211_get_key
Jeff Johnson295189b2012-06-20 16:38:30 -070011494 * This function is used to get the key information
11495 */
11496#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
Mahesh A Saptasagar1a51bc02014-06-02 18:28:08 +053011497static int __wlan_hdd_cfg80211_get_key(
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011498 struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -070011499 struct net_device *ndev,
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011500 u8 key_index, bool pairwise,
Jeff Johnson295189b2012-06-20 16:38:30 -070011501 const u8 *mac_addr, void *cookie,
11502 void (*callback)(void *cookie, struct key_params*)
11503 )
11504#else
Mahesh A Saptasagar1a51bc02014-06-02 18:28:08 +053011505static int __wlan_hdd_cfg80211_get_key(
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011506 struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -070011507 struct net_device *ndev,
11508 u8 key_index, const u8 *mac_addr, void *cookie,
11509 void (*callback)(void *cookie, struct key_params*)
11510 )
11511#endif
11512{
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011513 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( ndev );
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +053011514 hdd_wext_state_t *pWextState = NULL;
11515 tCsrRoamProfile *pRoamProfile = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -070011516 struct key_params params;
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +053011517 hdd_context_t *pHddCtx;
11518 int ret = 0;
Jeff Johnson295189b2012-06-20 16:38:30 -070011519
11520 ENTER();
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011521
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +053011522 if (NULL == pAdapter)
11523 {
11524 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
11525 "%s: HDD adapter is Null", __func__);
11526 return -ENODEV;
11527 }
11528
11529 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
11530 ret = wlan_hdd_validate_context(pHddCtx);
11531 if (0 != ret)
11532 {
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +053011533 return ret;
11534 }
11535
11536 pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
11537 pRoamProfile = &(pWextState->roamProfile);
11538
Sushant Kaushik8bc7df22014-04-09 17:55:29 +053011539 hddLog(VOS_TRACE_LEVEL_INFO, "%s: device_mode = %s (%d)",
11540 __func__, hdd_device_modetoString(pAdapter->device_mode),
11541 pAdapter->device_mode);
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053011542
Jeff Johnson295189b2012-06-20 16:38:30 -070011543 memset(&params, 0, sizeof(params));
11544
11545 if (CSR_MAX_NUM_KEY <= key_index)
11546 {
c_hpothu6ff1c3c2013-10-01 19:01:57 +053011547 hddLog(VOS_TRACE_LEVEL_ERROR, FL("invalid key index %d"), key_index);
Jeff Johnson295189b2012-06-20 16:38:30 -070011548 return -EINVAL;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011549 }
Jeff Johnson295189b2012-06-20 16:38:30 -070011550
11551 switch(pRoamProfile->EncryptionType.encryptionType[0])
11552 {
11553 case eCSR_ENCRYPT_TYPE_NONE:
11554 params.cipher = IW_AUTH_CIPHER_NONE;
11555 break;
11556
11557 case eCSR_ENCRYPT_TYPE_WEP40_STATICKEY:
11558 case eCSR_ENCRYPT_TYPE_WEP40:
11559 params.cipher = WLAN_CIPHER_SUITE_WEP40;
11560 break;
11561
11562 case eCSR_ENCRYPT_TYPE_WEP104_STATICKEY:
11563 case eCSR_ENCRYPT_TYPE_WEP104:
11564 params.cipher = WLAN_CIPHER_SUITE_WEP104;
11565 break;
11566
11567 case eCSR_ENCRYPT_TYPE_TKIP:
11568 params.cipher = WLAN_CIPHER_SUITE_TKIP;
11569 break;
11570
11571 case eCSR_ENCRYPT_TYPE_AES:
11572 params.cipher = WLAN_CIPHER_SUITE_AES_CMAC;
11573 break;
11574
11575 default:
11576 params.cipher = IW_AUTH_CIPHER_NONE;
11577 break;
11578 }
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053011579
c_hpothuaaf19692014-05-17 17:01:48 +053011580 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
11581 TRACE_CODE_HDD_CFG80211_GET_KEY,
11582 pAdapter->sessionId, params.cipher));
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053011583
Jeff Johnson295189b2012-06-20 16:38:30 -070011584 params.key_len = pRoamProfile->Keys.KeyLength[key_index];
11585 params.seq_len = 0;
11586 params.seq = NULL;
11587 params.key = &pRoamProfile->Keys.KeyMaterial[key_index][0];
11588 callback(cookie, &params);
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053011589 EXIT();
Jeff Johnson295189b2012-06-20 16:38:30 -070011590 return 0;
11591}
11592
Mahesh A Saptasagar1a51bc02014-06-02 18:28:08 +053011593#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
11594static int wlan_hdd_cfg80211_get_key(
11595 struct wiphy *wiphy,
11596 struct net_device *ndev,
11597 u8 key_index, bool pairwise,
11598 const u8 *mac_addr, void *cookie,
11599 void (*callback)(void *cookie, struct key_params*)
11600 )
11601#else
11602static int wlan_hdd_cfg80211_get_key(
11603 struct wiphy *wiphy,
11604 struct net_device *ndev,
11605 u8 key_index, const u8 *mac_addr, void *cookie,
11606 void (*callback)(void *cookie, struct key_params*)
11607 )
11608#endif
11609{
11610 int ret;
11611
11612 vos_ssr_protect(__func__);
11613#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
11614 ret = __wlan_hdd_cfg80211_get_key(wiphy, ndev, key_index, pairwise,
11615 mac_addr, cookie, callback);
11616#else
11617 ret = __wlan_hdd_cfg80211_get_key(wiphy, ndev, key_index, mac_addr,
11618 callback);
11619#endif
11620 vos_ssr_unprotect(__func__);
11621
11622 return ret;
11623}
11624
Jeff Johnson295189b2012-06-20 16:38:30 -070011625/*
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053011626 * FUNCTION: __wlan_hdd_cfg80211_del_key
Jeff Johnson295189b2012-06-20 16:38:30 -070011627 * This function is used to delete the key information
11628 */
11629#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053011630static int __wlan_hdd_cfg80211_del_key( struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -070011631 struct net_device *ndev,
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011632 u8 key_index,
11633 bool pairwise,
Jeff Johnson295189b2012-06-20 16:38:30 -070011634 const u8 *mac_addr
11635 )
11636#else
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053011637static int __wlan_hdd_cfg80211_del_key( struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -070011638 struct net_device *ndev,
11639 u8 key_index,
11640 const u8 *mac_addr
11641 )
11642#endif
11643{
11644 int status = 0;
11645
11646 //This code needs to be revisited. There is sme_removeKey API, we should
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011647 //plan to use that. After the change to use correct index in setkey,
Jeff Johnson295189b2012-06-20 16:38:30 -070011648 //it is observed that this is invalidating peer
11649 //key index whenever re-key is done. This is affecting data link.
11650 //It should be ok to ignore del_key.
11651#if 0
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011652 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( ndev );
11653 v_CONTEXT_t pVosContext = (WLAN_HDD_GET_CTX(pAdapter))->pvosContext;
Jeff Johnson295189b2012-06-20 16:38:30 -070011654 u8 groupmacaddr[WNI_CFG_BSSID_LEN] = {0xFF,0xFF,0xFF,0xFF,0xFF,0xFF};
11655 tCsrRoamSetKey setKey;
11656 v_U32_t roamId= 0xFF;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011657
Jeff Johnson295189b2012-06-20 16:38:30 -070011658 ENTER();
11659
11660 hddLog(VOS_TRACE_LEVEL_INFO_HIGH, "%s: device_mode = %d\n",
11661 __func__,pAdapter->device_mode);
11662
11663 if (CSR_MAX_NUM_KEY <= key_index)
11664 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011665 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Invalid key index %d", __func__,
Jeff Johnson295189b2012-06-20 16:38:30 -070011666 key_index);
11667
11668 return -EINVAL;
11669 }
11670
11671 vos_mem_zero(&setKey,sizeof(tCsrRoamSetKey));
11672 setKey.keyId = key_index;
11673
11674 if (mac_addr)
11675 vos_mem_copy(setKey.peerMac, mac_addr,WNI_CFG_BSSID_LEN);
11676 else
11677 vos_mem_copy(setKey.peerMac, groupmacaddr, WNI_CFG_BSSID_LEN);
11678
11679 setKey.encType = eCSR_ENCRYPT_TYPE_NONE;
11680
11681 if ((pAdapter->device_mode == WLAN_HDD_SOFTAP)
Jeff Johnson295189b2012-06-20 16:38:30 -070011682 || (pAdapter->device_mode == WLAN_HDD_P2P_GO)
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011683 )
11684 {
11685
11686 hdd_hostapd_state_t *pHostapdState =
Jeff Johnson295189b2012-06-20 16:38:30 -070011687 WLAN_HDD_GET_HOSTAP_STATE_PTR(pAdapter);
11688 if( pHostapdState->bssState == BSS_START)
11689 {
11690 status = WLANSAP_SetKeySta( pVosContext, &setKey);
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011691
Jeff Johnson295189b2012-06-20 16:38:30 -070011692 if ( status != eHAL_STATUS_SUCCESS )
11693 {
11694 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
11695 "[%4d] WLANSAP_SetKeySta returned ERROR status= %d",
11696 __LINE__, status );
11697 }
11698 }
11699 }
11700 else if ( (pAdapter->device_mode == WLAN_HDD_INFRA_STATION)
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011701 || (pAdapter->device_mode == WLAN_HDD_P2P_CLIENT)
Jeff Johnson295189b2012-06-20 16:38:30 -070011702 )
11703 {
11704 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
11705
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011706 pHddStaCtx->roam_info.roamingState = HDD_ROAM_STATE_SETTING_KEY;
11707
11708 hddLog(VOS_TRACE_LEVEL_INFO_MED,
Jeff Johnson295189b2012-06-20 16:38:30 -070011709 "%s: delete key for peerMac %2x:%2x:%2x:%2x:%2x:%2x",
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011710 __func__, setKey.peerMac[0], setKey.peerMac[1],
11711 setKey.peerMac[2], setKey.peerMac[3],
Jeff Johnson295189b2012-06-20 16:38:30 -070011712 setKey.peerMac[4], setKey.peerMac[5]);
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011713 if(pAdapter->sessionCtx.station.conn_info.connState ==
11714 eConnectionState_Associated)
Jeff Johnson295189b2012-06-20 16:38:30 -070011715 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011716 status = sme_RoamSetKey( WLAN_HDD_GET_HAL_CTX(pAdapter),
Jeff Johnson295189b2012-06-20 16:38:30 -070011717 pAdapter->sessionId, &setKey, &roamId );
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011718
Jeff Johnson295189b2012-06-20 16:38:30 -070011719 if ( 0 != status )
11720 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011721 hddLog(VOS_TRACE_LEVEL_ERROR,
Jeff Johnson295189b2012-06-20 16:38:30 -070011722 "%s: sme_RoamSetKey failure, returned %d",
11723 __func__, status);
11724 pHddStaCtx->roam_info.roamingState = HDD_ROAM_STATE_NONE;
11725 return -EINVAL;
11726 }
11727 }
11728 }
11729#endif
Jeff Johnsone7245742012-09-05 17:12:55 -070011730 EXIT();
Jeff Johnson295189b2012-06-20 16:38:30 -070011731 return status;
11732}
11733
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053011734#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
11735static int wlan_hdd_cfg80211_del_key( struct wiphy *wiphy,
11736 struct net_device *ndev,
11737 u8 key_index,
11738 bool pairwise,
11739 const u8 *mac_addr
11740 )
11741#else
11742static int wlan_hdd_cfg80211_del_key( struct wiphy *wiphy,
11743 struct net_device *ndev,
11744 u8 key_index,
11745 const u8 *mac_addr
11746 )
11747#endif
11748{
11749 int ret;
11750
11751 vos_ssr_protect(__func__);
11752#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
11753 ret = __wlan_hdd_cfg80211_del_key(wiphy, ndev, key_index, pairwise,
11754 mac_addr);
11755#else
11756 ret = __wlan_hdd_cfg80211_del_key(wiphy, ndev, key_index, mac_addr);
11757#endif
11758 vos_ssr_unprotect(__func__);
11759
11760 return ret;
11761}
11762
Jeff Johnson295189b2012-06-20 16:38:30 -070011763/*
Mahesh A Saptasagar1a51bc02014-06-02 18:28:08 +053011764 * FUNCTION: __wlan_hdd_cfg80211_set_default_key
Jeff Johnson295189b2012-06-20 16:38:30 -070011765 * This function is used to set the default tx key index
11766 */
11767#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
Mahesh A Saptasagar1a51bc02014-06-02 18:28:08 +053011768static int __wlan_hdd_cfg80211_set_default_key( struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -070011769 struct net_device *ndev,
11770 u8 key_index,
11771 bool unicast, bool multicast)
11772#else
Mahesh A Saptasagar1a51bc02014-06-02 18:28:08 +053011773static int __wlan_hdd_cfg80211_set_default_key( struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -070011774 struct net_device *ndev,
11775 u8 key_index)
11776#endif
11777{
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011778 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( ndev );
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053011779 int status;
Gopichand Nakkala29149562013-05-10 21:43:41 +053011780 hdd_wext_state_t *pWextState;
11781 hdd_station_ctx_t *pHddStaCtx;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053011782 hdd_context_t *pHddCtx;
Jeff Johnson295189b2012-06-20 16:38:30 -070011783
11784 ENTER();
11785
Gopichand Nakkala29149562013-05-10 21:43:41 +053011786 if ((NULL == pAdapter))
11787 {
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053011788 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
Gopichand Nakkala29149562013-05-10 21:43:41 +053011789 "invalid adapter");
11790 return -EINVAL;
11791 }
11792
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053011793 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
11794 TRACE_CODE_HDD_CFG80211_SET_DEFAULT_KEY,
11795 pAdapter->sessionId, key_index));
11796
Gopichand Nakkala29149562013-05-10 21:43:41 +053011797 pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
11798 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
11799
11800 if ((NULL == pWextState) || (NULL == pHddStaCtx))
11801 {
11802 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
11803 "invalid Wext state or HDD context");
11804 return -EINVAL;
11805 }
11806
Arif Hussain6d2a3322013-11-17 19:50:10 -080011807 hddLog(VOS_TRACE_LEVEL_INFO, "%s: device_mode = %d key_index = %d",
Jeff Johnson295189b2012-06-20 16:38:30 -070011808 __func__,pAdapter->device_mode, key_index);
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011809
Jeff Johnson295189b2012-06-20 16:38:30 -070011810 if (CSR_MAX_NUM_KEY <= key_index)
11811 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011812 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Invalid key index %d", __func__,
Jeff Johnson295189b2012-06-20 16:38:30 -070011813 key_index);
11814
11815 return -EINVAL;
11816 }
11817
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053011818 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
11819 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053011820 if (0 != status)
Jeff Johnson04dd8a82012-06-29 20:41:40 -070011821 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053011822 return status;
Jeff Johnson04dd8a82012-06-29 20:41:40 -070011823 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011824
Jeff Johnson295189b2012-06-20 16:38:30 -070011825 if ((pAdapter->device_mode == WLAN_HDD_INFRA_STATION)
Jeff Johnson295189b2012-06-20 16:38:30 -070011826 || (pAdapter->device_mode == WLAN_HDD_P2P_CLIENT)
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011827 )
Jeff Johnson295189b2012-06-20 16:38:30 -070011828 {
Gopichand Nakkala29149562013-05-10 21:43:41 +053011829 if ( (eCSR_ENCRYPT_TYPE_TKIP !=
Arif Hussain6943f522013-11-04 20:10:10 -080011830 pHddStaCtx->conn_info.ucEncryptionType) &&
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011831 (eCSR_ENCRYPT_TYPE_AES !=
Arif Hussain6943f522013-11-04 20:10:10 -080011832 pHddStaCtx->conn_info.ucEncryptionType)
Jeff Johnson295189b2012-06-20 16:38:30 -070011833 )
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011834 {
11835 /* if default key index is not same as previous one,
Jeff Johnson295189b2012-06-20 16:38:30 -070011836 * then update the default key index */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011837
Jeff Johnson295189b2012-06-20 16:38:30 -070011838 tCsrRoamSetKey setKey;
11839 v_U32_t roamId= 0xFF;
11840 tCsrKeys *Keys = &pWextState->roamProfile.Keys;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011841
11842 hddLog(VOS_TRACE_LEVEL_INFO_HIGH, "%s: default tx key index %d",
Jeff Johnson295189b2012-06-20 16:38:30 -070011843 __func__, key_index);
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011844
Jeff Johnson295189b2012-06-20 16:38:30 -070011845 Keys->defaultIndex = (u8)key_index;
11846 vos_mem_zero(&setKey,sizeof(tCsrRoamSetKey));
11847 setKey.keyId = key_index;
11848 setKey.keyLength = Keys->KeyLength[key_index];
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011849
11850 vos_mem_copy(&setKey.Key[0],
11851 &Keys->KeyMaterial[key_index][0],
Jeff Johnson295189b2012-06-20 16:38:30 -070011852 Keys->KeyLength[key_index]);
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011853
Gopichand Nakkala29149562013-05-10 21:43:41 +053011854 setKey.keyDirection = eSIR_TX_RX;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011855
11856 vos_mem_copy(setKey.peerMac,
Jeff Johnson295189b2012-06-20 16:38:30 -070011857 &pHddStaCtx->conn_info.bssId[0],
11858 WNI_CFG_BSSID_LEN);
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011859
Gopichand Nakkala29149562013-05-10 21:43:41 +053011860 if (Keys->KeyLength[key_index] == CSR_WEP40_KEY_LEN &&
11861 pWextState->roamProfile.EncryptionType.encryptionType[0] ==
11862 eCSR_ENCRYPT_TYPE_WEP104)
11863 {
11864 /*In the case of dynamic wep supplicant hardcodes DWEP type to eCSR_ENCRYPT_TYPE_WEP104
11865 even though ap is configured for WEP-40 encryption. In this canse the key length
11866 is 5 but the encryption type is 104 hence checking the key langht(5) and encryption
11867 type(104) and switching encryption type to 40*/
11868 pWextState->roamProfile.EncryptionType.encryptionType[0] =
11869 eCSR_ENCRYPT_TYPE_WEP40;
11870 pWextState->roamProfile.mcEncryptionType.encryptionType[0] =
11871 eCSR_ENCRYPT_TYPE_WEP40;
11872 }
11873
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011874 setKey.encType =
Jeff Johnson295189b2012-06-20 16:38:30 -070011875 pWextState->roamProfile.EncryptionType.encryptionType[0];
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011876
Jeff Johnson295189b2012-06-20 16:38:30 -070011877 /* issue set key request */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011878 status = sme_RoamSetKey( WLAN_HDD_GET_HAL_CTX(pAdapter),
Jeff Johnson295189b2012-06-20 16:38:30 -070011879 pAdapter->sessionId, &setKey, &roamId );
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011880
Jeff Johnson295189b2012-06-20 16:38:30 -070011881 if ( 0 != status )
11882 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011883 hddLog(VOS_TRACE_LEVEL_ERROR,
11884 "%s: sme_RoamSetKey failed, returned %d", __func__,
Jeff Johnson295189b2012-06-20 16:38:30 -070011885 status);
11886 return -EINVAL;
11887 }
11888 }
11889 }
11890
11891 /* In SoftAp mode setting key direction for default mode */
11892 else if ( WLAN_HDD_SOFTAP == pAdapter->device_mode )
11893 {
11894 if ( (eCSR_ENCRYPT_TYPE_TKIP !=
11895 pWextState->roamProfile.EncryptionType.encryptionType[0]) &&
11896 (eCSR_ENCRYPT_TYPE_AES !=
11897 pWextState->roamProfile.EncryptionType.encryptionType[0])
11898 )
11899 {
11900 /* Saving key direction for default key index to TX default */
11901 hdd_ap_ctx_t *pAPCtx = WLAN_HDD_GET_AP_CTX_PTR(pAdapter);
11902 pAPCtx->wepKey[key_index].keyDirection = eSIR_TX_DEFAULT;
11903 }
11904 }
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053011905 EXIT();
Jeff Johnson295189b2012-06-20 16:38:30 -070011906 return status;
11907}
11908
Mahesh A Saptasagar1a51bc02014-06-02 18:28:08 +053011909#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
11910static int wlan_hdd_cfg80211_set_default_key( struct wiphy *wiphy,
11911 struct net_device *ndev,
11912 u8 key_index,
11913 bool unicast, bool multicast)
11914#else
11915static int wlan_hdd_cfg80211_set_default_key( struct wiphy *wiphy,
11916 struct net_device *ndev,
11917 u8 key_index)
11918#endif
11919{
11920 int ret;
11921 vos_ssr_protect(__func__);
11922#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
11923 ret = __wlan_hdd_cfg80211_set_default_key(wiphy, ndev, key_index, unicast,
11924 multicast);
11925#else
11926 ret = __wlan_hdd_cfg80211_set_default_key(wiphy, ndev, key_index);
11927#endif
11928 vos_ssr_unprotect(__func__);
11929
11930 return ret;
11931}
11932
Jeff Johnson295189b2012-06-20 16:38:30 -070011933/*
11934 * FUNCTION: wlan_hdd_cfg80211_inform_bss
11935 * This function is used to inform the BSS details to nl80211 interface.
11936 */
11937static struct cfg80211_bss* wlan_hdd_cfg80211_inform_bss(
11938 hdd_adapter_t *pAdapter, tCsrRoamConnectedProfile *roamProfile)
11939{
11940 struct net_device *dev = pAdapter->dev;
11941 struct wireless_dev *wdev = dev->ieee80211_ptr;
11942 struct wiphy *wiphy = wdev->wiphy;
11943 tSirBssDescription *pBssDesc = roamProfile->pBssDesc;
11944 int chan_no;
11945 int ie_length;
11946 const char *ie;
11947 unsigned int freq;
11948 struct ieee80211_channel *chan;
11949 int rssi = 0;
11950 struct cfg80211_bss *bss = NULL;
11951
Jeff Johnson295189b2012-06-20 16:38:30 -070011952 if( NULL == pBssDesc )
11953 {
Arif Hussain6d2a3322013-11-17 19:50:10 -080011954 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: pBssDesc is NULL", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -070011955 return bss;
11956 }
11957
11958 chan_no = pBssDesc->channelId;
11959 ie_length = GET_IE_LEN_IN_BSS_DESC( pBssDesc->length );
11960 ie = ((ie_length != 0) ? (const char *)&pBssDesc->ieFields: NULL);
11961
11962 if( NULL == ie )
11963 {
Arif Hussain6d2a3322013-11-17 19:50:10 -080011964 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: IE of BSS descriptor is NULL", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -070011965 return bss;
11966 }
11967
11968#if (LINUX_VERSION_CODE > KERNEL_VERSION(2,6,38))
11969 if (chan_no <= ARRAY_SIZE(hdd_channels_2_4_GHZ))
11970 {
11971 freq = ieee80211_channel_to_frequency(chan_no, IEEE80211_BAND_2GHZ);
11972 }
11973 else
11974 {
11975 freq = ieee80211_channel_to_frequency(chan_no, IEEE80211_BAND_5GHZ);
11976 }
11977#else
11978 freq = ieee80211_channel_to_frequency(chan_no);
11979#endif
11980
11981 chan = __ieee80211_get_channel(wiphy, freq);
11982
Santhosh Kumar Padmaa45fdb12014-04-15 15:54:38 +053011983 if (!chan) {
11984 hddLog(VOS_TRACE_LEVEL_ERROR, "%s chan pointer is NULL", __func__);
11985 return NULL;
11986 }
11987
Abhishek Singhaee43942014-06-16 18:55:47 +053011988 rssi = (VOS_MIN ((pBssDesc->rssi + pBssDesc->sinr), 0))*100;
Jeff Johnson295189b2012-06-20 16:38:30 -070011989
Anand N Sunkad9f80b742015-07-30 20:05:51 +053011990 return cfg80211_inform_bss(wiphy, chan,
11991#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,18,0))
11992 CFG80211_BSS_FTYPE_UNKNOWN,
11993#endif
11994 pBssDesc->bssId,
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011995 le64_to_cpu(*(__le64 *)pBssDesc->timeStamp),
Jeff Johnson295189b2012-06-20 16:38:30 -070011996 pBssDesc->capabilityInfo,
11997 pBssDesc->beaconInterval, ie, ie_length,
Abhishek Singhaee43942014-06-16 18:55:47 +053011998 rssi, GFP_KERNEL );
Jeff Johnson295189b2012-06-20 16:38:30 -070011999}
12000
12001
12002
12003/*
12004 * FUNCTION: wlan_hdd_cfg80211_inform_bss_frame
12005 * This function is used to inform the BSS details to nl80211 interface.
12006 */
12007struct cfg80211_bss*
12008wlan_hdd_cfg80211_inform_bss_frame( hdd_adapter_t *pAdapter,
12009 tSirBssDescription *bss_desc
12010 )
12011{
12012 /*
12013 cfg80211_inform_bss() is not updating ie field of bss entry, if entry
12014 already exists in bss data base of cfg80211 for that particular BSS ID.
12015 Using cfg80211_inform_bss_frame to update the bss entry instead of
12016 cfg80211_inform_bss, But this call expects mgmt packet as input. As of
12017 now there is no possibility to get the mgmt(probe response) frame from PE,
12018 converting bss_desc to ieee80211_mgmt(probe response) and passing to
12019 cfg80211_inform_bss_frame.
12020 */
12021 struct net_device *dev = pAdapter->dev;
12022 struct wireless_dev *wdev = dev->ieee80211_ptr;
12023 struct wiphy *wiphy = wdev->wiphy;
12024 int chan_no = bss_desc->channelId;
Madan Mohan Koyyalamudi86f629e2012-11-09 16:27:29 -080012025#ifdef WLAN_ENABLE_AGEIE_ON_SCAN_RESULTS
12026 qcom_ie_age *qie_age = NULL;
12027 int ie_length = GET_IE_LEN_IN_BSS_DESC( bss_desc->length ) + sizeof(qcom_ie_age);
12028#else
Jeff Johnson295189b2012-06-20 16:38:30 -070012029 int ie_length = GET_IE_LEN_IN_BSS_DESC( bss_desc->length );
Madan Mohan Koyyalamudi86f629e2012-11-09 16:27:29 -080012030#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070012031 const char *ie =
12032 ((ie_length != 0) ? (const char *)&bss_desc->ieFields: NULL);
12033 unsigned int freq;
12034 struct ieee80211_channel *chan;
Abhishek Singh1e2bfa32014-01-02 15:44:15 +053012035 struct ieee80211_mgmt *mgmt = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -070012036 struct cfg80211_bss *bss_status = NULL;
12037 size_t frame_len = sizeof (struct ieee80211_mgmt) + ie_length;
12038 int rssi = 0;
Wilson Yangf80a0542013-10-07 13:02:37 -070012039 hdd_context_t *pHddCtx;
12040 int status;
Jeff Johnsone7245742012-09-05 17:12:55 -070012041#ifdef WLAN_OPEN_SOURCE
12042 struct timespec ts;
12043#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070012044
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053012045
Wilson Yangf80a0542013-10-07 13:02:37 -070012046 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
12047 status = wlan_hdd_validate_context(pHddCtx);
Wilson Yangf80a0542013-10-07 13:02:37 -070012048 if (0 != status)
12049 {
Madan Mohan Koyyalamudi2e5c9142012-11-02 13:17:48 -070012050 return NULL;
Wilson Yangf80a0542013-10-07 13:02:37 -070012051 }
12052
Abhishek Singh1e2bfa32014-01-02 15:44:15 +053012053 mgmt = kzalloc((sizeof (struct ieee80211_mgmt) + ie_length), GFP_KERNEL);
Wilson Yangf80a0542013-10-07 13:02:37 -070012054 if (!mgmt)
12055 {
12056 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
12057 "%s: memory allocation failed ", __func__);
12058 return NULL;
12059 }
Madan Mohan Koyyalamudi2e5c9142012-11-02 13:17:48 -070012060
Jeff Johnson295189b2012-06-20 16:38:30 -070012061 memcpy(mgmt->bssid, bss_desc->bssId, ETH_ALEN);
Jeff Johnsone7245742012-09-05 17:12:55 -070012062
12063#ifdef WLAN_OPEN_SOURCE
12064 /* Android does not want the timestamp from the frame.
12065 Instead it wants a monotonic increasing value */
12066 get_monotonic_boottime(&ts);
12067 mgmt->u.probe_resp.timestamp =
12068 ((u64)ts.tv_sec * 1000000) + (ts.tv_nsec / 1000);
12069#else
12070 /* keep old behavior for non-open source (for now) */
Jeff Johnson295189b2012-06-20 16:38:30 -070012071 memcpy(&mgmt->u.probe_resp.timestamp, bss_desc->timeStamp,
12072 sizeof (bss_desc->timeStamp));
Jeff Johnsone7245742012-09-05 17:12:55 -070012073
12074#endif
12075
Jeff Johnson295189b2012-06-20 16:38:30 -070012076 mgmt->u.probe_resp.beacon_int = bss_desc->beaconInterval;
12077 mgmt->u.probe_resp.capab_info = bss_desc->capabilityInfo;
Madan Mohan Koyyalamudi86f629e2012-11-09 16:27:29 -080012078
12079#ifdef WLAN_ENABLE_AGEIE_ON_SCAN_RESULTS
12080 /* GPS Requirement: need age ie per entry. Using vendor specific. */
12081 /* Assuming this is the last IE, copy at the end */
12082 ie_length -=sizeof(qcom_ie_age);
12083 qie_age = (qcom_ie_age *)(mgmt->u.probe_resp.variable + ie_length);
12084 qie_age->element_id = QCOM_VENDOR_IE_ID;
12085 qie_age->len = QCOM_VENDOR_IE_AGE_LEN;
12086 qie_age->oui_1 = QCOM_OUI1;
12087 qie_age->oui_2 = QCOM_OUI2;
12088 qie_age->oui_3 = QCOM_OUI3;
12089 qie_age->type = QCOM_VENDOR_IE_AGE_TYPE;
12090 qie_age->age = vos_timer_get_system_ticks() - bss_desc->nReceivedTime;
12091#endif
12092
Jeff Johnson295189b2012-06-20 16:38:30 -070012093 memcpy(mgmt->u.probe_resp.variable, ie, ie_length);
Gopichand Nakkalad908ec82013-05-16 19:32:19 +053012094 if (bss_desc->fProbeRsp)
12095 {
12096 mgmt->frame_control |=
12097 (u16)(IEEE80211_FTYPE_MGMT | IEEE80211_STYPE_PROBE_RESP);
12098 }
12099 else
12100 {
12101 mgmt->frame_control |=
12102 (u16)(IEEE80211_FTYPE_MGMT | IEEE80211_STYPE_BEACON);
12103 }
Jeff Johnson295189b2012-06-20 16:38:30 -070012104
12105#if (LINUX_VERSION_CODE > KERNEL_VERSION(2,6,38))
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012106 if (chan_no <= ARRAY_SIZE(hdd_channels_2_4_GHZ) &&
Jeff Johnson295189b2012-06-20 16:38:30 -070012107 (wiphy->bands[IEEE80211_BAND_2GHZ] != NULL))
12108 {
12109 freq = ieee80211_channel_to_frequency(chan_no, IEEE80211_BAND_2GHZ);
12110 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012111 else if ((chan_no > ARRAY_SIZE(hdd_channels_2_4_GHZ)) &&
Jeff Johnson295189b2012-06-20 16:38:30 -070012112 (wiphy->bands[IEEE80211_BAND_5GHZ] != NULL))
12113
12114 {
12115 freq = ieee80211_channel_to_frequency(chan_no, IEEE80211_BAND_5GHZ);
12116 }
12117 else
12118 {
Nirav Shah20ac06f2013-12-12 18:14:06 +053012119 hddLog(VOS_TRACE_LEVEL_ERROR, "%s Invalid chan_no:%d",
12120 __func__, chan_no);
Jeff Johnson295189b2012-06-20 16:38:30 -070012121 kfree(mgmt);
12122 return NULL;
12123 }
12124#else
12125 freq = ieee80211_channel_to_frequency(chan_no);
12126#endif
12127 chan = __ieee80211_get_channel(wiphy, freq);
Leela V Kiran Kumar Reddy90032de2013-01-24 18:33:30 -080012128 /*when the band is changed on the fly using the GUI, three things are done
12129 * 1. scan abort 2.flush scan results from cache 3.update the band with the new band user specified(refer to the hdd_setBand_helper function)
12130 * as part of the scan abort, message willbe queued to PE and we proceed with flushing and changinh the band.
12131 * pe will stop the scanning further and report back the results what ever it had till now by calling the call back function.
12132 * if the time between update band and scandone call back is sufficent enough the band change reflects in SME, SME validates the channels
12133 * and discards the channels correponding to previous band and calls back with zero bss results.
12134 * but if the time between band update and scan done callback is very small then band change will not reflect in SME and SME reports to HDD
12135 * all the channels correponding to previous band.this is due to race condition.but those channels are invalid to the new band and so
12136 * this function __ieee80211_get_channel will return NULL.Each time we report scan result with this pointer null warning kernel trace is printed.
12137 * if the scan results contain large number of APs continuosly kernel warning trace is printed and it will lead to apps watch dog bark.
12138 * So drop the bss and continue to next bss.
12139 */
12140 if(chan == NULL)
12141 {
Nirav Shah20ac06f2013-12-12 18:14:06 +053012142 hddLog(VOS_TRACE_LEVEL_ERROR, "%s chan pointer is NULL", __func__);
Chilam Ngc4244af2013-04-01 15:37:32 -070012143 kfree(mgmt);
Leela V Kiran Kumar Reddy90032de2013-01-24 18:33:30 -080012144 return NULL;
12145 }
Hanumantha Reddy Pothula904bcef2015-06-19 11:56:29 +053012146 /*To keep the rssi icon of the connected AP in the scan window
12147 *and the rssi icon of the wireless networks in sync
12148 * */
12149 if (( eConnectionState_Associated ==
12150 pAdapter->sessionCtx.station.conn_info.connState ) &&
12151 ( VOS_TRUE == vos_mem_compare(bss_desc->bssId,
12152 pAdapter->sessionCtx.station.conn_info.bssId,
12153 WNI_CFG_BSSID_LEN)) &&
12154 (pHddCtx->hdd_wlan_suspended == FALSE))
12155 {
12156 /* supplicant takes the signal strength in terms of mBm(100*dBm) */
12157 rssi = (pAdapter->rssi * 100);
12158 }
12159 else
12160 {
12161 rssi = (VOS_MIN ((bss_desc->rssi + bss_desc->sinr), 0))*100;
12162 }
Jeff Johnson295189b2012-06-20 16:38:30 -070012163
Nirav Shah20ac06f2013-12-12 18:14:06 +053012164 hddLog(VOS_TRACE_LEVEL_INFO, "%s: BSSID:" MAC_ADDRESS_STR " Channel:%d"
Sushant Kaushik0b343422015-05-25 17:15:55 +053012165 " RSSI:%d", __func__, MAC_ADDR_ARRAY(mgmt->bssid),
12166 vos_freq_to_chan(chan->center_freq), (int)(rssi/100));
Nirav Shah20ac06f2013-12-12 18:14:06 +053012167
Jeff Johnson295189b2012-06-20 16:38:30 -070012168 bss_status = cfg80211_inform_bss_frame(wiphy, chan, mgmt,
12169 frame_len, rssi, GFP_KERNEL);
12170 kfree(mgmt);
12171 return bss_status;
12172}
12173
12174/*
12175 * FUNCTION: wlan_hdd_cfg80211_update_bss_db
12176 * This function is used to update the BSS data base of CFG8011
12177 */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012178struct cfg80211_bss* wlan_hdd_cfg80211_update_bss_db( hdd_adapter_t *pAdapter,
Jeff Johnson295189b2012-06-20 16:38:30 -070012179 tCsrRoamInfo *pRoamInfo
12180 )
12181{
12182 tCsrRoamConnectedProfile roamProfile;
12183 tHalHandle hHal = WLAN_HDD_GET_HAL_CTX(pAdapter);
12184 struct cfg80211_bss *bss = NULL;
12185
12186 ENTER();
12187
12188 memset(&roamProfile, 0, sizeof(tCsrRoamConnectedProfile));
12189 sme_RoamGetConnectProfile(hHal, pAdapter->sessionId, &roamProfile);
12190
12191 if (NULL != roamProfile.pBssDesc)
12192 {
Girish Gowlif4b68022014-08-28 23:18:57 +053012193 bss = wlan_hdd_cfg80211_inform_bss_frame(pAdapter,
12194 roamProfile.pBssDesc);
Jeff Johnson295189b2012-06-20 16:38:30 -070012195
12196 if (NULL == bss)
12197 {
12198 hddLog(VOS_TRACE_LEVEL_INFO, "%s: cfg80211_inform_bss return NULL",
12199 __func__);
12200 }
12201
12202 sme_RoamFreeConnectProfile(hHal, &roamProfile);
12203 }
12204 else
12205 {
12206 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: roamProfile.pBssDesc is NULL",
12207 __func__);
12208 }
12209 return bss;
12210}
12211
12212/*
12213 * FUNCTION: wlan_hdd_cfg80211_update_bss
12214 */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012215static int wlan_hdd_cfg80211_update_bss( struct wiphy *wiphy,
12216 hdd_adapter_t *pAdapter
Jeff Johnson295189b2012-06-20 16:38:30 -070012217 )
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012218{
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053012219 tHalHandle hHal = WLAN_HDD_GET_HAL_CTX(pAdapter);
Jeff Johnson295189b2012-06-20 16:38:30 -070012220 tCsrScanResultInfo *pScanResult;
12221 eHalStatus status = 0;
12222 tScanResultHandle pResult;
12223 struct cfg80211_bss *bss_status = NULL;
Wilson Yangf80a0542013-10-07 13:02:37 -070012224 hdd_context_t *pHddCtx;
Deepthi Gowri10d0ae12015-05-25 14:39:50 +053012225 bool is_p2p_scan = false;
Jeff Johnson295189b2012-06-20 16:38:30 -070012226 ENTER();
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053012227
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053012228 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
12229 TRACE_CODE_HDD_CFG80211_UPDATE_BSS,
12230 NO_SESSION, pAdapter->sessionId));
12231
Wilson Yangf80a0542013-10-07 13:02:37 -070012232 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
12233
12234 if (pHddCtx->isLogpInProgress)
Jeff Johnson295189b2012-06-20 16:38:30 -070012235 {
Wilson Yangf80a0542013-10-07 13:02:37 -070012236 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
12237 "%s:LOGP in Progress. Ignore!!!",__func__);
12238 return -EAGAIN;
Jeff Johnson295189b2012-06-20 16:38:30 -070012239 }
12240
Wilson Yangf80a0542013-10-07 13:02:37 -070012241
12242 /*bss_update is not allowed during wlan driver loading or unloading*/
Mihir Shete18156292014-03-11 15:38:30 +053012243 if (WLAN_HDD_IS_LOAD_UNLOAD_IN_PROGRESS(pHddCtx))
Wilson Yangf80a0542013-10-07 13:02:37 -070012244 {
12245 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
12246 "%s:Loading_unloading in Progress. Ignore!!!",__func__);
12247 return VOS_STATUS_E_PERM;
12248 }
12249
Deepthi Gowri10d0ae12015-05-25 14:39:50 +053012250 if (pAdapter->request != NULL)
12251 {
12252 if ((pAdapter->request->n_ssids == 1)
12253 && (pAdapter->request->ssids != NULL)
12254 && vos_mem_compare(&pAdapter->request->ssids[0], "DIRECT-", 7))
12255 is_p2p_scan = true;
12256 }
Jeff Johnson295189b2012-06-20 16:38:30 -070012257 /*
12258 * start getting scan results and populate cgf80211 BSS database
12259 */
12260 status = sme_ScanGetResult(hHal, pAdapter->sessionId, NULL, &pResult);
12261
12262 /* no scan results */
12263 if (NULL == pResult)
12264 {
Nirav Shah20ac06f2013-12-12 18:14:06 +053012265 hddLog(VOS_TRACE_LEVEL_INFO, "%s: No scan result Status %d",
12266 __func__, status);
Mahesh A Saptasagar51dc36c2015-06-16 12:07:15 +053012267 wlan_hdd_get_frame_logs(pAdapter,
12268 WLAN_HDD_GET_FRAME_LOG_CMD_SEND_AND_CLEAR);
Jeff Johnson295189b2012-06-20 16:38:30 -070012269 return status;
12270 }
12271
12272 pScanResult = sme_ScanResultGetFirst(hHal, pResult);
12273
12274 while (pScanResult)
12275 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012276 /*
12277 * cfg80211_inform_bss() is not updating ie field of bss entry, if
12278 * entry already exists in bss data base of cfg80211 for that
12279 * particular BSS ID. Using cfg80211_inform_bss_frame to update the
12280 * bss entry instead of cfg80211_inform_bss, But this call expects
12281 * mgmt packet as input. As of now there is no possibility to get
12282 * the mgmt(probe response) frame from PE, converting bss_desc to
Jeff Johnson295189b2012-06-20 16:38:30 -070012283 * ieee80211_mgmt(probe response) and passing to c
12284 * fg80211_inform_bss_frame.
12285 * */
Deepthi Gowri10d0ae12015-05-25 14:39:50 +053012286 if(is_p2p_scan && (pScanResult->ssId.ssId != NULL) &&
12287 !vos_mem_compare( pScanResult->ssId.ssId, "DIRECT-", 7) )
12288 {
Deepthi Gowri10d0ae12015-05-25 14:39:50 +053012289 pScanResult = sme_ScanResultGetNext(hHal, pResult);
12290 continue; //Skip the non p2p bss entries
12291 }
Jeff Johnson295189b2012-06-20 16:38:30 -070012292 bss_status = wlan_hdd_cfg80211_inform_bss_frame(pAdapter,
12293 &pScanResult->BssDescriptor);
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012294
Jeff Johnson295189b2012-06-20 16:38:30 -070012295
12296 if (NULL == bss_status)
12297 {
12298 hddLog(VOS_TRACE_LEVEL_INFO,
Arif Hussain6d2a3322013-11-17 19:50:10 -080012299 "%s: NULL returned by cfg80211_inform_bss", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -070012300 }
12301 else
12302 {
Yue Maf49ba872013-08-19 12:04:25 -070012303 cfg80211_put_bss(
12304#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,9,0))
12305 wiphy,
12306#endif
12307 bss_status);
Jeff Johnson295189b2012-06-20 16:38:30 -070012308 }
12309
12310 pScanResult = sme_ScanResultGetNext(hHal, pResult);
12311 }
12312
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012313 sme_ScanResultPurge(hHal, pResult);
Deepthi Gowri10d0ae12015-05-25 14:39:50 +053012314 is_p2p_scan = false;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012315 return 0;
Jeff Johnson295189b2012-06-20 16:38:30 -070012316}
12317
Jeff Johnson04dd8a82012-06-29 20:41:40 -070012318void
12319hddPrintMacAddr(tCsrBssid macAddr, tANI_U8 logLevel)
12320{
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012321 VOS_TRACE(VOS_MODULE_ID_HDD, logLevel,
Arif Hussaina7c8e412013-11-20 11:06:42 -080012322 MAC_ADDRESS_STR, MAC_ADDR_ARRAY(macAddr));
Jeff Johnson04dd8a82012-06-29 20:41:40 -070012323} /****** end hddPrintMacAddr() ******/
12324
12325void
Madan Mohan Koyyalamudic75be962012-10-18 19:19:03 -070012326hddPrintPmkId(tANI_U8 *pmkId, tANI_U8 logLevel)
Jeff Johnson04dd8a82012-06-29 20:41:40 -070012327{
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012328 VOS_TRACE(VOS_MODULE_ID_HDD, logLevel,
Arif Hussain6d2a3322013-11-17 19:50:10 -080012329 "%02X:%02X:%02X:%02X:%02X:%02X:%02X:%02X:%02X:%02X:%02X:%02X:%02X:%02X:%02X:%02X",
Madan Mohan Koyyalamudic75be962012-10-18 19:19:03 -070012330 pmkId[0], pmkId[1], pmkId[2], pmkId[3], pmkId[4],
12331 pmkId[5], pmkId[6], pmkId[7], pmkId[8], pmkId[9], pmkId[10],
12332 pmkId[11], pmkId[12], pmkId[13], pmkId[14], pmkId[15]);
Jeff Johnson04dd8a82012-06-29 20:41:40 -070012333} /****** end hddPrintPmkId() ******/
12334
12335//hddPrintMacAddr(tCsrBssid macAddr, tANI_U8 logLevel);
12336//hddPrintMacAddr(macAddr, VOS_TRACE_LEVEL_FATAL);
12337
12338//void sirDumpBuf(tpAniSirGlobal pMac, tANI_U8 modId, tANI_U32 level, tANI_U8 *buf, tANI_U32 size);
12339//sirDumpBuf(pMac, VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL, pmkid, 16);
12340
12341#define dump_bssid(bssid) \
12342 { \
Jeff Johnsone7245742012-09-05 17:12:55 -070012343 hddLog(VOS_TRACE_LEVEL_INFO, "BSSID (MAC) address:\t"); \
12344 hddPrintMacAddr(bssid, VOS_TRACE_LEVEL_INFO);\
Jeff Johnson04dd8a82012-06-29 20:41:40 -070012345 }
12346
12347#define dump_pmkid(pMac, pmkid) \
12348 { \
Jeff Johnsone7245742012-09-05 17:12:55 -070012349 hddLog(VOS_TRACE_LEVEL_INFO, "PMKSA-ID:\t"); \
12350 hddPrintPmkId(pmkid, VOS_TRACE_LEVEL_INFO);\
Jeff Johnson04dd8a82012-06-29 20:41:40 -070012351 }
12352
Madan Mohan Koyyalamudi1b4afb02012-10-22 15:25:16 -070012353#if defined(FEATURE_WLAN_LFR) && (LINUX_VERSION_CODE >= KERNEL_VERSION(3,4,0))
Jeff Johnson04dd8a82012-06-29 20:41:40 -070012354/*
12355 * FUNCTION: wlan_hdd_cfg80211_pmksa_candidate_notify
12356 * This function is used to notify the supplicant of a new PMKSA candidate.
12357 */
12358int wlan_hdd_cfg80211_pmksa_candidate_notify(
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012359 hdd_adapter_t *pAdapter, tCsrRoamInfo *pRoamInfo,
Jeff Johnson04dd8a82012-06-29 20:41:40 -070012360 int index, bool preauth )
12361{
Jeff Johnsone7245742012-09-05 17:12:55 -070012362#ifdef FEATURE_WLAN_OKC
Jeff Johnson04dd8a82012-06-29 20:41:40 -070012363 struct net_device *dev = pAdapter->dev;
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -070012364 hdd_context_t *pHddCtx = (hdd_context_t*)pAdapter->pHddCtx;
Jeff Johnson04dd8a82012-06-29 20:41:40 -070012365
12366 ENTER();
Jeff Johnsone7245742012-09-05 17:12:55 -070012367 hddLog(VOS_TRACE_LEVEL_INFO, "%s is going to notify supplicant of:", __func__);
Jeff Johnson04dd8a82012-06-29 20:41:40 -070012368
12369 if( NULL == pRoamInfo )
12370 {
Arif Hussain6d2a3322013-11-17 19:50:10 -080012371 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: pRoamInfo is NULL", __func__);
Jeff Johnson04dd8a82012-06-29 20:41:40 -070012372 return -EINVAL;
12373 }
12374
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -070012375 if (eANI_BOOLEAN_TRUE == hdd_is_okc_mode_enabled(pHddCtx))
12376 {
12377 dump_bssid(pRoamInfo->bssid);
12378 cfg80211_pmksa_candidate_notify(dev, index,
Jeff Johnson04dd8a82012-06-29 20:41:40 -070012379 pRoamInfo->bssid, preauth, GFP_KERNEL);
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -070012380 }
Jeff Johnsone7245742012-09-05 17:12:55 -070012381#endif /* FEATURE_WLAN_OKC */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012382 return 0;
Jeff Johnson04dd8a82012-06-29 20:41:40 -070012383}
12384#endif //FEATURE_WLAN_LFR
12385
Yue Maef608272013-04-08 23:09:17 -070012386#ifdef FEATURE_WLAN_LFR_METRICS
12387/*
12388 * FUNCTION: wlan_hdd_cfg80211_roam_metrics_preauth
12389 * 802.11r/LFR metrics reporting function to report preauth initiation
12390 *
12391 */
12392#define MAX_LFR_METRICS_EVENT_LENGTH 100
12393VOS_STATUS wlan_hdd_cfg80211_roam_metrics_preauth(hdd_adapter_t *pAdapter,
12394 tCsrRoamInfo *pRoamInfo)
12395{
12396 unsigned char metrics_notification[MAX_LFR_METRICS_EVENT_LENGTH + 1];
12397 union iwreq_data wrqu;
12398
12399 ENTER();
12400
12401 if (NULL == pAdapter)
12402 {
12403 hddLog(LOGE, "%s: pAdapter is NULL!", __func__);
12404 return VOS_STATUS_E_FAILURE;
12405 }
12406
12407 /* create the event */
12408 memset(&wrqu, 0, sizeof(wrqu));
12409 memset(metrics_notification, 0, sizeof(metrics_notification));
12410
12411 wrqu.data.pointer = metrics_notification;
12412 wrqu.data.length = scnprintf(metrics_notification,
12413 sizeof(metrics_notification), "QCOM: LFR_PREAUTH_INIT "
12414 MAC_ADDRESS_STR, MAC_ADDR_ARRAY(pRoamInfo->bssid));
12415
12416 wireless_send_event(pAdapter->dev, IWEVCUSTOM, &wrqu, metrics_notification);
12417
12418 EXIT();
12419
12420 return VOS_STATUS_SUCCESS;
12421}
12422
12423/*
12424 * FUNCTION: wlan_hdd_cfg80211_roam_metrics_preauth_status
12425 * 802.11r/LFR metrics reporting function to report preauth completion
12426 * or failure
12427 */
12428VOS_STATUS wlan_hdd_cfg80211_roam_metrics_preauth_status(
12429 hdd_adapter_t *pAdapter, tCsrRoamInfo *pRoamInfo, bool preauth_status)
12430{
12431 unsigned char metrics_notification[MAX_LFR_METRICS_EVENT_LENGTH + 1];
12432 union iwreq_data wrqu;
12433
12434 ENTER();
12435
12436 if (NULL == pAdapter)
12437 {
12438 hddLog(LOGE, "%s: pAdapter is NULL!", __func__);
12439 return VOS_STATUS_E_FAILURE;
12440 }
12441
12442 /* create the event */
12443 memset(&wrqu, 0, sizeof(wrqu));
12444 memset(metrics_notification, 0, sizeof(metrics_notification));
12445
12446 scnprintf(metrics_notification, sizeof(metrics_notification),
12447 "QCOM: LFR_PREAUTH_STATUS "MAC_ADDRESS_STR,
12448 MAC_ADDR_ARRAY(pRoamInfo->bssid));
12449
12450 if (1 == preauth_status)
12451 strncat(metrics_notification, " TRUE", 5);
12452 else
12453 strncat(metrics_notification, " FALSE", 6);
12454
12455 wrqu.data.pointer = metrics_notification;
12456 wrqu.data.length = strlen(metrics_notification);
12457
12458 wireless_send_event(pAdapter->dev, IWEVCUSTOM, &wrqu, metrics_notification);
12459
12460 EXIT();
12461
12462 return VOS_STATUS_SUCCESS;
12463}
12464
12465/*
12466 * FUNCTION: wlan_hdd_cfg80211_roam_metrics_handover
12467 * 802.11r/LFR metrics reporting function to report handover initiation
12468 *
12469 */
12470VOS_STATUS wlan_hdd_cfg80211_roam_metrics_handover(hdd_adapter_t * pAdapter,
12471 tCsrRoamInfo *pRoamInfo)
12472{
12473 unsigned char metrics_notification[MAX_LFR_METRICS_EVENT_LENGTH + 1];
12474 union iwreq_data wrqu;
12475
12476 ENTER();
12477
12478 if (NULL == pAdapter)
12479 {
12480 hddLog(LOGE, "%s: pAdapter is NULL!", __func__);
12481 return VOS_STATUS_E_FAILURE;
12482 }
12483
12484 /* create the event */
12485 memset(&wrqu, 0, sizeof(wrqu));
12486 memset(metrics_notification, 0, sizeof(metrics_notification));
12487
12488 wrqu.data.pointer = metrics_notification;
12489 wrqu.data.length = scnprintf(metrics_notification,
12490 sizeof(metrics_notification), "QCOM: LFR_PREAUTH_HANDOVER "
12491 MAC_ADDRESS_STR, MAC_ADDR_ARRAY(pRoamInfo->bssid));
12492
12493 wireless_send_event(pAdapter->dev, IWEVCUSTOM, &wrqu, metrics_notification);
12494
12495 EXIT();
12496
12497 return VOS_STATUS_SUCCESS;
12498}
12499#endif
12500
Jeff Johnson295189b2012-06-20 16:38:30 -070012501/*
12502 * FUNCTION: hdd_cfg80211_scan_done_callback
12503 * scanning callback function, called after finishing scan
12504 *
12505 */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012506static eHalStatus hdd_cfg80211_scan_done_callback(tHalHandle halHandle,
Jeff Johnson295189b2012-06-20 16:38:30 -070012507 void *pContext, tANI_U32 scanId, eCsrScanStatus status)
12508{
12509 struct net_device *dev = (struct net_device *) pContext;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012510 //struct wireless_dev *wdev = dev->ieee80211_ptr;
Jeff Johnson295189b2012-06-20 16:38:30 -070012511 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( dev );
Chandrasekaran, Manishekar41b8e1f2015-03-10 13:30:28 +053012512 hdd_scaninfo_t *pScanInfo;
Jeff Johnson295189b2012-06-20 16:38:30 -070012513 struct cfg80211_scan_request *req = NULL;
12514 int ret = 0;
Mahesh A Saptasagar05a357e2014-02-26 16:28:06 +053012515 bool aborted = false;
c_hpothu6ff1c3c2013-10-01 19:01:57 +053012516 long waitRet = 0;
Agarwal Ashishbd3e10b2014-11-24 19:19:46 +053012517 tANI_U8 i;
Chandrasekaran, Manishekar41b8e1f2015-03-10 13:30:28 +053012518 hdd_context_t *pHddCtx;
Jeff Johnson295189b2012-06-20 16:38:30 -070012519
12520 ENTER();
12521
Chandrasekaran, Manishekar41b8e1f2015-03-10 13:30:28 +053012522 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Siddharth Bhal5c2e02d2015-05-05 17:35:29 +053012523 if (NULL == pHddCtx) {
12524 hddLog(VOS_TRACE_LEVEL_ERROR, FL("HDD context is Null"));
Chandrasekaran, Manishekar41b8e1f2015-03-10 13:30:28 +053012525 goto allow_suspend;
12526 }
12527
12528 pScanInfo = &pHddCtx->scan_info;
12529
Jeff Johnson295189b2012-06-20 16:38:30 -070012530 hddLog(VOS_TRACE_LEVEL_INFO,
12531 "%s called with halHandle = %p, pContext = %p,"
Arif Hussain6d2a3322013-11-17 19:50:10 -080012532 "scanID = %d, returned status = %d",
Jeff Johnson295189b2012-06-20 16:38:30 -070012533 __func__, halHandle, pContext, (int) scanId, (int) status);
12534
Kiet Lamac06e2c2013-10-23 16:25:07 +053012535 pScanInfo->mScanPendingCounter = 0;
12536
Jeff Johnson295189b2012-06-20 16:38:30 -070012537 //Block on scan req completion variable. Can't wait forever though.
c_hpothu6ff1c3c2013-10-01 19:01:57 +053012538 waitRet = wait_for_completion_interruptible_timeout(
Jeff Johnson295189b2012-06-20 16:38:30 -070012539 &pScanInfo->scan_req_completion_event,
12540 msecs_to_jiffies(WLAN_WAIT_TIME_SCAN_REQ));
c_hpothu6ff1c3c2013-10-01 19:01:57 +053012541 if (waitRet <= 0)
Jeff Johnson295189b2012-06-20 16:38:30 -070012542 {
c_hpothu6ff1c3c2013-10-01 19:01:57 +053012543 hddLog(VOS_TRACE_LEVEL_ERROR,
12544 "%s wait on scan_req_completion_event failed %ld",__func__, waitRet);
Jeff Johnson295189b2012-06-20 16:38:30 -070012545 VOS_ASSERT(pScanInfo->mScanPending);
Jeff Johnsone7245742012-09-05 17:12:55 -070012546 goto allow_suspend;
Jeff Johnson295189b2012-06-20 16:38:30 -070012547 }
12548
Yue Maef608272013-04-08 23:09:17 -070012549 if (pScanInfo->mScanPending != VOS_TRUE)
Jeff Johnson295189b2012-06-20 16:38:30 -070012550 {
12551 VOS_ASSERT(pScanInfo->mScanPending);
Jeff Johnsone7245742012-09-05 17:12:55 -070012552 goto allow_suspend;
Jeff Johnson295189b2012-06-20 16:38:30 -070012553 }
12554
12555 /* Check the scanId */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012556 if (pScanInfo->scanId != scanId)
Jeff Johnson295189b2012-06-20 16:38:30 -070012557 {
12558 hddLog(VOS_TRACE_LEVEL_INFO,
12559 "%s called with mismatched scanId pScanInfo->scanId = %d "
Arif Hussain6d2a3322013-11-17 19:50:10 -080012560 "scanId = %d", __func__, (int) pScanInfo->scanId,
Jeff Johnson295189b2012-06-20 16:38:30 -070012561 (int) scanId);
12562 }
12563
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012564 ret = wlan_hdd_cfg80211_update_bss((WLAN_HDD_GET_CTX(pAdapter))->wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -070012565 pAdapter);
12566
12567 if (0 > ret)
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012568 hddLog(VOS_TRACE_LEVEL_INFO, "%s: NO SCAN result", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -070012569
12570
12571 /* If any client wait scan result through WEXT
12572 * send scan done event to client */
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -070012573 if (pHddCtx->scan_info.waitScanResult)
Jeff Johnson295189b2012-06-20 16:38:30 -070012574 {
12575 /* The other scan request waiting for current scan finish
12576 * Send event to notify current scan finished */
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -070012577 if(WEXT_SCAN_PENDING_DELAY == pHddCtx->scan_info.scan_pending_option)
Jeff Johnson295189b2012-06-20 16:38:30 -070012578 {
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -070012579 vos_event_set(&pHddCtx->scan_info.scan_finished_event);
Jeff Johnson295189b2012-06-20 16:38:30 -070012580 }
12581 /* Send notify to WEXT client */
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -070012582 else if(WEXT_SCAN_PENDING_PIGGYBACK == pHddCtx->scan_info.scan_pending_option)
Jeff Johnson295189b2012-06-20 16:38:30 -070012583 {
12584 struct net_device *dev = pAdapter->dev;
12585 union iwreq_data wrqu;
12586 int we_event;
12587 char *msg;
12588
12589 memset(&wrqu, '\0', sizeof(wrqu));
12590 we_event = SIOCGIWSCAN;
12591 msg = NULL;
12592 wireless_send_event(dev, we_event, &wrqu, msg);
12593 }
12594 }
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -070012595 pHddCtx->scan_info.waitScanResult = FALSE;
Jeff Johnson295189b2012-06-20 16:38:30 -070012596
12597 /* Get the Scan Req */
12598 req = pAdapter->request;
12599
12600 if (!req)
12601 {
Arif Hussain6d2a3322013-11-17 19:50:10 -080012602 hddLog(VOS_TRACE_LEVEL_ERROR, "request is became NULL");
Madan Mohan Koyyalamudi9f5a10c2012-09-28 14:46:16 -070012603 pScanInfo->mScanPending = VOS_FALSE;
Jeff Johnsone7245742012-09-05 17:12:55 -070012604 goto allow_suspend;
Jeff Johnson295189b2012-06-20 16:38:30 -070012605 }
12606
Jeff Johnson295189b2012-06-20 16:38:30 -070012607 pAdapter->request = NULL;
Jeff Johnsone7245742012-09-05 17:12:55 -070012608 /* Scan is no longer pending */
12609 pScanInfo->mScanPending = VOS_FALSE;
Jeff Johnson295189b2012-06-20 16:38:30 -070012610
Agarwal Ashishbd3e10b2014-11-24 19:19:46 +053012611 /* last_scan_timestamp is used to decide if new scan
12612 * is needed or not on station interface. If last station
12613 * scan time and new station scan time is less then
12614 * last_scan_timestamp ; driver will return cached scan.
12615 */
12616 if (req->no_cck == FALSE && status == eCSR_SCAN_SUCCESS) // no_cck will be set during p2p find
12617 {
12618 pScanInfo->last_scan_timestamp = vos_timer_get_system_time();
12619
12620 if ( req->n_channels )
12621 {
12622 for (i = 0; i < req->n_channels ; i++ )
12623 {
12624 pHddCtx->scan_info.last_scan_channelList[i] = req->channels[i]->hw_value;
12625 }
12626 /* store no of channel scanned */
12627 pHddCtx->scan_info.last_scan_numChannels= req->n_channels;
12628 }
12629
12630 }
12631
Madan Mohan Koyyalamudib764bf82012-10-11 16:38:51 -070012632 /*
12633 * cfg80211_scan_done informing NL80211 about completion
12634 * of scanning
12635 */
Mahesh A Saptasagar05a357e2014-02-26 16:28:06 +053012636 if (status == eCSR_SCAN_ABORT || status == eCSR_SCAN_FAILURE)
12637 {
12638 aborted = true;
12639 }
12640 cfg80211_scan_done(req, aborted);
Madan Mohan Koyyalamudif4e81002012-11-13 10:46:38 -080012641 complete(&pScanInfo->abortscan_event_var);
Jeff Johnson295189b2012-06-20 16:38:30 -070012642
Hanumantha Reddy Pothulaca1d1cc2015-10-26 15:37:35 +053012643 if ((pHddCtx->cfg_ini->enableMacSpoofing == MAC_ADDR_SPOOFING_FW_HOST_ENABLE
12644 ) && (pHddCtx->spoofMacAddr.isEnabled
12645 || pHddCtx->spoofMacAddr.isReqDeferred)) {
Siddharth Bhal76972212014-10-15 16:22:51 +053012646 /* Generate new random mac addr for next scan */
12647 hddLog(VOS_TRACE_LEVEL_INFO, "scan completed - generate new spoof mac addr");
12648 hdd_processSpoofMacAddrRequest(pHddCtx);
12649 }
12650
Jeff Johnsone7245742012-09-05 17:12:55 -070012651allow_suspend:
Madan Mohan Koyyalamudi9f5a10c2012-09-28 14:46:16 -070012652 /* release the wake lock at the end of the scan*/
Sushant Kaushik83392fa2015-05-05 17:44:40 +053012653 hdd_allow_suspend(WIFI_POWER_EVENT_WAKELOCK_SCAN);
Jeff Johnsone7245742012-09-05 17:12:55 -070012654
Madan Mohan Koyyalamudi10d83a92012-09-28 15:47:05 -070012655 /* Acquire wakelock to handle the case where APP's tries to suspend
12656 * immediatly after the driver gets connect request(i.e after scan)
12657 * from supplicant, this result in app's is suspending and not able
12658 * to process the connect request to AP */
Sushant Kaushik83392fa2015-05-05 17:44:40 +053012659 hdd_prevent_suspend_timeout(1000, WIFI_POWER_EVENT_WAKELOCK_SCAN);
Madan Mohan Koyyalamudi10d83a92012-09-28 15:47:05 -070012660
Gopichand Nakkala638ebc72013-03-21 18:04:02 -070012661#ifdef FEATURE_WLAN_TDLS
Pradeep Reddy POTTETIc7822df2015-02-19 20:15:41 +053012662 wlan_hdd_tdls_scan_done_callback(pAdapter);
Gopichand Nakkala638ebc72013-03-21 18:04:02 -070012663#endif
12664
Jeff Johnson295189b2012-06-20 16:38:30 -070012665 EXIT();
12666 return 0;
12667}
12668
12669/*
Rashmi Ramannab1429032014-04-26 14:59:09 +053012670 * FUNCTION: hdd_isConnectionInProgress
12671 * Go through each adapter and check if Connection is in progress
Madan Mohan Koyyalamudicfd53742013-01-11 15:29:03 -080012672 *
12673 */
Padma, Santhosh Kumar98f271d2014-12-31 17:23:31 +053012674v_BOOL_t hdd_isConnectionInProgress( hdd_context_t *pHddCtx)
Madan Mohan Koyyalamudicfd53742013-01-11 15:29:03 -080012675{
12676 hdd_adapter_list_node_t *pAdapterNode = NULL, *pNext = NULL;
12677 hdd_station_ctx_t *pHddStaCtx = NULL;
12678 hdd_adapter_t *pAdapter = NULL;
12679 VOS_STATUS status = 0;
12680 v_U8_t staId = 0;
12681 v_U8_t *staMac = NULL;
12682
c_hpothu9b781ba2013-12-30 20:57:45 +053012683 if (TRUE == pHddCtx->btCoexModeSet)
12684 {
12685 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Rashmi Ramannab1429032014-04-26 14:59:09 +053012686 FL("BTCoex Mode operation in progress"));
12687 return VOS_TRUE;
c_hpothu9b781ba2013-12-30 20:57:45 +053012688 }
12689
Madan Mohan Koyyalamudicfd53742013-01-11 15:29:03 -080012690 status = hdd_get_front_adapter ( pHddCtx, &pAdapterNode );
12691
12692 while ( NULL != pAdapterNode && VOS_STATUS_SUCCESS == status )
12693 {
12694 pAdapter = pAdapterNode->pAdapter;
12695
12696 if( pAdapter )
12697 {
12698 hddLog(VOS_TRACE_LEVEL_INFO,
Sushant Kaushik8bc7df22014-04-09 17:55:29 +053012699 "%s: Adapter with device mode %s (%d) exists",
12700 __func__, hdd_device_modetoString(pAdapter->device_mode),
12701 pAdapter->device_mode);
Padma, Santhosh Kumar98f271d2014-12-31 17:23:31 +053012702 if (((WLAN_HDD_INFRA_STATION == pAdapter->device_mode) ||
Rashmi Ramannab1429032014-04-26 14:59:09 +053012703 (WLAN_HDD_P2P_CLIENT == pAdapter->device_mode) ||
12704 (WLAN_HDD_P2P_DEVICE == pAdapter->device_mode)) &&
12705 (eConnectionState_Connecting ==
12706 (WLAN_HDD_GET_STATION_CTX_PTR(pAdapter))->conn_info.connState))
12707 {
12708 hddLog(VOS_TRACE_LEVEL_ERROR,
12709 "%s: %p(%d) Connection is in progress", __func__,
12710 WLAN_HDD_GET_STATION_CTX_PTR(pAdapter), pAdapter->sessionId);
12711 return VOS_TRUE;
12712 }
Padma, Santhosh Kumar98f271d2014-12-31 17:23:31 +053012713 if ((WLAN_HDD_INFRA_STATION == pAdapter->device_mode) &&
Padma, Santhosh Kumar3b9657d2015-02-04 19:37:32 +053012714 smeNeighborMiddleOfRoaming(WLAN_HDD_GET_HAL_CTX(pAdapter)))
Padma, Santhosh Kumar98f271d2014-12-31 17:23:31 +053012715 {
12716 hddLog(VOS_TRACE_LEVEL_ERROR,
12717 "%s: %p(%d) Reassociation is in progress", __func__,
12718 WLAN_HDD_GET_STATION_CTX_PTR(pAdapter), pAdapter->sessionId);
12719 return VOS_TRUE;
12720 }
12721 if ((WLAN_HDD_INFRA_STATION == pAdapter->device_mode) ||
Sushant Kaushik8bc7df22014-04-09 17:55:29 +053012722 (WLAN_HDD_P2P_CLIENT == pAdapter->device_mode) ||
12723 (WLAN_HDD_P2P_DEVICE == pAdapter->device_mode))
Madan Mohan Koyyalamudicfd53742013-01-11 15:29:03 -080012724 {
12725 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
12726 if ((eConnectionState_Associated == pHddStaCtx->conn_info.connState) &&
Sushant Kaushik8bc7df22014-04-09 17:55:29 +053012727 (VOS_FALSE == pHddStaCtx->conn_info.uIsAuthenticated))
Madan Mohan Koyyalamudicfd53742013-01-11 15:29:03 -080012728 {
12729 staMac = (v_U8_t *) &(pAdapter->macAddressCurrent.bytes[0]);
12730 hddLog(VOS_TRACE_LEVEL_ERROR,
Arif Hussain24bafea2013-11-15 15:10:03 -080012731 "%s: client " MAC_ADDRESS_STR
12732 " is in the middle of WPS/EAPOL exchange.", __func__,
12733 MAC_ADDR_ARRAY(staMac));
Rashmi Ramannab1429032014-04-26 14:59:09 +053012734 return VOS_TRUE;
Madan Mohan Koyyalamudicfd53742013-01-11 15:29:03 -080012735 }
12736 }
12737 else if ((WLAN_HDD_SOFTAP == pAdapter->device_mode) ||
12738 (WLAN_HDD_P2P_GO == pAdapter->device_mode))
12739 {
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +053012740 v_CONTEXT_t pVosContext = ( WLAN_HDD_GET_CTX(pAdapter))->pvosContext;
12741 ptSapContext pSapCtx = NULL;
12742 pSapCtx = VOS_GET_SAP_CB(pVosContext);
12743 if(pSapCtx == NULL){
12744 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
12745 FL("psapCtx is NULL"));
12746 return VOS_FALSE;
12747 }
Madan Mohan Koyyalamudicfd53742013-01-11 15:29:03 -080012748 for (staId = 0; staId < WLAN_MAX_STA_COUNT; staId++)
12749 {
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +053012750 if ((pSapCtx->aStaInfo[staId].isUsed) &&
12751 (WLANTL_STA_CONNECTED == pSapCtx->aStaInfo[staId].tlSTAState))
Madan Mohan Koyyalamudicfd53742013-01-11 15:29:03 -080012752 {
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +053012753 staMac = (v_U8_t *) &(pSapCtx->aStaInfo[staId].macAddrSTA.bytes[0]);
Madan Mohan Koyyalamudicfd53742013-01-11 15:29:03 -080012754
12755 hddLog(VOS_TRACE_LEVEL_ERROR,
Arif Hussain24bafea2013-11-15 15:10:03 -080012756 "%s: client " MAC_ADDRESS_STR " of SoftAP/P2P-GO is in the "
12757 "middle of WPS/EAPOL exchange.", __func__,
12758 MAC_ADDR_ARRAY(staMac));
Rashmi Ramannab1429032014-04-26 14:59:09 +053012759 return VOS_TRUE;
Madan Mohan Koyyalamudicfd53742013-01-11 15:29:03 -080012760 }
12761 }
12762 }
12763 }
12764 status = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
12765 pAdapterNode = pNext;
12766 }
Rashmi Ramannab1429032014-04-26 14:59:09 +053012767 return VOS_FALSE;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012768}
Madan Mohan Koyyalamudicfd53742013-01-11 15:29:03 -080012769
12770/*
Mahesh A Saptasagarfafb7fe2014-05-16 13:19:37 +053012771 * FUNCTION: __wlan_hdd_cfg80211_scan
Jeff Johnson295189b2012-06-20 16:38:30 -070012772 * this scan respond to scan trigger and update cfg80211 scan database
12773 * later, scan dump command can be used to recieve scan results
12774 */
Mahesh A Saptasagarfafb7fe2014-05-16 13:19:37 +053012775int __wlan_hdd_cfg80211_scan( struct wiphy *wiphy,
Jeff Johnson3bbe4bf2013-01-18 17:05:29 -080012776#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,6,0))
12777 struct net_device *dev,
12778#endif
12779 struct cfg80211_scan_request *request)
12780{
Siddharth Bhal0c162d02014-05-06 19:50:42 +053012781 hdd_adapter_t *pAdapter = NULL;
12782 hdd_context_t *pHddCtx = NULL;
12783 hdd_wext_state_t *pwextBuf = NULL;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053012784 hdd_config_t *cfg_param = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -070012785 tCsrScanRequest scanRequest;
12786 tANI_U8 *channelList = NULL, i;
12787 v_U32_t scanId = 0;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053012788 int status;
12789 hdd_scaninfo_t *pScanInfo = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -070012790 v_U8_t* pP2pIe = NULL;
Agarwal Ashishbd3e10b2014-11-24 19:19:46 +053012791 int ret = 0;
Sushant Kaushik86592172015-04-27 16:35:03 +053012792 v_U8_t *pWpsIe=NULL;
Deepthi Gowrid5c5c2b2015-06-11 17:00:46 +053012793 bool is_p2p_scan = false;
Hanumantha Reddy Pothula2e282d12015-06-19 14:01:26 +053012794 v_S7_t rssi=0;
12795 hdd_station_ctx_t *pHddStaCtx=NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -070012796
Siddharth Bhal0c162d02014-05-06 19:50:42 +053012797#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,6,0))
12798 struct net_device *dev = NULL;
12799 if (NULL == request)
12800 {
12801 hddLog(VOS_TRACE_LEVEL_ERROR,
12802 "%s: scan req param null", __func__);
12803 return -EINVAL;
12804 }
12805 dev = request->wdev->netdev;
12806#endif
12807
12808 pAdapter = WLAN_HDD_GET_PRIV_PTR( dev );
12809 pHddCtx = WLAN_HDD_GET_CTX( pAdapter );
12810 pwextBuf = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
12811
Jeff Johnson295189b2012-06-20 16:38:30 -070012812 ENTER();
12813
Sushant Kaushik8bc7df22014-04-09 17:55:29 +053012814 hddLog(VOS_TRACE_LEVEL_INFO, "%s: device_mode = %s (%d)",
12815 __func__, hdd_device_modetoString(pAdapter->device_mode),
12816 pAdapter->device_mode);
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053012817
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053012818 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053012819 if (0 != status)
12820 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053012821 return status;
12822 }
12823
Siddharth Bhal0c162d02014-05-06 19:50:42 +053012824 if (NULL == pwextBuf)
12825 {
12826 hddLog (VOS_TRACE_LEVEL_ERROR, "%s ERROR: invalid WEXT state\n",
12827 __func__);
12828 return -EIO;
12829 }
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053012830 cfg_param = pHddCtx->cfg_ini;
12831 pScanInfo = &pHddCtx->scan_info;
12832
Hanumantha Reddy Pothula2e282d12015-06-19 14:01:26 +053012833 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
12834 if ( (pHddStaCtx != NULL) && (TRUE == hdd_connIsConnected(pHddStaCtx)))
12835 {
12836 wlan_hdd_get_roam_rssi(pAdapter, &rssi);
12837 hddLog(VOS_TRACE_LEVEL_INFO, FL("rssi: %d"), rssi);
12838 }
12839
Jeff Johnson295189b2012-06-20 16:38:30 -070012840#ifdef WLAN_BTAMP_FEATURE
12841 //Scan not supported when AMP traffic is on.
Gopichand Nakkala681989c2013-03-06 22:27:48 -080012842 if (VOS_TRUE == WLANBAP_AmpSessionOn())
Jeff Johnson295189b2012-06-20 16:38:30 -070012843 {
Madan Mohan Koyyalamudifd4e1da2012-11-09 17:50:19 -080012844 hddLog(VOS_TRACE_LEVEL_ERROR,
Jeff Johnson295189b2012-06-20 16:38:30 -070012845 "%s: No scanning when AMP is on", __func__);
12846 return -EOPNOTSUPP;
12847 }
12848#endif
12849 //Scan on any other interface is not supported.
Gopichand Nakkala681989c2013-03-06 22:27:48 -080012850 if (pAdapter->device_mode == WLAN_HDD_SOFTAP)
Jeff Johnson295189b2012-06-20 16:38:30 -070012851 {
Gopichand Nakkala681989c2013-03-06 22:27:48 -080012852 hddLog(VOS_TRACE_LEVEL_ERROR,
Sushant Kaushik8bc7df22014-04-09 17:55:29 +053012853 "%s: Not scanning on device_mode = %s (%d)",
12854 __func__, hdd_device_modetoString(pAdapter->device_mode),
12855 pAdapter->device_mode);
Jeff Johnson295189b2012-06-20 16:38:30 -070012856 return -EOPNOTSUPP;
12857 }
12858
12859 if (TRUE == pScanInfo->mScanPending)
12860 {
Kiet Lamac06e2c2013-10-23 16:25:07 +053012861 if ( MAX_PENDING_LOG > pScanInfo->mScanPendingCounter++ )
12862 {
12863 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: mScanPending is TRUE", __func__);
12864 }
Gopichand Nakkala681989c2013-03-06 22:27:48 -080012865 return -EBUSY;
Jeff Johnson295189b2012-06-20 16:38:30 -070012866 }
12867
Hanumantha Reddy Pothula4b6be062015-08-18 14:06:24 +053012868 // Don't allow scan if PNO scan is going on.
12869 if (pHddCtx->isPnoEnable)
12870 {
12871 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
12872 FL("pno scan in progress"));
12873 return -EBUSY;
12874 }
12875
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012876 //Don't Allow Scan and return busy if Remain On
Jeff Johnson32d95a32012-09-10 13:15:23 -070012877 //Channel and action frame is pending
12878 //Otherwise Cancel Remain On Channel and allow Scan
12879 //If no action frame pending
Gopichand Nakkala681989c2013-03-06 22:27:48 -080012880 if (0 != wlan_hdd_check_remain_on_channel(pAdapter))
Jeff Johnson32d95a32012-09-10 13:15:23 -070012881 {
Kiet Lamac06e2c2013-10-23 16:25:07 +053012882 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Remain On Channel Pending", __func__);
Jeff Johnson32d95a32012-09-10 13:15:23 -070012883 return -EBUSY;
12884 }
12885
Jeff Johnson295189b2012-06-20 16:38:30 -070012886 if (mutex_lock_interruptible(&pHddCtx->tmInfo.tmOperationLock))
12887 {
12888 VOS_TRACE(VOS_MODULE_ID_HDD,VOS_TRACE_LEVEL_ERROR,
Jeff Johnson1250df42012-12-10 14:31:52 -080012889 "%s: Acquire lock fail", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -070012890 return -EAGAIN;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012891 }
Jeff Johnson295189b2012-06-20 16:38:30 -070012892 if (TRUE == pHddCtx->tmInfo.tmAction.enterImps)
12893 {
Nirav Shah20ac06f2013-12-12 18:14:06 +053012894 hddLog(VOS_TRACE_LEVEL_ERROR,
Jeff Johnson295189b2012-06-20 16:38:30 -070012895 "%s: MAX TM Level Scan not allowed", __func__);
12896 mutex_unlock(&pHddCtx->tmInfo.tmOperationLock);
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012897 return -EBUSY;
Jeff Johnson295189b2012-06-20 16:38:30 -070012898 }
12899 mutex_unlock(&pHddCtx->tmInfo.tmOperationLock);
12900
Madan Mohan Koyyalamudicfd53742013-01-11 15:29:03 -080012901 /* Check if scan is allowed at this point of time.
12902 */
Padma, Santhosh Kumar98f271d2014-12-31 17:23:31 +053012903 if (hdd_isConnectionInProgress(pHddCtx))
Madan Mohan Koyyalamudicfd53742013-01-11 15:29:03 -080012904 {
12905 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Scan not allowed", __func__);
12906 return -EBUSY;
12907 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012908
Jeff Johnson295189b2012-06-20 16:38:30 -070012909 vos_mem_zero( &scanRequest, sizeof(scanRequest));
12910
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +053012911 /* Even though supplicant doesn't provide any SSIDs, n_ssids is set to 1.
12912 * Becasue of this, driver is assuming that this is not wildcard scan and so
12913 * is not aging out the scan results.
12914 */
12915 if (request->ssids && '\0' == request->ssids->ssid[0])
Jeff Johnson295189b2012-06-20 16:38:30 -070012916 {
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +053012917 request->n_ssids = 0;
Jeff Johnson295189b2012-06-20 16:38:30 -070012918 }
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +053012919
12920 if ((request->ssids) && (0 < request->n_ssids))
12921 {
12922 tCsrSSIDInfo *SsidInfo;
12923 int j;
12924 scanRequest.SSIDs.numOfSSIDs = request->n_ssids;
12925 /* Allocate num_ssid tCsrSSIDInfo structure */
12926 SsidInfo = scanRequest.SSIDs.SSIDList =
12927 ( tCsrSSIDInfo *)vos_mem_malloc(
12928 request->n_ssids*sizeof(tCsrSSIDInfo));
12929
12930 if(NULL == scanRequest.SSIDs.SSIDList)
12931 {
12932 hddLog(VOS_TRACE_LEVEL_ERROR,
12933 "%s: memory alloc failed SSIDInfo buffer", __func__);
12934 return -ENOMEM;
12935 }
12936
12937 /* copy all the ssid's and their length */
12938 for(j = 0; j < request->n_ssids; j++, SsidInfo++)
12939 {
12940 /* get the ssid length */
12941 SsidInfo->SSID.length = request->ssids[j].ssid_len;
12942 vos_mem_copy(SsidInfo->SSID.ssId, &request->ssids[j].ssid[0],
12943 SsidInfo->SSID.length);
12944 SsidInfo->SSID.ssId[SsidInfo->SSID.length] = '\0';
12945 hddLog(VOS_TRACE_LEVEL_INFO, "SSID number %d: %s",
12946 j, SsidInfo->SSID.ssId);
12947 }
12948 /* set the scan type to active */
12949 scanRequest.scanType = eSIR_ACTIVE_SCAN;
12950 }
12951 else if(WLAN_HDD_P2P_GO == pAdapter->device_mode)
Jeff Johnson295189b2012-06-20 16:38:30 -070012952 {
Siddharth Bhal0c162d02014-05-06 19:50:42 +053012953 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
12954 TRACE_CODE_HDD_CFG80211_SCAN,
12955 pAdapter->sessionId, 0));
Jeff Johnson295189b2012-06-20 16:38:30 -070012956 /* set the scan type to active */
12957 scanRequest.scanType = eSIR_ACTIVE_SCAN;
Jeff Johnson295189b2012-06-20 16:38:30 -070012958 }
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +053012959 else
12960 {
12961 /*Set the scan type to default type, in this case it is ACTIVE*/
12962 scanRequest.scanType = pScanInfo->scan_mode;
12963 }
12964 scanRequest.minChnTime = cfg_param->nActiveMinChnTime;
12965 scanRequest.maxChnTime = cfg_param->nActiveMaxChnTime;
Jeff Johnson295189b2012-06-20 16:38:30 -070012966
12967 /* set BSSType to default type */
12968 scanRequest.BSSType = eCSR_BSS_TYPE_ANY;
12969
12970 /*TODO: scan the requested channels only*/
12971
12972 /*Right now scanning all the channels */
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +053012973 if (MAX_CHANNEL < request->n_channels)
Jeff Johnson295189b2012-06-20 16:38:30 -070012974 {
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +053012975 hddLog(VOS_TRACE_LEVEL_WARN,
12976 "No of Scan Channels exceeded limit: %d", request->n_channels);
12977 request->n_channels = MAX_CHANNEL;
12978 }
12979
12980 hddLog(VOS_TRACE_LEVEL_INFO,
12981 "No of Scan Channels: %d", request->n_channels);
12982
12983
12984 if( request->n_channels )
12985 {
12986 char chList [(request->n_channels*5)+1];
12987 int len;
12988 channelList = vos_mem_malloc( request->n_channels );
12989 if( NULL == channelList )
c_hpothu53512302014-04-15 18:49:53 +053012990 {
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +053012991 hddLog(VOS_TRACE_LEVEL_ERROR,
12992 "%s: memory alloc failed channelList", __func__);
12993 status = -ENOMEM;
12994 goto free_mem;
c_hpothu53512302014-04-15 18:49:53 +053012995 }
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +053012996
12997 for( i = 0, len = 0; i < request->n_channels ; i++ )
12998 {
12999 channelList[i] = request->channels[i]->hw_value;
13000 len += snprintf(chList+len, 5, "%d ", channelList[i]);
13001 }
13002
Nirav Shah20ac06f2013-12-12 18:14:06 +053013003 hddLog(VOS_TRACE_LEVEL_INFO,
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +053013004 "Channel-List: %s ", chList);
13005 }
c_hpothu53512302014-04-15 18:49:53 +053013006
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +053013007 scanRequest.ChannelInfo.numOfChannels = request->n_channels;
13008 scanRequest.ChannelInfo.ChannelList = channelList;
13009
13010 /* set requestType to full scan */
13011 scanRequest.requestType = eCSR_SCAN_REQUEST_FULL_SCAN;
13012
Agarwal Ashishbd3e10b2014-11-24 19:19:46 +053013013 /* if there is back to back scan happening in driver with in
13014 * nDeferScanTimeInterval interval driver should defer new scan request
13015 * and should provide last cached scan results instead of new channel list.
13016 * This rule is not applicable if scan is p2p scan.
13017 * This condition will work only in case when last request no of channels
13018 * and channels are exactly same as new request.
Agarwal Ashish57e84372014-12-05 18:26:53 +053013019 * This should be done only in connected state
Sushant Kaushik86592172015-04-27 16:35:03 +053013020 * Scan shouldn't be defered for WPS scan case.
Agarwal Ashishbd3e10b2014-11-24 19:19:46 +053013021 */
Agarwal Ashishbd3e10b2014-11-24 19:19:46 +053013022
Sushant Kaushik86592172015-04-27 16:35:03 +053013023 pWpsIe = wlan_hdd_get_wps_ie_ptr((v_U8_t*)request->ie,request->ie_len);
13024 /* if wps ie is NULL , then only defer scan */
13025 if ( pWpsIe == NULL &&
13026 (VOS_STATUS_SUCCESS == hdd_is_any_session_connected(pHddCtx)))
Agarwal Ashish57e84372014-12-05 18:26:53 +053013027 {
13028 if ( pScanInfo->last_scan_timestamp !=0 &&
13029 ((vos_timer_get_system_time() - pScanInfo->last_scan_timestamp ) < pHddCtx->cfg_ini->nDeferScanTimeInterval))
13030 {
13031 if ( request->no_cck == FALSE && scanRequest.ChannelInfo.numOfChannels != 1 &&
13032 (pScanInfo->last_scan_numChannels == scanRequest.ChannelInfo.numOfChannels) &&
13033 vos_mem_compare(pScanInfo->last_scan_channelList,
13034 channelList, pScanInfo->last_scan_numChannels))
13035 {
13036 hddLog(VOS_TRACE_LEVEL_WARN,
13037 " New and old station scan time differ is less then %u",
13038 pHddCtx->cfg_ini->nDeferScanTimeInterval);
13039
13040 ret = wlan_hdd_cfg80211_update_bss((WLAN_HDD_GET_CTX(pAdapter))->wiphy,
Agarwal Ashishbd3e10b2014-11-24 19:19:46 +053013041 pAdapter);
13042
Agarwal Ashish57e84372014-12-05 18:26:53 +053013043 hddLog(VOS_TRACE_LEVEL_WARN,
Masti, Narayanraddide03eb02015-02-06 11:23:50 +053013044 "Return old cached scan as all channels and no of channels are same");
13045
Agarwal Ashish57e84372014-12-05 18:26:53 +053013046 if (0 > ret)
13047 hddLog(VOS_TRACE_LEVEL_INFO, "%s: NO SCAN result", __func__);
Agarwal Ashishbd3e10b2014-11-24 19:19:46 +053013048
Agarwal Ashish57e84372014-12-05 18:26:53 +053013049 cfg80211_scan_done(request, eCSR_SCAN_SUCCESS);
Masti, Narayanraddide03eb02015-02-06 11:23:50 +053013050
13051 status = eHAL_STATUS_SUCCESS;
13052 goto free_mem;
Agarwal Ashish57e84372014-12-05 18:26:53 +053013053 }
13054 }
Agarwal Ashishbd3e10b2014-11-24 19:19:46 +053013055 }
13056
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +053013057 /* Flush the scan results(only p2p beacons) for STA scan and P2P
13058 * search (Flush on both full scan and social scan but not on single
13059 * channel scan).P2P search happens on 3 social channels (1, 6, 11)
13060 */
13061
13062 /* Supplicant does single channel scan after 8-way handshake
13063 * and in that case driver shoudnt flush scan results. If
13064 * driver flushes the scan results here and unfortunately if
13065 * the AP doesnt respond to our probe req then association
13066 * fails which is not desired
13067 */
Deepthi Gowrid5c5c2b2015-06-11 17:00:46 +053013068 if ((request->n_ssids == 1)
13069 && (request->ssids != NULL)
13070 && vos_mem_compare(&request->ssids[0], "DIRECT-", 7))
13071 is_p2p_scan = true;
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +053013072
Deepthi Gowrid5c5c2b2015-06-11 17:00:46 +053013073 if( is_p2p_scan ||
13074 (request->n_channels != WLAN_HDD_P2P_SINGLE_CHANNEL_SCAN) )
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +053013075 {
13076 hddLog(VOS_TRACE_LEVEL_DEBUG, "Flushing P2P Results");
13077 sme_ScanFlushP2PResult( WLAN_HDD_GET_HAL_CTX(pAdapter),
13078 pAdapter->sessionId );
13079 }
13080
13081 if( request->ie_len )
13082 {
13083 /* save this for future association (join requires this) */
13084 /*TODO: Array needs to be converted to dynamic allocation,
13085 * as multiple ie.s can be sent in cfg80211_scan_request structure
13086 * CR 597966
13087 */
13088 memset( &pScanInfo->scanAddIE, 0, sizeof(pScanInfo->scanAddIE) );
13089 memcpy( pScanInfo->scanAddIE.addIEdata, request->ie, request->ie_len);
13090 pScanInfo->scanAddIE.length = request->ie_len;
13091
13092 if ((WLAN_HDD_INFRA_STATION == pAdapter->device_mode) ||
13093 (WLAN_HDD_P2P_CLIENT == pAdapter->device_mode) ||
13094 (WLAN_HDD_P2P_DEVICE == pAdapter->device_mode))
Jeff Johnson295189b2012-06-20 16:38:30 -070013095 {
Ganesh Kondabattini7500fb32015-04-10 14:50:32 +053013096 if (request->ie_len <= SIR_MAC_MAX_ADD_IE_LENGTH)
Jeff Johnson295189b2012-06-20 16:38:30 -070013097 {
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +053013098 pwextBuf->roamProfile.nAddIEScanLength = request->ie_len;
13099 memcpy( pwextBuf->roamProfile.addIEScan,
13100 request->ie, request->ie_len);
13101 }
13102 else
13103 {
13104 hddLog(VOS_TRACE_LEVEL_ERROR, "Scan Ie length is invalid:"
13105 "%zu", request->ie_len);
Jeff Johnson295189b2012-06-20 16:38:30 -070013106 }
13107
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +053013108 }
13109 scanRequest.uIEFieldLen = pScanInfo->scanAddIE.length;
13110 scanRequest.pIEField = pScanInfo->scanAddIE.addIEdata;
13111
13112 pP2pIe = wlan_hdd_get_p2p_ie_ptr((v_U8_t*)request->ie,
13113 request->ie_len);
13114 if (pP2pIe != NULL)
13115 {
13116#ifdef WLAN_FEATURE_P2P_DEBUG
13117 if (((globalP2PConnectionStatus == P2P_GO_NEG_COMPLETED) ||
13118 (globalP2PConnectionStatus == P2P_GO_NEG_PROCESS)) &&
13119 (WLAN_HDD_P2P_CLIENT == pAdapter->device_mode))
Nirav Shah20ac06f2013-12-12 18:14:06 +053013120 {
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +053013121 globalP2PConnectionStatus = P2P_CLIENT_CONNECTING_STATE_1;
13122 hddLog(VOS_TRACE_LEVEL_ERROR,"[P2P State] Changing state from "
13123 "Go nego completed to Connection is started");
13124 hddLog(VOS_TRACE_LEVEL_ERROR,"[P2P]P2P Scanning is started "
13125 "for 8way Handshake");
Nirav Shah20ac06f2013-12-12 18:14:06 +053013126 }
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +053013127 else if((globalP2PConnectionStatus == P2P_CLIENT_DISCONNECTED_STATE) &&
13128 (WLAN_HDD_P2P_CLIENT == pAdapter->device_mode))
Jeff Johnson295189b2012-06-20 16:38:30 -070013129 {
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +053013130 globalP2PConnectionStatus = P2P_CLIENT_CONNECTING_STATE_2;
13131 hddLog(VOS_TRACE_LEVEL_ERROR,"[P2P State] Changing state from "
13132 "Disconnected state to Connection is started");
13133 hddLog(VOS_TRACE_LEVEL_ERROR,"[P2P]P2P Scanning is started "
13134 "for 4way Handshake");
13135 }
13136#endif
13137
13138 /* no_cck will be set during p2p find to disable 11b rates */
13139 if(TRUE == request->no_cck)
13140 {
13141 hddLog(VOS_TRACE_LEVEL_INFO,
13142 "%s: This is a P2P Search", __func__);
13143 scanRequest.p2pSearch = 1;
13144
13145 if( request->n_channels == WLAN_HDD_P2P_SOCIAL_CHANNELS )
Agarwal Ashish4f616132013-12-30 23:32:50 +053013146 {
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +053013147 /* set requestType to P2P Discovery */
13148 scanRequest.requestType = eCSR_SCAN_P2P_DISCOVERY;
13149 }
13150
13151 /*
13152 Skip Dfs Channel in case of P2P Search
13153 if it is set in ini file
13154 */
13155 if(cfg_param->skipDfsChnlInP2pSearch)
13156 {
13157 scanRequest.skipDfsChnlInP2pSearch = 1;
Agarwal Ashish4f616132013-12-30 23:32:50 +053013158 }
13159 else
13160 {
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +053013161 scanRequest.skipDfsChnlInP2pSearch = 0;
Agarwal Ashish4f616132013-12-30 23:32:50 +053013162 }
Jeff Johnson295189b2012-06-20 16:38:30 -070013163
Agarwal Ashish4f616132013-12-30 23:32:50 +053013164 }
Jeff Johnson295189b2012-06-20 16:38:30 -070013165 }
13166 }
13167
13168 INIT_COMPLETION(pScanInfo->scan_req_completion_event);
13169
Pradeep Reddy POTTETIc7822df2015-02-19 20:15:41 +053013170#ifdef FEATURE_WLAN_TDLS
13171 /* if tdls disagree scan right now, return immediately.
13172 tdls will schedule the scan when scan is allowed. (return SUCCESS)
13173 or will reject the scan if any TDLS is in progress. (return -EBUSY)
13174 */
13175 status = wlan_hdd_tdls_scan_callback (pAdapter,
13176 wiphy,
13177#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,6,0))
13178 dev,
13179#endif
13180 request);
13181 if(status <= 0)
13182 {
13183 if(!status)
13184 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: TDLS in progress."
13185 "scan rejected %d", __func__, status);
13186 else
13187 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: TDLS teardown is ongoing %d",
13188 __func__, status);
13189
13190 return status;
13191 }
13192#endif
13193
Madan Mohan Koyyalamudi9f5a10c2012-09-28 14:46:16 -070013194 /* acquire the wakelock to avoid the apps suspend during the scan. To
13195 * address the following issues.
13196 * 1) Disconnected scenario: we are not allowing the suspend as WLAN is not in
13197 * BMPS/IMPS this result in android trying to suspend aggressively and backing off
13198 * for long time, this result in apps running at full power for long time.
13199 * 2) Connected scenario: If we allow the suspend during the scan, RIVA will
13200 * be stuck in full power because of resume BMPS
13201 */
Sushant Kaushik83392fa2015-05-05 17:44:40 +053013202 hdd_prevent_suspend(WIFI_POWER_EVENT_WAKELOCK_SCAN);
Jeff Johnsone7245742012-09-05 17:12:55 -070013203
Nirav Shah20ac06f2013-12-12 18:14:06 +053013204 hddLog(VOS_TRACE_LEVEL_INFO_HIGH,
13205 "requestType %d, scanType %d, minChnTime %d, maxChnTime %d,"
Sushant Kaushik8bc7df22014-04-09 17:55:29 +053013206 "p2pSearch %d, skipDfsChnlInP2pSearch %d",
13207 scanRequest.requestType, scanRequest.scanType,
13208 scanRequest.minChnTime, scanRequest.maxChnTime,
Nirav Shah20ac06f2013-12-12 18:14:06 +053013209 scanRequest.p2pSearch, scanRequest.skipDfsChnlInP2pSearch);
13210
Hanumantha Reddy Pothulaca1d1cc2015-10-26 15:37:35 +053013211 if (pHddCtx->spoofMacAddr.isEnabled &&
13212 pHddCtx->cfg_ini->enableMacSpoofing == 1)
Siddharth Bhal76972212014-10-15 16:22:51 +053013213 {
13214 hddLog(VOS_TRACE_LEVEL_INFO,
13215 "%s: MAC Spoofing enabled for current scan", __func__);
13216 /* Updating SelfSta Mac Addr in TL which will be used to get staidx
13217 * to fill TxBds for probe request during current scan
13218 */
Padma, Santhosh Kumar79236142015-02-09 18:19:33 +053013219 status = WLANTL_updateSpoofMacAddr(pHddCtx->pvosContext,
Siddharth Bhal76972212014-10-15 16:22:51 +053013220 &pHddCtx->spoofMacAddr.randomMacAddr, &pAdapter->macAddressCurrent);
Padma, Santhosh Kumar79236142015-02-09 18:19:33 +053013221
13222 if(status != VOS_STATUS_SUCCESS)
13223 {
Sushant Kaushik83392fa2015-05-05 17:44:40 +053013224 hdd_allow_suspend(WIFI_POWER_EVENT_WAKELOCK_SCAN);
Padma, Santhosh Kumar79236142015-02-09 18:19:33 +053013225 status = -EFAULT;
Ganesh Kondabattini6d3b4902015-05-12 23:19:22 +053013226#ifdef FEATURE_WLAN_TDLS
13227 wlan_hdd_tdls_scan_done_callback(pAdapter);
13228#endif
Padma, Santhosh Kumar79236142015-02-09 18:19:33 +053013229 goto free_mem;
13230 }
Siddharth Bhal76972212014-10-15 16:22:51 +053013231 }
Mahesh A Saptasagar51dc36c2015-06-16 12:07:15 +053013232 wlan_hdd_get_frame_logs(pAdapter, WLAN_HDD_GET_FRAME_LOG_CMD_CLEAR);
Jeff Johnsone7245742012-09-05 17:12:55 -070013233 status = sme_ScanRequest( WLAN_HDD_GET_HAL_CTX(pAdapter),
Jeff Johnson295189b2012-06-20 16:38:30 -070013234 pAdapter->sessionId, &scanRequest, &scanId,
13235 &hdd_cfg80211_scan_done_callback, dev );
Jeff Johnsone7245742012-09-05 17:12:55 -070013236
Jeff Johnson295189b2012-06-20 16:38:30 -070013237 if (eHAL_STATUS_SUCCESS != status)
13238 {
13239 hddLog(VOS_TRACE_LEVEL_ERROR,
13240 "%s: sme_ScanRequest returned error %d", __func__, status);
13241 complete(&pScanInfo->scan_req_completion_event);
Madan Mohan Koyyalamudi3b230fe2012-10-18 14:46:32 -070013242 if(eHAL_STATUS_RESOURCES == status)
13243 {
Nirav Shah20ac06f2013-12-12 18:14:06 +053013244 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: HO is in progress."
13245 "So defer the scan by informing busy",__func__);
Madan Mohan Koyyalamudi3b230fe2012-10-18 14:46:32 -070013246 status = -EBUSY;
13247 } else {
13248 status = -EIO;
13249 }
Sushant Kaushik83392fa2015-05-05 17:44:40 +053013250 hdd_allow_suspend(WIFI_POWER_EVENT_WAKELOCK_SCAN);
Pradeep Reddy POTTETIc7822df2015-02-19 20:15:41 +053013251
13252#ifdef FEATURE_WLAN_TDLS
13253 wlan_hdd_tdls_scan_done_callback(pAdapter);
13254#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070013255 goto free_mem;
13256 }
13257
13258 pScanInfo->mScanPending = TRUE;
Kaushik, Sushant4975a572014-10-21 16:07:48 +053013259 pScanInfo->sessionId = pAdapter->sessionId;
Jeff Johnson295189b2012-06-20 16:38:30 -070013260 pAdapter->request = request;
13261 pScanInfo->scanId = scanId;
13262
13263 complete(&pScanInfo->scan_req_completion_event);
13264
13265free_mem:
13266 if( scanRequest.SSIDs.SSIDList )
13267 {
13268 vos_mem_free(scanRequest.SSIDs.SSIDList);
13269 }
13270
13271 if( channelList )
13272 vos_mem_free( channelList );
13273
13274 EXIT();
Jeff Johnson295189b2012-06-20 16:38:30 -070013275 return status;
13276}
13277
Mahesh A Saptasagarfafb7fe2014-05-16 13:19:37 +053013278int wlan_hdd_cfg80211_scan( struct wiphy *wiphy,
13279#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,6,0))
13280 struct net_device *dev,
13281#endif
13282 struct cfg80211_scan_request *request)
13283{
13284 int ret;
13285
13286 vos_ssr_protect(__func__);
13287 ret = __wlan_hdd_cfg80211_scan(wiphy,
13288#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,6,0))
13289 dev,
13290#endif
13291 request);
13292 vos_ssr_unprotect(__func__);
13293
13294 return ret;
13295}
Shailender Karmuchi15cd0672013-05-15 19:50:04 -070013296
13297void hdd_select_cbmode( hdd_adapter_t *pAdapter,v_U8_t operationChannel)
13298{
13299 v_U8_t iniDot11Mode =
13300 (WLAN_HDD_GET_CTX(pAdapter))->cfg_ini->dot11Mode;
13301 eHddDot11Mode hddDot11Mode = iniDot11Mode;
13302
Arun Kumar Khandavalli94a2bb02013-12-28 19:17:25 +053013303 hddLog(LOG1, FL("Channel Bonding Mode Selected is %u"),
13304 iniDot11Mode);
Shailender Karmuchi15cd0672013-05-15 19:50:04 -070013305 switch ( iniDot11Mode )
13306 {
13307 case eHDD_DOT11_MODE_AUTO:
13308 case eHDD_DOT11_MODE_11ac:
13309 case eHDD_DOT11_MODE_11ac_ONLY:
13310#ifdef WLAN_FEATURE_11AC
Abhishek Singh4b1d2352014-08-01 21:59:28 +053013311 if ( sme_IsFeatureSupportedByDriver(DOT11AC) &&
13312 sme_IsFeatureSupportedByFW(DOT11AC) )
13313 hddDot11Mode = eHDD_DOT11_MODE_11ac;
13314 else
13315 hddDot11Mode = eHDD_DOT11_MODE_11n;
Shailender Karmuchi15cd0672013-05-15 19:50:04 -070013316#else
13317 hddDot11Mode = eHDD_DOT11_MODE_11n;
13318#endif
13319 break;
13320 case eHDD_DOT11_MODE_11n:
13321 case eHDD_DOT11_MODE_11n_ONLY:
13322 hddDot11Mode = eHDD_DOT11_MODE_11n;
13323 break;
13324 default:
13325 hddDot11Mode = iniDot11Mode;
13326 break;
13327 }
Hardik Kantilal Patel086e0a32014-11-20 14:56:26 +053013328#ifdef WLAN_FEATURE_AP_HT40_24G
13329 if (operationChannel > SIR_11B_CHANNEL_END)
13330#endif
13331 {
13332 /* This call decides required channel bonding mode */
13333 sme_SelectCBMode((WLAN_HDD_GET_CTX(pAdapter)->hHal),
Shailender Karmuchi15cd0672013-05-15 19:50:04 -070013334 hdd_cfg_xlate_to_csr_phy_mode(hddDot11Mode),
13335 operationChannel);
Hardik Kantilal Patel086e0a32014-11-20 14:56:26 +053013336 }
Shailender Karmuchi15cd0672013-05-15 19:50:04 -070013337}
13338
Jeff Johnson295189b2012-06-20 16:38:30 -070013339/*
13340 * FUNCTION: wlan_hdd_cfg80211_connect_start
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013341 * This function is used to start the association process
Jeff Johnson295189b2012-06-20 16:38:30 -070013342 */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013343int wlan_hdd_cfg80211_connect_start( hdd_adapter_t *pAdapter,
Hanumantha Reddy Pothula64081b72015-09-11 15:47:32 +053013344 const u8 *ssid, size_t ssid_len, const u8 *bssid,
13345 const u8 *bssid_hint, u8 operatingChannel)
Jeff Johnson295189b2012-06-20 16:38:30 -070013346{
13347 int status = 0;
13348 hdd_wext_state_t *pWextState;
Yue Mae36e3552014-03-05 17:06:20 -080013349 hdd_context_t *pHddCtx;
Jeff Johnson295189b2012-06-20 16:38:30 -070013350 v_U32_t roamId;
13351 tCsrRoamProfile *pRoamProfile;
Jeff Johnson295189b2012-06-20 16:38:30 -070013352 eCsrAuthType RSNAuthType;
Hanumantha Reddy Pothula64081b72015-09-11 15:47:32 +053013353 const u8 *pValidBssid = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -070013354
13355 ENTER();
13356
13357 pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
Yue Mae36e3552014-03-05 17:06:20 -080013358 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
13359
13360 status = wlan_hdd_validate_context(pHddCtx);
13361 if (status)
13362 {
Yue Mae36e3552014-03-05 17:06:20 -080013363 return status;
13364 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013365
Jeff Johnson295189b2012-06-20 16:38:30 -070013366 if (SIR_MAC_MAX_SSID_LENGTH < ssid_len)
13367 {
13368 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: wrong SSID len", __func__);
13369 return -EINVAL;
13370 }
13371
13372 pRoamProfile = &pWextState->roamProfile;
13373
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013374 if (pRoamProfile)
Jeff Johnson295189b2012-06-20 16:38:30 -070013375 {
Jeff Johnsone7245742012-09-05 17:12:55 -070013376 hdd_station_ctx_t *pHddStaCtx;
13377 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
Jeff Johnson295189b2012-06-20 16:38:30 -070013378
Siddharth Bhalda0d1622015-04-24 15:47:49 +053013379 wlan_hdd_get_frame_logs(pAdapter, WLAN_HDD_GET_FRAME_LOG_CMD_CLEAR);
13380
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013381 if (HDD_WMM_USER_MODE_NO_QOS ==
Jeff Johnson295189b2012-06-20 16:38:30 -070013382 (WLAN_HDD_GET_CTX(pAdapter))->cfg_ini->WmmMode)
13383 {
13384 /*QoS not enabled in cfg file*/
13385 pRoamProfile->uapsd_mask = 0;
13386 }
13387 else
13388 {
13389 /*QoS enabled, update uapsd mask from cfg file*/
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013390 pRoamProfile->uapsd_mask =
Jeff Johnson295189b2012-06-20 16:38:30 -070013391 (WLAN_HDD_GET_CTX(pAdapter))->cfg_ini->UapsdMask;
13392 }
13393
13394 pRoamProfile->SSIDs.numOfSSIDs = 1;
13395 pRoamProfile->SSIDs.SSIDList->SSID.length = ssid_len;
13396 vos_mem_zero(pRoamProfile->SSIDs.SSIDList->SSID.ssId,
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013397 sizeof(pRoamProfile->SSIDs.SSIDList->SSID.ssId));
Jeff Johnson295189b2012-06-20 16:38:30 -070013398 vos_mem_copy((void *)(pRoamProfile->SSIDs.SSIDList->SSID.ssId),
13399 ssid, ssid_len);
13400
13401 if (bssid)
13402 {
Hanumantha Reddy Pothula64081b72015-09-11 15:47:32 +053013403 pValidBssid = bssid;
13404 }
13405 else if (bssid_hint)
13406 {
13407 pValidBssid = bssid_hint;
13408 }
13409 if (pValidBssid)
13410 {
Jeff Johnson295189b2012-06-20 16:38:30 -070013411 pRoamProfile->BSSIDs.numOfBSSIDs = 1;
Hanumantha Reddy Pothula64081b72015-09-11 15:47:32 +053013412 vos_mem_copy((void *)(pRoamProfile->BSSIDs.bssid), pValidBssid,
Jeff Johnson295189b2012-06-20 16:38:30 -070013413 WNI_CFG_BSSID_LEN);
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013414 /* Save BSSID in seperate variable as well, as RoamProfile
13415 BSSID is getting zeroed out in the association process. And in
Jeff Johnson295189b2012-06-20 16:38:30 -070013416 case of join failure we should send valid BSSID to supplicant
13417 */
Hanumantha Reddy Pothula64081b72015-09-11 15:47:32 +053013418 vos_mem_copy((void *)(pWextState->req_bssId), pValidBssid,
Jeff Johnson295189b2012-06-20 16:38:30 -070013419 WNI_CFG_BSSID_LEN);
13420 }
Dhanashri Atre51981c62013-06-13 11:47:57 -070013421 else
13422 {
13423 vos_mem_zero((void *)(pRoamProfile->BSSIDs.bssid),WNI_CFG_BSSID_LEN);
13424 }
Jeff Johnson295189b2012-06-20 16:38:30 -070013425
Arun Kumar Khandavalli94a2bb02013-12-28 19:17:25 +053013426 hddLog(LOG1, FL("Connect to SSID: %s opertating Channel: %u"),
13427 pRoamProfile->SSIDs.SSIDList->SSID.ssId, operatingChannel);
Jeff Johnson295189b2012-06-20 16:38:30 -070013428 if ((IW_AUTH_WPA_VERSION_WPA == pWextState->wpaVersion) ||
13429 (IW_AUTH_WPA_VERSION_WPA2 == pWextState->wpaVersion))
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013430 {
Jeff Johnson295189b2012-06-20 16:38:30 -070013431 /*set gen ie*/
13432 hdd_SetGENIEToCsr(pAdapter, &RSNAuthType);
13433 /*set auth*/
13434 hdd_set_csr_auth_type(pAdapter, RSNAuthType);
13435 }
Jeff Johnson295189b2012-06-20 16:38:30 -070013436#ifdef FEATURE_WLAN_WAPI
13437 if (pAdapter->wapi_info.nWapiMode)
13438 {
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -070013439 hddLog(LOG1, "%s: Setting WAPI AUTH Type and Encryption Mode values", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -070013440 switch (pAdapter->wapi_info.wapiAuthMode)
13441 {
13442 case WAPI_AUTH_MODE_PSK:
13443 {
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -070013444 hddLog(LOG1, "%s: WAPI AUTH TYPE: PSK: %d", __func__,
Jeff Johnson295189b2012-06-20 16:38:30 -070013445 pAdapter->wapi_info.wapiAuthMode);
13446 pRoamProfile->AuthType.authType[0] = eCSR_AUTH_TYPE_WAPI_WAI_PSK;
13447 break;
13448 }
13449 case WAPI_AUTH_MODE_CERT:
13450 {
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -070013451 hddLog(LOG1, "%s: WAPI AUTH TYPE: CERT: %d", __func__,
Jeff Johnson295189b2012-06-20 16:38:30 -070013452 pAdapter->wapi_info.wapiAuthMode);
13453 pRoamProfile->AuthType.authType[0] = eCSR_AUTH_TYPE_WAPI_WAI_CERTIFICATE;
13454 break;
13455 }
13456 } // End of switch
13457 if ( pAdapter->wapi_info.wapiAuthMode == WAPI_AUTH_MODE_PSK ||
13458 pAdapter->wapi_info.wapiAuthMode == WAPI_AUTH_MODE_CERT)
13459 {
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -070013460 hddLog(LOG1, "%s: WAPI PAIRWISE/GROUP ENCRYPTION: WPI", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -070013461 pRoamProfile->AuthType.numEntries = 1;
13462 pRoamProfile->EncryptionType.numEntries = 1;
13463 pRoamProfile->EncryptionType.encryptionType[0] = eCSR_ENCRYPT_TYPE_WPI;
13464 pRoamProfile->mcEncryptionType.numEntries = 1;
13465 pRoamProfile->mcEncryptionType.encryptionType[0] = eCSR_ENCRYPT_TYPE_WPI;
13466 }
13467 }
13468#endif /* FEATURE_WLAN_WAPI */
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053013469#ifdef WLAN_FEATURE_GTK_OFFLOAD
Gopichand Nakkalad36ee622013-05-07 14:13:27 +053013470 /* Initializing gtkOffloadReqParams */
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053013471 if ((WLAN_HDD_INFRA_STATION == pAdapter->device_mode) ||
13472 (WLAN_HDD_P2P_CLIENT == pAdapter->device_mode))
13473 {
Gopichand Nakkalad36ee622013-05-07 14:13:27 +053013474 memset(&pHddStaCtx->gtkOffloadReqParams, 0,
13475 sizeof (tSirGtkOffloadParams));
13476 pHddStaCtx->gtkOffloadReqParams.ulFlags = GTK_OFFLOAD_DISABLE;
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053013477 }
13478#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070013479 pRoamProfile->csrPersona = pAdapter->device_mode;
13480
Jeff Johnson32d95a32012-09-10 13:15:23 -070013481 if( operatingChannel )
13482 {
13483 pRoamProfile->ChannelInfo.ChannelList = &operatingChannel;
13484 pRoamProfile->ChannelInfo.numOfChannels = 1;
13485 }
Chet Lanctot186b5732013-03-18 10:26:30 -070013486 else
13487 {
13488 pRoamProfile->ChannelInfo.ChannelList = NULL;
13489 pRoamProfile->ChannelInfo.numOfChannels = 0;
13490 }
Shailender Karmuchi15cd0672013-05-15 19:50:04 -070013491 if ( (WLAN_HDD_IBSS == pAdapter->device_mode) && operatingChannel)
13492 {
13493 hdd_select_cbmode(pAdapter,operatingChannel);
13494 }
Arun Kumar Khandavalli94a2bb02013-12-28 19:17:25 +053013495
Agarwal Ashish40f9b872015-09-01 16:17:35 +053013496 /*
13497 * Change conn_state to connecting before sme_RoamConnect(),
13498 * because sme_RoamConnect() has a direct path to call
13499 * hdd_smeRoamCallback(), which will change the conn_state
13500 * If direct path, conn_state will be accordingly changed
13501 * to NotConnected or Associated by either
13502 * hdd_AssociationCompletionHandler() or hdd_DisConnectHandler()
13503 * in sme_RoamCallback()
13504 * if sme_RomConnect is to be queued,
13505 * Connecting state will remain until it is completed.
13506 * If connection state is not changed,
13507 * connection state will remain in eConnectionState_NotConnected state.
13508 * In hdd_AssociationCompletionHandler, "hddDisconInProgress" is set to true
13509 * if conn state is eConnectionState_NotConnected.
13510 * If "hddDisconInProgress" is set to true then cfg80211 layer is not
13511 * informed of connect result indication which is an issue.
13512 */
13513
Gopichand Nakkalaa3c8fb62013-06-21 15:36:42 +053013514 if (WLAN_HDD_INFRA_STATION == pAdapter->device_mode ||
13515 WLAN_HDD_P2P_CLIENT == pAdapter->device_mode)
Abhishek Singhf4669da2014-05-26 15:07:49 +053013516 {
13517 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Agarwal Ashish40f9b872015-09-01 16:17:35 +053013518 FL("Set HDD connState to eConnectionState_Connecting"));
Madan Mohan Koyyalamudidf86c422012-12-04 17:03:44 -080013519 hdd_connSetConnectionState(WLAN_HDD_GET_STATION_CTX_PTR(pAdapter),
13520 eConnectionState_Connecting);
Abhishek Singhf4669da2014-05-26 15:07:49 +053013521 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013522 status = sme_RoamConnect( WLAN_HDD_GET_HAL_CTX(pAdapter),
Jeff Johnson295189b2012-06-20 16:38:30 -070013523 pAdapter->sessionId, pRoamProfile, &roamId);
13524
Gopichand Nakkalaa3c8fb62013-06-21 15:36:42 +053013525 if ((eHAL_STATUS_SUCCESS != status) &&
13526 (WLAN_HDD_INFRA_STATION == pAdapter->device_mode ||
13527 WLAN_HDD_P2P_CLIENT == pAdapter->device_mode))
Madan Mohan Koyyalamudid5acbf52012-11-28 01:45:08 +053013528
13529 {
Agarwal Ashish40f9b872015-09-01 16:17:35 +053013530 hddLog(VOS_TRACE_LEVEL_ERROR,
13531 FL("sme_RoamConnect (session %d) failed with status %d. -> NotConnected"),
13532 pAdapter->sessionId, status);
Madan Mohan Koyyalamudi42dcd162012-12-03 16:34:04 -080013533 /* change back to NotAssociated */
Madan Mohan Koyyalamudid5acbf52012-11-28 01:45:08 +053013534 hdd_connSetConnectionState(WLAN_HDD_GET_STATION_CTX_PTR(pAdapter),
Madan Mohan Koyyalamudi42dcd162012-12-03 16:34:04 -080013535 eConnectionState_NotConnected);
Madan Mohan Koyyalamudid5acbf52012-11-28 01:45:08 +053013536 }
Madan Mohan Koyyalamudidf86c422012-12-04 17:03:44 -080013537
13538 pRoamProfile->ChannelInfo.ChannelList = NULL;
13539 pRoamProfile->ChannelInfo.numOfChannels = 0;
13540
Jeff Johnson295189b2012-06-20 16:38:30 -070013541 }
13542 else
13543 {
13544 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: No valid Roam profile", __func__);
13545 return -EINVAL;
13546 }
Madan Mohan Koyyalamudifd4e1da2012-11-09 17:50:19 -080013547 EXIT();
Jeff Johnson295189b2012-06-20 16:38:30 -070013548 return status;
13549}
13550
13551/*
13552 * FUNCTION: wlan_hdd_set_cfg80211_auth_type
13553 * This function is used to set the authentication type (OPEN/SHARED).
13554 *
13555 */
13556static int wlan_hdd_cfg80211_set_auth_type(hdd_adapter_t *pAdapter,
13557 enum nl80211_auth_type auth_type)
13558{
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013559 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
Jeff Johnson295189b2012-06-20 16:38:30 -070013560 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
13561
13562 ENTER();
13563
13564 /*set authentication type*/
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013565 switch (auth_type)
Jeff Johnson295189b2012-06-20 16:38:30 -070013566 {
Jeff Johnson295189b2012-06-20 16:38:30 -070013567 case NL80211_AUTHTYPE_AUTOMATIC:
Gopichand Nakkala29149562013-05-10 21:43:41 +053013568 hddLog(VOS_TRACE_LEVEL_INFO,
13569 "%s: set authentication type to AUTOSWITCH", __func__);
13570 pHddStaCtx->conn_info.authType = eCSR_AUTH_TYPE_AUTOSWITCH;
13571 break;
13572
13573 case NL80211_AUTHTYPE_OPEN_SYSTEM:
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070013574#ifdef WLAN_FEATURE_VOWIFI_11R
13575 case NL80211_AUTHTYPE_FT:
13576#endif /* WLAN_FEATURE_VOWIFI_11R */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013577 hddLog(VOS_TRACE_LEVEL_INFO,
Jeff Johnson295189b2012-06-20 16:38:30 -070013578 "%s: set authentication type to OPEN", __func__);
13579 pHddStaCtx->conn_info.authType = eCSR_AUTH_TYPE_OPEN_SYSTEM;
13580 break;
13581
13582 case NL80211_AUTHTYPE_SHARED_KEY:
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013583 hddLog(VOS_TRACE_LEVEL_INFO,
Jeff Johnson295189b2012-06-20 16:38:30 -070013584 "%s: set authentication type to SHARED", __func__);
13585 pHddStaCtx->conn_info.authType = eCSR_AUTH_TYPE_SHARED_KEY;
13586 break;
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -080013587#ifdef FEATURE_WLAN_ESE
Jeff Johnson295189b2012-06-20 16:38:30 -070013588 case NL80211_AUTHTYPE_NETWORK_EAP:
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013589 hddLog(VOS_TRACE_LEVEL_INFO,
Jeff Johnson295189b2012-06-20 16:38:30 -070013590 "%s: set authentication type to CCKM WPA", __func__);
13591 pHddStaCtx->conn_info.authType = eCSR_AUTH_TYPE_CCKM_WPA;//eCSR_AUTH_TYPE_CCKM_RSN needs to be handled as well if required.
13592 break;
13593#endif
13594
13595
13596 default:
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013597 hddLog(VOS_TRACE_LEVEL_ERROR,
13598 "%s: Unsupported authentication type %d", __func__,
Jeff Johnson295189b2012-06-20 16:38:30 -070013599 auth_type);
13600 pHddStaCtx->conn_info.authType = eCSR_AUTH_TYPE_UNKNOWN;
13601 return -EINVAL;
13602 }
13603
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013604 pWextState->roamProfile.AuthType.authType[0] =
Jeff Johnson295189b2012-06-20 16:38:30 -070013605 pHddStaCtx->conn_info.authType;
13606 return 0;
13607}
13608
13609/*
13610 * FUNCTION: wlan_hdd_set_akm_suite
13611 * This function is used to set the key mgmt type(PSK/8021x).
13612 *
13613 */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013614static int wlan_hdd_set_akm_suite( hdd_adapter_t *pAdapter,
Jeff Johnson295189b2012-06-20 16:38:30 -070013615 u32 key_mgmt
13616 )
13617{
13618 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
13619 ENTER();
Abhishek Singhae408032014-09-25 17:22:04 +053013620 /* Should be in ieee802_11_defs.h */
13621#define WLAN_AKM_SUITE_8021X_SHA256 0x000FAC05
13622#define WLAN_AKM_SUITE_PSK_SHA256 0x000FAC06
Jeff Johnson295189b2012-06-20 16:38:30 -070013623 /*set key mgmt type*/
13624 switch(key_mgmt)
13625 {
13626 case WLAN_AKM_SUITE_PSK:
Abhishek Singhae408032014-09-25 17:22:04 +053013627 case WLAN_AKM_SUITE_PSK_SHA256:
Gopichand Nakkala356fb102013-03-06 12:34:04 +053013628#ifdef WLAN_FEATURE_VOWIFI_11R
13629 case WLAN_AKM_SUITE_FT_PSK:
13630#endif
13631 hddLog(VOS_TRACE_LEVEL_INFO, "%s: setting key mgmt type to PSK",
Jeff Johnson295189b2012-06-20 16:38:30 -070013632 __func__);
13633 pWextState->authKeyMgmt |= IW_AUTH_KEY_MGMT_PSK;
13634 break;
13635
13636 case WLAN_AKM_SUITE_8021X:
Abhishek Singhae408032014-09-25 17:22:04 +053013637 case WLAN_AKM_SUITE_8021X_SHA256:
Gopichand Nakkala356fb102013-03-06 12:34:04 +053013638#ifdef WLAN_FEATURE_VOWIFI_11R
13639 case WLAN_AKM_SUITE_FT_8021X:
13640#endif
13641 hddLog(VOS_TRACE_LEVEL_INFO, "%s: setting key mgmt type to 8021x",
Jeff Johnson295189b2012-06-20 16:38:30 -070013642 __func__);
13643 pWextState->authKeyMgmt |= IW_AUTH_KEY_MGMT_802_1X;
13644 break;
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -080013645#ifdef FEATURE_WLAN_ESE
Jeff Johnson295189b2012-06-20 16:38:30 -070013646#define WLAN_AKM_SUITE_CCKM 0x00409600 /* Should be in ieee802_11_defs.h */
13647#define IW_AUTH_KEY_MGMT_CCKM 8 /* Should be in linux/wireless.h */
13648 case WLAN_AKM_SUITE_CCKM:
13649 hddLog(VOS_TRACE_LEVEL_INFO, "%s: setting key mgmt type to CCKM",
13650 __func__);
13651 pWextState->authKeyMgmt |= IW_AUTH_KEY_MGMT_CCKM;
13652 break;
13653#endif
Leela Venkata Kiran Kumar Reddy Chiralae208a832014-04-27 22:34:25 -070013654#ifndef WLAN_AKM_SUITE_OSEN
13655#define WLAN_AKM_SUITE_OSEN 0x506f9a01 /* Should be in ieee802_11_defs.h */
13656 case WLAN_AKM_SUITE_OSEN:
13657 hddLog(VOS_TRACE_LEVEL_INFO, "%s: setting key mgmt type to OSEN",
13658 __func__);
13659 pWextState->authKeyMgmt |= IW_AUTH_KEY_MGMT_802_1X;
13660 break;
13661#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070013662
13663 default:
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013664 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Unsupported key mgmt type %d",
Jeff Johnson295189b2012-06-20 16:38:30 -070013665 __func__, key_mgmt);
13666 return -EINVAL;
13667
13668 }
13669 return 0;
13670}
13671
13672/*
13673 * FUNCTION: wlan_hdd_cfg80211_set_cipher
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013674 * This function is used to set the encryption type
Jeff Johnson295189b2012-06-20 16:38:30 -070013675 * (NONE/WEP40/WEP104/TKIP/CCMP).
13676 */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013677static int wlan_hdd_cfg80211_set_cipher( hdd_adapter_t *pAdapter,
13678 u32 cipher,
Jeff Johnson295189b2012-06-20 16:38:30 -070013679 bool ucast
13680 )
13681{
13682 eCsrEncryptionType encryptionType = eCSR_ENCRYPT_TYPE_NONE;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013683 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
Jeff Johnson295189b2012-06-20 16:38:30 -070013684 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
13685
13686 ENTER();
13687
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013688 if (!cipher)
Jeff Johnson295189b2012-06-20 16:38:30 -070013689 {
Ratheesh S P36dbc932015-08-07 14:28:57 +053013690 hddLog(VOS_TRACE_LEVEL_INFO, "%s: received cipher %d - considering none",
Jeff Johnson295189b2012-06-20 16:38:30 -070013691 __func__, cipher);
13692 encryptionType = eCSR_ENCRYPT_TYPE_NONE;
13693 }
13694 else
13695 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013696
Jeff Johnson295189b2012-06-20 16:38:30 -070013697 /*set encryption method*/
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013698 switch (cipher)
Jeff Johnson295189b2012-06-20 16:38:30 -070013699 {
13700 case IW_AUTH_CIPHER_NONE:
13701 encryptionType = eCSR_ENCRYPT_TYPE_NONE;
13702 break;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013703
Jeff Johnson295189b2012-06-20 16:38:30 -070013704 case WLAN_CIPHER_SUITE_WEP40:
Gopichand Nakkala29149562013-05-10 21:43:41 +053013705 encryptionType = eCSR_ENCRYPT_TYPE_WEP40;
Jeff Johnson295189b2012-06-20 16:38:30 -070013706 break;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013707
Jeff Johnson295189b2012-06-20 16:38:30 -070013708 case WLAN_CIPHER_SUITE_WEP104:
Gopichand Nakkala29149562013-05-10 21:43:41 +053013709 encryptionType = eCSR_ENCRYPT_TYPE_WEP104;
Jeff Johnson295189b2012-06-20 16:38:30 -070013710 break;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013711
Jeff Johnson295189b2012-06-20 16:38:30 -070013712 case WLAN_CIPHER_SUITE_TKIP:
13713 encryptionType = eCSR_ENCRYPT_TYPE_TKIP;
13714 break;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013715
Jeff Johnson295189b2012-06-20 16:38:30 -070013716 case WLAN_CIPHER_SUITE_CCMP:
13717 encryptionType = eCSR_ENCRYPT_TYPE_AES;
13718 break;
13719#ifdef FEATURE_WLAN_WAPI
13720 case WLAN_CIPHER_SUITE_SMS4:
13721 encryptionType = eCSR_ENCRYPT_TYPE_WPI;
13722 break;
13723#endif
13724
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -080013725#ifdef FEATURE_WLAN_ESE
Jeff Johnson295189b2012-06-20 16:38:30 -070013726 case WLAN_CIPHER_SUITE_KRK:
13727 encryptionType = eCSR_ENCRYPT_TYPE_KRK;
13728 break;
13729#endif
13730 default:
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013731 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Unsupported cipher type %d",
Jeff Johnson295189b2012-06-20 16:38:30 -070013732 __func__, cipher);
13733 return -EOPNOTSUPP;
13734 }
13735 }
13736
13737 if (ucast)
13738 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013739 hddLog(VOS_TRACE_LEVEL_INFO, "%s: setting unicast cipher type to %d",
Jeff Johnson295189b2012-06-20 16:38:30 -070013740 __func__, encryptionType);
13741 pHddStaCtx->conn_info.ucEncryptionType = encryptionType;
13742 pWextState->roamProfile.EncryptionType.numEntries = 1;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013743 pWextState->roamProfile.EncryptionType.encryptionType[0] =
Jeff Johnson295189b2012-06-20 16:38:30 -070013744 encryptionType;
13745 }
13746 else
13747 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013748 hddLog(VOS_TRACE_LEVEL_INFO, "%s: setting mcast cipher type to %d",
Jeff Johnson295189b2012-06-20 16:38:30 -070013749 __func__, encryptionType);
13750 pHddStaCtx->conn_info.mcEncryptionType = encryptionType;
13751 pWextState->roamProfile.mcEncryptionType.numEntries = 1;
13752 pWextState->roamProfile.mcEncryptionType.encryptionType[0] = encryptionType;
13753 }
13754
13755 return 0;
13756}
13757
13758
13759/*
13760 * FUNCTION: wlan_hdd_cfg80211_set_ie
13761 * This function is used to parse WPA/RSN IE's.
13762 */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013763int wlan_hdd_cfg80211_set_ie( hdd_adapter_t *pAdapter,
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053013764#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,18,0))
13765 const u8 *ie,
13766#else
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013767 u8 *ie,
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053013768#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070013769 size_t ie_len
13770 )
13771{
13772 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053013773#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,18,0))
13774 const u8 *genie = ie;
13775#else
Jeff Johnson295189b2012-06-20 16:38:30 -070013776 u8 *genie = ie;
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053013777#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070013778 v_U16_t remLen = ie_len;
13779#ifdef FEATURE_WLAN_WAPI
13780 v_U32_t akmsuite[MAX_NUM_AKM_SUITES];
13781 u16 *tmp;
13782 v_U16_t akmsuiteCount;
13783 int *akmlist;
13784#endif
13785 ENTER();
13786
13787 /* clear previous assocAddIE */
13788 pWextState->assocAddIE.length = 0;
13789 pWextState->roamProfile.bWPSAssociation = VOS_FALSE;
Leela Venkata Kiran Kumar Reddy Chiralaf257bef2014-04-11 18:48:12 -070013790 pWextState->roamProfile.bOSENAssociation = VOS_FALSE;
Jeff Johnson295189b2012-06-20 16:38:30 -070013791
13792 while (remLen >= 2)
13793 {
13794 v_U16_t eLen = 0;
13795 v_U8_t elementId;
13796 elementId = *genie++;
13797 eLen = *genie++;
13798 remLen -= 2;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013799
Arif Hussain6d2a3322013-11-17 19:50:10 -080013800 hddLog(VOS_TRACE_LEVEL_INFO, "%s: IE[0x%X], LEN[%d]",
Jeff Johnson295189b2012-06-20 16:38:30 -070013801 __func__, elementId, eLen);
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013802
13803 switch ( elementId )
Jeff Johnson295189b2012-06-20 16:38:30 -070013804 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013805 case DOT11F_EID_WPA:
Madan Mohan Koyyalamudief3b66e2012-10-11 14:29:42 -070013806 if (4 > eLen) /* should have at least OUI which is 4 bytes so extra 2 bytes not needed */
Jeff Johnson295189b2012-06-20 16:38:30 -070013807 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013808 hddLog(VOS_TRACE_LEVEL_ERROR,
Jeff Johnson295189b2012-06-20 16:38:30 -070013809 "%s: Invalid WPA IE", __func__);
13810 return -EINVAL;
13811 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013812 else if (0 == memcmp(&genie[0], "\x00\x50\xf2\x04", 4))
Jeff Johnson295189b2012-06-20 16:38:30 -070013813 {
13814 v_U16_t curAddIELen = pWextState->assocAddIE.length;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013815 hddLog (VOS_TRACE_LEVEL_INFO, "%s Set WPS IE(len %d)",
Jeff Johnson295189b2012-06-20 16:38:30 -070013816 __func__, eLen + 2);
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013817
Ganesh Kondabattini7500fb32015-04-10 14:50:32 +053013818 if( SIR_MAC_MAX_ADD_IE_LENGTH < (pWextState->assocAddIE.length + eLen) )
Jeff Johnson295189b2012-06-20 16:38:30 -070013819 {
Jeff Johnson902c9832012-12-10 14:28:09 -080013820 hddLog(VOS_TRACE_LEVEL_FATAL, "Cannot accommodate assocAddIE. "
13821 "Need bigger buffer space");
Jeff Johnson295189b2012-06-20 16:38:30 -070013822 VOS_ASSERT(0);
13823 return -ENOMEM;
13824 }
13825 // WSC IE is saved to Additional IE ; it should be accumulated to handle WPS IE + P2P IE
13826 memcpy( pWextState->assocAddIE.addIEdata + curAddIELen, genie - 2, eLen + 2);
13827 pWextState->assocAddIE.length += eLen + 2;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013828
Jeff Johnson295189b2012-06-20 16:38:30 -070013829 pWextState->roamProfile.bWPSAssociation = VOS_TRUE;
13830 pWextState->roamProfile.pAddIEAssoc = pWextState->assocAddIE.addIEdata;
13831 pWextState->roamProfile.nAddIEAssocLength = pWextState->assocAddIE.length;
13832 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013833 else if (0 == memcmp(&genie[0], "\x00\x50\xf2", 3))
13834 {
Jeff Johnson295189b2012-06-20 16:38:30 -070013835 hddLog (VOS_TRACE_LEVEL_INFO, "%s Set WPA IE (len %d)",__func__, eLen + 2);
13836 memset( pWextState->WPARSNIE, 0, MAX_WPA_RSN_IE_LEN );
13837 memcpy( pWextState->WPARSNIE, genie - 2, (eLen + 2) /*ie_len*/);
13838 pWextState->roamProfile.pWPAReqIE = pWextState->WPARSNIE;
13839 pWextState->roamProfile.nWPAReqIELength = eLen + 2;//ie_len;
13840 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013841 else if ( (0 == memcmp(&genie[0], P2P_OUI_TYPE,
Kiet Lam8da98992013-11-21 15:59:07 +053013842 P2P_OUI_TYPE_SIZE)))
Jeff Johnson295189b2012-06-20 16:38:30 -070013843 {
13844 v_U16_t curAddIELen = pWextState->assocAddIE.length;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013845 hddLog (VOS_TRACE_LEVEL_INFO, "%s Set P2P IE(len %d)",
Jeff Johnson295189b2012-06-20 16:38:30 -070013846 __func__, eLen + 2);
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013847
Ganesh Kondabattini7500fb32015-04-10 14:50:32 +053013848 if( SIR_MAC_MAX_ADD_IE_LENGTH < (pWextState->assocAddIE.length + eLen) )
Jeff Johnson295189b2012-06-20 16:38:30 -070013849 {
Jeff Johnson902c9832012-12-10 14:28:09 -080013850 hddLog(VOS_TRACE_LEVEL_FATAL, "Cannot accommodate assocAddIE "
13851 "Need bigger buffer space");
Jeff Johnson295189b2012-06-20 16:38:30 -070013852 VOS_ASSERT(0);
13853 return -ENOMEM;
13854 }
13855 // P2P IE is saved to Additional IE ; it should be accumulated to handle WPS IE + P2P IE
13856 memcpy( pWextState->assocAddIE.addIEdata + curAddIELen, genie - 2, eLen + 2);
13857 pWextState->assocAddIE.length += eLen + 2;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013858
Jeff Johnson295189b2012-06-20 16:38:30 -070013859 pWextState->roamProfile.pAddIEAssoc = pWextState->assocAddIE.addIEdata;
13860 pWextState->roamProfile.nAddIEAssocLength = pWextState->assocAddIE.length;
13861 }
Jeff Johnson295189b2012-06-20 16:38:30 -070013862#ifdef WLAN_FEATURE_WFD
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013863 else if ( (0 == memcmp(&genie[0], WFD_OUI_TYPE,
13864 WFD_OUI_TYPE_SIZE))
Jeff Johnson295189b2012-06-20 16:38:30 -070013865 /*Consider WFD IE, only for P2P Client */
13866 && (WLAN_HDD_P2P_CLIENT == pAdapter->device_mode) )
13867 {
13868 v_U16_t curAddIELen = pWextState->assocAddIE.length;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013869 hddLog (VOS_TRACE_LEVEL_INFO, "%s Set WFD IE(len %d)",
Jeff Johnson295189b2012-06-20 16:38:30 -070013870 __func__, eLen + 2);
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013871
Ganesh Kondabattini7500fb32015-04-10 14:50:32 +053013872 if( SIR_MAC_MAX_ADD_IE_LENGTH < (pWextState->assocAddIE.length + eLen) )
Jeff Johnson295189b2012-06-20 16:38:30 -070013873 {
Jeff Johnson902c9832012-12-10 14:28:09 -080013874 hddLog(VOS_TRACE_LEVEL_FATAL, "Cannot accommodate assocAddIE "
13875 "Need bigger buffer space");
Jeff Johnson295189b2012-06-20 16:38:30 -070013876 VOS_ASSERT(0);
13877 return -ENOMEM;
13878 }
13879 // WFD IE is saved to Additional IE ; it should be accumulated to handle
13880 // WPS IE + P2P IE + WFD IE
13881 memcpy( pWextState->assocAddIE.addIEdata + curAddIELen, genie - 2, eLen + 2);
13882 pWextState->assocAddIE.length += eLen + 2;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013883
Jeff Johnson295189b2012-06-20 16:38:30 -070013884 pWextState->roamProfile.pAddIEAssoc = pWextState->assocAddIE.addIEdata;
13885 pWextState->roamProfile.nAddIEAssocLength = pWextState->assocAddIE.length;
13886 }
13887#endif
Madan Mohan Koyyalamudief3b66e2012-10-11 14:29:42 -070013888 /* Appending HS 2.0 Indication Element in Assiciation Request */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013889 else if ( (0 == memcmp(&genie[0], HS20_OUI_TYPE,
Madan Mohan Koyyalamudi1bed5982012-10-22 14:38:06 -070013890 HS20_OUI_TYPE_SIZE)) )
13891 {
13892 v_U16_t curAddIELen = pWextState->assocAddIE.length;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013893 hddLog (VOS_TRACE_LEVEL_INFO, "%s Set HS20 IE(len %d)",
Madan Mohan Koyyalamudi1bed5982012-10-22 14:38:06 -070013894 __func__, eLen + 2);
Madan Mohan Koyyalamudief3b66e2012-10-11 14:29:42 -070013895
Ganesh Kondabattini7500fb32015-04-10 14:50:32 +053013896 if( SIR_MAC_MAX_ADD_IE_LENGTH < (pWextState->assocAddIE.length + eLen) )
Madan Mohan Koyyalamudi1bed5982012-10-22 14:38:06 -070013897 {
Jeff Johnson902c9832012-12-10 14:28:09 -080013898 hddLog(VOS_TRACE_LEVEL_FATAL, "Cannot accommodate assocAddIE "
13899 "Need bigger buffer space");
Madan Mohan Koyyalamudi1bed5982012-10-22 14:38:06 -070013900 VOS_ASSERT(0);
13901 return -ENOMEM;
13902 }
13903 memcpy( pWextState->assocAddIE.addIEdata + curAddIELen, genie - 2, eLen + 2);
13904 pWextState->assocAddIE.length += eLen + 2;
Madan Mohan Koyyalamudief3b66e2012-10-11 14:29:42 -070013905
Madan Mohan Koyyalamudi1bed5982012-10-22 14:38:06 -070013906 pWextState->roamProfile.pAddIEAssoc = pWextState->assocAddIE.addIEdata;
13907 pWextState->roamProfile.nAddIEAssocLength = pWextState->assocAddIE.length;
13908 }
Leela Venkata Kiran Kumar Reddy Chiralaf257bef2014-04-11 18:48:12 -070013909 /* Appending OSEN Information Element in Assiciation Request */
13910 else if ( (0 == memcmp(&genie[0], OSEN_OUI_TYPE,
13911 OSEN_OUI_TYPE_SIZE)) )
13912 {
13913 v_U16_t curAddIELen = pWextState->assocAddIE.length;
13914 hddLog (VOS_TRACE_LEVEL_INFO, "%s Set OSEN IE(len %d)",
13915 __func__, eLen + 2);
Madan Mohan Koyyalamudief3b66e2012-10-11 14:29:42 -070013916
Ganesh Kondabattini7500fb32015-04-10 14:50:32 +053013917 if( SIR_MAC_MAX_ADD_IE_LENGTH < (pWextState->assocAddIE.length + eLen) )
Leela Venkata Kiran Kumar Reddy Chiralaf257bef2014-04-11 18:48:12 -070013918 {
13919 hddLog(VOS_TRACE_LEVEL_FATAL, "Cannot accommodate assocAddIE "
13920 "Need bigger buffer space");
13921 VOS_ASSERT(0);
13922 return -ENOMEM;
13923 }
13924 memcpy( pWextState->assocAddIE.addIEdata + curAddIELen, genie - 2, eLen + 2);
13925 pWextState->assocAddIE.length += eLen + 2;
13926
13927 pWextState->roamProfile.bOSENAssociation = VOS_TRUE;
13928 pWextState->roamProfile.pAddIEAssoc = pWextState->assocAddIE.addIEdata;
13929 pWextState->roamProfile.nAddIEAssocLength = pWextState->assocAddIE.length;
13930 }
13931
Abhishek Singh4322e622015-06-10 15:42:54 +053013932 /* Update only for WPA IE */
13933 if (!memcmp(genie, WPA_OUI_TYPE, WPA_OUI_TYPE_SIZE) &&
13934 (WLAN_HDD_IBSS == pAdapter->device_mode)) {
Praveen Kumar Sirisilla7d68b7b2013-09-22 14:01:42 -070013935
13936 /* populating as ADDIE in beacon frames */
13937 if (ccmCfgSetStr(WLAN_HDD_GET_HAL_CTX(pAdapter),
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053013938 WNI_CFG_PROBE_RSP_BCN_ADDNIE_DATA, (u8 *)genie - 2, eLen + 2,
Praveen Kumar Sirisilla7d68b7b2013-09-22 14:01:42 -070013939 NULL, eANI_BOOLEAN_FALSE)== eHAL_STATUS_SUCCESS)
13940 {
13941 if (ccmCfgSetInt(WLAN_HDD_GET_HAL_CTX(pAdapter),
13942 WNI_CFG_PROBE_RSP_BCN_ADDNIE_FLAG, 1,NULL,
13943 eANI_BOOLEAN_FALSE) == eHAL_STATUS_FAILURE)
13944 {
13945 hddLog(LOGE,
13946 "Coldn't pass "
13947 "WNI_CFG_PROBE_RSP_BCN_ADDNIE_FLAG to CCM");
13948 }
13949 }/* ccmCfgSetStr(,WNI_CFG_PROBE_RSP_BCN_ADDNIE_DATA, , )*/
13950 else
13951 hddLog(LOGE,
13952 "Could not pass on "
13953 "WNI_CFG_PROBE_RSP_BCN_ADDNIE_DATA to CCM");
13954
13955 /* IBSS mode doesn't contain params->proberesp_ies still
13956 beaconIE's need to be populated in probe response frames */
13957 if ( (NULL != (genie - 2)) && (0 != eLen + 2) )
13958 {
13959 u16 rem_probe_resp_ie_len = eLen + 2;
13960 u8 probe_rsp_ie_len[3] = {0};
13961 u8 counter = 0;
13962
13963 /* Check Probe Resp Length if it is greater then 255 then
13964 Store Probe Rsp IEs into WNI_CFG_PROBE_RSP_ADDNIE_DATA1
13965 & WNI_CFG_PROBE_RSP_ADDNIE_DATA2 CFG Variable As We are
13966 not able Store More then 255 bytes into One Variable */
13967
13968 while ((rem_probe_resp_ie_len > 0) && (counter < 3))
13969 {
13970 if (rem_probe_resp_ie_len > MAX_CFG_STRING_LEN)
13971 {
13972 probe_rsp_ie_len[counter++] = MAX_CFG_STRING_LEN;
13973 rem_probe_resp_ie_len -= MAX_CFG_STRING_LEN;
13974 }
13975 else
13976 {
13977 probe_rsp_ie_len[counter++] = rem_probe_resp_ie_len;
13978 rem_probe_resp_ie_len = 0;
13979 }
13980 }
13981
13982 rem_probe_resp_ie_len = 0;
13983
13984 if (probe_rsp_ie_len[0] > 0)
13985 {
13986 if (ccmCfgSetStr(WLAN_HDD_GET_HAL_CTX(pAdapter),
13987 WNI_CFG_PROBE_RSP_ADDNIE_DATA1,
13988 (tANI_U8*)(genie - 2),
13989 probe_rsp_ie_len[0], NULL,
13990 eANI_BOOLEAN_FALSE)
13991 == eHAL_STATUS_FAILURE)
13992 {
13993 hddLog(LOGE,
13994 "Could not pass"
13995 "on WNI_CFG_PROBE_RSP_ADDNIE_DATA1 to CCM");
13996 }
13997 rem_probe_resp_ie_len += probe_rsp_ie_len[0];
13998 }
13999
14000 if (probe_rsp_ie_len[1] > 0)
14001 {
14002 if (ccmCfgSetStr(WLAN_HDD_GET_HAL_CTX(pAdapter),
14003 WNI_CFG_PROBE_RSP_ADDNIE_DATA2,
14004 (tANI_U8*)(genie - (2 + rem_probe_resp_ie_len)),
14005 probe_rsp_ie_len[1], NULL,
14006 eANI_BOOLEAN_FALSE)
14007 == eHAL_STATUS_FAILURE)
14008 {
14009 hddLog(LOGE,
14010 "Could not pass"
14011 "on WNI_CFG_PROBE_RSP_ADDNIE_DATA2 to CCM");
14012 }
14013 rem_probe_resp_ie_len += probe_rsp_ie_len[1];
14014 }
14015
14016 if (probe_rsp_ie_len[2] > 0)
14017 {
14018 if (ccmCfgSetStr(WLAN_HDD_GET_HAL_CTX(pAdapter),
14019 WNI_CFG_PROBE_RSP_ADDNIE_DATA3,
14020 (tANI_U8*)(genie - (2 + rem_probe_resp_ie_len)),
14021 probe_rsp_ie_len[2], NULL,
14022 eANI_BOOLEAN_FALSE)
14023 == eHAL_STATUS_FAILURE)
14024 {
14025 hddLog(LOGE,
14026 "Could not pass"
14027 "on WNI_CFG_PROBE_RSP_ADDNIE_DATA3 to CCM");
14028 }
14029 rem_probe_resp_ie_len += probe_rsp_ie_len[2];
14030 }
14031
14032 if (ccmCfgSetInt(WLAN_HDD_GET_HAL_CTX(pAdapter),
14033 WNI_CFG_PROBE_RSP_ADDNIE_FLAG, 1,NULL,
14034 eANI_BOOLEAN_FALSE) == eHAL_STATUS_FAILURE)
14035 {
14036 hddLog(LOGE,
14037 "Could not pass"
14038 "on WNI_CFG_PROBE_RSP_ADDNIE_FLAG to CCM");
14039 }
14040 }
Praveen Kumar Sirisilla7d68b7b2013-09-22 14:01:42 -070014041 } /* end of if (WLAN_HDD_IBSS == pAdapter->device_mode) */
Jeff Johnson295189b2012-06-20 16:38:30 -070014042 break;
14043 case DOT11F_EID_RSN:
14044 hddLog (VOS_TRACE_LEVEL_INFO, "%s Set RSN IE(len %d)",__func__, eLen + 2);
14045 memset( pWextState->WPARSNIE, 0, MAX_WPA_RSN_IE_LEN );
14046 memcpy( pWextState->WPARSNIE, genie - 2, (eLen + 2)/*ie_len*/);
14047 pWextState->roamProfile.pRSNReqIE = pWextState->WPARSNIE;
14048 pWextState->roamProfile.nRSNReqIELength = eLen + 2; //ie_len;
14049 break;
Abhishek Singh15d95602015-03-24 15:52:57 +053014050
14051 /* Appending Extended Capabilities with Interworking bit set
14052 * in Assoc Req.
14053 *
14054 * In assoc req this EXT Cap will only be taken into account if
14055 * interworkingService bit is set to 1. Currently
14056 * driver is only interested in interworkingService capability
14057 * from supplicant. If in future any other EXT Cap info is
14058 * required from supplicat, it needs to be handled while
14059 * sending Assoc Req in LIM.
14060 */
Madan Mohan Koyyalamudief3b66e2012-10-11 14:29:42 -070014061 case DOT11F_EID_EXTCAP:
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014062 {
Madan Mohan Koyyalamudief3b66e2012-10-11 14:29:42 -070014063 v_U16_t curAddIELen = pWextState->assocAddIE.length;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014064 hddLog (VOS_TRACE_LEVEL_INFO, "%s Set Extended CAPS IE(len %d)",
Madan Mohan Koyyalamudief3b66e2012-10-11 14:29:42 -070014065 __func__, eLen + 2);
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014066
Ganesh Kondabattini7500fb32015-04-10 14:50:32 +053014067 if( SIR_MAC_MAX_ADD_IE_LENGTH < (pWextState->assocAddIE.length + eLen) )
Madan Mohan Koyyalamudief3b66e2012-10-11 14:29:42 -070014068 {
Jeff Johnson902c9832012-12-10 14:28:09 -080014069 hddLog(VOS_TRACE_LEVEL_FATAL, "Cannot accommodate assocAddIE "
14070 "Need bigger buffer space");
Madan Mohan Koyyalamudief3b66e2012-10-11 14:29:42 -070014071 VOS_ASSERT(0);
14072 return -ENOMEM;
14073 }
14074 memcpy( pWextState->assocAddIE.addIEdata + curAddIELen, genie - 2, eLen + 2);
14075 pWextState->assocAddIE.length += eLen + 2;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014076
Madan Mohan Koyyalamudief3b66e2012-10-11 14:29:42 -070014077 pWextState->roamProfile.pAddIEAssoc = pWextState->assocAddIE.addIEdata;
14078 pWextState->roamProfile.nAddIEAssocLength = pWextState->assocAddIE.length;
14079 break;
14080 }
Jeff Johnson295189b2012-06-20 16:38:30 -070014081#ifdef FEATURE_WLAN_WAPI
14082 case WLAN_EID_WAPI:
14083 pAdapter->wapi_info.nWapiMode = 1; //Setting WAPI Mode to ON=1
Jeff Johnson0299d0a2013-10-30 12:37:43 -070014084 hddLog(VOS_TRACE_LEVEL_INFO, "WAPI MODE IS %u",
Jeff Johnson295189b2012-06-20 16:38:30 -070014085 pAdapter->wapi_info.nWapiMode);
14086 tmp = (u16 *)ie;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014087 tmp = tmp + 2; // Skip element Id and Len, Version
Jeff Johnson295189b2012-06-20 16:38:30 -070014088 akmsuiteCount = WPA_GET_LE16(tmp);
14089 tmp = tmp + 1;
14090 akmlist = (int *)(tmp);
14091 if(akmsuiteCount <= MAX_NUM_AKM_SUITES)
14092 {
14093 memcpy(akmsuite, akmlist, (4*akmsuiteCount));
14094 }
14095 else
14096 {
Arif Hussain6d2a3322013-11-17 19:50:10 -080014097 hddLog(VOS_TRACE_LEVEL_FATAL, "Invalid akmSuite count");
Jeff Johnson295189b2012-06-20 16:38:30 -070014098 VOS_ASSERT(0);
14099 return -EINVAL;
14100 }
14101
14102 if (WAPI_PSK_AKM_SUITE == akmsuite[0])
14103 {
14104 hddLog(VOS_TRACE_LEVEL_INFO, "%s: WAPI AUTH MODE SET TO PSK",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -070014105 __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -070014106 pAdapter->wapi_info.wapiAuthMode = WAPI_AUTH_MODE_PSK;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014107 }
Jeff Johnson295189b2012-06-20 16:38:30 -070014108 if (WAPI_CERT_AKM_SUITE == akmsuite[0])
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014109 {
Jeff Johnson295189b2012-06-20 16:38:30 -070014110 hddLog(VOS_TRACE_LEVEL_INFO, "%s: WAPI AUTH MODE SET TO CERTIFICATE",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -070014111 __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -070014112 pAdapter->wapi_info.wapiAuthMode = WAPI_AUTH_MODE_CERT;
14113 }
14114 break;
14115#endif
14116 default:
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014117 hddLog (VOS_TRACE_LEVEL_ERROR,
Jeff Johnson295189b2012-06-20 16:38:30 -070014118 "%s Set UNKNOWN IE %X", __func__, elementId);
Madan Mohan Koyyalamudief3b66e2012-10-11 14:29:42 -070014119 /* when Unknown IE is received we should break and continue
14120 * to the next IE in the buffer instead we were returning
14121 * so changing this to break */
14122 break;
Jeff Johnson295189b2012-06-20 16:38:30 -070014123 }
14124 genie += eLen;
14125 remLen -= eLen;
14126 }
14127 EXIT();
14128 return 0;
14129}
14130
14131/*
Gopichand Nakkala18f0c262013-05-07 23:25:08 +053014132 * FUNCTION: hdd_isWPAIEPresent
14133 * Parse the received IE to find the WPA IE
14134 *
14135 */
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053014136static bool hdd_isWPAIEPresent(
14137#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 18, 0))
14138 const u8 *ie,
14139#else
14140 u8 *ie,
14141#endif
14142 u8 ie_len)
Gopichand Nakkala18f0c262013-05-07 23:25:08 +053014143{
14144 v_U8_t eLen = 0;
14145 v_U16_t remLen = ie_len;
14146 v_U8_t elementId = 0;
14147
14148 while (remLen >= 2)
14149 {
14150 elementId = *ie++;
14151 eLen = *ie++;
14152 remLen -= 2;
14153 if (eLen > remLen)
14154 {
14155 hddLog(VOS_TRACE_LEVEL_ERROR,
14156 "%s: IE length is wrong %d", __func__, eLen);
14157 return FALSE;
14158 }
14159 if ((elementId == DOT11F_EID_WPA) && (remLen > 5))
14160 {
14161 /* OUI - 0x00 0X50 0XF2
14162 WPA Information Element - 0x01
14163 WPA version - 0x01*/
14164 if (0 == memcmp(&ie[0], "\x00\x50\xf2\x01\x01", 5))
14165 return TRUE;
14166 }
14167 ie += eLen;
14168 remLen -= eLen;
14169 }
14170 return FALSE;
14171}
14172
14173/*
Jeff Johnson295189b2012-06-20 16:38:30 -070014174 * FUNCTION: wlan_hdd_cfg80211_set_privacy
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014175 * This function is used to initialize the security
Jeff Johnson295189b2012-06-20 16:38:30 -070014176 * parameters during connect operation.
14177 */
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053014178int wlan_hdd_cfg80211_set_privacy(hdd_adapter_t *pAdapter,
Jeff Johnson295189b2012-06-20 16:38:30 -070014179 struct cfg80211_connect_params *req
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053014180 )
Jeff Johnson295189b2012-06-20 16:38:30 -070014181{
14182 int status = 0;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014183 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
Jeff Johnson295189b2012-06-20 16:38:30 -070014184 ENTER();
14185
14186 /*set wpa version*/
14187 pWextState->wpaVersion = IW_AUTH_WPA_VERSION_DISABLED;
14188
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014189 if (req->crypto.wpa_versions)
Jeff Johnson295189b2012-06-20 16:38:30 -070014190 {
Gopichand Nakkala781ded42013-06-28 12:10:45 +053014191 if (NL80211_WPA_VERSION_1 == req->crypto.wpa_versions)
Jeff Johnson295189b2012-06-20 16:38:30 -070014192 {
14193 pWextState->wpaVersion = IW_AUTH_WPA_VERSION_WPA;
14194 }
14195 else if (NL80211_WPA_VERSION_2 == req->crypto.wpa_versions)
14196 {
14197 pWextState->wpaVersion = IW_AUTH_WPA_VERSION_WPA2;
14198 }
14199 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014200
14201 hddLog(VOS_TRACE_LEVEL_INFO, "%s: set wpa version to %d", __func__,
Jeff Johnson295189b2012-06-20 16:38:30 -070014202 pWextState->wpaVersion);
14203
14204 /*set authentication type*/
14205 status = wlan_hdd_cfg80211_set_auth_type(pAdapter, req->auth_type);
14206
14207 if (0 > status)
14208 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014209 hddLog(VOS_TRACE_LEVEL_ERROR,
Jeff Johnson295189b2012-06-20 16:38:30 -070014210 "%s: failed to set authentication type ", __func__);
14211 return status;
14212 }
14213
14214 /*set key mgmt type*/
14215 if (req->crypto.n_akm_suites)
14216 {
14217 status = wlan_hdd_set_akm_suite(pAdapter, req->crypto.akm_suites[0]);
14218 if (0 > status)
14219 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014220 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: failed to set akm suite",
Jeff Johnson295189b2012-06-20 16:38:30 -070014221 __func__);
14222 return status;
14223 }
14224 }
14225
14226 /*set pairwise cipher type*/
14227 if (req->crypto.n_ciphers_pairwise)
14228 {
14229 status = wlan_hdd_cfg80211_set_cipher(pAdapter,
14230 req->crypto.ciphers_pairwise[0], true);
14231 if (0 > status)
14232 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014233 hddLog(VOS_TRACE_LEVEL_ERROR,
Jeff Johnson295189b2012-06-20 16:38:30 -070014234 "%s: failed to set unicast cipher type", __func__);
14235 return status;
14236 }
14237 }
14238 else
14239 {
14240 /*Reset previous cipher suite to none*/
14241 status = wlan_hdd_cfg80211_set_cipher(pAdapter, 0, true);
14242 if (0 > status)
14243 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014244 hddLog(VOS_TRACE_LEVEL_ERROR,
Jeff Johnson295189b2012-06-20 16:38:30 -070014245 "%s: failed to set unicast cipher type", __func__);
14246 return status;
14247 }
14248 }
14249
14250 /*set group cipher type*/
14251 status = wlan_hdd_cfg80211_set_cipher(pAdapter, req->crypto.cipher_group,
14252 false);
14253
14254 if (0 > status)
14255 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014256 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: failed to set mcast cipher type",
Jeff Johnson295189b2012-06-20 16:38:30 -070014257 __func__);
14258 return status;
14259 }
14260
Chet Lanctot186b5732013-03-18 10:26:30 -070014261#ifdef WLAN_FEATURE_11W
14262 pWextState->roamProfile.MFPEnabled = (req->mfp == NL80211_MFP_REQUIRED);
14263#endif
14264
Jeff Johnson295189b2012-06-20 16:38:30 -070014265 /*parse WPA/RSN IE, and set the correspoing fileds in Roam profile*/
14266 if (req->ie_len)
14267 {
14268 status = wlan_hdd_cfg80211_set_ie(pAdapter, req->ie, req->ie_len);
14269 if ( 0 > status)
14270 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014271 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: failed to parse the WPA/RSN IE",
Jeff Johnson295189b2012-06-20 16:38:30 -070014272 __func__);
14273 return status;
14274 }
14275 }
14276
14277 /*incase of WEP set default key information*/
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014278 if (req->key && req->key_len)
Jeff Johnson295189b2012-06-20 16:38:30 -070014279 {
14280 if ( (WLAN_CIPHER_SUITE_WEP40 == req->crypto.ciphers_pairwise[0])
14281 || (WLAN_CIPHER_SUITE_WEP104 == req->crypto.ciphers_pairwise[0])
14282 )
14283 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014284 if ( IW_AUTH_KEY_MGMT_802_1X
Jeff Johnson295189b2012-06-20 16:38:30 -070014285 == (pWextState->authKeyMgmt & IW_AUTH_KEY_MGMT_802_1X ))
14286 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014287 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Dynamic WEP not supported",
Jeff Johnson295189b2012-06-20 16:38:30 -070014288 __func__);
14289 return -EOPNOTSUPP;
14290 }
14291 else
14292 {
14293 u8 key_len = req->key_len;
14294 u8 key_idx = req->key_idx;
14295
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014296 if ((eCSR_SECURITY_WEP_KEYSIZE_MAX_BYTES >= key_len)
Jeff Johnson295189b2012-06-20 16:38:30 -070014297 && (CSR_MAX_NUM_KEY > key_idx)
14298 )
14299 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014300 hddLog(VOS_TRACE_LEVEL_INFO,
14301 "%s: setting default wep key, key_idx = %hu key_len %hu",
Jeff Johnson295189b2012-06-20 16:38:30 -070014302 __func__, key_idx, key_len);
14303 vos_mem_copy(
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014304 &pWextState->roamProfile.Keys.KeyMaterial[key_idx][0],
Jeff Johnson295189b2012-06-20 16:38:30 -070014305 req->key, key_len);
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014306 pWextState->roamProfile.Keys.KeyLength[key_idx] =
Jeff Johnson295189b2012-06-20 16:38:30 -070014307 (u8)key_len;
14308 pWextState->roamProfile.Keys.defaultIndex = (u8)key_idx;
14309 }
14310 }
14311 }
14312 }
14313
14314 return status;
14315}
14316
14317/*
Vinay Krishna Eranna21042322014-01-08 19:21:39 +053014318 * FUNCTION: wlan_hdd_try_disconnect
14319 * This function is used to disconnect from previous
14320 * connection
14321 */
14322static int wlan_hdd_try_disconnect( hdd_adapter_t *pAdapter )
14323{
14324 long ret = 0;
14325 hdd_station_ctx_t *pHddStaCtx;
14326 eMib_dot11DesiredBssType connectedBssType;
14327
14328 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
14329
14330 hdd_connGetConnectedBssType(pHddStaCtx,&connectedBssType );
14331
14332 if((eMib_dot11DesiredBssType_independent == connectedBssType) ||
14333 (eConnectionState_Associated == pHddStaCtx->conn_info.connState) ||
14334 (eConnectionState_IbssConnected == pHddStaCtx->conn_info.connState))
14335 {
Abhishek Singhf7962582015-10-23 10:54:06 +053014336 hdd_connSetConnectionState(pHddStaCtx,
14337 eConnectionState_Disconnecting);
Vinay Krishna Eranna21042322014-01-08 19:21:39 +053014338 /* Issue disconnect to CSR */
14339 INIT_COMPLETION(pAdapter->disconnect_comp_var);
14340 if( eHAL_STATUS_SUCCESS ==
14341 sme_RoamDisconnect( WLAN_HDD_GET_HAL_CTX(pAdapter),
14342 pAdapter->sessionId,
14343 eCSR_DISCONNECT_REASON_UNSPECIFIED ) )
14344 {
14345 ret = wait_for_completion_interruptible_timeout(
14346 &pAdapter->disconnect_comp_var,
14347 msecs_to_jiffies(WLAN_WAIT_TIME_DISCONNECT));
14348 if (0 >= ret)
14349 {
14350 hddLog(LOGE, FL("Failed to receive disconnect event"));
14351 return -EALREADY;
14352 }
14353 }
14354 }
14355 else if(eConnectionState_Disconnecting == pHddStaCtx->conn_info.connState)
14356 {
14357 ret = wait_for_completion_interruptible_timeout(
14358 &pAdapter->disconnect_comp_var,
14359 msecs_to_jiffies(WLAN_WAIT_TIME_DISCONNECT));
14360 if (0 >= ret)
14361 {
14362 hddLog(LOGE, FL("Failed to receive disconnect event"));
14363 return -EALREADY;
14364 }
14365 }
14366
14367 return 0;
14368}
14369
14370/*
Agarwal Ashish51325b52014-06-16 16:50:49 +053014371 * FUNCTION: __wlan_hdd_cfg80211_connect
14372 * This function is used to start the association process
Jeff Johnson295189b2012-06-20 16:38:30 -070014373 */
Mahesh A Saptasagarfafb7fe2014-05-16 13:19:37 +053014374static int __wlan_hdd_cfg80211_connect( struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -070014375 struct net_device *ndev,
14376 struct cfg80211_connect_params *req
14377 )
14378{
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053014379 int status;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014380 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( ndev );
Jeff Johnson295189b2012-06-20 16:38:30 -070014381 VOS_STATUS exitbmpsStatus = VOS_STATUS_E_INVAL;
Sushant Kaushikba6764e2014-06-30 19:52:09 +053014382 hdd_context_t *pHddCtx = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -070014383
14384 ENTER();
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053014385
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053014386 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
14387 TRACE_CODE_HDD_CFG80211_CONNECT,
14388 pAdapter->sessionId, pAdapter->device_mode));
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014389 hddLog(VOS_TRACE_LEVEL_INFO,
Sushant Kaushik8bc7df22014-04-09 17:55:29 +053014390 "%s: device_mode = %s (%d)", __func__,
14391 hdd_device_modetoString(pAdapter->device_mode),
14392 pAdapter->device_mode);
Jeff Johnson295189b2012-06-20 16:38:30 -070014393
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053014394 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Rajesh Chauhana0516c62014-01-30 16:11:18 -080014395 if (!pHddCtx)
14396 {
14397 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
14398 "%s: HDD context is null", __func__);
Agarwal Ashish51325b52014-06-16 16:50:49 +053014399 return -EINVAL;
Rajesh Chauhana0516c62014-01-30 16:11:18 -080014400 }
14401
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053014402 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053014403 if (0 != status)
Jeff Johnson295189b2012-06-20 16:38:30 -070014404 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053014405 return status;
Jeff Johnson295189b2012-06-20 16:38:30 -070014406 }
14407
Agarwal Ashish51325b52014-06-16 16:50:49 +053014408 if (vos_max_concurrent_connections_reached()) {
14409 hddLog(VOS_TRACE_LEVEL_INFO, FL("Reached max concurrent connections"));
14410 return -ECONNREFUSED;
14411 }
14412
Jeff Johnson295189b2012-06-20 16:38:30 -070014413#ifdef WLAN_BTAMP_FEATURE
14414 //Infra connect not supported when AMP traffic is on.
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014415 if( VOS_TRUE == WLANBAP_AmpSessionOn() )
Jeff Johnson295189b2012-06-20 16:38:30 -070014416 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014417 hddLog(VOS_TRACE_LEVEL_ERROR,
Jeff Johnson295189b2012-06-20 16:38:30 -070014418 "%s: No connection when AMP is on", __func__);
Madan Mohan Koyyalamudicae253a2012-11-06 19:10:35 -080014419 return -ECONNREFUSED;
Jeff Johnson295189b2012-06-20 16:38:30 -070014420 }
14421#endif
Vinay Krishna Eranna21042322014-01-08 19:21:39 +053014422
14423 //If Device Mode is Station Concurrent Sessions Exit BMps
14424 //P2P Mode will be taken care in Open/close adapter
14425 if((WLAN_HDD_INFRA_STATION == pAdapter->device_mode) &&
Agarwal Ashish51325b52014-06-16 16:50:49 +053014426 (vos_concurrent_open_sessions_running())) {
14427 exitbmpsStatus = hdd_disable_bmps_imps(pHddCtx,
14428 WLAN_HDD_INFRA_STATION);
Vinay Krishna Eranna21042322014-01-08 19:21:39 +053014429 }
14430
14431 /*Try disconnecting if already in connected state*/
14432 status = wlan_hdd_try_disconnect(pAdapter);
14433 if ( 0 > status)
14434 {
14435 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Failed to disconnect the existing"
14436 " connection"));
14437 return -EALREADY;
14438 }
14439
Jeff Johnson295189b2012-06-20 16:38:30 -070014440 /*initialise security parameters*/
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014441 status = wlan_hdd_cfg80211_set_privacy(pAdapter, req);
Jeff Johnson295189b2012-06-20 16:38:30 -070014442
14443 if ( 0 > status)
14444 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014445 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: failed to set security params",
Jeff Johnson295189b2012-06-20 16:38:30 -070014446 __func__);
14447 return status;
14448 }
Mohit Khanna765234a2012-09-11 15:08:35 -070014449 if ( req->channel )
14450 {
14451 status = wlan_hdd_cfg80211_connect_start(pAdapter, req->ssid,
14452 req->ssid_len, req->bssid,
Hanumantha Reddy Pothula64081b72015-09-11 15:47:32 +053014453 req->bssid_hint,
Mohit Khanna765234a2012-09-11 15:08:35 -070014454 req->channel->hw_value);
14455 }
14456 else
14457 {
14458 status = wlan_hdd_cfg80211_connect_start(pAdapter, req->ssid,
Hanumantha Reddy Pothula64081b72015-09-11 15:47:32 +053014459 req->ssid_len, req->bssid,
14460 req->bssid_hint, 0);
Mohit Khanna765234a2012-09-11 15:08:35 -070014461 }
Jeff Johnson295189b2012-06-20 16:38:30 -070014462
Sushant Kaushikd7083982015-03-18 14:33:24 +053014463 if (0 != status)
Jeff Johnson295189b2012-06-20 16:38:30 -070014464 {
14465 //ReEnable BMPS if disabled
14466 if((VOS_STATUS_SUCCESS == exitbmpsStatus) &&
14467 (NULL != pHddCtx))
14468 {
Gopichand Nakkalaa2fe5b02013-06-06 16:32:28 +053014469 if (pHddCtx->hdd_wlan_suspended)
14470 {
14471 hdd_set_pwrparams(pHddCtx);
14472 }
Jeff Johnson295189b2012-06-20 16:38:30 -070014473 //ReEnable Bmps and Imps back
14474 hdd_enable_bmps_imps(pHddCtx);
14475 }
Agarwal Ashish51325b52014-06-16 16:50:49 +053014476 hddLog(VOS_TRACE_LEVEL_ERROR, FL("connect failed"));
Jeff Johnson295189b2012-06-20 16:38:30 -070014477 return status;
14478 }
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053014479 pHddCtx->isAmpAllowed = VOS_FALSE;
Jeff Johnson295189b2012-06-20 16:38:30 -070014480 EXIT();
14481 return status;
14482}
14483
Mahesh A Saptasagarfafb7fe2014-05-16 13:19:37 +053014484static int wlan_hdd_cfg80211_connect( struct wiphy *wiphy,
14485 struct net_device *ndev,
14486 struct cfg80211_connect_params *req)
14487{
14488 int ret;
14489 vos_ssr_protect(__func__);
14490 ret = __wlan_hdd_cfg80211_connect(wiphy, ndev, req);
14491 vos_ssr_unprotect(__func__);
14492
14493 return ret;
14494}
Jeff Johnson295189b2012-06-20 16:38:30 -070014495
14496/*
Gopichand Nakkala78a6c812013-05-13 16:39:49 +053014497 * FUNCTION: wlan_hdd_disconnect
14498 * This function is used to issue a disconnect request to SME
14499 */
14500int wlan_hdd_disconnect( hdd_adapter_t *pAdapter, u16 reason )
14501{
Abhishek Singh6ab864d2014-11-27 12:10:10 +053014502 int status, result = 0;
Gopichand Nakkala78a6c812013-05-13 16:39:49 +053014503 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053014504 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Abhishek Singhdc2bfd42014-06-19 17:59:05 +053014505 long ret;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053014506
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053014507 ENTER();
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053014508
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053014509 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053014510 if (0 != status)
14511 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053014512 return status;
14513 }
Abhishek Singh07e4a892015-11-23 11:29:57 +053014514 /* Indicate sme of disconnect so that in progress connection or preauth
14515 * can be aborted
14516 */
14517 sme_abortConnection(WLAN_HDD_GET_HAL_CTX(pAdapter),
Sushant Kaushikb4834d22015-07-15 15:29:05 +053014518 pAdapter->sessionId);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053014519 pHddCtx->isAmpAllowed = VOS_TRUE;
Agarwal Ashishc65b5ca2014-07-28 21:02:57 +053014520
Agarwal Ashish47d18112014-08-04 19:55:07 +053014521 /* Need to apply spin lock before decreasing active sessions
14522 * as there can be chance for double decrement if context switch
14523 * Calls hdd_DisConnectHandler.
14524 */
14525
14526 spin_lock_bh(&pAdapter->lock_for_active_session);
Agarwal Ashishc65b5ca2014-07-28 21:02:57 +053014527 if (eConnectionState_Associated == pHddStaCtx->conn_info.connState)
14528 {
Agarwal Ashishc65b5ca2014-07-28 21:02:57 +053014529 wlan_hdd_decr_active_session(pHddCtx, pAdapter->device_mode);
14530 }
Agarwal Ashish47d18112014-08-04 19:55:07 +053014531 hdd_connSetConnectionState( pHddStaCtx, eConnectionState_Disconnecting );
14532 spin_unlock_bh(&pAdapter->lock_for_active_session);
Agarwal Ashishc65b5ca2014-07-28 21:02:57 +053014533
Abhishek Singhf4669da2014-05-26 15:07:49 +053014534 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Agarwal Ashish47d18112014-08-04 19:55:07 +053014535 FL( "Set HDD connState to eConnectionState_Disconnecting" ));
14536
Gopichand Nakkala78a6c812013-05-13 16:39:49 +053014537 INIT_COMPLETION(pAdapter->disconnect_comp_var);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053014538
Mihir Shete182a0b22014-08-18 16:08:48 +053014539 /*
14540 * stop tx queues before deleting STA/BSS context from the firmware.
14541 * tx has to be disabled because the firmware can get busy dropping
14542 * the tx frames after BSS/STA has been deleted and will not send
14543 * back a response resulting in WDI timeout
14544 */
Padma, Santhosh Kumar9dacb5c2014-12-17 19:22:56 +053014545 hddLog(VOS_TRACE_LEVEL_INFO, FL("Disabling queues"));
Mihir Shete182a0b22014-08-18 16:08:48 +053014546 netif_tx_disable(pAdapter->dev);
14547 netif_carrier_off(pAdapter->dev);
Arun Kumar Khandavalli94a2bb02013-12-28 19:17:25 +053014548
Mihir Shete182a0b22014-08-18 16:08:48 +053014549 /*issue disconnect*/
Gopichand Nakkala78a6c812013-05-13 16:39:49 +053014550 status = sme_RoamDisconnect( WLAN_HDD_GET_HAL_CTX(pAdapter),
14551 pAdapter->sessionId, reason);
Abhishek Singhdc2bfd42014-06-19 17:59:05 +053014552 if(eHAL_STATUS_CMD_NOT_QUEUED == status)
14553 {
14554 hddLog(VOS_TRACE_LEVEL_INFO,
14555 FL("status = %d, already disconnected"),
14556 (int)status );
Gopichand Nakkala78a6c812013-05-13 16:39:49 +053014557
Abhishek Singhdc2bfd42014-06-19 17:59:05 +053014558 }
14559 else if ( 0 != status )
Gopichand Nakkala78a6c812013-05-13 16:39:49 +053014560 {
14561 hddLog(VOS_TRACE_LEVEL_ERROR,
Arif Hussain6d2a3322013-11-17 19:50:10 -080014562 "%s csrRoamDisconnect failure, returned %d",
Gopichand Nakkala78a6c812013-05-13 16:39:49 +053014563 __func__, (int)status );
Abhishek Singh6ab864d2014-11-27 12:10:10 +053014564 result = -EINVAL;
14565 goto disconnected;
Gopichand Nakkala78a6c812013-05-13 16:39:49 +053014566 }
Abhishek Singhdc2bfd42014-06-19 17:59:05 +053014567 ret = wait_for_completion_interruptible_timeout(
Gopichand Nakkala78a6c812013-05-13 16:39:49 +053014568 &pAdapter->disconnect_comp_var,
14569 msecs_to_jiffies(WLAN_WAIT_TIME_DISCONNECT));
Abhishek Singhdc2bfd42014-06-19 17:59:05 +053014570 if (!ret && ( eHAL_STATUS_CMD_NOT_QUEUED != status ))
c_hpothu6ff1c3c2013-10-01 19:01:57 +053014571 {
14572 hddLog(VOS_TRACE_LEVEL_ERROR,
Mahesh A Saptasagar05a357e2014-02-26 16:28:06 +053014573 "%s: Failed to disconnect, timed out", __func__);
Abhishek Singh6ab864d2014-11-27 12:10:10 +053014574 result = -ETIMEDOUT;
Mahesh A Saptasagar05a357e2014-02-26 16:28:06 +053014575 }
Abhishek Singhdc2bfd42014-06-19 17:59:05 +053014576 else if (ret == -ERESTARTSYS)
Mahesh A Saptasagar05a357e2014-02-26 16:28:06 +053014577 {
14578 hddLog(VOS_TRACE_LEVEL_ERROR,
14579 "%s: Failed to disconnect, wait interrupted", __func__);
Abhishek Singh6ab864d2014-11-27 12:10:10 +053014580 result = -ERESTARTSYS;
c_hpothu6ff1c3c2013-10-01 19:01:57 +053014581 }
Abhishek Singh6ab864d2014-11-27 12:10:10 +053014582disconnected:
Abhishek Singhdc2bfd42014-06-19 17:59:05 +053014583 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
14584 FL("Set HDD connState to eConnectionState_NotConnected"));
14585 pHddStaCtx->conn_info.connState = eConnectionState_NotConnected;
14586
Abhishek Singh087de602015-10-21 17:18:55 +053014587#if LINUX_VERSION_CODE >= KERNEL_VERSION(3, 11, 0)
14588 /* Sending disconnect event to userspace for kernel version < 3.11
14589 * is handled by __cfg80211_disconnect call to __cfg80211_disconnected
14590 */
14591 hddLog(LOG1, FL("Send disconnected event to userspace"));
14592 cfg80211_disconnected(pAdapter->dev, WLAN_REASON_UNSPECIFIED,
14593 NULL, 0, GFP_KERNEL);
14594#endif
14595
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053014596 EXIT();
Abhishek Singh6ab864d2014-11-27 12:10:10 +053014597 return result;
Gopichand Nakkala78a6c812013-05-13 16:39:49 +053014598}
14599
14600
14601/*
Mahesh A Saptasagarfafb7fe2014-05-16 13:19:37 +053014602 * FUNCTION: __wlan_hdd_cfg80211_disconnect
Jeff Johnson295189b2012-06-20 16:38:30 -070014603 * This function is used to issue a disconnect request to SME
14604 */
Mahesh A Saptasagarfafb7fe2014-05-16 13:19:37 +053014605static int __wlan_hdd_cfg80211_disconnect( struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -070014606 struct net_device *dev,
14607 u16 reason
14608 )
14609{
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014610 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( dev );
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053014611 int status;
Chandrasekaran, Manishekar41b8e1f2015-03-10 13:30:28 +053014612 tCsrRoamProfile *pRoamProfile;
14613 hdd_station_ctx_t *pHddStaCtx;
14614 hdd_context_t *pHddCtx;
Gopichand Nakkalaaa353782013-05-17 20:36:22 +053014615#ifdef FEATURE_WLAN_TDLS
Gopichand Nakkala2a0a1572013-02-10 21:39:16 -080014616 tANI_U8 staIdx;
14617#endif
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014618
Jeff Johnson295189b2012-06-20 16:38:30 -070014619 ENTER();
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053014620
Chandrasekaran, Manishekar41b8e1f2015-03-10 13:30:28 +053014621 if (!pAdapter) {
14622 hddLog(VOS_TRACE_LEVEL_ERROR, FL("HDD adpater is NULL"));
14623 return -EINVAL;
14624 }
14625
14626 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
14627 if (!pHddStaCtx) {
14628 hddLog(VOS_TRACE_LEVEL_ERROR, FL("HDD STA context is NULL"));
14629 return -EINVAL;
14630 }
14631
14632 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
14633 status = wlan_hdd_validate_context(pHddCtx);
14634 if (0 != status)
14635 {
14636 return status;
14637 }
14638
14639 pRoamProfile = &(WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter))->roamProfile;
14640
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053014641 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
14642 TRACE_CODE_HDD_CFG80211_DISCONNECT,
14643 pAdapter->sessionId, reason));
Sushant Kaushik8bc7df22014-04-09 17:55:29 +053014644 hddLog(VOS_TRACE_LEVEL_INFO, "%s: device_mode = %s(%d)",
14645 __func__, hdd_device_modetoString(pAdapter->device_mode),
14646 pAdapter->device_mode);
Jeff Johnson295189b2012-06-20 16:38:30 -070014647
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014648 hddLog(VOS_TRACE_LEVEL_INFO, "%s: Disconnect called with reason code %d",
14649 __func__, reason);
Jeff Johnson295189b2012-06-20 16:38:30 -070014650
Jeff Johnson295189b2012-06-20 16:38:30 -070014651 if (NULL != pRoamProfile)
14652 {
14653 /*issue disconnect request to SME, if station is in connected state*/
Mahesh A Saptasagar280fd5a2013-12-05 15:38:31 +053014654 if ((pHddStaCtx->conn_info.connState == eConnectionState_Associated) ||
14655 (pHddStaCtx->conn_info.connState == eConnectionState_Connecting))
Jeff Johnson295189b2012-06-20 16:38:30 -070014656 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014657 eCsrRoamDisconnectReason reasonCode =
Jeff Johnson295189b2012-06-20 16:38:30 -070014658 eCSR_DISCONNECT_REASON_UNSPECIFIED;
Gopichand Nakkalaaa353782013-05-17 20:36:22 +053014659 hdd_scaninfo_t *pScanInfo;
Jeff Johnson295189b2012-06-20 16:38:30 -070014660 switch(reason)
14661 {
14662 case WLAN_REASON_MIC_FAILURE:
14663 reasonCode = eCSR_DISCONNECT_REASON_MIC_ERROR;
14664 break;
14665
14666 case WLAN_REASON_DISASSOC_DUE_TO_INACTIVITY:
14667 case WLAN_REASON_DISASSOC_AP_BUSY:
14668 case WLAN_REASON_CLASS3_FRAME_FROM_NONASSOC_STA:
14669 reasonCode = eCSR_DISCONNECT_REASON_DISASSOC;
14670 break;
14671
14672 case WLAN_REASON_PREV_AUTH_NOT_VALID:
14673 case WLAN_REASON_CLASS2_FRAME_FROM_NONAUTH_STA:
Abhishek Singhc3269a52014-05-21 17:22:24 +053014674 case WLAN_REASON_DEAUTH_LEAVING:
Jeff Johnson295189b2012-06-20 16:38:30 -070014675 reasonCode = eCSR_DISCONNECT_REASON_DEAUTH;
14676 break;
14677
Jeff Johnson295189b2012-06-20 16:38:30 -070014678 default:
14679 reasonCode = eCSR_DISCONNECT_REASON_UNSPECIFIED;
14680 break;
14681 }
Gopichand Nakkalaaa353782013-05-17 20:36:22 +053014682 pScanInfo = &pHddCtx->scan_info;
14683 if (pScanInfo->mScanPending)
14684 {
Srinivas, Dasari138af4f2014-02-07 11:13:45 +053014685 hddLog(VOS_TRACE_LEVEL_INFO, "Disconnect is in progress, "
Gopichand Nakkalaaa353782013-05-17 20:36:22 +053014686 "Aborting Scan");
Kaushik, Sushant4975a572014-10-21 16:07:48 +053014687 hdd_abort_mac_scan(pHddCtx, pScanInfo->sessionId,
Srinivas, Dasari138af4f2014-02-07 11:13:45 +053014688 eCSR_SCAN_ABORT_DEFAULT);
Gopichand Nakkalaaa353782013-05-17 20:36:22 +053014689 }
Agarwal Ashishc089cec2015-08-10 13:10:04 +053014690 wlan_hdd_cancel_existing_remain_on_channel(pAdapter);
Gopichand Nakkala2a0a1572013-02-10 21:39:16 -080014691#ifdef FEATURE_WLAN_TDLS
14692 /* First clean up the tdls peers if any */
Gopichand Nakkala4327a152013-03-04 23:22:42 -080014693 for (staIdx = 0 ; staIdx < HDD_MAX_NUM_TDLS_STA; staIdx++)
Gopichand Nakkala2a0a1572013-02-10 21:39:16 -080014694 {
Gopichand Nakkala4327a152013-03-04 23:22:42 -080014695 if ((pHddCtx->tdlsConnInfo[staIdx].sessionId == pAdapter->sessionId) &&
14696 (pHddCtx->tdlsConnInfo[staIdx].staId))
Gopichand Nakkala2a0a1572013-02-10 21:39:16 -080014697 {
Hoonki Lee11f7dda2013-02-14 16:55:44 -080014698 uint8 *mac;
Gopichand Nakkala4327a152013-03-04 23:22:42 -080014699 mac = pHddCtx->tdlsConnInfo[staIdx].peerMac.bytes;
Masti, Narayanraddi34e0e562015-03-05 18:23:03 +053014700 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Gopichand Nakkalac87400e2013-03-13 18:51:00 -070014701 "%s: call sme_DeleteTdlsPeerSta staId %d sessionId %d " MAC_ADDRESS_STR,
Gopichand Nakkala4327a152013-03-04 23:22:42 -080014702 __func__, pHddCtx->tdlsConnInfo[staIdx].staId, pAdapter->sessionId,
Gopichand Nakkalac87400e2013-03-13 18:51:00 -070014703 MAC_ADDR_ARRAY(mac));
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053014704 status = sme_DeleteTdlsPeerSta(
14705 WLAN_HDD_GET_HAL_CTX(pAdapter),
14706 pAdapter->sessionId,
14707 mac);
14708 if (status != eHAL_STATUS_SUCCESS) {
14709 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Failed to delete TDLS peer STA"));
14710 return -EPERM;
14711 }
Gopichand Nakkala2a0a1572013-02-10 21:39:16 -080014712 }
14713 }
14714#endif
Arun Kumar Khandavalli94a2bb02013-12-28 19:17:25 +053014715 hddLog(LOG1, FL("Disconnecting with reasoncode:%u"), reasonCode);
Gopichand Nakkala78a6c812013-05-13 16:39:49 +053014716 status = wlan_hdd_disconnect(pAdapter, reasonCode);
14717 if ( 0 != status )
Jeff Johnson295189b2012-06-20 16:38:30 -070014718 {
14719 hddLog(VOS_TRACE_LEVEL_ERROR,
Arif Hussain6d2a3322013-11-17 19:50:10 -080014720 "%s wlan_hdd_disconnect failure, returned %d",
Jeff Johnson295189b2012-06-20 16:38:30 -070014721 __func__, (int)status );
14722 return -EINVAL;
14723 }
Jeff Johnson295189b2012-06-20 16:38:30 -070014724 }
Mahesh A Saptasagar280fd5a2013-12-05 15:38:31 +053014725 else
14726 {
14727 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: unexpected cfg disconnect API"
14728 "called while in %d state", __func__,
14729 pHddStaCtx->conn_info.connState);
14730 }
Jeff Johnson295189b2012-06-20 16:38:30 -070014731 }
14732 else
14733 {
14734 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: No valid roam profile", __func__);
14735 }
14736
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053014737 EXIT();
Jeff Johnson295189b2012-06-20 16:38:30 -070014738 return status;
14739}
14740
Mahesh A Saptasagarfafb7fe2014-05-16 13:19:37 +053014741static int wlan_hdd_cfg80211_disconnect( struct wiphy *wiphy,
14742 struct net_device *dev,
14743 u16 reason
14744 )
14745{
14746 int ret;
14747 vos_ssr_protect(__func__);
14748 ret = __wlan_hdd_cfg80211_disconnect(wiphy, dev, reason);
14749 vos_ssr_unprotect(__func__);
14750
14751 return ret;
14752}
Gopichand Nakkala78a6c812013-05-13 16:39:49 +053014753
Jeff Johnson295189b2012-06-20 16:38:30 -070014754/*
14755 * FUNCTION: wlan_hdd_cfg80211_set_privacy_ibss
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014756 * This function is used to initialize the security
Jeff Johnson295189b2012-06-20 16:38:30 -070014757 * settings in IBSS mode.
14758 */
14759static int wlan_hdd_cfg80211_set_privacy_ibss(
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014760 hdd_adapter_t *pAdapter,
Jeff Johnson295189b2012-06-20 16:38:30 -070014761 struct cfg80211_ibss_params *params
14762 )
14763{
14764 int status = 0;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014765 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
Jeff Johnson295189b2012-06-20 16:38:30 -070014766 eCsrEncryptionType encryptionType = eCSR_ENCRYPT_TYPE_NONE;
14767 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014768
Jeff Johnson295189b2012-06-20 16:38:30 -070014769 ENTER();
14770
14771 pWextState->wpaVersion = IW_AUTH_WPA_VERSION_DISABLED;
Ravi Joshib58ca0d2013-10-29 09:50:23 -070014772 vos_mem_zero(&pHddStaCtx->ibss_enc_key, sizeof(tCsrRoamSetKey));
Jeff Johnson295189b2012-06-20 16:38:30 -070014773
14774 if (params->ie_len && ( NULL != params->ie) )
14775 {
Shailender Karmuchi67edd312013-06-18 16:30:48 -070014776 if (wlan_hdd_cfg80211_get_ie_ptr (params->ie,
14777 params->ie_len, WLAN_EID_RSN ))
Jeff Johnson295189b2012-06-20 16:38:30 -070014778 {
14779 pWextState->wpaVersion = IW_AUTH_WPA_VERSION_WPA2;
14780 encryptionType = eCSR_ENCRYPT_TYPE_AES;
14781 }
Shailender Karmuchi67edd312013-06-18 16:30:48 -070014782 else if ( hdd_isWPAIEPresent (params->ie, params->ie_len ))
Jeff Johnson295189b2012-06-20 16:38:30 -070014783 {
Shailender Karmuchi642e9812013-05-30 14:34:49 -070014784 tDot11fIEWPA dot11WPAIE;
14785 tHalHandle halHandle = WLAN_HDD_GET_HAL_CTX(pAdapter);
Shailender Karmuchi67edd312013-06-18 16:30:48 -070014786 u8 *ie;
Shailender Karmuchi642e9812013-05-30 14:34:49 -070014787
Wilson Yang00256342013-10-10 23:13:38 -070014788 memset(&dot11WPAIE, 0, sizeof(dot11WPAIE));
Shailender Karmuchi67edd312013-06-18 16:30:48 -070014789 ie = wlan_hdd_cfg80211_get_ie_ptr (params->ie,
14790 params->ie_len, DOT11F_EID_WPA);
14791 if ( NULL != ie )
14792 {
14793 pWextState->wpaVersion = IW_AUTH_WPA_VERSION_WPA;
14794 // Unpack the WPA IE
14795 //Skip past the EID byte and length byte - and four byte WiFi OUI
14796 dot11fUnpackIeWPA((tpAniSirGlobal) halHandle,
14797 &ie[2+4],
14798 ie[1] - 4,
14799 &dot11WPAIE);
14800 /*Extract the multicast cipher, the encType for unicast
14801 cipher for wpa-none is none*/
14802 encryptionType =
14803 hdd_TranslateWPAToCsrEncryptionType(dot11WPAIE.multicast_cipher);
14804 }
Jeff Johnson295189b2012-06-20 16:38:30 -070014805 }
Shailender Karmuchi67edd312013-06-18 16:30:48 -070014806
Jeff Johnson295189b2012-06-20 16:38:30 -070014807 status = wlan_hdd_cfg80211_set_ie(pAdapter, params->ie, params->ie_len);
14808
14809 if (0 > status)
14810 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014811 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: failed to parse WPA/RSN IE",
Jeff Johnson295189b2012-06-20 16:38:30 -070014812 __func__);
14813 return status;
14814 }
14815 }
14816
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014817 pWextState->roamProfile.AuthType.authType[0] =
14818 pHddStaCtx->conn_info.authType =
Jeff Johnson295189b2012-06-20 16:38:30 -070014819 eCSR_AUTH_TYPE_OPEN_SYSTEM;
14820
14821 if (params->privacy)
14822 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014823 /* Security enabled IBSS, At this time there is no information available
14824 * about the security paramters, so initialise the encryption type to
Jeff Johnson295189b2012-06-20 16:38:30 -070014825 * eCSR_ENCRYPT_TYPE_WEP40_STATICKEY.
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014826 * The correct security parameters will be updated later in
Jeff Johnson295189b2012-06-20 16:38:30 -070014827 * wlan_hdd_cfg80211_add_key */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014828 /* Hal expects encryption type to be set inorder
Jeff Johnson295189b2012-06-20 16:38:30 -070014829 *enable privacy bit in beacons */
14830
14831 encryptionType = eCSR_ENCRYPT_TYPE_WEP40_STATICKEY;
14832 }
Shailender Karmuchi642e9812013-05-30 14:34:49 -070014833 VOS_TRACE (VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO_HIGH,
14834 "encryptionType=%d", encryptionType);
Jeff Johnson295189b2012-06-20 16:38:30 -070014835 pHddStaCtx->conn_info.ucEncryptionType = encryptionType;
14836 pWextState->roamProfile.EncryptionType.numEntries = 1;
14837 pWextState->roamProfile.EncryptionType.encryptionType[0] = encryptionType;
Jeff Johnson295189b2012-06-20 16:38:30 -070014838 return status;
14839}
14840
14841/*
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053014842 * FUNCTION: __wlan_hdd_cfg80211_join_ibss
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014843 * This function is used to create/join an IBSS
Jeff Johnson295189b2012-06-20 16:38:30 -070014844 */
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053014845static int __wlan_hdd_cfg80211_join_ibss( struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -070014846 struct net_device *dev,
14847 struct cfg80211_ibss_params *params
14848 )
14849{
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014850 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( dev );
Jeff Johnson295189b2012-06-20 16:38:30 -070014851 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
14852 tCsrRoamProfile *pRoamProfile;
14853 int status;
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053014854 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
14855 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053014856 tSirMacAddr bssid;
Jeff Johnson295189b2012-06-20 16:38:30 -070014857
14858 ENTER();
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053014859
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053014860 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
14861 TRACE_CODE_HDD_CFG80211_JOIN_IBSS,
14862 pAdapter->sessionId, pAdapter->device_mode));
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014863 hddLog(VOS_TRACE_LEVEL_INFO,
Sushant Kaushik8bc7df22014-04-09 17:55:29 +053014864 "%s: device_mode = %s (%d)", __func__,
14865 hdd_device_modetoString(pAdapter->device_mode),
14866 pAdapter->device_mode);
Jeff Johnson295189b2012-06-20 16:38:30 -070014867
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053014868 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053014869 if (0 != status)
Jeff Johnson295189b2012-06-20 16:38:30 -070014870 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053014871 return status;
Jeff Johnson295189b2012-06-20 16:38:30 -070014872 }
14873
14874 if (NULL == pWextState)
14875 {
Arif Hussain6d2a3322013-11-17 19:50:10 -080014876 hddLog (VOS_TRACE_LEVEL_ERROR, "%s ERROR: Data Storage Corruption",
Jeff Johnson295189b2012-06-20 16:38:30 -070014877 __func__);
14878 return -EIO;
14879 }
14880
Agarwal Ashish51325b52014-06-16 16:50:49 +053014881 if (vos_max_concurrent_connections_reached()) {
14882 hddLog(VOS_TRACE_LEVEL_INFO, FL("Reached max concurrent connections"));
14883 return -ECONNREFUSED;
14884 }
14885
Vinay Krishna Eranna21042322014-01-08 19:21:39 +053014886 /*Try disconnecting if already in connected state*/
14887 status = wlan_hdd_try_disconnect(pAdapter);
14888 if ( 0 > status)
14889 {
14890 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Failed to disconnect the existing"
14891 " IBSS connection"));
14892 return -EALREADY;
14893 }
14894
Jeff Johnson295189b2012-06-20 16:38:30 -070014895 pRoamProfile = &pWextState->roamProfile;
14896
14897 if ( eCSR_BSS_TYPE_START_IBSS != pRoamProfile->BSSType )
14898 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014899 hddLog (VOS_TRACE_LEVEL_ERROR,
Arif Hussain6d2a3322013-11-17 19:50:10 -080014900 "%s Interface type is not set to IBSS", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -070014901 return -EINVAL;
14902 }
14903
Praveen Kumar Sirisillad123d142013-09-24 16:50:13 -070014904 /* BSSID is provided by upper layers hence no need to AUTO generate */
14905 if (NULL != params->bssid) {
14906 if (ccmCfgSetInt(pHddCtx->hHal, WNI_CFG_IBSS_AUTO_BSSID, 0,
14907 NULL, eANI_BOOLEAN_FALSE)==eHAL_STATUS_FAILURE) {
14908 hddLog (VOS_TRACE_LEVEL_ERROR,
14909 "%s:ccmCfgStInt faild for WNI_CFG_IBSS_AUTO_BSSID", __func__);
14910 return -EIO;
14911 }
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053014912 vos_mem_copy((v_U8_t *)bssid, (v_U8_t *)params->bssid, sizeof(bssid));
Praveen Kumar Sirisillad123d142013-09-24 16:50:13 -070014913 }
krunal sonie9002db2013-11-25 14:24:17 -080014914 else if(pHddCtx->cfg_ini->isCoalesingInIBSSAllowed == 0)
14915 {
14916 if (ccmCfgSetInt(pHddCtx->hHal, WNI_CFG_IBSS_AUTO_BSSID, 0,
14917 NULL, eANI_BOOLEAN_FALSE)==eHAL_STATUS_FAILURE)
14918 {
14919 hddLog (VOS_TRACE_LEVEL_ERROR,
14920 "%s:ccmCfgStInt faild for WNI_CFG_IBSS_AUTO_BSSID", __func__);
14921 return -EIO;
14922 }
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053014923
14924 vos_mem_copy((v_U8_t *)bssid,
krunal sonie9002db2013-11-25 14:24:17 -080014925 (v_U8_t *)&pHddCtx->cfg_ini->IbssBssid.bytes[0],
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053014926 sizeof(bssid));
krunal sonie9002db2013-11-25 14:24:17 -080014927 }
Praveen Kumar Sirisillad123d142013-09-24 16:50:13 -070014928
Jeff Johnson295189b2012-06-20 16:38:30 -070014929 /* Set Channel */
Yue Maf49ba872013-08-19 12:04:25 -070014930 if (NULL !=
14931#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,8,0))
14932 params->chandef.chan)
14933#else
14934 params->channel)
14935#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070014936 {
14937 u8 channelNum;
Shailender Karmuchi15cd0672013-05-15 19:50:04 -070014938 v_U32_t numChans = WNI_CFG_VALID_CHANNEL_LIST_LEN;
14939 v_U8_t validChan[WNI_CFG_VALID_CHANNEL_LIST_LEN];
14940 tHalHandle hHal = WLAN_HDD_GET_HAL_CTX(pAdapter);
14941 int indx;
Jeff Johnson295189b2012-06-20 16:38:30 -070014942
14943 /* Get channel number */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014944 channelNum =
Yue Maf49ba872013-08-19 12:04:25 -070014945 ieee80211_frequency_to_channel(
14946#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,8,0))
14947 params->chandef.chan->center_freq);
14948#else
14949 params->channel->center_freq);
14950#endif
Shailender Karmuchi15cd0672013-05-15 19:50:04 -070014951
14952 if (0 != ccmCfgGetStr(hHal, WNI_CFG_VALID_CHANNEL_LIST,
14953 validChan, &numChans))
Jeff Johnson295189b2012-06-20 16:38:30 -070014954 {
Shailender Karmuchi15cd0672013-05-15 19:50:04 -070014955 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: No valid channel list",
14956 __func__);
14957 return -EOPNOTSUPP;
Jeff Johnson295189b2012-06-20 16:38:30 -070014958 }
Shailender Karmuchi15cd0672013-05-15 19:50:04 -070014959
14960 for (indx = 0; indx < numChans; indx++)
Jeff Johnson295189b2012-06-20 16:38:30 -070014961 {
Shailender Karmuchi15cd0672013-05-15 19:50:04 -070014962 if (channelNum == validChan[indx])
14963 {
14964 break;
14965 }
14966 }
14967 if (indx >= numChans)
14968 {
14969 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Not valid Channel %d",
Jeff Johnson295189b2012-06-20 16:38:30 -070014970 __func__, channelNum);
14971 return -EINVAL;
14972 }
Shailender Karmuchi15cd0672013-05-15 19:50:04 -070014973 /* Set the Operational Channel */
14974 hddLog(VOS_TRACE_LEVEL_INFO_HIGH, "%s: set channel %d", __func__,
14975 channelNum);
14976 pRoamProfile->ChannelInfo.numOfChannels = 1;
14977 pHddStaCtx->conn_info.operationChannel = channelNum;
14978 pRoamProfile->ChannelInfo.ChannelList =
14979 &pHddStaCtx->conn_info.operationChannel;
Jeff Johnson295189b2012-06-20 16:38:30 -070014980 }
14981
14982 /* Initialize security parameters */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014983 status = wlan_hdd_cfg80211_set_privacy_ibss(pAdapter, params);
Jeff Johnson295189b2012-06-20 16:38:30 -070014984 if (status < 0)
14985 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014986 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: failed to set security parameters",
Jeff Johnson295189b2012-06-20 16:38:30 -070014987 __func__);
14988 return status;
14989 }
14990
14991 /* Issue connect start */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014992 status = wlan_hdd_cfg80211_connect_start(pAdapter, params->ssid,
Abhishek Singh4d924682015-11-17 15:23:06 +053014993 params->ssid_len, (const u8 *)&bssid, NULL,
Shailender Karmuchi15cd0672013-05-15 19:50:04 -070014994 pHddStaCtx->conn_info.operationChannel);
Jeff Johnson295189b2012-06-20 16:38:30 -070014995
14996 if (0 > status)
Jeff Johnson295189b2012-06-20 16:38:30 -070014997 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: connect failed", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -070014998
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053014999 EXIT();
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053015000 return status;
Jeff Johnson295189b2012-06-20 16:38:30 -070015001}
15002
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053015003static int wlan_hdd_cfg80211_join_ibss( struct wiphy *wiphy,
15004 struct net_device *dev,
15005 struct cfg80211_ibss_params *params
15006 )
15007{
15008 int ret = 0;
15009
15010 vos_ssr_protect(__func__);
15011 ret = __wlan_hdd_cfg80211_join_ibss(wiphy, dev, params);
15012 vos_ssr_unprotect(__func__);
15013
15014 return ret;
15015}
15016
Jeff Johnson295189b2012-06-20 16:38:30 -070015017/*
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053015018 * FUNCTION: __wlan_hdd_cfg80211_leave_ibss
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015019 * This function is used to leave an IBSS
Jeff Johnson295189b2012-06-20 16:38:30 -070015020 */
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053015021static int __wlan_hdd_cfg80211_leave_ibss( struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -070015022 struct net_device *dev
15023 )
15024{
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015025 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( dev );
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053015026 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
15027 tCsrRoamProfile *pRoamProfile;
15028 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053015029 int status;
Jeff Johnson295189b2012-06-20 16:38:30 -070015030
15031 ENTER();
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053015032
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053015033 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
15034 TRACE_CODE_HDD_CFG80211_LEAVE_IBSS,
15035 pAdapter->sessionId, eCSR_DISCONNECT_REASON_IBSS_LEAVE));
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053015036 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053015037 if (0 != status)
Jeff Johnson04dd8a82012-06-29 20:41:40 -070015038 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053015039 return status;
Jeff Johnson04dd8a82012-06-29 20:41:40 -070015040 }
15041
Sushant Kaushik8bc7df22014-04-09 17:55:29 +053015042 hddLog(VOS_TRACE_LEVEL_INFO, "%s: device_mode = %s (%d)", __func__,
15043 hdd_device_modetoString(pAdapter->device_mode),
15044 pAdapter->device_mode);
Jeff Johnson295189b2012-06-20 16:38:30 -070015045 if (NULL == pWextState)
15046 {
Arif Hussain6d2a3322013-11-17 19:50:10 -080015047 hddLog (VOS_TRACE_LEVEL_ERROR, "%s ERROR: Data Storage Corruption",
Jeff Johnson295189b2012-06-20 16:38:30 -070015048 __func__);
15049 return -EIO;
15050 }
15051
15052 pRoamProfile = &pWextState->roamProfile;
15053
15054 /* Issue disconnect only if interface type is set to IBSS */
15055 if (eCSR_BSS_TYPE_START_IBSS != pRoamProfile->BSSType)
15056 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015057 hddLog (VOS_TRACE_LEVEL_ERROR, "%s: BSS Type is not set to IBSS",
Jeff Johnson295189b2012-06-20 16:38:30 -070015058 __func__);
15059 return -EINVAL;
15060 }
15061
15062 /* Issue Disconnect request */
15063 INIT_COMPLETION(pAdapter->disconnect_comp_var);
15064 sme_RoamDisconnect( WLAN_HDD_GET_HAL_CTX(pAdapter), pAdapter->sessionId,
15065 eCSR_DISCONNECT_REASON_IBSS_LEAVE);
15066
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053015067 EXIT();
Jeff Johnson295189b2012-06-20 16:38:30 -070015068 return 0;
15069}
15070
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053015071static int wlan_hdd_cfg80211_leave_ibss( struct wiphy *wiphy,
15072 struct net_device *dev
15073 )
15074{
15075 int ret = 0;
15076
15077 vos_ssr_protect(__func__);
15078 ret = __wlan_hdd_cfg80211_leave_ibss(wiphy, dev);
15079 vos_ssr_unprotect(__func__);
15080
15081 return ret;
15082}
15083
Jeff Johnson295189b2012-06-20 16:38:30 -070015084/*
Mahesh A Saptasagar179d2252014-06-02 21:32:21 +053015085 * FUNCTION: __wlan_hdd_cfg80211_set_wiphy_params
Jeff Johnson295189b2012-06-20 16:38:30 -070015086 * This function is used to set the phy parameters
15087 * (RTS Threshold/FRAG Threshold/Retry Count etc ...)
15088 */
Mahesh A Saptasagar179d2252014-06-02 21:32:21 +053015089static int __wlan_hdd_cfg80211_set_wiphy_params(struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -070015090 u32 changed)
15091{
15092 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
15093 tHalHandle hHal = pHddCtx->hHal;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053015094 int status;
Jeff Johnson295189b2012-06-20 16:38:30 -070015095
15096 ENTER();
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053015097
15098 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053015099 TRACE_CODE_HDD_CFG80211_SET_WIPHY_PARAMS,
15100 NO_SESSION, wiphy->rts_threshold));
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053015101
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053015102 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053015103 if (0 != status)
Jeff Johnson04dd8a82012-06-29 20:41:40 -070015104 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053015105 return status;
Jeff Johnson04dd8a82012-06-29 20:41:40 -070015106 }
15107
Jeff Johnson295189b2012-06-20 16:38:30 -070015108 if (changed & WIPHY_PARAM_RTS_THRESHOLD)
15109 {
15110 u16 rts_threshold = (wiphy->rts_threshold == -1) ?
15111 WNI_CFG_RTS_THRESHOLD_STAMAX :
15112 wiphy->rts_threshold;
15113
15114 if ((WNI_CFG_RTS_THRESHOLD_STAMIN > rts_threshold) ||
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015115 (WNI_CFG_RTS_THRESHOLD_STAMAX < rts_threshold))
Jeff Johnson295189b2012-06-20 16:38:30 -070015116 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015117 hddLog(VOS_TRACE_LEVEL_ERROR,
15118 "%s: Invalid RTS Threshold value %hu",
Jeff Johnson295189b2012-06-20 16:38:30 -070015119 __func__, rts_threshold);
15120 return -EINVAL;
15121 }
15122
15123 if (0 != ccmCfgSetInt(hHal, WNI_CFG_RTS_THRESHOLD,
15124 rts_threshold, ccmCfgSetCallback,
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015125 eANI_BOOLEAN_TRUE))
Jeff Johnson295189b2012-06-20 16:38:30 -070015126 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015127 hddLog(VOS_TRACE_LEVEL_ERROR,
15128 "%s: ccmCfgSetInt failed for rts_threshold value %hu",
Jeff Johnson295189b2012-06-20 16:38:30 -070015129 __func__, rts_threshold);
15130 return -EIO;
15131 }
15132
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015133 hddLog(VOS_TRACE_LEVEL_INFO_MED, "%s: set rts threshold %hu", __func__,
Jeff Johnson295189b2012-06-20 16:38:30 -070015134 rts_threshold);
15135 }
15136
15137 if (changed & WIPHY_PARAM_FRAG_THRESHOLD)
15138 {
15139 u16 frag_threshold = (wiphy->frag_threshold == -1) ?
15140 WNI_CFG_FRAGMENTATION_THRESHOLD_STAMAX :
15141 wiphy->frag_threshold;
15142
15143 if ((WNI_CFG_FRAGMENTATION_THRESHOLD_STAMIN > frag_threshold)||
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015144 (WNI_CFG_FRAGMENTATION_THRESHOLD_STAMAX < frag_threshold) )
Jeff Johnson295189b2012-06-20 16:38:30 -070015145 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015146 hddLog(VOS_TRACE_LEVEL_ERROR,
15147 "%s: Invalid frag_threshold value %hu", __func__,
Jeff Johnson295189b2012-06-20 16:38:30 -070015148 frag_threshold);
15149 return -EINVAL;
15150 }
15151
15152 if (0 != ccmCfgSetInt(hHal, WNI_CFG_FRAGMENTATION_THRESHOLD,
15153 frag_threshold, ccmCfgSetCallback,
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015154 eANI_BOOLEAN_TRUE))
Jeff Johnson295189b2012-06-20 16:38:30 -070015155 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015156 hddLog(VOS_TRACE_LEVEL_ERROR,
15157 "%s: ccmCfgSetInt failed for frag_threshold value %hu",
Jeff Johnson295189b2012-06-20 16:38:30 -070015158 __func__, frag_threshold);
15159 return -EIO;
15160 }
15161
15162 hddLog(VOS_TRACE_LEVEL_INFO_MED, "%s: set frag threshold %hu", __func__,
15163 frag_threshold);
15164 }
15165
15166 if ((changed & WIPHY_PARAM_RETRY_SHORT)
15167 || (changed & WIPHY_PARAM_RETRY_LONG))
15168 {
15169 u8 retry_value = (changed & WIPHY_PARAM_RETRY_SHORT) ?
15170 wiphy->retry_short :
15171 wiphy->retry_long;
15172
15173 if ((WNI_CFG_LONG_RETRY_LIMIT_STAMIN > retry_value) ||
15174 (WNI_CFG_LONG_RETRY_LIMIT_STAMAX < retry_value))
15175 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015176 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Invalid Retry count %hu",
Jeff Johnson295189b2012-06-20 16:38:30 -070015177 __func__, retry_value);
15178 return -EINVAL;
15179 }
15180
15181 if (changed & WIPHY_PARAM_RETRY_SHORT)
15182 {
15183 if (0 != ccmCfgSetInt(hHal, WNI_CFG_LONG_RETRY_LIMIT,
15184 retry_value, ccmCfgSetCallback,
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015185 eANI_BOOLEAN_TRUE))
Jeff Johnson295189b2012-06-20 16:38:30 -070015186 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015187 hddLog(VOS_TRACE_LEVEL_ERROR,
15188 "%s: ccmCfgSetInt failed for long retry count %hu",
Jeff Johnson295189b2012-06-20 16:38:30 -070015189 __func__, retry_value);
15190 return -EIO;
15191 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015192 hddLog(VOS_TRACE_LEVEL_INFO_MED, "%s: set long retry count %hu",
Jeff Johnson295189b2012-06-20 16:38:30 -070015193 __func__, retry_value);
15194 }
15195 else if (changed & WIPHY_PARAM_RETRY_SHORT)
15196 {
15197 if (0 != ccmCfgSetInt(hHal, WNI_CFG_SHORT_RETRY_LIMIT,
15198 retry_value, ccmCfgSetCallback,
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015199 eANI_BOOLEAN_TRUE))
Jeff Johnson295189b2012-06-20 16:38:30 -070015200 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015201 hddLog(VOS_TRACE_LEVEL_ERROR,
15202 "%s: ccmCfgSetInt failed for short retry count %hu",
Jeff Johnson295189b2012-06-20 16:38:30 -070015203 __func__, retry_value);
15204 return -EIO;
15205 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015206 hddLog(VOS_TRACE_LEVEL_INFO_MED, "%s: set short retry count %hu",
Jeff Johnson295189b2012-06-20 16:38:30 -070015207 __func__, retry_value);
15208 }
15209 }
15210
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053015211 EXIT();
Jeff Johnson295189b2012-06-20 16:38:30 -070015212 return 0;
15213}
15214
Mahesh A Saptasagar179d2252014-06-02 21:32:21 +053015215static int wlan_hdd_cfg80211_set_wiphy_params(struct wiphy *wiphy,
15216 u32 changed)
15217{
15218 int ret;
15219
15220 vos_ssr_protect(__func__);
15221 ret = __wlan_hdd_cfg80211_set_wiphy_params(wiphy, changed);
15222 vos_ssr_unprotect(__func__);
15223
15224 return ret;
15225}
15226
Jeff Johnson295189b2012-06-20 16:38:30 -070015227/*
Mahesh A Saptasagar179d2252014-06-02 21:32:21 +053015228 * FUNCTION: __wlan_hdd_cfg80211_set_txpower
Jeff Johnson295189b2012-06-20 16:38:30 -070015229 * This function is used to set the txpower
15230 */
Mahesh A Saptasagar179d2252014-06-02 21:32:21 +053015231static int __wlan_hdd_cfg80211_set_txpower(struct wiphy *wiphy,
Yue Maf49ba872013-08-19 12:04:25 -070015232#if LINUX_VERSION_CODE >= KERNEL_VERSION(3,8,0)
15233 struct wireless_dev *wdev,
15234#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070015235#if LINUX_VERSION_CODE <= KERNEL_VERSION(2,6,35)
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015236 enum tx_power_setting type,
Jeff Johnson295189b2012-06-20 16:38:30 -070015237#else
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015238 enum nl80211_tx_power_setting type,
Jeff Johnson295189b2012-06-20 16:38:30 -070015239#endif
15240 int dbm)
15241{
15242 hdd_context_t *pHddCtx = (hdd_context_t*) wiphy_priv(wiphy);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053015243 tHalHandle hHal = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -070015244 tSirMacAddr bssid = {0xFF,0xFF,0xFF,0xFF,0xFF,0xFF};
15245 tSirMacAddr selfMac = {0xFF,0xFF,0xFF,0xFF,0xFF,0xFF};
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053015246 int status;
Jeff Johnson295189b2012-06-20 16:38:30 -070015247
15248 ENTER();
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053015249
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053015250 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
15251 TRACE_CODE_HDD_CFG80211_SET_TXPOWER,
15252 NO_SESSION, type ));
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053015253 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053015254 if (0 != status)
15255 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053015256 return status;
15257 }
15258
15259 hHal = pHddCtx->hHal;
15260
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015261 if (0 != ccmCfgSetInt(hHal, WNI_CFG_CURRENT_TX_POWER_LEVEL,
15262 dbm, ccmCfgSetCallback,
15263 eANI_BOOLEAN_TRUE))
Jeff Johnson295189b2012-06-20 16:38:30 -070015264 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015265 hddLog(VOS_TRACE_LEVEL_ERROR,
Jeff Johnson295189b2012-06-20 16:38:30 -070015266 "%s: ccmCfgSetInt failed for tx power %hu", __func__, dbm);
15267 return -EIO;
15268 }
15269
15270 hddLog(VOS_TRACE_LEVEL_INFO_MED, "%s: set tx power level %d dbm", __func__,
15271 dbm);
15272
15273 switch(type)
15274 {
15275 case NL80211_TX_POWER_AUTOMATIC: /*automatically determine transmit power*/
15276 /* Fall through */
15277 case NL80211_TX_POWER_LIMITED: /*limit TX power by the mBm parameter*/
15278 if( sme_SetMaxTxPower(hHal, bssid, selfMac, dbm) != eHAL_STATUS_SUCCESS )
15279 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015280 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Setting maximum tx power failed",
15281 __func__);
15282 return -EIO;
Jeff Johnson295189b2012-06-20 16:38:30 -070015283 }
15284 break;
15285 case NL80211_TX_POWER_FIXED: /*fix TX power to the mBm parameter*/
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015286 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: NL80211_TX_POWER_FIXED not supported",
Jeff Johnson295189b2012-06-20 16:38:30 -070015287 __func__);
15288 return -EOPNOTSUPP;
15289 break;
15290 default:
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015291 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Invalid power setting type %d",
15292 __func__, type);
Jeff Johnson295189b2012-06-20 16:38:30 -070015293 return -EIO;
15294 }
15295
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053015296 EXIT();
Jeff Johnson295189b2012-06-20 16:38:30 -070015297 return 0;
15298}
15299
Mahesh A Saptasagar179d2252014-06-02 21:32:21 +053015300static int wlan_hdd_cfg80211_set_txpower(struct wiphy *wiphy,
15301#if LINUX_VERSION_CODE >= KERNEL_VERSION(3,8,0)
15302 struct wireless_dev *wdev,
15303#endif
15304#if LINUX_VERSION_CODE <= KERNEL_VERSION(2,6,35)
15305 enum tx_power_setting type,
15306#else
15307 enum nl80211_tx_power_setting type,
15308#endif
15309 int dbm)
15310{
15311 int ret;
15312 vos_ssr_protect(__func__);
15313 ret = __wlan_hdd_cfg80211_set_txpower(wiphy,
15314#if LINUX_VERSION_CODE >= KERNEL_VERSION(3,8,0)
15315 wdev,
15316#endif
15317#if LINUX_VERSION_CODE <= KERNEL_VERSION(2,6,35)
15318 type,
15319#else
15320 type,
15321#endif
15322 dbm);
15323 vos_ssr_unprotect(__func__);
15324
15325 return ret;
15326}
15327
Jeff Johnson295189b2012-06-20 16:38:30 -070015328/*
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053015329 * FUNCTION: __wlan_hdd_cfg80211_get_txpower
Jeff Johnson295189b2012-06-20 16:38:30 -070015330 * This function is used to read the txpower
15331 */
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053015332static int __wlan_hdd_cfg80211_get_txpower(struct wiphy *wiphy,
Yue Maf49ba872013-08-19 12:04:25 -070015333#if LINUX_VERSION_CODE >= KERNEL_VERSION(3,8,0)
15334 struct wireless_dev *wdev,
15335#endif
15336 int *dbm)
Jeff Johnson295189b2012-06-20 16:38:30 -070015337{
15338
15339 hdd_adapter_t *pAdapter;
15340 hdd_context_t *pHddCtx = (hdd_context_t*) wiphy_priv(wiphy);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053015341 int status;
Jeff Johnson295189b2012-06-20 16:38:30 -070015342
Jeff Johnsone7245742012-09-05 17:12:55 -070015343 ENTER();
15344
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053015345 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053015346 if (0 != status)
Jeff Johnson04dd8a82012-06-29 20:41:40 -070015347 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053015348 *dbm = 0;
15349 return status;
Jeff Johnson04dd8a82012-06-29 20:41:40 -070015350 }
15351
Jeff Johnson295189b2012-06-20 16:38:30 -070015352 pAdapter = hdd_get_adapter(pHddCtx, WLAN_HDD_INFRA_STATION);
15353 if (NULL == pAdapter)
15354 {
15355 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: Not in station context " ,__func__);
15356 return -ENOENT;
15357 }
15358
Konamki, Sreelakshmi7b464be2015-07-14 12:17:01 +053015359 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
15360 TRACE_CODE_HDD_CFG80211_GET_TXPOWER,
15361 pAdapter->sessionId, pAdapter->device_mode));
Jeff Johnson295189b2012-06-20 16:38:30 -070015362 wlan_hdd_get_classAstats(pAdapter);
15363 *dbm = pAdapter->hdd_stats.ClassA_stat.max_pwr;
15364
Jeff Johnsone7245742012-09-05 17:12:55 -070015365 EXIT();
Jeff Johnson295189b2012-06-20 16:38:30 -070015366 return 0;
15367}
15368
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053015369static int wlan_hdd_cfg80211_get_txpower(struct wiphy *wiphy,
15370#if LINUX_VERSION_CODE >= KERNEL_VERSION(3,8,0)
15371 struct wireless_dev *wdev,
15372#endif
15373 int *dbm)
15374{
15375 int ret;
15376
15377 vos_ssr_protect(__func__);
15378 ret = __wlan_hdd_cfg80211_get_txpower(wiphy,
15379#if LINUX_VERSION_CODE >= KERNEL_VERSION(3,8,0)
15380 wdev,
15381#endif
15382 dbm);
15383 vos_ssr_unprotect(__func__);
15384
15385 return ret;
15386}
15387
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053015388static int __wlan_hdd_cfg80211_get_station(struct wiphy *wiphy, struct net_device *dev,
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053015389#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,18,0))
15390 const u8* mac,
15391#else
15392 u8* mac,
15393#endif
15394 struct station_info *sinfo)
Jeff Johnson295189b2012-06-20 16:38:30 -070015395{
15396 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( dev );
15397 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
15398 int ssidlen = pHddStaCtx->conn_info.SSID.SSID.length;
c_hpothu44ff4e02014-05-08 00:13:57 +053015399 tANI_U32 rate_flags;
Jeff Johnson295189b2012-06-20 16:38:30 -070015400
15401 hdd_context_t *pHddCtx = (hdd_context_t*) wiphy_priv(wiphy);
15402 hdd_config_t *pCfg = pHddCtx->cfg_ini;
Jeff Johnson295189b2012-06-20 16:38:30 -070015403
15404 tANI_U8 OperationalRates[CSR_DOT11_SUPPORTED_RATES_MAX];
15405 tANI_U32 ORLeng = CSR_DOT11_SUPPORTED_RATES_MAX;
15406 tANI_U8 ExtendedRates[CSR_DOT11_EXTENDED_SUPPORTED_RATES_MAX];
15407 tANI_U32 ERLeng = CSR_DOT11_EXTENDED_SUPPORTED_RATES_MAX;
15408 tANI_U8 MCSRates[SIZE_OF_BASIC_MCS_SET];
15409 tANI_U32 MCSLeng = SIZE_OF_BASIC_MCS_SET;
15410 tANI_U16 maxRate = 0;
15411 tANI_U16 myRate;
15412 tANI_U16 currentRate = 0;
15413 tANI_U8 maxSpeedMCS = 0;
15414 tANI_U8 maxMCSIdx = 0;
15415 tANI_U8 rateFlag = 1;
c_hpothu79aab322014-07-14 21:11:01 +053015416 tANI_U8 i, j, rssidx, mode=0;
Madan Mohan Koyyalamudic75be962012-10-18 19:19:03 -070015417 tANI_U16 temp;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053015418 int status;
Jeff Johnson295189b2012-06-20 16:38:30 -070015419
Leo Chang6f8870f2013-03-26 18:11:36 -070015420#ifdef WLAN_FEATURE_11AC
15421 tANI_U32 vht_mcs_map;
15422 eDataRate11ACMaxMcs vhtMaxMcs;
15423#endif /* WLAN_FEATURE_11AC */
15424
Jeff Johnsone7245742012-09-05 17:12:55 -070015425 ENTER();
15426
Jeff Johnson295189b2012-06-20 16:38:30 -070015427 if ((eConnectionState_Associated != pHddStaCtx->conn_info.connState) ||
15428 (0 == ssidlen))
15429 {
15430 hddLog(VOS_TRACE_LEVEL_INFO, "%s: Not associated or"
15431 " Invalid ssidlen, %d", __func__, ssidlen);
15432 /*To keep GUI happy*/
15433 return 0;
15434 }
15435
Mukul Sharma811205f2014-07-09 21:07:30 +053015436 if (VOS_TRUE == pHddStaCtx->hdd_ReassocScenario)
15437 {
15438 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
15439 "%s: Roaming in progress, so unable to proceed this request", __func__);
15440 return 0;
15441 }
15442
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053015443 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053015444 if (0 != status)
Jeff Johnson04dd8a82012-06-29 20:41:40 -070015445 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053015446 return status;
Jeff Johnson04dd8a82012-06-29 20:41:40 -070015447 }
15448
Hanumantha Reddy Pothuladce66742015-08-25 18:08:44 +053015449 wlan_hdd_get_station_stats(pAdapter);
15450 rate_flags = pAdapter->hdd_stats.ClassA_stat.tx_rate_flags;
Jeff Johnson295189b2012-06-20 16:38:30 -070015451
Kiet Lam3b17fc82013-09-27 05:24:08 +053015452 wlan_hdd_get_rssi(pAdapter, &sinfo->signal);
15453 sinfo->filled |= STATION_INFO_SIGNAL;
15454
c_hpothu09f19542014-05-30 21:53:31 +053015455 /*overwrite rate_flags if MAX link-speed need to be reported*/
c_hpothu44ff4e02014-05-08 00:13:57 +053015456 if ((eHDD_LINK_SPEED_REPORT_MAX == pCfg->reportMaxLinkSpeed) ||
15457 (eHDD_LINK_SPEED_REPORT_MAX_SCALED == pCfg->reportMaxLinkSpeed &&
c_hpothu79aab322014-07-14 21:11:01 +053015458 sinfo->signal >= pCfg->linkSpeedRssiLow))
c_hpothu44ff4e02014-05-08 00:13:57 +053015459 {
15460 rate_flags = pAdapter->maxRateFlags;
15461 }
c_hpothu44ff4e02014-05-08 00:13:57 +053015462
Jeff Johnson295189b2012-06-20 16:38:30 -070015463 //convert to the UI units of 100kbps
15464 myRate = pAdapter->hdd_stats.ClassA_stat.tx_rate * 5;
15465
15466#ifdef LINKSPEED_DEBUG_ENABLED
Leo Chang6f8870f2013-03-26 18:11:36 -070015467 pr_info("RSSI %d, RLMS %u, rate %d, rssi high %d, rssi mid %d, rssi low %d, rate_flags 0x%x, MCS %d\n",
Jeff Johnson295189b2012-06-20 16:38:30 -070015468 sinfo->signal,
15469 pCfg->reportMaxLinkSpeed,
15470 myRate,
15471 (int) pCfg->linkSpeedRssiHigh,
Madan Mohan Koyyalamudi8df78d52012-11-02 12:30:06 -070015472 (int) pCfg->linkSpeedRssiMid,
15473 (int) pCfg->linkSpeedRssiLow,
Leo Chang6f8870f2013-03-26 18:11:36 -070015474 (int) rate_flags,
15475 (int) pAdapter->hdd_stats.ClassA_stat.mcs_index);
Jeff Johnson295189b2012-06-20 16:38:30 -070015476#endif //LINKSPEED_DEBUG_ENABLED
15477
15478 if (eHDD_LINK_SPEED_REPORT_ACTUAL != pCfg->reportMaxLinkSpeed)
15479 {
15480 // we do not want to necessarily report the current speed
15481 if (eHDD_LINK_SPEED_REPORT_MAX == pCfg->reportMaxLinkSpeed)
15482 {
15483 // report the max possible speed
15484 rssidx = 0;
15485 }
15486 else if (eHDD_LINK_SPEED_REPORT_MAX_SCALED == pCfg->reportMaxLinkSpeed)
15487 {
15488 // report the max possible speed with RSSI scaling
15489 if (sinfo->signal >= pCfg->linkSpeedRssiHigh)
15490 {
15491 // report the max possible speed
15492 rssidx = 0;
15493 }
Madan Mohan Koyyalamudi8df78d52012-11-02 12:30:06 -070015494 else if (sinfo->signal >= pCfg->linkSpeedRssiMid)
Jeff Johnson295189b2012-06-20 16:38:30 -070015495 {
15496 // report middle speed
15497 rssidx = 1;
15498 }
Madan Mohan Koyyalamudi8df78d52012-11-02 12:30:06 -070015499 else if (sinfo->signal >= pCfg->linkSpeedRssiLow)
15500 {
15501 // report middle speed
15502 rssidx = 2;
15503 }
Jeff Johnson295189b2012-06-20 16:38:30 -070015504 else
15505 {
15506 // report actual speed
Madan Mohan Koyyalamudi8df78d52012-11-02 12:30:06 -070015507 rssidx = 3;
Jeff Johnson295189b2012-06-20 16:38:30 -070015508 }
15509 }
15510 else
15511 {
15512 // unknown, treat as eHDD_LINK_SPEED_REPORT_MAX
15513 hddLog(VOS_TRACE_LEVEL_ERROR,
15514 "%s: Invalid value for reportMaxLinkSpeed: %u",
15515 __func__, pCfg->reportMaxLinkSpeed);
15516 rssidx = 0;
15517 }
15518
15519 maxRate = 0;
15520
15521 /* Get Basic Rate Set */
Gopichand Nakkala05ab1322013-02-15 11:28:38 +053015522 if (0 != ccmCfgGetStr(WLAN_HDD_GET_HAL_CTX(pAdapter), WNI_CFG_OPERATIONAL_RATE_SET,
15523 OperationalRates, &ORLeng))
15524 {
15525 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: ccm api returned failure", __func__);
15526 /*To keep GUI happy*/
15527 return 0;
15528 }
15529
Jeff Johnson295189b2012-06-20 16:38:30 -070015530 for (i = 0; i < ORLeng; i++)
15531 {
Jeff Johnsone7245742012-09-05 17:12:55 -070015532 for (j = 0; j < (sizeof(supported_data_rate) / sizeof(supported_data_rate[0])); j ++)
Jeff Johnson295189b2012-06-20 16:38:30 -070015533 {
15534 /* Validate Rate Set */
15535 if (supported_data_rate[j].beacon_rate_index == (OperationalRates[i] & 0x7F))
15536 {
15537 currentRate = supported_data_rate[j].supported_rate[rssidx];
15538 break;
15539 }
15540 }
15541 /* Update MAX rate */
15542 maxRate = (currentRate > maxRate)?currentRate:maxRate;
15543 }
15544
15545 /* Get Extended Rate Set */
Gopichand Nakkala05ab1322013-02-15 11:28:38 +053015546 if (0 != ccmCfgGetStr(WLAN_HDD_GET_HAL_CTX(pAdapter), WNI_CFG_EXTENDED_OPERATIONAL_RATE_SET,
15547 ExtendedRates, &ERLeng))
15548 {
15549 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: ccm api returned failure", __func__);
15550 /*To keep GUI happy*/
15551 return 0;
15552 }
15553
Jeff Johnson295189b2012-06-20 16:38:30 -070015554 for (i = 0; i < ERLeng; i++)
15555 {
Jeff Johnsone7245742012-09-05 17:12:55 -070015556 for (j = 0; j < (sizeof(supported_data_rate) / sizeof(supported_data_rate[0])); j ++)
Jeff Johnson295189b2012-06-20 16:38:30 -070015557 {
15558 if (supported_data_rate[j].beacon_rate_index == (ExtendedRates[i] & 0x7F))
15559 {
15560 currentRate = supported_data_rate[j].supported_rate[rssidx];
15561 break;
15562 }
15563 }
15564 /* Update MAX rate */
15565 maxRate = (currentRate > maxRate)?currentRate:maxRate;
15566 }
c_hpothu79aab322014-07-14 21:11:01 +053015567
Kiet Lamb69f8dc2013-11-15 15:34:27 +053015568 /* Get MCS Rate Set --
Kaushik, Sushantdc304d82014-01-22 10:58:37 +053015569 Only if we are always reporting max speed (or)
Kiet Lamb69f8dc2013-11-15 15:34:27 +053015570 if we have good rssi */
c_hpothu79aab322014-07-14 21:11:01 +053015571 if ((3 != rssidx) && !(rate_flags & eHAL_TX_RATE_LEGACY))
Jeff Johnson295189b2012-06-20 16:38:30 -070015572 {
c_hpothu79aab322014-07-14 21:11:01 +053015573 if (rate_flags & eHAL_TX_RATE_VHT80)
15574 mode = 2;
15575 else if (rate_flags & (eHAL_TX_RATE_VHT40 | eHAL_TX_RATE_HT40))
15576 mode = 1;
15577 else
15578 mode = 0;
15579
Gopichand Nakkala05ab1322013-02-15 11:28:38 +053015580 if (0 != ccmCfgGetStr(WLAN_HDD_GET_HAL_CTX(pAdapter), WNI_CFG_CURRENT_MCS_SET,
15581 MCSRates, &MCSLeng))
15582 {
15583 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: ccm api returned failure", __func__);
15584 /*To keep GUI happy*/
15585 return 0;
15586 }
Jeff Johnson295189b2012-06-20 16:38:30 -070015587 rateFlag = 0;
Leo Chang6f8870f2013-03-26 18:11:36 -070015588#ifdef WLAN_FEATURE_11AC
15589 /* VHT80 rate has seperate rate table */
Gopichand Nakkala4c705372013-04-24 13:20:33 +053015590 if (rate_flags & (eHAL_TX_RATE_VHT20|eHAL_TX_RATE_VHT40|eHAL_TX_RATE_VHT80))
Jeff Johnson295189b2012-06-20 16:38:30 -070015591 {
Leo Chang6f8870f2013-03-26 18:11:36 -070015592 ccmCfgGetInt(WLAN_HDD_GET_HAL_CTX(pAdapter), WNI_CFG_VHT_TX_MCS_MAP, &vht_mcs_map);
Gopichand Nakkala4c705372013-04-24 13:20:33 +053015593 vhtMaxMcs = (eDataRate11ACMaxMcs)(vht_mcs_map & DATA_RATE_11AC_MCS_MASK );
Leo Chang6f8870f2013-03-26 18:11:36 -070015594 if (rate_flags & eHAL_TX_RATE_SGI)
Jeff Johnson295189b2012-06-20 16:38:30 -070015595 {
Leo Chang6f8870f2013-03-26 18:11:36 -070015596 rateFlag |= 1;
Jeff Johnson295189b2012-06-20 16:38:30 -070015597 }
Leo Chang6f8870f2013-03-26 18:11:36 -070015598 if (DATA_RATE_11AC_MAX_MCS_7 == vhtMaxMcs)
Jeff Johnson295189b2012-06-20 16:38:30 -070015599 {
Leo Chang6f8870f2013-03-26 18:11:36 -070015600 maxMCSIdx = 7;
15601 }
15602 else if (DATA_RATE_11AC_MAX_MCS_8 == vhtMaxMcs)
15603 {
15604 maxMCSIdx = 8;
15605 }
15606 else if (DATA_RATE_11AC_MAX_MCS_9 == vhtMaxMcs)
15607 {
Gopichand Nakkala4c705372013-04-24 13:20:33 +053015608 //VHT20 is supporting 0~8
15609 if (rate_flags & eHAL_TX_RATE_VHT20)
15610 maxMCSIdx = 8;
15611 else
15612 maxMCSIdx = 9;
Leo Chang6f8870f2013-03-26 18:11:36 -070015613 }
Gopichand Nakkala4c705372013-04-24 13:20:33 +053015614
c_hpothu79aab322014-07-14 21:11:01 +053015615 if (0 != rssidx)/*check for scaled */
15616 {
15617 //get middle rate MCS index if rssi=1/2
15618 for (i=0; i <= maxMCSIdx; i++)
15619 {
15620 if (sinfo->signal <= rssiMcsTbl[mode][i])
15621 {
15622 maxMCSIdx = i;
15623 break;
15624 }
15625 }
15626 }
15627
Gopichand Nakkala4c705372013-04-24 13:20:33 +053015628 if (rate_flags & eHAL_TX_RATE_VHT80)
15629 {
15630 currentRate = supported_vht_mcs_rate[pAdapter->hdd_stats.ClassA_stat.mcs_index].supported_VHT80_rate[rateFlag];
15631 maxRate = supported_vht_mcs_rate[maxMCSIdx].supported_VHT80_rate[rateFlag];
15632 }
15633 else if (rate_flags & eHAL_TX_RATE_VHT40)
15634 {
15635 currentRate = supported_vht_mcs_rate[pAdapter->hdd_stats.ClassA_stat.mcs_index].supported_VHT40_rate[rateFlag];
15636 maxRate = supported_vht_mcs_rate[maxMCSIdx].supported_VHT40_rate[rateFlag];
15637 }
15638 else if (rate_flags & eHAL_TX_RATE_VHT20)
15639 {
15640 currentRate = supported_vht_mcs_rate[pAdapter->hdd_stats.ClassA_stat.mcs_index].supported_VHT20_rate[rateFlag];
15641 maxRate = supported_vht_mcs_rate[maxMCSIdx].supported_VHT20_rate[rateFlag];
15642 }
15643
Leo Chang6f8870f2013-03-26 18:11:36 -070015644 maxSpeedMCS = 1;
15645 if (currentRate > maxRate)
15646 {
15647 maxRate = currentRate;
15648 }
Gopichand Nakkala4c705372013-04-24 13:20:33 +053015649
Leo Chang6f8870f2013-03-26 18:11:36 -070015650 }
15651 else
15652#endif /* WLAN_FEATURE_11AC */
15653 {
15654 if (rate_flags & eHAL_TX_RATE_HT40)
15655 {
15656 rateFlag |= 1;
15657 }
15658 if (rate_flags & eHAL_TX_RATE_SGI)
15659 {
15660 rateFlag |= 2;
15661 }
15662
Girish Gowli01abcee2014-07-31 20:18:55 +053015663 temp = sizeof(supported_mcs_rate) / sizeof(supported_mcs_rate[0]);
c_hpothu79aab322014-07-14 21:11:01 +053015664 if (rssidx == 1 || rssidx == 2)
15665 {
15666 //get middle rate MCS index if rssi=1/2
15667 for (i=0; i <= 7; i++)
15668 {
15669 if (sinfo->signal <= rssiMcsTbl[mode][i])
15670 {
15671 temp = i+1;
15672 break;
15673 }
15674 }
15675 }
c_hpothu79aab322014-07-14 21:11:01 +053015676
15677 for (i = 0; i < MCSLeng; i++)
15678 {
Leo Chang6f8870f2013-03-26 18:11:36 -070015679 for (j = 0; j < temp; j++)
15680 {
15681 if (supported_mcs_rate[j].beacon_rate_index == MCSRates[i])
15682 {
15683 currentRate = supported_mcs_rate[j].supported_rate[rateFlag];
Hanumantha Reddy Pothulafa623742015-06-16 14:08:24 +053015684 maxMCSIdx = supported_mcs_rate[j].beacon_rate_index;
Leo Chang6f8870f2013-03-26 18:11:36 -070015685 break;
15686 }
15687 }
15688 if ((j < temp) && (currentRate > maxRate))
15689 {
15690 maxRate = currentRate;
Leo Chang6f8870f2013-03-26 18:11:36 -070015691 }
Jeff Johnson295189b2012-06-20 16:38:30 -070015692 }
Hanumantha Reddy Pothulafa623742015-06-16 14:08:24 +053015693 maxSpeedMCS = 1;
Jeff Johnson295189b2012-06-20 16:38:30 -070015694 }
15695 }
15696
Gopichand Nakkala4c705372013-04-24 13:20:33 +053015697 else if (!(rate_flags & eHAL_TX_RATE_LEGACY))
15698 {
15699 maxRate = myRate;
15700 maxSpeedMCS = 1;
15701 maxMCSIdx = pAdapter->hdd_stats.ClassA_stat.mcs_index;
15702 }
Jeff Johnson295189b2012-06-20 16:38:30 -070015703 // make sure we report a value at least as big as our current rate
c_hpothu79aab322014-07-14 21:11:01 +053015704 if ((maxRate < myRate) || (0 == maxRate))
Jeff Johnson295189b2012-06-20 16:38:30 -070015705 {
15706 maxRate = myRate;
15707 if (rate_flags & eHAL_TX_RATE_LEGACY)
15708 {
15709 maxSpeedMCS = 0;
15710 }
15711 else
15712 {
15713 maxSpeedMCS = 1;
15714 maxMCSIdx = pAdapter->hdd_stats.ClassA_stat.mcs_index;
15715 }
15716 }
15717
Gopichand Nakkala4c705372013-04-24 13:20:33 +053015718 if (rate_flags & eHAL_TX_RATE_LEGACY)
Jeff Johnson295189b2012-06-20 16:38:30 -070015719 {
15720 sinfo->txrate.legacy = maxRate;
15721#ifdef LINKSPEED_DEBUG_ENABLED
15722 pr_info("Reporting legacy rate %d\n", sinfo->txrate.legacy);
15723#endif //LINKSPEED_DEBUG_ENABLED
15724 }
15725 else
15726 {
15727 sinfo->txrate.mcs = maxMCSIdx;
Leo Chang6f8870f2013-03-26 18:11:36 -070015728#ifdef WLAN_FEATURE_11AC
15729 sinfo->txrate.nss = 1;
15730 if (rate_flags & eHAL_TX_RATE_VHT80)
15731 {
15732 sinfo->txrate.flags |= RATE_INFO_FLAGS_VHT_MCS;
Gopichand Nakkala4c705372013-04-24 13:20:33 +053015733 sinfo->txrate.flags |= RATE_INFO_FLAGS_80_MHZ_WIDTH;
Leo Chang6f8870f2013-03-26 18:11:36 -070015734 }
Gopichand Nakkala4c705372013-04-24 13:20:33 +053015735 else if (rate_flags & eHAL_TX_RATE_VHT40)
Leo Chang6f8870f2013-03-26 18:11:36 -070015736 {
Gopichand Nakkala4c705372013-04-24 13:20:33 +053015737 sinfo->txrate.flags |= RATE_INFO_FLAGS_VHT_MCS;
15738 sinfo->txrate.flags |= RATE_INFO_FLAGS_40_MHZ_WIDTH;
15739 }
15740 else if (rate_flags & eHAL_TX_RATE_VHT20)
15741 {
15742 sinfo->txrate.flags |= RATE_INFO_FLAGS_VHT_MCS;
15743 }
15744#endif /* WLAN_FEATURE_11AC */
15745 if (rate_flags & (eHAL_TX_RATE_HT20 | eHAL_TX_RATE_HT40))
15746 {
15747 sinfo->txrate.flags |= RATE_INFO_FLAGS_MCS;
15748 if (rate_flags & eHAL_TX_RATE_HT40)
15749 {
15750 sinfo->txrate.flags |= RATE_INFO_FLAGS_40_MHZ_WIDTH;
15751 }
Leo Chang6f8870f2013-03-26 18:11:36 -070015752 }
Jeff Johnson295189b2012-06-20 16:38:30 -070015753 if (rate_flags & eHAL_TX_RATE_SGI)
15754 {
15755 sinfo->txrate.flags |= RATE_INFO_FLAGS_SHORT_GI;
15756 }
Gopichand Nakkala4c705372013-04-24 13:20:33 +053015757
Jeff Johnson295189b2012-06-20 16:38:30 -070015758#ifdef LINKSPEED_DEBUG_ENABLED
15759 pr_info("Reporting MCS rate %d flags %x\n",
15760 sinfo->txrate.mcs,
15761 sinfo->txrate.flags );
15762#endif //LINKSPEED_DEBUG_ENABLED
15763 }
15764 }
15765 else
15766 {
15767 // report current rate instead of max rate
15768
15769 if (rate_flags & eHAL_TX_RATE_LEGACY)
15770 {
15771 //provide to the UI in units of 100kbps
15772 sinfo->txrate.legacy = myRate;
15773#ifdef LINKSPEED_DEBUG_ENABLED
15774 pr_info("Reporting actual legacy rate %d\n", sinfo->txrate.legacy);
15775#endif //LINKSPEED_DEBUG_ENABLED
15776 }
15777 else
15778 {
15779 //must be MCS
15780 sinfo->txrate.mcs = pAdapter->hdd_stats.ClassA_stat.mcs_index;
Leo Chang6f8870f2013-03-26 18:11:36 -070015781#ifdef WLAN_FEATURE_11AC
15782 sinfo->txrate.nss = 1;
15783 if (rate_flags & eHAL_TX_RATE_VHT80)
15784 {
15785 sinfo->txrate.flags |= RATE_INFO_FLAGS_VHT_MCS;
15786 }
15787 else
15788#endif /* WLAN_FEATURE_11AC */
15789 {
15790 sinfo->txrate.flags |= RATE_INFO_FLAGS_MCS;
15791 }
Jeff Johnson295189b2012-06-20 16:38:30 -070015792 if (rate_flags & eHAL_TX_RATE_SGI)
15793 {
15794 sinfo->txrate.flags |= RATE_INFO_FLAGS_SHORT_GI;
15795 }
15796 if (rate_flags & eHAL_TX_RATE_HT40)
15797 {
15798 sinfo->txrate.flags |= RATE_INFO_FLAGS_40_MHZ_WIDTH;
15799 }
Leo Chang6f8870f2013-03-26 18:11:36 -070015800#ifdef WLAN_FEATURE_11AC
15801 else if (rate_flags & eHAL_TX_RATE_VHT80)
15802 {
15803 sinfo->txrate.flags |= RATE_INFO_FLAGS_80_MHZ_WIDTH;
15804 }
15805#endif /* WLAN_FEATURE_11AC */
Jeff Johnson295189b2012-06-20 16:38:30 -070015806#ifdef LINKSPEED_DEBUG_ENABLED
15807 pr_info("Reporting actual MCS rate %d flags %x\n",
15808 sinfo->txrate.mcs,
15809 sinfo->txrate.flags );
15810#endif //LINKSPEED_DEBUG_ENABLED
15811 }
15812 }
15813 sinfo->filled |= STATION_INFO_TX_BITRATE;
15814
Madan Mohan Koyyalamudi4d4d2812012-09-24 14:08:29 -070015815 sinfo->tx_packets =
15816 pAdapter->hdd_stats.summary_stat.tx_frm_cnt[0] +
15817 pAdapter->hdd_stats.summary_stat.tx_frm_cnt[1] +
15818 pAdapter->hdd_stats.summary_stat.tx_frm_cnt[2] +
15819 pAdapter->hdd_stats.summary_stat.tx_frm_cnt[3];
15820
15821 sinfo->tx_retries =
15822 pAdapter->hdd_stats.summary_stat.retry_cnt[0] +
15823 pAdapter->hdd_stats.summary_stat.retry_cnt[1] +
15824 pAdapter->hdd_stats.summary_stat.retry_cnt[2] +
15825 pAdapter->hdd_stats.summary_stat.retry_cnt[3];
15826
15827 sinfo->tx_failed =
15828 pAdapter->hdd_stats.summary_stat.fail_cnt[0] +
15829 pAdapter->hdd_stats.summary_stat.fail_cnt[1] +
15830 pAdapter->hdd_stats.summary_stat.fail_cnt[2] +
15831 pAdapter->hdd_stats.summary_stat.fail_cnt[3];
15832
15833 sinfo->filled |=
15834 STATION_INFO_TX_PACKETS |
15835 STATION_INFO_TX_RETRIES |
15836 STATION_INFO_TX_FAILED;
15837
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053015838 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
15839 TRACE_CODE_HDD_CFG80211_GET_STA,
15840 pAdapter->sessionId, maxRate));
Madan Mohan Koyyalamudi4d4d2812012-09-24 14:08:29 -070015841 EXIT();
15842 return 0;
Jeff Johnson295189b2012-06-20 16:38:30 -070015843}
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053015844#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,16,0))
15845static int wlan_hdd_cfg80211_get_station(struct wiphy *wiphy, struct net_device *dev,
15846 const u8* mac, struct station_info *sinfo)
15847#else
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053015848static int wlan_hdd_cfg80211_get_station(struct wiphy *wiphy, struct net_device *dev,
15849 u8* mac, struct station_info *sinfo)
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053015850#endif
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053015851{
15852 int ret;
15853
15854 vos_ssr_protect(__func__);
15855 ret = __wlan_hdd_cfg80211_get_station(wiphy, dev, mac, sinfo);
15856 vos_ssr_unprotect(__func__);
15857
15858 return ret;
15859}
15860
15861static int __wlan_hdd_cfg80211_set_power_mgmt(struct wiphy *wiphy,
Sameer Thalappilc9f26e92013-06-07 10:11:06 -070015862 struct net_device *dev, bool mode, int timeout)
Jeff Johnson295189b2012-06-20 16:38:30 -070015863{
15864 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
Gopichand Nakkala20c4c042013-04-19 22:08:55 +053015865 hdd_context_t *pHddCtx;
Jeff Johnson295189b2012-06-20 16:38:30 -070015866 VOS_STATUS vos_status;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053015867 int status;
Jeff Johnson295189b2012-06-20 16:38:30 -070015868
Jeff Johnsone7245742012-09-05 17:12:55 -070015869 ENTER();
15870
Jeff Johnson295189b2012-06-20 16:38:30 -070015871 if (NULL == pAdapter)
15872 {
Arif Hussain6d2a3322013-11-17 19:50:10 -080015873 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Adapter is NULL", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -070015874 return -ENODEV;
15875 }
15876
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053015877 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
15878 TRACE_CODE_HDD_CFG80211_SET_POWER_MGMT,
15879 pAdapter->sessionId, timeout));
15880
Gopichand Nakkala20c4c042013-04-19 22:08:55 +053015881 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053015882 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053015883 if (0 != status)
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015884 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053015885 return status;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015886 }
15887
Gopichand Nakkala20c4c042013-04-19 22:08:55 +053015888 if ((DRIVER_POWER_MODE_AUTO == !mode) &&
15889 (TRUE == pHddCtx->hdd_wlan_suspended) &&
15890 (pHddCtx->cfg_ini->fhostArpOffload) &&
15891 (eConnectionState_Associated ==
15892 (WLAN_HDD_GET_STATION_CTX_PTR(pAdapter))->conn_info.connState))
15893 {
Amar Singhald53568e2013-09-26 11:03:45 -070015894
15895 hddLog(VOS_TRACE_LEVEL_INFO,
15896 "offload: in cfg80211_set_power_mgmt, calling arp offload");
Gopichand Nakkalab03e8082013-05-30 18:09:25 +053015897 vos_status = hdd_conf_arp_offload(pAdapter, TRUE);
Gopichand Nakkala20c4c042013-04-19 22:08:55 +053015898 if (!VOS_IS_STATUS_SUCCESS(vos_status))
15899 {
15900 hddLog(VOS_TRACE_LEVEL_INFO,
Arif Hussain6d2a3322013-11-17 19:50:10 -080015901 "%s:Failed to enable ARPOFFLOAD Feature %d",
Gopichand Nakkala20c4c042013-04-19 22:08:55 +053015902 __func__, vos_status);
15903 }
15904 }
15905
Jeff Johnson295189b2012-06-20 16:38:30 -070015906 /**The get power cmd from the supplicant gets updated by the nl only
15907 *on successful execution of the function call
15908 *we are oppositely mapped w.r.t mode in the driver
15909 **/
15910 vos_status = wlan_hdd_enter_bmps(pAdapter, !mode);
15911
15912 if (VOS_STATUS_E_FAILURE == vos_status)
15913 {
c_hpothu6ff1c3c2013-10-01 19:01:57 +053015914 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
15915 "%s: failed to enter bmps mode", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -070015916 return -EINVAL;
15917 }
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053015918 EXIT();
Jeff Johnson295189b2012-06-20 16:38:30 -070015919 return 0;
15920}
15921
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053015922static int wlan_hdd_cfg80211_set_power_mgmt(struct wiphy *wiphy,
15923 struct net_device *dev, bool mode, int timeout)
15924{
15925 int ret;
Jeff Johnson295189b2012-06-20 16:38:30 -070015926
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053015927 vos_ssr_protect(__func__);
15928 ret = __wlan_hdd_cfg80211_set_power_mgmt(wiphy, dev, mode, timeout);
15929 vos_ssr_unprotect(__func__);
15930
15931 return ret;
15932}
Sushant Kaushik084f6592015-09-10 13:11:56 +053015933
Jeff Johnson295189b2012-06-20 16:38:30 -070015934#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053015935static int __wlan_hdd_set_default_mgmt_key(struct wiphy *wiphy,
15936 struct net_device *netdev,
15937 u8 key_index)
15938{
15939 ENTER();
15940 return 0;
15941}
15942
Jeff Johnson295189b2012-06-20 16:38:30 -070015943static int wlan_hdd_set_default_mgmt_key(struct wiphy *wiphy,
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053015944 struct net_device *netdev,
15945 u8 key_index)
15946{
15947 int ret;
15948 vos_ssr_protect(__func__);
15949 ret = __wlan_hdd_set_default_mgmt_key(wiphy, netdev, key_index);
15950 vos_ssr_unprotect(__func__);
15951 return ret;
15952}
15953#endif //LINUX_VERSION_CODE
15954
15955#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,4,0))
15956static int __wlan_hdd_set_txq_params(struct wiphy *wiphy,
15957 struct net_device *dev,
15958 struct ieee80211_txq_params *params)
15959{
15960 ENTER();
15961 return 0;
15962}
15963#elif (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
15964static int __wlan_hdd_set_txq_params(struct wiphy *wiphy,
15965 struct ieee80211_txq_params *params)
Jeff Johnson295189b2012-06-20 16:38:30 -070015966{
Jeff Johnsone7245742012-09-05 17:12:55 -070015967 ENTER();
Jeff Johnson295189b2012-06-20 16:38:30 -070015968 return 0;
15969}
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015970#endif //LINUX_VERSION_CODE
Jeff Johnson295189b2012-06-20 16:38:30 -070015971
15972#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,4,0))
15973static int wlan_hdd_set_txq_params(struct wiphy *wiphy,
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053015974 struct net_device *dev,
15975 struct ieee80211_txq_params *params)
Jeff Johnson295189b2012-06-20 16:38:30 -070015976{
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053015977 int ret;
15978
15979 vos_ssr_protect(__func__);
15980 ret = __wlan_hdd_set_txq_params(wiphy, dev, params);
15981 vos_ssr_unprotect(__func__);
15982 return ret;
Jeff Johnson295189b2012-06-20 16:38:30 -070015983}
15984#elif (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
15985static int wlan_hdd_set_txq_params(struct wiphy *wiphy,
15986 struct ieee80211_txq_params *params)
15987{
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053015988 int ret;
15989
15990 vos_ssr_protect(__func__);
15991 ret = __wlan_hdd_set_txq_params(wiphy, params);
15992 vos_ssr_unprotect(__func__);
15993 return ret;
Jeff Johnson295189b2012-06-20 16:38:30 -070015994}
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053015995#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070015996
Naresh Jayaram69e3f282014-10-14 12:29:12 +053015997static int __wlan_hdd_cfg80211_del_station(struct wiphy *wiphy,
Hanumantha Reddy Pothulabfd06f72014-10-31 14:03:37 +053015998 struct net_device *dev,
15999 struct tagCsrDelStaParams *pDelStaParams)
Jeff Johnson295189b2012-06-20 16:38:30 -070016000{
16001 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053016002 hdd_context_t *pHddCtx;
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -080016003 VOS_STATUS vos_status;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053016004 int status;
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -080016005 v_U8_t staId;
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +053016006 v_CONTEXT_t pVosContext = NULL;
16007 ptSapContext pSapCtx = NULL;
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053016008
Jeff Johnsone7245742012-09-05 17:12:55 -070016009 ENTER();
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053016010
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053016011 if ( NULL == pAdapter )
Jeff Johnson295189b2012-06-20 16:38:30 -070016012 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053016013 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Invalid Adapter" ,__func__);
Jeff Johnson295189b2012-06-20 16:38:30 -070016014 return -EINVAL;
16015 }
16016
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053016017 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
16018 TRACE_CODE_HDD_CFG80211_DEL_STA,
16019 pAdapter->sessionId, pAdapter->device_mode));
16020
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053016021 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
16022 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053016023 if (0 != status)
Jeff Johnson04dd8a82012-06-29 20:41:40 -070016024 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053016025 return status;
Jeff Johnson04dd8a82012-06-29 20:41:40 -070016026 }
16027
Jeff Johnson295189b2012-06-20 16:38:30 -070016028 if ( (WLAN_HDD_SOFTAP == pAdapter->device_mode)
Jeff Johnson295189b2012-06-20 16:38:30 -070016029 || (WLAN_HDD_P2P_GO == pAdapter->device_mode)
Jeff Johnson295189b2012-06-20 16:38:30 -070016030 )
16031 {
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +053016032 pVosContext = ( WLAN_HDD_GET_CTX(pAdapter))->pvosContext;
16033 pSapCtx = VOS_GET_SAP_CB(pVosContext);
16034 if(pSapCtx == NULL){
16035 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
16036 FL("psapCtx is NULL"));
16037 return -ENOENT;
16038 }
Hanumantha Reddy Pothulabfd06f72014-10-31 14:03:37 +053016039 if (vos_is_macaddr_broadcast((v_MACADDR_t *)pDelStaParams->peerMacAddr))
Jeff Johnson295189b2012-06-20 16:38:30 -070016040 {
16041 v_U16_t i;
16042 for(i = 0; i < WLAN_MAX_STA_COUNT; i++)
16043 {
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +053016044 if ((pSapCtx->aStaInfo[i].isUsed) &&
16045 (!pSapCtx->aStaInfo[i].isDeauthInProgress))
Jeff Johnson295189b2012-06-20 16:38:30 -070016046 {
Hanumantha Reddy Pothulabfd06f72014-10-31 14:03:37 +053016047 vos_mem_copy(pDelStaParams->peerMacAddr,
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +053016048 pSapCtx->aStaInfo[i].macAddrSTA.bytes,
Hanumantha Reddy Pothulabfd06f72014-10-31 14:03:37 +053016049 ETHER_ADDR_LEN);
16050
Jeff Johnson295189b2012-06-20 16:38:30 -070016051 hddLog(VOS_TRACE_LEVEL_INFO,
Arif Hussain24bafea2013-11-15 15:10:03 -080016052 "%s: Delete STA with MAC::"
16053 MAC_ADDRESS_STR,
Hanumantha Reddy Pothulabfd06f72014-10-31 14:03:37 +053016054 __func__,
16055 MAC_ADDR_ARRAY(pDelStaParams->peerMacAddr));
16056 vos_status = hdd_softap_sta_deauth(pAdapter, pDelStaParams);
Rajesh Chauhan18488fc2013-08-22 10:15:03 -070016057 if (VOS_IS_STATUS_SUCCESS(vos_status))
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +053016058 pSapCtx->aStaInfo[i].isDeauthInProgress = TRUE;
Jeff Johnson295189b2012-06-20 16:38:30 -070016059 }
16060 }
16061 }
16062 else
16063 {
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -080016064
Hanumantha Reddy Pothulabfd06f72014-10-31 14:03:37 +053016065 vos_status = hdd_softap_GetStaId(pAdapter,
16066 (v_MACADDR_t *)pDelStaParams->peerMacAddr, &staId);
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -080016067 if (!VOS_IS_STATUS_SUCCESS(vos_status))
16068 {
16069 hddLog(VOS_TRACE_LEVEL_INFO,
Arif Hussain24bafea2013-11-15 15:10:03 -080016070 "%s: Skip this DEL STA as this is not used::"
16071 MAC_ADDRESS_STR,
Hanumantha Reddy Pothulabfd06f72014-10-31 14:03:37 +053016072 __func__, MAC_ADDR_ARRAY(pDelStaParams->peerMacAddr));
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -080016073 return -ENOENT;
16074 }
16075
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +053016076 if( pSapCtx->aStaInfo[staId].isDeauthInProgress == TRUE)
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -080016077 {
16078 hddLog(VOS_TRACE_LEVEL_INFO,
Arif Hussain24bafea2013-11-15 15:10:03 -080016079 "%s: Skip this DEL STA as deauth is in progress::"
16080 MAC_ADDRESS_STR,
Hanumantha Reddy Pothulabfd06f72014-10-31 14:03:37 +053016081 __func__, MAC_ADDR_ARRAY(pDelStaParams->peerMacAddr));
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -080016082 return -ENOENT;
16083 }
16084
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +053016085 pSapCtx->aStaInfo[staId].isDeauthInProgress = TRUE;
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -080016086
Jeff Johnson295189b2012-06-20 16:38:30 -070016087 hddLog(VOS_TRACE_LEVEL_INFO,
16088 "%s: Delete STA with MAC::"
Arif Hussain24bafea2013-11-15 15:10:03 -080016089 MAC_ADDRESS_STR,
Jeff Johnson295189b2012-06-20 16:38:30 -070016090 __func__,
Hanumantha Reddy Pothulabfd06f72014-10-31 14:03:37 +053016091 MAC_ADDR_ARRAY(pDelStaParams->peerMacAddr));
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -080016092
Hanumantha Reddy Pothulabfd06f72014-10-31 14:03:37 +053016093 vos_status = hdd_softap_sta_deauth(pAdapter, pDelStaParams);
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -080016094 if (!VOS_IS_STATUS_SUCCESS(vos_status))
16095 {
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +053016096 pSapCtx->aStaInfo[staId].isDeauthInProgress = FALSE;
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -080016097 hddLog(VOS_TRACE_LEVEL_INFO,
16098 "%s: STA removal failed for ::"
Arif Hussain24bafea2013-11-15 15:10:03 -080016099 MAC_ADDRESS_STR,
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -080016100 __func__,
Hanumantha Reddy Pothulabfd06f72014-10-31 14:03:37 +053016101 MAC_ADDR_ARRAY(pDelStaParams->peerMacAddr));
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -080016102 return -ENOENT;
16103 }
16104
Jeff Johnson295189b2012-06-20 16:38:30 -070016105 }
16106 }
16107
16108 EXIT();
16109
16110 return 0;
16111}
Naresh Jayaram69e3f282014-10-14 12:29:12 +053016112
16113#ifdef CFG80211_DEL_STA_V2
16114static int wlan_hdd_cfg80211_del_station(struct wiphy *wiphy,
16115 struct net_device *dev,
16116 struct station_del_parameters *param)
16117#else
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053016118#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,16,0))
16119static int wlan_hdd_cfg80211_del_station(struct wiphy *wiphy,
16120 struct net_device *dev, const u8 *mac)
16121#else
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053016122static int wlan_hdd_cfg80211_del_station(struct wiphy *wiphy,
16123 struct net_device *dev, u8 *mac)
Naresh Jayaram69e3f282014-10-14 12:29:12 +053016124#endif
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053016125#endif
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053016126{
16127 int ret;
Hanumantha Reddy Pothulabfd06f72014-10-31 14:03:37 +053016128 struct tagCsrDelStaParams delStaParams;
Jeff Johnson295189b2012-06-20 16:38:30 -070016129
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053016130 vos_ssr_protect(__func__);
Hanumantha Reddy Pothulabfd06f72014-10-31 14:03:37 +053016131
Naresh Jayaram69e3f282014-10-14 12:29:12 +053016132#ifdef CFG80211_DEL_STA_V2
Hanumantha Reddy Pothulabfd06f72014-10-31 14:03:37 +053016133 if (NULL == param) {
16134 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Invalid argumet passed", __func__);
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053016135 vos_ssr_unprotect(__func__);
Hanumantha Reddy Pothulabfd06f72014-10-31 14:03:37 +053016136 return -EINVAL;
16137 }
16138
16139 WLANSAP_PopulateDelStaParams(param->mac, param->reason_code,
16140 param->subtype, &delStaParams);
16141
Naresh Jayaram69e3f282014-10-14 12:29:12 +053016142#else
Sushant Kaushik4cd28f62014-12-26 14:23:50 +053016143 WLANSAP_PopulateDelStaParams(mac, eSIR_MAC_DEAUTH_LEAVING_BSS_REASON,
Hanumantha Reddy Pothulabfd06f72014-10-31 14:03:37 +053016144 (SIR_MAC_MGMT_DEAUTH >> 4), &delStaParams);
Naresh Jayaram69e3f282014-10-14 12:29:12 +053016145#endif
Hanumantha Reddy Pothulabfd06f72014-10-31 14:03:37 +053016146 ret = __wlan_hdd_cfg80211_del_station(wiphy, dev, &delStaParams);
16147
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053016148 vos_ssr_unprotect(__func__);
16149
16150 return ret;
16151}
16152
16153static int __wlan_hdd_cfg80211_add_station(struct wiphy *wiphy,
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053016154 struct net_device *dev,
16155#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,18,0))
16156 const u8 *mac,
16157#else
16158 u8 *mac,
16159#endif
16160 struct station_parameters *params)
Hoonki Lee11f7dda2013-02-14 16:55:44 -080016161{
Mahesh A Saptasagar74088392015-02-05 17:22:09 +053016162 hdd_adapter_t *pAdapter;
16163 hdd_context_t *pHddCtx;
Gopichand Nakkalab977a972013-02-18 19:15:09 -080016164 int status = -EPERM;
Hoonki Lee11f7dda2013-02-14 16:55:44 -080016165#ifdef FEATURE_WLAN_TDLS
16166 u32 mask, set;
Mahesh A Saptasagar74088392015-02-05 17:22:09 +053016167
Hoonki Lee11f7dda2013-02-14 16:55:44 -080016168 ENTER();
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053016169
Mahesh A Saptasagar74088392015-02-05 17:22:09 +053016170 pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
16171 if (NULL == pAdapter)
16172 {
16173 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
16174 "%s: Adapter is NULL",__func__);
16175 return -EINVAL;
16176 }
16177 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
16178 status = wlan_hdd_validate_context(pHddCtx);
16179 if (0 != status)
16180 {
Mahesh A Saptasagar74088392015-02-05 17:22:09 +053016181 return status;
16182 }
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053016183
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053016184 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
16185 TRACE_CODE_HDD_CFG80211_ADD_STA,
16186 pAdapter->sessionId, params->listen_interval));
Mohit Khanna698ba2a2012-12-04 15:08:18 -080016187 mask = params->sta_flags_mask;
16188
16189 set = params->sta_flags_set;
16190
Masti, Narayanraddi34e0e562015-03-05 18:23:03 +053016191 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Gopichand Nakkalac87400e2013-03-13 18:51:00 -070016192 "%s: mask 0x%x set 0x%x " MAC_ADDRESS_STR,
16193 __func__, mask, set, MAC_ADDR_ARRAY(mac));
Mohit Khanna698ba2a2012-12-04 15:08:18 -080016194
16195 if (mask & BIT(NL80211_STA_FLAG_TDLS_PEER)) {
16196 if (set & BIT(NL80211_STA_FLAG_TDLS_PEER)) {
Gopichand Nakkala681989c2013-03-06 22:27:48 -080016197 status = wlan_hdd_tdls_add_station(wiphy, dev, mac, 0, NULL);
Mohit Khanna698ba2a2012-12-04 15:08:18 -080016198 }
16199 }
16200#endif
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053016201 EXIT();
Gopichand Nakkalab977a972013-02-18 19:15:09 -080016202 return status;
Jeff Johnson295189b2012-06-20 16:38:30 -070016203}
16204
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053016205#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,16,0))
16206static int wlan_hdd_cfg80211_add_station(struct wiphy *wiphy,
16207 struct net_device *dev, const u8 *mac,
16208 struct station_parameters *params)
16209#else
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053016210static int wlan_hdd_cfg80211_add_station(struct wiphy *wiphy,
16211 struct net_device *dev, u8 *mac, struct station_parameters *params)
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053016212#endif
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053016213{
16214 int ret;
Jeff Johnson04dd8a82012-06-29 20:41:40 -070016215
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053016216 vos_ssr_protect(__func__);
16217 ret = __wlan_hdd_cfg80211_add_station(wiphy, dev, mac, params);
16218 vos_ssr_unprotect(__func__);
16219
16220 return ret;
16221}
Jeff Johnson04dd8a82012-06-29 20:41:40 -070016222#ifdef FEATURE_WLAN_LFR
Wilson Yang6507c4e2013-10-01 20:11:19 -070016223
Mahesh A Saptasagarf7418d72014-06-02 14:48:54 +053016224static int __wlan_hdd_cfg80211_set_pmksa(struct wiphy *wiphy, struct net_device *dev,
Jeff Johnsond13512a2012-07-17 11:42:19 -070016225 struct cfg80211_pmksa *pmksa)
Jeff Johnson04dd8a82012-06-29 20:41:40 -070016226{
Jeff Johnson04dd8a82012-06-29 20:41:40 -070016227 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
16228 tHalHandle halHandle;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016229 eHalStatus result;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053016230 int status;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053016231 hdd_context_t *pHddCtx;
Kanchanapally, Vidyullatha2633ace2014-09-25 15:16:50 +053016232 tPmkidCacheInfo pmk_id;
Jeff Johnsone7245742012-09-05 17:12:55 -070016233
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053016234 ENTER();
16235
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016236 // Validate pAdapter
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053016237 if ( NULL == pAdapter )
Jeff Johnson04dd8a82012-06-29 20:41:40 -070016238 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053016239 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Invalid Adapter" ,__func__);
Jeff Johnson04dd8a82012-06-29 20:41:40 -070016240 return -EINVAL;
16241 }
16242
Kanchanapally, Vidyullatha2633ace2014-09-25 15:16:50 +053016243 if (!pmksa) {
16244 hddLog(LOGE, FL("pmksa is NULL"));
16245 return -EINVAL;
16246 }
16247
16248 if (!pmksa->bssid || !pmksa->pmkid) {
16249 hddLog(LOGE, FL("pmksa->bssid(%p) or pmksa->pmkid(%p) is NULL"),
16250 pmksa->bssid, pmksa->pmkid);
16251 return -EINVAL;
16252 }
16253
16254 hddLog(VOS_TRACE_LEVEL_DEBUG, "%s: set PMKSA for " MAC_ADDRESS_STR,
16255 __func__, MAC_ADDR_ARRAY(pmksa->bssid));
16256
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053016257 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
16258 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053016259 if (0 != status)
Jeff Johnson04dd8a82012-06-29 20:41:40 -070016260 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053016261 return status;
Jeff Johnson04dd8a82012-06-29 20:41:40 -070016262 }
16263
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016264 // Retrieve halHandle
Jeff Johnson04dd8a82012-06-29 20:41:40 -070016265 halHandle = WLAN_HDD_GET_HAL_CTX(pAdapter);
16266
Kanchanapally, Vidyullatha2633ace2014-09-25 15:16:50 +053016267 vos_mem_copy(pmk_id.BSSID, pmksa->bssid, ETHER_ADDR_LEN);
16268 vos_mem_copy(pmk_id.PMKID, pmksa->pmkid, CSR_RSN_PMKID_SIZE);
Jeff Johnson04dd8a82012-06-29 20:41:40 -070016269
Kanchanapally, Vidyullatha2633ace2014-09-25 15:16:50 +053016270 /* Add to the PMKSA ID Cache in CSR */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016271 result = sme_RoamSetPMKIDCache(halHandle,pAdapter->sessionId,
Kanchanapally, Vidyullatha2633ace2014-09-25 15:16:50 +053016272 &pmk_id, 1, FALSE);
16273
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053016274 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
16275 TRACE_CODE_HDD_CFG80211_SET_PMKSA,
16276 pAdapter->sessionId, result));
Kanchanapally, Vidyullatha2633ace2014-09-25 15:16:50 +053016277
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053016278 EXIT();
Kanchanapally, Vidyullatha2633ace2014-09-25 15:16:50 +053016279 return HAL_STATUS_SUCCESS(result) ? 0 : -EINVAL;
Jeff Johnson04dd8a82012-06-29 20:41:40 -070016280}
16281
Mahesh A Saptasagarf7418d72014-06-02 14:48:54 +053016282static int wlan_hdd_cfg80211_set_pmksa(struct wiphy *wiphy, struct net_device *dev,
16283 struct cfg80211_pmksa *pmksa)
16284{
16285 int ret;
16286
16287 vos_ssr_protect(__func__);
16288 ret = __wlan_hdd_cfg80211_set_pmksa(wiphy, dev, pmksa);
16289 vos_ssr_unprotect(__func__);
16290
16291 return ret;
16292}
Jeff Johnson04dd8a82012-06-29 20:41:40 -070016293
Wilson Yang6507c4e2013-10-01 20:11:19 -070016294
Mahesh A Saptasagarf7418d72014-06-02 14:48:54 +053016295static int __wlan_hdd_cfg80211_del_pmksa(struct wiphy *wiphy, struct net_device *dev,
Wilson Yang6507c4e2013-10-01 20:11:19 -070016296 struct cfg80211_pmksa *pmksa)
Jeff Johnson04dd8a82012-06-29 20:41:40 -070016297{
Wilson Yang6507c4e2013-10-01 20:11:19 -070016298 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
16299 tHalHandle halHandle;
Wilson Yang6507c4e2013-10-01 20:11:19 -070016300 hdd_context_t *pHddCtx;
Wilson Yangef657d32014-01-15 19:19:23 -080016301 int status = 0;
Wilson Yang6507c4e2013-10-01 20:11:19 -070016302
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053016303 ENTER();
16304
Wilson Yang6507c4e2013-10-01 20:11:19 -070016305 /* Validate pAdapter */
16306 if (NULL == pAdapter)
16307 {
16308 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Invalid Adapter" ,__func__);
16309 return -EINVAL;
16310 }
16311
Kanchanapally, Vidyullatha2633ace2014-09-25 15:16:50 +053016312 if (!pmksa) {
16313 hddLog(LOGE, FL("pmksa is NULL"));
16314 return -EINVAL;
16315 }
16316
16317 if (!pmksa->bssid) {
16318 hddLog(LOGE, FL("pmksa->bssid is NULL"));
16319 return -EINVAL;
16320 }
16321
Kiet Lam98c46a12014-10-31 15:34:57 -070016322 hddLog(VOS_TRACE_LEVEL_DEBUG, "%s: deleting PMKSA for " MAC_ADDRESS_STR,
16323 __func__, MAC_ADDR_ARRAY(pmksa->bssid));
16324
Wilson Yang6507c4e2013-10-01 20:11:19 -070016325 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
16326 status = wlan_hdd_validate_context(pHddCtx);
Wilson Yang6507c4e2013-10-01 20:11:19 -070016327 if (0 != status)
16328 {
Wilson Yang6507c4e2013-10-01 20:11:19 -070016329 return status;
16330 }
16331
16332 /*Retrieve halHandle*/
16333 halHandle = WLAN_HDD_GET_HAL_CTX(pAdapter);
16334
Konamki, Sreelakshmi7b464be2015-07-14 12:17:01 +053016335 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
16336 TRACE_CODE_HDD_CFG80211_DEL_PMKSA,
16337 pAdapter->sessionId, 0));
Kanchanapally, Vidyullatha2633ace2014-09-25 15:16:50 +053016338 /* Delete the PMKID CSR cache */
16339 if (eHAL_STATUS_SUCCESS !=
16340 sme_RoamDelPMKIDfromCache(halHandle,
16341 pAdapter->sessionId, pmksa->bssid, FALSE)) {
16342 hddLog(LOGE, FL("Failed to delete PMKSA for "MAC_ADDRESS_STR),
16343 MAC_ADDR_ARRAY(pmksa->bssid));
16344 status = -EINVAL;
Wilson Yang6507c4e2013-10-01 20:11:19 -070016345 }
16346
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053016347 EXIT();
16348 return status;
Jeff Johnson04dd8a82012-06-29 20:41:40 -070016349}
16350
Wilson Yang6507c4e2013-10-01 20:11:19 -070016351
Mahesh A Saptasagarf7418d72014-06-02 14:48:54 +053016352static int wlan_hdd_cfg80211_del_pmksa(struct wiphy *wiphy, struct net_device *dev,
16353 struct cfg80211_pmksa *pmksa)
16354{
16355 int ret;
Wilson Yang6507c4e2013-10-01 20:11:19 -070016356
Mahesh A Saptasagarf7418d72014-06-02 14:48:54 +053016357 vos_ssr_protect(__func__);
16358 ret = __wlan_hdd_cfg80211_del_pmksa(wiphy, dev, pmksa);
16359 vos_ssr_unprotect(__func__);
16360
16361 return ret;
16362
16363}
16364
16365static int __wlan_hdd_cfg80211_flush_pmksa(struct wiphy *wiphy, struct net_device *dev)
Jeff Johnson04dd8a82012-06-29 20:41:40 -070016366{
Wilson Yang6507c4e2013-10-01 20:11:19 -070016367 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
16368 tHalHandle halHandle;
16369 hdd_context_t *pHddCtx;
Wilson Yangef657d32014-01-15 19:19:23 -080016370 int status = 0;
Wilson Yang6507c4e2013-10-01 20:11:19 -070016371
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053016372 ENTER();
Wilson Yang6507c4e2013-10-01 20:11:19 -070016373
16374 /* Validate pAdapter */
16375 if (NULL == pAdapter)
16376 {
16377 hddLog(VOS_TRACE_LEVEL_ERROR,
16378 "%s: Invalid Adapter" ,__func__);
16379 return -EINVAL;
16380 }
16381
16382 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
16383 status = wlan_hdd_validate_context(pHddCtx);
Wilson Yang6507c4e2013-10-01 20:11:19 -070016384 if (0 != status)
16385 {
Wilson Yang6507c4e2013-10-01 20:11:19 -070016386 return status;
16387 }
16388
16389 /*Retrieve halHandle*/
16390 halHandle = WLAN_HDD_GET_HAL_CTX(pAdapter);
16391
Kanchanapally, Vidyullatha2633ace2014-09-25 15:16:50 +053016392 /* Flush the PMKID cache in CSR */
16393 if (eHAL_STATUS_SUCCESS !=
16394 sme_RoamDelPMKIDfromCache(halHandle, pAdapter->sessionId, NULL, TRUE)) {
16395 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Cannot flush PMKIDCache"));
16396 status = -EINVAL;
Wilson Yang6507c4e2013-10-01 20:11:19 -070016397 }
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053016398 EXIT();
Wilson Yangef657d32014-01-15 19:19:23 -080016399 return status;
Jeff Johnson04dd8a82012-06-29 20:41:40 -070016400}
Mahesh A Saptasagarf7418d72014-06-02 14:48:54 +053016401
16402static int wlan_hdd_cfg80211_flush_pmksa(struct wiphy *wiphy, struct net_device *dev)
16403{
16404 int ret;
16405
16406 vos_ssr_protect(__func__);
16407 ret = __wlan_hdd_cfg80211_flush_pmksa(wiphy, dev);
16408 vos_ssr_unprotect(__func__);
16409
16410 return ret;
16411}
Jeff Johnson04dd8a82012-06-29 20:41:40 -070016412#endif
16413
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070016414#if defined(WLAN_FEATURE_VOWIFI_11R) && defined(KERNEL_SUPPORT_11R_CFG80211)
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053016415static int __wlan_hdd_cfg80211_update_ft_ies(struct wiphy *wiphy,
16416 struct net_device *dev,
16417 struct cfg80211_update_ft_ies_params *ftie)
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070016418{
16419 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
16420 hdd_station_ctx_t *pHddStaCtx;
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +053016421 hdd_context_t *pHddCtx;
16422 int ret = 0;
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070016423
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053016424 ENTER();
16425
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070016426 if (NULL == pAdapter)
16427 {
Arif Hussain6d2a3322013-11-17 19:50:10 -080016428 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Adapter is NULL", __func__);
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070016429 return -ENODEV;
16430 }
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +053016431 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
16432 ret = wlan_hdd_validate_context(pHddCtx);
16433 if (0 != ret)
16434 {
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +053016435 return ret;
16436 }
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070016437 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
Mahesh A Saptasagar74088392015-02-05 17:22:09 +053016438 if (NULL == pHddStaCtx)
16439 {
16440 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: STA Context is NULL", __func__);
16441 return -EINVAL;
16442 }
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070016443
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053016444 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
16445 TRACE_CODE_HDD_CFG80211_UPDATE_FT_IES,
16446 pAdapter->sessionId, pHddStaCtx->conn_info.connState));
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070016447 // Added for debug on reception of Re-assoc Req.
16448 if (eConnectionState_Associated != pHddStaCtx->conn_info.connState)
16449 {
Arif Hussain6d2a3322013-11-17 19:50:10 -080016450 hddLog(LOGE, FL("Called with Ie of length = %zu when not associated"),
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070016451 ftie->ie_len);
Arif Hussain6d2a3322013-11-17 19:50:10 -080016452 hddLog(LOGE, FL("Should be Re-assoc Req IEs"));
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070016453 }
16454
16455#ifdef WLAN_FEATURE_VOWIFI_11R_DEBUG
Arif Hussain6d2a3322013-11-17 19:50:10 -080016456 hddLog(LOGE, FL("%s called with Ie of length = %zu"), __func__,
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070016457 ftie->ie_len);
16458#endif
16459
16460 // Pass the received FT IEs to SME
Gopichand Nakkala356fb102013-03-06 12:34:04 +053016461 sme_SetFTIEs( WLAN_HDD_GET_HAL_CTX(pAdapter), pAdapter->sessionId,
16462 (const u8 *)ftie->ie,
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070016463 ftie->ie_len);
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053016464
16465 EXIT();
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070016466 return 0;
16467}
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053016468
16469static int wlan_hdd_cfg80211_update_ft_ies(struct wiphy *wiphy,
16470 struct net_device *dev,
16471 struct cfg80211_update_ft_ies_params *ftie)
16472{
16473 int ret;
16474
16475 vos_ssr_protect(__func__);
16476 ret = __wlan_hdd_cfg80211_update_ft_ies(wiphy, dev, ftie);
16477 vos_ssr_unprotect(__func__);
16478
16479 return ret;
16480}
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070016481#endif
Jeff Johnson04dd8a82012-06-29 20:41:40 -070016482
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053016483#ifdef FEATURE_WLAN_SCAN_PNO
16484
16485void hdd_cfg80211_sched_scan_done_callback(void *callbackContext,
16486 tSirPrefNetworkFoundInd *pPrefNetworkFoundInd)
16487{
16488 int ret;
16489 hdd_adapter_t* pAdapter = (hdd_adapter_t*)callbackContext;
16490 hdd_context_t *pHddCtx;
16491
Nirav Shah80830bf2013-12-31 16:35:12 +053016492 ENTER();
16493
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053016494 if (NULL == pAdapter)
16495 {
Agarwal Ashish971c2882013-10-30 20:11:12 +053016496 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053016497 "%s: HDD adapter is Null", __func__);
16498 return ;
16499 }
16500
16501 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
16502 if (NULL == pHddCtx)
16503 {
16504 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
16505 "%s: HDD context is Null!!!", __func__);
16506 return ;
16507 }
16508
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053016509 spin_lock(&pHddCtx->schedScan_lock);
16510 if (TRUE == pHddCtx->isWiphySuspended)
16511 {
16512 pHddCtx->isSchedScanUpdatePending = TRUE;
16513 spin_unlock(&pHddCtx->schedScan_lock);
16514 hddLog(VOS_TRACE_LEVEL_INFO,
16515 "%s: Update cfg80211 scan database after it resume", __func__);
16516 return ;
16517 }
16518 spin_unlock(&pHddCtx->schedScan_lock);
16519
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053016520 ret = wlan_hdd_cfg80211_update_bss(pHddCtx->wiphy, pAdapter);
16521
16522 if (0 > ret)
16523 hddLog(VOS_TRACE_LEVEL_INFO, "%s: NO SCAN result", __func__);
Mahesh A Saptasagarfb49cdd2015-10-16 18:41:59 +053016524 else
16525 {
16526 /* Acquire wakelock to handle the case where APP's tries to suspend
16527 * immediatly after the driver gets connect request(i.e after pno)
16528 * from supplicant, this result in app's is suspending and not able
16529 * to process the connect request to AP */
16530 hdd_prevent_suspend_timeout(1000, WIFI_POWER_EVENT_WAKELOCK_SCAN);
16531 }
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053016532 cfg80211_sched_scan_results(pHddCtx->wiphy);
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053016533 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
16534 "%s: cfg80211 scan result database updated", __func__);
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053016535}
16536
16537/*
Mahesh A Saptasagar0f7b0372013-11-28 23:23:07 +053016538 * FUNCTION: wlan_hdd_is_pno_allowed
Vinay Krishna Erannacbf75f42014-02-26 17:35:20 +053016539 * Disallow pno if any session is active
Mahesh A Saptasagar0f7b0372013-11-28 23:23:07 +053016540 */
16541static eHalStatus wlan_hdd_is_pno_allowed(hdd_adapter_t *pAdapter)
16542{
16543 hdd_adapter_list_node_t *pAdapterNode = NULL, *pNext = NULL;
16544 hdd_adapter_t *pTempAdapter = NULL;
Vinay Krishna Eranna23ffd182013-12-26 19:16:55 +053016545 hdd_station_ctx_t *pStaCtx;
Mahesh A Saptasagar0f7b0372013-11-28 23:23:07 +053016546 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
16547 int status = 0;
16548 status = hdd_get_front_adapter(pHddCtx, &pAdapterNode);
16549
Vinay Krishna Erannacbf75f42014-02-26 17:35:20 +053016550 /* The current firmware design does not allow PNO during any
16551 * active sessions. Hence, determine the active sessions
16552 * and return a failure.
16553 */
Mahesh A Saptasagar0f7b0372013-11-28 23:23:07 +053016554 while ((NULL != pAdapterNode) && (VOS_STATUS_SUCCESS == status))
16555 {
16556 pTempAdapter = pAdapterNode->pAdapter;
Vinay Krishna Eranna23ffd182013-12-26 19:16:55 +053016557 pStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pTempAdapter);
Mahesh A Saptasagar0f7b0372013-11-28 23:23:07 +053016558
Vinay Krishna Eranna23ffd182013-12-26 19:16:55 +053016559 if (((WLAN_HDD_INFRA_STATION == pTempAdapter->device_mode)
16560 && (eConnectionState_NotConnected != pStaCtx->conn_info.connState))
16561 || (WLAN_HDD_P2P_CLIENT == pTempAdapter->device_mode)
16562 || (WLAN_HDD_P2P_GO == pTempAdapter->device_mode)
16563 || (WLAN_HDD_SOFTAP == pTempAdapter->device_mode)
Siddharth Bhal63a19a72014-11-07 14:31:56 +053016564 || (WLAN_HDD_TM_LEVEL_4 == pHddCtx->tmInfo.currentTmLevel)
Vinay Krishna Eranna23ffd182013-12-26 19:16:55 +053016565 )
Mahesh A Saptasagar0f7b0372013-11-28 23:23:07 +053016566 {
Vinay Krishna Eranna23ffd182013-12-26 19:16:55 +053016567 return eHAL_STATUS_FAILURE;
Mahesh A Saptasagar0f7b0372013-11-28 23:23:07 +053016568 }
16569 status = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
16570 pAdapterNode = pNext;
16571 }
Vinay Krishna Eranna23ffd182013-12-26 19:16:55 +053016572 return eHAL_STATUS_SUCCESS;
Mahesh A Saptasagar0f7b0372013-11-28 23:23:07 +053016573}
16574
Vinay Krishna Erannaf0e523b2014-03-01 21:00:16 +053016575void hdd_cfg80211_sched_scan_start_status_cb(void *callbackContext, VOS_STATUS status)
16576{
16577 hdd_adapter_t *pAdapter = callbackContext;
16578 hdd_context_t *pHddCtx;
16579
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053016580 ENTER();
16581
Vinay Krishna Erannaf0e523b2014-03-01 21:00:16 +053016582 if ((NULL == pAdapter) || (WLAN_HDD_ADAPTER_MAGIC != pAdapter->magic))
16583 {
16584 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
16585 FL("Invalid adapter or adapter has invalid magic"));
16586 return;
16587 }
16588
16589 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
16590 if (0 != wlan_hdd_validate_context(pHddCtx))
16591 {
Vinay Krishna Erannaf0e523b2014-03-01 21:00:16 +053016592 return;
16593 }
16594
c_hpothub53c45d2014-08-18 16:53:14 +053016595 if (VOS_STATUS_SUCCESS != status)
16596 {
16597 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Vinay Krishna Erannaf0e523b2014-03-01 21:00:16 +053016598 FL("PNO enable response status = %d"), status);
c_hpothub53c45d2014-08-18 16:53:14 +053016599 pHddCtx->isPnoEnable = FALSE;
16600 }
Vinay Krishna Erannaf0e523b2014-03-01 21:00:16 +053016601
16602 pAdapter->pno_req_status = (status == VOS_STATUS_SUCCESS) ? 0 : -EBUSY;
16603 complete(&pAdapter->pno_comp_var);
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053016604 EXIT();
Vinay Krishna Erannaf0e523b2014-03-01 21:00:16 +053016605}
16606
Mahesh A Saptasagar0f7b0372013-11-28 23:23:07 +053016607/*
Mahesh A Saptasagar6cc38562014-05-23 21:22:17 +053016608 * FUNCTION: __wlan_hdd_cfg80211_sched_scan_start
16609 * Function to enable PNO
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053016610 */
Mahesh A Saptasagar6cc38562014-05-23 21:22:17 +053016611static int __wlan_hdd_cfg80211_sched_scan_start(struct wiphy *wiphy,
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053016612 struct net_device *dev, struct cfg80211_sched_scan_request *request)
16613{
16614 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053016615 tSirPNOScanReq pnoRequest = {0};
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053016616 hdd_context_t *pHddCtx;
16617 tHalHandle hHal;
Mahesh A Saptasagar7bd6ad42014-07-21 18:56:33 +053016618 v_U32_t i, indx, num_ch, tempInterval, j;
Sushant Kaushikd62d9782014-02-19 15:39:40 +053016619 u8 valid_ch[WNI_CFG_VALID_CHANNEL_LIST_LEN] = {0};
16620 u8 channels_allowed[WNI_CFG_VALID_CHANNEL_LIST_LEN] = {0};
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053016621 v_U32_t num_channels_allowed = WNI_CFG_VALID_CHANNEL_LIST_LEN;
16622 eHalStatus status = eHAL_STATUS_FAILURE;
Kamath Vinayakba5313f2013-08-22 15:52:39 +053016623 int ret = 0;
Sachin Ahuja697ba3f2014-11-12 18:57:11 +053016624 hdd_config_t *pConfig = NULL;
16625 v_U32_t num_ignore_dfs_ch = 0;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053016626
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053016627 ENTER();
16628
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053016629 if (NULL == pAdapter)
16630 {
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053016631 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053016632 "%s: HDD adapter is Null", __func__);
16633 return -ENODEV;
16634 }
16635
16636 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053016637 ret = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053016638
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053016639 if (0 != ret)
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053016640 {
Kamath Vinayakba5313f2013-08-22 15:52:39 +053016641 return -EINVAL;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053016642 }
16643
Sachin Ahuja697ba3f2014-11-12 18:57:11 +053016644 pConfig = pHddCtx->cfg_ini;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053016645 hHal = WLAN_HDD_GET_HAL_CTX(pAdapter);
16646 if (NULL == hHal)
16647 {
16648 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
16649 "%s: HAL context is Null!!!", __func__);
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053016650 return -EINVAL;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053016651 }
Konamki, Sreelakshmi7b464be2015-07-14 12:17:01 +053016652 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
16653 TRACE_CODE_HDD_CFG80211_SCHED_SCAN_START,
16654 pAdapter->sessionId, pAdapter->device_mode));
Sushant Kaushik2fe89932014-09-03 10:58:09 +053016655 sme_ScanFlushResult(hHal, pAdapter->sessionId);
Mahesh A Saptasagar2395ee62014-05-21 19:12:21 +053016656 ret = wlan_hdd_scan_abort(pAdapter);
Girish Gowli4bf7a632014-06-12 13:42:11 +053016657 if (ret < 0)
Mahesh A Saptasagar2395ee62014-05-21 19:12:21 +053016658 {
16659 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
16660 "%s: aborting the existing scan is unsuccessfull", __func__);
16661 return -EBUSY;
16662 }
16663
Vinay Krishna Eranna23ffd182013-12-26 19:16:55 +053016664 if (eHAL_STATUS_SUCCESS != wlan_hdd_is_pno_allowed(pAdapter))
Mahesh A Saptasagar0f7b0372013-11-28 23:23:07 +053016665 {
Vinay Krishna Erannacbf75f42014-02-26 17:35:20 +053016666 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_WARN,
Vinay Krishna Eranna23ffd182013-12-26 19:16:55 +053016667 FL("Cannot handle sched_scan"));
Mahesh A Saptasagar0f7b0372013-11-28 23:23:07 +053016668 return -EBUSY;
16669 }
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053016670
c_hpothu37f21312014-04-09 21:49:54 +053016671 if (TRUE == pHddCtx->isPnoEnable)
16672 {
16673 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_WARN,
16674 FL("already PNO is enabled"));
16675 return -EBUSY;
16676 }
c_hpothu225aa7c2014-10-22 17:45:13 +053016677
16678 if (VOS_STATUS_SUCCESS != wlan_hdd_cancel_remain_on_channel(pHddCtx))
16679 {
16680 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
16681 "%s: abort ROC failed ", __func__);
16682 return -EBUSY;
16683 }
16684
c_hpothu37f21312014-04-09 21:49:54 +053016685 pHddCtx->isPnoEnable = TRUE;
16686
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053016687 pnoRequest.enable = 1; /*Enable PNO */
16688 pnoRequest.ucNetworksCount = request->n_match_sets;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053016689
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053016690 if (( !pnoRequest.ucNetworksCount ) ||
16691 ( pnoRequest.ucNetworksCount > SIR_PNO_MAX_SUPP_NETWORKS ))
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053016692 {
16693 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Sushant Kaushik1e406c32014-05-09 15:57:52 +053016694 "%s: Network input is not correct %d Max Network supported is %d",
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053016695 __func__, pnoRequest.ucNetworksCount,
Sushant Kaushik1e406c32014-05-09 15:57:52 +053016696 SIR_PNO_MAX_SUPP_NETWORKS);
Kamath Vinayakba5313f2013-08-22 15:52:39 +053016697 ret = -EINVAL;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053016698 goto error;
16699 }
16700
16701 if ( SIR_PNO_MAX_NETW_CHANNELS_EX < request->n_channels )
16702 {
16703 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Nirav Shah80830bf2013-12-31 16:35:12 +053016704 "%s: Incorrect number of channels %d",
16705 __func__, request->n_channels);
Kamath Vinayakba5313f2013-08-22 15:52:39 +053016706 ret = -EINVAL;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053016707 goto error;
16708 }
16709
16710 /* Framework provides one set of channels(all)
16711 * common for all saved profile */
16712 if (0 != ccmCfgGetStr(hHal, WNI_CFG_VALID_CHANNEL_LIST,
16713 channels_allowed, &num_channels_allowed))
16714 {
16715 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
16716 "%s: failed to get valid channel list", __func__);
Kamath Vinayakba5313f2013-08-22 15:52:39 +053016717 ret = -EINVAL;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053016718 goto error;
16719 }
16720 /* Checking each channel against allowed channel list */
16721 num_ch = 0;
Nirav Shah80830bf2013-12-31 16:35:12 +053016722 if (request->n_channels)
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053016723 {
Nirav Shah80830bf2013-12-31 16:35:12 +053016724 char chList [(request->n_channels*5)+1];
16725 int len;
16726 for (i = 0, len = 0; i < request->n_channels; i++)
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053016727 {
Nirav Shah80830bf2013-12-31 16:35:12 +053016728 for (indx = 0; indx < num_channels_allowed; indx++)
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053016729 {
Nirav Shah80830bf2013-12-31 16:35:12 +053016730 if (request->channels[i]->hw_value == channels_allowed[indx])
16731 {
Sachin Ahuja697ba3f2014-11-12 18:57:11 +053016732 if ((!pConfig->enableDFSPnoChnlScan) &&
16733 (NV_CHANNEL_DFS == vos_nv_getChannelEnabledState(channels_allowed[indx])))
16734 {
16735 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
16736 "%s : Dropping DFS channel : %d",
16737 __func__,channels_allowed[indx]);
16738 num_ignore_dfs_ch++;
16739 break;
16740 }
16741
Nirav Shah80830bf2013-12-31 16:35:12 +053016742 valid_ch[num_ch++] = request->channels[i]->hw_value;
16743 len += snprintf(chList+len, 5, "%d ",
16744 request->channels[i]->hw_value);
16745 break ;
16746 }
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053016747 }
16748 }
Nirav Shah80830bf2013-12-31 16:35:12 +053016749 hddLog(VOS_TRACE_LEVEL_INFO,"Channel-List: %s ", chList);
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053016750
Sachin Ahuja697ba3f2014-11-12 18:57:11 +053016751 /*If all channels are DFS and dropped, then ignore the PNO request*/
16752 if (num_ignore_dfs_ch == request->n_channels)
16753 {
16754 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
16755 "%s : All requested channels are DFS channels", __func__);
16756 ret = -EINVAL;
16757 goto error;
16758 }
16759 }
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053016760
16761 pnoRequest.aNetworks =
16762 vos_mem_malloc(sizeof(tSirNetworkType)*pnoRequest.ucNetworksCount);
16763 if (pnoRequest.aNetworks == NULL)
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053016764 {
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053016765 VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR,
16766 FL("failed to allocate memory aNetworks %u"),
16767 (uint32)sizeof(tSirNetworkType)*pnoRequest.ucNetworksCount);
16768 goto error;
16769 }
16770 vos_mem_zero(pnoRequest.aNetworks,
16771 sizeof(tSirNetworkType)*pnoRequest.ucNetworksCount);
16772
16773 /* Filling per profile params */
16774 for (i = 0; i < pnoRequest.ucNetworksCount; i++)
16775 {
16776 pnoRequest.aNetworks[i].ssId.length =
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053016777 request->match_sets[i].ssid.ssid_len;
16778
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053016779 if (( 0 == pnoRequest.aNetworks[i].ssId.length ) ||
16780 ( pnoRequest.aNetworks[i].ssId.length > 32 ) )
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053016781 {
16782 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Nirav Shah80830bf2013-12-31 16:35:12 +053016783 "%s: SSID Len %d is not correct for network %d",
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053016784 __func__, pnoRequest.aNetworks[i].ssId.length, i);
Kamath Vinayakba5313f2013-08-22 15:52:39 +053016785 ret = -EINVAL;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053016786 goto error;
16787 }
16788
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053016789 memcpy(pnoRequest.aNetworks[i].ssId.ssId,
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053016790 request->match_sets[i].ssid.ssid,
16791 request->match_sets[i].ssid.ssid_len);
Sushant Kaushik1e406c32014-05-09 15:57:52 +053016792 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
16793 "%s: SSID of network %d is %s ", __func__,
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053016794 i, pnoRequest.aNetworks[i].ssId.ssId);
16795 pnoRequest.aNetworks[i].authentication = 0; /*eAUTH_TYPE_ANY*/
16796 pnoRequest.aNetworks[i].encryption = 0; /*eED_ANY*/
16797 pnoRequest.aNetworks[i].bcastNetwType = 0; /*eBCAST_UNKNOWN*/
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053016798
16799 /*Copying list of valid channel into request */
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053016800 memcpy(pnoRequest.aNetworks[i].aChannels, valid_ch, num_ch);
16801 pnoRequest.aNetworks[i].ucChannelCount = num_ch;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053016802
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053016803 pnoRequest.aNetworks[i].rssiThreshold = 0; //Default value
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053016804 }
16805
Mahesh A Saptasagar7bd6ad42014-07-21 18:56:33 +053016806 for (i = 0; i < request->n_ssids; i++)
16807 {
16808 j = 0;
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053016809 while (j < pnoRequest.ucNetworksCount)
Mahesh A Saptasagar7bd6ad42014-07-21 18:56:33 +053016810 {
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053016811 if ((pnoRequest.aNetworks[j].ssId.length ==
Mahesh A Saptasagar7bd6ad42014-07-21 18:56:33 +053016812 request->ssids[i].ssid_len) &&
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053016813 (0 == memcmp(pnoRequest.aNetworks[j].ssId.ssId,
Mahesh A Saptasagar7bd6ad42014-07-21 18:56:33 +053016814 request->ssids[i].ssid,
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053016815 pnoRequest.aNetworks[j].ssId.length)))
Mahesh A Saptasagar7bd6ad42014-07-21 18:56:33 +053016816 {
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053016817 pnoRequest.aNetworks[j].bcastNetwType = eBCAST_HIDDEN;
Mahesh A Saptasagar7bd6ad42014-07-21 18:56:33 +053016818 break;
16819 }
16820 j++;
16821 }
16822 }
16823 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
16824 "Number of hidden networks being Configured = %d",
16825 request->n_ssids);
Madan Mohan Koyyalamudia7765d52013-09-18 16:49:56 +053016826 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Jeff Johnson59a121e2013-11-30 09:46:08 -080016827 "request->ie_len = %zu", request->ie_len);
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053016828
16829 pnoRequest.p24GProbeTemplate = vos_mem_malloc(SIR_PNO_MAX_PB_REQ_SIZE);
16830 if (pnoRequest.p24GProbeTemplate == NULL)
16831 {
16832 VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR,
16833 FL("failed to allocate memory p24GProbeTemplate %u"),
16834 SIR_PNO_MAX_PB_REQ_SIZE);
16835 goto error;
16836 }
16837
16838 pnoRequest.p5GProbeTemplate = vos_mem_malloc(SIR_PNO_MAX_PB_REQ_SIZE);
16839 if (pnoRequest.p5GProbeTemplate == NULL)
16840 {
16841 VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR,
16842 FL("failed to allocate memory p5GProbeTemplate %u"),
16843 SIR_PNO_MAX_PB_REQ_SIZE);
16844 goto error;
16845 }
16846
16847 vos_mem_zero(pnoRequest.p24GProbeTemplate, SIR_PNO_MAX_PB_REQ_SIZE);
16848 vos_mem_zero(pnoRequest.p5GProbeTemplate, SIR_PNO_MAX_PB_REQ_SIZE);
16849
Hanumantha Reddy Pothula06e87b22015-03-02 18:02:23 +053016850 if ((0 < request->ie_len) && (request->ie_len <= SIR_PNO_MAX_PB_REQ_SIZE) &&
16851 (NULL != request->ie))
Madan Mohan Koyyalamudia7765d52013-09-18 16:49:56 +053016852 {
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053016853 pnoRequest.us24GProbeTemplateLen = request->ie_len;
16854 memcpy(pnoRequest.p24GProbeTemplate, request->ie,
16855 pnoRequest.us24GProbeTemplateLen);
Madan Mohan Koyyalamudia7765d52013-09-18 16:49:56 +053016856
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053016857 pnoRequest.us5GProbeTemplateLen = request->ie_len;
16858 memcpy(pnoRequest.p5GProbeTemplate, request->ie,
16859 pnoRequest.us5GProbeTemplateLen);
Madan Mohan Koyyalamudia7765d52013-09-18 16:49:56 +053016860 }
16861
Madan Mohan Koyyalamudi1d16f462013-08-27 16:25:34 +053016862 /* Driver gets only one time interval which is hardcoded in
16863 * supplicant for 10000ms. Taking power consumption into account 6 timers
16864 * will be used, Timervalue is increased exponentially i.e 10,20,40,
16865 * 80,160,320 secs. And number of scan cycle for each timer
16866 * is configurable through INI param gPNOScanTimerRepeatValue.
16867 * If it is set to 0 only one timer will be used and PNO scan cycle
16868 * will be repeated after each interval specified by supplicant
16869 * till PNO is disabled.
16870 */
16871 if (0 == pHddCtx->cfg_ini->configPNOScanTimerRepeatValue)
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053016872 pnoRequest.scanTimers.ucScanTimersCount = HDD_PNO_SCAN_TIMERS_SET_ONE;
Madan Mohan Koyyalamudi1d16f462013-08-27 16:25:34 +053016873 else
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053016874 pnoRequest.scanTimers.ucScanTimersCount =
Madan Mohan Koyyalamudi1d16f462013-08-27 16:25:34 +053016875 HDD_PNO_SCAN_TIMERS_SET_MULTIPLE;
16876
16877 tempInterval = (request->interval)/1000;
16878 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
16879 "Base scan interval = %d PNOScanTimerRepeatValue = %d",
16880 tempInterval, pHddCtx->cfg_ini->configPNOScanTimerRepeatValue);
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053016881 for ( i = 0; i < pnoRequest.scanTimers.ucScanTimersCount; i++)
Madan Mohan Koyyalamudi1d16f462013-08-27 16:25:34 +053016882 {
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053016883 pnoRequest.scanTimers.aTimerValues[i].uTimerRepeat =
Madan Mohan Koyyalamudi1d16f462013-08-27 16:25:34 +053016884 pHddCtx->cfg_ini->configPNOScanTimerRepeatValue;
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053016885 pnoRequest.scanTimers.aTimerValues[i].uTimerValue = tempInterval;
Madan Mohan Koyyalamudi1d16f462013-08-27 16:25:34 +053016886 tempInterval *= 2;
16887 }
16888 //Repeat last timer until pno disabled.
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053016889 pnoRequest.scanTimers.aTimerValues[i-1].uTimerRepeat = 0;
Madan Mohan Koyyalamudi1d16f462013-08-27 16:25:34 +053016890
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053016891 pnoRequest.modePNO = SIR_PNO_MODE_IMMEDIATE;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053016892
Vinay Krishna Erannaf0e523b2014-03-01 21:00:16 +053016893 INIT_COMPLETION(pAdapter->pno_comp_var);
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053016894 pnoRequest.statusCallback = hdd_cfg80211_sched_scan_start_status_cb;
16895 pnoRequest.callbackContext = pAdapter;
Vinay Krishna Erannaf0e523b2014-03-01 21:00:16 +053016896 pAdapter->pno_req_status = 0;
16897
Nirav Shah80830bf2013-12-31 16:35:12 +053016898 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
16899 "SessionId %d, enable %d, modePNO %d, ucScanTimersCount %d",
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053016900 pAdapter->sessionId, pnoRequest.enable, pnoRequest.modePNO,
16901 pnoRequest.scanTimers.ucScanTimersCount);
Nirav Shah80830bf2013-12-31 16:35:12 +053016902
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053016903 status = sme_SetPreferredNetworkList(WLAN_HDD_GET_HAL_CTX(pAdapter),
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053016904 &pnoRequest, pAdapter->sessionId,
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053016905 hdd_cfg80211_sched_scan_done_callback, pAdapter);
16906 if (eHAL_STATUS_SUCCESS != status)
16907 {
16908 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Nirav Shah80830bf2013-12-31 16:35:12 +053016909 "%s: Failed to enable PNO", __func__);
Kamath Vinayakba5313f2013-08-22 15:52:39 +053016910 ret = -EINVAL;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053016911 goto error;
16912 }
16913
Vinay Krishna Erannaf0e523b2014-03-01 21:00:16 +053016914 ret = wait_for_completion_timeout(
16915 &pAdapter->pno_comp_var,
16916 msecs_to_jiffies(WLAN_WAIT_TIME_PNO));
16917 if (0 >= ret)
16918 {
16919 // Did not receive the response for PNO enable in time.
16920 // Assuming the PNO enable was success.
16921 // Returning error from here, because we timeout, results
16922 // in side effect of Wifi (Wifi Setting) not to work.
16923 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
16924 FL("Timed out waiting for PNO to be Enabled"));
16925 ret = 0;
Vinay Krishna Erannaf0e523b2014-03-01 21:00:16 +053016926 }
16927
16928 ret = pAdapter->pno_req_status;
c_hpothu37f21312014-04-09 21:49:54 +053016929 return ret;
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053016930
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053016931error:
Vinay Krishna Erannaf0e523b2014-03-01 21:00:16 +053016932 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
16933 FL("PNO scanRequest offloaded ret = %d"), ret);
c_hpothu37f21312014-04-09 21:49:54 +053016934 pHddCtx->isPnoEnable = FALSE;
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053016935 if (pnoRequest.aNetworks)
16936 vos_mem_free(pnoRequest.aNetworks);
16937 if (pnoRequest.p24GProbeTemplate)
16938 vos_mem_free(pnoRequest.p24GProbeTemplate);
16939 if (pnoRequest.p5GProbeTemplate)
16940 vos_mem_free(pnoRequest.p5GProbeTemplate);
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053016941
16942 EXIT();
Kamath Vinayakba5313f2013-08-22 15:52:39 +053016943 return ret;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053016944}
16945
16946/*
Mahesh A Saptasagar6cc38562014-05-23 21:22:17 +053016947 * FUNCTION: wlan_hdd_cfg80211_sched_scan_start
16948 * NL interface to enable PNO
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053016949 */
Mahesh A Saptasagar6cc38562014-05-23 21:22:17 +053016950static int wlan_hdd_cfg80211_sched_scan_start(struct wiphy *wiphy,
16951 struct net_device *dev, struct cfg80211_sched_scan_request *request)
16952{
16953 int ret;
16954
16955 vos_ssr_protect(__func__);
16956 ret = __wlan_hdd_cfg80211_sched_scan_start(wiphy, dev, request);
16957 vos_ssr_unprotect(__func__);
16958
16959 return ret;
16960}
16961
16962/*
16963 * FUNCTION: __wlan_hdd_cfg80211_sched_scan_stop
16964 * Function to disable PNO
16965 */
16966static int __wlan_hdd_cfg80211_sched_scan_stop(struct wiphy *wiphy,
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053016967 struct net_device *dev)
16968{
16969 eHalStatus status = eHAL_STATUS_FAILURE;
16970 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
16971 hdd_context_t *pHddCtx;
16972 tHalHandle hHal;
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053016973 tSirPNOScanReq pnoRequest = {0};
Kamath Vinayakba5313f2013-08-22 15:52:39 +053016974 int ret = 0;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053016975
16976 ENTER();
16977
16978 if (NULL == pAdapter)
16979 {
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053016980 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053016981 "%s: HDD adapter is Null", __func__);
16982 return -ENODEV;
16983 }
16984
16985 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053016986
Kamath Vinayakba5313f2013-08-22 15:52:39 +053016987 if (NULL == pHddCtx)
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053016988 {
Gopichand Nakkalac005b7c2013-05-14 16:04:14 +053016989 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Kamath Vinayakba5313f2013-08-22 15:52:39 +053016990 "%s: HDD context is Null", __func__);
16991 return -ENODEV;
16992 }
16993
16994 /* The return 0 is intentional when isLogpInProgress and
16995 * isLoadUnloadInProgress. We did observe a crash due to a return of
16996 * failure in sched_scan_stop , especially for a case where the unload
16997 * of the happens at the same time. The function __cfg80211_stop_sched_scan
16998 * was clearing rdev->sched_scan_req only when the sched_scan_stop returns
16999 * success. If it returns a failure , then its next invocation due to the
17000 * clean up of the second interface will have the dev pointer corresponding
17001 * to the first one leading to a crash.
17002 */
17003 if (pHddCtx->isLogpInProgress)
17004 {
17005 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
17006 "%s: LOGP in Progress. Ignore!!!", __func__);
Mahesh A Saptasagar0c11d822015-10-08 19:54:08 +053017007 pHddCtx->isPnoEnable = FALSE;
Kamath Vinayakba5313f2013-08-22 15:52:39 +053017008 return ret;
17009 }
17010
Mihir Shete18156292014-03-11 15:38:30 +053017011 if (WLAN_HDD_IS_LOAD_UNLOAD_IN_PROGRESS(pHddCtx))
Kamath Vinayakba5313f2013-08-22 15:52:39 +053017012 {
17013 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
17014 "%s: Unloading/Loading in Progress. Ignore!!!", __func__);
17015 return ret;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053017016 }
17017
17018 hHal = WLAN_HDD_GET_HAL_CTX(pAdapter);
17019 if (NULL == hHal)
17020 {
17021 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
17022 "%s: HAL context is Null!!!", __func__);
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053017023 return -EINVAL;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053017024 }
17025
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053017026 pnoRequest.enable = 0; /* Disable PNO */
17027 pnoRequest.ucNetworksCount = 0;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053017028
Konamki, Sreelakshmi7b464be2015-07-14 12:17:01 +053017029 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
17030 TRACE_CODE_HDD_CFG80211_SCHED_SCAN_STOP,
17031 pAdapter->sessionId, pAdapter->device_mode));
Hanumantha Reddy Pothula0e408dc2015-11-23 12:04:53 +053017032
17033 INIT_COMPLETION(pAdapter->pno_comp_var);
17034 pnoRequest.statusCallback = hdd_cfg80211_sched_scan_start_status_cb;
17035 pnoRequest.callbackContext = pAdapter;
17036 pAdapter->pno_req_status = 0;
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053017037 status = sme_SetPreferredNetworkList(hHal, &pnoRequest,
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053017038 pAdapter->sessionId,
17039 NULL, pAdapter);
17040 if (eHAL_STATUS_SUCCESS != status)
17041 {
17042 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
17043 "Failed to disabled PNO");
Kamath Vinayakba5313f2013-08-22 15:52:39 +053017044 ret = -EINVAL;
Vinay Krishna Erannaf0e523b2014-03-01 21:00:16 +053017045 goto error;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053017046 }
Hanumantha Reddy Pothula0e408dc2015-11-23 12:04:53 +053017047 ret = wait_for_completion_timeout(
17048 &pAdapter->pno_comp_var,
17049 msecs_to_jiffies(WLAN_WAIT_TIME_PNO));
17050 if (0 >= ret)
17051 {
17052 // Did not receive the response for PNO disable in time.
17053 // Assuming the PNO disable was success.
17054 // Returning error from here, because we timeout, results
17055 // in side effect of Wifi (Wifi Setting) not to work.
17056 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
17057 FL("Timed out waiting for PNO to be disabled"));
17058 ret = 0;
17059 }
17060
17061 ret = pAdapter->pno_req_status;
17062 pHddCtx->isPnoEnable = (ret == 0) ? FALSE : TRUE;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053017063
Vinay Krishna Erannaf0e523b2014-03-01 21:00:16 +053017064error:
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053017065 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Vinay Krishna Erannaf0e523b2014-03-01 21:00:16 +053017066 FL("PNO scan disabled ret = %d"), ret);
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053017067
17068 EXIT();
Kamath Vinayakba5313f2013-08-22 15:52:39 +053017069 return ret;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053017070}
17071
Mahesh A Saptasagar6cc38562014-05-23 21:22:17 +053017072/*
17073 * FUNCTION: wlan_hdd_cfg80211_sched_scan_stop
17074 * NL interface to disable PNO
17075 */
17076static int wlan_hdd_cfg80211_sched_scan_stop(struct wiphy *wiphy,
17077 struct net_device *dev)
17078{
17079 int ret;
17080
17081 vos_ssr_protect(__func__);
17082 ret = __wlan_hdd_cfg80211_sched_scan_stop(wiphy, dev);
17083 vos_ssr_unprotect(__func__);
17084
17085 return ret;
17086}
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053017087#endif /*FEATURE_WLAN_SCAN_PNO*/
17088
17089
Mohit Khanna698ba2a2012-12-04 15:08:18 -080017090#ifdef FEATURE_WLAN_TDLS
Sunil Dutt Undekarieacac6f2014-03-21 14:08:53 +053017091#if TDLS_MGMT_VERSION2
Anand N Sunkad9f80b742015-07-30 20:05:51 +053017092static int __wlan_hdd_cfg80211_tdls_mgmt(struct wiphy *wiphy,
17093 struct net_device *dev,
17094 u8 *peer, u8 action_code,
17095 u8 dialog_token,
17096 u16 status_code, u32 peer_capability,
17097 const u8 *buf, size_t len)
17098#else /* TDLS_MGMT_VERSION2 */
17099#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 17, 0)) || defined(WITH_BACKPORTS)
17100static int __wlan_hdd_cfg80211_tdls_mgmt(struct wiphy *wiphy,
17101 struct net_device *dev,
17102 const u8 *peer, u8 action_code,
17103 u8 dialog_token, u16 status_code,
17104 u32 peer_capability, bool initiator,
17105 const u8 *buf, size_t len)
17106#elif (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 16, 0))
17107static int __wlan_hdd_cfg80211_tdls_mgmt(struct wiphy *wiphy,
17108 struct net_device *dev,
17109 const u8 *peer, u8 action_code,
17110 u8 dialog_token, u16 status_code,
17111 u32 peer_capability, const u8 *buf,
17112 size_t len)
17113#elif (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 15, 0))
17114static int __wlan_hdd_cfg80211_tdls_mgmt(struct wiphy *wiphy,
17115 struct net_device *dev,
17116 u8 *peer, u8 action_code,
17117 u8 dialog_token,
17118 u16 status_code, u32 peer_capability,
17119 const u8 *buf, size_t len)
Sunil Dutt Undekarieacac6f2014-03-21 14:08:53 +053017120#else
Anand N Sunkad9f80b742015-07-30 20:05:51 +053017121static int __wlan_hdd_cfg80211_tdls_mgmt(struct wiphy *wiphy,
17122 struct net_device *dev,
17123 u8 *peer, u8 action_code,
17124 u8 dialog_token,
17125 u16 status_code, const u8 *buf,
17126 size_t len)
17127#endif
Sunil Dutt Undekarieacac6f2014-03-21 14:08:53 +053017128#endif
Mohit Khanna698ba2a2012-12-04 15:08:18 -080017129{
Mahesh A Saptasagar74088392015-02-05 17:22:09 +053017130 hdd_adapter_t *pAdapter;
17131 hdd_context_t *pHddCtx;
Mohit Khanna698ba2a2012-12-04 15:08:18 -080017132 VOS_STATUS status;
Gopichand Nakkala05922802013-03-14 12:23:19 -070017133 int max_sta_failed = 0;
Hoonki Leea34dd892013-02-05 22:56:02 -080017134 int responder;
Hoonki Leed37cbb32013-04-20 00:31:14 -070017135 long rc;
Ganesh Kondabattini862aec92015-01-22 20:58:46 +053017136 int ret;
Masti, Narayanraddi3b681932015-10-08 19:22:25 +053017137 hddTdlsPeer_t *pTdlsPeer;
Anand N Sunkad9bfc2622015-07-30 15:18:54 +053017138#if !(TDLS_MGMT_VERSION2) && (LINUX_VERSION_CODE < KERNEL_VERSION(3,15,0))
Sunil Dutt Undekarieacac6f2014-03-21 14:08:53 +053017139 u32 peer_capability = 0;
17140#endif
Rajesh Chauhana34c6e62014-03-25 16:37:58 +053017141 tANI_U16 numCurrTdlsPeers;
Ganesh Kondabattini8d0d35b2015-08-20 15:39:09 +053017142 hdd_station_ctx_t *pHddStaCtx = NULL;
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053017143
Mahesh A Saptasagar74088392015-02-05 17:22:09 +053017144 pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
17145 if (NULL == pAdapter)
17146 {
17147 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
17148 "%s: Adapter is NULL",__func__);
17149 return -EINVAL;
17150 }
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053017151 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
17152 TRACE_CODE_HDD_CFG80211_TDLS_MGMT,
17153 pAdapter->sessionId, action_code));
Ganesh Kondabattini8d0d35b2015-08-20 15:39:09 +053017154
Mahesh A Saptasagar74088392015-02-05 17:22:09 +053017155 pHddCtx = wiphy_priv(wiphy);
Hoonki Lee11f7dda2013-02-14 16:55:44 -080017156 if (NULL == pHddCtx || NULL == pHddCtx->cfg_ini)
Mohit Khanna698ba2a2012-12-04 15:08:18 -080017157 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053017158 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Mohit Khanna698ba2a2012-12-04 15:08:18 -080017159 "Invalid arguments");
17160 return -EINVAL;
17161 }
Ganesh Kondabattini8d0d35b2015-08-20 15:39:09 +053017162
Sameer Thalappil75ea31a2013-02-21 19:38:16 -080017163 if (pHddCtx->isLogpInProgress)
17164 {
17165 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
17166 "%s:LOGP in Progress. Ignore!!!", __func__);
Atul Mittal115287b2014-07-08 13:26:33 +053017167 wlan_hdd_tdls_set_link_status(pAdapter,
17168 peer,
17169 eTDLS_LINK_IDLE,
17170 eTDLS_LINK_UNSPECIFIED);
Sameer Thalappil75ea31a2013-02-21 19:38:16 -080017171 return -EBUSY;
17172 }
Ganesh Kondabattini8d0d35b2015-08-20 15:39:09 +053017173
Mahesh A Saptasagar74088392015-02-05 17:22:09 +053017174 if (WLAN_HDD_IS_LOAD_UNLOAD_IN_PROGRESS(pHddCtx))
17175 {
17176 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
17177 "%s: Unloading/Loading in Progress. Ignore!!!", __func__);
17178 return -EAGAIN;
17179 }
Ganesh Kondabattini8d0d35b2015-08-20 15:39:09 +053017180
Hoonki Lee27511902013-03-14 18:19:06 -070017181 if (eTDLS_SUPPORT_NOT_ENABLED == pHddCtx->tdls_mode)
Mohit Khanna698ba2a2012-12-04 15:08:18 -080017182 {
Masti, Narayanraddi34e0e562015-03-05 18:23:03 +053017183 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Hoonki Lee27511902013-03-14 18:19:06 -070017184 "%s: TDLS mode is disabled OR not enabled in FW."
17185 MAC_ADDRESS_STR " action %d declined.",
17186 __func__, MAC_ADDR_ARRAY(peer), action_code);
Mohit Khanna698ba2a2012-12-04 15:08:18 -080017187 return -ENOTSUPP;
17188 }
Lee Hoonkic1262f22013-01-24 21:59:00 -080017189
Ganesh Kondabattini8d0d35b2015-08-20 15:39:09 +053017190 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
17191
17192 if( NULL == pHddStaCtx )
17193 {
17194 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
17195 "%s: HDD station context NULL ",__func__);
17196 return -EINVAL;
17197 }
17198
17199 /* STA should be connected and authenticated
17200 * before sending any TDLS frames
17201 */
17202 if ((eConnectionState_Associated != pHddStaCtx->conn_info.connState) ||
17203 (FALSE == pHddStaCtx->conn_info.uIsAuthenticated))
17204 {
17205 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
17206 "STA is not connected or unauthenticated. "
17207 "connState %u, uIsAuthenticated %u",
17208 pHddStaCtx->conn_info.connState,
17209 pHddStaCtx->conn_info.uIsAuthenticated);
17210 return -EAGAIN;
17211 }
17212
Hoonki Lee27511902013-03-14 18:19:06 -070017213 /* other than teardown frame, other mgmt frames are not sent if disabled */
17214 if (SIR_MAC_TDLS_TEARDOWN != action_code)
17215 {
17216 /* if tdls_mode is disabled to respond to peer's request */
17217 if (eTDLS_SUPPORT_DISABLED == pHddCtx->tdls_mode)
17218 {
Masti, Narayanraddi34e0e562015-03-05 18:23:03 +053017219 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Hoonki Lee27511902013-03-14 18:19:06 -070017220 "%s: " MAC_ADDRESS_STR
Gopichand Nakkala34d1b062013-03-19 15:28:33 -070017221 " TDLS mode is disabled. action %d declined.",
17222 __func__, MAC_ADDR_ARRAY(peer), action_code);
Hoonki Lee27511902013-03-14 18:19:06 -070017223
Ganesh Kondabattini8d0d35b2015-08-20 15:39:09 +053017224 return -ENOTSUPP;
Hoonki Lee27511902013-03-14 18:19:06 -070017225 }
Agarwal Ashish4b87f922014-06-18 03:03:21 +053017226
17227 if (vos_max_concurrent_connections_reached())
17228 {
17229 hddLog(VOS_TRACE_LEVEL_INFO, FL("Reached max concurrent connections"));
17230 return -EINVAL;
17231 }
Hoonki Lee27511902013-03-14 18:19:06 -070017232 }
17233
Gopichand Nakkalab977a972013-02-18 19:15:09 -080017234 if (WLAN_IS_TDLS_SETUP_ACTION(action_code))
17235 {
Pradeep Reddy POTTETI9db32f02015-01-29 15:22:54 +053017236 if (NULL != wlan_hdd_tdls_is_progress(pHddCtx, peer, TRUE, TRUE))
Gopichand Nakkalab977a972013-02-18 19:15:09 -080017237 {
17238 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Gopichand Nakkalac87400e2013-03-13 18:51:00 -070017239 "%s: " MAC_ADDRESS_STR
Gopichand Nakkala34d1b062013-03-19 15:28:33 -070017240 " TDLS setup is ongoing. action %d declined.",
17241 __func__, MAC_ADDR_ARRAY(peer), action_code);
17242 return -EPERM;
Gopichand Nakkalab977a972013-02-18 19:15:09 -080017243 }
17244 }
17245
Hoonki Lee11f7dda2013-02-14 16:55:44 -080017246 if (SIR_MAC_TDLS_SETUP_REQ == action_code ||
17247 SIR_MAC_TDLS_SETUP_RSP == action_code )
Lee Hoonkic1262f22013-01-24 21:59:00 -080017248 {
Rajesh Chauhana34c6e62014-03-25 16:37:58 +053017249 numCurrTdlsPeers = wlan_hdd_tdlsConnectedPeers(pAdapter);
17250 if (HDD_MAX_NUM_TDLS_STA <= numCurrTdlsPeers)
Lee Hoonkic1262f22013-01-24 21:59:00 -080017251 {
17252 /* supplicant still sends tdls_mgmt(SETUP_REQ) even after
17253 we return error code at 'add_station()'. Hence we have this
17254 check again in addtion to add_station().
17255 Anyway, there is no hard to double-check. */
Hoonki Lee11f7dda2013-02-14 16:55:44 -080017256 if (SIR_MAC_TDLS_SETUP_REQ == action_code)
Lee Hoonkic1262f22013-01-24 21:59:00 -080017257 {
Gopichand Nakkalac87400e2013-03-13 18:51:00 -070017258 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
17259 "%s: " MAC_ADDRESS_STR
Rajesh Chauhana34c6e62014-03-25 16:37:58 +053017260 " TDLS Max peer already connected. action (%d) declined. Num of peers (%d), Max allowed (%d).",
17261 __func__, MAC_ADDR_ARRAY(peer), action_code,
17262 numCurrTdlsPeers, HDD_MAX_NUM_TDLS_STA);
Sunil Dutt388ac8f2013-11-28 18:06:52 +053017263 return -EINVAL;
Lee Hoonkic1262f22013-01-24 21:59:00 -080017264 }
17265 else
17266 {
Gopichand Nakkalab977a972013-02-18 19:15:09 -080017267 /* maximum reached. tweak to send error code to peer and return
17268 error code to supplicant */
Lee Hoonkic1262f22013-01-24 21:59:00 -080017269 status_code = eSIR_MAC_UNSPEC_FAILURE_STATUS;
Gopichand Nakkalac87400e2013-03-13 18:51:00 -070017270 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
17271 "%s: " MAC_ADDRESS_STR
Rajesh Chauhana34c6e62014-03-25 16:37:58 +053017272 " TDLS Max peer already connected, send response status (%d). Num of peers (%d), Max allowed (%d).",
17273 __func__, MAC_ADDR_ARRAY(peer), status_code,
17274 numCurrTdlsPeers, HDD_MAX_NUM_TDLS_STA);
Gopichand Nakkala05922802013-03-14 12:23:19 -070017275 max_sta_failed = -EPERM;
Gopichand Nakkalab977a972013-02-18 19:15:09 -080017276 /* fall through to send setup resp with failure status
17277 code */
Lee Hoonkic1262f22013-01-24 21:59:00 -080017278 }
17279 }
Hoonki Lee11f7dda2013-02-14 16:55:44 -080017280 else
17281 {
Masti, Narayanraddi6b93b472015-09-04 17:48:11 +053017282 mutex_lock(&pHddCtx->tdls_lock);
17283 pTdlsPeer = wlan_hdd_tdls_find_peer(pAdapter, peer, FALSE);
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -070017284 if (pTdlsPeer && TDLS_IS_CONNECTED(pTdlsPeer))
Hoonki Lee11f7dda2013-02-14 16:55:44 -080017285 {
Masti, Narayanraddi6b93b472015-09-04 17:48:11 +053017286 mutex_unlock(&pHddCtx->tdls_lock);
Gopichand Nakkalac87400e2013-03-13 18:51:00 -070017287 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Gopichand Nakkala34d1b062013-03-19 15:28:33 -070017288 "%s:" MAC_ADDRESS_STR " already connected. action %d declined.",
17289 __func__, MAC_ADDR_ARRAY(peer), action_code);
Hoonki Lee11f7dda2013-02-14 16:55:44 -080017290 return -EPERM;
17291 }
Masti, Narayanraddi6b93b472015-09-04 17:48:11 +053017292 mutex_unlock(&pHddCtx->tdls_lock);
Hoonki Lee11f7dda2013-02-14 16:55:44 -080017293 }
Lee Hoonkic1262f22013-01-24 21:59:00 -080017294 }
Mohit Khanna698ba2a2012-12-04 15:08:18 -080017295
Masti, Narayanraddi34e0e562015-03-05 18:23:03 +053017296 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Arun Kumar Khandavalli9fb625e2014-03-17 16:07:40 +053017297 "%s: " MAC_ADDRESS_STR " action %d, dialog_token %d status %d, len = %zu",
Gopichand Nakkalac87400e2013-03-13 18:51:00 -070017298 "tdls_mgmt", MAC_ADDR_ARRAY(peer),
17299 action_code, dialog_token, status_code, len);
Mohit Khanna698ba2a2012-12-04 15:08:18 -080017300
Hoonki Leea34dd892013-02-05 22:56:02 -080017301 /*Except teardown responder will not be used so just make 0*/
17302 responder = 0;
Hoonki Lee11f7dda2013-02-14 16:55:44 -080017303 if (SIR_MAC_TDLS_TEARDOWN == action_code)
Hoonki Leea34dd892013-02-05 22:56:02 -080017304 {
Gopichand Nakkala97a65fd2013-04-16 16:59:38 -070017305
Masti, Narayanraddi6b93b472015-09-04 17:48:11 +053017306 mutex_lock(&pHddCtx->tdls_lock);
17307 pTdlsPeer = wlan_hdd_tdls_find_peer(pAdapter, peer, FALSE);
Gopichand Nakkala97a65fd2013-04-16 16:59:38 -070017308
17309 if(pTdlsPeer && TDLS_IS_CONNECTED(pTdlsPeer))
17310 responder = pTdlsPeer->is_responder;
17311 else
Hoonki Leea34dd892013-02-05 22:56:02 -080017312 {
Gopichand Nakkala97a65fd2013-04-16 16:59:38 -070017313 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Arun Kumar Khandavalli9fb625e2014-03-17 16:07:40 +053017314 "%s: " MAC_ADDRESS_STR " peer doesn't exist or not connected %d dialog_token %d status %d, len = %zu",
Gopichand Nakkala97a65fd2013-04-16 16:59:38 -070017315 __func__, MAC_ADDR_ARRAY(peer), (NULL == pTdlsPeer) ? -1 : pTdlsPeer->link_status,
17316 dialog_token, status_code, len);
Masti, Narayanraddi6b93b472015-09-04 17:48:11 +053017317 mutex_unlock(&pHddCtx->tdls_lock);
Gopichand Nakkala97a65fd2013-04-16 16:59:38 -070017318 return -EPERM;
Hoonki Leea34dd892013-02-05 22:56:02 -080017319 }
Masti, Narayanraddi6b93b472015-09-04 17:48:11 +053017320 mutex_unlock(&pHddCtx->tdls_lock);
Mohit Khanna698ba2a2012-12-04 15:08:18 -080017321 }
Mohit Khanna698ba2a2012-12-04 15:08:18 -080017322
Masti, Narayanraddi3b681932015-10-08 19:22:25 +053017323 /* Discard TDLS setup if peer is removed by user app */
17324 if ((pHddCtx->cfg_ini->fTDLSExternalControl) &&
17325 ((SIR_MAC_TDLS_SETUP_REQ == action_code) ||
17326 (SIR_MAC_TDLS_SETUP_CNF == action_code) ||
17327 (SIR_MAC_TDLS_DIS_REQ == action_code))) {
17328
17329 mutex_lock(&pHddCtx->tdls_lock);
17330 pTdlsPeer = wlan_hdd_tdls_find_peer(pAdapter, peer, FALSE);
17331 if (pTdlsPeer && (FALSE == pTdlsPeer->isForcedPeer)) {
17332 mutex_unlock(&pHddCtx->tdls_lock);
17333 hddLog(LOGE, FL("TDLS External Control enabled, but peer "
17334 MAC_ADDRESS_STR " is not forced, so reject the action code %d"),
17335 MAC_ADDR_ARRAY(peer), action_code);
17336 return -EINVAL;
17337 }
17338 mutex_unlock(&pHddCtx->tdls_lock);
17339 }
17340
Gopichand Nakkala2f1ff152013-07-01 11:27:43 +053017341 /* For explicit trigger of DIS_REQ come out of BMPS for
17342 successfully receiving DIS_RSP from peer. */
Hoonki Lee14621352013-04-16 17:51:19 -070017343 if ((SIR_MAC_TDLS_SETUP_RSP == action_code) ||
Gopichand Nakkala2f1ff152013-07-01 11:27:43 +053017344 (SIR_MAC_TDLS_DIS_RSP == action_code) ||
17345 (SIR_MAC_TDLS_DIS_REQ == action_code))
Hoonki Lee14621352013-04-16 17:51:19 -070017346 {
17347 if (TRUE == sme_IsPmcBmps(WLAN_HDD_GET_HAL_CTX(pAdapter)))
17348 {
Masti, Narayanraddi34e0e562015-03-05 18:23:03 +053017349 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Gopichand Nakkala2f1ff152013-07-01 11:27:43 +053017350 "%s: Sending frame action_code %u.Disable BMPS", __func__, action_code);
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053017351 status = hdd_disable_bmps_imps(pHddCtx, WLAN_HDD_INFRA_STATION);
17352 if (status != VOS_STATUS_SUCCESS) {
17353 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Failed to set BMPS/IMPS"));
17354 }
Hoonki Lee14621352013-04-16 17:51:19 -070017355 }
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053017356 if (SIR_MAC_TDLS_DIS_REQ != action_code) {
Anand N Sunkad9bfc2622015-07-30 15:18:54 +053017357 if (0 != wlan_hdd_tdls_set_cap(pAdapter, peer, eTDLS_CAP_SUPPORTED)) {
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053017358 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Failed to set TDLS capabilities"));
17359 }
17360 }
Hoonki Lee14621352013-04-16 17:51:19 -070017361 }
17362
Hoonki Lee5305c3a2013-04-29 23:28:59 -070017363 /* make sure doesn't call send_mgmt() while it is pending */
17364 if (TDLS_CTX_MAGIC == pAdapter->mgmtTxCompletionStatus)
17365 {
17366 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Arif Hussain6d2a3322013-11-17 19:50:10 -080017367 "%s: " MAC_ADDRESS_STR " action %d couldn't sent, as one is pending. return EBUSY",
Hoonki Lee5305c3a2013-04-29 23:28:59 -070017368 __func__, MAC_ADDR_ARRAY(peer), action_code);
Ganesh Kondabattini862aec92015-01-22 20:58:46 +053017369 ret = -EBUSY;
17370 goto tx_failed;
Hoonki Lee5305c3a2013-04-29 23:28:59 -070017371 }
17372
17373 pAdapter->mgmtTxCompletionStatus = TDLS_CTX_MAGIC;
Gopichand Nakkalab977a972013-02-18 19:15:09 -080017374 INIT_COMPLETION(pAdapter->tdls_mgmt_comp);
17375
Ganesh Kondabattini8d0d35b2015-08-20 15:39:09 +053017376 status = sme_SendTdlsMgmtFrame(WLAN_HDD_GET_HAL_CTX(pAdapter),
17377 pAdapter->sessionId, peer, action_code, dialog_token,
17378 status_code, peer_capability, (tANI_U8 *)buf, len,
17379 responder);
Mohit Khanna698ba2a2012-12-04 15:08:18 -080017380
Gopichand Nakkalab977a972013-02-18 19:15:09 -080017381 if (VOS_STATUS_SUCCESS != status)
17382 {
Mohit Khanna698ba2a2012-12-04 15:08:18 -080017383 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
17384 "%s: sme_SendTdlsMgmtFrame failed!", __func__);
Hoonki Lee5305c3a2013-04-29 23:28:59 -070017385 pAdapter->mgmtTxCompletionStatus = FALSE;
Ganesh Kondabattini862aec92015-01-22 20:58:46 +053017386 ret = -EINVAL;
17387 goto tx_failed;
Mohit Khanna698ba2a2012-12-04 15:08:18 -080017388 }
17389
Ganesh Kondabattini8d0d35b2015-08-20 15:39:09 +053017390 if ((SIR_MAC_TDLS_DIS_REQ == action_code) ||
17391 (SIR_MAC_TDLS_DIS_RSP == action_code))
17392 {
17393 /* for DIS_REQ/DIS_RSP, supplicant don't consider the return status.
17394 * So we no need to wait for tdls_mgmt_comp for sending ack status.
17395 */
17396 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
17397 "%s: tx done for frm %u", __func__, action_code);
17398 return 0;
17399 }
17400
17401 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
17402 "%s: Wait for tdls_mgmt_comp. Timeout %u ms", __func__,
17403 WAIT_TIME_TDLS_MGMT);
17404
Hoonki Leed37cbb32013-04-20 00:31:14 -070017405 rc = wait_for_completion_interruptible_timeout(&pAdapter->tdls_mgmt_comp,
17406 msecs_to_jiffies(WAIT_TIME_TDLS_MGMT));
17407
17408 if ((rc <= 0) || (TRUE != pAdapter->mgmtTxCompletionStatus))
Gopichand Nakkalab977a972013-02-18 19:15:09 -080017409 {
Hoonki Leed37cbb32013-04-20 00:31:14 -070017410 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Jeff Johnson0299d0a2013-10-30 12:37:43 -070017411 "%s: Mgmt Tx Completion failed status %ld TxCompletion %u",
Hoonki Leed37cbb32013-04-20 00:31:14 -070017412 __func__, rc, pAdapter->mgmtTxCompletionStatus);
Hoonki Lee5305c3a2013-04-29 23:28:59 -070017413 pAdapter->mgmtTxCompletionStatus = FALSE;
Yue Ma4f55ef32014-01-23 16:45:33 -080017414
17415 if (pHddCtx->isLogpInProgress)
17416 {
17417 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
17418 "%s: LOGP in Progress. Ignore!!!", __func__);
17419 return -EAGAIN;
17420 }
Abhishek Singh837adf22015-10-01 17:37:37 +053017421 if (rc <= 0)
17422 vos_fatal_event_logs_req(WLAN_LOG_TYPE_FATAL,
17423 WLAN_LOG_INDICATOR_HOST_DRIVER,
17424 WLAN_LOG_REASON_HDD_TIME_OUT,
17425 TRUE, TRUE);
Yue Ma4f55ef32014-01-23 16:45:33 -080017426
Ganesh Kondabattini862aec92015-01-22 20:58:46 +053017427 ret = -EINVAL;
17428 goto tx_failed;
Gopichand Nakkalab977a972013-02-18 19:15:09 -080017429 }
Ganesh Kondabattini8d0d35b2015-08-20 15:39:09 +053017430 else
17431 {
17432 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
17433 "%s: Mgmt Tx Completion status %ld TxCompletion %u",
17434 __func__, rc, pAdapter->mgmtTxCompletionStatus);
17435 }
Gopichand Nakkalab977a972013-02-18 19:15:09 -080017436
Gopichand Nakkala05922802013-03-14 12:23:19 -070017437 if (max_sta_failed)
Hoonki Lee14621352013-04-16 17:51:19 -070017438 {
Ganesh Kondabattini862aec92015-01-22 20:58:46 +053017439 ret = max_sta_failed;
17440 goto tx_failed;
Hoonki Lee14621352013-04-16 17:51:19 -070017441 }
Gopichand Nakkalab977a972013-02-18 19:15:09 -080017442
Hoonki Leea34dd892013-02-05 22:56:02 -080017443 if (SIR_MAC_TDLS_SETUP_RSP == action_code)
17444 {
Anand N Sunkad9bfc2622015-07-30 15:18:54 +053017445 if (0 != wlan_hdd_tdls_set_responder(pAdapter, peer, TRUE)) {
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053017446 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Failed to set TDLS responder: Setup Response"));
17447 }
Hoonki Leea34dd892013-02-05 22:56:02 -080017448 }
17449 else if (SIR_MAC_TDLS_SETUP_CNF == action_code)
17450 {
Anand N Sunkad9bfc2622015-07-30 15:18:54 +053017451 if (0 != wlan_hdd_tdls_set_responder(pAdapter, peer, FALSE)) {
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053017452 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Failed to set TDLS responder: Setup Response"));
17453 }
Hoonki Leea34dd892013-02-05 22:56:02 -080017454 }
Mohit Khanna698ba2a2012-12-04 15:08:18 -080017455
17456 return 0;
Ganesh Kondabattini862aec92015-01-22 20:58:46 +053017457
17458tx_failed:
17459 /* add_station will be called before sending TDLS_SETUP_REQ and
17460 * TDLS_SETUP_RSP and as part of add_station driver will enable
17461 * BMPS. NL80211_TDLS_DISABLE_LINK will be called if the tx of
17462 * TDLS_SETUP_REQ or TDLS_SETUP_RSP fails. BMPS will be enabled
17463 * as part of processing NL80211_TDLS_DISABLE_LINK. So need to
17464 * enable BMPS for TDLS_SETUP_REQ and TDLS_SETUP_RSP if tx fails.
17465 */
17466
17467 if ((SIR_MAC_TDLS_SETUP_REQ == action_code) ||
17468 (SIR_MAC_TDLS_SETUP_RSP == action_code))
17469 wlan_hdd_tdls_check_bmps(pAdapter);
17470 return ret;
Mohit Khanna698ba2a2012-12-04 15:08:18 -080017471}
17472
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053017473#if TDLS_MGMT_VERSION2
17474static int wlan_hdd_cfg80211_tdls_mgmt(struct wiphy *wiphy, struct net_device *dev,
17475 u8 *peer, u8 action_code, u8 dialog_token,
17476 u16 status_code, u32 peer_capability,
17477 const u8 *buf, size_t len)
Anand N Sunkad9bfc2622015-07-30 15:18:54 +053017478#else /* TDLS_MGMT_VERSION2 */
17479#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,17,0))
17480static int wlan_hdd_cfg80211_tdls_mgmt(struct wiphy *wiphy,
17481 struct net_device *dev,
17482 const u8 *peer, u8 action_code,
17483 u8 dialog_token, u16 status_code,
17484 u32 peer_capability, bool initiator,
17485 const u8 *buf, size_t len)
17486#elif (LINUX_VERSION_CODE >= KERNEL_VERSION(3,16,0))
17487static int wlan_hdd_cfg80211_tdls_mgmt(struct wiphy *wiphy,
17488 struct net_device *dev,
17489 const u8 *peer, u8 action_code,
17490 u8 dialog_token, u16 status_code,
17491 u32 peer_capability, const u8 *buf,
17492 size_t len)
17493#elif (LINUX_VERSION_CODE >= KERNEL_VERSION(3,15,0))
17494static int wlan_hdd_cfg80211_tdls_mgmt(struct wiphy *wiphy,
17495 struct net_device *dev,
17496 u8 *peer, u8 action_code,
17497 u8 dialog_token,
17498 u16 status_code, u32 peer_capability,
17499 const u8 *buf, size_t len)
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053017500#else
17501static int wlan_hdd_cfg80211_tdls_mgmt(struct wiphy *wiphy, struct net_device *dev,
17502 u8 *peer, u8 action_code, u8 dialog_token,
17503 u16 status_code, const u8 *buf, size_t len)
17504#endif
Anand N Sunkad9bfc2622015-07-30 15:18:54 +053017505#endif
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053017506{
17507 int ret;
17508
Anand N Sunkad9f80b742015-07-30 20:05:51 +053017509 vos_ssr_protect(__func__);
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053017510#if TDLS_MGMT_VERSION2
Anand N Sunkad9f80b742015-07-30 20:05:51 +053017511 ret = __wlan_hdd_cfg80211_tdls_mgmt(wiphy, dev, peer, action_code,
17512 dialog_token, status_code,
17513 peer_capability, buf, len);
17514#else /* TDLS_MGMT_VERSION2 */
17515#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 17, 0)) || defined(WITH_BACKPORTS)
17516 ret = __wlan_hdd_cfg80211_tdls_mgmt(wiphy, dev, peer, action_code,
17517 dialog_token, status_code,
17518 peer_capability, initiator,
17519 buf, len);
17520#elif (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 16, 0))
17521 ret = __wlan_hdd_cfg80211_tdls_mgmt(wiphy, dev, peer, action_code,
17522 dialog_token, status_code,
17523 peer_capability, buf, len);
17524#elif (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 15, 0))
17525 ret = __wlan_hdd_cfg80211_tdls_mgmt(wiphy, dev, peer, action_code,
17526 dialog_token, status_code,
17527 peer_capability, buf, len);
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053017528#else
Anand N Sunkad9f80b742015-07-30 20:05:51 +053017529 ret = __wlan_hdd_cfg80211_tdls_mgmt(wiphy, dev, peer, action_code,
17530 dialog_token, status_code, buf, len);
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053017531#endif
Anand N Sunkad9f80b742015-07-30 20:05:51 +053017532#endif
17533 vos_ssr_unprotect(__func__);
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053017534
Anand N Sunkad9f80b742015-07-30 20:05:51 +053017535 return ret;
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053017536}
Atul Mittal115287b2014-07-08 13:26:33 +053017537
17538int wlan_hdd_tdls_extctrl_config_peer(hdd_adapter_t *pAdapter,
Anand N Sunkad9bfc2622015-07-30 15:18:54 +053017539#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,18,0))
17540 const u8 *peer,
17541#else
Atul Mittal115287b2014-07-08 13:26:33 +053017542 u8 *peer,
Anand N Sunkad9bfc2622015-07-30 15:18:54 +053017543#endif
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053017544 tdls_req_params_t *tdls_peer_params,
Atul Mittal115287b2014-07-08 13:26:33 +053017545 cfg80211_exttdls_callback callback)
17546{
17547
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053017548 hddTdlsPeer_t *pTdlsPeer = NULL;
Atul Mittal115287b2014-07-08 13:26:33 +053017549 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Pradeep Reddy POTTETIe30ed252015-02-18 14:27:55 +053017550 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
Atul Mittal115287b2014-07-08 13:26:33 +053017551 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
17552 " %s : NL80211_TDLS_SETUP for " MAC_ADDRESS_STR,
17553 __func__, MAC_ADDR_ARRAY(peer));
17554
17555 if ( (FALSE == pHddCtx->cfg_ini->fTDLSExternalControl) ||
17556 (FALSE == pHddCtx->cfg_ini->fEnableTDLSImplicitTrigger) ) {
17557
17558 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053017559 " %s TDLS External control (%d) and Implicit Trigger (%d) not enabled ",
17560 __func__, pHddCtx->cfg_ini->fTDLSExternalControl,
17561 pHddCtx->cfg_ini->fEnableTDLSImplicitTrigger);
Atul Mittal115287b2014-07-08 13:26:33 +053017562 return -ENOTSUPP;
17563 }
17564
17565 /* To cater the requirement of establishing the TDLS link
17566 * irrespective of the data traffic , get an entry of TDLS peer.
17567 */
Masti, Narayanraddi6dbcdbb2015-05-13 10:28:06 +053017568 mutex_lock(&pHddCtx->tdls_lock);
Atul Mittal115287b2014-07-08 13:26:33 +053017569 pTdlsPeer = wlan_hdd_tdls_get_peer(pAdapter, peer);
17570 if (pTdlsPeer == NULL) {
17571 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
17572 "%s: peer " MAC_ADDRESS_STR " not existing",
17573 __func__, MAC_ADDR_ARRAY(peer));
Masti, Narayanraddi6dbcdbb2015-05-13 10:28:06 +053017574 mutex_unlock(&pHddCtx->tdls_lock);
Atul Mittal115287b2014-07-08 13:26:33 +053017575 return -EINVAL;
17576 }
17577
Pradeep Reddy POTTETI60ad2402015-02-26 16:48:21 +053017578 /* check FW TDLS Off Channel capability */
17579 if ((TRUE == sme_IsFeatureSupportedByFW(TDLS_OFF_CHANNEL)) &&
Pradeep Reddy POTTETI0cb99bc2015-06-08 12:59:09 +053017580 (TRUE == pHddCtx->cfg_ini->fEnableTDLSOffChannel) &&
Pradeep Reddy POTTETI60ad2402015-02-26 16:48:21 +053017581 (NULL != tdls_peer_params))
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053017582 {
17583 pTdlsPeer->peerParams.channel = tdls_peer_params->channel;
17584 pTdlsPeer->peerParams.global_operating_class =
17585 tdls_peer_params->global_operating_class;
17586 pTdlsPeer->peerParams.max_latency_ms = tdls_peer_params->max_latency_ms;
17587 pTdlsPeer->peerParams.min_bandwidth_kbps =
17588 tdls_peer_params->min_bandwidth_kbps;
Pradeep Reddy POTTETIe30ed252015-02-18 14:27:55 +053017589 /* check configured channel is valid, non dfs and
17590 * not current operating channel */
17591 if ((sme_IsTdlsOffChannelValid(WLAN_HDD_GET_HAL_CTX(pAdapter),
17592 tdls_peer_params->channel)) &&
17593 (pHddStaCtx) &&
17594 (tdls_peer_params->channel !=
17595 pHddStaCtx->conn_info.operationChannel))
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053017596 {
17597 pTdlsPeer->isOffChannelConfigured = TRUE;
17598 }
17599 else
17600 {
17601 pTdlsPeer->isOffChannelConfigured = FALSE;
17602 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
17603 "%s: Configured Tdls Off Channel is not valid", __func__);
17604
17605 }
17606 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Pradeep Reddy POTTETIe30ed252015-02-18 14:27:55 +053017607 "%s: tdls_off_channel %d isOffChannelConfigured %d "
17608 "current operating channel %d",
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053017609 __func__, pTdlsPeer->peerParams.channel,
Pradeep Reddy POTTETIe30ed252015-02-18 14:27:55 +053017610 pTdlsPeer->isOffChannelConfigured,
17611 (pHddStaCtx ? pHddStaCtx->conn_info.operationChannel : 0));
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053017612 }
17613 else
17614 {
17615 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Pradeep Reddy POTTETI0cb99bc2015-06-08 12:59:09 +053017616 "%s: TDLS off channel FW capability %d, "
17617 "host capab %d or Invalid TDLS Peer Params", __func__,
17618 sme_IsFeatureSupportedByFW(TDLS_OFF_CHANNEL),
17619 pHddCtx->cfg_ini->fEnableTDLSOffChannel);
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053017620 }
17621
Atul Mittal115287b2014-07-08 13:26:33 +053017622 if ( 0 != wlan_hdd_tdls_set_force_peer(pAdapter, peer, TRUE) ) {
17623
Masti, Narayanraddi6b93b472015-09-04 17:48:11 +053017624 mutex_unlock(&pHddCtx->tdls_lock);
17625
Atul Mittal115287b2014-07-08 13:26:33 +053017626 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
17627 " %s TDLS Add Force Peer Failed",
17628 __func__);
17629 return -EINVAL;
17630 }
17631 /*EXT TDLS*/
17632
17633 if ( 0 != wlan_hdd_set_callback(pTdlsPeer, callback) ) {
Masti, Narayanraddi6b93b472015-09-04 17:48:11 +053017634 mutex_unlock(&pHddCtx->tdls_lock);
Atul Mittal115287b2014-07-08 13:26:33 +053017635 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
17636 " %s TDLS set callback Failed",
17637 __func__);
17638 return -EINVAL;
17639 }
17640
Masti, Narayanraddi6b93b472015-09-04 17:48:11 +053017641 mutex_unlock(&pHddCtx->tdls_lock);
17642
Atul Mittal115287b2014-07-08 13:26:33 +053017643 return(0);
17644
17645}
17646
Anand N Sunkad9bfc2622015-07-30 15:18:54 +053017647int wlan_hdd_tdls_extctrl_deconfig_peer(hdd_adapter_t *pAdapter,
17648#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,18,0))
17649 const u8 *peer
17650#else
17651 u8 *peer
17652#endif
17653)
Atul Mittal115287b2014-07-08 13:26:33 +053017654{
17655
17656 hddTdlsPeer_t *pTdlsPeer;
17657 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
17658 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
17659 " %s : NL80211_TDLS_TEARDOWN for " MAC_ADDRESS_STR,
17660 __func__, MAC_ADDR_ARRAY(peer));
17661
Chandrasekaran, Manishekar41b8e1f2015-03-10 13:30:28 +053017662 if (0 != wlan_hdd_validate_context(pHddCtx)) {
17663 hddLog(VOS_TRACE_LEVEL_ERROR, FL("HDD context is NULL"));
17664 return -EINVAL;
17665 }
17666
Atul Mittal115287b2014-07-08 13:26:33 +053017667 if ( (FALSE == pHddCtx->cfg_ini->fTDLSExternalControl) ||
17668 (FALSE == pHddCtx->cfg_ini->fEnableTDLSImplicitTrigger) ) {
17669
17670 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053017671 " %s TDLS External control (%d) and Implicit Trigger (%d) not enabled ",
17672 __func__, pHddCtx->cfg_ini->fTDLSExternalControl,
17673 pHddCtx->cfg_ini->fEnableTDLSImplicitTrigger);
Atul Mittal115287b2014-07-08 13:26:33 +053017674 return -ENOTSUPP;
17675 }
17676
Masti, Narayanraddi6b93b472015-09-04 17:48:11 +053017677 mutex_lock(&pHddCtx->tdls_lock);
17678 pTdlsPeer = wlan_hdd_tdls_find_peer(pAdapter, peer, FALSE);
Atul Mittal115287b2014-07-08 13:26:33 +053017679
17680 if ( NULL == pTdlsPeer ) {
Masti, Narayanraddi6b93b472015-09-04 17:48:11 +053017681 mutex_unlock(&pHddCtx->tdls_lock);
Atul Mittal115287b2014-07-08 13:26:33 +053017682 hddLog(VOS_TRACE_LEVEL_INFO, "%s: " MAC_ADDRESS_STR
Agarwal Ashisha7ef41d2015-06-25 18:00:26 +053017683 " peer not existing",
Atul Mittal115287b2014-07-08 13:26:33 +053017684 __func__, MAC_ADDR_ARRAY(peer));
17685 return -EINVAL;
17686 }
17687 else {
17688 wlan_hdd_tdls_indicate_teardown(pAdapter, pTdlsPeer,
17689 eSIR_MAC_TDLS_TEARDOWN_UNSPEC_REASON);
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053017690 /* if channel switch is configured, reset
17691 the channel for this peer */
17692 if (TRUE == pTdlsPeer->isOffChannelConfigured)
17693 {
17694 pTdlsPeer->peerParams.channel = 0;
17695 pTdlsPeer->isOffChannelConfigured = FALSE;
17696 }
Atul Mittal115287b2014-07-08 13:26:33 +053017697 }
17698
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053017699 if ( 0 != wlan_hdd_tdls_set_force_peer(pAdapter, peer, FALSE) ) {
Masti, Narayanraddi6b93b472015-09-04 17:48:11 +053017700 mutex_unlock(&pHddCtx->tdls_lock);
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053017701 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Failed to set force peer"));
Atul Mittal115287b2014-07-08 13:26:33 +053017702 return -EINVAL;
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053017703 }
Atul Mittal115287b2014-07-08 13:26:33 +053017704
17705 /*EXT TDLS*/
17706
17707 if ( 0 != wlan_hdd_set_callback(pTdlsPeer, NULL )) {
Masti, Narayanraddi6b93b472015-09-04 17:48:11 +053017708 mutex_unlock(&pHddCtx->tdls_lock);
Atul Mittal115287b2014-07-08 13:26:33 +053017709 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
17710 " %s TDLS set callback Failed",
17711 __func__);
17712 return -EINVAL;
17713 }
Atul Mittal115287b2014-07-08 13:26:33 +053017714
Masti, Narayanraddi6b93b472015-09-04 17:48:11 +053017715 mutex_unlock(&pHddCtx->tdls_lock);
17716
17717 return(0);
Atul Mittal115287b2014-07-08 13:26:33 +053017718}
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053017719static int __wlan_hdd_cfg80211_tdls_oper(struct wiphy *wiphy, struct net_device *dev,
Anand N Sunkad9bfc2622015-07-30 15:18:54 +053017720#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,18,0))
17721 const u8 *peer,
17722#else
17723 u8 *peer,
17724#endif
17725 enum nl80211_tdls_operation oper)
Mohit Khanna698ba2a2012-12-04 15:08:18 -080017726{
17727 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
17728 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053017729 int status;
Hoonki Lee5305c3a2013-04-29 23:28:59 -070017730 hddTdlsPeer_t *pTdlsPeer;
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053017731
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053017732 ENTER();
17733
Chandrasekaran, Manishekar41b8e1f2015-03-10 13:30:28 +053017734 if (!pAdapter) {
17735 hddLog(VOS_TRACE_LEVEL_ERROR, FL("HDD adpater is NULL"));
17736 return -EINVAL;
17737 }
17738
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053017739 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
17740 TRACE_CODE_HDD_CFG80211_TDLS_OPER,
17741 pAdapter->sessionId, oper));
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053017742 if ( NULL == peer )
Mohit Khanna698ba2a2012-12-04 15:08:18 -080017743 {
Gopichand Nakkalab977a972013-02-18 19:15:09 -080017744 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Chilam Ngc4244af2013-04-01 15:37:32 -070017745 "%s: Invalid arguments", __func__);
Mohit Khanna698ba2a2012-12-04 15:08:18 -080017746 return -EINVAL;
17747 }
Hoonki Lee1090c6a2013-01-16 17:40:54 -080017748
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053017749 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053017750 if (0 != status)
Sameer Thalappil75ea31a2013-02-21 19:38:16 -080017751 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053017752 return status;
Sameer Thalappil75ea31a2013-02-21 19:38:16 -080017753 }
17754
Mohit Khanna698ba2a2012-12-04 15:08:18 -080017755
17756 if( FALSE == pHddCtx->cfg_ini->fEnableTDLSSupport ||
Hoonki Lee1090c6a2013-01-16 17:40:54 -080017757 FALSE == sme_IsFeatureSupportedByFW(TDLS))
Mohit Khanna698ba2a2012-12-04 15:08:18 -080017758 {
Hoonki Lee1090c6a2013-01-16 17:40:54 -080017759 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053017760 "TDLS Disabled in INI (%d) OR not enabled in FW (%d) "
17761 "Cannot process TDLS commands",
17762 pHddCtx->cfg_ini->fEnableTDLSSupport,
17763 sme_IsFeatureSupportedByFW(TDLS));
Mohit Khanna698ba2a2012-12-04 15:08:18 -080017764 return -ENOTSUPP;
17765 }
17766
17767 switch (oper) {
17768 case NL80211_TDLS_ENABLE_LINK:
17769 {
Mohit Khanna698ba2a2012-12-04 15:08:18 -080017770 VOS_STATUS status;
c_hpothu6ff1c3c2013-10-01 19:01:57 +053017771 long ret;
Gopichand Nakkala79ff85d2013-05-27 17:05:29 +053017772 tCsrTdlsLinkEstablishParams tdlsLinkEstablishParams;
Agarwal Ashish16020c42014-12-29 22:01:11 +053017773 WLAN_STADescType staDesc;
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053017774 tANI_U16 numCurrTdlsPeers = 0;
17775 hddTdlsPeer_t *connPeer = NULL;
Pradeep Reddy POTTETIfcac7902015-04-16 12:25:17 +053017776 tANI_U8 suppChannelLen = 0;
Mohit Khanna698ba2a2012-12-04 15:08:18 -080017777
Agarwal Ashisha7ef41d2015-06-25 18:00:26 +053017778 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
17779 " %s : NL80211_TDLS_ENABLE_LINK for " MAC_ADDRESS_STR,
17780 __func__, MAC_ADDR_ARRAY(peer));
Masti, Narayanraddi6b93b472015-09-04 17:48:11 +053017781
Sunil Dutt41de4e22013-11-14 18:09:02 +053017782 pTdlsPeer = wlan_hdd_tdls_find_peer(pAdapter, peer, TRUE);
Agarwal Ashish16020c42014-12-29 22:01:11 +053017783 memset(&staDesc, 0, sizeof(staDesc));
Sunil Dutt41de4e22013-11-14 18:09:02 +053017784 if ( NULL == pTdlsPeer ) {
17785 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: " MAC_ADDRESS_STR
17786 " (oper %d) not exsting. ignored",
17787 __func__, MAC_ADDR_ARRAY(peer), (int)oper);
17788 return -EINVAL;
17789 }
17790
17791 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
17792 "%s: " MAC_ADDRESS_STR " link_status %d (%s) ", "tdls_oper",
17793 MAC_ADDR_ARRAY(peer), pTdlsPeer->link_status,
17794 "NL80211_TDLS_ENABLE_LINK");
17795
Gopichand Nakkala2f4a2822013-04-17 11:22:01 -070017796 if (!TDLS_STA_INDEX_VALID(pTdlsPeer->staId))
17797 {
17798 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Invalid Staion Index %u "
17799 MAC_ADDRESS_STR " failed",
17800 __func__, pTdlsPeer->staId, MAC_ADDR_ARRAY(peer));
17801 return -EINVAL;
17802 }
17803
Pradeep Reddy POTTETIf3148e82015-04-16 12:10:33 +053017804 /* before starting tdls connection, set tdls
17805 * off channel established status to default value */
17806 pTdlsPeer->isOffChannelEstablished = FALSE;
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053017807 /* TDLS Off Channel, Disable tdls channel switch,
17808 when there are more than one tdls link */
17809 numCurrTdlsPeers = wlan_hdd_tdlsConnectedPeers(pAdapter);
Pradeep Reddy POTTETIa9991b62015-03-26 18:03:19 +053017810 if (numCurrTdlsPeers == 2)
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053017811 {
17812 /* get connected peer and send disable tdls off chan */
17813 connPeer = wlan_hdd_tdls_get_connected_peer(pAdapter);
Pradeep Reddy POTTETIfdaf38b2015-05-13 13:01:22 +053017814 if ((connPeer) &&
17815 (connPeer->isOffChannelSupported == TRUE) &&
17816 (connPeer->isOffChannelConfigured == TRUE))
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053017817 {
17818 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
17819 "%s: More then one peer connected, Disable "
17820 "TDLS channel switch", __func__);
17821
Pradeep Reddy POTTETI16d83332015-03-26 18:28:13 +053017822 connPeer->isOffChannelEstablished = FALSE;
Masti, Narayanraddi6b93b472015-09-04 17:48:11 +053017823
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053017824 ret = sme_SendTdlsChanSwitchReq(
17825 WLAN_HDD_GET_HAL_CTX(pAdapter),
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053017826 pAdapter->sessionId,
17827 connPeer->peerMac,
17828 connPeer->peerParams.channel,
17829 TDLS_OFF_CHANNEL_BW_OFFSET,
17830 TDLS_CHANNEL_SWITCH_DISABLE);
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053017831 if (ret != VOS_STATUS_SUCCESS) {
Agarwal Ashisha7ef41d2015-06-25 18:00:26 +053017832 hddLog(VOS_TRACE_LEVEL_ERROR,
17833 FL("Failed to send TDLS switch channel request"));
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053017834 }
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053017835 }
17836 else
17837 {
17838 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
17839 "%s: No TDLS Connected Peer or "
Pradeep Reddy POTTETIfdaf38b2015-05-13 13:01:22 +053017840 "isOffChannelSupported %d "
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053017841 "isOffChannelConfigured %d",
17842 __func__,
Pradeep Reddy POTTETIfdaf38b2015-05-13 13:01:22 +053017843 (connPeer ? (connPeer->isOffChannelSupported)
17844 : -1),
17845 (connPeer ? (connPeer->isOffChannelConfigured)
17846 : -1));
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053017847 }
17848 }
17849
Hoonki Lee5305c3a2013-04-29 23:28:59 -070017850 if (eTDLS_LINK_CONNECTED != pTdlsPeer->link_status)
Gopichand Nakkalac87400e2013-03-13 18:51:00 -070017851 {
Madan Mohan Koyyalamudice419872013-09-13 19:36:52 +053017852 if (IS_ADVANCE_TDLS_ENABLE) {
Gopichand Nakkala24be5312013-07-02 16:47:12 +053017853
Madan Mohan Koyyalamudice419872013-09-13 19:36:52 +053017854 if (0 != wlan_hdd_tdls_get_link_establish_params(
17855 pAdapter, peer,&tdlsLinkEstablishParams)) {
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053017856 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Failed to get link establishment params"));
Madan Mohan Koyyalamudice419872013-09-13 19:36:52 +053017857 return -EINVAL;
17858 }
17859 INIT_COMPLETION(pAdapter->tdls_link_establish_req_comp);
Gopichand Nakkala79ff85d2013-05-27 17:05:29 +053017860
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053017861 ret = sme_SendTdlsLinkEstablishParams(
17862 WLAN_HDD_GET_HAL_CTX(pAdapter),
17863 pAdapter->sessionId, peer,
17864 &tdlsLinkEstablishParams);
17865 if (ret != VOS_STATUS_SUCCESS) {
17866 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Failed to send link establishment params"));
17867 }
Madan Mohan Koyyalamudice419872013-09-13 19:36:52 +053017868 /* Send TDLS peer UAPSD capabilities to the firmware and
17869 * register with the TL on after the response for this operation
17870 * is received .
17871 */
17872 ret = wait_for_completion_interruptible_timeout(
17873 &pAdapter->tdls_link_establish_req_comp,
17874 msecs_to_jiffies(WAIT_TIME_TDLS_LINK_ESTABLISH_REQ));
17875 if (ret <= 0)
17876 {
17877 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Agarwal Ashisha7ef41d2015-06-25 18:00:26 +053017878 FL("Link Establish Request Failed Status %ld"),
17879 ret);
Madan Mohan Koyyalamudice419872013-09-13 19:36:52 +053017880 return -EINVAL;
17881 }
Gopichand Nakkala79ff85d2013-05-27 17:05:29 +053017882 }
Masti, Narayanraddi6b93b472015-09-04 17:48:11 +053017883
Atul Mittal115287b2014-07-08 13:26:33 +053017884 wlan_hdd_tdls_set_peer_link_status(pTdlsPeer,
17885 eTDLS_LINK_CONNECTED,
17886 eTDLS_LINK_SUCCESS);
Agarwal Ashish16020c42014-12-29 22:01:11 +053017887 staDesc.ucSTAId = pTdlsPeer->staId;
17888 staDesc.ucQosEnabled = tdlsLinkEstablishParams.qos;
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053017889 ret = WLANTL_UpdateTdlsSTAClient(
17890 pHddCtx->pvosContext,
17891 &staDesc);
17892 if (ret != VOS_STATUS_SUCCESS) {
17893 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Failed to update TDLS STA params"));
17894 }
Agarwal Ashish16020c42014-12-29 22:01:11 +053017895
Gopichand Nakkala471708b2013-06-04 20:03:01 +053017896 /* Mark TDLS client Authenticated .*/
17897 status = WLANTL_ChangeSTAState( pHddCtx->pvosContext,
17898 pTdlsPeer->staId,
17899 WLANTL_STA_AUTHENTICATED);
Gopichand Nakkalaccd3a382013-03-19 13:56:10 -070017900 if (VOS_STATUS_SUCCESS == status)
17901 {
Hoonki Lee14621352013-04-16 17:51:19 -070017902 if (pTdlsPeer->is_responder == 0)
17903 {
17904 v_U8_t staId = (v_U8_t)pTdlsPeer->staId;
Ganesh Kondabattinicbfdc392015-09-11 19:12:59 +053017905 tdlsConnInfo_t *tdlsInfo;
17906
17907 tdlsInfo = wlan_hdd_get_conn_info(pHddCtx, staId);
17908
17909 /* Initialize initiator wait callback */
17910 vos_timer_init(
17911 &pTdlsPeer->initiatorWaitTimeoutTimer,
17912 VOS_TIMER_TYPE_SW,
17913 wlan_hdd_tdls_initiator_wait_cb,
17914 tdlsInfo);
Hoonki Lee14621352013-04-16 17:51:19 -070017915
17916 wlan_hdd_tdls_timer_restart(pAdapter,
17917 &pTdlsPeer->initiatorWaitTimeoutTimer,
17918 WAIT_TIME_TDLS_INITIATOR);
17919 /* suspend initiator TX until it receives direct packet from the
17920 reponder or WAIT_TIME_TDLS_INITIATOR timer expires */
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053017921 ret = WLANTL_SuspendDataTx(
17922 (WLAN_HDD_GET_CTX(pAdapter))->pvosContext,
17923 &staId, NULL);
17924 if (ret != VOS_STATUS_SUCCESS) {
17925 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Failed to suspend data tx"));
17926 }
Hoonki Lee14621352013-04-16 17:51:19 -070017927 }
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053017928
Pradeep Reddy POTTETIfcac7902015-04-16 12:25:17 +053017929 if ((TRUE == pTdlsPeer->isOffChannelSupported) &&
Pradeep Reddy POTTETIfdaf38b2015-05-13 13:01:22 +053017930 (TRUE == pTdlsPeer->isOffChannelConfigured))
Pradeep Reddy POTTETIfcac7902015-04-16 12:25:17 +053017931 {
Pradeep Reddy POTTETIfdaf38b2015-05-13 13:01:22 +053017932 suppChannelLen =
17933 tdlsLinkEstablishParams.supportedChannelsLen;
17934
17935 if ((suppChannelLen > 0) &&
17936 (suppChannelLen <= SIR_MAC_MAX_SUPP_CHANNELS))
17937 {
17938 tANI_U8 suppPeerChannel = 0;
17939 int i = 0;
17940 for (i = 0U; i < suppChannelLen; i++)
17941 {
17942 suppPeerChannel =
17943 tdlsLinkEstablishParams.supportedChannels[i];
17944
17945 pTdlsPeer->isOffChannelSupported = FALSE;
17946 if (suppPeerChannel ==
17947 pTdlsPeer->peerParams.channel)
17948 {
17949 pTdlsPeer->isOffChannelSupported = TRUE;
17950 break;
17951 }
17952 }
17953 }
17954 else
17955 {
17956 pTdlsPeer->isOffChannelSupported = FALSE;
17957 }
Pradeep Reddy POTTETIfcac7902015-04-16 12:25:17 +053017958 }
17959 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
17960 "%s: TDLS channel switch request for channel "
17961 "%d isOffChannelConfigured %d suppChannelLen "
Pradeep Reddy POTTETIfdaf38b2015-05-13 13:01:22 +053017962 "%d isOffChannelSupported %d", __func__,
17963 pTdlsPeer->peerParams.channel,
Pradeep Reddy POTTETIfcac7902015-04-16 12:25:17 +053017964 pTdlsPeer->isOffChannelConfigured,
Pradeep Reddy POTTETIfdaf38b2015-05-13 13:01:22 +053017965 suppChannelLen,
17966 pTdlsPeer->isOffChannelSupported);
Pradeep Reddy POTTETIfcac7902015-04-16 12:25:17 +053017967
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053017968 /* TDLS Off Channel, Enable tdls channel switch,
17969 when their is only one tdls link and it supports */
17970 numCurrTdlsPeers = wlan_hdd_tdlsConnectedPeers(pAdapter);
17971 if ((numCurrTdlsPeers == 1) &&
17972 (TRUE == pTdlsPeer->isOffChannelSupported) &&
17973 (TRUE == pTdlsPeer->isOffChannelConfigured))
17974 {
17975 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
17976 "%s: Send TDLS channel switch request for channel %d",
17977 __func__, pTdlsPeer->peerParams.channel);
Pradeep Reddy POTTETI16d83332015-03-26 18:28:13 +053017978
17979 pTdlsPeer->isOffChannelEstablished = TRUE;
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053017980 ret = sme_SendTdlsChanSwitchReq(WLAN_HDD_GET_HAL_CTX(pAdapter),
17981 pAdapter->sessionId,
17982 pTdlsPeer->peerMac,
17983 pTdlsPeer->peerParams.channel,
17984 TDLS_OFF_CHANNEL_BW_OFFSET,
17985 TDLS_CHANNEL_SWITCH_ENABLE);
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053017986 if (ret != VOS_STATUS_SUCCESS) {
17987 hddLog(VOS_TRACE_LEVEL_ERROR, FL("TDLS offchannel: Failed to send TDLS switch channel req"));
17988 }
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053017989 }
17990 else
17991 {
17992 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
17993 "%s: TDLS channel switch request not sent"
17994 " numCurrTdlsPeers %d "
17995 "isOffChannelSupported %d "
17996 "isOffChannelConfigured %d",
17997 __func__, numCurrTdlsPeers,
17998 pTdlsPeer->isOffChannelSupported,
17999 pTdlsPeer->isOffChannelConfigured);
18000 }
18001
Gopichand Nakkalaccd3a382013-03-19 13:56:10 -070018002 }
Gopichand Nakkalac87400e2013-03-13 18:51:00 -070018003 wlan_hdd_tdls_check_bmps(pAdapter);
Gopichand Nakkala79ff85d2013-05-27 17:05:29 +053018004
18005 /* Update TL about the UAPSD masks , to route the packets to firmware */
Gopichand Nakkala574f6d12013-06-27 19:38:43 +053018006 if ((TRUE == pHddCtx->cfg_ini->fEnableTDLSBufferSta)
18007 || pHddCtx->cfg_ini->fTDLSUapsdMask )
Gopichand Nakkala79ff85d2013-05-27 17:05:29 +053018008 {
Gopichand Nakkala574f6d12013-06-27 19:38:43 +053018009 int ac;
18010 uint8 ucAc[4] = { WLANTL_AC_VO,
18011 WLANTL_AC_VI,
18012 WLANTL_AC_BK,
18013 WLANTL_AC_BE };
18014 uint8 tlTid[4] = { 7, 5, 2, 3 } ;
18015 for(ac=0; ac < 4; ac++)
18016 {
18017 status = WLANTL_EnableUAPSDForAC( (WLAN_HDD_GET_CTX(pAdapter))->pvosContext,
18018 pTdlsPeer->staId, ucAc[ac],
18019 tlTid[ac], tlTid[ac], 0, 0,
18020 WLANTL_BI_DIR );
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053018021 if (status != VOS_STATUS_SUCCESS) {
18022 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Failed to enable UAPSD for AC"));
18023 }
Gopichand Nakkala574f6d12013-06-27 19:38:43 +053018024 }
Gopichand Nakkala79ff85d2013-05-27 17:05:29 +053018025 }
Gopichand Nakkalac87400e2013-03-13 18:51:00 -070018026 }
Mohit Khanna698ba2a2012-12-04 15:08:18 -080018027 }
18028 break;
18029 case NL80211_TDLS_DISABLE_LINK:
Lee Hoonkic1262f22013-01-24 21:59:00 -080018030 {
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053018031 tANI_U16 numCurrTdlsPeers = 0;
18032 hddTdlsPeer_t *connPeer = NULL;
18033
Agarwal Ashisha7ef41d2015-06-25 18:00:26 +053018034 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
18035 " %s : NL80211_TDLS_DISABLE_LINK for " MAC_ADDRESS_STR,
18036 __func__, MAC_ADDR_ARRAY(peer));
18037
Masti, Narayanraddi8208f062015-10-15 13:16:17 +053018038 mutex_lock(&pHddCtx->tdls_lock);
18039 pTdlsPeer = wlan_hdd_tdls_find_peer(pAdapter, peer, FALSE);
Sunil Dutt41de4e22013-11-14 18:09:02 +053018040
Agarwal Ashisha7ef41d2015-06-25 18:00:26 +053018041
Sunil Dutt41de4e22013-11-14 18:09:02 +053018042 if ( NULL == pTdlsPeer ) {
Masti, Narayanraddi8208f062015-10-15 13:16:17 +053018043 mutex_unlock(&pHddCtx->tdls_lock);
Sunil Dutt41de4e22013-11-14 18:09:02 +053018044 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: " MAC_ADDRESS_STR
18045 " (oper %d) not exsting. ignored",
18046 __func__, MAC_ADDR_ARRAY(peer), (int)oper);
18047 return -EINVAL;
18048 }
18049
18050 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
18051 "%s: " MAC_ADDRESS_STR " link_status %d (%s) ", "tdls_oper",
18052 MAC_ADDR_ARRAY(peer), pTdlsPeer->link_status,
18053 "NL80211_TDLS_DISABLE_LINK");
18054
Hoonki Lee5305c3a2013-04-29 23:28:59 -070018055 if(TDLS_STA_INDEX_VALID(pTdlsPeer->staId))
Lee Hoonkic1262f22013-01-24 21:59:00 -080018056 {
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -070018057 long status;
18058
Pradeep Reddy POTTETIf3148e82015-04-16 12:10:33 +053018059 /* set tdls off channel status to false for this peer */
18060 pTdlsPeer->isOffChannelEstablished = FALSE;
Atul Mittal271a7652014-09-12 13:18:22 +053018061 wlan_hdd_tdls_set_peer_link_status(pTdlsPeer,
18062 eTDLS_LINK_TEARING,
18063 (pTdlsPeer->link_status == eTDLS_LINK_TEARING)?
18064 eTDLS_LINK_UNSPECIFIED:
18065 eTDLS_LINK_DROPPED_BY_REMOTE);
Masti, Narayanraddi8208f062015-10-15 13:16:17 +053018066 mutex_unlock(&pHddCtx->tdls_lock);
18067
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -070018068 INIT_COMPLETION(pAdapter->tdls_del_station_comp);
18069
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053018070 status = sme_DeleteTdlsPeerSta(
18071 WLAN_HDD_GET_HAL_CTX(pAdapter),
18072 pAdapter->sessionId, peer );
18073 if (status != VOS_STATUS_SUCCESS) {
18074 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Failed to delete TDLS peer STA"));
18075 }
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -070018076
18077 status = wait_for_completion_interruptible_timeout(&pAdapter->tdls_del_station_comp,
18078 msecs_to_jiffies(WAIT_TIME_TDLS_DEL_STA));
Masti, Narayanraddi8208f062015-10-15 13:16:17 +053018079
18080 mutex_lock(&pHddCtx->tdls_lock);
18081 pTdlsPeer = wlan_hdd_tdls_find_peer(pAdapter, peer, FALSE);
18082 if ( NULL == pTdlsPeer ) {
18083 mutex_unlock(&pHddCtx->tdls_lock);
18084 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: " MAC_ADDRESS_STR
18085 " peer was freed in other context",
18086 __func__, MAC_ADDR_ARRAY(peer));
18087 return -EINVAL;
18088 }
18089
Atul Mittal271a7652014-09-12 13:18:22 +053018090 wlan_hdd_tdls_set_peer_link_status(pTdlsPeer,
Atul Mittal454664b2014-10-10 11:03:46 +053018091 eTDLS_LINK_IDLE,
18092 eTDLS_LINK_UNSPECIFIED);
Masti, Narayanraddi8208f062015-10-15 13:16:17 +053018093 mutex_unlock(&pHddCtx->tdls_lock);
18094
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -070018095 if (status <= 0)
18096 {
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -070018097 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
18098 "%s: Del station failed status %ld",
18099 __func__, status);
18100 return -EPERM;
18101 }
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053018102
18103 /* TDLS Off Channel, Enable tdls channel switch,
18104 when their is only one tdls link and it supports */
18105 numCurrTdlsPeers = wlan_hdd_tdlsConnectedPeers(pAdapter);
18106 if (numCurrTdlsPeers == 1)
18107 {
Masti, Narayanraddi8208f062015-10-15 13:16:17 +053018108 tSirMacAddr peerMac;
18109 int channel;
Masti, Narayanraddi3818aea2015-10-17 15:20:28 +053018110
Masti, Narayanraddi8208f062015-10-15 13:16:17 +053018111 mutex_lock(&pHddCtx->tdls_lock);
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053018112 connPeer = wlan_hdd_tdls_get_connected_peer(pAdapter);
Masti, Narayanraddi3818aea2015-10-17 15:20:28 +053018113
18114 if (connPeer == NULL) {
18115 mutex_unlock(&pHddCtx->tdls_lock);
18116 hddLog(VOS_TRACE_LEVEL_ERROR,
18117 "%s connPeer is NULL", __func__);
18118 return -EINVAL;
18119 }
18120
Masti, Narayanraddi8208f062015-10-15 13:16:17 +053018121 vos_mem_copy(peerMac, connPeer->peerMac, sizeof(tSirMacAddr));
18122 channel = connPeer->peerParams.channel;
18123
18124 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
18125 "%s: TDLS channel switch "
18126 "isOffChannelSupported %d "
18127 "isOffChannelConfigured %d "
18128 "isOffChannelEstablished %d",
18129 __func__,
18130 (connPeer ? connPeer->isOffChannelSupported : -1),
18131 (connPeer ? connPeer->isOffChannelConfigured : -1),
18132 (connPeer ? connPeer->isOffChannelEstablished : -1));
18133
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053018134 if ((connPeer) &&
18135 (connPeer->isOffChannelSupported == TRUE) &&
18136 (connPeer->isOffChannelConfigured == TRUE))
18137 {
Pradeep Reddy POTTETI16d83332015-03-26 18:28:13 +053018138 connPeer->isOffChannelEstablished = TRUE;
Masti, Narayanraddi8208f062015-10-15 13:16:17 +053018139 mutex_unlock(&pHddCtx->tdls_lock);
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053018140 status = sme_SendTdlsChanSwitchReq(
18141 WLAN_HDD_GET_HAL_CTX(pAdapter),
18142 pAdapter->sessionId,
Masti, Narayanraddi8208f062015-10-15 13:16:17 +053018143 peerMac,
18144 channel,
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053018145 TDLS_OFF_CHANNEL_BW_OFFSET,
18146 TDLS_CHANNEL_SWITCH_ENABLE);
18147 if (status != VOS_STATUS_SUCCESS) {
18148 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Failed to send TDLS switch channel req"));
18149 }
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053018150 }
Masti, Narayanraddi8208f062015-10-15 13:16:17 +053018151 else
18152 mutex_unlock(&pHddCtx->tdls_lock);
18153 }
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053018154 else
18155 {
18156 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
18157 "%s: TDLS channel switch request not sent "
18158 "numCurrTdlsPeers %d ",
18159 __func__, numCurrTdlsPeers);
18160 }
Lee Hoonkic1262f22013-01-24 21:59:00 -080018161 }
18162 else
18163 {
Masti, Narayanraddi8208f062015-10-15 13:16:17 +053018164 mutex_unlock(&pHddCtx->tdls_lock);
Gopichand Nakkalac87400e2013-03-13 18:51:00 -070018165 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
18166 "%s: TDLS Peer Station doesn't exist.", __func__);
Lee Hoonkic1262f22013-01-24 21:59:00 -080018167 }
Lee Hoonkic1262f22013-01-24 21:59:00 -080018168 }
Gopichand Nakkalac87400e2013-03-13 18:51:00 -070018169 break;
Mohit Khanna698ba2a2012-12-04 15:08:18 -080018170 case NL80211_TDLS_TEARDOWN:
Sunil Dutt41de4e22013-11-14 18:09:02 +053018171 {
Atul Mittal115287b2014-07-08 13:26:33 +053018172 status = wlan_hdd_tdls_extctrl_deconfig_peer(pAdapter, peer);
Sunil Dutt41de4e22013-11-14 18:09:02 +053018173
Atul Mittal115287b2014-07-08 13:26:33 +053018174 if (0 != status)
18175 {
18176 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Agarwal Ashisha7ef41d2015-06-25 18:00:26 +053018177 FL("Error in TDLS Teardown"));
Atul Mittal115287b2014-07-08 13:26:33 +053018178 return status;
Sunil Dutt41de4e22013-11-14 18:09:02 +053018179 }
Sunil Dutt41de4e22013-11-14 18:09:02 +053018180 break;
18181 }
Mohit Khanna698ba2a2012-12-04 15:08:18 -080018182 case NL80211_TDLS_SETUP:
Sunil Dutt41de4e22013-11-14 18:09:02 +053018183 {
Atul Mittal115287b2014-07-08 13:26:33 +053018184 status = wlan_hdd_tdls_extctrl_config_peer(pAdapter,
18185 peer,
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053018186 NULL,
Atul Mittal115287b2014-07-08 13:26:33 +053018187 NULL);
Sunil Dutt41de4e22013-11-14 18:09:02 +053018188
Atul Mittal115287b2014-07-08 13:26:33 +053018189 if (0 != status)
18190 {
18191 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Agarwal Ashisha7ef41d2015-06-25 18:00:26 +053018192 FL("Error in TDLS Setup"));
Atul Mittal115287b2014-07-08 13:26:33 +053018193 return status;
Naresh Jayaram937abdf2013-11-26 19:50:25 +053018194 }
Naresh Jayaramdb4514b2013-11-25 18:08:10 +053018195 break;
Sunil Dutt41de4e22013-11-14 18:09:02 +053018196 }
Mohit Khanna698ba2a2012-12-04 15:08:18 -080018197 case NL80211_TDLS_DISCOVERY_REQ:
18198 /* We don't support in-driver setup/teardown/discovery */
c_hpothu6ff1c3c2013-10-01 19:01:57 +053018199 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_WARN,
Agarwal Ashisha7ef41d2015-06-25 18:00:26 +053018200 "%s: Driver doesn't support in-driver setup/teardown/discovery "
c_hpothu6ff1c3c2013-10-01 19:01:57 +053018201 ,__func__);
Mohit Khanna698ba2a2012-12-04 15:08:18 -080018202 return -ENOTSUPP;
18203 default:
c_hpothu6ff1c3c2013-10-01 19:01:57 +053018204 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
18205 "%s: unsupported event",__func__);
Mohit Khanna698ba2a2012-12-04 15:08:18 -080018206 return -ENOTSUPP;
18207 }
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053018208
18209 EXIT();
Mohit Khanna698ba2a2012-12-04 15:08:18 -080018210 return 0;
18211}
Chilam NG571c65a2013-01-19 12:27:36 +053018212
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053018213static int wlan_hdd_cfg80211_tdls_oper(struct wiphy *wiphy, struct net_device *dev,
Anand N Sunkad9bfc2622015-07-30 15:18:54 +053018214#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,18,0))
18215 const u8 *peer,
18216#else
18217 u8 *peer,
18218#endif
18219 enum nl80211_tdls_operation oper)
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053018220{
18221 int ret;
18222
18223 vos_ssr_protect(__func__);
18224 ret = __wlan_hdd_cfg80211_tdls_oper(wiphy, dev, peer, oper);
18225 vos_ssr_unprotect(__func__);
18226
18227 return ret;
18228}
18229
Chilam NG571c65a2013-01-19 12:27:36 +053018230int wlan_hdd_cfg80211_send_tdls_discover_req(struct wiphy *wiphy,
18231 struct net_device *dev, u8 *peer)
18232{
Arif Hussaina7c8e412013-11-20 11:06:42 -080018233 hddLog(VOS_TRACE_LEVEL_INFO,
18234 "tdls send discover req: "MAC_ADDRESS_STR,
18235 MAC_ADDR_ARRAY(peer));
Chilam NG571c65a2013-01-19 12:27:36 +053018236
Sunil Dutt Undekarieacac6f2014-03-21 14:08:53 +053018237#if TDLS_MGMT_VERSION2
18238 return wlan_hdd_cfg80211_tdls_mgmt(wiphy, dev, peer,
18239 WLAN_TDLS_DISCOVERY_REQUEST, 1, 0, 0, NULL, 0);
18240#else
Anand N Sunkad9bfc2622015-07-30 15:18:54 +053018241#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,17,0))
18242 return wlan_hdd_cfg80211_tdls_mgmt(wiphy, dev, peer,
18243 WLAN_TDLS_DISCOVERY_REQUEST, 1, 0, 0, 0, NULL, 0);
18244#elif (LINUX_VERSION_CODE >= KERNEL_VERSION(3,16,0))
18245 return wlan_hdd_cfg80211_tdls_mgmt(wiphy, dev, peer,
18246 WLAN_TDLS_DISCOVERY_REQUEST, 1, 0, 0, NULL, 0);
18247#elif (LINUX_VERSION_CODE >= KERNEL_VERSION(3,15,0))
18248 return wlan_hdd_cfg80211_tdls_mgmt(wiphy, dev, peer,
18249 WLAN_TDLS_DISCOVERY_REQUEST, 1, 0, 0, NULL, 0);
18250#else
Chilam NG571c65a2013-01-19 12:27:36 +053018251 return wlan_hdd_cfg80211_tdls_mgmt(wiphy, dev, peer,
18252 WLAN_TDLS_DISCOVERY_REQUEST, 1, 0, NULL, 0);
Sunil Dutt Undekarieacac6f2014-03-21 14:08:53 +053018253#endif
Anand N Sunkad9bfc2622015-07-30 15:18:54 +053018254#endif /* KERNEL_VERSION */
Chilam NG571c65a2013-01-19 12:27:36 +053018255}
Mohit Khanna698ba2a2012-12-04 15:08:18 -080018256#endif
18257
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053018258#ifdef WLAN_FEATURE_GTK_OFFLOAD
18259/*
18260 * FUNCTION: wlan_hdd_cfg80211_update_replayCounterCallback
18261 * Callback rountine called upon receiving response for
18262 * get offload info
18263 */
18264void wlan_hdd_cfg80211_update_replayCounterCallback(void *callbackContext,
18265 tpSirGtkOffloadGetInfoRspParams pGtkOffloadGetInfoRsp)
18266{
18267
18268 hdd_adapter_t *pAdapter = (hdd_adapter_t *)callbackContext;
Gopichand Nakkalad36ee622013-05-07 14:13:27 +053018269 tANI_U8 tempReplayCounter[8];
18270 hdd_station_ctx_t *pHddStaCtx;
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053018271
18272 ENTER();
18273
18274 if (NULL == pAdapter)
18275 {
Agarwal Ashish971c2882013-10-30 20:11:12 +053018276 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053018277 "%s: HDD adapter is Null", __func__);
18278 return ;
18279 }
18280
18281 if (NULL == pGtkOffloadGetInfoRsp)
18282 {
18283 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
18284 "%s: pGtkOffloadGetInfoRsp is Null", __func__);
18285 return ;
18286 }
18287
18288 if (VOS_STATUS_SUCCESS != pGtkOffloadGetInfoRsp->ulStatus)
18289 {
18290 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
18291 "%s: wlan Failed to get replay counter value",
18292 __func__);
18293 return ;
18294 }
18295
Gopichand Nakkalad36ee622013-05-07 14:13:27 +053018296 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
18297 /* Update replay counter */
18298 pHddStaCtx->gtkOffloadReqParams.ullKeyReplayCounter =
18299 pGtkOffloadGetInfoRsp->ullKeyReplayCounter;
18300
18301 {
18302 /* changing from little to big endian since supplicant
18303 * works on big endian format
18304 */
18305 int i;
18306 tANI_U8 *p = (tANI_U8 *)&pGtkOffloadGetInfoRsp->ullKeyReplayCounter;
18307
18308 for (i = 0; i < 8; i++)
18309 {
18310 tempReplayCounter[7-i] = (tANI_U8)p[i];
18311 }
18312 }
18313
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053018314 /* Update replay counter to NL */
18315 cfg80211_gtk_rekey_notify(pAdapter->dev, pGtkOffloadGetInfoRsp->bssId,
Gopichand Nakkalad36ee622013-05-07 14:13:27 +053018316 tempReplayCounter, GFP_KERNEL);
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053018317}
18318
18319/*
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053018320 * FUNCTION: __wlan_hdd_cfg80211_set_rekey_data
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053018321 * This function is used to offload GTK rekeying job to the firmware.
18322 */
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053018323int __wlan_hdd_cfg80211_set_rekey_data(struct wiphy *wiphy, struct net_device *dev,
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053018324 struct cfg80211_gtk_rekey_data *data)
18325{
18326 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
18327 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
18328 hdd_station_ctx_t *pHddStaCtx;
18329 tHalHandle hHal;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053018330 int result;
Gopichand Nakkalad36ee622013-05-07 14:13:27 +053018331 tSirGtkOffloadParams hddGtkOffloadReqParams;
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053018332 eHalStatus status = eHAL_STATUS_FAILURE;
18333
18334 ENTER();
18335
18336 if (NULL == pAdapter)
18337 {
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053018338 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053018339 "%s: HDD adapter is Null", __func__);
18340 return -ENODEV;
18341 }
18342
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053018343 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
18344 TRACE_CODE_HDD_CFG80211_SET_REKEY_DATA,
18345 pAdapter->sessionId, pAdapter->device_mode));
18346
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053018347 result = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053018348 if (0 != result)
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053018349 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053018350 return result;
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053018351 }
18352
18353 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
18354 hHal = WLAN_HDD_GET_HAL_CTX(pAdapter);
18355 if (NULL == hHal)
18356 {
18357 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
18358 "%s: HAL context is Null!!!", __func__);
18359 return -EAGAIN;
18360 }
18361
Gopichand Nakkalad36ee622013-05-07 14:13:27 +053018362 pHddStaCtx->gtkOffloadReqParams.ulFlags = GTK_OFFLOAD_ENABLE;
18363 memcpy(pHddStaCtx->gtkOffloadReqParams.aKCK, data->kck, NL80211_KCK_LEN);
18364 memcpy(pHddStaCtx->gtkOffloadReqParams.aKEK, data->kek, NL80211_KEK_LEN);
18365 memcpy(pHddStaCtx->gtkOffloadReqParams.bssId, &pHddStaCtx->conn_info.bssId,
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053018366 WNI_CFG_BSSID_LEN);
Gopichand Nakkalad36ee622013-05-07 14:13:27 +053018367 {
18368 /* changing from big to little endian since driver
18369 * works on little endian format
18370 */
18371 tANI_U8 *p =
18372 (tANI_U8 *)&pHddStaCtx->gtkOffloadReqParams.ullKeyReplayCounter;
18373 int i;
18374
18375 for (i = 0; i < 8; i++)
18376 {
18377 p[7-i] = data->replay_ctr[i];
18378 }
18379 }
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053018380
18381 if (TRUE == pHddCtx->hdd_wlan_suspended)
18382 {
18383 /* if wlan is suspended, enable GTK offload directly from here */
Gopichand Nakkalad36ee622013-05-07 14:13:27 +053018384 memcpy(&hddGtkOffloadReqParams, &pHddStaCtx->gtkOffloadReqParams,
18385 sizeof (tSirGtkOffloadParams));
18386 status = sme_SetGTKOffload(hHal, &hddGtkOffloadReqParams,
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053018387 pAdapter->sessionId);
18388
18389 if (eHAL_STATUS_SUCCESS != status)
18390 {
18391 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
18392 "%s: sme_SetGTKOffload failed, returned %d",
18393 __func__, status);
Vinay Krishna Eranna6f22c1f2014-10-13 16:03:06 +053018394
18395 /* Need to clear any trace of key value in the memory.
18396 * Thus zero out the memory even though it is local
18397 * variable.
18398 */
18399 vos_mem_zero(&hddGtkOffloadReqParams,
18400 sizeof(hddGtkOffloadReqParams));
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053018401 return status;
18402 }
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053018403 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
18404 "%s: sme_SetGTKOffload successfull", __func__);
18405 }
18406 else
18407 {
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053018408 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
18409 "%s: wlan not suspended GTKOffload request is stored",
18410 __func__);
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053018411 }
Gopichand Nakkalad36ee622013-05-07 14:13:27 +053018412
Vinay Krishna Eranna6f22c1f2014-10-13 16:03:06 +053018413 /* Need to clear any trace of key value in the memory.
18414 * Thus zero out the memory even though it is local
18415 * variable.
18416 */
18417 vos_mem_zero(&hddGtkOffloadReqParams,
18418 sizeof(hddGtkOffloadReqParams));
18419
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053018420 EXIT();
Gopichand Nakkalad36ee622013-05-07 14:13:27 +053018421 return eHAL_STATUS_SUCCESS;
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053018422}
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053018423
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053018424int wlan_hdd_cfg80211_set_rekey_data(struct wiphy *wiphy, struct net_device *dev,
18425 struct cfg80211_gtk_rekey_data *data)
18426{
18427 int ret;
18428
18429 vos_ssr_protect(__func__);
18430 ret = __wlan_hdd_cfg80211_set_rekey_data(wiphy, dev, data);
18431 vos_ssr_unprotect(__func__);
18432
18433 return ret;
18434}
18435#endif /*WLAN_FEATURE_GTK_OFFLOAD*/
Gopichand Nakkalac005b7c2013-05-14 16:04:14 +053018436/*
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053018437 * FUNCTION: __wlan_hdd_cfg80211_set_mac_acl
Gopichand Nakkalac005b7c2013-05-14 16:04:14 +053018438 * This function is used to set access control policy
18439 */
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053018440static int __wlan_hdd_cfg80211_set_mac_acl(struct wiphy *wiphy,
18441 struct net_device *dev,
18442 const struct cfg80211_acl_data *params)
Gopichand Nakkalac005b7c2013-05-14 16:04:14 +053018443{
18444 int i;
18445 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
18446 hdd_hostapd_state_t *pHostapdState;
18447 tsap_Config_t *pConfig;
18448 v_CONTEXT_t pVosContext = NULL;
18449 hdd_context_t *pHddCtx;
18450 int status;
18451
18452 ENTER();
18453
18454 if (NULL == pAdapter)
18455 {
18456 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
18457 "%s: HDD adapter is Null", __func__);
18458 return -ENODEV;
18459 }
18460
18461 if (NULL == params)
18462 {
18463 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
18464 "%s: params is Null", __func__);
18465 return -EINVAL;
18466 }
18467
18468 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
18469 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalac005b7c2013-05-14 16:04:14 +053018470 if (0 != status)
18471 {
Gopichand Nakkalac005b7c2013-05-14 16:04:14 +053018472 return status;
18473 }
18474
18475 pVosContext = pHddCtx->pvosContext;
18476 pHostapdState = WLAN_HDD_GET_HOSTAP_STATE_PTR(pAdapter);
18477
18478 if (NULL == pHostapdState)
18479 {
18480 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
18481 "%s: pHostapdState is Null", __func__);
18482 return -EINVAL;
18483 }
18484
18485 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,"acl policy: = %d"
18486 "no acl entries = %d", params->acl_policy, params->n_acl_entries);
Konamki, Sreelakshmi7b464be2015-07-14 12:17:01 +053018487 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
18488 TRACE_CODE_HDD_CFG80211_SET_MAC_ACL,
18489 pAdapter->sessionId, pAdapter->device_mode));
Gopichand Nakkalac005b7c2013-05-14 16:04:14 +053018490
18491 if (WLAN_HDD_SOFTAP == pAdapter->device_mode)
18492 {
18493 pConfig = &pAdapter->sessionCtx.ap.sapConfig;
18494
18495 /* default value */
18496 pConfig->num_accept_mac = 0;
18497 pConfig->num_deny_mac = 0;
18498
18499 /**
18500 * access control policy
18501 * @NL80211_ACL_POLICY_ACCEPT_UNLESS_LISTED: Deny stations which are
18502 * listed in hostapd.deny file.
18503 * @NL80211_ACL_POLICY_DENY_UNLESS_LISTED: Allow stations which are
18504 * listed in hostapd.accept file.
18505 */
18506 if (NL80211_ACL_POLICY_DENY_UNLESS_LISTED == params->acl_policy)
18507 {
18508 pConfig->SapMacaddr_acl = eSAP_DENY_UNLESS_ACCEPTED;
18509 }
18510 else if (NL80211_ACL_POLICY_ACCEPT_UNLESS_LISTED == params->acl_policy)
18511 {
18512 pConfig->SapMacaddr_acl = eSAP_ACCEPT_UNLESS_DENIED;
18513 }
18514 else
18515 {
18516 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
18517 "%s:Acl Policy : %d is not supported",
18518 __func__, params->acl_policy);
18519 return -ENOTSUPP;
18520 }
18521
18522 if (eSAP_DENY_UNLESS_ACCEPTED == pConfig->SapMacaddr_acl)
18523 {
18524 pConfig->num_accept_mac = params->n_acl_entries;
18525 for (i = 0; i < params->n_acl_entries; i++)
18526 {
18527 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
18528 "** Add ACL MAC entry %i in WhiletList :"
18529 MAC_ADDRESS_STR, i,
18530 MAC_ADDR_ARRAY(params->mac_addrs[i].addr));
18531
18532 vos_mem_copy(&pConfig->accept_mac[i], params->mac_addrs[i].addr,
18533 sizeof(qcmacaddr));
18534 }
18535 }
18536 else if (eSAP_ACCEPT_UNLESS_DENIED == pConfig->SapMacaddr_acl)
18537 {
18538 pConfig->num_deny_mac = params->n_acl_entries;
18539 for (i = 0; i < params->n_acl_entries; i++)
18540 {
18541 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
18542 "** Add ACL MAC entry %i in BlackList :"
18543 MAC_ADDRESS_STR, i,
18544 MAC_ADDR_ARRAY(params->mac_addrs[i].addr));
18545
18546 vos_mem_copy(&pConfig->deny_mac[i], params->mac_addrs[i].addr,
18547 sizeof(qcmacaddr));
18548 }
18549 }
18550
18551 if (VOS_STATUS_SUCCESS != WLANSAP_SetMacACL(pVosContext, pConfig))
18552 {
18553 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
18554 "%s: SAP Set Mac Acl fail", __func__);
18555 return -EINVAL;
18556 }
18557 }
18558 else
18559 {
18560 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Sushant Kaushik8bc7df22014-04-09 17:55:29 +053018561 "%s: Invalid device_mode = %s (%d)",
18562 __func__, hdd_device_modetoString(pAdapter->device_mode),
18563 pAdapter->device_mode);
Gopichand Nakkalac005b7c2013-05-14 16:04:14 +053018564 return -EINVAL;
18565 }
18566
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053018567 EXIT();
Gopichand Nakkalac005b7c2013-05-14 16:04:14 +053018568 return 0;
18569}
18570
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053018571static int wlan_hdd_cfg80211_set_mac_acl(struct wiphy *wiphy,
18572 struct net_device *dev,
18573 const struct cfg80211_acl_data *params)
18574{
18575 int ret;
18576 vos_ssr_protect(__func__);
18577 ret = __wlan_hdd_cfg80211_set_mac_acl(wiphy, dev, params);
18578 vos_ssr_unprotect(__func__);
18579
18580 return ret;
18581}
18582
Leo Chang9056f462013-08-01 19:21:11 -070018583#ifdef WLAN_NL80211_TESTMODE
18584#ifdef FEATURE_WLAN_LPHB
Leo Changd9df8aa2013-09-26 13:32:26 -070018585void wlan_hdd_cfg80211_lphb_ind_handler
Leo Chang9056f462013-08-01 19:21:11 -070018586(
18587 void *pAdapter,
18588 void *indCont
18589)
18590{
Leo Changd9df8aa2013-09-26 13:32:26 -070018591 tSirLPHBInd *lphbInd;
18592 struct sk_buff *skb;
c_hpothu73f35e62014-04-18 13:40:08 +053018593 hdd_context_t *pHddCtxt;
Leo Chang9056f462013-08-01 19:21:11 -070018594
18595 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Leo Changd9df8aa2013-09-26 13:32:26 -070018596 "LPHB indication arrived");
Leo Chang9056f462013-08-01 19:21:11 -070018597
c_hpothu73f35e62014-04-18 13:40:08 +053018598 if (pAdapter == NULL)
18599 {
18600 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
18601 "%s: pAdapter is NULL\n",__func__);
18602 return;
18603 }
18604
Leo Chang9056f462013-08-01 19:21:11 -070018605 if (NULL == indCont)
18606 {
18607 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Leo Changd9df8aa2013-09-26 13:32:26 -070018608 "LPHB IND, invalid argument");
Leo Chang9056f462013-08-01 19:21:11 -070018609 return;
18610 }
18611
c_hpothu73f35e62014-04-18 13:40:08 +053018612 pHddCtxt = (hdd_context_t *)pAdapter;
Leo Changd9df8aa2013-09-26 13:32:26 -070018613 lphbInd = (tSirLPHBInd *)indCont;
Leo Chang9056f462013-08-01 19:21:11 -070018614 skb = cfg80211_testmode_alloc_event_skb(
c_hpothu73f35e62014-04-18 13:40:08 +053018615 pHddCtxt->wiphy,
Leo Changd9df8aa2013-09-26 13:32:26 -070018616 sizeof(tSirLPHBInd),
Leo Chang9056f462013-08-01 19:21:11 -070018617 GFP_ATOMIC);
18618 if (!skb)
18619 {
18620 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
18621 "LPHB timeout, NL buffer alloc fail");
18622 return;
18623 }
18624
Leo Changac3ba772013-10-07 09:47:04 -070018625 if(nla_put_u32(skb, WLAN_HDD_TM_ATTR_CMD, WLAN_HDD_TM_CMD_WLAN_HB))
Leo Changd9df8aa2013-09-26 13:32:26 -070018626 {
18627 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
18628 "WLAN_HDD_TM_ATTR_CMD put fail");
18629 goto nla_put_failure;
18630 }
Leo Changac3ba772013-10-07 09:47:04 -070018631 if(nla_put_u32(skb, WLAN_HDD_TM_ATTR_TYPE, lphbInd->protocolType))
Leo Changd9df8aa2013-09-26 13:32:26 -070018632 {
18633 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
18634 "WLAN_HDD_TM_ATTR_TYPE put fail");
18635 goto nla_put_failure;
18636 }
Leo Changac3ba772013-10-07 09:47:04 -070018637 if(nla_put(skb, WLAN_HDD_TM_ATTR_DATA,
Leo Changd9df8aa2013-09-26 13:32:26 -070018638 sizeof(tSirLPHBInd), lphbInd))
18639 {
18640 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
18641 "WLAN_HDD_TM_ATTR_DATA put fail");
18642 goto nla_put_failure;
18643 }
Leo Chang9056f462013-08-01 19:21:11 -070018644 cfg80211_testmode_event(skb, GFP_ATOMIC);
18645 return;
18646
18647nla_put_failure:
18648 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
18649 "NLA Put fail");
18650 kfree_skb(skb);
18651
18652 return;
18653}
18654#endif /* FEATURE_WLAN_LPHB */
18655
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053018656static int __wlan_hdd_cfg80211_testmode(struct wiphy *wiphy, void *data, int len)
Leo Chang9056f462013-08-01 19:21:11 -070018657{
18658 struct nlattr *tb[WLAN_HDD_TM_ATTR_MAX + 1];
18659 int err = 0;
18660#ifdef FEATURE_WLAN_LPHB
18661 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
Leo Changd9df8aa2013-09-26 13:32:26 -070018662 eHalStatus smeStatus;
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053018663
18664 ENTER();
18665
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +053018666 err = wlan_hdd_validate_context(pHddCtx);
18667 if (0 != err)
18668 {
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +053018669 return err;
18670 }
Leo Chang9056f462013-08-01 19:21:11 -070018671#endif /* FEATURE_WLAN_LPHB */
18672
18673 err = nla_parse(tb, WLAN_HDD_TM_ATTR_MAX, data, len, wlan_hdd_tm_policy);
18674 if (err)
18675 {
18676 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
18677 "%s Testmode INV ATTR", __func__);
18678 return err;
18679 }
18680
18681 if (!tb[WLAN_HDD_TM_ATTR_CMD])
18682 {
18683 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
18684 "%s Testmode INV CMD", __func__);
18685 return -EINVAL;
18686 }
18687
Konamki, Sreelakshmi7b464be2015-07-14 12:17:01 +053018688 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
18689 TRACE_CODE_HDD_CFG80211_TESTMODE,
18690 NO_SESSION, nla_get_u32(tb[WLAN_HDD_TM_ATTR_CMD])));
Leo Chang9056f462013-08-01 19:21:11 -070018691 switch (nla_get_u32(tb[WLAN_HDD_TM_ATTR_CMD]))
18692 {
18693#ifdef FEATURE_WLAN_LPHB
18694 /* Low Power Heartbeat configuration request */
18695 case WLAN_HDD_TM_CMD_WLAN_HB:
18696 {
18697 int buf_len;
18698 void *buf;
18699 tSirLPHBReq *hb_params = NULL;
Amar Singhal05852702014-02-04 14:40:00 -080018700 tSirLPHBReq *hb_params_temp = NULL;
Leo Chang9056f462013-08-01 19:21:11 -070018701
18702 if (!tb[WLAN_HDD_TM_ATTR_DATA])
18703 {
18704 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
18705 "%s Testmode INV DATA", __func__);
18706 return -EINVAL;
18707 }
18708
18709 buf = nla_data(tb[WLAN_HDD_TM_ATTR_DATA]);
18710 buf_len = nla_len(tb[WLAN_HDD_TM_ATTR_DATA]);
Amar Singhal05852702014-02-04 14:40:00 -080018711
18712 hb_params_temp =(tSirLPHBReq *)buf;
18713 if ((hb_params_temp->cmd == LPHB_SET_TCP_PARAMS_INDID) &&
18714 (hb_params_temp->params.lphbTcpParamReq.timePeriodSec == 0))
18715 return -EINVAL;
18716
Leo Chang9056f462013-08-01 19:21:11 -070018717 hb_params = (tSirLPHBReq *)vos_mem_malloc(sizeof(tSirLPHBReq));
18718 if (NULL == hb_params)
18719 {
18720 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
18721 "%s Request Buffer Alloc Fail", __func__);
18722 return -EINVAL;
18723 }
18724
18725 vos_mem_copy(hb_params, buf, buf_len);
Leo Changd9df8aa2013-09-26 13:32:26 -070018726 smeStatus = sme_LPHBConfigReq((tHalHandle)(pHddCtx->hHal),
18727 hb_params,
18728 wlan_hdd_cfg80211_lphb_ind_handler);
18729 if (eHAL_STATUS_SUCCESS != smeStatus)
Leo Chang9056f462013-08-01 19:21:11 -070018730 {
Leo Changd9df8aa2013-09-26 13:32:26 -070018731 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
18732 "LPHB Config Fail, disable");
Leo Chang9056f462013-08-01 19:21:11 -070018733 vos_mem_free(hb_params);
18734 }
Leo Chang9056f462013-08-01 19:21:11 -070018735 return 0;
18736 }
18737#endif /* FEATURE_WLAN_LPHB */
18738 default:
c_hpothu6ff1c3c2013-10-01 19:01:57 +053018739 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
18740 "%s: unsupported event",__func__);
Leo Chang9056f462013-08-01 19:21:11 -070018741 return -EOPNOTSUPP;
18742 }
18743
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053018744 EXIT();
18745 return err;
Leo Chang9056f462013-08-01 19:21:11 -070018746}
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053018747
Anand N Sunkade9adb1b2015-07-29 09:56:45 +053018748static int wlan_hdd_cfg80211_testmode(struct wiphy *wiphy,
18749#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,12,0))
18750 struct wireless_dev *wdev,
18751#endif
18752 void *data, int len)
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053018753{
18754 int ret;
18755
18756 vos_ssr_protect(__func__);
18757 ret = __wlan_hdd_cfg80211_testmode(wiphy, data, len);
18758 vos_ssr_unprotect(__func__);
18759
18760 return ret;
18761}
Leo Chang9056f462013-08-01 19:21:11 -070018762#endif /* CONFIG_NL80211_TESTMODE */
18763
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053018764static int __wlan_hdd_cfg80211_dump_survey(struct wiphy *wiphy,
Madan Mohan Koyyalamudid9383fd2013-08-13 09:27:30 +053018765 struct net_device *dev,
18766 int idx, struct survey_info *survey)
18767{
18768 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
18769 hdd_context_t *pHddCtx;
Mihir Sheted9072e02013-08-21 17:02:29 +053018770 hdd_station_ctx_t *pHddStaCtx;
Madan Mohan Koyyalamudid9383fd2013-08-13 09:27:30 +053018771 tHalHandle halHandle;
Mihir Sheted9072e02013-08-21 17:02:29 +053018772 v_U32_t channel = 0, freq = 0; /* Initialization Required */
Madan Mohan Koyyalamudid9383fd2013-08-13 09:27:30 +053018773 v_S7_t snr,rssi;
18774 int status, i, j, filled = 0;
18775
18776 ENTER();
18777
Madan Mohan Koyyalamudid9383fd2013-08-13 09:27:30 +053018778 if (NULL == pAdapter)
18779 {
18780 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
18781 "%s: HDD adapter is Null", __func__);
18782 return -ENODEV;
18783 }
18784
18785 if (NULL == wiphy)
18786 {
18787 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
18788 "%s: wiphy is Null", __func__);
18789 return -ENODEV;
18790 }
18791
18792 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
18793 status = wlan_hdd_validate_context(pHddCtx);
Madan Mohan Koyyalamudid9383fd2013-08-13 09:27:30 +053018794 if (0 != status)
18795 {
Madan Mohan Koyyalamudid9383fd2013-08-13 09:27:30 +053018796 return status;
18797 }
18798
Mihir Sheted9072e02013-08-21 17:02:29 +053018799 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
18800
Madan Mohan Koyyalamudid9383fd2013-08-13 09:27:30 +053018801 if (0 == pHddCtx->cfg_ini->fEnableSNRMonitoring ||
Mihir Sheted9072e02013-08-21 17:02:29 +053018802 0 != pAdapter->survey_idx ||
18803 eConnectionState_Associated != pHddStaCtx->conn_info.connState)
Madan Mohan Koyyalamudid9383fd2013-08-13 09:27:30 +053018804 {
18805 /* The survey dump ops when implemented completely is expected to
18806 * return a survey of all channels and the ops is called by the
18807 * kernel with incremental values of the argument 'idx' till it
18808 * returns -ENONET. But we can only support the survey for the
18809 * operating channel for now. survey_idx is used to track
18810 * that the ops is called only once and then return -ENONET for
18811 * the next iteration
18812 */
18813 pAdapter->survey_idx = 0;
18814 return -ENONET;
18815 }
18816
Mukul Sharma9d5233b2015-06-11 20:28:20 +053018817 if (VOS_TRUE == pHddStaCtx->hdd_ReassocScenario)
18818 {
18819 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
18820 "%s: Roaming in progress, hence return ", __func__);
18821 return -ENONET;
18822 }
18823
Madan Mohan Koyyalamudid9383fd2013-08-13 09:27:30 +053018824 halHandle = WLAN_HDD_GET_HAL_CTX(pAdapter);
18825
18826 wlan_hdd_get_snr(pAdapter, &snr);
18827 wlan_hdd_get_rssi(pAdapter, &rssi);
18828
Konamki, Sreelakshmi7b464be2015-07-14 12:17:01 +053018829 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
18830 TRACE_CODE_HDD_CFG80211_DUMP_SURVEY,
18831 pAdapter->sessionId, pAdapter->device_mode));
Madan Mohan Koyyalamudid9383fd2013-08-13 09:27:30 +053018832 sme_GetOperationChannel(halHandle, &channel, pAdapter->sessionId);
18833 hdd_wlan_get_freq(channel, &freq);
18834
18835
18836 for (i = 0; i < IEEE80211_NUM_BANDS; i++)
18837 {
18838 if (NULL == wiphy->bands[i])
18839 {
18840 VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_INFO,
18841 "%s: wiphy->bands[i] is NULL, i = %d", __func__, i);
18842 continue;
18843 }
18844
18845 for (j = 0; j < wiphy->bands[i]->n_channels; j++)
18846 {
18847 struct ieee80211_supported_band *band = wiphy->bands[i];
18848
18849 if (band->channels[j].center_freq == (v_U16_t)freq)
18850 {
18851 survey->channel = &band->channels[j];
18852 /* The Rx BDs contain SNR values in dB for the received frames
18853 * while the supplicant expects noise. So we calculate and
18854 * return the value of noise (dBm)
18855 * SNR (dB) = RSSI (dBm) - NOISE (dBm)
18856 */
18857 survey->noise = rssi - snr;
18858 survey->filled = SURVEY_INFO_NOISE_DBM;
18859 filled = 1;
18860 }
18861 }
18862 }
18863
18864 if (filled)
18865 pAdapter->survey_idx = 1;
18866 else
18867 {
18868 pAdapter->survey_idx = 0;
18869 return -ENONET;
18870 }
18871
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053018872 EXIT();
Madan Mohan Koyyalamudid9383fd2013-08-13 09:27:30 +053018873 return 0;
18874}
18875
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053018876static int wlan_hdd_cfg80211_dump_survey(struct wiphy *wiphy,
18877 struct net_device *dev,
18878 int idx, struct survey_info *survey)
18879{
18880 int ret;
18881
18882 vos_ssr_protect(__func__);
18883 ret = __wlan_hdd_cfg80211_dump_survey(wiphy, dev, idx, survey);
18884 vos_ssr_unprotect(__func__);
18885
18886 return ret;
18887}
18888
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053018889/*
Mahesh A Saptasagarbcc5b662014-06-02 21:46:23 +053018890 * FUNCTION: __wlan_hdd_cfg80211_resume_wlan
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053018891 * this is called when cfg80211 driver resume
18892 * driver updates latest sched_scan scan result(if any) to cfg80211 database
18893 */
Mahesh A Saptasagarbcc5b662014-06-02 21:46:23 +053018894int __wlan_hdd_cfg80211_resume_wlan(struct wiphy *wiphy)
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053018895{
18896 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
18897 hdd_adapter_t *pAdapter;
18898 hdd_adapter_list_node_t *pAdapterNode, *pNext;
18899 VOS_STATUS status = VOS_STATUS_SUCCESS;
18900
18901 ENTER();
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053018902
Mahesh A Saptasagar74088392015-02-05 17:22:09 +053018903 if (0 != wlan_hdd_validate_context(pHddCtx))
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053018904 {
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053018905 return 0;
18906 }
18907
Konamki, Sreelakshmi7b464be2015-07-14 12:17:01 +053018908 MTRACE(vos_trace(VOS_MODULE_ID_HDD, TRACE_CODE_HDD_CFG80211_RESUME_WLAN,
18909 NO_SESSION, pHddCtx->isWiphySuspended));
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053018910 spin_lock(&pHddCtx->schedScan_lock);
18911 pHddCtx->isWiphySuspended = FALSE;
18912 if (TRUE != pHddCtx->isSchedScanUpdatePending)
18913 {
18914 spin_unlock(&pHddCtx->schedScan_lock);
18915 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
18916 "%s: Return resume is not due to PNO indication", __func__);
18917 return 0;
18918 }
18919 // Reset flag to avoid updatating cfg80211 data old results again
18920 pHddCtx->isSchedScanUpdatePending = FALSE;
18921 spin_unlock(&pHddCtx->schedScan_lock);
18922
18923 status = hdd_get_front_adapter ( pHddCtx, &pAdapterNode );
18924
18925 while ( NULL != pAdapterNode && VOS_STATUS_SUCCESS == status )
18926 {
18927 pAdapter = pAdapterNode->pAdapter;
18928 if ( (NULL != pAdapter) &&
18929 (WLAN_HDD_INFRA_STATION == pAdapter->device_mode) )
18930 {
18931 if (0 != wlan_hdd_cfg80211_update_bss(pHddCtx->wiphy, pAdapter))
Mahesh A Saptasagarb9c50402014-01-16 15:49:22 +053018932 {
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053018933 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_WARN,
18934 "%s: NO SCAN result", __func__);
Mahesh A Saptasagarb9c50402014-01-16 15:49:22 +053018935 }
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053018936 else
Mahesh A Saptasagarb9c50402014-01-16 15:49:22 +053018937 {
18938 /* Acquire wakelock to handle the case where APP's tries to
18939 * suspend immediately after updating the scan results. Whis
18940 * results in app's is in suspended state and not able to
18941 * process the connect request to AP
18942 */
Sushant Kaushik83392fa2015-05-05 17:44:40 +053018943 hdd_prevent_suspend_timeout(2000,
18944 WIFI_POWER_EVENT_WAKELOCK_RESUME_WLAN);
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053018945 cfg80211_sched_scan_results(pHddCtx->wiphy);
Mahesh A Saptasagarb9c50402014-01-16 15:49:22 +053018946 }
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053018947
18948 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
18949 "%s : cfg80211 scan result database updated", __func__);
18950
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053018951 EXIT();
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053018952 return 0;
18953
18954 }
18955 status = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
18956 pAdapterNode = pNext;
18957 }
18958
18959 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
18960 "%s: Failed to find Adapter", __func__);
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053018961 EXIT();
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053018962 return 0;
18963}
18964
Mahesh A Saptasagarbcc5b662014-06-02 21:46:23 +053018965int wlan_hdd_cfg80211_resume_wlan(struct wiphy *wiphy)
18966{
18967 int ret;
18968
18969 vos_ssr_protect(__func__);
18970 ret = __wlan_hdd_cfg80211_resume_wlan(wiphy);
18971 vos_ssr_unprotect(__func__);
18972
18973 return ret;
18974}
18975
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053018976/*
Mahesh A Saptasagarbcc5b662014-06-02 21:46:23 +053018977 * FUNCTION: __wlan_hdd_cfg80211_suspend_wlan
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053018978 * this is called when cfg80211 driver suspends
18979 */
Mahesh A Saptasagarbcc5b662014-06-02 21:46:23 +053018980int __wlan_hdd_cfg80211_suspend_wlan(struct wiphy *wiphy,
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053018981 struct cfg80211_wowlan *wow)
18982{
18983 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +053018984 int ret = 0;
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053018985
18986 ENTER();
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053018987
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +053018988 ret = wlan_hdd_validate_context(pHddCtx);
18989 if (0 != ret)
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053018990 {
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +053018991 return ret;
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053018992 }
18993
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +053018994
Konamki, Sreelakshmi7b464be2015-07-14 12:17:01 +053018995 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
18996 TRACE_CODE_HDD_CFG80211_SUSPEND_WLAN,
18997 NO_SESSION, pHddCtx->isWiphySuspended));
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053018998 pHddCtx->isWiphySuspended = TRUE;
18999
19000 EXIT();
19001
19002 return 0;
19003}
19004
Mahesh A Saptasagarbcc5b662014-06-02 21:46:23 +053019005int wlan_hdd_cfg80211_suspend_wlan(struct wiphy *wiphy,
19006 struct cfg80211_wowlan *wow)
19007{
19008 int ret;
19009
19010 vos_ssr_protect(__func__);
19011 ret = __wlan_hdd_cfg80211_suspend_wlan(wiphy, wow);
19012 vos_ssr_unprotect(__func__);
19013
19014 return ret;
19015}
Padma, Santhosh Kumar2ccac212015-10-20 17:27:27 +053019016
19017#ifdef FEATURE_OEM_DATA_SUPPORT
19018static void wlan_hdd_cfg80211_oem_data_rsp_ind_new(void *ctx,
19019 void *pMsg)
19020{
19021 hdd_context_t *pHddCtx = (hdd_context_t *)ctx;
19022
19023 ENTER();
19024
19025 if (wlan_hdd_validate_context(pHddCtx)) {
19026 return;
19027 }
19028 if (!pMsg)
19029 {
19030 hddLog(VOS_TRACE_LEVEL_ERROR, FL("pMsg is null"));
19031 return;
19032 }
19033
19034 send_oem_data_rsp_msg(sizeof(tOemDataRspNew), pMsg);
19035
19036 EXIT();
19037 return;
19038
19039}
19040
19041void wlan_hdd_cfg80211_oemdata_callback(void *ctx, const tANI_U16 evType,
19042 void *pMsg)
19043{
19044 hdd_context_t *pHddCtx = (hdd_context_t *)ctx;
19045
19046 ENTER();
19047
19048 if (wlan_hdd_validate_context(pHddCtx)) {
19049 return;
19050 }
19051
19052 hddLog(VOS_TRACE_LEVEL_INFO, FL("Rcvd Event (%d)"), evType);
19053
19054 switch(evType) {
19055 case SIR_HAL_START_OEM_DATA_RSP_IND_NEW:
19056 wlan_hdd_cfg80211_oem_data_rsp_ind_new(ctx, pMsg);
19057 break;
19058 default:
19059 hddLog(VOS_TRACE_LEVEL_ERROR, FL("invalid event type %d "), evType);
19060 break;
19061 }
19062 EXIT();
19063}
19064#endif
19065
Jeff Johnson295189b2012-06-20 16:38:30 -070019066/* cfg80211_ops */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053019067static struct cfg80211_ops wlan_hdd_cfg80211_ops =
Jeff Johnson295189b2012-06-20 16:38:30 -070019068{
19069 .add_virtual_intf = wlan_hdd_add_virtual_intf,
19070 .del_virtual_intf = wlan_hdd_del_virtual_intf,
19071 .change_virtual_intf = wlan_hdd_cfg80211_change_iface,
19072 .change_station = wlan_hdd_change_station,
19073#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,4,0))
19074 .add_beacon = wlan_hdd_cfg80211_add_beacon,
19075 .del_beacon = wlan_hdd_cfg80211_del_beacon,
19076 .set_beacon = wlan_hdd_cfg80211_set_beacon,
Jeff Johnson04dd8a82012-06-29 20:41:40 -070019077#else
19078 .start_ap = wlan_hdd_cfg80211_start_ap,
19079 .change_beacon = wlan_hdd_cfg80211_change_beacon,
19080 .stop_ap = wlan_hdd_cfg80211_stop_ap,
Jeff Johnson295189b2012-06-20 16:38:30 -070019081#endif
19082 .change_bss = wlan_hdd_cfg80211_change_bss,
19083 .add_key = wlan_hdd_cfg80211_add_key,
19084 .get_key = wlan_hdd_cfg80211_get_key,
19085 .del_key = wlan_hdd_cfg80211_del_key,
19086 .set_default_key = wlan_hdd_cfg80211_set_default_key,
Jeff Johnson3bbe4bf2013-01-18 17:05:29 -080019087#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,6,0))
Jeff Johnson295189b2012-06-20 16:38:30 -070019088 .set_channel = wlan_hdd_cfg80211_set_channel,
Jeff Johnson3bbe4bf2013-01-18 17:05:29 -080019089#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070019090 .scan = wlan_hdd_cfg80211_scan,
19091 .connect = wlan_hdd_cfg80211_connect,
19092 .disconnect = wlan_hdd_cfg80211_disconnect,
19093 .join_ibss = wlan_hdd_cfg80211_join_ibss,
19094 .leave_ibss = wlan_hdd_cfg80211_leave_ibss,
19095 .set_wiphy_params = wlan_hdd_cfg80211_set_wiphy_params,
19096 .set_tx_power = wlan_hdd_cfg80211_set_txpower,
19097 .get_tx_power = wlan_hdd_cfg80211_get_txpower,
Jeff Johnson295189b2012-06-20 16:38:30 -070019098 .remain_on_channel = wlan_hdd_cfg80211_remain_on_channel,
19099 .cancel_remain_on_channel = wlan_hdd_cfg80211_cancel_remain_on_channel,
DARAM SUDHA39eede62014-02-12 11:16:40 +053019100 .mgmt_tx = wlan_hdd_mgmt_tx,
Jeff Johnson295189b2012-06-20 16:38:30 -070019101#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
19102 .mgmt_tx_cancel_wait = wlan_hdd_cfg80211_mgmt_tx_cancel_wait,
19103 .set_default_mgmt_key = wlan_hdd_set_default_mgmt_key,
19104 .set_txq_params = wlan_hdd_set_txq_params,
19105#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070019106 .get_station = wlan_hdd_cfg80211_get_station,
19107 .set_power_mgmt = wlan_hdd_cfg80211_set_power_mgmt,
19108 .del_station = wlan_hdd_cfg80211_del_station,
Jeff Johnson04dd8a82012-06-29 20:41:40 -070019109 .add_station = wlan_hdd_cfg80211_add_station,
19110#ifdef FEATURE_WLAN_LFR
19111 .set_pmksa = wlan_hdd_cfg80211_set_pmksa,
19112 .del_pmksa = wlan_hdd_cfg80211_del_pmksa,
19113 .flush_pmksa = wlan_hdd_cfg80211_flush_pmksa,
19114#endif
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070019115#if defined(WLAN_FEATURE_VOWIFI_11R) && defined(KERNEL_SUPPORT_11R_CFG80211)
19116 .update_ft_ies = wlan_hdd_cfg80211_update_ft_ies,
19117#endif
Mohit Khanna698ba2a2012-12-04 15:08:18 -080019118#ifdef FEATURE_WLAN_TDLS
19119 .tdls_mgmt = wlan_hdd_cfg80211_tdls_mgmt,
19120 .tdls_oper = wlan_hdd_cfg80211_tdls_oper,
19121#endif
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053019122#ifdef WLAN_FEATURE_GTK_OFFLOAD
19123 .set_rekey_data = wlan_hdd_cfg80211_set_rekey_data,
19124#endif /* WLAN_FEATURE_GTK_OFFLOAD */
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053019125#ifdef FEATURE_WLAN_SCAN_PNO
19126 .sched_scan_start = wlan_hdd_cfg80211_sched_scan_start,
19127 .sched_scan_stop = wlan_hdd_cfg80211_sched_scan_stop,
19128#endif /*FEATURE_WLAN_SCAN_PNO */
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053019129 .resume = wlan_hdd_cfg80211_resume_wlan,
19130 .suspend = wlan_hdd_cfg80211_suspend_wlan,
Gopichand Nakkalac005b7c2013-05-14 16:04:14 +053019131 .set_mac_acl = wlan_hdd_cfg80211_set_mac_acl,
Leo Chang9056f462013-08-01 19:21:11 -070019132#ifdef WLAN_NL80211_TESTMODE
19133 .testmode_cmd = wlan_hdd_cfg80211_testmode,
19134#endif
Madan Mohan Koyyalamudid9383fd2013-08-13 09:27:30 +053019135 .dump_survey = wlan_hdd_cfg80211_dump_survey,
Jeff Johnson295189b2012-06-20 16:38:30 -070019136};
19137