blob: 1d43e6d210203be90721df2851de1458f5f82e81 [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
210static 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
Jeff Johnson295189b2012-06-20 16:38:30 -0700228static struct ieee80211_channel hdd_social_channels_2_4_GHZ[] =
229{
230 HDD2GHZCHAN(2412, 1, 0) ,
231 HDD2GHZCHAN(2437, 6, 0) ,
232 HDD2GHZCHAN(2462, 11, 0) ,
233};
Jeff Johnson295189b2012-06-20 16:38:30 -0700234
235static struct ieee80211_channel hdd_channels_5_GHZ[] =
236{
Madan Mohan Koyyalamudic3a240c2012-09-28 15:34:08 -0700237 HDD5GHZCHAN(4920, 240, 0) ,
238 HDD5GHZCHAN(4940, 244, 0) ,
239 HDD5GHZCHAN(4960, 248, 0) ,
240 HDD5GHZCHAN(4980, 252, 0) ,
241 HDD5GHZCHAN(5040, 208, 0) ,
242 HDD5GHZCHAN(5060, 212, 0) ,
243 HDD5GHZCHAN(5080, 216, 0) ,
Jeff Johnson295189b2012-06-20 16:38:30 -0700244 HDD5GHZCHAN(5180, 36, 0) ,
245 HDD5GHZCHAN(5200, 40, 0) ,
246 HDD5GHZCHAN(5220, 44, 0) ,
247 HDD5GHZCHAN(5240, 48, 0) ,
248 HDD5GHZCHAN(5260, 52, 0) ,
249 HDD5GHZCHAN(5280, 56, 0) ,
250 HDD5GHZCHAN(5300, 60, 0) ,
251 HDD5GHZCHAN(5320, 64, 0) ,
252 HDD5GHZCHAN(5500,100, 0) ,
253 HDD5GHZCHAN(5520,104, 0) ,
254 HDD5GHZCHAN(5540,108, 0) ,
255 HDD5GHZCHAN(5560,112, 0) ,
256 HDD5GHZCHAN(5580,116, 0) ,
257 HDD5GHZCHAN(5600,120, 0) ,
258 HDD5GHZCHAN(5620,124, 0) ,
259 HDD5GHZCHAN(5640,128, 0) ,
260 HDD5GHZCHAN(5660,132, 0) ,
261 HDD5GHZCHAN(5680,136, 0) ,
262 HDD5GHZCHAN(5700,140, 0) ,
Leo Chang80de3c22013-11-26 10:52:12 -0800263#ifdef FEATURE_WLAN_CH144
264 HDD5GHZCHAN(5720,144, 0) ,
265#endif /* FEATURE_WLAN_CH144 */
Jeff Johnson295189b2012-06-20 16:38:30 -0700266 HDD5GHZCHAN(5745,149, 0) ,
267 HDD5GHZCHAN(5765,153, 0) ,
268 HDD5GHZCHAN(5785,157, 0) ,
269 HDD5GHZCHAN(5805,161, 0) ,
270 HDD5GHZCHAN(5825,165, 0) ,
271};
272
273static struct ieee80211_rate g_mode_rates[] =
274{
Gopichand Nakkala747461f2013-04-24 19:24:45 +0530275 HDD_G_MODE_RATETAB(10, 0x1, 0),
276 HDD_G_MODE_RATETAB(20, 0x2, 0),
277 HDD_G_MODE_RATETAB(55, 0x4, 0),
278 HDD_G_MODE_RATETAB(110, 0x8, 0),
279 HDD_G_MODE_RATETAB(60, 0x10, 0),
280 HDD_G_MODE_RATETAB(90, 0x20, 0),
281 HDD_G_MODE_RATETAB(120, 0x40, 0),
282 HDD_G_MODE_RATETAB(180, 0x80, 0),
283 HDD_G_MODE_RATETAB(240, 0x100, 0),
284 HDD_G_MODE_RATETAB(360, 0x200, 0),
285 HDD_G_MODE_RATETAB(480, 0x400, 0),
Jeff Johnson295189b2012-06-20 16:38:30 -0700286 HDD_G_MODE_RATETAB(540, 0x800, 0),
Gopichand Nakkala747461f2013-04-24 19:24:45 +0530287};
Jeff Johnson295189b2012-06-20 16:38:30 -0700288
289static struct ieee80211_rate a_mode_rates[] =
290{
Gopichand Nakkala747461f2013-04-24 19:24:45 +0530291 HDD_G_MODE_RATETAB(60, 0x10, 0),
292 HDD_G_MODE_RATETAB(90, 0x20, 0),
293 HDD_G_MODE_RATETAB(120, 0x40, 0),
294 HDD_G_MODE_RATETAB(180, 0x80, 0),
295 HDD_G_MODE_RATETAB(240, 0x100, 0),
296 HDD_G_MODE_RATETAB(360, 0x200, 0),
297 HDD_G_MODE_RATETAB(480, 0x400, 0),
Jeff Johnson295189b2012-06-20 16:38:30 -0700298 HDD_G_MODE_RATETAB(540, 0x800, 0),
299};
300
301static struct ieee80211_supported_band wlan_hdd_band_2_4_GHZ =
302{
303 .channels = hdd_channels_2_4_GHZ,
304 .n_channels = ARRAY_SIZE(hdd_channels_2_4_GHZ),
305 .band = IEEE80211_BAND_2GHZ,
306 .bitrates = g_mode_rates,
307 .n_bitrates = g_mode_rates_size,
308 .ht_cap.ht_supported = 1,
309 .ht_cap.cap = IEEE80211_HT_CAP_SGI_20
310 | IEEE80211_HT_CAP_GRN_FLD
311 | IEEE80211_HT_CAP_DSSSCCK40
312 | IEEE80211_HT_CAP_LSIG_TXOP_PROT,
313 .ht_cap.ampdu_factor = IEEE80211_HT_MAX_AMPDU_64K,
314 .ht_cap.ampdu_density = IEEE80211_HT_MPDU_DENSITY_16,
315 .ht_cap.mcs.rx_mask = { 0xff, 0, 0, 0, 0, 0, 0, 0, 0, 0, },
316 .ht_cap.mcs.rx_highest = cpu_to_le16( 72 ),
317 .ht_cap.mcs.tx_params = IEEE80211_HT_MCS_TX_DEFINED,
318};
319
Jeff Johnson295189b2012-06-20 16:38:30 -0700320static struct ieee80211_supported_band wlan_hdd_band_p2p_2_4_GHZ =
321{
322 .channels = hdd_social_channels_2_4_GHZ,
323 .n_channels = ARRAY_SIZE(hdd_social_channels_2_4_GHZ),
324 .band = IEEE80211_BAND_2GHZ,
325 .bitrates = g_mode_rates,
326 .n_bitrates = g_mode_rates_size,
327 .ht_cap.ht_supported = 1,
328 .ht_cap.cap = IEEE80211_HT_CAP_SGI_20
329 | IEEE80211_HT_CAP_GRN_FLD
330 | IEEE80211_HT_CAP_DSSSCCK40
331 | IEEE80211_HT_CAP_LSIG_TXOP_PROT,
332 .ht_cap.ampdu_factor = IEEE80211_HT_MAX_AMPDU_64K,
333 .ht_cap.ampdu_density = IEEE80211_HT_MPDU_DENSITY_16,
334 .ht_cap.mcs.rx_mask = { 0xff, 0, 0, 0, 0, 0, 0, 0, 0, 0, },
335 .ht_cap.mcs.rx_highest = cpu_to_le16( 72 ),
336 .ht_cap.mcs.tx_params = IEEE80211_HT_MCS_TX_DEFINED,
337};
Jeff Johnson295189b2012-06-20 16:38:30 -0700338
339static struct ieee80211_supported_band wlan_hdd_band_5_GHZ =
340{
341 .channels = hdd_channels_5_GHZ,
342 .n_channels = ARRAY_SIZE(hdd_channels_5_GHZ),
343 .band = IEEE80211_BAND_5GHZ,
344 .bitrates = a_mode_rates,
345 .n_bitrates = a_mode_rates_size,
346 .ht_cap.ht_supported = 1,
347 .ht_cap.cap = IEEE80211_HT_CAP_SGI_20
348 | IEEE80211_HT_CAP_GRN_FLD
349 | IEEE80211_HT_CAP_DSSSCCK40
350 | IEEE80211_HT_CAP_LSIG_TXOP_PROT
351 | IEEE80211_HT_CAP_SGI_40
352 | IEEE80211_HT_CAP_SUP_WIDTH_20_40,
353 .ht_cap.ampdu_factor = IEEE80211_HT_MAX_AMPDU_64K,
354 .ht_cap.ampdu_density = IEEE80211_HT_MPDU_DENSITY_16,
355 .ht_cap.mcs.rx_mask = { 0xff, 0, 0, 0, 0, 0, 0, 0, 0, 0, },
356 .ht_cap.mcs.rx_highest = cpu_to_le16( 72 ),
357 .ht_cap.mcs.tx_params = IEEE80211_HT_MCS_TX_DEFINED,
358};
359
Gopichand Nakkala747461f2013-04-24 19:24:45 +0530360/* This structure contain information what kind of frame are expected in
Jeff Johnson295189b2012-06-20 16:38:30 -0700361 TX/RX direction for each kind of interface */
362static const struct ieee80211_txrx_stypes
363wlan_hdd_txrx_stypes[NUM_NL80211_IFTYPES] = {
364 [NL80211_IFTYPE_STATION] = {
365 .tx = 0xffff,
366 .rx = BIT(SIR_MAC_MGMT_ACTION) |
367 BIT(SIR_MAC_MGMT_PROBE_REQ),
368 },
369 [NL80211_IFTYPE_AP] = {
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 Johnsonbc006202013-04-29 14:05:30 -0700379 [NL80211_IFTYPE_ADHOC] = {
380 .tx = 0xffff,
381 .rx = BIT(SIR_MAC_MGMT_ASSOC_REQ) |
382 BIT(SIR_MAC_MGMT_REASSOC_REQ) |
383 BIT(SIR_MAC_MGMT_PROBE_REQ) |
384 BIT(SIR_MAC_MGMT_DISASSOC) |
385 BIT(SIR_MAC_MGMT_AUTH) |
386 BIT(SIR_MAC_MGMT_DEAUTH) |
387 BIT(SIR_MAC_MGMT_ACTION),
388 },
Jeff Johnson295189b2012-06-20 16:38:30 -0700389 [NL80211_IFTYPE_P2P_CLIENT] = {
390 .tx = 0xffff,
391 .rx = BIT(SIR_MAC_MGMT_ACTION) |
392 BIT(SIR_MAC_MGMT_PROBE_REQ),
393 },
394 [NL80211_IFTYPE_P2P_GO] = {
395 /* This is also same as for SoftAP */
396 .tx = 0xffff,
397 .rx = BIT(SIR_MAC_MGMT_ASSOC_REQ) |
398 BIT(SIR_MAC_MGMT_REASSOC_REQ) |
399 BIT(SIR_MAC_MGMT_PROBE_REQ) |
400 BIT(SIR_MAC_MGMT_DISASSOC) |
401 BIT(SIR_MAC_MGMT_AUTH) |
402 BIT(SIR_MAC_MGMT_DEAUTH) |
403 BIT(SIR_MAC_MGMT_ACTION),
404 },
Jeff Johnson295189b2012-06-20 16:38:30 -0700405};
406
Sudhir Sattayappa Kohalli278eee52013-01-16 17:35:13 -0800407#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,4,0))
Sudhir Sattayappa Kohalli278eee52013-01-16 17:35:13 -0800408static const struct ieee80211_iface_limit
409wlan_hdd_iface_limit[] = {
410 {
Sunil Ravia72c3992013-01-31 06:12:22 -0800411 /* max = 3 ; Our driver create two interfaces during driver init
412 * wlan0 and p2p0 interfaces. p2p0 is considered as station
413 * interface until a group is formed. In JB architecture, once the
414 * group is formed, interface type of p2p0 is changed to P2P GO or
415 * Client.
416 * When supplicant remove the group, it first issue a set interface
417 * cmd to change the mode back to Station. In JB this works fine as
418 * we advertize two station type interface during driver init.
419 * Some vendors create separate interface for P2P GO/Client,
420 * after group formation(Third one). But while group remove
421 * supplicant first tries to change the mode(3rd interface) to STATION
422 * But as we advertized only two sta type interfaces nl80211 was
423 * returning error for the third one which was leading to failure in
424 * delete interface. Ideally while removing the group, supplicant
425 * should not try to change the 3rd interface mode to Station type.
426 * Till we get a fix in wpa_supplicant, we advertize max STA
427 * interface type to 3
428 */
429 .max = 3,
Sudhir Sattayappa Kohalli278eee52013-01-16 17:35:13 -0800430 .types = BIT(NL80211_IFTYPE_STATION),
431 },
432 {
433 .max = 1,
Jeff Johnsonbc006202013-04-29 14:05:30 -0700434 .types = BIT(NL80211_IFTYPE_ADHOC) | BIT(NL80211_IFTYPE_AP),
Sudhir Sattayappa Kohalli278eee52013-01-16 17:35:13 -0800435 },
436 {
437 .max = 1,
438 .types = BIT(NL80211_IFTYPE_P2P_GO) |
439 BIT(NL80211_IFTYPE_P2P_CLIENT),
440 },
441};
442
443/* By default, only single channel concurrency is allowed */
444static struct ieee80211_iface_combination
445wlan_hdd_iface_combination = {
446 .limits = wlan_hdd_iface_limit,
447 .num_different_channels = 1,
Sunil Ravia72c3992013-01-31 06:12:22 -0800448 /*
449 * max = WLAN_MAX_INTERFACES ; JellyBean architecture creates wlan0
450 * and p2p0 interfaces during driver init
451 * Some vendors create separate interface for P2P operations.
452 * wlan0: STA interface
453 * p2p0: P2P Device interface, action frames goes
454 * through this interface.
455 * p2p-xx: P2P interface, After GO negotiation this interface is
456 * created for p2p operations(GO/CLIENT interface).
457 */
458 .max_interfaces = WLAN_MAX_INTERFACES,
Sudhir Sattayappa Kohalli278eee52013-01-16 17:35:13 -0800459 .n_limits = ARRAY_SIZE(wlan_hdd_iface_limit),
460 .beacon_int_infra_match = false,
461};
462#endif
Sudhir Sattayappa Kohalli278eee52013-01-16 17:35:13 -0800463
Jeff Johnson295189b2012-06-20 16:38:30 -0700464static struct cfg80211_ops wlan_hdd_cfg80211_ops;
465
466/* Data rate 100KBPS based on IE Index */
467struct index_data_rate_type
468{
469 v_U8_t beacon_rate_index;
470 v_U16_t supported_rate[4];
471};
472
473/* 11B, 11G Rate table include Basic rate and Extended rate
474 The IDX field is the rate index
475 The HI field is the rate when RSSI is strong or being ignored
476 (in this case we report actual rate)
477 The MID field is the rate when RSSI is moderate
478 (in this case we cap 11b rates at 5.5 and 11g rates at 24)
479 The LO field is the rate when RSSI is low
480 (in this case we don't report rates, actual current rate used)
481 */
482static const struct
483{
484 v_U8_t beacon_rate_index;
Madan Mohan Koyyalamudi8df78d52012-11-02 12:30:06 -0700485 v_U16_t supported_rate[4];
Jeff Johnson295189b2012-06-20 16:38:30 -0700486} supported_data_rate[] =
487{
Madan Mohan Koyyalamudi8df78d52012-11-02 12:30:06 -0700488/* IDX HI HM LM LO (RSSI-based index */
489 {2, { 10, 10, 10, 0}},
490 {4, { 20, 20, 10, 0}},
491 {11, { 55, 20, 10, 0}},
492 {12, { 60, 55, 20, 0}},
493 {18, { 90, 55, 20, 0}},
494 {22, {110, 55, 20, 0}},
495 {24, {120, 90, 60, 0}},
496 {36, {180, 120, 60, 0}},
497 {44, {220, 180, 60, 0}},
498 {48, {240, 180, 90, 0}},
499 {66, {330, 180, 90, 0}},
500 {72, {360, 240, 90, 0}},
501 {96, {480, 240, 120, 0}},
502 {108, {540, 240, 120, 0}}
Jeff Johnson295189b2012-06-20 16:38:30 -0700503};
504
505/* MCS Based rate table */
506static struct index_data_rate_type supported_mcs_rate[] =
507{
508/* MCS L20 L40 S20 S40 */
509 {0, {65, 135, 72, 150}},
510 {1, {130, 270, 144, 300}},
511 {2, {195, 405, 217, 450}},
512 {3, {260, 540, 289, 600}},
513 {4, {390, 810, 433, 900}},
514 {5, {520, 1080, 578, 1200}},
515 {6, {585, 1215, 650, 1350}},
516 {7, {650, 1350, 722, 1500}}
517};
518
Leo Chang6f8870f2013-03-26 18:11:36 -0700519#ifdef WLAN_FEATURE_11AC
520
Gopichand Nakkala4c705372013-04-24 13:20:33 +0530521#define DATA_RATE_11AC_MCS_MASK 0x03
Leo Chang6f8870f2013-03-26 18:11:36 -0700522
523struct index_vht_data_rate_type
524{
525 v_U8_t beacon_rate_index;
Gopichand Nakkala4c705372013-04-24 13:20:33 +0530526 v_U16_t supported_VHT80_rate[2];
527 v_U16_t supported_VHT40_rate[2];
528 v_U16_t supported_VHT20_rate[2];
Leo Chang6f8870f2013-03-26 18:11:36 -0700529};
530
531typedef enum
532{
533 DATA_RATE_11AC_MAX_MCS_7,
534 DATA_RATE_11AC_MAX_MCS_8,
535 DATA_RATE_11AC_MAX_MCS_9,
536 DATA_RATE_11AC_MAX_MCS_NA
537} eDataRate11ACMaxMcs;
538
Mahesh A Saptasagar7bd6ad42014-07-21 18:56:33 +0530539/* SSID broadcast type */
540typedef enum eSSIDBcastType
541{
542 eBCAST_UNKNOWN = 0,
543 eBCAST_NORMAL = 1,
544 eBCAST_HIDDEN = 2,
545} tSSIDBcastType;
546
Leo Chang6f8870f2013-03-26 18:11:36 -0700547/* MCS Based VHT rate table */
548static struct index_vht_data_rate_type supported_vht_mcs_rate[] =
549{
Gopichand Nakkala4c705372013-04-24 13:20:33 +0530550/* MCS L80 S80 L40 S40 L20 S40*/
551 {0, {293, 325}, {135, 150}, {65, 72}},
552 {1, {585, 650}, {270, 300}, {130, 144}},
553 {2, {878, 975}, {405, 450}, {195, 217}},
554 {3, {1170, 1300}, {540, 600}, {260, 289}},
555 {4, {1755, 1950}, {810, 900}, {390, 433}},
556 {5, {2340, 2600}, {1080, 1200}, {520, 578}},
557 {6, {2633, 2925}, {1215, 1350}, {585, 650}},
558 {7, {2925, 3250}, {1350, 1500}, {650, 722}},
559 {8, {3510, 3900}, {1620, 1800}, {780, 867}},
560 {9, {3900, 4333}, {1800, 2000}, {780, 867}}
Leo Chang6f8870f2013-03-26 18:11:36 -0700561};
562#endif /* WLAN_FEATURE_11AC */
563
c_hpothu79aab322014-07-14 21:11:01 +0530564/*array index points to MCS and array value points respective rssi*/
565static int rssiMcsTbl[][10] =
566{
567/*MCS 0 1 2 3 4 5 6 7 8 9*/
568 {-82, -79, -77, -74, -70, -66, -65, -64, -59, -57}, //20
569 {-79, -76, -74, -71, -67, -63, -62, -61, -56, -54}, //40
570 {-76, -73, -71, -68, -64, -60, -59, -58, -53, -51} //80
571};
572
Jeff Johnson295189b2012-06-20 16:38:30 -0700573extern struct net_device_ops net_ops_struct;
Dasari Srinivas7875a302014-09-26 17:50:57 +0530574#ifdef FEATURE_WLAN_SCAN_PNO
575static eHalStatus wlan_hdd_is_pno_allowed(hdd_adapter_t *pAdapter);
576#endif
Jeff Johnson295189b2012-06-20 16:38:30 -0700577
Leo Chang9056f462013-08-01 19:21:11 -0700578#ifdef WLAN_NL80211_TESTMODE
579enum wlan_hdd_tm_attr
580{
581 WLAN_HDD_TM_ATTR_INVALID = 0,
582 WLAN_HDD_TM_ATTR_CMD = 1,
583 WLAN_HDD_TM_ATTR_DATA = 2,
584 WLAN_HDD_TM_ATTR_TYPE = 3,
585 /* keep last */
586 WLAN_HDD_TM_ATTR_AFTER_LAST,
587 WLAN_HDD_TM_ATTR_MAX = WLAN_HDD_TM_ATTR_AFTER_LAST - 1,
588};
589
590enum wlan_hdd_tm_cmd
591{
592 WLAN_HDD_TM_CMD_WLAN_HB = 1,
593};
594
595#define WLAN_HDD_TM_DATA_MAX_LEN 5000
596
597static const struct nla_policy wlan_hdd_tm_policy[WLAN_HDD_TM_ATTR_MAX + 1] =
598{
599 [WLAN_HDD_TM_ATTR_CMD] = { .type = NLA_U32 },
600 [WLAN_HDD_TM_ATTR_DATA] = { .type = NLA_BINARY,
601 .len = WLAN_HDD_TM_DATA_MAX_LEN },
602};
603#endif /* WLAN_NL80211_TESTMODE */
604
Rajesh Chauhan98a31f82014-01-06 20:15:25 -0800605#ifdef FEATURE_WLAN_CH_AVOID
606/*
607 * FUNCTION: wlan_hdd_send_avoid_freq_event
608 * This is called when wlan driver needs to send vendor specific
609 * avoid frequency range event to userspace
610 */
611int wlan_hdd_send_avoid_freq_event(hdd_context_t *pHddCtx,
612 tHddAvoidFreqList *pAvoidFreqList)
613{
614 struct sk_buff *vendor_event;
615
616 ENTER();
617
618 if (!pHddCtx)
619 {
620 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
621 "%s: HDD context is null", __func__);
622 return -1;
623 }
624
625 if (!pAvoidFreqList)
626 {
627 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
628 "%s: pAvoidFreqList is null", __func__);
629 return -1;
630 }
631
632 vendor_event = cfg80211_vendor_event_alloc(pHddCtx->wiphy,
Anand N Sunkad26ca6cc2015-07-29 09:54:52 +0530633#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 18, 0))
634 NULL,
635#endif
Rajesh Chauhan98a31f82014-01-06 20:15:25 -0800636 sizeof(tHddAvoidFreqList),
Sunil Duttc69bccb2014-05-26 21:30:20 +0530637 QCA_NL80211_VENDOR_SUBCMD_AVOID_FREQUENCY_INDEX,
Rajesh Chauhan98a31f82014-01-06 20:15:25 -0800638 GFP_KERNEL);
639 if (!vendor_event)
640 {
641 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
642 "%s: cfg80211_vendor_event_alloc failed", __func__);
643 return -1;
644 }
645
646 memcpy(skb_put(vendor_event, sizeof(tHddAvoidFreqList)),
647 (void *)pAvoidFreqList, sizeof(tHddAvoidFreqList));
648
649 cfg80211_vendor_event(vendor_event, GFP_KERNEL);
650
651 EXIT();
652 return 0;
653}
654#endif /* FEATURE_WLAN_CH_AVOID */
655
Srinivas Dasari030bad32015-02-18 23:23:54 +0530656/*
657 * FUNCTION: __wlan_hdd_cfg80211_nan_request
658 * This is called when wlan driver needs to send vendor specific
659 * nan request event.
660 */
661static int __wlan_hdd_cfg80211_nan_request(struct wiphy *wiphy,
662 struct wireless_dev *wdev,
663 const void *data, int data_len)
664{
665 tNanRequestReq nan_req;
666 VOS_STATUS status;
667 int ret_val = -1;
Srinivas Dasaria3f11c02015-03-20 13:15:20 +0530668 struct net_device *dev = wdev->netdev;
669 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
670 tHalHandle hHal = WLAN_HDD_GET_HAL_CTX(pAdapter);
Srinivas Dasari030bad32015-02-18 23:23:54 +0530671 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
672
673 if (0 == data_len)
674 {
675 hddLog(VOS_TRACE_LEVEL_ERROR,
676 FL("NAN - Invalid Request, length = 0"));
677 return ret_val;
678 }
679
680 if (NULL == data)
681 {
682 hddLog(VOS_TRACE_LEVEL_ERROR,
683 FL("NAN - Invalid Request, data is NULL"));
684 return ret_val;
685 }
686
687 status = wlan_hdd_validate_context(pHddCtx);
688 if (0 != status)
689 {
690 hddLog(VOS_TRACE_LEVEL_ERROR,
691 FL("HDD context is not valid"));
692 return -EINVAL;
693 }
694
695 hddLog(LOG1, FL("Received NAN command"));
696 vos_trace_hex_dump( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
697 (tANI_U8 *)data, data_len);
698
699 /* check the NAN Capability */
700 if (TRUE != sme_IsFeatureSupportedByFW(NAN))
701 {
702 hddLog(VOS_TRACE_LEVEL_ERROR,
703 FL("NAN is not supported by Firmware"));
704 return -EINVAL;
705 }
706
707 nan_req.request_data_len = data_len;
708 nan_req.request_data = data;
709
Srinivas Dasaria3f11c02015-03-20 13:15:20 +0530710 status = sme_NanRequest(hHal, &nan_req, pAdapter->sessionId);
Srinivas Dasari030bad32015-02-18 23:23:54 +0530711 if (VOS_STATUS_SUCCESS == status)
712 {
713 ret_val = 0;
714 }
715 return ret_val;
716}
717
718/*
719 * FUNCTION: wlan_hdd_cfg80211_nan_request
720 * Wrapper to protect the nan vendor command from ssr
721 */
722static int wlan_hdd_cfg80211_nan_request(struct wiphy *wiphy,
723 struct wireless_dev *wdev,
724 const void *data, int data_len)
725{
726 int ret;
727
728 vos_ssr_protect(__func__);
729 ret = __wlan_hdd_cfg80211_nan_request(wiphy, wdev, data, data_len);
730 vos_ssr_unprotect(__func__);
731
732 return ret;
733}
734
735/*
736 * FUNCTION: wlan_hdd_cfg80211_nan_callback
737 * This is a callback function and it gets called
738 * when we need to report nan response event to
739 * upper layers.
740 */
741static void wlan_hdd_cfg80211_nan_callback(void* ctx, tSirNanEvent* msg)
742{
743 hdd_context_t *pHddCtx = (hdd_context_t *)ctx;
744 struct sk_buff *vendor_event;
745 int status;
746 tSirNanEvent *data;
747
748 ENTER();
749 if (NULL == msg)
750 {
751 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
752 FL(" msg received here is null"));
753 return;
754 }
755 data = msg;
756
757 status = wlan_hdd_validate_context(pHddCtx);
758
759 if (0 != status)
760 {
761 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
762 FL("HDD context is not valid"));
763 return;
764 }
765
766 vendor_event = cfg80211_vendor_event_alloc(pHddCtx->wiphy,
Anand N Sunkad26ca6cc2015-07-29 09:54:52 +0530767#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 18, 0))
768 NULL,
769#endif
Srinivas Dasari030bad32015-02-18 23:23:54 +0530770 data->event_data_len +
771 NLMSG_HDRLEN,
772 QCA_NL80211_VENDOR_SUBCMD_NAN_INDEX,
773 GFP_KERNEL);
774
775 if (!vendor_event)
776 {
777 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
778 FL("cfg80211_vendor_event_alloc failed"));
779 return;
780 }
781 if (nla_put(vendor_event, QCA_WLAN_VENDOR_ATTR_NAN,
782 data->event_data_len, data->event_data))
783 {
784 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
785 FL("QCA_WLAN_VENDOR_ATTR_NAN put fail"));
786 kfree_skb(vendor_event);
787 return;
788 }
789 cfg80211_vendor_event(vendor_event, GFP_KERNEL);
790 EXIT();
791}
792
793/*
794 * FUNCTION: wlan_hdd_cfg80211_nan_init
795 * This function is called to register the callback to sme layer
796 */
797inline void wlan_hdd_cfg80211_nan_init(hdd_context_t *pHddCtx)
798{
799 sme_NanRegisterCallback(pHddCtx->hHal, wlan_hdd_cfg80211_nan_callback);
800}
801
802
Sunil Duttc69bccb2014-05-26 21:30:20 +0530803#ifdef WLAN_FEATURE_LINK_LAYER_STATS
804
805static v_BOOL_t put_wifi_rate_stat( tpSirWifiRateStat stats,
806 struct sk_buff *vendor_event)
807{
808 if (nla_put_u8(vendor_event,
809 QCA_WLAN_VENDOR_ATTR_LL_STATS_RATE_PREAMBLE,
810 stats->rate.preamble) ||
811 nla_put_u8(vendor_event,
812 QCA_WLAN_VENDOR_ATTR_LL_STATS_RATE_NSS,
813 stats->rate.nss) ||
814 nla_put_u8(vendor_event,
815 QCA_WLAN_VENDOR_ATTR_LL_STATS_RATE_BW,
816 stats->rate.bw) ||
817 nla_put_u8(vendor_event,
818 QCA_WLAN_VENDOR_ATTR_LL_STATS_RATE_MCS_INDEX,
819 stats->rate.rateMcsIdx) ||
820 nla_put_u32(vendor_event, QCA_WLAN_VENDOR_ATTR_LL_STATS_RATE_BIT_RATE,
821 stats->rate.bitrate ) ||
822 nla_put_u32(vendor_event, QCA_WLAN_VENDOR_ATTR_LL_STATS_RATE_TX_MPDU,
823 stats->txMpdu ) ||
824 nla_put_u32(vendor_event, QCA_WLAN_VENDOR_ATTR_LL_STATS_RATE_RX_MPDU,
825 stats->rxMpdu ) ||
826 nla_put_u32(vendor_event, QCA_WLAN_VENDOR_ATTR_LL_STATS_RATE_MPDU_LOST,
827 stats->mpduLost ) ||
828 nla_put_u32(vendor_event, QCA_WLAN_VENDOR_ATTR_LL_STATS_RATE_RETRIES,
829 stats->retries) ||
830 nla_put_u32(vendor_event,
831 QCA_WLAN_VENDOR_ATTR_LL_STATS_RATE_RETRIES_SHORT,
832 stats->retriesShort ) ||
833 nla_put_u32(vendor_event,
834 QCA_WLAN_VENDOR_ATTR_LL_STATS_RATE_RETRIES_LONG,
835 stats->retriesLong))
836 {
837 hddLog(VOS_TRACE_LEVEL_ERROR,
838 FL("QCA_WLAN_VENDOR_ATTR put fail"));
839 return FALSE;
840 }
841 return TRUE;
842}
843
844static v_BOOL_t put_wifi_peer_info( tpSirWifiPeerInfo stats,
845 struct sk_buff *vendor_event)
846{
847 u32 i = 0;
848 struct nlattr *rateInfo;
849 if (nla_put_u32(vendor_event, QCA_WLAN_VENDOR_ATTR_LL_STATS_PEER_INFO_TYPE,
850 stats->type) ||
851 nla_put(vendor_event,
852 QCA_WLAN_VENDOR_ATTR_LL_STATS_PEER_INFO_MAC_ADDRESS,
853 VOS_MAC_ADDR_SIZE, &stats->peerMacAddress[0]) ||
854 nla_put_u32(vendor_event,
855 QCA_WLAN_VENDOR_ATTR_LL_STATS_PEER_INFO_CAPABILITIES,
856 stats->capabilities) ||
857 nla_put_u32(vendor_event,
858 QCA_WLAN_VENDOR_ATTR_LL_STATS_PEER_INFO_NUM_RATES,
859 stats->numRate))
860 {
861 hddLog(VOS_TRACE_LEVEL_ERROR,
862 FL("QCA_WLAN_VENDOR_ATTR put fail"));
863 goto error;
864 }
865
866 rateInfo = nla_nest_start(vendor_event,
867 QCA_WLAN_VENDOR_ATTR_LL_STATS_PEER_INFO_RATE_INFO);
Sushant Kaushikee1f55e2015-01-22 11:27:01 +0530868 if(!rateInfo)
869 return FALSE;
Sunil Duttc69bccb2014-05-26 21:30:20 +0530870 for (i = 0; i < stats->numRate; i++)
871 {
872 struct nlattr *rates;
873 tpSirWifiRateStat pRateStats = (tpSirWifiRateStat )((uint8 *)
874 stats->rateStats +
875 (i * sizeof(tSirWifiRateStat)));
876 rates = nla_nest_start(vendor_event, i);
Sushant Kaushikee1f55e2015-01-22 11:27:01 +0530877 if(!rates)
878 return FALSE;
Sunil Duttc69bccb2014-05-26 21:30:20 +0530879
880 if (FALSE == put_wifi_rate_stat(pRateStats, vendor_event))
881 {
882 hddLog(VOS_TRACE_LEVEL_ERROR,
883 FL("QCA_WLAN_VENDOR_ATTR put fail"));
884 return FALSE;
885 }
886 nla_nest_end(vendor_event, rates);
887 }
888 nla_nest_end(vendor_event, rateInfo);
889
890 return TRUE;
891error:
892 return FALSE;
893}
894
895static v_BOOL_t put_wifi_wmm_ac_stat( tpSirWifiWmmAcStat stats,
896 struct sk_buff *vendor_event)
897{
898 if (nla_put_u32(vendor_event, QCA_WLAN_VENDOR_ATTR_LL_STATS_WMM_AC_AC,
899 stats->ac ) ||
900 nla_put_u32(vendor_event,
901 QCA_WLAN_VENDOR_ATTR_LL_STATS_WMM_AC_TX_MPDU,
902 stats->txMpdu ) ||
903 nla_put_u32(vendor_event,
904 QCA_WLAN_VENDOR_ATTR_LL_STATS_WMM_AC_RX_MPDU,
905 stats->rxMpdu ) ||
906 nla_put_u32(vendor_event,
907 QCA_WLAN_VENDOR_ATTR_LL_STATS_WMM_AC_TX_MCAST,
908 stats->txMcast ) ||
909 nla_put_u32(vendor_event,
910 QCA_WLAN_VENDOR_ATTR_LL_STATS_WMM_AC_RX_MCAST,
911 stats->rxMcast ) ||
912 nla_put_u32(vendor_event,
913 QCA_WLAN_VENDOR_ATTR_LL_STATS_WMM_AC_RX_AMPDU,
914 stats->rxAmpdu ) ||
915 nla_put_u32(vendor_event,
916 QCA_WLAN_VENDOR_ATTR_LL_STATS_WMM_AC_TX_AMPDU,
917 stats->txAmpdu ) ||
918 nla_put_u32(vendor_event,
919 QCA_WLAN_VENDOR_ATTR_LL_STATS_WMM_AC_MPDU_LOST,
920 stats->mpduLost )||
921 nla_put_u32(vendor_event,
922 QCA_WLAN_VENDOR_ATTR_LL_STATS_WMM_AC_RETRIES,
923 stats->retries ) ||
924 nla_put_u32(vendor_event,
925 QCA_WLAN_VENDOR_ATTR_LL_STATS_WMM_AC_RETRIES_SHORT,
926 stats->retriesShort ) ||
927 nla_put_u32(vendor_event,
928 QCA_WLAN_VENDOR_ATTR_LL_STATS_WMM_AC_RETRIES_LONG,
929 stats->retriesLong ) ||
930 nla_put_u32(vendor_event,
931 QCA_WLAN_VENDOR_ATTR_LL_STATS_WMM_AC_CONTENTION_TIME_MIN,
932 stats->contentionTimeMin ) ||
933 nla_put_u32(vendor_event,
934 QCA_WLAN_VENDOR_ATTR_LL_STATS_WMM_AC_CONTENTION_TIME_MAX,
935 stats->contentionTimeMax ) ||
936 nla_put_u32(vendor_event,
937 QCA_WLAN_VENDOR_ATTR_LL_STATS_WMM_AC_CONTENTION_TIME_AVG,
938 stats->contentionTimeAvg ) ||
939 nla_put_u32(vendor_event,
940 QCA_WLAN_VENDOR_ATTR_LL_STATS_WMM_AC_CONTENTION_NUM_SAMPLES,
941 stats->contentionNumSamples ))
942 {
943 hddLog(VOS_TRACE_LEVEL_ERROR,
944 FL("QCA_WLAN_VENDOR_ATTR put fail") );
945 return FALSE;
946 }
947 return TRUE;
948}
949
950static v_BOOL_t put_wifi_interface_info(tpSirWifiInterfaceInfo stats,
951 struct sk_buff *vendor_event)
952{
Dino Myclec8f3f332014-07-21 16:48:27 +0530953 if (nla_put_s32(vendor_event,
Sunil Duttc69bccb2014-05-26 21:30:20 +0530954 QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_INFO_MODE, stats->mode ) ||
955 nla_put(vendor_event,
956 QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_INFO_MAC_ADDR,
957 VOS_MAC_ADDR_SIZE, stats->macAddr) ||
958 nla_put_u32(vendor_event,
959 QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_INFO_STATE,
960 stats->state ) ||
961 nla_put_u32(vendor_event,
962 QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_INFO_ROAMING,
963 stats->roaming ) ||
964 nla_put_u32(vendor_event,
965 QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_INFO_CAPABILITIES,
966 stats->capabilities ) ||
967 nla_put(vendor_event,
968 QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_INFO_SSID,
969 strlen(stats->ssid), stats->ssid) ||
970 nla_put(vendor_event,
971 QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_INFO_BSSID,
972 WNI_CFG_BSSID_LEN, stats->bssid) ||
973 nla_put(vendor_event,
974 QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_INFO_AP_COUNTRY_STR,
975 WNI_CFG_COUNTRY_CODE_LEN, stats->apCountryStr) ||
976 nla_put(vendor_event,
977 QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_INFO_COUNTRY_STR,
978 WNI_CFG_COUNTRY_CODE_LEN, stats->countryStr)
979 )
980 {
981 hddLog(VOS_TRACE_LEVEL_ERROR,
982 FL("QCA_WLAN_VENDOR_ATTR put fail") );
983 return FALSE;
984 }
985 return TRUE;
986}
987
Dino Mycle3b9536d2014-07-09 22:05:24 +0530988static v_BOOL_t put_wifi_iface_stats(hdd_adapter_t *pAdapter,
989 tpSirWifiIfaceStat pWifiIfaceStat,
Sunil Duttc69bccb2014-05-26 21:30:20 +0530990 struct sk_buff *vendor_event)
991{
992 int i = 0;
993 struct nlattr *wmmInfo;
Dino Mycle3b9536d2014-07-09 22:05:24 +0530994 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
995 WLANTL_InterfaceStatsType *pWifiIfaceStatTL = NULL;
Srinivas Dasaria8a304f2014-11-15 16:13:37 +0530996 tSirWifiWmmAcStat accessclassStats;
Dino Mycle3b9536d2014-07-09 22:05:24 +0530997
Sunil Duttc69bccb2014-05-26 21:30:20 +0530998 if (FALSE == put_wifi_interface_info(
999 &pWifiIfaceStat->info,
1000 vendor_event))
1001 {
1002 hddLog(VOS_TRACE_LEVEL_ERROR,
1003 FL("QCA_WLAN_VENDOR_ATTR put fail") );
1004 return FALSE;
1005
1006 }
Dino Mycle3b9536d2014-07-09 22:05:24 +05301007 pWifiIfaceStatTL = (WLANTL_InterfaceStatsType *)
1008 vos_mem_malloc(sizeof(WLANTL_InterfaceStatsType));
1009 if (NULL == pWifiIfaceStatTL)
1010 {
1011 hddLog(VOS_TRACE_LEVEL_ERROR, FL("vos_mem_malloc failed"));
1012 return FALSE;
1013 }
1014
Srinivas Dasaria8a304f2014-11-15 16:13:37 +05301015 accessclassStats = pWifiIfaceStat->AccessclassStats[WIFI_AC_BK];
1016 pWifiIfaceStat->AccessclassStats[WIFI_AC_BK] =
1017 pWifiIfaceStat->AccessclassStats[WIFI_AC_BE];
1018 pWifiIfaceStat->AccessclassStats[WIFI_AC_BE] = accessclassStats;
1019
1020 accessclassStats.ac = pWifiIfaceStat->AccessclassStats[WIFI_AC_BK].ac;
1021 pWifiIfaceStat->AccessclassStats[WIFI_AC_BK].ac =
1022 pWifiIfaceStat->AccessclassStats[WIFI_AC_BE].ac;
1023 pWifiIfaceStat->AccessclassStats[WIFI_AC_BE].ac = accessclassStats.ac;
Dino Mycle3b9536d2014-07-09 22:05:24 +05301024
1025 if ( pWifiIfaceStat->info.state == WIFI_ASSOCIATED)
1026 {
1027 if (VOS_STATUS_SUCCESS ==
1028 WLANTL_CollectInterfaceStats((WLAN_HDD_GET_CTX(pAdapter))->pvosContext,
1029 pHddStaCtx->conn_info.staId[0], pWifiIfaceStatTL))
1030 {
1031 /* mgmtRx, MgmtActionRx, rxMcast, rxMpdu, rxAmpdu, rssiData are
1032 * obtained from TL structure
1033 */
1034
1035 pWifiIfaceStat->mgmtRx = pWifiIfaceStat->beaconRx +
1036 pWifiIfaceStatTL->mgmtRx;
Dino Mycle3b9536d2014-07-09 22:05:24 +05301037 pWifiIfaceStat->rssiData = pWifiIfaceStatTL->rssiData;
1038
Srinivas Dasari98947432014-11-07 19:41:24 +05301039 pWifiIfaceStat->AccessclassStats[WIFI_AC_VO].rxMcast
1040 = pWifiIfaceStatTL->accessCategoryStats[WLANTL_AC_VO].rxMcast;
1041 pWifiIfaceStat->AccessclassStats[WIFI_AC_VI].rxMcast
1042 = pWifiIfaceStatTL->accessCategoryStats[WLANTL_AC_VI].rxMcast;
1043 pWifiIfaceStat->AccessclassStats[WIFI_AC_BE].rxMcast
1044 = pWifiIfaceStatTL->accessCategoryStats[WLANTL_AC_BE].rxMcast;
1045 pWifiIfaceStat->AccessclassStats[WIFI_AC_BK].rxMcast
1046 = pWifiIfaceStatTL->accessCategoryStats[WLANTL_AC_BK].rxMcast;
Dino Mycle3b9536d2014-07-09 22:05:24 +05301047
Srinivas Dasari98947432014-11-07 19:41:24 +05301048 pWifiIfaceStat->AccessclassStats[WIFI_AC_VO].rxMpdu
1049 = pWifiIfaceStatTL->accessCategoryStats[WLANTL_AC_VO].rxMpdu;
1050 pWifiIfaceStat->AccessclassStats[WIFI_AC_VI].rxMpdu
1051 = pWifiIfaceStatTL->accessCategoryStats[WLANTL_AC_VI].rxMpdu;
1052 pWifiIfaceStat->AccessclassStats[WIFI_AC_BE].rxMpdu
1053 = pWifiIfaceStatTL->accessCategoryStats[WLANTL_AC_BE].rxMpdu;
1054 pWifiIfaceStat->AccessclassStats[WIFI_AC_BK].rxMpdu
1055 = pWifiIfaceStatTL->accessCategoryStats[WLANTL_AC_BK].rxMpdu;
Dino Mycle3b9536d2014-07-09 22:05:24 +05301056
Srinivas Dasari98947432014-11-07 19:41:24 +05301057 pWifiIfaceStat->AccessclassStats[WIFI_AC_VO].rxAmpdu
1058 = pWifiIfaceStatTL->accessCategoryStats[WLANTL_AC_VO].rxAmpdu;
1059 pWifiIfaceStat->AccessclassStats[WIFI_AC_VI].rxAmpdu
1060 = pWifiIfaceStatTL->accessCategoryStats[WLANTL_AC_VI].rxAmpdu;
1061 pWifiIfaceStat->AccessclassStats[WIFI_AC_BE].rxAmpdu
1062 = pWifiIfaceStatTL->accessCategoryStats[WLANTL_AC_BE].rxAmpdu;
1063 pWifiIfaceStat->AccessclassStats[WIFI_AC_BK].rxAmpdu
1064 = pWifiIfaceStatTL->accessCategoryStats[WLANTL_AC_BK].rxAmpdu;
Dino Mycle3b9536d2014-07-09 22:05:24 +05301065 }
1066 else
1067 {
1068 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Error in getting stats from TL"));
1069 }
1070
Dino Mycle3b9536d2014-07-09 22:05:24 +05301071 pWifiIfaceStat->AccessclassStats[WIFI_AC_VO].txMcast =
1072 pAdapter->hdd_stats.hddTxRxStats.txMcast[WLANTL_AC_VO];
1073 pWifiIfaceStat->AccessclassStats[WIFI_AC_VI].txMcast =
1074 pAdapter->hdd_stats.hddTxRxStats.txMcast[WLANTL_AC_VI];
1075 pWifiIfaceStat->AccessclassStats[WIFI_AC_BE].txMcast =
1076 pAdapter->hdd_stats.hddTxRxStats.txMcast[WLANTL_AC_BE];
1077 pWifiIfaceStat->AccessclassStats[WIFI_AC_BK].txMcast =
1078 pAdapter->hdd_stats.hddTxRxStats.txMcast[WLANTL_AC_BK];
1079 }
1080 else
1081 {
1082 hddLog(VOS_TRACE_LEVEL_INFO, FL("Interface not Associated"));
1083 }
1084
1085
Sunil Duttc69bccb2014-05-26 21:30:20 +05301086
1087 if (nla_put_u32(vendor_event,
mukul sharma4bd8d2e2015-08-13 20:33:25 +05301088 QCA_WLAN_VENDOR_ATTR_LL_STATS_TYPE,
1089 QCA_WLAN_VENDOR_ATTR_LL_STATS_TYPE_IFACE) ||
1090 nla_put_u32(vendor_event,
Sunil Duttc69bccb2014-05-26 21:30:20 +05301091 QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_BEACON_RX,
1092 pWifiIfaceStat->beaconRx) ||
1093 nla_put_u32(vendor_event,
1094 QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_MGMT_RX,
1095 pWifiIfaceStat->mgmtRx) ||
1096 nla_put_u32(vendor_event,
1097 QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_MGMT_ACTION_RX,
1098 pWifiIfaceStat->mgmtActionRx) ||
1099 nla_put_u32(vendor_event,
1100 QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_MGMT_ACTION_TX,
1101 pWifiIfaceStat->mgmtActionTx) ||
Dino Mycle3b9536d2014-07-09 22:05:24 +05301102 nla_put_s32(vendor_event,
Sunil Duttc69bccb2014-05-26 21:30:20 +05301103 QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_RSSI_MGMT,
1104 pWifiIfaceStat->rssiMgmt) ||
Dino Mycle3b9536d2014-07-09 22:05:24 +05301105 nla_put_s32(vendor_event,
Sunil Duttc69bccb2014-05-26 21:30:20 +05301106 QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_RSSI_DATA,
1107 pWifiIfaceStat->rssiData) ||
Dino Mycle3b9536d2014-07-09 22:05:24 +05301108 nla_put_s32(vendor_event,
Sunil Duttc69bccb2014-05-26 21:30:20 +05301109 QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_RSSI_ACK,
1110 pWifiIfaceStat->rssiAck))
1111 {
1112 hddLog(VOS_TRACE_LEVEL_ERROR,
Mukul Sharmaf1bd9322015-10-20 16:03:42 +05301113 FL("QCA_WLAN_VENDOR_ATTR put fail"));
1114 vos_mem_free(pWifiIfaceStatTL);
Sunil Duttc69bccb2014-05-26 21:30:20 +05301115 return FALSE;
1116 }
1117
Mukul Sharmaf1bd9322015-10-20 16:03:42 +05301118#ifdef FEATURE_EXT_LL_STAT
1119 /*
1120 * Ensure when EXT_LL_STAT is supported by both host and fwr,
1121 * then host should send Leaky AP stats to upper layer,
1122 * otherwise no need to send these stats.
1123 */
1124 if(sme_IsFeatureSupportedByFW(EXT_LL_STAT) &&
1125 sme_IsFeatureSupportedByDriver(EXT_LL_STAT)
1126 )
1127 {
1128 hddLog(VOS_TRACE_LEVEL_INFO,
1129 FL("EXT_LL_STAT is supported by fwr and host %u %u %u %llu"),
1130 pWifiIfaceStat->leakyApStat.is_leaky_ap,
1131 pWifiIfaceStat->leakyApStat.avg_rx_frms_leaked,
1132 pWifiIfaceStat->leakyApStat.rx_leak_window,
1133 pWifiIfaceStat->leakyApStat.avg_bcn_spread);
1134 if (nla_put_u32(vendor_event,
1135 QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_LEAKY_AP_DETECTED,
1136 pWifiIfaceStat->leakyApStat.is_leaky_ap) ||
1137 nla_put_u32(vendor_event,
1138 QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_LEAKY_AP_AVG_NUM_FRAMES_LEAKED,
1139 pWifiIfaceStat->leakyApStat.avg_rx_frms_leaked) ||
1140 nla_put_u32(vendor_event,
1141 QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_LEAKY_AP_GUARD_TIME,
1142 pWifiIfaceStat->leakyApStat.rx_leak_window) ||
1143 nla_put_u64(vendor_event,
1144 QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_AVERAGE_TSF_OFFSET,
1145 pWifiIfaceStat->leakyApStat.avg_bcn_spread))
1146 {
1147 hddLog(VOS_TRACE_LEVEL_ERROR,
1148 FL("EXT_LL_STAT put fail"));
1149 vos_mem_free(pWifiIfaceStatTL);
1150 return FALSE;
1151 }
1152 }
1153#endif
Sunil Duttc69bccb2014-05-26 21:30:20 +05301154 wmmInfo = nla_nest_start(vendor_event,
1155 QCA_WLAN_VENDOR_ATTR_LL_STATS_WMM_INFO);
Sushant Kaushikee1f55e2015-01-22 11:27:01 +05301156 if(!wmmInfo)
1157 {
1158 vos_mem_free(pWifiIfaceStatTL);
1159 return FALSE;
1160 }
Sunil Duttc69bccb2014-05-26 21:30:20 +05301161 for (i = 0; i < WIFI_AC_MAX; i++)
1162 {
1163 struct nlattr *wmmStats;
1164 wmmStats = nla_nest_start(vendor_event, i);
Sushant Kaushikee1f55e2015-01-22 11:27:01 +05301165 if(!wmmStats)
1166 {
1167 vos_mem_free(pWifiIfaceStatTL);
1168 return FALSE;
1169 }
Sunil Duttc69bccb2014-05-26 21:30:20 +05301170 if (FALSE == put_wifi_wmm_ac_stat(
1171 &pWifiIfaceStat->AccessclassStats[i],
1172 vendor_event))
1173 {
1174 hddLog(VOS_TRACE_LEVEL_ERROR,
1175 FL("QCA_WLAN_VENDOR_ATTR put Fail"));
Dino Mycle3b9536d2014-07-09 22:05:24 +05301176 vos_mem_free(pWifiIfaceStatTL);
Sunil Duttc69bccb2014-05-26 21:30:20 +05301177 return FALSE;
1178 }
1179
1180 nla_nest_end(vendor_event, wmmStats);
1181 }
1182 nla_nest_end(vendor_event, wmmInfo);
Dino Mycle3b9536d2014-07-09 22:05:24 +05301183 vos_mem_free(pWifiIfaceStatTL);
Sunil Duttc69bccb2014-05-26 21:30:20 +05301184 return TRUE;
1185}
1186
1187static tSirWifiInterfaceMode
1188 hdd_map_device_to_ll_iface_mode ( int deviceMode )
1189{
1190 switch (deviceMode)
1191 {
1192 case WLAN_HDD_INFRA_STATION:
1193 return WIFI_INTERFACE_STA;
1194 case WLAN_HDD_SOFTAP:
1195 return WIFI_INTERFACE_SOFTAP;
1196 case WLAN_HDD_P2P_CLIENT:
1197 return WIFI_INTERFACE_P2P_CLIENT;
1198 case WLAN_HDD_P2P_GO:
1199 return WIFI_INTERFACE_P2P_GO;
1200 case WLAN_HDD_IBSS:
1201 return WIFI_INTERFACE_IBSS;
1202 default:
Dino Myclec8f3f332014-07-21 16:48:27 +05301203 return WIFI_INTERFACE_UNKNOWN;
Sunil Duttc69bccb2014-05-26 21:30:20 +05301204 }
1205}
1206
1207static v_BOOL_t hdd_get_interface_info(hdd_adapter_t *pAdapter,
1208 tpSirWifiInterfaceInfo pInfo)
1209{
1210 v_U8_t *staMac = NULL;
1211 hdd_station_ctx_t *pHddStaCtx;
1212 tHalHandle hHal = WLAN_HDD_GET_HAL_CTX(pAdapter);
1213 tpAniSirGlobal pMac = PMAC_STRUCT( hHal );
1214
1215 pInfo->mode = hdd_map_device_to_ll_iface_mode(pAdapter->device_mode);
1216
1217 vos_mem_copy(pInfo->macAddr,
1218 pAdapter->macAddressCurrent.bytes, sizeof(v_MACADDR_t));
1219
1220 if (((WLAN_HDD_INFRA_STATION == pAdapter->device_mode) ||
1221 (WLAN_HDD_P2P_CLIENT == pAdapter->device_mode) ||
1222 (WLAN_HDD_P2P_DEVICE == pAdapter->device_mode)))
1223 {
1224 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
1225 if (eConnectionState_NotConnected == pHddStaCtx->conn_info.connState)
1226 {
1227 pInfo->state = WIFI_DISCONNECTED;
1228 }
1229 if (eConnectionState_Connecting == pHddStaCtx->conn_info.connState)
1230 {
1231 hddLog(VOS_TRACE_LEVEL_ERROR,
1232 "%s: Session ID %d, Connection is in progress", __func__,
1233 pAdapter->sessionId);
1234 pInfo->state = WIFI_ASSOCIATING;
1235 }
1236 if ((eConnectionState_Associated == pHddStaCtx->conn_info.connState) &&
1237 (VOS_FALSE == pHddStaCtx->conn_info.uIsAuthenticated))
1238 {
1239 staMac = (v_U8_t *) &(pAdapter->macAddressCurrent.bytes[0]);
1240 hddLog(VOS_TRACE_LEVEL_ERROR,
1241 "%s: client " MAC_ADDRESS_STR
1242 " is in the middle of WPS/EAPOL exchange.", __func__,
1243 MAC_ADDR_ARRAY(staMac));
1244 pInfo->state = WIFI_AUTHENTICATING;
1245 }
1246 if (eConnectionState_Associated == pHddStaCtx->conn_info.connState)
1247 {
1248 pInfo->state = WIFI_ASSOCIATED;
1249 vos_mem_copy(pInfo->bssid,
1250 &pHddStaCtx->conn_info.bssId, WNI_CFG_BSSID_LEN);
1251 vos_mem_copy(pInfo->ssid,
1252 pHddStaCtx->conn_info.SSID.SSID.ssId,
1253 pHddStaCtx->conn_info.SSID.SSID.length);
1254 //NULL Terminate the string.
1255 pInfo->ssid[pHddStaCtx->conn_info.SSID.SSID.length] = 0;
1256 }
1257 }
1258 vos_mem_copy(pInfo->countryStr,
1259 pMac->scan.countryCodeCurrent, WNI_CFG_COUNTRY_CODE_LEN);
1260
1261 vos_mem_copy(pInfo->apCountryStr,
1262 pMac->scan.countryCodeCurrent, WNI_CFG_COUNTRY_CODE_LEN);
1263
1264 return TRUE;
1265}
1266
1267/*
1268 * hdd_link_layer_process_peer_stats () - This function is called after
1269 * receiving Link Layer Peer statistics from FW.This function converts
1270 * the firmware data to the NL data and sends the same to the kernel/upper
1271 * layers.
1272 */
1273static v_VOID_t hdd_link_layer_process_peer_stats(hdd_adapter_t *pAdapter,
1274 v_VOID_t *pData)
1275{
1276 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Sunil Duttc69bccb2014-05-26 21:30:20 +05301277 tpSirWifiPeerStat pWifiPeerStat;
1278 tpSirWifiPeerInfo pWifiPeerInfo;
1279 struct nlattr *peerInfo;
1280 struct sk_buff *vendor_event;
1281 int status, i;
1282
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05301283 ENTER();
1284
Sunil Duttc69bccb2014-05-26 21:30:20 +05301285 status = wlan_hdd_validate_context(pHddCtx);
1286 if (0 != status)
1287 {
Sunil Duttc69bccb2014-05-26 21:30:20 +05301288 return;
1289 }
1290
1291 pWifiPeerStat = (tpSirWifiPeerStat) pData;
1292
1293 hddLog(VOS_TRACE_LEVEL_INFO,
1294 "LL_STATS_PEER_ALL : numPeers %u",
1295 pWifiPeerStat->numPeers);
Sunil Duttc69bccb2014-05-26 21:30:20 +05301296 /*
1297 * Allocate a size of 4096 for the peer stats comprising
1298 * each of size = sizeof (tSirWifiPeerInfo) + numRate *
1299 * sizeof (tSirWifiRateStat).Each field is put with an
1300 * NL attribute.The size of 4096 is considered assuming
1301 * that number of rates shall not exceed beyond 50 with
1302 * the sizeof (tSirWifiRateStat) being 32.
1303 */
mukul sharma4bd8d2e2015-08-13 20:33:25 +05301304 vendor_event = cfg80211_vendor_cmd_alloc_reply_skb(pHddCtx->wiphy,
1305 LL_STATS_EVENT_BUF_SIZE);
Sunil Duttc69bccb2014-05-26 21:30:20 +05301306 if (!vendor_event)
1307 {
1308 hddLog(VOS_TRACE_LEVEL_ERROR,
mukul sharma4bd8d2e2015-08-13 20:33:25 +05301309 "%s: cfg80211_vendor_cmd_alloc_reply_skb failed",
Sunil Duttc69bccb2014-05-26 21:30:20 +05301310 __func__);
1311 return;
1312 }
1313 if (nla_put_u32(vendor_event,
mukul sharma4bd8d2e2015-08-13 20:33:25 +05301314 QCA_WLAN_VENDOR_ATTR_LL_STATS_TYPE,
1315 QCA_WLAN_VENDOR_ATTR_LL_STATS_TYPE_PEER) ||
1316 nla_put_u32(vendor_event,
Sunil Duttc69bccb2014-05-26 21:30:20 +05301317 QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_NUM_PEERS,
1318 pWifiPeerStat->numPeers))
1319 {
1320 hddLog(VOS_TRACE_LEVEL_ERROR,
1321 "%s: QCA_WLAN_VENDOR_ATTR put fail", __func__);
1322 kfree_skb(vendor_event);
1323 return;
1324 }
1325
1326 peerInfo = nla_nest_start(vendor_event,
1327 QCA_WLAN_VENDOR_ATTR_LL_STATS_PEER_INFO);
Sushant Kaushikee1f55e2015-01-22 11:27:01 +05301328 if(!peerInfo)
1329 {
1330 hddLog(VOS_TRACE_LEVEL_ERROR,
1331 "%s: QCA_WLAN_VENDOR_ATTR_LL_STATS_PEER_INFO put fail",
1332 __func__);
1333 kfree_skb(vendor_event);
1334 return;
1335 }
Sunil Duttc69bccb2014-05-26 21:30:20 +05301336
1337 pWifiPeerInfo = (tpSirWifiPeerInfo) ((uint8 *)
1338 pWifiPeerStat->peerInfo);
1339
1340 for (i = 1; i <= pWifiPeerStat->numPeers; i++)
1341 {
Sunil Duttc69bccb2014-05-26 21:30:20 +05301342 int numRate = pWifiPeerInfo->numRate;
Sushant Kaushikee1f55e2015-01-22 11:27:01 +05301343 struct nlattr *peers = nla_nest_start(vendor_event, i);
Sunil Duttc69bccb2014-05-26 21:30:20 +05301344
Sushant Kaushikee1f55e2015-01-22 11:27:01 +05301345 if(!peers)
1346 {
1347 hddLog(VOS_TRACE_LEVEL_ERROR,
1348 "%s: peer stats put fail",
1349 __func__);
1350 kfree_skb(vendor_event);
1351 return;
1352 }
Sunil Duttc69bccb2014-05-26 21:30:20 +05301353 if (FALSE == put_wifi_peer_info(
1354 pWifiPeerInfo, vendor_event))
1355 {
1356 hddLog(VOS_TRACE_LEVEL_ERROR,
1357 "%s: put_wifi_peer_info put fail", __func__);
1358 kfree_skb(vendor_event);
1359 return;
1360 }
1361
1362 pWifiPeerInfo = (tpSirWifiPeerInfo) ((uint8 *)
1363 pWifiPeerStat->peerInfo +
1364 (i * sizeof(tSirWifiPeerInfo)) +
1365 (numRate * sizeof (tSirWifiRateStat)));
1366 nla_nest_end(vendor_event, peers);
1367 }
1368 nla_nest_end(vendor_event, peerInfo);
mukul sharma4bd8d2e2015-08-13 20:33:25 +05301369 cfg80211_vendor_cmd_reply(vendor_event);
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05301370 EXIT();
Sunil Duttc69bccb2014-05-26 21:30:20 +05301371}
1372
1373/*
1374 * hdd_link_layer_process_iface_stats () - This function is called after
1375 * receiving Link Layer Interface statistics from FW.This function converts
1376 * the firmware data to the NL data and sends the same to the kernel/upper
1377 * layers.
1378 */
1379static v_VOID_t hdd_link_layer_process_iface_stats(hdd_adapter_t *pAdapter,
1380 v_VOID_t *pData)
1381{
1382 tpSirWifiIfaceStat pWifiIfaceStat;
1383 struct sk_buff *vendor_event;
1384 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
1385 int status;
1386
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05301387 ENTER();
1388
Sunil Duttc69bccb2014-05-26 21:30:20 +05301389 status = wlan_hdd_validate_context(pHddCtx);
1390 if (0 != status)
1391 {
Sunil Duttc69bccb2014-05-26 21:30:20 +05301392 return;
1393 }
1394 /*
1395 * Allocate a size of 4096 for the interface stats comprising
1396 * sizeof (tpSirWifiIfaceStat).The size of 4096 is considered
1397 * assuming that all these fit with in the limit.Please take
1398 * a call on the limit based on the data requirements on
1399 * interface statistics.
1400 */
mukul sharma4bd8d2e2015-08-13 20:33:25 +05301401 vendor_event = cfg80211_vendor_cmd_alloc_reply_skb(pHddCtx->wiphy,
1402 LL_STATS_EVENT_BUF_SIZE);
Sunil Duttc69bccb2014-05-26 21:30:20 +05301403 if (!vendor_event)
1404 {
1405 hddLog(VOS_TRACE_LEVEL_ERROR,
mukul sharma4bd8d2e2015-08-13 20:33:25 +05301406 FL("cfg80211_vendor_cmd_alloc_reply_skb failed") );
Sunil Duttc69bccb2014-05-26 21:30:20 +05301407 return;
1408 }
1409
1410 pWifiIfaceStat = (tpSirWifiIfaceStat) pData;
1411
Dino Mycle3b9536d2014-07-09 22:05:24 +05301412
1413 if (FALSE == hdd_get_interface_info( pAdapter,
1414 &pWifiIfaceStat->info))
1415 {
1416 hddLog(VOS_TRACE_LEVEL_ERROR,
1417 FL("hdd_get_interface_info get fail") );
1418 kfree_skb(vendor_event);
1419 return;
1420 }
1421
1422 if (FALSE == put_wifi_iface_stats( pAdapter, pWifiIfaceStat,
1423 vendor_event))
1424 {
1425 hddLog(VOS_TRACE_LEVEL_ERROR,
1426 FL("put_wifi_iface_stats fail") );
1427 kfree_skb(vendor_event);
1428 return;
1429 }
1430
Sunil Duttc69bccb2014-05-26 21:30:20 +05301431 hddLog(VOS_TRACE_LEVEL_INFO,
1432 "WMI_LINK_STATS_IFACE Data");
1433
mukul sharma4bd8d2e2015-08-13 20:33:25 +05301434 cfg80211_vendor_cmd_reply(vendor_event);
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05301435
1436 EXIT();
Sunil Duttc69bccb2014-05-26 21:30:20 +05301437}
1438
1439/*
1440 * hdd_link_layer_process_radio_stats () - This function is called after
1441 * receiving Link Layer Radio statistics from FW.This function converts
1442 * the firmware data to the NL data and sends the same to the kernel/upper
1443 * layers.
1444 */
1445static v_VOID_t hdd_link_layer_process_radio_stats(hdd_adapter_t *pAdapter,
1446 v_VOID_t *pData)
1447{
1448 int status, i;
1449 tpSirWifiRadioStat pWifiRadioStat;
1450 tpSirWifiChannelStats pWifiChannelStats;
1451 struct sk_buff *vendor_event;
1452 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
1453 struct nlattr *chList;
1454
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05301455 ENTER();
1456
Sunil Duttc69bccb2014-05-26 21:30:20 +05301457 status = wlan_hdd_validate_context(pHddCtx);
1458 if (0 != status)
1459 {
Sunil Duttc69bccb2014-05-26 21:30:20 +05301460 return;
1461 }
1462 pWifiRadioStat = (tpSirWifiRadioStat) pData;
1463
1464 hddLog(VOS_TRACE_LEVEL_INFO,
1465 "LL_STATS_RADIO"
1466 " radio is %d onTime is %u "
1467 " txTime is %u rxTime is %u "
1468 " onTimeScan is %u onTimeNbd is %u "
Dino Mycle6fb96c12014-06-10 11:52:40 +05301469 " onTimeEXTScan is %u onTimeRoamScan is %u "
Sunil Duttc69bccb2014-05-26 21:30:20 +05301470 " onTimePnoScan is %u onTimeHs20 is %u "
1471 " numChannels is %u",
1472 pWifiRadioStat->radio, pWifiRadioStat->onTime,
1473 pWifiRadioStat->txTime, pWifiRadioStat->rxTime,
1474 pWifiRadioStat->onTimeScan, pWifiRadioStat->onTimeNbd,
Dino Mycle6fb96c12014-06-10 11:52:40 +05301475 pWifiRadioStat->onTimeEXTScan,
Sunil Duttc69bccb2014-05-26 21:30:20 +05301476 pWifiRadioStat->onTimeRoamScan,
1477 pWifiRadioStat->onTimePnoScan,
1478 pWifiRadioStat->onTimeHs20,
1479 pWifiRadioStat->numChannels);
1480 /*
1481 * Allocate a size of 4096 for the Radio stats comprising
1482 * sizeof (tSirWifiRadioStat) + numChannels * sizeof
1483 * (tSirWifiChannelStats).Each channel data is put with an
1484 * NL attribute.The size of 4096 is considered assuming that
1485 * number of channels shall not exceed beyond 60 with the
1486 * sizeof (tSirWifiChannelStats) being 24 bytes.
1487 */
1488
mukul sharma4bd8d2e2015-08-13 20:33:25 +05301489 vendor_event = cfg80211_vendor_cmd_alloc_reply_skb(pHddCtx->wiphy,
1490 LL_STATS_EVENT_BUF_SIZE);
Sunil Duttc69bccb2014-05-26 21:30:20 +05301491 if (!vendor_event)
1492 {
1493 hddLog(VOS_TRACE_LEVEL_ERROR,
mukul sharma4bd8d2e2015-08-13 20:33:25 +05301494 FL("cfg80211_vendor_cmd_alloc_reply_skb failed") );
Sunil Duttc69bccb2014-05-26 21:30:20 +05301495 return;
1496 }
1497
1498 if (nla_put_u32(vendor_event,
mukul sharma4bd8d2e2015-08-13 20:33:25 +05301499 QCA_WLAN_VENDOR_ATTR_LL_STATS_TYPE,
1500 QCA_WLAN_VENDOR_ATTR_LL_STATS_TYPE_RADIO) ||
1501 nla_put_u32(vendor_event,
Sunil Duttc69bccb2014-05-26 21:30:20 +05301502 QCA_WLAN_VENDOR_ATTR_LL_STATS_RADIO_ID,
1503 pWifiRadioStat->radio) ||
1504 nla_put_u32(vendor_event,
1505 QCA_WLAN_VENDOR_ATTR_LL_STATS_RADIO_ON_TIME,
1506 pWifiRadioStat->onTime) ||
1507 nla_put_u32(vendor_event,
1508 QCA_WLAN_VENDOR_ATTR_LL_STATS_RADIO_TX_TIME,
1509 pWifiRadioStat->txTime) ||
1510 nla_put_u32(vendor_event,
1511 QCA_WLAN_VENDOR_ATTR_LL_STATS_RADIO_RX_TIME,
1512 pWifiRadioStat->rxTime) ||
1513 nla_put_u32(vendor_event,
1514 QCA_WLAN_VENDOR_ATTR_LL_STATS_RADIO_ON_TIME_SCAN,
1515 pWifiRadioStat->onTimeScan) ||
1516 nla_put_u32(vendor_event,
1517 QCA_WLAN_VENDOR_ATTR_LL_STATS_RADIO_ON_TIME_NBD,
1518 pWifiRadioStat->onTimeNbd) ||
1519 nla_put_u32(vendor_event,
Dino Mycle6fb96c12014-06-10 11:52:40 +05301520 QCA_WLAN_VENDOR_ATTR_LL_STATS_RADIO_ON_TIME_EXTSCAN,
1521 pWifiRadioStat->onTimeEXTScan)||
Sunil Duttc69bccb2014-05-26 21:30:20 +05301522 nla_put_u32(vendor_event,
1523 QCA_WLAN_VENDOR_ATTR_LL_STATS_RADIO_ON_TIME_ROAM_SCAN,
1524 pWifiRadioStat->onTimeRoamScan) ||
1525 nla_put_u32(vendor_event,
1526 QCA_WLAN_VENDOR_ATTR_LL_STATS_RADIO_ON_TIME_PNO_SCAN,
1527 pWifiRadioStat->onTimePnoScan) ||
1528 nla_put_u32(vendor_event,
1529 QCA_WLAN_VENDOR_ATTR_LL_STATS_RADIO_ON_TIME_HS20,
1530 pWifiRadioStat->onTimeHs20) ||
1531 nla_put_u32(vendor_event,
1532 QCA_WLAN_VENDOR_ATTR_LL_STATS_RADIO_NUM_CHANNELS,
1533 pWifiRadioStat->numChannels))
1534 {
1535 hddLog(VOS_TRACE_LEVEL_ERROR,
1536 FL("QCA_WLAN_VENDOR_ATTR put fail"));
1537 kfree_skb(vendor_event);
1538 return ;
1539 }
1540
1541 chList = nla_nest_start(vendor_event,
1542 QCA_WLAN_VENDOR_ATTR_LL_STATS_CH_INFO);
Sushant Kaushikee1f55e2015-01-22 11:27:01 +05301543 if(!chList)
1544 {
1545 hddLog(VOS_TRACE_LEVEL_ERROR,
1546 "%s: QCA_WLAN_VENDOR_ATTR_LL_STATS_CH_INFO put fail",
1547 __func__);
1548 kfree_skb(vendor_event);
1549 return;
1550 }
Sunil Duttc69bccb2014-05-26 21:30:20 +05301551 for (i = 0; i < pWifiRadioStat->numChannels; i++)
1552 {
1553 struct nlattr *chInfo;
1554
1555 pWifiChannelStats = (tpSirWifiChannelStats) ((uint8*)
1556 pWifiRadioStat->channels +
1557 (i * sizeof(tSirWifiChannelStats)));
1558
Sunil Duttc69bccb2014-05-26 21:30:20 +05301559 chInfo = nla_nest_start(vendor_event, i);
Sushant Kaushikee1f55e2015-01-22 11:27:01 +05301560 if(!chInfo)
1561 {
1562 hddLog(VOS_TRACE_LEVEL_ERROR,
1563 "%s: failed to put chInfo",
1564 __func__);
1565 kfree_skb(vendor_event);
1566 return;
1567 }
Sunil Duttc69bccb2014-05-26 21:30:20 +05301568
1569 if (nla_put_u32(vendor_event,
1570 QCA_WLAN_VENDOR_ATTR_LL_STATS_CHANNEL_INFO_WIDTH,
1571 pWifiChannelStats->channel.width) ||
1572 nla_put_u32(vendor_event,
1573 QCA_WLAN_VENDOR_ATTR_LL_STATS_CHANNEL_INFO_CENTER_FREQ,
1574 pWifiChannelStats->channel.centerFreq) ||
1575 nla_put_u32(vendor_event,
1576 QCA_WLAN_VENDOR_ATTR_LL_STATS_CHANNEL_INFO_CENTER_FREQ0,
1577 pWifiChannelStats->channel.centerFreq0) ||
1578 nla_put_u32(vendor_event,
1579 QCA_WLAN_VENDOR_ATTR_LL_STATS_CHANNEL_INFO_CENTER_FREQ1,
1580 pWifiChannelStats->channel.centerFreq1) ||
1581 nla_put_u32(vendor_event,
1582 QCA_WLAN_VENDOR_ATTR_LL_STATS_CHANNEL_ON_TIME,
1583 pWifiChannelStats->onTime) ||
1584 nla_put_u32(vendor_event,
1585 QCA_WLAN_VENDOR_ATTR_LL_STATS_CHANNEL_CCA_BUSY_TIME,
1586 pWifiChannelStats->ccaBusyTime))
1587 {
1588 hddLog(VOS_TRACE_LEVEL_ERROR,
1589 FL("cfg80211_vendor_event_alloc failed") );
1590 kfree_skb(vendor_event);
1591 return ;
1592 }
1593 nla_nest_end(vendor_event, chInfo);
1594 }
1595 nla_nest_end(vendor_event, chList);
1596
mukul sharma4bd8d2e2015-08-13 20:33:25 +05301597 cfg80211_vendor_cmd_reply(vendor_event);
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05301598
1599 EXIT();
Sunil Duttc69bccb2014-05-26 21:30:20 +05301600 return;
1601}
1602
1603/*
1604 * hdd_link_layer_stats_ind_callback () - This function is called after
1605 * receiving Link Layer indications from FW.This callback converts the firmware
1606 * data to the NL data and send the same to the kernel/upper layers.
1607 */
1608static void hdd_link_layer_stats_ind_callback ( void *pCtx,
1609 int indType,
Dino Mycled3d50022014-07-07 12:58:25 +05301610 void *pRsp, u8 *macAddr)
Sunil Duttc69bccb2014-05-26 21:30:20 +05301611{
Dino Mycled3d50022014-07-07 12:58:25 +05301612 hdd_context_t *pHddCtx = (hdd_context_t *)pCtx;
1613 hdd_adapter_t *pAdapter = NULL;
mukul sharma4bd8d2e2015-08-13 20:33:25 +05301614 struct hdd_ll_stats_context *context;
Dino Mycled3d50022014-07-07 12:58:25 +05301615 tpSirLLStatsResults linkLayerStatsResults = (tpSirLLStatsResults)pRsp;
Sunil Duttc69bccb2014-05-26 21:30:20 +05301616 int status;
1617
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05301618 ENTER();
Sunil Duttc69bccb2014-05-26 21:30:20 +05301619
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05301620 status = wlan_hdd_validate_context(pHddCtx);
Sunil Duttc69bccb2014-05-26 21:30:20 +05301621 if (0 != status)
1622 {
Sunil Duttc69bccb2014-05-26 21:30:20 +05301623 return;
1624 }
1625
Dino Mycled3d50022014-07-07 12:58:25 +05301626 pAdapter = hdd_get_adapter_by_macaddr(pHddCtx, macAddr);
1627 if (NULL == pAdapter)
1628 {
1629 hddLog(VOS_TRACE_LEVEL_ERROR,
1630 FL(" MAC address %pM does not exist with host"),
1631 macAddr);
1632 return;
1633 }
1634
Sunil Duttc69bccb2014-05-26 21:30:20 +05301635 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Dino Mycled3d50022014-07-07 12:58:25 +05301636 "%s: Interface: %s LLStats indType: %d", __func__,
1637 pAdapter->dev->name, indType);
1638
Sunil Duttc69bccb2014-05-26 21:30:20 +05301639 switch (indType)
1640 {
1641 case SIR_HAL_LL_STATS_RESULTS_RSP:
1642 {
Sunil Duttc69bccb2014-05-26 21:30:20 +05301643 hddLog(VOS_TRACE_LEVEL_INFO,
Sushant Kaushik81a730c2015-09-14 14:49:52 +05301644 "LL_STATS RESP paramID = 0x%x, ifaceId = %u MAC: %pM "
1645 "respId = %u, moreResultToFollow = %u",
1646 linkLayerStatsResults->paramId, linkLayerStatsResults->ifaceId,
1647 macAddr, linkLayerStatsResults->respId,
1648 linkLayerStatsResults->moreResultToFollow);
1649
mukul sharma4bd8d2e2015-08-13 20:33:25 +05301650 spin_lock(&hdd_context_lock);
1651 context = &pHddCtx->ll_stats_context;
1652 /* validate response received from target */
1653 if ((context->request_id != linkLayerStatsResults->respId) ||
1654 !(context->request_bitmap & linkLayerStatsResults->paramId))
1655 {
1656 spin_unlock(&hdd_context_lock);
1657 hddLog(LOGE,
1658 FL("Error : Request id %d response id %d request bitmap 0x%x"
1659 "response bitmap 0x%x"),
1660 context->request_id, linkLayerStatsResults->respId,
1661 context->request_bitmap, linkLayerStatsResults->paramId);
1662 return;
1663 }
1664 spin_unlock(&hdd_context_lock);
1665
Sunil Duttc69bccb2014-05-26 21:30:20 +05301666 if ( linkLayerStatsResults->paramId & WMI_LINK_STATS_RADIO )
1667 {
1668 hdd_link_layer_process_radio_stats(pAdapter,
1669 (v_VOID_t *)linkLayerStatsResults->result);
mukul sharma4bd8d2e2015-08-13 20:33:25 +05301670 spin_lock(&hdd_context_lock);
1671 context->request_bitmap &= ~(WMI_LINK_STATS_RADIO);
1672 spin_unlock(&hdd_context_lock);
Sunil Duttc69bccb2014-05-26 21:30:20 +05301673 }
1674 else if ( linkLayerStatsResults->paramId & WMI_LINK_STATS_IFACE )
1675 {
1676 hdd_link_layer_process_iface_stats(pAdapter,
1677 (v_VOID_t *)linkLayerStatsResults->result);
mukul sharma4bd8d2e2015-08-13 20:33:25 +05301678 spin_lock(&hdd_context_lock);
1679 context->request_bitmap &= ~(WMI_LINK_STATS_IFACE);
1680 spin_unlock(&hdd_context_lock);
Sunil Duttc69bccb2014-05-26 21:30:20 +05301681 }
1682 else if ( linkLayerStatsResults->paramId &
1683 WMI_LINK_STATS_ALL_PEER )
1684 {
1685 hdd_link_layer_process_peer_stats(pAdapter,
1686 (v_VOID_t *)linkLayerStatsResults->result);
mukul sharma4bd8d2e2015-08-13 20:33:25 +05301687 spin_lock(&hdd_context_lock);
1688 context->request_bitmap &= ~(WMI_LINK_STATS_ALL_PEER);
1689 spin_unlock(&hdd_context_lock);
Sunil Duttc69bccb2014-05-26 21:30:20 +05301690 } /* WMI_LINK_STATS_ALL_PEER */
1691 else
1692 {
1693 hddLog(VOS_TRACE_LEVEL_ERROR,
1694 FL("INVALID LL_STATS_NOTIFY RESPONSE ***********"));
1695 }
1696
mukul sharma4bd8d2e2015-08-13 20:33:25 +05301697 spin_lock(&hdd_context_lock);
1698 /* complete response event if all requests are completed */
1699 if (0 == context->request_bitmap)
1700 complete(&context->response_event);
1701 spin_unlock(&hdd_context_lock);
1702
Sunil Duttc69bccb2014-05-26 21:30:20 +05301703 break;
1704 }
1705 default:
1706 hddLog(VOS_TRACE_LEVEL_ERROR, "invalid event type %d", indType);
1707 break;
1708 }
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05301709
1710 EXIT();
Sunil Duttc69bccb2014-05-26 21:30:20 +05301711 return;
1712}
1713
1714const struct
1715nla_policy
1716qca_wlan_vendor_ll_set_policy[QCA_WLAN_VENDOR_ATTR_LL_STATS_SET_MAX +1] =
1717{
1718 [QCA_WLAN_VENDOR_ATTR_LL_STATS_SET_CONFIG_MPDU_SIZE_THRESHOLD] =
1719 { .type = NLA_U32 },
1720 [QCA_WLAN_VENDOR_ATTR_LL_STATS_SET_CONFIG_AGGRESSIVE_STATS_GATHERING] =
1721 { .type = NLA_U32 },
1722};
1723
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05301724static int __wlan_hdd_cfg80211_ll_stats_set(struct wiphy *wiphy,
1725 struct wireless_dev *wdev,
1726 const void *data,
1727 int data_len)
Sunil Duttc69bccb2014-05-26 21:30:20 +05301728{
1729 int status;
1730 struct nlattr *tb_vendor[QCA_WLAN_VENDOR_ATTR_LL_STATS_SET_MAX + 1];
Dino Mycledf0a5d92014-07-04 09:41:55 +05301731 tSirLLStatsSetReq linkLayerStatsSetReq;
Sunil Duttc69bccb2014-05-26 21:30:20 +05301732 struct net_device *dev = wdev->netdev;
1733 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
1734 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
1735
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05301736 ENTER();
1737
Sunil Duttc69bccb2014-05-26 21:30:20 +05301738 status = wlan_hdd_validate_context(pHddCtx);
1739 if (0 != status)
1740 {
Sunil Duttc69bccb2014-05-26 21:30:20 +05301741 return -EINVAL;
1742 }
1743
1744 if (NULL == pAdapter)
1745 {
1746 hddLog(VOS_TRACE_LEVEL_ERROR,
1747 FL("HDD adapter is Null"));
1748 return -ENODEV;
1749 }
Dino Mycledf0a5d92014-07-04 09:41:55 +05301750 /* check the LLStats Capability */
1751 if ( (TRUE != pHddCtx->cfg_ini->fEnableLLStats) ||
1752 (TRUE != sme_IsFeatureSupportedByFW(LINK_LAYER_STATS_MEAS)))
1753 {
1754 hddLog(VOS_TRACE_LEVEL_ERROR,
1755 FL("Link Layer Statistics not supported by Firmware"));
1756 return -EINVAL;
1757 }
Sunil Duttc69bccb2014-05-26 21:30:20 +05301758
1759 if (nla_parse(tb_vendor, QCA_WLAN_VENDOR_ATTR_LL_STATS_SET_MAX,
1760 (struct nlattr *)data,
1761 data_len, qca_wlan_vendor_ll_set_policy))
1762 {
1763 hddLog(VOS_TRACE_LEVEL_ERROR, FL() );
1764 return -EINVAL;
1765 }
1766 if (!tb_vendor
1767 [QCA_WLAN_VENDOR_ATTR_LL_STATS_SET_CONFIG_MPDU_SIZE_THRESHOLD])
1768 {
1769 hddLog(VOS_TRACE_LEVEL_ERROR, FL("MPDU size Not present"));
1770 return -EINVAL;
1771 }
1772 if (!tb_vendor[
1773 QCA_WLAN_VENDOR_ATTR_LL_STATS_SET_CONFIG_AGGRESSIVE_STATS_GATHERING])
1774 {
1775 hddLog(VOS_TRACE_LEVEL_ERROR, FL(" Stats Gathering Not Present"));
1776 return -EINVAL;
1777 }
Sunil Duttc69bccb2014-05-26 21:30:20 +05301778 // Shall take the request Id if the Upper layers pass. 1 For now.
Dino Mycledf0a5d92014-07-04 09:41:55 +05301779 linkLayerStatsSetReq.reqId = 1;
Sunil Duttc69bccb2014-05-26 21:30:20 +05301780
Dino Mycledf0a5d92014-07-04 09:41:55 +05301781 linkLayerStatsSetReq.mpduSizeThreshold =
Sunil Duttc69bccb2014-05-26 21:30:20 +05301782 nla_get_u32(
1783 tb_vendor[QCA_WLAN_VENDOR_ATTR_LL_STATS_SET_CONFIG_MPDU_SIZE_THRESHOLD]);
1784
Dino Mycledf0a5d92014-07-04 09:41:55 +05301785 linkLayerStatsSetReq.aggressiveStatisticsGathering =
Sunil Duttc69bccb2014-05-26 21:30:20 +05301786 nla_get_u32(
1787 tb_vendor[QCA_WLAN_VENDOR_ATTR_LL_STATS_SET_CONFIG_AGGRESSIVE_STATS_GATHERING]);
1788
Dino Mycled3d50022014-07-07 12:58:25 +05301789 vos_mem_copy(linkLayerStatsSetReq.macAddr,
1790 pAdapter->macAddressCurrent.bytes, sizeof(v_MACADDR_t));
Sunil Duttc69bccb2014-05-26 21:30:20 +05301791
1792
1793 hddLog(VOS_TRACE_LEVEL_INFO,
Sushant Kaushik81a730c2015-09-14 14:49:52 +05301794 "LL_STATS_SET reqId = %d, MAC = %pM, mpduSizeThreshold = %d "
1795 "Statistics Gathering = %d ",
1796 linkLayerStatsSetReq.reqId, linkLayerStatsSetReq.macAddr,
1797 linkLayerStatsSetReq.mpduSizeThreshold,
1798 linkLayerStatsSetReq.aggressiveStatisticsGathering);
Sunil Duttc69bccb2014-05-26 21:30:20 +05301799
1800 if (eHAL_STATUS_SUCCESS != sme_SetLinkLayerStatsIndCB(
1801 pHddCtx->hHal,
Dino Mycled3d50022014-07-07 12:58:25 +05301802 hdd_link_layer_stats_ind_callback))
Sunil Duttc69bccb2014-05-26 21:30:20 +05301803 {
1804 hddLog(VOS_TRACE_LEVEL_ERROR, "%s:"
1805 "sme_SetLinkLayerStatsIndCB Failed", __func__);
Sunil Duttc69bccb2014-05-26 21:30:20 +05301806 return -EINVAL;
1807
1808 }
Srinivas Dasari98947432014-11-07 19:41:24 +05301809
Sunil Duttc69bccb2014-05-26 21:30:20 +05301810 if (eHAL_STATUS_SUCCESS != sme_LLStatsSetReq( pHddCtx->hHal,
Dino Mycledf0a5d92014-07-04 09:41:55 +05301811 &linkLayerStatsSetReq))
Sunil Duttc69bccb2014-05-26 21:30:20 +05301812 {
1813 hddLog(VOS_TRACE_LEVEL_ERROR, "%s:"
1814 "sme_LLStatsSetReq Failed", __func__);
Sunil Duttc69bccb2014-05-26 21:30:20 +05301815 return -EINVAL;
1816 }
1817
1818 pAdapter->isLinkLayerStatsSet = 1;
1819
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05301820 EXIT();
Sunil Duttc69bccb2014-05-26 21:30:20 +05301821 return 0;
1822}
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05301823static int wlan_hdd_cfg80211_ll_stats_set(struct wiphy *wiphy,
1824 struct wireless_dev *wdev,
1825 const void *data,
1826 int data_len)
1827{
1828 int ret = 0;
1829
1830 vos_ssr_protect(__func__);
1831 ret = __wlan_hdd_cfg80211_ll_stats_set(wiphy, wdev, data, data_len);
1832 vos_ssr_unprotect(__func__);
1833
1834 return ret;
1835}
Sunil Duttc69bccb2014-05-26 21:30:20 +05301836
1837const struct
1838nla_policy
1839qca_wlan_vendor_ll_get_policy[QCA_WLAN_VENDOR_ATTR_LL_STATS_GET_MAX +1] =
1840{
1841 /* Unsigned 32bit value provided by the caller issuing the GET stats
1842 * command. When reporting
1843 * the stats results, the driver uses the same value to indicate
1844 * which GET request the results
1845 * correspond to.
1846 */
1847 [QCA_WLAN_VENDOR_ATTR_LL_STATS_GET_CONFIG_REQ_ID] = { .type = NLA_U32 },
1848
1849 /* Unsigned 32bit value . bit mask to identify what statistics are
1850 requested for retrieval */
1851 [QCA_WLAN_VENDOR_ATTR_LL_STATS_GET_CONFIG_REQ_MASK] = { .type = NLA_U32 },
1852};
1853
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05301854static int __wlan_hdd_cfg80211_ll_stats_get(struct wiphy *wiphy,
1855 struct wireless_dev *wdev,
1856 const void *data,
1857 int data_len)
Sunil Duttc69bccb2014-05-26 21:30:20 +05301858{
mukul sharma4bd8d2e2015-08-13 20:33:25 +05301859 unsigned long rc;
1860 struct hdd_ll_stats_context *context;
Sunil Duttc69bccb2014-05-26 21:30:20 +05301861 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
1862 struct nlattr *tb_vendor[QCA_WLAN_VENDOR_ATTR_LL_STATS_GET_MAX + 1];
Dino Mycledf0a5d92014-07-04 09:41:55 +05301863 tSirLLStatsGetReq linkLayerStatsGetReq;
Sunil Duttc69bccb2014-05-26 21:30:20 +05301864 struct net_device *dev = wdev->netdev;
1865 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
Mukul Sharma10313ba2015-07-29 19:14:39 +05301866 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
Sunil Duttc69bccb2014-05-26 21:30:20 +05301867 int status;
1868
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05301869 ENTER();
1870
Sunil Duttc69bccb2014-05-26 21:30:20 +05301871 status = wlan_hdd_validate_context(pHddCtx);
1872 if (0 != status)
1873 {
Sunil Duttc69bccb2014-05-26 21:30:20 +05301874 return -EINVAL ;
1875 }
1876
1877 if (NULL == pAdapter)
1878 {
1879 hddLog(VOS_TRACE_LEVEL_FATAL,
1880 "%s: HDD adapter is Null", __func__);
1881 return -ENODEV;
1882 }
Mukul Sharma10313ba2015-07-29 19:14:39 +05301883
1884 if (pHddStaCtx == NULL)
1885 {
1886 hddLog(VOS_TRACE_LEVEL_FATAL,
1887 "%s: HddStaCtx is Null", __func__);
1888 return -ENODEV;
1889 }
1890
Dino Mycledf0a5d92014-07-04 09:41:55 +05301891 /* check the LLStats Capability */
1892 if ( (TRUE != pHddCtx->cfg_ini->fEnableLLStats) ||
1893 (TRUE != sme_IsFeatureSupportedByFW(LINK_LAYER_STATS_MEAS)))
1894 {
1895 hddLog(VOS_TRACE_LEVEL_ERROR,
1896 FL("Link Layer Statistics not supported by Firmware"));
1897 return -EINVAL;
1898 }
1899
Sunil Duttc69bccb2014-05-26 21:30:20 +05301900
1901 if (!pAdapter->isLinkLayerStatsSet)
1902 {
Sushant Kaushikdc3184b2015-10-09 12:00:21 +05301903 hddLog(VOS_TRACE_LEVEL_ERROR,
Sunil Duttc69bccb2014-05-26 21:30:20 +05301904 "%s: isLinkLayerStatsSet : %d",
1905 __func__, pAdapter->isLinkLayerStatsSet);
1906 return -EINVAL;
1907 }
1908
Mukul Sharma10313ba2015-07-29 19:14:39 +05301909 if (VOS_TRUE == pHddStaCtx->hdd_ReassocScenario)
1910 {
1911 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
1912 "%s: Roaming in progress, so unable to proceed this request", __func__);
1913 return -EBUSY;
1914 }
1915
Sunil Duttc69bccb2014-05-26 21:30:20 +05301916 if (nla_parse(tb_vendor, QCA_WLAN_VENDOR_ATTR_LL_STATS_GET_MAX,
1917 (struct nlattr *)data,
1918 data_len, qca_wlan_vendor_ll_get_policy))
1919 {
1920 hddLog(VOS_TRACE_LEVEL_ERROR, FL() );
1921 return -EINVAL;
1922 }
1923
1924 if (!tb_vendor
1925 [QCA_WLAN_VENDOR_ATTR_LL_STATS_GET_CONFIG_REQ_ID])
1926 {
1927 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Request Id Not present"));
1928 return -EINVAL;
1929 }
1930
1931 if (!tb_vendor
1932 [QCA_WLAN_VENDOR_ATTR_LL_STATS_GET_CONFIG_REQ_MASK])
1933 {
1934 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Req Mask Not present"));
1935 return -EINVAL;
1936 }
1937
Sunil Duttc69bccb2014-05-26 21:30:20 +05301938
Dino Mycledf0a5d92014-07-04 09:41:55 +05301939 linkLayerStatsGetReq.reqId =
Sunil Duttc69bccb2014-05-26 21:30:20 +05301940 nla_get_u32( tb_vendor[
1941 QCA_WLAN_VENDOR_ATTR_LL_STATS_GET_CONFIG_REQ_ID]);
Dino Mycledf0a5d92014-07-04 09:41:55 +05301942 linkLayerStatsGetReq.paramIdMask =
Sunil Duttc69bccb2014-05-26 21:30:20 +05301943 nla_get_u32( tb_vendor[
1944 QCA_WLAN_VENDOR_ATTR_LL_STATS_GET_CONFIG_REQ_MASK]);
1945
Dino Mycled3d50022014-07-07 12:58:25 +05301946 vos_mem_copy(linkLayerStatsGetReq.macAddr,
1947 pAdapter->macAddressCurrent.bytes, sizeof(v_MACADDR_t));
Sunil Duttc69bccb2014-05-26 21:30:20 +05301948
1949 hddLog(VOS_TRACE_LEVEL_INFO,
Sushant Kaushik81a730c2015-09-14 14:49:52 +05301950 "LL_STATS_GET reqId = %d, MAC = %pM, paramIdMask = %d",
1951 linkLayerStatsGetReq.reqId, linkLayerStatsGetReq.macAddr,
Dino Mycledf0a5d92014-07-04 09:41:55 +05301952 linkLayerStatsGetReq.paramIdMask);
Sunil Duttc69bccb2014-05-26 21:30:20 +05301953
mukul sharma4bd8d2e2015-08-13 20:33:25 +05301954 spin_lock(&hdd_context_lock);
1955 context = &pHddCtx->ll_stats_context;
1956 context->request_id = linkLayerStatsGetReq.reqId;
1957 context->request_bitmap = linkLayerStatsGetReq.paramIdMask;
1958 INIT_COMPLETION(context->response_event);
1959 spin_unlock(&hdd_context_lock);
1960
Sunil Duttc69bccb2014-05-26 21:30:20 +05301961 if (eHAL_STATUS_SUCCESS != sme_LLStatsGetReq( pHddCtx->hHal,
Dino Mycledf0a5d92014-07-04 09:41:55 +05301962 &linkLayerStatsGetReq))
Sunil Duttc69bccb2014-05-26 21:30:20 +05301963 {
1964 hddLog(VOS_TRACE_LEVEL_ERROR, "%s:"
1965 "sme_LLStatsGetReq Failed", __func__);
Sunil Duttc69bccb2014-05-26 21:30:20 +05301966 return -EINVAL;
1967 }
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05301968
mukul sharma4bd8d2e2015-08-13 20:33:25 +05301969 rc = wait_for_completion_timeout(&context->response_event,
1970 msecs_to_jiffies(WLAN_WAIT_TIME_LL_STATS));
1971 if (!rc)
1972 {
1973 hddLog(LOGE,
1974 FL("Target response timed out request id %d request bitmap 0x%x"),
1975 context->request_id, context->request_bitmap);
1976 return -ETIMEDOUT;
1977 }
1978
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05301979 EXIT();
Sunil Duttc69bccb2014-05-26 21:30:20 +05301980 return 0;
1981}
1982
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05301983static int wlan_hdd_cfg80211_ll_stats_get(struct wiphy *wiphy,
1984 struct wireless_dev *wdev,
1985 const void *data,
1986 int data_len)
1987{
1988 int ret = 0;
1989
1990 vos_ssr_protect(__func__);
1991 ret = __wlan_hdd_cfg80211_ll_stats_get(wiphy, wdev, data, data_len);
1992 vos_ssr_unprotect(__func__);
1993
1994 return ret;
1995}
1996
Sunil Duttc69bccb2014-05-26 21:30:20 +05301997const struct
1998nla_policy
1999qca_wlan_vendor_ll_clr_policy[QCA_WLAN_VENDOR_ATTR_LL_STATS_CLR_MAX +1] =
2000{
2001 [QCA_WLAN_VENDOR_ATTR_LL_STATS_CLR_CONFIG_REQ_MASK] = {.type = NLA_U32 },
2002 [QCA_WLAN_VENDOR_ATTR_LL_STATS_CLR_CONFIG_STOP_REQ] = {.type = NLA_U8 },
2003 [QCA_WLAN_VENDOR_ATTR_LL_STATS_CLR_CONFIG_RSP_MASK] = {.type = NLA_U32 },
2004 [QCA_WLAN_VENDOR_ATTR_LL_STATS_CLR_CONFIG_STOP_RSP] = {.type = NLA_U8 },
2005};
2006
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05302007static int __wlan_hdd_cfg80211_ll_stats_clear(struct wiphy *wiphy,
2008 struct wireless_dev *wdev,
2009 const void *data,
2010 int data_len)
Sunil Duttc69bccb2014-05-26 21:30:20 +05302011{
2012 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
2013 struct nlattr *tb_vendor[QCA_WLAN_VENDOR_ATTR_LL_STATS_CLR_MAX + 1];
Dino Mycledf0a5d92014-07-04 09:41:55 +05302014 tSirLLStatsClearReq linkLayerStatsClearReq;
Sunil Duttc69bccb2014-05-26 21:30:20 +05302015 struct net_device *dev = wdev->netdev;
2016 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
2017 u32 statsClearReqMask;
2018 u8 stopReq;
2019 int status;
2020
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05302021 ENTER();
2022
Sunil Duttc69bccb2014-05-26 21:30:20 +05302023 status = wlan_hdd_validate_context(pHddCtx);
2024 if (0 != status)
2025 {
Sunil Duttc69bccb2014-05-26 21:30:20 +05302026 return -EINVAL;
2027 }
2028
2029 if (NULL == pAdapter)
2030 {
2031 hddLog(VOS_TRACE_LEVEL_FATAL,
2032 "%s: HDD adapter is Null", __func__);
2033 return -ENODEV;
2034 }
Dino Mycledf0a5d92014-07-04 09:41:55 +05302035 /* check the LLStats Capability */
2036 if ( (TRUE != pHddCtx->cfg_ini->fEnableLLStats) ||
2037 (TRUE != sme_IsFeatureSupportedByFW(LINK_LAYER_STATS_MEAS)))
2038 {
2039 hddLog(VOS_TRACE_LEVEL_ERROR,
2040 FL("Enable LLStats Capability"));
2041 return -EINVAL;
2042 }
Sunil Duttc69bccb2014-05-26 21:30:20 +05302043
2044 if (!pAdapter->isLinkLayerStatsSet)
2045 {
2046 hddLog(VOS_TRACE_LEVEL_FATAL,
2047 "%s: isLinkLayerStatsSet : %d",
2048 __func__, pAdapter->isLinkLayerStatsSet);
2049 return -EINVAL;
2050 }
2051
2052 if (nla_parse(tb_vendor, QCA_WLAN_VENDOR_ATTR_LL_STATS_CLR_MAX,
2053 (struct nlattr *)data,
2054 data_len, qca_wlan_vendor_ll_clr_policy))
2055 {
2056 hddLog(VOS_TRACE_LEVEL_ERROR, FL() );
2057 return -EINVAL;
2058 }
2059
2060 if (!tb_vendor[QCA_WLAN_VENDOR_ATTR_LL_STATS_CLR_CONFIG_REQ_MASK] ||
2061
2062 !tb_vendor[QCA_WLAN_VENDOR_ATTR_LL_STATS_CLR_CONFIG_STOP_REQ])
2063 {
2064 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Error in LL_STATS CLR CONFIG PARA") );
2065 return -EINVAL;
2066
2067 }
2068
Sunil Duttc69bccb2014-05-26 21:30:20 +05302069
Dino Mycledf0a5d92014-07-04 09:41:55 +05302070 statsClearReqMask = linkLayerStatsClearReq.statsClearReqMask =
Sunil Duttc69bccb2014-05-26 21:30:20 +05302071 nla_get_u32(
2072 tb_vendor[QCA_WLAN_VENDOR_ATTR_LL_STATS_CLR_CONFIG_REQ_MASK]);
2073
Dino Mycledf0a5d92014-07-04 09:41:55 +05302074 stopReq = linkLayerStatsClearReq.stopReq =
Sunil Duttc69bccb2014-05-26 21:30:20 +05302075 nla_get_u8(
2076 tb_vendor[QCA_WLAN_VENDOR_ATTR_LL_STATS_CLR_CONFIG_STOP_REQ]);
2077
2078 // Shall take the request Id if the Upper layers pass. 1 For now.
Dino Mycledf0a5d92014-07-04 09:41:55 +05302079 linkLayerStatsClearReq.reqId = 1;
Sunil Duttc69bccb2014-05-26 21:30:20 +05302080
Dino Mycled3d50022014-07-07 12:58:25 +05302081 vos_mem_copy(linkLayerStatsClearReq.macAddr,
2082 pAdapter->macAddressCurrent.bytes, sizeof(v_MACADDR_t));
Sunil Duttc69bccb2014-05-26 21:30:20 +05302083
2084 hddLog(VOS_TRACE_LEVEL_INFO,
Sushant Kaushik81a730c2015-09-14 14:49:52 +05302085 "LL_STATS_CLEAR reqId = %d, MAC = %pM,"
2086 "statsClearReqMask = 0x%X, stopReq = %d",
2087 linkLayerStatsClearReq.reqId,
2088 linkLayerStatsClearReq.macAddr,
2089 linkLayerStatsClearReq.statsClearReqMask,
Dino Mycledf0a5d92014-07-04 09:41:55 +05302090 linkLayerStatsClearReq.stopReq);
Sunil Duttc69bccb2014-05-26 21:30:20 +05302091
2092 if (eHAL_STATUS_SUCCESS == sme_LLStatsClearReq(pHddCtx->hHal,
Dino Mycledf0a5d92014-07-04 09:41:55 +05302093 &linkLayerStatsClearReq))
Sunil Duttc69bccb2014-05-26 21:30:20 +05302094 {
2095 struct sk_buff *temp_skbuff;
Srinivas Dasari98947432014-11-07 19:41:24 +05302096 hdd_station_ctx_t *pHddStaCtx;
2097
2098 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
2099 if (VOS_STATUS_SUCCESS !=
2100 WLANTL_ClearInterfaceStats((WLAN_HDD_GET_CTX(pAdapter))->pvosContext,
2101 pHddStaCtx->conn_info.staId[0], statsClearReqMask))
2102 {
2103 hddLog(VOS_TRACE_LEVEL_ERROR, "%s:"
2104 "WLANTL_ClearInterfaceStats Failed", __func__);
2105 return -EINVAL;
2106 }
2107 if ((statsClearReqMask & WIFI_STATS_IFACE_AC) ||
2108 (statsClearReqMask & WIFI_STATS_IFACE)) {
2109 pAdapter->hdd_stats.hddTxRxStats.txMcast[WLANTL_AC_VO] = 0;
2110 pAdapter->hdd_stats.hddTxRxStats.txMcast[WLANTL_AC_VI] = 0;
2111 pAdapter->hdd_stats.hddTxRxStats.txMcast[WLANTL_AC_BE] = 0;
2112 pAdapter->hdd_stats.hddTxRxStats.txMcast[WLANTL_AC_BK] = 0;
2113 }
2114
Sunil Duttc69bccb2014-05-26 21:30:20 +05302115 temp_skbuff = cfg80211_vendor_cmd_alloc_reply_skb(wiphy,
2116 2 * sizeof(u32) +
2117 NLMSG_HDRLEN);
2118
2119 if (temp_skbuff != NULL)
2120 {
2121
2122 if (nla_put_u32(temp_skbuff,
2123 QCA_WLAN_VENDOR_ATTR_LL_STATS_CLR_CONFIG_RSP_MASK,
2124 statsClearReqMask) ||
2125 nla_put_u32(temp_skbuff,
2126 QCA_WLAN_VENDOR_ATTR_LL_STATS_CLR_CONFIG_STOP_RSP,
2127 stopReq))
2128 {
2129 hddLog(VOS_TRACE_LEVEL_ERROR, FL("LL_STATS_CLR put fail"));
2130 kfree_skb(temp_skbuff);
2131 return -EINVAL;
2132 }
2133 /* If the ask is to stop the stats collection as part of clear
2134 * (stopReq = 1) , ensure that no further requests of get
2135 * go to the firmware by having isLinkLayerStatsSet set to 0.
2136 * However it the stopReq as part of the clear request is 0 ,
Dino Mycledf0a5d92014-07-04 09:41:55 +05302137 * the request to get the statistics are honoured as in this
Sunil Duttc69bccb2014-05-26 21:30:20 +05302138 * case the firmware is just asked to clear the statistics.
2139 */
Dino Mycledf0a5d92014-07-04 09:41:55 +05302140 if (linkLayerStatsClearReq.stopReq == 1)
Sunil Duttc69bccb2014-05-26 21:30:20 +05302141 pAdapter->isLinkLayerStatsSet = 0;
2142 return cfg80211_vendor_cmd_reply(temp_skbuff);
2143 }
2144 return -ENOMEM;
2145 }
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05302146
2147 EXIT();
Sunil Duttc69bccb2014-05-26 21:30:20 +05302148 return -EINVAL;
2149}
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05302150static int wlan_hdd_cfg80211_ll_stats_clear(struct wiphy *wiphy,
2151 struct wireless_dev *wdev,
2152 const void *data,
2153 int data_len)
2154{
2155 int ret = 0;
2156
2157 vos_ssr_protect(__func__);
2158 ret = __wlan_hdd_cfg80211_ll_stats_clear(wiphy, wdev, data, data_len);
2159 vos_ssr_unprotect(__func__);
2160
2161 return ret;
2162
2163
2164}
Sunil Duttc69bccb2014-05-26 21:30:20 +05302165#endif /* WLAN_FEATURE_LINK_LAYER_STATS */
2166
Dino Mycle6fb96c12014-06-10 11:52:40 +05302167#ifdef WLAN_FEATURE_EXTSCAN
2168static const struct nla_policy
2169wlan_hdd_extscan_config_policy
2170 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX + 1] =
2171{
2172 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_REQUEST_ID] =
2173 { .type = NLA_U32 },
2174 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_GET_VALID_CHANNELS_CONFIG_PARAM_WIFI_BAND] =
2175 { .type = NLA_U32 },
2176 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_CHANNEL_SPEC_CHANNEL] = { .type = NLA_U32 },
2177 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_CHANNEL_SPEC_DWELL_TIME] =
2178 { .type = NLA_U32 },
2179 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_CHANNEL_SPEC_PASSIVE] = { .type = NLA_U8 },
2180 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_CHANNEL_SPEC_CLASS] = { .type = NLA_U8 },
2181
2182 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_INDEX] = { .type = NLA_U8 },
2183 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_BAND] = { .type = NLA_U8 },
2184 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_PERIOD] = { .type = NLA_U32 },
2185 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_REPORT_EVENTS] =
2186 { .type = NLA_U8 },
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05302187 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_MAX_PERIOD] =
2188 { .type = NLA_U32 },
2189 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_EXPONENT] =
2190 { .type = NLA_U32 },
2191 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_STEP_COUNT] =
2192 { .type = NLA_U32 },
Dino Mycle6fb96c12014-06-10 11:52:40 +05302193 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_NUM_CHANNEL_SPECS] =
2194 { .type = NLA_U32 },
2195 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_SCAN_CMD_PARAMS_BASE_PERIOD] =
2196 { .type = NLA_U32 },
2197 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_SCAN_CMD_PARAMS_MAX_AP_PER_SCAN] =
2198 { .type = NLA_U32 },
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05302199 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_SCAN_CMD_PARAMS_REPORT_THRESHOLD_PERCENT] =
2200 { .type = NLA_U8 },
2201 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_SCAN_CMD_PARAMS_REPORT_THRESHOLD_NUM_SCANS] =
Dino Mycle6fb96c12014-06-10 11:52:40 +05302202 { .type = NLA_U8 },
2203 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_SCAN_CMD_PARAMS_NUM_BUCKETS] =
2204 { .type = NLA_U8 },
2205 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_GET_CACHED_SCAN_RESULTS_CONFIG_PARAM_FLUSH] =
2206 { .type = NLA_U8 },
2207
2208 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_GET_CACHED_SCAN_RESULTS_CONFIG_PARAM_MAX] =
2209 { .type = NLA_U32 },
2210 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_AP_THRESHOLD_PARAM_BSSID] =
2211 { .type = NLA_UNSPEC },
2212 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_AP_THRESHOLD_PARAM_RSSI_LOW] =
2213 { .type = NLA_S32 },
2214 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_AP_THRESHOLD_PARAM_RSSI_HIGH] =
2215 { .type = NLA_S32 },
2216 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_AP_THRESHOLD_PARAM_CHANNEL] =
2217 { .type = NLA_U32 },
2218 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_BSSID_HOTLIST_PARAMS_NUM_AP] =
2219 { .type = NLA_U32 },
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05302220 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_BSSID_HOTLIST_PARAMS_LOST_AP_SAMPLE_SIZE] =
2221 { .type = NLA_U32 },
2222 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_SSID_THRESHOLD_PARAM_SSID] =
2223 { .type = NLA_BINARY,
2224 .len = IEEE80211_MAX_SSID_LEN + 1 },
2225 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_SSID_HOTLIST_PARAMS_LOST_SSID_SAMPLE_SIZE] =
Dino Mycle6fb96c12014-06-10 11:52:40 +05302226 { .type = NLA_U32 },
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05302227 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_SSID_HOTLIST_PARAMS_NUM_SSID] =
2228 { .type = NLA_U32 },
2229 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_SSID_THRESHOLD_PARAM_BAND] =
2230 { .type = NLA_U8 },
2231 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_SSID_THRESHOLD_PARAM_RSSI_LOW] =
2232 { .type = NLA_S32 },
2233 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_SSID_THRESHOLD_PARAM_RSSI_HIGH] =
2234 { .type = NLA_S32 },
2235 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_CONFIGURATION_FLAGS] =
2236 { .type = NLA_U32 },
Dino Mycle6fb96c12014-06-10 11:52:40 +05302237};
2238
Padma, Santhosh Kumara1aa4a32015-06-19 19:00:46 +05302239/**
2240 * wlan_hdd_cfg80211_extscan_get_capabilities_rsp() - response from target
2241 * @ctx: hdd global context
2242 * @data: capabilities data
2243 *
2244 * Return: none
2245 */
2246static void
2247wlan_hdd_cfg80211_extscan_get_capabilities_rsp(void *ctx, void *pMsg)
Dino Mycle6fb96c12014-06-10 11:52:40 +05302248{
Padma, Santhosh Kumara1aa4a32015-06-19 19:00:46 +05302249 struct hdd_ext_scan_context *context;
Dino Mycle6fb96c12014-06-10 11:52:40 +05302250 hdd_context_t *pHddCtx = (hdd_context_t *)ctx;
Padma, Santhosh Kumara1aa4a32015-06-19 19:00:46 +05302251 tSirEXTScanCapabilitiesEvent *data =
2252 (tSirEXTScanCapabilitiesEvent *) pMsg;
Dino Mycle6fb96c12014-06-10 11:52:40 +05302253
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05302254 ENTER();
2255
2256 if (wlan_hdd_validate_context(pHddCtx))
2257 {
Dino Mycle6fb96c12014-06-10 11:52:40 +05302258 return;
2259 }
2260
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05302261 if (!pMsg)
2262 {
2263 hddLog(VOS_TRACE_LEVEL_ERROR, FL("pMsg is null"));
2264 return;
2265 }
Dino Mycle6fb96c12014-06-10 11:52:40 +05302266
Padma, Santhosh Kumara1aa4a32015-06-19 19:00:46 +05302267 vos_spin_lock_acquire(&hdd_context_lock);
2268
2269 context = &pHddCtx->ext_scan_context;
2270 /* validate response received from target*/
2271 if (context->request_id != data->requestId)
2272 {
2273 vos_spin_lock_release(&hdd_context_lock);
2274 hddLog(LOGE,
2275 FL("Target response id did not match: request_id %d resposne_id %d"),
2276 context->request_id, data->requestId);
Dino Mycle6fb96c12014-06-10 11:52:40 +05302277 return;
2278 }
Padma, Santhosh Kumara1aa4a32015-06-19 19:00:46 +05302279 else
2280 {
2281 context->capability_response = *data;
2282 complete(&context->response_event);
Dino Mycle6fb96c12014-06-10 11:52:40 +05302283 }
2284
Padma, Santhosh Kumara1aa4a32015-06-19 19:00:46 +05302285 vos_spin_lock_release(&hdd_context_lock);
Dino Mycle6fb96c12014-06-10 11:52:40 +05302286
Dino Mycle6fb96c12014-06-10 11:52:40 +05302287 return;
2288}
2289
Padma, Santhosh Kumara1aa4a32015-06-19 19:00:46 +05302290/*
2291 * define short names for the global vendor params
2292 * used by wlan_hdd_send_ext_scan_capability()
2293 */
2294#define PARAM_REQUEST_ID \
2295 QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_REQUEST_ID
2296#define PARAM_STATUS \
2297 QCA_WLAN_VENDOR_ATTR_EXTSCAN_STATUS
2298#define MAX_SCAN_CACHE_SIZE \
2299 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_CAPABILITIES_MAX_SCAN_CACHE_SIZE
2300#define MAX_SCAN_BUCKETS \
2301 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_CAPABILITIES_MAX_SCAN_BUCKETS
2302#define MAX_AP_CACHE_PER_SCAN \
2303 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_CAPABILITIES_MAX_AP_CACHE_PER_SCAN
2304#define MAX_RSSI_SAMPLE_SIZE \
2305 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_CAPABILITIES_MAX_RSSI_SAMPLE_SIZE
2306#define MAX_SCAN_RPT_THRHOLD \
2307 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_CAPABILITIES_MAX_SCAN_REPORTING_THRESHOLD
2308#define MAX_HOTLIST_BSSIDS \
2309 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_CAPABILITIES_MAX_HOTLIST_BSSIDS
2310#define MAX_BSSID_HISTORY_ENTRIES \
2311 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_CAPABILITIES_MAX_BSSID_HISTORY_ENTRIES
2312#define MAX_HOTLIST_SSIDS \
2313 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_CAPABILITIES_MAX_HOTLIST_SSIDS
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05302314#define MAX_SIGNIFICANT_WIFI_CHANGE_APS \
2315 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_CAPABILITIES_MAX_SIGNIFICANT_WIFI_CHANGE_APS
Padma, Santhosh Kumara1aa4a32015-06-19 19:00:46 +05302316
2317static int wlan_hdd_send_ext_scan_capability(void *ctx)
2318{
2319 hdd_context_t *pHddCtx = (hdd_context_t *)ctx;
2320 struct sk_buff *skb = NULL;
2321 int ret;
2322 tSirEXTScanCapabilitiesEvent *data;
2323 tANI_U32 nl_buf_len;
2324
2325 ret = wlan_hdd_validate_context(pHddCtx);
2326 if (0 != ret)
2327 {
2328 return ret;
2329 }
2330
2331 data = &(pHddCtx->ext_scan_context.capability_response);
2332
2333 nl_buf_len = NLMSG_HDRLEN;
2334 nl_buf_len += (sizeof(data->requestId) + NLA_HDRLEN) +
2335 (sizeof(data->status) + NLA_HDRLEN) +
2336 (sizeof(data->scanCacheSize) + NLA_HDRLEN) +
2337 (sizeof(data->scanBuckets) + NLA_HDRLEN) +
2338 (sizeof(data->maxApPerScan) + NLA_HDRLEN) +
2339 (sizeof(data->maxRssiSampleSize) + NLA_HDRLEN) +
2340 (sizeof(data->maxScanReportingThreshold) + NLA_HDRLEN) +
2341 (sizeof(data->maxHotlistAPs) + NLA_HDRLEN) +
2342 (sizeof(data->maxBsidHistoryEntries) + NLA_HDRLEN) +
2343 (sizeof(data->maxHotlistSSIDs) + NLA_HDRLEN);
2344
2345 skb = cfg80211_vendor_cmd_alloc_reply_skb(pHddCtx->wiphy, nl_buf_len);
2346
2347 if (!skb)
2348 {
2349 hddLog(LOGE, FL("cfg80211_vendor_cmd_alloc_reply_skb failed"));
2350 return -ENOMEM;
2351 }
2352
2353 hddLog(LOG1, "Req Id (%u) Status (%u)", data->requestId, data->status);
2354 hddLog(LOG1, "Scan cache size (%u) Scan buckets (%u) Max AP per scan (%u)",
2355 data->scanCacheSize, data->scanBuckets, data->maxApPerScan);
2356 hddLog(LOG1, "max_rssi_sample_size (%u) max_scan_reporting_threshold (%u)",
2357 data->maxRssiSampleSize, data->maxScanReportingThreshold);
2358 hddLog(LOG1, "max_hotlist_bssids (%u) max_bssid_history_entries (%u)"
2359 "max_hotlist_ssids (%u)", data->maxHotlistAPs,
2360 data->maxBsidHistoryEntries, data->maxHotlistSSIDs);
2361
2362 if (nla_put_u32(skb, PARAM_REQUEST_ID, data->requestId) ||
2363 nla_put_u32(skb, PARAM_STATUS, data->status) ||
2364 nla_put_u32(skb, MAX_SCAN_CACHE_SIZE, data->scanCacheSize) ||
2365 nla_put_u32(skb, MAX_SCAN_BUCKETS, data->scanBuckets) ||
2366 nla_put_u32(skb, MAX_AP_CACHE_PER_SCAN,
2367 data->maxApPerScan) ||
2368 nla_put_u32(skb, MAX_RSSI_SAMPLE_SIZE,
2369 data->maxRssiSampleSize) ||
2370 nla_put_u32(skb, MAX_SCAN_RPT_THRHOLD,
2371 data->maxScanReportingThreshold) ||
2372 nla_put_u32(skb, MAX_HOTLIST_BSSIDS, data->maxHotlistAPs) ||
2373 nla_put_u32(skb, MAX_BSSID_HISTORY_ENTRIES,
2374 data->maxBsidHistoryEntries) ||
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05302375 nla_put_u32(skb, MAX_HOTLIST_SSIDS, data->maxHotlistSSIDs) ||
2376 nla_put_u32(skb, MAX_SIGNIFICANT_WIFI_CHANGE_APS, 0))
Padma, Santhosh Kumara1aa4a32015-06-19 19:00:46 +05302377 {
2378 hddLog(LOGE, FL("nla put fail"));
2379 goto nla_put_failure;
2380 }
2381
2382 cfg80211_vendor_cmd_reply(skb);
2383 return 0;
2384
2385nla_put_failure:
2386 kfree_skb(skb);
2387 return -EINVAL;;
2388}
2389
2390/*
2391 * done with short names for the global vendor params
2392 * used by wlan_hdd_send_ext_scan_capability()
2393 */
2394#undef PARAM_REQUEST_ID
2395#undef PARAM_STATUS
2396#undef MAX_SCAN_CACHE_SIZE
2397#undef MAX_SCAN_BUCKETS
2398#undef MAX_AP_CACHE_PER_SCAN
2399#undef MAX_RSSI_SAMPLE_SIZE
2400#undef MAX_SCAN_RPT_THRHOLD
2401#undef MAX_HOTLIST_BSSIDS
Padma, Santhosh Kumara1aa4a32015-06-19 19:00:46 +05302402#undef MAX_BSSID_HISTORY_ENTRIES
2403#undef MAX_HOTLIST_SSIDS
Dino Mycle6fb96c12014-06-10 11:52:40 +05302404
2405static void wlan_hdd_cfg80211_extscan_start_rsp(void *ctx, void *pMsg)
2406{
2407 tpSirEXTScanStartRspParams pData = (tpSirEXTScanStartRspParams) pMsg;
2408 hdd_context_t *pHddCtx = (hdd_context_t *)ctx;
Dino Mycle6fb96c12014-06-10 11:52:40 +05302409 tpAniSirGlobal pMac = PMAC_STRUCT( pHddCtx->hHal );
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05302410 struct hdd_ext_scan_context *context;
Dino Mycle6fb96c12014-06-10 11:52:40 +05302411
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05302412 ENTER();
Dino Mycle6fb96c12014-06-10 11:52:40 +05302413
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05302414 if (wlan_hdd_validate_context(pHddCtx))
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05302415 return;
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05302416
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05302417 if (!pMsg)
2418 {
2419 hddLog(VOS_TRACE_LEVEL_ERROR, FL("pMsg is null"));
Dino Mycle6fb96c12014-06-10 11:52:40 +05302420 return;
2421 }
2422
Dino Mycle6fb96c12014-06-10 11:52:40 +05302423 hddLog(VOS_TRACE_LEVEL_INFO, "Req Id (%u)", pData->requestId);
2424 hddLog(VOS_TRACE_LEVEL_INFO, "Status (%u)", pData->status);
2425
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05302426 context = &pHddCtx->ext_scan_context;
2427 spin_lock(&hdd_context_lock);
2428 if (context->request_id == pData->requestId) {
2429 context->response_status = pData->status ? -EINVAL : 0;
2430 complete(&context->response_event);
Dino Mycle6fb96c12014-06-10 11:52:40 +05302431 }
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05302432 spin_unlock(&hdd_context_lock);
Dino Mycle6fb96c12014-06-10 11:52:40 +05302433
2434 /*
2435 * Store the Request ID for comparing with the requestID obtained
2436 * in other requests.HDD shall return a failure is the extscan_stop
2437 * request is issued with a different requestId as that of the
2438 * extscan_start request. Also, This requestId shall be used while
2439 * indicating the full scan results to the upper layers.
2440 * The requestId is stored with the assumption that the firmware
2441 * shall return the ext scan start request's requestId in ext scan
2442 * start response.
2443 */
2444 if (pData->status == 0)
2445 pMac->sme.extScanStartReqId = pData->requestId;
2446
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05302447 EXIT();
Dino Mycle6fb96c12014-06-10 11:52:40 +05302448 return;
Dino Mycle6fb96c12014-06-10 11:52:40 +05302449}
2450
2451
2452static void wlan_hdd_cfg80211_extscan_stop_rsp(void *ctx, void *pMsg)
2453{
2454 tpSirEXTScanStopRspParams pData = (tpSirEXTScanStopRspParams) pMsg;
2455 hdd_context_t *pHddCtx = (hdd_context_t *)ctx;
Padma, Santhosh Kumar57cff7f2015-08-17 18:33:14 +05302456 struct hdd_ext_scan_context *context;
Dino Mycle6fb96c12014-06-10 11:52:40 +05302457
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05302458 ENTER();
2459
2460 if (wlan_hdd_validate_context(pHddCtx)){
2461 return;
2462 }
Padma, Santhosh Kumar57cff7f2015-08-17 18:33:14 +05302463
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05302464 if (!pMsg)
2465 {
2466 hddLog(VOS_TRACE_LEVEL_ERROR, FL("pMsg is null"));
Dino Mycle6fb96c12014-06-10 11:52:40 +05302467 return;
2468 }
2469
Padma, Santhosh Kumar57cff7f2015-08-17 18:33:14 +05302470 hddLog(VOS_TRACE_LEVEL_INFO, "Req Id %u Status %u", pData->requestId,
2471 pData->status);
Dino Mycle6fb96c12014-06-10 11:52:40 +05302472
Padma, Santhosh Kumar57cff7f2015-08-17 18:33:14 +05302473 context = &pHddCtx->ext_scan_context;
2474 spin_lock(&hdd_context_lock);
2475 if (context->request_id == pData->requestId) {
2476 context->response_status = pData->status ? -EINVAL : 0;
2477 complete(&context->response_event);
Dino Mycle6fb96c12014-06-10 11:52:40 +05302478 }
Padma, Santhosh Kumar57cff7f2015-08-17 18:33:14 +05302479 spin_unlock(&hdd_context_lock);
Dino Mycle6fb96c12014-06-10 11:52:40 +05302480
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05302481 EXIT();
Dino Mycle6fb96c12014-06-10 11:52:40 +05302482 return;
Dino Mycle6fb96c12014-06-10 11:52:40 +05302483}
2484
Dino Mycle6fb96c12014-06-10 11:52:40 +05302485static void wlan_hdd_cfg80211_extscan_set_bss_hotlist_rsp(void *ctx,
2486 void *pMsg)
2487{
2488 hdd_context_t *pHddCtx = (hdd_context_t *)ctx;
Dino Mycle6fb96c12014-06-10 11:52:40 +05302489 tpSirEXTScanSetBssidHotListRspParams pData =
2490 (tpSirEXTScanSetBssidHotListRspParams) pMsg;
Padma, Santhosh Kumar37f4fd12015-08-19 14:37:37 +05302491 struct hdd_ext_scan_context *context;
Dino Mycle6fb96c12014-06-10 11:52:40 +05302492
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05302493 ENTER();
2494
2495 if (wlan_hdd_validate_context(pHddCtx)){
Dino Mycle6fb96c12014-06-10 11:52:40 +05302496 return;
2497 }
Padma, Santhosh Kumar37f4fd12015-08-19 14:37:37 +05302498
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05302499 if (!pMsg)
2500 {
2501 hddLog(VOS_TRACE_LEVEL_ERROR, FL("pMsg is null"));
2502 return;
2503 }
2504
Padma, Santhosh Kumar37f4fd12015-08-19 14:37:37 +05302505 hddLog(VOS_TRACE_LEVEL_INFO, "Req Id %u Status %u", pData->requestId,
2506 pData->status);
Dino Mycle6fb96c12014-06-10 11:52:40 +05302507
Padma, Santhosh Kumar37f4fd12015-08-19 14:37:37 +05302508 context = &pHddCtx->ext_scan_context;
2509 spin_lock(&hdd_context_lock);
2510 if (context->request_id == pData->requestId) {
2511 context->response_status = pData->status ? -EINVAL : 0;
2512 complete(&context->response_event);
Dino Mycle6fb96c12014-06-10 11:52:40 +05302513 }
Padma, Santhosh Kumar37f4fd12015-08-19 14:37:37 +05302514 spin_unlock(&hdd_context_lock);
Dino Mycle6fb96c12014-06-10 11:52:40 +05302515
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05302516 EXIT();
Dino Mycle6fb96c12014-06-10 11:52:40 +05302517 return;
Dino Mycle6fb96c12014-06-10 11:52:40 +05302518}
2519
2520static void wlan_hdd_cfg80211_extscan_reset_bss_hotlist_rsp(void *ctx,
2521 void *pMsg)
2522{
2523 hdd_context_t *pHddCtx = (hdd_context_t *)ctx;
Dino Mycle6fb96c12014-06-10 11:52:40 +05302524 tpSirEXTScanResetBssidHotlistRspParams pData =
2525 (tpSirEXTScanResetBssidHotlistRspParams) pMsg;
Padma, Santhosh Kumar04a3bab2015-08-20 13:09:35 +05302526 struct hdd_ext_scan_context *context;
Dino Mycle6fb96c12014-06-10 11:52:40 +05302527
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05302528 ENTER();
2529
2530 if (wlan_hdd_validate_context(pHddCtx)) {
2531 return;
2532 }
2533 if (!pMsg)
2534 {
2535 hddLog(VOS_TRACE_LEVEL_ERROR, FL("pMsg is null"));
Dino Mycle6fb96c12014-06-10 11:52:40 +05302536 return;
2537 }
2538
Padma, Santhosh Kumar04a3bab2015-08-20 13:09:35 +05302539 hddLog(VOS_TRACE_LEVEL_INFO, "Req Id %u Status %u", pData->requestId,
2540 pData->status);
Dino Mycle6fb96c12014-06-10 11:52:40 +05302541
Padma, Santhosh Kumar04a3bab2015-08-20 13:09:35 +05302542 context = &pHddCtx->ext_scan_context;
2543 spin_lock(&hdd_context_lock);
2544 if (context->request_id == pData->requestId) {
2545 context->response_status = pData->status ? -EINVAL : 0;
2546 complete(&context->response_event);
Dino Mycle6fb96c12014-06-10 11:52:40 +05302547 }
Padma, Santhosh Kumar04a3bab2015-08-20 13:09:35 +05302548 spin_unlock(&hdd_context_lock);
Dino Mycle6fb96c12014-06-10 11:52:40 +05302549
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05302550 EXIT();
Dino Mycle6fb96c12014-06-10 11:52:40 +05302551 return;
Dino Mycle6fb96c12014-06-10 11:52:40 +05302552}
2553
Padma, Santhosh Kumar9acee012015-08-21 19:58:01 +05302554static void wlan_hdd_cfg80211_extscan_set_ssid_hotlist_rsp(void *ctx,
2555 void *pMsg)
2556{
2557 hdd_context_t *pHddCtx = (hdd_context_t *)ctx;
2558 tpSirEXTScanSetSsidHotListRspParams pData =
2559 (tpSirEXTScanSetSsidHotListRspParams) pMsg;
2560 struct hdd_ext_scan_context *context;
2561
2562 if (wlan_hdd_validate_context(pHddCtx)){
2563 return;
2564 }
2565
2566 if (!pMsg)
2567 {
2568 hddLog(VOS_TRACE_LEVEL_ERROR, FL("pMsg is null"));
2569 return;
2570 }
2571
2572 hddLog(VOS_TRACE_LEVEL_INFO, "Req Id %u Status %u", pData->requestId,
2573 pData->status);
2574
2575 context = &pHddCtx->ext_scan_context;
2576 spin_lock(&hdd_context_lock);
2577 if (context->request_id == pData->requestId) {
2578 context->response_status = pData->status ? -EINVAL : 0;
2579 complete(&context->response_event);
2580 }
2581 spin_unlock(&hdd_context_lock);
2582
2583 return;
2584}
2585
2586static void wlan_hdd_cfg80211_extscan_reset_ssid_hotlist_rsp(void *ctx,
2587 void *pMsg)
2588{
2589 hdd_context_t *pHddCtx = (hdd_context_t *)ctx;
2590 tpSirEXTScanResetSsidHotlistRspParams pData =
2591 (tpSirEXTScanResetSsidHotlistRspParams) pMsg;
2592 struct hdd_ext_scan_context *context;
2593
2594 if (wlan_hdd_validate_context(pHddCtx)) {
2595 return;
2596 }
2597 if (!pMsg)
2598 {
2599 hddLog(VOS_TRACE_LEVEL_ERROR, FL("pMsg is null"));
2600 return;
2601 }
2602
2603 hddLog(VOS_TRACE_LEVEL_INFO, "Req Id %u Status %u", pData->requestId,
2604 pData->status);
2605
2606 context = &pHddCtx->ext_scan_context;
2607 spin_lock(&hdd_context_lock);
2608 if (context->request_id == pData->requestId) {
2609 context->response_status = pData->status ? -EINVAL : 0;
2610 complete(&context->response_event);
2611 }
2612 spin_unlock(&hdd_context_lock);
2613
2614 return;
2615}
2616
2617
Dino Mycle6fb96c12014-06-10 11:52:40 +05302618static void wlan_hdd_cfg80211_extscan_cached_results_ind(void *ctx,
2619 void *pMsg)
2620{
2621 hdd_context_t *pHddCtx = (hdd_context_t *)ctx;
2622 struct sk_buff *skb = NULL;
Padma, Santhosh Kumare1b8a942015-08-25 12:44:24 +05302623 tANI_U32 i = 0, j, resultsPerEvent, scan_id_index;
Dino Mycle6fb96c12014-06-10 11:52:40 +05302624 tANI_S32 totalResults;
2625 tpSirWifiScanResultEvent pData = (tpSirWifiScanResultEvent) pMsg;
Padma, Santhosh Kumare1b8a942015-08-25 12:44:24 +05302626 tpSirWifiScanResult pSirWifiScanResult, head_ptr;
2627 struct hdd_ext_scan_context *context;
2628 bool ignore_cached_results = false;
2629 tExtscanCachedScanResult *result;
2630 struct nlattr *nla_results;
2631 tANI_U16 ieLength= 0;
2632 tANI_U8 *ie = NULL;
Dino Mycle6fb96c12014-06-10 11:52:40 +05302633
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05302634 ENTER();
2635
Padma, Santhosh Kumare1b8a942015-08-25 12:44:24 +05302636 if (wlan_hdd_validate_context(pHddCtx))
Dino Mycle6fb96c12014-06-10 11:52:40 +05302637 return;
Padma, Santhosh Kumare1b8a942015-08-25 12:44:24 +05302638
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05302639 if (!pMsg)
2640 {
2641 hddLog(VOS_TRACE_LEVEL_ERROR, FL("pMsg is null"));
2642 return;
2643 }
2644
Padma, Santhosh Kumare1b8a942015-08-25 12:44:24 +05302645 spin_lock(&hdd_context_lock);
2646 context = &pHddCtx->ext_scan_context;
2647 ignore_cached_results = context->ignore_cached_results;
2648 spin_unlock(&hdd_context_lock);
Dino Mycle6fb96c12014-06-10 11:52:40 +05302649
Padma, Santhosh Kumare1b8a942015-08-25 12:44:24 +05302650 if (ignore_cached_results) {
2651 hddLog(LOGE,
2652 FL("Ignore the cached results received after timeout"));
2653 return;
2654 }
Dino Mycle6fb96c12014-06-10 11:52:40 +05302655
Padma, Santhosh Kumare1b8a942015-08-25 12:44:24 +05302656 hddLog(VOS_TRACE_LEVEL_INFO, "Req Id %u More Data %u No of scan ids %u",
2657 pData->requestId, pData->moreData, pData->scanResultSize);
Dino Mycle6fb96c12014-06-10 11:52:40 +05302658
Padma, Santhosh Kumare1b8a942015-08-25 12:44:24 +05302659 result = (tExtscanCachedScanResult *)&(pData->result);
Dino Mycle6fb96c12014-06-10 11:52:40 +05302660
Padma, Santhosh Kumare1b8a942015-08-25 12:44:24 +05302661 for (scan_id_index = 0; scan_id_index < pData->scanResultSize;
2662 scan_id_index++) {
2663 result+= scan_id_index;
Dino Mycle6fb96c12014-06-10 11:52:40 +05302664
Padma, Santhosh Kumare1b8a942015-08-25 12:44:24 +05302665 totalResults = result->num_results;
2666 hddLog(VOS_TRACE_LEVEL_INFO, "scan_id %u flags %u Num results %u",
2667 result->scan_id, result->flags, totalResults);
2668 i = 0;
Dino Mycle6fb96c12014-06-10 11:52:40 +05302669
Padma, Santhosh Kumare1b8a942015-08-25 12:44:24 +05302670 do{
2671 resultsPerEvent = ((totalResults >= EXTSCAN_MAX_CACHED_RESULTS_PER_IND) ?
2672 EXTSCAN_MAX_CACHED_RESULTS_PER_IND : totalResults);
2673 totalResults -= EXTSCAN_MAX_CACHED_RESULTS_PER_IND;
Dino Mycle6fb96c12014-06-10 11:52:40 +05302674
Padma, Santhosh Kumare1b8a942015-08-25 12:44:24 +05302675 skb = cfg80211_vendor_cmd_alloc_reply_skb(pHddCtx->wiphy,
2676 EXTSCAN_EVENT_BUF_SIZE + NLMSG_HDRLEN);
2677
2678 if (!skb) {
2679 hddLog(VOS_TRACE_LEVEL_ERROR,
2680 FL("cfg80211_vendor_event_alloc failed"));
2681 return;
2682 }
2683
2684 hddLog(VOS_TRACE_LEVEL_INFO, "resultsPerEvent (%u)", resultsPerEvent);
2685
2686 if (nla_put_u32(skb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_REQUEST_ID,
2687 pData->requestId) ||
2688 nla_put_u32(skb,
2689 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_NUM_RESULTS_AVAILABLE,
2690 resultsPerEvent)) {
2691 hddLog(VOS_TRACE_LEVEL_ERROR, FL("put fail"));
2692 goto fail;
2693 }
2694 if (nla_put_u8(skb,
2695 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_MORE_DATA,
2696 pData->moreData ? 1 : (totalResults > 0 ? 1 : 0 )))
Dino Mycle6fb96c12014-06-10 11:52:40 +05302697 {
2698 hddLog(VOS_TRACE_LEVEL_ERROR, FL("put fail"));
2699 goto fail;
2700 }
2701
Padma, Santhosh Kumare1b8a942015-08-25 12:44:24 +05302702 if (nla_put_u32(skb,
2703 QCA_WLAN_VENDOR_ATTR_EXTSCAN_CACHED_RESULTS_SCAN_ID,
2704 result->scan_id)) {
2705 hddLog(LOGE, FL("put fail"));
2706 goto fail;
Dino Mycle6fb96c12014-06-10 11:52:40 +05302707 }
Dino Mycle6fb96c12014-06-10 11:52:40 +05302708
Padma, Santhosh Kumare1b8a942015-08-25 12:44:24 +05302709 nla_results = nla_nest_start(skb,
2710 QCA_WLAN_VENDOR_ATTR_EXTSCAN_CACHED_RESULTS_LIST);
2711 if (!nla_results)
2712 goto fail;
2713
2714 if (resultsPerEvent) {
2715 struct nlattr *aps;
2716 struct nlattr *nla_result;
2717
2718 nla_result = nla_nest_start(skb, scan_id_index);
2719 if(!nla_result)
2720 goto fail;
2721
2722 if (nla_put_u32(skb,
2723 QCA_WLAN_VENDOR_ATTR_EXTSCAN_CACHED_RESULTS_SCAN_ID,
2724 result->scan_id) ||
2725 nla_put_u32(skb,
2726 QCA_WLAN_VENDOR_ATTR_EXTSCAN_CACHED_RESULTS_FLAGS,
2727 result->flags) ||
2728 nla_put_u32(skb,
2729 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_NUM_RESULTS_AVAILABLE,
2730 totalResults)) {
2731 hddLog(LOGE, FL("put fail"));
2732 goto fail;
2733 }
2734
2735 aps = nla_nest_start(skb,
2736 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_LIST);
2737 if (!aps)
2738 {
2739 hddLog(VOS_TRACE_LEVEL_ERROR, FL("put fail"));
2740 goto fail;
2741 }
2742
2743 head_ptr = (tpSirWifiScanResult) &(result->ap);
2744
2745 for (j = 0; j < resultsPerEvent; j++, i++) {
2746 struct nlattr *ap;
2747 pSirWifiScanResult = head_ptr + i;
2748
2749 /*
2750 * Firmware returns timestamp from WiFi turn ON till
2751 * BSSID was cached (in seconds). Add this with
2752 * time gap between system boot up to WiFi turn ON
2753 * to derive the time since boot when the
2754 * BSSID was cached.
2755 */
2756 pSirWifiScanResult->ts += pHddCtx->wifi_turn_on_time_since_boot;
2757 hddLog(VOS_TRACE_LEVEL_INFO, "[index=%u] Timestamp(%llu) "
2758 "Ssid (%s)"
2759 "Bssid: %pM "
2760 "Channel (%u)"
2761 "Rssi (%d)"
2762 "RTT (%u)"
2763 "RTT_SD (%u)"
2764 "Beacon Period %u"
2765 "Capability 0x%x "
2766 "Ie length %d",
2767 i,
2768 pSirWifiScanResult->ts,
2769 pSirWifiScanResult->ssid,
2770 pSirWifiScanResult->bssid,
2771 pSirWifiScanResult->channel,
2772 pSirWifiScanResult->rssi,
2773 pSirWifiScanResult->rtt,
2774 pSirWifiScanResult->rtt_sd,
2775 pSirWifiScanResult->beaconPeriod,
2776 pSirWifiScanResult->capability,
2777 ieLength);
2778
2779 ap = nla_nest_start(skb, j + 1);
2780 if (!ap)
2781 {
2782 hddLog(VOS_TRACE_LEVEL_ERROR, FL("put fail"));
2783 goto fail;
2784 }
2785
2786 if (nla_put_u64(skb,
2787 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_TIME_STAMP,
2788 pSirWifiScanResult->ts) )
2789 {
2790 hddLog(VOS_TRACE_LEVEL_ERROR, FL("put fail"));
2791 goto fail;
2792 }
2793 if (nla_put(skb,
2794 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_SSID,
2795 sizeof(pSirWifiScanResult->ssid),
2796 pSirWifiScanResult->ssid) )
2797 {
2798 hddLog(VOS_TRACE_LEVEL_ERROR, FL("put fail"));
2799 goto fail;
2800 }
2801 if (nla_put(skb,
2802 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_BSSID,
2803 sizeof(pSirWifiScanResult->bssid),
2804 pSirWifiScanResult->bssid) )
2805 {
2806 hddLog(VOS_TRACE_LEVEL_ERROR, FL("put fail"));
2807 goto fail;
2808 }
2809 if (nla_put_u32(skb,
2810 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_CHANNEL,
2811 pSirWifiScanResult->channel) )
2812 {
2813 hddLog(VOS_TRACE_LEVEL_ERROR, FL("put fail"));
2814 goto fail;
2815 }
2816 if (nla_put_s32(skb,
2817 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_RSSI,
2818 pSirWifiScanResult->rssi) )
2819 {
2820 hddLog(VOS_TRACE_LEVEL_ERROR, FL("put fail"));
2821 goto fail;
2822 }
2823 if (nla_put_u32(skb,
2824 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_RTT,
2825 pSirWifiScanResult->rtt) )
2826 {
2827 hddLog(VOS_TRACE_LEVEL_ERROR, FL("put fail"));
2828 goto fail;
2829 }
2830 if (nla_put_u32(skb,
2831 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_RTT_SD,
2832 pSirWifiScanResult->rtt_sd))
2833 {
2834 hddLog(VOS_TRACE_LEVEL_ERROR, FL("put fail"));
2835 goto fail;
2836 }
2837 if (nla_put_u32(skb,
2838 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_BEACON_PERIOD,
2839 pSirWifiScanResult->beaconPeriod))
2840 {
2841 hddLog(VOS_TRACE_LEVEL_ERROR, FL("put fail"));
2842 goto fail;
2843 }
2844 if (nla_put_u32(skb,
2845 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_CAPABILITY,
2846 pSirWifiScanResult->capability))
2847 {
2848 hddLog(VOS_TRACE_LEVEL_ERROR, FL("put fail"));
2849 goto fail;
2850 }
2851 if (nla_put_u32(skb,
2852 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_IE_LENGTH,
2853 ieLength))
2854 {
2855 hddLog(VOS_TRACE_LEVEL_ERROR, FL("put fail"));
2856 goto fail;
2857 }
2858
2859 if (ieLength)
2860 if (nla_put(skb,
2861 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_IE_DATA,
2862 ieLength, ie)) {
2863 hddLog(VOS_TRACE_LEVEL_ERROR, FL("put fail"));
2864 goto fail;
2865 }
2866
2867 nla_nest_end(skb, ap);
2868 }
2869 nla_nest_end(skb, aps);
2870 nla_nest_end(skb, nla_result);
2871 }
2872
2873 nla_nest_end(skb, nla_results);
2874
2875 cfg80211_vendor_cmd_reply(skb);
2876
2877 } while (totalResults > 0);
2878 }
2879
2880 if (!pData->moreData) {
2881 spin_lock(&hdd_context_lock);
2882 context->response_status = 0;
2883 complete(&context->response_event);
2884 spin_unlock(&hdd_context_lock);
2885 }
Dino Mycle6fb96c12014-06-10 11:52:40 +05302886
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05302887 EXIT();
Dino Mycle6fb96c12014-06-10 11:52:40 +05302888 return;
2889fail:
2890 kfree_skb(skb);
2891 return;
2892}
2893
2894static void wlan_hdd_cfg80211_extscan_hotlist_match_ind(void *ctx,
2895 void *pMsg)
2896{
Padma, Santhosh Kumar37f4fd12015-08-19 14:37:37 +05302897 tpSirEXTScanHotlistMatch pData = (tpSirEXTScanHotlistMatch) pMsg;
Dino Mycle6fb96c12014-06-10 11:52:40 +05302898 hdd_context_t *pHddCtx = (hdd_context_t *)ctx;
2899 struct sk_buff *skb = NULL;
Padma, Santhosh Kumar37f4fd12015-08-19 14:37:37 +05302900 tANI_U32 i, index;
Dino Mycle6fb96c12014-06-10 11:52:40 +05302901
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05302902 ENTER();
2903
2904 if (wlan_hdd_validate_context(pHddCtx)) {
Padma, Santhosh Kumar37f4fd12015-08-19 14:37:37 +05302905 hddLog(LOGE,
2906 FL("HDD context is not valid or response"));
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05302907 return;
2908 }
2909 if (!pMsg)
2910 {
2911 hddLog(VOS_TRACE_LEVEL_ERROR, FL("pMsg is null"));
Dino Mycle6fb96c12014-06-10 11:52:40 +05302912 return;
2913 }
2914
Padma, Santhosh Kumar37f4fd12015-08-19 14:37:37 +05302915 if (pData->bss_found)
2916 index = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_HOTLIST_AP_FOUND_INDEX;
2917 else
2918 index = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_HOTLIST_AP_LOST_INDEX;
2919
Dino Mycle6fb96c12014-06-10 11:52:40 +05302920 skb = cfg80211_vendor_event_alloc(pHddCtx->wiphy,
Anand N Sunkad26ca6cc2015-07-29 09:54:52 +05302921#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 18, 0))
2922 NULL,
2923#endif
Dino Mycle6fb96c12014-06-10 11:52:40 +05302924 EXTSCAN_EVENT_BUF_SIZE + NLMSG_HDRLEN,
Padma, Santhosh Kumar37f4fd12015-08-19 14:37:37 +05302925 index, GFP_KERNEL);
Dino Mycle6fb96c12014-06-10 11:52:40 +05302926
2927 if (!skb) {
2928 hddLog(VOS_TRACE_LEVEL_ERROR,
2929 FL("cfg80211_vendor_event_alloc failed"));
2930 return;
2931 }
Dino Mycle6fb96c12014-06-10 11:52:40 +05302932
Padma, Santhosh Kumar37f4fd12015-08-19 14:37:37 +05302933 hddLog(VOS_TRACE_LEVEL_INFO, "Req Id (%u)", pData->requestId);
2934 hddLog(VOS_TRACE_LEVEL_INFO, "Num results (%u)", pData->numHotlistBss);
2935 hddLog(VOS_TRACE_LEVEL_INFO, "More Data (%u)", pData->moreData);
2936 hddLog(VOS_TRACE_LEVEL_INFO, "ap_found %u", pData->bss_found);
2937
2938 for (i = 0; i < pData->numHotlistBss; i++) {
Dino Mycle6fb96c12014-06-10 11:52:40 +05302939 hddLog(VOS_TRACE_LEVEL_INFO, "[index=%u] Timestamp(0x%lld) "
2940 "Ssid (%s) "
2941 "Bssid (" MAC_ADDRESS_STR ") "
2942 "Channel (%u) "
2943 "Rssi (%d) "
2944 "RTT (%u) "
2945 "RTT_SD (%u) ",
2946 i,
Padma, Santhosh Kumar37f4fd12015-08-19 14:37:37 +05302947 pData->bssHotlist[i].ts,
2948 pData->bssHotlist[i].ssid,
2949 MAC_ADDR_ARRAY(pData->bssHotlist[i].bssid),
2950 pData->bssHotlist[i].channel,
2951 pData->bssHotlist[i].rssi,
2952 pData->bssHotlist[i].rtt,
2953 pData->bssHotlist[i].rtt_sd);
Dino Mycle6fb96c12014-06-10 11:52:40 +05302954 }
2955
2956 if (nla_put_u32(skb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_REQUEST_ID,
2957 pData->requestId) ||
2958 nla_put_u32(skb,
2959 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_NUM_RESULTS_AVAILABLE,
Padma, Santhosh Kumar37f4fd12015-08-19 14:37:37 +05302960 pData->numHotlistBss)) {
Dino Mycle6fb96c12014-06-10 11:52:40 +05302961 hddLog(VOS_TRACE_LEVEL_ERROR, FL("put fail"));
2962 goto fail;
2963 }
Padma, Santhosh Kumar37f4fd12015-08-19 14:37:37 +05302964 if (pData->numHotlistBss) {
Dino Mycle6fb96c12014-06-10 11:52:40 +05302965 struct nlattr *aps;
2966
2967 aps = nla_nest_start(skb,
2968 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_LIST);
2969 if (!aps)
2970 goto fail;
2971
Padma, Santhosh Kumar37f4fd12015-08-19 14:37:37 +05302972 for (i = 0; i < pData->numHotlistBss; i++) {
Dino Mycle6fb96c12014-06-10 11:52:40 +05302973 struct nlattr *ap;
2974
2975 ap = nla_nest_start(skb, i + 1);
2976 if (!ap)
2977 goto fail;
2978
2979 if (nla_put_u64(skb,
2980 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_TIME_STAMP,
Padma, Santhosh Kumar37f4fd12015-08-19 14:37:37 +05302981 pData->bssHotlist[i].ts) ||
Dino Mycle6fb96c12014-06-10 11:52:40 +05302982 nla_put(skb,
2983 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_SSID,
Padma, Santhosh Kumar37f4fd12015-08-19 14:37:37 +05302984 sizeof(pData->bssHotlist[i].ssid),
2985 pData->bssHotlist[i].ssid) ||
Dino Mycle6fb96c12014-06-10 11:52:40 +05302986 nla_put(skb,
2987 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_BSSID,
Padma, Santhosh Kumar37f4fd12015-08-19 14:37:37 +05302988 sizeof(pData->bssHotlist[i].bssid),
2989 pData->bssHotlist[i].bssid) ||
Dino Mycle6fb96c12014-06-10 11:52:40 +05302990 nla_put_u32(skb,
2991 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_CHANNEL,
Padma, Santhosh Kumar37f4fd12015-08-19 14:37:37 +05302992 pData->bssHotlist[i].channel) ||
Dino Mycle6fb96c12014-06-10 11:52:40 +05302993 nla_put_s32(skb,
2994 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_RSSI,
Padma, Santhosh Kumar37f4fd12015-08-19 14:37:37 +05302995 pData->bssHotlist[i].rssi) ||
Dino Mycle6fb96c12014-06-10 11:52:40 +05302996 nla_put_u32(skb,
2997 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_RTT,
Padma, Santhosh Kumar37f4fd12015-08-19 14:37:37 +05302998 pData->bssHotlist[i].rtt) ||
Dino Mycle6fb96c12014-06-10 11:52:40 +05302999 nla_put_u32(skb,
3000 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_RTT_SD,
Padma, Santhosh Kumar37f4fd12015-08-19 14:37:37 +05303001 pData->bssHotlist[i].rtt_sd))
Dino Mycle6fb96c12014-06-10 11:52:40 +05303002 goto fail;
3003
3004 nla_nest_end(skb, ap);
3005 }
3006 nla_nest_end(skb, aps);
3007
3008 if (nla_put_u8(skb,
3009 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_MORE_DATA,
3010 pData->moreData))
3011 goto fail;
3012 }
3013
3014 cfg80211_vendor_event(skb, GFP_KERNEL);
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05303015 EXIT();
Dino Mycle6fb96c12014-06-10 11:52:40 +05303016 return;
3017
3018fail:
3019 kfree_skb(skb);
3020 return;
3021
3022}
Dino Mycle6fb96c12014-06-10 11:52:40 +05303023
Padma, Santhosh Kumar9acee012015-08-21 19:58:01 +05303024/**
3025 * wlan_hdd_cfg80211_extscan_hotlist_ssid_match_ind() -
3026 * Handle an SSID hotlist match event
3027 * @ctx: HDD context registered with SME
3028 * @event: The SSID hotlist match event
3029 *
3030 * This function will take an SSID match event that was generated by
3031 * firmware and will convert it into a cfg80211 vendor event which is
3032 * sent to userspace.
3033 *
3034 * Return: none
3035 */
3036static void
3037wlan_hdd_cfg80211_extscan_hotlist_ssid_match_ind(void *ctx,
3038 void *pMsg)
3039{
3040 hdd_context_t *hdd_ctx = ctx;
3041 struct sk_buff *skb;
3042 tANI_U32 i, index;
3043 tpSirEXTScanSsidHotlistMatch pData = (tpSirEXTScanSsidHotlistMatch) pMsg;
3044
3045 ENTER();
3046
3047 if (wlan_hdd_validate_context(hdd_ctx)) {
3048 hddLog(LOGE,
3049 FL("HDD context is not valid or response"));
3050 return;
3051 }
3052 if (!pMsg)
3053 {
3054 hddLog(VOS_TRACE_LEVEL_ERROR, FL("pMsg is null"));
3055 return;
3056 }
3057
3058 if (pData->ssid_found) {
3059 index = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_HOTLIST_SSID_FOUND_INDEX;
3060 hddLog(LOG1, "SSID hotlist found");
3061 } else {
3062 index = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_HOTLIST_SSID_LOST_INDEX;
3063 hddLog(LOG1, "SSID hotlist lost");
3064 }
3065
3066 skb = cfg80211_vendor_event_alloc(hdd_ctx->wiphy,
3067#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 18, 0))
3068 NULL,
3069#endif
3070 EXTSCAN_EVENT_BUF_SIZE + NLMSG_HDRLEN,
3071 index, GFP_KERNEL);
3072
3073 if (!skb) {
3074 hddLog(LOGE, FL("cfg80211_vendor_event_alloc failed"));
3075 return;
3076 }
3077 hddLog(LOG1, "Req Id %u, Num of SSIDs %u, More Data (%u)",
3078 pData->requestId, pData->numHotlistSsid, pData->moreData);
3079
3080 for (i = 0; i < pData->numHotlistSsid; i++) {
3081 hddLog(LOG1, "[i=%d] Timestamp %llu "
3082 "Ssid: %s "
3083 "Bssid (" MAC_ADDRESS_STR ") "
3084 "Channel %u "
3085 "Rssi %d "
3086 "RTT %u "
3087 "RTT_SD %u",
3088 i,
3089 pData->ssidHotlist[i].ts,
3090 pData->ssidHotlist[i].ssid,
3091 MAC_ADDR_ARRAY(pData->ssidHotlist[i].bssid),
3092 pData->ssidHotlist[i].channel,
3093 pData->ssidHotlist[i].rssi,
3094 pData->ssidHotlist[i].rtt,
3095 pData->ssidHotlist[i].rtt_sd);
3096 }
3097
3098 if (nla_put_u32(skb,
3099 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_REQUEST_ID,
3100 pData->requestId) ||
3101 nla_put_u32(skb,
3102 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_NUM_RESULTS_AVAILABLE,
3103 pData->numHotlistSsid)) {
3104 hddLog(LOGE, FL("put fail"));
3105 goto fail;
3106 }
3107
3108 if (pData->numHotlistSsid) {
3109 struct nlattr *aps;
3110 aps = nla_nest_start(skb,
3111 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_LIST);
3112 if (!aps) {
3113 hddLog(LOGE, FL("nest fail"));
3114 goto fail;
3115 }
3116
3117 for (i = 0; i < pData->numHotlistSsid; i++) {
3118 struct nlattr *ap;
3119
3120 ap = nla_nest_start(skb, i);
3121 if (!ap) {
3122 hddLog(LOGE, FL("nest fail"));
3123 goto fail;
3124 }
3125
3126 if (nla_put_u64(skb,
3127 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_TIME_STAMP,
3128 pData->ssidHotlist[i].ts) ||
3129 nla_put(skb,
3130 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_SSID,
3131 sizeof(pData->ssidHotlist[i].ssid),
3132 pData->ssidHotlist[i].ssid) ||
3133 nla_put(skb,
3134 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_BSSID,
3135 sizeof(pData->ssidHotlist[i].bssid),
3136 pData->ssidHotlist[i].bssid) ||
3137 nla_put_u32(skb,
3138 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_CHANNEL,
3139 pData->ssidHotlist[i].channel) ||
3140 nla_put_s32(skb,
3141 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_RSSI,
3142 pData->ssidHotlist[i].rssi) ||
3143 nla_put_u32(skb,
3144 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_RTT,
3145 pData->ssidHotlist[i].rtt) ||
3146 nla_put_u32(skb,
3147 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_RTT_SD,
3148 pData->ssidHotlist[i].rtt_sd)) {
3149 hddLog(LOGE, FL("put fail"));
3150 goto fail;
3151 }
3152 nla_nest_end(skb, ap);
3153 }
3154 nla_nest_end(skb, aps);
3155
3156 if (nla_put_u8(skb,
3157 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_MORE_DATA,
3158 pData->moreData)) {
3159 hddLog(LOGE, FL("put fail"));
3160 goto fail;
3161 }
3162 }
3163
3164 cfg80211_vendor_event(skb, GFP_KERNEL);
3165 return;
3166
3167fail:
3168 kfree_skb(skb);
3169 return;
3170
3171}
3172
3173
Dino Mycle6fb96c12014-06-10 11:52:40 +05303174static void wlan_hdd_cfg80211_extscan_full_scan_result_event(void *ctx,
3175 void *pMsg)
3176{
3177 struct sk_buff *skb;
3178 hdd_context_t *pHddCtx = (hdd_context_t *)ctx;
3179 tpSirWifiFullScanResultEvent pData =
3180 (tpSirWifiFullScanResultEvent) (pMsg);
3181
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05303182 ENTER();
3183
3184 if (wlan_hdd_validate_context(pHddCtx)) {
Padma, Santhosh Kumare1b8a942015-08-25 12:44:24 +05303185 hddLog(LOGE,
3186 FL("HDD context is not valid or response"));
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05303187 return;
3188 }
3189 if (!pMsg)
3190 {
3191 hddLog(VOS_TRACE_LEVEL_ERROR, FL("pMsg is null"));
Dino Mycle6fb96c12014-06-10 11:52:40 +05303192 return;
3193 }
3194
Padma, Santhosh Kumare1b8a942015-08-25 12:44:24 +05303195 /*
3196 * If the full scan result including IE data exceeds NL 4K size
3197 * limitation, drop that beacon/probe rsp frame.
3198 */
3199 if ((sizeof(*pData) + pData->ieLength) >= EXTSCAN_EVENT_BUF_SIZE) {
3200 hddLog(LOGE, FL("Frame exceeded NL size limilation, drop it!"));
3201 return;
3202 }
3203
Dino Mycle6fb96c12014-06-10 11:52:40 +05303204 skb = cfg80211_vendor_event_alloc(pHddCtx->wiphy,
Anand N Sunkad26ca6cc2015-07-29 09:54:52 +05303205#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 18, 0))
3206 NULL,
3207#endif
Dino Mycle6fb96c12014-06-10 11:52:40 +05303208 EXTSCAN_EVENT_BUF_SIZE + NLMSG_HDRLEN,
3209 QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_FULL_SCAN_RESULT_INDEX,
3210 GFP_KERNEL);
3211
3212 if (!skb) {
3213 hddLog(VOS_TRACE_LEVEL_ERROR,
3214 FL("cfg80211_vendor_event_alloc failed"));
3215 return;
3216 }
3217
Dino Mycle6fb96c12014-06-10 11:52:40 +05303218 hddLog(VOS_TRACE_LEVEL_INFO, FL("Req Id (%u)"), pData->requestId);
3219 hddLog(VOS_TRACE_LEVEL_INFO, FL("More Data (%u)"), pData->moreData);
3220 hddLog(VOS_TRACE_LEVEL_INFO, FL("AP Info: Timestamp(0x%llX) "
3221 "Ssid (%s)"
3222 "Bssid (" MAC_ADDRESS_STR ")"
3223 "Channel (%u)"
3224 "Rssi (%d)"
3225 "RTT (%u)"
Padma, Santhosh Kumare1b8a942015-08-25 12:44:24 +05303226 "RTT_SD (%u)"
3227 "Bcn Period %d"
3228 "Capability 0x%X "),
Dino Mycle6fb96c12014-06-10 11:52:40 +05303229 pData->ap.ts,
3230 pData->ap.ssid,
3231 MAC_ADDR_ARRAY(pData->ap.bssid),
3232 pData->ap.channel,
3233 pData->ap.rssi,
3234 pData->ap.rtt,
Padma, Santhosh Kumare1b8a942015-08-25 12:44:24 +05303235 pData->ap.rtt_sd,
3236 pData->ap.beaconPeriod,
3237 pData->ap.capability);
3238
Dino Mycle6fb96c12014-06-10 11:52:40 +05303239 hddLog(VOS_TRACE_LEVEL_INFO, "IE Length (%u)", pData->ieLength);
3240 if (nla_put_u32(skb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_REQUEST_ID,
3241 pData->requestId) ||
3242 nla_put_u64(skb,
3243 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_TIME_STAMP,
3244 pData->ap.ts) ||
3245 nla_put(skb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_SSID,
3246 sizeof(pData->ap.ssid),
3247 pData->ap.ssid) ||
3248 nla_put(skb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_BSSID,
3249 WNI_CFG_BSSID_LEN,
3250 pData->ap.bssid) ||
3251 nla_put_u32(skb,
3252 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_CHANNEL,
3253 pData->ap.channel) ||
Dasari Srinivas90747d72014-10-08 12:16:15 +05303254 nla_put_s32(skb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_RSSI,
Dino Mycle6fb96c12014-06-10 11:52:40 +05303255 pData->ap.rssi) ||
3256 nla_put_u32(skb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_RTT,
3257 pData->ap.rtt) ||
3258 nla_put_u32(skb,
3259 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_RTT_SD,
3260 pData->ap.rtt_sd) ||
3261 nla_put_u16(skb,
3262 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_BEACON_PERIOD,
3263 pData->ap.beaconPeriod) ||
3264 nla_put_u16(skb,
3265 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_CAPABILITY,
3266 pData->ap.capability) ||
3267 nla_put_u32(skb,
3268 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_IE_LENGTH,
Padma, Santhosh Kumare1b8a942015-08-25 12:44:24 +05303269 pData->ieLength) ||
3270 nla_put_u8(skb,
3271 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_MORE_DATA,
3272 pData->moreData))
Dino Mycle6fb96c12014-06-10 11:52:40 +05303273 {
3274 hddLog(VOS_TRACE_LEVEL_ERROR, FL("nla put fail"));
3275 goto nla_put_failure;
3276 }
Padma, Santhosh Kumare1b8a942015-08-25 12:44:24 +05303277
3278 if (pData->ieLength) {
3279 if (nla_put(skb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_IE_DATA,
3280 pData->ieLength,
3281 pData->ie))
3282 {
3283 hddLog(VOS_TRACE_LEVEL_ERROR, FL("nla put fail"));
3284 goto nla_put_failure;
3285 }
Dino Mycle6fb96c12014-06-10 11:52:40 +05303286 }
3287
3288 cfg80211_vendor_event(skb, GFP_KERNEL);
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05303289 EXIT();
Dino Mycle6fb96c12014-06-10 11:52:40 +05303290 return;
3291
3292nla_put_failure:
3293 kfree_skb(skb);
3294 return;
3295}
3296
3297static void wlan_hdd_cfg80211_extscan_scan_res_available_event(void *ctx,
3298 void *pMsg)
3299{
3300 hdd_context_t *pHddCtx = (hdd_context_t *)ctx;
3301 struct sk_buff *skb = NULL;
3302 tpSirEXTScanResultsAvailableIndParams pData =
3303 (tpSirEXTScanResultsAvailableIndParams) pMsg;
3304
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05303305 ENTER();
3306
3307 if (wlan_hdd_validate_context(pHddCtx)){
Padma, Santhosh Kumare1b8a942015-08-25 12:44:24 +05303308 hddLog(LOGE,
3309 FL("HDD context is not valid or response"));
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05303310 return;
3311 }
3312 if (!pMsg)
3313 {
3314 hddLog(VOS_TRACE_LEVEL_ERROR, FL("pMsg is null"));
Dino Mycle6fb96c12014-06-10 11:52:40 +05303315 return;
3316 }
3317
3318 skb = cfg80211_vendor_event_alloc(pHddCtx->wiphy,
Anand N Sunkad26ca6cc2015-07-29 09:54:52 +05303319#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 18, 0))
3320 NULL,
3321#endif
Dino Mycle6fb96c12014-06-10 11:52:40 +05303322 EXTSCAN_EVENT_BUF_SIZE + NLMSG_HDRLEN,
3323 QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_SCAN_RESULTS_AVAILABLE_INDEX,
3324 GFP_KERNEL);
3325
3326 if (!skb) {
3327 hddLog(VOS_TRACE_LEVEL_ERROR,
3328 FL("cfg80211_vendor_event_alloc failed"));
3329 return;
3330 }
3331
Dino Mycle6fb96c12014-06-10 11:52:40 +05303332 hddLog(VOS_TRACE_LEVEL_INFO, "Req Id (%u)", pData->requestId);
3333 hddLog(VOS_TRACE_LEVEL_INFO, "Num results (%u)",
3334 pData->numResultsAvailable);
3335 if (nla_put_u32(skb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_REQUEST_ID,
3336 pData->requestId) ||
3337 nla_put_u32(skb,
3338 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_NUM_RESULTS_AVAILABLE,
3339 pData->numResultsAvailable)) {
3340 hddLog(VOS_TRACE_LEVEL_ERROR, FL("nla put fail"));
3341 goto nla_put_failure;
3342 }
3343
3344 cfg80211_vendor_event(skb, GFP_KERNEL);
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05303345 EXIT();
Dino Mycle6fb96c12014-06-10 11:52:40 +05303346 return;
3347
3348nla_put_failure:
3349 kfree_skb(skb);
3350 return;
3351}
3352
3353static void wlan_hdd_cfg80211_extscan_scan_progress_event(void *ctx, void *pMsg)
3354{
3355 hdd_context_t *pHddCtx = (hdd_context_t *)ctx;
3356 struct sk_buff *skb = NULL;
3357 tpSirEXTScanProgressIndParams pData =
3358 (tpSirEXTScanProgressIndParams) pMsg;
3359
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05303360 ENTER();
3361
3362 if (wlan_hdd_validate_context(pHddCtx)){
Padma, Santhosh Kumare1b8a942015-08-25 12:44:24 +05303363 hddLog(LOGE,
3364 FL("HDD context is not valid or response"));
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05303365 return;
3366 }
3367 if (!pMsg)
3368 {
3369 hddLog(VOS_TRACE_LEVEL_ERROR, FL("pMsg is null"));
Dino Mycle6fb96c12014-06-10 11:52:40 +05303370 return;
3371 }
3372
3373 skb = cfg80211_vendor_event_alloc(pHddCtx->wiphy,
Anand N Sunkad26ca6cc2015-07-29 09:54:52 +05303374#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 18, 0))
3375 NULL,
3376#endif
Dino Mycle6fb96c12014-06-10 11:52:40 +05303377 EXTSCAN_EVENT_BUF_SIZE + NLMSG_HDRLEN,
3378 QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_SCAN_EVENT_INDEX,
3379 GFP_KERNEL);
3380
3381 if (!skb) {
3382 hddLog(VOS_TRACE_LEVEL_ERROR,
3383 FL("cfg80211_vendor_event_alloc failed"));
3384 return;
3385 }
Padma, Santhosh Kumare1b8a942015-08-25 12:44:24 +05303386 hddLog(VOS_TRACE_LEVEL_INFO, FL("Request Id (%u) "), pData->requestId);
Dino Mycle6fb96c12014-06-10 11:52:40 +05303387 hddLog(VOS_TRACE_LEVEL_INFO, "Scan event type (%u)",
3388 pData->extScanEventType);
3389 hddLog(VOS_TRACE_LEVEL_INFO, "Scan event status (%u)",
3390 pData->status);
3391
3392 if (nla_put_u8(skb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_EVENT_TYPE,
3393 pData->extScanEventType) ||
3394 nla_put_u32(skb,
Dasari Srinivas5a288652014-06-30 17:13:22 +05303395 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_REQUEST_ID,
3396 pData->requestId) ||
3397 nla_put_u32(skb,
Dino Mycle6fb96c12014-06-10 11:52:40 +05303398 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_EVENT_STATUS,
3399 pData->status)) {
3400 hddLog(VOS_TRACE_LEVEL_ERROR, FL("nla put fail"));
3401 goto nla_put_failure;
3402 }
3403
3404 cfg80211_vendor_event(skb, GFP_KERNEL);
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05303405 EXIT();
Dino Mycle6fb96c12014-06-10 11:52:40 +05303406 return;
3407
3408nla_put_failure:
3409 kfree_skb(skb);
3410 return;
3411}
3412
3413void wlan_hdd_cfg80211_extscan_callback(void *ctx, const tANI_U16 evType,
3414 void *pMsg)
3415{
3416 hdd_context_t *pHddCtx = (hdd_context_t *)ctx;
3417
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05303418 ENTER();
3419
Dino Mycle6fb96c12014-06-10 11:52:40 +05303420 if (wlan_hdd_validate_context(pHddCtx)) {
Dino Mycle6fb96c12014-06-10 11:52:40 +05303421 return;
3422 }
3423
3424 hddLog(VOS_TRACE_LEVEL_INFO, FL("Rcvd Event (%d)"), evType);
3425
3426
3427 switch(evType) {
3428 case SIR_HAL_EXTSCAN_START_RSP:
3429 wlan_hdd_cfg80211_extscan_start_rsp(ctx, pMsg);
3430 break;
3431
3432 case SIR_HAL_EXTSCAN_STOP_RSP:
3433 wlan_hdd_cfg80211_extscan_stop_rsp(ctx, pMsg);
3434 break;
3435 case SIR_HAL_EXTSCAN_GET_CACHED_RESULTS_RSP:
3436 /* There is no need to send this response to upper layer
3437 Just log the message */
3438 hddLog(VOS_TRACE_LEVEL_INFO,
3439 FL("Rcvd SIR_HAL_EXTSCAN_CACHED_RESULTS_RSP"));
3440 break;
3441 case SIR_HAL_EXTSCAN_SET_BSS_HOTLIST_RSP:
3442 wlan_hdd_cfg80211_extscan_set_bss_hotlist_rsp(ctx, pMsg);
3443 break;
3444
3445 case SIR_HAL_EXTSCAN_RESET_BSS_HOTLIST_RSP:
3446 wlan_hdd_cfg80211_extscan_reset_bss_hotlist_rsp(ctx, pMsg);
3447 break;
3448
Padma, Santhosh Kumar9acee012015-08-21 19:58:01 +05303449 case SIR_HAL_EXTSCAN_SET_SSID_HOTLIST_RSP:
3450 wlan_hdd_cfg80211_extscan_set_ssid_hotlist_rsp(ctx, pMsg);
3451 break;
3452
3453 case SIR_HAL_EXTSCAN_RESET_SSID_HOTLIST_RSP:
3454 wlan_hdd_cfg80211_extscan_reset_ssid_hotlist_rsp(ctx, pMsg);
3455 break;
3456
Dino Mycle6fb96c12014-06-10 11:52:40 +05303457 case SIR_HAL_EXTSCAN_GET_CAPABILITIES_RSP:
Padma, Santhosh Kumara1aa4a32015-06-19 19:00:46 +05303458 wlan_hdd_cfg80211_extscan_get_capabilities_rsp(ctx, pMsg);
Dino Mycle6fb96c12014-06-10 11:52:40 +05303459 break;
3460 case SIR_HAL_EXTSCAN_PROGRESS_IND:
3461 wlan_hdd_cfg80211_extscan_scan_progress_event(ctx, pMsg);
3462 break;
3463 case SIR_HAL_EXTSCAN_SCAN_AVAILABLE_IND:
3464 wlan_hdd_cfg80211_extscan_scan_res_available_event(ctx, pMsg);
3465 break;
3466 case SIR_HAL_EXTSCAN_SCAN_RESULT_IND:
3467 wlan_hdd_cfg80211_extscan_cached_results_ind(ctx, pMsg);
3468 break;
3469 case SIR_HAL_EXTSCAN_HOTLIST_MATCH_IND:
3470 wlan_hdd_cfg80211_extscan_hotlist_match_ind(ctx, pMsg);
3471 break;
Padma, Santhosh Kumar9acee012015-08-21 19:58:01 +05303472 case SIR_HAL_EXTSCAN_SSID_HOTLIST_MATCH_IND:
3473 wlan_hdd_cfg80211_extscan_hotlist_ssid_match_ind(ctx, pMsg);
3474 break;
Dino Mycle6fb96c12014-06-10 11:52:40 +05303475 case SIR_HAL_EXTSCAN_FULL_SCAN_RESULT_IND:
3476 wlan_hdd_cfg80211_extscan_full_scan_result_event(ctx, pMsg);
3477 break;
3478 default:
3479 hddLog(VOS_TRACE_LEVEL_ERROR, FL("invalid event type %d "), evType);
3480 break;
3481 }
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05303482 EXIT();
Dino Mycle6fb96c12014-06-10 11:52:40 +05303483}
3484
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05303485static int __wlan_hdd_cfg80211_extscan_get_capabilities(struct wiphy *wiphy,
3486 struct wireless_dev *wdev,
3487 const void *data, int dataLen)
Dino Mycle6fb96c12014-06-10 11:52:40 +05303488{
Dino Myclee8843b32014-07-04 14:21:45 +05303489 tSirGetEXTScanCapabilitiesReqParams reqMsg;
Dino Mycle6fb96c12014-06-10 11:52:40 +05303490 struct net_device *dev = wdev->netdev;
3491 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
3492 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
3493 struct nlattr
3494 *tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX + 1];
3495 eHalStatus status;
Padma, Santhosh Kumara1aa4a32015-06-19 19:00:46 +05303496 struct hdd_ext_scan_context *context;
3497 unsigned long rc;
3498 int ret;
Dino Mycle6fb96c12014-06-10 11:52:40 +05303499
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05303500 ENTER();
3501
Dino Mycle6fb96c12014-06-10 11:52:40 +05303502 status = wlan_hdd_validate_context(pHddCtx);
3503 if (0 != status)
3504 {
Dino Mycle6fb96c12014-06-10 11:52:40 +05303505 return -EINVAL;
3506 }
Dino Myclee8843b32014-07-04 14:21:45 +05303507 /* check the EXTScan Capability */
3508 if ( (TRUE != pHddCtx->cfg_ini->fEnableEXTScan) ||
Padma, Santhosh Kumar2ac54992015-10-12 18:20:58 +05303509 (TRUE != sme_IsFeatureSupportedByFW(EXTENDED_SCAN)) ||
3510 (TRUE != sme_IsFeatureSupportedByFW(EXT_SCAN_ENHANCED)))
Dino Myclee8843b32014-07-04 14:21:45 +05303511 {
3512 hddLog(VOS_TRACE_LEVEL_ERROR,
3513 FL("EXTScan not enabled/supported by Firmware"));
3514 return -EINVAL;
3515 }
3516
Dino Mycle6fb96c12014-06-10 11:52:40 +05303517 if (nla_parse(tb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX,
3518 data, dataLen,
3519 wlan_hdd_extscan_config_policy)) {
3520 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Invalid ATTR"));
3521 return -EINVAL;
3522 }
3523
3524 /* Parse and fetch request Id */
3525 if (!tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_REQUEST_ID]) {
3526 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr request id failed"));
3527 return -EINVAL;
3528 }
3529
Dino Myclee8843b32014-07-04 14:21:45 +05303530 reqMsg.requestId = nla_get_u32(
Dino Mycle6fb96c12014-06-10 11:52:40 +05303531 tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_REQUEST_ID]);
Dino Myclee8843b32014-07-04 14:21:45 +05303532 hddLog(VOS_TRACE_LEVEL_INFO, FL("Req Id (%d)"), reqMsg.requestId);
Dino Mycle6fb96c12014-06-10 11:52:40 +05303533
Dino Myclee8843b32014-07-04 14:21:45 +05303534 reqMsg.sessionId = pAdapter->sessionId;
3535 hddLog(VOS_TRACE_LEVEL_INFO, FL("Session Id (%d)"), reqMsg.sessionId);
Dino Mycle6fb96c12014-06-10 11:52:40 +05303536
Padma, Santhosh Kumara1aa4a32015-06-19 19:00:46 +05303537 vos_spin_lock_acquire(&hdd_context_lock);
3538 context = &pHddCtx->ext_scan_context;
3539 context->request_id = reqMsg.requestId;
3540 INIT_COMPLETION(context->response_event);
3541 vos_spin_lock_release(&hdd_context_lock);
3542
Dino Myclee8843b32014-07-04 14:21:45 +05303543 status = sme_EXTScanGetCapabilities(pHddCtx->hHal, &reqMsg);
Dino Mycle6fb96c12014-06-10 11:52:40 +05303544 if (!HAL_STATUS_SUCCESS(status)) {
3545 hddLog(VOS_TRACE_LEVEL_ERROR,
3546 FL("sme_EXTScanGetCapabilities failed(err=%d)"), status);
Dino Mycle6fb96c12014-06-10 11:52:40 +05303547 return -EINVAL;
3548 }
Padma, Santhosh Kumara1aa4a32015-06-19 19:00:46 +05303549
3550 rc = wait_for_completion_timeout(&context->response_event,
3551 msecs_to_jiffies(WLAN_WAIT_TIME_EXTSCAN));
3552 if (!rc) {
3553 hddLog(LOGE, FL("Target response timed out"));
3554 return -ETIMEDOUT;
3555 }
3556
3557 ret = wlan_hdd_send_ext_scan_capability(pHddCtx);
3558 if (ret)
3559 hddLog(LOGE, FL("Failed to send ext scan capability to user space"));
3560
3561 return ret;
3562
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05303563 EXIT();
Dino Mycle6fb96c12014-06-10 11:52:40 +05303564 return 0;
3565}
3566
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05303567static int wlan_hdd_cfg80211_extscan_get_capabilities(struct wiphy *wiphy,
3568 struct wireless_dev *wdev,
3569 const void *data, int dataLen)
3570{
3571 int ret = 0;
Dino Mycle6fb96c12014-06-10 11:52:40 +05303572
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05303573 vos_ssr_protect(__func__);
3574 ret = __wlan_hdd_cfg80211_extscan_get_capabilities(wiphy, wdev, data, dataLen);
3575 vos_ssr_unprotect(__func__);
3576
3577 return ret;
3578}
3579
3580static int __wlan_hdd_cfg80211_extscan_get_cached_results(struct wiphy *wiphy,
3581 struct wireless_dev *wdev,
3582 const void *data, int dataLen)
Dino Mycle6fb96c12014-06-10 11:52:40 +05303583{
Dino Myclee8843b32014-07-04 14:21:45 +05303584 tSirEXTScanGetCachedResultsReqParams reqMsg;
Dino Mycle6fb96c12014-06-10 11:52:40 +05303585 struct net_device *dev = wdev->netdev;
3586 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
3587 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
3588 struct nlattr
3589 *tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX + 1];
3590 eHalStatus status;
Padma, Santhosh Kumare1b8a942015-08-25 12:44:24 +05303591 struct hdd_ext_scan_context *context;
3592 unsigned long rc;
3593 int retval;
Dino Mycle6fb96c12014-06-10 11:52:40 +05303594
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05303595 ENTER();
3596
Padma, Santhosh Kumare1b8a942015-08-25 12:44:24 +05303597 if (VOS_FTM_MODE == hdd_get_conparam()) {
3598 hddLog(LOGE, FL("Command not allowed in FTM mode"));
3599 return -EINVAL;
3600 }
3601
Dino Mycle6fb96c12014-06-10 11:52:40 +05303602 status = wlan_hdd_validate_context(pHddCtx);
3603 if (0 != status)
3604 {
Dino Mycle6fb96c12014-06-10 11:52:40 +05303605 return -EINVAL;
3606 }
Dino Myclee8843b32014-07-04 14:21:45 +05303607 /* check the EXTScan Capability */
3608 if ( (TRUE != pHddCtx->cfg_ini->fEnableEXTScan) ||
Padma, Santhosh Kumar2ac54992015-10-12 18:20:58 +05303609 (TRUE != sme_IsFeatureSupportedByFW(EXTENDED_SCAN)) ||
3610 (TRUE != sme_IsFeatureSupportedByFW(EXT_SCAN_ENHANCED)))
Dino Myclee8843b32014-07-04 14:21:45 +05303611 {
3612 hddLog(VOS_TRACE_LEVEL_ERROR,
3613 FL("EXTScan not enabled/supported by Firmware"));
3614 return -EINVAL;
3615 }
3616
Dino Mycle6fb96c12014-06-10 11:52:40 +05303617 if (nla_parse(tb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX,
3618 data, dataLen,
3619 wlan_hdd_extscan_config_policy)) {
3620 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Invalid ATTR"));
3621 return -EINVAL;
3622 }
3623 /* Parse and fetch request Id */
3624 if (!tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_REQUEST_ID]) {
3625 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr request id failed"));
3626 return -EINVAL;
3627 }
Dino Mycle6fb96c12014-06-10 11:52:40 +05303628
Dino Myclee8843b32014-07-04 14:21:45 +05303629 reqMsg.requestId = nla_get_u32(
Dino Mycle6fb96c12014-06-10 11:52:40 +05303630 tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_REQUEST_ID]);
3631
Dino Myclee8843b32014-07-04 14:21:45 +05303632 hddLog(VOS_TRACE_LEVEL_INFO, FL("Req Id (%d)"), reqMsg.requestId);
Dino Mycle6fb96c12014-06-10 11:52:40 +05303633
Dino Myclee8843b32014-07-04 14:21:45 +05303634 reqMsg.sessionId = pAdapter->sessionId;
3635 hddLog(VOS_TRACE_LEVEL_INFO, FL("Session Id (%d)"), reqMsg.sessionId);
Dino Mycle6fb96c12014-06-10 11:52:40 +05303636
3637 /* Parse and fetch flush parameter */
3638 if (!tb
3639 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_GET_CACHED_SCAN_RESULTS_CONFIG_PARAM_FLUSH])
3640 {
3641 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr flush failed"));
3642 goto failed;
3643 }
Dino Myclee8843b32014-07-04 14:21:45 +05303644 reqMsg.flush = nla_get_u8(
Dino Mycle6fb96c12014-06-10 11:52:40 +05303645 tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_GET_CACHED_SCAN_RESULTS_CONFIG_PARAM_FLUSH]);
3646
Dino Myclee8843b32014-07-04 14:21:45 +05303647 hddLog(VOS_TRACE_LEVEL_INFO, FL("Flush (%d)"), reqMsg.flush);
Dino Mycle6fb96c12014-06-10 11:52:40 +05303648
Padma, Santhosh Kumare1b8a942015-08-25 12:44:24 +05303649 spin_lock(&hdd_context_lock);
3650 context = &pHddCtx->ext_scan_context;
3651 context->request_id = reqMsg.requestId;
3652 context->ignore_cached_results = false;
3653 INIT_COMPLETION(context->response_event);
3654 spin_unlock(&hdd_context_lock);
3655
Dino Myclee8843b32014-07-04 14:21:45 +05303656 status = sme_getCachedResults(pHddCtx->hHal, &reqMsg);
Dino Mycle6fb96c12014-06-10 11:52:40 +05303657 if (!HAL_STATUS_SUCCESS(status)) {
3658 hddLog(VOS_TRACE_LEVEL_ERROR,
3659 FL("sme_getCachedResults failed(err=%d)"), status);
Dino Mycle6fb96c12014-06-10 11:52:40 +05303660 return -EINVAL;
3661 }
Padma, Santhosh Kumare1b8a942015-08-25 12:44:24 +05303662
3663 rc = wait_for_completion_timeout(&context->response_event,
3664 msecs_to_jiffies(WLAN_WAIT_TIME_EXTSCAN));
3665 if (!rc) {
3666 hddLog(LOGE, FL("Target response timed out"));
3667 retval = -ETIMEDOUT;
3668 spin_lock(&hdd_context_lock);
3669 context->ignore_cached_results = true;
3670 spin_unlock(&hdd_context_lock);
3671 } else {
3672 spin_lock(&hdd_context_lock);
3673 retval = context->response_status;
3674 spin_unlock(&hdd_context_lock);
3675 }
3676
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05303677 EXIT();
Padma, Santhosh Kumare1b8a942015-08-25 12:44:24 +05303678 return retval;
Dino Mycle6fb96c12014-06-10 11:52:40 +05303679
3680failed:
Dino Mycle6fb96c12014-06-10 11:52:40 +05303681 return -EINVAL;
3682}
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05303683static int wlan_hdd_cfg80211_extscan_get_cached_results(struct wiphy *wiphy,
3684 struct wireless_dev *wdev,
3685 const void *data, int dataLen)
3686{
3687 int ret = 0;
Dino Mycle6fb96c12014-06-10 11:52:40 +05303688
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05303689 vos_ssr_protect(__func__);
3690 ret = __wlan_hdd_cfg80211_extscan_get_cached_results(wiphy, wdev, data, dataLen);
3691 vos_ssr_unprotect(__func__);
3692
3693 return ret;
3694}
3695
3696static int __wlan_hdd_cfg80211_extscan_set_bssid_hotlist(struct wiphy *wiphy,
Dino Mycle6fb96c12014-06-10 11:52:40 +05303697 struct wireless_dev *wdev,
Edhar, Mahesh Kumared8631f2015-01-20 14:31:47 +05303698 const void *data, int dataLen)
Dino Mycle6fb96c12014-06-10 11:52:40 +05303699{
3700 tpSirEXTScanSetBssidHotListReqParams pReqMsg = NULL;
3701 struct net_device *dev = wdev->netdev;
3702 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
3703 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
3704 struct nlattr
3705 *tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX + 1];
3706 struct nlattr
3707 *tb2[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX + 1];
3708 struct nlattr *apTh;
3709 eHalStatus status;
3710 tANI_U8 i = 0;
3711 int rem;
Padma, Santhosh Kumar37f4fd12015-08-19 14:37:37 +05303712 struct hdd_ext_scan_context *context;
3713 tANI_U32 request_id;
3714 unsigned long rc;
3715 int retval;
Dino Mycle6fb96c12014-06-10 11:52:40 +05303716
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05303717 ENTER();
3718
Padma, Santhosh Kumar37f4fd12015-08-19 14:37:37 +05303719 if (VOS_FTM_MODE == hdd_get_conparam()) {
3720 hddLog(LOGE, FL("Command not allowed in FTM mode"));
3721 return -EINVAL;
3722 }
3723
Dino Mycle6fb96c12014-06-10 11:52:40 +05303724 status = wlan_hdd_validate_context(pHddCtx);
3725 if (0 != status)
3726 {
Dino Mycle6fb96c12014-06-10 11:52:40 +05303727 return -EINVAL;
3728 }
Dino Myclee8843b32014-07-04 14:21:45 +05303729 /* check the EXTScan Capability */
3730 if ( (TRUE != pHddCtx->cfg_ini->fEnableEXTScan) ||
Padma, Santhosh Kumar2ac54992015-10-12 18:20:58 +05303731 (TRUE != sme_IsFeatureSupportedByFW(EXTENDED_SCAN)) ||
3732 (TRUE != sme_IsFeatureSupportedByFW(EXT_SCAN_ENHANCED)))
Dino Myclee8843b32014-07-04 14:21:45 +05303733 {
3734 hddLog(VOS_TRACE_LEVEL_ERROR,
3735 FL("EXTScan not enabled/supported by Firmware"));
3736 return -EINVAL;
3737 }
3738
Dino Mycle6fb96c12014-06-10 11:52:40 +05303739 if (nla_parse(tb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX,
3740 data, dataLen,
3741 wlan_hdd_extscan_config_policy)) {
3742 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Invalid ATTR"));
3743 return -EINVAL;
3744 }
3745
3746 /* Parse and fetch request Id */
3747 if (!tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_REQUEST_ID]) {
3748 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr request id failed"));
3749 return -EINVAL;
3750 }
Dino Mycle6fb96c12014-06-10 11:52:40 +05303751 pReqMsg = (tpSirEXTScanSetBssidHotListReqParams)
3752 vos_mem_malloc(sizeof(*pReqMsg));
3753 if (!pReqMsg) {
3754 hddLog(VOS_TRACE_LEVEL_ERROR, FL("vos_mem_malloc failed"));
3755 return -ENOMEM;
3756 }
3757
Dino Myclee8843b32014-07-04 14:21:45 +05303758
Dino Mycle6fb96c12014-06-10 11:52:40 +05303759 pReqMsg->requestId = nla_get_u32(
3760 tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_REQUEST_ID]);
3761 hddLog(VOS_TRACE_LEVEL_INFO, FL("Req Id (%d)"), pReqMsg->requestId);
3762
3763 /* Parse and fetch number of APs */
3764 if (!tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_BSSID_HOTLIST_PARAMS_NUM_AP]) {
3765 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr number of AP failed"));
3766 goto fail;
3767 }
3768
Padma, Santhosh Kumar37f4fd12015-08-19 14:37:37 +05303769 /* Parse and fetch lost ap sample size */
3770 if (!tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_BSSID_HOTLIST_PARAMS_LOST_AP_SAMPLE_SIZE]) {
3771 hddLog(LOGE, FL("attr lost ap sample size failed"));
3772 goto fail;
3773 }
3774
3775 pReqMsg->lostBssidSampleSize = nla_get_u32(
3776 tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_BSSID_HOTLIST_PARAMS_LOST_AP_SAMPLE_SIZE]);
3777 hddLog(LOG1, FL("Lost ap sample size %d"), pReqMsg->lostBssidSampleSize);
3778
Dino Mycle6fb96c12014-06-10 11:52:40 +05303779 pReqMsg->sessionId = pAdapter->sessionId;
3780 hddLog(VOS_TRACE_LEVEL_INFO, FL("Session Id (%d)"), pReqMsg->sessionId);
3781
Padma, Santhosh Kumar37f4fd12015-08-19 14:37:37 +05303782 pReqMsg->numBssid = nla_get_u32(
Dino Mycle6fb96c12014-06-10 11:52:40 +05303783 tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_BSSID_HOTLIST_PARAMS_NUM_AP]);
Padma, Santhosh Kumar37f4fd12015-08-19 14:37:37 +05303784 hddLog(VOS_TRACE_LEVEL_INFO, FL("Number of AP (%d)"), pReqMsg->numBssid);
Dino Mycle6fb96c12014-06-10 11:52:40 +05303785
3786 nla_for_each_nested(apTh,
3787 tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_AP_THRESHOLD_PARAM], rem) {
3788 if(nla_parse(tb2, QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX,
3789 nla_data(apTh), nla_len(apTh),
3790 NULL)) {
3791 hddLog(VOS_TRACE_LEVEL_ERROR, FL("nla_parse failed"));
3792 goto fail;
3793 }
3794
3795 /* Parse and fetch MAC address */
3796 if (!tb2[QCA_WLAN_VENDOR_ATTR_EXTSCAN_AP_THRESHOLD_PARAM_BSSID]) {
3797 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr mac address failed"));
3798 goto fail;
3799 }
3800 memcpy(pReqMsg->ap[i].bssid, nla_data(
3801 tb2[QCA_WLAN_VENDOR_ATTR_EXTSCAN_AP_THRESHOLD_PARAM_BSSID]),
3802 sizeof(tSirMacAddr));
3803 hddLog(VOS_TRACE_LEVEL_INFO, FL("BSSID: %pM "), pReqMsg->ap[i].bssid);
3804
3805 /* Parse and fetch low RSSI */
3806 if (!tb2[QCA_WLAN_VENDOR_ATTR_EXTSCAN_AP_THRESHOLD_PARAM_RSSI_LOW]) {
3807 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr low RSSI failed"));
3808 goto fail;
3809 }
3810 pReqMsg->ap[i].low = nla_get_s32(
3811 tb2[QCA_WLAN_VENDOR_ATTR_EXTSCAN_AP_THRESHOLD_PARAM_RSSI_LOW]);
3812 hddLog(VOS_TRACE_LEVEL_INFO, FL("RSSI low (%d)"), pReqMsg->ap[i].low);
3813
3814 /* Parse and fetch high RSSI */
3815 if (!tb2[QCA_WLAN_VENDOR_ATTR_EXTSCAN_AP_THRESHOLD_PARAM_RSSI_HIGH]) {
3816 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr high RSSI failed"));
3817 goto fail;
3818 }
3819 pReqMsg->ap[i].high = nla_get_s32(
3820 tb2[QCA_WLAN_VENDOR_ATTR_EXTSCAN_AP_THRESHOLD_PARAM_RSSI_HIGH]);
3821 hddLog(VOS_TRACE_LEVEL_INFO, FL("RSSI High (%d)"),
3822 pReqMsg->ap[i].high);
Dino Mycle6fb96c12014-06-10 11:52:40 +05303823 i++;
3824 }
Padma, Santhosh Kumar37f4fd12015-08-19 14:37:37 +05303825
3826 context = &pHddCtx->ext_scan_context;
3827 spin_lock(&hdd_context_lock);
3828 INIT_COMPLETION(context->response_event);
3829 context->request_id = request_id = pReqMsg->requestId;
3830 spin_unlock(&hdd_context_lock);
3831
Dino Mycle6fb96c12014-06-10 11:52:40 +05303832 status = sme_SetBssHotlist(pHddCtx->hHal, pReqMsg);
3833 if (!HAL_STATUS_SUCCESS(status)) {
3834 hddLog(VOS_TRACE_LEVEL_ERROR,
3835 FL("sme_SetBssHotlist failed(err=%d)"), status);
3836 vos_mem_free(pReqMsg);
3837 return -EINVAL;
3838 }
3839
Padma, Santhosh Kumar37f4fd12015-08-19 14:37:37 +05303840 /* request was sent -- wait for the response */
3841 rc = wait_for_completion_timeout(&context->response_event,
3842 msecs_to_jiffies(WLAN_WAIT_TIME_EXTSCAN));
3843
3844 if (!rc) {
3845 hddLog(LOGE, FL("sme_SetBssHotlist timed out"));
3846 retval = -ETIMEDOUT;
3847 } else {
3848 spin_lock(&hdd_context_lock);
3849 if (context->request_id == request_id)
3850 retval = context->response_status;
3851 else
3852 retval = -EINVAL;
3853 spin_unlock(&hdd_context_lock);
3854 }
3855
Dino Myclee8843b32014-07-04 14:21:45 +05303856 vos_mem_free(pReqMsg);
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05303857 EXIT();
Padma, Santhosh Kumar37f4fd12015-08-19 14:37:37 +05303858 return retval;
Dino Mycle6fb96c12014-06-10 11:52:40 +05303859
3860fail:
3861 vos_mem_free(pReqMsg);
3862 return -EINVAL;
3863}
3864
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05303865static int wlan_hdd_cfg80211_extscan_set_bssid_hotlist(struct wiphy *wiphy,
3866 struct wireless_dev *wdev,
3867 const void *data, int dataLen)
3868{
3869 int ret = 0;
3870
3871 vos_ssr_protect(__func__);
3872 ret = __wlan_hdd_cfg80211_extscan_set_bssid_hotlist(wiphy, wdev, data,
3873 dataLen);
3874 vos_ssr_unprotect(__func__);
3875
3876 return ret;
3877}
3878
Padma, Santhosh Kumar9acee012015-08-21 19:58:01 +05303879/*
3880 * define short names for the global vendor params
3881 * used by wlan_hdd_cfg80211_extscan_set_ssid_hotlist()
3882 */
3883#define PARAM_MAX \
3884QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX
3885#define PARAM_REQUEST_ID \
3886QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_REQUEST_ID
3887#define PARAMS_LOST_SSID_SAMPLE_SIZE \
3888QCA_WLAN_VENDOR_ATTR_EXTSCAN_SSID_HOTLIST_PARAMS_LOST_SSID_SAMPLE_SIZE
3889#define PARAMS_NUM_SSID \
3890QCA_WLAN_VENDOR_ATTR_EXTSCAN_SSID_HOTLIST_PARAMS_NUM_SSID
3891#define THRESHOLD_PARAM \
3892QCA_WLAN_VENDOR_ATTR_EXTSCAN_SSID_THRESHOLD_PARAM
3893#define PARAM_SSID \
3894QCA_WLAN_VENDOR_ATTR_EXTSCAN_SSID_THRESHOLD_PARAM_SSID
3895#define PARAM_BAND \
3896QCA_WLAN_VENDOR_ATTR_EXTSCAN_SSID_THRESHOLD_PARAM_BAND
3897#define PARAM_RSSI_LOW \
3898QCA_WLAN_VENDOR_ATTR_EXTSCAN_SSID_THRESHOLD_PARAM_RSSI_LOW
3899#define PARAM_RSSI_HIGH \
3900QCA_WLAN_VENDOR_ATTR_EXTSCAN_SSID_THRESHOLD_PARAM_RSSI_HIGH
3901
3902/**
3903 * __wlan_hdd_cfg80211_extscan_set_ssid_hotlist() - set ssid hot list
3904 * @wiphy: Pointer to wireless phy
3905 * @wdev: Pointer to wireless device
3906 * @data: Pointer to data
3907 * @data_len: Data length
3908 *
3909 * Return: 0 on success, negative errno on failure
3910 */
3911static int
3912__wlan_hdd_cfg80211_extscan_set_ssid_hotlist(struct wiphy *wiphy,
3913 struct wireless_dev *wdev,
3914 const void *data,
3915 int data_len)
3916{
3917 tSirEXTScanSetSsidHotListReqParams *request;
3918 struct net_device *dev = wdev->netdev;
3919 hdd_adapter_t *adapter = WLAN_HDD_GET_PRIV_PTR(dev);
3920 hdd_context_t *hdd_ctx = wiphy_priv(wiphy);
3921 struct nlattr *tb[PARAM_MAX + 1];
3922 struct nlattr *tb2[PARAM_MAX + 1];
3923 struct nlattr *ssids;
3924 struct hdd_ext_scan_context *context;
3925 uint32_t request_id;
3926 char ssid_string[SIR_MAC_MAX_SSID_LENGTH + 1] = {'\0'};
3927 int ssid_len;
3928 eHalStatus status;
3929 int i, rem, retval;
3930 unsigned long rc;
3931
3932 ENTER();
3933
3934 if (VOS_FTM_MODE == hdd_get_conparam()) {
3935 hddLog(LOGE, FL("Command not allowed in FTM mode"));
3936 return -EINVAL;
3937 }
3938
3939 retval = wlan_hdd_validate_context(hdd_ctx);
3940 if (0 != retval) {
3941 hddLog(LOGE, FL("HDD context is not valid"));
3942 return -EINVAL;
3943 }
3944
3945 /* check the EXTScan Capability */
3946 if ( (TRUE != hdd_ctx->cfg_ini->fEnableEXTScan) ||
Padma, Santhosh Kumar2ac54992015-10-12 18:20:58 +05303947 (TRUE != sme_IsFeatureSupportedByFW(EXTENDED_SCAN)) ||
3948 (TRUE != sme_IsFeatureSupportedByFW(EXT_SCAN_ENHANCED)))
Padma, Santhosh Kumar9acee012015-08-21 19:58:01 +05303949 {
3950 hddLog(VOS_TRACE_LEVEL_ERROR,
3951 FL("EXTScan not enabled/supported by Firmware"));
3952 return -EINVAL;
3953 }
3954
3955 if (nla_parse(tb, PARAM_MAX,
3956 data, data_len,
3957 wlan_hdd_extscan_config_policy)) {
3958 hddLog(LOGE, FL("Invalid ATTR"));
3959 return -EINVAL;
3960 }
3961
3962 request = vos_mem_malloc(sizeof(*request));
3963 if (!request) {
3964 hddLog(LOGE, FL("vos_mem_malloc failed"));
3965 return -ENOMEM;
3966 }
3967
3968 /* Parse and fetch request Id */
3969 if (!tb[PARAM_REQUEST_ID]) {
3970 hddLog(LOGE, FL("attr request id failed"));
3971 goto fail;
3972 }
3973
3974 request->request_id = nla_get_u32(tb[PARAM_REQUEST_ID]);
3975 hddLog(LOG1, FL("Request Id %d"), request->request_id);
3976
3977 /* Parse and fetch lost SSID sample size */
3978 if (!tb[PARAMS_LOST_SSID_SAMPLE_SIZE]) {
3979 hddLog(LOGE, FL("attr number of Ssid failed"));
3980 goto fail;
3981 }
3982 request->lost_ssid_sample_size =
3983 nla_get_u32(tb[PARAMS_LOST_SSID_SAMPLE_SIZE]);
3984 hddLog(LOG1, FL("Lost SSID Sample Size %d"),
3985 request->lost_ssid_sample_size);
3986
3987 /* Parse and fetch number of hotlist SSID */
3988 if (!tb[PARAMS_NUM_SSID]) {
3989 hddLog(LOGE, FL("attr number of Ssid failed"));
3990 goto fail;
3991 }
3992 request->ssid_count = nla_get_u32(tb[PARAMS_NUM_SSID]);
3993 hddLog(LOG1, FL("Number of SSID %d"), request->ssid_count);
3994
3995 request->session_id = adapter->sessionId;
3996 hddLog(LOG1, FL("Session Id (%d)"), request->session_id);
3997
3998 i = 0;
3999 nla_for_each_nested(ssids, tb[THRESHOLD_PARAM], rem) {
4000 if (i >= WLAN_EXTSCAN_MAX_HOTLIST_SSIDS) {
4001 hddLog(LOGE,
4002 FL("Too Many SSIDs, %d exceeds %d"),
4003 i, WLAN_EXTSCAN_MAX_HOTLIST_SSIDS);
4004 break;
4005 }
4006 if (nla_parse(tb2, PARAM_MAX,
4007 nla_data(ssids), nla_len(ssids),
4008 wlan_hdd_extscan_config_policy)) {
4009 hddLog(LOGE, FL("nla_parse failed"));
4010 goto fail;
4011 }
4012
4013 /* Parse and fetch SSID */
4014 if (!tb2[PARAM_SSID]) {
4015 hddLog(LOGE, FL("attr ssid failed"));
4016 goto fail;
4017 }
4018 nla_memcpy(ssid_string,
4019 tb2[PARAM_SSID],
4020 sizeof(ssid_string));
4021 hddLog(LOG1, FL("SSID %s"),
4022 ssid_string);
4023 ssid_len = strlen(ssid_string);
4024 memcpy(request->ssid[i].ssid.ssId, ssid_string, ssid_len);
4025 request->ssid[i].ssid.length = ssid_len;
4026 request->ssid[i].ssid.ssId[ssid_len] = '\0';
4027 hddLog(LOG1, FL("After copying SSID %s"),
4028 request->ssid[i].ssid.ssId);
4029 hddLog(LOG1, FL("After copying length: %d"),
4030 ssid_len);
4031
4032 /* Parse and fetch low RSSI */
4033 if (!tb2[PARAM_BAND]) {
4034 hddLog(LOGE, FL("attr band failed"));
4035 goto fail;
4036 }
4037 request->ssid[i].band = nla_get_u8(tb2[PARAM_BAND]);
4038 hddLog(LOG1, FL("band %d"), request->ssid[i].band);
4039
4040 /* Parse and fetch low RSSI */
4041 if (!tb2[PARAM_RSSI_LOW]) {
4042 hddLog(LOGE, FL("attr low RSSI failed"));
4043 goto fail;
4044 }
4045 request->ssid[i].rssi_low = nla_get_s32(tb2[PARAM_RSSI_LOW]);
4046 hddLog(LOG1, FL("RSSI low %d"), request->ssid[i].rssi_low);
4047
4048 /* Parse and fetch high RSSI */
4049 if (!tb2[PARAM_RSSI_HIGH]) {
4050 hddLog(LOGE, FL("attr high RSSI failed"));
4051 goto fail;
4052 }
4053 request->ssid[i].rssi_high = nla_get_u32(tb2[PARAM_RSSI_HIGH]);
4054 hddLog(LOG1, FL("RSSI high %d"), request->ssid[i].rssi_high);
4055 i++;
4056 }
4057
4058 context = &hdd_ctx->ext_scan_context;
4059 spin_lock(&hdd_context_lock);
4060 INIT_COMPLETION(context->response_event);
4061 context->request_id = request_id = request->request_id;
4062 spin_unlock(&hdd_context_lock);
4063
4064 status = sme_set_ssid_hotlist(hdd_ctx->hHal, request);
4065 if (!HAL_STATUS_SUCCESS(status)) {
4066 hddLog(LOGE,
4067 FL("sme_set_ssid_hotlist failed(err=%d)"), status);
4068 goto fail;
4069 }
4070
4071 vos_mem_free(request);
4072
4073 /* request was sent -- wait for the response */
4074 rc = wait_for_completion_timeout(&context->response_event,
4075 msecs_to_jiffies
4076 (WLAN_WAIT_TIME_EXTSCAN));
4077 if (!rc) {
4078 hddLog(LOGE, FL("sme_set_ssid_hotlist timed out"));
4079 retval = -ETIMEDOUT;
4080 } else {
4081 spin_lock(&hdd_context_lock);
4082 if (context->request_id == request_id)
4083 retval = context->response_status;
4084 else
4085 retval = -EINVAL;
4086 spin_unlock(&hdd_context_lock);
4087 }
4088
4089 return retval;
4090
4091fail:
4092 vos_mem_free(request);
4093 return -EINVAL;
4094}
4095
4096/*
4097 * done with short names for the global vendor params
4098 * used by wlan_hdd_cfg80211_extscan_set_ssid_hotlist()
4099 */
4100#undef PARAM_MAX
4101#undef PARAM_REQUEST_ID
4102#undef PARAMS_NUM_SSID
4103#undef THRESHOLD_PARAM
4104#undef PARAM_SSID
4105#undef PARAM_BAND
4106#undef PARAM_RSSI_LOW
4107#undef PARAM_RSSI_HIGH
4108
4109static int wlan_hdd_cfg80211_extscan_set_ssid_hotlist(struct wiphy *wiphy,
4110 struct wireless_dev *wdev,
4111 const void *data, int dataLen)
4112{
4113 int ret = 0;
4114
4115 vos_ssr_protect(__func__);
4116 ret = __wlan_hdd_cfg80211_extscan_set_ssid_hotlist(wiphy, wdev, data,
4117 dataLen);
4118 vos_ssr_unprotect(__func__);
4119
4120 return ret;
4121}
4122
4123static int
4124__wlan_hdd_cfg80211_extscan_reset_ssid_hotlist(struct wiphy *wiphy,
4125 struct wireless_dev *wdev,
4126 const void *data,
4127 int data_len)
4128{
4129 tSirEXTScanResetSsidHotlistReqParams request;
4130 struct net_device *dev = wdev->netdev;
4131 hdd_adapter_t *adapter = WLAN_HDD_GET_PRIV_PTR(dev);
4132 hdd_context_t *hdd_ctx = wiphy_priv(wiphy);
4133 struct nlattr *tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX + 1];
4134 struct hdd_ext_scan_context *context;
4135 uint32_t request_id;
4136 eHalStatus status;
4137 int retval;
4138 unsigned long rc;
4139
4140 ENTER();
4141
4142 if (VOS_FTM_MODE == hdd_get_conparam()) {
4143 hddLog(LOGE, FL("Command not allowed in FTM mode"));
4144 return -EINVAL;
4145 }
4146
4147 retval = wlan_hdd_validate_context(hdd_ctx);
4148 if (0 != retval) {
4149 hddLog(LOGE, FL("HDD context is not valid"));
4150 return -EINVAL;
4151 }
4152
4153 /* check the EXTScan Capability */
4154 if ( (TRUE != hdd_ctx->cfg_ini->fEnableEXTScan) ||
Padma, Santhosh Kumar2ac54992015-10-12 18:20:58 +05304155 (TRUE != sme_IsFeatureSupportedByFW(EXTENDED_SCAN)) ||
4156 (TRUE != sme_IsFeatureSupportedByFW(EXT_SCAN_ENHANCED)))
Padma, Santhosh Kumar9acee012015-08-21 19:58:01 +05304157 {
4158 hddLog(LOGE,
4159 FL("EXTScan not enabled/supported by Firmware"));
4160 return -EINVAL;
4161 }
4162
4163 if (nla_parse(tb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX,
4164 data, data_len,
4165 wlan_hdd_extscan_config_policy)) {
4166 hddLog(LOGE, FL("Invalid ATTR"));
4167 return -EINVAL;
4168 }
4169
4170 /* Parse and fetch request Id */
4171 if (!tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_REQUEST_ID]) {
4172 hddLog(LOGE, FL("attr request id failed"));
4173 return -EINVAL;
4174 }
4175
4176 request.requestId = nla_get_u32(
4177 tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_REQUEST_ID]);
4178 request.sessionId = adapter->sessionId;
4179 hddLog(LOG1, FL("Request Id %d Session Id %d"), request.requestId,
4180 request.sessionId);
4181
4182 context = &hdd_ctx->ext_scan_context;
4183 spin_lock(&hdd_context_lock);
4184 INIT_COMPLETION(context->response_event);
4185 context->request_id = request_id = request.requestId;
4186 spin_unlock(&hdd_context_lock);
4187
4188 status = sme_reset_ssid_hotlist(hdd_ctx->hHal, &request);
4189 if (!HAL_STATUS_SUCCESS(status)) {
4190 hddLog(LOGE,
4191 FL("sme_reset_ssid_hotlist failed(err=%d)"), status);
4192 return -EINVAL;
4193 }
4194
4195 /* request was sent -- wait for the response */
4196 rc = wait_for_completion_timeout(&context->response_event,
4197 msecs_to_jiffies
4198 (WLAN_WAIT_TIME_EXTSCAN));
4199 if (!rc) {
4200 hddLog(LOGE, FL("sme_reset_ssid_hotlist timed out"));
4201 retval = -ETIMEDOUT;
4202 } else {
4203 spin_lock(&hdd_context_lock);
4204 if (context->request_id == request_id)
4205 retval = context->response_status;
4206 else
4207 retval = -EINVAL;
4208 spin_unlock(&hdd_context_lock);
4209 }
4210
4211 return retval;
4212}
4213
4214static int
4215wlan_hdd_cfg80211_extscan_reset_ssid_hotlist(struct wiphy *wiphy,
4216 struct wireless_dev *wdev,
4217 const void *data,
4218 int data_len)
4219{
4220 int ret;
4221
4222 vos_ssr_protect(__func__);
4223 ret = __wlan_hdd_cfg80211_extscan_reset_ssid_hotlist(wiphy, wdev,
4224 data, data_len);
4225 vos_ssr_unprotect(__func__);
4226
4227 return ret;
4228}
4229
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05304230static int __wlan_hdd_cfg80211_extscan_get_valid_channels(struct wiphy *wiphy,
Dino Mycle6fb96c12014-06-10 11:52:40 +05304231 struct wireless_dev *wdev,
Jeff Johnson393c2702014-12-16 11:09:35 +05304232 const void *data, int dataLen)
Dino Mycle6fb96c12014-06-10 11:52:40 +05304233{
4234 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
4235 tANI_U32 ChannelList[WNI_CFG_VALID_CHANNEL_LIST_LEN] = {0};
4236 tANI_U8 numChannels = 0;
4237 struct nlattr *tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX + 1];
Padma, Santhosh Kumar387aa9c2015-06-19 15:39:37 +05304238 tANI_U32 requestId, maxChannels;
Dino Mycle6fb96c12014-06-10 11:52:40 +05304239 tWifiBand wifiBand;
4240 eHalStatus status;
4241 struct sk_buff *replySkb;
4242 tANI_U8 i;
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05304243 int ret;
Dino Mycle6fb96c12014-06-10 11:52:40 +05304244
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05304245 ENTER();
4246
Dino Mycle6fb96c12014-06-10 11:52:40 +05304247 status = wlan_hdd_validate_context(pHddCtx);
4248 if (0 != status)
4249 {
Dino Mycle6fb96c12014-06-10 11:52:40 +05304250 return -EINVAL;
4251 }
Dino Myclee8843b32014-07-04 14:21:45 +05304252
Dino Mycle6fb96c12014-06-10 11:52:40 +05304253 if (nla_parse(tb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX,
4254 data, dataLen,
4255 wlan_hdd_extscan_config_policy)) {
4256 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Invalid ATTR"));
4257 return -EINVAL;
4258 }
4259
4260 /* Parse and fetch request Id */
4261 if (!tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_REQUEST_ID]) {
4262 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr request id failed"));
4263 return -EINVAL;
4264 }
4265 requestId = nla_get_u32(
4266 tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_REQUEST_ID]);
4267 hddLog(VOS_TRACE_LEVEL_INFO, FL("Req Id (%d)"), requestId);
4268
4269 /* Parse and fetch wifi band */
4270 if (!tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_GET_VALID_CHANNELS_CONFIG_PARAM_WIFI_BAND])
4271 {
4272 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr wifi band failed"));
4273 return -EINVAL;
4274 }
4275 wifiBand = nla_get_u32(
4276 tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_GET_VALID_CHANNELS_CONFIG_PARAM_WIFI_BAND]);
4277 hddLog(VOS_TRACE_LEVEL_INFO, FL("Wifi band (%d)"), wifiBand);
4278
Padma, Santhosh Kumar387aa9c2015-06-19 15:39:37 +05304279 /* Parse and fetch max channels */
4280 if (!tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_GET_VALID_CHANNELS_CONFIG_PARAM_MAX_CHANNELS])
4281 {
4282 hddLog(LOGE, FL("attr max channels failed"));
4283 return -EINVAL;
4284 }
4285 maxChannels = nla_get_u32(
4286 tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_GET_VALID_CHANNELS_CONFIG_PARAM_MAX_CHANNELS]);
4287 hddLog(VOS_TRACE_LEVEL_INFO, FL("Max channels %d"), maxChannels);
4288
Dino Mycle6fb96c12014-06-10 11:52:40 +05304289 status = sme_GetValidChannelsByBand((tHalHandle)(pHddCtx->hHal),
4290 wifiBand, ChannelList,
4291 &numChannels);
4292 if (eHAL_STATUS_SUCCESS != status) {
4293 hddLog(VOS_TRACE_LEVEL_ERROR,
4294 FL("sme_GetValidChannelsByBand failed (err=%d)"), status);
4295 return -EINVAL;
4296 }
Padma, Santhosh Kumar387aa9c2015-06-19 15:39:37 +05304297
4298 numChannels = VOS_MIN(numChannels, maxChannels);
Dino Mycle6fb96c12014-06-10 11:52:40 +05304299 hddLog(VOS_TRACE_LEVEL_INFO, FL("Number of channels (%d)"), numChannels);
Padma, Santhosh Kumar387aa9c2015-06-19 15:39:37 +05304300
Dino Mycle6fb96c12014-06-10 11:52:40 +05304301 for (i = 0; i < numChannels; i++)
4302 hddLog(VOS_TRACE_LEVEL_INFO, "Channel: %u ", ChannelList[i]);
4303
4304 replySkb = cfg80211_vendor_cmd_alloc_reply_skb(wiphy, sizeof(u32) +
4305 sizeof(u32) * numChannels +
4306 NLMSG_HDRLEN);
4307
4308 if (!replySkb) {
4309 hddLog(VOS_TRACE_LEVEL_ERROR,
4310 FL("valid channels: buffer alloc fail"));
4311 return -EINVAL;
4312 }
4313 if (nla_put_u32(replySkb,
4314 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_NUM_CHANNELS,
4315 numChannels) ||
4316 nla_put(replySkb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_CHANNELS,
4317 sizeof(u32) * numChannels, ChannelList)) {
4318
4319 hddLog(VOS_TRACE_LEVEL_ERROR, FL("nla put fail"));
4320 kfree_skb(replySkb);
4321 return -EINVAL;
4322 }
4323
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05304324 ret = cfg80211_vendor_cmd_reply(replySkb);
4325
4326 EXIT();
4327 return ret;
Dino Mycle6fb96c12014-06-10 11:52:40 +05304328}
4329
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05304330static int wlan_hdd_cfg80211_extscan_get_valid_channels(struct wiphy *wiphy,
4331 struct wireless_dev *wdev,
4332 const void *data, int dataLen)
4333{
4334 int ret = 0;
4335
4336 vos_ssr_protect(__func__);
4337 ret = __wlan_hdd_cfg80211_extscan_get_valid_channels(wiphy, wdev, data,
4338 dataLen);
4339 vos_ssr_unprotect(__func__);
4340
4341 return ret;
4342}
4343
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05304344static int hdd_extscan_start_fill_bucket_channel_spec(
4345 hdd_context_t *pHddCtx,
4346 tpSirEXTScanStartReqParams pReqMsg,
4347 struct nlattr **tb)
4348{
4349 struct nlattr *bucket[
4350 QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX + 1];
4351 struct nlattr *channel[
4352 QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX + 1];
4353 struct nlattr *buckets;
4354 struct nlattr *channels;
4355 int rem1, rem2;
4356 eHalStatus status;
4357 tANI_U8 bktIndex, j, numChannels;
4358 tANI_U32 chanList[WNI_CFG_VALID_CHANNEL_LIST_LEN] = {0};
4359 tANI_U32 passive_max_chn_time, active_max_chn_time;
4360
4361 bktIndex = 0;
4362
4363 nla_for_each_nested(buckets,
4364 tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC], rem1) {
4365 if (nla_parse(bucket,
4366 QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX,
4367 nla_data(buckets), nla_len(buckets), NULL)) {
4368 hddLog(LOGE, FL("nla_parse failed"));
4369 return -EINVAL;
4370 }
4371
4372 /* Parse and fetch bucket spec */
4373 if (!bucket[QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_INDEX]) {
4374 hddLog(LOGE, FL("attr bucket index failed"));
4375 return -EINVAL;
4376 }
4377 pReqMsg->buckets[bktIndex].bucket = nla_get_u8(
4378 bucket[QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_INDEX]);
4379 hddLog(LOG1, FL("Bucket spec Index %d"),
4380 pReqMsg->buckets[bktIndex].bucket);
4381
4382 /* Parse and fetch wifi band */
4383 if (!bucket[QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_BAND]) {
4384 hddLog(LOGE, FL("attr wifi band failed"));
4385 return -EINVAL;
4386 }
4387 pReqMsg->buckets[bktIndex].band = nla_get_u8(
4388 bucket[QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_BAND]);
4389 hddLog(LOG1, FL("Wifi band %d"),
4390 pReqMsg->buckets[bktIndex].band);
4391
4392 /* Parse and fetch period */
4393 if (!bucket[QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_PERIOD]) {
4394 hddLog(LOGE, FL("attr period failed"));
4395 return -EINVAL;
4396 }
4397 pReqMsg->buckets[bktIndex].period = nla_get_u32(
4398 bucket[QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_PERIOD]);
4399 hddLog(LOG1, FL("period %d"),
4400 pReqMsg->buckets[bktIndex].period);
4401
4402 /* Parse and fetch report events */
4403 if (!bucket[
4404 QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_REPORT_EVENTS]) {
4405 hddLog(LOGE, FL("attr report events failed"));
4406 return -EINVAL;
4407 }
4408 pReqMsg->buckets[bktIndex].reportEvents = nla_get_u8(
4409 bucket[
4410 QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_REPORT_EVENTS]);
4411 hddLog(LOG1, FL("report events %d"),
4412 pReqMsg->buckets[bktIndex].reportEvents);
4413
4414 /* Parse and fetch max period */
4415 if (!bucket[QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_MAX_PERIOD]) {
4416 hddLog(LOGE, FL("attr max period failed"));
4417 return -EINVAL;
4418 }
4419 pReqMsg->buckets[bktIndex].max_period = nla_get_u32(
4420 bucket[QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_MAX_PERIOD]);
4421 hddLog(LOG1, FL("max period %u"),
4422 pReqMsg->buckets[bktIndex].max_period);
4423
4424 /* Parse and fetch exponent */
4425 if (!bucket[QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_EXPONENT]) {
4426 hddLog(LOGE, FL("attr exponent failed"));
4427 return -EINVAL;
4428 }
4429 pReqMsg->buckets[bktIndex].exponent = nla_get_u32(
4430 bucket[QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_EXPONENT]);
4431 hddLog(LOG1, FL("exponent %u"),
4432 pReqMsg->buckets[bktIndex].exponent);
4433
4434 /* Parse and fetch step count */
4435 if (!bucket[QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_STEP_COUNT]) {
4436 hddLog(LOGE, FL("attr step count failed"));
4437 return -EINVAL;
4438 }
4439 pReqMsg->buckets[bktIndex].step_count = nla_get_u32(
4440 bucket[QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_STEP_COUNT]);
4441 hddLog(LOG1, FL("Step count %u"),
4442 pReqMsg->buckets[bktIndex].step_count);
4443
4444 ccmCfgGetInt(pHddCtx->hHal, WNI_CFG_PASSIVE_MAXIMUM_CHANNEL_TIME, &passive_max_chn_time);
4445 ccmCfgGetInt(pHddCtx->hHal, WNI_CFG_PASSIVE_MAXIMUM_CHANNEL_TIME, &active_max_chn_time);
4446
4447 /* Framework shall pass the channel list if the input WiFi band is
4448 * WIFI_BAND_UNSPECIFIED.
4449 * If the input WiFi band is specified (any value other than
4450 * WIFI_BAND_UNSPECIFIED) then driver populates the channel list
4451 */
4452 if (pReqMsg->buckets[bktIndex].band != WIFI_BAND_UNSPECIFIED) {
4453 numChannels = 0;
4454 hddLog(LOG1, "WiFi band is specified, driver to fill channel list");
4455 status = sme_GetValidChannelsByBand(pHddCtx->hHal,
4456 pReqMsg->buckets[bktIndex].band,
4457 chanList, &numChannels);
4458 if (!HAL_STATUS_SUCCESS(status)) {
4459 hddLog(LOGE,
4460 FL("sme_GetValidChannelsByBand failed (err=%d)"),
4461 status);
4462 return -EINVAL;
4463 }
4464
4465 pReqMsg->buckets[bktIndex].numChannels =
4466 VOS_MIN(numChannels, WLAN_EXTSCAN_MAX_CHANNELS);
4467 hddLog(LOG1, FL("Num channels %d"),
4468 pReqMsg->buckets[bktIndex].numChannels);
4469
4470 for (j = 0; j < pReqMsg->buckets[bktIndex].numChannels;
4471 j++) {
4472 pReqMsg->buckets[bktIndex].channels[j].channel =
4473 chanList[j];
4474 pReqMsg->buckets[bktIndex].channels[j].
4475 chnlClass = 0;
4476 if (CSR_IS_CHANNEL_DFS(
4477 vos_freq_to_chan(chanList[j]))) {
4478 pReqMsg->buckets[bktIndex].channels[j].
4479 passive = 1;
4480 pReqMsg->buckets[bktIndex].channels[j].
4481 dwellTimeMs = passive_max_chn_time;
4482 } else {
4483 pReqMsg->buckets[bktIndex].channels[j].
4484 passive = 0;
4485 pReqMsg->buckets[bktIndex].channels[j].
4486 dwellTimeMs = active_max_chn_time;
4487 }
4488
4489 hddLog(LOG1,
4490 "Channel %u Passive %u Dwell time %u ms",
4491 pReqMsg->buckets[bktIndex].channels[j].channel,
4492 pReqMsg->buckets[bktIndex].channels[j].passive,
4493 pReqMsg->buckets[bktIndex].channels[j].dwellTimeMs);
4494 }
4495
4496 bktIndex++;
4497 continue;
4498 }
4499
4500 /* Parse and fetch number of channels */
4501 if (!bucket[
4502 QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_NUM_CHANNEL_SPECS]) {
4503 hddLog(LOGE, FL("attr num channels failed"));
4504 return -EINVAL;
4505 }
4506
4507 pReqMsg->buckets[bktIndex].numChannels =
4508 nla_get_u32(bucket[
4509 QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_NUM_CHANNEL_SPECS]);
4510 hddLog(LOG1, FL("num channels %d"),
4511 pReqMsg->buckets[bktIndex].numChannels);
4512
4513 if (!bucket[QCA_WLAN_VENDOR_ATTR_EXTSCAN_CHANNEL_SPEC]) {
4514 hddLog(LOGE, FL("attr channel spec failed"));
4515 return -EINVAL;
4516 }
4517
4518 j = 0;
4519 nla_for_each_nested(channels,
4520 bucket[QCA_WLAN_VENDOR_ATTR_EXTSCAN_CHANNEL_SPEC], rem2) {
4521 if (nla_parse(channel,
4522 QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX,
4523 nla_data(channels), nla_len(channels),
4524 wlan_hdd_extscan_config_policy)) {
4525 hddLog(LOGE, FL("nla_parse failed"));
4526 return -EINVAL;
4527 }
4528
4529 /* Parse and fetch channel */
4530 if (!channel[
4531 QCA_WLAN_VENDOR_ATTR_EXTSCAN_CHANNEL_SPEC_CHANNEL]) {
4532 hddLog(LOGE, FL("attr channel failed"));
4533 return -EINVAL;
4534 }
4535 pReqMsg->buckets[bktIndex].channels[j].channel =
4536 nla_get_u32(channel[
4537 QCA_WLAN_VENDOR_ATTR_EXTSCAN_CHANNEL_SPEC_CHANNEL]);
4538 hddLog(LOG1, FL("channel %u"),
4539 pReqMsg->buckets[bktIndex].channels[j].channel);
4540
4541 /* Parse and fetch dwell time */
4542 if (!channel[
4543 QCA_WLAN_VENDOR_ATTR_EXTSCAN_CHANNEL_SPEC_DWELL_TIME]) {
4544 hddLog(LOGE, FL("attr dwelltime failed"));
4545 return -EINVAL;
4546 }
4547 pReqMsg->buckets[bktIndex].channels[j].dwellTimeMs =
4548 nla_get_u32(channel[
4549 QCA_WLAN_VENDOR_ATTR_EXTSCAN_CHANNEL_SPEC_DWELL_TIME]);
4550
4551 hddLog(LOG1, FL("Dwell time (%u ms)"),
4552 pReqMsg->buckets[bktIndex].channels[j].dwellTimeMs);
4553
4554
4555 /* Parse and fetch channel spec passive */
4556 if (!channel[
4557 QCA_WLAN_VENDOR_ATTR_EXTSCAN_CHANNEL_SPEC_PASSIVE]) {
4558 hddLog(LOGE,
4559 FL("attr channel spec passive failed"));
4560 return -EINVAL;
4561 }
4562 pReqMsg->buckets[bktIndex].channels[j].passive =
4563 nla_get_u8(channel[
4564 QCA_WLAN_VENDOR_ATTR_EXTSCAN_CHANNEL_SPEC_PASSIVE]);
4565 hddLog(LOG1, FL("Chnl spec passive %u"),
4566 pReqMsg->buckets[bktIndex].channels[j].passive);
4567
4568 j++;
4569 }
4570
4571 bktIndex++;
4572 }
4573
4574 return 0;
4575}
4576
4577
4578/*
4579 * define short names for the global vendor params
4580 * used by wlan_hdd_cfg80211_extscan_start()
4581 */
4582#define PARAM_MAX \
4583QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX
4584#define PARAM_REQUEST_ID \
4585QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_REQUEST_ID
4586#define PARAM_BASE_PERIOD \
4587QCA_WLAN_VENDOR_ATTR_EXTSCAN_SCAN_CMD_PARAMS_BASE_PERIOD
4588#define PARAM_MAX_AP_PER_SCAN \
4589QCA_WLAN_VENDOR_ATTR_EXTSCAN_SCAN_CMD_PARAMS_MAX_AP_PER_SCAN
4590#define PARAM_RPT_THRHLD_PERCENT \
4591QCA_WLAN_VENDOR_ATTR_EXTSCAN_SCAN_CMD_PARAMS_REPORT_THRESHOLD_PERCENT
4592#define PARAM_RPT_THRHLD_NUM_SCANS \
4593QCA_WLAN_VENDOR_ATTR_EXTSCAN_SCAN_CMD_PARAMS_REPORT_THRESHOLD_NUM_SCANS
4594#define PARAM_NUM_BUCKETS \
4595QCA_WLAN_VENDOR_ATTR_EXTSCAN_SCAN_CMD_PARAMS_NUM_BUCKETS
4596
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05304597static int __wlan_hdd_cfg80211_extscan_start(struct wiphy *wiphy,
Dino Mycle6fb96c12014-06-10 11:52:40 +05304598 struct wireless_dev *wdev,
Jeff Johnson393c2702014-12-16 11:09:35 +05304599 const void *data, int dataLen)
Dino Mycle6fb96c12014-06-10 11:52:40 +05304600{
Dino Myclee8843b32014-07-04 14:21:45 +05304601 tpSirEXTScanStartReqParams pReqMsg = NULL;
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05304602 struct net_device *dev = wdev->netdev;
4603 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
4604 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
4605 struct nlattr *tb[PARAM_MAX + 1];
4606 int retval;
Dino Mycle6fb96c12014-06-10 11:52:40 +05304607 eHalStatus status;
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05304608 tANI_U32 request_id;
4609 struct hdd_ext_scan_context *context;
4610 unsigned long rc;
Dino Mycle6fb96c12014-06-10 11:52:40 +05304611
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05304612 ENTER();
4613
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05304614 if (VOS_FTM_MODE == hdd_get_conparam()) {
4615 hddLog(LOGE, FL("Command not allowed in FTM mode"));
4616 return -EINVAL;
4617 }
4618
Dino Mycle6fb96c12014-06-10 11:52:40 +05304619 status = wlan_hdd_validate_context(pHddCtx);
4620 if (0 != status)
4621 {
Dino Mycle6fb96c12014-06-10 11:52:40 +05304622 return -EINVAL;
4623 }
Dino Myclee8843b32014-07-04 14:21:45 +05304624 /* check the EXTScan Capability */
4625 if ( (TRUE != pHddCtx->cfg_ini->fEnableEXTScan) ||
Padma, Santhosh Kumar2ac54992015-10-12 18:20:58 +05304626 (TRUE != sme_IsFeatureSupportedByFW(EXTENDED_SCAN)) ||
4627 (TRUE != sme_IsFeatureSupportedByFW(EXT_SCAN_ENHANCED)))
Dino Myclee8843b32014-07-04 14:21:45 +05304628 {
4629 hddLog(VOS_TRACE_LEVEL_ERROR,
4630 FL("EXTScan not enabled/supported by Firmware"));
4631 return -EINVAL;
4632 }
4633
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05304634 if (nla_parse(tb, PARAM_MAX,
Dino Mycle6fb96c12014-06-10 11:52:40 +05304635 data, dataLen,
4636 wlan_hdd_extscan_config_policy)) {
4637 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Invalid ATTR"));
4638 return -EINVAL;
4639 }
4640
4641 /* Parse and fetch request Id */
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05304642 if (!tb[PARAM_REQUEST_ID]) {
Dino Mycle6fb96c12014-06-10 11:52:40 +05304643 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr request id failed"));
4644 return -EINVAL;
4645 }
4646
Dino Myclee8843b32014-07-04 14:21:45 +05304647 pReqMsg = (tpSirEXTScanStartReqParams)
4648 vos_mem_malloc(sizeof(*pReqMsg));
Dino Mycle6fb96c12014-06-10 11:52:40 +05304649 if (!pReqMsg) {
Dino Myclee8843b32014-07-04 14:21:45 +05304650 hddLog(VOS_TRACE_LEVEL_ERROR, FL("vos_mem_malloc failed"));
4651 return -ENOMEM;
Dino Mycle6fb96c12014-06-10 11:52:40 +05304652 }
4653
4654 pReqMsg->requestId = nla_get_u32(
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05304655 tb[PARAM_REQUEST_ID]);
Dino Mycle6fb96c12014-06-10 11:52:40 +05304656 hddLog(VOS_TRACE_LEVEL_INFO, FL("Req Id (%d)"), pReqMsg->requestId);
4657
4658 pReqMsg->sessionId = pAdapter->sessionId;
4659 hddLog(VOS_TRACE_LEVEL_INFO, FL("Session Id (%d)"), pReqMsg->sessionId);
4660
4661 /* Parse and fetch base period */
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05304662 if (!tb[PARAM_BASE_PERIOD]) {
Dino Mycle6fb96c12014-06-10 11:52:40 +05304663 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr base period failed"));
4664 goto fail;
4665 }
4666 pReqMsg->basePeriod = nla_get_u32(
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05304667 tb[PARAM_BASE_PERIOD]);
Dino Mycle6fb96c12014-06-10 11:52:40 +05304668 hddLog(VOS_TRACE_LEVEL_INFO, FL("Base Period (%d)"),
4669 pReqMsg->basePeriod);
4670
4671 /* Parse and fetch max AP per scan */
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05304672 if (!tb[PARAM_MAX_AP_PER_SCAN]) {
Dino Mycle6fb96c12014-06-10 11:52:40 +05304673 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr max_ap_per_scan failed"));
4674 goto fail;
4675 }
4676 pReqMsg->maxAPperScan = nla_get_u32(
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05304677 tb[PARAM_MAX_AP_PER_SCAN]);
Dino Mycle6fb96c12014-06-10 11:52:40 +05304678 hddLog(VOS_TRACE_LEVEL_INFO, FL("Max AP per Scan (%d)"),
4679 pReqMsg->maxAPperScan);
4680
4681 /* Parse and fetch report threshold */
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05304682 if (!tb[PARAM_RPT_THRHLD_PERCENT]) {
Dino Mycle6fb96c12014-06-10 11:52:40 +05304683 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr report_threshold failed"));
4684 goto fail;
4685 }
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05304686 pReqMsg->reportThresholdPercent = nla_get_u8(
4687 tb[PARAM_RPT_THRHLD_PERCENT]);
Dino Mycle6fb96c12014-06-10 11:52:40 +05304688 hddLog(VOS_TRACE_LEVEL_INFO, FL("Report Threshold (%d)"),
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05304689 pReqMsg->reportThresholdPercent);
4690
4691 /* Parse and fetch report threshold num scans */
4692 if (!tb[PARAM_RPT_THRHLD_NUM_SCANS]) {
4693 hddLog(LOGE, FL("attr report_threshold num scans failed"));
4694 goto fail;
4695 }
4696 pReqMsg->reportThresholdNumScans = nla_get_u8(
4697 tb[PARAM_RPT_THRHLD_NUM_SCANS]);
4698 hddLog(LOG1, FL("Report Threshold num scans %d"),
4699 pReqMsg->reportThresholdNumScans);
Dino Mycle6fb96c12014-06-10 11:52:40 +05304700
4701 /* Parse and fetch number of buckets */
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05304702 if (!tb[PARAM_NUM_BUCKETS]) {
Dino Mycle6fb96c12014-06-10 11:52:40 +05304703 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr number of buckets failed"));
4704 goto fail;
4705 }
4706 pReqMsg->numBuckets = nla_get_u8(
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05304707 tb[PARAM_NUM_BUCKETS]);
Dino Mycle6fb96c12014-06-10 11:52:40 +05304708 if (pReqMsg->numBuckets > WLAN_EXTSCAN_MAX_BUCKETS) {
4709 hddLog(VOS_TRACE_LEVEL_WARN, FL("Exceeded MAX number of buckets "
4710 "Setting numBuckets to %u"), WLAN_EXTSCAN_MAX_BUCKETS);
4711 pReqMsg->numBuckets = WLAN_EXTSCAN_MAX_BUCKETS;
4712 }
4713 hddLog(VOS_TRACE_LEVEL_INFO, FL("Number of Buckets (%d)"),
4714 pReqMsg->numBuckets);
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05304715
Dino Mycle6fb96c12014-06-10 11:52:40 +05304716 if (!tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC]) {
4717 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr bucket spec failed"));
4718 goto fail;
4719 }
4720
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05304721 pReqMsg->homeAwayTime = pHddCtx->cfg_ini->nRestTimeConc;
Dino Mycle6fb96c12014-06-10 11:52:40 +05304722
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05304723 if (hdd_extscan_start_fill_bucket_channel_spec(pHddCtx, pReqMsg, tb))
4724 goto fail;
Dasari Srinivas8b2ce272014-09-16 16:57:30 +05304725
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05304726 context = &pHddCtx->ext_scan_context;
4727 spin_lock(&hdd_context_lock);
4728 INIT_COMPLETION(context->response_event);
4729 context->request_id = request_id = pReqMsg->requestId;
4730 spin_unlock(&hdd_context_lock);
Dasari Srinivas8b2ce272014-09-16 16:57:30 +05304731
Dino Mycle6fb96c12014-06-10 11:52:40 +05304732 status = sme_EXTScanStart(pHddCtx->hHal, pReqMsg);
4733 if (!HAL_STATUS_SUCCESS(status)) {
4734 hddLog(VOS_TRACE_LEVEL_ERROR,
4735 FL("sme_EXTScanStart failed(err=%d)"), status);
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05304736 goto fail;
4737 }
4738
4739 /* request was sent -- wait for the response */
4740 rc = wait_for_completion_timeout(&context->response_event,
4741 msecs_to_jiffies(WLAN_WAIT_TIME_EXTSCAN));
4742
4743 if (!rc) {
4744 hddLog(LOGE, FL("sme_ExtScanStart timed out"));
4745 retval = -ETIMEDOUT;
4746 } else {
4747 spin_lock(&hdd_context_lock);
4748 if (context->request_id == request_id)
4749 retval = context->response_status;
4750 else
4751 retval = -EINVAL;
4752 spin_unlock(&hdd_context_lock);
Dino Mycle6fb96c12014-06-10 11:52:40 +05304753 }
4754
Dino Myclee8843b32014-07-04 14:21:45 +05304755 vos_mem_free(pReqMsg);
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05304756 EXIT();
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05304757 return retval;
Dino Mycle6fb96c12014-06-10 11:52:40 +05304758
4759fail:
4760 vos_mem_free(pReqMsg);
4761 return -EINVAL;
4762}
4763
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05304764/*
4765 * done with short names for the global vendor params
4766 * used by wlan_hdd_cfg80211_extscan_start()
4767 */
4768#undef PARAM_MAX
4769#undef PARAM_REQUEST_ID
4770#undef PARAM_BASE_PERIOD
4771#undef PARAMS_MAX_AP_PER_SCAN
4772#undef PARAMS_RPT_THRHLD_PERCENT
4773#undef PARAMS_RPT_THRHLD_NUM_SCANS
4774#undef PARAMS_NUM_BUCKETS
4775
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05304776static int wlan_hdd_cfg80211_extscan_start(struct wiphy *wiphy,
4777 struct wireless_dev *wdev,
4778 const void *data, int dataLen)
4779{
4780 int ret = 0;
4781
4782 vos_ssr_protect(__func__);
4783 ret = __wlan_hdd_cfg80211_extscan_start(wiphy, wdev, data, dataLen);
4784 vos_ssr_unprotect(__func__);
4785
4786 return ret;
4787}
4788
4789static int __wlan_hdd_cfg80211_extscan_stop(struct wiphy *wiphy,
Dino Mycle6fb96c12014-06-10 11:52:40 +05304790 struct wireless_dev *wdev,
Jeff Johnson393c2702014-12-16 11:09:35 +05304791 const void *data, int dataLen)
Dino Mycle6fb96c12014-06-10 11:52:40 +05304792{
Dino Myclee8843b32014-07-04 14:21:45 +05304793 tSirEXTScanStopReqParams reqMsg;
Dino Mycle6fb96c12014-06-10 11:52:40 +05304794 struct net_device *dev = wdev->netdev;
4795 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
4796 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
4797 struct nlattr *tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX + 1];
4798 eHalStatus status;
Padma, Santhosh Kumar57cff7f2015-08-17 18:33:14 +05304799 int retval;
4800 unsigned long rc;
4801 struct hdd_ext_scan_context *context;
4802 tANI_U32 request_id;
Dino Mycle6fb96c12014-06-10 11:52:40 +05304803
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05304804 ENTER();
4805
Padma, Santhosh Kumar57cff7f2015-08-17 18:33:14 +05304806 if (VOS_FTM_MODE == hdd_get_conparam()) {
4807 hddLog(LOGE, FL("Command not allowed in FTM mode"));
4808 return -EINVAL;
4809 }
4810
Dino Mycle6fb96c12014-06-10 11:52:40 +05304811 status = wlan_hdd_validate_context(pHddCtx);
4812 if (0 != status)
4813 {
Dino Mycle6fb96c12014-06-10 11:52:40 +05304814 return -EINVAL;
4815 }
Dino Myclee8843b32014-07-04 14:21:45 +05304816 /* check the EXTScan Capability */
4817 if ( (TRUE != pHddCtx->cfg_ini->fEnableEXTScan) ||
Padma, Santhosh Kumar2ac54992015-10-12 18:20:58 +05304818 (TRUE != sme_IsFeatureSupportedByFW(EXTENDED_SCAN)) ||
4819 (TRUE != sme_IsFeatureSupportedByFW(EXT_SCAN_ENHANCED)))
Dino Myclee8843b32014-07-04 14:21:45 +05304820 {
4821 hddLog(VOS_TRACE_LEVEL_ERROR,
4822 FL("EXTScan not enabled/supported by Firmware"));
4823 return -EINVAL;
4824 }
4825
Dino Mycle6fb96c12014-06-10 11:52:40 +05304826 if (nla_parse(tb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX,
4827 data, dataLen,
4828 wlan_hdd_extscan_config_policy)) {
4829 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Invalid ATTR"));
4830 return -EINVAL;
4831 }
4832
4833 /* Parse and fetch request Id */
4834 if (!tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_REQUEST_ID]) {
4835 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr request id failed"));
4836 return -EINVAL;
4837 }
4838
Dino Myclee8843b32014-07-04 14:21:45 +05304839 reqMsg.requestId = nla_get_u32(
Dino Mycle6fb96c12014-06-10 11:52:40 +05304840 tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_REQUEST_ID]);
Dino Myclee8843b32014-07-04 14:21:45 +05304841 hddLog(VOS_TRACE_LEVEL_INFO, FL("Req Id (%d)"), reqMsg.requestId);
Dino Mycle6fb96c12014-06-10 11:52:40 +05304842
Dino Myclee8843b32014-07-04 14:21:45 +05304843 reqMsg.sessionId = pAdapter->sessionId;
4844 hddLog(VOS_TRACE_LEVEL_INFO, FL("Session Id (%d)"), reqMsg.sessionId);
Dino Mycle6fb96c12014-06-10 11:52:40 +05304845
Padma, Santhosh Kumar57cff7f2015-08-17 18:33:14 +05304846 context = &pHddCtx->ext_scan_context;
4847 spin_lock(&hdd_context_lock);
4848 INIT_COMPLETION(context->response_event);
4849 context->request_id = request_id = reqMsg.sessionId;
4850 spin_unlock(&hdd_context_lock);
4851
Dino Myclee8843b32014-07-04 14:21:45 +05304852 status = sme_EXTScanStop(pHddCtx->hHal, &reqMsg);
Dino Mycle6fb96c12014-06-10 11:52:40 +05304853 if (!HAL_STATUS_SUCCESS(status)) {
4854 hddLog(VOS_TRACE_LEVEL_ERROR,
4855 FL("sme_EXTScanStop failed(err=%d)"), status);
Dino Mycle6fb96c12014-06-10 11:52:40 +05304856 return -EINVAL;
4857 }
4858
Padma, Santhosh Kumar57cff7f2015-08-17 18:33:14 +05304859 /* request was sent -- wait for the response */
4860 rc = wait_for_completion_timeout(&context->response_event,
4861 msecs_to_jiffies(WLAN_WAIT_TIME_EXTSCAN));
4862
4863 if (!rc) {
4864 hddLog(LOGE, FL("sme_ExtScanStop timed out"));
4865 retval = -ETIMEDOUT;
4866 } else {
4867 spin_lock(&hdd_context_lock);
4868 if (context->request_id == request_id)
4869 retval = context->response_status;
4870 else
4871 retval = -EINVAL;
4872 spin_unlock(&hdd_context_lock);
4873 }
4874
4875 return retval;
4876
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05304877 EXIT();
Dino Mycle6fb96c12014-06-10 11:52:40 +05304878 return 0;
4879}
4880
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05304881static int wlan_hdd_cfg80211_extscan_stop(struct wiphy *wiphy,
4882 struct wireless_dev *wdev,
4883 const void *data, int dataLen)
4884{
4885 int ret = 0;
4886
4887 vos_ssr_protect(__func__);
4888 ret = __wlan_hdd_cfg80211_extscan_stop(wiphy, wdev, data, dataLen);
4889 vos_ssr_unprotect(__func__);
4890
4891 return ret;
4892}
4893
4894static int __wlan_hdd_cfg80211_extscan_reset_bssid_hotlist(struct wiphy *wiphy,
Dino Mycle6fb96c12014-06-10 11:52:40 +05304895 struct wireless_dev *wdev,
Jeff Johnson393c2702014-12-16 11:09:35 +05304896 const void *data, int dataLen)
Dino Mycle6fb96c12014-06-10 11:52:40 +05304897{
Dino Myclee8843b32014-07-04 14:21:45 +05304898 tSirEXTScanResetBssidHotlistReqParams reqMsg;
Dino Mycle6fb96c12014-06-10 11:52:40 +05304899 struct net_device *dev = wdev->netdev;
4900 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
4901 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
4902 struct nlattr *tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX + 1];
4903 eHalStatus status;
Padma, Santhosh Kumar04a3bab2015-08-20 13:09:35 +05304904 struct hdd_ext_scan_context *context;
4905 tANI_U32 request_id;
4906 unsigned long rc;
4907 int retval;
Dino Mycle6fb96c12014-06-10 11:52:40 +05304908
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05304909 ENTER();
4910
Padma, Santhosh Kumar04a3bab2015-08-20 13:09:35 +05304911 if (VOS_FTM_MODE == hdd_get_conparam()) {
4912 hddLog(LOGE, FL("Command not allowed in FTM mode"));
4913 return -EINVAL;
4914 }
4915
Dino Mycle6fb96c12014-06-10 11:52:40 +05304916 status = wlan_hdd_validate_context(pHddCtx);
4917 if (0 != status)
4918 {
Padma, Santhosh Kumar04a3bab2015-08-20 13:09:35 +05304919 hddLog(LOGE, FL("HDD context is not valid"));
Dino Mycle6fb96c12014-06-10 11:52:40 +05304920 return -EINVAL;
4921 }
Dino Myclee8843b32014-07-04 14:21:45 +05304922 /* check the EXTScan Capability */
4923 if ( (TRUE != pHddCtx->cfg_ini->fEnableEXTScan) ||
Padma, Santhosh Kumar2ac54992015-10-12 18:20:58 +05304924 (TRUE != sme_IsFeatureSupportedByFW(EXTENDED_SCAN)) ||
4925 (TRUE != sme_IsFeatureSupportedByFW(EXT_SCAN_ENHANCED)))
Dino Myclee8843b32014-07-04 14:21:45 +05304926 {
4927 hddLog(VOS_TRACE_LEVEL_ERROR,
4928 FL("EXTScan not enabled/supported by Firmware"));
4929 return -EINVAL;
4930 }
4931
Dino Mycle6fb96c12014-06-10 11:52:40 +05304932 if (nla_parse(tb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX,
4933 data, dataLen,
4934 wlan_hdd_extscan_config_policy)) {
4935 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Invalid ATTR"));
4936 return -EINVAL;
4937 }
4938
4939 /* Parse and fetch request Id */
4940 if (!tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_REQUEST_ID]) {
4941 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr request id failed"));
4942 return -EINVAL;
4943 }
4944
Dino Myclee8843b32014-07-04 14:21:45 +05304945 reqMsg.requestId = nla_get_u32(
Dino Mycle6fb96c12014-06-10 11:52:40 +05304946 tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_REQUEST_ID]);
Dino Myclee8843b32014-07-04 14:21:45 +05304947 hddLog(VOS_TRACE_LEVEL_INFO, FL("Req Id (%d)"), reqMsg.requestId);
Dino Mycle6fb96c12014-06-10 11:52:40 +05304948
Dino Myclee8843b32014-07-04 14:21:45 +05304949 reqMsg.sessionId = pAdapter->sessionId;
4950 hddLog(VOS_TRACE_LEVEL_INFO, FL("Session Id (%d)"), reqMsg.sessionId);
Dino Mycle6fb96c12014-06-10 11:52:40 +05304951
Padma, Santhosh Kumar04a3bab2015-08-20 13:09:35 +05304952 context = &pHddCtx->ext_scan_context;
4953 spin_lock(&hdd_context_lock);
4954 INIT_COMPLETION(context->response_event);
4955 context->request_id = request_id = reqMsg.requestId;
4956 spin_unlock(&hdd_context_lock);
4957
Dino Myclee8843b32014-07-04 14:21:45 +05304958 status = sme_ResetBssHotlist(pHddCtx->hHal, &reqMsg);
Dino Mycle6fb96c12014-06-10 11:52:40 +05304959 if (!HAL_STATUS_SUCCESS(status)) {
4960 hddLog(VOS_TRACE_LEVEL_ERROR,
4961 FL("sme_ResetBssHotlist failed(err=%d)"), status);
Dino Mycle6fb96c12014-06-10 11:52:40 +05304962 return -EINVAL;
4963 }
Padma, Santhosh Kumar04a3bab2015-08-20 13:09:35 +05304964
4965 /* request was sent -- wait for the response */
4966 rc = wait_for_completion_timeout(&context->response_event,
4967 msecs_to_jiffies(WLAN_WAIT_TIME_EXTSCAN));
4968 if (!rc) {
4969 hddLog(LOGE, FL("sme_ResetBssHotlist timed out"));
4970 retval = -ETIMEDOUT;
4971 } else {
4972 spin_lock(&hdd_context_lock);
4973 if (context->request_id == request_id)
4974 retval = context->response_status;
4975 else
4976 retval = -EINVAL;
4977 spin_unlock(&hdd_context_lock);
4978 }
4979
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05304980 EXIT();
Padma, Santhosh Kumar04a3bab2015-08-20 13:09:35 +05304981 return retval;
Dino Mycle6fb96c12014-06-10 11:52:40 +05304982}
4983
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05304984static int wlan_hdd_cfg80211_extscan_reset_bssid_hotlist(struct wiphy *wiphy,
4985 struct wireless_dev *wdev,
4986 const void *data, int dataLen)
4987{
4988 int ret = 0;
4989
4990 vos_ssr_protect(__func__);
4991 ret = __wlan_hdd_cfg80211_extscan_reset_bssid_hotlist(wiphy, wdev, data, dataLen);
4992 vos_ssr_unprotect(__func__);
4993
4994 return ret;
4995}
Dino Mycle6fb96c12014-06-10 11:52:40 +05304996#endif /* WLAN_FEATURE_EXTSCAN */
4997
Atul Mittal115287b2014-07-08 13:26:33 +05304998/*EXT TDLS*/
4999static const struct nla_policy
5000wlan_hdd_tdls_config_enable_policy[QCA_WLAN_VENDOR_ATTR_TDLS_ENABLE_MAX +1] =
5001{
5002 [QCA_WLAN_VENDOR_ATTR_TDLS_ENABLE_MAC_ADDR] = {.type = NLA_UNSPEC },
5003 [QCA_WLAN_VENDOR_ATTR_TDLS_ENABLE_CHANNEL] = {.type = NLA_S32 },
5004 [QCA_WLAN_VENDOR_ATTR_TDLS_ENABLE_GLOBAL_OPERATING_CLASS] =
5005 {.type = NLA_S32 },
5006 [QCA_WLAN_VENDOR_ATTR_TDLS_ENABLE_MAX_LATENCY_MS] = {.type = NLA_S32 },
5007 [QCA_WLAN_VENDOR_ATTR_TDLS_ENABLE_MIN_BANDWIDTH_KBPS] = {.type = NLA_S32 },
5008
5009};
5010
5011static const struct nla_policy
5012wlan_hdd_tdls_config_disable_policy[QCA_WLAN_VENDOR_ATTR_TDLS_DISABLE_MAX +1] =
5013{
5014 [QCA_WLAN_VENDOR_ATTR_TDLS_DISABLE_MAC_ADDR] = {.type = NLA_UNSPEC },
5015
5016};
5017
5018static const struct nla_policy
5019wlan_hdd_tdls_config_state_change_policy[
5020 QCA_WLAN_VENDOR_ATTR_TDLS_STATE_MAX +1] =
5021{
5022 [QCA_WLAN_VENDOR_ATTR_TDLS_STATE_MAC_ADDR] = {.type = NLA_UNSPEC },
5023 [QCA_WLAN_VENDOR_ATTR_TDLS_NEW_STATE] = {.type = NLA_S32 },
5024 [QCA_WLAN_VENDOR_ATTR_TDLS_STATE_REASON] = {.type = NLA_S32 },
Atul Mittal0a9f68d2014-10-16 15:26:38 +05305025 [QCA_WLAN_VENDOR_ATTR_TDLS_STATE_CHANNEL] = {.type = NLA_S32 },
5026 [QCA_WLAN_VENDOR_ATTR_TDLS_STATE_GLOBAL_OPERATING_CLASS] =
5027 {.type = NLA_S32 },
Atul Mittal115287b2014-07-08 13:26:33 +05305028
5029};
5030
5031static const struct nla_policy
5032wlan_hdd_tdls_config_get_status_policy[
5033 QCA_WLAN_VENDOR_ATTR_TDLS_GET_STATUS_MAX +1] =
5034{
5035 [QCA_WLAN_VENDOR_ATTR_TDLS_GET_STATUS_MAC_ADDR] = {.type = NLA_UNSPEC },
5036 [QCA_WLAN_VENDOR_ATTR_TDLS_GET_STATUS_STATE] = {.type = NLA_S32 },
5037 [QCA_WLAN_VENDOR_ATTR_TDLS_GET_STATUS_REASON] = {.type = NLA_S32 },
Atul Mittal0a9f68d2014-10-16 15:26:38 +05305038 [QCA_WLAN_VENDOR_ATTR_TDLS_GET_STATUS_CHANNEL] = {.type = NLA_S32 },
5039 [QCA_WLAN_VENDOR_ATTR_TDLS_GET_STATUS_GLOBAL_OPERATING_CLASS]
5040 = {.type = NLA_S32 },
Atul Mittal115287b2014-07-08 13:26:33 +05305041
5042};
Siddharth Bhala3a5cb42014-09-29 21:13:13 +05305043
5044static const struct nla_policy
5045wlan_hdd_mac_config[QCA_WLAN_VENDOR_ATTR_SET_SCANNING_MAC_OUI_MAX+1] =
5046{
5047 [QCA_WLAN_VENDOR_ATTR_SET_SCANNING_MAC_OUI] = {.type = NLA_UNSPEC },
5048};
5049
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05305050static int __wlan_hdd_cfg80211_set_spoofed_mac_oui(struct wiphy *wiphy,
Siddharth Bhala3a5cb42014-09-29 21:13:13 +05305051 struct wireless_dev *wdev,
Jeff Johnson393c2702014-12-16 11:09:35 +05305052 const void *data,
Siddharth Bhala3a5cb42014-09-29 21:13:13 +05305053 int data_len)
5054{
5055
5056 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
5057 struct nlattr *tb[QCA_WLAN_VENDOR_ATTR_SET_SCANNING_MAC_OUI_MAX + 1];
5058
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05305059 ENTER();
5060
Siddharth Bhala3a5cb42014-09-29 21:13:13 +05305061 if (0 != wlan_hdd_validate_context(pHddCtx)){
Siddharth Bhala3a5cb42014-09-29 21:13:13 +05305062 return -EINVAL;
5063 }
Hanumantha Reddy Pothulaca1d1cc2015-10-26 15:37:35 +05305064 if (0 == pHddCtx->cfg_ini->enableMacSpoofing) {
Ratheesh S P36dbc932015-08-07 14:28:57 +05305065 hddLog(VOS_TRACE_LEVEL_INFO, FL("MAC_SPOOFED_SCAN disabled in ini"));
Siddharth Bhala3a5cb42014-09-29 21:13:13 +05305066 return -ENOTSUPP;
Siddharth Bhal76972212014-10-15 16:22:51 +05305067 }
Siddharth Bhala3a5cb42014-09-29 21:13:13 +05305068 if (TRUE != sme_IsFeatureSupportedByFW(MAC_SPOOFED_SCAN)){
Ratheesh S P36dbc932015-08-07 14:28:57 +05305069 hddLog(VOS_TRACE_LEVEL_INFO, FL("MAC_SPOOFED_SCAN not supported by FW"));
Siddharth Bhala3a5cb42014-09-29 21:13:13 +05305070 return -ENOTSUPP;
5071 }
5072
5073 if (nla_parse(tb, QCA_WLAN_VENDOR_ATTR_SET_SCANNING_MAC_OUI_MAX,
5074 data, data_len, wlan_hdd_mac_config)) {
5075 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Invalid ATTR"));
5076 return -EINVAL;
5077 }
5078
5079 /* Parse and fetch mac address */
5080 if (!tb[QCA_WLAN_VENDOR_ATTR_SET_SCANNING_MAC_OUI]) {
5081 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr mac addr failed"));
5082 return -EINVAL;
5083 }
5084
5085 memcpy(pHddCtx->spoofMacAddr.randomMacAddr.bytes, nla_data(
5086 tb[QCA_WLAN_VENDOR_ATTR_SET_SCANNING_MAC_OUI]),
5087 VOS_MAC_ADDR_LAST_3_BYTES);
5088
Siddharth Bhal76972212014-10-15 16:22:51 +05305089 pHddCtx->spoofMacAddr.isEnabled = TRUE;
5090
5091 vos_trace_hex_dump( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO, nla_data(
Siddharth Bhala3a5cb42014-09-29 21:13:13 +05305092 tb[QCA_WLAN_VENDOR_ATTR_SET_SCANNING_MAC_OUI]),
5093 VOS_MAC_ADDR_FIRST_3_BYTES);
Siddharth Bhal76972212014-10-15 16:22:51 +05305094 if ((pHddCtx->spoofMacAddr.randomMacAddr.bytes[0] == 0) &&
5095 (pHddCtx->spoofMacAddr.randomMacAddr.bytes[1] == 0) &&
5096 (pHddCtx->spoofMacAddr.randomMacAddr.bytes[2] == 0))
5097 {
5098 hddLog(LOG1, FL("ZERO MAC OUI Recieved. Disabling Spoofing"));
5099 vos_mem_zero(pHddCtx->spoofMacAddr.randomMacAddr.bytes,
5100 VOS_MAC_ADDRESS_LEN);
5101 pHddCtx->spoofMacAddr.isEnabled = FALSE;
Siddharth Bhala3a5cb42014-09-29 21:13:13 +05305102 }
Siddharth Bhala3a5cb42014-09-29 21:13:13 +05305103
Siddharth Bhal76972212014-10-15 16:22:51 +05305104 if (VOS_STATUS_SUCCESS != hdd_processSpoofMacAddrRequest(pHddCtx))
5105 {
Siddharth Bhala3a5cb42014-09-29 21:13:13 +05305106 hddLog(LOGE, FL("Failed to send Spoof Mac Addr to FW"));
5107 }
5108
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05305109 EXIT();
Siddharth Bhala3a5cb42014-09-29 21:13:13 +05305110 return 0;
5111}
5112
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05305113static int wlan_hdd_cfg80211_set_spoofed_mac_oui(struct wiphy *wiphy,
5114 struct wireless_dev *wdev,
5115 const void *data,
5116 int data_len)
5117{
5118 int ret = 0;
5119
5120 vos_ssr_protect(__func__);
5121 ret = __wlan_hdd_cfg80211_set_spoofed_mac_oui(wiphy, wdev, data, data_len);
5122 vos_ssr_unprotect(__func__);
5123
5124 return ret;
5125}
5126
5127static int __wlan_hdd_cfg80211_exttdls_get_status(struct wiphy *wiphy,
Atul Mittal115287b2014-07-08 13:26:33 +05305128 struct wireless_dev *wdev,
Jeff Johnson393c2702014-12-16 11:09:35 +05305129 const void *data,
Atul Mittal115287b2014-07-08 13:26:33 +05305130 int data_len)
5131{
5132 u8 peer[6] = {0};
5133 struct net_device *dev = wdev->netdev;
5134 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
5135 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
5136 struct nlattr *tb[QCA_WLAN_VENDOR_ATTR_TDLS_GET_STATUS_MAX + 1];
5137 eHalStatus ret;
5138 tANI_S32 state;
5139 tANI_S32 reason;
Atul Mittal0a9f68d2014-10-16 15:26:38 +05305140 tANI_S32 global_operating_class = 0;
5141 tANI_S32 channel = 0;
Atul Mittal115287b2014-07-08 13:26:33 +05305142 struct sk_buff *skb = NULL;
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05305143 int retVal;
5144
5145 ENTER();
Atul Mittal115287b2014-07-08 13:26:33 +05305146
Chandrasekaran, Manishekar41b8e1f2015-03-10 13:30:28 +05305147 if (!pAdapter) {
5148 hddLog(VOS_TRACE_LEVEL_ERROR, FL("HDD adpater is NULL"));
5149 return -EINVAL;
5150 }
5151
Atul Mittal115287b2014-07-08 13:26:33 +05305152 ret = wlan_hdd_validate_context(pHddCtx);
5153 if (0 != ret) {
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +05305154 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Invalid HDD context"));
Atul Mittal115287b2014-07-08 13:26:33 +05305155 return -EINVAL;
5156 }
5157 if (pHddCtx->cfg_ini->fTDLSExternalControl == FALSE) {
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +05305158 hddLog(VOS_TRACE_LEVEL_ERROR, FL("TDLS external control is disabled"));
Atul Mittal115287b2014-07-08 13:26:33 +05305159 return -ENOTSUPP;
5160 }
5161 if (nla_parse(tb, QCA_WLAN_VENDOR_ATTR_TDLS_GET_STATUS_MAX,
5162 data, data_len,
5163 wlan_hdd_tdls_config_get_status_policy)) {
5164 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Invalid ATTR"));
5165 return -EINVAL;
5166 }
5167
5168 /* Parse and fetch mac address */
5169 if (!tb[QCA_WLAN_VENDOR_ATTR_TDLS_GET_STATUS_MAC_ADDR]) {
5170 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr mac addr failed"));
5171 return -EINVAL;
5172 }
5173
5174 memcpy(peer, nla_data(
5175 tb[QCA_WLAN_VENDOR_ATTR_TDLS_GET_STATUS_MAC_ADDR]),
5176 sizeof(peer));
5177 hddLog(VOS_TRACE_LEVEL_INFO, FL(MAC_ADDRESS_STR),MAC_ADDR_ARRAY(peer));
5178
Konamki, Sreelakshmiabb59ed2015-06-12 12:13:23 +05305179 wlan_hdd_tdls_get_status(pAdapter, peer, &state, &reason);
Atul Mittal115287b2014-07-08 13:26:33 +05305180
Atul Mittal115287b2014-07-08 13:26:33 +05305181 skb = cfg80211_vendor_cmd_alloc_reply_skb(wiphy,
Atul Mittal0a9f68d2014-10-16 15:26:38 +05305182 4 * sizeof(s32) +
Atul Mittal115287b2014-07-08 13:26:33 +05305183 NLMSG_HDRLEN);
5184
5185 if (!skb) {
5186 hddLog(VOS_TRACE_LEVEL_ERROR,
5187 FL("cfg80211_vendor_cmd_alloc_reply_skb failed"));
5188 return -EINVAL;
5189 }
Atul Mittal0a9f68d2014-10-16 15:26:38 +05305190 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 +05305191 reason,
5192 state,
Atul Mittal0a9f68d2014-10-16 15:26:38 +05305193 global_operating_class,
5194 channel,
Atul Mittal115287b2014-07-08 13:26:33 +05305195 MAC_ADDR_ARRAY(peer));
Atul Mittal0a9f68d2014-10-16 15:26:38 +05305196 if (nla_put_s32(skb,
5197 QCA_WLAN_VENDOR_ATTR_TDLS_GET_STATUS_STATE,
5198 state) ||
5199 nla_put_s32(skb,
5200 QCA_WLAN_VENDOR_ATTR_TDLS_GET_STATUS_REASON,
5201 reason) ||
5202 nla_put_s32(skb,
5203 QCA_WLAN_VENDOR_ATTR_TDLS_GET_STATUS_GLOBAL_OPERATING_CLASS,
5204 global_operating_class) ||
5205 nla_put_s32(skb,
5206 QCA_WLAN_VENDOR_ATTR_TDLS_GET_STATUS_CHANNEL,
5207 channel)) {
Atul Mittal115287b2014-07-08 13:26:33 +05305208
5209 hddLog(VOS_TRACE_LEVEL_ERROR, FL("nla put fail"));
5210 goto nla_put_failure;
5211 }
5212
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05305213 retVal = cfg80211_vendor_cmd_reply(skb);
5214 EXIT();
5215 return retVal;
Atul Mittal115287b2014-07-08 13:26:33 +05305216
5217nla_put_failure:
5218 kfree_skb(skb);
5219 return -EINVAL;
5220}
5221
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05305222static int wlan_hdd_cfg80211_exttdls_get_status(struct wiphy *wiphy,
5223 struct wireless_dev *wdev,
5224 const void *data,
5225 int data_len)
5226{
5227 int ret = 0;
5228
5229 vos_ssr_protect(__func__);
5230 ret = __wlan_hdd_cfg80211_exttdls_get_status(wiphy, wdev, data, data_len);
5231 vos_ssr_unprotect(__func__);
5232
5233 return ret;
5234}
5235
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +05305236static int wlan_hdd_cfg80211_exttdls_callback(
5237#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,18,0))
5238 const tANI_U8* mac,
5239#else
5240 tANI_U8* mac,
5241#endif
Atul Mittal115287b2014-07-08 13:26:33 +05305242 tANI_S32 state,
5243 tANI_S32 reason,
5244 void *ctx)
5245{
5246 hdd_adapter_t* pAdapter = (hdd_adapter_t*)ctx;
Atul Mittal115287b2014-07-08 13:26:33 +05305247 struct sk_buff *skb = NULL;
Atul Mittal0a9f68d2014-10-16 15:26:38 +05305248 tANI_S32 global_operating_class = 0;
5249 tANI_S32 channel = 0;
Chandrasekaran, Manishekar41b8e1f2015-03-10 13:30:28 +05305250 hdd_context_t *pHddCtx;
Atul Mittal115287b2014-07-08 13:26:33 +05305251
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05305252 ENTER();
5253
Chandrasekaran, Manishekar41b8e1f2015-03-10 13:30:28 +05305254 if (!pAdapter) {
5255 hddLog(VOS_TRACE_LEVEL_ERROR, FL("HDD adpater is NULL"));
5256 return -EINVAL;
5257 }
5258
5259 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Atul Mittal115287b2014-07-08 13:26:33 +05305260 if (wlan_hdd_validate_context(pHddCtx)) {
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +05305261 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Invalid HDD context"));
Atul Mittal115287b2014-07-08 13:26:33 +05305262 return -EINVAL;
5263 }
5264
5265 if (pHddCtx->cfg_ini->fTDLSExternalControl == FALSE) {
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +05305266 hddLog(VOS_TRACE_LEVEL_ERROR, FL("TDLS external control is disabled"));
Atul Mittal115287b2014-07-08 13:26:33 +05305267 return -ENOTSUPP;
5268 }
Anand N Sunkad26ca6cc2015-07-29 09:54:52 +05305269 skb = cfg80211_vendor_event_alloc(pHddCtx->wiphy,
5270#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 18, 0))
5271 NULL,
5272#endif
Atul Mittal115287b2014-07-08 13:26:33 +05305273 EXTTDLS_EVENT_BUF_SIZE + NLMSG_HDRLEN,
5274 QCA_NL80211_VENDOR_SUBCMD_TDLS_STATE_CHANGE_INDEX,
5275 GFP_KERNEL);
5276
5277 if (!skb) {
5278 hddLog(VOS_TRACE_LEVEL_ERROR,
5279 FL("cfg80211_vendor_event_alloc failed"));
5280 return -EINVAL;
5281 }
5282 hddLog(VOS_TRACE_LEVEL_INFO, FL("Entering "));
Atul Mittal0a9f68d2014-10-16 15:26:38 +05305283 hddLog(VOS_TRACE_LEVEL_INFO, "Reason: (%d) Status: (%d) Class: (%d) Channel: (%d)",
5284 reason,
5285 state,
5286 global_operating_class,
5287 channel);
Atul Mittal115287b2014-07-08 13:26:33 +05305288 hddLog(VOS_TRACE_LEVEL_WARN, "tdls peer " MAC_ADDRESS_STR,
5289 MAC_ADDR_ARRAY(mac));
5290
Atul Mittal0a9f68d2014-10-16 15:26:38 +05305291 if (nla_put(skb,
5292 QCA_WLAN_VENDOR_ATTR_TDLS_STATE_MAC_ADDR,
5293 VOS_MAC_ADDR_SIZE, mac) ||
5294 nla_put_s32(skb,
5295 QCA_WLAN_VENDOR_ATTR_TDLS_NEW_STATE,
5296 state) ||
5297 nla_put_s32(skb,
5298 QCA_WLAN_VENDOR_ATTR_TDLS_STATE_REASON,
5299 reason) ||
5300 nla_put_s32(skb,
5301 QCA_WLAN_VENDOR_ATTR_TDLS_STATE_CHANNEL,
5302 channel) ||
5303 nla_put_s32(skb,
5304 QCA_WLAN_VENDOR_ATTR_TDLS_STATE_GLOBAL_OPERATING_CLASS,
5305 global_operating_class)
5306 ) {
Atul Mittal115287b2014-07-08 13:26:33 +05305307 hddLog(VOS_TRACE_LEVEL_ERROR, FL("nla put fail"));
5308 goto nla_put_failure;
5309 }
5310
5311 cfg80211_vendor_event(skb, GFP_KERNEL);
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05305312 EXIT();
Atul Mittal115287b2014-07-08 13:26:33 +05305313 return (0);
5314
5315nla_put_failure:
5316 kfree_skb(skb);
5317 return -EINVAL;
5318}
5319
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05305320static int __wlan_hdd_cfg80211_exttdls_enable(struct wiphy *wiphy,
Atul Mittal115287b2014-07-08 13:26:33 +05305321 struct wireless_dev *wdev,
Jeff Johnson393c2702014-12-16 11:09:35 +05305322 const void *data,
Atul Mittal115287b2014-07-08 13:26:33 +05305323 int data_len)
5324{
5325 u8 peer[6] = {0};
5326 struct net_device *dev = wdev->netdev;
Atul Mittal115287b2014-07-08 13:26:33 +05305327 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
5328 struct nlattr *tb[QCA_WLAN_VENDOR_ATTR_TDLS_ENABLE_MAX + 1];
5329 eHalStatus status;
5330 tdls_req_params_t pReqMsg = {0};
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05305331 int ret;
Chandrasekaran, Manishekar41b8e1f2015-03-10 13:30:28 +05305332 hdd_adapter_t *pAdapter;
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05305333
5334 ENTER();
Atul Mittal115287b2014-07-08 13:26:33 +05305335
Chandrasekaran, Manishekar41b8e1f2015-03-10 13:30:28 +05305336 if (!dev) {
5337 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Dev pointer is NULL"));
5338 return -EINVAL;
5339 }
5340
5341 pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
5342 if (!pAdapter) {
5343 hddLog(VOS_TRACE_LEVEL_ERROR, FL("HDD adpater is NULL"));
5344 return -EINVAL;
5345 }
5346
Atul Mittal115287b2014-07-08 13:26:33 +05305347 status = wlan_hdd_validate_context(pHddCtx);
5348 if (0 != status) {
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +05305349 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Invalid HDD context"));
Atul Mittal115287b2014-07-08 13:26:33 +05305350 return -EINVAL;
5351 }
5352 if (pHddCtx->cfg_ini->fTDLSExternalControl == FALSE) {
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +05305353 hddLog(VOS_TRACE_LEVEL_ERROR, FL("TDLS external control is disabled"));
Atul Mittal115287b2014-07-08 13:26:33 +05305354 return -ENOTSUPP;
5355 }
5356 if (nla_parse(tb, QCA_WLAN_VENDOR_ATTR_TDLS_ENABLE_MAX,
5357 data, data_len,
5358 wlan_hdd_tdls_config_enable_policy)) {
5359 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Invalid ATTR"));
5360 return -EINVAL;
5361 }
5362
5363 /* Parse and fetch mac address */
5364 if (!tb[QCA_WLAN_VENDOR_ATTR_TDLS_ENABLE_MAC_ADDR]) {
5365 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr mac addr failed"));
5366 return -EINVAL;
5367 }
5368
5369 memcpy(peer, nla_data(
5370 tb[QCA_WLAN_VENDOR_ATTR_TDLS_ENABLE_MAC_ADDR]),
5371 sizeof(peer));
5372 hddLog(VOS_TRACE_LEVEL_INFO, FL(MAC_ADDRESS_STR),MAC_ADDR_ARRAY(peer));
5373
5374 /* Parse and fetch channel */
5375 if (!tb[QCA_WLAN_VENDOR_ATTR_TDLS_ENABLE_CHANNEL]) {
5376 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr channel failed"));
5377 return -EINVAL;
5378 }
5379 pReqMsg.channel = nla_get_s32(
5380 tb[QCA_WLAN_VENDOR_ATTR_TDLS_ENABLE_CHANNEL]);
5381 hddLog(VOS_TRACE_LEVEL_INFO, FL("Channel Num (%d)"), pReqMsg.channel);
5382
5383 /* Parse and fetch global operating class */
5384 if (!tb[QCA_WLAN_VENDOR_ATTR_TDLS_ENABLE_GLOBAL_OPERATING_CLASS]) {
5385 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr operating class failed"));
5386 return -EINVAL;
5387 }
5388 pReqMsg.global_operating_class = nla_get_s32(
5389 tb[QCA_WLAN_VENDOR_ATTR_TDLS_ENABLE_GLOBAL_OPERATING_CLASS]);
5390 hddLog(VOS_TRACE_LEVEL_INFO, FL("Operating class (%d)"),
5391 pReqMsg.global_operating_class);
5392
5393 /* Parse and fetch latency ms */
5394 if (!tb[QCA_WLAN_VENDOR_ATTR_TDLS_ENABLE_MAX_LATENCY_MS]) {
5395 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr latency failed"));
5396 return -EINVAL;
5397 }
5398 pReqMsg.max_latency_ms = nla_get_s32(
5399 tb[QCA_WLAN_VENDOR_ATTR_TDLS_ENABLE_MAX_LATENCY_MS]);
5400 hddLog(VOS_TRACE_LEVEL_INFO, FL("Latency (%d)"),
5401 pReqMsg.max_latency_ms);
5402
5403 /* Parse and fetch required bandwidth kbps */
5404 if (!tb[QCA_WLAN_VENDOR_ATTR_TDLS_ENABLE_MIN_BANDWIDTH_KBPS]) {
5405 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr bandwidth failed"));
5406 return -EINVAL;
5407 }
5408
5409 pReqMsg.min_bandwidth_kbps = nla_get_s32(
5410 tb[QCA_WLAN_VENDOR_ATTR_TDLS_ENABLE_MIN_BANDWIDTH_KBPS]);
5411 hddLog(VOS_TRACE_LEVEL_INFO, FL("Bandwidth (%d)"),
5412 pReqMsg.min_bandwidth_kbps);
5413
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05305414 ret = wlan_hdd_tdls_extctrl_config_peer(pAdapter,
Atul Mittal115287b2014-07-08 13:26:33 +05305415 peer,
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +05305416 &pReqMsg,
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05305417 wlan_hdd_cfg80211_exttdls_callback);
5418
5419 EXIT();
5420 return ret;
Atul Mittal115287b2014-07-08 13:26:33 +05305421}
5422
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05305423static int wlan_hdd_cfg80211_exttdls_enable(struct wiphy *wiphy,
5424 struct wireless_dev *wdev,
5425 const void *data,
5426 int data_len)
5427{
5428 int ret = 0;
5429
5430 vos_ssr_protect(__func__);
5431 ret = __wlan_hdd_cfg80211_exttdls_enable(wiphy, wdev, data, data_len);
5432 vos_ssr_unprotect(__func__);
5433
5434 return ret;
5435}
5436
5437static int __wlan_hdd_cfg80211_exttdls_disable(struct wiphy *wiphy,
Atul Mittal115287b2014-07-08 13:26:33 +05305438 struct wireless_dev *wdev,
Jeff Johnson393c2702014-12-16 11:09:35 +05305439 const void *data,
Atul Mittal115287b2014-07-08 13:26:33 +05305440 int data_len)
5441{
5442 u8 peer[6] = {0};
5443 struct net_device *dev = wdev->netdev;
Atul Mittal115287b2014-07-08 13:26:33 +05305444 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
5445 struct nlattr *tb[QCA_WLAN_VENDOR_ATTR_TDLS_DISABLE_MAX + 1];
5446 eHalStatus status;
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05305447 int ret;
Chandrasekaran, Manishekar41b8e1f2015-03-10 13:30:28 +05305448 hdd_adapter_t *pAdapter;
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05305449
5450 ENTER();
Atul Mittal115287b2014-07-08 13:26:33 +05305451
Chandrasekaran, Manishekar41b8e1f2015-03-10 13:30:28 +05305452 if (!dev) {
5453 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Dev pointer is NULL"));
5454 return -EINVAL;
5455 }
5456
5457 pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
5458 if (!pAdapter) {
5459 hddLog(VOS_TRACE_LEVEL_ERROR, FL("HDD adapter is NULL"));
5460 return -EINVAL;
5461 }
5462
Atul Mittal115287b2014-07-08 13:26:33 +05305463 status = wlan_hdd_validate_context(pHddCtx);
5464 if (0 != status) {
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +05305465 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Invalid HDD context"));
Atul Mittal115287b2014-07-08 13:26:33 +05305466 return -EINVAL;
5467 }
5468 if (pHddCtx->cfg_ini->fTDLSExternalControl == FALSE) {
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +05305469 hddLog(VOS_TRACE_LEVEL_ERROR, FL("TDLS external control is disabled"));
Atul Mittal115287b2014-07-08 13:26:33 +05305470 return -ENOTSUPP;
5471 }
5472 if (nla_parse(tb, QCA_WLAN_VENDOR_ATTR_TDLS_DISABLE_MAX,
5473 data, data_len,
5474 wlan_hdd_tdls_config_disable_policy)) {
5475 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Invalid ATTR"));
5476 return -EINVAL;
5477 }
5478 /* Parse and fetch mac address */
5479 if (!tb[QCA_WLAN_VENDOR_ATTR_TDLS_DISABLE_MAC_ADDR]) {
5480 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr mac addr failed"));
5481 return -EINVAL;
5482 }
5483
5484 memcpy(peer, nla_data(
5485 tb[QCA_WLAN_VENDOR_ATTR_TDLS_DISABLE_MAC_ADDR]),
5486 sizeof(peer));
5487 hddLog(VOS_TRACE_LEVEL_INFO, FL(MAC_ADDRESS_STR),MAC_ADDR_ARRAY(peer));
5488
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05305489 ret = wlan_hdd_tdls_extctrl_deconfig_peer(pAdapter, peer);
5490
5491 EXIT();
5492 return ret;
Atul Mittal115287b2014-07-08 13:26:33 +05305493}
5494
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05305495static int wlan_hdd_cfg80211_exttdls_disable(struct wiphy *wiphy,
5496 struct wireless_dev *wdev,
5497 const void *data,
5498 int data_len)
5499{
5500 int ret = 0;
5501
5502 vos_ssr_protect(__func__);
5503 ret = __wlan_hdd_cfg80211_exttdls_disable(wiphy, wdev, data, data_len);
5504 vos_ssr_unprotect(__func__);
5505
5506 return ret;
5507}
5508
Dasari Srinivas7875a302014-09-26 17:50:57 +05305509static int
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05305510__wlan_hdd_cfg80211_get_supported_features(struct wiphy *wiphy,
Dasari Srinivas7875a302014-09-26 17:50:57 +05305511 struct wireless_dev *wdev,
Jeff Johnson393c2702014-12-16 11:09:35 +05305512 const void *data, int data_len)
Dasari Srinivas7875a302014-09-26 17:50:57 +05305513{
5514 struct net_device *dev = wdev->netdev;
5515 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
5516 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
5517 struct sk_buff *skb = NULL;
5518 tANI_U32 fset = 0;
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05305519 int ret = 0;
Dasari Srinivas7875a302014-09-26 17:50:57 +05305520
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05305521 ENTER();
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05305522
5523 ret = wlan_hdd_validate_context(pHddCtx);
5524 if (0 != ret)
5525 {
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05305526 return ret;
5527 }
Dasari Srinivas7875a302014-09-26 17:50:57 +05305528 if (wiphy->interface_modes & BIT(NL80211_IFTYPE_STATION)) {
5529 hddLog(LOG1, FL("Infra Station mode is supported by driver"));
5530 fset |= WIFI_FEATURE_INFRA;
5531 }
5532
5533 if (TRUE == hdd_is_5g_supported(pHddCtx)) {
5534 hddLog(LOG1, FL("INFRA_5G is supported by firmware"));
5535 fset |= WIFI_FEATURE_INFRA_5G;
5536 }
5537
5538#ifdef WLAN_FEATURE_P2P
5539 if ((wiphy->interface_modes & BIT(NL80211_IFTYPE_P2P_CLIENT)) &&
5540 (wiphy->interface_modes & BIT(NL80211_IFTYPE_P2P_GO))) {
5541 hddLog(LOG1, FL("WiFi-Direct is supported by driver"));
5542 fset |= WIFI_FEATURE_P2P;
5543 }
5544#endif
5545
5546 /* Soft-AP is supported currently by default */
5547 fset |= WIFI_FEATURE_SOFT_AP;
5548
Kanchanapally, Vidyullatha683aed02015-03-24 16:58:38 +05305549 /* HOTSPOT is a supplicant feature, enable it by default */
5550 fset |= WIFI_FEATURE_HOTSPOT;
5551
Dasari Srinivas7875a302014-09-26 17:50:57 +05305552#ifdef WLAN_FEATURE_EXTSCAN
5553 if ((TRUE == pHddCtx->cfg_ini->fEnableEXTScan) &&
Padma, Santhosh Kumar2ac54992015-10-12 18:20:58 +05305554 sme_IsFeatureSupportedByFW(EXTENDED_SCAN) &&
5555 sme_IsFeatureSupportedByFW(EXT_SCAN_ENHANCED)) {
5556 hddLog(LOG1, FL("Enhanced EXTScan is supported by firmware"));
Dasari Srinivas7875a302014-09-26 17:50:57 +05305557 fset |= WIFI_FEATURE_EXTSCAN;
5558 }
5559#endif
5560
Dasari Srinivas7875a302014-09-26 17:50:57 +05305561 if (sme_IsFeatureSupportedByFW(NAN)) {
5562 hddLog(LOG1, FL("NAN is supported by firmware"));
5563 fset |= WIFI_FEATURE_NAN;
5564 }
Dasari Srinivas7875a302014-09-26 17:50:57 +05305565
5566 /* D2D RTT is not supported currently by default */
5567 if (sme_IsFeatureSupportedByFW(RTT)) {
5568 hddLog(LOG1, FL("RTT is supported by firmware"));
5569 fset |= WIFI_FEATURE_D2AP_RTT;
5570 }
5571
5572#ifdef FEATURE_WLAN_BATCH_SCAN
5573 if (fset & WIFI_FEATURE_EXTSCAN) {
5574 hddLog(LOG1, FL("Batch scan is supported as extscan is supported"));
5575 fset &= ~WIFI_FEATURE_BATCH_SCAN;
5576 } else if (sme_IsFeatureSupportedByFW(BATCH_SCAN)) {
5577 hddLog(LOG1, FL("Batch scan is supported by firmware"));
5578 fset |= WIFI_FEATURE_BATCH_SCAN;
5579 }
5580#endif
5581
5582#ifdef FEATURE_WLAN_SCAN_PNO
5583 if (pHddCtx->cfg_ini->configPNOScanSupport &&
5584 (eHAL_STATUS_SUCCESS == wlan_hdd_is_pno_allowed(pAdapter))) {
5585 hddLog(LOG1, FL("PNO is supported by firmware"));
5586 fset |= WIFI_FEATURE_PNO;
5587 }
5588#endif
5589
5590 /* STA+STA is supported currently by default */
5591 fset |= WIFI_FEATURE_ADDITIONAL_STA;
5592
5593#ifdef FEATURE_WLAN_TDLS
5594 if ((TRUE == pHddCtx->cfg_ini->fEnableTDLSSupport) &&
5595 sme_IsFeatureSupportedByFW(TDLS)) {
5596 hddLog(LOG1, FL("TDLS is supported by firmware"));
5597 fset |= WIFI_FEATURE_TDLS;
5598 }
5599
5600 /* TDLS_OFFCHANNEL is not supported currently by default */
5601#endif
5602
5603#ifdef WLAN_AP_STA_CONCURRENCY
5604 /* AP+STA concurrency is supported currently by default */
5605 fset |= WIFI_FEATURE_AP_STA;
5606#endif
5607
Mukul Sharma5add0532015-08-17 15:57:47 +05305608#ifdef WLAN_FEATURE_LINK_LAYER_STATS
5609 fset |= WIFI_FEATURE_LINK_LAYER_STATS;
5610 hddLog(LOG1, FL("Link layer stats is supported by driver"));
5611#endif
5612
Dasari Srinivas7875a302014-09-26 17:50:57 +05305613 skb = cfg80211_vendor_cmd_alloc_reply_skb(wiphy, sizeof(fset) +
5614 NLMSG_HDRLEN);
5615
5616 if (!skb) {
5617 hddLog(LOGE, FL("cfg80211_vendor_cmd_alloc_reply_skb failed"));
5618 return -EINVAL;
5619 }
5620 hddLog(LOG1, FL("Supported Features : 0x%x"), fset);
5621
5622 if (nla_put_u32(skb, QCA_WLAN_VENDOR_ATTR_FEATURE_SET, fset)) {
5623 hddLog(LOGE, FL("nla put fail"));
5624 goto nla_put_failure;
5625 }
5626
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05305627 ret = cfg80211_vendor_cmd_reply(skb);
5628 EXIT();
5629 return ret;
Dasari Srinivas7875a302014-09-26 17:50:57 +05305630
5631nla_put_failure:
5632 kfree_skb(skb);
5633 return -EINVAL;
5634}
5635
Dasari Srinivase18b2cf2014-10-28 17:09:42 +05305636static int
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05305637wlan_hdd_cfg80211_get_supported_features(struct wiphy *wiphy,
5638 struct wireless_dev *wdev,
5639 const void *data, int data_len)
5640{
5641 int ret = 0;
5642
5643 vos_ssr_protect(__func__);
5644 ret = __wlan_hdd_cfg80211_get_supported_features(wiphy, wdev, data, data_len);
5645 vos_ssr_unprotect(__func__);
5646
5647 return ret;
5648}
5649
Sachin Ahujac08f72a2015-09-22 15:25:47 +05305650
5651static const struct
5652nla_policy
5653qca_wlan_vendor_wifi_logger_get_ring_data_policy
5654[QCA_WLAN_VENDOR_ATTR_WIFI_LOGGER_GET_RING_DATA_MAX + 1] = {
5655 [QCA_WLAN_VENDOR_ATTR_WIFI_LOGGER_GET_RING_DATA_ID]
5656 = {.type = NLA_U32 },
5657};
5658
5659static int
5660 __wlan_hdd_cfg80211_wifi_logger_get_ring_data(struct wiphy *wiphy,
5661 struct wireless_dev *wdev,
5662 const void *data,
5663 int data_len)
5664{
5665 int ret;
5666 VOS_STATUS status;
5667 uint32_t ring_id;
5668 hdd_context_t *hdd_ctx = wiphy_priv(wiphy);
5669 struct nlattr *tb
5670 [QCA_WLAN_VENDOR_ATTR_WIFI_LOGGER_GET_RING_DATA_MAX + 1];
5671
5672 ENTER();
5673
5674 ret = wlan_hdd_validate_context(hdd_ctx);
5675 if (0 != ret) {
5676 return ret;
5677 }
5678
5679 if (nla_parse(tb, QCA_WLAN_VENDOR_ATTR_WIFI_LOGGER_GET_RING_DATA_MAX,
5680 data, data_len,
5681 qca_wlan_vendor_wifi_logger_get_ring_data_policy)) {
5682 hddLog(LOGE, FL("Invalid attribute"));
5683 return -EINVAL;
5684 }
5685
5686 /* Parse and fetch ring id */
5687 if (!tb[QCA_WLAN_VENDOR_ATTR_WIFI_LOGGER_GET_RING_DATA_ID]) {
5688 hddLog(LOGE, FL("attr ATTR failed"));
5689 return -EINVAL;
5690 }
5691
5692 ring_id = nla_get_u32(
5693 tb[QCA_WLAN_VENDOR_ATTR_WIFI_LOGGER_GET_RING_DATA_ID]);
5694
5695 hddLog(LOG1, FL("Bug report triggered by framework"));
5696
5697 status = vos_fatal_event_logs_req(WLAN_LOG_TYPE_NON_FATAL,
5698 WLAN_LOG_INDICATOR_FRAMEWORK,
5699 WLAN_LOG_REASON_CODE_FRAMEWORK,
Abhishek Singh837adf22015-10-01 17:37:37 +05305700 TRUE, TRUE
Sachin Ahujac08f72a2015-09-22 15:25:47 +05305701 );
5702 if (VOS_STATUS_SUCCESS != status) {
5703 hddLog(LOGE, FL("Failed to trigger bug report"));
5704
5705 return -EINVAL;
5706 }
5707
5708 return 0;
5709
5710
5711}
5712
5713
5714static int
5715 wlan_hdd_cfg80211_wifi_logger_get_ring_data(struct wiphy *wiphy,
5716 struct wireless_dev *wdev,
5717 const void *data,
5718 int data_len)
5719{
5720 int ret = 0;
5721
5722 vos_ssr_protect(__func__);
5723 ret = __wlan_hdd_cfg80211_wifi_logger_get_ring_data(wiphy,
5724 wdev, data, data_len);
5725 vos_ssr_unprotect(__func__);
5726
5727 return ret;
5728
5729}
5730
5731
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05305732static int
5733__wlan_hdd_cfg80211_get_concurrency_matrix(struct wiphy *wiphy,
Dasari Srinivase18b2cf2014-10-28 17:09:42 +05305734 struct wireless_dev *wdev,
Jeff Johnson393c2702014-12-16 11:09:35 +05305735 const void *data, int data_len)
Dasari Srinivase18b2cf2014-10-28 17:09:42 +05305736{
5737 uint32_t feature_set_matrix[WLAN_HDD_MAX_FEATURE_SET] = {0};
5738 uint8_t i, feature_sets, max_feature_sets;
5739 struct nlattr *tb[QCA_WLAN_VENDOR_ATTR_GET_CONCURRENCY_MATRIX_MAX + 1];
5740 struct sk_buff *reply_skb;
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05305741 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
5742 int ret;
Dasari Srinivase18b2cf2014-10-28 17:09:42 +05305743
5744 ENTER();
5745
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05305746 ret = wlan_hdd_validate_context(pHddCtx);
5747 if (0 != ret)
5748 {
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05305749 return ret;
5750 }
5751
Dasari Srinivase18b2cf2014-10-28 17:09:42 +05305752 if (nla_parse(tb, QCA_WLAN_VENDOR_ATTR_GET_CONCURRENCY_MATRIX_MAX,
5753 data, data_len, NULL)) {
5754 hddLog(LOGE, FL("Invalid ATTR"));
5755 return -EINVAL;
5756 }
5757
5758 /* Parse and fetch max feature set */
5759 if (!tb[QCA_WLAN_VENDOR_ATTR_GET_CONCURRENCY_MATRIX_CONFIG_PARAM_SET_SIZE_MAX]) {
5760 hddLog(LOGE, FL("Attr max feature set size failed"));
5761 return -EINVAL;
5762 }
5763 max_feature_sets = nla_get_u32(
5764 tb[QCA_WLAN_VENDOR_ATTR_GET_CONCURRENCY_MATRIX_CONFIG_PARAM_SET_SIZE_MAX]);
5765 hddLog(LOG1, FL("Max feature set size (%d)"), max_feature_sets);
5766
5767 /* Fill feature combination matrix */
5768 feature_sets = 0;
Dasari Srinivase18b2cf2014-10-28 17:09:42 +05305769 feature_set_matrix[feature_sets++] = WIFI_FEATURE_INFRA |
5770 WIFI_FEATURE_P2P;
5771
Dasari Srinivase18b2cf2014-10-28 17:09:42 +05305772 feature_set_matrix[feature_sets++] = WIFI_FEATURE_INFRA |
5773 WIFI_FEATURE_SOFT_AP;
5774
Dasari Srinivase18b2cf2014-10-28 17:09:42 +05305775 feature_set_matrix[feature_sets++] = WIFI_FEATURE_P2P |
5776 WIFI_FEATURE_SOFT_AP;
5777
Dasari Srinivase18b2cf2014-10-28 17:09:42 +05305778 feature_set_matrix[feature_sets++] = WIFI_FEATURE_INFRA |
5779 WIFI_FEATURE_SOFT_AP |
5780 WIFI_FEATURE_P2P;
5781
5782 /* Add more feature combinations here */
5783
5784 feature_sets = VOS_MIN(feature_sets, max_feature_sets);
5785 hddLog(LOG1, FL("Number of feature sets (%d)"), feature_sets);
5786 hddLog(LOG1, "Feature set matrix");
5787 for (i = 0; i < feature_sets; i++)
5788 hddLog(LOG1, "[%d] 0x%02X", i, feature_set_matrix[i]);
5789
5790 reply_skb = cfg80211_vendor_cmd_alloc_reply_skb(wiphy, sizeof(u32) +
5791 sizeof(u32) * feature_sets +
5792 NLMSG_HDRLEN);
5793
5794 if (reply_skb) {
5795 if (nla_put_u32(reply_skb,
5796 QCA_WLAN_VENDOR_ATTR_GET_CONCURRENCY_MATRIX_RESULTS_SET_SIZE,
5797 feature_sets) ||
5798 nla_put(reply_skb,
5799 QCA_WLAN_VENDOR_ATTR_GET_CONCURRENCY_MATRIX_RESULTS_SET,
5800 sizeof(u32) * feature_sets, feature_set_matrix)) {
5801 hddLog(LOGE, FL("nla put fail"));
5802 kfree_skb(reply_skb);
5803 return -EINVAL;
5804 }
5805
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05305806 ret = cfg80211_vendor_cmd_reply(reply_skb);
5807 EXIT();
5808 return ret;
Dasari Srinivase18b2cf2014-10-28 17:09:42 +05305809 }
5810 hddLog(LOGE, FL("Feature set matrix: buffer alloc fail"));
5811 return -ENOMEM;
5812
Dasari Srinivase18b2cf2014-10-28 17:09:42 +05305813}
5814
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05305815static int
5816wlan_hdd_cfg80211_get_concurrency_matrix(struct wiphy *wiphy,
5817 struct wireless_dev *wdev,
5818 const void *data, int data_len)
5819{
5820 int ret = 0;
5821
5822 vos_ssr_protect(__func__);
5823 ret = __wlan_hdd_cfg80211_get_concurrency_matrix(wiphy, wdev, data,
5824 data_len);
5825 vos_ssr_unprotect(__func__);
5826
5827 return ret;
5828}
5829
c_manjeecfd1efb2015-09-25 19:32:34 +05305830
5831static int
5832__wlan_hdd_cfg80211_get_fw_mem_dump(struct wiphy *wiphy,
5833 struct wireless_dev *wdev,
5834 const void *data, int data_len)
5835{
5836 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
5837 int ret;
5838 ENTER();
5839
5840 ret = wlan_hdd_validate_context(pHddCtx);
5841 if (0 != ret)
5842 {
5843 return ret;
5844 }
5845
5846 if( !pHddCtx->cfg_ini->enableFwrMemDump ||
5847 (FALSE == sme_IsFeatureSupportedByFW(MEMORY_DUMP_SUPPORTED)))
5848 {
5849 hddLog(VOS_TRACE_LEVEL_INFO, FL("FW dump Logging not supported"));
5850 return -EINVAL;
5851 }
5852 /*call common API for FW mem dump req*/
5853 ret = wlan_hdd_fw_mem_dump_req(pHddCtx);
5854
5855 EXIT();
5856 return ret;
5857}
5858
5859/**
5860 * wlan_hdd_cfg80211_get_fw_mem_dump() - Get FW memory dump
5861 * @wiphy: pointer to wireless wiphy structure.
5862 * @wdev: pointer to wireless_dev structure.
5863 * @data: Pointer to the NL data.
5864 * @data_len:Length of @data
5865 *
5866 * This is called when wlan driver needs to get the firmware memory dump
5867 * via vendor specific command.
5868 *
5869 * Return: 0 on success, error number otherwise.
5870 */
5871
5872static int
5873wlan_hdd_cfg80211_get_fw_mem_dump(struct wiphy *wiphy,
5874 struct wireless_dev *wdev,
5875 const void *data, int data_len)
Sushant Kaushik8e644982015-09-23 12:18:54 +05305876{
5877 int ret = 0;
5878 vos_ssr_protect(__func__);
5879 ret = __wlan_hdd_cfg80211_get_fw_mem_dump(wiphy, wdev, data,
5880 data_len);
5881 vos_ssr_unprotect(__func__);
5882 return ret;
5883}
c_manjeecfd1efb2015-09-25 19:32:34 +05305884
Sushant Kaushik8e644982015-09-23 12:18:54 +05305885static const struct
5886nla_policy
5887qca_wlan_vendor_wifi_logger_start_policy
5888[QCA_WLAN_VENDOR_ATTR_WIFI_LOGGER_START_MAX + 1] = {
5889 [QCA_WLAN_VENDOR_ATTR_WIFI_LOGGER_RING_ID]
5890 = {.type = NLA_U32 },
5891 [QCA_WLAN_VENDOR_ATTR_WIFI_LOGGER_VERBOSE_LEVEL]
5892 = {.type = NLA_U32 },
5893 [QCA_WLAN_VENDOR_ATTR_WIFI_LOGGER_FLAGS]
5894 = {.type = NLA_U32 },
5895};
5896
5897/**
5898 * __wlan_hdd_cfg80211_wifi_logger_start() - This function is used to enable
5899 * or disable the collection of packet statistics from the firmware
5900 * @wiphy: WIPHY structure pointer
5901 * @wdev: Wireless device structure pointer
5902 * @data: Pointer to the data received
5903 * @data_len: Length of the data received
5904 *
5905 * This function is used to enable or disable the collection of packet
5906 * statistics from the firmware
5907 *
5908 * Return: 0 on success and errno on failure
5909 */
5910static int __wlan_hdd_cfg80211_wifi_logger_start(struct wiphy *wiphy,
5911 struct wireless_dev *wdev,
5912 const void *data,
5913 int data_len)
5914{
5915 eHalStatus status;
5916 hdd_context_t *hdd_ctx = wiphy_priv(wiphy);
5917 struct nlattr *tb[QCA_WLAN_VENDOR_ATTR_WIFI_LOGGER_START_MAX + 1];
5918 tAniWifiStartLog start_log;
5919
5920 status = wlan_hdd_validate_context(hdd_ctx);
5921 if (0 != status) {
5922 return -EINVAL;
5923 }
5924
5925 if (nla_parse(tb, QCA_WLAN_VENDOR_ATTR_WIFI_LOGGER_START_MAX,
5926 data, data_len,
5927 qca_wlan_vendor_wifi_logger_start_policy)) {
5928 hddLog(LOGE, FL("Invalid attribute"));
5929 return -EINVAL;
5930 }
5931
5932 /* Parse and fetch ring id */
5933 if (!tb[QCA_WLAN_VENDOR_ATTR_WIFI_LOGGER_RING_ID]) {
5934 hddLog(LOGE, FL("attr ATTR failed"));
5935 return -EINVAL;
5936 }
5937 start_log.ringId = nla_get_u32(
5938 tb[QCA_WLAN_VENDOR_ATTR_WIFI_LOGGER_RING_ID]);
5939 hddLog(LOG1, FL("Ring ID=%d"), start_log.ringId);
5940
5941 /* Parse and fetch verbose level */
5942 if (!tb[QCA_WLAN_VENDOR_ATTR_WIFI_LOGGER_VERBOSE_LEVEL]) {
5943 hddLog(LOGE, FL("attr verbose_level failed"));
5944 return -EINVAL;
5945 }
5946 start_log.verboseLevel = nla_get_u32(
5947 tb[QCA_WLAN_VENDOR_ATTR_WIFI_LOGGER_VERBOSE_LEVEL]);
5948 hddLog(LOG1, FL("verbose_level=%d"), start_log.verboseLevel);
5949
5950 /* Parse and fetch flag */
5951 if (!tb[QCA_WLAN_VENDOR_ATTR_WIFI_LOGGER_FLAGS]) {
5952 hddLog(LOGE, FL("attr flag failed"));
5953 return -EINVAL;
5954 }
5955 start_log.flag = nla_get_u32(
5956 tb[QCA_WLAN_VENDOR_ATTR_WIFI_LOGGER_FLAGS]);
5957 hddLog(LOG1, FL("flag=%d"), start_log.flag);
5958
5959 if ((RING_ID_PER_PACKET_STATS == start_log.ringId) &&
Sushant Kaushik33200572015-08-05 16:46:20 +05305960 (!hdd_ctx->cfg_ini->wlanPerPktStatsLogEnable ||
5961 !vos_isPktStatsEnabled()))
5962
Sushant Kaushik8e644982015-09-23 12:18:54 +05305963 {
5964 hddLog(LOGE, FL("per pkt stats not enabled"));
5965 return -EINVAL;
5966 }
Sushant Kaushik8e644982015-09-23 12:18:54 +05305967
Sushant Kaushik33200572015-08-05 16:46:20 +05305968 vos_set_ring_log_level(start_log.ringId, start_log.verboseLevel);
Sushant Kaushik8e644982015-09-23 12:18:54 +05305969 return 0;
5970}
5971
5972/**
5973 * wlan_hdd_cfg80211_wifi_logger_start() - Wrapper function used to enable
5974 * or disable the collection of packet statistics from the firmware
5975 * @wiphy: WIPHY structure pointer
5976 * @wdev: Wireless device structure pointer
5977 * @data: Pointer to the data received
5978 * @data_len: Length of the data received
5979 *
5980 * This function is used to enable or disable the collection of packet
5981 * statistics from the firmware
5982 *
5983 * Return: 0 on success and errno on failure
5984 */
5985static int wlan_hdd_cfg80211_wifi_logger_start(struct wiphy *wiphy,
5986 struct wireless_dev *wdev,
5987 const void *data,
5988 int data_len)
c_manjeecfd1efb2015-09-25 19:32:34 +05305989{
5990 int ret = 0;
5991
5992 vos_ssr_protect(__func__);
Sushant Kaushik8e644982015-09-23 12:18:54 +05305993
5994 ret = __wlan_hdd_cfg80211_wifi_logger_start(wiphy,
5995 wdev, data, data_len);
c_manjeecfd1efb2015-09-25 19:32:34 +05305996 vos_ssr_unprotect(__func__);
5997
5998 return ret;
c_manjeecfd1efb2015-09-25 19:32:34 +05305999}
6000
6001
Agarwal Ashish738843c2014-09-25 12:27:56 +05306002static const struct nla_policy
6003wlan_hdd_set_no_dfs_flag_config_policy[QCA_WLAN_VENDOR_ATTR_SET_NO_DFS_FLAG_MAX
6004 +1] =
6005{
6006 [QCA_WLAN_VENDOR_ATTR_SET_NO_DFS_FLAG] = {.type = NLA_U32 },
6007};
6008
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05306009static int __wlan_hdd_cfg80211_disable_dfs_channels(struct wiphy *wiphy,
Agarwal Ashish738843c2014-09-25 12:27:56 +05306010 struct wireless_dev *wdev,
Jeff Johnson393c2702014-12-16 11:09:35 +05306011 const void *data,
Agarwal Ashish738843c2014-09-25 12:27:56 +05306012 int data_len)
6013{
6014 struct net_device *dev = wdev->netdev;
6015 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
6016 tHalHandle hHal = WLAN_HDD_GET_HAL_CTX(pAdapter);
6017 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
6018 struct nlattr *tb[QCA_WLAN_VENDOR_ATTR_SET_NO_DFS_FLAG_MAX + 1];
6019 eHalStatus status;
6020 u32 dfsFlag = 0;
6021
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05306022 ENTER();
6023
Agarwal Ashish738843c2014-09-25 12:27:56 +05306024 status = wlan_hdd_validate_context(pHddCtx);
6025 if (0 != status) {
Agarwal Ashish738843c2014-09-25 12:27:56 +05306026 return -EINVAL;
6027 }
6028 if (nla_parse(tb, QCA_WLAN_VENDOR_ATTR_SET_NO_DFS_FLAG_MAX,
6029 data, data_len,
6030 wlan_hdd_set_no_dfs_flag_config_policy)) {
6031 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Invalid ATTR"));
6032 return -EINVAL;
6033 }
6034
6035 /* Parse and fetch required bandwidth kbps */
6036 if (!tb[QCA_WLAN_VENDOR_ATTR_SET_NO_DFS_FLAG]) {
6037 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr dfs flag failed"));
6038 return -EINVAL;
6039 }
6040
6041 dfsFlag = nla_get_u32(
6042 tb[QCA_WLAN_VENDOR_ATTR_SET_NO_DFS_FLAG]);
6043 hddLog(VOS_TRACE_LEVEL_INFO, FL(" DFS flag (%d)"),
6044 dfsFlag);
6045
6046 pHddCtx->disable_dfs_flag = dfsFlag;
6047
6048 sme_disable_dfs_channel(hHal, dfsFlag);
6049 sme_FilterScanResults(hHal, pAdapter->sessionId);
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05306050
6051 EXIT();
Agarwal Ashish738843c2014-09-25 12:27:56 +05306052 return 0;
6053}
Atul Mittal115287b2014-07-08 13:26:33 +05306054
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05306055static int wlan_hdd_cfg80211_disable_dfs_channels(struct wiphy *wiphy,
6056 struct wireless_dev *wdev,
6057 const void *data,
6058 int data_len)
6059{
6060 int ret = 0;
6061
6062 vos_ssr_protect(__func__);
6063 ret = __wlan_hdd_cfg80211_disable_dfs_channels(wiphy, wdev, data, data_len);
6064 vos_ssr_unprotect(__func__);
6065
6066 return ret;
6067
6068}
6069
Mukul Sharma2a271632014-10-13 14:59:01 +05306070const struct
6071nla_policy qca_wlan_vendor_attr[QCA_WLAN_VENDOR_ATTR_MAX+1] =
6072{
6073 [QCA_WLAN_VENDOR_ATTR_ROAMING_POLICY] = { .type = NLA_U32 },
6074 [QCA_WLAN_VENDOR_ATTR_MAC_ADDR] = { .type = NLA_UNSPEC },
6075};
6076
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05306077static int __wlan_hdd_cfg80211_firmware_roaming(struct wiphy *wiphy,
Jeff Johnson393c2702014-12-16 11:09:35 +05306078 struct wireless_dev *wdev, const void *data, int data_len)
Mukul Sharma2a271632014-10-13 14:59:01 +05306079{
6080
6081 u8 bssid[6] = {0};
6082 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
6083 struct nlattr *tb[QCA_WLAN_VENDOR_ATTR_MAX + 1];
6084 eHalStatus status = eHAL_STATUS_SUCCESS;
6085 v_U32_t isFwrRoamEnabled = FALSE;
6086 int ret;
6087
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05306088 ENTER();
6089
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05306090 ret = wlan_hdd_validate_context(pHddCtx);
6091 if (0 != ret) {
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05306092 return ret;
Mukul Sharma2a271632014-10-13 14:59:01 +05306093 }
6094
6095 ret = nla_parse(tb, QCA_WLAN_VENDOR_ATTR_MAX,
6096 data, data_len,
6097 qca_wlan_vendor_attr);
6098 if (ret){
6099 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Invalid ATTR"));
6100 return -EINVAL;
6101 }
6102
6103 /* Parse and fetch Enable flag */
6104 if (!tb[QCA_WLAN_VENDOR_ATTR_ROAMING_POLICY]) {
6105 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr enable failed"));
6106 return -EINVAL;
6107 }
6108
6109 isFwrRoamEnabled = nla_get_u32(
6110 tb[QCA_WLAN_VENDOR_ATTR_ROAMING_POLICY]);
6111
6112 hddLog(VOS_TRACE_LEVEL_INFO, FL("isFwrRoamEnabled (%d)"), isFwrRoamEnabled);
6113
6114 /* Parse and fetch bssid */
6115 if (!tb[QCA_WLAN_VENDOR_ATTR_MAC_ADDR]) {
6116 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr bss id failed"));
6117 return -EINVAL;
6118 }
6119
6120 memcpy(bssid, nla_data(
6121 tb[QCA_WLAN_VENDOR_ATTR_MAC_ADDR]),
6122 sizeof(bssid));
6123 hddLog(VOS_TRACE_LEVEL_INFO, FL(MAC_ADDRESS_STR),MAC_ADDR_ARRAY(bssid));
6124
6125 //Update roaming
6126 status = sme_ConfigFwrRoaming((tHalHandle)(pHddCtx->hHal), isFwrRoamEnabled);
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05306127 EXIT();
Mukul Sharma2a271632014-10-13 14:59:01 +05306128 return status;
6129}
6130
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05306131static int wlan_hdd_cfg80211_firmware_roaming(struct wiphy *wiphy,
6132 struct wireless_dev *wdev, const void *data, int data_len)
6133{
6134 int ret = 0;
6135
6136 vos_ssr_protect(__func__);
6137 ret = __wlan_hdd_cfg80211_firmware_roaming(wiphy, wdev, data, data_len);
6138 vos_ssr_unprotect(__func__);
6139
6140 return ret;
6141}
6142
Sushant Kaushik847890c2015-09-28 16:05:17 +05306143static const struct
6144nla_policy
6145qca_wlan_vendor_get_wifi_info_policy[
6146 QCA_WLAN_VENDOR_ATTR_WIFI_INFO_GET_MAX +1] = {
6147 [QCA_WLAN_VENDOR_ATTR_WIFI_INFO_DRIVER_VERSION] = {.type = NLA_U8 },
6148 [QCA_WLAN_VENDOR_ATTR_WIFI_INFO_FIRMWARE_VERSION] = {.type = NLA_U8 },
6149};
6150
6151
6152/**
6153 * __wlan_hdd_cfg80211_get_wifi_info() - Get the wifi driver related info
6154 * @wiphy: pointer to wireless wiphy structure.
6155 * @wdev: pointer to wireless_dev structure.
6156 * @data: Pointer to the data to be passed via vendor interface
6157 * @data_len:Length of the data to be passed
6158 *
6159 * This is called when wlan driver needs to send wifi driver related info
6160 * (driver/fw version) to the user space application upon request.
6161 *
6162 * Return: Return the Success or Failure code.
6163 */
6164static int __wlan_hdd_cfg80211_get_wifi_info(struct wiphy *wiphy,
6165 struct wireless_dev *wdev,
6166 const void *data, int data_len)
6167{
6168 hdd_context_t *hdd_ctx = wiphy_priv(wiphy);
6169 struct nlattr *tb_vendor[QCA_WLAN_VENDOR_ATTR_WIFI_INFO_GET_MAX + 1];
6170 tSirVersionString version;
6171 uint32 version_len;
6172 uint8 attr;
6173 int status;
6174 struct sk_buff *reply_skb = NULL;
6175
6176 if (VOS_FTM_MODE == hdd_get_conparam()) {
6177 hddLog(LOGE, FL("Command not allowed in FTM mode"));
6178 return -EINVAL;
6179 }
6180
6181 status = wlan_hdd_validate_context(hdd_ctx);
6182 if (0 != status) {
6183 hddLog(LOGE, FL("HDD context is not valid"));
6184 return -EINVAL;
6185 }
6186
6187 if (nla_parse(tb_vendor, QCA_WLAN_VENDOR_ATTR_WIFI_INFO_GET_MAX, data,
6188 data_len, qca_wlan_vendor_get_wifi_info_policy)) {
6189 hddLog(LOGE, FL("WIFI_INFO_GET NL CMD parsing failed"));
6190 return -EINVAL;
6191 }
6192
6193 if (tb_vendor[QCA_WLAN_VENDOR_ATTR_WIFI_INFO_DRIVER_VERSION]) {
6194 hddLog(LOG1, FL("Rcvd req for Driver version Driver version is %s"),
6195 QWLAN_VERSIONSTR);
6196 strlcpy(version, QWLAN_VERSIONSTR, sizeof(version));
6197 attr = QCA_WLAN_VENDOR_ATTR_WIFI_INFO_DRIVER_VERSION;
6198 } else if (tb_vendor[QCA_WLAN_VENDOR_ATTR_WIFI_INFO_FIRMWARE_VERSION]) {
6199 hddLog(LOG1, FL("Rcvd req for FW version FW version is %s"),
6200 hdd_ctx->fw_Version);
6201 strlcpy(version, hdd_ctx->fw_Version, sizeof(version));
6202 attr = QCA_WLAN_VENDOR_ATTR_WIFI_INFO_FIRMWARE_VERSION;
6203 } else {
6204 hddLog(LOGE, FL("Invalid attribute in get wifi info request"));
6205 return -EINVAL;
6206 }
6207
6208 version_len = strlen(version);
6209 reply_skb = cfg80211_vendor_cmd_alloc_reply_skb(wiphy,
6210 version_len + NLA_HDRLEN + NLMSG_HDRLEN);
6211 if (!reply_skb) {
6212 hddLog(LOGE, FL("cfg80211_vendor_cmd_alloc_reply_skb failed"));
6213 return -ENOMEM;
6214 }
6215
6216 if (nla_put(reply_skb, attr, version_len, version)) {
6217 hddLog(LOGE, FL("nla put fail"));
6218 kfree_skb(reply_skb);
6219 return -EINVAL;
6220 }
6221
6222 return cfg80211_vendor_cmd_reply(reply_skb);
6223}
6224
6225/**
6226 * __wlan_hdd_cfg80211_get_wifi_info() - Get the wifi driver related info
6227 * @wiphy: pointer to wireless wiphy structure.
6228 * @wdev: pointer to wireless_dev structure.
6229 * @data: Pointer to the data to be passed via vendor interface
6230 * @data_len:Length of the data to be passed
6231 * @data_len: Length of the data received
6232 *
6233 * This function is used to enable or disable the collection of packet
6234 * statistics from the firmware
6235 *
6236 * Return: 0 on success and errno on failure
6237 */
6238
6239static int
6240wlan_hdd_cfg80211_get_wifi_info(struct wiphy *wiphy,
6241 struct wireless_dev *wdev,
6242 const void *data, int data_len)
6243
6244
6245{
6246 int ret = 0;
6247
6248 vos_ssr_protect(__func__);
6249 ret = __wlan_hdd_cfg80211_get_wifi_info(wiphy,
6250 wdev, data, data_len);
6251 vos_ssr_unprotect(__func__);
6252
6253 return ret;
6254}
6255
6256
Gupta, Kapil7c34b322015-09-30 13:12:35 +05306257/*
6258 * define short names for the global vendor params
6259 * used by __wlan_hdd_cfg80211_monitor_rssi()
6260 */
6261#define PARAM_MAX QCA_WLAN_VENDOR_ATTR_RSSI_MONITORING_MAX
6262#define PARAM_REQUEST_ID QCA_WLAN_VENDOR_ATTR_RSSI_MONITORING_REQUEST_ID
6263#define PARAM_CONTROL QCA_WLAN_VENDOR_ATTR_RSSI_MONITORING_CONTROL
6264#define PARAM_MIN_RSSI QCA_WLAN_VENDOR_ATTR_RSSI_MONITORING_MIN_RSSI
6265#define PARAM_MAX_RSSI QCA_WLAN_VENDOR_ATTR_RSSI_MONITORING_MAX_RSSI
6266
6267/**---------------------------------------------------------------------------
6268
6269 \brief hdd_rssi_monitor_start_done - callback to be executed when rssi
6270 monitor start is completed successfully.
6271
6272 \return - None
6273
6274 --------------------------------------------------------------------------*/
6275void hdd_rssi_monitor_start_done(void *fwRssiMonitorCbContext, VOS_STATUS status)
6276{
6277 hdd_context_t* pHddCtx = (hdd_context_t*)fwRssiMonitorCbContext;
6278
6279 if (NULL == pHddCtx)
6280 {
6281 hddLog(VOS_TRACE_LEVEL_ERROR,
6282 "%s: HDD context is NULL",__func__);
6283 return;
6284 }
6285
6286 if (VOS_STATUS_SUCCESS == status)
6287 {
6288 hddLog(VOS_TRACE_LEVEL_INFO, FL("Rssi Monitor start successful"));
6289 }
6290 else
6291 {
6292 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Rssi Monitor start not successful"));
6293 }
6294
6295 return;
6296}
6297
6298/**---------------------------------------------------------------------------
6299
6300 \brief hdd_rssi_monitor_stop_done - callback to be executed when rssi monitor
6301 stop is completed successfully.
6302
6303 \return - None
6304
6305 --------------------------------------------------------------------------*/
6306void hdd_rssi_monitor_stop_done(void *fwRssiMonitorCbContext, VOS_STATUS status)
6307{
6308 hdd_context_t* pHddCtx = (hdd_context_t*)fwRssiMonitorCbContext;
6309
6310 if (NULL == pHddCtx)
6311 {
6312 hddLog(VOS_TRACE_LEVEL_ERROR,
6313 "%s: HDD context is NULL",__func__);
6314 return;
6315 }
6316
6317 if (VOS_STATUS_SUCCESS == status)
6318 {
6319 hddLog(VOS_TRACE_LEVEL_INFO, FL("Rssi Monitor stop successful"));
6320 }
6321 else
6322 {
6323 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Rssi Monitor stop not successful"));
6324 }
6325
6326 return;
6327}
6328
6329/**
6330 * __wlan_hdd_cfg80211_monitor_rssi() - monitor rssi
6331 * @wiphy: Pointer to wireless phy
6332 * @wdev: Pointer to wireless device
6333 * @data: Pointer to data
6334 * @data_len: Data length
6335 *
6336 * Return: 0 on success, negative errno on failure
6337 */
6338
6339static int
6340__wlan_hdd_cfg80211_monitor_rssi(struct wiphy *wiphy,
6341 struct wireless_dev *wdev,
6342 const void *data,
6343 int data_len)
6344{
6345 struct net_device *dev = wdev->netdev;
6346 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
6347 hdd_context_t *hdd_ctx = wiphy_priv(wiphy);
6348 hdd_station_ctx_t *pHddStaCtx;
6349 struct nlattr *tb[PARAM_MAX + 1];
6350 tpSirRssiMonitorReq pReq;
6351 eHalStatus status;
6352 int ret;
6353 uint32_t control;
6354 static const struct nla_policy policy[PARAM_MAX + 1] = {
6355 [PARAM_REQUEST_ID] = { .type = NLA_U32 },
6356 [PARAM_CONTROL] = { .type = NLA_U32 },
6357 [PARAM_MIN_RSSI] = { .type = NLA_S8 },
6358 [PARAM_MAX_RSSI] = { .type = NLA_S8 },
6359 };
6360
6361 ENTER();
6362
6363 ret = wlan_hdd_validate_context(hdd_ctx);
6364 if (0 != ret) {
6365 return -EINVAL;
6366 }
6367
6368 if (!hdd_connIsConnected(WLAN_HDD_GET_STATION_CTX_PTR(pAdapter))) {
6369 hddLog(LOGE, FL("Not in Connected state!"));
6370 return -ENOTSUPP;
6371 }
6372
6373 if (nla_parse(tb, PARAM_MAX, data, data_len, policy)) {
6374 hddLog(LOGE, FL("Invalid ATTR"));
6375 return -EINVAL;
6376 }
6377
6378 if (!tb[PARAM_REQUEST_ID]) {
6379 hddLog(LOGE, FL("attr request id failed"));
6380 return -EINVAL;
6381 }
6382
6383 if (!tb[PARAM_CONTROL]) {
6384 hddLog(LOGE, FL("attr control failed"));
6385 return -EINVAL;
6386 }
6387
6388 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
6389
6390 pReq = vos_mem_malloc(sizeof(tSirRssiMonitorReq));
6391 if(NULL == pReq)
6392 {
6393 hddLog(LOGE,
6394 FL("vos_mem_alloc failed "));
6395 return eHAL_STATUS_FAILED_ALLOC;
6396 }
6397 vos_mem_set(pReq, sizeof(tSirRssiMonitorReq), 0);
6398
6399 pReq->requestId = nla_get_u32(tb[PARAM_REQUEST_ID]);
6400 pReq->sessionId = pAdapter->sessionId;
6401 pReq->rssiMonitorCbContext = hdd_ctx;
6402 control = nla_get_u32(tb[PARAM_CONTROL]);
6403 vos_mem_copy( &pReq->currentBssId, pHddStaCtx->conn_info.bssId, WNI_CFG_BSSID_LEN);
6404
6405 hddLog(LOG1, FL("Request Id: %u Session_id: %d Control: %d"),
6406 pReq->requestId, pReq->sessionId, control);
6407
6408 if (control == QCA_WLAN_RSSI_MONITORING_START) {
6409 if (!tb[PARAM_MIN_RSSI]) {
6410 hddLog(LOGE, FL("attr min rssi failed"));
6411 return -EINVAL;
6412 }
6413
6414 if (!tb[PARAM_MAX_RSSI]) {
6415 hddLog(LOGE, FL("attr max rssi failed"));
6416 return -EINVAL;
6417 }
6418
6419 pReq->minRssi = nla_get_s8(tb[PARAM_MIN_RSSI]);
6420 pReq->maxRssi = nla_get_s8(tb[PARAM_MAX_RSSI]);
6421 pReq->rssiMonitorCallback = hdd_rssi_monitor_start_done;
6422
6423 if (!(pReq->minRssi < pReq->maxRssi)) {
6424 hddLog(LOGW, FL("min_rssi: %d must be less than max_rssi: %d"),
6425 pReq->minRssi, pReq->maxRssi);
6426 return -EINVAL;
6427 }
6428 hddLog(LOG1, FL("Min_rssi: %d Max_rssi: %d"),
6429 pReq->minRssi, pReq->maxRssi);
6430 status = sme_StartRssiMonitoring(hdd_ctx->hHal, pReq);
6431
6432 }
6433 else if (control == QCA_WLAN_RSSI_MONITORING_STOP) {
6434 pReq->rssiMonitorCallback = hdd_rssi_monitor_stop_done;
6435 status = sme_StopRssiMonitoring(hdd_ctx->hHal, pReq);
6436 }
6437 else {
6438 hddLog(LOGE, FL("Invalid control cmd: %d"), control);
6439 return -EINVAL;
6440 }
6441
6442 if (!HAL_STATUS_SUCCESS(status)) {
6443 hddLog(LOGE,
6444 FL("sme_set_rssi_monitoring failed(err=%d)"), status);
6445 return -EINVAL;
6446 }
6447
6448 return 0;
6449}
6450
6451/*
6452 * done with short names for the global vendor params
6453 * used by __wlan_hdd_cfg80211_monitor_rssi()
6454 */
6455#undef PARAM_MAX
6456#undef PARAM_CONTROL
6457#undef PARAM_REQUEST_ID
6458#undef PARAM_MAX_RSSI
6459#undef PARAM_MIN_RSSI
6460
6461/**
6462 * wlan_hdd_cfg80211_monitor_rssi() - SSR wrapper to rssi monitoring
6463 * @wiphy: wiphy structure pointer
6464 * @wdev: Wireless device structure pointer
6465 * @data: Pointer to the data received
6466 * @data_len: Length of @data
6467 *
6468 * Return: 0 on success; errno on failure
6469 */
6470static int
6471wlan_hdd_cfg80211_monitor_rssi(struct wiphy *wiphy, struct wireless_dev *wdev,
6472 const void *data, int data_len)
6473{
6474 int ret;
6475
6476 vos_ssr_protect(__func__);
6477 ret = __wlan_hdd_cfg80211_monitor_rssi(wiphy, wdev, data, data_len);
6478 vos_ssr_unprotect(__func__);
6479
6480 return ret;
6481}
6482
6483/**
6484 * hdd_rssi_threshold_breached_cb() - rssi breached NL event
6485 * @hddctx: HDD context
6486 * @data: rssi breached event data
6487 *
6488 * This function reads the rssi breached event %data and fill in the skb with
6489 * NL attributes and send up the NL event.
6490 * This callback execute in atomic context and must not invoke any
6491 * blocking calls.
6492 *
6493 * Return: none
6494 */
6495void hdd_rssi_threshold_breached_cb(void *hddctx,
6496 struct rssi_breach_event *data)
6497{
6498 hdd_context_t *pHddCtx = (hdd_context_t *)hddctx;
6499 int status;
6500 struct sk_buff *skb;
6501
6502 ENTER();
6503 status = wlan_hdd_validate_context(pHddCtx);
6504
6505 if (0 != status) {
6506 return;
6507 }
6508
6509 if (!data) {
6510 hddLog(LOGE, FL("data is null"));
6511 return;
6512 }
6513
6514 skb = cfg80211_vendor_event_alloc(pHddCtx->wiphy,
6515#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 18, 0))
6516 NULL,
6517#endif
6518 EXTSCAN_EVENT_BUF_SIZE + NLMSG_HDRLEN,
6519 QCA_NL80211_VENDOR_SUBCMD_MONITOR_RSSI_INDEX,
6520 GFP_KERNEL);
6521
6522 if (!skb) {
6523 hddLog(LOGE, FL("cfg80211_vendor_event_alloc failed"));
6524 return;
6525 }
6526
6527 hddLog(LOG1, "Req Id: %u Current rssi: %d",
6528 data->request_id, data->curr_rssi);
6529 hddLog(LOG1, "Current BSSID: "MAC_ADDRESS_STR,
6530 MAC_ADDR_ARRAY(data->curr_bssid.bytes));
6531
6532 if (nla_put_u32(skb, QCA_WLAN_VENDOR_ATTR_RSSI_MONITORING_REQUEST_ID,
6533 data->request_id) ||
6534 nla_put(skb, QCA_WLAN_VENDOR_ATTR_RSSI_MONITORING_CUR_BSSID,
6535 sizeof(data->curr_bssid), data->curr_bssid.bytes) ||
6536 nla_put_s8(skb, QCA_WLAN_VENDOR_ATTR_RSSI_MONITORING_CUR_RSSI,
6537 data->curr_rssi)) {
6538 hddLog(LOGE, FL("nla put fail"));
6539 goto fail;
6540 }
6541
6542 cfg80211_vendor_event(skb, GFP_KERNEL);
6543 return;
6544
6545fail:
6546 kfree_skb(skb);
6547 return;
6548}
6549
6550
6551
Srinivas Dasari41d97c92015-07-29 13:09:39 +05306552/**
6553 * __wlan_hdd_cfg80211_setband() - set band
6554 * @wiphy: Pointer to wireless phy
6555 * @wdev: Pointer to wireless device
6556 * @data: Pointer to data
6557 * @data_len: Data length
6558 *
6559 * Return: 0 on success, negative errno on failure
6560 */
6561static int
6562__wlan_hdd_cfg80211_setband(struct wiphy *wiphy,
6563 struct wireless_dev *wdev,
6564 const void *data,
6565 int data_len)
6566{
6567 struct net_device *dev = wdev->netdev;
6568 hdd_context_t *hdd_ctx = wiphy_priv(wiphy);
6569 struct nlattr *tb[QCA_WLAN_VENDOR_ATTR_MAX + 1];
6570 int ret;
6571 static const struct nla_policy policy[QCA_WLAN_VENDOR_ATTR_MAX + 1]
6572 = {[QCA_WLAN_VENDOR_ATTR_SETBAND_VALUE] = { .type = NLA_U32 }};
6573
6574 ENTER();
6575
6576 ret = wlan_hdd_validate_context(hdd_ctx);
6577 if (0 != ret) {
6578 hddLog(LOGE, FL("HDD context is not valid"));
6579 return ret;
6580 }
6581
6582 if (nla_parse(tb, QCA_WLAN_VENDOR_ATTR_MAX, data, data_len,
6583 policy)) {
6584 hddLog(LOGE, FL("Invalid ATTR"));
6585 return -EINVAL;
6586 }
6587
6588 if (!tb[QCA_WLAN_VENDOR_ATTR_SETBAND_VALUE]) {
6589 hddLog(LOGE, FL("attr QCA_WLAN_VENDOR_ATTR_SETBAND_VALUE failed"));
6590 return -EINVAL;
6591 }
6592
Hanumantha Reddy Pothula1347e432015-08-05 09:53:44 +05306593 hdd_ctx->isSetBandByNL = TRUE;
6594 ret = hdd_setBand(dev,
Srinivas Dasari41d97c92015-07-29 13:09:39 +05306595 nla_get_u32(tb[QCA_WLAN_VENDOR_ATTR_SETBAND_VALUE]));
Hanumantha Reddy Pothula1347e432015-08-05 09:53:44 +05306596 hdd_ctx->isSetBandByNL = FALSE;
6597
6598 EXIT();
6599 return ret;
Srinivas Dasari41d97c92015-07-29 13:09:39 +05306600}
6601
6602/**
6603 * wlan_hdd_cfg80211_setband() - Wrapper to offload packets
6604 * @wiphy: wiphy structure pointer
6605 * @wdev: Wireless device structure pointer
6606 * @data: Pointer to the data received
6607 * @data_len: Length of @data
6608 *
6609 * Return: 0 on success; errno on failure
6610 */
6611static int wlan_hdd_cfg80211_setband(struct wiphy *wiphy,
6612 struct wireless_dev *wdev,
6613 const void *data,
6614 int data_len)
6615{
6616 int ret = 0;
6617
6618 vos_ssr_protect(__func__);
6619 ret = __wlan_hdd_cfg80211_setband(wiphy,
6620 wdev, data, data_len);
6621 vos_ssr_unprotect(__func__);
6622
6623 return ret;
6624}
6625
Srinivas Girigowda8bf64cb2015-09-30 19:50:09 +05306626#ifdef WLAN_FEATURE_OFFLOAD_PACKETS
6627/**
6628 * hdd_map_req_id_to_pattern_id() - map request id to pattern id
6629 * @hdd_ctx: HDD context
6630 * @request_id: [input] request id
6631 * @pattern_id: [output] pattern id
6632 *
6633 * This function loops through request id to pattern id array
6634 * if the slot is available, store the request id and return pattern id
6635 * if entry exists, return the pattern id
6636 *
6637 * Return: 0 on success and errno on failure
6638 */
6639static int hdd_map_req_id_to_pattern_id(hdd_context_t *hdd_ctx,
6640 uint32_t request_id,
6641 uint8_t *pattern_id)
6642{
6643 uint32_t i;
6644
6645 mutex_lock(&hdd_ctx->op_ctx.op_lock);
6646 for (i = 0; i < MAXNUM_PERIODIC_TX_PTRNS; i++)
6647 {
6648 if (hdd_ctx->op_ctx.op_table[i].request_id == 0)
6649 {
6650 hdd_ctx->op_ctx.op_table[i].request_id = request_id;
6651 *pattern_id = hdd_ctx->op_ctx.op_table[i].pattern_id;
6652 mutex_unlock(&hdd_ctx->op_ctx.op_lock);
6653 return 0;
6654 } else if (hdd_ctx->op_ctx.op_table[i].request_id ==
6655 request_id) {
6656 *pattern_id = hdd_ctx->op_ctx.op_table[i].pattern_id;
6657 mutex_unlock(&hdd_ctx->op_ctx.op_lock);
6658 return 0;
6659 }
6660 }
6661 mutex_unlock(&hdd_ctx->op_ctx.op_lock);
6662 return -EINVAL;
6663}
6664
6665/**
6666 * hdd_unmap_req_id_to_pattern_id() - unmap request id to pattern id
6667 * @hdd_ctx: HDD context
6668 * @request_id: [input] request id
6669 * @pattern_id: [output] pattern id
6670 *
6671 * This function loops through request id to pattern id array
6672 * reset request id to 0 (slot available again) and
6673 * return pattern id
6674 *
6675 * Return: 0 on success and errno on failure
6676 */
6677static int hdd_unmap_req_id_to_pattern_id(hdd_context_t *hdd_ctx,
6678 uint32_t request_id,
6679 uint8_t *pattern_id)
6680{
6681 uint32_t i;
6682
6683 mutex_lock(&hdd_ctx->op_ctx.op_lock);
6684 for (i = 0; i < MAXNUM_PERIODIC_TX_PTRNS; i++)
6685 {
6686 if (hdd_ctx->op_ctx.op_table[i].request_id == request_id)
6687 {
6688 hdd_ctx->op_ctx.op_table[i].request_id = 0;
6689 *pattern_id = hdd_ctx->op_ctx.op_table[i].pattern_id;
6690 mutex_unlock(&hdd_ctx->op_ctx.op_lock);
6691 return 0;
6692 }
6693 }
6694 mutex_unlock(&hdd_ctx->op_ctx.op_lock);
6695 return -EINVAL;
6696}
6697
6698
6699/*
6700 * define short names for the global vendor params
6701 * used by __wlan_hdd_cfg80211_offloaded_packets()
6702 */
6703#define PARAM_MAX QCA_WLAN_VENDOR_ATTR_OFFLOADED_PACKETS_MAX
6704#define PARAM_REQUEST_ID \
6705 QCA_WLAN_VENDOR_ATTR_OFFLOADED_PACKETS_REQUEST_ID
6706#define PARAM_CONTROL \
6707 QCA_WLAN_VENDOR_ATTR_OFFLOADED_PACKETS_SENDING_CONTROL
6708#define PARAM_IP_PACKET \
6709 QCA_WLAN_VENDOR_ATTR_OFFLOADED_PACKETS_IP_PACKET_DATA
6710#define PARAM_SRC_MAC_ADDR \
6711 QCA_WLAN_VENDOR_ATTR_OFFLOADED_PACKETS_SRC_MAC_ADDR
6712#define PARAM_DST_MAC_ADDR \
6713 QCA_WLAN_VENDOR_ATTR_OFFLOADED_PACKETS_DST_MAC_ADDR
6714#define PARAM_PERIOD QCA_WLAN_VENDOR_ATTR_OFFLOADED_PACKETS_PERIOD
6715
6716/**
6717 * wlan_hdd_add_tx_ptrn() - add tx pattern
6718 * @adapter: adapter pointer
6719 * @hdd_ctx: hdd context
6720 * @tb: nl attributes
6721 *
6722 * This function reads the NL attributes and forms a AddTxPtrn message
6723 * posts it to SME.
6724 *
6725 */
6726static int
6727wlan_hdd_add_tx_ptrn(hdd_adapter_t *adapter, hdd_context_t *hdd_ctx,
6728 struct nlattr **tb)
6729{
6730 struct sSirAddPeriodicTxPtrn *add_req;
6731 eHalStatus status;
6732 uint32_t request_id, ret, len;
6733 uint8_t pattern_id = 0;
6734 v_MACADDR_t dst_addr;
6735 uint16_t eth_type = htons(ETH_P_IP);
6736
6737 if (!hdd_connIsConnected(WLAN_HDD_GET_STATION_CTX_PTR(adapter)))
6738 {
6739 hddLog(LOGE, FL("Not in Connected state!"));
6740 return -ENOTSUPP;
6741 }
6742
6743 add_req = vos_mem_malloc(sizeof(*add_req));
6744 if (!add_req)
6745 {
6746 hddLog(LOGE, FL("memory allocation failed"));
6747 return -ENOMEM;
6748 }
6749
6750 /* Parse and fetch request Id */
6751 if (!tb[PARAM_REQUEST_ID])
6752 {
6753 hddLog(LOGE, FL("attr request id failed"));
6754 goto fail;
6755 }
6756
6757 request_id = nla_get_u32(tb[PARAM_REQUEST_ID]);
6758 hddLog(LOG1, FL("Request Id: %u"), request_id);
6759 if (request_id == 0)
6760 {
6761 hddLog(LOGE, FL("request_id cannot be zero"));
6762 return -EINVAL;
6763 }
6764
6765 if (!tb[PARAM_PERIOD])
6766 {
6767 hddLog(LOGE, FL("attr period failed"));
6768 goto fail;
6769 }
6770 add_req->usPtrnIntervalMs = nla_get_u32(tb[PARAM_PERIOD]);
6771 hddLog(LOG1, FL("Period: %u ms"), add_req->usPtrnIntervalMs);
6772 if (add_req->usPtrnIntervalMs == 0)
6773 {
6774 hddLog(LOGE, FL("Invalid interval zero, return failure"));
6775 goto fail;
6776 }
6777
6778 if (!tb[PARAM_SRC_MAC_ADDR])
6779 {
6780 hddLog(LOGE, FL("attr source mac address failed"));
6781 goto fail;
6782 }
6783 nla_memcpy(add_req->macAddress, tb[PARAM_SRC_MAC_ADDR],
6784 VOS_MAC_ADDR_SIZE);
6785 hddLog(LOG1, "input src mac address: "MAC_ADDRESS_STR,
6786 MAC_ADDR_ARRAY(add_req->macAddress));
6787
6788 if (memcmp(add_req->macAddress, adapter->macAddressCurrent.bytes,
6789 VOS_MAC_ADDR_SIZE))
6790 {
6791 hddLog(LOGE,
6792 FL("input src mac address and connected ap bssid are different"));
6793 goto fail;
6794 }
6795
6796 if (!tb[PARAM_DST_MAC_ADDR])
6797 {
6798 hddLog(LOGE, FL("attr dst mac address failed"));
6799 goto fail;
6800 }
6801 nla_memcpy(dst_addr.bytes, tb[PARAM_DST_MAC_ADDR], VOS_MAC_ADDR_SIZE);
6802 hddLog(LOG1, "input dst mac address: "MAC_ADDRESS_STR,
6803 MAC_ADDR_ARRAY(dst_addr.bytes));
6804
6805 if (!tb[PARAM_IP_PACKET])
6806 {
6807 hddLog(LOGE, FL("attr ip packet failed"));
6808 goto fail;
6809 }
6810 add_req->ucPtrnSize = nla_len(tb[PARAM_IP_PACKET]);
6811 hddLog(LOG1, FL("IP packet len: %u"), add_req->ucPtrnSize);
6812
6813 if (add_req->ucPtrnSize < 0 ||
6814 add_req->ucPtrnSize > (PERIODIC_TX_PTRN_MAX_SIZE -
6815 HDD_ETH_HEADER_LEN))
6816 {
6817 hddLog(LOGE, FL("Invalid IP packet len: %d"),
6818 add_req->ucPtrnSize);
6819 goto fail;
6820 }
6821
6822 len = 0;
6823 vos_mem_copy(&add_req->ucPattern[0], dst_addr.bytes, VOS_MAC_ADDR_SIZE);
6824 len += VOS_MAC_ADDR_SIZE;
6825 vos_mem_copy(&add_req->ucPattern[len], add_req->macAddress,
6826 VOS_MAC_ADDR_SIZE);
6827 len += VOS_MAC_ADDR_SIZE;
6828 vos_mem_copy(&add_req->ucPattern[len], &eth_type, 2);
6829 len += 2;
6830
6831 /*
6832 * This is the IP packet, add 14 bytes Ethernet (802.3) header
6833 * ------------------------------------------------------------
6834 * | 14 bytes Ethernet (802.3) header | IP header and payload |
6835 * ------------------------------------------------------------
6836 */
6837 vos_mem_copy(&add_req->ucPattern[len],
6838 nla_data(tb[PARAM_IP_PACKET]),
6839 add_req->ucPtrnSize);
6840 add_req->ucPtrnSize += len;
6841
6842 VOS_TRACE_HEX_DUMP(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
6843 add_req->ucPattern, add_req->ucPtrnSize);
6844
6845 ret = hdd_map_req_id_to_pattern_id(hdd_ctx, request_id, &pattern_id);
6846 if (ret)
6847 {
6848 hddLog(LOGW, FL("req id to pattern id failed (ret=%d)"), ret);
6849 goto fail;
6850 }
6851 add_req->ucPtrnId = pattern_id;
6852 hddLog(LOG1, FL("pattern id: %d"), add_req->ucPtrnId);
6853
6854 status = sme_AddPeriodicTxPtrn(hdd_ctx->hHal, add_req);
6855 if (!HAL_STATUS_SUCCESS(status))
6856 {
6857 hddLog(LOGE,
6858 FL("sme_AddPeriodicTxPtrn failed (err=%d)"), status);
6859 goto fail;
6860 }
6861
6862 EXIT();
6863 vos_mem_free(add_req);
6864 return 0;
6865
6866fail:
6867 vos_mem_free(add_req);
6868 return -EINVAL;
6869}
6870
6871/**
6872 * wlan_hdd_del_tx_ptrn() - delete tx pattern
6873 * @adapter: adapter pointer
6874 * @hdd_ctx: hdd context
6875 * @tb: nl attributes
6876 *
6877 * This function reads the NL attributes and forms a DelTxPtrn message
6878 * posts it to SME.
6879 *
6880 */
6881static int
6882wlan_hdd_del_tx_ptrn(hdd_adapter_t *adapter, hdd_context_t *hdd_ctx,
6883 struct nlattr **tb)
6884{
6885 struct sSirDelPeriodicTxPtrn *del_req;
6886 eHalStatus status;
6887 uint32_t request_id, ret;
6888 uint8_t pattern_id = 0;
6889
6890 /* Parse and fetch request Id */
6891 if (!tb[PARAM_REQUEST_ID])
6892 {
6893 hddLog(LOGE, FL("attr request id failed"));
6894 return -EINVAL;
6895 }
6896 request_id = nla_get_u32(tb[PARAM_REQUEST_ID]);
6897 if (request_id == 0)
6898 {
6899 hddLog(LOGE, FL("request_id cannot be zero"));
6900 return -EINVAL;
6901 }
6902
6903 ret = hdd_unmap_req_id_to_pattern_id(hdd_ctx, request_id, &pattern_id);
6904 if (ret)
6905 {
6906 hddLog(LOGW, FL("req id to pattern id failed (ret=%d)"), ret);
6907 return -EINVAL;
6908 }
6909
6910 del_req = vos_mem_malloc(sizeof(*del_req));
6911 if (!del_req)
6912 {
6913 hddLog(LOGE, FL("memory allocation failed"));
6914 return -ENOMEM;
6915 }
6916
6917 vos_mem_set(del_req, sizeof(*del_req), 0);
6918 vos_mem_copy(del_req->macAddress, adapter->macAddressCurrent.bytes,
6919 VOS_MAC_ADDR_SIZE);
6920 hddLog(LOG1, MAC_ADDRESS_STR, MAC_ADDR_ARRAY(del_req->macAddress));
6921 del_req->ucPatternIdBitmap |= (0x1 << pattern_id);
6922 hddLog(LOG1, FL("Request Id: %u Pattern id: %d, bitmap %04x"),
6923 request_id, pattern_id, del_req->ucPatternIdBitmap);
6924
6925 status = sme_DelPeriodicTxPtrn(hdd_ctx->hHal, del_req);
6926 if (!HAL_STATUS_SUCCESS(status))
6927 {
6928 hddLog(LOGE,
6929 FL("sme_DelPeriodicTxPtrn failed (err=%d)"), status);
6930 goto fail;
6931 }
6932
6933 EXIT();
6934 vos_mem_free(del_req);
6935 return 0;
6936
6937fail:
6938 vos_mem_free(del_req);
6939 return -EINVAL;
6940}
6941
6942
6943/**
6944 * __wlan_hdd_cfg80211_offloaded_packets() - send offloaded packets
6945 * @wiphy: Pointer to wireless phy
6946 * @wdev: Pointer to wireless device
6947 * @data: Pointer to data
6948 * @data_len: Data length
6949 *
6950 * Return: 0 on success, negative errno on failure
6951 */
6952static int
6953__wlan_hdd_cfg80211_offloaded_packets(struct wiphy *wiphy,
6954 struct wireless_dev *wdev,
6955 const void *data,
6956 int data_len)
6957{
6958 struct net_device *dev = wdev->netdev;
6959 hdd_adapter_t *adapter = WLAN_HDD_GET_PRIV_PTR(dev);
6960 hdd_context_t *hdd_ctx = wiphy_priv(wiphy);
6961 struct nlattr *tb[PARAM_MAX + 1];
6962 uint8_t control;
6963 int ret;
6964 static const struct nla_policy policy[PARAM_MAX + 1] =
6965 {
6966 [PARAM_REQUEST_ID] = { .type = NLA_U32 },
6967 [PARAM_CONTROL] = { .type = NLA_U32 },
6968 [PARAM_SRC_MAC_ADDR] = { .type = NLA_BINARY,
6969 .len = VOS_MAC_ADDR_SIZE },
6970 [PARAM_DST_MAC_ADDR] = { .type = NLA_BINARY,
6971 .len = VOS_MAC_ADDR_SIZE },
6972 [PARAM_PERIOD] = { .type = NLA_U32 },
6973 };
6974
6975 ENTER();
6976
6977 ret = wlan_hdd_validate_context(hdd_ctx);
6978 if (0 != ret)
6979 {
6980 hddLog(LOGE, FL("HDD context is not valid"));
6981 return ret;
6982 }
6983
6984 if (!sme_IsFeatureSupportedByFW(WLAN_PERIODIC_TX_PTRN))
6985 {
6986 hddLog(LOGE,
6987 FL("Periodic Tx Pattern Offload feature is not supported in FW!"));
6988 return -ENOTSUPP;
6989 }
6990
6991 if (nla_parse(tb, PARAM_MAX, data, data_len, policy))
6992 {
6993 hddLog(LOGE, FL("Invalid ATTR"));
6994 return -EINVAL;
6995 }
6996
6997 if (!tb[PARAM_CONTROL])
6998 {
6999 hddLog(LOGE, FL("attr control failed"));
7000 return -EINVAL;
7001 }
7002 control = nla_get_u32(tb[PARAM_CONTROL]);
7003 hddLog(LOG1, FL("Control: %d"), control);
7004
7005 if (control == WLAN_START_OFFLOADED_PACKETS)
7006 return wlan_hdd_add_tx_ptrn(adapter, hdd_ctx, tb);
7007 else if (control == WLAN_STOP_OFFLOADED_PACKETS)
7008 return wlan_hdd_del_tx_ptrn(adapter, hdd_ctx, tb);
7009 else
7010 {
7011 hddLog(LOGE, FL("Invalid control: %d"), control);
7012 return -EINVAL;
7013 }
7014}
7015
7016/*
7017 * done with short names for the global vendor params
7018 * used by __wlan_hdd_cfg80211_offloaded_packets()
7019 */
7020#undef PARAM_MAX
7021#undef PARAM_REQUEST_ID
7022#undef PARAM_CONTROL
7023#undef PARAM_IP_PACKET
7024#undef PARAM_SRC_MAC_ADDR
7025#undef PARAM_DST_MAC_ADDR
7026#undef PARAM_PERIOD
7027
7028/**
7029 * wlan_hdd_cfg80211_offloaded_packets() - Wrapper to offload packets
7030 * @wiphy: wiphy structure pointer
7031 * @wdev: Wireless device structure pointer
7032 * @data: Pointer to the data received
7033 * @data_len: Length of @data
7034 *
7035 * Return: 0 on success; errno on failure
7036 */
7037static int wlan_hdd_cfg80211_offloaded_packets(struct wiphy *wiphy,
7038 struct wireless_dev *wdev,
7039 const void *data,
7040 int data_len)
7041{
7042 int ret = 0;
7043
7044 vos_ssr_protect(__func__);
7045 ret = __wlan_hdd_cfg80211_offloaded_packets(wiphy,
7046 wdev, data, data_len);
7047 vos_ssr_unprotect(__func__);
7048
7049 return ret;
7050}
7051#endif
7052
Deepthi Gowriae6a1662015-10-12 12:59:37 +05307053static const struct
7054nla_policy
7055qca_wlan_vendor_attr_policy[QCA_WLAN_VENDOR_ATTR_MAX+1] = {
7056 [QCA_WLAN_VENDOR_ATTR_MAC_ADDR] = { .type = NLA_UNSPEC },
7057};
7058
7059/**
7060 * wlan_hdd_cfg80211_get_link_properties() - This function is used to
7061 * get link properties like nss, rate flags and operating frequency for
7062 * the connection with the given peer.
7063 * @wiphy: WIPHY structure pointer
7064 * @wdev: Wireless device structure pointer
7065 * @data: Pointer to the data received
7066 * @data_len: Length of the data received
7067 *
7068 * This function return the above link properties on success.
7069 *
7070 * Return: 0 on success and errno on failure
7071 */
7072static int wlan_hdd_cfg80211_get_link_properties(struct wiphy *wiphy,
7073 struct wireless_dev *wdev,
7074 const void *data,
7075 int data_len)
7076{
7077 hdd_context_t *hdd_ctx = wiphy_priv(wiphy);
7078 struct net_device *dev = wdev->netdev;
7079 hdd_adapter_t *adapter = WLAN_HDD_GET_PRIV_PTR(dev);
7080 hdd_station_ctx_t *hdd_sta_ctx;
7081 struct nlattr *tb[QCA_WLAN_VENDOR_ATTR_MAX+1];
7082 uint8_t peer_mac[VOS_MAC_ADDR_SIZE];
7083 uint32_t sta_id;
7084 struct sk_buff *reply_skb;
7085 uint32_t rate_flags = 0;
7086 uint8_t nss;
7087 uint8_t final_rate_flags = 0;
7088 uint32_t freq;
7089 v_CONTEXT_t pVosContext = NULL;
7090 ptSapContext pSapCtx = NULL;
7091
7092 if (0 != wlan_hdd_validate_context(hdd_ctx)) {
7093 hddLog(VOS_TRACE_LEVEL_ERROR, FL("HDD context is not valid"));
7094 return -EINVAL;
7095 }
7096
7097 if (nla_parse(tb, QCA_WLAN_VENDOR_ATTR_MAX, data, data_len,
7098 qca_wlan_vendor_attr_policy)) {
7099 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Invalid attribute"));
7100 return -EINVAL;
7101 }
7102
7103 if (!tb[QCA_WLAN_VENDOR_ATTR_MAC_ADDR]) {
7104 hddLog(VOS_TRACE_LEVEL_ERROR,
7105 FL("Attribute peerMac not provided for mode=%d"),
7106 adapter->device_mode);
7107 return -EINVAL;
7108 }
7109
7110 memcpy(peer_mac, nla_data(tb[QCA_WLAN_VENDOR_ATTR_MAC_ADDR]),
7111 sizeof(peer_mac));
7112 hddLog(VOS_TRACE_LEVEL_INFO,
7113 FL("peerMac="MAC_ADDRESS_STR" for device_mode:%d"),
7114 MAC_ADDR_ARRAY(peer_mac), adapter->device_mode);
7115
7116 if (adapter->device_mode == WLAN_HDD_INFRA_STATION ||
7117 adapter->device_mode == WLAN_HDD_P2P_CLIENT) {
7118 hdd_sta_ctx = WLAN_HDD_GET_STATION_CTX_PTR(adapter);
7119 if ((hdd_sta_ctx->conn_info.connState !=
7120 eConnectionState_Associated) ||
7121 !vos_mem_compare(hdd_sta_ctx->conn_info.bssId, peer_mac,
7122 VOS_MAC_ADDRESS_LEN)) {
7123 hddLog(VOS_TRACE_LEVEL_ERROR,
7124 FL("Not Associated to mac "MAC_ADDRESS_STR),
7125 MAC_ADDR_ARRAY(peer_mac));
7126 return -EINVAL;
7127 }
7128
7129 nss = 1; //pronto supports only one spatial stream
7130 freq = vos_chan_to_freq(
7131 hdd_sta_ctx->conn_info.operationChannel);
7132 rate_flags = hdd_sta_ctx->conn_info.rate_flags;
7133
7134 } else if (adapter->device_mode == WLAN_HDD_P2P_GO ||
7135 adapter->device_mode == WLAN_HDD_SOFTAP) {
7136
7137 pVosContext = ( WLAN_HDD_GET_CTX(adapter))->pvosContext;
7138 pSapCtx = VOS_GET_SAP_CB(pVosContext);
7139 if(pSapCtx == NULL){
7140 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
7141 FL("psapCtx is NULL"));
7142 return -ENOENT;
7143 }
7144
7145
7146 for (sta_id = 0; sta_id < WLAN_MAX_STA_COUNT; sta_id++) {
7147 if (pSapCtx->aStaInfo[sta_id].isUsed &&
7148 !vos_is_macaddr_broadcast(
7149 &pSapCtx->aStaInfo[sta_id].macAddrSTA) &&
7150 vos_mem_compare(
7151 &pSapCtx->aStaInfo[sta_id].macAddrSTA,
7152 peer_mac, VOS_MAC_ADDRESS_LEN))
7153 break;
7154 }
7155
7156 if (WLAN_MAX_STA_COUNT == sta_id) {
7157 hddLog(VOS_TRACE_LEVEL_ERROR,
7158 FL("No active peer with mac="MAC_ADDRESS_STR),
7159 MAC_ADDR_ARRAY(peer_mac));
7160 return -EINVAL;
7161 }
7162
7163 nss = 1; //pronto supports only one spatial stream
7164 freq = vos_chan_to_freq(
7165 (WLAN_HDD_GET_AP_CTX_PTR(adapter))->operatingChannel);
7166 rate_flags = pSapCtx->aStaInfo[sta_id].rate_flags;
7167 } else {
7168 hddLog(VOS_TRACE_LEVEL_ERROR,
7169 FL("Not Associated! with mac"MAC_ADDRESS_STR),
7170 MAC_ADDR_ARRAY(peer_mac));
7171 return -EINVAL;
7172 }
7173
7174 if (!(rate_flags & eHAL_TX_RATE_LEGACY)) {
7175 if (rate_flags & eHAL_TX_RATE_VHT80) {
7176 final_rate_flags |= RATE_INFO_FLAGS_VHT_MCS;
7177 final_rate_flags |= RATE_INFO_FLAGS_80_MHZ_WIDTH;
7178 } else if (rate_flags & eHAL_TX_RATE_VHT40) {
7179 final_rate_flags |= RATE_INFO_FLAGS_VHT_MCS;
7180 final_rate_flags |= RATE_INFO_FLAGS_40_MHZ_WIDTH;
7181 } else if (rate_flags & eHAL_TX_RATE_VHT20) {
7182 final_rate_flags |= RATE_INFO_FLAGS_VHT_MCS;
7183 } else if (rate_flags & (eHAL_TX_RATE_HT20 | eHAL_TX_RATE_HT40)) {
7184 final_rate_flags |= RATE_INFO_FLAGS_MCS;
7185 if (rate_flags & eHAL_TX_RATE_HT40)
7186 final_rate_flags |= RATE_INFO_FLAGS_40_MHZ_WIDTH;
7187 }
7188
7189 if (rate_flags & eHAL_TX_RATE_SGI) {
7190 if (!(final_rate_flags & RATE_INFO_FLAGS_VHT_MCS))
7191 final_rate_flags |= RATE_INFO_FLAGS_MCS;
7192 final_rate_flags |= RATE_INFO_FLAGS_SHORT_GI;
7193 }
7194 }
7195
7196 reply_skb = cfg80211_vendor_cmd_alloc_reply_skb(wiphy,
7197 sizeof(u8) + sizeof(u8) + sizeof(u32) + NLMSG_HDRLEN);
7198
7199 if (NULL == reply_skb) {
7200 hddLog(VOS_TRACE_LEVEL_ERROR,
7201 FL("getLinkProperties: skb alloc failed"));
7202 return -EINVAL;
7203 }
7204
7205 if (nla_put_u8(reply_skb,
7206 QCA_WLAN_VENDOR_ATTR_LINK_PROPERTIES_NSS,
7207 nss) ||
7208 nla_put_u8(reply_skb,
7209 QCA_WLAN_VENDOR_ATTR_LINK_PROPERTIES_RATE_FLAGS,
7210 final_rate_flags) ||
7211 nla_put_u32(reply_skb,
7212 QCA_WLAN_VENDOR_ATTR_LINK_PROPERTIES_FREQ,
7213 freq)) {
7214 hddLog(VOS_TRACE_LEVEL_ERROR, FL("nla_put failed"));
7215 kfree_skb(reply_skb);
7216 return -EINVAL;
7217 }
7218
7219 return cfg80211_vendor_cmd_reply(reply_skb);
7220}
7221
Arun Khandavalli7eeb1592015-10-19 21:36:57 +05307222#define PARAM_WIFICONFIG_MAX QCA_WLAN_VENDOR_ATTR_CONFIG_MAX
7223#define PARAM_MODULATED_DTIM QCA_WLAN_VENDOR_ATTR_CONFIG_MODULATED_DTIM
7224#define PARAM_STATS_AVG_FACTOR QCA_WLAN_VENDOR_ATTR_CONFIG_STATS_AVG_FACTOR
7225#define PARAM_GUARD_TIME QCA_WLAN_VENDOR_ATTR_CONFIG_GUARD_TIME
7226
7227/**
7228 * __wlan_hdd_cfg80211_wifi_configuration_set() - Wifi configuration
7229 * vendor command
7230 *
7231 * @wiphy: wiphy device pointer
7232 * @wdev: wireless device pointer
7233 * @data: Vendor command data buffer
7234 * @data_len: Buffer length
7235 *
7236 * Handles QCA_WLAN_VENDOR_ATTR_CONFIG_MAX.
7237 *
7238 * Return: EOK or other error codes.
7239 */
7240
7241static int __wlan_hdd_cfg80211_wifi_configuration_set(struct wiphy *wiphy,
7242 struct wireless_dev *wdev,
7243 const void *data,
7244 int data_len)
7245{
7246 struct net_device *dev = wdev->netdev;
7247 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
7248 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
7249 hdd_station_ctx_t *pHddStaCtx;
7250 struct nlattr *tb[PARAM_WIFICONFIG_MAX + 1];
7251 tpSetWifiConfigParams pReq;
7252 eHalStatus status;
7253 int ret_val;
7254 static const struct nla_policy policy[PARAM_WIFICONFIG_MAX + 1] = {
7255 [PARAM_STATS_AVG_FACTOR] = { .type = NLA_U16 },
7256 [PARAM_MODULATED_DTIM] = { .type = NLA_U32 },
7257 [PARAM_GUARD_TIME] = { .type = NLA_U32},
7258 };
7259
7260 ENTER();
7261
7262 if (VOS_FTM_MODE == hdd_get_conparam()) {
7263 hddLog(LOGE, FL("Command not allowed in FTM mode"));
7264 return -EINVAL;
7265 }
7266
7267 ret_val = wlan_hdd_validate_context(pHddCtx);
7268 if (ret_val) {
7269 return ret_val;
7270 }
7271
7272 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
7273
7274 if (!hdd_connIsConnected(WLAN_HDD_GET_STATION_CTX_PTR(pAdapter))) {
7275 hddLog(LOGE, FL("Not in Connected state!"));
7276 return -ENOTSUPP;
7277 }
7278
7279 if (nla_parse(tb, PARAM_WIFICONFIG_MAX, data, data_len, policy)) {
7280 hddLog(LOGE, FL("Invalid ATTR"));
7281 return -EINVAL;
7282 }
7283
7284 /* check the Wifi Capability */
7285 if ( (TRUE != pHddCtx->cfg_ini->fEnableWifiConfig) &&
7286 (TRUE != sme_IsFeatureSupportedByFW(WIFI_CONFIG)))
7287 {
7288 hddLog(VOS_TRACE_LEVEL_ERROR,
7289 FL("WIFICONFIG not supported by Firmware"));
7290 return -EINVAL;
7291 }
7292
7293 pReq = vos_mem_malloc(sizeof(tSetWifiConfigParams));
7294
7295 if (!pReq) {
7296 VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR,
7297 "%s: Not able to allocate memory for tSetWifiConfigParams",
7298 __func__);
7299 return eHAL_STATUS_E_MALLOC_FAILED;
7300 }
7301
7302 vos_mem_set(pReq, sizeof(tSetWifiConfigParams), 0);
7303
7304 pReq->sessionId = pAdapter->sessionId;
7305 vos_mem_copy( &pReq->bssId, pHddStaCtx->conn_info.bssId, WNI_CFG_BSSID_LEN);
7306
7307 if (tb[PARAM_MODULATED_DTIM]) {
7308 pReq->paramValue = nla_get_u32(
7309 tb[PARAM_MODULATED_DTIM]);
7310 hddLog(LOG1, FL("Modulated DTIM: pReq->paramValue:%d "),
7311 pReq->paramValue);
7312 pHddCtx->cfg_ini->fMaxLIModulatedDTIM = pReq->paramValue;
7313 hdd_set_pwrparams(pHddCtx);
7314 if (BMPS == pmcGetPmcState(pHddCtx->hHal)) {
7315 hddLog( LOG1, FL("WifiConfig: Requesting FullPower!"));
7316
7317 sme_RequestFullPower(WLAN_HDD_GET_HAL_CTX(pAdapter),
7318 iw_full_power_cbfn, pAdapter,
7319 eSME_FULL_PWR_NEEDED_BY_HDD);
7320 }
7321 else
7322 {
7323 hddLog( LOG1, FL("WifiConfig Not in BMPS state"));
7324 }
7325 }
7326
7327 if (tb[PARAM_STATS_AVG_FACTOR]) {
7328 pReq->paramType = WIFI_CONFIG_SET_AVG_STATS_FACTOR;
7329 pReq->paramValue = nla_get_u16(
7330 tb[PARAM_STATS_AVG_FACTOR]);
7331 hddLog(LOG1, FL("AVG_STATS_FACTOR pReq->paramType:%d,pReq->paramValue:%d "),
7332 pReq->paramType, pReq->paramValue);
7333 status = sme_set_wificonfig_params(pHddCtx->hHal, pReq);
7334
7335 if (eHAL_STATUS_SUCCESS != status)
7336 {
7337 vos_mem_free(pReq);
7338 pReq = NULL;
7339 ret_val = -EPERM;
7340 return ret_val;
7341 }
7342 }
7343
7344
7345 if (tb[PARAM_GUARD_TIME]) {
7346 pReq->paramType = WIFI_CONFIG_SET_GUARD_TIME;
7347 pReq->paramValue = nla_get_u32(
7348 tb[PARAM_GUARD_TIME]);
7349 hddLog(LOG1, FL("GUARD_TIME pReq->paramType:%d,pReq->paramValue:%d "),
7350 pReq->paramType, pReq->paramValue);
7351 status = sme_set_wificonfig_params(pHddCtx->hHal, pReq);
7352
7353 if (eHAL_STATUS_SUCCESS != status)
7354 {
7355 vos_mem_free(pReq);
7356 pReq = NULL;
7357 ret_val = -EPERM;
7358 return ret_val;
7359 }
7360
7361 }
7362
7363 EXIT();
7364 return ret_val;
7365}
7366
7367/**
7368 * wlan_hdd_cfg80211_wifi_configuration_set() - Wifi configuration
7369 * vendor command
7370 *
7371 * @wiphy: wiphy device pointer
7372 * @wdev: wireless device pointer
7373 * @data: Vendor command data buffer
7374 * @data_len: Buffer length
7375 *
7376 * Handles QCA_WLAN_VENDOR_ATTR_CONFIG_MAX.
7377 *
7378 * Return: EOK or other error codes.
7379 */
7380static int wlan_hdd_cfg80211_wifi_configuration_set(struct wiphy *wiphy,
7381 struct wireless_dev *wdev,
7382 const void *data,
7383 int data_len)
7384{
7385 int ret;
7386
7387 vos_ssr_protect(__func__);
7388 ret = __wlan_hdd_cfg80211_wifi_configuration_set(wiphy, wdev,
7389 data, data_len);
7390 vos_ssr_unprotect(__func__);
7391
7392 return ret;
7393}
Sunil Duttc69bccb2014-05-26 21:30:20 +05307394const struct wiphy_vendor_command hdd_wiphy_vendor_commands[] =
7395{
Mukul Sharma2a271632014-10-13 14:59:01 +05307396 {
7397 .info.vendor_id = QCA_NL80211_VENDOR_ID,
7398 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_ROAMING,
7399 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
7400 WIPHY_VENDOR_CMD_NEED_NETDEV |
7401 WIPHY_VENDOR_CMD_NEED_RUNNING,
Edhar, Mahesh Kumar59129f52015-01-14 14:26:04 +05307402 .doit = wlan_hdd_cfg80211_firmware_roaming
Mukul Sharma2a271632014-10-13 14:59:01 +05307403 },
Srinivas Dasari030bad32015-02-18 23:23:54 +05307404
7405 {
7406 .info.vendor_id = QCA_NL80211_VENDOR_ID,
7407 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_NAN,
7408 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
7409 WIPHY_VENDOR_CMD_NEED_NETDEV |
7410 WIPHY_VENDOR_CMD_NEED_RUNNING,
7411 .doit = wlan_hdd_cfg80211_nan_request
7412 },
7413
Sunil Duttc69bccb2014-05-26 21:30:20 +05307414#ifdef WLAN_FEATURE_LINK_LAYER_STATS
7415 {
7416 .info.vendor_id = QCA_NL80211_VENDOR_ID,
7417 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_LL_STATS_CLR,
7418 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
7419 WIPHY_VENDOR_CMD_NEED_NETDEV |
7420 WIPHY_VENDOR_CMD_NEED_RUNNING,
Edhar, Mahesh Kumar59129f52015-01-14 14:26:04 +05307421 .doit = wlan_hdd_cfg80211_ll_stats_clear
Sunil Duttc69bccb2014-05-26 21:30:20 +05307422 },
7423
7424 {
7425 .info.vendor_id = QCA_NL80211_VENDOR_ID,
7426 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_LL_STATS_SET,
7427 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
7428 WIPHY_VENDOR_CMD_NEED_NETDEV |
7429 WIPHY_VENDOR_CMD_NEED_RUNNING,
Edhar, Mahesh Kumar59129f52015-01-14 14:26:04 +05307430 .doit = wlan_hdd_cfg80211_ll_stats_set
Sunil Duttc69bccb2014-05-26 21:30:20 +05307431 },
7432
7433 {
7434 .info.vendor_id = QCA_NL80211_VENDOR_ID,
7435 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_LL_STATS_GET,
7436 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
7437 WIPHY_VENDOR_CMD_NEED_NETDEV |
7438 WIPHY_VENDOR_CMD_NEED_RUNNING,
Edhar, Mahesh Kumar59129f52015-01-14 14:26:04 +05307439 .doit = wlan_hdd_cfg80211_ll_stats_get
Dino Mycle6fb96c12014-06-10 11:52:40 +05307440 },
Sunil Duttc69bccb2014-05-26 21:30:20 +05307441#endif /* WLAN_FEATURE_LINK_LAYER_STATS */
Dino Mycle6fb96c12014-06-10 11:52:40 +05307442#ifdef WLAN_FEATURE_EXTSCAN
7443 {
7444 .info.vendor_id = QCA_NL80211_VENDOR_ID,
7445 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_START,
7446 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
7447 WIPHY_VENDOR_CMD_NEED_NETDEV |
7448 WIPHY_VENDOR_CMD_NEED_RUNNING,
Edhar, Mahesh Kumar59129f52015-01-14 14:26:04 +05307449 .doit = wlan_hdd_cfg80211_extscan_start
Dino Mycle6fb96c12014-06-10 11:52:40 +05307450 },
7451 {
7452 .info.vendor_id = QCA_NL80211_VENDOR_ID,
7453 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_STOP,
7454 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
7455 WIPHY_VENDOR_CMD_NEED_NETDEV |
7456 WIPHY_VENDOR_CMD_NEED_RUNNING,
Edhar, Mahesh Kumar59129f52015-01-14 14:26:04 +05307457 .doit = wlan_hdd_cfg80211_extscan_stop
Dino Mycle6fb96c12014-06-10 11:52:40 +05307458 },
7459 {
7460 .info.vendor_id = QCA_NL80211_VENDOR_ID,
7461 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_GET_VALID_CHANNELS,
7462 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
7463 WIPHY_VENDOR_CMD_NEED_NETDEV,
Edhar, Mahesh Kumar59129f52015-01-14 14:26:04 +05307464 .doit = wlan_hdd_cfg80211_extscan_get_valid_channels
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_GET_CAPABILITIES,
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_get_capabilities
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_GET_CACHED_RESULTS,
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_get_cached_results
Dino Mycle6fb96c12014-06-10 11:52:40 +05307481 },
7482 {
7483 .info.vendor_id = QCA_NL80211_VENDOR_ID,
7484 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_SET_BSSID_HOTLIST,
7485 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
7486 WIPHY_VENDOR_CMD_NEED_NETDEV |
7487 WIPHY_VENDOR_CMD_NEED_RUNNING,
Edhar, Mahesh Kumar59129f52015-01-14 14:26:04 +05307488 .doit = wlan_hdd_cfg80211_extscan_set_bssid_hotlist
Dino Mycle6fb96c12014-06-10 11:52:40 +05307489 },
7490 {
7491 .info.vendor_id = QCA_NL80211_VENDOR_ID,
7492 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_RESET_BSSID_HOTLIST,
7493 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
7494 WIPHY_VENDOR_CMD_NEED_NETDEV |
7495 WIPHY_VENDOR_CMD_NEED_RUNNING,
Edhar, Mahesh Kumar59129f52015-01-14 14:26:04 +05307496 .doit = wlan_hdd_cfg80211_extscan_reset_bssid_hotlist
Dino Mycle6fb96c12014-06-10 11:52:40 +05307497 },
Padma, Santhosh Kumar9acee012015-08-21 19:58:01 +05307498 {
7499 .info.vendor_id = QCA_NL80211_VENDOR_ID,
7500 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_SET_SSID_HOTLIST,
7501 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
7502 WIPHY_VENDOR_CMD_NEED_NETDEV |
7503 WIPHY_VENDOR_CMD_NEED_RUNNING,
7504 .doit = wlan_hdd_cfg80211_extscan_set_ssid_hotlist
7505 },
7506 {
7507 .info.vendor_id = QCA_NL80211_VENDOR_ID,
7508 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_RESET_SSID_HOTLIST,
7509 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
7510 WIPHY_VENDOR_CMD_NEED_NETDEV |
7511 WIPHY_VENDOR_CMD_NEED_RUNNING,
7512 .doit = wlan_hdd_cfg80211_extscan_reset_ssid_hotlist
7513 },
Dino Mycle6fb96c12014-06-10 11:52:40 +05307514#endif /* WLAN_FEATURE_EXTSCAN */
Atul Mittal115287b2014-07-08 13:26:33 +05307515/*EXT TDLS*/
7516 {
7517 .info.vendor_id = QCA_NL80211_VENDOR_ID,
7518 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_TDLS_ENABLE,
7519 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
7520 WIPHY_VENDOR_CMD_NEED_NETDEV |
7521 WIPHY_VENDOR_CMD_NEED_RUNNING,
Edhar, Mahesh Kumar59129f52015-01-14 14:26:04 +05307522 .doit = wlan_hdd_cfg80211_exttdls_enable
Atul Mittal115287b2014-07-08 13:26:33 +05307523 },
7524 {
7525 .info.vendor_id = QCA_NL80211_VENDOR_ID,
7526 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_TDLS_DISABLE,
7527 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
7528 WIPHY_VENDOR_CMD_NEED_NETDEV |
7529 WIPHY_VENDOR_CMD_NEED_RUNNING,
Edhar, Mahesh Kumar59129f52015-01-14 14:26:04 +05307530 .doit = wlan_hdd_cfg80211_exttdls_disable
Atul Mittal115287b2014-07-08 13:26:33 +05307531 },
7532 {
7533 .info.vendor_id = QCA_NL80211_VENDOR_ID,
7534 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_TDLS_GET_STATUS,
7535 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
7536 WIPHY_VENDOR_CMD_NEED_NETDEV,
Edhar, Mahesh Kumar59129f52015-01-14 14:26:04 +05307537 .doit = wlan_hdd_cfg80211_exttdls_get_status
Atul Mittal115287b2014-07-08 13:26:33 +05307538 },
Dasari Srinivas7875a302014-09-26 17:50:57 +05307539 {
7540 .info.vendor_id = QCA_NL80211_VENDOR_ID,
7541 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_GET_SUPPORTED_FEATURES,
7542 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
7543 WIPHY_VENDOR_CMD_NEED_NETDEV,
Edhar, Mahesh Kumar59129f52015-01-14 14:26:04 +05307544 .doit = wlan_hdd_cfg80211_get_supported_features
Dasari Srinivas7875a302014-09-26 17:50:57 +05307545 },
Agarwal Ashish738843c2014-09-25 12:27:56 +05307546 {
7547 .info.vendor_id = QCA_NL80211_VENDOR_ID,
7548 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_NO_DFS_FLAG,
7549 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
7550 WIPHY_VENDOR_CMD_NEED_NETDEV,
Edhar, Mahesh Kumar59129f52015-01-14 14:26:04 +05307551 .doit = wlan_hdd_cfg80211_disable_dfs_channels
Agarwal Ashish738843c2014-09-25 12:27:56 +05307552 },
Siddharth Bhala3a5cb42014-09-29 21:13:13 +05307553 {
7554 .info.vendor_id = QCA_NL80211_VENDOR_ID,
7555 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_MAC_OUI,
7556 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
7557 WIPHY_VENDOR_CMD_NEED_NETDEV,
Edhar, Mahesh Kumar59129f52015-01-14 14:26:04 +05307558 .doit = wlan_hdd_cfg80211_set_spoofed_mac_oui
Siddharth Bhala3a5cb42014-09-29 21:13:13 +05307559 },
Dasari Srinivase18b2cf2014-10-28 17:09:42 +05307560 {
7561 .info.vendor_id = QCA_NL80211_VENDOR_ID,
7562 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_GET_CONCURRENCY_MATRIX,
7563 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
7564 WIPHY_VENDOR_CMD_NEED_NETDEV,
Edhar, Mahesh Kumar59129f52015-01-14 14:26:04 +05307565 .doit = wlan_hdd_cfg80211_get_concurrency_matrix
Dasari Srinivase18b2cf2014-10-28 17:09:42 +05307566 },
Srinivas Dasari41d97c92015-07-29 13:09:39 +05307567 {
7568 .info.vendor_id = QCA_NL80211_VENDOR_ID,
c_manjeecfd1efb2015-09-25 19:32:34 +05307569 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_WIFI_LOGGER_MEMORY_DUMP,
7570 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
7571 WIPHY_VENDOR_CMD_NEED_NETDEV |
7572 WIPHY_VENDOR_CMD_NEED_RUNNING,
7573 .doit = wlan_hdd_cfg80211_get_fw_mem_dump
7574 },
7575 {
7576 .info.vendor_id = QCA_NL80211_VENDOR_ID,
Srinivas Dasari41d97c92015-07-29 13:09:39 +05307577 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_SETBAND,
7578 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
7579 WIPHY_VENDOR_CMD_NEED_NETDEV |
7580 WIPHY_VENDOR_CMD_NEED_RUNNING,
7581 .doit = wlan_hdd_cfg80211_setband
Sushant Kaushik8e644982015-09-23 12:18:54 +05307582 },
7583 {
7584 .info.vendor_id = QCA_NL80211_VENDOR_ID,
7585 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_WIFI_LOGGER_START,
7586 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
7587 WIPHY_VENDOR_CMD_NEED_NETDEV,
7588 .doit = wlan_hdd_cfg80211_wifi_logger_start
7589 },
Sushant Kaushik847890c2015-09-28 16:05:17 +05307590 {
7591 .info.vendor_id = QCA_NL80211_VENDOR_ID,
7592 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_GET_WIFI_INFO,
7593 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
7594 WIPHY_VENDOR_CMD_NEED_NETDEV|
7595 WIPHY_VENDOR_CMD_NEED_RUNNING,
7596 .doit = wlan_hdd_cfg80211_get_wifi_info
Sachin Ahujac08f72a2015-09-22 15:25:47 +05307597 },
7598 {
7599 .info.vendor_id = QCA_NL80211_VENDOR_ID,
7600 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_GET_RING_DATA,
7601 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
7602 WIPHY_VENDOR_CMD_NEED_NETDEV |
7603 WIPHY_VENDOR_CMD_NEED_RUNNING,
7604 .doit = wlan_hdd_cfg80211_wifi_logger_get_ring_data
Gupta, Kapil7c34b322015-09-30 13:12:35 +05307605 },
7606 {
7607 .info.vendor_id = QCA_NL80211_VENDOR_ID,
7608 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_MONITOR_RSSI,
7609 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
7610 WIPHY_VENDOR_CMD_NEED_NETDEV |
7611 WIPHY_VENDOR_CMD_NEED_RUNNING,
7612 .doit = wlan_hdd_cfg80211_monitor_rssi
Srinivas Girigowda8bf64cb2015-09-30 19:50:09 +05307613 },
7614#ifdef WLAN_FEATURE_OFFLOAD_PACKETS
7615 {
7616 .info.vendor_id = QCA_NL80211_VENDOR_ID,
7617 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_OFFLOADED_PACKETS,
7618 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
7619 WIPHY_VENDOR_CMD_NEED_NETDEV |
7620 WIPHY_VENDOR_CMD_NEED_RUNNING,
7621 .doit = wlan_hdd_cfg80211_offloaded_packets
Deepthi Gowriae6a1662015-10-12 12:59:37 +05307622 },
Srinivas Girigowda8bf64cb2015-09-30 19:50:09 +05307623#endif
Deepthi Gowriae6a1662015-10-12 12:59:37 +05307624 {
7625 .info.vendor_id = QCA_NL80211_VENDOR_ID,
7626 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_LINK_PROPERTIES,
7627 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
7628 WIPHY_VENDOR_CMD_NEED_NETDEV |
7629 WIPHY_VENDOR_CMD_NEED_RUNNING,
7630 .doit = wlan_hdd_cfg80211_get_link_properties
Arun Khandavalli7eeb1592015-10-19 21:36:57 +05307631 },
7632 {
7633 .info.vendor_id = QCA_NL80211_VENDOR_ID,
7634 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_SET_WIFI_CONFIGURATION,
7635 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
7636 WIPHY_VENDOR_CMD_NEED_NETDEV |
7637 WIPHY_VENDOR_CMD_NEED_RUNNING,
7638 .doit = wlan_hdd_cfg80211_wifi_configuration_set
Deepthi Gowriae6a1662015-10-12 12:59:37 +05307639 }
Sunil Duttc69bccb2014-05-26 21:30:20 +05307640};
7641
Rajesh Chauhan98a31f82014-01-06 20:15:25 -08007642/* vendor specific events */
Sunil Duttc69bccb2014-05-26 21:30:20 +05307643static const
7644struct nl80211_vendor_cmd_info wlan_hdd_cfg80211_vendor_events[] =
Rajesh Chauhan98a31f82014-01-06 20:15:25 -08007645{
7646#ifdef FEATURE_WLAN_CH_AVOID
7647 {
Sunil Duttc69bccb2014-05-26 21:30:20 +05307648 .vendor_id = QCA_NL80211_VENDOR_ID,
7649 .subcmd = QCA_NL80211_VENDOR_SUBCMD_AVOID_FREQUENCY
Rajesh Chauhan98a31f82014-01-06 20:15:25 -08007650 },
Sunil Duttc69bccb2014-05-26 21:30:20 +05307651#endif /* FEATURE_WLAN_CH_AVOID Index = 0*/
7652#ifdef WLAN_FEATURE_LINK_LAYER_STATS
7653 {
7654 /* Index = 1*/
7655 .vendor_id = QCA_NL80211_VENDOR_ID,
7656 .subcmd = QCA_NL80211_VENDOR_SUBCMD_LL_STATS_SET
7657 },
7658 {
7659 /* Index = 2*/
7660 .vendor_id = QCA_NL80211_VENDOR_ID,
7661 .subcmd = QCA_NL80211_VENDOR_SUBCMD_LL_STATS_GET
7662 },
7663 {
7664 /* Index = 3*/
7665 .vendor_id = QCA_NL80211_VENDOR_ID,
7666 .subcmd = QCA_NL80211_VENDOR_SUBCMD_LL_STATS_CLR
7667 },
7668 {
7669 /* Index = 4*/
7670 .vendor_id = QCA_NL80211_VENDOR_ID,
7671 .subcmd = QCA_NL80211_VENDOR_SUBCMD_LL_STATS_RADIO_RESULTS
7672 },
7673 {
7674 /* Index = 5*/
7675 .vendor_id = QCA_NL80211_VENDOR_ID,
7676 .subcmd = QCA_NL80211_VENDOR_SUBCMD_LL_STATS_IFACE_RESULTS
7677 },
7678 {
7679 /* Index = 6*/
7680 .vendor_id = QCA_NL80211_VENDOR_ID,
7681 .subcmd = QCA_NL80211_VENDOR_SUBCMD_LL_STATS_PEERS_RESULTS
7682 },
7683#endif /* WLAN_FEATURE_LINK_LAYER_STATS */
Dino Mycle6fb96c12014-06-10 11:52:40 +05307684#ifdef WLAN_FEATURE_EXTSCAN
7685 {
7686 .vendor_id = QCA_NL80211_VENDOR_ID,
7687 .subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_START
7688 },
7689 {
7690 .vendor_id = QCA_NL80211_VENDOR_ID,
7691 .subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_STOP
7692 },
7693 {
7694 .vendor_id = QCA_NL80211_VENDOR_ID,
7695 .subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_GET_CAPABILITIES
7696 },
7697 {
7698 .vendor_id = QCA_NL80211_VENDOR_ID,
7699 .subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_GET_CACHED_RESULTS
7700 },
7701 {
7702 .vendor_id = QCA_NL80211_VENDOR_ID,
7703 .subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_SCAN_RESULTS_AVAILABLE
7704 },
7705 {
7706 .vendor_id = QCA_NL80211_VENDOR_ID,
7707 .subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_FULL_SCAN_RESULT
7708 },
7709 {
7710 .vendor_id = QCA_NL80211_VENDOR_ID,
7711 .subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_SCAN_EVENT
7712 },
7713 {
7714 .vendor_id = QCA_NL80211_VENDOR_ID,
7715 .subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_HOTLIST_AP_FOUND
7716 },
7717 {
7718 .vendor_id = QCA_NL80211_VENDOR_ID,
7719 .subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_SET_BSSID_HOTLIST
7720 },
7721 {
7722 .vendor_id = QCA_NL80211_VENDOR_ID,
7723 .subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_RESET_BSSID_HOTLIST
7724 },
Padma, Santhosh Kumar9acee012015-08-21 19:58:01 +05307725 {
7726 .vendor_id = QCA_NL80211_VENDOR_ID,
7727 .subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_SET_SSID_HOTLIST
7728 },
7729 {
7730 .vendor_id = QCA_NL80211_VENDOR_ID,
7731 .subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_RESET_SSID_HOTLIST
7732 },
7733 [QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_HOTLIST_SSID_FOUND_INDEX] = {
7734 .vendor_id = QCA_NL80211_VENDOR_ID,
7735 .subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_HOTLIST_SSID_FOUND
7736 },
7737 [QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_HOTLIST_SSID_LOST_INDEX] = {
7738 .vendor_id = QCA_NL80211_VENDOR_ID,
7739 .subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_HOTLIST_SSID_LOST
7740 },
Dino Mycle6fb96c12014-06-10 11:52:40 +05307741#endif /* WLAN_FEATURE_EXTSCAN */
Atul Mittal115287b2014-07-08 13:26:33 +05307742/*EXT TDLS*/
7743 {
7744 .vendor_id = QCA_NL80211_VENDOR_ID,
7745 .subcmd = QCA_NL80211_VENDOR_SUBCMD_TDLS_STATE
7746 },
c_manjeecfd1efb2015-09-25 19:32:34 +05307747 [QCA_NL80211_VENDOR_SUBCMD_WIFI_LOGGER_MEMORY_DUMP_INDEX] = {
7748 .vendor_id = QCA_NL80211_VENDOR_ID,
7749 .subcmd = QCA_NL80211_VENDOR_SUBCMD_WIFI_LOGGER_MEMORY_DUMP
7750 },
7751
Srinivas Dasari030bad32015-02-18 23:23:54 +05307752
7753 {
7754 .vendor_id = QCA_NL80211_VENDOR_ID,
7755 .subcmd = QCA_NL80211_VENDOR_SUBCMD_NAN
7756 },
7757
Sushant Kaushik084f6592015-09-10 13:11:56 +05307758 {
7759 .vendor_id = QCA_NL80211_VENDOR_ID,
7760 .subcmd = QCA_NL80211_VENDOR_SUBCMD_GET_WIFI_INFO,
Gupta, Kapil7c34b322015-09-30 13:12:35 +05307761 },
7762 [QCA_NL80211_VENDOR_SUBCMD_MONITOR_RSSI_INDEX] = {
7763 .vendor_id = QCA_NL80211_VENDOR_ID,
7764 .subcmd = QCA_NL80211_VENDOR_SUBCMD_MONITOR_RSSI
7765 },
Sushant Kaushik084f6592015-09-10 13:11:56 +05307766
Rajesh Chauhan98a31f82014-01-06 20:15:25 -08007767};
7768
Jeff Johnson295189b2012-06-20 16:38:30 -07007769/*
Madan Mohan Koyyalamudi71278262013-04-12 22:00:48 +05307770 * FUNCTION: wlan_hdd_cfg80211_wiphy_alloc
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307771 * This function is called by hdd_wlan_startup()
7772 * during initialization.
Madan Mohan Koyyalamudi71278262013-04-12 22:00:48 +05307773 * This function is used to allocate wiphy structure.
Jeff Johnson295189b2012-06-20 16:38:30 -07007774 */
Madan Mohan Koyyalamudi71278262013-04-12 22:00:48 +05307775struct wiphy *wlan_hdd_cfg80211_wiphy_alloc(int priv_size)
Jeff Johnson295189b2012-06-20 16:38:30 -07007776{
7777 struct wiphy *wiphy;
7778 ENTER();
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307779 /*
7780 * Create wiphy device
Jeff Johnson295189b2012-06-20 16:38:30 -07007781 */
7782 wiphy = wiphy_new(&wlan_hdd_cfg80211_ops, priv_size);
7783
7784 if (!wiphy)
7785 {
7786 /* Print error and jump into err label and free the memory */
7787 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: wiphy init failed", __func__);
7788 return NULL;
7789 }
7790
Sunil Duttc69bccb2014-05-26 21:30:20 +05307791
Jeff Johnson295189b2012-06-20 16:38:30 -07007792 return wiphy;
7793}
7794
7795/*
7796 * FUNCTION: wlan_hdd_cfg80211_update_band
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307797 * This function is called from the supplicant through a
Jeff Johnson295189b2012-06-20 16:38:30 -07007798 * private ioctl to change the band value
7799 */
7800int wlan_hdd_cfg80211_update_band(struct wiphy *wiphy, eCsrBand eBand)
7801{
Gopichand Nakkala1f7a64f2013-04-01 18:37:17 +05307802 int i, j;
7803 eNVChannelEnabledType channelEnabledState;
7804
Jeff Johnsone7245742012-09-05 17:12:55 -07007805 ENTER();
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05307806
Gopichand Nakkala1f7a64f2013-04-01 18:37:17 +05307807 for (i = 0; i < IEEE80211_NUM_BANDS; i++)
Jeff Johnson295189b2012-06-20 16:38:30 -07007808 {
Gopichand Nakkala1f7a64f2013-04-01 18:37:17 +05307809
7810 if (NULL == wiphy->bands[i])
7811 {
7812 hddLog(VOS_TRACE_LEVEL_ERROR,"%s: wiphy->bands[i] is NULL, i = %d",
7813 __func__, i);
7814 continue;
7815 }
7816
7817 for (j = 0; j < wiphy->bands[i]->n_channels; j++)
7818 {
7819 struct ieee80211_supported_band *band = wiphy->bands[i];
7820
7821 channelEnabledState = vos_nv_getChannelEnabledState(
7822 band->channels[j].hw_value);
7823
7824 if (IEEE80211_BAND_2GHZ == i && eCSR_BAND_5G == eBand) // 5G only
7825 {
Abhishek Singh678227a2014-11-04 10:52:38 +05307826 band->channels[j].flags |= IEEE80211_CHAN_DISABLED;
Gopichand Nakkala1f7a64f2013-04-01 18:37:17 +05307827 continue;
7828 }
7829 else if (IEEE80211_BAND_5GHZ == i && eCSR_BAND_24 == eBand) // 2G only
7830 {
7831 band->channels[j].flags |= IEEE80211_CHAN_DISABLED;
7832 continue;
7833 }
7834
7835 if (NV_CHANNEL_DISABLE == channelEnabledState ||
7836 NV_CHANNEL_INVALID == channelEnabledState)
7837 {
7838 band->channels[j].flags |= IEEE80211_CHAN_DISABLED;
7839 }
7840 else if (NV_CHANNEL_DFS == channelEnabledState)
7841 {
7842 band->channels[j].flags &= ~IEEE80211_CHAN_DISABLED;
7843 band->channels[j].flags |= IEEE80211_CHAN_RADAR;
7844 }
7845 else
7846 {
7847 band->channels[j].flags &= ~(IEEE80211_CHAN_DISABLED
7848 |IEEE80211_CHAN_RADAR);
7849 }
7850 }
Jeff Johnson295189b2012-06-20 16:38:30 -07007851 }
7852 return 0;
7853}
7854/*
7855 * FUNCTION: wlan_hdd_cfg80211_init
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307856 * This function is called by hdd_wlan_startup()
7857 * during initialization.
Jeff Johnson295189b2012-06-20 16:38:30 -07007858 * This function is used to initialize and register wiphy structure.
7859 */
Madan Mohan Koyyalamudi71278262013-04-12 22:00:48 +05307860int wlan_hdd_cfg80211_init(struct device *dev,
Jeff Johnson295189b2012-06-20 16:38:30 -07007861 struct wiphy *wiphy,
7862 hdd_config_t *pCfg
7863 )
7864{
Gopichand Nakkala1f7a64f2013-04-01 18:37:17 +05307865 int i, j;
Vinay Krishna Erannafacf5e22014-02-24 13:16:25 +05307866 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
7867
Jeff Johnsone7245742012-09-05 17:12:55 -07007868 ENTER();
7869
Jeff Johnson295189b2012-06-20 16:38:30 -07007870 /* Now bind the underlying wlan device with wiphy */
7871 set_wiphy_dev(wiphy, dev);
7872
7873 wiphy->mgmt_stypes = wlan_hdd_txrx_stypes;
Amar Singhalfddc28c2013-09-05 13:03:40 -07007874
Kiet Lam6c583332013-10-14 05:37:09 +05307875#ifndef CONFIG_ENABLE_LINUX_REG
Amar Singhal0a402232013-10-11 20:57:16 -07007876 /* the flag for the other case would be initialzed in
7877 vos_init_wiphy_from_nv_bin */
Amar Singhal0a402232013-10-11 20:57:16 -07007878 wiphy->flags |= WIPHY_FLAG_STRICT_REGULATORY;
Kiet Lam6c583332013-10-14 05:37:09 +05307879#endif
Amar Singhala49cbc52013-10-08 18:37:44 -07007880
Amar Singhalfddc28c2013-09-05 13:03:40 -07007881 /* This will disable updating of NL channels from passive to
7882 * active if a beacon is received on passive channel. */
Anand N Sunkade9adb1b2015-07-29 09:56:45 +05307883#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,14,0))
7884 wiphy->regulatory_flags |= REGULATORY_DISABLE_BEACON_HINTS;
7885#else
Amar Singhalfddc28c2013-09-05 13:03:40 -07007886 wiphy->flags |= WIPHY_FLAG_DISABLE_BEACON_HINTS;
Anand N Sunkade9adb1b2015-07-29 09:56:45 +05307887#endif
Amar Singhalfddc28c2013-09-05 13:03:40 -07007888
Amar Singhala49cbc52013-10-08 18:37:44 -07007889
Jeff Johnson04dd8a82012-06-29 20:41:40 -07007890#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,4,0))
Madan Mohan Koyyalamudi1b4afb02012-10-22 15:25:16 -07007891 wiphy->flags |= WIPHY_FLAG_HAVE_AP_SME
7892 | WIPHY_FLAG_AP_PROBE_RESP_OFFLOAD
7893 | WIPHY_FLAG_HAS_REMAIN_ON_CHANNEL
Jeff Johnsone7245742012-09-05 17:12:55 -07007894 | WIPHY_FLAG_OFFCHAN_TX;
Anand N Sunkade9adb1b2015-07-29 09:56:45 +05307895#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,14,0))
7896 wiphy->regulatory_flags = REGULATORY_COUNTRY_IE_IGNORE;
7897#else
7898 wiphy->country_ie_pref = NL80211_COUNTRY_IE_IGNORE_CORE;
7899#endif
Jeff Johnson04dd8a82012-06-29 20:41:40 -07007900#endif
Amar Singhala49cbc52013-10-08 18:37:44 -07007901
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08007902#if defined (WLAN_FEATURE_VOWIFI_11R) || defined (FEATURE_WLAN_ESE) || defined(FEATURE_WLAN_LFR)
Srinivas Girigowda640728a2013-03-28 12:21:54 -07007903 if (pCfg->isFastTransitionEnabled
James Zmuda77fb5ae2013-01-29 08:00:17 -08007904#ifdef FEATURE_WLAN_LFR
Srinivas Girigowda640728a2013-03-28 12:21:54 -07007905 || pCfg->isFastRoamIniFeatureEnabled
7906#endif
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08007907#ifdef FEATURE_WLAN_ESE
7908 || pCfg->isEseIniFeatureEnabled
Srinivas Girigowda640728a2013-03-28 12:21:54 -07007909#endif
7910 )
7911 {
7912 wiphy->flags |= WIPHY_FLAG_SUPPORTS_FW_ROAM;
7913 }
James Zmuda77fb5ae2013-01-29 08:00:17 -08007914#endif
Mohit Khanna698ba2a2012-12-04 15:08:18 -08007915#ifdef FEATURE_WLAN_TDLS
7916 wiphy->flags |= WIPHY_FLAG_SUPPORTS_TDLS
7917 | WIPHY_FLAG_TDLS_EXTERNAL_SETUP;
7918#endif
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +05307919#ifdef FEATURE_WLAN_SCAN_PNO
Hardik Kantilal Patel3dfd8792013-11-13 20:34:57 +05307920 if (pCfg->configPNOScanSupport)
7921 {
7922 wiphy->flags |= WIPHY_FLAG_SUPPORTS_SCHED_SCAN;
7923 wiphy->max_sched_scan_ssids = SIR_PNO_MAX_SUPP_NETWORKS;
7924 wiphy->max_match_sets = SIR_PNO_MAX_SUPP_NETWORKS;
7925 wiphy->max_sched_scan_ie_len = SIR_MAC_MAX_IE_LENGTH;
7926 }
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +05307927#endif/*FEATURE_WLAN_SCAN_PNO*/
Mohit Khanna698ba2a2012-12-04 15:08:18 -08007928
Abhishek Singh10d85972015-04-17 10:27:23 +05307929#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,4,0))
7930 wiphy->features |= NL80211_FEATURE_HT_IBSS;
7931#endif
7932
Amar Singhalfddc28c2013-09-05 13:03:40 -07007933#ifdef CONFIG_ENABLE_LINUX_REG
Madan Mohan Koyyalamudic3a240c2012-09-28 15:34:08 -07007934 /* even with WIPHY_FLAG_CUSTOM_REGULATORY,
7935 driver can still register regulatory callback and
Amar Singhalfddc28c2013-09-05 13:03:40 -07007936 it will get regulatory settings in wiphy->band[], but
Madan Mohan Koyyalamudic3a240c2012-09-28 15:34:08 -07007937 driver need to determine what to do with both
7938 regulatory settings */
Amar Singhalfddc28c2013-09-05 13:03:40 -07007939
7940 wiphy->reg_notifier = wlan_hdd_linux_reg_notifier;
Amar Singhala49cbc52013-10-08 18:37:44 -07007941#else
7942 wiphy->reg_notifier = wlan_hdd_crda_reg_notifier;
Amar Singhalfddc28c2013-09-05 13:03:40 -07007943#endif
Jeff Johnson04dd8a82012-06-29 20:41:40 -07007944
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307945 wiphy->max_scan_ssids = MAX_SCAN_SSID;
7946
Ganesh Kondabattini7500fb32015-04-10 14:50:32 +05307947 wiphy->max_scan_ie_len = SIR_MAC_MAX_ADD_IE_LENGTH;
Jeff Johnson295189b2012-06-20 16:38:30 -07007948
Gopichand Nakkalac005b7c2013-05-14 16:04:14 +05307949 wiphy->max_acl_mac_addrs = MAX_ACL_MAC_ADDRESS;
7950
Jeff Johnson295189b2012-06-20 16:38:30 -07007951 /* Supports STATION & AD-HOC modes right now */
Bhargav Shah0d2e3e52015-07-24 16:51:01 +05307952 wiphy->interface_modes = BIT(NL80211_IFTYPE_STATION)
7953 | BIT(NL80211_IFTYPE_ADHOC)
7954 | BIT(NL80211_IFTYPE_P2P_CLIENT)
7955 | BIT(NL80211_IFTYPE_P2P_GO)
7956 | BIT(NL80211_IFTYPE_AP);
7957
7958 if (VOS_MONITOR_MODE == hdd_get_conparam())
7959 {
7960 wiphy->interface_modes |= BIT(NL80211_IFTYPE_MONITOR);
7961 }
Jeff Johnson295189b2012-06-20 16:38:30 -07007962
Rashmi Ramannabd3feb72014-02-25 16:14:48 +05307963 if( pCfg->advertiseConcurrentOperation )
Sudhir Sattayappa Kohalli278eee52013-01-16 17:35:13 -08007964 {
Rashmi Ramannabd3feb72014-02-25 16:14:48 +05307965#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,4,0))
7966 if( pCfg->enableMCC )
7967 {
7968 /* Currently, supports up to two channels */
7969 wlan_hdd_iface_combination.num_different_channels = 2;
Sudhir Sattayappa Kohalli278eee52013-01-16 17:35:13 -08007970
Rashmi Ramannabd3feb72014-02-25 16:14:48 +05307971 if( !pCfg->allowMCCGODiffBI )
7972 wlan_hdd_iface_combination.beacon_int_infra_match = true;
Sudhir Sattayappa Kohalli278eee52013-01-16 17:35:13 -08007973
Rashmi Ramannabd3feb72014-02-25 16:14:48 +05307974 }
7975 wiphy->iface_combinations = &wlan_hdd_iface_combination;
7976 wiphy->n_iface_combinations = 1;
Sudhir Sattayappa Kohalli278eee52013-01-16 17:35:13 -08007977#endif
Rashmi Ramannabd3feb72014-02-25 16:14:48 +05307978 }
Sudhir Sattayappa Kohalli278eee52013-01-16 17:35:13 -08007979
Jeff Johnson295189b2012-06-20 16:38:30 -07007980 /* Before registering we need to update the ht capabilitied based
7981 * on ini values*/
7982 if( !pCfg->ShortGI20MhzEnable )
7983 {
7984 wlan_hdd_band_2_4_GHZ.ht_cap.cap &= ~IEEE80211_HT_CAP_SGI_20;
7985 wlan_hdd_band_5_GHZ.ht_cap.cap &= ~IEEE80211_HT_CAP_SGI_20;
7986 wlan_hdd_band_p2p_2_4_GHZ.ht_cap.cap &= ~IEEE80211_HT_CAP_SGI_20;
7987 }
7988
7989 if( !pCfg->ShortGI40MhzEnable )
7990 {
7991 wlan_hdd_band_5_GHZ.ht_cap.cap &= ~IEEE80211_HT_CAP_SGI_40;
7992 }
7993
7994 if( !pCfg->nChannelBondingMode5GHz )
7995 {
7996 wlan_hdd_band_5_GHZ.ht_cap.cap &= ~IEEE80211_HT_CAP_SUP_WIDTH_20_40;
7997 }
7998
Gopichand Nakkala1f7a64f2013-04-01 18:37:17 +05307999 wiphy->bands[IEEE80211_BAND_2GHZ] = &wlan_hdd_band_2_4_GHZ;
Vinay Krishna Erannafacf5e22014-02-24 13:16:25 +05308000 if (true == hdd_is_5g_supported(pHddCtx))
8001 {
8002 wiphy->bands[IEEE80211_BAND_5GHZ] = &wlan_hdd_band_5_GHZ;
8003 }
Gopichand Nakkala1f7a64f2013-04-01 18:37:17 +05308004
8005 for (i = 0; i < IEEE80211_NUM_BANDS; i++)
8006 {
8007
8008 if (NULL == wiphy->bands[i])
8009 {
Ratheesh S P36dbc932015-08-07 14:28:57 +05308010 hddLog(VOS_TRACE_LEVEL_INFO,"%s: wiphy->bands[i] is NULL, i = %d",
Gopichand Nakkala1f7a64f2013-04-01 18:37:17 +05308011 __func__, i);
8012 continue;
8013 }
8014
8015 for (j = 0; j < wiphy->bands[i]->n_channels; j++)
8016 {
8017 struct ieee80211_supported_band *band = wiphy->bands[i];
8018
8019 if (IEEE80211_BAND_2GHZ == i && eCSR_BAND_5G == pCfg->nBandCapability) // 5G only
8020 {
8021 // Enable social channels for P2P
8022 if (WLAN_HDD_IS_SOCIAL_CHANNEL(band->channels[j].center_freq))
8023 band->channels[j].flags &= ~IEEE80211_CHAN_DISABLED;
8024 else
8025 band->channels[j].flags |= IEEE80211_CHAN_DISABLED;
8026 continue;
8027 }
8028 else if (IEEE80211_BAND_5GHZ == i && eCSR_BAND_24 == pCfg->nBandCapability) // 2G only
8029 {
8030 band->channels[j].flags |= IEEE80211_CHAN_DISABLED;
8031 continue;
8032 }
8033 }
Jeff Johnson295189b2012-06-20 16:38:30 -07008034 }
8035 /*Initialise the supported cipher suite details*/
8036 wiphy->cipher_suites = hdd_cipher_suites;
8037 wiphy->n_cipher_suites = ARRAY_SIZE(hdd_cipher_suites);
8038
8039 /*signal strength in mBm (100*dBm) */
8040 wiphy->signal_type = CFG80211_SIGNAL_TYPE_MBM;
8041
8042#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
Sushant Kaushik4f640e42014-07-08 12:27:09 +05308043 wiphy->max_remain_on_channel_duration = 5000;
Jeff Johnson295189b2012-06-20 16:38:30 -07008044#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07008045
Sunil Duttc69bccb2014-05-26 21:30:20 +05308046 wiphy->n_vendor_commands = ARRAY_SIZE(hdd_wiphy_vendor_commands);
8047 wiphy->vendor_commands = hdd_wiphy_vendor_commands;
Rajesh Chauhan98a31f82014-01-06 20:15:25 -08008048 wiphy->vendor_events = wlan_hdd_cfg80211_vendor_events;
8049 wiphy->n_vendor_events = ARRAY_SIZE(wlan_hdd_cfg80211_vendor_events);
8050
Madan Mohan Koyyalamudi71278262013-04-12 22:00:48 +05308051 EXIT();
8052 return 0;
8053}
8054
8055/* In this function we are registering wiphy. */
8056int wlan_hdd_cfg80211_register(struct wiphy *wiphy)
8057{
8058 ENTER();
8059 /* Register our wiphy dev with cfg80211 */
Jeff Johnson295189b2012-06-20 16:38:30 -07008060 if (0 > wiphy_register(wiphy))
8061 {
Madan Mohan Koyyalamudi71278262013-04-12 22:00:48 +05308062 /* print error */
Jeff Johnson295189b2012-06-20 16:38:30 -07008063 hddLog(VOS_TRACE_LEVEL_ERROR,"%s: wiphy register failed", __func__);
8064 return -EIO;
8065 }
8066
8067 EXIT();
8068 return 0;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308069}
Jeff Johnson295189b2012-06-20 16:38:30 -07008070
Madan Mohan Koyyalamudi71278262013-04-12 22:00:48 +05308071/* In this function we are updating channel list when,
8072 regulatory domain is FCC and country code is US.
8073 Here In FCC standard 5GHz UNII-1 Bands are indoor only.
8074 As per FCC smart phone is not a indoor device.
8075 GO should not opeate on indoor channels */
8076void wlan_hdd_cfg80211_update_reg_info(struct wiphy *wiphy)
8077{
8078 int j;
8079 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
8080 tANI_U8 defaultCountryCode[3] = SME_INVALID_COUNTRY_CODE;
8081 //Default counrtycode from NV at the time of wiphy initialization.
8082 if (eHAL_STATUS_SUCCESS != sme_GetDefaultCountryCodeFrmNv(pHddCtx->hHal,
8083 &defaultCountryCode[0]))
8084 {
Jeff Johnson0299d0a2013-10-30 12:37:43 -07008085 hddLog(LOGE, FL("Failed to get default country code from NV"));
Madan Mohan Koyyalamudi71278262013-04-12 22:00:48 +05308086 }
8087 if ((defaultCountryCode[0]== 'U') && (defaultCountryCode[1]=='S'))
8088 {
Madan Mohan Koyyalamudi71278262013-04-12 22:00:48 +05308089 if (NULL == wiphy->bands[IEEE80211_BAND_5GHZ])
8090 {
8091 hddLog(VOS_TRACE_LEVEL_ERROR,"%s: wiphy->bands[IEEE80211_BAND_5GHZ] is NULL",__func__ );
8092 return;
8093 }
8094 for (j = 0; j < wiphy->bands[IEEE80211_BAND_5GHZ]->n_channels; j++)
8095 {
8096 struct ieee80211_supported_band *band = wiphy->bands[IEEE80211_BAND_5GHZ];
8097 // Mark UNII -1 band channel as passive
8098 if (WLAN_HDD_CHANNEL_IN_UNII_1_BAND(band->channels[j].center_freq))
8099 band->channels[j].flags |= IEEE80211_CHAN_PASSIVE_SCAN;
8100 }
8101 }
8102}
8103
Agarwal Ashish8fa0e9a2014-05-23 00:40:12 +05308104/* This function registers for all frame which supplicant is interested in */
8105void wlan_hdd_cfg80211_register_frames(hdd_adapter_t* pAdapter)
Jeff Johnson295189b2012-06-20 16:38:30 -07008106{
Jeff Johnson295189b2012-06-20 16:38:30 -07008107 tHalHandle hHal = WLAN_HDD_GET_HAL_CTX(pAdapter);
8108 /* Register for all P2P action, public action etc frames */
8109 v_U16_t type = (SIR_MAC_MGMT_FRAME << 2) | ( SIR_MAC_MGMT_ACTION << 4);
8110
Jeff Johnsone7245742012-09-05 17:12:55 -07008111 ENTER();
8112
Jeff Johnson295189b2012-06-20 16:38:30 -07008113 /* Right now we are registering these frame when driver is getting
8114 initialized. Once we will move to 2.6.37 kernel, in which we have
8115 frame register ops, we will move this code as a part of that */
8116 /* GAS Initial Request */
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308117 sme_RegisterMgmtFrame(hHal, pAdapter->sessionId, type,
Jeff Johnson295189b2012-06-20 16:38:30 -07008118 (v_U8_t*)GAS_INITIAL_REQ, GAS_INITIAL_REQ_SIZE );
8119
8120 /* GAS Initial Response */
8121 sme_RegisterMgmtFrame(hHal, pAdapter->sessionId, type,
8122 (v_U8_t*)GAS_INITIAL_RSP, GAS_INITIAL_RSP_SIZE );
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308123
Jeff Johnson295189b2012-06-20 16:38:30 -07008124 /* GAS Comeback Request */
8125 sme_RegisterMgmtFrame(hHal, pAdapter->sessionId, type,
8126 (v_U8_t*)GAS_COMEBACK_REQ, GAS_COMEBACK_REQ_SIZE );
8127
8128 /* GAS Comeback Response */
8129 sme_RegisterMgmtFrame(hHal, pAdapter->sessionId, type,
8130 (v_U8_t*)GAS_COMEBACK_RSP, GAS_COMEBACK_RSP_SIZE );
8131
8132 /* P2P Public Action */
8133 sme_RegisterMgmtFrame(hHal, pAdapter->sessionId, type,
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308134 (v_U8_t*)P2P_PUBLIC_ACTION_FRAME,
Jeff Johnson295189b2012-06-20 16:38:30 -07008135 P2P_PUBLIC_ACTION_FRAME_SIZE );
8136
8137 /* P2P Action */
8138 sme_RegisterMgmtFrame(hHal, pAdapter->sessionId, type,
8139 (v_U8_t*)P2P_ACTION_FRAME,
8140 P2P_ACTION_FRAME_SIZE );
Chet Lanctot186b5732013-03-18 10:26:30 -07008141
Gopichand Nakkalae3d56e72013-04-21 23:33:32 +05308142 /* WNM BSS Transition Request frame */
8143 sme_RegisterMgmtFrame(hHal, pAdapter->sessionId, type,
8144 (v_U8_t*)WNM_BSS_ACTION_FRAME,
8145 WNM_BSS_ACTION_FRAME_SIZE );
Leela Venkata Kiran Kumar Reddy Chiralae8e62c82013-10-29 18:23:26 -07008146
8147 /* WNM-Notification */
8148 sme_RegisterMgmtFrame(hHal, pAdapter->sessionId, type,
8149 (v_U8_t*)WNM_NOTIFICATION_FRAME,
8150 WNM_NOTIFICATION_FRAME_SIZE );
Jeff Johnson295189b2012-06-20 16:38:30 -07008151}
8152
Agarwal Ashish8fa0e9a2014-05-23 00:40:12 +05308153void wlan_hdd_cfg80211_deregister_frames(hdd_adapter_t* pAdapter)
Jeff Johnson295189b2012-06-20 16:38:30 -07008154{
Jeff Johnson295189b2012-06-20 16:38:30 -07008155 tHalHandle hHal = WLAN_HDD_GET_HAL_CTX(pAdapter);
8156 /* Register for all P2P action, public action etc frames */
8157 v_U16_t type = (SIR_MAC_MGMT_FRAME << 2) | ( SIR_MAC_MGMT_ACTION << 4);
8158
Jeff Johnsone7245742012-09-05 17:12:55 -07008159 ENTER();
8160
Jeff Johnson295189b2012-06-20 16:38:30 -07008161 /* Right now we are registering these frame when driver is getting
8162 initialized. Once we will move to 2.6.37 kernel, in which we have
8163 frame register ops, we will move this code as a part of that */
8164 /* GAS Initial Request */
8165
8166 sme_DeregisterMgmtFrame(hHal, pAdapter->sessionId, type,
8167 (v_U8_t*)GAS_INITIAL_REQ, GAS_INITIAL_REQ_SIZE );
8168
8169 /* GAS Initial Response */
8170 sme_DeregisterMgmtFrame(hHal, pAdapter->sessionId, type,
8171 (v_U8_t*)GAS_INITIAL_RSP, GAS_INITIAL_RSP_SIZE );
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308172
Jeff Johnson295189b2012-06-20 16:38:30 -07008173 /* GAS Comeback Request */
8174 sme_DeregisterMgmtFrame(hHal, pAdapter->sessionId, type,
8175 (v_U8_t*)GAS_COMEBACK_REQ, GAS_COMEBACK_REQ_SIZE );
8176
8177 /* GAS Comeback Response */
8178 sme_DeregisterMgmtFrame(hHal, pAdapter->sessionId, type,
8179 (v_U8_t*)GAS_COMEBACK_RSP, GAS_COMEBACK_RSP_SIZE );
8180
8181 /* P2P Public Action */
8182 sme_DeregisterMgmtFrame(hHal, pAdapter->sessionId, type,
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308183 (v_U8_t*)P2P_PUBLIC_ACTION_FRAME,
Jeff Johnson295189b2012-06-20 16:38:30 -07008184 P2P_PUBLIC_ACTION_FRAME_SIZE );
8185
8186 /* P2P Action */
8187 sme_DeregisterMgmtFrame(hHal, pAdapter->sessionId, type,
8188 (v_U8_t*)P2P_ACTION_FRAME,
8189 P2P_ACTION_FRAME_SIZE );
Leela Venkata Kiran Kumar Reddy Chiralae8e62c82013-10-29 18:23:26 -07008190 /* WNM-Notification */
8191 sme_DeregisterMgmtFrame(hHal, pAdapter->sessionId, type,
8192 (v_U8_t*)WNM_NOTIFICATION_FRAME,
8193 WNM_NOTIFICATION_FRAME_SIZE );
Jeff Johnson295189b2012-06-20 16:38:30 -07008194}
8195
8196#ifdef FEATURE_WLAN_WAPI
8197void wlan_hdd_cfg80211_set_key_wapi(hdd_adapter_t* pAdapter, u8 key_index,
Anand N Sunkad9bfc2622015-07-30 15:18:54 +05308198 const u8 *mac_addr, const u8 *key , int key_Len)
Jeff Johnson295189b2012-06-20 16:38:30 -07008199{
8200 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
8201 tCsrRoamSetKey setKey;
8202 v_BOOL_t isConnected = TRUE;
8203 int status = 0;
8204 v_U32_t roamId= 0xFF;
8205 tANI_U8 *pKeyPtr = NULL;
8206 int n = 0;
8207
Sushant Kaushik8bc7df22014-04-09 17:55:29 +05308208 hddLog(VOS_TRACE_LEVEL_INFO, "%s: device_mode = %s(%d)",
8209 __func__, hdd_device_modetoString(pAdapter->device_mode),
8210 pAdapter->device_mode);
Jeff Johnson295189b2012-06-20 16:38:30 -07008211
Gopichand Nakkalae7480202013-02-11 15:24:22 +05308212 vos_mem_zero(&setKey, sizeof(tCsrRoamSetKey));
Jeff Johnson295189b2012-06-20 16:38:30 -07008213 setKey.keyId = key_index; // Store Key ID
8214 setKey.encType = eCSR_ENCRYPT_TYPE_WPI; // SET WAPI Encryption
8215 setKey.keyDirection = eSIR_TX_RX; // Key Directionn both TX and RX
8216 setKey.paeRole = 0 ; // the PAE role
8217 if (!mac_addr || is_broadcast_ether_addr(mac_addr))
8218 {
8219 vos_set_macaddr_broadcast( (v_MACADDR_t *)setKey.peerMac );
8220 }
8221 else
8222 {
8223 isConnected = hdd_connIsConnected(pHddStaCtx);
8224 vos_mem_copy(setKey.peerMac,&pHddStaCtx->conn_info.bssId,WNI_CFG_BSSID_LEN);
8225 }
8226 setKey.keyLength = key_Len;
8227 pKeyPtr = setKey.Key;
8228 memcpy( pKeyPtr, key, key_Len);
8229
Arif Hussain6d2a3322013-11-17 19:50:10 -08008230 hddLog(VOS_TRACE_LEVEL_INFO,"%s: WAPI KEY LENGTH:0x%04x",
Jeff Johnson295189b2012-06-20 16:38:30 -07008231 __func__, key_Len);
8232 for (n = 0 ; n < key_Len; n++)
8233 hddLog(VOS_TRACE_LEVEL_INFO, "%s WAPI KEY Data[%d]:%02x ",
8234 __func__,n,setKey.Key[n]);
8235
8236 pHddStaCtx->roam_info.roamingState = HDD_ROAM_STATE_SETTING_KEY;
8237 if ( isConnected )
8238 {
8239 status= sme_RoamSetKey( WLAN_HDD_GET_HAL_CTX(pAdapter),
8240 pAdapter->sessionId, &setKey, &roamId );
8241 }
8242 if ( status != 0 )
8243 {
8244 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
8245 "[%4d] sme_RoamSetKey returned ERROR status= %d",
8246 __LINE__, status );
8247 pHddStaCtx->roam_info.roamingState = HDD_ROAM_STATE_NONE;
8248 }
Vinay Krishna Eranna6f22c1f2014-10-13 16:03:06 +05308249 /* Need to clear any trace of key value in the memory.
8250 * Thus zero out the memory even though it is local
8251 * variable.
8252 */
8253 vos_mem_zero(&setKey, sizeof(setKey));
Jeff Johnson295189b2012-06-20 16:38:30 -07008254}
8255#endif /* FEATURE_WLAN_WAPI*/
8256
8257#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,4,0))
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308258int wlan_hdd_cfg80211_alloc_new_beacon(hdd_adapter_t *pAdapter,
Jeff Johnson295189b2012-06-20 16:38:30 -07008259 beacon_data_t **ppBeacon,
8260 struct beacon_parameters *params)
Jeff Johnson04dd8a82012-06-29 20:41:40 -07008261#else
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308262int wlan_hdd_cfg80211_alloc_new_beacon(hdd_adapter_t *pAdapter,
Jeff Johnson04dd8a82012-06-29 20:41:40 -07008263 beacon_data_t **ppBeacon,
8264 struct cfg80211_beacon_data *params,
8265 int dtim_period)
8266#endif
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308267{
Jeff Johnson295189b2012-06-20 16:38:30 -07008268 int size;
8269 beacon_data_t *beacon = NULL;
8270 beacon_data_t *old = NULL;
8271 int head_len,tail_len;
8272
Jeff Johnsone7245742012-09-05 17:12:55 -07008273 ENTER();
Jeff Johnson295189b2012-06-20 16:38:30 -07008274 if (params->head && !params->head_len)
c_hpothu6ff1c3c2013-10-01 19:01:57 +05308275 {
8276 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
8277 FL("head_len is NULL"));
Jeff Johnson295189b2012-06-20 16:38:30 -07008278 return -EINVAL;
c_hpothu6ff1c3c2013-10-01 19:01:57 +05308279 }
Jeff Johnson295189b2012-06-20 16:38:30 -07008280
8281 old = pAdapter->sessionCtx.ap.beacon;
8282
8283 if (!params->head && !old)
c_hpothu6ff1c3c2013-10-01 19:01:57 +05308284 {
8285 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
8286 FL("session(%d) old and new heads points to NULL"),
8287 pAdapter->sessionId);
Jeff Johnson295189b2012-06-20 16:38:30 -07008288 return -EINVAL;
c_hpothu6ff1c3c2013-10-01 19:01:57 +05308289 }
8290
8291 if (params->tail && !params->tail_len)
8292 {
8293 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
8294 FL("tail_len is zero but tail is not NULL"));
8295 return -EINVAL;
8296 }
Jeff Johnson295189b2012-06-20 16:38:30 -07008297
Jeff Johnson295189b2012-06-20 16:38:30 -07008298#if (LINUX_VERSION_CODE <= KERNEL_VERSION(2,6,38))
8299 /* Kernel 3.0 is not updating dtim_period for set beacon */
8300 if (!params->dtim_period)
c_hpothu6ff1c3c2013-10-01 19:01:57 +05308301 {
8302 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
8303 FL("dtim period is 0"));
Jeff Johnson295189b2012-06-20 16:38:30 -07008304 return -EINVAL;
c_hpothu6ff1c3c2013-10-01 19:01:57 +05308305 }
Jeff Johnson295189b2012-06-20 16:38:30 -07008306#endif
8307
8308 if(params->head)
8309 head_len = params->head_len;
8310 else
8311 head_len = old->head_len;
8312
8313 if(params->tail || !old)
8314 tail_len = params->tail_len;
8315 else
8316 tail_len = old->tail_len;
8317
8318 size = sizeof(beacon_data_t) + head_len + tail_len;
8319
8320 beacon = kzalloc(size, GFP_KERNEL);
8321
8322 if( beacon == NULL )
c_hpothu6ff1c3c2013-10-01 19:01:57 +05308323 {
8324 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
8325 FL("Mem allocation for beacon failed"));
Jeff Johnson295189b2012-06-20 16:38:30 -07008326 return -ENOMEM;
c_hpothu6ff1c3c2013-10-01 19:01:57 +05308327 }
Jeff Johnson295189b2012-06-20 16:38:30 -07008328
Jeff Johnson04dd8a82012-06-29 20:41:40 -07008329#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,4,0))
Jeff Johnson295189b2012-06-20 16:38:30 -07008330 if(params->dtim_period || !old )
8331 beacon->dtim_period = params->dtim_period;
8332 else
8333 beacon->dtim_period = old->dtim_period;
Jeff Johnson04dd8a82012-06-29 20:41:40 -07008334#else
8335 if(dtim_period || !old )
8336 beacon->dtim_period = dtim_period;
8337 else
8338 beacon->dtim_period = old->dtim_period;
8339#endif
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308340
Jeff Johnson295189b2012-06-20 16:38:30 -07008341 beacon->head = ((u8 *) beacon) + sizeof(beacon_data_t);
8342 beacon->tail = beacon->head + head_len;
8343 beacon->head_len = head_len;
8344 beacon->tail_len = tail_len;
8345
8346 if(params->head) {
8347 memcpy (beacon->head,params->head,beacon->head_len);
8348 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308349 else {
Jeff Johnson295189b2012-06-20 16:38:30 -07008350 if(old)
8351 memcpy (beacon->head,old->head,beacon->head_len);
8352 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308353
Jeff Johnson295189b2012-06-20 16:38:30 -07008354 if(params->tail) {
8355 memcpy (beacon->tail,params->tail,beacon->tail_len);
8356 }
8357 else {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308358 if(old)
Jeff Johnson295189b2012-06-20 16:38:30 -07008359 memcpy (beacon->tail,old->tail,beacon->tail_len);
8360 }
8361
8362 *ppBeacon = beacon;
8363
8364 kfree(old);
8365
8366 return 0;
8367
8368}
Jeff Johnson295189b2012-06-20 16:38:30 -07008369
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +05308370v_U8_t* wlan_hdd_cfg80211_get_ie_ptr(
8371#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 18, 0))
8372 const v_U8_t *pIes,
8373#else
8374 v_U8_t *pIes,
8375#endif
8376 int length, v_U8_t eid)
Jeff Johnson295189b2012-06-20 16:38:30 -07008377{
8378 int left = length;
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +05308379 v_U8_t *ptr = (v_U8_t *)pIes;
Jeff Johnson295189b2012-06-20 16:38:30 -07008380 v_U8_t elem_id,elem_len;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308381
Jeff Johnson295189b2012-06-20 16:38:30 -07008382 while(left >= 2)
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308383 {
Jeff Johnson295189b2012-06-20 16:38:30 -07008384 elem_id = ptr[0];
8385 elem_len = ptr[1];
8386 left -= 2;
8387 if(elem_len > left)
8388 {
8389 hddLog(VOS_TRACE_LEVEL_FATAL,
Madan Mohan Koyyalamudi8bdd3112012-09-24 13:55:14 -07008390 FL("****Invalid IEs eid = %d elem_len=%d left=%d*****"),
Jeff Johnson295189b2012-06-20 16:38:30 -07008391 eid,elem_len,left);
8392 return NULL;
8393 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308394 if (elem_id == eid)
Jeff Johnson295189b2012-06-20 16:38:30 -07008395 {
8396 return ptr;
8397 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308398
Jeff Johnson295189b2012-06-20 16:38:30 -07008399 left -= elem_len;
8400 ptr += (elem_len + 2);
8401 }
8402 return NULL;
8403}
8404
Jeff Johnson295189b2012-06-20 16:38:30 -07008405/* Check if rate is 11g rate or not */
8406static int wlan_hdd_rate_is_11g(u8 rate)
8407{
Sanjay Devnani28322e22013-06-21 16:13:40 -07008408 static const u8 gRateArray[8] = {12, 18, 24, 36, 48, 72, 96, 108}; /* actual rate * 2 */
Jeff Johnson295189b2012-06-20 16:38:30 -07008409 u8 i;
8410 for (i = 0; i < 8; i++)
8411 {
8412 if(rate == gRateArray[i])
8413 return TRUE;
8414 }
8415 return FALSE;
8416}
8417
8418/* Check for 11g rate and set proper 11g only mode */
8419static void wlan_hdd_check_11gmode(u8 *pIe, u8* require_ht,
8420 u8* pCheckRatesfor11g, eSapPhyMode* pSapHw_mode)
8421{
8422 u8 i, num_rates = pIe[0];
8423
8424 pIe += 1;
8425 for ( i = 0; i < num_rates; i++)
8426 {
8427 if( *pCheckRatesfor11g && (TRUE == wlan_hdd_rate_is_11g(pIe[i] & RATE_MASK)))
8428 {
8429 /* If rate set have 11g rate than change the mode to 11G */
8430 *pSapHw_mode = eSAP_DOT11_MODE_11g;
8431 if (pIe[i] & BASIC_RATE_MASK)
8432 {
8433 /* If we have 11g rate as basic rate, it means mode
8434 is 11g only mode.
8435 */
8436 *pSapHw_mode = eSAP_DOT11_MODE_11g_ONLY;
8437 *pCheckRatesfor11g = FALSE;
8438 }
8439 }
8440 else if((BASIC_RATE_MASK | WLAN_BSS_MEMBERSHIP_SELECTOR_HT_PHY) == pIe[i])
8441 {
8442 *require_ht = TRUE;
8443 }
8444 }
8445 return;
8446}
8447
8448static void wlan_hdd_set_sapHwmode(hdd_adapter_t *pHostapdAdapter)
8449{
8450 tsap_Config_t *pConfig = &pHostapdAdapter->sessionCtx.ap.sapConfig;
8451 beacon_data_t *pBeacon = pHostapdAdapter->sessionCtx.ap.beacon;
8452 struct ieee80211_mgmt *pMgmt_frame = (struct ieee80211_mgmt*)pBeacon->head;
8453 u8 checkRatesfor11g = TRUE;
8454 u8 require_ht = FALSE;
8455 u8 *pIe=NULL;
8456
8457 pConfig->SapHw_mode= eSAP_DOT11_MODE_11b;
8458
8459 pIe = wlan_hdd_cfg80211_get_ie_ptr(&pMgmt_frame->u.beacon.variable[0],
8460 pBeacon->head_len, WLAN_EID_SUPP_RATES);
8461 if (pIe != NULL)
8462 {
8463 pIe += 1;
8464 wlan_hdd_check_11gmode(pIe, &require_ht, &checkRatesfor11g,
8465 &pConfig->SapHw_mode);
8466 }
8467
8468 pIe = wlan_hdd_cfg80211_get_ie_ptr(pBeacon->tail, pBeacon->tail_len,
8469 WLAN_EID_EXT_SUPP_RATES);
8470 if (pIe != NULL)
8471 {
8472
8473 pIe += 1;
8474 wlan_hdd_check_11gmode(pIe, &require_ht, &checkRatesfor11g,
8475 &pConfig->SapHw_mode);
8476 }
8477
8478 if( pConfig->channel > 14 )
8479 {
8480 pConfig->SapHw_mode= eSAP_DOT11_MODE_11a;
8481 }
8482
8483 pIe = wlan_hdd_cfg80211_get_ie_ptr(pBeacon->tail, pBeacon->tail_len,
8484 WLAN_EID_HT_CAPABILITY);
8485
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308486 if(pIe)
Jeff Johnson295189b2012-06-20 16:38:30 -07008487 {
8488 pConfig->SapHw_mode= eSAP_DOT11_MODE_11n;
8489 if(require_ht)
8490 pConfig->SapHw_mode= eSAP_DOT11_MODE_11n_ONLY;
8491 }
8492}
8493
Gopichand Nakkala2b25f4e2013-03-21 19:14:07 +05308494static int wlan_hdd_add_ie(hdd_adapter_t* pHostapdAdapter, v_U8_t *genie,
8495 v_U8_t *total_ielen, v_U8_t *oui, v_U8_t oui_size)
8496{
Arif Hussaine7f3ea52013-09-12 21:56:36 -07008497 v_U16_t ielen = 0;
Gopichand Nakkala2b25f4e2013-03-21 19:14:07 +05308498 v_U8_t *pIe = NULL;
8499 beacon_data_t *pBeacon = pHostapdAdapter->sessionCtx.ap.beacon;
8500
8501 pIe = wlan_hdd_get_vendor_oui_ie_ptr(oui, oui_size,
8502 pBeacon->tail, pBeacon->tail_len);
8503
8504 if (pIe)
8505 {
8506 ielen = pIe[1] + 2;
8507 if ((*total_ielen + ielen) <= MAX_GENIE_LEN)
8508 {
8509 vos_mem_copy(&genie[*total_ielen], pIe, ielen);
8510 }
8511 else
8512 {
8513 hddLog( VOS_TRACE_LEVEL_ERROR, "**Ie Length is too big***");
8514 return -EINVAL;
8515 }
8516 *total_ielen += ielen;
8517 }
8518 return 0;
8519}
8520
Arif Hussaine7f3ea52013-09-12 21:56:36 -07008521static void wlan_hdd_add_hostapd_conf_vsie(hdd_adapter_t* pHostapdAdapter,
8522 v_U8_t *genie, v_U8_t *total_ielen)
8523{
8524 beacon_data_t *pBeacon = pHostapdAdapter->sessionCtx.ap.beacon;
8525 int left = pBeacon->tail_len;
8526 v_U8_t *ptr = pBeacon->tail;
8527 v_U8_t elem_id, elem_len;
8528 v_U16_t ielen = 0;
8529
8530 if ( NULL == ptr || 0 == left )
8531 return;
8532
8533 while (left >= 2)
8534 {
8535 elem_id = ptr[0];
8536 elem_len = ptr[1];
8537 left -= 2;
8538 if (elem_len > left)
8539 {
8540 hddLog( VOS_TRACE_LEVEL_ERROR,
8541 "****Invalid IEs eid = %d elem_len=%d left=%d*****",
8542 elem_id, elem_len, left);
8543 return;
8544 }
8545 if (IE_EID_VENDOR == elem_id)
8546 {
8547 /* skipping the VSIE's which we don't want to include or
8548 * it will be included by existing code
8549 */
8550 if ((memcmp( &ptr[2], WPS_OUI_TYPE, WPS_OUI_TYPE_SIZE) != 0 ) &&
8551#ifdef WLAN_FEATURE_WFD
8552 (memcmp( &ptr[2], WFD_OUI_TYPE, WFD_OUI_TYPE_SIZE) != 0) &&
8553#endif
8554 (memcmp( &ptr[2], WHITELIST_OUI_TYPE, WPA_OUI_TYPE_SIZE) != 0) &&
8555 (memcmp( &ptr[2], BLACKLIST_OUI_TYPE, WPA_OUI_TYPE_SIZE) != 0) &&
8556 (memcmp( &ptr[2], "\x00\x50\xf2\x02", WPA_OUI_TYPE_SIZE) != 0) &&
8557 (memcmp( &ptr[2], WPA_OUI_TYPE, WPA_OUI_TYPE_SIZE) != 0) &&
8558 (memcmp( &ptr[2], P2P_OUI_TYPE, P2P_OUI_TYPE_SIZE) != 0))
8559 {
8560 ielen = ptr[1] + 2;
8561 if ((*total_ielen + ielen) <= MAX_GENIE_LEN)
8562 {
8563 vos_mem_copy(&genie[*total_ielen], ptr, ielen);
8564 *total_ielen += ielen;
8565 }
8566 else
8567 {
8568 hddLog( VOS_TRACE_LEVEL_ERROR,
8569 "IE Length is too big "
8570 "IEs eid=%d elem_len=%d total_ie_lent=%d",
8571 elem_id, elem_len, *total_ielen);
8572 }
8573 }
8574 }
8575
8576 left -= elem_len;
8577 ptr += (elem_len + 2);
8578 }
8579 return;
8580}
8581
Jeff Johnson04dd8a82012-06-29 20:41:40 -07008582#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,4,0))
Jeff Johnson295189b2012-06-20 16:38:30 -07008583static int wlan_hdd_cfg80211_update_apies(hdd_adapter_t* pHostapdAdapter,
8584 struct beacon_parameters *params)
Jeff Johnson04dd8a82012-06-29 20:41:40 -07008585#else
8586static int wlan_hdd_cfg80211_update_apies(hdd_adapter_t* pHostapdAdapter,
8587 struct cfg80211_beacon_data *params)
8588#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07008589{
8590 v_U8_t *genie;
Gopichand Nakkala2b25f4e2013-03-21 19:14:07 +05308591 v_U8_t total_ielen = 0;
Jeff Johnson295189b2012-06-20 16:38:30 -07008592 v_U8_t addIE[1] = {0};
Jeff Johnsone7245742012-09-05 17:12:55 -07008593 int ret = 0;
Jeff Johnson295189b2012-06-20 16:38:30 -07008594
8595 genie = vos_mem_malloc(MAX_GENIE_LEN);
8596
8597 if(genie == NULL) {
8598
8599 return -ENOMEM;
8600 }
8601
Gopichand Nakkala2b25f4e2013-03-21 19:14:07 +05308602 if (0 != wlan_hdd_add_ie(pHostapdAdapter, genie,
8603 &total_ielen, WPS_OUI_TYPE, WPS_OUI_TYPE_SIZE))
Jeff Johnson295189b2012-06-20 16:38:30 -07008604 {
c_hpothu6ff1c3c2013-10-01 19:01:57 +05308605 hddLog(LOGE,
8606 FL("Adding WPS IE failed"));
Gopichand Nakkala2b25f4e2013-03-21 19:14:07 +05308607 ret = -EINVAL;
8608 goto done;
Jeff Johnson295189b2012-06-20 16:38:30 -07008609 }
8610
8611#ifdef WLAN_FEATURE_WFD
Gopichand Nakkala2b25f4e2013-03-21 19:14:07 +05308612 if (0 != wlan_hdd_add_ie(pHostapdAdapter, genie,
8613 &total_ielen, WFD_OUI_TYPE, WFD_OUI_TYPE_SIZE))
8614 {
c_hpothu6ff1c3c2013-10-01 19:01:57 +05308615 hddLog(LOGE,
8616 FL("Adding WFD IE failed"));
Gopichand Nakkala2b25f4e2013-03-21 19:14:07 +05308617 ret = -EINVAL;
8618 goto done;
Jeff Johnson295189b2012-06-20 16:38:30 -07008619 }
8620#endif
8621
Gopichand Nakkala2b25f4e2013-03-21 19:14:07 +05308622 if (0 != wlan_hdd_add_ie(pHostapdAdapter, genie,
8623 &total_ielen, P2P_OUI_TYPE, P2P_OUI_TYPE_SIZE))
Jeff Johnson295189b2012-06-20 16:38:30 -07008624 {
c_hpothu6ff1c3c2013-10-01 19:01:57 +05308625 hddLog(LOGE,
8626 FL("Adding P2P IE failed"));
Gopichand Nakkala2b25f4e2013-03-21 19:14:07 +05308627 ret = -EINVAL;
8628 goto done;
8629 }
8630
8631 if (WLAN_HDD_SOFTAP == pHostapdAdapter->device_mode)
8632 {
Arif Hussaine7f3ea52013-09-12 21:56:36 -07008633 wlan_hdd_add_hostapd_conf_vsie(pHostapdAdapter, genie, &total_ielen);
Jeff Johnson295189b2012-06-20 16:38:30 -07008634 }
Jeff Johnson295189b2012-06-20 16:38:30 -07008635
8636 if (ccmCfgSetStr((WLAN_HDD_GET_CTX(pHostapdAdapter))->hHal,
8637 WNI_CFG_PROBE_RSP_BCN_ADDNIE_DATA, genie, total_ielen, NULL,
8638 eANI_BOOLEAN_FALSE)==eHAL_STATUS_FAILURE)
8639 {
8640 hddLog(LOGE,
8641 "Could not pass on WNI_CFG_PROBE_RSP_BCN_ADDNIE_DATA to CCM");
Jeff Johnsone7245742012-09-05 17:12:55 -07008642 ret = -EINVAL;
8643 goto done;
Jeff Johnson295189b2012-06-20 16:38:30 -07008644 }
8645
8646 if (ccmCfgSetInt((WLAN_HDD_GET_CTX(pHostapdAdapter))->hHal,
8647 WNI_CFG_PROBE_RSP_BCN_ADDNIE_FLAG, 1,NULL,
8648 test_bit(SOFTAP_BSS_STARTED, &pHostapdAdapter->event_flags) ?
8649 eANI_BOOLEAN_TRUE : eANI_BOOLEAN_FALSE)
8650 ==eHAL_STATUS_FAILURE)
8651 {
8652 hddLog(LOGE,
8653 "Could not pass on WNI_CFG_PROBE_RSP_BCN_ADDNIE_FLAG to CCM");
Jeff Johnsone7245742012-09-05 17:12:55 -07008654 ret = -EINVAL;
8655 goto done;
Jeff Johnson295189b2012-06-20 16:38:30 -07008656 }
8657
8658 // Added for ProResp IE
8659 if ( (params->proberesp_ies != NULL) && (params->proberesp_ies_len != 0) )
8660 {
8661 u16 rem_probe_resp_ie_len = params->proberesp_ies_len;
8662 u8 probe_rsp_ie_len[3] = {0};
8663 u8 counter = 0;
8664 /* Check Probe Resp Length if it is greater then 255 then Store
8665 Probe Resp IEs into WNI_CFG_PROBE_RSP_ADDNIE_DATA1 &
8666 WNI_CFG_PROBE_RSP_ADDNIE_DATA2 CFG Variable As We are not able
8667 Store More then 255 bytes into One Variable.
8668 */
8669 while ((rem_probe_resp_ie_len > 0) && (counter < 3))
8670 {
8671 if (rem_probe_resp_ie_len > MAX_CFG_STRING_LEN)
8672 {
8673 probe_rsp_ie_len[counter++] = MAX_CFG_STRING_LEN;
8674 rem_probe_resp_ie_len -= MAX_CFG_STRING_LEN;
8675 }
8676 else
8677 {
8678 probe_rsp_ie_len[counter++] = rem_probe_resp_ie_len;
8679 rem_probe_resp_ie_len = 0;
8680 }
8681 }
8682
8683 rem_probe_resp_ie_len = 0;
8684
8685 if (probe_rsp_ie_len[0] > 0)
8686 {
8687 if (ccmCfgSetStr((WLAN_HDD_GET_CTX(pHostapdAdapter))->hHal,
8688 WNI_CFG_PROBE_RSP_ADDNIE_DATA1,
8689 (tANI_U8*)&params->proberesp_ies[rem_probe_resp_ie_len],
8690 probe_rsp_ie_len[0], NULL,
8691 eANI_BOOLEAN_FALSE) == eHAL_STATUS_FAILURE)
8692 {
8693 hddLog(LOGE,
8694 "Could not pass on WNI_CFG_PROBE_RSP_ADDNIE_DATA1 to CCM");
Jeff Johnsone7245742012-09-05 17:12:55 -07008695 ret = -EINVAL;
8696 goto done;
Jeff Johnson295189b2012-06-20 16:38:30 -07008697 }
8698 rem_probe_resp_ie_len += probe_rsp_ie_len[0];
8699 }
8700
8701 if (probe_rsp_ie_len[1] > 0)
8702 {
8703 if (ccmCfgSetStr((WLAN_HDD_GET_CTX(pHostapdAdapter))->hHal,
8704 WNI_CFG_PROBE_RSP_ADDNIE_DATA2,
8705 (tANI_U8*)&params->proberesp_ies[rem_probe_resp_ie_len],
8706 probe_rsp_ie_len[1], NULL,
8707 eANI_BOOLEAN_FALSE) == eHAL_STATUS_FAILURE)
8708 {
8709 hddLog(LOGE,
8710 "Could not pass on WNI_CFG_PROBE_RSP_ADDNIE_DATA2 to CCM");
Jeff Johnsone7245742012-09-05 17:12:55 -07008711 ret = -EINVAL;
8712 goto done;
Jeff Johnson295189b2012-06-20 16:38:30 -07008713 }
8714 rem_probe_resp_ie_len += probe_rsp_ie_len[1];
8715 }
8716
8717 if (probe_rsp_ie_len[2] > 0)
8718 {
8719 if (ccmCfgSetStr((WLAN_HDD_GET_CTX(pHostapdAdapter))->hHal,
8720 WNI_CFG_PROBE_RSP_ADDNIE_DATA3,
8721 (tANI_U8*)&params->proberesp_ies[rem_probe_resp_ie_len],
8722 probe_rsp_ie_len[2], NULL,
8723 eANI_BOOLEAN_FALSE) == eHAL_STATUS_FAILURE)
8724 {
8725 hddLog(LOGE,
8726 "Could not pass on WNI_CFG_PROBE_RSP_ADDNIE_DATA3 to CCM");
Jeff Johnsone7245742012-09-05 17:12:55 -07008727 ret = -EINVAL;
8728 goto done;
Jeff Johnson295189b2012-06-20 16:38:30 -07008729 }
8730 rem_probe_resp_ie_len += probe_rsp_ie_len[2];
8731 }
8732
8733 if (probe_rsp_ie_len[1] == 0 )
8734 {
8735 if ( eHAL_STATUS_FAILURE == ccmCfgSetStr((WLAN_HDD_GET_CTX(pHostapdAdapter))->hHal,
8736 WNI_CFG_PROBE_RSP_ADDNIE_DATA2, (tANI_U8*)addIE, 0, NULL,
8737 eANI_BOOLEAN_FALSE) )
8738 {
8739 hddLog(LOGE,
Arif Hussain6d2a3322013-11-17 19:50:10 -08008740 "Could not pass on WNI_CFG_PROBE_RSP_ADDNIE_DATA2 to CCM");
Jeff Johnson295189b2012-06-20 16:38:30 -07008741 }
8742 }
8743
8744 if (probe_rsp_ie_len[2] == 0 )
8745 {
8746 if ( eHAL_STATUS_FAILURE == ccmCfgSetStr((WLAN_HDD_GET_CTX(pHostapdAdapter))->hHal,
8747 WNI_CFG_PROBE_RSP_ADDNIE_DATA3, (tANI_U8*)addIE, 0, NULL,
8748 eANI_BOOLEAN_FALSE) )
8749 {
8750 hddLog(LOGE,
Arif Hussain6d2a3322013-11-17 19:50:10 -08008751 "Could not pass on WNI_CFG_PROBE_RSP_ADDNIE_DATA3 to CCM");
Jeff Johnson295189b2012-06-20 16:38:30 -07008752 }
8753 }
8754
8755 if (ccmCfgSetInt((WLAN_HDD_GET_CTX(pHostapdAdapter))->hHal,
8756 WNI_CFG_PROBE_RSP_ADDNIE_FLAG, 1,NULL,
8757 test_bit(SOFTAP_BSS_STARTED, &pHostapdAdapter->event_flags) ?
8758 eANI_BOOLEAN_TRUE : eANI_BOOLEAN_FALSE)
8759 == eHAL_STATUS_FAILURE)
8760 {
8761 hddLog(LOGE,
8762 "Could not pass on WNI_CFG_PROBE_RSP_ADDNIE_FLAG to CCM");
Jeff Johnsone7245742012-09-05 17:12:55 -07008763 ret = -EINVAL;
8764 goto done;
Jeff Johnson295189b2012-06-20 16:38:30 -07008765 }
8766 }
8767 else
8768 {
8769 // Reset WNI_CFG_PROBE_RSP Flags
8770 wlan_hdd_reset_prob_rspies(pHostapdAdapter);
8771
8772 hddLog(VOS_TRACE_LEVEL_INFO,
8773 "%s: No Probe Response IE received in set beacon",
8774 __func__);
8775 }
8776
8777 // Added for AssocResp IE
8778 if ( (params->assocresp_ies != NULL) && (params->assocresp_ies_len != 0) )
8779 {
8780 if (ccmCfgSetStr((WLAN_HDD_GET_CTX(pHostapdAdapter))->hHal,
8781 WNI_CFG_ASSOC_RSP_ADDNIE_DATA, (tANI_U8*)params->assocresp_ies,
8782 params->assocresp_ies_len, NULL,
8783 eANI_BOOLEAN_FALSE) == eHAL_STATUS_FAILURE)
8784 {
8785 hddLog(LOGE,
8786 "Could not pass on WNI_CFG_ASSOC_RSP_ADDNIE_DATA to CCM");
Jeff Johnsone7245742012-09-05 17:12:55 -07008787 ret = -EINVAL;
8788 goto done;
Jeff Johnson295189b2012-06-20 16:38:30 -07008789 }
8790
8791 if (ccmCfgSetInt((WLAN_HDD_GET_CTX(pHostapdAdapter))->hHal,
8792 WNI_CFG_ASSOC_RSP_ADDNIE_FLAG, 1, NULL,
8793 test_bit(SOFTAP_BSS_STARTED, &pHostapdAdapter->event_flags) ?
8794 eANI_BOOLEAN_TRUE : eANI_BOOLEAN_FALSE)
8795 == eHAL_STATUS_FAILURE)
8796 {
8797 hddLog(LOGE,
8798 "Could not pass on WNI_CFG_ASSOC_RSP_ADDNIE_FLAG to CCM");
Jeff Johnsone7245742012-09-05 17:12:55 -07008799 ret = -EINVAL;
8800 goto done;
Jeff Johnson295189b2012-06-20 16:38:30 -07008801 }
8802 }
8803 else
8804 {
8805 hddLog(VOS_TRACE_LEVEL_INFO,
8806 "%s: No Assoc Response IE received in set beacon",
8807 __func__);
8808
8809 if ( eHAL_STATUS_FAILURE == ccmCfgSetInt((WLAN_HDD_GET_CTX(pHostapdAdapter))->hHal,
8810 WNI_CFG_ASSOC_RSP_ADDNIE_FLAG, 0, NULL,
8811 eANI_BOOLEAN_FALSE) )
8812 {
8813 hddLog(LOGE,
Arif Hussain6d2a3322013-11-17 19:50:10 -08008814 "Could not pass on WNI_CFG_ASSOC_RSP_ADDNIE_FLAG to CCM");
Jeff Johnson295189b2012-06-20 16:38:30 -07008815 }
8816 }
8817
Jeff Johnsone7245742012-09-05 17:12:55 -07008818done:
Jeff Johnson295189b2012-06-20 16:38:30 -07008819 vos_mem_free(genie);
Gopichand Nakkala2b25f4e2013-03-21 19:14:07 +05308820 return ret;
Jeff Johnson295189b2012-06-20 16:38:30 -07008821}
Jeff Johnson295189b2012-06-20 16:38:30 -07008822
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308823/*
Jeff Johnson295189b2012-06-20 16:38:30 -07008824 * FUNCTION: wlan_hdd_validate_operation_channel
8825 * called by wlan_hdd_cfg80211_start_bss() and
8826 * wlan_hdd_cfg80211_set_channel()
8827 * This function validates whether given channel is part of valid
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308828 * channel list.
8829 */
Varun Reddy Yeturu920df212013-05-22 08:07:23 -07008830VOS_STATUS wlan_hdd_validate_operation_channel(hdd_adapter_t *pAdapter,int channel)
Jeff Johnson295189b2012-06-20 16:38:30 -07008831{
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308832
Jeff Johnson295189b2012-06-20 16:38:30 -07008833 v_U32_t num_ch = 0;
8834 u8 valid_ch[WNI_CFG_VALID_CHANNEL_LIST_LEN];
8835 u32 indx = 0;
8836 tHalHandle hHal = WLAN_HDD_GET_HAL_CTX(pAdapter);
Madan Mohan Koyylamudi64267f72013-02-05 14:07:08 +05308837 v_U8_t fValidChannel = FALSE, count = 0;
8838 hdd_config_t *hdd_pConfig_ini= (WLAN_HDD_GET_CTX(pAdapter))->cfg_ini;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308839
Jeff Johnson295189b2012-06-20 16:38:30 -07008840 num_ch = WNI_CFG_VALID_CHANNEL_LIST_LEN;
8841
Madan Mohan Koyylamudi64267f72013-02-05 14:07:08 +05308842 if ( hdd_pConfig_ini->sapAllowAllChannel)
Jeff Johnson295189b2012-06-20 16:38:30 -07008843 {
Madan Mohan Koyylamudi64267f72013-02-05 14:07:08 +05308844 /* Validate the channel */
8845 for (count = RF_CHAN_1 ; count <= RF_CHAN_165 ; count++)
Jeff Johnson295189b2012-06-20 16:38:30 -07008846 {
Madan Mohan Koyylamudi64267f72013-02-05 14:07:08 +05308847 if ( channel == rfChannels[count].channelNum )
8848 {
8849 fValidChannel = TRUE;
8850 break;
8851 }
8852 }
8853 if (fValidChannel != TRUE)
8854 {
8855 hddLog(VOS_TRACE_LEVEL_ERROR,
8856 "%s: Invalid Channel [%d]", __func__, channel);
8857 return VOS_STATUS_E_FAILURE;
Jeff Johnson295189b2012-06-20 16:38:30 -07008858 }
8859 }
Madan Mohan Koyylamudi64267f72013-02-05 14:07:08 +05308860 else
Jeff Johnson295189b2012-06-20 16:38:30 -07008861 {
Madan Mohan Koyylamudi64267f72013-02-05 14:07:08 +05308862 if (0 != ccmCfgGetStr(hHal, WNI_CFG_VALID_CHANNEL_LIST,
8863 valid_ch, &num_ch))
8864 {
8865 hddLog(VOS_TRACE_LEVEL_ERROR,
8866 "%s: failed to get valid channel list", __func__);
8867 return VOS_STATUS_E_FAILURE;
8868 }
8869 for (indx = 0; indx < num_ch; indx++)
8870 {
8871 if (channel == valid_ch[indx])
8872 {
8873 break;
8874 }
8875 }
8876
Rashmi Ramanna3b59e122014-04-10 14:45:13 +05308877 if (indx >= num_ch)
8878 {
8879 if (WLAN_HDD_P2P_GO == pAdapter->device_mode)
8880 {
8881 eCsrBand band;
8882 unsigned int freq;
8883
8884 sme_GetFreqBand(hHal, &band);
8885
8886 if (eCSR_BAND_5G == band)
8887 {
8888#if (LINUX_VERSION_CODE > KERNEL_VERSION(2,6,38))
8889 if (channel <= ARRAY_SIZE(hdd_channels_2_4_GHZ))
8890 {
8891 freq = ieee80211_channel_to_frequency(channel,
8892 IEEE80211_BAND_2GHZ);
8893 }
8894 else
8895 {
8896 freq = ieee80211_channel_to_frequency(channel,
8897 IEEE80211_BAND_5GHZ);
8898 }
8899#else
8900 freq = ieee80211_channel_to_frequency(channel);
8901#endif
8902 if(WLAN_HDD_IS_SOCIAL_CHANNEL(freq))
8903 return VOS_STATUS_SUCCESS;
8904 }
8905 }
8906
8907 hddLog(VOS_TRACE_LEVEL_ERROR,
8908 "%s: Invalid Channel [%d]", __func__, channel);
8909 return VOS_STATUS_E_FAILURE;
8910 }
Jeff Johnson295189b2012-06-20 16:38:30 -07008911 }
Rashmi Ramanna3b59e122014-04-10 14:45:13 +05308912
Jeff Johnson295189b2012-06-20 16:38:30 -07008913 return VOS_STATUS_SUCCESS;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308914
Jeff Johnson295189b2012-06-20 16:38:30 -07008915}
8916
Viral Modi3a32cc52013-02-08 11:14:52 -08008917/**
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +05308918 * FUNCTION: __wlan_hdd_cfg80211_set_channel
Viral Modi3a32cc52013-02-08 11:14:52 -08008919 * This function is used to set the channel number
8920 */
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +05308921static int __wlan_hdd_cfg80211_set_channel( struct wiphy *wiphy, struct net_device *dev,
Viral Modi3a32cc52013-02-08 11:14:52 -08008922 struct ieee80211_channel *chan,
8923 enum nl80211_channel_type channel_type
8924 )
8925{
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05308926 hdd_adapter_t *pAdapter = NULL;
Viral Modi3a32cc52013-02-08 11:14:52 -08008927 v_U32_t num_ch = 0;
Jeff Johnson4416a782013-03-25 14:17:50 -07008928 int channel = 0;
Viral Modi3a32cc52013-02-08 11:14:52 -08008929 int freq = chan->center_freq; /* freq is in MHZ */
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05308930 hdd_context_t *pHddCtx;
8931 int status;
Viral Modi3a32cc52013-02-08 11:14:52 -08008932
8933 ENTER();
8934
8935 if( NULL == dev )
8936 {
8937 hddLog(VOS_TRACE_LEVEL_ERROR,
Arif Hussain6d2a3322013-11-17 19:50:10 -08008938 "%s: Called with dev = NULL.", __func__);
Viral Modi3a32cc52013-02-08 11:14:52 -08008939 return -ENODEV;
8940 }
8941 pAdapter = WLAN_HDD_GET_PRIV_PTR( dev );
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +05308942
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05308943 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
8944 TRACE_CODE_HDD_CFG80211_SET_CHANNEL, pAdapter->sessionId,
8945 channel_type ));
Viral Modi3a32cc52013-02-08 11:14:52 -08008946 hddLog(VOS_TRACE_LEVEL_INFO,
Sushant Kaushik8bc7df22014-04-09 17:55:29 +05308947 "%s: device_mode = %s (%d) freq = %d", __func__,
8948 hdd_device_modetoString(pAdapter->device_mode),
8949 pAdapter->device_mode, chan->center_freq);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05308950
8951 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
8952 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05308953 if (0 != status)
Viral Modi3a32cc52013-02-08 11:14:52 -08008954 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05308955 return status;
Viral Modi3a32cc52013-02-08 11:14:52 -08008956 }
8957
8958 /*
8959 * Do freq to chan conversion
8960 * TODO: for 11a
8961 */
8962
8963 channel = ieee80211_frequency_to_channel(freq);
8964
8965 /* Check freq range */
8966 if ((WNI_CFG_CURRENT_CHANNEL_STAMIN > channel) ||
8967 (WNI_CFG_CURRENT_CHANNEL_STAMAX < channel))
8968 {
8969 hddLog(VOS_TRACE_LEVEL_ERROR,
Arif Hussain6d2a3322013-11-17 19:50:10 -08008970 "%s: Channel [%d] is outside valid range from %d to %d",
Viral Modi3a32cc52013-02-08 11:14:52 -08008971 __func__, channel, WNI_CFG_CURRENT_CHANNEL_STAMIN,
8972 WNI_CFG_CURRENT_CHANNEL_STAMAX);
8973 return -EINVAL;
8974 }
8975
8976 num_ch = WNI_CFG_VALID_CHANNEL_LIST_LEN;
8977
Gopichand Nakkala6ab19562013-03-07 13:59:42 +05308978 if ((WLAN_HDD_SOFTAP != pAdapter->device_mode) &&
8979 (WLAN_HDD_P2P_GO != pAdapter->device_mode))
Viral Modi3a32cc52013-02-08 11:14:52 -08008980 {
8981 if(VOS_STATUS_SUCCESS != wlan_hdd_validate_operation_channel(pAdapter,channel))
8982 {
8983 hddLog(VOS_TRACE_LEVEL_ERROR,
Arif Hussain6d2a3322013-11-17 19:50:10 -08008984 "%s: Invalid Channel [%d]", __func__, channel);
Viral Modi3a32cc52013-02-08 11:14:52 -08008985 return -EINVAL;
8986 }
8987 hddLog(VOS_TRACE_LEVEL_INFO_HIGH,
8988 "%s: set channel to [%d] for device mode =%d",
8989 __func__, channel,pAdapter->device_mode);
8990 }
8991 if( (pAdapter->device_mode == WLAN_HDD_INFRA_STATION)
Viral Modi3a32cc52013-02-08 11:14:52 -08008992 || (pAdapter->device_mode == WLAN_HDD_P2P_CLIENT)
Viral Modi3a32cc52013-02-08 11:14:52 -08008993 )
8994 {
8995 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
8996 tCsrRoamProfile * pRoamProfile = &pWextState->roamProfile;
8997 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
8998
8999 if (eConnectionState_IbssConnected == pHddStaCtx->conn_info.connState)
9000 {
9001 /* Link is up then return cant set channel*/
9002 hddLog( VOS_TRACE_LEVEL_ERROR,
Arif Hussain6d2a3322013-11-17 19:50:10 -08009003 "%s: IBSS Associated, can't set the channel", __func__);
Viral Modi3a32cc52013-02-08 11:14:52 -08009004 return -EINVAL;
9005 }
9006
9007 num_ch = pRoamProfile->ChannelInfo.numOfChannels = 1;
9008 pHddStaCtx->conn_info.operationChannel = channel;
9009 pRoamProfile->ChannelInfo.ChannelList =
9010 &pHddStaCtx->conn_info.operationChannel;
9011 }
9012 else if ((pAdapter->device_mode == WLAN_HDD_SOFTAP)
Viral Modi3a32cc52013-02-08 11:14:52 -08009013 || (pAdapter->device_mode == WLAN_HDD_P2P_GO)
Viral Modi3a32cc52013-02-08 11:14:52 -08009014 )
9015 {
Gopichand Nakkalac8fa7b62013-03-11 13:56:41 +05309016 if (WLAN_HDD_P2P_GO == pAdapter->device_mode)
9017 {
9018 if(VOS_STATUS_SUCCESS !=
9019 wlan_hdd_validate_operation_channel(pAdapter,channel))
9020 {
9021 hddLog(VOS_TRACE_LEVEL_ERROR,
Arif Hussain6d2a3322013-11-17 19:50:10 -08009022 "%s: Invalid Channel [%d]", __func__, channel);
Gopichand Nakkalac8fa7b62013-03-11 13:56:41 +05309023 return -EINVAL;
9024 }
9025 (WLAN_HDD_GET_AP_CTX_PTR(pAdapter))->sapConfig.channel = channel;
9026 }
9027 else if ( WLAN_HDD_SOFTAP == pAdapter->device_mode )
Viral Modi3a32cc52013-02-08 11:14:52 -08009028 {
9029 hdd_config_t *cfg_param = (WLAN_HDD_GET_CTX(pAdapter))->cfg_ini;
9030
9031 /* If auto channel selection is configured as enable/ 1 then ignore
9032 channel set by supplicant
9033 */
9034 if ( cfg_param->apAutoChannelSelection )
9035 {
Gopichand Nakkalac8fa7b62013-03-11 13:56:41 +05309036 (WLAN_HDD_GET_AP_CTX_PTR(pAdapter))->sapConfig.channel =
9037 AUTO_CHANNEL_SELECT;
Viral Modi3a32cc52013-02-08 11:14:52 -08009038 hddLog(VOS_TRACE_LEVEL_INFO_HIGH,
Sushant Kaushik8bc7df22014-04-09 17:55:29 +05309039 "%s: set channel to auto channel (0) for device mode =%s (%d)",
9040 __func__, hdd_device_modetoString(pAdapter->device_mode),
9041 pAdapter->device_mode);
Viral Modi3a32cc52013-02-08 11:14:52 -08009042 }
Gopichand Nakkalac8fa7b62013-03-11 13:56:41 +05309043 else
9044 {
9045 if(VOS_STATUS_SUCCESS !=
9046 wlan_hdd_validate_operation_channel(pAdapter,channel))
9047 {
9048 hddLog(VOS_TRACE_LEVEL_ERROR,
Arif Hussain6d2a3322013-11-17 19:50:10 -08009049 "%s: Invalid Channel [%d]", __func__, channel);
Gopichand Nakkalac8fa7b62013-03-11 13:56:41 +05309050 return -EINVAL;
9051 }
9052 (WLAN_HDD_GET_AP_CTX_PTR(pAdapter))->sapConfig.channel = channel;
9053 }
Viral Modi3a32cc52013-02-08 11:14:52 -08009054 }
9055 }
9056 else
9057 {
9058 hddLog(VOS_TRACE_LEVEL_FATAL,
9059 "%s: Invalid device mode failed to set valid channel", __func__);
9060 return -EINVAL;
9061 }
9062 EXIT();
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05309063 return status;
Viral Modi3a32cc52013-02-08 11:14:52 -08009064}
9065
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +05309066static int wlan_hdd_cfg80211_set_channel( struct wiphy *wiphy,
9067 struct net_device *dev,
9068 struct ieee80211_channel *chan,
9069 enum nl80211_channel_type channel_type
9070 )
9071{
9072 int ret;
9073
9074 vos_ssr_protect(__func__);
9075 ret = __wlan_hdd_cfg80211_set_channel(wiphy, dev, chan, channel_type);
9076 vos_ssr_unprotect(__func__);
9077
9078 return ret;
9079}
9080
Jeff Johnson295189b2012-06-20 16:38:30 -07009081#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,4,0))
9082static int wlan_hdd_cfg80211_start_bss(hdd_adapter_t *pHostapdAdapter,
9083 struct beacon_parameters *params)
Jeff Johnson04dd8a82012-06-29 20:41:40 -07009084#else
9085static int wlan_hdd_cfg80211_start_bss(hdd_adapter_t *pHostapdAdapter,
9086 struct cfg80211_beacon_data *params,
9087 const u8 *ssid, size_t ssid_len,
Kanchanapally, Vidyullathaacc59252015-05-20 16:49:07 +05309088 enum nl80211_hidden_ssid hidden_ssid,
9089 v_U8_t auth_type)
Jeff Johnson04dd8a82012-06-29 20:41:40 -07009090#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07009091{
9092 tsap_Config_t *pConfig;
9093 beacon_data_t *pBeacon = NULL;
9094 struct ieee80211_mgmt *pMgmt_frame;
9095 v_U8_t *pIe=NULL;
9096 v_U16_t capab_info;
9097 eCsrAuthType RSNAuthType;
9098 eCsrEncryptionType RSNEncryptType;
9099 eCsrEncryptionType mcRSNEncryptType;
9100 int status = VOS_STATUS_SUCCESS;
9101 tpWLAN_SAPEventCB pSapEventCallback;
9102 hdd_hostapd_state_t *pHostapdState;
9103 v_U8_t wpaRsnIEdata[(SIR_MAC_MAX_IE_LENGTH * 2)+4]; //Max ie length 255 * 2(WPA+RSN) + 2 bytes (vendor specific ID) * 2
9104 v_CONTEXT_t pVosContext = (WLAN_HDD_GET_CTX(pHostapdAdapter))->pvosContext;
Madan Mohan Koyylamudia16d0202013-02-01 11:05:57 +05309105 tHalHandle hHal = WLAN_HDD_GET_HAL_CTX(pHostapdAdapter);
Jeff Johnson295189b2012-06-20 16:38:30 -07009106 struct qc_mac_acl_entry *acl_entry = NULL;
Siddharth Bhal5cba24e2014-05-08 18:59:39 +05309107 hdd_config_t *iniConfig;
Jeff Johnson295189b2012-06-20 16:38:30 -07009108 v_SINT_t i;
Madan Mohan Koyyalamudi543172b2012-12-05 16:40:18 -08009109 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pHostapdAdapter);
Peng Xu2446a892014-09-05 17:21:18 +05309110 tSmeConfigParams *psmeConfig;
Chet Lanctot40142442014-05-20 13:39:25 -07009111 v_BOOL_t MFPCapable = VOS_FALSE;
9112 v_BOOL_t MFPRequired = VOS_FALSE;
Sushant Kaushik7dc03272015-02-18 11:25:12 +05309113 v_BOOL_t sapEnable11AC =
9114 (WLAN_HDD_GET_CTX(pHostapdAdapter))->cfg_ini->sapEnable11AC;
Jeff Johnson295189b2012-06-20 16:38:30 -07009115 ENTER();
9116
Siddharth Bhal5cba24e2014-05-08 18:59:39 +05309117 iniConfig = pHddCtx->cfg_ini;
9118
Jeff Johnson295189b2012-06-20 16:38:30 -07009119 pHostapdState = WLAN_HDD_GET_HOSTAP_STATE_PTR(pHostapdAdapter);
9120
9121 pConfig = &pHostapdAdapter->sessionCtx.ap.sapConfig;
9122
9123 pBeacon = pHostapdAdapter->sessionCtx.ap.beacon;
9124
9125 pMgmt_frame = (struct ieee80211_mgmt*)pBeacon->head;
9126
9127 pConfig->beacon_int = pMgmt_frame->u.beacon.beacon_int;
9128
9129 //channel is already set in the set_channel Call back
9130 //pConfig->channel = pCommitConfig->channel;
9131
9132 /*Protection parameter to enable or disable*/
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309133 pConfig->protEnabled =
Jeff Johnson295189b2012-06-20 16:38:30 -07009134 (WLAN_HDD_GET_CTX(pHostapdAdapter))->cfg_ini->apProtEnabled;
9135
9136 pConfig->dtim_period = pBeacon->dtim_period;
9137
Arif Hussain6d2a3322013-11-17 19:50:10 -08009138 hddLog(VOS_TRACE_LEVEL_INFO_HIGH,"****pConfig->dtim_period=%d***",
Jeff Johnson295189b2012-06-20 16:38:30 -07009139 pConfig->dtim_period);
9140
Madan Mohan Koyyalamudie0ca11f2012-11-27 15:57:52 -08009141 if (pHostapdAdapter->device_mode == WLAN_HDD_SOFTAP)
Jeff Johnson32d95a32012-09-10 13:15:23 -07009142 {
9143 pIe = wlan_hdd_cfg80211_get_ie_ptr(pBeacon->tail, pBeacon->tail_len,
Jeff Johnson295189b2012-06-20 16:38:30 -07009144 WLAN_EID_COUNTRY);
Kiet Lam083504c2013-11-25 14:17:45 +05309145 if(memcmp(pHddCtx->cfg_ini->apCntryCode, CFG_AP_COUNTRY_CODE_DEFAULT, 3) != 0)
9146 {
9147 tANI_BOOLEAN restartNeeded;
9148 pConfig->ieee80211d = 1;
9149 vos_mem_copy(pConfig->countryCode, pHddCtx->cfg_ini->apCntryCode, 3);
9150 sme_setRegInfo(hHal, pConfig->countryCode);
9151 sme_ResetCountryCodeInformation(hHal, &restartNeeded);
9152 }
9153 else if(pIe)
Jeff Johnson295189b2012-06-20 16:38:30 -07009154 {
Jeff Johnson32d95a32012-09-10 13:15:23 -07009155 tANI_BOOLEAN restartNeeded;
Jeff Johnson32d95a32012-09-10 13:15:23 -07009156 pConfig->ieee80211d = 1;
9157 vos_mem_copy(pConfig->countryCode, &pIe[2], 3);
9158 sme_setRegInfo(hHal, pConfig->countryCode);
9159 sme_ResetCountryCodeInformation(hHal, &restartNeeded);
Jeff Johnson295189b2012-06-20 16:38:30 -07009160 }
Jeff Johnson32d95a32012-09-10 13:15:23 -07009161 else
9162 {
9163 pConfig->ieee80211d = 0;
9164 }
Madan Mohan Koyylamudia16d0202013-02-01 11:05:57 +05309165 /*
9166 * If auto channel is configured i.e. channel is 0,
9167 * so skip channel validation.
9168 */
9169 if( AUTO_CHANNEL_SELECT != pConfig->channel )
9170 {
9171 if(VOS_STATUS_SUCCESS != wlan_hdd_validate_operation_channel(pHostapdAdapter,pConfig->channel))
9172 {
9173 hddLog(VOS_TRACE_LEVEL_ERROR,
Arif Hussain6d2a3322013-11-17 19:50:10 -08009174 "%s: Invalid Channel [%d]", __func__, pConfig->channel);
Madan Mohan Koyylamudia16d0202013-02-01 11:05:57 +05309175 return -EINVAL;
9176 }
9177 }
9178 else
9179 {
9180 if(1 != pHddCtx->is_dynamic_channel_range_set)
9181 {
9182 hdd_config_t *hdd_pConfig= (WLAN_HDD_GET_CTX(pHostapdAdapter))->cfg_ini;
9183 WLANSAP_SetChannelRange(hHal, hdd_pConfig->apStartChannelNum,
9184 hdd_pConfig->apEndChannelNum,hdd_pConfig->apOperatingBand);
9185 }
9186 pHddCtx->is_dynamic_channel_range_set = 0;
9187 }
Jeff Johnson295189b2012-06-20 16:38:30 -07009188 }
Jeff Johnson32d95a32012-09-10 13:15:23 -07009189 else
Jeff Johnson295189b2012-06-20 16:38:30 -07009190 {
9191 pConfig->ieee80211d = 0;
9192 }
Kanchanapally, Vidyullathaacc59252015-05-20 16:49:07 +05309193
9194#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,4,0))
9195 if (params->auth_type == NL80211_AUTHTYPE_OPEN_SYSTEM)
9196 pConfig->authType = eSAP_OPEN_SYSTEM;
9197 else if (params->auth_type == NL80211_AUTHTYPE_SHARED_KEY)
9198 pConfig->authType = eSAP_SHARED_KEY;
9199 else
9200 pConfig->authType = eSAP_AUTO_SWITCH;
9201#else
9202 if (auth_type == NL80211_AUTHTYPE_OPEN_SYSTEM)
9203 pConfig->authType = eSAP_OPEN_SYSTEM;
9204 else if (auth_type == NL80211_AUTHTYPE_SHARED_KEY)
9205 pConfig->authType = eSAP_SHARED_KEY;
9206 else
9207 pConfig->authType = eSAP_AUTO_SWITCH;
9208#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07009209
9210 capab_info = pMgmt_frame->u.beacon.capab_info;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309211
9212 pConfig->privacy = (pMgmt_frame->u.beacon.capab_info &
Jeff Johnson295189b2012-06-20 16:38:30 -07009213 WLAN_CAPABILITY_PRIVACY) ? VOS_TRUE : VOS_FALSE;
9214
9215 (WLAN_HDD_GET_AP_CTX_PTR(pHostapdAdapter))->uPrivacy = pConfig->privacy;
9216
9217 /*Set wps station to configured*/
9218 pIe = wlan_hdd_get_wps_ie_ptr(pBeacon->tail, pBeacon->tail_len);
9219
9220 if(pIe)
9221 {
9222 if(pIe[1] < (2 + WPS_OUI_TYPE_SIZE))
9223 {
Arif Hussain6d2a3322013-11-17 19:50:10 -08009224 hddLog( VOS_TRACE_LEVEL_ERROR, "**Wps Ie Length is too small***");
Jeff Johnson295189b2012-06-20 16:38:30 -07009225 return -EINVAL;
9226 }
9227 else if(memcmp(&pIe[2], WPS_OUI_TYPE, WPS_OUI_TYPE_SIZE) == 0)
9228 {
Madan Mohan Koyyalamudi8bdd3112012-09-24 13:55:14 -07009229 hddLog( VOS_TRACE_LEVEL_INFO, "** WPS IE(len %d) ***", (pIe[1]+2));
Jeff Johnson295189b2012-06-20 16:38:30 -07009230 /* Check 15 bit of WPS IE as it contain information for wps state
9231 * WPS state
9232 */
9233 if(SAP_WPS_ENABLED_UNCONFIGURED == pIe[15])
9234 {
9235 pConfig->wps_state = SAP_WPS_ENABLED_UNCONFIGURED;
9236 } else if(SAP_WPS_ENABLED_CONFIGURED == pIe[15])
9237 {
9238 pConfig->wps_state = SAP_WPS_ENABLED_CONFIGURED;
9239 }
9240 }
9241 }
9242 else
9243 {
9244 pConfig->wps_state = SAP_WPS_DISABLED;
9245 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309246 pConfig->fwdWPSPBCProbeReq = 1; // Forward WPS PBC probe request frame up
Jeff Johnson295189b2012-06-20 16:38:30 -07009247
c_hpothufe599e92014-06-16 11:38:55 +05309248 pConfig->RSNEncryptType = eCSR_ENCRYPT_TYPE_NONE;
9249 pConfig->mcRSNEncryptType = eCSR_ENCRYPT_TYPE_NONE;
9250 (WLAN_HDD_GET_AP_CTX_PTR(pHostapdAdapter))->ucEncryptType =
9251 eCSR_ENCRYPT_TYPE_NONE;
9252
Jeff Johnson295189b2012-06-20 16:38:30 -07009253 pConfig->RSNWPAReqIELength = 0;
9254 pConfig->pRSNWPAReqIE = NULL;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309255 pIe = wlan_hdd_cfg80211_get_ie_ptr(pBeacon->tail, pBeacon->tail_len,
Jeff Johnson295189b2012-06-20 16:38:30 -07009256 WLAN_EID_RSN);
9257 if(pIe && pIe[1])
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309258 {
Jeff Johnson295189b2012-06-20 16:38:30 -07009259 pConfig->RSNWPAReqIELength = pIe[1] + 2;
9260 memcpy(&wpaRsnIEdata[0], pIe, pConfig->RSNWPAReqIELength);
9261 pConfig->pRSNWPAReqIE = &wpaRsnIEdata[0];
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309262 /* The actual processing may eventually be more extensive than
9263 * this. Right now, just consume any PMKIDs that are sent in
Jeff Johnson295189b2012-06-20 16:38:30 -07009264 * by the app.
9265 * */
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309266 status = hdd_softap_unpackIE(
Jeff Johnson295189b2012-06-20 16:38:30 -07009267 vos_get_context( VOS_MODULE_ID_SME, pVosContext),
9268 &RSNEncryptType,
9269 &mcRSNEncryptType,
9270 &RSNAuthType,
Chet Lanctot8cecea22014-02-11 19:09:36 -08009271 &MFPCapable,
9272 &MFPRequired,
Jeff Johnson295189b2012-06-20 16:38:30 -07009273 pConfig->pRSNWPAReqIE[1]+2,
9274 pConfig->pRSNWPAReqIE );
9275
9276 if( VOS_STATUS_SUCCESS == status )
9277 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309278 /* Now copy over all the security attributes you have
9279 * parsed out
Jeff Johnson295189b2012-06-20 16:38:30 -07009280 * */
9281 pConfig->RSNEncryptType = RSNEncryptType; // Use the cipher type in the RSN IE
9282 pConfig->mcRSNEncryptType = mcRSNEncryptType;
9283 (WLAN_HDD_GET_AP_CTX_PTR(pHostapdAdapter))->ucEncryptType
9284 = RSNEncryptType;
Gopichand Nakkala66c0bd02013-04-10 11:36:29 +05309285 hddLog( LOG1, FL("CSR AuthType = %d, "
Arif Hussain6d2a3322013-11-17 19:50:10 -08009286 "EncryptionType = %d mcEncryptionType = %d"),
Jeff Johnson295189b2012-06-20 16:38:30 -07009287 RSNAuthType, RSNEncryptType, mcRSNEncryptType);
9288 }
9289 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309290
Jeff Johnson295189b2012-06-20 16:38:30 -07009291 pIe = wlan_hdd_get_vendor_oui_ie_ptr(WPA_OUI_TYPE, WPA_OUI_TYPE_SIZE,
9292 pBeacon->tail, pBeacon->tail_len);
9293
9294 if(pIe && pIe[1] && (pIe[0] == DOT11F_EID_WPA))
9295 {
9296 if (pConfig->pRSNWPAReqIE)
9297 {
9298 /*Mixed mode WPA/WPA2*/
9299 memcpy((&wpaRsnIEdata[0] + pConfig->RSNWPAReqIELength), pIe, pIe[1] + 2);
9300 pConfig->RSNWPAReqIELength += pIe[1] + 2;
9301 }
9302 else
9303 {
9304 pConfig->RSNWPAReqIELength = pIe[1] + 2;
9305 memcpy(&wpaRsnIEdata[0], pIe, pConfig->RSNWPAReqIELength);
9306 pConfig->pRSNWPAReqIE = &wpaRsnIEdata[0];
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309307 status = hdd_softap_unpackIE(
Jeff Johnson295189b2012-06-20 16:38:30 -07009308 vos_get_context( VOS_MODULE_ID_SME, pVosContext),
9309 &RSNEncryptType,
9310 &mcRSNEncryptType,
9311 &RSNAuthType,
Chet Lanctot8cecea22014-02-11 19:09:36 -08009312 &MFPCapable,
9313 &MFPRequired,
Jeff Johnson295189b2012-06-20 16:38:30 -07009314 pConfig->pRSNWPAReqIE[1]+2,
9315 pConfig->pRSNWPAReqIE );
9316
9317 if( VOS_STATUS_SUCCESS == status )
9318 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309319 /* Now copy over all the security attributes you have
9320 * parsed out
Jeff Johnson295189b2012-06-20 16:38:30 -07009321 * */
9322 pConfig->RSNEncryptType = RSNEncryptType; // Use the cipher type in the RSN IE
9323 pConfig->mcRSNEncryptType = mcRSNEncryptType;
9324 (WLAN_HDD_GET_AP_CTX_PTR(pHostapdAdapter))->ucEncryptType
9325 = RSNEncryptType;
Gopichand Nakkala66c0bd02013-04-10 11:36:29 +05309326 hddLog( LOG1, FL("CSR AuthType = %d, "
Arif Hussain6d2a3322013-11-17 19:50:10 -08009327 "EncryptionType = %d mcEncryptionType = %d"),
Jeff Johnson295189b2012-06-20 16:38:30 -07009328 RSNAuthType, RSNEncryptType, mcRSNEncryptType);
9329 }
9330 }
9331 }
9332
Jeff Johnson4416a782013-03-25 14:17:50 -07009333 if (pConfig->RSNWPAReqIELength > sizeof wpaRsnIEdata) {
9334 hddLog( VOS_TRACE_LEVEL_ERROR, "**RSNWPAReqIELength is too large***");
9335 return -EINVAL;
9336 }
9337
Jeff Johnson295189b2012-06-20 16:38:30 -07009338 pConfig->SSIDinfo.ssidHidden = VOS_FALSE;
9339
Jeff Johnson04dd8a82012-06-29 20:41:40 -07009340#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,4,0))
Jeff Johnson295189b2012-06-20 16:38:30 -07009341 if (params->ssid != NULL)
9342 {
9343 memcpy(pConfig->SSIDinfo.ssid.ssId, params->ssid, params->ssid_len);
9344 pConfig->SSIDinfo.ssid.length = params->ssid_len;
9345 if (params->hidden_ssid != NL80211_HIDDEN_SSID_NOT_IN_USE)
9346 pConfig->SSIDinfo.ssidHidden = VOS_TRUE;
9347 }
Jeff Johnson04dd8a82012-06-29 20:41:40 -07009348#else
9349 if (ssid != NULL)
9350 {
9351 memcpy(pConfig->SSIDinfo.ssid.ssId, ssid, ssid_len);
9352 pConfig->SSIDinfo.ssid.length = ssid_len;
9353 if (hidden_ssid != NL80211_HIDDEN_SSID_NOT_IN_USE)
9354 pConfig->SSIDinfo.ssidHidden = VOS_TRUE;
9355 }
9356#endif
9357
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309358 vos_mem_copy(pConfig->self_macaddr.bytes,
Jeff Johnson295189b2012-06-20 16:38:30 -07009359 pHostapdAdapter->macAddressCurrent.bytes, sizeof(v_MACADDR_t));
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309360
Jeff Johnson295189b2012-06-20 16:38:30 -07009361 /* default value */
9362 pConfig->SapMacaddr_acl = eSAP_ACCEPT_UNLESS_DENIED;
9363 pConfig->num_accept_mac = 0;
9364 pConfig->num_deny_mac = 0;
9365
9366 pIe = wlan_hdd_get_vendor_oui_ie_ptr(BLACKLIST_OUI_TYPE, WPA_OUI_TYPE_SIZE,
9367 pBeacon->tail, pBeacon->tail_len);
9368
9369 /* pIe for black list is following form:
9370 type : 1 byte
9371 length : 1 byte
9372 OUI : 4 bytes
9373 acl type : 1 byte
9374 no of mac addr in black list: 1 byte
9375 list of mac_acl_entries: variable, 6 bytes per mac address + sizeof(int) for vlan id
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309376 */
9377 if ((pIe != NULL) && (pIe[1] != 0))
Jeff Johnson295189b2012-06-20 16:38:30 -07009378 {
9379 pConfig->SapMacaddr_acl = pIe[6];
9380 pConfig->num_deny_mac = pIe[7];
Arif Hussain6d2a3322013-11-17 19:50:10 -08009381 hddLog(VOS_TRACE_LEVEL_INFO,"acl type = %d no deny mac = %d",
Jeff Johnson295189b2012-06-20 16:38:30 -07009382 pIe[6], pIe[7]);
Gopichand Nakkalac005b7c2013-05-14 16:04:14 +05309383 if (pConfig->num_deny_mac > MAX_ACL_MAC_ADDRESS)
9384 pConfig->num_deny_mac = MAX_ACL_MAC_ADDRESS;
Jeff Johnson295189b2012-06-20 16:38:30 -07009385 acl_entry = (struct qc_mac_acl_entry *)(pIe + 8);
9386 for (i = 0; i < pConfig->num_deny_mac; i++)
9387 {
9388 vos_mem_copy(&pConfig->deny_mac[i], acl_entry->addr, sizeof(qcmacaddr));
9389 acl_entry++;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309390 }
Jeff Johnson295189b2012-06-20 16:38:30 -07009391 }
9392 pIe = wlan_hdd_get_vendor_oui_ie_ptr(WHITELIST_OUI_TYPE, WPA_OUI_TYPE_SIZE,
9393 pBeacon->tail, pBeacon->tail_len);
9394
9395 /* pIe for white list is following form:
9396 type : 1 byte
9397 length : 1 byte
9398 OUI : 4 bytes
9399 acl type : 1 byte
9400 no of mac addr in white list: 1 byte
9401 list of mac_acl_entries: variable, 6 bytes per mac address + sizeof(int) for vlan id
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309402 */
9403 if ((pIe != NULL) && (pIe[1] != 0))
Jeff Johnson295189b2012-06-20 16:38:30 -07009404 {
9405 pConfig->SapMacaddr_acl = pIe[6];
9406 pConfig->num_accept_mac = pIe[7];
Arif Hussain6d2a3322013-11-17 19:50:10 -08009407 hddLog(VOS_TRACE_LEVEL_INFO,"acl type = %d no accept mac = %d",
Jeff Johnson295189b2012-06-20 16:38:30 -07009408 pIe[6], pIe[7]);
Gopichand Nakkalac005b7c2013-05-14 16:04:14 +05309409 if (pConfig->num_accept_mac > MAX_ACL_MAC_ADDRESS)
9410 pConfig->num_accept_mac = MAX_ACL_MAC_ADDRESS;
Jeff Johnson295189b2012-06-20 16:38:30 -07009411 acl_entry = (struct qc_mac_acl_entry *)(pIe + 8);
9412 for (i = 0; i < pConfig->num_accept_mac; i++)
9413 {
9414 vos_mem_copy(&pConfig->accept_mac[i], acl_entry->addr, sizeof(qcmacaddr));
9415 acl_entry++;
9416 }
9417 }
Gopichand Nakkalac005b7c2013-05-14 16:04:14 +05309418
Jeff Johnson295189b2012-06-20 16:38:30 -07009419 wlan_hdd_set_sapHwmode(pHostapdAdapter);
9420
Jeff Johnsone7245742012-09-05 17:12:55 -07009421#ifdef WLAN_FEATURE_11AC
Ravi Kumar Vaishnavbbaebbe2013-01-15 17:09:48 -08009422 /* Overwrite the hostapd setting for HW mode only for 11ac.
Sushant Kaushik7dc03272015-02-18 11:25:12 +05309423 * This is valid only if mode is set to 11n in hostapd, sapEnable11AC
9424 * is set in .ini and 11ac is supported by both host and firmware.
Kiet Lam0f320422013-11-21 19:29:17 +05309425 * Otherwise, leave whatever is set in hostapd (a OR b OR g OR n mode)
9426 */
Ravi Kumar Vaishnavbbaebbe2013-01-15 17:09:48 -08009427 if( ((pConfig->SapHw_mode == eSAP_DOT11_MODE_11n) ||
9428 (pConfig->SapHw_mode == eSAP_DOT11_MODE_11n_ONLY)) &&
Sushant Kaushik7dc03272015-02-18 11:25:12 +05309429 (sapEnable11AC) && (sme_IsFeatureSupportedByDriver(DOT11AC)) &&
9430 (sme_IsFeatureSupportedByFW(DOT11AC)) )
Jeff Johnsone7245742012-09-05 17:12:55 -07009431 {
Siddharth Bhalf42f8592014-05-15 13:39:07 +05309432 v_U32_t operatingBand = 0;
Jeff Johnsone7245742012-09-05 17:12:55 -07009433 pConfig->SapHw_mode = eSAP_DOT11_MODE_11ac;
Siddharth Bhalf42f8592014-05-15 13:39:07 +05309434 ccmCfgGetInt(hHal, WNI_CFG_SAP_CHANNEL_SELECT_OPERATING_BAND, &operatingBand);
Ravi Joshi83bfaa12013-05-28 22:12:08 -07009435
Siddharth Bhal5cba24e2014-05-08 18:59:39 +05309436 /* If ACS disable and selected channel <= 14
9437 * OR
9438 * ACS enabled and ACS operating band is choosen as 2.4
9439 * AND
9440 * VHT in 2.4G Disabled
9441 * THEN
9442 * Fallback to 11N mode
9443 */
9444 if (((AUTO_CHANNEL_SELECT != pConfig->channel && pConfig->channel <= SIR_11B_CHANNEL_END)
9445 || (AUTO_CHANNEL_SELECT == pConfig->channel &&
Deepthi Gowri7db41f32014-10-13 17:02:29 +05309446 operatingBand == eSAP_RF_SUBBAND_2_4_GHZ)) &&
Siddharth Bhal5cba24e2014-05-08 18:59:39 +05309447 iniConfig->enableVhtFor24GHzBand == FALSE)
Ravi Joshi83bfaa12013-05-28 22:12:08 -07009448 {
Siddharth Bhalf42f8592014-05-15 13:39:07 +05309449 hddLog(LOGW, FL("Setting hwmode to 11n, operatingBand = %d, Channel = %d"),
9450 operatingBand, pConfig->channel);
Ravi Joshi83bfaa12013-05-28 22:12:08 -07009451 pConfig->SapHw_mode = eSAP_DOT11_MODE_11n;
9452 }
Jeff Johnsone7245742012-09-05 17:12:55 -07009453 }
9454#endif
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309455
Jeff Johnson295189b2012-06-20 16:38:30 -07009456 // ht_capab is not what the name conveys,this is used for protection bitmap
9457 pConfig->ht_capab =
9458 (WLAN_HDD_GET_CTX(pHostapdAdapter))->cfg_ini->apProtection;
9459
9460 if ( 0 != wlan_hdd_cfg80211_update_apies(pHostapdAdapter, params) )
9461 {
9462 hddLog(LOGE, FL("SAP Not able to set AP IEs"));
9463 return -EINVAL;
9464 }
9465
9466 //Uapsd Enabled Bit
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309467 pConfig->UapsdEnable =
Jeff Johnson295189b2012-06-20 16:38:30 -07009468 (WLAN_HDD_GET_CTX(pHostapdAdapter))->cfg_ini->apUapsdEnabled;
9469 //Enable OBSS protection
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309470 pConfig->obssProtEnabled =
9471 (WLAN_HDD_GET_CTX(pHostapdAdapter))->cfg_ini->apOBSSProtEnabled;
Jeff Johnson295189b2012-06-20 16:38:30 -07009472
Chet Lanctot8cecea22014-02-11 19:09:36 -08009473#ifdef WLAN_FEATURE_11W
9474 pConfig->mfpCapable = MFPCapable;
9475 pConfig->mfpRequired = MFPRequired;
9476 hddLog(LOGW, FL("Soft AP MFP capable %d, MFP required %d\n"),
9477 pConfig->mfpCapable, pConfig->mfpRequired);
9478#endif
9479
Arif Hussain6d2a3322013-11-17 19:50:10 -08009480 hddLog(LOGW, FL("SOftAP macaddress : "MAC_ADDRESS_STR),
Jeff Johnson295189b2012-06-20 16:38:30 -07009481 MAC_ADDR_ARRAY(pHostapdAdapter->macAddressCurrent.bytes));
Arif Hussain6d2a3322013-11-17 19:50:10 -08009482 hddLog(LOGW,FL("ssid =%s, beaconint=%d, channel=%d"),
9483 pConfig->SSIDinfo.ssid.ssId, (int)pConfig->beacon_int,
9484 (int)pConfig->channel);
9485 hddLog(LOGW,FL("hw_mode=%x, privacy=%d, authType=%d"),
9486 pConfig->SapHw_mode, pConfig->privacy,
9487 pConfig->authType);
9488 hddLog(LOGW,FL("RSN/WPALen=%d, Uapsd = %d"),
9489 (int)pConfig->RSNWPAReqIELength, pConfig->UapsdEnable);
9490 hddLog(LOGW,FL("ProtEnabled = %d, OBSSProtEnabled = %d"),
9491 pConfig->protEnabled, pConfig->obssProtEnabled);
Jeff Johnson295189b2012-06-20 16:38:30 -07009492
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309493 if(test_bit(SOFTAP_BSS_STARTED, &pHostapdAdapter->event_flags))
Jeff Johnson295189b2012-06-20 16:38:30 -07009494 {
9495 //Bss already started. just return.
9496 //TODO Probably it should update some beacon params.
9497 hddLog( LOGE, "Bss Already started...Ignore the request");
9498 EXIT();
9499 return 0;
9500 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309501
Agarwal Ashish51325b52014-06-16 16:50:49 +05309502 if (vos_max_concurrent_connections_reached()) {
9503 hddLog(VOS_TRACE_LEVEL_INFO, FL("Reached max concurrent connections"));
9504 return -EINVAL;
9505 }
9506
Jeff Johnson295189b2012-06-20 16:38:30 -07009507 pConfig->persona = pHostapdAdapter->device_mode;
9508
Peng Xu2446a892014-09-05 17:21:18 +05309509 psmeConfig = (tSmeConfigParams*) vos_mem_malloc(sizeof(tSmeConfigParams));
9510 if ( NULL != psmeConfig)
9511 {
Hardik Kantilal Patel086e0a32014-11-20 14:56:26 +05309512 vos_mem_zero(psmeConfig, sizeof (tSmeConfigParams));
Peng Xu2446a892014-09-05 17:21:18 +05309513 sme_GetConfigParam(hHal, psmeConfig);
9514 pConfig->scanBandPreference = psmeConfig->csrConfig.scanBandPreference;
Hardik Kantilal Patel086e0a32014-11-20 14:56:26 +05309515#ifdef WLAN_FEATURE_AP_HT40_24G
9516 if (((pHostapdAdapter->device_mode == WLAN_HDD_SOFTAP)
9517 || (pHostapdAdapter->device_mode == WLAN_HDD_P2P_GO))
9518 && pHddCtx->cfg_ini->apHT40_24GEnabled)
9519 {
9520 psmeConfig->csrConfig.apHT40_24GEnabled = 1;
9521 sme_UpdateConfig (hHal, psmeConfig);
9522 }
9523#endif
Peng Xu2446a892014-09-05 17:21:18 +05309524 vos_mem_free(psmeConfig);
9525 }
Peng Xuafc34e32014-09-25 13:23:55 +05309526 pConfig->acsBandSwitchThreshold = iniConfig->acsBandSwitchThreshold;
Peng Xu2446a892014-09-05 17:21:18 +05309527
Jeff Johnson295189b2012-06-20 16:38:30 -07009528 pSapEventCallback = hdd_hostapd_SAPEventCB;
9529 if(WLANSAP_StartBss(pVosContext, pSapEventCallback, pConfig,
9530 (v_PVOID_t)pHostapdAdapter->dev) != VOS_STATUS_SUCCESS)
9531 {
Arif Hussain6d2a3322013-11-17 19:50:10 -08009532 hddLog(LOGE,FL("SAP Start Bss fail"));
Jeff Johnson295189b2012-06-20 16:38:30 -07009533 return -EINVAL;
9534 }
9535
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309536 hddLog(LOG1,
Jeff Johnson295189b2012-06-20 16:38:30 -07009537 FL("Waiting for Scan to complete(auto mode) and BSS to start"));
9538
9539 status = vos_wait_single_event(&pHostapdState->vosEvent, 10000);
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309540
Jeff Johnson295189b2012-06-20 16:38:30 -07009541 if (!VOS_IS_STATUS_SUCCESS(status))
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309542 {
9543 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Arif Hussain6d2a3322013-11-17 19:50:10 -08009544 ("ERROR: HDD vos wait for single_event failed!!"));
Tushnim Bhattacharyyaad37df12013-10-02 12:01:33 -07009545 smeGetCommandQStatus(hHal);
Jeff Johnson295189b2012-06-20 16:38:30 -07009546 VOS_ASSERT(0);
9547 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309548
Jeff Johnson295189b2012-06-20 16:38:30 -07009549 set_bit(SOFTAP_BSS_STARTED, &pHostapdAdapter->event_flags);
Kaushik, Sushantf6070802014-10-15 15:09:23 +05309550 /* Initialize WMM configuation */
9551 hdd_wmm_init(pHostapdAdapter);
Agarwal Ashish51325b52014-06-16 16:50:49 +05309552 wlan_hdd_incr_active_session(pHddCtx, pHostapdAdapter->device_mode);
Jeff Johnson295189b2012-06-20 16:38:30 -07009553
Madan Mohan Koyyalamudi26bd7142012-10-30 18:14:19 -07009554#ifdef WLAN_FEATURE_P2P_DEBUG
9555 if (pHostapdAdapter->device_mode == WLAN_HDD_P2P_GO)
9556 {
9557 if(globalP2PConnectionStatus == P2P_GO_NEG_COMPLETED)
9558 {
9559 globalP2PConnectionStatus = P2P_GO_COMPLETED_STATE;
9560 hddLog(LOGE,"[P2P State] From Go nego completed to "
Jeff Johnson1250df42012-12-10 14:31:52 -08009561 "Non-autonomous Group started");
Madan Mohan Koyyalamudi26bd7142012-10-30 18:14:19 -07009562 }
9563 else if(globalP2PConnectionStatus == P2P_NOT_ACTIVE)
9564 {
9565 globalP2PConnectionStatus = P2P_GO_COMPLETED_STATE;
9566 hddLog(LOGE,"[P2P State] From Inactive to "
Jeff Johnson1250df42012-12-10 14:31:52 -08009567 "Autonomous Group started");
Madan Mohan Koyyalamudi26bd7142012-10-30 18:14:19 -07009568 }
9569 }
9570#endif
9571
Jeff Johnson295189b2012-06-20 16:38:30 -07009572 pHostapdState->bCommit = TRUE;
9573 EXIT();
9574
9575 return 0;
9576}
9577
Jeff Johnson04dd8a82012-06-29 20:41:40 -07009578#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,4,0))
Mukul Sharmab0e0a982014-12-15 18:58:53 +05309579static int __wlan_hdd_cfg80211_add_beacon(struct wiphy *wiphy,
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309580 struct net_device *dev,
Jeff Johnson295189b2012-06-20 16:38:30 -07009581 struct beacon_parameters *params)
9582{
9583 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +05309584 hdd_context_t *pHddCtx;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05309585 int status;
Jeff Johnson295189b2012-06-20 16:38:30 -07009586
9587 ENTER();
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +05309588
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05309589 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
9590 TRACE_CODE_HDD_CFG80211_ADD_BEACON,
9591 pAdapter->sessionId, params->interval));
Sushant Kaushik8bc7df22014-04-09 17:55:29 +05309592 hddLog(VOS_TRACE_LEVEL_INFO_HIGH, "device mode=%s (%d)",
9593 hdd_device_modetoString(pAdapter->device_mode),
9594 pAdapter->device_mode);
Jeff Johnson295189b2012-06-20 16:38:30 -07009595
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05309596 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
9597 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05309598 if (0 != status)
Jeff Johnson04dd8a82012-06-29 20:41:40 -07009599 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05309600 return status;
Jeff Johnson04dd8a82012-06-29 20:41:40 -07009601 }
9602
Agarwal Ashish51325b52014-06-16 16:50:49 +05309603 if (vos_max_concurrent_connections_reached()) {
9604 hddLog(VOS_TRACE_LEVEL_INFO, FL("Reached max concurrent connections"));
9605 return -EINVAL;
9606 }
9607
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309608 if ( (pAdapter->device_mode == WLAN_HDD_SOFTAP)
Jeff Johnson295189b2012-06-20 16:38:30 -07009609 || (pAdapter->device_mode == WLAN_HDD_P2P_GO)
Jeff Johnson295189b2012-06-20 16:38:30 -07009610 )
9611 {
9612 beacon_data_t *old,*new;
9613
9614 old = pAdapter->sessionCtx.ap.beacon;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309615
Jeff Johnson295189b2012-06-20 16:38:30 -07009616 if (old)
c_hpothu6ff1c3c2013-10-01 19:01:57 +05309617 {
9618 hddLog(VOS_TRACE_LEVEL_WARN,
9619 FL("already beacon info added to session(%d)"),
9620 pAdapter->sessionId);
Jeff Johnson295189b2012-06-20 16:38:30 -07009621 return -EALREADY;
c_hpothu6ff1c3c2013-10-01 19:01:57 +05309622 }
Jeff Johnson295189b2012-06-20 16:38:30 -07009623
9624 status = wlan_hdd_cfg80211_alloc_new_beacon(pAdapter,&new,params);
9625
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309626 if(status != VOS_STATUS_SUCCESS)
Jeff Johnson295189b2012-06-20 16:38:30 -07009627 {
9628 hddLog(VOS_TRACE_LEVEL_FATAL,
Arif Hussain6d2a3322013-11-17 19:50:10 -08009629 "%s:Error!!! Allocating the new beacon",__func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07009630 return -EINVAL;
9631 }
9632
9633 pAdapter->sessionCtx.ap.beacon = new;
9634
9635 status = wlan_hdd_cfg80211_start_bss(pAdapter, params);
9636 }
9637
9638 EXIT();
9639 return status;
9640}
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309641
Mukul Sharmab0e0a982014-12-15 18:58:53 +05309642static int wlan_hdd_cfg80211_add_beacon(struct wiphy *wiphy,
9643 struct net_device *dev,
9644 struct beacon_parameters *params)
9645{
9646 int ret;
9647
9648 vos_ssr_protect(__func__);
9649 ret = __wlan_hdd_cfg80211_add_beacon(wiphy, dev, params);
9650 vos_ssr_unprotect(__func__);
9651
9652 return ret;
9653}
9654
9655static int __wlan_hdd_cfg80211_set_beacon(struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -07009656 struct net_device *dev,
9657 struct beacon_parameters *params)
9658{
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309659 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +05309660 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
9661 hdd_context_t *pHddCtx;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05309662 int status;
Jeff Johnson295189b2012-06-20 16:38:30 -07009663
9664 ENTER();
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05309665
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +05309666 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
9667 TRACE_CODE_HDD_CFG80211_SET_BEACON,
9668 pAdapter->sessionId, pHddStaCtx->conn_info.authType));
9669 hddLog(VOS_TRACE_LEVEL_INFO, "%s: device_mode = %s (%d)",
9670 __func__, hdd_device_modetoString(pAdapter->device_mode),
9671 pAdapter->device_mode);
9672
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05309673 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
9674 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05309675 if (0 != status)
Jeff Johnson04dd8a82012-06-29 20:41:40 -07009676 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05309677 return status;
Jeff Johnson04dd8a82012-06-29 20:41:40 -07009678 }
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +05309679
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309680 if ((pAdapter->device_mode == WLAN_HDD_SOFTAP)
Jeff Johnson295189b2012-06-20 16:38:30 -07009681 || (pAdapter->device_mode == WLAN_HDD_P2P_GO)
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309682 )
Jeff Johnson295189b2012-06-20 16:38:30 -07009683 {
9684 beacon_data_t *old,*new;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309685
Jeff Johnson295189b2012-06-20 16:38:30 -07009686 old = pAdapter->sessionCtx.ap.beacon;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309687
Jeff Johnson295189b2012-06-20 16:38:30 -07009688 if (!old)
c_hpothu6ff1c3c2013-10-01 19:01:57 +05309689 {
9690 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
9691 FL("session(%d) old and new heads points to NULL"),
9692 pAdapter->sessionId);
Jeff Johnson295189b2012-06-20 16:38:30 -07009693 return -ENOENT;
c_hpothu6ff1c3c2013-10-01 19:01:57 +05309694 }
Jeff Johnson295189b2012-06-20 16:38:30 -07009695
9696 status = wlan_hdd_cfg80211_alloc_new_beacon(pAdapter,&new,params);
9697
9698 if(status != VOS_STATUS_SUCCESS) {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309699 hddLog(VOS_TRACE_LEVEL_FATAL,
Arif Hussain6d2a3322013-11-17 19:50:10 -08009700 "%s: Error!!! Allocating the new beacon",__func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07009701 return -EINVAL;
9702 }
9703
9704 pAdapter->sessionCtx.ap.beacon = new;
9705
9706 status = wlan_hdd_cfg80211_start_bss(pAdapter, params);
9707 }
9708
9709 EXIT();
9710 return status;
9711}
9712
Mukul Sharmab0e0a982014-12-15 18:58:53 +05309713static int wlan_hdd_cfg80211_set_beacon(struct wiphy *wiphy,
9714 struct net_device *dev,
9715 struct beacon_parameters *params)
9716{
9717 int ret;
9718
9719 vos_ssr_protect(__func__);
9720 ret = __wlan_hdd_cfg80211_set_beacon(wiphy, dev, params);
9721 vos_ssr_unprotect(__func__);
9722
9723 return ret;
9724}
9725
Jeff Johnson04dd8a82012-06-29 20:41:40 -07009726#endif //(LINUX_VERSION_CODE < KERNEL_VERSION(3,4,0))
9727
9728#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,4,0))
Mukul Sharmab0e0a982014-12-15 18:58:53 +05309729static int __wlan_hdd_cfg80211_del_beacon(struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -07009730 struct net_device *dev)
Jeff Johnson04dd8a82012-06-29 20:41:40 -07009731#else
Mukul Sharmab0e0a982014-12-15 18:58:53 +05309732static int __wlan_hdd_cfg80211_stop_ap (struct wiphy *wiphy,
Jeff Johnson04dd8a82012-06-29 20:41:40 -07009733 struct net_device *dev)
9734#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07009735{
9736 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
Jeff Johnsone7245742012-09-05 17:12:55 -07009737 hdd_context_t *pHddCtx = NULL;
9738 hdd_scaninfo_t *pScanInfo = NULL;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05309739 VOS_STATUS status;
Mahesh A Saptasagar2395ee62014-05-21 19:12:21 +05309740 long ret;
Jeff Johnson295189b2012-06-20 16:38:30 -07009741
9742 ENTER();
9743
9744 if (NULL == pAdapter)
9745 {
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +05309746 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07009747 "%s: HDD adapter context is Null", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07009748 return -ENODEV;
9749 }
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -07009750
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05309751 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
9752 TRACE_CODE_HDD_CFG80211_STOP_AP,
9753 pAdapter->sessionId, pAdapter->device_mode));
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05309754 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
9755 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05309756 if (0 != status)
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -07009757 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05309758 return status;
Jeff Johnson4416a782013-03-25 14:17:50 -07009759 }
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -07009760
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -07009761 pScanInfo = &pHddCtx->scan_info;
9762
Sushant Kaushik8bc7df22014-04-09 17:55:29 +05309763 hddLog(VOS_TRACE_LEVEL_INFO, "%s: device_mode = %s (%d)",
9764 __func__, hdd_device_modetoString(pAdapter->device_mode),
9765 pAdapter->device_mode);
Jeff Johnson295189b2012-06-20 16:38:30 -07009766
Mahesh A Saptasagar2395ee62014-05-21 19:12:21 +05309767 ret = wlan_hdd_scan_abort(pAdapter);
9768
Girish Gowli4bf7a632014-06-12 13:42:11 +05309769 if (ret < 0)
Jeff Johnsone7245742012-09-05 17:12:55 -07009770 {
Mahesh A Saptasagar2395ee62014-05-21 19:12:21 +05309771 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
9772 FL("Timeout occurred while waiting for abortscan %ld"), ret);
c_hpothu6ff1c3c2013-10-01 19:01:57 +05309773
Mahesh A Saptasagar2395ee62014-05-21 19:12:21 +05309774 if (pHddCtx->isLogpInProgress)
Jeff Johnsone7245742012-09-05 17:12:55 -07009775 {
Mahesh A Saptasagar2395ee62014-05-21 19:12:21 +05309776 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
9777 "%s: LOGP in Progress. Ignore!!!", __func__);
Yue Ma4f55ef32014-01-23 16:45:33 -08009778
Jeff Johnsone7245742012-09-05 17:12:55 -07009779 VOS_ASSERT(pScanInfo->mScanPending);
Mahesh A Saptasagar2395ee62014-05-21 19:12:21 +05309780 return -EAGAIN;
Jeff Johnsone7245742012-09-05 17:12:55 -07009781 }
Mahesh A Saptasagar2395ee62014-05-21 19:12:21 +05309782 VOS_ASSERT(pScanInfo->mScanPending);
Jeff Johnsone7245742012-09-05 17:12:55 -07009783 }
9784
Rashmi Ramanna1f0948d2014-08-28 15:33:48 +05309785 /* Delete all associated STAs before stopping AP/P2P GO */
9786 hdd_del_all_sta(pAdapter);
Arun Kumar Khandavallia3bd8002014-01-17 16:21:19 +05309787 hdd_hostapd_stop(dev);
9788
Jeff Johnson295189b2012-06-20 16:38:30 -07009789 if ((pAdapter->device_mode == WLAN_HDD_SOFTAP)
Jeff Johnson295189b2012-06-20 16:38:30 -07009790 || (pAdapter->device_mode == WLAN_HDD_P2P_GO)
Jeff Johnson295189b2012-06-20 16:38:30 -07009791 )
9792 {
9793 beacon_data_t *old;
9794
9795 old = pAdapter->sessionCtx.ap.beacon;
9796
9797 if (!old)
c_hpothu6ff1c3c2013-10-01 19:01:57 +05309798 {
9799 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
9800 FL("session(%d) beacon data points to NULL"),
9801 pAdapter->sessionId);
Jeff Johnson295189b2012-06-20 16:38:30 -07009802 return -ENOENT;
c_hpothu6ff1c3c2013-10-01 19:01:57 +05309803 }
Jeff Johnson295189b2012-06-20 16:38:30 -07009804
Jeff Johnson295189b2012-06-20 16:38:30 -07009805 hdd_cleanup_actionframe(pHddCtx, pAdapter);
Jeff Johnson295189b2012-06-20 16:38:30 -07009806
9807 mutex_lock(&pHddCtx->sap_lock);
9808 if(test_bit(SOFTAP_BSS_STARTED, &pAdapter->event_flags))
9809 {
Jeff Johnson4416a782013-03-25 14:17:50 -07009810 if ( VOS_STATUS_SUCCESS == (status = WLANSAP_StopBss(pHddCtx->pvosContext) ) )
Jeff Johnson295189b2012-06-20 16:38:30 -07009811 {
9812 hdd_hostapd_state_t *pHostapdState = WLAN_HDD_GET_HOSTAP_STATE_PTR(pAdapter);
9813
9814 status = vos_wait_single_event(&pHostapdState->vosEvent, 10000);
9815
9816 if (!VOS_IS_STATUS_SUCCESS(status))
9817 {
9818 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Arif Hussain6d2a3322013-11-17 19:50:10 -08009819 ("ERROR: HDD vos wait for single_event failed!!"));
Jeff Johnson295189b2012-06-20 16:38:30 -07009820 VOS_ASSERT(0);
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05309821 }
9822 }
Jeff Johnson295189b2012-06-20 16:38:30 -07009823 clear_bit(SOFTAP_BSS_STARTED, &pAdapter->event_flags);
Agarwal Ashish51325b52014-06-16 16:50:49 +05309824 /* BSS stopped, clear the active sessions for this device mode */
9825 wlan_hdd_decr_active_session(pHddCtx, pAdapter->device_mode);
Jeff Johnson295189b2012-06-20 16:38:30 -07009826 }
9827 mutex_unlock(&pHddCtx->sap_lock);
9828
9829 if(status != VOS_STATUS_SUCCESS)
9830 {
9831 hddLog(VOS_TRACE_LEVEL_FATAL,
Arif Hussain6d2a3322013-11-17 19:50:10 -08009832 "%s:Error!!! Stopping the BSS",__func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07009833 return -EINVAL;
9834 }
9835
Jeff Johnson4416a782013-03-25 14:17:50 -07009836 if (ccmCfgSetInt(pHddCtx->hHal,
Jeff Johnson295189b2012-06-20 16:38:30 -07009837 WNI_CFG_PROBE_RSP_BCN_ADDNIE_FLAG, 0,NULL, eANI_BOOLEAN_FALSE)
9838 ==eHAL_STATUS_FAILURE)
9839 {
9840 hddLog(LOGE,
Arif Hussain6d2a3322013-11-17 19:50:10 -08009841 "Could not pass on WNI_CFG_PROBE_RSP_BCN_ADDNIE_FLAG to CCM");
Jeff Johnson295189b2012-06-20 16:38:30 -07009842 }
9843
Jeff Johnson4416a782013-03-25 14:17:50 -07009844 if ( eHAL_STATUS_FAILURE == ccmCfgSetInt(pHddCtx->hHal,
Jeff Johnson295189b2012-06-20 16:38:30 -07009845 WNI_CFG_ASSOC_RSP_ADDNIE_FLAG, 0, NULL,
9846 eANI_BOOLEAN_FALSE) )
9847 {
9848 hddLog(LOGE,
Arif Hussain6d2a3322013-11-17 19:50:10 -08009849 "Could not pass on WNI_CFG_ASSOC_RSP_ADDNIE_FLAG to CCM");
Jeff Johnson295189b2012-06-20 16:38:30 -07009850 }
9851
9852 // Reset WNI_CFG_PROBE_RSP Flags
9853 wlan_hdd_reset_prob_rspies(pAdapter);
9854
9855 pAdapter->sessionCtx.ap.beacon = NULL;
9856 kfree(old);
Madan Mohan Koyyalamudi26bd7142012-10-30 18:14:19 -07009857#ifdef WLAN_FEATURE_P2P_DEBUG
9858 if((pAdapter->device_mode == WLAN_HDD_P2P_GO) &&
9859 (globalP2PConnectionStatus == P2P_GO_COMPLETED_STATE))
9860 {
9861 hddLog(LOGE,"[P2P State] From GO completed to Inactive state "
9862 "GO got removed");
9863 globalP2PConnectionStatus = P2P_NOT_ACTIVE;
9864 }
9865#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07009866 }
9867 EXIT();
9868 return status;
9869}
Jeff Johnson04dd8a82012-06-29 20:41:40 -07009870
Mukul Sharmab0e0a982014-12-15 18:58:53 +05309871#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,4,0))
9872static int wlan_hdd_cfg80211_del_beacon(struct wiphy *wiphy,
9873 struct net_device *dev)
9874{
9875 int ret;
9876
9877 vos_ssr_protect(__func__);
9878 ret = __wlan_hdd_cfg80211_del_beacon(wiphy, dev);
9879 vos_ssr_unprotect(__func__);
9880
9881 return ret;
9882}
9883#else
9884static int wlan_hdd_cfg80211_stop_ap(struct wiphy *wiphy,
9885 struct net_device *dev)
9886{
9887 int ret;
9888
9889 vos_ssr_protect(__func__);
9890 ret = __wlan_hdd_cfg80211_stop_ap(wiphy, dev);
9891 vos_ssr_unprotect(__func__);
9892
9893 return ret;
9894}
9895#endif
9896
Jeff Johnson04dd8a82012-06-29 20:41:40 -07009897#if (LINUX_VERSION_CODE > KERNEL_VERSION(3,3,0))
9898
Mukul Sharmab0e0a982014-12-15 18:58:53 +05309899static int __wlan_hdd_cfg80211_start_ap(struct wiphy *wiphy,
Pratik Bhalgata0c7f262012-11-22 17:40:24 +05309900 struct net_device *dev,
Jeff Johnson04dd8a82012-06-29 20:41:40 -07009901 struct cfg80211_ap_settings *params)
9902{
Pratik Bhalgata0c7f262012-11-22 17:40:24 +05309903 hdd_adapter_t *pAdapter;
9904 hdd_context_t *pHddCtx;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05309905 int status;
Jeff Johnson04dd8a82012-06-29 20:41:40 -07009906
9907 ENTER();
9908
Girish Gowlib143d7a2015-02-18 19:39:55 +05309909 if (NULL == dev || NULL == params)
Madan Mohan Koyyalamudib2c36892012-10-18 20:52:38 -07009910 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05309911 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Girish Gowlib143d7a2015-02-18 19:39:55 +05309912 "%s: Device or params is Null", __func__);
Pratik Bhalgata0c7f262012-11-22 17:40:24 +05309913 return -ENODEV;
9914 }
9915
9916 pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
9917 if (NULL == pAdapter)
9918 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05309919 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Pratik Bhalgata0c7f262012-11-22 17:40:24 +05309920 "%s: HDD adapter is Null", __func__);
9921 return -ENODEV;
9922 }
9923
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05309924 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
9925 TRACE_CODE_HDD_CFG80211_START_AP, pAdapter->sessionId,
9926 params-> beacon_interval));
Pratik Bhalgata0c7f262012-11-22 17:40:24 +05309927 if (WLAN_HDD_ADAPTER_MAGIC != pAdapter->magic)
9928 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05309929 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Pratik Bhalgata0c7f262012-11-22 17:40:24 +05309930 "%s: HDD adapter magic is invalid", __func__);
9931 return -ENODEV;
9932 }
9933
9934 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05309935 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05309936 if (0 != status)
Pratik Bhalgata0c7f262012-11-22 17:40:24 +05309937 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05309938 return status;
Pratik Bhalgata0c7f262012-11-22 17:40:24 +05309939 }
9940
Sushant Kaushik8bc7df22014-04-09 17:55:29 +05309941 hddLog(VOS_TRACE_LEVEL_INFO_HIGH, "%s: device mode = %s (%d)",
9942 __func__, hdd_device_modetoString(pAdapter->device_mode),
9943 pAdapter->device_mode);
Pratik Bhalgata0c7f262012-11-22 17:40:24 +05309944
9945 if ((pAdapter->device_mode == WLAN_HDD_SOFTAP)
Jeff Johnson04dd8a82012-06-29 20:41:40 -07009946 || (pAdapter->device_mode == WLAN_HDD_P2P_GO)
Jeff Johnson04dd8a82012-06-29 20:41:40 -07009947 )
9948 {
Pratik Bhalgata0c7f262012-11-22 17:40:24 +05309949 beacon_data_t *old, *new;
Jeff Johnson04dd8a82012-06-29 20:41:40 -07009950
9951 old = pAdapter->sessionCtx.ap.beacon;
Pratik Bhalgata0c7f262012-11-22 17:40:24 +05309952
Jeff Johnson04dd8a82012-06-29 20:41:40 -07009953 if (old)
c_hpothu6ff1c3c2013-10-01 19:01:57 +05309954 {
9955 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_WARN,
9956 FL("already beacon info added to session(%d)"),
9957 pAdapter->sessionId);
Jeff Johnson04dd8a82012-06-29 20:41:40 -07009958 return -EALREADY;
c_hpothu6ff1c3c2013-10-01 19:01:57 +05309959 }
Jeff Johnson04dd8a82012-06-29 20:41:40 -07009960
Girish Gowlib143d7a2015-02-18 19:39:55 +05309961#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,4,0))
9962 status = wlan_hdd_cfg80211_alloc_new_beacon(pAdapter,
9963 &new,
9964 &params->beacon);
9965#else
9966 status = wlan_hdd_cfg80211_alloc_new_beacon(pAdapter,
9967 &new,
9968 &params->beacon,
9969 params->dtim_period);
9970#endif
Jeff Johnson04dd8a82012-06-29 20:41:40 -07009971
Pratik Bhalgata0c7f262012-11-22 17:40:24 +05309972 if (status != 0)
Jeff Johnson04dd8a82012-06-29 20:41:40 -07009973 {
9974 hddLog(VOS_TRACE_LEVEL_FATAL,
Pratik Bhalgata0c7f262012-11-22 17:40:24 +05309975 "%s:Error!!! Allocating the new beacon", __func__);
Jeff Johnson04dd8a82012-06-29 20:41:40 -07009976 return -EINVAL;
9977 }
9978 pAdapter->sessionCtx.ap.beacon = new;
Viral Modi3a32cc52013-02-08 11:14:52 -08009979#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,6,0))
Yue Maf49ba872013-08-19 12:04:25 -07009980 wlan_hdd_cfg80211_set_channel(wiphy, dev,
9981#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,8,0))
9982 params->channel, params->channel_type);
9983#else
9984 params->chandef.chan, cfg80211_get_chandef_type(&(params->chandef)));
9985#endif
Viral Modi3a32cc52013-02-08 11:14:52 -08009986#endif
Jeff Johnson04dd8a82012-06-29 20:41:40 -07009987 status = wlan_hdd_cfg80211_start_bss(pAdapter, &params->beacon, params->ssid,
Kanchanapally, Vidyullathaacc59252015-05-20 16:49:07 +05309988 params->ssid_len, params->hidden_ssid,
9989 params->auth_type);
Jeff Johnson04dd8a82012-06-29 20:41:40 -07009990 }
9991
9992 EXIT();
9993 return status;
9994}
9995
Mukul Sharmab0e0a982014-12-15 18:58:53 +05309996static int wlan_hdd_cfg80211_start_ap(struct wiphy *wiphy,
9997 struct net_device *dev,
9998 struct cfg80211_ap_settings *params)
9999{
10000 int ret;
Jeff Johnson04dd8a82012-06-29 20:41:40 -070010001
Mukul Sharmab0e0a982014-12-15 18:58:53 +053010002 vos_ssr_protect(__func__);
10003 ret = __wlan_hdd_cfg80211_start_ap(wiphy, dev, params);
10004 vos_ssr_unprotect(__func__);
10005
10006 return ret;
10007}
10008
10009static int __wlan_hdd_cfg80211_change_beacon(struct wiphy *wiphy,
Jeff Johnson04dd8a82012-06-29 20:41:40 -070010010 struct net_device *dev,
10011 struct cfg80211_beacon_data *params)
10012{
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010013 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053010014 hdd_context_t *pHddCtx;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053010015 int status;
Jeff Johnson04dd8a82012-06-29 20:41:40 -070010016
10017 ENTER();
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053010018
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053010019 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
10020 TRACE_CODE_HDD_CFG80211_CHANGE_BEACON,
10021 pAdapter->sessionId, pAdapter->device_mode));
Arif Hussain6d2a3322013-11-17 19:50:10 -080010022 hddLog(VOS_TRACE_LEVEL_INFO, "%s: device_mode = %d",
Jeff Johnson04dd8a82012-06-29 20:41:40 -070010023 __func__, pAdapter->device_mode);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053010024
10025 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
10026 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053010027 if (0 != status)
Madan Mohan Koyyalamudib2c36892012-10-18 20:52:38 -070010028 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053010029 return status;
Madan Mohan Koyyalamudib2c36892012-10-18 20:52:38 -070010030 }
Jeff Johnson04dd8a82012-06-29 20:41:40 -070010031
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010032 if ((pAdapter->device_mode == WLAN_HDD_SOFTAP)
Jeff Johnson04dd8a82012-06-29 20:41:40 -070010033 || (pAdapter->device_mode == WLAN_HDD_P2P_GO)
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010034 )
Jeff Johnson04dd8a82012-06-29 20:41:40 -070010035 {
10036 beacon_data_t *old,*new;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010037
Jeff Johnson04dd8a82012-06-29 20:41:40 -070010038 old = pAdapter->sessionCtx.ap.beacon;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010039
Jeff Johnson04dd8a82012-06-29 20:41:40 -070010040 if (!old)
c_hpothu6ff1c3c2013-10-01 19:01:57 +053010041 {
10042 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
10043 FL("session(%d) beacon data points to NULL"),
10044 pAdapter->sessionId);
Jeff Johnson04dd8a82012-06-29 20:41:40 -070010045 return -ENOENT;
c_hpothu6ff1c3c2013-10-01 19:01:57 +053010046 }
Jeff Johnson04dd8a82012-06-29 20:41:40 -070010047
10048 status = wlan_hdd_cfg80211_alloc_new_beacon(pAdapter, &new, params, 0);
10049
10050 if(status != VOS_STATUS_SUCCESS) {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010051 hddLog(VOS_TRACE_LEVEL_FATAL,
Arif Hussain6d2a3322013-11-17 19:50:10 -080010052 "%s: Error!!! Allocating the new beacon",__func__);
Jeff Johnson04dd8a82012-06-29 20:41:40 -070010053 return -EINVAL;
10054 }
10055
10056 pAdapter->sessionCtx.ap.beacon = new;
10057
Kanchanapally, Vidyullathaacc59252015-05-20 16:49:07 +053010058 status = wlan_hdd_cfg80211_start_bss(pAdapter, params, NULL, 0, 0,
10059 pAdapter->sessionCtx.ap.sapConfig.authType);
Jeff Johnson04dd8a82012-06-29 20:41:40 -070010060 }
10061
10062 EXIT();
10063 return status;
10064}
10065
Mukul Sharmab0e0a982014-12-15 18:58:53 +053010066static int wlan_hdd_cfg80211_change_beacon(struct wiphy *wiphy,
10067 struct net_device *dev,
10068 struct cfg80211_beacon_data *params)
10069{
10070 int ret;
Jeff Johnson04dd8a82012-06-29 20:41:40 -070010071
Mukul Sharmab0e0a982014-12-15 18:58:53 +053010072 vos_ssr_protect(__func__);
10073 ret = __wlan_hdd_cfg80211_change_beacon(wiphy, dev, params);
10074 vos_ssr_unprotect(__func__);
10075
10076 return ret;
10077}
10078
10079#endif //(LINUX_VERSION_CODE > KERNEL_VERSION(3,3,0))
Jeff Johnson295189b2012-06-20 16:38:30 -070010080
Mahesh A Saptasagar179d2252014-06-02 21:32:21 +053010081static int __wlan_hdd_cfg80211_change_bss (struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -070010082 struct net_device *dev,
10083 struct bss_parameters *params)
10084{
10085 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +053010086 hdd_context_t *pHddCtx;
10087 int ret = 0;
Jeff Johnson295189b2012-06-20 16:38:30 -070010088
10089 ENTER();
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053010090
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +053010091 if (NULL == pAdapter)
10092 {
10093 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
10094 "%s: HDD adapter is Null", __func__);
10095 return -ENODEV;
10096 }
10097 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +053010098 ret = wlan_hdd_validate_context(pHddCtx);
10099 if (0 != ret)
10100 {
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +053010101 return ret;
10102 }
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053010103 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
10104 TRACE_CODE_HDD_CFG80211_CHANGE_BSS,
10105 pAdapter->sessionId, params->ap_isolate));
Sushant Kaushik8bc7df22014-04-09 17:55:29 +053010106 hddLog(VOS_TRACE_LEVEL_INFO, "%s: device_mode = %s (%d)",
10107 __func__, hdd_device_modetoString(pAdapter->device_mode),
10108 pAdapter->device_mode);
Jeff Johnson295189b2012-06-20 16:38:30 -070010109
10110 if((pAdapter->device_mode == WLAN_HDD_SOFTAP)
Jeff Johnson295189b2012-06-20 16:38:30 -070010111 || (pAdapter->device_mode == WLAN_HDD_P2P_GO)
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010112 )
Jeff Johnson295189b2012-06-20 16:38:30 -070010113 {
10114 /* ap_isolate == -1 means that in change bss, upper layer doesn't
10115 * want to update this parameter */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010116 if (-1 != params->ap_isolate)
Jeff Johnson295189b2012-06-20 16:38:30 -070010117 {
10118 pAdapter->sessionCtx.ap.apDisableIntraBssFwd = !!params->ap_isolate;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010119 }
Jeff Johnson295189b2012-06-20 16:38:30 -070010120 }
10121
10122 EXIT();
10123 return 0;
10124}
10125
Mahesh A Saptasagar179d2252014-06-02 21:32:21 +053010126static int wlan_hdd_cfg80211_change_bss (struct wiphy *wiphy,
10127 struct net_device *dev,
10128 struct bss_parameters *params)
10129{
10130 int ret;
10131
10132 vos_ssr_protect(__func__);
10133 ret = __wlan_hdd_cfg80211_change_bss(wiphy, dev, params);
10134 vos_ssr_unprotect(__func__);
10135
10136 return ret;
10137}
Kiet Lam10841362013-11-01 11:36:50 +053010138/* FUNCTION: wlan_hdd_change_country_code_cd
10139* to wait for contry code completion
10140*/
10141void* wlan_hdd_change_country_code_cb(void *pAdapter)
10142{
10143 hdd_adapter_t *call_back_pAdapter = pAdapter;
10144 complete(&call_back_pAdapter->change_country_code);
10145 return NULL;
10146}
10147
Jeff Johnson295189b2012-06-20 16:38:30 -070010148/*
Mahesh A Saptasagar0e59c472014-04-14 19:17:41 +053010149 * FUNCTION: __wlan_hdd_cfg80211_change_iface
Jeff Johnson295189b2012-06-20 16:38:30 -070010150 * This function is used to set the interface type (INFRASTRUCTURE/ADHOC)
10151 */
Mahesh A Saptasagar0e59c472014-04-14 19:17:41 +053010152int __wlan_hdd_cfg80211_change_iface( struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -070010153 struct net_device *ndev,
10154 enum nl80211_iftype type,
10155 u32 *flags,
10156 struct vif_params *params
10157 )
10158{
10159 struct wireless_dev *wdev;
10160 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( ndev );
Rajesh Chauhana0516c62014-01-30 16:11:18 -080010161 hdd_context_t *pHddCtx;
Mohit Khanna0f232092012-09-11 14:46:08 -070010162 hdd_adapter_t *pP2pAdapter = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -070010163 tCsrRoamProfile *pRoamProfile = NULL;
10164 eCsrRoamBssType LastBSSType;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053010165 hdd_config_t *pConfig = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -070010166 eMib_dot11DesiredBssType connectedBssType;
10167 VOS_STATUS status;
c_hpothu6ff1c3c2013-10-01 19:01:57 +053010168 long ret;
Jeff Johnson295189b2012-06-20 16:38:30 -070010169
10170 ENTER();
10171
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053010172 if (!pAdapter)
Rajesh Chauhana0516c62014-01-30 16:11:18 -080010173 {
10174 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
10175 "%s: Adapter context is null", __func__);
10176 return VOS_STATUS_E_FAILURE;
10177 }
10178
10179 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
10180 if (!pHddCtx)
10181 {
10182 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
10183 "%s: HDD context is null", __func__);
10184 return VOS_STATUS_E_FAILURE;
10185 }
10186
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053010187 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
10188 TRACE_CODE_HDD_CFG80211_CHANGE_IFACE,
10189 pAdapter->sessionId, type));
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053010190 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053010191 if (0 != status)
Jeff Johnson295189b2012-06-20 16:38:30 -070010192 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053010193 return status;
Jeff Johnson295189b2012-06-20 16:38:30 -070010194 }
10195
Sushant Kaushik8bc7df22014-04-09 17:55:29 +053010196 hddLog(VOS_TRACE_LEVEL_INFO, "%s: device_mode = %s (%d)",
10197 __func__, hdd_device_modetoString(pAdapter->device_mode),
10198 pAdapter->device_mode);
Jeff Johnson295189b2012-06-20 16:38:30 -070010199
Agarwal Ashish51325b52014-06-16 16:50:49 +053010200 if (vos_max_concurrent_connections_reached()) {
10201 hddLog(VOS_TRACE_LEVEL_INFO, FL("Reached max concurrent connections"));
10202 return -EINVAL;
10203 }
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053010204 pConfig = pHddCtx->cfg_ini;
Jeff Johnson295189b2012-06-20 16:38:30 -070010205 wdev = ndev->ieee80211_ptr;
10206
10207#ifdef WLAN_BTAMP_FEATURE
10208 if((NL80211_IFTYPE_P2P_CLIENT == type)||
10209 (NL80211_IFTYPE_ADHOC == type)||
10210 (NL80211_IFTYPE_AP == type)||
10211 (NL80211_IFTYPE_P2P_GO == type))
10212 {
10213 pHddCtx->isAmpAllowed = VOS_FALSE;
10214 // stop AMP traffic
10215 status = WLANBAP_StopAmp();
10216 if(VOS_STATUS_SUCCESS != status )
10217 {
10218 pHddCtx->isAmpAllowed = VOS_TRUE;
10219 hddLog(VOS_TRACE_LEVEL_FATAL,
10220 "%s: Failed to stop AMP", __func__);
10221 return -EINVAL;
10222 }
10223 }
10224#endif //WLAN_BTAMP_FEATURE
10225 /* Reset the current device mode bit mask*/
10226 wlan_hdd_clear_concurrency_mode(pHddCtx, pAdapter->device_mode);
10227
Masti, Narayanraddi575ccc72015-08-17 18:04:57 +053010228 if ((pAdapter->device_mode == WLAN_HDD_P2P_DEVICE) &&
10229 ((type == NL80211_IFTYPE_P2P_CLIENT) ||
10230 (type == NL80211_IFTYPE_P2P_GO)))
10231 {
10232 /* Notify Mode change in case of concurrency.
10233 * Below function invokes TDLS teardown Functionality Since TDLS is
10234 * not Supported in case of concurrency i.e Once P2P session
10235 * is detected disable offchannel and teardown TDLS links
10236 */
10237 hddLog(LOG1,
10238 FL("Device mode = %d Interface type = %d"),
10239 pAdapter->device_mode, type);
10240 hdd_tdls_notify_mode_change(pAdapter, pHddCtx);
10241 }
Masti, Narayanraddifdde4d02015-04-16 14:41:51 +053010242
Jeff Johnson295189b2012-06-20 16:38:30 -070010243 if( (pAdapter->device_mode == WLAN_HDD_INFRA_STATION)
Jeff Johnson295189b2012-06-20 16:38:30 -070010244 || (pAdapter->device_mode == WLAN_HDD_P2P_CLIENT)
Jeff Johnsone7245742012-09-05 17:12:55 -070010245 || (pAdapter->device_mode == WLAN_HDD_P2P_DEVICE)
Jeff Johnson295189b2012-06-20 16:38:30 -070010246 )
10247 {
10248 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
Rajesh Chauhana0516c62014-01-30 16:11:18 -080010249 if (!pWextState)
10250 {
10251 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
10252 "%s: pWextState is null", __func__);
10253 return VOS_STATUS_E_FAILURE;
10254 }
Jeff Johnson295189b2012-06-20 16:38:30 -070010255 pRoamProfile = &pWextState->roamProfile;
10256 LastBSSType = pRoamProfile->BSSType;
10257
10258 switch (type)
10259 {
10260 case NL80211_IFTYPE_STATION:
Jeff Johnson295189b2012-06-20 16:38:30 -070010261 case NL80211_IFTYPE_P2P_CLIENT:
Jeff Johnson295189b2012-06-20 16:38:30 -070010262 hddLog(VOS_TRACE_LEVEL_INFO,
10263 "%s: setting interface Type to INFRASTRUCTURE", __func__);
10264 pRoamProfile->BSSType = eCSR_BSS_TYPE_INFRASTRUCTURE;
Jeff Johnsone7245742012-09-05 17:12:55 -070010265#ifdef WLAN_FEATURE_11AC
10266 if(pConfig->dot11Mode == eHDD_DOT11_MODE_AUTO)
10267 {
10268 pConfig->dot11Mode = eHDD_DOT11_MODE_11ac;
10269 }
10270#endif
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010271 pRoamProfile->phyMode =
Jeff Johnsone7245742012-09-05 17:12:55 -070010272 hdd_cfg_xlate_to_csr_phy_mode(pConfig->dot11Mode);
Jeff Johnson295189b2012-06-20 16:38:30 -070010273 wdev->iftype = type;
Gopichand Nakkalaf527dc62012-12-31 16:35:10 -080010274 //Check for sub-string p2p to confirm its a p2p interface
10275 if (NULL != strstr(ndev->name,"p2p"))
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010276 {
Mahesh A Saptasagarc48ae8a2015-08-09 00:04:35 +053010277#ifdef FEATURE_WLAN_TDLS
10278 mutex_lock(&pHddCtx->tdls_lock);
10279 wlan_hdd_tdls_exit(pAdapter, TRUE);
10280 mutex_unlock(&pHddCtx->tdls_lock);
10281#endif
Gopichand Nakkala864d3552012-12-31 16:08:51 -080010282 pAdapter->device_mode = (type == NL80211_IFTYPE_STATION) ?
10283 WLAN_HDD_P2P_DEVICE : WLAN_HDD_P2P_CLIENT;
10284 }
10285 else
10286 {
10287 pAdapter->device_mode = (type == NL80211_IFTYPE_STATION) ?
Jeff Johnson295189b2012-06-20 16:38:30 -070010288 WLAN_HDD_INFRA_STATION: WLAN_HDD_P2P_CLIENT;
Gopichand Nakkala864d3552012-12-31 16:08:51 -080010289 }
Jeff Johnson295189b2012-06-20 16:38:30 -070010290 break;
Mahesh A Saptasagar36cdc802015-01-07 18:41:17 +053010291
Jeff Johnson295189b2012-06-20 16:38:30 -070010292 case NL80211_IFTYPE_ADHOC:
10293 hddLog(VOS_TRACE_LEVEL_INFO,
10294 "%s: setting interface Type to ADHOC", __func__);
10295 pRoamProfile->BSSType = eCSR_BSS_TYPE_START_IBSS;
10296 pRoamProfile->phyMode =
10297 hdd_cfg_xlate_to_csr_phy_mode(pConfig->dot11Mode);
Shailender Karmuchia734f332013-04-19 14:02:48 -070010298 pAdapter->device_mode = WLAN_HDD_IBSS;
Jeff Johnson295189b2012-06-20 16:38:30 -070010299 wdev->iftype = type;
Katya Nigam1fd24402015-02-16 14:52:19 +053010300 hdd_set_ibss_ops( pAdapter );
10301 hdd_ibss_init_tx_rx( pAdapter );
Nirav Shah7e3c8132015-06-22 23:51:42 +053010302
10303 status = hdd_sta_id_hash_attach(pAdapter);
10304 if (VOS_STATUS_SUCCESS != status) {
10305 hddLog(VOS_TRACE_LEVEL_ERROR,
10306 FL("Failed to initialize hash for IBSS"));
10307 }
Jeff Johnson295189b2012-06-20 16:38:30 -070010308 break;
10309
10310 case NL80211_IFTYPE_AP:
Jeff Johnson295189b2012-06-20 16:38:30 -070010311 case NL80211_IFTYPE_P2P_GO:
Jeff Johnson295189b2012-06-20 16:38:30 -070010312 {
10313 hddLog(VOS_TRACE_LEVEL_INFO_HIGH,
10314 "%s: setting interface Type to %s", __func__,
10315 (type == NL80211_IFTYPE_AP) ? "SoftAP" : "P2pGo");
10316
Gopichand Nakkalaf527dc62012-12-31 16:35:10 -080010317 //Cancel any remain on channel for GO mode
10318 if (NL80211_IFTYPE_P2P_GO == type)
10319 {
10320 wlan_hdd_cancel_existing_remain_on_channel(pAdapter);
10321 }
Mohit Khanna0f232092012-09-11 14:46:08 -070010322 if (NL80211_IFTYPE_AP == type)
10323 {
10324 /* As Loading WLAN Driver one interface being created for p2p device
10325 * address. This will take one HW STA and the max number of clients
10326 * that can connect to softAP will be reduced by one. so while changing
10327 * the interface type to NL80211_IFTYPE_AP (SoftAP) remove p2p0
10328 * interface as it is not required in SoftAP mode.
10329 */
10330
10331 // Get P2P Adapter
10332 pP2pAdapter = hdd_get_adapter(pHddCtx, WLAN_HDD_P2P_DEVICE);
10333
10334 if (pP2pAdapter)
10335 {
Agarwal Ashish3a38bd12014-06-12 15:16:52 +053010336 hdd_stop_adapter(pHddCtx, pP2pAdapter, VOS_TRUE);
c_hpothu002231a2015-02-05 14:58:51 +053010337 hdd_deinit_adapter(pHddCtx, pP2pAdapter, TRUE);
Mohit Khanna0f232092012-09-11 14:46:08 -070010338 hdd_close_adapter(pHddCtx, pP2pAdapter, VOS_TRUE);
10339 }
10340 }
Swaroop Goltia2e32212014-04-09 23:37:33 +053010341 //Disable IMPS & BMPS for SAP/GO
10342 if(VOS_STATUS_E_FAILURE ==
10343 hdd_disable_bmps_imps(pHddCtx, WLAN_HDD_P2P_GO))
10344 {
10345 //Fail to Exit BMPS
10346 VOS_ASSERT(0);
10347 }
Deepthi Gowri500fc472014-08-11 19:53:10 +053010348
10349 hdd_stop_adapter( pHddCtx, pAdapter, VOS_TRUE );
10350
Madan Mohan Koyyalamudi96797442013-10-08 16:04:42 +053010351#ifdef FEATURE_WLAN_TDLS
Mohit Khanna0f232092012-09-11 14:46:08 -070010352
Madan Mohan Koyyalamudi96797442013-10-08 16:04:42 +053010353 /* A Mutex Lock is introduced while changing the mode to
10354 * protect the concurrent access for the Adapters by TDLS
10355 * module.
10356 */
Rajesh Chauhana34c6e62014-03-25 16:37:58 +053010357 mutex_lock(&pHddCtx->tdls_lock);
Madan Mohan Koyyalamudi96797442013-10-08 16:04:42 +053010358#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070010359 //De-init the adapter.
c_hpothu002231a2015-02-05 14:58:51 +053010360 hdd_deinit_adapter( pHddCtx, pAdapter, TRUE);
Jeff Johnson295189b2012-06-20 16:38:30 -070010361 memset(&pAdapter->sessionCtx, 0, sizeof(pAdapter->sessionCtx));
Jeff Johnson295189b2012-06-20 16:38:30 -070010362 pAdapter->device_mode = (type == NL80211_IFTYPE_AP) ?
10363 WLAN_HDD_SOFTAP : WLAN_HDD_P2P_GO;
Madan Mohan Koyyalamudi96797442013-10-08 16:04:42 +053010364#ifdef FEATURE_WLAN_TDLS
10365 mutex_unlock(&pHddCtx->tdls_lock);
10366#endif
Madan Mohan Koyyalamudi3ff2a0b2012-10-15 14:33:46 -070010367 if ((WLAN_HDD_SOFTAP == pAdapter->device_mode) &&
10368 (pConfig->apRandomBssidEnabled))
10369 {
10370 /* To meet Android requirements create a randomized
10371 MAC address of the form 02:1A:11:Fx:xx:xx */
10372 get_random_bytes(&ndev->dev_addr[3], 3);
10373 ndev->dev_addr[0] = 0x02;
10374 ndev->dev_addr[1] = 0x1A;
10375 ndev->dev_addr[2] = 0x11;
10376 ndev->dev_addr[3] |= 0xF0;
10377 memcpy(pAdapter->macAddressCurrent.bytes, ndev->dev_addr,
10378 VOS_MAC_ADDR_SIZE);
Arif Hussain24bafea2013-11-15 15:10:03 -080010379 pr_info("wlan: Generated HotSpot BSSID " MAC_ADDRESS_STR"\n",
10380 MAC_ADDR_ARRAY(ndev->dev_addr));
Madan Mohan Koyyalamudi3ff2a0b2012-10-15 14:33:46 -070010381 }
10382
Jeff Johnson295189b2012-06-20 16:38:30 -070010383 hdd_set_ap_ops( pAdapter->dev );
10384
Kiet Lam10841362013-11-01 11:36:50 +053010385 /* This is for only SAP mode where users can
10386 * control country through ini.
10387 * P2P GO follows station country code
10388 * acquired during the STA scanning. */
10389 if((NL80211_IFTYPE_AP == type) &&
10390 (memcmp(pConfig->apCntryCode, CFG_AP_COUNTRY_CODE_DEFAULT, 3) != 0))
10391 {
10392 int status = 0;
10393 VOS_TRACE(VOS_MODULE_ID_HDD,VOS_TRACE_LEVEL_INFO,
10394 "%s: setting country code from INI ", __func__);
10395 init_completion(&pAdapter->change_country_code);
10396 status = (int)sme_ChangeCountryCode(pHddCtx->hHal,
10397 (void *)(tSmeChangeCountryCallback)
10398 wlan_hdd_change_country_code_cb,
10399 pConfig->apCntryCode, pAdapter,
10400 pHddCtx->pvosContext,
Abhishek Singha306a442013-11-07 18:39:01 +053010401 eSIR_FALSE,
10402 eSIR_TRUE);
Kiet Lam10841362013-11-01 11:36:50 +053010403 if (eHAL_STATUS_SUCCESS == status)
10404 {
10405 /* Wait for completion */
c_hpothu6ff1c3c2013-10-01 19:01:57 +053010406 ret = wait_for_completion_interruptible_timeout(
Kiet Lam10841362013-11-01 11:36:50 +053010407 &pAdapter->change_country_code,
10408 msecs_to_jiffies(WLAN_WAIT_TIME_COUNTRY));
c_hpothu6ff1c3c2013-10-01 19:01:57 +053010409 if (ret <= 0)
Kiet Lam10841362013-11-01 11:36:50 +053010410 {
10411 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
c_hpothu6ff1c3c2013-10-01 19:01:57 +053010412 FL("SME Timed out while setting country code %ld"),
10413 ret);
Yue Ma4f55ef32014-01-23 16:45:33 -080010414
10415 if (pHddCtx->isLogpInProgress)
10416 {
10417 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
10418 "%s: LOGP in Progress. Ignore!!!", __func__);
10419 return -EAGAIN;
10420 }
Kiet Lam10841362013-11-01 11:36:50 +053010421 }
10422 }
10423 else
10424 {
10425 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Arif Hussain6d2a3322013-11-17 19:50:10 -080010426 "%s: SME Change Country code failed",__func__);
Kiet Lam10841362013-11-01 11:36:50 +053010427 return -EINVAL;
10428 }
10429 }
Jeff Johnson295189b2012-06-20 16:38:30 -070010430 status = hdd_init_ap_mode(pAdapter);
10431 if(status != VOS_STATUS_SUCCESS)
10432 {
10433 hddLog(VOS_TRACE_LEVEL_FATAL,
10434 "%s: Error initializing the ap mode", __func__);
10435 return -EINVAL;
10436 }
10437 hdd_set_conparam(1);
10438
Nirav Shah7e3c8132015-06-22 23:51:42 +053010439 status = hdd_sta_id_hash_attach(pAdapter);
10440 if (VOS_STATUS_SUCCESS != status)
10441 {
10442 hddLog(VOS_TRACE_LEVEL_ERROR,
10443 FL("Failed to initialize hash for AP"));
10444 return -EINVAL;
10445 }
10446
Jeff Johnson295189b2012-06-20 16:38:30 -070010447 /*interface type changed update in wiphy structure*/
10448 if(wdev)
10449 {
10450 wdev->iftype = type;
10451 pHddCtx->change_iface = type;
10452 }
10453 else
10454 {
10455 hddLog(VOS_TRACE_LEVEL_ERROR,
10456 "%s: ERROR !!!! Wireless dev is NULL", __func__);
10457 return -EINVAL;
10458 }
10459 goto done;
10460 }
10461
10462 default:
10463 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Unsupported interface Type",
10464 __func__);
10465 return -EOPNOTSUPP;
10466 }
10467 }
10468 else if ( (pAdapter->device_mode == WLAN_HDD_SOFTAP)
Jeff Johnson295189b2012-06-20 16:38:30 -070010469 || (pAdapter->device_mode == WLAN_HDD_P2P_GO)
Jeff Johnson295189b2012-06-20 16:38:30 -070010470 )
10471 {
10472 switch(type)
10473 {
10474 case NL80211_IFTYPE_STATION:
Jeff Johnson295189b2012-06-20 16:38:30 -070010475 case NL80211_IFTYPE_P2P_CLIENT:
Jeff Johnson295189b2012-06-20 16:38:30 -070010476 case NL80211_IFTYPE_ADHOC:
Deepthi Gowri500fc472014-08-11 19:53:10 +053010477
10478 hdd_stop_adapter( pHddCtx, pAdapter, VOS_TRUE );
Madan Mohan Koyyalamudi96797442013-10-08 16:04:42 +053010479#ifdef FEATURE_WLAN_TDLS
10480
10481 /* A Mutex Lock is introduced while changing the mode to
10482 * protect the concurrent access for the Adapters by TDLS
10483 * module.
10484 */
Rajesh Chauhana34c6e62014-03-25 16:37:58 +053010485 mutex_lock(&pHddCtx->tdls_lock);
Madan Mohan Koyyalamudi96797442013-10-08 16:04:42 +053010486#endif
c_hpothu002231a2015-02-05 14:58:51 +053010487 hdd_deinit_adapter( pHddCtx, pAdapter, TRUE);
Jeff Johnson295189b2012-06-20 16:38:30 -070010488 wdev->iftype = type;
Gopichand Nakkalaf527dc62012-12-31 16:35:10 -080010489 //Check for sub-string p2p to confirm its a p2p interface
10490 if (NULL != strstr(ndev->name,"p2p"))
Gopichand Nakkala864d3552012-12-31 16:08:51 -080010491 {
10492 pAdapter->device_mode = (type == NL80211_IFTYPE_STATION) ?
10493 WLAN_HDD_P2P_DEVICE : WLAN_HDD_P2P_CLIENT;
10494 }
10495 else
10496 {
10497 pAdapter->device_mode = (type == NL80211_IFTYPE_STATION) ?
Jeff Johnson295189b2012-06-20 16:38:30 -070010498 WLAN_HDD_INFRA_STATION: WLAN_HDD_P2P_CLIENT;
Gopichand Nakkala864d3552012-12-31 16:08:51 -080010499 }
Jeff Johnson295189b2012-06-20 16:38:30 -070010500 hdd_set_conparam(0);
10501 pHddCtx->change_iface = type;
Jeff Johnson295189b2012-06-20 16:38:30 -070010502 memset(&pAdapter->sessionCtx, 0, sizeof(pAdapter->sessionCtx));
10503 hdd_set_station_ops( pAdapter->dev );
Madan Mohan Koyyalamudi96797442013-10-08 16:04:42 +053010504#ifdef FEATURE_WLAN_TDLS
10505 mutex_unlock(&pHddCtx->tdls_lock);
10506#endif
Sunil Dutt66485cb2013-12-19 19:05:03 +053010507 status = hdd_init_station_mode( pAdapter );
Jeff Johnson295189b2012-06-20 16:38:30 -070010508 if( VOS_STATUS_SUCCESS != status )
10509 return -EOPNOTSUPP;
Jeff Johnsone7245742012-09-05 17:12:55 -070010510 /* In case of JB, for P2P-GO, only change interface will be called,
10511 * This is the right place to enable back bmps_imps()
10512 */
Gopichand Nakkalaa2fe5b02013-06-06 16:32:28 +053010513 if (pHddCtx->hdd_wlan_suspended)
10514 {
10515 hdd_set_pwrparams(pHddCtx);
10516 }
Jeff Johnsone7245742012-09-05 17:12:55 -070010517 hdd_enable_bmps_imps(pHddCtx);
Jeff Johnson295189b2012-06-20 16:38:30 -070010518 goto done;
10519 case NL80211_IFTYPE_AP:
Jeff Johnson295189b2012-06-20 16:38:30 -070010520 case NL80211_IFTYPE_P2P_GO:
Jeff Johnson295189b2012-06-20 16:38:30 -070010521 wdev->iftype = type;
Jeff Johnson295189b2012-06-20 16:38:30 -070010522 pAdapter->device_mode = (type == NL80211_IFTYPE_AP) ?
10523 WLAN_HDD_SOFTAP : WLAN_HDD_P2P_GO;
Jeff Johnson295189b2012-06-20 16:38:30 -070010524 goto done;
10525 default:
10526 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Unsupported interface Type",
10527 __func__);
10528 return -EOPNOTSUPP;
10529
10530 }
10531
10532 }
10533 else
10534 {
Sushant Kaushik8bc7df22014-04-09 17:55:29 +053010535 hddLog(VOS_TRACE_LEVEL_ERROR,"%s: unsupported device mode(%s (%d))",
10536 __func__, hdd_device_modetoString(pAdapter->device_mode),
10537 pAdapter->device_mode);
Jeff Johnson295189b2012-06-20 16:38:30 -070010538 return -EOPNOTSUPP;
10539 }
10540
10541
10542 if(pRoamProfile)
10543 {
10544 if ( LastBSSType != pRoamProfile->BSSType )
10545 {
10546 /*interface type changed update in wiphy structure*/
10547 wdev->iftype = type;
10548
10549 /*the BSS mode changed, We need to issue disconnect
10550 if connected or in IBSS disconnect state*/
10551 if ( hdd_connGetConnectedBssType(
10552 WLAN_HDD_GET_STATION_CTX_PTR(pAdapter), &connectedBssType ) ||
10553 ( eCSR_BSS_TYPE_START_IBSS == LastBSSType ) )
10554 {
10555 /*need to issue a disconnect to CSR.*/
10556 INIT_COMPLETION(pAdapter->disconnect_comp_var);
10557 if( eHAL_STATUS_SUCCESS ==
10558 sme_RoamDisconnect( WLAN_HDD_GET_HAL_CTX(pAdapter),
10559 pAdapter->sessionId,
10560 eCSR_DISCONNECT_REASON_UNSPECIFIED ) )
10561 {
c_hpothu6ff1c3c2013-10-01 19:01:57 +053010562 ret = wait_for_completion_interruptible_timeout(
10563 &pAdapter->disconnect_comp_var,
10564 msecs_to_jiffies(WLAN_WAIT_TIME_DISCONNECT));
10565 if (ret <= 0)
10566 {
10567 hddLog(VOS_TRACE_LEVEL_ERROR,
10568 FL("wait on disconnect_comp_var failed %ld"), ret);
10569 }
Jeff Johnson295189b2012-06-20 16:38:30 -070010570 }
10571 }
10572 }
10573 }
10574
10575done:
10576 /*set bitmask based on updated value*/
10577 wlan_hdd_set_concurrency_mode(pHddCtx, pAdapter->device_mode);
Leo Chang6fe1f922013-06-07 19:21:24 -070010578
10579 /* Only STA mode support TM now
10580 * all other mode, TM feature should be disabled */
10581 if ( (pHddCtx->cfg_ini->thermalMitigationEnable) &&
10582 (~VOS_STA & pHddCtx->concurrency_mode) )
10583 {
10584 hddDevTmLevelChangedHandler(pHddCtx->parent_dev, 0);
10585 }
10586
Jeff Johnson295189b2012-06-20 16:38:30 -070010587#ifdef WLAN_BTAMP_FEATURE
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010588 if((NL80211_IFTYPE_STATION == type) && (pHddCtx->concurrency_mode <= 1) &&
Agarwal Ashish51325b52014-06-16 16:50:49 +053010589 (pHddCtx->no_of_open_sessions[WLAN_HDD_INFRA_STATION] <=1))
Jeff Johnson295189b2012-06-20 16:38:30 -070010590 {
10591 //we are ok to do AMP
10592 pHddCtx->isAmpAllowed = VOS_TRUE;
10593 }
10594#endif //WLAN_BTAMP_FEATURE
10595 EXIT();
10596 return 0;
10597}
10598
Mahesh A Saptasagar0e59c472014-04-14 19:17:41 +053010599/*
10600 * FUNCTION: wlan_hdd_cfg80211_change_iface
10601 * wrapper function to protect the actual implementation from SSR.
10602 */
10603int wlan_hdd_cfg80211_change_iface( struct wiphy *wiphy,
10604 struct net_device *ndev,
10605 enum nl80211_iftype type,
10606 u32 *flags,
10607 struct vif_params *params
10608 )
10609{
10610 int ret;
10611
10612 vos_ssr_protect(__func__);
10613 ret = __wlan_hdd_cfg80211_change_iface(wiphy, ndev, type, flags, params);
10614 vos_ssr_unprotect(__func__);
10615
10616 return ret;
10617}
10618
Gopichand Nakkala681989c2013-03-06 22:27:48 -080010619#ifdef FEATURE_WLAN_TDLS
10620static int wlan_hdd_tdls_add_station(struct wiphy *wiphy,
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053010621 struct net_device *dev,
10622#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,18,0))
10623 const u8 *mac,
10624#else
10625 u8 *mac,
10626#endif
10627 bool update, tCsrStaParams *StaParams)
Gopichand Nakkala681989c2013-03-06 22:27:48 -080010628{
Gopichand Nakkala681989c2013-03-06 22:27:48 -080010629 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
Hoonki Lee5305c3a2013-04-29 23:28:59 -070010630 hddTdlsPeer_t *pTdlsPeer;
c_hpothu6ff1c3c2013-10-01 19:01:57 +053010631 long ret;
Rajesh Chauhana34c6e62014-03-25 16:37:58 +053010632 tANI_U16 numCurrTdlsPeers;
Chandrasekaran, Manishekar41b8e1f2015-03-10 13:30:28 +053010633 hdd_adapter_t *pAdapter;
Ganesh Kondabattinif065c1f2015-08-05 23:05:23 +053010634 VOS_STATUS status;
Gopichand Nakkala681989c2013-03-06 22:27:48 -080010635
10636 ENTER();
10637
Chandrasekaran, Manishekar41b8e1f2015-03-10 13:30:28 +053010638 if (!dev) {
10639 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Dev pointer is NULL"));
10640 return -EINVAL;
10641 }
10642
10643 pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
10644 if (!pAdapter) {
10645 hddLog(VOS_TRACE_LEVEL_ERROR, FL("HDD adapter is NULL"));
10646 return -EINVAL;
10647 }
10648
Gopichand Nakkala838be5d2013-04-10 22:41:51 +053010649 if (NULL == pHddCtx || NULL == pHddCtx->cfg_ini)
Gopichand Nakkala681989c2013-03-06 22:27:48 -080010650 {
10651 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
10652 "Invalid arguments");
10653 return -EINVAL;
10654 }
Hoonki Lee27511902013-03-14 18:19:06 -070010655
10656 if ((eTDLS_SUPPORT_NOT_ENABLED == pHddCtx->tdls_mode) ||
10657 (eTDLS_SUPPORT_DISABLED == pHddCtx->tdls_mode))
10658 {
Masti, Narayanraddi34e0e562015-03-05 18:23:03 +053010659 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Hoonki Lee27511902013-03-14 18:19:06 -070010660 "%s: TDLS mode is disabled OR not enabled in FW."
10661 MAC_ADDRESS_STR " Request declined.",
10662 __func__, MAC_ADDR_ARRAY(mac));
10663 return -ENOTSUPP;
10664 }
10665
Gopichand Nakkala681989c2013-03-06 22:27:48 -080010666 if (pHddCtx->isLogpInProgress)
10667 {
10668 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
10669 "%s:LOGP in Progress. Ignore!!!", __func__);
Atul Mittal115287b2014-07-08 13:26:33 +053010670 wlan_hdd_tdls_set_link_status(pAdapter,
10671 mac,
10672 eTDLS_LINK_IDLE,
10673 eTDLS_LINK_UNSPECIFIED);
Gopichand Nakkala681989c2013-03-06 22:27:48 -080010674 return -EBUSY;
10675 }
10676
Masti, Narayanraddi6dbcdbb2015-05-13 10:28:06 +053010677 mutex_lock(&pHddCtx->tdls_lock);
Naresh Jayaram9c6f4462014-02-13 12:20:31 +053010678 pTdlsPeer = wlan_hdd_tdls_get_peer(pAdapter, mac);
Hoonki Lee5305c3a2013-04-29 23:28:59 -070010679
10680 if ( NULL == pTdlsPeer ) {
Masti, Narayanraddi34e0e562015-03-05 18:23:03 +053010681 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Hoonki Lee5305c3a2013-04-29 23:28:59 -070010682 "%s: " MAC_ADDRESS_STR " (update %d) not exist. return invalid",
10683 __func__, MAC_ADDR_ARRAY(mac), update);
Masti, Narayanraddi6dbcdbb2015-05-13 10:28:06 +053010684 mutex_unlock(&pHddCtx->tdls_lock);
Hoonki Lee5305c3a2013-04-29 23:28:59 -070010685 return -EINVAL;
Gopichand Nakkala34d1b062013-03-19 15:28:33 -070010686 }
Hoonki Lee5305c3a2013-04-29 23:28:59 -070010687
10688 /* in add station, we accept existing valid staId if there is */
10689 if ((0 == update) &&
10690 ((pTdlsPeer->link_status >= eTDLS_LINK_CONNECTING) ||
10691 (TDLS_STA_INDEX_VALID(pTdlsPeer->staId))))
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -070010692 {
Masti, Narayanraddi34e0e562015-03-05 18:23:03 +053010693 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -070010694 "%s: " MAC_ADDRESS_STR
Hoonki Lee5305c3a2013-04-29 23:28:59 -070010695 " link_status %d. staId %d. add station ignored.",
10696 __func__, MAC_ADDR_ARRAY(mac), pTdlsPeer->link_status, pTdlsPeer->staId);
Masti, Narayanraddi6b93b472015-09-04 17:48:11 +053010697 mutex_unlock(&pHddCtx->tdls_lock);
Hoonki Lee5305c3a2013-04-29 23:28:59 -070010698 return 0;
10699 }
10700 /* in change station, we accept only when staId is valid */
10701 if ((1 == update) &&
10702 ((pTdlsPeer->link_status > eTDLS_LINK_CONNECTING) ||
10703 (!TDLS_STA_INDEX_VALID(pTdlsPeer->staId))))
10704 {
Masti, Narayanraddi6b93b472015-09-04 17:48:11 +053010705 tANI_U16 staId = pTdlsPeer->staId;
Masti, Narayanraddi34e0e562015-03-05 18:23:03 +053010706 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Hoonki Lee5305c3a2013-04-29 23:28:59 -070010707 "%s: " MAC_ADDRESS_STR
10708 " link status %d. staId %d. change station %s.",
Masti, Narayanraddi6b93b472015-09-04 17:48:11 +053010709 __func__, MAC_ADDR_ARRAY(mac), pTdlsPeer->link_status, staId,
10710 (TDLS_STA_INDEX_VALID(staId)) ? "ignored" : "declined");
10711 mutex_unlock(&pHddCtx->tdls_lock);
10712 return (TDLS_STA_INDEX_VALID(staId)) ? 0 : -EPERM;
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -070010713 }
Masti, Narayanraddi6b93b472015-09-04 17:48:11 +053010714 mutex_unlock(&pHddCtx->tdls_lock);
Gopichand Nakkala34d1b062013-03-19 15:28:33 -070010715
10716 /* when others are on-going, we want to change link_status to idle */
Pradeep Reddy POTTETI9db32f02015-01-29 15:22:54 +053010717 if (NULL != wlan_hdd_tdls_is_progress(pHddCtx, mac, TRUE, TRUE))
Gopichand Nakkala681989c2013-03-06 22:27:48 -080010718 {
Gopichand Nakkalac87400e2013-03-13 18:51:00 -070010719 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
10720 "%s: " MAC_ADDRESS_STR
10721 " TDLS setup is ongoing. Request declined.",
10722 __func__, MAC_ADDR_ARRAY(mac));
Gopichand Nakkala05922802013-03-14 12:23:19 -070010723 goto error;
Gopichand Nakkala681989c2013-03-06 22:27:48 -080010724 }
10725
10726 /* first to check if we reached to maximum supported TDLS peer.
10727 TODO: for now, return -EPERM looks working fine,
10728 but need to check if any other errno fit into this category.*/
Rajesh Chauhana34c6e62014-03-25 16:37:58 +053010729 numCurrTdlsPeers = wlan_hdd_tdlsConnectedPeers(pAdapter);
10730 if (HDD_MAX_NUM_TDLS_STA <= numCurrTdlsPeers)
Gopichand Nakkala681989c2013-03-06 22:27:48 -080010731 {
Gopichand Nakkalac87400e2013-03-13 18:51:00 -070010732 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
10733 "%s: " MAC_ADDRESS_STR
Rajesh Chauhana34c6e62014-03-25 16:37:58 +053010734 " TDLS Max peer already connected. Request declined."
10735 " Num of peers (%d), Max allowed (%d).",
10736 __func__, MAC_ADDR_ARRAY(mac), numCurrTdlsPeers,
10737 HDD_MAX_NUM_TDLS_STA);
Gopichand Nakkala05922802013-03-14 12:23:19 -070010738 goto error;
Gopichand Nakkala681989c2013-03-06 22:27:48 -080010739 }
10740 else
10741 {
10742 hddTdlsPeer_t *pTdlsPeer;
Masti, Narayanraddi6b93b472015-09-04 17:48:11 +053010743 mutex_lock(&pHddCtx->tdls_lock);
10744 pTdlsPeer = wlan_hdd_tdls_find_peer(pAdapter, mac, FALSE);
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -070010745 if (pTdlsPeer && TDLS_IS_CONNECTED(pTdlsPeer))
Gopichand Nakkala681989c2013-03-06 22:27:48 -080010746 {
Masti, Narayanraddi6b93b472015-09-04 17:48:11 +053010747 mutex_unlock(&pHddCtx->tdls_lock);
Gopichand Nakkalac87400e2013-03-13 18:51:00 -070010748 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
10749 "%s: " MAC_ADDRESS_STR " already connected. Request declined.",
10750 __func__, MAC_ADDR_ARRAY(mac));
Gopichand Nakkala681989c2013-03-06 22:27:48 -080010751 return -EPERM;
10752 }
Masti, Narayanraddi6b93b472015-09-04 17:48:11 +053010753 mutex_unlock(&pHddCtx->tdls_lock);
Gopichand Nakkala681989c2013-03-06 22:27:48 -080010754 }
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -070010755 if (0 == update)
Atul Mittal115287b2014-07-08 13:26:33 +053010756 wlan_hdd_tdls_set_link_status(pAdapter,
10757 mac,
10758 eTDLS_LINK_CONNECTING,
10759 eTDLS_LINK_SUCCESS);
Gopichand Nakkala681989c2013-03-06 22:27:48 -080010760
Jeff Johnsond75fe012013-04-06 10:53:06 -070010761 /* debug code */
Gopichand Nakkala838be5d2013-04-10 22:41:51 +053010762 if (NULL != StaParams)
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -070010763 {
Masti, Narayanraddi34e0e562015-03-05 18:23:03 +053010764 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -070010765 "%s: TDLS Peer Parameters.", __func__);
Hoonki Lee66b75f32013-04-16 18:30:07 -070010766 if(StaParams->htcap_present)
10767 {
Masti, Narayanraddi34e0e562015-03-05 18:23:03 +053010768 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Hoonki Lee66b75f32013-04-16 18:30:07 -070010769 "ht_capa->cap_info: %0x", StaParams->HTCap.capInfo);
Masti, Narayanraddi34e0e562015-03-05 18:23:03 +053010770 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Hoonki Lee66b75f32013-04-16 18:30:07 -070010771 "ht_capa->extended_capabilities: %0x",
10772 StaParams->HTCap.extendedHtCapInfo);
10773 }
Masti, Narayanraddi34e0e562015-03-05 18:23:03 +053010774 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -070010775 "params->capability: %0x",StaParams->capability);
Masti, Narayanraddi34e0e562015-03-05 18:23:03 +053010776 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Jeff Johnson0299d0a2013-10-30 12:37:43 -070010777 "params->ext_capab_len: %0x",StaParams->extn_capability[0]);
Hoonki Lee66b75f32013-04-16 18:30:07 -070010778 if(StaParams->vhtcap_present)
10779 {
Masti, Narayanraddi34e0e562015-03-05 18:23:03 +053010780 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Hoonki Lee66b75f32013-04-16 18:30:07 -070010781 "rxMcsMap %x rxHighest %x txMcsMap %x txHighest %x",
10782 StaParams->VHTCap.suppMcs.rxMcsMap, StaParams->VHTCap.suppMcs.rxHighest,
10783 StaParams->VHTCap.suppMcs.txMcsMap, StaParams->VHTCap.suppMcs.txHighest);
10784 }
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -070010785 {
10786 int i = 0;
Hoonki Lee5305c3a2013-04-29 23:28:59 -070010787 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO, "Supported rates:");
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -070010788 for (i = 0; i < sizeof(StaParams->supported_rates); i++)
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 "[%d]: %x ", i, StaParams->supported_rates[i]);
10791 }
Jeff Johnsond75fe012013-04-06 10:53:06 -070010792 } /* end debug code */
Gopichand Nakkala838be5d2013-04-10 22:41:51 +053010793 else if ((1 == update) && (NULL == StaParams))
10794 {
10795 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
10796 "%s : update is true, but staParams is NULL. Error!", __func__);
10797 return -EPERM;
10798 }
Gopichand Nakkala681989c2013-03-06 22:27:48 -080010799
10800 INIT_COMPLETION(pAdapter->tdls_add_station_comp);
10801
10802 if (!update)
10803 {
Ganesh Kondabattinif065c1f2015-08-05 23:05:23 +053010804 /*Before adding sta make sure that device exited from BMPS*/
10805 if (TRUE == sme_IsPmcBmps(WLAN_HDD_GET_HAL_CTX(pAdapter)))
10806 {
10807 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
10808 "%s: Adding tdls peer sta. Disable BMPS", __func__);
10809 status = hdd_disable_bmps_imps(pHddCtx, WLAN_HDD_INFRA_STATION);
10810 if (status != VOS_STATUS_SUCCESS) {
10811 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Failed to set BMPS/IMPS"));
10812 }
10813 }
10814
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053010815 ret = sme_AddTdlsPeerSta(WLAN_HDD_GET_HAL_CTX(pAdapter),
Gopichand Nakkala681989c2013-03-06 22:27:48 -080010816 pAdapter->sessionId, mac);
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053010817 if (ret != eHAL_STATUS_SUCCESS) {
Ganesh Kondabattinif065c1f2015-08-05 23:05:23 +053010818 hddLog(VOS_TRACE_LEVEL_ERROR,
10819 FL("Failed to add TDLS peer STA. Enable Bmps"));
10820 wlan_hdd_tdls_check_bmps(pAdapter);
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053010821 return -EPERM;
10822 }
Gopichand Nakkala681989c2013-03-06 22:27:48 -080010823 }
10824 else
10825 {
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053010826 ret = sme_ChangeTdlsPeerSta(WLAN_HDD_GET_HAL_CTX(pAdapter),
Gopichand Nakkala681989c2013-03-06 22:27:48 -080010827 pAdapter->sessionId, mac, StaParams);
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053010828 if (ret != eHAL_STATUS_SUCCESS) {
10829 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Failed to change TDLS peer STA params"));
10830 return -EPERM;
10831 }
Gopichand Nakkala681989c2013-03-06 22:27:48 -080010832 }
10833
c_hpothu6ff1c3c2013-10-01 19:01:57 +053010834 ret = wait_for_completion_interruptible_timeout(&pAdapter->tdls_add_station_comp,
Gopichand Nakkala681989c2013-03-06 22:27:48 -080010835 msecs_to_jiffies(WAIT_TIME_TDLS_ADD_STA));
10836
c_hpothu6ff1c3c2013-10-01 19:01:57 +053010837 if (ret <= 0)
Gopichand Nakkala681989c2013-03-06 22:27:48 -080010838 {
Gopichand Nakkalac87400e2013-03-13 18:51:00 -070010839 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
c_hpothu6ff1c3c2013-10-01 19:01:57 +053010840 "%s: timeout waiting for tdls add station indication %ld",
10841 __func__, ret);
Gopichand Nakkala34d1b062013-03-19 15:28:33 -070010842 return -EPERM;
Gopichand Nakkala681989c2013-03-06 22:27:48 -080010843 }
c_hpothu6ff1c3c2013-10-01 19:01:57 +053010844
Gopichand Nakkala681989c2013-03-06 22:27:48 -080010845 if ( eHAL_STATUS_SUCCESS != pAdapter->tdlsAddStaStatus)
10846 {
Gopichand Nakkalac87400e2013-03-13 18:51:00 -070010847 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Gopichand Nakkala681989c2013-03-06 22:27:48 -080010848 "%s: Add Station is unsucessful", __func__);
Gopichand Nakkala34d1b062013-03-19 15:28:33 -070010849 return -EPERM;
Gopichand Nakkala681989c2013-03-06 22:27:48 -080010850 }
10851
10852 return 0;
Gopichand Nakkala05922802013-03-14 12:23:19 -070010853
10854error:
Atul Mittal115287b2014-07-08 13:26:33 +053010855 wlan_hdd_tdls_set_link_status(pAdapter,
10856 mac,
10857 eTDLS_LINK_IDLE,
10858 eTDLS_LINK_UNSPECIFIED);
Gopichand Nakkala05922802013-03-14 12:23:19 -070010859 return -EPERM;
10860
Gopichand Nakkala681989c2013-03-06 22:27:48 -080010861}
10862#endif
10863
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053010864static int __wlan_hdd_change_station(struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -070010865 struct net_device *dev,
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053010866#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,18,0))
10867 const u8 *mac,
10868#else
Jeff Johnson295189b2012-06-20 16:38:30 -070010869 u8 *mac,
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053010870#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070010871 struct station_parameters *params)
10872{
10873 VOS_STATUS status = VOS_STATUS_SUCCESS;
Mahesh A Saptasagar74088392015-02-05 17:22:09 +053010874 hdd_adapter_t *pAdapter;
Gopichand Nakkala29149562013-05-10 21:43:41 +053010875 hdd_context_t *pHddCtx;
10876 hdd_station_ctx_t *pHddStaCtx;
Jeff Johnson295189b2012-06-20 16:38:30 -070010877 v_MACADDR_t STAMacAddress;
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +053010878 int ret = 0;
Gopichand Nakkalab0856222013-03-12 22:39:05 -070010879#ifdef FEATURE_WLAN_TDLS
Gopichand Nakkala681989c2013-03-06 22:27:48 -080010880 tCsrStaParams StaParams = {0};
Gopichand Nakkala681989c2013-03-06 22:27:48 -080010881 tANI_U8 isBufSta = 0;
Naresh Jayaram3180aa42014-02-12 21:47:26 +053010882 tANI_U8 isOffChannelSupported = 0;
Gopichand Nakkalab0856222013-03-12 22:39:05 -070010883#endif
Jeff Johnsone7245742012-09-05 17:12:55 -070010884
Mahesh A Saptasagar74088392015-02-05 17:22:09 +053010885 ENTER();
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053010886
Mahesh A Saptasagar74088392015-02-05 17:22:09 +053010887 pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
Gopichand Nakkala29149562013-05-10 21:43:41 +053010888 if ((NULL == pAdapter))
10889 {
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053010890 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
Gopichand Nakkala29149562013-05-10 21:43:41 +053010891 "invalid adapter ");
10892 return -EINVAL;
10893 }
10894
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053010895 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
10896 TRACE_CODE_HDD_CHANGE_STATION,
10897 pAdapter->sessionId, params->listen_interval));
Gopichand Nakkala29149562013-05-10 21:43:41 +053010898 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Gopichand Nakkala29149562013-05-10 21:43:41 +053010899
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +053010900 ret = wlan_hdd_validate_context(pHddCtx);
10901 if (0 != ret)
Gopichand Nakkala29149562013-05-10 21:43:41 +053010902 {
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +053010903 return ret;
Gopichand Nakkala29149562013-05-10 21:43:41 +053010904 }
10905
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +053010906 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
10907
10908 if (NULL == pHddStaCtx)
Jeff Johnson04dd8a82012-06-29 20:41:40 -070010909 {
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +053010910 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
10911 "invalid HDD station context");
10912 return -EINVAL;
Jeff Johnson04dd8a82012-06-29 20:41:40 -070010913 }
Jeff Johnson295189b2012-06-20 16:38:30 -070010914 vos_mem_copy(STAMacAddress.bytes, mac, sizeof(v_MACADDR_t));
10915
Gopichand Nakkala681989c2013-03-06 22:27:48 -080010916 if ((pAdapter->device_mode == WLAN_HDD_SOFTAP)
10917 || (pAdapter->device_mode == WLAN_HDD_P2P_GO))
Jeff Johnson295189b2012-06-20 16:38:30 -070010918 {
Gopichand Nakkala681989c2013-03-06 22:27:48 -080010919 if (params->sta_flags_set & BIT(NL80211_STA_FLAG_AUTHORIZED))
Jeff Johnson295189b2012-06-20 16:38:30 -070010920 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010921 status = hdd_softap_change_STA_state( pAdapter, &STAMacAddress,
Jeff Johnson295189b2012-06-20 16:38:30 -070010922 WLANTL_STA_AUTHENTICATED);
10923
Gopichand Nakkala29149562013-05-10 21:43:41 +053010924 if (status != VOS_STATUS_SUCCESS)
10925 {
10926 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
10927 "%s: Not able to change TL state to AUTHENTICATED", __func__);
10928 return -EINVAL;
10929 }
Jeff Johnson295189b2012-06-20 16:38:30 -070010930 }
10931 }
Hoonki Leea6d49be2013-04-05 09:43:25 -070010932 else if ((pAdapter->device_mode == WLAN_HDD_INFRA_STATION)
10933 || (pAdapter->device_mode == WLAN_HDD_P2P_CLIENT)) {
Gopichand Nakkala29149562013-05-10 21:43:41 +053010934#ifdef FEATURE_WLAN_TDLS
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -070010935 if (params->sta_flags_set & BIT(NL80211_STA_FLAG_TDLS_PEER)) {
10936 StaParams.capability = params->capability;
10937 StaParams.uapsd_queues = params->uapsd_queues;
10938 StaParams.max_sp = params->max_sp;
10939
Naresh Jayaram3180aa42014-02-12 21:47:26 +053010940 /* Convert (first channel , number of channels) tuple to
10941 * the total list of channels. This goes with the assumption
10942 * that if the first channel is < 14, then the next channels
10943 * are an incremental of 1 else an incremental of 4 till the number
10944 * of channels.
10945 */
10946 if (0 != params->supported_channels_len) {
10947 int i = 0,j = 0,k = 0, no_of_channels = 0 ;
10948 for ( i = 0 ; i < params->supported_channels_len ; i+=2)
10949 {
10950 int wifi_chan_index;
10951 StaParams.supported_channels[j] = params->supported_channels[i];
10952 wifi_chan_index =
10953 ((StaParams.supported_channels[j] <= HDD_CHANNEL_14 ) ? 1 : 4 );
10954 no_of_channels = params->supported_channels[i+1];
10955 for(k=1; k <= no_of_channels; k++)
10956 {
10957 StaParams.supported_channels[j+1] =
10958 StaParams.supported_channels[j] + wifi_chan_index;
10959 j+=1;
10960 }
10961 }
10962 StaParams.supported_channels_len = j;
10963 }
10964 vos_mem_copy(StaParams.supported_oper_classes,
10965 params->supported_oper_classes,
10966 params->supported_oper_classes_len);
10967 StaParams.supported_oper_classes_len =
10968 params->supported_oper_classes_len;
10969
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -070010970 if (0 != params->ext_capab_len)
10971 vos_mem_copy(StaParams.extn_capability, params->ext_capab,
10972 sizeof(StaParams.extn_capability));
10973
10974 if (NULL != params->ht_capa)
Hoonki Lee66b75f32013-04-16 18:30:07 -070010975 {
10976 StaParams.htcap_present = 1;
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -070010977 vos_mem_copy(&StaParams.HTCap, params->ht_capa, sizeof(tSirHTCap));
Hoonki Lee66b75f32013-04-16 18:30:07 -070010978 }
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -070010979
10980 StaParams.supported_rates_len = params->supported_rates_len;
10981
10982 /* Note : The Maximum sizeof supported_rates sent by the Supplicant is 32.
10983 * The supported_rates array , for all the structures propogating till Add Sta
10984 * to the firmware has to be modified , if the supplicant (ieee80211) is
10985 * modified to send more rates.
10986 */
10987
10988 /* To avoid Data Currption , set to max length to SIR_MAC_MAX_SUPP_RATES
10989 */
10990 if (StaParams.supported_rates_len > SIR_MAC_MAX_SUPP_RATES)
10991 StaParams.supported_rates_len = SIR_MAC_MAX_SUPP_RATES;
10992
10993 if (0 != StaParams.supported_rates_len) {
10994 int i = 0;
10995 vos_mem_copy(StaParams.supported_rates, params->supported_rates,
10996 StaParams.supported_rates_len);
Hoonki Lee5305c3a2013-04-29 23:28:59 -070010997 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -070010998 "Supported Rates with Length %d", StaParams.supported_rates_len);
10999 for (i=0; i < StaParams.supported_rates_len; i++)
Hoonki Lee5305c3a2013-04-29 23:28:59 -070011000 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -070011001 "[%d]: %0x", i, StaParams.supported_rates[i]);
11002 }
11003
11004 if (NULL != params->vht_capa)
Hoonki Lee66b75f32013-04-16 18:30:07 -070011005 {
11006 StaParams.vhtcap_present = 1;
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -070011007 vos_mem_copy(&StaParams.VHTCap, params->vht_capa, sizeof(tSirVHTCap));
Hoonki Lee66b75f32013-04-16 18:30:07 -070011008 }
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -070011009
Gopichand Nakkala681989c2013-03-06 22:27:48 -080011010 if (0 != params->ext_capab_len ) {
11011 /*Define A Macro : TODO Sunil*/
11012 if ((1<<4) & StaParams.extn_capability[3]) {
11013 isBufSta = 1;
11014 }
Naresh Jayaram3180aa42014-02-12 21:47:26 +053011015 /* TDLS Channel Switching Support */
11016 if ((1<<6) & StaParams.extn_capability[3]) {
11017 isOffChannelSupported = 1;
11018 }
Gopichand Nakkala681989c2013-03-06 22:27:48 -080011019 }
Naresh Jayaram3180aa42014-02-12 21:47:26 +053011020 status = wlan_hdd_tdls_set_peer_caps( pAdapter, mac,
11021 &StaParams, isBufSta,
11022 isOffChannelSupported);
11023
Gopichand Nakkala79ff85d2013-05-27 17:05:29 +053011024 if (VOS_STATUS_SUCCESS != status) {
11025 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
11026 "%s: wlan_hdd_tdls_set_peer_caps failed!", __func__);
11027 return -EINVAL;
11028 }
Gopichand Nakkala681989c2013-03-06 22:27:48 -080011029 status = wlan_hdd_tdls_add_station(wiphy, dev, mac, 1, &StaParams);
11030
11031 if (VOS_STATUS_SUCCESS != status) {
11032 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
11033 "%s: sme_ChangeTdlsPeerSta failed!", __func__);
11034 return -EINVAL;
11035 }
11036 }
Gopichand Nakkalab0856222013-03-12 22:39:05 -070011037#endif
Gopichand Nakkala6239acd2013-06-14 14:48:00 +053011038 }
Jeff Johnsone7245742012-09-05 17:12:55 -070011039 EXIT();
Jeff Johnson295189b2012-06-20 16:38:30 -070011040 return status;
11041}
11042
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053011043#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,16,0))
11044static int wlan_hdd_change_station(struct wiphy *wiphy,
11045 struct net_device *dev,
11046 const u8 *mac,
11047 struct station_parameters *params)
11048#else
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053011049static int wlan_hdd_change_station(struct wiphy *wiphy,
11050 struct net_device *dev,
11051 u8 *mac,
11052 struct station_parameters *params)
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053011053#endif
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053011054{
11055 int ret;
11056
11057 vos_ssr_protect(__func__);
11058 ret = __wlan_hdd_change_station(wiphy, dev, mac, params);
11059 vos_ssr_unprotect(__func__);
11060
11061 return ret;
11062}
11063
Jeff Johnson295189b2012-06-20 16:38:30 -070011064/*
Mahesh A Saptasagar1a51bc02014-06-02 18:28:08 +053011065 * FUNCTION: __wlan_hdd_cfg80211_add_key
Jeff Johnson295189b2012-06-20 16:38:30 -070011066 * This function is used to initialize the key information
11067 */
11068#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
Mahesh A Saptasagar1a51bc02014-06-02 18:28:08 +053011069static int __wlan_hdd_cfg80211_add_key( struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -070011070 struct net_device *ndev,
11071 u8 key_index, bool pairwise,
11072 const u8 *mac_addr,
11073 struct key_params *params
11074 )
11075#else
Mahesh A Saptasagar1a51bc02014-06-02 18:28:08 +053011076static int __wlan_hdd_cfg80211_add_key( struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -070011077 struct net_device *ndev,
11078 u8 key_index, const u8 *mac_addr,
11079 struct key_params *params
11080 )
11081#endif
11082{
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -070011083 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( ndev );
Jeff Johnson295189b2012-06-20 16:38:30 -070011084 tCsrRoamSetKey setKey;
11085 u8 groupmacaddr[WNI_CFG_BSSID_LEN] = {0xFF,0xFF,0xFF,0xFF,0xFF,0xFF};
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053011086 int status;
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -070011087 v_U32_t roamId= 0xFF;
11088 v_CONTEXT_t pVosContext = (WLAN_HDD_GET_CTX(pAdapter))->pvosContext;
Jeff Johnson295189b2012-06-20 16:38:30 -070011089 hdd_hostapd_state_t *pHostapdState;
11090 VOS_STATUS vos_status;
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070011091 eHalStatus halStatus;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053011092 hdd_context_t *pHddCtx;
Jeff Johnson295189b2012-06-20 16:38:30 -070011093
11094 ENTER();
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053011095
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053011096 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
11097 TRACE_CODE_HDD_CFG80211_ADD_KEY,
11098 pAdapter->sessionId, params->key_len));
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053011099 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
11100 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053011101 if (0 != status)
Jeff Johnson04dd8a82012-06-29 20:41:40 -070011102 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053011103 return status;
Jeff Johnson04dd8a82012-06-29 20:41:40 -070011104 }
11105
Sushant Kaushik8bc7df22014-04-09 17:55:29 +053011106 hddLog(VOS_TRACE_LEVEL_INFO, "%s: device_mode = %s (%d)",
11107 __func__, hdd_device_modetoString(pAdapter->device_mode),
11108 pAdapter->device_mode);
Jeff Johnson295189b2012-06-20 16:38:30 -070011109
11110 if (CSR_MAX_NUM_KEY <= key_index)
11111 {
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -070011112 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Invalid key index %d", __func__,
Jeff Johnson295189b2012-06-20 16:38:30 -070011113 key_index);
11114
11115 return -EINVAL;
11116 }
11117
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -070011118 if (CSR_MAX_KEY_LEN < params->key_len)
11119 {
11120 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Invalid key length %d", __func__,
11121 params->key_len);
11122
11123 return -EINVAL;
11124 }
11125
11126 hddLog(VOS_TRACE_LEVEL_INFO,
11127 "%s: called with key index = %d & key length %d",
11128 __func__, key_index, params->key_len);
Jeff Johnson295189b2012-06-20 16:38:30 -070011129
11130 /*extract key idx, key len and key*/
11131 vos_mem_zero(&setKey,sizeof(tCsrRoamSetKey));
11132 setKey.keyId = key_index;
11133 setKey.keyLength = params->key_len;
11134 vos_mem_copy(&setKey.Key[0],params->key, params->key_len);
11135
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -070011136 switch (params->cipher)
Jeff Johnson295189b2012-06-20 16:38:30 -070011137 {
11138 case WLAN_CIPHER_SUITE_WEP40:
11139 setKey.encType = eCSR_ENCRYPT_TYPE_WEP40_STATICKEY;
11140 break;
11141
11142 case WLAN_CIPHER_SUITE_WEP104:
11143 setKey.encType = eCSR_ENCRYPT_TYPE_WEP104_STATICKEY;
11144 break;
11145
11146 case WLAN_CIPHER_SUITE_TKIP:
11147 {
11148 u8 *pKey = &setKey.Key[0];
11149 setKey.encType = eCSR_ENCRYPT_TYPE_TKIP;
11150
11151 vos_mem_zero(pKey, CSR_MAX_KEY_LEN);
11152
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -070011153 /*Supplicant sends the 32bytes key in this order
Jeff Johnson295189b2012-06-20 16:38:30 -070011154
11155 |--------------|----------|----------|
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -070011156 | Tk1 |TX-MIC | RX Mic |
Jeff Johnson295189b2012-06-20 16:38:30 -070011157 |--------------|----------|----------|
11158 <---16bytes---><--8bytes--><--8bytes-->
11159
11160 */
11161 /*Sme expects the 32 bytes key to be in the below order
11162
11163 |--------------|----------|----------|
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -070011164 | Tk1 |RX-MIC | TX Mic |
Jeff Johnson295189b2012-06-20 16:38:30 -070011165 |--------------|----------|----------|
11166 <---16bytes---><--8bytes--><--8bytes-->
11167 */
11168 /* Copy the Temporal Key 1 (TK1) */
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -070011169 vos_mem_copy(pKey, params->key, 16);
Jeff Johnson295189b2012-06-20 16:38:30 -070011170
11171 /*Copy the rx mic first*/
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -070011172 vos_mem_copy(&pKey[16], &params->key[24], 8);
Jeff Johnson295189b2012-06-20 16:38:30 -070011173
11174 /*Copy the tx mic */
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -070011175 vos_mem_copy(&pKey[24], &params->key[16], 8);
Jeff Johnson295189b2012-06-20 16:38:30 -070011176
11177
11178 break;
11179 }
11180
11181 case WLAN_CIPHER_SUITE_CCMP:
11182 setKey.encType = eCSR_ENCRYPT_TYPE_AES;
11183 break;
11184
11185#ifdef FEATURE_WLAN_WAPI
11186 case WLAN_CIPHER_SUITE_SMS4:
11187 {
11188 vos_mem_zero(&setKey,sizeof(tCsrRoamSetKey));
11189 wlan_hdd_cfg80211_set_key_wapi(pAdapter, key_index, mac_addr,
11190 params->key, params->key_len);
11191 return 0;
11192 }
11193#endif
Chet Lanctot186b5732013-03-18 10:26:30 -070011194
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -080011195#ifdef FEATURE_WLAN_ESE
Jeff Johnson295189b2012-06-20 16:38:30 -070011196 case WLAN_CIPHER_SUITE_KRK:
11197 setKey.encType = eCSR_ENCRYPT_TYPE_KRK;
11198 break;
11199#endif
Chet Lanctot186b5732013-03-18 10:26:30 -070011200
11201#ifdef WLAN_FEATURE_11W
11202 case WLAN_CIPHER_SUITE_AES_CMAC:
11203 setKey.encType = eCSR_ENCRYPT_TYPE_AES_CMAC;
Chet Lanctot3b5158a2013-03-31 16:45:21 -070011204 break;
Chet Lanctot186b5732013-03-18 10:26:30 -070011205#endif
11206
Jeff Johnson295189b2012-06-20 16:38:30 -070011207 default:
Jeff Johnson0299d0a2013-10-30 12:37:43 -070011208 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: unsupported cipher type %u",
Jeff Johnson295189b2012-06-20 16:38:30 -070011209 __func__, params->cipher);
Vinay Krishna Eranna6f22c1f2014-10-13 16:03:06 +053011210 status = -EOPNOTSUPP;
11211 goto end;
Jeff Johnson295189b2012-06-20 16:38:30 -070011212 }
11213
11214 hddLog(VOS_TRACE_LEVEL_INFO_MED, "%s: encryption type %d",
11215 __func__, setKey.encType);
11216
Shailender Karmuchi642e9812013-05-30 14:34:49 -070011217 if (
Jeff Johnson295189b2012-06-20 16:38:30 -070011218#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
11219 (!pairwise)
11220#else
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -070011221 (!mac_addr || is_broadcast_ether_addr(mac_addr))
Jeff Johnson295189b2012-06-20 16:38:30 -070011222#endif
Shailender Karmuchi642e9812013-05-30 14:34:49 -070011223 )
11224 {
11225 /* set group key*/
11226 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
11227 "%s- %d: setting Broadcast key",
11228 __func__, __LINE__);
11229 setKey.keyDirection = eSIR_RX_ONLY;
11230 vos_mem_copy(setKey.peerMac,groupmacaddr,WNI_CFG_BSSID_LEN);
11231 }
11232 else
11233 {
11234 /* set pairwise key*/
11235 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
11236 "%s- %d: setting pairwise key",
11237 __func__, __LINE__);
11238 setKey.keyDirection = eSIR_TX_RX;
11239 vos_mem_copy(setKey.peerMac, mac_addr,WNI_CFG_BSSID_LEN);
11240 }
11241 if ((WLAN_HDD_IBSS == pAdapter->device_mode) && !pairwise)
11242 {
11243 setKey.keyDirection = eSIR_TX_RX;
11244 /*Set the group key*/
11245 status = sme_RoamSetKey( WLAN_HDD_GET_HAL_CTX(pAdapter),
11246 pAdapter->sessionId, &setKey, &roamId );
Jeff Johnson295189b2012-06-20 16:38:30 -070011247
Shailender Karmuchi642e9812013-05-30 14:34:49 -070011248 if ( 0 != status )
11249 {
11250 hddLog(VOS_TRACE_LEVEL_ERROR,
11251 "%s: sme_RoamSetKey failed, returned %d", __func__, status);
Vinay Krishna Eranna6f22c1f2014-10-13 16:03:06 +053011252 status = -EINVAL;
11253 goto end;
Shailender Karmuchi642e9812013-05-30 14:34:49 -070011254 }
11255 /*Save the keys here and call sme_RoamSetKey for setting
11256 the PTK after peer joins the IBSS network*/
11257 vos_mem_copy(&pAdapter->sessionCtx.station.ibss_enc_key,
11258 &setKey, sizeof(tCsrRoamSetKey));
Vinay Krishna Eranna6f22c1f2014-10-13 16:03:06 +053011259 goto end;
Shailender Karmuchi642e9812013-05-30 14:34:49 -070011260 }
Gopichand Nakkala29149562013-05-10 21:43:41 +053011261 if ((pAdapter->device_mode == WLAN_HDD_SOFTAP) ||
11262 (pAdapter->device_mode == WLAN_HDD_P2P_GO))
11263 {
Jeff Johnson295189b2012-06-20 16:38:30 -070011264 pHostapdState = WLAN_HDD_GET_HOSTAP_STATE_PTR(pAdapter);
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -070011265 if( pHostapdState->bssState == BSS_START )
11266 {
Nirav Shah4b53d4b2015-05-08 05:35:00 -070011267 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
11268 vos_status = wlan_hdd_check_ula_done(pAdapter);
11269
11270 if ( vos_status != VOS_STATUS_SUCCESS )
11271 {
11272 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
11273 "[%4d] wlan_hdd_check_ula_done returned ERROR status= %d",
11274 __LINE__, vos_status );
11275
11276 pHddStaCtx->roam_info.roamingState = HDD_ROAM_STATE_NONE;
11277
11278 status = -EINVAL;
11279 goto end;
11280 }
11281
Jeff Johnson295189b2012-06-20 16:38:30 -070011282 status = WLANSAP_SetKeySta( pVosContext, &setKey);
11283
11284 if ( status != eHAL_STATUS_SUCCESS )
11285 {
11286 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
11287 "[%4d] WLANSAP_SetKeySta returned ERROR status= %d",
11288 __LINE__, status );
Vinay Krishna Eranna6f22c1f2014-10-13 16:03:06 +053011289 status = -EINVAL;
11290 goto end;
Jeff Johnson295189b2012-06-20 16:38:30 -070011291 }
11292 }
11293
11294 /* Saving WEP keys */
11295 else if( eCSR_ENCRYPT_TYPE_WEP40_STATICKEY == setKey.encType ||
11296 eCSR_ENCRYPT_TYPE_WEP104_STATICKEY == setKey.encType )
11297 {
11298 //Save the wep key in ap context. Issue setkey after the BSS is started.
11299 hdd_ap_ctx_t *pAPCtx = WLAN_HDD_GET_AP_CTX_PTR(pAdapter);
11300 vos_mem_copy(&pAPCtx->wepKey[key_index], &setKey, sizeof(tCsrRoamSetKey));
11301 }
11302 else
11303 {
11304 //Save the key in ap context. Issue setkey after the BSS is started.
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -070011305 hdd_ap_ctx_t *pAPCtx = WLAN_HDD_GET_AP_CTX_PTR(pAdapter);
Jeff Johnson295189b2012-06-20 16:38:30 -070011306 vos_mem_copy(&pAPCtx->groupKey, &setKey, sizeof(tCsrRoamSetKey));
11307 }
11308 }
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -070011309 else if ( (pAdapter->device_mode == WLAN_HDD_INFRA_STATION) ||
11310 (pAdapter->device_mode == WLAN_HDD_P2P_CLIENT) )
Jeff Johnson295189b2012-06-20 16:38:30 -070011311 {
11312 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
11313 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
11314
Gopichand Nakkala3d295922013-05-07 16:19:14 +053011315#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
11316 if (!pairwise)
11317#else
11318 if (!mac_addr || is_broadcast_ether_addr(mac_addr))
11319#endif
11320 {
11321 /* set group key*/
11322 if (pHddStaCtx->roam_info.deferKeyComplete)
11323 {
11324 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
11325 "%s- %d: Perform Set key Complete",
11326 __func__, __LINE__);
11327 hdd_PerformRoamSetKeyComplete(pAdapter);
11328 }
11329 }
11330
Jeff Johnson295189b2012-06-20 16:38:30 -070011331 pWextState->roamProfile.Keys.KeyLength[key_index] = (u8)params->key_len;
11332
Venkata Prathyusha Kuntupalliee2ce712013-01-17 14:09:24 -080011333 pWextState->roamProfile.Keys.defaultIndex = key_index;
11334
11335
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -070011336 vos_mem_copy(&pWextState->roamProfile.Keys.KeyMaterial[key_index][0],
Jeff Johnson295189b2012-06-20 16:38:30 -070011337 params->key, params->key_len);
11338
Gopichand Nakkala3d295922013-05-07 16:19:14 +053011339
Jeff Johnson295189b2012-06-20 16:38:30 -070011340 pHddStaCtx->roam_info.roamingState = HDD_ROAM_STATE_SETTING_KEY;
11341
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011342 hddLog(VOS_TRACE_LEVEL_INFO_MED,
Jeff Johnson295189b2012-06-20 16:38:30 -070011343 "%s: set key for peerMac %2x:%2x:%2x:%2x:%2x:%2x, direction %d",
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011344 __func__, setKey.peerMac[0], setKey.peerMac[1],
11345 setKey.peerMac[2], setKey.peerMac[3],
11346 setKey.peerMac[4], setKey.peerMac[5],
Jeff Johnson295189b2012-06-20 16:38:30 -070011347 setKey.keyDirection);
11348
Nirav Shah4b53d4b2015-05-08 05:35:00 -070011349 vos_status = wlan_hdd_check_ula_done(pAdapter);
Nirav Shah4f765af2015-01-21 19:51:30 +053011350
Nirav Shah4b53d4b2015-05-08 05:35:00 -070011351 if ( vos_status != VOS_STATUS_SUCCESS )
11352 {
11353 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Jeff Johnson295189b2012-06-20 16:38:30 -070011354 "[%4d] wlan_hdd_check_ula_done returned ERROR status= %d",
11355 __LINE__, vos_status );
11356
Nirav Shah4b53d4b2015-05-08 05:35:00 -070011357 pHddStaCtx->roam_info.roamingState = HDD_ROAM_STATE_NONE;
Jeff Johnson295189b2012-06-20 16:38:30 -070011358
Nirav Shah4b53d4b2015-05-08 05:35:00 -070011359 status = -EINVAL;
11360 goto end;
Jeff Johnson295189b2012-06-20 16:38:30 -070011361
11362 }
11363
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070011364#ifdef WLAN_FEATURE_VOWIFI_11R
Gopichand Nakkala3d295922013-05-07 16:19:14 +053011365 /* The supplicant may attempt to set the PTK once pre-authentication
11366 is done. Save the key in the UMAC and include it in the ADD BSS
11367 request */
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070011368 halStatus = sme_FTUpdateKey( WLAN_HDD_GET_HAL_CTX(pAdapter), &setKey);
Gopichand Nakkala3d295922013-05-07 16:19:14 +053011369 if ( halStatus == eHAL_STATUS_FT_PREAUTH_KEY_SUCCESS )
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070011370 {
Gopichand Nakkala3d295922013-05-07 16:19:14 +053011371 hddLog(VOS_TRACE_LEVEL_INFO_MED,
11372 "%s: Update PreAuth Key success", __func__);
Vinay Krishna Eranna6f22c1f2014-10-13 16:03:06 +053011373 status = 0;
11374 goto end;
Gopichand Nakkala3d295922013-05-07 16:19:14 +053011375 }
11376 else if ( halStatus == eHAL_STATUS_FT_PREAUTH_KEY_FAILED )
11377 {
11378 hddLog(VOS_TRACE_LEVEL_ERROR,
11379 "%s: Update PreAuth Key failed", __func__);
Vinay Krishna Eranna6f22c1f2014-10-13 16:03:06 +053011380 status = -EINVAL;
11381 goto end;
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070011382 }
11383#endif /* WLAN_FEATURE_VOWIFI_11R */
Jeff Johnson295189b2012-06-20 16:38:30 -070011384
11385 /* issue set key request to SME*/
11386 status = sme_RoamSetKey( WLAN_HDD_GET_HAL_CTX(pAdapter),
11387 pAdapter->sessionId, &setKey, &roamId );
11388
11389 if ( 0 != status )
11390 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011391 hddLog(VOS_TRACE_LEVEL_ERROR,
Jeff Johnson295189b2012-06-20 16:38:30 -070011392 "%s: sme_RoamSetKey failed, returned %d", __func__, status);
11393 pHddStaCtx->roam_info.roamingState = HDD_ROAM_STATE_NONE;
Vinay Krishna Eranna6f22c1f2014-10-13 16:03:06 +053011394 status = -EINVAL;
11395 goto end;
Jeff Johnson295189b2012-06-20 16:38:30 -070011396 }
11397
11398
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011399 /* in case of IBSS as there was no information available about WEP keys during
11400 * IBSS join, group key intialized with NULL key, so re-initialize group key
Jeff Johnson295189b2012-06-20 16:38:30 -070011401 * with correct value*/
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011402 if ( (eCSR_BSS_TYPE_START_IBSS == pWextState->roamProfile.BSSType) &&
11403 !( ( IW_AUTH_KEY_MGMT_802_1X
11404 == (pWextState->authKeyMgmt & IW_AUTH_KEY_MGMT_802_1X))
Jeff Johnson295189b2012-06-20 16:38:30 -070011405 && (eCSR_AUTH_TYPE_OPEN_SYSTEM == pHddStaCtx->conn_info.authType)
11406 )
11407 &&
11408 ( (WLAN_CIPHER_SUITE_WEP40 == params->cipher)
11409 || (WLAN_CIPHER_SUITE_WEP104 == params->cipher)
11410 )
11411 )
11412 {
11413 setKey.keyDirection = eSIR_RX_ONLY;
11414 vos_mem_copy(setKey.peerMac,groupmacaddr,WNI_CFG_BSSID_LEN);
11415
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011416 hddLog(VOS_TRACE_LEVEL_INFO_MED,
Jeff Johnson295189b2012-06-20 16:38:30 -070011417 "%s: set key peerMac %2x:%2x:%2x:%2x:%2x:%2x, direction %d",
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011418 __func__, setKey.peerMac[0], setKey.peerMac[1],
11419 setKey.peerMac[2], setKey.peerMac[3],
11420 setKey.peerMac[4], setKey.peerMac[5],
Jeff Johnson295189b2012-06-20 16:38:30 -070011421 setKey.keyDirection);
11422
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011423 status = sme_RoamSetKey( WLAN_HDD_GET_HAL_CTX(pAdapter),
Jeff Johnson295189b2012-06-20 16:38:30 -070011424 pAdapter->sessionId, &setKey, &roamId );
11425
11426 if ( 0 != status )
11427 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011428 hddLog(VOS_TRACE_LEVEL_ERROR,
11429 "%s: sme_RoamSetKey failed for group key (IBSS), returned %d",
Jeff Johnson295189b2012-06-20 16:38:30 -070011430 __func__, status);
11431 pHddStaCtx->roam_info.roamingState = HDD_ROAM_STATE_NONE;
Vinay Krishna Eranna6f22c1f2014-10-13 16:03:06 +053011432 status = -EINVAL;
11433 goto end;
Jeff Johnson295189b2012-06-20 16:38:30 -070011434 }
11435 }
11436 }
11437
Vinay Krishna Eranna6f22c1f2014-10-13 16:03:06 +053011438end:
11439 /* Need to clear any trace of key value in the memory.
11440 * Thus zero out the memory even though it is local
11441 * variable.
11442 */
11443 vos_mem_zero(&setKey, sizeof(setKey));
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053011444 EXIT();
Vinay Krishna Eranna6f22c1f2014-10-13 16:03:06 +053011445 return status;
Jeff Johnson295189b2012-06-20 16:38:30 -070011446}
11447
Mahesh A Saptasagar1a51bc02014-06-02 18:28:08 +053011448#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
11449static int wlan_hdd_cfg80211_add_key( struct wiphy *wiphy,
11450 struct net_device *ndev,
11451 u8 key_index, bool pairwise,
11452 const u8 *mac_addr,
11453 struct key_params *params
11454 )
11455#else
11456static int wlan_hdd_cfg80211_add_key( struct wiphy *wiphy,
11457 struct net_device *ndev,
11458 u8 key_index, const u8 *mac_addr,
11459 struct key_params *params
11460 )
11461#endif
11462{
11463 int ret;
11464 vos_ssr_protect(__func__);
11465#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
11466 ret = __wlan_hdd_cfg80211_add_key(wiphy, ndev, key_index, pairwise,
11467 mac_addr, params);
11468#else
11469 ret = __wlan_hdd_cfg80211_add_key(wiphy, ndev, key_index, mac_addr,
11470 params);
11471#endif
11472 vos_ssr_unprotect(__func__);
11473
11474 return ret;
11475}
11476
Jeff Johnson295189b2012-06-20 16:38:30 -070011477/*
Mahesh A Saptasagar1a51bc02014-06-02 18:28:08 +053011478 * FUNCTION: __wlan_hdd_cfg80211_get_key
Jeff Johnson295189b2012-06-20 16:38:30 -070011479 * This function is used to get the key information
11480 */
11481#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
Mahesh A Saptasagar1a51bc02014-06-02 18:28:08 +053011482static int __wlan_hdd_cfg80211_get_key(
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011483 struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -070011484 struct net_device *ndev,
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011485 u8 key_index, bool pairwise,
Jeff Johnson295189b2012-06-20 16:38:30 -070011486 const u8 *mac_addr, void *cookie,
11487 void (*callback)(void *cookie, struct key_params*)
11488 )
11489#else
Mahesh A Saptasagar1a51bc02014-06-02 18:28:08 +053011490static int __wlan_hdd_cfg80211_get_key(
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011491 struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -070011492 struct net_device *ndev,
11493 u8 key_index, const u8 *mac_addr, void *cookie,
11494 void (*callback)(void *cookie, struct key_params*)
11495 )
11496#endif
11497{
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011498 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( ndev );
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +053011499 hdd_wext_state_t *pWextState = NULL;
11500 tCsrRoamProfile *pRoamProfile = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -070011501 struct key_params params;
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +053011502 hdd_context_t *pHddCtx;
11503 int ret = 0;
Jeff Johnson295189b2012-06-20 16:38:30 -070011504
11505 ENTER();
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011506
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +053011507 if (NULL == pAdapter)
11508 {
11509 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
11510 "%s: HDD adapter is Null", __func__);
11511 return -ENODEV;
11512 }
11513
11514 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
11515 ret = wlan_hdd_validate_context(pHddCtx);
11516 if (0 != ret)
11517 {
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +053011518 return ret;
11519 }
11520
11521 pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
11522 pRoamProfile = &(pWextState->roamProfile);
11523
Sushant Kaushik8bc7df22014-04-09 17:55:29 +053011524 hddLog(VOS_TRACE_LEVEL_INFO, "%s: device_mode = %s (%d)",
11525 __func__, hdd_device_modetoString(pAdapter->device_mode),
11526 pAdapter->device_mode);
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053011527
Jeff Johnson295189b2012-06-20 16:38:30 -070011528 memset(&params, 0, sizeof(params));
11529
11530 if (CSR_MAX_NUM_KEY <= key_index)
11531 {
c_hpothu6ff1c3c2013-10-01 19:01:57 +053011532 hddLog(VOS_TRACE_LEVEL_ERROR, FL("invalid key index %d"), key_index);
Jeff Johnson295189b2012-06-20 16:38:30 -070011533 return -EINVAL;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011534 }
Jeff Johnson295189b2012-06-20 16:38:30 -070011535
11536 switch(pRoamProfile->EncryptionType.encryptionType[0])
11537 {
11538 case eCSR_ENCRYPT_TYPE_NONE:
11539 params.cipher = IW_AUTH_CIPHER_NONE;
11540 break;
11541
11542 case eCSR_ENCRYPT_TYPE_WEP40_STATICKEY:
11543 case eCSR_ENCRYPT_TYPE_WEP40:
11544 params.cipher = WLAN_CIPHER_SUITE_WEP40;
11545 break;
11546
11547 case eCSR_ENCRYPT_TYPE_WEP104_STATICKEY:
11548 case eCSR_ENCRYPT_TYPE_WEP104:
11549 params.cipher = WLAN_CIPHER_SUITE_WEP104;
11550 break;
11551
11552 case eCSR_ENCRYPT_TYPE_TKIP:
11553 params.cipher = WLAN_CIPHER_SUITE_TKIP;
11554 break;
11555
11556 case eCSR_ENCRYPT_TYPE_AES:
11557 params.cipher = WLAN_CIPHER_SUITE_AES_CMAC;
11558 break;
11559
11560 default:
11561 params.cipher = IW_AUTH_CIPHER_NONE;
11562 break;
11563 }
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053011564
c_hpothuaaf19692014-05-17 17:01:48 +053011565 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
11566 TRACE_CODE_HDD_CFG80211_GET_KEY,
11567 pAdapter->sessionId, params.cipher));
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053011568
Jeff Johnson295189b2012-06-20 16:38:30 -070011569 params.key_len = pRoamProfile->Keys.KeyLength[key_index];
11570 params.seq_len = 0;
11571 params.seq = NULL;
11572 params.key = &pRoamProfile->Keys.KeyMaterial[key_index][0];
11573 callback(cookie, &params);
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053011574 EXIT();
Jeff Johnson295189b2012-06-20 16:38:30 -070011575 return 0;
11576}
11577
Mahesh A Saptasagar1a51bc02014-06-02 18:28:08 +053011578#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
11579static int wlan_hdd_cfg80211_get_key(
11580 struct wiphy *wiphy,
11581 struct net_device *ndev,
11582 u8 key_index, bool pairwise,
11583 const u8 *mac_addr, void *cookie,
11584 void (*callback)(void *cookie, struct key_params*)
11585 )
11586#else
11587static int wlan_hdd_cfg80211_get_key(
11588 struct wiphy *wiphy,
11589 struct net_device *ndev,
11590 u8 key_index, const u8 *mac_addr, void *cookie,
11591 void (*callback)(void *cookie, struct key_params*)
11592 )
11593#endif
11594{
11595 int ret;
11596
11597 vos_ssr_protect(__func__);
11598#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
11599 ret = __wlan_hdd_cfg80211_get_key(wiphy, ndev, key_index, pairwise,
11600 mac_addr, cookie, callback);
11601#else
11602 ret = __wlan_hdd_cfg80211_get_key(wiphy, ndev, key_index, mac_addr,
11603 callback);
11604#endif
11605 vos_ssr_unprotect(__func__);
11606
11607 return ret;
11608}
11609
Jeff Johnson295189b2012-06-20 16:38:30 -070011610/*
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053011611 * FUNCTION: __wlan_hdd_cfg80211_del_key
Jeff Johnson295189b2012-06-20 16:38:30 -070011612 * This function is used to delete the key information
11613 */
11614#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053011615static int __wlan_hdd_cfg80211_del_key( struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -070011616 struct net_device *ndev,
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011617 u8 key_index,
11618 bool pairwise,
Jeff Johnson295189b2012-06-20 16:38:30 -070011619 const u8 *mac_addr
11620 )
11621#else
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053011622static int __wlan_hdd_cfg80211_del_key( struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -070011623 struct net_device *ndev,
11624 u8 key_index,
11625 const u8 *mac_addr
11626 )
11627#endif
11628{
11629 int status = 0;
11630
11631 //This code needs to be revisited. There is sme_removeKey API, we should
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011632 //plan to use that. After the change to use correct index in setkey,
Jeff Johnson295189b2012-06-20 16:38:30 -070011633 //it is observed that this is invalidating peer
11634 //key index whenever re-key is done. This is affecting data link.
11635 //It should be ok to ignore del_key.
11636#if 0
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011637 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( ndev );
11638 v_CONTEXT_t pVosContext = (WLAN_HDD_GET_CTX(pAdapter))->pvosContext;
Jeff Johnson295189b2012-06-20 16:38:30 -070011639 u8 groupmacaddr[WNI_CFG_BSSID_LEN] = {0xFF,0xFF,0xFF,0xFF,0xFF,0xFF};
11640 tCsrRoamSetKey setKey;
11641 v_U32_t roamId= 0xFF;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011642
Jeff Johnson295189b2012-06-20 16:38:30 -070011643 ENTER();
11644
11645 hddLog(VOS_TRACE_LEVEL_INFO_HIGH, "%s: device_mode = %d\n",
11646 __func__,pAdapter->device_mode);
11647
11648 if (CSR_MAX_NUM_KEY <= key_index)
11649 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011650 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Invalid key index %d", __func__,
Jeff Johnson295189b2012-06-20 16:38:30 -070011651 key_index);
11652
11653 return -EINVAL;
11654 }
11655
11656 vos_mem_zero(&setKey,sizeof(tCsrRoamSetKey));
11657 setKey.keyId = key_index;
11658
11659 if (mac_addr)
11660 vos_mem_copy(setKey.peerMac, mac_addr,WNI_CFG_BSSID_LEN);
11661 else
11662 vos_mem_copy(setKey.peerMac, groupmacaddr, WNI_CFG_BSSID_LEN);
11663
11664 setKey.encType = eCSR_ENCRYPT_TYPE_NONE;
11665
11666 if ((pAdapter->device_mode == WLAN_HDD_SOFTAP)
Jeff Johnson295189b2012-06-20 16:38:30 -070011667 || (pAdapter->device_mode == WLAN_HDD_P2P_GO)
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011668 )
11669 {
11670
11671 hdd_hostapd_state_t *pHostapdState =
Jeff Johnson295189b2012-06-20 16:38:30 -070011672 WLAN_HDD_GET_HOSTAP_STATE_PTR(pAdapter);
11673 if( pHostapdState->bssState == BSS_START)
11674 {
11675 status = WLANSAP_SetKeySta( pVosContext, &setKey);
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011676
Jeff Johnson295189b2012-06-20 16:38:30 -070011677 if ( status != eHAL_STATUS_SUCCESS )
11678 {
11679 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
11680 "[%4d] WLANSAP_SetKeySta returned ERROR status= %d",
11681 __LINE__, status );
11682 }
11683 }
11684 }
11685 else if ( (pAdapter->device_mode == WLAN_HDD_INFRA_STATION)
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011686 || (pAdapter->device_mode == WLAN_HDD_P2P_CLIENT)
Jeff Johnson295189b2012-06-20 16:38:30 -070011687 )
11688 {
11689 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
11690
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011691 pHddStaCtx->roam_info.roamingState = HDD_ROAM_STATE_SETTING_KEY;
11692
11693 hddLog(VOS_TRACE_LEVEL_INFO_MED,
Jeff Johnson295189b2012-06-20 16:38:30 -070011694 "%s: delete key for peerMac %2x:%2x:%2x:%2x:%2x:%2x",
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011695 __func__, setKey.peerMac[0], setKey.peerMac[1],
11696 setKey.peerMac[2], setKey.peerMac[3],
Jeff Johnson295189b2012-06-20 16:38:30 -070011697 setKey.peerMac[4], setKey.peerMac[5]);
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011698 if(pAdapter->sessionCtx.station.conn_info.connState ==
11699 eConnectionState_Associated)
Jeff Johnson295189b2012-06-20 16:38:30 -070011700 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011701 status = sme_RoamSetKey( WLAN_HDD_GET_HAL_CTX(pAdapter),
Jeff Johnson295189b2012-06-20 16:38:30 -070011702 pAdapter->sessionId, &setKey, &roamId );
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011703
Jeff Johnson295189b2012-06-20 16:38:30 -070011704 if ( 0 != status )
11705 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011706 hddLog(VOS_TRACE_LEVEL_ERROR,
Jeff Johnson295189b2012-06-20 16:38:30 -070011707 "%s: sme_RoamSetKey failure, returned %d",
11708 __func__, status);
11709 pHddStaCtx->roam_info.roamingState = HDD_ROAM_STATE_NONE;
11710 return -EINVAL;
11711 }
11712 }
11713 }
11714#endif
Jeff Johnsone7245742012-09-05 17:12:55 -070011715 EXIT();
Jeff Johnson295189b2012-06-20 16:38:30 -070011716 return status;
11717}
11718
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053011719#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
11720static int wlan_hdd_cfg80211_del_key( struct wiphy *wiphy,
11721 struct net_device *ndev,
11722 u8 key_index,
11723 bool pairwise,
11724 const u8 *mac_addr
11725 )
11726#else
11727static int wlan_hdd_cfg80211_del_key( struct wiphy *wiphy,
11728 struct net_device *ndev,
11729 u8 key_index,
11730 const u8 *mac_addr
11731 )
11732#endif
11733{
11734 int ret;
11735
11736 vos_ssr_protect(__func__);
11737#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
11738 ret = __wlan_hdd_cfg80211_del_key(wiphy, ndev, key_index, pairwise,
11739 mac_addr);
11740#else
11741 ret = __wlan_hdd_cfg80211_del_key(wiphy, ndev, key_index, mac_addr);
11742#endif
11743 vos_ssr_unprotect(__func__);
11744
11745 return ret;
11746}
11747
Jeff Johnson295189b2012-06-20 16:38:30 -070011748/*
Mahesh A Saptasagar1a51bc02014-06-02 18:28:08 +053011749 * FUNCTION: __wlan_hdd_cfg80211_set_default_key
Jeff Johnson295189b2012-06-20 16:38:30 -070011750 * This function is used to set the default tx key index
11751 */
11752#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
Mahesh A Saptasagar1a51bc02014-06-02 18:28:08 +053011753static int __wlan_hdd_cfg80211_set_default_key( struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -070011754 struct net_device *ndev,
11755 u8 key_index,
11756 bool unicast, bool multicast)
11757#else
Mahesh A Saptasagar1a51bc02014-06-02 18:28:08 +053011758static int __wlan_hdd_cfg80211_set_default_key( struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -070011759 struct net_device *ndev,
11760 u8 key_index)
11761#endif
11762{
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011763 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( ndev );
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053011764 int status;
Gopichand Nakkala29149562013-05-10 21:43:41 +053011765 hdd_wext_state_t *pWextState;
11766 hdd_station_ctx_t *pHddStaCtx;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053011767 hdd_context_t *pHddCtx;
Jeff Johnson295189b2012-06-20 16:38:30 -070011768
11769 ENTER();
11770
Gopichand Nakkala29149562013-05-10 21:43:41 +053011771 if ((NULL == pAdapter))
11772 {
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053011773 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
Gopichand Nakkala29149562013-05-10 21:43:41 +053011774 "invalid adapter");
11775 return -EINVAL;
11776 }
11777
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053011778 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
11779 TRACE_CODE_HDD_CFG80211_SET_DEFAULT_KEY,
11780 pAdapter->sessionId, key_index));
11781
Gopichand Nakkala29149562013-05-10 21:43:41 +053011782 pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
11783 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
11784
11785 if ((NULL == pWextState) || (NULL == pHddStaCtx))
11786 {
11787 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
11788 "invalid Wext state or HDD context");
11789 return -EINVAL;
11790 }
11791
Arif Hussain6d2a3322013-11-17 19:50:10 -080011792 hddLog(VOS_TRACE_LEVEL_INFO, "%s: device_mode = %d key_index = %d",
Jeff Johnson295189b2012-06-20 16:38:30 -070011793 __func__,pAdapter->device_mode, key_index);
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011794
Jeff Johnson295189b2012-06-20 16:38:30 -070011795 if (CSR_MAX_NUM_KEY <= key_index)
11796 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011797 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Invalid key index %d", __func__,
Jeff Johnson295189b2012-06-20 16:38:30 -070011798 key_index);
11799
11800 return -EINVAL;
11801 }
11802
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053011803 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
11804 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053011805 if (0 != status)
Jeff Johnson04dd8a82012-06-29 20:41:40 -070011806 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053011807 return status;
Jeff Johnson04dd8a82012-06-29 20:41:40 -070011808 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011809
Jeff Johnson295189b2012-06-20 16:38:30 -070011810 if ((pAdapter->device_mode == WLAN_HDD_INFRA_STATION)
Jeff Johnson295189b2012-06-20 16:38:30 -070011811 || (pAdapter->device_mode == WLAN_HDD_P2P_CLIENT)
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011812 )
Jeff Johnson295189b2012-06-20 16:38:30 -070011813 {
Gopichand Nakkala29149562013-05-10 21:43:41 +053011814 if ( (eCSR_ENCRYPT_TYPE_TKIP !=
Arif Hussain6943f522013-11-04 20:10:10 -080011815 pHddStaCtx->conn_info.ucEncryptionType) &&
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011816 (eCSR_ENCRYPT_TYPE_AES !=
Arif Hussain6943f522013-11-04 20:10:10 -080011817 pHddStaCtx->conn_info.ucEncryptionType)
Jeff Johnson295189b2012-06-20 16:38:30 -070011818 )
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011819 {
11820 /* if default key index is not same as previous one,
Jeff Johnson295189b2012-06-20 16:38:30 -070011821 * then update the default key index */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011822
Jeff Johnson295189b2012-06-20 16:38:30 -070011823 tCsrRoamSetKey setKey;
11824 v_U32_t roamId= 0xFF;
11825 tCsrKeys *Keys = &pWextState->roamProfile.Keys;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011826
11827 hddLog(VOS_TRACE_LEVEL_INFO_HIGH, "%s: default tx key index %d",
Jeff Johnson295189b2012-06-20 16:38:30 -070011828 __func__, key_index);
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011829
Jeff Johnson295189b2012-06-20 16:38:30 -070011830 Keys->defaultIndex = (u8)key_index;
11831 vos_mem_zero(&setKey,sizeof(tCsrRoamSetKey));
11832 setKey.keyId = key_index;
11833 setKey.keyLength = Keys->KeyLength[key_index];
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011834
11835 vos_mem_copy(&setKey.Key[0],
11836 &Keys->KeyMaterial[key_index][0],
Jeff Johnson295189b2012-06-20 16:38:30 -070011837 Keys->KeyLength[key_index]);
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011838
Gopichand Nakkala29149562013-05-10 21:43:41 +053011839 setKey.keyDirection = eSIR_TX_RX;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011840
11841 vos_mem_copy(setKey.peerMac,
Jeff Johnson295189b2012-06-20 16:38:30 -070011842 &pHddStaCtx->conn_info.bssId[0],
11843 WNI_CFG_BSSID_LEN);
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011844
Gopichand Nakkala29149562013-05-10 21:43:41 +053011845 if (Keys->KeyLength[key_index] == CSR_WEP40_KEY_LEN &&
11846 pWextState->roamProfile.EncryptionType.encryptionType[0] ==
11847 eCSR_ENCRYPT_TYPE_WEP104)
11848 {
11849 /*In the case of dynamic wep supplicant hardcodes DWEP type to eCSR_ENCRYPT_TYPE_WEP104
11850 even though ap is configured for WEP-40 encryption. In this canse the key length
11851 is 5 but the encryption type is 104 hence checking the key langht(5) and encryption
11852 type(104) and switching encryption type to 40*/
11853 pWextState->roamProfile.EncryptionType.encryptionType[0] =
11854 eCSR_ENCRYPT_TYPE_WEP40;
11855 pWextState->roamProfile.mcEncryptionType.encryptionType[0] =
11856 eCSR_ENCRYPT_TYPE_WEP40;
11857 }
11858
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011859 setKey.encType =
Jeff Johnson295189b2012-06-20 16:38:30 -070011860 pWextState->roamProfile.EncryptionType.encryptionType[0];
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011861
Jeff Johnson295189b2012-06-20 16:38:30 -070011862 /* issue set key request */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011863 status = sme_RoamSetKey( WLAN_HDD_GET_HAL_CTX(pAdapter),
Jeff Johnson295189b2012-06-20 16:38:30 -070011864 pAdapter->sessionId, &setKey, &roamId );
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011865
Jeff Johnson295189b2012-06-20 16:38:30 -070011866 if ( 0 != status )
11867 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011868 hddLog(VOS_TRACE_LEVEL_ERROR,
11869 "%s: sme_RoamSetKey failed, returned %d", __func__,
Jeff Johnson295189b2012-06-20 16:38:30 -070011870 status);
11871 return -EINVAL;
11872 }
11873 }
11874 }
11875
11876 /* In SoftAp mode setting key direction for default mode */
11877 else if ( WLAN_HDD_SOFTAP == pAdapter->device_mode )
11878 {
11879 if ( (eCSR_ENCRYPT_TYPE_TKIP !=
11880 pWextState->roamProfile.EncryptionType.encryptionType[0]) &&
11881 (eCSR_ENCRYPT_TYPE_AES !=
11882 pWextState->roamProfile.EncryptionType.encryptionType[0])
11883 )
11884 {
11885 /* Saving key direction for default key index to TX default */
11886 hdd_ap_ctx_t *pAPCtx = WLAN_HDD_GET_AP_CTX_PTR(pAdapter);
11887 pAPCtx->wepKey[key_index].keyDirection = eSIR_TX_DEFAULT;
11888 }
11889 }
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053011890 EXIT();
Jeff Johnson295189b2012-06-20 16:38:30 -070011891 return status;
11892}
11893
Mahesh A Saptasagar1a51bc02014-06-02 18:28:08 +053011894#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
11895static int wlan_hdd_cfg80211_set_default_key( struct wiphy *wiphy,
11896 struct net_device *ndev,
11897 u8 key_index,
11898 bool unicast, bool multicast)
11899#else
11900static int wlan_hdd_cfg80211_set_default_key( struct wiphy *wiphy,
11901 struct net_device *ndev,
11902 u8 key_index)
11903#endif
11904{
11905 int ret;
11906 vos_ssr_protect(__func__);
11907#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
11908 ret = __wlan_hdd_cfg80211_set_default_key(wiphy, ndev, key_index, unicast,
11909 multicast);
11910#else
11911 ret = __wlan_hdd_cfg80211_set_default_key(wiphy, ndev, key_index);
11912#endif
11913 vos_ssr_unprotect(__func__);
11914
11915 return ret;
11916}
11917
Jeff Johnson295189b2012-06-20 16:38:30 -070011918/*
11919 * FUNCTION: wlan_hdd_cfg80211_inform_bss
11920 * This function is used to inform the BSS details to nl80211 interface.
11921 */
11922static struct cfg80211_bss* wlan_hdd_cfg80211_inform_bss(
11923 hdd_adapter_t *pAdapter, tCsrRoamConnectedProfile *roamProfile)
11924{
11925 struct net_device *dev = pAdapter->dev;
11926 struct wireless_dev *wdev = dev->ieee80211_ptr;
11927 struct wiphy *wiphy = wdev->wiphy;
11928 tSirBssDescription *pBssDesc = roamProfile->pBssDesc;
11929 int chan_no;
11930 int ie_length;
11931 const char *ie;
11932 unsigned int freq;
11933 struct ieee80211_channel *chan;
11934 int rssi = 0;
11935 struct cfg80211_bss *bss = NULL;
11936
Jeff Johnson295189b2012-06-20 16:38:30 -070011937 if( NULL == pBssDesc )
11938 {
Arif Hussain6d2a3322013-11-17 19:50:10 -080011939 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: pBssDesc is NULL", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -070011940 return bss;
11941 }
11942
11943 chan_no = pBssDesc->channelId;
11944 ie_length = GET_IE_LEN_IN_BSS_DESC( pBssDesc->length );
11945 ie = ((ie_length != 0) ? (const char *)&pBssDesc->ieFields: NULL);
11946
11947 if( NULL == ie )
11948 {
Arif Hussain6d2a3322013-11-17 19:50:10 -080011949 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: IE of BSS descriptor is NULL", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -070011950 return bss;
11951 }
11952
11953#if (LINUX_VERSION_CODE > KERNEL_VERSION(2,6,38))
11954 if (chan_no <= ARRAY_SIZE(hdd_channels_2_4_GHZ))
11955 {
11956 freq = ieee80211_channel_to_frequency(chan_no, IEEE80211_BAND_2GHZ);
11957 }
11958 else
11959 {
11960 freq = ieee80211_channel_to_frequency(chan_no, IEEE80211_BAND_5GHZ);
11961 }
11962#else
11963 freq = ieee80211_channel_to_frequency(chan_no);
11964#endif
11965
11966 chan = __ieee80211_get_channel(wiphy, freq);
11967
Santhosh Kumar Padmaa45fdb12014-04-15 15:54:38 +053011968 if (!chan) {
11969 hddLog(VOS_TRACE_LEVEL_ERROR, "%s chan pointer is NULL", __func__);
11970 return NULL;
11971 }
11972
Abhishek Singhaee43942014-06-16 18:55:47 +053011973 rssi = (VOS_MIN ((pBssDesc->rssi + pBssDesc->sinr), 0))*100;
Jeff Johnson295189b2012-06-20 16:38:30 -070011974
Anand N Sunkad9f80b742015-07-30 20:05:51 +053011975 return cfg80211_inform_bss(wiphy, chan,
11976#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,18,0))
11977 CFG80211_BSS_FTYPE_UNKNOWN,
11978#endif
11979 pBssDesc->bssId,
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011980 le64_to_cpu(*(__le64 *)pBssDesc->timeStamp),
Jeff Johnson295189b2012-06-20 16:38:30 -070011981 pBssDesc->capabilityInfo,
11982 pBssDesc->beaconInterval, ie, ie_length,
Abhishek Singhaee43942014-06-16 18:55:47 +053011983 rssi, GFP_KERNEL );
Jeff Johnson295189b2012-06-20 16:38:30 -070011984}
11985
11986
11987
11988/*
11989 * FUNCTION: wlan_hdd_cfg80211_inform_bss_frame
11990 * This function is used to inform the BSS details to nl80211 interface.
11991 */
11992struct cfg80211_bss*
11993wlan_hdd_cfg80211_inform_bss_frame( hdd_adapter_t *pAdapter,
11994 tSirBssDescription *bss_desc
11995 )
11996{
11997 /*
11998 cfg80211_inform_bss() is not updating ie field of bss entry, if entry
11999 already exists in bss data base of cfg80211 for that particular BSS ID.
12000 Using cfg80211_inform_bss_frame to update the bss entry instead of
12001 cfg80211_inform_bss, But this call expects mgmt packet as input. As of
12002 now there is no possibility to get the mgmt(probe response) frame from PE,
12003 converting bss_desc to ieee80211_mgmt(probe response) and passing to
12004 cfg80211_inform_bss_frame.
12005 */
12006 struct net_device *dev = pAdapter->dev;
12007 struct wireless_dev *wdev = dev->ieee80211_ptr;
12008 struct wiphy *wiphy = wdev->wiphy;
12009 int chan_no = bss_desc->channelId;
Madan Mohan Koyyalamudi86f629e2012-11-09 16:27:29 -080012010#ifdef WLAN_ENABLE_AGEIE_ON_SCAN_RESULTS
12011 qcom_ie_age *qie_age = NULL;
12012 int ie_length = GET_IE_LEN_IN_BSS_DESC( bss_desc->length ) + sizeof(qcom_ie_age);
12013#else
Jeff Johnson295189b2012-06-20 16:38:30 -070012014 int ie_length = GET_IE_LEN_IN_BSS_DESC( bss_desc->length );
Madan Mohan Koyyalamudi86f629e2012-11-09 16:27:29 -080012015#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070012016 const char *ie =
12017 ((ie_length != 0) ? (const char *)&bss_desc->ieFields: NULL);
12018 unsigned int freq;
12019 struct ieee80211_channel *chan;
Abhishek Singh1e2bfa32014-01-02 15:44:15 +053012020 struct ieee80211_mgmt *mgmt = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -070012021 struct cfg80211_bss *bss_status = NULL;
12022 size_t frame_len = sizeof (struct ieee80211_mgmt) + ie_length;
12023 int rssi = 0;
Wilson Yangf80a0542013-10-07 13:02:37 -070012024 hdd_context_t *pHddCtx;
12025 int status;
Jeff Johnsone7245742012-09-05 17:12:55 -070012026#ifdef WLAN_OPEN_SOURCE
12027 struct timespec ts;
12028#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070012029
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053012030
Wilson Yangf80a0542013-10-07 13:02:37 -070012031 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
12032 status = wlan_hdd_validate_context(pHddCtx);
Wilson Yangf80a0542013-10-07 13:02:37 -070012033 if (0 != status)
12034 {
Madan Mohan Koyyalamudi2e5c9142012-11-02 13:17:48 -070012035 return NULL;
Wilson Yangf80a0542013-10-07 13:02:37 -070012036 }
12037
Abhishek Singh1e2bfa32014-01-02 15:44:15 +053012038 mgmt = kzalloc((sizeof (struct ieee80211_mgmt) + ie_length), GFP_KERNEL);
Wilson Yangf80a0542013-10-07 13:02:37 -070012039 if (!mgmt)
12040 {
12041 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
12042 "%s: memory allocation failed ", __func__);
12043 return NULL;
12044 }
Madan Mohan Koyyalamudi2e5c9142012-11-02 13:17:48 -070012045
Jeff Johnson295189b2012-06-20 16:38:30 -070012046 memcpy(mgmt->bssid, bss_desc->bssId, ETH_ALEN);
Jeff Johnsone7245742012-09-05 17:12:55 -070012047
12048#ifdef WLAN_OPEN_SOURCE
12049 /* Android does not want the timestamp from the frame.
12050 Instead it wants a monotonic increasing value */
12051 get_monotonic_boottime(&ts);
12052 mgmt->u.probe_resp.timestamp =
12053 ((u64)ts.tv_sec * 1000000) + (ts.tv_nsec / 1000);
12054#else
12055 /* keep old behavior for non-open source (for now) */
Jeff Johnson295189b2012-06-20 16:38:30 -070012056 memcpy(&mgmt->u.probe_resp.timestamp, bss_desc->timeStamp,
12057 sizeof (bss_desc->timeStamp));
Jeff Johnsone7245742012-09-05 17:12:55 -070012058
12059#endif
12060
Jeff Johnson295189b2012-06-20 16:38:30 -070012061 mgmt->u.probe_resp.beacon_int = bss_desc->beaconInterval;
12062 mgmt->u.probe_resp.capab_info = bss_desc->capabilityInfo;
Madan Mohan Koyyalamudi86f629e2012-11-09 16:27:29 -080012063
12064#ifdef WLAN_ENABLE_AGEIE_ON_SCAN_RESULTS
12065 /* GPS Requirement: need age ie per entry. Using vendor specific. */
12066 /* Assuming this is the last IE, copy at the end */
12067 ie_length -=sizeof(qcom_ie_age);
12068 qie_age = (qcom_ie_age *)(mgmt->u.probe_resp.variable + ie_length);
12069 qie_age->element_id = QCOM_VENDOR_IE_ID;
12070 qie_age->len = QCOM_VENDOR_IE_AGE_LEN;
12071 qie_age->oui_1 = QCOM_OUI1;
12072 qie_age->oui_2 = QCOM_OUI2;
12073 qie_age->oui_3 = QCOM_OUI3;
12074 qie_age->type = QCOM_VENDOR_IE_AGE_TYPE;
12075 qie_age->age = vos_timer_get_system_ticks() - bss_desc->nReceivedTime;
12076#endif
12077
Jeff Johnson295189b2012-06-20 16:38:30 -070012078 memcpy(mgmt->u.probe_resp.variable, ie, ie_length);
Gopichand Nakkalad908ec82013-05-16 19:32:19 +053012079 if (bss_desc->fProbeRsp)
12080 {
12081 mgmt->frame_control |=
12082 (u16)(IEEE80211_FTYPE_MGMT | IEEE80211_STYPE_PROBE_RESP);
12083 }
12084 else
12085 {
12086 mgmt->frame_control |=
12087 (u16)(IEEE80211_FTYPE_MGMT | IEEE80211_STYPE_BEACON);
12088 }
Jeff Johnson295189b2012-06-20 16:38:30 -070012089
12090#if (LINUX_VERSION_CODE > KERNEL_VERSION(2,6,38))
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012091 if (chan_no <= ARRAY_SIZE(hdd_channels_2_4_GHZ) &&
Jeff Johnson295189b2012-06-20 16:38:30 -070012092 (wiphy->bands[IEEE80211_BAND_2GHZ] != NULL))
12093 {
12094 freq = ieee80211_channel_to_frequency(chan_no, IEEE80211_BAND_2GHZ);
12095 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012096 else if ((chan_no > ARRAY_SIZE(hdd_channels_2_4_GHZ)) &&
Jeff Johnson295189b2012-06-20 16:38:30 -070012097 (wiphy->bands[IEEE80211_BAND_5GHZ] != NULL))
12098
12099 {
12100 freq = ieee80211_channel_to_frequency(chan_no, IEEE80211_BAND_5GHZ);
12101 }
12102 else
12103 {
Nirav Shah20ac06f2013-12-12 18:14:06 +053012104 hddLog(VOS_TRACE_LEVEL_ERROR, "%s Invalid chan_no:%d",
12105 __func__, chan_no);
Jeff Johnson295189b2012-06-20 16:38:30 -070012106 kfree(mgmt);
12107 return NULL;
12108 }
12109#else
12110 freq = ieee80211_channel_to_frequency(chan_no);
12111#endif
12112 chan = __ieee80211_get_channel(wiphy, freq);
Leela V Kiran Kumar Reddy90032de2013-01-24 18:33:30 -080012113 /*when the band is changed on the fly using the GUI, three things are done
12114 * 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)
12115 * as part of the scan abort, message willbe queued to PE and we proceed with flushing and changinh the band.
12116 * pe will stop the scanning further and report back the results what ever it had till now by calling the call back function.
12117 * if the time between update band and scandone call back is sufficent enough the band change reflects in SME, SME validates the channels
12118 * and discards the channels correponding to previous band and calls back with zero bss results.
12119 * 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
12120 * all the channels correponding to previous band.this is due to race condition.but those channels are invalid to the new band and so
12121 * this function __ieee80211_get_channel will return NULL.Each time we report scan result with this pointer null warning kernel trace is printed.
12122 * if the scan results contain large number of APs continuosly kernel warning trace is printed and it will lead to apps watch dog bark.
12123 * So drop the bss and continue to next bss.
12124 */
12125 if(chan == NULL)
12126 {
Nirav Shah20ac06f2013-12-12 18:14:06 +053012127 hddLog(VOS_TRACE_LEVEL_ERROR, "%s chan pointer is NULL", __func__);
Chilam Ngc4244af2013-04-01 15:37:32 -070012128 kfree(mgmt);
Leela V Kiran Kumar Reddy90032de2013-01-24 18:33:30 -080012129 return NULL;
12130 }
Hanumantha Reddy Pothula904bcef2015-06-19 11:56:29 +053012131 /*To keep the rssi icon of the connected AP in the scan window
12132 *and the rssi icon of the wireless networks in sync
12133 * */
12134 if (( eConnectionState_Associated ==
12135 pAdapter->sessionCtx.station.conn_info.connState ) &&
12136 ( VOS_TRUE == vos_mem_compare(bss_desc->bssId,
12137 pAdapter->sessionCtx.station.conn_info.bssId,
12138 WNI_CFG_BSSID_LEN)) &&
12139 (pHddCtx->hdd_wlan_suspended == FALSE))
12140 {
12141 /* supplicant takes the signal strength in terms of mBm(100*dBm) */
12142 rssi = (pAdapter->rssi * 100);
12143 }
12144 else
12145 {
12146 rssi = (VOS_MIN ((bss_desc->rssi + bss_desc->sinr), 0))*100;
12147 }
Jeff Johnson295189b2012-06-20 16:38:30 -070012148
Nirav Shah20ac06f2013-12-12 18:14:06 +053012149 hddLog(VOS_TRACE_LEVEL_INFO, "%s: BSSID:" MAC_ADDRESS_STR " Channel:%d"
Sushant Kaushik0b343422015-05-25 17:15:55 +053012150 " RSSI:%d", __func__, MAC_ADDR_ARRAY(mgmt->bssid),
12151 vos_freq_to_chan(chan->center_freq), (int)(rssi/100));
Nirav Shah20ac06f2013-12-12 18:14:06 +053012152
Jeff Johnson295189b2012-06-20 16:38:30 -070012153 bss_status = cfg80211_inform_bss_frame(wiphy, chan, mgmt,
12154 frame_len, rssi, GFP_KERNEL);
12155 kfree(mgmt);
12156 return bss_status;
12157}
12158
12159/*
12160 * FUNCTION: wlan_hdd_cfg80211_update_bss_db
12161 * This function is used to update the BSS data base of CFG8011
12162 */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012163struct cfg80211_bss* wlan_hdd_cfg80211_update_bss_db( hdd_adapter_t *pAdapter,
Jeff Johnson295189b2012-06-20 16:38:30 -070012164 tCsrRoamInfo *pRoamInfo
12165 )
12166{
12167 tCsrRoamConnectedProfile roamProfile;
12168 tHalHandle hHal = WLAN_HDD_GET_HAL_CTX(pAdapter);
12169 struct cfg80211_bss *bss = NULL;
12170
12171 ENTER();
12172
12173 memset(&roamProfile, 0, sizeof(tCsrRoamConnectedProfile));
12174 sme_RoamGetConnectProfile(hHal, pAdapter->sessionId, &roamProfile);
12175
12176 if (NULL != roamProfile.pBssDesc)
12177 {
Girish Gowlif4b68022014-08-28 23:18:57 +053012178 bss = wlan_hdd_cfg80211_inform_bss_frame(pAdapter,
12179 roamProfile.pBssDesc);
Jeff Johnson295189b2012-06-20 16:38:30 -070012180
12181 if (NULL == bss)
12182 {
12183 hddLog(VOS_TRACE_LEVEL_INFO, "%s: cfg80211_inform_bss return NULL",
12184 __func__);
12185 }
12186
12187 sme_RoamFreeConnectProfile(hHal, &roamProfile);
12188 }
12189 else
12190 {
12191 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: roamProfile.pBssDesc is NULL",
12192 __func__);
12193 }
12194 return bss;
12195}
12196
12197/*
12198 * FUNCTION: wlan_hdd_cfg80211_update_bss
12199 */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012200static int wlan_hdd_cfg80211_update_bss( struct wiphy *wiphy,
12201 hdd_adapter_t *pAdapter
Jeff Johnson295189b2012-06-20 16:38:30 -070012202 )
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012203{
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053012204 tHalHandle hHal = WLAN_HDD_GET_HAL_CTX(pAdapter);
Jeff Johnson295189b2012-06-20 16:38:30 -070012205 tCsrScanResultInfo *pScanResult;
12206 eHalStatus status = 0;
12207 tScanResultHandle pResult;
12208 struct cfg80211_bss *bss_status = NULL;
Wilson Yangf80a0542013-10-07 13:02:37 -070012209 hdd_context_t *pHddCtx;
Deepthi Gowri10d0ae12015-05-25 14:39:50 +053012210 bool is_p2p_scan = false;
Jeff Johnson295189b2012-06-20 16:38:30 -070012211 ENTER();
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053012212
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053012213 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
12214 TRACE_CODE_HDD_CFG80211_UPDATE_BSS,
12215 NO_SESSION, pAdapter->sessionId));
12216
Wilson Yangf80a0542013-10-07 13:02:37 -070012217 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
12218
12219 if (pHddCtx->isLogpInProgress)
Jeff Johnson295189b2012-06-20 16:38:30 -070012220 {
Wilson Yangf80a0542013-10-07 13:02:37 -070012221 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
12222 "%s:LOGP in Progress. Ignore!!!",__func__);
12223 return -EAGAIN;
Jeff Johnson295189b2012-06-20 16:38:30 -070012224 }
12225
Wilson Yangf80a0542013-10-07 13:02:37 -070012226
12227 /*bss_update is not allowed during wlan driver loading or unloading*/
Mihir Shete18156292014-03-11 15:38:30 +053012228 if (WLAN_HDD_IS_LOAD_UNLOAD_IN_PROGRESS(pHddCtx))
Wilson Yangf80a0542013-10-07 13:02:37 -070012229 {
12230 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
12231 "%s:Loading_unloading in Progress. Ignore!!!",__func__);
12232 return VOS_STATUS_E_PERM;
12233 }
12234
Deepthi Gowri10d0ae12015-05-25 14:39:50 +053012235 if (pAdapter->request != NULL)
12236 {
12237 if ((pAdapter->request->n_ssids == 1)
12238 && (pAdapter->request->ssids != NULL)
12239 && vos_mem_compare(&pAdapter->request->ssids[0], "DIRECT-", 7))
12240 is_p2p_scan = true;
12241 }
Jeff Johnson295189b2012-06-20 16:38:30 -070012242 /*
12243 * start getting scan results and populate cgf80211 BSS database
12244 */
12245 status = sme_ScanGetResult(hHal, pAdapter->sessionId, NULL, &pResult);
12246
12247 /* no scan results */
12248 if (NULL == pResult)
12249 {
Nirav Shah20ac06f2013-12-12 18:14:06 +053012250 hddLog(VOS_TRACE_LEVEL_INFO, "%s: No scan result Status %d",
12251 __func__, status);
Mahesh A Saptasagar51dc36c2015-06-16 12:07:15 +053012252 wlan_hdd_get_frame_logs(pAdapter,
12253 WLAN_HDD_GET_FRAME_LOG_CMD_SEND_AND_CLEAR);
Jeff Johnson295189b2012-06-20 16:38:30 -070012254 return status;
12255 }
12256
12257 pScanResult = sme_ScanResultGetFirst(hHal, pResult);
12258
12259 while (pScanResult)
12260 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012261 /*
12262 * cfg80211_inform_bss() is not updating ie field of bss entry, if
12263 * entry already exists in bss data base of cfg80211 for that
12264 * particular BSS ID. Using cfg80211_inform_bss_frame to update the
12265 * bss entry instead of cfg80211_inform_bss, But this call expects
12266 * mgmt packet as input. As of now there is no possibility to get
12267 * the mgmt(probe response) frame from PE, converting bss_desc to
Jeff Johnson295189b2012-06-20 16:38:30 -070012268 * ieee80211_mgmt(probe response) and passing to c
12269 * fg80211_inform_bss_frame.
12270 * */
Deepthi Gowri10d0ae12015-05-25 14:39:50 +053012271 if(is_p2p_scan && (pScanResult->ssId.ssId != NULL) &&
12272 !vos_mem_compare( pScanResult->ssId.ssId, "DIRECT-", 7) )
12273 {
Deepthi Gowri10d0ae12015-05-25 14:39:50 +053012274 pScanResult = sme_ScanResultGetNext(hHal, pResult);
12275 continue; //Skip the non p2p bss entries
12276 }
Jeff Johnson295189b2012-06-20 16:38:30 -070012277 bss_status = wlan_hdd_cfg80211_inform_bss_frame(pAdapter,
12278 &pScanResult->BssDescriptor);
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012279
Jeff Johnson295189b2012-06-20 16:38:30 -070012280
12281 if (NULL == bss_status)
12282 {
12283 hddLog(VOS_TRACE_LEVEL_INFO,
Arif Hussain6d2a3322013-11-17 19:50:10 -080012284 "%s: NULL returned by cfg80211_inform_bss", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -070012285 }
12286 else
12287 {
Yue Maf49ba872013-08-19 12:04:25 -070012288 cfg80211_put_bss(
12289#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,9,0))
12290 wiphy,
12291#endif
12292 bss_status);
Jeff Johnson295189b2012-06-20 16:38:30 -070012293 }
12294
12295 pScanResult = sme_ScanResultGetNext(hHal, pResult);
12296 }
12297
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012298 sme_ScanResultPurge(hHal, pResult);
Deepthi Gowri10d0ae12015-05-25 14:39:50 +053012299 is_p2p_scan = false;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012300 return 0;
Jeff Johnson295189b2012-06-20 16:38:30 -070012301}
12302
Jeff Johnson04dd8a82012-06-29 20:41:40 -070012303void
12304hddPrintMacAddr(tCsrBssid macAddr, tANI_U8 logLevel)
12305{
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012306 VOS_TRACE(VOS_MODULE_ID_HDD, logLevel,
Arif Hussaina7c8e412013-11-20 11:06:42 -080012307 MAC_ADDRESS_STR, MAC_ADDR_ARRAY(macAddr));
Jeff Johnson04dd8a82012-06-29 20:41:40 -070012308} /****** end hddPrintMacAddr() ******/
12309
12310void
Madan Mohan Koyyalamudic75be962012-10-18 19:19:03 -070012311hddPrintPmkId(tANI_U8 *pmkId, tANI_U8 logLevel)
Jeff Johnson04dd8a82012-06-29 20:41:40 -070012312{
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012313 VOS_TRACE(VOS_MODULE_ID_HDD, logLevel,
Arif Hussain6d2a3322013-11-17 19:50:10 -080012314 "%02X:%02X:%02X:%02X:%02X:%02X:%02X:%02X:%02X:%02X:%02X:%02X:%02X:%02X:%02X:%02X",
Madan Mohan Koyyalamudic75be962012-10-18 19:19:03 -070012315 pmkId[0], pmkId[1], pmkId[2], pmkId[3], pmkId[4],
12316 pmkId[5], pmkId[6], pmkId[7], pmkId[8], pmkId[9], pmkId[10],
12317 pmkId[11], pmkId[12], pmkId[13], pmkId[14], pmkId[15]);
Jeff Johnson04dd8a82012-06-29 20:41:40 -070012318} /****** end hddPrintPmkId() ******/
12319
12320//hddPrintMacAddr(tCsrBssid macAddr, tANI_U8 logLevel);
12321//hddPrintMacAddr(macAddr, VOS_TRACE_LEVEL_FATAL);
12322
12323//void sirDumpBuf(tpAniSirGlobal pMac, tANI_U8 modId, tANI_U32 level, tANI_U8 *buf, tANI_U32 size);
12324//sirDumpBuf(pMac, VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL, pmkid, 16);
12325
12326#define dump_bssid(bssid) \
12327 { \
Jeff Johnsone7245742012-09-05 17:12:55 -070012328 hddLog(VOS_TRACE_LEVEL_INFO, "BSSID (MAC) address:\t"); \
12329 hddPrintMacAddr(bssid, VOS_TRACE_LEVEL_INFO);\
Jeff Johnson04dd8a82012-06-29 20:41:40 -070012330 }
12331
12332#define dump_pmkid(pMac, pmkid) \
12333 { \
Jeff Johnsone7245742012-09-05 17:12:55 -070012334 hddLog(VOS_TRACE_LEVEL_INFO, "PMKSA-ID:\t"); \
12335 hddPrintPmkId(pmkid, VOS_TRACE_LEVEL_INFO);\
Jeff Johnson04dd8a82012-06-29 20:41:40 -070012336 }
12337
Madan Mohan Koyyalamudi1b4afb02012-10-22 15:25:16 -070012338#if defined(FEATURE_WLAN_LFR) && (LINUX_VERSION_CODE >= KERNEL_VERSION(3,4,0))
Jeff Johnson04dd8a82012-06-29 20:41:40 -070012339/*
12340 * FUNCTION: wlan_hdd_cfg80211_pmksa_candidate_notify
12341 * This function is used to notify the supplicant of a new PMKSA candidate.
12342 */
12343int wlan_hdd_cfg80211_pmksa_candidate_notify(
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012344 hdd_adapter_t *pAdapter, tCsrRoamInfo *pRoamInfo,
Jeff Johnson04dd8a82012-06-29 20:41:40 -070012345 int index, bool preauth )
12346{
Jeff Johnsone7245742012-09-05 17:12:55 -070012347#ifdef FEATURE_WLAN_OKC
Jeff Johnson04dd8a82012-06-29 20:41:40 -070012348 struct net_device *dev = pAdapter->dev;
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -070012349 hdd_context_t *pHddCtx = (hdd_context_t*)pAdapter->pHddCtx;
Jeff Johnson04dd8a82012-06-29 20:41:40 -070012350
12351 ENTER();
Jeff Johnsone7245742012-09-05 17:12:55 -070012352 hddLog(VOS_TRACE_LEVEL_INFO, "%s is going to notify supplicant of:", __func__);
Jeff Johnson04dd8a82012-06-29 20:41:40 -070012353
12354 if( NULL == pRoamInfo )
12355 {
Arif Hussain6d2a3322013-11-17 19:50:10 -080012356 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: pRoamInfo is NULL", __func__);
Jeff Johnson04dd8a82012-06-29 20:41:40 -070012357 return -EINVAL;
12358 }
12359
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -070012360 if (eANI_BOOLEAN_TRUE == hdd_is_okc_mode_enabled(pHddCtx))
12361 {
12362 dump_bssid(pRoamInfo->bssid);
12363 cfg80211_pmksa_candidate_notify(dev, index,
Jeff Johnson04dd8a82012-06-29 20:41:40 -070012364 pRoamInfo->bssid, preauth, GFP_KERNEL);
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -070012365 }
Jeff Johnsone7245742012-09-05 17:12:55 -070012366#endif /* FEATURE_WLAN_OKC */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012367 return 0;
Jeff Johnson04dd8a82012-06-29 20:41:40 -070012368}
12369#endif //FEATURE_WLAN_LFR
12370
Yue Maef608272013-04-08 23:09:17 -070012371#ifdef FEATURE_WLAN_LFR_METRICS
12372/*
12373 * FUNCTION: wlan_hdd_cfg80211_roam_metrics_preauth
12374 * 802.11r/LFR metrics reporting function to report preauth initiation
12375 *
12376 */
12377#define MAX_LFR_METRICS_EVENT_LENGTH 100
12378VOS_STATUS wlan_hdd_cfg80211_roam_metrics_preauth(hdd_adapter_t *pAdapter,
12379 tCsrRoamInfo *pRoamInfo)
12380{
12381 unsigned char metrics_notification[MAX_LFR_METRICS_EVENT_LENGTH + 1];
12382 union iwreq_data wrqu;
12383
12384 ENTER();
12385
12386 if (NULL == pAdapter)
12387 {
12388 hddLog(LOGE, "%s: pAdapter is NULL!", __func__);
12389 return VOS_STATUS_E_FAILURE;
12390 }
12391
12392 /* create the event */
12393 memset(&wrqu, 0, sizeof(wrqu));
12394 memset(metrics_notification, 0, sizeof(metrics_notification));
12395
12396 wrqu.data.pointer = metrics_notification;
12397 wrqu.data.length = scnprintf(metrics_notification,
12398 sizeof(metrics_notification), "QCOM: LFR_PREAUTH_INIT "
12399 MAC_ADDRESS_STR, MAC_ADDR_ARRAY(pRoamInfo->bssid));
12400
12401 wireless_send_event(pAdapter->dev, IWEVCUSTOM, &wrqu, metrics_notification);
12402
12403 EXIT();
12404
12405 return VOS_STATUS_SUCCESS;
12406}
12407
12408/*
12409 * FUNCTION: wlan_hdd_cfg80211_roam_metrics_preauth_status
12410 * 802.11r/LFR metrics reporting function to report preauth completion
12411 * or failure
12412 */
12413VOS_STATUS wlan_hdd_cfg80211_roam_metrics_preauth_status(
12414 hdd_adapter_t *pAdapter, tCsrRoamInfo *pRoamInfo, bool preauth_status)
12415{
12416 unsigned char metrics_notification[MAX_LFR_METRICS_EVENT_LENGTH + 1];
12417 union iwreq_data wrqu;
12418
12419 ENTER();
12420
12421 if (NULL == pAdapter)
12422 {
12423 hddLog(LOGE, "%s: pAdapter is NULL!", __func__);
12424 return VOS_STATUS_E_FAILURE;
12425 }
12426
12427 /* create the event */
12428 memset(&wrqu, 0, sizeof(wrqu));
12429 memset(metrics_notification, 0, sizeof(metrics_notification));
12430
12431 scnprintf(metrics_notification, sizeof(metrics_notification),
12432 "QCOM: LFR_PREAUTH_STATUS "MAC_ADDRESS_STR,
12433 MAC_ADDR_ARRAY(pRoamInfo->bssid));
12434
12435 if (1 == preauth_status)
12436 strncat(metrics_notification, " TRUE", 5);
12437 else
12438 strncat(metrics_notification, " FALSE", 6);
12439
12440 wrqu.data.pointer = metrics_notification;
12441 wrqu.data.length = strlen(metrics_notification);
12442
12443 wireless_send_event(pAdapter->dev, IWEVCUSTOM, &wrqu, metrics_notification);
12444
12445 EXIT();
12446
12447 return VOS_STATUS_SUCCESS;
12448}
12449
12450/*
12451 * FUNCTION: wlan_hdd_cfg80211_roam_metrics_handover
12452 * 802.11r/LFR metrics reporting function to report handover initiation
12453 *
12454 */
12455VOS_STATUS wlan_hdd_cfg80211_roam_metrics_handover(hdd_adapter_t * pAdapter,
12456 tCsrRoamInfo *pRoamInfo)
12457{
12458 unsigned char metrics_notification[MAX_LFR_METRICS_EVENT_LENGTH + 1];
12459 union iwreq_data wrqu;
12460
12461 ENTER();
12462
12463 if (NULL == pAdapter)
12464 {
12465 hddLog(LOGE, "%s: pAdapter is NULL!", __func__);
12466 return VOS_STATUS_E_FAILURE;
12467 }
12468
12469 /* create the event */
12470 memset(&wrqu, 0, sizeof(wrqu));
12471 memset(metrics_notification, 0, sizeof(metrics_notification));
12472
12473 wrqu.data.pointer = metrics_notification;
12474 wrqu.data.length = scnprintf(metrics_notification,
12475 sizeof(metrics_notification), "QCOM: LFR_PREAUTH_HANDOVER "
12476 MAC_ADDRESS_STR, MAC_ADDR_ARRAY(pRoamInfo->bssid));
12477
12478 wireless_send_event(pAdapter->dev, IWEVCUSTOM, &wrqu, metrics_notification);
12479
12480 EXIT();
12481
12482 return VOS_STATUS_SUCCESS;
12483}
12484#endif
12485
Jeff Johnson295189b2012-06-20 16:38:30 -070012486/*
12487 * FUNCTION: hdd_cfg80211_scan_done_callback
12488 * scanning callback function, called after finishing scan
12489 *
12490 */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012491static eHalStatus hdd_cfg80211_scan_done_callback(tHalHandle halHandle,
Jeff Johnson295189b2012-06-20 16:38:30 -070012492 void *pContext, tANI_U32 scanId, eCsrScanStatus status)
12493{
12494 struct net_device *dev = (struct net_device *) pContext;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012495 //struct wireless_dev *wdev = dev->ieee80211_ptr;
Jeff Johnson295189b2012-06-20 16:38:30 -070012496 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( dev );
Chandrasekaran, Manishekar41b8e1f2015-03-10 13:30:28 +053012497 hdd_scaninfo_t *pScanInfo;
Jeff Johnson295189b2012-06-20 16:38:30 -070012498 struct cfg80211_scan_request *req = NULL;
12499 int ret = 0;
Mahesh A Saptasagar05a357e2014-02-26 16:28:06 +053012500 bool aborted = false;
c_hpothu6ff1c3c2013-10-01 19:01:57 +053012501 long waitRet = 0;
Agarwal Ashishbd3e10b2014-11-24 19:19:46 +053012502 tANI_U8 i;
Chandrasekaran, Manishekar41b8e1f2015-03-10 13:30:28 +053012503 hdd_context_t *pHddCtx;
Jeff Johnson295189b2012-06-20 16:38:30 -070012504
12505 ENTER();
12506
Chandrasekaran, Manishekar41b8e1f2015-03-10 13:30:28 +053012507 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Siddharth Bhal5c2e02d2015-05-05 17:35:29 +053012508 if (NULL == pHddCtx) {
12509 hddLog(VOS_TRACE_LEVEL_ERROR, FL("HDD context is Null"));
Chandrasekaran, Manishekar41b8e1f2015-03-10 13:30:28 +053012510 goto allow_suspend;
12511 }
12512
12513 pScanInfo = &pHddCtx->scan_info;
12514
Jeff Johnson295189b2012-06-20 16:38:30 -070012515 hddLog(VOS_TRACE_LEVEL_INFO,
12516 "%s called with halHandle = %p, pContext = %p,"
Arif Hussain6d2a3322013-11-17 19:50:10 -080012517 "scanID = %d, returned status = %d",
Jeff Johnson295189b2012-06-20 16:38:30 -070012518 __func__, halHandle, pContext, (int) scanId, (int) status);
12519
Kiet Lamac06e2c2013-10-23 16:25:07 +053012520 pScanInfo->mScanPendingCounter = 0;
12521
Jeff Johnson295189b2012-06-20 16:38:30 -070012522 //Block on scan req completion variable. Can't wait forever though.
c_hpothu6ff1c3c2013-10-01 19:01:57 +053012523 waitRet = wait_for_completion_interruptible_timeout(
Jeff Johnson295189b2012-06-20 16:38:30 -070012524 &pScanInfo->scan_req_completion_event,
12525 msecs_to_jiffies(WLAN_WAIT_TIME_SCAN_REQ));
c_hpothu6ff1c3c2013-10-01 19:01:57 +053012526 if (waitRet <= 0)
Jeff Johnson295189b2012-06-20 16:38:30 -070012527 {
c_hpothu6ff1c3c2013-10-01 19:01:57 +053012528 hddLog(VOS_TRACE_LEVEL_ERROR,
12529 "%s wait on scan_req_completion_event failed %ld",__func__, waitRet);
Jeff Johnson295189b2012-06-20 16:38:30 -070012530 VOS_ASSERT(pScanInfo->mScanPending);
Jeff Johnsone7245742012-09-05 17:12:55 -070012531 goto allow_suspend;
Jeff Johnson295189b2012-06-20 16:38:30 -070012532 }
12533
Yue Maef608272013-04-08 23:09:17 -070012534 if (pScanInfo->mScanPending != VOS_TRUE)
Jeff Johnson295189b2012-06-20 16:38:30 -070012535 {
12536 VOS_ASSERT(pScanInfo->mScanPending);
Jeff Johnsone7245742012-09-05 17:12:55 -070012537 goto allow_suspend;
Jeff Johnson295189b2012-06-20 16:38:30 -070012538 }
12539
12540 /* Check the scanId */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012541 if (pScanInfo->scanId != scanId)
Jeff Johnson295189b2012-06-20 16:38:30 -070012542 {
12543 hddLog(VOS_TRACE_LEVEL_INFO,
12544 "%s called with mismatched scanId pScanInfo->scanId = %d "
Arif Hussain6d2a3322013-11-17 19:50:10 -080012545 "scanId = %d", __func__, (int) pScanInfo->scanId,
Jeff Johnson295189b2012-06-20 16:38:30 -070012546 (int) scanId);
12547 }
12548
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012549 ret = wlan_hdd_cfg80211_update_bss((WLAN_HDD_GET_CTX(pAdapter))->wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -070012550 pAdapter);
12551
12552 if (0 > ret)
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012553 hddLog(VOS_TRACE_LEVEL_INFO, "%s: NO SCAN result", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -070012554
12555
12556 /* If any client wait scan result through WEXT
12557 * send scan done event to client */
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -070012558 if (pHddCtx->scan_info.waitScanResult)
Jeff Johnson295189b2012-06-20 16:38:30 -070012559 {
12560 /* The other scan request waiting for current scan finish
12561 * Send event to notify current scan finished */
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -070012562 if(WEXT_SCAN_PENDING_DELAY == pHddCtx->scan_info.scan_pending_option)
Jeff Johnson295189b2012-06-20 16:38:30 -070012563 {
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -070012564 vos_event_set(&pHddCtx->scan_info.scan_finished_event);
Jeff Johnson295189b2012-06-20 16:38:30 -070012565 }
12566 /* Send notify to WEXT client */
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -070012567 else if(WEXT_SCAN_PENDING_PIGGYBACK == pHddCtx->scan_info.scan_pending_option)
Jeff Johnson295189b2012-06-20 16:38:30 -070012568 {
12569 struct net_device *dev = pAdapter->dev;
12570 union iwreq_data wrqu;
12571 int we_event;
12572 char *msg;
12573
12574 memset(&wrqu, '\0', sizeof(wrqu));
12575 we_event = SIOCGIWSCAN;
12576 msg = NULL;
12577 wireless_send_event(dev, we_event, &wrqu, msg);
12578 }
12579 }
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -070012580 pHddCtx->scan_info.waitScanResult = FALSE;
Jeff Johnson295189b2012-06-20 16:38:30 -070012581
12582 /* Get the Scan Req */
12583 req = pAdapter->request;
12584
12585 if (!req)
12586 {
Arif Hussain6d2a3322013-11-17 19:50:10 -080012587 hddLog(VOS_TRACE_LEVEL_ERROR, "request is became NULL");
Madan Mohan Koyyalamudi9f5a10c2012-09-28 14:46:16 -070012588 pScanInfo->mScanPending = VOS_FALSE;
Jeff Johnsone7245742012-09-05 17:12:55 -070012589 goto allow_suspend;
Jeff Johnson295189b2012-06-20 16:38:30 -070012590 }
12591
Jeff Johnson295189b2012-06-20 16:38:30 -070012592 pAdapter->request = NULL;
Jeff Johnsone7245742012-09-05 17:12:55 -070012593 /* Scan is no longer pending */
12594 pScanInfo->mScanPending = VOS_FALSE;
Jeff Johnson295189b2012-06-20 16:38:30 -070012595
Agarwal Ashishbd3e10b2014-11-24 19:19:46 +053012596 /* last_scan_timestamp is used to decide if new scan
12597 * is needed or not on station interface. If last station
12598 * scan time and new station scan time is less then
12599 * last_scan_timestamp ; driver will return cached scan.
12600 */
12601 if (req->no_cck == FALSE && status == eCSR_SCAN_SUCCESS) // no_cck will be set during p2p find
12602 {
12603 pScanInfo->last_scan_timestamp = vos_timer_get_system_time();
12604
12605 if ( req->n_channels )
12606 {
12607 for (i = 0; i < req->n_channels ; i++ )
12608 {
12609 pHddCtx->scan_info.last_scan_channelList[i] = req->channels[i]->hw_value;
12610 }
12611 /* store no of channel scanned */
12612 pHddCtx->scan_info.last_scan_numChannels= req->n_channels;
12613 }
12614
12615 }
12616
Madan Mohan Koyyalamudib764bf82012-10-11 16:38:51 -070012617 /*
12618 * cfg80211_scan_done informing NL80211 about completion
12619 * of scanning
12620 */
Mahesh A Saptasagar05a357e2014-02-26 16:28:06 +053012621 if (status == eCSR_SCAN_ABORT || status == eCSR_SCAN_FAILURE)
12622 {
12623 aborted = true;
12624 }
12625 cfg80211_scan_done(req, aborted);
Madan Mohan Koyyalamudif4e81002012-11-13 10:46:38 -080012626 complete(&pScanInfo->abortscan_event_var);
Jeff Johnson295189b2012-06-20 16:38:30 -070012627
Hanumantha Reddy Pothulaca1d1cc2015-10-26 15:37:35 +053012628 if ((pHddCtx->cfg_ini->enableMacSpoofing == MAC_ADDR_SPOOFING_FW_HOST_ENABLE
12629 ) && (pHddCtx->spoofMacAddr.isEnabled
12630 || pHddCtx->spoofMacAddr.isReqDeferred)) {
Siddharth Bhal76972212014-10-15 16:22:51 +053012631 /* Generate new random mac addr for next scan */
12632 hddLog(VOS_TRACE_LEVEL_INFO, "scan completed - generate new spoof mac addr");
12633 hdd_processSpoofMacAddrRequest(pHddCtx);
12634 }
12635
Jeff Johnsone7245742012-09-05 17:12:55 -070012636allow_suspend:
Madan Mohan Koyyalamudi9f5a10c2012-09-28 14:46:16 -070012637 /* release the wake lock at the end of the scan*/
Sushant Kaushik83392fa2015-05-05 17:44:40 +053012638 hdd_allow_suspend(WIFI_POWER_EVENT_WAKELOCK_SCAN);
Jeff Johnsone7245742012-09-05 17:12:55 -070012639
Madan Mohan Koyyalamudi10d83a92012-09-28 15:47:05 -070012640 /* Acquire wakelock to handle the case where APP's tries to suspend
12641 * immediatly after the driver gets connect request(i.e after scan)
12642 * from supplicant, this result in app's is suspending and not able
12643 * to process the connect request to AP */
Sushant Kaushik83392fa2015-05-05 17:44:40 +053012644 hdd_prevent_suspend_timeout(1000, WIFI_POWER_EVENT_WAKELOCK_SCAN);
Madan Mohan Koyyalamudi10d83a92012-09-28 15:47:05 -070012645
Gopichand Nakkala638ebc72013-03-21 18:04:02 -070012646#ifdef FEATURE_WLAN_TDLS
Pradeep Reddy POTTETIc7822df2015-02-19 20:15:41 +053012647 wlan_hdd_tdls_scan_done_callback(pAdapter);
Gopichand Nakkala638ebc72013-03-21 18:04:02 -070012648#endif
12649
Jeff Johnson295189b2012-06-20 16:38:30 -070012650 EXIT();
12651 return 0;
12652}
12653
12654/*
Rashmi Ramannab1429032014-04-26 14:59:09 +053012655 * FUNCTION: hdd_isConnectionInProgress
12656 * Go through each adapter and check if Connection is in progress
Madan Mohan Koyyalamudicfd53742013-01-11 15:29:03 -080012657 *
12658 */
Padma, Santhosh Kumar98f271d2014-12-31 17:23:31 +053012659v_BOOL_t hdd_isConnectionInProgress( hdd_context_t *pHddCtx)
Madan Mohan Koyyalamudicfd53742013-01-11 15:29:03 -080012660{
12661 hdd_adapter_list_node_t *pAdapterNode = NULL, *pNext = NULL;
12662 hdd_station_ctx_t *pHddStaCtx = NULL;
12663 hdd_adapter_t *pAdapter = NULL;
12664 VOS_STATUS status = 0;
12665 v_U8_t staId = 0;
12666 v_U8_t *staMac = NULL;
12667
c_hpothu9b781ba2013-12-30 20:57:45 +053012668 if (TRUE == pHddCtx->btCoexModeSet)
12669 {
12670 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Rashmi Ramannab1429032014-04-26 14:59:09 +053012671 FL("BTCoex Mode operation in progress"));
12672 return VOS_TRUE;
c_hpothu9b781ba2013-12-30 20:57:45 +053012673 }
12674
Madan Mohan Koyyalamudicfd53742013-01-11 15:29:03 -080012675 status = hdd_get_front_adapter ( pHddCtx, &pAdapterNode );
12676
12677 while ( NULL != pAdapterNode && VOS_STATUS_SUCCESS == status )
12678 {
12679 pAdapter = pAdapterNode->pAdapter;
12680
12681 if( pAdapter )
12682 {
12683 hddLog(VOS_TRACE_LEVEL_INFO,
Sushant Kaushik8bc7df22014-04-09 17:55:29 +053012684 "%s: Adapter with device mode %s (%d) exists",
12685 __func__, hdd_device_modetoString(pAdapter->device_mode),
12686 pAdapter->device_mode);
Padma, Santhosh Kumar98f271d2014-12-31 17:23:31 +053012687 if (((WLAN_HDD_INFRA_STATION == pAdapter->device_mode) ||
Rashmi Ramannab1429032014-04-26 14:59:09 +053012688 (WLAN_HDD_P2P_CLIENT == pAdapter->device_mode) ||
12689 (WLAN_HDD_P2P_DEVICE == pAdapter->device_mode)) &&
12690 (eConnectionState_Connecting ==
12691 (WLAN_HDD_GET_STATION_CTX_PTR(pAdapter))->conn_info.connState))
12692 {
12693 hddLog(VOS_TRACE_LEVEL_ERROR,
12694 "%s: %p(%d) Connection is in progress", __func__,
12695 WLAN_HDD_GET_STATION_CTX_PTR(pAdapter), pAdapter->sessionId);
12696 return VOS_TRUE;
12697 }
Padma, Santhosh Kumar98f271d2014-12-31 17:23:31 +053012698 if ((WLAN_HDD_INFRA_STATION == pAdapter->device_mode) &&
Padma, Santhosh Kumar3b9657d2015-02-04 19:37:32 +053012699 smeNeighborMiddleOfRoaming(WLAN_HDD_GET_HAL_CTX(pAdapter)))
Padma, Santhosh Kumar98f271d2014-12-31 17:23:31 +053012700 {
12701 hddLog(VOS_TRACE_LEVEL_ERROR,
12702 "%s: %p(%d) Reassociation is in progress", __func__,
12703 WLAN_HDD_GET_STATION_CTX_PTR(pAdapter), pAdapter->sessionId);
12704 return VOS_TRUE;
12705 }
12706 if ((WLAN_HDD_INFRA_STATION == pAdapter->device_mode) ||
Sushant Kaushik8bc7df22014-04-09 17:55:29 +053012707 (WLAN_HDD_P2P_CLIENT == pAdapter->device_mode) ||
12708 (WLAN_HDD_P2P_DEVICE == pAdapter->device_mode))
Madan Mohan Koyyalamudicfd53742013-01-11 15:29:03 -080012709 {
12710 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
12711 if ((eConnectionState_Associated == pHddStaCtx->conn_info.connState) &&
Sushant Kaushik8bc7df22014-04-09 17:55:29 +053012712 (VOS_FALSE == pHddStaCtx->conn_info.uIsAuthenticated))
Madan Mohan Koyyalamudicfd53742013-01-11 15:29:03 -080012713 {
12714 staMac = (v_U8_t *) &(pAdapter->macAddressCurrent.bytes[0]);
12715 hddLog(VOS_TRACE_LEVEL_ERROR,
Arif Hussain24bafea2013-11-15 15:10:03 -080012716 "%s: client " MAC_ADDRESS_STR
12717 " is in the middle of WPS/EAPOL exchange.", __func__,
12718 MAC_ADDR_ARRAY(staMac));
Rashmi Ramannab1429032014-04-26 14:59:09 +053012719 return VOS_TRUE;
Madan Mohan Koyyalamudicfd53742013-01-11 15:29:03 -080012720 }
12721 }
12722 else if ((WLAN_HDD_SOFTAP == pAdapter->device_mode) ||
12723 (WLAN_HDD_P2P_GO == pAdapter->device_mode))
12724 {
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +053012725 v_CONTEXT_t pVosContext = ( WLAN_HDD_GET_CTX(pAdapter))->pvosContext;
12726 ptSapContext pSapCtx = NULL;
12727 pSapCtx = VOS_GET_SAP_CB(pVosContext);
12728 if(pSapCtx == NULL){
12729 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
12730 FL("psapCtx is NULL"));
12731 return VOS_FALSE;
12732 }
Madan Mohan Koyyalamudicfd53742013-01-11 15:29:03 -080012733 for (staId = 0; staId < WLAN_MAX_STA_COUNT; staId++)
12734 {
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +053012735 if ((pSapCtx->aStaInfo[staId].isUsed) &&
12736 (WLANTL_STA_CONNECTED == pSapCtx->aStaInfo[staId].tlSTAState))
Madan Mohan Koyyalamudicfd53742013-01-11 15:29:03 -080012737 {
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +053012738 staMac = (v_U8_t *) &(pSapCtx->aStaInfo[staId].macAddrSTA.bytes[0]);
Madan Mohan Koyyalamudicfd53742013-01-11 15:29:03 -080012739
12740 hddLog(VOS_TRACE_LEVEL_ERROR,
Arif Hussain24bafea2013-11-15 15:10:03 -080012741 "%s: client " MAC_ADDRESS_STR " of SoftAP/P2P-GO is in the "
12742 "middle of WPS/EAPOL exchange.", __func__,
12743 MAC_ADDR_ARRAY(staMac));
Rashmi Ramannab1429032014-04-26 14:59:09 +053012744 return VOS_TRUE;
Madan Mohan Koyyalamudicfd53742013-01-11 15:29:03 -080012745 }
12746 }
12747 }
12748 }
12749 status = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
12750 pAdapterNode = pNext;
12751 }
Rashmi Ramannab1429032014-04-26 14:59:09 +053012752 return VOS_FALSE;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012753}
Madan Mohan Koyyalamudicfd53742013-01-11 15:29:03 -080012754
12755/*
Mahesh A Saptasagarfafb7fe2014-05-16 13:19:37 +053012756 * FUNCTION: __wlan_hdd_cfg80211_scan
Jeff Johnson295189b2012-06-20 16:38:30 -070012757 * this scan respond to scan trigger and update cfg80211 scan database
12758 * later, scan dump command can be used to recieve scan results
12759 */
Mahesh A Saptasagarfafb7fe2014-05-16 13:19:37 +053012760int __wlan_hdd_cfg80211_scan( struct wiphy *wiphy,
Jeff Johnson3bbe4bf2013-01-18 17:05:29 -080012761#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,6,0))
12762 struct net_device *dev,
12763#endif
12764 struct cfg80211_scan_request *request)
12765{
Siddharth Bhal0c162d02014-05-06 19:50:42 +053012766 hdd_adapter_t *pAdapter = NULL;
12767 hdd_context_t *pHddCtx = NULL;
12768 hdd_wext_state_t *pwextBuf = NULL;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053012769 hdd_config_t *cfg_param = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -070012770 tCsrScanRequest scanRequest;
12771 tANI_U8 *channelList = NULL, i;
12772 v_U32_t scanId = 0;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053012773 int status;
12774 hdd_scaninfo_t *pScanInfo = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -070012775 v_U8_t* pP2pIe = NULL;
Agarwal Ashishbd3e10b2014-11-24 19:19:46 +053012776 int ret = 0;
Sushant Kaushik86592172015-04-27 16:35:03 +053012777 v_U8_t *pWpsIe=NULL;
Deepthi Gowrid5c5c2b2015-06-11 17:00:46 +053012778 bool is_p2p_scan = false;
Hanumantha Reddy Pothula2e282d12015-06-19 14:01:26 +053012779 v_S7_t rssi=0;
12780 hdd_station_ctx_t *pHddStaCtx=NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -070012781
Siddharth Bhal0c162d02014-05-06 19:50:42 +053012782#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,6,0))
12783 struct net_device *dev = NULL;
12784 if (NULL == request)
12785 {
12786 hddLog(VOS_TRACE_LEVEL_ERROR,
12787 "%s: scan req param null", __func__);
12788 return -EINVAL;
12789 }
12790 dev = request->wdev->netdev;
12791#endif
12792
12793 pAdapter = WLAN_HDD_GET_PRIV_PTR( dev );
12794 pHddCtx = WLAN_HDD_GET_CTX( pAdapter );
12795 pwextBuf = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
12796
Jeff Johnson295189b2012-06-20 16:38:30 -070012797 ENTER();
12798
Sushant Kaushik8bc7df22014-04-09 17:55:29 +053012799 hddLog(VOS_TRACE_LEVEL_INFO, "%s: device_mode = %s (%d)",
12800 __func__, hdd_device_modetoString(pAdapter->device_mode),
12801 pAdapter->device_mode);
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053012802
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053012803 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053012804 if (0 != status)
12805 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053012806 return status;
12807 }
12808
Siddharth Bhal0c162d02014-05-06 19:50:42 +053012809 if (NULL == pwextBuf)
12810 {
12811 hddLog (VOS_TRACE_LEVEL_ERROR, "%s ERROR: invalid WEXT state\n",
12812 __func__);
12813 return -EIO;
12814 }
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053012815 cfg_param = pHddCtx->cfg_ini;
12816 pScanInfo = &pHddCtx->scan_info;
12817
Hanumantha Reddy Pothula2e282d12015-06-19 14:01:26 +053012818 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
12819 if ( (pHddStaCtx != NULL) && (TRUE == hdd_connIsConnected(pHddStaCtx)))
12820 {
12821 wlan_hdd_get_roam_rssi(pAdapter, &rssi);
12822 hddLog(VOS_TRACE_LEVEL_INFO, FL("rssi: %d"), rssi);
12823 }
12824
Jeff Johnson295189b2012-06-20 16:38:30 -070012825#ifdef WLAN_BTAMP_FEATURE
12826 //Scan not supported when AMP traffic is on.
Gopichand Nakkala681989c2013-03-06 22:27:48 -080012827 if (VOS_TRUE == WLANBAP_AmpSessionOn())
Jeff Johnson295189b2012-06-20 16:38:30 -070012828 {
Madan Mohan Koyyalamudifd4e1da2012-11-09 17:50:19 -080012829 hddLog(VOS_TRACE_LEVEL_ERROR,
Jeff Johnson295189b2012-06-20 16:38:30 -070012830 "%s: No scanning when AMP is on", __func__);
12831 return -EOPNOTSUPP;
12832 }
12833#endif
12834 //Scan on any other interface is not supported.
Gopichand Nakkala681989c2013-03-06 22:27:48 -080012835 if (pAdapter->device_mode == WLAN_HDD_SOFTAP)
Jeff Johnson295189b2012-06-20 16:38:30 -070012836 {
Gopichand Nakkala681989c2013-03-06 22:27:48 -080012837 hddLog(VOS_TRACE_LEVEL_ERROR,
Sushant Kaushik8bc7df22014-04-09 17:55:29 +053012838 "%s: Not scanning on device_mode = %s (%d)",
12839 __func__, hdd_device_modetoString(pAdapter->device_mode),
12840 pAdapter->device_mode);
Jeff Johnson295189b2012-06-20 16:38:30 -070012841 return -EOPNOTSUPP;
12842 }
12843
12844 if (TRUE == pScanInfo->mScanPending)
12845 {
Kiet Lamac06e2c2013-10-23 16:25:07 +053012846 if ( MAX_PENDING_LOG > pScanInfo->mScanPendingCounter++ )
12847 {
12848 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: mScanPending is TRUE", __func__);
12849 }
Gopichand Nakkala681989c2013-03-06 22:27:48 -080012850 return -EBUSY;
Jeff Johnson295189b2012-06-20 16:38:30 -070012851 }
12852
Hanumantha Reddy Pothula4b6be062015-08-18 14:06:24 +053012853 // Don't allow scan if PNO scan is going on.
12854 if (pHddCtx->isPnoEnable)
12855 {
12856 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
12857 FL("pno scan in progress"));
12858 return -EBUSY;
12859 }
12860
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012861 //Don't Allow Scan and return busy if Remain On
Jeff Johnson32d95a32012-09-10 13:15:23 -070012862 //Channel and action frame is pending
12863 //Otherwise Cancel Remain On Channel and allow Scan
12864 //If no action frame pending
Gopichand Nakkala681989c2013-03-06 22:27:48 -080012865 if (0 != wlan_hdd_check_remain_on_channel(pAdapter))
Jeff Johnson32d95a32012-09-10 13:15:23 -070012866 {
Kiet Lamac06e2c2013-10-23 16:25:07 +053012867 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Remain On Channel Pending", __func__);
Jeff Johnson32d95a32012-09-10 13:15:23 -070012868 return -EBUSY;
12869 }
12870
Jeff Johnson295189b2012-06-20 16:38:30 -070012871 if (mutex_lock_interruptible(&pHddCtx->tmInfo.tmOperationLock))
12872 {
12873 VOS_TRACE(VOS_MODULE_ID_HDD,VOS_TRACE_LEVEL_ERROR,
Jeff Johnson1250df42012-12-10 14:31:52 -080012874 "%s: Acquire lock fail", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -070012875 return -EAGAIN;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012876 }
Jeff Johnson295189b2012-06-20 16:38:30 -070012877 if (TRUE == pHddCtx->tmInfo.tmAction.enterImps)
12878 {
Nirav Shah20ac06f2013-12-12 18:14:06 +053012879 hddLog(VOS_TRACE_LEVEL_ERROR,
Jeff Johnson295189b2012-06-20 16:38:30 -070012880 "%s: MAX TM Level Scan not allowed", __func__);
12881 mutex_unlock(&pHddCtx->tmInfo.tmOperationLock);
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012882 return -EBUSY;
Jeff Johnson295189b2012-06-20 16:38:30 -070012883 }
12884 mutex_unlock(&pHddCtx->tmInfo.tmOperationLock);
12885
Madan Mohan Koyyalamudicfd53742013-01-11 15:29:03 -080012886 /* Check if scan is allowed at this point of time.
12887 */
Padma, Santhosh Kumar98f271d2014-12-31 17:23:31 +053012888 if (hdd_isConnectionInProgress(pHddCtx))
Madan Mohan Koyyalamudicfd53742013-01-11 15:29:03 -080012889 {
12890 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Scan not allowed", __func__);
12891 return -EBUSY;
12892 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012893
Jeff Johnson295189b2012-06-20 16:38:30 -070012894 vos_mem_zero( &scanRequest, sizeof(scanRequest));
12895
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +053012896 /* Even though supplicant doesn't provide any SSIDs, n_ssids is set to 1.
12897 * Becasue of this, driver is assuming that this is not wildcard scan and so
12898 * is not aging out the scan results.
12899 */
12900 if (request->ssids && '\0' == request->ssids->ssid[0])
Jeff Johnson295189b2012-06-20 16:38:30 -070012901 {
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +053012902 request->n_ssids = 0;
Jeff Johnson295189b2012-06-20 16:38:30 -070012903 }
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +053012904
12905 if ((request->ssids) && (0 < request->n_ssids))
12906 {
12907 tCsrSSIDInfo *SsidInfo;
12908 int j;
12909 scanRequest.SSIDs.numOfSSIDs = request->n_ssids;
12910 /* Allocate num_ssid tCsrSSIDInfo structure */
12911 SsidInfo = scanRequest.SSIDs.SSIDList =
12912 ( tCsrSSIDInfo *)vos_mem_malloc(
12913 request->n_ssids*sizeof(tCsrSSIDInfo));
12914
12915 if(NULL == scanRequest.SSIDs.SSIDList)
12916 {
12917 hddLog(VOS_TRACE_LEVEL_ERROR,
12918 "%s: memory alloc failed SSIDInfo buffer", __func__);
12919 return -ENOMEM;
12920 }
12921
12922 /* copy all the ssid's and their length */
12923 for(j = 0; j < request->n_ssids; j++, SsidInfo++)
12924 {
12925 /* get the ssid length */
12926 SsidInfo->SSID.length = request->ssids[j].ssid_len;
12927 vos_mem_copy(SsidInfo->SSID.ssId, &request->ssids[j].ssid[0],
12928 SsidInfo->SSID.length);
12929 SsidInfo->SSID.ssId[SsidInfo->SSID.length] = '\0';
12930 hddLog(VOS_TRACE_LEVEL_INFO, "SSID number %d: %s",
12931 j, SsidInfo->SSID.ssId);
12932 }
12933 /* set the scan type to active */
12934 scanRequest.scanType = eSIR_ACTIVE_SCAN;
12935 }
12936 else if(WLAN_HDD_P2P_GO == pAdapter->device_mode)
Jeff Johnson295189b2012-06-20 16:38:30 -070012937 {
Siddharth Bhal0c162d02014-05-06 19:50:42 +053012938 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
12939 TRACE_CODE_HDD_CFG80211_SCAN,
12940 pAdapter->sessionId, 0));
Jeff Johnson295189b2012-06-20 16:38:30 -070012941 /* set the scan type to active */
12942 scanRequest.scanType = eSIR_ACTIVE_SCAN;
Jeff Johnson295189b2012-06-20 16:38:30 -070012943 }
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +053012944 else
12945 {
12946 /*Set the scan type to default type, in this case it is ACTIVE*/
12947 scanRequest.scanType = pScanInfo->scan_mode;
12948 }
12949 scanRequest.minChnTime = cfg_param->nActiveMinChnTime;
12950 scanRequest.maxChnTime = cfg_param->nActiveMaxChnTime;
Jeff Johnson295189b2012-06-20 16:38:30 -070012951
12952 /* set BSSType to default type */
12953 scanRequest.BSSType = eCSR_BSS_TYPE_ANY;
12954
12955 /*TODO: scan the requested channels only*/
12956
12957 /*Right now scanning all the channels */
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +053012958 if (MAX_CHANNEL < request->n_channels)
Jeff Johnson295189b2012-06-20 16:38:30 -070012959 {
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +053012960 hddLog(VOS_TRACE_LEVEL_WARN,
12961 "No of Scan Channels exceeded limit: %d", request->n_channels);
12962 request->n_channels = MAX_CHANNEL;
12963 }
12964
12965 hddLog(VOS_TRACE_LEVEL_INFO,
12966 "No of Scan Channels: %d", request->n_channels);
12967
12968
12969 if( request->n_channels )
12970 {
12971 char chList [(request->n_channels*5)+1];
12972 int len;
12973 channelList = vos_mem_malloc( request->n_channels );
12974 if( NULL == channelList )
c_hpothu53512302014-04-15 18:49:53 +053012975 {
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +053012976 hddLog(VOS_TRACE_LEVEL_ERROR,
12977 "%s: memory alloc failed channelList", __func__);
12978 status = -ENOMEM;
12979 goto free_mem;
c_hpothu53512302014-04-15 18:49:53 +053012980 }
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +053012981
12982 for( i = 0, len = 0; i < request->n_channels ; i++ )
12983 {
12984 channelList[i] = request->channels[i]->hw_value;
12985 len += snprintf(chList+len, 5, "%d ", channelList[i]);
12986 }
12987
Nirav Shah20ac06f2013-12-12 18:14:06 +053012988 hddLog(VOS_TRACE_LEVEL_INFO,
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +053012989 "Channel-List: %s ", chList);
12990 }
c_hpothu53512302014-04-15 18:49:53 +053012991
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +053012992 scanRequest.ChannelInfo.numOfChannels = request->n_channels;
12993 scanRequest.ChannelInfo.ChannelList = channelList;
12994
12995 /* set requestType to full scan */
12996 scanRequest.requestType = eCSR_SCAN_REQUEST_FULL_SCAN;
12997
Agarwal Ashishbd3e10b2014-11-24 19:19:46 +053012998 /* if there is back to back scan happening in driver with in
12999 * nDeferScanTimeInterval interval driver should defer new scan request
13000 * and should provide last cached scan results instead of new channel list.
13001 * This rule is not applicable if scan is p2p scan.
13002 * This condition will work only in case when last request no of channels
13003 * and channels are exactly same as new request.
Agarwal Ashish57e84372014-12-05 18:26:53 +053013004 * This should be done only in connected state
Sushant Kaushik86592172015-04-27 16:35:03 +053013005 * Scan shouldn't be defered for WPS scan case.
Agarwal Ashishbd3e10b2014-11-24 19:19:46 +053013006 */
Agarwal Ashishbd3e10b2014-11-24 19:19:46 +053013007
Sushant Kaushik86592172015-04-27 16:35:03 +053013008 pWpsIe = wlan_hdd_get_wps_ie_ptr((v_U8_t*)request->ie,request->ie_len);
13009 /* if wps ie is NULL , then only defer scan */
13010 if ( pWpsIe == NULL &&
13011 (VOS_STATUS_SUCCESS == hdd_is_any_session_connected(pHddCtx)))
Agarwal Ashish57e84372014-12-05 18:26:53 +053013012 {
13013 if ( pScanInfo->last_scan_timestamp !=0 &&
13014 ((vos_timer_get_system_time() - pScanInfo->last_scan_timestamp ) < pHddCtx->cfg_ini->nDeferScanTimeInterval))
13015 {
13016 if ( request->no_cck == FALSE && scanRequest.ChannelInfo.numOfChannels != 1 &&
13017 (pScanInfo->last_scan_numChannels == scanRequest.ChannelInfo.numOfChannels) &&
13018 vos_mem_compare(pScanInfo->last_scan_channelList,
13019 channelList, pScanInfo->last_scan_numChannels))
13020 {
13021 hddLog(VOS_TRACE_LEVEL_WARN,
13022 " New and old station scan time differ is less then %u",
13023 pHddCtx->cfg_ini->nDeferScanTimeInterval);
13024
13025 ret = wlan_hdd_cfg80211_update_bss((WLAN_HDD_GET_CTX(pAdapter))->wiphy,
Agarwal Ashishbd3e10b2014-11-24 19:19:46 +053013026 pAdapter);
13027
Agarwal Ashish57e84372014-12-05 18:26:53 +053013028 hddLog(VOS_TRACE_LEVEL_WARN,
Masti, Narayanraddide03eb02015-02-06 11:23:50 +053013029 "Return old cached scan as all channels and no of channels are same");
13030
Agarwal Ashish57e84372014-12-05 18:26:53 +053013031 if (0 > ret)
13032 hddLog(VOS_TRACE_LEVEL_INFO, "%s: NO SCAN result", __func__);
Agarwal Ashishbd3e10b2014-11-24 19:19:46 +053013033
Agarwal Ashish57e84372014-12-05 18:26:53 +053013034 cfg80211_scan_done(request, eCSR_SCAN_SUCCESS);
Masti, Narayanraddide03eb02015-02-06 11:23:50 +053013035
13036 status = eHAL_STATUS_SUCCESS;
13037 goto free_mem;
Agarwal Ashish57e84372014-12-05 18:26:53 +053013038 }
13039 }
Agarwal Ashishbd3e10b2014-11-24 19:19:46 +053013040 }
13041
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +053013042 /* Flush the scan results(only p2p beacons) for STA scan and P2P
13043 * search (Flush on both full scan and social scan but not on single
13044 * channel scan).P2P search happens on 3 social channels (1, 6, 11)
13045 */
13046
13047 /* Supplicant does single channel scan after 8-way handshake
13048 * and in that case driver shoudnt flush scan results. If
13049 * driver flushes the scan results here and unfortunately if
13050 * the AP doesnt respond to our probe req then association
13051 * fails which is not desired
13052 */
Deepthi Gowrid5c5c2b2015-06-11 17:00:46 +053013053 if ((request->n_ssids == 1)
13054 && (request->ssids != NULL)
13055 && vos_mem_compare(&request->ssids[0], "DIRECT-", 7))
13056 is_p2p_scan = true;
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +053013057
Deepthi Gowrid5c5c2b2015-06-11 17:00:46 +053013058 if( is_p2p_scan ||
13059 (request->n_channels != WLAN_HDD_P2P_SINGLE_CHANNEL_SCAN) )
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +053013060 {
13061 hddLog(VOS_TRACE_LEVEL_DEBUG, "Flushing P2P Results");
13062 sme_ScanFlushP2PResult( WLAN_HDD_GET_HAL_CTX(pAdapter),
13063 pAdapter->sessionId );
13064 }
13065
13066 if( request->ie_len )
13067 {
13068 /* save this for future association (join requires this) */
13069 /*TODO: Array needs to be converted to dynamic allocation,
13070 * as multiple ie.s can be sent in cfg80211_scan_request structure
13071 * CR 597966
13072 */
13073 memset( &pScanInfo->scanAddIE, 0, sizeof(pScanInfo->scanAddIE) );
13074 memcpy( pScanInfo->scanAddIE.addIEdata, request->ie, request->ie_len);
13075 pScanInfo->scanAddIE.length = request->ie_len;
13076
13077 if ((WLAN_HDD_INFRA_STATION == pAdapter->device_mode) ||
13078 (WLAN_HDD_P2P_CLIENT == pAdapter->device_mode) ||
13079 (WLAN_HDD_P2P_DEVICE == pAdapter->device_mode))
Jeff Johnson295189b2012-06-20 16:38:30 -070013080 {
Ganesh Kondabattini7500fb32015-04-10 14:50:32 +053013081 if (request->ie_len <= SIR_MAC_MAX_ADD_IE_LENGTH)
Jeff Johnson295189b2012-06-20 16:38:30 -070013082 {
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +053013083 pwextBuf->roamProfile.nAddIEScanLength = request->ie_len;
13084 memcpy( pwextBuf->roamProfile.addIEScan,
13085 request->ie, request->ie_len);
13086 }
13087 else
13088 {
13089 hddLog(VOS_TRACE_LEVEL_ERROR, "Scan Ie length is invalid:"
13090 "%zu", request->ie_len);
Jeff Johnson295189b2012-06-20 16:38:30 -070013091 }
13092
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +053013093 }
13094 scanRequest.uIEFieldLen = pScanInfo->scanAddIE.length;
13095 scanRequest.pIEField = pScanInfo->scanAddIE.addIEdata;
13096
13097 pP2pIe = wlan_hdd_get_p2p_ie_ptr((v_U8_t*)request->ie,
13098 request->ie_len);
13099 if (pP2pIe != NULL)
13100 {
13101#ifdef WLAN_FEATURE_P2P_DEBUG
13102 if (((globalP2PConnectionStatus == P2P_GO_NEG_COMPLETED) ||
13103 (globalP2PConnectionStatus == P2P_GO_NEG_PROCESS)) &&
13104 (WLAN_HDD_P2P_CLIENT == pAdapter->device_mode))
Nirav Shah20ac06f2013-12-12 18:14:06 +053013105 {
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +053013106 globalP2PConnectionStatus = P2P_CLIENT_CONNECTING_STATE_1;
13107 hddLog(VOS_TRACE_LEVEL_ERROR,"[P2P State] Changing state from "
13108 "Go nego completed to Connection is started");
13109 hddLog(VOS_TRACE_LEVEL_ERROR,"[P2P]P2P Scanning is started "
13110 "for 8way Handshake");
Nirav Shah20ac06f2013-12-12 18:14:06 +053013111 }
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +053013112 else if((globalP2PConnectionStatus == P2P_CLIENT_DISCONNECTED_STATE) &&
13113 (WLAN_HDD_P2P_CLIENT == pAdapter->device_mode))
Jeff Johnson295189b2012-06-20 16:38:30 -070013114 {
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +053013115 globalP2PConnectionStatus = P2P_CLIENT_CONNECTING_STATE_2;
13116 hddLog(VOS_TRACE_LEVEL_ERROR,"[P2P State] Changing state from "
13117 "Disconnected state to Connection is started");
13118 hddLog(VOS_TRACE_LEVEL_ERROR,"[P2P]P2P Scanning is started "
13119 "for 4way Handshake");
13120 }
13121#endif
13122
13123 /* no_cck will be set during p2p find to disable 11b rates */
13124 if(TRUE == request->no_cck)
13125 {
13126 hddLog(VOS_TRACE_LEVEL_INFO,
13127 "%s: This is a P2P Search", __func__);
13128 scanRequest.p2pSearch = 1;
13129
13130 if( request->n_channels == WLAN_HDD_P2P_SOCIAL_CHANNELS )
Agarwal Ashish4f616132013-12-30 23:32:50 +053013131 {
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +053013132 /* set requestType to P2P Discovery */
13133 scanRequest.requestType = eCSR_SCAN_P2P_DISCOVERY;
13134 }
13135
13136 /*
13137 Skip Dfs Channel in case of P2P Search
13138 if it is set in ini file
13139 */
13140 if(cfg_param->skipDfsChnlInP2pSearch)
13141 {
13142 scanRequest.skipDfsChnlInP2pSearch = 1;
Agarwal Ashish4f616132013-12-30 23:32:50 +053013143 }
13144 else
13145 {
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +053013146 scanRequest.skipDfsChnlInP2pSearch = 0;
Agarwal Ashish4f616132013-12-30 23:32:50 +053013147 }
Jeff Johnson295189b2012-06-20 16:38:30 -070013148
Agarwal Ashish4f616132013-12-30 23:32:50 +053013149 }
Jeff Johnson295189b2012-06-20 16:38:30 -070013150 }
13151 }
13152
13153 INIT_COMPLETION(pScanInfo->scan_req_completion_event);
13154
Pradeep Reddy POTTETIc7822df2015-02-19 20:15:41 +053013155#ifdef FEATURE_WLAN_TDLS
13156 /* if tdls disagree scan right now, return immediately.
13157 tdls will schedule the scan when scan is allowed. (return SUCCESS)
13158 or will reject the scan if any TDLS is in progress. (return -EBUSY)
13159 */
13160 status = wlan_hdd_tdls_scan_callback (pAdapter,
13161 wiphy,
13162#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,6,0))
13163 dev,
13164#endif
13165 request);
13166 if(status <= 0)
13167 {
13168 if(!status)
13169 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: TDLS in progress."
13170 "scan rejected %d", __func__, status);
13171 else
13172 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: TDLS teardown is ongoing %d",
13173 __func__, status);
13174
13175 return status;
13176 }
13177#endif
13178
Madan Mohan Koyyalamudi9f5a10c2012-09-28 14:46:16 -070013179 /* acquire the wakelock to avoid the apps suspend during the scan. To
13180 * address the following issues.
13181 * 1) Disconnected scenario: we are not allowing the suspend as WLAN is not in
13182 * BMPS/IMPS this result in android trying to suspend aggressively and backing off
13183 * for long time, this result in apps running at full power for long time.
13184 * 2) Connected scenario: If we allow the suspend during the scan, RIVA will
13185 * be stuck in full power because of resume BMPS
13186 */
Sushant Kaushik83392fa2015-05-05 17:44:40 +053013187 hdd_prevent_suspend(WIFI_POWER_EVENT_WAKELOCK_SCAN);
Jeff Johnsone7245742012-09-05 17:12:55 -070013188
Nirav Shah20ac06f2013-12-12 18:14:06 +053013189 hddLog(VOS_TRACE_LEVEL_INFO_HIGH,
13190 "requestType %d, scanType %d, minChnTime %d, maxChnTime %d,"
Sushant Kaushik8bc7df22014-04-09 17:55:29 +053013191 "p2pSearch %d, skipDfsChnlInP2pSearch %d",
13192 scanRequest.requestType, scanRequest.scanType,
13193 scanRequest.minChnTime, scanRequest.maxChnTime,
Nirav Shah20ac06f2013-12-12 18:14:06 +053013194 scanRequest.p2pSearch, scanRequest.skipDfsChnlInP2pSearch);
13195
Hanumantha Reddy Pothulaca1d1cc2015-10-26 15:37:35 +053013196 if (pHddCtx->spoofMacAddr.isEnabled &&
13197 pHddCtx->cfg_ini->enableMacSpoofing == 1)
Siddharth Bhal76972212014-10-15 16:22:51 +053013198 {
13199 hddLog(VOS_TRACE_LEVEL_INFO,
13200 "%s: MAC Spoofing enabled for current scan", __func__);
13201 /* Updating SelfSta Mac Addr in TL which will be used to get staidx
13202 * to fill TxBds for probe request during current scan
13203 */
Padma, Santhosh Kumar79236142015-02-09 18:19:33 +053013204 status = WLANTL_updateSpoofMacAddr(pHddCtx->pvosContext,
Siddharth Bhal76972212014-10-15 16:22:51 +053013205 &pHddCtx->spoofMacAddr.randomMacAddr, &pAdapter->macAddressCurrent);
Padma, Santhosh Kumar79236142015-02-09 18:19:33 +053013206
13207 if(status != VOS_STATUS_SUCCESS)
13208 {
Sushant Kaushik83392fa2015-05-05 17:44:40 +053013209 hdd_allow_suspend(WIFI_POWER_EVENT_WAKELOCK_SCAN);
Padma, Santhosh Kumar79236142015-02-09 18:19:33 +053013210 status = -EFAULT;
Ganesh Kondabattini6d3b4902015-05-12 23:19:22 +053013211#ifdef FEATURE_WLAN_TDLS
13212 wlan_hdd_tdls_scan_done_callback(pAdapter);
13213#endif
Padma, Santhosh Kumar79236142015-02-09 18:19:33 +053013214 goto free_mem;
13215 }
Siddharth Bhal76972212014-10-15 16:22:51 +053013216 }
Mahesh A Saptasagar51dc36c2015-06-16 12:07:15 +053013217 wlan_hdd_get_frame_logs(pAdapter, WLAN_HDD_GET_FRAME_LOG_CMD_CLEAR);
Jeff Johnsone7245742012-09-05 17:12:55 -070013218 status = sme_ScanRequest( WLAN_HDD_GET_HAL_CTX(pAdapter),
Jeff Johnson295189b2012-06-20 16:38:30 -070013219 pAdapter->sessionId, &scanRequest, &scanId,
13220 &hdd_cfg80211_scan_done_callback, dev );
Jeff Johnsone7245742012-09-05 17:12:55 -070013221
Jeff Johnson295189b2012-06-20 16:38:30 -070013222 if (eHAL_STATUS_SUCCESS != status)
13223 {
13224 hddLog(VOS_TRACE_LEVEL_ERROR,
13225 "%s: sme_ScanRequest returned error %d", __func__, status);
13226 complete(&pScanInfo->scan_req_completion_event);
Madan Mohan Koyyalamudi3b230fe2012-10-18 14:46:32 -070013227 if(eHAL_STATUS_RESOURCES == status)
13228 {
Nirav Shah20ac06f2013-12-12 18:14:06 +053013229 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: HO is in progress."
13230 "So defer the scan by informing busy",__func__);
Madan Mohan Koyyalamudi3b230fe2012-10-18 14:46:32 -070013231 status = -EBUSY;
13232 } else {
13233 status = -EIO;
13234 }
Sushant Kaushik83392fa2015-05-05 17:44:40 +053013235 hdd_allow_suspend(WIFI_POWER_EVENT_WAKELOCK_SCAN);
Pradeep Reddy POTTETIc7822df2015-02-19 20:15:41 +053013236
13237#ifdef FEATURE_WLAN_TDLS
13238 wlan_hdd_tdls_scan_done_callback(pAdapter);
13239#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070013240 goto free_mem;
13241 }
13242
13243 pScanInfo->mScanPending = TRUE;
Kaushik, Sushant4975a572014-10-21 16:07:48 +053013244 pScanInfo->sessionId = pAdapter->sessionId;
Jeff Johnson295189b2012-06-20 16:38:30 -070013245 pAdapter->request = request;
13246 pScanInfo->scanId = scanId;
13247
13248 complete(&pScanInfo->scan_req_completion_event);
13249
13250free_mem:
13251 if( scanRequest.SSIDs.SSIDList )
13252 {
13253 vos_mem_free(scanRequest.SSIDs.SSIDList);
13254 }
13255
13256 if( channelList )
13257 vos_mem_free( channelList );
13258
13259 EXIT();
Jeff Johnson295189b2012-06-20 16:38:30 -070013260 return status;
13261}
13262
Mahesh A Saptasagarfafb7fe2014-05-16 13:19:37 +053013263int wlan_hdd_cfg80211_scan( struct wiphy *wiphy,
13264#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,6,0))
13265 struct net_device *dev,
13266#endif
13267 struct cfg80211_scan_request *request)
13268{
13269 int ret;
13270
13271 vos_ssr_protect(__func__);
13272 ret = __wlan_hdd_cfg80211_scan(wiphy,
13273#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,6,0))
13274 dev,
13275#endif
13276 request);
13277 vos_ssr_unprotect(__func__);
13278
13279 return ret;
13280}
Shailender Karmuchi15cd0672013-05-15 19:50:04 -070013281
13282void hdd_select_cbmode( hdd_adapter_t *pAdapter,v_U8_t operationChannel)
13283{
13284 v_U8_t iniDot11Mode =
13285 (WLAN_HDD_GET_CTX(pAdapter))->cfg_ini->dot11Mode;
13286 eHddDot11Mode hddDot11Mode = iniDot11Mode;
13287
Arun Kumar Khandavalli94a2bb02013-12-28 19:17:25 +053013288 hddLog(LOG1, FL("Channel Bonding Mode Selected is %u"),
13289 iniDot11Mode);
Shailender Karmuchi15cd0672013-05-15 19:50:04 -070013290 switch ( iniDot11Mode )
13291 {
13292 case eHDD_DOT11_MODE_AUTO:
13293 case eHDD_DOT11_MODE_11ac:
13294 case eHDD_DOT11_MODE_11ac_ONLY:
13295#ifdef WLAN_FEATURE_11AC
Abhishek Singh4b1d2352014-08-01 21:59:28 +053013296 if ( sme_IsFeatureSupportedByDriver(DOT11AC) &&
13297 sme_IsFeatureSupportedByFW(DOT11AC) )
13298 hddDot11Mode = eHDD_DOT11_MODE_11ac;
13299 else
13300 hddDot11Mode = eHDD_DOT11_MODE_11n;
Shailender Karmuchi15cd0672013-05-15 19:50:04 -070013301#else
13302 hddDot11Mode = eHDD_DOT11_MODE_11n;
13303#endif
13304 break;
13305 case eHDD_DOT11_MODE_11n:
13306 case eHDD_DOT11_MODE_11n_ONLY:
13307 hddDot11Mode = eHDD_DOT11_MODE_11n;
13308 break;
13309 default:
13310 hddDot11Mode = iniDot11Mode;
13311 break;
13312 }
Hardik Kantilal Patel086e0a32014-11-20 14:56:26 +053013313#ifdef WLAN_FEATURE_AP_HT40_24G
13314 if (operationChannel > SIR_11B_CHANNEL_END)
13315#endif
13316 {
13317 /* This call decides required channel bonding mode */
13318 sme_SelectCBMode((WLAN_HDD_GET_CTX(pAdapter)->hHal),
Shailender Karmuchi15cd0672013-05-15 19:50:04 -070013319 hdd_cfg_xlate_to_csr_phy_mode(hddDot11Mode),
13320 operationChannel);
Hardik Kantilal Patel086e0a32014-11-20 14:56:26 +053013321 }
Shailender Karmuchi15cd0672013-05-15 19:50:04 -070013322}
13323
Jeff Johnson295189b2012-06-20 16:38:30 -070013324/*
13325 * FUNCTION: wlan_hdd_cfg80211_connect_start
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013326 * This function is used to start the association process
Jeff Johnson295189b2012-06-20 16:38:30 -070013327 */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013328int wlan_hdd_cfg80211_connect_start( hdd_adapter_t *pAdapter,
Hanumantha Reddy Pothula64081b72015-09-11 15:47:32 +053013329 const u8 *ssid, size_t ssid_len, const u8 *bssid,
13330 const u8 *bssid_hint, u8 operatingChannel)
Jeff Johnson295189b2012-06-20 16:38:30 -070013331{
13332 int status = 0;
13333 hdd_wext_state_t *pWextState;
Yue Mae36e3552014-03-05 17:06:20 -080013334 hdd_context_t *pHddCtx;
Jeff Johnson295189b2012-06-20 16:38:30 -070013335 v_U32_t roamId;
13336 tCsrRoamProfile *pRoamProfile;
Jeff Johnson295189b2012-06-20 16:38:30 -070013337 eCsrAuthType RSNAuthType;
Hanumantha Reddy Pothula64081b72015-09-11 15:47:32 +053013338 const u8 *pValidBssid = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -070013339
13340 ENTER();
13341
13342 pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
Yue Mae36e3552014-03-05 17:06:20 -080013343 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
13344
13345 status = wlan_hdd_validate_context(pHddCtx);
13346 if (status)
13347 {
Yue Mae36e3552014-03-05 17:06:20 -080013348 return status;
13349 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013350
Jeff Johnson295189b2012-06-20 16:38:30 -070013351 if (SIR_MAC_MAX_SSID_LENGTH < ssid_len)
13352 {
13353 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: wrong SSID len", __func__);
13354 return -EINVAL;
13355 }
13356
13357 pRoamProfile = &pWextState->roamProfile;
13358
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013359 if (pRoamProfile)
Jeff Johnson295189b2012-06-20 16:38:30 -070013360 {
Jeff Johnsone7245742012-09-05 17:12:55 -070013361 hdd_station_ctx_t *pHddStaCtx;
13362 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
Jeff Johnson295189b2012-06-20 16:38:30 -070013363
Siddharth Bhalda0d1622015-04-24 15:47:49 +053013364 wlan_hdd_get_frame_logs(pAdapter, WLAN_HDD_GET_FRAME_LOG_CMD_CLEAR);
13365
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013366 if (HDD_WMM_USER_MODE_NO_QOS ==
Jeff Johnson295189b2012-06-20 16:38:30 -070013367 (WLAN_HDD_GET_CTX(pAdapter))->cfg_ini->WmmMode)
13368 {
13369 /*QoS not enabled in cfg file*/
13370 pRoamProfile->uapsd_mask = 0;
13371 }
13372 else
13373 {
13374 /*QoS enabled, update uapsd mask from cfg file*/
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013375 pRoamProfile->uapsd_mask =
Jeff Johnson295189b2012-06-20 16:38:30 -070013376 (WLAN_HDD_GET_CTX(pAdapter))->cfg_ini->UapsdMask;
13377 }
13378
13379 pRoamProfile->SSIDs.numOfSSIDs = 1;
13380 pRoamProfile->SSIDs.SSIDList->SSID.length = ssid_len;
13381 vos_mem_zero(pRoamProfile->SSIDs.SSIDList->SSID.ssId,
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013382 sizeof(pRoamProfile->SSIDs.SSIDList->SSID.ssId));
Jeff Johnson295189b2012-06-20 16:38:30 -070013383 vos_mem_copy((void *)(pRoamProfile->SSIDs.SSIDList->SSID.ssId),
13384 ssid, ssid_len);
13385
13386 if (bssid)
13387 {
Hanumantha Reddy Pothula64081b72015-09-11 15:47:32 +053013388 pValidBssid = bssid;
13389 }
13390 else if (bssid_hint)
13391 {
13392 pValidBssid = bssid_hint;
13393 }
13394 if (pValidBssid)
13395 {
Jeff Johnson295189b2012-06-20 16:38:30 -070013396 pRoamProfile->BSSIDs.numOfBSSIDs = 1;
Hanumantha Reddy Pothula64081b72015-09-11 15:47:32 +053013397 vos_mem_copy((void *)(pRoamProfile->BSSIDs.bssid), pValidBssid,
Jeff Johnson295189b2012-06-20 16:38:30 -070013398 WNI_CFG_BSSID_LEN);
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013399 /* Save BSSID in seperate variable as well, as RoamProfile
13400 BSSID is getting zeroed out in the association process. And in
Jeff Johnson295189b2012-06-20 16:38:30 -070013401 case of join failure we should send valid BSSID to supplicant
13402 */
Hanumantha Reddy Pothula64081b72015-09-11 15:47:32 +053013403 vos_mem_copy((void *)(pWextState->req_bssId), pValidBssid,
Jeff Johnson295189b2012-06-20 16:38:30 -070013404 WNI_CFG_BSSID_LEN);
13405 }
Dhanashri Atre51981c62013-06-13 11:47:57 -070013406 else
13407 {
13408 vos_mem_zero((void *)(pRoamProfile->BSSIDs.bssid),WNI_CFG_BSSID_LEN);
13409 }
Jeff Johnson295189b2012-06-20 16:38:30 -070013410
Arun Kumar Khandavalli94a2bb02013-12-28 19:17:25 +053013411 hddLog(LOG1, FL("Connect to SSID: %s opertating Channel: %u"),
13412 pRoamProfile->SSIDs.SSIDList->SSID.ssId, operatingChannel);
Jeff Johnson295189b2012-06-20 16:38:30 -070013413 if ((IW_AUTH_WPA_VERSION_WPA == pWextState->wpaVersion) ||
13414 (IW_AUTH_WPA_VERSION_WPA2 == pWextState->wpaVersion))
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013415 {
Jeff Johnson295189b2012-06-20 16:38:30 -070013416 /*set gen ie*/
13417 hdd_SetGENIEToCsr(pAdapter, &RSNAuthType);
13418 /*set auth*/
13419 hdd_set_csr_auth_type(pAdapter, RSNAuthType);
13420 }
Jeff Johnson295189b2012-06-20 16:38:30 -070013421#ifdef FEATURE_WLAN_WAPI
13422 if (pAdapter->wapi_info.nWapiMode)
13423 {
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -070013424 hddLog(LOG1, "%s: Setting WAPI AUTH Type and Encryption Mode values", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -070013425 switch (pAdapter->wapi_info.wapiAuthMode)
13426 {
13427 case WAPI_AUTH_MODE_PSK:
13428 {
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -070013429 hddLog(LOG1, "%s: WAPI AUTH TYPE: PSK: %d", __func__,
Jeff Johnson295189b2012-06-20 16:38:30 -070013430 pAdapter->wapi_info.wapiAuthMode);
13431 pRoamProfile->AuthType.authType[0] = eCSR_AUTH_TYPE_WAPI_WAI_PSK;
13432 break;
13433 }
13434 case WAPI_AUTH_MODE_CERT:
13435 {
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -070013436 hddLog(LOG1, "%s: WAPI AUTH TYPE: CERT: %d", __func__,
Jeff Johnson295189b2012-06-20 16:38:30 -070013437 pAdapter->wapi_info.wapiAuthMode);
13438 pRoamProfile->AuthType.authType[0] = eCSR_AUTH_TYPE_WAPI_WAI_CERTIFICATE;
13439 break;
13440 }
13441 } // End of switch
13442 if ( pAdapter->wapi_info.wapiAuthMode == WAPI_AUTH_MODE_PSK ||
13443 pAdapter->wapi_info.wapiAuthMode == WAPI_AUTH_MODE_CERT)
13444 {
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -070013445 hddLog(LOG1, "%s: WAPI PAIRWISE/GROUP ENCRYPTION: WPI", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -070013446 pRoamProfile->AuthType.numEntries = 1;
13447 pRoamProfile->EncryptionType.numEntries = 1;
13448 pRoamProfile->EncryptionType.encryptionType[0] = eCSR_ENCRYPT_TYPE_WPI;
13449 pRoamProfile->mcEncryptionType.numEntries = 1;
13450 pRoamProfile->mcEncryptionType.encryptionType[0] = eCSR_ENCRYPT_TYPE_WPI;
13451 }
13452 }
13453#endif /* FEATURE_WLAN_WAPI */
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053013454#ifdef WLAN_FEATURE_GTK_OFFLOAD
Gopichand Nakkalad36ee622013-05-07 14:13:27 +053013455 /* Initializing gtkOffloadReqParams */
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053013456 if ((WLAN_HDD_INFRA_STATION == pAdapter->device_mode) ||
13457 (WLAN_HDD_P2P_CLIENT == pAdapter->device_mode))
13458 {
Gopichand Nakkalad36ee622013-05-07 14:13:27 +053013459 memset(&pHddStaCtx->gtkOffloadReqParams, 0,
13460 sizeof (tSirGtkOffloadParams));
13461 pHddStaCtx->gtkOffloadReqParams.ulFlags = GTK_OFFLOAD_DISABLE;
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053013462 }
13463#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070013464 pRoamProfile->csrPersona = pAdapter->device_mode;
13465
Jeff Johnson32d95a32012-09-10 13:15:23 -070013466 if( operatingChannel )
13467 {
13468 pRoamProfile->ChannelInfo.ChannelList = &operatingChannel;
13469 pRoamProfile->ChannelInfo.numOfChannels = 1;
13470 }
Chet Lanctot186b5732013-03-18 10:26:30 -070013471 else
13472 {
13473 pRoamProfile->ChannelInfo.ChannelList = NULL;
13474 pRoamProfile->ChannelInfo.numOfChannels = 0;
13475 }
Shailender Karmuchi15cd0672013-05-15 19:50:04 -070013476 if ( (WLAN_HDD_IBSS == pAdapter->device_mode) && operatingChannel)
13477 {
13478 hdd_select_cbmode(pAdapter,operatingChannel);
13479 }
Arun Kumar Khandavalli94a2bb02013-12-28 19:17:25 +053013480
Agarwal Ashish40f9b872015-09-01 16:17:35 +053013481 /*
13482 * Change conn_state to connecting before sme_RoamConnect(),
13483 * because sme_RoamConnect() has a direct path to call
13484 * hdd_smeRoamCallback(), which will change the conn_state
13485 * If direct path, conn_state will be accordingly changed
13486 * to NotConnected or Associated by either
13487 * hdd_AssociationCompletionHandler() or hdd_DisConnectHandler()
13488 * in sme_RoamCallback()
13489 * if sme_RomConnect is to be queued,
13490 * Connecting state will remain until it is completed.
13491 * If connection state is not changed,
13492 * connection state will remain in eConnectionState_NotConnected state.
13493 * In hdd_AssociationCompletionHandler, "hddDisconInProgress" is set to true
13494 * if conn state is eConnectionState_NotConnected.
13495 * If "hddDisconInProgress" is set to true then cfg80211 layer is not
13496 * informed of connect result indication which is an issue.
13497 */
13498
Gopichand Nakkalaa3c8fb62013-06-21 15:36:42 +053013499 if (WLAN_HDD_INFRA_STATION == pAdapter->device_mode ||
13500 WLAN_HDD_P2P_CLIENT == pAdapter->device_mode)
Abhishek Singhf4669da2014-05-26 15:07:49 +053013501 {
13502 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Agarwal Ashish40f9b872015-09-01 16:17:35 +053013503 FL("Set HDD connState to eConnectionState_Connecting"));
Madan Mohan Koyyalamudidf86c422012-12-04 17:03:44 -080013504 hdd_connSetConnectionState(WLAN_HDD_GET_STATION_CTX_PTR(pAdapter),
13505 eConnectionState_Connecting);
Abhishek Singhf4669da2014-05-26 15:07:49 +053013506 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013507 status = sme_RoamConnect( WLAN_HDD_GET_HAL_CTX(pAdapter),
Jeff Johnson295189b2012-06-20 16:38:30 -070013508 pAdapter->sessionId, pRoamProfile, &roamId);
13509
Gopichand Nakkalaa3c8fb62013-06-21 15:36:42 +053013510 if ((eHAL_STATUS_SUCCESS != status) &&
13511 (WLAN_HDD_INFRA_STATION == pAdapter->device_mode ||
13512 WLAN_HDD_P2P_CLIENT == pAdapter->device_mode))
Madan Mohan Koyyalamudid5acbf52012-11-28 01:45:08 +053013513
13514 {
Agarwal Ashish40f9b872015-09-01 16:17:35 +053013515 hddLog(VOS_TRACE_LEVEL_ERROR,
13516 FL("sme_RoamConnect (session %d) failed with status %d. -> NotConnected"),
13517 pAdapter->sessionId, status);
Madan Mohan Koyyalamudi42dcd162012-12-03 16:34:04 -080013518 /* change back to NotAssociated */
Madan Mohan Koyyalamudid5acbf52012-11-28 01:45:08 +053013519 hdd_connSetConnectionState(WLAN_HDD_GET_STATION_CTX_PTR(pAdapter),
Madan Mohan Koyyalamudi42dcd162012-12-03 16:34:04 -080013520 eConnectionState_NotConnected);
Madan Mohan Koyyalamudid5acbf52012-11-28 01:45:08 +053013521 }
Madan Mohan Koyyalamudidf86c422012-12-04 17:03:44 -080013522
13523 pRoamProfile->ChannelInfo.ChannelList = NULL;
13524 pRoamProfile->ChannelInfo.numOfChannels = 0;
13525
Jeff Johnson295189b2012-06-20 16:38:30 -070013526 }
13527 else
13528 {
13529 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: No valid Roam profile", __func__);
13530 return -EINVAL;
13531 }
Madan Mohan Koyyalamudifd4e1da2012-11-09 17:50:19 -080013532 EXIT();
Jeff Johnson295189b2012-06-20 16:38:30 -070013533 return status;
13534}
13535
13536/*
13537 * FUNCTION: wlan_hdd_set_cfg80211_auth_type
13538 * This function is used to set the authentication type (OPEN/SHARED).
13539 *
13540 */
13541static int wlan_hdd_cfg80211_set_auth_type(hdd_adapter_t *pAdapter,
13542 enum nl80211_auth_type auth_type)
13543{
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013544 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
Jeff Johnson295189b2012-06-20 16:38:30 -070013545 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
13546
13547 ENTER();
13548
13549 /*set authentication type*/
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013550 switch (auth_type)
Jeff Johnson295189b2012-06-20 16:38:30 -070013551 {
Jeff Johnson295189b2012-06-20 16:38:30 -070013552 case NL80211_AUTHTYPE_AUTOMATIC:
Gopichand Nakkala29149562013-05-10 21:43:41 +053013553 hddLog(VOS_TRACE_LEVEL_INFO,
13554 "%s: set authentication type to AUTOSWITCH", __func__);
13555 pHddStaCtx->conn_info.authType = eCSR_AUTH_TYPE_AUTOSWITCH;
13556 break;
13557
13558 case NL80211_AUTHTYPE_OPEN_SYSTEM:
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070013559#ifdef WLAN_FEATURE_VOWIFI_11R
13560 case NL80211_AUTHTYPE_FT:
13561#endif /* WLAN_FEATURE_VOWIFI_11R */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013562 hddLog(VOS_TRACE_LEVEL_INFO,
Jeff Johnson295189b2012-06-20 16:38:30 -070013563 "%s: set authentication type to OPEN", __func__);
13564 pHddStaCtx->conn_info.authType = eCSR_AUTH_TYPE_OPEN_SYSTEM;
13565 break;
13566
13567 case NL80211_AUTHTYPE_SHARED_KEY:
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013568 hddLog(VOS_TRACE_LEVEL_INFO,
Jeff Johnson295189b2012-06-20 16:38:30 -070013569 "%s: set authentication type to SHARED", __func__);
13570 pHddStaCtx->conn_info.authType = eCSR_AUTH_TYPE_SHARED_KEY;
13571 break;
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -080013572#ifdef FEATURE_WLAN_ESE
Jeff Johnson295189b2012-06-20 16:38:30 -070013573 case NL80211_AUTHTYPE_NETWORK_EAP:
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013574 hddLog(VOS_TRACE_LEVEL_INFO,
Jeff Johnson295189b2012-06-20 16:38:30 -070013575 "%s: set authentication type to CCKM WPA", __func__);
13576 pHddStaCtx->conn_info.authType = eCSR_AUTH_TYPE_CCKM_WPA;//eCSR_AUTH_TYPE_CCKM_RSN needs to be handled as well if required.
13577 break;
13578#endif
13579
13580
13581 default:
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013582 hddLog(VOS_TRACE_LEVEL_ERROR,
13583 "%s: Unsupported authentication type %d", __func__,
Jeff Johnson295189b2012-06-20 16:38:30 -070013584 auth_type);
13585 pHddStaCtx->conn_info.authType = eCSR_AUTH_TYPE_UNKNOWN;
13586 return -EINVAL;
13587 }
13588
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013589 pWextState->roamProfile.AuthType.authType[0] =
Jeff Johnson295189b2012-06-20 16:38:30 -070013590 pHddStaCtx->conn_info.authType;
13591 return 0;
13592}
13593
13594/*
13595 * FUNCTION: wlan_hdd_set_akm_suite
13596 * This function is used to set the key mgmt type(PSK/8021x).
13597 *
13598 */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013599static int wlan_hdd_set_akm_suite( hdd_adapter_t *pAdapter,
Jeff Johnson295189b2012-06-20 16:38:30 -070013600 u32 key_mgmt
13601 )
13602{
13603 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
13604 ENTER();
Abhishek Singhae408032014-09-25 17:22:04 +053013605 /* Should be in ieee802_11_defs.h */
13606#define WLAN_AKM_SUITE_8021X_SHA256 0x000FAC05
13607#define WLAN_AKM_SUITE_PSK_SHA256 0x000FAC06
Jeff Johnson295189b2012-06-20 16:38:30 -070013608 /*set key mgmt type*/
13609 switch(key_mgmt)
13610 {
13611 case WLAN_AKM_SUITE_PSK:
Abhishek Singhae408032014-09-25 17:22:04 +053013612 case WLAN_AKM_SUITE_PSK_SHA256:
Gopichand Nakkala356fb102013-03-06 12:34:04 +053013613#ifdef WLAN_FEATURE_VOWIFI_11R
13614 case WLAN_AKM_SUITE_FT_PSK:
13615#endif
13616 hddLog(VOS_TRACE_LEVEL_INFO, "%s: setting key mgmt type to PSK",
Jeff Johnson295189b2012-06-20 16:38:30 -070013617 __func__);
13618 pWextState->authKeyMgmt |= IW_AUTH_KEY_MGMT_PSK;
13619 break;
13620
13621 case WLAN_AKM_SUITE_8021X:
Abhishek Singhae408032014-09-25 17:22:04 +053013622 case WLAN_AKM_SUITE_8021X_SHA256:
Gopichand Nakkala356fb102013-03-06 12:34:04 +053013623#ifdef WLAN_FEATURE_VOWIFI_11R
13624 case WLAN_AKM_SUITE_FT_8021X:
13625#endif
13626 hddLog(VOS_TRACE_LEVEL_INFO, "%s: setting key mgmt type to 8021x",
Jeff Johnson295189b2012-06-20 16:38:30 -070013627 __func__);
13628 pWextState->authKeyMgmt |= IW_AUTH_KEY_MGMT_802_1X;
13629 break;
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -080013630#ifdef FEATURE_WLAN_ESE
Jeff Johnson295189b2012-06-20 16:38:30 -070013631#define WLAN_AKM_SUITE_CCKM 0x00409600 /* Should be in ieee802_11_defs.h */
13632#define IW_AUTH_KEY_MGMT_CCKM 8 /* Should be in linux/wireless.h */
13633 case WLAN_AKM_SUITE_CCKM:
13634 hddLog(VOS_TRACE_LEVEL_INFO, "%s: setting key mgmt type to CCKM",
13635 __func__);
13636 pWextState->authKeyMgmt |= IW_AUTH_KEY_MGMT_CCKM;
13637 break;
13638#endif
Leela Venkata Kiran Kumar Reddy Chiralae208a832014-04-27 22:34:25 -070013639#ifndef WLAN_AKM_SUITE_OSEN
13640#define WLAN_AKM_SUITE_OSEN 0x506f9a01 /* Should be in ieee802_11_defs.h */
13641 case WLAN_AKM_SUITE_OSEN:
13642 hddLog(VOS_TRACE_LEVEL_INFO, "%s: setting key mgmt type to OSEN",
13643 __func__);
13644 pWextState->authKeyMgmt |= IW_AUTH_KEY_MGMT_802_1X;
13645 break;
13646#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070013647
13648 default:
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013649 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Unsupported key mgmt type %d",
Jeff Johnson295189b2012-06-20 16:38:30 -070013650 __func__, key_mgmt);
13651 return -EINVAL;
13652
13653 }
13654 return 0;
13655}
13656
13657/*
13658 * FUNCTION: wlan_hdd_cfg80211_set_cipher
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013659 * This function is used to set the encryption type
Jeff Johnson295189b2012-06-20 16:38:30 -070013660 * (NONE/WEP40/WEP104/TKIP/CCMP).
13661 */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013662static int wlan_hdd_cfg80211_set_cipher( hdd_adapter_t *pAdapter,
13663 u32 cipher,
Jeff Johnson295189b2012-06-20 16:38:30 -070013664 bool ucast
13665 )
13666{
13667 eCsrEncryptionType encryptionType = eCSR_ENCRYPT_TYPE_NONE;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013668 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
Jeff Johnson295189b2012-06-20 16:38:30 -070013669 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
13670
13671 ENTER();
13672
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013673 if (!cipher)
Jeff Johnson295189b2012-06-20 16:38:30 -070013674 {
Ratheesh S P36dbc932015-08-07 14:28:57 +053013675 hddLog(VOS_TRACE_LEVEL_INFO, "%s: received cipher %d - considering none",
Jeff Johnson295189b2012-06-20 16:38:30 -070013676 __func__, cipher);
13677 encryptionType = eCSR_ENCRYPT_TYPE_NONE;
13678 }
13679 else
13680 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013681
Jeff Johnson295189b2012-06-20 16:38:30 -070013682 /*set encryption method*/
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013683 switch (cipher)
Jeff Johnson295189b2012-06-20 16:38:30 -070013684 {
13685 case IW_AUTH_CIPHER_NONE:
13686 encryptionType = eCSR_ENCRYPT_TYPE_NONE;
13687 break;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013688
Jeff Johnson295189b2012-06-20 16:38:30 -070013689 case WLAN_CIPHER_SUITE_WEP40:
Gopichand Nakkala29149562013-05-10 21:43:41 +053013690 encryptionType = eCSR_ENCRYPT_TYPE_WEP40;
Jeff Johnson295189b2012-06-20 16:38:30 -070013691 break;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013692
Jeff Johnson295189b2012-06-20 16:38:30 -070013693 case WLAN_CIPHER_SUITE_WEP104:
Gopichand Nakkala29149562013-05-10 21:43:41 +053013694 encryptionType = eCSR_ENCRYPT_TYPE_WEP104;
Jeff Johnson295189b2012-06-20 16:38:30 -070013695 break;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013696
Jeff Johnson295189b2012-06-20 16:38:30 -070013697 case WLAN_CIPHER_SUITE_TKIP:
13698 encryptionType = eCSR_ENCRYPT_TYPE_TKIP;
13699 break;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013700
Jeff Johnson295189b2012-06-20 16:38:30 -070013701 case WLAN_CIPHER_SUITE_CCMP:
13702 encryptionType = eCSR_ENCRYPT_TYPE_AES;
13703 break;
13704#ifdef FEATURE_WLAN_WAPI
13705 case WLAN_CIPHER_SUITE_SMS4:
13706 encryptionType = eCSR_ENCRYPT_TYPE_WPI;
13707 break;
13708#endif
13709
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -080013710#ifdef FEATURE_WLAN_ESE
Jeff Johnson295189b2012-06-20 16:38:30 -070013711 case WLAN_CIPHER_SUITE_KRK:
13712 encryptionType = eCSR_ENCRYPT_TYPE_KRK;
13713 break;
13714#endif
13715 default:
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013716 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Unsupported cipher type %d",
Jeff Johnson295189b2012-06-20 16:38:30 -070013717 __func__, cipher);
13718 return -EOPNOTSUPP;
13719 }
13720 }
13721
13722 if (ucast)
13723 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013724 hddLog(VOS_TRACE_LEVEL_INFO, "%s: setting unicast cipher type to %d",
Jeff Johnson295189b2012-06-20 16:38:30 -070013725 __func__, encryptionType);
13726 pHddStaCtx->conn_info.ucEncryptionType = encryptionType;
13727 pWextState->roamProfile.EncryptionType.numEntries = 1;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013728 pWextState->roamProfile.EncryptionType.encryptionType[0] =
Jeff Johnson295189b2012-06-20 16:38:30 -070013729 encryptionType;
13730 }
13731 else
13732 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013733 hddLog(VOS_TRACE_LEVEL_INFO, "%s: setting mcast cipher type to %d",
Jeff Johnson295189b2012-06-20 16:38:30 -070013734 __func__, encryptionType);
13735 pHddStaCtx->conn_info.mcEncryptionType = encryptionType;
13736 pWextState->roamProfile.mcEncryptionType.numEntries = 1;
13737 pWextState->roamProfile.mcEncryptionType.encryptionType[0] = encryptionType;
13738 }
13739
13740 return 0;
13741}
13742
13743
13744/*
13745 * FUNCTION: wlan_hdd_cfg80211_set_ie
13746 * This function is used to parse WPA/RSN IE's.
13747 */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013748int wlan_hdd_cfg80211_set_ie( hdd_adapter_t *pAdapter,
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053013749#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,18,0))
13750 const u8 *ie,
13751#else
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013752 u8 *ie,
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053013753#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070013754 size_t ie_len
13755 )
13756{
13757 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053013758#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,18,0))
13759 const u8 *genie = ie;
13760#else
Jeff Johnson295189b2012-06-20 16:38:30 -070013761 u8 *genie = ie;
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053013762#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070013763 v_U16_t remLen = ie_len;
13764#ifdef FEATURE_WLAN_WAPI
13765 v_U32_t akmsuite[MAX_NUM_AKM_SUITES];
13766 u16 *tmp;
13767 v_U16_t akmsuiteCount;
13768 int *akmlist;
13769#endif
13770 ENTER();
13771
13772 /* clear previous assocAddIE */
13773 pWextState->assocAddIE.length = 0;
13774 pWextState->roamProfile.bWPSAssociation = VOS_FALSE;
Leela Venkata Kiran Kumar Reddy Chiralaf257bef2014-04-11 18:48:12 -070013775 pWextState->roamProfile.bOSENAssociation = VOS_FALSE;
Jeff Johnson295189b2012-06-20 16:38:30 -070013776
13777 while (remLen >= 2)
13778 {
13779 v_U16_t eLen = 0;
13780 v_U8_t elementId;
13781 elementId = *genie++;
13782 eLen = *genie++;
13783 remLen -= 2;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013784
Arif Hussain6d2a3322013-11-17 19:50:10 -080013785 hddLog(VOS_TRACE_LEVEL_INFO, "%s: IE[0x%X], LEN[%d]",
Jeff Johnson295189b2012-06-20 16:38:30 -070013786 __func__, elementId, eLen);
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013787
13788 switch ( elementId )
Jeff Johnson295189b2012-06-20 16:38:30 -070013789 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013790 case DOT11F_EID_WPA:
Madan Mohan Koyyalamudief3b66e2012-10-11 14:29:42 -070013791 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 -070013792 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013793 hddLog(VOS_TRACE_LEVEL_ERROR,
Jeff Johnson295189b2012-06-20 16:38:30 -070013794 "%s: Invalid WPA IE", __func__);
13795 return -EINVAL;
13796 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013797 else if (0 == memcmp(&genie[0], "\x00\x50\xf2\x04", 4))
Jeff Johnson295189b2012-06-20 16:38:30 -070013798 {
13799 v_U16_t curAddIELen = pWextState->assocAddIE.length;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013800 hddLog (VOS_TRACE_LEVEL_INFO, "%s Set WPS IE(len %d)",
Jeff Johnson295189b2012-06-20 16:38:30 -070013801 __func__, eLen + 2);
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013802
Ganesh Kondabattini7500fb32015-04-10 14:50:32 +053013803 if( SIR_MAC_MAX_ADD_IE_LENGTH < (pWextState->assocAddIE.length + eLen) )
Jeff Johnson295189b2012-06-20 16:38:30 -070013804 {
Jeff Johnson902c9832012-12-10 14:28:09 -080013805 hddLog(VOS_TRACE_LEVEL_FATAL, "Cannot accommodate assocAddIE. "
13806 "Need bigger buffer space");
Jeff Johnson295189b2012-06-20 16:38:30 -070013807 VOS_ASSERT(0);
13808 return -ENOMEM;
13809 }
13810 // WSC IE is saved to Additional IE ; it should be accumulated to handle WPS IE + P2P IE
13811 memcpy( pWextState->assocAddIE.addIEdata + curAddIELen, genie - 2, eLen + 2);
13812 pWextState->assocAddIE.length += eLen + 2;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013813
Jeff Johnson295189b2012-06-20 16:38:30 -070013814 pWextState->roamProfile.bWPSAssociation = VOS_TRUE;
13815 pWextState->roamProfile.pAddIEAssoc = pWextState->assocAddIE.addIEdata;
13816 pWextState->roamProfile.nAddIEAssocLength = pWextState->assocAddIE.length;
13817 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013818 else if (0 == memcmp(&genie[0], "\x00\x50\xf2", 3))
13819 {
Jeff Johnson295189b2012-06-20 16:38:30 -070013820 hddLog (VOS_TRACE_LEVEL_INFO, "%s Set WPA IE (len %d)",__func__, eLen + 2);
13821 memset( pWextState->WPARSNIE, 0, MAX_WPA_RSN_IE_LEN );
13822 memcpy( pWextState->WPARSNIE, genie - 2, (eLen + 2) /*ie_len*/);
13823 pWextState->roamProfile.pWPAReqIE = pWextState->WPARSNIE;
13824 pWextState->roamProfile.nWPAReqIELength = eLen + 2;//ie_len;
13825 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013826 else if ( (0 == memcmp(&genie[0], P2P_OUI_TYPE,
Kiet Lam8da98992013-11-21 15:59:07 +053013827 P2P_OUI_TYPE_SIZE)))
Jeff Johnson295189b2012-06-20 16:38:30 -070013828 {
13829 v_U16_t curAddIELen = pWextState->assocAddIE.length;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013830 hddLog (VOS_TRACE_LEVEL_INFO, "%s Set P2P IE(len %d)",
Jeff Johnson295189b2012-06-20 16:38:30 -070013831 __func__, eLen + 2);
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013832
Ganesh Kondabattini7500fb32015-04-10 14:50:32 +053013833 if( SIR_MAC_MAX_ADD_IE_LENGTH < (pWextState->assocAddIE.length + eLen) )
Jeff Johnson295189b2012-06-20 16:38:30 -070013834 {
Jeff Johnson902c9832012-12-10 14:28:09 -080013835 hddLog(VOS_TRACE_LEVEL_FATAL, "Cannot accommodate assocAddIE "
13836 "Need bigger buffer space");
Jeff Johnson295189b2012-06-20 16:38:30 -070013837 VOS_ASSERT(0);
13838 return -ENOMEM;
13839 }
13840 // P2P IE is saved to Additional IE ; it should be accumulated to handle WPS IE + P2P IE
13841 memcpy( pWextState->assocAddIE.addIEdata + curAddIELen, genie - 2, eLen + 2);
13842 pWextState->assocAddIE.length += eLen + 2;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013843
Jeff Johnson295189b2012-06-20 16:38:30 -070013844 pWextState->roamProfile.pAddIEAssoc = pWextState->assocAddIE.addIEdata;
13845 pWextState->roamProfile.nAddIEAssocLength = pWextState->assocAddIE.length;
13846 }
Jeff Johnson295189b2012-06-20 16:38:30 -070013847#ifdef WLAN_FEATURE_WFD
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013848 else if ( (0 == memcmp(&genie[0], WFD_OUI_TYPE,
13849 WFD_OUI_TYPE_SIZE))
Jeff Johnson295189b2012-06-20 16:38:30 -070013850 /*Consider WFD IE, only for P2P Client */
13851 && (WLAN_HDD_P2P_CLIENT == pAdapter->device_mode) )
13852 {
13853 v_U16_t curAddIELen = pWextState->assocAddIE.length;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013854 hddLog (VOS_TRACE_LEVEL_INFO, "%s Set WFD IE(len %d)",
Jeff Johnson295189b2012-06-20 16:38:30 -070013855 __func__, eLen + 2);
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013856
Ganesh Kondabattini7500fb32015-04-10 14:50:32 +053013857 if( SIR_MAC_MAX_ADD_IE_LENGTH < (pWextState->assocAddIE.length + eLen) )
Jeff Johnson295189b2012-06-20 16:38:30 -070013858 {
Jeff Johnson902c9832012-12-10 14:28:09 -080013859 hddLog(VOS_TRACE_LEVEL_FATAL, "Cannot accommodate assocAddIE "
13860 "Need bigger buffer space");
Jeff Johnson295189b2012-06-20 16:38:30 -070013861 VOS_ASSERT(0);
13862 return -ENOMEM;
13863 }
13864 // WFD IE is saved to Additional IE ; it should be accumulated to handle
13865 // WPS IE + P2P IE + WFD IE
13866 memcpy( pWextState->assocAddIE.addIEdata + curAddIELen, genie - 2, eLen + 2);
13867 pWextState->assocAddIE.length += eLen + 2;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013868
Jeff Johnson295189b2012-06-20 16:38:30 -070013869 pWextState->roamProfile.pAddIEAssoc = pWextState->assocAddIE.addIEdata;
13870 pWextState->roamProfile.nAddIEAssocLength = pWextState->assocAddIE.length;
13871 }
13872#endif
Madan Mohan Koyyalamudief3b66e2012-10-11 14:29:42 -070013873 /* Appending HS 2.0 Indication Element in Assiciation Request */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013874 else if ( (0 == memcmp(&genie[0], HS20_OUI_TYPE,
Madan Mohan Koyyalamudi1bed5982012-10-22 14:38:06 -070013875 HS20_OUI_TYPE_SIZE)) )
13876 {
13877 v_U16_t curAddIELen = pWextState->assocAddIE.length;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013878 hddLog (VOS_TRACE_LEVEL_INFO, "%s Set HS20 IE(len %d)",
Madan Mohan Koyyalamudi1bed5982012-10-22 14:38:06 -070013879 __func__, eLen + 2);
Madan Mohan Koyyalamudief3b66e2012-10-11 14:29:42 -070013880
Ganesh Kondabattini7500fb32015-04-10 14:50:32 +053013881 if( SIR_MAC_MAX_ADD_IE_LENGTH < (pWextState->assocAddIE.length + eLen) )
Madan Mohan Koyyalamudi1bed5982012-10-22 14:38:06 -070013882 {
Jeff Johnson902c9832012-12-10 14:28:09 -080013883 hddLog(VOS_TRACE_LEVEL_FATAL, "Cannot accommodate assocAddIE "
13884 "Need bigger buffer space");
Madan Mohan Koyyalamudi1bed5982012-10-22 14:38:06 -070013885 VOS_ASSERT(0);
13886 return -ENOMEM;
13887 }
13888 memcpy( pWextState->assocAddIE.addIEdata + curAddIELen, genie - 2, eLen + 2);
13889 pWextState->assocAddIE.length += eLen + 2;
Madan Mohan Koyyalamudief3b66e2012-10-11 14:29:42 -070013890
Madan Mohan Koyyalamudi1bed5982012-10-22 14:38:06 -070013891 pWextState->roamProfile.pAddIEAssoc = pWextState->assocAddIE.addIEdata;
13892 pWextState->roamProfile.nAddIEAssocLength = pWextState->assocAddIE.length;
13893 }
Leela Venkata Kiran Kumar Reddy Chiralaf257bef2014-04-11 18:48:12 -070013894 /* Appending OSEN Information Element in Assiciation Request */
13895 else if ( (0 == memcmp(&genie[0], OSEN_OUI_TYPE,
13896 OSEN_OUI_TYPE_SIZE)) )
13897 {
13898 v_U16_t curAddIELen = pWextState->assocAddIE.length;
13899 hddLog (VOS_TRACE_LEVEL_INFO, "%s Set OSEN IE(len %d)",
13900 __func__, eLen + 2);
Madan Mohan Koyyalamudief3b66e2012-10-11 14:29:42 -070013901
Ganesh Kondabattini7500fb32015-04-10 14:50:32 +053013902 if( SIR_MAC_MAX_ADD_IE_LENGTH < (pWextState->assocAddIE.length + eLen) )
Leela Venkata Kiran Kumar Reddy Chiralaf257bef2014-04-11 18:48:12 -070013903 {
13904 hddLog(VOS_TRACE_LEVEL_FATAL, "Cannot accommodate assocAddIE "
13905 "Need bigger buffer space");
13906 VOS_ASSERT(0);
13907 return -ENOMEM;
13908 }
13909 memcpy( pWextState->assocAddIE.addIEdata + curAddIELen, genie - 2, eLen + 2);
13910 pWextState->assocAddIE.length += eLen + 2;
13911
13912 pWextState->roamProfile.bOSENAssociation = VOS_TRUE;
13913 pWextState->roamProfile.pAddIEAssoc = pWextState->assocAddIE.addIEdata;
13914 pWextState->roamProfile.nAddIEAssocLength = pWextState->assocAddIE.length;
13915 }
13916
Abhishek Singh4322e622015-06-10 15:42:54 +053013917 /* Update only for WPA IE */
13918 if (!memcmp(genie, WPA_OUI_TYPE, WPA_OUI_TYPE_SIZE) &&
13919 (WLAN_HDD_IBSS == pAdapter->device_mode)) {
Praveen Kumar Sirisilla7d68b7b2013-09-22 14:01:42 -070013920
13921 /* populating as ADDIE in beacon frames */
13922 if (ccmCfgSetStr(WLAN_HDD_GET_HAL_CTX(pAdapter),
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053013923 WNI_CFG_PROBE_RSP_BCN_ADDNIE_DATA, (u8 *)genie - 2, eLen + 2,
Praveen Kumar Sirisilla7d68b7b2013-09-22 14:01:42 -070013924 NULL, eANI_BOOLEAN_FALSE)== eHAL_STATUS_SUCCESS)
13925 {
13926 if (ccmCfgSetInt(WLAN_HDD_GET_HAL_CTX(pAdapter),
13927 WNI_CFG_PROBE_RSP_BCN_ADDNIE_FLAG, 1,NULL,
13928 eANI_BOOLEAN_FALSE) == eHAL_STATUS_FAILURE)
13929 {
13930 hddLog(LOGE,
13931 "Coldn't pass "
13932 "WNI_CFG_PROBE_RSP_BCN_ADDNIE_FLAG to CCM");
13933 }
13934 }/* ccmCfgSetStr(,WNI_CFG_PROBE_RSP_BCN_ADDNIE_DATA, , )*/
13935 else
13936 hddLog(LOGE,
13937 "Could not pass on "
13938 "WNI_CFG_PROBE_RSP_BCN_ADDNIE_DATA to CCM");
13939
13940 /* IBSS mode doesn't contain params->proberesp_ies still
13941 beaconIE's need to be populated in probe response frames */
13942 if ( (NULL != (genie - 2)) && (0 != eLen + 2) )
13943 {
13944 u16 rem_probe_resp_ie_len = eLen + 2;
13945 u8 probe_rsp_ie_len[3] = {0};
13946 u8 counter = 0;
13947
13948 /* Check Probe Resp Length if it is greater then 255 then
13949 Store Probe Rsp IEs into WNI_CFG_PROBE_RSP_ADDNIE_DATA1
13950 & WNI_CFG_PROBE_RSP_ADDNIE_DATA2 CFG Variable As We are
13951 not able Store More then 255 bytes into One Variable */
13952
13953 while ((rem_probe_resp_ie_len > 0) && (counter < 3))
13954 {
13955 if (rem_probe_resp_ie_len > MAX_CFG_STRING_LEN)
13956 {
13957 probe_rsp_ie_len[counter++] = MAX_CFG_STRING_LEN;
13958 rem_probe_resp_ie_len -= MAX_CFG_STRING_LEN;
13959 }
13960 else
13961 {
13962 probe_rsp_ie_len[counter++] = rem_probe_resp_ie_len;
13963 rem_probe_resp_ie_len = 0;
13964 }
13965 }
13966
13967 rem_probe_resp_ie_len = 0;
13968
13969 if (probe_rsp_ie_len[0] > 0)
13970 {
13971 if (ccmCfgSetStr(WLAN_HDD_GET_HAL_CTX(pAdapter),
13972 WNI_CFG_PROBE_RSP_ADDNIE_DATA1,
13973 (tANI_U8*)(genie - 2),
13974 probe_rsp_ie_len[0], NULL,
13975 eANI_BOOLEAN_FALSE)
13976 == eHAL_STATUS_FAILURE)
13977 {
13978 hddLog(LOGE,
13979 "Could not pass"
13980 "on WNI_CFG_PROBE_RSP_ADDNIE_DATA1 to CCM");
13981 }
13982 rem_probe_resp_ie_len += probe_rsp_ie_len[0];
13983 }
13984
13985 if (probe_rsp_ie_len[1] > 0)
13986 {
13987 if (ccmCfgSetStr(WLAN_HDD_GET_HAL_CTX(pAdapter),
13988 WNI_CFG_PROBE_RSP_ADDNIE_DATA2,
13989 (tANI_U8*)(genie - (2 + rem_probe_resp_ie_len)),
13990 probe_rsp_ie_len[1], NULL,
13991 eANI_BOOLEAN_FALSE)
13992 == eHAL_STATUS_FAILURE)
13993 {
13994 hddLog(LOGE,
13995 "Could not pass"
13996 "on WNI_CFG_PROBE_RSP_ADDNIE_DATA2 to CCM");
13997 }
13998 rem_probe_resp_ie_len += probe_rsp_ie_len[1];
13999 }
14000
14001 if (probe_rsp_ie_len[2] > 0)
14002 {
14003 if (ccmCfgSetStr(WLAN_HDD_GET_HAL_CTX(pAdapter),
14004 WNI_CFG_PROBE_RSP_ADDNIE_DATA3,
14005 (tANI_U8*)(genie - (2 + rem_probe_resp_ie_len)),
14006 probe_rsp_ie_len[2], NULL,
14007 eANI_BOOLEAN_FALSE)
14008 == eHAL_STATUS_FAILURE)
14009 {
14010 hddLog(LOGE,
14011 "Could not pass"
14012 "on WNI_CFG_PROBE_RSP_ADDNIE_DATA3 to CCM");
14013 }
14014 rem_probe_resp_ie_len += probe_rsp_ie_len[2];
14015 }
14016
14017 if (ccmCfgSetInt(WLAN_HDD_GET_HAL_CTX(pAdapter),
14018 WNI_CFG_PROBE_RSP_ADDNIE_FLAG, 1,NULL,
14019 eANI_BOOLEAN_FALSE) == eHAL_STATUS_FAILURE)
14020 {
14021 hddLog(LOGE,
14022 "Could not pass"
14023 "on WNI_CFG_PROBE_RSP_ADDNIE_FLAG to CCM");
14024 }
14025 }
Praveen Kumar Sirisilla7d68b7b2013-09-22 14:01:42 -070014026 } /* end of if (WLAN_HDD_IBSS == pAdapter->device_mode) */
Jeff Johnson295189b2012-06-20 16:38:30 -070014027 break;
14028 case DOT11F_EID_RSN:
14029 hddLog (VOS_TRACE_LEVEL_INFO, "%s Set RSN IE(len %d)",__func__, eLen + 2);
14030 memset( pWextState->WPARSNIE, 0, MAX_WPA_RSN_IE_LEN );
14031 memcpy( pWextState->WPARSNIE, genie - 2, (eLen + 2)/*ie_len*/);
14032 pWextState->roamProfile.pRSNReqIE = pWextState->WPARSNIE;
14033 pWextState->roamProfile.nRSNReqIELength = eLen + 2; //ie_len;
14034 break;
Abhishek Singh15d95602015-03-24 15:52:57 +053014035
14036 /* Appending Extended Capabilities with Interworking bit set
14037 * in Assoc Req.
14038 *
14039 * In assoc req this EXT Cap will only be taken into account if
14040 * interworkingService bit is set to 1. Currently
14041 * driver is only interested in interworkingService capability
14042 * from supplicant. If in future any other EXT Cap info is
14043 * required from supplicat, it needs to be handled while
14044 * sending Assoc Req in LIM.
14045 */
Madan Mohan Koyyalamudief3b66e2012-10-11 14:29:42 -070014046 case DOT11F_EID_EXTCAP:
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014047 {
Madan Mohan Koyyalamudief3b66e2012-10-11 14:29:42 -070014048 v_U16_t curAddIELen = pWextState->assocAddIE.length;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014049 hddLog (VOS_TRACE_LEVEL_INFO, "%s Set Extended CAPS IE(len %d)",
Madan Mohan Koyyalamudief3b66e2012-10-11 14:29:42 -070014050 __func__, eLen + 2);
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014051
Ganesh Kondabattini7500fb32015-04-10 14:50:32 +053014052 if( SIR_MAC_MAX_ADD_IE_LENGTH < (pWextState->assocAddIE.length + eLen) )
Madan Mohan Koyyalamudief3b66e2012-10-11 14:29:42 -070014053 {
Jeff Johnson902c9832012-12-10 14:28:09 -080014054 hddLog(VOS_TRACE_LEVEL_FATAL, "Cannot accommodate assocAddIE "
14055 "Need bigger buffer space");
Madan Mohan Koyyalamudief3b66e2012-10-11 14:29:42 -070014056 VOS_ASSERT(0);
14057 return -ENOMEM;
14058 }
14059 memcpy( pWextState->assocAddIE.addIEdata + curAddIELen, genie - 2, eLen + 2);
14060 pWextState->assocAddIE.length += eLen + 2;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014061
Madan Mohan Koyyalamudief3b66e2012-10-11 14:29:42 -070014062 pWextState->roamProfile.pAddIEAssoc = pWextState->assocAddIE.addIEdata;
14063 pWextState->roamProfile.nAddIEAssocLength = pWextState->assocAddIE.length;
14064 break;
14065 }
Jeff Johnson295189b2012-06-20 16:38:30 -070014066#ifdef FEATURE_WLAN_WAPI
14067 case WLAN_EID_WAPI:
14068 pAdapter->wapi_info.nWapiMode = 1; //Setting WAPI Mode to ON=1
Jeff Johnson0299d0a2013-10-30 12:37:43 -070014069 hddLog(VOS_TRACE_LEVEL_INFO, "WAPI MODE IS %u",
Jeff Johnson295189b2012-06-20 16:38:30 -070014070 pAdapter->wapi_info.nWapiMode);
14071 tmp = (u16 *)ie;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014072 tmp = tmp + 2; // Skip element Id and Len, Version
Jeff Johnson295189b2012-06-20 16:38:30 -070014073 akmsuiteCount = WPA_GET_LE16(tmp);
14074 tmp = tmp + 1;
14075 akmlist = (int *)(tmp);
14076 if(akmsuiteCount <= MAX_NUM_AKM_SUITES)
14077 {
14078 memcpy(akmsuite, akmlist, (4*akmsuiteCount));
14079 }
14080 else
14081 {
Arif Hussain6d2a3322013-11-17 19:50:10 -080014082 hddLog(VOS_TRACE_LEVEL_FATAL, "Invalid akmSuite count");
Jeff Johnson295189b2012-06-20 16:38:30 -070014083 VOS_ASSERT(0);
14084 return -EINVAL;
14085 }
14086
14087 if (WAPI_PSK_AKM_SUITE == akmsuite[0])
14088 {
14089 hddLog(VOS_TRACE_LEVEL_INFO, "%s: WAPI AUTH MODE SET TO PSK",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -070014090 __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -070014091 pAdapter->wapi_info.wapiAuthMode = WAPI_AUTH_MODE_PSK;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014092 }
Jeff Johnson295189b2012-06-20 16:38:30 -070014093 if (WAPI_CERT_AKM_SUITE == akmsuite[0])
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014094 {
Jeff Johnson295189b2012-06-20 16:38:30 -070014095 hddLog(VOS_TRACE_LEVEL_INFO, "%s: WAPI AUTH MODE SET TO CERTIFICATE",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -070014096 __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -070014097 pAdapter->wapi_info.wapiAuthMode = WAPI_AUTH_MODE_CERT;
14098 }
14099 break;
14100#endif
14101 default:
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014102 hddLog (VOS_TRACE_LEVEL_ERROR,
Jeff Johnson295189b2012-06-20 16:38:30 -070014103 "%s Set UNKNOWN IE %X", __func__, elementId);
Madan Mohan Koyyalamudief3b66e2012-10-11 14:29:42 -070014104 /* when Unknown IE is received we should break and continue
14105 * to the next IE in the buffer instead we were returning
14106 * so changing this to break */
14107 break;
Jeff Johnson295189b2012-06-20 16:38:30 -070014108 }
14109 genie += eLen;
14110 remLen -= eLen;
14111 }
14112 EXIT();
14113 return 0;
14114}
14115
14116/*
Gopichand Nakkala18f0c262013-05-07 23:25:08 +053014117 * FUNCTION: hdd_isWPAIEPresent
14118 * Parse the received IE to find the WPA IE
14119 *
14120 */
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053014121static bool hdd_isWPAIEPresent(
14122#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 18, 0))
14123 const u8 *ie,
14124#else
14125 u8 *ie,
14126#endif
14127 u8 ie_len)
Gopichand Nakkala18f0c262013-05-07 23:25:08 +053014128{
14129 v_U8_t eLen = 0;
14130 v_U16_t remLen = ie_len;
14131 v_U8_t elementId = 0;
14132
14133 while (remLen >= 2)
14134 {
14135 elementId = *ie++;
14136 eLen = *ie++;
14137 remLen -= 2;
14138 if (eLen > remLen)
14139 {
14140 hddLog(VOS_TRACE_LEVEL_ERROR,
14141 "%s: IE length is wrong %d", __func__, eLen);
14142 return FALSE;
14143 }
14144 if ((elementId == DOT11F_EID_WPA) && (remLen > 5))
14145 {
14146 /* OUI - 0x00 0X50 0XF2
14147 WPA Information Element - 0x01
14148 WPA version - 0x01*/
14149 if (0 == memcmp(&ie[0], "\x00\x50\xf2\x01\x01", 5))
14150 return TRUE;
14151 }
14152 ie += eLen;
14153 remLen -= eLen;
14154 }
14155 return FALSE;
14156}
14157
14158/*
Jeff Johnson295189b2012-06-20 16:38:30 -070014159 * FUNCTION: wlan_hdd_cfg80211_set_privacy
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014160 * This function is used to initialize the security
Jeff Johnson295189b2012-06-20 16:38:30 -070014161 * parameters during connect operation.
14162 */
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053014163int wlan_hdd_cfg80211_set_privacy(hdd_adapter_t *pAdapter,
Jeff Johnson295189b2012-06-20 16:38:30 -070014164 struct cfg80211_connect_params *req
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053014165 )
Jeff Johnson295189b2012-06-20 16:38:30 -070014166{
14167 int status = 0;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014168 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
Jeff Johnson295189b2012-06-20 16:38:30 -070014169 ENTER();
14170
14171 /*set wpa version*/
14172 pWextState->wpaVersion = IW_AUTH_WPA_VERSION_DISABLED;
14173
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014174 if (req->crypto.wpa_versions)
Jeff Johnson295189b2012-06-20 16:38:30 -070014175 {
Gopichand Nakkala781ded42013-06-28 12:10:45 +053014176 if (NL80211_WPA_VERSION_1 == req->crypto.wpa_versions)
Jeff Johnson295189b2012-06-20 16:38:30 -070014177 {
14178 pWextState->wpaVersion = IW_AUTH_WPA_VERSION_WPA;
14179 }
14180 else if (NL80211_WPA_VERSION_2 == req->crypto.wpa_versions)
14181 {
14182 pWextState->wpaVersion = IW_AUTH_WPA_VERSION_WPA2;
14183 }
14184 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014185
14186 hddLog(VOS_TRACE_LEVEL_INFO, "%s: set wpa version to %d", __func__,
Jeff Johnson295189b2012-06-20 16:38:30 -070014187 pWextState->wpaVersion);
14188
14189 /*set authentication type*/
14190 status = wlan_hdd_cfg80211_set_auth_type(pAdapter, req->auth_type);
14191
14192 if (0 > status)
14193 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014194 hddLog(VOS_TRACE_LEVEL_ERROR,
Jeff Johnson295189b2012-06-20 16:38:30 -070014195 "%s: failed to set authentication type ", __func__);
14196 return status;
14197 }
14198
14199 /*set key mgmt type*/
14200 if (req->crypto.n_akm_suites)
14201 {
14202 status = wlan_hdd_set_akm_suite(pAdapter, req->crypto.akm_suites[0]);
14203 if (0 > status)
14204 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014205 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: failed to set akm suite",
Jeff Johnson295189b2012-06-20 16:38:30 -070014206 __func__);
14207 return status;
14208 }
14209 }
14210
14211 /*set pairwise cipher type*/
14212 if (req->crypto.n_ciphers_pairwise)
14213 {
14214 status = wlan_hdd_cfg80211_set_cipher(pAdapter,
14215 req->crypto.ciphers_pairwise[0], true);
14216 if (0 > status)
14217 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014218 hddLog(VOS_TRACE_LEVEL_ERROR,
Jeff Johnson295189b2012-06-20 16:38:30 -070014219 "%s: failed to set unicast cipher type", __func__);
14220 return status;
14221 }
14222 }
14223 else
14224 {
14225 /*Reset previous cipher suite to none*/
14226 status = wlan_hdd_cfg80211_set_cipher(pAdapter, 0, true);
14227 if (0 > status)
14228 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014229 hddLog(VOS_TRACE_LEVEL_ERROR,
Jeff Johnson295189b2012-06-20 16:38:30 -070014230 "%s: failed to set unicast cipher type", __func__);
14231 return status;
14232 }
14233 }
14234
14235 /*set group cipher type*/
14236 status = wlan_hdd_cfg80211_set_cipher(pAdapter, req->crypto.cipher_group,
14237 false);
14238
14239 if (0 > status)
14240 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014241 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: failed to set mcast cipher type",
Jeff Johnson295189b2012-06-20 16:38:30 -070014242 __func__);
14243 return status;
14244 }
14245
Chet Lanctot186b5732013-03-18 10:26:30 -070014246#ifdef WLAN_FEATURE_11W
14247 pWextState->roamProfile.MFPEnabled = (req->mfp == NL80211_MFP_REQUIRED);
14248#endif
14249
Jeff Johnson295189b2012-06-20 16:38:30 -070014250 /*parse WPA/RSN IE, and set the correspoing fileds in Roam profile*/
14251 if (req->ie_len)
14252 {
14253 status = wlan_hdd_cfg80211_set_ie(pAdapter, req->ie, req->ie_len);
14254 if ( 0 > status)
14255 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014256 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: failed to parse the WPA/RSN IE",
Jeff Johnson295189b2012-06-20 16:38:30 -070014257 __func__);
14258 return status;
14259 }
14260 }
14261
14262 /*incase of WEP set default key information*/
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014263 if (req->key && req->key_len)
Jeff Johnson295189b2012-06-20 16:38:30 -070014264 {
14265 if ( (WLAN_CIPHER_SUITE_WEP40 == req->crypto.ciphers_pairwise[0])
14266 || (WLAN_CIPHER_SUITE_WEP104 == req->crypto.ciphers_pairwise[0])
14267 )
14268 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014269 if ( IW_AUTH_KEY_MGMT_802_1X
Jeff Johnson295189b2012-06-20 16:38:30 -070014270 == (pWextState->authKeyMgmt & IW_AUTH_KEY_MGMT_802_1X ))
14271 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014272 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Dynamic WEP not supported",
Jeff Johnson295189b2012-06-20 16:38:30 -070014273 __func__);
14274 return -EOPNOTSUPP;
14275 }
14276 else
14277 {
14278 u8 key_len = req->key_len;
14279 u8 key_idx = req->key_idx;
14280
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014281 if ((eCSR_SECURITY_WEP_KEYSIZE_MAX_BYTES >= key_len)
Jeff Johnson295189b2012-06-20 16:38:30 -070014282 && (CSR_MAX_NUM_KEY > key_idx)
14283 )
14284 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014285 hddLog(VOS_TRACE_LEVEL_INFO,
14286 "%s: setting default wep key, key_idx = %hu key_len %hu",
Jeff Johnson295189b2012-06-20 16:38:30 -070014287 __func__, key_idx, key_len);
14288 vos_mem_copy(
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014289 &pWextState->roamProfile.Keys.KeyMaterial[key_idx][0],
Jeff Johnson295189b2012-06-20 16:38:30 -070014290 req->key, key_len);
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014291 pWextState->roamProfile.Keys.KeyLength[key_idx] =
Jeff Johnson295189b2012-06-20 16:38:30 -070014292 (u8)key_len;
14293 pWextState->roamProfile.Keys.defaultIndex = (u8)key_idx;
14294 }
14295 }
14296 }
14297 }
14298
14299 return status;
14300}
14301
14302/*
Vinay Krishna Eranna21042322014-01-08 19:21:39 +053014303 * FUNCTION: wlan_hdd_try_disconnect
14304 * This function is used to disconnect from previous
14305 * connection
14306 */
14307static int wlan_hdd_try_disconnect( hdd_adapter_t *pAdapter )
14308{
14309 long ret = 0;
14310 hdd_station_ctx_t *pHddStaCtx;
14311 eMib_dot11DesiredBssType connectedBssType;
14312
14313 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
14314
14315 hdd_connGetConnectedBssType(pHddStaCtx,&connectedBssType );
14316
14317 if((eMib_dot11DesiredBssType_independent == connectedBssType) ||
14318 (eConnectionState_Associated == pHddStaCtx->conn_info.connState) ||
14319 (eConnectionState_IbssConnected == pHddStaCtx->conn_info.connState))
14320 {
Abhishek Singhf7962582015-10-23 10:54:06 +053014321 hdd_connSetConnectionState(pHddStaCtx,
14322 eConnectionState_Disconnecting);
Vinay Krishna Eranna21042322014-01-08 19:21:39 +053014323 /* Issue disconnect to CSR */
14324 INIT_COMPLETION(pAdapter->disconnect_comp_var);
14325 if( eHAL_STATUS_SUCCESS ==
14326 sme_RoamDisconnect( WLAN_HDD_GET_HAL_CTX(pAdapter),
14327 pAdapter->sessionId,
14328 eCSR_DISCONNECT_REASON_UNSPECIFIED ) )
14329 {
14330 ret = wait_for_completion_interruptible_timeout(
14331 &pAdapter->disconnect_comp_var,
14332 msecs_to_jiffies(WLAN_WAIT_TIME_DISCONNECT));
14333 if (0 >= ret)
14334 {
14335 hddLog(LOGE, FL("Failed to receive disconnect event"));
14336 return -EALREADY;
14337 }
14338 }
14339 }
14340 else if(eConnectionState_Disconnecting == pHddStaCtx->conn_info.connState)
14341 {
14342 ret = wait_for_completion_interruptible_timeout(
14343 &pAdapter->disconnect_comp_var,
14344 msecs_to_jiffies(WLAN_WAIT_TIME_DISCONNECT));
14345 if (0 >= ret)
14346 {
14347 hddLog(LOGE, FL("Failed to receive disconnect event"));
14348 return -EALREADY;
14349 }
14350 }
14351
14352 return 0;
14353}
14354
14355/*
Agarwal Ashish51325b52014-06-16 16:50:49 +053014356 * FUNCTION: __wlan_hdd_cfg80211_connect
14357 * This function is used to start the association process
Jeff Johnson295189b2012-06-20 16:38:30 -070014358 */
Mahesh A Saptasagarfafb7fe2014-05-16 13:19:37 +053014359static int __wlan_hdd_cfg80211_connect( struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -070014360 struct net_device *ndev,
14361 struct cfg80211_connect_params *req
14362 )
14363{
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053014364 int status;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014365 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( ndev );
Jeff Johnson295189b2012-06-20 16:38:30 -070014366 VOS_STATUS exitbmpsStatus = VOS_STATUS_E_INVAL;
Sushant Kaushikba6764e2014-06-30 19:52:09 +053014367 hdd_context_t *pHddCtx = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -070014368
14369 ENTER();
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053014370
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053014371 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
14372 TRACE_CODE_HDD_CFG80211_CONNECT,
14373 pAdapter->sessionId, pAdapter->device_mode));
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014374 hddLog(VOS_TRACE_LEVEL_INFO,
Sushant Kaushik8bc7df22014-04-09 17:55:29 +053014375 "%s: device_mode = %s (%d)", __func__,
14376 hdd_device_modetoString(pAdapter->device_mode),
14377 pAdapter->device_mode);
Jeff Johnson295189b2012-06-20 16:38:30 -070014378
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053014379 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Rajesh Chauhana0516c62014-01-30 16:11:18 -080014380 if (!pHddCtx)
14381 {
14382 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
14383 "%s: HDD context is null", __func__);
Agarwal Ashish51325b52014-06-16 16:50:49 +053014384 return -EINVAL;
Rajesh Chauhana0516c62014-01-30 16:11:18 -080014385 }
14386
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053014387 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053014388 if (0 != status)
Jeff Johnson295189b2012-06-20 16:38:30 -070014389 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053014390 return status;
Jeff Johnson295189b2012-06-20 16:38:30 -070014391 }
14392
Agarwal Ashish51325b52014-06-16 16:50:49 +053014393 if (vos_max_concurrent_connections_reached()) {
14394 hddLog(VOS_TRACE_LEVEL_INFO, FL("Reached max concurrent connections"));
14395 return -ECONNREFUSED;
14396 }
14397
Jeff Johnson295189b2012-06-20 16:38:30 -070014398#ifdef WLAN_BTAMP_FEATURE
14399 //Infra connect not supported when AMP traffic is on.
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014400 if( VOS_TRUE == WLANBAP_AmpSessionOn() )
Jeff Johnson295189b2012-06-20 16:38:30 -070014401 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014402 hddLog(VOS_TRACE_LEVEL_ERROR,
Jeff Johnson295189b2012-06-20 16:38:30 -070014403 "%s: No connection when AMP is on", __func__);
Madan Mohan Koyyalamudicae253a2012-11-06 19:10:35 -080014404 return -ECONNREFUSED;
Jeff Johnson295189b2012-06-20 16:38:30 -070014405 }
14406#endif
Vinay Krishna Eranna21042322014-01-08 19:21:39 +053014407
14408 //If Device Mode is Station Concurrent Sessions Exit BMps
14409 //P2P Mode will be taken care in Open/close adapter
14410 if((WLAN_HDD_INFRA_STATION == pAdapter->device_mode) &&
Agarwal Ashish51325b52014-06-16 16:50:49 +053014411 (vos_concurrent_open_sessions_running())) {
14412 exitbmpsStatus = hdd_disable_bmps_imps(pHddCtx,
14413 WLAN_HDD_INFRA_STATION);
Vinay Krishna Eranna21042322014-01-08 19:21:39 +053014414 }
14415
14416 /*Try disconnecting if already in connected state*/
14417 status = wlan_hdd_try_disconnect(pAdapter);
14418 if ( 0 > status)
14419 {
14420 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Failed to disconnect the existing"
14421 " connection"));
14422 return -EALREADY;
14423 }
14424
Jeff Johnson295189b2012-06-20 16:38:30 -070014425 /*initialise security parameters*/
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014426 status = wlan_hdd_cfg80211_set_privacy(pAdapter, req);
Jeff Johnson295189b2012-06-20 16:38:30 -070014427
14428 if ( 0 > status)
14429 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014430 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: failed to set security params",
Jeff Johnson295189b2012-06-20 16:38:30 -070014431 __func__);
14432 return status;
14433 }
Mohit Khanna765234a2012-09-11 15:08:35 -070014434 if ( req->channel )
14435 {
14436 status = wlan_hdd_cfg80211_connect_start(pAdapter, req->ssid,
14437 req->ssid_len, req->bssid,
Hanumantha Reddy Pothula64081b72015-09-11 15:47:32 +053014438 req->bssid_hint,
Mohit Khanna765234a2012-09-11 15:08:35 -070014439 req->channel->hw_value);
14440 }
14441 else
14442 {
14443 status = wlan_hdd_cfg80211_connect_start(pAdapter, req->ssid,
Hanumantha Reddy Pothula64081b72015-09-11 15:47:32 +053014444 req->ssid_len, req->bssid,
14445 req->bssid_hint, 0);
Mohit Khanna765234a2012-09-11 15:08:35 -070014446 }
Jeff Johnson295189b2012-06-20 16:38:30 -070014447
Sushant Kaushikd7083982015-03-18 14:33:24 +053014448 if (0 != status)
Jeff Johnson295189b2012-06-20 16:38:30 -070014449 {
14450 //ReEnable BMPS if disabled
14451 if((VOS_STATUS_SUCCESS == exitbmpsStatus) &&
14452 (NULL != pHddCtx))
14453 {
Gopichand Nakkalaa2fe5b02013-06-06 16:32:28 +053014454 if (pHddCtx->hdd_wlan_suspended)
14455 {
14456 hdd_set_pwrparams(pHddCtx);
14457 }
Jeff Johnson295189b2012-06-20 16:38:30 -070014458 //ReEnable Bmps and Imps back
14459 hdd_enable_bmps_imps(pHddCtx);
14460 }
Agarwal Ashish51325b52014-06-16 16:50:49 +053014461 hddLog(VOS_TRACE_LEVEL_ERROR, FL("connect failed"));
Jeff Johnson295189b2012-06-20 16:38:30 -070014462 return status;
14463 }
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053014464 pHddCtx->isAmpAllowed = VOS_FALSE;
Jeff Johnson295189b2012-06-20 16:38:30 -070014465 EXIT();
14466 return status;
14467}
14468
Mahesh A Saptasagarfafb7fe2014-05-16 13:19:37 +053014469static int wlan_hdd_cfg80211_connect( struct wiphy *wiphy,
14470 struct net_device *ndev,
14471 struct cfg80211_connect_params *req)
14472{
14473 int ret;
14474 vos_ssr_protect(__func__);
14475 ret = __wlan_hdd_cfg80211_connect(wiphy, ndev, req);
14476 vos_ssr_unprotect(__func__);
14477
14478 return ret;
14479}
Jeff Johnson295189b2012-06-20 16:38:30 -070014480
14481/*
Gopichand Nakkala78a6c812013-05-13 16:39:49 +053014482 * FUNCTION: wlan_hdd_disconnect
14483 * This function is used to issue a disconnect request to SME
14484 */
14485int wlan_hdd_disconnect( hdd_adapter_t *pAdapter, u16 reason )
14486{
Abhishek Singh6ab864d2014-11-27 12:10:10 +053014487 int status, result = 0;
Gopichand Nakkala78a6c812013-05-13 16:39:49 +053014488 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053014489 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Abhishek Singhdc2bfd42014-06-19 17:59:05 +053014490 long ret;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053014491
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053014492 ENTER();
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053014493
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053014494 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053014495 if (0 != status)
14496 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053014497 return status;
14498 }
14499
Sushant Kaushikb4834d22015-07-15 15:29:05 +053014500 if (pHddStaCtx->conn_info.connState == eConnectionState_Connecting)
14501 {
14502 sme_abortConnection(WLAN_HDD_GET_HAL_CTX(pAdapter),
14503 pAdapter->sessionId);
14504 }
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053014505 pHddCtx->isAmpAllowed = VOS_TRUE;
Agarwal Ashishc65b5ca2014-07-28 21:02:57 +053014506
Agarwal Ashish47d18112014-08-04 19:55:07 +053014507 /* Need to apply spin lock before decreasing active sessions
14508 * as there can be chance for double decrement if context switch
14509 * Calls hdd_DisConnectHandler.
14510 */
14511
14512 spin_lock_bh(&pAdapter->lock_for_active_session);
Agarwal Ashishc65b5ca2014-07-28 21:02:57 +053014513 if (eConnectionState_Associated == pHddStaCtx->conn_info.connState)
14514 {
Agarwal Ashishc65b5ca2014-07-28 21:02:57 +053014515 wlan_hdd_decr_active_session(pHddCtx, pAdapter->device_mode);
14516 }
Agarwal Ashish47d18112014-08-04 19:55:07 +053014517 hdd_connSetConnectionState( pHddStaCtx, eConnectionState_Disconnecting );
14518 spin_unlock_bh(&pAdapter->lock_for_active_session);
Agarwal Ashishc65b5ca2014-07-28 21:02:57 +053014519
Abhishek Singhf4669da2014-05-26 15:07:49 +053014520 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Agarwal Ashish47d18112014-08-04 19:55:07 +053014521 FL( "Set HDD connState to eConnectionState_Disconnecting" ));
14522
Gopichand Nakkala78a6c812013-05-13 16:39:49 +053014523 INIT_COMPLETION(pAdapter->disconnect_comp_var);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053014524
Mihir Shete182a0b22014-08-18 16:08:48 +053014525 /*
14526 * stop tx queues before deleting STA/BSS context from the firmware.
14527 * tx has to be disabled because the firmware can get busy dropping
14528 * the tx frames after BSS/STA has been deleted and will not send
14529 * back a response resulting in WDI timeout
14530 */
Padma, Santhosh Kumar9dacb5c2014-12-17 19:22:56 +053014531 hddLog(VOS_TRACE_LEVEL_INFO, FL("Disabling queues"));
Mihir Shete182a0b22014-08-18 16:08:48 +053014532 netif_tx_disable(pAdapter->dev);
14533 netif_carrier_off(pAdapter->dev);
Arun Kumar Khandavalli94a2bb02013-12-28 19:17:25 +053014534
Mihir Shete182a0b22014-08-18 16:08:48 +053014535 /*issue disconnect*/
Gopichand Nakkala78a6c812013-05-13 16:39:49 +053014536 status = sme_RoamDisconnect( WLAN_HDD_GET_HAL_CTX(pAdapter),
14537 pAdapter->sessionId, reason);
Abhishek Singhdc2bfd42014-06-19 17:59:05 +053014538 if(eHAL_STATUS_CMD_NOT_QUEUED == status)
14539 {
14540 hddLog(VOS_TRACE_LEVEL_INFO,
14541 FL("status = %d, already disconnected"),
14542 (int)status );
Gopichand Nakkala78a6c812013-05-13 16:39:49 +053014543
Abhishek Singhdc2bfd42014-06-19 17:59:05 +053014544 }
14545 else if ( 0 != status )
Gopichand Nakkala78a6c812013-05-13 16:39:49 +053014546 {
14547 hddLog(VOS_TRACE_LEVEL_ERROR,
Arif Hussain6d2a3322013-11-17 19:50:10 -080014548 "%s csrRoamDisconnect failure, returned %d",
Gopichand Nakkala78a6c812013-05-13 16:39:49 +053014549 __func__, (int)status );
Abhishek Singh6ab864d2014-11-27 12:10:10 +053014550 result = -EINVAL;
14551 goto disconnected;
Gopichand Nakkala78a6c812013-05-13 16:39:49 +053014552 }
Abhishek Singhdc2bfd42014-06-19 17:59:05 +053014553 ret = wait_for_completion_interruptible_timeout(
Gopichand Nakkala78a6c812013-05-13 16:39:49 +053014554 &pAdapter->disconnect_comp_var,
14555 msecs_to_jiffies(WLAN_WAIT_TIME_DISCONNECT));
Abhishek Singhdc2bfd42014-06-19 17:59:05 +053014556 if (!ret && ( eHAL_STATUS_CMD_NOT_QUEUED != status ))
c_hpothu6ff1c3c2013-10-01 19:01:57 +053014557 {
14558 hddLog(VOS_TRACE_LEVEL_ERROR,
Mahesh A Saptasagar05a357e2014-02-26 16:28:06 +053014559 "%s: Failed to disconnect, timed out", __func__);
Abhishek Singh6ab864d2014-11-27 12:10:10 +053014560 result = -ETIMEDOUT;
Mahesh A Saptasagar05a357e2014-02-26 16:28:06 +053014561 }
Abhishek Singhdc2bfd42014-06-19 17:59:05 +053014562 else if (ret == -ERESTARTSYS)
Mahesh A Saptasagar05a357e2014-02-26 16:28:06 +053014563 {
14564 hddLog(VOS_TRACE_LEVEL_ERROR,
14565 "%s: Failed to disconnect, wait interrupted", __func__);
Abhishek Singh6ab864d2014-11-27 12:10:10 +053014566 result = -ERESTARTSYS;
c_hpothu6ff1c3c2013-10-01 19:01:57 +053014567 }
Abhishek Singh6ab864d2014-11-27 12:10:10 +053014568disconnected:
Abhishek Singhdc2bfd42014-06-19 17:59:05 +053014569 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
14570 FL("Set HDD connState to eConnectionState_NotConnected"));
14571 pHddStaCtx->conn_info.connState = eConnectionState_NotConnected;
14572
Abhishek Singh087de602015-10-21 17:18:55 +053014573#if LINUX_VERSION_CODE >= KERNEL_VERSION(3, 11, 0)
14574 /* Sending disconnect event to userspace for kernel version < 3.11
14575 * is handled by __cfg80211_disconnect call to __cfg80211_disconnected
14576 */
14577 hddLog(LOG1, FL("Send disconnected event to userspace"));
14578 cfg80211_disconnected(pAdapter->dev, WLAN_REASON_UNSPECIFIED,
14579 NULL, 0, GFP_KERNEL);
14580#endif
14581
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053014582 EXIT();
Abhishek Singh6ab864d2014-11-27 12:10:10 +053014583 return result;
Gopichand Nakkala78a6c812013-05-13 16:39:49 +053014584}
14585
14586
14587/*
Mahesh A Saptasagarfafb7fe2014-05-16 13:19:37 +053014588 * FUNCTION: __wlan_hdd_cfg80211_disconnect
Jeff Johnson295189b2012-06-20 16:38:30 -070014589 * This function is used to issue a disconnect request to SME
14590 */
Mahesh A Saptasagarfafb7fe2014-05-16 13:19:37 +053014591static int __wlan_hdd_cfg80211_disconnect( struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -070014592 struct net_device *dev,
14593 u16 reason
14594 )
14595{
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014596 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( dev );
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053014597 int status;
Chandrasekaran, Manishekar41b8e1f2015-03-10 13:30:28 +053014598 tCsrRoamProfile *pRoamProfile;
14599 hdd_station_ctx_t *pHddStaCtx;
14600 hdd_context_t *pHddCtx;
Gopichand Nakkalaaa353782013-05-17 20:36:22 +053014601#ifdef FEATURE_WLAN_TDLS
Gopichand Nakkala2a0a1572013-02-10 21:39:16 -080014602 tANI_U8 staIdx;
14603#endif
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014604
Jeff Johnson295189b2012-06-20 16:38:30 -070014605 ENTER();
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053014606
Chandrasekaran, Manishekar41b8e1f2015-03-10 13:30:28 +053014607 if (!pAdapter) {
14608 hddLog(VOS_TRACE_LEVEL_ERROR, FL("HDD adpater is NULL"));
14609 return -EINVAL;
14610 }
14611
14612 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
14613 if (!pHddStaCtx) {
14614 hddLog(VOS_TRACE_LEVEL_ERROR, FL("HDD STA context is NULL"));
14615 return -EINVAL;
14616 }
14617
14618 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
14619 status = wlan_hdd_validate_context(pHddCtx);
14620 if (0 != status)
14621 {
14622 return status;
14623 }
14624
14625 pRoamProfile = &(WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter))->roamProfile;
14626
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053014627 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
14628 TRACE_CODE_HDD_CFG80211_DISCONNECT,
14629 pAdapter->sessionId, reason));
Sushant Kaushik8bc7df22014-04-09 17:55:29 +053014630 hddLog(VOS_TRACE_LEVEL_INFO, "%s: device_mode = %s(%d)",
14631 __func__, hdd_device_modetoString(pAdapter->device_mode),
14632 pAdapter->device_mode);
Jeff Johnson295189b2012-06-20 16:38:30 -070014633
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014634 hddLog(VOS_TRACE_LEVEL_INFO, "%s: Disconnect called with reason code %d",
14635 __func__, reason);
Jeff Johnson295189b2012-06-20 16:38:30 -070014636
Jeff Johnson295189b2012-06-20 16:38:30 -070014637 if (NULL != pRoamProfile)
14638 {
14639 /*issue disconnect request to SME, if station is in connected state*/
Mahesh A Saptasagar280fd5a2013-12-05 15:38:31 +053014640 if ((pHddStaCtx->conn_info.connState == eConnectionState_Associated) ||
14641 (pHddStaCtx->conn_info.connState == eConnectionState_Connecting))
Jeff Johnson295189b2012-06-20 16:38:30 -070014642 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014643 eCsrRoamDisconnectReason reasonCode =
Jeff Johnson295189b2012-06-20 16:38:30 -070014644 eCSR_DISCONNECT_REASON_UNSPECIFIED;
Gopichand Nakkalaaa353782013-05-17 20:36:22 +053014645 hdd_scaninfo_t *pScanInfo;
Jeff Johnson295189b2012-06-20 16:38:30 -070014646 switch(reason)
14647 {
14648 case WLAN_REASON_MIC_FAILURE:
14649 reasonCode = eCSR_DISCONNECT_REASON_MIC_ERROR;
14650 break;
14651
14652 case WLAN_REASON_DISASSOC_DUE_TO_INACTIVITY:
14653 case WLAN_REASON_DISASSOC_AP_BUSY:
14654 case WLAN_REASON_CLASS3_FRAME_FROM_NONASSOC_STA:
14655 reasonCode = eCSR_DISCONNECT_REASON_DISASSOC;
14656 break;
14657
14658 case WLAN_REASON_PREV_AUTH_NOT_VALID:
14659 case WLAN_REASON_CLASS2_FRAME_FROM_NONAUTH_STA:
Abhishek Singhc3269a52014-05-21 17:22:24 +053014660 case WLAN_REASON_DEAUTH_LEAVING:
Jeff Johnson295189b2012-06-20 16:38:30 -070014661 reasonCode = eCSR_DISCONNECT_REASON_DEAUTH;
14662 break;
14663
Jeff Johnson295189b2012-06-20 16:38:30 -070014664 default:
14665 reasonCode = eCSR_DISCONNECT_REASON_UNSPECIFIED;
14666 break;
14667 }
Gopichand Nakkalaaa353782013-05-17 20:36:22 +053014668 pScanInfo = &pHddCtx->scan_info;
14669 if (pScanInfo->mScanPending)
14670 {
Srinivas, Dasari138af4f2014-02-07 11:13:45 +053014671 hddLog(VOS_TRACE_LEVEL_INFO, "Disconnect is in progress, "
Gopichand Nakkalaaa353782013-05-17 20:36:22 +053014672 "Aborting Scan");
Kaushik, Sushant4975a572014-10-21 16:07:48 +053014673 hdd_abort_mac_scan(pHddCtx, pScanInfo->sessionId,
Srinivas, Dasari138af4f2014-02-07 11:13:45 +053014674 eCSR_SCAN_ABORT_DEFAULT);
Gopichand Nakkalaaa353782013-05-17 20:36:22 +053014675 }
Agarwal Ashishc089cec2015-08-10 13:10:04 +053014676 wlan_hdd_cancel_existing_remain_on_channel(pAdapter);
Gopichand Nakkala2a0a1572013-02-10 21:39:16 -080014677#ifdef FEATURE_WLAN_TDLS
14678 /* First clean up the tdls peers if any */
Gopichand Nakkala4327a152013-03-04 23:22:42 -080014679 for (staIdx = 0 ; staIdx < HDD_MAX_NUM_TDLS_STA; staIdx++)
Gopichand Nakkala2a0a1572013-02-10 21:39:16 -080014680 {
Gopichand Nakkala4327a152013-03-04 23:22:42 -080014681 if ((pHddCtx->tdlsConnInfo[staIdx].sessionId == pAdapter->sessionId) &&
14682 (pHddCtx->tdlsConnInfo[staIdx].staId))
Gopichand Nakkala2a0a1572013-02-10 21:39:16 -080014683 {
Hoonki Lee11f7dda2013-02-14 16:55:44 -080014684 uint8 *mac;
Gopichand Nakkala4327a152013-03-04 23:22:42 -080014685 mac = pHddCtx->tdlsConnInfo[staIdx].peerMac.bytes;
Masti, Narayanraddi34e0e562015-03-05 18:23:03 +053014686 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Gopichand Nakkalac87400e2013-03-13 18:51:00 -070014687 "%s: call sme_DeleteTdlsPeerSta staId %d sessionId %d " MAC_ADDRESS_STR,
Gopichand Nakkala4327a152013-03-04 23:22:42 -080014688 __func__, pHddCtx->tdlsConnInfo[staIdx].staId, pAdapter->sessionId,
Gopichand Nakkalac87400e2013-03-13 18:51:00 -070014689 MAC_ADDR_ARRAY(mac));
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053014690 status = sme_DeleteTdlsPeerSta(
14691 WLAN_HDD_GET_HAL_CTX(pAdapter),
14692 pAdapter->sessionId,
14693 mac);
14694 if (status != eHAL_STATUS_SUCCESS) {
14695 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Failed to delete TDLS peer STA"));
14696 return -EPERM;
14697 }
Gopichand Nakkala2a0a1572013-02-10 21:39:16 -080014698 }
14699 }
14700#endif
Arun Kumar Khandavalli94a2bb02013-12-28 19:17:25 +053014701 hddLog(LOG1, FL("Disconnecting with reasoncode:%u"), reasonCode);
Gopichand Nakkala78a6c812013-05-13 16:39:49 +053014702 status = wlan_hdd_disconnect(pAdapter, reasonCode);
14703 if ( 0 != status )
Jeff Johnson295189b2012-06-20 16:38:30 -070014704 {
14705 hddLog(VOS_TRACE_LEVEL_ERROR,
Arif Hussain6d2a3322013-11-17 19:50:10 -080014706 "%s wlan_hdd_disconnect failure, returned %d",
Jeff Johnson295189b2012-06-20 16:38:30 -070014707 __func__, (int)status );
14708 return -EINVAL;
14709 }
Jeff Johnson295189b2012-06-20 16:38:30 -070014710 }
Mahesh A Saptasagar280fd5a2013-12-05 15:38:31 +053014711 else
14712 {
14713 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: unexpected cfg disconnect API"
14714 "called while in %d state", __func__,
14715 pHddStaCtx->conn_info.connState);
14716 }
Jeff Johnson295189b2012-06-20 16:38:30 -070014717 }
14718 else
14719 {
14720 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: No valid roam profile", __func__);
14721 }
14722
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053014723 EXIT();
Jeff Johnson295189b2012-06-20 16:38:30 -070014724 return status;
14725}
14726
Mahesh A Saptasagarfafb7fe2014-05-16 13:19:37 +053014727static int wlan_hdd_cfg80211_disconnect( struct wiphy *wiphy,
14728 struct net_device *dev,
14729 u16 reason
14730 )
14731{
14732 int ret;
14733 vos_ssr_protect(__func__);
14734 ret = __wlan_hdd_cfg80211_disconnect(wiphy, dev, reason);
14735 vos_ssr_unprotect(__func__);
14736
14737 return ret;
14738}
Gopichand Nakkala78a6c812013-05-13 16:39:49 +053014739
Jeff Johnson295189b2012-06-20 16:38:30 -070014740/*
14741 * FUNCTION: wlan_hdd_cfg80211_set_privacy_ibss
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014742 * This function is used to initialize the security
Jeff Johnson295189b2012-06-20 16:38:30 -070014743 * settings in IBSS mode.
14744 */
14745static int wlan_hdd_cfg80211_set_privacy_ibss(
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014746 hdd_adapter_t *pAdapter,
Jeff Johnson295189b2012-06-20 16:38:30 -070014747 struct cfg80211_ibss_params *params
14748 )
14749{
14750 int status = 0;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014751 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
Jeff Johnson295189b2012-06-20 16:38:30 -070014752 eCsrEncryptionType encryptionType = eCSR_ENCRYPT_TYPE_NONE;
14753 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014754
Jeff Johnson295189b2012-06-20 16:38:30 -070014755 ENTER();
14756
14757 pWextState->wpaVersion = IW_AUTH_WPA_VERSION_DISABLED;
Ravi Joshib58ca0d2013-10-29 09:50:23 -070014758 vos_mem_zero(&pHddStaCtx->ibss_enc_key, sizeof(tCsrRoamSetKey));
Jeff Johnson295189b2012-06-20 16:38:30 -070014759
14760 if (params->ie_len && ( NULL != params->ie) )
14761 {
Shailender Karmuchi67edd312013-06-18 16:30:48 -070014762 if (wlan_hdd_cfg80211_get_ie_ptr (params->ie,
14763 params->ie_len, WLAN_EID_RSN ))
Jeff Johnson295189b2012-06-20 16:38:30 -070014764 {
14765 pWextState->wpaVersion = IW_AUTH_WPA_VERSION_WPA2;
14766 encryptionType = eCSR_ENCRYPT_TYPE_AES;
14767 }
Shailender Karmuchi67edd312013-06-18 16:30:48 -070014768 else if ( hdd_isWPAIEPresent (params->ie, params->ie_len ))
Jeff Johnson295189b2012-06-20 16:38:30 -070014769 {
Shailender Karmuchi642e9812013-05-30 14:34:49 -070014770 tDot11fIEWPA dot11WPAIE;
14771 tHalHandle halHandle = WLAN_HDD_GET_HAL_CTX(pAdapter);
Shailender Karmuchi67edd312013-06-18 16:30:48 -070014772 u8 *ie;
Shailender Karmuchi642e9812013-05-30 14:34:49 -070014773
Wilson Yang00256342013-10-10 23:13:38 -070014774 memset(&dot11WPAIE, 0, sizeof(dot11WPAIE));
Shailender Karmuchi67edd312013-06-18 16:30:48 -070014775 ie = wlan_hdd_cfg80211_get_ie_ptr (params->ie,
14776 params->ie_len, DOT11F_EID_WPA);
14777 if ( NULL != ie )
14778 {
14779 pWextState->wpaVersion = IW_AUTH_WPA_VERSION_WPA;
14780 // Unpack the WPA IE
14781 //Skip past the EID byte and length byte - and four byte WiFi OUI
14782 dot11fUnpackIeWPA((tpAniSirGlobal) halHandle,
14783 &ie[2+4],
14784 ie[1] - 4,
14785 &dot11WPAIE);
14786 /*Extract the multicast cipher, the encType for unicast
14787 cipher for wpa-none is none*/
14788 encryptionType =
14789 hdd_TranslateWPAToCsrEncryptionType(dot11WPAIE.multicast_cipher);
14790 }
Jeff Johnson295189b2012-06-20 16:38:30 -070014791 }
Shailender Karmuchi67edd312013-06-18 16:30:48 -070014792
Jeff Johnson295189b2012-06-20 16:38:30 -070014793 status = wlan_hdd_cfg80211_set_ie(pAdapter, params->ie, params->ie_len);
14794
14795 if (0 > status)
14796 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014797 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: failed to parse WPA/RSN IE",
Jeff Johnson295189b2012-06-20 16:38:30 -070014798 __func__);
14799 return status;
14800 }
14801 }
14802
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014803 pWextState->roamProfile.AuthType.authType[0] =
14804 pHddStaCtx->conn_info.authType =
Jeff Johnson295189b2012-06-20 16:38:30 -070014805 eCSR_AUTH_TYPE_OPEN_SYSTEM;
14806
14807 if (params->privacy)
14808 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014809 /* Security enabled IBSS, At this time there is no information available
14810 * about the security paramters, so initialise the encryption type to
Jeff Johnson295189b2012-06-20 16:38:30 -070014811 * eCSR_ENCRYPT_TYPE_WEP40_STATICKEY.
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014812 * The correct security parameters will be updated later in
Jeff Johnson295189b2012-06-20 16:38:30 -070014813 * wlan_hdd_cfg80211_add_key */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014814 /* Hal expects encryption type to be set inorder
Jeff Johnson295189b2012-06-20 16:38:30 -070014815 *enable privacy bit in beacons */
14816
14817 encryptionType = eCSR_ENCRYPT_TYPE_WEP40_STATICKEY;
14818 }
Shailender Karmuchi642e9812013-05-30 14:34:49 -070014819 VOS_TRACE (VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO_HIGH,
14820 "encryptionType=%d", encryptionType);
Jeff Johnson295189b2012-06-20 16:38:30 -070014821 pHddStaCtx->conn_info.ucEncryptionType = encryptionType;
14822 pWextState->roamProfile.EncryptionType.numEntries = 1;
14823 pWextState->roamProfile.EncryptionType.encryptionType[0] = encryptionType;
Jeff Johnson295189b2012-06-20 16:38:30 -070014824 return status;
14825}
14826
14827/*
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053014828 * FUNCTION: __wlan_hdd_cfg80211_join_ibss
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014829 * This function is used to create/join an IBSS
Jeff Johnson295189b2012-06-20 16:38:30 -070014830 */
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053014831static int __wlan_hdd_cfg80211_join_ibss( struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -070014832 struct net_device *dev,
14833 struct cfg80211_ibss_params *params
14834 )
14835{
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014836 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( dev );
Jeff Johnson295189b2012-06-20 16:38:30 -070014837 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
14838 tCsrRoamProfile *pRoamProfile;
14839 int status;
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053014840 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
14841 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053014842 tSirMacAddr bssid;
Jeff Johnson295189b2012-06-20 16:38:30 -070014843
14844 ENTER();
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053014845
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053014846 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
14847 TRACE_CODE_HDD_CFG80211_JOIN_IBSS,
14848 pAdapter->sessionId, pAdapter->device_mode));
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014849 hddLog(VOS_TRACE_LEVEL_INFO,
Sushant Kaushik8bc7df22014-04-09 17:55:29 +053014850 "%s: device_mode = %s (%d)", __func__,
14851 hdd_device_modetoString(pAdapter->device_mode),
14852 pAdapter->device_mode);
Jeff Johnson295189b2012-06-20 16:38:30 -070014853
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053014854 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053014855 if (0 != status)
Jeff Johnson295189b2012-06-20 16:38:30 -070014856 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053014857 return status;
Jeff Johnson295189b2012-06-20 16:38:30 -070014858 }
14859
14860 if (NULL == pWextState)
14861 {
Arif Hussain6d2a3322013-11-17 19:50:10 -080014862 hddLog (VOS_TRACE_LEVEL_ERROR, "%s ERROR: Data Storage Corruption",
Jeff Johnson295189b2012-06-20 16:38:30 -070014863 __func__);
14864 return -EIO;
14865 }
14866
Agarwal Ashish51325b52014-06-16 16:50:49 +053014867 if (vos_max_concurrent_connections_reached()) {
14868 hddLog(VOS_TRACE_LEVEL_INFO, FL("Reached max concurrent connections"));
14869 return -ECONNREFUSED;
14870 }
14871
Vinay Krishna Eranna21042322014-01-08 19:21:39 +053014872 /*Try disconnecting if already in connected state*/
14873 status = wlan_hdd_try_disconnect(pAdapter);
14874 if ( 0 > status)
14875 {
14876 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Failed to disconnect the existing"
14877 " IBSS connection"));
14878 return -EALREADY;
14879 }
14880
Jeff Johnson295189b2012-06-20 16:38:30 -070014881 pRoamProfile = &pWextState->roamProfile;
14882
14883 if ( eCSR_BSS_TYPE_START_IBSS != pRoamProfile->BSSType )
14884 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014885 hddLog (VOS_TRACE_LEVEL_ERROR,
Arif Hussain6d2a3322013-11-17 19:50:10 -080014886 "%s Interface type is not set to IBSS", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -070014887 return -EINVAL;
14888 }
14889
Praveen Kumar Sirisillad123d142013-09-24 16:50:13 -070014890 /* BSSID is provided by upper layers hence no need to AUTO generate */
14891 if (NULL != params->bssid) {
14892 if (ccmCfgSetInt(pHddCtx->hHal, WNI_CFG_IBSS_AUTO_BSSID, 0,
14893 NULL, eANI_BOOLEAN_FALSE)==eHAL_STATUS_FAILURE) {
14894 hddLog (VOS_TRACE_LEVEL_ERROR,
14895 "%s:ccmCfgStInt faild for WNI_CFG_IBSS_AUTO_BSSID", __func__);
14896 return -EIO;
14897 }
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053014898 vos_mem_copy((v_U8_t *)bssid, (v_U8_t *)params->bssid, sizeof(bssid));
Praveen Kumar Sirisillad123d142013-09-24 16:50:13 -070014899 }
krunal sonie9002db2013-11-25 14:24:17 -080014900 else if(pHddCtx->cfg_ini->isCoalesingInIBSSAllowed == 0)
14901 {
14902 if (ccmCfgSetInt(pHddCtx->hHal, WNI_CFG_IBSS_AUTO_BSSID, 0,
14903 NULL, eANI_BOOLEAN_FALSE)==eHAL_STATUS_FAILURE)
14904 {
14905 hddLog (VOS_TRACE_LEVEL_ERROR,
14906 "%s:ccmCfgStInt faild for WNI_CFG_IBSS_AUTO_BSSID", __func__);
14907 return -EIO;
14908 }
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053014909
14910 vos_mem_copy((v_U8_t *)bssid,
krunal sonie9002db2013-11-25 14:24:17 -080014911 (v_U8_t *)&pHddCtx->cfg_ini->IbssBssid.bytes[0],
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053014912 sizeof(bssid));
krunal sonie9002db2013-11-25 14:24:17 -080014913 }
Praveen Kumar Sirisillad123d142013-09-24 16:50:13 -070014914
Jeff Johnson295189b2012-06-20 16:38:30 -070014915 /* Set Channel */
Yue Maf49ba872013-08-19 12:04:25 -070014916 if (NULL !=
14917#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,8,0))
14918 params->chandef.chan)
14919#else
14920 params->channel)
14921#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070014922 {
14923 u8 channelNum;
Shailender Karmuchi15cd0672013-05-15 19:50:04 -070014924 v_U32_t numChans = WNI_CFG_VALID_CHANNEL_LIST_LEN;
14925 v_U8_t validChan[WNI_CFG_VALID_CHANNEL_LIST_LEN];
14926 tHalHandle hHal = WLAN_HDD_GET_HAL_CTX(pAdapter);
14927 int indx;
Jeff Johnson295189b2012-06-20 16:38:30 -070014928
14929 /* Get channel number */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014930 channelNum =
Yue Maf49ba872013-08-19 12:04:25 -070014931 ieee80211_frequency_to_channel(
14932#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,8,0))
14933 params->chandef.chan->center_freq);
14934#else
14935 params->channel->center_freq);
14936#endif
Shailender Karmuchi15cd0672013-05-15 19:50:04 -070014937
14938 if (0 != ccmCfgGetStr(hHal, WNI_CFG_VALID_CHANNEL_LIST,
14939 validChan, &numChans))
Jeff Johnson295189b2012-06-20 16:38:30 -070014940 {
Shailender Karmuchi15cd0672013-05-15 19:50:04 -070014941 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: No valid channel list",
14942 __func__);
14943 return -EOPNOTSUPP;
Jeff Johnson295189b2012-06-20 16:38:30 -070014944 }
Shailender Karmuchi15cd0672013-05-15 19:50:04 -070014945
14946 for (indx = 0; indx < numChans; indx++)
Jeff Johnson295189b2012-06-20 16:38:30 -070014947 {
Shailender Karmuchi15cd0672013-05-15 19:50:04 -070014948 if (channelNum == validChan[indx])
14949 {
14950 break;
14951 }
14952 }
14953 if (indx >= numChans)
14954 {
14955 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Not valid Channel %d",
Jeff Johnson295189b2012-06-20 16:38:30 -070014956 __func__, channelNum);
14957 return -EINVAL;
14958 }
Shailender Karmuchi15cd0672013-05-15 19:50:04 -070014959 /* Set the Operational Channel */
14960 hddLog(VOS_TRACE_LEVEL_INFO_HIGH, "%s: set channel %d", __func__,
14961 channelNum);
14962 pRoamProfile->ChannelInfo.numOfChannels = 1;
14963 pHddStaCtx->conn_info.operationChannel = channelNum;
14964 pRoamProfile->ChannelInfo.ChannelList =
14965 &pHddStaCtx->conn_info.operationChannel;
Jeff Johnson295189b2012-06-20 16:38:30 -070014966 }
14967
14968 /* Initialize security parameters */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014969 status = wlan_hdd_cfg80211_set_privacy_ibss(pAdapter, params);
Jeff Johnson295189b2012-06-20 16:38:30 -070014970 if (status < 0)
14971 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014972 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: failed to set security parameters",
Jeff Johnson295189b2012-06-20 16:38:30 -070014973 __func__);
14974 return status;
14975 }
14976
14977 /* Issue connect start */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014978 status = wlan_hdd_cfg80211_connect_start(pAdapter, params->ssid,
Hanumantha Reddy Pothula64081b72015-09-11 15:47:32 +053014979 params->ssid_len, params->bssid, NULL,
Shailender Karmuchi15cd0672013-05-15 19:50:04 -070014980 pHddStaCtx->conn_info.operationChannel);
Jeff Johnson295189b2012-06-20 16:38:30 -070014981
14982 if (0 > status)
Jeff Johnson295189b2012-06-20 16:38:30 -070014983 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: connect failed", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -070014984
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053014985 EXIT();
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053014986 return status;
Jeff Johnson295189b2012-06-20 16:38:30 -070014987}
14988
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053014989static int wlan_hdd_cfg80211_join_ibss( struct wiphy *wiphy,
14990 struct net_device *dev,
14991 struct cfg80211_ibss_params *params
14992 )
14993{
14994 int ret = 0;
14995
14996 vos_ssr_protect(__func__);
14997 ret = __wlan_hdd_cfg80211_join_ibss(wiphy, dev, params);
14998 vos_ssr_unprotect(__func__);
14999
15000 return ret;
15001}
15002
Jeff Johnson295189b2012-06-20 16:38:30 -070015003/*
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053015004 * FUNCTION: __wlan_hdd_cfg80211_leave_ibss
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015005 * This function is used to leave an IBSS
Jeff Johnson295189b2012-06-20 16:38:30 -070015006 */
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053015007static int __wlan_hdd_cfg80211_leave_ibss( struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -070015008 struct net_device *dev
15009 )
15010{
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015011 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( dev );
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053015012 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
15013 tCsrRoamProfile *pRoamProfile;
15014 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053015015 int status;
Jeff Johnson295189b2012-06-20 16:38:30 -070015016
15017 ENTER();
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053015018
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053015019 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
15020 TRACE_CODE_HDD_CFG80211_LEAVE_IBSS,
15021 pAdapter->sessionId, eCSR_DISCONNECT_REASON_IBSS_LEAVE));
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053015022 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053015023 if (0 != status)
Jeff Johnson04dd8a82012-06-29 20:41:40 -070015024 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053015025 return status;
Jeff Johnson04dd8a82012-06-29 20:41:40 -070015026 }
15027
Sushant Kaushik8bc7df22014-04-09 17:55:29 +053015028 hddLog(VOS_TRACE_LEVEL_INFO, "%s: device_mode = %s (%d)", __func__,
15029 hdd_device_modetoString(pAdapter->device_mode),
15030 pAdapter->device_mode);
Jeff Johnson295189b2012-06-20 16:38:30 -070015031 if (NULL == pWextState)
15032 {
Arif Hussain6d2a3322013-11-17 19:50:10 -080015033 hddLog (VOS_TRACE_LEVEL_ERROR, "%s ERROR: Data Storage Corruption",
Jeff Johnson295189b2012-06-20 16:38:30 -070015034 __func__);
15035 return -EIO;
15036 }
15037
15038 pRoamProfile = &pWextState->roamProfile;
15039
15040 /* Issue disconnect only if interface type is set to IBSS */
15041 if (eCSR_BSS_TYPE_START_IBSS != pRoamProfile->BSSType)
15042 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015043 hddLog (VOS_TRACE_LEVEL_ERROR, "%s: BSS Type is not set to IBSS",
Jeff Johnson295189b2012-06-20 16:38:30 -070015044 __func__);
15045 return -EINVAL;
15046 }
15047
15048 /* Issue Disconnect request */
15049 INIT_COMPLETION(pAdapter->disconnect_comp_var);
15050 sme_RoamDisconnect( WLAN_HDD_GET_HAL_CTX(pAdapter), pAdapter->sessionId,
15051 eCSR_DISCONNECT_REASON_IBSS_LEAVE);
15052
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053015053 EXIT();
Jeff Johnson295189b2012-06-20 16:38:30 -070015054 return 0;
15055}
15056
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053015057static int wlan_hdd_cfg80211_leave_ibss( struct wiphy *wiphy,
15058 struct net_device *dev
15059 )
15060{
15061 int ret = 0;
15062
15063 vos_ssr_protect(__func__);
15064 ret = __wlan_hdd_cfg80211_leave_ibss(wiphy, dev);
15065 vos_ssr_unprotect(__func__);
15066
15067 return ret;
15068}
15069
Jeff Johnson295189b2012-06-20 16:38:30 -070015070/*
Mahesh A Saptasagar179d2252014-06-02 21:32:21 +053015071 * FUNCTION: __wlan_hdd_cfg80211_set_wiphy_params
Jeff Johnson295189b2012-06-20 16:38:30 -070015072 * This function is used to set the phy parameters
15073 * (RTS Threshold/FRAG Threshold/Retry Count etc ...)
15074 */
Mahesh A Saptasagar179d2252014-06-02 21:32:21 +053015075static int __wlan_hdd_cfg80211_set_wiphy_params(struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -070015076 u32 changed)
15077{
15078 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
15079 tHalHandle hHal = pHddCtx->hHal;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053015080 int status;
Jeff Johnson295189b2012-06-20 16:38:30 -070015081
15082 ENTER();
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053015083
15084 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053015085 TRACE_CODE_HDD_CFG80211_SET_WIPHY_PARAMS,
15086 NO_SESSION, wiphy->rts_threshold));
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053015087
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053015088 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053015089 if (0 != status)
Jeff Johnson04dd8a82012-06-29 20:41:40 -070015090 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053015091 return status;
Jeff Johnson04dd8a82012-06-29 20:41:40 -070015092 }
15093
Jeff Johnson295189b2012-06-20 16:38:30 -070015094 if (changed & WIPHY_PARAM_RTS_THRESHOLD)
15095 {
15096 u16 rts_threshold = (wiphy->rts_threshold == -1) ?
15097 WNI_CFG_RTS_THRESHOLD_STAMAX :
15098 wiphy->rts_threshold;
15099
15100 if ((WNI_CFG_RTS_THRESHOLD_STAMIN > rts_threshold) ||
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015101 (WNI_CFG_RTS_THRESHOLD_STAMAX < rts_threshold))
Jeff Johnson295189b2012-06-20 16:38:30 -070015102 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015103 hddLog(VOS_TRACE_LEVEL_ERROR,
15104 "%s: Invalid RTS Threshold value %hu",
Jeff Johnson295189b2012-06-20 16:38:30 -070015105 __func__, rts_threshold);
15106 return -EINVAL;
15107 }
15108
15109 if (0 != ccmCfgSetInt(hHal, WNI_CFG_RTS_THRESHOLD,
15110 rts_threshold, ccmCfgSetCallback,
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015111 eANI_BOOLEAN_TRUE))
Jeff Johnson295189b2012-06-20 16:38:30 -070015112 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015113 hddLog(VOS_TRACE_LEVEL_ERROR,
15114 "%s: ccmCfgSetInt failed for rts_threshold value %hu",
Jeff Johnson295189b2012-06-20 16:38:30 -070015115 __func__, rts_threshold);
15116 return -EIO;
15117 }
15118
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015119 hddLog(VOS_TRACE_LEVEL_INFO_MED, "%s: set rts threshold %hu", __func__,
Jeff Johnson295189b2012-06-20 16:38:30 -070015120 rts_threshold);
15121 }
15122
15123 if (changed & WIPHY_PARAM_FRAG_THRESHOLD)
15124 {
15125 u16 frag_threshold = (wiphy->frag_threshold == -1) ?
15126 WNI_CFG_FRAGMENTATION_THRESHOLD_STAMAX :
15127 wiphy->frag_threshold;
15128
15129 if ((WNI_CFG_FRAGMENTATION_THRESHOLD_STAMIN > frag_threshold)||
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015130 (WNI_CFG_FRAGMENTATION_THRESHOLD_STAMAX < frag_threshold) )
Jeff Johnson295189b2012-06-20 16:38:30 -070015131 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015132 hddLog(VOS_TRACE_LEVEL_ERROR,
15133 "%s: Invalid frag_threshold value %hu", __func__,
Jeff Johnson295189b2012-06-20 16:38:30 -070015134 frag_threshold);
15135 return -EINVAL;
15136 }
15137
15138 if (0 != ccmCfgSetInt(hHal, WNI_CFG_FRAGMENTATION_THRESHOLD,
15139 frag_threshold, ccmCfgSetCallback,
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015140 eANI_BOOLEAN_TRUE))
Jeff Johnson295189b2012-06-20 16:38:30 -070015141 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015142 hddLog(VOS_TRACE_LEVEL_ERROR,
15143 "%s: ccmCfgSetInt failed for frag_threshold value %hu",
Jeff Johnson295189b2012-06-20 16:38:30 -070015144 __func__, frag_threshold);
15145 return -EIO;
15146 }
15147
15148 hddLog(VOS_TRACE_LEVEL_INFO_MED, "%s: set frag threshold %hu", __func__,
15149 frag_threshold);
15150 }
15151
15152 if ((changed & WIPHY_PARAM_RETRY_SHORT)
15153 || (changed & WIPHY_PARAM_RETRY_LONG))
15154 {
15155 u8 retry_value = (changed & WIPHY_PARAM_RETRY_SHORT) ?
15156 wiphy->retry_short :
15157 wiphy->retry_long;
15158
15159 if ((WNI_CFG_LONG_RETRY_LIMIT_STAMIN > retry_value) ||
15160 (WNI_CFG_LONG_RETRY_LIMIT_STAMAX < retry_value))
15161 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015162 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Invalid Retry count %hu",
Jeff Johnson295189b2012-06-20 16:38:30 -070015163 __func__, retry_value);
15164 return -EINVAL;
15165 }
15166
15167 if (changed & WIPHY_PARAM_RETRY_SHORT)
15168 {
15169 if (0 != ccmCfgSetInt(hHal, WNI_CFG_LONG_RETRY_LIMIT,
15170 retry_value, ccmCfgSetCallback,
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015171 eANI_BOOLEAN_TRUE))
Jeff Johnson295189b2012-06-20 16:38:30 -070015172 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015173 hddLog(VOS_TRACE_LEVEL_ERROR,
15174 "%s: ccmCfgSetInt failed for long retry count %hu",
Jeff Johnson295189b2012-06-20 16:38:30 -070015175 __func__, retry_value);
15176 return -EIO;
15177 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015178 hddLog(VOS_TRACE_LEVEL_INFO_MED, "%s: set long retry count %hu",
Jeff Johnson295189b2012-06-20 16:38:30 -070015179 __func__, retry_value);
15180 }
15181 else if (changed & WIPHY_PARAM_RETRY_SHORT)
15182 {
15183 if (0 != ccmCfgSetInt(hHal, WNI_CFG_SHORT_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 short 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 short retry count %hu",
Jeff Johnson295189b2012-06-20 16:38:30 -070015193 __func__, retry_value);
15194 }
15195 }
15196
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053015197 EXIT();
Jeff Johnson295189b2012-06-20 16:38:30 -070015198 return 0;
15199}
15200
Mahesh A Saptasagar179d2252014-06-02 21:32:21 +053015201static int wlan_hdd_cfg80211_set_wiphy_params(struct wiphy *wiphy,
15202 u32 changed)
15203{
15204 int ret;
15205
15206 vos_ssr_protect(__func__);
15207 ret = __wlan_hdd_cfg80211_set_wiphy_params(wiphy, changed);
15208 vos_ssr_unprotect(__func__);
15209
15210 return ret;
15211}
15212
Jeff Johnson295189b2012-06-20 16:38:30 -070015213/*
Mahesh A Saptasagar179d2252014-06-02 21:32:21 +053015214 * FUNCTION: __wlan_hdd_cfg80211_set_txpower
Jeff Johnson295189b2012-06-20 16:38:30 -070015215 * This function is used to set the txpower
15216 */
Mahesh A Saptasagar179d2252014-06-02 21:32:21 +053015217static int __wlan_hdd_cfg80211_set_txpower(struct wiphy *wiphy,
Yue Maf49ba872013-08-19 12:04:25 -070015218#if LINUX_VERSION_CODE >= KERNEL_VERSION(3,8,0)
15219 struct wireless_dev *wdev,
15220#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070015221#if LINUX_VERSION_CODE <= KERNEL_VERSION(2,6,35)
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015222 enum tx_power_setting type,
Jeff Johnson295189b2012-06-20 16:38:30 -070015223#else
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015224 enum nl80211_tx_power_setting type,
Jeff Johnson295189b2012-06-20 16:38:30 -070015225#endif
15226 int dbm)
15227{
15228 hdd_context_t *pHddCtx = (hdd_context_t*) wiphy_priv(wiphy);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053015229 tHalHandle hHal = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -070015230 tSirMacAddr bssid = {0xFF,0xFF,0xFF,0xFF,0xFF,0xFF};
15231 tSirMacAddr selfMac = {0xFF,0xFF,0xFF,0xFF,0xFF,0xFF};
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053015232 int status;
Jeff Johnson295189b2012-06-20 16:38:30 -070015233
15234 ENTER();
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053015235
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053015236 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
15237 TRACE_CODE_HDD_CFG80211_SET_TXPOWER,
15238 NO_SESSION, type ));
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053015239 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053015240 if (0 != status)
15241 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053015242 return status;
15243 }
15244
15245 hHal = pHddCtx->hHal;
15246
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015247 if (0 != ccmCfgSetInt(hHal, WNI_CFG_CURRENT_TX_POWER_LEVEL,
15248 dbm, ccmCfgSetCallback,
15249 eANI_BOOLEAN_TRUE))
Jeff Johnson295189b2012-06-20 16:38:30 -070015250 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015251 hddLog(VOS_TRACE_LEVEL_ERROR,
Jeff Johnson295189b2012-06-20 16:38:30 -070015252 "%s: ccmCfgSetInt failed for tx power %hu", __func__, dbm);
15253 return -EIO;
15254 }
15255
15256 hddLog(VOS_TRACE_LEVEL_INFO_MED, "%s: set tx power level %d dbm", __func__,
15257 dbm);
15258
15259 switch(type)
15260 {
15261 case NL80211_TX_POWER_AUTOMATIC: /*automatically determine transmit power*/
15262 /* Fall through */
15263 case NL80211_TX_POWER_LIMITED: /*limit TX power by the mBm parameter*/
15264 if( sme_SetMaxTxPower(hHal, bssid, selfMac, dbm) != eHAL_STATUS_SUCCESS )
15265 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015266 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Setting maximum tx power failed",
15267 __func__);
15268 return -EIO;
Jeff Johnson295189b2012-06-20 16:38:30 -070015269 }
15270 break;
15271 case NL80211_TX_POWER_FIXED: /*fix TX power to the mBm parameter*/
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015272 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: NL80211_TX_POWER_FIXED not supported",
Jeff Johnson295189b2012-06-20 16:38:30 -070015273 __func__);
15274 return -EOPNOTSUPP;
15275 break;
15276 default:
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015277 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Invalid power setting type %d",
15278 __func__, type);
Jeff Johnson295189b2012-06-20 16:38:30 -070015279 return -EIO;
15280 }
15281
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053015282 EXIT();
Jeff Johnson295189b2012-06-20 16:38:30 -070015283 return 0;
15284}
15285
Mahesh A Saptasagar179d2252014-06-02 21:32:21 +053015286static int wlan_hdd_cfg80211_set_txpower(struct wiphy *wiphy,
15287#if LINUX_VERSION_CODE >= KERNEL_VERSION(3,8,0)
15288 struct wireless_dev *wdev,
15289#endif
15290#if LINUX_VERSION_CODE <= KERNEL_VERSION(2,6,35)
15291 enum tx_power_setting type,
15292#else
15293 enum nl80211_tx_power_setting type,
15294#endif
15295 int dbm)
15296{
15297 int ret;
15298 vos_ssr_protect(__func__);
15299 ret = __wlan_hdd_cfg80211_set_txpower(wiphy,
15300#if LINUX_VERSION_CODE >= KERNEL_VERSION(3,8,0)
15301 wdev,
15302#endif
15303#if LINUX_VERSION_CODE <= KERNEL_VERSION(2,6,35)
15304 type,
15305#else
15306 type,
15307#endif
15308 dbm);
15309 vos_ssr_unprotect(__func__);
15310
15311 return ret;
15312}
15313
Jeff Johnson295189b2012-06-20 16:38:30 -070015314/*
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053015315 * FUNCTION: __wlan_hdd_cfg80211_get_txpower
Jeff Johnson295189b2012-06-20 16:38:30 -070015316 * This function is used to read the txpower
15317 */
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053015318static int __wlan_hdd_cfg80211_get_txpower(struct wiphy *wiphy,
Yue Maf49ba872013-08-19 12:04:25 -070015319#if LINUX_VERSION_CODE >= KERNEL_VERSION(3,8,0)
15320 struct wireless_dev *wdev,
15321#endif
15322 int *dbm)
Jeff Johnson295189b2012-06-20 16:38:30 -070015323{
15324
15325 hdd_adapter_t *pAdapter;
15326 hdd_context_t *pHddCtx = (hdd_context_t*) wiphy_priv(wiphy);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053015327 int status;
Jeff Johnson295189b2012-06-20 16:38:30 -070015328
Jeff Johnsone7245742012-09-05 17:12:55 -070015329 ENTER();
15330
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053015331 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053015332 if (0 != status)
Jeff Johnson04dd8a82012-06-29 20:41:40 -070015333 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053015334 *dbm = 0;
15335 return status;
Jeff Johnson04dd8a82012-06-29 20:41:40 -070015336 }
15337
Jeff Johnson295189b2012-06-20 16:38:30 -070015338 pAdapter = hdd_get_adapter(pHddCtx, WLAN_HDD_INFRA_STATION);
15339 if (NULL == pAdapter)
15340 {
15341 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: Not in station context " ,__func__);
15342 return -ENOENT;
15343 }
15344
Konamki, Sreelakshmi7b464be2015-07-14 12:17:01 +053015345 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
15346 TRACE_CODE_HDD_CFG80211_GET_TXPOWER,
15347 pAdapter->sessionId, pAdapter->device_mode));
Jeff Johnson295189b2012-06-20 16:38:30 -070015348 wlan_hdd_get_classAstats(pAdapter);
15349 *dbm = pAdapter->hdd_stats.ClassA_stat.max_pwr;
15350
Jeff Johnsone7245742012-09-05 17:12:55 -070015351 EXIT();
Jeff Johnson295189b2012-06-20 16:38:30 -070015352 return 0;
15353}
15354
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053015355static int wlan_hdd_cfg80211_get_txpower(struct wiphy *wiphy,
15356#if LINUX_VERSION_CODE >= KERNEL_VERSION(3,8,0)
15357 struct wireless_dev *wdev,
15358#endif
15359 int *dbm)
15360{
15361 int ret;
15362
15363 vos_ssr_protect(__func__);
15364 ret = __wlan_hdd_cfg80211_get_txpower(wiphy,
15365#if LINUX_VERSION_CODE >= KERNEL_VERSION(3,8,0)
15366 wdev,
15367#endif
15368 dbm);
15369 vos_ssr_unprotect(__func__);
15370
15371 return ret;
15372}
15373
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053015374static int __wlan_hdd_cfg80211_get_station(struct wiphy *wiphy, struct net_device *dev,
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053015375#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,18,0))
15376 const u8* mac,
15377#else
15378 u8* mac,
15379#endif
15380 struct station_info *sinfo)
Jeff Johnson295189b2012-06-20 16:38:30 -070015381{
15382 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( dev );
15383 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
15384 int ssidlen = pHddStaCtx->conn_info.SSID.SSID.length;
c_hpothu44ff4e02014-05-08 00:13:57 +053015385 tANI_U32 rate_flags;
Jeff Johnson295189b2012-06-20 16:38:30 -070015386
15387 hdd_context_t *pHddCtx = (hdd_context_t*) wiphy_priv(wiphy);
15388 hdd_config_t *pCfg = pHddCtx->cfg_ini;
Jeff Johnson295189b2012-06-20 16:38:30 -070015389
15390 tANI_U8 OperationalRates[CSR_DOT11_SUPPORTED_RATES_MAX];
15391 tANI_U32 ORLeng = CSR_DOT11_SUPPORTED_RATES_MAX;
15392 tANI_U8 ExtendedRates[CSR_DOT11_EXTENDED_SUPPORTED_RATES_MAX];
15393 tANI_U32 ERLeng = CSR_DOT11_EXTENDED_SUPPORTED_RATES_MAX;
15394 tANI_U8 MCSRates[SIZE_OF_BASIC_MCS_SET];
15395 tANI_U32 MCSLeng = SIZE_OF_BASIC_MCS_SET;
15396 tANI_U16 maxRate = 0;
15397 tANI_U16 myRate;
15398 tANI_U16 currentRate = 0;
15399 tANI_U8 maxSpeedMCS = 0;
15400 tANI_U8 maxMCSIdx = 0;
15401 tANI_U8 rateFlag = 1;
c_hpothu79aab322014-07-14 21:11:01 +053015402 tANI_U8 i, j, rssidx, mode=0;
Madan Mohan Koyyalamudic75be962012-10-18 19:19:03 -070015403 tANI_U16 temp;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053015404 int status;
Jeff Johnson295189b2012-06-20 16:38:30 -070015405
Leo Chang6f8870f2013-03-26 18:11:36 -070015406#ifdef WLAN_FEATURE_11AC
15407 tANI_U32 vht_mcs_map;
15408 eDataRate11ACMaxMcs vhtMaxMcs;
15409#endif /* WLAN_FEATURE_11AC */
15410
Jeff Johnsone7245742012-09-05 17:12:55 -070015411 ENTER();
15412
Jeff Johnson295189b2012-06-20 16:38:30 -070015413 if ((eConnectionState_Associated != pHddStaCtx->conn_info.connState) ||
15414 (0 == ssidlen))
15415 {
15416 hddLog(VOS_TRACE_LEVEL_INFO, "%s: Not associated or"
15417 " Invalid ssidlen, %d", __func__, ssidlen);
15418 /*To keep GUI happy*/
15419 return 0;
15420 }
15421
Mukul Sharma811205f2014-07-09 21:07:30 +053015422 if (VOS_TRUE == pHddStaCtx->hdd_ReassocScenario)
15423 {
15424 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
15425 "%s: Roaming in progress, so unable to proceed this request", __func__);
15426 return 0;
15427 }
15428
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053015429 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053015430 if (0 != status)
Jeff Johnson04dd8a82012-06-29 20:41:40 -070015431 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053015432 return status;
Jeff Johnson04dd8a82012-06-29 20:41:40 -070015433 }
15434
Hanumantha Reddy Pothuladce66742015-08-25 18:08:44 +053015435 wlan_hdd_get_station_stats(pAdapter);
15436 rate_flags = pAdapter->hdd_stats.ClassA_stat.tx_rate_flags;
Jeff Johnson295189b2012-06-20 16:38:30 -070015437
Kiet Lam3b17fc82013-09-27 05:24:08 +053015438 wlan_hdd_get_rssi(pAdapter, &sinfo->signal);
15439 sinfo->filled |= STATION_INFO_SIGNAL;
15440
c_hpothu09f19542014-05-30 21:53:31 +053015441 /*overwrite rate_flags if MAX link-speed need to be reported*/
c_hpothu44ff4e02014-05-08 00:13:57 +053015442 if ((eHDD_LINK_SPEED_REPORT_MAX == pCfg->reportMaxLinkSpeed) ||
15443 (eHDD_LINK_SPEED_REPORT_MAX_SCALED == pCfg->reportMaxLinkSpeed &&
c_hpothu79aab322014-07-14 21:11:01 +053015444 sinfo->signal >= pCfg->linkSpeedRssiLow))
c_hpothu44ff4e02014-05-08 00:13:57 +053015445 {
15446 rate_flags = pAdapter->maxRateFlags;
15447 }
c_hpothu44ff4e02014-05-08 00:13:57 +053015448
Jeff Johnson295189b2012-06-20 16:38:30 -070015449 //convert to the UI units of 100kbps
15450 myRate = pAdapter->hdd_stats.ClassA_stat.tx_rate * 5;
15451
15452#ifdef LINKSPEED_DEBUG_ENABLED
Leo Chang6f8870f2013-03-26 18:11:36 -070015453 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 -070015454 sinfo->signal,
15455 pCfg->reportMaxLinkSpeed,
15456 myRate,
15457 (int) pCfg->linkSpeedRssiHigh,
Madan Mohan Koyyalamudi8df78d52012-11-02 12:30:06 -070015458 (int) pCfg->linkSpeedRssiMid,
15459 (int) pCfg->linkSpeedRssiLow,
Leo Chang6f8870f2013-03-26 18:11:36 -070015460 (int) rate_flags,
15461 (int) pAdapter->hdd_stats.ClassA_stat.mcs_index);
Jeff Johnson295189b2012-06-20 16:38:30 -070015462#endif //LINKSPEED_DEBUG_ENABLED
15463
15464 if (eHDD_LINK_SPEED_REPORT_ACTUAL != pCfg->reportMaxLinkSpeed)
15465 {
15466 // we do not want to necessarily report the current speed
15467 if (eHDD_LINK_SPEED_REPORT_MAX == pCfg->reportMaxLinkSpeed)
15468 {
15469 // report the max possible speed
15470 rssidx = 0;
15471 }
15472 else if (eHDD_LINK_SPEED_REPORT_MAX_SCALED == pCfg->reportMaxLinkSpeed)
15473 {
15474 // report the max possible speed with RSSI scaling
15475 if (sinfo->signal >= pCfg->linkSpeedRssiHigh)
15476 {
15477 // report the max possible speed
15478 rssidx = 0;
15479 }
Madan Mohan Koyyalamudi8df78d52012-11-02 12:30:06 -070015480 else if (sinfo->signal >= pCfg->linkSpeedRssiMid)
Jeff Johnson295189b2012-06-20 16:38:30 -070015481 {
15482 // report middle speed
15483 rssidx = 1;
15484 }
Madan Mohan Koyyalamudi8df78d52012-11-02 12:30:06 -070015485 else if (sinfo->signal >= pCfg->linkSpeedRssiLow)
15486 {
15487 // report middle speed
15488 rssidx = 2;
15489 }
Jeff Johnson295189b2012-06-20 16:38:30 -070015490 else
15491 {
15492 // report actual speed
Madan Mohan Koyyalamudi8df78d52012-11-02 12:30:06 -070015493 rssidx = 3;
Jeff Johnson295189b2012-06-20 16:38:30 -070015494 }
15495 }
15496 else
15497 {
15498 // unknown, treat as eHDD_LINK_SPEED_REPORT_MAX
15499 hddLog(VOS_TRACE_LEVEL_ERROR,
15500 "%s: Invalid value for reportMaxLinkSpeed: %u",
15501 __func__, pCfg->reportMaxLinkSpeed);
15502 rssidx = 0;
15503 }
15504
15505 maxRate = 0;
15506
15507 /* Get Basic Rate Set */
Gopichand Nakkala05ab1322013-02-15 11:28:38 +053015508 if (0 != ccmCfgGetStr(WLAN_HDD_GET_HAL_CTX(pAdapter), WNI_CFG_OPERATIONAL_RATE_SET,
15509 OperationalRates, &ORLeng))
15510 {
15511 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: ccm api returned failure", __func__);
15512 /*To keep GUI happy*/
15513 return 0;
15514 }
15515
Jeff Johnson295189b2012-06-20 16:38:30 -070015516 for (i = 0; i < ORLeng; i++)
15517 {
Jeff Johnsone7245742012-09-05 17:12:55 -070015518 for (j = 0; j < (sizeof(supported_data_rate) / sizeof(supported_data_rate[0])); j ++)
Jeff Johnson295189b2012-06-20 16:38:30 -070015519 {
15520 /* Validate Rate Set */
15521 if (supported_data_rate[j].beacon_rate_index == (OperationalRates[i] & 0x7F))
15522 {
15523 currentRate = supported_data_rate[j].supported_rate[rssidx];
15524 break;
15525 }
15526 }
15527 /* Update MAX rate */
15528 maxRate = (currentRate > maxRate)?currentRate:maxRate;
15529 }
15530
15531 /* Get Extended Rate Set */
Gopichand Nakkala05ab1322013-02-15 11:28:38 +053015532 if (0 != ccmCfgGetStr(WLAN_HDD_GET_HAL_CTX(pAdapter), WNI_CFG_EXTENDED_OPERATIONAL_RATE_SET,
15533 ExtendedRates, &ERLeng))
15534 {
15535 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: ccm api returned failure", __func__);
15536 /*To keep GUI happy*/
15537 return 0;
15538 }
15539
Jeff Johnson295189b2012-06-20 16:38:30 -070015540 for (i = 0; i < ERLeng; i++)
15541 {
Jeff Johnsone7245742012-09-05 17:12:55 -070015542 for (j = 0; j < (sizeof(supported_data_rate) / sizeof(supported_data_rate[0])); j ++)
Jeff Johnson295189b2012-06-20 16:38:30 -070015543 {
15544 if (supported_data_rate[j].beacon_rate_index == (ExtendedRates[i] & 0x7F))
15545 {
15546 currentRate = supported_data_rate[j].supported_rate[rssidx];
15547 break;
15548 }
15549 }
15550 /* Update MAX rate */
15551 maxRate = (currentRate > maxRate)?currentRate:maxRate;
15552 }
c_hpothu79aab322014-07-14 21:11:01 +053015553
Kiet Lamb69f8dc2013-11-15 15:34:27 +053015554 /* Get MCS Rate Set --
Kaushik, Sushantdc304d82014-01-22 10:58:37 +053015555 Only if we are always reporting max speed (or)
Kiet Lamb69f8dc2013-11-15 15:34:27 +053015556 if we have good rssi */
c_hpothu79aab322014-07-14 21:11:01 +053015557 if ((3 != rssidx) && !(rate_flags & eHAL_TX_RATE_LEGACY))
Jeff Johnson295189b2012-06-20 16:38:30 -070015558 {
c_hpothu79aab322014-07-14 21:11:01 +053015559 if (rate_flags & eHAL_TX_RATE_VHT80)
15560 mode = 2;
15561 else if (rate_flags & (eHAL_TX_RATE_VHT40 | eHAL_TX_RATE_HT40))
15562 mode = 1;
15563 else
15564 mode = 0;
15565
Gopichand Nakkala05ab1322013-02-15 11:28:38 +053015566 if (0 != ccmCfgGetStr(WLAN_HDD_GET_HAL_CTX(pAdapter), WNI_CFG_CURRENT_MCS_SET,
15567 MCSRates, &MCSLeng))
15568 {
15569 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: ccm api returned failure", __func__);
15570 /*To keep GUI happy*/
15571 return 0;
15572 }
Jeff Johnson295189b2012-06-20 16:38:30 -070015573 rateFlag = 0;
Leo Chang6f8870f2013-03-26 18:11:36 -070015574#ifdef WLAN_FEATURE_11AC
15575 /* VHT80 rate has seperate rate table */
Gopichand Nakkala4c705372013-04-24 13:20:33 +053015576 if (rate_flags & (eHAL_TX_RATE_VHT20|eHAL_TX_RATE_VHT40|eHAL_TX_RATE_VHT80))
Jeff Johnson295189b2012-06-20 16:38:30 -070015577 {
Leo Chang6f8870f2013-03-26 18:11:36 -070015578 ccmCfgGetInt(WLAN_HDD_GET_HAL_CTX(pAdapter), WNI_CFG_VHT_TX_MCS_MAP, &vht_mcs_map);
Gopichand Nakkala4c705372013-04-24 13:20:33 +053015579 vhtMaxMcs = (eDataRate11ACMaxMcs)(vht_mcs_map & DATA_RATE_11AC_MCS_MASK );
Leo Chang6f8870f2013-03-26 18:11:36 -070015580 if (rate_flags & eHAL_TX_RATE_SGI)
Jeff Johnson295189b2012-06-20 16:38:30 -070015581 {
Leo Chang6f8870f2013-03-26 18:11:36 -070015582 rateFlag |= 1;
Jeff Johnson295189b2012-06-20 16:38:30 -070015583 }
Leo Chang6f8870f2013-03-26 18:11:36 -070015584 if (DATA_RATE_11AC_MAX_MCS_7 == vhtMaxMcs)
Jeff Johnson295189b2012-06-20 16:38:30 -070015585 {
Leo Chang6f8870f2013-03-26 18:11:36 -070015586 maxMCSIdx = 7;
15587 }
15588 else if (DATA_RATE_11AC_MAX_MCS_8 == vhtMaxMcs)
15589 {
15590 maxMCSIdx = 8;
15591 }
15592 else if (DATA_RATE_11AC_MAX_MCS_9 == vhtMaxMcs)
15593 {
Gopichand Nakkala4c705372013-04-24 13:20:33 +053015594 //VHT20 is supporting 0~8
15595 if (rate_flags & eHAL_TX_RATE_VHT20)
15596 maxMCSIdx = 8;
15597 else
15598 maxMCSIdx = 9;
Leo Chang6f8870f2013-03-26 18:11:36 -070015599 }
Gopichand Nakkala4c705372013-04-24 13:20:33 +053015600
c_hpothu79aab322014-07-14 21:11:01 +053015601 if (0 != rssidx)/*check for scaled */
15602 {
15603 //get middle rate MCS index if rssi=1/2
15604 for (i=0; i <= maxMCSIdx; i++)
15605 {
15606 if (sinfo->signal <= rssiMcsTbl[mode][i])
15607 {
15608 maxMCSIdx = i;
15609 break;
15610 }
15611 }
15612 }
15613
Gopichand Nakkala4c705372013-04-24 13:20:33 +053015614 if (rate_flags & eHAL_TX_RATE_VHT80)
15615 {
15616 currentRate = supported_vht_mcs_rate[pAdapter->hdd_stats.ClassA_stat.mcs_index].supported_VHT80_rate[rateFlag];
15617 maxRate = supported_vht_mcs_rate[maxMCSIdx].supported_VHT80_rate[rateFlag];
15618 }
15619 else if (rate_flags & eHAL_TX_RATE_VHT40)
15620 {
15621 currentRate = supported_vht_mcs_rate[pAdapter->hdd_stats.ClassA_stat.mcs_index].supported_VHT40_rate[rateFlag];
15622 maxRate = supported_vht_mcs_rate[maxMCSIdx].supported_VHT40_rate[rateFlag];
15623 }
15624 else if (rate_flags & eHAL_TX_RATE_VHT20)
15625 {
15626 currentRate = supported_vht_mcs_rate[pAdapter->hdd_stats.ClassA_stat.mcs_index].supported_VHT20_rate[rateFlag];
15627 maxRate = supported_vht_mcs_rate[maxMCSIdx].supported_VHT20_rate[rateFlag];
15628 }
15629
Leo Chang6f8870f2013-03-26 18:11:36 -070015630 maxSpeedMCS = 1;
15631 if (currentRate > maxRate)
15632 {
15633 maxRate = currentRate;
15634 }
Gopichand Nakkala4c705372013-04-24 13:20:33 +053015635
Leo Chang6f8870f2013-03-26 18:11:36 -070015636 }
15637 else
15638#endif /* WLAN_FEATURE_11AC */
15639 {
15640 if (rate_flags & eHAL_TX_RATE_HT40)
15641 {
15642 rateFlag |= 1;
15643 }
15644 if (rate_flags & eHAL_TX_RATE_SGI)
15645 {
15646 rateFlag |= 2;
15647 }
15648
Girish Gowli01abcee2014-07-31 20:18:55 +053015649 temp = sizeof(supported_mcs_rate) / sizeof(supported_mcs_rate[0]);
c_hpothu79aab322014-07-14 21:11:01 +053015650 if (rssidx == 1 || rssidx == 2)
15651 {
15652 //get middle rate MCS index if rssi=1/2
15653 for (i=0; i <= 7; i++)
15654 {
15655 if (sinfo->signal <= rssiMcsTbl[mode][i])
15656 {
15657 temp = i+1;
15658 break;
15659 }
15660 }
15661 }
c_hpothu79aab322014-07-14 21:11:01 +053015662
15663 for (i = 0; i < MCSLeng; i++)
15664 {
Leo Chang6f8870f2013-03-26 18:11:36 -070015665 for (j = 0; j < temp; j++)
15666 {
15667 if (supported_mcs_rate[j].beacon_rate_index == MCSRates[i])
15668 {
15669 currentRate = supported_mcs_rate[j].supported_rate[rateFlag];
Hanumantha Reddy Pothulafa623742015-06-16 14:08:24 +053015670 maxMCSIdx = supported_mcs_rate[j].beacon_rate_index;
Leo Chang6f8870f2013-03-26 18:11:36 -070015671 break;
15672 }
15673 }
15674 if ((j < temp) && (currentRate > maxRate))
15675 {
15676 maxRate = currentRate;
Leo Chang6f8870f2013-03-26 18:11:36 -070015677 }
Jeff Johnson295189b2012-06-20 16:38:30 -070015678 }
Hanumantha Reddy Pothulafa623742015-06-16 14:08:24 +053015679 maxSpeedMCS = 1;
Jeff Johnson295189b2012-06-20 16:38:30 -070015680 }
15681 }
15682
Gopichand Nakkala4c705372013-04-24 13:20:33 +053015683 else if (!(rate_flags & eHAL_TX_RATE_LEGACY))
15684 {
15685 maxRate = myRate;
15686 maxSpeedMCS = 1;
15687 maxMCSIdx = pAdapter->hdd_stats.ClassA_stat.mcs_index;
15688 }
Jeff Johnson295189b2012-06-20 16:38:30 -070015689 // make sure we report a value at least as big as our current rate
c_hpothu79aab322014-07-14 21:11:01 +053015690 if ((maxRate < myRate) || (0 == maxRate))
Jeff Johnson295189b2012-06-20 16:38:30 -070015691 {
15692 maxRate = myRate;
15693 if (rate_flags & eHAL_TX_RATE_LEGACY)
15694 {
15695 maxSpeedMCS = 0;
15696 }
15697 else
15698 {
15699 maxSpeedMCS = 1;
15700 maxMCSIdx = pAdapter->hdd_stats.ClassA_stat.mcs_index;
15701 }
15702 }
15703
Gopichand Nakkala4c705372013-04-24 13:20:33 +053015704 if (rate_flags & eHAL_TX_RATE_LEGACY)
Jeff Johnson295189b2012-06-20 16:38:30 -070015705 {
15706 sinfo->txrate.legacy = maxRate;
15707#ifdef LINKSPEED_DEBUG_ENABLED
15708 pr_info("Reporting legacy rate %d\n", sinfo->txrate.legacy);
15709#endif //LINKSPEED_DEBUG_ENABLED
15710 }
15711 else
15712 {
15713 sinfo->txrate.mcs = maxMCSIdx;
Leo Chang6f8870f2013-03-26 18:11:36 -070015714#ifdef WLAN_FEATURE_11AC
15715 sinfo->txrate.nss = 1;
15716 if (rate_flags & eHAL_TX_RATE_VHT80)
15717 {
15718 sinfo->txrate.flags |= RATE_INFO_FLAGS_VHT_MCS;
Gopichand Nakkala4c705372013-04-24 13:20:33 +053015719 sinfo->txrate.flags |= RATE_INFO_FLAGS_80_MHZ_WIDTH;
Leo Chang6f8870f2013-03-26 18:11:36 -070015720 }
Gopichand Nakkala4c705372013-04-24 13:20:33 +053015721 else if (rate_flags & eHAL_TX_RATE_VHT40)
Leo Chang6f8870f2013-03-26 18:11:36 -070015722 {
Gopichand Nakkala4c705372013-04-24 13:20:33 +053015723 sinfo->txrate.flags |= RATE_INFO_FLAGS_VHT_MCS;
15724 sinfo->txrate.flags |= RATE_INFO_FLAGS_40_MHZ_WIDTH;
15725 }
15726 else if (rate_flags & eHAL_TX_RATE_VHT20)
15727 {
15728 sinfo->txrate.flags |= RATE_INFO_FLAGS_VHT_MCS;
15729 }
15730#endif /* WLAN_FEATURE_11AC */
15731 if (rate_flags & (eHAL_TX_RATE_HT20 | eHAL_TX_RATE_HT40))
15732 {
15733 sinfo->txrate.flags |= RATE_INFO_FLAGS_MCS;
15734 if (rate_flags & eHAL_TX_RATE_HT40)
15735 {
15736 sinfo->txrate.flags |= RATE_INFO_FLAGS_40_MHZ_WIDTH;
15737 }
Leo Chang6f8870f2013-03-26 18:11:36 -070015738 }
Jeff Johnson295189b2012-06-20 16:38:30 -070015739 if (rate_flags & eHAL_TX_RATE_SGI)
15740 {
15741 sinfo->txrate.flags |= RATE_INFO_FLAGS_SHORT_GI;
15742 }
Gopichand Nakkala4c705372013-04-24 13:20:33 +053015743
Jeff Johnson295189b2012-06-20 16:38:30 -070015744#ifdef LINKSPEED_DEBUG_ENABLED
15745 pr_info("Reporting MCS rate %d flags %x\n",
15746 sinfo->txrate.mcs,
15747 sinfo->txrate.flags );
15748#endif //LINKSPEED_DEBUG_ENABLED
15749 }
15750 }
15751 else
15752 {
15753 // report current rate instead of max rate
15754
15755 if (rate_flags & eHAL_TX_RATE_LEGACY)
15756 {
15757 //provide to the UI in units of 100kbps
15758 sinfo->txrate.legacy = myRate;
15759#ifdef LINKSPEED_DEBUG_ENABLED
15760 pr_info("Reporting actual legacy rate %d\n", sinfo->txrate.legacy);
15761#endif //LINKSPEED_DEBUG_ENABLED
15762 }
15763 else
15764 {
15765 //must be MCS
15766 sinfo->txrate.mcs = pAdapter->hdd_stats.ClassA_stat.mcs_index;
Leo Chang6f8870f2013-03-26 18:11:36 -070015767#ifdef WLAN_FEATURE_11AC
15768 sinfo->txrate.nss = 1;
15769 if (rate_flags & eHAL_TX_RATE_VHT80)
15770 {
15771 sinfo->txrate.flags |= RATE_INFO_FLAGS_VHT_MCS;
15772 }
15773 else
15774#endif /* WLAN_FEATURE_11AC */
15775 {
15776 sinfo->txrate.flags |= RATE_INFO_FLAGS_MCS;
15777 }
Jeff Johnson295189b2012-06-20 16:38:30 -070015778 if (rate_flags & eHAL_TX_RATE_SGI)
15779 {
15780 sinfo->txrate.flags |= RATE_INFO_FLAGS_SHORT_GI;
15781 }
15782 if (rate_flags & eHAL_TX_RATE_HT40)
15783 {
15784 sinfo->txrate.flags |= RATE_INFO_FLAGS_40_MHZ_WIDTH;
15785 }
Leo Chang6f8870f2013-03-26 18:11:36 -070015786#ifdef WLAN_FEATURE_11AC
15787 else if (rate_flags & eHAL_TX_RATE_VHT80)
15788 {
15789 sinfo->txrate.flags |= RATE_INFO_FLAGS_80_MHZ_WIDTH;
15790 }
15791#endif /* WLAN_FEATURE_11AC */
Jeff Johnson295189b2012-06-20 16:38:30 -070015792#ifdef LINKSPEED_DEBUG_ENABLED
15793 pr_info("Reporting actual MCS rate %d flags %x\n",
15794 sinfo->txrate.mcs,
15795 sinfo->txrate.flags );
15796#endif //LINKSPEED_DEBUG_ENABLED
15797 }
15798 }
15799 sinfo->filled |= STATION_INFO_TX_BITRATE;
15800
Madan Mohan Koyyalamudi4d4d2812012-09-24 14:08:29 -070015801 sinfo->tx_packets =
15802 pAdapter->hdd_stats.summary_stat.tx_frm_cnt[0] +
15803 pAdapter->hdd_stats.summary_stat.tx_frm_cnt[1] +
15804 pAdapter->hdd_stats.summary_stat.tx_frm_cnt[2] +
15805 pAdapter->hdd_stats.summary_stat.tx_frm_cnt[3];
15806
15807 sinfo->tx_retries =
15808 pAdapter->hdd_stats.summary_stat.retry_cnt[0] +
15809 pAdapter->hdd_stats.summary_stat.retry_cnt[1] +
15810 pAdapter->hdd_stats.summary_stat.retry_cnt[2] +
15811 pAdapter->hdd_stats.summary_stat.retry_cnt[3];
15812
15813 sinfo->tx_failed =
15814 pAdapter->hdd_stats.summary_stat.fail_cnt[0] +
15815 pAdapter->hdd_stats.summary_stat.fail_cnt[1] +
15816 pAdapter->hdd_stats.summary_stat.fail_cnt[2] +
15817 pAdapter->hdd_stats.summary_stat.fail_cnt[3];
15818
15819 sinfo->filled |=
15820 STATION_INFO_TX_PACKETS |
15821 STATION_INFO_TX_RETRIES |
15822 STATION_INFO_TX_FAILED;
15823
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053015824 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
15825 TRACE_CODE_HDD_CFG80211_GET_STA,
15826 pAdapter->sessionId, maxRate));
Madan Mohan Koyyalamudi4d4d2812012-09-24 14:08:29 -070015827 EXIT();
15828 return 0;
Jeff Johnson295189b2012-06-20 16:38:30 -070015829}
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053015830#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,16,0))
15831static int wlan_hdd_cfg80211_get_station(struct wiphy *wiphy, struct net_device *dev,
15832 const u8* mac, struct station_info *sinfo)
15833#else
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053015834static int wlan_hdd_cfg80211_get_station(struct wiphy *wiphy, struct net_device *dev,
15835 u8* mac, struct station_info *sinfo)
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053015836#endif
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053015837{
15838 int ret;
15839
15840 vos_ssr_protect(__func__);
15841 ret = __wlan_hdd_cfg80211_get_station(wiphy, dev, mac, sinfo);
15842 vos_ssr_unprotect(__func__);
15843
15844 return ret;
15845}
15846
15847static int __wlan_hdd_cfg80211_set_power_mgmt(struct wiphy *wiphy,
Sameer Thalappilc9f26e92013-06-07 10:11:06 -070015848 struct net_device *dev, bool mode, int timeout)
Jeff Johnson295189b2012-06-20 16:38:30 -070015849{
15850 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
Gopichand Nakkala20c4c042013-04-19 22:08:55 +053015851 hdd_context_t *pHddCtx;
Jeff Johnson295189b2012-06-20 16:38:30 -070015852 VOS_STATUS vos_status;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053015853 int status;
Jeff Johnson295189b2012-06-20 16:38:30 -070015854
Jeff Johnsone7245742012-09-05 17:12:55 -070015855 ENTER();
15856
Jeff Johnson295189b2012-06-20 16:38:30 -070015857 if (NULL == pAdapter)
15858 {
Arif Hussain6d2a3322013-11-17 19:50:10 -080015859 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Adapter is NULL", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -070015860 return -ENODEV;
15861 }
15862
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053015863 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
15864 TRACE_CODE_HDD_CFG80211_SET_POWER_MGMT,
15865 pAdapter->sessionId, timeout));
15866
Gopichand Nakkala20c4c042013-04-19 22:08:55 +053015867 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053015868 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053015869 if (0 != status)
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015870 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053015871 return status;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015872 }
15873
Gopichand Nakkala20c4c042013-04-19 22:08:55 +053015874 if ((DRIVER_POWER_MODE_AUTO == !mode) &&
15875 (TRUE == pHddCtx->hdd_wlan_suspended) &&
15876 (pHddCtx->cfg_ini->fhostArpOffload) &&
15877 (eConnectionState_Associated ==
15878 (WLAN_HDD_GET_STATION_CTX_PTR(pAdapter))->conn_info.connState))
15879 {
Amar Singhald53568e2013-09-26 11:03:45 -070015880
15881 hddLog(VOS_TRACE_LEVEL_INFO,
15882 "offload: in cfg80211_set_power_mgmt, calling arp offload");
Gopichand Nakkalab03e8082013-05-30 18:09:25 +053015883 vos_status = hdd_conf_arp_offload(pAdapter, TRUE);
Gopichand Nakkala20c4c042013-04-19 22:08:55 +053015884 if (!VOS_IS_STATUS_SUCCESS(vos_status))
15885 {
15886 hddLog(VOS_TRACE_LEVEL_INFO,
Arif Hussain6d2a3322013-11-17 19:50:10 -080015887 "%s:Failed to enable ARPOFFLOAD Feature %d",
Gopichand Nakkala20c4c042013-04-19 22:08:55 +053015888 __func__, vos_status);
15889 }
15890 }
15891
Jeff Johnson295189b2012-06-20 16:38:30 -070015892 /**The get power cmd from the supplicant gets updated by the nl only
15893 *on successful execution of the function call
15894 *we are oppositely mapped w.r.t mode in the driver
15895 **/
15896 vos_status = wlan_hdd_enter_bmps(pAdapter, !mode);
15897
15898 if (VOS_STATUS_E_FAILURE == vos_status)
15899 {
c_hpothu6ff1c3c2013-10-01 19:01:57 +053015900 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
15901 "%s: failed to enter bmps mode", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -070015902 return -EINVAL;
15903 }
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053015904 EXIT();
Jeff Johnson295189b2012-06-20 16:38:30 -070015905 return 0;
15906}
15907
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053015908static int wlan_hdd_cfg80211_set_power_mgmt(struct wiphy *wiphy,
15909 struct net_device *dev, bool mode, int timeout)
15910{
15911 int ret;
Jeff Johnson295189b2012-06-20 16:38:30 -070015912
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053015913 vos_ssr_protect(__func__);
15914 ret = __wlan_hdd_cfg80211_set_power_mgmt(wiphy, dev, mode, timeout);
15915 vos_ssr_unprotect(__func__);
15916
15917 return ret;
15918}
Sushant Kaushik084f6592015-09-10 13:11:56 +053015919
Jeff Johnson295189b2012-06-20 16:38:30 -070015920#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053015921static int __wlan_hdd_set_default_mgmt_key(struct wiphy *wiphy,
15922 struct net_device *netdev,
15923 u8 key_index)
15924{
15925 ENTER();
15926 return 0;
15927}
15928
Jeff Johnson295189b2012-06-20 16:38:30 -070015929static int wlan_hdd_set_default_mgmt_key(struct wiphy *wiphy,
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053015930 struct net_device *netdev,
15931 u8 key_index)
15932{
15933 int ret;
15934 vos_ssr_protect(__func__);
15935 ret = __wlan_hdd_set_default_mgmt_key(wiphy, netdev, key_index);
15936 vos_ssr_unprotect(__func__);
15937 return ret;
15938}
15939#endif //LINUX_VERSION_CODE
15940
15941#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,4,0))
15942static int __wlan_hdd_set_txq_params(struct wiphy *wiphy,
15943 struct net_device *dev,
15944 struct ieee80211_txq_params *params)
15945{
15946 ENTER();
15947 return 0;
15948}
15949#elif (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
15950static int __wlan_hdd_set_txq_params(struct wiphy *wiphy,
15951 struct ieee80211_txq_params *params)
Jeff Johnson295189b2012-06-20 16:38:30 -070015952{
Jeff Johnsone7245742012-09-05 17:12:55 -070015953 ENTER();
Jeff Johnson295189b2012-06-20 16:38:30 -070015954 return 0;
15955}
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015956#endif //LINUX_VERSION_CODE
Jeff Johnson295189b2012-06-20 16:38:30 -070015957
15958#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,4,0))
15959static int wlan_hdd_set_txq_params(struct wiphy *wiphy,
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053015960 struct net_device *dev,
15961 struct ieee80211_txq_params *params)
Jeff Johnson295189b2012-06-20 16:38:30 -070015962{
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053015963 int ret;
15964
15965 vos_ssr_protect(__func__);
15966 ret = __wlan_hdd_set_txq_params(wiphy, dev, params);
15967 vos_ssr_unprotect(__func__);
15968 return ret;
Jeff Johnson295189b2012-06-20 16:38:30 -070015969}
15970#elif (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
15971static int wlan_hdd_set_txq_params(struct wiphy *wiphy,
15972 struct ieee80211_txq_params *params)
15973{
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053015974 int ret;
15975
15976 vos_ssr_protect(__func__);
15977 ret = __wlan_hdd_set_txq_params(wiphy, params);
15978 vos_ssr_unprotect(__func__);
15979 return ret;
Jeff Johnson295189b2012-06-20 16:38:30 -070015980}
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053015981#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070015982
Naresh Jayaram69e3f282014-10-14 12:29:12 +053015983static int __wlan_hdd_cfg80211_del_station(struct wiphy *wiphy,
Hanumantha Reddy Pothulabfd06f72014-10-31 14:03:37 +053015984 struct net_device *dev,
15985 struct tagCsrDelStaParams *pDelStaParams)
Jeff Johnson295189b2012-06-20 16:38:30 -070015986{
15987 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053015988 hdd_context_t *pHddCtx;
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -080015989 VOS_STATUS vos_status;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053015990 int status;
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -080015991 v_U8_t staId;
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +053015992 v_CONTEXT_t pVosContext = NULL;
15993 ptSapContext pSapCtx = NULL;
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053015994
Jeff Johnsone7245742012-09-05 17:12:55 -070015995 ENTER();
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053015996
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053015997 if ( NULL == pAdapter )
Jeff Johnson295189b2012-06-20 16:38:30 -070015998 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053015999 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Invalid Adapter" ,__func__);
Jeff Johnson295189b2012-06-20 16:38:30 -070016000 return -EINVAL;
16001 }
16002
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053016003 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
16004 TRACE_CODE_HDD_CFG80211_DEL_STA,
16005 pAdapter->sessionId, pAdapter->device_mode));
16006
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053016007 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
16008 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053016009 if (0 != status)
Jeff Johnson04dd8a82012-06-29 20:41:40 -070016010 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053016011 return status;
Jeff Johnson04dd8a82012-06-29 20:41:40 -070016012 }
16013
Jeff Johnson295189b2012-06-20 16:38:30 -070016014 if ( (WLAN_HDD_SOFTAP == pAdapter->device_mode)
Jeff Johnson295189b2012-06-20 16:38:30 -070016015 || (WLAN_HDD_P2P_GO == pAdapter->device_mode)
Jeff Johnson295189b2012-06-20 16:38:30 -070016016 )
16017 {
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +053016018 pVosContext = ( WLAN_HDD_GET_CTX(pAdapter))->pvosContext;
16019 pSapCtx = VOS_GET_SAP_CB(pVosContext);
16020 if(pSapCtx == NULL){
16021 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
16022 FL("psapCtx is NULL"));
16023 return -ENOENT;
16024 }
Hanumantha Reddy Pothulabfd06f72014-10-31 14:03:37 +053016025 if (vos_is_macaddr_broadcast((v_MACADDR_t *)pDelStaParams->peerMacAddr))
Jeff Johnson295189b2012-06-20 16:38:30 -070016026 {
16027 v_U16_t i;
16028 for(i = 0; i < WLAN_MAX_STA_COUNT; i++)
16029 {
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +053016030 if ((pSapCtx->aStaInfo[i].isUsed) &&
16031 (!pSapCtx->aStaInfo[i].isDeauthInProgress))
Jeff Johnson295189b2012-06-20 16:38:30 -070016032 {
Hanumantha Reddy Pothulabfd06f72014-10-31 14:03:37 +053016033 vos_mem_copy(pDelStaParams->peerMacAddr,
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +053016034 pSapCtx->aStaInfo[i].macAddrSTA.bytes,
Hanumantha Reddy Pothulabfd06f72014-10-31 14:03:37 +053016035 ETHER_ADDR_LEN);
16036
Jeff Johnson295189b2012-06-20 16:38:30 -070016037 hddLog(VOS_TRACE_LEVEL_INFO,
Arif Hussain24bafea2013-11-15 15:10:03 -080016038 "%s: Delete STA with MAC::"
16039 MAC_ADDRESS_STR,
Hanumantha Reddy Pothulabfd06f72014-10-31 14:03:37 +053016040 __func__,
16041 MAC_ADDR_ARRAY(pDelStaParams->peerMacAddr));
16042 vos_status = hdd_softap_sta_deauth(pAdapter, pDelStaParams);
Rajesh Chauhan18488fc2013-08-22 10:15:03 -070016043 if (VOS_IS_STATUS_SUCCESS(vos_status))
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +053016044 pSapCtx->aStaInfo[i].isDeauthInProgress = TRUE;
Jeff Johnson295189b2012-06-20 16:38:30 -070016045 }
16046 }
16047 }
16048 else
16049 {
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -080016050
Hanumantha Reddy Pothulabfd06f72014-10-31 14:03:37 +053016051 vos_status = hdd_softap_GetStaId(pAdapter,
16052 (v_MACADDR_t *)pDelStaParams->peerMacAddr, &staId);
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -080016053 if (!VOS_IS_STATUS_SUCCESS(vos_status))
16054 {
16055 hddLog(VOS_TRACE_LEVEL_INFO,
Arif Hussain24bafea2013-11-15 15:10:03 -080016056 "%s: Skip this DEL STA as this is not used::"
16057 MAC_ADDRESS_STR,
Hanumantha Reddy Pothulabfd06f72014-10-31 14:03:37 +053016058 __func__, MAC_ADDR_ARRAY(pDelStaParams->peerMacAddr));
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -080016059 return -ENOENT;
16060 }
16061
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +053016062 if( pSapCtx->aStaInfo[staId].isDeauthInProgress == TRUE)
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -080016063 {
16064 hddLog(VOS_TRACE_LEVEL_INFO,
Arif Hussain24bafea2013-11-15 15:10:03 -080016065 "%s: Skip this DEL STA as deauth is in progress::"
16066 MAC_ADDRESS_STR,
Hanumantha Reddy Pothulabfd06f72014-10-31 14:03:37 +053016067 __func__, MAC_ADDR_ARRAY(pDelStaParams->peerMacAddr));
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -080016068 return -ENOENT;
16069 }
16070
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +053016071 pSapCtx->aStaInfo[staId].isDeauthInProgress = TRUE;
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -080016072
Jeff Johnson295189b2012-06-20 16:38:30 -070016073 hddLog(VOS_TRACE_LEVEL_INFO,
16074 "%s: Delete STA with MAC::"
Arif Hussain24bafea2013-11-15 15:10:03 -080016075 MAC_ADDRESS_STR,
Jeff Johnson295189b2012-06-20 16:38:30 -070016076 __func__,
Hanumantha Reddy Pothulabfd06f72014-10-31 14:03:37 +053016077 MAC_ADDR_ARRAY(pDelStaParams->peerMacAddr));
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -080016078
Hanumantha Reddy Pothulabfd06f72014-10-31 14:03:37 +053016079 vos_status = hdd_softap_sta_deauth(pAdapter, pDelStaParams);
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -080016080 if (!VOS_IS_STATUS_SUCCESS(vos_status))
16081 {
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +053016082 pSapCtx->aStaInfo[staId].isDeauthInProgress = FALSE;
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -080016083 hddLog(VOS_TRACE_LEVEL_INFO,
16084 "%s: STA removal failed for ::"
Arif Hussain24bafea2013-11-15 15:10:03 -080016085 MAC_ADDRESS_STR,
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -080016086 __func__,
Hanumantha Reddy Pothulabfd06f72014-10-31 14:03:37 +053016087 MAC_ADDR_ARRAY(pDelStaParams->peerMacAddr));
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -080016088 return -ENOENT;
16089 }
16090
Jeff Johnson295189b2012-06-20 16:38:30 -070016091 }
16092 }
16093
16094 EXIT();
16095
16096 return 0;
16097}
Naresh Jayaram69e3f282014-10-14 12:29:12 +053016098
16099#ifdef CFG80211_DEL_STA_V2
16100static int wlan_hdd_cfg80211_del_station(struct wiphy *wiphy,
16101 struct net_device *dev,
16102 struct station_del_parameters *param)
16103#else
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053016104#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,16,0))
16105static int wlan_hdd_cfg80211_del_station(struct wiphy *wiphy,
16106 struct net_device *dev, const u8 *mac)
16107#else
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053016108static int wlan_hdd_cfg80211_del_station(struct wiphy *wiphy,
16109 struct net_device *dev, u8 *mac)
Naresh Jayaram69e3f282014-10-14 12:29:12 +053016110#endif
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053016111#endif
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053016112{
16113 int ret;
Hanumantha Reddy Pothulabfd06f72014-10-31 14:03:37 +053016114 struct tagCsrDelStaParams delStaParams;
Jeff Johnson295189b2012-06-20 16:38:30 -070016115
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053016116 vos_ssr_protect(__func__);
Hanumantha Reddy Pothulabfd06f72014-10-31 14:03:37 +053016117
Naresh Jayaram69e3f282014-10-14 12:29:12 +053016118#ifdef CFG80211_DEL_STA_V2
Hanumantha Reddy Pothulabfd06f72014-10-31 14:03:37 +053016119 if (NULL == param) {
16120 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Invalid argumet passed", __func__);
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053016121 vos_ssr_unprotect(__func__);
Hanumantha Reddy Pothulabfd06f72014-10-31 14:03:37 +053016122 return -EINVAL;
16123 }
16124
16125 WLANSAP_PopulateDelStaParams(param->mac, param->reason_code,
16126 param->subtype, &delStaParams);
16127
Naresh Jayaram69e3f282014-10-14 12:29:12 +053016128#else
Sushant Kaushik4cd28f62014-12-26 14:23:50 +053016129 WLANSAP_PopulateDelStaParams(mac, eSIR_MAC_DEAUTH_LEAVING_BSS_REASON,
Hanumantha Reddy Pothulabfd06f72014-10-31 14:03:37 +053016130 (SIR_MAC_MGMT_DEAUTH >> 4), &delStaParams);
Naresh Jayaram69e3f282014-10-14 12:29:12 +053016131#endif
Hanumantha Reddy Pothulabfd06f72014-10-31 14:03:37 +053016132 ret = __wlan_hdd_cfg80211_del_station(wiphy, dev, &delStaParams);
16133
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053016134 vos_ssr_unprotect(__func__);
16135
16136 return ret;
16137}
16138
16139static int __wlan_hdd_cfg80211_add_station(struct wiphy *wiphy,
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053016140 struct net_device *dev,
16141#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,18,0))
16142 const u8 *mac,
16143#else
16144 u8 *mac,
16145#endif
16146 struct station_parameters *params)
Hoonki Lee11f7dda2013-02-14 16:55:44 -080016147{
Mahesh A Saptasagar74088392015-02-05 17:22:09 +053016148 hdd_adapter_t *pAdapter;
16149 hdd_context_t *pHddCtx;
Gopichand Nakkalab977a972013-02-18 19:15:09 -080016150 int status = -EPERM;
Hoonki Lee11f7dda2013-02-14 16:55:44 -080016151#ifdef FEATURE_WLAN_TDLS
16152 u32 mask, set;
Mahesh A Saptasagar74088392015-02-05 17:22:09 +053016153
Hoonki Lee11f7dda2013-02-14 16:55:44 -080016154 ENTER();
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053016155
Mahesh A Saptasagar74088392015-02-05 17:22:09 +053016156 pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
16157 if (NULL == pAdapter)
16158 {
16159 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
16160 "%s: Adapter is NULL",__func__);
16161 return -EINVAL;
16162 }
16163 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
16164 status = wlan_hdd_validate_context(pHddCtx);
16165 if (0 != status)
16166 {
Mahesh A Saptasagar74088392015-02-05 17:22:09 +053016167 return status;
16168 }
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053016169
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053016170 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
16171 TRACE_CODE_HDD_CFG80211_ADD_STA,
16172 pAdapter->sessionId, params->listen_interval));
Mohit Khanna698ba2a2012-12-04 15:08:18 -080016173 mask = params->sta_flags_mask;
16174
16175 set = params->sta_flags_set;
16176
Masti, Narayanraddi34e0e562015-03-05 18:23:03 +053016177 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Gopichand Nakkalac87400e2013-03-13 18:51:00 -070016178 "%s: mask 0x%x set 0x%x " MAC_ADDRESS_STR,
16179 __func__, mask, set, MAC_ADDR_ARRAY(mac));
Mohit Khanna698ba2a2012-12-04 15:08:18 -080016180
16181 if (mask & BIT(NL80211_STA_FLAG_TDLS_PEER)) {
16182 if (set & BIT(NL80211_STA_FLAG_TDLS_PEER)) {
Gopichand Nakkala681989c2013-03-06 22:27:48 -080016183 status = wlan_hdd_tdls_add_station(wiphy, dev, mac, 0, NULL);
Mohit Khanna698ba2a2012-12-04 15:08:18 -080016184 }
16185 }
16186#endif
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053016187 EXIT();
Gopichand Nakkalab977a972013-02-18 19:15:09 -080016188 return status;
Jeff Johnson295189b2012-06-20 16:38:30 -070016189}
16190
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053016191#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,16,0))
16192static int wlan_hdd_cfg80211_add_station(struct wiphy *wiphy,
16193 struct net_device *dev, const u8 *mac,
16194 struct station_parameters *params)
16195#else
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053016196static int wlan_hdd_cfg80211_add_station(struct wiphy *wiphy,
16197 struct net_device *dev, u8 *mac, struct station_parameters *params)
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053016198#endif
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053016199{
16200 int ret;
Jeff Johnson04dd8a82012-06-29 20:41:40 -070016201
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053016202 vos_ssr_protect(__func__);
16203 ret = __wlan_hdd_cfg80211_add_station(wiphy, dev, mac, params);
16204 vos_ssr_unprotect(__func__);
16205
16206 return ret;
16207}
Jeff Johnson04dd8a82012-06-29 20:41:40 -070016208#ifdef FEATURE_WLAN_LFR
Wilson Yang6507c4e2013-10-01 20:11:19 -070016209
Mahesh A Saptasagarf7418d72014-06-02 14:48:54 +053016210static int __wlan_hdd_cfg80211_set_pmksa(struct wiphy *wiphy, struct net_device *dev,
Jeff Johnsond13512a2012-07-17 11:42:19 -070016211 struct cfg80211_pmksa *pmksa)
Jeff Johnson04dd8a82012-06-29 20:41:40 -070016212{
Jeff Johnson04dd8a82012-06-29 20:41:40 -070016213 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
16214 tHalHandle halHandle;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016215 eHalStatus result;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053016216 int status;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053016217 hdd_context_t *pHddCtx;
Kanchanapally, Vidyullatha2633ace2014-09-25 15:16:50 +053016218 tPmkidCacheInfo pmk_id;
Jeff Johnsone7245742012-09-05 17:12:55 -070016219
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053016220 ENTER();
16221
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016222 // Validate pAdapter
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053016223 if ( NULL == pAdapter )
Jeff Johnson04dd8a82012-06-29 20:41:40 -070016224 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053016225 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Invalid Adapter" ,__func__);
Jeff Johnson04dd8a82012-06-29 20:41:40 -070016226 return -EINVAL;
16227 }
16228
Kanchanapally, Vidyullatha2633ace2014-09-25 15:16:50 +053016229 if (!pmksa) {
16230 hddLog(LOGE, FL("pmksa is NULL"));
16231 return -EINVAL;
16232 }
16233
16234 if (!pmksa->bssid || !pmksa->pmkid) {
16235 hddLog(LOGE, FL("pmksa->bssid(%p) or pmksa->pmkid(%p) is NULL"),
16236 pmksa->bssid, pmksa->pmkid);
16237 return -EINVAL;
16238 }
16239
16240 hddLog(VOS_TRACE_LEVEL_DEBUG, "%s: set PMKSA for " MAC_ADDRESS_STR,
16241 __func__, MAC_ADDR_ARRAY(pmksa->bssid));
16242
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053016243 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
16244 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053016245 if (0 != status)
Jeff Johnson04dd8a82012-06-29 20:41:40 -070016246 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053016247 return status;
Jeff Johnson04dd8a82012-06-29 20:41:40 -070016248 }
16249
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016250 // Retrieve halHandle
Jeff Johnson04dd8a82012-06-29 20:41:40 -070016251 halHandle = WLAN_HDD_GET_HAL_CTX(pAdapter);
16252
Kanchanapally, Vidyullatha2633ace2014-09-25 15:16:50 +053016253 vos_mem_copy(pmk_id.BSSID, pmksa->bssid, ETHER_ADDR_LEN);
16254 vos_mem_copy(pmk_id.PMKID, pmksa->pmkid, CSR_RSN_PMKID_SIZE);
Jeff Johnson04dd8a82012-06-29 20:41:40 -070016255
Kanchanapally, Vidyullatha2633ace2014-09-25 15:16:50 +053016256 /* Add to the PMKSA ID Cache in CSR */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016257 result = sme_RoamSetPMKIDCache(halHandle,pAdapter->sessionId,
Kanchanapally, Vidyullatha2633ace2014-09-25 15:16:50 +053016258 &pmk_id, 1, FALSE);
16259
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053016260 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
16261 TRACE_CODE_HDD_CFG80211_SET_PMKSA,
16262 pAdapter->sessionId, result));
Kanchanapally, Vidyullatha2633ace2014-09-25 15:16:50 +053016263
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053016264 EXIT();
Kanchanapally, Vidyullatha2633ace2014-09-25 15:16:50 +053016265 return HAL_STATUS_SUCCESS(result) ? 0 : -EINVAL;
Jeff Johnson04dd8a82012-06-29 20:41:40 -070016266}
16267
Mahesh A Saptasagarf7418d72014-06-02 14:48:54 +053016268static int wlan_hdd_cfg80211_set_pmksa(struct wiphy *wiphy, struct net_device *dev,
16269 struct cfg80211_pmksa *pmksa)
16270{
16271 int ret;
16272
16273 vos_ssr_protect(__func__);
16274 ret = __wlan_hdd_cfg80211_set_pmksa(wiphy, dev, pmksa);
16275 vos_ssr_unprotect(__func__);
16276
16277 return ret;
16278}
Jeff Johnson04dd8a82012-06-29 20:41:40 -070016279
Wilson Yang6507c4e2013-10-01 20:11:19 -070016280
Mahesh A Saptasagarf7418d72014-06-02 14:48:54 +053016281static int __wlan_hdd_cfg80211_del_pmksa(struct wiphy *wiphy, struct net_device *dev,
Wilson Yang6507c4e2013-10-01 20:11:19 -070016282 struct cfg80211_pmksa *pmksa)
Jeff Johnson04dd8a82012-06-29 20:41:40 -070016283{
Wilson Yang6507c4e2013-10-01 20:11:19 -070016284 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
16285 tHalHandle halHandle;
Wilson Yang6507c4e2013-10-01 20:11:19 -070016286 hdd_context_t *pHddCtx;
Wilson Yangef657d32014-01-15 19:19:23 -080016287 int status = 0;
Wilson Yang6507c4e2013-10-01 20:11:19 -070016288
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053016289 ENTER();
16290
Wilson Yang6507c4e2013-10-01 20:11:19 -070016291 /* Validate pAdapter */
16292 if (NULL == pAdapter)
16293 {
16294 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Invalid Adapter" ,__func__);
16295 return -EINVAL;
16296 }
16297
Kanchanapally, Vidyullatha2633ace2014-09-25 15:16:50 +053016298 if (!pmksa) {
16299 hddLog(LOGE, FL("pmksa is NULL"));
16300 return -EINVAL;
16301 }
16302
16303 if (!pmksa->bssid) {
16304 hddLog(LOGE, FL("pmksa->bssid is NULL"));
16305 return -EINVAL;
16306 }
16307
Kiet Lam98c46a12014-10-31 15:34:57 -070016308 hddLog(VOS_TRACE_LEVEL_DEBUG, "%s: deleting PMKSA for " MAC_ADDRESS_STR,
16309 __func__, MAC_ADDR_ARRAY(pmksa->bssid));
16310
Wilson Yang6507c4e2013-10-01 20:11:19 -070016311 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
16312 status = wlan_hdd_validate_context(pHddCtx);
Wilson Yang6507c4e2013-10-01 20:11:19 -070016313 if (0 != status)
16314 {
Wilson Yang6507c4e2013-10-01 20:11:19 -070016315 return status;
16316 }
16317
16318 /*Retrieve halHandle*/
16319 halHandle = WLAN_HDD_GET_HAL_CTX(pAdapter);
16320
Konamki, Sreelakshmi7b464be2015-07-14 12:17:01 +053016321 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
16322 TRACE_CODE_HDD_CFG80211_DEL_PMKSA,
16323 pAdapter->sessionId, 0));
Kanchanapally, Vidyullatha2633ace2014-09-25 15:16:50 +053016324 /* Delete the PMKID CSR cache */
16325 if (eHAL_STATUS_SUCCESS !=
16326 sme_RoamDelPMKIDfromCache(halHandle,
16327 pAdapter->sessionId, pmksa->bssid, FALSE)) {
16328 hddLog(LOGE, FL("Failed to delete PMKSA for "MAC_ADDRESS_STR),
16329 MAC_ADDR_ARRAY(pmksa->bssid));
16330 status = -EINVAL;
Wilson Yang6507c4e2013-10-01 20:11:19 -070016331 }
16332
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053016333 EXIT();
16334 return status;
Jeff Johnson04dd8a82012-06-29 20:41:40 -070016335}
16336
Wilson Yang6507c4e2013-10-01 20:11:19 -070016337
Mahesh A Saptasagarf7418d72014-06-02 14:48:54 +053016338static int wlan_hdd_cfg80211_del_pmksa(struct wiphy *wiphy, struct net_device *dev,
16339 struct cfg80211_pmksa *pmksa)
16340{
16341 int ret;
Wilson Yang6507c4e2013-10-01 20:11:19 -070016342
Mahesh A Saptasagarf7418d72014-06-02 14:48:54 +053016343 vos_ssr_protect(__func__);
16344 ret = __wlan_hdd_cfg80211_del_pmksa(wiphy, dev, pmksa);
16345 vos_ssr_unprotect(__func__);
16346
16347 return ret;
16348
16349}
16350
16351static int __wlan_hdd_cfg80211_flush_pmksa(struct wiphy *wiphy, struct net_device *dev)
Jeff Johnson04dd8a82012-06-29 20:41:40 -070016352{
Wilson Yang6507c4e2013-10-01 20:11:19 -070016353 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
16354 tHalHandle halHandle;
16355 hdd_context_t *pHddCtx;
Wilson Yangef657d32014-01-15 19:19:23 -080016356 int status = 0;
Wilson Yang6507c4e2013-10-01 20:11:19 -070016357
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053016358 ENTER();
Wilson Yang6507c4e2013-10-01 20:11:19 -070016359
16360 /* Validate pAdapter */
16361 if (NULL == pAdapter)
16362 {
16363 hddLog(VOS_TRACE_LEVEL_ERROR,
16364 "%s: Invalid Adapter" ,__func__);
16365 return -EINVAL;
16366 }
16367
16368 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
16369 status = wlan_hdd_validate_context(pHddCtx);
Wilson Yang6507c4e2013-10-01 20:11:19 -070016370 if (0 != status)
16371 {
Wilson Yang6507c4e2013-10-01 20:11:19 -070016372 return status;
16373 }
16374
16375 /*Retrieve halHandle*/
16376 halHandle = WLAN_HDD_GET_HAL_CTX(pAdapter);
16377
Kanchanapally, Vidyullatha2633ace2014-09-25 15:16:50 +053016378 /* Flush the PMKID cache in CSR */
16379 if (eHAL_STATUS_SUCCESS !=
16380 sme_RoamDelPMKIDfromCache(halHandle, pAdapter->sessionId, NULL, TRUE)) {
16381 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Cannot flush PMKIDCache"));
16382 status = -EINVAL;
Wilson Yang6507c4e2013-10-01 20:11:19 -070016383 }
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053016384 EXIT();
Wilson Yangef657d32014-01-15 19:19:23 -080016385 return status;
Jeff Johnson04dd8a82012-06-29 20:41:40 -070016386}
Mahesh A Saptasagarf7418d72014-06-02 14:48:54 +053016387
16388static int wlan_hdd_cfg80211_flush_pmksa(struct wiphy *wiphy, struct net_device *dev)
16389{
16390 int ret;
16391
16392 vos_ssr_protect(__func__);
16393 ret = __wlan_hdd_cfg80211_flush_pmksa(wiphy, dev);
16394 vos_ssr_unprotect(__func__);
16395
16396 return ret;
16397}
Jeff Johnson04dd8a82012-06-29 20:41:40 -070016398#endif
16399
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070016400#if defined(WLAN_FEATURE_VOWIFI_11R) && defined(KERNEL_SUPPORT_11R_CFG80211)
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053016401static int __wlan_hdd_cfg80211_update_ft_ies(struct wiphy *wiphy,
16402 struct net_device *dev,
16403 struct cfg80211_update_ft_ies_params *ftie)
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070016404{
16405 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
16406 hdd_station_ctx_t *pHddStaCtx;
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +053016407 hdd_context_t *pHddCtx;
16408 int ret = 0;
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070016409
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053016410 ENTER();
16411
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070016412 if (NULL == pAdapter)
16413 {
Arif Hussain6d2a3322013-11-17 19:50:10 -080016414 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Adapter is NULL", __func__);
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070016415 return -ENODEV;
16416 }
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +053016417 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
16418 ret = wlan_hdd_validate_context(pHddCtx);
16419 if (0 != ret)
16420 {
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +053016421 return ret;
16422 }
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070016423 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
Mahesh A Saptasagar74088392015-02-05 17:22:09 +053016424 if (NULL == pHddStaCtx)
16425 {
16426 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: STA Context is NULL", __func__);
16427 return -EINVAL;
16428 }
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070016429
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053016430 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
16431 TRACE_CODE_HDD_CFG80211_UPDATE_FT_IES,
16432 pAdapter->sessionId, pHddStaCtx->conn_info.connState));
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070016433 // Added for debug on reception of Re-assoc Req.
16434 if (eConnectionState_Associated != pHddStaCtx->conn_info.connState)
16435 {
Arif Hussain6d2a3322013-11-17 19:50:10 -080016436 hddLog(LOGE, FL("Called with Ie of length = %zu when not associated"),
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070016437 ftie->ie_len);
Arif Hussain6d2a3322013-11-17 19:50:10 -080016438 hddLog(LOGE, FL("Should be Re-assoc Req IEs"));
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070016439 }
16440
16441#ifdef WLAN_FEATURE_VOWIFI_11R_DEBUG
Arif Hussain6d2a3322013-11-17 19:50:10 -080016442 hddLog(LOGE, FL("%s called with Ie of length = %zu"), __func__,
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070016443 ftie->ie_len);
16444#endif
16445
16446 // Pass the received FT IEs to SME
Gopichand Nakkala356fb102013-03-06 12:34:04 +053016447 sme_SetFTIEs( WLAN_HDD_GET_HAL_CTX(pAdapter), pAdapter->sessionId,
16448 (const u8 *)ftie->ie,
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070016449 ftie->ie_len);
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053016450
16451 EXIT();
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070016452 return 0;
16453}
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053016454
16455static int wlan_hdd_cfg80211_update_ft_ies(struct wiphy *wiphy,
16456 struct net_device *dev,
16457 struct cfg80211_update_ft_ies_params *ftie)
16458{
16459 int ret;
16460
16461 vos_ssr_protect(__func__);
16462 ret = __wlan_hdd_cfg80211_update_ft_ies(wiphy, dev, ftie);
16463 vos_ssr_unprotect(__func__);
16464
16465 return ret;
16466}
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070016467#endif
Jeff Johnson04dd8a82012-06-29 20:41:40 -070016468
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053016469#ifdef FEATURE_WLAN_SCAN_PNO
16470
16471void hdd_cfg80211_sched_scan_done_callback(void *callbackContext,
16472 tSirPrefNetworkFoundInd *pPrefNetworkFoundInd)
16473{
16474 int ret;
16475 hdd_adapter_t* pAdapter = (hdd_adapter_t*)callbackContext;
16476 hdd_context_t *pHddCtx;
16477
Nirav Shah80830bf2013-12-31 16:35:12 +053016478 ENTER();
16479
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053016480 if (NULL == pAdapter)
16481 {
Agarwal Ashish971c2882013-10-30 20:11:12 +053016482 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053016483 "%s: HDD adapter is Null", __func__);
16484 return ;
16485 }
16486
16487 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
16488 if (NULL == pHddCtx)
16489 {
16490 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
16491 "%s: HDD context is Null!!!", __func__);
16492 return ;
16493 }
16494
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053016495 spin_lock(&pHddCtx->schedScan_lock);
16496 if (TRUE == pHddCtx->isWiphySuspended)
16497 {
16498 pHddCtx->isSchedScanUpdatePending = TRUE;
16499 spin_unlock(&pHddCtx->schedScan_lock);
16500 hddLog(VOS_TRACE_LEVEL_INFO,
16501 "%s: Update cfg80211 scan database after it resume", __func__);
16502 return ;
16503 }
16504 spin_unlock(&pHddCtx->schedScan_lock);
16505
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053016506 ret = wlan_hdd_cfg80211_update_bss(pHddCtx->wiphy, pAdapter);
16507
16508 if (0 > ret)
16509 hddLog(VOS_TRACE_LEVEL_INFO, "%s: NO SCAN result", __func__);
Mahesh A Saptasagarfb49cdd2015-10-16 18:41:59 +053016510 else
16511 {
16512 /* Acquire wakelock to handle the case where APP's tries to suspend
16513 * immediatly after the driver gets connect request(i.e after pno)
16514 * from supplicant, this result in app's is suspending and not able
16515 * to process the connect request to AP */
16516 hdd_prevent_suspend_timeout(1000, WIFI_POWER_EVENT_WAKELOCK_SCAN);
16517 }
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053016518 cfg80211_sched_scan_results(pHddCtx->wiphy);
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053016519 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
16520 "%s: cfg80211 scan result database updated", __func__);
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053016521}
16522
16523/*
Mahesh A Saptasagar0f7b0372013-11-28 23:23:07 +053016524 * FUNCTION: wlan_hdd_is_pno_allowed
Vinay Krishna Erannacbf75f42014-02-26 17:35:20 +053016525 * Disallow pno if any session is active
Mahesh A Saptasagar0f7b0372013-11-28 23:23:07 +053016526 */
16527static eHalStatus wlan_hdd_is_pno_allowed(hdd_adapter_t *pAdapter)
16528{
16529 hdd_adapter_list_node_t *pAdapterNode = NULL, *pNext = NULL;
16530 hdd_adapter_t *pTempAdapter = NULL;
Vinay Krishna Eranna23ffd182013-12-26 19:16:55 +053016531 hdd_station_ctx_t *pStaCtx;
Mahesh A Saptasagar0f7b0372013-11-28 23:23:07 +053016532 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
16533 int status = 0;
16534 status = hdd_get_front_adapter(pHddCtx, &pAdapterNode);
16535
Vinay Krishna Erannacbf75f42014-02-26 17:35:20 +053016536 /* The current firmware design does not allow PNO during any
16537 * active sessions. Hence, determine the active sessions
16538 * and return a failure.
16539 */
Mahesh A Saptasagar0f7b0372013-11-28 23:23:07 +053016540 while ((NULL != pAdapterNode) && (VOS_STATUS_SUCCESS == status))
16541 {
16542 pTempAdapter = pAdapterNode->pAdapter;
Vinay Krishna Eranna23ffd182013-12-26 19:16:55 +053016543 pStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pTempAdapter);
Mahesh A Saptasagar0f7b0372013-11-28 23:23:07 +053016544
Vinay Krishna Eranna23ffd182013-12-26 19:16:55 +053016545 if (((WLAN_HDD_INFRA_STATION == pTempAdapter->device_mode)
16546 && (eConnectionState_NotConnected != pStaCtx->conn_info.connState))
16547 || (WLAN_HDD_P2P_CLIENT == pTempAdapter->device_mode)
16548 || (WLAN_HDD_P2P_GO == pTempAdapter->device_mode)
16549 || (WLAN_HDD_SOFTAP == pTempAdapter->device_mode)
Siddharth Bhal63a19a72014-11-07 14:31:56 +053016550 || (WLAN_HDD_TM_LEVEL_4 == pHddCtx->tmInfo.currentTmLevel)
Vinay Krishna Eranna23ffd182013-12-26 19:16:55 +053016551 )
Mahesh A Saptasagar0f7b0372013-11-28 23:23:07 +053016552 {
Vinay Krishna Eranna23ffd182013-12-26 19:16:55 +053016553 return eHAL_STATUS_FAILURE;
Mahesh A Saptasagar0f7b0372013-11-28 23:23:07 +053016554 }
16555 status = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
16556 pAdapterNode = pNext;
16557 }
Vinay Krishna Eranna23ffd182013-12-26 19:16:55 +053016558 return eHAL_STATUS_SUCCESS;
Mahesh A Saptasagar0f7b0372013-11-28 23:23:07 +053016559}
16560
Vinay Krishna Erannaf0e523b2014-03-01 21:00:16 +053016561void hdd_cfg80211_sched_scan_start_status_cb(void *callbackContext, VOS_STATUS status)
16562{
16563 hdd_adapter_t *pAdapter = callbackContext;
16564 hdd_context_t *pHddCtx;
16565
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053016566 ENTER();
16567
Vinay Krishna Erannaf0e523b2014-03-01 21:00:16 +053016568 if ((NULL == pAdapter) || (WLAN_HDD_ADAPTER_MAGIC != pAdapter->magic))
16569 {
16570 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
16571 FL("Invalid adapter or adapter has invalid magic"));
16572 return;
16573 }
16574
16575 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
16576 if (0 != wlan_hdd_validate_context(pHddCtx))
16577 {
Vinay Krishna Erannaf0e523b2014-03-01 21:00:16 +053016578 return;
16579 }
16580
c_hpothub53c45d2014-08-18 16:53:14 +053016581 if (VOS_STATUS_SUCCESS != status)
16582 {
16583 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Vinay Krishna Erannaf0e523b2014-03-01 21:00:16 +053016584 FL("PNO enable response status = %d"), status);
c_hpothub53c45d2014-08-18 16:53:14 +053016585 pHddCtx->isPnoEnable = FALSE;
16586 }
Vinay Krishna Erannaf0e523b2014-03-01 21:00:16 +053016587
16588 pAdapter->pno_req_status = (status == VOS_STATUS_SUCCESS) ? 0 : -EBUSY;
16589 complete(&pAdapter->pno_comp_var);
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053016590 EXIT();
Vinay Krishna Erannaf0e523b2014-03-01 21:00:16 +053016591}
16592
Mahesh A Saptasagar0f7b0372013-11-28 23:23:07 +053016593/*
Mahesh A Saptasagar6cc38562014-05-23 21:22:17 +053016594 * FUNCTION: __wlan_hdd_cfg80211_sched_scan_start
16595 * Function to enable PNO
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053016596 */
Mahesh A Saptasagar6cc38562014-05-23 21:22:17 +053016597static int __wlan_hdd_cfg80211_sched_scan_start(struct wiphy *wiphy,
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053016598 struct net_device *dev, struct cfg80211_sched_scan_request *request)
16599{
16600 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053016601 tSirPNOScanReq pnoRequest = {0};
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053016602 hdd_context_t *pHddCtx;
16603 tHalHandle hHal;
Mahesh A Saptasagar7bd6ad42014-07-21 18:56:33 +053016604 v_U32_t i, indx, num_ch, tempInterval, j;
Sushant Kaushikd62d9782014-02-19 15:39:40 +053016605 u8 valid_ch[WNI_CFG_VALID_CHANNEL_LIST_LEN] = {0};
16606 u8 channels_allowed[WNI_CFG_VALID_CHANNEL_LIST_LEN] = {0};
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053016607 v_U32_t num_channels_allowed = WNI_CFG_VALID_CHANNEL_LIST_LEN;
16608 eHalStatus status = eHAL_STATUS_FAILURE;
Kamath Vinayakba5313f2013-08-22 15:52:39 +053016609 int ret = 0;
Sachin Ahuja697ba3f2014-11-12 18:57:11 +053016610 hdd_config_t *pConfig = NULL;
16611 v_U32_t num_ignore_dfs_ch = 0;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053016612
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053016613 ENTER();
16614
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053016615 if (NULL == pAdapter)
16616 {
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053016617 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053016618 "%s: HDD adapter is Null", __func__);
16619 return -ENODEV;
16620 }
16621
16622 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053016623 ret = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053016624
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053016625 if (0 != ret)
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053016626 {
Kamath Vinayakba5313f2013-08-22 15:52:39 +053016627 return -EINVAL;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053016628 }
16629
Sachin Ahuja697ba3f2014-11-12 18:57:11 +053016630 pConfig = pHddCtx->cfg_ini;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053016631 hHal = WLAN_HDD_GET_HAL_CTX(pAdapter);
16632 if (NULL == hHal)
16633 {
16634 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
16635 "%s: HAL context is Null!!!", __func__);
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053016636 return -EINVAL;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053016637 }
Konamki, Sreelakshmi7b464be2015-07-14 12:17:01 +053016638 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
16639 TRACE_CODE_HDD_CFG80211_SCHED_SCAN_START,
16640 pAdapter->sessionId, pAdapter->device_mode));
Sushant Kaushik2fe89932014-09-03 10:58:09 +053016641 sme_ScanFlushResult(hHal, pAdapter->sessionId);
Mahesh A Saptasagar2395ee62014-05-21 19:12:21 +053016642 ret = wlan_hdd_scan_abort(pAdapter);
Girish Gowli4bf7a632014-06-12 13:42:11 +053016643 if (ret < 0)
Mahesh A Saptasagar2395ee62014-05-21 19:12:21 +053016644 {
16645 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
16646 "%s: aborting the existing scan is unsuccessfull", __func__);
16647 return -EBUSY;
16648 }
16649
Vinay Krishna Eranna23ffd182013-12-26 19:16:55 +053016650 if (eHAL_STATUS_SUCCESS != wlan_hdd_is_pno_allowed(pAdapter))
Mahesh A Saptasagar0f7b0372013-11-28 23:23:07 +053016651 {
Vinay Krishna Erannacbf75f42014-02-26 17:35:20 +053016652 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_WARN,
Vinay Krishna Eranna23ffd182013-12-26 19:16:55 +053016653 FL("Cannot handle sched_scan"));
Mahesh A Saptasagar0f7b0372013-11-28 23:23:07 +053016654 return -EBUSY;
16655 }
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053016656
c_hpothu37f21312014-04-09 21:49:54 +053016657 if (TRUE == pHddCtx->isPnoEnable)
16658 {
16659 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_WARN,
16660 FL("already PNO is enabled"));
16661 return -EBUSY;
16662 }
c_hpothu225aa7c2014-10-22 17:45:13 +053016663
16664 if (VOS_STATUS_SUCCESS != wlan_hdd_cancel_remain_on_channel(pHddCtx))
16665 {
16666 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
16667 "%s: abort ROC failed ", __func__);
16668 return -EBUSY;
16669 }
16670
c_hpothu37f21312014-04-09 21:49:54 +053016671 pHddCtx->isPnoEnable = TRUE;
16672
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053016673 pnoRequest.enable = 1; /*Enable PNO */
16674 pnoRequest.ucNetworksCount = request->n_match_sets;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053016675
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053016676 if (( !pnoRequest.ucNetworksCount ) ||
16677 ( pnoRequest.ucNetworksCount > SIR_PNO_MAX_SUPP_NETWORKS ))
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053016678 {
16679 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Sushant Kaushik1e406c32014-05-09 15:57:52 +053016680 "%s: Network input is not correct %d Max Network supported is %d",
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053016681 __func__, pnoRequest.ucNetworksCount,
Sushant Kaushik1e406c32014-05-09 15:57:52 +053016682 SIR_PNO_MAX_SUPP_NETWORKS);
Kamath Vinayakba5313f2013-08-22 15:52:39 +053016683 ret = -EINVAL;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053016684 goto error;
16685 }
16686
16687 if ( SIR_PNO_MAX_NETW_CHANNELS_EX < request->n_channels )
16688 {
16689 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Nirav Shah80830bf2013-12-31 16:35:12 +053016690 "%s: Incorrect number of channels %d",
16691 __func__, request->n_channels);
Kamath Vinayakba5313f2013-08-22 15:52:39 +053016692 ret = -EINVAL;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053016693 goto error;
16694 }
16695
16696 /* Framework provides one set of channels(all)
16697 * common for all saved profile */
16698 if (0 != ccmCfgGetStr(hHal, WNI_CFG_VALID_CHANNEL_LIST,
16699 channels_allowed, &num_channels_allowed))
16700 {
16701 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
16702 "%s: failed to get valid channel list", __func__);
Kamath Vinayakba5313f2013-08-22 15:52:39 +053016703 ret = -EINVAL;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053016704 goto error;
16705 }
16706 /* Checking each channel against allowed channel list */
16707 num_ch = 0;
Nirav Shah80830bf2013-12-31 16:35:12 +053016708 if (request->n_channels)
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053016709 {
Nirav Shah80830bf2013-12-31 16:35:12 +053016710 char chList [(request->n_channels*5)+1];
16711 int len;
16712 for (i = 0, len = 0; i < request->n_channels; i++)
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053016713 {
Nirav Shah80830bf2013-12-31 16:35:12 +053016714 for (indx = 0; indx < num_channels_allowed; indx++)
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053016715 {
Nirav Shah80830bf2013-12-31 16:35:12 +053016716 if (request->channels[i]->hw_value == channels_allowed[indx])
16717 {
Sachin Ahuja697ba3f2014-11-12 18:57:11 +053016718 if ((!pConfig->enableDFSPnoChnlScan) &&
16719 (NV_CHANNEL_DFS == vos_nv_getChannelEnabledState(channels_allowed[indx])))
16720 {
16721 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
16722 "%s : Dropping DFS channel : %d",
16723 __func__,channels_allowed[indx]);
16724 num_ignore_dfs_ch++;
16725 break;
16726 }
16727
Nirav Shah80830bf2013-12-31 16:35:12 +053016728 valid_ch[num_ch++] = request->channels[i]->hw_value;
16729 len += snprintf(chList+len, 5, "%d ",
16730 request->channels[i]->hw_value);
16731 break ;
16732 }
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053016733 }
16734 }
Nirav Shah80830bf2013-12-31 16:35:12 +053016735 hddLog(VOS_TRACE_LEVEL_INFO,"Channel-List: %s ", chList);
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053016736
Sachin Ahuja697ba3f2014-11-12 18:57:11 +053016737 /*If all channels are DFS and dropped, then ignore the PNO request*/
16738 if (num_ignore_dfs_ch == request->n_channels)
16739 {
16740 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
16741 "%s : All requested channels are DFS channels", __func__);
16742 ret = -EINVAL;
16743 goto error;
16744 }
16745 }
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053016746
16747 pnoRequest.aNetworks =
16748 vos_mem_malloc(sizeof(tSirNetworkType)*pnoRequest.ucNetworksCount);
16749 if (pnoRequest.aNetworks == NULL)
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053016750 {
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053016751 VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR,
16752 FL("failed to allocate memory aNetworks %u"),
16753 (uint32)sizeof(tSirNetworkType)*pnoRequest.ucNetworksCount);
16754 goto error;
16755 }
16756 vos_mem_zero(pnoRequest.aNetworks,
16757 sizeof(tSirNetworkType)*pnoRequest.ucNetworksCount);
16758
16759 /* Filling per profile params */
16760 for (i = 0; i < pnoRequest.ucNetworksCount; i++)
16761 {
16762 pnoRequest.aNetworks[i].ssId.length =
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053016763 request->match_sets[i].ssid.ssid_len;
16764
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053016765 if (( 0 == pnoRequest.aNetworks[i].ssId.length ) ||
16766 ( pnoRequest.aNetworks[i].ssId.length > 32 ) )
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053016767 {
16768 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Nirav Shah80830bf2013-12-31 16:35:12 +053016769 "%s: SSID Len %d is not correct for network %d",
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053016770 __func__, pnoRequest.aNetworks[i].ssId.length, i);
Kamath Vinayakba5313f2013-08-22 15:52:39 +053016771 ret = -EINVAL;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053016772 goto error;
16773 }
16774
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053016775 memcpy(pnoRequest.aNetworks[i].ssId.ssId,
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053016776 request->match_sets[i].ssid.ssid,
16777 request->match_sets[i].ssid.ssid_len);
Sushant Kaushik1e406c32014-05-09 15:57:52 +053016778 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
16779 "%s: SSID of network %d is %s ", __func__,
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053016780 i, pnoRequest.aNetworks[i].ssId.ssId);
16781 pnoRequest.aNetworks[i].authentication = 0; /*eAUTH_TYPE_ANY*/
16782 pnoRequest.aNetworks[i].encryption = 0; /*eED_ANY*/
16783 pnoRequest.aNetworks[i].bcastNetwType = 0; /*eBCAST_UNKNOWN*/
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053016784
16785 /*Copying list of valid channel into request */
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053016786 memcpy(pnoRequest.aNetworks[i].aChannels, valid_ch, num_ch);
16787 pnoRequest.aNetworks[i].ucChannelCount = num_ch;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053016788
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053016789 pnoRequest.aNetworks[i].rssiThreshold = 0; //Default value
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053016790 }
16791
Mahesh A Saptasagar7bd6ad42014-07-21 18:56:33 +053016792 for (i = 0; i < request->n_ssids; i++)
16793 {
16794 j = 0;
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053016795 while (j < pnoRequest.ucNetworksCount)
Mahesh A Saptasagar7bd6ad42014-07-21 18:56:33 +053016796 {
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053016797 if ((pnoRequest.aNetworks[j].ssId.length ==
Mahesh A Saptasagar7bd6ad42014-07-21 18:56:33 +053016798 request->ssids[i].ssid_len) &&
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053016799 (0 == memcmp(pnoRequest.aNetworks[j].ssId.ssId,
Mahesh A Saptasagar7bd6ad42014-07-21 18:56:33 +053016800 request->ssids[i].ssid,
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053016801 pnoRequest.aNetworks[j].ssId.length)))
Mahesh A Saptasagar7bd6ad42014-07-21 18:56:33 +053016802 {
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053016803 pnoRequest.aNetworks[j].bcastNetwType = eBCAST_HIDDEN;
Mahesh A Saptasagar7bd6ad42014-07-21 18:56:33 +053016804 break;
16805 }
16806 j++;
16807 }
16808 }
16809 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
16810 "Number of hidden networks being Configured = %d",
16811 request->n_ssids);
Madan Mohan Koyyalamudia7765d52013-09-18 16:49:56 +053016812 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Jeff Johnson59a121e2013-11-30 09:46:08 -080016813 "request->ie_len = %zu", request->ie_len);
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053016814
16815 pnoRequest.p24GProbeTemplate = vos_mem_malloc(SIR_PNO_MAX_PB_REQ_SIZE);
16816 if (pnoRequest.p24GProbeTemplate == NULL)
16817 {
16818 VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR,
16819 FL("failed to allocate memory p24GProbeTemplate %u"),
16820 SIR_PNO_MAX_PB_REQ_SIZE);
16821 goto error;
16822 }
16823
16824 pnoRequest.p5GProbeTemplate = vos_mem_malloc(SIR_PNO_MAX_PB_REQ_SIZE);
16825 if (pnoRequest.p5GProbeTemplate == NULL)
16826 {
16827 VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR,
16828 FL("failed to allocate memory p5GProbeTemplate %u"),
16829 SIR_PNO_MAX_PB_REQ_SIZE);
16830 goto error;
16831 }
16832
16833 vos_mem_zero(pnoRequest.p24GProbeTemplate, SIR_PNO_MAX_PB_REQ_SIZE);
16834 vos_mem_zero(pnoRequest.p5GProbeTemplate, SIR_PNO_MAX_PB_REQ_SIZE);
16835
Hanumantha Reddy Pothula06e87b22015-03-02 18:02:23 +053016836 if ((0 < request->ie_len) && (request->ie_len <= SIR_PNO_MAX_PB_REQ_SIZE) &&
16837 (NULL != request->ie))
Madan Mohan Koyyalamudia7765d52013-09-18 16:49:56 +053016838 {
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053016839 pnoRequest.us24GProbeTemplateLen = request->ie_len;
16840 memcpy(pnoRequest.p24GProbeTemplate, request->ie,
16841 pnoRequest.us24GProbeTemplateLen);
Madan Mohan Koyyalamudia7765d52013-09-18 16:49:56 +053016842
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053016843 pnoRequest.us5GProbeTemplateLen = request->ie_len;
16844 memcpy(pnoRequest.p5GProbeTemplate, request->ie,
16845 pnoRequest.us5GProbeTemplateLen);
Madan Mohan Koyyalamudia7765d52013-09-18 16:49:56 +053016846 }
16847
Madan Mohan Koyyalamudi1d16f462013-08-27 16:25:34 +053016848 /* Driver gets only one time interval which is hardcoded in
16849 * supplicant for 10000ms. Taking power consumption into account 6 timers
16850 * will be used, Timervalue is increased exponentially i.e 10,20,40,
16851 * 80,160,320 secs. And number of scan cycle for each timer
16852 * is configurable through INI param gPNOScanTimerRepeatValue.
16853 * If it is set to 0 only one timer will be used and PNO scan cycle
16854 * will be repeated after each interval specified by supplicant
16855 * till PNO is disabled.
16856 */
16857 if (0 == pHddCtx->cfg_ini->configPNOScanTimerRepeatValue)
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053016858 pnoRequest.scanTimers.ucScanTimersCount = HDD_PNO_SCAN_TIMERS_SET_ONE;
Madan Mohan Koyyalamudi1d16f462013-08-27 16:25:34 +053016859 else
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053016860 pnoRequest.scanTimers.ucScanTimersCount =
Madan Mohan Koyyalamudi1d16f462013-08-27 16:25:34 +053016861 HDD_PNO_SCAN_TIMERS_SET_MULTIPLE;
16862
16863 tempInterval = (request->interval)/1000;
16864 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
16865 "Base scan interval = %d PNOScanTimerRepeatValue = %d",
16866 tempInterval, pHddCtx->cfg_ini->configPNOScanTimerRepeatValue);
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053016867 for ( i = 0; i < pnoRequest.scanTimers.ucScanTimersCount; i++)
Madan Mohan Koyyalamudi1d16f462013-08-27 16:25:34 +053016868 {
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053016869 pnoRequest.scanTimers.aTimerValues[i].uTimerRepeat =
Madan Mohan Koyyalamudi1d16f462013-08-27 16:25:34 +053016870 pHddCtx->cfg_ini->configPNOScanTimerRepeatValue;
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053016871 pnoRequest.scanTimers.aTimerValues[i].uTimerValue = tempInterval;
Madan Mohan Koyyalamudi1d16f462013-08-27 16:25:34 +053016872 tempInterval *= 2;
16873 }
16874 //Repeat last timer until pno disabled.
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053016875 pnoRequest.scanTimers.aTimerValues[i-1].uTimerRepeat = 0;
Madan Mohan Koyyalamudi1d16f462013-08-27 16:25:34 +053016876
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053016877 pnoRequest.modePNO = SIR_PNO_MODE_IMMEDIATE;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053016878
Vinay Krishna Erannaf0e523b2014-03-01 21:00:16 +053016879 INIT_COMPLETION(pAdapter->pno_comp_var);
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053016880 pnoRequest.statusCallback = hdd_cfg80211_sched_scan_start_status_cb;
16881 pnoRequest.callbackContext = pAdapter;
Vinay Krishna Erannaf0e523b2014-03-01 21:00:16 +053016882 pAdapter->pno_req_status = 0;
16883
Nirav Shah80830bf2013-12-31 16:35:12 +053016884 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
16885 "SessionId %d, enable %d, modePNO %d, ucScanTimersCount %d",
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053016886 pAdapter->sessionId, pnoRequest.enable, pnoRequest.modePNO,
16887 pnoRequest.scanTimers.ucScanTimersCount);
Nirav Shah80830bf2013-12-31 16:35:12 +053016888
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053016889 status = sme_SetPreferredNetworkList(WLAN_HDD_GET_HAL_CTX(pAdapter),
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053016890 &pnoRequest, pAdapter->sessionId,
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053016891 hdd_cfg80211_sched_scan_done_callback, pAdapter);
16892 if (eHAL_STATUS_SUCCESS != status)
16893 {
16894 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Nirav Shah80830bf2013-12-31 16:35:12 +053016895 "%s: Failed to enable PNO", __func__);
Kamath Vinayakba5313f2013-08-22 15:52:39 +053016896 ret = -EINVAL;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053016897 goto error;
16898 }
16899
Vinay Krishna Erannaf0e523b2014-03-01 21:00:16 +053016900 ret = wait_for_completion_timeout(
16901 &pAdapter->pno_comp_var,
16902 msecs_to_jiffies(WLAN_WAIT_TIME_PNO));
16903 if (0 >= ret)
16904 {
16905 // Did not receive the response for PNO enable in time.
16906 // Assuming the PNO enable was success.
16907 // Returning error from here, because we timeout, results
16908 // in side effect of Wifi (Wifi Setting) not to work.
16909 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
16910 FL("Timed out waiting for PNO to be Enabled"));
16911 ret = 0;
Vinay Krishna Erannaf0e523b2014-03-01 21:00:16 +053016912 }
16913
16914 ret = pAdapter->pno_req_status;
c_hpothu37f21312014-04-09 21:49:54 +053016915 return ret;
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053016916
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053016917error:
Vinay Krishna Erannaf0e523b2014-03-01 21:00:16 +053016918 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
16919 FL("PNO scanRequest offloaded ret = %d"), ret);
c_hpothu37f21312014-04-09 21:49:54 +053016920 pHddCtx->isPnoEnable = FALSE;
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053016921 if (pnoRequest.aNetworks)
16922 vos_mem_free(pnoRequest.aNetworks);
16923 if (pnoRequest.p24GProbeTemplate)
16924 vos_mem_free(pnoRequest.p24GProbeTemplate);
16925 if (pnoRequest.p5GProbeTemplate)
16926 vos_mem_free(pnoRequest.p5GProbeTemplate);
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053016927
16928 EXIT();
Kamath Vinayakba5313f2013-08-22 15:52:39 +053016929 return ret;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053016930}
16931
16932/*
Mahesh A Saptasagar6cc38562014-05-23 21:22:17 +053016933 * FUNCTION: wlan_hdd_cfg80211_sched_scan_start
16934 * NL interface to enable PNO
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053016935 */
Mahesh A Saptasagar6cc38562014-05-23 21:22:17 +053016936static int wlan_hdd_cfg80211_sched_scan_start(struct wiphy *wiphy,
16937 struct net_device *dev, struct cfg80211_sched_scan_request *request)
16938{
16939 int ret;
16940
16941 vos_ssr_protect(__func__);
16942 ret = __wlan_hdd_cfg80211_sched_scan_start(wiphy, dev, request);
16943 vos_ssr_unprotect(__func__);
16944
16945 return ret;
16946}
16947
16948/*
16949 * FUNCTION: __wlan_hdd_cfg80211_sched_scan_stop
16950 * Function to disable PNO
16951 */
16952static int __wlan_hdd_cfg80211_sched_scan_stop(struct wiphy *wiphy,
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053016953 struct net_device *dev)
16954{
16955 eHalStatus status = eHAL_STATUS_FAILURE;
16956 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
16957 hdd_context_t *pHddCtx;
16958 tHalHandle hHal;
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053016959 tSirPNOScanReq pnoRequest = {0};
Kamath Vinayakba5313f2013-08-22 15:52:39 +053016960 int ret = 0;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053016961
16962 ENTER();
16963
16964 if (NULL == pAdapter)
16965 {
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053016966 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053016967 "%s: HDD adapter is Null", __func__);
16968 return -ENODEV;
16969 }
16970
16971 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053016972
Kamath Vinayakba5313f2013-08-22 15:52:39 +053016973 if (NULL == pHddCtx)
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053016974 {
Gopichand Nakkalac005b7c2013-05-14 16:04:14 +053016975 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Kamath Vinayakba5313f2013-08-22 15:52:39 +053016976 "%s: HDD context is Null", __func__);
16977 return -ENODEV;
16978 }
16979
16980 /* The return 0 is intentional when isLogpInProgress and
16981 * isLoadUnloadInProgress. We did observe a crash due to a return of
16982 * failure in sched_scan_stop , especially for a case where the unload
16983 * of the happens at the same time. The function __cfg80211_stop_sched_scan
16984 * was clearing rdev->sched_scan_req only when the sched_scan_stop returns
16985 * success. If it returns a failure , then its next invocation due to the
16986 * clean up of the second interface will have the dev pointer corresponding
16987 * to the first one leading to a crash.
16988 */
16989 if (pHddCtx->isLogpInProgress)
16990 {
16991 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
16992 "%s: LOGP in Progress. Ignore!!!", __func__);
Mahesh A Saptasagar0c11d822015-10-08 19:54:08 +053016993 pHddCtx->isPnoEnable = FALSE;
Kamath Vinayakba5313f2013-08-22 15:52:39 +053016994 return ret;
16995 }
16996
Mihir Shete18156292014-03-11 15:38:30 +053016997 if (WLAN_HDD_IS_LOAD_UNLOAD_IN_PROGRESS(pHddCtx))
Kamath Vinayakba5313f2013-08-22 15:52:39 +053016998 {
16999 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
17000 "%s: Unloading/Loading in Progress. Ignore!!!", __func__);
17001 return ret;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053017002 }
17003
17004 hHal = WLAN_HDD_GET_HAL_CTX(pAdapter);
17005 if (NULL == hHal)
17006 {
17007 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
17008 "%s: HAL context is Null!!!", __func__);
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053017009 return -EINVAL;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053017010 }
17011
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053017012 pnoRequest.enable = 0; /* Disable PNO */
17013 pnoRequest.ucNetworksCount = 0;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053017014
Konamki, Sreelakshmi7b464be2015-07-14 12:17:01 +053017015 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
17016 TRACE_CODE_HDD_CFG80211_SCHED_SCAN_STOP,
17017 pAdapter->sessionId, pAdapter->device_mode));
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053017018 status = sme_SetPreferredNetworkList(hHal, &pnoRequest,
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053017019 pAdapter->sessionId,
17020 NULL, pAdapter);
17021 if (eHAL_STATUS_SUCCESS != status)
17022 {
17023 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
17024 "Failed to disabled PNO");
Kamath Vinayakba5313f2013-08-22 15:52:39 +053017025 ret = -EINVAL;
Vinay Krishna Erannaf0e523b2014-03-01 21:00:16 +053017026 goto error;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053017027 }
c_hpothu37f21312014-04-09 21:49:54 +053017028 pHddCtx->isPnoEnable = FALSE;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053017029
Vinay Krishna Erannaf0e523b2014-03-01 21:00:16 +053017030error:
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053017031 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Vinay Krishna Erannaf0e523b2014-03-01 21:00:16 +053017032 FL("PNO scan disabled ret = %d"), ret);
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053017033
17034 EXIT();
Kamath Vinayakba5313f2013-08-22 15:52:39 +053017035 return ret;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053017036}
17037
Mahesh A Saptasagar6cc38562014-05-23 21:22:17 +053017038/*
17039 * FUNCTION: wlan_hdd_cfg80211_sched_scan_stop
17040 * NL interface to disable PNO
17041 */
17042static int wlan_hdd_cfg80211_sched_scan_stop(struct wiphy *wiphy,
17043 struct net_device *dev)
17044{
17045 int ret;
17046
17047 vos_ssr_protect(__func__);
17048 ret = __wlan_hdd_cfg80211_sched_scan_stop(wiphy, dev);
17049 vos_ssr_unprotect(__func__);
17050
17051 return ret;
17052}
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053017053#endif /*FEATURE_WLAN_SCAN_PNO*/
17054
17055
Mohit Khanna698ba2a2012-12-04 15:08:18 -080017056#ifdef FEATURE_WLAN_TDLS
Sunil Dutt Undekarieacac6f2014-03-21 14:08:53 +053017057#if TDLS_MGMT_VERSION2
Anand N Sunkad9f80b742015-07-30 20:05:51 +053017058static int __wlan_hdd_cfg80211_tdls_mgmt(struct wiphy *wiphy,
17059 struct net_device *dev,
17060 u8 *peer, u8 action_code,
17061 u8 dialog_token,
17062 u16 status_code, u32 peer_capability,
17063 const u8 *buf, size_t len)
17064#else /* TDLS_MGMT_VERSION2 */
17065#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 17, 0)) || defined(WITH_BACKPORTS)
17066static int __wlan_hdd_cfg80211_tdls_mgmt(struct wiphy *wiphy,
17067 struct net_device *dev,
17068 const u8 *peer, u8 action_code,
17069 u8 dialog_token, u16 status_code,
17070 u32 peer_capability, bool initiator,
17071 const u8 *buf, size_t len)
17072#elif (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 16, 0))
17073static int __wlan_hdd_cfg80211_tdls_mgmt(struct wiphy *wiphy,
17074 struct net_device *dev,
17075 const u8 *peer, u8 action_code,
17076 u8 dialog_token, u16 status_code,
17077 u32 peer_capability, const u8 *buf,
17078 size_t len)
17079#elif (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 15, 0))
17080static int __wlan_hdd_cfg80211_tdls_mgmt(struct wiphy *wiphy,
17081 struct net_device *dev,
17082 u8 *peer, u8 action_code,
17083 u8 dialog_token,
17084 u16 status_code, u32 peer_capability,
17085 const u8 *buf, size_t len)
Sunil Dutt Undekarieacac6f2014-03-21 14:08:53 +053017086#else
Anand N Sunkad9f80b742015-07-30 20:05:51 +053017087static int __wlan_hdd_cfg80211_tdls_mgmt(struct wiphy *wiphy,
17088 struct net_device *dev,
17089 u8 *peer, u8 action_code,
17090 u8 dialog_token,
17091 u16 status_code, const u8 *buf,
17092 size_t len)
17093#endif
Sunil Dutt Undekarieacac6f2014-03-21 14:08:53 +053017094#endif
Mohit Khanna698ba2a2012-12-04 15:08:18 -080017095{
Mahesh A Saptasagar74088392015-02-05 17:22:09 +053017096 hdd_adapter_t *pAdapter;
17097 hdd_context_t *pHddCtx;
Mohit Khanna698ba2a2012-12-04 15:08:18 -080017098 VOS_STATUS status;
Gopichand Nakkala05922802013-03-14 12:23:19 -070017099 int max_sta_failed = 0;
Hoonki Leea34dd892013-02-05 22:56:02 -080017100 int responder;
Hoonki Leed37cbb32013-04-20 00:31:14 -070017101 long rc;
Ganesh Kondabattini862aec92015-01-22 20:58:46 +053017102 int ret;
Masti, Narayanraddi3b681932015-10-08 19:22:25 +053017103 hddTdlsPeer_t *pTdlsPeer;
Anand N Sunkad9bfc2622015-07-30 15:18:54 +053017104#if !(TDLS_MGMT_VERSION2) && (LINUX_VERSION_CODE < KERNEL_VERSION(3,15,0))
Sunil Dutt Undekarieacac6f2014-03-21 14:08:53 +053017105 u32 peer_capability = 0;
17106#endif
Rajesh Chauhana34c6e62014-03-25 16:37:58 +053017107 tANI_U16 numCurrTdlsPeers;
Ganesh Kondabattini8d0d35b2015-08-20 15:39:09 +053017108 hdd_station_ctx_t *pHddStaCtx = NULL;
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053017109
Mahesh A Saptasagar74088392015-02-05 17:22:09 +053017110 pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
17111 if (NULL == pAdapter)
17112 {
17113 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
17114 "%s: Adapter is NULL",__func__);
17115 return -EINVAL;
17116 }
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053017117 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
17118 TRACE_CODE_HDD_CFG80211_TDLS_MGMT,
17119 pAdapter->sessionId, action_code));
Ganesh Kondabattini8d0d35b2015-08-20 15:39:09 +053017120
Mahesh A Saptasagar74088392015-02-05 17:22:09 +053017121 pHddCtx = wiphy_priv(wiphy);
Hoonki Lee11f7dda2013-02-14 16:55:44 -080017122 if (NULL == pHddCtx || NULL == pHddCtx->cfg_ini)
Mohit Khanna698ba2a2012-12-04 15:08:18 -080017123 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053017124 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Mohit Khanna698ba2a2012-12-04 15:08:18 -080017125 "Invalid arguments");
17126 return -EINVAL;
17127 }
Ganesh Kondabattini8d0d35b2015-08-20 15:39:09 +053017128
Sameer Thalappil75ea31a2013-02-21 19:38:16 -080017129 if (pHddCtx->isLogpInProgress)
17130 {
17131 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
17132 "%s:LOGP in Progress. Ignore!!!", __func__);
Atul Mittal115287b2014-07-08 13:26:33 +053017133 wlan_hdd_tdls_set_link_status(pAdapter,
17134 peer,
17135 eTDLS_LINK_IDLE,
17136 eTDLS_LINK_UNSPECIFIED);
Sameer Thalappil75ea31a2013-02-21 19:38:16 -080017137 return -EBUSY;
17138 }
Ganesh Kondabattini8d0d35b2015-08-20 15:39:09 +053017139
Mahesh A Saptasagar74088392015-02-05 17:22:09 +053017140 if (WLAN_HDD_IS_LOAD_UNLOAD_IN_PROGRESS(pHddCtx))
17141 {
17142 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
17143 "%s: Unloading/Loading in Progress. Ignore!!!", __func__);
17144 return -EAGAIN;
17145 }
Ganesh Kondabattini8d0d35b2015-08-20 15:39:09 +053017146
Hoonki Lee27511902013-03-14 18:19:06 -070017147 if (eTDLS_SUPPORT_NOT_ENABLED == pHddCtx->tdls_mode)
Mohit Khanna698ba2a2012-12-04 15:08:18 -080017148 {
Masti, Narayanraddi34e0e562015-03-05 18:23:03 +053017149 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Hoonki Lee27511902013-03-14 18:19:06 -070017150 "%s: TDLS mode is disabled OR not enabled in FW."
17151 MAC_ADDRESS_STR " action %d declined.",
17152 __func__, MAC_ADDR_ARRAY(peer), action_code);
Mohit Khanna698ba2a2012-12-04 15:08:18 -080017153 return -ENOTSUPP;
17154 }
Lee Hoonkic1262f22013-01-24 21:59:00 -080017155
Ganesh Kondabattini8d0d35b2015-08-20 15:39:09 +053017156 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
17157
17158 if( NULL == pHddStaCtx )
17159 {
17160 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
17161 "%s: HDD station context NULL ",__func__);
17162 return -EINVAL;
17163 }
17164
17165 /* STA should be connected and authenticated
17166 * before sending any TDLS frames
17167 */
17168 if ((eConnectionState_Associated != pHddStaCtx->conn_info.connState) ||
17169 (FALSE == pHddStaCtx->conn_info.uIsAuthenticated))
17170 {
17171 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
17172 "STA is not connected or unauthenticated. "
17173 "connState %u, uIsAuthenticated %u",
17174 pHddStaCtx->conn_info.connState,
17175 pHddStaCtx->conn_info.uIsAuthenticated);
17176 return -EAGAIN;
17177 }
17178
Hoonki Lee27511902013-03-14 18:19:06 -070017179 /* other than teardown frame, other mgmt frames are not sent if disabled */
17180 if (SIR_MAC_TDLS_TEARDOWN != action_code)
17181 {
17182 /* if tdls_mode is disabled to respond to peer's request */
17183 if (eTDLS_SUPPORT_DISABLED == pHddCtx->tdls_mode)
17184 {
Masti, Narayanraddi34e0e562015-03-05 18:23:03 +053017185 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Hoonki Lee27511902013-03-14 18:19:06 -070017186 "%s: " MAC_ADDRESS_STR
Gopichand Nakkala34d1b062013-03-19 15:28:33 -070017187 " TDLS mode is disabled. action %d declined.",
17188 __func__, MAC_ADDR_ARRAY(peer), action_code);
Hoonki Lee27511902013-03-14 18:19:06 -070017189
Ganesh Kondabattini8d0d35b2015-08-20 15:39:09 +053017190 return -ENOTSUPP;
Hoonki Lee27511902013-03-14 18:19:06 -070017191 }
Agarwal Ashish4b87f922014-06-18 03:03:21 +053017192
17193 if (vos_max_concurrent_connections_reached())
17194 {
17195 hddLog(VOS_TRACE_LEVEL_INFO, FL("Reached max concurrent connections"));
17196 return -EINVAL;
17197 }
Hoonki Lee27511902013-03-14 18:19:06 -070017198 }
17199
Gopichand Nakkalab977a972013-02-18 19:15:09 -080017200 if (WLAN_IS_TDLS_SETUP_ACTION(action_code))
17201 {
Pradeep Reddy POTTETI9db32f02015-01-29 15:22:54 +053017202 if (NULL != wlan_hdd_tdls_is_progress(pHddCtx, peer, TRUE, TRUE))
Gopichand Nakkalab977a972013-02-18 19:15:09 -080017203 {
17204 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Gopichand Nakkalac87400e2013-03-13 18:51:00 -070017205 "%s: " MAC_ADDRESS_STR
Gopichand Nakkala34d1b062013-03-19 15:28:33 -070017206 " TDLS setup is ongoing. action %d declined.",
17207 __func__, MAC_ADDR_ARRAY(peer), action_code);
17208 return -EPERM;
Gopichand Nakkalab977a972013-02-18 19:15:09 -080017209 }
17210 }
17211
Hoonki Lee11f7dda2013-02-14 16:55:44 -080017212 if (SIR_MAC_TDLS_SETUP_REQ == action_code ||
17213 SIR_MAC_TDLS_SETUP_RSP == action_code )
Lee Hoonkic1262f22013-01-24 21:59:00 -080017214 {
Rajesh Chauhana34c6e62014-03-25 16:37:58 +053017215 numCurrTdlsPeers = wlan_hdd_tdlsConnectedPeers(pAdapter);
17216 if (HDD_MAX_NUM_TDLS_STA <= numCurrTdlsPeers)
Lee Hoonkic1262f22013-01-24 21:59:00 -080017217 {
17218 /* supplicant still sends tdls_mgmt(SETUP_REQ) even after
17219 we return error code at 'add_station()'. Hence we have this
17220 check again in addtion to add_station().
17221 Anyway, there is no hard to double-check. */
Hoonki Lee11f7dda2013-02-14 16:55:44 -080017222 if (SIR_MAC_TDLS_SETUP_REQ == action_code)
Lee Hoonkic1262f22013-01-24 21:59:00 -080017223 {
Gopichand Nakkalac87400e2013-03-13 18:51:00 -070017224 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
17225 "%s: " MAC_ADDRESS_STR
Rajesh Chauhana34c6e62014-03-25 16:37:58 +053017226 " TDLS Max peer already connected. action (%d) declined. Num of peers (%d), Max allowed (%d).",
17227 __func__, MAC_ADDR_ARRAY(peer), action_code,
17228 numCurrTdlsPeers, HDD_MAX_NUM_TDLS_STA);
Sunil Dutt388ac8f2013-11-28 18:06:52 +053017229 return -EINVAL;
Lee Hoonkic1262f22013-01-24 21:59:00 -080017230 }
17231 else
17232 {
Gopichand Nakkalab977a972013-02-18 19:15:09 -080017233 /* maximum reached. tweak to send error code to peer and return
17234 error code to supplicant */
Lee Hoonkic1262f22013-01-24 21:59:00 -080017235 status_code = eSIR_MAC_UNSPEC_FAILURE_STATUS;
Gopichand Nakkalac87400e2013-03-13 18:51:00 -070017236 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
17237 "%s: " MAC_ADDRESS_STR
Rajesh Chauhana34c6e62014-03-25 16:37:58 +053017238 " TDLS Max peer already connected, send response status (%d). Num of peers (%d), Max allowed (%d).",
17239 __func__, MAC_ADDR_ARRAY(peer), status_code,
17240 numCurrTdlsPeers, HDD_MAX_NUM_TDLS_STA);
Gopichand Nakkala05922802013-03-14 12:23:19 -070017241 max_sta_failed = -EPERM;
Gopichand Nakkalab977a972013-02-18 19:15:09 -080017242 /* fall through to send setup resp with failure status
17243 code */
Lee Hoonkic1262f22013-01-24 21:59:00 -080017244 }
17245 }
Hoonki Lee11f7dda2013-02-14 16:55:44 -080017246 else
17247 {
Masti, Narayanraddi6b93b472015-09-04 17:48:11 +053017248 mutex_lock(&pHddCtx->tdls_lock);
17249 pTdlsPeer = wlan_hdd_tdls_find_peer(pAdapter, peer, FALSE);
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -070017250 if (pTdlsPeer && TDLS_IS_CONNECTED(pTdlsPeer))
Hoonki Lee11f7dda2013-02-14 16:55:44 -080017251 {
Masti, Narayanraddi6b93b472015-09-04 17:48:11 +053017252 mutex_unlock(&pHddCtx->tdls_lock);
Gopichand Nakkalac87400e2013-03-13 18:51:00 -070017253 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Gopichand Nakkala34d1b062013-03-19 15:28:33 -070017254 "%s:" MAC_ADDRESS_STR " already connected. action %d declined.",
17255 __func__, MAC_ADDR_ARRAY(peer), action_code);
Hoonki Lee11f7dda2013-02-14 16:55:44 -080017256 return -EPERM;
17257 }
Masti, Narayanraddi6b93b472015-09-04 17:48:11 +053017258 mutex_unlock(&pHddCtx->tdls_lock);
Hoonki Lee11f7dda2013-02-14 16:55:44 -080017259 }
Lee Hoonkic1262f22013-01-24 21:59:00 -080017260 }
Mohit Khanna698ba2a2012-12-04 15:08:18 -080017261
Masti, Narayanraddi34e0e562015-03-05 18:23:03 +053017262 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Arun Kumar Khandavalli9fb625e2014-03-17 16:07:40 +053017263 "%s: " MAC_ADDRESS_STR " action %d, dialog_token %d status %d, len = %zu",
Gopichand Nakkalac87400e2013-03-13 18:51:00 -070017264 "tdls_mgmt", MAC_ADDR_ARRAY(peer),
17265 action_code, dialog_token, status_code, len);
Mohit Khanna698ba2a2012-12-04 15:08:18 -080017266
Hoonki Leea34dd892013-02-05 22:56:02 -080017267 /*Except teardown responder will not be used so just make 0*/
17268 responder = 0;
Hoonki Lee11f7dda2013-02-14 16:55:44 -080017269 if (SIR_MAC_TDLS_TEARDOWN == action_code)
Hoonki Leea34dd892013-02-05 22:56:02 -080017270 {
Gopichand Nakkala97a65fd2013-04-16 16:59:38 -070017271
Masti, Narayanraddi6b93b472015-09-04 17:48:11 +053017272 mutex_lock(&pHddCtx->tdls_lock);
17273 pTdlsPeer = wlan_hdd_tdls_find_peer(pAdapter, peer, FALSE);
Gopichand Nakkala97a65fd2013-04-16 16:59:38 -070017274
17275 if(pTdlsPeer && TDLS_IS_CONNECTED(pTdlsPeer))
17276 responder = pTdlsPeer->is_responder;
17277 else
Hoonki Leea34dd892013-02-05 22:56:02 -080017278 {
Gopichand Nakkala97a65fd2013-04-16 16:59:38 -070017279 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Arun Kumar Khandavalli9fb625e2014-03-17 16:07:40 +053017280 "%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 -070017281 __func__, MAC_ADDR_ARRAY(peer), (NULL == pTdlsPeer) ? -1 : pTdlsPeer->link_status,
17282 dialog_token, status_code, len);
Masti, Narayanraddi6b93b472015-09-04 17:48:11 +053017283 mutex_unlock(&pHddCtx->tdls_lock);
Gopichand Nakkala97a65fd2013-04-16 16:59:38 -070017284 return -EPERM;
Hoonki Leea34dd892013-02-05 22:56:02 -080017285 }
Masti, Narayanraddi6b93b472015-09-04 17:48:11 +053017286 mutex_unlock(&pHddCtx->tdls_lock);
Mohit Khanna698ba2a2012-12-04 15:08:18 -080017287 }
Mohit Khanna698ba2a2012-12-04 15:08:18 -080017288
Masti, Narayanraddi3b681932015-10-08 19:22:25 +053017289 /* Discard TDLS setup if peer is removed by user app */
17290 if ((pHddCtx->cfg_ini->fTDLSExternalControl) &&
17291 ((SIR_MAC_TDLS_SETUP_REQ == action_code) ||
17292 (SIR_MAC_TDLS_SETUP_CNF == action_code) ||
17293 (SIR_MAC_TDLS_DIS_REQ == action_code))) {
17294
17295 mutex_lock(&pHddCtx->tdls_lock);
17296 pTdlsPeer = wlan_hdd_tdls_find_peer(pAdapter, peer, FALSE);
17297 if (pTdlsPeer && (FALSE == pTdlsPeer->isForcedPeer)) {
17298 mutex_unlock(&pHddCtx->tdls_lock);
17299 hddLog(LOGE, FL("TDLS External Control enabled, but peer "
17300 MAC_ADDRESS_STR " is not forced, so reject the action code %d"),
17301 MAC_ADDR_ARRAY(peer), action_code);
17302 return -EINVAL;
17303 }
17304 mutex_unlock(&pHddCtx->tdls_lock);
17305 }
17306
Gopichand Nakkala2f1ff152013-07-01 11:27:43 +053017307 /* For explicit trigger of DIS_REQ come out of BMPS for
17308 successfully receiving DIS_RSP from peer. */
Hoonki Lee14621352013-04-16 17:51:19 -070017309 if ((SIR_MAC_TDLS_SETUP_RSP == action_code) ||
Gopichand Nakkala2f1ff152013-07-01 11:27:43 +053017310 (SIR_MAC_TDLS_DIS_RSP == action_code) ||
17311 (SIR_MAC_TDLS_DIS_REQ == action_code))
Hoonki Lee14621352013-04-16 17:51:19 -070017312 {
17313 if (TRUE == sme_IsPmcBmps(WLAN_HDD_GET_HAL_CTX(pAdapter)))
17314 {
Masti, Narayanraddi34e0e562015-03-05 18:23:03 +053017315 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Gopichand Nakkala2f1ff152013-07-01 11:27:43 +053017316 "%s: Sending frame action_code %u.Disable BMPS", __func__, action_code);
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053017317 status = hdd_disable_bmps_imps(pHddCtx, WLAN_HDD_INFRA_STATION);
17318 if (status != VOS_STATUS_SUCCESS) {
17319 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Failed to set BMPS/IMPS"));
17320 }
Hoonki Lee14621352013-04-16 17:51:19 -070017321 }
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053017322 if (SIR_MAC_TDLS_DIS_REQ != action_code) {
Anand N Sunkad9bfc2622015-07-30 15:18:54 +053017323 if (0 != wlan_hdd_tdls_set_cap(pAdapter, peer, eTDLS_CAP_SUPPORTED)) {
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053017324 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Failed to set TDLS capabilities"));
17325 }
17326 }
Hoonki Lee14621352013-04-16 17:51:19 -070017327 }
17328
Hoonki Lee5305c3a2013-04-29 23:28:59 -070017329 /* make sure doesn't call send_mgmt() while it is pending */
17330 if (TDLS_CTX_MAGIC == pAdapter->mgmtTxCompletionStatus)
17331 {
17332 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Arif Hussain6d2a3322013-11-17 19:50:10 -080017333 "%s: " MAC_ADDRESS_STR " action %d couldn't sent, as one is pending. return EBUSY",
Hoonki Lee5305c3a2013-04-29 23:28:59 -070017334 __func__, MAC_ADDR_ARRAY(peer), action_code);
Ganesh Kondabattini862aec92015-01-22 20:58:46 +053017335 ret = -EBUSY;
17336 goto tx_failed;
Hoonki Lee5305c3a2013-04-29 23:28:59 -070017337 }
17338
17339 pAdapter->mgmtTxCompletionStatus = TDLS_CTX_MAGIC;
Gopichand Nakkalab977a972013-02-18 19:15:09 -080017340 INIT_COMPLETION(pAdapter->tdls_mgmt_comp);
17341
Ganesh Kondabattini8d0d35b2015-08-20 15:39:09 +053017342 status = sme_SendTdlsMgmtFrame(WLAN_HDD_GET_HAL_CTX(pAdapter),
17343 pAdapter->sessionId, peer, action_code, dialog_token,
17344 status_code, peer_capability, (tANI_U8 *)buf, len,
17345 responder);
Mohit Khanna698ba2a2012-12-04 15:08:18 -080017346
Gopichand Nakkalab977a972013-02-18 19:15:09 -080017347 if (VOS_STATUS_SUCCESS != status)
17348 {
Mohit Khanna698ba2a2012-12-04 15:08:18 -080017349 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
17350 "%s: sme_SendTdlsMgmtFrame failed!", __func__);
Hoonki Lee5305c3a2013-04-29 23:28:59 -070017351 pAdapter->mgmtTxCompletionStatus = FALSE;
Ganesh Kondabattini862aec92015-01-22 20:58:46 +053017352 ret = -EINVAL;
17353 goto tx_failed;
Mohit Khanna698ba2a2012-12-04 15:08:18 -080017354 }
17355
Ganesh Kondabattini8d0d35b2015-08-20 15:39:09 +053017356 if ((SIR_MAC_TDLS_DIS_REQ == action_code) ||
17357 (SIR_MAC_TDLS_DIS_RSP == action_code))
17358 {
17359 /* for DIS_REQ/DIS_RSP, supplicant don't consider the return status.
17360 * So we no need to wait for tdls_mgmt_comp for sending ack status.
17361 */
17362 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
17363 "%s: tx done for frm %u", __func__, action_code);
17364 return 0;
17365 }
17366
17367 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
17368 "%s: Wait for tdls_mgmt_comp. Timeout %u ms", __func__,
17369 WAIT_TIME_TDLS_MGMT);
17370
Hoonki Leed37cbb32013-04-20 00:31:14 -070017371 rc = wait_for_completion_interruptible_timeout(&pAdapter->tdls_mgmt_comp,
17372 msecs_to_jiffies(WAIT_TIME_TDLS_MGMT));
17373
17374 if ((rc <= 0) || (TRUE != pAdapter->mgmtTxCompletionStatus))
Gopichand Nakkalab977a972013-02-18 19:15:09 -080017375 {
Hoonki Leed37cbb32013-04-20 00:31:14 -070017376 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Jeff Johnson0299d0a2013-10-30 12:37:43 -070017377 "%s: Mgmt Tx Completion failed status %ld TxCompletion %u",
Hoonki Leed37cbb32013-04-20 00:31:14 -070017378 __func__, rc, pAdapter->mgmtTxCompletionStatus);
Hoonki Lee5305c3a2013-04-29 23:28:59 -070017379 pAdapter->mgmtTxCompletionStatus = FALSE;
Yue Ma4f55ef32014-01-23 16:45:33 -080017380
17381 if (pHddCtx->isLogpInProgress)
17382 {
17383 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
17384 "%s: LOGP in Progress. Ignore!!!", __func__);
17385 return -EAGAIN;
17386 }
Abhishek Singh837adf22015-10-01 17:37:37 +053017387 if (rc <= 0)
17388 vos_fatal_event_logs_req(WLAN_LOG_TYPE_FATAL,
17389 WLAN_LOG_INDICATOR_HOST_DRIVER,
17390 WLAN_LOG_REASON_HDD_TIME_OUT,
17391 TRUE, TRUE);
Yue Ma4f55ef32014-01-23 16:45:33 -080017392
Ganesh Kondabattini862aec92015-01-22 20:58:46 +053017393 ret = -EINVAL;
17394 goto tx_failed;
Gopichand Nakkalab977a972013-02-18 19:15:09 -080017395 }
Ganesh Kondabattini8d0d35b2015-08-20 15:39:09 +053017396 else
17397 {
17398 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
17399 "%s: Mgmt Tx Completion status %ld TxCompletion %u",
17400 __func__, rc, pAdapter->mgmtTxCompletionStatus);
17401 }
Gopichand Nakkalab977a972013-02-18 19:15:09 -080017402
Gopichand Nakkala05922802013-03-14 12:23:19 -070017403 if (max_sta_failed)
Hoonki Lee14621352013-04-16 17:51:19 -070017404 {
Ganesh Kondabattini862aec92015-01-22 20:58:46 +053017405 ret = max_sta_failed;
17406 goto tx_failed;
Hoonki Lee14621352013-04-16 17:51:19 -070017407 }
Gopichand Nakkalab977a972013-02-18 19:15:09 -080017408
Hoonki Leea34dd892013-02-05 22:56:02 -080017409 if (SIR_MAC_TDLS_SETUP_RSP == action_code)
17410 {
Anand N Sunkad9bfc2622015-07-30 15:18:54 +053017411 if (0 != wlan_hdd_tdls_set_responder(pAdapter, peer, TRUE)) {
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053017412 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Failed to set TDLS responder: Setup Response"));
17413 }
Hoonki Leea34dd892013-02-05 22:56:02 -080017414 }
17415 else if (SIR_MAC_TDLS_SETUP_CNF == action_code)
17416 {
Anand N Sunkad9bfc2622015-07-30 15:18:54 +053017417 if (0 != wlan_hdd_tdls_set_responder(pAdapter, peer, FALSE)) {
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053017418 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Failed to set TDLS responder: Setup Response"));
17419 }
Hoonki Leea34dd892013-02-05 22:56:02 -080017420 }
Mohit Khanna698ba2a2012-12-04 15:08:18 -080017421
17422 return 0;
Ganesh Kondabattini862aec92015-01-22 20:58:46 +053017423
17424tx_failed:
17425 /* add_station will be called before sending TDLS_SETUP_REQ and
17426 * TDLS_SETUP_RSP and as part of add_station driver will enable
17427 * BMPS. NL80211_TDLS_DISABLE_LINK will be called if the tx of
17428 * TDLS_SETUP_REQ or TDLS_SETUP_RSP fails. BMPS will be enabled
17429 * as part of processing NL80211_TDLS_DISABLE_LINK. So need to
17430 * enable BMPS for TDLS_SETUP_REQ and TDLS_SETUP_RSP if tx fails.
17431 */
17432
17433 if ((SIR_MAC_TDLS_SETUP_REQ == action_code) ||
17434 (SIR_MAC_TDLS_SETUP_RSP == action_code))
17435 wlan_hdd_tdls_check_bmps(pAdapter);
17436 return ret;
Mohit Khanna698ba2a2012-12-04 15:08:18 -080017437}
17438
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053017439#if TDLS_MGMT_VERSION2
17440static int wlan_hdd_cfg80211_tdls_mgmt(struct wiphy *wiphy, struct net_device *dev,
17441 u8 *peer, u8 action_code, u8 dialog_token,
17442 u16 status_code, u32 peer_capability,
17443 const u8 *buf, size_t len)
Anand N Sunkad9bfc2622015-07-30 15:18:54 +053017444#else /* TDLS_MGMT_VERSION2 */
17445#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,17,0))
17446static int wlan_hdd_cfg80211_tdls_mgmt(struct wiphy *wiphy,
17447 struct net_device *dev,
17448 const u8 *peer, u8 action_code,
17449 u8 dialog_token, u16 status_code,
17450 u32 peer_capability, bool initiator,
17451 const u8 *buf, size_t len)
17452#elif (LINUX_VERSION_CODE >= KERNEL_VERSION(3,16,0))
17453static int wlan_hdd_cfg80211_tdls_mgmt(struct wiphy *wiphy,
17454 struct net_device *dev,
17455 const u8 *peer, u8 action_code,
17456 u8 dialog_token, u16 status_code,
17457 u32 peer_capability, const u8 *buf,
17458 size_t len)
17459#elif (LINUX_VERSION_CODE >= KERNEL_VERSION(3,15,0))
17460static int wlan_hdd_cfg80211_tdls_mgmt(struct wiphy *wiphy,
17461 struct net_device *dev,
17462 u8 *peer, u8 action_code,
17463 u8 dialog_token,
17464 u16 status_code, u32 peer_capability,
17465 const u8 *buf, size_t len)
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053017466#else
17467static int wlan_hdd_cfg80211_tdls_mgmt(struct wiphy *wiphy, struct net_device *dev,
17468 u8 *peer, u8 action_code, u8 dialog_token,
17469 u16 status_code, const u8 *buf, size_t len)
17470#endif
Anand N Sunkad9bfc2622015-07-30 15:18:54 +053017471#endif
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053017472{
17473 int ret;
17474
Anand N Sunkad9f80b742015-07-30 20:05:51 +053017475 vos_ssr_protect(__func__);
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053017476#if TDLS_MGMT_VERSION2
Anand N Sunkad9f80b742015-07-30 20:05:51 +053017477 ret = __wlan_hdd_cfg80211_tdls_mgmt(wiphy, dev, peer, action_code,
17478 dialog_token, status_code,
17479 peer_capability, buf, len);
17480#else /* TDLS_MGMT_VERSION2 */
17481#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 17, 0)) || defined(WITH_BACKPORTS)
17482 ret = __wlan_hdd_cfg80211_tdls_mgmt(wiphy, dev, peer, action_code,
17483 dialog_token, status_code,
17484 peer_capability, initiator,
17485 buf, len);
17486#elif (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 16, 0))
17487 ret = __wlan_hdd_cfg80211_tdls_mgmt(wiphy, dev, peer, action_code,
17488 dialog_token, status_code,
17489 peer_capability, buf, len);
17490#elif (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 15, 0))
17491 ret = __wlan_hdd_cfg80211_tdls_mgmt(wiphy, dev, peer, action_code,
17492 dialog_token, status_code,
17493 peer_capability, buf, len);
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053017494#else
Anand N Sunkad9f80b742015-07-30 20:05:51 +053017495 ret = __wlan_hdd_cfg80211_tdls_mgmt(wiphy, dev, peer, action_code,
17496 dialog_token, status_code, buf, len);
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053017497#endif
Anand N Sunkad9f80b742015-07-30 20:05:51 +053017498#endif
17499 vos_ssr_unprotect(__func__);
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053017500
Anand N Sunkad9f80b742015-07-30 20:05:51 +053017501 return ret;
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053017502}
Atul Mittal115287b2014-07-08 13:26:33 +053017503
17504int wlan_hdd_tdls_extctrl_config_peer(hdd_adapter_t *pAdapter,
Anand N Sunkad9bfc2622015-07-30 15:18:54 +053017505#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,18,0))
17506 const u8 *peer,
17507#else
Atul Mittal115287b2014-07-08 13:26:33 +053017508 u8 *peer,
Anand N Sunkad9bfc2622015-07-30 15:18:54 +053017509#endif
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053017510 tdls_req_params_t *tdls_peer_params,
Atul Mittal115287b2014-07-08 13:26:33 +053017511 cfg80211_exttdls_callback callback)
17512{
17513
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053017514 hddTdlsPeer_t *pTdlsPeer = NULL;
Atul Mittal115287b2014-07-08 13:26:33 +053017515 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Pradeep Reddy POTTETIe30ed252015-02-18 14:27:55 +053017516 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
Atul Mittal115287b2014-07-08 13:26:33 +053017517 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
17518 " %s : NL80211_TDLS_SETUP for " MAC_ADDRESS_STR,
17519 __func__, MAC_ADDR_ARRAY(peer));
17520
17521 if ( (FALSE == pHddCtx->cfg_ini->fTDLSExternalControl) ||
17522 (FALSE == pHddCtx->cfg_ini->fEnableTDLSImplicitTrigger) ) {
17523
17524 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053017525 " %s TDLS External control (%d) and Implicit Trigger (%d) not enabled ",
17526 __func__, pHddCtx->cfg_ini->fTDLSExternalControl,
17527 pHddCtx->cfg_ini->fEnableTDLSImplicitTrigger);
Atul Mittal115287b2014-07-08 13:26:33 +053017528 return -ENOTSUPP;
17529 }
17530
17531 /* To cater the requirement of establishing the TDLS link
17532 * irrespective of the data traffic , get an entry of TDLS peer.
17533 */
Masti, Narayanraddi6dbcdbb2015-05-13 10:28:06 +053017534 mutex_lock(&pHddCtx->tdls_lock);
Atul Mittal115287b2014-07-08 13:26:33 +053017535 pTdlsPeer = wlan_hdd_tdls_get_peer(pAdapter, peer);
17536 if (pTdlsPeer == NULL) {
17537 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
17538 "%s: peer " MAC_ADDRESS_STR " not existing",
17539 __func__, MAC_ADDR_ARRAY(peer));
Masti, Narayanraddi6dbcdbb2015-05-13 10:28:06 +053017540 mutex_unlock(&pHddCtx->tdls_lock);
Atul Mittal115287b2014-07-08 13:26:33 +053017541 return -EINVAL;
17542 }
17543
Pradeep Reddy POTTETI60ad2402015-02-26 16:48:21 +053017544 /* check FW TDLS Off Channel capability */
17545 if ((TRUE == sme_IsFeatureSupportedByFW(TDLS_OFF_CHANNEL)) &&
Pradeep Reddy POTTETI0cb99bc2015-06-08 12:59:09 +053017546 (TRUE == pHddCtx->cfg_ini->fEnableTDLSOffChannel) &&
Pradeep Reddy POTTETI60ad2402015-02-26 16:48:21 +053017547 (NULL != tdls_peer_params))
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053017548 {
17549 pTdlsPeer->peerParams.channel = tdls_peer_params->channel;
17550 pTdlsPeer->peerParams.global_operating_class =
17551 tdls_peer_params->global_operating_class;
17552 pTdlsPeer->peerParams.max_latency_ms = tdls_peer_params->max_latency_ms;
17553 pTdlsPeer->peerParams.min_bandwidth_kbps =
17554 tdls_peer_params->min_bandwidth_kbps;
Pradeep Reddy POTTETIe30ed252015-02-18 14:27:55 +053017555 /* check configured channel is valid, non dfs and
17556 * not current operating channel */
17557 if ((sme_IsTdlsOffChannelValid(WLAN_HDD_GET_HAL_CTX(pAdapter),
17558 tdls_peer_params->channel)) &&
17559 (pHddStaCtx) &&
17560 (tdls_peer_params->channel !=
17561 pHddStaCtx->conn_info.operationChannel))
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053017562 {
17563 pTdlsPeer->isOffChannelConfigured = TRUE;
17564 }
17565 else
17566 {
17567 pTdlsPeer->isOffChannelConfigured = FALSE;
17568 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
17569 "%s: Configured Tdls Off Channel is not valid", __func__);
17570
17571 }
17572 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Pradeep Reddy POTTETIe30ed252015-02-18 14:27:55 +053017573 "%s: tdls_off_channel %d isOffChannelConfigured %d "
17574 "current operating channel %d",
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053017575 __func__, pTdlsPeer->peerParams.channel,
Pradeep Reddy POTTETIe30ed252015-02-18 14:27:55 +053017576 pTdlsPeer->isOffChannelConfigured,
17577 (pHddStaCtx ? pHddStaCtx->conn_info.operationChannel : 0));
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053017578 }
17579 else
17580 {
17581 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Pradeep Reddy POTTETI0cb99bc2015-06-08 12:59:09 +053017582 "%s: TDLS off channel FW capability %d, "
17583 "host capab %d or Invalid TDLS Peer Params", __func__,
17584 sme_IsFeatureSupportedByFW(TDLS_OFF_CHANNEL),
17585 pHddCtx->cfg_ini->fEnableTDLSOffChannel);
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053017586 }
17587
Atul Mittal115287b2014-07-08 13:26:33 +053017588 if ( 0 != wlan_hdd_tdls_set_force_peer(pAdapter, peer, TRUE) ) {
17589
Masti, Narayanraddi6b93b472015-09-04 17:48:11 +053017590 mutex_unlock(&pHddCtx->tdls_lock);
17591
Atul Mittal115287b2014-07-08 13:26:33 +053017592 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
17593 " %s TDLS Add Force Peer Failed",
17594 __func__);
17595 return -EINVAL;
17596 }
17597 /*EXT TDLS*/
17598
17599 if ( 0 != wlan_hdd_set_callback(pTdlsPeer, callback) ) {
Masti, Narayanraddi6b93b472015-09-04 17:48:11 +053017600 mutex_unlock(&pHddCtx->tdls_lock);
Atul Mittal115287b2014-07-08 13:26:33 +053017601 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
17602 " %s TDLS set callback Failed",
17603 __func__);
17604 return -EINVAL;
17605 }
17606
Masti, Narayanraddi6b93b472015-09-04 17:48:11 +053017607 mutex_unlock(&pHddCtx->tdls_lock);
17608
Atul Mittal115287b2014-07-08 13:26:33 +053017609 return(0);
17610
17611}
17612
Anand N Sunkad9bfc2622015-07-30 15:18:54 +053017613int wlan_hdd_tdls_extctrl_deconfig_peer(hdd_adapter_t *pAdapter,
17614#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,18,0))
17615 const u8 *peer
17616#else
17617 u8 *peer
17618#endif
17619)
Atul Mittal115287b2014-07-08 13:26:33 +053017620{
17621
17622 hddTdlsPeer_t *pTdlsPeer;
17623 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
17624 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
17625 " %s : NL80211_TDLS_TEARDOWN for " MAC_ADDRESS_STR,
17626 __func__, MAC_ADDR_ARRAY(peer));
17627
Chandrasekaran, Manishekar41b8e1f2015-03-10 13:30:28 +053017628 if (0 != wlan_hdd_validate_context(pHddCtx)) {
17629 hddLog(VOS_TRACE_LEVEL_ERROR, FL("HDD context is NULL"));
17630 return -EINVAL;
17631 }
17632
Atul Mittal115287b2014-07-08 13:26:33 +053017633 if ( (FALSE == pHddCtx->cfg_ini->fTDLSExternalControl) ||
17634 (FALSE == pHddCtx->cfg_ini->fEnableTDLSImplicitTrigger) ) {
17635
17636 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053017637 " %s TDLS External control (%d) and Implicit Trigger (%d) not enabled ",
17638 __func__, pHddCtx->cfg_ini->fTDLSExternalControl,
17639 pHddCtx->cfg_ini->fEnableTDLSImplicitTrigger);
Atul Mittal115287b2014-07-08 13:26:33 +053017640 return -ENOTSUPP;
17641 }
17642
Masti, Narayanraddi6b93b472015-09-04 17:48:11 +053017643 mutex_lock(&pHddCtx->tdls_lock);
17644 pTdlsPeer = wlan_hdd_tdls_find_peer(pAdapter, peer, FALSE);
Atul Mittal115287b2014-07-08 13:26:33 +053017645
17646 if ( NULL == pTdlsPeer ) {
Masti, Narayanraddi6b93b472015-09-04 17:48:11 +053017647 mutex_unlock(&pHddCtx->tdls_lock);
Atul Mittal115287b2014-07-08 13:26:33 +053017648 hddLog(VOS_TRACE_LEVEL_INFO, "%s: " MAC_ADDRESS_STR
Agarwal Ashisha7ef41d2015-06-25 18:00:26 +053017649 " peer not existing",
Atul Mittal115287b2014-07-08 13:26:33 +053017650 __func__, MAC_ADDR_ARRAY(peer));
17651 return -EINVAL;
17652 }
17653 else {
17654 wlan_hdd_tdls_indicate_teardown(pAdapter, pTdlsPeer,
17655 eSIR_MAC_TDLS_TEARDOWN_UNSPEC_REASON);
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053017656 /* if channel switch is configured, reset
17657 the channel for this peer */
17658 if (TRUE == pTdlsPeer->isOffChannelConfigured)
17659 {
17660 pTdlsPeer->peerParams.channel = 0;
17661 pTdlsPeer->isOffChannelConfigured = FALSE;
17662 }
Atul Mittal115287b2014-07-08 13:26:33 +053017663 }
17664
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053017665 if ( 0 != wlan_hdd_tdls_set_force_peer(pAdapter, peer, FALSE) ) {
Masti, Narayanraddi6b93b472015-09-04 17:48:11 +053017666 mutex_unlock(&pHddCtx->tdls_lock);
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053017667 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Failed to set force peer"));
Atul Mittal115287b2014-07-08 13:26:33 +053017668 return -EINVAL;
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053017669 }
Atul Mittal115287b2014-07-08 13:26:33 +053017670
17671 /*EXT TDLS*/
17672
17673 if ( 0 != wlan_hdd_set_callback(pTdlsPeer, NULL )) {
Masti, Narayanraddi6b93b472015-09-04 17:48:11 +053017674 mutex_unlock(&pHddCtx->tdls_lock);
Atul Mittal115287b2014-07-08 13:26:33 +053017675 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
17676 " %s TDLS set callback Failed",
17677 __func__);
17678 return -EINVAL;
17679 }
Atul Mittal115287b2014-07-08 13:26:33 +053017680
Masti, Narayanraddi6b93b472015-09-04 17:48:11 +053017681 mutex_unlock(&pHddCtx->tdls_lock);
17682
17683 return(0);
Atul Mittal115287b2014-07-08 13:26:33 +053017684}
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053017685static int __wlan_hdd_cfg80211_tdls_oper(struct wiphy *wiphy, struct net_device *dev,
Anand N Sunkad9bfc2622015-07-30 15:18:54 +053017686#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,18,0))
17687 const u8 *peer,
17688#else
17689 u8 *peer,
17690#endif
17691 enum nl80211_tdls_operation oper)
Mohit Khanna698ba2a2012-12-04 15:08:18 -080017692{
17693 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
17694 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053017695 int status;
Hoonki Lee5305c3a2013-04-29 23:28:59 -070017696 hddTdlsPeer_t *pTdlsPeer;
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053017697
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053017698 ENTER();
17699
Chandrasekaran, Manishekar41b8e1f2015-03-10 13:30:28 +053017700 if (!pAdapter) {
17701 hddLog(VOS_TRACE_LEVEL_ERROR, FL("HDD adpater is NULL"));
17702 return -EINVAL;
17703 }
17704
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053017705 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
17706 TRACE_CODE_HDD_CFG80211_TDLS_OPER,
17707 pAdapter->sessionId, oper));
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053017708 if ( NULL == peer )
Mohit Khanna698ba2a2012-12-04 15:08:18 -080017709 {
Gopichand Nakkalab977a972013-02-18 19:15:09 -080017710 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Chilam Ngc4244af2013-04-01 15:37:32 -070017711 "%s: Invalid arguments", __func__);
Mohit Khanna698ba2a2012-12-04 15:08:18 -080017712 return -EINVAL;
17713 }
Hoonki Lee1090c6a2013-01-16 17:40:54 -080017714
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053017715 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053017716 if (0 != status)
Sameer Thalappil75ea31a2013-02-21 19:38:16 -080017717 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053017718 return status;
Sameer Thalappil75ea31a2013-02-21 19:38:16 -080017719 }
17720
Mohit Khanna698ba2a2012-12-04 15:08:18 -080017721
17722 if( FALSE == pHddCtx->cfg_ini->fEnableTDLSSupport ||
Hoonki Lee1090c6a2013-01-16 17:40:54 -080017723 FALSE == sme_IsFeatureSupportedByFW(TDLS))
Mohit Khanna698ba2a2012-12-04 15:08:18 -080017724 {
Hoonki Lee1090c6a2013-01-16 17:40:54 -080017725 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053017726 "TDLS Disabled in INI (%d) OR not enabled in FW (%d) "
17727 "Cannot process TDLS commands",
17728 pHddCtx->cfg_ini->fEnableTDLSSupport,
17729 sme_IsFeatureSupportedByFW(TDLS));
Mohit Khanna698ba2a2012-12-04 15:08:18 -080017730 return -ENOTSUPP;
17731 }
17732
17733 switch (oper) {
17734 case NL80211_TDLS_ENABLE_LINK:
17735 {
Mohit Khanna698ba2a2012-12-04 15:08:18 -080017736 VOS_STATUS status;
c_hpothu6ff1c3c2013-10-01 19:01:57 +053017737 long ret;
Gopichand Nakkala79ff85d2013-05-27 17:05:29 +053017738 tCsrTdlsLinkEstablishParams tdlsLinkEstablishParams;
Agarwal Ashish16020c42014-12-29 22:01:11 +053017739 WLAN_STADescType staDesc;
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053017740 tANI_U16 numCurrTdlsPeers = 0;
17741 hddTdlsPeer_t *connPeer = NULL;
Pradeep Reddy POTTETIfcac7902015-04-16 12:25:17 +053017742 tANI_U8 suppChannelLen = 0;
Mohit Khanna698ba2a2012-12-04 15:08:18 -080017743
Agarwal Ashisha7ef41d2015-06-25 18:00:26 +053017744 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
17745 " %s : NL80211_TDLS_ENABLE_LINK for " MAC_ADDRESS_STR,
17746 __func__, MAC_ADDR_ARRAY(peer));
Masti, Narayanraddi6b93b472015-09-04 17:48:11 +053017747
Sunil Dutt41de4e22013-11-14 18:09:02 +053017748 pTdlsPeer = wlan_hdd_tdls_find_peer(pAdapter, peer, TRUE);
Agarwal Ashish16020c42014-12-29 22:01:11 +053017749 memset(&staDesc, 0, sizeof(staDesc));
Sunil Dutt41de4e22013-11-14 18:09:02 +053017750 if ( NULL == pTdlsPeer ) {
17751 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: " MAC_ADDRESS_STR
17752 " (oper %d) not exsting. ignored",
17753 __func__, MAC_ADDR_ARRAY(peer), (int)oper);
17754 return -EINVAL;
17755 }
17756
17757 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
17758 "%s: " MAC_ADDRESS_STR " link_status %d (%s) ", "tdls_oper",
17759 MAC_ADDR_ARRAY(peer), pTdlsPeer->link_status,
17760 "NL80211_TDLS_ENABLE_LINK");
17761
Gopichand Nakkala2f4a2822013-04-17 11:22:01 -070017762 if (!TDLS_STA_INDEX_VALID(pTdlsPeer->staId))
17763 {
17764 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Invalid Staion Index %u "
17765 MAC_ADDRESS_STR " failed",
17766 __func__, pTdlsPeer->staId, MAC_ADDR_ARRAY(peer));
17767 return -EINVAL;
17768 }
17769
Pradeep Reddy POTTETIf3148e82015-04-16 12:10:33 +053017770 /* before starting tdls connection, set tdls
17771 * off channel established status to default value */
17772 pTdlsPeer->isOffChannelEstablished = FALSE;
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053017773 /* TDLS Off Channel, Disable tdls channel switch,
17774 when there are more than one tdls link */
17775 numCurrTdlsPeers = wlan_hdd_tdlsConnectedPeers(pAdapter);
Pradeep Reddy POTTETIa9991b62015-03-26 18:03:19 +053017776 if (numCurrTdlsPeers == 2)
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053017777 {
17778 /* get connected peer and send disable tdls off chan */
17779 connPeer = wlan_hdd_tdls_get_connected_peer(pAdapter);
Pradeep Reddy POTTETIfdaf38b2015-05-13 13:01:22 +053017780 if ((connPeer) &&
17781 (connPeer->isOffChannelSupported == TRUE) &&
17782 (connPeer->isOffChannelConfigured == TRUE))
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053017783 {
17784 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
17785 "%s: More then one peer connected, Disable "
17786 "TDLS channel switch", __func__);
17787
Pradeep Reddy POTTETI16d83332015-03-26 18:28:13 +053017788 connPeer->isOffChannelEstablished = FALSE;
Masti, Narayanraddi6b93b472015-09-04 17:48:11 +053017789
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053017790 ret = sme_SendTdlsChanSwitchReq(
17791 WLAN_HDD_GET_HAL_CTX(pAdapter),
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053017792 pAdapter->sessionId,
17793 connPeer->peerMac,
17794 connPeer->peerParams.channel,
17795 TDLS_OFF_CHANNEL_BW_OFFSET,
17796 TDLS_CHANNEL_SWITCH_DISABLE);
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053017797 if (ret != VOS_STATUS_SUCCESS) {
Agarwal Ashisha7ef41d2015-06-25 18:00:26 +053017798 hddLog(VOS_TRACE_LEVEL_ERROR,
17799 FL("Failed to send TDLS switch channel request"));
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053017800 }
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053017801 }
17802 else
17803 {
17804 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
17805 "%s: No TDLS Connected Peer or "
Pradeep Reddy POTTETIfdaf38b2015-05-13 13:01:22 +053017806 "isOffChannelSupported %d "
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053017807 "isOffChannelConfigured %d",
17808 __func__,
Pradeep Reddy POTTETIfdaf38b2015-05-13 13:01:22 +053017809 (connPeer ? (connPeer->isOffChannelSupported)
17810 : -1),
17811 (connPeer ? (connPeer->isOffChannelConfigured)
17812 : -1));
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053017813 }
17814 }
17815
Hoonki Lee5305c3a2013-04-29 23:28:59 -070017816 if (eTDLS_LINK_CONNECTED != pTdlsPeer->link_status)
Gopichand Nakkalac87400e2013-03-13 18:51:00 -070017817 {
Madan Mohan Koyyalamudice419872013-09-13 19:36:52 +053017818 if (IS_ADVANCE_TDLS_ENABLE) {
Gopichand Nakkala24be5312013-07-02 16:47:12 +053017819
Madan Mohan Koyyalamudice419872013-09-13 19:36:52 +053017820 if (0 != wlan_hdd_tdls_get_link_establish_params(
17821 pAdapter, peer,&tdlsLinkEstablishParams)) {
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053017822 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Failed to get link establishment params"));
Madan Mohan Koyyalamudice419872013-09-13 19:36:52 +053017823 return -EINVAL;
17824 }
17825 INIT_COMPLETION(pAdapter->tdls_link_establish_req_comp);
Gopichand Nakkala79ff85d2013-05-27 17:05:29 +053017826
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053017827 ret = sme_SendTdlsLinkEstablishParams(
17828 WLAN_HDD_GET_HAL_CTX(pAdapter),
17829 pAdapter->sessionId, peer,
17830 &tdlsLinkEstablishParams);
17831 if (ret != VOS_STATUS_SUCCESS) {
17832 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Failed to send link establishment params"));
17833 }
Madan Mohan Koyyalamudice419872013-09-13 19:36:52 +053017834 /* Send TDLS peer UAPSD capabilities to the firmware and
17835 * register with the TL on after the response for this operation
17836 * is received .
17837 */
17838 ret = wait_for_completion_interruptible_timeout(
17839 &pAdapter->tdls_link_establish_req_comp,
17840 msecs_to_jiffies(WAIT_TIME_TDLS_LINK_ESTABLISH_REQ));
17841 if (ret <= 0)
17842 {
17843 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Agarwal Ashisha7ef41d2015-06-25 18:00:26 +053017844 FL("Link Establish Request Failed Status %ld"),
17845 ret);
Madan Mohan Koyyalamudice419872013-09-13 19:36:52 +053017846 return -EINVAL;
17847 }
Gopichand Nakkala79ff85d2013-05-27 17:05:29 +053017848 }
Masti, Narayanraddi6b93b472015-09-04 17:48:11 +053017849
Atul Mittal115287b2014-07-08 13:26:33 +053017850 wlan_hdd_tdls_set_peer_link_status(pTdlsPeer,
17851 eTDLS_LINK_CONNECTED,
17852 eTDLS_LINK_SUCCESS);
Agarwal Ashish16020c42014-12-29 22:01:11 +053017853 staDesc.ucSTAId = pTdlsPeer->staId;
17854 staDesc.ucQosEnabled = tdlsLinkEstablishParams.qos;
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053017855 ret = WLANTL_UpdateTdlsSTAClient(
17856 pHddCtx->pvosContext,
17857 &staDesc);
17858 if (ret != VOS_STATUS_SUCCESS) {
17859 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Failed to update TDLS STA params"));
17860 }
Agarwal Ashish16020c42014-12-29 22:01:11 +053017861
Gopichand Nakkala471708b2013-06-04 20:03:01 +053017862 /* Mark TDLS client Authenticated .*/
17863 status = WLANTL_ChangeSTAState( pHddCtx->pvosContext,
17864 pTdlsPeer->staId,
17865 WLANTL_STA_AUTHENTICATED);
Gopichand Nakkalaccd3a382013-03-19 13:56:10 -070017866 if (VOS_STATUS_SUCCESS == status)
17867 {
Hoonki Lee14621352013-04-16 17:51:19 -070017868 if (pTdlsPeer->is_responder == 0)
17869 {
17870 v_U8_t staId = (v_U8_t)pTdlsPeer->staId;
Ganesh Kondabattinicbfdc392015-09-11 19:12:59 +053017871 tdlsConnInfo_t *tdlsInfo;
17872
17873 tdlsInfo = wlan_hdd_get_conn_info(pHddCtx, staId);
17874
17875 /* Initialize initiator wait callback */
17876 vos_timer_init(
17877 &pTdlsPeer->initiatorWaitTimeoutTimer,
17878 VOS_TIMER_TYPE_SW,
17879 wlan_hdd_tdls_initiator_wait_cb,
17880 tdlsInfo);
Hoonki Lee14621352013-04-16 17:51:19 -070017881
17882 wlan_hdd_tdls_timer_restart(pAdapter,
17883 &pTdlsPeer->initiatorWaitTimeoutTimer,
17884 WAIT_TIME_TDLS_INITIATOR);
17885 /* suspend initiator TX until it receives direct packet from the
17886 reponder or WAIT_TIME_TDLS_INITIATOR timer expires */
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053017887 ret = WLANTL_SuspendDataTx(
17888 (WLAN_HDD_GET_CTX(pAdapter))->pvosContext,
17889 &staId, NULL);
17890 if (ret != VOS_STATUS_SUCCESS) {
17891 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Failed to suspend data tx"));
17892 }
Hoonki Lee14621352013-04-16 17:51:19 -070017893 }
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053017894
Pradeep Reddy POTTETIfcac7902015-04-16 12:25:17 +053017895 if ((TRUE == pTdlsPeer->isOffChannelSupported) &&
Pradeep Reddy POTTETIfdaf38b2015-05-13 13:01:22 +053017896 (TRUE == pTdlsPeer->isOffChannelConfigured))
Pradeep Reddy POTTETIfcac7902015-04-16 12:25:17 +053017897 {
Pradeep Reddy POTTETIfdaf38b2015-05-13 13:01:22 +053017898 suppChannelLen =
17899 tdlsLinkEstablishParams.supportedChannelsLen;
17900
17901 if ((suppChannelLen > 0) &&
17902 (suppChannelLen <= SIR_MAC_MAX_SUPP_CHANNELS))
17903 {
17904 tANI_U8 suppPeerChannel = 0;
17905 int i = 0;
17906 for (i = 0U; i < suppChannelLen; i++)
17907 {
17908 suppPeerChannel =
17909 tdlsLinkEstablishParams.supportedChannels[i];
17910
17911 pTdlsPeer->isOffChannelSupported = FALSE;
17912 if (suppPeerChannel ==
17913 pTdlsPeer->peerParams.channel)
17914 {
17915 pTdlsPeer->isOffChannelSupported = TRUE;
17916 break;
17917 }
17918 }
17919 }
17920 else
17921 {
17922 pTdlsPeer->isOffChannelSupported = FALSE;
17923 }
Pradeep Reddy POTTETIfcac7902015-04-16 12:25:17 +053017924 }
17925 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
17926 "%s: TDLS channel switch request for channel "
17927 "%d isOffChannelConfigured %d suppChannelLen "
Pradeep Reddy POTTETIfdaf38b2015-05-13 13:01:22 +053017928 "%d isOffChannelSupported %d", __func__,
17929 pTdlsPeer->peerParams.channel,
Pradeep Reddy POTTETIfcac7902015-04-16 12:25:17 +053017930 pTdlsPeer->isOffChannelConfigured,
Pradeep Reddy POTTETIfdaf38b2015-05-13 13:01:22 +053017931 suppChannelLen,
17932 pTdlsPeer->isOffChannelSupported);
Pradeep Reddy POTTETIfcac7902015-04-16 12:25:17 +053017933
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053017934 /* TDLS Off Channel, Enable tdls channel switch,
17935 when their is only one tdls link and it supports */
17936 numCurrTdlsPeers = wlan_hdd_tdlsConnectedPeers(pAdapter);
17937 if ((numCurrTdlsPeers == 1) &&
17938 (TRUE == pTdlsPeer->isOffChannelSupported) &&
17939 (TRUE == pTdlsPeer->isOffChannelConfigured))
17940 {
17941 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
17942 "%s: Send TDLS channel switch request for channel %d",
17943 __func__, pTdlsPeer->peerParams.channel);
Pradeep Reddy POTTETI16d83332015-03-26 18:28:13 +053017944
17945 pTdlsPeer->isOffChannelEstablished = TRUE;
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053017946 ret = sme_SendTdlsChanSwitchReq(WLAN_HDD_GET_HAL_CTX(pAdapter),
17947 pAdapter->sessionId,
17948 pTdlsPeer->peerMac,
17949 pTdlsPeer->peerParams.channel,
17950 TDLS_OFF_CHANNEL_BW_OFFSET,
17951 TDLS_CHANNEL_SWITCH_ENABLE);
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053017952 if (ret != VOS_STATUS_SUCCESS) {
17953 hddLog(VOS_TRACE_LEVEL_ERROR, FL("TDLS offchannel: Failed to send TDLS switch channel req"));
17954 }
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053017955 }
17956 else
17957 {
17958 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
17959 "%s: TDLS channel switch request not sent"
17960 " numCurrTdlsPeers %d "
17961 "isOffChannelSupported %d "
17962 "isOffChannelConfigured %d",
17963 __func__, numCurrTdlsPeers,
17964 pTdlsPeer->isOffChannelSupported,
17965 pTdlsPeer->isOffChannelConfigured);
17966 }
17967
Gopichand Nakkalaccd3a382013-03-19 13:56:10 -070017968 }
Gopichand Nakkalac87400e2013-03-13 18:51:00 -070017969 wlan_hdd_tdls_check_bmps(pAdapter);
Gopichand Nakkala79ff85d2013-05-27 17:05:29 +053017970
17971 /* Update TL about the UAPSD masks , to route the packets to firmware */
Gopichand Nakkala574f6d12013-06-27 19:38:43 +053017972 if ((TRUE == pHddCtx->cfg_ini->fEnableTDLSBufferSta)
17973 || pHddCtx->cfg_ini->fTDLSUapsdMask )
Gopichand Nakkala79ff85d2013-05-27 17:05:29 +053017974 {
Gopichand Nakkala574f6d12013-06-27 19:38:43 +053017975 int ac;
17976 uint8 ucAc[4] = { WLANTL_AC_VO,
17977 WLANTL_AC_VI,
17978 WLANTL_AC_BK,
17979 WLANTL_AC_BE };
17980 uint8 tlTid[4] = { 7, 5, 2, 3 } ;
17981 for(ac=0; ac < 4; ac++)
17982 {
17983 status = WLANTL_EnableUAPSDForAC( (WLAN_HDD_GET_CTX(pAdapter))->pvosContext,
17984 pTdlsPeer->staId, ucAc[ac],
17985 tlTid[ac], tlTid[ac], 0, 0,
17986 WLANTL_BI_DIR );
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053017987 if (status != VOS_STATUS_SUCCESS) {
17988 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Failed to enable UAPSD for AC"));
17989 }
Gopichand Nakkala574f6d12013-06-27 19:38:43 +053017990 }
Gopichand Nakkala79ff85d2013-05-27 17:05:29 +053017991 }
Gopichand Nakkalac87400e2013-03-13 18:51:00 -070017992 }
Mohit Khanna698ba2a2012-12-04 15:08:18 -080017993 }
17994 break;
17995 case NL80211_TDLS_DISABLE_LINK:
Lee Hoonkic1262f22013-01-24 21:59:00 -080017996 {
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053017997 tANI_U16 numCurrTdlsPeers = 0;
17998 hddTdlsPeer_t *connPeer = NULL;
17999
Agarwal Ashisha7ef41d2015-06-25 18:00:26 +053018000 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
18001 " %s : NL80211_TDLS_DISABLE_LINK for " MAC_ADDRESS_STR,
18002 __func__, MAC_ADDR_ARRAY(peer));
18003
Masti, Narayanraddi8208f062015-10-15 13:16:17 +053018004 mutex_lock(&pHddCtx->tdls_lock);
18005 pTdlsPeer = wlan_hdd_tdls_find_peer(pAdapter, peer, FALSE);
Sunil Dutt41de4e22013-11-14 18:09:02 +053018006
Agarwal Ashisha7ef41d2015-06-25 18:00:26 +053018007
Sunil Dutt41de4e22013-11-14 18:09:02 +053018008 if ( NULL == pTdlsPeer ) {
Masti, Narayanraddi8208f062015-10-15 13:16:17 +053018009 mutex_unlock(&pHddCtx->tdls_lock);
Sunil Dutt41de4e22013-11-14 18:09:02 +053018010 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: " MAC_ADDRESS_STR
18011 " (oper %d) not exsting. ignored",
18012 __func__, MAC_ADDR_ARRAY(peer), (int)oper);
18013 return -EINVAL;
18014 }
18015
18016 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
18017 "%s: " MAC_ADDRESS_STR " link_status %d (%s) ", "tdls_oper",
18018 MAC_ADDR_ARRAY(peer), pTdlsPeer->link_status,
18019 "NL80211_TDLS_DISABLE_LINK");
18020
Hoonki Lee5305c3a2013-04-29 23:28:59 -070018021 if(TDLS_STA_INDEX_VALID(pTdlsPeer->staId))
Lee Hoonkic1262f22013-01-24 21:59:00 -080018022 {
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -070018023 long status;
18024
Pradeep Reddy POTTETIf3148e82015-04-16 12:10:33 +053018025 /* set tdls off channel status to false for this peer */
18026 pTdlsPeer->isOffChannelEstablished = FALSE;
Atul Mittal271a7652014-09-12 13:18:22 +053018027 wlan_hdd_tdls_set_peer_link_status(pTdlsPeer,
18028 eTDLS_LINK_TEARING,
18029 (pTdlsPeer->link_status == eTDLS_LINK_TEARING)?
18030 eTDLS_LINK_UNSPECIFIED:
18031 eTDLS_LINK_DROPPED_BY_REMOTE);
Masti, Narayanraddi8208f062015-10-15 13:16:17 +053018032 mutex_unlock(&pHddCtx->tdls_lock);
18033
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -070018034 INIT_COMPLETION(pAdapter->tdls_del_station_comp);
18035
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053018036 status = sme_DeleteTdlsPeerSta(
18037 WLAN_HDD_GET_HAL_CTX(pAdapter),
18038 pAdapter->sessionId, peer );
18039 if (status != VOS_STATUS_SUCCESS) {
18040 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Failed to delete TDLS peer STA"));
18041 }
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -070018042
18043 status = wait_for_completion_interruptible_timeout(&pAdapter->tdls_del_station_comp,
18044 msecs_to_jiffies(WAIT_TIME_TDLS_DEL_STA));
Masti, Narayanraddi8208f062015-10-15 13:16:17 +053018045
18046 mutex_lock(&pHddCtx->tdls_lock);
18047 pTdlsPeer = wlan_hdd_tdls_find_peer(pAdapter, peer, FALSE);
18048 if ( NULL == pTdlsPeer ) {
18049 mutex_unlock(&pHddCtx->tdls_lock);
18050 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: " MAC_ADDRESS_STR
18051 " peer was freed in other context",
18052 __func__, MAC_ADDR_ARRAY(peer));
18053 return -EINVAL;
18054 }
18055
Atul Mittal271a7652014-09-12 13:18:22 +053018056 wlan_hdd_tdls_set_peer_link_status(pTdlsPeer,
Atul Mittal454664b2014-10-10 11:03:46 +053018057 eTDLS_LINK_IDLE,
18058 eTDLS_LINK_UNSPECIFIED);
Masti, Narayanraddi8208f062015-10-15 13:16:17 +053018059 mutex_unlock(&pHddCtx->tdls_lock);
18060
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -070018061 if (status <= 0)
18062 {
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -070018063 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
18064 "%s: Del station failed status %ld",
18065 __func__, status);
18066 return -EPERM;
18067 }
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053018068
18069 /* TDLS Off Channel, Enable tdls channel switch,
18070 when their is only one tdls link and it supports */
18071 numCurrTdlsPeers = wlan_hdd_tdlsConnectedPeers(pAdapter);
18072 if (numCurrTdlsPeers == 1)
18073 {
Masti, Narayanraddi8208f062015-10-15 13:16:17 +053018074 tSirMacAddr peerMac;
18075 int channel;
Masti, Narayanraddi3818aea2015-10-17 15:20:28 +053018076
Masti, Narayanraddi8208f062015-10-15 13:16:17 +053018077 mutex_lock(&pHddCtx->tdls_lock);
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053018078 connPeer = wlan_hdd_tdls_get_connected_peer(pAdapter);
Masti, Narayanraddi3818aea2015-10-17 15:20:28 +053018079
18080 if (connPeer == NULL) {
18081 mutex_unlock(&pHddCtx->tdls_lock);
18082 hddLog(VOS_TRACE_LEVEL_ERROR,
18083 "%s connPeer is NULL", __func__);
18084 return -EINVAL;
18085 }
18086
Masti, Narayanraddi8208f062015-10-15 13:16:17 +053018087 vos_mem_copy(peerMac, connPeer->peerMac, sizeof(tSirMacAddr));
18088 channel = connPeer->peerParams.channel;
18089
18090 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
18091 "%s: TDLS channel switch "
18092 "isOffChannelSupported %d "
18093 "isOffChannelConfigured %d "
18094 "isOffChannelEstablished %d",
18095 __func__,
18096 (connPeer ? connPeer->isOffChannelSupported : -1),
18097 (connPeer ? connPeer->isOffChannelConfigured : -1),
18098 (connPeer ? connPeer->isOffChannelEstablished : -1));
18099
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053018100 if ((connPeer) &&
18101 (connPeer->isOffChannelSupported == TRUE) &&
18102 (connPeer->isOffChannelConfigured == TRUE))
18103 {
Pradeep Reddy POTTETI16d83332015-03-26 18:28:13 +053018104 connPeer->isOffChannelEstablished = TRUE;
Masti, Narayanraddi8208f062015-10-15 13:16:17 +053018105 mutex_unlock(&pHddCtx->tdls_lock);
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053018106 status = sme_SendTdlsChanSwitchReq(
18107 WLAN_HDD_GET_HAL_CTX(pAdapter),
18108 pAdapter->sessionId,
Masti, Narayanraddi8208f062015-10-15 13:16:17 +053018109 peerMac,
18110 channel,
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053018111 TDLS_OFF_CHANNEL_BW_OFFSET,
18112 TDLS_CHANNEL_SWITCH_ENABLE);
18113 if (status != VOS_STATUS_SUCCESS) {
18114 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Failed to send TDLS switch channel req"));
18115 }
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053018116 }
Masti, Narayanraddi8208f062015-10-15 13:16:17 +053018117 else
18118 mutex_unlock(&pHddCtx->tdls_lock);
18119 }
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053018120 else
18121 {
18122 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
18123 "%s: TDLS channel switch request not sent "
18124 "numCurrTdlsPeers %d ",
18125 __func__, numCurrTdlsPeers);
18126 }
Lee Hoonkic1262f22013-01-24 21:59:00 -080018127 }
18128 else
18129 {
Masti, Narayanraddi8208f062015-10-15 13:16:17 +053018130 mutex_unlock(&pHddCtx->tdls_lock);
Gopichand Nakkalac87400e2013-03-13 18:51:00 -070018131 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
18132 "%s: TDLS Peer Station doesn't exist.", __func__);
Lee Hoonkic1262f22013-01-24 21:59:00 -080018133 }
Lee Hoonkic1262f22013-01-24 21:59:00 -080018134 }
Gopichand Nakkalac87400e2013-03-13 18:51:00 -070018135 break;
Mohit Khanna698ba2a2012-12-04 15:08:18 -080018136 case NL80211_TDLS_TEARDOWN:
Sunil Dutt41de4e22013-11-14 18:09:02 +053018137 {
Atul Mittal115287b2014-07-08 13:26:33 +053018138 status = wlan_hdd_tdls_extctrl_deconfig_peer(pAdapter, peer);
Sunil Dutt41de4e22013-11-14 18:09:02 +053018139
Atul Mittal115287b2014-07-08 13:26:33 +053018140 if (0 != status)
18141 {
18142 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Agarwal Ashisha7ef41d2015-06-25 18:00:26 +053018143 FL("Error in TDLS Teardown"));
Atul Mittal115287b2014-07-08 13:26:33 +053018144 return status;
Sunil Dutt41de4e22013-11-14 18:09:02 +053018145 }
Sunil Dutt41de4e22013-11-14 18:09:02 +053018146 break;
18147 }
Mohit Khanna698ba2a2012-12-04 15:08:18 -080018148 case NL80211_TDLS_SETUP:
Sunil Dutt41de4e22013-11-14 18:09:02 +053018149 {
Atul Mittal115287b2014-07-08 13:26:33 +053018150 status = wlan_hdd_tdls_extctrl_config_peer(pAdapter,
18151 peer,
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053018152 NULL,
Atul Mittal115287b2014-07-08 13:26:33 +053018153 NULL);
Sunil Dutt41de4e22013-11-14 18:09:02 +053018154
Atul Mittal115287b2014-07-08 13:26:33 +053018155 if (0 != status)
18156 {
18157 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Agarwal Ashisha7ef41d2015-06-25 18:00:26 +053018158 FL("Error in TDLS Setup"));
Atul Mittal115287b2014-07-08 13:26:33 +053018159 return status;
Naresh Jayaram937abdf2013-11-26 19:50:25 +053018160 }
Naresh Jayaramdb4514b2013-11-25 18:08:10 +053018161 break;
Sunil Dutt41de4e22013-11-14 18:09:02 +053018162 }
Mohit Khanna698ba2a2012-12-04 15:08:18 -080018163 case NL80211_TDLS_DISCOVERY_REQ:
18164 /* We don't support in-driver setup/teardown/discovery */
c_hpothu6ff1c3c2013-10-01 19:01:57 +053018165 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_WARN,
Agarwal Ashisha7ef41d2015-06-25 18:00:26 +053018166 "%s: Driver doesn't support in-driver setup/teardown/discovery "
c_hpothu6ff1c3c2013-10-01 19:01:57 +053018167 ,__func__);
Mohit Khanna698ba2a2012-12-04 15:08:18 -080018168 return -ENOTSUPP;
18169 default:
c_hpothu6ff1c3c2013-10-01 19:01:57 +053018170 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
18171 "%s: unsupported event",__func__);
Mohit Khanna698ba2a2012-12-04 15:08:18 -080018172 return -ENOTSUPP;
18173 }
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053018174
18175 EXIT();
Mohit Khanna698ba2a2012-12-04 15:08:18 -080018176 return 0;
18177}
Chilam NG571c65a2013-01-19 12:27:36 +053018178
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053018179static int wlan_hdd_cfg80211_tdls_oper(struct wiphy *wiphy, struct net_device *dev,
Anand N Sunkad9bfc2622015-07-30 15:18:54 +053018180#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,18,0))
18181 const u8 *peer,
18182#else
18183 u8 *peer,
18184#endif
18185 enum nl80211_tdls_operation oper)
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053018186{
18187 int ret;
18188
18189 vos_ssr_protect(__func__);
18190 ret = __wlan_hdd_cfg80211_tdls_oper(wiphy, dev, peer, oper);
18191 vos_ssr_unprotect(__func__);
18192
18193 return ret;
18194}
18195
Chilam NG571c65a2013-01-19 12:27:36 +053018196int wlan_hdd_cfg80211_send_tdls_discover_req(struct wiphy *wiphy,
18197 struct net_device *dev, u8 *peer)
18198{
Arif Hussaina7c8e412013-11-20 11:06:42 -080018199 hddLog(VOS_TRACE_LEVEL_INFO,
18200 "tdls send discover req: "MAC_ADDRESS_STR,
18201 MAC_ADDR_ARRAY(peer));
Chilam NG571c65a2013-01-19 12:27:36 +053018202
Sunil Dutt Undekarieacac6f2014-03-21 14:08:53 +053018203#if TDLS_MGMT_VERSION2
18204 return wlan_hdd_cfg80211_tdls_mgmt(wiphy, dev, peer,
18205 WLAN_TDLS_DISCOVERY_REQUEST, 1, 0, 0, NULL, 0);
18206#else
Anand N Sunkad9bfc2622015-07-30 15:18:54 +053018207#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,17,0))
18208 return wlan_hdd_cfg80211_tdls_mgmt(wiphy, dev, peer,
18209 WLAN_TDLS_DISCOVERY_REQUEST, 1, 0, 0, 0, NULL, 0);
18210#elif (LINUX_VERSION_CODE >= KERNEL_VERSION(3,16,0))
18211 return wlan_hdd_cfg80211_tdls_mgmt(wiphy, dev, peer,
18212 WLAN_TDLS_DISCOVERY_REQUEST, 1, 0, 0, NULL, 0);
18213#elif (LINUX_VERSION_CODE >= KERNEL_VERSION(3,15,0))
18214 return wlan_hdd_cfg80211_tdls_mgmt(wiphy, dev, peer,
18215 WLAN_TDLS_DISCOVERY_REQUEST, 1, 0, 0, NULL, 0);
18216#else
Chilam NG571c65a2013-01-19 12:27:36 +053018217 return wlan_hdd_cfg80211_tdls_mgmt(wiphy, dev, peer,
18218 WLAN_TDLS_DISCOVERY_REQUEST, 1, 0, NULL, 0);
Sunil Dutt Undekarieacac6f2014-03-21 14:08:53 +053018219#endif
Anand N Sunkad9bfc2622015-07-30 15:18:54 +053018220#endif /* KERNEL_VERSION */
Chilam NG571c65a2013-01-19 12:27:36 +053018221}
Mohit Khanna698ba2a2012-12-04 15:08:18 -080018222#endif
18223
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053018224#ifdef WLAN_FEATURE_GTK_OFFLOAD
18225/*
18226 * FUNCTION: wlan_hdd_cfg80211_update_replayCounterCallback
18227 * Callback rountine called upon receiving response for
18228 * get offload info
18229 */
18230void wlan_hdd_cfg80211_update_replayCounterCallback(void *callbackContext,
18231 tpSirGtkOffloadGetInfoRspParams pGtkOffloadGetInfoRsp)
18232{
18233
18234 hdd_adapter_t *pAdapter = (hdd_adapter_t *)callbackContext;
Gopichand Nakkalad36ee622013-05-07 14:13:27 +053018235 tANI_U8 tempReplayCounter[8];
18236 hdd_station_ctx_t *pHddStaCtx;
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053018237
18238 ENTER();
18239
18240 if (NULL == pAdapter)
18241 {
Agarwal Ashish971c2882013-10-30 20:11:12 +053018242 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053018243 "%s: HDD adapter is Null", __func__);
18244 return ;
18245 }
18246
18247 if (NULL == pGtkOffloadGetInfoRsp)
18248 {
18249 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
18250 "%s: pGtkOffloadGetInfoRsp is Null", __func__);
18251 return ;
18252 }
18253
18254 if (VOS_STATUS_SUCCESS != pGtkOffloadGetInfoRsp->ulStatus)
18255 {
18256 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
18257 "%s: wlan Failed to get replay counter value",
18258 __func__);
18259 return ;
18260 }
18261
Gopichand Nakkalad36ee622013-05-07 14:13:27 +053018262 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
18263 /* Update replay counter */
18264 pHddStaCtx->gtkOffloadReqParams.ullKeyReplayCounter =
18265 pGtkOffloadGetInfoRsp->ullKeyReplayCounter;
18266
18267 {
18268 /* changing from little to big endian since supplicant
18269 * works on big endian format
18270 */
18271 int i;
18272 tANI_U8 *p = (tANI_U8 *)&pGtkOffloadGetInfoRsp->ullKeyReplayCounter;
18273
18274 for (i = 0; i < 8; i++)
18275 {
18276 tempReplayCounter[7-i] = (tANI_U8)p[i];
18277 }
18278 }
18279
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053018280 /* Update replay counter to NL */
18281 cfg80211_gtk_rekey_notify(pAdapter->dev, pGtkOffloadGetInfoRsp->bssId,
Gopichand Nakkalad36ee622013-05-07 14:13:27 +053018282 tempReplayCounter, GFP_KERNEL);
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053018283}
18284
18285/*
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053018286 * FUNCTION: __wlan_hdd_cfg80211_set_rekey_data
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053018287 * This function is used to offload GTK rekeying job to the firmware.
18288 */
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053018289int __wlan_hdd_cfg80211_set_rekey_data(struct wiphy *wiphy, struct net_device *dev,
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053018290 struct cfg80211_gtk_rekey_data *data)
18291{
18292 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
18293 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
18294 hdd_station_ctx_t *pHddStaCtx;
18295 tHalHandle hHal;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053018296 int result;
Gopichand Nakkalad36ee622013-05-07 14:13:27 +053018297 tSirGtkOffloadParams hddGtkOffloadReqParams;
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053018298 eHalStatus status = eHAL_STATUS_FAILURE;
18299
18300 ENTER();
18301
18302 if (NULL == pAdapter)
18303 {
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053018304 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053018305 "%s: HDD adapter is Null", __func__);
18306 return -ENODEV;
18307 }
18308
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053018309 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
18310 TRACE_CODE_HDD_CFG80211_SET_REKEY_DATA,
18311 pAdapter->sessionId, pAdapter->device_mode));
18312
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053018313 result = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053018314 if (0 != result)
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053018315 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053018316 return result;
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053018317 }
18318
18319 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
18320 hHal = WLAN_HDD_GET_HAL_CTX(pAdapter);
18321 if (NULL == hHal)
18322 {
18323 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
18324 "%s: HAL context is Null!!!", __func__);
18325 return -EAGAIN;
18326 }
18327
Gopichand Nakkalad36ee622013-05-07 14:13:27 +053018328 pHddStaCtx->gtkOffloadReqParams.ulFlags = GTK_OFFLOAD_ENABLE;
18329 memcpy(pHddStaCtx->gtkOffloadReqParams.aKCK, data->kck, NL80211_KCK_LEN);
18330 memcpy(pHddStaCtx->gtkOffloadReqParams.aKEK, data->kek, NL80211_KEK_LEN);
18331 memcpy(pHddStaCtx->gtkOffloadReqParams.bssId, &pHddStaCtx->conn_info.bssId,
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053018332 WNI_CFG_BSSID_LEN);
Gopichand Nakkalad36ee622013-05-07 14:13:27 +053018333 {
18334 /* changing from big to little endian since driver
18335 * works on little endian format
18336 */
18337 tANI_U8 *p =
18338 (tANI_U8 *)&pHddStaCtx->gtkOffloadReqParams.ullKeyReplayCounter;
18339 int i;
18340
18341 for (i = 0; i < 8; i++)
18342 {
18343 p[7-i] = data->replay_ctr[i];
18344 }
18345 }
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053018346
18347 if (TRUE == pHddCtx->hdd_wlan_suspended)
18348 {
18349 /* if wlan is suspended, enable GTK offload directly from here */
Gopichand Nakkalad36ee622013-05-07 14:13:27 +053018350 memcpy(&hddGtkOffloadReqParams, &pHddStaCtx->gtkOffloadReqParams,
18351 sizeof (tSirGtkOffloadParams));
18352 status = sme_SetGTKOffload(hHal, &hddGtkOffloadReqParams,
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053018353 pAdapter->sessionId);
18354
18355 if (eHAL_STATUS_SUCCESS != status)
18356 {
18357 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
18358 "%s: sme_SetGTKOffload failed, returned %d",
18359 __func__, status);
Vinay Krishna Eranna6f22c1f2014-10-13 16:03:06 +053018360
18361 /* Need to clear any trace of key value in the memory.
18362 * Thus zero out the memory even though it is local
18363 * variable.
18364 */
18365 vos_mem_zero(&hddGtkOffloadReqParams,
18366 sizeof(hddGtkOffloadReqParams));
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053018367 return status;
18368 }
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053018369 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
18370 "%s: sme_SetGTKOffload successfull", __func__);
18371 }
18372 else
18373 {
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053018374 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
18375 "%s: wlan not suspended GTKOffload request is stored",
18376 __func__);
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053018377 }
Gopichand Nakkalad36ee622013-05-07 14:13:27 +053018378
Vinay Krishna Eranna6f22c1f2014-10-13 16:03:06 +053018379 /* Need to clear any trace of key value in the memory.
18380 * Thus zero out the memory even though it is local
18381 * variable.
18382 */
18383 vos_mem_zero(&hddGtkOffloadReqParams,
18384 sizeof(hddGtkOffloadReqParams));
18385
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053018386 EXIT();
Gopichand Nakkalad36ee622013-05-07 14:13:27 +053018387 return eHAL_STATUS_SUCCESS;
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053018388}
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053018389
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053018390int wlan_hdd_cfg80211_set_rekey_data(struct wiphy *wiphy, struct net_device *dev,
18391 struct cfg80211_gtk_rekey_data *data)
18392{
18393 int ret;
18394
18395 vos_ssr_protect(__func__);
18396 ret = __wlan_hdd_cfg80211_set_rekey_data(wiphy, dev, data);
18397 vos_ssr_unprotect(__func__);
18398
18399 return ret;
18400}
18401#endif /*WLAN_FEATURE_GTK_OFFLOAD*/
Gopichand Nakkalac005b7c2013-05-14 16:04:14 +053018402/*
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053018403 * FUNCTION: __wlan_hdd_cfg80211_set_mac_acl
Gopichand Nakkalac005b7c2013-05-14 16:04:14 +053018404 * This function is used to set access control policy
18405 */
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053018406static int __wlan_hdd_cfg80211_set_mac_acl(struct wiphy *wiphy,
18407 struct net_device *dev,
18408 const struct cfg80211_acl_data *params)
Gopichand Nakkalac005b7c2013-05-14 16:04:14 +053018409{
18410 int i;
18411 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
18412 hdd_hostapd_state_t *pHostapdState;
18413 tsap_Config_t *pConfig;
18414 v_CONTEXT_t pVosContext = NULL;
18415 hdd_context_t *pHddCtx;
18416 int status;
18417
18418 ENTER();
18419
18420 if (NULL == pAdapter)
18421 {
18422 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
18423 "%s: HDD adapter is Null", __func__);
18424 return -ENODEV;
18425 }
18426
18427 if (NULL == params)
18428 {
18429 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
18430 "%s: params is Null", __func__);
18431 return -EINVAL;
18432 }
18433
18434 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
18435 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalac005b7c2013-05-14 16:04:14 +053018436 if (0 != status)
18437 {
Gopichand Nakkalac005b7c2013-05-14 16:04:14 +053018438 return status;
18439 }
18440
18441 pVosContext = pHddCtx->pvosContext;
18442 pHostapdState = WLAN_HDD_GET_HOSTAP_STATE_PTR(pAdapter);
18443
18444 if (NULL == pHostapdState)
18445 {
18446 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
18447 "%s: pHostapdState is Null", __func__);
18448 return -EINVAL;
18449 }
18450
18451 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,"acl policy: = %d"
18452 "no acl entries = %d", params->acl_policy, params->n_acl_entries);
Konamki, Sreelakshmi7b464be2015-07-14 12:17:01 +053018453 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
18454 TRACE_CODE_HDD_CFG80211_SET_MAC_ACL,
18455 pAdapter->sessionId, pAdapter->device_mode));
Gopichand Nakkalac005b7c2013-05-14 16:04:14 +053018456
18457 if (WLAN_HDD_SOFTAP == pAdapter->device_mode)
18458 {
18459 pConfig = &pAdapter->sessionCtx.ap.sapConfig;
18460
18461 /* default value */
18462 pConfig->num_accept_mac = 0;
18463 pConfig->num_deny_mac = 0;
18464
18465 /**
18466 * access control policy
18467 * @NL80211_ACL_POLICY_ACCEPT_UNLESS_LISTED: Deny stations which are
18468 * listed in hostapd.deny file.
18469 * @NL80211_ACL_POLICY_DENY_UNLESS_LISTED: Allow stations which are
18470 * listed in hostapd.accept file.
18471 */
18472 if (NL80211_ACL_POLICY_DENY_UNLESS_LISTED == params->acl_policy)
18473 {
18474 pConfig->SapMacaddr_acl = eSAP_DENY_UNLESS_ACCEPTED;
18475 }
18476 else if (NL80211_ACL_POLICY_ACCEPT_UNLESS_LISTED == params->acl_policy)
18477 {
18478 pConfig->SapMacaddr_acl = eSAP_ACCEPT_UNLESS_DENIED;
18479 }
18480 else
18481 {
18482 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
18483 "%s:Acl Policy : %d is not supported",
18484 __func__, params->acl_policy);
18485 return -ENOTSUPP;
18486 }
18487
18488 if (eSAP_DENY_UNLESS_ACCEPTED == pConfig->SapMacaddr_acl)
18489 {
18490 pConfig->num_accept_mac = params->n_acl_entries;
18491 for (i = 0; i < params->n_acl_entries; i++)
18492 {
18493 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
18494 "** Add ACL MAC entry %i in WhiletList :"
18495 MAC_ADDRESS_STR, i,
18496 MAC_ADDR_ARRAY(params->mac_addrs[i].addr));
18497
18498 vos_mem_copy(&pConfig->accept_mac[i], params->mac_addrs[i].addr,
18499 sizeof(qcmacaddr));
18500 }
18501 }
18502 else if (eSAP_ACCEPT_UNLESS_DENIED == pConfig->SapMacaddr_acl)
18503 {
18504 pConfig->num_deny_mac = params->n_acl_entries;
18505 for (i = 0; i < params->n_acl_entries; i++)
18506 {
18507 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
18508 "** Add ACL MAC entry %i in BlackList :"
18509 MAC_ADDRESS_STR, i,
18510 MAC_ADDR_ARRAY(params->mac_addrs[i].addr));
18511
18512 vos_mem_copy(&pConfig->deny_mac[i], params->mac_addrs[i].addr,
18513 sizeof(qcmacaddr));
18514 }
18515 }
18516
18517 if (VOS_STATUS_SUCCESS != WLANSAP_SetMacACL(pVosContext, pConfig))
18518 {
18519 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
18520 "%s: SAP Set Mac Acl fail", __func__);
18521 return -EINVAL;
18522 }
18523 }
18524 else
18525 {
18526 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Sushant Kaushik8bc7df22014-04-09 17:55:29 +053018527 "%s: Invalid device_mode = %s (%d)",
18528 __func__, hdd_device_modetoString(pAdapter->device_mode),
18529 pAdapter->device_mode);
Gopichand Nakkalac005b7c2013-05-14 16:04:14 +053018530 return -EINVAL;
18531 }
18532
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053018533 EXIT();
Gopichand Nakkalac005b7c2013-05-14 16:04:14 +053018534 return 0;
18535}
18536
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053018537static int wlan_hdd_cfg80211_set_mac_acl(struct wiphy *wiphy,
18538 struct net_device *dev,
18539 const struct cfg80211_acl_data *params)
18540{
18541 int ret;
18542 vos_ssr_protect(__func__);
18543 ret = __wlan_hdd_cfg80211_set_mac_acl(wiphy, dev, params);
18544 vos_ssr_unprotect(__func__);
18545
18546 return ret;
18547}
18548
Leo Chang9056f462013-08-01 19:21:11 -070018549#ifdef WLAN_NL80211_TESTMODE
18550#ifdef FEATURE_WLAN_LPHB
Leo Changd9df8aa2013-09-26 13:32:26 -070018551void wlan_hdd_cfg80211_lphb_ind_handler
Leo Chang9056f462013-08-01 19:21:11 -070018552(
18553 void *pAdapter,
18554 void *indCont
18555)
18556{
Leo Changd9df8aa2013-09-26 13:32:26 -070018557 tSirLPHBInd *lphbInd;
18558 struct sk_buff *skb;
c_hpothu73f35e62014-04-18 13:40:08 +053018559 hdd_context_t *pHddCtxt;
Leo Chang9056f462013-08-01 19:21:11 -070018560
18561 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Leo Changd9df8aa2013-09-26 13:32:26 -070018562 "LPHB indication arrived");
Leo Chang9056f462013-08-01 19:21:11 -070018563
c_hpothu73f35e62014-04-18 13:40:08 +053018564 if (pAdapter == NULL)
18565 {
18566 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
18567 "%s: pAdapter is NULL\n",__func__);
18568 return;
18569 }
18570
Leo Chang9056f462013-08-01 19:21:11 -070018571 if (NULL == indCont)
18572 {
18573 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Leo Changd9df8aa2013-09-26 13:32:26 -070018574 "LPHB IND, invalid argument");
Leo Chang9056f462013-08-01 19:21:11 -070018575 return;
18576 }
18577
c_hpothu73f35e62014-04-18 13:40:08 +053018578 pHddCtxt = (hdd_context_t *)pAdapter;
Leo Changd9df8aa2013-09-26 13:32:26 -070018579 lphbInd = (tSirLPHBInd *)indCont;
Leo Chang9056f462013-08-01 19:21:11 -070018580 skb = cfg80211_testmode_alloc_event_skb(
c_hpothu73f35e62014-04-18 13:40:08 +053018581 pHddCtxt->wiphy,
Leo Changd9df8aa2013-09-26 13:32:26 -070018582 sizeof(tSirLPHBInd),
Leo Chang9056f462013-08-01 19:21:11 -070018583 GFP_ATOMIC);
18584 if (!skb)
18585 {
18586 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
18587 "LPHB timeout, NL buffer alloc fail");
18588 return;
18589 }
18590
Leo Changac3ba772013-10-07 09:47:04 -070018591 if(nla_put_u32(skb, WLAN_HDD_TM_ATTR_CMD, WLAN_HDD_TM_CMD_WLAN_HB))
Leo Changd9df8aa2013-09-26 13:32:26 -070018592 {
18593 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
18594 "WLAN_HDD_TM_ATTR_CMD put fail");
18595 goto nla_put_failure;
18596 }
Leo Changac3ba772013-10-07 09:47:04 -070018597 if(nla_put_u32(skb, WLAN_HDD_TM_ATTR_TYPE, lphbInd->protocolType))
Leo Changd9df8aa2013-09-26 13:32:26 -070018598 {
18599 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
18600 "WLAN_HDD_TM_ATTR_TYPE put fail");
18601 goto nla_put_failure;
18602 }
Leo Changac3ba772013-10-07 09:47:04 -070018603 if(nla_put(skb, WLAN_HDD_TM_ATTR_DATA,
Leo Changd9df8aa2013-09-26 13:32:26 -070018604 sizeof(tSirLPHBInd), lphbInd))
18605 {
18606 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
18607 "WLAN_HDD_TM_ATTR_DATA put fail");
18608 goto nla_put_failure;
18609 }
Leo Chang9056f462013-08-01 19:21:11 -070018610 cfg80211_testmode_event(skb, GFP_ATOMIC);
18611 return;
18612
18613nla_put_failure:
18614 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
18615 "NLA Put fail");
18616 kfree_skb(skb);
18617
18618 return;
18619}
18620#endif /* FEATURE_WLAN_LPHB */
18621
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053018622static int __wlan_hdd_cfg80211_testmode(struct wiphy *wiphy, void *data, int len)
Leo Chang9056f462013-08-01 19:21:11 -070018623{
18624 struct nlattr *tb[WLAN_HDD_TM_ATTR_MAX + 1];
18625 int err = 0;
18626#ifdef FEATURE_WLAN_LPHB
18627 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
Leo Changd9df8aa2013-09-26 13:32:26 -070018628 eHalStatus smeStatus;
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053018629
18630 ENTER();
18631
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +053018632 err = wlan_hdd_validate_context(pHddCtx);
18633 if (0 != err)
18634 {
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +053018635 return err;
18636 }
Leo Chang9056f462013-08-01 19:21:11 -070018637#endif /* FEATURE_WLAN_LPHB */
18638
18639 err = nla_parse(tb, WLAN_HDD_TM_ATTR_MAX, data, len, wlan_hdd_tm_policy);
18640 if (err)
18641 {
18642 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
18643 "%s Testmode INV ATTR", __func__);
18644 return err;
18645 }
18646
18647 if (!tb[WLAN_HDD_TM_ATTR_CMD])
18648 {
18649 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
18650 "%s Testmode INV CMD", __func__);
18651 return -EINVAL;
18652 }
18653
Konamki, Sreelakshmi7b464be2015-07-14 12:17:01 +053018654 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
18655 TRACE_CODE_HDD_CFG80211_TESTMODE,
18656 NO_SESSION, nla_get_u32(tb[WLAN_HDD_TM_ATTR_CMD])));
Leo Chang9056f462013-08-01 19:21:11 -070018657 switch (nla_get_u32(tb[WLAN_HDD_TM_ATTR_CMD]))
18658 {
18659#ifdef FEATURE_WLAN_LPHB
18660 /* Low Power Heartbeat configuration request */
18661 case WLAN_HDD_TM_CMD_WLAN_HB:
18662 {
18663 int buf_len;
18664 void *buf;
18665 tSirLPHBReq *hb_params = NULL;
Amar Singhal05852702014-02-04 14:40:00 -080018666 tSirLPHBReq *hb_params_temp = NULL;
Leo Chang9056f462013-08-01 19:21:11 -070018667
18668 if (!tb[WLAN_HDD_TM_ATTR_DATA])
18669 {
18670 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
18671 "%s Testmode INV DATA", __func__);
18672 return -EINVAL;
18673 }
18674
18675 buf = nla_data(tb[WLAN_HDD_TM_ATTR_DATA]);
18676 buf_len = nla_len(tb[WLAN_HDD_TM_ATTR_DATA]);
Amar Singhal05852702014-02-04 14:40:00 -080018677
18678 hb_params_temp =(tSirLPHBReq *)buf;
18679 if ((hb_params_temp->cmd == LPHB_SET_TCP_PARAMS_INDID) &&
18680 (hb_params_temp->params.lphbTcpParamReq.timePeriodSec == 0))
18681 return -EINVAL;
18682
Leo Chang9056f462013-08-01 19:21:11 -070018683 hb_params = (tSirLPHBReq *)vos_mem_malloc(sizeof(tSirLPHBReq));
18684 if (NULL == hb_params)
18685 {
18686 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
18687 "%s Request Buffer Alloc Fail", __func__);
18688 return -EINVAL;
18689 }
18690
18691 vos_mem_copy(hb_params, buf, buf_len);
Leo Changd9df8aa2013-09-26 13:32:26 -070018692 smeStatus = sme_LPHBConfigReq((tHalHandle)(pHddCtx->hHal),
18693 hb_params,
18694 wlan_hdd_cfg80211_lphb_ind_handler);
18695 if (eHAL_STATUS_SUCCESS != smeStatus)
Leo Chang9056f462013-08-01 19:21:11 -070018696 {
Leo Changd9df8aa2013-09-26 13:32:26 -070018697 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
18698 "LPHB Config Fail, disable");
Leo Chang9056f462013-08-01 19:21:11 -070018699 vos_mem_free(hb_params);
18700 }
Leo Chang9056f462013-08-01 19:21:11 -070018701 return 0;
18702 }
18703#endif /* FEATURE_WLAN_LPHB */
18704 default:
c_hpothu6ff1c3c2013-10-01 19:01:57 +053018705 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
18706 "%s: unsupported event",__func__);
Leo Chang9056f462013-08-01 19:21:11 -070018707 return -EOPNOTSUPP;
18708 }
18709
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053018710 EXIT();
18711 return err;
Leo Chang9056f462013-08-01 19:21:11 -070018712}
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053018713
Anand N Sunkade9adb1b2015-07-29 09:56:45 +053018714static int wlan_hdd_cfg80211_testmode(struct wiphy *wiphy,
18715#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,12,0))
18716 struct wireless_dev *wdev,
18717#endif
18718 void *data, int len)
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053018719{
18720 int ret;
18721
18722 vos_ssr_protect(__func__);
18723 ret = __wlan_hdd_cfg80211_testmode(wiphy, data, len);
18724 vos_ssr_unprotect(__func__);
18725
18726 return ret;
18727}
Leo Chang9056f462013-08-01 19:21:11 -070018728#endif /* CONFIG_NL80211_TESTMODE */
18729
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053018730static int __wlan_hdd_cfg80211_dump_survey(struct wiphy *wiphy,
Madan Mohan Koyyalamudid9383fd2013-08-13 09:27:30 +053018731 struct net_device *dev,
18732 int idx, struct survey_info *survey)
18733{
18734 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
18735 hdd_context_t *pHddCtx;
Mihir Sheted9072e02013-08-21 17:02:29 +053018736 hdd_station_ctx_t *pHddStaCtx;
Madan Mohan Koyyalamudid9383fd2013-08-13 09:27:30 +053018737 tHalHandle halHandle;
Mihir Sheted9072e02013-08-21 17:02:29 +053018738 v_U32_t channel = 0, freq = 0; /* Initialization Required */
Madan Mohan Koyyalamudid9383fd2013-08-13 09:27:30 +053018739 v_S7_t snr,rssi;
18740 int status, i, j, filled = 0;
18741
18742 ENTER();
18743
Madan Mohan Koyyalamudid9383fd2013-08-13 09:27:30 +053018744 if (NULL == pAdapter)
18745 {
18746 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
18747 "%s: HDD adapter is Null", __func__);
18748 return -ENODEV;
18749 }
18750
18751 if (NULL == wiphy)
18752 {
18753 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
18754 "%s: wiphy is Null", __func__);
18755 return -ENODEV;
18756 }
18757
18758 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
18759 status = wlan_hdd_validate_context(pHddCtx);
Madan Mohan Koyyalamudid9383fd2013-08-13 09:27:30 +053018760 if (0 != status)
18761 {
Madan Mohan Koyyalamudid9383fd2013-08-13 09:27:30 +053018762 return status;
18763 }
18764
Mihir Sheted9072e02013-08-21 17:02:29 +053018765 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
18766
Madan Mohan Koyyalamudid9383fd2013-08-13 09:27:30 +053018767 if (0 == pHddCtx->cfg_ini->fEnableSNRMonitoring ||
Mihir Sheted9072e02013-08-21 17:02:29 +053018768 0 != pAdapter->survey_idx ||
18769 eConnectionState_Associated != pHddStaCtx->conn_info.connState)
Madan Mohan Koyyalamudid9383fd2013-08-13 09:27:30 +053018770 {
18771 /* The survey dump ops when implemented completely is expected to
18772 * return a survey of all channels and the ops is called by the
18773 * kernel with incremental values of the argument 'idx' till it
18774 * returns -ENONET. But we can only support the survey for the
18775 * operating channel for now. survey_idx is used to track
18776 * that the ops is called only once and then return -ENONET for
18777 * the next iteration
18778 */
18779 pAdapter->survey_idx = 0;
18780 return -ENONET;
18781 }
18782
Mukul Sharma9d5233b2015-06-11 20:28:20 +053018783 if (VOS_TRUE == pHddStaCtx->hdd_ReassocScenario)
18784 {
18785 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
18786 "%s: Roaming in progress, hence return ", __func__);
18787 return -ENONET;
18788 }
18789
Madan Mohan Koyyalamudid9383fd2013-08-13 09:27:30 +053018790 halHandle = WLAN_HDD_GET_HAL_CTX(pAdapter);
18791
18792 wlan_hdd_get_snr(pAdapter, &snr);
18793 wlan_hdd_get_rssi(pAdapter, &rssi);
18794
Konamki, Sreelakshmi7b464be2015-07-14 12:17:01 +053018795 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
18796 TRACE_CODE_HDD_CFG80211_DUMP_SURVEY,
18797 pAdapter->sessionId, pAdapter->device_mode));
Madan Mohan Koyyalamudid9383fd2013-08-13 09:27:30 +053018798 sme_GetOperationChannel(halHandle, &channel, pAdapter->sessionId);
18799 hdd_wlan_get_freq(channel, &freq);
18800
18801
18802 for (i = 0; i < IEEE80211_NUM_BANDS; i++)
18803 {
18804 if (NULL == wiphy->bands[i])
18805 {
18806 VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_INFO,
18807 "%s: wiphy->bands[i] is NULL, i = %d", __func__, i);
18808 continue;
18809 }
18810
18811 for (j = 0; j < wiphy->bands[i]->n_channels; j++)
18812 {
18813 struct ieee80211_supported_band *band = wiphy->bands[i];
18814
18815 if (band->channels[j].center_freq == (v_U16_t)freq)
18816 {
18817 survey->channel = &band->channels[j];
18818 /* The Rx BDs contain SNR values in dB for the received frames
18819 * while the supplicant expects noise. So we calculate and
18820 * return the value of noise (dBm)
18821 * SNR (dB) = RSSI (dBm) - NOISE (dBm)
18822 */
18823 survey->noise = rssi - snr;
18824 survey->filled = SURVEY_INFO_NOISE_DBM;
18825 filled = 1;
18826 }
18827 }
18828 }
18829
18830 if (filled)
18831 pAdapter->survey_idx = 1;
18832 else
18833 {
18834 pAdapter->survey_idx = 0;
18835 return -ENONET;
18836 }
18837
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053018838 EXIT();
Madan Mohan Koyyalamudid9383fd2013-08-13 09:27:30 +053018839 return 0;
18840}
18841
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053018842static int wlan_hdd_cfg80211_dump_survey(struct wiphy *wiphy,
18843 struct net_device *dev,
18844 int idx, struct survey_info *survey)
18845{
18846 int ret;
18847
18848 vos_ssr_protect(__func__);
18849 ret = __wlan_hdd_cfg80211_dump_survey(wiphy, dev, idx, survey);
18850 vos_ssr_unprotect(__func__);
18851
18852 return ret;
18853}
18854
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053018855/*
Mahesh A Saptasagarbcc5b662014-06-02 21:46:23 +053018856 * FUNCTION: __wlan_hdd_cfg80211_resume_wlan
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053018857 * this is called when cfg80211 driver resume
18858 * driver updates latest sched_scan scan result(if any) to cfg80211 database
18859 */
Mahesh A Saptasagarbcc5b662014-06-02 21:46:23 +053018860int __wlan_hdd_cfg80211_resume_wlan(struct wiphy *wiphy)
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053018861{
18862 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
18863 hdd_adapter_t *pAdapter;
18864 hdd_adapter_list_node_t *pAdapterNode, *pNext;
18865 VOS_STATUS status = VOS_STATUS_SUCCESS;
18866
18867 ENTER();
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053018868
Mahesh A Saptasagar74088392015-02-05 17:22:09 +053018869 if (0 != wlan_hdd_validate_context(pHddCtx))
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053018870 {
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053018871 return 0;
18872 }
18873
Konamki, Sreelakshmi7b464be2015-07-14 12:17:01 +053018874 MTRACE(vos_trace(VOS_MODULE_ID_HDD, TRACE_CODE_HDD_CFG80211_RESUME_WLAN,
18875 NO_SESSION, pHddCtx->isWiphySuspended));
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053018876 spin_lock(&pHddCtx->schedScan_lock);
18877 pHddCtx->isWiphySuspended = FALSE;
18878 if (TRUE != pHddCtx->isSchedScanUpdatePending)
18879 {
18880 spin_unlock(&pHddCtx->schedScan_lock);
18881 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
18882 "%s: Return resume is not due to PNO indication", __func__);
18883 return 0;
18884 }
18885 // Reset flag to avoid updatating cfg80211 data old results again
18886 pHddCtx->isSchedScanUpdatePending = FALSE;
18887 spin_unlock(&pHddCtx->schedScan_lock);
18888
18889 status = hdd_get_front_adapter ( pHddCtx, &pAdapterNode );
18890
18891 while ( NULL != pAdapterNode && VOS_STATUS_SUCCESS == status )
18892 {
18893 pAdapter = pAdapterNode->pAdapter;
18894 if ( (NULL != pAdapter) &&
18895 (WLAN_HDD_INFRA_STATION == pAdapter->device_mode) )
18896 {
18897 if (0 != wlan_hdd_cfg80211_update_bss(pHddCtx->wiphy, pAdapter))
Mahesh A Saptasagarb9c50402014-01-16 15:49:22 +053018898 {
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053018899 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_WARN,
18900 "%s: NO SCAN result", __func__);
Mahesh A Saptasagarb9c50402014-01-16 15:49:22 +053018901 }
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053018902 else
Mahesh A Saptasagarb9c50402014-01-16 15:49:22 +053018903 {
18904 /* Acquire wakelock to handle the case where APP's tries to
18905 * suspend immediately after updating the scan results. Whis
18906 * results in app's is in suspended state and not able to
18907 * process the connect request to AP
18908 */
Sushant Kaushik83392fa2015-05-05 17:44:40 +053018909 hdd_prevent_suspend_timeout(2000,
18910 WIFI_POWER_EVENT_WAKELOCK_RESUME_WLAN);
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053018911 cfg80211_sched_scan_results(pHddCtx->wiphy);
Mahesh A Saptasagarb9c50402014-01-16 15:49:22 +053018912 }
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053018913
18914 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
18915 "%s : cfg80211 scan result database updated", __func__);
18916
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053018917 EXIT();
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053018918 return 0;
18919
18920 }
18921 status = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
18922 pAdapterNode = pNext;
18923 }
18924
18925 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
18926 "%s: Failed to find Adapter", __func__);
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053018927 EXIT();
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053018928 return 0;
18929}
18930
Mahesh A Saptasagarbcc5b662014-06-02 21:46:23 +053018931int wlan_hdd_cfg80211_resume_wlan(struct wiphy *wiphy)
18932{
18933 int ret;
18934
18935 vos_ssr_protect(__func__);
18936 ret = __wlan_hdd_cfg80211_resume_wlan(wiphy);
18937 vos_ssr_unprotect(__func__);
18938
18939 return ret;
18940}
18941
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053018942/*
Mahesh A Saptasagarbcc5b662014-06-02 21:46:23 +053018943 * FUNCTION: __wlan_hdd_cfg80211_suspend_wlan
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053018944 * this is called when cfg80211 driver suspends
18945 */
Mahesh A Saptasagarbcc5b662014-06-02 21:46:23 +053018946int __wlan_hdd_cfg80211_suspend_wlan(struct wiphy *wiphy,
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053018947 struct cfg80211_wowlan *wow)
18948{
18949 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +053018950 int ret = 0;
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053018951
18952 ENTER();
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053018953
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +053018954 ret = wlan_hdd_validate_context(pHddCtx);
18955 if (0 != ret)
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053018956 {
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +053018957 return ret;
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053018958 }
18959
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +053018960
Konamki, Sreelakshmi7b464be2015-07-14 12:17:01 +053018961 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
18962 TRACE_CODE_HDD_CFG80211_SUSPEND_WLAN,
18963 NO_SESSION, pHddCtx->isWiphySuspended));
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053018964 pHddCtx->isWiphySuspended = TRUE;
18965
18966 EXIT();
18967
18968 return 0;
18969}
18970
Mahesh A Saptasagarbcc5b662014-06-02 21:46:23 +053018971int wlan_hdd_cfg80211_suspend_wlan(struct wiphy *wiphy,
18972 struct cfg80211_wowlan *wow)
18973{
18974 int ret;
18975
18976 vos_ssr_protect(__func__);
18977 ret = __wlan_hdd_cfg80211_suspend_wlan(wiphy, wow);
18978 vos_ssr_unprotect(__func__);
18979
18980 return ret;
18981}
Jeff Johnson295189b2012-06-20 16:38:30 -070018982/* cfg80211_ops */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053018983static struct cfg80211_ops wlan_hdd_cfg80211_ops =
Jeff Johnson295189b2012-06-20 16:38:30 -070018984{
18985 .add_virtual_intf = wlan_hdd_add_virtual_intf,
18986 .del_virtual_intf = wlan_hdd_del_virtual_intf,
18987 .change_virtual_intf = wlan_hdd_cfg80211_change_iface,
18988 .change_station = wlan_hdd_change_station,
18989#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,4,0))
18990 .add_beacon = wlan_hdd_cfg80211_add_beacon,
18991 .del_beacon = wlan_hdd_cfg80211_del_beacon,
18992 .set_beacon = wlan_hdd_cfg80211_set_beacon,
Jeff Johnson04dd8a82012-06-29 20:41:40 -070018993#else
18994 .start_ap = wlan_hdd_cfg80211_start_ap,
18995 .change_beacon = wlan_hdd_cfg80211_change_beacon,
18996 .stop_ap = wlan_hdd_cfg80211_stop_ap,
Jeff Johnson295189b2012-06-20 16:38:30 -070018997#endif
18998 .change_bss = wlan_hdd_cfg80211_change_bss,
18999 .add_key = wlan_hdd_cfg80211_add_key,
19000 .get_key = wlan_hdd_cfg80211_get_key,
19001 .del_key = wlan_hdd_cfg80211_del_key,
19002 .set_default_key = wlan_hdd_cfg80211_set_default_key,
Jeff Johnson3bbe4bf2013-01-18 17:05:29 -080019003#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,6,0))
Jeff Johnson295189b2012-06-20 16:38:30 -070019004 .set_channel = wlan_hdd_cfg80211_set_channel,
Jeff Johnson3bbe4bf2013-01-18 17:05:29 -080019005#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070019006 .scan = wlan_hdd_cfg80211_scan,
19007 .connect = wlan_hdd_cfg80211_connect,
19008 .disconnect = wlan_hdd_cfg80211_disconnect,
19009 .join_ibss = wlan_hdd_cfg80211_join_ibss,
19010 .leave_ibss = wlan_hdd_cfg80211_leave_ibss,
19011 .set_wiphy_params = wlan_hdd_cfg80211_set_wiphy_params,
19012 .set_tx_power = wlan_hdd_cfg80211_set_txpower,
19013 .get_tx_power = wlan_hdd_cfg80211_get_txpower,
Jeff Johnson295189b2012-06-20 16:38:30 -070019014 .remain_on_channel = wlan_hdd_cfg80211_remain_on_channel,
19015 .cancel_remain_on_channel = wlan_hdd_cfg80211_cancel_remain_on_channel,
DARAM SUDHA39eede62014-02-12 11:16:40 +053019016 .mgmt_tx = wlan_hdd_mgmt_tx,
Jeff Johnson295189b2012-06-20 16:38:30 -070019017#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
19018 .mgmt_tx_cancel_wait = wlan_hdd_cfg80211_mgmt_tx_cancel_wait,
19019 .set_default_mgmt_key = wlan_hdd_set_default_mgmt_key,
19020 .set_txq_params = wlan_hdd_set_txq_params,
19021#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070019022 .get_station = wlan_hdd_cfg80211_get_station,
19023 .set_power_mgmt = wlan_hdd_cfg80211_set_power_mgmt,
19024 .del_station = wlan_hdd_cfg80211_del_station,
Jeff Johnson04dd8a82012-06-29 20:41:40 -070019025 .add_station = wlan_hdd_cfg80211_add_station,
19026#ifdef FEATURE_WLAN_LFR
19027 .set_pmksa = wlan_hdd_cfg80211_set_pmksa,
19028 .del_pmksa = wlan_hdd_cfg80211_del_pmksa,
19029 .flush_pmksa = wlan_hdd_cfg80211_flush_pmksa,
19030#endif
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070019031#if defined(WLAN_FEATURE_VOWIFI_11R) && defined(KERNEL_SUPPORT_11R_CFG80211)
19032 .update_ft_ies = wlan_hdd_cfg80211_update_ft_ies,
19033#endif
Mohit Khanna698ba2a2012-12-04 15:08:18 -080019034#ifdef FEATURE_WLAN_TDLS
19035 .tdls_mgmt = wlan_hdd_cfg80211_tdls_mgmt,
19036 .tdls_oper = wlan_hdd_cfg80211_tdls_oper,
19037#endif
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053019038#ifdef WLAN_FEATURE_GTK_OFFLOAD
19039 .set_rekey_data = wlan_hdd_cfg80211_set_rekey_data,
19040#endif /* WLAN_FEATURE_GTK_OFFLOAD */
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053019041#ifdef FEATURE_WLAN_SCAN_PNO
19042 .sched_scan_start = wlan_hdd_cfg80211_sched_scan_start,
19043 .sched_scan_stop = wlan_hdd_cfg80211_sched_scan_stop,
19044#endif /*FEATURE_WLAN_SCAN_PNO */
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053019045 .resume = wlan_hdd_cfg80211_resume_wlan,
19046 .suspend = wlan_hdd_cfg80211_suspend_wlan,
Gopichand Nakkalac005b7c2013-05-14 16:04:14 +053019047 .set_mac_acl = wlan_hdd_cfg80211_set_mac_acl,
Leo Chang9056f462013-08-01 19:21:11 -070019048#ifdef WLAN_NL80211_TESTMODE
19049 .testmode_cmd = wlan_hdd_cfg80211_testmode,
19050#endif
Madan Mohan Koyyalamudid9383fd2013-08-13 09:27:30 +053019051 .dump_survey = wlan_hdd_cfg80211_dump_survey,
Jeff Johnson295189b2012-06-20 16:38:30 -070019052};
19053