blob: bad6ebee779ca5b671c6347dcfe3654568ee2564 [file] [log] [blame]
Jeff Johnson295189b2012-06-20 16:38:30 -07001/*
Kiet Lam842dad02014-02-18 18:44:02 -08002 * Copyright (c) 2012-2014 The Linux Foundation. All rights reserved.
3 *
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.
Kiet Lamaa8e15a2014-02-11 23:30:06 -080026 */
Kiet Lam842dad02014-02-18 18:44:02 -080027
28
Kiet Lama7f454d2014-07-24 12:04:06 -070029
30
Jeff Johnson295189b2012-06-20 16:38:30 -070031/**========================================================================
32
33 \file wlan_hdd_cfg80211.c
34
35 \brief WLAN Host Device Driver implementation
36
Jeff Johnson295189b2012-06-20 16:38:30 -070037 ========================================================================*/
38
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -070039/**=========================================================================
Jeff Johnson295189b2012-06-20 16:38:30 -070040
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -070041 EDIT HISTORY FOR FILE
Jeff Johnson295189b2012-06-20 16:38:30 -070042
43
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -070044 This section contains comments describing changes made to the module.
45 Notice that changes are listed in reverse chronological order.
Jeff Johnson295189b2012-06-20 16:38:30 -070046
47
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -070048 $Header:$ $DateTime: $ $Author: $
Jeff Johnson295189b2012-06-20 16:38:30 -070049
50
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -070051 when who what, where, why
Jeff Johnson295189b2012-06-20 16:38:30 -070052 -------- --- --------------------------------------------------------
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -070053 21/12/09 Ashwani Created module.
Jeff Johnson295189b2012-06-20 16:38:30 -070054
55 07/06/10 Kumar Deepak Implemented cfg80211 callbacks for ANDROID
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -070056 Ganesh K
Jeff Johnson295189b2012-06-20 16:38:30 -070057 ==========================================================================*/
58
Jeff Johnson295189b2012-06-20 16:38:30 -070059
60#include <linux/version.h>
61#include <linux/module.h>
62#include <linux/kernel.h>
63#include <linux/init.h>
64#include <linux/wireless.h>
65#include <wlan_hdd_includes.h>
66#include <net/arp.h>
67#include <net/cfg80211.h>
68#include <linux/wireless.h>
69#include <wlan_hdd_wowl.h>
70#include <aniGlobal.h>
71#include "ccmApi.h"
72#include "sirParams.h"
73#include "dot11f.h"
74#include "wlan_hdd_assoc.h"
75#include "wlan_hdd_wext.h"
76#include "sme_Api.h"
77#include "wlan_hdd_p2p.h"
78#include "wlan_hdd_cfg80211.h"
79#include "wlan_hdd_hostapd.h"
80#include "sapInternal.h"
81#include "wlan_hdd_softap_tx_rx.h"
82#include "wlan_hdd_main.h"
Madan Mohan Koyyalamudid5acbf52012-11-28 01:45:08 +053083#include "wlan_hdd_assoc.h"
Gopichand Nakkala20c4c042013-04-19 22:08:55 +053084#include "wlan_hdd_power.h"
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053085#include "wlan_hdd_trace.h"
86#include "vos_types.h"
87#include "vos_trace.h"
Jeff Johnson295189b2012-06-20 16:38:30 -070088#ifdef WLAN_BTAMP_FEATURE
89#include "bap_hdd_misc.h"
90#endif
91#include <qc_sap_ioctl.h>
Mohit Khanna698ba2a2012-12-04 15:08:18 -080092#ifdef FEATURE_WLAN_TDLS
93#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"
Mohit Khanna698ba2a2012-12-04 15:08:18 -080096#endif
Madan Mohan Koyylamudi64267f72013-02-05 14:07:08 +053097#include "wlan_nv.h"
Leo Chang6fe1f922013-06-07 19:21:24 -070098#include "wlan_hdd_dev_pwr.h"
Jeff Johnson295189b2012-06-20 16:38:30 -070099
100#define g_mode_rates_size (12)
101#define a_mode_rates_size (8)
102#define FREQ_BASE_80211G (2407)
103#define FREQ_BAND_DIFF_80211G (5)
Jeff Johnson04dd8a82012-06-29 20:41:40 -0700104#define MAX_SCAN_SSID 9
Kiet Lamac06e2c2013-10-23 16:25:07 +0530105#define MAX_PENDING_LOG 5
Jeff Johnson295189b2012-06-20 16:38:30 -0700106#define GET_IE_LEN_IN_BSS_DESC(lenInBss) ( lenInBss + sizeof(lenInBss) - \
krunal soni2a6a9062014-02-11 14:14:23 -0800107 ((uintptr_t)OFFSET_OF( tSirBssDescription, ieFields)))
Jeff Johnson295189b2012-06-20 16:38:30 -0700108
109#define HDD2GHZCHAN(freq, chan, flag) { \
110 .band = IEEE80211_BAND_2GHZ, \
111 .center_freq = (freq), \
112 .hw_value = (chan),\
113 .flags = (flag), \
114 .max_antenna_gain = 0 ,\
115 .max_power = 30, \
116}
117
118#define HDD5GHZCHAN(freq, chan, flag) { \
119 .band = IEEE80211_BAND_5GHZ, \
120 .center_freq = (freq), \
121 .hw_value = (chan),\
122 .flags = (flag), \
123 .max_antenna_gain = 0 ,\
124 .max_power = 30, \
125}
126
127#define HDD_G_MODE_RATETAB(rate, rate_id, flag)\
128{\
129 .bitrate = rate, \
130 .hw_value = rate_id, \
131 .flags = flag, \
132}
133
Lee Hoonkic1262f22013-01-24 21:59:00 -0800134#ifndef WLAN_FEATURE_TDLS_DEBUG
135#define TDLS_LOG_LEVEL VOS_TRACE_LEVEL_INFO
136#else
137#define TDLS_LOG_LEVEL VOS_TRACE_LEVEL_ERROR
138#endif
139
Gopichand Nakkala356fb102013-03-06 12:34:04 +0530140#ifdef WLAN_FEATURE_VOWIFI_11R
141#define WLAN_AKM_SUITE_FT_8021X 0x000FAC03
142#define WLAN_AKM_SUITE_FT_PSK 0x000FAC04
143#endif
144
Naresh Jayaram3180aa42014-02-12 21:47:26 +0530145#define HDD_CHANNEL_14 14
146
Sunil Duttc69bccb2014-05-26 21:30:20 +0530147#ifdef WLAN_FEATURE_LINK_LAYER_STATS
148/*
149 * Used to allocate the size of 4096 for the link layer stats.
150 * The size of 4096 is considered assuming that all data per
151 * respective event fit with in the limit.Please take a call
152 * on the limit based on the data requirements on link layer
153 * statistics.
154 */
155#define LL_STATS_EVENT_BUF_SIZE 4096
156#endif
Dino Mycle6fb96c12014-06-10 11:52:40 +0530157#ifdef WLAN_FEATURE_EXTSCAN
158/*
159 * Used to allocate the size of 4096 for the EXTScan NL data.
160 * The size of 4096 is considered assuming that all data per
161 * respective event fit with in the limit.Please take a call
162 * on the limit based on the data requirements.
163 */
164
165#define EXTSCAN_EVENT_BUF_SIZE 4096
166#define EXTSCAN_MAX_CACHED_RESULTS_PER_IND 32
167#endif
Sunil Duttc69bccb2014-05-26 21:30:20 +0530168
Atul Mittal115287b2014-07-08 13:26:33 +0530169/*EXT TDLS*/
170/*
171 * Used to allocate the size of 4096 for the TDLS.
172 * The size of 4096 is considered assuming that all data per
173 * respective event fit with in the limit.Please take a call
174 * on the limit based on the data requirements on link layer
175 * statistics.
176 */
177#define EXTTDLS_EVENT_BUF_SIZE 4096
178
Gopichand Nakkala747461f2013-04-24 19:24:45 +0530179static const u32 hdd_cipher_suites[] =
Jeff Johnson295189b2012-06-20 16:38:30 -0700180{
181 WLAN_CIPHER_SUITE_WEP40,
182 WLAN_CIPHER_SUITE_WEP104,
183 WLAN_CIPHER_SUITE_TKIP,
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -0800184#ifdef FEATURE_WLAN_ESE
Jeff Johnson295189b2012-06-20 16:38:30 -0700185#define WLAN_CIPHER_SUITE_KRK 0x004096ff /* use for KRK */
186 WLAN_CIPHER_SUITE_KRK,
187 WLAN_CIPHER_SUITE_CCMP,
188#else
189 WLAN_CIPHER_SUITE_CCMP,
190#endif
191#ifdef FEATURE_WLAN_WAPI
192 WLAN_CIPHER_SUITE_SMS4,
193#endif
Chet Lanctot186b5732013-03-18 10:26:30 -0700194#ifdef WLAN_FEATURE_11W
195 WLAN_CIPHER_SUITE_AES_CMAC,
196#endif
Jeff Johnson295189b2012-06-20 16:38:30 -0700197};
198
199static inline int is_broadcast_ether_addr(const u8 *addr)
200{
201 return ((addr[0] == 0xff) && (addr[1] == 0xff) && (addr[2] == 0xff) &&
202 (addr[3] == 0xff) && (addr[4] == 0xff) && (addr[5] == 0xff));
203}
204
205static struct ieee80211_channel hdd_channels_2_4_GHZ[] =
Gopichand Nakkala747461f2013-04-24 19:24:45 +0530206{
Jeff Johnson295189b2012-06-20 16:38:30 -0700207 HDD2GHZCHAN(2412, 1, 0) ,
208 HDD2GHZCHAN(2417, 2, 0) ,
209 HDD2GHZCHAN(2422, 3, 0) ,
210 HDD2GHZCHAN(2427, 4, 0) ,
211 HDD2GHZCHAN(2432, 5, 0) ,
212 HDD2GHZCHAN(2437, 6, 0) ,
213 HDD2GHZCHAN(2442, 7, 0) ,
214 HDD2GHZCHAN(2447, 8, 0) ,
215 HDD2GHZCHAN(2452, 9, 0) ,
216 HDD2GHZCHAN(2457, 10, 0) ,
217 HDD2GHZCHAN(2462, 11, 0) ,
218 HDD2GHZCHAN(2467, 12, 0) ,
219 HDD2GHZCHAN(2472, 13, 0) ,
220 HDD2GHZCHAN(2484, 14, 0) ,
221};
222
Jeff Johnson295189b2012-06-20 16:38:30 -0700223static struct ieee80211_channel hdd_social_channels_2_4_GHZ[] =
224{
225 HDD2GHZCHAN(2412, 1, 0) ,
226 HDD2GHZCHAN(2437, 6, 0) ,
227 HDD2GHZCHAN(2462, 11, 0) ,
228};
Jeff Johnson295189b2012-06-20 16:38:30 -0700229
230static struct ieee80211_channel hdd_channels_5_GHZ[] =
231{
Madan Mohan Koyyalamudic3a240c2012-09-28 15:34:08 -0700232 HDD5GHZCHAN(4920, 240, 0) ,
233 HDD5GHZCHAN(4940, 244, 0) ,
234 HDD5GHZCHAN(4960, 248, 0) ,
235 HDD5GHZCHAN(4980, 252, 0) ,
236 HDD5GHZCHAN(5040, 208, 0) ,
237 HDD5GHZCHAN(5060, 212, 0) ,
238 HDD5GHZCHAN(5080, 216, 0) ,
Jeff Johnson295189b2012-06-20 16:38:30 -0700239 HDD5GHZCHAN(5180, 36, 0) ,
240 HDD5GHZCHAN(5200, 40, 0) ,
241 HDD5GHZCHAN(5220, 44, 0) ,
242 HDD5GHZCHAN(5240, 48, 0) ,
243 HDD5GHZCHAN(5260, 52, 0) ,
244 HDD5GHZCHAN(5280, 56, 0) ,
245 HDD5GHZCHAN(5300, 60, 0) ,
246 HDD5GHZCHAN(5320, 64, 0) ,
247 HDD5GHZCHAN(5500,100, 0) ,
248 HDD5GHZCHAN(5520,104, 0) ,
249 HDD5GHZCHAN(5540,108, 0) ,
250 HDD5GHZCHAN(5560,112, 0) ,
251 HDD5GHZCHAN(5580,116, 0) ,
252 HDD5GHZCHAN(5600,120, 0) ,
253 HDD5GHZCHAN(5620,124, 0) ,
254 HDD5GHZCHAN(5640,128, 0) ,
255 HDD5GHZCHAN(5660,132, 0) ,
256 HDD5GHZCHAN(5680,136, 0) ,
257 HDD5GHZCHAN(5700,140, 0) ,
Leo Chang80de3c22013-11-26 10:52:12 -0800258#ifdef FEATURE_WLAN_CH144
259 HDD5GHZCHAN(5720,144, 0) ,
260#endif /* FEATURE_WLAN_CH144 */
Jeff Johnson295189b2012-06-20 16:38:30 -0700261 HDD5GHZCHAN(5745,149, 0) ,
262 HDD5GHZCHAN(5765,153, 0) ,
263 HDD5GHZCHAN(5785,157, 0) ,
264 HDD5GHZCHAN(5805,161, 0) ,
265 HDD5GHZCHAN(5825,165, 0) ,
266};
267
268static struct ieee80211_rate g_mode_rates[] =
269{
Gopichand Nakkala747461f2013-04-24 19:24:45 +0530270 HDD_G_MODE_RATETAB(10, 0x1, 0),
271 HDD_G_MODE_RATETAB(20, 0x2, 0),
272 HDD_G_MODE_RATETAB(55, 0x4, 0),
273 HDD_G_MODE_RATETAB(110, 0x8, 0),
274 HDD_G_MODE_RATETAB(60, 0x10, 0),
275 HDD_G_MODE_RATETAB(90, 0x20, 0),
276 HDD_G_MODE_RATETAB(120, 0x40, 0),
277 HDD_G_MODE_RATETAB(180, 0x80, 0),
278 HDD_G_MODE_RATETAB(240, 0x100, 0),
279 HDD_G_MODE_RATETAB(360, 0x200, 0),
280 HDD_G_MODE_RATETAB(480, 0x400, 0),
Jeff Johnson295189b2012-06-20 16:38:30 -0700281 HDD_G_MODE_RATETAB(540, 0x800, 0),
Gopichand Nakkala747461f2013-04-24 19:24:45 +0530282};
Jeff Johnson295189b2012-06-20 16:38:30 -0700283
284static struct ieee80211_rate a_mode_rates[] =
285{
Gopichand Nakkala747461f2013-04-24 19:24:45 +0530286 HDD_G_MODE_RATETAB(60, 0x10, 0),
287 HDD_G_MODE_RATETAB(90, 0x20, 0),
288 HDD_G_MODE_RATETAB(120, 0x40, 0),
289 HDD_G_MODE_RATETAB(180, 0x80, 0),
290 HDD_G_MODE_RATETAB(240, 0x100, 0),
291 HDD_G_MODE_RATETAB(360, 0x200, 0),
292 HDD_G_MODE_RATETAB(480, 0x400, 0),
Jeff Johnson295189b2012-06-20 16:38:30 -0700293 HDD_G_MODE_RATETAB(540, 0x800, 0),
294};
295
296static struct ieee80211_supported_band wlan_hdd_band_2_4_GHZ =
297{
298 .channels = hdd_channels_2_4_GHZ,
299 .n_channels = ARRAY_SIZE(hdd_channels_2_4_GHZ),
300 .band = IEEE80211_BAND_2GHZ,
301 .bitrates = g_mode_rates,
302 .n_bitrates = g_mode_rates_size,
303 .ht_cap.ht_supported = 1,
304 .ht_cap.cap = IEEE80211_HT_CAP_SGI_20
305 | IEEE80211_HT_CAP_GRN_FLD
306 | IEEE80211_HT_CAP_DSSSCCK40
307 | IEEE80211_HT_CAP_LSIG_TXOP_PROT,
308 .ht_cap.ampdu_factor = IEEE80211_HT_MAX_AMPDU_64K,
309 .ht_cap.ampdu_density = IEEE80211_HT_MPDU_DENSITY_16,
310 .ht_cap.mcs.rx_mask = { 0xff, 0, 0, 0, 0, 0, 0, 0, 0, 0, },
311 .ht_cap.mcs.rx_highest = cpu_to_le16( 72 ),
312 .ht_cap.mcs.tx_params = IEEE80211_HT_MCS_TX_DEFINED,
313};
314
Jeff Johnson295189b2012-06-20 16:38:30 -0700315static struct ieee80211_supported_band wlan_hdd_band_p2p_2_4_GHZ =
316{
317 .channels = hdd_social_channels_2_4_GHZ,
318 .n_channels = ARRAY_SIZE(hdd_social_channels_2_4_GHZ),
319 .band = IEEE80211_BAND_2GHZ,
320 .bitrates = g_mode_rates,
321 .n_bitrates = g_mode_rates_size,
322 .ht_cap.ht_supported = 1,
323 .ht_cap.cap = IEEE80211_HT_CAP_SGI_20
324 | IEEE80211_HT_CAP_GRN_FLD
325 | IEEE80211_HT_CAP_DSSSCCK40
326 | IEEE80211_HT_CAP_LSIG_TXOP_PROT,
327 .ht_cap.ampdu_factor = IEEE80211_HT_MAX_AMPDU_64K,
328 .ht_cap.ampdu_density = IEEE80211_HT_MPDU_DENSITY_16,
329 .ht_cap.mcs.rx_mask = { 0xff, 0, 0, 0, 0, 0, 0, 0, 0, 0, },
330 .ht_cap.mcs.rx_highest = cpu_to_le16( 72 ),
331 .ht_cap.mcs.tx_params = IEEE80211_HT_MCS_TX_DEFINED,
332};
Jeff Johnson295189b2012-06-20 16:38:30 -0700333
334static struct ieee80211_supported_band wlan_hdd_band_5_GHZ =
335{
336 .channels = hdd_channels_5_GHZ,
337 .n_channels = ARRAY_SIZE(hdd_channels_5_GHZ),
338 .band = IEEE80211_BAND_5GHZ,
339 .bitrates = a_mode_rates,
340 .n_bitrates = a_mode_rates_size,
341 .ht_cap.ht_supported = 1,
342 .ht_cap.cap = IEEE80211_HT_CAP_SGI_20
343 | IEEE80211_HT_CAP_GRN_FLD
344 | IEEE80211_HT_CAP_DSSSCCK40
345 | IEEE80211_HT_CAP_LSIG_TXOP_PROT
346 | IEEE80211_HT_CAP_SGI_40
347 | IEEE80211_HT_CAP_SUP_WIDTH_20_40,
348 .ht_cap.ampdu_factor = IEEE80211_HT_MAX_AMPDU_64K,
349 .ht_cap.ampdu_density = IEEE80211_HT_MPDU_DENSITY_16,
350 .ht_cap.mcs.rx_mask = { 0xff, 0, 0, 0, 0, 0, 0, 0, 0, 0, },
351 .ht_cap.mcs.rx_highest = cpu_to_le16( 72 ),
352 .ht_cap.mcs.tx_params = IEEE80211_HT_MCS_TX_DEFINED,
353};
354
Gopichand Nakkala747461f2013-04-24 19:24:45 +0530355/* This structure contain information what kind of frame are expected in
Jeff Johnson295189b2012-06-20 16:38:30 -0700356 TX/RX direction for each kind of interface */
357static const struct ieee80211_txrx_stypes
358wlan_hdd_txrx_stypes[NUM_NL80211_IFTYPES] = {
359 [NL80211_IFTYPE_STATION] = {
360 .tx = 0xffff,
361 .rx = BIT(SIR_MAC_MGMT_ACTION) |
362 BIT(SIR_MAC_MGMT_PROBE_REQ),
363 },
364 [NL80211_IFTYPE_AP] = {
365 .tx = 0xffff,
366 .rx = BIT(SIR_MAC_MGMT_ASSOC_REQ) |
367 BIT(SIR_MAC_MGMT_REASSOC_REQ) |
368 BIT(SIR_MAC_MGMT_PROBE_REQ) |
369 BIT(SIR_MAC_MGMT_DISASSOC) |
370 BIT(SIR_MAC_MGMT_AUTH) |
371 BIT(SIR_MAC_MGMT_DEAUTH) |
372 BIT(SIR_MAC_MGMT_ACTION),
373 },
Jeff Johnsonbc006202013-04-29 14:05:30 -0700374 [NL80211_IFTYPE_ADHOC] = {
375 .tx = 0xffff,
376 .rx = BIT(SIR_MAC_MGMT_ASSOC_REQ) |
377 BIT(SIR_MAC_MGMT_REASSOC_REQ) |
378 BIT(SIR_MAC_MGMT_PROBE_REQ) |
379 BIT(SIR_MAC_MGMT_DISASSOC) |
380 BIT(SIR_MAC_MGMT_AUTH) |
381 BIT(SIR_MAC_MGMT_DEAUTH) |
382 BIT(SIR_MAC_MGMT_ACTION),
383 },
Jeff Johnson295189b2012-06-20 16:38:30 -0700384 [NL80211_IFTYPE_P2P_CLIENT] = {
385 .tx = 0xffff,
386 .rx = BIT(SIR_MAC_MGMT_ACTION) |
387 BIT(SIR_MAC_MGMT_PROBE_REQ),
388 },
389 [NL80211_IFTYPE_P2P_GO] = {
390 /* This is also same as for SoftAP */
391 .tx = 0xffff,
392 .rx = BIT(SIR_MAC_MGMT_ASSOC_REQ) |
393 BIT(SIR_MAC_MGMT_REASSOC_REQ) |
394 BIT(SIR_MAC_MGMT_PROBE_REQ) |
395 BIT(SIR_MAC_MGMT_DISASSOC) |
396 BIT(SIR_MAC_MGMT_AUTH) |
397 BIT(SIR_MAC_MGMT_DEAUTH) |
398 BIT(SIR_MAC_MGMT_ACTION),
399 },
Jeff Johnson295189b2012-06-20 16:38:30 -0700400};
401
Sudhir Sattayappa Kohalli278eee52013-01-16 17:35:13 -0800402#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,4,0))
Sudhir Sattayappa Kohalli278eee52013-01-16 17:35:13 -0800403static const struct ieee80211_iface_limit
404wlan_hdd_iface_limit[] = {
405 {
Sunil Ravia72c3992013-01-31 06:12:22 -0800406 /* max = 3 ; Our driver create two interfaces during driver init
407 * wlan0 and p2p0 interfaces. p2p0 is considered as station
408 * interface until a group is formed. In JB architecture, once the
409 * group is formed, interface type of p2p0 is changed to P2P GO or
410 * Client.
411 * When supplicant remove the group, it first issue a set interface
412 * cmd to change the mode back to Station. In JB this works fine as
413 * we advertize two station type interface during driver init.
414 * Some vendors create separate interface for P2P GO/Client,
415 * after group formation(Third one). But while group remove
416 * supplicant first tries to change the mode(3rd interface) to STATION
417 * But as we advertized only two sta type interfaces nl80211 was
418 * returning error for the third one which was leading to failure in
419 * delete interface. Ideally while removing the group, supplicant
420 * should not try to change the 3rd interface mode to Station type.
421 * Till we get a fix in wpa_supplicant, we advertize max STA
422 * interface type to 3
423 */
424 .max = 3,
Sudhir Sattayappa Kohalli278eee52013-01-16 17:35:13 -0800425 .types = BIT(NL80211_IFTYPE_STATION),
426 },
427 {
428 .max = 1,
Jeff Johnsonbc006202013-04-29 14:05:30 -0700429 .types = BIT(NL80211_IFTYPE_ADHOC) | BIT(NL80211_IFTYPE_AP),
Sudhir Sattayappa Kohalli278eee52013-01-16 17:35:13 -0800430 },
431 {
432 .max = 1,
433 .types = BIT(NL80211_IFTYPE_P2P_GO) |
434 BIT(NL80211_IFTYPE_P2P_CLIENT),
435 },
436};
437
438/* By default, only single channel concurrency is allowed */
439static struct ieee80211_iface_combination
440wlan_hdd_iface_combination = {
441 .limits = wlan_hdd_iface_limit,
442 .num_different_channels = 1,
Sunil Ravia72c3992013-01-31 06:12:22 -0800443 /*
444 * max = WLAN_MAX_INTERFACES ; JellyBean architecture creates wlan0
445 * and p2p0 interfaces during driver init
446 * Some vendors create separate interface for P2P operations.
447 * wlan0: STA interface
448 * p2p0: P2P Device interface, action frames goes
449 * through this interface.
450 * p2p-xx: P2P interface, After GO negotiation this interface is
451 * created for p2p operations(GO/CLIENT interface).
452 */
453 .max_interfaces = WLAN_MAX_INTERFACES,
Sudhir Sattayappa Kohalli278eee52013-01-16 17:35:13 -0800454 .n_limits = ARRAY_SIZE(wlan_hdd_iface_limit),
455 .beacon_int_infra_match = false,
456};
457#endif
Sudhir Sattayappa Kohalli278eee52013-01-16 17:35:13 -0800458
Jeff Johnson295189b2012-06-20 16:38:30 -0700459static struct cfg80211_ops wlan_hdd_cfg80211_ops;
460
461/* Data rate 100KBPS based on IE Index */
462struct index_data_rate_type
463{
464 v_U8_t beacon_rate_index;
465 v_U16_t supported_rate[4];
466};
467
468/* 11B, 11G Rate table include Basic rate and Extended rate
469 The IDX field is the rate index
470 The HI field is the rate when RSSI is strong or being ignored
471 (in this case we report actual rate)
472 The MID field is the rate when RSSI is moderate
473 (in this case we cap 11b rates at 5.5 and 11g rates at 24)
474 The LO field is the rate when RSSI is low
475 (in this case we don't report rates, actual current rate used)
476 */
477static const struct
478{
479 v_U8_t beacon_rate_index;
Madan Mohan Koyyalamudi8df78d52012-11-02 12:30:06 -0700480 v_U16_t supported_rate[4];
Jeff Johnson295189b2012-06-20 16:38:30 -0700481} supported_data_rate[] =
482{
Madan Mohan Koyyalamudi8df78d52012-11-02 12:30:06 -0700483/* IDX HI HM LM LO (RSSI-based index */
484 {2, { 10, 10, 10, 0}},
485 {4, { 20, 20, 10, 0}},
486 {11, { 55, 20, 10, 0}},
487 {12, { 60, 55, 20, 0}},
488 {18, { 90, 55, 20, 0}},
489 {22, {110, 55, 20, 0}},
490 {24, {120, 90, 60, 0}},
491 {36, {180, 120, 60, 0}},
492 {44, {220, 180, 60, 0}},
493 {48, {240, 180, 90, 0}},
494 {66, {330, 180, 90, 0}},
495 {72, {360, 240, 90, 0}},
496 {96, {480, 240, 120, 0}},
497 {108, {540, 240, 120, 0}}
Jeff Johnson295189b2012-06-20 16:38:30 -0700498};
499
500/* MCS Based rate table */
501static struct index_data_rate_type supported_mcs_rate[] =
502{
503/* MCS L20 L40 S20 S40 */
504 {0, {65, 135, 72, 150}},
505 {1, {130, 270, 144, 300}},
506 {2, {195, 405, 217, 450}},
507 {3, {260, 540, 289, 600}},
508 {4, {390, 810, 433, 900}},
509 {5, {520, 1080, 578, 1200}},
510 {6, {585, 1215, 650, 1350}},
511 {7, {650, 1350, 722, 1500}}
512};
513
Leo Chang6f8870f2013-03-26 18:11:36 -0700514#ifdef WLAN_FEATURE_11AC
515
Gopichand Nakkala4c705372013-04-24 13:20:33 +0530516#define DATA_RATE_11AC_MCS_MASK 0x03
Leo Chang6f8870f2013-03-26 18:11:36 -0700517
518struct index_vht_data_rate_type
519{
520 v_U8_t beacon_rate_index;
Gopichand Nakkala4c705372013-04-24 13:20:33 +0530521 v_U16_t supported_VHT80_rate[2];
522 v_U16_t supported_VHT40_rate[2];
523 v_U16_t supported_VHT20_rate[2];
Leo Chang6f8870f2013-03-26 18:11:36 -0700524};
525
526typedef enum
527{
528 DATA_RATE_11AC_MAX_MCS_7,
529 DATA_RATE_11AC_MAX_MCS_8,
530 DATA_RATE_11AC_MAX_MCS_9,
531 DATA_RATE_11AC_MAX_MCS_NA
532} eDataRate11ACMaxMcs;
533
Mahesh A Saptasagar7bd6ad42014-07-21 18:56:33 +0530534/* SSID broadcast type */
535typedef enum eSSIDBcastType
536{
537 eBCAST_UNKNOWN = 0,
538 eBCAST_NORMAL = 1,
539 eBCAST_HIDDEN = 2,
540} tSSIDBcastType;
541
Leo Chang6f8870f2013-03-26 18:11:36 -0700542/* MCS Based VHT rate table */
543static struct index_vht_data_rate_type supported_vht_mcs_rate[] =
544{
Gopichand Nakkala4c705372013-04-24 13:20:33 +0530545/* MCS L80 S80 L40 S40 L20 S40*/
546 {0, {293, 325}, {135, 150}, {65, 72}},
547 {1, {585, 650}, {270, 300}, {130, 144}},
548 {2, {878, 975}, {405, 450}, {195, 217}},
549 {3, {1170, 1300}, {540, 600}, {260, 289}},
550 {4, {1755, 1950}, {810, 900}, {390, 433}},
551 {5, {2340, 2600}, {1080, 1200}, {520, 578}},
552 {6, {2633, 2925}, {1215, 1350}, {585, 650}},
553 {7, {2925, 3250}, {1350, 1500}, {650, 722}},
554 {8, {3510, 3900}, {1620, 1800}, {780, 867}},
555 {9, {3900, 4333}, {1800, 2000}, {780, 867}}
Leo Chang6f8870f2013-03-26 18:11:36 -0700556};
557#endif /* WLAN_FEATURE_11AC */
558
c_hpothu79aab322014-07-14 21:11:01 +0530559/*array index points to MCS and array value points respective rssi*/
560static int rssiMcsTbl[][10] =
561{
562/*MCS 0 1 2 3 4 5 6 7 8 9*/
563 {-82, -79, -77, -74, -70, -66, -65, -64, -59, -57}, //20
564 {-79, -76, -74, -71, -67, -63, -62, -61, -56, -54}, //40
565 {-76, -73, -71, -68, -64, -60, -59, -58, -53, -51} //80
566};
567
Jeff Johnson295189b2012-06-20 16:38:30 -0700568extern struct net_device_ops net_ops_struct;
Dasari Srinivas7875a302014-09-26 17:50:57 +0530569#ifdef FEATURE_WLAN_SCAN_PNO
570static eHalStatus wlan_hdd_is_pno_allowed(hdd_adapter_t *pAdapter);
571#endif
Jeff Johnson295189b2012-06-20 16:38:30 -0700572
Leo Chang9056f462013-08-01 19:21:11 -0700573#ifdef WLAN_NL80211_TESTMODE
574enum wlan_hdd_tm_attr
575{
576 WLAN_HDD_TM_ATTR_INVALID = 0,
577 WLAN_HDD_TM_ATTR_CMD = 1,
578 WLAN_HDD_TM_ATTR_DATA = 2,
579 WLAN_HDD_TM_ATTR_TYPE = 3,
580 /* keep last */
581 WLAN_HDD_TM_ATTR_AFTER_LAST,
582 WLAN_HDD_TM_ATTR_MAX = WLAN_HDD_TM_ATTR_AFTER_LAST - 1,
583};
584
585enum wlan_hdd_tm_cmd
586{
587 WLAN_HDD_TM_CMD_WLAN_HB = 1,
588};
589
590#define WLAN_HDD_TM_DATA_MAX_LEN 5000
591
592static const struct nla_policy wlan_hdd_tm_policy[WLAN_HDD_TM_ATTR_MAX + 1] =
593{
594 [WLAN_HDD_TM_ATTR_CMD] = { .type = NLA_U32 },
595 [WLAN_HDD_TM_ATTR_DATA] = { .type = NLA_BINARY,
596 .len = WLAN_HDD_TM_DATA_MAX_LEN },
597};
598#endif /* WLAN_NL80211_TESTMODE */
599
Rajesh Chauhan98a31f82014-01-06 20:15:25 -0800600#ifdef FEATURE_WLAN_CH_AVOID
601/*
602 * FUNCTION: wlan_hdd_send_avoid_freq_event
603 * This is called when wlan driver needs to send vendor specific
604 * avoid frequency range event to userspace
605 */
606int wlan_hdd_send_avoid_freq_event(hdd_context_t *pHddCtx,
607 tHddAvoidFreqList *pAvoidFreqList)
608{
609 struct sk_buff *vendor_event;
610
611 ENTER();
612
613 if (!pHddCtx)
614 {
615 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
616 "%s: HDD context is null", __func__);
617 return -1;
618 }
619
620 if (!pAvoidFreqList)
621 {
622 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
623 "%s: pAvoidFreqList is null", __func__);
624 return -1;
625 }
626
627 vendor_event = cfg80211_vendor_event_alloc(pHddCtx->wiphy,
628 sizeof(tHddAvoidFreqList),
Sunil Duttc69bccb2014-05-26 21:30:20 +0530629 QCA_NL80211_VENDOR_SUBCMD_AVOID_FREQUENCY_INDEX,
Rajesh Chauhan98a31f82014-01-06 20:15:25 -0800630 GFP_KERNEL);
631 if (!vendor_event)
632 {
633 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
634 "%s: cfg80211_vendor_event_alloc failed", __func__);
635 return -1;
636 }
637
638 memcpy(skb_put(vendor_event, sizeof(tHddAvoidFreqList)),
639 (void *)pAvoidFreqList, sizeof(tHddAvoidFreqList));
640
641 cfg80211_vendor_event(vendor_event, GFP_KERNEL);
642
643 EXIT();
644 return 0;
645}
646#endif /* FEATURE_WLAN_CH_AVOID */
647
Sunil Duttc69bccb2014-05-26 21:30:20 +0530648#ifdef WLAN_FEATURE_LINK_LAYER_STATS
649
650static v_BOOL_t put_wifi_rate_stat( tpSirWifiRateStat stats,
651 struct sk_buff *vendor_event)
652{
653 if (nla_put_u8(vendor_event,
654 QCA_WLAN_VENDOR_ATTR_LL_STATS_RATE_PREAMBLE,
655 stats->rate.preamble) ||
656 nla_put_u8(vendor_event,
657 QCA_WLAN_VENDOR_ATTR_LL_STATS_RATE_NSS,
658 stats->rate.nss) ||
659 nla_put_u8(vendor_event,
660 QCA_WLAN_VENDOR_ATTR_LL_STATS_RATE_BW,
661 stats->rate.bw) ||
662 nla_put_u8(vendor_event,
663 QCA_WLAN_VENDOR_ATTR_LL_STATS_RATE_MCS_INDEX,
664 stats->rate.rateMcsIdx) ||
665 nla_put_u32(vendor_event, QCA_WLAN_VENDOR_ATTR_LL_STATS_RATE_BIT_RATE,
666 stats->rate.bitrate ) ||
667 nla_put_u32(vendor_event, QCA_WLAN_VENDOR_ATTR_LL_STATS_RATE_TX_MPDU,
668 stats->txMpdu ) ||
669 nla_put_u32(vendor_event, QCA_WLAN_VENDOR_ATTR_LL_STATS_RATE_RX_MPDU,
670 stats->rxMpdu ) ||
671 nla_put_u32(vendor_event, QCA_WLAN_VENDOR_ATTR_LL_STATS_RATE_MPDU_LOST,
672 stats->mpduLost ) ||
673 nla_put_u32(vendor_event, QCA_WLAN_VENDOR_ATTR_LL_STATS_RATE_RETRIES,
674 stats->retries) ||
675 nla_put_u32(vendor_event,
676 QCA_WLAN_VENDOR_ATTR_LL_STATS_RATE_RETRIES_SHORT,
677 stats->retriesShort ) ||
678 nla_put_u32(vendor_event,
679 QCA_WLAN_VENDOR_ATTR_LL_STATS_RATE_RETRIES_LONG,
680 stats->retriesLong))
681 {
682 hddLog(VOS_TRACE_LEVEL_ERROR,
683 FL("QCA_WLAN_VENDOR_ATTR put fail"));
684 return FALSE;
685 }
686 return TRUE;
687}
688
689static v_BOOL_t put_wifi_peer_info( tpSirWifiPeerInfo stats,
690 struct sk_buff *vendor_event)
691{
692 u32 i = 0;
693 struct nlattr *rateInfo;
694 if (nla_put_u32(vendor_event, QCA_WLAN_VENDOR_ATTR_LL_STATS_PEER_INFO_TYPE,
695 stats->type) ||
696 nla_put(vendor_event,
697 QCA_WLAN_VENDOR_ATTR_LL_STATS_PEER_INFO_MAC_ADDRESS,
698 VOS_MAC_ADDR_SIZE, &stats->peerMacAddress[0]) ||
699 nla_put_u32(vendor_event,
700 QCA_WLAN_VENDOR_ATTR_LL_STATS_PEER_INFO_CAPABILITIES,
701 stats->capabilities) ||
702 nla_put_u32(vendor_event,
703 QCA_WLAN_VENDOR_ATTR_LL_STATS_PEER_INFO_NUM_RATES,
704 stats->numRate))
705 {
706 hddLog(VOS_TRACE_LEVEL_ERROR,
707 FL("QCA_WLAN_VENDOR_ATTR put fail"));
708 goto error;
709 }
710
711 rateInfo = nla_nest_start(vendor_event,
712 QCA_WLAN_VENDOR_ATTR_LL_STATS_PEER_INFO_RATE_INFO);
713 for (i = 0; i < stats->numRate; i++)
714 {
715 struct nlattr *rates;
716 tpSirWifiRateStat pRateStats = (tpSirWifiRateStat )((uint8 *)
717 stats->rateStats +
718 (i * sizeof(tSirWifiRateStat)));
719 rates = nla_nest_start(vendor_event, i);
720
721 if (FALSE == put_wifi_rate_stat(pRateStats, vendor_event))
722 {
723 hddLog(VOS_TRACE_LEVEL_ERROR,
724 FL("QCA_WLAN_VENDOR_ATTR put fail"));
725 return FALSE;
726 }
727 nla_nest_end(vendor_event, rates);
728 }
729 nla_nest_end(vendor_event, rateInfo);
730
731 return TRUE;
732error:
733 return FALSE;
734}
735
736static v_BOOL_t put_wifi_wmm_ac_stat( tpSirWifiWmmAcStat stats,
737 struct sk_buff *vendor_event)
738{
739 if (nla_put_u32(vendor_event, QCA_WLAN_VENDOR_ATTR_LL_STATS_WMM_AC_AC,
740 stats->ac ) ||
741 nla_put_u32(vendor_event,
742 QCA_WLAN_VENDOR_ATTR_LL_STATS_WMM_AC_TX_MPDU,
743 stats->txMpdu ) ||
744 nla_put_u32(vendor_event,
745 QCA_WLAN_VENDOR_ATTR_LL_STATS_WMM_AC_RX_MPDU,
746 stats->rxMpdu ) ||
747 nla_put_u32(vendor_event,
748 QCA_WLAN_VENDOR_ATTR_LL_STATS_WMM_AC_TX_MCAST,
749 stats->txMcast ) ||
750 nla_put_u32(vendor_event,
751 QCA_WLAN_VENDOR_ATTR_LL_STATS_WMM_AC_RX_MCAST,
752 stats->rxMcast ) ||
753 nla_put_u32(vendor_event,
754 QCA_WLAN_VENDOR_ATTR_LL_STATS_WMM_AC_RX_AMPDU,
755 stats->rxAmpdu ) ||
756 nla_put_u32(vendor_event,
757 QCA_WLAN_VENDOR_ATTR_LL_STATS_WMM_AC_TX_AMPDU,
758 stats->txAmpdu ) ||
759 nla_put_u32(vendor_event,
760 QCA_WLAN_VENDOR_ATTR_LL_STATS_WMM_AC_MPDU_LOST,
761 stats->mpduLost )||
762 nla_put_u32(vendor_event,
763 QCA_WLAN_VENDOR_ATTR_LL_STATS_WMM_AC_RETRIES,
764 stats->retries ) ||
765 nla_put_u32(vendor_event,
766 QCA_WLAN_VENDOR_ATTR_LL_STATS_WMM_AC_RETRIES_SHORT,
767 stats->retriesShort ) ||
768 nla_put_u32(vendor_event,
769 QCA_WLAN_VENDOR_ATTR_LL_STATS_WMM_AC_RETRIES_LONG,
770 stats->retriesLong ) ||
771 nla_put_u32(vendor_event,
772 QCA_WLAN_VENDOR_ATTR_LL_STATS_WMM_AC_CONTENTION_TIME_MIN,
773 stats->contentionTimeMin ) ||
774 nla_put_u32(vendor_event,
775 QCA_WLAN_VENDOR_ATTR_LL_STATS_WMM_AC_CONTENTION_TIME_MAX,
776 stats->contentionTimeMax ) ||
777 nla_put_u32(vendor_event,
778 QCA_WLAN_VENDOR_ATTR_LL_STATS_WMM_AC_CONTENTION_TIME_AVG,
779 stats->contentionTimeAvg ) ||
780 nla_put_u32(vendor_event,
781 QCA_WLAN_VENDOR_ATTR_LL_STATS_WMM_AC_CONTENTION_NUM_SAMPLES,
782 stats->contentionNumSamples ))
783 {
784 hddLog(VOS_TRACE_LEVEL_ERROR,
785 FL("QCA_WLAN_VENDOR_ATTR put fail") );
786 return FALSE;
787 }
788 return TRUE;
789}
790
791static v_BOOL_t put_wifi_interface_info(tpSirWifiInterfaceInfo stats,
792 struct sk_buff *vendor_event)
793{
Dino Myclec8f3f332014-07-21 16:48:27 +0530794 if (nla_put_s32(vendor_event,
Sunil Duttc69bccb2014-05-26 21:30:20 +0530795 QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_INFO_MODE, stats->mode ) ||
796 nla_put(vendor_event,
797 QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_INFO_MAC_ADDR,
798 VOS_MAC_ADDR_SIZE, stats->macAddr) ||
799 nla_put_u32(vendor_event,
800 QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_INFO_STATE,
801 stats->state ) ||
802 nla_put_u32(vendor_event,
803 QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_INFO_ROAMING,
804 stats->roaming ) ||
805 nla_put_u32(vendor_event,
806 QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_INFO_CAPABILITIES,
807 stats->capabilities ) ||
808 nla_put(vendor_event,
809 QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_INFO_SSID,
810 strlen(stats->ssid), stats->ssid) ||
811 nla_put(vendor_event,
812 QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_INFO_BSSID,
813 WNI_CFG_BSSID_LEN, stats->bssid) ||
814 nla_put(vendor_event,
815 QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_INFO_AP_COUNTRY_STR,
816 WNI_CFG_COUNTRY_CODE_LEN, stats->apCountryStr) ||
817 nla_put(vendor_event,
818 QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_INFO_COUNTRY_STR,
819 WNI_CFG_COUNTRY_CODE_LEN, stats->countryStr)
820 )
821 {
822 hddLog(VOS_TRACE_LEVEL_ERROR,
823 FL("QCA_WLAN_VENDOR_ATTR put fail") );
824 return FALSE;
825 }
826 return TRUE;
827}
828
Dino Mycle3b9536d2014-07-09 22:05:24 +0530829static v_BOOL_t put_wifi_iface_stats(hdd_adapter_t *pAdapter,
830 tpSirWifiIfaceStat pWifiIfaceStat,
Sunil Duttc69bccb2014-05-26 21:30:20 +0530831 struct sk_buff *vendor_event)
832{
833 int i = 0;
834 struct nlattr *wmmInfo;
Dino Mycle3b9536d2014-07-09 22:05:24 +0530835 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
836 WLANTL_InterfaceStatsType *pWifiIfaceStatTL = NULL;
837
Sunil Duttc69bccb2014-05-26 21:30:20 +0530838 if (FALSE == put_wifi_interface_info(
839 &pWifiIfaceStat->info,
840 vendor_event))
841 {
842 hddLog(VOS_TRACE_LEVEL_ERROR,
843 FL("QCA_WLAN_VENDOR_ATTR put fail") );
844 return FALSE;
845
846 }
Dino Mycle3b9536d2014-07-09 22:05:24 +0530847 pWifiIfaceStatTL = (WLANTL_InterfaceStatsType *)
848 vos_mem_malloc(sizeof(WLANTL_InterfaceStatsType));
849 if (NULL == pWifiIfaceStatTL)
850 {
851 hddLog(VOS_TRACE_LEVEL_ERROR, FL("vos_mem_malloc failed"));
852 return FALSE;
853 }
854
855
856 if ( pWifiIfaceStat->info.state == WIFI_ASSOCIATED)
857 {
858 if (VOS_STATUS_SUCCESS ==
859 WLANTL_CollectInterfaceStats((WLAN_HDD_GET_CTX(pAdapter))->pvosContext,
860 pHddStaCtx->conn_info.staId[0], pWifiIfaceStatTL))
861 {
862 /* mgmtRx, MgmtActionRx, rxMcast, rxMpdu, rxAmpdu, rssiData are
863 * obtained from TL structure
864 */
865
866 pWifiIfaceStat->mgmtRx = pWifiIfaceStat->beaconRx +
867 pWifiIfaceStatTL->mgmtRx;
868 pWifiIfaceStat->mgmtActionRx = pWifiIfaceStatTL->mgmtActionRx;
869 pWifiIfaceStat->mgmtActionTx = pWifiIfaceStatTL->mgmtActionTx;
870 pWifiIfaceStat->rssiData = pWifiIfaceStatTL->rssiData;
871
872 vos_mem_copy(
873 (void *) &pWifiIfaceStat->AccessclassStats[WIFI_AC_VO],
874 (void *) &pWifiIfaceStatTL->accessCategoryStats[WLANTL_AC_VO],
875 sizeof(WLANTL_AccessCategoryStatsType));
876
877 vos_mem_copy(
878 (void *) &pWifiIfaceStat->AccessclassStats[WIFI_AC_VI],
879 (void *) &pWifiIfaceStatTL->accessCategoryStats[WLANTL_AC_VI],
880 sizeof(WLANTL_AccessCategoryStatsType));
881
882 vos_mem_copy(
883 (void *) &pWifiIfaceStat->AccessclassStats[WIFI_AC_BE],
884 (void *) &pWifiIfaceStatTL->accessCategoryStats[WLANTL_AC_BE],
885 sizeof(WLANTL_AccessCategoryStatsType));
886
887 vos_mem_copy(
888 (void *) &pWifiIfaceStat->AccessclassStats[WIFI_AC_BK],
889 (void *) &pWifiIfaceStatTL->accessCategoryStats[WLANTL_AC_BK],
890 sizeof(WLANTL_AccessCategoryStatsType));
891 }
892 else
893 {
894 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Error in getting stats from TL"));
895 }
896
897 pWifiIfaceStat->AccessclassStats[WIFI_AC_VO].txMpdu =
898 pAdapter->hdd_stats.hddTxRxStats.txFetchedAC[WLANTL_AC_VO];
899 pWifiIfaceStat->AccessclassStats[WIFI_AC_VI].txMpdu =
900 pAdapter->hdd_stats.hddTxRxStats.txFetchedAC[WLANTL_AC_VI];
901 pWifiIfaceStat->AccessclassStats[WIFI_AC_BE].txMpdu =
902 pAdapter->hdd_stats.hddTxRxStats.txFetchedAC[WLANTL_AC_BE];
903 pWifiIfaceStat->AccessclassStats[WIFI_AC_BK].txMpdu =
904 pAdapter->hdd_stats.hddTxRxStats.txFetchedAC[WLANTL_AC_BK];
905
906 pWifiIfaceStat->AccessclassStats[WIFI_AC_VO].txMcast =
907 pAdapter->hdd_stats.hddTxRxStats.txMcast[WLANTL_AC_VO];
908 pWifiIfaceStat->AccessclassStats[WIFI_AC_VI].txMcast =
909 pAdapter->hdd_stats.hddTxRxStats.txMcast[WLANTL_AC_VI];
910 pWifiIfaceStat->AccessclassStats[WIFI_AC_BE].txMcast =
911 pAdapter->hdd_stats.hddTxRxStats.txMcast[WLANTL_AC_BE];
912 pWifiIfaceStat->AccessclassStats[WIFI_AC_BK].txMcast =
913 pAdapter->hdd_stats.hddTxRxStats.txMcast[WLANTL_AC_BK];
914 }
915 else
916 {
917 hddLog(VOS_TRACE_LEVEL_INFO, FL("Interface not Associated"));
918 }
919
920
Sunil Duttc69bccb2014-05-26 21:30:20 +0530921
922 if (nla_put_u32(vendor_event,
923 QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_BEACON_RX,
924 pWifiIfaceStat->beaconRx) ||
925 nla_put_u32(vendor_event,
926 QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_MGMT_RX,
927 pWifiIfaceStat->mgmtRx) ||
928 nla_put_u32(vendor_event,
929 QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_MGMT_ACTION_RX,
930 pWifiIfaceStat->mgmtActionRx) ||
931 nla_put_u32(vendor_event,
932 QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_MGMT_ACTION_TX,
933 pWifiIfaceStat->mgmtActionTx) ||
Dino Mycle3b9536d2014-07-09 22:05:24 +0530934 nla_put_s32(vendor_event,
Sunil Duttc69bccb2014-05-26 21:30:20 +0530935 QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_RSSI_MGMT,
936 pWifiIfaceStat->rssiMgmt) ||
Dino Mycle3b9536d2014-07-09 22:05:24 +0530937 nla_put_s32(vendor_event,
Sunil Duttc69bccb2014-05-26 21:30:20 +0530938 QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_RSSI_DATA,
939 pWifiIfaceStat->rssiData) ||
Dino Mycle3b9536d2014-07-09 22:05:24 +0530940 nla_put_s32(vendor_event,
Sunil Duttc69bccb2014-05-26 21:30:20 +0530941 QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_RSSI_ACK,
942 pWifiIfaceStat->rssiAck))
943 {
944 hddLog(VOS_TRACE_LEVEL_ERROR,
945 FL("QCA_WLAN_VENDOR_ATTR put fail"));
Dino Mycle3b9536d2014-07-09 22:05:24 +0530946 vos_mem_free(pWifiIfaceStatTL);
Sunil Duttc69bccb2014-05-26 21:30:20 +0530947 return FALSE;
948 }
949
950 wmmInfo = nla_nest_start(vendor_event,
951 QCA_WLAN_VENDOR_ATTR_LL_STATS_WMM_INFO);
952 for (i = 0; i < WIFI_AC_MAX; i++)
953 {
954 struct nlattr *wmmStats;
955 wmmStats = nla_nest_start(vendor_event, i);
956 if (FALSE == put_wifi_wmm_ac_stat(
957 &pWifiIfaceStat->AccessclassStats[i],
958 vendor_event))
959 {
960 hddLog(VOS_TRACE_LEVEL_ERROR,
961 FL("QCA_WLAN_VENDOR_ATTR put Fail"));
Dino Mycle3b9536d2014-07-09 22:05:24 +0530962 vos_mem_free(pWifiIfaceStatTL);
Sunil Duttc69bccb2014-05-26 21:30:20 +0530963 return FALSE;
964 }
965
966 nla_nest_end(vendor_event, wmmStats);
967 }
968 nla_nest_end(vendor_event, wmmInfo);
Dino Mycle3b9536d2014-07-09 22:05:24 +0530969 vos_mem_free(pWifiIfaceStatTL);
Sunil Duttc69bccb2014-05-26 21:30:20 +0530970 return TRUE;
971}
972
973static tSirWifiInterfaceMode
974 hdd_map_device_to_ll_iface_mode ( int deviceMode )
975{
976 switch (deviceMode)
977 {
978 case WLAN_HDD_INFRA_STATION:
979 return WIFI_INTERFACE_STA;
980 case WLAN_HDD_SOFTAP:
981 return WIFI_INTERFACE_SOFTAP;
982 case WLAN_HDD_P2P_CLIENT:
983 return WIFI_INTERFACE_P2P_CLIENT;
984 case WLAN_HDD_P2P_GO:
985 return WIFI_INTERFACE_P2P_GO;
986 case WLAN_HDD_IBSS:
987 return WIFI_INTERFACE_IBSS;
988 default:
Dino Myclec8f3f332014-07-21 16:48:27 +0530989 return WIFI_INTERFACE_UNKNOWN;
Sunil Duttc69bccb2014-05-26 21:30:20 +0530990 }
991}
992
993static v_BOOL_t hdd_get_interface_info(hdd_adapter_t *pAdapter,
994 tpSirWifiInterfaceInfo pInfo)
995{
996 v_U8_t *staMac = NULL;
997 hdd_station_ctx_t *pHddStaCtx;
998 tHalHandle hHal = WLAN_HDD_GET_HAL_CTX(pAdapter);
999 tpAniSirGlobal pMac = PMAC_STRUCT( hHal );
1000
1001 pInfo->mode = hdd_map_device_to_ll_iface_mode(pAdapter->device_mode);
1002
1003 vos_mem_copy(pInfo->macAddr,
1004 pAdapter->macAddressCurrent.bytes, sizeof(v_MACADDR_t));
1005
1006 if (((WLAN_HDD_INFRA_STATION == pAdapter->device_mode) ||
1007 (WLAN_HDD_P2P_CLIENT == pAdapter->device_mode) ||
1008 (WLAN_HDD_P2P_DEVICE == pAdapter->device_mode)))
1009 {
1010 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
1011 if (eConnectionState_NotConnected == pHddStaCtx->conn_info.connState)
1012 {
1013 pInfo->state = WIFI_DISCONNECTED;
1014 }
1015 if (eConnectionState_Connecting == pHddStaCtx->conn_info.connState)
1016 {
1017 hddLog(VOS_TRACE_LEVEL_ERROR,
1018 "%s: Session ID %d, Connection is in progress", __func__,
1019 pAdapter->sessionId);
1020 pInfo->state = WIFI_ASSOCIATING;
1021 }
1022 if ((eConnectionState_Associated == pHddStaCtx->conn_info.connState) &&
1023 (VOS_FALSE == pHddStaCtx->conn_info.uIsAuthenticated))
1024 {
1025 staMac = (v_U8_t *) &(pAdapter->macAddressCurrent.bytes[0]);
1026 hddLog(VOS_TRACE_LEVEL_ERROR,
1027 "%s: client " MAC_ADDRESS_STR
1028 " is in the middle of WPS/EAPOL exchange.", __func__,
1029 MAC_ADDR_ARRAY(staMac));
1030 pInfo->state = WIFI_AUTHENTICATING;
1031 }
1032 if (eConnectionState_Associated == pHddStaCtx->conn_info.connState)
1033 {
1034 pInfo->state = WIFI_ASSOCIATED;
1035 vos_mem_copy(pInfo->bssid,
1036 &pHddStaCtx->conn_info.bssId, WNI_CFG_BSSID_LEN);
1037 vos_mem_copy(pInfo->ssid,
1038 pHddStaCtx->conn_info.SSID.SSID.ssId,
1039 pHddStaCtx->conn_info.SSID.SSID.length);
1040 //NULL Terminate the string.
1041 pInfo->ssid[pHddStaCtx->conn_info.SSID.SSID.length] = 0;
1042 }
1043 }
1044 vos_mem_copy(pInfo->countryStr,
1045 pMac->scan.countryCodeCurrent, WNI_CFG_COUNTRY_CODE_LEN);
1046
1047 vos_mem_copy(pInfo->apCountryStr,
1048 pMac->scan.countryCodeCurrent, WNI_CFG_COUNTRY_CODE_LEN);
1049
1050 return TRUE;
1051}
1052
1053/*
1054 * hdd_link_layer_process_peer_stats () - This function is called after
1055 * receiving Link Layer Peer statistics from FW.This function converts
1056 * the firmware data to the NL data and sends the same to the kernel/upper
1057 * layers.
1058 */
1059static v_VOID_t hdd_link_layer_process_peer_stats(hdd_adapter_t *pAdapter,
1060 v_VOID_t *pData)
1061{
1062 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
1063 tpSirWifiRateStat pWifiRateStat;
1064 tpSirWifiPeerStat pWifiPeerStat;
1065 tpSirWifiPeerInfo pWifiPeerInfo;
1066 struct nlattr *peerInfo;
1067 struct sk_buff *vendor_event;
1068 int status, i;
1069
1070 status = wlan_hdd_validate_context(pHddCtx);
1071 if (0 != status)
1072 {
1073 hddLog(VOS_TRACE_LEVEL_ERROR,
1074 FL("HDD context is not valid") );
1075 return;
1076 }
1077
1078 pWifiPeerStat = (tpSirWifiPeerStat) pData;
1079
1080 hddLog(VOS_TRACE_LEVEL_INFO,
1081 "LL_STATS_PEER_ALL : numPeers %u",
1082 pWifiPeerStat->numPeers);
1083 {
1084 for (i = 0; i < pWifiPeerStat->numPeers; i++)
1085 {
1086 pWifiPeerInfo = (tpSirWifiPeerInfo)
1087 ((uint8 *)pWifiPeerStat->peerInfo +
1088 ( i * sizeof(tSirWifiPeerInfo)));
1089
Dasari Srinivas1be0c4e2014-10-19 13:03:41 +05301090 if (WLAN_HDD_INFRA_STATION == pAdapter->device_mode) {
1091 pWifiPeerInfo->type = WIFI_PEER_AP;
1092 }
1093 if (WLAN_HDD_P2P_CLIENT == pAdapter->device_mode) {
1094 pWifiPeerInfo->type = WIFI_PEER_P2P_GO;
1095 }
1096
Sunil Duttc69bccb2014-05-26 21:30:20 +05301097 hddLog(VOS_TRACE_LEVEL_INFO,
1098 " %d) LL_STATS Channel Stats "
1099 " Peer Type %u "
1100 " peerMacAddress %pM "
1101 " capabilities 0x%x "
1102 " numRate %u ",
1103 i,
1104 pWifiPeerInfo->type,
1105 pWifiPeerInfo->peerMacAddress,
1106 pWifiPeerInfo->capabilities,
1107 pWifiPeerInfo->numRate);
1108 {
1109 int j;
1110 for (j = 0; j < pWifiPeerInfo->numRate; j++)
1111 {
1112 pWifiRateStat = (tpSirWifiRateStat)
1113 ((tANI_U8 *) pWifiPeerInfo->rateStats +
1114 ( j * sizeof(tSirWifiRateStat)));
1115
1116 hddLog(VOS_TRACE_LEVEL_INFO,
1117 " peer Rate Stats "
1118 " preamble %u "
1119 " nss %u "
1120 " bw %u "
1121 " rateMcsIdx %u "
1122 " reserved %u "
1123 " bitrate %u "
1124 " txMpdu %u "
1125 " rxMpdu %u "
1126 " mpduLost %u "
1127 " retries %u "
1128 " retriesShort %u "
1129 " retriesLong %u",
1130 pWifiRateStat->rate.preamble,
1131 pWifiRateStat->rate.nss,
1132 pWifiRateStat->rate.bw,
1133 pWifiRateStat->rate.rateMcsIdx,
1134 pWifiRateStat->rate.reserved,
1135 pWifiRateStat->rate.bitrate,
1136 pWifiRateStat->txMpdu,
1137 pWifiRateStat->rxMpdu,
1138 pWifiRateStat->mpduLost,
1139 pWifiRateStat->retries,
1140 pWifiRateStat->retriesShort,
1141 pWifiRateStat->retriesLong);
1142 }
1143 }
1144 }
1145 }
1146
1147 /*
1148 * Allocate a size of 4096 for the peer stats comprising
1149 * each of size = sizeof (tSirWifiPeerInfo) + numRate *
1150 * sizeof (tSirWifiRateStat).Each field is put with an
1151 * NL attribute.The size of 4096 is considered assuming
1152 * that number of rates shall not exceed beyond 50 with
1153 * the sizeof (tSirWifiRateStat) being 32.
1154 */
1155 vendor_event = cfg80211_vendor_event_alloc(pHddCtx->wiphy,
1156 LL_STATS_EVENT_BUF_SIZE + NLMSG_HDRLEN,
1157 QCA_NL80211_VENDOR_SUBCMD_LL_PEER_INFO_STATS_INDEX,
1158 GFP_KERNEL);
1159 if (!vendor_event)
1160 {
1161 hddLog(VOS_TRACE_LEVEL_ERROR,
1162 "%s: cfg80211_vendor_event_alloc failed",
1163 __func__);
1164 return;
1165 }
1166 if (nla_put_u32(vendor_event,
1167 QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_NUM_PEERS,
1168 pWifiPeerStat->numPeers))
1169 {
1170 hddLog(VOS_TRACE_LEVEL_ERROR,
1171 "%s: QCA_WLAN_VENDOR_ATTR put fail", __func__);
1172 kfree_skb(vendor_event);
1173 return;
1174 }
1175
1176 peerInfo = nla_nest_start(vendor_event,
1177 QCA_WLAN_VENDOR_ATTR_LL_STATS_PEER_INFO);
1178
1179 pWifiPeerInfo = (tpSirWifiPeerInfo) ((uint8 *)
1180 pWifiPeerStat->peerInfo);
1181
1182 for (i = 1; i <= pWifiPeerStat->numPeers; i++)
1183 {
1184 struct nlattr *peers = nla_nest_start(vendor_event, i);
1185 int numRate = pWifiPeerInfo->numRate;
1186
1187 if (FALSE == put_wifi_peer_info(
1188 pWifiPeerInfo, vendor_event))
1189 {
1190 hddLog(VOS_TRACE_LEVEL_ERROR,
1191 "%s: put_wifi_peer_info put fail", __func__);
1192 kfree_skb(vendor_event);
1193 return;
1194 }
1195
1196 pWifiPeerInfo = (tpSirWifiPeerInfo) ((uint8 *)
1197 pWifiPeerStat->peerInfo +
1198 (i * sizeof(tSirWifiPeerInfo)) +
1199 (numRate * sizeof (tSirWifiRateStat)));
1200 nla_nest_end(vendor_event, peers);
1201 }
1202 nla_nest_end(vendor_event, peerInfo);
1203 cfg80211_vendor_event(vendor_event, GFP_KERNEL);
1204}
1205
1206/*
1207 * hdd_link_layer_process_iface_stats () - This function is called after
1208 * receiving Link Layer Interface statistics from FW.This function converts
1209 * the firmware data to the NL data and sends the same to the kernel/upper
1210 * layers.
1211 */
1212static v_VOID_t hdd_link_layer_process_iface_stats(hdd_adapter_t *pAdapter,
1213 v_VOID_t *pData)
1214{
1215 tpSirWifiIfaceStat pWifiIfaceStat;
1216 struct sk_buff *vendor_event;
1217 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
1218 int status;
1219
1220 status = wlan_hdd_validate_context(pHddCtx);
1221 if (0 != status)
1222 {
1223 hddLog(VOS_TRACE_LEVEL_ERROR,
1224 FL("HDD context is not valid") );
1225 return;
1226 }
1227 /*
1228 * Allocate a size of 4096 for the interface stats comprising
1229 * sizeof (tpSirWifiIfaceStat).The size of 4096 is considered
1230 * assuming that all these fit with in the limit.Please take
1231 * a call on the limit based on the data requirements on
1232 * interface statistics.
1233 */
1234 vendor_event = cfg80211_vendor_event_alloc(pHddCtx->wiphy,
1235 LL_STATS_EVENT_BUF_SIZE + NLMSG_HDRLEN,
1236 QCA_NL80211_VENDOR_SUBCMD_LL_IFACE_STATS_INDEX,
1237 GFP_KERNEL);
1238 if (!vendor_event)
1239 {
1240 hddLog(VOS_TRACE_LEVEL_ERROR,
1241 FL("cfg80211_vendor_event_alloc failed") );
1242 return;
1243 }
1244
1245 pWifiIfaceStat = (tpSirWifiIfaceStat) pData;
1246
Dino Mycle3b9536d2014-07-09 22:05:24 +05301247
1248 if (FALSE == hdd_get_interface_info( pAdapter,
1249 &pWifiIfaceStat->info))
1250 {
1251 hddLog(VOS_TRACE_LEVEL_ERROR,
1252 FL("hdd_get_interface_info get fail") );
1253 kfree_skb(vendor_event);
1254 return;
1255 }
1256
1257 if (FALSE == put_wifi_iface_stats( pAdapter, pWifiIfaceStat,
1258 vendor_event))
1259 {
1260 hddLog(VOS_TRACE_LEVEL_ERROR,
1261 FL("put_wifi_iface_stats fail") );
1262 kfree_skb(vendor_event);
1263 return;
1264 }
1265
Sunil Duttc69bccb2014-05-26 21:30:20 +05301266 hddLog(VOS_TRACE_LEVEL_INFO,
1267 "WMI_LINK_STATS_IFACE Data");
1268
1269 hddLog(VOS_TRACE_LEVEL_INFO,
1270 "LL_STATS_IFACE: "
1271 " Mode %u "
1272 " MAC %pM "
1273 " State %u "
1274 " Roaming %u "
1275 " capabilities 0x%x "
1276 " SSID %s "
1277 " BSSID %pM",
1278 pWifiIfaceStat->info.mode,
1279 pWifiIfaceStat->info.macAddr,
1280 pWifiIfaceStat->info.state,
1281 pWifiIfaceStat->info.roaming,
1282 pWifiIfaceStat->info.capabilities,
1283 pWifiIfaceStat->info.ssid,
1284 pWifiIfaceStat->info.bssid);
1285
1286 hddLog(VOS_TRACE_LEVEL_INFO,
1287 " AP country str: %c%c%c",
1288 pWifiIfaceStat->info.apCountryStr[0],
1289 pWifiIfaceStat->info.apCountryStr[1],
1290 pWifiIfaceStat->info.apCountryStr[2]);
1291
1292
1293 hddLog(VOS_TRACE_LEVEL_INFO,
1294 " Country Str Association: %c%c%c",
1295 pWifiIfaceStat->info.countryStr[0],
1296 pWifiIfaceStat->info.countryStr[1],
1297 pWifiIfaceStat->info.countryStr[2]);
1298
1299 hddLog(VOS_TRACE_LEVEL_INFO,
1300 " beaconRx %u "
1301 " mgmtRx %u "
1302 " mgmtActionRx %u "
1303 " mgmtActionTx %u "
Dino Mycle3b9536d2014-07-09 22:05:24 +05301304 " rssiMgmt %d "
1305 " rssiData %d "
1306 " rssiAck %d",
Sunil Duttc69bccb2014-05-26 21:30:20 +05301307 pWifiIfaceStat->beaconRx,
1308 pWifiIfaceStat->mgmtRx,
1309 pWifiIfaceStat->mgmtActionRx,
1310 pWifiIfaceStat->mgmtActionTx,
1311 pWifiIfaceStat->rssiMgmt,
1312 pWifiIfaceStat->rssiData,
1313 pWifiIfaceStat->rssiAck );
1314
1315
1316 {
1317 int i;
1318 for (i = 0 ; i < WIFI_AC_MAX; i ++)
1319 {
1320 hddLog(VOS_TRACE_LEVEL_INFO,
1321
1322 " %d) LL_STATS IFACE: "
1323 " ac: %u txMpdu: %u "
1324 " rxMpdu: %u txMcast: %u "
1325 " rxMcast: %u rxAmpdu: %u "
1326 " txAmpdu: %u mpduLost: %u "
1327 " retries: %u retriesShort: %u "
1328 " retriesLong: %u contentionTimeMin: %u "
1329 " contentionTimeMax: %u contentionTimeAvg: %u "
1330 " contentionNumSamples: %u",
1331 i,
1332 pWifiIfaceStat->AccessclassStats[i].ac,
1333 pWifiIfaceStat->AccessclassStats[i].txMpdu,
1334 pWifiIfaceStat->AccessclassStats[i].rxMpdu,
1335 pWifiIfaceStat->AccessclassStats[i].txMcast,
1336 pWifiIfaceStat->AccessclassStats[i].rxMcast,
1337 pWifiIfaceStat->AccessclassStats[i].rxAmpdu,
1338 pWifiIfaceStat->AccessclassStats[i].txAmpdu,
1339 pWifiIfaceStat->AccessclassStats[i].mpduLost,
1340 pWifiIfaceStat->AccessclassStats[i].retries,
1341 pWifiIfaceStat->
1342 AccessclassStats[i].retriesShort,
1343 pWifiIfaceStat->AccessclassStats[i].retriesLong,
1344 pWifiIfaceStat->
1345 AccessclassStats[i].contentionTimeMin,
1346 pWifiIfaceStat->
1347 AccessclassStats[i].contentionTimeMax,
1348 pWifiIfaceStat->
1349 AccessclassStats[i].contentionTimeAvg,
1350 pWifiIfaceStat->
1351 AccessclassStats[i].contentionNumSamples);
1352
1353 }
1354 }
1355
Sunil Duttc69bccb2014-05-26 21:30:20 +05301356 cfg80211_vendor_event(vendor_event, GFP_KERNEL);
1357}
1358
1359/*
1360 * hdd_link_layer_process_radio_stats () - This function is called after
1361 * receiving Link Layer Radio statistics from FW.This function converts
1362 * the firmware data to the NL data and sends the same to the kernel/upper
1363 * layers.
1364 */
1365static v_VOID_t hdd_link_layer_process_radio_stats(hdd_adapter_t *pAdapter,
1366 v_VOID_t *pData)
1367{
1368 int status, i;
1369 tpSirWifiRadioStat pWifiRadioStat;
1370 tpSirWifiChannelStats pWifiChannelStats;
1371 struct sk_buff *vendor_event;
1372 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
1373 struct nlattr *chList;
1374
1375 status = wlan_hdd_validate_context(pHddCtx);
1376 if (0 != status)
1377 {
1378 hddLog(VOS_TRACE_LEVEL_ERROR,
1379 FL("HDD context is not valid") );
1380 return;
1381 }
1382 pWifiRadioStat = (tpSirWifiRadioStat) pData;
1383
1384 hddLog(VOS_TRACE_LEVEL_INFO,
1385 "LL_STATS_RADIO"
1386 " radio is %d onTime is %u "
1387 " txTime is %u rxTime is %u "
1388 " onTimeScan is %u onTimeNbd is %u "
Dino Mycle6fb96c12014-06-10 11:52:40 +05301389 " onTimeEXTScan is %u onTimeRoamScan is %u "
Sunil Duttc69bccb2014-05-26 21:30:20 +05301390 " onTimePnoScan is %u onTimeHs20 is %u "
1391 " numChannels is %u",
1392 pWifiRadioStat->radio, pWifiRadioStat->onTime,
1393 pWifiRadioStat->txTime, pWifiRadioStat->rxTime,
1394 pWifiRadioStat->onTimeScan, pWifiRadioStat->onTimeNbd,
Dino Mycle6fb96c12014-06-10 11:52:40 +05301395 pWifiRadioStat->onTimeEXTScan,
Sunil Duttc69bccb2014-05-26 21:30:20 +05301396 pWifiRadioStat->onTimeRoamScan,
1397 pWifiRadioStat->onTimePnoScan,
1398 pWifiRadioStat->onTimeHs20,
1399 pWifiRadioStat->numChannels);
1400 /*
1401 * Allocate a size of 4096 for the Radio stats comprising
1402 * sizeof (tSirWifiRadioStat) + numChannels * sizeof
1403 * (tSirWifiChannelStats).Each channel data is put with an
1404 * NL attribute.The size of 4096 is considered assuming that
1405 * number of channels shall not exceed beyond 60 with the
1406 * sizeof (tSirWifiChannelStats) being 24 bytes.
1407 */
1408
1409 vendor_event = cfg80211_vendor_event_alloc(pHddCtx->wiphy,
1410 LL_STATS_EVENT_BUF_SIZE + NLMSG_HDRLEN ,
1411 QCA_NL80211_VENDOR_SUBCMD_LL_RADIO_STATS_INDEX,
1412 GFP_KERNEL);
1413
1414 if (!vendor_event)
1415 {
1416 hddLog(VOS_TRACE_LEVEL_ERROR,
1417 FL("cfg80211_vendor_event_alloc failed") );
1418 return;
1419 }
1420
1421 if (nla_put_u32(vendor_event,
1422 QCA_WLAN_VENDOR_ATTR_LL_STATS_RADIO_ID,
1423 pWifiRadioStat->radio) ||
1424 nla_put_u32(vendor_event,
1425 QCA_WLAN_VENDOR_ATTR_LL_STATS_RADIO_ON_TIME,
1426 pWifiRadioStat->onTime) ||
1427 nla_put_u32(vendor_event,
1428 QCA_WLAN_VENDOR_ATTR_LL_STATS_RADIO_TX_TIME,
1429 pWifiRadioStat->txTime) ||
1430 nla_put_u32(vendor_event,
1431 QCA_WLAN_VENDOR_ATTR_LL_STATS_RADIO_RX_TIME,
1432 pWifiRadioStat->rxTime) ||
1433 nla_put_u32(vendor_event,
1434 QCA_WLAN_VENDOR_ATTR_LL_STATS_RADIO_ON_TIME_SCAN,
1435 pWifiRadioStat->onTimeScan) ||
1436 nla_put_u32(vendor_event,
1437 QCA_WLAN_VENDOR_ATTR_LL_STATS_RADIO_ON_TIME_NBD,
1438 pWifiRadioStat->onTimeNbd) ||
1439 nla_put_u32(vendor_event,
Dino Mycle6fb96c12014-06-10 11:52:40 +05301440 QCA_WLAN_VENDOR_ATTR_LL_STATS_RADIO_ON_TIME_EXTSCAN,
1441 pWifiRadioStat->onTimeEXTScan)||
Sunil Duttc69bccb2014-05-26 21:30:20 +05301442 nla_put_u32(vendor_event,
1443 QCA_WLAN_VENDOR_ATTR_LL_STATS_RADIO_ON_TIME_ROAM_SCAN,
1444 pWifiRadioStat->onTimeRoamScan) ||
1445 nla_put_u32(vendor_event,
1446 QCA_WLAN_VENDOR_ATTR_LL_STATS_RADIO_ON_TIME_PNO_SCAN,
1447 pWifiRadioStat->onTimePnoScan) ||
1448 nla_put_u32(vendor_event,
1449 QCA_WLAN_VENDOR_ATTR_LL_STATS_RADIO_ON_TIME_HS20,
1450 pWifiRadioStat->onTimeHs20) ||
1451 nla_put_u32(vendor_event,
1452 QCA_WLAN_VENDOR_ATTR_LL_STATS_RADIO_NUM_CHANNELS,
1453 pWifiRadioStat->numChannels))
1454 {
1455 hddLog(VOS_TRACE_LEVEL_ERROR,
1456 FL("QCA_WLAN_VENDOR_ATTR put fail"));
1457 kfree_skb(vendor_event);
1458 return ;
1459 }
1460
1461 chList = nla_nest_start(vendor_event,
1462 QCA_WLAN_VENDOR_ATTR_LL_STATS_CH_INFO);
1463 for (i = 0; i < pWifiRadioStat->numChannels; i++)
1464 {
1465 struct nlattr *chInfo;
1466
1467 pWifiChannelStats = (tpSirWifiChannelStats) ((uint8*)
1468 pWifiRadioStat->channels +
1469 (i * sizeof(tSirWifiChannelStats)));
1470
1471 hddLog(VOS_TRACE_LEVEL_INFO,
1472 " %d) Channel Info"
1473 " width is %u "
1474 " CenterFreq %u "
1475 " CenterFreq0 %u "
1476 " CenterFreq1 %u "
1477 " onTime %u "
1478 " ccaBusyTime %u",
1479 i,
1480 pWifiChannelStats->channel.width,
1481 pWifiChannelStats->channel.centerFreq,
1482 pWifiChannelStats->channel.centerFreq0,
1483 pWifiChannelStats->channel.centerFreq1,
1484 pWifiChannelStats->onTime,
1485 pWifiChannelStats->ccaBusyTime);
1486
1487
1488 chInfo = nla_nest_start(vendor_event, i);
1489
1490 if (nla_put_u32(vendor_event,
1491 QCA_WLAN_VENDOR_ATTR_LL_STATS_CHANNEL_INFO_WIDTH,
1492 pWifiChannelStats->channel.width) ||
1493 nla_put_u32(vendor_event,
1494 QCA_WLAN_VENDOR_ATTR_LL_STATS_CHANNEL_INFO_CENTER_FREQ,
1495 pWifiChannelStats->channel.centerFreq) ||
1496 nla_put_u32(vendor_event,
1497 QCA_WLAN_VENDOR_ATTR_LL_STATS_CHANNEL_INFO_CENTER_FREQ0,
1498 pWifiChannelStats->channel.centerFreq0) ||
1499 nla_put_u32(vendor_event,
1500 QCA_WLAN_VENDOR_ATTR_LL_STATS_CHANNEL_INFO_CENTER_FREQ1,
1501 pWifiChannelStats->channel.centerFreq1) ||
1502 nla_put_u32(vendor_event,
1503 QCA_WLAN_VENDOR_ATTR_LL_STATS_CHANNEL_ON_TIME,
1504 pWifiChannelStats->onTime) ||
1505 nla_put_u32(vendor_event,
1506 QCA_WLAN_VENDOR_ATTR_LL_STATS_CHANNEL_CCA_BUSY_TIME,
1507 pWifiChannelStats->ccaBusyTime))
1508 {
1509 hddLog(VOS_TRACE_LEVEL_ERROR,
1510 FL("cfg80211_vendor_event_alloc failed") );
1511 kfree_skb(vendor_event);
1512 return ;
1513 }
1514 nla_nest_end(vendor_event, chInfo);
1515 }
1516 nla_nest_end(vendor_event, chList);
1517
1518 cfg80211_vendor_event(vendor_event, GFP_KERNEL);
1519 return;
1520}
1521
1522/*
1523 * hdd_link_layer_stats_ind_callback () - This function is called after
1524 * receiving Link Layer indications from FW.This callback converts the firmware
1525 * data to the NL data and send the same to the kernel/upper layers.
1526 */
1527static void hdd_link_layer_stats_ind_callback ( void *pCtx,
1528 int indType,
Dino Mycled3d50022014-07-07 12:58:25 +05301529 void *pRsp, u8 *macAddr)
Sunil Duttc69bccb2014-05-26 21:30:20 +05301530{
Dino Mycled3d50022014-07-07 12:58:25 +05301531 hdd_context_t *pHddCtx = (hdd_context_t *)pCtx;
1532 hdd_adapter_t *pAdapter = NULL;
1533 tpSirLLStatsResults linkLayerStatsResults = (tpSirLLStatsResults)pRsp;
Sunil Duttc69bccb2014-05-26 21:30:20 +05301534 int status;
1535
1536 status = wlan_hdd_validate_context(pHddCtx);
1537
1538 if (0 != status)
1539 {
1540 hddLog(VOS_TRACE_LEVEL_ERROR,
1541 FL("HDD context is not valid"));
1542 return;
1543 }
1544
Dino Mycled3d50022014-07-07 12:58:25 +05301545
1546
1547 pAdapter = hdd_get_adapter_by_macaddr(pHddCtx, macAddr);
1548 if (NULL == pAdapter)
1549 {
1550 hddLog(VOS_TRACE_LEVEL_ERROR,
1551 FL(" MAC address %pM does not exist with host"),
1552 macAddr);
1553 return;
1554 }
1555
Sunil Duttc69bccb2014-05-26 21:30:20 +05301556 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Dino Mycled3d50022014-07-07 12:58:25 +05301557 "%s: Interface: %s LLStats indType: %d", __func__,
1558 pAdapter->dev->name, indType);
1559
Sunil Duttc69bccb2014-05-26 21:30:20 +05301560 switch (indType)
1561 {
1562 case SIR_HAL_LL_STATS_RESULTS_RSP:
1563 {
Sunil Duttc69bccb2014-05-26 21:30:20 +05301564 hddLog(VOS_TRACE_LEVEL_INFO,
1565 FL("RESPONSE SIR_HAL_LL_STATS_RESULTS_RSP") );
1566 hddLog(VOS_TRACE_LEVEL_INFO,
1567 "LL_STATS RESULTS RESPONSE paramID = 0x%x",
1568 linkLayerStatsResults->paramId);
1569 hddLog(VOS_TRACE_LEVEL_INFO,
Dino Mycled3d50022014-07-07 12:58:25 +05301570 "LL_STATS RESULTS RESPONSE ifaceId = %u MAC: %pM",
1571 linkLayerStatsResults->ifaceId, macAddr);
Sunil Duttc69bccb2014-05-26 21:30:20 +05301572 hddLog(VOS_TRACE_LEVEL_INFO,
1573 "LL_STATS RESULTS RESPONSE respId = %u",
1574 linkLayerStatsResults->respId);
1575 hddLog(VOS_TRACE_LEVEL_INFO,
1576 "LL_STATS RESULTS RESPONSE moreResultToFollow = %u",
1577 linkLayerStatsResults->moreResultToFollow);
1578 hddLog(VOS_TRACE_LEVEL_INFO,
1579 "LL_STATS RESULTS RESPONSE result = %p",
1580 linkLayerStatsResults->result);
1581 if ( linkLayerStatsResults->paramId & WMI_LINK_STATS_RADIO )
1582 {
1583 hdd_link_layer_process_radio_stats(pAdapter,
1584 (v_VOID_t *)linkLayerStatsResults->result);
1585 }
1586 else if ( linkLayerStatsResults->paramId & WMI_LINK_STATS_IFACE )
1587 {
1588 hdd_link_layer_process_iface_stats(pAdapter,
1589 (v_VOID_t *)linkLayerStatsResults->result);
1590 }
1591 else if ( linkLayerStatsResults->paramId &
1592 WMI_LINK_STATS_ALL_PEER )
1593 {
1594 hdd_link_layer_process_peer_stats(pAdapter,
1595 (v_VOID_t *)linkLayerStatsResults->result);
1596 } /* WMI_LINK_STATS_ALL_PEER */
1597 else
1598 {
1599 hddLog(VOS_TRACE_LEVEL_ERROR,
1600 FL("INVALID LL_STATS_NOTIFY RESPONSE ***********"));
1601 }
1602
1603 break;
1604 }
1605 default:
1606 hddLog(VOS_TRACE_LEVEL_ERROR, "invalid event type %d", indType);
1607 break;
1608 }
1609 return;
1610}
1611
1612const struct
1613nla_policy
1614qca_wlan_vendor_ll_set_policy[QCA_WLAN_VENDOR_ATTR_LL_STATS_SET_MAX +1] =
1615{
1616 [QCA_WLAN_VENDOR_ATTR_LL_STATS_SET_CONFIG_MPDU_SIZE_THRESHOLD] =
1617 { .type = NLA_U32 },
1618 [QCA_WLAN_VENDOR_ATTR_LL_STATS_SET_CONFIG_AGGRESSIVE_STATS_GATHERING] =
1619 { .type = NLA_U32 },
1620};
1621
1622static int wlan_hdd_cfg80211_ll_stats_set(struct wiphy *wiphy,
1623 struct wireless_dev *wdev,
1624 void *data,
1625 int data_len)
1626{
1627 int status;
1628 struct nlattr *tb_vendor[QCA_WLAN_VENDOR_ATTR_LL_STATS_SET_MAX + 1];
Dino Mycledf0a5d92014-07-04 09:41:55 +05301629 tSirLLStatsSetReq linkLayerStatsSetReq;
Sunil Duttc69bccb2014-05-26 21:30:20 +05301630 struct net_device *dev = wdev->netdev;
1631 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
1632 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
1633
1634 status = wlan_hdd_validate_context(pHddCtx);
1635 if (0 != status)
1636 {
1637 hddLog(VOS_TRACE_LEVEL_ERROR,
1638 FL("HDD context is not valid"));
1639 return -EINVAL;
1640 }
1641
1642 if (NULL == pAdapter)
1643 {
1644 hddLog(VOS_TRACE_LEVEL_ERROR,
1645 FL("HDD adapter is Null"));
1646 return -ENODEV;
1647 }
Dino Mycledf0a5d92014-07-04 09:41:55 +05301648 /* check the LLStats Capability */
1649 if ( (TRUE != pHddCtx->cfg_ini->fEnableLLStats) ||
1650 (TRUE != sme_IsFeatureSupportedByFW(LINK_LAYER_STATS_MEAS)))
1651 {
1652 hddLog(VOS_TRACE_LEVEL_ERROR,
1653 FL("Link Layer Statistics not supported by Firmware"));
1654 return -EINVAL;
1655 }
Sunil Duttc69bccb2014-05-26 21:30:20 +05301656
1657 if (nla_parse(tb_vendor, QCA_WLAN_VENDOR_ATTR_LL_STATS_SET_MAX,
1658 (struct nlattr *)data,
1659 data_len, qca_wlan_vendor_ll_set_policy))
1660 {
1661 hddLog(VOS_TRACE_LEVEL_ERROR, FL() );
1662 return -EINVAL;
1663 }
1664 if (!tb_vendor
1665 [QCA_WLAN_VENDOR_ATTR_LL_STATS_SET_CONFIG_MPDU_SIZE_THRESHOLD])
1666 {
1667 hddLog(VOS_TRACE_LEVEL_ERROR, FL("MPDU size Not present"));
1668 return -EINVAL;
1669 }
1670 if (!tb_vendor[
1671 QCA_WLAN_VENDOR_ATTR_LL_STATS_SET_CONFIG_AGGRESSIVE_STATS_GATHERING])
1672 {
1673 hddLog(VOS_TRACE_LEVEL_ERROR, FL(" Stats Gathering Not Present"));
1674 return -EINVAL;
1675 }
Sunil Duttc69bccb2014-05-26 21:30:20 +05301676 // Shall take the request Id if the Upper layers pass. 1 For now.
Dino Mycledf0a5d92014-07-04 09:41:55 +05301677 linkLayerStatsSetReq.reqId = 1;
Sunil Duttc69bccb2014-05-26 21:30:20 +05301678
Dino Mycledf0a5d92014-07-04 09:41:55 +05301679 linkLayerStatsSetReq.mpduSizeThreshold =
Sunil Duttc69bccb2014-05-26 21:30:20 +05301680 nla_get_u32(
1681 tb_vendor[QCA_WLAN_VENDOR_ATTR_LL_STATS_SET_CONFIG_MPDU_SIZE_THRESHOLD]);
1682
Dino Mycledf0a5d92014-07-04 09:41:55 +05301683 linkLayerStatsSetReq.aggressiveStatisticsGathering =
Sunil Duttc69bccb2014-05-26 21:30:20 +05301684 nla_get_u32(
1685 tb_vendor[QCA_WLAN_VENDOR_ATTR_LL_STATS_SET_CONFIG_AGGRESSIVE_STATS_GATHERING]);
1686
Dino Mycled3d50022014-07-07 12:58:25 +05301687 vos_mem_copy(linkLayerStatsSetReq.macAddr,
1688 pAdapter->macAddressCurrent.bytes, sizeof(v_MACADDR_t));
Sunil Duttc69bccb2014-05-26 21:30:20 +05301689
1690
1691 hddLog(VOS_TRACE_LEVEL_INFO,
Dino Mycled3d50022014-07-07 12:58:25 +05301692 "LL_STATS_SET reqId = %d", linkLayerStatsSetReq.reqId);
Sunil Duttc69bccb2014-05-26 21:30:20 +05301693 hddLog(VOS_TRACE_LEVEL_INFO,
Dino Mycled3d50022014-07-07 12:58:25 +05301694 "LL_STATS_SET MAC = %pM", linkLayerStatsSetReq.macAddr);
Sunil Duttc69bccb2014-05-26 21:30:20 +05301695 hddLog(VOS_TRACE_LEVEL_INFO,
1696 "LL_STATS_SET mpduSizeThreshold = %d",
Dino Mycledf0a5d92014-07-04 09:41:55 +05301697 linkLayerStatsSetReq.mpduSizeThreshold);
Sunil Duttc69bccb2014-05-26 21:30:20 +05301698 hddLog(VOS_TRACE_LEVEL_INFO,
1699 "LL_STATS_SET aggressive Statistics Gathering = %d",
Dino Mycledf0a5d92014-07-04 09:41:55 +05301700 linkLayerStatsSetReq.aggressiveStatisticsGathering);
Sunil Duttc69bccb2014-05-26 21:30:20 +05301701
1702 if (eHAL_STATUS_SUCCESS != sme_SetLinkLayerStatsIndCB(
1703 pHddCtx->hHal,
Dino Mycled3d50022014-07-07 12:58:25 +05301704 hdd_link_layer_stats_ind_callback))
Sunil Duttc69bccb2014-05-26 21:30:20 +05301705 {
1706 hddLog(VOS_TRACE_LEVEL_ERROR, "%s:"
1707 "sme_SetLinkLayerStatsIndCB Failed", __func__);
Sunil Duttc69bccb2014-05-26 21:30:20 +05301708 return -EINVAL;
1709
1710 }
1711 if (eHAL_STATUS_SUCCESS != sme_LLStatsSetReq( pHddCtx->hHal,
Dino Mycledf0a5d92014-07-04 09:41:55 +05301712 &linkLayerStatsSetReq))
Sunil Duttc69bccb2014-05-26 21:30:20 +05301713 {
1714 hddLog(VOS_TRACE_LEVEL_ERROR, "%s:"
1715 "sme_LLStatsSetReq Failed", __func__);
Sunil Duttc69bccb2014-05-26 21:30:20 +05301716 return -EINVAL;
1717 }
1718
1719 pAdapter->isLinkLayerStatsSet = 1;
1720
1721 return 0;
1722}
1723
1724const struct
1725nla_policy
1726qca_wlan_vendor_ll_get_policy[QCA_WLAN_VENDOR_ATTR_LL_STATS_GET_MAX +1] =
1727{
1728 /* Unsigned 32bit value provided by the caller issuing the GET stats
1729 * command. When reporting
1730 * the stats results, the driver uses the same value to indicate
1731 * which GET request the results
1732 * correspond to.
1733 */
1734 [QCA_WLAN_VENDOR_ATTR_LL_STATS_GET_CONFIG_REQ_ID] = { .type = NLA_U32 },
1735
1736 /* Unsigned 32bit value . bit mask to identify what statistics are
1737 requested for retrieval */
1738 [QCA_WLAN_VENDOR_ATTR_LL_STATS_GET_CONFIG_REQ_MASK] = { .type = NLA_U32 },
1739};
1740
1741static int wlan_hdd_cfg80211_ll_stats_get(struct wiphy *wiphy,
1742 struct wireless_dev *wdev,
1743 void *data,
1744 int data_len)
1745{
1746 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
1747 struct nlattr *tb_vendor[QCA_WLAN_VENDOR_ATTR_LL_STATS_GET_MAX + 1];
Dino Mycledf0a5d92014-07-04 09:41:55 +05301748 tSirLLStatsGetReq linkLayerStatsGetReq;
Sunil Duttc69bccb2014-05-26 21:30:20 +05301749 struct net_device *dev = wdev->netdev;
1750 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
1751 int status;
1752
1753 status = wlan_hdd_validate_context(pHddCtx);
1754 if (0 != status)
1755 {
1756 hddLog(VOS_TRACE_LEVEL_ERROR,
1757 FL("HDD context is not valid"));
1758 return -EINVAL ;
1759 }
1760
1761 if (NULL == pAdapter)
1762 {
1763 hddLog(VOS_TRACE_LEVEL_FATAL,
1764 "%s: HDD adapter is Null", __func__);
1765 return -ENODEV;
1766 }
Dino Mycledf0a5d92014-07-04 09:41:55 +05301767 /* check the LLStats Capability */
1768 if ( (TRUE != pHddCtx->cfg_ini->fEnableLLStats) ||
1769 (TRUE != sme_IsFeatureSupportedByFW(LINK_LAYER_STATS_MEAS)))
1770 {
1771 hddLog(VOS_TRACE_LEVEL_ERROR,
1772 FL("Link Layer Statistics not supported by Firmware"));
1773 return -EINVAL;
1774 }
1775
Sunil Duttc69bccb2014-05-26 21:30:20 +05301776
1777 if (!pAdapter->isLinkLayerStatsSet)
1778 {
1779 hddLog(VOS_TRACE_LEVEL_FATAL,
1780 "%s: isLinkLayerStatsSet : %d",
1781 __func__, pAdapter->isLinkLayerStatsSet);
1782 return -EINVAL;
1783 }
1784
1785 if (nla_parse(tb_vendor, QCA_WLAN_VENDOR_ATTR_LL_STATS_GET_MAX,
1786 (struct nlattr *)data,
1787 data_len, qca_wlan_vendor_ll_get_policy))
1788 {
1789 hddLog(VOS_TRACE_LEVEL_ERROR, FL() );
1790 return -EINVAL;
1791 }
1792
1793 if (!tb_vendor
1794 [QCA_WLAN_VENDOR_ATTR_LL_STATS_GET_CONFIG_REQ_ID])
1795 {
1796 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Request Id Not present"));
1797 return -EINVAL;
1798 }
1799
1800 if (!tb_vendor
1801 [QCA_WLAN_VENDOR_ATTR_LL_STATS_GET_CONFIG_REQ_MASK])
1802 {
1803 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Req Mask Not present"));
1804 return -EINVAL;
1805 }
1806
Sunil Duttc69bccb2014-05-26 21:30:20 +05301807
Dino Mycledf0a5d92014-07-04 09:41:55 +05301808 linkLayerStatsGetReq.reqId =
Sunil Duttc69bccb2014-05-26 21:30:20 +05301809 nla_get_u32( tb_vendor[
1810 QCA_WLAN_VENDOR_ATTR_LL_STATS_GET_CONFIG_REQ_ID]);
Dino Mycledf0a5d92014-07-04 09:41:55 +05301811 linkLayerStatsGetReq.paramIdMask =
Sunil Duttc69bccb2014-05-26 21:30:20 +05301812 nla_get_u32( tb_vendor[
1813 QCA_WLAN_VENDOR_ATTR_LL_STATS_GET_CONFIG_REQ_MASK]);
1814
Dino Mycled3d50022014-07-07 12:58:25 +05301815 vos_mem_copy(linkLayerStatsGetReq.macAddr,
1816 pAdapter->macAddressCurrent.bytes, sizeof(v_MACADDR_t));
Sunil Duttc69bccb2014-05-26 21:30:20 +05301817
1818 hddLog(VOS_TRACE_LEVEL_INFO,
Dino Mycledf0a5d92014-07-04 09:41:55 +05301819 "LL_STATS_GET reqId = %d", linkLayerStatsGetReq.reqId);
Sunil Duttc69bccb2014-05-26 21:30:20 +05301820 hddLog(VOS_TRACE_LEVEL_INFO,
Dino Mycled3d50022014-07-07 12:58:25 +05301821 "LL_STATS_GET MAC = %pM", linkLayerStatsGetReq.macAddr);
Sunil Duttc69bccb2014-05-26 21:30:20 +05301822 hddLog(VOS_TRACE_LEVEL_INFO,
1823 "LL_STATS_GET paramIdMask = %d",
Dino Mycledf0a5d92014-07-04 09:41:55 +05301824 linkLayerStatsGetReq.paramIdMask);
Sunil Duttc69bccb2014-05-26 21:30:20 +05301825
1826 if (eHAL_STATUS_SUCCESS != sme_LLStatsGetReq( pHddCtx->hHal,
Dino Mycledf0a5d92014-07-04 09:41:55 +05301827 &linkLayerStatsGetReq))
Sunil Duttc69bccb2014-05-26 21:30:20 +05301828 {
1829 hddLog(VOS_TRACE_LEVEL_ERROR, "%s:"
1830 "sme_LLStatsGetReq Failed", __func__);
Sunil Duttc69bccb2014-05-26 21:30:20 +05301831 return -EINVAL;
1832 }
1833 return 0;
1834}
1835
1836const struct
1837nla_policy
1838qca_wlan_vendor_ll_clr_policy[QCA_WLAN_VENDOR_ATTR_LL_STATS_CLR_MAX +1] =
1839{
1840 [QCA_WLAN_VENDOR_ATTR_LL_STATS_CLR_CONFIG_REQ_MASK] = {.type = NLA_U32 },
1841 [QCA_WLAN_VENDOR_ATTR_LL_STATS_CLR_CONFIG_STOP_REQ] = {.type = NLA_U8 },
1842 [QCA_WLAN_VENDOR_ATTR_LL_STATS_CLR_CONFIG_RSP_MASK] = {.type = NLA_U32 },
1843 [QCA_WLAN_VENDOR_ATTR_LL_STATS_CLR_CONFIG_STOP_RSP] = {.type = NLA_U8 },
1844};
1845
1846static int wlan_hdd_cfg80211_ll_stats_clear(struct wiphy *wiphy,
1847 struct wireless_dev *wdev,
1848 void *data,
1849 int data_len)
1850{
1851 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
1852 struct nlattr *tb_vendor[QCA_WLAN_VENDOR_ATTR_LL_STATS_CLR_MAX + 1];
Dino Mycledf0a5d92014-07-04 09:41:55 +05301853 tSirLLStatsClearReq linkLayerStatsClearReq;
Sunil Duttc69bccb2014-05-26 21:30:20 +05301854 struct net_device *dev = wdev->netdev;
1855 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
1856 u32 statsClearReqMask;
1857 u8 stopReq;
1858 int status;
1859
1860 status = wlan_hdd_validate_context(pHddCtx);
1861 if (0 != status)
1862 {
1863 hddLog(VOS_TRACE_LEVEL_ERROR,
1864 FL("HDD context is not valid"));
1865 return -EINVAL;
1866 }
1867
1868 if (NULL == pAdapter)
1869 {
1870 hddLog(VOS_TRACE_LEVEL_FATAL,
1871 "%s: HDD adapter is Null", __func__);
1872 return -ENODEV;
1873 }
Dino Mycledf0a5d92014-07-04 09:41:55 +05301874 /* check the LLStats Capability */
1875 if ( (TRUE != pHddCtx->cfg_ini->fEnableLLStats) ||
1876 (TRUE != sme_IsFeatureSupportedByFW(LINK_LAYER_STATS_MEAS)))
1877 {
1878 hddLog(VOS_TRACE_LEVEL_ERROR,
1879 FL("Enable LLStats Capability"));
1880 return -EINVAL;
1881 }
Sunil Duttc69bccb2014-05-26 21:30:20 +05301882
1883 if (!pAdapter->isLinkLayerStatsSet)
1884 {
1885 hddLog(VOS_TRACE_LEVEL_FATAL,
1886 "%s: isLinkLayerStatsSet : %d",
1887 __func__, pAdapter->isLinkLayerStatsSet);
1888 return -EINVAL;
1889 }
1890
1891 if (nla_parse(tb_vendor, QCA_WLAN_VENDOR_ATTR_LL_STATS_CLR_MAX,
1892 (struct nlattr *)data,
1893 data_len, qca_wlan_vendor_ll_clr_policy))
1894 {
1895 hddLog(VOS_TRACE_LEVEL_ERROR, FL() );
1896 return -EINVAL;
1897 }
1898
1899 if (!tb_vendor[QCA_WLAN_VENDOR_ATTR_LL_STATS_CLR_CONFIG_REQ_MASK] ||
1900
1901 !tb_vendor[QCA_WLAN_VENDOR_ATTR_LL_STATS_CLR_CONFIG_STOP_REQ])
1902 {
1903 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Error in LL_STATS CLR CONFIG PARA") );
1904 return -EINVAL;
1905
1906 }
1907
Sunil Duttc69bccb2014-05-26 21:30:20 +05301908
Dino Mycledf0a5d92014-07-04 09:41:55 +05301909 statsClearReqMask = linkLayerStatsClearReq.statsClearReqMask =
Sunil Duttc69bccb2014-05-26 21:30:20 +05301910 nla_get_u32(
1911 tb_vendor[QCA_WLAN_VENDOR_ATTR_LL_STATS_CLR_CONFIG_REQ_MASK]);
1912
Dino Mycledf0a5d92014-07-04 09:41:55 +05301913 stopReq = linkLayerStatsClearReq.stopReq =
Sunil Duttc69bccb2014-05-26 21:30:20 +05301914 nla_get_u8(
1915 tb_vendor[QCA_WLAN_VENDOR_ATTR_LL_STATS_CLR_CONFIG_STOP_REQ]);
1916
1917 // Shall take the request Id if the Upper layers pass. 1 For now.
Dino Mycledf0a5d92014-07-04 09:41:55 +05301918 linkLayerStatsClearReq.reqId = 1;
Sunil Duttc69bccb2014-05-26 21:30:20 +05301919
Dino Mycled3d50022014-07-07 12:58:25 +05301920 vos_mem_copy(linkLayerStatsClearReq.macAddr,
1921 pAdapter->macAddressCurrent.bytes, sizeof(v_MACADDR_t));
Sunil Duttc69bccb2014-05-26 21:30:20 +05301922
1923 hddLog(VOS_TRACE_LEVEL_INFO,
Dino Mycledf0a5d92014-07-04 09:41:55 +05301924 "LL_STATS_CLEAR reqId = %d", linkLayerStatsClearReq.reqId);
Sunil Duttc69bccb2014-05-26 21:30:20 +05301925 hddLog(VOS_TRACE_LEVEL_INFO,
Dino Mycled3d50022014-07-07 12:58:25 +05301926 "LL_STATS_CLEAR MAC = %pM", linkLayerStatsClearReq.macAddr);
Sunil Duttc69bccb2014-05-26 21:30:20 +05301927 hddLog(VOS_TRACE_LEVEL_INFO,
1928 "LL_STATS_CLEAR statsClearReqMask = 0x%X",
Dino Mycledf0a5d92014-07-04 09:41:55 +05301929 linkLayerStatsClearReq.statsClearReqMask);
Sunil Duttc69bccb2014-05-26 21:30:20 +05301930 hddLog(VOS_TRACE_LEVEL_INFO,
1931 "LL_STATS_CLEAR stopReq = %d",
Dino Mycledf0a5d92014-07-04 09:41:55 +05301932 linkLayerStatsClearReq.stopReq);
Sunil Duttc69bccb2014-05-26 21:30:20 +05301933
1934 if (eHAL_STATUS_SUCCESS == sme_LLStatsClearReq(pHddCtx->hHal,
Dino Mycledf0a5d92014-07-04 09:41:55 +05301935 &linkLayerStatsClearReq))
Sunil Duttc69bccb2014-05-26 21:30:20 +05301936 {
1937 struct sk_buff *temp_skbuff;
1938 temp_skbuff = cfg80211_vendor_cmd_alloc_reply_skb(wiphy,
1939 2 * sizeof(u32) +
1940 NLMSG_HDRLEN);
1941
1942 if (temp_skbuff != NULL)
1943 {
1944
1945 if (nla_put_u32(temp_skbuff,
1946 QCA_WLAN_VENDOR_ATTR_LL_STATS_CLR_CONFIG_RSP_MASK,
1947 statsClearReqMask) ||
1948 nla_put_u32(temp_skbuff,
1949 QCA_WLAN_VENDOR_ATTR_LL_STATS_CLR_CONFIG_STOP_RSP,
1950 stopReq))
1951 {
1952 hddLog(VOS_TRACE_LEVEL_ERROR, FL("LL_STATS_CLR put fail"));
1953 kfree_skb(temp_skbuff);
1954 return -EINVAL;
1955 }
1956 /* If the ask is to stop the stats collection as part of clear
1957 * (stopReq = 1) , ensure that no further requests of get
1958 * go to the firmware by having isLinkLayerStatsSet set to 0.
1959 * However it the stopReq as part of the clear request is 0 ,
Dino Mycledf0a5d92014-07-04 09:41:55 +05301960 * the request to get the statistics are honoured as in this
Sunil Duttc69bccb2014-05-26 21:30:20 +05301961 * case the firmware is just asked to clear the statistics.
1962 */
Dino Mycledf0a5d92014-07-04 09:41:55 +05301963 if (linkLayerStatsClearReq.stopReq == 1)
Sunil Duttc69bccb2014-05-26 21:30:20 +05301964 pAdapter->isLinkLayerStatsSet = 0;
1965 return cfg80211_vendor_cmd_reply(temp_skbuff);
1966 }
1967 return -ENOMEM;
1968 }
Sunil Duttc69bccb2014-05-26 21:30:20 +05301969 return -EINVAL;
1970}
1971#endif /* WLAN_FEATURE_LINK_LAYER_STATS */
1972
Dino Mycle6fb96c12014-06-10 11:52:40 +05301973#ifdef WLAN_FEATURE_EXTSCAN
1974static const struct nla_policy
1975wlan_hdd_extscan_config_policy
1976 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX + 1] =
1977{
1978 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_REQUEST_ID] =
1979 { .type = NLA_U32 },
1980 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_GET_VALID_CHANNELS_CONFIG_PARAM_WIFI_BAND] =
1981 { .type = NLA_U32 },
1982 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_CHANNEL_SPEC_CHANNEL] = { .type = NLA_U32 },
1983 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_CHANNEL_SPEC_DWELL_TIME] =
1984 { .type = NLA_U32 },
1985 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_CHANNEL_SPEC_PASSIVE] = { .type = NLA_U8 },
1986 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_CHANNEL_SPEC_CLASS] = { .type = NLA_U8 },
1987
1988 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_INDEX] = { .type = NLA_U8 },
1989 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_BAND] = { .type = NLA_U8 },
1990 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_PERIOD] = { .type = NLA_U32 },
1991 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_REPORT_EVENTS] =
1992 { .type = NLA_U8 },
1993 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_NUM_CHANNEL_SPECS] =
1994 { .type = NLA_U32 },
1995 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_SCAN_CMD_PARAMS_BASE_PERIOD] =
1996 { .type = NLA_U32 },
1997 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_SCAN_CMD_PARAMS_MAX_AP_PER_SCAN] =
1998 { .type = NLA_U32 },
1999 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_SCAN_CMD_PARAMS_REPORT_THRESHOLD] =
2000 { .type = NLA_U8 },
2001 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_SCAN_CMD_PARAMS_NUM_BUCKETS] =
2002 { .type = NLA_U8 },
2003 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_GET_CACHED_SCAN_RESULTS_CONFIG_PARAM_FLUSH] =
2004 { .type = NLA_U8 },
2005
2006 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_GET_CACHED_SCAN_RESULTS_CONFIG_PARAM_MAX] =
2007 { .type = NLA_U32 },
2008 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_AP_THRESHOLD_PARAM_BSSID] =
2009 { .type = NLA_UNSPEC },
2010 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_AP_THRESHOLD_PARAM_RSSI_LOW] =
2011 { .type = NLA_S32 },
2012 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_AP_THRESHOLD_PARAM_RSSI_HIGH] =
2013 { .type = NLA_S32 },
2014 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_AP_THRESHOLD_PARAM_CHANNEL] =
2015 { .type = NLA_U32 },
2016 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_BSSID_HOTLIST_PARAMS_NUM_AP] =
2017 { .type = NLA_U32 },
2018 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_SIGNIFICANT_CHANGE_PARAMS_RSSI_SAMPLE_SIZE] =
2019 { .type = NLA_U32 },
2020 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_SIGNIFICANT_CHANGE_PARAMS_LOST_AP_SAMPLE_SIZE]
2021 = { .type = NLA_U32 },
2022 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_SIGNIFICANT_CHANGE_PARAMS_MIN_BREACHING] =
2023 { .type = NLA_U32 },
2024 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_SIGNIFICANT_CHANGE_PARAMS_NUM_AP] = { .type =
2025 NLA_U32 },
2026};
2027
2028static void wlan_hdd_cfg80211_extscan_get_capabilities_ind(void *ctx, void *pMsg)
2029{
2030 hdd_context_t *pHddCtx = (hdd_context_t *)ctx;
2031 struct sk_buff *skb = NULL;
2032 tpSirEXTScanCapabilitiesEvent pData =
2033 (tpSirEXTScanCapabilitiesEvent) pMsg;
2034
2035 if (wlan_hdd_validate_context(pHddCtx) || !pData) {
2036 hddLog(VOS_TRACE_LEVEL_ERROR, FL("HDD context is not valid "
2037 "or pData(%p) is null"), pData);
2038 return;
2039 }
2040
2041 skb = cfg80211_vendor_event_alloc(pHddCtx->wiphy,
2042 EXTSCAN_EVENT_BUF_SIZE + NLMSG_HDRLEN,
2043 QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_GET_CAPABILITIES_INDEX,
2044 GFP_KERNEL);
2045
2046 if (!skb) {
2047 hddLog(VOS_TRACE_LEVEL_ERROR,
2048 FL("cfg80211_vendor_event_alloc failed"));
2049 return;
2050 }
2051
2052 hddLog(VOS_TRACE_LEVEL_INFO, "Req Id (%u)", pData->requestId);
2053 hddLog(VOS_TRACE_LEVEL_INFO, "Scan cache size (%u)", pData->scanCacheSize);
2054 hddLog(VOS_TRACE_LEVEL_INFO, "Scan buckets (%u)", pData->scanBuckets);
2055 hddLog(VOS_TRACE_LEVEL_INFO, "Max AP per scan (%u)", pData->maxApPerScan);
2056 hddLog(VOS_TRACE_LEVEL_INFO, "maxRssiSampleSize (%u)",
2057 pData->maxRssiSampleSize);
2058 hddLog(VOS_TRACE_LEVEL_INFO, "maxScanReportingThreshold (%u)",
2059 pData->maxScanReportingThreshold);
2060 hddLog(VOS_TRACE_LEVEL_INFO, "maxHotlistAPs (%u)", pData->maxHotlistAPs);
2061 hddLog(VOS_TRACE_LEVEL_INFO, "maxSignificantWifiChangeAPs (%u)",
2062 pData->maxSignificantWifiChangeAPs);
2063 hddLog(VOS_TRACE_LEVEL_INFO, "maxBsidHistoryEntries (%u)",
2064 pData->maxBsidHistoryEntries);
2065
2066 if (nla_put_u32(skb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_REQUEST_ID,
2067 pData->requestId) ||
2068 nla_put_u32(skb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_STATUS, pData->status) ||
2069 nla_put_u32(skb,
2070 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_CAPABILITIES_MAX_SCAN_CACHE_SIZE,
2071 pData->scanCacheSize) ||
2072 nla_put_u32(skb,
2073 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_CAPABILITIES_MAX_SCAN_BUCKETS,
2074 pData->scanBuckets) ||
2075 nla_put_u32(skb,
2076 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_CAPABILITIES_MAX_AP_CACHE_PER_SCAN,
2077 pData->maxApPerScan) ||
2078 nla_put_u32(skb,
2079 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_CAPABILITIES_MAX_RSSI_SAMPLE_SIZE,
2080 pData->maxRssiSampleSize) ||
2081 nla_put_u32(skb,
2082 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_CAPABILITIES_MAX_SCAN_REPORTING_THRESHOLD,
2083 pData->maxScanReportingThreshold) ||
2084 nla_put_u32(skb,
2085 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_CAPABILITIES_MAX_HOTLIST_APS,
2086 pData->maxHotlistAPs) ||
2087 nla_put_u32(skb,
2088 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_CAPABILITIES_MAX_SIGNIFICANT_WIFI_CHANGE_APS,
2089 pData->maxSignificantWifiChangeAPs) ||
2090 nla_put_u32(skb,
2091 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_CAPABILITIES_MAX_BSSID_HISTORY_ENTRIES,
2092 pData->maxBsidHistoryEntries)) {
2093 hddLog(VOS_TRACE_LEVEL_ERROR, FL("nla put fail"));
2094 goto nla_put_failure;
2095 }
2096
2097 cfg80211_vendor_event(skb, GFP_KERNEL);
2098 return;
2099
2100nla_put_failure:
2101 kfree_skb(skb);
2102 return;
2103}
2104
2105
2106static void wlan_hdd_cfg80211_extscan_start_rsp(void *ctx, void *pMsg)
2107{
2108 tpSirEXTScanStartRspParams pData = (tpSirEXTScanStartRspParams) pMsg;
2109 hdd_context_t *pHddCtx = (hdd_context_t *)ctx;
2110 struct sk_buff *skb = NULL;
2111 tpAniSirGlobal pMac = PMAC_STRUCT( pHddCtx->hHal );
2112
2113
2114 if (wlan_hdd_validate_context(pHddCtx) || !pData) {
2115 hddLog(VOS_TRACE_LEVEL_ERROR, FL("HDD context is not valid "
2116 "or pData(%p) is null"), pData);
2117 return;
2118 }
2119
2120 skb = cfg80211_vendor_event_alloc(pHddCtx->wiphy,
2121 EXTSCAN_EVENT_BUF_SIZE + NLMSG_HDRLEN,
2122 QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_START_INDEX,
2123 GFP_KERNEL);
2124
2125 if (!skb) {
2126 hddLog(VOS_TRACE_LEVEL_ERROR,
2127 FL("cfg80211_vendor_event_alloc failed"));
2128 return;
2129 }
2130 hddLog(VOS_TRACE_LEVEL_INFO, FL("Entering "));
2131 hddLog(VOS_TRACE_LEVEL_INFO, "Req Id (%u)", pData->requestId);
2132 hddLog(VOS_TRACE_LEVEL_INFO, "Status (%u)", pData->status);
2133
2134 if (nla_put_u32(skb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_REQUEST_ID,
2135 pData->requestId) ||
2136 nla_put_u32(skb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_STATUS, pData->status)) {
2137 hddLog(VOS_TRACE_LEVEL_ERROR, FL("nla put fail"));
2138 goto nla_put_failure;
2139 }
2140
2141 /*
2142 * Store the Request ID for comparing with the requestID obtained
2143 * in other requests.HDD shall return a failure is the extscan_stop
2144 * request is issued with a different requestId as that of the
2145 * extscan_start request. Also, This requestId shall be used while
2146 * indicating the full scan results to the upper layers.
2147 * The requestId is stored with the assumption that the firmware
2148 * shall return the ext scan start request's requestId in ext scan
2149 * start response.
2150 */
2151 if (pData->status == 0)
2152 pMac->sme.extScanStartReqId = pData->requestId;
2153
2154
2155 cfg80211_vendor_event(skb, GFP_KERNEL);
2156 return;
2157
2158nla_put_failure:
2159 kfree_skb(skb);
2160 return;
2161}
2162
2163
2164static void wlan_hdd_cfg80211_extscan_stop_rsp(void *ctx, void *pMsg)
2165{
2166 tpSirEXTScanStopRspParams pData = (tpSirEXTScanStopRspParams) pMsg;
2167 hdd_context_t *pHddCtx = (hdd_context_t *)ctx;
2168 struct sk_buff *skb = NULL;
2169
2170 if (wlan_hdd_validate_context(pHddCtx) || !pData) {
2171 hddLog(VOS_TRACE_LEVEL_ERROR, FL("HDD context is not valid "
2172 "or pData(%p) is null"), pData);
2173 return;
2174 }
2175
2176 skb = cfg80211_vendor_event_alloc(pHddCtx->wiphy,
2177 EXTSCAN_EVENT_BUF_SIZE + NLMSG_HDRLEN,
2178 QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_STOP_INDEX,
2179 GFP_KERNEL);
2180
2181 if (!skb) {
2182 hddLog(VOS_TRACE_LEVEL_ERROR,
2183 FL("cfg80211_vendor_event_alloc failed"));
2184 return;
2185 }
2186 hddLog(VOS_TRACE_LEVEL_INFO, FL("Entering "));
2187 hddLog(VOS_TRACE_LEVEL_INFO, "Req Id (%u)", pData->requestId);
2188
2189 if (nla_put_u32(skb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_REQUEST_ID,
2190 pData->requestId) ||
2191 nla_put_u32(skb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_STATUS, pData->status)) {
2192 hddLog(VOS_TRACE_LEVEL_ERROR, FL("nla put fail"));
2193 goto nla_put_failure;
2194 }
2195
2196 cfg80211_vendor_event(skb, GFP_KERNEL);
2197 return;
2198
2199nla_put_failure:
2200 kfree_skb(skb);
2201 return;
2202}
2203
2204
2205static void wlan_hdd_cfg80211_extscan_set_bss_hotlist_rsp(void *ctx,
2206 void *pMsg)
2207{
2208 hdd_context_t *pHddCtx = (hdd_context_t *)ctx;
2209 struct sk_buff *skb = NULL;
2210 tpSirEXTScanSetBssidHotListRspParams pData =
2211 (tpSirEXTScanSetBssidHotListRspParams) pMsg;
2212
2213 if (wlan_hdd_validate_context(pHddCtx) || !pData) {
2214 hddLog(VOS_TRACE_LEVEL_ERROR, FL("HDD context is not valid "
2215 "or pData(%p) is null"), pData);
2216 return;
2217 }
2218 skb = cfg80211_vendor_event_alloc(pHddCtx->wiphy,
2219 EXTSCAN_EVENT_BUF_SIZE + NLMSG_HDRLEN,
2220 QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_SET_BSSID_HOTLIST_INDEX,
2221 GFP_KERNEL);
2222
2223 if (!skb) {
2224 hddLog(VOS_TRACE_LEVEL_ERROR,
2225 FL("cfg80211_vendor_event_alloc failed"));
2226 return;
2227 }
2228 hddLog(VOS_TRACE_LEVEL_INFO, FL("Entering "));
2229 hddLog(VOS_TRACE_LEVEL_INFO, "Req Id (%u)", pData->requestId);
2230 hddLog(VOS_TRACE_LEVEL_INFO, "Status (%u)", pData->status);
2231
2232 if (nla_put_u32(skb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_REQUEST_ID,
2233 pData->requestId) ||
2234 nla_put_u32(skb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_STATUS, pData->status)) {
2235 hddLog(VOS_TRACE_LEVEL_ERROR, FL("nla put fail"));
2236 goto nla_put_failure;
2237 }
2238
2239 cfg80211_vendor_event(skb, GFP_KERNEL);
2240 return;
2241
2242nla_put_failure:
2243 kfree_skb(skb);
2244 return;
2245}
2246
2247static void wlan_hdd_cfg80211_extscan_reset_bss_hotlist_rsp(void *ctx,
2248 void *pMsg)
2249{
2250 hdd_context_t *pHddCtx = (hdd_context_t *)ctx;
2251 struct sk_buff *skb = NULL;
2252 tpSirEXTScanResetBssidHotlistRspParams pData =
2253 (tpSirEXTScanResetBssidHotlistRspParams) pMsg;
2254
2255 if (wlan_hdd_validate_context(pHddCtx) || !pData) {
2256 hddLog(VOS_TRACE_LEVEL_ERROR, FL("HDD context is not valid "
2257 "or pData(%p) is null"), pData);
2258 return;
2259 }
2260
2261 skb = cfg80211_vendor_event_alloc(pHddCtx->wiphy,
2262 EXTSCAN_EVENT_BUF_SIZE + NLMSG_HDRLEN,
2263 QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_RESET_BSSID_HOTLIST_INDEX,
2264 GFP_KERNEL);
2265
2266 if (!skb) {
2267 hddLog(VOS_TRACE_LEVEL_ERROR,
2268 FL("cfg80211_vendor_event_alloc failed"));
2269 return;
2270 }
2271 hddLog(VOS_TRACE_LEVEL_INFO, FL("Entering "));
2272 hddLog(VOS_TRACE_LEVEL_INFO, "Req Id (%u)", pData->requestId);
2273
2274 if (nla_put_u32(skb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_REQUEST_ID,
2275 pData->requestId) ||
2276 nla_put_u32(skb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_STATUS, pData->status)) {
2277 hddLog(VOS_TRACE_LEVEL_ERROR, FL("nla put fail"));
2278 goto nla_put_failure;
2279 }
2280
2281 cfg80211_vendor_event(skb, GFP_KERNEL);
2282 return;
2283
2284nla_put_failure:
2285 kfree_skb(skb);
2286 return;
2287}
2288
2289
2290static void wlan_hdd_cfg80211_extscan_set_signf_wifi_change_rsp(void *ctx,
2291 void *pMsg)
2292{
2293 hdd_context_t *pHddCtx = (hdd_context_t *)ctx;
2294 struct sk_buff *skb = NULL;
2295 tpSirEXTScanSetSignificantChangeRspParams pData =
2296 (tpSirEXTScanSetSignificantChangeRspParams) pMsg;
2297
2298 if (wlan_hdd_validate_context(pHddCtx) || !pData) {
2299 hddLog(VOS_TRACE_LEVEL_ERROR, FL("HDD context is not valid "
2300 "or pData(%p) is null"), pData);
2301 return;
2302 }
2303
2304 skb = cfg80211_vendor_event_alloc(pHddCtx->wiphy,
2305 EXTSCAN_EVENT_BUF_SIZE + NLMSG_HDRLEN,
2306 QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_SET_SIGNIFICANT_CHANGE_INDEX,
2307 GFP_KERNEL);
2308
2309 if (!skb) {
2310 hddLog(VOS_TRACE_LEVEL_ERROR,
2311 FL("cfg80211_vendor_event_alloc failed"));
2312 return;
2313 }
2314 hddLog(VOS_TRACE_LEVEL_INFO, FL("Entering "));
2315 hddLog(VOS_TRACE_LEVEL_INFO, "Req Id (%u)", pData->requestId);
2316 hddLog(VOS_TRACE_LEVEL_INFO, "Status (%u)", pData->status);
2317
2318 if (nla_put_u32(skb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_REQUEST_ID,
2319 pData->requestId) ||
2320 nla_put_u32(skb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_STATUS, pData->status)) {
2321 hddLog(VOS_TRACE_LEVEL_ERROR, FL("nla put fail"));
2322 goto nla_put_failure;
2323 }
2324
2325 cfg80211_vendor_event(skb, GFP_KERNEL);
2326 return;
2327
2328nla_put_failure:
2329 kfree_skb(skb);
2330 return;
2331}
2332
2333
2334static void wlan_hdd_cfg80211_extscan_reset_signf_wifi_change_rsp(void *ctx,
2335 void *pMsg)
2336{
2337 hdd_context_t *pHddCtx = (hdd_context_t *)ctx;
2338 struct sk_buff *skb = NULL;
2339 tpSirEXTScanResetSignificantChangeRspParams pData =
2340 (tpSirEXTScanResetSignificantChangeRspParams) pMsg;
2341
2342 if (wlan_hdd_validate_context(pHddCtx) || !pData) {
2343 hddLog(VOS_TRACE_LEVEL_ERROR, FL("HDD context is not valid "
2344 "or pData(%p) is null"), pData);
2345 return;
2346 }
2347
2348 skb = cfg80211_vendor_event_alloc(pHddCtx->wiphy,
2349 EXTSCAN_EVENT_BUF_SIZE + NLMSG_HDRLEN,
2350 QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_RESET_SIGNIFICANT_CHANGE_INDEX,
2351 GFP_KERNEL);
2352
2353 if (!skb) {
2354 hddLog(VOS_TRACE_LEVEL_ERROR,
2355 FL("cfg80211_vendor_event_alloc failed"));
2356 return;
2357 }
2358 hddLog(VOS_TRACE_LEVEL_INFO, FL("Entering "));
2359 hddLog(VOS_TRACE_LEVEL_INFO, "Req Id (%u)", pData->requestId);
2360 hddLog(VOS_TRACE_LEVEL_INFO, "Status (%u)", pData->status);
2361
2362 if (nla_put_u32(skb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_REQUEST_ID,
2363 pData->requestId) ||
2364 nla_put_u32(skb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_STATUS, pData->status)) {
2365 hddLog(VOS_TRACE_LEVEL_ERROR, FL("nla put fail"));
2366 goto nla_put_failure;
2367 }
2368
2369 cfg80211_vendor_event(skb, GFP_KERNEL);
2370 return;
2371
2372nla_put_failure:
2373 kfree_skb(skb);
2374 return;
2375}
2376
2377static void wlan_hdd_cfg80211_extscan_cached_results_ind(void *ctx,
2378 void *pMsg)
2379{
2380 hdd_context_t *pHddCtx = (hdd_context_t *)ctx;
2381 struct sk_buff *skb = NULL;
2382 tANI_U32 i = 0, j, resultsPerEvent;
2383 tANI_S32 totalResults;
2384 tpSirWifiScanResultEvent pData = (tpSirWifiScanResultEvent) pMsg;
2385 tpSirWifiScanResult pSirWifiScanResult;
2386
2387 if (wlan_hdd_validate_context(pHddCtx) || !pData) {
2388 hddLog(VOS_TRACE_LEVEL_ERROR, FL("HDD context is not valid "
2389 "or pData(%p) is null"), pData);
2390 return;
2391 }
2392 totalResults = pData->numOfAps;
2393 hddLog(VOS_TRACE_LEVEL_INFO, "Req Id (%u)", pData->requestId);
2394 hddLog(VOS_TRACE_LEVEL_INFO, "Num results (%u)", pData->numOfAps);
2395 hddLog(VOS_TRACE_LEVEL_INFO, "More Data (%u)", pData->moreData);
2396
2397 do{
2398 resultsPerEvent = ((totalResults >= EXTSCAN_MAX_CACHED_RESULTS_PER_IND) ?
2399 EXTSCAN_MAX_CACHED_RESULTS_PER_IND : totalResults);
2400 totalResults -= EXTSCAN_MAX_CACHED_RESULTS_PER_IND;
2401
2402 skb = cfg80211_vendor_event_alloc(pHddCtx->wiphy,
2403 EXTSCAN_EVENT_BUF_SIZE + NLMSG_HDRLEN,
2404 QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_GET_CACHED_RESULTS_INDEX,
2405 GFP_KERNEL);
2406
2407 if (!skb) {
2408 hddLog(VOS_TRACE_LEVEL_ERROR,
2409 FL("cfg80211_vendor_event_alloc failed"));
2410 return;
2411 }
2412
2413 hddLog(VOS_TRACE_LEVEL_INFO, "resultsPerEvent (%u)", resultsPerEvent);
2414
2415 if (nla_put_u32(skb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_REQUEST_ID,
2416 pData->requestId) ||
2417 nla_put_u32(skb,
2418 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_NUM_RESULTS_AVAILABLE,
2419 resultsPerEvent)) {
2420 hddLog(VOS_TRACE_LEVEL_ERROR, FL("put fail"));
2421 goto fail;
2422 }
2423 if (nla_put_u8(skb,
2424 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_MORE_DATA,
2425 pData->moreData ? 1 : (totalResults > 0 ? 1 : 0 )))
2426 {
2427 hddLog(VOS_TRACE_LEVEL_ERROR, FL("put fail"));
2428 goto fail;
2429 }
2430
2431 if (resultsPerEvent) {
2432 struct nlattr *aps;
2433
2434 aps = nla_nest_start(skb,
2435 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_LIST);
2436 if (!aps)
2437 {
2438 hddLog(VOS_TRACE_LEVEL_ERROR, FL("put fail"));
2439 goto fail;
2440 }
2441
2442 for (j = 0; j < resultsPerEvent; j++, i++) {
2443 struct nlattr *ap;
2444 pSirWifiScanResult = (tpSirWifiScanResult) ((tANI_U8 *)
2445 pData->ap + ( i* sizeof(tSirWifiScanResult)));
2446
2447 hddLog(VOS_TRACE_LEVEL_INFO, "[index=%u] Timestamp(%llu) "
2448 "Ssid (%s)"
2449 "Bssid: %pM "
2450 "Channel (%u)"
2451 "Rssi (%d)"
2452 "RTT (%u)"
2453 "RTT_SD (%u)",
2454 i,
2455 pSirWifiScanResult->ts,
2456 pSirWifiScanResult->ssid,
2457 pSirWifiScanResult->bssid,
2458 pSirWifiScanResult->channel,
2459 pSirWifiScanResult->rssi,
2460 pSirWifiScanResult->rtt,
2461 pSirWifiScanResult->rtt_sd);
2462
2463 ap = nla_nest_start(skb, j + 1);
2464 if (!ap)
2465 {
2466 hddLog(VOS_TRACE_LEVEL_ERROR, FL("put fail"));
2467 goto fail;
2468 }
2469
2470 if (nla_put_u64(skb,
2471 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_TIME_STAMP,
2472 pSirWifiScanResult->ts) )
2473 {
2474 hddLog(VOS_TRACE_LEVEL_ERROR, FL("put fail"));
2475 goto fail;
2476 }
2477 if (nla_put(skb,
2478 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_SSID,
2479 sizeof(pSirWifiScanResult->ssid),
2480 pSirWifiScanResult->ssid) )
2481 {
2482 hddLog(VOS_TRACE_LEVEL_ERROR, FL("put fail"));
2483 goto fail;
2484 }
2485 if (nla_put(skb,
2486 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_BSSID,
2487 sizeof(pSirWifiScanResult->bssid),
2488 pSirWifiScanResult->bssid) )
2489 {
2490 hddLog(VOS_TRACE_LEVEL_ERROR, FL("put fail"));
2491 goto fail;
2492 }
2493 if (nla_put_u32(skb,
2494 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_CHANNEL,
2495 pSirWifiScanResult->channel) )
2496 {
2497 hddLog(VOS_TRACE_LEVEL_ERROR, FL("put fail"));
2498 goto fail;
2499 }
Dasari Srinivas90747d72014-10-08 12:16:15 +05302500 if (nla_put_s32(skb,
Dino Mycle6fb96c12014-06-10 11:52:40 +05302501 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_RSSI,
2502 pSirWifiScanResult->rssi) )
2503 {
2504 hddLog(VOS_TRACE_LEVEL_ERROR, FL("put fail"));
2505 goto fail;
2506 }
2507 if (nla_put_u32(skb,
2508 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_RTT,
2509 pSirWifiScanResult->rtt) )
2510 {
2511 hddLog(VOS_TRACE_LEVEL_ERROR, FL("put fail"));
2512 goto fail;
2513 }
2514 if (nla_put_u32(skb,
2515 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_RTT_SD,
2516 pSirWifiScanResult->rtt_sd))
2517 {
2518 hddLog(VOS_TRACE_LEVEL_ERROR, FL("put fail"));
2519 goto fail;
2520 }
2521
2522 nla_nest_end(skb, ap);
2523 }
2524 nla_nest_end(skb, aps);
2525
2526 }
2527 cfg80211_vendor_event(skb, GFP_KERNEL);
2528 } while (totalResults > 0);
2529
2530 return;
2531fail:
2532 kfree_skb(skb);
2533 return;
2534}
2535
2536static void wlan_hdd_cfg80211_extscan_hotlist_match_ind(void *ctx,
2537 void *pMsg)
2538{
2539 tpSirWifiScanResultEvent pData = (tpSirWifiScanResultEvent) pMsg;
2540 hdd_context_t *pHddCtx = (hdd_context_t *)ctx;
2541 struct sk_buff *skb = NULL;
2542 tANI_U32 i;
2543
2544 if (wlan_hdd_validate_context(pHddCtx) || !pData) {
2545 hddLog(VOS_TRACE_LEVEL_ERROR, FL("HDD context is not valid "
2546 "or pData(%p) is null"), pData);
2547 return;
2548 }
2549
2550 skb = cfg80211_vendor_event_alloc(pHddCtx->wiphy,
2551 EXTSCAN_EVENT_BUF_SIZE + NLMSG_HDRLEN,
2552 QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_HOTLIST_AP_FOUND_INDEX,
2553 GFP_KERNEL);
2554
2555 if (!skb) {
2556 hddLog(VOS_TRACE_LEVEL_ERROR,
2557 FL("cfg80211_vendor_event_alloc failed"));
2558 return;
2559 }
2560 hddLog(VOS_TRACE_LEVEL_INFO, FL("Entering "));
2561 hddLog(VOS_TRACE_LEVEL_INFO, "Req Id (%u)", pData->requestId);
2562 hddLog(VOS_TRACE_LEVEL_INFO, "Num results (%u)", pData->numOfAps);
2563 hddLog(VOS_TRACE_LEVEL_INFO, "More Data (%u)", pData->moreData);
2564
2565 for (i = 0; i < pData->numOfAps; i++) {
2566 hddLog(VOS_TRACE_LEVEL_INFO, "[index=%u] Timestamp(0x%lld) "
2567 "Ssid (%s) "
2568 "Bssid (" MAC_ADDRESS_STR ") "
2569 "Channel (%u) "
2570 "Rssi (%d) "
2571 "RTT (%u) "
2572 "RTT_SD (%u) ",
2573 i,
2574 pData->ap[i].ts,
2575 pData->ap[i].ssid,
2576 MAC_ADDR_ARRAY(pData->ap[i].bssid),
2577 pData->ap[i].channel,
2578 pData->ap[i].rssi,
2579 pData->ap[i].rtt,
2580 pData->ap[i].rtt_sd);
2581 }
2582
2583 if (nla_put_u32(skb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_REQUEST_ID,
2584 pData->requestId) ||
2585 nla_put_u32(skb,
2586 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_NUM_RESULTS_AVAILABLE,
2587 pData->numOfAps)) {
2588 hddLog(VOS_TRACE_LEVEL_ERROR, FL("put fail"));
2589 goto fail;
2590 }
2591 if (pData->numOfAps) {
2592 struct nlattr *aps;
2593
2594 aps = nla_nest_start(skb,
2595 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_LIST);
2596 if (!aps)
2597 goto fail;
2598
2599 for (i = 0; i < pData->numOfAps; i++) {
2600 struct nlattr *ap;
2601
2602 ap = nla_nest_start(skb, i + 1);
2603 if (!ap)
2604 goto fail;
2605
2606 if (nla_put_u64(skb,
2607 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_TIME_STAMP,
2608 pData->ap[i].ts) ||
2609 nla_put(skb,
2610 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_SSID,
2611 sizeof(pData->ap[i].ssid),
2612 pData->ap[i].ssid) ||
2613 nla_put(skb,
2614 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_BSSID,
2615 sizeof(pData->ap[i].bssid),
2616 pData->ap[i].bssid) ||
2617 nla_put_u32(skb,
2618 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_CHANNEL,
2619 pData->ap[i].channel) ||
2620 nla_put_s32(skb,
2621 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_RSSI,
2622 pData->ap[i].rssi) ||
2623 nla_put_u32(skb,
2624 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_RTT,
2625 pData->ap[i].rtt) ||
2626 nla_put_u32(skb,
2627 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_RTT_SD,
2628 pData->ap[i].rtt_sd))
2629 goto fail;
2630
2631 nla_nest_end(skb, ap);
2632 }
2633 nla_nest_end(skb, aps);
2634
2635 if (nla_put_u8(skb,
2636 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_MORE_DATA,
2637 pData->moreData))
2638 goto fail;
2639 }
2640
2641 cfg80211_vendor_event(skb, GFP_KERNEL);
2642 return;
2643
2644fail:
2645 kfree_skb(skb);
2646 return;
2647
2648}
2649static void wlan_hdd_cfg80211_extscan_signif_wifi_change_results_ind(void *ctx,
2650 void *pMsg)
2651{
2652 hdd_context_t *pHddCtx = (hdd_context_t *)ctx;
2653 struct sk_buff *skb = NULL;
2654 tANI_U32 i, j;
2655 tpSirWifiSignificantChangeEvent pData =
2656 (tpSirWifiSignificantChangeEvent) pMsg;
2657
2658 if (wlan_hdd_validate_context(pHddCtx) || !pData) {
2659 hddLog(VOS_TRACE_LEVEL_ERROR, FL("HDD context is not valid "
2660 "or pData(%p) is null"), pData);
2661 return;
2662 }
2663 skb = cfg80211_vendor_event_alloc(pHddCtx->wiphy,
2664 EXTSCAN_EVENT_BUF_SIZE,
2665 QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_SIGNIFICANT_CHANGE_INDEX,
2666 GFP_KERNEL);
2667
2668 if (!skb) {
2669 hddLog(VOS_TRACE_LEVEL_ERROR,
2670 FL("cfg80211_vendor_event_alloc failed"));
2671 return;
2672 }
2673 hddLog(VOS_TRACE_LEVEL_INFO, FL("Entering "));
2674 hddLog(VOS_TRACE_LEVEL_INFO, "Req Id (%u)", pData->requestId);
2675 hddLog(VOS_TRACE_LEVEL_INFO, "total List Size %u ", pData->numSigRssiBss);
2676 hddLog(VOS_TRACE_LEVEL_INFO, " CUrrent List size (%u)",
2677 pData->numSigRssiBss);
2678 hddLog(VOS_TRACE_LEVEL_INFO, "moreData (%u)", pData->moreData);
2679
2680 for (i = 0; i < pData->numSigRssiBss; i++) {
2681 hddLog(VOS_TRACE_LEVEL_INFO , "Rssi List [%d] BSSID: (%pM) Channel %u "
2682 " num RSSI %u ",
2683 i, pData->sigRssiResult[i].bssid,
2684 pData->sigRssiResult[i].channel,
2685 pData->sigRssiResult[i].numRssi);
2686
2687 for (j = 0; j < pData->sigRssiResult[i].numRssi; j++){
2688
2689 hddLog(VOS_TRACE_LEVEL_INFO,
2690 " [%d]",
Dino Myclec8f3f332014-07-21 16:48:27 +05302691 pData->sigRssiResult[i].rssi[j]);
Dino Mycle6fb96c12014-06-10 11:52:40 +05302692
2693 }
2694 }
2695
2696
2697 if (nla_put_u32(skb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_REQUEST_ID,
2698 pData->requestId) ||
2699 nla_put_u32(skb,
2700 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_NUM_RESULTS_AVAILABLE,
2701 pData->numSigRssiBss)) {
2702 hddLog(VOS_TRACE_LEVEL_ERROR, FL("put fail"));
2703 goto fail;
2704 }
2705
2706 if (pData->numSigRssiBss) {
2707 struct nlattr *aps;
2708 aps = nla_nest_start(skb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_LIST);
2709 if (!aps)
2710 goto fail;
2711 for (i = 0; i < pData->numSigRssiBss; i++) {
2712 struct nlattr *ap;
2713
2714 ap = nla_nest_start(skb, i);
2715 if (!ap)
2716 goto fail;
2717 if (nla_put(skb,
2718 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SIGNIFICANT_CHANGE_RESULT_BSSID,
2719 sizeof(tSirMacAddr), pData->sigRssiResult[i].bssid) ||
2720 nla_put_u32(skb,
2721 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SIGNIFICANT_CHANGE_RESULT_CHANNEL,
2722 pData->sigRssiResult[i].channel) ||
2723 nla_put_u32(skb,
2724 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SIGNIFICANT_CHANGE_RESULT_NUM_RSSI,
2725 pData->sigRssiResult[i].numRssi) ||
2726 nla_put(skb,
2727 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SIGNIFICANT_CHANGE_RESULT_RSSI_LIST,
2728 sizeof(s32) * pData->sigRssiResult[i].numRssi,
2729 pData->sigRssiResult[i].rssi))
2730 goto fail;
2731 nla_nest_end(skb, ap);
2732 }
2733 nla_nest_end(skb, aps);
2734 if (nla_put_u8(skb,
2735 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_MORE_DATA,
2736 pData->moreData))
2737 goto fail;
2738 }
2739 cfg80211_vendor_event(skb, GFP_KERNEL);
2740 return;
2741fail:
2742 kfree_skb(skb);
2743 return;
2744}
2745
2746static void wlan_hdd_cfg80211_extscan_full_scan_result_event(void *ctx,
2747 void *pMsg)
2748{
2749 struct sk_buff *skb;
2750 hdd_context_t *pHddCtx = (hdd_context_t *)ctx;
2751 tpSirWifiFullScanResultEvent pData =
2752 (tpSirWifiFullScanResultEvent) (pMsg);
2753
2754 if (wlan_hdd_validate_context(pHddCtx) || !pData) {
2755 hddLog(VOS_TRACE_LEVEL_ERROR, FL("HDD context is not valid "
2756 "or pData(%p) is null"), pData);
2757 return;
2758 }
2759
2760 skb = cfg80211_vendor_event_alloc(pHddCtx->wiphy,
2761 EXTSCAN_EVENT_BUF_SIZE + NLMSG_HDRLEN,
2762 QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_FULL_SCAN_RESULT_INDEX,
2763 GFP_KERNEL);
2764
2765 if (!skb) {
2766 hddLog(VOS_TRACE_LEVEL_ERROR,
2767 FL("cfg80211_vendor_event_alloc failed"));
2768 return;
2769 }
2770
2771 hddLog(VOS_TRACE_LEVEL_INFO, FL("Entering "));
2772 hddLog(VOS_TRACE_LEVEL_INFO, FL("Req Id (%u)"), pData->requestId);
2773 hddLog(VOS_TRACE_LEVEL_INFO, FL("More Data (%u)"), pData->moreData);
2774 hddLog(VOS_TRACE_LEVEL_INFO, FL("AP Info: Timestamp(0x%llX) "
2775 "Ssid (%s)"
2776 "Bssid (" MAC_ADDRESS_STR ")"
2777 "Channel (%u)"
2778 "Rssi (%d)"
2779 "RTT (%u)"
2780 "RTT_SD (%u)"),
2781 pData->ap.ts,
2782 pData->ap.ssid,
2783 MAC_ADDR_ARRAY(pData->ap.bssid),
2784 pData->ap.channel,
2785 pData->ap.rssi,
2786 pData->ap.rtt,
2787 pData->ap.rtt_sd);
2788 hddLog(VOS_TRACE_LEVEL_INFO, "IE Length (%u)", pData->ieLength);
2789 if (nla_put_u32(skb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_REQUEST_ID,
2790 pData->requestId) ||
2791 nla_put_u64(skb,
2792 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_TIME_STAMP,
2793 pData->ap.ts) ||
2794 nla_put(skb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_SSID,
2795 sizeof(pData->ap.ssid),
2796 pData->ap.ssid) ||
2797 nla_put(skb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_BSSID,
2798 WNI_CFG_BSSID_LEN,
2799 pData->ap.bssid) ||
2800 nla_put_u32(skb,
2801 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_CHANNEL,
2802 pData->ap.channel) ||
Dasari Srinivas90747d72014-10-08 12:16:15 +05302803 nla_put_s32(skb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_RSSI,
Dino Mycle6fb96c12014-06-10 11:52:40 +05302804 pData->ap.rssi) ||
2805 nla_put_u32(skb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_RTT,
2806 pData->ap.rtt) ||
2807 nla_put_u32(skb,
2808 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_RTT_SD,
2809 pData->ap.rtt_sd) ||
2810 nla_put_u16(skb,
2811 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_BEACON_PERIOD,
2812 pData->ap.beaconPeriod) ||
2813 nla_put_u16(skb,
2814 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_CAPABILITY,
2815 pData->ap.capability) ||
2816 nla_put_u32(skb,
2817 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_IE_LENGTH,
2818 pData->ieLength))
2819 {
2820 hddLog(VOS_TRACE_LEVEL_ERROR, FL("nla put fail"));
2821 goto nla_put_failure;
2822 }
2823 if (nla_put(skb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_IE_DATA,
2824 pData->ieLength,
2825 pData->ie))
2826 {
2827 hddLog(VOS_TRACE_LEVEL_ERROR, FL("nla put fail"));
2828 goto nla_put_failure;
2829 }
2830
2831 cfg80211_vendor_event(skb, GFP_KERNEL);
2832 return;
2833
2834nla_put_failure:
2835 kfree_skb(skb);
2836 return;
2837}
2838
2839static void wlan_hdd_cfg80211_extscan_scan_res_available_event(void *ctx,
2840 void *pMsg)
2841{
2842 hdd_context_t *pHddCtx = (hdd_context_t *)ctx;
2843 struct sk_buff *skb = NULL;
2844 tpSirEXTScanResultsAvailableIndParams pData =
2845 (tpSirEXTScanResultsAvailableIndParams) pMsg;
2846
2847 if (wlan_hdd_validate_context(pHddCtx) || !pData) {
2848 hddLog(VOS_TRACE_LEVEL_ERROR, FL("HDD context is not valid "
2849 "or pData(%p) is null"), pData);
2850 return;
2851 }
2852
2853 skb = cfg80211_vendor_event_alloc(pHddCtx->wiphy,
2854 EXTSCAN_EVENT_BUF_SIZE + NLMSG_HDRLEN,
2855 QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_SCAN_RESULTS_AVAILABLE_INDEX,
2856 GFP_KERNEL);
2857
2858 if (!skb) {
2859 hddLog(VOS_TRACE_LEVEL_ERROR,
2860 FL("cfg80211_vendor_event_alloc failed"));
2861 return;
2862 }
2863
2864 hddLog(VOS_TRACE_LEVEL_INFO, FL("Entering "));
2865 hddLog(VOS_TRACE_LEVEL_INFO, "Req Id (%u)", pData->requestId);
2866 hddLog(VOS_TRACE_LEVEL_INFO, "Num results (%u)",
2867 pData->numResultsAvailable);
2868 if (nla_put_u32(skb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_REQUEST_ID,
2869 pData->requestId) ||
2870 nla_put_u32(skb,
2871 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_NUM_RESULTS_AVAILABLE,
2872 pData->numResultsAvailable)) {
2873 hddLog(VOS_TRACE_LEVEL_ERROR, FL("nla put fail"));
2874 goto nla_put_failure;
2875 }
2876
2877 cfg80211_vendor_event(skb, GFP_KERNEL);
2878 return;
2879
2880nla_put_failure:
2881 kfree_skb(skb);
2882 return;
2883}
2884
2885static void wlan_hdd_cfg80211_extscan_scan_progress_event(void *ctx, void *pMsg)
2886{
2887 hdd_context_t *pHddCtx = (hdd_context_t *)ctx;
2888 struct sk_buff *skb = NULL;
2889 tpSirEXTScanProgressIndParams pData =
2890 (tpSirEXTScanProgressIndParams) pMsg;
2891
2892 if (wlan_hdd_validate_context(pHddCtx) || !pData) {
2893 hddLog(VOS_TRACE_LEVEL_ERROR, FL("HDD context is not valid "
2894 "or pData(%p) is null"), pData);
2895 return;
2896 }
2897
2898 skb = cfg80211_vendor_event_alloc(pHddCtx->wiphy,
2899 EXTSCAN_EVENT_BUF_SIZE + NLMSG_HDRLEN,
2900 QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_SCAN_EVENT_INDEX,
2901 GFP_KERNEL);
2902
2903 if (!skb) {
2904 hddLog(VOS_TRACE_LEVEL_ERROR,
2905 FL("cfg80211_vendor_event_alloc failed"));
2906 return;
2907 }
2908 hddLog(VOS_TRACE_LEVEL_INFO, FL("Entering "));
2909 hddLog(VOS_TRACE_LEVEL_INFO, "Scan event type (%u)",
2910 pData->extScanEventType);
2911 hddLog(VOS_TRACE_LEVEL_INFO, "Scan event status (%u)",
2912 pData->status);
2913
2914 if (nla_put_u8(skb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_EVENT_TYPE,
2915 pData->extScanEventType) ||
2916 nla_put_u32(skb,
Dasari Srinivas5a288652014-06-30 17:13:22 +05302917 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_REQUEST_ID,
2918 pData->requestId) ||
2919 nla_put_u32(skb,
Dino Mycle6fb96c12014-06-10 11:52:40 +05302920 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_EVENT_STATUS,
2921 pData->status)) {
2922 hddLog(VOS_TRACE_LEVEL_ERROR, FL("nla put fail"));
2923 goto nla_put_failure;
2924 }
2925
2926 cfg80211_vendor_event(skb, GFP_KERNEL);
2927 return;
2928
2929nla_put_failure:
2930 kfree_skb(skb);
2931 return;
2932}
2933
2934void wlan_hdd_cfg80211_extscan_callback(void *ctx, const tANI_U16 evType,
2935 void *pMsg)
2936{
2937 hdd_context_t *pHddCtx = (hdd_context_t *)ctx;
2938
2939 if (wlan_hdd_validate_context(pHddCtx)) {
Dasari Srinivasb46ed1d2014-10-08 13:03:08 +05302940 hddLog(VOS_TRACE_LEVEL_INFO, FL("HDD context is not valid"));
Dino Mycle6fb96c12014-06-10 11:52:40 +05302941 return;
2942 }
2943
2944 hddLog(VOS_TRACE_LEVEL_INFO, FL("Rcvd Event (%d)"), evType);
2945
2946
2947 switch(evType) {
2948 case SIR_HAL_EXTSCAN_START_RSP:
2949 wlan_hdd_cfg80211_extscan_start_rsp(ctx, pMsg);
2950 break;
2951
2952 case SIR_HAL_EXTSCAN_STOP_RSP:
2953 wlan_hdd_cfg80211_extscan_stop_rsp(ctx, pMsg);
2954 break;
2955 case SIR_HAL_EXTSCAN_GET_CACHED_RESULTS_RSP:
2956 /* There is no need to send this response to upper layer
2957 Just log the message */
2958 hddLog(VOS_TRACE_LEVEL_INFO,
2959 FL("Rcvd SIR_HAL_EXTSCAN_CACHED_RESULTS_RSP"));
2960 break;
2961 case SIR_HAL_EXTSCAN_SET_BSS_HOTLIST_RSP:
2962 wlan_hdd_cfg80211_extscan_set_bss_hotlist_rsp(ctx, pMsg);
2963 break;
2964
2965 case SIR_HAL_EXTSCAN_RESET_BSS_HOTLIST_RSP:
2966 wlan_hdd_cfg80211_extscan_reset_bss_hotlist_rsp(ctx, pMsg);
2967 break;
2968
2969 case SIR_HAL_EXTSCAN_SET_SIGNF_RSSI_CHANGE_RSP:
2970 wlan_hdd_cfg80211_extscan_set_signf_wifi_change_rsp(ctx, pMsg);
2971 break;
2972
2973 case SIR_HAL_EXTSCAN_RESET_SIGNF_RSSI_CHANGE_RSP:
2974 wlan_hdd_cfg80211_extscan_reset_signf_wifi_change_rsp(ctx, pMsg);
2975 break;
2976 case SIR_HAL_EXTSCAN_GET_CAPABILITIES_RSP:
2977 wlan_hdd_cfg80211_extscan_get_capabilities_ind(ctx, pMsg);
2978 break;
2979 case SIR_HAL_EXTSCAN_PROGRESS_IND:
2980 wlan_hdd_cfg80211_extscan_scan_progress_event(ctx, pMsg);
2981 break;
2982 case SIR_HAL_EXTSCAN_SCAN_AVAILABLE_IND:
2983 wlan_hdd_cfg80211_extscan_scan_res_available_event(ctx, pMsg);
2984 break;
2985 case SIR_HAL_EXTSCAN_SCAN_RESULT_IND:
2986 wlan_hdd_cfg80211_extscan_cached_results_ind(ctx, pMsg);
2987 break;
2988 case SIR_HAL_EXTSCAN_HOTLIST_MATCH_IND:
2989 wlan_hdd_cfg80211_extscan_hotlist_match_ind(ctx, pMsg);
2990 break;
2991 case SIR_HAL_EXTSCAN_SIGNF_WIFI_CHANGE_IND:
2992 wlan_hdd_cfg80211_extscan_signif_wifi_change_results_ind(ctx, pMsg);
2993 break;
2994 case SIR_HAL_EXTSCAN_FULL_SCAN_RESULT_IND:
2995 wlan_hdd_cfg80211_extscan_full_scan_result_event(ctx, pMsg);
2996 break;
2997 default:
2998 hddLog(VOS_TRACE_LEVEL_ERROR, FL("invalid event type %d "), evType);
2999 break;
3000 }
3001}
3002
3003static int wlan_hdd_cfg80211_extscan_get_capabilities(struct wiphy *wiphy,
3004 struct wireless_dev *wdev,
3005 void *data, int dataLen)
3006{
Dino Myclee8843b32014-07-04 14:21:45 +05303007 tSirGetEXTScanCapabilitiesReqParams reqMsg;
Dino Mycle6fb96c12014-06-10 11:52:40 +05303008 struct net_device *dev = wdev->netdev;
3009 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
3010 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
3011 struct nlattr
3012 *tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX + 1];
3013 eHalStatus status;
3014
3015 hddLog(VOS_TRACE_LEVEL_INFO, FL("Entering"));
3016 status = wlan_hdd_validate_context(pHddCtx);
3017 if (0 != status)
3018 {
3019 hddLog(VOS_TRACE_LEVEL_ERROR,
3020 FL("HDD context is not valid"));
3021 return -EINVAL;
3022 }
Dino Myclee8843b32014-07-04 14:21:45 +05303023 /* check the EXTScan Capability */
3024 if ( (TRUE != pHddCtx->cfg_ini->fEnableEXTScan) ||
3025 (TRUE != sme_IsFeatureSupportedByFW(EXTENDED_SCAN)))
3026 {
3027 hddLog(VOS_TRACE_LEVEL_ERROR,
3028 FL("EXTScan not enabled/supported by Firmware"));
3029 return -EINVAL;
3030 }
3031
Dino Mycle6fb96c12014-06-10 11:52:40 +05303032 if (nla_parse(tb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX,
3033 data, dataLen,
3034 wlan_hdd_extscan_config_policy)) {
3035 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Invalid ATTR"));
3036 return -EINVAL;
3037 }
3038
3039 /* Parse and fetch request Id */
3040 if (!tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_REQUEST_ID]) {
3041 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr request id failed"));
3042 return -EINVAL;
3043 }
3044
Dino Mycle6fb96c12014-06-10 11:52:40 +05303045
Dino Myclee8843b32014-07-04 14:21:45 +05303046 reqMsg.requestId = nla_get_u32(
Dino Mycle6fb96c12014-06-10 11:52:40 +05303047 tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_REQUEST_ID]);
Dino Myclee8843b32014-07-04 14:21:45 +05303048 hddLog(VOS_TRACE_LEVEL_INFO, FL("Req Id (%d)"), reqMsg.requestId);
Dino Mycle6fb96c12014-06-10 11:52:40 +05303049
Dino Myclee8843b32014-07-04 14:21:45 +05303050 reqMsg.sessionId = pAdapter->sessionId;
3051 hddLog(VOS_TRACE_LEVEL_INFO, FL("Session Id (%d)"), reqMsg.sessionId);
Dino Mycle6fb96c12014-06-10 11:52:40 +05303052
Dino Myclee8843b32014-07-04 14:21:45 +05303053 status = sme_EXTScanGetCapabilities(pHddCtx->hHal, &reqMsg);
Dino Mycle6fb96c12014-06-10 11:52:40 +05303054 if (!HAL_STATUS_SUCCESS(status)) {
3055 hddLog(VOS_TRACE_LEVEL_ERROR,
3056 FL("sme_EXTScanGetCapabilities failed(err=%d)"), status);
Dino Mycle6fb96c12014-06-10 11:52:40 +05303057 return -EINVAL;
3058 }
3059
3060 return 0;
3061}
3062
3063
3064static int wlan_hdd_cfg80211_extscan_get_cached_results(struct wiphy *wiphy,
3065 struct wireless_dev *wdev,
3066 void *data, int dataLen)
3067{
Dino Myclee8843b32014-07-04 14:21:45 +05303068 tSirEXTScanGetCachedResultsReqParams reqMsg;
Dino Mycle6fb96c12014-06-10 11:52:40 +05303069 struct net_device *dev = wdev->netdev;
3070 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
3071 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
3072 struct nlattr
3073 *tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX + 1];
3074 eHalStatus status;
3075
3076 status = wlan_hdd_validate_context(pHddCtx);
3077 if (0 != status)
3078 {
3079 hddLog(VOS_TRACE_LEVEL_ERROR,
3080 FL("HDD context is not valid"));
3081 return -EINVAL;
3082 }
Dino Myclee8843b32014-07-04 14:21:45 +05303083 /* check the EXTScan Capability */
3084 if ( (TRUE != pHddCtx->cfg_ini->fEnableEXTScan) ||
3085 (TRUE != sme_IsFeatureSupportedByFW(EXTENDED_SCAN)))
3086 {
3087 hddLog(VOS_TRACE_LEVEL_ERROR,
3088 FL("EXTScan not enabled/supported by Firmware"));
3089 return -EINVAL;
3090 }
3091
Dino Mycle6fb96c12014-06-10 11:52:40 +05303092 if (nla_parse(tb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX,
3093 data, dataLen,
3094 wlan_hdd_extscan_config_policy)) {
3095 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Invalid ATTR"));
3096 return -EINVAL;
3097 }
3098 /* Parse and fetch request Id */
3099 if (!tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_REQUEST_ID]) {
3100 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr request id failed"));
3101 return -EINVAL;
3102 }
Dino Mycle6fb96c12014-06-10 11:52:40 +05303103
Dino Myclee8843b32014-07-04 14:21:45 +05303104 reqMsg.requestId = nla_get_u32(
Dino Mycle6fb96c12014-06-10 11:52:40 +05303105 tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_REQUEST_ID]);
3106
Dino Myclee8843b32014-07-04 14:21:45 +05303107 hddLog(VOS_TRACE_LEVEL_INFO, FL("Req Id (%d)"), reqMsg.requestId);
Dino Mycle6fb96c12014-06-10 11:52:40 +05303108
Dino Myclee8843b32014-07-04 14:21:45 +05303109 reqMsg.sessionId = pAdapter->sessionId;
3110 hddLog(VOS_TRACE_LEVEL_INFO, FL("Session Id (%d)"), reqMsg.sessionId);
Dino Mycle6fb96c12014-06-10 11:52:40 +05303111
3112 /* Parse and fetch flush parameter */
3113 if (!tb
3114 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_GET_CACHED_SCAN_RESULTS_CONFIG_PARAM_FLUSH])
3115 {
3116 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr flush failed"));
3117 goto failed;
3118 }
Dino Myclee8843b32014-07-04 14:21:45 +05303119 reqMsg.flush = nla_get_u8(
Dino Mycle6fb96c12014-06-10 11:52:40 +05303120 tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_GET_CACHED_SCAN_RESULTS_CONFIG_PARAM_FLUSH]);
3121
Dino Myclee8843b32014-07-04 14:21:45 +05303122 hddLog(VOS_TRACE_LEVEL_INFO, FL("Flush (%d)"), reqMsg.flush);
Dino Mycle6fb96c12014-06-10 11:52:40 +05303123
Dino Myclee8843b32014-07-04 14:21:45 +05303124 status = sme_getCachedResults(pHddCtx->hHal, &reqMsg);
Dino Mycle6fb96c12014-06-10 11:52:40 +05303125 if (!HAL_STATUS_SUCCESS(status)) {
3126 hddLog(VOS_TRACE_LEVEL_ERROR,
3127 FL("sme_getCachedResults failed(err=%d)"), status);
Dino Mycle6fb96c12014-06-10 11:52:40 +05303128 return -EINVAL;
3129 }
3130 return 0;
3131
3132failed:
Dino Mycle6fb96c12014-06-10 11:52:40 +05303133 return -EINVAL;
3134}
3135
3136static int wlan_hdd_cfg80211_extscan_set_bssid_hotlist(struct wiphy *wiphy,
3137 struct wireless_dev *wdev,
3138 void *data, int dataLen)
3139{
3140 tpSirEXTScanSetBssidHotListReqParams pReqMsg = NULL;
3141 struct net_device *dev = wdev->netdev;
3142 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
3143 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
3144 struct nlattr
3145 *tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX + 1];
3146 struct nlattr
3147 *tb2[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX + 1];
3148 struct nlattr *apTh;
3149 eHalStatus status;
3150 tANI_U8 i = 0;
3151 int rem;
3152
3153 status = wlan_hdd_validate_context(pHddCtx);
3154 if (0 != status)
3155 {
3156 hddLog(VOS_TRACE_LEVEL_ERROR,
3157 FL("HDD context is not valid"));
3158 return -EINVAL;
3159 }
Dino Myclee8843b32014-07-04 14:21:45 +05303160 /* check the EXTScan Capability */
3161 if ( (TRUE != pHddCtx->cfg_ini->fEnableEXTScan) ||
3162 (TRUE != sme_IsFeatureSupportedByFW(EXTENDED_SCAN)))
3163 {
3164 hddLog(VOS_TRACE_LEVEL_ERROR,
3165 FL("EXTScan not enabled/supported by Firmware"));
3166 return -EINVAL;
3167 }
3168
Dino Mycle6fb96c12014-06-10 11:52:40 +05303169 if (nla_parse(tb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX,
3170 data, dataLen,
3171 wlan_hdd_extscan_config_policy)) {
3172 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Invalid ATTR"));
3173 return -EINVAL;
3174 }
3175
3176 /* Parse and fetch request Id */
3177 if (!tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_REQUEST_ID]) {
3178 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr request id failed"));
3179 return -EINVAL;
3180 }
Dino Mycle6fb96c12014-06-10 11:52:40 +05303181 pReqMsg = (tpSirEXTScanSetBssidHotListReqParams)
3182 vos_mem_malloc(sizeof(*pReqMsg));
3183 if (!pReqMsg) {
3184 hddLog(VOS_TRACE_LEVEL_ERROR, FL("vos_mem_malloc failed"));
3185 return -ENOMEM;
3186 }
3187
Dino Myclee8843b32014-07-04 14:21:45 +05303188
Dino Mycle6fb96c12014-06-10 11:52:40 +05303189 pReqMsg->requestId = nla_get_u32(
3190 tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_REQUEST_ID]);
3191 hddLog(VOS_TRACE_LEVEL_INFO, FL("Req Id (%d)"), pReqMsg->requestId);
3192
3193 /* Parse and fetch number of APs */
3194 if (!tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_BSSID_HOTLIST_PARAMS_NUM_AP]) {
3195 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr number of AP failed"));
3196 goto fail;
3197 }
3198
3199 pReqMsg->sessionId = pAdapter->sessionId;
3200 hddLog(VOS_TRACE_LEVEL_INFO, FL("Session Id (%d)"), pReqMsg->sessionId);
3201
3202 pReqMsg->numAp = nla_get_u32(
3203 tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_BSSID_HOTLIST_PARAMS_NUM_AP]);
3204 hddLog(VOS_TRACE_LEVEL_INFO, FL("Number of AP (%d)"), pReqMsg->numAp);
3205
3206 nla_for_each_nested(apTh,
3207 tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_AP_THRESHOLD_PARAM], rem) {
3208 if(nla_parse(tb2, QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX,
3209 nla_data(apTh), nla_len(apTh),
3210 NULL)) {
3211 hddLog(VOS_TRACE_LEVEL_ERROR, FL("nla_parse failed"));
3212 goto fail;
3213 }
3214
3215 /* Parse and fetch MAC address */
3216 if (!tb2[QCA_WLAN_VENDOR_ATTR_EXTSCAN_AP_THRESHOLD_PARAM_BSSID]) {
3217 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr mac address failed"));
3218 goto fail;
3219 }
3220 memcpy(pReqMsg->ap[i].bssid, nla_data(
3221 tb2[QCA_WLAN_VENDOR_ATTR_EXTSCAN_AP_THRESHOLD_PARAM_BSSID]),
3222 sizeof(tSirMacAddr));
3223 hddLog(VOS_TRACE_LEVEL_INFO, FL("BSSID: %pM "), pReqMsg->ap[i].bssid);
3224
3225 /* Parse and fetch low RSSI */
3226 if (!tb2[QCA_WLAN_VENDOR_ATTR_EXTSCAN_AP_THRESHOLD_PARAM_RSSI_LOW]) {
3227 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr low RSSI failed"));
3228 goto fail;
3229 }
3230 pReqMsg->ap[i].low = nla_get_s32(
3231 tb2[QCA_WLAN_VENDOR_ATTR_EXTSCAN_AP_THRESHOLD_PARAM_RSSI_LOW]);
3232 hddLog(VOS_TRACE_LEVEL_INFO, FL("RSSI low (%d)"), pReqMsg->ap[i].low);
3233
3234 /* Parse and fetch high RSSI */
3235 if (!tb2[QCA_WLAN_VENDOR_ATTR_EXTSCAN_AP_THRESHOLD_PARAM_RSSI_HIGH]) {
3236 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr high RSSI failed"));
3237 goto fail;
3238 }
3239 pReqMsg->ap[i].high = nla_get_s32(
3240 tb2[QCA_WLAN_VENDOR_ATTR_EXTSCAN_AP_THRESHOLD_PARAM_RSSI_HIGH]);
3241 hddLog(VOS_TRACE_LEVEL_INFO, FL("RSSI High (%d)"),
3242 pReqMsg->ap[i].high);
3243
3244 /* Parse and fetch channel */
3245 if (!tb2[QCA_WLAN_VENDOR_ATTR_EXTSCAN_AP_THRESHOLD_PARAM_CHANNEL]) {
3246 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr channel failed"));
3247 goto fail;
3248 }
3249 pReqMsg->ap[i].channel = nla_get_u32(
3250 tb2[QCA_WLAN_VENDOR_ATTR_EXTSCAN_AP_THRESHOLD_PARAM_CHANNEL]);
3251 hddLog(VOS_TRACE_LEVEL_INFO,
3252 FL("Channel (%u)"), pReqMsg->ap[i].channel);
3253 i++;
3254 }
3255 status = sme_SetBssHotlist(pHddCtx->hHal, pReqMsg);
3256 if (!HAL_STATUS_SUCCESS(status)) {
3257 hddLog(VOS_TRACE_LEVEL_ERROR,
3258 FL("sme_SetBssHotlist failed(err=%d)"), status);
3259 vos_mem_free(pReqMsg);
3260 return -EINVAL;
3261 }
3262
Dino Myclee8843b32014-07-04 14:21:45 +05303263 vos_mem_free(pReqMsg);
3264
Dino Mycle6fb96c12014-06-10 11:52:40 +05303265 return 0;
3266
3267fail:
3268 vos_mem_free(pReqMsg);
3269 return -EINVAL;
3270}
3271
3272static int wlan_hdd_cfg80211_extscan_set_significant_change(struct wiphy *wiphy,
3273 struct wireless_dev *wdev,
3274 void *data, int dataLen)
3275{
3276 tpSirEXTScanSetSignificantChangeReqParams pReqMsg = NULL;
3277 struct net_device *dev = wdev->netdev;
3278 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
3279 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
3280 struct nlattr
3281 *tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX + 1];
3282 struct nlattr
3283 *tb2[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX + 1];
3284 struct nlattr *apTh;
3285 eHalStatus status;
3286 int i = 0;
3287 int rem;
3288
3289 status = wlan_hdd_validate_context(pHddCtx);
3290 if (0 != status)
3291 {
3292 hddLog(VOS_TRACE_LEVEL_ERROR,
3293 FL("HDD context is not valid"));
3294 return -EINVAL;
3295 }
Dino Myclee8843b32014-07-04 14:21:45 +05303296 /* check the EXTScan Capability */
3297 if ( (TRUE != pHddCtx->cfg_ini->fEnableEXTScan) ||
3298 (TRUE != sme_IsFeatureSupportedByFW(EXTENDED_SCAN)))
3299 {
3300 hddLog(VOS_TRACE_LEVEL_ERROR,
3301 FL("EXTScan not enabled/supported by Firmware"));
3302 return -EINVAL;
3303 }
3304
Dino Mycle6fb96c12014-06-10 11:52:40 +05303305 if (nla_parse(tb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX,
3306 data, dataLen,
3307 wlan_hdd_extscan_config_policy)) {
3308 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Invalid ATTR"));
3309 return -EINVAL;
3310 }
3311
3312 /* Parse and fetch request Id */
3313 if (!tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_REQUEST_ID]) {
3314 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr request id failed"));
3315 return -EINVAL;
3316 }
Dino Mycle6fb96c12014-06-10 11:52:40 +05303317 pReqMsg = (tpSirEXTScanSetSignificantChangeReqParams)
Dino Myclee8843b32014-07-04 14:21:45 +05303318 vos_mem_malloc(sizeof(*pReqMsg));
Dino Mycle6fb96c12014-06-10 11:52:40 +05303319 if (!pReqMsg) {
Dino Myclee8843b32014-07-04 14:21:45 +05303320 hddLog(VOS_TRACE_LEVEL_ERROR, FL("vos_mem_malloc failed"));
3321 return -ENOMEM;
Dino Mycle6fb96c12014-06-10 11:52:40 +05303322 }
3323
Dino Myclee8843b32014-07-04 14:21:45 +05303324
3325
Dino Mycle6fb96c12014-06-10 11:52:40 +05303326 pReqMsg->requestId = nla_get_u32(
3327 tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_REQUEST_ID]);
3328 hddLog(VOS_TRACE_LEVEL_INFO, FL("Req Id (%d)"), pReqMsg->requestId);
3329
3330 /* Parse and fetch RSSI sample size */
3331 if (!tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SIGNIFICANT_CHANGE_PARAMS_RSSI_SAMPLE_SIZE])
3332 {
3333 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr RSSI sample size failed"));
3334 goto fail;
3335 }
3336 pReqMsg->rssiSampleSize = nla_get_u32(
3337 tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SIGNIFICANT_CHANGE_PARAMS_RSSI_SAMPLE_SIZE]);
3338 hddLog(VOS_TRACE_LEVEL_INFO,
3339 FL("RSSI sample size (%u)"), pReqMsg->rssiSampleSize);
3340
3341 /* Parse and fetch lost AP sample size */
3342 if (!tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SIGNIFICANT_CHANGE_PARAMS_LOST_AP_SAMPLE_SIZE])
3343 {
3344 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr lost AP sample size failed"));
3345 goto fail;
3346 }
3347 pReqMsg->lostApSampleSize = nla_get_u32(
3348 tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SIGNIFICANT_CHANGE_PARAMS_LOST_AP_SAMPLE_SIZE]);
3349 hddLog(VOS_TRACE_LEVEL_INFO,
3350 FL("Lost AP sample size (%u)"), pReqMsg->lostApSampleSize);
3351 /* Parse and fetch minimum Breaching */
3352 if (!tb
3353 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_SIGNIFICANT_CHANGE_PARAMS_MIN_BREACHING]) {
3354 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr minBreaching failed"));
3355 goto fail;
3356 }
3357 pReqMsg->minBreaching = nla_get_u32(
3358 tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SIGNIFICANT_CHANGE_PARAMS_MIN_BREACHING]);
3359 hddLog(VOS_TRACE_LEVEL_INFO, FL(" Breaching (%d)"), pReqMsg->minBreaching);
3360
3361 /* Parse and fetch number of APs */
3362 if (!tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SIGNIFICANT_CHANGE_PARAMS_NUM_AP]) {
3363 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr number of AP failed"));
3364 goto fail;
3365 }
3366 pReqMsg->numAp = nla_get_u32(
3367 tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SIGNIFICANT_CHANGE_PARAMS_NUM_AP]);
3368 hddLog(VOS_TRACE_LEVEL_INFO, FL("Number of AP (%d)"), pReqMsg->numAp);
3369
3370 pReqMsg->sessionId = pAdapter->sessionId;
3371 hddLog(VOS_TRACE_LEVEL_INFO, FL("Session Id (%d)"), pReqMsg->sessionId);
3372
3373 nla_for_each_nested(apTh,
3374 tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_AP_THRESHOLD_PARAM], rem) {
3375 if(nla_parse(tb2,
3376 QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX,
3377 nla_data(apTh), nla_len(apTh),
3378 NULL)) {
3379 hddLog(VOS_TRACE_LEVEL_ERROR, FL("nla_parse failed"));
3380 goto fail;
3381 }
3382
3383 /* Parse and fetch MAC address */
3384 if (!tb2[QCA_WLAN_VENDOR_ATTR_EXTSCAN_AP_THRESHOLD_PARAM_BSSID]) {
3385 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr mac address failed"));
3386 goto fail;
3387 }
3388 memcpy(pReqMsg->ap[i].bssid, nla_data(
3389 tb2[QCA_WLAN_VENDOR_ATTR_EXTSCAN_AP_THRESHOLD_PARAM_BSSID]),
3390 sizeof(tSirMacAddr));
3391
3392 /* Parse and fetch low RSSI */
3393 if (!tb2[QCA_WLAN_VENDOR_ATTR_EXTSCAN_AP_THRESHOLD_PARAM_RSSI_LOW]) {
3394 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr low RSSI failed"));
3395 goto fail;
3396 }
3397 pReqMsg->ap[i].low = nla_get_s32(
3398 tb2[QCA_WLAN_VENDOR_ATTR_EXTSCAN_AP_THRESHOLD_PARAM_RSSI_LOW]);
3399 hddLog(VOS_TRACE_LEVEL_INFO, FL("RSSI low (%d)"), pReqMsg->ap[i].low);
3400
3401 /* Parse and fetch high RSSI */
3402 if (!tb2[QCA_WLAN_VENDOR_ATTR_EXTSCAN_AP_THRESHOLD_PARAM_RSSI_HIGH]) {
3403 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr high RSSI failed"));
3404 goto fail;
3405 }
3406 pReqMsg->ap[i].high = nla_get_s32(
3407 tb2[QCA_WLAN_VENDOR_ATTR_EXTSCAN_AP_THRESHOLD_PARAM_RSSI_HIGH]);
3408 hddLog(VOS_TRACE_LEVEL_INFO,
3409 FL("RSSI High (%d)"), pReqMsg->ap[i].high);
3410
3411 /* Parse and fetch channel */
3412 if (!tb2[QCA_WLAN_VENDOR_ATTR_EXTSCAN_AP_THRESHOLD_PARAM_CHANNEL]) {
3413 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr channel failed"));
3414 goto fail;
3415 }
3416 pReqMsg->ap[i].channel = nla_get_u32(
3417 tb2[QCA_WLAN_VENDOR_ATTR_EXTSCAN_AP_THRESHOLD_PARAM_CHANNEL]);
3418 hddLog(VOS_TRACE_LEVEL_INFO,
3419 FL("Channel (%u)"), pReqMsg->ap[i].channel);
3420 i++;
3421 }
3422
3423 status = sme_SetSignificantChange(pHddCtx->hHal, pReqMsg);
3424 if (!HAL_STATUS_SUCCESS(status)) {
3425 hddLog(VOS_TRACE_LEVEL_ERROR,
3426 FL("sme_SetSignificantChange failed(err=%d)"), status);
3427 vos_mem_free(pReqMsg);
3428 return -EINVAL;
3429 }
Dino Myclee8843b32014-07-04 14:21:45 +05303430 vos_mem_free(pReqMsg);
Dino Mycle6fb96c12014-06-10 11:52:40 +05303431 hddLog(VOS_TRACE_LEVEL_ERROR, FL(" Exiting"));
3432 return 0;
3433
3434fail:
3435 vos_mem_free(pReqMsg);
3436 return -EINVAL;
3437}
3438
3439static int wlan_hdd_cfg80211_extscan_get_valid_channels(struct wiphy *wiphy,
3440 struct wireless_dev *wdev,
3441 void *data, int dataLen)
3442{
3443 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
3444 tANI_U32 ChannelList[WNI_CFG_VALID_CHANNEL_LIST_LEN] = {0};
3445 tANI_U8 numChannels = 0;
3446 struct nlattr *tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX + 1];
3447 tANI_U32 requestId;
3448 tWifiBand wifiBand;
3449 eHalStatus status;
3450 struct sk_buff *replySkb;
3451 tANI_U8 i;
3452
3453 hddLog(VOS_TRACE_LEVEL_INFO, FL("Entering"));
3454 status = wlan_hdd_validate_context(pHddCtx);
3455 if (0 != status)
3456 {
3457 hddLog(VOS_TRACE_LEVEL_ERROR,
3458 FL("HDD context is not valid"));
3459 return -EINVAL;
3460 }
Dino Myclee8843b32014-07-04 14:21:45 +05303461 /* check the EXTScan Capability */
3462 if ( (TRUE != pHddCtx->cfg_ini->fEnableEXTScan) ||
3463 (TRUE != sme_IsFeatureSupportedByFW(EXTENDED_SCAN)))
3464 {
3465 hddLog(VOS_TRACE_LEVEL_ERROR,
3466 FL("EXTScan not enabled/supported by Firmware"));
3467 return -EINVAL;
3468 }
3469
Dino Mycle6fb96c12014-06-10 11:52:40 +05303470 if (nla_parse(tb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX,
3471 data, dataLen,
3472 wlan_hdd_extscan_config_policy)) {
3473 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Invalid ATTR"));
3474 return -EINVAL;
3475 }
3476
3477 /* Parse and fetch request Id */
3478 if (!tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_REQUEST_ID]) {
3479 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr request id failed"));
3480 return -EINVAL;
3481 }
3482 requestId = nla_get_u32(
3483 tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_REQUEST_ID]);
3484 hddLog(VOS_TRACE_LEVEL_INFO, FL("Req Id (%d)"), requestId);
3485
3486 /* Parse and fetch wifi band */
3487 if (!tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_GET_VALID_CHANNELS_CONFIG_PARAM_WIFI_BAND])
3488 {
3489 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr wifi band failed"));
3490 return -EINVAL;
3491 }
3492 wifiBand = nla_get_u32(
3493 tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_GET_VALID_CHANNELS_CONFIG_PARAM_WIFI_BAND]);
3494 hddLog(VOS_TRACE_LEVEL_INFO, FL("Wifi band (%d)"), wifiBand);
3495
3496 status = sme_GetValidChannelsByBand((tHalHandle)(pHddCtx->hHal),
3497 wifiBand, ChannelList,
3498 &numChannels);
3499 if (eHAL_STATUS_SUCCESS != status) {
3500 hddLog(VOS_TRACE_LEVEL_ERROR,
3501 FL("sme_GetValidChannelsByBand failed (err=%d)"), status);
3502 return -EINVAL;
3503 }
3504 hddLog(VOS_TRACE_LEVEL_INFO, FL("Number of channels (%d)"), numChannels);
3505 for (i = 0; i < numChannels; i++)
3506 hddLog(VOS_TRACE_LEVEL_INFO, "Channel: %u ", ChannelList[i]);
3507
3508 replySkb = cfg80211_vendor_cmd_alloc_reply_skb(wiphy, sizeof(u32) +
3509 sizeof(u32) * numChannels +
3510 NLMSG_HDRLEN);
3511
3512 if (!replySkb) {
3513 hddLog(VOS_TRACE_LEVEL_ERROR,
3514 FL("valid channels: buffer alloc fail"));
3515 return -EINVAL;
3516 }
3517 if (nla_put_u32(replySkb,
3518 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_NUM_CHANNELS,
3519 numChannels) ||
3520 nla_put(replySkb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_CHANNELS,
3521 sizeof(u32) * numChannels, ChannelList)) {
3522
3523 hddLog(VOS_TRACE_LEVEL_ERROR, FL("nla put fail"));
3524 kfree_skb(replySkb);
3525 return -EINVAL;
3526 }
3527
3528 return cfg80211_vendor_cmd_reply(replySkb);
3529}
3530
3531static int wlan_hdd_cfg80211_extscan_start(struct wiphy *wiphy,
3532 struct wireless_dev *wdev,
3533 void *data, int dataLen)
3534{
Dino Myclee8843b32014-07-04 14:21:45 +05303535 tpSirEXTScanStartReqParams pReqMsg = NULL;
Dino Mycle6fb96c12014-06-10 11:52:40 +05303536 struct net_device *dev = wdev->netdev;
3537 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
3538 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
3539 struct nlattr *tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX + 1];
3540 struct nlattr *bucket[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX + 1];
3541 struct nlattr *channel[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX + 1];
3542 struct nlattr *buckets;
3543 struct nlattr *channels;
3544 int rem1;
3545 int rem2;
3546 eHalStatus status;
Dasari Srinivas8b2ce272014-09-16 16:57:30 +05303547 tANI_U32 j = 0, index = 0;
Dino Mycle6fb96c12014-06-10 11:52:40 +05303548
3549 status = wlan_hdd_validate_context(pHddCtx);
3550 if (0 != status)
3551 {
3552 hddLog(VOS_TRACE_LEVEL_ERROR,
3553 FL("HDD context is not valid"));
3554 return -EINVAL;
3555 }
Dino Myclee8843b32014-07-04 14:21:45 +05303556 /* check the EXTScan Capability */
3557 if ( (TRUE != pHddCtx->cfg_ini->fEnableEXTScan) ||
3558 (TRUE != sme_IsFeatureSupportedByFW(EXTENDED_SCAN)))
3559 {
3560 hddLog(VOS_TRACE_LEVEL_ERROR,
3561 FL("EXTScan not enabled/supported by Firmware"));
3562 return -EINVAL;
3563 }
3564
Dino Mycle6fb96c12014-06-10 11:52:40 +05303565 if (nla_parse(tb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX,
3566 data, dataLen,
3567 wlan_hdd_extscan_config_policy)) {
3568 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Invalid ATTR"));
3569 return -EINVAL;
3570 }
3571
3572 /* Parse and fetch request Id */
3573 if (!tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_REQUEST_ID]) {
3574 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr request id failed"));
3575 return -EINVAL;
3576 }
3577
Dino Myclee8843b32014-07-04 14:21:45 +05303578 pReqMsg = (tpSirEXTScanStartReqParams)
3579 vos_mem_malloc(sizeof(*pReqMsg));
Dino Mycle6fb96c12014-06-10 11:52:40 +05303580 if (!pReqMsg) {
Dino Myclee8843b32014-07-04 14:21:45 +05303581 hddLog(VOS_TRACE_LEVEL_ERROR, FL("vos_mem_malloc failed"));
3582 return -ENOMEM;
Dino Mycle6fb96c12014-06-10 11:52:40 +05303583 }
3584
3585 pReqMsg->requestId = nla_get_u32(
3586 tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_REQUEST_ID]);
3587 hddLog(VOS_TRACE_LEVEL_INFO, FL("Req Id (%d)"), pReqMsg->requestId);
3588
3589 pReqMsg->sessionId = pAdapter->sessionId;
3590 hddLog(VOS_TRACE_LEVEL_INFO, FL("Session Id (%d)"), pReqMsg->sessionId);
3591
3592 /* Parse and fetch base period */
3593 if (!tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SCAN_CMD_PARAMS_BASE_PERIOD]) {
3594 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr base period failed"));
3595 goto fail;
3596 }
3597 pReqMsg->basePeriod = nla_get_u32(
3598 tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SCAN_CMD_PARAMS_BASE_PERIOD]);
3599 hddLog(VOS_TRACE_LEVEL_INFO, FL("Base Period (%d)"),
3600 pReqMsg->basePeriod);
3601
3602 /* Parse and fetch max AP per scan */
3603 if (!tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SCAN_CMD_PARAMS_MAX_AP_PER_SCAN]) {
3604 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr max_ap_per_scan failed"));
3605 goto fail;
3606 }
3607 pReqMsg->maxAPperScan = nla_get_u32(
3608 tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SCAN_CMD_PARAMS_MAX_AP_PER_SCAN]);
3609 hddLog(VOS_TRACE_LEVEL_INFO, FL("Max AP per Scan (%d)"),
3610 pReqMsg->maxAPperScan);
3611
3612 /* Parse and fetch report threshold */
3613 if (!tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SCAN_CMD_PARAMS_REPORT_THRESHOLD]) {
3614 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr report_threshold failed"));
3615 goto fail;
3616 }
3617 pReqMsg->reportThreshold = nla_get_u8(
3618 tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SCAN_CMD_PARAMS_REPORT_THRESHOLD]);
3619 hddLog(VOS_TRACE_LEVEL_INFO, FL("Report Threshold (%d)"),
3620 pReqMsg->reportThreshold);
3621
3622 /* Parse and fetch number of buckets */
3623 if (!tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SCAN_CMD_PARAMS_NUM_BUCKETS]) {
3624 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr number of buckets failed"));
3625 goto fail;
3626 }
3627 pReqMsg->numBuckets = nla_get_u8(
3628 tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SCAN_CMD_PARAMS_NUM_BUCKETS]);
3629 if (pReqMsg->numBuckets > WLAN_EXTSCAN_MAX_BUCKETS) {
3630 hddLog(VOS_TRACE_LEVEL_WARN, FL("Exceeded MAX number of buckets "
3631 "Setting numBuckets to %u"), WLAN_EXTSCAN_MAX_BUCKETS);
3632 pReqMsg->numBuckets = WLAN_EXTSCAN_MAX_BUCKETS;
3633 }
3634 hddLog(VOS_TRACE_LEVEL_INFO, FL("Number of Buckets (%d)"),
3635 pReqMsg->numBuckets);
3636 if (!tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC]) {
3637 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr bucket spec failed"));
3638 goto fail;
3639 }
3640
3641 nla_for_each_nested(buckets,
3642 tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC], rem1) {
3643 if(nla_parse(bucket,
3644 QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX,
3645 nla_data(buckets), nla_len(buckets), NULL)) { //policy
3646 hddLog(VOS_TRACE_LEVEL_ERROR, FL("nla_parse failed"));
3647 goto fail;
3648 }
3649
3650 /* Parse and fetch bucket spec */
3651 if (!bucket[QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_INDEX]) {
3652 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr bucket index failed"));
3653 goto fail;
3654 }
Dasari Srinivas8b2ce272014-09-16 16:57:30 +05303655
3656 pReqMsg->buckets[index].bucket = nla_get_u8(
3657 bucket[QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_INDEX]);
3658
3659 hddLog(VOS_TRACE_LEVEL_INFO, FL("Bucket spec Index (%d)"),
3660 pReqMsg->buckets[index].bucket);
Dino Mycle6fb96c12014-06-10 11:52:40 +05303661
3662 /* Parse and fetch wifi band */
3663 if (!bucket[QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_BAND]) {
3664 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr wifi band failed"));
3665 goto fail;
3666 }
Dasari Srinivas8b2ce272014-09-16 16:57:30 +05303667 pReqMsg->buckets[index].band = nla_get_u8(
Dino Mycle6fb96c12014-06-10 11:52:40 +05303668 bucket[QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_BAND]);
3669 hddLog(VOS_TRACE_LEVEL_INFO, FL("Wifi band (%d)"),
Dasari Srinivas8b2ce272014-09-16 16:57:30 +05303670 pReqMsg->buckets[index].band);
Dino Mycle6fb96c12014-06-10 11:52:40 +05303671
3672 /* Parse and fetch period */
3673 if (!bucket[QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_PERIOD]) {
3674 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr period failed"));
3675 goto fail;
3676 }
Dasari Srinivas8b2ce272014-09-16 16:57:30 +05303677 pReqMsg->buckets[index].period = nla_get_u32(
Dino Mycle6fb96c12014-06-10 11:52:40 +05303678 bucket[QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_PERIOD]);
3679 hddLog(VOS_TRACE_LEVEL_INFO, FL("period (%d)"),
Dasari Srinivas8b2ce272014-09-16 16:57:30 +05303680 pReqMsg->buckets[index].period);
Dino Mycle6fb96c12014-06-10 11:52:40 +05303681
3682 /* Parse and fetch report events */
3683 if (!bucket[QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_REPORT_EVENTS]) {
3684 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr report events failed"));
3685 goto fail;
3686 }
Dasari Srinivas8b2ce272014-09-16 16:57:30 +05303687 pReqMsg->buckets[index].reportEvents = nla_get_u8(
Dino Mycle6fb96c12014-06-10 11:52:40 +05303688 bucket[QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_REPORT_EVENTS]);
3689 hddLog(VOS_TRACE_LEVEL_INFO, FL("report events (%d)"),
Dasari Srinivas8b2ce272014-09-16 16:57:30 +05303690 pReqMsg->buckets[index].reportEvents);
Dino Mycle6fb96c12014-06-10 11:52:40 +05303691
3692 /* Parse and fetch number of channels */
Dasari Srinivas8b2ce272014-09-16 16:57:30 +05303693 if (!bucket[QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_NUM_CHANNEL_SPECS])
3694 {
Dino Mycle6fb96c12014-06-10 11:52:40 +05303695 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr num channels failed"));
3696 goto fail;
3697 }
Dasari Srinivas8b2ce272014-09-16 16:57:30 +05303698 pReqMsg->buckets[index].numChannels = nla_get_u32(
Dino Mycle6fb96c12014-06-10 11:52:40 +05303699 bucket[QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_NUM_CHANNEL_SPECS]);
3700 hddLog(VOS_TRACE_LEVEL_INFO, FL("num channels (%d)"),
Dasari Srinivas8b2ce272014-09-16 16:57:30 +05303701 pReqMsg->buckets[index].numChannels);
Dino Mycle6fb96c12014-06-10 11:52:40 +05303702
3703 if (!bucket[QCA_WLAN_VENDOR_ATTR_EXTSCAN_CHANNEL_SPEC]) {
3704 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr channel spec failed"));
3705 goto fail;
3706 }
3707
3708 j = 0;
3709 nla_for_each_nested(channels,
3710 bucket[QCA_WLAN_VENDOR_ATTR_EXTSCAN_CHANNEL_SPEC], rem2) {
3711 if(nla_parse(channel,
3712 QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX,
3713 nla_data(channels), nla_len(channels),
3714 NULL)) { //wlan_hdd_extscan_config_policy here
3715 hddLog(VOS_TRACE_LEVEL_ERROR, FL("nla_parse failed"));
3716 goto fail;
3717 }
3718
3719 /* Parse and fetch channel */
3720 if (!channel[QCA_WLAN_VENDOR_ATTR_EXTSCAN_CHANNEL_SPEC_CHANNEL]) {
3721 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr channel failed"));
3722 goto fail;
3723 }
Dasari Srinivas8b2ce272014-09-16 16:57:30 +05303724 pReqMsg->buckets[index].channels[j].channel = nla_get_u32(
Dino Mycle6fb96c12014-06-10 11:52:40 +05303725 channel[QCA_WLAN_VENDOR_ATTR_EXTSCAN_CHANNEL_SPEC_CHANNEL]);
3726 hddLog(VOS_TRACE_LEVEL_INFO, FL("channel (%u)"),
Dasari Srinivas8b2ce272014-09-16 16:57:30 +05303727 pReqMsg->buckets[index].channels[j].channel);
Dino Mycle6fb96c12014-06-10 11:52:40 +05303728
3729 /* Parse and fetch dwell time */
3730 if (!channel[QCA_WLAN_VENDOR_ATTR_EXTSCAN_CHANNEL_SPEC_DWELL_TIME]) {
3731 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr dwelltime failed"));
3732 goto fail;
3733 }
Dasari Srinivas8b2ce272014-09-16 16:57:30 +05303734 pReqMsg->buckets[index].channels[j].dwellTimeMs = nla_get_u32(
Dino Mycle6fb96c12014-06-10 11:52:40 +05303735 channel[QCA_WLAN_VENDOR_ATTR_EXTSCAN_CHANNEL_SPEC_DWELL_TIME]);
3736 hddLog(VOS_TRACE_LEVEL_INFO, FL("Dwell time (%u ms)"),
Dasari Srinivas8b2ce272014-09-16 16:57:30 +05303737 pReqMsg->buckets[index].channels[j].dwellTimeMs);
Dino Mycle6fb96c12014-06-10 11:52:40 +05303738
3739 /* Parse and fetch channel spec passive */
3740 if (!channel[QCA_WLAN_VENDOR_ATTR_EXTSCAN_CHANNEL_SPEC_PASSIVE]) {
3741 hddLog(VOS_TRACE_LEVEL_ERROR,
3742 FL("attr channel spec passive failed"));
3743 goto fail;
3744 }
Dasari Srinivas8b2ce272014-09-16 16:57:30 +05303745 pReqMsg->buckets[index].channels[j].passive = nla_get_u8(
Dino Mycle6fb96c12014-06-10 11:52:40 +05303746 channel[QCA_WLAN_VENDOR_ATTR_EXTSCAN_CHANNEL_SPEC_PASSIVE]);
3747 hddLog(VOS_TRACE_LEVEL_INFO, FL("Chnl spec passive (%u)"),
Dasari Srinivas8b2ce272014-09-16 16:57:30 +05303748 pReqMsg->buckets[index].channels[j].passive);
Dino Mycle6fb96c12014-06-10 11:52:40 +05303749 j++;
3750 }
Dasari Srinivas8b2ce272014-09-16 16:57:30 +05303751 index++;
Dino Mycle6fb96c12014-06-10 11:52:40 +05303752 }
3753 status = sme_EXTScanStart(pHddCtx->hHal, pReqMsg);
3754 if (!HAL_STATUS_SUCCESS(status)) {
3755 hddLog(VOS_TRACE_LEVEL_ERROR,
3756 FL("sme_EXTScanStart failed(err=%d)"), status);
3757 vos_mem_free(pReqMsg);
3758 return -EINVAL;
3759 }
3760
Dino Myclee8843b32014-07-04 14:21:45 +05303761 vos_mem_free(pReqMsg);
Dino Mycle6fb96c12014-06-10 11:52:40 +05303762 return 0;
3763
3764fail:
3765 vos_mem_free(pReqMsg);
3766 return -EINVAL;
3767}
3768
3769static int wlan_hdd_cfg80211_extscan_stop(struct wiphy *wiphy,
3770 struct wireless_dev *wdev,
3771 void *data, int dataLen)
3772{
Dino Myclee8843b32014-07-04 14:21:45 +05303773 tSirEXTScanStopReqParams reqMsg;
Dino Mycle6fb96c12014-06-10 11:52:40 +05303774 struct net_device *dev = wdev->netdev;
3775 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
3776 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
3777 struct nlattr *tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX + 1];
3778 eHalStatus status;
3779
3780 status = wlan_hdd_validate_context(pHddCtx);
3781 if (0 != status)
3782 {
3783 hddLog(VOS_TRACE_LEVEL_ERROR,
3784 FL("HDD context is not valid"));
3785 return -EINVAL;
3786 }
Dino Myclee8843b32014-07-04 14:21:45 +05303787 /* check the EXTScan Capability */
3788 if ( (TRUE != pHddCtx->cfg_ini->fEnableEXTScan) ||
3789 (TRUE != sme_IsFeatureSupportedByFW(EXTENDED_SCAN)))
3790 {
3791 hddLog(VOS_TRACE_LEVEL_ERROR,
3792 FL("EXTScan not enabled/supported by Firmware"));
3793 return -EINVAL;
3794 }
3795
Dino Mycle6fb96c12014-06-10 11:52:40 +05303796 if (nla_parse(tb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX,
3797 data, dataLen,
3798 wlan_hdd_extscan_config_policy)) {
3799 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Invalid ATTR"));
3800 return -EINVAL;
3801 }
3802
3803 /* Parse and fetch request Id */
3804 if (!tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_REQUEST_ID]) {
3805 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr request id failed"));
3806 return -EINVAL;
3807 }
3808
Dino Myclee8843b32014-07-04 14:21:45 +05303809 reqMsg.requestId = nla_get_u32(
Dino Mycle6fb96c12014-06-10 11:52:40 +05303810 tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_REQUEST_ID]);
Dino Myclee8843b32014-07-04 14:21:45 +05303811 hddLog(VOS_TRACE_LEVEL_INFO, FL("Req Id (%d)"), reqMsg.requestId);
Dino Mycle6fb96c12014-06-10 11:52:40 +05303812
Dino Myclee8843b32014-07-04 14:21:45 +05303813 reqMsg.sessionId = pAdapter->sessionId;
3814 hddLog(VOS_TRACE_LEVEL_INFO, FL("Session Id (%d)"), reqMsg.sessionId);
Dino Mycle6fb96c12014-06-10 11:52:40 +05303815
Dino Myclee8843b32014-07-04 14:21:45 +05303816 status = sme_EXTScanStop(pHddCtx->hHal, &reqMsg);
Dino Mycle6fb96c12014-06-10 11:52:40 +05303817 if (!HAL_STATUS_SUCCESS(status)) {
3818 hddLog(VOS_TRACE_LEVEL_ERROR,
3819 FL("sme_EXTScanStop failed(err=%d)"), status);
Dino Mycle6fb96c12014-06-10 11:52:40 +05303820 return -EINVAL;
3821 }
3822
3823 return 0;
3824}
3825
3826static int wlan_hdd_cfg80211_extscan_reset_bssid_hotlist(struct wiphy *wiphy,
3827 struct wireless_dev *wdev,
3828 void *data, int dataLen)
3829{
Dino Myclee8843b32014-07-04 14:21:45 +05303830 tSirEXTScanResetBssidHotlistReqParams reqMsg;
Dino Mycle6fb96c12014-06-10 11:52:40 +05303831 struct net_device *dev = wdev->netdev;
3832 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
3833 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
3834 struct nlattr *tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX + 1];
3835 eHalStatus status;
3836
3837 status = wlan_hdd_validate_context(pHddCtx);
3838 if (0 != status)
3839 {
3840 hddLog(VOS_TRACE_LEVEL_ERROR,
3841 FL("HDD context is not valid"));
3842 return -EINVAL;
3843 }
Dino Myclee8843b32014-07-04 14:21:45 +05303844 /* check the EXTScan Capability */
3845 if ( (TRUE != pHddCtx->cfg_ini->fEnableEXTScan) ||
3846 (TRUE != sme_IsFeatureSupportedByFW(EXTENDED_SCAN)))
3847 {
3848 hddLog(VOS_TRACE_LEVEL_ERROR,
3849 FL("EXTScan not enabled/supported by Firmware"));
3850 return -EINVAL;
3851 }
3852
Dino Mycle6fb96c12014-06-10 11:52:40 +05303853 if (nla_parse(tb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX,
3854 data, dataLen,
3855 wlan_hdd_extscan_config_policy)) {
3856 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Invalid ATTR"));
3857 return -EINVAL;
3858 }
3859
3860 /* Parse and fetch request Id */
3861 if (!tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_REQUEST_ID]) {
3862 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr request id failed"));
3863 return -EINVAL;
3864 }
3865
Dino Myclee8843b32014-07-04 14:21:45 +05303866 reqMsg.requestId = nla_get_u32(
Dino Mycle6fb96c12014-06-10 11:52:40 +05303867 tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_REQUEST_ID]);
Dino Myclee8843b32014-07-04 14:21:45 +05303868 hddLog(VOS_TRACE_LEVEL_INFO, FL("Req Id (%d)"), reqMsg.requestId);
Dino Mycle6fb96c12014-06-10 11:52:40 +05303869
Dino Myclee8843b32014-07-04 14:21:45 +05303870 reqMsg.sessionId = pAdapter->sessionId;
3871 hddLog(VOS_TRACE_LEVEL_INFO, FL("Session Id (%d)"), reqMsg.sessionId);
Dino Mycle6fb96c12014-06-10 11:52:40 +05303872
Dino Myclee8843b32014-07-04 14:21:45 +05303873 status = sme_ResetBssHotlist(pHddCtx->hHal, &reqMsg);
Dino Mycle6fb96c12014-06-10 11:52:40 +05303874 if (!HAL_STATUS_SUCCESS(status)) {
3875 hddLog(VOS_TRACE_LEVEL_ERROR,
3876 FL("sme_ResetBssHotlist failed(err=%d)"), status);
Dino Mycle6fb96c12014-06-10 11:52:40 +05303877 return -EINVAL;
3878 }
3879
3880 return 0;
3881}
3882
3883static int wlan_hdd_cfg80211_extscan_reset_significant_change(
3884 struct wiphy *wiphy,
3885 struct wireless_dev *wdev,
3886 void *data, int dataLen)
3887{
Dino Myclee8843b32014-07-04 14:21:45 +05303888 tSirEXTScanResetSignificantChangeReqParams reqMsg;
Dino Mycle6fb96c12014-06-10 11:52:40 +05303889 struct net_device *dev = wdev->netdev;
3890 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
3891 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
3892 struct nlattr *tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX + 1];
3893 eHalStatus status;
3894
3895 hddLog(VOS_TRACE_LEVEL_INFO, FL(" Entering"));
3896 status = wlan_hdd_validate_context(pHddCtx);
3897 if (0 != status)
3898 {
3899 hddLog(VOS_TRACE_LEVEL_ERROR,
3900 FL("HDD context is not valid"));
3901 return -EINVAL;
3902 }
Dino Myclee8843b32014-07-04 14:21:45 +05303903 /* check the EXTScan Capability */
3904 if ( (TRUE != pHddCtx->cfg_ini->fEnableEXTScan) ||
3905 (TRUE != sme_IsFeatureSupportedByFW(EXTENDED_SCAN)))
3906 {
3907 hddLog(VOS_TRACE_LEVEL_ERROR,
3908 FL("EXTScan not enabled/supported by Firmware"));
3909 return -EINVAL;
3910 }
3911
Dino Mycle6fb96c12014-06-10 11:52:40 +05303912 if (nla_parse(tb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX,
3913 data, dataLen,
3914 wlan_hdd_extscan_config_policy)) {
3915 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Invalid ATTR"));
3916 return -EINVAL;
3917 }
3918
3919 /* Parse and fetch request Id */
3920 if (!tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_REQUEST_ID]) {
3921 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr request id failed"));
3922 return -EINVAL;
3923 }
3924
Dino Mycle6fb96c12014-06-10 11:52:40 +05303925
Dino Myclee8843b32014-07-04 14:21:45 +05303926 reqMsg.requestId = nla_get_u32(
Dino Mycle6fb96c12014-06-10 11:52:40 +05303927 tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_REQUEST_ID]);
Dino Myclee8843b32014-07-04 14:21:45 +05303928 hddLog(VOS_TRACE_LEVEL_INFO, FL("Req Id (%d)"), reqMsg.requestId);
Dino Mycle6fb96c12014-06-10 11:52:40 +05303929
Dino Myclee8843b32014-07-04 14:21:45 +05303930 reqMsg.sessionId = pAdapter->sessionId;
3931 hddLog(VOS_TRACE_LEVEL_INFO, FL("Session Id (%d)"), reqMsg.sessionId);
Dino Mycle6fb96c12014-06-10 11:52:40 +05303932
Dino Myclee8843b32014-07-04 14:21:45 +05303933 status = sme_ResetSignificantChange(pHddCtx->hHal, &reqMsg);
Dino Mycle6fb96c12014-06-10 11:52:40 +05303934 if (!HAL_STATUS_SUCCESS(status)) {
3935 hddLog(VOS_TRACE_LEVEL_ERROR,
3936 FL("sme_ResetSignificantChange failed(err=%d)"), status);
Dino Mycle6fb96c12014-06-10 11:52:40 +05303937 return -EINVAL;
3938 }
3939
3940 hddLog(VOS_TRACE_LEVEL_ERROR, FL(" Exiting"));
3941 return 0;
3942}
3943
3944#endif /* WLAN_FEATURE_EXTSCAN */
3945
Atul Mittal115287b2014-07-08 13:26:33 +05303946/*EXT TDLS*/
3947static const struct nla_policy
3948wlan_hdd_tdls_config_enable_policy[QCA_WLAN_VENDOR_ATTR_TDLS_ENABLE_MAX +1] =
3949{
3950 [QCA_WLAN_VENDOR_ATTR_TDLS_ENABLE_MAC_ADDR] = {.type = NLA_UNSPEC },
3951 [QCA_WLAN_VENDOR_ATTR_TDLS_ENABLE_CHANNEL] = {.type = NLA_S32 },
3952 [QCA_WLAN_VENDOR_ATTR_TDLS_ENABLE_GLOBAL_OPERATING_CLASS] =
3953 {.type = NLA_S32 },
3954 [QCA_WLAN_VENDOR_ATTR_TDLS_ENABLE_MAX_LATENCY_MS] = {.type = NLA_S32 },
3955 [QCA_WLAN_VENDOR_ATTR_TDLS_ENABLE_MIN_BANDWIDTH_KBPS] = {.type = NLA_S32 },
3956
3957};
3958
3959static const struct nla_policy
3960wlan_hdd_tdls_config_disable_policy[QCA_WLAN_VENDOR_ATTR_TDLS_DISABLE_MAX +1] =
3961{
3962 [QCA_WLAN_VENDOR_ATTR_TDLS_DISABLE_MAC_ADDR] = {.type = NLA_UNSPEC },
3963
3964};
3965
3966static const struct nla_policy
3967wlan_hdd_tdls_config_state_change_policy[
3968 QCA_WLAN_VENDOR_ATTR_TDLS_STATE_MAX +1] =
3969{
3970 [QCA_WLAN_VENDOR_ATTR_TDLS_STATE_MAC_ADDR] = {.type = NLA_UNSPEC },
3971 [QCA_WLAN_VENDOR_ATTR_TDLS_NEW_STATE] = {.type = NLA_S32 },
3972 [QCA_WLAN_VENDOR_ATTR_TDLS_STATE_REASON] = {.type = NLA_S32 },
Atul Mittal0a9f68d2014-10-16 15:26:38 +05303973 [QCA_WLAN_VENDOR_ATTR_TDLS_STATE_CHANNEL] = {.type = NLA_S32 },
3974 [QCA_WLAN_VENDOR_ATTR_TDLS_STATE_GLOBAL_OPERATING_CLASS] =
3975 {.type = NLA_S32 },
Atul Mittal115287b2014-07-08 13:26:33 +05303976
3977};
3978
3979static const struct nla_policy
3980wlan_hdd_tdls_config_get_status_policy[
3981 QCA_WLAN_VENDOR_ATTR_TDLS_GET_STATUS_MAX +1] =
3982{
3983 [QCA_WLAN_VENDOR_ATTR_TDLS_GET_STATUS_MAC_ADDR] = {.type = NLA_UNSPEC },
3984 [QCA_WLAN_VENDOR_ATTR_TDLS_GET_STATUS_STATE] = {.type = NLA_S32 },
3985 [QCA_WLAN_VENDOR_ATTR_TDLS_GET_STATUS_REASON] = {.type = NLA_S32 },
Atul Mittal0a9f68d2014-10-16 15:26:38 +05303986 [QCA_WLAN_VENDOR_ATTR_TDLS_GET_STATUS_CHANNEL] = {.type = NLA_S32 },
3987 [QCA_WLAN_VENDOR_ATTR_TDLS_GET_STATUS_GLOBAL_OPERATING_CLASS]
3988 = {.type = NLA_S32 },
Atul Mittal115287b2014-07-08 13:26:33 +05303989
3990};
Siddharth Bhala3a5cb42014-09-29 21:13:13 +05303991
3992static const struct nla_policy
3993wlan_hdd_mac_config[QCA_WLAN_VENDOR_ATTR_SET_SCANNING_MAC_OUI_MAX+1] =
3994{
3995 [QCA_WLAN_VENDOR_ATTR_SET_SCANNING_MAC_OUI] = {.type = NLA_UNSPEC },
3996};
3997
3998static int wlan_hdd_cfg80211_set_spoofed_mac_oui(struct wiphy *wiphy,
3999 struct wireless_dev *wdev,
4000 void *data,
4001 int data_len)
4002{
4003
4004 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
4005 struct nlattr *tb[QCA_WLAN_VENDOR_ATTR_SET_SCANNING_MAC_OUI_MAX + 1];
4006
4007 if (0 != wlan_hdd_validate_context(pHddCtx)){
4008 hddLog(VOS_TRACE_LEVEL_ERROR, FL("hdd Ctx invalid while spoof macAddr"));
4009 return -EINVAL;
4010 }
4011 if (FALSE == pHddCtx->cfg_ini->enableMacSpoofing) {
4012 hddLog(VOS_TRACE_LEVEL_ERROR, FL("MAC_SPOOFED_SCAN disabled in ini"));
4013 return -ENOTSUPP;
Siddharth Bhal76972212014-10-15 16:22:51 +05304014 }
Siddharth Bhala3a5cb42014-09-29 21:13:13 +05304015 if (TRUE != sme_IsFeatureSupportedByFW(MAC_SPOOFED_SCAN)){
4016 hddLog(VOS_TRACE_LEVEL_ERROR, FL("MAC_SPOOFED_SCAN not supported by FW"));
4017 return -ENOTSUPP;
4018 }
4019
4020 if (nla_parse(tb, QCA_WLAN_VENDOR_ATTR_SET_SCANNING_MAC_OUI_MAX,
4021 data, data_len, wlan_hdd_mac_config)) {
4022 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Invalid ATTR"));
4023 return -EINVAL;
4024 }
4025
4026 /* Parse and fetch mac address */
4027 if (!tb[QCA_WLAN_VENDOR_ATTR_SET_SCANNING_MAC_OUI]) {
4028 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr mac addr failed"));
4029 return -EINVAL;
4030 }
4031
4032 memcpy(pHddCtx->spoofMacAddr.randomMacAddr.bytes, nla_data(
4033 tb[QCA_WLAN_VENDOR_ATTR_SET_SCANNING_MAC_OUI]),
4034 VOS_MAC_ADDR_LAST_3_BYTES);
4035
Siddharth Bhal76972212014-10-15 16:22:51 +05304036 pHddCtx->spoofMacAddr.isEnabled = TRUE;
4037
4038 vos_trace_hex_dump( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO, nla_data(
Siddharth Bhala3a5cb42014-09-29 21:13:13 +05304039 tb[QCA_WLAN_VENDOR_ATTR_SET_SCANNING_MAC_OUI]),
4040 VOS_MAC_ADDR_FIRST_3_BYTES);
Siddharth Bhal76972212014-10-15 16:22:51 +05304041 if ((pHddCtx->spoofMacAddr.randomMacAddr.bytes[0] == 0) &&
4042 (pHddCtx->spoofMacAddr.randomMacAddr.bytes[1] == 0) &&
4043 (pHddCtx->spoofMacAddr.randomMacAddr.bytes[2] == 0))
4044 {
4045 hddLog(LOG1, FL("ZERO MAC OUI Recieved. Disabling Spoofing"));
4046 vos_mem_zero(pHddCtx->spoofMacAddr.randomMacAddr.bytes,
4047 VOS_MAC_ADDRESS_LEN);
4048 pHddCtx->spoofMacAddr.isEnabled = FALSE;
Siddharth Bhala3a5cb42014-09-29 21:13:13 +05304049 }
Siddharth Bhala3a5cb42014-09-29 21:13:13 +05304050
Siddharth Bhal76972212014-10-15 16:22:51 +05304051 if (VOS_STATUS_SUCCESS != hdd_processSpoofMacAddrRequest(pHddCtx))
4052 {
Siddharth Bhala3a5cb42014-09-29 21:13:13 +05304053 hddLog(LOGE, FL("Failed to send Spoof Mac Addr to FW"));
4054 }
4055
4056 return 0;
4057}
4058
Atul Mittal115287b2014-07-08 13:26:33 +05304059static int wlan_hdd_cfg80211_exttdls_get_status(struct wiphy *wiphy,
4060 struct wireless_dev *wdev,
4061 void *data,
4062 int data_len)
4063{
4064 u8 peer[6] = {0};
4065 struct net_device *dev = wdev->netdev;
4066 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
4067 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
4068 struct nlattr *tb[QCA_WLAN_VENDOR_ATTR_TDLS_GET_STATUS_MAX + 1];
4069 eHalStatus ret;
4070 tANI_S32 state;
4071 tANI_S32 reason;
Atul Mittal0a9f68d2014-10-16 15:26:38 +05304072 tANI_S32 global_operating_class = 0;
4073 tANI_S32 channel = 0;
Atul Mittal115287b2014-07-08 13:26:33 +05304074 struct sk_buff *skb = NULL;
4075
4076 ret = wlan_hdd_validate_context(pHddCtx);
4077 if (0 != ret) {
4078
4079 return -EINVAL;
4080 }
4081 if (pHddCtx->cfg_ini->fTDLSExternalControl == FALSE) {
4082
4083 return -ENOTSUPP;
4084 }
4085 if (nla_parse(tb, QCA_WLAN_VENDOR_ATTR_TDLS_GET_STATUS_MAX,
4086 data, data_len,
4087 wlan_hdd_tdls_config_get_status_policy)) {
4088 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Invalid ATTR"));
4089 return -EINVAL;
4090 }
4091
4092 /* Parse and fetch mac address */
4093 if (!tb[QCA_WLAN_VENDOR_ATTR_TDLS_GET_STATUS_MAC_ADDR]) {
4094 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr mac addr failed"));
4095 return -EINVAL;
4096 }
4097
4098 memcpy(peer, nla_data(
4099 tb[QCA_WLAN_VENDOR_ATTR_TDLS_GET_STATUS_MAC_ADDR]),
4100 sizeof(peer));
4101 hddLog(VOS_TRACE_LEVEL_INFO, FL(MAC_ADDRESS_STR),MAC_ADDR_ARRAY(peer));
4102
4103 ret = wlan_hdd_tdls_get_status(pAdapter, peer, &state, &reason);
4104
4105 if (0 != ret) {
4106 hddLog(VOS_TRACE_LEVEL_ERROR,
4107 FL("get status Failed"));
4108 return -EINVAL;
4109 }
4110 skb = cfg80211_vendor_cmd_alloc_reply_skb(wiphy,
Atul Mittal0a9f68d2014-10-16 15:26:38 +05304111 4 * sizeof(s32) +
Atul Mittal115287b2014-07-08 13:26:33 +05304112 NLMSG_HDRLEN);
4113
4114 if (!skb) {
4115 hddLog(VOS_TRACE_LEVEL_ERROR,
4116 FL("cfg80211_vendor_cmd_alloc_reply_skb failed"));
4117 return -EINVAL;
4118 }
Atul Mittal0a9f68d2014-10-16 15:26:38 +05304119 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 +05304120 reason,
4121 state,
Atul Mittal0a9f68d2014-10-16 15:26:38 +05304122 global_operating_class,
4123 channel,
Atul Mittal115287b2014-07-08 13:26:33 +05304124 MAC_ADDR_ARRAY(peer));
Atul Mittal0a9f68d2014-10-16 15:26:38 +05304125 if (nla_put_s32(skb,
4126 QCA_WLAN_VENDOR_ATTR_TDLS_GET_STATUS_STATE,
4127 state) ||
4128 nla_put_s32(skb,
4129 QCA_WLAN_VENDOR_ATTR_TDLS_GET_STATUS_REASON,
4130 reason) ||
4131 nla_put_s32(skb,
4132 QCA_WLAN_VENDOR_ATTR_TDLS_GET_STATUS_GLOBAL_OPERATING_CLASS,
4133 global_operating_class) ||
4134 nla_put_s32(skb,
4135 QCA_WLAN_VENDOR_ATTR_TDLS_GET_STATUS_CHANNEL,
4136 channel)) {
Atul Mittal115287b2014-07-08 13:26:33 +05304137
4138 hddLog(VOS_TRACE_LEVEL_ERROR, FL("nla put fail"));
4139 goto nla_put_failure;
4140 }
4141
4142 return cfg80211_vendor_cmd_reply(skb);
4143
4144nla_put_failure:
4145 kfree_skb(skb);
4146 return -EINVAL;
4147}
4148
4149static int wlan_hdd_cfg80211_exttdls_callback(tANI_U8* mac,
4150 tANI_S32 state,
4151 tANI_S32 reason,
4152 void *ctx)
4153{
4154 hdd_adapter_t* pAdapter = (hdd_adapter_t*)ctx;
4155 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
4156 struct sk_buff *skb = NULL;
Atul Mittal0a9f68d2014-10-16 15:26:38 +05304157 tANI_S32 global_operating_class = 0;
4158 tANI_S32 channel = 0;
Atul Mittal115287b2014-07-08 13:26:33 +05304159
4160 if (wlan_hdd_validate_context(pHddCtx)) {
4161 hddLog(VOS_TRACE_LEVEL_ERROR, FL("HDD context is not valid "));
4162 return -EINVAL;
4163 }
4164
4165 if (pHddCtx->cfg_ini->fTDLSExternalControl == FALSE) {
4166
4167 return -ENOTSUPP;
4168 }
4169 skb = cfg80211_vendor_event_alloc(
4170 pHddCtx->wiphy,
4171 EXTTDLS_EVENT_BUF_SIZE + NLMSG_HDRLEN,
4172 QCA_NL80211_VENDOR_SUBCMD_TDLS_STATE_CHANGE_INDEX,
4173 GFP_KERNEL);
4174
4175 if (!skb) {
4176 hddLog(VOS_TRACE_LEVEL_ERROR,
4177 FL("cfg80211_vendor_event_alloc failed"));
4178 return -EINVAL;
4179 }
4180 hddLog(VOS_TRACE_LEVEL_INFO, FL("Entering "));
Atul Mittal0a9f68d2014-10-16 15:26:38 +05304181 hddLog(VOS_TRACE_LEVEL_INFO, "Reason: (%d) Status: (%d) Class: (%d) Channel: (%d)",
4182 reason,
4183 state,
4184 global_operating_class,
4185 channel);
Atul Mittal115287b2014-07-08 13:26:33 +05304186 hddLog(VOS_TRACE_LEVEL_WARN, "tdls peer " MAC_ADDRESS_STR,
4187 MAC_ADDR_ARRAY(mac));
4188
Atul Mittal0a9f68d2014-10-16 15:26:38 +05304189 if (nla_put(skb,
4190 QCA_WLAN_VENDOR_ATTR_TDLS_STATE_MAC_ADDR,
4191 VOS_MAC_ADDR_SIZE, mac) ||
4192 nla_put_s32(skb,
4193 QCA_WLAN_VENDOR_ATTR_TDLS_NEW_STATE,
4194 state) ||
4195 nla_put_s32(skb,
4196 QCA_WLAN_VENDOR_ATTR_TDLS_STATE_REASON,
4197 reason) ||
4198 nla_put_s32(skb,
4199 QCA_WLAN_VENDOR_ATTR_TDLS_STATE_CHANNEL,
4200 channel) ||
4201 nla_put_s32(skb,
4202 QCA_WLAN_VENDOR_ATTR_TDLS_STATE_GLOBAL_OPERATING_CLASS,
4203 global_operating_class)
4204 ) {
Atul Mittal115287b2014-07-08 13:26:33 +05304205 hddLog(VOS_TRACE_LEVEL_ERROR, FL("nla put fail"));
4206 goto nla_put_failure;
4207 }
4208
4209 cfg80211_vendor_event(skb, GFP_KERNEL);
4210 return (0);
4211
4212nla_put_failure:
4213 kfree_skb(skb);
4214 return -EINVAL;
4215}
4216
4217static int wlan_hdd_cfg80211_exttdls_enable(struct wiphy *wiphy,
4218 struct wireless_dev *wdev,
4219 void *data,
4220 int data_len)
4221{
4222 u8 peer[6] = {0};
4223 struct net_device *dev = wdev->netdev;
4224 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
4225 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
4226 struct nlattr *tb[QCA_WLAN_VENDOR_ATTR_TDLS_ENABLE_MAX + 1];
4227 eHalStatus status;
4228 tdls_req_params_t pReqMsg = {0};
4229
4230 status = wlan_hdd_validate_context(pHddCtx);
4231 if (0 != status) {
4232 hddLog(VOS_TRACE_LEVEL_ERROR,
4233 FL("HDD context is not valid"));
4234 return -EINVAL;
4235 }
4236 if (pHddCtx->cfg_ini->fTDLSExternalControl == FALSE) {
4237
4238 return -ENOTSUPP;
4239 }
4240 if (nla_parse(tb, QCA_WLAN_VENDOR_ATTR_TDLS_ENABLE_MAX,
4241 data, data_len,
4242 wlan_hdd_tdls_config_enable_policy)) {
4243 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Invalid ATTR"));
4244 return -EINVAL;
4245 }
4246
4247 /* Parse and fetch mac address */
4248 if (!tb[QCA_WLAN_VENDOR_ATTR_TDLS_ENABLE_MAC_ADDR]) {
4249 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr mac addr failed"));
4250 return -EINVAL;
4251 }
4252
4253 memcpy(peer, nla_data(
4254 tb[QCA_WLAN_VENDOR_ATTR_TDLS_ENABLE_MAC_ADDR]),
4255 sizeof(peer));
4256 hddLog(VOS_TRACE_LEVEL_INFO, FL(MAC_ADDRESS_STR),MAC_ADDR_ARRAY(peer));
4257
4258 /* Parse and fetch channel */
4259 if (!tb[QCA_WLAN_VENDOR_ATTR_TDLS_ENABLE_CHANNEL]) {
4260 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr channel failed"));
4261 return -EINVAL;
4262 }
4263 pReqMsg.channel = nla_get_s32(
4264 tb[QCA_WLAN_VENDOR_ATTR_TDLS_ENABLE_CHANNEL]);
4265 hddLog(VOS_TRACE_LEVEL_INFO, FL("Channel Num (%d)"), pReqMsg.channel);
4266
4267 /* Parse and fetch global operating class */
4268 if (!tb[QCA_WLAN_VENDOR_ATTR_TDLS_ENABLE_GLOBAL_OPERATING_CLASS]) {
4269 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr operating class failed"));
4270 return -EINVAL;
4271 }
4272 pReqMsg.global_operating_class = nla_get_s32(
4273 tb[QCA_WLAN_VENDOR_ATTR_TDLS_ENABLE_GLOBAL_OPERATING_CLASS]);
4274 hddLog(VOS_TRACE_LEVEL_INFO, FL("Operating class (%d)"),
4275 pReqMsg.global_operating_class);
4276
4277 /* Parse and fetch latency ms */
4278 if (!tb[QCA_WLAN_VENDOR_ATTR_TDLS_ENABLE_MAX_LATENCY_MS]) {
4279 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr latency failed"));
4280 return -EINVAL;
4281 }
4282 pReqMsg.max_latency_ms = nla_get_s32(
4283 tb[QCA_WLAN_VENDOR_ATTR_TDLS_ENABLE_MAX_LATENCY_MS]);
4284 hddLog(VOS_TRACE_LEVEL_INFO, FL("Latency (%d)"),
4285 pReqMsg.max_latency_ms);
4286
4287 /* Parse and fetch required bandwidth kbps */
4288 if (!tb[QCA_WLAN_VENDOR_ATTR_TDLS_ENABLE_MIN_BANDWIDTH_KBPS]) {
4289 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr bandwidth failed"));
4290 return -EINVAL;
4291 }
4292
4293 pReqMsg.min_bandwidth_kbps = nla_get_s32(
4294 tb[QCA_WLAN_VENDOR_ATTR_TDLS_ENABLE_MIN_BANDWIDTH_KBPS]);
4295 hddLog(VOS_TRACE_LEVEL_INFO, FL("Bandwidth (%d)"),
4296 pReqMsg.min_bandwidth_kbps);
4297
4298 return (wlan_hdd_tdls_extctrl_config_peer(pAdapter,
4299 peer,
4300 wlan_hdd_cfg80211_exttdls_callback));
4301}
4302
4303static int wlan_hdd_cfg80211_exttdls_disable(struct wiphy *wiphy,
4304 struct wireless_dev *wdev,
4305 void *data,
4306 int data_len)
4307{
4308 u8 peer[6] = {0};
4309 struct net_device *dev = wdev->netdev;
4310 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
4311 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
4312 struct nlattr *tb[QCA_WLAN_VENDOR_ATTR_TDLS_DISABLE_MAX + 1];
4313 eHalStatus status;
4314
4315 status = wlan_hdd_validate_context(pHddCtx);
4316 if (0 != status) {
4317 hddLog(VOS_TRACE_LEVEL_ERROR,
4318 FL("HDD context is not valid"));
4319 return -EINVAL;
4320 }
4321 if (pHddCtx->cfg_ini->fTDLSExternalControl == FALSE) {
4322
4323 return -ENOTSUPP;
4324 }
4325 if (nla_parse(tb, QCA_WLAN_VENDOR_ATTR_TDLS_DISABLE_MAX,
4326 data, data_len,
4327 wlan_hdd_tdls_config_disable_policy)) {
4328 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Invalid ATTR"));
4329 return -EINVAL;
4330 }
4331 /* Parse and fetch mac address */
4332 if (!tb[QCA_WLAN_VENDOR_ATTR_TDLS_DISABLE_MAC_ADDR]) {
4333 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr mac addr failed"));
4334 return -EINVAL;
4335 }
4336
4337 memcpy(peer, nla_data(
4338 tb[QCA_WLAN_VENDOR_ATTR_TDLS_DISABLE_MAC_ADDR]),
4339 sizeof(peer));
4340 hddLog(VOS_TRACE_LEVEL_INFO, FL(MAC_ADDRESS_STR),MAC_ADDR_ARRAY(peer));
4341
4342 return (wlan_hdd_tdls_extctrl_deconfig_peer(pAdapter, peer));
4343}
4344
Dasari Srinivas7875a302014-09-26 17:50:57 +05304345static int
4346wlan_hdd_cfg80211_get_supported_features(struct wiphy *wiphy,
4347 struct wireless_dev *wdev,
4348 void *data, int data_len)
4349{
4350 struct net_device *dev = wdev->netdev;
4351 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
4352 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
4353 struct sk_buff *skb = NULL;
4354 tANI_U32 fset = 0;
4355
4356 if (wiphy->interface_modes & BIT(NL80211_IFTYPE_STATION)) {
4357 hddLog(LOG1, FL("Infra Station mode is supported by driver"));
4358 fset |= WIFI_FEATURE_INFRA;
4359 }
4360
4361 if (TRUE == hdd_is_5g_supported(pHddCtx)) {
4362 hddLog(LOG1, FL("INFRA_5G is supported by firmware"));
4363 fset |= WIFI_FEATURE_INFRA_5G;
4364 }
4365
4366#ifdef WLAN_FEATURE_P2P
4367 if ((wiphy->interface_modes & BIT(NL80211_IFTYPE_P2P_CLIENT)) &&
4368 (wiphy->interface_modes & BIT(NL80211_IFTYPE_P2P_GO))) {
4369 hddLog(LOG1, FL("WiFi-Direct is supported by driver"));
4370 fset |= WIFI_FEATURE_P2P;
4371 }
4372#endif
4373
4374 /* Soft-AP is supported currently by default */
4375 fset |= WIFI_FEATURE_SOFT_AP;
4376
4377#ifdef WLAN_FEATURE_EXTSCAN
4378 if ((TRUE == pHddCtx->cfg_ini->fEnableEXTScan) &&
4379 sme_IsFeatureSupportedByFW(EXTENDED_SCAN)) {
4380 hddLog(LOG1, FL("EXTScan is supported by firmware"));
4381 fset |= WIFI_FEATURE_EXTSCAN;
4382 }
4383#endif
4384
4385#ifdef WLAN_FEATURE_NAN
4386 if (sme_IsFeatureSupportedByFW(NAN)) {
4387 hddLog(LOG1, FL("NAN is supported by firmware"));
4388 fset |= WIFI_FEATURE_NAN;
4389 }
4390#endif
4391
4392 /* D2D RTT is not supported currently by default */
4393 if (sme_IsFeatureSupportedByFW(RTT)) {
4394 hddLog(LOG1, FL("RTT is supported by firmware"));
4395 fset |= WIFI_FEATURE_D2AP_RTT;
4396 }
4397
4398#ifdef FEATURE_WLAN_BATCH_SCAN
4399 if (fset & WIFI_FEATURE_EXTSCAN) {
4400 hddLog(LOG1, FL("Batch scan is supported as extscan is supported"));
4401 fset &= ~WIFI_FEATURE_BATCH_SCAN;
4402 } else if (sme_IsFeatureSupportedByFW(BATCH_SCAN)) {
4403 hddLog(LOG1, FL("Batch scan is supported by firmware"));
4404 fset |= WIFI_FEATURE_BATCH_SCAN;
4405 }
4406#endif
4407
4408#ifdef FEATURE_WLAN_SCAN_PNO
4409 if (pHddCtx->cfg_ini->configPNOScanSupport &&
4410 (eHAL_STATUS_SUCCESS == wlan_hdd_is_pno_allowed(pAdapter))) {
4411 hddLog(LOG1, FL("PNO is supported by firmware"));
4412 fset |= WIFI_FEATURE_PNO;
4413 }
4414#endif
4415
4416 /* STA+STA is supported currently by default */
4417 fset |= WIFI_FEATURE_ADDITIONAL_STA;
4418
4419#ifdef FEATURE_WLAN_TDLS
4420 if ((TRUE == pHddCtx->cfg_ini->fEnableTDLSSupport) &&
4421 sme_IsFeatureSupportedByFW(TDLS)) {
4422 hddLog(LOG1, FL("TDLS is supported by firmware"));
4423 fset |= WIFI_FEATURE_TDLS;
4424 }
4425
4426 /* TDLS_OFFCHANNEL is not supported currently by default */
4427#endif
4428
4429#ifdef WLAN_AP_STA_CONCURRENCY
4430 /* AP+STA concurrency is supported currently by default */
4431 fset |= WIFI_FEATURE_AP_STA;
4432#endif
4433
4434 skb = cfg80211_vendor_cmd_alloc_reply_skb(wiphy, sizeof(fset) +
4435 NLMSG_HDRLEN);
4436
4437 if (!skb) {
4438 hddLog(LOGE, FL("cfg80211_vendor_cmd_alloc_reply_skb failed"));
4439 return -EINVAL;
4440 }
4441 hddLog(LOG1, FL("Supported Features : 0x%x"), fset);
4442
4443 if (nla_put_u32(skb, QCA_WLAN_VENDOR_ATTR_FEATURE_SET, fset)) {
4444 hddLog(LOGE, FL("nla put fail"));
4445 goto nla_put_failure;
4446 }
4447
4448 return cfg80211_vendor_cmd_reply(skb);
4449
4450nla_put_failure:
4451 kfree_skb(skb);
4452 return -EINVAL;
4453}
4454
Agarwal Ashish738843c2014-09-25 12:27:56 +05304455static const struct nla_policy
4456wlan_hdd_set_no_dfs_flag_config_policy[QCA_WLAN_VENDOR_ATTR_SET_NO_DFS_FLAG_MAX
4457 +1] =
4458{
4459 [QCA_WLAN_VENDOR_ATTR_SET_NO_DFS_FLAG] = {.type = NLA_U32 },
4460};
4461
4462static int wlan_hdd_cfg80211_disable_dfs_channels(struct wiphy *wiphy,
4463 struct wireless_dev *wdev,
4464 void *data,
4465 int data_len)
4466{
4467 struct net_device *dev = wdev->netdev;
4468 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
4469 tHalHandle hHal = WLAN_HDD_GET_HAL_CTX(pAdapter);
4470 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
4471 struct nlattr *tb[QCA_WLAN_VENDOR_ATTR_SET_NO_DFS_FLAG_MAX + 1];
4472 eHalStatus status;
4473 u32 dfsFlag = 0;
4474
4475 status = wlan_hdd_validate_context(pHddCtx);
4476 if (0 != status) {
4477 hddLog(VOS_TRACE_LEVEL_ERROR,
4478 FL("HDD context is not valid"));
4479 return -EINVAL;
4480 }
4481 if (nla_parse(tb, QCA_WLAN_VENDOR_ATTR_SET_NO_DFS_FLAG_MAX,
4482 data, data_len,
4483 wlan_hdd_set_no_dfs_flag_config_policy)) {
4484 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Invalid ATTR"));
4485 return -EINVAL;
4486 }
4487
4488 /* Parse and fetch required bandwidth kbps */
4489 if (!tb[QCA_WLAN_VENDOR_ATTR_SET_NO_DFS_FLAG]) {
4490 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr dfs flag failed"));
4491 return -EINVAL;
4492 }
4493
4494 dfsFlag = nla_get_u32(
4495 tb[QCA_WLAN_VENDOR_ATTR_SET_NO_DFS_FLAG]);
4496 hddLog(VOS_TRACE_LEVEL_INFO, FL(" DFS flag (%d)"),
4497 dfsFlag);
4498
4499 pHddCtx->disable_dfs_flag = dfsFlag;
4500
4501 sme_disable_dfs_channel(hHal, dfsFlag);
4502 sme_FilterScanResults(hHal, pAdapter->sessionId);
4503 return 0;
4504}
Atul Mittal115287b2014-07-08 13:26:33 +05304505
Sunil Duttc69bccb2014-05-26 21:30:20 +05304506const struct wiphy_vendor_command hdd_wiphy_vendor_commands[] =
4507{
4508#ifdef WLAN_FEATURE_LINK_LAYER_STATS
4509 {
4510 .info.vendor_id = QCA_NL80211_VENDOR_ID,
4511 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_LL_STATS_CLR,
4512 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
4513 WIPHY_VENDOR_CMD_NEED_NETDEV |
4514 WIPHY_VENDOR_CMD_NEED_RUNNING,
4515 .doit = wlan_hdd_cfg80211_ll_stats_clear
4516 },
4517
4518 {
4519 .info.vendor_id = QCA_NL80211_VENDOR_ID,
4520 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_LL_STATS_SET,
4521 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
4522 WIPHY_VENDOR_CMD_NEED_NETDEV |
4523 WIPHY_VENDOR_CMD_NEED_RUNNING,
4524 .doit = wlan_hdd_cfg80211_ll_stats_set
4525 },
4526
4527 {
4528 .info.vendor_id = QCA_NL80211_VENDOR_ID,
4529 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_LL_STATS_GET,
4530 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
4531 WIPHY_VENDOR_CMD_NEED_NETDEV |
4532 WIPHY_VENDOR_CMD_NEED_RUNNING,
4533 .doit = wlan_hdd_cfg80211_ll_stats_get
Dino Mycle6fb96c12014-06-10 11:52:40 +05304534 },
Sunil Duttc69bccb2014-05-26 21:30:20 +05304535#endif /* WLAN_FEATURE_LINK_LAYER_STATS */
Dino Mycle6fb96c12014-06-10 11:52:40 +05304536#ifdef WLAN_FEATURE_EXTSCAN
4537 {
4538 .info.vendor_id = QCA_NL80211_VENDOR_ID,
4539 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_START,
4540 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
4541 WIPHY_VENDOR_CMD_NEED_NETDEV |
4542 WIPHY_VENDOR_CMD_NEED_RUNNING,
4543 .doit = wlan_hdd_cfg80211_extscan_start
4544 },
4545 {
4546 .info.vendor_id = QCA_NL80211_VENDOR_ID,
4547 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_STOP,
4548 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
4549 WIPHY_VENDOR_CMD_NEED_NETDEV |
4550 WIPHY_VENDOR_CMD_NEED_RUNNING,
4551 .doit = wlan_hdd_cfg80211_extscan_stop
4552 },
4553 {
4554 .info.vendor_id = QCA_NL80211_VENDOR_ID,
4555 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_GET_VALID_CHANNELS,
4556 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
4557 WIPHY_VENDOR_CMD_NEED_NETDEV,
4558 .doit = wlan_hdd_cfg80211_extscan_get_valid_channels
4559 },
4560 {
4561 .info.vendor_id = QCA_NL80211_VENDOR_ID,
4562 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_GET_CAPABILITIES,
4563 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
4564 WIPHY_VENDOR_CMD_NEED_NETDEV |
4565 WIPHY_VENDOR_CMD_NEED_RUNNING,
4566 .doit = wlan_hdd_cfg80211_extscan_get_capabilities
4567 },
4568 {
4569 .info.vendor_id = QCA_NL80211_VENDOR_ID,
4570 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_GET_CACHED_RESULTS,
4571 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
4572 WIPHY_VENDOR_CMD_NEED_NETDEV |
4573 WIPHY_VENDOR_CMD_NEED_RUNNING,
4574 .doit = wlan_hdd_cfg80211_extscan_get_cached_results
4575 },
4576 {
4577 .info.vendor_id = QCA_NL80211_VENDOR_ID,
4578 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_SET_BSSID_HOTLIST,
4579 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
4580 WIPHY_VENDOR_CMD_NEED_NETDEV |
4581 WIPHY_VENDOR_CMD_NEED_RUNNING,
4582 .doit = wlan_hdd_cfg80211_extscan_set_bssid_hotlist
4583 },
4584 {
4585 .info.vendor_id = QCA_NL80211_VENDOR_ID,
4586 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_RESET_BSSID_HOTLIST,
4587 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
4588 WIPHY_VENDOR_CMD_NEED_NETDEV |
4589 WIPHY_VENDOR_CMD_NEED_RUNNING,
4590 .doit = wlan_hdd_cfg80211_extscan_reset_bssid_hotlist
4591 },
4592 {
4593 .info.vendor_id = QCA_NL80211_VENDOR_ID,
4594 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_SET_SIGNIFICANT_CHANGE,
4595 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
4596 WIPHY_VENDOR_CMD_NEED_NETDEV |
4597 WIPHY_VENDOR_CMD_NEED_RUNNING,
4598 .doit = wlan_hdd_cfg80211_extscan_set_significant_change
4599 },
4600 {
4601 .info.vendor_id = QCA_NL80211_VENDOR_ID,
4602 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_RESET_SIGNIFICANT_CHANGE,
4603 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
4604 WIPHY_VENDOR_CMD_NEED_NETDEV |
4605 WIPHY_VENDOR_CMD_NEED_RUNNING,
4606 .doit = wlan_hdd_cfg80211_extscan_reset_significant_change
4607 },
4608#endif /* WLAN_FEATURE_EXTSCAN */
Atul Mittal115287b2014-07-08 13:26:33 +05304609/*EXT TDLS*/
4610 {
4611 .info.vendor_id = QCA_NL80211_VENDOR_ID,
4612 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_TDLS_ENABLE,
4613 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
4614 WIPHY_VENDOR_CMD_NEED_NETDEV |
4615 WIPHY_VENDOR_CMD_NEED_RUNNING,
4616 .doit = wlan_hdd_cfg80211_exttdls_enable
4617 },
4618 {
4619 .info.vendor_id = QCA_NL80211_VENDOR_ID,
4620 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_TDLS_DISABLE,
4621 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
4622 WIPHY_VENDOR_CMD_NEED_NETDEV |
4623 WIPHY_VENDOR_CMD_NEED_RUNNING,
4624 .doit = wlan_hdd_cfg80211_exttdls_disable
4625 },
4626 {
4627 .info.vendor_id = QCA_NL80211_VENDOR_ID,
4628 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_TDLS_GET_STATUS,
4629 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
4630 WIPHY_VENDOR_CMD_NEED_NETDEV,
4631 .doit = wlan_hdd_cfg80211_exttdls_get_status
4632 },
Dasari Srinivas7875a302014-09-26 17:50:57 +05304633 {
4634 .info.vendor_id = QCA_NL80211_VENDOR_ID,
4635 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_GET_SUPPORTED_FEATURES,
4636 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
4637 WIPHY_VENDOR_CMD_NEED_NETDEV,
4638 .doit = wlan_hdd_cfg80211_get_supported_features
4639 },
Agarwal Ashish738843c2014-09-25 12:27:56 +05304640 {
4641 .info.vendor_id = QCA_NL80211_VENDOR_ID,
4642 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_NO_DFS_FLAG,
4643 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
4644 WIPHY_VENDOR_CMD_NEED_NETDEV,
4645 .doit = wlan_hdd_cfg80211_disable_dfs_channels
4646 },
Siddharth Bhala3a5cb42014-09-29 21:13:13 +05304647 {
4648 .info.vendor_id = QCA_NL80211_VENDOR_ID,
4649 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_MAC_OUI,
4650 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
4651 WIPHY_VENDOR_CMD_NEED_NETDEV,
4652 .doit = wlan_hdd_cfg80211_set_spoofed_mac_oui
4653 },
Sunil Duttc69bccb2014-05-26 21:30:20 +05304654};
4655
Rajesh Chauhan98a31f82014-01-06 20:15:25 -08004656/* vendor specific events */
Sunil Duttc69bccb2014-05-26 21:30:20 +05304657static const
4658struct nl80211_vendor_cmd_info wlan_hdd_cfg80211_vendor_events[] =
Rajesh Chauhan98a31f82014-01-06 20:15:25 -08004659{
4660#ifdef FEATURE_WLAN_CH_AVOID
4661 {
Sunil Duttc69bccb2014-05-26 21:30:20 +05304662 .vendor_id = QCA_NL80211_VENDOR_ID,
4663 .subcmd = QCA_NL80211_VENDOR_SUBCMD_AVOID_FREQUENCY
Rajesh Chauhan98a31f82014-01-06 20:15:25 -08004664 },
Sunil Duttc69bccb2014-05-26 21:30:20 +05304665#endif /* FEATURE_WLAN_CH_AVOID Index = 0*/
4666#ifdef WLAN_FEATURE_LINK_LAYER_STATS
4667 {
4668 /* Index = 1*/
4669 .vendor_id = QCA_NL80211_VENDOR_ID,
4670 .subcmd = QCA_NL80211_VENDOR_SUBCMD_LL_STATS_SET
4671 },
4672 {
4673 /* Index = 2*/
4674 .vendor_id = QCA_NL80211_VENDOR_ID,
4675 .subcmd = QCA_NL80211_VENDOR_SUBCMD_LL_STATS_GET
4676 },
4677 {
4678 /* Index = 3*/
4679 .vendor_id = QCA_NL80211_VENDOR_ID,
4680 .subcmd = QCA_NL80211_VENDOR_SUBCMD_LL_STATS_CLR
4681 },
4682 {
4683 /* Index = 4*/
4684 .vendor_id = QCA_NL80211_VENDOR_ID,
4685 .subcmd = QCA_NL80211_VENDOR_SUBCMD_LL_STATS_RADIO_RESULTS
4686 },
4687 {
4688 /* Index = 5*/
4689 .vendor_id = QCA_NL80211_VENDOR_ID,
4690 .subcmd = QCA_NL80211_VENDOR_SUBCMD_LL_STATS_IFACE_RESULTS
4691 },
4692 {
4693 /* Index = 6*/
4694 .vendor_id = QCA_NL80211_VENDOR_ID,
4695 .subcmd = QCA_NL80211_VENDOR_SUBCMD_LL_STATS_PEERS_RESULTS
4696 },
4697#endif /* WLAN_FEATURE_LINK_LAYER_STATS */
Dino Mycle6fb96c12014-06-10 11:52:40 +05304698#ifdef WLAN_FEATURE_EXTSCAN
4699 {
4700 .vendor_id = QCA_NL80211_VENDOR_ID,
4701 .subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_START
4702 },
4703 {
4704 .vendor_id = QCA_NL80211_VENDOR_ID,
4705 .subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_STOP
4706 },
4707 {
4708 .vendor_id = QCA_NL80211_VENDOR_ID,
4709 .subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_GET_CAPABILITIES
4710 },
4711 {
4712 .vendor_id = QCA_NL80211_VENDOR_ID,
4713 .subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_GET_CACHED_RESULTS
4714 },
4715 {
4716 .vendor_id = QCA_NL80211_VENDOR_ID,
4717 .subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_SCAN_RESULTS_AVAILABLE
4718 },
4719 {
4720 .vendor_id = QCA_NL80211_VENDOR_ID,
4721 .subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_FULL_SCAN_RESULT
4722 },
4723 {
4724 .vendor_id = QCA_NL80211_VENDOR_ID,
4725 .subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_SCAN_EVENT
4726 },
4727 {
4728 .vendor_id = QCA_NL80211_VENDOR_ID,
4729 .subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_HOTLIST_AP_FOUND
4730 },
4731 {
4732 .vendor_id = QCA_NL80211_VENDOR_ID,
4733 .subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_SET_BSSID_HOTLIST
4734 },
4735 {
4736 .vendor_id = QCA_NL80211_VENDOR_ID,
4737 .subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_RESET_BSSID_HOTLIST
4738 },
4739 {
4740 .vendor_id = QCA_NL80211_VENDOR_ID,
4741 .subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_SIGNIFICANT_CHANGE
4742 },
4743 {
4744 .vendor_id = QCA_NL80211_VENDOR_ID,
4745 .subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_SET_SIGNIFICANT_CHANGE
4746 },
4747 {
4748 .vendor_id = QCA_NL80211_VENDOR_ID,
4749 .subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_RESET_SIGNIFICANT_CHANGE
4750 },
4751#endif /* WLAN_FEATURE_EXTSCAN */
Atul Mittal115287b2014-07-08 13:26:33 +05304752/*EXT TDLS*/
4753 {
4754 .vendor_id = QCA_NL80211_VENDOR_ID,
4755 .subcmd = QCA_NL80211_VENDOR_SUBCMD_TDLS_STATE
4756 },
Rajesh Chauhan98a31f82014-01-06 20:15:25 -08004757};
4758
Jeff Johnson295189b2012-06-20 16:38:30 -07004759/*
Madan Mohan Koyyalamudi71278262013-04-12 22:00:48 +05304760 * FUNCTION: wlan_hdd_cfg80211_wiphy_alloc
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304761 * This function is called by hdd_wlan_startup()
4762 * during initialization.
Madan Mohan Koyyalamudi71278262013-04-12 22:00:48 +05304763 * This function is used to allocate wiphy structure.
Jeff Johnson295189b2012-06-20 16:38:30 -07004764 */
Madan Mohan Koyyalamudi71278262013-04-12 22:00:48 +05304765struct wiphy *wlan_hdd_cfg80211_wiphy_alloc(int priv_size)
Jeff Johnson295189b2012-06-20 16:38:30 -07004766{
4767 struct wiphy *wiphy;
4768 ENTER();
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304769 /*
4770 * Create wiphy device
Jeff Johnson295189b2012-06-20 16:38:30 -07004771 */
4772 wiphy = wiphy_new(&wlan_hdd_cfg80211_ops, priv_size);
4773
4774 if (!wiphy)
4775 {
4776 /* Print error and jump into err label and free the memory */
4777 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: wiphy init failed", __func__);
4778 return NULL;
4779 }
4780
Sunil Duttc69bccb2014-05-26 21:30:20 +05304781
Jeff Johnson295189b2012-06-20 16:38:30 -07004782 return wiphy;
4783}
4784
4785/*
4786 * FUNCTION: wlan_hdd_cfg80211_update_band
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304787 * This function is called from the supplicant through a
Jeff Johnson295189b2012-06-20 16:38:30 -07004788 * private ioctl to change the band value
4789 */
4790int wlan_hdd_cfg80211_update_band(struct wiphy *wiphy, eCsrBand eBand)
4791{
Gopichand Nakkala1f7a64f2013-04-01 18:37:17 +05304792 int i, j;
4793 eNVChannelEnabledType channelEnabledState;
4794
Jeff Johnsone7245742012-09-05 17:12:55 -07004795 ENTER();
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05304796
Gopichand Nakkala1f7a64f2013-04-01 18:37:17 +05304797 for (i = 0; i < IEEE80211_NUM_BANDS; i++)
Jeff Johnson295189b2012-06-20 16:38:30 -07004798 {
Gopichand Nakkala1f7a64f2013-04-01 18:37:17 +05304799
4800 if (NULL == wiphy->bands[i])
4801 {
4802 hddLog(VOS_TRACE_LEVEL_ERROR,"%s: wiphy->bands[i] is NULL, i = %d",
4803 __func__, i);
4804 continue;
4805 }
4806
4807 for (j = 0; j < wiphy->bands[i]->n_channels; j++)
4808 {
4809 struct ieee80211_supported_band *band = wiphy->bands[i];
4810
4811 channelEnabledState = vos_nv_getChannelEnabledState(
4812 band->channels[j].hw_value);
4813
4814 if (IEEE80211_BAND_2GHZ == i && eCSR_BAND_5G == eBand) // 5G only
4815 {
4816 // Enable Social channels for P2P
4817 if (WLAN_HDD_IS_SOCIAL_CHANNEL(band->channels[j].center_freq) &&
4818 NV_CHANNEL_ENABLE == channelEnabledState)
4819 band->channels[j].flags &= ~IEEE80211_CHAN_DISABLED;
4820 else
4821 band->channels[j].flags |= IEEE80211_CHAN_DISABLED;
4822 continue;
4823 }
4824 else if (IEEE80211_BAND_5GHZ == i && eCSR_BAND_24 == eBand) // 2G only
4825 {
4826 band->channels[j].flags |= IEEE80211_CHAN_DISABLED;
4827 continue;
4828 }
4829
4830 if (NV_CHANNEL_DISABLE == channelEnabledState ||
4831 NV_CHANNEL_INVALID == channelEnabledState)
4832 {
4833 band->channels[j].flags |= IEEE80211_CHAN_DISABLED;
4834 }
4835 else if (NV_CHANNEL_DFS == channelEnabledState)
4836 {
4837 band->channels[j].flags &= ~IEEE80211_CHAN_DISABLED;
4838 band->channels[j].flags |= IEEE80211_CHAN_RADAR;
4839 }
4840 else
4841 {
4842 band->channels[j].flags &= ~(IEEE80211_CHAN_DISABLED
4843 |IEEE80211_CHAN_RADAR);
4844 }
4845 }
Jeff Johnson295189b2012-06-20 16:38:30 -07004846 }
4847 return 0;
4848}
4849/*
4850 * FUNCTION: wlan_hdd_cfg80211_init
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304851 * This function is called by hdd_wlan_startup()
4852 * during initialization.
Jeff Johnson295189b2012-06-20 16:38:30 -07004853 * This function is used to initialize and register wiphy structure.
4854 */
Madan Mohan Koyyalamudi71278262013-04-12 22:00:48 +05304855int wlan_hdd_cfg80211_init(struct device *dev,
Jeff Johnson295189b2012-06-20 16:38:30 -07004856 struct wiphy *wiphy,
4857 hdd_config_t *pCfg
4858 )
4859{
Gopichand Nakkala1f7a64f2013-04-01 18:37:17 +05304860 int i, j;
Vinay Krishna Erannafacf5e22014-02-24 13:16:25 +05304861 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
4862
Jeff Johnsone7245742012-09-05 17:12:55 -07004863 ENTER();
4864
Jeff Johnson295189b2012-06-20 16:38:30 -07004865 /* Now bind the underlying wlan device with wiphy */
4866 set_wiphy_dev(wiphy, dev);
4867
4868 wiphy->mgmt_stypes = wlan_hdd_txrx_stypes;
Amar Singhalfddc28c2013-09-05 13:03:40 -07004869
Kiet Lam6c583332013-10-14 05:37:09 +05304870#ifndef CONFIG_ENABLE_LINUX_REG
Amar Singhal0a402232013-10-11 20:57:16 -07004871 /* the flag for the other case would be initialzed in
4872 vos_init_wiphy_from_nv_bin */
Amar Singhal0a402232013-10-11 20:57:16 -07004873 wiphy->flags |= WIPHY_FLAG_STRICT_REGULATORY;
Kiet Lam6c583332013-10-14 05:37:09 +05304874#endif
Amar Singhala49cbc52013-10-08 18:37:44 -07004875
Amar Singhalfddc28c2013-09-05 13:03:40 -07004876 /* This will disable updating of NL channels from passive to
4877 * active if a beacon is received on passive channel. */
4878 wiphy->flags |= WIPHY_FLAG_DISABLE_BEACON_HINTS;
Amar Singhalf0073192013-09-20 12:34:56 -07004879
Amar Singhalfddc28c2013-09-05 13:03:40 -07004880
Amar Singhala49cbc52013-10-08 18:37:44 -07004881
Jeff Johnson04dd8a82012-06-29 20:41:40 -07004882#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,4,0))
Madan Mohan Koyyalamudi1b4afb02012-10-22 15:25:16 -07004883 wiphy->flags |= WIPHY_FLAG_HAVE_AP_SME
4884 | WIPHY_FLAG_AP_PROBE_RESP_OFFLOAD
4885 | WIPHY_FLAG_HAS_REMAIN_ON_CHANNEL
Jeff Johnsone7245742012-09-05 17:12:55 -07004886 | WIPHY_FLAG_OFFCHAN_TX;
Kiet Lam6c583332013-10-14 05:37:09 +05304887 wiphy->country_ie_pref = NL80211_COUNTRY_IE_IGNORE_CORE;
Jeff Johnson04dd8a82012-06-29 20:41:40 -07004888#endif
Amar Singhala49cbc52013-10-08 18:37:44 -07004889
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08004890#if defined (WLAN_FEATURE_VOWIFI_11R) || defined (FEATURE_WLAN_ESE) || defined(FEATURE_WLAN_LFR)
Srinivas Girigowda640728a2013-03-28 12:21:54 -07004891 if (pCfg->isFastTransitionEnabled
James Zmuda77fb5ae2013-01-29 08:00:17 -08004892#ifdef FEATURE_WLAN_LFR
Srinivas Girigowda640728a2013-03-28 12:21:54 -07004893 || pCfg->isFastRoamIniFeatureEnabled
4894#endif
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08004895#ifdef FEATURE_WLAN_ESE
4896 || pCfg->isEseIniFeatureEnabled
Srinivas Girigowda640728a2013-03-28 12:21:54 -07004897#endif
4898 )
4899 {
4900 wiphy->flags |= WIPHY_FLAG_SUPPORTS_FW_ROAM;
4901 }
James Zmuda77fb5ae2013-01-29 08:00:17 -08004902#endif
Mohit Khanna698ba2a2012-12-04 15:08:18 -08004903#ifdef FEATURE_WLAN_TDLS
4904 wiphy->flags |= WIPHY_FLAG_SUPPORTS_TDLS
4905 | WIPHY_FLAG_TDLS_EXTERNAL_SETUP;
4906#endif
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +05304907#ifdef FEATURE_WLAN_SCAN_PNO
Hardik Kantilal Patel3dfd8792013-11-13 20:34:57 +05304908 if (pCfg->configPNOScanSupport)
4909 {
4910 wiphy->flags |= WIPHY_FLAG_SUPPORTS_SCHED_SCAN;
4911 wiphy->max_sched_scan_ssids = SIR_PNO_MAX_SUPP_NETWORKS;
4912 wiphy->max_match_sets = SIR_PNO_MAX_SUPP_NETWORKS;
4913 wiphy->max_sched_scan_ie_len = SIR_MAC_MAX_IE_LENGTH;
4914 }
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +05304915#endif/*FEATURE_WLAN_SCAN_PNO*/
Mohit Khanna698ba2a2012-12-04 15:08:18 -08004916
Amar Singhalfddc28c2013-09-05 13:03:40 -07004917#ifdef CONFIG_ENABLE_LINUX_REG
Madan Mohan Koyyalamudic3a240c2012-09-28 15:34:08 -07004918 /* even with WIPHY_FLAG_CUSTOM_REGULATORY,
4919 driver can still register regulatory callback and
Amar Singhalfddc28c2013-09-05 13:03:40 -07004920 it will get regulatory settings in wiphy->band[], but
Madan Mohan Koyyalamudic3a240c2012-09-28 15:34:08 -07004921 driver need to determine what to do with both
4922 regulatory settings */
Amar Singhalfddc28c2013-09-05 13:03:40 -07004923
4924 wiphy->reg_notifier = wlan_hdd_linux_reg_notifier;
Amar Singhala49cbc52013-10-08 18:37:44 -07004925#else
4926 wiphy->reg_notifier = wlan_hdd_crda_reg_notifier;
Amar Singhalfddc28c2013-09-05 13:03:40 -07004927#endif
Jeff Johnson04dd8a82012-06-29 20:41:40 -07004928
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304929 wiphy->max_scan_ssids = MAX_SCAN_SSID;
4930
Madan Mohan Koyyalamudi6815b162013-07-19 17:17:46 +05304931 wiphy->max_scan_ie_len = SIR_MAC_MAX_IE_LENGTH;
Jeff Johnson295189b2012-06-20 16:38:30 -07004932
Gopichand Nakkalac005b7c2013-05-14 16:04:14 +05304933 wiphy->max_acl_mac_addrs = MAX_ACL_MAC_ADDRESS;
4934
Jeff Johnson295189b2012-06-20 16:38:30 -07004935 /* Supports STATION & AD-HOC modes right now */
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304936 wiphy->interface_modes = BIT(NL80211_IFTYPE_STATION)
Jeff Johnson295189b2012-06-20 16:38:30 -07004937 | BIT(NL80211_IFTYPE_ADHOC)
Jeff Johnson295189b2012-06-20 16:38:30 -07004938 | BIT(NL80211_IFTYPE_P2P_CLIENT)
4939 | BIT(NL80211_IFTYPE_P2P_GO)
Jeff Johnson295189b2012-06-20 16:38:30 -07004940 | BIT(NL80211_IFTYPE_AP);
4941
Rashmi Ramannabd3feb72014-02-25 16:14:48 +05304942 if( pCfg->advertiseConcurrentOperation )
Sudhir Sattayappa Kohalli278eee52013-01-16 17:35:13 -08004943 {
Rashmi Ramannabd3feb72014-02-25 16:14:48 +05304944#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,4,0))
4945 if( pCfg->enableMCC )
4946 {
4947 /* Currently, supports up to two channels */
4948 wlan_hdd_iface_combination.num_different_channels = 2;
Sudhir Sattayappa Kohalli278eee52013-01-16 17:35:13 -08004949
Rashmi Ramannabd3feb72014-02-25 16:14:48 +05304950 if( !pCfg->allowMCCGODiffBI )
4951 wlan_hdd_iface_combination.beacon_int_infra_match = true;
Sudhir Sattayappa Kohalli278eee52013-01-16 17:35:13 -08004952
Rashmi Ramannabd3feb72014-02-25 16:14:48 +05304953 }
4954 wiphy->iface_combinations = &wlan_hdd_iface_combination;
4955 wiphy->n_iface_combinations = 1;
Sudhir Sattayappa Kohalli278eee52013-01-16 17:35:13 -08004956#endif
Rashmi Ramannabd3feb72014-02-25 16:14:48 +05304957 }
Sudhir Sattayappa Kohalli278eee52013-01-16 17:35:13 -08004958
Jeff Johnson295189b2012-06-20 16:38:30 -07004959 /* Before registering we need to update the ht capabilitied based
4960 * on ini values*/
4961 if( !pCfg->ShortGI20MhzEnable )
4962 {
4963 wlan_hdd_band_2_4_GHZ.ht_cap.cap &= ~IEEE80211_HT_CAP_SGI_20;
4964 wlan_hdd_band_5_GHZ.ht_cap.cap &= ~IEEE80211_HT_CAP_SGI_20;
4965 wlan_hdd_band_p2p_2_4_GHZ.ht_cap.cap &= ~IEEE80211_HT_CAP_SGI_20;
4966 }
4967
4968 if( !pCfg->ShortGI40MhzEnable )
4969 {
4970 wlan_hdd_band_5_GHZ.ht_cap.cap &= ~IEEE80211_HT_CAP_SGI_40;
4971 }
4972
4973 if( !pCfg->nChannelBondingMode5GHz )
4974 {
4975 wlan_hdd_band_5_GHZ.ht_cap.cap &= ~IEEE80211_HT_CAP_SUP_WIDTH_20_40;
4976 }
4977
Gopichand Nakkala1f7a64f2013-04-01 18:37:17 +05304978 wiphy->bands[IEEE80211_BAND_2GHZ] = &wlan_hdd_band_2_4_GHZ;
Vinay Krishna Erannafacf5e22014-02-24 13:16:25 +05304979 if (true == hdd_is_5g_supported(pHddCtx))
4980 {
4981 wiphy->bands[IEEE80211_BAND_5GHZ] = &wlan_hdd_band_5_GHZ;
4982 }
Gopichand Nakkala1f7a64f2013-04-01 18:37:17 +05304983
4984 for (i = 0; i < IEEE80211_NUM_BANDS; i++)
4985 {
4986
4987 if (NULL == wiphy->bands[i])
4988 {
4989 hddLog(VOS_TRACE_LEVEL_ERROR,"%s: wiphy->bands[i] is NULL, i = %d",
4990 __func__, i);
4991 continue;
4992 }
4993
4994 for (j = 0; j < wiphy->bands[i]->n_channels; j++)
4995 {
4996 struct ieee80211_supported_band *band = wiphy->bands[i];
4997
4998 if (IEEE80211_BAND_2GHZ == i && eCSR_BAND_5G == pCfg->nBandCapability) // 5G only
4999 {
5000 // Enable social channels for P2P
5001 if (WLAN_HDD_IS_SOCIAL_CHANNEL(band->channels[j].center_freq))
5002 band->channels[j].flags &= ~IEEE80211_CHAN_DISABLED;
5003 else
5004 band->channels[j].flags |= IEEE80211_CHAN_DISABLED;
5005 continue;
5006 }
5007 else if (IEEE80211_BAND_5GHZ == i && eCSR_BAND_24 == pCfg->nBandCapability) // 2G only
5008 {
5009 band->channels[j].flags |= IEEE80211_CHAN_DISABLED;
5010 continue;
5011 }
5012 }
Jeff Johnson295189b2012-06-20 16:38:30 -07005013 }
5014 /*Initialise the supported cipher suite details*/
5015 wiphy->cipher_suites = hdd_cipher_suites;
5016 wiphy->n_cipher_suites = ARRAY_SIZE(hdd_cipher_suites);
5017
5018 /*signal strength in mBm (100*dBm) */
5019 wiphy->signal_type = CFG80211_SIGNAL_TYPE_MBM;
5020
5021#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
Sushant Kaushik4f640e42014-07-08 12:27:09 +05305022 wiphy->max_remain_on_channel_duration = 5000;
Jeff Johnson295189b2012-06-20 16:38:30 -07005023#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07005024
Sunil Duttc69bccb2014-05-26 21:30:20 +05305025 wiphy->n_vendor_commands = ARRAY_SIZE(hdd_wiphy_vendor_commands);
5026 wiphy->vendor_commands = hdd_wiphy_vendor_commands;
Rajesh Chauhan98a31f82014-01-06 20:15:25 -08005027 wiphy->vendor_events = wlan_hdd_cfg80211_vendor_events;
5028 wiphy->n_vendor_events = ARRAY_SIZE(wlan_hdd_cfg80211_vendor_events);
5029
Madan Mohan Koyyalamudi71278262013-04-12 22:00:48 +05305030 EXIT();
5031 return 0;
5032}
5033
5034/* In this function we are registering wiphy. */
5035int wlan_hdd_cfg80211_register(struct wiphy *wiphy)
5036{
5037 ENTER();
5038 /* Register our wiphy dev with cfg80211 */
Jeff Johnson295189b2012-06-20 16:38:30 -07005039 if (0 > wiphy_register(wiphy))
5040 {
Madan Mohan Koyyalamudi71278262013-04-12 22:00:48 +05305041 /* print error */
Jeff Johnson295189b2012-06-20 16:38:30 -07005042 hddLog(VOS_TRACE_LEVEL_ERROR,"%s: wiphy register failed", __func__);
5043 return -EIO;
5044 }
5045
5046 EXIT();
5047 return 0;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305048}
Jeff Johnson295189b2012-06-20 16:38:30 -07005049
Madan Mohan Koyyalamudi71278262013-04-12 22:00:48 +05305050/* In this function we are updating channel list when,
5051 regulatory domain is FCC and country code is US.
5052 Here In FCC standard 5GHz UNII-1 Bands are indoor only.
5053 As per FCC smart phone is not a indoor device.
5054 GO should not opeate on indoor channels */
5055void wlan_hdd_cfg80211_update_reg_info(struct wiphy *wiphy)
5056{
5057 int j;
5058 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
5059 tANI_U8 defaultCountryCode[3] = SME_INVALID_COUNTRY_CODE;
5060 //Default counrtycode from NV at the time of wiphy initialization.
5061 if (eHAL_STATUS_SUCCESS != sme_GetDefaultCountryCodeFrmNv(pHddCtx->hHal,
5062 &defaultCountryCode[0]))
5063 {
Jeff Johnson0299d0a2013-10-30 12:37:43 -07005064 hddLog(LOGE, FL("Failed to get default country code from NV"));
Madan Mohan Koyyalamudi71278262013-04-12 22:00:48 +05305065 }
5066 if ((defaultCountryCode[0]== 'U') && (defaultCountryCode[1]=='S'))
5067 {
Madan Mohan Koyyalamudi71278262013-04-12 22:00:48 +05305068 if (NULL == wiphy->bands[IEEE80211_BAND_5GHZ])
5069 {
5070 hddLog(VOS_TRACE_LEVEL_ERROR,"%s: wiphy->bands[IEEE80211_BAND_5GHZ] is NULL",__func__ );
5071 return;
5072 }
5073 for (j = 0; j < wiphy->bands[IEEE80211_BAND_5GHZ]->n_channels; j++)
5074 {
5075 struct ieee80211_supported_band *band = wiphy->bands[IEEE80211_BAND_5GHZ];
5076 // Mark UNII -1 band channel as passive
5077 if (WLAN_HDD_CHANNEL_IN_UNII_1_BAND(band->channels[j].center_freq))
5078 band->channels[j].flags |= IEEE80211_CHAN_PASSIVE_SCAN;
5079 }
5080 }
5081}
5082
Agarwal Ashish8fa0e9a2014-05-23 00:40:12 +05305083/* This function registers for all frame which supplicant is interested in */
5084void wlan_hdd_cfg80211_register_frames(hdd_adapter_t* pAdapter)
Jeff Johnson295189b2012-06-20 16:38:30 -07005085{
Jeff Johnson295189b2012-06-20 16:38:30 -07005086 tHalHandle hHal = WLAN_HDD_GET_HAL_CTX(pAdapter);
5087 /* Register for all P2P action, public action etc frames */
5088 v_U16_t type = (SIR_MAC_MGMT_FRAME << 2) | ( SIR_MAC_MGMT_ACTION << 4);
5089
Jeff Johnsone7245742012-09-05 17:12:55 -07005090 ENTER();
5091
Jeff Johnson295189b2012-06-20 16:38:30 -07005092 /* Right now we are registering these frame when driver is getting
5093 initialized. Once we will move to 2.6.37 kernel, in which we have
5094 frame register ops, we will move this code as a part of that */
5095 /* GAS Initial Request */
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305096 sme_RegisterMgmtFrame(hHal, pAdapter->sessionId, type,
Jeff Johnson295189b2012-06-20 16:38:30 -07005097 (v_U8_t*)GAS_INITIAL_REQ, GAS_INITIAL_REQ_SIZE );
5098
5099 /* GAS Initial Response */
5100 sme_RegisterMgmtFrame(hHal, pAdapter->sessionId, type,
5101 (v_U8_t*)GAS_INITIAL_RSP, GAS_INITIAL_RSP_SIZE );
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305102
Jeff Johnson295189b2012-06-20 16:38:30 -07005103 /* GAS Comeback Request */
5104 sme_RegisterMgmtFrame(hHal, pAdapter->sessionId, type,
5105 (v_U8_t*)GAS_COMEBACK_REQ, GAS_COMEBACK_REQ_SIZE );
5106
5107 /* GAS Comeback Response */
5108 sme_RegisterMgmtFrame(hHal, pAdapter->sessionId, type,
5109 (v_U8_t*)GAS_COMEBACK_RSP, GAS_COMEBACK_RSP_SIZE );
5110
5111 /* P2P Public Action */
5112 sme_RegisterMgmtFrame(hHal, pAdapter->sessionId, type,
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305113 (v_U8_t*)P2P_PUBLIC_ACTION_FRAME,
Jeff Johnson295189b2012-06-20 16:38:30 -07005114 P2P_PUBLIC_ACTION_FRAME_SIZE );
5115
5116 /* P2P Action */
5117 sme_RegisterMgmtFrame(hHal, pAdapter->sessionId, type,
5118 (v_U8_t*)P2P_ACTION_FRAME,
5119 P2P_ACTION_FRAME_SIZE );
Chet Lanctot186b5732013-03-18 10:26:30 -07005120
Gopichand Nakkalae3d56e72013-04-21 23:33:32 +05305121 /* WNM BSS Transition Request frame */
5122 sme_RegisterMgmtFrame(hHal, pAdapter->sessionId, type,
5123 (v_U8_t*)WNM_BSS_ACTION_FRAME,
5124 WNM_BSS_ACTION_FRAME_SIZE );
Leela Venkata Kiran Kumar Reddy Chiralae8e62c82013-10-29 18:23:26 -07005125
5126 /* WNM-Notification */
5127 sme_RegisterMgmtFrame(hHal, pAdapter->sessionId, type,
5128 (v_U8_t*)WNM_NOTIFICATION_FRAME,
5129 WNM_NOTIFICATION_FRAME_SIZE );
Jeff Johnson295189b2012-06-20 16:38:30 -07005130}
5131
Agarwal Ashish8fa0e9a2014-05-23 00:40:12 +05305132void wlan_hdd_cfg80211_deregister_frames(hdd_adapter_t* pAdapter)
Jeff Johnson295189b2012-06-20 16:38:30 -07005133{
Jeff Johnson295189b2012-06-20 16:38:30 -07005134 tHalHandle hHal = WLAN_HDD_GET_HAL_CTX(pAdapter);
5135 /* Register for all P2P action, public action etc frames */
5136 v_U16_t type = (SIR_MAC_MGMT_FRAME << 2) | ( SIR_MAC_MGMT_ACTION << 4);
5137
Jeff Johnsone7245742012-09-05 17:12:55 -07005138 ENTER();
5139
Jeff Johnson295189b2012-06-20 16:38:30 -07005140 /* Right now we are registering these frame when driver is getting
5141 initialized. Once we will move to 2.6.37 kernel, in which we have
5142 frame register ops, we will move this code as a part of that */
5143 /* GAS Initial Request */
5144
5145 sme_DeregisterMgmtFrame(hHal, pAdapter->sessionId, type,
5146 (v_U8_t*)GAS_INITIAL_REQ, GAS_INITIAL_REQ_SIZE );
5147
5148 /* GAS Initial Response */
5149 sme_DeregisterMgmtFrame(hHal, pAdapter->sessionId, type,
5150 (v_U8_t*)GAS_INITIAL_RSP, GAS_INITIAL_RSP_SIZE );
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305151
Jeff Johnson295189b2012-06-20 16:38:30 -07005152 /* GAS Comeback Request */
5153 sme_DeregisterMgmtFrame(hHal, pAdapter->sessionId, type,
5154 (v_U8_t*)GAS_COMEBACK_REQ, GAS_COMEBACK_REQ_SIZE );
5155
5156 /* GAS Comeback Response */
5157 sme_DeregisterMgmtFrame(hHal, pAdapter->sessionId, type,
5158 (v_U8_t*)GAS_COMEBACK_RSP, GAS_COMEBACK_RSP_SIZE );
5159
5160 /* P2P Public Action */
5161 sme_DeregisterMgmtFrame(hHal, pAdapter->sessionId, type,
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305162 (v_U8_t*)P2P_PUBLIC_ACTION_FRAME,
Jeff Johnson295189b2012-06-20 16:38:30 -07005163 P2P_PUBLIC_ACTION_FRAME_SIZE );
5164
5165 /* P2P Action */
5166 sme_DeregisterMgmtFrame(hHal, pAdapter->sessionId, type,
5167 (v_U8_t*)P2P_ACTION_FRAME,
5168 P2P_ACTION_FRAME_SIZE );
Leela Venkata Kiran Kumar Reddy Chiralae8e62c82013-10-29 18:23:26 -07005169 /* WNM-Notification */
5170 sme_DeregisterMgmtFrame(hHal, pAdapter->sessionId, type,
5171 (v_U8_t*)WNM_NOTIFICATION_FRAME,
5172 WNM_NOTIFICATION_FRAME_SIZE );
Jeff Johnson295189b2012-06-20 16:38:30 -07005173}
5174
5175#ifdef FEATURE_WLAN_WAPI
5176void wlan_hdd_cfg80211_set_key_wapi(hdd_adapter_t* pAdapter, u8 key_index,
5177 const u8 *mac_addr, u8 *key , int key_Len)
5178{
5179 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
5180 tCsrRoamSetKey setKey;
5181 v_BOOL_t isConnected = TRUE;
5182 int status = 0;
5183 v_U32_t roamId= 0xFF;
5184 tANI_U8 *pKeyPtr = NULL;
5185 int n = 0;
5186
Sushant Kaushik8bc7df22014-04-09 17:55:29 +05305187 hddLog(VOS_TRACE_LEVEL_INFO, "%s: device_mode = %s(%d)",
5188 __func__, hdd_device_modetoString(pAdapter->device_mode),
5189 pAdapter->device_mode);
Jeff Johnson295189b2012-06-20 16:38:30 -07005190
Gopichand Nakkalae7480202013-02-11 15:24:22 +05305191 vos_mem_zero(&setKey, sizeof(tCsrRoamSetKey));
Jeff Johnson295189b2012-06-20 16:38:30 -07005192 setKey.keyId = key_index; // Store Key ID
5193 setKey.encType = eCSR_ENCRYPT_TYPE_WPI; // SET WAPI Encryption
5194 setKey.keyDirection = eSIR_TX_RX; // Key Directionn both TX and RX
5195 setKey.paeRole = 0 ; // the PAE role
5196 if (!mac_addr || is_broadcast_ether_addr(mac_addr))
5197 {
5198 vos_set_macaddr_broadcast( (v_MACADDR_t *)setKey.peerMac );
5199 }
5200 else
5201 {
5202 isConnected = hdd_connIsConnected(pHddStaCtx);
5203 vos_mem_copy(setKey.peerMac,&pHddStaCtx->conn_info.bssId,WNI_CFG_BSSID_LEN);
5204 }
5205 setKey.keyLength = key_Len;
5206 pKeyPtr = setKey.Key;
5207 memcpy( pKeyPtr, key, key_Len);
5208
Arif Hussain6d2a3322013-11-17 19:50:10 -08005209 hddLog(VOS_TRACE_LEVEL_INFO,"%s: WAPI KEY LENGTH:0x%04x",
Jeff Johnson295189b2012-06-20 16:38:30 -07005210 __func__, key_Len);
5211 for (n = 0 ; n < key_Len; n++)
5212 hddLog(VOS_TRACE_LEVEL_INFO, "%s WAPI KEY Data[%d]:%02x ",
5213 __func__,n,setKey.Key[n]);
5214
5215 pHddStaCtx->roam_info.roamingState = HDD_ROAM_STATE_SETTING_KEY;
5216 if ( isConnected )
5217 {
5218 status= sme_RoamSetKey( WLAN_HDD_GET_HAL_CTX(pAdapter),
5219 pAdapter->sessionId, &setKey, &roamId );
5220 }
5221 if ( status != 0 )
5222 {
5223 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
5224 "[%4d] sme_RoamSetKey returned ERROR status= %d",
5225 __LINE__, status );
5226 pHddStaCtx->roam_info.roamingState = HDD_ROAM_STATE_NONE;
5227 }
Vinay Krishna Eranna6f22c1f2014-10-13 16:03:06 +05305228 /* Need to clear any trace of key value in the memory.
5229 * Thus zero out the memory even though it is local
5230 * variable.
5231 */
5232 vos_mem_zero(&setKey, sizeof(setKey));
Jeff Johnson295189b2012-06-20 16:38:30 -07005233}
5234#endif /* FEATURE_WLAN_WAPI*/
5235
5236#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,4,0))
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305237int wlan_hdd_cfg80211_alloc_new_beacon(hdd_adapter_t *pAdapter,
Jeff Johnson295189b2012-06-20 16:38:30 -07005238 beacon_data_t **ppBeacon,
5239 struct beacon_parameters *params)
Jeff Johnson04dd8a82012-06-29 20:41:40 -07005240#else
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305241int wlan_hdd_cfg80211_alloc_new_beacon(hdd_adapter_t *pAdapter,
Jeff Johnson04dd8a82012-06-29 20:41:40 -07005242 beacon_data_t **ppBeacon,
5243 struct cfg80211_beacon_data *params,
5244 int dtim_period)
5245#endif
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305246{
Jeff Johnson295189b2012-06-20 16:38:30 -07005247 int size;
5248 beacon_data_t *beacon = NULL;
5249 beacon_data_t *old = NULL;
5250 int head_len,tail_len;
5251
Jeff Johnsone7245742012-09-05 17:12:55 -07005252 ENTER();
Jeff Johnson295189b2012-06-20 16:38:30 -07005253 if (params->head && !params->head_len)
c_hpothu6ff1c3c2013-10-01 19:01:57 +05305254 {
5255 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
5256 FL("head_len is NULL"));
Jeff Johnson295189b2012-06-20 16:38:30 -07005257 return -EINVAL;
c_hpothu6ff1c3c2013-10-01 19:01:57 +05305258 }
Jeff Johnson295189b2012-06-20 16:38:30 -07005259
5260 old = pAdapter->sessionCtx.ap.beacon;
5261
5262 if (!params->head && !old)
c_hpothu6ff1c3c2013-10-01 19:01:57 +05305263 {
5264 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
5265 FL("session(%d) old and new heads points to NULL"),
5266 pAdapter->sessionId);
Jeff Johnson295189b2012-06-20 16:38:30 -07005267 return -EINVAL;
c_hpothu6ff1c3c2013-10-01 19:01:57 +05305268 }
5269
5270 if (params->tail && !params->tail_len)
5271 {
5272 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
5273 FL("tail_len is zero but tail is not NULL"));
5274 return -EINVAL;
5275 }
Jeff Johnson295189b2012-06-20 16:38:30 -07005276
Jeff Johnson295189b2012-06-20 16:38:30 -07005277#if (LINUX_VERSION_CODE <= KERNEL_VERSION(2,6,38))
5278 /* Kernel 3.0 is not updating dtim_period for set beacon */
5279 if (!params->dtim_period)
c_hpothu6ff1c3c2013-10-01 19:01:57 +05305280 {
5281 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
5282 FL("dtim period is 0"));
Jeff Johnson295189b2012-06-20 16:38:30 -07005283 return -EINVAL;
c_hpothu6ff1c3c2013-10-01 19:01:57 +05305284 }
Jeff Johnson295189b2012-06-20 16:38:30 -07005285#endif
5286
5287 if(params->head)
5288 head_len = params->head_len;
5289 else
5290 head_len = old->head_len;
5291
5292 if(params->tail || !old)
5293 tail_len = params->tail_len;
5294 else
5295 tail_len = old->tail_len;
5296
5297 size = sizeof(beacon_data_t) + head_len + tail_len;
5298
5299 beacon = kzalloc(size, GFP_KERNEL);
5300
5301 if( beacon == NULL )
c_hpothu6ff1c3c2013-10-01 19:01:57 +05305302 {
5303 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
5304 FL("Mem allocation for beacon failed"));
Jeff Johnson295189b2012-06-20 16:38:30 -07005305 return -ENOMEM;
c_hpothu6ff1c3c2013-10-01 19:01:57 +05305306 }
Jeff Johnson295189b2012-06-20 16:38:30 -07005307
Jeff Johnson04dd8a82012-06-29 20:41:40 -07005308#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,4,0))
Jeff Johnson295189b2012-06-20 16:38:30 -07005309 if(params->dtim_period || !old )
5310 beacon->dtim_period = params->dtim_period;
5311 else
5312 beacon->dtim_period = old->dtim_period;
Jeff Johnson04dd8a82012-06-29 20:41:40 -07005313#else
5314 if(dtim_period || !old )
5315 beacon->dtim_period = dtim_period;
5316 else
5317 beacon->dtim_period = old->dtim_period;
5318#endif
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305319
Jeff Johnson295189b2012-06-20 16:38:30 -07005320 beacon->head = ((u8 *) beacon) + sizeof(beacon_data_t);
5321 beacon->tail = beacon->head + head_len;
5322 beacon->head_len = head_len;
5323 beacon->tail_len = tail_len;
5324
5325 if(params->head) {
5326 memcpy (beacon->head,params->head,beacon->head_len);
5327 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305328 else {
Jeff Johnson295189b2012-06-20 16:38:30 -07005329 if(old)
5330 memcpy (beacon->head,old->head,beacon->head_len);
5331 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305332
Jeff Johnson295189b2012-06-20 16:38:30 -07005333 if(params->tail) {
5334 memcpy (beacon->tail,params->tail,beacon->tail_len);
5335 }
5336 else {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305337 if(old)
Jeff Johnson295189b2012-06-20 16:38:30 -07005338 memcpy (beacon->tail,old->tail,beacon->tail_len);
5339 }
5340
5341 *ppBeacon = beacon;
5342
5343 kfree(old);
5344
5345 return 0;
5346
5347}
Jeff Johnson295189b2012-06-20 16:38:30 -07005348
5349v_U8_t* wlan_hdd_cfg80211_get_ie_ptr(v_U8_t *pIes, int length, v_U8_t eid)
5350{
5351 int left = length;
5352 v_U8_t *ptr = pIes;
5353 v_U8_t elem_id,elem_len;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305354
Jeff Johnson295189b2012-06-20 16:38:30 -07005355 while(left >= 2)
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305356 {
Jeff Johnson295189b2012-06-20 16:38:30 -07005357 elem_id = ptr[0];
5358 elem_len = ptr[1];
5359 left -= 2;
5360 if(elem_len > left)
5361 {
5362 hddLog(VOS_TRACE_LEVEL_FATAL,
Madan Mohan Koyyalamudi8bdd3112012-09-24 13:55:14 -07005363 FL("****Invalid IEs eid = %d elem_len=%d left=%d*****"),
Jeff Johnson295189b2012-06-20 16:38:30 -07005364 eid,elem_len,left);
5365 return NULL;
5366 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305367 if (elem_id == eid)
Jeff Johnson295189b2012-06-20 16:38:30 -07005368 {
5369 return ptr;
5370 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305371
Jeff Johnson295189b2012-06-20 16:38:30 -07005372 left -= elem_len;
5373 ptr += (elem_len + 2);
5374 }
5375 return NULL;
5376}
5377
Jeff Johnson295189b2012-06-20 16:38:30 -07005378/* Check if rate is 11g rate or not */
5379static int wlan_hdd_rate_is_11g(u8 rate)
5380{
Sanjay Devnani28322e22013-06-21 16:13:40 -07005381 static const u8 gRateArray[8] = {12, 18, 24, 36, 48, 72, 96, 108}; /* actual rate * 2 */
Jeff Johnson295189b2012-06-20 16:38:30 -07005382 u8 i;
5383 for (i = 0; i < 8; i++)
5384 {
5385 if(rate == gRateArray[i])
5386 return TRUE;
5387 }
5388 return FALSE;
5389}
5390
5391/* Check for 11g rate and set proper 11g only mode */
5392static void wlan_hdd_check_11gmode(u8 *pIe, u8* require_ht,
5393 u8* pCheckRatesfor11g, eSapPhyMode* pSapHw_mode)
5394{
5395 u8 i, num_rates = pIe[0];
5396
5397 pIe += 1;
5398 for ( i = 0; i < num_rates; i++)
5399 {
5400 if( *pCheckRatesfor11g && (TRUE == wlan_hdd_rate_is_11g(pIe[i] & RATE_MASK)))
5401 {
5402 /* If rate set have 11g rate than change the mode to 11G */
5403 *pSapHw_mode = eSAP_DOT11_MODE_11g;
5404 if (pIe[i] & BASIC_RATE_MASK)
5405 {
5406 /* If we have 11g rate as basic rate, it means mode
5407 is 11g only mode.
5408 */
5409 *pSapHw_mode = eSAP_DOT11_MODE_11g_ONLY;
5410 *pCheckRatesfor11g = FALSE;
5411 }
5412 }
5413 else if((BASIC_RATE_MASK | WLAN_BSS_MEMBERSHIP_SELECTOR_HT_PHY) == pIe[i])
5414 {
5415 *require_ht = TRUE;
5416 }
5417 }
5418 return;
5419}
5420
5421static void wlan_hdd_set_sapHwmode(hdd_adapter_t *pHostapdAdapter)
5422{
5423 tsap_Config_t *pConfig = &pHostapdAdapter->sessionCtx.ap.sapConfig;
5424 beacon_data_t *pBeacon = pHostapdAdapter->sessionCtx.ap.beacon;
5425 struct ieee80211_mgmt *pMgmt_frame = (struct ieee80211_mgmt*)pBeacon->head;
5426 u8 checkRatesfor11g = TRUE;
5427 u8 require_ht = FALSE;
5428 u8 *pIe=NULL;
5429
5430 pConfig->SapHw_mode= eSAP_DOT11_MODE_11b;
5431
5432 pIe = wlan_hdd_cfg80211_get_ie_ptr(&pMgmt_frame->u.beacon.variable[0],
5433 pBeacon->head_len, WLAN_EID_SUPP_RATES);
5434 if (pIe != NULL)
5435 {
5436 pIe += 1;
5437 wlan_hdd_check_11gmode(pIe, &require_ht, &checkRatesfor11g,
5438 &pConfig->SapHw_mode);
5439 }
5440
5441 pIe = wlan_hdd_cfg80211_get_ie_ptr(pBeacon->tail, pBeacon->tail_len,
5442 WLAN_EID_EXT_SUPP_RATES);
5443 if (pIe != NULL)
5444 {
5445
5446 pIe += 1;
5447 wlan_hdd_check_11gmode(pIe, &require_ht, &checkRatesfor11g,
5448 &pConfig->SapHw_mode);
5449 }
5450
5451 if( pConfig->channel > 14 )
5452 {
5453 pConfig->SapHw_mode= eSAP_DOT11_MODE_11a;
5454 }
5455
5456 pIe = wlan_hdd_cfg80211_get_ie_ptr(pBeacon->tail, pBeacon->tail_len,
5457 WLAN_EID_HT_CAPABILITY);
5458
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305459 if(pIe)
Jeff Johnson295189b2012-06-20 16:38:30 -07005460 {
5461 pConfig->SapHw_mode= eSAP_DOT11_MODE_11n;
5462 if(require_ht)
5463 pConfig->SapHw_mode= eSAP_DOT11_MODE_11n_ONLY;
5464 }
5465}
5466
Gopichand Nakkala2b25f4e2013-03-21 19:14:07 +05305467static int wlan_hdd_add_ie(hdd_adapter_t* pHostapdAdapter, v_U8_t *genie,
5468 v_U8_t *total_ielen, v_U8_t *oui, v_U8_t oui_size)
5469{
Arif Hussaine7f3ea52013-09-12 21:56:36 -07005470 v_U16_t ielen = 0;
Gopichand Nakkala2b25f4e2013-03-21 19:14:07 +05305471 v_U8_t *pIe = NULL;
5472 beacon_data_t *pBeacon = pHostapdAdapter->sessionCtx.ap.beacon;
5473
5474 pIe = wlan_hdd_get_vendor_oui_ie_ptr(oui, oui_size,
5475 pBeacon->tail, pBeacon->tail_len);
5476
5477 if (pIe)
5478 {
5479 ielen = pIe[1] + 2;
5480 if ((*total_ielen + ielen) <= MAX_GENIE_LEN)
5481 {
5482 vos_mem_copy(&genie[*total_ielen], pIe, ielen);
5483 }
5484 else
5485 {
5486 hddLog( VOS_TRACE_LEVEL_ERROR, "**Ie Length is too big***");
5487 return -EINVAL;
5488 }
5489 *total_ielen += ielen;
5490 }
5491 return 0;
5492}
5493
Arif Hussaine7f3ea52013-09-12 21:56:36 -07005494static void wlan_hdd_add_hostapd_conf_vsie(hdd_adapter_t* pHostapdAdapter,
5495 v_U8_t *genie, v_U8_t *total_ielen)
5496{
5497 beacon_data_t *pBeacon = pHostapdAdapter->sessionCtx.ap.beacon;
5498 int left = pBeacon->tail_len;
5499 v_U8_t *ptr = pBeacon->tail;
5500 v_U8_t elem_id, elem_len;
5501 v_U16_t ielen = 0;
5502
5503 if ( NULL == ptr || 0 == left )
5504 return;
5505
5506 while (left >= 2)
5507 {
5508 elem_id = ptr[0];
5509 elem_len = ptr[1];
5510 left -= 2;
5511 if (elem_len > left)
5512 {
5513 hddLog( VOS_TRACE_LEVEL_ERROR,
5514 "****Invalid IEs eid = %d elem_len=%d left=%d*****",
5515 elem_id, elem_len, left);
5516 return;
5517 }
5518 if (IE_EID_VENDOR == elem_id)
5519 {
5520 /* skipping the VSIE's which we don't want to include or
5521 * it will be included by existing code
5522 */
5523 if ((memcmp( &ptr[2], WPS_OUI_TYPE, WPS_OUI_TYPE_SIZE) != 0 ) &&
5524#ifdef WLAN_FEATURE_WFD
5525 (memcmp( &ptr[2], WFD_OUI_TYPE, WFD_OUI_TYPE_SIZE) != 0) &&
5526#endif
5527 (memcmp( &ptr[2], WHITELIST_OUI_TYPE, WPA_OUI_TYPE_SIZE) != 0) &&
5528 (memcmp( &ptr[2], BLACKLIST_OUI_TYPE, WPA_OUI_TYPE_SIZE) != 0) &&
5529 (memcmp( &ptr[2], "\x00\x50\xf2\x02", WPA_OUI_TYPE_SIZE) != 0) &&
5530 (memcmp( &ptr[2], WPA_OUI_TYPE, WPA_OUI_TYPE_SIZE) != 0) &&
5531 (memcmp( &ptr[2], P2P_OUI_TYPE, P2P_OUI_TYPE_SIZE) != 0))
5532 {
5533 ielen = ptr[1] + 2;
5534 if ((*total_ielen + ielen) <= MAX_GENIE_LEN)
5535 {
5536 vos_mem_copy(&genie[*total_ielen], ptr, ielen);
5537 *total_ielen += ielen;
5538 }
5539 else
5540 {
5541 hddLog( VOS_TRACE_LEVEL_ERROR,
5542 "IE Length is too big "
5543 "IEs eid=%d elem_len=%d total_ie_lent=%d",
5544 elem_id, elem_len, *total_ielen);
5545 }
5546 }
5547 }
5548
5549 left -= elem_len;
5550 ptr += (elem_len + 2);
5551 }
5552 return;
5553}
5554
Jeff Johnson04dd8a82012-06-29 20:41:40 -07005555#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,4,0))
Jeff Johnson295189b2012-06-20 16:38:30 -07005556static int wlan_hdd_cfg80211_update_apies(hdd_adapter_t* pHostapdAdapter,
5557 struct beacon_parameters *params)
Jeff Johnson04dd8a82012-06-29 20:41:40 -07005558#else
5559static int wlan_hdd_cfg80211_update_apies(hdd_adapter_t* pHostapdAdapter,
5560 struct cfg80211_beacon_data *params)
5561#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07005562{
5563 v_U8_t *genie;
Gopichand Nakkala2b25f4e2013-03-21 19:14:07 +05305564 v_U8_t total_ielen = 0;
Jeff Johnson295189b2012-06-20 16:38:30 -07005565 v_U8_t addIE[1] = {0};
Jeff Johnsone7245742012-09-05 17:12:55 -07005566 int ret = 0;
Jeff Johnson295189b2012-06-20 16:38:30 -07005567
5568 genie = vos_mem_malloc(MAX_GENIE_LEN);
5569
5570 if(genie == NULL) {
5571
5572 return -ENOMEM;
5573 }
5574
Gopichand Nakkala2b25f4e2013-03-21 19:14:07 +05305575 if (0 != wlan_hdd_add_ie(pHostapdAdapter, genie,
5576 &total_ielen, WPS_OUI_TYPE, WPS_OUI_TYPE_SIZE))
Jeff Johnson295189b2012-06-20 16:38:30 -07005577 {
c_hpothu6ff1c3c2013-10-01 19:01:57 +05305578 hddLog(LOGE,
5579 FL("Adding WPS IE failed"));
Gopichand Nakkala2b25f4e2013-03-21 19:14:07 +05305580 ret = -EINVAL;
5581 goto done;
Jeff Johnson295189b2012-06-20 16:38:30 -07005582 }
5583
5584#ifdef WLAN_FEATURE_WFD
Gopichand Nakkala2b25f4e2013-03-21 19:14:07 +05305585 if (0 != wlan_hdd_add_ie(pHostapdAdapter, genie,
5586 &total_ielen, WFD_OUI_TYPE, WFD_OUI_TYPE_SIZE))
5587 {
c_hpothu6ff1c3c2013-10-01 19:01:57 +05305588 hddLog(LOGE,
5589 FL("Adding WFD IE failed"));
Gopichand Nakkala2b25f4e2013-03-21 19:14:07 +05305590 ret = -EINVAL;
5591 goto done;
Jeff Johnson295189b2012-06-20 16:38:30 -07005592 }
5593#endif
5594
Gopichand Nakkala2b25f4e2013-03-21 19:14:07 +05305595 if (0 != wlan_hdd_add_ie(pHostapdAdapter, genie,
5596 &total_ielen, P2P_OUI_TYPE, P2P_OUI_TYPE_SIZE))
Jeff Johnson295189b2012-06-20 16:38:30 -07005597 {
c_hpothu6ff1c3c2013-10-01 19:01:57 +05305598 hddLog(LOGE,
5599 FL("Adding P2P IE failed"));
Gopichand Nakkala2b25f4e2013-03-21 19:14:07 +05305600 ret = -EINVAL;
5601 goto done;
5602 }
5603
5604 if (WLAN_HDD_SOFTAP == pHostapdAdapter->device_mode)
5605 {
Arif Hussaine7f3ea52013-09-12 21:56:36 -07005606 wlan_hdd_add_hostapd_conf_vsie(pHostapdAdapter, genie, &total_ielen);
Jeff Johnson295189b2012-06-20 16:38:30 -07005607 }
Jeff Johnson295189b2012-06-20 16:38:30 -07005608
5609 if (ccmCfgSetStr((WLAN_HDD_GET_CTX(pHostapdAdapter))->hHal,
5610 WNI_CFG_PROBE_RSP_BCN_ADDNIE_DATA, genie, total_ielen, NULL,
5611 eANI_BOOLEAN_FALSE)==eHAL_STATUS_FAILURE)
5612 {
5613 hddLog(LOGE,
5614 "Could not pass on WNI_CFG_PROBE_RSP_BCN_ADDNIE_DATA to CCM");
Jeff Johnsone7245742012-09-05 17:12:55 -07005615 ret = -EINVAL;
5616 goto done;
Jeff Johnson295189b2012-06-20 16:38:30 -07005617 }
5618
5619 if (ccmCfgSetInt((WLAN_HDD_GET_CTX(pHostapdAdapter))->hHal,
5620 WNI_CFG_PROBE_RSP_BCN_ADDNIE_FLAG, 1,NULL,
5621 test_bit(SOFTAP_BSS_STARTED, &pHostapdAdapter->event_flags) ?
5622 eANI_BOOLEAN_TRUE : eANI_BOOLEAN_FALSE)
5623 ==eHAL_STATUS_FAILURE)
5624 {
5625 hddLog(LOGE,
5626 "Could not pass on WNI_CFG_PROBE_RSP_BCN_ADDNIE_FLAG to CCM");
Jeff Johnsone7245742012-09-05 17:12:55 -07005627 ret = -EINVAL;
5628 goto done;
Jeff Johnson295189b2012-06-20 16:38:30 -07005629 }
5630
5631 // Added for ProResp IE
5632 if ( (params->proberesp_ies != NULL) && (params->proberesp_ies_len != 0) )
5633 {
5634 u16 rem_probe_resp_ie_len = params->proberesp_ies_len;
5635 u8 probe_rsp_ie_len[3] = {0};
5636 u8 counter = 0;
5637 /* Check Probe Resp Length if it is greater then 255 then Store
5638 Probe Resp IEs into WNI_CFG_PROBE_RSP_ADDNIE_DATA1 &
5639 WNI_CFG_PROBE_RSP_ADDNIE_DATA2 CFG Variable As We are not able
5640 Store More then 255 bytes into One Variable.
5641 */
5642 while ((rem_probe_resp_ie_len > 0) && (counter < 3))
5643 {
5644 if (rem_probe_resp_ie_len > MAX_CFG_STRING_LEN)
5645 {
5646 probe_rsp_ie_len[counter++] = MAX_CFG_STRING_LEN;
5647 rem_probe_resp_ie_len -= MAX_CFG_STRING_LEN;
5648 }
5649 else
5650 {
5651 probe_rsp_ie_len[counter++] = rem_probe_resp_ie_len;
5652 rem_probe_resp_ie_len = 0;
5653 }
5654 }
5655
5656 rem_probe_resp_ie_len = 0;
5657
5658 if (probe_rsp_ie_len[0] > 0)
5659 {
5660 if (ccmCfgSetStr((WLAN_HDD_GET_CTX(pHostapdAdapter))->hHal,
5661 WNI_CFG_PROBE_RSP_ADDNIE_DATA1,
5662 (tANI_U8*)&params->proberesp_ies[rem_probe_resp_ie_len],
5663 probe_rsp_ie_len[0], NULL,
5664 eANI_BOOLEAN_FALSE) == eHAL_STATUS_FAILURE)
5665 {
5666 hddLog(LOGE,
5667 "Could not pass on WNI_CFG_PROBE_RSP_ADDNIE_DATA1 to CCM");
Jeff Johnsone7245742012-09-05 17:12:55 -07005668 ret = -EINVAL;
5669 goto done;
Jeff Johnson295189b2012-06-20 16:38:30 -07005670 }
5671 rem_probe_resp_ie_len += probe_rsp_ie_len[0];
5672 }
5673
5674 if (probe_rsp_ie_len[1] > 0)
5675 {
5676 if (ccmCfgSetStr((WLAN_HDD_GET_CTX(pHostapdAdapter))->hHal,
5677 WNI_CFG_PROBE_RSP_ADDNIE_DATA2,
5678 (tANI_U8*)&params->proberesp_ies[rem_probe_resp_ie_len],
5679 probe_rsp_ie_len[1], NULL,
5680 eANI_BOOLEAN_FALSE) == eHAL_STATUS_FAILURE)
5681 {
5682 hddLog(LOGE,
5683 "Could not pass on WNI_CFG_PROBE_RSP_ADDNIE_DATA2 to CCM");
Jeff Johnsone7245742012-09-05 17:12:55 -07005684 ret = -EINVAL;
5685 goto done;
Jeff Johnson295189b2012-06-20 16:38:30 -07005686 }
5687 rem_probe_resp_ie_len += probe_rsp_ie_len[1];
5688 }
5689
5690 if (probe_rsp_ie_len[2] > 0)
5691 {
5692 if (ccmCfgSetStr((WLAN_HDD_GET_CTX(pHostapdAdapter))->hHal,
5693 WNI_CFG_PROBE_RSP_ADDNIE_DATA3,
5694 (tANI_U8*)&params->proberesp_ies[rem_probe_resp_ie_len],
5695 probe_rsp_ie_len[2], NULL,
5696 eANI_BOOLEAN_FALSE) == eHAL_STATUS_FAILURE)
5697 {
5698 hddLog(LOGE,
5699 "Could not pass on WNI_CFG_PROBE_RSP_ADDNIE_DATA3 to CCM");
Jeff Johnsone7245742012-09-05 17:12:55 -07005700 ret = -EINVAL;
5701 goto done;
Jeff Johnson295189b2012-06-20 16:38:30 -07005702 }
5703 rem_probe_resp_ie_len += probe_rsp_ie_len[2];
5704 }
5705
5706 if (probe_rsp_ie_len[1] == 0 )
5707 {
5708 if ( eHAL_STATUS_FAILURE == ccmCfgSetStr((WLAN_HDD_GET_CTX(pHostapdAdapter))->hHal,
5709 WNI_CFG_PROBE_RSP_ADDNIE_DATA2, (tANI_U8*)addIE, 0, NULL,
5710 eANI_BOOLEAN_FALSE) )
5711 {
5712 hddLog(LOGE,
Arif Hussain6d2a3322013-11-17 19:50:10 -08005713 "Could not pass on WNI_CFG_PROBE_RSP_ADDNIE_DATA2 to CCM");
Jeff Johnson295189b2012-06-20 16:38:30 -07005714 }
5715 }
5716
5717 if (probe_rsp_ie_len[2] == 0 )
5718 {
5719 if ( eHAL_STATUS_FAILURE == ccmCfgSetStr((WLAN_HDD_GET_CTX(pHostapdAdapter))->hHal,
5720 WNI_CFG_PROBE_RSP_ADDNIE_DATA3, (tANI_U8*)addIE, 0, NULL,
5721 eANI_BOOLEAN_FALSE) )
5722 {
5723 hddLog(LOGE,
Arif Hussain6d2a3322013-11-17 19:50:10 -08005724 "Could not pass on WNI_CFG_PROBE_RSP_ADDNIE_DATA3 to CCM");
Jeff Johnson295189b2012-06-20 16:38:30 -07005725 }
5726 }
5727
5728 if (ccmCfgSetInt((WLAN_HDD_GET_CTX(pHostapdAdapter))->hHal,
5729 WNI_CFG_PROBE_RSP_ADDNIE_FLAG, 1,NULL,
5730 test_bit(SOFTAP_BSS_STARTED, &pHostapdAdapter->event_flags) ?
5731 eANI_BOOLEAN_TRUE : eANI_BOOLEAN_FALSE)
5732 == eHAL_STATUS_FAILURE)
5733 {
5734 hddLog(LOGE,
5735 "Could not pass on WNI_CFG_PROBE_RSP_ADDNIE_FLAG to CCM");
Jeff Johnsone7245742012-09-05 17:12:55 -07005736 ret = -EINVAL;
5737 goto done;
Jeff Johnson295189b2012-06-20 16:38:30 -07005738 }
5739 }
5740 else
5741 {
5742 // Reset WNI_CFG_PROBE_RSP Flags
5743 wlan_hdd_reset_prob_rspies(pHostapdAdapter);
5744
5745 hddLog(VOS_TRACE_LEVEL_INFO,
5746 "%s: No Probe Response IE received in set beacon",
5747 __func__);
5748 }
5749
5750 // Added for AssocResp IE
5751 if ( (params->assocresp_ies != NULL) && (params->assocresp_ies_len != 0) )
5752 {
5753 if (ccmCfgSetStr((WLAN_HDD_GET_CTX(pHostapdAdapter))->hHal,
5754 WNI_CFG_ASSOC_RSP_ADDNIE_DATA, (tANI_U8*)params->assocresp_ies,
5755 params->assocresp_ies_len, NULL,
5756 eANI_BOOLEAN_FALSE) == eHAL_STATUS_FAILURE)
5757 {
5758 hddLog(LOGE,
5759 "Could not pass on WNI_CFG_ASSOC_RSP_ADDNIE_DATA to CCM");
Jeff Johnsone7245742012-09-05 17:12:55 -07005760 ret = -EINVAL;
5761 goto done;
Jeff Johnson295189b2012-06-20 16:38:30 -07005762 }
5763
5764 if (ccmCfgSetInt((WLAN_HDD_GET_CTX(pHostapdAdapter))->hHal,
5765 WNI_CFG_ASSOC_RSP_ADDNIE_FLAG, 1, NULL,
5766 test_bit(SOFTAP_BSS_STARTED, &pHostapdAdapter->event_flags) ?
5767 eANI_BOOLEAN_TRUE : eANI_BOOLEAN_FALSE)
5768 == eHAL_STATUS_FAILURE)
5769 {
5770 hddLog(LOGE,
5771 "Could not pass on WNI_CFG_ASSOC_RSP_ADDNIE_FLAG to CCM");
Jeff Johnsone7245742012-09-05 17:12:55 -07005772 ret = -EINVAL;
5773 goto done;
Jeff Johnson295189b2012-06-20 16:38:30 -07005774 }
5775 }
5776 else
5777 {
5778 hddLog(VOS_TRACE_LEVEL_INFO,
5779 "%s: No Assoc Response IE received in set beacon",
5780 __func__);
5781
5782 if ( eHAL_STATUS_FAILURE == ccmCfgSetInt((WLAN_HDD_GET_CTX(pHostapdAdapter))->hHal,
5783 WNI_CFG_ASSOC_RSP_ADDNIE_FLAG, 0, NULL,
5784 eANI_BOOLEAN_FALSE) )
5785 {
5786 hddLog(LOGE,
Arif Hussain6d2a3322013-11-17 19:50:10 -08005787 "Could not pass on WNI_CFG_ASSOC_RSP_ADDNIE_FLAG to CCM");
Jeff Johnson295189b2012-06-20 16:38:30 -07005788 }
5789 }
5790
Jeff Johnsone7245742012-09-05 17:12:55 -07005791done:
Jeff Johnson295189b2012-06-20 16:38:30 -07005792 vos_mem_free(genie);
Gopichand Nakkala2b25f4e2013-03-21 19:14:07 +05305793 return ret;
Jeff Johnson295189b2012-06-20 16:38:30 -07005794}
Jeff Johnson295189b2012-06-20 16:38:30 -07005795
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305796/*
Jeff Johnson295189b2012-06-20 16:38:30 -07005797 * FUNCTION: wlan_hdd_validate_operation_channel
5798 * called by wlan_hdd_cfg80211_start_bss() and
5799 * wlan_hdd_cfg80211_set_channel()
5800 * This function validates whether given channel is part of valid
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305801 * channel list.
5802 */
Varun Reddy Yeturu920df212013-05-22 08:07:23 -07005803VOS_STATUS wlan_hdd_validate_operation_channel(hdd_adapter_t *pAdapter,int channel)
Jeff Johnson295189b2012-06-20 16:38:30 -07005804{
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305805
Jeff Johnson295189b2012-06-20 16:38:30 -07005806 v_U32_t num_ch = 0;
5807 u8 valid_ch[WNI_CFG_VALID_CHANNEL_LIST_LEN];
5808 u32 indx = 0;
5809 tHalHandle hHal = WLAN_HDD_GET_HAL_CTX(pAdapter);
Madan Mohan Koyylamudi64267f72013-02-05 14:07:08 +05305810 v_U8_t fValidChannel = FALSE, count = 0;
5811 hdd_config_t *hdd_pConfig_ini= (WLAN_HDD_GET_CTX(pAdapter))->cfg_ini;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305812
Jeff Johnson295189b2012-06-20 16:38:30 -07005813 num_ch = WNI_CFG_VALID_CHANNEL_LIST_LEN;
5814
Madan Mohan Koyylamudi64267f72013-02-05 14:07:08 +05305815 if ( hdd_pConfig_ini->sapAllowAllChannel)
Jeff Johnson295189b2012-06-20 16:38:30 -07005816 {
Madan Mohan Koyylamudi64267f72013-02-05 14:07:08 +05305817 /* Validate the channel */
5818 for (count = RF_CHAN_1 ; count <= RF_CHAN_165 ; count++)
Jeff Johnson295189b2012-06-20 16:38:30 -07005819 {
Madan Mohan Koyylamudi64267f72013-02-05 14:07:08 +05305820 if ( channel == rfChannels[count].channelNum )
5821 {
5822 fValidChannel = TRUE;
5823 break;
5824 }
5825 }
5826 if (fValidChannel != TRUE)
5827 {
5828 hddLog(VOS_TRACE_LEVEL_ERROR,
5829 "%s: Invalid Channel [%d]", __func__, channel);
5830 return VOS_STATUS_E_FAILURE;
Jeff Johnson295189b2012-06-20 16:38:30 -07005831 }
5832 }
Madan Mohan Koyylamudi64267f72013-02-05 14:07:08 +05305833 else
Jeff Johnson295189b2012-06-20 16:38:30 -07005834 {
Madan Mohan Koyylamudi64267f72013-02-05 14:07:08 +05305835 if (0 != ccmCfgGetStr(hHal, WNI_CFG_VALID_CHANNEL_LIST,
5836 valid_ch, &num_ch))
5837 {
5838 hddLog(VOS_TRACE_LEVEL_ERROR,
5839 "%s: failed to get valid channel list", __func__);
5840 return VOS_STATUS_E_FAILURE;
5841 }
5842 for (indx = 0; indx < num_ch; indx++)
5843 {
5844 if (channel == valid_ch[indx])
5845 {
5846 break;
5847 }
5848 }
5849
Rashmi Ramanna3b59e122014-04-10 14:45:13 +05305850 if (indx >= num_ch)
5851 {
5852 if (WLAN_HDD_P2P_GO == pAdapter->device_mode)
5853 {
5854 eCsrBand band;
5855 unsigned int freq;
5856
5857 sme_GetFreqBand(hHal, &band);
5858
5859 if (eCSR_BAND_5G == band)
5860 {
5861#if (LINUX_VERSION_CODE > KERNEL_VERSION(2,6,38))
5862 if (channel <= ARRAY_SIZE(hdd_channels_2_4_GHZ))
5863 {
5864 freq = ieee80211_channel_to_frequency(channel,
5865 IEEE80211_BAND_2GHZ);
5866 }
5867 else
5868 {
5869 freq = ieee80211_channel_to_frequency(channel,
5870 IEEE80211_BAND_5GHZ);
5871 }
5872#else
5873 freq = ieee80211_channel_to_frequency(channel);
5874#endif
5875 if(WLAN_HDD_IS_SOCIAL_CHANNEL(freq))
5876 return VOS_STATUS_SUCCESS;
5877 }
5878 }
5879
5880 hddLog(VOS_TRACE_LEVEL_ERROR,
5881 "%s: Invalid Channel [%d]", __func__, channel);
5882 return VOS_STATUS_E_FAILURE;
5883 }
Jeff Johnson295189b2012-06-20 16:38:30 -07005884 }
Rashmi Ramanna3b59e122014-04-10 14:45:13 +05305885
Jeff Johnson295189b2012-06-20 16:38:30 -07005886 return VOS_STATUS_SUCCESS;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305887
Jeff Johnson295189b2012-06-20 16:38:30 -07005888}
5889
Viral Modi3a32cc52013-02-08 11:14:52 -08005890/**
5891 * FUNCTION: wlan_hdd_cfg80211_set_channel
5892 * This function is used to set the channel number
5893 */
5894static int wlan_hdd_cfg80211_set_channel( struct wiphy *wiphy, struct net_device *dev,
5895 struct ieee80211_channel *chan,
5896 enum nl80211_channel_type channel_type
5897 )
5898{
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05305899 hdd_adapter_t *pAdapter = NULL;
Viral Modi3a32cc52013-02-08 11:14:52 -08005900 v_U32_t num_ch = 0;
Jeff Johnson4416a782013-03-25 14:17:50 -07005901 int channel = 0;
Viral Modi3a32cc52013-02-08 11:14:52 -08005902 int freq = chan->center_freq; /* freq is in MHZ */
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05305903 hdd_context_t *pHddCtx;
5904 int status;
Viral Modi3a32cc52013-02-08 11:14:52 -08005905
5906 ENTER();
5907
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05305908
Viral Modi3a32cc52013-02-08 11:14:52 -08005909 if( NULL == dev )
5910 {
5911 hddLog(VOS_TRACE_LEVEL_ERROR,
Arif Hussain6d2a3322013-11-17 19:50:10 -08005912 "%s: Called with dev = NULL.", __func__);
Viral Modi3a32cc52013-02-08 11:14:52 -08005913 return -ENODEV;
5914 }
5915 pAdapter = WLAN_HDD_GET_PRIV_PTR( dev );
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +05305916
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05305917 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
5918 TRACE_CODE_HDD_CFG80211_SET_CHANNEL, pAdapter->sessionId,
5919 channel_type ));
Viral Modi3a32cc52013-02-08 11:14:52 -08005920 hddLog(VOS_TRACE_LEVEL_INFO,
Sushant Kaushik8bc7df22014-04-09 17:55:29 +05305921 "%s: device_mode = %s (%d) freq = %d", __func__,
5922 hdd_device_modetoString(pAdapter->device_mode),
5923 pAdapter->device_mode, chan->center_freq);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05305924
5925 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
5926 status = wlan_hdd_validate_context(pHddCtx);
5927
5928 if (0 != status)
Viral Modi3a32cc52013-02-08 11:14:52 -08005929 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05305930 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
5931 "%s: HDD context is not valid", __func__);
5932 return status;
Viral Modi3a32cc52013-02-08 11:14:52 -08005933 }
5934
5935 /*
5936 * Do freq to chan conversion
5937 * TODO: for 11a
5938 */
5939
5940 channel = ieee80211_frequency_to_channel(freq);
5941
5942 /* Check freq range */
5943 if ((WNI_CFG_CURRENT_CHANNEL_STAMIN > channel) ||
5944 (WNI_CFG_CURRENT_CHANNEL_STAMAX < channel))
5945 {
5946 hddLog(VOS_TRACE_LEVEL_ERROR,
Arif Hussain6d2a3322013-11-17 19:50:10 -08005947 "%s: Channel [%d] is outside valid range from %d to %d",
Viral Modi3a32cc52013-02-08 11:14:52 -08005948 __func__, channel, WNI_CFG_CURRENT_CHANNEL_STAMIN,
5949 WNI_CFG_CURRENT_CHANNEL_STAMAX);
5950 return -EINVAL;
5951 }
5952
5953 num_ch = WNI_CFG_VALID_CHANNEL_LIST_LEN;
5954
Gopichand Nakkala6ab19562013-03-07 13:59:42 +05305955 if ((WLAN_HDD_SOFTAP != pAdapter->device_mode) &&
5956 (WLAN_HDD_P2P_GO != pAdapter->device_mode))
Viral Modi3a32cc52013-02-08 11:14:52 -08005957 {
5958 if(VOS_STATUS_SUCCESS != wlan_hdd_validate_operation_channel(pAdapter,channel))
5959 {
5960 hddLog(VOS_TRACE_LEVEL_ERROR,
Arif Hussain6d2a3322013-11-17 19:50:10 -08005961 "%s: Invalid Channel [%d]", __func__, channel);
Viral Modi3a32cc52013-02-08 11:14:52 -08005962 return -EINVAL;
5963 }
5964 hddLog(VOS_TRACE_LEVEL_INFO_HIGH,
5965 "%s: set channel to [%d] for device mode =%d",
5966 __func__, channel,pAdapter->device_mode);
5967 }
5968 if( (pAdapter->device_mode == WLAN_HDD_INFRA_STATION)
Viral Modi3a32cc52013-02-08 11:14:52 -08005969 || (pAdapter->device_mode == WLAN_HDD_P2P_CLIENT)
Viral Modi3a32cc52013-02-08 11:14:52 -08005970 )
5971 {
5972 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
5973 tCsrRoamProfile * pRoamProfile = &pWextState->roamProfile;
5974 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
5975
5976 if (eConnectionState_IbssConnected == pHddStaCtx->conn_info.connState)
5977 {
5978 /* Link is up then return cant set channel*/
5979 hddLog( VOS_TRACE_LEVEL_ERROR,
Arif Hussain6d2a3322013-11-17 19:50:10 -08005980 "%s: IBSS Associated, can't set the channel", __func__);
Viral Modi3a32cc52013-02-08 11:14:52 -08005981 return -EINVAL;
5982 }
5983
5984 num_ch = pRoamProfile->ChannelInfo.numOfChannels = 1;
5985 pHddStaCtx->conn_info.operationChannel = channel;
5986 pRoamProfile->ChannelInfo.ChannelList =
5987 &pHddStaCtx->conn_info.operationChannel;
5988 }
5989 else if ((pAdapter->device_mode == WLAN_HDD_SOFTAP)
Viral Modi3a32cc52013-02-08 11:14:52 -08005990 || (pAdapter->device_mode == WLAN_HDD_P2P_GO)
Viral Modi3a32cc52013-02-08 11:14:52 -08005991 )
5992 {
Gopichand Nakkalac8fa7b62013-03-11 13:56:41 +05305993 if (WLAN_HDD_P2P_GO == pAdapter->device_mode)
5994 {
5995 if(VOS_STATUS_SUCCESS !=
5996 wlan_hdd_validate_operation_channel(pAdapter,channel))
5997 {
5998 hddLog(VOS_TRACE_LEVEL_ERROR,
Arif Hussain6d2a3322013-11-17 19:50:10 -08005999 "%s: Invalid Channel [%d]", __func__, channel);
Gopichand Nakkalac8fa7b62013-03-11 13:56:41 +05306000 return -EINVAL;
6001 }
6002 (WLAN_HDD_GET_AP_CTX_PTR(pAdapter))->sapConfig.channel = channel;
6003 }
6004 else if ( WLAN_HDD_SOFTAP == pAdapter->device_mode )
Viral Modi3a32cc52013-02-08 11:14:52 -08006005 {
6006 hdd_config_t *cfg_param = (WLAN_HDD_GET_CTX(pAdapter))->cfg_ini;
6007
6008 /* If auto channel selection is configured as enable/ 1 then ignore
6009 channel set by supplicant
6010 */
6011 if ( cfg_param->apAutoChannelSelection )
6012 {
Gopichand Nakkalac8fa7b62013-03-11 13:56:41 +05306013 (WLAN_HDD_GET_AP_CTX_PTR(pAdapter))->sapConfig.channel =
6014 AUTO_CHANNEL_SELECT;
Viral Modi3a32cc52013-02-08 11:14:52 -08006015 hddLog(VOS_TRACE_LEVEL_INFO_HIGH,
Sushant Kaushik8bc7df22014-04-09 17:55:29 +05306016 "%s: set channel to auto channel (0) for device mode =%s (%d)",
6017 __func__, hdd_device_modetoString(pAdapter->device_mode),
6018 pAdapter->device_mode);
Viral Modi3a32cc52013-02-08 11:14:52 -08006019 }
Gopichand Nakkalac8fa7b62013-03-11 13:56:41 +05306020 else
6021 {
6022 if(VOS_STATUS_SUCCESS !=
6023 wlan_hdd_validate_operation_channel(pAdapter,channel))
6024 {
6025 hddLog(VOS_TRACE_LEVEL_ERROR,
Arif Hussain6d2a3322013-11-17 19:50:10 -08006026 "%s: Invalid Channel [%d]", __func__, channel);
Gopichand Nakkalac8fa7b62013-03-11 13:56:41 +05306027 return -EINVAL;
6028 }
6029 (WLAN_HDD_GET_AP_CTX_PTR(pAdapter))->sapConfig.channel = channel;
6030 }
Viral Modi3a32cc52013-02-08 11:14:52 -08006031 }
6032 }
6033 else
6034 {
6035 hddLog(VOS_TRACE_LEVEL_FATAL,
6036 "%s: Invalid device mode failed to set valid channel", __func__);
6037 return -EINVAL;
6038 }
6039 EXIT();
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05306040 return status;
Viral Modi3a32cc52013-02-08 11:14:52 -08006041}
6042
Jeff Johnson295189b2012-06-20 16:38:30 -07006043#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,4,0))
6044static int wlan_hdd_cfg80211_start_bss(hdd_adapter_t *pHostapdAdapter,
6045 struct beacon_parameters *params)
Jeff Johnson04dd8a82012-06-29 20:41:40 -07006046#else
6047static int wlan_hdd_cfg80211_start_bss(hdd_adapter_t *pHostapdAdapter,
6048 struct cfg80211_beacon_data *params,
6049 const u8 *ssid, size_t ssid_len,
6050 enum nl80211_hidden_ssid hidden_ssid)
6051#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07006052{
6053 tsap_Config_t *pConfig;
6054 beacon_data_t *pBeacon = NULL;
6055 struct ieee80211_mgmt *pMgmt_frame;
6056 v_U8_t *pIe=NULL;
6057 v_U16_t capab_info;
6058 eCsrAuthType RSNAuthType;
6059 eCsrEncryptionType RSNEncryptType;
6060 eCsrEncryptionType mcRSNEncryptType;
6061 int status = VOS_STATUS_SUCCESS;
6062 tpWLAN_SAPEventCB pSapEventCallback;
6063 hdd_hostapd_state_t *pHostapdState;
6064 v_U8_t wpaRsnIEdata[(SIR_MAC_MAX_IE_LENGTH * 2)+4]; //Max ie length 255 * 2(WPA+RSN) + 2 bytes (vendor specific ID) * 2
6065 v_CONTEXT_t pVosContext = (WLAN_HDD_GET_CTX(pHostapdAdapter))->pvosContext;
Madan Mohan Koyylamudia16d0202013-02-01 11:05:57 +05306066 tHalHandle hHal = WLAN_HDD_GET_HAL_CTX(pHostapdAdapter);
Jeff Johnson295189b2012-06-20 16:38:30 -07006067 struct qc_mac_acl_entry *acl_entry = NULL;
Siddharth Bhal5cba24e2014-05-08 18:59:39 +05306068 hdd_config_t *iniConfig;
Jeff Johnson295189b2012-06-20 16:38:30 -07006069 v_SINT_t i;
Madan Mohan Koyyalamudi543172b2012-12-05 16:40:18 -08006070 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pHostapdAdapter);
Peng Xu2446a892014-09-05 17:21:18 +05306071 tSmeConfigParams *psmeConfig;
Chet Lanctot40142442014-05-20 13:39:25 -07006072 v_BOOL_t MFPCapable = VOS_FALSE;
6073 v_BOOL_t MFPRequired = VOS_FALSE;
Abhishek Singhf0ac1752014-03-05 17:47:09 +05306074 eHddDot11Mode sapDot11Mode =
6075 (WLAN_HDD_GET_CTX(pHostapdAdapter))->cfg_ini->sapDot11Mode;
Jeff Johnson295189b2012-06-20 16:38:30 -07006076
6077 ENTER();
6078
Siddharth Bhal5cba24e2014-05-08 18:59:39 +05306079 iniConfig = pHddCtx->cfg_ini;
6080
Jeff Johnson295189b2012-06-20 16:38:30 -07006081 pHostapdState = WLAN_HDD_GET_HOSTAP_STATE_PTR(pHostapdAdapter);
6082
6083 pConfig = &pHostapdAdapter->sessionCtx.ap.sapConfig;
6084
6085 pBeacon = pHostapdAdapter->sessionCtx.ap.beacon;
6086
6087 pMgmt_frame = (struct ieee80211_mgmt*)pBeacon->head;
6088
6089 pConfig->beacon_int = pMgmt_frame->u.beacon.beacon_int;
6090
6091 //channel is already set in the set_channel Call back
6092 //pConfig->channel = pCommitConfig->channel;
6093
6094 /*Protection parameter to enable or disable*/
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306095 pConfig->protEnabled =
Jeff Johnson295189b2012-06-20 16:38:30 -07006096 (WLAN_HDD_GET_CTX(pHostapdAdapter))->cfg_ini->apProtEnabled;
6097
6098 pConfig->dtim_period = pBeacon->dtim_period;
6099
Arif Hussain6d2a3322013-11-17 19:50:10 -08006100 hddLog(VOS_TRACE_LEVEL_INFO_HIGH,"****pConfig->dtim_period=%d***",
Jeff Johnson295189b2012-06-20 16:38:30 -07006101 pConfig->dtim_period);
6102
Madan Mohan Koyyalamudie0ca11f2012-11-27 15:57:52 -08006103 if (pHostapdAdapter->device_mode == WLAN_HDD_SOFTAP)
Jeff Johnson32d95a32012-09-10 13:15:23 -07006104 {
6105 pIe = wlan_hdd_cfg80211_get_ie_ptr(pBeacon->tail, pBeacon->tail_len,
Jeff Johnson295189b2012-06-20 16:38:30 -07006106 WLAN_EID_COUNTRY);
Kiet Lam083504c2013-11-25 14:17:45 +05306107 if(memcmp(pHddCtx->cfg_ini->apCntryCode, CFG_AP_COUNTRY_CODE_DEFAULT, 3) != 0)
6108 {
6109 tANI_BOOLEAN restartNeeded;
6110 pConfig->ieee80211d = 1;
6111 vos_mem_copy(pConfig->countryCode, pHddCtx->cfg_ini->apCntryCode, 3);
6112 sme_setRegInfo(hHal, pConfig->countryCode);
6113 sme_ResetCountryCodeInformation(hHal, &restartNeeded);
6114 }
6115 else if(pIe)
Jeff Johnson295189b2012-06-20 16:38:30 -07006116 {
Jeff Johnson32d95a32012-09-10 13:15:23 -07006117 tANI_BOOLEAN restartNeeded;
Jeff Johnson32d95a32012-09-10 13:15:23 -07006118 pConfig->ieee80211d = 1;
6119 vos_mem_copy(pConfig->countryCode, &pIe[2], 3);
6120 sme_setRegInfo(hHal, pConfig->countryCode);
6121 sme_ResetCountryCodeInformation(hHal, &restartNeeded);
Jeff Johnson295189b2012-06-20 16:38:30 -07006122 }
Jeff Johnson32d95a32012-09-10 13:15:23 -07006123 else
6124 {
6125 pConfig->ieee80211d = 0;
6126 }
Madan Mohan Koyylamudia16d0202013-02-01 11:05:57 +05306127 /*
6128 * If auto channel is configured i.e. channel is 0,
6129 * so skip channel validation.
6130 */
6131 if( AUTO_CHANNEL_SELECT != pConfig->channel )
6132 {
6133 if(VOS_STATUS_SUCCESS != wlan_hdd_validate_operation_channel(pHostapdAdapter,pConfig->channel))
6134 {
6135 hddLog(VOS_TRACE_LEVEL_ERROR,
Arif Hussain6d2a3322013-11-17 19:50:10 -08006136 "%s: Invalid Channel [%d]", __func__, pConfig->channel);
Madan Mohan Koyylamudia16d0202013-02-01 11:05:57 +05306137 return -EINVAL;
6138 }
6139 }
6140 else
6141 {
6142 if(1 != pHddCtx->is_dynamic_channel_range_set)
6143 {
6144 hdd_config_t *hdd_pConfig= (WLAN_HDD_GET_CTX(pHostapdAdapter))->cfg_ini;
6145 WLANSAP_SetChannelRange(hHal, hdd_pConfig->apStartChannelNum,
6146 hdd_pConfig->apEndChannelNum,hdd_pConfig->apOperatingBand);
6147 }
6148 pHddCtx->is_dynamic_channel_range_set = 0;
6149 }
Jeff Johnson295189b2012-06-20 16:38:30 -07006150 }
Jeff Johnson32d95a32012-09-10 13:15:23 -07006151 else
Jeff Johnson295189b2012-06-20 16:38:30 -07006152 {
6153 pConfig->ieee80211d = 0;
6154 }
6155 pConfig->authType = eSAP_AUTO_SWITCH;
6156
6157 capab_info = pMgmt_frame->u.beacon.capab_info;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306158
6159 pConfig->privacy = (pMgmt_frame->u.beacon.capab_info &
Jeff Johnson295189b2012-06-20 16:38:30 -07006160 WLAN_CAPABILITY_PRIVACY) ? VOS_TRUE : VOS_FALSE;
6161
6162 (WLAN_HDD_GET_AP_CTX_PTR(pHostapdAdapter))->uPrivacy = pConfig->privacy;
6163
6164 /*Set wps station to configured*/
6165 pIe = wlan_hdd_get_wps_ie_ptr(pBeacon->tail, pBeacon->tail_len);
6166
6167 if(pIe)
6168 {
6169 if(pIe[1] < (2 + WPS_OUI_TYPE_SIZE))
6170 {
Arif Hussain6d2a3322013-11-17 19:50:10 -08006171 hddLog( VOS_TRACE_LEVEL_ERROR, "**Wps Ie Length is too small***");
Jeff Johnson295189b2012-06-20 16:38:30 -07006172 return -EINVAL;
6173 }
6174 else if(memcmp(&pIe[2], WPS_OUI_TYPE, WPS_OUI_TYPE_SIZE) == 0)
6175 {
Madan Mohan Koyyalamudi8bdd3112012-09-24 13:55:14 -07006176 hddLog( VOS_TRACE_LEVEL_INFO, "** WPS IE(len %d) ***", (pIe[1]+2));
Jeff Johnson295189b2012-06-20 16:38:30 -07006177 /* Check 15 bit of WPS IE as it contain information for wps state
6178 * WPS state
6179 */
6180 if(SAP_WPS_ENABLED_UNCONFIGURED == pIe[15])
6181 {
6182 pConfig->wps_state = SAP_WPS_ENABLED_UNCONFIGURED;
6183 } else if(SAP_WPS_ENABLED_CONFIGURED == pIe[15])
6184 {
6185 pConfig->wps_state = SAP_WPS_ENABLED_CONFIGURED;
6186 }
6187 }
6188 }
6189 else
6190 {
6191 pConfig->wps_state = SAP_WPS_DISABLED;
6192 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306193 pConfig->fwdWPSPBCProbeReq = 1; // Forward WPS PBC probe request frame up
Jeff Johnson295189b2012-06-20 16:38:30 -07006194
c_hpothufe599e92014-06-16 11:38:55 +05306195 pConfig->RSNEncryptType = eCSR_ENCRYPT_TYPE_NONE;
6196 pConfig->mcRSNEncryptType = eCSR_ENCRYPT_TYPE_NONE;
6197 (WLAN_HDD_GET_AP_CTX_PTR(pHostapdAdapter))->ucEncryptType =
6198 eCSR_ENCRYPT_TYPE_NONE;
6199
Jeff Johnson295189b2012-06-20 16:38:30 -07006200 pConfig->RSNWPAReqIELength = 0;
6201 pConfig->pRSNWPAReqIE = NULL;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306202 pIe = wlan_hdd_cfg80211_get_ie_ptr(pBeacon->tail, pBeacon->tail_len,
Jeff Johnson295189b2012-06-20 16:38:30 -07006203 WLAN_EID_RSN);
6204 if(pIe && pIe[1])
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306205 {
Jeff Johnson295189b2012-06-20 16:38:30 -07006206 pConfig->RSNWPAReqIELength = pIe[1] + 2;
6207 memcpy(&wpaRsnIEdata[0], pIe, pConfig->RSNWPAReqIELength);
6208 pConfig->pRSNWPAReqIE = &wpaRsnIEdata[0];
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306209 /* The actual processing may eventually be more extensive than
6210 * this. Right now, just consume any PMKIDs that are sent in
Jeff Johnson295189b2012-06-20 16:38:30 -07006211 * by the app.
6212 * */
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306213 status = hdd_softap_unpackIE(
Jeff Johnson295189b2012-06-20 16:38:30 -07006214 vos_get_context( VOS_MODULE_ID_SME, pVosContext),
6215 &RSNEncryptType,
6216 &mcRSNEncryptType,
6217 &RSNAuthType,
Chet Lanctot8cecea22014-02-11 19:09:36 -08006218 &MFPCapable,
6219 &MFPRequired,
Jeff Johnson295189b2012-06-20 16:38:30 -07006220 pConfig->pRSNWPAReqIE[1]+2,
6221 pConfig->pRSNWPAReqIE );
6222
6223 if( VOS_STATUS_SUCCESS == status )
6224 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306225 /* Now copy over all the security attributes you have
6226 * parsed out
Jeff Johnson295189b2012-06-20 16:38:30 -07006227 * */
6228 pConfig->RSNEncryptType = RSNEncryptType; // Use the cipher type in the RSN IE
6229 pConfig->mcRSNEncryptType = mcRSNEncryptType;
6230 (WLAN_HDD_GET_AP_CTX_PTR(pHostapdAdapter))->ucEncryptType
6231 = RSNEncryptType;
Gopichand Nakkala66c0bd02013-04-10 11:36:29 +05306232 hddLog( LOG1, FL("CSR AuthType = %d, "
Arif Hussain6d2a3322013-11-17 19:50:10 -08006233 "EncryptionType = %d mcEncryptionType = %d"),
Jeff Johnson295189b2012-06-20 16:38:30 -07006234 RSNAuthType, RSNEncryptType, mcRSNEncryptType);
6235 }
6236 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306237
Jeff Johnson295189b2012-06-20 16:38:30 -07006238 pIe = wlan_hdd_get_vendor_oui_ie_ptr(WPA_OUI_TYPE, WPA_OUI_TYPE_SIZE,
6239 pBeacon->tail, pBeacon->tail_len);
6240
6241 if(pIe && pIe[1] && (pIe[0] == DOT11F_EID_WPA))
6242 {
6243 if (pConfig->pRSNWPAReqIE)
6244 {
6245 /*Mixed mode WPA/WPA2*/
6246 memcpy((&wpaRsnIEdata[0] + pConfig->RSNWPAReqIELength), pIe, pIe[1] + 2);
6247 pConfig->RSNWPAReqIELength += pIe[1] + 2;
6248 }
6249 else
6250 {
6251 pConfig->RSNWPAReqIELength = pIe[1] + 2;
6252 memcpy(&wpaRsnIEdata[0], pIe, pConfig->RSNWPAReqIELength);
6253 pConfig->pRSNWPAReqIE = &wpaRsnIEdata[0];
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306254 status = hdd_softap_unpackIE(
Jeff Johnson295189b2012-06-20 16:38:30 -07006255 vos_get_context( VOS_MODULE_ID_SME, pVosContext),
6256 &RSNEncryptType,
6257 &mcRSNEncryptType,
6258 &RSNAuthType,
Chet Lanctot8cecea22014-02-11 19:09:36 -08006259 &MFPCapable,
6260 &MFPRequired,
Jeff Johnson295189b2012-06-20 16:38:30 -07006261 pConfig->pRSNWPAReqIE[1]+2,
6262 pConfig->pRSNWPAReqIE );
6263
6264 if( VOS_STATUS_SUCCESS == status )
6265 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306266 /* Now copy over all the security attributes you have
6267 * parsed out
Jeff Johnson295189b2012-06-20 16:38:30 -07006268 * */
6269 pConfig->RSNEncryptType = RSNEncryptType; // Use the cipher type in the RSN IE
6270 pConfig->mcRSNEncryptType = mcRSNEncryptType;
6271 (WLAN_HDD_GET_AP_CTX_PTR(pHostapdAdapter))->ucEncryptType
6272 = RSNEncryptType;
Gopichand Nakkala66c0bd02013-04-10 11:36:29 +05306273 hddLog( LOG1, FL("CSR AuthType = %d, "
Arif Hussain6d2a3322013-11-17 19:50:10 -08006274 "EncryptionType = %d mcEncryptionType = %d"),
Jeff Johnson295189b2012-06-20 16:38:30 -07006275 RSNAuthType, RSNEncryptType, mcRSNEncryptType);
6276 }
6277 }
6278 }
6279
Jeff Johnson4416a782013-03-25 14:17:50 -07006280 if (pConfig->RSNWPAReqIELength > sizeof wpaRsnIEdata) {
6281 hddLog( VOS_TRACE_LEVEL_ERROR, "**RSNWPAReqIELength is too large***");
6282 return -EINVAL;
6283 }
6284
Jeff Johnson295189b2012-06-20 16:38:30 -07006285 pConfig->SSIDinfo.ssidHidden = VOS_FALSE;
6286
Jeff Johnson04dd8a82012-06-29 20:41:40 -07006287#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,4,0))
Jeff Johnson295189b2012-06-20 16:38:30 -07006288 if (params->ssid != NULL)
6289 {
6290 memcpy(pConfig->SSIDinfo.ssid.ssId, params->ssid, params->ssid_len);
6291 pConfig->SSIDinfo.ssid.length = params->ssid_len;
6292 if (params->hidden_ssid != NL80211_HIDDEN_SSID_NOT_IN_USE)
6293 pConfig->SSIDinfo.ssidHidden = VOS_TRUE;
6294 }
Jeff Johnson04dd8a82012-06-29 20:41:40 -07006295#else
6296 if (ssid != NULL)
6297 {
6298 memcpy(pConfig->SSIDinfo.ssid.ssId, ssid, ssid_len);
6299 pConfig->SSIDinfo.ssid.length = ssid_len;
6300 if (hidden_ssid != NL80211_HIDDEN_SSID_NOT_IN_USE)
6301 pConfig->SSIDinfo.ssidHidden = VOS_TRUE;
6302 }
6303#endif
6304
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306305 vos_mem_copy(pConfig->self_macaddr.bytes,
Jeff Johnson295189b2012-06-20 16:38:30 -07006306 pHostapdAdapter->macAddressCurrent.bytes, sizeof(v_MACADDR_t));
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306307
Jeff Johnson295189b2012-06-20 16:38:30 -07006308 /* default value */
6309 pConfig->SapMacaddr_acl = eSAP_ACCEPT_UNLESS_DENIED;
6310 pConfig->num_accept_mac = 0;
6311 pConfig->num_deny_mac = 0;
6312
6313 pIe = wlan_hdd_get_vendor_oui_ie_ptr(BLACKLIST_OUI_TYPE, WPA_OUI_TYPE_SIZE,
6314 pBeacon->tail, pBeacon->tail_len);
6315
6316 /* pIe for black list is following form:
6317 type : 1 byte
6318 length : 1 byte
6319 OUI : 4 bytes
6320 acl type : 1 byte
6321 no of mac addr in black list: 1 byte
6322 list of mac_acl_entries: variable, 6 bytes per mac address + sizeof(int) for vlan id
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306323 */
6324 if ((pIe != NULL) && (pIe[1] != 0))
Jeff Johnson295189b2012-06-20 16:38:30 -07006325 {
6326 pConfig->SapMacaddr_acl = pIe[6];
6327 pConfig->num_deny_mac = pIe[7];
Arif Hussain6d2a3322013-11-17 19:50:10 -08006328 hddLog(VOS_TRACE_LEVEL_INFO,"acl type = %d no deny mac = %d",
Jeff Johnson295189b2012-06-20 16:38:30 -07006329 pIe[6], pIe[7]);
Gopichand Nakkalac005b7c2013-05-14 16:04:14 +05306330 if (pConfig->num_deny_mac > MAX_ACL_MAC_ADDRESS)
6331 pConfig->num_deny_mac = MAX_ACL_MAC_ADDRESS;
Jeff Johnson295189b2012-06-20 16:38:30 -07006332 acl_entry = (struct qc_mac_acl_entry *)(pIe + 8);
6333 for (i = 0; i < pConfig->num_deny_mac; i++)
6334 {
6335 vos_mem_copy(&pConfig->deny_mac[i], acl_entry->addr, sizeof(qcmacaddr));
6336 acl_entry++;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306337 }
Jeff Johnson295189b2012-06-20 16:38:30 -07006338 }
6339 pIe = wlan_hdd_get_vendor_oui_ie_ptr(WHITELIST_OUI_TYPE, WPA_OUI_TYPE_SIZE,
6340 pBeacon->tail, pBeacon->tail_len);
6341
6342 /* pIe for white list is following form:
6343 type : 1 byte
6344 length : 1 byte
6345 OUI : 4 bytes
6346 acl type : 1 byte
6347 no of mac addr in white list: 1 byte
6348 list of mac_acl_entries: variable, 6 bytes per mac address + sizeof(int) for vlan id
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306349 */
6350 if ((pIe != NULL) && (pIe[1] != 0))
Jeff Johnson295189b2012-06-20 16:38:30 -07006351 {
6352 pConfig->SapMacaddr_acl = pIe[6];
6353 pConfig->num_accept_mac = pIe[7];
Arif Hussain6d2a3322013-11-17 19:50:10 -08006354 hddLog(VOS_TRACE_LEVEL_INFO,"acl type = %d no accept mac = %d",
Jeff Johnson295189b2012-06-20 16:38:30 -07006355 pIe[6], pIe[7]);
Gopichand Nakkalac005b7c2013-05-14 16:04:14 +05306356 if (pConfig->num_accept_mac > MAX_ACL_MAC_ADDRESS)
6357 pConfig->num_accept_mac = MAX_ACL_MAC_ADDRESS;
Jeff Johnson295189b2012-06-20 16:38:30 -07006358 acl_entry = (struct qc_mac_acl_entry *)(pIe + 8);
6359 for (i = 0; i < pConfig->num_accept_mac; i++)
6360 {
6361 vos_mem_copy(&pConfig->accept_mac[i], acl_entry->addr, sizeof(qcmacaddr));
6362 acl_entry++;
6363 }
6364 }
Gopichand Nakkalac005b7c2013-05-14 16:04:14 +05306365
Jeff Johnson295189b2012-06-20 16:38:30 -07006366 wlan_hdd_set_sapHwmode(pHostapdAdapter);
6367
Jeff Johnsone7245742012-09-05 17:12:55 -07006368#ifdef WLAN_FEATURE_11AC
Ravi Kumar Vaishnavbbaebbe2013-01-15 17:09:48 -08006369 /* Overwrite the hostapd setting for HW mode only for 11ac.
Kiet Lam0f320422013-11-21 19:29:17 +05306370 * This is valid only if mode is set to 11n in hostapd, either AUTO or
6371 * 11ac in .ini and 11ac is supported by both host and firmware.
6372 * Otherwise, leave whatever is set in hostapd (a OR b OR g OR n mode)
6373 */
Ravi Kumar Vaishnavbbaebbe2013-01-15 17:09:48 -08006374 if( ((pConfig->SapHw_mode == eSAP_DOT11_MODE_11n) ||
6375 (pConfig->SapHw_mode == eSAP_DOT11_MODE_11n_ONLY)) &&
Abhishek Singhf0ac1752014-03-05 17:47:09 +05306376 (( sapDot11Mode == eHDD_DOT11_MODE_AUTO ) ||
6377 ( sapDot11Mode == eHDD_DOT11_MODE_11ac ) ||
6378 ( sapDot11Mode == eHDD_DOT11_MODE_11ac_ONLY ) ) &&
6379 (sme_IsFeatureSupportedByDriver(DOT11AC)) &&
6380 (sme_IsFeatureSupportedByFW(DOT11AC)) )
Jeff Johnsone7245742012-09-05 17:12:55 -07006381 {
Siddharth Bhalf42f8592014-05-15 13:39:07 +05306382 v_U32_t operatingBand = 0;
Jeff Johnsone7245742012-09-05 17:12:55 -07006383 pConfig->SapHw_mode = eSAP_DOT11_MODE_11ac;
Siddharth Bhalf42f8592014-05-15 13:39:07 +05306384 ccmCfgGetInt(hHal, WNI_CFG_SAP_CHANNEL_SELECT_OPERATING_BAND, &operatingBand);
Ravi Joshi83bfaa12013-05-28 22:12:08 -07006385
Siddharth Bhal5cba24e2014-05-08 18:59:39 +05306386 /* If ACS disable and selected channel <= 14
6387 * OR
6388 * ACS enabled and ACS operating band is choosen as 2.4
6389 * AND
6390 * VHT in 2.4G Disabled
6391 * THEN
6392 * Fallback to 11N mode
6393 */
6394 if (((AUTO_CHANNEL_SELECT != pConfig->channel && pConfig->channel <= SIR_11B_CHANNEL_END)
6395 || (AUTO_CHANNEL_SELECT == pConfig->channel &&
Deepthi Gowri7db41f32014-10-13 17:02:29 +05306396 operatingBand == eSAP_RF_SUBBAND_2_4_GHZ)) &&
Siddharth Bhal5cba24e2014-05-08 18:59:39 +05306397 iniConfig->enableVhtFor24GHzBand == FALSE)
Ravi Joshi83bfaa12013-05-28 22:12:08 -07006398 {
Siddharth Bhalf42f8592014-05-15 13:39:07 +05306399 hddLog(LOGW, FL("Setting hwmode to 11n, operatingBand = %d, Channel = %d"),
6400 operatingBand, pConfig->channel);
Ravi Joshi83bfaa12013-05-28 22:12:08 -07006401 pConfig->SapHw_mode = eSAP_DOT11_MODE_11n;
6402 }
Jeff Johnsone7245742012-09-05 17:12:55 -07006403 }
6404#endif
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306405
Ravi Joshiaeb7d9e2013-05-02 12:28:14 -07006406 if ( AUTO_CHANNEL_SELECT != pConfig->channel )
6407 {
6408 sme_SelectCBMode(hHal,
6409 sapConvertSapPhyModeToCsrPhyMode(pConfig->SapHw_mode),
6410 pConfig->channel);
6411 }
Jeff Johnson295189b2012-06-20 16:38:30 -07006412 // ht_capab is not what the name conveys,this is used for protection bitmap
6413 pConfig->ht_capab =
6414 (WLAN_HDD_GET_CTX(pHostapdAdapter))->cfg_ini->apProtection;
6415
6416 if ( 0 != wlan_hdd_cfg80211_update_apies(pHostapdAdapter, params) )
6417 {
6418 hddLog(LOGE, FL("SAP Not able to set AP IEs"));
6419 return -EINVAL;
6420 }
6421
6422 //Uapsd Enabled Bit
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306423 pConfig->UapsdEnable =
Jeff Johnson295189b2012-06-20 16:38:30 -07006424 (WLAN_HDD_GET_CTX(pHostapdAdapter))->cfg_ini->apUapsdEnabled;
6425 //Enable OBSS protection
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306426 pConfig->obssProtEnabled =
6427 (WLAN_HDD_GET_CTX(pHostapdAdapter))->cfg_ini->apOBSSProtEnabled;
Jeff Johnson295189b2012-06-20 16:38:30 -07006428
Chet Lanctot8cecea22014-02-11 19:09:36 -08006429#ifdef WLAN_FEATURE_11W
6430 pConfig->mfpCapable = MFPCapable;
6431 pConfig->mfpRequired = MFPRequired;
6432 hddLog(LOGW, FL("Soft AP MFP capable %d, MFP required %d\n"),
6433 pConfig->mfpCapable, pConfig->mfpRequired);
6434#endif
6435
Arif Hussain6d2a3322013-11-17 19:50:10 -08006436 hddLog(LOGW, FL("SOftAP macaddress : "MAC_ADDRESS_STR),
Jeff Johnson295189b2012-06-20 16:38:30 -07006437 MAC_ADDR_ARRAY(pHostapdAdapter->macAddressCurrent.bytes));
Arif Hussain6d2a3322013-11-17 19:50:10 -08006438 hddLog(LOGW,FL("ssid =%s, beaconint=%d, channel=%d"),
6439 pConfig->SSIDinfo.ssid.ssId, (int)pConfig->beacon_int,
6440 (int)pConfig->channel);
6441 hddLog(LOGW,FL("hw_mode=%x, privacy=%d, authType=%d"),
6442 pConfig->SapHw_mode, pConfig->privacy,
6443 pConfig->authType);
6444 hddLog(LOGW,FL("RSN/WPALen=%d, Uapsd = %d"),
6445 (int)pConfig->RSNWPAReqIELength, pConfig->UapsdEnable);
6446 hddLog(LOGW,FL("ProtEnabled = %d, OBSSProtEnabled = %d"),
6447 pConfig->protEnabled, pConfig->obssProtEnabled);
Jeff Johnson295189b2012-06-20 16:38:30 -07006448
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306449 if(test_bit(SOFTAP_BSS_STARTED, &pHostapdAdapter->event_flags))
Jeff Johnson295189b2012-06-20 16:38:30 -07006450 {
6451 //Bss already started. just return.
6452 //TODO Probably it should update some beacon params.
6453 hddLog( LOGE, "Bss Already started...Ignore the request");
6454 EXIT();
6455 return 0;
6456 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306457
Agarwal Ashish51325b52014-06-16 16:50:49 +05306458 if (vos_max_concurrent_connections_reached()) {
6459 hddLog(VOS_TRACE_LEVEL_INFO, FL("Reached max concurrent connections"));
6460 return -EINVAL;
6461 }
6462
Jeff Johnson295189b2012-06-20 16:38:30 -07006463 pConfig->persona = pHostapdAdapter->device_mode;
6464
Peng Xu2446a892014-09-05 17:21:18 +05306465 psmeConfig = (tSmeConfigParams*) vos_mem_malloc(sizeof(tSmeConfigParams));
6466 if ( NULL != psmeConfig)
6467 {
6468 sme_GetConfigParam(hHal, psmeConfig);
6469 pConfig->scanBandPreference = psmeConfig->csrConfig.scanBandPreference;
6470 vos_mem_free(psmeConfig);
6471 }
Peng Xuafc34e32014-09-25 13:23:55 +05306472 pConfig->acsBandSwitchThreshold = iniConfig->acsBandSwitchThreshold;
Peng Xu2446a892014-09-05 17:21:18 +05306473
Jeff Johnson295189b2012-06-20 16:38:30 -07006474 pSapEventCallback = hdd_hostapd_SAPEventCB;
6475 if(WLANSAP_StartBss(pVosContext, pSapEventCallback, pConfig,
6476 (v_PVOID_t)pHostapdAdapter->dev) != VOS_STATUS_SUCCESS)
6477 {
Arif Hussain6d2a3322013-11-17 19:50:10 -08006478 hddLog(LOGE,FL("SAP Start Bss fail"));
Jeff Johnson295189b2012-06-20 16:38:30 -07006479 return -EINVAL;
6480 }
6481
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306482 hddLog(LOG1,
Jeff Johnson295189b2012-06-20 16:38:30 -07006483 FL("Waiting for Scan to complete(auto mode) and BSS to start"));
6484
6485 status = vos_wait_single_event(&pHostapdState->vosEvent, 10000);
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306486
Jeff Johnson295189b2012-06-20 16:38:30 -07006487 if (!VOS_IS_STATUS_SUCCESS(status))
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306488 {
6489 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Arif Hussain6d2a3322013-11-17 19:50:10 -08006490 ("ERROR: HDD vos wait for single_event failed!!"));
Tushnim Bhattacharyyaad37df12013-10-02 12:01:33 -07006491 smeGetCommandQStatus(hHal);
Jeff Johnson295189b2012-06-20 16:38:30 -07006492 VOS_ASSERT(0);
6493 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306494
Jeff Johnson295189b2012-06-20 16:38:30 -07006495 set_bit(SOFTAP_BSS_STARTED, &pHostapdAdapter->event_flags);
Kaushik, Sushantf6070802014-10-15 15:09:23 +05306496 /* Initialize WMM configuation */
6497 hdd_wmm_init(pHostapdAdapter);
Agarwal Ashish51325b52014-06-16 16:50:49 +05306498 wlan_hdd_incr_active_session(pHddCtx, pHostapdAdapter->device_mode);
Jeff Johnson295189b2012-06-20 16:38:30 -07006499
Madan Mohan Koyyalamudi26bd7142012-10-30 18:14:19 -07006500#ifdef WLAN_FEATURE_P2P_DEBUG
6501 if (pHostapdAdapter->device_mode == WLAN_HDD_P2P_GO)
6502 {
6503 if(globalP2PConnectionStatus == P2P_GO_NEG_COMPLETED)
6504 {
6505 globalP2PConnectionStatus = P2P_GO_COMPLETED_STATE;
6506 hddLog(LOGE,"[P2P State] From Go nego completed to "
Jeff Johnson1250df42012-12-10 14:31:52 -08006507 "Non-autonomous Group started");
Madan Mohan Koyyalamudi26bd7142012-10-30 18:14:19 -07006508 }
6509 else if(globalP2PConnectionStatus == P2P_NOT_ACTIVE)
6510 {
6511 globalP2PConnectionStatus = P2P_GO_COMPLETED_STATE;
6512 hddLog(LOGE,"[P2P State] From Inactive to "
Jeff Johnson1250df42012-12-10 14:31:52 -08006513 "Autonomous Group started");
Madan Mohan Koyyalamudi26bd7142012-10-30 18:14:19 -07006514 }
6515 }
6516#endif
6517
Jeff Johnson295189b2012-06-20 16:38:30 -07006518 pHostapdState->bCommit = TRUE;
6519 EXIT();
6520
6521 return 0;
6522}
6523
Jeff Johnson04dd8a82012-06-29 20:41:40 -07006524#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,4,0))
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306525static int wlan_hdd_cfg80211_add_beacon(struct wiphy *wiphy,
6526 struct net_device *dev,
Jeff Johnson295189b2012-06-20 16:38:30 -07006527 struct beacon_parameters *params)
6528{
6529 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +05306530 hdd_context_t *pHddCtx;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05306531 int status;
Jeff Johnson295189b2012-06-20 16:38:30 -07006532
6533 ENTER();
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +05306534
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05306535 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
6536 TRACE_CODE_HDD_CFG80211_ADD_BEACON,
6537 pAdapter->sessionId, params->interval));
Sushant Kaushik8bc7df22014-04-09 17:55:29 +05306538 hddLog(VOS_TRACE_LEVEL_INFO_HIGH, "device mode=%s (%d)",
6539 hdd_device_modetoString(pAdapter->device_mode),
6540 pAdapter->device_mode);
Jeff Johnson295189b2012-06-20 16:38:30 -07006541
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05306542 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
6543 status = wlan_hdd_validate_context(pHddCtx);
6544
6545 if (0 != status)
Jeff Johnson04dd8a82012-06-29 20:41:40 -07006546 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05306547 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
6548 "%s: HDD context is not valid", __func__);
6549 return status;
Jeff Johnson04dd8a82012-06-29 20:41:40 -07006550 }
6551
Agarwal Ashish51325b52014-06-16 16:50:49 +05306552 if (vos_max_concurrent_connections_reached()) {
6553 hddLog(VOS_TRACE_LEVEL_INFO, FL("Reached max concurrent connections"));
6554 return -EINVAL;
6555 }
6556
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306557 if ( (pAdapter->device_mode == WLAN_HDD_SOFTAP)
Jeff Johnson295189b2012-06-20 16:38:30 -07006558 || (pAdapter->device_mode == WLAN_HDD_P2P_GO)
Jeff Johnson295189b2012-06-20 16:38:30 -07006559 )
6560 {
6561 beacon_data_t *old,*new;
6562
6563 old = pAdapter->sessionCtx.ap.beacon;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306564
Jeff Johnson295189b2012-06-20 16:38:30 -07006565 if (old)
c_hpothu6ff1c3c2013-10-01 19:01:57 +05306566 {
6567 hddLog(VOS_TRACE_LEVEL_WARN,
6568 FL("already beacon info added to session(%d)"),
6569 pAdapter->sessionId);
Jeff Johnson295189b2012-06-20 16:38:30 -07006570 return -EALREADY;
c_hpothu6ff1c3c2013-10-01 19:01:57 +05306571 }
Jeff Johnson295189b2012-06-20 16:38:30 -07006572
6573 status = wlan_hdd_cfg80211_alloc_new_beacon(pAdapter,&new,params);
6574
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306575 if(status != VOS_STATUS_SUCCESS)
Jeff Johnson295189b2012-06-20 16:38:30 -07006576 {
6577 hddLog(VOS_TRACE_LEVEL_FATAL,
Arif Hussain6d2a3322013-11-17 19:50:10 -08006578 "%s:Error!!! Allocating the new beacon",__func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07006579 return -EINVAL;
6580 }
6581
6582 pAdapter->sessionCtx.ap.beacon = new;
6583
6584 status = wlan_hdd_cfg80211_start_bss(pAdapter, params);
6585 }
6586
6587 EXIT();
6588 return status;
6589}
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306590
6591static int wlan_hdd_cfg80211_set_beacon(struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -07006592 struct net_device *dev,
6593 struct beacon_parameters *params)
6594{
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306595 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +05306596 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
6597 hdd_context_t *pHddCtx;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05306598 int status;
Jeff Johnson295189b2012-06-20 16:38:30 -07006599
6600 ENTER();
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +05306601 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
6602 TRACE_CODE_HDD_CFG80211_SET_BEACON,
6603 pAdapter->sessionId, pHddStaCtx->conn_info.authType));
6604 hddLog(VOS_TRACE_LEVEL_INFO, "%s: device_mode = %s (%d)",
6605 __func__, hdd_device_modetoString(pAdapter->device_mode),
6606 pAdapter->device_mode);
6607
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05306608 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
6609 status = wlan_hdd_validate_context(pHddCtx);
6610
6611 if (0 != status)
Jeff Johnson04dd8a82012-06-29 20:41:40 -07006612 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05306613 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
6614 "%s: HDD context is not valid", __func__);
6615 return status;
Jeff Johnson04dd8a82012-06-29 20:41:40 -07006616 }
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +05306617
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306618 if ((pAdapter->device_mode == WLAN_HDD_SOFTAP)
Jeff Johnson295189b2012-06-20 16:38:30 -07006619 || (pAdapter->device_mode == WLAN_HDD_P2P_GO)
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306620 )
Jeff Johnson295189b2012-06-20 16:38:30 -07006621 {
6622 beacon_data_t *old,*new;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306623
Jeff Johnson295189b2012-06-20 16:38:30 -07006624 old = pAdapter->sessionCtx.ap.beacon;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306625
Jeff Johnson295189b2012-06-20 16:38:30 -07006626 if (!old)
c_hpothu6ff1c3c2013-10-01 19:01:57 +05306627 {
6628 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
6629 FL("session(%d) old and new heads points to NULL"),
6630 pAdapter->sessionId);
Jeff Johnson295189b2012-06-20 16:38:30 -07006631 return -ENOENT;
c_hpothu6ff1c3c2013-10-01 19:01:57 +05306632 }
Jeff Johnson295189b2012-06-20 16:38:30 -07006633
6634 status = wlan_hdd_cfg80211_alloc_new_beacon(pAdapter,&new,params);
6635
6636 if(status != VOS_STATUS_SUCCESS) {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306637 hddLog(VOS_TRACE_LEVEL_FATAL,
Arif Hussain6d2a3322013-11-17 19:50:10 -08006638 "%s: Error!!! Allocating the new beacon",__func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07006639 return -EINVAL;
6640 }
6641
6642 pAdapter->sessionCtx.ap.beacon = new;
6643
6644 status = wlan_hdd_cfg80211_start_bss(pAdapter, params);
6645 }
6646
6647 EXIT();
6648 return status;
6649}
6650
Jeff Johnson04dd8a82012-06-29 20:41:40 -07006651#endif //(LINUX_VERSION_CODE < KERNEL_VERSION(3,4,0))
6652
6653#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,4,0))
Jeff Johnson295189b2012-06-20 16:38:30 -07006654static int wlan_hdd_cfg80211_del_beacon(struct wiphy *wiphy,
6655 struct net_device *dev)
Jeff Johnson04dd8a82012-06-29 20:41:40 -07006656#else
6657static int wlan_hdd_cfg80211_stop_ap (struct wiphy *wiphy,
6658 struct net_device *dev)
6659#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07006660{
6661 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
Jeff Johnsone7245742012-09-05 17:12:55 -07006662 hdd_context_t *pHddCtx = NULL;
6663 hdd_scaninfo_t *pScanInfo = NULL;
6664 hdd_adapter_t *staAdapter = NULL;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05306665 VOS_STATUS status;
Mahesh A Saptasagar2395ee62014-05-21 19:12:21 +05306666 long ret;
Jeff Johnson295189b2012-06-20 16:38:30 -07006667
6668 ENTER();
6669
6670 if (NULL == pAdapter)
6671 {
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +05306672 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07006673 "%s: HDD adapter context is Null", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07006674 return -ENODEV;
6675 }
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -07006676
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05306677 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
6678 TRACE_CODE_HDD_CFG80211_STOP_AP,
6679 pAdapter->sessionId, pAdapter->device_mode));
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05306680 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
6681 status = wlan_hdd_validate_context(pHddCtx);
6682
6683 if (0 != status)
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -07006684 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05306685 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
6686 "%s: HDD context is not valid", __func__);
6687 return status;
Jeff Johnson4416a782013-03-25 14:17:50 -07006688 }
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -07006689
6690 staAdapter = hdd_get_adapter(pAdapter->pHddCtx, WLAN_HDD_INFRA_STATION);
6691 if (NULL == staAdapter)
6692 {
6693 staAdapter = hdd_get_adapter(pAdapter->pHddCtx, WLAN_HDD_P2P_CLIENT);
6694 if (NULL == staAdapter)
6695 {
Rajesh Chauhan52d885b2013-11-01 10:54:25 -07006696 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO_HIGH,
6697 "%s: HDD adapter context for STA/P2P-CLI is Null",
6698 __func__);
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -07006699 }
6700 }
6701
6702 pScanInfo = &pHddCtx->scan_info;
6703
Sushant Kaushik8bc7df22014-04-09 17:55:29 +05306704 hddLog(VOS_TRACE_LEVEL_INFO, "%s: device_mode = %s (%d)",
6705 __func__, hdd_device_modetoString(pAdapter->device_mode),
6706 pAdapter->device_mode);
Jeff Johnson295189b2012-06-20 16:38:30 -07006707
Mahesh A Saptasagar2395ee62014-05-21 19:12:21 +05306708 ret = wlan_hdd_scan_abort(pAdapter);
6709
Girish Gowli4bf7a632014-06-12 13:42:11 +05306710 if (ret < 0)
Jeff Johnsone7245742012-09-05 17:12:55 -07006711 {
Mahesh A Saptasagar2395ee62014-05-21 19:12:21 +05306712 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
6713 FL("Timeout occurred while waiting for abortscan %ld"), ret);
c_hpothu6ff1c3c2013-10-01 19:01:57 +05306714
Mahesh A Saptasagar2395ee62014-05-21 19:12:21 +05306715 if (pHddCtx->isLogpInProgress)
Jeff Johnsone7245742012-09-05 17:12:55 -07006716 {
Mahesh A Saptasagar2395ee62014-05-21 19:12:21 +05306717 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
6718 "%s: LOGP in Progress. Ignore!!!", __func__);
Yue Ma4f55ef32014-01-23 16:45:33 -08006719
Jeff Johnsone7245742012-09-05 17:12:55 -07006720 VOS_ASSERT(pScanInfo->mScanPending);
Mahesh A Saptasagar2395ee62014-05-21 19:12:21 +05306721 return -EAGAIN;
Jeff Johnsone7245742012-09-05 17:12:55 -07006722 }
Mahesh A Saptasagar2395ee62014-05-21 19:12:21 +05306723 VOS_ASSERT(pScanInfo->mScanPending);
Jeff Johnsone7245742012-09-05 17:12:55 -07006724 }
6725
Rashmi Ramanna1f0948d2014-08-28 15:33:48 +05306726 /* Delete all associated STAs before stopping AP/P2P GO */
6727 hdd_del_all_sta(pAdapter);
Arun Kumar Khandavallia3bd8002014-01-17 16:21:19 +05306728 hdd_hostapd_stop(dev);
6729
Jeff Johnson295189b2012-06-20 16:38:30 -07006730 if ((pAdapter->device_mode == WLAN_HDD_SOFTAP)
Jeff Johnson295189b2012-06-20 16:38:30 -07006731 || (pAdapter->device_mode == WLAN_HDD_P2P_GO)
Jeff Johnson295189b2012-06-20 16:38:30 -07006732 )
6733 {
6734 beacon_data_t *old;
6735
6736 old = pAdapter->sessionCtx.ap.beacon;
6737
6738 if (!old)
c_hpothu6ff1c3c2013-10-01 19:01:57 +05306739 {
6740 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
6741 FL("session(%d) beacon data points to NULL"),
6742 pAdapter->sessionId);
Jeff Johnson295189b2012-06-20 16:38:30 -07006743 return -ENOENT;
c_hpothu6ff1c3c2013-10-01 19:01:57 +05306744 }
Jeff Johnson295189b2012-06-20 16:38:30 -07006745
Jeff Johnson295189b2012-06-20 16:38:30 -07006746 hdd_cleanup_actionframe(pHddCtx, pAdapter);
Jeff Johnson295189b2012-06-20 16:38:30 -07006747
6748 mutex_lock(&pHddCtx->sap_lock);
6749 if(test_bit(SOFTAP_BSS_STARTED, &pAdapter->event_flags))
6750 {
Jeff Johnson4416a782013-03-25 14:17:50 -07006751 if ( VOS_STATUS_SUCCESS == (status = WLANSAP_StopBss(pHddCtx->pvosContext) ) )
Jeff Johnson295189b2012-06-20 16:38:30 -07006752 {
6753 hdd_hostapd_state_t *pHostapdState = WLAN_HDD_GET_HOSTAP_STATE_PTR(pAdapter);
6754
6755 status = vos_wait_single_event(&pHostapdState->vosEvent, 10000);
6756
6757 if (!VOS_IS_STATUS_SUCCESS(status))
6758 {
6759 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Arif Hussain6d2a3322013-11-17 19:50:10 -08006760 ("ERROR: HDD vos wait for single_event failed!!"));
Jeff Johnson295189b2012-06-20 16:38:30 -07006761 VOS_ASSERT(0);
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05306762 }
6763 }
Jeff Johnson295189b2012-06-20 16:38:30 -07006764 clear_bit(SOFTAP_BSS_STARTED, &pAdapter->event_flags);
Agarwal Ashish51325b52014-06-16 16:50:49 +05306765 /* BSS stopped, clear the active sessions for this device mode */
6766 wlan_hdd_decr_active_session(pHddCtx, pAdapter->device_mode);
Jeff Johnson295189b2012-06-20 16:38:30 -07006767 }
6768 mutex_unlock(&pHddCtx->sap_lock);
6769
6770 if(status != VOS_STATUS_SUCCESS)
6771 {
6772 hddLog(VOS_TRACE_LEVEL_FATAL,
Arif Hussain6d2a3322013-11-17 19:50:10 -08006773 "%s:Error!!! Stopping the BSS",__func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07006774 return -EINVAL;
6775 }
6776
Jeff Johnson4416a782013-03-25 14:17:50 -07006777 if (ccmCfgSetInt(pHddCtx->hHal,
Jeff Johnson295189b2012-06-20 16:38:30 -07006778 WNI_CFG_PROBE_RSP_BCN_ADDNIE_FLAG, 0,NULL, eANI_BOOLEAN_FALSE)
6779 ==eHAL_STATUS_FAILURE)
6780 {
6781 hddLog(LOGE,
Arif Hussain6d2a3322013-11-17 19:50:10 -08006782 "Could not pass on WNI_CFG_PROBE_RSP_BCN_ADDNIE_FLAG to CCM");
Jeff Johnson295189b2012-06-20 16:38:30 -07006783 }
6784
Jeff Johnson4416a782013-03-25 14:17:50 -07006785 if ( eHAL_STATUS_FAILURE == ccmCfgSetInt(pHddCtx->hHal,
Jeff Johnson295189b2012-06-20 16:38:30 -07006786 WNI_CFG_ASSOC_RSP_ADDNIE_FLAG, 0, NULL,
6787 eANI_BOOLEAN_FALSE) )
6788 {
6789 hddLog(LOGE,
Arif Hussain6d2a3322013-11-17 19:50:10 -08006790 "Could not pass on WNI_CFG_ASSOC_RSP_ADDNIE_FLAG to CCM");
Jeff Johnson295189b2012-06-20 16:38:30 -07006791 }
6792
6793 // Reset WNI_CFG_PROBE_RSP Flags
6794 wlan_hdd_reset_prob_rspies(pAdapter);
6795
6796 pAdapter->sessionCtx.ap.beacon = NULL;
6797 kfree(old);
Madan Mohan Koyyalamudi26bd7142012-10-30 18:14:19 -07006798#ifdef WLAN_FEATURE_P2P_DEBUG
6799 if((pAdapter->device_mode == WLAN_HDD_P2P_GO) &&
6800 (globalP2PConnectionStatus == P2P_GO_COMPLETED_STATE))
6801 {
6802 hddLog(LOGE,"[P2P State] From GO completed to Inactive state "
6803 "GO got removed");
6804 globalP2PConnectionStatus = P2P_NOT_ACTIVE;
6805 }
6806#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07006807 }
6808 EXIT();
6809 return status;
6810}
Jeff Johnson04dd8a82012-06-29 20:41:40 -07006811
6812#if (LINUX_VERSION_CODE > KERNEL_VERSION(3,3,0))
6813
Pratik Bhalgata0c7f262012-11-22 17:40:24 +05306814static int wlan_hdd_cfg80211_start_ap(struct wiphy *wiphy,
6815 struct net_device *dev,
Jeff Johnson04dd8a82012-06-29 20:41:40 -07006816 struct cfg80211_ap_settings *params)
6817{
Pratik Bhalgata0c7f262012-11-22 17:40:24 +05306818 hdd_adapter_t *pAdapter;
6819 hdd_context_t *pHddCtx;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05306820 int status;
Jeff Johnson04dd8a82012-06-29 20:41:40 -07006821
6822 ENTER();
6823
Pratik Bhalgata0c7f262012-11-22 17:40:24 +05306824 if (NULL == dev)
Madan Mohan Koyyalamudib2c36892012-10-18 20:52:38 -07006825 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05306826 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Pratik Bhalgata0c7f262012-11-22 17:40:24 +05306827 "%s: Device is Null", __func__);
6828 return -ENODEV;
6829 }
6830
6831 pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
6832 if (NULL == pAdapter)
6833 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05306834 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Pratik Bhalgata0c7f262012-11-22 17:40:24 +05306835 "%s: HDD adapter is Null", __func__);
6836 return -ENODEV;
6837 }
6838
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05306839 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
6840 TRACE_CODE_HDD_CFG80211_START_AP, pAdapter->sessionId,
6841 params-> beacon_interval));
Pratik Bhalgata0c7f262012-11-22 17:40:24 +05306842 if (WLAN_HDD_ADAPTER_MAGIC != pAdapter->magic)
6843 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05306844 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Pratik Bhalgata0c7f262012-11-22 17:40:24 +05306845 "%s: HDD adapter magic is invalid", __func__);
6846 return -ENODEV;
6847 }
6848
6849 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05306850 status = wlan_hdd_validate_context(pHddCtx);
Pratik Bhalgata0c7f262012-11-22 17:40:24 +05306851
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05306852 if (0 != status)
Pratik Bhalgata0c7f262012-11-22 17:40:24 +05306853 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05306854 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
6855 "%s: HDD context is not valid", __func__);
6856 return status;
Pratik Bhalgata0c7f262012-11-22 17:40:24 +05306857 }
6858
Sushant Kaushik8bc7df22014-04-09 17:55:29 +05306859 hddLog(VOS_TRACE_LEVEL_INFO_HIGH, "%s: device mode = %s (%d)",
6860 __func__, hdd_device_modetoString(pAdapter->device_mode),
6861 pAdapter->device_mode);
Pratik Bhalgata0c7f262012-11-22 17:40:24 +05306862
6863 if ((pAdapter->device_mode == WLAN_HDD_SOFTAP)
Jeff Johnson04dd8a82012-06-29 20:41:40 -07006864 || (pAdapter->device_mode == WLAN_HDD_P2P_GO)
Jeff Johnson04dd8a82012-06-29 20:41:40 -07006865 )
6866 {
Pratik Bhalgata0c7f262012-11-22 17:40:24 +05306867 beacon_data_t *old, *new;
Jeff Johnson04dd8a82012-06-29 20:41:40 -07006868
6869 old = pAdapter->sessionCtx.ap.beacon;
Pratik Bhalgata0c7f262012-11-22 17:40:24 +05306870
Jeff Johnson04dd8a82012-06-29 20:41:40 -07006871 if (old)
c_hpothu6ff1c3c2013-10-01 19:01:57 +05306872 {
6873 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_WARN,
6874 FL("already beacon info added to session(%d)"),
6875 pAdapter->sessionId);
Jeff Johnson04dd8a82012-06-29 20:41:40 -07006876 return -EALREADY;
c_hpothu6ff1c3c2013-10-01 19:01:57 +05306877 }
Jeff Johnson04dd8a82012-06-29 20:41:40 -07006878
6879 status = wlan_hdd_cfg80211_alloc_new_beacon(pAdapter, &new, &params->beacon, params->dtim_period);
6880
Pratik Bhalgata0c7f262012-11-22 17:40:24 +05306881 if (status != 0)
Jeff Johnson04dd8a82012-06-29 20:41:40 -07006882 {
6883 hddLog(VOS_TRACE_LEVEL_FATAL,
Pratik Bhalgata0c7f262012-11-22 17:40:24 +05306884 "%s:Error!!! Allocating the new beacon", __func__);
Jeff Johnson04dd8a82012-06-29 20:41:40 -07006885 return -EINVAL;
6886 }
6887 pAdapter->sessionCtx.ap.beacon = new;
Viral Modi3a32cc52013-02-08 11:14:52 -08006888#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,6,0))
Yue Maf49ba872013-08-19 12:04:25 -07006889 wlan_hdd_cfg80211_set_channel(wiphy, dev,
6890#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,8,0))
6891 params->channel, params->channel_type);
6892#else
6893 params->chandef.chan, cfg80211_get_chandef_type(&(params->chandef)));
6894#endif
Viral Modi3a32cc52013-02-08 11:14:52 -08006895#endif
Jeff Johnson04dd8a82012-06-29 20:41:40 -07006896 status = wlan_hdd_cfg80211_start_bss(pAdapter, &params->beacon, params->ssid,
6897 params->ssid_len, params->hidden_ssid);
6898 }
6899
6900 EXIT();
6901 return status;
6902}
6903
6904
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306905static int wlan_hdd_cfg80211_change_beacon(struct wiphy *wiphy,
Jeff Johnson04dd8a82012-06-29 20:41:40 -07006906 struct net_device *dev,
6907 struct cfg80211_beacon_data *params)
6908{
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306909 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +05306910 hdd_context_t *pHddCtx;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05306911 int status;
Jeff Johnson04dd8a82012-06-29 20:41:40 -07006912
6913 ENTER();
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +05306914
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05306915 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
6916 TRACE_CODE_HDD_CFG80211_CHANGE_BEACON,
6917 pAdapter->sessionId, pAdapter->device_mode));
Arif Hussain6d2a3322013-11-17 19:50:10 -08006918 hddLog(VOS_TRACE_LEVEL_INFO, "%s: device_mode = %d",
Jeff Johnson04dd8a82012-06-29 20:41:40 -07006919 __func__, pAdapter->device_mode);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05306920
6921 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
6922 status = wlan_hdd_validate_context(pHddCtx);
6923
6924 if (0 != status)
Madan Mohan Koyyalamudib2c36892012-10-18 20:52:38 -07006925 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05306926 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
6927 "%s: HDD context is not valid", __func__);
6928 return status;
Madan Mohan Koyyalamudib2c36892012-10-18 20:52:38 -07006929 }
Jeff Johnson04dd8a82012-06-29 20:41:40 -07006930
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306931 if ((pAdapter->device_mode == WLAN_HDD_SOFTAP)
Jeff Johnson04dd8a82012-06-29 20:41:40 -07006932 || (pAdapter->device_mode == WLAN_HDD_P2P_GO)
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306933 )
Jeff Johnson04dd8a82012-06-29 20:41:40 -07006934 {
6935 beacon_data_t *old,*new;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306936
Jeff Johnson04dd8a82012-06-29 20:41:40 -07006937 old = pAdapter->sessionCtx.ap.beacon;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306938
Jeff Johnson04dd8a82012-06-29 20:41:40 -07006939 if (!old)
c_hpothu6ff1c3c2013-10-01 19:01:57 +05306940 {
6941 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
6942 FL("session(%d) beacon data points to NULL"),
6943 pAdapter->sessionId);
Jeff Johnson04dd8a82012-06-29 20:41:40 -07006944 return -ENOENT;
c_hpothu6ff1c3c2013-10-01 19:01:57 +05306945 }
Jeff Johnson04dd8a82012-06-29 20:41:40 -07006946
6947 status = wlan_hdd_cfg80211_alloc_new_beacon(pAdapter, &new, params, 0);
6948
6949 if(status != VOS_STATUS_SUCCESS) {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306950 hddLog(VOS_TRACE_LEVEL_FATAL,
Arif Hussain6d2a3322013-11-17 19:50:10 -08006951 "%s: Error!!! Allocating the new beacon",__func__);
Jeff Johnson04dd8a82012-06-29 20:41:40 -07006952 return -EINVAL;
6953 }
6954
6955 pAdapter->sessionCtx.ap.beacon = new;
6956
6957 status = wlan_hdd_cfg80211_start_bss(pAdapter, params, NULL, 0, 0);
6958 }
6959
6960 EXIT();
6961 return status;
6962}
6963
6964#endif //(LINUX_VERSION_CODE > KERNEL_VERSION(3,3,0))
6965
Jeff Johnson295189b2012-06-20 16:38:30 -07006966
Mahesh A Saptasagar179d2252014-06-02 21:32:21 +05306967static int __wlan_hdd_cfg80211_change_bss (struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -07006968 struct net_device *dev,
6969 struct bss_parameters *params)
6970{
6971 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
6972
6973 ENTER();
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +05306974
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05306975 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
6976 TRACE_CODE_HDD_CFG80211_CHANGE_BSS,
6977 pAdapter->sessionId, params->ap_isolate));
Sushant Kaushik8bc7df22014-04-09 17:55:29 +05306978 hddLog(VOS_TRACE_LEVEL_INFO, "%s: device_mode = %s (%d)",
6979 __func__, hdd_device_modetoString(pAdapter->device_mode),
6980 pAdapter->device_mode);
Jeff Johnson295189b2012-06-20 16:38:30 -07006981
6982 if((pAdapter->device_mode == WLAN_HDD_SOFTAP)
Jeff Johnson295189b2012-06-20 16:38:30 -07006983 || (pAdapter->device_mode == WLAN_HDD_P2P_GO)
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306984 )
Jeff Johnson295189b2012-06-20 16:38:30 -07006985 {
6986 /* ap_isolate == -1 means that in change bss, upper layer doesn't
6987 * want to update this parameter */
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306988 if (-1 != params->ap_isolate)
Jeff Johnson295189b2012-06-20 16:38:30 -07006989 {
6990 pAdapter->sessionCtx.ap.apDisableIntraBssFwd = !!params->ap_isolate;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306991 }
Jeff Johnson295189b2012-06-20 16:38:30 -07006992 }
6993
6994 EXIT();
6995 return 0;
6996}
6997
Mahesh A Saptasagar179d2252014-06-02 21:32:21 +05306998static int wlan_hdd_cfg80211_change_bss (struct wiphy *wiphy,
6999 struct net_device *dev,
7000 struct bss_parameters *params)
7001{
7002 int ret;
7003
7004 vos_ssr_protect(__func__);
7005 ret = __wlan_hdd_cfg80211_change_bss(wiphy, dev, params);
7006 vos_ssr_unprotect(__func__);
7007
7008 return ret;
7009}
Kiet Lam10841362013-11-01 11:36:50 +05307010/* FUNCTION: wlan_hdd_change_country_code_cd
7011* to wait for contry code completion
7012*/
7013void* wlan_hdd_change_country_code_cb(void *pAdapter)
7014{
7015 hdd_adapter_t *call_back_pAdapter = pAdapter;
7016 complete(&call_back_pAdapter->change_country_code);
7017 return NULL;
7018}
7019
Jeff Johnson295189b2012-06-20 16:38:30 -07007020/*
Mahesh A Saptasagar0e59c472014-04-14 19:17:41 +05307021 * FUNCTION: __wlan_hdd_cfg80211_change_iface
Jeff Johnson295189b2012-06-20 16:38:30 -07007022 * This function is used to set the interface type (INFRASTRUCTURE/ADHOC)
7023 */
Mahesh A Saptasagar0e59c472014-04-14 19:17:41 +05307024int __wlan_hdd_cfg80211_change_iface( struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -07007025 struct net_device *ndev,
7026 enum nl80211_iftype type,
7027 u32 *flags,
7028 struct vif_params *params
7029 )
7030{
7031 struct wireless_dev *wdev;
7032 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( ndev );
Rajesh Chauhana0516c62014-01-30 16:11:18 -08007033 hdd_context_t *pHddCtx;
Mohit Khanna0f232092012-09-11 14:46:08 -07007034 hdd_adapter_t *pP2pAdapter = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -07007035 tCsrRoamProfile *pRoamProfile = NULL;
7036 eCsrRoamBssType LastBSSType;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05307037 hdd_config_t *pConfig = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -07007038 eMib_dot11DesiredBssType connectedBssType;
7039 VOS_STATUS status;
c_hpothu6ff1c3c2013-10-01 19:01:57 +05307040 long ret;
Jeff Johnson295189b2012-06-20 16:38:30 -07007041
7042 ENTER();
7043
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05307044 if (!pAdapter)
Rajesh Chauhana0516c62014-01-30 16:11:18 -08007045 {
7046 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
7047 "%s: Adapter context is null", __func__);
7048 return VOS_STATUS_E_FAILURE;
7049 }
7050
7051 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
7052 if (!pHddCtx)
7053 {
7054 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
7055 "%s: HDD context is null", __func__);
7056 return VOS_STATUS_E_FAILURE;
7057 }
7058
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05307059 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
7060 TRACE_CODE_HDD_CFG80211_CHANGE_IFACE,
7061 pAdapter->sessionId, type));
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05307062 status = wlan_hdd_validate_context(pHddCtx);
7063
7064 if (0 != status)
Jeff Johnson295189b2012-06-20 16:38:30 -07007065 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05307066 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
7067 "%s: HDD context is not valid", __func__);
7068 return status;
Jeff Johnson295189b2012-06-20 16:38:30 -07007069 }
7070
Sushant Kaushik8bc7df22014-04-09 17:55:29 +05307071 hddLog(VOS_TRACE_LEVEL_INFO, "%s: device_mode = %s (%d)",
7072 __func__, hdd_device_modetoString(pAdapter->device_mode),
7073 pAdapter->device_mode);
Jeff Johnson295189b2012-06-20 16:38:30 -07007074
Agarwal Ashish51325b52014-06-16 16:50:49 +05307075 if (vos_max_concurrent_connections_reached()) {
7076 hddLog(VOS_TRACE_LEVEL_INFO, FL("Reached max concurrent connections"));
7077 return -EINVAL;
7078 }
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05307079 pConfig = pHddCtx->cfg_ini;
Jeff Johnson295189b2012-06-20 16:38:30 -07007080 wdev = ndev->ieee80211_ptr;
7081
7082#ifdef WLAN_BTAMP_FEATURE
7083 if((NL80211_IFTYPE_P2P_CLIENT == type)||
7084 (NL80211_IFTYPE_ADHOC == type)||
7085 (NL80211_IFTYPE_AP == type)||
7086 (NL80211_IFTYPE_P2P_GO == type))
7087 {
7088 pHddCtx->isAmpAllowed = VOS_FALSE;
7089 // stop AMP traffic
7090 status = WLANBAP_StopAmp();
7091 if(VOS_STATUS_SUCCESS != status )
7092 {
7093 pHddCtx->isAmpAllowed = VOS_TRUE;
7094 hddLog(VOS_TRACE_LEVEL_FATAL,
7095 "%s: Failed to stop AMP", __func__);
7096 return -EINVAL;
7097 }
7098 }
7099#endif //WLAN_BTAMP_FEATURE
7100 /* Reset the current device mode bit mask*/
7101 wlan_hdd_clear_concurrency_mode(pHddCtx, pAdapter->device_mode);
7102
7103 if( (pAdapter->device_mode == WLAN_HDD_INFRA_STATION)
Jeff Johnson295189b2012-06-20 16:38:30 -07007104 || (pAdapter->device_mode == WLAN_HDD_P2P_CLIENT)
Jeff Johnsone7245742012-09-05 17:12:55 -07007105 || (pAdapter->device_mode == WLAN_HDD_P2P_DEVICE)
Jeff Johnson295189b2012-06-20 16:38:30 -07007106 )
7107 {
7108 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
Rajesh Chauhana0516c62014-01-30 16:11:18 -08007109 if (!pWextState)
7110 {
7111 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
7112 "%s: pWextState is null", __func__);
7113 return VOS_STATUS_E_FAILURE;
7114 }
Jeff Johnson295189b2012-06-20 16:38:30 -07007115 pRoamProfile = &pWextState->roamProfile;
7116 LastBSSType = pRoamProfile->BSSType;
7117
7118 switch (type)
7119 {
7120 case NL80211_IFTYPE_STATION:
Jeff Johnson295189b2012-06-20 16:38:30 -07007121 case NL80211_IFTYPE_P2P_CLIENT:
Jeff Johnson295189b2012-06-20 16:38:30 -07007122 hddLog(VOS_TRACE_LEVEL_INFO,
7123 "%s: setting interface Type to INFRASTRUCTURE", __func__);
7124 pRoamProfile->BSSType = eCSR_BSS_TYPE_INFRASTRUCTURE;
Jeff Johnsone7245742012-09-05 17:12:55 -07007125#ifdef WLAN_FEATURE_11AC
7126 if(pConfig->dot11Mode == eHDD_DOT11_MODE_AUTO)
7127 {
7128 pConfig->dot11Mode = eHDD_DOT11_MODE_11ac;
7129 }
7130#endif
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307131 pRoamProfile->phyMode =
Jeff Johnsone7245742012-09-05 17:12:55 -07007132 hdd_cfg_xlate_to_csr_phy_mode(pConfig->dot11Mode);
Jeff Johnson295189b2012-06-20 16:38:30 -07007133 wdev->iftype = type;
Gopichand Nakkalaf527dc62012-12-31 16:35:10 -08007134 //Check for sub-string p2p to confirm its a p2p interface
7135 if (NULL != strstr(ndev->name,"p2p"))
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307136 {
Gopichand Nakkala864d3552012-12-31 16:08:51 -08007137 pAdapter->device_mode = (type == NL80211_IFTYPE_STATION) ?
7138 WLAN_HDD_P2P_DEVICE : WLAN_HDD_P2P_CLIENT;
7139 }
7140 else
7141 {
7142 pAdapter->device_mode = (type == NL80211_IFTYPE_STATION) ?
Jeff Johnson295189b2012-06-20 16:38:30 -07007143 WLAN_HDD_INFRA_STATION: WLAN_HDD_P2P_CLIENT;
Gopichand Nakkala864d3552012-12-31 16:08:51 -08007144 }
Madan Mohan Koyyalamudi81746922013-07-17 14:38:51 +05307145#ifdef FEATURE_WLAN_TDLS
7146 /* The open adapter for the p2p shall skip initializations in
7147 * tdls_init if the device mode is WLAN_HDD_P2P_DEVICE, for
7148 * TDLS is supported only on WLAN_HDD_P2P_CLIENT. Hence invoke
7149 * tdls_init when the change_iface sets the device mode to
7150 * WLAN_HDD_P2P_CLIENT.
7151 */
7152
7153 if ( pAdapter->device_mode == WLAN_HDD_P2P_CLIENT)
7154 {
Agarwal Ashish4b87f922014-06-18 03:03:21 +05307155 if (0 != wlan_hdd_sta_tdls_init (pAdapter))
Madan Mohan Koyyalamudi81746922013-07-17 14:38:51 +05307156 {
c_hpothu6ff1c3c2013-10-01 19:01:57 +05307157 hddLog(VOS_TRACE_LEVEL_ERROR,
7158 "%s: tdls initialization failed", __func__);
Madan Mohan Koyyalamudi81746922013-07-17 14:38:51 +05307159 return -EINVAL;
7160 }
7161 }
7162#endif
7163
Jeff Johnson295189b2012-06-20 16:38:30 -07007164 break;
7165 case NL80211_IFTYPE_ADHOC:
7166 hddLog(VOS_TRACE_LEVEL_INFO,
7167 "%s: setting interface Type to ADHOC", __func__);
7168 pRoamProfile->BSSType = eCSR_BSS_TYPE_START_IBSS;
7169 pRoamProfile->phyMode =
7170 hdd_cfg_xlate_to_csr_phy_mode(pConfig->dot11Mode);
Shailender Karmuchia734f332013-04-19 14:02:48 -07007171 pAdapter->device_mode = WLAN_HDD_IBSS;
Jeff Johnson295189b2012-06-20 16:38:30 -07007172 wdev->iftype = type;
7173 break;
7174
7175 case NL80211_IFTYPE_AP:
Jeff Johnson295189b2012-06-20 16:38:30 -07007176 case NL80211_IFTYPE_P2P_GO:
Jeff Johnson295189b2012-06-20 16:38:30 -07007177 {
7178 hddLog(VOS_TRACE_LEVEL_INFO_HIGH,
7179 "%s: setting interface Type to %s", __func__,
7180 (type == NL80211_IFTYPE_AP) ? "SoftAP" : "P2pGo");
7181
Gopichand Nakkalaf527dc62012-12-31 16:35:10 -08007182 //Cancel any remain on channel for GO mode
7183 if (NL80211_IFTYPE_P2P_GO == type)
7184 {
7185 wlan_hdd_cancel_existing_remain_on_channel(pAdapter);
7186 }
Mohit Khanna0f232092012-09-11 14:46:08 -07007187 if (NL80211_IFTYPE_AP == type)
7188 {
7189 /* As Loading WLAN Driver one interface being created for p2p device
7190 * address. This will take one HW STA and the max number of clients
7191 * that can connect to softAP will be reduced by one. so while changing
7192 * the interface type to NL80211_IFTYPE_AP (SoftAP) remove p2p0
7193 * interface as it is not required in SoftAP mode.
7194 */
7195
7196 // Get P2P Adapter
7197 pP2pAdapter = hdd_get_adapter(pHddCtx, WLAN_HDD_P2P_DEVICE);
7198
7199 if (pP2pAdapter)
7200 {
Agarwal Ashish3a38bd12014-06-12 15:16:52 +05307201 hdd_stop_adapter(pHddCtx, pP2pAdapter, VOS_TRUE);
Mohit Khanna0f232092012-09-11 14:46:08 -07007202 hdd_deinit_adapter(pHddCtx, pP2pAdapter);
7203 hdd_close_adapter(pHddCtx, pP2pAdapter, VOS_TRUE);
7204 }
7205 }
Swaroop Goltia2e32212014-04-09 23:37:33 +05307206 //Disable IMPS & BMPS for SAP/GO
7207 if(VOS_STATUS_E_FAILURE ==
7208 hdd_disable_bmps_imps(pHddCtx, WLAN_HDD_P2P_GO))
7209 {
7210 //Fail to Exit BMPS
7211 VOS_ASSERT(0);
7212 }
Deepthi Gowri500fc472014-08-11 19:53:10 +05307213
7214 hdd_stop_adapter( pHddCtx, pAdapter, VOS_TRUE );
7215
Madan Mohan Koyyalamudi96797442013-10-08 16:04:42 +05307216#ifdef FEATURE_WLAN_TDLS
Mohit Khanna0f232092012-09-11 14:46:08 -07007217
Madan Mohan Koyyalamudi96797442013-10-08 16:04:42 +05307218 /* A Mutex Lock is introduced while changing the mode to
7219 * protect the concurrent access for the Adapters by TDLS
7220 * module.
7221 */
Rajesh Chauhana34c6e62014-03-25 16:37:58 +05307222 mutex_lock(&pHddCtx->tdls_lock);
Madan Mohan Koyyalamudi96797442013-10-08 16:04:42 +05307223#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07007224 //De-init the adapter.
Jeff Johnson295189b2012-06-20 16:38:30 -07007225 hdd_deinit_adapter( pHddCtx, pAdapter );
7226 memset(&pAdapter->sessionCtx, 0, sizeof(pAdapter->sessionCtx));
Jeff Johnson295189b2012-06-20 16:38:30 -07007227 pAdapter->device_mode = (type == NL80211_IFTYPE_AP) ?
7228 WLAN_HDD_SOFTAP : WLAN_HDD_P2P_GO;
Madan Mohan Koyyalamudi96797442013-10-08 16:04:42 +05307229#ifdef FEATURE_WLAN_TDLS
7230 mutex_unlock(&pHddCtx->tdls_lock);
7231#endif
Madan Mohan Koyyalamudi3ff2a0b2012-10-15 14:33:46 -07007232 if ((WLAN_HDD_SOFTAP == pAdapter->device_mode) &&
7233 (pConfig->apRandomBssidEnabled))
7234 {
7235 /* To meet Android requirements create a randomized
7236 MAC address of the form 02:1A:11:Fx:xx:xx */
7237 get_random_bytes(&ndev->dev_addr[3], 3);
7238 ndev->dev_addr[0] = 0x02;
7239 ndev->dev_addr[1] = 0x1A;
7240 ndev->dev_addr[2] = 0x11;
7241 ndev->dev_addr[3] |= 0xF0;
7242 memcpy(pAdapter->macAddressCurrent.bytes, ndev->dev_addr,
7243 VOS_MAC_ADDR_SIZE);
Arif Hussain24bafea2013-11-15 15:10:03 -08007244 pr_info("wlan: Generated HotSpot BSSID " MAC_ADDRESS_STR"\n",
7245 MAC_ADDR_ARRAY(ndev->dev_addr));
Madan Mohan Koyyalamudi3ff2a0b2012-10-15 14:33:46 -07007246 }
7247
Jeff Johnson295189b2012-06-20 16:38:30 -07007248 hdd_set_ap_ops( pAdapter->dev );
7249
Kiet Lam10841362013-11-01 11:36:50 +05307250 /* This is for only SAP mode where users can
7251 * control country through ini.
7252 * P2P GO follows station country code
7253 * acquired during the STA scanning. */
7254 if((NL80211_IFTYPE_AP == type) &&
7255 (memcmp(pConfig->apCntryCode, CFG_AP_COUNTRY_CODE_DEFAULT, 3) != 0))
7256 {
7257 int status = 0;
7258 VOS_TRACE(VOS_MODULE_ID_HDD,VOS_TRACE_LEVEL_INFO,
7259 "%s: setting country code from INI ", __func__);
7260 init_completion(&pAdapter->change_country_code);
7261 status = (int)sme_ChangeCountryCode(pHddCtx->hHal,
7262 (void *)(tSmeChangeCountryCallback)
7263 wlan_hdd_change_country_code_cb,
7264 pConfig->apCntryCode, pAdapter,
7265 pHddCtx->pvosContext,
Abhishek Singha306a442013-11-07 18:39:01 +05307266 eSIR_FALSE,
7267 eSIR_TRUE);
Kiet Lam10841362013-11-01 11:36:50 +05307268 if (eHAL_STATUS_SUCCESS == status)
7269 {
7270 /* Wait for completion */
c_hpothu6ff1c3c2013-10-01 19:01:57 +05307271 ret = wait_for_completion_interruptible_timeout(
Kiet Lam10841362013-11-01 11:36:50 +05307272 &pAdapter->change_country_code,
7273 msecs_to_jiffies(WLAN_WAIT_TIME_COUNTRY));
c_hpothu6ff1c3c2013-10-01 19:01:57 +05307274 if (ret <= 0)
Kiet Lam10841362013-11-01 11:36:50 +05307275 {
7276 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
c_hpothu6ff1c3c2013-10-01 19:01:57 +05307277 FL("SME Timed out while setting country code %ld"),
7278 ret);
Yue Ma4f55ef32014-01-23 16:45:33 -08007279
7280 if (pHddCtx->isLogpInProgress)
7281 {
7282 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
7283 "%s: LOGP in Progress. Ignore!!!", __func__);
7284 return -EAGAIN;
7285 }
Kiet Lam10841362013-11-01 11:36:50 +05307286 }
7287 }
7288 else
7289 {
7290 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Arif Hussain6d2a3322013-11-17 19:50:10 -08007291 "%s: SME Change Country code failed",__func__);
Kiet Lam10841362013-11-01 11:36:50 +05307292 return -EINVAL;
7293 }
7294 }
Jeff Johnson295189b2012-06-20 16:38:30 -07007295 status = hdd_init_ap_mode(pAdapter);
7296 if(status != VOS_STATUS_SUCCESS)
7297 {
7298 hddLog(VOS_TRACE_LEVEL_FATAL,
7299 "%s: Error initializing the ap mode", __func__);
7300 return -EINVAL;
7301 }
7302 hdd_set_conparam(1);
7303
Jeff Johnson295189b2012-06-20 16:38:30 -07007304 /*interface type changed update in wiphy structure*/
7305 if(wdev)
7306 {
7307 wdev->iftype = type;
7308 pHddCtx->change_iface = type;
7309 }
7310 else
7311 {
7312 hddLog(VOS_TRACE_LEVEL_ERROR,
7313 "%s: ERROR !!!! Wireless dev is NULL", __func__);
7314 return -EINVAL;
7315 }
7316 goto done;
7317 }
7318
7319 default:
7320 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Unsupported interface Type",
7321 __func__);
7322 return -EOPNOTSUPP;
7323 }
7324 }
7325 else if ( (pAdapter->device_mode == WLAN_HDD_SOFTAP)
Jeff Johnson295189b2012-06-20 16:38:30 -07007326 || (pAdapter->device_mode == WLAN_HDD_P2P_GO)
Jeff Johnson295189b2012-06-20 16:38:30 -07007327 )
7328 {
7329 switch(type)
7330 {
7331 case NL80211_IFTYPE_STATION:
Jeff Johnson295189b2012-06-20 16:38:30 -07007332 case NL80211_IFTYPE_P2P_CLIENT:
Jeff Johnson295189b2012-06-20 16:38:30 -07007333 case NL80211_IFTYPE_ADHOC:
Deepthi Gowri500fc472014-08-11 19:53:10 +05307334
7335 hdd_stop_adapter( pHddCtx, pAdapter, VOS_TRUE );
Madan Mohan Koyyalamudi96797442013-10-08 16:04:42 +05307336#ifdef FEATURE_WLAN_TDLS
7337
7338 /* A Mutex Lock is introduced while changing the mode to
7339 * protect the concurrent access for the Adapters by TDLS
7340 * module.
7341 */
Rajesh Chauhana34c6e62014-03-25 16:37:58 +05307342 mutex_lock(&pHddCtx->tdls_lock);
Madan Mohan Koyyalamudi96797442013-10-08 16:04:42 +05307343#endif
Jeff Johnson32d95a32012-09-10 13:15:23 -07007344 hdd_deinit_adapter( pHddCtx, pAdapter );
Jeff Johnson295189b2012-06-20 16:38:30 -07007345 wdev->iftype = type;
Gopichand Nakkalaf527dc62012-12-31 16:35:10 -08007346 //Check for sub-string p2p to confirm its a p2p interface
7347 if (NULL != strstr(ndev->name,"p2p"))
Gopichand Nakkala864d3552012-12-31 16:08:51 -08007348 {
7349 pAdapter->device_mode = (type == NL80211_IFTYPE_STATION) ?
7350 WLAN_HDD_P2P_DEVICE : WLAN_HDD_P2P_CLIENT;
7351 }
7352 else
7353 {
7354 pAdapter->device_mode = (type == NL80211_IFTYPE_STATION) ?
Jeff Johnson295189b2012-06-20 16:38:30 -07007355 WLAN_HDD_INFRA_STATION: WLAN_HDD_P2P_CLIENT;
Gopichand Nakkala864d3552012-12-31 16:08:51 -08007356 }
Jeff Johnson295189b2012-06-20 16:38:30 -07007357 hdd_set_conparam(0);
7358 pHddCtx->change_iface = type;
Jeff Johnson295189b2012-06-20 16:38:30 -07007359 memset(&pAdapter->sessionCtx, 0, sizeof(pAdapter->sessionCtx));
7360 hdd_set_station_ops( pAdapter->dev );
Madan Mohan Koyyalamudi96797442013-10-08 16:04:42 +05307361#ifdef FEATURE_WLAN_TDLS
7362 mutex_unlock(&pHddCtx->tdls_lock);
7363#endif
Sunil Dutt66485cb2013-12-19 19:05:03 +05307364 status = hdd_init_station_mode( pAdapter );
Jeff Johnson295189b2012-06-20 16:38:30 -07007365 if( VOS_STATUS_SUCCESS != status )
7366 return -EOPNOTSUPP;
Jeff Johnsone7245742012-09-05 17:12:55 -07007367 /* In case of JB, for P2P-GO, only change interface will be called,
7368 * This is the right place to enable back bmps_imps()
7369 */
Gopichand Nakkalaa2fe5b02013-06-06 16:32:28 +05307370 if (pHddCtx->hdd_wlan_suspended)
7371 {
7372 hdd_set_pwrparams(pHddCtx);
7373 }
Jeff Johnsone7245742012-09-05 17:12:55 -07007374 hdd_enable_bmps_imps(pHddCtx);
Jeff Johnson295189b2012-06-20 16:38:30 -07007375 goto done;
7376 case NL80211_IFTYPE_AP:
Jeff Johnson295189b2012-06-20 16:38:30 -07007377 case NL80211_IFTYPE_P2P_GO:
Jeff Johnson295189b2012-06-20 16:38:30 -07007378 wdev->iftype = type;
Jeff Johnson295189b2012-06-20 16:38:30 -07007379 pAdapter->device_mode = (type == NL80211_IFTYPE_AP) ?
7380 WLAN_HDD_SOFTAP : WLAN_HDD_P2P_GO;
Jeff Johnson295189b2012-06-20 16:38:30 -07007381 goto done;
7382 default:
7383 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Unsupported interface Type",
7384 __func__);
7385 return -EOPNOTSUPP;
7386
7387 }
7388
7389 }
7390 else
7391 {
Sushant Kaushik8bc7df22014-04-09 17:55:29 +05307392 hddLog(VOS_TRACE_LEVEL_ERROR,"%s: unsupported device mode(%s (%d))",
7393 __func__, hdd_device_modetoString(pAdapter->device_mode),
7394 pAdapter->device_mode);
Jeff Johnson295189b2012-06-20 16:38:30 -07007395 return -EOPNOTSUPP;
7396 }
7397
7398
7399 if(pRoamProfile)
7400 {
7401 if ( LastBSSType != pRoamProfile->BSSType )
7402 {
7403 /*interface type changed update in wiphy structure*/
7404 wdev->iftype = type;
7405
7406 /*the BSS mode changed, We need to issue disconnect
7407 if connected or in IBSS disconnect state*/
7408 if ( hdd_connGetConnectedBssType(
7409 WLAN_HDD_GET_STATION_CTX_PTR(pAdapter), &connectedBssType ) ||
7410 ( eCSR_BSS_TYPE_START_IBSS == LastBSSType ) )
7411 {
7412 /*need to issue a disconnect to CSR.*/
7413 INIT_COMPLETION(pAdapter->disconnect_comp_var);
7414 if( eHAL_STATUS_SUCCESS ==
7415 sme_RoamDisconnect( WLAN_HDD_GET_HAL_CTX(pAdapter),
7416 pAdapter->sessionId,
7417 eCSR_DISCONNECT_REASON_UNSPECIFIED ) )
7418 {
c_hpothu6ff1c3c2013-10-01 19:01:57 +05307419 ret = wait_for_completion_interruptible_timeout(
7420 &pAdapter->disconnect_comp_var,
7421 msecs_to_jiffies(WLAN_WAIT_TIME_DISCONNECT));
7422 if (ret <= 0)
7423 {
7424 hddLog(VOS_TRACE_LEVEL_ERROR,
7425 FL("wait on disconnect_comp_var failed %ld"), ret);
7426 }
Jeff Johnson295189b2012-06-20 16:38:30 -07007427 }
7428 }
7429 }
7430 }
7431
7432done:
7433 /*set bitmask based on updated value*/
7434 wlan_hdd_set_concurrency_mode(pHddCtx, pAdapter->device_mode);
Leo Chang6fe1f922013-06-07 19:21:24 -07007435
7436 /* Only STA mode support TM now
7437 * all other mode, TM feature should be disabled */
7438 if ( (pHddCtx->cfg_ini->thermalMitigationEnable) &&
7439 (~VOS_STA & pHddCtx->concurrency_mode) )
7440 {
7441 hddDevTmLevelChangedHandler(pHddCtx->parent_dev, 0);
7442 }
7443
Jeff Johnson295189b2012-06-20 16:38:30 -07007444#ifdef WLAN_BTAMP_FEATURE
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307445 if((NL80211_IFTYPE_STATION == type) && (pHddCtx->concurrency_mode <= 1) &&
Agarwal Ashish51325b52014-06-16 16:50:49 +05307446 (pHddCtx->no_of_open_sessions[WLAN_HDD_INFRA_STATION] <=1))
Jeff Johnson295189b2012-06-20 16:38:30 -07007447 {
7448 //we are ok to do AMP
7449 pHddCtx->isAmpAllowed = VOS_TRUE;
7450 }
7451#endif //WLAN_BTAMP_FEATURE
7452 EXIT();
7453 return 0;
7454}
7455
Mahesh A Saptasagar0e59c472014-04-14 19:17:41 +05307456/*
7457 * FUNCTION: wlan_hdd_cfg80211_change_iface
7458 * wrapper function to protect the actual implementation from SSR.
7459 */
7460int wlan_hdd_cfg80211_change_iface( struct wiphy *wiphy,
7461 struct net_device *ndev,
7462 enum nl80211_iftype type,
7463 u32 *flags,
7464 struct vif_params *params
7465 )
7466{
7467 int ret;
7468
7469 vos_ssr_protect(__func__);
7470 ret = __wlan_hdd_cfg80211_change_iface(wiphy, ndev, type, flags, params);
7471 vos_ssr_unprotect(__func__);
7472
7473 return ret;
7474}
7475
Gopichand Nakkala681989c2013-03-06 22:27:48 -08007476#ifdef FEATURE_WLAN_TDLS
7477static int wlan_hdd_tdls_add_station(struct wiphy *wiphy,
7478 struct net_device *dev, u8 *mac, bool update, tCsrStaParams *StaParams)
7479{
7480 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
7481 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
7482 VOS_STATUS status;
Hoonki Lee5305c3a2013-04-29 23:28:59 -07007483 hddTdlsPeer_t *pTdlsPeer;
c_hpothu6ff1c3c2013-10-01 19:01:57 +05307484 long ret;
Rajesh Chauhana34c6e62014-03-25 16:37:58 +05307485 tANI_U16 numCurrTdlsPeers;
Gopichand Nakkala681989c2013-03-06 22:27:48 -08007486
7487 ENTER();
7488
Gopichand Nakkala838be5d2013-04-10 22:41:51 +05307489 if (NULL == pHddCtx || NULL == pHddCtx->cfg_ini)
Gopichand Nakkala681989c2013-03-06 22:27:48 -08007490 {
7491 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
7492 "Invalid arguments");
7493 return -EINVAL;
7494 }
Hoonki Lee27511902013-03-14 18:19:06 -07007495
7496 if ((eTDLS_SUPPORT_NOT_ENABLED == pHddCtx->tdls_mode) ||
7497 (eTDLS_SUPPORT_DISABLED == pHddCtx->tdls_mode))
7498 {
7499 VOS_TRACE( VOS_MODULE_ID_HDD, TDLS_LOG_LEVEL,
7500 "%s: TDLS mode is disabled OR not enabled in FW."
7501 MAC_ADDRESS_STR " Request declined.",
7502 __func__, MAC_ADDR_ARRAY(mac));
7503 return -ENOTSUPP;
7504 }
7505
Gopichand Nakkala681989c2013-03-06 22:27:48 -08007506 if (pHddCtx->isLogpInProgress)
7507 {
7508 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
7509 "%s:LOGP in Progress. Ignore!!!", __func__);
Atul Mittal115287b2014-07-08 13:26:33 +05307510 wlan_hdd_tdls_set_link_status(pAdapter,
7511 mac,
7512 eTDLS_LINK_IDLE,
7513 eTDLS_LINK_UNSPECIFIED);
Gopichand Nakkala681989c2013-03-06 22:27:48 -08007514 return -EBUSY;
7515 }
7516
Naresh Jayaram9c6f4462014-02-13 12:20:31 +05307517 pTdlsPeer = wlan_hdd_tdls_get_peer(pAdapter, mac);
Hoonki Lee5305c3a2013-04-29 23:28:59 -07007518
7519 if ( NULL == pTdlsPeer ) {
7520 VOS_TRACE( VOS_MODULE_ID_HDD, TDLS_LOG_LEVEL,
7521 "%s: " MAC_ADDRESS_STR " (update %d) not exist. return invalid",
7522 __func__, MAC_ADDR_ARRAY(mac), update);
7523 return -EINVAL;
Gopichand Nakkala34d1b062013-03-19 15:28:33 -07007524 }
Hoonki Lee5305c3a2013-04-29 23:28:59 -07007525
7526 /* in add station, we accept existing valid staId if there is */
7527 if ((0 == update) &&
7528 ((pTdlsPeer->link_status >= eTDLS_LINK_CONNECTING) ||
7529 (TDLS_STA_INDEX_VALID(pTdlsPeer->staId))))
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -07007530 {
Hoonki Lee5305c3a2013-04-29 23:28:59 -07007531 VOS_TRACE( VOS_MODULE_ID_HDD, TDLS_LOG_LEVEL,
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -07007532 "%s: " MAC_ADDRESS_STR
Hoonki Lee5305c3a2013-04-29 23:28:59 -07007533 " link_status %d. staId %d. add station ignored.",
7534 __func__, MAC_ADDR_ARRAY(mac), pTdlsPeer->link_status, pTdlsPeer->staId);
7535 return 0;
7536 }
7537 /* in change station, we accept only when staId is valid */
7538 if ((1 == update) &&
7539 ((pTdlsPeer->link_status > eTDLS_LINK_CONNECTING) ||
7540 (!TDLS_STA_INDEX_VALID(pTdlsPeer->staId))))
7541 {
7542 VOS_TRACE( VOS_MODULE_ID_HDD, TDLS_LOG_LEVEL,
7543 "%s: " MAC_ADDRESS_STR
7544 " link status %d. staId %d. change station %s.",
7545 __func__, MAC_ADDR_ARRAY(mac), pTdlsPeer->link_status, pTdlsPeer->staId,
7546 (TDLS_STA_INDEX_VALID(pTdlsPeer->staId)) ? "ignored" : "declined");
7547 return (TDLS_STA_INDEX_VALID(pTdlsPeer->staId)) ? 0 : -EPERM;
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -07007548 }
Gopichand Nakkala34d1b062013-03-19 15:28:33 -07007549
7550 /* when others are on-going, we want to change link_status to idle */
Madan Mohan Koyyalamudi96797442013-10-08 16:04:42 +05307551 if (NULL != wlan_hdd_tdls_is_progress(pHddCtx, mac, TRUE))
Gopichand Nakkala681989c2013-03-06 22:27:48 -08007552 {
Gopichand Nakkalac87400e2013-03-13 18:51:00 -07007553 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
7554 "%s: " MAC_ADDRESS_STR
7555 " TDLS setup is ongoing. Request declined.",
7556 __func__, MAC_ADDR_ARRAY(mac));
Gopichand Nakkala05922802013-03-14 12:23:19 -07007557 goto error;
Gopichand Nakkala681989c2013-03-06 22:27:48 -08007558 }
7559
7560 /* first to check if we reached to maximum supported TDLS peer.
7561 TODO: for now, return -EPERM looks working fine,
7562 but need to check if any other errno fit into this category.*/
Rajesh Chauhana34c6e62014-03-25 16:37:58 +05307563 numCurrTdlsPeers = wlan_hdd_tdlsConnectedPeers(pAdapter);
7564 if (HDD_MAX_NUM_TDLS_STA <= numCurrTdlsPeers)
Gopichand Nakkala681989c2013-03-06 22:27:48 -08007565 {
Gopichand Nakkalac87400e2013-03-13 18:51:00 -07007566 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
7567 "%s: " MAC_ADDRESS_STR
Rajesh Chauhana34c6e62014-03-25 16:37:58 +05307568 " TDLS Max peer already connected. Request declined."
7569 " Num of peers (%d), Max allowed (%d).",
7570 __func__, MAC_ADDR_ARRAY(mac), numCurrTdlsPeers,
7571 HDD_MAX_NUM_TDLS_STA);
Gopichand Nakkala05922802013-03-14 12:23:19 -07007572 goto error;
Gopichand Nakkala681989c2013-03-06 22:27:48 -08007573 }
7574 else
7575 {
7576 hddTdlsPeer_t *pTdlsPeer;
Madan Mohan Koyyalamudi96797442013-10-08 16:04:42 +05307577 pTdlsPeer = wlan_hdd_tdls_find_peer(pAdapter, mac, TRUE);
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -07007578 if (pTdlsPeer && TDLS_IS_CONNECTED(pTdlsPeer))
Gopichand Nakkala681989c2013-03-06 22:27:48 -08007579 {
Gopichand Nakkalac87400e2013-03-13 18:51:00 -07007580 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
7581 "%s: " MAC_ADDRESS_STR " already connected. Request declined.",
7582 __func__, MAC_ADDR_ARRAY(mac));
Gopichand Nakkala681989c2013-03-06 22:27:48 -08007583 return -EPERM;
7584 }
7585 }
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -07007586 if (0 == update)
Atul Mittal115287b2014-07-08 13:26:33 +05307587 wlan_hdd_tdls_set_link_status(pAdapter,
7588 mac,
7589 eTDLS_LINK_CONNECTING,
7590 eTDLS_LINK_SUCCESS);
Gopichand Nakkala681989c2013-03-06 22:27:48 -08007591
Jeff Johnsond75fe012013-04-06 10:53:06 -07007592 /* debug code */
Gopichand Nakkala838be5d2013-04-10 22:41:51 +05307593 if (NULL != StaParams)
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -07007594 {
7595 VOS_TRACE(VOS_MODULE_ID_HDD, TDLS_LOG_LEVEL,
7596 "%s: TDLS Peer Parameters.", __func__);
Hoonki Lee66b75f32013-04-16 18:30:07 -07007597 if(StaParams->htcap_present)
7598 {
7599 VOS_TRACE(VOS_MODULE_ID_HDD, TDLS_LOG_LEVEL,
7600 "ht_capa->cap_info: %0x", StaParams->HTCap.capInfo);
7601 VOS_TRACE(VOS_MODULE_ID_HDD, TDLS_LOG_LEVEL,
7602 "ht_capa->extended_capabilities: %0x",
7603 StaParams->HTCap.extendedHtCapInfo);
7604 }
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -07007605 VOS_TRACE(VOS_MODULE_ID_HDD, TDLS_LOG_LEVEL,
7606 "params->capability: %0x",StaParams->capability);
7607 VOS_TRACE(VOS_MODULE_ID_HDD, TDLS_LOG_LEVEL,
Jeff Johnson0299d0a2013-10-30 12:37:43 -07007608 "params->ext_capab_len: %0x",StaParams->extn_capability[0]);
Hoonki Lee66b75f32013-04-16 18:30:07 -07007609 if(StaParams->vhtcap_present)
7610 {
7611 VOS_TRACE(VOS_MODULE_ID_HDD, TDLS_LOG_LEVEL,
7612 "rxMcsMap %x rxHighest %x txMcsMap %x txHighest %x",
7613 StaParams->VHTCap.suppMcs.rxMcsMap, StaParams->VHTCap.suppMcs.rxHighest,
7614 StaParams->VHTCap.suppMcs.txMcsMap, StaParams->VHTCap.suppMcs.txHighest);
7615 }
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -07007616 {
7617 int i = 0;
Hoonki Lee5305c3a2013-04-29 23:28:59 -07007618 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO, "Supported rates:");
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -07007619 for (i = 0; i < sizeof(StaParams->supported_rates); i++)
7620 VOS_TRACE(VOS_MODULE_ID_HDD, TDLS_LOG_LEVEL,
7621 "[%d]: %x ", i, StaParams->supported_rates[i]);
7622 }
Jeff Johnsond75fe012013-04-06 10:53:06 -07007623 } /* end debug code */
Gopichand Nakkala838be5d2013-04-10 22:41:51 +05307624 else if ((1 == update) && (NULL == StaParams))
7625 {
7626 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
7627 "%s : update is true, but staParams is NULL. Error!", __func__);
7628 return -EPERM;
7629 }
Gopichand Nakkala681989c2013-03-06 22:27:48 -08007630
7631 INIT_COMPLETION(pAdapter->tdls_add_station_comp);
7632
7633 if (!update)
7634 {
7635 status = sme_AddTdlsPeerSta(WLAN_HDD_GET_HAL_CTX(pAdapter),
7636 pAdapter->sessionId, mac);
7637 }
7638 else
7639 {
7640 status = sme_ChangeTdlsPeerSta(WLAN_HDD_GET_HAL_CTX(pAdapter),
7641 pAdapter->sessionId, mac, StaParams);
7642 }
7643
c_hpothu6ff1c3c2013-10-01 19:01:57 +05307644 ret = wait_for_completion_interruptible_timeout(&pAdapter->tdls_add_station_comp,
Gopichand Nakkala681989c2013-03-06 22:27:48 -08007645 msecs_to_jiffies(WAIT_TIME_TDLS_ADD_STA));
7646
c_hpothu6ff1c3c2013-10-01 19:01:57 +05307647 if (ret <= 0)
Gopichand Nakkala681989c2013-03-06 22:27:48 -08007648 {
Gopichand Nakkalac87400e2013-03-13 18:51:00 -07007649 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
c_hpothu6ff1c3c2013-10-01 19:01:57 +05307650 "%s: timeout waiting for tdls add station indication %ld",
7651 __func__, ret);
Gopichand Nakkala34d1b062013-03-19 15:28:33 -07007652 return -EPERM;
Gopichand Nakkala681989c2013-03-06 22:27:48 -08007653 }
c_hpothu6ff1c3c2013-10-01 19:01:57 +05307654
Gopichand Nakkala681989c2013-03-06 22:27:48 -08007655 if ( eHAL_STATUS_SUCCESS != pAdapter->tdlsAddStaStatus)
7656 {
Gopichand Nakkalac87400e2013-03-13 18:51:00 -07007657 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Gopichand Nakkala681989c2013-03-06 22:27:48 -08007658 "%s: Add Station is unsucessful", __func__);
Gopichand Nakkala34d1b062013-03-19 15:28:33 -07007659 return -EPERM;
Gopichand Nakkala681989c2013-03-06 22:27:48 -08007660 }
7661
7662 return 0;
Gopichand Nakkala05922802013-03-14 12:23:19 -07007663
7664error:
Atul Mittal115287b2014-07-08 13:26:33 +05307665 wlan_hdd_tdls_set_link_status(pAdapter,
7666 mac,
7667 eTDLS_LINK_IDLE,
7668 eTDLS_LINK_UNSPECIFIED);
Gopichand Nakkala05922802013-03-14 12:23:19 -07007669 return -EPERM;
7670
Gopichand Nakkala681989c2013-03-06 22:27:48 -08007671}
7672#endif
7673
Jeff Johnson295189b2012-06-20 16:38:30 -07007674static int wlan_hdd_change_station(struct wiphy *wiphy,
7675 struct net_device *dev,
7676 u8 *mac,
7677 struct station_parameters *params)
7678{
7679 VOS_STATUS status = VOS_STATUS_SUCCESS;
7680 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( dev );
Gopichand Nakkala29149562013-05-10 21:43:41 +05307681 hdd_context_t *pHddCtx;
7682 hdd_station_ctx_t *pHddStaCtx;
Jeff Johnson295189b2012-06-20 16:38:30 -07007683 v_MACADDR_t STAMacAddress;
Gopichand Nakkalab0856222013-03-12 22:39:05 -07007684#ifdef FEATURE_WLAN_TDLS
Gopichand Nakkala681989c2013-03-06 22:27:48 -08007685 tCsrStaParams StaParams = {0};
Gopichand Nakkala681989c2013-03-06 22:27:48 -08007686 tANI_U8 isBufSta = 0;
Naresh Jayaram3180aa42014-02-12 21:47:26 +05307687 tANI_U8 isOffChannelSupported = 0;
Gopichand Nakkalab0856222013-03-12 22:39:05 -07007688#endif
Jeff Johnsone7245742012-09-05 17:12:55 -07007689 ENTER();
7690
Gopichand Nakkala29149562013-05-10 21:43:41 +05307691 if ((NULL == pAdapter))
7692 {
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +05307693 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
Gopichand Nakkala29149562013-05-10 21:43:41 +05307694 "invalid adapter ");
7695 return -EINVAL;
7696 }
7697
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05307698 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
7699 TRACE_CODE_HDD_CHANGE_STATION,
7700 pAdapter->sessionId, params->listen_interval));
Gopichand Nakkala29149562013-05-10 21:43:41 +05307701 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
7702 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
7703
7704 if ((NULL == pHddCtx) || (NULL == pHddStaCtx))
7705 {
7706 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
7707 "invalid HDD state or HDD station context");
7708 return -EINVAL;
7709 }
7710
7711 if (pHddCtx->isLogpInProgress)
Jeff Johnson04dd8a82012-06-29 20:41:40 -07007712 {
7713 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
7714 "%s:LOGP in Progress. Ignore!!!", __func__);
7715 return -EAGAIN;
7716 }
7717
Jeff Johnson295189b2012-06-20 16:38:30 -07007718 vos_mem_copy(STAMacAddress.bytes, mac, sizeof(v_MACADDR_t));
7719
Gopichand Nakkala681989c2013-03-06 22:27:48 -08007720 if ((pAdapter->device_mode == WLAN_HDD_SOFTAP)
7721 || (pAdapter->device_mode == WLAN_HDD_P2P_GO))
Jeff Johnson295189b2012-06-20 16:38:30 -07007722 {
Gopichand Nakkala681989c2013-03-06 22:27:48 -08007723 if (params->sta_flags_set & BIT(NL80211_STA_FLAG_AUTHORIZED))
Jeff Johnson295189b2012-06-20 16:38:30 -07007724 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307725 status = hdd_softap_change_STA_state( pAdapter, &STAMacAddress,
Jeff Johnson295189b2012-06-20 16:38:30 -07007726 WLANTL_STA_AUTHENTICATED);
7727
Gopichand Nakkala29149562013-05-10 21:43:41 +05307728 if (status != VOS_STATUS_SUCCESS)
7729 {
7730 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
7731 "%s: Not able to change TL state to AUTHENTICATED", __func__);
7732 return -EINVAL;
7733 }
Jeff Johnson295189b2012-06-20 16:38:30 -07007734 }
7735 }
Hoonki Leea6d49be2013-04-05 09:43:25 -07007736 else if ((pAdapter->device_mode == WLAN_HDD_INFRA_STATION)
7737 || (pAdapter->device_mode == WLAN_HDD_P2P_CLIENT)) {
Gopichand Nakkala29149562013-05-10 21:43:41 +05307738#ifdef FEATURE_WLAN_TDLS
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -07007739 if (params->sta_flags_set & BIT(NL80211_STA_FLAG_TDLS_PEER)) {
7740 StaParams.capability = params->capability;
7741 StaParams.uapsd_queues = params->uapsd_queues;
7742 StaParams.max_sp = params->max_sp;
7743
Naresh Jayaram3180aa42014-02-12 21:47:26 +05307744 /* Convert (first channel , number of channels) tuple to
7745 * the total list of channels. This goes with the assumption
7746 * that if the first channel is < 14, then the next channels
7747 * are an incremental of 1 else an incremental of 4 till the number
7748 * of channels.
7749 */
7750 if (0 != params->supported_channels_len) {
7751 int i = 0,j = 0,k = 0, no_of_channels = 0 ;
7752 for ( i = 0 ; i < params->supported_channels_len ; i+=2)
7753 {
7754 int wifi_chan_index;
7755 StaParams.supported_channels[j] = params->supported_channels[i];
7756 wifi_chan_index =
7757 ((StaParams.supported_channels[j] <= HDD_CHANNEL_14 ) ? 1 : 4 );
7758 no_of_channels = params->supported_channels[i+1];
7759 for(k=1; k <= no_of_channels; k++)
7760 {
7761 StaParams.supported_channels[j+1] =
7762 StaParams.supported_channels[j] + wifi_chan_index;
7763 j+=1;
7764 }
7765 }
7766 StaParams.supported_channels_len = j;
7767 }
7768 vos_mem_copy(StaParams.supported_oper_classes,
7769 params->supported_oper_classes,
7770 params->supported_oper_classes_len);
7771 StaParams.supported_oper_classes_len =
7772 params->supported_oper_classes_len;
7773
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -07007774 if (0 != params->ext_capab_len)
7775 vos_mem_copy(StaParams.extn_capability, params->ext_capab,
7776 sizeof(StaParams.extn_capability));
7777
7778 if (NULL != params->ht_capa)
Hoonki Lee66b75f32013-04-16 18:30:07 -07007779 {
7780 StaParams.htcap_present = 1;
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -07007781 vos_mem_copy(&StaParams.HTCap, params->ht_capa, sizeof(tSirHTCap));
Hoonki Lee66b75f32013-04-16 18:30:07 -07007782 }
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -07007783
7784 StaParams.supported_rates_len = params->supported_rates_len;
7785
7786 /* Note : The Maximum sizeof supported_rates sent by the Supplicant is 32.
7787 * The supported_rates array , for all the structures propogating till Add Sta
7788 * to the firmware has to be modified , if the supplicant (ieee80211) is
7789 * modified to send more rates.
7790 */
7791
7792 /* To avoid Data Currption , set to max length to SIR_MAC_MAX_SUPP_RATES
7793 */
7794 if (StaParams.supported_rates_len > SIR_MAC_MAX_SUPP_RATES)
7795 StaParams.supported_rates_len = SIR_MAC_MAX_SUPP_RATES;
7796
7797 if (0 != StaParams.supported_rates_len) {
7798 int i = 0;
7799 vos_mem_copy(StaParams.supported_rates, params->supported_rates,
7800 StaParams.supported_rates_len);
Hoonki Lee5305c3a2013-04-29 23:28:59 -07007801 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -07007802 "Supported Rates with Length %d", StaParams.supported_rates_len);
7803 for (i=0; i < StaParams.supported_rates_len; i++)
Hoonki Lee5305c3a2013-04-29 23:28:59 -07007804 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -07007805 "[%d]: %0x", i, StaParams.supported_rates[i]);
7806 }
7807
7808 if (NULL != params->vht_capa)
Hoonki Lee66b75f32013-04-16 18:30:07 -07007809 {
7810 StaParams.vhtcap_present = 1;
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -07007811 vos_mem_copy(&StaParams.VHTCap, params->vht_capa, sizeof(tSirVHTCap));
Hoonki Lee66b75f32013-04-16 18:30:07 -07007812 }
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -07007813
Gopichand Nakkala681989c2013-03-06 22:27:48 -08007814 if (0 != params->ext_capab_len ) {
7815 /*Define A Macro : TODO Sunil*/
7816 if ((1<<4) & StaParams.extn_capability[3]) {
7817 isBufSta = 1;
7818 }
Naresh Jayaram3180aa42014-02-12 21:47:26 +05307819 /* TDLS Channel Switching Support */
7820 if ((1<<6) & StaParams.extn_capability[3]) {
7821 isOffChannelSupported = 1;
7822 }
Gopichand Nakkala681989c2013-03-06 22:27:48 -08007823 }
Naresh Jayaram3180aa42014-02-12 21:47:26 +05307824 status = wlan_hdd_tdls_set_peer_caps( pAdapter, mac,
7825 &StaParams, isBufSta,
7826 isOffChannelSupported);
7827
Gopichand Nakkala79ff85d2013-05-27 17:05:29 +05307828 if (VOS_STATUS_SUCCESS != status) {
7829 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
7830 "%s: wlan_hdd_tdls_set_peer_caps failed!", __func__);
7831 return -EINVAL;
7832 }
Gopichand Nakkala681989c2013-03-06 22:27:48 -08007833 status = wlan_hdd_tdls_add_station(wiphy, dev, mac, 1, &StaParams);
7834
7835 if (VOS_STATUS_SUCCESS != status) {
7836 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
7837 "%s: sme_ChangeTdlsPeerSta failed!", __func__);
7838 return -EINVAL;
7839 }
7840 }
Gopichand Nakkalab0856222013-03-12 22:39:05 -07007841#endif
Gopichand Nakkala6239acd2013-06-14 14:48:00 +05307842 }
Jeff Johnsone7245742012-09-05 17:12:55 -07007843 EXIT();
Jeff Johnson295189b2012-06-20 16:38:30 -07007844 return status;
7845}
7846
7847/*
Mahesh A Saptasagar1a51bc02014-06-02 18:28:08 +05307848 * FUNCTION: __wlan_hdd_cfg80211_add_key
Jeff Johnson295189b2012-06-20 16:38:30 -07007849 * This function is used to initialize the key information
7850 */
7851#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
Mahesh A Saptasagar1a51bc02014-06-02 18:28:08 +05307852static int __wlan_hdd_cfg80211_add_key( struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -07007853 struct net_device *ndev,
7854 u8 key_index, bool pairwise,
7855 const u8 *mac_addr,
7856 struct key_params *params
7857 )
7858#else
Mahesh A Saptasagar1a51bc02014-06-02 18:28:08 +05307859static int __wlan_hdd_cfg80211_add_key( struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -07007860 struct net_device *ndev,
7861 u8 key_index, const u8 *mac_addr,
7862 struct key_params *params
7863 )
7864#endif
7865{
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -07007866 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( ndev );
Jeff Johnson295189b2012-06-20 16:38:30 -07007867 tCsrRoamSetKey setKey;
7868 u8 groupmacaddr[WNI_CFG_BSSID_LEN] = {0xFF,0xFF,0xFF,0xFF,0xFF,0xFF};
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05307869 int status;
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -07007870 v_U32_t roamId= 0xFF;
7871 v_CONTEXT_t pVosContext = (WLAN_HDD_GET_CTX(pAdapter))->pvosContext;
Jeff Johnson295189b2012-06-20 16:38:30 -07007872 hdd_hostapd_state_t *pHostapdState;
7873 VOS_STATUS vos_status;
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -07007874 eHalStatus halStatus;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05307875 hdd_context_t *pHddCtx;
Jeff Johnson295189b2012-06-20 16:38:30 -07007876
7877 ENTER();
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +05307878
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05307879 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
7880 TRACE_CODE_HDD_CFG80211_ADD_KEY,
7881 pAdapter->sessionId, params->key_len));
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05307882 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
7883 status = wlan_hdd_validate_context(pHddCtx);
7884
7885 if (0 != status)
Jeff Johnson04dd8a82012-06-29 20:41:40 -07007886 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05307887 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
7888 "%s: HDD context is not valid", __func__);
7889 return status;
Jeff Johnson04dd8a82012-06-29 20:41:40 -07007890 }
7891
Sushant Kaushik8bc7df22014-04-09 17:55:29 +05307892 hddLog(VOS_TRACE_LEVEL_INFO, "%s: device_mode = %s (%d)",
7893 __func__, hdd_device_modetoString(pAdapter->device_mode),
7894 pAdapter->device_mode);
Jeff Johnson295189b2012-06-20 16:38:30 -07007895
7896 if (CSR_MAX_NUM_KEY <= key_index)
7897 {
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -07007898 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Invalid key index %d", __func__,
Jeff Johnson295189b2012-06-20 16:38:30 -07007899 key_index);
7900
7901 return -EINVAL;
7902 }
7903
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -07007904 if (CSR_MAX_KEY_LEN < params->key_len)
7905 {
7906 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Invalid key length %d", __func__,
7907 params->key_len);
7908
7909 return -EINVAL;
7910 }
7911
7912 hddLog(VOS_TRACE_LEVEL_INFO,
7913 "%s: called with key index = %d & key length %d",
7914 __func__, key_index, params->key_len);
Jeff Johnson295189b2012-06-20 16:38:30 -07007915
7916 /*extract key idx, key len and key*/
7917 vos_mem_zero(&setKey,sizeof(tCsrRoamSetKey));
7918 setKey.keyId = key_index;
7919 setKey.keyLength = params->key_len;
7920 vos_mem_copy(&setKey.Key[0],params->key, params->key_len);
7921
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -07007922 switch (params->cipher)
Jeff Johnson295189b2012-06-20 16:38:30 -07007923 {
7924 case WLAN_CIPHER_SUITE_WEP40:
7925 setKey.encType = eCSR_ENCRYPT_TYPE_WEP40_STATICKEY;
7926 break;
7927
7928 case WLAN_CIPHER_SUITE_WEP104:
7929 setKey.encType = eCSR_ENCRYPT_TYPE_WEP104_STATICKEY;
7930 break;
7931
7932 case WLAN_CIPHER_SUITE_TKIP:
7933 {
7934 u8 *pKey = &setKey.Key[0];
7935 setKey.encType = eCSR_ENCRYPT_TYPE_TKIP;
7936
7937 vos_mem_zero(pKey, CSR_MAX_KEY_LEN);
7938
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -07007939 /*Supplicant sends the 32bytes key in this order
Jeff Johnson295189b2012-06-20 16:38:30 -07007940
7941 |--------------|----------|----------|
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -07007942 | Tk1 |TX-MIC | RX Mic |
Jeff Johnson295189b2012-06-20 16:38:30 -07007943 |--------------|----------|----------|
7944 <---16bytes---><--8bytes--><--8bytes-->
7945
7946 */
7947 /*Sme expects the 32 bytes key to be in the below order
7948
7949 |--------------|----------|----------|
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -07007950 | Tk1 |RX-MIC | TX Mic |
Jeff Johnson295189b2012-06-20 16:38:30 -07007951 |--------------|----------|----------|
7952 <---16bytes---><--8bytes--><--8bytes-->
7953 */
7954 /* Copy the Temporal Key 1 (TK1) */
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -07007955 vos_mem_copy(pKey, params->key, 16);
Jeff Johnson295189b2012-06-20 16:38:30 -07007956
7957 /*Copy the rx mic first*/
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -07007958 vos_mem_copy(&pKey[16], &params->key[24], 8);
Jeff Johnson295189b2012-06-20 16:38:30 -07007959
7960 /*Copy the tx mic */
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -07007961 vos_mem_copy(&pKey[24], &params->key[16], 8);
Jeff Johnson295189b2012-06-20 16:38:30 -07007962
7963
7964 break;
7965 }
7966
7967 case WLAN_CIPHER_SUITE_CCMP:
7968 setKey.encType = eCSR_ENCRYPT_TYPE_AES;
7969 break;
7970
7971#ifdef FEATURE_WLAN_WAPI
7972 case WLAN_CIPHER_SUITE_SMS4:
7973 {
7974 vos_mem_zero(&setKey,sizeof(tCsrRoamSetKey));
7975 wlan_hdd_cfg80211_set_key_wapi(pAdapter, key_index, mac_addr,
7976 params->key, params->key_len);
7977 return 0;
7978 }
7979#endif
Chet Lanctot186b5732013-03-18 10:26:30 -07007980
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08007981#ifdef FEATURE_WLAN_ESE
Jeff Johnson295189b2012-06-20 16:38:30 -07007982 case WLAN_CIPHER_SUITE_KRK:
7983 setKey.encType = eCSR_ENCRYPT_TYPE_KRK;
7984 break;
7985#endif
Chet Lanctot186b5732013-03-18 10:26:30 -07007986
7987#ifdef WLAN_FEATURE_11W
7988 case WLAN_CIPHER_SUITE_AES_CMAC:
7989 setKey.encType = eCSR_ENCRYPT_TYPE_AES_CMAC;
Chet Lanctot3b5158a2013-03-31 16:45:21 -07007990 break;
Chet Lanctot186b5732013-03-18 10:26:30 -07007991#endif
7992
Jeff Johnson295189b2012-06-20 16:38:30 -07007993 default:
Jeff Johnson0299d0a2013-10-30 12:37:43 -07007994 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: unsupported cipher type %u",
Jeff Johnson295189b2012-06-20 16:38:30 -07007995 __func__, params->cipher);
Vinay Krishna Eranna6f22c1f2014-10-13 16:03:06 +05307996 status = -EOPNOTSUPP;
7997 goto end;
Jeff Johnson295189b2012-06-20 16:38:30 -07007998 }
7999
8000 hddLog(VOS_TRACE_LEVEL_INFO_MED, "%s: encryption type %d",
8001 __func__, setKey.encType);
8002
Shailender Karmuchi642e9812013-05-30 14:34:49 -07008003 if (
Jeff Johnson295189b2012-06-20 16:38:30 -07008004#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
8005 (!pairwise)
8006#else
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -07008007 (!mac_addr || is_broadcast_ether_addr(mac_addr))
Jeff Johnson295189b2012-06-20 16:38:30 -07008008#endif
Shailender Karmuchi642e9812013-05-30 14:34:49 -07008009 )
8010 {
8011 /* set group key*/
8012 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
8013 "%s- %d: setting Broadcast key",
8014 __func__, __LINE__);
8015 setKey.keyDirection = eSIR_RX_ONLY;
8016 vos_mem_copy(setKey.peerMac,groupmacaddr,WNI_CFG_BSSID_LEN);
8017 }
8018 else
8019 {
8020 /* set pairwise key*/
8021 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
8022 "%s- %d: setting pairwise key",
8023 __func__, __LINE__);
8024 setKey.keyDirection = eSIR_TX_RX;
8025 vos_mem_copy(setKey.peerMac, mac_addr,WNI_CFG_BSSID_LEN);
8026 }
8027 if ((WLAN_HDD_IBSS == pAdapter->device_mode) && !pairwise)
8028 {
8029 setKey.keyDirection = eSIR_TX_RX;
8030 /*Set the group key*/
8031 status = sme_RoamSetKey( WLAN_HDD_GET_HAL_CTX(pAdapter),
8032 pAdapter->sessionId, &setKey, &roamId );
Jeff Johnson295189b2012-06-20 16:38:30 -07008033
Shailender Karmuchi642e9812013-05-30 14:34:49 -07008034 if ( 0 != status )
8035 {
8036 hddLog(VOS_TRACE_LEVEL_ERROR,
8037 "%s: sme_RoamSetKey failed, returned %d", __func__, status);
Vinay Krishna Eranna6f22c1f2014-10-13 16:03:06 +05308038 status = -EINVAL;
8039 goto end;
Shailender Karmuchi642e9812013-05-30 14:34:49 -07008040 }
8041 /*Save the keys here and call sme_RoamSetKey for setting
8042 the PTK after peer joins the IBSS network*/
8043 vos_mem_copy(&pAdapter->sessionCtx.station.ibss_enc_key,
8044 &setKey, sizeof(tCsrRoamSetKey));
Vinay Krishna Eranna6f22c1f2014-10-13 16:03:06 +05308045 goto end;
Shailender Karmuchi642e9812013-05-30 14:34:49 -07008046 }
Gopichand Nakkala29149562013-05-10 21:43:41 +05308047 if ((pAdapter->device_mode == WLAN_HDD_SOFTAP) ||
8048 (pAdapter->device_mode == WLAN_HDD_P2P_GO))
8049 {
Jeff Johnson295189b2012-06-20 16:38:30 -07008050 pHostapdState = WLAN_HDD_GET_HOSTAP_STATE_PTR(pAdapter);
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -07008051 if( pHostapdState->bssState == BSS_START )
8052 {
c_hpothu7c55da62014-01-23 18:34:02 +05308053 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
8054 vos_status = wlan_hdd_check_ula_done(pAdapter);
8055
8056 if ( vos_status != VOS_STATUS_SUCCESS )
8057 {
8058 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
8059 "[%4d] wlan_hdd_check_ula_done returned ERROR status= %d",
8060 __LINE__, vos_status );
8061
8062 pHddStaCtx->roam_info.roamingState = HDD_ROAM_STATE_NONE;
8063
Vinay Krishna Eranna6f22c1f2014-10-13 16:03:06 +05308064 status = -EINVAL;
8065 goto end;
c_hpothu7c55da62014-01-23 18:34:02 +05308066 }
8067
Jeff Johnson295189b2012-06-20 16:38:30 -07008068 status = WLANSAP_SetKeySta( pVosContext, &setKey);
8069
8070 if ( status != eHAL_STATUS_SUCCESS )
8071 {
8072 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
8073 "[%4d] WLANSAP_SetKeySta returned ERROR status= %d",
8074 __LINE__, status );
Vinay Krishna Eranna6f22c1f2014-10-13 16:03:06 +05308075 status = -EINVAL;
8076 goto end;
Jeff Johnson295189b2012-06-20 16:38:30 -07008077 }
8078 }
8079
8080 /* Saving WEP keys */
8081 else if( eCSR_ENCRYPT_TYPE_WEP40_STATICKEY == setKey.encType ||
8082 eCSR_ENCRYPT_TYPE_WEP104_STATICKEY == setKey.encType )
8083 {
8084 //Save the wep key in ap context. Issue setkey after the BSS is started.
8085 hdd_ap_ctx_t *pAPCtx = WLAN_HDD_GET_AP_CTX_PTR(pAdapter);
8086 vos_mem_copy(&pAPCtx->wepKey[key_index], &setKey, sizeof(tCsrRoamSetKey));
8087 }
8088 else
8089 {
8090 //Save the key in ap context. Issue setkey after the BSS is started.
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -07008091 hdd_ap_ctx_t *pAPCtx = WLAN_HDD_GET_AP_CTX_PTR(pAdapter);
Jeff Johnson295189b2012-06-20 16:38:30 -07008092 vos_mem_copy(&pAPCtx->groupKey, &setKey, sizeof(tCsrRoamSetKey));
8093 }
8094 }
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -07008095 else if ( (pAdapter->device_mode == WLAN_HDD_INFRA_STATION) ||
8096 (pAdapter->device_mode == WLAN_HDD_P2P_CLIENT) )
Jeff Johnson295189b2012-06-20 16:38:30 -07008097 {
8098 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
8099 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
8100
Gopichand Nakkala3d295922013-05-07 16:19:14 +05308101#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
8102 if (!pairwise)
8103#else
8104 if (!mac_addr || is_broadcast_ether_addr(mac_addr))
8105#endif
8106 {
8107 /* set group key*/
8108 if (pHddStaCtx->roam_info.deferKeyComplete)
8109 {
8110 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
8111 "%s- %d: Perform Set key Complete",
8112 __func__, __LINE__);
8113 hdd_PerformRoamSetKeyComplete(pAdapter);
8114 }
8115 }
8116
Jeff Johnson295189b2012-06-20 16:38:30 -07008117 pWextState->roamProfile.Keys.KeyLength[key_index] = (u8)params->key_len;
8118
Venkata Prathyusha Kuntupalliee2ce712013-01-17 14:09:24 -08008119 pWextState->roamProfile.Keys.defaultIndex = key_index;
8120
8121
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -07008122 vos_mem_copy(&pWextState->roamProfile.Keys.KeyMaterial[key_index][0],
Jeff Johnson295189b2012-06-20 16:38:30 -07008123 params->key, params->key_len);
8124
Gopichand Nakkala3d295922013-05-07 16:19:14 +05308125
Jeff Johnson295189b2012-06-20 16:38:30 -07008126 pHddStaCtx->roam_info.roamingState = HDD_ROAM_STATE_SETTING_KEY;
8127
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308128 hddLog(VOS_TRACE_LEVEL_INFO_MED,
Jeff Johnson295189b2012-06-20 16:38:30 -07008129 "%s: set key for peerMac %2x:%2x:%2x:%2x:%2x:%2x, direction %d",
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308130 __func__, setKey.peerMac[0], setKey.peerMac[1],
8131 setKey.peerMac[2], setKey.peerMac[3],
8132 setKey.peerMac[4], setKey.peerMac[5],
Jeff Johnson295189b2012-06-20 16:38:30 -07008133 setKey.keyDirection);
8134
8135 vos_status = wlan_hdd_check_ula_done(pAdapter);
8136
8137 if ( vos_status != VOS_STATUS_SUCCESS )
8138 {
8139 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
8140 "[%4d] wlan_hdd_check_ula_done returned ERROR status= %d",
8141 __LINE__, vos_status );
8142
8143 pHddStaCtx->roam_info.roamingState = HDD_ROAM_STATE_NONE;
8144
Vinay Krishna Eranna6f22c1f2014-10-13 16:03:06 +05308145 status = -EINVAL;
8146 goto end;
Jeff Johnson295189b2012-06-20 16:38:30 -07008147
8148 }
8149
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -07008150#ifdef WLAN_FEATURE_VOWIFI_11R
Gopichand Nakkala3d295922013-05-07 16:19:14 +05308151 /* The supplicant may attempt to set the PTK once pre-authentication
8152 is done. Save the key in the UMAC and include it in the ADD BSS
8153 request */
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -07008154 halStatus = sme_FTUpdateKey( WLAN_HDD_GET_HAL_CTX(pAdapter), &setKey);
Gopichand Nakkala3d295922013-05-07 16:19:14 +05308155 if ( halStatus == eHAL_STATUS_FT_PREAUTH_KEY_SUCCESS )
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -07008156 {
Gopichand Nakkala3d295922013-05-07 16:19:14 +05308157 hddLog(VOS_TRACE_LEVEL_INFO_MED,
8158 "%s: Update PreAuth Key success", __func__);
Vinay Krishna Eranna6f22c1f2014-10-13 16:03:06 +05308159 status = 0;
8160 goto end;
Gopichand Nakkala3d295922013-05-07 16:19:14 +05308161 }
8162 else if ( halStatus == eHAL_STATUS_FT_PREAUTH_KEY_FAILED )
8163 {
8164 hddLog(VOS_TRACE_LEVEL_ERROR,
8165 "%s: Update PreAuth Key failed", __func__);
Vinay Krishna Eranna6f22c1f2014-10-13 16:03:06 +05308166 status = -EINVAL;
8167 goto end;
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -07008168 }
8169#endif /* WLAN_FEATURE_VOWIFI_11R */
Jeff Johnson295189b2012-06-20 16:38:30 -07008170
8171 /* issue set key request to SME*/
8172 status = sme_RoamSetKey( WLAN_HDD_GET_HAL_CTX(pAdapter),
8173 pAdapter->sessionId, &setKey, &roamId );
8174
8175 if ( 0 != status )
8176 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308177 hddLog(VOS_TRACE_LEVEL_ERROR,
Jeff Johnson295189b2012-06-20 16:38:30 -07008178 "%s: sme_RoamSetKey failed, returned %d", __func__, status);
8179 pHddStaCtx->roam_info.roamingState = HDD_ROAM_STATE_NONE;
Vinay Krishna Eranna6f22c1f2014-10-13 16:03:06 +05308180 status = -EINVAL;
8181 goto end;
Jeff Johnson295189b2012-06-20 16:38:30 -07008182 }
8183
8184
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308185 /* in case of IBSS as there was no information available about WEP keys during
8186 * IBSS join, group key intialized with NULL key, so re-initialize group key
Jeff Johnson295189b2012-06-20 16:38:30 -07008187 * with correct value*/
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308188 if ( (eCSR_BSS_TYPE_START_IBSS == pWextState->roamProfile.BSSType) &&
8189 !( ( IW_AUTH_KEY_MGMT_802_1X
8190 == (pWextState->authKeyMgmt & IW_AUTH_KEY_MGMT_802_1X))
Jeff Johnson295189b2012-06-20 16:38:30 -07008191 && (eCSR_AUTH_TYPE_OPEN_SYSTEM == pHddStaCtx->conn_info.authType)
8192 )
8193 &&
8194 ( (WLAN_CIPHER_SUITE_WEP40 == params->cipher)
8195 || (WLAN_CIPHER_SUITE_WEP104 == params->cipher)
8196 )
8197 )
8198 {
8199 setKey.keyDirection = eSIR_RX_ONLY;
8200 vos_mem_copy(setKey.peerMac,groupmacaddr,WNI_CFG_BSSID_LEN);
8201
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308202 hddLog(VOS_TRACE_LEVEL_INFO_MED,
Jeff Johnson295189b2012-06-20 16:38:30 -07008203 "%s: set key peerMac %2x:%2x:%2x:%2x:%2x:%2x, direction %d",
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308204 __func__, setKey.peerMac[0], setKey.peerMac[1],
8205 setKey.peerMac[2], setKey.peerMac[3],
8206 setKey.peerMac[4], setKey.peerMac[5],
Jeff Johnson295189b2012-06-20 16:38:30 -07008207 setKey.keyDirection);
8208
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308209 status = sme_RoamSetKey( WLAN_HDD_GET_HAL_CTX(pAdapter),
Jeff Johnson295189b2012-06-20 16:38:30 -07008210 pAdapter->sessionId, &setKey, &roamId );
8211
8212 if ( 0 != status )
8213 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308214 hddLog(VOS_TRACE_LEVEL_ERROR,
8215 "%s: sme_RoamSetKey failed for group key (IBSS), returned %d",
Jeff Johnson295189b2012-06-20 16:38:30 -07008216 __func__, status);
8217 pHddStaCtx->roam_info.roamingState = HDD_ROAM_STATE_NONE;
Vinay Krishna Eranna6f22c1f2014-10-13 16:03:06 +05308218 status = -EINVAL;
8219 goto end;
Jeff Johnson295189b2012-06-20 16:38:30 -07008220 }
8221 }
8222 }
8223
Vinay Krishna Eranna6f22c1f2014-10-13 16:03:06 +05308224end:
8225 /* Need to clear any trace of key value in the memory.
8226 * Thus zero out the memory even though it is local
8227 * variable.
8228 */
8229 vos_mem_zero(&setKey, sizeof(setKey));
8230
8231 return status;
Jeff Johnson295189b2012-06-20 16:38:30 -07008232}
8233
Mahesh A Saptasagar1a51bc02014-06-02 18:28:08 +05308234#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
8235static int wlan_hdd_cfg80211_add_key( struct wiphy *wiphy,
8236 struct net_device *ndev,
8237 u8 key_index, bool pairwise,
8238 const u8 *mac_addr,
8239 struct key_params *params
8240 )
8241#else
8242static int wlan_hdd_cfg80211_add_key( struct wiphy *wiphy,
8243 struct net_device *ndev,
8244 u8 key_index, const u8 *mac_addr,
8245 struct key_params *params
8246 )
8247#endif
8248{
8249 int ret;
8250 vos_ssr_protect(__func__);
8251#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
8252 ret = __wlan_hdd_cfg80211_add_key(wiphy, ndev, key_index, pairwise,
8253 mac_addr, params);
8254#else
8255 ret = __wlan_hdd_cfg80211_add_key(wiphy, ndev, key_index, mac_addr,
8256 params);
8257#endif
8258 vos_ssr_unprotect(__func__);
8259
8260 return ret;
8261}
8262
Jeff Johnson295189b2012-06-20 16:38:30 -07008263/*
Mahesh A Saptasagar1a51bc02014-06-02 18:28:08 +05308264 * FUNCTION: __wlan_hdd_cfg80211_get_key
Jeff Johnson295189b2012-06-20 16:38:30 -07008265 * This function is used to get the key information
8266 */
8267#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
Mahesh A Saptasagar1a51bc02014-06-02 18:28:08 +05308268static int __wlan_hdd_cfg80211_get_key(
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308269 struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -07008270 struct net_device *ndev,
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308271 u8 key_index, bool pairwise,
Jeff Johnson295189b2012-06-20 16:38:30 -07008272 const u8 *mac_addr, void *cookie,
8273 void (*callback)(void *cookie, struct key_params*)
8274 )
8275#else
Mahesh A Saptasagar1a51bc02014-06-02 18:28:08 +05308276static int __wlan_hdd_cfg80211_get_key(
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308277 struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -07008278 struct net_device *ndev,
8279 u8 key_index, const u8 *mac_addr, void *cookie,
8280 void (*callback)(void *cookie, struct key_params*)
8281 )
8282#endif
8283{
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308284 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( ndev );
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +05308285 hdd_wext_state_t *pWextState= WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
8286 tCsrRoamProfile *pRoamProfile = &(pWextState->roamProfile);
Jeff Johnson295189b2012-06-20 16:38:30 -07008287 struct key_params params;
8288
8289 ENTER();
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308290
Sushant Kaushik8bc7df22014-04-09 17:55:29 +05308291 hddLog(VOS_TRACE_LEVEL_INFO, "%s: device_mode = %s (%d)",
8292 __func__, hdd_device_modetoString(pAdapter->device_mode),
8293 pAdapter->device_mode);
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +05308294
Jeff Johnson295189b2012-06-20 16:38:30 -07008295 memset(&params, 0, sizeof(params));
8296
8297 if (CSR_MAX_NUM_KEY <= key_index)
8298 {
c_hpothu6ff1c3c2013-10-01 19:01:57 +05308299 hddLog(VOS_TRACE_LEVEL_ERROR, FL("invalid key index %d"), key_index);
Jeff Johnson295189b2012-06-20 16:38:30 -07008300 return -EINVAL;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308301 }
Jeff Johnson295189b2012-06-20 16:38:30 -07008302
8303 switch(pRoamProfile->EncryptionType.encryptionType[0])
8304 {
8305 case eCSR_ENCRYPT_TYPE_NONE:
8306 params.cipher = IW_AUTH_CIPHER_NONE;
8307 break;
8308
8309 case eCSR_ENCRYPT_TYPE_WEP40_STATICKEY:
8310 case eCSR_ENCRYPT_TYPE_WEP40:
8311 params.cipher = WLAN_CIPHER_SUITE_WEP40;
8312 break;
8313
8314 case eCSR_ENCRYPT_TYPE_WEP104_STATICKEY:
8315 case eCSR_ENCRYPT_TYPE_WEP104:
8316 params.cipher = WLAN_CIPHER_SUITE_WEP104;
8317 break;
8318
8319 case eCSR_ENCRYPT_TYPE_TKIP:
8320 params.cipher = WLAN_CIPHER_SUITE_TKIP;
8321 break;
8322
8323 case eCSR_ENCRYPT_TYPE_AES:
8324 params.cipher = WLAN_CIPHER_SUITE_AES_CMAC;
8325 break;
8326
8327 default:
8328 params.cipher = IW_AUTH_CIPHER_NONE;
8329 break;
8330 }
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +05308331
c_hpothuaaf19692014-05-17 17:01:48 +05308332 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
8333 TRACE_CODE_HDD_CFG80211_GET_KEY,
8334 pAdapter->sessionId, params.cipher));
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +05308335
Jeff Johnson295189b2012-06-20 16:38:30 -07008336 params.key_len = pRoamProfile->Keys.KeyLength[key_index];
8337 params.seq_len = 0;
8338 params.seq = NULL;
8339 params.key = &pRoamProfile->Keys.KeyMaterial[key_index][0];
8340 callback(cookie, &params);
8341 return 0;
8342}
8343
Mahesh A Saptasagar1a51bc02014-06-02 18:28:08 +05308344#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
8345static int wlan_hdd_cfg80211_get_key(
8346 struct wiphy *wiphy,
8347 struct net_device *ndev,
8348 u8 key_index, bool pairwise,
8349 const u8 *mac_addr, void *cookie,
8350 void (*callback)(void *cookie, struct key_params*)
8351 )
8352#else
8353static int wlan_hdd_cfg80211_get_key(
8354 struct wiphy *wiphy,
8355 struct net_device *ndev,
8356 u8 key_index, const u8 *mac_addr, void *cookie,
8357 void (*callback)(void *cookie, struct key_params*)
8358 )
8359#endif
8360{
8361 int ret;
8362
8363 vos_ssr_protect(__func__);
8364#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
8365 ret = __wlan_hdd_cfg80211_get_key(wiphy, ndev, key_index, pairwise,
8366 mac_addr, cookie, callback);
8367#else
8368 ret = __wlan_hdd_cfg80211_get_key(wiphy, ndev, key_index, mac_addr,
8369 callback);
8370#endif
8371 vos_ssr_unprotect(__func__);
8372
8373 return ret;
8374}
8375
Jeff Johnson295189b2012-06-20 16:38:30 -07008376/*
8377 * FUNCTION: wlan_hdd_cfg80211_del_key
8378 * This function is used to delete the key information
8379 */
8380#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308381static int wlan_hdd_cfg80211_del_key( struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -07008382 struct net_device *ndev,
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308383 u8 key_index,
8384 bool pairwise,
Jeff Johnson295189b2012-06-20 16:38:30 -07008385 const u8 *mac_addr
8386 )
8387#else
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308388static int wlan_hdd_cfg80211_del_key( struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -07008389 struct net_device *ndev,
8390 u8 key_index,
8391 const u8 *mac_addr
8392 )
8393#endif
8394{
8395 int status = 0;
8396
8397 //This code needs to be revisited. There is sme_removeKey API, we should
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308398 //plan to use that. After the change to use correct index in setkey,
Jeff Johnson295189b2012-06-20 16:38:30 -07008399 //it is observed that this is invalidating peer
8400 //key index whenever re-key is done. This is affecting data link.
8401 //It should be ok to ignore del_key.
8402#if 0
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308403 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( ndev );
8404 v_CONTEXT_t pVosContext = (WLAN_HDD_GET_CTX(pAdapter))->pvosContext;
Jeff Johnson295189b2012-06-20 16:38:30 -07008405 u8 groupmacaddr[WNI_CFG_BSSID_LEN] = {0xFF,0xFF,0xFF,0xFF,0xFF,0xFF};
8406 tCsrRoamSetKey setKey;
8407 v_U32_t roamId= 0xFF;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308408
Jeff Johnson295189b2012-06-20 16:38:30 -07008409 ENTER();
8410
8411 hddLog(VOS_TRACE_LEVEL_INFO_HIGH, "%s: device_mode = %d\n",
8412 __func__,pAdapter->device_mode);
8413
8414 if (CSR_MAX_NUM_KEY <= key_index)
8415 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308416 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Invalid key index %d", __func__,
Jeff Johnson295189b2012-06-20 16:38:30 -07008417 key_index);
8418
8419 return -EINVAL;
8420 }
8421
8422 vos_mem_zero(&setKey,sizeof(tCsrRoamSetKey));
8423 setKey.keyId = key_index;
8424
8425 if (mac_addr)
8426 vos_mem_copy(setKey.peerMac, mac_addr,WNI_CFG_BSSID_LEN);
8427 else
8428 vos_mem_copy(setKey.peerMac, groupmacaddr, WNI_CFG_BSSID_LEN);
8429
8430 setKey.encType = eCSR_ENCRYPT_TYPE_NONE;
8431
8432 if ((pAdapter->device_mode == WLAN_HDD_SOFTAP)
Jeff Johnson295189b2012-06-20 16:38:30 -07008433 || (pAdapter->device_mode == WLAN_HDD_P2P_GO)
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308434 )
8435 {
8436
8437 hdd_hostapd_state_t *pHostapdState =
Jeff Johnson295189b2012-06-20 16:38:30 -07008438 WLAN_HDD_GET_HOSTAP_STATE_PTR(pAdapter);
8439 if( pHostapdState->bssState == BSS_START)
8440 {
8441 status = WLANSAP_SetKeySta( pVosContext, &setKey);
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308442
Jeff Johnson295189b2012-06-20 16:38:30 -07008443 if ( status != eHAL_STATUS_SUCCESS )
8444 {
8445 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
8446 "[%4d] WLANSAP_SetKeySta returned ERROR status= %d",
8447 __LINE__, status );
8448 }
8449 }
8450 }
8451 else if ( (pAdapter->device_mode == WLAN_HDD_INFRA_STATION)
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308452 || (pAdapter->device_mode == WLAN_HDD_P2P_CLIENT)
Jeff Johnson295189b2012-06-20 16:38:30 -07008453 )
8454 {
8455 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
8456
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308457 pHddStaCtx->roam_info.roamingState = HDD_ROAM_STATE_SETTING_KEY;
8458
8459 hddLog(VOS_TRACE_LEVEL_INFO_MED,
Jeff Johnson295189b2012-06-20 16:38:30 -07008460 "%s: delete key for peerMac %2x:%2x:%2x:%2x:%2x:%2x",
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308461 __func__, setKey.peerMac[0], setKey.peerMac[1],
8462 setKey.peerMac[2], setKey.peerMac[3],
Jeff Johnson295189b2012-06-20 16:38:30 -07008463 setKey.peerMac[4], setKey.peerMac[5]);
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308464 if(pAdapter->sessionCtx.station.conn_info.connState ==
8465 eConnectionState_Associated)
Jeff Johnson295189b2012-06-20 16:38:30 -07008466 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308467 status = sme_RoamSetKey( WLAN_HDD_GET_HAL_CTX(pAdapter),
Jeff Johnson295189b2012-06-20 16:38:30 -07008468 pAdapter->sessionId, &setKey, &roamId );
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308469
Jeff Johnson295189b2012-06-20 16:38:30 -07008470 if ( 0 != status )
8471 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308472 hddLog(VOS_TRACE_LEVEL_ERROR,
Jeff Johnson295189b2012-06-20 16:38:30 -07008473 "%s: sme_RoamSetKey failure, returned %d",
8474 __func__, status);
8475 pHddStaCtx->roam_info.roamingState = HDD_ROAM_STATE_NONE;
8476 return -EINVAL;
8477 }
8478 }
8479 }
8480#endif
Jeff Johnsone7245742012-09-05 17:12:55 -07008481 EXIT();
Jeff Johnson295189b2012-06-20 16:38:30 -07008482 return status;
8483}
8484
8485/*
Mahesh A Saptasagar1a51bc02014-06-02 18:28:08 +05308486 * FUNCTION: __wlan_hdd_cfg80211_set_default_key
Jeff Johnson295189b2012-06-20 16:38:30 -07008487 * This function is used to set the default tx key index
8488 */
8489#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
Mahesh A Saptasagar1a51bc02014-06-02 18:28:08 +05308490static int __wlan_hdd_cfg80211_set_default_key( struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -07008491 struct net_device *ndev,
8492 u8 key_index,
8493 bool unicast, bool multicast)
8494#else
Mahesh A Saptasagar1a51bc02014-06-02 18:28:08 +05308495static int __wlan_hdd_cfg80211_set_default_key( struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -07008496 struct net_device *ndev,
8497 u8 key_index)
8498#endif
8499{
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308500 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( ndev );
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05308501 int status;
Gopichand Nakkala29149562013-05-10 21:43:41 +05308502 hdd_wext_state_t *pWextState;
8503 hdd_station_ctx_t *pHddStaCtx;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05308504 hdd_context_t *pHddCtx;
Jeff Johnson295189b2012-06-20 16:38:30 -07008505
8506 ENTER();
8507
Gopichand Nakkala29149562013-05-10 21:43:41 +05308508 if ((NULL == pAdapter))
8509 {
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +05308510 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
Gopichand Nakkala29149562013-05-10 21:43:41 +05308511 "invalid adapter");
8512 return -EINVAL;
8513 }
8514
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05308515 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
8516 TRACE_CODE_HDD_CFG80211_SET_DEFAULT_KEY,
8517 pAdapter->sessionId, key_index));
8518
Gopichand Nakkala29149562013-05-10 21:43:41 +05308519 pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
8520 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
8521
8522 if ((NULL == pWextState) || (NULL == pHddStaCtx))
8523 {
8524 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
8525 "invalid Wext state or HDD context");
8526 return -EINVAL;
8527 }
8528
Arif Hussain6d2a3322013-11-17 19:50:10 -08008529 hddLog(VOS_TRACE_LEVEL_INFO, "%s: device_mode = %d key_index = %d",
Jeff Johnson295189b2012-06-20 16:38:30 -07008530 __func__,pAdapter->device_mode, key_index);
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308531
Jeff Johnson295189b2012-06-20 16:38:30 -07008532 if (CSR_MAX_NUM_KEY <= key_index)
8533 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308534 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Invalid key index %d", __func__,
Jeff Johnson295189b2012-06-20 16:38:30 -07008535 key_index);
8536
8537 return -EINVAL;
8538 }
8539
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05308540 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
8541 status = wlan_hdd_validate_context(pHddCtx);
8542
8543 if (0 != status)
Jeff Johnson04dd8a82012-06-29 20:41:40 -07008544 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05308545 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
8546 "%s: HDD context is not valid", __func__);
8547 return status;
Jeff Johnson04dd8a82012-06-29 20:41:40 -07008548 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308549
Jeff Johnson295189b2012-06-20 16:38:30 -07008550 if ((pAdapter->device_mode == WLAN_HDD_INFRA_STATION)
Jeff Johnson295189b2012-06-20 16:38:30 -07008551 || (pAdapter->device_mode == WLAN_HDD_P2P_CLIENT)
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308552 )
Jeff Johnson295189b2012-06-20 16:38:30 -07008553 {
Gopichand Nakkala29149562013-05-10 21:43:41 +05308554 if ( (eCSR_ENCRYPT_TYPE_TKIP !=
Arif Hussain6943f522013-11-04 20:10:10 -08008555 pHddStaCtx->conn_info.ucEncryptionType) &&
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308556 (eCSR_ENCRYPT_TYPE_AES !=
Arif Hussain6943f522013-11-04 20:10:10 -08008557 pHddStaCtx->conn_info.ucEncryptionType)
Jeff Johnson295189b2012-06-20 16:38:30 -07008558 )
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308559 {
8560 /* if default key index is not same as previous one,
Jeff Johnson295189b2012-06-20 16:38:30 -07008561 * then update the default key index */
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308562
Jeff Johnson295189b2012-06-20 16:38:30 -07008563 tCsrRoamSetKey setKey;
8564 v_U32_t roamId= 0xFF;
8565 tCsrKeys *Keys = &pWextState->roamProfile.Keys;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308566
8567 hddLog(VOS_TRACE_LEVEL_INFO_HIGH, "%s: default tx key index %d",
Jeff Johnson295189b2012-06-20 16:38:30 -07008568 __func__, key_index);
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308569
Jeff Johnson295189b2012-06-20 16:38:30 -07008570 Keys->defaultIndex = (u8)key_index;
8571 vos_mem_zero(&setKey,sizeof(tCsrRoamSetKey));
8572 setKey.keyId = key_index;
8573 setKey.keyLength = Keys->KeyLength[key_index];
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308574
8575 vos_mem_copy(&setKey.Key[0],
8576 &Keys->KeyMaterial[key_index][0],
Jeff Johnson295189b2012-06-20 16:38:30 -07008577 Keys->KeyLength[key_index]);
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308578
Gopichand Nakkala29149562013-05-10 21:43:41 +05308579 setKey.keyDirection = eSIR_TX_RX;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308580
8581 vos_mem_copy(setKey.peerMac,
Jeff Johnson295189b2012-06-20 16:38:30 -07008582 &pHddStaCtx->conn_info.bssId[0],
8583 WNI_CFG_BSSID_LEN);
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308584
Gopichand Nakkala29149562013-05-10 21:43:41 +05308585 if (Keys->KeyLength[key_index] == CSR_WEP40_KEY_LEN &&
8586 pWextState->roamProfile.EncryptionType.encryptionType[0] ==
8587 eCSR_ENCRYPT_TYPE_WEP104)
8588 {
8589 /*In the case of dynamic wep supplicant hardcodes DWEP type to eCSR_ENCRYPT_TYPE_WEP104
8590 even though ap is configured for WEP-40 encryption. In this canse the key length
8591 is 5 but the encryption type is 104 hence checking the key langht(5) and encryption
8592 type(104) and switching encryption type to 40*/
8593 pWextState->roamProfile.EncryptionType.encryptionType[0] =
8594 eCSR_ENCRYPT_TYPE_WEP40;
8595 pWextState->roamProfile.mcEncryptionType.encryptionType[0] =
8596 eCSR_ENCRYPT_TYPE_WEP40;
8597 }
8598
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308599 setKey.encType =
Jeff Johnson295189b2012-06-20 16:38:30 -07008600 pWextState->roamProfile.EncryptionType.encryptionType[0];
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308601
Jeff Johnson295189b2012-06-20 16:38:30 -07008602 /* issue set key request */
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308603 status = sme_RoamSetKey( WLAN_HDD_GET_HAL_CTX(pAdapter),
Jeff Johnson295189b2012-06-20 16:38:30 -07008604 pAdapter->sessionId, &setKey, &roamId );
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308605
Jeff Johnson295189b2012-06-20 16:38:30 -07008606 if ( 0 != status )
8607 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308608 hddLog(VOS_TRACE_LEVEL_ERROR,
8609 "%s: sme_RoamSetKey failed, returned %d", __func__,
Jeff Johnson295189b2012-06-20 16:38:30 -07008610 status);
8611 return -EINVAL;
8612 }
8613 }
8614 }
8615
8616 /* In SoftAp mode setting key direction for default mode */
8617 else if ( WLAN_HDD_SOFTAP == pAdapter->device_mode )
8618 {
8619 if ( (eCSR_ENCRYPT_TYPE_TKIP !=
8620 pWextState->roamProfile.EncryptionType.encryptionType[0]) &&
8621 (eCSR_ENCRYPT_TYPE_AES !=
8622 pWextState->roamProfile.EncryptionType.encryptionType[0])
8623 )
8624 {
8625 /* Saving key direction for default key index to TX default */
8626 hdd_ap_ctx_t *pAPCtx = WLAN_HDD_GET_AP_CTX_PTR(pAdapter);
8627 pAPCtx->wepKey[key_index].keyDirection = eSIR_TX_DEFAULT;
8628 }
8629 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308630
Jeff Johnson295189b2012-06-20 16:38:30 -07008631 return status;
8632}
8633
Mahesh A Saptasagar1a51bc02014-06-02 18:28:08 +05308634#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
8635static int wlan_hdd_cfg80211_set_default_key( struct wiphy *wiphy,
8636 struct net_device *ndev,
8637 u8 key_index,
8638 bool unicast, bool multicast)
8639#else
8640static int wlan_hdd_cfg80211_set_default_key( struct wiphy *wiphy,
8641 struct net_device *ndev,
8642 u8 key_index)
8643#endif
8644{
8645 int ret;
8646 vos_ssr_protect(__func__);
8647#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
8648 ret = __wlan_hdd_cfg80211_set_default_key(wiphy, ndev, key_index, unicast,
8649 multicast);
8650#else
8651 ret = __wlan_hdd_cfg80211_set_default_key(wiphy, ndev, key_index);
8652#endif
8653 vos_ssr_unprotect(__func__);
8654
8655 return ret;
8656}
8657
Jeff Johnson295189b2012-06-20 16:38:30 -07008658/*
8659 * FUNCTION: wlan_hdd_cfg80211_inform_bss
8660 * This function is used to inform the BSS details to nl80211 interface.
8661 */
8662static struct cfg80211_bss* wlan_hdd_cfg80211_inform_bss(
8663 hdd_adapter_t *pAdapter, tCsrRoamConnectedProfile *roamProfile)
8664{
8665 struct net_device *dev = pAdapter->dev;
8666 struct wireless_dev *wdev = dev->ieee80211_ptr;
8667 struct wiphy *wiphy = wdev->wiphy;
8668 tSirBssDescription *pBssDesc = roamProfile->pBssDesc;
8669 int chan_no;
8670 int ie_length;
8671 const char *ie;
8672 unsigned int freq;
8673 struct ieee80211_channel *chan;
8674 int rssi = 0;
8675 struct cfg80211_bss *bss = NULL;
8676
8677 ENTER();
8678
8679 if( NULL == pBssDesc )
8680 {
Arif Hussain6d2a3322013-11-17 19:50:10 -08008681 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: pBssDesc is NULL", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07008682 return bss;
8683 }
8684
8685 chan_no = pBssDesc->channelId;
8686 ie_length = GET_IE_LEN_IN_BSS_DESC( pBssDesc->length );
8687 ie = ((ie_length != 0) ? (const char *)&pBssDesc->ieFields: NULL);
8688
8689 if( NULL == ie )
8690 {
Arif Hussain6d2a3322013-11-17 19:50:10 -08008691 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: IE of BSS descriptor is NULL", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07008692 return bss;
8693 }
8694
8695#if (LINUX_VERSION_CODE > KERNEL_VERSION(2,6,38))
8696 if (chan_no <= ARRAY_SIZE(hdd_channels_2_4_GHZ))
8697 {
8698 freq = ieee80211_channel_to_frequency(chan_no, IEEE80211_BAND_2GHZ);
8699 }
8700 else
8701 {
8702 freq = ieee80211_channel_to_frequency(chan_no, IEEE80211_BAND_5GHZ);
8703 }
8704#else
8705 freq = ieee80211_channel_to_frequency(chan_no);
8706#endif
8707
8708 chan = __ieee80211_get_channel(wiphy, freq);
8709
Santhosh Kumar Padmaa45fdb12014-04-15 15:54:38 +05308710 if (!chan) {
8711 hddLog(VOS_TRACE_LEVEL_ERROR, "%s chan pointer is NULL", __func__);
8712 return NULL;
8713 }
8714
Abhishek Singhaee43942014-06-16 18:55:47 +05308715 rssi = (VOS_MIN ((pBssDesc->rssi + pBssDesc->sinr), 0))*100;
Jeff Johnson295189b2012-06-20 16:38:30 -07008716
Abhishek Singhaee43942014-06-16 18:55:47 +05308717 return cfg80211_inform_bss(wiphy, chan, pBssDesc->bssId,
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308718 le64_to_cpu(*(__le64 *)pBssDesc->timeStamp),
Jeff Johnson295189b2012-06-20 16:38:30 -07008719 pBssDesc->capabilityInfo,
8720 pBssDesc->beaconInterval, ie, ie_length,
Abhishek Singhaee43942014-06-16 18:55:47 +05308721 rssi, GFP_KERNEL );
Jeff Johnson295189b2012-06-20 16:38:30 -07008722}
8723
8724
8725
8726/*
8727 * FUNCTION: wlan_hdd_cfg80211_inform_bss_frame
8728 * This function is used to inform the BSS details to nl80211 interface.
8729 */
8730struct cfg80211_bss*
8731wlan_hdd_cfg80211_inform_bss_frame( hdd_adapter_t *pAdapter,
8732 tSirBssDescription *bss_desc
8733 )
8734{
8735 /*
8736 cfg80211_inform_bss() is not updating ie field of bss entry, if entry
8737 already exists in bss data base of cfg80211 for that particular BSS ID.
8738 Using cfg80211_inform_bss_frame to update the bss entry instead of
8739 cfg80211_inform_bss, But this call expects mgmt packet as input. As of
8740 now there is no possibility to get the mgmt(probe response) frame from PE,
8741 converting bss_desc to ieee80211_mgmt(probe response) and passing to
8742 cfg80211_inform_bss_frame.
8743 */
8744 struct net_device *dev = pAdapter->dev;
8745 struct wireless_dev *wdev = dev->ieee80211_ptr;
8746 struct wiphy *wiphy = wdev->wiphy;
8747 int chan_no = bss_desc->channelId;
Madan Mohan Koyyalamudi86f629e2012-11-09 16:27:29 -08008748#ifdef WLAN_ENABLE_AGEIE_ON_SCAN_RESULTS
8749 qcom_ie_age *qie_age = NULL;
8750 int ie_length = GET_IE_LEN_IN_BSS_DESC( bss_desc->length ) + sizeof(qcom_ie_age);
8751#else
Jeff Johnson295189b2012-06-20 16:38:30 -07008752 int ie_length = GET_IE_LEN_IN_BSS_DESC( bss_desc->length );
Madan Mohan Koyyalamudi86f629e2012-11-09 16:27:29 -08008753#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07008754 const char *ie =
8755 ((ie_length != 0) ? (const char *)&bss_desc->ieFields: NULL);
8756 unsigned int freq;
8757 struct ieee80211_channel *chan;
Abhishek Singh1e2bfa32014-01-02 15:44:15 +05308758 struct ieee80211_mgmt *mgmt = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -07008759 struct cfg80211_bss *bss_status = NULL;
8760 size_t frame_len = sizeof (struct ieee80211_mgmt) + ie_length;
8761 int rssi = 0;
Wilson Yangf80a0542013-10-07 13:02:37 -07008762 hdd_context_t *pHddCtx;
8763 int status;
Jeff Johnsone7245742012-09-05 17:12:55 -07008764#ifdef WLAN_OPEN_SOURCE
8765 struct timespec ts;
8766#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07008767
Wilson Yangf80a0542013-10-07 13:02:37 -07008768 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
8769 status = wlan_hdd_validate_context(pHddCtx);
8770
8771 /*bss_update is not allowed during wlan driver loading or unloading*/
Mihir Shete18156292014-03-11 15:38:30 +05308772 if (WLAN_HDD_IS_LOAD_UNLOAD_IN_PROGRESS(pHddCtx))
Wilson Yangf80a0542013-10-07 13:02:37 -07008773 {
8774 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
8775 "%s:Loading_unloading in Progress. Ignore!!!",__func__);
8776 return NULL;
8777 }
8778
8779
8780 if (0 != status)
8781 {
8782 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
8783 "%s: HDD context is not valid", __func__);
Madan Mohan Koyyalamudi2e5c9142012-11-02 13:17:48 -07008784 return NULL;
Wilson Yangf80a0542013-10-07 13:02:37 -07008785 }
8786
Abhishek Singh1e2bfa32014-01-02 15:44:15 +05308787 mgmt = kzalloc((sizeof (struct ieee80211_mgmt) + ie_length), GFP_KERNEL);
Wilson Yangf80a0542013-10-07 13:02:37 -07008788 if (!mgmt)
8789 {
8790 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
8791 "%s: memory allocation failed ", __func__);
8792 return NULL;
8793 }
Madan Mohan Koyyalamudi2e5c9142012-11-02 13:17:48 -07008794
Jeff Johnson295189b2012-06-20 16:38:30 -07008795 memcpy(mgmt->bssid, bss_desc->bssId, ETH_ALEN);
Jeff Johnsone7245742012-09-05 17:12:55 -07008796
8797#ifdef WLAN_OPEN_SOURCE
8798 /* Android does not want the timestamp from the frame.
8799 Instead it wants a monotonic increasing value */
8800 get_monotonic_boottime(&ts);
8801 mgmt->u.probe_resp.timestamp =
8802 ((u64)ts.tv_sec * 1000000) + (ts.tv_nsec / 1000);
8803#else
8804 /* keep old behavior for non-open source (for now) */
Jeff Johnson295189b2012-06-20 16:38:30 -07008805 memcpy(&mgmt->u.probe_resp.timestamp, bss_desc->timeStamp,
8806 sizeof (bss_desc->timeStamp));
Jeff Johnsone7245742012-09-05 17:12:55 -07008807
8808#endif
8809
Jeff Johnson295189b2012-06-20 16:38:30 -07008810 mgmt->u.probe_resp.beacon_int = bss_desc->beaconInterval;
8811 mgmt->u.probe_resp.capab_info = bss_desc->capabilityInfo;
Madan Mohan Koyyalamudi86f629e2012-11-09 16:27:29 -08008812
8813#ifdef WLAN_ENABLE_AGEIE_ON_SCAN_RESULTS
8814 /* GPS Requirement: need age ie per entry. Using vendor specific. */
8815 /* Assuming this is the last IE, copy at the end */
8816 ie_length -=sizeof(qcom_ie_age);
8817 qie_age = (qcom_ie_age *)(mgmt->u.probe_resp.variable + ie_length);
8818 qie_age->element_id = QCOM_VENDOR_IE_ID;
8819 qie_age->len = QCOM_VENDOR_IE_AGE_LEN;
8820 qie_age->oui_1 = QCOM_OUI1;
8821 qie_age->oui_2 = QCOM_OUI2;
8822 qie_age->oui_3 = QCOM_OUI3;
8823 qie_age->type = QCOM_VENDOR_IE_AGE_TYPE;
8824 qie_age->age = vos_timer_get_system_ticks() - bss_desc->nReceivedTime;
8825#endif
8826
Jeff Johnson295189b2012-06-20 16:38:30 -07008827 memcpy(mgmt->u.probe_resp.variable, ie, ie_length);
Gopichand Nakkalad908ec82013-05-16 19:32:19 +05308828 if (bss_desc->fProbeRsp)
8829 {
8830 mgmt->frame_control |=
8831 (u16)(IEEE80211_FTYPE_MGMT | IEEE80211_STYPE_PROBE_RESP);
8832 }
8833 else
8834 {
8835 mgmt->frame_control |=
8836 (u16)(IEEE80211_FTYPE_MGMT | IEEE80211_STYPE_BEACON);
8837 }
Jeff Johnson295189b2012-06-20 16:38:30 -07008838
8839#if (LINUX_VERSION_CODE > KERNEL_VERSION(2,6,38))
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308840 if (chan_no <= ARRAY_SIZE(hdd_channels_2_4_GHZ) &&
Jeff Johnson295189b2012-06-20 16:38:30 -07008841 (wiphy->bands[IEEE80211_BAND_2GHZ] != NULL))
8842 {
8843 freq = ieee80211_channel_to_frequency(chan_no, IEEE80211_BAND_2GHZ);
8844 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308845 else if ((chan_no > ARRAY_SIZE(hdd_channels_2_4_GHZ)) &&
Jeff Johnson295189b2012-06-20 16:38:30 -07008846 (wiphy->bands[IEEE80211_BAND_5GHZ] != NULL))
8847
8848 {
8849 freq = ieee80211_channel_to_frequency(chan_no, IEEE80211_BAND_5GHZ);
8850 }
8851 else
8852 {
Nirav Shah20ac06f2013-12-12 18:14:06 +05308853 hddLog(VOS_TRACE_LEVEL_ERROR, "%s Invalid chan_no:%d",
8854 __func__, chan_no);
Jeff Johnson295189b2012-06-20 16:38:30 -07008855 kfree(mgmt);
8856 return NULL;
8857 }
8858#else
8859 freq = ieee80211_channel_to_frequency(chan_no);
8860#endif
8861 chan = __ieee80211_get_channel(wiphy, freq);
Leela V Kiran Kumar Reddy90032de2013-01-24 18:33:30 -08008862 /*when the band is changed on the fly using the GUI, three things are done
8863 * 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)
8864 * as part of the scan abort, message willbe queued to PE and we proceed with flushing and changinh the band.
8865 * pe will stop the scanning further and report back the results what ever it had till now by calling the call back function.
8866 * if the time between update band and scandone call back is sufficent enough the band change reflects in SME, SME validates the channels
8867 * and discards the channels correponding to previous band and calls back with zero bss results.
8868 * 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
8869 * all the channels correponding to previous band.this is due to race condition.but those channels are invalid to the new band and so
8870 * this function __ieee80211_get_channel will return NULL.Each time we report scan result with this pointer null warning kernel trace is printed.
8871 * if the scan results contain large number of APs continuosly kernel warning trace is printed and it will lead to apps watch dog bark.
8872 * So drop the bss and continue to next bss.
8873 */
8874 if(chan == NULL)
8875 {
Nirav Shah20ac06f2013-12-12 18:14:06 +05308876 hddLog(VOS_TRACE_LEVEL_ERROR, "%s chan pointer is NULL", __func__);
Chilam Ngc4244af2013-04-01 15:37:32 -07008877 kfree(mgmt);
Leela V Kiran Kumar Reddy90032de2013-01-24 18:33:30 -08008878 return NULL;
8879 }
Jeff Johnson295189b2012-06-20 16:38:30 -07008880 /*To keep the rssi icon of the connected AP in the scan window
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308881 *and the rssi icon of the wireless networks in sync
Jeff Johnson295189b2012-06-20 16:38:30 -07008882 * */
8883 if (( eConnectionState_Associated ==
8884 pAdapter->sessionCtx.station.conn_info.connState ) &&
8885 ( VOS_TRUE == vos_mem_compare(bss_desc->bssId,
8886 pAdapter->sessionCtx.station.conn_info.bssId,
8887 WNI_CFG_BSSID_LEN)))
8888 {
8889 /* supplicant takes the signal strength in terms of mBm(100*dBm) */
8890 rssi = (pAdapter->rssi * 100);
8891 }
8892 else
8893 {
8894 rssi = (VOS_MIN ((bss_desc->rssi + bss_desc->sinr), 0))*100;
8895 }
8896
Nirav Shah20ac06f2013-12-12 18:14:06 +05308897 hddLog(VOS_TRACE_LEVEL_INFO, "%s: BSSID:" MAC_ADDRESS_STR " Channel:%d"
8898 "RSSI:%d", __func__, MAC_ADDR_ARRAY(mgmt->bssid),
8899 chan->center_freq, (int)(rssi/100));
8900
Jeff Johnson295189b2012-06-20 16:38:30 -07008901 bss_status = cfg80211_inform_bss_frame(wiphy, chan, mgmt,
8902 frame_len, rssi, GFP_KERNEL);
8903 kfree(mgmt);
8904 return bss_status;
8905}
8906
8907/*
8908 * FUNCTION: wlan_hdd_cfg80211_update_bss_db
8909 * This function is used to update the BSS data base of CFG8011
8910 */
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308911struct cfg80211_bss* wlan_hdd_cfg80211_update_bss_db( hdd_adapter_t *pAdapter,
Jeff Johnson295189b2012-06-20 16:38:30 -07008912 tCsrRoamInfo *pRoamInfo
8913 )
8914{
8915 tCsrRoamConnectedProfile roamProfile;
8916 tHalHandle hHal = WLAN_HDD_GET_HAL_CTX(pAdapter);
8917 struct cfg80211_bss *bss = NULL;
8918
8919 ENTER();
8920
8921 memset(&roamProfile, 0, sizeof(tCsrRoamConnectedProfile));
8922 sme_RoamGetConnectProfile(hHal, pAdapter->sessionId, &roamProfile);
8923
8924 if (NULL != roamProfile.pBssDesc)
8925 {
Girish Gowlif4b68022014-08-28 23:18:57 +05308926 bss = wlan_hdd_cfg80211_inform_bss_frame(pAdapter,
8927 roamProfile.pBssDesc);
Jeff Johnson295189b2012-06-20 16:38:30 -07008928
8929 if (NULL == bss)
8930 {
8931 hddLog(VOS_TRACE_LEVEL_INFO, "%s: cfg80211_inform_bss return NULL",
8932 __func__);
8933 }
8934
8935 sme_RoamFreeConnectProfile(hHal, &roamProfile);
8936 }
8937 else
8938 {
8939 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: roamProfile.pBssDesc is NULL",
8940 __func__);
8941 }
8942 return bss;
8943}
8944
8945/*
8946 * FUNCTION: wlan_hdd_cfg80211_update_bss
8947 */
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308948static int wlan_hdd_cfg80211_update_bss( struct wiphy *wiphy,
8949 hdd_adapter_t *pAdapter
Jeff Johnson295189b2012-06-20 16:38:30 -07008950 )
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308951{
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +05308952 tHalHandle hHal = WLAN_HDD_GET_HAL_CTX(pAdapter);
Jeff Johnson295189b2012-06-20 16:38:30 -07008953 tCsrScanResultInfo *pScanResult;
8954 eHalStatus status = 0;
8955 tScanResultHandle pResult;
8956 struct cfg80211_bss *bss_status = NULL;
Wilson Yangf80a0542013-10-07 13:02:37 -07008957 hdd_context_t *pHddCtx;
Jeff Johnson295189b2012-06-20 16:38:30 -07008958
8959 ENTER();
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +05308960
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05308961 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
8962 TRACE_CODE_HDD_CFG80211_UPDATE_BSS,
8963 NO_SESSION, pAdapter->sessionId));
8964
Wilson Yangf80a0542013-10-07 13:02:37 -07008965 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
8966
8967 if (pHddCtx->isLogpInProgress)
Jeff Johnson295189b2012-06-20 16:38:30 -07008968 {
Wilson Yangf80a0542013-10-07 13:02:37 -07008969 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
8970 "%s:LOGP in Progress. Ignore!!!",__func__);
8971 return -EAGAIN;
Jeff Johnson295189b2012-06-20 16:38:30 -07008972 }
8973
Wilson Yangf80a0542013-10-07 13:02:37 -07008974
8975 /*bss_update is not allowed during wlan driver loading or unloading*/
Mihir Shete18156292014-03-11 15:38:30 +05308976 if (WLAN_HDD_IS_LOAD_UNLOAD_IN_PROGRESS(pHddCtx))
Wilson Yangf80a0542013-10-07 13:02:37 -07008977 {
8978 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
8979 "%s:Loading_unloading in Progress. Ignore!!!",__func__);
8980 return VOS_STATUS_E_PERM;
8981 }
8982
8983
Jeff Johnson295189b2012-06-20 16:38:30 -07008984 /*
8985 * start getting scan results and populate cgf80211 BSS database
8986 */
8987 status = sme_ScanGetResult(hHal, pAdapter->sessionId, NULL, &pResult);
8988
8989 /* no scan results */
8990 if (NULL == pResult)
8991 {
Nirav Shah20ac06f2013-12-12 18:14:06 +05308992 hddLog(VOS_TRACE_LEVEL_INFO, "%s: No scan result Status %d",
8993 __func__, status);
Jeff Johnson295189b2012-06-20 16:38:30 -07008994 return status;
8995 }
8996
8997 pScanResult = sme_ScanResultGetFirst(hHal, pResult);
8998
8999 while (pScanResult)
9000 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309001 /*
9002 * cfg80211_inform_bss() is not updating ie field of bss entry, if
9003 * entry already exists in bss data base of cfg80211 for that
9004 * particular BSS ID. Using cfg80211_inform_bss_frame to update the
9005 * bss entry instead of cfg80211_inform_bss, But this call expects
9006 * mgmt packet as input. As of now there is no possibility to get
9007 * the mgmt(probe response) frame from PE, converting bss_desc to
Jeff Johnson295189b2012-06-20 16:38:30 -07009008 * ieee80211_mgmt(probe response) and passing to c
9009 * fg80211_inform_bss_frame.
9010 * */
9011
9012 bss_status = wlan_hdd_cfg80211_inform_bss_frame(pAdapter,
9013 &pScanResult->BssDescriptor);
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309014
Jeff Johnson295189b2012-06-20 16:38:30 -07009015
9016 if (NULL == bss_status)
9017 {
9018 hddLog(VOS_TRACE_LEVEL_INFO,
Arif Hussain6d2a3322013-11-17 19:50:10 -08009019 "%s: NULL returned by cfg80211_inform_bss", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07009020 }
9021 else
9022 {
Yue Maf49ba872013-08-19 12:04:25 -07009023 cfg80211_put_bss(
9024#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,9,0))
9025 wiphy,
9026#endif
9027 bss_status);
Jeff Johnson295189b2012-06-20 16:38:30 -07009028 }
9029
9030 pScanResult = sme_ScanResultGetNext(hHal, pResult);
9031 }
9032
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309033 sme_ScanResultPurge(hHal, pResult);
Jeff Johnson295189b2012-06-20 16:38:30 -07009034
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309035 return 0;
Jeff Johnson295189b2012-06-20 16:38:30 -07009036}
9037
Jeff Johnson04dd8a82012-06-29 20:41:40 -07009038void
9039hddPrintMacAddr(tCsrBssid macAddr, tANI_U8 logLevel)
9040{
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309041 VOS_TRACE(VOS_MODULE_ID_HDD, logLevel,
Arif Hussaina7c8e412013-11-20 11:06:42 -08009042 MAC_ADDRESS_STR, MAC_ADDR_ARRAY(macAddr));
Jeff Johnson04dd8a82012-06-29 20:41:40 -07009043} /****** end hddPrintMacAddr() ******/
9044
9045void
Madan Mohan Koyyalamudic75be962012-10-18 19:19:03 -07009046hddPrintPmkId(tANI_U8 *pmkId, tANI_U8 logLevel)
Jeff Johnson04dd8a82012-06-29 20:41:40 -07009047{
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309048 VOS_TRACE(VOS_MODULE_ID_HDD, logLevel,
Arif Hussain6d2a3322013-11-17 19:50:10 -08009049 "%02X:%02X:%02X:%02X:%02X:%02X:%02X:%02X:%02X:%02X:%02X:%02X:%02X:%02X:%02X:%02X",
Madan Mohan Koyyalamudic75be962012-10-18 19:19:03 -07009050 pmkId[0], pmkId[1], pmkId[2], pmkId[3], pmkId[4],
9051 pmkId[5], pmkId[6], pmkId[7], pmkId[8], pmkId[9], pmkId[10],
9052 pmkId[11], pmkId[12], pmkId[13], pmkId[14], pmkId[15]);
Jeff Johnson04dd8a82012-06-29 20:41:40 -07009053} /****** end hddPrintPmkId() ******/
9054
9055//hddPrintMacAddr(tCsrBssid macAddr, tANI_U8 logLevel);
9056//hddPrintMacAddr(macAddr, VOS_TRACE_LEVEL_FATAL);
9057
9058//void sirDumpBuf(tpAniSirGlobal pMac, tANI_U8 modId, tANI_U32 level, tANI_U8 *buf, tANI_U32 size);
9059//sirDumpBuf(pMac, VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL, pmkid, 16);
9060
9061#define dump_bssid(bssid) \
9062 { \
Jeff Johnsone7245742012-09-05 17:12:55 -07009063 hddLog(VOS_TRACE_LEVEL_INFO, "BSSID (MAC) address:\t"); \
9064 hddPrintMacAddr(bssid, VOS_TRACE_LEVEL_INFO);\
Jeff Johnson04dd8a82012-06-29 20:41:40 -07009065 }
9066
9067#define dump_pmkid(pMac, pmkid) \
9068 { \
Jeff Johnsone7245742012-09-05 17:12:55 -07009069 hddLog(VOS_TRACE_LEVEL_INFO, "PMKSA-ID:\t"); \
9070 hddPrintPmkId(pmkid, VOS_TRACE_LEVEL_INFO);\
Jeff Johnson04dd8a82012-06-29 20:41:40 -07009071 }
9072
Madan Mohan Koyyalamudi1b4afb02012-10-22 15:25:16 -07009073#if defined(FEATURE_WLAN_LFR) && (LINUX_VERSION_CODE >= KERNEL_VERSION(3,4,0))
Jeff Johnson04dd8a82012-06-29 20:41:40 -07009074/*
9075 * FUNCTION: wlan_hdd_cfg80211_pmksa_candidate_notify
9076 * This function is used to notify the supplicant of a new PMKSA candidate.
9077 */
9078int wlan_hdd_cfg80211_pmksa_candidate_notify(
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309079 hdd_adapter_t *pAdapter, tCsrRoamInfo *pRoamInfo,
Jeff Johnson04dd8a82012-06-29 20:41:40 -07009080 int index, bool preauth )
9081{
Jeff Johnsone7245742012-09-05 17:12:55 -07009082#ifdef FEATURE_WLAN_OKC
Jeff Johnson04dd8a82012-06-29 20:41:40 -07009083 struct net_device *dev = pAdapter->dev;
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07009084 hdd_context_t *pHddCtx = (hdd_context_t*)pAdapter->pHddCtx;
Jeff Johnson04dd8a82012-06-29 20:41:40 -07009085
9086 ENTER();
Jeff Johnsone7245742012-09-05 17:12:55 -07009087 hddLog(VOS_TRACE_LEVEL_INFO, "%s is going to notify supplicant of:", __func__);
Jeff Johnson04dd8a82012-06-29 20:41:40 -07009088
9089 if( NULL == pRoamInfo )
9090 {
Arif Hussain6d2a3322013-11-17 19:50:10 -08009091 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: pRoamInfo is NULL", __func__);
Jeff Johnson04dd8a82012-06-29 20:41:40 -07009092 return -EINVAL;
9093 }
9094
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07009095 if (eANI_BOOLEAN_TRUE == hdd_is_okc_mode_enabled(pHddCtx))
9096 {
9097 dump_bssid(pRoamInfo->bssid);
9098 cfg80211_pmksa_candidate_notify(dev, index,
Jeff Johnson04dd8a82012-06-29 20:41:40 -07009099 pRoamInfo->bssid, preauth, GFP_KERNEL);
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07009100 }
Jeff Johnsone7245742012-09-05 17:12:55 -07009101#endif /* FEATURE_WLAN_OKC */
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309102 return 0;
Jeff Johnson04dd8a82012-06-29 20:41:40 -07009103}
9104#endif //FEATURE_WLAN_LFR
9105
Yue Maef608272013-04-08 23:09:17 -07009106#ifdef FEATURE_WLAN_LFR_METRICS
9107/*
9108 * FUNCTION: wlan_hdd_cfg80211_roam_metrics_preauth
9109 * 802.11r/LFR metrics reporting function to report preauth initiation
9110 *
9111 */
9112#define MAX_LFR_METRICS_EVENT_LENGTH 100
9113VOS_STATUS wlan_hdd_cfg80211_roam_metrics_preauth(hdd_adapter_t *pAdapter,
9114 tCsrRoamInfo *pRoamInfo)
9115{
9116 unsigned char metrics_notification[MAX_LFR_METRICS_EVENT_LENGTH + 1];
9117 union iwreq_data wrqu;
9118
9119 ENTER();
9120
9121 if (NULL == pAdapter)
9122 {
9123 hddLog(LOGE, "%s: pAdapter is NULL!", __func__);
9124 return VOS_STATUS_E_FAILURE;
9125 }
9126
9127 /* create the event */
9128 memset(&wrqu, 0, sizeof(wrqu));
9129 memset(metrics_notification, 0, sizeof(metrics_notification));
9130
9131 wrqu.data.pointer = metrics_notification;
9132 wrqu.data.length = scnprintf(metrics_notification,
9133 sizeof(metrics_notification), "QCOM: LFR_PREAUTH_INIT "
9134 MAC_ADDRESS_STR, MAC_ADDR_ARRAY(pRoamInfo->bssid));
9135
9136 wireless_send_event(pAdapter->dev, IWEVCUSTOM, &wrqu, metrics_notification);
9137
9138 EXIT();
9139
9140 return VOS_STATUS_SUCCESS;
9141}
9142
9143/*
9144 * FUNCTION: wlan_hdd_cfg80211_roam_metrics_preauth_status
9145 * 802.11r/LFR metrics reporting function to report preauth completion
9146 * or failure
9147 */
9148VOS_STATUS wlan_hdd_cfg80211_roam_metrics_preauth_status(
9149 hdd_adapter_t *pAdapter, tCsrRoamInfo *pRoamInfo, bool preauth_status)
9150{
9151 unsigned char metrics_notification[MAX_LFR_METRICS_EVENT_LENGTH + 1];
9152 union iwreq_data wrqu;
9153
9154 ENTER();
9155
9156 if (NULL == pAdapter)
9157 {
9158 hddLog(LOGE, "%s: pAdapter is NULL!", __func__);
9159 return VOS_STATUS_E_FAILURE;
9160 }
9161
9162 /* create the event */
9163 memset(&wrqu, 0, sizeof(wrqu));
9164 memset(metrics_notification, 0, sizeof(metrics_notification));
9165
9166 scnprintf(metrics_notification, sizeof(metrics_notification),
9167 "QCOM: LFR_PREAUTH_STATUS "MAC_ADDRESS_STR,
9168 MAC_ADDR_ARRAY(pRoamInfo->bssid));
9169
9170 if (1 == preauth_status)
9171 strncat(metrics_notification, " TRUE", 5);
9172 else
9173 strncat(metrics_notification, " FALSE", 6);
9174
9175 wrqu.data.pointer = metrics_notification;
9176 wrqu.data.length = strlen(metrics_notification);
9177
9178 wireless_send_event(pAdapter->dev, IWEVCUSTOM, &wrqu, metrics_notification);
9179
9180 EXIT();
9181
9182 return VOS_STATUS_SUCCESS;
9183}
9184
9185/*
9186 * FUNCTION: wlan_hdd_cfg80211_roam_metrics_handover
9187 * 802.11r/LFR metrics reporting function to report handover initiation
9188 *
9189 */
9190VOS_STATUS wlan_hdd_cfg80211_roam_metrics_handover(hdd_adapter_t * pAdapter,
9191 tCsrRoamInfo *pRoamInfo)
9192{
9193 unsigned char metrics_notification[MAX_LFR_METRICS_EVENT_LENGTH + 1];
9194 union iwreq_data wrqu;
9195
9196 ENTER();
9197
9198 if (NULL == pAdapter)
9199 {
9200 hddLog(LOGE, "%s: pAdapter is NULL!", __func__);
9201 return VOS_STATUS_E_FAILURE;
9202 }
9203
9204 /* create the event */
9205 memset(&wrqu, 0, sizeof(wrqu));
9206 memset(metrics_notification, 0, sizeof(metrics_notification));
9207
9208 wrqu.data.pointer = metrics_notification;
9209 wrqu.data.length = scnprintf(metrics_notification,
9210 sizeof(metrics_notification), "QCOM: LFR_PREAUTH_HANDOVER "
9211 MAC_ADDRESS_STR, MAC_ADDR_ARRAY(pRoamInfo->bssid));
9212
9213 wireless_send_event(pAdapter->dev, IWEVCUSTOM, &wrqu, metrics_notification);
9214
9215 EXIT();
9216
9217 return VOS_STATUS_SUCCESS;
9218}
9219#endif
9220
Jeff Johnson295189b2012-06-20 16:38:30 -07009221/*
9222 * FUNCTION: hdd_cfg80211_scan_done_callback
9223 * scanning callback function, called after finishing scan
9224 *
9225 */
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309226static eHalStatus hdd_cfg80211_scan_done_callback(tHalHandle halHandle,
Jeff Johnson295189b2012-06-20 16:38:30 -07009227 void *pContext, tANI_U32 scanId, eCsrScanStatus status)
9228{
9229 struct net_device *dev = (struct net_device *) pContext;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309230 //struct wireless_dev *wdev = dev->ieee80211_ptr;
Jeff Johnson295189b2012-06-20 16:38:30 -07009231 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( dev );
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -07009232 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
9233 hdd_scaninfo_t *pScanInfo = &pHddCtx->scan_info;
Jeff Johnson295189b2012-06-20 16:38:30 -07009234 struct cfg80211_scan_request *req = NULL;
9235 int ret = 0;
Mahesh A Saptasagar05a357e2014-02-26 16:28:06 +05309236 bool aborted = false;
c_hpothu6ff1c3c2013-10-01 19:01:57 +05309237 long waitRet = 0;
Jeff Johnson295189b2012-06-20 16:38:30 -07009238
9239 ENTER();
9240
9241 hddLog(VOS_TRACE_LEVEL_INFO,
9242 "%s called with halHandle = %p, pContext = %p,"
Arif Hussain6d2a3322013-11-17 19:50:10 -08009243 "scanID = %d, returned status = %d",
Jeff Johnson295189b2012-06-20 16:38:30 -07009244 __func__, halHandle, pContext, (int) scanId, (int) status);
9245
Kiet Lamac06e2c2013-10-23 16:25:07 +05309246 pScanInfo->mScanPendingCounter = 0;
9247
Jeff Johnson295189b2012-06-20 16:38:30 -07009248 //Block on scan req completion variable. Can't wait forever though.
c_hpothu6ff1c3c2013-10-01 19:01:57 +05309249 waitRet = wait_for_completion_interruptible_timeout(
Jeff Johnson295189b2012-06-20 16:38:30 -07009250 &pScanInfo->scan_req_completion_event,
9251 msecs_to_jiffies(WLAN_WAIT_TIME_SCAN_REQ));
c_hpothu6ff1c3c2013-10-01 19:01:57 +05309252 if (waitRet <= 0)
Jeff Johnson295189b2012-06-20 16:38:30 -07009253 {
c_hpothu6ff1c3c2013-10-01 19:01:57 +05309254 hddLog(VOS_TRACE_LEVEL_ERROR,
9255 "%s wait on scan_req_completion_event failed %ld",__func__, waitRet);
Jeff Johnson295189b2012-06-20 16:38:30 -07009256 VOS_ASSERT(pScanInfo->mScanPending);
Jeff Johnsone7245742012-09-05 17:12:55 -07009257 goto allow_suspend;
Jeff Johnson295189b2012-06-20 16:38:30 -07009258 }
9259
Yue Maef608272013-04-08 23:09:17 -07009260 if (pScanInfo->mScanPending != VOS_TRUE)
Jeff Johnson295189b2012-06-20 16:38:30 -07009261 {
9262 VOS_ASSERT(pScanInfo->mScanPending);
Jeff Johnsone7245742012-09-05 17:12:55 -07009263 goto allow_suspend;
Jeff Johnson295189b2012-06-20 16:38:30 -07009264 }
9265
9266 /* Check the scanId */
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309267 if (pScanInfo->scanId != scanId)
Jeff Johnson295189b2012-06-20 16:38:30 -07009268 {
9269 hddLog(VOS_TRACE_LEVEL_INFO,
9270 "%s called with mismatched scanId pScanInfo->scanId = %d "
Arif Hussain6d2a3322013-11-17 19:50:10 -08009271 "scanId = %d", __func__, (int) pScanInfo->scanId,
Jeff Johnson295189b2012-06-20 16:38:30 -07009272 (int) scanId);
9273 }
9274
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309275 ret = wlan_hdd_cfg80211_update_bss((WLAN_HDD_GET_CTX(pAdapter))->wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -07009276 pAdapter);
9277
9278 if (0 > ret)
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309279 hddLog(VOS_TRACE_LEVEL_INFO, "%s: NO SCAN result", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07009280
9281
9282 /* If any client wait scan result through WEXT
9283 * send scan done event to client */
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -07009284 if (pHddCtx->scan_info.waitScanResult)
Jeff Johnson295189b2012-06-20 16:38:30 -07009285 {
9286 /* The other scan request waiting for current scan finish
9287 * Send event to notify current scan finished */
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -07009288 if(WEXT_SCAN_PENDING_DELAY == pHddCtx->scan_info.scan_pending_option)
Jeff Johnson295189b2012-06-20 16:38:30 -07009289 {
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -07009290 vos_event_set(&pHddCtx->scan_info.scan_finished_event);
Jeff Johnson295189b2012-06-20 16:38:30 -07009291 }
9292 /* Send notify to WEXT client */
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -07009293 else if(WEXT_SCAN_PENDING_PIGGYBACK == pHddCtx->scan_info.scan_pending_option)
Jeff Johnson295189b2012-06-20 16:38:30 -07009294 {
9295 struct net_device *dev = pAdapter->dev;
9296 union iwreq_data wrqu;
9297 int we_event;
9298 char *msg;
9299
9300 memset(&wrqu, '\0', sizeof(wrqu));
9301 we_event = SIOCGIWSCAN;
9302 msg = NULL;
9303 wireless_send_event(dev, we_event, &wrqu, msg);
9304 }
9305 }
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -07009306 pHddCtx->scan_info.waitScanResult = FALSE;
Jeff Johnson295189b2012-06-20 16:38:30 -07009307
9308 /* Get the Scan Req */
9309 req = pAdapter->request;
9310
9311 if (!req)
9312 {
Arif Hussain6d2a3322013-11-17 19:50:10 -08009313 hddLog(VOS_TRACE_LEVEL_ERROR, "request is became NULL");
Madan Mohan Koyyalamudi9f5a10c2012-09-28 14:46:16 -07009314 pScanInfo->mScanPending = VOS_FALSE;
Jeff Johnsone7245742012-09-05 17:12:55 -07009315 goto allow_suspend;
Jeff Johnson295189b2012-06-20 16:38:30 -07009316 }
9317
9318 /*
9319 * setting up 0, just in case.
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309320 */
Jeff Johnson295189b2012-06-20 16:38:30 -07009321 req->n_ssids = 0;
9322 req->n_channels = 0;
9323 req->ie = 0;
9324
Jeff Johnson295189b2012-06-20 16:38:30 -07009325 pAdapter->request = NULL;
Jeff Johnsone7245742012-09-05 17:12:55 -07009326 /* Scan is no longer pending */
9327 pScanInfo->mScanPending = VOS_FALSE;
Jeff Johnson295189b2012-06-20 16:38:30 -07009328
Madan Mohan Koyyalamudib764bf82012-10-11 16:38:51 -07009329 /*
9330 * cfg80211_scan_done informing NL80211 about completion
9331 * of scanning
9332 */
Mahesh A Saptasagar05a357e2014-02-26 16:28:06 +05309333 if (status == eCSR_SCAN_ABORT || status == eCSR_SCAN_FAILURE)
9334 {
9335 aborted = true;
9336 }
9337 cfg80211_scan_done(req, aborted);
Madan Mohan Koyyalamudif4e81002012-11-13 10:46:38 -08009338 complete(&pScanInfo->abortscan_event_var);
Jeff Johnson295189b2012-06-20 16:38:30 -07009339
Siddharth Bhal76972212014-10-15 16:22:51 +05309340 if (pHddCtx->spoofMacAddr.isEnabled || pHddCtx->spoofMacAddr.isReqDeferred) {
9341 /* Generate new random mac addr for next scan */
9342 hddLog(VOS_TRACE_LEVEL_INFO, "scan completed - generate new spoof mac addr");
9343 hdd_processSpoofMacAddrRequest(pHddCtx);
9344 }
9345
Jeff Johnsone7245742012-09-05 17:12:55 -07009346allow_suspend:
Madan Mohan Koyyalamudi9f5a10c2012-09-28 14:46:16 -07009347 /* release the wake lock at the end of the scan*/
9348 hdd_allow_suspend();
Jeff Johnsone7245742012-09-05 17:12:55 -07009349
Madan Mohan Koyyalamudi10d83a92012-09-28 15:47:05 -07009350 /* Acquire wakelock to handle the case where APP's tries to suspend
9351 * immediatly after the driver gets connect request(i.e after scan)
9352 * from supplicant, this result in app's is suspending and not able
9353 * to process the connect request to AP */
Mahesh A Saptasagarb9c50402014-01-16 15:49:22 +05309354 hdd_prevent_suspend_timeout(1000);
Madan Mohan Koyyalamudi10d83a92012-09-28 15:47:05 -07009355
Gopichand Nakkala638ebc72013-03-21 18:04:02 -07009356#ifdef FEATURE_WLAN_TDLS
c_hpothu3c8f8e82014-06-02 18:01:50 +05309357 if (!(eTDLS_SUPPORT_NOT_ENABLED == pHddCtx->tdls_mode))
9358 {
9359 wlan_hdd_tdls_scan_done_callback(pAdapter);
9360 }
Gopichand Nakkala638ebc72013-03-21 18:04:02 -07009361#endif
9362
Jeff Johnson295189b2012-06-20 16:38:30 -07009363 EXIT();
9364 return 0;
9365}
9366
9367/*
Rashmi Ramannab1429032014-04-26 14:59:09 +05309368 * FUNCTION: hdd_isConnectionInProgress
9369 * Go through each adapter and check if Connection is in progress
Madan Mohan Koyyalamudicfd53742013-01-11 15:29:03 -08009370 *
9371 */
Ganesh Kondabattiniaeb7b772014-08-11 20:00:36 +05309372v_BOOL_t hdd_isConnectionInProgress( hdd_context_t *pHddCtx, v_BOOL_t isRoC )
Madan Mohan Koyyalamudicfd53742013-01-11 15:29:03 -08009373{
9374 hdd_adapter_list_node_t *pAdapterNode = NULL, *pNext = NULL;
9375 hdd_station_ctx_t *pHddStaCtx = NULL;
9376 hdd_adapter_t *pAdapter = NULL;
9377 VOS_STATUS status = 0;
9378 v_U8_t staId = 0;
9379 v_U8_t *staMac = NULL;
9380
c_hpothu9b781ba2013-12-30 20:57:45 +05309381 if (TRUE == pHddCtx->btCoexModeSet)
9382 {
9383 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Rashmi Ramannab1429032014-04-26 14:59:09 +05309384 FL("BTCoex Mode operation in progress"));
9385 return VOS_TRUE;
c_hpothu9b781ba2013-12-30 20:57:45 +05309386 }
9387
Madan Mohan Koyyalamudicfd53742013-01-11 15:29:03 -08009388 status = hdd_get_front_adapter ( pHddCtx, &pAdapterNode );
9389
9390 while ( NULL != pAdapterNode && VOS_STATUS_SUCCESS == status )
9391 {
9392 pAdapter = pAdapterNode->pAdapter;
9393
9394 if( pAdapter )
9395 {
9396 hddLog(VOS_TRACE_LEVEL_INFO,
Sushant Kaushik8bc7df22014-04-09 17:55:29 +05309397 "%s: Adapter with device mode %s (%d) exists",
9398 __func__, hdd_device_modetoString(pAdapter->device_mode),
9399 pAdapter->device_mode);
Ganesh Kondabattiniaeb7b772014-08-11 20:00:36 +05309400 if ((((!isRoC) && (WLAN_HDD_INFRA_STATION == pAdapter->device_mode)) ||
Rashmi Ramannab1429032014-04-26 14:59:09 +05309401 (WLAN_HDD_P2P_CLIENT == pAdapter->device_mode) ||
9402 (WLAN_HDD_P2P_DEVICE == pAdapter->device_mode)) &&
9403 (eConnectionState_Connecting ==
9404 (WLAN_HDD_GET_STATION_CTX_PTR(pAdapter))->conn_info.connState))
9405 {
9406 hddLog(VOS_TRACE_LEVEL_ERROR,
9407 "%s: %p(%d) Connection is in progress", __func__,
9408 WLAN_HDD_GET_STATION_CTX_PTR(pAdapter), pAdapter->sessionId);
9409 return VOS_TRUE;
9410 }
Ganesh Kondabattiniaeb7b772014-08-11 20:00:36 +05309411 if (((!isRoC) && (WLAN_HDD_INFRA_STATION == pAdapter->device_mode)) ||
Sushant Kaushik8bc7df22014-04-09 17:55:29 +05309412 (WLAN_HDD_P2P_CLIENT == pAdapter->device_mode) ||
9413 (WLAN_HDD_P2P_DEVICE == pAdapter->device_mode))
Madan Mohan Koyyalamudicfd53742013-01-11 15:29:03 -08009414 {
9415 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
9416 if ((eConnectionState_Associated == pHddStaCtx->conn_info.connState) &&
Sushant Kaushik8bc7df22014-04-09 17:55:29 +05309417 (VOS_FALSE == pHddStaCtx->conn_info.uIsAuthenticated))
Madan Mohan Koyyalamudicfd53742013-01-11 15:29:03 -08009418 {
9419 staMac = (v_U8_t *) &(pAdapter->macAddressCurrent.bytes[0]);
9420 hddLog(VOS_TRACE_LEVEL_ERROR,
Arif Hussain24bafea2013-11-15 15:10:03 -08009421 "%s: client " MAC_ADDRESS_STR
9422 " is in the middle of WPS/EAPOL exchange.", __func__,
9423 MAC_ADDR_ARRAY(staMac));
Rashmi Ramannab1429032014-04-26 14:59:09 +05309424 return VOS_TRUE;
Madan Mohan Koyyalamudicfd53742013-01-11 15:29:03 -08009425 }
9426 }
9427 else if ((WLAN_HDD_SOFTAP == pAdapter->device_mode) ||
9428 (WLAN_HDD_P2P_GO == pAdapter->device_mode))
9429 {
9430 for (staId = 0; staId < WLAN_MAX_STA_COUNT; staId++)
9431 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309432 if ((pAdapter->aStaInfo[staId].isUsed) &&
Madan Mohan Koyyalamudicfd53742013-01-11 15:29:03 -08009433 (WLANTL_STA_CONNECTED == pAdapter->aStaInfo[staId].tlSTAState))
9434 {
9435 staMac = (v_U8_t *) &(pAdapter->aStaInfo[staId].macAddrSTA.bytes[0]);
9436
9437 hddLog(VOS_TRACE_LEVEL_ERROR,
Arif Hussain24bafea2013-11-15 15:10:03 -08009438 "%s: client " MAC_ADDRESS_STR " of SoftAP/P2P-GO is in the "
9439 "middle of WPS/EAPOL exchange.", __func__,
9440 MAC_ADDR_ARRAY(staMac));
Rashmi Ramannab1429032014-04-26 14:59:09 +05309441 return VOS_TRUE;
Madan Mohan Koyyalamudicfd53742013-01-11 15:29:03 -08009442 }
9443 }
9444 }
9445 }
9446 status = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
9447 pAdapterNode = pNext;
9448 }
Rashmi Ramannab1429032014-04-26 14:59:09 +05309449 return VOS_FALSE;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309450}
Madan Mohan Koyyalamudicfd53742013-01-11 15:29:03 -08009451
9452/*
Mahesh A Saptasagarfafb7fe2014-05-16 13:19:37 +05309453 * FUNCTION: __wlan_hdd_cfg80211_scan
Jeff Johnson295189b2012-06-20 16:38:30 -07009454 * this scan respond to scan trigger and update cfg80211 scan database
9455 * later, scan dump command can be used to recieve scan results
9456 */
Mahesh A Saptasagarfafb7fe2014-05-16 13:19:37 +05309457int __wlan_hdd_cfg80211_scan( struct wiphy *wiphy,
Jeff Johnson3bbe4bf2013-01-18 17:05:29 -08009458#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,6,0))
9459 struct net_device *dev,
9460#endif
9461 struct cfg80211_scan_request *request)
9462{
Siddharth Bhal0c162d02014-05-06 19:50:42 +05309463 hdd_adapter_t *pAdapter = NULL;
9464 hdd_context_t *pHddCtx = NULL;
9465 hdd_wext_state_t *pwextBuf = NULL;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05309466 hdd_config_t *cfg_param = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -07009467 tCsrScanRequest scanRequest;
9468 tANI_U8 *channelList = NULL, i;
9469 v_U32_t scanId = 0;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05309470 int status;
9471 hdd_scaninfo_t *pScanInfo = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -07009472 v_U8_t* pP2pIe = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -07009473
Siddharth Bhal0c162d02014-05-06 19:50:42 +05309474#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,6,0))
9475 struct net_device *dev = NULL;
9476 if (NULL == request)
9477 {
9478 hddLog(VOS_TRACE_LEVEL_ERROR,
9479 "%s: scan req param null", __func__);
9480 return -EINVAL;
9481 }
9482 dev = request->wdev->netdev;
9483#endif
9484
9485 pAdapter = WLAN_HDD_GET_PRIV_PTR( dev );
9486 pHddCtx = WLAN_HDD_GET_CTX( pAdapter );
9487 pwextBuf = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
9488
Jeff Johnson295189b2012-06-20 16:38:30 -07009489 ENTER();
9490
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +05309491
Sushant Kaushik8bc7df22014-04-09 17:55:29 +05309492 hddLog(VOS_TRACE_LEVEL_INFO, "%s: device_mode = %s (%d)",
9493 __func__, hdd_device_modetoString(pAdapter->device_mode),
9494 pAdapter->device_mode);
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +05309495
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05309496 status = wlan_hdd_validate_context(pHddCtx);
9497
9498 if (0 != status)
9499 {
9500 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
9501 "%s: HDD context is not valid", __func__);
9502 return status;
9503 }
9504
Siddharth Bhal0c162d02014-05-06 19:50:42 +05309505 if (NULL == pwextBuf)
9506 {
9507 hddLog (VOS_TRACE_LEVEL_ERROR, "%s ERROR: invalid WEXT state\n",
9508 __func__);
9509 return -EIO;
9510 }
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05309511 cfg_param = pHddCtx->cfg_ini;
9512 pScanInfo = &pHddCtx->scan_info;
9513
Jeff Johnson295189b2012-06-20 16:38:30 -07009514#ifdef WLAN_BTAMP_FEATURE
9515 //Scan not supported when AMP traffic is on.
Gopichand Nakkala681989c2013-03-06 22:27:48 -08009516 if (VOS_TRUE == WLANBAP_AmpSessionOn())
Jeff Johnson295189b2012-06-20 16:38:30 -07009517 {
Madan Mohan Koyyalamudifd4e1da2012-11-09 17:50:19 -08009518 hddLog(VOS_TRACE_LEVEL_ERROR,
Jeff Johnson295189b2012-06-20 16:38:30 -07009519 "%s: No scanning when AMP is on", __func__);
9520 return -EOPNOTSUPP;
9521 }
9522#endif
9523 //Scan on any other interface is not supported.
Gopichand Nakkala681989c2013-03-06 22:27:48 -08009524 if (pAdapter->device_mode == WLAN_HDD_SOFTAP)
Jeff Johnson295189b2012-06-20 16:38:30 -07009525 {
Gopichand Nakkala681989c2013-03-06 22:27:48 -08009526 hddLog(VOS_TRACE_LEVEL_ERROR,
Sushant Kaushik8bc7df22014-04-09 17:55:29 +05309527 "%s: Not scanning on device_mode = %s (%d)",
9528 __func__, hdd_device_modetoString(pAdapter->device_mode),
9529 pAdapter->device_mode);
Jeff Johnson295189b2012-06-20 16:38:30 -07009530 return -EOPNOTSUPP;
9531 }
9532
9533 if (TRUE == pScanInfo->mScanPending)
9534 {
Kiet Lamac06e2c2013-10-23 16:25:07 +05309535 if ( MAX_PENDING_LOG > pScanInfo->mScanPendingCounter++ )
9536 {
9537 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: mScanPending is TRUE", __func__);
9538 }
Gopichand Nakkala681989c2013-03-06 22:27:48 -08009539 return -EBUSY;
Jeff Johnson295189b2012-06-20 16:38:30 -07009540 }
9541
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309542 //Don't Allow Scan and return busy if Remain On
Jeff Johnson32d95a32012-09-10 13:15:23 -07009543 //Channel and action frame is pending
9544 //Otherwise Cancel Remain On Channel and allow Scan
9545 //If no action frame pending
Gopichand Nakkala681989c2013-03-06 22:27:48 -08009546 if (0 != wlan_hdd_check_remain_on_channel(pAdapter))
Jeff Johnson32d95a32012-09-10 13:15:23 -07009547 {
Kiet Lamac06e2c2013-10-23 16:25:07 +05309548 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Remain On Channel Pending", __func__);
Jeff Johnson32d95a32012-09-10 13:15:23 -07009549 return -EBUSY;
9550 }
Gopichand Nakkala681989c2013-03-06 22:27:48 -08009551#ifdef FEATURE_WLAN_TDLS
Gopichand Nakkala638ebc72013-03-21 18:04:02 -07009552 /* if tdls disagree scan right now, return immediately.
9553 tdls will schedule the scan when scan is allowed. (return SUCCESS)
9554 or will reject the scan if any TDLS is in progress. (return -EBUSY)
9555 */
9556 status = wlan_hdd_tdls_scan_callback (pAdapter,
9557 wiphy,
9558#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,6,0))
9559 dev,
Gopichand Nakkalac3c42b92013-03-20 19:42:34 -07009560#endif
Gopichand Nakkala638ebc72013-03-21 18:04:02 -07009561 request);
9562 if(status <= 0)
9563 {
Nirav Shah20ac06f2013-12-12 18:14:06 +05309564 if(!status)
9565 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: TDLS in progress."
9566 "scan rejected %d", __func__, status);
9567 else
9568 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: TDLS teardown is ongoing %d",
9569 __func__, status);
9570
Gopichand Nakkala638ebc72013-03-21 18:04:02 -07009571 return status;
Gopichand Nakkala681989c2013-03-06 22:27:48 -08009572 }
9573#endif
Jeff Johnson32d95a32012-09-10 13:15:23 -07009574
Jeff Johnson295189b2012-06-20 16:38:30 -07009575 if (mutex_lock_interruptible(&pHddCtx->tmInfo.tmOperationLock))
9576 {
9577 VOS_TRACE(VOS_MODULE_ID_HDD,VOS_TRACE_LEVEL_ERROR,
Jeff Johnson1250df42012-12-10 14:31:52 -08009578 "%s: Acquire lock fail", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07009579 return -EAGAIN;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309580 }
Jeff Johnson295189b2012-06-20 16:38:30 -07009581 if (TRUE == pHddCtx->tmInfo.tmAction.enterImps)
9582 {
Nirav Shah20ac06f2013-12-12 18:14:06 +05309583 hddLog(VOS_TRACE_LEVEL_ERROR,
Jeff Johnson295189b2012-06-20 16:38:30 -07009584 "%s: MAX TM Level Scan not allowed", __func__);
9585 mutex_unlock(&pHddCtx->tmInfo.tmOperationLock);
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309586 return -EBUSY;
Jeff Johnson295189b2012-06-20 16:38:30 -07009587 }
9588 mutex_unlock(&pHddCtx->tmInfo.tmOperationLock);
9589
Madan Mohan Koyyalamudicfd53742013-01-11 15:29:03 -08009590 /* Check if scan is allowed at this point of time.
9591 */
Ganesh Kondabattiniaeb7b772014-08-11 20:00:36 +05309592 if (hdd_isConnectionInProgress(pHddCtx, VOS_FALSE))
Madan Mohan Koyyalamudicfd53742013-01-11 15:29:03 -08009593 {
9594 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Scan not allowed", __func__);
9595 return -EBUSY;
9596 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309597
Jeff Johnson295189b2012-06-20 16:38:30 -07009598 vos_mem_zero( &scanRequest, sizeof(scanRequest));
9599
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +05309600 hddLog(VOS_TRACE_LEVEL_INFO, "scan request for ssid = %d",
9601 (int)request->n_ssids);
9602
9603 /* Even though supplicant doesn't provide any SSIDs, n_ssids is set to 1.
9604 * Becasue of this, driver is assuming that this is not wildcard scan and so
9605 * is not aging out the scan results.
9606 */
9607 if (request->ssids && '\0' == request->ssids->ssid[0])
Jeff Johnson295189b2012-06-20 16:38:30 -07009608 {
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +05309609 request->n_ssids = 0;
Jeff Johnson295189b2012-06-20 16:38:30 -07009610 }
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +05309611
9612 if ((request->ssids) && (0 < request->n_ssids))
9613 {
9614 tCsrSSIDInfo *SsidInfo;
9615 int j;
9616 scanRequest.SSIDs.numOfSSIDs = request->n_ssids;
9617 /* Allocate num_ssid tCsrSSIDInfo structure */
9618 SsidInfo = scanRequest.SSIDs.SSIDList =
9619 ( tCsrSSIDInfo *)vos_mem_malloc(
9620 request->n_ssids*sizeof(tCsrSSIDInfo));
9621
9622 if(NULL == scanRequest.SSIDs.SSIDList)
9623 {
9624 hddLog(VOS_TRACE_LEVEL_ERROR,
9625 "%s: memory alloc failed SSIDInfo buffer", __func__);
9626 return -ENOMEM;
9627 }
9628
9629 /* copy all the ssid's and their length */
9630 for(j = 0; j < request->n_ssids; j++, SsidInfo++)
9631 {
9632 /* get the ssid length */
9633 SsidInfo->SSID.length = request->ssids[j].ssid_len;
9634 vos_mem_copy(SsidInfo->SSID.ssId, &request->ssids[j].ssid[0],
9635 SsidInfo->SSID.length);
9636 SsidInfo->SSID.ssId[SsidInfo->SSID.length] = '\0';
9637 hddLog(VOS_TRACE_LEVEL_INFO, "SSID number %d: %s",
9638 j, SsidInfo->SSID.ssId);
9639 }
9640 /* set the scan type to active */
9641 scanRequest.scanType = eSIR_ACTIVE_SCAN;
9642 }
9643 else if(WLAN_HDD_P2P_GO == pAdapter->device_mode)
Jeff Johnson295189b2012-06-20 16:38:30 -07009644 {
Siddharth Bhal0c162d02014-05-06 19:50:42 +05309645 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
9646 TRACE_CODE_HDD_CFG80211_SCAN,
9647 pAdapter->sessionId, 0));
Jeff Johnson295189b2012-06-20 16:38:30 -07009648 /* set the scan type to active */
9649 scanRequest.scanType = eSIR_ACTIVE_SCAN;
Jeff Johnson295189b2012-06-20 16:38:30 -07009650 }
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +05309651 else
9652 {
9653 /*Set the scan type to default type, in this case it is ACTIVE*/
9654 scanRequest.scanType = pScanInfo->scan_mode;
9655 }
9656 scanRequest.minChnTime = cfg_param->nActiveMinChnTime;
9657 scanRequest.maxChnTime = cfg_param->nActiveMaxChnTime;
Jeff Johnson295189b2012-06-20 16:38:30 -07009658
9659 /* set BSSType to default type */
9660 scanRequest.BSSType = eCSR_BSS_TYPE_ANY;
9661
9662 /*TODO: scan the requested channels only*/
9663
9664 /*Right now scanning all the channels */
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +05309665 if (MAX_CHANNEL < request->n_channels)
Jeff Johnson295189b2012-06-20 16:38:30 -07009666 {
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +05309667 hddLog(VOS_TRACE_LEVEL_WARN,
9668 "No of Scan Channels exceeded limit: %d", request->n_channels);
9669 request->n_channels = MAX_CHANNEL;
9670 }
9671
9672 hddLog(VOS_TRACE_LEVEL_INFO,
9673 "No of Scan Channels: %d", request->n_channels);
9674
9675
9676 if( request->n_channels )
9677 {
9678 char chList [(request->n_channels*5)+1];
9679 int len;
9680 channelList = vos_mem_malloc( request->n_channels );
9681 if( NULL == channelList )
c_hpothu53512302014-04-15 18:49:53 +05309682 {
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +05309683 hddLog(VOS_TRACE_LEVEL_ERROR,
9684 "%s: memory alloc failed channelList", __func__);
9685 status = -ENOMEM;
9686 goto free_mem;
c_hpothu53512302014-04-15 18:49:53 +05309687 }
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +05309688
9689 for( i = 0, len = 0; i < request->n_channels ; i++ )
9690 {
9691 channelList[i] = request->channels[i]->hw_value;
9692 len += snprintf(chList+len, 5, "%d ", channelList[i]);
9693 }
9694
Nirav Shah20ac06f2013-12-12 18:14:06 +05309695 hddLog(VOS_TRACE_LEVEL_INFO,
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +05309696 "Channel-List: %s ", chList);
9697 }
c_hpothu53512302014-04-15 18:49:53 +05309698
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +05309699 scanRequest.ChannelInfo.numOfChannels = request->n_channels;
9700 scanRequest.ChannelInfo.ChannelList = channelList;
9701
9702 /* set requestType to full scan */
9703 scanRequest.requestType = eCSR_SCAN_REQUEST_FULL_SCAN;
9704
9705 /* Flush the scan results(only p2p beacons) for STA scan and P2P
9706 * search (Flush on both full scan and social scan but not on single
9707 * channel scan).P2P search happens on 3 social channels (1, 6, 11)
9708 */
9709
9710 /* Supplicant does single channel scan after 8-way handshake
9711 * and in that case driver shoudnt flush scan results. If
9712 * driver flushes the scan results here and unfortunately if
9713 * the AP doesnt respond to our probe req then association
9714 * fails which is not desired
9715 */
9716
9717 if( request->n_channels != WLAN_HDD_P2P_SINGLE_CHANNEL_SCAN )
9718 {
9719 hddLog(VOS_TRACE_LEVEL_DEBUG, "Flushing P2P Results");
9720 sme_ScanFlushP2PResult( WLAN_HDD_GET_HAL_CTX(pAdapter),
9721 pAdapter->sessionId );
9722 }
9723
9724 if( request->ie_len )
9725 {
9726 /* save this for future association (join requires this) */
9727 /*TODO: Array needs to be converted to dynamic allocation,
9728 * as multiple ie.s can be sent in cfg80211_scan_request structure
9729 * CR 597966
9730 */
9731 memset( &pScanInfo->scanAddIE, 0, sizeof(pScanInfo->scanAddIE) );
9732 memcpy( pScanInfo->scanAddIE.addIEdata, request->ie, request->ie_len);
9733 pScanInfo->scanAddIE.length = request->ie_len;
9734
9735 if ((WLAN_HDD_INFRA_STATION == pAdapter->device_mode) ||
9736 (WLAN_HDD_P2P_CLIENT == pAdapter->device_mode) ||
9737 (WLAN_HDD_P2P_DEVICE == pAdapter->device_mode))
Jeff Johnson295189b2012-06-20 16:38:30 -07009738 {
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +05309739 if ( request->ie_len <= SIR_MAC_MAX_IE_LENGTH)
Jeff Johnson295189b2012-06-20 16:38:30 -07009740 {
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +05309741 pwextBuf->roamProfile.nAddIEScanLength = request->ie_len;
9742 memcpy( pwextBuf->roamProfile.addIEScan,
9743 request->ie, request->ie_len);
9744 }
9745 else
9746 {
9747 hddLog(VOS_TRACE_LEVEL_ERROR, "Scan Ie length is invalid:"
9748 "%zu", request->ie_len);
Jeff Johnson295189b2012-06-20 16:38:30 -07009749 }
9750
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +05309751 }
9752 scanRequest.uIEFieldLen = pScanInfo->scanAddIE.length;
9753 scanRequest.pIEField = pScanInfo->scanAddIE.addIEdata;
9754
9755 pP2pIe = wlan_hdd_get_p2p_ie_ptr((v_U8_t*)request->ie,
9756 request->ie_len);
9757 if (pP2pIe != NULL)
9758 {
9759#ifdef WLAN_FEATURE_P2P_DEBUG
9760 if (((globalP2PConnectionStatus == P2P_GO_NEG_COMPLETED) ||
9761 (globalP2PConnectionStatus == P2P_GO_NEG_PROCESS)) &&
9762 (WLAN_HDD_P2P_CLIENT == pAdapter->device_mode))
Nirav Shah20ac06f2013-12-12 18:14:06 +05309763 {
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +05309764 globalP2PConnectionStatus = P2P_CLIENT_CONNECTING_STATE_1;
9765 hddLog(VOS_TRACE_LEVEL_ERROR,"[P2P State] Changing state from "
9766 "Go nego completed to Connection is started");
9767 hddLog(VOS_TRACE_LEVEL_ERROR,"[P2P]P2P Scanning is started "
9768 "for 8way Handshake");
Nirav Shah20ac06f2013-12-12 18:14:06 +05309769 }
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +05309770 else if((globalP2PConnectionStatus == P2P_CLIENT_DISCONNECTED_STATE) &&
9771 (WLAN_HDD_P2P_CLIENT == pAdapter->device_mode))
Jeff Johnson295189b2012-06-20 16:38:30 -07009772 {
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +05309773 globalP2PConnectionStatus = P2P_CLIENT_CONNECTING_STATE_2;
9774 hddLog(VOS_TRACE_LEVEL_ERROR,"[P2P State] Changing state from "
9775 "Disconnected state to Connection is started");
9776 hddLog(VOS_TRACE_LEVEL_ERROR,"[P2P]P2P Scanning is started "
9777 "for 4way Handshake");
9778 }
9779#endif
9780
9781 /* no_cck will be set during p2p find to disable 11b rates */
9782 if(TRUE == request->no_cck)
9783 {
9784 hddLog(VOS_TRACE_LEVEL_INFO,
9785 "%s: This is a P2P Search", __func__);
9786 scanRequest.p2pSearch = 1;
9787
9788 if( request->n_channels == WLAN_HDD_P2P_SOCIAL_CHANNELS )
Agarwal Ashish4f616132013-12-30 23:32:50 +05309789 {
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +05309790 /* set requestType to P2P Discovery */
9791 scanRequest.requestType = eCSR_SCAN_P2P_DISCOVERY;
9792 }
9793
9794 /*
9795 Skip Dfs Channel in case of P2P Search
9796 if it is set in ini file
9797 */
9798 if(cfg_param->skipDfsChnlInP2pSearch)
9799 {
9800 scanRequest.skipDfsChnlInP2pSearch = 1;
Agarwal Ashish4f616132013-12-30 23:32:50 +05309801 }
9802 else
9803 {
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +05309804 scanRequest.skipDfsChnlInP2pSearch = 0;
Agarwal Ashish4f616132013-12-30 23:32:50 +05309805 }
Jeff Johnson295189b2012-06-20 16:38:30 -07009806
Agarwal Ashish4f616132013-12-30 23:32:50 +05309807 }
Jeff Johnson295189b2012-06-20 16:38:30 -07009808 }
9809 }
9810
9811 INIT_COMPLETION(pScanInfo->scan_req_completion_event);
9812
Madan Mohan Koyyalamudi9f5a10c2012-09-28 14:46:16 -07009813 /* acquire the wakelock to avoid the apps suspend during the scan. To
9814 * address the following issues.
9815 * 1) Disconnected scenario: we are not allowing the suspend as WLAN is not in
9816 * BMPS/IMPS this result in android trying to suspend aggressively and backing off
9817 * for long time, this result in apps running at full power for long time.
9818 * 2) Connected scenario: If we allow the suspend during the scan, RIVA will
9819 * be stuck in full power because of resume BMPS
9820 */
9821 hdd_prevent_suspend();
Jeff Johnsone7245742012-09-05 17:12:55 -07009822
Nirav Shah20ac06f2013-12-12 18:14:06 +05309823 hddLog(VOS_TRACE_LEVEL_INFO_HIGH,
9824 "requestType %d, scanType %d, minChnTime %d, maxChnTime %d,"
Sushant Kaushik8bc7df22014-04-09 17:55:29 +05309825 "p2pSearch %d, skipDfsChnlInP2pSearch %d",
9826 scanRequest.requestType, scanRequest.scanType,
9827 scanRequest.minChnTime, scanRequest.maxChnTime,
Nirav Shah20ac06f2013-12-12 18:14:06 +05309828 scanRequest.p2pSearch, scanRequest.skipDfsChnlInP2pSearch);
9829
Siddharth Bhal76972212014-10-15 16:22:51 +05309830 if (pHddCtx->spoofMacAddr.isEnabled)
9831 {
9832 hddLog(VOS_TRACE_LEVEL_INFO,
9833 "%s: MAC Spoofing enabled for current scan", __func__);
9834 /* Updating SelfSta Mac Addr in TL which will be used to get staidx
9835 * to fill TxBds for probe request during current scan
9836 */
9837 WLANTL_updateSpoofMacAddr(pHddCtx->pvosContext,
9838 &pHddCtx->spoofMacAddr.randomMacAddr, &pAdapter->macAddressCurrent);
9839 }
9840
Jeff Johnsone7245742012-09-05 17:12:55 -07009841 status = sme_ScanRequest( WLAN_HDD_GET_HAL_CTX(pAdapter),
Jeff Johnson295189b2012-06-20 16:38:30 -07009842 pAdapter->sessionId, &scanRequest, &scanId,
9843 &hdd_cfg80211_scan_done_callback, dev );
Jeff Johnsone7245742012-09-05 17:12:55 -07009844
Jeff Johnson295189b2012-06-20 16:38:30 -07009845 if (eHAL_STATUS_SUCCESS != status)
9846 {
9847 hddLog(VOS_TRACE_LEVEL_ERROR,
9848 "%s: sme_ScanRequest returned error %d", __func__, status);
9849 complete(&pScanInfo->scan_req_completion_event);
Madan Mohan Koyyalamudi3b230fe2012-10-18 14:46:32 -07009850 if(eHAL_STATUS_RESOURCES == status)
9851 {
Nirav Shah20ac06f2013-12-12 18:14:06 +05309852 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: HO is in progress."
9853 "So defer the scan by informing busy",__func__);
Madan Mohan Koyyalamudi3b230fe2012-10-18 14:46:32 -07009854 status = -EBUSY;
9855 } else {
9856 status = -EIO;
9857 }
Madan Mohan Koyyalamudi9f5a10c2012-09-28 14:46:16 -07009858 hdd_allow_suspend();
Jeff Johnson295189b2012-06-20 16:38:30 -07009859 goto free_mem;
9860 }
9861
9862 pScanInfo->mScanPending = TRUE;
Kaushik, Sushant4975a572014-10-21 16:07:48 +05309863 pScanInfo->sessionId = pAdapter->sessionId;
Jeff Johnson295189b2012-06-20 16:38:30 -07009864 pAdapter->request = request;
9865 pScanInfo->scanId = scanId;
9866
9867 complete(&pScanInfo->scan_req_completion_event);
9868
9869free_mem:
9870 if( scanRequest.SSIDs.SSIDList )
9871 {
9872 vos_mem_free(scanRequest.SSIDs.SSIDList);
9873 }
9874
9875 if( channelList )
9876 vos_mem_free( channelList );
9877
9878 EXIT();
9879
9880 return status;
9881}
9882
Mahesh A Saptasagarfafb7fe2014-05-16 13:19:37 +05309883int wlan_hdd_cfg80211_scan( struct wiphy *wiphy,
9884#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,6,0))
9885 struct net_device *dev,
9886#endif
9887 struct cfg80211_scan_request *request)
9888{
9889 int ret;
9890
9891 vos_ssr_protect(__func__);
9892 ret = __wlan_hdd_cfg80211_scan(wiphy,
9893#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,6,0))
9894 dev,
9895#endif
9896 request);
9897 vos_ssr_unprotect(__func__);
9898
9899 return ret;
9900}
Shailender Karmuchi15cd0672013-05-15 19:50:04 -07009901
9902void hdd_select_cbmode( hdd_adapter_t *pAdapter,v_U8_t operationChannel)
9903{
9904 v_U8_t iniDot11Mode =
9905 (WLAN_HDD_GET_CTX(pAdapter))->cfg_ini->dot11Mode;
9906 eHddDot11Mode hddDot11Mode = iniDot11Mode;
9907
Arun Kumar Khandavalli94a2bb02013-12-28 19:17:25 +05309908 hddLog(LOG1, FL("Channel Bonding Mode Selected is %u"),
9909 iniDot11Mode);
Shailender Karmuchi15cd0672013-05-15 19:50:04 -07009910 switch ( iniDot11Mode )
9911 {
9912 case eHDD_DOT11_MODE_AUTO:
9913 case eHDD_DOT11_MODE_11ac:
9914 case eHDD_DOT11_MODE_11ac_ONLY:
9915#ifdef WLAN_FEATURE_11AC
Abhishek Singh4b1d2352014-08-01 21:59:28 +05309916 if ( sme_IsFeatureSupportedByDriver(DOT11AC) &&
9917 sme_IsFeatureSupportedByFW(DOT11AC) )
9918 hddDot11Mode = eHDD_DOT11_MODE_11ac;
9919 else
9920 hddDot11Mode = eHDD_DOT11_MODE_11n;
Shailender Karmuchi15cd0672013-05-15 19:50:04 -07009921#else
9922 hddDot11Mode = eHDD_DOT11_MODE_11n;
9923#endif
9924 break;
9925 case eHDD_DOT11_MODE_11n:
9926 case eHDD_DOT11_MODE_11n_ONLY:
9927 hddDot11Mode = eHDD_DOT11_MODE_11n;
9928 break;
9929 default:
9930 hddDot11Mode = iniDot11Mode;
9931 break;
9932 }
9933 /* This call decides required channel bonding mode */
9934 sme_SelectCBMode((WLAN_HDD_GET_CTX(pAdapter)->hHal),
9935 hdd_cfg_xlate_to_csr_phy_mode(hddDot11Mode),
9936 operationChannel);
9937}
9938
Jeff Johnson295189b2012-06-20 16:38:30 -07009939/*
9940 * FUNCTION: wlan_hdd_cfg80211_connect_start
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309941 * This function is used to start the association process
Jeff Johnson295189b2012-06-20 16:38:30 -07009942 */
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309943int wlan_hdd_cfg80211_connect_start( hdd_adapter_t *pAdapter,
Jeff Johnson32d95a32012-09-10 13:15:23 -07009944 const u8 *ssid, size_t ssid_len, const u8 *bssid, u8 operatingChannel)
Jeff Johnson295189b2012-06-20 16:38:30 -07009945{
9946 int status = 0;
9947 hdd_wext_state_t *pWextState;
Yue Mae36e3552014-03-05 17:06:20 -08009948 hdd_context_t *pHddCtx;
Jeff Johnson295189b2012-06-20 16:38:30 -07009949 v_U32_t roamId;
9950 tCsrRoamProfile *pRoamProfile;
Jeff Johnson295189b2012-06-20 16:38:30 -07009951 eCsrAuthType RSNAuthType;
9952
9953 ENTER();
9954
9955 pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
Yue Mae36e3552014-03-05 17:06:20 -08009956 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
9957
9958 status = wlan_hdd_validate_context(pHddCtx);
9959 if (status)
9960 {
9961 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
9962 "%s: HDD context is not valid!", __func__);
9963 return status;
9964 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309965
Jeff Johnson295189b2012-06-20 16:38:30 -07009966 if (SIR_MAC_MAX_SSID_LENGTH < ssid_len)
9967 {
9968 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: wrong SSID len", __func__);
9969 return -EINVAL;
9970 }
9971
9972 pRoamProfile = &pWextState->roamProfile;
9973
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309974 if (pRoamProfile)
Jeff Johnson295189b2012-06-20 16:38:30 -07009975 {
Jeff Johnsone7245742012-09-05 17:12:55 -07009976 hdd_station_ctx_t *pHddStaCtx;
9977 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
Jeff Johnson295189b2012-06-20 16:38:30 -07009978
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309979 if (HDD_WMM_USER_MODE_NO_QOS ==
Jeff Johnson295189b2012-06-20 16:38:30 -07009980 (WLAN_HDD_GET_CTX(pAdapter))->cfg_ini->WmmMode)
9981 {
9982 /*QoS not enabled in cfg file*/
9983 pRoamProfile->uapsd_mask = 0;
9984 }
9985 else
9986 {
9987 /*QoS enabled, update uapsd mask from cfg file*/
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309988 pRoamProfile->uapsd_mask =
Jeff Johnson295189b2012-06-20 16:38:30 -07009989 (WLAN_HDD_GET_CTX(pAdapter))->cfg_ini->UapsdMask;
9990 }
9991
9992 pRoamProfile->SSIDs.numOfSSIDs = 1;
9993 pRoamProfile->SSIDs.SSIDList->SSID.length = ssid_len;
9994 vos_mem_zero(pRoamProfile->SSIDs.SSIDList->SSID.ssId,
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309995 sizeof(pRoamProfile->SSIDs.SSIDList->SSID.ssId));
Jeff Johnson295189b2012-06-20 16:38:30 -07009996 vos_mem_copy((void *)(pRoamProfile->SSIDs.SSIDList->SSID.ssId),
9997 ssid, ssid_len);
9998
9999 if (bssid)
10000 {
10001 pRoamProfile->BSSIDs.numOfBSSIDs = 1;
10002 vos_mem_copy((void *)(pRoamProfile->BSSIDs.bssid), bssid,
10003 WNI_CFG_BSSID_LEN);
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010004 /* Save BSSID in seperate variable as well, as RoamProfile
10005 BSSID is getting zeroed out in the association process. And in
Jeff Johnson295189b2012-06-20 16:38:30 -070010006 case of join failure we should send valid BSSID to supplicant
10007 */
10008 vos_mem_copy((void *)(pWextState->req_bssId), bssid,
10009 WNI_CFG_BSSID_LEN);
10010 }
Dhanashri Atre51981c62013-06-13 11:47:57 -070010011 else
10012 {
10013 vos_mem_zero((void *)(pRoamProfile->BSSIDs.bssid),WNI_CFG_BSSID_LEN);
10014 }
Jeff Johnson295189b2012-06-20 16:38:30 -070010015
Arun Kumar Khandavalli94a2bb02013-12-28 19:17:25 +053010016 hddLog(LOG1, FL("Connect to SSID: %s opertating Channel: %u"),
10017 pRoamProfile->SSIDs.SSIDList->SSID.ssId, operatingChannel);
Jeff Johnson295189b2012-06-20 16:38:30 -070010018 if ((IW_AUTH_WPA_VERSION_WPA == pWextState->wpaVersion) ||
10019 (IW_AUTH_WPA_VERSION_WPA2 == pWextState->wpaVersion))
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010020 {
Jeff Johnson295189b2012-06-20 16:38:30 -070010021 /*set gen ie*/
10022 hdd_SetGENIEToCsr(pAdapter, &RSNAuthType);
10023 /*set auth*/
10024 hdd_set_csr_auth_type(pAdapter, RSNAuthType);
10025 }
Jeff Johnson295189b2012-06-20 16:38:30 -070010026#ifdef FEATURE_WLAN_WAPI
10027 if (pAdapter->wapi_info.nWapiMode)
10028 {
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -070010029 hddLog(LOG1, "%s: Setting WAPI AUTH Type and Encryption Mode values", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -070010030 switch (pAdapter->wapi_info.wapiAuthMode)
10031 {
10032 case WAPI_AUTH_MODE_PSK:
10033 {
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -070010034 hddLog(LOG1, "%s: WAPI AUTH TYPE: PSK: %d", __func__,
Jeff Johnson295189b2012-06-20 16:38:30 -070010035 pAdapter->wapi_info.wapiAuthMode);
10036 pRoamProfile->AuthType.authType[0] = eCSR_AUTH_TYPE_WAPI_WAI_PSK;
10037 break;
10038 }
10039 case WAPI_AUTH_MODE_CERT:
10040 {
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -070010041 hddLog(LOG1, "%s: WAPI AUTH TYPE: CERT: %d", __func__,
Jeff Johnson295189b2012-06-20 16:38:30 -070010042 pAdapter->wapi_info.wapiAuthMode);
10043 pRoamProfile->AuthType.authType[0] = eCSR_AUTH_TYPE_WAPI_WAI_CERTIFICATE;
10044 break;
10045 }
10046 } // End of switch
10047 if ( pAdapter->wapi_info.wapiAuthMode == WAPI_AUTH_MODE_PSK ||
10048 pAdapter->wapi_info.wapiAuthMode == WAPI_AUTH_MODE_CERT)
10049 {
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -070010050 hddLog(LOG1, "%s: WAPI PAIRWISE/GROUP ENCRYPTION: WPI", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -070010051 pRoamProfile->AuthType.numEntries = 1;
10052 pRoamProfile->EncryptionType.numEntries = 1;
10053 pRoamProfile->EncryptionType.encryptionType[0] = eCSR_ENCRYPT_TYPE_WPI;
10054 pRoamProfile->mcEncryptionType.numEntries = 1;
10055 pRoamProfile->mcEncryptionType.encryptionType[0] = eCSR_ENCRYPT_TYPE_WPI;
10056 }
10057 }
10058#endif /* FEATURE_WLAN_WAPI */
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053010059#ifdef WLAN_FEATURE_GTK_OFFLOAD
Gopichand Nakkalad36ee622013-05-07 14:13:27 +053010060 /* Initializing gtkOffloadReqParams */
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053010061 if ((WLAN_HDD_INFRA_STATION == pAdapter->device_mode) ||
10062 (WLAN_HDD_P2P_CLIENT == pAdapter->device_mode))
10063 {
Gopichand Nakkalad36ee622013-05-07 14:13:27 +053010064 memset(&pHddStaCtx->gtkOffloadReqParams, 0,
10065 sizeof (tSirGtkOffloadParams));
10066 pHddStaCtx->gtkOffloadReqParams.ulFlags = GTK_OFFLOAD_DISABLE;
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053010067 }
10068#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070010069 pRoamProfile->csrPersona = pAdapter->device_mode;
10070
Jeff Johnson32d95a32012-09-10 13:15:23 -070010071 if( operatingChannel )
10072 {
10073 pRoamProfile->ChannelInfo.ChannelList = &operatingChannel;
10074 pRoamProfile->ChannelInfo.numOfChannels = 1;
10075 }
Chet Lanctot186b5732013-03-18 10:26:30 -070010076 else
10077 {
10078 pRoamProfile->ChannelInfo.ChannelList = NULL;
10079 pRoamProfile->ChannelInfo.numOfChannels = 0;
10080 }
Shailender Karmuchi15cd0672013-05-15 19:50:04 -070010081 if ( (WLAN_HDD_IBSS == pAdapter->device_mode) && operatingChannel)
10082 {
10083 hdd_select_cbmode(pAdapter,operatingChannel);
10084 }
Arun Kumar Khandavalli94a2bb02013-12-28 19:17:25 +053010085
Madan Mohan Koyyalamudi42dcd162012-12-03 16:34:04 -080010086 /* change conn_state to connecting before sme_RoamConnect(), because sme_RoamConnect()
10087 * has a direct path to call hdd_smeRoamCallback(), which will change the conn_state
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010088 * If direct path, conn_state will be accordingly changed to NotConnected or Associated
Madan Mohan Koyyalamudi42dcd162012-12-03 16:34:04 -080010089 * by either hdd_AssociationCompletionHandler() or hdd_DisConnectHandler() in sme_RoamCallback()
Madan Mohan Koyyalamudidf86c422012-12-04 17:03:44 -080010090 * if sme_RomConnect is to be queued, Connecting state will remain until it is completed.
10091 */
Gopichand Nakkalaa3c8fb62013-06-21 15:36:42 +053010092 if (WLAN_HDD_INFRA_STATION == pAdapter->device_mode ||
10093 WLAN_HDD_P2P_CLIENT == pAdapter->device_mode)
Abhishek Singhf4669da2014-05-26 15:07:49 +053010094 {
10095 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
10096 "%s: Set HDD connState to eConnectionState_Connecting",
10097 __func__);
Madan Mohan Koyyalamudidf86c422012-12-04 17:03:44 -080010098 hdd_connSetConnectionState(WLAN_HDD_GET_STATION_CTX_PTR(pAdapter),
10099 eConnectionState_Connecting);
Abhishek Singhf4669da2014-05-26 15:07:49 +053010100 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010101 status = sme_RoamConnect( WLAN_HDD_GET_HAL_CTX(pAdapter),
Jeff Johnson295189b2012-06-20 16:38:30 -070010102 pAdapter->sessionId, pRoamProfile, &roamId);
10103
Gopichand Nakkalaa3c8fb62013-06-21 15:36:42 +053010104 if ((eHAL_STATUS_SUCCESS != status) &&
10105 (WLAN_HDD_INFRA_STATION == pAdapter->device_mode ||
10106 WLAN_HDD_P2P_CLIENT == pAdapter->device_mode))
Madan Mohan Koyyalamudid5acbf52012-11-28 01:45:08 +053010107
10108 {
Madan Mohan Koyyalamudi42dcd162012-12-03 16:34:04 -080010109 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: sme_RoamConnect (session %d) failed with "
10110 "status %d. -> NotConnected", __func__, pAdapter->sessionId, status);
10111 /* change back to NotAssociated */
Madan Mohan Koyyalamudid5acbf52012-11-28 01:45:08 +053010112 hdd_connSetConnectionState(WLAN_HDD_GET_STATION_CTX_PTR(pAdapter),
Madan Mohan Koyyalamudi42dcd162012-12-03 16:34:04 -080010113 eConnectionState_NotConnected);
Madan Mohan Koyyalamudid5acbf52012-11-28 01:45:08 +053010114 }
Madan Mohan Koyyalamudidf86c422012-12-04 17:03:44 -080010115
10116 pRoamProfile->ChannelInfo.ChannelList = NULL;
10117 pRoamProfile->ChannelInfo.numOfChannels = 0;
10118
Jeff Johnson295189b2012-06-20 16:38:30 -070010119 }
10120 else
10121 {
10122 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: No valid Roam profile", __func__);
10123 return -EINVAL;
10124 }
Madan Mohan Koyyalamudifd4e1da2012-11-09 17:50:19 -080010125 EXIT();
Jeff Johnson295189b2012-06-20 16:38:30 -070010126 return status;
10127}
10128
10129/*
10130 * FUNCTION: wlan_hdd_set_cfg80211_auth_type
10131 * This function is used to set the authentication type (OPEN/SHARED).
10132 *
10133 */
10134static int wlan_hdd_cfg80211_set_auth_type(hdd_adapter_t *pAdapter,
10135 enum nl80211_auth_type auth_type)
10136{
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010137 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
Jeff Johnson295189b2012-06-20 16:38:30 -070010138 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
10139
10140 ENTER();
10141
10142 /*set authentication type*/
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010143 switch (auth_type)
Jeff Johnson295189b2012-06-20 16:38:30 -070010144 {
Jeff Johnson295189b2012-06-20 16:38:30 -070010145 case NL80211_AUTHTYPE_AUTOMATIC:
Gopichand Nakkala29149562013-05-10 21:43:41 +053010146 hddLog(VOS_TRACE_LEVEL_INFO,
10147 "%s: set authentication type to AUTOSWITCH", __func__);
10148 pHddStaCtx->conn_info.authType = eCSR_AUTH_TYPE_AUTOSWITCH;
10149 break;
10150
10151 case NL80211_AUTHTYPE_OPEN_SYSTEM:
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070010152#ifdef WLAN_FEATURE_VOWIFI_11R
10153 case NL80211_AUTHTYPE_FT:
10154#endif /* WLAN_FEATURE_VOWIFI_11R */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010155 hddLog(VOS_TRACE_LEVEL_INFO,
Jeff Johnson295189b2012-06-20 16:38:30 -070010156 "%s: set authentication type to OPEN", __func__);
10157 pHddStaCtx->conn_info.authType = eCSR_AUTH_TYPE_OPEN_SYSTEM;
10158 break;
10159
10160 case NL80211_AUTHTYPE_SHARED_KEY:
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010161 hddLog(VOS_TRACE_LEVEL_INFO,
Jeff Johnson295189b2012-06-20 16:38:30 -070010162 "%s: set authentication type to SHARED", __func__);
10163 pHddStaCtx->conn_info.authType = eCSR_AUTH_TYPE_SHARED_KEY;
10164 break;
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -080010165#ifdef FEATURE_WLAN_ESE
Jeff Johnson295189b2012-06-20 16:38:30 -070010166 case NL80211_AUTHTYPE_NETWORK_EAP:
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010167 hddLog(VOS_TRACE_LEVEL_INFO,
Jeff Johnson295189b2012-06-20 16:38:30 -070010168 "%s: set authentication type to CCKM WPA", __func__);
10169 pHddStaCtx->conn_info.authType = eCSR_AUTH_TYPE_CCKM_WPA;//eCSR_AUTH_TYPE_CCKM_RSN needs to be handled as well if required.
10170 break;
10171#endif
10172
10173
10174 default:
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010175 hddLog(VOS_TRACE_LEVEL_ERROR,
10176 "%s: Unsupported authentication type %d", __func__,
Jeff Johnson295189b2012-06-20 16:38:30 -070010177 auth_type);
10178 pHddStaCtx->conn_info.authType = eCSR_AUTH_TYPE_UNKNOWN;
10179 return -EINVAL;
10180 }
10181
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010182 pWextState->roamProfile.AuthType.authType[0] =
Jeff Johnson295189b2012-06-20 16:38:30 -070010183 pHddStaCtx->conn_info.authType;
10184 return 0;
10185}
10186
10187/*
10188 * FUNCTION: wlan_hdd_set_akm_suite
10189 * This function is used to set the key mgmt type(PSK/8021x).
10190 *
10191 */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010192static int wlan_hdd_set_akm_suite( hdd_adapter_t *pAdapter,
Jeff Johnson295189b2012-06-20 16:38:30 -070010193 u32 key_mgmt
10194 )
10195{
10196 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
10197 ENTER();
Abhishek Singhae408032014-09-25 17:22:04 +053010198 /* Should be in ieee802_11_defs.h */
10199#define WLAN_AKM_SUITE_8021X_SHA256 0x000FAC05
10200#define WLAN_AKM_SUITE_PSK_SHA256 0x000FAC06
Jeff Johnson295189b2012-06-20 16:38:30 -070010201 /*set key mgmt type*/
10202 switch(key_mgmt)
10203 {
10204 case WLAN_AKM_SUITE_PSK:
Abhishek Singhae408032014-09-25 17:22:04 +053010205 case WLAN_AKM_SUITE_PSK_SHA256:
Gopichand Nakkala356fb102013-03-06 12:34:04 +053010206#ifdef WLAN_FEATURE_VOWIFI_11R
10207 case WLAN_AKM_SUITE_FT_PSK:
10208#endif
10209 hddLog(VOS_TRACE_LEVEL_INFO, "%s: setting key mgmt type to PSK",
Jeff Johnson295189b2012-06-20 16:38:30 -070010210 __func__);
10211 pWextState->authKeyMgmt |= IW_AUTH_KEY_MGMT_PSK;
10212 break;
10213
10214 case WLAN_AKM_SUITE_8021X:
Abhishek Singhae408032014-09-25 17:22:04 +053010215 case WLAN_AKM_SUITE_8021X_SHA256:
Gopichand Nakkala356fb102013-03-06 12:34:04 +053010216#ifdef WLAN_FEATURE_VOWIFI_11R
10217 case WLAN_AKM_SUITE_FT_8021X:
10218#endif
10219 hddLog(VOS_TRACE_LEVEL_INFO, "%s: setting key mgmt type to 8021x",
Jeff Johnson295189b2012-06-20 16:38:30 -070010220 __func__);
10221 pWextState->authKeyMgmt |= IW_AUTH_KEY_MGMT_802_1X;
10222 break;
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -080010223#ifdef FEATURE_WLAN_ESE
Jeff Johnson295189b2012-06-20 16:38:30 -070010224#define WLAN_AKM_SUITE_CCKM 0x00409600 /* Should be in ieee802_11_defs.h */
10225#define IW_AUTH_KEY_MGMT_CCKM 8 /* Should be in linux/wireless.h */
10226 case WLAN_AKM_SUITE_CCKM:
10227 hddLog(VOS_TRACE_LEVEL_INFO, "%s: setting key mgmt type to CCKM",
10228 __func__);
10229 pWextState->authKeyMgmt |= IW_AUTH_KEY_MGMT_CCKM;
10230 break;
10231#endif
Leela Venkata Kiran Kumar Reddy Chiralae208a832014-04-27 22:34:25 -070010232#ifndef WLAN_AKM_SUITE_OSEN
10233#define WLAN_AKM_SUITE_OSEN 0x506f9a01 /* Should be in ieee802_11_defs.h */
10234 case WLAN_AKM_SUITE_OSEN:
10235 hddLog(VOS_TRACE_LEVEL_INFO, "%s: setting key mgmt type to OSEN",
10236 __func__);
10237 pWextState->authKeyMgmt |= IW_AUTH_KEY_MGMT_802_1X;
10238 break;
10239#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070010240
10241 default:
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010242 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Unsupported key mgmt type %d",
Jeff Johnson295189b2012-06-20 16:38:30 -070010243 __func__, key_mgmt);
10244 return -EINVAL;
10245
10246 }
10247 return 0;
10248}
10249
10250/*
10251 * FUNCTION: wlan_hdd_cfg80211_set_cipher
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010252 * This function is used to set the encryption type
Jeff Johnson295189b2012-06-20 16:38:30 -070010253 * (NONE/WEP40/WEP104/TKIP/CCMP).
10254 */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010255static int wlan_hdd_cfg80211_set_cipher( hdd_adapter_t *pAdapter,
10256 u32 cipher,
Jeff Johnson295189b2012-06-20 16:38:30 -070010257 bool ucast
10258 )
10259{
10260 eCsrEncryptionType encryptionType = eCSR_ENCRYPT_TYPE_NONE;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010261 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
Jeff Johnson295189b2012-06-20 16:38:30 -070010262 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
10263
10264 ENTER();
10265
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010266 if (!cipher)
Jeff Johnson295189b2012-06-20 16:38:30 -070010267 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010268 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: received cipher %d - considering none",
Jeff Johnson295189b2012-06-20 16:38:30 -070010269 __func__, cipher);
10270 encryptionType = eCSR_ENCRYPT_TYPE_NONE;
10271 }
10272 else
10273 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010274
Jeff Johnson295189b2012-06-20 16:38:30 -070010275 /*set encryption method*/
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010276 switch (cipher)
Jeff Johnson295189b2012-06-20 16:38:30 -070010277 {
10278 case IW_AUTH_CIPHER_NONE:
10279 encryptionType = eCSR_ENCRYPT_TYPE_NONE;
10280 break;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010281
Jeff Johnson295189b2012-06-20 16:38:30 -070010282 case WLAN_CIPHER_SUITE_WEP40:
Gopichand Nakkala29149562013-05-10 21:43:41 +053010283 encryptionType = eCSR_ENCRYPT_TYPE_WEP40;
Jeff Johnson295189b2012-06-20 16:38:30 -070010284 break;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010285
Jeff Johnson295189b2012-06-20 16:38:30 -070010286 case WLAN_CIPHER_SUITE_WEP104:
Gopichand Nakkala29149562013-05-10 21:43:41 +053010287 encryptionType = eCSR_ENCRYPT_TYPE_WEP104;
Jeff Johnson295189b2012-06-20 16:38:30 -070010288 break;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010289
Jeff Johnson295189b2012-06-20 16:38:30 -070010290 case WLAN_CIPHER_SUITE_TKIP:
10291 encryptionType = eCSR_ENCRYPT_TYPE_TKIP;
10292 break;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010293
Jeff Johnson295189b2012-06-20 16:38:30 -070010294 case WLAN_CIPHER_SUITE_CCMP:
10295 encryptionType = eCSR_ENCRYPT_TYPE_AES;
10296 break;
10297#ifdef FEATURE_WLAN_WAPI
10298 case WLAN_CIPHER_SUITE_SMS4:
10299 encryptionType = eCSR_ENCRYPT_TYPE_WPI;
10300 break;
10301#endif
10302
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -080010303#ifdef FEATURE_WLAN_ESE
Jeff Johnson295189b2012-06-20 16:38:30 -070010304 case WLAN_CIPHER_SUITE_KRK:
10305 encryptionType = eCSR_ENCRYPT_TYPE_KRK;
10306 break;
10307#endif
10308 default:
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010309 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Unsupported cipher type %d",
Jeff Johnson295189b2012-06-20 16:38:30 -070010310 __func__, cipher);
10311 return -EOPNOTSUPP;
10312 }
10313 }
10314
10315 if (ucast)
10316 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010317 hddLog(VOS_TRACE_LEVEL_INFO, "%s: setting unicast cipher type to %d",
Jeff Johnson295189b2012-06-20 16:38:30 -070010318 __func__, encryptionType);
10319 pHddStaCtx->conn_info.ucEncryptionType = encryptionType;
10320 pWextState->roamProfile.EncryptionType.numEntries = 1;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010321 pWextState->roamProfile.EncryptionType.encryptionType[0] =
Jeff Johnson295189b2012-06-20 16:38:30 -070010322 encryptionType;
10323 }
10324 else
10325 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010326 hddLog(VOS_TRACE_LEVEL_INFO, "%s: setting mcast cipher type to %d",
Jeff Johnson295189b2012-06-20 16:38:30 -070010327 __func__, encryptionType);
10328 pHddStaCtx->conn_info.mcEncryptionType = encryptionType;
10329 pWextState->roamProfile.mcEncryptionType.numEntries = 1;
10330 pWextState->roamProfile.mcEncryptionType.encryptionType[0] = encryptionType;
10331 }
10332
10333 return 0;
10334}
10335
10336
10337/*
10338 * FUNCTION: wlan_hdd_cfg80211_set_ie
10339 * This function is used to parse WPA/RSN IE's.
10340 */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010341int wlan_hdd_cfg80211_set_ie( hdd_adapter_t *pAdapter,
10342 u8 *ie,
Jeff Johnson295189b2012-06-20 16:38:30 -070010343 size_t ie_len
10344 )
10345{
10346 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
10347 u8 *genie = ie;
10348 v_U16_t remLen = ie_len;
10349#ifdef FEATURE_WLAN_WAPI
10350 v_U32_t akmsuite[MAX_NUM_AKM_SUITES];
10351 u16 *tmp;
10352 v_U16_t akmsuiteCount;
10353 int *akmlist;
10354#endif
10355 ENTER();
10356
10357 /* clear previous assocAddIE */
10358 pWextState->assocAddIE.length = 0;
10359 pWextState->roamProfile.bWPSAssociation = VOS_FALSE;
Leela Venkata Kiran Kumar Reddy Chiralaf257bef2014-04-11 18:48:12 -070010360 pWextState->roamProfile.bOSENAssociation = VOS_FALSE;
Jeff Johnson295189b2012-06-20 16:38:30 -070010361
10362 while (remLen >= 2)
10363 {
10364 v_U16_t eLen = 0;
10365 v_U8_t elementId;
10366 elementId = *genie++;
10367 eLen = *genie++;
10368 remLen -= 2;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010369
Arif Hussain6d2a3322013-11-17 19:50:10 -080010370 hddLog(VOS_TRACE_LEVEL_INFO, "%s: IE[0x%X], LEN[%d]",
Jeff Johnson295189b2012-06-20 16:38:30 -070010371 __func__, elementId, eLen);
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010372
10373 switch ( elementId )
Jeff Johnson295189b2012-06-20 16:38:30 -070010374 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010375 case DOT11F_EID_WPA:
Madan Mohan Koyyalamudief3b66e2012-10-11 14:29:42 -070010376 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 -070010377 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010378 hddLog(VOS_TRACE_LEVEL_ERROR,
Jeff Johnson295189b2012-06-20 16:38:30 -070010379 "%s: Invalid WPA IE", __func__);
10380 return -EINVAL;
10381 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010382 else if (0 == memcmp(&genie[0], "\x00\x50\xf2\x04", 4))
Jeff Johnson295189b2012-06-20 16:38:30 -070010383 {
10384 v_U16_t curAddIELen = pWextState->assocAddIE.length;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010385 hddLog (VOS_TRACE_LEVEL_INFO, "%s Set WPS IE(len %d)",
Jeff Johnson295189b2012-06-20 16:38:30 -070010386 __func__, eLen + 2);
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010387
Jeff Johnson295189b2012-06-20 16:38:30 -070010388 if( SIR_MAC_MAX_IE_LENGTH < (pWextState->assocAddIE.length + eLen) )
10389 {
Jeff Johnson902c9832012-12-10 14:28:09 -080010390 hddLog(VOS_TRACE_LEVEL_FATAL, "Cannot accommodate assocAddIE. "
10391 "Need bigger buffer space");
Jeff Johnson295189b2012-06-20 16:38:30 -070010392 VOS_ASSERT(0);
10393 return -ENOMEM;
10394 }
10395 // WSC IE is saved to Additional IE ; it should be accumulated to handle WPS IE + P2P IE
10396 memcpy( pWextState->assocAddIE.addIEdata + curAddIELen, genie - 2, eLen + 2);
10397 pWextState->assocAddIE.length += eLen + 2;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010398
Jeff Johnson295189b2012-06-20 16:38:30 -070010399 pWextState->roamProfile.bWPSAssociation = VOS_TRUE;
10400 pWextState->roamProfile.pAddIEAssoc = pWextState->assocAddIE.addIEdata;
10401 pWextState->roamProfile.nAddIEAssocLength = pWextState->assocAddIE.length;
10402 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010403 else if (0 == memcmp(&genie[0], "\x00\x50\xf2", 3))
10404 {
Jeff Johnson295189b2012-06-20 16:38:30 -070010405 hddLog (VOS_TRACE_LEVEL_INFO, "%s Set WPA IE (len %d)",__func__, eLen + 2);
10406 memset( pWextState->WPARSNIE, 0, MAX_WPA_RSN_IE_LEN );
10407 memcpy( pWextState->WPARSNIE, genie - 2, (eLen + 2) /*ie_len*/);
10408 pWextState->roamProfile.pWPAReqIE = pWextState->WPARSNIE;
10409 pWextState->roamProfile.nWPAReqIELength = eLen + 2;//ie_len;
10410 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010411 else if ( (0 == memcmp(&genie[0], P2P_OUI_TYPE,
Kiet Lam8da98992013-11-21 15:59:07 +053010412 P2P_OUI_TYPE_SIZE)))
Jeff Johnson295189b2012-06-20 16:38:30 -070010413 {
10414 v_U16_t curAddIELen = pWextState->assocAddIE.length;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010415 hddLog (VOS_TRACE_LEVEL_INFO, "%s Set P2P IE(len %d)",
Jeff Johnson295189b2012-06-20 16:38:30 -070010416 __func__, eLen + 2);
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010417
Jeff Johnson295189b2012-06-20 16:38:30 -070010418 if( SIR_MAC_MAX_IE_LENGTH < (pWextState->assocAddIE.length + eLen) )
10419 {
Jeff Johnson902c9832012-12-10 14:28:09 -080010420 hddLog(VOS_TRACE_LEVEL_FATAL, "Cannot accommodate assocAddIE "
10421 "Need bigger buffer space");
Jeff Johnson295189b2012-06-20 16:38:30 -070010422 VOS_ASSERT(0);
10423 return -ENOMEM;
10424 }
10425 // P2P IE is saved to Additional IE ; it should be accumulated to handle WPS IE + P2P IE
10426 memcpy( pWextState->assocAddIE.addIEdata + curAddIELen, genie - 2, eLen + 2);
10427 pWextState->assocAddIE.length += eLen + 2;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010428
Jeff Johnson295189b2012-06-20 16:38:30 -070010429 pWextState->roamProfile.pAddIEAssoc = pWextState->assocAddIE.addIEdata;
10430 pWextState->roamProfile.nAddIEAssocLength = pWextState->assocAddIE.length;
10431 }
Jeff Johnson295189b2012-06-20 16:38:30 -070010432#ifdef WLAN_FEATURE_WFD
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010433 else if ( (0 == memcmp(&genie[0], WFD_OUI_TYPE,
10434 WFD_OUI_TYPE_SIZE))
Jeff Johnson295189b2012-06-20 16:38:30 -070010435 /*Consider WFD IE, only for P2P Client */
10436 && (WLAN_HDD_P2P_CLIENT == pAdapter->device_mode) )
10437 {
10438 v_U16_t curAddIELen = pWextState->assocAddIE.length;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010439 hddLog (VOS_TRACE_LEVEL_INFO, "%s Set WFD IE(len %d)",
Jeff Johnson295189b2012-06-20 16:38:30 -070010440 __func__, eLen + 2);
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010441
Jeff Johnson295189b2012-06-20 16:38:30 -070010442 if( SIR_MAC_MAX_IE_LENGTH < (pWextState->assocAddIE.length + eLen) )
10443 {
Jeff Johnson902c9832012-12-10 14:28:09 -080010444 hddLog(VOS_TRACE_LEVEL_FATAL, "Cannot accommodate assocAddIE "
10445 "Need bigger buffer space");
Jeff Johnson295189b2012-06-20 16:38:30 -070010446 VOS_ASSERT(0);
10447 return -ENOMEM;
10448 }
10449 // WFD IE is saved to Additional IE ; it should be accumulated to handle
10450 // WPS IE + P2P IE + WFD IE
10451 memcpy( pWextState->assocAddIE.addIEdata + curAddIELen, genie - 2, eLen + 2);
10452 pWextState->assocAddIE.length += eLen + 2;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010453
Jeff Johnson295189b2012-06-20 16:38:30 -070010454 pWextState->roamProfile.pAddIEAssoc = pWextState->assocAddIE.addIEdata;
10455 pWextState->roamProfile.nAddIEAssocLength = pWextState->assocAddIE.length;
10456 }
10457#endif
Madan Mohan Koyyalamudief3b66e2012-10-11 14:29:42 -070010458 /* Appending HS 2.0 Indication Element in Assiciation Request */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010459 else if ( (0 == memcmp(&genie[0], HS20_OUI_TYPE,
Madan Mohan Koyyalamudi1bed5982012-10-22 14:38:06 -070010460 HS20_OUI_TYPE_SIZE)) )
10461 {
10462 v_U16_t curAddIELen = pWextState->assocAddIE.length;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010463 hddLog (VOS_TRACE_LEVEL_INFO, "%s Set HS20 IE(len %d)",
Madan Mohan Koyyalamudi1bed5982012-10-22 14:38:06 -070010464 __func__, eLen + 2);
Madan Mohan Koyyalamudief3b66e2012-10-11 14:29:42 -070010465
Madan Mohan Koyyalamudi1bed5982012-10-22 14:38:06 -070010466 if( SIR_MAC_MAX_IE_LENGTH < (pWextState->assocAddIE.length + eLen) )
10467 {
Jeff Johnson902c9832012-12-10 14:28:09 -080010468 hddLog(VOS_TRACE_LEVEL_FATAL, "Cannot accommodate assocAddIE "
10469 "Need bigger buffer space");
Madan Mohan Koyyalamudi1bed5982012-10-22 14:38:06 -070010470 VOS_ASSERT(0);
10471 return -ENOMEM;
10472 }
10473 memcpy( pWextState->assocAddIE.addIEdata + curAddIELen, genie - 2, eLen + 2);
10474 pWextState->assocAddIE.length += eLen + 2;
Madan Mohan Koyyalamudief3b66e2012-10-11 14:29:42 -070010475
Madan Mohan Koyyalamudi1bed5982012-10-22 14:38:06 -070010476 pWextState->roamProfile.pAddIEAssoc = pWextState->assocAddIE.addIEdata;
10477 pWextState->roamProfile.nAddIEAssocLength = pWextState->assocAddIE.length;
10478 }
Leela Venkata Kiran Kumar Reddy Chiralaf257bef2014-04-11 18:48:12 -070010479 /* Appending OSEN Information Element in Assiciation Request */
10480 else if ( (0 == memcmp(&genie[0], OSEN_OUI_TYPE,
10481 OSEN_OUI_TYPE_SIZE)) )
10482 {
10483 v_U16_t curAddIELen = pWextState->assocAddIE.length;
10484 hddLog (VOS_TRACE_LEVEL_INFO, "%s Set OSEN IE(len %d)",
10485 __func__, eLen + 2);
Madan Mohan Koyyalamudief3b66e2012-10-11 14:29:42 -070010486
Leela Venkata Kiran Kumar Reddy Chiralaf257bef2014-04-11 18:48:12 -070010487 if( SIR_MAC_MAX_IE_LENGTH < (pWextState->assocAddIE.length + eLen) )
10488 {
10489 hddLog(VOS_TRACE_LEVEL_FATAL, "Cannot accommodate assocAddIE "
10490 "Need bigger buffer space");
10491 VOS_ASSERT(0);
10492 return -ENOMEM;
10493 }
10494 memcpy( pWextState->assocAddIE.addIEdata + curAddIELen, genie - 2, eLen + 2);
10495 pWextState->assocAddIE.length += eLen + 2;
10496
10497 pWextState->roamProfile.bOSENAssociation = VOS_TRUE;
10498 pWextState->roamProfile.pAddIEAssoc = pWextState->assocAddIE.addIEdata;
10499 pWextState->roamProfile.nAddIEAssocLength = pWextState->assocAddIE.length;
10500 }
10501
10502 break;
Praveen Kumar Sirisilla7d68b7b2013-09-22 14:01:42 -070010503 if (WLAN_HDD_IBSS == pAdapter->device_mode) {
10504
10505 /* populating as ADDIE in beacon frames */
10506 if (ccmCfgSetStr(WLAN_HDD_GET_HAL_CTX(pAdapter),
10507 WNI_CFG_PROBE_RSP_BCN_ADDNIE_DATA, genie - 2, eLen + 2,
10508 NULL, eANI_BOOLEAN_FALSE)== eHAL_STATUS_SUCCESS)
10509 {
10510 if (ccmCfgSetInt(WLAN_HDD_GET_HAL_CTX(pAdapter),
10511 WNI_CFG_PROBE_RSP_BCN_ADDNIE_FLAG, 1,NULL,
10512 eANI_BOOLEAN_FALSE) == eHAL_STATUS_FAILURE)
10513 {
10514 hddLog(LOGE,
10515 "Coldn't pass "
10516 "WNI_CFG_PROBE_RSP_BCN_ADDNIE_FLAG to CCM");
10517 }
10518 }/* ccmCfgSetStr(,WNI_CFG_PROBE_RSP_BCN_ADDNIE_DATA, , )*/
10519 else
10520 hddLog(LOGE,
10521 "Could not pass on "
10522 "WNI_CFG_PROBE_RSP_BCN_ADDNIE_DATA to CCM");
10523
10524 /* IBSS mode doesn't contain params->proberesp_ies still
10525 beaconIE's need to be populated in probe response frames */
10526 if ( (NULL != (genie - 2)) && (0 != eLen + 2) )
10527 {
10528 u16 rem_probe_resp_ie_len = eLen + 2;
10529 u8 probe_rsp_ie_len[3] = {0};
10530 u8 counter = 0;
10531
10532 /* Check Probe Resp Length if it is greater then 255 then
10533 Store Probe Rsp IEs into WNI_CFG_PROBE_RSP_ADDNIE_DATA1
10534 & WNI_CFG_PROBE_RSP_ADDNIE_DATA2 CFG Variable As We are
10535 not able Store More then 255 bytes into One Variable */
10536
10537 while ((rem_probe_resp_ie_len > 0) && (counter < 3))
10538 {
10539 if (rem_probe_resp_ie_len > MAX_CFG_STRING_LEN)
10540 {
10541 probe_rsp_ie_len[counter++] = MAX_CFG_STRING_LEN;
10542 rem_probe_resp_ie_len -= MAX_CFG_STRING_LEN;
10543 }
10544 else
10545 {
10546 probe_rsp_ie_len[counter++] = rem_probe_resp_ie_len;
10547 rem_probe_resp_ie_len = 0;
10548 }
10549 }
10550
10551 rem_probe_resp_ie_len = 0;
10552
10553 if (probe_rsp_ie_len[0] > 0)
10554 {
10555 if (ccmCfgSetStr(WLAN_HDD_GET_HAL_CTX(pAdapter),
10556 WNI_CFG_PROBE_RSP_ADDNIE_DATA1,
10557 (tANI_U8*)(genie - 2),
10558 probe_rsp_ie_len[0], NULL,
10559 eANI_BOOLEAN_FALSE)
10560 == eHAL_STATUS_FAILURE)
10561 {
10562 hddLog(LOGE,
10563 "Could not pass"
10564 "on WNI_CFG_PROBE_RSP_ADDNIE_DATA1 to CCM");
10565 }
10566 rem_probe_resp_ie_len += probe_rsp_ie_len[0];
10567 }
10568
10569 if (probe_rsp_ie_len[1] > 0)
10570 {
10571 if (ccmCfgSetStr(WLAN_HDD_GET_HAL_CTX(pAdapter),
10572 WNI_CFG_PROBE_RSP_ADDNIE_DATA2,
10573 (tANI_U8*)(genie - (2 + rem_probe_resp_ie_len)),
10574 probe_rsp_ie_len[1], NULL,
10575 eANI_BOOLEAN_FALSE)
10576 == eHAL_STATUS_FAILURE)
10577 {
10578 hddLog(LOGE,
10579 "Could not pass"
10580 "on WNI_CFG_PROBE_RSP_ADDNIE_DATA2 to CCM");
10581 }
10582 rem_probe_resp_ie_len += probe_rsp_ie_len[1];
10583 }
10584
10585 if (probe_rsp_ie_len[2] > 0)
10586 {
10587 if (ccmCfgSetStr(WLAN_HDD_GET_HAL_CTX(pAdapter),
10588 WNI_CFG_PROBE_RSP_ADDNIE_DATA3,
10589 (tANI_U8*)(genie - (2 + rem_probe_resp_ie_len)),
10590 probe_rsp_ie_len[2], NULL,
10591 eANI_BOOLEAN_FALSE)
10592 == eHAL_STATUS_FAILURE)
10593 {
10594 hddLog(LOGE,
10595 "Could not pass"
10596 "on WNI_CFG_PROBE_RSP_ADDNIE_DATA3 to CCM");
10597 }
10598 rem_probe_resp_ie_len += probe_rsp_ie_len[2];
10599 }
10600
10601 if (ccmCfgSetInt(WLAN_HDD_GET_HAL_CTX(pAdapter),
10602 WNI_CFG_PROBE_RSP_ADDNIE_FLAG, 1,NULL,
10603 eANI_BOOLEAN_FALSE) == eHAL_STATUS_FAILURE)
10604 {
10605 hddLog(LOGE,
10606 "Could not pass"
10607 "on WNI_CFG_PROBE_RSP_ADDNIE_FLAG to CCM");
10608 }
10609 }
10610 else
10611 {
10612 // Reset WNI_CFG_PROBE_RSP Flags
10613 wlan_hdd_reset_prob_rspies(pAdapter);
10614
10615 hddLog(VOS_TRACE_LEVEL_INFO,
10616 "%s: No Probe Response IE received in set beacon",
10617 __func__);
10618 }
10619 } /* end of if (WLAN_HDD_IBSS == pAdapter->device_mode) */
Jeff Johnson295189b2012-06-20 16:38:30 -070010620 break;
10621 case DOT11F_EID_RSN:
10622 hddLog (VOS_TRACE_LEVEL_INFO, "%s Set RSN IE(len %d)",__func__, eLen + 2);
10623 memset( pWextState->WPARSNIE, 0, MAX_WPA_RSN_IE_LEN );
10624 memcpy( pWextState->WPARSNIE, genie - 2, (eLen + 2)/*ie_len*/);
10625 pWextState->roamProfile.pRSNReqIE = pWextState->WPARSNIE;
10626 pWextState->roamProfile.nRSNReqIELength = eLen + 2; //ie_len;
10627 break;
Madan Mohan Koyyalamudief3b66e2012-10-11 14:29:42 -070010628 /* Appending Extended Capabilities with Interworking bit set in Assoc Req */
10629 case DOT11F_EID_EXTCAP:
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010630 {
Madan Mohan Koyyalamudief3b66e2012-10-11 14:29:42 -070010631 v_U16_t curAddIELen = pWextState->assocAddIE.length;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010632 hddLog (VOS_TRACE_LEVEL_INFO, "%s Set Extended CAPS IE(len %d)",
Madan Mohan Koyyalamudief3b66e2012-10-11 14:29:42 -070010633 __func__, eLen + 2);
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010634
Madan Mohan Koyyalamudief3b66e2012-10-11 14:29:42 -070010635 if( SIR_MAC_MAX_IE_LENGTH < (pWextState->assocAddIE.length + eLen) )
10636 {
Jeff Johnson902c9832012-12-10 14:28:09 -080010637 hddLog(VOS_TRACE_LEVEL_FATAL, "Cannot accommodate assocAddIE "
10638 "Need bigger buffer space");
Madan Mohan Koyyalamudief3b66e2012-10-11 14:29:42 -070010639 VOS_ASSERT(0);
10640 return -ENOMEM;
10641 }
10642 memcpy( pWextState->assocAddIE.addIEdata + curAddIELen, genie - 2, eLen + 2);
10643 pWextState->assocAddIE.length += eLen + 2;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010644
Madan Mohan Koyyalamudief3b66e2012-10-11 14:29:42 -070010645 pWextState->roamProfile.pAddIEAssoc = pWextState->assocAddIE.addIEdata;
10646 pWextState->roamProfile.nAddIEAssocLength = pWextState->assocAddIE.length;
10647 break;
10648 }
Jeff Johnson295189b2012-06-20 16:38:30 -070010649#ifdef FEATURE_WLAN_WAPI
10650 case WLAN_EID_WAPI:
10651 pAdapter->wapi_info.nWapiMode = 1; //Setting WAPI Mode to ON=1
Jeff Johnson0299d0a2013-10-30 12:37:43 -070010652 hddLog(VOS_TRACE_LEVEL_INFO, "WAPI MODE IS %u",
Jeff Johnson295189b2012-06-20 16:38:30 -070010653 pAdapter->wapi_info.nWapiMode);
10654 tmp = (u16 *)ie;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010655 tmp = tmp + 2; // Skip element Id and Len, Version
Jeff Johnson295189b2012-06-20 16:38:30 -070010656 akmsuiteCount = WPA_GET_LE16(tmp);
10657 tmp = tmp + 1;
10658 akmlist = (int *)(tmp);
10659 if(akmsuiteCount <= MAX_NUM_AKM_SUITES)
10660 {
10661 memcpy(akmsuite, akmlist, (4*akmsuiteCount));
10662 }
10663 else
10664 {
Arif Hussain6d2a3322013-11-17 19:50:10 -080010665 hddLog(VOS_TRACE_LEVEL_FATAL, "Invalid akmSuite count");
Jeff Johnson295189b2012-06-20 16:38:30 -070010666 VOS_ASSERT(0);
10667 return -EINVAL;
10668 }
10669
10670 if (WAPI_PSK_AKM_SUITE == akmsuite[0])
10671 {
10672 hddLog(VOS_TRACE_LEVEL_INFO, "%s: WAPI AUTH MODE SET TO PSK",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -070010673 __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -070010674 pAdapter->wapi_info.wapiAuthMode = WAPI_AUTH_MODE_PSK;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010675 }
Jeff Johnson295189b2012-06-20 16:38:30 -070010676 if (WAPI_CERT_AKM_SUITE == akmsuite[0])
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010677 {
Jeff Johnson295189b2012-06-20 16:38:30 -070010678 hddLog(VOS_TRACE_LEVEL_INFO, "%s: WAPI AUTH MODE SET TO CERTIFICATE",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -070010679 __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -070010680 pAdapter->wapi_info.wapiAuthMode = WAPI_AUTH_MODE_CERT;
10681 }
10682 break;
10683#endif
10684 default:
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010685 hddLog (VOS_TRACE_LEVEL_ERROR,
Jeff Johnson295189b2012-06-20 16:38:30 -070010686 "%s Set UNKNOWN IE %X", __func__, elementId);
Madan Mohan Koyyalamudief3b66e2012-10-11 14:29:42 -070010687 /* when Unknown IE is received we should break and continue
10688 * to the next IE in the buffer instead we were returning
10689 * so changing this to break */
10690 break;
Jeff Johnson295189b2012-06-20 16:38:30 -070010691 }
10692 genie += eLen;
10693 remLen -= eLen;
10694 }
10695 EXIT();
10696 return 0;
10697}
10698
10699/*
Gopichand Nakkala18f0c262013-05-07 23:25:08 +053010700 * FUNCTION: hdd_isWPAIEPresent
10701 * Parse the received IE to find the WPA IE
10702 *
10703 */
10704static bool hdd_isWPAIEPresent(u8 *ie, u8 ie_len)
10705{
10706 v_U8_t eLen = 0;
10707 v_U16_t remLen = ie_len;
10708 v_U8_t elementId = 0;
10709
10710 while (remLen >= 2)
10711 {
10712 elementId = *ie++;
10713 eLen = *ie++;
10714 remLen -= 2;
10715 if (eLen > remLen)
10716 {
10717 hddLog(VOS_TRACE_LEVEL_ERROR,
10718 "%s: IE length is wrong %d", __func__, eLen);
10719 return FALSE;
10720 }
10721 if ((elementId == DOT11F_EID_WPA) && (remLen > 5))
10722 {
10723 /* OUI - 0x00 0X50 0XF2
10724 WPA Information Element - 0x01
10725 WPA version - 0x01*/
10726 if (0 == memcmp(&ie[0], "\x00\x50\xf2\x01\x01", 5))
10727 return TRUE;
10728 }
10729 ie += eLen;
10730 remLen -= eLen;
10731 }
10732 return FALSE;
10733}
10734
10735/*
Jeff Johnson295189b2012-06-20 16:38:30 -070010736 * FUNCTION: wlan_hdd_cfg80211_set_privacy
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010737 * This function is used to initialize the security
Jeff Johnson295189b2012-06-20 16:38:30 -070010738 * parameters during connect operation.
10739 */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010740int wlan_hdd_cfg80211_set_privacy( hdd_adapter_t *pAdapter,
Jeff Johnson295189b2012-06-20 16:38:30 -070010741 struct cfg80211_connect_params *req
10742 )
10743{
10744 int status = 0;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010745 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
Jeff Johnson295189b2012-06-20 16:38:30 -070010746 ENTER();
10747
10748 /*set wpa version*/
10749 pWextState->wpaVersion = IW_AUTH_WPA_VERSION_DISABLED;
10750
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010751 if (req->crypto.wpa_versions)
Jeff Johnson295189b2012-06-20 16:38:30 -070010752 {
Gopichand Nakkala781ded42013-06-28 12:10:45 +053010753 if (NL80211_WPA_VERSION_1 == req->crypto.wpa_versions)
Jeff Johnson295189b2012-06-20 16:38:30 -070010754 {
10755 pWextState->wpaVersion = IW_AUTH_WPA_VERSION_WPA;
10756 }
10757 else if (NL80211_WPA_VERSION_2 == req->crypto.wpa_versions)
10758 {
10759 pWextState->wpaVersion = IW_AUTH_WPA_VERSION_WPA2;
10760 }
10761 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010762
10763 hddLog(VOS_TRACE_LEVEL_INFO, "%s: set wpa version to %d", __func__,
Jeff Johnson295189b2012-06-20 16:38:30 -070010764 pWextState->wpaVersion);
10765
10766 /*set authentication type*/
10767 status = wlan_hdd_cfg80211_set_auth_type(pAdapter, req->auth_type);
10768
10769 if (0 > status)
10770 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010771 hddLog(VOS_TRACE_LEVEL_ERROR,
Jeff Johnson295189b2012-06-20 16:38:30 -070010772 "%s: failed to set authentication type ", __func__);
10773 return status;
10774 }
10775
10776 /*set key mgmt type*/
10777 if (req->crypto.n_akm_suites)
10778 {
10779 status = wlan_hdd_set_akm_suite(pAdapter, req->crypto.akm_suites[0]);
10780 if (0 > status)
10781 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010782 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: failed to set akm suite",
Jeff Johnson295189b2012-06-20 16:38:30 -070010783 __func__);
10784 return status;
10785 }
10786 }
10787
10788 /*set pairwise cipher type*/
10789 if (req->crypto.n_ciphers_pairwise)
10790 {
10791 status = wlan_hdd_cfg80211_set_cipher(pAdapter,
10792 req->crypto.ciphers_pairwise[0], true);
10793 if (0 > status)
10794 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010795 hddLog(VOS_TRACE_LEVEL_ERROR,
Jeff Johnson295189b2012-06-20 16:38:30 -070010796 "%s: failed to set unicast cipher type", __func__);
10797 return status;
10798 }
10799 }
10800 else
10801 {
10802 /*Reset previous cipher suite to none*/
10803 status = wlan_hdd_cfg80211_set_cipher(pAdapter, 0, true);
10804 if (0 > status)
10805 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010806 hddLog(VOS_TRACE_LEVEL_ERROR,
Jeff Johnson295189b2012-06-20 16:38:30 -070010807 "%s: failed to set unicast cipher type", __func__);
10808 return status;
10809 }
10810 }
10811
10812 /*set group cipher type*/
10813 status = wlan_hdd_cfg80211_set_cipher(pAdapter, req->crypto.cipher_group,
10814 false);
10815
10816 if (0 > status)
10817 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010818 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: failed to set mcast cipher type",
Jeff Johnson295189b2012-06-20 16:38:30 -070010819 __func__);
10820 return status;
10821 }
10822
Chet Lanctot186b5732013-03-18 10:26:30 -070010823#ifdef WLAN_FEATURE_11W
10824 pWextState->roamProfile.MFPEnabled = (req->mfp == NL80211_MFP_REQUIRED);
10825#endif
10826
Jeff Johnson295189b2012-06-20 16:38:30 -070010827 /*parse WPA/RSN IE, and set the correspoing fileds in Roam profile*/
10828 if (req->ie_len)
10829 {
10830 status = wlan_hdd_cfg80211_set_ie(pAdapter, req->ie, req->ie_len);
10831 if ( 0 > status)
10832 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010833 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: failed to parse the WPA/RSN IE",
Jeff Johnson295189b2012-06-20 16:38:30 -070010834 __func__);
10835 return status;
10836 }
10837 }
10838
10839 /*incase of WEP set default key information*/
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010840 if (req->key && req->key_len)
Jeff Johnson295189b2012-06-20 16:38:30 -070010841 {
10842 if ( (WLAN_CIPHER_SUITE_WEP40 == req->crypto.ciphers_pairwise[0])
10843 || (WLAN_CIPHER_SUITE_WEP104 == req->crypto.ciphers_pairwise[0])
10844 )
10845 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010846 if ( IW_AUTH_KEY_MGMT_802_1X
Jeff Johnson295189b2012-06-20 16:38:30 -070010847 == (pWextState->authKeyMgmt & IW_AUTH_KEY_MGMT_802_1X ))
10848 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010849 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Dynamic WEP not supported",
Jeff Johnson295189b2012-06-20 16:38:30 -070010850 __func__);
10851 return -EOPNOTSUPP;
10852 }
10853 else
10854 {
10855 u8 key_len = req->key_len;
10856 u8 key_idx = req->key_idx;
10857
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010858 if ((eCSR_SECURITY_WEP_KEYSIZE_MAX_BYTES >= key_len)
Jeff Johnson295189b2012-06-20 16:38:30 -070010859 && (CSR_MAX_NUM_KEY > key_idx)
10860 )
10861 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010862 hddLog(VOS_TRACE_LEVEL_INFO,
10863 "%s: setting default wep key, key_idx = %hu key_len %hu",
Jeff Johnson295189b2012-06-20 16:38:30 -070010864 __func__, key_idx, key_len);
10865 vos_mem_copy(
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010866 &pWextState->roamProfile.Keys.KeyMaterial[key_idx][0],
Jeff Johnson295189b2012-06-20 16:38:30 -070010867 req->key, key_len);
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010868 pWextState->roamProfile.Keys.KeyLength[key_idx] =
Jeff Johnson295189b2012-06-20 16:38:30 -070010869 (u8)key_len;
10870 pWextState->roamProfile.Keys.defaultIndex = (u8)key_idx;
10871 }
10872 }
10873 }
10874 }
10875
10876 return status;
10877}
10878
10879/*
Vinay Krishna Eranna21042322014-01-08 19:21:39 +053010880 * FUNCTION: wlan_hdd_try_disconnect
10881 * This function is used to disconnect from previous
10882 * connection
10883 */
10884static int wlan_hdd_try_disconnect( hdd_adapter_t *pAdapter )
10885{
10886 long ret = 0;
10887 hdd_station_ctx_t *pHddStaCtx;
10888 eMib_dot11DesiredBssType connectedBssType;
10889
10890 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
10891
10892 hdd_connGetConnectedBssType(pHddStaCtx,&connectedBssType );
10893
10894 if((eMib_dot11DesiredBssType_independent == connectedBssType) ||
10895 (eConnectionState_Associated == pHddStaCtx->conn_info.connState) ||
10896 (eConnectionState_IbssConnected == pHddStaCtx->conn_info.connState))
10897 {
10898 /* Issue disconnect to CSR */
10899 INIT_COMPLETION(pAdapter->disconnect_comp_var);
10900 if( eHAL_STATUS_SUCCESS ==
10901 sme_RoamDisconnect( WLAN_HDD_GET_HAL_CTX(pAdapter),
10902 pAdapter->sessionId,
10903 eCSR_DISCONNECT_REASON_UNSPECIFIED ) )
10904 {
10905 ret = wait_for_completion_interruptible_timeout(
10906 &pAdapter->disconnect_comp_var,
10907 msecs_to_jiffies(WLAN_WAIT_TIME_DISCONNECT));
10908 if (0 >= ret)
10909 {
10910 hddLog(LOGE, FL("Failed to receive disconnect event"));
10911 return -EALREADY;
10912 }
10913 }
10914 }
10915 else if(eConnectionState_Disconnecting == pHddStaCtx->conn_info.connState)
10916 {
10917 ret = wait_for_completion_interruptible_timeout(
10918 &pAdapter->disconnect_comp_var,
10919 msecs_to_jiffies(WLAN_WAIT_TIME_DISCONNECT));
10920 if (0 >= ret)
10921 {
10922 hddLog(LOGE, FL("Failed to receive disconnect event"));
10923 return -EALREADY;
10924 }
10925 }
10926
10927 return 0;
10928}
10929
10930/*
Agarwal Ashish51325b52014-06-16 16:50:49 +053010931 * FUNCTION: __wlan_hdd_cfg80211_connect
10932 * This function is used to start the association process
Jeff Johnson295189b2012-06-20 16:38:30 -070010933 */
Mahesh A Saptasagarfafb7fe2014-05-16 13:19:37 +053010934static int __wlan_hdd_cfg80211_connect( struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -070010935 struct net_device *ndev,
10936 struct cfg80211_connect_params *req
10937 )
10938{
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053010939 int status;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010940 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( ndev );
Jeff Johnson295189b2012-06-20 16:38:30 -070010941 VOS_STATUS exitbmpsStatus = VOS_STATUS_E_INVAL;
Sushant Kaushikba6764e2014-06-30 19:52:09 +053010942 hdd_context_t *pHddCtx = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -070010943
10944 ENTER();
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053010945
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053010946 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
10947 TRACE_CODE_HDD_CFG80211_CONNECT,
10948 pAdapter->sessionId, pAdapter->device_mode));
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010949 hddLog(VOS_TRACE_LEVEL_INFO,
Sushant Kaushik8bc7df22014-04-09 17:55:29 +053010950 "%s: device_mode = %s (%d)", __func__,
10951 hdd_device_modetoString(pAdapter->device_mode),
10952 pAdapter->device_mode);
Jeff Johnson295189b2012-06-20 16:38:30 -070010953
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053010954 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Rajesh Chauhana0516c62014-01-30 16:11:18 -080010955 if (!pHddCtx)
10956 {
10957 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
10958 "%s: HDD context is null", __func__);
Agarwal Ashish51325b52014-06-16 16:50:49 +053010959 return -EINVAL;
Rajesh Chauhana0516c62014-01-30 16:11:18 -080010960 }
10961
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053010962 status = wlan_hdd_validate_context(pHddCtx);
10963
10964 if (0 != status)
Jeff Johnson295189b2012-06-20 16:38:30 -070010965 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053010966 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
10967 "%s: HDD context is not valid", __func__);
10968 return status;
Jeff Johnson295189b2012-06-20 16:38:30 -070010969 }
10970
Agarwal Ashish51325b52014-06-16 16:50:49 +053010971 if (vos_max_concurrent_connections_reached()) {
10972 hddLog(VOS_TRACE_LEVEL_INFO, FL("Reached max concurrent connections"));
10973 return -ECONNREFUSED;
10974 }
10975
Jeff Johnson295189b2012-06-20 16:38:30 -070010976#ifdef WLAN_BTAMP_FEATURE
10977 //Infra connect not supported when AMP traffic is on.
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010978 if( VOS_TRUE == WLANBAP_AmpSessionOn() )
Jeff Johnson295189b2012-06-20 16:38:30 -070010979 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010980 hddLog(VOS_TRACE_LEVEL_ERROR,
Jeff Johnson295189b2012-06-20 16:38:30 -070010981 "%s: No connection when AMP is on", __func__);
Madan Mohan Koyyalamudicae253a2012-11-06 19:10:35 -080010982 return -ECONNREFUSED;
Jeff Johnson295189b2012-06-20 16:38:30 -070010983 }
10984#endif
Vinay Krishna Eranna21042322014-01-08 19:21:39 +053010985
10986 //If Device Mode is Station Concurrent Sessions Exit BMps
10987 //P2P Mode will be taken care in Open/close adapter
10988 if((WLAN_HDD_INFRA_STATION == pAdapter->device_mode) &&
Agarwal Ashish51325b52014-06-16 16:50:49 +053010989 (vos_concurrent_open_sessions_running())) {
10990 exitbmpsStatus = hdd_disable_bmps_imps(pHddCtx,
10991 WLAN_HDD_INFRA_STATION);
Vinay Krishna Eranna21042322014-01-08 19:21:39 +053010992 }
10993
10994 /*Try disconnecting if already in connected state*/
10995 status = wlan_hdd_try_disconnect(pAdapter);
10996 if ( 0 > status)
10997 {
10998 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Failed to disconnect the existing"
10999 " connection"));
11000 return -EALREADY;
11001 }
11002
Jeff Johnson295189b2012-06-20 16:38:30 -070011003 /*initialise security parameters*/
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011004 status = wlan_hdd_cfg80211_set_privacy(pAdapter, req);
Jeff Johnson295189b2012-06-20 16:38:30 -070011005
11006 if ( 0 > status)
11007 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011008 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: failed to set security params",
Jeff Johnson295189b2012-06-20 16:38:30 -070011009 __func__);
11010 return status;
11011 }
Mohit Khanna765234a2012-09-11 15:08:35 -070011012 if ( req->channel )
11013 {
11014 status = wlan_hdd_cfg80211_connect_start(pAdapter, req->ssid,
11015 req->ssid_len, req->bssid,
11016 req->channel->hw_value);
11017 }
11018 else
11019 {
11020 status = wlan_hdd_cfg80211_connect_start(pAdapter, req->ssid,
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053011021 req->ssid_len, req->bssid, 0);
Mohit Khanna765234a2012-09-11 15:08:35 -070011022 }
Jeff Johnson295189b2012-06-20 16:38:30 -070011023
11024 if (0 > status)
11025 {
11026 //ReEnable BMPS if disabled
11027 if((VOS_STATUS_SUCCESS == exitbmpsStatus) &&
11028 (NULL != pHddCtx))
11029 {
Gopichand Nakkalaa2fe5b02013-06-06 16:32:28 +053011030 if (pHddCtx->hdd_wlan_suspended)
11031 {
11032 hdd_set_pwrparams(pHddCtx);
11033 }
Jeff Johnson295189b2012-06-20 16:38:30 -070011034 //ReEnable Bmps and Imps back
11035 hdd_enable_bmps_imps(pHddCtx);
11036 }
Agarwal Ashish51325b52014-06-16 16:50:49 +053011037 hddLog(VOS_TRACE_LEVEL_ERROR, FL("connect failed"));
Jeff Johnson295189b2012-06-20 16:38:30 -070011038 return status;
11039 }
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053011040 pHddCtx->isAmpAllowed = VOS_FALSE;
Jeff Johnson295189b2012-06-20 16:38:30 -070011041 EXIT();
11042 return status;
11043}
11044
Mahesh A Saptasagarfafb7fe2014-05-16 13:19:37 +053011045static int wlan_hdd_cfg80211_connect( struct wiphy *wiphy,
11046 struct net_device *ndev,
11047 struct cfg80211_connect_params *req)
11048{
11049 int ret;
11050 vos_ssr_protect(__func__);
11051 ret = __wlan_hdd_cfg80211_connect(wiphy, ndev, req);
11052 vos_ssr_unprotect(__func__);
11053
11054 return ret;
11055}
Jeff Johnson295189b2012-06-20 16:38:30 -070011056
11057/*
Gopichand Nakkala78a6c812013-05-13 16:39:49 +053011058 * FUNCTION: wlan_hdd_disconnect
11059 * This function is used to issue a disconnect request to SME
11060 */
11061int wlan_hdd_disconnect( hdd_adapter_t *pAdapter, u16 reason )
11062{
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053011063 int status;
Gopichand Nakkala78a6c812013-05-13 16:39:49 +053011064 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053011065 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Abhishek Singhdc2bfd42014-06-19 17:59:05 +053011066 long ret;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053011067
11068 status = wlan_hdd_validate_context(pHddCtx);
11069
11070 if (0 != status)
11071 {
11072 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
11073 "%s: HDD context is not valid", __func__);
11074 return status;
11075 }
11076
11077 pHddCtx->isAmpAllowed = VOS_TRUE;
Agarwal Ashishc65b5ca2014-07-28 21:02:57 +053011078
Agarwal Ashish47d18112014-08-04 19:55:07 +053011079 /* Need to apply spin lock before decreasing active sessions
11080 * as there can be chance for double decrement if context switch
11081 * Calls hdd_DisConnectHandler.
11082 */
11083
11084 spin_lock_bh(&pAdapter->lock_for_active_session);
Agarwal Ashishc65b5ca2014-07-28 21:02:57 +053011085 if (eConnectionState_Associated == pHddStaCtx->conn_info.connState)
11086 {
Agarwal Ashishc65b5ca2014-07-28 21:02:57 +053011087 wlan_hdd_decr_active_session(pHddCtx, pAdapter->device_mode);
11088 }
Agarwal Ashish47d18112014-08-04 19:55:07 +053011089 hdd_connSetConnectionState( pHddStaCtx, eConnectionState_Disconnecting );
11090 spin_unlock_bh(&pAdapter->lock_for_active_session);
Agarwal Ashishc65b5ca2014-07-28 21:02:57 +053011091
Abhishek Singhf4669da2014-05-26 15:07:49 +053011092 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Agarwal Ashish47d18112014-08-04 19:55:07 +053011093 FL( "Set HDD connState to eConnectionState_Disconnecting" ));
11094
Gopichand Nakkala78a6c812013-05-13 16:39:49 +053011095 INIT_COMPLETION(pAdapter->disconnect_comp_var);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053011096
Mihir Shete182a0b22014-08-18 16:08:48 +053011097 /*
11098 * stop tx queues before deleting STA/BSS context from the firmware.
11099 * tx has to be disabled because the firmware can get busy dropping
11100 * the tx frames after BSS/STA has been deleted and will not send
11101 * back a response resulting in WDI timeout
11102 */
11103 netif_tx_disable(pAdapter->dev);
11104 netif_carrier_off(pAdapter->dev);
Arun Kumar Khandavalli94a2bb02013-12-28 19:17:25 +053011105
Mihir Shete182a0b22014-08-18 16:08:48 +053011106 /*issue disconnect*/
Gopichand Nakkala78a6c812013-05-13 16:39:49 +053011107 status = sme_RoamDisconnect( WLAN_HDD_GET_HAL_CTX(pAdapter),
11108 pAdapter->sessionId, reason);
Abhishek Singhdc2bfd42014-06-19 17:59:05 +053011109 if(eHAL_STATUS_CMD_NOT_QUEUED == status)
11110 {
11111 hddLog(VOS_TRACE_LEVEL_INFO,
11112 FL("status = %d, already disconnected"),
11113 (int)status );
Gopichand Nakkala78a6c812013-05-13 16:39:49 +053011114
Abhishek Singhdc2bfd42014-06-19 17:59:05 +053011115 }
11116 else if ( 0 != status )
Gopichand Nakkala78a6c812013-05-13 16:39:49 +053011117 {
11118 hddLog(VOS_TRACE_LEVEL_ERROR,
Arif Hussain6d2a3322013-11-17 19:50:10 -080011119 "%s csrRoamDisconnect failure, returned %d",
Gopichand Nakkala78a6c812013-05-13 16:39:49 +053011120 __func__, (int)status );
11121 return -EINVAL;
11122 }
Abhishek Singhdc2bfd42014-06-19 17:59:05 +053011123 ret = wait_for_completion_interruptible_timeout(
Gopichand Nakkala78a6c812013-05-13 16:39:49 +053011124 &pAdapter->disconnect_comp_var,
11125 msecs_to_jiffies(WLAN_WAIT_TIME_DISCONNECT));
Abhishek Singhdc2bfd42014-06-19 17:59:05 +053011126 if (!ret && ( eHAL_STATUS_CMD_NOT_QUEUED != status ))
c_hpothu6ff1c3c2013-10-01 19:01:57 +053011127 {
11128 hddLog(VOS_TRACE_LEVEL_ERROR,
Mahesh A Saptasagar05a357e2014-02-26 16:28:06 +053011129 "%s: Failed to disconnect, timed out", __func__);
11130 return -ETIMEDOUT;
11131 }
Abhishek Singhdc2bfd42014-06-19 17:59:05 +053011132 else if (ret == -ERESTARTSYS)
Mahesh A Saptasagar05a357e2014-02-26 16:28:06 +053011133 {
11134 hddLog(VOS_TRACE_LEVEL_ERROR,
11135 "%s: Failed to disconnect, wait interrupted", __func__);
Abhishek Singhdc2bfd42014-06-19 17:59:05 +053011136 return ret;
c_hpothu6ff1c3c2013-10-01 19:01:57 +053011137 }
Abhishek Singhdc2bfd42014-06-19 17:59:05 +053011138 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
11139 FL("Set HDD connState to eConnectionState_NotConnected"));
11140 pHddStaCtx->conn_info.connState = eConnectionState_NotConnected;
11141
Mahesh A Saptasagar05a357e2014-02-26 16:28:06 +053011142 return 0;
Gopichand Nakkala78a6c812013-05-13 16:39:49 +053011143}
11144
11145
11146/*
Mahesh A Saptasagarfafb7fe2014-05-16 13:19:37 +053011147 * FUNCTION: __wlan_hdd_cfg80211_disconnect
Jeff Johnson295189b2012-06-20 16:38:30 -070011148 * This function is used to issue a disconnect request to SME
11149 */
Mahesh A Saptasagarfafb7fe2014-05-16 13:19:37 +053011150static int __wlan_hdd_cfg80211_disconnect( struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -070011151 struct net_device *dev,
11152 u16 reason
11153 )
11154{
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011155 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( dev );
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053011156 tCsrRoamProfile *pRoamProfile =
11157 &(WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter))->roamProfile;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053011158 int status;
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053011159 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
11160 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Gopichand Nakkalaaa353782013-05-17 20:36:22 +053011161#ifdef FEATURE_WLAN_TDLS
Gopichand Nakkala2a0a1572013-02-10 21:39:16 -080011162 tANI_U8 staIdx;
11163#endif
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011164
Jeff Johnson295189b2012-06-20 16:38:30 -070011165 ENTER();
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053011166
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053011167 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
11168 TRACE_CODE_HDD_CFG80211_DISCONNECT,
11169 pAdapter->sessionId, reason));
Sushant Kaushik8bc7df22014-04-09 17:55:29 +053011170 hddLog(VOS_TRACE_LEVEL_INFO, "%s: device_mode = %s(%d)",
11171 __func__, hdd_device_modetoString(pAdapter->device_mode),
11172 pAdapter->device_mode);
Jeff Johnson295189b2012-06-20 16:38:30 -070011173
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011174 hddLog(VOS_TRACE_LEVEL_INFO, "%s: Disconnect called with reason code %d",
11175 __func__, reason);
Jeff Johnson295189b2012-06-20 16:38:30 -070011176
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053011177 status = wlan_hdd_validate_context(pHddCtx);
11178
11179 if (0 != status)
Jeff Johnson295189b2012-06-20 16:38:30 -070011180 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053011181 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
11182 "%s: HDD context is not valid", __func__);
11183 return status;
Jeff Johnson295189b2012-06-20 16:38:30 -070011184 }
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053011185
Jeff Johnson295189b2012-06-20 16:38:30 -070011186 if (NULL != pRoamProfile)
11187 {
11188 /*issue disconnect request to SME, if station is in connected state*/
Mahesh A Saptasagar280fd5a2013-12-05 15:38:31 +053011189 if ((pHddStaCtx->conn_info.connState == eConnectionState_Associated) ||
11190 (pHddStaCtx->conn_info.connState == eConnectionState_Connecting))
Jeff Johnson295189b2012-06-20 16:38:30 -070011191 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011192 eCsrRoamDisconnectReason reasonCode =
Jeff Johnson295189b2012-06-20 16:38:30 -070011193 eCSR_DISCONNECT_REASON_UNSPECIFIED;
Gopichand Nakkalaaa353782013-05-17 20:36:22 +053011194 hdd_scaninfo_t *pScanInfo;
Jeff Johnson295189b2012-06-20 16:38:30 -070011195 switch(reason)
11196 {
11197 case WLAN_REASON_MIC_FAILURE:
11198 reasonCode = eCSR_DISCONNECT_REASON_MIC_ERROR;
11199 break;
11200
11201 case WLAN_REASON_DISASSOC_DUE_TO_INACTIVITY:
11202 case WLAN_REASON_DISASSOC_AP_BUSY:
11203 case WLAN_REASON_CLASS3_FRAME_FROM_NONASSOC_STA:
11204 reasonCode = eCSR_DISCONNECT_REASON_DISASSOC;
11205 break;
11206
11207 case WLAN_REASON_PREV_AUTH_NOT_VALID:
11208 case WLAN_REASON_CLASS2_FRAME_FROM_NONAUTH_STA:
Abhishek Singhc3269a52014-05-21 17:22:24 +053011209 case WLAN_REASON_DEAUTH_LEAVING:
Jeff Johnson295189b2012-06-20 16:38:30 -070011210 reasonCode = eCSR_DISCONNECT_REASON_DEAUTH;
11211 break;
11212
Jeff Johnson295189b2012-06-20 16:38:30 -070011213 default:
11214 reasonCode = eCSR_DISCONNECT_REASON_UNSPECIFIED;
11215 break;
11216 }
Gopichand Nakkalaaa353782013-05-17 20:36:22 +053011217 pScanInfo = &pHddCtx->scan_info;
11218 if (pScanInfo->mScanPending)
11219 {
Srinivas, Dasari138af4f2014-02-07 11:13:45 +053011220 hddLog(VOS_TRACE_LEVEL_INFO, "Disconnect is in progress, "
Gopichand Nakkalaaa353782013-05-17 20:36:22 +053011221 "Aborting Scan");
Kaushik, Sushant4975a572014-10-21 16:07:48 +053011222 hdd_abort_mac_scan(pHddCtx, pScanInfo->sessionId,
Srinivas, Dasari138af4f2014-02-07 11:13:45 +053011223 eCSR_SCAN_ABORT_DEFAULT);
Gopichand Nakkalaaa353782013-05-17 20:36:22 +053011224 }
Jeff Johnson295189b2012-06-20 16:38:30 -070011225
Gopichand Nakkala2a0a1572013-02-10 21:39:16 -080011226#ifdef FEATURE_WLAN_TDLS
11227 /* First clean up the tdls peers if any */
Gopichand Nakkala4327a152013-03-04 23:22:42 -080011228 for (staIdx = 0 ; staIdx < HDD_MAX_NUM_TDLS_STA; staIdx++)
Gopichand Nakkala2a0a1572013-02-10 21:39:16 -080011229 {
Gopichand Nakkala4327a152013-03-04 23:22:42 -080011230 if ((pHddCtx->tdlsConnInfo[staIdx].sessionId == pAdapter->sessionId) &&
11231 (pHddCtx->tdlsConnInfo[staIdx].staId))
Gopichand Nakkala2a0a1572013-02-10 21:39:16 -080011232 {
Hoonki Lee11f7dda2013-02-14 16:55:44 -080011233 uint8 *mac;
Gopichand Nakkala4327a152013-03-04 23:22:42 -080011234 mac = pHddCtx->tdlsConnInfo[staIdx].peerMac.bytes;
Hoonki Lee11f7dda2013-02-14 16:55:44 -080011235 VOS_TRACE(VOS_MODULE_ID_HDD, TDLS_LOG_LEVEL,
Gopichand Nakkalac87400e2013-03-13 18:51:00 -070011236 "%s: call sme_DeleteTdlsPeerSta staId %d sessionId %d " MAC_ADDRESS_STR,
Gopichand Nakkala4327a152013-03-04 23:22:42 -080011237 __func__, pHddCtx->tdlsConnInfo[staIdx].staId, pAdapter->sessionId,
Gopichand Nakkalac87400e2013-03-13 18:51:00 -070011238 MAC_ADDR_ARRAY(mac));
Gopichand Nakkala2a0a1572013-02-10 21:39:16 -080011239 sme_DeleteTdlsPeerSta(WLAN_HDD_GET_HAL_CTX(pAdapter),
Gopichand Nakkala4327a152013-03-04 23:22:42 -080011240 pAdapter->sessionId,
11241 mac);
Gopichand Nakkala2a0a1572013-02-10 21:39:16 -080011242 }
11243 }
11244#endif
Arun Kumar Khandavalli94a2bb02013-12-28 19:17:25 +053011245 hddLog(LOG1, FL("Disconnecting with reasoncode:%u"), reasonCode);
Gopichand Nakkala78a6c812013-05-13 16:39:49 +053011246 status = wlan_hdd_disconnect(pAdapter, reasonCode);
11247 if ( 0 != status )
Jeff Johnson295189b2012-06-20 16:38:30 -070011248 {
11249 hddLog(VOS_TRACE_LEVEL_ERROR,
Arif Hussain6d2a3322013-11-17 19:50:10 -080011250 "%s wlan_hdd_disconnect failure, returned %d",
Jeff Johnson295189b2012-06-20 16:38:30 -070011251 __func__, (int)status );
11252 return -EINVAL;
11253 }
Jeff Johnson295189b2012-06-20 16:38:30 -070011254 }
Mahesh A Saptasagar280fd5a2013-12-05 15:38:31 +053011255 else
11256 {
11257 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: unexpected cfg disconnect API"
11258 "called while in %d state", __func__,
11259 pHddStaCtx->conn_info.connState);
11260 }
Jeff Johnson295189b2012-06-20 16:38:30 -070011261 }
11262 else
11263 {
11264 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: No valid roam profile", __func__);
11265 }
11266
11267 return status;
11268}
11269
Mahesh A Saptasagarfafb7fe2014-05-16 13:19:37 +053011270static int wlan_hdd_cfg80211_disconnect( struct wiphy *wiphy,
11271 struct net_device *dev,
11272 u16 reason
11273 )
11274{
11275 int ret;
11276 vos_ssr_protect(__func__);
11277 ret = __wlan_hdd_cfg80211_disconnect(wiphy, dev, reason);
11278 vos_ssr_unprotect(__func__);
11279
11280 return ret;
11281}
Gopichand Nakkala78a6c812013-05-13 16:39:49 +053011282
Jeff Johnson295189b2012-06-20 16:38:30 -070011283/*
11284 * FUNCTION: wlan_hdd_cfg80211_set_privacy_ibss
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011285 * This function is used to initialize the security
Jeff Johnson295189b2012-06-20 16:38:30 -070011286 * settings in IBSS mode.
11287 */
11288static int wlan_hdd_cfg80211_set_privacy_ibss(
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011289 hdd_adapter_t *pAdapter,
Jeff Johnson295189b2012-06-20 16:38:30 -070011290 struct cfg80211_ibss_params *params
11291 )
11292{
11293 int status = 0;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011294 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
Jeff Johnson295189b2012-06-20 16:38:30 -070011295 eCsrEncryptionType encryptionType = eCSR_ENCRYPT_TYPE_NONE;
11296 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011297
Jeff Johnson295189b2012-06-20 16:38:30 -070011298 ENTER();
11299
11300 pWextState->wpaVersion = IW_AUTH_WPA_VERSION_DISABLED;
Ravi Joshib58ca0d2013-10-29 09:50:23 -070011301 vos_mem_zero(&pHddStaCtx->ibss_enc_key, sizeof(tCsrRoamSetKey));
Jeff Johnson295189b2012-06-20 16:38:30 -070011302
11303 if (params->ie_len && ( NULL != params->ie) )
11304 {
Shailender Karmuchi67edd312013-06-18 16:30:48 -070011305 if (wlan_hdd_cfg80211_get_ie_ptr (params->ie,
11306 params->ie_len, WLAN_EID_RSN ))
Jeff Johnson295189b2012-06-20 16:38:30 -070011307 {
11308 pWextState->wpaVersion = IW_AUTH_WPA_VERSION_WPA2;
11309 encryptionType = eCSR_ENCRYPT_TYPE_AES;
11310 }
Shailender Karmuchi67edd312013-06-18 16:30:48 -070011311 else if ( hdd_isWPAIEPresent (params->ie, params->ie_len ))
Jeff Johnson295189b2012-06-20 16:38:30 -070011312 {
Shailender Karmuchi642e9812013-05-30 14:34:49 -070011313 tDot11fIEWPA dot11WPAIE;
11314 tHalHandle halHandle = WLAN_HDD_GET_HAL_CTX(pAdapter);
Shailender Karmuchi67edd312013-06-18 16:30:48 -070011315 u8 *ie;
Shailender Karmuchi642e9812013-05-30 14:34:49 -070011316
Wilson Yang00256342013-10-10 23:13:38 -070011317 memset(&dot11WPAIE, 0, sizeof(dot11WPAIE));
Shailender Karmuchi67edd312013-06-18 16:30:48 -070011318 ie = wlan_hdd_cfg80211_get_ie_ptr (params->ie,
11319 params->ie_len, DOT11F_EID_WPA);
11320 if ( NULL != ie )
11321 {
11322 pWextState->wpaVersion = IW_AUTH_WPA_VERSION_WPA;
11323 // Unpack the WPA IE
11324 //Skip past the EID byte and length byte - and four byte WiFi OUI
11325 dot11fUnpackIeWPA((tpAniSirGlobal) halHandle,
11326 &ie[2+4],
11327 ie[1] - 4,
11328 &dot11WPAIE);
11329 /*Extract the multicast cipher, the encType for unicast
11330 cipher for wpa-none is none*/
11331 encryptionType =
11332 hdd_TranslateWPAToCsrEncryptionType(dot11WPAIE.multicast_cipher);
11333 }
Jeff Johnson295189b2012-06-20 16:38:30 -070011334 }
Shailender Karmuchi67edd312013-06-18 16:30:48 -070011335
Jeff Johnson295189b2012-06-20 16:38:30 -070011336 status = wlan_hdd_cfg80211_set_ie(pAdapter, params->ie, params->ie_len);
11337
11338 if (0 > status)
11339 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011340 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: failed to parse WPA/RSN IE",
Jeff Johnson295189b2012-06-20 16:38:30 -070011341 __func__);
11342 return status;
11343 }
11344 }
11345
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011346 pWextState->roamProfile.AuthType.authType[0] =
11347 pHddStaCtx->conn_info.authType =
Jeff Johnson295189b2012-06-20 16:38:30 -070011348 eCSR_AUTH_TYPE_OPEN_SYSTEM;
11349
11350 if (params->privacy)
11351 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011352 /* Security enabled IBSS, At this time there is no information available
11353 * about the security paramters, so initialise the encryption type to
Jeff Johnson295189b2012-06-20 16:38:30 -070011354 * eCSR_ENCRYPT_TYPE_WEP40_STATICKEY.
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011355 * The correct security parameters will be updated later in
Jeff Johnson295189b2012-06-20 16:38:30 -070011356 * wlan_hdd_cfg80211_add_key */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011357 /* Hal expects encryption type to be set inorder
Jeff Johnson295189b2012-06-20 16:38:30 -070011358 *enable privacy bit in beacons */
11359
11360 encryptionType = eCSR_ENCRYPT_TYPE_WEP40_STATICKEY;
11361 }
Shailender Karmuchi642e9812013-05-30 14:34:49 -070011362 VOS_TRACE (VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO_HIGH,
11363 "encryptionType=%d", encryptionType);
Jeff Johnson295189b2012-06-20 16:38:30 -070011364 pHddStaCtx->conn_info.ucEncryptionType = encryptionType;
11365 pWextState->roamProfile.EncryptionType.numEntries = 1;
11366 pWextState->roamProfile.EncryptionType.encryptionType[0] = encryptionType;
Jeff Johnson295189b2012-06-20 16:38:30 -070011367 return status;
11368}
11369
11370/*
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053011371 * FUNCTION: __wlan_hdd_cfg80211_join_ibss
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011372 * This function is used to create/join an IBSS
Jeff Johnson295189b2012-06-20 16:38:30 -070011373 */
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053011374static int __wlan_hdd_cfg80211_join_ibss( struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -070011375 struct net_device *dev,
11376 struct cfg80211_ibss_params *params
11377 )
11378{
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011379 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( dev );
Jeff Johnson295189b2012-06-20 16:38:30 -070011380 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
11381 tCsrRoamProfile *pRoamProfile;
11382 int status;
krunal sonie9002db2013-11-25 14:24:17 -080011383 bool alloc_bssid = VOS_FALSE;
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053011384 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
11385 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Jeff Johnson295189b2012-06-20 16:38:30 -070011386
11387 ENTER();
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053011388
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053011389 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
11390 TRACE_CODE_HDD_CFG80211_JOIN_IBSS,
11391 pAdapter->sessionId, pAdapter->device_mode));
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011392 hddLog(VOS_TRACE_LEVEL_INFO,
Sushant Kaushik8bc7df22014-04-09 17:55:29 +053011393 "%s: device_mode = %s (%d)", __func__,
11394 hdd_device_modetoString(pAdapter->device_mode),
11395 pAdapter->device_mode);
Jeff Johnson295189b2012-06-20 16:38:30 -070011396
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053011397 status = wlan_hdd_validate_context(pHddCtx);
11398
11399 if (0 != status)
Jeff Johnson295189b2012-06-20 16:38:30 -070011400 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053011401 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
11402 "%s: HDD context is not valid", __func__);
11403 return status;
Jeff Johnson295189b2012-06-20 16:38:30 -070011404 }
11405
11406 if (NULL == pWextState)
11407 {
Arif Hussain6d2a3322013-11-17 19:50:10 -080011408 hddLog (VOS_TRACE_LEVEL_ERROR, "%s ERROR: Data Storage Corruption",
Jeff Johnson295189b2012-06-20 16:38:30 -070011409 __func__);
11410 return -EIO;
11411 }
11412
Agarwal Ashish51325b52014-06-16 16:50:49 +053011413 if (vos_max_concurrent_connections_reached()) {
11414 hddLog(VOS_TRACE_LEVEL_INFO, FL("Reached max concurrent connections"));
11415 return -ECONNREFUSED;
11416 }
11417
Vinay Krishna Eranna21042322014-01-08 19:21:39 +053011418 /*Try disconnecting if already in connected state*/
11419 status = wlan_hdd_try_disconnect(pAdapter);
11420 if ( 0 > status)
11421 {
11422 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Failed to disconnect the existing"
11423 " IBSS connection"));
11424 return -EALREADY;
11425 }
11426
Jeff Johnson295189b2012-06-20 16:38:30 -070011427 pRoamProfile = &pWextState->roamProfile;
11428
11429 if ( eCSR_BSS_TYPE_START_IBSS != pRoamProfile->BSSType )
11430 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011431 hddLog (VOS_TRACE_LEVEL_ERROR,
Arif Hussain6d2a3322013-11-17 19:50:10 -080011432 "%s Interface type is not set to IBSS", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -070011433 return -EINVAL;
11434 }
11435
Praveen Kumar Sirisillad123d142013-09-24 16:50:13 -070011436 /* BSSID is provided by upper layers hence no need to AUTO generate */
11437 if (NULL != params->bssid) {
11438 if (ccmCfgSetInt(pHddCtx->hHal, WNI_CFG_IBSS_AUTO_BSSID, 0,
11439 NULL, eANI_BOOLEAN_FALSE)==eHAL_STATUS_FAILURE) {
11440 hddLog (VOS_TRACE_LEVEL_ERROR,
11441 "%s:ccmCfgStInt faild for WNI_CFG_IBSS_AUTO_BSSID", __func__);
11442 return -EIO;
11443 }
11444 }
krunal sonie9002db2013-11-25 14:24:17 -080011445 else if(pHddCtx->cfg_ini->isCoalesingInIBSSAllowed == 0)
11446 {
11447 if (ccmCfgSetInt(pHddCtx->hHal, WNI_CFG_IBSS_AUTO_BSSID, 0,
11448 NULL, eANI_BOOLEAN_FALSE)==eHAL_STATUS_FAILURE)
11449 {
11450 hddLog (VOS_TRACE_LEVEL_ERROR,
11451 "%s:ccmCfgStInt faild for WNI_CFG_IBSS_AUTO_BSSID", __func__);
11452 return -EIO;
11453 }
11454 params->bssid = vos_mem_malloc(sizeof(VOS_MAC_ADDR_SIZE));
11455 if (!params->bssid)
11456 {
11457 hddLog (VOS_TRACE_LEVEL_ERROR,
11458 "%s:Failed memory allocation", __func__);
11459 return -EIO;
11460 }
11461 vos_mem_copy((v_U8_t *)params->bssid,
11462 (v_U8_t *)&pHddCtx->cfg_ini->IbssBssid.bytes[0],
11463 VOS_MAC_ADDR_SIZE);
11464 alloc_bssid = VOS_TRUE;
11465 }
Praveen Kumar Sirisillad123d142013-09-24 16:50:13 -070011466
Jeff Johnson295189b2012-06-20 16:38:30 -070011467 /* Set Channel */
Yue Maf49ba872013-08-19 12:04:25 -070011468 if (NULL !=
11469#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,8,0))
11470 params->chandef.chan)
11471#else
11472 params->channel)
11473#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070011474 {
11475 u8 channelNum;
Shailender Karmuchi15cd0672013-05-15 19:50:04 -070011476 v_U32_t numChans = WNI_CFG_VALID_CHANNEL_LIST_LEN;
11477 v_U8_t validChan[WNI_CFG_VALID_CHANNEL_LIST_LEN];
11478 tHalHandle hHal = WLAN_HDD_GET_HAL_CTX(pAdapter);
11479 int indx;
Jeff Johnson295189b2012-06-20 16:38:30 -070011480
11481 /* Get channel number */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011482 channelNum =
Yue Maf49ba872013-08-19 12:04:25 -070011483 ieee80211_frequency_to_channel(
11484#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,8,0))
11485 params->chandef.chan->center_freq);
11486#else
11487 params->channel->center_freq);
11488#endif
Shailender Karmuchi15cd0672013-05-15 19:50:04 -070011489
11490 if (0 != ccmCfgGetStr(hHal, WNI_CFG_VALID_CHANNEL_LIST,
11491 validChan, &numChans))
Jeff Johnson295189b2012-06-20 16:38:30 -070011492 {
Shailender Karmuchi15cd0672013-05-15 19:50:04 -070011493 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: No valid channel list",
11494 __func__);
11495 return -EOPNOTSUPP;
Jeff Johnson295189b2012-06-20 16:38:30 -070011496 }
Shailender Karmuchi15cd0672013-05-15 19:50:04 -070011497
11498 for (indx = 0; indx < numChans; indx++)
Jeff Johnson295189b2012-06-20 16:38:30 -070011499 {
Shailender Karmuchi15cd0672013-05-15 19:50:04 -070011500 if (channelNum == validChan[indx])
11501 {
11502 break;
11503 }
11504 }
11505 if (indx >= numChans)
11506 {
11507 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Not valid Channel %d",
Jeff Johnson295189b2012-06-20 16:38:30 -070011508 __func__, channelNum);
11509 return -EINVAL;
11510 }
Shailender Karmuchi15cd0672013-05-15 19:50:04 -070011511 /* Set the Operational Channel */
11512 hddLog(VOS_TRACE_LEVEL_INFO_HIGH, "%s: set channel %d", __func__,
11513 channelNum);
11514 pRoamProfile->ChannelInfo.numOfChannels = 1;
11515 pHddStaCtx->conn_info.operationChannel = channelNum;
11516 pRoamProfile->ChannelInfo.ChannelList =
11517 &pHddStaCtx->conn_info.operationChannel;
Jeff Johnson295189b2012-06-20 16:38:30 -070011518 }
11519
11520 /* Initialize security parameters */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011521 status = wlan_hdd_cfg80211_set_privacy_ibss(pAdapter, params);
Jeff Johnson295189b2012-06-20 16:38:30 -070011522 if (status < 0)
11523 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011524 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: failed to set security parameters",
Jeff Johnson295189b2012-06-20 16:38:30 -070011525 __func__);
11526 return status;
11527 }
11528
11529 /* Issue connect start */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011530 status = wlan_hdd_cfg80211_connect_start(pAdapter, params->ssid,
Shailender Karmuchi15cd0672013-05-15 19:50:04 -070011531 params->ssid_len, params->bssid,
11532 pHddStaCtx->conn_info.operationChannel);
Jeff Johnson295189b2012-06-20 16:38:30 -070011533
11534 if (0 > status)
11535 {
11536 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: connect failed", __func__);
11537 return status;
11538 }
11539
krunal sonie9002db2013-11-25 14:24:17 -080011540 if (NULL != params->bssid &&
11541 pHddCtx->cfg_ini->isCoalesingInIBSSAllowed == 0 &&
11542 alloc_bssid == VOS_TRUE)
11543 {
11544 vos_mem_free(params->bssid);
11545 }
Jeff Johnson295189b2012-06-20 16:38:30 -070011546 return 0;
11547}
11548
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053011549static int wlan_hdd_cfg80211_join_ibss( struct wiphy *wiphy,
11550 struct net_device *dev,
11551 struct cfg80211_ibss_params *params
11552 )
11553{
11554 int ret = 0;
11555
11556 vos_ssr_protect(__func__);
11557 ret = __wlan_hdd_cfg80211_join_ibss(wiphy, dev, params);
11558 vos_ssr_unprotect(__func__);
11559
11560 return ret;
11561}
11562
Jeff Johnson295189b2012-06-20 16:38:30 -070011563/*
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053011564 * FUNCTION: __wlan_hdd_cfg80211_leave_ibss
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011565 * This function is used to leave an IBSS
Jeff Johnson295189b2012-06-20 16:38:30 -070011566 */
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053011567static int __wlan_hdd_cfg80211_leave_ibss( struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -070011568 struct net_device *dev
11569 )
11570{
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011571 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( dev );
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053011572 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
11573 tCsrRoamProfile *pRoamProfile;
11574 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053011575 int status;
Jeff Johnson295189b2012-06-20 16:38:30 -070011576
11577 ENTER();
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053011578
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053011579 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
11580 TRACE_CODE_HDD_CFG80211_LEAVE_IBSS,
11581 pAdapter->sessionId, eCSR_DISCONNECT_REASON_IBSS_LEAVE));
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053011582 status = wlan_hdd_validate_context(pHddCtx);
11583
11584 if (0 != status)
Jeff Johnson04dd8a82012-06-29 20:41:40 -070011585 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053011586 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
11587 "%s: HDD context is not valid", __func__);
11588 return status;
Jeff Johnson04dd8a82012-06-29 20:41:40 -070011589 }
11590
Sushant Kaushik8bc7df22014-04-09 17:55:29 +053011591 hddLog(VOS_TRACE_LEVEL_INFO, "%s: device_mode = %s (%d)", __func__,
11592 hdd_device_modetoString(pAdapter->device_mode),
11593 pAdapter->device_mode);
Jeff Johnson295189b2012-06-20 16:38:30 -070011594 if (NULL == pWextState)
11595 {
Arif Hussain6d2a3322013-11-17 19:50:10 -080011596 hddLog (VOS_TRACE_LEVEL_ERROR, "%s ERROR: Data Storage Corruption",
Jeff Johnson295189b2012-06-20 16:38:30 -070011597 __func__);
11598 return -EIO;
11599 }
11600
11601 pRoamProfile = &pWextState->roamProfile;
11602
11603 /* Issue disconnect only if interface type is set to IBSS */
11604 if (eCSR_BSS_TYPE_START_IBSS != pRoamProfile->BSSType)
11605 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011606 hddLog (VOS_TRACE_LEVEL_ERROR, "%s: BSS Type is not set to IBSS",
Jeff Johnson295189b2012-06-20 16:38:30 -070011607 __func__);
11608 return -EINVAL;
11609 }
11610
11611 /* Issue Disconnect request */
11612 INIT_COMPLETION(pAdapter->disconnect_comp_var);
11613 sme_RoamDisconnect( WLAN_HDD_GET_HAL_CTX(pAdapter), pAdapter->sessionId,
11614 eCSR_DISCONNECT_REASON_IBSS_LEAVE);
11615
11616 return 0;
11617}
11618
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053011619static int wlan_hdd_cfg80211_leave_ibss( struct wiphy *wiphy,
11620 struct net_device *dev
11621 )
11622{
11623 int ret = 0;
11624
11625 vos_ssr_protect(__func__);
11626 ret = __wlan_hdd_cfg80211_leave_ibss(wiphy, dev);
11627 vos_ssr_unprotect(__func__);
11628
11629 return ret;
11630}
11631
Jeff Johnson295189b2012-06-20 16:38:30 -070011632/*
Mahesh A Saptasagar179d2252014-06-02 21:32:21 +053011633 * FUNCTION: __wlan_hdd_cfg80211_set_wiphy_params
Jeff Johnson295189b2012-06-20 16:38:30 -070011634 * This function is used to set the phy parameters
11635 * (RTS Threshold/FRAG Threshold/Retry Count etc ...)
11636 */
Mahesh A Saptasagar179d2252014-06-02 21:32:21 +053011637static int __wlan_hdd_cfg80211_set_wiphy_params(struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -070011638 u32 changed)
11639{
11640 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
11641 tHalHandle hHal = pHddCtx->hHal;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053011642 int status;
Jeff Johnson295189b2012-06-20 16:38:30 -070011643
11644 ENTER();
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053011645 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
11646 TRACE_CODE_HDD_CFG80211_SET_WIPHY_PARAMS,
11647 NO_SESSION, wiphy->rts_threshold));
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053011648 status = wlan_hdd_validate_context(pHddCtx);
11649
11650 if (0 != status)
Jeff Johnson04dd8a82012-06-29 20:41:40 -070011651 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053011652 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
11653 "%s: HDD context is not valid", __func__);
11654 return status;
Jeff Johnson04dd8a82012-06-29 20:41:40 -070011655 }
11656
Jeff Johnson295189b2012-06-20 16:38:30 -070011657 if (changed & WIPHY_PARAM_RTS_THRESHOLD)
11658 {
11659 u16 rts_threshold = (wiphy->rts_threshold == -1) ?
11660 WNI_CFG_RTS_THRESHOLD_STAMAX :
11661 wiphy->rts_threshold;
11662
11663 if ((WNI_CFG_RTS_THRESHOLD_STAMIN > rts_threshold) ||
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011664 (WNI_CFG_RTS_THRESHOLD_STAMAX < rts_threshold))
Jeff Johnson295189b2012-06-20 16:38:30 -070011665 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011666 hddLog(VOS_TRACE_LEVEL_ERROR,
11667 "%s: Invalid RTS Threshold value %hu",
Jeff Johnson295189b2012-06-20 16:38:30 -070011668 __func__, rts_threshold);
11669 return -EINVAL;
11670 }
11671
11672 if (0 != ccmCfgSetInt(hHal, WNI_CFG_RTS_THRESHOLD,
11673 rts_threshold, ccmCfgSetCallback,
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011674 eANI_BOOLEAN_TRUE))
Jeff Johnson295189b2012-06-20 16:38:30 -070011675 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011676 hddLog(VOS_TRACE_LEVEL_ERROR,
11677 "%s: ccmCfgSetInt failed for rts_threshold value %hu",
Jeff Johnson295189b2012-06-20 16:38:30 -070011678 __func__, rts_threshold);
11679 return -EIO;
11680 }
11681
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011682 hddLog(VOS_TRACE_LEVEL_INFO_MED, "%s: set rts threshold %hu", __func__,
Jeff Johnson295189b2012-06-20 16:38:30 -070011683 rts_threshold);
11684 }
11685
11686 if (changed & WIPHY_PARAM_FRAG_THRESHOLD)
11687 {
11688 u16 frag_threshold = (wiphy->frag_threshold == -1) ?
11689 WNI_CFG_FRAGMENTATION_THRESHOLD_STAMAX :
11690 wiphy->frag_threshold;
11691
11692 if ((WNI_CFG_FRAGMENTATION_THRESHOLD_STAMIN > frag_threshold)||
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011693 (WNI_CFG_FRAGMENTATION_THRESHOLD_STAMAX < frag_threshold) )
Jeff Johnson295189b2012-06-20 16:38:30 -070011694 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011695 hddLog(VOS_TRACE_LEVEL_ERROR,
11696 "%s: Invalid frag_threshold value %hu", __func__,
Jeff Johnson295189b2012-06-20 16:38:30 -070011697 frag_threshold);
11698 return -EINVAL;
11699 }
11700
11701 if (0 != ccmCfgSetInt(hHal, WNI_CFG_FRAGMENTATION_THRESHOLD,
11702 frag_threshold, ccmCfgSetCallback,
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011703 eANI_BOOLEAN_TRUE))
Jeff Johnson295189b2012-06-20 16:38:30 -070011704 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011705 hddLog(VOS_TRACE_LEVEL_ERROR,
11706 "%s: ccmCfgSetInt failed for frag_threshold value %hu",
Jeff Johnson295189b2012-06-20 16:38:30 -070011707 __func__, frag_threshold);
11708 return -EIO;
11709 }
11710
11711 hddLog(VOS_TRACE_LEVEL_INFO_MED, "%s: set frag threshold %hu", __func__,
11712 frag_threshold);
11713 }
11714
11715 if ((changed & WIPHY_PARAM_RETRY_SHORT)
11716 || (changed & WIPHY_PARAM_RETRY_LONG))
11717 {
11718 u8 retry_value = (changed & WIPHY_PARAM_RETRY_SHORT) ?
11719 wiphy->retry_short :
11720 wiphy->retry_long;
11721
11722 if ((WNI_CFG_LONG_RETRY_LIMIT_STAMIN > retry_value) ||
11723 (WNI_CFG_LONG_RETRY_LIMIT_STAMAX < retry_value))
11724 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011725 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Invalid Retry count %hu",
Jeff Johnson295189b2012-06-20 16:38:30 -070011726 __func__, retry_value);
11727 return -EINVAL;
11728 }
11729
11730 if (changed & WIPHY_PARAM_RETRY_SHORT)
11731 {
11732 if (0 != ccmCfgSetInt(hHal, WNI_CFG_LONG_RETRY_LIMIT,
11733 retry_value, ccmCfgSetCallback,
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011734 eANI_BOOLEAN_TRUE))
Jeff Johnson295189b2012-06-20 16:38:30 -070011735 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011736 hddLog(VOS_TRACE_LEVEL_ERROR,
11737 "%s: ccmCfgSetInt failed for long retry count %hu",
Jeff Johnson295189b2012-06-20 16:38:30 -070011738 __func__, retry_value);
11739 return -EIO;
11740 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011741 hddLog(VOS_TRACE_LEVEL_INFO_MED, "%s: set long retry count %hu",
Jeff Johnson295189b2012-06-20 16:38:30 -070011742 __func__, retry_value);
11743 }
11744 else if (changed & WIPHY_PARAM_RETRY_SHORT)
11745 {
11746 if (0 != ccmCfgSetInt(hHal, WNI_CFG_SHORT_RETRY_LIMIT,
11747 retry_value, ccmCfgSetCallback,
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011748 eANI_BOOLEAN_TRUE))
Jeff Johnson295189b2012-06-20 16:38:30 -070011749 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011750 hddLog(VOS_TRACE_LEVEL_ERROR,
11751 "%s: ccmCfgSetInt failed for short retry count %hu",
Jeff Johnson295189b2012-06-20 16:38:30 -070011752 __func__, retry_value);
11753 return -EIO;
11754 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011755 hddLog(VOS_TRACE_LEVEL_INFO_MED, "%s: set short retry count %hu",
Jeff Johnson295189b2012-06-20 16:38:30 -070011756 __func__, retry_value);
11757 }
11758 }
11759
11760 return 0;
11761}
11762
Mahesh A Saptasagar179d2252014-06-02 21:32:21 +053011763static int wlan_hdd_cfg80211_set_wiphy_params(struct wiphy *wiphy,
11764 u32 changed)
11765{
11766 int ret;
11767
11768 vos_ssr_protect(__func__);
11769 ret = __wlan_hdd_cfg80211_set_wiphy_params(wiphy, changed);
11770 vos_ssr_unprotect(__func__);
11771
11772 return ret;
11773}
11774
Jeff Johnson295189b2012-06-20 16:38:30 -070011775/*
Mahesh A Saptasagar179d2252014-06-02 21:32:21 +053011776 * FUNCTION: __wlan_hdd_cfg80211_set_txpower
Jeff Johnson295189b2012-06-20 16:38:30 -070011777 * This function is used to set the txpower
11778 */
Mahesh A Saptasagar179d2252014-06-02 21:32:21 +053011779static int __wlan_hdd_cfg80211_set_txpower(struct wiphy *wiphy,
Yue Maf49ba872013-08-19 12:04:25 -070011780#if LINUX_VERSION_CODE >= KERNEL_VERSION(3,8,0)
11781 struct wireless_dev *wdev,
11782#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070011783#if LINUX_VERSION_CODE <= KERNEL_VERSION(2,6,35)
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011784 enum tx_power_setting type,
Jeff Johnson295189b2012-06-20 16:38:30 -070011785#else
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011786 enum nl80211_tx_power_setting type,
Jeff Johnson295189b2012-06-20 16:38:30 -070011787#endif
11788 int dbm)
11789{
11790 hdd_context_t *pHddCtx = (hdd_context_t*) wiphy_priv(wiphy);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053011791 tHalHandle hHal = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -070011792 tSirMacAddr bssid = {0xFF,0xFF,0xFF,0xFF,0xFF,0xFF};
11793 tSirMacAddr selfMac = {0xFF,0xFF,0xFF,0xFF,0xFF,0xFF};
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053011794 int status;
Jeff Johnson295189b2012-06-20 16:38:30 -070011795
11796 ENTER();
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053011797 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
11798 TRACE_CODE_HDD_CFG80211_SET_TXPOWER,
11799 NO_SESSION, type ));
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053011800 status = wlan_hdd_validate_context(pHddCtx);
11801
11802 if (0 != status)
11803 {
11804 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
11805 "%s: HDD context is not valid", __func__);
11806 return status;
11807 }
11808
11809 hHal = pHddCtx->hHal;
11810
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011811 if (0 != ccmCfgSetInt(hHal, WNI_CFG_CURRENT_TX_POWER_LEVEL,
11812 dbm, ccmCfgSetCallback,
11813 eANI_BOOLEAN_TRUE))
Jeff Johnson295189b2012-06-20 16:38:30 -070011814 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011815 hddLog(VOS_TRACE_LEVEL_ERROR,
Jeff Johnson295189b2012-06-20 16:38:30 -070011816 "%s: ccmCfgSetInt failed for tx power %hu", __func__, dbm);
11817 return -EIO;
11818 }
11819
11820 hddLog(VOS_TRACE_LEVEL_INFO_MED, "%s: set tx power level %d dbm", __func__,
11821 dbm);
11822
11823 switch(type)
11824 {
11825 case NL80211_TX_POWER_AUTOMATIC: /*automatically determine transmit power*/
11826 /* Fall through */
11827 case NL80211_TX_POWER_LIMITED: /*limit TX power by the mBm parameter*/
11828 if( sme_SetMaxTxPower(hHal, bssid, selfMac, dbm) != eHAL_STATUS_SUCCESS )
11829 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011830 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Setting maximum tx power failed",
11831 __func__);
11832 return -EIO;
Jeff Johnson295189b2012-06-20 16:38:30 -070011833 }
11834 break;
11835 case NL80211_TX_POWER_FIXED: /*fix TX power to the mBm parameter*/
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011836 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: NL80211_TX_POWER_FIXED not supported",
Jeff Johnson295189b2012-06-20 16:38:30 -070011837 __func__);
11838 return -EOPNOTSUPP;
11839 break;
11840 default:
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011841 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Invalid power setting type %d",
11842 __func__, type);
Jeff Johnson295189b2012-06-20 16:38:30 -070011843 return -EIO;
11844 }
11845
11846 return 0;
11847}
11848
Mahesh A Saptasagar179d2252014-06-02 21:32:21 +053011849static int wlan_hdd_cfg80211_set_txpower(struct wiphy *wiphy,
11850#if LINUX_VERSION_CODE >= KERNEL_VERSION(3,8,0)
11851 struct wireless_dev *wdev,
11852#endif
11853#if LINUX_VERSION_CODE <= KERNEL_VERSION(2,6,35)
11854 enum tx_power_setting type,
11855#else
11856 enum nl80211_tx_power_setting type,
11857#endif
11858 int dbm)
11859{
11860 int ret;
11861 vos_ssr_protect(__func__);
11862 ret = __wlan_hdd_cfg80211_set_txpower(wiphy,
11863#if LINUX_VERSION_CODE >= KERNEL_VERSION(3,8,0)
11864 wdev,
11865#endif
11866#if LINUX_VERSION_CODE <= KERNEL_VERSION(2,6,35)
11867 type,
11868#else
11869 type,
11870#endif
11871 dbm);
11872 vos_ssr_unprotect(__func__);
11873
11874 return ret;
11875}
11876
Jeff Johnson295189b2012-06-20 16:38:30 -070011877/*
11878 * FUNCTION: wlan_hdd_cfg80211_get_txpower
11879 * This function is used to read the txpower
11880 */
Yue Maf49ba872013-08-19 12:04:25 -070011881static int wlan_hdd_cfg80211_get_txpower(struct wiphy *wiphy,
11882#if LINUX_VERSION_CODE >= KERNEL_VERSION(3,8,0)
11883 struct wireless_dev *wdev,
11884#endif
11885 int *dbm)
Jeff Johnson295189b2012-06-20 16:38:30 -070011886{
11887
11888 hdd_adapter_t *pAdapter;
11889 hdd_context_t *pHddCtx = (hdd_context_t*) wiphy_priv(wiphy);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053011890 int status;
Jeff Johnson295189b2012-06-20 16:38:30 -070011891
Jeff Johnsone7245742012-09-05 17:12:55 -070011892 ENTER();
11893
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053011894 status = wlan_hdd_validate_context(pHddCtx);
Jeff Johnson295189b2012-06-20 16:38:30 -070011895
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053011896 if (0 != status)
Jeff Johnson04dd8a82012-06-29 20:41:40 -070011897 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053011898 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
11899 "%s: HDD context is not valid", __func__);
11900 *dbm = 0;
11901 return status;
Jeff Johnson04dd8a82012-06-29 20:41:40 -070011902 }
11903
Jeff Johnson295189b2012-06-20 16:38:30 -070011904 pAdapter = hdd_get_adapter(pHddCtx, WLAN_HDD_INFRA_STATION);
11905 if (NULL == pAdapter)
11906 {
11907 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: Not in station context " ,__func__);
11908 return -ENOENT;
11909 }
11910
11911 wlan_hdd_get_classAstats(pAdapter);
11912 *dbm = pAdapter->hdd_stats.ClassA_stat.max_pwr;
11913
Jeff Johnsone7245742012-09-05 17:12:55 -070011914 EXIT();
Jeff Johnson295189b2012-06-20 16:38:30 -070011915 return 0;
11916}
11917
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053011918static int __wlan_hdd_cfg80211_get_station(struct wiphy *wiphy, struct net_device *dev,
Jeff Johnson295189b2012-06-20 16:38:30 -070011919 u8* mac, struct station_info *sinfo)
11920{
11921 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( dev );
11922 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
11923 int ssidlen = pHddStaCtx->conn_info.SSID.SSID.length;
c_hpothu44ff4e02014-05-08 00:13:57 +053011924 tANI_U32 rate_flags;
Jeff Johnson295189b2012-06-20 16:38:30 -070011925
11926 hdd_context_t *pHddCtx = (hdd_context_t*) wiphy_priv(wiphy);
11927 hdd_config_t *pCfg = pHddCtx->cfg_ini;
Jeff Johnson295189b2012-06-20 16:38:30 -070011928
11929 tANI_U8 OperationalRates[CSR_DOT11_SUPPORTED_RATES_MAX];
11930 tANI_U32 ORLeng = CSR_DOT11_SUPPORTED_RATES_MAX;
11931 tANI_U8 ExtendedRates[CSR_DOT11_EXTENDED_SUPPORTED_RATES_MAX];
11932 tANI_U32 ERLeng = CSR_DOT11_EXTENDED_SUPPORTED_RATES_MAX;
11933 tANI_U8 MCSRates[SIZE_OF_BASIC_MCS_SET];
11934 tANI_U32 MCSLeng = SIZE_OF_BASIC_MCS_SET;
11935 tANI_U16 maxRate = 0;
11936 tANI_U16 myRate;
11937 tANI_U16 currentRate = 0;
11938 tANI_U8 maxSpeedMCS = 0;
11939 tANI_U8 maxMCSIdx = 0;
11940 tANI_U8 rateFlag = 1;
c_hpothu79aab322014-07-14 21:11:01 +053011941 tANI_U8 i, j, rssidx, mode=0;
Madan Mohan Koyyalamudic75be962012-10-18 19:19:03 -070011942 tANI_U16 temp;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053011943 int status;
Jeff Johnson295189b2012-06-20 16:38:30 -070011944
Leo Chang6f8870f2013-03-26 18:11:36 -070011945#ifdef WLAN_FEATURE_11AC
11946 tANI_U32 vht_mcs_map;
11947 eDataRate11ACMaxMcs vhtMaxMcs;
11948#endif /* WLAN_FEATURE_11AC */
11949
Jeff Johnsone7245742012-09-05 17:12:55 -070011950 ENTER();
11951
Jeff Johnson295189b2012-06-20 16:38:30 -070011952 if ((eConnectionState_Associated != pHddStaCtx->conn_info.connState) ||
11953 (0 == ssidlen))
11954 {
11955 hddLog(VOS_TRACE_LEVEL_INFO, "%s: Not associated or"
11956 " Invalid ssidlen, %d", __func__, ssidlen);
11957 /*To keep GUI happy*/
11958 return 0;
11959 }
11960
Mukul Sharma811205f2014-07-09 21:07:30 +053011961 if (VOS_TRUE == pHddStaCtx->hdd_ReassocScenario)
11962 {
11963 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
11964 "%s: Roaming in progress, so unable to proceed this request", __func__);
11965 return 0;
11966 }
11967
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053011968 status = wlan_hdd_validate_context(pHddCtx);
11969
11970 if (0 != status)
Jeff Johnson04dd8a82012-06-29 20:41:40 -070011971 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053011972 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
11973 "%s: HDD context is not valid", __func__);
11974 return status;
Jeff Johnson04dd8a82012-06-29 20:41:40 -070011975 }
11976
Jeff Johnson295189b2012-06-20 16:38:30 -070011977
Kiet Lam3b17fc82013-09-27 05:24:08 +053011978 wlan_hdd_get_rssi(pAdapter, &sinfo->signal);
11979 sinfo->filled |= STATION_INFO_SIGNAL;
11980
c_hpothu09f19542014-05-30 21:53:31 +053011981 wlan_hdd_get_station_stats(pAdapter);
11982 rate_flags = pAdapter->hdd_stats.ClassA_stat.tx_rate_flags;
11983
11984 /*overwrite rate_flags if MAX link-speed need to be reported*/
c_hpothu44ff4e02014-05-08 00:13:57 +053011985 if ((eHDD_LINK_SPEED_REPORT_MAX == pCfg->reportMaxLinkSpeed) ||
11986 (eHDD_LINK_SPEED_REPORT_MAX_SCALED == pCfg->reportMaxLinkSpeed &&
c_hpothu79aab322014-07-14 21:11:01 +053011987 sinfo->signal >= pCfg->linkSpeedRssiLow))
c_hpothu44ff4e02014-05-08 00:13:57 +053011988 {
11989 rate_flags = pAdapter->maxRateFlags;
11990 }
c_hpothu44ff4e02014-05-08 00:13:57 +053011991
Jeff Johnson295189b2012-06-20 16:38:30 -070011992 //convert to the UI units of 100kbps
11993 myRate = pAdapter->hdd_stats.ClassA_stat.tx_rate * 5;
11994
11995#ifdef LINKSPEED_DEBUG_ENABLED
Leo Chang6f8870f2013-03-26 18:11:36 -070011996 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 -070011997 sinfo->signal,
11998 pCfg->reportMaxLinkSpeed,
11999 myRate,
12000 (int) pCfg->linkSpeedRssiHigh,
Madan Mohan Koyyalamudi8df78d52012-11-02 12:30:06 -070012001 (int) pCfg->linkSpeedRssiMid,
12002 (int) pCfg->linkSpeedRssiLow,
Leo Chang6f8870f2013-03-26 18:11:36 -070012003 (int) rate_flags,
12004 (int) pAdapter->hdd_stats.ClassA_stat.mcs_index);
Jeff Johnson295189b2012-06-20 16:38:30 -070012005#endif //LINKSPEED_DEBUG_ENABLED
12006
12007 if (eHDD_LINK_SPEED_REPORT_ACTUAL != pCfg->reportMaxLinkSpeed)
12008 {
12009 // we do not want to necessarily report the current speed
12010 if (eHDD_LINK_SPEED_REPORT_MAX == pCfg->reportMaxLinkSpeed)
12011 {
12012 // report the max possible speed
12013 rssidx = 0;
12014 }
12015 else if (eHDD_LINK_SPEED_REPORT_MAX_SCALED == pCfg->reportMaxLinkSpeed)
12016 {
12017 // report the max possible speed with RSSI scaling
12018 if (sinfo->signal >= pCfg->linkSpeedRssiHigh)
12019 {
12020 // report the max possible speed
12021 rssidx = 0;
12022 }
Madan Mohan Koyyalamudi8df78d52012-11-02 12:30:06 -070012023 else if (sinfo->signal >= pCfg->linkSpeedRssiMid)
Jeff Johnson295189b2012-06-20 16:38:30 -070012024 {
12025 // report middle speed
12026 rssidx = 1;
12027 }
Madan Mohan Koyyalamudi8df78d52012-11-02 12:30:06 -070012028 else if (sinfo->signal >= pCfg->linkSpeedRssiLow)
12029 {
12030 // report middle speed
12031 rssidx = 2;
12032 }
Jeff Johnson295189b2012-06-20 16:38:30 -070012033 else
12034 {
12035 // report actual speed
Madan Mohan Koyyalamudi8df78d52012-11-02 12:30:06 -070012036 rssidx = 3;
Jeff Johnson295189b2012-06-20 16:38:30 -070012037 }
12038 }
12039 else
12040 {
12041 // unknown, treat as eHDD_LINK_SPEED_REPORT_MAX
12042 hddLog(VOS_TRACE_LEVEL_ERROR,
12043 "%s: Invalid value for reportMaxLinkSpeed: %u",
12044 __func__, pCfg->reportMaxLinkSpeed);
12045 rssidx = 0;
12046 }
12047
12048 maxRate = 0;
12049
12050 /* Get Basic Rate Set */
Gopichand Nakkala05ab1322013-02-15 11:28:38 +053012051 if (0 != ccmCfgGetStr(WLAN_HDD_GET_HAL_CTX(pAdapter), WNI_CFG_OPERATIONAL_RATE_SET,
12052 OperationalRates, &ORLeng))
12053 {
12054 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: ccm api returned failure", __func__);
12055 /*To keep GUI happy*/
12056 return 0;
12057 }
12058
Jeff Johnson295189b2012-06-20 16:38:30 -070012059 for (i = 0; i < ORLeng; i++)
12060 {
Jeff Johnsone7245742012-09-05 17:12:55 -070012061 for (j = 0; j < (sizeof(supported_data_rate) / sizeof(supported_data_rate[0])); j ++)
Jeff Johnson295189b2012-06-20 16:38:30 -070012062 {
12063 /* Validate Rate Set */
12064 if (supported_data_rate[j].beacon_rate_index == (OperationalRates[i] & 0x7F))
12065 {
12066 currentRate = supported_data_rate[j].supported_rate[rssidx];
12067 break;
12068 }
12069 }
12070 /* Update MAX rate */
12071 maxRate = (currentRate > maxRate)?currentRate:maxRate;
12072 }
12073
12074 /* Get Extended Rate Set */
Gopichand Nakkala05ab1322013-02-15 11:28:38 +053012075 if (0 != ccmCfgGetStr(WLAN_HDD_GET_HAL_CTX(pAdapter), WNI_CFG_EXTENDED_OPERATIONAL_RATE_SET,
12076 ExtendedRates, &ERLeng))
12077 {
12078 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: ccm api returned failure", __func__);
12079 /*To keep GUI happy*/
12080 return 0;
12081 }
12082
Jeff Johnson295189b2012-06-20 16:38:30 -070012083 for (i = 0; i < ERLeng; i++)
12084 {
Jeff Johnsone7245742012-09-05 17:12:55 -070012085 for (j = 0; j < (sizeof(supported_data_rate) / sizeof(supported_data_rate[0])); j ++)
Jeff Johnson295189b2012-06-20 16:38:30 -070012086 {
12087 if (supported_data_rate[j].beacon_rate_index == (ExtendedRates[i] & 0x7F))
12088 {
12089 currentRate = supported_data_rate[j].supported_rate[rssidx];
12090 break;
12091 }
12092 }
12093 /* Update MAX rate */
12094 maxRate = (currentRate > maxRate)?currentRate:maxRate;
12095 }
c_hpothu79aab322014-07-14 21:11:01 +053012096
Kiet Lamb69f8dc2013-11-15 15:34:27 +053012097 /* Get MCS Rate Set --
Kaushik, Sushantdc304d82014-01-22 10:58:37 +053012098 Only if we are always reporting max speed (or)
Kiet Lamb69f8dc2013-11-15 15:34:27 +053012099 if we have good rssi */
c_hpothu79aab322014-07-14 21:11:01 +053012100 if ((3 != rssidx) && !(rate_flags & eHAL_TX_RATE_LEGACY))
Jeff Johnson295189b2012-06-20 16:38:30 -070012101 {
c_hpothu79aab322014-07-14 21:11:01 +053012102 if (rate_flags & eHAL_TX_RATE_VHT80)
12103 mode = 2;
12104 else if (rate_flags & (eHAL_TX_RATE_VHT40 | eHAL_TX_RATE_HT40))
12105 mode = 1;
12106 else
12107 mode = 0;
12108
Gopichand Nakkala05ab1322013-02-15 11:28:38 +053012109 if (0 != ccmCfgGetStr(WLAN_HDD_GET_HAL_CTX(pAdapter), WNI_CFG_CURRENT_MCS_SET,
12110 MCSRates, &MCSLeng))
12111 {
12112 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: ccm api returned failure", __func__);
12113 /*To keep GUI happy*/
12114 return 0;
12115 }
Jeff Johnson295189b2012-06-20 16:38:30 -070012116 rateFlag = 0;
Leo Chang6f8870f2013-03-26 18:11:36 -070012117#ifdef WLAN_FEATURE_11AC
12118 /* VHT80 rate has seperate rate table */
Gopichand Nakkala4c705372013-04-24 13:20:33 +053012119 if (rate_flags & (eHAL_TX_RATE_VHT20|eHAL_TX_RATE_VHT40|eHAL_TX_RATE_VHT80))
Jeff Johnson295189b2012-06-20 16:38:30 -070012120 {
Leo Chang6f8870f2013-03-26 18:11:36 -070012121 ccmCfgGetInt(WLAN_HDD_GET_HAL_CTX(pAdapter), WNI_CFG_VHT_TX_MCS_MAP, &vht_mcs_map);
Gopichand Nakkala4c705372013-04-24 13:20:33 +053012122 vhtMaxMcs = (eDataRate11ACMaxMcs)(vht_mcs_map & DATA_RATE_11AC_MCS_MASK );
Leo Chang6f8870f2013-03-26 18:11:36 -070012123 if (rate_flags & eHAL_TX_RATE_SGI)
Jeff Johnson295189b2012-06-20 16:38:30 -070012124 {
Leo Chang6f8870f2013-03-26 18:11:36 -070012125 rateFlag |= 1;
Jeff Johnson295189b2012-06-20 16:38:30 -070012126 }
Leo Chang6f8870f2013-03-26 18:11:36 -070012127 if (DATA_RATE_11AC_MAX_MCS_7 == vhtMaxMcs)
Jeff Johnson295189b2012-06-20 16:38:30 -070012128 {
Leo Chang6f8870f2013-03-26 18:11:36 -070012129 maxMCSIdx = 7;
12130 }
12131 else if (DATA_RATE_11AC_MAX_MCS_8 == vhtMaxMcs)
12132 {
12133 maxMCSIdx = 8;
12134 }
12135 else if (DATA_RATE_11AC_MAX_MCS_9 == vhtMaxMcs)
12136 {
Gopichand Nakkala4c705372013-04-24 13:20:33 +053012137 //VHT20 is supporting 0~8
12138 if (rate_flags & eHAL_TX_RATE_VHT20)
12139 maxMCSIdx = 8;
12140 else
12141 maxMCSIdx = 9;
Leo Chang6f8870f2013-03-26 18:11:36 -070012142 }
Gopichand Nakkala4c705372013-04-24 13:20:33 +053012143
c_hpothu79aab322014-07-14 21:11:01 +053012144 if (0 != rssidx)/*check for scaled */
12145 {
12146 //get middle rate MCS index if rssi=1/2
12147 for (i=0; i <= maxMCSIdx; i++)
12148 {
12149 if (sinfo->signal <= rssiMcsTbl[mode][i])
12150 {
12151 maxMCSIdx = i;
12152 break;
12153 }
12154 }
12155 }
12156
Gopichand Nakkala4c705372013-04-24 13:20:33 +053012157 if (rate_flags & eHAL_TX_RATE_VHT80)
12158 {
12159 currentRate = supported_vht_mcs_rate[pAdapter->hdd_stats.ClassA_stat.mcs_index].supported_VHT80_rate[rateFlag];
12160 maxRate = supported_vht_mcs_rate[maxMCSIdx].supported_VHT80_rate[rateFlag];
12161 }
12162 else if (rate_flags & eHAL_TX_RATE_VHT40)
12163 {
12164 currentRate = supported_vht_mcs_rate[pAdapter->hdd_stats.ClassA_stat.mcs_index].supported_VHT40_rate[rateFlag];
12165 maxRate = supported_vht_mcs_rate[maxMCSIdx].supported_VHT40_rate[rateFlag];
12166 }
12167 else if (rate_flags & eHAL_TX_RATE_VHT20)
12168 {
12169 currentRate = supported_vht_mcs_rate[pAdapter->hdd_stats.ClassA_stat.mcs_index].supported_VHT20_rate[rateFlag];
12170 maxRate = supported_vht_mcs_rate[maxMCSIdx].supported_VHT20_rate[rateFlag];
12171 }
12172
Leo Chang6f8870f2013-03-26 18:11:36 -070012173 maxSpeedMCS = 1;
12174 if (currentRate > maxRate)
12175 {
12176 maxRate = currentRate;
12177 }
Gopichand Nakkala4c705372013-04-24 13:20:33 +053012178
Leo Chang6f8870f2013-03-26 18:11:36 -070012179 }
12180 else
12181#endif /* WLAN_FEATURE_11AC */
12182 {
12183 if (rate_flags & eHAL_TX_RATE_HT40)
12184 {
12185 rateFlag |= 1;
12186 }
12187 if (rate_flags & eHAL_TX_RATE_SGI)
12188 {
12189 rateFlag |= 2;
12190 }
12191
Girish Gowli01abcee2014-07-31 20:18:55 +053012192 temp = sizeof(supported_mcs_rate) / sizeof(supported_mcs_rate[0]);
c_hpothu79aab322014-07-14 21:11:01 +053012193 if (rssidx == 1 || rssidx == 2)
12194 {
12195 //get middle rate MCS index if rssi=1/2
12196 for (i=0; i <= 7; i++)
12197 {
12198 if (sinfo->signal <= rssiMcsTbl[mode][i])
12199 {
12200 temp = i+1;
12201 break;
12202 }
12203 }
12204 }
c_hpothu79aab322014-07-14 21:11:01 +053012205
12206 for (i = 0; i < MCSLeng; i++)
12207 {
Leo Chang6f8870f2013-03-26 18:11:36 -070012208 for (j = 0; j < temp; j++)
12209 {
12210 if (supported_mcs_rate[j].beacon_rate_index == MCSRates[i])
12211 {
12212 currentRate = supported_mcs_rate[j].supported_rate[rateFlag];
12213 break;
12214 }
12215 }
12216 if ((j < temp) && (currentRate > maxRate))
12217 {
12218 maxRate = currentRate;
12219 maxSpeedMCS = 1;
12220 maxMCSIdx = supported_mcs_rate[j].beacon_rate_index;
12221 }
Jeff Johnson295189b2012-06-20 16:38:30 -070012222 }
12223 }
12224 }
12225
Gopichand Nakkala4c705372013-04-24 13:20:33 +053012226 else if (!(rate_flags & eHAL_TX_RATE_LEGACY))
12227 {
12228 maxRate = myRate;
12229 maxSpeedMCS = 1;
12230 maxMCSIdx = pAdapter->hdd_stats.ClassA_stat.mcs_index;
12231 }
Jeff Johnson295189b2012-06-20 16:38:30 -070012232 // make sure we report a value at least as big as our current rate
c_hpothu79aab322014-07-14 21:11:01 +053012233 if ((maxRate < myRate) || (0 == maxRate))
Jeff Johnson295189b2012-06-20 16:38:30 -070012234 {
12235 maxRate = myRate;
12236 if (rate_flags & eHAL_TX_RATE_LEGACY)
12237 {
12238 maxSpeedMCS = 0;
12239 }
12240 else
12241 {
12242 maxSpeedMCS = 1;
12243 maxMCSIdx = pAdapter->hdd_stats.ClassA_stat.mcs_index;
12244 }
12245 }
12246
Gopichand Nakkala4c705372013-04-24 13:20:33 +053012247 if (rate_flags & eHAL_TX_RATE_LEGACY)
Jeff Johnson295189b2012-06-20 16:38:30 -070012248 {
12249 sinfo->txrate.legacy = maxRate;
12250#ifdef LINKSPEED_DEBUG_ENABLED
12251 pr_info("Reporting legacy rate %d\n", sinfo->txrate.legacy);
12252#endif //LINKSPEED_DEBUG_ENABLED
12253 }
12254 else
12255 {
12256 sinfo->txrate.mcs = maxMCSIdx;
Leo Chang6f8870f2013-03-26 18:11:36 -070012257#ifdef WLAN_FEATURE_11AC
12258 sinfo->txrate.nss = 1;
12259 if (rate_flags & eHAL_TX_RATE_VHT80)
12260 {
12261 sinfo->txrate.flags |= RATE_INFO_FLAGS_VHT_MCS;
Gopichand Nakkala4c705372013-04-24 13:20:33 +053012262 sinfo->txrate.flags |= RATE_INFO_FLAGS_80_MHZ_WIDTH;
Leo Chang6f8870f2013-03-26 18:11:36 -070012263 }
Gopichand Nakkala4c705372013-04-24 13:20:33 +053012264 else if (rate_flags & eHAL_TX_RATE_VHT40)
Leo Chang6f8870f2013-03-26 18:11:36 -070012265 {
Gopichand Nakkala4c705372013-04-24 13:20:33 +053012266 sinfo->txrate.flags |= RATE_INFO_FLAGS_VHT_MCS;
12267 sinfo->txrate.flags |= RATE_INFO_FLAGS_40_MHZ_WIDTH;
12268 }
12269 else if (rate_flags & eHAL_TX_RATE_VHT20)
12270 {
12271 sinfo->txrate.flags |= RATE_INFO_FLAGS_VHT_MCS;
12272 }
12273#endif /* WLAN_FEATURE_11AC */
12274 if (rate_flags & (eHAL_TX_RATE_HT20 | eHAL_TX_RATE_HT40))
12275 {
12276 sinfo->txrate.flags |= RATE_INFO_FLAGS_MCS;
12277 if (rate_flags & eHAL_TX_RATE_HT40)
12278 {
12279 sinfo->txrate.flags |= RATE_INFO_FLAGS_40_MHZ_WIDTH;
12280 }
Leo Chang6f8870f2013-03-26 18:11:36 -070012281 }
Jeff Johnson295189b2012-06-20 16:38:30 -070012282 if (rate_flags & eHAL_TX_RATE_SGI)
12283 {
12284 sinfo->txrate.flags |= RATE_INFO_FLAGS_SHORT_GI;
12285 }
Gopichand Nakkala4c705372013-04-24 13:20:33 +053012286
Jeff Johnson295189b2012-06-20 16:38:30 -070012287#ifdef LINKSPEED_DEBUG_ENABLED
12288 pr_info("Reporting MCS rate %d flags %x\n",
12289 sinfo->txrate.mcs,
12290 sinfo->txrate.flags );
12291#endif //LINKSPEED_DEBUG_ENABLED
12292 }
12293 }
12294 else
12295 {
12296 // report current rate instead of max rate
12297
12298 if (rate_flags & eHAL_TX_RATE_LEGACY)
12299 {
12300 //provide to the UI in units of 100kbps
12301 sinfo->txrate.legacy = myRate;
12302#ifdef LINKSPEED_DEBUG_ENABLED
12303 pr_info("Reporting actual legacy rate %d\n", sinfo->txrate.legacy);
12304#endif //LINKSPEED_DEBUG_ENABLED
12305 }
12306 else
12307 {
12308 //must be MCS
12309 sinfo->txrate.mcs = pAdapter->hdd_stats.ClassA_stat.mcs_index;
Leo Chang6f8870f2013-03-26 18:11:36 -070012310#ifdef WLAN_FEATURE_11AC
12311 sinfo->txrate.nss = 1;
12312 if (rate_flags & eHAL_TX_RATE_VHT80)
12313 {
12314 sinfo->txrate.flags |= RATE_INFO_FLAGS_VHT_MCS;
12315 }
12316 else
12317#endif /* WLAN_FEATURE_11AC */
12318 {
12319 sinfo->txrate.flags |= RATE_INFO_FLAGS_MCS;
12320 }
Jeff Johnson295189b2012-06-20 16:38:30 -070012321 if (rate_flags & eHAL_TX_RATE_SGI)
12322 {
12323 sinfo->txrate.flags |= RATE_INFO_FLAGS_SHORT_GI;
12324 }
12325 if (rate_flags & eHAL_TX_RATE_HT40)
12326 {
12327 sinfo->txrate.flags |= RATE_INFO_FLAGS_40_MHZ_WIDTH;
12328 }
Leo Chang6f8870f2013-03-26 18:11:36 -070012329#ifdef WLAN_FEATURE_11AC
12330 else if (rate_flags & eHAL_TX_RATE_VHT80)
12331 {
12332 sinfo->txrate.flags |= RATE_INFO_FLAGS_80_MHZ_WIDTH;
12333 }
12334#endif /* WLAN_FEATURE_11AC */
Jeff Johnson295189b2012-06-20 16:38:30 -070012335#ifdef LINKSPEED_DEBUG_ENABLED
12336 pr_info("Reporting actual MCS rate %d flags %x\n",
12337 sinfo->txrate.mcs,
12338 sinfo->txrate.flags );
12339#endif //LINKSPEED_DEBUG_ENABLED
12340 }
12341 }
12342 sinfo->filled |= STATION_INFO_TX_BITRATE;
12343
Madan Mohan Koyyalamudi4d4d2812012-09-24 14:08:29 -070012344 sinfo->tx_packets =
12345 pAdapter->hdd_stats.summary_stat.tx_frm_cnt[0] +
12346 pAdapter->hdd_stats.summary_stat.tx_frm_cnt[1] +
12347 pAdapter->hdd_stats.summary_stat.tx_frm_cnt[2] +
12348 pAdapter->hdd_stats.summary_stat.tx_frm_cnt[3];
12349
12350 sinfo->tx_retries =
12351 pAdapter->hdd_stats.summary_stat.retry_cnt[0] +
12352 pAdapter->hdd_stats.summary_stat.retry_cnt[1] +
12353 pAdapter->hdd_stats.summary_stat.retry_cnt[2] +
12354 pAdapter->hdd_stats.summary_stat.retry_cnt[3];
12355
12356 sinfo->tx_failed =
12357 pAdapter->hdd_stats.summary_stat.fail_cnt[0] +
12358 pAdapter->hdd_stats.summary_stat.fail_cnt[1] +
12359 pAdapter->hdd_stats.summary_stat.fail_cnt[2] +
12360 pAdapter->hdd_stats.summary_stat.fail_cnt[3];
12361
12362 sinfo->filled |=
12363 STATION_INFO_TX_PACKETS |
12364 STATION_INFO_TX_RETRIES |
12365 STATION_INFO_TX_FAILED;
12366
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053012367 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
12368 TRACE_CODE_HDD_CFG80211_GET_STA,
12369 pAdapter->sessionId, maxRate));
Madan Mohan Koyyalamudi4d4d2812012-09-24 14:08:29 -070012370 EXIT();
12371 return 0;
Jeff Johnson295189b2012-06-20 16:38:30 -070012372}
12373
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053012374static int wlan_hdd_cfg80211_get_station(struct wiphy *wiphy, struct net_device *dev,
12375 u8* mac, struct station_info *sinfo)
12376{
12377 int ret;
12378
12379 vos_ssr_protect(__func__);
12380 ret = __wlan_hdd_cfg80211_get_station(wiphy, dev, mac, sinfo);
12381 vos_ssr_unprotect(__func__);
12382
12383 return ret;
12384}
12385
12386static int __wlan_hdd_cfg80211_set_power_mgmt(struct wiphy *wiphy,
Sameer Thalappilc9f26e92013-06-07 10:11:06 -070012387 struct net_device *dev, bool mode, int timeout)
Jeff Johnson295189b2012-06-20 16:38:30 -070012388{
12389 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
Gopichand Nakkala20c4c042013-04-19 22:08:55 +053012390 hdd_context_t *pHddCtx;
Jeff Johnson295189b2012-06-20 16:38:30 -070012391 VOS_STATUS vos_status;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053012392 int status;
Jeff Johnson295189b2012-06-20 16:38:30 -070012393
Jeff Johnsone7245742012-09-05 17:12:55 -070012394 ENTER();
12395
Jeff Johnson295189b2012-06-20 16:38:30 -070012396 if (NULL == pAdapter)
12397 {
Arif Hussain6d2a3322013-11-17 19:50:10 -080012398 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Adapter is NULL", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -070012399 return -ENODEV;
12400 }
12401
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053012402 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
12403 TRACE_CODE_HDD_CFG80211_SET_POWER_MGMT,
12404 pAdapter->sessionId, timeout));
12405
Gopichand Nakkala20c4c042013-04-19 22:08:55 +053012406 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053012407 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkala20c4c042013-04-19 22:08:55 +053012408
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053012409 if (0 != status)
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012410 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053012411 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
12412 "%s: HDD context is not valid", __func__);
12413 return status;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012414 }
12415
Gopichand Nakkala20c4c042013-04-19 22:08:55 +053012416 if ((DRIVER_POWER_MODE_AUTO == !mode) &&
12417 (TRUE == pHddCtx->hdd_wlan_suspended) &&
12418 (pHddCtx->cfg_ini->fhostArpOffload) &&
12419 (eConnectionState_Associated ==
12420 (WLAN_HDD_GET_STATION_CTX_PTR(pAdapter))->conn_info.connState))
12421 {
Amar Singhald53568e2013-09-26 11:03:45 -070012422
12423 hddLog(VOS_TRACE_LEVEL_INFO,
12424 "offload: in cfg80211_set_power_mgmt, calling arp offload");
Gopichand Nakkalab03e8082013-05-30 18:09:25 +053012425 vos_status = hdd_conf_arp_offload(pAdapter, TRUE);
Gopichand Nakkala20c4c042013-04-19 22:08:55 +053012426 if (!VOS_IS_STATUS_SUCCESS(vos_status))
12427 {
12428 hddLog(VOS_TRACE_LEVEL_INFO,
Arif Hussain6d2a3322013-11-17 19:50:10 -080012429 "%s:Failed to enable ARPOFFLOAD Feature %d",
Gopichand Nakkala20c4c042013-04-19 22:08:55 +053012430 __func__, vos_status);
12431 }
12432 }
12433
Jeff Johnson295189b2012-06-20 16:38:30 -070012434 /**The get power cmd from the supplicant gets updated by the nl only
12435 *on successful execution of the function call
12436 *we are oppositely mapped w.r.t mode in the driver
12437 **/
12438 vos_status = wlan_hdd_enter_bmps(pAdapter, !mode);
12439
Jeff Johnsone7245742012-09-05 17:12:55 -070012440 EXIT();
Jeff Johnson295189b2012-06-20 16:38:30 -070012441 if (VOS_STATUS_E_FAILURE == vos_status)
12442 {
c_hpothu6ff1c3c2013-10-01 19:01:57 +053012443 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
12444 "%s: failed to enter bmps mode", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -070012445 return -EINVAL;
12446 }
12447 return 0;
12448}
12449
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053012450static int wlan_hdd_cfg80211_set_power_mgmt(struct wiphy *wiphy,
12451 struct net_device *dev, bool mode, int timeout)
12452{
12453 int ret;
Jeff Johnson295189b2012-06-20 16:38:30 -070012454
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053012455 vos_ssr_protect(__func__);
12456 ret = __wlan_hdd_cfg80211_set_power_mgmt(wiphy, dev, mode, timeout);
12457 vos_ssr_unprotect(__func__);
12458
12459 return ret;
12460}
Jeff Johnson295189b2012-06-20 16:38:30 -070012461#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
12462static int wlan_hdd_set_default_mgmt_key(struct wiphy *wiphy,
12463 struct net_device *netdev,
12464 u8 key_index)
12465{
Jeff Johnsone7245742012-09-05 17:12:55 -070012466 ENTER();
Jeff Johnson295189b2012-06-20 16:38:30 -070012467 return 0;
12468}
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012469#endif //LINUX_VERSION_CODE
Jeff Johnson295189b2012-06-20 16:38:30 -070012470
12471#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,4,0))
12472static int wlan_hdd_set_txq_params(struct wiphy *wiphy,
12473 struct net_device *dev,
12474 struct ieee80211_txq_params *params)
12475{
Jeff Johnsone7245742012-09-05 17:12:55 -070012476 ENTER();
Jeff Johnson295189b2012-06-20 16:38:30 -070012477 return 0;
12478}
12479#elif (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
12480static int wlan_hdd_set_txq_params(struct wiphy *wiphy,
12481 struct ieee80211_txq_params *params)
12482{
Jeff Johnsone7245742012-09-05 17:12:55 -070012483 ENTER();
Jeff Johnson295189b2012-06-20 16:38:30 -070012484 return 0;
12485}
12486#endif //LINUX_VERSION_CODE
12487
Naresh Jayaram69e3f282014-10-14 12:29:12 +053012488#ifdef CFG80211_DEL_STA_V2
12489static int __wlan_hdd_cfg80211_del_station(struct wiphy *wiphy,
12490 struct net_device *dev,
12491 struct station_del_parameters *param)
12492#else
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053012493static int __wlan_hdd_cfg80211_del_station(struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -070012494 struct net_device *dev, u8 *mac)
Naresh Jayaram69e3f282014-10-14 12:29:12 +053012495#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070012496{
12497 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053012498 hdd_context_t *pHddCtx;
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -080012499 VOS_STATUS vos_status;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053012500 int status;
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -080012501 v_U8_t staId;
Jeff Johnson295189b2012-06-20 16:38:30 -070012502
Jeff Johnsone7245742012-09-05 17:12:55 -070012503 ENTER();
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053012504
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053012505 if ( NULL == pAdapter )
Jeff Johnson295189b2012-06-20 16:38:30 -070012506 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053012507 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Invalid Adapter" ,__func__);
Jeff Johnson295189b2012-06-20 16:38:30 -070012508 return -EINVAL;
12509 }
12510
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053012511 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
12512 TRACE_CODE_HDD_CFG80211_DEL_STA,
12513 pAdapter->sessionId, pAdapter->device_mode));
12514
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053012515 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
12516 status = wlan_hdd_validate_context(pHddCtx);
Jeff Johnson295189b2012-06-20 16:38:30 -070012517
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053012518 if (0 != status)
Jeff Johnson04dd8a82012-06-29 20:41:40 -070012519 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053012520 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
12521 "%s: HDD context is not valid", __func__);
12522 return status;
Jeff Johnson04dd8a82012-06-29 20:41:40 -070012523 }
12524
Jeff Johnson295189b2012-06-20 16:38:30 -070012525 if ( (WLAN_HDD_SOFTAP == pAdapter->device_mode)
Jeff Johnson295189b2012-06-20 16:38:30 -070012526 || (WLAN_HDD_P2P_GO == pAdapter->device_mode)
Jeff Johnson295189b2012-06-20 16:38:30 -070012527 )
12528 {
12529 if( NULL == mac )
12530 {
12531 v_U16_t i;
12532 for(i = 0; i < WLAN_MAX_STA_COUNT; i++)
12533 {
Rajesh Chauhan18488fc2013-08-22 10:15:03 -070012534 if ((pAdapter->aStaInfo[i].isUsed) &&
12535 (!pAdapter->aStaInfo[i].isDeauthInProgress))
Jeff Johnson295189b2012-06-20 16:38:30 -070012536 {
12537 u8 *macAddr = pAdapter->aStaInfo[i].macAddrSTA.bytes;
12538 hddLog(VOS_TRACE_LEVEL_INFO,
Arif Hussain24bafea2013-11-15 15:10:03 -080012539 "%s: Delete STA with MAC::"
12540 MAC_ADDRESS_STR,
12541 __func__, MAC_ADDR_ARRAY(macAddr));
Rajesh Chauhan18488fc2013-08-22 10:15:03 -070012542 vos_status = hdd_softap_sta_deauth(pAdapter, macAddr);
12543 if (VOS_IS_STATUS_SUCCESS(vos_status))
12544 pAdapter->aStaInfo[i].isDeauthInProgress = TRUE;
Jeff Johnson295189b2012-06-20 16:38:30 -070012545 }
12546 }
12547 }
12548 else
12549 {
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -080012550
12551 vos_status = hdd_softap_GetStaId(pAdapter,(v_MACADDR_t *)mac, &staId);
12552 if (!VOS_IS_STATUS_SUCCESS(vos_status))
12553 {
12554 hddLog(VOS_TRACE_LEVEL_INFO,
Arif Hussain24bafea2013-11-15 15:10:03 -080012555 "%s: Skip this DEL STA as this is not used::"
12556 MAC_ADDRESS_STR,
12557 __func__, MAC_ADDR_ARRAY(mac));
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -080012558 return -ENOENT;
12559 }
12560
12561 if( pAdapter->aStaInfo[staId].isDeauthInProgress == TRUE)
12562 {
12563 hddLog(VOS_TRACE_LEVEL_INFO,
Arif Hussain24bafea2013-11-15 15:10:03 -080012564 "%s: Skip this DEL STA as deauth is in progress::"
12565 MAC_ADDRESS_STR,
12566 __func__, MAC_ADDR_ARRAY(mac));
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -080012567 return -ENOENT;
12568 }
12569
12570 pAdapter->aStaInfo[staId].isDeauthInProgress = TRUE;
12571
Jeff Johnson295189b2012-06-20 16:38:30 -070012572 hddLog(VOS_TRACE_LEVEL_INFO,
12573 "%s: Delete STA with MAC::"
Arif Hussain24bafea2013-11-15 15:10:03 -080012574 MAC_ADDRESS_STR,
Jeff Johnson295189b2012-06-20 16:38:30 -070012575 __func__,
Arif Hussain24bafea2013-11-15 15:10:03 -080012576 MAC_ADDR_ARRAY(mac));
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -080012577
12578 vos_status = hdd_softap_sta_deauth(pAdapter, mac);
12579 if (!VOS_IS_STATUS_SUCCESS(vos_status))
12580 {
12581 pAdapter->aStaInfo[staId].isDeauthInProgress = FALSE;
12582 hddLog(VOS_TRACE_LEVEL_INFO,
12583 "%s: STA removal failed for ::"
Arif Hussain24bafea2013-11-15 15:10:03 -080012584 MAC_ADDRESS_STR,
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -080012585 __func__,
Arif Hussain24bafea2013-11-15 15:10:03 -080012586 MAC_ADDR_ARRAY(mac));
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -080012587 return -ENOENT;
12588 }
12589
Jeff Johnson295189b2012-06-20 16:38:30 -070012590 }
12591 }
12592
12593 EXIT();
12594
12595 return 0;
12596}
Naresh Jayaram69e3f282014-10-14 12:29:12 +053012597
12598#ifdef CFG80211_DEL_STA_V2
12599static int wlan_hdd_cfg80211_del_station(struct wiphy *wiphy,
12600 struct net_device *dev,
12601 struct station_del_parameters *param)
12602#else
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053012603static int wlan_hdd_cfg80211_del_station(struct wiphy *wiphy,
12604 struct net_device *dev, u8 *mac)
Naresh Jayaram69e3f282014-10-14 12:29:12 +053012605#endif
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053012606{
12607 int ret;
Jeff Johnson295189b2012-06-20 16:38:30 -070012608
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053012609 vos_ssr_protect(__func__);
Naresh Jayaram69e3f282014-10-14 12:29:12 +053012610#ifdef CFG80211_DEL_STA_V2
12611 ret = __wlan_hdd_cfg80211_del_station(wiphy, dev, param);
12612#else
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053012613 ret = __wlan_hdd_cfg80211_del_station(wiphy, dev, mac);
Naresh Jayaram69e3f282014-10-14 12:29:12 +053012614#endif
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053012615 vos_ssr_unprotect(__func__);
12616
12617 return ret;
12618}
12619
12620static int __wlan_hdd_cfg80211_add_station(struct wiphy *wiphy,
Hoonki Lee11f7dda2013-02-14 16:55:44 -080012621 struct net_device *dev, u8 *mac, struct station_parameters *params)
12622{
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053012623 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
Gopichand Nakkalab977a972013-02-18 19:15:09 -080012624 int status = -EPERM;
Hoonki Lee11f7dda2013-02-14 16:55:44 -080012625#ifdef FEATURE_WLAN_TDLS
12626 u32 mask, set;
Hoonki Lee11f7dda2013-02-14 16:55:44 -080012627 ENTER();
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053012628
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053012629 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
12630 TRACE_CODE_HDD_CFG80211_ADD_STA,
12631 pAdapter->sessionId, params->listen_interval));
Mohit Khanna698ba2a2012-12-04 15:08:18 -080012632 mask = params->sta_flags_mask;
12633
12634 set = params->sta_flags_set;
12635
Gopichand Nakkalac87400e2013-03-13 18:51:00 -070012636#ifdef WLAN_FEATURE_TDLS_DEBUG
12637 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
12638 "%s: mask 0x%x set 0x%x " MAC_ADDRESS_STR,
12639 __func__, mask, set, MAC_ADDR_ARRAY(mac));
12640#endif
Mohit Khanna698ba2a2012-12-04 15:08:18 -080012641
12642 if (mask & BIT(NL80211_STA_FLAG_TDLS_PEER)) {
12643 if (set & BIT(NL80211_STA_FLAG_TDLS_PEER)) {
Gopichand Nakkala681989c2013-03-06 22:27:48 -080012644 status = wlan_hdd_tdls_add_station(wiphy, dev, mac, 0, NULL);
Mohit Khanna698ba2a2012-12-04 15:08:18 -080012645 }
12646 }
12647#endif
Gopichand Nakkalab977a972013-02-18 19:15:09 -080012648 return status;
Jeff Johnson295189b2012-06-20 16:38:30 -070012649}
12650
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053012651static int wlan_hdd_cfg80211_add_station(struct wiphy *wiphy,
12652 struct net_device *dev, u8 *mac, struct station_parameters *params)
12653{
12654 int ret;
Jeff Johnson04dd8a82012-06-29 20:41:40 -070012655
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053012656 vos_ssr_protect(__func__);
12657 ret = __wlan_hdd_cfg80211_add_station(wiphy, dev, mac, params);
12658 vos_ssr_unprotect(__func__);
12659
12660 return ret;
12661}
Jeff Johnson04dd8a82012-06-29 20:41:40 -070012662#ifdef FEATURE_WLAN_LFR
Wilson Yang6507c4e2013-10-01 20:11:19 -070012663
Mahesh A Saptasagarf7418d72014-06-02 14:48:54 +053012664static int __wlan_hdd_cfg80211_set_pmksa(struct wiphy *wiphy, struct net_device *dev,
Jeff Johnsond13512a2012-07-17 11:42:19 -070012665 struct cfg80211_pmksa *pmksa)
Jeff Johnson04dd8a82012-06-29 20:41:40 -070012666{
Jeff Johnson04dd8a82012-06-29 20:41:40 -070012667 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
12668 tHalHandle halHandle;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012669 eHalStatus result;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053012670 int status;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053012671 hdd_context_t *pHddCtx;
Kanchanapally, Vidyullatha2633ace2014-09-25 15:16:50 +053012672 tPmkidCacheInfo pmk_id;
Jeff Johnsone7245742012-09-05 17:12:55 -070012673
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012674 // Validate pAdapter
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053012675 if ( NULL == pAdapter )
Jeff Johnson04dd8a82012-06-29 20:41:40 -070012676 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053012677 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Invalid Adapter" ,__func__);
Jeff Johnson04dd8a82012-06-29 20:41:40 -070012678 return -EINVAL;
12679 }
12680
Kanchanapally, Vidyullatha2633ace2014-09-25 15:16:50 +053012681 if (!pmksa) {
12682 hddLog(LOGE, FL("pmksa is NULL"));
12683 return -EINVAL;
12684 }
12685
12686 if (!pmksa->bssid || !pmksa->pmkid) {
12687 hddLog(LOGE, FL("pmksa->bssid(%p) or pmksa->pmkid(%p) is NULL"),
12688 pmksa->bssid, pmksa->pmkid);
12689 return -EINVAL;
12690 }
12691
12692 hddLog(VOS_TRACE_LEVEL_DEBUG, "%s: set PMKSA for " MAC_ADDRESS_STR,
12693 __func__, MAC_ADDR_ARRAY(pmksa->bssid));
12694
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053012695 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
12696 status = wlan_hdd_validate_context(pHddCtx);
Jeff Johnson04dd8a82012-06-29 20:41:40 -070012697
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053012698 if (0 != status)
Jeff Johnson04dd8a82012-06-29 20:41:40 -070012699 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053012700 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
12701 "%s: HDD context is not valid", __func__);
12702 return status;
Jeff Johnson04dd8a82012-06-29 20:41:40 -070012703 }
12704
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012705 // Retrieve halHandle
Jeff Johnson04dd8a82012-06-29 20:41:40 -070012706 halHandle = WLAN_HDD_GET_HAL_CTX(pAdapter);
12707
Kanchanapally, Vidyullatha2633ace2014-09-25 15:16:50 +053012708 vos_mem_copy(pmk_id.BSSID, pmksa->bssid, ETHER_ADDR_LEN);
12709 vos_mem_copy(pmk_id.PMKID, pmksa->pmkid, CSR_RSN_PMKID_SIZE);
Jeff Johnson04dd8a82012-06-29 20:41:40 -070012710
Kanchanapally, Vidyullatha2633ace2014-09-25 15:16:50 +053012711 /* Add to the PMKSA ID Cache in CSR */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012712 result = sme_RoamSetPMKIDCache(halHandle,pAdapter->sessionId,
Kanchanapally, Vidyullatha2633ace2014-09-25 15:16:50 +053012713 &pmk_id, 1, FALSE);
12714
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053012715 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
12716 TRACE_CODE_HDD_CFG80211_SET_PMKSA,
12717 pAdapter->sessionId, result));
Kanchanapally, Vidyullatha2633ace2014-09-25 15:16:50 +053012718
12719 return HAL_STATUS_SUCCESS(result) ? 0 : -EINVAL;
Jeff Johnson04dd8a82012-06-29 20:41:40 -070012720}
12721
Mahesh A Saptasagarf7418d72014-06-02 14:48:54 +053012722static int wlan_hdd_cfg80211_set_pmksa(struct wiphy *wiphy, struct net_device *dev,
12723 struct cfg80211_pmksa *pmksa)
12724{
12725 int ret;
12726
12727 vos_ssr_protect(__func__);
12728 ret = __wlan_hdd_cfg80211_set_pmksa(wiphy, dev, pmksa);
12729 vos_ssr_unprotect(__func__);
12730
12731 return ret;
12732}
Jeff Johnson04dd8a82012-06-29 20:41:40 -070012733
Wilson Yang6507c4e2013-10-01 20:11:19 -070012734
Mahesh A Saptasagarf7418d72014-06-02 14:48:54 +053012735static int __wlan_hdd_cfg80211_del_pmksa(struct wiphy *wiphy, struct net_device *dev,
Wilson Yang6507c4e2013-10-01 20:11:19 -070012736 struct cfg80211_pmksa *pmksa)
Jeff Johnson04dd8a82012-06-29 20:41:40 -070012737{
Wilson Yang6507c4e2013-10-01 20:11:19 -070012738 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
12739 tHalHandle halHandle;
Wilson Yang6507c4e2013-10-01 20:11:19 -070012740 hdd_context_t *pHddCtx;
Wilson Yangef657d32014-01-15 19:19:23 -080012741 int status = 0;
Wilson Yang6507c4e2013-10-01 20:11:19 -070012742
Wilson Yang6507c4e2013-10-01 20:11:19 -070012743 /* Validate pAdapter */
12744 if (NULL == pAdapter)
12745 {
12746 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Invalid Adapter" ,__func__);
12747 return -EINVAL;
12748 }
12749
Kanchanapally, Vidyullatha2633ace2014-09-25 15:16:50 +053012750 if (!pmksa) {
12751 hddLog(LOGE, FL("pmksa is NULL"));
12752 return -EINVAL;
12753 }
12754
12755 if (!pmksa->bssid) {
12756 hddLog(LOGE, FL("pmksa->bssid is NULL"));
12757 return -EINVAL;
12758 }
12759
Kiet Lam98c46a12014-10-31 15:34:57 -070012760 hddLog(VOS_TRACE_LEVEL_DEBUG, "%s: deleting PMKSA for " MAC_ADDRESS_STR,
12761 __func__, MAC_ADDR_ARRAY(pmksa->bssid));
12762
Wilson Yang6507c4e2013-10-01 20:11:19 -070012763 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
12764 status = wlan_hdd_validate_context(pHddCtx);
12765
12766 if (0 != status)
12767 {
12768 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
12769 "%s: HDD context is not valid", __func__);
12770 return status;
12771 }
12772
12773 /*Retrieve halHandle*/
12774 halHandle = WLAN_HDD_GET_HAL_CTX(pAdapter);
12775
Kanchanapally, Vidyullatha2633ace2014-09-25 15:16:50 +053012776 /* Delete the PMKID CSR cache */
12777 if (eHAL_STATUS_SUCCESS !=
12778 sme_RoamDelPMKIDfromCache(halHandle,
12779 pAdapter->sessionId, pmksa->bssid, FALSE)) {
12780 hddLog(LOGE, FL("Failed to delete PMKSA for "MAC_ADDRESS_STR),
12781 MAC_ADDR_ARRAY(pmksa->bssid));
12782 status = -EINVAL;
Wilson Yang6507c4e2013-10-01 20:11:19 -070012783 }
12784
Wilson Yangef657d32014-01-15 19:19:23 -080012785 return status;
Jeff Johnson04dd8a82012-06-29 20:41:40 -070012786}
12787
Wilson Yang6507c4e2013-10-01 20:11:19 -070012788
Mahesh A Saptasagarf7418d72014-06-02 14:48:54 +053012789static int wlan_hdd_cfg80211_del_pmksa(struct wiphy *wiphy, struct net_device *dev,
12790 struct cfg80211_pmksa *pmksa)
12791{
12792 int ret;
Wilson Yang6507c4e2013-10-01 20:11:19 -070012793
Mahesh A Saptasagarf7418d72014-06-02 14:48:54 +053012794 vos_ssr_protect(__func__);
12795 ret = __wlan_hdd_cfg80211_del_pmksa(wiphy, dev, pmksa);
12796 vos_ssr_unprotect(__func__);
12797
12798 return ret;
12799
12800}
12801
12802static int __wlan_hdd_cfg80211_flush_pmksa(struct wiphy *wiphy, struct net_device *dev)
Jeff Johnson04dd8a82012-06-29 20:41:40 -070012803{
Wilson Yang6507c4e2013-10-01 20:11:19 -070012804 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
12805 tHalHandle halHandle;
12806 hdd_context_t *pHddCtx;
Wilson Yangef657d32014-01-15 19:19:23 -080012807 int status = 0;
Wilson Yang6507c4e2013-10-01 20:11:19 -070012808
12809 hddLog(VOS_TRACE_LEVEL_DEBUG, "%s: flushing PMKSA ",__func__);
12810
12811 /* Validate pAdapter */
12812 if (NULL == pAdapter)
12813 {
12814 hddLog(VOS_TRACE_LEVEL_ERROR,
12815 "%s: Invalid Adapter" ,__func__);
12816 return -EINVAL;
12817 }
12818
12819 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
12820 status = wlan_hdd_validate_context(pHddCtx);
12821
12822 if (0 != status)
12823 {
12824 hddLog(VOS_TRACE_LEVEL_ERROR,
12825 "%s: HDD context is not valid", __func__);
12826 return status;
12827 }
12828
12829 /*Retrieve halHandle*/
12830 halHandle = WLAN_HDD_GET_HAL_CTX(pAdapter);
12831
Kanchanapally, Vidyullatha2633ace2014-09-25 15:16:50 +053012832 /* Flush the PMKID cache in CSR */
12833 if (eHAL_STATUS_SUCCESS !=
12834 sme_RoamDelPMKIDfromCache(halHandle, pAdapter->sessionId, NULL, TRUE)) {
12835 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Cannot flush PMKIDCache"));
12836 status = -EINVAL;
Wilson Yang6507c4e2013-10-01 20:11:19 -070012837 }
12838
Wilson Yangef657d32014-01-15 19:19:23 -080012839 return status;
Jeff Johnson04dd8a82012-06-29 20:41:40 -070012840}
Mahesh A Saptasagarf7418d72014-06-02 14:48:54 +053012841
12842static int wlan_hdd_cfg80211_flush_pmksa(struct wiphy *wiphy, struct net_device *dev)
12843{
12844 int ret;
12845
12846 vos_ssr_protect(__func__);
12847 ret = __wlan_hdd_cfg80211_flush_pmksa(wiphy, dev);
12848 vos_ssr_unprotect(__func__);
12849
12850 return ret;
12851}
Jeff Johnson04dd8a82012-06-29 20:41:40 -070012852#endif
12853
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070012854#if defined(WLAN_FEATURE_VOWIFI_11R) && defined(KERNEL_SUPPORT_11R_CFG80211)
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053012855static int __wlan_hdd_cfg80211_update_ft_ies(struct wiphy *wiphy,
12856 struct net_device *dev,
12857 struct cfg80211_update_ft_ies_params *ftie)
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070012858{
12859 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
12860 hdd_station_ctx_t *pHddStaCtx;
12861
12862 if (NULL == pAdapter)
12863 {
Arif Hussain6d2a3322013-11-17 19:50:10 -080012864 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Adapter is NULL", __func__);
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070012865 return -ENODEV;
12866 }
12867
12868 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
12869
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053012870 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
12871 TRACE_CODE_HDD_CFG80211_UPDATE_FT_IES,
12872 pAdapter->sessionId, pHddStaCtx->conn_info.connState));
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070012873 // Added for debug on reception of Re-assoc Req.
12874 if (eConnectionState_Associated != pHddStaCtx->conn_info.connState)
12875 {
Arif Hussain6d2a3322013-11-17 19:50:10 -080012876 hddLog(LOGE, FL("Called with Ie of length = %zu when not associated"),
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070012877 ftie->ie_len);
Arif Hussain6d2a3322013-11-17 19:50:10 -080012878 hddLog(LOGE, FL("Should be Re-assoc Req IEs"));
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070012879 }
12880
12881#ifdef WLAN_FEATURE_VOWIFI_11R_DEBUG
Arif Hussain6d2a3322013-11-17 19:50:10 -080012882 hddLog(LOGE, FL("%s called with Ie of length = %zu"), __func__,
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070012883 ftie->ie_len);
12884#endif
12885
12886 // Pass the received FT IEs to SME
Gopichand Nakkala356fb102013-03-06 12:34:04 +053012887 sme_SetFTIEs( WLAN_HDD_GET_HAL_CTX(pAdapter), pAdapter->sessionId,
12888 (const u8 *)ftie->ie,
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070012889 ftie->ie_len);
12890 return 0;
12891}
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053012892
12893static int wlan_hdd_cfg80211_update_ft_ies(struct wiphy *wiphy,
12894 struct net_device *dev,
12895 struct cfg80211_update_ft_ies_params *ftie)
12896{
12897 int ret;
12898
12899 vos_ssr_protect(__func__);
12900 ret = __wlan_hdd_cfg80211_update_ft_ies(wiphy, dev, ftie);
12901 vos_ssr_unprotect(__func__);
12902
12903 return ret;
12904}
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070012905#endif
Jeff Johnson04dd8a82012-06-29 20:41:40 -070012906
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053012907#ifdef FEATURE_WLAN_SCAN_PNO
12908
12909void hdd_cfg80211_sched_scan_done_callback(void *callbackContext,
12910 tSirPrefNetworkFoundInd *pPrefNetworkFoundInd)
12911{
12912 int ret;
12913 hdd_adapter_t* pAdapter = (hdd_adapter_t*)callbackContext;
12914 hdd_context_t *pHddCtx;
12915
Nirav Shah80830bf2013-12-31 16:35:12 +053012916 ENTER();
12917
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053012918 if (NULL == pAdapter)
12919 {
Agarwal Ashish971c2882013-10-30 20:11:12 +053012920 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053012921 "%s: HDD adapter is Null", __func__);
12922 return ;
12923 }
12924
12925 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
12926 if (NULL == pHddCtx)
12927 {
12928 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
12929 "%s: HDD context is Null!!!", __func__);
12930 return ;
12931 }
12932
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053012933 spin_lock(&pHddCtx->schedScan_lock);
12934 if (TRUE == pHddCtx->isWiphySuspended)
12935 {
12936 pHddCtx->isSchedScanUpdatePending = TRUE;
12937 spin_unlock(&pHddCtx->schedScan_lock);
12938 hddLog(VOS_TRACE_LEVEL_INFO,
12939 "%s: Update cfg80211 scan database after it resume", __func__);
12940 return ;
12941 }
12942 spin_unlock(&pHddCtx->schedScan_lock);
12943
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053012944 ret = wlan_hdd_cfg80211_update_bss(pHddCtx->wiphy, pAdapter);
12945
12946 if (0 > ret)
12947 hddLog(VOS_TRACE_LEVEL_INFO, "%s: NO SCAN result", __func__);
12948
12949 cfg80211_sched_scan_results(pHddCtx->wiphy);
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053012950 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
12951 "%s: cfg80211 scan result database updated", __func__);
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053012952}
12953
12954/*
Mahesh A Saptasagar0f7b0372013-11-28 23:23:07 +053012955 * FUNCTION: wlan_hdd_is_pno_allowed
Vinay Krishna Erannacbf75f42014-02-26 17:35:20 +053012956 * Disallow pno if any session is active
Mahesh A Saptasagar0f7b0372013-11-28 23:23:07 +053012957 */
12958static eHalStatus wlan_hdd_is_pno_allowed(hdd_adapter_t *pAdapter)
12959{
12960 hdd_adapter_list_node_t *pAdapterNode = NULL, *pNext = NULL;
12961 hdd_adapter_t *pTempAdapter = NULL;
Vinay Krishna Eranna23ffd182013-12-26 19:16:55 +053012962 hdd_station_ctx_t *pStaCtx;
Mahesh A Saptasagar0f7b0372013-11-28 23:23:07 +053012963 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
12964 int status = 0;
12965 status = hdd_get_front_adapter(pHddCtx, &pAdapterNode);
12966
Vinay Krishna Erannacbf75f42014-02-26 17:35:20 +053012967 /* The current firmware design does not allow PNO during any
12968 * active sessions. Hence, determine the active sessions
12969 * and return a failure.
12970 */
Mahesh A Saptasagar0f7b0372013-11-28 23:23:07 +053012971 while ((NULL != pAdapterNode) && (VOS_STATUS_SUCCESS == status))
12972 {
12973 pTempAdapter = pAdapterNode->pAdapter;
Vinay Krishna Eranna23ffd182013-12-26 19:16:55 +053012974 pStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pTempAdapter);
Mahesh A Saptasagar0f7b0372013-11-28 23:23:07 +053012975
Vinay Krishna Eranna23ffd182013-12-26 19:16:55 +053012976 if (((WLAN_HDD_INFRA_STATION == pTempAdapter->device_mode)
12977 && (eConnectionState_NotConnected != pStaCtx->conn_info.connState))
12978 || (WLAN_HDD_P2P_CLIENT == pTempAdapter->device_mode)
12979 || (WLAN_HDD_P2P_GO == pTempAdapter->device_mode)
12980 || (WLAN_HDD_SOFTAP == pTempAdapter->device_mode)
12981 )
Mahesh A Saptasagar0f7b0372013-11-28 23:23:07 +053012982 {
Vinay Krishna Eranna23ffd182013-12-26 19:16:55 +053012983 return eHAL_STATUS_FAILURE;
Mahesh A Saptasagar0f7b0372013-11-28 23:23:07 +053012984 }
12985 status = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
12986 pAdapterNode = pNext;
12987 }
Vinay Krishna Eranna23ffd182013-12-26 19:16:55 +053012988 return eHAL_STATUS_SUCCESS;
Mahesh A Saptasagar0f7b0372013-11-28 23:23:07 +053012989}
12990
Vinay Krishna Erannaf0e523b2014-03-01 21:00:16 +053012991void hdd_cfg80211_sched_scan_start_status_cb(void *callbackContext, VOS_STATUS status)
12992{
12993 hdd_adapter_t *pAdapter = callbackContext;
12994 hdd_context_t *pHddCtx;
12995
12996 if ((NULL == pAdapter) || (WLAN_HDD_ADAPTER_MAGIC != pAdapter->magic))
12997 {
12998 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
12999 FL("Invalid adapter or adapter has invalid magic"));
13000 return;
13001 }
13002
13003 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
13004 if (0 != wlan_hdd_validate_context(pHddCtx))
13005 {
13006 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
13007 FL("HDD context is not valid"));
13008 return;
13009 }
13010
c_hpothub53c45d2014-08-18 16:53:14 +053013011 if (VOS_STATUS_SUCCESS != status)
13012 {
13013 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Vinay Krishna Erannaf0e523b2014-03-01 21:00:16 +053013014 FL("PNO enable response status = %d"), status);
c_hpothub53c45d2014-08-18 16:53:14 +053013015 pHddCtx->isPnoEnable = FALSE;
13016 }
Vinay Krishna Erannaf0e523b2014-03-01 21:00:16 +053013017
13018 pAdapter->pno_req_status = (status == VOS_STATUS_SUCCESS) ? 0 : -EBUSY;
13019 complete(&pAdapter->pno_comp_var);
13020}
13021
Mahesh A Saptasagar0f7b0372013-11-28 23:23:07 +053013022/*
Mahesh A Saptasagar6cc38562014-05-23 21:22:17 +053013023 * FUNCTION: __wlan_hdd_cfg80211_sched_scan_start
13024 * Function to enable PNO
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053013025 */
Mahesh A Saptasagar6cc38562014-05-23 21:22:17 +053013026static int __wlan_hdd_cfg80211_sched_scan_start(struct wiphy *wiphy,
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053013027 struct net_device *dev, struct cfg80211_sched_scan_request *request)
13028{
13029 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
13030 tpSirPNOScanReq pPnoRequest = NULL;
13031 hdd_context_t *pHddCtx;
13032 tHalHandle hHal;
Mahesh A Saptasagar7bd6ad42014-07-21 18:56:33 +053013033 v_U32_t i, indx, num_ch, tempInterval, j;
Sushant Kaushikd62d9782014-02-19 15:39:40 +053013034 u8 valid_ch[WNI_CFG_VALID_CHANNEL_LIST_LEN] = {0};
13035 u8 channels_allowed[WNI_CFG_VALID_CHANNEL_LIST_LEN] = {0};
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053013036 v_U32_t num_channels_allowed = WNI_CFG_VALID_CHANNEL_LIST_LEN;
13037 eHalStatus status = eHAL_STATUS_FAILURE;
Kamath Vinayakba5313f2013-08-22 15:52:39 +053013038 int ret = 0;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053013039
13040 if (NULL == pAdapter)
13041 {
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053013042 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053013043 "%s: HDD adapter is Null", __func__);
13044 return -ENODEV;
13045 }
13046
13047 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053013048 ret = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053013049
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053013050 if (0 != ret)
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053013051 {
Gopichand Nakkalac005b7c2013-05-14 16:04:14 +053013052 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
13053 "%s: HDD context is not valid", __func__);
Kamath Vinayakba5313f2013-08-22 15:52:39 +053013054 return -EINVAL;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053013055 }
13056
13057 hHal = WLAN_HDD_GET_HAL_CTX(pAdapter);
13058 if (NULL == hHal)
13059 {
13060 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
13061 "%s: HAL context is Null!!!", __func__);
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053013062 return -EINVAL;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053013063 }
Sushant Kaushik2fe89932014-09-03 10:58:09 +053013064 sme_ScanFlushResult(hHal, pAdapter->sessionId);
Mahesh A Saptasagar2395ee62014-05-21 19:12:21 +053013065 ret = wlan_hdd_scan_abort(pAdapter);
Girish Gowli4bf7a632014-06-12 13:42:11 +053013066 if (ret < 0)
Mahesh A Saptasagar2395ee62014-05-21 19:12:21 +053013067 {
13068 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
13069 "%s: aborting the existing scan is unsuccessfull", __func__);
13070 return -EBUSY;
13071 }
13072
Vinay Krishna Eranna23ffd182013-12-26 19:16:55 +053013073 if (eHAL_STATUS_SUCCESS != wlan_hdd_is_pno_allowed(pAdapter))
Mahesh A Saptasagar0f7b0372013-11-28 23:23:07 +053013074 {
Vinay Krishna Erannacbf75f42014-02-26 17:35:20 +053013075 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_WARN,
Vinay Krishna Eranna23ffd182013-12-26 19:16:55 +053013076 FL("Cannot handle sched_scan"));
Mahesh A Saptasagar0f7b0372013-11-28 23:23:07 +053013077 return -EBUSY;
13078 }
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053013079
c_hpothu37f21312014-04-09 21:49:54 +053013080 if (TRUE == pHddCtx->isPnoEnable)
13081 {
13082 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_WARN,
13083 FL("already PNO is enabled"));
13084 return -EBUSY;
13085 }
c_hpothu225aa7c2014-10-22 17:45:13 +053013086
13087 if (VOS_STATUS_SUCCESS != wlan_hdd_cancel_remain_on_channel(pHddCtx))
13088 {
13089 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
13090 "%s: abort ROC failed ", __func__);
13091 return -EBUSY;
13092 }
13093
c_hpothu37f21312014-04-09 21:49:54 +053013094 pHddCtx->isPnoEnable = TRUE;
13095
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053013096 pPnoRequest = (tpSirPNOScanReq) vos_mem_malloc(sizeof (tSirPNOScanReq));
13097 if (NULL == pPnoRequest)
13098 {
13099 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
13100 "%s: vos_mem_malloc failed", __func__);
c_hpothu37f21312014-04-09 21:49:54 +053013101 pHddCtx->isPnoEnable = FALSE;
Kamath Vinayakba5313f2013-08-22 15:52:39 +053013102 return -ENOMEM;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053013103 }
13104
Madan Mohan Koyyalamudic3f04352013-09-26 19:21:48 +053013105 memset(pPnoRequest, 0, sizeof (tSirPNOScanReq));
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053013106 pPnoRequest->enable = 1; /*Enable PNO */
13107 pPnoRequest->ucNetworksCount = request->n_match_sets;
13108
13109 if (( !pPnoRequest->ucNetworksCount ) ||
13110 ( pPnoRequest->ucNetworksCount > SIR_PNO_MAX_SUPP_NETWORKS ))
13111 {
13112 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Sushant Kaushik1e406c32014-05-09 15:57:52 +053013113 "%s: Network input is not correct %d Max Network supported is %d",
13114 __func__, pPnoRequest->ucNetworksCount,
13115 SIR_PNO_MAX_SUPP_NETWORKS);
Kamath Vinayakba5313f2013-08-22 15:52:39 +053013116 ret = -EINVAL;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053013117 goto error;
13118 }
13119
13120 if ( SIR_PNO_MAX_NETW_CHANNELS_EX < request->n_channels )
13121 {
13122 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Nirav Shah80830bf2013-12-31 16:35:12 +053013123 "%s: Incorrect number of channels %d",
13124 __func__, request->n_channels);
Kamath Vinayakba5313f2013-08-22 15:52:39 +053013125 ret = -EINVAL;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053013126 goto error;
13127 }
13128
13129 /* Framework provides one set of channels(all)
13130 * common for all saved profile */
13131 if (0 != ccmCfgGetStr(hHal, WNI_CFG_VALID_CHANNEL_LIST,
13132 channels_allowed, &num_channels_allowed))
13133 {
13134 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
13135 "%s: failed to get valid channel list", __func__);
Kamath Vinayakba5313f2013-08-22 15:52:39 +053013136 ret = -EINVAL;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053013137 goto error;
13138 }
13139 /* Checking each channel against allowed channel list */
13140 num_ch = 0;
Nirav Shah80830bf2013-12-31 16:35:12 +053013141 if (request->n_channels)
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053013142 {
Nirav Shah80830bf2013-12-31 16:35:12 +053013143 char chList [(request->n_channels*5)+1];
13144 int len;
13145 for (i = 0, len = 0; i < request->n_channels; i++)
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053013146 {
Nirav Shah80830bf2013-12-31 16:35:12 +053013147 for (indx = 0; indx < num_channels_allowed; indx++)
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053013148 {
Nirav Shah80830bf2013-12-31 16:35:12 +053013149 if (request->channels[i]->hw_value == channels_allowed[indx])
13150 {
13151 valid_ch[num_ch++] = request->channels[i]->hw_value;
13152 len += snprintf(chList+len, 5, "%d ",
13153 request->channels[i]->hw_value);
13154 break ;
13155 }
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053013156 }
13157 }
Nirav Shah80830bf2013-12-31 16:35:12 +053013158 hddLog(VOS_TRACE_LEVEL_INFO,"Channel-List: %s ", chList);
13159 }
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053013160
13161 /* Filling per profile params */
13162 for (i = 0; i < pPnoRequest->ucNetworksCount; i++)
13163 {
13164 pPnoRequest->aNetworks[i].ssId.length =
13165 request->match_sets[i].ssid.ssid_len;
13166
13167 if (( 0 == pPnoRequest->aNetworks[i].ssId.length ) ||
13168 ( pPnoRequest->aNetworks[i].ssId.length > 32 ) )
13169 {
13170 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Nirav Shah80830bf2013-12-31 16:35:12 +053013171 "%s: SSID Len %d is not correct for network %d",
13172 __func__, pPnoRequest->aNetworks[i].ssId.length, i);
Kamath Vinayakba5313f2013-08-22 15:52:39 +053013173 ret = -EINVAL;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053013174 goto error;
13175 }
13176
13177 memcpy(pPnoRequest->aNetworks[i].ssId.ssId,
13178 request->match_sets[i].ssid.ssid,
13179 request->match_sets[i].ssid.ssid_len);
Sushant Kaushik1e406c32014-05-09 15:57:52 +053013180 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
13181 "%s: SSID of network %d is %s ", __func__,
13182 i, pPnoRequest->aNetworks[i].ssId.ssId);
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053013183 pPnoRequest->aNetworks[i].authentication = 0; /*eAUTH_TYPE_ANY*/
13184 pPnoRequest->aNetworks[i].encryption = 0; /*eED_ANY*/
13185 pPnoRequest->aNetworks[i].bcastNetwType = 0; /*eBCAST_UNKNOWN*/
13186
13187 /*Copying list of valid channel into request */
13188 memcpy(pPnoRequest->aNetworks[i].aChannels, valid_ch, num_ch);
13189 pPnoRequest->aNetworks[i].ucChannelCount = num_ch;
13190
13191 pPnoRequest->aNetworks[i].rssiThreshold = 0; //Default value
13192 }
13193
Mahesh A Saptasagar7bd6ad42014-07-21 18:56:33 +053013194 for (i = 0; i < request->n_ssids; i++)
13195 {
13196 j = 0;
13197 while (j < pPnoRequest->ucNetworksCount)
13198 {
13199 if ((pPnoRequest->aNetworks[j].ssId.length ==
13200 request->ssids[i].ssid_len) &&
13201 (0 == memcmp(pPnoRequest->aNetworks[j].ssId.ssId,
13202 request->ssids[i].ssid,
13203 pPnoRequest->aNetworks[j].ssId.length)))
13204 {
13205 pPnoRequest->aNetworks[j].bcastNetwType = eBCAST_HIDDEN;
13206 break;
13207 }
13208 j++;
13209 }
13210 }
13211 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
13212 "Number of hidden networks being Configured = %d",
13213 request->n_ssids);
Madan Mohan Koyyalamudia7765d52013-09-18 16:49:56 +053013214 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Jeff Johnson59a121e2013-11-30 09:46:08 -080013215 "request->ie_len = %zu", request->ie_len);
Madan Mohan Koyyalamudia7765d52013-09-18 16:49:56 +053013216 if ((0 < request->ie_len) && (NULL != request->ie))
13217 {
13218 pPnoRequest->us24GProbeTemplateLen = request->ie_len;
13219 memcpy(&pPnoRequest->p24GProbeTemplate, request->ie,
13220 pPnoRequest->us24GProbeTemplateLen);
13221
13222 pPnoRequest->us5GProbeTemplateLen = request->ie_len;
13223 memcpy(&pPnoRequest->p5GProbeTemplate, request->ie,
13224 pPnoRequest->us5GProbeTemplateLen);
13225 }
13226
Madan Mohan Koyyalamudi1d16f462013-08-27 16:25:34 +053013227 /* Driver gets only one time interval which is hardcoded in
13228 * supplicant for 10000ms. Taking power consumption into account 6 timers
13229 * will be used, Timervalue is increased exponentially i.e 10,20,40,
13230 * 80,160,320 secs. And number of scan cycle for each timer
13231 * is configurable through INI param gPNOScanTimerRepeatValue.
13232 * If it is set to 0 only one timer will be used and PNO scan cycle
13233 * will be repeated after each interval specified by supplicant
13234 * till PNO is disabled.
13235 */
13236 if (0 == pHddCtx->cfg_ini->configPNOScanTimerRepeatValue)
13237 pPnoRequest->scanTimers.ucScanTimersCount = HDD_PNO_SCAN_TIMERS_SET_ONE;
13238 else
13239 pPnoRequest->scanTimers.ucScanTimersCount =
13240 HDD_PNO_SCAN_TIMERS_SET_MULTIPLE;
13241
13242 tempInterval = (request->interval)/1000;
13243 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
13244 "Base scan interval = %d PNOScanTimerRepeatValue = %d",
13245 tempInterval, pHddCtx->cfg_ini->configPNOScanTimerRepeatValue);
13246 for ( i = 0; i < pPnoRequest->scanTimers.ucScanTimersCount; i++)
13247 {
13248 pPnoRequest->scanTimers.aTimerValues[i].uTimerRepeat =
13249 pHddCtx->cfg_ini->configPNOScanTimerRepeatValue;
13250 pPnoRequest->scanTimers.aTimerValues[i].uTimerValue = tempInterval;
13251 tempInterval *= 2;
13252 }
13253 //Repeat last timer until pno disabled.
13254 pPnoRequest->scanTimers.aTimerValues[i-1].uTimerRepeat = 0;
13255
Madan Mohan Koyyalamudid206c7b2013-09-26 22:54:51 +053013256 pPnoRequest->modePNO = SIR_PNO_MODE_IMMEDIATE;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053013257
Vinay Krishna Erannaf0e523b2014-03-01 21:00:16 +053013258 INIT_COMPLETION(pAdapter->pno_comp_var);
13259 pPnoRequest->statusCallback = hdd_cfg80211_sched_scan_start_status_cb;
13260 pPnoRequest->callbackContext = pAdapter;
13261 pAdapter->pno_req_status = 0;
13262
Nirav Shah80830bf2013-12-31 16:35:12 +053013263 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
13264 "SessionId %d, enable %d, modePNO %d, ucScanTimersCount %d",
13265 pAdapter->sessionId, pPnoRequest->enable, pPnoRequest->modePNO,
13266 pPnoRequest->scanTimers.ucScanTimersCount);
13267
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053013268 status = sme_SetPreferredNetworkList(WLAN_HDD_GET_HAL_CTX(pAdapter),
13269 pPnoRequest, pAdapter->sessionId,
13270 hdd_cfg80211_sched_scan_done_callback, pAdapter);
13271 if (eHAL_STATUS_SUCCESS != status)
13272 {
13273 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Nirav Shah80830bf2013-12-31 16:35:12 +053013274 "%s: Failed to enable PNO", __func__);
Kamath Vinayakba5313f2013-08-22 15:52:39 +053013275 ret = -EINVAL;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053013276 goto error;
13277 }
13278
Vinay Krishna Erannaf0e523b2014-03-01 21:00:16 +053013279 ret = wait_for_completion_timeout(
13280 &pAdapter->pno_comp_var,
13281 msecs_to_jiffies(WLAN_WAIT_TIME_PNO));
13282 if (0 >= ret)
13283 {
13284 // Did not receive the response for PNO enable in time.
13285 // Assuming the PNO enable was success.
13286 // Returning error from here, because we timeout, results
13287 // in side effect of Wifi (Wifi Setting) not to work.
13288 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
13289 FL("Timed out waiting for PNO to be Enabled"));
13290 ret = 0;
13291 goto error;
13292 }
13293
c_hpothu3c986b22014-07-09 14:45:09 +053013294 vos_mem_free(pPnoRequest);
Vinay Krishna Erannaf0e523b2014-03-01 21:00:16 +053013295 ret = pAdapter->pno_req_status;
c_hpothu37f21312014-04-09 21:49:54 +053013296 return ret;
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053013297
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053013298error:
Vinay Krishna Erannaf0e523b2014-03-01 21:00:16 +053013299 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
13300 FL("PNO scanRequest offloaded ret = %d"), ret);
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053013301 vos_mem_free(pPnoRequest);
c_hpothu37f21312014-04-09 21:49:54 +053013302 pHddCtx->isPnoEnable = FALSE;
Kamath Vinayakba5313f2013-08-22 15:52:39 +053013303 return ret;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053013304}
13305
13306/*
Mahesh A Saptasagar6cc38562014-05-23 21:22:17 +053013307 * FUNCTION: wlan_hdd_cfg80211_sched_scan_start
13308 * NL interface to enable PNO
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053013309 */
Mahesh A Saptasagar6cc38562014-05-23 21:22:17 +053013310static int wlan_hdd_cfg80211_sched_scan_start(struct wiphy *wiphy,
13311 struct net_device *dev, struct cfg80211_sched_scan_request *request)
13312{
13313 int ret;
13314
13315 vos_ssr_protect(__func__);
13316 ret = __wlan_hdd_cfg80211_sched_scan_start(wiphy, dev, request);
13317 vos_ssr_unprotect(__func__);
13318
13319 return ret;
13320}
13321
13322/*
13323 * FUNCTION: __wlan_hdd_cfg80211_sched_scan_stop
13324 * Function to disable PNO
13325 */
13326static int __wlan_hdd_cfg80211_sched_scan_stop(struct wiphy *wiphy,
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053013327 struct net_device *dev)
13328{
13329 eHalStatus status = eHAL_STATUS_FAILURE;
13330 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
13331 hdd_context_t *pHddCtx;
13332 tHalHandle hHal;
13333 tpSirPNOScanReq pPnoRequest = NULL;
Kamath Vinayakba5313f2013-08-22 15:52:39 +053013334 int ret = 0;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053013335
13336 ENTER();
13337
13338 if (NULL == pAdapter)
13339 {
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053013340 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053013341 "%s: HDD adapter is Null", __func__);
13342 return -ENODEV;
13343 }
13344
13345 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053013346
Kamath Vinayakba5313f2013-08-22 15:52:39 +053013347 if (NULL == pHddCtx)
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053013348 {
Gopichand Nakkalac005b7c2013-05-14 16:04:14 +053013349 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Kamath Vinayakba5313f2013-08-22 15:52:39 +053013350 "%s: HDD context is Null", __func__);
13351 return -ENODEV;
13352 }
13353
13354 /* The return 0 is intentional when isLogpInProgress and
13355 * isLoadUnloadInProgress. We did observe a crash due to a return of
13356 * failure in sched_scan_stop , especially for a case where the unload
13357 * of the happens at the same time. The function __cfg80211_stop_sched_scan
13358 * was clearing rdev->sched_scan_req only when the sched_scan_stop returns
13359 * success. If it returns a failure , then its next invocation due to the
13360 * clean up of the second interface will have the dev pointer corresponding
13361 * to the first one leading to a crash.
13362 */
13363 if (pHddCtx->isLogpInProgress)
13364 {
13365 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
13366 "%s: LOGP in Progress. Ignore!!!", __func__);
13367 return ret;
13368 }
13369
Mihir Shete18156292014-03-11 15:38:30 +053013370 if (WLAN_HDD_IS_LOAD_UNLOAD_IN_PROGRESS(pHddCtx))
Kamath Vinayakba5313f2013-08-22 15:52:39 +053013371 {
13372 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
13373 "%s: Unloading/Loading in Progress. Ignore!!!", __func__);
13374 return ret;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053013375 }
13376
13377 hHal = WLAN_HDD_GET_HAL_CTX(pAdapter);
13378 if (NULL == hHal)
13379 {
13380 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
13381 "%s: HAL context is Null!!!", __func__);
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053013382 return -EINVAL;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053013383 }
13384
13385 pPnoRequest = (tpSirPNOScanReq) vos_mem_malloc(sizeof (tSirPNOScanReq));
13386 if (NULL == pPnoRequest)
13387 {
13388 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
13389 "%s: vos_mem_malloc failed", __func__);
Kamath Vinayakba5313f2013-08-22 15:52:39 +053013390 return -ENOMEM;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053013391 }
13392
13393 memset(pPnoRequest, 0, sizeof (tSirPNOScanReq));
13394 pPnoRequest->enable = 0; /* Disable PNO */
13395 pPnoRequest->ucNetworksCount = 0;
13396
13397 status = sme_SetPreferredNetworkList(hHal, pPnoRequest,
13398 pAdapter->sessionId,
13399 NULL, pAdapter);
13400 if (eHAL_STATUS_SUCCESS != status)
13401 {
13402 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
13403 "Failed to disabled PNO");
Kamath Vinayakba5313f2013-08-22 15:52:39 +053013404 ret = -EINVAL;
Vinay Krishna Erannaf0e523b2014-03-01 21:00:16 +053013405 goto error;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053013406 }
c_hpothu37f21312014-04-09 21:49:54 +053013407 pHddCtx->isPnoEnable = FALSE;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053013408
Vinay Krishna Erannaf0e523b2014-03-01 21:00:16 +053013409error:
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053013410 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Vinay Krishna Erannaf0e523b2014-03-01 21:00:16 +053013411 FL("PNO scan disabled ret = %d"), ret);
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053013412 vos_mem_free(pPnoRequest);
13413
13414 EXIT();
Kamath Vinayakba5313f2013-08-22 15:52:39 +053013415 return ret;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053013416}
13417
Mahesh A Saptasagar6cc38562014-05-23 21:22:17 +053013418/*
13419 * FUNCTION: wlan_hdd_cfg80211_sched_scan_stop
13420 * NL interface to disable PNO
13421 */
13422static int wlan_hdd_cfg80211_sched_scan_stop(struct wiphy *wiphy,
13423 struct net_device *dev)
13424{
13425 int ret;
13426
13427 vos_ssr_protect(__func__);
13428 ret = __wlan_hdd_cfg80211_sched_scan_stop(wiphy, dev);
13429 vos_ssr_unprotect(__func__);
13430
13431 return ret;
13432}
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053013433#endif /*FEATURE_WLAN_SCAN_PNO*/
13434
13435
Mohit Khanna698ba2a2012-12-04 15:08:18 -080013436#ifdef FEATURE_WLAN_TDLS
Sunil Dutt Undekarieacac6f2014-03-21 14:08:53 +053013437#if TDLS_MGMT_VERSION2
Mohit Khanna698ba2a2012-12-04 15:08:18 -080013438static int wlan_hdd_cfg80211_tdls_mgmt(struct wiphy *wiphy, struct net_device *dev,
13439 u8 *peer, u8 action_code, u8 dialog_token,
Sunil Dutt Undekarieacac6f2014-03-21 14:08:53 +053013440 u16 status_code, u32 peer_capability, const u8 *buf, size_t len)
13441#else
13442static int wlan_hdd_cfg80211_tdls_mgmt(struct wiphy *wiphy, struct net_device *dev,
13443 u8 *peer, u8 action_code, u8 dialog_token,
13444 u16 status_code, const u8 *buf, size_t len)
13445#endif
Mohit Khanna698ba2a2012-12-04 15:08:18 -080013446{
13447
13448 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
13449 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
Mohit Khanna698ba2a2012-12-04 15:08:18 -080013450 u8 peerMac[6];
13451 VOS_STATUS status;
Gopichand Nakkala05922802013-03-14 12:23:19 -070013452 int max_sta_failed = 0;
Hoonki Leea34dd892013-02-05 22:56:02 -080013453 int responder;
Hoonki Leed37cbb32013-04-20 00:31:14 -070013454 long rc;
Sunil Dutt Undekarieacac6f2014-03-21 14:08:53 +053013455#if !(TDLS_MGMT_VERSION2)
13456 u32 peer_capability = 0;
13457#endif
Rajesh Chauhana34c6e62014-03-25 16:37:58 +053013458 tANI_U16 numCurrTdlsPeers;
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053013459
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053013460 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
13461 TRACE_CODE_HDD_CFG80211_TDLS_MGMT,
13462 pAdapter->sessionId, action_code));
Hoonki Lee11f7dda2013-02-14 16:55:44 -080013463 if (NULL == pHddCtx || NULL == pHddCtx->cfg_ini)
Mohit Khanna698ba2a2012-12-04 15:08:18 -080013464 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013465 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Mohit Khanna698ba2a2012-12-04 15:08:18 -080013466 "Invalid arguments");
13467 return -EINVAL;
13468 }
13469
Sameer Thalappil75ea31a2013-02-21 19:38:16 -080013470 if (pHddCtx->isLogpInProgress)
13471 {
13472 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
13473 "%s:LOGP in Progress. Ignore!!!", __func__);
Atul Mittal115287b2014-07-08 13:26:33 +053013474 wlan_hdd_tdls_set_link_status(pAdapter,
13475 peer,
13476 eTDLS_LINK_IDLE,
13477 eTDLS_LINK_UNSPECIFIED);
Sameer Thalappil75ea31a2013-02-21 19:38:16 -080013478 return -EBUSY;
13479 }
13480
Hoonki Lee27511902013-03-14 18:19:06 -070013481 if (eTDLS_SUPPORT_NOT_ENABLED == pHddCtx->tdls_mode)
Mohit Khanna698ba2a2012-12-04 15:08:18 -080013482 {
Hoonki Lee27511902013-03-14 18:19:06 -070013483 VOS_TRACE( VOS_MODULE_ID_HDD, TDLS_LOG_LEVEL,
13484 "%s: TDLS mode is disabled OR not enabled in FW."
13485 MAC_ADDRESS_STR " action %d declined.",
13486 __func__, MAC_ADDR_ARRAY(peer), action_code);
Mohit Khanna698ba2a2012-12-04 15:08:18 -080013487 return -ENOTSUPP;
13488 }
Lee Hoonkic1262f22013-01-24 21:59:00 -080013489
Hoonki Lee27511902013-03-14 18:19:06 -070013490 /* other than teardown frame, other mgmt frames are not sent if disabled */
13491 if (SIR_MAC_TDLS_TEARDOWN != action_code)
13492 {
13493 /* if tdls_mode is disabled to respond to peer's request */
13494 if (eTDLS_SUPPORT_DISABLED == pHddCtx->tdls_mode)
13495 {
13496 VOS_TRACE( VOS_MODULE_ID_HDD, TDLS_LOG_LEVEL,
13497 "%s: " MAC_ADDRESS_STR
Gopichand Nakkala34d1b062013-03-19 15:28:33 -070013498 " TDLS mode is disabled. action %d declined.",
13499 __func__, MAC_ADDR_ARRAY(peer), action_code);
Hoonki Lee27511902013-03-14 18:19:06 -070013500
13501 return -ENOTSUPP;
13502 }
Agarwal Ashish4b87f922014-06-18 03:03:21 +053013503
13504 if (vos_max_concurrent_connections_reached())
13505 {
13506 hddLog(VOS_TRACE_LEVEL_INFO, FL("Reached max concurrent connections"));
13507 return -EINVAL;
13508 }
Hoonki Lee27511902013-03-14 18:19:06 -070013509 }
13510
Gopichand Nakkalab977a972013-02-18 19:15:09 -080013511 if (WLAN_IS_TDLS_SETUP_ACTION(action_code))
13512 {
Madan Mohan Koyyalamudi96797442013-10-08 16:04:42 +053013513 if (NULL != wlan_hdd_tdls_is_progress(pHddCtx, peer, TRUE))
Gopichand Nakkalab977a972013-02-18 19:15:09 -080013514 {
13515 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Gopichand Nakkalac87400e2013-03-13 18:51:00 -070013516 "%s: " MAC_ADDRESS_STR
Gopichand Nakkala34d1b062013-03-19 15:28:33 -070013517 " TDLS setup is ongoing. action %d declined.",
13518 __func__, MAC_ADDR_ARRAY(peer), action_code);
13519 return -EPERM;
Gopichand Nakkalab977a972013-02-18 19:15:09 -080013520 }
13521 }
13522
Hoonki Lee11f7dda2013-02-14 16:55:44 -080013523 if (SIR_MAC_TDLS_SETUP_REQ == action_code ||
13524 SIR_MAC_TDLS_SETUP_RSP == action_code )
Lee Hoonkic1262f22013-01-24 21:59:00 -080013525 {
Rajesh Chauhana34c6e62014-03-25 16:37:58 +053013526 numCurrTdlsPeers = wlan_hdd_tdlsConnectedPeers(pAdapter);
13527 if (HDD_MAX_NUM_TDLS_STA <= numCurrTdlsPeers)
Lee Hoonkic1262f22013-01-24 21:59:00 -080013528 {
13529 /* supplicant still sends tdls_mgmt(SETUP_REQ) even after
13530 we return error code at 'add_station()'. Hence we have this
13531 check again in addtion to add_station().
13532 Anyway, there is no hard to double-check. */
Hoonki Lee11f7dda2013-02-14 16:55:44 -080013533 if (SIR_MAC_TDLS_SETUP_REQ == action_code)
Lee Hoonkic1262f22013-01-24 21:59:00 -080013534 {
Gopichand Nakkalac87400e2013-03-13 18:51:00 -070013535 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
13536 "%s: " MAC_ADDRESS_STR
Rajesh Chauhana34c6e62014-03-25 16:37:58 +053013537 " TDLS Max peer already connected. action (%d) declined. Num of peers (%d), Max allowed (%d).",
13538 __func__, MAC_ADDR_ARRAY(peer), action_code,
13539 numCurrTdlsPeers, HDD_MAX_NUM_TDLS_STA);
Sunil Dutt388ac8f2013-11-28 18:06:52 +053013540 return -EINVAL;
Lee Hoonkic1262f22013-01-24 21:59:00 -080013541 }
13542 else
13543 {
Gopichand Nakkalab977a972013-02-18 19:15:09 -080013544 /* maximum reached. tweak to send error code to peer and return
13545 error code to supplicant */
Lee Hoonkic1262f22013-01-24 21:59:00 -080013546 status_code = eSIR_MAC_UNSPEC_FAILURE_STATUS;
Gopichand Nakkalac87400e2013-03-13 18:51:00 -070013547 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
13548 "%s: " MAC_ADDRESS_STR
Rajesh Chauhana34c6e62014-03-25 16:37:58 +053013549 " TDLS Max peer already connected, send response status (%d). Num of peers (%d), Max allowed (%d).",
13550 __func__, MAC_ADDR_ARRAY(peer), status_code,
13551 numCurrTdlsPeers, HDD_MAX_NUM_TDLS_STA);
Gopichand Nakkala05922802013-03-14 12:23:19 -070013552 max_sta_failed = -EPERM;
Gopichand Nakkalab977a972013-02-18 19:15:09 -080013553 /* fall through to send setup resp with failure status
13554 code */
Lee Hoonkic1262f22013-01-24 21:59:00 -080013555 }
13556 }
Hoonki Lee11f7dda2013-02-14 16:55:44 -080013557 else
13558 {
13559 hddTdlsPeer_t *pTdlsPeer;
Madan Mohan Koyyalamudi96797442013-10-08 16:04:42 +053013560 pTdlsPeer = wlan_hdd_tdls_find_peer(pAdapter, peer, TRUE);
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -070013561 if (pTdlsPeer && TDLS_IS_CONNECTED(pTdlsPeer))
Hoonki Lee11f7dda2013-02-14 16:55:44 -080013562 {
Gopichand Nakkalac87400e2013-03-13 18:51:00 -070013563 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Gopichand Nakkala34d1b062013-03-19 15:28:33 -070013564 "%s:" MAC_ADDRESS_STR " already connected. action %d declined.",
13565 __func__, MAC_ADDR_ARRAY(peer), action_code);
Hoonki Lee11f7dda2013-02-14 16:55:44 -080013566 return -EPERM;
13567 }
13568 }
Lee Hoonkic1262f22013-01-24 21:59:00 -080013569 }
Hoonki Lee11f7dda2013-02-14 16:55:44 -080013570 vos_mem_copy(peerMac, peer, 6);
Mohit Khanna698ba2a2012-12-04 15:08:18 -080013571
Hoonki Lee1090c6a2013-01-16 17:40:54 -080013572#ifdef WLAN_FEATURE_TDLS_DEBUG
13573 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Arun Kumar Khandavalli9fb625e2014-03-17 16:07:40 +053013574 "%s: " MAC_ADDRESS_STR " action %d, dialog_token %d status %d, len = %zu",
Gopichand Nakkalac87400e2013-03-13 18:51:00 -070013575 "tdls_mgmt", MAC_ADDR_ARRAY(peer),
13576 action_code, dialog_token, status_code, len);
Hoonki Lee1090c6a2013-01-16 17:40:54 -080013577#endif
Mohit Khanna698ba2a2012-12-04 15:08:18 -080013578
Hoonki Leea34dd892013-02-05 22:56:02 -080013579 /*Except teardown responder will not be used so just make 0*/
13580 responder = 0;
Hoonki Lee11f7dda2013-02-14 16:55:44 -080013581 if (SIR_MAC_TDLS_TEARDOWN == action_code)
Hoonki Leea34dd892013-02-05 22:56:02 -080013582 {
Gopichand Nakkala97a65fd2013-04-16 16:59:38 -070013583
13584 hddTdlsPeer_t *pTdlsPeer;
Madan Mohan Koyyalamudi96797442013-10-08 16:04:42 +053013585 pTdlsPeer = wlan_hdd_tdls_find_peer(pAdapter, peerMac, TRUE);
Gopichand Nakkala97a65fd2013-04-16 16:59:38 -070013586
13587 if(pTdlsPeer && TDLS_IS_CONNECTED(pTdlsPeer))
13588 responder = pTdlsPeer->is_responder;
13589 else
Hoonki Leea34dd892013-02-05 22:56:02 -080013590 {
Gopichand Nakkala97a65fd2013-04-16 16:59:38 -070013591 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Arun Kumar Khandavalli9fb625e2014-03-17 16:07:40 +053013592 "%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 -070013593 __func__, MAC_ADDR_ARRAY(peer), (NULL == pTdlsPeer) ? -1 : pTdlsPeer->link_status,
13594 dialog_token, status_code, len);
13595 return -EPERM;
Hoonki Leea34dd892013-02-05 22:56:02 -080013596 }
Mohit Khanna698ba2a2012-12-04 15:08:18 -080013597 }
Mohit Khanna698ba2a2012-12-04 15:08:18 -080013598
Gopichand Nakkala2f1ff152013-07-01 11:27:43 +053013599 /* For explicit trigger of DIS_REQ come out of BMPS for
13600 successfully receiving DIS_RSP from peer. */
Hoonki Lee14621352013-04-16 17:51:19 -070013601 if ((SIR_MAC_TDLS_SETUP_RSP == action_code) ||
Gopichand Nakkala2f1ff152013-07-01 11:27:43 +053013602 (SIR_MAC_TDLS_DIS_RSP == action_code) ||
13603 (SIR_MAC_TDLS_DIS_REQ == action_code))
Hoonki Lee14621352013-04-16 17:51:19 -070013604 {
13605 if (TRUE == sme_IsPmcBmps(WLAN_HDD_GET_HAL_CTX(pAdapter)))
13606 {
13607 VOS_TRACE( VOS_MODULE_ID_HDD, TDLS_LOG_LEVEL,
Gopichand Nakkala2f1ff152013-07-01 11:27:43 +053013608 "%s: Sending frame action_code %u.Disable BMPS", __func__, action_code);
Hoonki Lee14621352013-04-16 17:51:19 -070013609 hdd_disable_bmps_imps(pHddCtx, WLAN_HDD_INFRA_STATION);
13610 }
Gopichand Nakkala2f1ff152013-07-01 11:27:43 +053013611 if (SIR_MAC_TDLS_DIS_REQ != action_code)
13612 wlan_hdd_tdls_set_cap(pAdapter, peerMac, eTDLS_CAP_SUPPORTED);
Hoonki Lee14621352013-04-16 17:51:19 -070013613 }
13614
Hoonki Lee5305c3a2013-04-29 23:28:59 -070013615 /* make sure doesn't call send_mgmt() while it is pending */
13616 if (TDLS_CTX_MAGIC == pAdapter->mgmtTxCompletionStatus)
13617 {
13618 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Arif Hussain6d2a3322013-11-17 19:50:10 -080013619 "%s: " MAC_ADDRESS_STR " action %d couldn't sent, as one is pending. return EBUSY",
Hoonki Lee5305c3a2013-04-29 23:28:59 -070013620 __func__, MAC_ADDR_ARRAY(peer), action_code);
13621 return -EBUSY;
13622 }
13623
13624 pAdapter->mgmtTxCompletionStatus = TDLS_CTX_MAGIC;
Gopichand Nakkalab977a972013-02-18 19:15:09 -080013625 INIT_COMPLETION(pAdapter->tdls_mgmt_comp);
13626
Mohit Khanna698ba2a2012-12-04 15:08:18 -080013627 status = sme_SendTdlsMgmtFrame(WLAN_HDD_GET_HAL_CTX(pAdapter), pAdapter->sessionId,
Pradeep Reddy POTTETIca171f82014-03-21 14:17:35 +053013628 peerMac, action_code, dialog_token, status_code, peer_capability, (tANI_U8 *)buf, len, responder);
Mohit Khanna698ba2a2012-12-04 15:08:18 -080013629
Gopichand Nakkalab977a972013-02-18 19:15:09 -080013630 if (VOS_STATUS_SUCCESS != status)
13631 {
Mohit Khanna698ba2a2012-12-04 15:08:18 -080013632 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
13633 "%s: sme_SendTdlsMgmtFrame failed!", __func__);
Hoonki Lee5305c3a2013-04-29 23:28:59 -070013634 pAdapter->mgmtTxCompletionStatus = FALSE;
Hoonki Lee14621352013-04-16 17:51:19 -070013635 wlan_hdd_tdls_check_bmps(pAdapter);
Sunil Dutt388ac8f2013-11-28 18:06:52 +053013636 return -EINVAL;
Mohit Khanna698ba2a2012-12-04 15:08:18 -080013637 }
13638
Hoonki Leed37cbb32013-04-20 00:31:14 -070013639 rc = wait_for_completion_interruptible_timeout(&pAdapter->tdls_mgmt_comp,
13640 msecs_to_jiffies(WAIT_TIME_TDLS_MGMT));
13641
13642 if ((rc <= 0) || (TRUE != pAdapter->mgmtTxCompletionStatus))
Gopichand Nakkalab977a972013-02-18 19:15:09 -080013643 {
Hoonki Leed37cbb32013-04-20 00:31:14 -070013644 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Jeff Johnson0299d0a2013-10-30 12:37:43 -070013645 "%s: Mgmt Tx Completion failed status %ld TxCompletion %u",
Hoonki Leed37cbb32013-04-20 00:31:14 -070013646 __func__, rc, pAdapter->mgmtTxCompletionStatus);
Hoonki Lee5305c3a2013-04-29 23:28:59 -070013647 pAdapter->mgmtTxCompletionStatus = FALSE;
Yue Ma4f55ef32014-01-23 16:45:33 -080013648
13649 if (pHddCtx->isLogpInProgress)
13650 {
13651 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
13652 "%s: LOGP in Progress. Ignore!!!", __func__);
13653 return -EAGAIN;
13654 }
13655
Hoonki Leed37cbb32013-04-20 00:31:14 -070013656 wlan_hdd_tdls_check_bmps(pAdapter);
Sunil Dutt388ac8f2013-11-28 18:06:52 +053013657 return -EINVAL;
Gopichand Nakkalab977a972013-02-18 19:15:09 -080013658 }
13659
Gopichand Nakkala05922802013-03-14 12:23:19 -070013660 if (max_sta_failed)
Hoonki Lee14621352013-04-16 17:51:19 -070013661 {
13662 wlan_hdd_tdls_check_bmps(pAdapter);
Gopichand Nakkala05922802013-03-14 12:23:19 -070013663 return max_sta_failed;
Hoonki Lee14621352013-04-16 17:51:19 -070013664 }
Gopichand Nakkalab977a972013-02-18 19:15:09 -080013665
Hoonki Leea34dd892013-02-05 22:56:02 -080013666 if (SIR_MAC_TDLS_SETUP_RSP == action_code)
13667 {
Gopichand Nakkala4327a152013-03-04 23:22:42 -080013668 wlan_hdd_tdls_set_responder(pAdapter, peerMac, TRUE);
Hoonki Leea34dd892013-02-05 22:56:02 -080013669 }
13670 else if (SIR_MAC_TDLS_SETUP_CNF == action_code)
13671 {
Gopichand Nakkala4327a152013-03-04 23:22:42 -080013672 wlan_hdd_tdls_set_responder(pAdapter, peerMac, FALSE);
Hoonki Leea34dd892013-02-05 22:56:02 -080013673 }
Mohit Khanna698ba2a2012-12-04 15:08:18 -080013674
13675 return 0;
13676}
13677
Atul Mittal115287b2014-07-08 13:26:33 +053013678
13679int wlan_hdd_tdls_extctrl_config_peer(hdd_adapter_t *pAdapter,
13680 u8 *peer,
13681 cfg80211_exttdls_callback callback)
13682{
13683
13684 hddTdlsPeer_t *pTdlsPeer;
13685 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
13686 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
13687 " %s : NL80211_TDLS_SETUP for " MAC_ADDRESS_STR,
13688 __func__, MAC_ADDR_ARRAY(peer));
13689
13690 if ( (FALSE == pHddCtx->cfg_ini->fTDLSExternalControl) ||
13691 (FALSE == pHddCtx->cfg_ini->fEnableTDLSImplicitTrigger) ) {
13692
13693 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
13694 " %s TDLS External control and Implicit Trigger not enabled ",
13695 __func__);
13696 return -ENOTSUPP;
13697 }
13698
13699 /* To cater the requirement of establishing the TDLS link
13700 * irrespective of the data traffic , get an entry of TDLS peer.
13701 */
13702 pTdlsPeer = wlan_hdd_tdls_get_peer(pAdapter, peer);
13703 if (pTdlsPeer == NULL) {
13704 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
13705 "%s: peer " MAC_ADDRESS_STR " not existing",
13706 __func__, MAC_ADDR_ARRAY(peer));
13707 return -EINVAL;
13708 }
13709
13710 if ( 0 != wlan_hdd_tdls_set_force_peer(pAdapter, peer, TRUE) ) {
13711
13712 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
13713 " %s TDLS Add Force Peer Failed",
13714 __func__);
13715 return -EINVAL;
13716 }
13717 /*EXT TDLS*/
13718
13719 if ( 0 != wlan_hdd_set_callback(pTdlsPeer, callback) ) {
13720 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
13721 " %s TDLS set callback Failed",
13722 __func__);
13723 return -EINVAL;
13724 }
13725
13726 return(0);
13727
13728}
13729
13730int wlan_hdd_tdls_extctrl_deconfig_peer(hdd_adapter_t *pAdapter, u8 *peer)
13731{
13732
13733 hddTdlsPeer_t *pTdlsPeer;
13734 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
13735 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
13736 " %s : NL80211_TDLS_TEARDOWN for " MAC_ADDRESS_STR,
13737 __func__, MAC_ADDR_ARRAY(peer));
13738
13739 if ( (FALSE == pHddCtx->cfg_ini->fTDLSExternalControl) ||
13740 (FALSE == pHddCtx->cfg_ini->fEnableTDLSImplicitTrigger) ) {
13741
13742 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
13743 " %s TDLS External control and Implicit Trigger not enabled ",
13744 __func__);
13745 return -ENOTSUPP;
13746 }
13747
13748
13749 pTdlsPeer = wlan_hdd_tdls_find_peer(pAdapter, peer, TRUE);
13750
13751 if ( NULL == pTdlsPeer ) {
13752 hddLog(VOS_TRACE_LEVEL_INFO, "%s: " MAC_ADDRESS_STR
13753 " peer not exsting",
13754 __func__, MAC_ADDR_ARRAY(peer));
13755 return -EINVAL;
13756 }
13757 else {
13758 wlan_hdd_tdls_indicate_teardown(pAdapter, pTdlsPeer,
13759 eSIR_MAC_TDLS_TEARDOWN_UNSPEC_REASON);
13760 }
13761
13762 if ( 0 != wlan_hdd_tdls_set_force_peer(pAdapter, peer, FALSE) )
13763 return -EINVAL;
13764
13765 /*EXT TDLS*/
13766
13767 if ( 0 != wlan_hdd_set_callback(pTdlsPeer, NULL )) {
13768
13769 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
13770 " %s TDLS set callback Failed",
13771 __func__);
13772 return -EINVAL;
13773 }
13774 return(0);
13775
13776}
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053013777static int __wlan_hdd_cfg80211_tdls_oper(struct wiphy *wiphy, struct net_device *dev,
Mohit Khanna698ba2a2012-12-04 15:08:18 -080013778 u8 *peer, enum nl80211_tdls_operation oper)
13779{
13780 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
13781 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053013782 int status;
Hoonki Lee5305c3a2013-04-29 23:28:59 -070013783 hddTdlsPeer_t *pTdlsPeer;
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053013784
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053013785 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
13786 TRACE_CODE_HDD_CFG80211_TDLS_OPER,
13787 pAdapter->sessionId, oper));
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053013788 if ( NULL == peer )
Mohit Khanna698ba2a2012-12-04 15:08:18 -080013789 {
Gopichand Nakkalab977a972013-02-18 19:15:09 -080013790 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Chilam Ngc4244af2013-04-01 15:37:32 -070013791 "%s: Invalid arguments", __func__);
Mohit Khanna698ba2a2012-12-04 15:08:18 -080013792 return -EINVAL;
13793 }
Hoonki Lee1090c6a2013-01-16 17:40:54 -080013794
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053013795 status = wlan_hdd_validate_context(pHddCtx);
13796
13797 if (0 != status)
Sameer Thalappil75ea31a2013-02-21 19:38:16 -080013798 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053013799 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
13800 "%s: HDD context is not valid", __func__);
13801 return status;
Sameer Thalappil75ea31a2013-02-21 19:38:16 -080013802 }
13803
Mohit Khanna698ba2a2012-12-04 15:08:18 -080013804
13805 if( FALSE == pHddCtx->cfg_ini->fEnableTDLSSupport ||
Hoonki Lee1090c6a2013-01-16 17:40:54 -080013806 FALSE == sme_IsFeatureSupportedByFW(TDLS))
Mohit Khanna698ba2a2012-12-04 15:08:18 -080013807 {
Hoonki Lee1090c6a2013-01-16 17:40:54 -080013808 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Chilam Ngc4244af2013-04-01 15:37:32 -070013809 "TDLS Disabled in INI OR not enabled in FW. "
13810 "Cannot process TDLS commands");
Mohit Khanna698ba2a2012-12-04 15:08:18 -080013811 return -ENOTSUPP;
13812 }
13813
13814 switch (oper) {
13815 case NL80211_TDLS_ENABLE_LINK:
13816 {
Mohit Khanna698ba2a2012-12-04 15:08:18 -080013817 VOS_STATUS status;
c_hpothu6ff1c3c2013-10-01 19:01:57 +053013818 long ret;
Gopichand Nakkala79ff85d2013-05-27 17:05:29 +053013819 tCsrTdlsLinkEstablishParams tdlsLinkEstablishParams;
Mohit Khanna698ba2a2012-12-04 15:08:18 -080013820
Sunil Dutt41de4e22013-11-14 18:09:02 +053013821 pTdlsPeer = wlan_hdd_tdls_find_peer(pAdapter, peer, TRUE);
13822
13823 if ( NULL == pTdlsPeer ) {
13824 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: " MAC_ADDRESS_STR
13825 " (oper %d) not exsting. ignored",
13826 __func__, MAC_ADDR_ARRAY(peer), (int)oper);
13827 return -EINVAL;
13828 }
13829
13830 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
13831 "%s: " MAC_ADDRESS_STR " link_status %d (%s) ", "tdls_oper",
13832 MAC_ADDR_ARRAY(peer), pTdlsPeer->link_status,
13833 "NL80211_TDLS_ENABLE_LINK");
13834
Gopichand Nakkala2f4a2822013-04-17 11:22:01 -070013835 if (!TDLS_STA_INDEX_VALID(pTdlsPeer->staId))
13836 {
13837 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Invalid Staion Index %u "
13838 MAC_ADDRESS_STR " failed",
13839 __func__, pTdlsPeer->staId, MAC_ADDR_ARRAY(peer));
13840 return -EINVAL;
13841 }
13842
Hoonki Lee5305c3a2013-04-29 23:28:59 -070013843 if (eTDLS_LINK_CONNECTED != pTdlsPeer->link_status)
Gopichand Nakkalac87400e2013-03-13 18:51:00 -070013844 {
Madan Mohan Koyyalamudice419872013-09-13 19:36:52 +053013845 if (IS_ADVANCE_TDLS_ENABLE) {
Gopichand Nakkala24be5312013-07-02 16:47:12 +053013846
Madan Mohan Koyyalamudice419872013-09-13 19:36:52 +053013847 if (0 != wlan_hdd_tdls_get_link_establish_params(
13848 pAdapter, peer,&tdlsLinkEstablishParams)) {
13849 return -EINVAL;
13850 }
13851 INIT_COMPLETION(pAdapter->tdls_link_establish_req_comp);
Gopichand Nakkala79ff85d2013-05-27 17:05:29 +053013852
Madan Mohan Koyyalamudice419872013-09-13 19:36:52 +053013853 sme_SendTdlsLinkEstablishParams(WLAN_HDD_GET_HAL_CTX(pAdapter),
13854 pAdapter->sessionId, peer, &tdlsLinkEstablishParams);
13855 /* Send TDLS peer UAPSD capabilities to the firmware and
13856 * register with the TL on after the response for this operation
13857 * is received .
13858 */
13859 ret = wait_for_completion_interruptible_timeout(
13860 &pAdapter->tdls_link_establish_req_comp,
13861 msecs_to_jiffies(WAIT_TIME_TDLS_LINK_ESTABLISH_REQ));
13862 if (ret <= 0)
13863 {
13864 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
13865 "%s: Link Establish Request Faled Status %ld",
13866 __func__, ret);
13867 return -EINVAL;
13868 }
Gopichand Nakkala79ff85d2013-05-27 17:05:29 +053013869 }
Atul Mittal115287b2014-07-08 13:26:33 +053013870 wlan_hdd_tdls_set_peer_link_status(pTdlsPeer,
13871 eTDLS_LINK_CONNECTED,
13872 eTDLS_LINK_SUCCESS);
Gopichand Nakkala471708b2013-06-04 20:03:01 +053013873 /* Mark TDLS client Authenticated .*/
13874 status = WLANTL_ChangeSTAState( pHddCtx->pvosContext,
13875 pTdlsPeer->staId,
13876 WLANTL_STA_AUTHENTICATED);
Gopichand Nakkalaccd3a382013-03-19 13:56:10 -070013877 if (VOS_STATUS_SUCCESS == status)
13878 {
Hoonki Lee14621352013-04-16 17:51:19 -070013879 if (pTdlsPeer->is_responder == 0)
13880 {
13881 v_U8_t staId = (v_U8_t)pTdlsPeer->staId;
13882
13883 wlan_hdd_tdls_timer_restart(pAdapter,
13884 &pTdlsPeer->initiatorWaitTimeoutTimer,
13885 WAIT_TIME_TDLS_INITIATOR);
13886 /* suspend initiator TX until it receives direct packet from the
13887 reponder or WAIT_TIME_TDLS_INITIATOR timer expires */
13888 WLANTL_SuspendDataTx( (WLAN_HDD_GET_CTX(pAdapter))->pvosContext,
13889 &staId, NULL);
13890 }
Gopichand Nakkalaccd3a382013-03-19 13:56:10 -070013891 wlan_hdd_tdls_increment_peer_count(pAdapter);
13892 }
Gopichand Nakkalac87400e2013-03-13 18:51:00 -070013893 wlan_hdd_tdls_check_bmps(pAdapter);
Gopichand Nakkala79ff85d2013-05-27 17:05:29 +053013894
13895 /* Update TL about the UAPSD masks , to route the packets to firmware */
Gopichand Nakkala574f6d12013-06-27 19:38:43 +053013896 if ((TRUE == pHddCtx->cfg_ini->fEnableTDLSBufferSta)
13897 || pHddCtx->cfg_ini->fTDLSUapsdMask )
Gopichand Nakkala79ff85d2013-05-27 17:05:29 +053013898 {
Gopichand Nakkala574f6d12013-06-27 19:38:43 +053013899 int ac;
13900 uint8 ucAc[4] = { WLANTL_AC_VO,
13901 WLANTL_AC_VI,
13902 WLANTL_AC_BK,
13903 WLANTL_AC_BE };
13904 uint8 tlTid[4] = { 7, 5, 2, 3 } ;
13905 for(ac=0; ac < 4; ac++)
13906 {
13907 status = WLANTL_EnableUAPSDForAC( (WLAN_HDD_GET_CTX(pAdapter))->pvosContext,
13908 pTdlsPeer->staId, ucAc[ac],
13909 tlTid[ac], tlTid[ac], 0, 0,
13910 WLANTL_BI_DIR );
13911 }
Gopichand Nakkala79ff85d2013-05-27 17:05:29 +053013912 }
Gopichand Nakkalac87400e2013-03-13 18:51:00 -070013913 }
13914
Mohit Khanna698ba2a2012-12-04 15:08:18 -080013915 }
13916 break;
13917 case NL80211_TDLS_DISABLE_LINK:
Lee Hoonkic1262f22013-01-24 21:59:00 -080013918 {
Sunil Dutt41de4e22013-11-14 18:09:02 +053013919 pTdlsPeer = wlan_hdd_tdls_find_peer(pAdapter, peer, TRUE);
13920
13921 if ( NULL == pTdlsPeer ) {
13922 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: " MAC_ADDRESS_STR
13923 " (oper %d) not exsting. ignored",
13924 __func__, MAC_ADDR_ARRAY(peer), (int)oper);
13925 return -EINVAL;
13926 }
13927
13928 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
13929 "%s: " MAC_ADDRESS_STR " link_status %d (%s) ", "tdls_oper",
13930 MAC_ADDR_ARRAY(peer), pTdlsPeer->link_status,
13931 "NL80211_TDLS_DISABLE_LINK");
13932
Hoonki Lee5305c3a2013-04-29 23:28:59 -070013933 if(TDLS_STA_INDEX_VALID(pTdlsPeer->staId))
Lee Hoonkic1262f22013-01-24 21:59:00 -080013934 {
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -070013935 long status;
13936
Atul Mittal271a7652014-09-12 13:18:22 +053013937
13938 wlan_hdd_tdls_set_peer_link_status(pTdlsPeer,
13939 eTDLS_LINK_TEARING,
13940 (pTdlsPeer->link_status == eTDLS_LINK_TEARING)?
13941 eTDLS_LINK_UNSPECIFIED:
13942 eTDLS_LINK_DROPPED_BY_REMOTE);
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -070013943 INIT_COMPLETION(pAdapter->tdls_del_station_comp);
13944
Lee Hoonkic1262f22013-01-24 21:59:00 -080013945 sme_DeleteTdlsPeerSta( WLAN_HDD_GET_HAL_CTX(pAdapter),
13946 pAdapter->sessionId, peer );
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -070013947
13948 status = wait_for_completion_interruptible_timeout(&pAdapter->tdls_del_station_comp,
13949 msecs_to_jiffies(WAIT_TIME_TDLS_DEL_STA));
Atul Mittal271a7652014-09-12 13:18:22 +053013950 wlan_hdd_tdls_set_peer_link_status(pTdlsPeer,
Atul Mittal454664b2014-10-10 11:03:46 +053013951 eTDLS_LINK_IDLE,
13952 eTDLS_LINK_UNSPECIFIED);
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -070013953 if (status <= 0)
13954 {
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -070013955 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
13956 "%s: Del station failed status %ld",
13957 __func__, status);
13958 return -EPERM;
13959 }
Lee Hoonkic1262f22013-01-24 21:59:00 -080013960 }
13961 else
13962 {
Gopichand Nakkalac87400e2013-03-13 18:51:00 -070013963 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
13964 "%s: TDLS Peer Station doesn't exist.", __func__);
Lee Hoonkic1262f22013-01-24 21:59:00 -080013965 }
Lee Hoonkic1262f22013-01-24 21:59:00 -080013966 }
Gopichand Nakkalac87400e2013-03-13 18:51:00 -070013967 break;
Mohit Khanna698ba2a2012-12-04 15:08:18 -080013968 case NL80211_TDLS_TEARDOWN:
Sunil Dutt41de4e22013-11-14 18:09:02 +053013969 {
Atul Mittal115287b2014-07-08 13:26:33 +053013970 status = wlan_hdd_tdls_extctrl_deconfig_peer(pAdapter, peer);
Sunil Dutt41de4e22013-11-14 18:09:02 +053013971
Atul Mittal115287b2014-07-08 13:26:33 +053013972 if (0 != status)
13973 {
13974 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
13975 "%s: Error in TDLS Teardown", __func__);
13976 return status;
Sunil Dutt41de4e22013-11-14 18:09:02 +053013977 }
Sunil Dutt41de4e22013-11-14 18:09:02 +053013978 break;
13979 }
Mohit Khanna698ba2a2012-12-04 15:08:18 -080013980 case NL80211_TDLS_SETUP:
Sunil Dutt41de4e22013-11-14 18:09:02 +053013981 {
Atul Mittal115287b2014-07-08 13:26:33 +053013982 status = wlan_hdd_tdls_extctrl_config_peer(pAdapter,
13983 peer,
13984 NULL);
Sunil Dutt41de4e22013-11-14 18:09:02 +053013985
Atul Mittal115287b2014-07-08 13:26:33 +053013986 if (0 != status)
13987 {
13988 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
13989 "%s: Error in TDLS Setup", __func__);
13990 return status;
Naresh Jayaram937abdf2013-11-26 19:50:25 +053013991 }
Naresh Jayaramdb4514b2013-11-25 18:08:10 +053013992 break;
Sunil Dutt41de4e22013-11-14 18:09:02 +053013993 }
Mohit Khanna698ba2a2012-12-04 15:08:18 -080013994 case NL80211_TDLS_DISCOVERY_REQ:
13995 /* We don't support in-driver setup/teardown/discovery */
c_hpothu6ff1c3c2013-10-01 19:01:57 +053013996 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_WARN,
13997 "%s: We don't support in-driver setup/teardown/discovery "
13998 ,__func__);
Mohit Khanna698ba2a2012-12-04 15:08:18 -080013999 return -ENOTSUPP;
14000 default:
c_hpothu6ff1c3c2013-10-01 19:01:57 +053014001 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
14002 "%s: unsupported event",__func__);
Mohit Khanna698ba2a2012-12-04 15:08:18 -080014003 return -ENOTSUPP;
14004 }
14005 return 0;
14006}
Chilam NG571c65a2013-01-19 12:27:36 +053014007
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053014008static int wlan_hdd_cfg80211_tdls_oper(struct wiphy *wiphy, struct net_device *dev,
14009 u8 *peer, enum nl80211_tdls_operation oper)
14010{
14011 int ret;
14012
14013 vos_ssr_protect(__func__);
14014 ret = __wlan_hdd_cfg80211_tdls_oper(wiphy, dev, peer, oper);
14015 vos_ssr_unprotect(__func__);
14016
14017 return ret;
14018}
14019
Chilam NG571c65a2013-01-19 12:27:36 +053014020int wlan_hdd_cfg80211_send_tdls_discover_req(struct wiphy *wiphy,
14021 struct net_device *dev, u8 *peer)
14022{
Arif Hussaina7c8e412013-11-20 11:06:42 -080014023 hddLog(VOS_TRACE_LEVEL_INFO,
14024 "tdls send discover req: "MAC_ADDRESS_STR,
14025 MAC_ADDR_ARRAY(peer));
Chilam NG571c65a2013-01-19 12:27:36 +053014026
Sunil Dutt Undekarieacac6f2014-03-21 14:08:53 +053014027#if TDLS_MGMT_VERSION2
14028 return wlan_hdd_cfg80211_tdls_mgmt(wiphy, dev, peer,
14029 WLAN_TDLS_DISCOVERY_REQUEST, 1, 0, 0, NULL, 0);
14030#else
Chilam NG571c65a2013-01-19 12:27:36 +053014031 return wlan_hdd_cfg80211_tdls_mgmt(wiphy, dev, peer,
14032 WLAN_TDLS_DISCOVERY_REQUEST, 1, 0, NULL, 0);
Sunil Dutt Undekarieacac6f2014-03-21 14:08:53 +053014033#endif
Chilam NG571c65a2013-01-19 12:27:36 +053014034}
Mohit Khanna698ba2a2012-12-04 15:08:18 -080014035#endif
14036
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053014037#ifdef WLAN_FEATURE_GTK_OFFLOAD
14038/*
14039 * FUNCTION: wlan_hdd_cfg80211_update_replayCounterCallback
14040 * Callback rountine called upon receiving response for
14041 * get offload info
14042 */
14043void wlan_hdd_cfg80211_update_replayCounterCallback(void *callbackContext,
14044 tpSirGtkOffloadGetInfoRspParams pGtkOffloadGetInfoRsp)
14045{
14046
14047 hdd_adapter_t *pAdapter = (hdd_adapter_t *)callbackContext;
Gopichand Nakkalad36ee622013-05-07 14:13:27 +053014048 tANI_U8 tempReplayCounter[8];
14049 hdd_station_ctx_t *pHddStaCtx;
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053014050
14051 ENTER();
14052
14053 if (NULL == pAdapter)
14054 {
Agarwal Ashish971c2882013-10-30 20:11:12 +053014055 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053014056 "%s: HDD adapter is Null", __func__);
14057 return ;
14058 }
14059
14060 if (NULL == pGtkOffloadGetInfoRsp)
14061 {
14062 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
14063 "%s: pGtkOffloadGetInfoRsp is Null", __func__);
14064 return ;
14065 }
14066
14067 if (VOS_STATUS_SUCCESS != pGtkOffloadGetInfoRsp->ulStatus)
14068 {
14069 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
14070 "%s: wlan Failed to get replay counter value",
14071 __func__);
14072 return ;
14073 }
14074
Gopichand Nakkalad36ee622013-05-07 14:13:27 +053014075 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
14076 /* Update replay counter */
14077 pHddStaCtx->gtkOffloadReqParams.ullKeyReplayCounter =
14078 pGtkOffloadGetInfoRsp->ullKeyReplayCounter;
14079
14080 {
14081 /* changing from little to big endian since supplicant
14082 * works on big endian format
14083 */
14084 int i;
14085 tANI_U8 *p = (tANI_U8 *)&pGtkOffloadGetInfoRsp->ullKeyReplayCounter;
14086
14087 for (i = 0; i < 8; i++)
14088 {
14089 tempReplayCounter[7-i] = (tANI_U8)p[i];
14090 }
14091 }
14092
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053014093 /* Update replay counter to NL */
14094 cfg80211_gtk_rekey_notify(pAdapter->dev, pGtkOffloadGetInfoRsp->bssId,
Gopichand Nakkalad36ee622013-05-07 14:13:27 +053014095 tempReplayCounter, GFP_KERNEL);
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053014096}
14097
14098/*
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053014099 * FUNCTION: __wlan_hdd_cfg80211_set_rekey_data
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053014100 * This function is used to offload GTK rekeying job to the firmware.
14101 */
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053014102int __wlan_hdd_cfg80211_set_rekey_data(struct wiphy *wiphy, struct net_device *dev,
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053014103 struct cfg80211_gtk_rekey_data *data)
14104{
14105 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
14106 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
14107 hdd_station_ctx_t *pHddStaCtx;
14108 tHalHandle hHal;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053014109 int result;
Gopichand Nakkalad36ee622013-05-07 14:13:27 +053014110 tSirGtkOffloadParams hddGtkOffloadReqParams;
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053014111 eHalStatus status = eHAL_STATUS_FAILURE;
14112
14113 ENTER();
14114
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053014115
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053014116 if (NULL == pAdapter)
14117 {
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053014118 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053014119 "%s: HDD adapter is Null", __func__);
14120 return -ENODEV;
14121 }
14122
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053014123 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
14124 TRACE_CODE_HDD_CFG80211_SET_REKEY_DATA,
14125 pAdapter->sessionId, pAdapter->device_mode));
14126
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053014127 result = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053014128
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053014129 if (0 != result)
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053014130 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053014131 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
14132 "%s: HDD context is not valid", __func__);
14133 return result;
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053014134 }
14135
14136 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
14137 hHal = WLAN_HDD_GET_HAL_CTX(pAdapter);
14138 if (NULL == hHal)
14139 {
14140 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
14141 "%s: HAL context is Null!!!", __func__);
14142 return -EAGAIN;
14143 }
14144
Gopichand Nakkalad36ee622013-05-07 14:13:27 +053014145 pHddStaCtx->gtkOffloadReqParams.ulFlags = GTK_OFFLOAD_ENABLE;
14146 memcpy(pHddStaCtx->gtkOffloadReqParams.aKCK, data->kck, NL80211_KCK_LEN);
14147 memcpy(pHddStaCtx->gtkOffloadReqParams.aKEK, data->kek, NL80211_KEK_LEN);
14148 memcpy(pHddStaCtx->gtkOffloadReqParams.bssId, &pHddStaCtx->conn_info.bssId,
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053014149 WNI_CFG_BSSID_LEN);
Gopichand Nakkalad36ee622013-05-07 14:13:27 +053014150 {
14151 /* changing from big to little endian since driver
14152 * works on little endian format
14153 */
14154 tANI_U8 *p =
14155 (tANI_U8 *)&pHddStaCtx->gtkOffloadReqParams.ullKeyReplayCounter;
14156 int i;
14157
14158 for (i = 0; i < 8; i++)
14159 {
14160 p[7-i] = data->replay_ctr[i];
14161 }
14162 }
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053014163
14164 if (TRUE == pHddCtx->hdd_wlan_suspended)
14165 {
14166 /* if wlan is suspended, enable GTK offload directly from here */
Gopichand Nakkalad36ee622013-05-07 14:13:27 +053014167 memcpy(&hddGtkOffloadReqParams, &pHddStaCtx->gtkOffloadReqParams,
14168 sizeof (tSirGtkOffloadParams));
14169 status = sme_SetGTKOffload(hHal, &hddGtkOffloadReqParams,
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053014170 pAdapter->sessionId);
14171
14172 if (eHAL_STATUS_SUCCESS != status)
14173 {
14174 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
14175 "%s: sme_SetGTKOffload failed, returned %d",
14176 __func__, status);
Vinay Krishna Eranna6f22c1f2014-10-13 16:03:06 +053014177
14178 /* Need to clear any trace of key value in the memory.
14179 * Thus zero out the memory even though it is local
14180 * variable.
14181 */
14182 vos_mem_zero(&hddGtkOffloadReqParams,
14183 sizeof(hddGtkOffloadReqParams));
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053014184 return status;
14185 }
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053014186 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
14187 "%s: sme_SetGTKOffload successfull", __func__);
14188 }
14189 else
14190 {
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053014191 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
14192 "%s: wlan not suspended GTKOffload request is stored",
14193 __func__);
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053014194 }
Gopichand Nakkalad36ee622013-05-07 14:13:27 +053014195
Vinay Krishna Eranna6f22c1f2014-10-13 16:03:06 +053014196 /* Need to clear any trace of key value in the memory.
14197 * Thus zero out the memory even though it is local
14198 * variable.
14199 */
14200 vos_mem_zero(&hddGtkOffloadReqParams,
14201 sizeof(hddGtkOffloadReqParams));
14202
Gopichand Nakkalad36ee622013-05-07 14:13:27 +053014203 return eHAL_STATUS_SUCCESS;
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053014204}
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053014205
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053014206int wlan_hdd_cfg80211_set_rekey_data(struct wiphy *wiphy, struct net_device *dev,
14207 struct cfg80211_gtk_rekey_data *data)
14208{
14209 int ret;
14210
14211 vos_ssr_protect(__func__);
14212 ret = __wlan_hdd_cfg80211_set_rekey_data(wiphy, dev, data);
14213 vos_ssr_unprotect(__func__);
14214
14215 return ret;
14216}
14217#endif /*WLAN_FEATURE_GTK_OFFLOAD*/
Gopichand Nakkalac005b7c2013-05-14 16:04:14 +053014218/*
14219 * FUNCTION: wlan_hdd_cfg80211_set_mac_acl
14220 * This function is used to set access control policy
14221 */
14222static int wlan_hdd_cfg80211_set_mac_acl(struct wiphy *wiphy,
14223 struct net_device *dev, const struct cfg80211_acl_data *params)
14224{
14225 int i;
14226 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
14227 hdd_hostapd_state_t *pHostapdState;
14228 tsap_Config_t *pConfig;
14229 v_CONTEXT_t pVosContext = NULL;
14230 hdd_context_t *pHddCtx;
14231 int status;
14232
14233 ENTER();
14234
14235 if (NULL == pAdapter)
14236 {
14237 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
14238 "%s: HDD adapter is Null", __func__);
14239 return -ENODEV;
14240 }
14241
14242 if (NULL == params)
14243 {
14244 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
14245 "%s: params is Null", __func__);
14246 return -EINVAL;
14247 }
14248
14249 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
14250 status = wlan_hdd_validate_context(pHddCtx);
14251
14252 if (0 != status)
14253 {
14254 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
14255 "%s: HDD context is not valid", __func__);
14256 return status;
14257 }
14258
14259 pVosContext = pHddCtx->pvosContext;
14260 pHostapdState = WLAN_HDD_GET_HOSTAP_STATE_PTR(pAdapter);
14261
14262 if (NULL == pHostapdState)
14263 {
14264 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
14265 "%s: pHostapdState is Null", __func__);
14266 return -EINVAL;
14267 }
14268
14269 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,"acl policy: = %d"
14270 "no acl entries = %d", params->acl_policy, params->n_acl_entries);
14271
14272 if (WLAN_HDD_SOFTAP == pAdapter->device_mode)
14273 {
14274 pConfig = &pAdapter->sessionCtx.ap.sapConfig;
14275
14276 /* default value */
14277 pConfig->num_accept_mac = 0;
14278 pConfig->num_deny_mac = 0;
14279
14280 /**
14281 * access control policy
14282 * @NL80211_ACL_POLICY_ACCEPT_UNLESS_LISTED: Deny stations which are
14283 * listed in hostapd.deny file.
14284 * @NL80211_ACL_POLICY_DENY_UNLESS_LISTED: Allow stations which are
14285 * listed in hostapd.accept file.
14286 */
14287 if (NL80211_ACL_POLICY_DENY_UNLESS_LISTED == params->acl_policy)
14288 {
14289 pConfig->SapMacaddr_acl = eSAP_DENY_UNLESS_ACCEPTED;
14290 }
14291 else if (NL80211_ACL_POLICY_ACCEPT_UNLESS_LISTED == params->acl_policy)
14292 {
14293 pConfig->SapMacaddr_acl = eSAP_ACCEPT_UNLESS_DENIED;
14294 }
14295 else
14296 {
14297 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
14298 "%s:Acl Policy : %d is not supported",
14299 __func__, params->acl_policy);
14300 return -ENOTSUPP;
14301 }
14302
14303 if (eSAP_DENY_UNLESS_ACCEPTED == pConfig->SapMacaddr_acl)
14304 {
14305 pConfig->num_accept_mac = params->n_acl_entries;
14306 for (i = 0; i < params->n_acl_entries; i++)
14307 {
14308 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
14309 "** Add ACL MAC entry %i in WhiletList :"
14310 MAC_ADDRESS_STR, i,
14311 MAC_ADDR_ARRAY(params->mac_addrs[i].addr));
14312
14313 vos_mem_copy(&pConfig->accept_mac[i], params->mac_addrs[i].addr,
14314 sizeof(qcmacaddr));
14315 }
14316 }
14317 else if (eSAP_ACCEPT_UNLESS_DENIED == pConfig->SapMacaddr_acl)
14318 {
14319 pConfig->num_deny_mac = params->n_acl_entries;
14320 for (i = 0; i < params->n_acl_entries; i++)
14321 {
14322 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
14323 "** Add ACL MAC entry %i in BlackList :"
14324 MAC_ADDRESS_STR, i,
14325 MAC_ADDR_ARRAY(params->mac_addrs[i].addr));
14326
14327 vos_mem_copy(&pConfig->deny_mac[i], params->mac_addrs[i].addr,
14328 sizeof(qcmacaddr));
14329 }
14330 }
14331
14332 if (VOS_STATUS_SUCCESS != WLANSAP_SetMacACL(pVosContext, pConfig))
14333 {
14334 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
14335 "%s: SAP Set Mac Acl fail", __func__);
14336 return -EINVAL;
14337 }
14338 }
14339 else
14340 {
14341 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Sushant Kaushik8bc7df22014-04-09 17:55:29 +053014342 "%s: Invalid device_mode = %s (%d)",
14343 __func__, hdd_device_modetoString(pAdapter->device_mode),
14344 pAdapter->device_mode);
Gopichand Nakkalac005b7c2013-05-14 16:04:14 +053014345 return -EINVAL;
14346 }
14347
14348 return 0;
14349}
14350
Leo Chang9056f462013-08-01 19:21:11 -070014351#ifdef WLAN_NL80211_TESTMODE
14352#ifdef FEATURE_WLAN_LPHB
Leo Changd9df8aa2013-09-26 13:32:26 -070014353void wlan_hdd_cfg80211_lphb_ind_handler
Leo Chang9056f462013-08-01 19:21:11 -070014354(
14355 void *pAdapter,
14356 void *indCont
14357)
14358{
Leo Changd9df8aa2013-09-26 13:32:26 -070014359 tSirLPHBInd *lphbInd;
14360 struct sk_buff *skb;
c_hpothu73f35e62014-04-18 13:40:08 +053014361 hdd_context_t *pHddCtxt;
Leo Chang9056f462013-08-01 19:21:11 -070014362
14363 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Leo Changd9df8aa2013-09-26 13:32:26 -070014364 "LPHB indication arrived");
Leo Chang9056f462013-08-01 19:21:11 -070014365
c_hpothu73f35e62014-04-18 13:40:08 +053014366 if (pAdapter == NULL)
14367 {
14368 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
14369 "%s: pAdapter is NULL\n",__func__);
14370 return;
14371 }
14372
Leo Chang9056f462013-08-01 19:21:11 -070014373 if (NULL == indCont)
14374 {
14375 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Leo Changd9df8aa2013-09-26 13:32:26 -070014376 "LPHB IND, invalid argument");
Leo Chang9056f462013-08-01 19:21:11 -070014377 return;
14378 }
14379
c_hpothu73f35e62014-04-18 13:40:08 +053014380 pHddCtxt = (hdd_context_t *)pAdapter;
Leo Changd9df8aa2013-09-26 13:32:26 -070014381 lphbInd = (tSirLPHBInd *)indCont;
Leo Chang9056f462013-08-01 19:21:11 -070014382 skb = cfg80211_testmode_alloc_event_skb(
c_hpothu73f35e62014-04-18 13:40:08 +053014383 pHddCtxt->wiphy,
Leo Changd9df8aa2013-09-26 13:32:26 -070014384 sizeof(tSirLPHBInd),
Leo Chang9056f462013-08-01 19:21:11 -070014385 GFP_ATOMIC);
14386 if (!skb)
14387 {
14388 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
14389 "LPHB timeout, NL buffer alloc fail");
14390 return;
14391 }
14392
Leo Changac3ba772013-10-07 09:47:04 -070014393 if(nla_put_u32(skb, WLAN_HDD_TM_ATTR_CMD, WLAN_HDD_TM_CMD_WLAN_HB))
Leo Changd9df8aa2013-09-26 13:32:26 -070014394 {
14395 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
14396 "WLAN_HDD_TM_ATTR_CMD put fail");
14397 goto nla_put_failure;
14398 }
Leo Changac3ba772013-10-07 09:47:04 -070014399 if(nla_put_u32(skb, WLAN_HDD_TM_ATTR_TYPE, lphbInd->protocolType))
Leo Changd9df8aa2013-09-26 13:32:26 -070014400 {
14401 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
14402 "WLAN_HDD_TM_ATTR_TYPE put fail");
14403 goto nla_put_failure;
14404 }
Leo Changac3ba772013-10-07 09:47:04 -070014405 if(nla_put(skb, WLAN_HDD_TM_ATTR_DATA,
Leo Changd9df8aa2013-09-26 13:32:26 -070014406 sizeof(tSirLPHBInd), lphbInd))
14407 {
14408 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
14409 "WLAN_HDD_TM_ATTR_DATA put fail");
14410 goto nla_put_failure;
14411 }
Leo Chang9056f462013-08-01 19:21:11 -070014412 cfg80211_testmode_event(skb, GFP_ATOMIC);
14413 return;
14414
14415nla_put_failure:
14416 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
14417 "NLA Put fail");
14418 kfree_skb(skb);
14419
14420 return;
14421}
14422#endif /* FEATURE_WLAN_LPHB */
14423
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053014424static int __wlan_hdd_cfg80211_testmode(struct wiphy *wiphy, void *data, int len)
Leo Chang9056f462013-08-01 19:21:11 -070014425{
14426 struct nlattr *tb[WLAN_HDD_TM_ATTR_MAX + 1];
14427 int err = 0;
14428#ifdef FEATURE_WLAN_LPHB
14429 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
Leo Changd9df8aa2013-09-26 13:32:26 -070014430 eHalStatus smeStatus;
Leo Chang9056f462013-08-01 19:21:11 -070014431#endif /* FEATURE_WLAN_LPHB */
14432
14433 err = nla_parse(tb, WLAN_HDD_TM_ATTR_MAX, data, len, wlan_hdd_tm_policy);
14434 if (err)
14435 {
14436 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
14437 "%s Testmode INV ATTR", __func__);
14438 return err;
14439 }
14440
14441 if (!tb[WLAN_HDD_TM_ATTR_CMD])
14442 {
14443 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
14444 "%s Testmode INV CMD", __func__);
14445 return -EINVAL;
14446 }
14447
14448 switch (nla_get_u32(tb[WLAN_HDD_TM_ATTR_CMD]))
14449 {
14450#ifdef FEATURE_WLAN_LPHB
14451 /* Low Power Heartbeat configuration request */
14452 case WLAN_HDD_TM_CMD_WLAN_HB:
14453 {
14454 int buf_len;
14455 void *buf;
14456 tSirLPHBReq *hb_params = NULL;
Amar Singhal05852702014-02-04 14:40:00 -080014457 tSirLPHBReq *hb_params_temp = NULL;
Leo Chang9056f462013-08-01 19:21:11 -070014458
14459 if (!tb[WLAN_HDD_TM_ATTR_DATA])
14460 {
14461 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
14462 "%s Testmode INV DATA", __func__);
14463 return -EINVAL;
14464 }
14465
14466 buf = nla_data(tb[WLAN_HDD_TM_ATTR_DATA]);
14467 buf_len = nla_len(tb[WLAN_HDD_TM_ATTR_DATA]);
Amar Singhal05852702014-02-04 14:40:00 -080014468
14469 hb_params_temp =(tSirLPHBReq *)buf;
14470 if ((hb_params_temp->cmd == LPHB_SET_TCP_PARAMS_INDID) &&
14471 (hb_params_temp->params.lphbTcpParamReq.timePeriodSec == 0))
14472 return -EINVAL;
14473
Leo Chang9056f462013-08-01 19:21:11 -070014474 hb_params = (tSirLPHBReq *)vos_mem_malloc(sizeof(tSirLPHBReq));
14475 if (NULL == hb_params)
14476 {
14477 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
14478 "%s Request Buffer Alloc Fail", __func__);
14479 return -EINVAL;
14480 }
14481
14482 vos_mem_copy(hb_params, buf, buf_len);
Leo Changd9df8aa2013-09-26 13:32:26 -070014483 smeStatus = sme_LPHBConfigReq((tHalHandle)(pHddCtx->hHal),
14484 hb_params,
14485 wlan_hdd_cfg80211_lphb_ind_handler);
14486 if (eHAL_STATUS_SUCCESS != smeStatus)
Leo Chang9056f462013-08-01 19:21:11 -070014487 {
Leo Changd9df8aa2013-09-26 13:32:26 -070014488 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
14489 "LPHB Config Fail, disable");
Leo Chang9056f462013-08-01 19:21:11 -070014490 vos_mem_free(hb_params);
14491 }
Leo Chang9056f462013-08-01 19:21:11 -070014492 return 0;
14493 }
14494#endif /* FEATURE_WLAN_LPHB */
14495 default:
c_hpothu6ff1c3c2013-10-01 19:01:57 +053014496 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
14497 "%s: unsupported event",__func__);
Leo Chang9056f462013-08-01 19:21:11 -070014498 return -EOPNOTSUPP;
14499 }
14500
14501 return err;
14502}
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053014503
14504static int wlan_hdd_cfg80211_testmode(struct wiphy *wiphy, void *data, int len)
14505{
14506 int ret;
14507
14508 vos_ssr_protect(__func__);
14509 ret = __wlan_hdd_cfg80211_testmode(wiphy, data, len);
14510 vos_ssr_unprotect(__func__);
14511
14512 return ret;
14513}
Leo Chang9056f462013-08-01 19:21:11 -070014514#endif /* CONFIG_NL80211_TESTMODE */
14515
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053014516static int __wlan_hdd_cfg80211_dump_survey(struct wiphy *wiphy,
Madan Mohan Koyyalamudid9383fd2013-08-13 09:27:30 +053014517 struct net_device *dev,
14518 int idx, struct survey_info *survey)
14519{
14520 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
14521 hdd_context_t *pHddCtx;
Mihir Sheted9072e02013-08-21 17:02:29 +053014522 hdd_station_ctx_t *pHddStaCtx;
Madan Mohan Koyyalamudid9383fd2013-08-13 09:27:30 +053014523 tHalHandle halHandle;
Mihir Sheted9072e02013-08-21 17:02:29 +053014524 v_U32_t channel = 0, freq = 0; /* Initialization Required */
Madan Mohan Koyyalamudid9383fd2013-08-13 09:27:30 +053014525 v_S7_t snr,rssi;
14526 int status, i, j, filled = 0;
14527
14528 ENTER();
14529
Madan Mohan Koyyalamudid9383fd2013-08-13 09:27:30 +053014530 if (NULL == pAdapter)
14531 {
14532 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
14533 "%s: HDD adapter is Null", __func__);
14534 return -ENODEV;
14535 }
14536
14537 if (NULL == wiphy)
14538 {
14539 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
14540 "%s: wiphy is Null", __func__);
14541 return -ENODEV;
14542 }
14543
14544 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
14545 status = wlan_hdd_validate_context(pHddCtx);
14546
14547 if (0 != status)
14548 {
14549 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
14550 "%s: HDD context is not valid", __func__);
14551 return status;
14552 }
14553
Mihir Sheted9072e02013-08-21 17:02:29 +053014554 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
14555
Madan Mohan Koyyalamudid9383fd2013-08-13 09:27:30 +053014556 if (0 == pHddCtx->cfg_ini->fEnableSNRMonitoring ||
Mihir Sheted9072e02013-08-21 17:02:29 +053014557 0 != pAdapter->survey_idx ||
14558 eConnectionState_Associated != pHddStaCtx->conn_info.connState)
Madan Mohan Koyyalamudid9383fd2013-08-13 09:27:30 +053014559 {
14560 /* The survey dump ops when implemented completely is expected to
14561 * return a survey of all channels and the ops is called by the
14562 * kernel with incremental values of the argument 'idx' till it
14563 * returns -ENONET. But we can only support the survey for the
14564 * operating channel for now. survey_idx is used to track
14565 * that the ops is called only once and then return -ENONET for
14566 * the next iteration
14567 */
14568 pAdapter->survey_idx = 0;
14569 return -ENONET;
14570 }
14571
14572 halHandle = WLAN_HDD_GET_HAL_CTX(pAdapter);
14573
14574 wlan_hdd_get_snr(pAdapter, &snr);
14575 wlan_hdd_get_rssi(pAdapter, &rssi);
14576
14577 sme_GetOperationChannel(halHandle, &channel, pAdapter->sessionId);
14578 hdd_wlan_get_freq(channel, &freq);
14579
14580
14581 for (i = 0; i < IEEE80211_NUM_BANDS; i++)
14582 {
14583 if (NULL == wiphy->bands[i])
14584 {
14585 VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_INFO,
14586 "%s: wiphy->bands[i] is NULL, i = %d", __func__, i);
14587 continue;
14588 }
14589
14590 for (j = 0; j < wiphy->bands[i]->n_channels; j++)
14591 {
14592 struct ieee80211_supported_band *band = wiphy->bands[i];
14593
14594 if (band->channels[j].center_freq == (v_U16_t)freq)
14595 {
14596 survey->channel = &band->channels[j];
14597 /* The Rx BDs contain SNR values in dB for the received frames
14598 * while the supplicant expects noise. So we calculate and
14599 * return the value of noise (dBm)
14600 * SNR (dB) = RSSI (dBm) - NOISE (dBm)
14601 */
14602 survey->noise = rssi - snr;
14603 survey->filled = SURVEY_INFO_NOISE_DBM;
14604 filled = 1;
14605 }
14606 }
14607 }
14608
14609 if (filled)
14610 pAdapter->survey_idx = 1;
14611 else
14612 {
14613 pAdapter->survey_idx = 0;
14614 return -ENONET;
14615 }
14616
14617 return 0;
14618}
14619
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053014620static int wlan_hdd_cfg80211_dump_survey(struct wiphy *wiphy,
14621 struct net_device *dev,
14622 int idx, struct survey_info *survey)
14623{
14624 int ret;
14625
14626 vos_ssr_protect(__func__);
14627 ret = __wlan_hdd_cfg80211_dump_survey(wiphy, dev, idx, survey);
14628 vos_ssr_unprotect(__func__);
14629
14630 return ret;
14631}
14632
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053014633/*
Mahesh A Saptasagarbcc5b662014-06-02 21:46:23 +053014634 * FUNCTION: __wlan_hdd_cfg80211_resume_wlan
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053014635 * this is called when cfg80211 driver resume
14636 * driver updates latest sched_scan scan result(if any) to cfg80211 database
14637 */
Mahesh A Saptasagarbcc5b662014-06-02 21:46:23 +053014638int __wlan_hdd_cfg80211_resume_wlan(struct wiphy *wiphy)
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053014639{
14640 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
14641 hdd_adapter_t *pAdapter;
14642 hdd_adapter_list_node_t *pAdapterNode, *pNext;
14643 VOS_STATUS status = VOS_STATUS_SUCCESS;
14644
14645 ENTER();
14646
14647 if ( NULL == pHddCtx )
14648 {
14649 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
14650 "%s: HddCtx validation failed", __func__);
14651 return 0;
14652 }
14653
14654 if (pHddCtx->isLogpInProgress)
14655 {
14656 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
14657 "%s: LOGP in Progress. Ignore!!!", __func__);
14658 return 0;
14659 }
14660
Mihir Shete18156292014-03-11 15:38:30 +053014661 if (WLAN_HDD_IS_LOAD_UNLOAD_IN_PROGRESS(pHddCtx))
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053014662 {
14663 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
14664 "%s: Unloading/Loading in Progress. Ignore!!!", __func__);
14665 return 0;
14666 }
14667
14668 spin_lock(&pHddCtx->schedScan_lock);
14669 pHddCtx->isWiphySuspended = FALSE;
14670 if (TRUE != pHddCtx->isSchedScanUpdatePending)
14671 {
14672 spin_unlock(&pHddCtx->schedScan_lock);
14673 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
14674 "%s: Return resume is not due to PNO indication", __func__);
14675 return 0;
14676 }
14677 // Reset flag to avoid updatating cfg80211 data old results again
14678 pHddCtx->isSchedScanUpdatePending = FALSE;
14679 spin_unlock(&pHddCtx->schedScan_lock);
14680
Mahesh A Saptasagarb9c50402014-01-16 15:49:22 +053014681
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053014682 status = hdd_get_front_adapter ( pHddCtx, &pAdapterNode );
14683
14684 while ( NULL != pAdapterNode && VOS_STATUS_SUCCESS == status )
14685 {
14686 pAdapter = pAdapterNode->pAdapter;
14687 if ( (NULL != pAdapter) &&
14688 (WLAN_HDD_INFRA_STATION == pAdapter->device_mode) )
14689 {
14690 if (0 != wlan_hdd_cfg80211_update_bss(pHddCtx->wiphy, pAdapter))
Mahesh A Saptasagarb9c50402014-01-16 15:49:22 +053014691 {
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053014692 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_WARN,
14693 "%s: NO SCAN result", __func__);
Mahesh A Saptasagarb9c50402014-01-16 15:49:22 +053014694 }
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053014695 else
Mahesh A Saptasagarb9c50402014-01-16 15:49:22 +053014696 {
14697 /* Acquire wakelock to handle the case where APP's tries to
14698 * suspend immediately after updating the scan results. Whis
14699 * results in app's is in suspended state and not able to
14700 * process the connect request to AP
14701 */
14702 hdd_prevent_suspend_timeout(2000);
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053014703 cfg80211_sched_scan_results(pHddCtx->wiphy);
Mahesh A Saptasagarb9c50402014-01-16 15:49:22 +053014704 }
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053014705
14706 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
14707 "%s : cfg80211 scan result database updated", __func__);
14708
14709 return 0;
14710
14711 }
14712 status = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
14713 pAdapterNode = pNext;
14714 }
14715
14716 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
14717 "%s: Failed to find Adapter", __func__);
14718 return 0;
14719}
14720
Mahesh A Saptasagarbcc5b662014-06-02 21:46:23 +053014721int wlan_hdd_cfg80211_resume_wlan(struct wiphy *wiphy)
14722{
14723 int ret;
14724
14725 vos_ssr_protect(__func__);
14726 ret = __wlan_hdd_cfg80211_resume_wlan(wiphy);
14727 vos_ssr_unprotect(__func__);
14728
14729 return ret;
14730}
14731
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053014732/*
Mahesh A Saptasagarbcc5b662014-06-02 21:46:23 +053014733 * FUNCTION: __wlan_hdd_cfg80211_suspend_wlan
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053014734 * this is called when cfg80211 driver suspends
14735 */
Mahesh A Saptasagarbcc5b662014-06-02 21:46:23 +053014736int __wlan_hdd_cfg80211_suspend_wlan(struct wiphy *wiphy,
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053014737 struct cfg80211_wowlan *wow)
14738{
14739 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
14740
14741 ENTER();
14742 if (NULL == pHddCtx)
14743 {
14744 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
14745 "%s: HddCtx validation failed", __func__);
14746 return 0;
14747 }
14748
14749 pHddCtx->isWiphySuspended = TRUE;
14750
14751 EXIT();
14752
14753 return 0;
14754}
14755
Mahesh A Saptasagarbcc5b662014-06-02 21:46:23 +053014756int wlan_hdd_cfg80211_suspend_wlan(struct wiphy *wiphy,
14757 struct cfg80211_wowlan *wow)
14758{
14759 int ret;
14760
14761 vos_ssr_protect(__func__);
14762 ret = __wlan_hdd_cfg80211_suspend_wlan(wiphy, wow);
14763 vos_ssr_unprotect(__func__);
14764
14765 return ret;
14766}
Jeff Johnson295189b2012-06-20 16:38:30 -070014767/* cfg80211_ops */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014768static struct cfg80211_ops wlan_hdd_cfg80211_ops =
Jeff Johnson295189b2012-06-20 16:38:30 -070014769{
14770 .add_virtual_intf = wlan_hdd_add_virtual_intf,
14771 .del_virtual_intf = wlan_hdd_del_virtual_intf,
14772 .change_virtual_intf = wlan_hdd_cfg80211_change_iface,
14773 .change_station = wlan_hdd_change_station,
14774#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,4,0))
14775 .add_beacon = wlan_hdd_cfg80211_add_beacon,
14776 .del_beacon = wlan_hdd_cfg80211_del_beacon,
14777 .set_beacon = wlan_hdd_cfg80211_set_beacon,
Jeff Johnson04dd8a82012-06-29 20:41:40 -070014778#else
14779 .start_ap = wlan_hdd_cfg80211_start_ap,
14780 .change_beacon = wlan_hdd_cfg80211_change_beacon,
14781 .stop_ap = wlan_hdd_cfg80211_stop_ap,
Jeff Johnson295189b2012-06-20 16:38:30 -070014782#endif
14783 .change_bss = wlan_hdd_cfg80211_change_bss,
14784 .add_key = wlan_hdd_cfg80211_add_key,
14785 .get_key = wlan_hdd_cfg80211_get_key,
14786 .del_key = wlan_hdd_cfg80211_del_key,
14787 .set_default_key = wlan_hdd_cfg80211_set_default_key,
Jeff Johnson3bbe4bf2013-01-18 17:05:29 -080014788#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,6,0))
Jeff Johnson295189b2012-06-20 16:38:30 -070014789 .set_channel = wlan_hdd_cfg80211_set_channel,
Jeff Johnson3bbe4bf2013-01-18 17:05:29 -080014790#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070014791 .scan = wlan_hdd_cfg80211_scan,
14792 .connect = wlan_hdd_cfg80211_connect,
14793 .disconnect = wlan_hdd_cfg80211_disconnect,
14794 .join_ibss = wlan_hdd_cfg80211_join_ibss,
14795 .leave_ibss = wlan_hdd_cfg80211_leave_ibss,
14796 .set_wiphy_params = wlan_hdd_cfg80211_set_wiphy_params,
14797 .set_tx_power = wlan_hdd_cfg80211_set_txpower,
14798 .get_tx_power = wlan_hdd_cfg80211_get_txpower,
Jeff Johnson295189b2012-06-20 16:38:30 -070014799 .remain_on_channel = wlan_hdd_cfg80211_remain_on_channel,
14800 .cancel_remain_on_channel = wlan_hdd_cfg80211_cancel_remain_on_channel,
DARAM SUDHA39eede62014-02-12 11:16:40 +053014801 .mgmt_tx = wlan_hdd_mgmt_tx,
Jeff Johnson295189b2012-06-20 16:38:30 -070014802#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
14803 .mgmt_tx_cancel_wait = wlan_hdd_cfg80211_mgmt_tx_cancel_wait,
14804 .set_default_mgmt_key = wlan_hdd_set_default_mgmt_key,
14805 .set_txq_params = wlan_hdd_set_txq_params,
14806#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070014807 .get_station = wlan_hdd_cfg80211_get_station,
14808 .set_power_mgmt = wlan_hdd_cfg80211_set_power_mgmt,
14809 .del_station = wlan_hdd_cfg80211_del_station,
Jeff Johnson04dd8a82012-06-29 20:41:40 -070014810 .add_station = wlan_hdd_cfg80211_add_station,
14811#ifdef FEATURE_WLAN_LFR
14812 .set_pmksa = wlan_hdd_cfg80211_set_pmksa,
14813 .del_pmksa = wlan_hdd_cfg80211_del_pmksa,
14814 .flush_pmksa = wlan_hdd_cfg80211_flush_pmksa,
14815#endif
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070014816#if defined(WLAN_FEATURE_VOWIFI_11R) && defined(KERNEL_SUPPORT_11R_CFG80211)
14817 .update_ft_ies = wlan_hdd_cfg80211_update_ft_ies,
14818#endif
Mohit Khanna698ba2a2012-12-04 15:08:18 -080014819#ifdef FEATURE_WLAN_TDLS
14820 .tdls_mgmt = wlan_hdd_cfg80211_tdls_mgmt,
14821 .tdls_oper = wlan_hdd_cfg80211_tdls_oper,
14822#endif
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053014823#ifdef WLAN_FEATURE_GTK_OFFLOAD
14824 .set_rekey_data = wlan_hdd_cfg80211_set_rekey_data,
14825#endif /* WLAN_FEATURE_GTK_OFFLOAD */
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053014826#ifdef FEATURE_WLAN_SCAN_PNO
14827 .sched_scan_start = wlan_hdd_cfg80211_sched_scan_start,
14828 .sched_scan_stop = wlan_hdd_cfg80211_sched_scan_stop,
14829#endif /*FEATURE_WLAN_SCAN_PNO */
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053014830 .resume = wlan_hdd_cfg80211_resume_wlan,
14831 .suspend = wlan_hdd_cfg80211_suspend_wlan,
Gopichand Nakkalac005b7c2013-05-14 16:04:14 +053014832 .set_mac_acl = wlan_hdd_cfg80211_set_mac_acl,
Leo Chang9056f462013-08-01 19:21:11 -070014833#ifdef WLAN_NL80211_TESTMODE
14834 .testmode_cmd = wlan_hdd_cfg80211_testmode,
14835#endif
Madan Mohan Koyyalamudid9383fd2013-08-13 09:27:30 +053014836 .dump_survey = wlan_hdd_cfg80211_dump_survey,
Jeff Johnson295189b2012-06-20 16:38:30 -070014837};
14838