blob: 76403faa0748f34b1fe38264624966771312153f [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;
4014 }
4015 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
4036 vos_trace_hex_dump( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,nla_data(
4037 tb[QCA_WLAN_VENDOR_ATTR_SET_SCANNING_MAC_OUI]),
4038 VOS_MAC_ADDR_FIRST_3_BYTES);
4039
4040 if (VOS_STATUS_SUCCESS != vos_randomize_n_bytes(
4041 (void *)(&pHddCtx->spoofMacAddr.randomMacAddr.bytes[3]),
4042 VOS_MAC_ADDR_LAST_3_BYTES)) {
4043 hddLog(LOGE, FL("Failed to generate random Mac Addr"));
4044 }
4045 vos_trace_hex_dump( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
4046 pHddCtx->spoofMacAddr.randomMacAddr.bytes,
4047 VOS_MAC_ADDR_SIZE);
4048
4049 if (eHAL_STATUS_SUCCESS != sme_SpoofMacAddrReq(pHddCtx->hHal,
4050 &pHddCtx->spoofMacAddr.randomMacAddr)) {
4051 hddLog(LOGE, FL("Failed to send Spoof Mac Addr to FW"));
4052 }
4053
4054 return 0;
4055}
4056
Atul Mittal115287b2014-07-08 13:26:33 +05304057static int wlan_hdd_cfg80211_exttdls_get_status(struct wiphy *wiphy,
4058 struct wireless_dev *wdev,
4059 void *data,
4060 int data_len)
4061{
4062 u8 peer[6] = {0};
4063 struct net_device *dev = wdev->netdev;
4064 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
4065 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
4066 struct nlattr *tb[QCA_WLAN_VENDOR_ATTR_TDLS_GET_STATUS_MAX + 1];
4067 eHalStatus ret;
4068 tANI_S32 state;
4069 tANI_S32 reason;
Atul Mittal0a9f68d2014-10-16 15:26:38 +05304070 tANI_S32 global_operating_class = 0;
4071 tANI_S32 channel = 0;
Atul Mittal115287b2014-07-08 13:26:33 +05304072 struct sk_buff *skb = NULL;
4073
4074 ret = wlan_hdd_validate_context(pHddCtx);
4075 if (0 != ret) {
4076
4077 return -EINVAL;
4078 }
4079 if (pHddCtx->cfg_ini->fTDLSExternalControl == FALSE) {
4080
4081 return -ENOTSUPP;
4082 }
4083 if (nla_parse(tb, QCA_WLAN_VENDOR_ATTR_TDLS_GET_STATUS_MAX,
4084 data, data_len,
4085 wlan_hdd_tdls_config_get_status_policy)) {
4086 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Invalid ATTR"));
4087 return -EINVAL;
4088 }
4089
4090 /* Parse and fetch mac address */
4091 if (!tb[QCA_WLAN_VENDOR_ATTR_TDLS_GET_STATUS_MAC_ADDR]) {
4092 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr mac addr failed"));
4093 return -EINVAL;
4094 }
4095
4096 memcpy(peer, nla_data(
4097 tb[QCA_WLAN_VENDOR_ATTR_TDLS_GET_STATUS_MAC_ADDR]),
4098 sizeof(peer));
4099 hddLog(VOS_TRACE_LEVEL_INFO, FL(MAC_ADDRESS_STR),MAC_ADDR_ARRAY(peer));
4100
4101 ret = wlan_hdd_tdls_get_status(pAdapter, peer, &state, &reason);
4102
4103 if (0 != ret) {
4104 hddLog(VOS_TRACE_LEVEL_ERROR,
4105 FL("get status Failed"));
4106 return -EINVAL;
4107 }
4108 skb = cfg80211_vendor_cmd_alloc_reply_skb(wiphy,
Atul Mittal0a9f68d2014-10-16 15:26:38 +05304109 4 * sizeof(s32) +
Atul Mittal115287b2014-07-08 13:26:33 +05304110 NLMSG_HDRLEN);
4111
4112 if (!skb) {
4113 hddLog(VOS_TRACE_LEVEL_ERROR,
4114 FL("cfg80211_vendor_cmd_alloc_reply_skb failed"));
4115 return -EINVAL;
4116 }
Atul Mittal0a9f68d2014-10-16 15:26:38 +05304117 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 +05304118 reason,
4119 state,
Atul Mittal0a9f68d2014-10-16 15:26:38 +05304120 global_operating_class,
4121 channel,
Atul Mittal115287b2014-07-08 13:26:33 +05304122 MAC_ADDR_ARRAY(peer));
Atul Mittal0a9f68d2014-10-16 15:26:38 +05304123 if (nla_put_s32(skb,
4124 QCA_WLAN_VENDOR_ATTR_TDLS_GET_STATUS_STATE,
4125 state) ||
4126 nla_put_s32(skb,
4127 QCA_WLAN_VENDOR_ATTR_TDLS_GET_STATUS_REASON,
4128 reason) ||
4129 nla_put_s32(skb,
4130 QCA_WLAN_VENDOR_ATTR_TDLS_GET_STATUS_GLOBAL_OPERATING_CLASS,
4131 global_operating_class) ||
4132 nla_put_s32(skb,
4133 QCA_WLAN_VENDOR_ATTR_TDLS_GET_STATUS_CHANNEL,
4134 channel)) {
Atul Mittal115287b2014-07-08 13:26:33 +05304135
4136 hddLog(VOS_TRACE_LEVEL_ERROR, FL("nla put fail"));
4137 goto nla_put_failure;
4138 }
4139
4140 return cfg80211_vendor_cmd_reply(skb);
4141
4142nla_put_failure:
4143 kfree_skb(skb);
4144 return -EINVAL;
4145}
4146
4147static int wlan_hdd_cfg80211_exttdls_callback(tANI_U8* mac,
4148 tANI_S32 state,
4149 tANI_S32 reason,
4150 void *ctx)
4151{
4152 hdd_adapter_t* pAdapter = (hdd_adapter_t*)ctx;
4153 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
4154 struct sk_buff *skb = NULL;
Atul Mittal0a9f68d2014-10-16 15:26:38 +05304155 tANI_S32 global_operating_class = 0;
4156 tANI_S32 channel = 0;
Atul Mittal115287b2014-07-08 13:26:33 +05304157
4158 if (wlan_hdd_validate_context(pHddCtx)) {
4159 hddLog(VOS_TRACE_LEVEL_ERROR, FL("HDD context is not valid "));
4160 return -EINVAL;
4161 }
4162
4163 if (pHddCtx->cfg_ini->fTDLSExternalControl == FALSE) {
4164
4165 return -ENOTSUPP;
4166 }
4167 skb = cfg80211_vendor_event_alloc(
4168 pHddCtx->wiphy,
4169 EXTTDLS_EVENT_BUF_SIZE + NLMSG_HDRLEN,
4170 QCA_NL80211_VENDOR_SUBCMD_TDLS_STATE_CHANGE_INDEX,
4171 GFP_KERNEL);
4172
4173 if (!skb) {
4174 hddLog(VOS_TRACE_LEVEL_ERROR,
4175 FL("cfg80211_vendor_event_alloc failed"));
4176 return -EINVAL;
4177 }
4178 hddLog(VOS_TRACE_LEVEL_INFO, FL("Entering "));
Atul Mittal0a9f68d2014-10-16 15:26:38 +05304179 hddLog(VOS_TRACE_LEVEL_INFO, "Reason: (%d) Status: (%d) Class: (%d) Channel: (%d)",
4180 reason,
4181 state,
4182 global_operating_class,
4183 channel);
Atul Mittal115287b2014-07-08 13:26:33 +05304184 hddLog(VOS_TRACE_LEVEL_WARN, "tdls peer " MAC_ADDRESS_STR,
4185 MAC_ADDR_ARRAY(mac));
4186
Atul Mittal0a9f68d2014-10-16 15:26:38 +05304187 if (nla_put(skb,
4188 QCA_WLAN_VENDOR_ATTR_TDLS_STATE_MAC_ADDR,
4189 VOS_MAC_ADDR_SIZE, mac) ||
4190 nla_put_s32(skb,
4191 QCA_WLAN_VENDOR_ATTR_TDLS_NEW_STATE,
4192 state) ||
4193 nla_put_s32(skb,
4194 QCA_WLAN_VENDOR_ATTR_TDLS_STATE_REASON,
4195 reason) ||
4196 nla_put_s32(skb,
4197 QCA_WLAN_VENDOR_ATTR_TDLS_STATE_CHANNEL,
4198 channel) ||
4199 nla_put_s32(skb,
4200 QCA_WLAN_VENDOR_ATTR_TDLS_STATE_GLOBAL_OPERATING_CLASS,
4201 global_operating_class)
4202 ) {
Atul Mittal115287b2014-07-08 13:26:33 +05304203 hddLog(VOS_TRACE_LEVEL_ERROR, FL("nla put fail"));
4204 goto nla_put_failure;
4205 }
4206
4207 cfg80211_vendor_event(skb, GFP_KERNEL);
4208 return (0);
4209
4210nla_put_failure:
4211 kfree_skb(skb);
4212 return -EINVAL;
4213}
4214
4215static int wlan_hdd_cfg80211_exttdls_enable(struct wiphy *wiphy,
4216 struct wireless_dev *wdev,
4217 void *data,
4218 int data_len)
4219{
4220 u8 peer[6] = {0};
4221 struct net_device *dev = wdev->netdev;
4222 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
4223 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
4224 struct nlattr *tb[QCA_WLAN_VENDOR_ATTR_TDLS_ENABLE_MAX + 1];
4225 eHalStatus status;
4226 tdls_req_params_t pReqMsg = {0};
4227
4228 status = wlan_hdd_validate_context(pHddCtx);
4229 if (0 != status) {
4230 hddLog(VOS_TRACE_LEVEL_ERROR,
4231 FL("HDD context is not valid"));
4232 return -EINVAL;
4233 }
4234 if (pHddCtx->cfg_ini->fTDLSExternalControl == FALSE) {
4235
4236 return -ENOTSUPP;
4237 }
4238 if (nla_parse(tb, QCA_WLAN_VENDOR_ATTR_TDLS_ENABLE_MAX,
4239 data, data_len,
4240 wlan_hdd_tdls_config_enable_policy)) {
4241 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Invalid ATTR"));
4242 return -EINVAL;
4243 }
4244
4245 /* Parse and fetch mac address */
4246 if (!tb[QCA_WLAN_VENDOR_ATTR_TDLS_ENABLE_MAC_ADDR]) {
4247 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr mac addr failed"));
4248 return -EINVAL;
4249 }
4250
4251 memcpy(peer, nla_data(
4252 tb[QCA_WLAN_VENDOR_ATTR_TDLS_ENABLE_MAC_ADDR]),
4253 sizeof(peer));
4254 hddLog(VOS_TRACE_LEVEL_INFO, FL(MAC_ADDRESS_STR),MAC_ADDR_ARRAY(peer));
4255
4256 /* Parse and fetch channel */
4257 if (!tb[QCA_WLAN_VENDOR_ATTR_TDLS_ENABLE_CHANNEL]) {
4258 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr channel failed"));
4259 return -EINVAL;
4260 }
4261 pReqMsg.channel = nla_get_s32(
4262 tb[QCA_WLAN_VENDOR_ATTR_TDLS_ENABLE_CHANNEL]);
4263 hddLog(VOS_TRACE_LEVEL_INFO, FL("Channel Num (%d)"), pReqMsg.channel);
4264
4265 /* Parse and fetch global operating class */
4266 if (!tb[QCA_WLAN_VENDOR_ATTR_TDLS_ENABLE_GLOBAL_OPERATING_CLASS]) {
4267 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr operating class failed"));
4268 return -EINVAL;
4269 }
4270 pReqMsg.global_operating_class = nla_get_s32(
4271 tb[QCA_WLAN_VENDOR_ATTR_TDLS_ENABLE_GLOBAL_OPERATING_CLASS]);
4272 hddLog(VOS_TRACE_LEVEL_INFO, FL("Operating class (%d)"),
4273 pReqMsg.global_operating_class);
4274
4275 /* Parse and fetch latency ms */
4276 if (!tb[QCA_WLAN_VENDOR_ATTR_TDLS_ENABLE_MAX_LATENCY_MS]) {
4277 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr latency failed"));
4278 return -EINVAL;
4279 }
4280 pReqMsg.max_latency_ms = nla_get_s32(
4281 tb[QCA_WLAN_VENDOR_ATTR_TDLS_ENABLE_MAX_LATENCY_MS]);
4282 hddLog(VOS_TRACE_LEVEL_INFO, FL("Latency (%d)"),
4283 pReqMsg.max_latency_ms);
4284
4285 /* Parse and fetch required bandwidth kbps */
4286 if (!tb[QCA_WLAN_VENDOR_ATTR_TDLS_ENABLE_MIN_BANDWIDTH_KBPS]) {
4287 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr bandwidth failed"));
4288 return -EINVAL;
4289 }
4290
4291 pReqMsg.min_bandwidth_kbps = nla_get_s32(
4292 tb[QCA_WLAN_VENDOR_ATTR_TDLS_ENABLE_MIN_BANDWIDTH_KBPS]);
4293 hddLog(VOS_TRACE_LEVEL_INFO, FL("Bandwidth (%d)"),
4294 pReqMsg.min_bandwidth_kbps);
4295
4296 return (wlan_hdd_tdls_extctrl_config_peer(pAdapter,
4297 peer,
4298 wlan_hdd_cfg80211_exttdls_callback));
4299}
4300
4301static int wlan_hdd_cfg80211_exttdls_disable(struct wiphy *wiphy,
4302 struct wireless_dev *wdev,
4303 void *data,
4304 int data_len)
4305{
4306 u8 peer[6] = {0};
4307 struct net_device *dev = wdev->netdev;
4308 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
4309 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
4310 struct nlattr *tb[QCA_WLAN_VENDOR_ATTR_TDLS_DISABLE_MAX + 1];
4311 eHalStatus status;
4312
4313 status = wlan_hdd_validate_context(pHddCtx);
4314 if (0 != status) {
4315 hddLog(VOS_TRACE_LEVEL_ERROR,
4316 FL("HDD context is not valid"));
4317 return -EINVAL;
4318 }
4319 if (pHddCtx->cfg_ini->fTDLSExternalControl == FALSE) {
4320
4321 return -ENOTSUPP;
4322 }
4323 if (nla_parse(tb, QCA_WLAN_VENDOR_ATTR_TDLS_DISABLE_MAX,
4324 data, data_len,
4325 wlan_hdd_tdls_config_disable_policy)) {
4326 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Invalid ATTR"));
4327 return -EINVAL;
4328 }
4329 /* Parse and fetch mac address */
4330 if (!tb[QCA_WLAN_VENDOR_ATTR_TDLS_DISABLE_MAC_ADDR]) {
4331 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr mac addr failed"));
4332 return -EINVAL;
4333 }
4334
4335 memcpy(peer, nla_data(
4336 tb[QCA_WLAN_VENDOR_ATTR_TDLS_DISABLE_MAC_ADDR]),
4337 sizeof(peer));
4338 hddLog(VOS_TRACE_LEVEL_INFO, FL(MAC_ADDRESS_STR),MAC_ADDR_ARRAY(peer));
4339
4340 return (wlan_hdd_tdls_extctrl_deconfig_peer(pAdapter, peer));
4341}
4342
Dasari Srinivas7875a302014-09-26 17:50:57 +05304343static int
4344wlan_hdd_cfg80211_get_supported_features(struct wiphy *wiphy,
4345 struct wireless_dev *wdev,
4346 void *data, int data_len)
4347{
4348 struct net_device *dev = wdev->netdev;
4349 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
4350 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
4351 struct sk_buff *skb = NULL;
4352 tANI_U32 fset = 0;
4353
4354 if (wiphy->interface_modes & BIT(NL80211_IFTYPE_STATION)) {
4355 hddLog(LOG1, FL("Infra Station mode is supported by driver"));
4356 fset |= WIFI_FEATURE_INFRA;
4357 }
4358
4359 if (TRUE == hdd_is_5g_supported(pHddCtx)) {
4360 hddLog(LOG1, FL("INFRA_5G is supported by firmware"));
4361 fset |= WIFI_FEATURE_INFRA_5G;
4362 }
4363
4364#ifdef WLAN_FEATURE_P2P
4365 if ((wiphy->interface_modes & BIT(NL80211_IFTYPE_P2P_CLIENT)) &&
4366 (wiphy->interface_modes & BIT(NL80211_IFTYPE_P2P_GO))) {
4367 hddLog(LOG1, FL("WiFi-Direct is supported by driver"));
4368 fset |= WIFI_FEATURE_P2P;
4369 }
4370#endif
4371
4372 /* Soft-AP is supported currently by default */
4373 fset |= WIFI_FEATURE_SOFT_AP;
4374
4375#ifdef WLAN_FEATURE_EXTSCAN
4376 if ((TRUE == pHddCtx->cfg_ini->fEnableEXTScan) &&
4377 sme_IsFeatureSupportedByFW(EXTENDED_SCAN)) {
4378 hddLog(LOG1, FL("EXTScan is supported by firmware"));
4379 fset |= WIFI_FEATURE_EXTSCAN;
4380 }
4381#endif
4382
4383#ifdef WLAN_FEATURE_NAN
4384 if (sme_IsFeatureSupportedByFW(NAN)) {
4385 hddLog(LOG1, FL("NAN is supported by firmware"));
4386 fset |= WIFI_FEATURE_NAN;
4387 }
4388#endif
4389
4390 /* D2D RTT is not supported currently by default */
4391 if (sme_IsFeatureSupportedByFW(RTT)) {
4392 hddLog(LOG1, FL("RTT is supported by firmware"));
4393 fset |= WIFI_FEATURE_D2AP_RTT;
4394 }
4395
4396#ifdef FEATURE_WLAN_BATCH_SCAN
4397 if (fset & WIFI_FEATURE_EXTSCAN) {
4398 hddLog(LOG1, FL("Batch scan is supported as extscan is supported"));
4399 fset &= ~WIFI_FEATURE_BATCH_SCAN;
4400 } else if (sme_IsFeatureSupportedByFW(BATCH_SCAN)) {
4401 hddLog(LOG1, FL("Batch scan is supported by firmware"));
4402 fset |= WIFI_FEATURE_BATCH_SCAN;
4403 }
4404#endif
4405
4406#ifdef FEATURE_WLAN_SCAN_PNO
4407 if (pHddCtx->cfg_ini->configPNOScanSupport &&
4408 (eHAL_STATUS_SUCCESS == wlan_hdd_is_pno_allowed(pAdapter))) {
4409 hddLog(LOG1, FL("PNO is supported by firmware"));
4410 fset |= WIFI_FEATURE_PNO;
4411 }
4412#endif
4413
4414 /* STA+STA is supported currently by default */
4415 fset |= WIFI_FEATURE_ADDITIONAL_STA;
4416
4417#ifdef FEATURE_WLAN_TDLS
4418 if ((TRUE == pHddCtx->cfg_ini->fEnableTDLSSupport) &&
4419 sme_IsFeatureSupportedByFW(TDLS)) {
4420 hddLog(LOG1, FL("TDLS is supported by firmware"));
4421 fset |= WIFI_FEATURE_TDLS;
4422 }
4423
4424 /* TDLS_OFFCHANNEL is not supported currently by default */
4425#endif
4426
4427#ifdef WLAN_AP_STA_CONCURRENCY
4428 /* AP+STA concurrency is supported currently by default */
4429 fset |= WIFI_FEATURE_AP_STA;
4430#endif
4431
4432 skb = cfg80211_vendor_cmd_alloc_reply_skb(wiphy, sizeof(fset) +
4433 NLMSG_HDRLEN);
4434
4435 if (!skb) {
4436 hddLog(LOGE, FL("cfg80211_vendor_cmd_alloc_reply_skb failed"));
4437 return -EINVAL;
4438 }
4439 hddLog(LOG1, FL("Supported Features : 0x%x"), fset);
4440
4441 if (nla_put_u32(skb, QCA_WLAN_VENDOR_ATTR_FEATURE_SET, fset)) {
4442 hddLog(LOGE, FL("nla put fail"));
4443 goto nla_put_failure;
4444 }
4445
4446 return cfg80211_vendor_cmd_reply(skb);
4447
4448nla_put_failure:
4449 kfree_skb(skb);
4450 return -EINVAL;
4451}
4452
Agarwal Ashish738843c2014-09-25 12:27:56 +05304453static const struct nla_policy
4454wlan_hdd_set_no_dfs_flag_config_policy[QCA_WLAN_VENDOR_ATTR_SET_NO_DFS_FLAG_MAX
4455 +1] =
4456{
4457 [QCA_WLAN_VENDOR_ATTR_SET_NO_DFS_FLAG] = {.type = NLA_U32 },
4458};
4459
4460static int wlan_hdd_cfg80211_disable_dfs_channels(struct wiphy *wiphy,
4461 struct wireless_dev *wdev,
4462 void *data,
4463 int data_len)
4464{
4465 struct net_device *dev = wdev->netdev;
4466 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
4467 tHalHandle hHal = WLAN_HDD_GET_HAL_CTX(pAdapter);
4468 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
4469 struct nlattr *tb[QCA_WLAN_VENDOR_ATTR_SET_NO_DFS_FLAG_MAX + 1];
4470 eHalStatus status;
4471 u32 dfsFlag = 0;
4472
4473 status = wlan_hdd_validate_context(pHddCtx);
4474 if (0 != status) {
4475 hddLog(VOS_TRACE_LEVEL_ERROR,
4476 FL("HDD context is not valid"));
4477 return -EINVAL;
4478 }
4479 if (nla_parse(tb, QCA_WLAN_VENDOR_ATTR_SET_NO_DFS_FLAG_MAX,
4480 data, data_len,
4481 wlan_hdd_set_no_dfs_flag_config_policy)) {
4482 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Invalid ATTR"));
4483 return -EINVAL;
4484 }
4485
4486 /* Parse and fetch required bandwidth kbps */
4487 if (!tb[QCA_WLAN_VENDOR_ATTR_SET_NO_DFS_FLAG]) {
4488 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr dfs flag failed"));
4489 return -EINVAL;
4490 }
4491
4492 dfsFlag = nla_get_u32(
4493 tb[QCA_WLAN_VENDOR_ATTR_SET_NO_DFS_FLAG]);
4494 hddLog(VOS_TRACE_LEVEL_INFO, FL(" DFS flag (%d)"),
4495 dfsFlag);
4496
4497 pHddCtx->disable_dfs_flag = dfsFlag;
4498
4499 sme_disable_dfs_channel(hHal, dfsFlag);
4500 sme_FilterScanResults(hHal, pAdapter->sessionId);
4501 return 0;
4502}
Atul Mittal115287b2014-07-08 13:26:33 +05304503
Sunil Duttc69bccb2014-05-26 21:30:20 +05304504const struct wiphy_vendor_command hdd_wiphy_vendor_commands[] =
4505{
4506#ifdef WLAN_FEATURE_LINK_LAYER_STATS
4507 {
4508 .info.vendor_id = QCA_NL80211_VENDOR_ID,
4509 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_LL_STATS_CLR,
4510 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
4511 WIPHY_VENDOR_CMD_NEED_NETDEV |
4512 WIPHY_VENDOR_CMD_NEED_RUNNING,
4513 .doit = wlan_hdd_cfg80211_ll_stats_clear
4514 },
4515
4516 {
4517 .info.vendor_id = QCA_NL80211_VENDOR_ID,
4518 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_LL_STATS_SET,
4519 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
4520 WIPHY_VENDOR_CMD_NEED_NETDEV |
4521 WIPHY_VENDOR_CMD_NEED_RUNNING,
4522 .doit = wlan_hdd_cfg80211_ll_stats_set
4523 },
4524
4525 {
4526 .info.vendor_id = QCA_NL80211_VENDOR_ID,
4527 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_LL_STATS_GET,
4528 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
4529 WIPHY_VENDOR_CMD_NEED_NETDEV |
4530 WIPHY_VENDOR_CMD_NEED_RUNNING,
4531 .doit = wlan_hdd_cfg80211_ll_stats_get
Dino Mycle6fb96c12014-06-10 11:52:40 +05304532 },
Sunil Duttc69bccb2014-05-26 21:30:20 +05304533#endif /* WLAN_FEATURE_LINK_LAYER_STATS */
Dino Mycle6fb96c12014-06-10 11:52:40 +05304534#ifdef WLAN_FEATURE_EXTSCAN
4535 {
4536 .info.vendor_id = QCA_NL80211_VENDOR_ID,
4537 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_START,
4538 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
4539 WIPHY_VENDOR_CMD_NEED_NETDEV |
4540 WIPHY_VENDOR_CMD_NEED_RUNNING,
4541 .doit = wlan_hdd_cfg80211_extscan_start
4542 },
4543 {
4544 .info.vendor_id = QCA_NL80211_VENDOR_ID,
4545 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_STOP,
4546 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
4547 WIPHY_VENDOR_CMD_NEED_NETDEV |
4548 WIPHY_VENDOR_CMD_NEED_RUNNING,
4549 .doit = wlan_hdd_cfg80211_extscan_stop
4550 },
4551 {
4552 .info.vendor_id = QCA_NL80211_VENDOR_ID,
4553 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_GET_VALID_CHANNELS,
4554 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
4555 WIPHY_VENDOR_CMD_NEED_NETDEV,
4556 .doit = wlan_hdd_cfg80211_extscan_get_valid_channels
4557 },
4558 {
4559 .info.vendor_id = QCA_NL80211_VENDOR_ID,
4560 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_GET_CAPABILITIES,
4561 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
4562 WIPHY_VENDOR_CMD_NEED_NETDEV |
4563 WIPHY_VENDOR_CMD_NEED_RUNNING,
4564 .doit = wlan_hdd_cfg80211_extscan_get_capabilities
4565 },
4566 {
4567 .info.vendor_id = QCA_NL80211_VENDOR_ID,
4568 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_GET_CACHED_RESULTS,
4569 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
4570 WIPHY_VENDOR_CMD_NEED_NETDEV |
4571 WIPHY_VENDOR_CMD_NEED_RUNNING,
4572 .doit = wlan_hdd_cfg80211_extscan_get_cached_results
4573 },
4574 {
4575 .info.vendor_id = QCA_NL80211_VENDOR_ID,
4576 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_SET_BSSID_HOTLIST,
4577 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
4578 WIPHY_VENDOR_CMD_NEED_NETDEV |
4579 WIPHY_VENDOR_CMD_NEED_RUNNING,
4580 .doit = wlan_hdd_cfg80211_extscan_set_bssid_hotlist
4581 },
4582 {
4583 .info.vendor_id = QCA_NL80211_VENDOR_ID,
4584 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_RESET_BSSID_HOTLIST,
4585 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
4586 WIPHY_VENDOR_CMD_NEED_NETDEV |
4587 WIPHY_VENDOR_CMD_NEED_RUNNING,
4588 .doit = wlan_hdd_cfg80211_extscan_reset_bssid_hotlist
4589 },
4590 {
4591 .info.vendor_id = QCA_NL80211_VENDOR_ID,
4592 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_SET_SIGNIFICANT_CHANGE,
4593 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
4594 WIPHY_VENDOR_CMD_NEED_NETDEV |
4595 WIPHY_VENDOR_CMD_NEED_RUNNING,
4596 .doit = wlan_hdd_cfg80211_extscan_set_significant_change
4597 },
4598 {
4599 .info.vendor_id = QCA_NL80211_VENDOR_ID,
4600 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_RESET_SIGNIFICANT_CHANGE,
4601 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
4602 WIPHY_VENDOR_CMD_NEED_NETDEV |
4603 WIPHY_VENDOR_CMD_NEED_RUNNING,
4604 .doit = wlan_hdd_cfg80211_extscan_reset_significant_change
4605 },
4606#endif /* WLAN_FEATURE_EXTSCAN */
Atul Mittal115287b2014-07-08 13:26:33 +05304607/*EXT TDLS*/
4608 {
4609 .info.vendor_id = QCA_NL80211_VENDOR_ID,
4610 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_TDLS_ENABLE,
4611 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
4612 WIPHY_VENDOR_CMD_NEED_NETDEV |
4613 WIPHY_VENDOR_CMD_NEED_RUNNING,
4614 .doit = wlan_hdd_cfg80211_exttdls_enable
4615 },
4616 {
4617 .info.vendor_id = QCA_NL80211_VENDOR_ID,
4618 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_TDLS_DISABLE,
4619 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
4620 WIPHY_VENDOR_CMD_NEED_NETDEV |
4621 WIPHY_VENDOR_CMD_NEED_RUNNING,
4622 .doit = wlan_hdd_cfg80211_exttdls_disable
4623 },
4624 {
4625 .info.vendor_id = QCA_NL80211_VENDOR_ID,
4626 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_TDLS_GET_STATUS,
4627 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
4628 WIPHY_VENDOR_CMD_NEED_NETDEV,
4629 .doit = wlan_hdd_cfg80211_exttdls_get_status
4630 },
Dasari Srinivas7875a302014-09-26 17:50:57 +05304631 {
4632 .info.vendor_id = QCA_NL80211_VENDOR_ID,
4633 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_GET_SUPPORTED_FEATURES,
4634 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
4635 WIPHY_VENDOR_CMD_NEED_NETDEV,
4636 .doit = wlan_hdd_cfg80211_get_supported_features
4637 },
Agarwal Ashish738843c2014-09-25 12:27:56 +05304638 {
4639 .info.vendor_id = QCA_NL80211_VENDOR_ID,
4640 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_NO_DFS_FLAG,
4641 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
4642 WIPHY_VENDOR_CMD_NEED_NETDEV,
4643 .doit = wlan_hdd_cfg80211_disable_dfs_channels
4644 },
Siddharth Bhala3a5cb42014-09-29 21:13:13 +05304645 {
4646 .info.vendor_id = QCA_NL80211_VENDOR_ID,
4647 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_MAC_OUI,
4648 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
4649 WIPHY_VENDOR_CMD_NEED_NETDEV,
4650 .doit = wlan_hdd_cfg80211_set_spoofed_mac_oui
4651 },
Sunil Duttc69bccb2014-05-26 21:30:20 +05304652};
4653
Rajesh Chauhan98a31f82014-01-06 20:15:25 -08004654/* vendor specific events */
Sunil Duttc69bccb2014-05-26 21:30:20 +05304655static const
4656struct nl80211_vendor_cmd_info wlan_hdd_cfg80211_vendor_events[] =
Rajesh Chauhan98a31f82014-01-06 20:15:25 -08004657{
4658#ifdef FEATURE_WLAN_CH_AVOID
4659 {
Sunil Duttc69bccb2014-05-26 21:30:20 +05304660 .vendor_id = QCA_NL80211_VENDOR_ID,
4661 .subcmd = QCA_NL80211_VENDOR_SUBCMD_AVOID_FREQUENCY
Rajesh Chauhan98a31f82014-01-06 20:15:25 -08004662 },
Sunil Duttc69bccb2014-05-26 21:30:20 +05304663#endif /* FEATURE_WLAN_CH_AVOID Index = 0*/
4664#ifdef WLAN_FEATURE_LINK_LAYER_STATS
4665 {
4666 /* Index = 1*/
4667 .vendor_id = QCA_NL80211_VENDOR_ID,
4668 .subcmd = QCA_NL80211_VENDOR_SUBCMD_LL_STATS_SET
4669 },
4670 {
4671 /* Index = 2*/
4672 .vendor_id = QCA_NL80211_VENDOR_ID,
4673 .subcmd = QCA_NL80211_VENDOR_SUBCMD_LL_STATS_GET
4674 },
4675 {
4676 /* Index = 3*/
4677 .vendor_id = QCA_NL80211_VENDOR_ID,
4678 .subcmd = QCA_NL80211_VENDOR_SUBCMD_LL_STATS_CLR
4679 },
4680 {
4681 /* Index = 4*/
4682 .vendor_id = QCA_NL80211_VENDOR_ID,
4683 .subcmd = QCA_NL80211_VENDOR_SUBCMD_LL_STATS_RADIO_RESULTS
4684 },
4685 {
4686 /* Index = 5*/
4687 .vendor_id = QCA_NL80211_VENDOR_ID,
4688 .subcmd = QCA_NL80211_VENDOR_SUBCMD_LL_STATS_IFACE_RESULTS
4689 },
4690 {
4691 /* Index = 6*/
4692 .vendor_id = QCA_NL80211_VENDOR_ID,
4693 .subcmd = QCA_NL80211_VENDOR_SUBCMD_LL_STATS_PEERS_RESULTS
4694 },
4695#endif /* WLAN_FEATURE_LINK_LAYER_STATS */
Dino Mycle6fb96c12014-06-10 11:52:40 +05304696#ifdef WLAN_FEATURE_EXTSCAN
4697 {
4698 .vendor_id = QCA_NL80211_VENDOR_ID,
4699 .subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_START
4700 },
4701 {
4702 .vendor_id = QCA_NL80211_VENDOR_ID,
4703 .subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_STOP
4704 },
4705 {
4706 .vendor_id = QCA_NL80211_VENDOR_ID,
4707 .subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_GET_CAPABILITIES
4708 },
4709 {
4710 .vendor_id = QCA_NL80211_VENDOR_ID,
4711 .subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_GET_CACHED_RESULTS
4712 },
4713 {
4714 .vendor_id = QCA_NL80211_VENDOR_ID,
4715 .subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_SCAN_RESULTS_AVAILABLE
4716 },
4717 {
4718 .vendor_id = QCA_NL80211_VENDOR_ID,
4719 .subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_FULL_SCAN_RESULT
4720 },
4721 {
4722 .vendor_id = QCA_NL80211_VENDOR_ID,
4723 .subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_SCAN_EVENT
4724 },
4725 {
4726 .vendor_id = QCA_NL80211_VENDOR_ID,
4727 .subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_HOTLIST_AP_FOUND
4728 },
4729 {
4730 .vendor_id = QCA_NL80211_VENDOR_ID,
4731 .subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_SET_BSSID_HOTLIST
4732 },
4733 {
4734 .vendor_id = QCA_NL80211_VENDOR_ID,
4735 .subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_RESET_BSSID_HOTLIST
4736 },
4737 {
4738 .vendor_id = QCA_NL80211_VENDOR_ID,
4739 .subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_SIGNIFICANT_CHANGE
4740 },
4741 {
4742 .vendor_id = QCA_NL80211_VENDOR_ID,
4743 .subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_SET_SIGNIFICANT_CHANGE
4744 },
4745 {
4746 .vendor_id = QCA_NL80211_VENDOR_ID,
4747 .subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_RESET_SIGNIFICANT_CHANGE
4748 },
4749#endif /* WLAN_FEATURE_EXTSCAN */
Atul Mittal115287b2014-07-08 13:26:33 +05304750/*EXT TDLS*/
4751 {
4752 .vendor_id = QCA_NL80211_VENDOR_ID,
4753 .subcmd = QCA_NL80211_VENDOR_SUBCMD_TDLS_STATE
4754 },
Rajesh Chauhan98a31f82014-01-06 20:15:25 -08004755};
4756
Jeff Johnson295189b2012-06-20 16:38:30 -07004757/*
Madan Mohan Koyyalamudi71278262013-04-12 22:00:48 +05304758 * FUNCTION: wlan_hdd_cfg80211_wiphy_alloc
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304759 * This function is called by hdd_wlan_startup()
4760 * during initialization.
Madan Mohan Koyyalamudi71278262013-04-12 22:00:48 +05304761 * This function is used to allocate wiphy structure.
Jeff Johnson295189b2012-06-20 16:38:30 -07004762 */
Madan Mohan Koyyalamudi71278262013-04-12 22:00:48 +05304763struct wiphy *wlan_hdd_cfg80211_wiphy_alloc(int priv_size)
Jeff Johnson295189b2012-06-20 16:38:30 -07004764{
4765 struct wiphy *wiphy;
4766 ENTER();
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304767 /*
4768 * Create wiphy device
Jeff Johnson295189b2012-06-20 16:38:30 -07004769 */
4770 wiphy = wiphy_new(&wlan_hdd_cfg80211_ops, priv_size);
4771
4772 if (!wiphy)
4773 {
4774 /* Print error and jump into err label and free the memory */
4775 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: wiphy init failed", __func__);
4776 return NULL;
4777 }
4778
Sunil Duttc69bccb2014-05-26 21:30:20 +05304779
Jeff Johnson295189b2012-06-20 16:38:30 -07004780 return wiphy;
4781}
4782
4783/*
4784 * FUNCTION: wlan_hdd_cfg80211_update_band
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304785 * This function is called from the supplicant through a
Jeff Johnson295189b2012-06-20 16:38:30 -07004786 * private ioctl to change the band value
4787 */
4788int wlan_hdd_cfg80211_update_band(struct wiphy *wiphy, eCsrBand eBand)
4789{
Gopichand Nakkala1f7a64f2013-04-01 18:37:17 +05304790 int i, j;
4791 eNVChannelEnabledType channelEnabledState;
4792
Jeff Johnsone7245742012-09-05 17:12:55 -07004793 ENTER();
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05304794
Gopichand Nakkala1f7a64f2013-04-01 18:37:17 +05304795 for (i = 0; i < IEEE80211_NUM_BANDS; i++)
Jeff Johnson295189b2012-06-20 16:38:30 -07004796 {
Gopichand Nakkala1f7a64f2013-04-01 18:37:17 +05304797
4798 if (NULL == wiphy->bands[i])
4799 {
4800 hddLog(VOS_TRACE_LEVEL_ERROR,"%s: wiphy->bands[i] is NULL, i = %d",
4801 __func__, i);
4802 continue;
4803 }
4804
4805 for (j = 0; j < wiphy->bands[i]->n_channels; j++)
4806 {
4807 struct ieee80211_supported_band *band = wiphy->bands[i];
4808
4809 channelEnabledState = vos_nv_getChannelEnabledState(
4810 band->channels[j].hw_value);
4811
4812 if (IEEE80211_BAND_2GHZ == i && eCSR_BAND_5G == eBand) // 5G only
4813 {
4814 // Enable Social channels for P2P
4815 if (WLAN_HDD_IS_SOCIAL_CHANNEL(band->channels[j].center_freq) &&
4816 NV_CHANNEL_ENABLE == channelEnabledState)
4817 band->channels[j].flags &= ~IEEE80211_CHAN_DISABLED;
4818 else
4819 band->channels[j].flags |= IEEE80211_CHAN_DISABLED;
4820 continue;
4821 }
4822 else if (IEEE80211_BAND_5GHZ == i && eCSR_BAND_24 == eBand) // 2G only
4823 {
4824 band->channels[j].flags |= IEEE80211_CHAN_DISABLED;
4825 continue;
4826 }
4827
4828 if (NV_CHANNEL_DISABLE == channelEnabledState ||
4829 NV_CHANNEL_INVALID == channelEnabledState)
4830 {
4831 band->channels[j].flags |= IEEE80211_CHAN_DISABLED;
4832 }
4833 else if (NV_CHANNEL_DFS == channelEnabledState)
4834 {
4835 band->channels[j].flags &= ~IEEE80211_CHAN_DISABLED;
4836 band->channels[j].flags |= IEEE80211_CHAN_RADAR;
4837 }
4838 else
4839 {
4840 band->channels[j].flags &= ~(IEEE80211_CHAN_DISABLED
4841 |IEEE80211_CHAN_RADAR);
4842 }
4843 }
Jeff Johnson295189b2012-06-20 16:38:30 -07004844 }
4845 return 0;
4846}
4847/*
4848 * FUNCTION: wlan_hdd_cfg80211_init
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304849 * This function is called by hdd_wlan_startup()
4850 * during initialization.
Jeff Johnson295189b2012-06-20 16:38:30 -07004851 * This function is used to initialize and register wiphy structure.
4852 */
Madan Mohan Koyyalamudi71278262013-04-12 22:00:48 +05304853int wlan_hdd_cfg80211_init(struct device *dev,
Jeff Johnson295189b2012-06-20 16:38:30 -07004854 struct wiphy *wiphy,
4855 hdd_config_t *pCfg
4856 )
4857{
Gopichand Nakkala1f7a64f2013-04-01 18:37:17 +05304858 int i, j;
Vinay Krishna Erannafacf5e22014-02-24 13:16:25 +05304859 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
4860
Jeff Johnsone7245742012-09-05 17:12:55 -07004861 ENTER();
4862
Jeff Johnson295189b2012-06-20 16:38:30 -07004863 /* Now bind the underlying wlan device with wiphy */
4864 set_wiphy_dev(wiphy, dev);
4865
4866 wiphy->mgmt_stypes = wlan_hdd_txrx_stypes;
Amar Singhalfddc28c2013-09-05 13:03:40 -07004867
Kiet Lam6c583332013-10-14 05:37:09 +05304868#ifndef CONFIG_ENABLE_LINUX_REG
Amar Singhal0a402232013-10-11 20:57:16 -07004869 /* the flag for the other case would be initialzed in
4870 vos_init_wiphy_from_nv_bin */
Amar Singhal0a402232013-10-11 20:57:16 -07004871 wiphy->flags |= WIPHY_FLAG_STRICT_REGULATORY;
Kiet Lam6c583332013-10-14 05:37:09 +05304872#endif
Amar Singhala49cbc52013-10-08 18:37:44 -07004873
Amar Singhalfddc28c2013-09-05 13:03:40 -07004874 /* This will disable updating of NL channels from passive to
4875 * active if a beacon is received on passive channel. */
4876 wiphy->flags |= WIPHY_FLAG_DISABLE_BEACON_HINTS;
Amar Singhalf0073192013-09-20 12:34:56 -07004877
Amar Singhalfddc28c2013-09-05 13:03:40 -07004878
Amar Singhala49cbc52013-10-08 18:37:44 -07004879
Jeff Johnson04dd8a82012-06-29 20:41:40 -07004880#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,4,0))
Madan Mohan Koyyalamudi1b4afb02012-10-22 15:25:16 -07004881 wiphy->flags |= WIPHY_FLAG_HAVE_AP_SME
4882 | WIPHY_FLAG_AP_PROBE_RESP_OFFLOAD
4883 | WIPHY_FLAG_HAS_REMAIN_ON_CHANNEL
Jeff Johnsone7245742012-09-05 17:12:55 -07004884 | WIPHY_FLAG_OFFCHAN_TX;
Kiet Lam6c583332013-10-14 05:37:09 +05304885 wiphy->country_ie_pref = NL80211_COUNTRY_IE_IGNORE_CORE;
Jeff Johnson04dd8a82012-06-29 20:41:40 -07004886#endif
Amar Singhala49cbc52013-10-08 18:37:44 -07004887
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08004888#if defined (WLAN_FEATURE_VOWIFI_11R) || defined (FEATURE_WLAN_ESE) || defined(FEATURE_WLAN_LFR)
Srinivas Girigowda640728a2013-03-28 12:21:54 -07004889 if (pCfg->isFastTransitionEnabled
James Zmuda77fb5ae2013-01-29 08:00:17 -08004890#ifdef FEATURE_WLAN_LFR
Srinivas Girigowda640728a2013-03-28 12:21:54 -07004891 || pCfg->isFastRoamIniFeatureEnabled
4892#endif
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08004893#ifdef FEATURE_WLAN_ESE
4894 || pCfg->isEseIniFeatureEnabled
Srinivas Girigowda640728a2013-03-28 12:21:54 -07004895#endif
4896 )
4897 {
4898 wiphy->flags |= WIPHY_FLAG_SUPPORTS_FW_ROAM;
4899 }
James Zmuda77fb5ae2013-01-29 08:00:17 -08004900#endif
Mohit Khanna698ba2a2012-12-04 15:08:18 -08004901#ifdef FEATURE_WLAN_TDLS
4902 wiphy->flags |= WIPHY_FLAG_SUPPORTS_TDLS
4903 | WIPHY_FLAG_TDLS_EXTERNAL_SETUP;
4904#endif
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +05304905#ifdef FEATURE_WLAN_SCAN_PNO
Hardik Kantilal Patel3dfd8792013-11-13 20:34:57 +05304906 if (pCfg->configPNOScanSupport)
4907 {
4908 wiphy->flags |= WIPHY_FLAG_SUPPORTS_SCHED_SCAN;
4909 wiphy->max_sched_scan_ssids = SIR_PNO_MAX_SUPP_NETWORKS;
4910 wiphy->max_match_sets = SIR_PNO_MAX_SUPP_NETWORKS;
4911 wiphy->max_sched_scan_ie_len = SIR_MAC_MAX_IE_LENGTH;
4912 }
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +05304913#endif/*FEATURE_WLAN_SCAN_PNO*/
Mohit Khanna698ba2a2012-12-04 15:08:18 -08004914
Amar Singhalfddc28c2013-09-05 13:03:40 -07004915#ifdef CONFIG_ENABLE_LINUX_REG
Madan Mohan Koyyalamudic3a240c2012-09-28 15:34:08 -07004916 /* even with WIPHY_FLAG_CUSTOM_REGULATORY,
4917 driver can still register regulatory callback and
Amar Singhalfddc28c2013-09-05 13:03:40 -07004918 it will get regulatory settings in wiphy->band[], but
Madan Mohan Koyyalamudic3a240c2012-09-28 15:34:08 -07004919 driver need to determine what to do with both
4920 regulatory settings */
Amar Singhalfddc28c2013-09-05 13:03:40 -07004921
4922 wiphy->reg_notifier = wlan_hdd_linux_reg_notifier;
Amar Singhala49cbc52013-10-08 18:37:44 -07004923#else
4924 wiphy->reg_notifier = wlan_hdd_crda_reg_notifier;
Amar Singhalfddc28c2013-09-05 13:03:40 -07004925#endif
Jeff Johnson04dd8a82012-06-29 20:41:40 -07004926
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304927 wiphy->max_scan_ssids = MAX_SCAN_SSID;
4928
Madan Mohan Koyyalamudi6815b162013-07-19 17:17:46 +05304929 wiphy->max_scan_ie_len = SIR_MAC_MAX_IE_LENGTH;
Jeff Johnson295189b2012-06-20 16:38:30 -07004930
Gopichand Nakkalac005b7c2013-05-14 16:04:14 +05304931 wiphy->max_acl_mac_addrs = MAX_ACL_MAC_ADDRESS;
4932
Jeff Johnson295189b2012-06-20 16:38:30 -07004933 /* Supports STATION & AD-HOC modes right now */
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304934 wiphy->interface_modes = BIT(NL80211_IFTYPE_STATION)
Jeff Johnson295189b2012-06-20 16:38:30 -07004935 | BIT(NL80211_IFTYPE_ADHOC)
Jeff Johnson295189b2012-06-20 16:38:30 -07004936 | BIT(NL80211_IFTYPE_P2P_CLIENT)
4937 | BIT(NL80211_IFTYPE_P2P_GO)
Jeff Johnson295189b2012-06-20 16:38:30 -07004938 | BIT(NL80211_IFTYPE_AP);
4939
Rashmi Ramannabd3feb72014-02-25 16:14:48 +05304940 if( pCfg->advertiseConcurrentOperation )
Sudhir Sattayappa Kohalli278eee52013-01-16 17:35:13 -08004941 {
Rashmi Ramannabd3feb72014-02-25 16:14:48 +05304942#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,4,0))
4943 if( pCfg->enableMCC )
4944 {
4945 /* Currently, supports up to two channels */
4946 wlan_hdd_iface_combination.num_different_channels = 2;
Sudhir Sattayappa Kohalli278eee52013-01-16 17:35:13 -08004947
Rashmi Ramannabd3feb72014-02-25 16:14:48 +05304948 if( !pCfg->allowMCCGODiffBI )
4949 wlan_hdd_iface_combination.beacon_int_infra_match = true;
Sudhir Sattayappa Kohalli278eee52013-01-16 17:35:13 -08004950
Rashmi Ramannabd3feb72014-02-25 16:14:48 +05304951 }
4952 wiphy->iface_combinations = &wlan_hdd_iface_combination;
4953 wiphy->n_iface_combinations = 1;
Sudhir Sattayappa Kohalli278eee52013-01-16 17:35:13 -08004954#endif
Rashmi Ramannabd3feb72014-02-25 16:14:48 +05304955 }
Sudhir Sattayappa Kohalli278eee52013-01-16 17:35:13 -08004956
Jeff Johnson295189b2012-06-20 16:38:30 -07004957 /* Before registering we need to update the ht capabilitied based
4958 * on ini values*/
4959 if( !pCfg->ShortGI20MhzEnable )
4960 {
4961 wlan_hdd_band_2_4_GHZ.ht_cap.cap &= ~IEEE80211_HT_CAP_SGI_20;
4962 wlan_hdd_band_5_GHZ.ht_cap.cap &= ~IEEE80211_HT_CAP_SGI_20;
4963 wlan_hdd_band_p2p_2_4_GHZ.ht_cap.cap &= ~IEEE80211_HT_CAP_SGI_20;
4964 }
4965
4966 if( !pCfg->ShortGI40MhzEnable )
4967 {
4968 wlan_hdd_band_5_GHZ.ht_cap.cap &= ~IEEE80211_HT_CAP_SGI_40;
4969 }
4970
4971 if( !pCfg->nChannelBondingMode5GHz )
4972 {
4973 wlan_hdd_band_5_GHZ.ht_cap.cap &= ~IEEE80211_HT_CAP_SUP_WIDTH_20_40;
4974 }
4975
Gopichand Nakkala1f7a64f2013-04-01 18:37:17 +05304976 wiphy->bands[IEEE80211_BAND_2GHZ] = &wlan_hdd_band_2_4_GHZ;
Vinay Krishna Erannafacf5e22014-02-24 13:16:25 +05304977 if (true == hdd_is_5g_supported(pHddCtx))
4978 {
4979 wiphy->bands[IEEE80211_BAND_5GHZ] = &wlan_hdd_band_5_GHZ;
4980 }
Gopichand Nakkala1f7a64f2013-04-01 18:37:17 +05304981
4982 for (i = 0; i < IEEE80211_NUM_BANDS; i++)
4983 {
4984
4985 if (NULL == wiphy->bands[i])
4986 {
4987 hddLog(VOS_TRACE_LEVEL_ERROR,"%s: wiphy->bands[i] is NULL, i = %d",
4988 __func__, i);
4989 continue;
4990 }
4991
4992 for (j = 0; j < wiphy->bands[i]->n_channels; j++)
4993 {
4994 struct ieee80211_supported_band *band = wiphy->bands[i];
4995
4996 if (IEEE80211_BAND_2GHZ == i && eCSR_BAND_5G == pCfg->nBandCapability) // 5G only
4997 {
4998 // Enable social channels for P2P
4999 if (WLAN_HDD_IS_SOCIAL_CHANNEL(band->channels[j].center_freq))
5000 band->channels[j].flags &= ~IEEE80211_CHAN_DISABLED;
5001 else
5002 band->channels[j].flags |= IEEE80211_CHAN_DISABLED;
5003 continue;
5004 }
5005 else if (IEEE80211_BAND_5GHZ == i && eCSR_BAND_24 == pCfg->nBandCapability) // 2G only
5006 {
5007 band->channels[j].flags |= IEEE80211_CHAN_DISABLED;
5008 continue;
5009 }
5010 }
Jeff Johnson295189b2012-06-20 16:38:30 -07005011 }
5012 /*Initialise the supported cipher suite details*/
5013 wiphy->cipher_suites = hdd_cipher_suites;
5014 wiphy->n_cipher_suites = ARRAY_SIZE(hdd_cipher_suites);
5015
5016 /*signal strength in mBm (100*dBm) */
5017 wiphy->signal_type = CFG80211_SIGNAL_TYPE_MBM;
5018
5019#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
Sushant Kaushik4f640e42014-07-08 12:27:09 +05305020 wiphy->max_remain_on_channel_duration = 5000;
Jeff Johnson295189b2012-06-20 16:38:30 -07005021#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07005022
Sunil Duttc69bccb2014-05-26 21:30:20 +05305023 wiphy->n_vendor_commands = ARRAY_SIZE(hdd_wiphy_vendor_commands);
5024 wiphy->vendor_commands = hdd_wiphy_vendor_commands;
Rajesh Chauhan98a31f82014-01-06 20:15:25 -08005025 wiphy->vendor_events = wlan_hdd_cfg80211_vendor_events;
5026 wiphy->n_vendor_events = ARRAY_SIZE(wlan_hdd_cfg80211_vendor_events);
5027
Madan Mohan Koyyalamudi71278262013-04-12 22:00:48 +05305028 EXIT();
5029 return 0;
5030}
5031
5032/* In this function we are registering wiphy. */
5033int wlan_hdd_cfg80211_register(struct wiphy *wiphy)
5034{
5035 ENTER();
5036 /* Register our wiphy dev with cfg80211 */
Jeff Johnson295189b2012-06-20 16:38:30 -07005037 if (0 > wiphy_register(wiphy))
5038 {
Madan Mohan Koyyalamudi71278262013-04-12 22:00:48 +05305039 /* print error */
Jeff Johnson295189b2012-06-20 16:38:30 -07005040 hddLog(VOS_TRACE_LEVEL_ERROR,"%s: wiphy register failed", __func__);
5041 return -EIO;
5042 }
5043
5044 EXIT();
5045 return 0;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305046}
Jeff Johnson295189b2012-06-20 16:38:30 -07005047
Madan Mohan Koyyalamudi71278262013-04-12 22:00:48 +05305048/* In this function we are updating channel list when,
5049 regulatory domain is FCC and country code is US.
5050 Here In FCC standard 5GHz UNII-1 Bands are indoor only.
5051 As per FCC smart phone is not a indoor device.
5052 GO should not opeate on indoor channels */
5053void wlan_hdd_cfg80211_update_reg_info(struct wiphy *wiphy)
5054{
5055 int j;
5056 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
5057 tANI_U8 defaultCountryCode[3] = SME_INVALID_COUNTRY_CODE;
5058 //Default counrtycode from NV at the time of wiphy initialization.
5059 if (eHAL_STATUS_SUCCESS != sme_GetDefaultCountryCodeFrmNv(pHddCtx->hHal,
5060 &defaultCountryCode[0]))
5061 {
Jeff Johnson0299d0a2013-10-30 12:37:43 -07005062 hddLog(LOGE, FL("Failed to get default country code from NV"));
Madan Mohan Koyyalamudi71278262013-04-12 22:00:48 +05305063 }
5064 if ((defaultCountryCode[0]== 'U') && (defaultCountryCode[1]=='S'))
5065 {
Madan Mohan Koyyalamudi71278262013-04-12 22:00:48 +05305066 if (NULL == wiphy->bands[IEEE80211_BAND_5GHZ])
5067 {
5068 hddLog(VOS_TRACE_LEVEL_ERROR,"%s: wiphy->bands[IEEE80211_BAND_5GHZ] is NULL",__func__ );
5069 return;
5070 }
5071 for (j = 0; j < wiphy->bands[IEEE80211_BAND_5GHZ]->n_channels; j++)
5072 {
5073 struct ieee80211_supported_band *band = wiphy->bands[IEEE80211_BAND_5GHZ];
5074 // Mark UNII -1 band channel as passive
5075 if (WLAN_HDD_CHANNEL_IN_UNII_1_BAND(band->channels[j].center_freq))
5076 band->channels[j].flags |= IEEE80211_CHAN_PASSIVE_SCAN;
5077 }
5078 }
5079}
5080
Agarwal Ashish8fa0e9a2014-05-23 00:40:12 +05305081/* This function registers for all frame which supplicant is interested in */
5082void wlan_hdd_cfg80211_register_frames(hdd_adapter_t* pAdapter)
Jeff Johnson295189b2012-06-20 16:38:30 -07005083{
Jeff Johnson295189b2012-06-20 16:38:30 -07005084 tHalHandle hHal = WLAN_HDD_GET_HAL_CTX(pAdapter);
5085 /* Register for all P2P action, public action etc frames */
5086 v_U16_t type = (SIR_MAC_MGMT_FRAME << 2) | ( SIR_MAC_MGMT_ACTION << 4);
5087
Jeff Johnsone7245742012-09-05 17:12:55 -07005088 ENTER();
5089
Jeff Johnson295189b2012-06-20 16:38:30 -07005090 /* Right now we are registering these frame when driver is getting
5091 initialized. Once we will move to 2.6.37 kernel, in which we have
5092 frame register ops, we will move this code as a part of that */
5093 /* GAS Initial Request */
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305094 sme_RegisterMgmtFrame(hHal, pAdapter->sessionId, type,
Jeff Johnson295189b2012-06-20 16:38:30 -07005095 (v_U8_t*)GAS_INITIAL_REQ, GAS_INITIAL_REQ_SIZE );
5096
5097 /* GAS Initial Response */
5098 sme_RegisterMgmtFrame(hHal, pAdapter->sessionId, type,
5099 (v_U8_t*)GAS_INITIAL_RSP, GAS_INITIAL_RSP_SIZE );
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305100
Jeff Johnson295189b2012-06-20 16:38:30 -07005101 /* GAS Comeback Request */
5102 sme_RegisterMgmtFrame(hHal, pAdapter->sessionId, type,
5103 (v_U8_t*)GAS_COMEBACK_REQ, GAS_COMEBACK_REQ_SIZE );
5104
5105 /* GAS Comeback Response */
5106 sme_RegisterMgmtFrame(hHal, pAdapter->sessionId, type,
5107 (v_U8_t*)GAS_COMEBACK_RSP, GAS_COMEBACK_RSP_SIZE );
5108
5109 /* P2P Public Action */
5110 sme_RegisterMgmtFrame(hHal, pAdapter->sessionId, type,
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305111 (v_U8_t*)P2P_PUBLIC_ACTION_FRAME,
Jeff Johnson295189b2012-06-20 16:38:30 -07005112 P2P_PUBLIC_ACTION_FRAME_SIZE );
5113
5114 /* P2P Action */
5115 sme_RegisterMgmtFrame(hHal, pAdapter->sessionId, type,
5116 (v_U8_t*)P2P_ACTION_FRAME,
5117 P2P_ACTION_FRAME_SIZE );
Chet Lanctot186b5732013-03-18 10:26:30 -07005118
Gopichand Nakkalae3d56e72013-04-21 23:33:32 +05305119 /* WNM BSS Transition Request frame */
5120 sme_RegisterMgmtFrame(hHal, pAdapter->sessionId, type,
5121 (v_U8_t*)WNM_BSS_ACTION_FRAME,
5122 WNM_BSS_ACTION_FRAME_SIZE );
Leela Venkata Kiran Kumar Reddy Chiralae8e62c82013-10-29 18:23:26 -07005123
5124 /* WNM-Notification */
5125 sme_RegisterMgmtFrame(hHal, pAdapter->sessionId, type,
5126 (v_U8_t*)WNM_NOTIFICATION_FRAME,
5127 WNM_NOTIFICATION_FRAME_SIZE );
Jeff Johnson295189b2012-06-20 16:38:30 -07005128}
5129
Agarwal Ashish8fa0e9a2014-05-23 00:40:12 +05305130void wlan_hdd_cfg80211_deregister_frames(hdd_adapter_t* pAdapter)
Jeff Johnson295189b2012-06-20 16:38:30 -07005131{
Jeff Johnson295189b2012-06-20 16:38:30 -07005132 tHalHandle hHal = WLAN_HDD_GET_HAL_CTX(pAdapter);
5133 /* Register for all P2P action, public action etc frames */
5134 v_U16_t type = (SIR_MAC_MGMT_FRAME << 2) | ( SIR_MAC_MGMT_ACTION << 4);
5135
Jeff Johnsone7245742012-09-05 17:12:55 -07005136 ENTER();
5137
Jeff Johnson295189b2012-06-20 16:38:30 -07005138 /* Right now we are registering these frame when driver is getting
5139 initialized. Once we will move to 2.6.37 kernel, in which we have
5140 frame register ops, we will move this code as a part of that */
5141 /* GAS Initial Request */
5142
5143 sme_DeregisterMgmtFrame(hHal, pAdapter->sessionId, type,
5144 (v_U8_t*)GAS_INITIAL_REQ, GAS_INITIAL_REQ_SIZE );
5145
5146 /* GAS Initial Response */
5147 sme_DeregisterMgmtFrame(hHal, pAdapter->sessionId, type,
5148 (v_U8_t*)GAS_INITIAL_RSP, GAS_INITIAL_RSP_SIZE );
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305149
Jeff Johnson295189b2012-06-20 16:38:30 -07005150 /* GAS Comeback Request */
5151 sme_DeregisterMgmtFrame(hHal, pAdapter->sessionId, type,
5152 (v_U8_t*)GAS_COMEBACK_REQ, GAS_COMEBACK_REQ_SIZE );
5153
5154 /* GAS Comeback Response */
5155 sme_DeregisterMgmtFrame(hHal, pAdapter->sessionId, type,
5156 (v_U8_t*)GAS_COMEBACK_RSP, GAS_COMEBACK_RSP_SIZE );
5157
5158 /* P2P Public Action */
5159 sme_DeregisterMgmtFrame(hHal, pAdapter->sessionId, type,
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305160 (v_U8_t*)P2P_PUBLIC_ACTION_FRAME,
Jeff Johnson295189b2012-06-20 16:38:30 -07005161 P2P_PUBLIC_ACTION_FRAME_SIZE );
5162
5163 /* P2P Action */
5164 sme_DeregisterMgmtFrame(hHal, pAdapter->sessionId, type,
5165 (v_U8_t*)P2P_ACTION_FRAME,
5166 P2P_ACTION_FRAME_SIZE );
Leela Venkata Kiran Kumar Reddy Chiralae8e62c82013-10-29 18:23:26 -07005167 /* WNM-Notification */
5168 sme_DeregisterMgmtFrame(hHal, pAdapter->sessionId, type,
5169 (v_U8_t*)WNM_NOTIFICATION_FRAME,
5170 WNM_NOTIFICATION_FRAME_SIZE );
Jeff Johnson295189b2012-06-20 16:38:30 -07005171}
5172
5173#ifdef FEATURE_WLAN_WAPI
5174void wlan_hdd_cfg80211_set_key_wapi(hdd_adapter_t* pAdapter, u8 key_index,
5175 const u8 *mac_addr, u8 *key , int key_Len)
5176{
5177 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
5178 tCsrRoamSetKey setKey;
5179 v_BOOL_t isConnected = TRUE;
5180 int status = 0;
5181 v_U32_t roamId= 0xFF;
5182 tANI_U8 *pKeyPtr = NULL;
5183 int n = 0;
5184
Sushant Kaushik8bc7df22014-04-09 17:55:29 +05305185 hddLog(VOS_TRACE_LEVEL_INFO, "%s: device_mode = %s(%d)",
5186 __func__, hdd_device_modetoString(pAdapter->device_mode),
5187 pAdapter->device_mode);
Jeff Johnson295189b2012-06-20 16:38:30 -07005188
Gopichand Nakkalae7480202013-02-11 15:24:22 +05305189 vos_mem_zero(&setKey, sizeof(tCsrRoamSetKey));
Jeff Johnson295189b2012-06-20 16:38:30 -07005190 setKey.keyId = key_index; // Store Key ID
5191 setKey.encType = eCSR_ENCRYPT_TYPE_WPI; // SET WAPI Encryption
5192 setKey.keyDirection = eSIR_TX_RX; // Key Directionn both TX and RX
5193 setKey.paeRole = 0 ; // the PAE role
5194 if (!mac_addr || is_broadcast_ether_addr(mac_addr))
5195 {
5196 vos_set_macaddr_broadcast( (v_MACADDR_t *)setKey.peerMac );
5197 }
5198 else
5199 {
5200 isConnected = hdd_connIsConnected(pHddStaCtx);
5201 vos_mem_copy(setKey.peerMac,&pHddStaCtx->conn_info.bssId,WNI_CFG_BSSID_LEN);
5202 }
5203 setKey.keyLength = key_Len;
5204 pKeyPtr = setKey.Key;
5205 memcpy( pKeyPtr, key, key_Len);
5206
Arif Hussain6d2a3322013-11-17 19:50:10 -08005207 hddLog(VOS_TRACE_LEVEL_INFO,"%s: WAPI KEY LENGTH:0x%04x",
Jeff Johnson295189b2012-06-20 16:38:30 -07005208 __func__, key_Len);
5209 for (n = 0 ; n < key_Len; n++)
5210 hddLog(VOS_TRACE_LEVEL_INFO, "%s WAPI KEY Data[%d]:%02x ",
5211 __func__,n,setKey.Key[n]);
5212
5213 pHddStaCtx->roam_info.roamingState = HDD_ROAM_STATE_SETTING_KEY;
5214 if ( isConnected )
5215 {
5216 status= sme_RoamSetKey( WLAN_HDD_GET_HAL_CTX(pAdapter),
5217 pAdapter->sessionId, &setKey, &roamId );
5218 }
5219 if ( status != 0 )
5220 {
5221 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
5222 "[%4d] sme_RoamSetKey returned ERROR status= %d",
5223 __LINE__, status );
5224 pHddStaCtx->roam_info.roamingState = HDD_ROAM_STATE_NONE;
5225 }
Vinay Krishna Eranna6f22c1f2014-10-13 16:03:06 +05305226 /* Need to clear any trace of key value in the memory.
5227 * Thus zero out the memory even though it is local
5228 * variable.
5229 */
5230 vos_mem_zero(&setKey, sizeof(setKey));
Jeff Johnson295189b2012-06-20 16:38:30 -07005231}
5232#endif /* FEATURE_WLAN_WAPI*/
5233
5234#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,4,0))
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305235int wlan_hdd_cfg80211_alloc_new_beacon(hdd_adapter_t *pAdapter,
Jeff Johnson295189b2012-06-20 16:38:30 -07005236 beacon_data_t **ppBeacon,
5237 struct beacon_parameters *params)
Jeff Johnson04dd8a82012-06-29 20:41:40 -07005238#else
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305239int wlan_hdd_cfg80211_alloc_new_beacon(hdd_adapter_t *pAdapter,
Jeff Johnson04dd8a82012-06-29 20:41:40 -07005240 beacon_data_t **ppBeacon,
5241 struct cfg80211_beacon_data *params,
5242 int dtim_period)
5243#endif
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305244{
Jeff Johnson295189b2012-06-20 16:38:30 -07005245 int size;
5246 beacon_data_t *beacon = NULL;
5247 beacon_data_t *old = NULL;
5248 int head_len,tail_len;
5249
Jeff Johnsone7245742012-09-05 17:12:55 -07005250 ENTER();
Jeff Johnson295189b2012-06-20 16:38:30 -07005251 if (params->head && !params->head_len)
c_hpothu6ff1c3c2013-10-01 19:01:57 +05305252 {
5253 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
5254 FL("head_len is NULL"));
Jeff Johnson295189b2012-06-20 16:38:30 -07005255 return -EINVAL;
c_hpothu6ff1c3c2013-10-01 19:01:57 +05305256 }
Jeff Johnson295189b2012-06-20 16:38:30 -07005257
5258 old = pAdapter->sessionCtx.ap.beacon;
5259
5260 if (!params->head && !old)
c_hpothu6ff1c3c2013-10-01 19:01:57 +05305261 {
5262 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
5263 FL("session(%d) old and new heads points to NULL"),
5264 pAdapter->sessionId);
Jeff Johnson295189b2012-06-20 16:38:30 -07005265 return -EINVAL;
c_hpothu6ff1c3c2013-10-01 19:01:57 +05305266 }
5267
5268 if (params->tail && !params->tail_len)
5269 {
5270 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
5271 FL("tail_len is zero but tail is not NULL"));
5272 return -EINVAL;
5273 }
Jeff Johnson295189b2012-06-20 16:38:30 -07005274
Jeff Johnson295189b2012-06-20 16:38:30 -07005275#if (LINUX_VERSION_CODE <= KERNEL_VERSION(2,6,38))
5276 /* Kernel 3.0 is not updating dtim_period for set beacon */
5277 if (!params->dtim_period)
c_hpothu6ff1c3c2013-10-01 19:01:57 +05305278 {
5279 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
5280 FL("dtim period is 0"));
Jeff Johnson295189b2012-06-20 16:38:30 -07005281 return -EINVAL;
c_hpothu6ff1c3c2013-10-01 19:01:57 +05305282 }
Jeff Johnson295189b2012-06-20 16:38:30 -07005283#endif
5284
5285 if(params->head)
5286 head_len = params->head_len;
5287 else
5288 head_len = old->head_len;
5289
5290 if(params->tail || !old)
5291 tail_len = params->tail_len;
5292 else
5293 tail_len = old->tail_len;
5294
5295 size = sizeof(beacon_data_t) + head_len + tail_len;
5296
5297 beacon = kzalloc(size, GFP_KERNEL);
5298
5299 if( beacon == NULL )
c_hpothu6ff1c3c2013-10-01 19:01:57 +05305300 {
5301 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
5302 FL("Mem allocation for beacon failed"));
Jeff Johnson295189b2012-06-20 16:38:30 -07005303 return -ENOMEM;
c_hpothu6ff1c3c2013-10-01 19:01:57 +05305304 }
Jeff Johnson295189b2012-06-20 16:38:30 -07005305
Jeff Johnson04dd8a82012-06-29 20:41:40 -07005306#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,4,0))
Jeff Johnson295189b2012-06-20 16:38:30 -07005307 if(params->dtim_period || !old )
5308 beacon->dtim_period = params->dtim_period;
5309 else
5310 beacon->dtim_period = old->dtim_period;
Jeff Johnson04dd8a82012-06-29 20:41:40 -07005311#else
5312 if(dtim_period || !old )
5313 beacon->dtim_period = dtim_period;
5314 else
5315 beacon->dtim_period = old->dtim_period;
5316#endif
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305317
Jeff Johnson295189b2012-06-20 16:38:30 -07005318 beacon->head = ((u8 *) beacon) + sizeof(beacon_data_t);
5319 beacon->tail = beacon->head + head_len;
5320 beacon->head_len = head_len;
5321 beacon->tail_len = tail_len;
5322
5323 if(params->head) {
5324 memcpy (beacon->head,params->head,beacon->head_len);
5325 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305326 else {
Jeff Johnson295189b2012-06-20 16:38:30 -07005327 if(old)
5328 memcpy (beacon->head,old->head,beacon->head_len);
5329 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305330
Jeff Johnson295189b2012-06-20 16:38:30 -07005331 if(params->tail) {
5332 memcpy (beacon->tail,params->tail,beacon->tail_len);
5333 }
5334 else {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305335 if(old)
Jeff Johnson295189b2012-06-20 16:38:30 -07005336 memcpy (beacon->tail,old->tail,beacon->tail_len);
5337 }
5338
5339 *ppBeacon = beacon;
5340
5341 kfree(old);
5342
5343 return 0;
5344
5345}
Jeff Johnson295189b2012-06-20 16:38:30 -07005346
5347v_U8_t* wlan_hdd_cfg80211_get_ie_ptr(v_U8_t *pIes, int length, v_U8_t eid)
5348{
5349 int left = length;
5350 v_U8_t *ptr = pIes;
5351 v_U8_t elem_id,elem_len;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305352
Jeff Johnson295189b2012-06-20 16:38:30 -07005353 while(left >= 2)
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305354 {
Jeff Johnson295189b2012-06-20 16:38:30 -07005355 elem_id = ptr[0];
5356 elem_len = ptr[1];
5357 left -= 2;
5358 if(elem_len > left)
5359 {
5360 hddLog(VOS_TRACE_LEVEL_FATAL,
Madan Mohan Koyyalamudi8bdd3112012-09-24 13:55:14 -07005361 FL("****Invalid IEs eid = %d elem_len=%d left=%d*****"),
Jeff Johnson295189b2012-06-20 16:38:30 -07005362 eid,elem_len,left);
5363 return NULL;
5364 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305365 if (elem_id == eid)
Jeff Johnson295189b2012-06-20 16:38:30 -07005366 {
5367 return ptr;
5368 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305369
Jeff Johnson295189b2012-06-20 16:38:30 -07005370 left -= elem_len;
5371 ptr += (elem_len + 2);
5372 }
5373 return NULL;
5374}
5375
Jeff Johnson295189b2012-06-20 16:38:30 -07005376/* Check if rate is 11g rate or not */
5377static int wlan_hdd_rate_is_11g(u8 rate)
5378{
Sanjay Devnani28322e22013-06-21 16:13:40 -07005379 static const u8 gRateArray[8] = {12, 18, 24, 36, 48, 72, 96, 108}; /* actual rate * 2 */
Jeff Johnson295189b2012-06-20 16:38:30 -07005380 u8 i;
5381 for (i = 0; i < 8; i++)
5382 {
5383 if(rate == gRateArray[i])
5384 return TRUE;
5385 }
5386 return FALSE;
5387}
5388
5389/* Check for 11g rate and set proper 11g only mode */
5390static void wlan_hdd_check_11gmode(u8 *pIe, u8* require_ht,
5391 u8* pCheckRatesfor11g, eSapPhyMode* pSapHw_mode)
5392{
5393 u8 i, num_rates = pIe[0];
5394
5395 pIe += 1;
5396 for ( i = 0; i < num_rates; i++)
5397 {
5398 if( *pCheckRatesfor11g && (TRUE == wlan_hdd_rate_is_11g(pIe[i] & RATE_MASK)))
5399 {
5400 /* If rate set have 11g rate than change the mode to 11G */
5401 *pSapHw_mode = eSAP_DOT11_MODE_11g;
5402 if (pIe[i] & BASIC_RATE_MASK)
5403 {
5404 /* If we have 11g rate as basic rate, it means mode
5405 is 11g only mode.
5406 */
5407 *pSapHw_mode = eSAP_DOT11_MODE_11g_ONLY;
5408 *pCheckRatesfor11g = FALSE;
5409 }
5410 }
5411 else if((BASIC_RATE_MASK | WLAN_BSS_MEMBERSHIP_SELECTOR_HT_PHY) == pIe[i])
5412 {
5413 *require_ht = TRUE;
5414 }
5415 }
5416 return;
5417}
5418
5419static void wlan_hdd_set_sapHwmode(hdd_adapter_t *pHostapdAdapter)
5420{
5421 tsap_Config_t *pConfig = &pHostapdAdapter->sessionCtx.ap.sapConfig;
5422 beacon_data_t *pBeacon = pHostapdAdapter->sessionCtx.ap.beacon;
5423 struct ieee80211_mgmt *pMgmt_frame = (struct ieee80211_mgmt*)pBeacon->head;
5424 u8 checkRatesfor11g = TRUE;
5425 u8 require_ht = FALSE;
5426 u8 *pIe=NULL;
5427
5428 pConfig->SapHw_mode= eSAP_DOT11_MODE_11b;
5429
5430 pIe = wlan_hdd_cfg80211_get_ie_ptr(&pMgmt_frame->u.beacon.variable[0],
5431 pBeacon->head_len, WLAN_EID_SUPP_RATES);
5432 if (pIe != NULL)
5433 {
5434 pIe += 1;
5435 wlan_hdd_check_11gmode(pIe, &require_ht, &checkRatesfor11g,
5436 &pConfig->SapHw_mode);
5437 }
5438
5439 pIe = wlan_hdd_cfg80211_get_ie_ptr(pBeacon->tail, pBeacon->tail_len,
5440 WLAN_EID_EXT_SUPP_RATES);
5441 if (pIe != NULL)
5442 {
5443
5444 pIe += 1;
5445 wlan_hdd_check_11gmode(pIe, &require_ht, &checkRatesfor11g,
5446 &pConfig->SapHw_mode);
5447 }
5448
5449 if( pConfig->channel > 14 )
5450 {
5451 pConfig->SapHw_mode= eSAP_DOT11_MODE_11a;
5452 }
5453
5454 pIe = wlan_hdd_cfg80211_get_ie_ptr(pBeacon->tail, pBeacon->tail_len,
5455 WLAN_EID_HT_CAPABILITY);
5456
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305457 if(pIe)
Jeff Johnson295189b2012-06-20 16:38:30 -07005458 {
5459 pConfig->SapHw_mode= eSAP_DOT11_MODE_11n;
5460 if(require_ht)
5461 pConfig->SapHw_mode= eSAP_DOT11_MODE_11n_ONLY;
5462 }
5463}
5464
Gopichand Nakkala2b25f4e2013-03-21 19:14:07 +05305465static int wlan_hdd_add_ie(hdd_adapter_t* pHostapdAdapter, v_U8_t *genie,
5466 v_U8_t *total_ielen, v_U8_t *oui, v_U8_t oui_size)
5467{
Arif Hussaine7f3ea52013-09-12 21:56:36 -07005468 v_U16_t ielen = 0;
Gopichand Nakkala2b25f4e2013-03-21 19:14:07 +05305469 v_U8_t *pIe = NULL;
5470 beacon_data_t *pBeacon = pHostapdAdapter->sessionCtx.ap.beacon;
5471
5472 pIe = wlan_hdd_get_vendor_oui_ie_ptr(oui, oui_size,
5473 pBeacon->tail, pBeacon->tail_len);
5474
5475 if (pIe)
5476 {
5477 ielen = pIe[1] + 2;
5478 if ((*total_ielen + ielen) <= MAX_GENIE_LEN)
5479 {
5480 vos_mem_copy(&genie[*total_ielen], pIe, ielen);
5481 }
5482 else
5483 {
5484 hddLog( VOS_TRACE_LEVEL_ERROR, "**Ie Length is too big***");
5485 return -EINVAL;
5486 }
5487 *total_ielen += ielen;
5488 }
5489 return 0;
5490}
5491
Arif Hussaine7f3ea52013-09-12 21:56:36 -07005492static void wlan_hdd_add_hostapd_conf_vsie(hdd_adapter_t* pHostapdAdapter,
5493 v_U8_t *genie, v_U8_t *total_ielen)
5494{
5495 beacon_data_t *pBeacon = pHostapdAdapter->sessionCtx.ap.beacon;
5496 int left = pBeacon->tail_len;
5497 v_U8_t *ptr = pBeacon->tail;
5498 v_U8_t elem_id, elem_len;
5499 v_U16_t ielen = 0;
5500
5501 if ( NULL == ptr || 0 == left )
5502 return;
5503
5504 while (left >= 2)
5505 {
5506 elem_id = ptr[0];
5507 elem_len = ptr[1];
5508 left -= 2;
5509 if (elem_len > left)
5510 {
5511 hddLog( VOS_TRACE_LEVEL_ERROR,
5512 "****Invalid IEs eid = %d elem_len=%d left=%d*****",
5513 elem_id, elem_len, left);
5514 return;
5515 }
5516 if (IE_EID_VENDOR == elem_id)
5517 {
5518 /* skipping the VSIE's which we don't want to include or
5519 * it will be included by existing code
5520 */
5521 if ((memcmp( &ptr[2], WPS_OUI_TYPE, WPS_OUI_TYPE_SIZE) != 0 ) &&
5522#ifdef WLAN_FEATURE_WFD
5523 (memcmp( &ptr[2], WFD_OUI_TYPE, WFD_OUI_TYPE_SIZE) != 0) &&
5524#endif
5525 (memcmp( &ptr[2], WHITELIST_OUI_TYPE, WPA_OUI_TYPE_SIZE) != 0) &&
5526 (memcmp( &ptr[2], BLACKLIST_OUI_TYPE, WPA_OUI_TYPE_SIZE) != 0) &&
5527 (memcmp( &ptr[2], "\x00\x50\xf2\x02", WPA_OUI_TYPE_SIZE) != 0) &&
5528 (memcmp( &ptr[2], WPA_OUI_TYPE, WPA_OUI_TYPE_SIZE) != 0) &&
5529 (memcmp( &ptr[2], P2P_OUI_TYPE, P2P_OUI_TYPE_SIZE) != 0))
5530 {
5531 ielen = ptr[1] + 2;
5532 if ((*total_ielen + ielen) <= MAX_GENIE_LEN)
5533 {
5534 vos_mem_copy(&genie[*total_ielen], ptr, ielen);
5535 *total_ielen += ielen;
5536 }
5537 else
5538 {
5539 hddLog( VOS_TRACE_LEVEL_ERROR,
5540 "IE Length is too big "
5541 "IEs eid=%d elem_len=%d total_ie_lent=%d",
5542 elem_id, elem_len, *total_ielen);
5543 }
5544 }
5545 }
5546
5547 left -= elem_len;
5548 ptr += (elem_len + 2);
5549 }
5550 return;
5551}
5552
Jeff Johnson04dd8a82012-06-29 20:41:40 -07005553#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,4,0))
Jeff Johnson295189b2012-06-20 16:38:30 -07005554static int wlan_hdd_cfg80211_update_apies(hdd_adapter_t* pHostapdAdapter,
5555 struct beacon_parameters *params)
Jeff Johnson04dd8a82012-06-29 20:41:40 -07005556#else
5557static int wlan_hdd_cfg80211_update_apies(hdd_adapter_t* pHostapdAdapter,
5558 struct cfg80211_beacon_data *params)
5559#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07005560{
5561 v_U8_t *genie;
Gopichand Nakkala2b25f4e2013-03-21 19:14:07 +05305562 v_U8_t total_ielen = 0;
Jeff Johnson295189b2012-06-20 16:38:30 -07005563 v_U8_t addIE[1] = {0};
Jeff Johnsone7245742012-09-05 17:12:55 -07005564 int ret = 0;
Jeff Johnson295189b2012-06-20 16:38:30 -07005565
5566 genie = vos_mem_malloc(MAX_GENIE_LEN);
5567
5568 if(genie == NULL) {
5569
5570 return -ENOMEM;
5571 }
5572
Gopichand Nakkala2b25f4e2013-03-21 19:14:07 +05305573 if (0 != wlan_hdd_add_ie(pHostapdAdapter, genie,
5574 &total_ielen, WPS_OUI_TYPE, WPS_OUI_TYPE_SIZE))
Jeff Johnson295189b2012-06-20 16:38:30 -07005575 {
c_hpothu6ff1c3c2013-10-01 19:01:57 +05305576 hddLog(LOGE,
5577 FL("Adding WPS IE failed"));
Gopichand Nakkala2b25f4e2013-03-21 19:14:07 +05305578 ret = -EINVAL;
5579 goto done;
Jeff Johnson295189b2012-06-20 16:38:30 -07005580 }
5581
5582#ifdef WLAN_FEATURE_WFD
Gopichand Nakkala2b25f4e2013-03-21 19:14:07 +05305583 if (0 != wlan_hdd_add_ie(pHostapdAdapter, genie,
5584 &total_ielen, WFD_OUI_TYPE, WFD_OUI_TYPE_SIZE))
5585 {
c_hpothu6ff1c3c2013-10-01 19:01:57 +05305586 hddLog(LOGE,
5587 FL("Adding WFD IE failed"));
Gopichand Nakkala2b25f4e2013-03-21 19:14:07 +05305588 ret = -EINVAL;
5589 goto done;
Jeff Johnson295189b2012-06-20 16:38:30 -07005590 }
5591#endif
5592
Gopichand Nakkala2b25f4e2013-03-21 19:14:07 +05305593 if (0 != wlan_hdd_add_ie(pHostapdAdapter, genie,
5594 &total_ielen, P2P_OUI_TYPE, P2P_OUI_TYPE_SIZE))
Jeff Johnson295189b2012-06-20 16:38:30 -07005595 {
c_hpothu6ff1c3c2013-10-01 19:01:57 +05305596 hddLog(LOGE,
5597 FL("Adding P2P IE failed"));
Gopichand Nakkala2b25f4e2013-03-21 19:14:07 +05305598 ret = -EINVAL;
5599 goto done;
5600 }
5601
5602 if (WLAN_HDD_SOFTAP == pHostapdAdapter->device_mode)
5603 {
Arif Hussaine7f3ea52013-09-12 21:56:36 -07005604 wlan_hdd_add_hostapd_conf_vsie(pHostapdAdapter, genie, &total_ielen);
Jeff Johnson295189b2012-06-20 16:38:30 -07005605 }
Jeff Johnson295189b2012-06-20 16:38:30 -07005606
5607 if (ccmCfgSetStr((WLAN_HDD_GET_CTX(pHostapdAdapter))->hHal,
5608 WNI_CFG_PROBE_RSP_BCN_ADDNIE_DATA, genie, total_ielen, NULL,
5609 eANI_BOOLEAN_FALSE)==eHAL_STATUS_FAILURE)
5610 {
5611 hddLog(LOGE,
5612 "Could not pass on WNI_CFG_PROBE_RSP_BCN_ADDNIE_DATA to CCM");
Jeff Johnsone7245742012-09-05 17:12:55 -07005613 ret = -EINVAL;
5614 goto done;
Jeff Johnson295189b2012-06-20 16:38:30 -07005615 }
5616
5617 if (ccmCfgSetInt((WLAN_HDD_GET_CTX(pHostapdAdapter))->hHal,
5618 WNI_CFG_PROBE_RSP_BCN_ADDNIE_FLAG, 1,NULL,
5619 test_bit(SOFTAP_BSS_STARTED, &pHostapdAdapter->event_flags) ?
5620 eANI_BOOLEAN_TRUE : eANI_BOOLEAN_FALSE)
5621 ==eHAL_STATUS_FAILURE)
5622 {
5623 hddLog(LOGE,
5624 "Could not pass on WNI_CFG_PROBE_RSP_BCN_ADDNIE_FLAG to CCM");
Jeff Johnsone7245742012-09-05 17:12:55 -07005625 ret = -EINVAL;
5626 goto done;
Jeff Johnson295189b2012-06-20 16:38:30 -07005627 }
5628
5629 // Added for ProResp IE
5630 if ( (params->proberesp_ies != NULL) && (params->proberesp_ies_len != 0) )
5631 {
5632 u16 rem_probe_resp_ie_len = params->proberesp_ies_len;
5633 u8 probe_rsp_ie_len[3] = {0};
5634 u8 counter = 0;
5635 /* Check Probe Resp Length if it is greater then 255 then Store
5636 Probe Resp IEs into WNI_CFG_PROBE_RSP_ADDNIE_DATA1 &
5637 WNI_CFG_PROBE_RSP_ADDNIE_DATA2 CFG Variable As We are not able
5638 Store More then 255 bytes into One Variable.
5639 */
5640 while ((rem_probe_resp_ie_len > 0) && (counter < 3))
5641 {
5642 if (rem_probe_resp_ie_len > MAX_CFG_STRING_LEN)
5643 {
5644 probe_rsp_ie_len[counter++] = MAX_CFG_STRING_LEN;
5645 rem_probe_resp_ie_len -= MAX_CFG_STRING_LEN;
5646 }
5647 else
5648 {
5649 probe_rsp_ie_len[counter++] = rem_probe_resp_ie_len;
5650 rem_probe_resp_ie_len = 0;
5651 }
5652 }
5653
5654 rem_probe_resp_ie_len = 0;
5655
5656 if (probe_rsp_ie_len[0] > 0)
5657 {
5658 if (ccmCfgSetStr((WLAN_HDD_GET_CTX(pHostapdAdapter))->hHal,
5659 WNI_CFG_PROBE_RSP_ADDNIE_DATA1,
5660 (tANI_U8*)&params->proberesp_ies[rem_probe_resp_ie_len],
5661 probe_rsp_ie_len[0], NULL,
5662 eANI_BOOLEAN_FALSE) == eHAL_STATUS_FAILURE)
5663 {
5664 hddLog(LOGE,
5665 "Could not pass on WNI_CFG_PROBE_RSP_ADDNIE_DATA1 to CCM");
Jeff Johnsone7245742012-09-05 17:12:55 -07005666 ret = -EINVAL;
5667 goto done;
Jeff Johnson295189b2012-06-20 16:38:30 -07005668 }
5669 rem_probe_resp_ie_len += probe_rsp_ie_len[0];
5670 }
5671
5672 if (probe_rsp_ie_len[1] > 0)
5673 {
5674 if (ccmCfgSetStr((WLAN_HDD_GET_CTX(pHostapdAdapter))->hHal,
5675 WNI_CFG_PROBE_RSP_ADDNIE_DATA2,
5676 (tANI_U8*)&params->proberesp_ies[rem_probe_resp_ie_len],
5677 probe_rsp_ie_len[1], NULL,
5678 eANI_BOOLEAN_FALSE) == eHAL_STATUS_FAILURE)
5679 {
5680 hddLog(LOGE,
5681 "Could not pass on WNI_CFG_PROBE_RSP_ADDNIE_DATA2 to CCM");
Jeff Johnsone7245742012-09-05 17:12:55 -07005682 ret = -EINVAL;
5683 goto done;
Jeff Johnson295189b2012-06-20 16:38:30 -07005684 }
5685 rem_probe_resp_ie_len += probe_rsp_ie_len[1];
5686 }
5687
5688 if (probe_rsp_ie_len[2] > 0)
5689 {
5690 if (ccmCfgSetStr((WLAN_HDD_GET_CTX(pHostapdAdapter))->hHal,
5691 WNI_CFG_PROBE_RSP_ADDNIE_DATA3,
5692 (tANI_U8*)&params->proberesp_ies[rem_probe_resp_ie_len],
5693 probe_rsp_ie_len[2], NULL,
5694 eANI_BOOLEAN_FALSE) == eHAL_STATUS_FAILURE)
5695 {
5696 hddLog(LOGE,
5697 "Could not pass on WNI_CFG_PROBE_RSP_ADDNIE_DATA3 to CCM");
Jeff Johnsone7245742012-09-05 17:12:55 -07005698 ret = -EINVAL;
5699 goto done;
Jeff Johnson295189b2012-06-20 16:38:30 -07005700 }
5701 rem_probe_resp_ie_len += probe_rsp_ie_len[2];
5702 }
5703
5704 if (probe_rsp_ie_len[1] == 0 )
5705 {
5706 if ( eHAL_STATUS_FAILURE == ccmCfgSetStr((WLAN_HDD_GET_CTX(pHostapdAdapter))->hHal,
5707 WNI_CFG_PROBE_RSP_ADDNIE_DATA2, (tANI_U8*)addIE, 0, NULL,
5708 eANI_BOOLEAN_FALSE) )
5709 {
5710 hddLog(LOGE,
Arif Hussain6d2a3322013-11-17 19:50:10 -08005711 "Could not pass on WNI_CFG_PROBE_RSP_ADDNIE_DATA2 to CCM");
Jeff Johnson295189b2012-06-20 16:38:30 -07005712 }
5713 }
5714
5715 if (probe_rsp_ie_len[2] == 0 )
5716 {
5717 if ( eHAL_STATUS_FAILURE == ccmCfgSetStr((WLAN_HDD_GET_CTX(pHostapdAdapter))->hHal,
5718 WNI_CFG_PROBE_RSP_ADDNIE_DATA3, (tANI_U8*)addIE, 0, NULL,
5719 eANI_BOOLEAN_FALSE) )
5720 {
5721 hddLog(LOGE,
Arif Hussain6d2a3322013-11-17 19:50:10 -08005722 "Could not pass on WNI_CFG_PROBE_RSP_ADDNIE_DATA3 to CCM");
Jeff Johnson295189b2012-06-20 16:38:30 -07005723 }
5724 }
5725
5726 if (ccmCfgSetInt((WLAN_HDD_GET_CTX(pHostapdAdapter))->hHal,
5727 WNI_CFG_PROBE_RSP_ADDNIE_FLAG, 1,NULL,
5728 test_bit(SOFTAP_BSS_STARTED, &pHostapdAdapter->event_flags) ?
5729 eANI_BOOLEAN_TRUE : eANI_BOOLEAN_FALSE)
5730 == eHAL_STATUS_FAILURE)
5731 {
5732 hddLog(LOGE,
5733 "Could not pass on WNI_CFG_PROBE_RSP_ADDNIE_FLAG to CCM");
Jeff Johnsone7245742012-09-05 17:12:55 -07005734 ret = -EINVAL;
5735 goto done;
Jeff Johnson295189b2012-06-20 16:38:30 -07005736 }
5737 }
5738 else
5739 {
5740 // Reset WNI_CFG_PROBE_RSP Flags
5741 wlan_hdd_reset_prob_rspies(pHostapdAdapter);
5742
5743 hddLog(VOS_TRACE_LEVEL_INFO,
5744 "%s: No Probe Response IE received in set beacon",
5745 __func__);
5746 }
5747
5748 // Added for AssocResp IE
5749 if ( (params->assocresp_ies != NULL) && (params->assocresp_ies_len != 0) )
5750 {
5751 if (ccmCfgSetStr((WLAN_HDD_GET_CTX(pHostapdAdapter))->hHal,
5752 WNI_CFG_ASSOC_RSP_ADDNIE_DATA, (tANI_U8*)params->assocresp_ies,
5753 params->assocresp_ies_len, NULL,
5754 eANI_BOOLEAN_FALSE) == eHAL_STATUS_FAILURE)
5755 {
5756 hddLog(LOGE,
5757 "Could not pass on WNI_CFG_ASSOC_RSP_ADDNIE_DATA to CCM");
Jeff Johnsone7245742012-09-05 17:12:55 -07005758 ret = -EINVAL;
5759 goto done;
Jeff Johnson295189b2012-06-20 16:38:30 -07005760 }
5761
5762 if (ccmCfgSetInt((WLAN_HDD_GET_CTX(pHostapdAdapter))->hHal,
5763 WNI_CFG_ASSOC_RSP_ADDNIE_FLAG, 1, NULL,
5764 test_bit(SOFTAP_BSS_STARTED, &pHostapdAdapter->event_flags) ?
5765 eANI_BOOLEAN_TRUE : eANI_BOOLEAN_FALSE)
5766 == eHAL_STATUS_FAILURE)
5767 {
5768 hddLog(LOGE,
5769 "Could not pass on WNI_CFG_ASSOC_RSP_ADDNIE_FLAG to CCM");
Jeff Johnsone7245742012-09-05 17:12:55 -07005770 ret = -EINVAL;
5771 goto done;
Jeff Johnson295189b2012-06-20 16:38:30 -07005772 }
5773 }
5774 else
5775 {
5776 hddLog(VOS_TRACE_LEVEL_INFO,
5777 "%s: No Assoc Response IE received in set beacon",
5778 __func__);
5779
5780 if ( eHAL_STATUS_FAILURE == ccmCfgSetInt((WLAN_HDD_GET_CTX(pHostapdAdapter))->hHal,
5781 WNI_CFG_ASSOC_RSP_ADDNIE_FLAG, 0, NULL,
5782 eANI_BOOLEAN_FALSE) )
5783 {
5784 hddLog(LOGE,
Arif Hussain6d2a3322013-11-17 19:50:10 -08005785 "Could not pass on WNI_CFG_ASSOC_RSP_ADDNIE_FLAG to CCM");
Jeff Johnson295189b2012-06-20 16:38:30 -07005786 }
5787 }
5788
Jeff Johnsone7245742012-09-05 17:12:55 -07005789done:
Jeff Johnson295189b2012-06-20 16:38:30 -07005790 vos_mem_free(genie);
Gopichand Nakkala2b25f4e2013-03-21 19:14:07 +05305791 return ret;
Jeff Johnson295189b2012-06-20 16:38:30 -07005792}
Jeff Johnson295189b2012-06-20 16:38:30 -07005793
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305794/*
Jeff Johnson295189b2012-06-20 16:38:30 -07005795 * FUNCTION: wlan_hdd_validate_operation_channel
5796 * called by wlan_hdd_cfg80211_start_bss() and
5797 * wlan_hdd_cfg80211_set_channel()
5798 * This function validates whether given channel is part of valid
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305799 * channel list.
5800 */
Varun Reddy Yeturu920df212013-05-22 08:07:23 -07005801VOS_STATUS wlan_hdd_validate_operation_channel(hdd_adapter_t *pAdapter,int channel)
Jeff Johnson295189b2012-06-20 16:38:30 -07005802{
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305803
Jeff Johnson295189b2012-06-20 16:38:30 -07005804 v_U32_t num_ch = 0;
5805 u8 valid_ch[WNI_CFG_VALID_CHANNEL_LIST_LEN];
5806 u32 indx = 0;
5807 tHalHandle hHal = WLAN_HDD_GET_HAL_CTX(pAdapter);
Madan Mohan Koyylamudi64267f72013-02-05 14:07:08 +05305808 v_U8_t fValidChannel = FALSE, count = 0;
5809 hdd_config_t *hdd_pConfig_ini= (WLAN_HDD_GET_CTX(pAdapter))->cfg_ini;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305810
Jeff Johnson295189b2012-06-20 16:38:30 -07005811 num_ch = WNI_CFG_VALID_CHANNEL_LIST_LEN;
5812
Madan Mohan Koyylamudi64267f72013-02-05 14:07:08 +05305813 if ( hdd_pConfig_ini->sapAllowAllChannel)
Jeff Johnson295189b2012-06-20 16:38:30 -07005814 {
Madan Mohan Koyylamudi64267f72013-02-05 14:07:08 +05305815 /* Validate the channel */
5816 for (count = RF_CHAN_1 ; count <= RF_CHAN_165 ; count++)
Jeff Johnson295189b2012-06-20 16:38:30 -07005817 {
Madan Mohan Koyylamudi64267f72013-02-05 14:07:08 +05305818 if ( channel == rfChannels[count].channelNum )
5819 {
5820 fValidChannel = TRUE;
5821 break;
5822 }
5823 }
5824 if (fValidChannel != TRUE)
5825 {
5826 hddLog(VOS_TRACE_LEVEL_ERROR,
5827 "%s: Invalid Channel [%d]", __func__, channel);
5828 return VOS_STATUS_E_FAILURE;
Jeff Johnson295189b2012-06-20 16:38:30 -07005829 }
5830 }
Madan Mohan Koyylamudi64267f72013-02-05 14:07:08 +05305831 else
Jeff Johnson295189b2012-06-20 16:38:30 -07005832 {
Madan Mohan Koyylamudi64267f72013-02-05 14:07:08 +05305833 if (0 != ccmCfgGetStr(hHal, WNI_CFG_VALID_CHANNEL_LIST,
5834 valid_ch, &num_ch))
5835 {
5836 hddLog(VOS_TRACE_LEVEL_ERROR,
5837 "%s: failed to get valid channel list", __func__);
5838 return VOS_STATUS_E_FAILURE;
5839 }
5840 for (indx = 0; indx < num_ch; indx++)
5841 {
5842 if (channel == valid_ch[indx])
5843 {
5844 break;
5845 }
5846 }
5847
Rashmi Ramanna3b59e122014-04-10 14:45:13 +05305848 if (indx >= num_ch)
5849 {
5850 if (WLAN_HDD_P2P_GO == pAdapter->device_mode)
5851 {
5852 eCsrBand band;
5853 unsigned int freq;
5854
5855 sme_GetFreqBand(hHal, &band);
5856
5857 if (eCSR_BAND_5G == band)
5858 {
5859#if (LINUX_VERSION_CODE > KERNEL_VERSION(2,6,38))
5860 if (channel <= ARRAY_SIZE(hdd_channels_2_4_GHZ))
5861 {
5862 freq = ieee80211_channel_to_frequency(channel,
5863 IEEE80211_BAND_2GHZ);
5864 }
5865 else
5866 {
5867 freq = ieee80211_channel_to_frequency(channel,
5868 IEEE80211_BAND_5GHZ);
5869 }
5870#else
5871 freq = ieee80211_channel_to_frequency(channel);
5872#endif
5873 if(WLAN_HDD_IS_SOCIAL_CHANNEL(freq))
5874 return VOS_STATUS_SUCCESS;
5875 }
5876 }
5877
5878 hddLog(VOS_TRACE_LEVEL_ERROR,
5879 "%s: Invalid Channel [%d]", __func__, channel);
5880 return VOS_STATUS_E_FAILURE;
5881 }
Jeff Johnson295189b2012-06-20 16:38:30 -07005882 }
Rashmi Ramanna3b59e122014-04-10 14:45:13 +05305883
Jeff Johnson295189b2012-06-20 16:38:30 -07005884 return VOS_STATUS_SUCCESS;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305885
Jeff Johnson295189b2012-06-20 16:38:30 -07005886}
5887
Viral Modi3a32cc52013-02-08 11:14:52 -08005888/**
5889 * FUNCTION: wlan_hdd_cfg80211_set_channel
5890 * This function is used to set the channel number
5891 */
5892static int wlan_hdd_cfg80211_set_channel( struct wiphy *wiphy, struct net_device *dev,
5893 struct ieee80211_channel *chan,
5894 enum nl80211_channel_type channel_type
5895 )
5896{
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05305897 hdd_adapter_t *pAdapter = NULL;
Viral Modi3a32cc52013-02-08 11:14:52 -08005898 v_U32_t num_ch = 0;
Jeff Johnson4416a782013-03-25 14:17:50 -07005899 int channel = 0;
Viral Modi3a32cc52013-02-08 11:14:52 -08005900 int freq = chan->center_freq; /* freq is in MHZ */
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05305901 hdd_context_t *pHddCtx;
5902 int status;
Viral Modi3a32cc52013-02-08 11:14:52 -08005903
5904 ENTER();
5905
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05305906
Viral Modi3a32cc52013-02-08 11:14:52 -08005907 if( NULL == dev )
5908 {
5909 hddLog(VOS_TRACE_LEVEL_ERROR,
Arif Hussain6d2a3322013-11-17 19:50:10 -08005910 "%s: Called with dev = NULL.", __func__);
Viral Modi3a32cc52013-02-08 11:14:52 -08005911 return -ENODEV;
5912 }
5913 pAdapter = WLAN_HDD_GET_PRIV_PTR( dev );
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +05305914
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05305915 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
5916 TRACE_CODE_HDD_CFG80211_SET_CHANNEL, pAdapter->sessionId,
5917 channel_type ));
Viral Modi3a32cc52013-02-08 11:14:52 -08005918 hddLog(VOS_TRACE_LEVEL_INFO,
Sushant Kaushik8bc7df22014-04-09 17:55:29 +05305919 "%s: device_mode = %s (%d) freq = %d", __func__,
5920 hdd_device_modetoString(pAdapter->device_mode),
5921 pAdapter->device_mode, chan->center_freq);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05305922
5923 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
5924 status = wlan_hdd_validate_context(pHddCtx);
5925
5926 if (0 != status)
Viral Modi3a32cc52013-02-08 11:14:52 -08005927 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05305928 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
5929 "%s: HDD context is not valid", __func__);
5930 return status;
Viral Modi3a32cc52013-02-08 11:14:52 -08005931 }
5932
5933 /*
5934 * Do freq to chan conversion
5935 * TODO: for 11a
5936 */
5937
5938 channel = ieee80211_frequency_to_channel(freq);
5939
5940 /* Check freq range */
5941 if ((WNI_CFG_CURRENT_CHANNEL_STAMIN > channel) ||
5942 (WNI_CFG_CURRENT_CHANNEL_STAMAX < channel))
5943 {
5944 hddLog(VOS_TRACE_LEVEL_ERROR,
Arif Hussain6d2a3322013-11-17 19:50:10 -08005945 "%s: Channel [%d] is outside valid range from %d to %d",
Viral Modi3a32cc52013-02-08 11:14:52 -08005946 __func__, channel, WNI_CFG_CURRENT_CHANNEL_STAMIN,
5947 WNI_CFG_CURRENT_CHANNEL_STAMAX);
5948 return -EINVAL;
5949 }
5950
5951 num_ch = WNI_CFG_VALID_CHANNEL_LIST_LEN;
5952
Gopichand Nakkala6ab19562013-03-07 13:59:42 +05305953 if ((WLAN_HDD_SOFTAP != pAdapter->device_mode) &&
5954 (WLAN_HDD_P2P_GO != pAdapter->device_mode))
Viral Modi3a32cc52013-02-08 11:14:52 -08005955 {
5956 if(VOS_STATUS_SUCCESS != wlan_hdd_validate_operation_channel(pAdapter,channel))
5957 {
5958 hddLog(VOS_TRACE_LEVEL_ERROR,
Arif Hussain6d2a3322013-11-17 19:50:10 -08005959 "%s: Invalid Channel [%d]", __func__, channel);
Viral Modi3a32cc52013-02-08 11:14:52 -08005960 return -EINVAL;
5961 }
5962 hddLog(VOS_TRACE_LEVEL_INFO_HIGH,
5963 "%s: set channel to [%d] for device mode =%d",
5964 __func__, channel,pAdapter->device_mode);
5965 }
5966 if( (pAdapter->device_mode == WLAN_HDD_INFRA_STATION)
Viral Modi3a32cc52013-02-08 11:14:52 -08005967 || (pAdapter->device_mode == WLAN_HDD_P2P_CLIENT)
Viral Modi3a32cc52013-02-08 11:14:52 -08005968 )
5969 {
5970 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
5971 tCsrRoamProfile * pRoamProfile = &pWextState->roamProfile;
5972 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
5973
5974 if (eConnectionState_IbssConnected == pHddStaCtx->conn_info.connState)
5975 {
5976 /* Link is up then return cant set channel*/
5977 hddLog( VOS_TRACE_LEVEL_ERROR,
Arif Hussain6d2a3322013-11-17 19:50:10 -08005978 "%s: IBSS Associated, can't set the channel", __func__);
Viral Modi3a32cc52013-02-08 11:14:52 -08005979 return -EINVAL;
5980 }
5981
5982 num_ch = pRoamProfile->ChannelInfo.numOfChannels = 1;
5983 pHddStaCtx->conn_info.operationChannel = channel;
5984 pRoamProfile->ChannelInfo.ChannelList =
5985 &pHddStaCtx->conn_info.operationChannel;
5986 }
5987 else if ((pAdapter->device_mode == WLAN_HDD_SOFTAP)
Viral Modi3a32cc52013-02-08 11:14:52 -08005988 || (pAdapter->device_mode == WLAN_HDD_P2P_GO)
Viral Modi3a32cc52013-02-08 11:14:52 -08005989 )
5990 {
Gopichand Nakkalac8fa7b62013-03-11 13:56:41 +05305991 if (WLAN_HDD_P2P_GO == pAdapter->device_mode)
5992 {
5993 if(VOS_STATUS_SUCCESS !=
5994 wlan_hdd_validate_operation_channel(pAdapter,channel))
5995 {
5996 hddLog(VOS_TRACE_LEVEL_ERROR,
Arif Hussain6d2a3322013-11-17 19:50:10 -08005997 "%s: Invalid Channel [%d]", __func__, channel);
Gopichand Nakkalac8fa7b62013-03-11 13:56:41 +05305998 return -EINVAL;
5999 }
6000 (WLAN_HDD_GET_AP_CTX_PTR(pAdapter))->sapConfig.channel = channel;
6001 }
6002 else if ( WLAN_HDD_SOFTAP == pAdapter->device_mode )
Viral Modi3a32cc52013-02-08 11:14:52 -08006003 {
6004 hdd_config_t *cfg_param = (WLAN_HDD_GET_CTX(pAdapter))->cfg_ini;
6005
6006 /* If auto channel selection is configured as enable/ 1 then ignore
6007 channel set by supplicant
6008 */
6009 if ( cfg_param->apAutoChannelSelection )
6010 {
Gopichand Nakkalac8fa7b62013-03-11 13:56:41 +05306011 (WLAN_HDD_GET_AP_CTX_PTR(pAdapter))->sapConfig.channel =
6012 AUTO_CHANNEL_SELECT;
Viral Modi3a32cc52013-02-08 11:14:52 -08006013 hddLog(VOS_TRACE_LEVEL_INFO_HIGH,
Sushant Kaushik8bc7df22014-04-09 17:55:29 +05306014 "%s: set channel to auto channel (0) for device mode =%s (%d)",
6015 __func__, hdd_device_modetoString(pAdapter->device_mode),
6016 pAdapter->device_mode);
Viral Modi3a32cc52013-02-08 11:14:52 -08006017 }
Gopichand Nakkalac8fa7b62013-03-11 13:56:41 +05306018 else
6019 {
6020 if(VOS_STATUS_SUCCESS !=
6021 wlan_hdd_validate_operation_channel(pAdapter,channel))
6022 {
6023 hddLog(VOS_TRACE_LEVEL_ERROR,
Arif Hussain6d2a3322013-11-17 19:50:10 -08006024 "%s: Invalid Channel [%d]", __func__, channel);
Gopichand Nakkalac8fa7b62013-03-11 13:56:41 +05306025 return -EINVAL;
6026 }
6027 (WLAN_HDD_GET_AP_CTX_PTR(pAdapter))->sapConfig.channel = channel;
6028 }
Viral Modi3a32cc52013-02-08 11:14:52 -08006029 }
6030 }
6031 else
6032 {
6033 hddLog(VOS_TRACE_LEVEL_FATAL,
6034 "%s: Invalid device mode failed to set valid channel", __func__);
6035 return -EINVAL;
6036 }
6037 EXIT();
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05306038 return status;
Viral Modi3a32cc52013-02-08 11:14:52 -08006039}
6040
Jeff Johnson295189b2012-06-20 16:38:30 -07006041#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,4,0))
6042static int wlan_hdd_cfg80211_start_bss(hdd_adapter_t *pHostapdAdapter,
6043 struct beacon_parameters *params)
Jeff Johnson04dd8a82012-06-29 20:41:40 -07006044#else
6045static int wlan_hdd_cfg80211_start_bss(hdd_adapter_t *pHostapdAdapter,
6046 struct cfg80211_beacon_data *params,
6047 const u8 *ssid, size_t ssid_len,
6048 enum nl80211_hidden_ssid hidden_ssid)
6049#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07006050{
6051 tsap_Config_t *pConfig;
6052 beacon_data_t *pBeacon = NULL;
6053 struct ieee80211_mgmt *pMgmt_frame;
6054 v_U8_t *pIe=NULL;
6055 v_U16_t capab_info;
6056 eCsrAuthType RSNAuthType;
6057 eCsrEncryptionType RSNEncryptType;
6058 eCsrEncryptionType mcRSNEncryptType;
6059 int status = VOS_STATUS_SUCCESS;
6060 tpWLAN_SAPEventCB pSapEventCallback;
6061 hdd_hostapd_state_t *pHostapdState;
6062 v_U8_t wpaRsnIEdata[(SIR_MAC_MAX_IE_LENGTH * 2)+4]; //Max ie length 255 * 2(WPA+RSN) + 2 bytes (vendor specific ID) * 2
6063 v_CONTEXT_t pVosContext = (WLAN_HDD_GET_CTX(pHostapdAdapter))->pvosContext;
Madan Mohan Koyylamudia16d0202013-02-01 11:05:57 +05306064 tHalHandle hHal = WLAN_HDD_GET_HAL_CTX(pHostapdAdapter);
Jeff Johnson295189b2012-06-20 16:38:30 -07006065 struct qc_mac_acl_entry *acl_entry = NULL;
Siddharth Bhal5cba24e2014-05-08 18:59:39 +05306066 hdd_config_t *iniConfig;
Jeff Johnson295189b2012-06-20 16:38:30 -07006067 v_SINT_t i;
Madan Mohan Koyyalamudi543172b2012-12-05 16:40:18 -08006068 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pHostapdAdapter);
Peng Xu2446a892014-09-05 17:21:18 +05306069 tSmeConfigParams *psmeConfig;
Chet Lanctot40142442014-05-20 13:39:25 -07006070 v_BOOL_t MFPCapable = VOS_FALSE;
6071 v_BOOL_t MFPRequired = VOS_FALSE;
Abhishek Singhf0ac1752014-03-05 17:47:09 +05306072 eHddDot11Mode sapDot11Mode =
6073 (WLAN_HDD_GET_CTX(pHostapdAdapter))->cfg_ini->sapDot11Mode;
Jeff Johnson295189b2012-06-20 16:38:30 -07006074
6075 ENTER();
6076
Siddharth Bhal5cba24e2014-05-08 18:59:39 +05306077 iniConfig = pHddCtx->cfg_ini;
6078
Jeff Johnson295189b2012-06-20 16:38:30 -07006079 pHostapdState = WLAN_HDD_GET_HOSTAP_STATE_PTR(pHostapdAdapter);
6080
6081 pConfig = &pHostapdAdapter->sessionCtx.ap.sapConfig;
6082
6083 pBeacon = pHostapdAdapter->sessionCtx.ap.beacon;
6084
6085 pMgmt_frame = (struct ieee80211_mgmt*)pBeacon->head;
6086
6087 pConfig->beacon_int = pMgmt_frame->u.beacon.beacon_int;
6088
6089 //channel is already set in the set_channel Call back
6090 //pConfig->channel = pCommitConfig->channel;
6091
6092 /*Protection parameter to enable or disable*/
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306093 pConfig->protEnabled =
Jeff Johnson295189b2012-06-20 16:38:30 -07006094 (WLAN_HDD_GET_CTX(pHostapdAdapter))->cfg_ini->apProtEnabled;
6095
6096 pConfig->dtim_period = pBeacon->dtim_period;
6097
Arif Hussain6d2a3322013-11-17 19:50:10 -08006098 hddLog(VOS_TRACE_LEVEL_INFO_HIGH,"****pConfig->dtim_period=%d***",
Jeff Johnson295189b2012-06-20 16:38:30 -07006099 pConfig->dtim_period);
6100
Madan Mohan Koyyalamudie0ca11f2012-11-27 15:57:52 -08006101 if (pHostapdAdapter->device_mode == WLAN_HDD_SOFTAP)
Jeff Johnson32d95a32012-09-10 13:15:23 -07006102 {
6103 pIe = wlan_hdd_cfg80211_get_ie_ptr(pBeacon->tail, pBeacon->tail_len,
Jeff Johnson295189b2012-06-20 16:38:30 -07006104 WLAN_EID_COUNTRY);
Kiet Lam083504c2013-11-25 14:17:45 +05306105 if(memcmp(pHddCtx->cfg_ini->apCntryCode, CFG_AP_COUNTRY_CODE_DEFAULT, 3) != 0)
6106 {
6107 tANI_BOOLEAN restartNeeded;
6108 pConfig->ieee80211d = 1;
6109 vos_mem_copy(pConfig->countryCode, pHddCtx->cfg_ini->apCntryCode, 3);
6110 sme_setRegInfo(hHal, pConfig->countryCode);
6111 sme_ResetCountryCodeInformation(hHal, &restartNeeded);
6112 }
6113 else if(pIe)
Jeff Johnson295189b2012-06-20 16:38:30 -07006114 {
Jeff Johnson32d95a32012-09-10 13:15:23 -07006115 tANI_BOOLEAN restartNeeded;
Jeff Johnson32d95a32012-09-10 13:15:23 -07006116 pConfig->ieee80211d = 1;
6117 vos_mem_copy(pConfig->countryCode, &pIe[2], 3);
6118 sme_setRegInfo(hHal, pConfig->countryCode);
6119 sme_ResetCountryCodeInformation(hHal, &restartNeeded);
Jeff Johnson295189b2012-06-20 16:38:30 -07006120 }
Jeff Johnson32d95a32012-09-10 13:15:23 -07006121 else
6122 {
6123 pConfig->ieee80211d = 0;
6124 }
Madan Mohan Koyylamudia16d0202013-02-01 11:05:57 +05306125 /*
6126 * If auto channel is configured i.e. channel is 0,
6127 * so skip channel validation.
6128 */
6129 if( AUTO_CHANNEL_SELECT != pConfig->channel )
6130 {
6131 if(VOS_STATUS_SUCCESS != wlan_hdd_validate_operation_channel(pHostapdAdapter,pConfig->channel))
6132 {
6133 hddLog(VOS_TRACE_LEVEL_ERROR,
Arif Hussain6d2a3322013-11-17 19:50:10 -08006134 "%s: Invalid Channel [%d]", __func__, pConfig->channel);
Madan Mohan Koyylamudia16d0202013-02-01 11:05:57 +05306135 return -EINVAL;
6136 }
6137 }
6138 else
6139 {
6140 if(1 != pHddCtx->is_dynamic_channel_range_set)
6141 {
6142 hdd_config_t *hdd_pConfig= (WLAN_HDD_GET_CTX(pHostapdAdapter))->cfg_ini;
6143 WLANSAP_SetChannelRange(hHal, hdd_pConfig->apStartChannelNum,
6144 hdd_pConfig->apEndChannelNum,hdd_pConfig->apOperatingBand);
6145 }
6146 pHddCtx->is_dynamic_channel_range_set = 0;
6147 }
Jeff Johnson295189b2012-06-20 16:38:30 -07006148 }
Jeff Johnson32d95a32012-09-10 13:15:23 -07006149 else
Jeff Johnson295189b2012-06-20 16:38:30 -07006150 {
6151 pConfig->ieee80211d = 0;
6152 }
6153 pConfig->authType = eSAP_AUTO_SWITCH;
6154
6155 capab_info = pMgmt_frame->u.beacon.capab_info;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306156
6157 pConfig->privacy = (pMgmt_frame->u.beacon.capab_info &
Jeff Johnson295189b2012-06-20 16:38:30 -07006158 WLAN_CAPABILITY_PRIVACY) ? VOS_TRUE : VOS_FALSE;
6159
6160 (WLAN_HDD_GET_AP_CTX_PTR(pHostapdAdapter))->uPrivacy = pConfig->privacy;
6161
6162 /*Set wps station to configured*/
6163 pIe = wlan_hdd_get_wps_ie_ptr(pBeacon->tail, pBeacon->tail_len);
6164
6165 if(pIe)
6166 {
6167 if(pIe[1] < (2 + WPS_OUI_TYPE_SIZE))
6168 {
Arif Hussain6d2a3322013-11-17 19:50:10 -08006169 hddLog( VOS_TRACE_LEVEL_ERROR, "**Wps Ie Length is too small***");
Jeff Johnson295189b2012-06-20 16:38:30 -07006170 return -EINVAL;
6171 }
6172 else if(memcmp(&pIe[2], WPS_OUI_TYPE, WPS_OUI_TYPE_SIZE) == 0)
6173 {
Madan Mohan Koyyalamudi8bdd3112012-09-24 13:55:14 -07006174 hddLog( VOS_TRACE_LEVEL_INFO, "** WPS IE(len %d) ***", (pIe[1]+2));
Jeff Johnson295189b2012-06-20 16:38:30 -07006175 /* Check 15 bit of WPS IE as it contain information for wps state
6176 * WPS state
6177 */
6178 if(SAP_WPS_ENABLED_UNCONFIGURED == pIe[15])
6179 {
6180 pConfig->wps_state = SAP_WPS_ENABLED_UNCONFIGURED;
6181 } else if(SAP_WPS_ENABLED_CONFIGURED == pIe[15])
6182 {
6183 pConfig->wps_state = SAP_WPS_ENABLED_CONFIGURED;
6184 }
6185 }
6186 }
6187 else
6188 {
6189 pConfig->wps_state = SAP_WPS_DISABLED;
6190 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306191 pConfig->fwdWPSPBCProbeReq = 1; // Forward WPS PBC probe request frame up
Jeff Johnson295189b2012-06-20 16:38:30 -07006192
c_hpothufe599e92014-06-16 11:38:55 +05306193 pConfig->RSNEncryptType = eCSR_ENCRYPT_TYPE_NONE;
6194 pConfig->mcRSNEncryptType = eCSR_ENCRYPT_TYPE_NONE;
6195 (WLAN_HDD_GET_AP_CTX_PTR(pHostapdAdapter))->ucEncryptType =
6196 eCSR_ENCRYPT_TYPE_NONE;
6197
Jeff Johnson295189b2012-06-20 16:38:30 -07006198 pConfig->RSNWPAReqIELength = 0;
6199 pConfig->pRSNWPAReqIE = NULL;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306200 pIe = wlan_hdd_cfg80211_get_ie_ptr(pBeacon->tail, pBeacon->tail_len,
Jeff Johnson295189b2012-06-20 16:38:30 -07006201 WLAN_EID_RSN);
6202 if(pIe && pIe[1])
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306203 {
Jeff Johnson295189b2012-06-20 16:38:30 -07006204 pConfig->RSNWPAReqIELength = pIe[1] + 2;
6205 memcpy(&wpaRsnIEdata[0], pIe, pConfig->RSNWPAReqIELength);
6206 pConfig->pRSNWPAReqIE = &wpaRsnIEdata[0];
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306207 /* The actual processing may eventually be more extensive than
6208 * this. Right now, just consume any PMKIDs that are sent in
Jeff Johnson295189b2012-06-20 16:38:30 -07006209 * by the app.
6210 * */
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306211 status = hdd_softap_unpackIE(
Jeff Johnson295189b2012-06-20 16:38:30 -07006212 vos_get_context( VOS_MODULE_ID_SME, pVosContext),
6213 &RSNEncryptType,
6214 &mcRSNEncryptType,
6215 &RSNAuthType,
Chet Lanctot8cecea22014-02-11 19:09:36 -08006216 &MFPCapable,
6217 &MFPRequired,
Jeff Johnson295189b2012-06-20 16:38:30 -07006218 pConfig->pRSNWPAReqIE[1]+2,
6219 pConfig->pRSNWPAReqIE );
6220
6221 if( VOS_STATUS_SUCCESS == status )
6222 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306223 /* Now copy over all the security attributes you have
6224 * parsed out
Jeff Johnson295189b2012-06-20 16:38:30 -07006225 * */
6226 pConfig->RSNEncryptType = RSNEncryptType; // Use the cipher type in the RSN IE
6227 pConfig->mcRSNEncryptType = mcRSNEncryptType;
6228 (WLAN_HDD_GET_AP_CTX_PTR(pHostapdAdapter))->ucEncryptType
6229 = RSNEncryptType;
Gopichand Nakkala66c0bd02013-04-10 11:36:29 +05306230 hddLog( LOG1, FL("CSR AuthType = %d, "
Arif Hussain6d2a3322013-11-17 19:50:10 -08006231 "EncryptionType = %d mcEncryptionType = %d"),
Jeff Johnson295189b2012-06-20 16:38:30 -07006232 RSNAuthType, RSNEncryptType, mcRSNEncryptType);
6233 }
6234 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306235
Jeff Johnson295189b2012-06-20 16:38:30 -07006236 pIe = wlan_hdd_get_vendor_oui_ie_ptr(WPA_OUI_TYPE, WPA_OUI_TYPE_SIZE,
6237 pBeacon->tail, pBeacon->tail_len);
6238
6239 if(pIe && pIe[1] && (pIe[0] == DOT11F_EID_WPA))
6240 {
6241 if (pConfig->pRSNWPAReqIE)
6242 {
6243 /*Mixed mode WPA/WPA2*/
6244 memcpy((&wpaRsnIEdata[0] + pConfig->RSNWPAReqIELength), pIe, pIe[1] + 2);
6245 pConfig->RSNWPAReqIELength += pIe[1] + 2;
6246 }
6247 else
6248 {
6249 pConfig->RSNWPAReqIELength = pIe[1] + 2;
6250 memcpy(&wpaRsnIEdata[0], pIe, pConfig->RSNWPAReqIELength);
6251 pConfig->pRSNWPAReqIE = &wpaRsnIEdata[0];
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306252 status = hdd_softap_unpackIE(
Jeff Johnson295189b2012-06-20 16:38:30 -07006253 vos_get_context( VOS_MODULE_ID_SME, pVosContext),
6254 &RSNEncryptType,
6255 &mcRSNEncryptType,
6256 &RSNAuthType,
Chet Lanctot8cecea22014-02-11 19:09:36 -08006257 &MFPCapable,
6258 &MFPRequired,
Jeff Johnson295189b2012-06-20 16:38:30 -07006259 pConfig->pRSNWPAReqIE[1]+2,
6260 pConfig->pRSNWPAReqIE );
6261
6262 if( VOS_STATUS_SUCCESS == status )
6263 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306264 /* Now copy over all the security attributes you have
6265 * parsed out
Jeff Johnson295189b2012-06-20 16:38:30 -07006266 * */
6267 pConfig->RSNEncryptType = RSNEncryptType; // Use the cipher type in the RSN IE
6268 pConfig->mcRSNEncryptType = mcRSNEncryptType;
6269 (WLAN_HDD_GET_AP_CTX_PTR(pHostapdAdapter))->ucEncryptType
6270 = RSNEncryptType;
Gopichand Nakkala66c0bd02013-04-10 11:36:29 +05306271 hddLog( LOG1, FL("CSR AuthType = %d, "
Arif Hussain6d2a3322013-11-17 19:50:10 -08006272 "EncryptionType = %d mcEncryptionType = %d"),
Jeff Johnson295189b2012-06-20 16:38:30 -07006273 RSNAuthType, RSNEncryptType, mcRSNEncryptType);
6274 }
6275 }
6276 }
6277
Jeff Johnson4416a782013-03-25 14:17:50 -07006278 if (pConfig->RSNWPAReqIELength > sizeof wpaRsnIEdata) {
6279 hddLog( VOS_TRACE_LEVEL_ERROR, "**RSNWPAReqIELength is too large***");
6280 return -EINVAL;
6281 }
6282
Jeff Johnson295189b2012-06-20 16:38:30 -07006283 pConfig->SSIDinfo.ssidHidden = VOS_FALSE;
6284
Jeff Johnson04dd8a82012-06-29 20:41:40 -07006285#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,4,0))
Jeff Johnson295189b2012-06-20 16:38:30 -07006286 if (params->ssid != NULL)
6287 {
6288 memcpy(pConfig->SSIDinfo.ssid.ssId, params->ssid, params->ssid_len);
6289 pConfig->SSIDinfo.ssid.length = params->ssid_len;
6290 if (params->hidden_ssid != NL80211_HIDDEN_SSID_NOT_IN_USE)
6291 pConfig->SSIDinfo.ssidHidden = VOS_TRUE;
6292 }
Jeff Johnson04dd8a82012-06-29 20:41:40 -07006293#else
6294 if (ssid != NULL)
6295 {
6296 memcpy(pConfig->SSIDinfo.ssid.ssId, ssid, ssid_len);
6297 pConfig->SSIDinfo.ssid.length = ssid_len;
6298 if (hidden_ssid != NL80211_HIDDEN_SSID_NOT_IN_USE)
6299 pConfig->SSIDinfo.ssidHidden = VOS_TRUE;
6300 }
6301#endif
6302
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306303 vos_mem_copy(pConfig->self_macaddr.bytes,
Jeff Johnson295189b2012-06-20 16:38:30 -07006304 pHostapdAdapter->macAddressCurrent.bytes, sizeof(v_MACADDR_t));
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306305
Jeff Johnson295189b2012-06-20 16:38:30 -07006306 /* default value */
6307 pConfig->SapMacaddr_acl = eSAP_ACCEPT_UNLESS_DENIED;
6308 pConfig->num_accept_mac = 0;
6309 pConfig->num_deny_mac = 0;
6310
6311 pIe = wlan_hdd_get_vendor_oui_ie_ptr(BLACKLIST_OUI_TYPE, WPA_OUI_TYPE_SIZE,
6312 pBeacon->tail, pBeacon->tail_len);
6313
6314 /* pIe for black list is following form:
6315 type : 1 byte
6316 length : 1 byte
6317 OUI : 4 bytes
6318 acl type : 1 byte
6319 no of mac addr in black list: 1 byte
6320 list of mac_acl_entries: variable, 6 bytes per mac address + sizeof(int) for vlan id
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306321 */
6322 if ((pIe != NULL) && (pIe[1] != 0))
Jeff Johnson295189b2012-06-20 16:38:30 -07006323 {
6324 pConfig->SapMacaddr_acl = pIe[6];
6325 pConfig->num_deny_mac = pIe[7];
Arif Hussain6d2a3322013-11-17 19:50:10 -08006326 hddLog(VOS_TRACE_LEVEL_INFO,"acl type = %d no deny mac = %d",
Jeff Johnson295189b2012-06-20 16:38:30 -07006327 pIe[6], pIe[7]);
Gopichand Nakkalac005b7c2013-05-14 16:04:14 +05306328 if (pConfig->num_deny_mac > MAX_ACL_MAC_ADDRESS)
6329 pConfig->num_deny_mac = MAX_ACL_MAC_ADDRESS;
Jeff Johnson295189b2012-06-20 16:38:30 -07006330 acl_entry = (struct qc_mac_acl_entry *)(pIe + 8);
6331 for (i = 0; i < pConfig->num_deny_mac; i++)
6332 {
6333 vos_mem_copy(&pConfig->deny_mac[i], acl_entry->addr, sizeof(qcmacaddr));
6334 acl_entry++;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306335 }
Jeff Johnson295189b2012-06-20 16:38:30 -07006336 }
6337 pIe = wlan_hdd_get_vendor_oui_ie_ptr(WHITELIST_OUI_TYPE, WPA_OUI_TYPE_SIZE,
6338 pBeacon->tail, pBeacon->tail_len);
6339
6340 /* pIe for white list is following form:
6341 type : 1 byte
6342 length : 1 byte
6343 OUI : 4 bytes
6344 acl type : 1 byte
6345 no of mac addr in white list: 1 byte
6346 list of mac_acl_entries: variable, 6 bytes per mac address + sizeof(int) for vlan id
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306347 */
6348 if ((pIe != NULL) && (pIe[1] != 0))
Jeff Johnson295189b2012-06-20 16:38:30 -07006349 {
6350 pConfig->SapMacaddr_acl = pIe[6];
6351 pConfig->num_accept_mac = pIe[7];
Arif Hussain6d2a3322013-11-17 19:50:10 -08006352 hddLog(VOS_TRACE_LEVEL_INFO,"acl type = %d no accept mac = %d",
Jeff Johnson295189b2012-06-20 16:38:30 -07006353 pIe[6], pIe[7]);
Gopichand Nakkalac005b7c2013-05-14 16:04:14 +05306354 if (pConfig->num_accept_mac > MAX_ACL_MAC_ADDRESS)
6355 pConfig->num_accept_mac = MAX_ACL_MAC_ADDRESS;
Jeff Johnson295189b2012-06-20 16:38:30 -07006356 acl_entry = (struct qc_mac_acl_entry *)(pIe + 8);
6357 for (i = 0; i < pConfig->num_accept_mac; i++)
6358 {
6359 vos_mem_copy(&pConfig->accept_mac[i], acl_entry->addr, sizeof(qcmacaddr));
6360 acl_entry++;
6361 }
6362 }
Gopichand Nakkalac005b7c2013-05-14 16:04:14 +05306363
Jeff Johnson295189b2012-06-20 16:38:30 -07006364 wlan_hdd_set_sapHwmode(pHostapdAdapter);
6365
Jeff Johnsone7245742012-09-05 17:12:55 -07006366#ifdef WLAN_FEATURE_11AC
Ravi Kumar Vaishnavbbaebbe2013-01-15 17:09:48 -08006367 /* Overwrite the hostapd setting for HW mode only for 11ac.
Kiet Lam0f320422013-11-21 19:29:17 +05306368 * This is valid only if mode is set to 11n in hostapd, either AUTO or
6369 * 11ac in .ini and 11ac is supported by both host and firmware.
6370 * Otherwise, leave whatever is set in hostapd (a OR b OR g OR n mode)
6371 */
Ravi Kumar Vaishnavbbaebbe2013-01-15 17:09:48 -08006372 if( ((pConfig->SapHw_mode == eSAP_DOT11_MODE_11n) ||
6373 (pConfig->SapHw_mode == eSAP_DOT11_MODE_11n_ONLY)) &&
Abhishek Singhf0ac1752014-03-05 17:47:09 +05306374 (( sapDot11Mode == eHDD_DOT11_MODE_AUTO ) ||
6375 ( sapDot11Mode == eHDD_DOT11_MODE_11ac ) ||
6376 ( sapDot11Mode == eHDD_DOT11_MODE_11ac_ONLY ) ) &&
6377 (sme_IsFeatureSupportedByDriver(DOT11AC)) &&
6378 (sme_IsFeatureSupportedByFW(DOT11AC)) )
Jeff Johnsone7245742012-09-05 17:12:55 -07006379 {
Siddharth Bhalf42f8592014-05-15 13:39:07 +05306380 v_U32_t operatingBand = 0;
Jeff Johnsone7245742012-09-05 17:12:55 -07006381 pConfig->SapHw_mode = eSAP_DOT11_MODE_11ac;
Siddharth Bhalf42f8592014-05-15 13:39:07 +05306382 ccmCfgGetInt(hHal, WNI_CFG_SAP_CHANNEL_SELECT_OPERATING_BAND, &operatingBand);
Ravi Joshi83bfaa12013-05-28 22:12:08 -07006383
Siddharth Bhal5cba24e2014-05-08 18:59:39 +05306384 /* If ACS disable and selected channel <= 14
6385 * OR
6386 * ACS enabled and ACS operating band is choosen as 2.4
6387 * AND
6388 * VHT in 2.4G Disabled
6389 * THEN
6390 * Fallback to 11N mode
6391 */
6392 if (((AUTO_CHANNEL_SELECT != pConfig->channel && pConfig->channel <= SIR_11B_CHANNEL_END)
6393 || (AUTO_CHANNEL_SELECT == pConfig->channel &&
Deepthi Gowri7db41f32014-10-13 17:02:29 +05306394 operatingBand == eSAP_RF_SUBBAND_2_4_GHZ)) &&
Siddharth Bhal5cba24e2014-05-08 18:59:39 +05306395 iniConfig->enableVhtFor24GHzBand == FALSE)
Ravi Joshi83bfaa12013-05-28 22:12:08 -07006396 {
Siddharth Bhalf42f8592014-05-15 13:39:07 +05306397 hddLog(LOGW, FL("Setting hwmode to 11n, operatingBand = %d, Channel = %d"),
6398 operatingBand, pConfig->channel);
Ravi Joshi83bfaa12013-05-28 22:12:08 -07006399 pConfig->SapHw_mode = eSAP_DOT11_MODE_11n;
6400 }
Jeff Johnsone7245742012-09-05 17:12:55 -07006401 }
6402#endif
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306403
Ravi Joshiaeb7d9e2013-05-02 12:28:14 -07006404 if ( AUTO_CHANNEL_SELECT != pConfig->channel )
6405 {
6406 sme_SelectCBMode(hHal,
6407 sapConvertSapPhyModeToCsrPhyMode(pConfig->SapHw_mode),
6408 pConfig->channel);
6409 }
Jeff Johnson295189b2012-06-20 16:38:30 -07006410 // ht_capab is not what the name conveys,this is used for protection bitmap
6411 pConfig->ht_capab =
6412 (WLAN_HDD_GET_CTX(pHostapdAdapter))->cfg_ini->apProtection;
6413
6414 if ( 0 != wlan_hdd_cfg80211_update_apies(pHostapdAdapter, params) )
6415 {
6416 hddLog(LOGE, FL("SAP Not able to set AP IEs"));
6417 return -EINVAL;
6418 }
6419
6420 //Uapsd Enabled Bit
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306421 pConfig->UapsdEnable =
Jeff Johnson295189b2012-06-20 16:38:30 -07006422 (WLAN_HDD_GET_CTX(pHostapdAdapter))->cfg_ini->apUapsdEnabled;
6423 //Enable OBSS protection
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306424 pConfig->obssProtEnabled =
6425 (WLAN_HDD_GET_CTX(pHostapdAdapter))->cfg_ini->apOBSSProtEnabled;
Jeff Johnson295189b2012-06-20 16:38:30 -07006426
Chet Lanctot8cecea22014-02-11 19:09:36 -08006427#ifdef WLAN_FEATURE_11W
6428 pConfig->mfpCapable = MFPCapable;
6429 pConfig->mfpRequired = MFPRequired;
6430 hddLog(LOGW, FL("Soft AP MFP capable %d, MFP required %d\n"),
6431 pConfig->mfpCapable, pConfig->mfpRequired);
6432#endif
6433
Arif Hussain6d2a3322013-11-17 19:50:10 -08006434 hddLog(LOGW, FL("SOftAP macaddress : "MAC_ADDRESS_STR),
Jeff Johnson295189b2012-06-20 16:38:30 -07006435 MAC_ADDR_ARRAY(pHostapdAdapter->macAddressCurrent.bytes));
Arif Hussain6d2a3322013-11-17 19:50:10 -08006436 hddLog(LOGW,FL("ssid =%s, beaconint=%d, channel=%d"),
6437 pConfig->SSIDinfo.ssid.ssId, (int)pConfig->beacon_int,
6438 (int)pConfig->channel);
6439 hddLog(LOGW,FL("hw_mode=%x, privacy=%d, authType=%d"),
6440 pConfig->SapHw_mode, pConfig->privacy,
6441 pConfig->authType);
6442 hddLog(LOGW,FL("RSN/WPALen=%d, Uapsd = %d"),
6443 (int)pConfig->RSNWPAReqIELength, pConfig->UapsdEnable);
6444 hddLog(LOGW,FL("ProtEnabled = %d, OBSSProtEnabled = %d"),
6445 pConfig->protEnabled, pConfig->obssProtEnabled);
Jeff Johnson295189b2012-06-20 16:38:30 -07006446
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306447 if(test_bit(SOFTAP_BSS_STARTED, &pHostapdAdapter->event_flags))
Jeff Johnson295189b2012-06-20 16:38:30 -07006448 {
6449 //Bss already started. just return.
6450 //TODO Probably it should update some beacon params.
6451 hddLog( LOGE, "Bss Already started...Ignore the request");
6452 EXIT();
6453 return 0;
6454 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306455
Agarwal Ashish51325b52014-06-16 16:50:49 +05306456 if (vos_max_concurrent_connections_reached()) {
6457 hddLog(VOS_TRACE_LEVEL_INFO, FL("Reached max concurrent connections"));
6458 return -EINVAL;
6459 }
6460
Jeff Johnson295189b2012-06-20 16:38:30 -07006461 pConfig->persona = pHostapdAdapter->device_mode;
6462
Peng Xu2446a892014-09-05 17:21:18 +05306463 psmeConfig = (tSmeConfigParams*) vos_mem_malloc(sizeof(tSmeConfigParams));
6464 if ( NULL != psmeConfig)
6465 {
6466 sme_GetConfigParam(hHal, psmeConfig);
6467 pConfig->scanBandPreference = psmeConfig->csrConfig.scanBandPreference;
6468 vos_mem_free(psmeConfig);
6469 }
Peng Xuafc34e32014-09-25 13:23:55 +05306470 pConfig->acsBandSwitchThreshold = iniConfig->acsBandSwitchThreshold;
Peng Xu2446a892014-09-05 17:21:18 +05306471
Jeff Johnson295189b2012-06-20 16:38:30 -07006472 pSapEventCallback = hdd_hostapd_SAPEventCB;
6473 if(WLANSAP_StartBss(pVosContext, pSapEventCallback, pConfig,
6474 (v_PVOID_t)pHostapdAdapter->dev) != VOS_STATUS_SUCCESS)
6475 {
Arif Hussain6d2a3322013-11-17 19:50:10 -08006476 hddLog(LOGE,FL("SAP Start Bss fail"));
Jeff Johnson295189b2012-06-20 16:38:30 -07006477 return -EINVAL;
6478 }
6479
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306480 hddLog(LOG1,
Jeff Johnson295189b2012-06-20 16:38:30 -07006481 FL("Waiting for Scan to complete(auto mode) and BSS to start"));
6482
6483 status = vos_wait_single_event(&pHostapdState->vosEvent, 10000);
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306484
Jeff Johnson295189b2012-06-20 16:38:30 -07006485 if (!VOS_IS_STATUS_SUCCESS(status))
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306486 {
6487 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Arif Hussain6d2a3322013-11-17 19:50:10 -08006488 ("ERROR: HDD vos wait for single_event failed!!"));
Tushnim Bhattacharyyaad37df12013-10-02 12:01:33 -07006489 smeGetCommandQStatus(hHal);
Jeff Johnson295189b2012-06-20 16:38:30 -07006490 VOS_ASSERT(0);
6491 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306492
Jeff Johnson295189b2012-06-20 16:38:30 -07006493 set_bit(SOFTAP_BSS_STARTED, &pHostapdAdapter->event_flags);
Kaushik, Sushantf6070802014-10-15 15:09:23 +05306494 /* Initialize WMM configuation */
6495 hdd_wmm_init(pHostapdAdapter);
Agarwal Ashish51325b52014-06-16 16:50:49 +05306496 wlan_hdd_incr_active_session(pHddCtx, pHostapdAdapter->device_mode);
Jeff Johnson295189b2012-06-20 16:38:30 -07006497
Madan Mohan Koyyalamudi26bd7142012-10-30 18:14:19 -07006498#ifdef WLAN_FEATURE_P2P_DEBUG
6499 if (pHostapdAdapter->device_mode == WLAN_HDD_P2P_GO)
6500 {
6501 if(globalP2PConnectionStatus == P2P_GO_NEG_COMPLETED)
6502 {
6503 globalP2PConnectionStatus = P2P_GO_COMPLETED_STATE;
6504 hddLog(LOGE,"[P2P State] From Go nego completed to "
Jeff Johnson1250df42012-12-10 14:31:52 -08006505 "Non-autonomous Group started");
Madan Mohan Koyyalamudi26bd7142012-10-30 18:14:19 -07006506 }
6507 else if(globalP2PConnectionStatus == P2P_NOT_ACTIVE)
6508 {
6509 globalP2PConnectionStatus = P2P_GO_COMPLETED_STATE;
6510 hddLog(LOGE,"[P2P State] From Inactive to "
Jeff Johnson1250df42012-12-10 14:31:52 -08006511 "Autonomous Group started");
Madan Mohan Koyyalamudi26bd7142012-10-30 18:14:19 -07006512 }
6513 }
6514#endif
6515
Jeff Johnson295189b2012-06-20 16:38:30 -07006516 pHostapdState->bCommit = TRUE;
6517 EXIT();
6518
6519 return 0;
6520}
6521
Jeff Johnson04dd8a82012-06-29 20:41:40 -07006522#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,4,0))
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306523static int wlan_hdd_cfg80211_add_beacon(struct wiphy *wiphy,
6524 struct net_device *dev,
Jeff Johnson295189b2012-06-20 16:38:30 -07006525 struct beacon_parameters *params)
6526{
6527 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +05306528 hdd_context_t *pHddCtx;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05306529 int status;
Jeff Johnson295189b2012-06-20 16:38:30 -07006530
6531 ENTER();
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +05306532
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05306533 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
6534 TRACE_CODE_HDD_CFG80211_ADD_BEACON,
6535 pAdapter->sessionId, params->interval));
Sushant Kaushik8bc7df22014-04-09 17:55:29 +05306536 hddLog(VOS_TRACE_LEVEL_INFO_HIGH, "device mode=%s (%d)",
6537 hdd_device_modetoString(pAdapter->device_mode),
6538 pAdapter->device_mode);
Jeff Johnson295189b2012-06-20 16:38:30 -07006539
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05306540 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
6541 status = wlan_hdd_validate_context(pHddCtx);
6542
6543 if (0 != status)
Jeff Johnson04dd8a82012-06-29 20:41:40 -07006544 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05306545 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
6546 "%s: HDD context is not valid", __func__);
6547 return status;
Jeff Johnson04dd8a82012-06-29 20:41:40 -07006548 }
6549
Agarwal Ashish51325b52014-06-16 16:50:49 +05306550 if (vos_max_concurrent_connections_reached()) {
6551 hddLog(VOS_TRACE_LEVEL_INFO, FL("Reached max concurrent connections"));
6552 return -EINVAL;
6553 }
6554
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306555 if ( (pAdapter->device_mode == WLAN_HDD_SOFTAP)
Jeff Johnson295189b2012-06-20 16:38:30 -07006556 || (pAdapter->device_mode == WLAN_HDD_P2P_GO)
Jeff Johnson295189b2012-06-20 16:38:30 -07006557 )
6558 {
6559 beacon_data_t *old,*new;
6560
6561 old = pAdapter->sessionCtx.ap.beacon;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306562
Jeff Johnson295189b2012-06-20 16:38:30 -07006563 if (old)
c_hpothu6ff1c3c2013-10-01 19:01:57 +05306564 {
6565 hddLog(VOS_TRACE_LEVEL_WARN,
6566 FL("already beacon info added to session(%d)"),
6567 pAdapter->sessionId);
Jeff Johnson295189b2012-06-20 16:38:30 -07006568 return -EALREADY;
c_hpothu6ff1c3c2013-10-01 19:01:57 +05306569 }
Jeff Johnson295189b2012-06-20 16:38:30 -07006570
6571 status = wlan_hdd_cfg80211_alloc_new_beacon(pAdapter,&new,params);
6572
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306573 if(status != VOS_STATUS_SUCCESS)
Jeff Johnson295189b2012-06-20 16:38:30 -07006574 {
6575 hddLog(VOS_TRACE_LEVEL_FATAL,
Arif Hussain6d2a3322013-11-17 19:50:10 -08006576 "%s:Error!!! Allocating the new beacon",__func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07006577 return -EINVAL;
6578 }
6579
6580 pAdapter->sessionCtx.ap.beacon = new;
6581
6582 status = wlan_hdd_cfg80211_start_bss(pAdapter, params);
6583 }
6584
6585 EXIT();
6586 return status;
6587}
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306588
6589static int wlan_hdd_cfg80211_set_beacon(struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -07006590 struct net_device *dev,
6591 struct beacon_parameters *params)
6592{
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306593 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +05306594 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
6595 hdd_context_t *pHddCtx;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05306596 int status;
Jeff Johnson295189b2012-06-20 16:38:30 -07006597
6598 ENTER();
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +05306599 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
6600 TRACE_CODE_HDD_CFG80211_SET_BEACON,
6601 pAdapter->sessionId, pHddStaCtx->conn_info.authType));
6602 hddLog(VOS_TRACE_LEVEL_INFO, "%s: device_mode = %s (%d)",
6603 __func__, hdd_device_modetoString(pAdapter->device_mode),
6604 pAdapter->device_mode);
6605
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05306606 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
6607 status = wlan_hdd_validate_context(pHddCtx);
6608
6609 if (0 != status)
Jeff Johnson04dd8a82012-06-29 20:41:40 -07006610 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05306611 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
6612 "%s: HDD context is not valid", __func__);
6613 return status;
Jeff Johnson04dd8a82012-06-29 20:41:40 -07006614 }
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +05306615
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306616 if ((pAdapter->device_mode == WLAN_HDD_SOFTAP)
Jeff Johnson295189b2012-06-20 16:38:30 -07006617 || (pAdapter->device_mode == WLAN_HDD_P2P_GO)
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306618 )
Jeff Johnson295189b2012-06-20 16:38:30 -07006619 {
6620 beacon_data_t *old,*new;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306621
Jeff Johnson295189b2012-06-20 16:38:30 -07006622 old = pAdapter->sessionCtx.ap.beacon;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306623
Jeff Johnson295189b2012-06-20 16:38:30 -07006624 if (!old)
c_hpothu6ff1c3c2013-10-01 19:01:57 +05306625 {
6626 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
6627 FL("session(%d) old and new heads points to NULL"),
6628 pAdapter->sessionId);
Jeff Johnson295189b2012-06-20 16:38:30 -07006629 return -ENOENT;
c_hpothu6ff1c3c2013-10-01 19:01:57 +05306630 }
Jeff Johnson295189b2012-06-20 16:38:30 -07006631
6632 status = wlan_hdd_cfg80211_alloc_new_beacon(pAdapter,&new,params);
6633
6634 if(status != VOS_STATUS_SUCCESS) {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306635 hddLog(VOS_TRACE_LEVEL_FATAL,
Arif Hussain6d2a3322013-11-17 19:50:10 -08006636 "%s: Error!!! Allocating the new beacon",__func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07006637 return -EINVAL;
6638 }
6639
6640 pAdapter->sessionCtx.ap.beacon = new;
6641
6642 status = wlan_hdd_cfg80211_start_bss(pAdapter, params);
6643 }
6644
6645 EXIT();
6646 return status;
6647}
6648
Jeff Johnson04dd8a82012-06-29 20:41:40 -07006649#endif //(LINUX_VERSION_CODE < KERNEL_VERSION(3,4,0))
6650
6651#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,4,0))
Jeff Johnson295189b2012-06-20 16:38:30 -07006652static int wlan_hdd_cfg80211_del_beacon(struct wiphy *wiphy,
6653 struct net_device *dev)
Jeff Johnson04dd8a82012-06-29 20:41:40 -07006654#else
6655static int wlan_hdd_cfg80211_stop_ap (struct wiphy *wiphy,
6656 struct net_device *dev)
6657#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07006658{
6659 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
Jeff Johnsone7245742012-09-05 17:12:55 -07006660 hdd_context_t *pHddCtx = NULL;
6661 hdd_scaninfo_t *pScanInfo = NULL;
6662 hdd_adapter_t *staAdapter = NULL;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05306663 VOS_STATUS status;
Mahesh A Saptasagar2395ee62014-05-21 19:12:21 +05306664 long ret;
Jeff Johnson295189b2012-06-20 16:38:30 -07006665
6666 ENTER();
6667
6668 if (NULL == pAdapter)
6669 {
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +05306670 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07006671 "%s: HDD adapter context is Null", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07006672 return -ENODEV;
6673 }
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -07006674
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05306675 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
6676 TRACE_CODE_HDD_CFG80211_STOP_AP,
6677 pAdapter->sessionId, pAdapter->device_mode));
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05306678 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
6679 status = wlan_hdd_validate_context(pHddCtx);
6680
6681 if (0 != status)
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -07006682 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05306683 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
6684 "%s: HDD context is not valid", __func__);
6685 return status;
Jeff Johnson4416a782013-03-25 14:17:50 -07006686 }
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -07006687
6688 staAdapter = hdd_get_adapter(pAdapter->pHddCtx, WLAN_HDD_INFRA_STATION);
6689 if (NULL == staAdapter)
6690 {
6691 staAdapter = hdd_get_adapter(pAdapter->pHddCtx, WLAN_HDD_P2P_CLIENT);
6692 if (NULL == staAdapter)
6693 {
Rajesh Chauhan52d885b2013-11-01 10:54:25 -07006694 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO_HIGH,
6695 "%s: HDD adapter context for STA/P2P-CLI is Null",
6696 __func__);
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -07006697 }
6698 }
6699
6700 pScanInfo = &pHddCtx->scan_info;
6701
Sushant Kaushik8bc7df22014-04-09 17:55:29 +05306702 hddLog(VOS_TRACE_LEVEL_INFO, "%s: device_mode = %s (%d)",
6703 __func__, hdd_device_modetoString(pAdapter->device_mode),
6704 pAdapter->device_mode);
Jeff Johnson295189b2012-06-20 16:38:30 -07006705
Mahesh A Saptasagar2395ee62014-05-21 19:12:21 +05306706 ret = wlan_hdd_scan_abort(pAdapter);
6707
Girish Gowli4bf7a632014-06-12 13:42:11 +05306708 if (ret < 0)
Jeff Johnsone7245742012-09-05 17:12:55 -07006709 {
Mahesh A Saptasagar2395ee62014-05-21 19:12:21 +05306710 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
6711 FL("Timeout occurred while waiting for abortscan %ld"), ret);
c_hpothu6ff1c3c2013-10-01 19:01:57 +05306712
Mahesh A Saptasagar2395ee62014-05-21 19:12:21 +05306713 if (pHddCtx->isLogpInProgress)
Jeff Johnsone7245742012-09-05 17:12:55 -07006714 {
Mahesh A Saptasagar2395ee62014-05-21 19:12:21 +05306715 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
6716 "%s: LOGP in Progress. Ignore!!!", __func__);
Yue Ma4f55ef32014-01-23 16:45:33 -08006717
Jeff Johnsone7245742012-09-05 17:12:55 -07006718 VOS_ASSERT(pScanInfo->mScanPending);
Mahesh A Saptasagar2395ee62014-05-21 19:12:21 +05306719 return -EAGAIN;
Jeff Johnsone7245742012-09-05 17:12:55 -07006720 }
Mahesh A Saptasagar2395ee62014-05-21 19:12:21 +05306721 VOS_ASSERT(pScanInfo->mScanPending);
Jeff Johnsone7245742012-09-05 17:12:55 -07006722 }
6723
Rashmi Ramanna1f0948d2014-08-28 15:33:48 +05306724 /* Delete all associated STAs before stopping AP/P2P GO */
6725 hdd_del_all_sta(pAdapter);
Arun Kumar Khandavallia3bd8002014-01-17 16:21:19 +05306726 hdd_hostapd_stop(dev);
6727
Jeff Johnson295189b2012-06-20 16:38:30 -07006728 if ((pAdapter->device_mode == WLAN_HDD_SOFTAP)
Jeff Johnson295189b2012-06-20 16:38:30 -07006729 || (pAdapter->device_mode == WLAN_HDD_P2P_GO)
Jeff Johnson295189b2012-06-20 16:38:30 -07006730 )
6731 {
6732 beacon_data_t *old;
6733
6734 old = pAdapter->sessionCtx.ap.beacon;
6735
6736 if (!old)
c_hpothu6ff1c3c2013-10-01 19:01:57 +05306737 {
6738 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
6739 FL("session(%d) beacon data points to NULL"),
6740 pAdapter->sessionId);
Jeff Johnson295189b2012-06-20 16:38:30 -07006741 return -ENOENT;
c_hpothu6ff1c3c2013-10-01 19:01:57 +05306742 }
Jeff Johnson295189b2012-06-20 16:38:30 -07006743
Jeff Johnson295189b2012-06-20 16:38:30 -07006744 hdd_cleanup_actionframe(pHddCtx, pAdapter);
Jeff Johnson295189b2012-06-20 16:38:30 -07006745
6746 mutex_lock(&pHddCtx->sap_lock);
6747 if(test_bit(SOFTAP_BSS_STARTED, &pAdapter->event_flags))
6748 {
Jeff Johnson4416a782013-03-25 14:17:50 -07006749 if ( VOS_STATUS_SUCCESS == (status = WLANSAP_StopBss(pHddCtx->pvosContext) ) )
Jeff Johnson295189b2012-06-20 16:38:30 -07006750 {
6751 hdd_hostapd_state_t *pHostapdState = WLAN_HDD_GET_HOSTAP_STATE_PTR(pAdapter);
6752
6753 status = vos_wait_single_event(&pHostapdState->vosEvent, 10000);
6754
6755 if (!VOS_IS_STATUS_SUCCESS(status))
6756 {
6757 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Arif Hussain6d2a3322013-11-17 19:50:10 -08006758 ("ERROR: HDD vos wait for single_event failed!!"));
Jeff Johnson295189b2012-06-20 16:38:30 -07006759 VOS_ASSERT(0);
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05306760 }
6761 }
Jeff Johnson295189b2012-06-20 16:38:30 -07006762 clear_bit(SOFTAP_BSS_STARTED, &pAdapter->event_flags);
Agarwal Ashish51325b52014-06-16 16:50:49 +05306763 /* BSS stopped, clear the active sessions for this device mode */
6764 wlan_hdd_decr_active_session(pHddCtx, pAdapter->device_mode);
Jeff Johnson295189b2012-06-20 16:38:30 -07006765 }
6766 mutex_unlock(&pHddCtx->sap_lock);
6767
6768 if(status != VOS_STATUS_SUCCESS)
6769 {
6770 hddLog(VOS_TRACE_LEVEL_FATAL,
Arif Hussain6d2a3322013-11-17 19:50:10 -08006771 "%s:Error!!! Stopping the BSS",__func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07006772 return -EINVAL;
6773 }
6774
Jeff Johnson4416a782013-03-25 14:17:50 -07006775 if (ccmCfgSetInt(pHddCtx->hHal,
Jeff Johnson295189b2012-06-20 16:38:30 -07006776 WNI_CFG_PROBE_RSP_BCN_ADDNIE_FLAG, 0,NULL, eANI_BOOLEAN_FALSE)
6777 ==eHAL_STATUS_FAILURE)
6778 {
6779 hddLog(LOGE,
Arif Hussain6d2a3322013-11-17 19:50:10 -08006780 "Could not pass on WNI_CFG_PROBE_RSP_BCN_ADDNIE_FLAG to CCM");
Jeff Johnson295189b2012-06-20 16:38:30 -07006781 }
6782
Jeff Johnson4416a782013-03-25 14:17:50 -07006783 if ( eHAL_STATUS_FAILURE == ccmCfgSetInt(pHddCtx->hHal,
Jeff Johnson295189b2012-06-20 16:38:30 -07006784 WNI_CFG_ASSOC_RSP_ADDNIE_FLAG, 0, NULL,
6785 eANI_BOOLEAN_FALSE) )
6786 {
6787 hddLog(LOGE,
Arif Hussain6d2a3322013-11-17 19:50:10 -08006788 "Could not pass on WNI_CFG_ASSOC_RSP_ADDNIE_FLAG to CCM");
Jeff Johnson295189b2012-06-20 16:38:30 -07006789 }
6790
6791 // Reset WNI_CFG_PROBE_RSP Flags
6792 wlan_hdd_reset_prob_rspies(pAdapter);
6793
6794 pAdapter->sessionCtx.ap.beacon = NULL;
6795 kfree(old);
Madan Mohan Koyyalamudi26bd7142012-10-30 18:14:19 -07006796#ifdef WLAN_FEATURE_P2P_DEBUG
6797 if((pAdapter->device_mode == WLAN_HDD_P2P_GO) &&
6798 (globalP2PConnectionStatus == P2P_GO_COMPLETED_STATE))
6799 {
6800 hddLog(LOGE,"[P2P State] From GO completed to Inactive state "
6801 "GO got removed");
6802 globalP2PConnectionStatus = P2P_NOT_ACTIVE;
6803 }
6804#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07006805 }
6806 EXIT();
6807 return status;
6808}
Jeff Johnson04dd8a82012-06-29 20:41:40 -07006809
6810#if (LINUX_VERSION_CODE > KERNEL_VERSION(3,3,0))
6811
Pratik Bhalgata0c7f262012-11-22 17:40:24 +05306812static int wlan_hdd_cfg80211_start_ap(struct wiphy *wiphy,
6813 struct net_device *dev,
Jeff Johnson04dd8a82012-06-29 20:41:40 -07006814 struct cfg80211_ap_settings *params)
6815{
Pratik Bhalgata0c7f262012-11-22 17:40:24 +05306816 hdd_adapter_t *pAdapter;
6817 hdd_context_t *pHddCtx;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05306818 int status;
Jeff Johnson04dd8a82012-06-29 20:41:40 -07006819
6820 ENTER();
6821
Pratik Bhalgata0c7f262012-11-22 17:40:24 +05306822 if (NULL == dev)
Madan Mohan Koyyalamudib2c36892012-10-18 20:52:38 -07006823 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05306824 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Pratik Bhalgata0c7f262012-11-22 17:40:24 +05306825 "%s: Device is Null", __func__);
6826 return -ENODEV;
6827 }
6828
6829 pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
6830 if (NULL == pAdapter)
6831 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05306832 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Pratik Bhalgata0c7f262012-11-22 17:40:24 +05306833 "%s: HDD adapter is Null", __func__);
6834 return -ENODEV;
6835 }
6836
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05306837 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
6838 TRACE_CODE_HDD_CFG80211_START_AP, pAdapter->sessionId,
6839 params-> beacon_interval));
Pratik Bhalgata0c7f262012-11-22 17:40:24 +05306840 if (WLAN_HDD_ADAPTER_MAGIC != pAdapter->magic)
6841 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05306842 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Pratik Bhalgata0c7f262012-11-22 17:40:24 +05306843 "%s: HDD adapter magic is invalid", __func__);
6844 return -ENODEV;
6845 }
6846
6847 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05306848 status = wlan_hdd_validate_context(pHddCtx);
Pratik Bhalgata0c7f262012-11-22 17:40:24 +05306849
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05306850 if (0 != status)
Pratik Bhalgata0c7f262012-11-22 17:40:24 +05306851 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05306852 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
6853 "%s: HDD context is not valid", __func__);
6854 return status;
Pratik Bhalgata0c7f262012-11-22 17:40:24 +05306855 }
6856
Sushant Kaushik8bc7df22014-04-09 17:55:29 +05306857 hddLog(VOS_TRACE_LEVEL_INFO_HIGH, "%s: device mode = %s (%d)",
6858 __func__, hdd_device_modetoString(pAdapter->device_mode),
6859 pAdapter->device_mode);
Pratik Bhalgata0c7f262012-11-22 17:40:24 +05306860
6861 if ((pAdapter->device_mode == WLAN_HDD_SOFTAP)
Jeff Johnson04dd8a82012-06-29 20:41:40 -07006862 || (pAdapter->device_mode == WLAN_HDD_P2P_GO)
Jeff Johnson04dd8a82012-06-29 20:41:40 -07006863 )
6864 {
Pratik Bhalgata0c7f262012-11-22 17:40:24 +05306865 beacon_data_t *old, *new;
Jeff Johnson04dd8a82012-06-29 20:41:40 -07006866
6867 old = pAdapter->sessionCtx.ap.beacon;
Pratik Bhalgata0c7f262012-11-22 17:40:24 +05306868
Jeff Johnson04dd8a82012-06-29 20:41:40 -07006869 if (old)
c_hpothu6ff1c3c2013-10-01 19:01:57 +05306870 {
6871 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_WARN,
6872 FL("already beacon info added to session(%d)"),
6873 pAdapter->sessionId);
Jeff Johnson04dd8a82012-06-29 20:41:40 -07006874 return -EALREADY;
c_hpothu6ff1c3c2013-10-01 19:01:57 +05306875 }
Jeff Johnson04dd8a82012-06-29 20:41:40 -07006876
6877 status = wlan_hdd_cfg80211_alloc_new_beacon(pAdapter, &new, &params->beacon, params->dtim_period);
6878
Pratik Bhalgata0c7f262012-11-22 17:40:24 +05306879 if (status != 0)
Jeff Johnson04dd8a82012-06-29 20:41:40 -07006880 {
6881 hddLog(VOS_TRACE_LEVEL_FATAL,
Pratik Bhalgata0c7f262012-11-22 17:40:24 +05306882 "%s:Error!!! Allocating the new beacon", __func__);
Jeff Johnson04dd8a82012-06-29 20:41:40 -07006883 return -EINVAL;
6884 }
6885 pAdapter->sessionCtx.ap.beacon = new;
Viral Modi3a32cc52013-02-08 11:14:52 -08006886#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,6,0))
Yue Maf49ba872013-08-19 12:04:25 -07006887 wlan_hdd_cfg80211_set_channel(wiphy, dev,
6888#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,8,0))
6889 params->channel, params->channel_type);
6890#else
6891 params->chandef.chan, cfg80211_get_chandef_type(&(params->chandef)));
6892#endif
Viral Modi3a32cc52013-02-08 11:14:52 -08006893#endif
Jeff Johnson04dd8a82012-06-29 20:41:40 -07006894 status = wlan_hdd_cfg80211_start_bss(pAdapter, &params->beacon, params->ssid,
6895 params->ssid_len, params->hidden_ssid);
6896 }
6897
6898 EXIT();
6899 return status;
6900}
6901
6902
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306903static int wlan_hdd_cfg80211_change_beacon(struct wiphy *wiphy,
Jeff Johnson04dd8a82012-06-29 20:41:40 -07006904 struct net_device *dev,
6905 struct cfg80211_beacon_data *params)
6906{
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306907 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +05306908 hdd_context_t *pHddCtx;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05306909 int status;
Jeff Johnson04dd8a82012-06-29 20:41:40 -07006910
6911 ENTER();
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +05306912
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05306913 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
6914 TRACE_CODE_HDD_CFG80211_CHANGE_BEACON,
6915 pAdapter->sessionId, pAdapter->device_mode));
Arif Hussain6d2a3322013-11-17 19:50:10 -08006916 hddLog(VOS_TRACE_LEVEL_INFO, "%s: device_mode = %d",
Jeff Johnson04dd8a82012-06-29 20:41:40 -07006917 __func__, pAdapter->device_mode);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05306918
6919 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
6920 status = wlan_hdd_validate_context(pHddCtx);
6921
6922 if (0 != status)
Madan Mohan Koyyalamudib2c36892012-10-18 20:52:38 -07006923 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05306924 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
6925 "%s: HDD context is not valid", __func__);
6926 return status;
Madan Mohan Koyyalamudib2c36892012-10-18 20:52:38 -07006927 }
Jeff Johnson04dd8a82012-06-29 20:41:40 -07006928
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306929 if ((pAdapter->device_mode == WLAN_HDD_SOFTAP)
Jeff Johnson04dd8a82012-06-29 20:41:40 -07006930 || (pAdapter->device_mode == WLAN_HDD_P2P_GO)
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306931 )
Jeff Johnson04dd8a82012-06-29 20:41:40 -07006932 {
6933 beacon_data_t *old,*new;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306934
Jeff Johnson04dd8a82012-06-29 20:41:40 -07006935 old = pAdapter->sessionCtx.ap.beacon;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306936
Jeff Johnson04dd8a82012-06-29 20:41:40 -07006937 if (!old)
c_hpothu6ff1c3c2013-10-01 19:01:57 +05306938 {
6939 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
6940 FL("session(%d) beacon data points to NULL"),
6941 pAdapter->sessionId);
Jeff Johnson04dd8a82012-06-29 20:41:40 -07006942 return -ENOENT;
c_hpothu6ff1c3c2013-10-01 19:01:57 +05306943 }
Jeff Johnson04dd8a82012-06-29 20:41:40 -07006944
6945 status = wlan_hdd_cfg80211_alloc_new_beacon(pAdapter, &new, params, 0);
6946
6947 if(status != VOS_STATUS_SUCCESS) {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306948 hddLog(VOS_TRACE_LEVEL_FATAL,
Arif Hussain6d2a3322013-11-17 19:50:10 -08006949 "%s: Error!!! Allocating the new beacon",__func__);
Jeff Johnson04dd8a82012-06-29 20:41:40 -07006950 return -EINVAL;
6951 }
6952
6953 pAdapter->sessionCtx.ap.beacon = new;
6954
6955 status = wlan_hdd_cfg80211_start_bss(pAdapter, params, NULL, 0, 0);
6956 }
6957
6958 EXIT();
6959 return status;
6960}
6961
6962#endif //(LINUX_VERSION_CODE > KERNEL_VERSION(3,3,0))
6963
Jeff Johnson295189b2012-06-20 16:38:30 -07006964
Mahesh A Saptasagar179d2252014-06-02 21:32:21 +05306965static int __wlan_hdd_cfg80211_change_bss (struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -07006966 struct net_device *dev,
6967 struct bss_parameters *params)
6968{
6969 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
6970
6971 ENTER();
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +05306972
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05306973 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
6974 TRACE_CODE_HDD_CFG80211_CHANGE_BSS,
6975 pAdapter->sessionId, params->ap_isolate));
Sushant Kaushik8bc7df22014-04-09 17:55:29 +05306976 hddLog(VOS_TRACE_LEVEL_INFO, "%s: device_mode = %s (%d)",
6977 __func__, hdd_device_modetoString(pAdapter->device_mode),
6978 pAdapter->device_mode);
Jeff Johnson295189b2012-06-20 16:38:30 -07006979
6980 if((pAdapter->device_mode == WLAN_HDD_SOFTAP)
Jeff Johnson295189b2012-06-20 16:38:30 -07006981 || (pAdapter->device_mode == WLAN_HDD_P2P_GO)
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306982 )
Jeff Johnson295189b2012-06-20 16:38:30 -07006983 {
6984 /* ap_isolate == -1 means that in change bss, upper layer doesn't
6985 * want to update this parameter */
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306986 if (-1 != params->ap_isolate)
Jeff Johnson295189b2012-06-20 16:38:30 -07006987 {
6988 pAdapter->sessionCtx.ap.apDisableIntraBssFwd = !!params->ap_isolate;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306989 }
Jeff Johnson295189b2012-06-20 16:38:30 -07006990 }
6991
6992 EXIT();
6993 return 0;
6994}
6995
Mahesh A Saptasagar179d2252014-06-02 21:32:21 +05306996static int wlan_hdd_cfg80211_change_bss (struct wiphy *wiphy,
6997 struct net_device *dev,
6998 struct bss_parameters *params)
6999{
7000 int ret;
7001
7002 vos_ssr_protect(__func__);
7003 ret = __wlan_hdd_cfg80211_change_bss(wiphy, dev, params);
7004 vos_ssr_unprotect(__func__);
7005
7006 return ret;
7007}
Kiet Lam10841362013-11-01 11:36:50 +05307008/* FUNCTION: wlan_hdd_change_country_code_cd
7009* to wait for contry code completion
7010*/
7011void* wlan_hdd_change_country_code_cb(void *pAdapter)
7012{
7013 hdd_adapter_t *call_back_pAdapter = pAdapter;
7014 complete(&call_back_pAdapter->change_country_code);
7015 return NULL;
7016}
7017
Jeff Johnson295189b2012-06-20 16:38:30 -07007018/*
Mahesh A Saptasagar0e59c472014-04-14 19:17:41 +05307019 * FUNCTION: __wlan_hdd_cfg80211_change_iface
Jeff Johnson295189b2012-06-20 16:38:30 -07007020 * This function is used to set the interface type (INFRASTRUCTURE/ADHOC)
7021 */
Mahesh A Saptasagar0e59c472014-04-14 19:17:41 +05307022int __wlan_hdd_cfg80211_change_iface( struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -07007023 struct net_device *ndev,
7024 enum nl80211_iftype type,
7025 u32 *flags,
7026 struct vif_params *params
7027 )
7028{
7029 struct wireless_dev *wdev;
7030 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( ndev );
Rajesh Chauhana0516c62014-01-30 16:11:18 -08007031 hdd_context_t *pHddCtx;
Mohit Khanna0f232092012-09-11 14:46:08 -07007032 hdd_adapter_t *pP2pAdapter = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -07007033 tCsrRoamProfile *pRoamProfile = NULL;
7034 eCsrRoamBssType LastBSSType;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05307035 hdd_config_t *pConfig = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -07007036 eMib_dot11DesiredBssType connectedBssType;
7037 VOS_STATUS status;
c_hpothu6ff1c3c2013-10-01 19:01:57 +05307038 long ret;
Jeff Johnson295189b2012-06-20 16:38:30 -07007039
7040 ENTER();
7041
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05307042 if (!pAdapter)
Rajesh Chauhana0516c62014-01-30 16:11:18 -08007043 {
7044 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
7045 "%s: Adapter context is null", __func__);
7046 return VOS_STATUS_E_FAILURE;
7047 }
7048
7049 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
7050 if (!pHddCtx)
7051 {
7052 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
7053 "%s: HDD context is null", __func__);
7054 return VOS_STATUS_E_FAILURE;
7055 }
7056
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05307057 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
7058 TRACE_CODE_HDD_CFG80211_CHANGE_IFACE,
7059 pAdapter->sessionId, type));
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05307060 status = wlan_hdd_validate_context(pHddCtx);
7061
7062 if (0 != status)
Jeff Johnson295189b2012-06-20 16:38:30 -07007063 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05307064 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
7065 "%s: HDD context is not valid", __func__);
7066 return status;
Jeff Johnson295189b2012-06-20 16:38:30 -07007067 }
7068
Sushant Kaushik8bc7df22014-04-09 17:55:29 +05307069 hddLog(VOS_TRACE_LEVEL_INFO, "%s: device_mode = %s (%d)",
7070 __func__, hdd_device_modetoString(pAdapter->device_mode),
7071 pAdapter->device_mode);
Jeff Johnson295189b2012-06-20 16:38:30 -07007072
Agarwal Ashish51325b52014-06-16 16:50:49 +05307073 if (vos_max_concurrent_connections_reached()) {
7074 hddLog(VOS_TRACE_LEVEL_INFO, FL("Reached max concurrent connections"));
7075 return -EINVAL;
7076 }
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05307077 pConfig = pHddCtx->cfg_ini;
Jeff Johnson295189b2012-06-20 16:38:30 -07007078 wdev = ndev->ieee80211_ptr;
7079
7080#ifdef WLAN_BTAMP_FEATURE
7081 if((NL80211_IFTYPE_P2P_CLIENT == type)||
7082 (NL80211_IFTYPE_ADHOC == type)||
7083 (NL80211_IFTYPE_AP == type)||
7084 (NL80211_IFTYPE_P2P_GO == type))
7085 {
7086 pHddCtx->isAmpAllowed = VOS_FALSE;
7087 // stop AMP traffic
7088 status = WLANBAP_StopAmp();
7089 if(VOS_STATUS_SUCCESS != status )
7090 {
7091 pHddCtx->isAmpAllowed = VOS_TRUE;
7092 hddLog(VOS_TRACE_LEVEL_FATAL,
7093 "%s: Failed to stop AMP", __func__);
7094 return -EINVAL;
7095 }
7096 }
7097#endif //WLAN_BTAMP_FEATURE
7098 /* Reset the current device mode bit mask*/
7099 wlan_hdd_clear_concurrency_mode(pHddCtx, pAdapter->device_mode);
7100
7101 if( (pAdapter->device_mode == WLAN_HDD_INFRA_STATION)
Jeff Johnson295189b2012-06-20 16:38:30 -07007102 || (pAdapter->device_mode == WLAN_HDD_P2P_CLIENT)
Jeff Johnsone7245742012-09-05 17:12:55 -07007103 || (pAdapter->device_mode == WLAN_HDD_P2P_DEVICE)
Jeff Johnson295189b2012-06-20 16:38:30 -07007104 )
7105 {
7106 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
Rajesh Chauhana0516c62014-01-30 16:11:18 -08007107 if (!pWextState)
7108 {
7109 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
7110 "%s: pWextState is null", __func__);
7111 return VOS_STATUS_E_FAILURE;
7112 }
Jeff Johnson295189b2012-06-20 16:38:30 -07007113 pRoamProfile = &pWextState->roamProfile;
7114 LastBSSType = pRoamProfile->BSSType;
7115
7116 switch (type)
7117 {
7118 case NL80211_IFTYPE_STATION:
Jeff Johnson295189b2012-06-20 16:38:30 -07007119 case NL80211_IFTYPE_P2P_CLIENT:
Jeff Johnson295189b2012-06-20 16:38:30 -07007120 hddLog(VOS_TRACE_LEVEL_INFO,
7121 "%s: setting interface Type to INFRASTRUCTURE", __func__);
7122 pRoamProfile->BSSType = eCSR_BSS_TYPE_INFRASTRUCTURE;
Jeff Johnsone7245742012-09-05 17:12:55 -07007123#ifdef WLAN_FEATURE_11AC
7124 if(pConfig->dot11Mode == eHDD_DOT11_MODE_AUTO)
7125 {
7126 pConfig->dot11Mode = eHDD_DOT11_MODE_11ac;
7127 }
7128#endif
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307129 pRoamProfile->phyMode =
Jeff Johnsone7245742012-09-05 17:12:55 -07007130 hdd_cfg_xlate_to_csr_phy_mode(pConfig->dot11Mode);
Jeff Johnson295189b2012-06-20 16:38:30 -07007131 wdev->iftype = type;
Gopichand Nakkalaf527dc62012-12-31 16:35:10 -08007132 //Check for sub-string p2p to confirm its a p2p interface
7133 if (NULL != strstr(ndev->name,"p2p"))
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307134 {
Gopichand Nakkala864d3552012-12-31 16:08:51 -08007135 pAdapter->device_mode = (type == NL80211_IFTYPE_STATION) ?
7136 WLAN_HDD_P2P_DEVICE : WLAN_HDD_P2P_CLIENT;
7137 }
7138 else
7139 {
7140 pAdapter->device_mode = (type == NL80211_IFTYPE_STATION) ?
Jeff Johnson295189b2012-06-20 16:38:30 -07007141 WLAN_HDD_INFRA_STATION: WLAN_HDD_P2P_CLIENT;
Gopichand Nakkala864d3552012-12-31 16:08:51 -08007142 }
Madan Mohan Koyyalamudi81746922013-07-17 14:38:51 +05307143#ifdef FEATURE_WLAN_TDLS
7144 /* The open adapter for the p2p shall skip initializations in
7145 * tdls_init if the device mode is WLAN_HDD_P2P_DEVICE, for
7146 * TDLS is supported only on WLAN_HDD_P2P_CLIENT. Hence invoke
7147 * tdls_init when the change_iface sets the device mode to
7148 * WLAN_HDD_P2P_CLIENT.
7149 */
7150
7151 if ( pAdapter->device_mode == WLAN_HDD_P2P_CLIENT)
7152 {
Agarwal Ashish4b87f922014-06-18 03:03:21 +05307153 if (0 != wlan_hdd_sta_tdls_init (pAdapter))
Madan Mohan Koyyalamudi81746922013-07-17 14:38:51 +05307154 {
c_hpothu6ff1c3c2013-10-01 19:01:57 +05307155 hddLog(VOS_TRACE_LEVEL_ERROR,
7156 "%s: tdls initialization failed", __func__);
Madan Mohan Koyyalamudi81746922013-07-17 14:38:51 +05307157 return -EINVAL;
7158 }
7159 }
7160#endif
7161
Jeff Johnson295189b2012-06-20 16:38:30 -07007162 break;
7163 case NL80211_IFTYPE_ADHOC:
7164 hddLog(VOS_TRACE_LEVEL_INFO,
7165 "%s: setting interface Type to ADHOC", __func__);
7166 pRoamProfile->BSSType = eCSR_BSS_TYPE_START_IBSS;
7167 pRoamProfile->phyMode =
7168 hdd_cfg_xlate_to_csr_phy_mode(pConfig->dot11Mode);
Shailender Karmuchia734f332013-04-19 14:02:48 -07007169 pAdapter->device_mode = WLAN_HDD_IBSS;
Jeff Johnson295189b2012-06-20 16:38:30 -07007170 wdev->iftype = type;
7171 break;
7172
7173 case NL80211_IFTYPE_AP:
Jeff Johnson295189b2012-06-20 16:38:30 -07007174 case NL80211_IFTYPE_P2P_GO:
Jeff Johnson295189b2012-06-20 16:38:30 -07007175 {
7176 hddLog(VOS_TRACE_LEVEL_INFO_HIGH,
7177 "%s: setting interface Type to %s", __func__,
7178 (type == NL80211_IFTYPE_AP) ? "SoftAP" : "P2pGo");
7179
Gopichand Nakkalaf527dc62012-12-31 16:35:10 -08007180 //Cancel any remain on channel for GO mode
7181 if (NL80211_IFTYPE_P2P_GO == type)
7182 {
7183 wlan_hdd_cancel_existing_remain_on_channel(pAdapter);
7184 }
Mohit Khanna0f232092012-09-11 14:46:08 -07007185 if (NL80211_IFTYPE_AP == type)
7186 {
7187 /* As Loading WLAN Driver one interface being created for p2p device
7188 * address. This will take one HW STA and the max number of clients
7189 * that can connect to softAP will be reduced by one. so while changing
7190 * the interface type to NL80211_IFTYPE_AP (SoftAP) remove p2p0
7191 * interface as it is not required in SoftAP mode.
7192 */
7193
7194 // Get P2P Adapter
7195 pP2pAdapter = hdd_get_adapter(pHddCtx, WLAN_HDD_P2P_DEVICE);
7196
7197 if (pP2pAdapter)
7198 {
Agarwal Ashish3a38bd12014-06-12 15:16:52 +05307199 hdd_stop_adapter(pHddCtx, pP2pAdapter, VOS_TRUE);
Mohit Khanna0f232092012-09-11 14:46:08 -07007200 hdd_deinit_adapter(pHddCtx, pP2pAdapter);
7201 hdd_close_adapter(pHddCtx, pP2pAdapter, VOS_TRUE);
7202 }
7203 }
Swaroop Goltia2e32212014-04-09 23:37:33 +05307204 //Disable IMPS & BMPS for SAP/GO
7205 if(VOS_STATUS_E_FAILURE ==
7206 hdd_disable_bmps_imps(pHddCtx, WLAN_HDD_P2P_GO))
7207 {
7208 //Fail to Exit BMPS
7209 VOS_ASSERT(0);
7210 }
Deepthi Gowri500fc472014-08-11 19:53:10 +05307211
7212 hdd_stop_adapter( pHddCtx, pAdapter, VOS_TRUE );
7213
Madan Mohan Koyyalamudi96797442013-10-08 16:04:42 +05307214#ifdef FEATURE_WLAN_TDLS
Mohit Khanna0f232092012-09-11 14:46:08 -07007215
Madan Mohan Koyyalamudi96797442013-10-08 16:04:42 +05307216 /* A Mutex Lock is introduced while changing the mode to
7217 * protect the concurrent access for the Adapters by TDLS
7218 * module.
7219 */
Rajesh Chauhana34c6e62014-03-25 16:37:58 +05307220 mutex_lock(&pHddCtx->tdls_lock);
Madan Mohan Koyyalamudi96797442013-10-08 16:04:42 +05307221#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07007222 //De-init the adapter.
Jeff Johnson295189b2012-06-20 16:38:30 -07007223 hdd_deinit_adapter( pHddCtx, pAdapter );
7224 memset(&pAdapter->sessionCtx, 0, sizeof(pAdapter->sessionCtx));
Jeff Johnson295189b2012-06-20 16:38:30 -07007225 pAdapter->device_mode = (type == NL80211_IFTYPE_AP) ?
7226 WLAN_HDD_SOFTAP : WLAN_HDD_P2P_GO;
Madan Mohan Koyyalamudi96797442013-10-08 16:04:42 +05307227#ifdef FEATURE_WLAN_TDLS
7228 mutex_unlock(&pHddCtx->tdls_lock);
7229#endif
Madan Mohan Koyyalamudi3ff2a0b2012-10-15 14:33:46 -07007230 if ((WLAN_HDD_SOFTAP == pAdapter->device_mode) &&
7231 (pConfig->apRandomBssidEnabled))
7232 {
7233 /* To meet Android requirements create a randomized
7234 MAC address of the form 02:1A:11:Fx:xx:xx */
7235 get_random_bytes(&ndev->dev_addr[3], 3);
7236 ndev->dev_addr[0] = 0x02;
7237 ndev->dev_addr[1] = 0x1A;
7238 ndev->dev_addr[2] = 0x11;
7239 ndev->dev_addr[3] |= 0xF0;
7240 memcpy(pAdapter->macAddressCurrent.bytes, ndev->dev_addr,
7241 VOS_MAC_ADDR_SIZE);
Arif Hussain24bafea2013-11-15 15:10:03 -08007242 pr_info("wlan: Generated HotSpot BSSID " MAC_ADDRESS_STR"\n",
7243 MAC_ADDR_ARRAY(ndev->dev_addr));
Madan Mohan Koyyalamudi3ff2a0b2012-10-15 14:33:46 -07007244 }
7245
Jeff Johnson295189b2012-06-20 16:38:30 -07007246 hdd_set_ap_ops( pAdapter->dev );
7247
Kiet Lam10841362013-11-01 11:36:50 +05307248 /* This is for only SAP mode where users can
7249 * control country through ini.
7250 * P2P GO follows station country code
7251 * acquired during the STA scanning. */
7252 if((NL80211_IFTYPE_AP == type) &&
7253 (memcmp(pConfig->apCntryCode, CFG_AP_COUNTRY_CODE_DEFAULT, 3) != 0))
7254 {
7255 int status = 0;
7256 VOS_TRACE(VOS_MODULE_ID_HDD,VOS_TRACE_LEVEL_INFO,
7257 "%s: setting country code from INI ", __func__);
7258 init_completion(&pAdapter->change_country_code);
7259 status = (int)sme_ChangeCountryCode(pHddCtx->hHal,
7260 (void *)(tSmeChangeCountryCallback)
7261 wlan_hdd_change_country_code_cb,
7262 pConfig->apCntryCode, pAdapter,
7263 pHddCtx->pvosContext,
Abhishek Singha306a442013-11-07 18:39:01 +05307264 eSIR_FALSE,
7265 eSIR_TRUE);
Kiet Lam10841362013-11-01 11:36:50 +05307266 if (eHAL_STATUS_SUCCESS == status)
7267 {
7268 /* Wait for completion */
c_hpothu6ff1c3c2013-10-01 19:01:57 +05307269 ret = wait_for_completion_interruptible_timeout(
Kiet Lam10841362013-11-01 11:36:50 +05307270 &pAdapter->change_country_code,
7271 msecs_to_jiffies(WLAN_WAIT_TIME_COUNTRY));
c_hpothu6ff1c3c2013-10-01 19:01:57 +05307272 if (ret <= 0)
Kiet Lam10841362013-11-01 11:36:50 +05307273 {
7274 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
c_hpothu6ff1c3c2013-10-01 19:01:57 +05307275 FL("SME Timed out while setting country code %ld"),
7276 ret);
Yue Ma4f55ef32014-01-23 16:45:33 -08007277
7278 if (pHddCtx->isLogpInProgress)
7279 {
7280 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
7281 "%s: LOGP in Progress. Ignore!!!", __func__);
7282 return -EAGAIN;
7283 }
Kiet Lam10841362013-11-01 11:36:50 +05307284 }
7285 }
7286 else
7287 {
7288 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Arif Hussain6d2a3322013-11-17 19:50:10 -08007289 "%s: SME Change Country code failed",__func__);
Kiet Lam10841362013-11-01 11:36:50 +05307290 return -EINVAL;
7291 }
7292 }
Jeff Johnson295189b2012-06-20 16:38:30 -07007293 status = hdd_init_ap_mode(pAdapter);
7294 if(status != VOS_STATUS_SUCCESS)
7295 {
7296 hddLog(VOS_TRACE_LEVEL_FATAL,
7297 "%s: Error initializing the ap mode", __func__);
7298 return -EINVAL;
7299 }
7300 hdd_set_conparam(1);
7301
Jeff Johnson295189b2012-06-20 16:38:30 -07007302 /*interface type changed update in wiphy structure*/
7303 if(wdev)
7304 {
7305 wdev->iftype = type;
7306 pHddCtx->change_iface = type;
7307 }
7308 else
7309 {
7310 hddLog(VOS_TRACE_LEVEL_ERROR,
7311 "%s: ERROR !!!! Wireless dev is NULL", __func__);
7312 return -EINVAL;
7313 }
7314 goto done;
7315 }
7316
7317 default:
7318 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Unsupported interface Type",
7319 __func__);
7320 return -EOPNOTSUPP;
7321 }
7322 }
7323 else if ( (pAdapter->device_mode == WLAN_HDD_SOFTAP)
Jeff Johnson295189b2012-06-20 16:38:30 -07007324 || (pAdapter->device_mode == WLAN_HDD_P2P_GO)
Jeff Johnson295189b2012-06-20 16:38:30 -07007325 )
7326 {
7327 switch(type)
7328 {
7329 case NL80211_IFTYPE_STATION:
Jeff Johnson295189b2012-06-20 16:38:30 -07007330 case NL80211_IFTYPE_P2P_CLIENT:
Jeff Johnson295189b2012-06-20 16:38:30 -07007331 case NL80211_IFTYPE_ADHOC:
Deepthi Gowri500fc472014-08-11 19:53:10 +05307332
7333 hdd_stop_adapter( pHddCtx, pAdapter, VOS_TRUE );
Madan Mohan Koyyalamudi96797442013-10-08 16:04:42 +05307334#ifdef FEATURE_WLAN_TDLS
7335
7336 /* A Mutex Lock is introduced while changing the mode to
7337 * protect the concurrent access for the Adapters by TDLS
7338 * module.
7339 */
Rajesh Chauhana34c6e62014-03-25 16:37:58 +05307340 mutex_lock(&pHddCtx->tdls_lock);
Madan Mohan Koyyalamudi96797442013-10-08 16:04:42 +05307341#endif
Jeff Johnson32d95a32012-09-10 13:15:23 -07007342 hdd_deinit_adapter( pHddCtx, pAdapter );
Jeff Johnson295189b2012-06-20 16:38:30 -07007343 wdev->iftype = type;
Gopichand Nakkalaf527dc62012-12-31 16:35:10 -08007344 //Check for sub-string p2p to confirm its a p2p interface
7345 if (NULL != strstr(ndev->name,"p2p"))
Gopichand Nakkala864d3552012-12-31 16:08:51 -08007346 {
7347 pAdapter->device_mode = (type == NL80211_IFTYPE_STATION) ?
7348 WLAN_HDD_P2P_DEVICE : WLAN_HDD_P2P_CLIENT;
7349 }
7350 else
7351 {
7352 pAdapter->device_mode = (type == NL80211_IFTYPE_STATION) ?
Jeff Johnson295189b2012-06-20 16:38:30 -07007353 WLAN_HDD_INFRA_STATION: WLAN_HDD_P2P_CLIENT;
Gopichand Nakkala864d3552012-12-31 16:08:51 -08007354 }
Jeff Johnson295189b2012-06-20 16:38:30 -07007355 hdd_set_conparam(0);
7356 pHddCtx->change_iface = type;
Jeff Johnson295189b2012-06-20 16:38:30 -07007357 memset(&pAdapter->sessionCtx, 0, sizeof(pAdapter->sessionCtx));
7358 hdd_set_station_ops( pAdapter->dev );
Madan Mohan Koyyalamudi96797442013-10-08 16:04:42 +05307359#ifdef FEATURE_WLAN_TDLS
7360 mutex_unlock(&pHddCtx->tdls_lock);
7361#endif
Sunil Dutt66485cb2013-12-19 19:05:03 +05307362 status = hdd_init_station_mode( pAdapter );
Jeff Johnson295189b2012-06-20 16:38:30 -07007363 if( VOS_STATUS_SUCCESS != status )
7364 return -EOPNOTSUPP;
Jeff Johnsone7245742012-09-05 17:12:55 -07007365 /* In case of JB, for P2P-GO, only change interface will be called,
7366 * This is the right place to enable back bmps_imps()
7367 */
Gopichand Nakkalaa2fe5b02013-06-06 16:32:28 +05307368 if (pHddCtx->hdd_wlan_suspended)
7369 {
7370 hdd_set_pwrparams(pHddCtx);
7371 }
Jeff Johnsone7245742012-09-05 17:12:55 -07007372 hdd_enable_bmps_imps(pHddCtx);
Jeff Johnson295189b2012-06-20 16:38:30 -07007373 goto done;
7374 case NL80211_IFTYPE_AP:
Jeff Johnson295189b2012-06-20 16:38:30 -07007375 case NL80211_IFTYPE_P2P_GO:
Jeff Johnson295189b2012-06-20 16:38:30 -07007376 wdev->iftype = type;
Jeff Johnson295189b2012-06-20 16:38:30 -07007377 pAdapter->device_mode = (type == NL80211_IFTYPE_AP) ?
7378 WLAN_HDD_SOFTAP : WLAN_HDD_P2P_GO;
Jeff Johnson295189b2012-06-20 16:38:30 -07007379 goto done;
7380 default:
7381 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Unsupported interface Type",
7382 __func__);
7383 return -EOPNOTSUPP;
7384
7385 }
7386
7387 }
7388 else
7389 {
Sushant Kaushik8bc7df22014-04-09 17:55:29 +05307390 hddLog(VOS_TRACE_LEVEL_ERROR,"%s: unsupported device mode(%s (%d))",
7391 __func__, hdd_device_modetoString(pAdapter->device_mode),
7392 pAdapter->device_mode);
Jeff Johnson295189b2012-06-20 16:38:30 -07007393 return -EOPNOTSUPP;
7394 }
7395
7396
7397 if(pRoamProfile)
7398 {
7399 if ( LastBSSType != pRoamProfile->BSSType )
7400 {
7401 /*interface type changed update in wiphy structure*/
7402 wdev->iftype = type;
7403
7404 /*the BSS mode changed, We need to issue disconnect
7405 if connected or in IBSS disconnect state*/
7406 if ( hdd_connGetConnectedBssType(
7407 WLAN_HDD_GET_STATION_CTX_PTR(pAdapter), &connectedBssType ) ||
7408 ( eCSR_BSS_TYPE_START_IBSS == LastBSSType ) )
7409 {
7410 /*need to issue a disconnect to CSR.*/
7411 INIT_COMPLETION(pAdapter->disconnect_comp_var);
7412 if( eHAL_STATUS_SUCCESS ==
7413 sme_RoamDisconnect( WLAN_HDD_GET_HAL_CTX(pAdapter),
7414 pAdapter->sessionId,
7415 eCSR_DISCONNECT_REASON_UNSPECIFIED ) )
7416 {
c_hpothu6ff1c3c2013-10-01 19:01:57 +05307417 ret = wait_for_completion_interruptible_timeout(
7418 &pAdapter->disconnect_comp_var,
7419 msecs_to_jiffies(WLAN_WAIT_TIME_DISCONNECT));
7420 if (ret <= 0)
7421 {
7422 hddLog(VOS_TRACE_LEVEL_ERROR,
7423 FL("wait on disconnect_comp_var failed %ld"), ret);
7424 }
Jeff Johnson295189b2012-06-20 16:38:30 -07007425 }
7426 }
7427 }
7428 }
7429
7430done:
7431 /*set bitmask based on updated value*/
7432 wlan_hdd_set_concurrency_mode(pHddCtx, pAdapter->device_mode);
Leo Chang6fe1f922013-06-07 19:21:24 -07007433
7434 /* Only STA mode support TM now
7435 * all other mode, TM feature should be disabled */
7436 if ( (pHddCtx->cfg_ini->thermalMitigationEnable) &&
7437 (~VOS_STA & pHddCtx->concurrency_mode) )
7438 {
7439 hddDevTmLevelChangedHandler(pHddCtx->parent_dev, 0);
7440 }
7441
Jeff Johnson295189b2012-06-20 16:38:30 -07007442#ifdef WLAN_BTAMP_FEATURE
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307443 if((NL80211_IFTYPE_STATION == type) && (pHddCtx->concurrency_mode <= 1) &&
Agarwal Ashish51325b52014-06-16 16:50:49 +05307444 (pHddCtx->no_of_open_sessions[WLAN_HDD_INFRA_STATION] <=1))
Jeff Johnson295189b2012-06-20 16:38:30 -07007445 {
7446 //we are ok to do AMP
7447 pHddCtx->isAmpAllowed = VOS_TRUE;
7448 }
7449#endif //WLAN_BTAMP_FEATURE
7450 EXIT();
7451 return 0;
7452}
7453
Mahesh A Saptasagar0e59c472014-04-14 19:17:41 +05307454/*
7455 * FUNCTION: wlan_hdd_cfg80211_change_iface
7456 * wrapper function to protect the actual implementation from SSR.
7457 */
7458int wlan_hdd_cfg80211_change_iface( struct wiphy *wiphy,
7459 struct net_device *ndev,
7460 enum nl80211_iftype type,
7461 u32 *flags,
7462 struct vif_params *params
7463 )
7464{
7465 int ret;
7466
7467 vos_ssr_protect(__func__);
7468 ret = __wlan_hdd_cfg80211_change_iface(wiphy, ndev, type, flags, params);
7469 vos_ssr_unprotect(__func__);
7470
7471 return ret;
7472}
7473
Gopichand Nakkala681989c2013-03-06 22:27:48 -08007474#ifdef FEATURE_WLAN_TDLS
7475static int wlan_hdd_tdls_add_station(struct wiphy *wiphy,
7476 struct net_device *dev, u8 *mac, bool update, tCsrStaParams *StaParams)
7477{
7478 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
7479 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
7480 VOS_STATUS status;
Hoonki Lee5305c3a2013-04-29 23:28:59 -07007481 hddTdlsPeer_t *pTdlsPeer;
c_hpothu6ff1c3c2013-10-01 19:01:57 +05307482 long ret;
Rajesh Chauhana34c6e62014-03-25 16:37:58 +05307483 tANI_U16 numCurrTdlsPeers;
Gopichand Nakkala681989c2013-03-06 22:27:48 -08007484
7485 ENTER();
7486
Gopichand Nakkala838be5d2013-04-10 22:41:51 +05307487 if (NULL == pHddCtx || NULL == pHddCtx->cfg_ini)
Gopichand Nakkala681989c2013-03-06 22:27:48 -08007488 {
7489 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
7490 "Invalid arguments");
7491 return -EINVAL;
7492 }
Hoonki Lee27511902013-03-14 18:19:06 -07007493
7494 if ((eTDLS_SUPPORT_NOT_ENABLED == pHddCtx->tdls_mode) ||
7495 (eTDLS_SUPPORT_DISABLED == pHddCtx->tdls_mode))
7496 {
7497 VOS_TRACE( VOS_MODULE_ID_HDD, TDLS_LOG_LEVEL,
7498 "%s: TDLS mode is disabled OR not enabled in FW."
7499 MAC_ADDRESS_STR " Request declined.",
7500 __func__, MAC_ADDR_ARRAY(mac));
7501 return -ENOTSUPP;
7502 }
7503
Gopichand Nakkala681989c2013-03-06 22:27:48 -08007504 if (pHddCtx->isLogpInProgress)
7505 {
7506 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
7507 "%s:LOGP in Progress. Ignore!!!", __func__);
Atul Mittal115287b2014-07-08 13:26:33 +05307508 wlan_hdd_tdls_set_link_status(pAdapter,
7509 mac,
7510 eTDLS_LINK_IDLE,
7511 eTDLS_LINK_UNSPECIFIED);
Gopichand Nakkala681989c2013-03-06 22:27:48 -08007512 return -EBUSY;
7513 }
7514
Naresh Jayaram9c6f4462014-02-13 12:20:31 +05307515 pTdlsPeer = wlan_hdd_tdls_get_peer(pAdapter, mac);
Hoonki Lee5305c3a2013-04-29 23:28:59 -07007516
7517 if ( NULL == pTdlsPeer ) {
7518 VOS_TRACE( VOS_MODULE_ID_HDD, TDLS_LOG_LEVEL,
7519 "%s: " MAC_ADDRESS_STR " (update %d) not exist. return invalid",
7520 __func__, MAC_ADDR_ARRAY(mac), update);
7521 return -EINVAL;
Gopichand Nakkala34d1b062013-03-19 15:28:33 -07007522 }
Hoonki Lee5305c3a2013-04-29 23:28:59 -07007523
7524 /* in add station, we accept existing valid staId if there is */
7525 if ((0 == update) &&
7526 ((pTdlsPeer->link_status >= eTDLS_LINK_CONNECTING) ||
7527 (TDLS_STA_INDEX_VALID(pTdlsPeer->staId))))
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -07007528 {
Hoonki Lee5305c3a2013-04-29 23:28:59 -07007529 VOS_TRACE( VOS_MODULE_ID_HDD, TDLS_LOG_LEVEL,
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -07007530 "%s: " MAC_ADDRESS_STR
Hoonki Lee5305c3a2013-04-29 23:28:59 -07007531 " link_status %d. staId %d. add station ignored.",
7532 __func__, MAC_ADDR_ARRAY(mac), pTdlsPeer->link_status, pTdlsPeer->staId);
7533 return 0;
7534 }
7535 /* in change station, we accept only when staId is valid */
7536 if ((1 == update) &&
7537 ((pTdlsPeer->link_status > eTDLS_LINK_CONNECTING) ||
7538 (!TDLS_STA_INDEX_VALID(pTdlsPeer->staId))))
7539 {
7540 VOS_TRACE( VOS_MODULE_ID_HDD, TDLS_LOG_LEVEL,
7541 "%s: " MAC_ADDRESS_STR
7542 " link status %d. staId %d. change station %s.",
7543 __func__, MAC_ADDR_ARRAY(mac), pTdlsPeer->link_status, pTdlsPeer->staId,
7544 (TDLS_STA_INDEX_VALID(pTdlsPeer->staId)) ? "ignored" : "declined");
7545 return (TDLS_STA_INDEX_VALID(pTdlsPeer->staId)) ? 0 : -EPERM;
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -07007546 }
Gopichand Nakkala34d1b062013-03-19 15:28:33 -07007547
7548 /* when others are on-going, we want to change link_status to idle */
Madan Mohan Koyyalamudi96797442013-10-08 16:04:42 +05307549 if (NULL != wlan_hdd_tdls_is_progress(pHddCtx, mac, TRUE))
Gopichand Nakkala681989c2013-03-06 22:27:48 -08007550 {
Gopichand Nakkalac87400e2013-03-13 18:51:00 -07007551 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
7552 "%s: " MAC_ADDRESS_STR
7553 " TDLS setup is ongoing. Request declined.",
7554 __func__, MAC_ADDR_ARRAY(mac));
Gopichand Nakkala05922802013-03-14 12:23:19 -07007555 goto error;
Gopichand Nakkala681989c2013-03-06 22:27:48 -08007556 }
7557
7558 /* first to check if we reached to maximum supported TDLS peer.
7559 TODO: for now, return -EPERM looks working fine,
7560 but need to check if any other errno fit into this category.*/
Rajesh Chauhana34c6e62014-03-25 16:37:58 +05307561 numCurrTdlsPeers = wlan_hdd_tdlsConnectedPeers(pAdapter);
7562 if (HDD_MAX_NUM_TDLS_STA <= numCurrTdlsPeers)
Gopichand Nakkala681989c2013-03-06 22:27:48 -08007563 {
Gopichand Nakkalac87400e2013-03-13 18:51:00 -07007564 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
7565 "%s: " MAC_ADDRESS_STR
Rajesh Chauhana34c6e62014-03-25 16:37:58 +05307566 " TDLS Max peer already connected. Request declined."
7567 " Num of peers (%d), Max allowed (%d).",
7568 __func__, MAC_ADDR_ARRAY(mac), numCurrTdlsPeers,
7569 HDD_MAX_NUM_TDLS_STA);
Gopichand Nakkala05922802013-03-14 12:23:19 -07007570 goto error;
Gopichand Nakkala681989c2013-03-06 22:27:48 -08007571 }
7572 else
7573 {
7574 hddTdlsPeer_t *pTdlsPeer;
Madan Mohan Koyyalamudi96797442013-10-08 16:04:42 +05307575 pTdlsPeer = wlan_hdd_tdls_find_peer(pAdapter, mac, TRUE);
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -07007576 if (pTdlsPeer && TDLS_IS_CONNECTED(pTdlsPeer))
Gopichand Nakkala681989c2013-03-06 22:27:48 -08007577 {
Gopichand Nakkalac87400e2013-03-13 18:51:00 -07007578 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
7579 "%s: " MAC_ADDRESS_STR " already connected. Request declined.",
7580 __func__, MAC_ADDR_ARRAY(mac));
Gopichand Nakkala681989c2013-03-06 22:27:48 -08007581 return -EPERM;
7582 }
7583 }
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -07007584 if (0 == update)
Atul Mittal115287b2014-07-08 13:26:33 +05307585 wlan_hdd_tdls_set_link_status(pAdapter,
7586 mac,
7587 eTDLS_LINK_CONNECTING,
7588 eTDLS_LINK_SUCCESS);
Gopichand Nakkala681989c2013-03-06 22:27:48 -08007589
Jeff Johnsond75fe012013-04-06 10:53:06 -07007590 /* debug code */
Gopichand Nakkala838be5d2013-04-10 22:41:51 +05307591 if (NULL != StaParams)
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -07007592 {
7593 VOS_TRACE(VOS_MODULE_ID_HDD, TDLS_LOG_LEVEL,
7594 "%s: TDLS Peer Parameters.", __func__);
Hoonki Lee66b75f32013-04-16 18:30:07 -07007595 if(StaParams->htcap_present)
7596 {
7597 VOS_TRACE(VOS_MODULE_ID_HDD, TDLS_LOG_LEVEL,
7598 "ht_capa->cap_info: %0x", StaParams->HTCap.capInfo);
7599 VOS_TRACE(VOS_MODULE_ID_HDD, TDLS_LOG_LEVEL,
7600 "ht_capa->extended_capabilities: %0x",
7601 StaParams->HTCap.extendedHtCapInfo);
7602 }
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -07007603 VOS_TRACE(VOS_MODULE_ID_HDD, TDLS_LOG_LEVEL,
7604 "params->capability: %0x",StaParams->capability);
7605 VOS_TRACE(VOS_MODULE_ID_HDD, TDLS_LOG_LEVEL,
Jeff Johnson0299d0a2013-10-30 12:37:43 -07007606 "params->ext_capab_len: %0x",StaParams->extn_capability[0]);
Hoonki Lee66b75f32013-04-16 18:30:07 -07007607 if(StaParams->vhtcap_present)
7608 {
7609 VOS_TRACE(VOS_MODULE_ID_HDD, TDLS_LOG_LEVEL,
7610 "rxMcsMap %x rxHighest %x txMcsMap %x txHighest %x",
7611 StaParams->VHTCap.suppMcs.rxMcsMap, StaParams->VHTCap.suppMcs.rxHighest,
7612 StaParams->VHTCap.suppMcs.txMcsMap, StaParams->VHTCap.suppMcs.txHighest);
7613 }
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -07007614 {
7615 int i = 0;
Hoonki Lee5305c3a2013-04-29 23:28:59 -07007616 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO, "Supported rates:");
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -07007617 for (i = 0; i < sizeof(StaParams->supported_rates); i++)
7618 VOS_TRACE(VOS_MODULE_ID_HDD, TDLS_LOG_LEVEL,
7619 "[%d]: %x ", i, StaParams->supported_rates[i]);
7620 }
Jeff Johnsond75fe012013-04-06 10:53:06 -07007621 } /* end debug code */
Gopichand Nakkala838be5d2013-04-10 22:41:51 +05307622 else if ((1 == update) && (NULL == StaParams))
7623 {
7624 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
7625 "%s : update is true, but staParams is NULL. Error!", __func__);
7626 return -EPERM;
7627 }
Gopichand Nakkala681989c2013-03-06 22:27:48 -08007628
7629 INIT_COMPLETION(pAdapter->tdls_add_station_comp);
7630
7631 if (!update)
7632 {
7633 status = sme_AddTdlsPeerSta(WLAN_HDD_GET_HAL_CTX(pAdapter),
7634 pAdapter->sessionId, mac);
7635 }
7636 else
7637 {
7638 status = sme_ChangeTdlsPeerSta(WLAN_HDD_GET_HAL_CTX(pAdapter),
7639 pAdapter->sessionId, mac, StaParams);
7640 }
7641
c_hpothu6ff1c3c2013-10-01 19:01:57 +05307642 ret = wait_for_completion_interruptible_timeout(&pAdapter->tdls_add_station_comp,
Gopichand Nakkala681989c2013-03-06 22:27:48 -08007643 msecs_to_jiffies(WAIT_TIME_TDLS_ADD_STA));
7644
c_hpothu6ff1c3c2013-10-01 19:01:57 +05307645 if (ret <= 0)
Gopichand Nakkala681989c2013-03-06 22:27:48 -08007646 {
Gopichand Nakkalac87400e2013-03-13 18:51:00 -07007647 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
c_hpothu6ff1c3c2013-10-01 19:01:57 +05307648 "%s: timeout waiting for tdls add station indication %ld",
7649 __func__, ret);
Gopichand Nakkala34d1b062013-03-19 15:28:33 -07007650 return -EPERM;
Gopichand Nakkala681989c2013-03-06 22:27:48 -08007651 }
c_hpothu6ff1c3c2013-10-01 19:01:57 +05307652
Gopichand Nakkala681989c2013-03-06 22:27:48 -08007653 if ( eHAL_STATUS_SUCCESS != pAdapter->tdlsAddStaStatus)
7654 {
Gopichand Nakkalac87400e2013-03-13 18:51:00 -07007655 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Gopichand Nakkala681989c2013-03-06 22:27:48 -08007656 "%s: Add Station is unsucessful", __func__);
Gopichand Nakkala34d1b062013-03-19 15:28:33 -07007657 return -EPERM;
Gopichand Nakkala681989c2013-03-06 22:27:48 -08007658 }
7659
7660 return 0;
Gopichand Nakkala05922802013-03-14 12:23:19 -07007661
7662error:
Atul Mittal115287b2014-07-08 13:26:33 +05307663 wlan_hdd_tdls_set_link_status(pAdapter,
7664 mac,
7665 eTDLS_LINK_IDLE,
7666 eTDLS_LINK_UNSPECIFIED);
Gopichand Nakkala05922802013-03-14 12:23:19 -07007667 return -EPERM;
7668
Gopichand Nakkala681989c2013-03-06 22:27:48 -08007669}
7670#endif
7671
Jeff Johnson295189b2012-06-20 16:38:30 -07007672static int wlan_hdd_change_station(struct wiphy *wiphy,
7673 struct net_device *dev,
7674 u8 *mac,
7675 struct station_parameters *params)
7676{
7677 VOS_STATUS status = VOS_STATUS_SUCCESS;
7678 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( dev );
Gopichand Nakkala29149562013-05-10 21:43:41 +05307679 hdd_context_t *pHddCtx;
7680 hdd_station_ctx_t *pHddStaCtx;
Jeff Johnson295189b2012-06-20 16:38:30 -07007681 v_MACADDR_t STAMacAddress;
Gopichand Nakkalab0856222013-03-12 22:39:05 -07007682#ifdef FEATURE_WLAN_TDLS
Gopichand Nakkala681989c2013-03-06 22:27:48 -08007683 tCsrStaParams StaParams = {0};
Gopichand Nakkala681989c2013-03-06 22:27:48 -08007684 tANI_U8 isBufSta = 0;
Naresh Jayaram3180aa42014-02-12 21:47:26 +05307685 tANI_U8 isOffChannelSupported = 0;
Gopichand Nakkalab0856222013-03-12 22:39:05 -07007686#endif
Jeff Johnsone7245742012-09-05 17:12:55 -07007687 ENTER();
7688
Gopichand Nakkala29149562013-05-10 21:43:41 +05307689 if ((NULL == pAdapter))
7690 {
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +05307691 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
Gopichand Nakkala29149562013-05-10 21:43:41 +05307692 "invalid adapter ");
7693 return -EINVAL;
7694 }
7695
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05307696 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
7697 TRACE_CODE_HDD_CHANGE_STATION,
7698 pAdapter->sessionId, params->listen_interval));
Gopichand Nakkala29149562013-05-10 21:43:41 +05307699 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
7700 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
7701
7702 if ((NULL == pHddCtx) || (NULL == pHddStaCtx))
7703 {
7704 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
7705 "invalid HDD state or HDD station context");
7706 return -EINVAL;
7707 }
7708
7709 if (pHddCtx->isLogpInProgress)
Jeff Johnson04dd8a82012-06-29 20:41:40 -07007710 {
7711 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
7712 "%s:LOGP in Progress. Ignore!!!", __func__);
7713 return -EAGAIN;
7714 }
7715
Jeff Johnson295189b2012-06-20 16:38:30 -07007716 vos_mem_copy(STAMacAddress.bytes, mac, sizeof(v_MACADDR_t));
7717
Gopichand Nakkala681989c2013-03-06 22:27:48 -08007718 if ((pAdapter->device_mode == WLAN_HDD_SOFTAP)
7719 || (pAdapter->device_mode == WLAN_HDD_P2P_GO))
Jeff Johnson295189b2012-06-20 16:38:30 -07007720 {
Gopichand Nakkala681989c2013-03-06 22:27:48 -08007721 if (params->sta_flags_set & BIT(NL80211_STA_FLAG_AUTHORIZED))
Jeff Johnson295189b2012-06-20 16:38:30 -07007722 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307723 status = hdd_softap_change_STA_state( pAdapter, &STAMacAddress,
Jeff Johnson295189b2012-06-20 16:38:30 -07007724 WLANTL_STA_AUTHENTICATED);
7725
Gopichand Nakkala29149562013-05-10 21:43:41 +05307726 if (status != VOS_STATUS_SUCCESS)
7727 {
7728 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
7729 "%s: Not able to change TL state to AUTHENTICATED", __func__);
7730 return -EINVAL;
7731 }
Jeff Johnson295189b2012-06-20 16:38:30 -07007732 }
7733 }
Hoonki Leea6d49be2013-04-05 09:43:25 -07007734 else if ((pAdapter->device_mode == WLAN_HDD_INFRA_STATION)
7735 || (pAdapter->device_mode == WLAN_HDD_P2P_CLIENT)) {
Gopichand Nakkala29149562013-05-10 21:43:41 +05307736#ifdef FEATURE_WLAN_TDLS
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -07007737 if (params->sta_flags_set & BIT(NL80211_STA_FLAG_TDLS_PEER)) {
7738 StaParams.capability = params->capability;
7739 StaParams.uapsd_queues = params->uapsd_queues;
7740 StaParams.max_sp = params->max_sp;
7741
Naresh Jayaram3180aa42014-02-12 21:47:26 +05307742 /* Convert (first channel , number of channels) tuple to
7743 * the total list of channels. This goes with the assumption
7744 * that if the first channel is < 14, then the next channels
7745 * are an incremental of 1 else an incremental of 4 till the number
7746 * of channels.
7747 */
7748 if (0 != params->supported_channels_len) {
7749 int i = 0,j = 0,k = 0, no_of_channels = 0 ;
7750 for ( i = 0 ; i < params->supported_channels_len ; i+=2)
7751 {
7752 int wifi_chan_index;
7753 StaParams.supported_channels[j] = params->supported_channels[i];
7754 wifi_chan_index =
7755 ((StaParams.supported_channels[j] <= HDD_CHANNEL_14 ) ? 1 : 4 );
7756 no_of_channels = params->supported_channels[i+1];
7757 for(k=1; k <= no_of_channels; k++)
7758 {
7759 StaParams.supported_channels[j+1] =
7760 StaParams.supported_channels[j] + wifi_chan_index;
7761 j+=1;
7762 }
7763 }
7764 StaParams.supported_channels_len = j;
7765 }
7766 vos_mem_copy(StaParams.supported_oper_classes,
7767 params->supported_oper_classes,
7768 params->supported_oper_classes_len);
7769 StaParams.supported_oper_classes_len =
7770 params->supported_oper_classes_len;
7771
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -07007772 if (0 != params->ext_capab_len)
7773 vos_mem_copy(StaParams.extn_capability, params->ext_capab,
7774 sizeof(StaParams.extn_capability));
7775
7776 if (NULL != params->ht_capa)
Hoonki Lee66b75f32013-04-16 18:30:07 -07007777 {
7778 StaParams.htcap_present = 1;
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -07007779 vos_mem_copy(&StaParams.HTCap, params->ht_capa, sizeof(tSirHTCap));
Hoonki Lee66b75f32013-04-16 18:30:07 -07007780 }
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -07007781
7782 StaParams.supported_rates_len = params->supported_rates_len;
7783
7784 /* Note : The Maximum sizeof supported_rates sent by the Supplicant is 32.
7785 * The supported_rates array , for all the structures propogating till Add Sta
7786 * to the firmware has to be modified , if the supplicant (ieee80211) is
7787 * modified to send more rates.
7788 */
7789
7790 /* To avoid Data Currption , set to max length to SIR_MAC_MAX_SUPP_RATES
7791 */
7792 if (StaParams.supported_rates_len > SIR_MAC_MAX_SUPP_RATES)
7793 StaParams.supported_rates_len = SIR_MAC_MAX_SUPP_RATES;
7794
7795 if (0 != StaParams.supported_rates_len) {
7796 int i = 0;
7797 vos_mem_copy(StaParams.supported_rates, params->supported_rates,
7798 StaParams.supported_rates_len);
Hoonki Lee5305c3a2013-04-29 23:28:59 -07007799 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -07007800 "Supported Rates with Length %d", StaParams.supported_rates_len);
7801 for (i=0; i < StaParams.supported_rates_len; i++)
Hoonki Lee5305c3a2013-04-29 23:28:59 -07007802 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -07007803 "[%d]: %0x", i, StaParams.supported_rates[i]);
7804 }
7805
7806 if (NULL != params->vht_capa)
Hoonki Lee66b75f32013-04-16 18:30:07 -07007807 {
7808 StaParams.vhtcap_present = 1;
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -07007809 vos_mem_copy(&StaParams.VHTCap, params->vht_capa, sizeof(tSirVHTCap));
Hoonki Lee66b75f32013-04-16 18:30:07 -07007810 }
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -07007811
Gopichand Nakkala681989c2013-03-06 22:27:48 -08007812 if (0 != params->ext_capab_len ) {
7813 /*Define A Macro : TODO Sunil*/
7814 if ((1<<4) & StaParams.extn_capability[3]) {
7815 isBufSta = 1;
7816 }
Naresh Jayaram3180aa42014-02-12 21:47:26 +05307817 /* TDLS Channel Switching Support */
7818 if ((1<<6) & StaParams.extn_capability[3]) {
7819 isOffChannelSupported = 1;
7820 }
Gopichand Nakkala681989c2013-03-06 22:27:48 -08007821 }
Naresh Jayaram3180aa42014-02-12 21:47:26 +05307822 status = wlan_hdd_tdls_set_peer_caps( pAdapter, mac,
7823 &StaParams, isBufSta,
7824 isOffChannelSupported);
7825
Gopichand Nakkala79ff85d2013-05-27 17:05:29 +05307826 if (VOS_STATUS_SUCCESS != status) {
7827 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
7828 "%s: wlan_hdd_tdls_set_peer_caps failed!", __func__);
7829 return -EINVAL;
7830 }
Gopichand Nakkala681989c2013-03-06 22:27:48 -08007831 status = wlan_hdd_tdls_add_station(wiphy, dev, mac, 1, &StaParams);
7832
7833 if (VOS_STATUS_SUCCESS != status) {
7834 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
7835 "%s: sme_ChangeTdlsPeerSta failed!", __func__);
7836 return -EINVAL;
7837 }
7838 }
Gopichand Nakkalab0856222013-03-12 22:39:05 -07007839#endif
Gopichand Nakkala6239acd2013-06-14 14:48:00 +05307840 }
Jeff Johnsone7245742012-09-05 17:12:55 -07007841 EXIT();
Jeff Johnson295189b2012-06-20 16:38:30 -07007842 return status;
7843}
7844
7845/*
Mahesh A Saptasagar1a51bc02014-06-02 18:28:08 +05307846 * FUNCTION: __wlan_hdd_cfg80211_add_key
Jeff Johnson295189b2012-06-20 16:38:30 -07007847 * This function is used to initialize the key information
7848 */
7849#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
Mahesh A Saptasagar1a51bc02014-06-02 18:28:08 +05307850static int __wlan_hdd_cfg80211_add_key( struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -07007851 struct net_device *ndev,
7852 u8 key_index, bool pairwise,
7853 const u8 *mac_addr,
7854 struct key_params *params
7855 )
7856#else
Mahesh A Saptasagar1a51bc02014-06-02 18:28:08 +05307857static int __wlan_hdd_cfg80211_add_key( struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -07007858 struct net_device *ndev,
7859 u8 key_index, const u8 *mac_addr,
7860 struct key_params *params
7861 )
7862#endif
7863{
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -07007864 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( ndev );
Jeff Johnson295189b2012-06-20 16:38:30 -07007865 tCsrRoamSetKey setKey;
7866 u8 groupmacaddr[WNI_CFG_BSSID_LEN] = {0xFF,0xFF,0xFF,0xFF,0xFF,0xFF};
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05307867 int status;
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -07007868 v_U32_t roamId= 0xFF;
7869 v_CONTEXT_t pVosContext = (WLAN_HDD_GET_CTX(pAdapter))->pvosContext;
Jeff Johnson295189b2012-06-20 16:38:30 -07007870 hdd_hostapd_state_t *pHostapdState;
7871 VOS_STATUS vos_status;
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -07007872 eHalStatus halStatus;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05307873 hdd_context_t *pHddCtx;
Jeff Johnson295189b2012-06-20 16:38:30 -07007874
7875 ENTER();
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +05307876
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05307877 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
7878 TRACE_CODE_HDD_CFG80211_ADD_KEY,
7879 pAdapter->sessionId, params->key_len));
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05307880 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
7881 status = wlan_hdd_validate_context(pHddCtx);
7882
7883 if (0 != status)
Jeff Johnson04dd8a82012-06-29 20:41:40 -07007884 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05307885 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
7886 "%s: HDD context is not valid", __func__);
7887 return status;
Jeff Johnson04dd8a82012-06-29 20:41:40 -07007888 }
7889
Sushant Kaushik8bc7df22014-04-09 17:55:29 +05307890 hddLog(VOS_TRACE_LEVEL_INFO, "%s: device_mode = %s (%d)",
7891 __func__, hdd_device_modetoString(pAdapter->device_mode),
7892 pAdapter->device_mode);
Jeff Johnson295189b2012-06-20 16:38:30 -07007893
7894 if (CSR_MAX_NUM_KEY <= key_index)
7895 {
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -07007896 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Invalid key index %d", __func__,
Jeff Johnson295189b2012-06-20 16:38:30 -07007897 key_index);
7898
7899 return -EINVAL;
7900 }
7901
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -07007902 if (CSR_MAX_KEY_LEN < params->key_len)
7903 {
7904 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Invalid key length %d", __func__,
7905 params->key_len);
7906
7907 return -EINVAL;
7908 }
7909
7910 hddLog(VOS_TRACE_LEVEL_INFO,
7911 "%s: called with key index = %d & key length %d",
7912 __func__, key_index, params->key_len);
Jeff Johnson295189b2012-06-20 16:38:30 -07007913
7914 /*extract key idx, key len and key*/
7915 vos_mem_zero(&setKey,sizeof(tCsrRoamSetKey));
7916 setKey.keyId = key_index;
7917 setKey.keyLength = params->key_len;
7918 vos_mem_copy(&setKey.Key[0],params->key, params->key_len);
7919
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -07007920 switch (params->cipher)
Jeff Johnson295189b2012-06-20 16:38:30 -07007921 {
7922 case WLAN_CIPHER_SUITE_WEP40:
7923 setKey.encType = eCSR_ENCRYPT_TYPE_WEP40_STATICKEY;
7924 break;
7925
7926 case WLAN_CIPHER_SUITE_WEP104:
7927 setKey.encType = eCSR_ENCRYPT_TYPE_WEP104_STATICKEY;
7928 break;
7929
7930 case WLAN_CIPHER_SUITE_TKIP:
7931 {
7932 u8 *pKey = &setKey.Key[0];
7933 setKey.encType = eCSR_ENCRYPT_TYPE_TKIP;
7934
7935 vos_mem_zero(pKey, CSR_MAX_KEY_LEN);
7936
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -07007937 /*Supplicant sends the 32bytes key in this order
Jeff Johnson295189b2012-06-20 16:38:30 -07007938
7939 |--------------|----------|----------|
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -07007940 | Tk1 |TX-MIC | RX Mic |
Jeff Johnson295189b2012-06-20 16:38:30 -07007941 |--------------|----------|----------|
7942 <---16bytes---><--8bytes--><--8bytes-->
7943
7944 */
7945 /*Sme expects the 32 bytes key to be in the below order
7946
7947 |--------------|----------|----------|
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -07007948 | Tk1 |RX-MIC | TX Mic |
Jeff Johnson295189b2012-06-20 16:38:30 -07007949 |--------------|----------|----------|
7950 <---16bytes---><--8bytes--><--8bytes-->
7951 */
7952 /* Copy the Temporal Key 1 (TK1) */
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -07007953 vos_mem_copy(pKey, params->key, 16);
Jeff Johnson295189b2012-06-20 16:38:30 -07007954
7955 /*Copy the rx mic first*/
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -07007956 vos_mem_copy(&pKey[16], &params->key[24], 8);
Jeff Johnson295189b2012-06-20 16:38:30 -07007957
7958 /*Copy the tx mic */
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -07007959 vos_mem_copy(&pKey[24], &params->key[16], 8);
Jeff Johnson295189b2012-06-20 16:38:30 -07007960
7961
7962 break;
7963 }
7964
7965 case WLAN_CIPHER_SUITE_CCMP:
7966 setKey.encType = eCSR_ENCRYPT_TYPE_AES;
7967 break;
7968
7969#ifdef FEATURE_WLAN_WAPI
7970 case WLAN_CIPHER_SUITE_SMS4:
7971 {
7972 vos_mem_zero(&setKey,sizeof(tCsrRoamSetKey));
7973 wlan_hdd_cfg80211_set_key_wapi(pAdapter, key_index, mac_addr,
7974 params->key, params->key_len);
7975 return 0;
7976 }
7977#endif
Chet Lanctot186b5732013-03-18 10:26:30 -07007978
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08007979#ifdef FEATURE_WLAN_ESE
Jeff Johnson295189b2012-06-20 16:38:30 -07007980 case WLAN_CIPHER_SUITE_KRK:
7981 setKey.encType = eCSR_ENCRYPT_TYPE_KRK;
7982 break;
7983#endif
Chet Lanctot186b5732013-03-18 10:26:30 -07007984
7985#ifdef WLAN_FEATURE_11W
7986 case WLAN_CIPHER_SUITE_AES_CMAC:
7987 setKey.encType = eCSR_ENCRYPT_TYPE_AES_CMAC;
Chet Lanctot3b5158a2013-03-31 16:45:21 -07007988 break;
Chet Lanctot186b5732013-03-18 10:26:30 -07007989#endif
7990
Jeff Johnson295189b2012-06-20 16:38:30 -07007991 default:
Jeff Johnson0299d0a2013-10-30 12:37:43 -07007992 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: unsupported cipher type %u",
Jeff Johnson295189b2012-06-20 16:38:30 -07007993 __func__, params->cipher);
Vinay Krishna Eranna6f22c1f2014-10-13 16:03:06 +05307994 status = -EOPNOTSUPP;
7995 goto end;
Jeff Johnson295189b2012-06-20 16:38:30 -07007996 }
7997
7998 hddLog(VOS_TRACE_LEVEL_INFO_MED, "%s: encryption type %d",
7999 __func__, setKey.encType);
8000
Shailender Karmuchi642e9812013-05-30 14:34:49 -07008001 if (
Jeff Johnson295189b2012-06-20 16:38:30 -07008002#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
8003 (!pairwise)
8004#else
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -07008005 (!mac_addr || is_broadcast_ether_addr(mac_addr))
Jeff Johnson295189b2012-06-20 16:38:30 -07008006#endif
Shailender Karmuchi642e9812013-05-30 14:34:49 -07008007 )
8008 {
8009 /* set group key*/
8010 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
8011 "%s- %d: setting Broadcast key",
8012 __func__, __LINE__);
8013 setKey.keyDirection = eSIR_RX_ONLY;
8014 vos_mem_copy(setKey.peerMac,groupmacaddr,WNI_CFG_BSSID_LEN);
8015 }
8016 else
8017 {
8018 /* set pairwise key*/
8019 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
8020 "%s- %d: setting pairwise key",
8021 __func__, __LINE__);
8022 setKey.keyDirection = eSIR_TX_RX;
8023 vos_mem_copy(setKey.peerMac, mac_addr,WNI_CFG_BSSID_LEN);
8024 }
8025 if ((WLAN_HDD_IBSS == pAdapter->device_mode) && !pairwise)
8026 {
8027 setKey.keyDirection = eSIR_TX_RX;
8028 /*Set the group key*/
8029 status = sme_RoamSetKey( WLAN_HDD_GET_HAL_CTX(pAdapter),
8030 pAdapter->sessionId, &setKey, &roamId );
Jeff Johnson295189b2012-06-20 16:38:30 -07008031
Shailender Karmuchi642e9812013-05-30 14:34:49 -07008032 if ( 0 != status )
8033 {
8034 hddLog(VOS_TRACE_LEVEL_ERROR,
8035 "%s: sme_RoamSetKey failed, returned %d", __func__, status);
Vinay Krishna Eranna6f22c1f2014-10-13 16:03:06 +05308036 status = -EINVAL;
8037 goto end;
Shailender Karmuchi642e9812013-05-30 14:34:49 -07008038 }
8039 /*Save the keys here and call sme_RoamSetKey for setting
8040 the PTK after peer joins the IBSS network*/
8041 vos_mem_copy(&pAdapter->sessionCtx.station.ibss_enc_key,
8042 &setKey, sizeof(tCsrRoamSetKey));
Vinay Krishna Eranna6f22c1f2014-10-13 16:03:06 +05308043 goto end;
Shailender Karmuchi642e9812013-05-30 14:34:49 -07008044 }
Gopichand Nakkala29149562013-05-10 21:43:41 +05308045 if ((pAdapter->device_mode == WLAN_HDD_SOFTAP) ||
8046 (pAdapter->device_mode == WLAN_HDD_P2P_GO))
8047 {
Jeff Johnson295189b2012-06-20 16:38:30 -07008048 pHostapdState = WLAN_HDD_GET_HOSTAP_STATE_PTR(pAdapter);
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -07008049 if( pHostapdState->bssState == BSS_START )
8050 {
c_hpothu7c55da62014-01-23 18:34:02 +05308051 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
8052 vos_status = wlan_hdd_check_ula_done(pAdapter);
8053
8054 if ( vos_status != VOS_STATUS_SUCCESS )
8055 {
8056 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
8057 "[%4d] wlan_hdd_check_ula_done returned ERROR status= %d",
8058 __LINE__, vos_status );
8059
8060 pHddStaCtx->roam_info.roamingState = HDD_ROAM_STATE_NONE;
8061
Vinay Krishna Eranna6f22c1f2014-10-13 16:03:06 +05308062 status = -EINVAL;
8063 goto end;
c_hpothu7c55da62014-01-23 18:34:02 +05308064 }
8065
Jeff Johnson295189b2012-06-20 16:38:30 -07008066 status = WLANSAP_SetKeySta( pVosContext, &setKey);
8067
8068 if ( status != eHAL_STATUS_SUCCESS )
8069 {
8070 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
8071 "[%4d] WLANSAP_SetKeySta returned ERROR status= %d",
8072 __LINE__, status );
Vinay Krishna Eranna6f22c1f2014-10-13 16:03:06 +05308073 status = -EINVAL;
8074 goto end;
Jeff Johnson295189b2012-06-20 16:38:30 -07008075 }
8076 }
8077
8078 /* Saving WEP keys */
8079 else if( eCSR_ENCRYPT_TYPE_WEP40_STATICKEY == setKey.encType ||
8080 eCSR_ENCRYPT_TYPE_WEP104_STATICKEY == setKey.encType )
8081 {
8082 //Save the wep key in ap context. Issue setkey after the BSS is started.
8083 hdd_ap_ctx_t *pAPCtx = WLAN_HDD_GET_AP_CTX_PTR(pAdapter);
8084 vos_mem_copy(&pAPCtx->wepKey[key_index], &setKey, sizeof(tCsrRoamSetKey));
8085 }
8086 else
8087 {
8088 //Save the key in ap context. Issue setkey after the BSS is started.
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -07008089 hdd_ap_ctx_t *pAPCtx = WLAN_HDD_GET_AP_CTX_PTR(pAdapter);
Jeff Johnson295189b2012-06-20 16:38:30 -07008090 vos_mem_copy(&pAPCtx->groupKey, &setKey, sizeof(tCsrRoamSetKey));
8091 }
8092 }
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -07008093 else if ( (pAdapter->device_mode == WLAN_HDD_INFRA_STATION) ||
8094 (pAdapter->device_mode == WLAN_HDD_P2P_CLIENT) )
Jeff Johnson295189b2012-06-20 16:38:30 -07008095 {
8096 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
8097 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
8098
Gopichand Nakkala3d295922013-05-07 16:19:14 +05308099#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
8100 if (!pairwise)
8101#else
8102 if (!mac_addr || is_broadcast_ether_addr(mac_addr))
8103#endif
8104 {
8105 /* set group key*/
8106 if (pHddStaCtx->roam_info.deferKeyComplete)
8107 {
8108 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
8109 "%s- %d: Perform Set key Complete",
8110 __func__, __LINE__);
8111 hdd_PerformRoamSetKeyComplete(pAdapter);
8112 }
8113 }
8114
Jeff Johnson295189b2012-06-20 16:38:30 -07008115 pWextState->roamProfile.Keys.KeyLength[key_index] = (u8)params->key_len;
8116
Venkata Prathyusha Kuntupalliee2ce712013-01-17 14:09:24 -08008117 pWextState->roamProfile.Keys.defaultIndex = key_index;
8118
8119
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -07008120 vos_mem_copy(&pWextState->roamProfile.Keys.KeyMaterial[key_index][0],
Jeff Johnson295189b2012-06-20 16:38:30 -07008121 params->key, params->key_len);
8122
Gopichand Nakkala3d295922013-05-07 16:19:14 +05308123
Jeff Johnson295189b2012-06-20 16:38:30 -07008124 pHddStaCtx->roam_info.roamingState = HDD_ROAM_STATE_SETTING_KEY;
8125
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308126 hddLog(VOS_TRACE_LEVEL_INFO_MED,
Jeff Johnson295189b2012-06-20 16:38:30 -07008127 "%s: set key for peerMac %2x:%2x:%2x:%2x:%2x:%2x, direction %d",
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308128 __func__, setKey.peerMac[0], setKey.peerMac[1],
8129 setKey.peerMac[2], setKey.peerMac[3],
8130 setKey.peerMac[4], setKey.peerMac[5],
Jeff Johnson295189b2012-06-20 16:38:30 -07008131 setKey.keyDirection);
8132
8133 vos_status = wlan_hdd_check_ula_done(pAdapter);
8134
8135 if ( vos_status != VOS_STATUS_SUCCESS )
8136 {
8137 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
8138 "[%4d] wlan_hdd_check_ula_done returned ERROR status= %d",
8139 __LINE__, vos_status );
8140
8141 pHddStaCtx->roam_info.roamingState = HDD_ROAM_STATE_NONE;
8142
Vinay Krishna Eranna6f22c1f2014-10-13 16:03:06 +05308143 status = -EINVAL;
8144 goto end;
Jeff Johnson295189b2012-06-20 16:38:30 -07008145
8146 }
8147
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -07008148#ifdef WLAN_FEATURE_VOWIFI_11R
Gopichand Nakkala3d295922013-05-07 16:19:14 +05308149 /* The supplicant may attempt to set the PTK once pre-authentication
8150 is done. Save the key in the UMAC and include it in the ADD BSS
8151 request */
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -07008152 halStatus = sme_FTUpdateKey( WLAN_HDD_GET_HAL_CTX(pAdapter), &setKey);
Gopichand Nakkala3d295922013-05-07 16:19:14 +05308153 if ( halStatus == eHAL_STATUS_FT_PREAUTH_KEY_SUCCESS )
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -07008154 {
Gopichand Nakkala3d295922013-05-07 16:19:14 +05308155 hddLog(VOS_TRACE_LEVEL_INFO_MED,
8156 "%s: Update PreAuth Key success", __func__);
Vinay Krishna Eranna6f22c1f2014-10-13 16:03:06 +05308157 status = 0;
8158 goto end;
Gopichand Nakkala3d295922013-05-07 16:19:14 +05308159 }
8160 else if ( halStatus == eHAL_STATUS_FT_PREAUTH_KEY_FAILED )
8161 {
8162 hddLog(VOS_TRACE_LEVEL_ERROR,
8163 "%s: Update PreAuth Key failed", __func__);
Vinay Krishna Eranna6f22c1f2014-10-13 16:03:06 +05308164 status = -EINVAL;
8165 goto end;
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -07008166 }
8167#endif /* WLAN_FEATURE_VOWIFI_11R */
Jeff Johnson295189b2012-06-20 16:38:30 -07008168
8169 /* issue set key request to SME*/
8170 status = sme_RoamSetKey( WLAN_HDD_GET_HAL_CTX(pAdapter),
8171 pAdapter->sessionId, &setKey, &roamId );
8172
8173 if ( 0 != status )
8174 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308175 hddLog(VOS_TRACE_LEVEL_ERROR,
Jeff Johnson295189b2012-06-20 16:38:30 -07008176 "%s: sme_RoamSetKey failed, returned %d", __func__, status);
8177 pHddStaCtx->roam_info.roamingState = HDD_ROAM_STATE_NONE;
Vinay Krishna Eranna6f22c1f2014-10-13 16:03:06 +05308178 status = -EINVAL;
8179 goto end;
Jeff Johnson295189b2012-06-20 16:38:30 -07008180 }
8181
8182
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308183 /* in case of IBSS as there was no information available about WEP keys during
8184 * IBSS join, group key intialized with NULL key, so re-initialize group key
Jeff Johnson295189b2012-06-20 16:38:30 -07008185 * with correct value*/
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308186 if ( (eCSR_BSS_TYPE_START_IBSS == pWextState->roamProfile.BSSType) &&
8187 !( ( IW_AUTH_KEY_MGMT_802_1X
8188 == (pWextState->authKeyMgmt & IW_AUTH_KEY_MGMT_802_1X))
Jeff Johnson295189b2012-06-20 16:38:30 -07008189 && (eCSR_AUTH_TYPE_OPEN_SYSTEM == pHddStaCtx->conn_info.authType)
8190 )
8191 &&
8192 ( (WLAN_CIPHER_SUITE_WEP40 == params->cipher)
8193 || (WLAN_CIPHER_SUITE_WEP104 == params->cipher)
8194 )
8195 )
8196 {
8197 setKey.keyDirection = eSIR_RX_ONLY;
8198 vos_mem_copy(setKey.peerMac,groupmacaddr,WNI_CFG_BSSID_LEN);
8199
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308200 hddLog(VOS_TRACE_LEVEL_INFO_MED,
Jeff Johnson295189b2012-06-20 16:38:30 -07008201 "%s: set key peerMac %2x:%2x:%2x:%2x:%2x:%2x, direction %d",
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308202 __func__, setKey.peerMac[0], setKey.peerMac[1],
8203 setKey.peerMac[2], setKey.peerMac[3],
8204 setKey.peerMac[4], setKey.peerMac[5],
Jeff Johnson295189b2012-06-20 16:38:30 -07008205 setKey.keyDirection);
8206
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308207 status = sme_RoamSetKey( WLAN_HDD_GET_HAL_CTX(pAdapter),
Jeff Johnson295189b2012-06-20 16:38:30 -07008208 pAdapter->sessionId, &setKey, &roamId );
8209
8210 if ( 0 != status )
8211 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308212 hddLog(VOS_TRACE_LEVEL_ERROR,
8213 "%s: sme_RoamSetKey failed for group key (IBSS), returned %d",
Jeff Johnson295189b2012-06-20 16:38:30 -07008214 __func__, status);
8215 pHddStaCtx->roam_info.roamingState = HDD_ROAM_STATE_NONE;
Vinay Krishna Eranna6f22c1f2014-10-13 16:03:06 +05308216 status = -EINVAL;
8217 goto end;
Jeff Johnson295189b2012-06-20 16:38:30 -07008218 }
8219 }
8220 }
8221
Vinay Krishna Eranna6f22c1f2014-10-13 16:03:06 +05308222end:
8223 /* Need to clear any trace of key value in the memory.
8224 * Thus zero out the memory even though it is local
8225 * variable.
8226 */
8227 vos_mem_zero(&setKey, sizeof(setKey));
8228
8229 return status;
Jeff Johnson295189b2012-06-20 16:38:30 -07008230}
8231
Mahesh A Saptasagar1a51bc02014-06-02 18:28:08 +05308232#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
8233static int wlan_hdd_cfg80211_add_key( struct wiphy *wiphy,
8234 struct net_device *ndev,
8235 u8 key_index, bool pairwise,
8236 const u8 *mac_addr,
8237 struct key_params *params
8238 )
8239#else
8240static int wlan_hdd_cfg80211_add_key( struct wiphy *wiphy,
8241 struct net_device *ndev,
8242 u8 key_index, const u8 *mac_addr,
8243 struct key_params *params
8244 )
8245#endif
8246{
8247 int ret;
8248 vos_ssr_protect(__func__);
8249#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
8250 ret = __wlan_hdd_cfg80211_add_key(wiphy, ndev, key_index, pairwise,
8251 mac_addr, params);
8252#else
8253 ret = __wlan_hdd_cfg80211_add_key(wiphy, ndev, key_index, mac_addr,
8254 params);
8255#endif
8256 vos_ssr_unprotect(__func__);
8257
8258 return ret;
8259}
8260
Jeff Johnson295189b2012-06-20 16:38:30 -07008261/*
Mahesh A Saptasagar1a51bc02014-06-02 18:28:08 +05308262 * FUNCTION: __wlan_hdd_cfg80211_get_key
Jeff Johnson295189b2012-06-20 16:38:30 -07008263 * This function is used to get the key information
8264 */
8265#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
Mahesh A Saptasagar1a51bc02014-06-02 18:28:08 +05308266static int __wlan_hdd_cfg80211_get_key(
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308267 struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -07008268 struct net_device *ndev,
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308269 u8 key_index, bool pairwise,
Jeff Johnson295189b2012-06-20 16:38:30 -07008270 const u8 *mac_addr, void *cookie,
8271 void (*callback)(void *cookie, struct key_params*)
8272 )
8273#else
Mahesh A Saptasagar1a51bc02014-06-02 18:28:08 +05308274static int __wlan_hdd_cfg80211_get_key(
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308275 struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -07008276 struct net_device *ndev,
8277 u8 key_index, const u8 *mac_addr, void *cookie,
8278 void (*callback)(void *cookie, struct key_params*)
8279 )
8280#endif
8281{
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308282 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( ndev );
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +05308283 hdd_wext_state_t *pWextState= WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
8284 tCsrRoamProfile *pRoamProfile = &(pWextState->roamProfile);
Jeff Johnson295189b2012-06-20 16:38:30 -07008285 struct key_params params;
8286
8287 ENTER();
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308288
Sushant Kaushik8bc7df22014-04-09 17:55:29 +05308289 hddLog(VOS_TRACE_LEVEL_INFO, "%s: device_mode = %s (%d)",
8290 __func__, hdd_device_modetoString(pAdapter->device_mode),
8291 pAdapter->device_mode);
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +05308292
Jeff Johnson295189b2012-06-20 16:38:30 -07008293 memset(&params, 0, sizeof(params));
8294
8295 if (CSR_MAX_NUM_KEY <= key_index)
8296 {
c_hpothu6ff1c3c2013-10-01 19:01:57 +05308297 hddLog(VOS_TRACE_LEVEL_ERROR, FL("invalid key index %d"), key_index);
Jeff Johnson295189b2012-06-20 16:38:30 -07008298 return -EINVAL;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308299 }
Jeff Johnson295189b2012-06-20 16:38:30 -07008300
8301 switch(pRoamProfile->EncryptionType.encryptionType[0])
8302 {
8303 case eCSR_ENCRYPT_TYPE_NONE:
8304 params.cipher = IW_AUTH_CIPHER_NONE;
8305 break;
8306
8307 case eCSR_ENCRYPT_TYPE_WEP40_STATICKEY:
8308 case eCSR_ENCRYPT_TYPE_WEP40:
8309 params.cipher = WLAN_CIPHER_SUITE_WEP40;
8310 break;
8311
8312 case eCSR_ENCRYPT_TYPE_WEP104_STATICKEY:
8313 case eCSR_ENCRYPT_TYPE_WEP104:
8314 params.cipher = WLAN_CIPHER_SUITE_WEP104;
8315 break;
8316
8317 case eCSR_ENCRYPT_TYPE_TKIP:
8318 params.cipher = WLAN_CIPHER_SUITE_TKIP;
8319 break;
8320
8321 case eCSR_ENCRYPT_TYPE_AES:
8322 params.cipher = WLAN_CIPHER_SUITE_AES_CMAC;
8323 break;
8324
8325 default:
8326 params.cipher = IW_AUTH_CIPHER_NONE;
8327 break;
8328 }
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +05308329
c_hpothuaaf19692014-05-17 17:01:48 +05308330 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
8331 TRACE_CODE_HDD_CFG80211_GET_KEY,
8332 pAdapter->sessionId, params.cipher));
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +05308333
Jeff Johnson295189b2012-06-20 16:38:30 -07008334 params.key_len = pRoamProfile->Keys.KeyLength[key_index];
8335 params.seq_len = 0;
8336 params.seq = NULL;
8337 params.key = &pRoamProfile->Keys.KeyMaterial[key_index][0];
8338 callback(cookie, &params);
8339 return 0;
8340}
8341
Mahesh A Saptasagar1a51bc02014-06-02 18:28:08 +05308342#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
8343static int wlan_hdd_cfg80211_get_key(
8344 struct wiphy *wiphy,
8345 struct net_device *ndev,
8346 u8 key_index, bool pairwise,
8347 const u8 *mac_addr, void *cookie,
8348 void (*callback)(void *cookie, struct key_params*)
8349 )
8350#else
8351static int wlan_hdd_cfg80211_get_key(
8352 struct wiphy *wiphy,
8353 struct net_device *ndev,
8354 u8 key_index, const u8 *mac_addr, void *cookie,
8355 void (*callback)(void *cookie, struct key_params*)
8356 )
8357#endif
8358{
8359 int ret;
8360
8361 vos_ssr_protect(__func__);
8362#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
8363 ret = __wlan_hdd_cfg80211_get_key(wiphy, ndev, key_index, pairwise,
8364 mac_addr, cookie, callback);
8365#else
8366 ret = __wlan_hdd_cfg80211_get_key(wiphy, ndev, key_index, mac_addr,
8367 callback);
8368#endif
8369 vos_ssr_unprotect(__func__);
8370
8371 return ret;
8372}
8373
Jeff Johnson295189b2012-06-20 16:38:30 -07008374/*
8375 * FUNCTION: wlan_hdd_cfg80211_del_key
8376 * This function is used to delete the key information
8377 */
8378#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308379static int wlan_hdd_cfg80211_del_key( struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -07008380 struct net_device *ndev,
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308381 u8 key_index,
8382 bool pairwise,
Jeff Johnson295189b2012-06-20 16:38:30 -07008383 const u8 *mac_addr
8384 )
8385#else
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308386static int wlan_hdd_cfg80211_del_key( struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -07008387 struct net_device *ndev,
8388 u8 key_index,
8389 const u8 *mac_addr
8390 )
8391#endif
8392{
8393 int status = 0;
8394
8395 //This code needs to be revisited. There is sme_removeKey API, we should
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308396 //plan to use that. After the change to use correct index in setkey,
Jeff Johnson295189b2012-06-20 16:38:30 -07008397 //it is observed that this is invalidating peer
8398 //key index whenever re-key is done. This is affecting data link.
8399 //It should be ok to ignore del_key.
8400#if 0
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308401 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( ndev );
8402 v_CONTEXT_t pVosContext = (WLAN_HDD_GET_CTX(pAdapter))->pvosContext;
Jeff Johnson295189b2012-06-20 16:38:30 -07008403 u8 groupmacaddr[WNI_CFG_BSSID_LEN] = {0xFF,0xFF,0xFF,0xFF,0xFF,0xFF};
8404 tCsrRoamSetKey setKey;
8405 v_U32_t roamId= 0xFF;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308406
Jeff Johnson295189b2012-06-20 16:38:30 -07008407 ENTER();
8408
8409 hddLog(VOS_TRACE_LEVEL_INFO_HIGH, "%s: device_mode = %d\n",
8410 __func__,pAdapter->device_mode);
8411
8412 if (CSR_MAX_NUM_KEY <= key_index)
8413 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308414 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Invalid key index %d", __func__,
Jeff Johnson295189b2012-06-20 16:38:30 -07008415 key_index);
8416
8417 return -EINVAL;
8418 }
8419
8420 vos_mem_zero(&setKey,sizeof(tCsrRoamSetKey));
8421 setKey.keyId = key_index;
8422
8423 if (mac_addr)
8424 vos_mem_copy(setKey.peerMac, mac_addr,WNI_CFG_BSSID_LEN);
8425 else
8426 vos_mem_copy(setKey.peerMac, groupmacaddr, WNI_CFG_BSSID_LEN);
8427
8428 setKey.encType = eCSR_ENCRYPT_TYPE_NONE;
8429
8430 if ((pAdapter->device_mode == WLAN_HDD_SOFTAP)
Jeff Johnson295189b2012-06-20 16:38:30 -07008431 || (pAdapter->device_mode == WLAN_HDD_P2P_GO)
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308432 )
8433 {
8434
8435 hdd_hostapd_state_t *pHostapdState =
Jeff Johnson295189b2012-06-20 16:38:30 -07008436 WLAN_HDD_GET_HOSTAP_STATE_PTR(pAdapter);
8437 if( pHostapdState->bssState == BSS_START)
8438 {
8439 status = WLANSAP_SetKeySta( pVosContext, &setKey);
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308440
Jeff Johnson295189b2012-06-20 16:38:30 -07008441 if ( status != eHAL_STATUS_SUCCESS )
8442 {
8443 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
8444 "[%4d] WLANSAP_SetKeySta returned ERROR status= %d",
8445 __LINE__, status );
8446 }
8447 }
8448 }
8449 else if ( (pAdapter->device_mode == WLAN_HDD_INFRA_STATION)
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308450 || (pAdapter->device_mode == WLAN_HDD_P2P_CLIENT)
Jeff Johnson295189b2012-06-20 16:38:30 -07008451 )
8452 {
8453 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
8454
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308455 pHddStaCtx->roam_info.roamingState = HDD_ROAM_STATE_SETTING_KEY;
8456
8457 hddLog(VOS_TRACE_LEVEL_INFO_MED,
Jeff Johnson295189b2012-06-20 16:38:30 -07008458 "%s: delete key for peerMac %2x:%2x:%2x:%2x:%2x:%2x",
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308459 __func__, setKey.peerMac[0], setKey.peerMac[1],
8460 setKey.peerMac[2], setKey.peerMac[3],
Jeff Johnson295189b2012-06-20 16:38:30 -07008461 setKey.peerMac[4], setKey.peerMac[5]);
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308462 if(pAdapter->sessionCtx.station.conn_info.connState ==
8463 eConnectionState_Associated)
Jeff Johnson295189b2012-06-20 16:38:30 -07008464 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308465 status = sme_RoamSetKey( WLAN_HDD_GET_HAL_CTX(pAdapter),
Jeff Johnson295189b2012-06-20 16:38:30 -07008466 pAdapter->sessionId, &setKey, &roamId );
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308467
Jeff Johnson295189b2012-06-20 16:38:30 -07008468 if ( 0 != status )
8469 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308470 hddLog(VOS_TRACE_LEVEL_ERROR,
Jeff Johnson295189b2012-06-20 16:38:30 -07008471 "%s: sme_RoamSetKey failure, returned %d",
8472 __func__, status);
8473 pHddStaCtx->roam_info.roamingState = HDD_ROAM_STATE_NONE;
8474 return -EINVAL;
8475 }
8476 }
8477 }
8478#endif
Jeff Johnsone7245742012-09-05 17:12:55 -07008479 EXIT();
Jeff Johnson295189b2012-06-20 16:38:30 -07008480 return status;
8481}
8482
8483/*
Mahesh A Saptasagar1a51bc02014-06-02 18:28:08 +05308484 * FUNCTION: __wlan_hdd_cfg80211_set_default_key
Jeff Johnson295189b2012-06-20 16:38:30 -07008485 * This function is used to set the default tx key index
8486 */
8487#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
Mahesh A Saptasagar1a51bc02014-06-02 18:28:08 +05308488static int __wlan_hdd_cfg80211_set_default_key( struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -07008489 struct net_device *ndev,
8490 u8 key_index,
8491 bool unicast, bool multicast)
8492#else
Mahesh A Saptasagar1a51bc02014-06-02 18:28:08 +05308493static int __wlan_hdd_cfg80211_set_default_key( struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -07008494 struct net_device *ndev,
8495 u8 key_index)
8496#endif
8497{
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308498 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( ndev );
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05308499 int status;
Gopichand Nakkala29149562013-05-10 21:43:41 +05308500 hdd_wext_state_t *pWextState;
8501 hdd_station_ctx_t *pHddStaCtx;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05308502 hdd_context_t *pHddCtx;
Jeff Johnson295189b2012-06-20 16:38:30 -07008503
8504 ENTER();
8505
Gopichand Nakkala29149562013-05-10 21:43:41 +05308506 if ((NULL == pAdapter))
8507 {
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +05308508 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
Gopichand Nakkala29149562013-05-10 21:43:41 +05308509 "invalid adapter");
8510 return -EINVAL;
8511 }
8512
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05308513 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
8514 TRACE_CODE_HDD_CFG80211_SET_DEFAULT_KEY,
8515 pAdapter->sessionId, key_index));
8516
Gopichand Nakkala29149562013-05-10 21:43:41 +05308517 pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
8518 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
8519
8520 if ((NULL == pWextState) || (NULL == pHddStaCtx))
8521 {
8522 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
8523 "invalid Wext state or HDD context");
8524 return -EINVAL;
8525 }
8526
Arif Hussain6d2a3322013-11-17 19:50:10 -08008527 hddLog(VOS_TRACE_LEVEL_INFO, "%s: device_mode = %d key_index = %d",
Jeff Johnson295189b2012-06-20 16:38:30 -07008528 __func__,pAdapter->device_mode, key_index);
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308529
Jeff Johnson295189b2012-06-20 16:38:30 -07008530 if (CSR_MAX_NUM_KEY <= key_index)
8531 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308532 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Invalid key index %d", __func__,
Jeff Johnson295189b2012-06-20 16:38:30 -07008533 key_index);
8534
8535 return -EINVAL;
8536 }
8537
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05308538 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
8539 status = wlan_hdd_validate_context(pHddCtx);
8540
8541 if (0 != status)
Jeff Johnson04dd8a82012-06-29 20:41:40 -07008542 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05308543 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
8544 "%s: HDD context is not valid", __func__);
8545 return status;
Jeff Johnson04dd8a82012-06-29 20:41:40 -07008546 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308547
Jeff Johnson295189b2012-06-20 16:38:30 -07008548 if ((pAdapter->device_mode == WLAN_HDD_INFRA_STATION)
Jeff Johnson295189b2012-06-20 16:38:30 -07008549 || (pAdapter->device_mode == WLAN_HDD_P2P_CLIENT)
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308550 )
Jeff Johnson295189b2012-06-20 16:38:30 -07008551 {
Gopichand Nakkala29149562013-05-10 21:43:41 +05308552 if ( (eCSR_ENCRYPT_TYPE_TKIP !=
Arif Hussain6943f522013-11-04 20:10:10 -08008553 pHddStaCtx->conn_info.ucEncryptionType) &&
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308554 (eCSR_ENCRYPT_TYPE_AES !=
Arif Hussain6943f522013-11-04 20:10:10 -08008555 pHddStaCtx->conn_info.ucEncryptionType)
Jeff Johnson295189b2012-06-20 16:38:30 -07008556 )
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308557 {
8558 /* if default key index is not same as previous one,
Jeff Johnson295189b2012-06-20 16:38:30 -07008559 * then update the default key index */
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308560
Jeff Johnson295189b2012-06-20 16:38:30 -07008561 tCsrRoamSetKey setKey;
8562 v_U32_t roamId= 0xFF;
8563 tCsrKeys *Keys = &pWextState->roamProfile.Keys;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308564
8565 hddLog(VOS_TRACE_LEVEL_INFO_HIGH, "%s: default tx key index %d",
Jeff Johnson295189b2012-06-20 16:38:30 -07008566 __func__, key_index);
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308567
Jeff Johnson295189b2012-06-20 16:38:30 -07008568 Keys->defaultIndex = (u8)key_index;
8569 vos_mem_zero(&setKey,sizeof(tCsrRoamSetKey));
8570 setKey.keyId = key_index;
8571 setKey.keyLength = Keys->KeyLength[key_index];
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308572
8573 vos_mem_copy(&setKey.Key[0],
8574 &Keys->KeyMaterial[key_index][0],
Jeff Johnson295189b2012-06-20 16:38:30 -07008575 Keys->KeyLength[key_index]);
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308576
Gopichand Nakkala29149562013-05-10 21:43:41 +05308577 setKey.keyDirection = eSIR_TX_RX;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308578
8579 vos_mem_copy(setKey.peerMac,
Jeff Johnson295189b2012-06-20 16:38:30 -07008580 &pHddStaCtx->conn_info.bssId[0],
8581 WNI_CFG_BSSID_LEN);
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308582
Gopichand Nakkala29149562013-05-10 21:43:41 +05308583 if (Keys->KeyLength[key_index] == CSR_WEP40_KEY_LEN &&
8584 pWextState->roamProfile.EncryptionType.encryptionType[0] ==
8585 eCSR_ENCRYPT_TYPE_WEP104)
8586 {
8587 /*In the case of dynamic wep supplicant hardcodes DWEP type to eCSR_ENCRYPT_TYPE_WEP104
8588 even though ap is configured for WEP-40 encryption. In this canse the key length
8589 is 5 but the encryption type is 104 hence checking the key langht(5) and encryption
8590 type(104) and switching encryption type to 40*/
8591 pWextState->roamProfile.EncryptionType.encryptionType[0] =
8592 eCSR_ENCRYPT_TYPE_WEP40;
8593 pWextState->roamProfile.mcEncryptionType.encryptionType[0] =
8594 eCSR_ENCRYPT_TYPE_WEP40;
8595 }
8596
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308597 setKey.encType =
Jeff Johnson295189b2012-06-20 16:38:30 -07008598 pWextState->roamProfile.EncryptionType.encryptionType[0];
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308599
Jeff Johnson295189b2012-06-20 16:38:30 -07008600 /* issue set key request */
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308601 status = sme_RoamSetKey( WLAN_HDD_GET_HAL_CTX(pAdapter),
Jeff Johnson295189b2012-06-20 16:38:30 -07008602 pAdapter->sessionId, &setKey, &roamId );
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308603
Jeff Johnson295189b2012-06-20 16:38:30 -07008604 if ( 0 != status )
8605 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308606 hddLog(VOS_TRACE_LEVEL_ERROR,
8607 "%s: sme_RoamSetKey failed, returned %d", __func__,
Jeff Johnson295189b2012-06-20 16:38:30 -07008608 status);
8609 return -EINVAL;
8610 }
8611 }
8612 }
8613
8614 /* In SoftAp mode setting key direction for default mode */
8615 else if ( WLAN_HDD_SOFTAP == pAdapter->device_mode )
8616 {
8617 if ( (eCSR_ENCRYPT_TYPE_TKIP !=
8618 pWextState->roamProfile.EncryptionType.encryptionType[0]) &&
8619 (eCSR_ENCRYPT_TYPE_AES !=
8620 pWextState->roamProfile.EncryptionType.encryptionType[0])
8621 )
8622 {
8623 /* Saving key direction for default key index to TX default */
8624 hdd_ap_ctx_t *pAPCtx = WLAN_HDD_GET_AP_CTX_PTR(pAdapter);
8625 pAPCtx->wepKey[key_index].keyDirection = eSIR_TX_DEFAULT;
8626 }
8627 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308628
Jeff Johnson295189b2012-06-20 16:38:30 -07008629 return status;
8630}
8631
Mahesh A Saptasagar1a51bc02014-06-02 18:28:08 +05308632#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
8633static int wlan_hdd_cfg80211_set_default_key( struct wiphy *wiphy,
8634 struct net_device *ndev,
8635 u8 key_index,
8636 bool unicast, bool multicast)
8637#else
8638static int wlan_hdd_cfg80211_set_default_key( struct wiphy *wiphy,
8639 struct net_device *ndev,
8640 u8 key_index)
8641#endif
8642{
8643 int ret;
8644 vos_ssr_protect(__func__);
8645#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
8646 ret = __wlan_hdd_cfg80211_set_default_key(wiphy, ndev, key_index, unicast,
8647 multicast);
8648#else
8649 ret = __wlan_hdd_cfg80211_set_default_key(wiphy, ndev, key_index);
8650#endif
8651 vos_ssr_unprotect(__func__);
8652
8653 return ret;
8654}
8655
Jeff Johnson295189b2012-06-20 16:38:30 -07008656/*
8657 * FUNCTION: wlan_hdd_cfg80211_inform_bss
8658 * This function is used to inform the BSS details to nl80211 interface.
8659 */
8660static struct cfg80211_bss* wlan_hdd_cfg80211_inform_bss(
8661 hdd_adapter_t *pAdapter, tCsrRoamConnectedProfile *roamProfile)
8662{
8663 struct net_device *dev = pAdapter->dev;
8664 struct wireless_dev *wdev = dev->ieee80211_ptr;
8665 struct wiphy *wiphy = wdev->wiphy;
8666 tSirBssDescription *pBssDesc = roamProfile->pBssDesc;
8667 int chan_no;
8668 int ie_length;
8669 const char *ie;
8670 unsigned int freq;
8671 struct ieee80211_channel *chan;
8672 int rssi = 0;
8673 struct cfg80211_bss *bss = NULL;
8674
8675 ENTER();
8676
8677 if( NULL == pBssDesc )
8678 {
Arif Hussain6d2a3322013-11-17 19:50:10 -08008679 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: pBssDesc is NULL", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07008680 return bss;
8681 }
8682
8683 chan_no = pBssDesc->channelId;
8684 ie_length = GET_IE_LEN_IN_BSS_DESC( pBssDesc->length );
8685 ie = ((ie_length != 0) ? (const char *)&pBssDesc->ieFields: NULL);
8686
8687 if( NULL == ie )
8688 {
Arif Hussain6d2a3322013-11-17 19:50:10 -08008689 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: IE of BSS descriptor is NULL", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07008690 return bss;
8691 }
8692
8693#if (LINUX_VERSION_CODE > KERNEL_VERSION(2,6,38))
8694 if (chan_no <= ARRAY_SIZE(hdd_channels_2_4_GHZ))
8695 {
8696 freq = ieee80211_channel_to_frequency(chan_no, IEEE80211_BAND_2GHZ);
8697 }
8698 else
8699 {
8700 freq = ieee80211_channel_to_frequency(chan_no, IEEE80211_BAND_5GHZ);
8701 }
8702#else
8703 freq = ieee80211_channel_to_frequency(chan_no);
8704#endif
8705
8706 chan = __ieee80211_get_channel(wiphy, freq);
8707
Santhosh Kumar Padmaa45fdb12014-04-15 15:54:38 +05308708 if (!chan) {
8709 hddLog(VOS_TRACE_LEVEL_ERROR, "%s chan pointer is NULL", __func__);
8710 return NULL;
8711 }
8712
Abhishek Singhaee43942014-06-16 18:55:47 +05308713 rssi = (VOS_MIN ((pBssDesc->rssi + pBssDesc->sinr), 0))*100;
Jeff Johnson295189b2012-06-20 16:38:30 -07008714
Abhishek Singhaee43942014-06-16 18:55:47 +05308715 return cfg80211_inform_bss(wiphy, chan, pBssDesc->bssId,
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308716 le64_to_cpu(*(__le64 *)pBssDesc->timeStamp),
Jeff Johnson295189b2012-06-20 16:38:30 -07008717 pBssDesc->capabilityInfo,
8718 pBssDesc->beaconInterval, ie, ie_length,
Abhishek Singhaee43942014-06-16 18:55:47 +05308719 rssi, GFP_KERNEL );
Jeff Johnson295189b2012-06-20 16:38:30 -07008720}
8721
8722
8723
8724/*
8725 * FUNCTION: wlan_hdd_cfg80211_inform_bss_frame
8726 * This function is used to inform the BSS details to nl80211 interface.
8727 */
8728struct cfg80211_bss*
8729wlan_hdd_cfg80211_inform_bss_frame( hdd_adapter_t *pAdapter,
8730 tSirBssDescription *bss_desc
8731 )
8732{
8733 /*
8734 cfg80211_inform_bss() is not updating ie field of bss entry, if entry
8735 already exists in bss data base of cfg80211 for that particular BSS ID.
8736 Using cfg80211_inform_bss_frame to update the bss entry instead of
8737 cfg80211_inform_bss, But this call expects mgmt packet as input. As of
8738 now there is no possibility to get the mgmt(probe response) frame from PE,
8739 converting bss_desc to ieee80211_mgmt(probe response) and passing to
8740 cfg80211_inform_bss_frame.
8741 */
8742 struct net_device *dev = pAdapter->dev;
8743 struct wireless_dev *wdev = dev->ieee80211_ptr;
8744 struct wiphy *wiphy = wdev->wiphy;
8745 int chan_no = bss_desc->channelId;
Madan Mohan Koyyalamudi86f629e2012-11-09 16:27:29 -08008746#ifdef WLAN_ENABLE_AGEIE_ON_SCAN_RESULTS
8747 qcom_ie_age *qie_age = NULL;
8748 int ie_length = GET_IE_LEN_IN_BSS_DESC( bss_desc->length ) + sizeof(qcom_ie_age);
8749#else
Jeff Johnson295189b2012-06-20 16:38:30 -07008750 int ie_length = GET_IE_LEN_IN_BSS_DESC( bss_desc->length );
Madan Mohan Koyyalamudi86f629e2012-11-09 16:27:29 -08008751#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07008752 const char *ie =
8753 ((ie_length != 0) ? (const char *)&bss_desc->ieFields: NULL);
8754 unsigned int freq;
8755 struct ieee80211_channel *chan;
Abhishek Singh1e2bfa32014-01-02 15:44:15 +05308756 struct ieee80211_mgmt *mgmt = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -07008757 struct cfg80211_bss *bss_status = NULL;
8758 size_t frame_len = sizeof (struct ieee80211_mgmt) + ie_length;
8759 int rssi = 0;
Wilson Yangf80a0542013-10-07 13:02:37 -07008760 hdd_context_t *pHddCtx;
8761 int status;
Jeff Johnsone7245742012-09-05 17:12:55 -07008762#ifdef WLAN_OPEN_SOURCE
8763 struct timespec ts;
8764#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07008765
Wilson Yangf80a0542013-10-07 13:02:37 -07008766 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
8767 status = wlan_hdd_validate_context(pHddCtx);
8768
8769 /*bss_update is not allowed during wlan driver loading or unloading*/
Mihir Shete18156292014-03-11 15:38:30 +05308770 if (WLAN_HDD_IS_LOAD_UNLOAD_IN_PROGRESS(pHddCtx))
Wilson Yangf80a0542013-10-07 13:02:37 -07008771 {
8772 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
8773 "%s:Loading_unloading in Progress. Ignore!!!",__func__);
8774 return NULL;
8775 }
8776
8777
8778 if (0 != status)
8779 {
8780 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
8781 "%s: HDD context is not valid", __func__);
Madan Mohan Koyyalamudi2e5c9142012-11-02 13:17:48 -07008782 return NULL;
Wilson Yangf80a0542013-10-07 13:02:37 -07008783 }
8784
Abhishek Singh1e2bfa32014-01-02 15:44:15 +05308785 mgmt = kzalloc((sizeof (struct ieee80211_mgmt) + ie_length), GFP_KERNEL);
Wilson Yangf80a0542013-10-07 13:02:37 -07008786 if (!mgmt)
8787 {
8788 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
8789 "%s: memory allocation failed ", __func__);
8790 return NULL;
8791 }
Madan Mohan Koyyalamudi2e5c9142012-11-02 13:17:48 -07008792
Jeff Johnson295189b2012-06-20 16:38:30 -07008793 memcpy(mgmt->bssid, bss_desc->bssId, ETH_ALEN);
Jeff Johnsone7245742012-09-05 17:12:55 -07008794
8795#ifdef WLAN_OPEN_SOURCE
8796 /* Android does not want the timestamp from the frame.
8797 Instead it wants a monotonic increasing value */
8798 get_monotonic_boottime(&ts);
8799 mgmt->u.probe_resp.timestamp =
8800 ((u64)ts.tv_sec * 1000000) + (ts.tv_nsec / 1000);
8801#else
8802 /* keep old behavior for non-open source (for now) */
Jeff Johnson295189b2012-06-20 16:38:30 -07008803 memcpy(&mgmt->u.probe_resp.timestamp, bss_desc->timeStamp,
8804 sizeof (bss_desc->timeStamp));
Jeff Johnsone7245742012-09-05 17:12:55 -07008805
8806#endif
8807
Jeff Johnson295189b2012-06-20 16:38:30 -07008808 mgmt->u.probe_resp.beacon_int = bss_desc->beaconInterval;
8809 mgmt->u.probe_resp.capab_info = bss_desc->capabilityInfo;
Madan Mohan Koyyalamudi86f629e2012-11-09 16:27:29 -08008810
8811#ifdef WLAN_ENABLE_AGEIE_ON_SCAN_RESULTS
8812 /* GPS Requirement: need age ie per entry. Using vendor specific. */
8813 /* Assuming this is the last IE, copy at the end */
8814 ie_length -=sizeof(qcom_ie_age);
8815 qie_age = (qcom_ie_age *)(mgmt->u.probe_resp.variable + ie_length);
8816 qie_age->element_id = QCOM_VENDOR_IE_ID;
8817 qie_age->len = QCOM_VENDOR_IE_AGE_LEN;
8818 qie_age->oui_1 = QCOM_OUI1;
8819 qie_age->oui_2 = QCOM_OUI2;
8820 qie_age->oui_3 = QCOM_OUI3;
8821 qie_age->type = QCOM_VENDOR_IE_AGE_TYPE;
8822 qie_age->age = vos_timer_get_system_ticks() - bss_desc->nReceivedTime;
8823#endif
8824
Jeff Johnson295189b2012-06-20 16:38:30 -07008825 memcpy(mgmt->u.probe_resp.variable, ie, ie_length);
Gopichand Nakkalad908ec82013-05-16 19:32:19 +05308826 if (bss_desc->fProbeRsp)
8827 {
8828 mgmt->frame_control |=
8829 (u16)(IEEE80211_FTYPE_MGMT | IEEE80211_STYPE_PROBE_RESP);
8830 }
8831 else
8832 {
8833 mgmt->frame_control |=
8834 (u16)(IEEE80211_FTYPE_MGMT | IEEE80211_STYPE_BEACON);
8835 }
Jeff Johnson295189b2012-06-20 16:38:30 -07008836
8837#if (LINUX_VERSION_CODE > KERNEL_VERSION(2,6,38))
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308838 if (chan_no <= ARRAY_SIZE(hdd_channels_2_4_GHZ) &&
Jeff Johnson295189b2012-06-20 16:38:30 -07008839 (wiphy->bands[IEEE80211_BAND_2GHZ] != NULL))
8840 {
8841 freq = ieee80211_channel_to_frequency(chan_no, IEEE80211_BAND_2GHZ);
8842 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308843 else if ((chan_no > ARRAY_SIZE(hdd_channels_2_4_GHZ)) &&
Jeff Johnson295189b2012-06-20 16:38:30 -07008844 (wiphy->bands[IEEE80211_BAND_5GHZ] != NULL))
8845
8846 {
8847 freq = ieee80211_channel_to_frequency(chan_no, IEEE80211_BAND_5GHZ);
8848 }
8849 else
8850 {
Nirav Shah20ac06f2013-12-12 18:14:06 +05308851 hddLog(VOS_TRACE_LEVEL_ERROR, "%s Invalid chan_no:%d",
8852 __func__, chan_no);
Jeff Johnson295189b2012-06-20 16:38:30 -07008853 kfree(mgmt);
8854 return NULL;
8855 }
8856#else
8857 freq = ieee80211_channel_to_frequency(chan_no);
8858#endif
8859 chan = __ieee80211_get_channel(wiphy, freq);
Leela V Kiran Kumar Reddy90032de2013-01-24 18:33:30 -08008860 /*when the band is changed on the fly using the GUI, three things are done
8861 * 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)
8862 * as part of the scan abort, message willbe queued to PE and we proceed with flushing and changinh the band.
8863 * pe will stop the scanning further and report back the results what ever it had till now by calling the call back function.
8864 * if the time between update band and scandone call back is sufficent enough the band change reflects in SME, SME validates the channels
8865 * and discards the channels correponding to previous band and calls back with zero bss results.
8866 * 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
8867 * all the channels correponding to previous band.this is due to race condition.but those channels are invalid to the new band and so
8868 * this function __ieee80211_get_channel will return NULL.Each time we report scan result with this pointer null warning kernel trace is printed.
8869 * if the scan results contain large number of APs continuosly kernel warning trace is printed and it will lead to apps watch dog bark.
8870 * So drop the bss and continue to next bss.
8871 */
8872 if(chan == NULL)
8873 {
Nirav Shah20ac06f2013-12-12 18:14:06 +05308874 hddLog(VOS_TRACE_LEVEL_ERROR, "%s chan pointer is NULL", __func__);
Chilam Ngc4244af2013-04-01 15:37:32 -07008875 kfree(mgmt);
Leela V Kiran Kumar Reddy90032de2013-01-24 18:33:30 -08008876 return NULL;
8877 }
Jeff Johnson295189b2012-06-20 16:38:30 -07008878 /*To keep the rssi icon of the connected AP in the scan window
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308879 *and the rssi icon of the wireless networks in sync
Jeff Johnson295189b2012-06-20 16:38:30 -07008880 * */
8881 if (( eConnectionState_Associated ==
8882 pAdapter->sessionCtx.station.conn_info.connState ) &&
8883 ( VOS_TRUE == vos_mem_compare(bss_desc->bssId,
8884 pAdapter->sessionCtx.station.conn_info.bssId,
8885 WNI_CFG_BSSID_LEN)))
8886 {
8887 /* supplicant takes the signal strength in terms of mBm(100*dBm) */
8888 rssi = (pAdapter->rssi * 100);
8889 }
8890 else
8891 {
8892 rssi = (VOS_MIN ((bss_desc->rssi + bss_desc->sinr), 0))*100;
8893 }
8894
Nirav Shah20ac06f2013-12-12 18:14:06 +05308895 hddLog(VOS_TRACE_LEVEL_INFO, "%s: BSSID:" MAC_ADDRESS_STR " Channel:%d"
8896 "RSSI:%d", __func__, MAC_ADDR_ARRAY(mgmt->bssid),
8897 chan->center_freq, (int)(rssi/100));
8898
Jeff Johnson295189b2012-06-20 16:38:30 -07008899 bss_status = cfg80211_inform_bss_frame(wiphy, chan, mgmt,
8900 frame_len, rssi, GFP_KERNEL);
8901 kfree(mgmt);
8902 return bss_status;
8903}
8904
8905/*
8906 * FUNCTION: wlan_hdd_cfg80211_update_bss_db
8907 * This function is used to update the BSS data base of CFG8011
8908 */
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308909struct cfg80211_bss* wlan_hdd_cfg80211_update_bss_db( hdd_adapter_t *pAdapter,
Jeff Johnson295189b2012-06-20 16:38:30 -07008910 tCsrRoamInfo *pRoamInfo
8911 )
8912{
8913 tCsrRoamConnectedProfile roamProfile;
8914 tHalHandle hHal = WLAN_HDD_GET_HAL_CTX(pAdapter);
8915 struct cfg80211_bss *bss = NULL;
8916
8917 ENTER();
8918
8919 memset(&roamProfile, 0, sizeof(tCsrRoamConnectedProfile));
8920 sme_RoamGetConnectProfile(hHal, pAdapter->sessionId, &roamProfile);
8921
8922 if (NULL != roamProfile.pBssDesc)
8923 {
Girish Gowlif4b68022014-08-28 23:18:57 +05308924 bss = wlan_hdd_cfg80211_inform_bss_frame(pAdapter,
8925 roamProfile.pBssDesc);
Jeff Johnson295189b2012-06-20 16:38:30 -07008926
8927 if (NULL == bss)
8928 {
8929 hddLog(VOS_TRACE_LEVEL_INFO, "%s: cfg80211_inform_bss return NULL",
8930 __func__);
8931 }
8932
8933 sme_RoamFreeConnectProfile(hHal, &roamProfile);
8934 }
8935 else
8936 {
8937 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: roamProfile.pBssDesc is NULL",
8938 __func__);
8939 }
8940 return bss;
8941}
8942
8943/*
8944 * FUNCTION: wlan_hdd_cfg80211_update_bss
8945 */
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308946static int wlan_hdd_cfg80211_update_bss( struct wiphy *wiphy,
8947 hdd_adapter_t *pAdapter
Jeff Johnson295189b2012-06-20 16:38:30 -07008948 )
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308949{
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +05308950 tHalHandle hHal = WLAN_HDD_GET_HAL_CTX(pAdapter);
Jeff Johnson295189b2012-06-20 16:38:30 -07008951 tCsrScanResultInfo *pScanResult;
8952 eHalStatus status = 0;
8953 tScanResultHandle pResult;
8954 struct cfg80211_bss *bss_status = NULL;
Wilson Yangf80a0542013-10-07 13:02:37 -07008955 hdd_context_t *pHddCtx;
Jeff Johnson295189b2012-06-20 16:38:30 -07008956
8957 ENTER();
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +05308958
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05308959 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
8960 TRACE_CODE_HDD_CFG80211_UPDATE_BSS,
8961 NO_SESSION, pAdapter->sessionId));
8962
Wilson Yangf80a0542013-10-07 13:02:37 -07008963 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
8964
8965 if (pHddCtx->isLogpInProgress)
Jeff Johnson295189b2012-06-20 16:38:30 -07008966 {
Wilson Yangf80a0542013-10-07 13:02:37 -07008967 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
8968 "%s:LOGP in Progress. Ignore!!!",__func__);
8969 return -EAGAIN;
Jeff Johnson295189b2012-06-20 16:38:30 -07008970 }
8971
Wilson Yangf80a0542013-10-07 13:02:37 -07008972
8973 /*bss_update is not allowed during wlan driver loading or unloading*/
Mihir Shete18156292014-03-11 15:38:30 +05308974 if (WLAN_HDD_IS_LOAD_UNLOAD_IN_PROGRESS(pHddCtx))
Wilson Yangf80a0542013-10-07 13:02:37 -07008975 {
8976 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
8977 "%s:Loading_unloading in Progress. Ignore!!!",__func__);
8978 return VOS_STATUS_E_PERM;
8979 }
8980
8981
Jeff Johnson295189b2012-06-20 16:38:30 -07008982 /*
8983 * start getting scan results and populate cgf80211 BSS database
8984 */
8985 status = sme_ScanGetResult(hHal, pAdapter->sessionId, NULL, &pResult);
8986
8987 /* no scan results */
8988 if (NULL == pResult)
8989 {
Nirav Shah20ac06f2013-12-12 18:14:06 +05308990 hddLog(VOS_TRACE_LEVEL_INFO, "%s: No scan result Status %d",
8991 __func__, status);
Jeff Johnson295189b2012-06-20 16:38:30 -07008992 return status;
8993 }
8994
8995 pScanResult = sme_ScanResultGetFirst(hHal, pResult);
8996
8997 while (pScanResult)
8998 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308999 /*
9000 * cfg80211_inform_bss() is not updating ie field of bss entry, if
9001 * entry already exists in bss data base of cfg80211 for that
9002 * particular BSS ID. Using cfg80211_inform_bss_frame to update the
9003 * bss entry instead of cfg80211_inform_bss, But this call expects
9004 * mgmt packet as input. As of now there is no possibility to get
9005 * the mgmt(probe response) frame from PE, converting bss_desc to
Jeff Johnson295189b2012-06-20 16:38:30 -07009006 * ieee80211_mgmt(probe response) and passing to c
9007 * fg80211_inform_bss_frame.
9008 * */
9009
9010 bss_status = wlan_hdd_cfg80211_inform_bss_frame(pAdapter,
9011 &pScanResult->BssDescriptor);
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309012
Jeff Johnson295189b2012-06-20 16:38:30 -07009013
9014 if (NULL == bss_status)
9015 {
9016 hddLog(VOS_TRACE_LEVEL_INFO,
Arif Hussain6d2a3322013-11-17 19:50:10 -08009017 "%s: NULL returned by cfg80211_inform_bss", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07009018 }
9019 else
9020 {
Yue Maf49ba872013-08-19 12:04:25 -07009021 cfg80211_put_bss(
9022#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,9,0))
9023 wiphy,
9024#endif
9025 bss_status);
Jeff Johnson295189b2012-06-20 16:38:30 -07009026 }
9027
9028 pScanResult = sme_ScanResultGetNext(hHal, pResult);
9029 }
9030
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309031 sme_ScanResultPurge(hHal, pResult);
Jeff Johnson295189b2012-06-20 16:38:30 -07009032
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309033 return 0;
Jeff Johnson295189b2012-06-20 16:38:30 -07009034}
9035
Jeff Johnson04dd8a82012-06-29 20:41:40 -07009036void
9037hddPrintMacAddr(tCsrBssid macAddr, tANI_U8 logLevel)
9038{
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309039 VOS_TRACE(VOS_MODULE_ID_HDD, logLevel,
Arif Hussaina7c8e412013-11-20 11:06:42 -08009040 MAC_ADDRESS_STR, MAC_ADDR_ARRAY(macAddr));
Jeff Johnson04dd8a82012-06-29 20:41:40 -07009041} /****** end hddPrintMacAddr() ******/
9042
9043void
Madan Mohan Koyyalamudic75be962012-10-18 19:19:03 -07009044hddPrintPmkId(tANI_U8 *pmkId, tANI_U8 logLevel)
Jeff Johnson04dd8a82012-06-29 20:41:40 -07009045{
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309046 VOS_TRACE(VOS_MODULE_ID_HDD, logLevel,
Arif Hussain6d2a3322013-11-17 19:50:10 -08009047 "%02X:%02X:%02X:%02X:%02X:%02X:%02X:%02X:%02X:%02X:%02X:%02X:%02X:%02X:%02X:%02X",
Madan Mohan Koyyalamudic75be962012-10-18 19:19:03 -07009048 pmkId[0], pmkId[1], pmkId[2], pmkId[3], pmkId[4],
9049 pmkId[5], pmkId[6], pmkId[7], pmkId[8], pmkId[9], pmkId[10],
9050 pmkId[11], pmkId[12], pmkId[13], pmkId[14], pmkId[15]);
Jeff Johnson04dd8a82012-06-29 20:41:40 -07009051} /****** end hddPrintPmkId() ******/
9052
9053//hddPrintMacAddr(tCsrBssid macAddr, tANI_U8 logLevel);
9054//hddPrintMacAddr(macAddr, VOS_TRACE_LEVEL_FATAL);
9055
9056//void sirDumpBuf(tpAniSirGlobal pMac, tANI_U8 modId, tANI_U32 level, tANI_U8 *buf, tANI_U32 size);
9057//sirDumpBuf(pMac, VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL, pmkid, 16);
9058
9059#define dump_bssid(bssid) \
9060 { \
Jeff Johnsone7245742012-09-05 17:12:55 -07009061 hddLog(VOS_TRACE_LEVEL_INFO, "BSSID (MAC) address:\t"); \
9062 hddPrintMacAddr(bssid, VOS_TRACE_LEVEL_INFO);\
Jeff Johnson04dd8a82012-06-29 20:41:40 -07009063 }
9064
9065#define dump_pmkid(pMac, pmkid) \
9066 { \
Jeff Johnsone7245742012-09-05 17:12:55 -07009067 hddLog(VOS_TRACE_LEVEL_INFO, "PMKSA-ID:\t"); \
9068 hddPrintPmkId(pmkid, VOS_TRACE_LEVEL_INFO);\
Jeff Johnson04dd8a82012-06-29 20:41:40 -07009069 }
9070
Madan Mohan Koyyalamudi1b4afb02012-10-22 15:25:16 -07009071#if defined(FEATURE_WLAN_LFR) && (LINUX_VERSION_CODE >= KERNEL_VERSION(3,4,0))
Jeff Johnson04dd8a82012-06-29 20:41:40 -07009072/*
9073 * FUNCTION: wlan_hdd_cfg80211_pmksa_candidate_notify
9074 * This function is used to notify the supplicant of a new PMKSA candidate.
9075 */
9076int wlan_hdd_cfg80211_pmksa_candidate_notify(
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309077 hdd_adapter_t *pAdapter, tCsrRoamInfo *pRoamInfo,
Jeff Johnson04dd8a82012-06-29 20:41:40 -07009078 int index, bool preauth )
9079{
Jeff Johnsone7245742012-09-05 17:12:55 -07009080#ifdef FEATURE_WLAN_OKC
Jeff Johnson04dd8a82012-06-29 20:41:40 -07009081 struct net_device *dev = pAdapter->dev;
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07009082 hdd_context_t *pHddCtx = (hdd_context_t*)pAdapter->pHddCtx;
Jeff Johnson04dd8a82012-06-29 20:41:40 -07009083
9084 ENTER();
Jeff Johnsone7245742012-09-05 17:12:55 -07009085 hddLog(VOS_TRACE_LEVEL_INFO, "%s is going to notify supplicant of:", __func__);
Jeff Johnson04dd8a82012-06-29 20:41:40 -07009086
9087 if( NULL == pRoamInfo )
9088 {
Arif Hussain6d2a3322013-11-17 19:50:10 -08009089 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: pRoamInfo is NULL", __func__);
Jeff Johnson04dd8a82012-06-29 20:41:40 -07009090 return -EINVAL;
9091 }
9092
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07009093 if (eANI_BOOLEAN_TRUE == hdd_is_okc_mode_enabled(pHddCtx))
9094 {
9095 dump_bssid(pRoamInfo->bssid);
9096 cfg80211_pmksa_candidate_notify(dev, index,
Jeff Johnson04dd8a82012-06-29 20:41:40 -07009097 pRoamInfo->bssid, preauth, GFP_KERNEL);
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07009098 }
Jeff Johnsone7245742012-09-05 17:12:55 -07009099#endif /* FEATURE_WLAN_OKC */
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309100 return 0;
Jeff Johnson04dd8a82012-06-29 20:41:40 -07009101}
9102#endif //FEATURE_WLAN_LFR
9103
Yue Maef608272013-04-08 23:09:17 -07009104#ifdef FEATURE_WLAN_LFR_METRICS
9105/*
9106 * FUNCTION: wlan_hdd_cfg80211_roam_metrics_preauth
9107 * 802.11r/LFR metrics reporting function to report preauth initiation
9108 *
9109 */
9110#define MAX_LFR_METRICS_EVENT_LENGTH 100
9111VOS_STATUS wlan_hdd_cfg80211_roam_metrics_preauth(hdd_adapter_t *pAdapter,
9112 tCsrRoamInfo *pRoamInfo)
9113{
9114 unsigned char metrics_notification[MAX_LFR_METRICS_EVENT_LENGTH + 1];
9115 union iwreq_data wrqu;
9116
9117 ENTER();
9118
9119 if (NULL == pAdapter)
9120 {
9121 hddLog(LOGE, "%s: pAdapter is NULL!", __func__);
9122 return VOS_STATUS_E_FAILURE;
9123 }
9124
9125 /* create the event */
9126 memset(&wrqu, 0, sizeof(wrqu));
9127 memset(metrics_notification, 0, sizeof(metrics_notification));
9128
9129 wrqu.data.pointer = metrics_notification;
9130 wrqu.data.length = scnprintf(metrics_notification,
9131 sizeof(metrics_notification), "QCOM: LFR_PREAUTH_INIT "
9132 MAC_ADDRESS_STR, MAC_ADDR_ARRAY(pRoamInfo->bssid));
9133
9134 wireless_send_event(pAdapter->dev, IWEVCUSTOM, &wrqu, metrics_notification);
9135
9136 EXIT();
9137
9138 return VOS_STATUS_SUCCESS;
9139}
9140
9141/*
9142 * FUNCTION: wlan_hdd_cfg80211_roam_metrics_preauth_status
9143 * 802.11r/LFR metrics reporting function to report preauth completion
9144 * or failure
9145 */
9146VOS_STATUS wlan_hdd_cfg80211_roam_metrics_preauth_status(
9147 hdd_adapter_t *pAdapter, tCsrRoamInfo *pRoamInfo, bool preauth_status)
9148{
9149 unsigned char metrics_notification[MAX_LFR_METRICS_EVENT_LENGTH + 1];
9150 union iwreq_data wrqu;
9151
9152 ENTER();
9153
9154 if (NULL == pAdapter)
9155 {
9156 hddLog(LOGE, "%s: pAdapter is NULL!", __func__);
9157 return VOS_STATUS_E_FAILURE;
9158 }
9159
9160 /* create the event */
9161 memset(&wrqu, 0, sizeof(wrqu));
9162 memset(metrics_notification, 0, sizeof(metrics_notification));
9163
9164 scnprintf(metrics_notification, sizeof(metrics_notification),
9165 "QCOM: LFR_PREAUTH_STATUS "MAC_ADDRESS_STR,
9166 MAC_ADDR_ARRAY(pRoamInfo->bssid));
9167
9168 if (1 == preauth_status)
9169 strncat(metrics_notification, " TRUE", 5);
9170 else
9171 strncat(metrics_notification, " FALSE", 6);
9172
9173 wrqu.data.pointer = metrics_notification;
9174 wrqu.data.length = strlen(metrics_notification);
9175
9176 wireless_send_event(pAdapter->dev, IWEVCUSTOM, &wrqu, metrics_notification);
9177
9178 EXIT();
9179
9180 return VOS_STATUS_SUCCESS;
9181}
9182
9183/*
9184 * FUNCTION: wlan_hdd_cfg80211_roam_metrics_handover
9185 * 802.11r/LFR metrics reporting function to report handover initiation
9186 *
9187 */
9188VOS_STATUS wlan_hdd_cfg80211_roam_metrics_handover(hdd_adapter_t * pAdapter,
9189 tCsrRoamInfo *pRoamInfo)
9190{
9191 unsigned char metrics_notification[MAX_LFR_METRICS_EVENT_LENGTH + 1];
9192 union iwreq_data wrqu;
9193
9194 ENTER();
9195
9196 if (NULL == pAdapter)
9197 {
9198 hddLog(LOGE, "%s: pAdapter is NULL!", __func__);
9199 return VOS_STATUS_E_FAILURE;
9200 }
9201
9202 /* create the event */
9203 memset(&wrqu, 0, sizeof(wrqu));
9204 memset(metrics_notification, 0, sizeof(metrics_notification));
9205
9206 wrqu.data.pointer = metrics_notification;
9207 wrqu.data.length = scnprintf(metrics_notification,
9208 sizeof(metrics_notification), "QCOM: LFR_PREAUTH_HANDOVER "
9209 MAC_ADDRESS_STR, MAC_ADDR_ARRAY(pRoamInfo->bssid));
9210
9211 wireless_send_event(pAdapter->dev, IWEVCUSTOM, &wrqu, metrics_notification);
9212
9213 EXIT();
9214
9215 return VOS_STATUS_SUCCESS;
9216}
9217#endif
9218
Jeff Johnson295189b2012-06-20 16:38:30 -07009219/*
9220 * FUNCTION: hdd_cfg80211_scan_done_callback
9221 * scanning callback function, called after finishing scan
9222 *
9223 */
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309224static eHalStatus hdd_cfg80211_scan_done_callback(tHalHandle halHandle,
Jeff Johnson295189b2012-06-20 16:38:30 -07009225 void *pContext, tANI_U32 scanId, eCsrScanStatus status)
9226{
9227 struct net_device *dev = (struct net_device *) pContext;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309228 //struct wireless_dev *wdev = dev->ieee80211_ptr;
Jeff Johnson295189b2012-06-20 16:38:30 -07009229 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( dev );
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -07009230 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
9231 hdd_scaninfo_t *pScanInfo = &pHddCtx->scan_info;
Jeff Johnson295189b2012-06-20 16:38:30 -07009232 struct cfg80211_scan_request *req = NULL;
9233 int ret = 0;
Mahesh A Saptasagar05a357e2014-02-26 16:28:06 +05309234 bool aborted = false;
c_hpothu6ff1c3c2013-10-01 19:01:57 +05309235 long waitRet = 0;
Jeff Johnson295189b2012-06-20 16:38:30 -07009236
9237 ENTER();
9238
9239 hddLog(VOS_TRACE_LEVEL_INFO,
9240 "%s called with halHandle = %p, pContext = %p,"
Arif Hussain6d2a3322013-11-17 19:50:10 -08009241 "scanID = %d, returned status = %d",
Jeff Johnson295189b2012-06-20 16:38:30 -07009242 __func__, halHandle, pContext, (int) scanId, (int) status);
9243
Kiet Lamac06e2c2013-10-23 16:25:07 +05309244 pScanInfo->mScanPendingCounter = 0;
9245
Jeff Johnson295189b2012-06-20 16:38:30 -07009246 //Block on scan req completion variable. Can't wait forever though.
c_hpothu6ff1c3c2013-10-01 19:01:57 +05309247 waitRet = wait_for_completion_interruptible_timeout(
Jeff Johnson295189b2012-06-20 16:38:30 -07009248 &pScanInfo->scan_req_completion_event,
9249 msecs_to_jiffies(WLAN_WAIT_TIME_SCAN_REQ));
c_hpothu6ff1c3c2013-10-01 19:01:57 +05309250 if (waitRet <= 0)
Jeff Johnson295189b2012-06-20 16:38:30 -07009251 {
c_hpothu6ff1c3c2013-10-01 19:01:57 +05309252 hddLog(VOS_TRACE_LEVEL_ERROR,
9253 "%s wait on scan_req_completion_event failed %ld",__func__, waitRet);
Jeff Johnson295189b2012-06-20 16:38:30 -07009254 VOS_ASSERT(pScanInfo->mScanPending);
Jeff Johnsone7245742012-09-05 17:12:55 -07009255 goto allow_suspend;
Jeff Johnson295189b2012-06-20 16:38:30 -07009256 }
9257
Yue Maef608272013-04-08 23:09:17 -07009258 if (pScanInfo->mScanPending != VOS_TRUE)
Jeff Johnson295189b2012-06-20 16:38:30 -07009259 {
9260 VOS_ASSERT(pScanInfo->mScanPending);
Jeff Johnsone7245742012-09-05 17:12:55 -07009261 goto allow_suspend;
Jeff Johnson295189b2012-06-20 16:38:30 -07009262 }
9263
9264 /* Check the scanId */
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309265 if (pScanInfo->scanId != scanId)
Jeff Johnson295189b2012-06-20 16:38:30 -07009266 {
9267 hddLog(VOS_TRACE_LEVEL_INFO,
9268 "%s called with mismatched scanId pScanInfo->scanId = %d "
Arif Hussain6d2a3322013-11-17 19:50:10 -08009269 "scanId = %d", __func__, (int) pScanInfo->scanId,
Jeff Johnson295189b2012-06-20 16:38:30 -07009270 (int) scanId);
9271 }
9272
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309273 ret = wlan_hdd_cfg80211_update_bss((WLAN_HDD_GET_CTX(pAdapter))->wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -07009274 pAdapter);
9275
9276 if (0 > ret)
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309277 hddLog(VOS_TRACE_LEVEL_INFO, "%s: NO SCAN result", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07009278
9279
9280 /* If any client wait scan result through WEXT
9281 * send scan done event to client */
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -07009282 if (pHddCtx->scan_info.waitScanResult)
Jeff Johnson295189b2012-06-20 16:38:30 -07009283 {
9284 /* The other scan request waiting for current scan finish
9285 * Send event to notify current scan finished */
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -07009286 if(WEXT_SCAN_PENDING_DELAY == pHddCtx->scan_info.scan_pending_option)
Jeff Johnson295189b2012-06-20 16:38:30 -07009287 {
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -07009288 vos_event_set(&pHddCtx->scan_info.scan_finished_event);
Jeff Johnson295189b2012-06-20 16:38:30 -07009289 }
9290 /* Send notify to WEXT client */
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -07009291 else if(WEXT_SCAN_PENDING_PIGGYBACK == pHddCtx->scan_info.scan_pending_option)
Jeff Johnson295189b2012-06-20 16:38:30 -07009292 {
9293 struct net_device *dev = pAdapter->dev;
9294 union iwreq_data wrqu;
9295 int we_event;
9296 char *msg;
9297
9298 memset(&wrqu, '\0', sizeof(wrqu));
9299 we_event = SIOCGIWSCAN;
9300 msg = NULL;
9301 wireless_send_event(dev, we_event, &wrqu, msg);
9302 }
9303 }
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -07009304 pHddCtx->scan_info.waitScanResult = FALSE;
Jeff Johnson295189b2012-06-20 16:38:30 -07009305
9306 /* Get the Scan Req */
9307 req = pAdapter->request;
9308
9309 if (!req)
9310 {
Arif Hussain6d2a3322013-11-17 19:50:10 -08009311 hddLog(VOS_TRACE_LEVEL_ERROR, "request is became NULL");
Madan Mohan Koyyalamudi9f5a10c2012-09-28 14:46:16 -07009312 pScanInfo->mScanPending = VOS_FALSE;
Jeff Johnsone7245742012-09-05 17:12:55 -07009313 goto allow_suspend;
Jeff Johnson295189b2012-06-20 16:38:30 -07009314 }
9315
9316 /*
9317 * setting up 0, just in case.
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309318 */
Jeff Johnson295189b2012-06-20 16:38:30 -07009319 req->n_ssids = 0;
9320 req->n_channels = 0;
9321 req->ie = 0;
9322
Jeff Johnson295189b2012-06-20 16:38:30 -07009323 pAdapter->request = NULL;
Jeff Johnsone7245742012-09-05 17:12:55 -07009324 /* Scan is no longer pending */
9325 pScanInfo->mScanPending = VOS_FALSE;
Jeff Johnson295189b2012-06-20 16:38:30 -07009326
Madan Mohan Koyyalamudib764bf82012-10-11 16:38:51 -07009327 /*
9328 * cfg80211_scan_done informing NL80211 about completion
9329 * of scanning
9330 */
Mahesh A Saptasagar05a357e2014-02-26 16:28:06 +05309331 if (status == eCSR_SCAN_ABORT || status == eCSR_SCAN_FAILURE)
9332 {
9333 aborted = true;
9334 }
9335 cfg80211_scan_done(req, aborted);
Madan Mohan Koyyalamudif4e81002012-11-13 10:46:38 -08009336 complete(&pScanInfo->abortscan_event_var);
Jeff Johnson295189b2012-06-20 16:38:30 -07009337
Jeff Johnsone7245742012-09-05 17:12:55 -07009338allow_suspend:
Madan Mohan Koyyalamudi9f5a10c2012-09-28 14:46:16 -07009339 /* release the wake lock at the end of the scan*/
9340 hdd_allow_suspend();
Jeff Johnsone7245742012-09-05 17:12:55 -07009341
Madan Mohan Koyyalamudi10d83a92012-09-28 15:47:05 -07009342 /* Acquire wakelock to handle the case where APP's tries to suspend
9343 * immediatly after the driver gets connect request(i.e after scan)
9344 * from supplicant, this result in app's is suspending and not able
9345 * to process the connect request to AP */
Mahesh A Saptasagarb9c50402014-01-16 15:49:22 +05309346 hdd_prevent_suspend_timeout(1000);
Madan Mohan Koyyalamudi10d83a92012-09-28 15:47:05 -07009347
Gopichand Nakkala638ebc72013-03-21 18:04:02 -07009348#ifdef FEATURE_WLAN_TDLS
c_hpothu3c8f8e82014-06-02 18:01:50 +05309349 if (!(eTDLS_SUPPORT_NOT_ENABLED == pHddCtx->tdls_mode))
9350 {
9351 wlan_hdd_tdls_scan_done_callback(pAdapter);
9352 }
Gopichand Nakkala638ebc72013-03-21 18:04:02 -07009353#endif
9354
Jeff Johnson295189b2012-06-20 16:38:30 -07009355 EXIT();
9356 return 0;
9357}
9358
9359/*
Rashmi Ramannab1429032014-04-26 14:59:09 +05309360 * FUNCTION: hdd_isConnectionInProgress
9361 * Go through each adapter and check if Connection is in progress
Madan Mohan Koyyalamudicfd53742013-01-11 15:29:03 -08009362 *
9363 */
Ganesh Kondabattiniaeb7b772014-08-11 20:00:36 +05309364v_BOOL_t hdd_isConnectionInProgress( hdd_context_t *pHddCtx, v_BOOL_t isRoC )
Madan Mohan Koyyalamudicfd53742013-01-11 15:29:03 -08009365{
9366 hdd_adapter_list_node_t *pAdapterNode = NULL, *pNext = NULL;
9367 hdd_station_ctx_t *pHddStaCtx = NULL;
9368 hdd_adapter_t *pAdapter = NULL;
9369 VOS_STATUS status = 0;
9370 v_U8_t staId = 0;
9371 v_U8_t *staMac = NULL;
9372
c_hpothu9b781ba2013-12-30 20:57:45 +05309373 if (TRUE == pHddCtx->btCoexModeSet)
9374 {
9375 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Rashmi Ramannab1429032014-04-26 14:59:09 +05309376 FL("BTCoex Mode operation in progress"));
9377 return VOS_TRUE;
c_hpothu9b781ba2013-12-30 20:57:45 +05309378 }
9379
Madan Mohan Koyyalamudicfd53742013-01-11 15:29:03 -08009380 status = hdd_get_front_adapter ( pHddCtx, &pAdapterNode );
9381
9382 while ( NULL != pAdapterNode && VOS_STATUS_SUCCESS == status )
9383 {
9384 pAdapter = pAdapterNode->pAdapter;
9385
9386 if( pAdapter )
9387 {
9388 hddLog(VOS_TRACE_LEVEL_INFO,
Sushant Kaushik8bc7df22014-04-09 17:55:29 +05309389 "%s: Adapter with device mode %s (%d) exists",
9390 __func__, hdd_device_modetoString(pAdapter->device_mode),
9391 pAdapter->device_mode);
Ganesh Kondabattiniaeb7b772014-08-11 20:00:36 +05309392 if ((((!isRoC) && (WLAN_HDD_INFRA_STATION == pAdapter->device_mode)) ||
Rashmi Ramannab1429032014-04-26 14:59:09 +05309393 (WLAN_HDD_P2P_CLIENT == pAdapter->device_mode) ||
9394 (WLAN_HDD_P2P_DEVICE == pAdapter->device_mode)) &&
9395 (eConnectionState_Connecting ==
9396 (WLAN_HDD_GET_STATION_CTX_PTR(pAdapter))->conn_info.connState))
9397 {
9398 hddLog(VOS_TRACE_LEVEL_ERROR,
9399 "%s: %p(%d) Connection is in progress", __func__,
9400 WLAN_HDD_GET_STATION_CTX_PTR(pAdapter), pAdapter->sessionId);
9401 return VOS_TRUE;
9402 }
Ganesh Kondabattiniaeb7b772014-08-11 20:00:36 +05309403 if (((!isRoC) && (WLAN_HDD_INFRA_STATION == pAdapter->device_mode)) ||
Sushant Kaushik8bc7df22014-04-09 17:55:29 +05309404 (WLAN_HDD_P2P_CLIENT == pAdapter->device_mode) ||
9405 (WLAN_HDD_P2P_DEVICE == pAdapter->device_mode))
Madan Mohan Koyyalamudicfd53742013-01-11 15:29:03 -08009406 {
9407 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
9408 if ((eConnectionState_Associated == pHddStaCtx->conn_info.connState) &&
Sushant Kaushik8bc7df22014-04-09 17:55:29 +05309409 (VOS_FALSE == pHddStaCtx->conn_info.uIsAuthenticated))
Madan Mohan Koyyalamudicfd53742013-01-11 15:29:03 -08009410 {
9411 staMac = (v_U8_t *) &(pAdapter->macAddressCurrent.bytes[0]);
9412 hddLog(VOS_TRACE_LEVEL_ERROR,
Arif Hussain24bafea2013-11-15 15:10:03 -08009413 "%s: client " MAC_ADDRESS_STR
9414 " is in the middle of WPS/EAPOL exchange.", __func__,
9415 MAC_ADDR_ARRAY(staMac));
Rashmi Ramannab1429032014-04-26 14:59:09 +05309416 return VOS_TRUE;
Madan Mohan Koyyalamudicfd53742013-01-11 15:29:03 -08009417 }
9418 }
9419 else if ((WLAN_HDD_SOFTAP == pAdapter->device_mode) ||
9420 (WLAN_HDD_P2P_GO == pAdapter->device_mode))
9421 {
9422 for (staId = 0; staId < WLAN_MAX_STA_COUNT; staId++)
9423 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309424 if ((pAdapter->aStaInfo[staId].isUsed) &&
Madan Mohan Koyyalamudicfd53742013-01-11 15:29:03 -08009425 (WLANTL_STA_CONNECTED == pAdapter->aStaInfo[staId].tlSTAState))
9426 {
9427 staMac = (v_U8_t *) &(pAdapter->aStaInfo[staId].macAddrSTA.bytes[0]);
9428
9429 hddLog(VOS_TRACE_LEVEL_ERROR,
Arif Hussain24bafea2013-11-15 15:10:03 -08009430 "%s: client " MAC_ADDRESS_STR " of SoftAP/P2P-GO is in the "
9431 "middle of WPS/EAPOL exchange.", __func__,
9432 MAC_ADDR_ARRAY(staMac));
Rashmi Ramannab1429032014-04-26 14:59:09 +05309433 return VOS_TRUE;
Madan Mohan Koyyalamudicfd53742013-01-11 15:29:03 -08009434 }
9435 }
9436 }
9437 }
9438 status = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
9439 pAdapterNode = pNext;
9440 }
Rashmi Ramannab1429032014-04-26 14:59:09 +05309441 return VOS_FALSE;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309442}
Madan Mohan Koyyalamudicfd53742013-01-11 15:29:03 -08009443
9444/*
Mahesh A Saptasagarfafb7fe2014-05-16 13:19:37 +05309445 * FUNCTION: __wlan_hdd_cfg80211_scan
Jeff Johnson295189b2012-06-20 16:38:30 -07009446 * this scan respond to scan trigger and update cfg80211 scan database
9447 * later, scan dump command can be used to recieve scan results
9448 */
Mahesh A Saptasagarfafb7fe2014-05-16 13:19:37 +05309449int __wlan_hdd_cfg80211_scan( struct wiphy *wiphy,
Jeff Johnson3bbe4bf2013-01-18 17:05:29 -08009450#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,6,0))
9451 struct net_device *dev,
9452#endif
9453 struct cfg80211_scan_request *request)
9454{
Siddharth Bhal0c162d02014-05-06 19:50:42 +05309455 hdd_adapter_t *pAdapter = NULL;
9456 hdd_context_t *pHddCtx = NULL;
9457 hdd_wext_state_t *pwextBuf = NULL;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05309458 hdd_config_t *cfg_param = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -07009459 tCsrScanRequest scanRequest;
9460 tANI_U8 *channelList = NULL, i;
9461 v_U32_t scanId = 0;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05309462 int status;
9463 hdd_scaninfo_t *pScanInfo = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -07009464 v_U8_t* pP2pIe = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -07009465
Siddharth Bhal0c162d02014-05-06 19:50:42 +05309466#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,6,0))
9467 struct net_device *dev = NULL;
9468 if (NULL == request)
9469 {
9470 hddLog(VOS_TRACE_LEVEL_ERROR,
9471 "%s: scan req param null", __func__);
9472 return -EINVAL;
9473 }
9474 dev = request->wdev->netdev;
9475#endif
9476
9477 pAdapter = WLAN_HDD_GET_PRIV_PTR( dev );
9478 pHddCtx = WLAN_HDD_GET_CTX( pAdapter );
9479 pwextBuf = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
9480
Jeff Johnson295189b2012-06-20 16:38:30 -07009481 ENTER();
9482
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +05309483
Sushant Kaushik8bc7df22014-04-09 17:55:29 +05309484 hddLog(VOS_TRACE_LEVEL_INFO, "%s: device_mode = %s (%d)",
9485 __func__, hdd_device_modetoString(pAdapter->device_mode),
9486 pAdapter->device_mode);
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +05309487
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05309488 status = wlan_hdd_validate_context(pHddCtx);
9489
9490 if (0 != status)
9491 {
9492 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
9493 "%s: HDD context is not valid", __func__);
9494 return status;
9495 }
9496
Siddharth Bhal0c162d02014-05-06 19:50:42 +05309497 if (NULL == pwextBuf)
9498 {
9499 hddLog (VOS_TRACE_LEVEL_ERROR, "%s ERROR: invalid WEXT state\n",
9500 __func__);
9501 return -EIO;
9502 }
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05309503 cfg_param = pHddCtx->cfg_ini;
9504 pScanInfo = &pHddCtx->scan_info;
9505
Jeff Johnson295189b2012-06-20 16:38:30 -07009506#ifdef WLAN_BTAMP_FEATURE
9507 //Scan not supported when AMP traffic is on.
Gopichand Nakkala681989c2013-03-06 22:27:48 -08009508 if (VOS_TRUE == WLANBAP_AmpSessionOn())
Jeff Johnson295189b2012-06-20 16:38:30 -07009509 {
Madan Mohan Koyyalamudifd4e1da2012-11-09 17:50:19 -08009510 hddLog(VOS_TRACE_LEVEL_ERROR,
Jeff Johnson295189b2012-06-20 16:38:30 -07009511 "%s: No scanning when AMP is on", __func__);
9512 return -EOPNOTSUPP;
9513 }
9514#endif
9515 //Scan on any other interface is not supported.
Gopichand Nakkala681989c2013-03-06 22:27:48 -08009516 if (pAdapter->device_mode == WLAN_HDD_SOFTAP)
Jeff Johnson295189b2012-06-20 16:38:30 -07009517 {
Gopichand Nakkala681989c2013-03-06 22:27:48 -08009518 hddLog(VOS_TRACE_LEVEL_ERROR,
Sushant Kaushik8bc7df22014-04-09 17:55:29 +05309519 "%s: Not scanning on device_mode = %s (%d)",
9520 __func__, hdd_device_modetoString(pAdapter->device_mode),
9521 pAdapter->device_mode);
Jeff Johnson295189b2012-06-20 16:38:30 -07009522 return -EOPNOTSUPP;
9523 }
9524
9525 if (TRUE == pScanInfo->mScanPending)
9526 {
Kiet Lamac06e2c2013-10-23 16:25:07 +05309527 if ( MAX_PENDING_LOG > pScanInfo->mScanPendingCounter++ )
9528 {
9529 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: mScanPending is TRUE", __func__);
9530 }
Gopichand Nakkala681989c2013-03-06 22:27:48 -08009531 return -EBUSY;
Jeff Johnson295189b2012-06-20 16:38:30 -07009532 }
9533
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309534 //Don't Allow Scan and return busy if Remain On
Jeff Johnson32d95a32012-09-10 13:15:23 -07009535 //Channel and action frame is pending
9536 //Otherwise Cancel Remain On Channel and allow Scan
9537 //If no action frame pending
Gopichand Nakkala681989c2013-03-06 22:27:48 -08009538 if (0 != wlan_hdd_check_remain_on_channel(pAdapter))
Jeff Johnson32d95a32012-09-10 13:15:23 -07009539 {
Kiet Lamac06e2c2013-10-23 16:25:07 +05309540 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Remain On Channel Pending", __func__);
Jeff Johnson32d95a32012-09-10 13:15:23 -07009541 return -EBUSY;
9542 }
Gopichand Nakkala681989c2013-03-06 22:27:48 -08009543#ifdef FEATURE_WLAN_TDLS
Gopichand Nakkala638ebc72013-03-21 18:04:02 -07009544 /* if tdls disagree scan right now, return immediately.
9545 tdls will schedule the scan when scan is allowed. (return SUCCESS)
9546 or will reject the scan if any TDLS is in progress. (return -EBUSY)
9547 */
9548 status = wlan_hdd_tdls_scan_callback (pAdapter,
9549 wiphy,
9550#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,6,0))
9551 dev,
Gopichand Nakkalac3c42b92013-03-20 19:42:34 -07009552#endif
Gopichand Nakkala638ebc72013-03-21 18:04:02 -07009553 request);
9554 if(status <= 0)
9555 {
Nirav Shah20ac06f2013-12-12 18:14:06 +05309556 if(!status)
9557 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: TDLS in progress."
9558 "scan rejected %d", __func__, status);
9559 else
9560 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: TDLS teardown is ongoing %d",
9561 __func__, status);
9562
Gopichand Nakkala638ebc72013-03-21 18:04:02 -07009563 return status;
Gopichand Nakkala681989c2013-03-06 22:27:48 -08009564 }
9565#endif
Jeff Johnson32d95a32012-09-10 13:15:23 -07009566
Jeff Johnson295189b2012-06-20 16:38:30 -07009567 if (mutex_lock_interruptible(&pHddCtx->tmInfo.tmOperationLock))
9568 {
9569 VOS_TRACE(VOS_MODULE_ID_HDD,VOS_TRACE_LEVEL_ERROR,
Jeff Johnson1250df42012-12-10 14:31:52 -08009570 "%s: Acquire lock fail", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07009571 return -EAGAIN;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309572 }
Jeff Johnson295189b2012-06-20 16:38:30 -07009573 if (TRUE == pHddCtx->tmInfo.tmAction.enterImps)
9574 {
Nirav Shah20ac06f2013-12-12 18:14:06 +05309575 hddLog(VOS_TRACE_LEVEL_ERROR,
Jeff Johnson295189b2012-06-20 16:38:30 -07009576 "%s: MAX TM Level Scan not allowed", __func__);
9577 mutex_unlock(&pHddCtx->tmInfo.tmOperationLock);
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309578 return -EBUSY;
Jeff Johnson295189b2012-06-20 16:38:30 -07009579 }
9580 mutex_unlock(&pHddCtx->tmInfo.tmOperationLock);
9581
Madan Mohan Koyyalamudicfd53742013-01-11 15:29:03 -08009582 /* Check if scan is allowed at this point of time.
9583 */
Ganesh Kondabattiniaeb7b772014-08-11 20:00:36 +05309584 if (hdd_isConnectionInProgress(pHddCtx, VOS_FALSE))
Madan Mohan Koyyalamudicfd53742013-01-11 15:29:03 -08009585 {
9586 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Scan not allowed", __func__);
9587 return -EBUSY;
9588 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309589
Jeff Johnson295189b2012-06-20 16:38:30 -07009590 vos_mem_zero( &scanRequest, sizeof(scanRequest));
9591
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +05309592 hddLog(VOS_TRACE_LEVEL_INFO, "scan request for ssid = %d",
9593 (int)request->n_ssids);
9594
9595 /* Even though supplicant doesn't provide any SSIDs, n_ssids is set to 1.
9596 * Becasue of this, driver is assuming that this is not wildcard scan and so
9597 * is not aging out the scan results.
9598 */
9599 if (request->ssids && '\0' == request->ssids->ssid[0])
Jeff Johnson295189b2012-06-20 16:38:30 -07009600 {
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +05309601 request->n_ssids = 0;
Jeff Johnson295189b2012-06-20 16:38:30 -07009602 }
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +05309603
9604 if ((request->ssids) && (0 < request->n_ssids))
9605 {
9606 tCsrSSIDInfo *SsidInfo;
9607 int j;
9608 scanRequest.SSIDs.numOfSSIDs = request->n_ssids;
9609 /* Allocate num_ssid tCsrSSIDInfo structure */
9610 SsidInfo = scanRequest.SSIDs.SSIDList =
9611 ( tCsrSSIDInfo *)vos_mem_malloc(
9612 request->n_ssids*sizeof(tCsrSSIDInfo));
9613
9614 if(NULL == scanRequest.SSIDs.SSIDList)
9615 {
9616 hddLog(VOS_TRACE_LEVEL_ERROR,
9617 "%s: memory alloc failed SSIDInfo buffer", __func__);
9618 return -ENOMEM;
9619 }
9620
9621 /* copy all the ssid's and their length */
9622 for(j = 0; j < request->n_ssids; j++, SsidInfo++)
9623 {
9624 /* get the ssid length */
9625 SsidInfo->SSID.length = request->ssids[j].ssid_len;
9626 vos_mem_copy(SsidInfo->SSID.ssId, &request->ssids[j].ssid[0],
9627 SsidInfo->SSID.length);
9628 SsidInfo->SSID.ssId[SsidInfo->SSID.length] = '\0';
9629 hddLog(VOS_TRACE_LEVEL_INFO, "SSID number %d: %s",
9630 j, SsidInfo->SSID.ssId);
9631 }
9632 /* set the scan type to active */
9633 scanRequest.scanType = eSIR_ACTIVE_SCAN;
9634 }
9635 else if(WLAN_HDD_P2P_GO == pAdapter->device_mode)
Jeff Johnson295189b2012-06-20 16:38:30 -07009636 {
Siddharth Bhal0c162d02014-05-06 19:50:42 +05309637 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
9638 TRACE_CODE_HDD_CFG80211_SCAN,
9639 pAdapter->sessionId, 0));
Jeff Johnson295189b2012-06-20 16:38:30 -07009640 /* set the scan type to active */
9641 scanRequest.scanType = eSIR_ACTIVE_SCAN;
Jeff Johnson295189b2012-06-20 16:38:30 -07009642 }
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +05309643 else
9644 {
9645 /*Set the scan type to default type, in this case it is ACTIVE*/
9646 scanRequest.scanType = pScanInfo->scan_mode;
9647 }
9648 scanRequest.minChnTime = cfg_param->nActiveMinChnTime;
9649 scanRequest.maxChnTime = cfg_param->nActiveMaxChnTime;
Jeff Johnson295189b2012-06-20 16:38:30 -07009650
9651 /* set BSSType to default type */
9652 scanRequest.BSSType = eCSR_BSS_TYPE_ANY;
9653
9654 /*TODO: scan the requested channels only*/
9655
9656 /*Right now scanning all the channels */
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +05309657 if (MAX_CHANNEL < request->n_channels)
Jeff Johnson295189b2012-06-20 16:38:30 -07009658 {
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +05309659 hddLog(VOS_TRACE_LEVEL_WARN,
9660 "No of Scan Channels exceeded limit: %d", request->n_channels);
9661 request->n_channels = MAX_CHANNEL;
9662 }
9663
9664 hddLog(VOS_TRACE_LEVEL_INFO,
9665 "No of Scan Channels: %d", request->n_channels);
9666
9667
9668 if( request->n_channels )
9669 {
9670 char chList [(request->n_channels*5)+1];
9671 int len;
9672 channelList = vos_mem_malloc( request->n_channels );
9673 if( NULL == channelList )
c_hpothu53512302014-04-15 18:49:53 +05309674 {
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +05309675 hddLog(VOS_TRACE_LEVEL_ERROR,
9676 "%s: memory alloc failed channelList", __func__);
9677 status = -ENOMEM;
9678 goto free_mem;
c_hpothu53512302014-04-15 18:49:53 +05309679 }
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +05309680
9681 for( i = 0, len = 0; i < request->n_channels ; i++ )
9682 {
9683 channelList[i] = request->channels[i]->hw_value;
9684 len += snprintf(chList+len, 5, "%d ", channelList[i]);
9685 }
9686
Nirav Shah20ac06f2013-12-12 18:14:06 +05309687 hddLog(VOS_TRACE_LEVEL_INFO,
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +05309688 "Channel-List: %s ", chList);
9689 }
c_hpothu53512302014-04-15 18:49:53 +05309690
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +05309691 scanRequest.ChannelInfo.numOfChannels = request->n_channels;
9692 scanRequest.ChannelInfo.ChannelList = channelList;
9693
9694 /* set requestType to full scan */
9695 scanRequest.requestType = eCSR_SCAN_REQUEST_FULL_SCAN;
9696
9697 /* Flush the scan results(only p2p beacons) for STA scan and P2P
9698 * search (Flush on both full scan and social scan but not on single
9699 * channel scan).P2P search happens on 3 social channels (1, 6, 11)
9700 */
9701
9702 /* Supplicant does single channel scan after 8-way handshake
9703 * and in that case driver shoudnt flush scan results. If
9704 * driver flushes the scan results here and unfortunately if
9705 * the AP doesnt respond to our probe req then association
9706 * fails which is not desired
9707 */
9708
9709 if( request->n_channels != WLAN_HDD_P2P_SINGLE_CHANNEL_SCAN )
9710 {
9711 hddLog(VOS_TRACE_LEVEL_DEBUG, "Flushing P2P Results");
9712 sme_ScanFlushP2PResult( WLAN_HDD_GET_HAL_CTX(pAdapter),
9713 pAdapter->sessionId );
9714 }
9715
9716 if( request->ie_len )
9717 {
9718 /* save this for future association (join requires this) */
9719 /*TODO: Array needs to be converted to dynamic allocation,
9720 * as multiple ie.s can be sent in cfg80211_scan_request structure
9721 * CR 597966
9722 */
9723 memset( &pScanInfo->scanAddIE, 0, sizeof(pScanInfo->scanAddIE) );
9724 memcpy( pScanInfo->scanAddIE.addIEdata, request->ie, request->ie_len);
9725 pScanInfo->scanAddIE.length = request->ie_len;
9726
9727 if ((WLAN_HDD_INFRA_STATION == pAdapter->device_mode) ||
9728 (WLAN_HDD_P2P_CLIENT == pAdapter->device_mode) ||
9729 (WLAN_HDD_P2P_DEVICE == pAdapter->device_mode))
Jeff Johnson295189b2012-06-20 16:38:30 -07009730 {
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +05309731 if ( request->ie_len <= SIR_MAC_MAX_IE_LENGTH)
Jeff Johnson295189b2012-06-20 16:38:30 -07009732 {
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +05309733 pwextBuf->roamProfile.nAddIEScanLength = request->ie_len;
9734 memcpy( pwextBuf->roamProfile.addIEScan,
9735 request->ie, request->ie_len);
9736 }
9737 else
9738 {
9739 hddLog(VOS_TRACE_LEVEL_ERROR, "Scan Ie length is invalid:"
9740 "%zu", request->ie_len);
Jeff Johnson295189b2012-06-20 16:38:30 -07009741 }
9742
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +05309743 }
9744 scanRequest.uIEFieldLen = pScanInfo->scanAddIE.length;
9745 scanRequest.pIEField = pScanInfo->scanAddIE.addIEdata;
9746
9747 pP2pIe = wlan_hdd_get_p2p_ie_ptr((v_U8_t*)request->ie,
9748 request->ie_len);
9749 if (pP2pIe != NULL)
9750 {
9751#ifdef WLAN_FEATURE_P2P_DEBUG
9752 if (((globalP2PConnectionStatus == P2P_GO_NEG_COMPLETED) ||
9753 (globalP2PConnectionStatus == P2P_GO_NEG_PROCESS)) &&
9754 (WLAN_HDD_P2P_CLIENT == pAdapter->device_mode))
Nirav Shah20ac06f2013-12-12 18:14:06 +05309755 {
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +05309756 globalP2PConnectionStatus = P2P_CLIENT_CONNECTING_STATE_1;
9757 hddLog(VOS_TRACE_LEVEL_ERROR,"[P2P State] Changing state from "
9758 "Go nego completed to Connection is started");
9759 hddLog(VOS_TRACE_LEVEL_ERROR,"[P2P]P2P Scanning is started "
9760 "for 8way Handshake");
Nirav Shah20ac06f2013-12-12 18:14:06 +05309761 }
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +05309762 else if((globalP2PConnectionStatus == P2P_CLIENT_DISCONNECTED_STATE) &&
9763 (WLAN_HDD_P2P_CLIENT == pAdapter->device_mode))
Jeff Johnson295189b2012-06-20 16:38:30 -07009764 {
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +05309765 globalP2PConnectionStatus = P2P_CLIENT_CONNECTING_STATE_2;
9766 hddLog(VOS_TRACE_LEVEL_ERROR,"[P2P State] Changing state from "
9767 "Disconnected state to Connection is started");
9768 hddLog(VOS_TRACE_LEVEL_ERROR,"[P2P]P2P Scanning is started "
9769 "for 4way Handshake");
9770 }
9771#endif
9772
9773 /* no_cck will be set during p2p find to disable 11b rates */
9774 if(TRUE == request->no_cck)
9775 {
9776 hddLog(VOS_TRACE_LEVEL_INFO,
9777 "%s: This is a P2P Search", __func__);
9778 scanRequest.p2pSearch = 1;
9779
9780 if( request->n_channels == WLAN_HDD_P2P_SOCIAL_CHANNELS )
Agarwal Ashish4f616132013-12-30 23:32:50 +05309781 {
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +05309782 /* set requestType to P2P Discovery */
9783 scanRequest.requestType = eCSR_SCAN_P2P_DISCOVERY;
9784 }
9785
9786 /*
9787 Skip Dfs Channel in case of P2P Search
9788 if it is set in ini file
9789 */
9790 if(cfg_param->skipDfsChnlInP2pSearch)
9791 {
9792 scanRequest.skipDfsChnlInP2pSearch = 1;
Agarwal Ashish4f616132013-12-30 23:32:50 +05309793 }
9794 else
9795 {
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +05309796 scanRequest.skipDfsChnlInP2pSearch = 0;
Agarwal Ashish4f616132013-12-30 23:32:50 +05309797 }
Jeff Johnson295189b2012-06-20 16:38:30 -07009798
Agarwal Ashish4f616132013-12-30 23:32:50 +05309799 }
Jeff Johnson295189b2012-06-20 16:38:30 -07009800 }
9801 }
9802
9803 INIT_COMPLETION(pScanInfo->scan_req_completion_event);
9804
Madan Mohan Koyyalamudi9f5a10c2012-09-28 14:46:16 -07009805 /* acquire the wakelock to avoid the apps suspend during the scan. To
9806 * address the following issues.
9807 * 1) Disconnected scenario: we are not allowing the suspend as WLAN is not in
9808 * BMPS/IMPS this result in android trying to suspend aggressively and backing off
9809 * for long time, this result in apps running at full power for long time.
9810 * 2) Connected scenario: If we allow the suspend during the scan, RIVA will
9811 * be stuck in full power because of resume BMPS
9812 */
9813 hdd_prevent_suspend();
Jeff Johnsone7245742012-09-05 17:12:55 -07009814
Nirav Shah20ac06f2013-12-12 18:14:06 +05309815 hddLog(VOS_TRACE_LEVEL_INFO_HIGH,
9816 "requestType %d, scanType %d, minChnTime %d, maxChnTime %d,"
Sushant Kaushik8bc7df22014-04-09 17:55:29 +05309817 "p2pSearch %d, skipDfsChnlInP2pSearch %d",
9818 scanRequest.requestType, scanRequest.scanType,
9819 scanRequest.minChnTime, scanRequest.maxChnTime,
Nirav Shah20ac06f2013-12-12 18:14:06 +05309820 scanRequest.p2pSearch, scanRequest.skipDfsChnlInP2pSearch);
9821
Jeff Johnsone7245742012-09-05 17:12:55 -07009822 status = sme_ScanRequest( WLAN_HDD_GET_HAL_CTX(pAdapter),
Jeff Johnson295189b2012-06-20 16:38:30 -07009823 pAdapter->sessionId, &scanRequest, &scanId,
9824 &hdd_cfg80211_scan_done_callback, dev );
Jeff Johnsone7245742012-09-05 17:12:55 -07009825
Jeff Johnson295189b2012-06-20 16:38:30 -07009826 if (eHAL_STATUS_SUCCESS != status)
9827 {
9828 hddLog(VOS_TRACE_LEVEL_ERROR,
9829 "%s: sme_ScanRequest returned error %d", __func__, status);
9830 complete(&pScanInfo->scan_req_completion_event);
Madan Mohan Koyyalamudi3b230fe2012-10-18 14:46:32 -07009831 if(eHAL_STATUS_RESOURCES == status)
9832 {
Nirav Shah20ac06f2013-12-12 18:14:06 +05309833 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: HO is in progress."
9834 "So defer the scan by informing busy",__func__);
Madan Mohan Koyyalamudi3b230fe2012-10-18 14:46:32 -07009835 status = -EBUSY;
9836 } else {
9837 status = -EIO;
9838 }
Madan Mohan Koyyalamudi9f5a10c2012-09-28 14:46:16 -07009839 hdd_allow_suspend();
Jeff Johnson295189b2012-06-20 16:38:30 -07009840 goto free_mem;
9841 }
9842
9843 pScanInfo->mScanPending = TRUE;
Kaushik, Sushant4975a572014-10-21 16:07:48 +05309844 pScanInfo->sessionId = pAdapter->sessionId;
Jeff Johnson295189b2012-06-20 16:38:30 -07009845 pAdapter->request = request;
9846 pScanInfo->scanId = scanId;
9847
9848 complete(&pScanInfo->scan_req_completion_event);
9849
9850free_mem:
9851 if( scanRequest.SSIDs.SSIDList )
9852 {
9853 vos_mem_free(scanRequest.SSIDs.SSIDList);
9854 }
9855
9856 if( channelList )
9857 vos_mem_free( channelList );
9858
9859 EXIT();
9860
9861 return status;
9862}
9863
Mahesh A Saptasagarfafb7fe2014-05-16 13:19:37 +05309864int wlan_hdd_cfg80211_scan( struct wiphy *wiphy,
9865#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,6,0))
9866 struct net_device *dev,
9867#endif
9868 struct cfg80211_scan_request *request)
9869{
9870 int ret;
9871
9872 vos_ssr_protect(__func__);
9873 ret = __wlan_hdd_cfg80211_scan(wiphy,
9874#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,6,0))
9875 dev,
9876#endif
9877 request);
9878 vos_ssr_unprotect(__func__);
9879
9880 return ret;
9881}
Shailender Karmuchi15cd0672013-05-15 19:50:04 -07009882
9883void hdd_select_cbmode( hdd_adapter_t *pAdapter,v_U8_t operationChannel)
9884{
9885 v_U8_t iniDot11Mode =
9886 (WLAN_HDD_GET_CTX(pAdapter))->cfg_ini->dot11Mode;
9887 eHddDot11Mode hddDot11Mode = iniDot11Mode;
9888
Arun Kumar Khandavalli94a2bb02013-12-28 19:17:25 +05309889 hddLog(LOG1, FL("Channel Bonding Mode Selected is %u"),
9890 iniDot11Mode);
Shailender Karmuchi15cd0672013-05-15 19:50:04 -07009891 switch ( iniDot11Mode )
9892 {
9893 case eHDD_DOT11_MODE_AUTO:
9894 case eHDD_DOT11_MODE_11ac:
9895 case eHDD_DOT11_MODE_11ac_ONLY:
9896#ifdef WLAN_FEATURE_11AC
Abhishek Singh4b1d2352014-08-01 21:59:28 +05309897 if ( sme_IsFeatureSupportedByDriver(DOT11AC) &&
9898 sme_IsFeatureSupportedByFW(DOT11AC) )
9899 hddDot11Mode = eHDD_DOT11_MODE_11ac;
9900 else
9901 hddDot11Mode = eHDD_DOT11_MODE_11n;
Shailender Karmuchi15cd0672013-05-15 19:50:04 -07009902#else
9903 hddDot11Mode = eHDD_DOT11_MODE_11n;
9904#endif
9905 break;
9906 case eHDD_DOT11_MODE_11n:
9907 case eHDD_DOT11_MODE_11n_ONLY:
9908 hddDot11Mode = eHDD_DOT11_MODE_11n;
9909 break;
9910 default:
9911 hddDot11Mode = iniDot11Mode;
9912 break;
9913 }
9914 /* This call decides required channel bonding mode */
9915 sme_SelectCBMode((WLAN_HDD_GET_CTX(pAdapter)->hHal),
9916 hdd_cfg_xlate_to_csr_phy_mode(hddDot11Mode),
9917 operationChannel);
9918}
9919
Jeff Johnson295189b2012-06-20 16:38:30 -07009920/*
9921 * FUNCTION: wlan_hdd_cfg80211_connect_start
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309922 * This function is used to start the association process
Jeff Johnson295189b2012-06-20 16:38:30 -07009923 */
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309924int wlan_hdd_cfg80211_connect_start( hdd_adapter_t *pAdapter,
Jeff Johnson32d95a32012-09-10 13:15:23 -07009925 const u8 *ssid, size_t ssid_len, const u8 *bssid, u8 operatingChannel)
Jeff Johnson295189b2012-06-20 16:38:30 -07009926{
9927 int status = 0;
9928 hdd_wext_state_t *pWextState;
Yue Mae36e3552014-03-05 17:06:20 -08009929 hdd_context_t *pHddCtx;
Jeff Johnson295189b2012-06-20 16:38:30 -07009930 v_U32_t roamId;
9931 tCsrRoamProfile *pRoamProfile;
Jeff Johnson295189b2012-06-20 16:38:30 -07009932 eCsrAuthType RSNAuthType;
9933
9934 ENTER();
9935
9936 pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
Yue Mae36e3552014-03-05 17:06:20 -08009937 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
9938
9939 status = wlan_hdd_validate_context(pHddCtx);
9940 if (status)
9941 {
9942 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
9943 "%s: HDD context is not valid!", __func__);
9944 return status;
9945 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309946
Jeff Johnson295189b2012-06-20 16:38:30 -07009947 if (SIR_MAC_MAX_SSID_LENGTH < ssid_len)
9948 {
9949 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: wrong SSID len", __func__);
9950 return -EINVAL;
9951 }
9952
9953 pRoamProfile = &pWextState->roamProfile;
9954
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309955 if (pRoamProfile)
Jeff Johnson295189b2012-06-20 16:38:30 -07009956 {
Jeff Johnsone7245742012-09-05 17:12:55 -07009957 hdd_station_ctx_t *pHddStaCtx;
9958 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
Jeff Johnson295189b2012-06-20 16:38:30 -07009959
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309960 if (HDD_WMM_USER_MODE_NO_QOS ==
Jeff Johnson295189b2012-06-20 16:38:30 -07009961 (WLAN_HDD_GET_CTX(pAdapter))->cfg_ini->WmmMode)
9962 {
9963 /*QoS not enabled in cfg file*/
9964 pRoamProfile->uapsd_mask = 0;
9965 }
9966 else
9967 {
9968 /*QoS enabled, update uapsd mask from cfg file*/
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309969 pRoamProfile->uapsd_mask =
Jeff Johnson295189b2012-06-20 16:38:30 -07009970 (WLAN_HDD_GET_CTX(pAdapter))->cfg_ini->UapsdMask;
9971 }
9972
9973 pRoamProfile->SSIDs.numOfSSIDs = 1;
9974 pRoamProfile->SSIDs.SSIDList->SSID.length = ssid_len;
9975 vos_mem_zero(pRoamProfile->SSIDs.SSIDList->SSID.ssId,
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309976 sizeof(pRoamProfile->SSIDs.SSIDList->SSID.ssId));
Jeff Johnson295189b2012-06-20 16:38:30 -07009977 vos_mem_copy((void *)(pRoamProfile->SSIDs.SSIDList->SSID.ssId),
9978 ssid, ssid_len);
9979
9980 if (bssid)
9981 {
9982 pRoamProfile->BSSIDs.numOfBSSIDs = 1;
9983 vos_mem_copy((void *)(pRoamProfile->BSSIDs.bssid), bssid,
9984 WNI_CFG_BSSID_LEN);
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309985 /* Save BSSID in seperate variable as well, as RoamProfile
9986 BSSID is getting zeroed out in the association process. And in
Jeff Johnson295189b2012-06-20 16:38:30 -07009987 case of join failure we should send valid BSSID to supplicant
9988 */
9989 vos_mem_copy((void *)(pWextState->req_bssId), bssid,
9990 WNI_CFG_BSSID_LEN);
9991 }
Dhanashri Atre51981c62013-06-13 11:47:57 -07009992 else
9993 {
9994 vos_mem_zero((void *)(pRoamProfile->BSSIDs.bssid),WNI_CFG_BSSID_LEN);
9995 }
Jeff Johnson295189b2012-06-20 16:38:30 -07009996
Arun Kumar Khandavalli94a2bb02013-12-28 19:17:25 +05309997 hddLog(LOG1, FL("Connect to SSID: %s opertating Channel: %u"),
9998 pRoamProfile->SSIDs.SSIDList->SSID.ssId, operatingChannel);
Jeff Johnson295189b2012-06-20 16:38:30 -07009999 if ((IW_AUTH_WPA_VERSION_WPA == pWextState->wpaVersion) ||
10000 (IW_AUTH_WPA_VERSION_WPA2 == pWextState->wpaVersion))
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010001 {
Jeff Johnson295189b2012-06-20 16:38:30 -070010002 /*set gen ie*/
10003 hdd_SetGENIEToCsr(pAdapter, &RSNAuthType);
10004 /*set auth*/
10005 hdd_set_csr_auth_type(pAdapter, RSNAuthType);
10006 }
Jeff Johnson295189b2012-06-20 16:38:30 -070010007#ifdef FEATURE_WLAN_WAPI
10008 if (pAdapter->wapi_info.nWapiMode)
10009 {
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -070010010 hddLog(LOG1, "%s: Setting WAPI AUTH Type and Encryption Mode values", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -070010011 switch (pAdapter->wapi_info.wapiAuthMode)
10012 {
10013 case WAPI_AUTH_MODE_PSK:
10014 {
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -070010015 hddLog(LOG1, "%s: WAPI AUTH TYPE: PSK: %d", __func__,
Jeff Johnson295189b2012-06-20 16:38:30 -070010016 pAdapter->wapi_info.wapiAuthMode);
10017 pRoamProfile->AuthType.authType[0] = eCSR_AUTH_TYPE_WAPI_WAI_PSK;
10018 break;
10019 }
10020 case WAPI_AUTH_MODE_CERT:
10021 {
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -070010022 hddLog(LOG1, "%s: WAPI AUTH TYPE: CERT: %d", __func__,
Jeff Johnson295189b2012-06-20 16:38:30 -070010023 pAdapter->wapi_info.wapiAuthMode);
10024 pRoamProfile->AuthType.authType[0] = eCSR_AUTH_TYPE_WAPI_WAI_CERTIFICATE;
10025 break;
10026 }
10027 } // End of switch
10028 if ( pAdapter->wapi_info.wapiAuthMode == WAPI_AUTH_MODE_PSK ||
10029 pAdapter->wapi_info.wapiAuthMode == WAPI_AUTH_MODE_CERT)
10030 {
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -070010031 hddLog(LOG1, "%s: WAPI PAIRWISE/GROUP ENCRYPTION: WPI", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -070010032 pRoamProfile->AuthType.numEntries = 1;
10033 pRoamProfile->EncryptionType.numEntries = 1;
10034 pRoamProfile->EncryptionType.encryptionType[0] = eCSR_ENCRYPT_TYPE_WPI;
10035 pRoamProfile->mcEncryptionType.numEntries = 1;
10036 pRoamProfile->mcEncryptionType.encryptionType[0] = eCSR_ENCRYPT_TYPE_WPI;
10037 }
10038 }
10039#endif /* FEATURE_WLAN_WAPI */
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053010040#ifdef WLAN_FEATURE_GTK_OFFLOAD
Gopichand Nakkalad36ee622013-05-07 14:13:27 +053010041 /* Initializing gtkOffloadReqParams */
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053010042 if ((WLAN_HDD_INFRA_STATION == pAdapter->device_mode) ||
10043 (WLAN_HDD_P2P_CLIENT == pAdapter->device_mode))
10044 {
Gopichand Nakkalad36ee622013-05-07 14:13:27 +053010045 memset(&pHddStaCtx->gtkOffloadReqParams, 0,
10046 sizeof (tSirGtkOffloadParams));
10047 pHddStaCtx->gtkOffloadReqParams.ulFlags = GTK_OFFLOAD_DISABLE;
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053010048 }
10049#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070010050 pRoamProfile->csrPersona = pAdapter->device_mode;
10051
Jeff Johnson32d95a32012-09-10 13:15:23 -070010052 if( operatingChannel )
10053 {
10054 pRoamProfile->ChannelInfo.ChannelList = &operatingChannel;
10055 pRoamProfile->ChannelInfo.numOfChannels = 1;
10056 }
Chet Lanctot186b5732013-03-18 10:26:30 -070010057 else
10058 {
10059 pRoamProfile->ChannelInfo.ChannelList = NULL;
10060 pRoamProfile->ChannelInfo.numOfChannels = 0;
10061 }
Shailender Karmuchi15cd0672013-05-15 19:50:04 -070010062 if ( (WLAN_HDD_IBSS == pAdapter->device_mode) && operatingChannel)
10063 {
10064 hdd_select_cbmode(pAdapter,operatingChannel);
10065 }
Arun Kumar Khandavalli94a2bb02013-12-28 19:17:25 +053010066
Madan Mohan Koyyalamudi42dcd162012-12-03 16:34:04 -080010067 /* change conn_state to connecting before sme_RoamConnect(), because sme_RoamConnect()
10068 * has a direct path to call hdd_smeRoamCallback(), which will change the conn_state
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010069 * If direct path, conn_state will be accordingly changed to NotConnected or Associated
Madan Mohan Koyyalamudi42dcd162012-12-03 16:34:04 -080010070 * by either hdd_AssociationCompletionHandler() or hdd_DisConnectHandler() in sme_RoamCallback()
Madan Mohan Koyyalamudidf86c422012-12-04 17:03:44 -080010071 * if sme_RomConnect is to be queued, Connecting state will remain until it is completed.
10072 */
Gopichand Nakkalaa3c8fb62013-06-21 15:36:42 +053010073 if (WLAN_HDD_INFRA_STATION == pAdapter->device_mode ||
10074 WLAN_HDD_P2P_CLIENT == pAdapter->device_mode)
Abhishek Singhf4669da2014-05-26 15:07:49 +053010075 {
10076 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
10077 "%s: Set HDD connState to eConnectionState_Connecting",
10078 __func__);
Madan Mohan Koyyalamudidf86c422012-12-04 17:03:44 -080010079 hdd_connSetConnectionState(WLAN_HDD_GET_STATION_CTX_PTR(pAdapter),
10080 eConnectionState_Connecting);
Abhishek Singhf4669da2014-05-26 15:07:49 +053010081 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010082 status = sme_RoamConnect( WLAN_HDD_GET_HAL_CTX(pAdapter),
Jeff Johnson295189b2012-06-20 16:38:30 -070010083 pAdapter->sessionId, pRoamProfile, &roamId);
10084
Gopichand Nakkalaa3c8fb62013-06-21 15:36:42 +053010085 if ((eHAL_STATUS_SUCCESS != status) &&
10086 (WLAN_HDD_INFRA_STATION == pAdapter->device_mode ||
10087 WLAN_HDD_P2P_CLIENT == pAdapter->device_mode))
Madan Mohan Koyyalamudid5acbf52012-11-28 01:45:08 +053010088
10089 {
Madan Mohan Koyyalamudi42dcd162012-12-03 16:34:04 -080010090 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: sme_RoamConnect (session %d) failed with "
10091 "status %d. -> NotConnected", __func__, pAdapter->sessionId, status);
10092 /* change back to NotAssociated */
Madan Mohan Koyyalamudid5acbf52012-11-28 01:45:08 +053010093 hdd_connSetConnectionState(WLAN_HDD_GET_STATION_CTX_PTR(pAdapter),
Madan Mohan Koyyalamudi42dcd162012-12-03 16:34:04 -080010094 eConnectionState_NotConnected);
Madan Mohan Koyyalamudid5acbf52012-11-28 01:45:08 +053010095 }
Madan Mohan Koyyalamudidf86c422012-12-04 17:03:44 -080010096
10097 pRoamProfile->ChannelInfo.ChannelList = NULL;
10098 pRoamProfile->ChannelInfo.numOfChannels = 0;
10099
Jeff Johnson295189b2012-06-20 16:38:30 -070010100 }
10101 else
10102 {
10103 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: No valid Roam profile", __func__);
10104 return -EINVAL;
10105 }
Madan Mohan Koyyalamudifd4e1da2012-11-09 17:50:19 -080010106 EXIT();
Jeff Johnson295189b2012-06-20 16:38:30 -070010107 return status;
10108}
10109
10110/*
10111 * FUNCTION: wlan_hdd_set_cfg80211_auth_type
10112 * This function is used to set the authentication type (OPEN/SHARED).
10113 *
10114 */
10115static int wlan_hdd_cfg80211_set_auth_type(hdd_adapter_t *pAdapter,
10116 enum nl80211_auth_type auth_type)
10117{
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010118 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
Jeff Johnson295189b2012-06-20 16:38:30 -070010119 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
10120
10121 ENTER();
10122
10123 /*set authentication type*/
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010124 switch (auth_type)
Jeff Johnson295189b2012-06-20 16:38:30 -070010125 {
Jeff Johnson295189b2012-06-20 16:38:30 -070010126 case NL80211_AUTHTYPE_AUTOMATIC:
Gopichand Nakkala29149562013-05-10 21:43:41 +053010127 hddLog(VOS_TRACE_LEVEL_INFO,
10128 "%s: set authentication type to AUTOSWITCH", __func__);
10129 pHddStaCtx->conn_info.authType = eCSR_AUTH_TYPE_AUTOSWITCH;
10130 break;
10131
10132 case NL80211_AUTHTYPE_OPEN_SYSTEM:
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070010133#ifdef WLAN_FEATURE_VOWIFI_11R
10134 case NL80211_AUTHTYPE_FT:
10135#endif /* WLAN_FEATURE_VOWIFI_11R */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010136 hddLog(VOS_TRACE_LEVEL_INFO,
Jeff Johnson295189b2012-06-20 16:38:30 -070010137 "%s: set authentication type to OPEN", __func__);
10138 pHddStaCtx->conn_info.authType = eCSR_AUTH_TYPE_OPEN_SYSTEM;
10139 break;
10140
10141 case NL80211_AUTHTYPE_SHARED_KEY:
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010142 hddLog(VOS_TRACE_LEVEL_INFO,
Jeff Johnson295189b2012-06-20 16:38:30 -070010143 "%s: set authentication type to SHARED", __func__);
10144 pHddStaCtx->conn_info.authType = eCSR_AUTH_TYPE_SHARED_KEY;
10145 break;
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -080010146#ifdef FEATURE_WLAN_ESE
Jeff Johnson295189b2012-06-20 16:38:30 -070010147 case NL80211_AUTHTYPE_NETWORK_EAP:
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010148 hddLog(VOS_TRACE_LEVEL_INFO,
Jeff Johnson295189b2012-06-20 16:38:30 -070010149 "%s: set authentication type to CCKM WPA", __func__);
10150 pHddStaCtx->conn_info.authType = eCSR_AUTH_TYPE_CCKM_WPA;//eCSR_AUTH_TYPE_CCKM_RSN needs to be handled as well if required.
10151 break;
10152#endif
10153
10154
10155 default:
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010156 hddLog(VOS_TRACE_LEVEL_ERROR,
10157 "%s: Unsupported authentication type %d", __func__,
Jeff Johnson295189b2012-06-20 16:38:30 -070010158 auth_type);
10159 pHddStaCtx->conn_info.authType = eCSR_AUTH_TYPE_UNKNOWN;
10160 return -EINVAL;
10161 }
10162
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010163 pWextState->roamProfile.AuthType.authType[0] =
Jeff Johnson295189b2012-06-20 16:38:30 -070010164 pHddStaCtx->conn_info.authType;
10165 return 0;
10166}
10167
10168/*
10169 * FUNCTION: wlan_hdd_set_akm_suite
10170 * This function is used to set the key mgmt type(PSK/8021x).
10171 *
10172 */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010173static int wlan_hdd_set_akm_suite( hdd_adapter_t *pAdapter,
Jeff Johnson295189b2012-06-20 16:38:30 -070010174 u32 key_mgmt
10175 )
10176{
10177 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
10178 ENTER();
Abhishek Singhae408032014-09-25 17:22:04 +053010179 /* Should be in ieee802_11_defs.h */
10180#define WLAN_AKM_SUITE_8021X_SHA256 0x000FAC05
10181#define WLAN_AKM_SUITE_PSK_SHA256 0x000FAC06
Jeff Johnson295189b2012-06-20 16:38:30 -070010182 /*set key mgmt type*/
10183 switch(key_mgmt)
10184 {
10185 case WLAN_AKM_SUITE_PSK:
Abhishek Singhae408032014-09-25 17:22:04 +053010186 case WLAN_AKM_SUITE_PSK_SHA256:
Gopichand Nakkala356fb102013-03-06 12:34:04 +053010187#ifdef WLAN_FEATURE_VOWIFI_11R
10188 case WLAN_AKM_SUITE_FT_PSK:
10189#endif
10190 hddLog(VOS_TRACE_LEVEL_INFO, "%s: setting key mgmt type to PSK",
Jeff Johnson295189b2012-06-20 16:38:30 -070010191 __func__);
10192 pWextState->authKeyMgmt |= IW_AUTH_KEY_MGMT_PSK;
10193 break;
10194
10195 case WLAN_AKM_SUITE_8021X:
Abhishek Singhae408032014-09-25 17:22:04 +053010196 case WLAN_AKM_SUITE_8021X_SHA256:
Gopichand Nakkala356fb102013-03-06 12:34:04 +053010197#ifdef WLAN_FEATURE_VOWIFI_11R
10198 case WLAN_AKM_SUITE_FT_8021X:
10199#endif
10200 hddLog(VOS_TRACE_LEVEL_INFO, "%s: setting key mgmt type to 8021x",
Jeff Johnson295189b2012-06-20 16:38:30 -070010201 __func__);
10202 pWextState->authKeyMgmt |= IW_AUTH_KEY_MGMT_802_1X;
10203 break;
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -080010204#ifdef FEATURE_WLAN_ESE
Jeff Johnson295189b2012-06-20 16:38:30 -070010205#define WLAN_AKM_SUITE_CCKM 0x00409600 /* Should be in ieee802_11_defs.h */
10206#define IW_AUTH_KEY_MGMT_CCKM 8 /* Should be in linux/wireless.h */
10207 case WLAN_AKM_SUITE_CCKM:
10208 hddLog(VOS_TRACE_LEVEL_INFO, "%s: setting key mgmt type to CCKM",
10209 __func__);
10210 pWextState->authKeyMgmt |= IW_AUTH_KEY_MGMT_CCKM;
10211 break;
10212#endif
Leela Venkata Kiran Kumar Reddy Chiralae208a832014-04-27 22:34:25 -070010213#ifndef WLAN_AKM_SUITE_OSEN
10214#define WLAN_AKM_SUITE_OSEN 0x506f9a01 /* Should be in ieee802_11_defs.h */
10215 case WLAN_AKM_SUITE_OSEN:
10216 hddLog(VOS_TRACE_LEVEL_INFO, "%s: setting key mgmt type to OSEN",
10217 __func__);
10218 pWextState->authKeyMgmt |= IW_AUTH_KEY_MGMT_802_1X;
10219 break;
10220#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070010221
10222 default:
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010223 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Unsupported key mgmt type %d",
Jeff Johnson295189b2012-06-20 16:38:30 -070010224 __func__, key_mgmt);
10225 return -EINVAL;
10226
10227 }
10228 return 0;
10229}
10230
10231/*
10232 * FUNCTION: wlan_hdd_cfg80211_set_cipher
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010233 * This function is used to set the encryption type
Jeff Johnson295189b2012-06-20 16:38:30 -070010234 * (NONE/WEP40/WEP104/TKIP/CCMP).
10235 */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010236static int wlan_hdd_cfg80211_set_cipher( hdd_adapter_t *pAdapter,
10237 u32 cipher,
Jeff Johnson295189b2012-06-20 16:38:30 -070010238 bool ucast
10239 )
10240{
10241 eCsrEncryptionType encryptionType = eCSR_ENCRYPT_TYPE_NONE;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010242 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
Jeff Johnson295189b2012-06-20 16:38:30 -070010243 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
10244
10245 ENTER();
10246
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010247 if (!cipher)
Jeff Johnson295189b2012-06-20 16:38:30 -070010248 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010249 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: received cipher %d - considering none",
Jeff Johnson295189b2012-06-20 16:38:30 -070010250 __func__, cipher);
10251 encryptionType = eCSR_ENCRYPT_TYPE_NONE;
10252 }
10253 else
10254 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010255
Jeff Johnson295189b2012-06-20 16:38:30 -070010256 /*set encryption method*/
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010257 switch (cipher)
Jeff Johnson295189b2012-06-20 16:38:30 -070010258 {
10259 case IW_AUTH_CIPHER_NONE:
10260 encryptionType = eCSR_ENCRYPT_TYPE_NONE;
10261 break;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010262
Jeff Johnson295189b2012-06-20 16:38:30 -070010263 case WLAN_CIPHER_SUITE_WEP40:
Gopichand Nakkala29149562013-05-10 21:43:41 +053010264 encryptionType = eCSR_ENCRYPT_TYPE_WEP40;
Jeff Johnson295189b2012-06-20 16:38:30 -070010265 break;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010266
Jeff Johnson295189b2012-06-20 16:38:30 -070010267 case WLAN_CIPHER_SUITE_WEP104:
Gopichand Nakkala29149562013-05-10 21:43:41 +053010268 encryptionType = eCSR_ENCRYPT_TYPE_WEP104;
Jeff Johnson295189b2012-06-20 16:38:30 -070010269 break;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010270
Jeff Johnson295189b2012-06-20 16:38:30 -070010271 case WLAN_CIPHER_SUITE_TKIP:
10272 encryptionType = eCSR_ENCRYPT_TYPE_TKIP;
10273 break;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010274
Jeff Johnson295189b2012-06-20 16:38:30 -070010275 case WLAN_CIPHER_SUITE_CCMP:
10276 encryptionType = eCSR_ENCRYPT_TYPE_AES;
10277 break;
10278#ifdef FEATURE_WLAN_WAPI
10279 case WLAN_CIPHER_SUITE_SMS4:
10280 encryptionType = eCSR_ENCRYPT_TYPE_WPI;
10281 break;
10282#endif
10283
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -080010284#ifdef FEATURE_WLAN_ESE
Jeff Johnson295189b2012-06-20 16:38:30 -070010285 case WLAN_CIPHER_SUITE_KRK:
10286 encryptionType = eCSR_ENCRYPT_TYPE_KRK;
10287 break;
10288#endif
10289 default:
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010290 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Unsupported cipher type %d",
Jeff Johnson295189b2012-06-20 16:38:30 -070010291 __func__, cipher);
10292 return -EOPNOTSUPP;
10293 }
10294 }
10295
10296 if (ucast)
10297 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010298 hddLog(VOS_TRACE_LEVEL_INFO, "%s: setting unicast cipher type to %d",
Jeff Johnson295189b2012-06-20 16:38:30 -070010299 __func__, encryptionType);
10300 pHddStaCtx->conn_info.ucEncryptionType = encryptionType;
10301 pWextState->roamProfile.EncryptionType.numEntries = 1;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010302 pWextState->roamProfile.EncryptionType.encryptionType[0] =
Jeff Johnson295189b2012-06-20 16:38:30 -070010303 encryptionType;
10304 }
10305 else
10306 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010307 hddLog(VOS_TRACE_LEVEL_INFO, "%s: setting mcast cipher type to %d",
Jeff Johnson295189b2012-06-20 16:38:30 -070010308 __func__, encryptionType);
10309 pHddStaCtx->conn_info.mcEncryptionType = encryptionType;
10310 pWextState->roamProfile.mcEncryptionType.numEntries = 1;
10311 pWextState->roamProfile.mcEncryptionType.encryptionType[0] = encryptionType;
10312 }
10313
10314 return 0;
10315}
10316
10317
10318/*
10319 * FUNCTION: wlan_hdd_cfg80211_set_ie
10320 * This function is used to parse WPA/RSN IE's.
10321 */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010322int wlan_hdd_cfg80211_set_ie( hdd_adapter_t *pAdapter,
10323 u8 *ie,
Jeff Johnson295189b2012-06-20 16:38:30 -070010324 size_t ie_len
10325 )
10326{
10327 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
10328 u8 *genie = ie;
10329 v_U16_t remLen = ie_len;
10330#ifdef FEATURE_WLAN_WAPI
10331 v_U32_t akmsuite[MAX_NUM_AKM_SUITES];
10332 u16 *tmp;
10333 v_U16_t akmsuiteCount;
10334 int *akmlist;
10335#endif
10336 ENTER();
10337
10338 /* clear previous assocAddIE */
10339 pWextState->assocAddIE.length = 0;
10340 pWextState->roamProfile.bWPSAssociation = VOS_FALSE;
Leela Venkata Kiran Kumar Reddy Chiralaf257bef2014-04-11 18:48:12 -070010341 pWextState->roamProfile.bOSENAssociation = VOS_FALSE;
Jeff Johnson295189b2012-06-20 16:38:30 -070010342
10343 while (remLen >= 2)
10344 {
10345 v_U16_t eLen = 0;
10346 v_U8_t elementId;
10347 elementId = *genie++;
10348 eLen = *genie++;
10349 remLen -= 2;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010350
Arif Hussain6d2a3322013-11-17 19:50:10 -080010351 hddLog(VOS_TRACE_LEVEL_INFO, "%s: IE[0x%X], LEN[%d]",
Jeff Johnson295189b2012-06-20 16:38:30 -070010352 __func__, elementId, eLen);
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010353
10354 switch ( elementId )
Jeff Johnson295189b2012-06-20 16:38:30 -070010355 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010356 case DOT11F_EID_WPA:
Madan Mohan Koyyalamudief3b66e2012-10-11 14:29:42 -070010357 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 -070010358 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010359 hddLog(VOS_TRACE_LEVEL_ERROR,
Jeff Johnson295189b2012-06-20 16:38:30 -070010360 "%s: Invalid WPA IE", __func__);
10361 return -EINVAL;
10362 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010363 else if (0 == memcmp(&genie[0], "\x00\x50\xf2\x04", 4))
Jeff Johnson295189b2012-06-20 16:38:30 -070010364 {
10365 v_U16_t curAddIELen = pWextState->assocAddIE.length;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010366 hddLog (VOS_TRACE_LEVEL_INFO, "%s Set WPS IE(len %d)",
Jeff Johnson295189b2012-06-20 16:38:30 -070010367 __func__, eLen + 2);
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010368
Jeff Johnson295189b2012-06-20 16:38:30 -070010369 if( SIR_MAC_MAX_IE_LENGTH < (pWextState->assocAddIE.length + eLen) )
10370 {
Jeff Johnson902c9832012-12-10 14:28:09 -080010371 hddLog(VOS_TRACE_LEVEL_FATAL, "Cannot accommodate assocAddIE. "
10372 "Need bigger buffer space");
Jeff Johnson295189b2012-06-20 16:38:30 -070010373 VOS_ASSERT(0);
10374 return -ENOMEM;
10375 }
10376 // WSC IE is saved to Additional IE ; it should be accumulated to handle WPS IE + P2P IE
10377 memcpy( pWextState->assocAddIE.addIEdata + curAddIELen, genie - 2, eLen + 2);
10378 pWextState->assocAddIE.length += eLen + 2;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010379
Jeff Johnson295189b2012-06-20 16:38:30 -070010380 pWextState->roamProfile.bWPSAssociation = VOS_TRUE;
10381 pWextState->roamProfile.pAddIEAssoc = pWextState->assocAddIE.addIEdata;
10382 pWextState->roamProfile.nAddIEAssocLength = pWextState->assocAddIE.length;
10383 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010384 else if (0 == memcmp(&genie[0], "\x00\x50\xf2", 3))
10385 {
Jeff Johnson295189b2012-06-20 16:38:30 -070010386 hddLog (VOS_TRACE_LEVEL_INFO, "%s Set WPA IE (len %d)",__func__, eLen + 2);
10387 memset( pWextState->WPARSNIE, 0, MAX_WPA_RSN_IE_LEN );
10388 memcpy( pWextState->WPARSNIE, genie - 2, (eLen + 2) /*ie_len*/);
10389 pWextState->roamProfile.pWPAReqIE = pWextState->WPARSNIE;
10390 pWextState->roamProfile.nWPAReqIELength = eLen + 2;//ie_len;
10391 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010392 else if ( (0 == memcmp(&genie[0], P2P_OUI_TYPE,
Kiet Lam8da98992013-11-21 15:59:07 +053010393 P2P_OUI_TYPE_SIZE)))
Jeff Johnson295189b2012-06-20 16:38:30 -070010394 {
10395 v_U16_t curAddIELen = pWextState->assocAddIE.length;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010396 hddLog (VOS_TRACE_LEVEL_INFO, "%s Set P2P IE(len %d)",
Jeff Johnson295189b2012-06-20 16:38:30 -070010397 __func__, eLen + 2);
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010398
Jeff Johnson295189b2012-06-20 16:38:30 -070010399 if( SIR_MAC_MAX_IE_LENGTH < (pWextState->assocAddIE.length + eLen) )
10400 {
Jeff Johnson902c9832012-12-10 14:28:09 -080010401 hddLog(VOS_TRACE_LEVEL_FATAL, "Cannot accommodate assocAddIE "
10402 "Need bigger buffer space");
Jeff Johnson295189b2012-06-20 16:38:30 -070010403 VOS_ASSERT(0);
10404 return -ENOMEM;
10405 }
10406 // P2P IE is saved to Additional IE ; it should be accumulated to handle WPS IE + P2P IE
10407 memcpy( pWextState->assocAddIE.addIEdata + curAddIELen, genie - 2, eLen + 2);
10408 pWextState->assocAddIE.length += eLen + 2;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010409
Jeff Johnson295189b2012-06-20 16:38:30 -070010410 pWextState->roamProfile.pAddIEAssoc = pWextState->assocAddIE.addIEdata;
10411 pWextState->roamProfile.nAddIEAssocLength = pWextState->assocAddIE.length;
10412 }
Jeff Johnson295189b2012-06-20 16:38:30 -070010413#ifdef WLAN_FEATURE_WFD
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010414 else if ( (0 == memcmp(&genie[0], WFD_OUI_TYPE,
10415 WFD_OUI_TYPE_SIZE))
Jeff Johnson295189b2012-06-20 16:38:30 -070010416 /*Consider WFD IE, only for P2P Client */
10417 && (WLAN_HDD_P2P_CLIENT == pAdapter->device_mode) )
10418 {
10419 v_U16_t curAddIELen = pWextState->assocAddIE.length;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010420 hddLog (VOS_TRACE_LEVEL_INFO, "%s Set WFD IE(len %d)",
Jeff Johnson295189b2012-06-20 16:38:30 -070010421 __func__, eLen + 2);
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010422
Jeff Johnson295189b2012-06-20 16:38:30 -070010423 if( SIR_MAC_MAX_IE_LENGTH < (pWextState->assocAddIE.length + eLen) )
10424 {
Jeff Johnson902c9832012-12-10 14:28:09 -080010425 hddLog(VOS_TRACE_LEVEL_FATAL, "Cannot accommodate assocAddIE "
10426 "Need bigger buffer space");
Jeff Johnson295189b2012-06-20 16:38:30 -070010427 VOS_ASSERT(0);
10428 return -ENOMEM;
10429 }
10430 // WFD IE is saved to Additional IE ; it should be accumulated to handle
10431 // WPS IE + P2P IE + WFD IE
10432 memcpy( pWextState->assocAddIE.addIEdata + curAddIELen, genie - 2, eLen + 2);
10433 pWextState->assocAddIE.length += eLen + 2;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010434
Jeff Johnson295189b2012-06-20 16:38:30 -070010435 pWextState->roamProfile.pAddIEAssoc = pWextState->assocAddIE.addIEdata;
10436 pWextState->roamProfile.nAddIEAssocLength = pWextState->assocAddIE.length;
10437 }
10438#endif
Madan Mohan Koyyalamudief3b66e2012-10-11 14:29:42 -070010439 /* Appending HS 2.0 Indication Element in Assiciation Request */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010440 else if ( (0 == memcmp(&genie[0], HS20_OUI_TYPE,
Madan Mohan Koyyalamudi1bed5982012-10-22 14:38:06 -070010441 HS20_OUI_TYPE_SIZE)) )
10442 {
10443 v_U16_t curAddIELen = pWextState->assocAddIE.length;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010444 hddLog (VOS_TRACE_LEVEL_INFO, "%s Set HS20 IE(len %d)",
Madan Mohan Koyyalamudi1bed5982012-10-22 14:38:06 -070010445 __func__, eLen + 2);
Madan Mohan Koyyalamudief3b66e2012-10-11 14:29:42 -070010446
Madan Mohan Koyyalamudi1bed5982012-10-22 14:38:06 -070010447 if( SIR_MAC_MAX_IE_LENGTH < (pWextState->assocAddIE.length + eLen) )
10448 {
Jeff Johnson902c9832012-12-10 14:28:09 -080010449 hddLog(VOS_TRACE_LEVEL_FATAL, "Cannot accommodate assocAddIE "
10450 "Need bigger buffer space");
Madan Mohan Koyyalamudi1bed5982012-10-22 14:38:06 -070010451 VOS_ASSERT(0);
10452 return -ENOMEM;
10453 }
10454 memcpy( pWextState->assocAddIE.addIEdata + curAddIELen, genie - 2, eLen + 2);
10455 pWextState->assocAddIE.length += eLen + 2;
Madan Mohan Koyyalamudief3b66e2012-10-11 14:29:42 -070010456
Madan Mohan Koyyalamudi1bed5982012-10-22 14:38:06 -070010457 pWextState->roamProfile.pAddIEAssoc = pWextState->assocAddIE.addIEdata;
10458 pWextState->roamProfile.nAddIEAssocLength = pWextState->assocAddIE.length;
10459 }
Leela Venkata Kiran Kumar Reddy Chiralaf257bef2014-04-11 18:48:12 -070010460 /* Appending OSEN Information Element in Assiciation Request */
10461 else if ( (0 == memcmp(&genie[0], OSEN_OUI_TYPE,
10462 OSEN_OUI_TYPE_SIZE)) )
10463 {
10464 v_U16_t curAddIELen = pWextState->assocAddIE.length;
10465 hddLog (VOS_TRACE_LEVEL_INFO, "%s Set OSEN IE(len %d)",
10466 __func__, eLen + 2);
Madan Mohan Koyyalamudief3b66e2012-10-11 14:29:42 -070010467
Leela Venkata Kiran Kumar Reddy Chiralaf257bef2014-04-11 18:48:12 -070010468 if( SIR_MAC_MAX_IE_LENGTH < (pWextState->assocAddIE.length + eLen) )
10469 {
10470 hddLog(VOS_TRACE_LEVEL_FATAL, "Cannot accommodate assocAddIE "
10471 "Need bigger buffer space");
10472 VOS_ASSERT(0);
10473 return -ENOMEM;
10474 }
10475 memcpy( pWextState->assocAddIE.addIEdata + curAddIELen, genie - 2, eLen + 2);
10476 pWextState->assocAddIE.length += eLen + 2;
10477
10478 pWextState->roamProfile.bOSENAssociation = VOS_TRUE;
10479 pWextState->roamProfile.pAddIEAssoc = pWextState->assocAddIE.addIEdata;
10480 pWextState->roamProfile.nAddIEAssocLength = pWextState->assocAddIE.length;
10481 }
10482
10483 break;
Praveen Kumar Sirisilla7d68b7b2013-09-22 14:01:42 -070010484 if (WLAN_HDD_IBSS == pAdapter->device_mode) {
10485
10486 /* populating as ADDIE in beacon frames */
10487 if (ccmCfgSetStr(WLAN_HDD_GET_HAL_CTX(pAdapter),
10488 WNI_CFG_PROBE_RSP_BCN_ADDNIE_DATA, genie - 2, eLen + 2,
10489 NULL, eANI_BOOLEAN_FALSE)== eHAL_STATUS_SUCCESS)
10490 {
10491 if (ccmCfgSetInt(WLAN_HDD_GET_HAL_CTX(pAdapter),
10492 WNI_CFG_PROBE_RSP_BCN_ADDNIE_FLAG, 1,NULL,
10493 eANI_BOOLEAN_FALSE) == eHAL_STATUS_FAILURE)
10494 {
10495 hddLog(LOGE,
10496 "Coldn't pass "
10497 "WNI_CFG_PROBE_RSP_BCN_ADDNIE_FLAG to CCM");
10498 }
10499 }/* ccmCfgSetStr(,WNI_CFG_PROBE_RSP_BCN_ADDNIE_DATA, , )*/
10500 else
10501 hddLog(LOGE,
10502 "Could not pass on "
10503 "WNI_CFG_PROBE_RSP_BCN_ADDNIE_DATA to CCM");
10504
10505 /* IBSS mode doesn't contain params->proberesp_ies still
10506 beaconIE's need to be populated in probe response frames */
10507 if ( (NULL != (genie - 2)) && (0 != eLen + 2) )
10508 {
10509 u16 rem_probe_resp_ie_len = eLen + 2;
10510 u8 probe_rsp_ie_len[3] = {0};
10511 u8 counter = 0;
10512
10513 /* Check Probe Resp Length if it is greater then 255 then
10514 Store Probe Rsp IEs into WNI_CFG_PROBE_RSP_ADDNIE_DATA1
10515 & WNI_CFG_PROBE_RSP_ADDNIE_DATA2 CFG Variable As We are
10516 not able Store More then 255 bytes into One Variable */
10517
10518 while ((rem_probe_resp_ie_len > 0) && (counter < 3))
10519 {
10520 if (rem_probe_resp_ie_len > MAX_CFG_STRING_LEN)
10521 {
10522 probe_rsp_ie_len[counter++] = MAX_CFG_STRING_LEN;
10523 rem_probe_resp_ie_len -= MAX_CFG_STRING_LEN;
10524 }
10525 else
10526 {
10527 probe_rsp_ie_len[counter++] = rem_probe_resp_ie_len;
10528 rem_probe_resp_ie_len = 0;
10529 }
10530 }
10531
10532 rem_probe_resp_ie_len = 0;
10533
10534 if (probe_rsp_ie_len[0] > 0)
10535 {
10536 if (ccmCfgSetStr(WLAN_HDD_GET_HAL_CTX(pAdapter),
10537 WNI_CFG_PROBE_RSP_ADDNIE_DATA1,
10538 (tANI_U8*)(genie - 2),
10539 probe_rsp_ie_len[0], NULL,
10540 eANI_BOOLEAN_FALSE)
10541 == eHAL_STATUS_FAILURE)
10542 {
10543 hddLog(LOGE,
10544 "Could not pass"
10545 "on WNI_CFG_PROBE_RSP_ADDNIE_DATA1 to CCM");
10546 }
10547 rem_probe_resp_ie_len += probe_rsp_ie_len[0];
10548 }
10549
10550 if (probe_rsp_ie_len[1] > 0)
10551 {
10552 if (ccmCfgSetStr(WLAN_HDD_GET_HAL_CTX(pAdapter),
10553 WNI_CFG_PROBE_RSP_ADDNIE_DATA2,
10554 (tANI_U8*)(genie - (2 + rem_probe_resp_ie_len)),
10555 probe_rsp_ie_len[1], NULL,
10556 eANI_BOOLEAN_FALSE)
10557 == eHAL_STATUS_FAILURE)
10558 {
10559 hddLog(LOGE,
10560 "Could not pass"
10561 "on WNI_CFG_PROBE_RSP_ADDNIE_DATA2 to CCM");
10562 }
10563 rem_probe_resp_ie_len += probe_rsp_ie_len[1];
10564 }
10565
10566 if (probe_rsp_ie_len[2] > 0)
10567 {
10568 if (ccmCfgSetStr(WLAN_HDD_GET_HAL_CTX(pAdapter),
10569 WNI_CFG_PROBE_RSP_ADDNIE_DATA3,
10570 (tANI_U8*)(genie - (2 + rem_probe_resp_ie_len)),
10571 probe_rsp_ie_len[2], NULL,
10572 eANI_BOOLEAN_FALSE)
10573 == eHAL_STATUS_FAILURE)
10574 {
10575 hddLog(LOGE,
10576 "Could not pass"
10577 "on WNI_CFG_PROBE_RSP_ADDNIE_DATA3 to CCM");
10578 }
10579 rem_probe_resp_ie_len += probe_rsp_ie_len[2];
10580 }
10581
10582 if (ccmCfgSetInt(WLAN_HDD_GET_HAL_CTX(pAdapter),
10583 WNI_CFG_PROBE_RSP_ADDNIE_FLAG, 1,NULL,
10584 eANI_BOOLEAN_FALSE) == eHAL_STATUS_FAILURE)
10585 {
10586 hddLog(LOGE,
10587 "Could not pass"
10588 "on WNI_CFG_PROBE_RSP_ADDNIE_FLAG to CCM");
10589 }
10590 }
10591 else
10592 {
10593 // Reset WNI_CFG_PROBE_RSP Flags
10594 wlan_hdd_reset_prob_rspies(pAdapter);
10595
10596 hddLog(VOS_TRACE_LEVEL_INFO,
10597 "%s: No Probe Response IE received in set beacon",
10598 __func__);
10599 }
10600 } /* end of if (WLAN_HDD_IBSS == pAdapter->device_mode) */
Jeff Johnson295189b2012-06-20 16:38:30 -070010601 break;
10602 case DOT11F_EID_RSN:
10603 hddLog (VOS_TRACE_LEVEL_INFO, "%s Set RSN IE(len %d)",__func__, eLen + 2);
10604 memset( pWextState->WPARSNIE, 0, MAX_WPA_RSN_IE_LEN );
10605 memcpy( pWextState->WPARSNIE, genie - 2, (eLen + 2)/*ie_len*/);
10606 pWextState->roamProfile.pRSNReqIE = pWextState->WPARSNIE;
10607 pWextState->roamProfile.nRSNReqIELength = eLen + 2; //ie_len;
10608 break;
Madan Mohan Koyyalamudief3b66e2012-10-11 14:29:42 -070010609 /* Appending Extended Capabilities with Interworking bit set in Assoc Req */
10610 case DOT11F_EID_EXTCAP:
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010611 {
Madan Mohan Koyyalamudief3b66e2012-10-11 14:29:42 -070010612 v_U16_t curAddIELen = pWextState->assocAddIE.length;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010613 hddLog (VOS_TRACE_LEVEL_INFO, "%s Set Extended CAPS IE(len %d)",
Madan Mohan Koyyalamudief3b66e2012-10-11 14:29:42 -070010614 __func__, eLen + 2);
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010615
Madan Mohan Koyyalamudief3b66e2012-10-11 14:29:42 -070010616 if( SIR_MAC_MAX_IE_LENGTH < (pWextState->assocAddIE.length + eLen) )
10617 {
Jeff Johnson902c9832012-12-10 14:28:09 -080010618 hddLog(VOS_TRACE_LEVEL_FATAL, "Cannot accommodate assocAddIE "
10619 "Need bigger buffer space");
Madan Mohan Koyyalamudief3b66e2012-10-11 14:29:42 -070010620 VOS_ASSERT(0);
10621 return -ENOMEM;
10622 }
10623 memcpy( pWextState->assocAddIE.addIEdata + curAddIELen, genie - 2, eLen + 2);
10624 pWextState->assocAddIE.length += eLen + 2;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010625
Madan Mohan Koyyalamudief3b66e2012-10-11 14:29:42 -070010626 pWextState->roamProfile.pAddIEAssoc = pWextState->assocAddIE.addIEdata;
10627 pWextState->roamProfile.nAddIEAssocLength = pWextState->assocAddIE.length;
10628 break;
10629 }
Jeff Johnson295189b2012-06-20 16:38:30 -070010630#ifdef FEATURE_WLAN_WAPI
10631 case WLAN_EID_WAPI:
10632 pAdapter->wapi_info.nWapiMode = 1; //Setting WAPI Mode to ON=1
Jeff Johnson0299d0a2013-10-30 12:37:43 -070010633 hddLog(VOS_TRACE_LEVEL_INFO, "WAPI MODE IS %u",
Jeff Johnson295189b2012-06-20 16:38:30 -070010634 pAdapter->wapi_info.nWapiMode);
10635 tmp = (u16 *)ie;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010636 tmp = tmp + 2; // Skip element Id and Len, Version
Jeff Johnson295189b2012-06-20 16:38:30 -070010637 akmsuiteCount = WPA_GET_LE16(tmp);
10638 tmp = tmp + 1;
10639 akmlist = (int *)(tmp);
10640 if(akmsuiteCount <= MAX_NUM_AKM_SUITES)
10641 {
10642 memcpy(akmsuite, akmlist, (4*akmsuiteCount));
10643 }
10644 else
10645 {
Arif Hussain6d2a3322013-11-17 19:50:10 -080010646 hddLog(VOS_TRACE_LEVEL_FATAL, "Invalid akmSuite count");
Jeff Johnson295189b2012-06-20 16:38:30 -070010647 VOS_ASSERT(0);
10648 return -EINVAL;
10649 }
10650
10651 if (WAPI_PSK_AKM_SUITE == akmsuite[0])
10652 {
10653 hddLog(VOS_TRACE_LEVEL_INFO, "%s: WAPI AUTH MODE SET TO PSK",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -070010654 __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -070010655 pAdapter->wapi_info.wapiAuthMode = WAPI_AUTH_MODE_PSK;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010656 }
Jeff Johnson295189b2012-06-20 16:38:30 -070010657 if (WAPI_CERT_AKM_SUITE == akmsuite[0])
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010658 {
Jeff Johnson295189b2012-06-20 16:38:30 -070010659 hddLog(VOS_TRACE_LEVEL_INFO, "%s: WAPI AUTH MODE SET TO CERTIFICATE",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -070010660 __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -070010661 pAdapter->wapi_info.wapiAuthMode = WAPI_AUTH_MODE_CERT;
10662 }
10663 break;
10664#endif
10665 default:
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010666 hddLog (VOS_TRACE_LEVEL_ERROR,
Jeff Johnson295189b2012-06-20 16:38:30 -070010667 "%s Set UNKNOWN IE %X", __func__, elementId);
Madan Mohan Koyyalamudief3b66e2012-10-11 14:29:42 -070010668 /* when Unknown IE is received we should break and continue
10669 * to the next IE in the buffer instead we were returning
10670 * so changing this to break */
10671 break;
Jeff Johnson295189b2012-06-20 16:38:30 -070010672 }
10673 genie += eLen;
10674 remLen -= eLen;
10675 }
10676 EXIT();
10677 return 0;
10678}
10679
10680/*
Gopichand Nakkala18f0c262013-05-07 23:25:08 +053010681 * FUNCTION: hdd_isWPAIEPresent
10682 * Parse the received IE to find the WPA IE
10683 *
10684 */
10685static bool hdd_isWPAIEPresent(u8 *ie, u8 ie_len)
10686{
10687 v_U8_t eLen = 0;
10688 v_U16_t remLen = ie_len;
10689 v_U8_t elementId = 0;
10690
10691 while (remLen >= 2)
10692 {
10693 elementId = *ie++;
10694 eLen = *ie++;
10695 remLen -= 2;
10696 if (eLen > remLen)
10697 {
10698 hddLog(VOS_TRACE_LEVEL_ERROR,
10699 "%s: IE length is wrong %d", __func__, eLen);
10700 return FALSE;
10701 }
10702 if ((elementId == DOT11F_EID_WPA) && (remLen > 5))
10703 {
10704 /* OUI - 0x00 0X50 0XF2
10705 WPA Information Element - 0x01
10706 WPA version - 0x01*/
10707 if (0 == memcmp(&ie[0], "\x00\x50\xf2\x01\x01", 5))
10708 return TRUE;
10709 }
10710 ie += eLen;
10711 remLen -= eLen;
10712 }
10713 return FALSE;
10714}
10715
10716/*
Jeff Johnson295189b2012-06-20 16:38:30 -070010717 * FUNCTION: wlan_hdd_cfg80211_set_privacy
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010718 * This function is used to initialize the security
Jeff Johnson295189b2012-06-20 16:38:30 -070010719 * parameters during connect operation.
10720 */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010721int wlan_hdd_cfg80211_set_privacy( hdd_adapter_t *pAdapter,
Jeff Johnson295189b2012-06-20 16:38:30 -070010722 struct cfg80211_connect_params *req
10723 )
10724{
10725 int status = 0;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010726 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
Jeff Johnson295189b2012-06-20 16:38:30 -070010727 ENTER();
10728
10729 /*set wpa version*/
10730 pWextState->wpaVersion = IW_AUTH_WPA_VERSION_DISABLED;
10731
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010732 if (req->crypto.wpa_versions)
Jeff Johnson295189b2012-06-20 16:38:30 -070010733 {
Gopichand Nakkala781ded42013-06-28 12:10:45 +053010734 if (NL80211_WPA_VERSION_1 == req->crypto.wpa_versions)
Jeff Johnson295189b2012-06-20 16:38:30 -070010735 {
10736 pWextState->wpaVersion = IW_AUTH_WPA_VERSION_WPA;
10737 }
10738 else if (NL80211_WPA_VERSION_2 == req->crypto.wpa_versions)
10739 {
10740 pWextState->wpaVersion = IW_AUTH_WPA_VERSION_WPA2;
10741 }
10742 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010743
10744 hddLog(VOS_TRACE_LEVEL_INFO, "%s: set wpa version to %d", __func__,
Jeff Johnson295189b2012-06-20 16:38:30 -070010745 pWextState->wpaVersion);
10746
10747 /*set authentication type*/
10748 status = wlan_hdd_cfg80211_set_auth_type(pAdapter, req->auth_type);
10749
10750 if (0 > status)
10751 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010752 hddLog(VOS_TRACE_LEVEL_ERROR,
Jeff Johnson295189b2012-06-20 16:38:30 -070010753 "%s: failed to set authentication type ", __func__);
10754 return status;
10755 }
10756
10757 /*set key mgmt type*/
10758 if (req->crypto.n_akm_suites)
10759 {
10760 status = wlan_hdd_set_akm_suite(pAdapter, req->crypto.akm_suites[0]);
10761 if (0 > status)
10762 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010763 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: failed to set akm suite",
Jeff Johnson295189b2012-06-20 16:38:30 -070010764 __func__);
10765 return status;
10766 }
10767 }
10768
10769 /*set pairwise cipher type*/
10770 if (req->crypto.n_ciphers_pairwise)
10771 {
10772 status = wlan_hdd_cfg80211_set_cipher(pAdapter,
10773 req->crypto.ciphers_pairwise[0], true);
10774 if (0 > status)
10775 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010776 hddLog(VOS_TRACE_LEVEL_ERROR,
Jeff Johnson295189b2012-06-20 16:38:30 -070010777 "%s: failed to set unicast cipher type", __func__);
10778 return status;
10779 }
10780 }
10781 else
10782 {
10783 /*Reset previous cipher suite to none*/
10784 status = wlan_hdd_cfg80211_set_cipher(pAdapter, 0, true);
10785 if (0 > status)
10786 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010787 hddLog(VOS_TRACE_LEVEL_ERROR,
Jeff Johnson295189b2012-06-20 16:38:30 -070010788 "%s: failed to set unicast cipher type", __func__);
10789 return status;
10790 }
10791 }
10792
10793 /*set group cipher type*/
10794 status = wlan_hdd_cfg80211_set_cipher(pAdapter, req->crypto.cipher_group,
10795 false);
10796
10797 if (0 > status)
10798 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010799 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: failed to set mcast cipher type",
Jeff Johnson295189b2012-06-20 16:38:30 -070010800 __func__);
10801 return status;
10802 }
10803
Chet Lanctot186b5732013-03-18 10:26:30 -070010804#ifdef WLAN_FEATURE_11W
10805 pWextState->roamProfile.MFPEnabled = (req->mfp == NL80211_MFP_REQUIRED);
10806#endif
10807
Jeff Johnson295189b2012-06-20 16:38:30 -070010808 /*parse WPA/RSN IE, and set the correspoing fileds in Roam profile*/
10809 if (req->ie_len)
10810 {
10811 status = wlan_hdd_cfg80211_set_ie(pAdapter, req->ie, req->ie_len);
10812 if ( 0 > status)
10813 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010814 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: failed to parse the WPA/RSN IE",
Jeff Johnson295189b2012-06-20 16:38:30 -070010815 __func__);
10816 return status;
10817 }
10818 }
10819
10820 /*incase of WEP set default key information*/
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010821 if (req->key && req->key_len)
Jeff Johnson295189b2012-06-20 16:38:30 -070010822 {
10823 if ( (WLAN_CIPHER_SUITE_WEP40 == req->crypto.ciphers_pairwise[0])
10824 || (WLAN_CIPHER_SUITE_WEP104 == req->crypto.ciphers_pairwise[0])
10825 )
10826 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010827 if ( IW_AUTH_KEY_MGMT_802_1X
Jeff Johnson295189b2012-06-20 16:38:30 -070010828 == (pWextState->authKeyMgmt & IW_AUTH_KEY_MGMT_802_1X ))
10829 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010830 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Dynamic WEP not supported",
Jeff Johnson295189b2012-06-20 16:38:30 -070010831 __func__);
10832 return -EOPNOTSUPP;
10833 }
10834 else
10835 {
10836 u8 key_len = req->key_len;
10837 u8 key_idx = req->key_idx;
10838
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010839 if ((eCSR_SECURITY_WEP_KEYSIZE_MAX_BYTES >= key_len)
Jeff Johnson295189b2012-06-20 16:38:30 -070010840 && (CSR_MAX_NUM_KEY > key_idx)
10841 )
10842 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010843 hddLog(VOS_TRACE_LEVEL_INFO,
10844 "%s: setting default wep key, key_idx = %hu key_len %hu",
Jeff Johnson295189b2012-06-20 16:38:30 -070010845 __func__, key_idx, key_len);
10846 vos_mem_copy(
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010847 &pWextState->roamProfile.Keys.KeyMaterial[key_idx][0],
Jeff Johnson295189b2012-06-20 16:38:30 -070010848 req->key, key_len);
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010849 pWextState->roamProfile.Keys.KeyLength[key_idx] =
Jeff Johnson295189b2012-06-20 16:38:30 -070010850 (u8)key_len;
10851 pWextState->roamProfile.Keys.defaultIndex = (u8)key_idx;
10852 }
10853 }
10854 }
10855 }
10856
10857 return status;
10858}
10859
10860/*
Vinay Krishna Eranna21042322014-01-08 19:21:39 +053010861 * FUNCTION: wlan_hdd_try_disconnect
10862 * This function is used to disconnect from previous
10863 * connection
10864 */
10865static int wlan_hdd_try_disconnect( hdd_adapter_t *pAdapter )
10866{
10867 long ret = 0;
10868 hdd_station_ctx_t *pHddStaCtx;
10869 eMib_dot11DesiredBssType connectedBssType;
10870
10871 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
10872
10873 hdd_connGetConnectedBssType(pHddStaCtx,&connectedBssType );
10874
10875 if((eMib_dot11DesiredBssType_independent == connectedBssType) ||
10876 (eConnectionState_Associated == pHddStaCtx->conn_info.connState) ||
10877 (eConnectionState_IbssConnected == pHddStaCtx->conn_info.connState))
10878 {
10879 /* Issue disconnect to CSR */
10880 INIT_COMPLETION(pAdapter->disconnect_comp_var);
10881 if( eHAL_STATUS_SUCCESS ==
10882 sme_RoamDisconnect( WLAN_HDD_GET_HAL_CTX(pAdapter),
10883 pAdapter->sessionId,
10884 eCSR_DISCONNECT_REASON_UNSPECIFIED ) )
10885 {
10886 ret = wait_for_completion_interruptible_timeout(
10887 &pAdapter->disconnect_comp_var,
10888 msecs_to_jiffies(WLAN_WAIT_TIME_DISCONNECT));
10889 if (0 >= ret)
10890 {
10891 hddLog(LOGE, FL("Failed to receive disconnect event"));
10892 return -EALREADY;
10893 }
10894 }
10895 }
10896 else if(eConnectionState_Disconnecting == pHddStaCtx->conn_info.connState)
10897 {
10898 ret = wait_for_completion_interruptible_timeout(
10899 &pAdapter->disconnect_comp_var,
10900 msecs_to_jiffies(WLAN_WAIT_TIME_DISCONNECT));
10901 if (0 >= ret)
10902 {
10903 hddLog(LOGE, FL("Failed to receive disconnect event"));
10904 return -EALREADY;
10905 }
10906 }
10907
10908 return 0;
10909}
10910
10911/*
Agarwal Ashish51325b52014-06-16 16:50:49 +053010912 * FUNCTION: __wlan_hdd_cfg80211_connect
10913 * This function is used to start the association process
Jeff Johnson295189b2012-06-20 16:38:30 -070010914 */
Mahesh A Saptasagarfafb7fe2014-05-16 13:19:37 +053010915static int __wlan_hdd_cfg80211_connect( struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -070010916 struct net_device *ndev,
10917 struct cfg80211_connect_params *req
10918 )
10919{
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053010920 int status;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010921 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( ndev );
Jeff Johnson295189b2012-06-20 16:38:30 -070010922 VOS_STATUS exitbmpsStatus = VOS_STATUS_E_INVAL;
Sushant Kaushikba6764e2014-06-30 19:52:09 +053010923 hdd_context_t *pHddCtx = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -070010924
10925 ENTER();
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053010926
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053010927 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
10928 TRACE_CODE_HDD_CFG80211_CONNECT,
10929 pAdapter->sessionId, pAdapter->device_mode));
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010930 hddLog(VOS_TRACE_LEVEL_INFO,
Sushant Kaushik8bc7df22014-04-09 17:55:29 +053010931 "%s: device_mode = %s (%d)", __func__,
10932 hdd_device_modetoString(pAdapter->device_mode),
10933 pAdapter->device_mode);
Jeff Johnson295189b2012-06-20 16:38:30 -070010934
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053010935 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Rajesh Chauhana0516c62014-01-30 16:11:18 -080010936 if (!pHddCtx)
10937 {
10938 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
10939 "%s: HDD context is null", __func__);
Agarwal Ashish51325b52014-06-16 16:50:49 +053010940 return -EINVAL;
Rajesh Chauhana0516c62014-01-30 16:11:18 -080010941 }
10942
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053010943 status = wlan_hdd_validate_context(pHddCtx);
10944
10945 if (0 != status)
Jeff Johnson295189b2012-06-20 16:38:30 -070010946 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053010947 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
10948 "%s: HDD context is not valid", __func__);
10949 return status;
Jeff Johnson295189b2012-06-20 16:38:30 -070010950 }
10951
Agarwal Ashish51325b52014-06-16 16:50:49 +053010952 if (vos_max_concurrent_connections_reached()) {
10953 hddLog(VOS_TRACE_LEVEL_INFO, FL("Reached max concurrent connections"));
10954 return -ECONNREFUSED;
10955 }
10956
Jeff Johnson295189b2012-06-20 16:38:30 -070010957#ifdef WLAN_BTAMP_FEATURE
10958 //Infra connect not supported when AMP traffic is on.
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010959 if( VOS_TRUE == WLANBAP_AmpSessionOn() )
Jeff Johnson295189b2012-06-20 16:38:30 -070010960 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010961 hddLog(VOS_TRACE_LEVEL_ERROR,
Jeff Johnson295189b2012-06-20 16:38:30 -070010962 "%s: No connection when AMP is on", __func__);
Madan Mohan Koyyalamudicae253a2012-11-06 19:10:35 -080010963 return -ECONNREFUSED;
Jeff Johnson295189b2012-06-20 16:38:30 -070010964 }
10965#endif
Vinay Krishna Eranna21042322014-01-08 19:21:39 +053010966
10967 //If Device Mode is Station Concurrent Sessions Exit BMps
10968 //P2P Mode will be taken care in Open/close adapter
10969 if((WLAN_HDD_INFRA_STATION == pAdapter->device_mode) &&
Agarwal Ashish51325b52014-06-16 16:50:49 +053010970 (vos_concurrent_open_sessions_running())) {
10971 exitbmpsStatus = hdd_disable_bmps_imps(pHddCtx,
10972 WLAN_HDD_INFRA_STATION);
Vinay Krishna Eranna21042322014-01-08 19:21:39 +053010973 }
10974
10975 /*Try disconnecting if already in connected state*/
10976 status = wlan_hdd_try_disconnect(pAdapter);
10977 if ( 0 > status)
10978 {
10979 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Failed to disconnect the existing"
10980 " connection"));
10981 return -EALREADY;
10982 }
10983
Jeff Johnson295189b2012-06-20 16:38:30 -070010984 /*initialise security parameters*/
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010985 status = wlan_hdd_cfg80211_set_privacy(pAdapter, req);
Jeff Johnson295189b2012-06-20 16:38:30 -070010986
10987 if ( 0 > status)
10988 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010989 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: failed to set security params",
Jeff Johnson295189b2012-06-20 16:38:30 -070010990 __func__);
10991 return status;
10992 }
Mohit Khanna765234a2012-09-11 15:08:35 -070010993 if ( req->channel )
10994 {
10995 status = wlan_hdd_cfg80211_connect_start(pAdapter, req->ssid,
10996 req->ssid_len, req->bssid,
10997 req->channel->hw_value);
10998 }
10999 else
11000 {
11001 status = wlan_hdd_cfg80211_connect_start(pAdapter, req->ssid,
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053011002 req->ssid_len, req->bssid, 0);
Mohit Khanna765234a2012-09-11 15:08:35 -070011003 }
Jeff Johnson295189b2012-06-20 16:38:30 -070011004
11005 if (0 > status)
11006 {
11007 //ReEnable BMPS if disabled
11008 if((VOS_STATUS_SUCCESS == exitbmpsStatus) &&
11009 (NULL != pHddCtx))
11010 {
Gopichand Nakkalaa2fe5b02013-06-06 16:32:28 +053011011 if (pHddCtx->hdd_wlan_suspended)
11012 {
11013 hdd_set_pwrparams(pHddCtx);
11014 }
Jeff Johnson295189b2012-06-20 16:38:30 -070011015 //ReEnable Bmps and Imps back
11016 hdd_enable_bmps_imps(pHddCtx);
11017 }
Agarwal Ashish51325b52014-06-16 16:50:49 +053011018 hddLog(VOS_TRACE_LEVEL_ERROR, FL("connect failed"));
Jeff Johnson295189b2012-06-20 16:38:30 -070011019 return status;
11020 }
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053011021 pHddCtx->isAmpAllowed = VOS_FALSE;
Jeff Johnson295189b2012-06-20 16:38:30 -070011022 EXIT();
11023 return status;
11024}
11025
Mahesh A Saptasagarfafb7fe2014-05-16 13:19:37 +053011026static int wlan_hdd_cfg80211_connect( struct wiphy *wiphy,
11027 struct net_device *ndev,
11028 struct cfg80211_connect_params *req)
11029{
11030 int ret;
11031 vos_ssr_protect(__func__);
11032 ret = __wlan_hdd_cfg80211_connect(wiphy, ndev, req);
11033 vos_ssr_unprotect(__func__);
11034
11035 return ret;
11036}
Jeff Johnson295189b2012-06-20 16:38:30 -070011037
11038/*
Gopichand Nakkala78a6c812013-05-13 16:39:49 +053011039 * FUNCTION: wlan_hdd_disconnect
11040 * This function is used to issue a disconnect request to SME
11041 */
11042int wlan_hdd_disconnect( hdd_adapter_t *pAdapter, u16 reason )
11043{
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053011044 int status;
Gopichand Nakkala78a6c812013-05-13 16:39:49 +053011045 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053011046 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Abhishek Singhdc2bfd42014-06-19 17:59:05 +053011047 long ret;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053011048
11049 status = wlan_hdd_validate_context(pHddCtx);
11050
11051 if (0 != status)
11052 {
11053 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
11054 "%s: HDD context is not valid", __func__);
11055 return status;
11056 }
11057
11058 pHddCtx->isAmpAllowed = VOS_TRUE;
Agarwal Ashishc65b5ca2014-07-28 21:02:57 +053011059
Agarwal Ashish47d18112014-08-04 19:55:07 +053011060 /* Need to apply spin lock before decreasing active sessions
11061 * as there can be chance for double decrement if context switch
11062 * Calls hdd_DisConnectHandler.
11063 */
11064
11065 spin_lock_bh(&pAdapter->lock_for_active_session);
Agarwal Ashishc65b5ca2014-07-28 21:02:57 +053011066 if (eConnectionState_Associated == pHddStaCtx->conn_info.connState)
11067 {
Agarwal Ashishc65b5ca2014-07-28 21:02:57 +053011068 wlan_hdd_decr_active_session(pHddCtx, pAdapter->device_mode);
11069 }
Agarwal Ashish47d18112014-08-04 19:55:07 +053011070 hdd_connSetConnectionState( pHddStaCtx, eConnectionState_Disconnecting );
11071 spin_unlock_bh(&pAdapter->lock_for_active_session);
Agarwal Ashishc65b5ca2014-07-28 21:02:57 +053011072
Abhishek Singhf4669da2014-05-26 15:07:49 +053011073 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Agarwal Ashish47d18112014-08-04 19:55:07 +053011074 FL( "Set HDD connState to eConnectionState_Disconnecting" ));
11075
Gopichand Nakkala78a6c812013-05-13 16:39:49 +053011076 INIT_COMPLETION(pAdapter->disconnect_comp_var);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053011077
Mihir Shete182a0b22014-08-18 16:08:48 +053011078 /*
11079 * stop tx queues before deleting STA/BSS context from the firmware.
11080 * tx has to be disabled because the firmware can get busy dropping
11081 * the tx frames after BSS/STA has been deleted and will not send
11082 * back a response resulting in WDI timeout
11083 */
11084 netif_tx_disable(pAdapter->dev);
11085 netif_carrier_off(pAdapter->dev);
Arun Kumar Khandavalli94a2bb02013-12-28 19:17:25 +053011086
Mihir Shete182a0b22014-08-18 16:08:48 +053011087 /*issue disconnect*/
Gopichand Nakkala78a6c812013-05-13 16:39:49 +053011088 status = sme_RoamDisconnect( WLAN_HDD_GET_HAL_CTX(pAdapter),
11089 pAdapter->sessionId, reason);
Abhishek Singhdc2bfd42014-06-19 17:59:05 +053011090 if(eHAL_STATUS_CMD_NOT_QUEUED == status)
11091 {
11092 hddLog(VOS_TRACE_LEVEL_INFO,
11093 FL("status = %d, already disconnected"),
11094 (int)status );
Gopichand Nakkala78a6c812013-05-13 16:39:49 +053011095
Abhishek Singhdc2bfd42014-06-19 17:59:05 +053011096 }
11097 else if ( 0 != status )
Gopichand Nakkala78a6c812013-05-13 16:39:49 +053011098 {
11099 hddLog(VOS_TRACE_LEVEL_ERROR,
Arif Hussain6d2a3322013-11-17 19:50:10 -080011100 "%s csrRoamDisconnect failure, returned %d",
Gopichand Nakkala78a6c812013-05-13 16:39:49 +053011101 __func__, (int)status );
11102 return -EINVAL;
11103 }
Abhishek Singhdc2bfd42014-06-19 17:59:05 +053011104 ret = wait_for_completion_interruptible_timeout(
Gopichand Nakkala78a6c812013-05-13 16:39:49 +053011105 &pAdapter->disconnect_comp_var,
11106 msecs_to_jiffies(WLAN_WAIT_TIME_DISCONNECT));
Abhishek Singhdc2bfd42014-06-19 17:59:05 +053011107 if (!ret && ( eHAL_STATUS_CMD_NOT_QUEUED != status ))
c_hpothu6ff1c3c2013-10-01 19:01:57 +053011108 {
11109 hddLog(VOS_TRACE_LEVEL_ERROR,
Mahesh A Saptasagar05a357e2014-02-26 16:28:06 +053011110 "%s: Failed to disconnect, timed out", __func__);
11111 return -ETIMEDOUT;
11112 }
Abhishek Singhdc2bfd42014-06-19 17:59:05 +053011113 else if (ret == -ERESTARTSYS)
Mahesh A Saptasagar05a357e2014-02-26 16:28:06 +053011114 {
11115 hddLog(VOS_TRACE_LEVEL_ERROR,
11116 "%s: Failed to disconnect, wait interrupted", __func__);
Abhishek Singhdc2bfd42014-06-19 17:59:05 +053011117 return ret;
c_hpothu6ff1c3c2013-10-01 19:01:57 +053011118 }
Abhishek Singhdc2bfd42014-06-19 17:59:05 +053011119 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
11120 FL("Set HDD connState to eConnectionState_NotConnected"));
11121 pHddStaCtx->conn_info.connState = eConnectionState_NotConnected;
11122
Mahesh A Saptasagar05a357e2014-02-26 16:28:06 +053011123 return 0;
Gopichand Nakkala78a6c812013-05-13 16:39:49 +053011124}
11125
11126
11127/*
Mahesh A Saptasagarfafb7fe2014-05-16 13:19:37 +053011128 * FUNCTION: __wlan_hdd_cfg80211_disconnect
Jeff Johnson295189b2012-06-20 16:38:30 -070011129 * This function is used to issue a disconnect request to SME
11130 */
Mahesh A Saptasagarfafb7fe2014-05-16 13:19:37 +053011131static int __wlan_hdd_cfg80211_disconnect( struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -070011132 struct net_device *dev,
11133 u16 reason
11134 )
11135{
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011136 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( dev );
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053011137 tCsrRoamProfile *pRoamProfile =
11138 &(WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter))->roamProfile;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053011139 int status;
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053011140 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
11141 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Gopichand Nakkalaaa353782013-05-17 20:36:22 +053011142#ifdef FEATURE_WLAN_TDLS
Gopichand Nakkala2a0a1572013-02-10 21:39:16 -080011143 tANI_U8 staIdx;
11144#endif
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011145
Jeff Johnson295189b2012-06-20 16:38:30 -070011146 ENTER();
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053011147
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053011148 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
11149 TRACE_CODE_HDD_CFG80211_DISCONNECT,
11150 pAdapter->sessionId, reason));
Sushant Kaushik8bc7df22014-04-09 17:55:29 +053011151 hddLog(VOS_TRACE_LEVEL_INFO, "%s: device_mode = %s(%d)",
11152 __func__, hdd_device_modetoString(pAdapter->device_mode),
11153 pAdapter->device_mode);
Jeff Johnson295189b2012-06-20 16:38:30 -070011154
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011155 hddLog(VOS_TRACE_LEVEL_INFO, "%s: Disconnect called with reason code %d",
11156 __func__, reason);
Jeff Johnson295189b2012-06-20 16:38:30 -070011157
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053011158 status = wlan_hdd_validate_context(pHddCtx);
11159
11160 if (0 != status)
Jeff Johnson295189b2012-06-20 16:38:30 -070011161 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053011162 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
11163 "%s: HDD context is not valid", __func__);
11164 return status;
Jeff Johnson295189b2012-06-20 16:38:30 -070011165 }
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053011166
Jeff Johnson295189b2012-06-20 16:38:30 -070011167 if (NULL != pRoamProfile)
11168 {
11169 /*issue disconnect request to SME, if station is in connected state*/
Mahesh A Saptasagar280fd5a2013-12-05 15:38:31 +053011170 if ((pHddStaCtx->conn_info.connState == eConnectionState_Associated) ||
11171 (pHddStaCtx->conn_info.connState == eConnectionState_Connecting))
Jeff Johnson295189b2012-06-20 16:38:30 -070011172 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011173 eCsrRoamDisconnectReason reasonCode =
Jeff Johnson295189b2012-06-20 16:38:30 -070011174 eCSR_DISCONNECT_REASON_UNSPECIFIED;
Gopichand Nakkalaaa353782013-05-17 20:36:22 +053011175 hdd_scaninfo_t *pScanInfo;
Jeff Johnson295189b2012-06-20 16:38:30 -070011176 switch(reason)
11177 {
11178 case WLAN_REASON_MIC_FAILURE:
11179 reasonCode = eCSR_DISCONNECT_REASON_MIC_ERROR;
11180 break;
11181
11182 case WLAN_REASON_DISASSOC_DUE_TO_INACTIVITY:
11183 case WLAN_REASON_DISASSOC_AP_BUSY:
11184 case WLAN_REASON_CLASS3_FRAME_FROM_NONASSOC_STA:
11185 reasonCode = eCSR_DISCONNECT_REASON_DISASSOC;
11186 break;
11187
11188 case WLAN_REASON_PREV_AUTH_NOT_VALID:
11189 case WLAN_REASON_CLASS2_FRAME_FROM_NONAUTH_STA:
Abhishek Singhc3269a52014-05-21 17:22:24 +053011190 case WLAN_REASON_DEAUTH_LEAVING:
Jeff Johnson295189b2012-06-20 16:38:30 -070011191 reasonCode = eCSR_DISCONNECT_REASON_DEAUTH;
11192 break;
11193
Jeff Johnson295189b2012-06-20 16:38:30 -070011194 default:
11195 reasonCode = eCSR_DISCONNECT_REASON_UNSPECIFIED;
11196 break;
11197 }
Gopichand Nakkalaaa353782013-05-17 20:36:22 +053011198 pScanInfo = &pHddCtx->scan_info;
11199 if (pScanInfo->mScanPending)
11200 {
Srinivas, Dasari138af4f2014-02-07 11:13:45 +053011201 hddLog(VOS_TRACE_LEVEL_INFO, "Disconnect is in progress, "
Gopichand Nakkalaaa353782013-05-17 20:36:22 +053011202 "Aborting Scan");
Kaushik, Sushant4975a572014-10-21 16:07:48 +053011203 hdd_abort_mac_scan(pHddCtx, pScanInfo->sessionId,
Srinivas, Dasari138af4f2014-02-07 11:13:45 +053011204 eCSR_SCAN_ABORT_DEFAULT);
Gopichand Nakkalaaa353782013-05-17 20:36:22 +053011205 }
Jeff Johnson295189b2012-06-20 16:38:30 -070011206
Gopichand Nakkala2a0a1572013-02-10 21:39:16 -080011207#ifdef FEATURE_WLAN_TDLS
11208 /* First clean up the tdls peers if any */
Gopichand Nakkala4327a152013-03-04 23:22:42 -080011209 for (staIdx = 0 ; staIdx < HDD_MAX_NUM_TDLS_STA; staIdx++)
Gopichand Nakkala2a0a1572013-02-10 21:39:16 -080011210 {
Gopichand Nakkala4327a152013-03-04 23:22:42 -080011211 if ((pHddCtx->tdlsConnInfo[staIdx].sessionId == pAdapter->sessionId) &&
11212 (pHddCtx->tdlsConnInfo[staIdx].staId))
Gopichand Nakkala2a0a1572013-02-10 21:39:16 -080011213 {
Hoonki Lee11f7dda2013-02-14 16:55:44 -080011214 uint8 *mac;
Gopichand Nakkala4327a152013-03-04 23:22:42 -080011215 mac = pHddCtx->tdlsConnInfo[staIdx].peerMac.bytes;
Hoonki Lee11f7dda2013-02-14 16:55:44 -080011216 VOS_TRACE(VOS_MODULE_ID_HDD, TDLS_LOG_LEVEL,
Gopichand Nakkalac87400e2013-03-13 18:51:00 -070011217 "%s: call sme_DeleteTdlsPeerSta staId %d sessionId %d " MAC_ADDRESS_STR,
Gopichand Nakkala4327a152013-03-04 23:22:42 -080011218 __func__, pHddCtx->tdlsConnInfo[staIdx].staId, pAdapter->sessionId,
Gopichand Nakkalac87400e2013-03-13 18:51:00 -070011219 MAC_ADDR_ARRAY(mac));
Gopichand Nakkala2a0a1572013-02-10 21:39:16 -080011220 sme_DeleteTdlsPeerSta(WLAN_HDD_GET_HAL_CTX(pAdapter),
Gopichand Nakkala4327a152013-03-04 23:22:42 -080011221 pAdapter->sessionId,
11222 mac);
Gopichand Nakkala2a0a1572013-02-10 21:39:16 -080011223 }
11224 }
11225#endif
Arun Kumar Khandavalli94a2bb02013-12-28 19:17:25 +053011226 hddLog(LOG1, FL("Disconnecting with reasoncode:%u"), reasonCode);
Gopichand Nakkala78a6c812013-05-13 16:39:49 +053011227 status = wlan_hdd_disconnect(pAdapter, reasonCode);
11228 if ( 0 != status )
Jeff Johnson295189b2012-06-20 16:38:30 -070011229 {
11230 hddLog(VOS_TRACE_LEVEL_ERROR,
Arif Hussain6d2a3322013-11-17 19:50:10 -080011231 "%s wlan_hdd_disconnect failure, returned %d",
Jeff Johnson295189b2012-06-20 16:38:30 -070011232 __func__, (int)status );
11233 return -EINVAL;
11234 }
Jeff Johnson295189b2012-06-20 16:38:30 -070011235 }
Mahesh A Saptasagar280fd5a2013-12-05 15:38:31 +053011236 else
11237 {
11238 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: unexpected cfg disconnect API"
11239 "called while in %d state", __func__,
11240 pHddStaCtx->conn_info.connState);
11241 }
Jeff Johnson295189b2012-06-20 16:38:30 -070011242 }
11243 else
11244 {
11245 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: No valid roam profile", __func__);
11246 }
11247
11248 return status;
11249}
11250
Mahesh A Saptasagarfafb7fe2014-05-16 13:19:37 +053011251static int wlan_hdd_cfg80211_disconnect( struct wiphy *wiphy,
11252 struct net_device *dev,
11253 u16 reason
11254 )
11255{
11256 int ret;
11257 vos_ssr_protect(__func__);
11258 ret = __wlan_hdd_cfg80211_disconnect(wiphy, dev, reason);
11259 vos_ssr_unprotect(__func__);
11260
11261 return ret;
11262}
Gopichand Nakkala78a6c812013-05-13 16:39:49 +053011263
Jeff Johnson295189b2012-06-20 16:38:30 -070011264/*
11265 * FUNCTION: wlan_hdd_cfg80211_set_privacy_ibss
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011266 * This function is used to initialize the security
Jeff Johnson295189b2012-06-20 16:38:30 -070011267 * settings in IBSS mode.
11268 */
11269static int wlan_hdd_cfg80211_set_privacy_ibss(
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011270 hdd_adapter_t *pAdapter,
Jeff Johnson295189b2012-06-20 16:38:30 -070011271 struct cfg80211_ibss_params *params
11272 )
11273{
11274 int status = 0;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011275 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
Jeff Johnson295189b2012-06-20 16:38:30 -070011276 eCsrEncryptionType encryptionType = eCSR_ENCRYPT_TYPE_NONE;
11277 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011278
Jeff Johnson295189b2012-06-20 16:38:30 -070011279 ENTER();
11280
11281 pWextState->wpaVersion = IW_AUTH_WPA_VERSION_DISABLED;
Ravi Joshib58ca0d2013-10-29 09:50:23 -070011282 vos_mem_zero(&pHddStaCtx->ibss_enc_key, sizeof(tCsrRoamSetKey));
Jeff Johnson295189b2012-06-20 16:38:30 -070011283
11284 if (params->ie_len && ( NULL != params->ie) )
11285 {
Shailender Karmuchi67edd312013-06-18 16:30:48 -070011286 if (wlan_hdd_cfg80211_get_ie_ptr (params->ie,
11287 params->ie_len, WLAN_EID_RSN ))
Jeff Johnson295189b2012-06-20 16:38:30 -070011288 {
11289 pWextState->wpaVersion = IW_AUTH_WPA_VERSION_WPA2;
11290 encryptionType = eCSR_ENCRYPT_TYPE_AES;
11291 }
Shailender Karmuchi67edd312013-06-18 16:30:48 -070011292 else if ( hdd_isWPAIEPresent (params->ie, params->ie_len ))
Jeff Johnson295189b2012-06-20 16:38:30 -070011293 {
Shailender Karmuchi642e9812013-05-30 14:34:49 -070011294 tDot11fIEWPA dot11WPAIE;
11295 tHalHandle halHandle = WLAN_HDD_GET_HAL_CTX(pAdapter);
Shailender Karmuchi67edd312013-06-18 16:30:48 -070011296 u8 *ie;
Shailender Karmuchi642e9812013-05-30 14:34:49 -070011297
Wilson Yang00256342013-10-10 23:13:38 -070011298 memset(&dot11WPAIE, 0, sizeof(dot11WPAIE));
Shailender Karmuchi67edd312013-06-18 16:30:48 -070011299 ie = wlan_hdd_cfg80211_get_ie_ptr (params->ie,
11300 params->ie_len, DOT11F_EID_WPA);
11301 if ( NULL != ie )
11302 {
11303 pWextState->wpaVersion = IW_AUTH_WPA_VERSION_WPA;
11304 // Unpack the WPA IE
11305 //Skip past the EID byte and length byte - and four byte WiFi OUI
11306 dot11fUnpackIeWPA((tpAniSirGlobal) halHandle,
11307 &ie[2+4],
11308 ie[1] - 4,
11309 &dot11WPAIE);
11310 /*Extract the multicast cipher, the encType for unicast
11311 cipher for wpa-none is none*/
11312 encryptionType =
11313 hdd_TranslateWPAToCsrEncryptionType(dot11WPAIE.multicast_cipher);
11314 }
Jeff Johnson295189b2012-06-20 16:38:30 -070011315 }
Shailender Karmuchi67edd312013-06-18 16:30:48 -070011316
Jeff Johnson295189b2012-06-20 16:38:30 -070011317 status = wlan_hdd_cfg80211_set_ie(pAdapter, params->ie, params->ie_len);
11318
11319 if (0 > status)
11320 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011321 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: failed to parse WPA/RSN IE",
Jeff Johnson295189b2012-06-20 16:38:30 -070011322 __func__);
11323 return status;
11324 }
11325 }
11326
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011327 pWextState->roamProfile.AuthType.authType[0] =
11328 pHddStaCtx->conn_info.authType =
Jeff Johnson295189b2012-06-20 16:38:30 -070011329 eCSR_AUTH_TYPE_OPEN_SYSTEM;
11330
11331 if (params->privacy)
11332 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011333 /* Security enabled IBSS, At this time there is no information available
11334 * about the security paramters, so initialise the encryption type to
Jeff Johnson295189b2012-06-20 16:38:30 -070011335 * eCSR_ENCRYPT_TYPE_WEP40_STATICKEY.
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011336 * The correct security parameters will be updated later in
Jeff Johnson295189b2012-06-20 16:38:30 -070011337 * wlan_hdd_cfg80211_add_key */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011338 /* Hal expects encryption type to be set inorder
Jeff Johnson295189b2012-06-20 16:38:30 -070011339 *enable privacy bit in beacons */
11340
11341 encryptionType = eCSR_ENCRYPT_TYPE_WEP40_STATICKEY;
11342 }
Shailender Karmuchi642e9812013-05-30 14:34:49 -070011343 VOS_TRACE (VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO_HIGH,
11344 "encryptionType=%d", encryptionType);
Jeff Johnson295189b2012-06-20 16:38:30 -070011345 pHddStaCtx->conn_info.ucEncryptionType = encryptionType;
11346 pWextState->roamProfile.EncryptionType.numEntries = 1;
11347 pWextState->roamProfile.EncryptionType.encryptionType[0] = encryptionType;
Jeff Johnson295189b2012-06-20 16:38:30 -070011348 return status;
11349}
11350
11351/*
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053011352 * FUNCTION: __wlan_hdd_cfg80211_join_ibss
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011353 * This function is used to create/join an IBSS
Jeff Johnson295189b2012-06-20 16:38:30 -070011354 */
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053011355static int __wlan_hdd_cfg80211_join_ibss( struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -070011356 struct net_device *dev,
11357 struct cfg80211_ibss_params *params
11358 )
11359{
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011360 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( dev );
Jeff Johnson295189b2012-06-20 16:38:30 -070011361 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
11362 tCsrRoamProfile *pRoamProfile;
11363 int status;
krunal sonie9002db2013-11-25 14:24:17 -080011364 bool alloc_bssid = VOS_FALSE;
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053011365 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
11366 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Jeff Johnson295189b2012-06-20 16:38:30 -070011367
11368 ENTER();
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053011369
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053011370 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
11371 TRACE_CODE_HDD_CFG80211_JOIN_IBSS,
11372 pAdapter->sessionId, pAdapter->device_mode));
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011373 hddLog(VOS_TRACE_LEVEL_INFO,
Sushant Kaushik8bc7df22014-04-09 17:55:29 +053011374 "%s: device_mode = %s (%d)", __func__,
11375 hdd_device_modetoString(pAdapter->device_mode),
11376 pAdapter->device_mode);
Jeff Johnson295189b2012-06-20 16:38:30 -070011377
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053011378 status = wlan_hdd_validate_context(pHddCtx);
11379
11380 if (0 != status)
Jeff Johnson295189b2012-06-20 16:38:30 -070011381 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053011382 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
11383 "%s: HDD context is not valid", __func__);
11384 return status;
Jeff Johnson295189b2012-06-20 16:38:30 -070011385 }
11386
11387 if (NULL == pWextState)
11388 {
Arif Hussain6d2a3322013-11-17 19:50:10 -080011389 hddLog (VOS_TRACE_LEVEL_ERROR, "%s ERROR: Data Storage Corruption",
Jeff Johnson295189b2012-06-20 16:38:30 -070011390 __func__);
11391 return -EIO;
11392 }
11393
Agarwal Ashish51325b52014-06-16 16:50:49 +053011394 if (vos_max_concurrent_connections_reached()) {
11395 hddLog(VOS_TRACE_LEVEL_INFO, FL("Reached max concurrent connections"));
11396 return -ECONNREFUSED;
11397 }
11398
Vinay Krishna Eranna21042322014-01-08 19:21:39 +053011399 /*Try disconnecting if already in connected state*/
11400 status = wlan_hdd_try_disconnect(pAdapter);
11401 if ( 0 > status)
11402 {
11403 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Failed to disconnect the existing"
11404 " IBSS connection"));
11405 return -EALREADY;
11406 }
11407
Jeff Johnson295189b2012-06-20 16:38:30 -070011408 pRoamProfile = &pWextState->roamProfile;
11409
11410 if ( eCSR_BSS_TYPE_START_IBSS != pRoamProfile->BSSType )
11411 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011412 hddLog (VOS_TRACE_LEVEL_ERROR,
Arif Hussain6d2a3322013-11-17 19:50:10 -080011413 "%s Interface type is not set to IBSS", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -070011414 return -EINVAL;
11415 }
11416
Praveen Kumar Sirisillad123d142013-09-24 16:50:13 -070011417 /* BSSID is provided by upper layers hence no need to AUTO generate */
11418 if (NULL != params->bssid) {
11419 if (ccmCfgSetInt(pHddCtx->hHal, WNI_CFG_IBSS_AUTO_BSSID, 0,
11420 NULL, eANI_BOOLEAN_FALSE)==eHAL_STATUS_FAILURE) {
11421 hddLog (VOS_TRACE_LEVEL_ERROR,
11422 "%s:ccmCfgStInt faild for WNI_CFG_IBSS_AUTO_BSSID", __func__);
11423 return -EIO;
11424 }
11425 }
krunal sonie9002db2013-11-25 14:24:17 -080011426 else if(pHddCtx->cfg_ini->isCoalesingInIBSSAllowed == 0)
11427 {
11428 if (ccmCfgSetInt(pHddCtx->hHal, WNI_CFG_IBSS_AUTO_BSSID, 0,
11429 NULL, eANI_BOOLEAN_FALSE)==eHAL_STATUS_FAILURE)
11430 {
11431 hddLog (VOS_TRACE_LEVEL_ERROR,
11432 "%s:ccmCfgStInt faild for WNI_CFG_IBSS_AUTO_BSSID", __func__);
11433 return -EIO;
11434 }
11435 params->bssid = vos_mem_malloc(sizeof(VOS_MAC_ADDR_SIZE));
11436 if (!params->bssid)
11437 {
11438 hddLog (VOS_TRACE_LEVEL_ERROR,
11439 "%s:Failed memory allocation", __func__);
11440 return -EIO;
11441 }
11442 vos_mem_copy((v_U8_t *)params->bssid,
11443 (v_U8_t *)&pHddCtx->cfg_ini->IbssBssid.bytes[0],
11444 VOS_MAC_ADDR_SIZE);
11445 alloc_bssid = VOS_TRUE;
11446 }
Praveen Kumar Sirisillad123d142013-09-24 16:50:13 -070011447
Jeff Johnson295189b2012-06-20 16:38:30 -070011448 /* Set Channel */
Yue Maf49ba872013-08-19 12:04:25 -070011449 if (NULL !=
11450#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,8,0))
11451 params->chandef.chan)
11452#else
11453 params->channel)
11454#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070011455 {
11456 u8 channelNum;
Shailender Karmuchi15cd0672013-05-15 19:50:04 -070011457 v_U32_t numChans = WNI_CFG_VALID_CHANNEL_LIST_LEN;
11458 v_U8_t validChan[WNI_CFG_VALID_CHANNEL_LIST_LEN];
11459 tHalHandle hHal = WLAN_HDD_GET_HAL_CTX(pAdapter);
11460 int indx;
Jeff Johnson295189b2012-06-20 16:38:30 -070011461
11462 /* Get channel number */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011463 channelNum =
Yue Maf49ba872013-08-19 12:04:25 -070011464 ieee80211_frequency_to_channel(
11465#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,8,0))
11466 params->chandef.chan->center_freq);
11467#else
11468 params->channel->center_freq);
11469#endif
Shailender Karmuchi15cd0672013-05-15 19:50:04 -070011470
11471 if (0 != ccmCfgGetStr(hHal, WNI_CFG_VALID_CHANNEL_LIST,
11472 validChan, &numChans))
Jeff Johnson295189b2012-06-20 16:38:30 -070011473 {
Shailender Karmuchi15cd0672013-05-15 19:50:04 -070011474 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: No valid channel list",
11475 __func__);
11476 return -EOPNOTSUPP;
Jeff Johnson295189b2012-06-20 16:38:30 -070011477 }
Shailender Karmuchi15cd0672013-05-15 19:50:04 -070011478
11479 for (indx = 0; indx < numChans; indx++)
Jeff Johnson295189b2012-06-20 16:38:30 -070011480 {
Shailender Karmuchi15cd0672013-05-15 19:50:04 -070011481 if (channelNum == validChan[indx])
11482 {
11483 break;
11484 }
11485 }
11486 if (indx >= numChans)
11487 {
11488 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Not valid Channel %d",
Jeff Johnson295189b2012-06-20 16:38:30 -070011489 __func__, channelNum);
11490 return -EINVAL;
11491 }
Shailender Karmuchi15cd0672013-05-15 19:50:04 -070011492 /* Set the Operational Channel */
11493 hddLog(VOS_TRACE_LEVEL_INFO_HIGH, "%s: set channel %d", __func__,
11494 channelNum);
11495 pRoamProfile->ChannelInfo.numOfChannels = 1;
11496 pHddStaCtx->conn_info.operationChannel = channelNum;
11497 pRoamProfile->ChannelInfo.ChannelList =
11498 &pHddStaCtx->conn_info.operationChannel;
Jeff Johnson295189b2012-06-20 16:38:30 -070011499 }
11500
11501 /* Initialize security parameters */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011502 status = wlan_hdd_cfg80211_set_privacy_ibss(pAdapter, params);
Jeff Johnson295189b2012-06-20 16:38:30 -070011503 if (status < 0)
11504 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011505 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: failed to set security parameters",
Jeff Johnson295189b2012-06-20 16:38:30 -070011506 __func__);
11507 return status;
11508 }
11509
11510 /* Issue connect start */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011511 status = wlan_hdd_cfg80211_connect_start(pAdapter, params->ssid,
Shailender Karmuchi15cd0672013-05-15 19:50:04 -070011512 params->ssid_len, params->bssid,
11513 pHddStaCtx->conn_info.operationChannel);
Jeff Johnson295189b2012-06-20 16:38:30 -070011514
11515 if (0 > status)
11516 {
11517 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: connect failed", __func__);
11518 return status;
11519 }
11520
krunal sonie9002db2013-11-25 14:24:17 -080011521 if (NULL != params->bssid &&
11522 pHddCtx->cfg_ini->isCoalesingInIBSSAllowed == 0 &&
11523 alloc_bssid == VOS_TRUE)
11524 {
11525 vos_mem_free(params->bssid);
11526 }
Jeff Johnson295189b2012-06-20 16:38:30 -070011527 return 0;
11528}
11529
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053011530static int wlan_hdd_cfg80211_join_ibss( struct wiphy *wiphy,
11531 struct net_device *dev,
11532 struct cfg80211_ibss_params *params
11533 )
11534{
11535 int ret = 0;
11536
11537 vos_ssr_protect(__func__);
11538 ret = __wlan_hdd_cfg80211_join_ibss(wiphy, dev, params);
11539 vos_ssr_unprotect(__func__);
11540
11541 return ret;
11542}
11543
Jeff Johnson295189b2012-06-20 16:38:30 -070011544/*
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053011545 * FUNCTION: __wlan_hdd_cfg80211_leave_ibss
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011546 * This function is used to leave an IBSS
Jeff Johnson295189b2012-06-20 16:38:30 -070011547 */
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053011548static int __wlan_hdd_cfg80211_leave_ibss( struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -070011549 struct net_device *dev
11550 )
11551{
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011552 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( dev );
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053011553 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
11554 tCsrRoamProfile *pRoamProfile;
11555 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053011556 int status;
Jeff Johnson295189b2012-06-20 16:38:30 -070011557
11558 ENTER();
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053011559
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053011560 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
11561 TRACE_CODE_HDD_CFG80211_LEAVE_IBSS,
11562 pAdapter->sessionId, eCSR_DISCONNECT_REASON_IBSS_LEAVE));
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053011563 status = wlan_hdd_validate_context(pHddCtx);
11564
11565 if (0 != status)
Jeff Johnson04dd8a82012-06-29 20:41:40 -070011566 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053011567 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
11568 "%s: HDD context is not valid", __func__);
11569 return status;
Jeff Johnson04dd8a82012-06-29 20:41:40 -070011570 }
11571
Sushant Kaushik8bc7df22014-04-09 17:55:29 +053011572 hddLog(VOS_TRACE_LEVEL_INFO, "%s: device_mode = %s (%d)", __func__,
11573 hdd_device_modetoString(pAdapter->device_mode),
11574 pAdapter->device_mode);
Jeff Johnson295189b2012-06-20 16:38:30 -070011575 if (NULL == pWextState)
11576 {
Arif Hussain6d2a3322013-11-17 19:50:10 -080011577 hddLog (VOS_TRACE_LEVEL_ERROR, "%s ERROR: Data Storage Corruption",
Jeff Johnson295189b2012-06-20 16:38:30 -070011578 __func__);
11579 return -EIO;
11580 }
11581
11582 pRoamProfile = &pWextState->roamProfile;
11583
11584 /* Issue disconnect only if interface type is set to IBSS */
11585 if (eCSR_BSS_TYPE_START_IBSS != pRoamProfile->BSSType)
11586 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011587 hddLog (VOS_TRACE_LEVEL_ERROR, "%s: BSS Type is not set to IBSS",
Jeff Johnson295189b2012-06-20 16:38:30 -070011588 __func__);
11589 return -EINVAL;
11590 }
11591
11592 /* Issue Disconnect request */
11593 INIT_COMPLETION(pAdapter->disconnect_comp_var);
11594 sme_RoamDisconnect( WLAN_HDD_GET_HAL_CTX(pAdapter), pAdapter->sessionId,
11595 eCSR_DISCONNECT_REASON_IBSS_LEAVE);
11596
11597 return 0;
11598}
11599
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053011600static int wlan_hdd_cfg80211_leave_ibss( struct wiphy *wiphy,
11601 struct net_device *dev
11602 )
11603{
11604 int ret = 0;
11605
11606 vos_ssr_protect(__func__);
11607 ret = __wlan_hdd_cfg80211_leave_ibss(wiphy, dev);
11608 vos_ssr_unprotect(__func__);
11609
11610 return ret;
11611}
11612
Jeff Johnson295189b2012-06-20 16:38:30 -070011613/*
Mahesh A Saptasagar179d2252014-06-02 21:32:21 +053011614 * FUNCTION: __wlan_hdd_cfg80211_set_wiphy_params
Jeff Johnson295189b2012-06-20 16:38:30 -070011615 * This function is used to set the phy parameters
11616 * (RTS Threshold/FRAG Threshold/Retry Count etc ...)
11617 */
Mahesh A Saptasagar179d2252014-06-02 21:32:21 +053011618static int __wlan_hdd_cfg80211_set_wiphy_params(struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -070011619 u32 changed)
11620{
11621 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
11622 tHalHandle hHal = pHddCtx->hHal;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053011623 int status;
Jeff Johnson295189b2012-06-20 16:38:30 -070011624
11625 ENTER();
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053011626 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
11627 TRACE_CODE_HDD_CFG80211_SET_WIPHY_PARAMS,
11628 NO_SESSION, wiphy->rts_threshold));
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053011629 status = wlan_hdd_validate_context(pHddCtx);
11630
11631 if (0 != status)
Jeff Johnson04dd8a82012-06-29 20:41:40 -070011632 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053011633 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
11634 "%s: HDD context is not valid", __func__);
11635 return status;
Jeff Johnson04dd8a82012-06-29 20:41:40 -070011636 }
11637
Jeff Johnson295189b2012-06-20 16:38:30 -070011638 if (changed & WIPHY_PARAM_RTS_THRESHOLD)
11639 {
11640 u16 rts_threshold = (wiphy->rts_threshold == -1) ?
11641 WNI_CFG_RTS_THRESHOLD_STAMAX :
11642 wiphy->rts_threshold;
11643
11644 if ((WNI_CFG_RTS_THRESHOLD_STAMIN > rts_threshold) ||
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011645 (WNI_CFG_RTS_THRESHOLD_STAMAX < rts_threshold))
Jeff Johnson295189b2012-06-20 16:38:30 -070011646 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011647 hddLog(VOS_TRACE_LEVEL_ERROR,
11648 "%s: Invalid RTS Threshold value %hu",
Jeff Johnson295189b2012-06-20 16:38:30 -070011649 __func__, rts_threshold);
11650 return -EINVAL;
11651 }
11652
11653 if (0 != ccmCfgSetInt(hHal, WNI_CFG_RTS_THRESHOLD,
11654 rts_threshold, ccmCfgSetCallback,
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011655 eANI_BOOLEAN_TRUE))
Jeff Johnson295189b2012-06-20 16:38:30 -070011656 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011657 hddLog(VOS_TRACE_LEVEL_ERROR,
11658 "%s: ccmCfgSetInt failed for rts_threshold value %hu",
Jeff Johnson295189b2012-06-20 16:38:30 -070011659 __func__, rts_threshold);
11660 return -EIO;
11661 }
11662
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011663 hddLog(VOS_TRACE_LEVEL_INFO_MED, "%s: set rts threshold %hu", __func__,
Jeff Johnson295189b2012-06-20 16:38:30 -070011664 rts_threshold);
11665 }
11666
11667 if (changed & WIPHY_PARAM_FRAG_THRESHOLD)
11668 {
11669 u16 frag_threshold = (wiphy->frag_threshold == -1) ?
11670 WNI_CFG_FRAGMENTATION_THRESHOLD_STAMAX :
11671 wiphy->frag_threshold;
11672
11673 if ((WNI_CFG_FRAGMENTATION_THRESHOLD_STAMIN > frag_threshold)||
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011674 (WNI_CFG_FRAGMENTATION_THRESHOLD_STAMAX < frag_threshold) )
Jeff Johnson295189b2012-06-20 16:38:30 -070011675 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011676 hddLog(VOS_TRACE_LEVEL_ERROR,
11677 "%s: Invalid frag_threshold value %hu", __func__,
Jeff Johnson295189b2012-06-20 16:38:30 -070011678 frag_threshold);
11679 return -EINVAL;
11680 }
11681
11682 if (0 != ccmCfgSetInt(hHal, WNI_CFG_FRAGMENTATION_THRESHOLD,
11683 frag_threshold, ccmCfgSetCallback,
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011684 eANI_BOOLEAN_TRUE))
Jeff Johnson295189b2012-06-20 16:38:30 -070011685 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011686 hddLog(VOS_TRACE_LEVEL_ERROR,
11687 "%s: ccmCfgSetInt failed for frag_threshold value %hu",
Jeff Johnson295189b2012-06-20 16:38:30 -070011688 __func__, frag_threshold);
11689 return -EIO;
11690 }
11691
11692 hddLog(VOS_TRACE_LEVEL_INFO_MED, "%s: set frag threshold %hu", __func__,
11693 frag_threshold);
11694 }
11695
11696 if ((changed & WIPHY_PARAM_RETRY_SHORT)
11697 || (changed & WIPHY_PARAM_RETRY_LONG))
11698 {
11699 u8 retry_value = (changed & WIPHY_PARAM_RETRY_SHORT) ?
11700 wiphy->retry_short :
11701 wiphy->retry_long;
11702
11703 if ((WNI_CFG_LONG_RETRY_LIMIT_STAMIN > retry_value) ||
11704 (WNI_CFG_LONG_RETRY_LIMIT_STAMAX < retry_value))
11705 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011706 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Invalid Retry count %hu",
Jeff Johnson295189b2012-06-20 16:38:30 -070011707 __func__, retry_value);
11708 return -EINVAL;
11709 }
11710
11711 if (changed & WIPHY_PARAM_RETRY_SHORT)
11712 {
11713 if (0 != ccmCfgSetInt(hHal, WNI_CFG_LONG_RETRY_LIMIT,
11714 retry_value, ccmCfgSetCallback,
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011715 eANI_BOOLEAN_TRUE))
Jeff Johnson295189b2012-06-20 16:38:30 -070011716 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011717 hddLog(VOS_TRACE_LEVEL_ERROR,
11718 "%s: ccmCfgSetInt failed for long retry count %hu",
Jeff Johnson295189b2012-06-20 16:38:30 -070011719 __func__, retry_value);
11720 return -EIO;
11721 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011722 hddLog(VOS_TRACE_LEVEL_INFO_MED, "%s: set long retry count %hu",
Jeff Johnson295189b2012-06-20 16:38:30 -070011723 __func__, retry_value);
11724 }
11725 else if (changed & WIPHY_PARAM_RETRY_SHORT)
11726 {
11727 if (0 != ccmCfgSetInt(hHal, WNI_CFG_SHORT_RETRY_LIMIT,
11728 retry_value, ccmCfgSetCallback,
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011729 eANI_BOOLEAN_TRUE))
Jeff Johnson295189b2012-06-20 16:38:30 -070011730 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011731 hddLog(VOS_TRACE_LEVEL_ERROR,
11732 "%s: ccmCfgSetInt failed for short retry count %hu",
Jeff Johnson295189b2012-06-20 16:38:30 -070011733 __func__, retry_value);
11734 return -EIO;
11735 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011736 hddLog(VOS_TRACE_LEVEL_INFO_MED, "%s: set short retry count %hu",
Jeff Johnson295189b2012-06-20 16:38:30 -070011737 __func__, retry_value);
11738 }
11739 }
11740
11741 return 0;
11742}
11743
Mahesh A Saptasagar179d2252014-06-02 21:32:21 +053011744static int wlan_hdd_cfg80211_set_wiphy_params(struct wiphy *wiphy,
11745 u32 changed)
11746{
11747 int ret;
11748
11749 vos_ssr_protect(__func__);
11750 ret = __wlan_hdd_cfg80211_set_wiphy_params(wiphy, changed);
11751 vos_ssr_unprotect(__func__);
11752
11753 return ret;
11754}
11755
Jeff Johnson295189b2012-06-20 16:38:30 -070011756/*
Mahesh A Saptasagar179d2252014-06-02 21:32:21 +053011757 * FUNCTION: __wlan_hdd_cfg80211_set_txpower
Jeff Johnson295189b2012-06-20 16:38:30 -070011758 * This function is used to set the txpower
11759 */
Mahesh A Saptasagar179d2252014-06-02 21:32:21 +053011760static int __wlan_hdd_cfg80211_set_txpower(struct wiphy *wiphy,
Yue Maf49ba872013-08-19 12:04:25 -070011761#if LINUX_VERSION_CODE >= KERNEL_VERSION(3,8,0)
11762 struct wireless_dev *wdev,
11763#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070011764#if LINUX_VERSION_CODE <= KERNEL_VERSION(2,6,35)
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011765 enum tx_power_setting type,
Jeff Johnson295189b2012-06-20 16:38:30 -070011766#else
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011767 enum nl80211_tx_power_setting type,
Jeff Johnson295189b2012-06-20 16:38:30 -070011768#endif
11769 int dbm)
11770{
11771 hdd_context_t *pHddCtx = (hdd_context_t*) wiphy_priv(wiphy);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053011772 tHalHandle hHal = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -070011773 tSirMacAddr bssid = {0xFF,0xFF,0xFF,0xFF,0xFF,0xFF};
11774 tSirMacAddr selfMac = {0xFF,0xFF,0xFF,0xFF,0xFF,0xFF};
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053011775 int status;
Jeff Johnson295189b2012-06-20 16:38:30 -070011776
11777 ENTER();
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053011778 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
11779 TRACE_CODE_HDD_CFG80211_SET_TXPOWER,
11780 NO_SESSION, type ));
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053011781 status = wlan_hdd_validate_context(pHddCtx);
11782
11783 if (0 != status)
11784 {
11785 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
11786 "%s: HDD context is not valid", __func__);
11787 return status;
11788 }
11789
11790 hHal = pHddCtx->hHal;
11791
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011792 if (0 != ccmCfgSetInt(hHal, WNI_CFG_CURRENT_TX_POWER_LEVEL,
11793 dbm, ccmCfgSetCallback,
11794 eANI_BOOLEAN_TRUE))
Jeff Johnson295189b2012-06-20 16:38:30 -070011795 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011796 hddLog(VOS_TRACE_LEVEL_ERROR,
Jeff Johnson295189b2012-06-20 16:38:30 -070011797 "%s: ccmCfgSetInt failed for tx power %hu", __func__, dbm);
11798 return -EIO;
11799 }
11800
11801 hddLog(VOS_TRACE_LEVEL_INFO_MED, "%s: set tx power level %d dbm", __func__,
11802 dbm);
11803
11804 switch(type)
11805 {
11806 case NL80211_TX_POWER_AUTOMATIC: /*automatically determine transmit power*/
11807 /* Fall through */
11808 case NL80211_TX_POWER_LIMITED: /*limit TX power by the mBm parameter*/
11809 if( sme_SetMaxTxPower(hHal, bssid, selfMac, dbm) != eHAL_STATUS_SUCCESS )
11810 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011811 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Setting maximum tx power failed",
11812 __func__);
11813 return -EIO;
Jeff Johnson295189b2012-06-20 16:38:30 -070011814 }
11815 break;
11816 case NL80211_TX_POWER_FIXED: /*fix TX power to the mBm parameter*/
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011817 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: NL80211_TX_POWER_FIXED not supported",
Jeff Johnson295189b2012-06-20 16:38:30 -070011818 __func__);
11819 return -EOPNOTSUPP;
11820 break;
11821 default:
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011822 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Invalid power setting type %d",
11823 __func__, type);
Jeff Johnson295189b2012-06-20 16:38:30 -070011824 return -EIO;
11825 }
11826
11827 return 0;
11828}
11829
Mahesh A Saptasagar179d2252014-06-02 21:32:21 +053011830static int wlan_hdd_cfg80211_set_txpower(struct wiphy *wiphy,
11831#if LINUX_VERSION_CODE >= KERNEL_VERSION(3,8,0)
11832 struct wireless_dev *wdev,
11833#endif
11834#if LINUX_VERSION_CODE <= KERNEL_VERSION(2,6,35)
11835 enum tx_power_setting type,
11836#else
11837 enum nl80211_tx_power_setting type,
11838#endif
11839 int dbm)
11840{
11841 int ret;
11842 vos_ssr_protect(__func__);
11843 ret = __wlan_hdd_cfg80211_set_txpower(wiphy,
11844#if LINUX_VERSION_CODE >= KERNEL_VERSION(3,8,0)
11845 wdev,
11846#endif
11847#if LINUX_VERSION_CODE <= KERNEL_VERSION(2,6,35)
11848 type,
11849#else
11850 type,
11851#endif
11852 dbm);
11853 vos_ssr_unprotect(__func__);
11854
11855 return ret;
11856}
11857
Jeff Johnson295189b2012-06-20 16:38:30 -070011858/*
11859 * FUNCTION: wlan_hdd_cfg80211_get_txpower
11860 * This function is used to read the txpower
11861 */
Yue Maf49ba872013-08-19 12:04:25 -070011862static int wlan_hdd_cfg80211_get_txpower(struct wiphy *wiphy,
11863#if LINUX_VERSION_CODE >= KERNEL_VERSION(3,8,0)
11864 struct wireless_dev *wdev,
11865#endif
11866 int *dbm)
Jeff Johnson295189b2012-06-20 16:38:30 -070011867{
11868
11869 hdd_adapter_t *pAdapter;
11870 hdd_context_t *pHddCtx = (hdd_context_t*) wiphy_priv(wiphy);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053011871 int status;
Jeff Johnson295189b2012-06-20 16:38:30 -070011872
Jeff Johnsone7245742012-09-05 17:12:55 -070011873 ENTER();
11874
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053011875 status = wlan_hdd_validate_context(pHddCtx);
Jeff Johnson295189b2012-06-20 16:38:30 -070011876
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053011877 if (0 != status)
Jeff Johnson04dd8a82012-06-29 20:41:40 -070011878 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053011879 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
11880 "%s: HDD context is not valid", __func__);
11881 *dbm = 0;
11882 return status;
Jeff Johnson04dd8a82012-06-29 20:41:40 -070011883 }
11884
Jeff Johnson295189b2012-06-20 16:38:30 -070011885 pAdapter = hdd_get_adapter(pHddCtx, WLAN_HDD_INFRA_STATION);
11886 if (NULL == pAdapter)
11887 {
11888 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: Not in station context " ,__func__);
11889 return -ENOENT;
11890 }
11891
11892 wlan_hdd_get_classAstats(pAdapter);
11893 *dbm = pAdapter->hdd_stats.ClassA_stat.max_pwr;
11894
Jeff Johnsone7245742012-09-05 17:12:55 -070011895 EXIT();
Jeff Johnson295189b2012-06-20 16:38:30 -070011896 return 0;
11897}
11898
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053011899static int __wlan_hdd_cfg80211_get_station(struct wiphy *wiphy, struct net_device *dev,
Jeff Johnson295189b2012-06-20 16:38:30 -070011900 u8* mac, struct station_info *sinfo)
11901{
11902 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( dev );
11903 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
11904 int ssidlen = pHddStaCtx->conn_info.SSID.SSID.length;
c_hpothu44ff4e02014-05-08 00:13:57 +053011905 tANI_U32 rate_flags;
Jeff Johnson295189b2012-06-20 16:38:30 -070011906
11907 hdd_context_t *pHddCtx = (hdd_context_t*) wiphy_priv(wiphy);
11908 hdd_config_t *pCfg = pHddCtx->cfg_ini;
Jeff Johnson295189b2012-06-20 16:38:30 -070011909
11910 tANI_U8 OperationalRates[CSR_DOT11_SUPPORTED_RATES_MAX];
11911 tANI_U32 ORLeng = CSR_DOT11_SUPPORTED_RATES_MAX;
11912 tANI_U8 ExtendedRates[CSR_DOT11_EXTENDED_SUPPORTED_RATES_MAX];
11913 tANI_U32 ERLeng = CSR_DOT11_EXTENDED_SUPPORTED_RATES_MAX;
11914 tANI_U8 MCSRates[SIZE_OF_BASIC_MCS_SET];
11915 tANI_U32 MCSLeng = SIZE_OF_BASIC_MCS_SET;
11916 tANI_U16 maxRate = 0;
11917 tANI_U16 myRate;
11918 tANI_U16 currentRate = 0;
11919 tANI_U8 maxSpeedMCS = 0;
11920 tANI_U8 maxMCSIdx = 0;
11921 tANI_U8 rateFlag = 1;
c_hpothu79aab322014-07-14 21:11:01 +053011922 tANI_U8 i, j, rssidx, mode=0;
Madan Mohan Koyyalamudic75be962012-10-18 19:19:03 -070011923 tANI_U16 temp;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053011924 int status;
Jeff Johnson295189b2012-06-20 16:38:30 -070011925
Leo Chang6f8870f2013-03-26 18:11:36 -070011926#ifdef WLAN_FEATURE_11AC
11927 tANI_U32 vht_mcs_map;
11928 eDataRate11ACMaxMcs vhtMaxMcs;
11929#endif /* WLAN_FEATURE_11AC */
11930
Jeff Johnsone7245742012-09-05 17:12:55 -070011931 ENTER();
11932
Jeff Johnson295189b2012-06-20 16:38:30 -070011933 if ((eConnectionState_Associated != pHddStaCtx->conn_info.connState) ||
11934 (0 == ssidlen))
11935 {
11936 hddLog(VOS_TRACE_LEVEL_INFO, "%s: Not associated or"
11937 " Invalid ssidlen, %d", __func__, ssidlen);
11938 /*To keep GUI happy*/
11939 return 0;
11940 }
11941
Mukul Sharma811205f2014-07-09 21:07:30 +053011942 if (VOS_TRUE == pHddStaCtx->hdd_ReassocScenario)
11943 {
11944 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
11945 "%s: Roaming in progress, so unable to proceed this request", __func__);
11946 return 0;
11947 }
11948
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053011949 status = wlan_hdd_validate_context(pHddCtx);
11950
11951 if (0 != status)
Jeff Johnson04dd8a82012-06-29 20:41:40 -070011952 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053011953 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
11954 "%s: HDD context is not valid", __func__);
11955 return status;
Jeff Johnson04dd8a82012-06-29 20:41:40 -070011956 }
11957
Jeff Johnson295189b2012-06-20 16:38:30 -070011958
Kiet Lam3b17fc82013-09-27 05:24:08 +053011959 wlan_hdd_get_rssi(pAdapter, &sinfo->signal);
11960 sinfo->filled |= STATION_INFO_SIGNAL;
11961
c_hpothu09f19542014-05-30 21:53:31 +053011962 wlan_hdd_get_station_stats(pAdapter);
11963 rate_flags = pAdapter->hdd_stats.ClassA_stat.tx_rate_flags;
11964
11965 /*overwrite rate_flags if MAX link-speed need to be reported*/
c_hpothu44ff4e02014-05-08 00:13:57 +053011966 if ((eHDD_LINK_SPEED_REPORT_MAX == pCfg->reportMaxLinkSpeed) ||
11967 (eHDD_LINK_SPEED_REPORT_MAX_SCALED == pCfg->reportMaxLinkSpeed &&
c_hpothu79aab322014-07-14 21:11:01 +053011968 sinfo->signal >= pCfg->linkSpeedRssiLow))
c_hpothu44ff4e02014-05-08 00:13:57 +053011969 {
11970 rate_flags = pAdapter->maxRateFlags;
11971 }
c_hpothu44ff4e02014-05-08 00:13:57 +053011972
Jeff Johnson295189b2012-06-20 16:38:30 -070011973 //convert to the UI units of 100kbps
11974 myRate = pAdapter->hdd_stats.ClassA_stat.tx_rate * 5;
11975
11976#ifdef LINKSPEED_DEBUG_ENABLED
Leo Chang6f8870f2013-03-26 18:11:36 -070011977 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 -070011978 sinfo->signal,
11979 pCfg->reportMaxLinkSpeed,
11980 myRate,
11981 (int) pCfg->linkSpeedRssiHigh,
Madan Mohan Koyyalamudi8df78d52012-11-02 12:30:06 -070011982 (int) pCfg->linkSpeedRssiMid,
11983 (int) pCfg->linkSpeedRssiLow,
Leo Chang6f8870f2013-03-26 18:11:36 -070011984 (int) rate_flags,
11985 (int) pAdapter->hdd_stats.ClassA_stat.mcs_index);
Jeff Johnson295189b2012-06-20 16:38:30 -070011986#endif //LINKSPEED_DEBUG_ENABLED
11987
11988 if (eHDD_LINK_SPEED_REPORT_ACTUAL != pCfg->reportMaxLinkSpeed)
11989 {
11990 // we do not want to necessarily report the current speed
11991 if (eHDD_LINK_SPEED_REPORT_MAX == pCfg->reportMaxLinkSpeed)
11992 {
11993 // report the max possible speed
11994 rssidx = 0;
11995 }
11996 else if (eHDD_LINK_SPEED_REPORT_MAX_SCALED == pCfg->reportMaxLinkSpeed)
11997 {
11998 // report the max possible speed with RSSI scaling
11999 if (sinfo->signal >= pCfg->linkSpeedRssiHigh)
12000 {
12001 // report the max possible speed
12002 rssidx = 0;
12003 }
Madan Mohan Koyyalamudi8df78d52012-11-02 12:30:06 -070012004 else if (sinfo->signal >= pCfg->linkSpeedRssiMid)
Jeff Johnson295189b2012-06-20 16:38:30 -070012005 {
12006 // report middle speed
12007 rssidx = 1;
12008 }
Madan Mohan Koyyalamudi8df78d52012-11-02 12:30:06 -070012009 else if (sinfo->signal >= pCfg->linkSpeedRssiLow)
12010 {
12011 // report middle speed
12012 rssidx = 2;
12013 }
Jeff Johnson295189b2012-06-20 16:38:30 -070012014 else
12015 {
12016 // report actual speed
Madan Mohan Koyyalamudi8df78d52012-11-02 12:30:06 -070012017 rssidx = 3;
Jeff Johnson295189b2012-06-20 16:38:30 -070012018 }
12019 }
12020 else
12021 {
12022 // unknown, treat as eHDD_LINK_SPEED_REPORT_MAX
12023 hddLog(VOS_TRACE_LEVEL_ERROR,
12024 "%s: Invalid value for reportMaxLinkSpeed: %u",
12025 __func__, pCfg->reportMaxLinkSpeed);
12026 rssidx = 0;
12027 }
12028
12029 maxRate = 0;
12030
12031 /* Get Basic Rate Set */
Gopichand Nakkala05ab1322013-02-15 11:28:38 +053012032 if (0 != ccmCfgGetStr(WLAN_HDD_GET_HAL_CTX(pAdapter), WNI_CFG_OPERATIONAL_RATE_SET,
12033 OperationalRates, &ORLeng))
12034 {
12035 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: ccm api returned failure", __func__);
12036 /*To keep GUI happy*/
12037 return 0;
12038 }
12039
Jeff Johnson295189b2012-06-20 16:38:30 -070012040 for (i = 0; i < ORLeng; i++)
12041 {
Jeff Johnsone7245742012-09-05 17:12:55 -070012042 for (j = 0; j < (sizeof(supported_data_rate) / sizeof(supported_data_rate[0])); j ++)
Jeff Johnson295189b2012-06-20 16:38:30 -070012043 {
12044 /* Validate Rate Set */
12045 if (supported_data_rate[j].beacon_rate_index == (OperationalRates[i] & 0x7F))
12046 {
12047 currentRate = supported_data_rate[j].supported_rate[rssidx];
12048 break;
12049 }
12050 }
12051 /* Update MAX rate */
12052 maxRate = (currentRate > maxRate)?currentRate:maxRate;
12053 }
12054
12055 /* Get Extended Rate Set */
Gopichand Nakkala05ab1322013-02-15 11:28:38 +053012056 if (0 != ccmCfgGetStr(WLAN_HDD_GET_HAL_CTX(pAdapter), WNI_CFG_EXTENDED_OPERATIONAL_RATE_SET,
12057 ExtendedRates, &ERLeng))
12058 {
12059 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: ccm api returned failure", __func__);
12060 /*To keep GUI happy*/
12061 return 0;
12062 }
12063
Jeff Johnson295189b2012-06-20 16:38:30 -070012064 for (i = 0; i < ERLeng; i++)
12065 {
Jeff Johnsone7245742012-09-05 17:12:55 -070012066 for (j = 0; j < (sizeof(supported_data_rate) / sizeof(supported_data_rate[0])); j ++)
Jeff Johnson295189b2012-06-20 16:38:30 -070012067 {
12068 if (supported_data_rate[j].beacon_rate_index == (ExtendedRates[i] & 0x7F))
12069 {
12070 currentRate = supported_data_rate[j].supported_rate[rssidx];
12071 break;
12072 }
12073 }
12074 /* Update MAX rate */
12075 maxRate = (currentRate > maxRate)?currentRate:maxRate;
12076 }
c_hpothu79aab322014-07-14 21:11:01 +053012077
Kiet Lamb69f8dc2013-11-15 15:34:27 +053012078 /* Get MCS Rate Set --
Kaushik, Sushantdc304d82014-01-22 10:58:37 +053012079 Only if we are always reporting max speed (or)
Kiet Lamb69f8dc2013-11-15 15:34:27 +053012080 if we have good rssi */
c_hpothu79aab322014-07-14 21:11:01 +053012081 if ((3 != rssidx) && !(rate_flags & eHAL_TX_RATE_LEGACY))
Jeff Johnson295189b2012-06-20 16:38:30 -070012082 {
c_hpothu79aab322014-07-14 21:11:01 +053012083 if (rate_flags & eHAL_TX_RATE_VHT80)
12084 mode = 2;
12085 else if (rate_flags & (eHAL_TX_RATE_VHT40 | eHAL_TX_RATE_HT40))
12086 mode = 1;
12087 else
12088 mode = 0;
12089
Gopichand Nakkala05ab1322013-02-15 11:28:38 +053012090 if (0 != ccmCfgGetStr(WLAN_HDD_GET_HAL_CTX(pAdapter), WNI_CFG_CURRENT_MCS_SET,
12091 MCSRates, &MCSLeng))
12092 {
12093 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: ccm api returned failure", __func__);
12094 /*To keep GUI happy*/
12095 return 0;
12096 }
Jeff Johnson295189b2012-06-20 16:38:30 -070012097 rateFlag = 0;
Leo Chang6f8870f2013-03-26 18:11:36 -070012098#ifdef WLAN_FEATURE_11AC
12099 /* VHT80 rate has seperate rate table */
Gopichand Nakkala4c705372013-04-24 13:20:33 +053012100 if (rate_flags & (eHAL_TX_RATE_VHT20|eHAL_TX_RATE_VHT40|eHAL_TX_RATE_VHT80))
Jeff Johnson295189b2012-06-20 16:38:30 -070012101 {
Leo Chang6f8870f2013-03-26 18:11:36 -070012102 ccmCfgGetInt(WLAN_HDD_GET_HAL_CTX(pAdapter), WNI_CFG_VHT_TX_MCS_MAP, &vht_mcs_map);
Gopichand Nakkala4c705372013-04-24 13:20:33 +053012103 vhtMaxMcs = (eDataRate11ACMaxMcs)(vht_mcs_map & DATA_RATE_11AC_MCS_MASK );
Leo Chang6f8870f2013-03-26 18:11:36 -070012104 if (rate_flags & eHAL_TX_RATE_SGI)
Jeff Johnson295189b2012-06-20 16:38:30 -070012105 {
Leo Chang6f8870f2013-03-26 18:11:36 -070012106 rateFlag |= 1;
Jeff Johnson295189b2012-06-20 16:38:30 -070012107 }
Leo Chang6f8870f2013-03-26 18:11:36 -070012108 if (DATA_RATE_11AC_MAX_MCS_7 == vhtMaxMcs)
Jeff Johnson295189b2012-06-20 16:38:30 -070012109 {
Leo Chang6f8870f2013-03-26 18:11:36 -070012110 maxMCSIdx = 7;
12111 }
12112 else if (DATA_RATE_11AC_MAX_MCS_8 == vhtMaxMcs)
12113 {
12114 maxMCSIdx = 8;
12115 }
12116 else if (DATA_RATE_11AC_MAX_MCS_9 == vhtMaxMcs)
12117 {
Gopichand Nakkala4c705372013-04-24 13:20:33 +053012118 //VHT20 is supporting 0~8
12119 if (rate_flags & eHAL_TX_RATE_VHT20)
12120 maxMCSIdx = 8;
12121 else
12122 maxMCSIdx = 9;
Leo Chang6f8870f2013-03-26 18:11:36 -070012123 }
Gopichand Nakkala4c705372013-04-24 13:20:33 +053012124
c_hpothu79aab322014-07-14 21:11:01 +053012125 if (0 != rssidx)/*check for scaled */
12126 {
12127 //get middle rate MCS index if rssi=1/2
12128 for (i=0; i <= maxMCSIdx; i++)
12129 {
12130 if (sinfo->signal <= rssiMcsTbl[mode][i])
12131 {
12132 maxMCSIdx = i;
12133 break;
12134 }
12135 }
12136 }
12137
Gopichand Nakkala4c705372013-04-24 13:20:33 +053012138 if (rate_flags & eHAL_TX_RATE_VHT80)
12139 {
12140 currentRate = supported_vht_mcs_rate[pAdapter->hdd_stats.ClassA_stat.mcs_index].supported_VHT80_rate[rateFlag];
12141 maxRate = supported_vht_mcs_rate[maxMCSIdx].supported_VHT80_rate[rateFlag];
12142 }
12143 else if (rate_flags & eHAL_TX_RATE_VHT40)
12144 {
12145 currentRate = supported_vht_mcs_rate[pAdapter->hdd_stats.ClassA_stat.mcs_index].supported_VHT40_rate[rateFlag];
12146 maxRate = supported_vht_mcs_rate[maxMCSIdx].supported_VHT40_rate[rateFlag];
12147 }
12148 else if (rate_flags & eHAL_TX_RATE_VHT20)
12149 {
12150 currentRate = supported_vht_mcs_rate[pAdapter->hdd_stats.ClassA_stat.mcs_index].supported_VHT20_rate[rateFlag];
12151 maxRate = supported_vht_mcs_rate[maxMCSIdx].supported_VHT20_rate[rateFlag];
12152 }
12153
Leo Chang6f8870f2013-03-26 18:11:36 -070012154 maxSpeedMCS = 1;
12155 if (currentRate > maxRate)
12156 {
12157 maxRate = currentRate;
12158 }
Gopichand Nakkala4c705372013-04-24 13:20:33 +053012159
Leo Chang6f8870f2013-03-26 18:11:36 -070012160 }
12161 else
12162#endif /* WLAN_FEATURE_11AC */
12163 {
12164 if (rate_flags & eHAL_TX_RATE_HT40)
12165 {
12166 rateFlag |= 1;
12167 }
12168 if (rate_flags & eHAL_TX_RATE_SGI)
12169 {
12170 rateFlag |= 2;
12171 }
12172
Girish Gowli01abcee2014-07-31 20:18:55 +053012173 temp = sizeof(supported_mcs_rate) / sizeof(supported_mcs_rate[0]);
c_hpothu79aab322014-07-14 21:11:01 +053012174 if (rssidx == 1 || rssidx == 2)
12175 {
12176 //get middle rate MCS index if rssi=1/2
12177 for (i=0; i <= 7; i++)
12178 {
12179 if (sinfo->signal <= rssiMcsTbl[mode][i])
12180 {
12181 temp = i+1;
12182 break;
12183 }
12184 }
12185 }
c_hpothu79aab322014-07-14 21:11:01 +053012186
12187 for (i = 0; i < MCSLeng; i++)
12188 {
Leo Chang6f8870f2013-03-26 18:11:36 -070012189 for (j = 0; j < temp; j++)
12190 {
12191 if (supported_mcs_rate[j].beacon_rate_index == MCSRates[i])
12192 {
12193 currentRate = supported_mcs_rate[j].supported_rate[rateFlag];
12194 break;
12195 }
12196 }
12197 if ((j < temp) && (currentRate > maxRate))
12198 {
12199 maxRate = currentRate;
12200 maxSpeedMCS = 1;
12201 maxMCSIdx = supported_mcs_rate[j].beacon_rate_index;
12202 }
Jeff Johnson295189b2012-06-20 16:38:30 -070012203 }
12204 }
12205 }
12206
Gopichand Nakkala4c705372013-04-24 13:20:33 +053012207 else if (!(rate_flags & eHAL_TX_RATE_LEGACY))
12208 {
12209 maxRate = myRate;
12210 maxSpeedMCS = 1;
12211 maxMCSIdx = pAdapter->hdd_stats.ClassA_stat.mcs_index;
12212 }
Jeff Johnson295189b2012-06-20 16:38:30 -070012213 // make sure we report a value at least as big as our current rate
c_hpothu79aab322014-07-14 21:11:01 +053012214 if ((maxRate < myRate) || (0 == maxRate))
Jeff Johnson295189b2012-06-20 16:38:30 -070012215 {
12216 maxRate = myRate;
12217 if (rate_flags & eHAL_TX_RATE_LEGACY)
12218 {
12219 maxSpeedMCS = 0;
12220 }
12221 else
12222 {
12223 maxSpeedMCS = 1;
12224 maxMCSIdx = pAdapter->hdd_stats.ClassA_stat.mcs_index;
12225 }
12226 }
12227
Gopichand Nakkala4c705372013-04-24 13:20:33 +053012228 if (rate_flags & eHAL_TX_RATE_LEGACY)
Jeff Johnson295189b2012-06-20 16:38:30 -070012229 {
12230 sinfo->txrate.legacy = maxRate;
12231#ifdef LINKSPEED_DEBUG_ENABLED
12232 pr_info("Reporting legacy rate %d\n", sinfo->txrate.legacy);
12233#endif //LINKSPEED_DEBUG_ENABLED
12234 }
12235 else
12236 {
12237 sinfo->txrate.mcs = maxMCSIdx;
Leo Chang6f8870f2013-03-26 18:11:36 -070012238#ifdef WLAN_FEATURE_11AC
12239 sinfo->txrate.nss = 1;
12240 if (rate_flags & eHAL_TX_RATE_VHT80)
12241 {
12242 sinfo->txrate.flags |= RATE_INFO_FLAGS_VHT_MCS;
Gopichand Nakkala4c705372013-04-24 13:20:33 +053012243 sinfo->txrate.flags |= RATE_INFO_FLAGS_80_MHZ_WIDTH;
Leo Chang6f8870f2013-03-26 18:11:36 -070012244 }
Gopichand Nakkala4c705372013-04-24 13:20:33 +053012245 else if (rate_flags & eHAL_TX_RATE_VHT40)
Leo Chang6f8870f2013-03-26 18:11:36 -070012246 {
Gopichand Nakkala4c705372013-04-24 13:20:33 +053012247 sinfo->txrate.flags |= RATE_INFO_FLAGS_VHT_MCS;
12248 sinfo->txrate.flags |= RATE_INFO_FLAGS_40_MHZ_WIDTH;
12249 }
12250 else if (rate_flags & eHAL_TX_RATE_VHT20)
12251 {
12252 sinfo->txrate.flags |= RATE_INFO_FLAGS_VHT_MCS;
12253 }
12254#endif /* WLAN_FEATURE_11AC */
12255 if (rate_flags & (eHAL_TX_RATE_HT20 | eHAL_TX_RATE_HT40))
12256 {
12257 sinfo->txrate.flags |= RATE_INFO_FLAGS_MCS;
12258 if (rate_flags & eHAL_TX_RATE_HT40)
12259 {
12260 sinfo->txrate.flags |= RATE_INFO_FLAGS_40_MHZ_WIDTH;
12261 }
Leo Chang6f8870f2013-03-26 18:11:36 -070012262 }
Jeff Johnson295189b2012-06-20 16:38:30 -070012263 if (rate_flags & eHAL_TX_RATE_SGI)
12264 {
12265 sinfo->txrate.flags |= RATE_INFO_FLAGS_SHORT_GI;
12266 }
Gopichand Nakkala4c705372013-04-24 13:20:33 +053012267
Jeff Johnson295189b2012-06-20 16:38:30 -070012268#ifdef LINKSPEED_DEBUG_ENABLED
12269 pr_info("Reporting MCS rate %d flags %x\n",
12270 sinfo->txrate.mcs,
12271 sinfo->txrate.flags );
12272#endif //LINKSPEED_DEBUG_ENABLED
12273 }
12274 }
12275 else
12276 {
12277 // report current rate instead of max rate
12278
12279 if (rate_flags & eHAL_TX_RATE_LEGACY)
12280 {
12281 //provide to the UI in units of 100kbps
12282 sinfo->txrate.legacy = myRate;
12283#ifdef LINKSPEED_DEBUG_ENABLED
12284 pr_info("Reporting actual legacy rate %d\n", sinfo->txrate.legacy);
12285#endif //LINKSPEED_DEBUG_ENABLED
12286 }
12287 else
12288 {
12289 //must be MCS
12290 sinfo->txrate.mcs = pAdapter->hdd_stats.ClassA_stat.mcs_index;
Leo Chang6f8870f2013-03-26 18:11:36 -070012291#ifdef WLAN_FEATURE_11AC
12292 sinfo->txrate.nss = 1;
12293 if (rate_flags & eHAL_TX_RATE_VHT80)
12294 {
12295 sinfo->txrate.flags |= RATE_INFO_FLAGS_VHT_MCS;
12296 }
12297 else
12298#endif /* WLAN_FEATURE_11AC */
12299 {
12300 sinfo->txrate.flags |= RATE_INFO_FLAGS_MCS;
12301 }
Jeff Johnson295189b2012-06-20 16:38:30 -070012302 if (rate_flags & eHAL_TX_RATE_SGI)
12303 {
12304 sinfo->txrate.flags |= RATE_INFO_FLAGS_SHORT_GI;
12305 }
12306 if (rate_flags & eHAL_TX_RATE_HT40)
12307 {
12308 sinfo->txrate.flags |= RATE_INFO_FLAGS_40_MHZ_WIDTH;
12309 }
Leo Chang6f8870f2013-03-26 18:11:36 -070012310#ifdef WLAN_FEATURE_11AC
12311 else if (rate_flags & eHAL_TX_RATE_VHT80)
12312 {
12313 sinfo->txrate.flags |= RATE_INFO_FLAGS_80_MHZ_WIDTH;
12314 }
12315#endif /* WLAN_FEATURE_11AC */
Jeff Johnson295189b2012-06-20 16:38:30 -070012316#ifdef LINKSPEED_DEBUG_ENABLED
12317 pr_info("Reporting actual MCS rate %d flags %x\n",
12318 sinfo->txrate.mcs,
12319 sinfo->txrate.flags );
12320#endif //LINKSPEED_DEBUG_ENABLED
12321 }
12322 }
12323 sinfo->filled |= STATION_INFO_TX_BITRATE;
12324
Madan Mohan Koyyalamudi4d4d2812012-09-24 14:08:29 -070012325 sinfo->tx_packets =
12326 pAdapter->hdd_stats.summary_stat.tx_frm_cnt[0] +
12327 pAdapter->hdd_stats.summary_stat.tx_frm_cnt[1] +
12328 pAdapter->hdd_stats.summary_stat.tx_frm_cnt[2] +
12329 pAdapter->hdd_stats.summary_stat.tx_frm_cnt[3];
12330
12331 sinfo->tx_retries =
12332 pAdapter->hdd_stats.summary_stat.retry_cnt[0] +
12333 pAdapter->hdd_stats.summary_stat.retry_cnt[1] +
12334 pAdapter->hdd_stats.summary_stat.retry_cnt[2] +
12335 pAdapter->hdd_stats.summary_stat.retry_cnt[3];
12336
12337 sinfo->tx_failed =
12338 pAdapter->hdd_stats.summary_stat.fail_cnt[0] +
12339 pAdapter->hdd_stats.summary_stat.fail_cnt[1] +
12340 pAdapter->hdd_stats.summary_stat.fail_cnt[2] +
12341 pAdapter->hdd_stats.summary_stat.fail_cnt[3];
12342
12343 sinfo->filled |=
12344 STATION_INFO_TX_PACKETS |
12345 STATION_INFO_TX_RETRIES |
12346 STATION_INFO_TX_FAILED;
12347
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053012348 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
12349 TRACE_CODE_HDD_CFG80211_GET_STA,
12350 pAdapter->sessionId, maxRate));
Madan Mohan Koyyalamudi4d4d2812012-09-24 14:08:29 -070012351 EXIT();
12352 return 0;
Jeff Johnson295189b2012-06-20 16:38:30 -070012353}
12354
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053012355static int wlan_hdd_cfg80211_get_station(struct wiphy *wiphy, struct net_device *dev,
12356 u8* mac, struct station_info *sinfo)
12357{
12358 int ret;
12359
12360 vos_ssr_protect(__func__);
12361 ret = __wlan_hdd_cfg80211_get_station(wiphy, dev, mac, sinfo);
12362 vos_ssr_unprotect(__func__);
12363
12364 return ret;
12365}
12366
12367static int __wlan_hdd_cfg80211_set_power_mgmt(struct wiphy *wiphy,
Sameer Thalappilc9f26e92013-06-07 10:11:06 -070012368 struct net_device *dev, bool mode, int timeout)
Jeff Johnson295189b2012-06-20 16:38:30 -070012369{
12370 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
Gopichand Nakkala20c4c042013-04-19 22:08:55 +053012371 hdd_context_t *pHddCtx;
Jeff Johnson295189b2012-06-20 16:38:30 -070012372 VOS_STATUS vos_status;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053012373 int status;
Jeff Johnson295189b2012-06-20 16:38:30 -070012374
Jeff Johnsone7245742012-09-05 17:12:55 -070012375 ENTER();
12376
Jeff Johnson295189b2012-06-20 16:38:30 -070012377 if (NULL == pAdapter)
12378 {
Arif Hussain6d2a3322013-11-17 19:50:10 -080012379 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Adapter is NULL", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -070012380 return -ENODEV;
12381 }
12382
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053012383 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
12384 TRACE_CODE_HDD_CFG80211_SET_POWER_MGMT,
12385 pAdapter->sessionId, timeout));
12386
Gopichand Nakkala20c4c042013-04-19 22:08:55 +053012387 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053012388 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkala20c4c042013-04-19 22:08:55 +053012389
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053012390 if (0 != status)
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012391 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053012392 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
12393 "%s: HDD context is not valid", __func__);
12394 return status;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012395 }
12396
Gopichand Nakkala20c4c042013-04-19 22:08:55 +053012397 if ((DRIVER_POWER_MODE_AUTO == !mode) &&
12398 (TRUE == pHddCtx->hdd_wlan_suspended) &&
12399 (pHddCtx->cfg_ini->fhostArpOffload) &&
12400 (eConnectionState_Associated ==
12401 (WLAN_HDD_GET_STATION_CTX_PTR(pAdapter))->conn_info.connState))
12402 {
Amar Singhald53568e2013-09-26 11:03:45 -070012403
12404 hddLog(VOS_TRACE_LEVEL_INFO,
12405 "offload: in cfg80211_set_power_mgmt, calling arp offload");
Gopichand Nakkalab03e8082013-05-30 18:09:25 +053012406 vos_status = hdd_conf_arp_offload(pAdapter, TRUE);
Gopichand Nakkala20c4c042013-04-19 22:08:55 +053012407 if (!VOS_IS_STATUS_SUCCESS(vos_status))
12408 {
12409 hddLog(VOS_TRACE_LEVEL_INFO,
Arif Hussain6d2a3322013-11-17 19:50:10 -080012410 "%s:Failed to enable ARPOFFLOAD Feature %d",
Gopichand Nakkala20c4c042013-04-19 22:08:55 +053012411 __func__, vos_status);
12412 }
12413 }
12414
Jeff Johnson295189b2012-06-20 16:38:30 -070012415 /**The get power cmd from the supplicant gets updated by the nl only
12416 *on successful execution of the function call
12417 *we are oppositely mapped w.r.t mode in the driver
12418 **/
12419 vos_status = wlan_hdd_enter_bmps(pAdapter, !mode);
12420
Jeff Johnsone7245742012-09-05 17:12:55 -070012421 EXIT();
Jeff Johnson295189b2012-06-20 16:38:30 -070012422 if (VOS_STATUS_E_FAILURE == vos_status)
12423 {
c_hpothu6ff1c3c2013-10-01 19:01:57 +053012424 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
12425 "%s: failed to enter bmps mode", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -070012426 return -EINVAL;
12427 }
12428 return 0;
12429}
12430
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053012431static int wlan_hdd_cfg80211_set_power_mgmt(struct wiphy *wiphy,
12432 struct net_device *dev, bool mode, int timeout)
12433{
12434 int ret;
Jeff Johnson295189b2012-06-20 16:38:30 -070012435
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053012436 vos_ssr_protect(__func__);
12437 ret = __wlan_hdd_cfg80211_set_power_mgmt(wiphy, dev, mode, timeout);
12438 vos_ssr_unprotect(__func__);
12439
12440 return ret;
12441}
Jeff Johnson295189b2012-06-20 16:38:30 -070012442#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
12443static int wlan_hdd_set_default_mgmt_key(struct wiphy *wiphy,
12444 struct net_device *netdev,
12445 u8 key_index)
12446{
Jeff Johnsone7245742012-09-05 17:12:55 -070012447 ENTER();
Jeff Johnson295189b2012-06-20 16:38:30 -070012448 return 0;
12449}
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012450#endif //LINUX_VERSION_CODE
Jeff Johnson295189b2012-06-20 16:38:30 -070012451
12452#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,4,0))
12453static int wlan_hdd_set_txq_params(struct wiphy *wiphy,
12454 struct net_device *dev,
12455 struct ieee80211_txq_params *params)
12456{
Jeff Johnsone7245742012-09-05 17:12:55 -070012457 ENTER();
Jeff Johnson295189b2012-06-20 16:38:30 -070012458 return 0;
12459}
12460#elif (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
12461static int wlan_hdd_set_txq_params(struct wiphy *wiphy,
12462 struct ieee80211_txq_params *params)
12463{
Jeff Johnsone7245742012-09-05 17:12:55 -070012464 ENTER();
Jeff Johnson295189b2012-06-20 16:38:30 -070012465 return 0;
12466}
12467#endif //LINUX_VERSION_CODE
12468
Naresh Jayaram69e3f282014-10-14 12:29:12 +053012469#ifdef CFG80211_DEL_STA_V2
12470static int __wlan_hdd_cfg80211_del_station(struct wiphy *wiphy,
12471 struct net_device *dev,
12472 struct station_del_parameters *param)
12473#else
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053012474static int __wlan_hdd_cfg80211_del_station(struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -070012475 struct net_device *dev, u8 *mac)
Naresh Jayaram69e3f282014-10-14 12:29:12 +053012476#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070012477{
12478 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053012479 hdd_context_t *pHddCtx;
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -080012480 VOS_STATUS vos_status;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053012481 int status;
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -080012482 v_U8_t staId;
Jeff Johnson295189b2012-06-20 16:38:30 -070012483
Jeff Johnsone7245742012-09-05 17:12:55 -070012484 ENTER();
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053012485
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053012486 if ( NULL == pAdapter )
Jeff Johnson295189b2012-06-20 16:38:30 -070012487 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053012488 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Invalid Adapter" ,__func__);
Jeff Johnson295189b2012-06-20 16:38:30 -070012489 return -EINVAL;
12490 }
12491
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053012492 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
12493 TRACE_CODE_HDD_CFG80211_DEL_STA,
12494 pAdapter->sessionId, pAdapter->device_mode));
12495
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053012496 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
12497 status = wlan_hdd_validate_context(pHddCtx);
Jeff Johnson295189b2012-06-20 16:38:30 -070012498
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053012499 if (0 != status)
Jeff Johnson04dd8a82012-06-29 20:41:40 -070012500 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053012501 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
12502 "%s: HDD context is not valid", __func__);
12503 return status;
Jeff Johnson04dd8a82012-06-29 20:41:40 -070012504 }
12505
Jeff Johnson295189b2012-06-20 16:38:30 -070012506 if ( (WLAN_HDD_SOFTAP == pAdapter->device_mode)
Jeff Johnson295189b2012-06-20 16:38:30 -070012507 || (WLAN_HDD_P2P_GO == pAdapter->device_mode)
Jeff Johnson295189b2012-06-20 16:38:30 -070012508 )
12509 {
12510 if( NULL == mac )
12511 {
12512 v_U16_t i;
12513 for(i = 0; i < WLAN_MAX_STA_COUNT; i++)
12514 {
Rajesh Chauhan18488fc2013-08-22 10:15:03 -070012515 if ((pAdapter->aStaInfo[i].isUsed) &&
12516 (!pAdapter->aStaInfo[i].isDeauthInProgress))
Jeff Johnson295189b2012-06-20 16:38:30 -070012517 {
12518 u8 *macAddr = pAdapter->aStaInfo[i].macAddrSTA.bytes;
12519 hddLog(VOS_TRACE_LEVEL_INFO,
Arif Hussain24bafea2013-11-15 15:10:03 -080012520 "%s: Delete STA with MAC::"
12521 MAC_ADDRESS_STR,
12522 __func__, MAC_ADDR_ARRAY(macAddr));
Rajesh Chauhan18488fc2013-08-22 10:15:03 -070012523 vos_status = hdd_softap_sta_deauth(pAdapter, macAddr);
12524 if (VOS_IS_STATUS_SUCCESS(vos_status))
12525 pAdapter->aStaInfo[i].isDeauthInProgress = TRUE;
Jeff Johnson295189b2012-06-20 16:38:30 -070012526 }
12527 }
12528 }
12529 else
12530 {
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -080012531
12532 vos_status = hdd_softap_GetStaId(pAdapter,(v_MACADDR_t *)mac, &staId);
12533 if (!VOS_IS_STATUS_SUCCESS(vos_status))
12534 {
12535 hddLog(VOS_TRACE_LEVEL_INFO,
Arif Hussain24bafea2013-11-15 15:10:03 -080012536 "%s: Skip this DEL STA as this is not used::"
12537 MAC_ADDRESS_STR,
12538 __func__, MAC_ADDR_ARRAY(mac));
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -080012539 return -ENOENT;
12540 }
12541
12542 if( pAdapter->aStaInfo[staId].isDeauthInProgress == TRUE)
12543 {
12544 hddLog(VOS_TRACE_LEVEL_INFO,
Arif Hussain24bafea2013-11-15 15:10:03 -080012545 "%s: Skip this DEL STA as deauth is in progress::"
12546 MAC_ADDRESS_STR,
12547 __func__, MAC_ADDR_ARRAY(mac));
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -080012548 return -ENOENT;
12549 }
12550
12551 pAdapter->aStaInfo[staId].isDeauthInProgress = TRUE;
12552
Jeff Johnson295189b2012-06-20 16:38:30 -070012553 hddLog(VOS_TRACE_LEVEL_INFO,
12554 "%s: Delete STA with MAC::"
Arif Hussain24bafea2013-11-15 15:10:03 -080012555 MAC_ADDRESS_STR,
Jeff Johnson295189b2012-06-20 16:38:30 -070012556 __func__,
Arif Hussain24bafea2013-11-15 15:10:03 -080012557 MAC_ADDR_ARRAY(mac));
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -080012558
12559 vos_status = hdd_softap_sta_deauth(pAdapter, mac);
12560 if (!VOS_IS_STATUS_SUCCESS(vos_status))
12561 {
12562 pAdapter->aStaInfo[staId].isDeauthInProgress = FALSE;
12563 hddLog(VOS_TRACE_LEVEL_INFO,
12564 "%s: STA removal failed for ::"
Arif Hussain24bafea2013-11-15 15:10:03 -080012565 MAC_ADDRESS_STR,
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -080012566 __func__,
Arif Hussain24bafea2013-11-15 15:10:03 -080012567 MAC_ADDR_ARRAY(mac));
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -080012568 return -ENOENT;
12569 }
12570
Jeff Johnson295189b2012-06-20 16:38:30 -070012571 }
12572 }
12573
12574 EXIT();
12575
12576 return 0;
12577}
Naresh Jayaram69e3f282014-10-14 12:29:12 +053012578
12579#ifdef CFG80211_DEL_STA_V2
12580static int wlan_hdd_cfg80211_del_station(struct wiphy *wiphy,
12581 struct net_device *dev,
12582 struct station_del_parameters *param)
12583#else
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053012584static int wlan_hdd_cfg80211_del_station(struct wiphy *wiphy,
12585 struct net_device *dev, u8 *mac)
Naresh Jayaram69e3f282014-10-14 12:29:12 +053012586#endif
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053012587{
12588 int ret;
Jeff Johnson295189b2012-06-20 16:38:30 -070012589
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053012590 vos_ssr_protect(__func__);
Naresh Jayaram69e3f282014-10-14 12:29:12 +053012591#ifdef CFG80211_DEL_STA_V2
12592 ret = __wlan_hdd_cfg80211_del_station(wiphy, dev, param);
12593#else
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053012594 ret = __wlan_hdd_cfg80211_del_station(wiphy, dev, mac);
Naresh Jayaram69e3f282014-10-14 12:29:12 +053012595#endif
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053012596 vos_ssr_unprotect(__func__);
12597
12598 return ret;
12599}
12600
12601static int __wlan_hdd_cfg80211_add_station(struct wiphy *wiphy,
Hoonki Lee11f7dda2013-02-14 16:55:44 -080012602 struct net_device *dev, u8 *mac, struct station_parameters *params)
12603{
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053012604 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
Gopichand Nakkalab977a972013-02-18 19:15:09 -080012605 int status = -EPERM;
Hoonki Lee11f7dda2013-02-14 16:55:44 -080012606#ifdef FEATURE_WLAN_TDLS
12607 u32 mask, set;
Hoonki Lee11f7dda2013-02-14 16:55:44 -080012608 ENTER();
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053012609
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053012610 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
12611 TRACE_CODE_HDD_CFG80211_ADD_STA,
12612 pAdapter->sessionId, params->listen_interval));
Mohit Khanna698ba2a2012-12-04 15:08:18 -080012613 mask = params->sta_flags_mask;
12614
12615 set = params->sta_flags_set;
12616
Gopichand Nakkalac87400e2013-03-13 18:51:00 -070012617#ifdef WLAN_FEATURE_TDLS_DEBUG
12618 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
12619 "%s: mask 0x%x set 0x%x " MAC_ADDRESS_STR,
12620 __func__, mask, set, MAC_ADDR_ARRAY(mac));
12621#endif
Mohit Khanna698ba2a2012-12-04 15:08:18 -080012622
12623 if (mask & BIT(NL80211_STA_FLAG_TDLS_PEER)) {
12624 if (set & BIT(NL80211_STA_FLAG_TDLS_PEER)) {
Gopichand Nakkala681989c2013-03-06 22:27:48 -080012625 status = wlan_hdd_tdls_add_station(wiphy, dev, mac, 0, NULL);
Mohit Khanna698ba2a2012-12-04 15:08:18 -080012626 }
12627 }
12628#endif
Gopichand Nakkalab977a972013-02-18 19:15:09 -080012629 return status;
Jeff Johnson295189b2012-06-20 16:38:30 -070012630}
12631
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053012632static int wlan_hdd_cfg80211_add_station(struct wiphy *wiphy,
12633 struct net_device *dev, u8 *mac, struct station_parameters *params)
12634{
12635 int ret;
Jeff Johnson04dd8a82012-06-29 20:41:40 -070012636
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053012637 vos_ssr_protect(__func__);
12638 ret = __wlan_hdd_cfg80211_add_station(wiphy, dev, mac, params);
12639 vos_ssr_unprotect(__func__);
12640
12641 return ret;
12642}
Jeff Johnson04dd8a82012-06-29 20:41:40 -070012643#ifdef FEATURE_WLAN_LFR
Wilson Yang6507c4e2013-10-01 20:11:19 -070012644
Mahesh A Saptasagarf7418d72014-06-02 14:48:54 +053012645static int __wlan_hdd_cfg80211_set_pmksa(struct wiphy *wiphy, struct net_device *dev,
Jeff Johnsond13512a2012-07-17 11:42:19 -070012646 struct cfg80211_pmksa *pmksa)
Jeff Johnson04dd8a82012-06-29 20:41:40 -070012647{
Jeff Johnson04dd8a82012-06-29 20:41:40 -070012648 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
12649 tHalHandle halHandle;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012650 eHalStatus result;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053012651 int status;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053012652 hdd_context_t *pHddCtx;
Kanchanapally, Vidyullatha2633ace2014-09-25 15:16:50 +053012653 tPmkidCacheInfo pmk_id;
Jeff Johnsone7245742012-09-05 17:12:55 -070012654
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012655 // Validate pAdapter
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053012656 if ( NULL == pAdapter )
Jeff Johnson04dd8a82012-06-29 20:41:40 -070012657 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053012658 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Invalid Adapter" ,__func__);
Jeff Johnson04dd8a82012-06-29 20:41:40 -070012659 return -EINVAL;
12660 }
12661
Kanchanapally, Vidyullatha2633ace2014-09-25 15:16:50 +053012662 if (!pmksa) {
12663 hddLog(LOGE, FL("pmksa is NULL"));
12664 return -EINVAL;
12665 }
12666
12667 if (!pmksa->bssid || !pmksa->pmkid) {
12668 hddLog(LOGE, FL("pmksa->bssid(%p) or pmksa->pmkid(%p) is NULL"),
12669 pmksa->bssid, pmksa->pmkid);
12670 return -EINVAL;
12671 }
12672
12673 hddLog(VOS_TRACE_LEVEL_DEBUG, "%s: set PMKSA for " MAC_ADDRESS_STR,
12674 __func__, MAC_ADDR_ARRAY(pmksa->bssid));
12675
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053012676 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
12677 status = wlan_hdd_validate_context(pHddCtx);
Jeff Johnson04dd8a82012-06-29 20:41:40 -070012678
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053012679 if (0 != status)
Jeff Johnson04dd8a82012-06-29 20:41:40 -070012680 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053012681 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
12682 "%s: HDD context is not valid", __func__);
12683 return status;
Jeff Johnson04dd8a82012-06-29 20:41:40 -070012684 }
12685
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012686 // Retrieve halHandle
Jeff Johnson04dd8a82012-06-29 20:41:40 -070012687 halHandle = WLAN_HDD_GET_HAL_CTX(pAdapter);
12688
Kanchanapally, Vidyullatha2633ace2014-09-25 15:16:50 +053012689 vos_mem_copy(pmk_id.BSSID, pmksa->bssid, ETHER_ADDR_LEN);
12690 vos_mem_copy(pmk_id.PMKID, pmksa->pmkid, CSR_RSN_PMKID_SIZE);
Jeff Johnson04dd8a82012-06-29 20:41:40 -070012691
Kanchanapally, Vidyullatha2633ace2014-09-25 15:16:50 +053012692 /* Add to the PMKSA ID Cache in CSR */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012693 result = sme_RoamSetPMKIDCache(halHandle,pAdapter->sessionId,
Kanchanapally, Vidyullatha2633ace2014-09-25 15:16:50 +053012694 &pmk_id, 1, FALSE);
12695
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053012696 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
12697 TRACE_CODE_HDD_CFG80211_SET_PMKSA,
12698 pAdapter->sessionId, result));
Kanchanapally, Vidyullatha2633ace2014-09-25 15:16:50 +053012699
12700 return HAL_STATUS_SUCCESS(result) ? 0 : -EINVAL;
Jeff Johnson04dd8a82012-06-29 20:41:40 -070012701}
12702
Mahesh A Saptasagarf7418d72014-06-02 14:48:54 +053012703static int wlan_hdd_cfg80211_set_pmksa(struct wiphy *wiphy, struct net_device *dev,
12704 struct cfg80211_pmksa *pmksa)
12705{
12706 int ret;
12707
12708 vos_ssr_protect(__func__);
12709 ret = __wlan_hdd_cfg80211_set_pmksa(wiphy, dev, pmksa);
12710 vos_ssr_unprotect(__func__);
12711
12712 return ret;
12713}
Jeff Johnson04dd8a82012-06-29 20:41:40 -070012714
Wilson Yang6507c4e2013-10-01 20:11:19 -070012715
Mahesh A Saptasagarf7418d72014-06-02 14:48:54 +053012716static int __wlan_hdd_cfg80211_del_pmksa(struct wiphy *wiphy, struct net_device *dev,
Wilson Yang6507c4e2013-10-01 20:11:19 -070012717 struct cfg80211_pmksa *pmksa)
Jeff Johnson04dd8a82012-06-29 20:41:40 -070012718{
Wilson Yang6507c4e2013-10-01 20:11:19 -070012719 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
12720 tHalHandle halHandle;
Wilson Yang6507c4e2013-10-01 20:11:19 -070012721 hdd_context_t *pHddCtx;
Wilson Yangef657d32014-01-15 19:19:23 -080012722 int status = 0;
Wilson Yang6507c4e2013-10-01 20:11:19 -070012723
Jeff Johnson0299d0a2013-10-30 12:37:43 -070012724 hddLog(VOS_TRACE_LEVEL_DEBUG, "%s: deleting PMKSA for " MAC_ADDRESS_STR,
12725 __func__, MAC_ADDR_ARRAY(pmksa->bssid));
Wilson Yang6507c4e2013-10-01 20:11:19 -070012726
12727 /* Validate pAdapter */
12728 if (NULL == pAdapter)
12729 {
12730 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Invalid Adapter" ,__func__);
12731 return -EINVAL;
12732 }
12733
Kanchanapally, Vidyullatha2633ace2014-09-25 15:16:50 +053012734 if (!pmksa) {
12735 hddLog(LOGE, FL("pmksa is NULL"));
12736 return -EINVAL;
12737 }
12738
12739 if (!pmksa->bssid) {
12740 hddLog(LOGE, FL("pmksa->bssid is NULL"));
12741 return -EINVAL;
12742 }
12743
Wilson Yang6507c4e2013-10-01 20:11:19 -070012744 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
12745 status = wlan_hdd_validate_context(pHddCtx);
12746
12747 if (0 != status)
12748 {
12749 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
12750 "%s: HDD context is not valid", __func__);
12751 return status;
12752 }
12753
12754 /*Retrieve halHandle*/
12755 halHandle = WLAN_HDD_GET_HAL_CTX(pAdapter);
12756
Kanchanapally, Vidyullatha2633ace2014-09-25 15:16:50 +053012757 /* Delete the PMKID CSR cache */
12758 if (eHAL_STATUS_SUCCESS !=
12759 sme_RoamDelPMKIDfromCache(halHandle,
12760 pAdapter->sessionId, pmksa->bssid, FALSE)) {
12761 hddLog(LOGE, FL("Failed to delete PMKSA for "MAC_ADDRESS_STR),
12762 MAC_ADDR_ARRAY(pmksa->bssid));
12763 status = -EINVAL;
Wilson Yang6507c4e2013-10-01 20:11:19 -070012764 }
12765
Wilson Yangef657d32014-01-15 19:19:23 -080012766 return status;
Jeff Johnson04dd8a82012-06-29 20:41:40 -070012767}
12768
Wilson Yang6507c4e2013-10-01 20:11:19 -070012769
Mahesh A Saptasagarf7418d72014-06-02 14:48:54 +053012770static int wlan_hdd_cfg80211_del_pmksa(struct wiphy *wiphy, struct net_device *dev,
12771 struct cfg80211_pmksa *pmksa)
12772{
12773 int ret;
Wilson Yang6507c4e2013-10-01 20:11:19 -070012774
Mahesh A Saptasagarf7418d72014-06-02 14:48:54 +053012775 vos_ssr_protect(__func__);
12776 ret = __wlan_hdd_cfg80211_del_pmksa(wiphy, dev, pmksa);
12777 vos_ssr_unprotect(__func__);
12778
12779 return ret;
12780
12781}
12782
12783static int __wlan_hdd_cfg80211_flush_pmksa(struct wiphy *wiphy, struct net_device *dev)
Jeff Johnson04dd8a82012-06-29 20:41:40 -070012784{
Wilson Yang6507c4e2013-10-01 20:11:19 -070012785 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
12786 tHalHandle halHandle;
12787 hdd_context_t *pHddCtx;
Wilson Yangef657d32014-01-15 19:19:23 -080012788 int status = 0;
Wilson Yang6507c4e2013-10-01 20:11:19 -070012789
12790 hddLog(VOS_TRACE_LEVEL_DEBUG, "%s: flushing PMKSA ",__func__);
12791
12792 /* Validate pAdapter */
12793 if (NULL == pAdapter)
12794 {
12795 hddLog(VOS_TRACE_LEVEL_ERROR,
12796 "%s: Invalid Adapter" ,__func__);
12797 return -EINVAL;
12798 }
12799
12800 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
12801 status = wlan_hdd_validate_context(pHddCtx);
12802
12803 if (0 != status)
12804 {
12805 hddLog(VOS_TRACE_LEVEL_ERROR,
12806 "%s: HDD context is not valid", __func__);
12807 return status;
12808 }
12809
12810 /*Retrieve halHandle*/
12811 halHandle = WLAN_HDD_GET_HAL_CTX(pAdapter);
12812
Kanchanapally, Vidyullatha2633ace2014-09-25 15:16:50 +053012813 /* Flush the PMKID cache in CSR */
12814 if (eHAL_STATUS_SUCCESS !=
12815 sme_RoamDelPMKIDfromCache(halHandle, pAdapter->sessionId, NULL, TRUE)) {
12816 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Cannot flush PMKIDCache"));
12817 status = -EINVAL;
Wilson Yang6507c4e2013-10-01 20:11:19 -070012818 }
12819
Wilson Yangef657d32014-01-15 19:19:23 -080012820 return status;
Jeff Johnson04dd8a82012-06-29 20:41:40 -070012821}
Mahesh A Saptasagarf7418d72014-06-02 14:48:54 +053012822
12823static int wlan_hdd_cfg80211_flush_pmksa(struct wiphy *wiphy, struct net_device *dev)
12824{
12825 int ret;
12826
12827 vos_ssr_protect(__func__);
12828 ret = __wlan_hdd_cfg80211_flush_pmksa(wiphy, dev);
12829 vos_ssr_unprotect(__func__);
12830
12831 return ret;
12832}
Jeff Johnson04dd8a82012-06-29 20:41:40 -070012833#endif
12834
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070012835#if defined(WLAN_FEATURE_VOWIFI_11R) && defined(KERNEL_SUPPORT_11R_CFG80211)
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053012836static int __wlan_hdd_cfg80211_update_ft_ies(struct wiphy *wiphy,
12837 struct net_device *dev,
12838 struct cfg80211_update_ft_ies_params *ftie)
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070012839{
12840 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
12841 hdd_station_ctx_t *pHddStaCtx;
12842
12843 if (NULL == pAdapter)
12844 {
Arif Hussain6d2a3322013-11-17 19:50:10 -080012845 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Adapter is NULL", __func__);
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070012846 return -ENODEV;
12847 }
12848
12849 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
12850
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053012851 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
12852 TRACE_CODE_HDD_CFG80211_UPDATE_FT_IES,
12853 pAdapter->sessionId, pHddStaCtx->conn_info.connState));
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070012854 // Added for debug on reception of Re-assoc Req.
12855 if (eConnectionState_Associated != pHddStaCtx->conn_info.connState)
12856 {
Arif Hussain6d2a3322013-11-17 19:50:10 -080012857 hddLog(LOGE, FL("Called with Ie of length = %zu when not associated"),
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070012858 ftie->ie_len);
Arif Hussain6d2a3322013-11-17 19:50:10 -080012859 hddLog(LOGE, FL("Should be Re-assoc Req IEs"));
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070012860 }
12861
12862#ifdef WLAN_FEATURE_VOWIFI_11R_DEBUG
Arif Hussain6d2a3322013-11-17 19:50:10 -080012863 hddLog(LOGE, FL("%s called with Ie of length = %zu"), __func__,
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070012864 ftie->ie_len);
12865#endif
12866
12867 // Pass the received FT IEs to SME
Gopichand Nakkala356fb102013-03-06 12:34:04 +053012868 sme_SetFTIEs( WLAN_HDD_GET_HAL_CTX(pAdapter), pAdapter->sessionId,
12869 (const u8 *)ftie->ie,
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070012870 ftie->ie_len);
12871 return 0;
12872}
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053012873
12874static int wlan_hdd_cfg80211_update_ft_ies(struct wiphy *wiphy,
12875 struct net_device *dev,
12876 struct cfg80211_update_ft_ies_params *ftie)
12877{
12878 int ret;
12879
12880 vos_ssr_protect(__func__);
12881 ret = __wlan_hdd_cfg80211_update_ft_ies(wiphy, dev, ftie);
12882 vos_ssr_unprotect(__func__);
12883
12884 return ret;
12885}
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070012886#endif
Jeff Johnson04dd8a82012-06-29 20:41:40 -070012887
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053012888#ifdef FEATURE_WLAN_SCAN_PNO
12889
12890void hdd_cfg80211_sched_scan_done_callback(void *callbackContext,
12891 tSirPrefNetworkFoundInd *pPrefNetworkFoundInd)
12892{
12893 int ret;
12894 hdd_adapter_t* pAdapter = (hdd_adapter_t*)callbackContext;
12895 hdd_context_t *pHddCtx;
12896
Nirav Shah80830bf2013-12-31 16:35:12 +053012897 ENTER();
12898
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053012899 if (NULL == pAdapter)
12900 {
Agarwal Ashish971c2882013-10-30 20:11:12 +053012901 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053012902 "%s: HDD adapter is Null", __func__);
12903 return ;
12904 }
12905
12906 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
12907 if (NULL == pHddCtx)
12908 {
12909 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
12910 "%s: HDD context is Null!!!", __func__);
12911 return ;
12912 }
12913
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053012914 spin_lock(&pHddCtx->schedScan_lock);
12915 if (TRUE == pHddCtx->isWiphySuspended)
12916 {
12917 pHddCtx->isSchedScanUpdatePending = TRUE;
12918 spin_unlock(&pHddCtx->schedScan_lock);
12919 hddLog(VOS_TRACE_LEVEL_INFO,
12920 "%s: Update cfg80211 scan database after it resume", __func__);
12921 return ;
12922 }
12923 spin_unlock(&pHddCtx->schedScan_lock);
12924
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053012925 ret = wlan_hdd_cfg80211_update_bss(pHddCtx->wiphy, pAdapter);
12926
12927 if (0 > ret)
12928 hddLog(VOS_TRACE_LEVEL_INFO, "%s: NO SCAN result", __func__);
12929
12930 cfg80211_sched_scan_results(pHddCtx->wiphy);
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053012931 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
12932 "%s: cfg80211 scan result database updated", __func__);
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053012933}
12934
12935/*
Mahesh A Saptasagar0f7b0372013-11-28 23:23:07 +053012936 * FUNCTION: wlan_hdd_is_pno_allowed
Vinay Krishna Erannacbf75f42014-02-26 17:35:20 +053012937 * Disallow pno if any session is active
Mahesh A Saptasagar0f7b0372013-11-28 23:23:07 +053012938 */
12939static eHalStatus wlan_hdd_is_pno_allowed(hdd_adapter_t *pAdapter)
12940{
12941 hdd_adapter_list_node_t *pAdapterNode = NULL, *pNext = NULL;
12942 hdd_adapter_t *pTempAdapter = NULL;
Vinay Krishna Eranna23ffd182013-12-26 19:16:55 +053012943 hdd_station_ctx_t *pStaCtx;
Mahesh A Saptasagar0f7b0372013-11-28 23:23:07 +053012944 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
12945 int status = 0;
12946 status = hdd_get_front_adapter(pHddCtx, &pAdapterNode);
12947
Vinay Krishna Erannacbf75f42014-02-26 17:35:20 +053012948 /* The current firmware design does not allow PNO during any
12949 * active sessions. Hence, determine the active sessions
12950 * and return a failure.
12951 */
Mahesh A Saptasagar0f7b0372013-11-28 23:23:07 +053012952 while ((NULL != pAdapterNode) && (VOS_STATUS_SUCCESS == status))
12953 {
12954 pTempAdapter = pAdapterNode->pAdapter;
Vinay Krishna Eranna23ffd182013-12-26 19:16:55 +053012955 pStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pTempAdapter);
Mahesh A Saptasagar0f7b0372013-11-28 23:23:07 +053012956
Vinay Krishna Eranna23ffd182013-12-26 19:16:55 +053012957 if (((WLAN_HDD_INFRA_STATION == pTempAdapter->device_mode)
12958 && (eConnectionState_NotConnected != pStaCtx->conn_info.connState))
12959 || (WLAN_HDD_P2P_CLIENT == pTempAdapter->device_mode)
12960 || (WLAN_HDD_P2P_GO == pTempAdapter->device_mode)
12961 || (WLAN_HDD_SOFTAP == pTempAdapter->device_mode)
12962 )
Mahesh A Saptasagar0f7b0372013-11-28 23:23:07 +053012963 {
Vinay Krishna Eranna23ffd182013-12-26 19:16:55 +053012964 return eHAL_STATUS_FAILURE;
Mahesh A Saptasagar0f7b0372013-11-28 23:23:07 +053012965 }
12966 status = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
12967 pAdapterNode = pNext;
12968 }
Vinay Krishna Eranna23ffd182013-12-26 19:16:55 +053012969 return eHAL_STATUS_SUCCESS;
Mahesh A Saptasagar0f7b0372013-11-28 23:23:07 +053012970}
12971
Vinay Krishna Erannaf0e523b2014-03-01 21:00:16 +053012972void hdd_cfg80211_sched_scan_start_status_cb(void *callbackContext, VOS_STATUS status)
12973{
12974 hdd_adapter_t *pAdapter = callbackContext;
12975 hdd_context_t *pHddCtx;
12976
12977 if ((NULL == pAdapter) || (WLAN_HDD_ADAPTER_MAGIC != pAdapter->magic))
12978 {
12979 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
12980 FL("Invalid adapter or adapter has invalid magic"));
12981 return;
12982 }
12983
12984 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
12985 if (0 != wlan_hdd_validate_context(pHddCtx))
12986 {
12987 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
12988 FL("HDD context is not valid"));
12989 return;
12990 }
12991
c_hpothub53c45d2014-08-18 16:53:14 +053012992 if (VOS_STATUS_SUCCESS != status)
12993 {
12994 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Vinay Krishna Erannaf0e523b2014-03-01 21:00:16 +053012995 FL("PNO enable response status = %d"), status);
c_hpothub53c45d2014-08-18 16:53:14 +053012996 pHddCtx->isPnoEnable = FALSE;
12997 }
Vinay Krishna Erannaf0e523b2014-03-01 21:00:16 +053012998
12999 pAdapter->pno_req_status = (status == VOS_STATUS_SUCCESS) ? 0 : -EBUSY;
13000 complete(&pAdapter->pno_comp_var);
13001}
13002
Mahesh A Saptasagar0f7b0372013-11-28 23:23:07 +053013003/*
Mahesh A Saptasagar6cc38562014-05-23 21:22:17 +053013004 * FUNCTION: __wlan_hdd_cfg80211_sched_scan_start
13005 * Function to enable PNO
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053013006 */
Mahesh A Saptasagar6cc38562014-05-23 21:22:17 +053013007static int __wlan_hdd_cfg80211_sched_scan_start(struct wiphy *wiphy,
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053013008 struct net_device *dev, struct cfg80211_sched_scan_request *request)
13009{
13010 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
13011 tpSirPNOScanReq pPnoRequest = NULL;
13012 hdd_context_t *pHddCtx;
13013 tHalHandle hHal;
Mahesh A Saptasagar7bd6ad42014-07-21 18:56:33 +053013014 v_U32_t i, indx, num_ch, tempInterval, j;
Sushant Kaushikd62d9782014-02-19 15:39:40 +053013015 u8 valid_ch[WNI_CFG_VALID_CHANNEL_LIST_LEN] = {0};
13016 u8 channels_allowed[WNI_CFG_VALID_CHANNEL_LIST_LEN] = {0};
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053013017 v_U32_t num_channels_allowed = WNI_CFG_VALID_CHANNEL_LIST_LEN;
13018 eHalStatus status = eHAL_STATUS_FAILURE;
Kamath Vinayakba5313f2013-08-22 15:52:39 +053013019 int ret = 0;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053013020
13021 if (NULL == pAdapter)
13022 {
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053013023 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053013024 "%s: HDD adapter is Null", __func__);
13025 return -ENODEV;
13026 }
13027
13028 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053013029 ret = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053013030
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053013031 if (0 != ret)
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053013032 {
Gopichand Nakkalac005b7c2013-05-14 16:04:14 +053013033 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
13034 "%s: HDD context is not valid", __func__);
Kamath Vinayakba5313f2013-08-22 15:52:39 +053013035 return -EINVAL;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053013036 }
13037
13038 hHal = WLAN_HDD_GET_HAL_CTX(pAdapter);
13039 if (NULL == hHal)
13040 {
13041 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
13042 "%s: HAL context is Null!!!", __func__);
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053013043 return -EINVAL;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053013044 }
Sushant Kaushik2fe89932014-09-03 10:58:09 +053013045 sme_ScanFlushResult(hHal, pAdapter->sessionId);
Mahesh A Saptasagar2395ee62014-05-21 19:12:21 +053013046 ret = wlan_hdd_scan_abort(pAdapter);
Girish Gowli4bf7a632014-06-12 13:42:11 +053013047 if (ret < 0)
Mahesh A Saptasagar2395ee62014-05-21 19:12:21 +053013048 {
13049 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
13050 "%s: aborting the existing scan is unsuccessfull", __func__);
13051 return -EBUSY;
13052 }
13053
Vinay Krishna Eranna23ffd182013-12-26 19:16:55 +053013054 if (eHAL_STATUS_SUCCESS != wlan_hdd_is_pno_allowed(pAdapter))
Mahesh A Saptasagar0f7b0372013-11-28 23:23:07 +053013055 {
Vinay Krishna Erannacbf75f42014-02-26 17:35:20 +053013056 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_WARN,
Vinay Krishna Eranna23ffd182013-12-26 19:16:55 +053013057 FL("Cannot handle sched_scan"));
Mahesh A Saptasagar0f7b0372013-11-28 23:23:07 +053013058 return -EBUSY;
13059 }
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053013060
c_hpothu37f21312014-04-09 21:49:54 +053013061 if (TRUE == pHddCtx->isPnoEnable)
13062 {
13063 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_WARN,
13064 FL("already PNO is enabled"));
13065 return -EBUSY;
13066 }
c_hpothu225aa7c2014-10-22 17:45:13 +053013067
13068 if (VOS_STATUS_SUCCESS != wlan_hdd_cancel_remain_on_channel(pHddCtx))
13069 {
13070 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
13071 "%s: abort ROC failed ", __func__);
13072 return -EBUSY;
13073 }
13074
c_hpothu37f21312014-04-09 21:49:54 +053013075 pHddCtx->isPnoEnable = TRUE;
13076
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053013077 pPnoRequest = (tpSirPNOScanReq) vos_mem_malloc(sizeof (tSirPNOScanReq));
13078 if (NULL == pPnoRequest)
13079 {
13080 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
13081 "%s: vos_mem_malloc failed", __func__);
c_hpothu37f21312014-04-09 21:49:54 +053013082 pHddCtx->isPnoEnable = FALSE;
Kamath Vinayakba5313f2013-08-22 15:52:39 +053013083 return -ENOMEM;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053013084 }
13085
Madan Mohan Koyyalamudic3f04352013-09-26 19:21:48 +053013086 memset(pPnoRequest, 0, sizeof (tSirPNOScanReq));
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053013087 pPnoRequest->enable = 1; /*Enable PNO */
13088 pPnoRequest->ucNetworksCount = request->n_match_sets;
13089
13090 if (( !pPnoRequest->ucNetworksCount ) ||
13091 ( pPnoRequest->ucNetworksCount > SIR_PNO_MAX_SUPP_NETWORKS ))
13092 {
13093 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Sushant Kaushik1e406c32014-05-09 15:57:52 +053013094 "%s: Network input is not correct %d Max Network supported is %d",
13095 __func__, pPnoRequest->ucNetworksCount,
13096 SIR_PNO_MAX_SUPP_NETWORKS);
Kamath Vinayakba5313f2013-08-22 15:52:39 +053013097 ret = -EINVAL;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053013098 goto error;
13099 }
13100
13101 if ( SIR_PNO_MAX_NETW_CHANNELS_EX < request->n_channels )
13102 {
13103 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Nirav Shah80830bf2013-12-31 16:35:12 +053013104 "%s: Incorrect number of channels %d",
13105 __func__, request->n_channels);
Kamath Vinayakba5313f2013-08-22 15:52:39 +053013106 ret = -EINVAL;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053013107 goto error;
13108 }
13109
13110 /* Framework provides one set of channels(all)
13111 * common for all saved profile */
13112 if (0 != ccmCfgGetStr(hHal, WNI_CFG_VALID_CHANNEL_LIST,
13113 channels_allowed, &num_channels_allowed))
13114 {
13115 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
13116 "%s: failed to get valid channel list", __func__);
Kamath Vinayakba5313f2013-08-22 15:52:39 +053013117 ret = -EINVAL;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053013118 goto error;
13119 }
13120 /* Checking each channel against allowed channel list */
13121 num_ch = 0;
Nirav Shah80830bf2013-12-31 16:35:12 +053013122 if (request->n_channels)
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053013123 {
Nirav Shah80830bf2013-12-31 16:35:12 +053013124 char chList [(request->n_channels*5)+1];
13125 int len;
13126 for (i = 0, len = 0; i < request->n_channels; i++)
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053013127 {
Nirav Shah80830bf2013-12-31 16:35:12 +053013128 for (indx = 0; indx < num_channels_allowed; indx++)
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053013129 {
Nirav Shah80830bf2013-12-31 16:35:12 +053013130 if (request->channels[i]->hw_value == channels_allowed[indx])
13131 {
13132 valid_ch[num_ch++] = request->channels[i]->hw_value;
13133 len += snprintf(chList+len, 5, "%d ",
13134 request->channels[i]->hw_value);
13135 break ;
13136 }
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053013137 }
13138 }
Nirav Shah80830bf2013-12-31 16:35:12 +053013139 hddLog(VOS_TRACE_LEVEL_INFO,"Channel-List: %s ", chList);
13140 }
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053013141
13142 /* Filling per profile params */
13143 for (i = 0; i < pPnoRequest->ucNetworksCount; i++)
13144 {
13145 pPnoRequest->aNetworks[i].ssId.length =
13146 request->match_sets[i].ssid.ssid_len;
13147
13148 if (( 0 == pPnoRequest->aNetworks[i].ssId.length ) ||
13149 ( pPnoRequest->aNetworks[i].ssId.length > 32 ) )
13150 {
13151 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Nirav Shah80830bf2013-12-31 16:35:12 +053013152 "%s: SSID Len %d is not correct for network %d",
13153 __func__, pPnoRequest->aNetworks[i].ssId.length, i);
Kamath Vinayakba5313f2013-08-22 15:52:39 +053013154 ret = -EINVAL;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053013155 goto error;
13156 }
13157
13158 memcpy(pPnoRequest->aNetworks[i].ssId.ssId,
13159 request->match_sets[i].ssid.ssid,
13160 request->match_sets[i].ssid.ssid_len);
Sushant Kaushik1e406c32014-05-09 15:57:52 +053013161 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
13162 "%s: SSID of network %d is %s ", __func__,
13163 i, pPnoRequest->aNetworks[i].ssId.ssId);
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053013164 pPnoRequest->aNetworks[i].authentication = 0; /*eAUTH_TYPE_ANY*/
13165 pPnoRequest->aNetworks[i].encryption = 0; /*eED_ANY*/
13166 pPnoRequest->aNetworks[i].bcastNetwType = 0; /*eBCAST_UNKNOWN*/
13167
13168 /*Copying list of valid channel into request */
13169 memcpy(pPnoRequest->aNetworks[i].aChannels, valid_ch, num_ch);
13170 pPnoRequest->aNetworks[i].ucChannelCount = num_ch;
13171
13172 pPnoRequest->aNetworks[i].rssiThreshold = 0; //Default value
13173 }
13174
Mahesh A Saptasagar7bd6ad42014-07-21 18:56:33 +053013175 for (i = 0; i < request->n_ssids; i++)
13176 {
13177 j = 0;
13178 while (j < pPnoRequest->ucNetworksCount)
13179 {
13180 if ((pPnoRequest->aNetworks[j].ssId.length ==
13181 request->ssids[i].ssid_len) &&
13182 (0 == memcmp(pPnoRequest->aNetworks[j].ssId.ssId,
13183 request->ssids[i].ssid,
13184 pPnoRequest->aNetworks[j].ssId.length)))
13185 {
13186 pPnoRequest->aNetworks[j].bcastNetwType = eBCAST_HIDDEN;
13187 break;
13188 }
13189 j++;
13190 }
13191 }
13192 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
13193 "Number of hidden networks being Configured = %d",
13194 request->n_ssids);
Madan Mohan Koyyalamudia7765d52013-09-18 16:49:56 +053013195 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Jeff Johnson59a121e2013-11-30 09:46:08 -080013196 "request->ie_len = %zu", request->ie_len);
Madan Mohan Koyyalamudia7765d52013-09-18 16:49:56 +053013197 if ((0 < request->ie_len) && (NULL != request->ie))
13198 {
13199 pPnoRequest->us24GProbeTemplateLen = request->ie_len;
13200 memcpy(&pPnoRequest->p24GProbeTemplate, request->ie,
13201 pPnoRequest->us24GProbeTemplateLen);
13202
13203 pPnoRequest->us5GProbeTemplateLen = request->ie_len;
13204 memcpy(&pPnoRequest->p5GProbeTemplate, request->ie,
13205 pPnoRequest->us5GProbeTemplateLen);
13206 }
13207
Madan Mohan Koyyalamudi1d16f462013-08-27 16:25:34 +053013208 /* Driver gets only one time interval which is hardcoded in
13209 * supplicant for 10000ms. Taking power consumption into account 6 timers
13210 * will be used, Timervalue is increased exponentially i.e 10,20,40,
13211 * 80,160,320 secs. And number of scan cycle for each timer
13212 * is configurable through INI param gPNOScanTimerRepeatValue.
13213 * If it is set to 0 only one timer will be used and PNO scan cycle
13214 * will be repeated after each interval specified by supplicant
13215 * till PNO is disabled.
13216 */
13217 if (0 == pHddCtx->cfg_ini->configPNOScanTimerRepeatValue)
13218 pPnoRequest->scanTimers.ucScanTimersCount = HDD_PNO_SCAN_TIMERS_SET_ONE;
13219 else
13220 pPnoRequest->scanTimers.ucScanTimersCount =
13221 HDD_PNO_SCAN_TIMERS_SET_MULTIPLE;
13222
13223 tempInterval = (request->interval)/1000;
13224 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
13225 "Base scan interval = %d PNOScanTimerRepeatValue = %d",
13226 tempInterval, pHddCtx->cfg_ini->configPNOScanTimerRepeatValue);
13227 for ( i = 0; i < pPnoRequest->scanTimers.ucScanTimersCount; i++)
13228 {
13229 pPnoRequest->scanTimers.aTimerValues[i].uTimerRepeat =
13230 pHddCtx->cfg_ini->configPNOScanTimerRepeatValue;
13231 pPnoRequest->scanTimers.aTimerValues[i].uTimerValue = tempInterval;
13232 tempInterval *= 2;
13233 }
13234 //Repeat last timer until pno disabled.
13235 pPnoRequest->scanTimers.aTimerValues[i-1].uTimerRepeat = 0;
13236
Madan Mohan Koyyalamudid206c7b2013-09-26 22:54:51 +053013237 pPnoRequest->modePNO = SIR_PNO_MODE_IMMEDIATE;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053013238
Vinay Krishna Erannaf0e523b2014-03-01 21:00:16 +053013239 INIT_COMPLETION(pAdapter->pno_comp_var);
13240 pPnoRequest->statusCallback = hdd_cfg80211_sched_scan_start_status_cb;
13241 pPnoRequest->callbackContext = pAdapter;
13242 pAdapter->pno_req_status = 0;
13243
Nirav Shah80830bf2013-12-31 16:35:12 +053013244 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
13245 "SessionId %d, enable %d, modePNO %d, ucScanTimersCount %d",
13246 pAdapter->sessionId, pPnoRequest->enable, pPnoRequest->modePNO,
13247 pPnoRequest->scanTimers.ucScanTimersCount);
13248
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053013249 status = sme_SetPreferredNetworkList(WLAN_HDD_GET_HAL_CTX(pAdapter),
13250 pPnoRequest, pAdapter->sessionId,
13251 hdd_cfg80211_sched_scan_done_callback, pAdapter);
13252 if (eHAL_STATUS_SUCCESS != status)
13253 {
13254 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Nirav Shah80830bf2013-12-31 16:35:12 +053013255 "%s: Failed to enable PNO", __func__);
Kamath Vinayakba5313f2013-08-22 15:52:39 +053013256 ret = -EINVAL;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053013257 goto error;
13258 }
13259
Vinay Krishna Erannaf0e523b2014-03-01 21:00:16 +053013260 ret = wait_for_completion_timeout(
13261 &pAdapter->pno_comp_var,
13262 msecs_to_jiffies(WLAN_WAIT_TIME_PNO));
13263 if (0 >= ret)
13264 {
13265 // Did not receive the response for PNO enable in time.
13266 // Assuming the PNO enable was success.
13267 // Returning error from here, because we timeout, results
13268 // in side effect of Wifi (Wifi Setting) not to work.
13269 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
13270 FL("Timed out waiting for PNO to be Enabled"));
13271 ret = 0;
13272 goto error;
13273 }
13274
c_hpothu3c986b22014-07-09 14:45:09 +053013275 vos_mem_free(pPnoRequest);
Vinay Krishna Erannaf0e523b2014-03-01 21:00:16 +053013276 ret = pAdapter->pno_req_status;
c_hpothu37f21312014-04-09 21:49:54 +053013277 return ret;
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053013278
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053013279error:
Vinay Krishna Erannaf0e523b2014-03-01 21:00:16 +053013280 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
13281 FL("PNO scanRequest offloaded ret = %d"), ret);
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053013282 vos_mem_free(pPnoRequest);
c_hpothu37f21312014-04-09 21:49:54 +053013283 pHddCtx->isPnoEnable = FALSE;
Kamath Vinayakba5313f2013-08-22 15:52:39 +053013284 return ret;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053013285}
13286
13287/*
Mahesh A Saptasagar6cc38562014-05-23 21:22:17 +053013288 * FUNCTION: wlan_hdd_cfg80211_sched_scan_start
13289 * NL interface to enable PNO
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053013290 */
Mahesh A Saptasagar6cc38562014-05-23 21:22:17 +053013291static int wlan_hdd_cfg80211_sched_scan_start(struct wiphy *wiphy,
13292 struct net_device *dev, struct cfg80211_sched_scan_request *request)
13293{
13294 int ret;
13295
13296 vos_ssr_protect(__func__);
13297 ret = __wlan_hdd_cfg80211_sched_scan_start(wiphy, dev, request);
13298 vos_ssr_unprotect(__func__);
13299
13300 return ret;
13301}
13302
13303/*
13304 * FUNCTION: __wlan_hdd_cfg80211_sched_scan_stop
13305 * Function to disable PNO
13306 */
13307static int __wlan_hdd_cfg80211_sched_scan_stop(struct wiphy *wiphy,
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053013308 struct net_device *dev)
13309{
13310 eHalStatus status = eHAL_STATUS_FAILURE;
13311 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
13312 hdd_context_t *pHddCtx;
13313 tHalHandle hHal;
13314 tpSirPNOScanReq pPnoRequest = NULL;
Kamath Vinayakba5313f2013-08-22 15:52:39 +053013315 int ret = 0;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053013316
13317 ENTER();
13318
13319 if (NULL == pAdapter)
13320 {
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053013321 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053013322 "%s: HDD adapter is Null", __func__);
13323 return -ENODEV;
13324 }
13325
13326 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053013327
Kamath Vinayakba5313f2013-08-22 15:52:39 +053013328 if (NULL == pHddCtx)
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053013329 {
Gopichand Nakkalac005b7c2013-05-14 16:04:14 +053013330 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Kamath Vinayakba5313f2013-08-22 15:52:39 +053013331 "%s: HDD context is Null", __func__);
13332 return -ENODEV;
13333 }
13334
13335 /* The return 0 is intentional when isLogpInProgress and
13336 * isLoadUnloadInProgress. We did observe a crash due to a return of
13337 * failure in sched_scan_stop , especially for a case where the unload
13338 * of the happens at the same time. The function __cfg80211_stop_sched_scan
13339 * was clearing rdev->sched_scan_req only when the sched_scan_stop returns
13340 * success. If it returns a failure , then its next invocation due to the
13341 * clean up of the second interface will have the dev pointer corresponding
13342 * to the first one leading to a crash.
13343 */
13344 if (pHddCtx->isLogpInProgress)
13345 {
13346 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
13347 "%s: LOGP in Progress. Ignore!!!", __func__);
13348 return ret;
13349 }
13350
Mihir Shete18156292014-03-11 15:38:30 +053013351 if (WLAN_HDD_IS_LOAD_UNLOAD_IN_PROGRESS(pHddCtx))
Kamath Vinayakba5313f2013-08-22 15:52:39 +053013352 {
13353 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
13354 "%s: Unloading/Loading in Progress. Ignore!!!", __func__);
13355 return ret;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053013356 }
13357
13358 hHal = WLAN_HDD_GET_HAL_CTX(pAdapter);
13359 if (NULL == hHal)
13360 {
13361 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
13362 "%s: HAL context is Null!!!", __func__);
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053013363 return -EINVAL;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053013364 }
13365
13366 pPnoRequest = (tpSirPNOScanReq) vos_mem_malloc(sizeof (tSirPNOScanReq));
13367 if (NULL == pPnoRequest)
13368 {
13369 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
13370 "%s: vos_mem_malloc failed", __func__);
Kamath Vinayakba5313f2013-08-22 15:52:39 +053013371 return -ENOMEM;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053013372 }
13373
13374 memset(pPnoRequest, 0, sizeof (tSirPNOScanReq));
13375 pPnoRequest->enable = 0; /* Disable PNO */
13376 pPnoRequest->ucNetworksCount = 0;
13377
13378 status = sme_SetPreferredNetworkList(hHal, pPnoRequest,
13379 pAdapter->sessionId,
13380 NULL, pAdapter);
13381 if (eHAL_STATUS_SUCCESS != status)
13382 {
13383 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
13384 "Failed to disabled PNO");
Kamath Vinayakba5313f2013-08-22 15:52:39 +053013385 ret = -EINVAL;
Vinay Krishna Erannaf0e523b2014-03-01 21:00:16 +053013386 goto error;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053013387 }
c_hpothu37f21312014-04-09 21:49:54 +053013388 pHddCtx->isPnoEnable = FALSE;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053013389
Vinay Krishna Erannaf0e523b2014-03-01 21:00:16 +053013390error:
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053013391 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Vinay Krishna Erannaf0e523b2014-03-01 21:00:16 +053013392 FL("PNO scan disabled ret = %d"), ret);
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053013393 vos_mem_free(pPnoRequest);
13394
13395 EXIT();
Kamath Vinayakba5313f2013-08-22 15:52:39 +053013396 return ret;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053013397}
13398
Mahesh A Saptasagar6cc38562014-05-23 21:22:17 +053013399/*
13400 * FUNCTION: wlan_hdd_cfg80211_sched_scan_stop
13401 * NL interface to disable PNO
13402 */
13403static int wlan_hdd_cfg80211_sched_scan_stop(struct wiphy *wiphy,
13404 struct net_device *dev)
13405{
13406 int ret;
13407
13408 vos_ssr_protect(__func__);
13409 ret = __wlan_hdd_cfg80211_sched_scan_stop(wiphy, dev);
13410 vos_ssr_unprotect(__func__);
13411
13412 return ret;
13413}
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053013414#endif /*FEATURE_WLAN_SCAN_PNO*/
13415
13416
Mohit Khanna698ba2a2012-12-04 15:08:18 -080013417#ifdef FEATURE_WLAN_TDLS
Sunil Dutt Undekarieacac6f2014-03-21 14:08:53 +053013418#if TDLS_MGMT_VERSION2
Mohit Khanna698ba2a2012-12-04 15:08:18 -080013419static int wlan_hdd_cfg80211_tdls_mgmt(struct wiphy *wiphy, struct net_device *dev,
13420 u8 *peer, u8 action_code, u8 dialog_token,
Sunil Dutt Undekarieacac6f2014-03-21 14:08:53 +053013421 u16 status_code, u32 peer_capability, const u8 *buf, size_t len)
13422#else
13423static int wlan_hdd_cfg80211_tdls_mgmt(struct wiphy *wiphy, struct net_device *dev,
13424 u8 *peer, u8 action_code, u8 dialog_token,
13425 u16 status_code, const u8 *buf, size_t len)
13426#endif
Mohit Khanna698ba2a2012-12-04 15:08:18 -080013427{
13428
13429 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
13430 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
Mohit Khanna698ba2a2012-12-04 15:08:18 -080013431 u8 peerMac[6];
13432 VOS_STATUS status;
Gopichand Nakkala05922802013-03-14 12:23:19 -070013433 int max_sta_failed = 0;
Hoonki Leea34dd892013-02-05 22:56:02 -080013434 int responder;
Hoonki Leed37cbb32013-04-20 00:31:14 -070013435 long rc;
Sunil Dutt Undekarieacac6f2014-03-21 14:08:53 +053013436#if !(TDLS_MGMT_VERSION2)
13437 u32 peer_capability = 0;
13438#endif
Rajesh Chauhana34c6e62014-03-25 16:37:58 +053013439 tANI_U16 numCurrTdlsPeers;
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053013440
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053013441 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
13442 TRACE_CODE_HDD_CFG80211_TDLS_MGMT,
13443 pAdapter->sessionId, action_code));
Hoonki Lee11f7dda2013-02-14 16:55:44 -080013444 if (NULL == pHddCtx || NULL == pHddCtx->cfg_ini)
Mohit Khanna698ba2a2012-12-04 15:08:18 -080013445 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013446 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Mohit Khanna698ba2a2012-12-04 15:08:18 -080013447 "Invalid arguments");
13448 return -EINVAL;
13449 }
13450
Sameer Thalappil75ea31a2013-02-21 19:38:16 -080013451 if (pHddCtx->isLogpInProgress)
13452 {
13453 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
13454 "%s:LOGP in Progress. Ignore!!!", __func__);
Atul Mittal115287b2014-07-08 13:26:33 +053013455 wlan_hdd_tdls_set_link_status(pAdapter,
13456 peer,
13457 eTDLS_LINK_IDLE,
13458 eTDLS_LINK_UNSPECIFIED);
Sameer Thalappil75ea31a2013-02-21 19:38:16 -080013459 return -EBUSY;
13460 }
13461
Hoonki Lee27511902013-03-14 18:19:06 -070013462 if (eTDLS_SUPPORT_NOT_ENABLED == pHddCtx->tdls_mode)
Mohit Khanna698ba2a2012-12-04 15:08:18 -080013463 {
Hoonki Lee27511902013-03-14 18:19:06 -070013464 VOS_TRACE( VOS_MODULE_ID_HDD, TDLS_LOG_LEVEL,
13465 "%s: TDLS mode is disabled OR not enabled in FW."
13466 MAC_ADDRESS_STR " action %d declined.",
13467 __func__, MAC_ADDR_ARRAY(peer), action_code);
Mohit Khanna698ba2a2012-12-04 15:08:18 -080013468 return -ENOTSUPP;
13469 }
Lee Hoonkic1262f22013-01-24 21:59:00 -080013470
Hoonki Lee27511902013-03-14 18:19:06 -070013471 /* other than teardown frame, other mgmt frames are not sent if disabled */
13472 if (SIR_MAC_TDLS_TEARDOWN != action_code)
13473 {
13474 /* if tdls_mode is disabled to respond to peer's request */
13475 if (eTDLS_SUPPORT_DISABLED == pHddCtx->tdls_mode)
13476 {
13477 VOS_TRACE( VOS_MODULE_ID_HDD, TDLS_LOG_LEVEL,
13478 "%s: " MAC_ADDRESS_STR
Gopichand Nakkala34d1b062013-03-19 15:28:33 -070013479 " TDLS mode is disabled. action %d declined.",
13480 __func__, MAC_ADDR_ARRAY(peer), action_code);
Hoonki Lee27511902013-03-14 18:19:06 -070013481
13482 return -ENOTSUPP;
13483 }
Agarwal Ashish4b87f922014-06-18 03:03:21 +053013484
13485 if (vos_max_concurrent_connections_reached())
13486 {
13487 hddLog(VOS_TRACE_LEVEL_INFO, FL("Reached max concurrent connections"));
13488 return -EINVAL;
13489 }
Hoonki Lee27511902013-03-14 18:19:06 -070013490 }
13491
Gopichand Nakkalab977a972013-02-18 19:15:09 -080013492 if (WLAN_IS_TDLS_SETUP_ACTION(action_code))
13493 {
Madan Mohan Koyyalamudi96797442013-10-08 16:04:42 +053013494 if (NULL != wlan_hdd_tdls_is_progress(pHddCtx, peer, TRUE))
Gopichand Nakkalab977a972013-02-18 19:15:09 -080013495 {
13496 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Gopichand Nakkalac87400e2013-03-13 18:51:00 -070013497 "%s: " MAC_ADDRESS_STR
Gopichand Nakkala34d1b062013-03-19 15:28:33 -070013498 " TDLS setup is ongoing. action %d declined.",
13499 __func__, MAC_ADDR_ARRAY(peer), action_code);
13500 return -EPERM;
Gopichand Nakkalab977a972013-02-18 19:15:09 -080013501 }
13502 }
13503
Hoonki Lee11f7dda2013-02-14 16:55:44 -080013504 if (SIR_MAC_TDLS_SETUP_REQ == action_code ||
13505 SIR_MAC_TDLS_SETUP_RSP == action_code )
Lee Hoonkic1262f22013-01-24 21:59:00 -080013506 {
Rajesh Chauhana34c6e62014-03-25 16:37:58 +053013507 numCurrTdlsPeers = wlan_hdd_tdlsConnectedPeers(pAdapter);
13508 if (HDD_MAX_NUM_TDLS_STA <= numCurrTdlsPeers)
Lee Hoonkic1262f22013-01-24 21:59:00 -080013509 {
13510 /* supplicant still sends tdls_mgmt(SETUP_REQ) even after
13511 we return error code at 'add_station()'. Hence we have this
13512 check again in addtion to add_station().
13513 Anyway, there is no hard to double-check. */
Hoonki Lee11f7dda2013-02-14 16:55:44 -080013514 if (SIR_MAC_TDLS_SETUP_REQ == action_code)
Lee Hoonkic1262f22013-01-24 21:59:00 -080013515 {
Gopichand Nakkalac87400e2013-03-13 18:51:00 -070013516 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
13517 "%s: " MAC_ADDRESS_STR
Rajesh Chauhana34c6e62014-03-25 16:37:58 +053013518 " TDLS Max peer already connected. action (%d) declined. Num of peers (%d), Max allowed (%d).",
13519 __func__, MAC_ADDR_ARRAY(peer), action_code,
13520 numCurrTdlsPeers, HDD_MAX_NUM_TDLS_STA);
Sunil Dutt388ac8f2013-11-28 18:06:52 +053013521 return -EINVAL;
Lee Hoonkic1262f22013-01-24 21:59:00 -080013522 }
13523 else
13524 {
Gopichand Nakkalab977a972013-02-18 19:15:09 -080013525 /* maximum reached. tweak to send error code to peer and return
13526 error code to supplicant */
Lee Hoonkic1262f22013-01-24 21:59:00 -080013527 status_code = eSIR_MAC_UNSPEC_FAILURE_STATUS;
Gopichand Nakkalac87400e2013-03-13 18:51:00 -070013528 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
13529 "%s: " MAC_ADDRESS_STR
Rajesh Chauhana34c6e62014-03-25 16:37:58 +053013530 " TDLS Max peer already connected, send response status (%d). Num of peers (%d), Max allowed (%d).",
13531 __func__, MAC_ADDR_ARRAY(peer), status_code,
13532 numCurrTdlsPeers, HDD_MAX_NUM_TDLS_STA);
Gopichand Nakkala05922802013-03-14 12:23:19 -070013533 max_sta_failed = -EPERM;
Gopichand Nakkalab977a972013-02-18 19:15:09 -080013534 /* fall through to send setup resp with failure status
13535 code */
Lee Hoonkic1262f22013-01-24 21:59:00 -080013536 }
13537 }
Hoonki Lee11f7dda2013-02-14 16:55:44 -080013538 else
13539 {
13540 hddTdlsPeer_t *pTdlsPeer;
Madan Mohan Koyyalamudi96797442013-10-08 16:04:42 +053013541 pTdlsPeer = wlan_hdd_tdls_find_peer(pAdapter, peer, TRUE);
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -070013542 if (pTdlsPeer && TDLS_IS_CONNECTED(pTdlsPeer))
Hoonki Lee11f7dda2013-02-14 16:55:44 -080013543 {
Gopichand Nakkalac87400e2013-03-13 18:51:00 -070013544 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Gopichand Nakkala34d1b062013-03-19 15:28:33 -070013545 "%s:" MAC_ADDRESS_STR " already connected. action %d declined.",
13546 __func__, MAC_ADDR_ARRAY(peer), action_code);
Hoonki Lee11f7dda2013-02-14 16:55:44 -080013547 return -EPERM;
13548 }
13549 }
Lee Hoonkic1262f22013-01-24 21:59:00 -080013550 }
Hoonki Lee11f7dda2013-02-14 16:55:44 -080013551 vos_mem_copy(peerMac, peer, 6);
Mohit Khanna698ba2a2012-12-04 15:08:18 -080013552
Hoonki Lee1090c6a2013-01-16 17:40:54 -080013553#ifdef WLAN_FEATURE_TDLS_DEBUG
13554 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Arun Kumar Khandavalli9fb625e2014-03-17 16:07:40 +053013555 "%s: " MAC_ADDRESS_STR " action %d, dialog_token %d status %d, len = %zu",
Gopichand Nakkalac87400e2013-03-13 18:51:00 -070013556 "tdls_mgmt", MAC_ADDR_ARRAY(peer),
13557 action_code, dialog_token, status_code, len);
Hoonki Lee1090c6a2013-01-16 17:40:54 -080013558#endif
Mohit Khanna698ba2a2012-12-04 15:08:18 -080013559
Hoonki Leea34dd892013-02-05 22:56:02 -080013560 /*Except teardown responder will not be used so just make 0*/
13561 responder = 0;
Hoonki Lee11f7dda2013-02-14 16:55:44 -080013562 if (SIR_MAC_TDLS_TEARDOWN == action_code)
Hoonki Leea34dd892013-02-05 22:56:02 -080013563 {
Gopichand Nakkala97a65fd2013-04-16 16:59:38 -070013564
13565 hddTdlsPeer_t *pTdlsPeer;
Madan Mohan Koyyalamudi96797442013-10-08 16:04:42 +053013566 pTdlsPeer = wlan_hdd_tdls_find_peer(pAdapter, peerMac, TRUE);
Gopichand Nakkala97a65fd2013-04-16 16:59:38 -070013567
13568 if(pTdlsPeer && TDLS_IS_CONNECTED(pTdlsPeer))
13569 responder = pTdlsPeer->is_responder;
13570 else
Hoonki Leea34dd892013-02-05 22:56:02 -080013571 {
Gopichand Nakkala97a65fd2013-04-16 16:59:38 -070013572 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Arun Kumar Khandavalli9fb625e2014-03-17 16:07:40 +053013573 "%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 -070013574 __func__, MAC_ADDR_ARRAY(peer), (NULL == pTdlsPeer) ? -1 : pTdlsPeer->link_status,
13575 dialog_token, status_code, len);
13576 return -EPERM;
Hoonki Leea34dd892013-02-05 22:56:02 -080013577 }
Mohit Khanna698ba2a2012-12-04 15:08:18 -080013578 }
Mohit Khanna698ba2a2012-12-04 15:08:18 -080013579
Gopichand Nakkala2f1ff152013-07-01 11:27:43 +053013580 /* For explicit trigger of DIS_REQ come out of BMPS for
13581 successfully receiving DIS_RSP from peer. */
Hoonki Lee14621352013-04-16 17:51:19 -070013582 if ((SIR_MAC_TDLS_SETUP_RSP == action_code) ||
Gopichand Nakkala2f1ff152013-07-01 11:27:43 +053013583 (SIR_MAC_TDLS_DIS_RSP == action_code) ||
13584 (SIR_MAC_TDLS_DIS_REQ == action_code))
Hoonki Lee14621352013-04-16 17:51:19 -070013585 {
13586 if (TRUE == sme_IsPmcBmps(WLAN_HDD_GET_HAL_CTX(pAdapter)))
13587 {
13588 VOS_TRACE( VOS_MODULE_ID_HDD, TDLS_LOG_LEVEL,
Gopichand Nakkala2f1ff152013-07-01 11:27:43 +053013589 "%s: Sending frame action_code %u.Disable BMPS", __func__, action_code);
Hoonki Lee14621352013-04-16 17:51:19 -070013590 hdd_disable_bmps_imps(pHddCtx, WLAN_HDD_INFRA_STATION);
13591 }
Gopichand Nakkala2f1ff152013-07-01 11:27:43 +053013592 if (SIR_MAC_TDLS_DIS_REQ != action_code)
13593 wlan_hdd_tdls_set_cap(pAdapter, peerMac, eTDLS_CAP_SUPPORTED);
Hoonki Lee14621352013-04-16 17:51:19 -070013594 }
13595
Hoonki Lee5305c3a2013-04-29 23:28:59 -070013596 /* make sure doesn't call send_mgmt() while it is pending */
13597 if (TDLS_CTX_MAGIC == pAdapter->mgmtTxCompletionStatus)
13598 {
13599 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Arif Hussain6d2a3322013-11-17 19:50:10 -080013600 "%s: " MAC_ADDRESS_STR " action %d couldn't sent, as one is pending. return EBUSY",
Hoonki Lee5305c3a2013-04-29 23:28:59 -070013601 __func__, MAC_ADDR_ARRAY(peer), action_code);
13602 return -EBUSY;
13603 }
13604
13605 pAdapter->mgmtTxCompletionStatus = TDLS_CTX_MAGIC;
Gopichand Nakkalab977a972013-02-18 19:15:09 -080013606 INIT_COMPLETION(pAdapter->tdls_mgmt_comp);
13607
Mohit Khanna698ba2a2012-12-04 15:08:18 -080013608 status = sme_SendTdlsMgmtFrame(WLAN_HDD_GET_HAL_CTX(pAdapter), pAdapter->sessionId,
Pradeep Reddy POTTETIca171f82014-03-21 14:17:35 +053013609 peerMac, action_code, dialog_token, status_code, peer_capability, (tANI_U8 *)buf, len, responder);
Mohit Khanna698ba2a2012-12-04 15:08:18 -080013610
Gopichand Nakkalab977a972013-02-18 19:15:09 -080013611 if (VOS_STATUS_SUCCESS != status)
13612 {
Mohit Khanna698ba2a2012-12-04 15:08:18 -080013613 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
13614 "%s: sme_SendTdlsMgmtFrame failed!", __func__);
Hoonki Lee5305c3a2013-04-29 23:28:59 -070013615 pAdapter->mgmtTxCompletionStatus = FALSE;
Hoonki Lee14621352013-04-16 17:51:19 -070013616 wlan_hdd_tdls_check_bmps(pAdapter);
Sunil Dutt388ac8f2013-11-28 18:06:52 +053013617 return -EINVAL;
Mohit Khanna698ba2a2012-12-04 15:08:18 -080013618 }
13619
Hoonki Leed37cbb32013-04-20 00:31:14 -070013620 rc = wait_for_completion_interruptible_timeout(&pAdapter->tdls_mgmt_comp,
13621 msecs_to_jiffies(WAIT_TIME_TDLS_MGMT));
13622
13623 if ((rc <= 0) || (TRUE != pAdapter->mgmtTxCompletionStatus))
Gopichand Nakkalab977a972013-02-18 19:15:09 -080013624 {
Hoonki Leed37cbb32013-04-20 00:31:14 -070013625 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Jeff Johnson0299d0a2013-10-30 12:37:43 -070013626 "%s: Mgmt Tx Completion failed status %ld TxCompletion %u",
Hoonki Leed37cbb32013-04-20 00:31:14 -070013627 __func__, rc, pAdapter->mgmtTxCompletionStatus);
Hoonki Lee5305c3a2013-04-29 23:28:59 -070013628 pAdapter->mgmtTxCompletionStatus = FALSE;
Yue Ma4f55ef32014-01-23 16:45:33 -080013629
13630 if (pHddCtx->isLogpInProgress)
13631 {
13632 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
13633 "%s: LOGP in Progress. Ignore!!!", __func__);
13634 return -EAGAIN;
13635 }
13636
Hoonki Leed37cbb32013-04-20 00:31:14 -070013637 wlan_hdd_tdls_check_bmps(pAdapter);
Sunil Dutt388ac8f2013-11-28 18:06:52 +053013638 return -EINVAL;
Gopichand Nakkalab977a972013-02-18 19:15:09 -080013639 }
13640
Gopichand Nakkala05922802013-03-14 12:23:19 -070013641 if (max_sta_failed)
Hoonki Lee14621352013-04-16 17:51:19 -070013642 {
13643 wlan_hdd_tdls_check_bmps(pAdapter);
Gopichand Nakkala05922802013-03-14 12:23:19 -070013644 return max_sta_failed;
Hoonki Lee14621352013-04-16 17:51:19 -070013645 }
Gopichand Nakkalab977a972013-02-18 19:15:09 -080013646
Hoonki Leea34dd892013-02-05 22:56:02 -080013647 if (SIR_MAC_TDLS_SETUP_RSP == action_code)
13648 {
Gopichand Nakkala4327a152013-03-04 23:22:42 -080013649 wlan_hdd_tdls_set_responder(pAdapter, peerMac, TRUE);
Hoonki Leea34dd892013-02-05 22:56:02 -080013650 }
13651 else if (SIR_MAC_TDLS_SETUP_CNF == action_code)
13652 {
Gopichand Nakkala4327a152013-03-04 23:22:42 -080013653 wlan_hdd_tdls_set_responder(pAdapter, peerMac, FALSE);
Hoonki Leea34dd892013-02-05 22:56:02 -080013654 }
Mohit Khanna698ba2a2012-12-04 15:08:18 -080013655
13656 return 0;
13657}
13658
Atul Mittal115287b2014-07-08 13:26:33 +053013659
13660int wlan_hdd_tdls_extctrl_config_peer(hdd_adapter_t *pAdapter,
13661 u8 *peer,
13662 cfg80211_exttdls_callback callback)
13663{
13664
13665 hddTdlsPeer_t *pTdlsPeer;
13666 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
13667 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
13668 " %s : NL80211_TDLS_SETUP for " MAC_ADDRESS_STR,
13669 __func__, MAC_ADDR_ARRAY(peer));
13670
13671 if ( (FALSE == pHddCtx->cfg_ini->fTDLSExternalControl) ||
13672 (FALSE == pHddCtx->cfg_ini->fEnableTDLSImplicitTrigger) ) {
13673
13674 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
13675 " %s TDLS External control and Implicit Trigger not enabled ",
13676 __func__);
13677 return -ENOTSUPP;
13678 }
13679
13680 /* To cater the requirement of establishing the TDLS link
13681 * irrespective of the data traffic , get an entry of TDLS peer.
13682 */
13683 pTdlsPeer = wlan_hdd_tdls_get_peer(pAdapter, peer);
13684 if (pTdlsPeer == NULL) {
13685 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
13686 "%s: peer " MAC_ADDRESS_STR " not existing",
13687 __func__, MAC_ADDR_ARRAY(peer));
13688 return -EINVAL;
13689 }
13690
13691 if ( 0 != wlan_hdd_tdls_set_force_peer(pAdapter, peer, TRUE) ) {
13692
13693 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
13694 " %s TDLS Add Force Peer Failed",
13695 __func__);
13696 return -EINVAL;
13697 }
13698 /*EXT TDLS*/
13699
13700 if ( 0 != wlan_hdd_set_callback(pTdlsPeer, callback) ) {
13701 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
13702 " %s TDLS set callback Failed",
13703 __func__);
13704 return -EINVAL;
13705 }
13706
13707 return(0);
13708
13709}
13710
13711int wlan_hdd_tdls_extctrl_deconfig_peer(hdd_adapter_t *pAdapter, u8 *peer)
13712{
13713
13714 hddTdlsPeer_t *pTdlsPeer;
13715 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
13716 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
13717 " %s : NL80211_TDLS_TEARDOWN for " MAC_ADDRESS_STR,
13718 __func__, MAC_ADDR_ARRAY(peer));
13719
13720 if ( (FALSE == pHddCtx->cfg_ini->fTDLSExternalControl) ||
13721 (FALSE == pHddCtx->cfg_ini->fEnableTDLSImplicitTrigger) ) {
13722
13723 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
13724 " %s TDLS External control and Implicit Trigger not enabled ",
13725 __func__);
13726 return -ENOTSUPP;
13727 }
13728
13729
13730 pTdlsPeer = wlan_hdd_tdls_find_peer(pAdapter, peer, TRUE);
13731
13732 if ( NULL == pTdlsPeer ) {
13733 hddLog(VOS_TRACE_LEVEL_INFO, "%s: " MAC_ADDRESS_STR
13734 " peer not exsting",
13735 __func__, MAC_ADDR_ARRAY(peer));
13736 return -EINVAL;
13737 }
13738 else {
13739 wlan_hdd_tdls_indicate_teardown(pAdapter, pTdlsPeer,
13740 eSIR_MAC_TDLS_TEARDOWN_UNSPEC_REASON);
13741 }
13742
13743 if ( 0 != wlan_hdd_tdls_set_force_peer(pAdapter, peer, FALSE) )
13744 return -EINVAL;
13745
13746 /*EXT TDLS*/
13747
13748 if ( 0 != wlan_hdd_set_callback(pTdlsPeer, NULL )) {
13749
13750 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
13751 " %s TDLS set callback Failed",
13752 __func__);
13753 return -EINVAL;
13754 }
13755 return(0);
13756
13757}
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053013758static int __wlan_hdd_cfg80211_tdls_oper(struct wiphy *wiphy, struct net_device *dev,
Mohit Khanna698ba2a2012-12-04 15:08:18 -080013759 u8 *peer, enum nl80211_tdls_operation oper)
13760{
13761 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
13762 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053013763 int status;
Hoonki Lee5305c3a2013-04-29 23:28:59 -070013764 hddTdlsPeer_t *pTdlsPeer;
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053013765
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053013766 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
13767 TRACE_CODE_HDD_CFG80211_TDLS_OPER,
13768 pAdapter->sessionId, oper));
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053013769 if ( NULL == peer )
Mohit Khanna698ba2a2012-12-04 15:08:18 -080013770 {
Gopichand Nakkalab977a972013-02-18 19:15:09 -080013771 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Chilam Ngc4244af2013-04-01 15:37:32 -070013772 "%s: Invalid arguments", __func__);
Mohit Khanna698ba2a2012-12-04 15:08:18 -080013773 return -EINVAL;
13774 }
Hoonki Lee1090c6a2013-01-16 17:40:54 -080013775
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053013776 status = wlan_hdd_validate_context(pHddCtx);
13777
13778 if (0 != status)
Sameer Thalappil75ea31a2013-02-21 19:38:16 -080013779 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053013780 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
13781 "%s: HDD context is not valid", __func__);
13782 return status;
Sameer Thalappil75ea31a2013-02-21 19:38:16 -080013783 }
13784
Mohit Khanna698ba2a2012-12-04 15:08:18 -080013785
13786 if( FALSE == pHddCtx->cfg_ini->fEnableTDLSSupport ||
Hoonki Lee1090c6a2013-01-16 17:40:54 -080013787 FALSE == sme_IsFeatureSupportedByFW(TDLS))
Mohit Khanna698ba2a2012-12-04 15:08:18 -080013788 {
Hoonki Lee1090c6a2013-01-16 17:40:54 -080013789 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Chilam Ngc4244af2013-04-01 15:37:32 -070013790 "TDLS Disabled in INI OR not enabled in FW. "
13791 "Cannot process TDLS commands");
Mohit Khanna698ba2a2012-12-04 15:08:18 -080013792 return -ENOTSUPP;
13793 }
13794
13795 switch (oper) {
13796 case NL80211_TDLS_ENABLE_LINK:
13797 {
Mohit Khanna698ba2a2012-12-04 15:08:18 -080013798 VOS_STATUS status;
c_hpothu6ff1c3c2013-10-01 19:01:57 +053013799 long ret;
Gopichand Nakkala79ff85d2013-05-27 17:05:29 +053013800 tCsrTdlsLinkEstablishParams tdlsLinkEstablishParams;
Mohit Khanna698ba2a2012-12-04 15:08:18 -080013801
Sunil Dutt41de4e22013-11-14 18:09:02 +053013802 pTdlsPeer = wlan_hdd_tdls_find_peer(pAdapter, peer, TRUE);
13803
13804 if ( NULL == pTdlsPeer ) {
13805 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: " MAC_ADDRESS_STR
13806 " (oper %d) not exsting. ignored",
13807 __func__, MAC_ADDR_ARRAY(peer), (int)oper);
13808 return -EINVAL;
13809 }
13810
13811 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
13812 "%s: " MAC_ADDRESS_STR " link_status %d (%s) ", "tdls_oper",
13813 MAC_ADDR_ARRAY(peer), pTdlsPeer->link_status,
13814 "NL80211_TDLS_ENABLE_LINK");
13815
Gopichand Nakkala2f4a2822013-04-17 11:22:01 -070013816 if (!TDLS_STA_INDEX_VALID(pTdlsPeer->staId))
13817 {
13818 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Invalid Staion Index %u "
13819 MAC_ADDRESS_STR " failed",
13820 __func__, pTdlsPeer->staId, MAC_ADDR_ARRAY(peer));
13821 return -EINVAL;
13822 }
13823
Hoonki Lee5305c3a2013-04-29 23:28:59 -070013824 if (eTDLS_LINK_CONNECTED != pTdlsPeer->link_status)
Gopichand Nakkalac87400e2013-03-13 18:51:00 -070013825 {
Madan Mohan Koyyalamudice419872013-09-13 19:36:52 +053013826 if (IS_ADVANCE_TDLS_ENABLE) {
Gopichand Nakkala24be5312013-07-02 16:47:12 +053013827
Madan Mohan Koyyalamudice419872013-09-13 19:36:52 +053013828 if (0 != wlan_hdd_tdls_get_link_establish_params(
13829 pAdapter, peer,&tdlsLinkEstablishParams)) {
13830 return -EINVAL;
13831 }
13832 INIT_COMPLETION(pAdapter->tdls_link_establish_req_comp);
Gopichand Nakkala79ff85d2013-05-27 17:05:29 +053013833
Madan Mohan Koyyalamudice419872013-09-13 19:36:52 +053013834 sme_SendTdlsLinkEstablishParams(WLAN_HDD_GET_HAL_CTX(pAdapter),
13835 pAdapter->sessionId, peer, &tdlsLinkEstablishParams);
13836 /* Send TDLS peer UAPSD capabilities to the firmware and
13837 * register with the TL on after the response for this operation
13838 * is received .
13839 */
13840 ret = wait_for_completion_interruptible_timeout(
13841 &pAdapter->tdls_link_establish_req_comp,
13842 msecs_to_jiffies(WAIT_TIME_TDLS_LINK_ESTABLISH_REQ));
13843 if (ret <= 0)
13844 {
13845 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
13846 "%s: Link Establish Request Faled Status %ld",
13847 __func__, ret);
13848 return -EINVAL;
13849 }
Gopichand Nakkala79ff85d2013-05-27 17:05:29 +053013850 }
Atul Mittal115287b2014-07-08 13:26:33 +053013851 wlan_hdd_tdls_set_peer_link_status(pTdlsPeer,
13852 eTDLS_LINK_CONNECTED,
13853 eTDLS_LINK_SUCCESS);
Gopichand Nakkala471708b2013-06-04 20:03:01 +053013854 /* Mark TDLS client Authenticated .*/
13855 status = WLANTL_ChangeSTAState( pHddCtx->pvosContext,
13856 pTdlsPeer->staId,
13857 WLANTL_STA_AUTHENTICATED);
Gopichand Nakkalaccd3a382013-03-19 13:56:10 -070013858 if (VOS_STATUS_SUCCESS == status)
13859 {
Hoonki Lee14621352013-04-16 17:51:19 -070013860 if (pTdlsPeer->is_responder == 0)
13861 {
13862 v_U8_t staId = (v_U8_t)pTdlsPeer->staId;
13863
13864 wlan_hdd_tdls_timer_restart(pAdapter,
13865 &pTdlsPeer->initiatorWaitTimeoutTimer,
13866 WAIT_TIME_TDLS_INITIATOR);
13867 /* suspend initiator TX until it receives direct packet from the
13868 reponder or WAIT_TIME_TDLS_INITIATOR timer expires */
13869 WLANTL_SuspendDataTx( (WLAN_HDD_GET_CTX(pAdapter))->pvosContext,
13870 &staId, NULL);
13871 }
Gopichand Nakkalaccd3a382013-03-19 13:56:10 -070013872 wlan_hdd_tdls_increment_peer_count(pAdapter);
13873 }
Gopichand Nakkalac87400e2013-03-13 18:51:00 -070013874 wlan_hdd_tdls_check_bmps(pAdapter);
Gopichand Nakkala79ff85d2013-05-27 17:05:29 +053013875
13876 /* Update TL about the UAPSD masks , to route the packets to firmware */
Gopichand Nakkala574f6d12013-06-27 19:38:43 +053013877 if ((TRUE == pHddCtx->cfg_ini->fEnableTDLSBufferSta)
13878 || pHddCtx->cfg_ini->fTDLSUapsdMask )
Gopichand Nakkala79ff85d2013-05-27 17:05:29 +053013879 {
Gopichand Nakkala574f6d12013-06-27 19:38:43 +053013880 int ac;
13881 uint8 ucAc[4] = { WLANTL_AC_VO,
13882 WLANTL_AC_VI,
13883 WLANTL_AC_BK,
13884 WLANTL_AC_BE };
13885 uint8 tlTid[4] = { 7, 5, 2, 3 } ;
13886 for(ac=0; ac < 4; ac++)
13887 {
13888 status = WLANTL_EnableUAPSDForAC( (WLAN_HDD_GET_CTX(pAdapter))->pvosContext,
13889 pTdlsPeer->staId, ucAc[ac],
13890 tlTid[ac], tlTid[ac], 0, 0,
13891 WLANTL_BI_DIR );
13892 }
Gopichand Nakkala79ff85d2013-05-27 17:05:29 +053013893 }
Gopichand Nakkalac87400e2013-03-13 18:51:00 -070013894 }
13895
Mohit Khanna698ba2a2012-12-04 15:08:18 -080013896 }
13897 break;
13898 case NL80211_TDLS_DISABLE_LINK:
Lee Hoonkic1262f22013-01-24 21:59:00 -080013899 {
Sunil Dutt41de4e22013-11-14 18:09:02 +053013900 pTdlsPeer = wlan_hdd_tdls_find_peer(pAdapter, peer, TRUE);
13901
13902 if ( NULL == pTdlsPeer ) {
13903 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: " MAC_ADDRESS_STR
13904 " (oper %d) not exsting. ignored",
13905 __func__, MAC_ADDR_ARRAY(peer), (int)oper);
13906 return -EINVAL;
13907 }
13908
13909 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
13910 "%s: " MAC_ADDRESS_STR " link_status %d (%s) ", "tdls_oper",
13911 MAC_ADDR_ARRAY(peer), pTdlsPeer->link_status,
13912 "NL80211_TDLS_DISABLE_LINK");
13913
Hoonki Lee5305c3a2013-04-29 23:28:59 -070013914 if(TDLS_STA_INDEX_VALID(pTdlsPeer->staId))
Lee Hoonkic1262f22013-01-24 21:59:00 -080013915 {
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -070013916 long status;
13917
Atul Mittal271a7652014-09-12 13:18:22 +053013918
13919 wlan_hdd_tdls_set_peer_link_status(pTdlsPeer,
13920 eTDLS_LINK_TEARING,
13921 (pTdlsPeer->link_status == eTDLS_LINK_TEARING)?
13922 eTDLS_LINK_UNSPECIFIED:
13923 eTDLS_LINK_DROPPED_BY_REMOTE);
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -070013924 INIT_COMPLETION(pAdapter->tdls_del_station_comp);
13925
Lee Hoonkic1262f22013-01-24 21:59:00 -080013926 sme_DeleteTdlsPeerSta( WLAN_HDD_GET_HAL_CTX(pAdapter),
13927 pAdapter->sessionId, peer );
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -070013928
13929 status = wait_for_completion_interruptible_timeout(&pAdapter->tdls_del_station_comp,
13930 msecs_to_jiffies(WAIT_TIME_TDLS_DEL_STA));
Atul Mittal271a7652014-09-12 13:18:22 +053013931 wlan_hdd_tdls_set_peer_link_status(pTdlsPeer,
Atul Mittal454664b2014-10-10 11:03:46 +053013932 eTDLS_LINK_IDLE,
13933 eTDLS_LINK_UNSPECIFIED);
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -070013934 if (status <= 0)
13935 {
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -070013936 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
13937 "%s: Del station failed status %ld",
13938 __func__, status);
13939 return -EPERM;
13940 }
Lee Hoonkic1262f22013-01-24 21:59:00 -080013941 }
13942 else
13943 {
Gopichand Nakkalac87400e2013-03-13 18:51:00 -070013944 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
13945 "%s: TDLS Peer Station doesn't exist.", __func__);
Lee Hoonkic1262f22013-01-24 21:59:00 -080013946 }
Lee Hoonkic1262f22013-01-24 21:59:00 -080013947 }
Gopichand Nakkalac87400e2013-03-13 18:51:00 -070013948 break;
Mohit Khanna698ba2a2012-12-04 15:08:18 -080013949 case NL80211_TDLS_TEARDOWN:
Sunil Dutt41de4e22013-11-14 18:09:02 +053013950 {
Atul Mittal115287b2014-07-08 13:26:33 +053013951 status = wlan_hdd_tdls_extctrl_deconfig_peer(pAdapter, peer);
Sunil Dutt41de4e22013-11-14 18:09:02 +053013952
Atul Mittal115287b2014-07-08 13:26:33 +053013953 if (0 != status)
13954 {
13955 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
13956 "%s: Error in TDLS Teardown", __func__);
13957 return status;
Sunil Dutt41de4e22013-11-14 18:09:02 +053013958 }
Sunil Dutt41de4e22013-11-14 18:09:02 +053013959 break;
13960 }
Mohit Khanna698ba2a2012-12-04 15:08:18 -080013961 case NL80211_TDLS_SETUP:
Sunil Dutt41de4e22013-11-14 18:09:02 +053013962 {
Atul Mittal115287b2014-07-08 13:26:33 +053013963 status = wlan_hdd_tdls_extctrl_config_peer(pAdapter,
13964 peer,
13965 NULL);
Sunil Dutt41de4e22013-11-14 18:09:02 +053013966
Atul Mittal115287b2014-07-08 13:26:33 +053013967 if (0 != status)
13968 {
13969 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
13970 "%s: Error in TDLS Setup", __func__);
13971 return status;
Naresh Jayaram937abdf2013-11-26 19:50:25 +053013972 }
Naresh Jayaramdb4514b2013-11-25 18:08:10 +053013973 break;
Sunil Dutt41de4e22013-11-14 18:09:02 +053013974 }
Mohit Khanna698ba2a2012-12-04 15:08:18 -080013975 case NL80211_TDLS_DISCOVERY_REQ:
13976 /* We don't support in-driver setup/teardown/discovery */
c_hpothu6ff1c3c2013-10-01 19:01:57 +053013977 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_WARN,
13978 "%s: We don't support in-driver setup/teardown/discovery "
13979 ,__func__);
Mohit Khanna698ba2a2012-12-04 15:08:18 -080013980 return -ENOTSUPP;
13981 default:
c_hpothu6ff1c3c2013-10-01 19:01:57 +053013982 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
13983 "%s: unsupported event",__func__);
Mohit Khanna698ba2a2012-12-04 15:08:18 -080013984 return -ENOTSUPP;
13985 }
13986 return 0;
13987}
Chilam NG571c65a2013-01-19 12:27:36 +053013988
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053013989static int wlan_hdd_cfg80211_tdls_oper(struct wiphy *wiphy, struct net_device *dev,
13990 u8 *peer, enum nl80211_tdls_operation oper)
13991{
13992 int ret;
13993
13994 vos_ssr_protect(__func__);
13995 ret = __wlan_hdd_cfg80211_tdls_oper(wiphy, dev, peer, oper);
13996 vos_ssr_unprotect(__func__);
13997
13998 return ret;
13999}
14000
Chilam NG571c65a2013-01-19 12:27:36 +053014001int wlan_hdd_cfg80211_send_tdls_discover_req(struct wiphy *wiphy,
14002 struct net_device *dev, u8 *peer)
14003{
Arif Hussaina7c8e412013-11-20 11:06:42 -080014004 hddLog(VOS_TRACE_LEVEL_INFO,
14005 "tdls send discover req: "MAC_ADDRESS_STR,
14006 MAC_ADDR_ARRAY(peer));
Chilam NG571c65a2013-01-19 12:27:36 +053014007
Sunil Dutt Undekarieacac6f2014-03-21 14:08:53 +053014008#if TDLS_MGMT_VERSION2
14009 return wlan_hdd_cfg80211_tdls_mgmt(wiphy, dev, peer,
14010 WLAN_TDLS_DISCOVERY_REQUEST, 1, 0, 0, NULL, 0);
14011#else
Chilam NG571c65a2013-01-19 12:27:36 +053014012 return wlan_hdd_cfg80211_tdls_mgmt(wiphy, dev, peer,
14013 WLAN_TDLS_DISCOVERY_REQUEST, 1, 0, NULL, 0);
Sunil Dutt Undekarieacac6f2014-03-21 14:08:53 +053014014#endif
Chilam NG571c65a2013-01-19 12:27:36 +053014015}
Mohit Khanna698ba2a2012-12-04 15:08:18 -080014016#endif
14017
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053014018#ifdef WLAN_FEATURE_GTK_OFFLOAD
14019/*
14020 * FUNCTION: wlan_hdd_cfg80211_update_replayCounterCallback
14021 * Callback rountine called upon receiving response for
14022 * get offload info
14023 */
14024void wlan_hdd_cfg80211_update_replayCounterCallback(void *callbackContext,
14025 tpSirGtkOffloadGetInfoRspParams pGtkOffloadGetInfoRsp)
14026{
14027
14028 hdd_adapter_t *pAdapter = (hdd_adapter_t *)callbackContext;
Gopichand Nakkalad36ee622013-05-07 14:13:27 +053014029 tANI_U8 tempReplayCounter[8];
14030 hdd_station_ctx_t *pHddStaCtx;
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053014031
14032 ENTER();
14033
14034 if (NULL == pAdapter)
14035 {
Agarwal Ashish971c2882013-10-30 20:11:12 +053014036 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053014037 "%s: HDD adapter is Null", __func__);
14038 return ;
14039 }
14040
14041 if (NULL == pGtkOffloadGetInfoRsp)
14042 {
14043 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
14044 "%s: pGtkOffloadGetInfoRsp is Null", __func__);
14045 return ;
14046 }
14047
14048 if (VOS_STATUS_SUCCESS != pGtkOffloadGetInfoRsp->ulStatus)
14049 {
14050 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
14051 "%s: wlan Failed to get replay counter value",
14052 __func__);
14053 return ;
14054 }
14055
Gopichand Nakkalad36ee622013-05-07 14:13:27 +053014056 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
14057 /* Update replay counter */
14058 pHddStaCtx->gtkOffloadReqParams.ullKeyReplayCounter =
14059 pGtkOffloadGetInfoRsp->ullKeyReplayCounter;
14060
14061 {
14062 /* changing from little to big endian since supplicant
14063 * works on big endian format
14064 */
14065 int i;
14066 tANI_U8 *p = (tANI_U8 *)&pGtkOffloadGetInfoRsp->ullKeyReplayCounter;
14067
14068 for (i = 0; i < 8; i++)
14069 {
14070 tempReplayCounter[7-i] = (tANI_U8)p[i];
14071 }
14072 }
14073
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053014074 /* Update replay counter to NL */
14075 cfg80211_gtk_rekey_notify(pAdapter->dev, pGtkOffloadGetInfoRsp->bssId,
Gopichand Nakkalad36ee622013-05-07 14:13:27 +053014076 tempReplayCounter, GFP_KERNEL);
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053014077}
14078
14079/*
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053014080 * FUNCTION: __wlan_hdd_cfg80211_set_rekey_data
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053014081 * This function is used to offload GTK rekeying job to the firmware.
14082 */
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053014083int __wlan_hdd_cfg80211_set_rekey_data(struct wiphy *wiphy, struct net_device *dev,
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053014084 struct cfg80211_gtk_rekey_data *data)
14085{
14086 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
14087 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
14088 hdd_station_ctx_t *pHddStaCtx;
14089 tHalHandle hHal;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053014090 int result;
Gopichand Nakkalad36ee622013-05-07 14:13:27 +053014091 tSirGtkOffloadParams hddGtkOffloadReqParams;
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053014092 eHalStatus status = eHAL_STATUS_FAILURE;
14093
14094 ENTER();
14095
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053014096
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053014097 if (NULL == pAdapter)
14098 {
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053014099 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053014100 "%s: HDD adapter is Null", __func__);
14101 return -ENODEV;
14102 }
14103
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053014104 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
14105 TRACE_CODE_HDD_CFG80211_SET_REKEY_DATA,
14106 pAdapter->sessionId, pAdapter->device_mode));
14107
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053014108 result = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053014109
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053014110 if (0 != result)
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053014111 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053014112 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
14113 "%s: HDD context is not valid", __func__);
14114 return result;
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053014115 }
14116
14117 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
14118 hHal = WLAN_HDD_GET_HAL_CTX(pAdapter);
14119 if (NULL == hHal)
14120 {
14121 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
14122 "%s: HAL context is Null!!!", __func__);
14123 return -EAGAIN;
14124 }
14125
Gopichand Nakkalad36ee622013-05-07 14:13:27 +053014126 pHddStaCtx->gtkOffloadReqParams.ulFlags = GTK_OFFLOAD_ENABLE;
14127 memcpy(pHddStaCtx->gtkOffloadReqParams.aKCK, data->kck, NL80211_KCK_LEN);
14128 memcpy(pHddStaCtx->gtkOffloadReqParams.aKEK, data->kek, NL80211_KEK_LEN);
14129 memcpy(pHddStaCtx->gtkOffloadReqParams.bssId, &pHddStaCtx->conn_info.bssId,
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053014130 WNI_CFG_BSSID_LEN);
Gopichand Nakkalad36ee622013-05-07 14:13:27 +053014131 {
14132 /* changing from big to little endian since driver
14133 * works on little endian format
14134 */
14135 tANI_U8 *p =
14136 (tANI_U8 *)&pHddStaCtx->gtkOffloadReqParams.ullKeyReplayCounter;
14137 int i;
14138
14139 for (i = 0; i < 8; i++)
14140 {
14141 p[7-i] = data->replay_ctr[i];
14142 }
14143 }
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053014144
14145 if (TRUE == pHddCtx->hdd_wlan_suspended)
14146 {
14147 /* if wlan is suspended, enable GTK offload directly from here */
Gopichand Nakkalad36ee622013-05-07 14:13:27 +053014148 memcpy(&hddGtkOffloadReqParams, &pHddStaCtx->gtkOffloadReqParams,
14149 sizeof (tSirGtkOffloadParams));
14150 status = sme_SetGTKOffload(hHal, &hddGtkOffloadReqParams,
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053014151 pAdapter->sessionId);
14152
14153 if (eHAL_STATUS_SUCCESS != status)
14154 {
14155 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
14156 "%s: sme_SetGTKOffload failed, returned %d",
14157 __func__, status);
Vinay Krishna Eranna6f22c1f2014-10-13 16:03:06 +053014158
14159 /* Need to clear any trace of key value in the memory.
14160 * Thus zero out the memory even though it is local
14161 * variable.
14162 */
14163 vos_mem_zero(&hddGtkOffloadReqParams,
14164 sizeof(hddGtkOffloadReqParams));
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053014165 return status;
14166 }
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053014167 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
14168 "%s: sme_SetGTKOffload successfull", __func__);
14169 }
14170 else
14171 {
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053014172 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
14173 "%s: wlan not suspended GTKOffload request is stored",
14174 __func__);
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053014175 }
Gopichand Nakkalad36ee622013-05-07 14:13:27 +053014176
Vinay Krishna Eranna6f22c1f2014-10-13 16:03:06 +053014177 /* Need to clear any trace of key value in the memory.
14178 * Thus zero out the memory even though it is local
14179 * variable.
14180 */
14181 vos_mem_zero(&hddGtkOffloadReqParams,
14182 sizeof(hddGtkOffloadReqParams));
14183
Gopichand Nakkalad36ee622013-05-07 14:13:27 +053014184 return eHAL_STATUS_SUCCESS;
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053014185}
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053014186
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053014187int wlan_hdd_cfg80211_set_rekey_data(struct wiphy *wiphy, struct net_device *dev,
14188 struct cfg80211_gtk_rekey_data *data)
14189{
14190 int ret;
14191
14192 vos_ssr_protect(__func__);
14193 ret = __wlan_hdd_cfg80211_set_rekey_data(wiphy, dev, data);
14194 vos_ssr_unprotect(__func__);
14195
14196 return ret;
14197}
14198#endif /*WLAN_FEATURE_GTK_OFFLOAD*/
Gopichand Nakkalac005b7c2013-05-14 16:04:14 +053014199/*
14200 * FUNCTION: wlan_hdd_cfg80211_set_mac_acl
14201 * This function is used to set access control policy
14202 */
14203static int wlan_hdd_cfg80211_set_mac_acl(struct wiphy *wiphy,
14204 struct net_device *dev, const struct cfg80211_acl_data *params)
14205{
14206 int i;
14207 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
14208 hdd_hostapd_state_t *pHostapdState;
14209 tsap_Config_t *pConfig;
14210 v_CONTEXT_t pVosContext = NULL;
14211 hdd_context_t *pHddCtx;
14212 int status;
14213
14214 ENTER();
14215
14216 if (NULL == pAdapter)
14217 {
14218 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
14219 "%s: HDD adapter is Null", __func__);
14220 return -ENODEV;
14221 }
14222
14223 if (NULL == params)
14224 {
14225 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
14226 "%s: params is Null", __func__);
14227 return -EINVAL;
14228 }
14229
14230 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
14231 status = wlan_hdd_validate_context(pHddCtx);
14232
14233 if (0 != status)
14234 {
14235 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
14236 "%s: HDD context is not valid", __func__);
14237 return status;
14238 }
14239
14240 pVosContext = pHddCtx->pvosContext;
14241 pHostapdState = WLAN_HDD_GET_HOSTAP_STATE_PTR(pAdapter);
14242
14243 if (NULL == pHostapdState)
14244 {
14245 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
14246 "%s: pHostapdState is Null", __func__);
14247 return -EINVAL;
14248 }
14249
14250 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,"acl policy: = %d"
14251 "no acl entries = %d", params->acl_policy, params->n_acl_entries);
14252
14253 if (WLAN_HDD_SOFTAP == pAdapter->device_mode)
14254 {
14255 pConfig = &pAdapter->sessionCtx.ap.sapConfig;
14256
14257 /* default value */
14258 pConfig->num_accept_mac = 0;
14259 pConfig->num_deny_mac = 0;
14260
14261 /**
14262 * access control policy
14263 * @NL80211_ACL_POLICY_ACCEPT_UNLESS_LISTED: Deny stations which are
14264 * listed in hostapd.deny file.
14265 * @NL80211_ACL_POLICY_DENY_UNLESS_LISTED: Allow stations which are
14266 * listed in hostapd.accept file.
14267 */
14268 if (NL80211_ACL_POLICY_DENY_UNLESS_LISTED == params->acl_policy)
14269 {
14270 pConfig->SapMacaddr_acl = eSAP_DENY_UNLESS_ACCEPTED;
14271 }
14272 else if (NL80211_ACL_POLICY_ACCEPT_UNLESS_LISTED == params->acl_policy)
14273 {
14274 pConfig->SapMacaddr_acl = eSAP_ACCEPT_UNLESS_DENIED;
14275 }
14276 else
14277 {
14278 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
14279 "%s:Acl Policy : %d is not supported",
14280 __func__, params->acl_policy);
14281 return -ENOTSUPP;
14282 }
14283
14284 if (eSAP_DENY_UNLESS_ACCEPTED == pConfig->SapMacaddr_acl)
14285 {
14286 pConfig->num_accept_mac = params->n_acl_entries;
14287 for (i = 0; i < params->n_acl_entries; i++)
14288 {
14289 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
14290 "** Add ACL MAC entry %i in WhiletList :"
14291 MAC_ADDRESS_STR, i,
14292 MAC_ADDR_ARRAY(params->mac_addrs[i].addr));
14293
14294 vos_mem_copy(&pConfig->accept_mac[i], params->mac_addrs[i].addr,
14295 sizeof(qcmacaddr));
14296 }
14297 }
14298 else if (eSAP_ACCEPT_UNLESS_DENIED == pConfig->SapMacaddr_acl)
14299 {
14300 pConfig->num_deny_mac = params->n_acl_entries;
14301 for (i = 0; i < params->n_acl_entries; i++)
14302 {
14303 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
14304 "** Add ACL MAC entry %i in BlackList :"
14305 MAC_ADDRESS_STR, i,
14306 MAC_ADDR_ARRAY(params->mac_addrs[i].addr));
14307
14308 vos_mem_copy(&pConfig->deny_mac[i], params->mac_addrs[i].addr,
14309 sizeof(qcmacaddr));
14310 }
14311 }
14312
14313 if (VOS_STATUS_SUCCESS != WLANSAP_SetMacACL(pVosContext, pConfig))
14314 {
14315 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
14316 "%s: SAP Set Mac Acl fail", __func__);
14317 return -EINVAL;
14318 }
14319 }
14320 else
14321 {
14322 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Sushant Kaushik8bc7df22014-04-09 17:55:29 +053014323 "%s: Invalid device_mode = %s (%d)",
14324 __func__, hdd_device_modetoString(pAdapter->device_mode),
14325 pAdapter->device_mode);
Gopichand Nakkalac005b7c2013-05-14 16:04:14 +053014326 return -EINVAL;
14327 }
14328
14329 return 0;
14330}
14331
Leo Chang9056f462013-08-01 19:21:11 -070014332#ifdef WLAN_NL80211_TESTMODE
14333#ifdef FEATURE_WLAN_LPHB
Leo Changd9df8aa2013-09-26 13:32:26 -070014334void wlan_hdd_cfg80211_lphb_ind_handler
Leo Chang9056f462013-08-01 19:21:11 -070014335(
14336 void *pAdapter,
14337 void *indCont
14338)
14339{
Leo Changd9df8aa2013-09-26 13:32:26 -070014340 tSirLPHBInd *lphbInd;
14341 struct sk_buff *skb;
c_hpothu73f35e62014-04-18 13:40:08 +053014342 hdd_context_t *pHddCtxt;
Leo Chang9056f462013-08-01 19:21:11 -070014343
14344 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Leo Changd9df8aa2013-09-26 13:32:26 -070014345 "LPHB indication arrived");
Leo Chang9056f462013-08-01 19:21:11 -070014346
c_hpothu73f35e62014-04-18 13:40:08 +053014347 if (pAdapter == NULL)
14348 {
14349 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
14350 "%s: pAdapter is NULL\n",__func__);
14351 return;
14352 }
14353
Leo Chang9056f462013-08-01 19:21:11 -070014354 if (NULL == indCont)
14355 {
14356 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Leo Changd9df8aa2013-09-26 13:32:26 -070014357 "LPHB IND, invalid argument");
Leo Chang9056f462013-08-01 19:21:11 -070014358 return;
14359 }
14360
c_hpothu73f35e62014-04-18 13:40:08 +053014361 pHddCtxt = (hdd_context_t *)pAdapter;
Leo Changd9df8aa2013-09-26 13:32:26 -070014362 lphbInd = (tSirLPHBInd *)indCont;
Leo Chang9056f462013-08-01 19:21:11 -070014363 skb = cfg80211_testmode_alloc_event_skb(
c_hpothu73f35e62014-04-18 13:40:08 +053014364 pHddCtxt->wiphy,
Leo Changd9df8aa2013-09-26 13:32:26 -070014365 sizeof(tSirLPHBInd),
Leo Chang9056f462013-08-01 19:21:11 -070014366 GFP_ATOMIC);
14367 if (!skb)
14368 {
14369 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
14370 "LPHB timeout, NL buffer alloc fail");
14371 return;
14372 }
14373
Leo Changac3ba772013-10-07 09:47:04 -070014374 if(nla_put_u32(skb, WLAN_HDD_TM_ATTR_CMD, WLAN_HDD_TM_CMD_WLAN_HB))
Leo Changd9df8aa2013-09-26 13:32:26 -070014375 {
14376 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
14377 "WLAN_HDD_TM_ATTR_CMD put fail");
14378 goto nla_put_failure;
14379 }
Leo Changac3ba772013-10-07 09:47:04 -070014380 if(nla_put_u32(skb, WLAN_HDD_TM_ATTR_TYPE, lphbInd->protocolType))
Leo Changd9df8aa2013-09-26 13:32:26 -070014381 {
14382 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
14383 "WLAN_HDD_TM_ATTR_TYPE put fail");
14384 goto nla_put_failure;
14385 }
Leo Changac3ba772013-10-07 09:47:04 -070014386 if(nla_put(skb, WLAN_HDD_TM_ATTR_DATA,
Leo Changd9df8aa2013-09-26 13:32:26 -070014387 sizeof(tSirLPHBInd), lphbInd))
14388 {
14389 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
14390 "WLAN_HDD_TM_ATTR_DATA put fail");
14391 goto nla_put_failure;
14392 }
Leo Chang9056f462013-08-01 19:21:11 -070014393 cfg80211_testmode_event(skb, GFP_ATOMIC);
14394 return;
14395
14396nla_put_failure:
14397 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
14398 "NLA Put fail");
14399 kfree_skb(skb);
14400
14401 return;
14402}
14403#endif /* FEATURE_WLAN_LPHB */
14404
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053014405static int __wlan_hdd_cfg80211_testmode(struct wiphy *wiphy, void *data, int len)
Leo Chang9056f462013-08-01 19:21:11 -070014406{
14407 struct nlattr *tb[WLAN_HDD_TM_ATTR_MAX + 1];
14408 int err = 0;
14409#ifdef FEATURE_WLAN_LPHB
14410 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
Leo Changd9df8aa2013-09-26 13:32:26 -070014411 eHalStatus smeStatus;
Leo Chang9056f462013-08-01 19:21:11 -070014412#endif /* FEATURE_WLAN_LPHB */
14413
14414 err = nla_parse(tb, WLAN_HDD_TM_ATTR_MAX, data, len, wlan_hdd_tm_policy);
14415 if (err)
14416 {
14417 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
14418 "%s Testmode INV ATTR", __func__);
14419 return err;
14420 }
14421
14422 if (!tb[WLAN_HDD_TM_ATTR_CMD])
14423 {
14424 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
14425 "%s Testmode INV CMD", __func__);
14426 return -EINVAL;
14427 }
14428
14429 switch (nla_get_u32(tb[WLAN_HDD_TM_ATTR_CMD]))
14430 {
14431#ifdef FEATURE_WLAN_LPHB
14432 /* Low Power Heartbeat configuration request */
14433 case WLAN_HDD_TM_CMD_WLAN_HB:
14434 {
14435 int buf_len;
14436 void *buf;
14437 tSirLPHBReq *hb_params = NULL;
Amar Singhal05852702014-02-04 14:40:00 -080014438 tSirLPHBReq *hb_params_temp = NULL;
Leo Chang9056f462013-08-01 19:21:11 -070014439
14440 if (!tb[WLAN_HDD_TM_ATTR_DATA])
14441 {
14442 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
14443 "%s Testmode INV DATA", __func__);
14444 return -EINVAL;
14445 }
14446
14447 buf = nla_data(tb[WLAN_HDD_TM_ATTR_DATA]);
14448 buf_len = nla_len(tb[WLAN_HDD_TM_ATTR_DATA]);
Amar Singhal05852702014-02-04 14:40:00 -080014449
14450 hb_params_temp =(tSirLPHBReq *)buf;
14451 if ((hb_params_temp->cmd == LPHB_SET_TCP_PARAMS_INDID) &&
14452 (hb_params_temp->params.lphbTcpParamReq.timePeriodSec == 0))
14453 return -EINVAL;
14454
Leo Chang9056f462013-08-01 19:21:11 -070014455 hb_params = (tSirLPHBReq *)vos_mem_malloc(sizeof(tSirLPHBReq));
14456 if (NULL == hb_params)
14457 {
14458 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
14459 "%s Request Buffer Alloc Fail", __func__);
14460 return -EINVAL;
14461 }
14462
14463 vos_mem_copy(hb_params, buf, buf_len);
Leo Changd9df8aa2013-09-26 13:32:26 -070014464 smeStatus = sme_LPHBConfigReq((tHalHandle)(pHddCtx->hHal),
14465 hb_params,
14466 wlan_hdd_cfg80211_lphb_ind_handler);
14467 if (eHAL_STATUS_SUCCESS != smeStatus)
Leo Chang9056f462013-08-01 19:21:11 -070014468 {
Leo Changd9df8aa2013-09-26 13:32:26 -070014469 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
14470 "LPHB Config Fail, disable");
Leo Chang9056f462013-08-01 19:21:11 -070014471 vos_mem_free(hb_params);
14472 }
Leo Chang9056f462013-08-01 19:21:11 -070014473 return 0;
14474 }
14475#endif /* FEATURE_WLAN_LPHB */
14476 default:
c_hpothu6ff1c3c2013-10-01 19:01:57 +053014477 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
14478 "%s: unsupported event",__func__);
Leo Chang9056f462013-08-01 19:21:11 -070014479 return -EOPNOTSUPP;
14480 }
14481
14482 return err;
14483}
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053014484
14485static int wlan_hdd_cfg80211_testmode(struct wiphy *wiphy, void *data, int len)
14486{
14487 int ret;
14488
14489 vos_ssr_protect(__func__);
14490 ret = __wlan_hdd_cfg80211_testmode(wiphy, data, len);
14491 vos_ssr_unprotect(__func__);
14492
14493 return ret;
14494}
Leo Chang9056f462013-08-01 19:21:11 -070014495#endif /* CONFIG_NL80211_TESTMODE */
14496
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053014497static int __wlan_hdd_cfg80211_dump_survey(struct wiphy *wiphy,
Madan Mohan Koyyalamudid9383fd2013-08-13 09:27:30 +053014498 struct net_device *dev,
14499 int idx, struct survey_info *survey)
14500{
14501 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
14502 hdd_context_t *pHddCtx;
Mihir Sheted9072e02013-08-21 17:02:29 +053014503 hdd_station_ctx_t *pHddStaCtx;
Madan Mohan Koyyalamudid9383fd2013-08-13 09:27:30 +053014504 tHalHandle halHandle;
Mihir Sheted9072e02013-08-21 17:02:29 +053014505 v_U32_t channel = 0, freq = 0; /* Initialization Required */
Madan Mohan Koyyalamudid9383fd2013-08-13 09:27:30 +053014506 v_S7_t snr,rssi;
14507 int status, i, j, filled = 0;
14508
14509 ENTER();
14510
Madan Mohan Koyyalamudid9383fd2013-08-13 09:27:30 +053014511 if (NULL == pAdapter)
14512 {
14513 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
14514 "%s: HDD adapter is Null", __func__);
14515 return -ENODEV;
14516 }
14517
14518 if (NULL == wiphy)
14519 {
14520 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
14521 "%s: wiphy is Null", __func__);
14522 return -ENODEV;
14523 }
14524
14525 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
14526 status = wlan_hdd_validate_context(pHddCtx);
14527
14528 if (0 != status)
14529 {
14530 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
14531 "%s: HDD context is not valid", __func__);
14532 return status;
14533 }
14534
Mihir Sheted9072e02013-08-21 17:02:29 +053014535 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
14536
Madan Mohan Koyyalamudid9383fd2013-08-13 09:27:30 +053014537 if (0 == pHddCtx->cfg_ini->fEnableSNRMonitoring ||
Mihir Sheted9072e02013-08-21 17:02:29 +053014538 0 != pAdapter->survey_idx ||
14539 eConnectionState_Associated != pHddStaCtx->conn_info.connState)
Madan Mohan Koyyalamudid9383fd2013-08-13 09:27:30 +053014540 {
14541 /* The survey dump ops when implemented completely is expected to
14542 * return a survey of all channels and the ops is called by the
14543 * kernel with incremental values of the argument 'idx' till it
14544 * returns -ENONET. But we can only support the survey for the
14545 * operating channel for now. survey_idx is used to track
14546 * that the ops is called only once and then return -ENONET for
14547 * the next iteration
14548 */
14549 pAdapter->survey_idx = 0;
14550 return -ENONET;
14551 }
14552
14553 halHandle = WLAN_HDD_GET_HAL_CTX(pAdapter);
14554
14555 wlan_hdd_get_snr(pAdapter, &snr);
14556 wlan_hdd_get_rssi(pAdapter, &rssi);
14557
14558 sme_GetOperationChannel(halHandle, &channel, pAdapter->sessionId);
14559 hdd_wlan_get_freq(channel, &freq);
14560
14561
14562 for (i = 0; i < IEEE80211_NUM_BANDS; i++)
14563 {
14564 if (NULL == wiphy->bands[i])
14565 {
14566 VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_INFO,
14567 "%s: wiphy->bands[i] is NULL, i = %d", __func__, i);
14568 continue;
14569 }
14570
14571 for (j = 0; j < wiphy->bands[i]->n_channels; j++)
14572 {
14573 struct ieee80211_supported_band *band = wiphy->bands[i];
14574
14575 if (band->channels[j].center_freq == (v_U16_t)freq)
14576 {
14577 survey->channel = &band->channels[j];
14578 /* The Rx BDs contain SNR values in dB for the received frames
14579 * while the supplicant expects noise. So we calculate and
14580 * return the value of noise (dBm)
14581 * SNR (dB) = RSSI (dBm) - NOISE (dBm)
14582 */
14583 survey->noise = rssi - snr;
14584 survey->filled = SURVEY_INFO_NOISE_DBM;
14585 filled = 1;
14586 }
14587 }
14588 }
14589
14590 if (filled)
14591 pAdapter->survey_idx = 1;
14592 else
14593 {
14594 pAdapter->survey_idx = 0;
14595 return -ENONET;
14596 }
14597
14598 return 0;
14599}
14600
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053014601static int wlan_hdd_cfg80211_dump_survey(struct wiphy *wiphy,
14602 struct net_device *dev,
14603 int idx, struct survey_info *survey)
14604{
14605 int ret;
14606
14607 vos_ssr_protect(__func__);
14608 ret = __wlan_hdd_cfg80211_dump_survey(wiphy, dev, idx, survey);
14609 vos_ssr_unprotect(__func__);
14610
14611 return ret;
14612}
14613
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053014614/*
Mahesh A Saptasagarbcc5b662014-06-02 21:46:23 +053014615 * FUNCTION: __wlan_hdd_cfg80211_resume_wlan
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053014616 * this is called when cfg80211 driver resume
14617 * driver updates latest sched_scan scan result(if any) to cfg80211 database
14618 */
Mahesh A Saptasagarbcc5b662014-06-02 21:46:23 +053014619int __wlan_hdd_cfg80211_resume_wlan(struct wiphy *wiphy)
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053014620{
14621 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
14622 hdd_adapter_t *pAdapter;
14623 hdd_adapter_list_node_t *pAdapterNode, *pNext;
14624 VOS_STATUS status = VOS_STATUS_SUCCESS;
14625
14626 ENTER();
14627
14628 if ( NULL == pHddCtx )
14629 {
14630 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
14631 "%s: HddCtx validation failed", __func__);
14632 return 0;
14633 }
14634
14635 if (pHddCtx->isLogpInProgress)
14636 {
14637 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
14638 "%s: LOGP in Progress. Ignore!!!", __func__);
14639 return 0;
14640 }
14641
Mihir Shete18156292014-03-11 15:38:30 +053014642 if (WLAN_HDD_IS_LOAD_UNLOAD_IN_PROGRESS(pHddCtx))
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053014643 {
14644 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
14645 "%s: Unloading/Loading in Progress. Ignore!!!", __func__);
14646 return 0;
14647 }
14648
14649 spin_lock(&pHddCtx->schedScan_lock);
14650 pHddCtx->isWiphySuspended = FALSE;
14651 if (TRUE != pHddCtx->isSchedScanUpdatePending)
14652 {
14653 spin_unlock(&pHddCtx->schedScan_lock);
14654 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
14655 "%s: Return resume is not due to PNO indication", __func__);
14656 return 0;
14657 }
14658 // Reset flag to avoid updatating cfg80211 data old results again
14659 pHddCtx->isSchedScanUpdatePending = FALSE;
14660 spin_unlock(&pHddCtx->schedScan_lock);
14661
Mahesh A Saptasagarb9c50402014-01-16 15:49:22 +053014662
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053014663 status = hdd_get_front_adapter ( pHddCtx, &pAdapterNode );
14664
14665 while ( NULL != pAdapterNode && VOS_STATUS_SUCCESS == status )
14666 {
14667 pAdapter = pAdapterNode->pAdapter;
14668 if ( (NULL != pAdapter) &&
14669 (WLAN_HDD_INFRA_STATION == pAdapter->device_mode) )
14670 {
14671 if (0 != wlan_hdd_cfg80211_update_bss(pHddCtx->wiphy, pAdapter))
Mahesh A Saptasagarb9c50402014-01-16 15:49:22 +053014672 {
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053014673 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_WARN,
14674 "%s: NO SCAN result", __func__);
Mahesh A Saptasagarb9c50402014-01-16 15:49:22 +053014675 }
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053014676 else
Mahesh A Saptasagarb9c50402014-01-16 15:49:22 +053014677 {
14678 /* Acquire wakelock to handle the case where APP's tries to
14679 * suspend immediately after updating the scan results. Whis
14680 * results in app's is in suspended state and not able to
14681 * process the connect request to AP
14682 */
14683 hdd_prevent_suspend_timeout(2000);
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053014684 cfg80211_sched_scan_results(pHddCtx->wiphy);
Mahesh A Saptasagarb9c50402014-01-16 15:49:22 +053014685 }
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053014686
14687 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
14688 "%s : cfg80211 scan result database updated", __func__);
14689
14690 return 0;
14691
14692 }
14693 status = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
14694 pAdapterNode = pNext;
14695 }
14696
14697 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
14698 "%s: Failed to find Adapter", __func__);
14699 return 0;
14700}
14701
Mahesh A Saptasagarbcc5b662014-06-02 21:46:23 +053014702int wlan_hdd_cfg80211_resume_wlan(struct wiphy *wiphy)
14703{
14704 int ret;
14705
14706 vos_ssr_protect(__func__);
14707 ret = __wlan_hdd_cfg80211_resume_wlan(wiphy);
14708 vos_ssr_unprotect(__func__);
14709
14710 return ret;
14711}
14712
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053014713/*
Mahesh A Saptasagarbcc5b662014-06-02 21:46:23 +053014714 * FUNCTION: __wlan_hdd_cfg80211_suspend_wlan
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053014715 * this is called when cfg80211 driver suspends
14716 */
Mahesh A Saptasagarbcc5b662014-06-02 21:46:23 +053014717int __wlan_hdd_cfg80211_suspend_wlan(struct wiphy *wiphy,
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053014718 struct cfg80211_wowlan *wow)
14719{
14720 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
14721
14722 ENTER();
14723 if (NULL == pHddCtx)
14724 {
14725 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
14726 "%s: HddCtx validation failed", __func__);
14727 return 0;
14728 }
14729
14730 pHddCtx->isWiphySuspended = TRUE;
14731
14732 EXIT();
14733
14734 return 0;
14735}
14736
Mahesh A Saptasagarbcc5b662014-06-02 21:46:23 +053014737int wlan_hdd_cfg80211_suspend_wlan(struct wiphy *wiphy,
14738 struct cfg80211_wowlan *wow)
14739{
14740 int ret;
14741
14742 vos_ssr_protect(__func__);
14743 ret = __wlan_hdd_cfg80211_suspend_wlan(wiphy, wow);
14744 vos_ssr_unprotect(__func__);
14745
14746 return ret;
14747}
Jeff Johnson295189b2012-06-20 16:38:30 -070014748/* cfg80211_ops */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014749static struct cfg80211_ops wlan_hdd_cfg80211_ops =
Jeff Johnson295189b2012-06-20 16:38:30 -070014750{
14751 .add_virtual_intf = wlan_hdd_add_virtual_intf,
14752 .del_virtual_intf = wlan_hdd_del_virtual_intf,
14753 .change_virtual_intf = wlan_hdd_cfg80211_change_iface,
14754 .change_station = wlan_hdd_change_station,
14755#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,4,0))
14756 .add_beacon = wlan_hdd_cfg80211_add_beacon,
14757 .del_beacon = wlan_hdd_cfg80211_del_beacon,
14758 .set_beacon = wlan_hdd_cfg80211_set_beacon,
Jeff Johnson04dd8a82012-06-29 20:41:40 -070014759#else
14760 .start_ap = wlan_hdd_cfg80211_start_ap,
14761 .change_beacon = wlan_hdd_cfg80211_change_beacon,
14762 .stop_ap = wlan_hdd_cfg80211_stop_ap,
Jeff Johnson295189b2012-06-20 16:38:30 -070014763#endif
14764 .change_bss = wlan_hdd_cfg80211_change_bss,
14765 .add_key = wlan_hdd_cfg80211_add_key,
14766 .get_key = wlan_hdd_cfg80211_get_key,
14767 .del_key = wlan_hdd_cfg80211_del_key,
14768 .set_default_key = wlan_hdd_cfg80211_set_default_key,
Jeff Johnson3bbe4bf2013-01-18 17:05:29 -080014769#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,6,0))
Jeff Johnson295189b2012-06-20 16:38:30 -070014770 .set_channel = wlan_hdd_cfg80211_set_channel,
Jeff Johnson3bbe4bf2013-01-18 17:05:29 -080014771#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070014772 .scan = wlan_hdd_cfg80211_scan,
14773 .connect = wlan_hdd_cfg80211_connect,
14774 .disconnect = wlan_hdd_cfg80211_disconnect,
14775 .join_ibss = wlan_hdd_cfg80211_join_ibss,
14776 .leave_ibss = wlan_hdd_cfg80211_leave_ibss,
14777 .set_wiphy_params = wlan_hdd_cfg80211_set_wiphy_params,
14778 .set_tx_power = wlan_hdd_cfg80211_set_txpower,
14779 .get_tx_power = wlan_hdd_cfg80211_get_txpower,
Jeff Johnson295189b2012-06-20 16:38:30 -070014780 .remain_on_channel = wlan_hdd_cfg80211_remain_on_channel,
14781 .cancel_remain_on_channel = wlan_hdd_cfg80211_cancel_remain_on_channel,
DARAM SUDHA39eede62014-02-12 11:16:40 +053014782 .mgmt_tx = wlan_hdd_mgmt_tx,
Jeff Johnson295189b2012-06-20 16:38:30 -070014783#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
14784 .mgmt_tx_cancel_wait = wlan_hdd_cfg80211_mgmt_tx_cancel_wait,
14785 .set_default_mgmt_key = wlan_hdd_set_default_mgmt_key,
14786 .set_txq_params = wlan_hdd_set_txq_params,
14787#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070014788 .get_station = wlan_hdd_cfg80211_get_station,
14789 .set_power_mgmt = wlan_hdd_cfg80211_set_power_mgmt,
14790 .del_station = wlan_hdd_cfg80211_del_station,
Jeff Johnson04dd8a82012-06-29 20:41:40 -070014791 .add_station = wlan_hdd_cfg80211_add_station,
14792#ifdef FEATURE_WLAN_LFR
14793 .set_pmksa = wlan_hdd_cfg80211_set_pmksa,
14794 .del_pmksa = wlan_hdd_cfg80211_del_pmksa,
14795 .flush_pmksa = wlan_hdd_cfg80211_flush_pmksa,
14796#endif
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070014797#if defined(WLAN_FEATURE_VOWIFI_11R) && defined(KERNEL_SUPPORT_11R_CFG80211)
14798 .update_ft_ies = wlan_hdd_cfg80211_update_ft_ies,
14799#endif
Mohit Khanna698ba2a2012-12-04 15:08:18 -080014800#ifdef FEATURE_WLAN_TDLS
14801 .tdls_mgmt = wlan_hdd_cfg80211_tdls_mgmt,
14802 .tdls_oper = wlan_hdd_cfg80211_tdls_oper,
14803#endif
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053014804#ifdef WLAN_FEATURE_GTK_OFFLOAD
14805 .set_rekey_data = wlan_hdd_cfg80211_set_rekey_data,
14806#endif /* WLAN_FEATURE_GTK_OFFLOAD */
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053014807#ifdef FEATURE_WLAN_SCAN_PNO
14808 .sched_scan_start = wlan_hdd_cfg80211_sched_scan_start,
14809 .sched_scan_stop = wlan_hdd_cfg80211_sched_scan_stop,
14810#endif /*FEATURE_WLAN_SCAN_PNO */
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053014811 .resume = wlan_hdd_cfg80211_resume_wlan,
14812 .suspend = wlan_hdd_cfg80211_suspend_wlan,
Gopichand Nakkalac005b7c2013-05-14 16:04:14 +053014813 .set_mac_acl = wlan_hdd_cfg80211_set_mac_acl,
Leo Chang9056f462013-08-01 19:21:11 -070014814#ifdef WLAN_NL80211_TESTMODE
14815 .testmode_cmd = wlan_hdd_cfg80211_testmode,
14816#endif
Madan Mohan Koyyalamudid9383fd2013-08-13 09:27:30 +053014817 .dump_survey = wlan_hdd_cfg80211_dump_survey,
Jeff Johnson295189b2012-06-20 16:38:30 -070014818};
14819