blob: ac89e878ec4f7873e717c825875e971ada1c49e0 [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;
569
Leo Chang9056f462013-08-01 19:21:11 -0700570#ifdef WLAN_NL80211_TESTMODE
571enum wlan_hdd_tm_attr
572{
573 WLAN_HDD_TM_ATTR_INVALID = 0,
574 WLAN_HDD_TM_ATTR_CMD = 1,
575 WLAN_HDD_TM_ATTR_DATA = 2,
576 WLAN_HDD_TM_ATTR_TYPE = 3,
577 /* keep last */
578 WLAN_HDD_TM_ATTR_AFTER_LAST,
579 WLAN_HDD_TM_ATTR_MAX = WLAN_HDD_TM_ATTR_AFTER_LAST - 1,
580};
581
582enum wlan_hdd_tm_cmd
583{
584 WLAN_HDD_TM_CMD_WLAN_HB = 1,
585};
586
587#define WLAN_HDD_TM_DATA_MAX_LEN 5000
588
589static const struct nla_policy wlan_hdd_tm_policy[WLAN_HDD_TM_ATTR_MAX + 1] =
590{
591 [WLAN_HDD_TM_ATTR_CMD] = { .type = NLA_U32 },
592 [WLAN_HDD_TM_ATTR_DATA] = { .type = NLA_BINARY,
593 .len = WLAN_HDD_TM_DATA_MAX_LEN },
594};
595#endif /* WLAN_NL80211_TESTMODE */
596
Rajesh Chauhan98a31f82014-01-06 20:15:25 -0800597#ifdef FEATURE_WLAN_CH_AVOID
598/*
599 * FUNCTION: wlan_hdd_send_avoid_freq_event
600 * This is called when wlan driver needs to send vendor specific
601 * avoid frequency range event to userspace
602 */
603int wlan_hdd_send_avoid_freq_event(hdd_context_t *pHddCtx,
604 tHddAvoidFreqList *pAvoidFreqList)
605{
606 struct sk_buff *vendor_event;
607
608 ENTER();
609
610 if (!pHddCtx)
611 {
612 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
613 "%s: HDD context is null", __func__);
614 return -1;
615 }
616
617 if (!pAvoidFreqList)
618 {
619 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
620 "%s: pAvoidFreqList is null", __func__);
621 return -1;
622 }
623
624 vendor_event = cfg80211_vendor_event_alloc(pHddCtx->wiphy,
625 sizeof(tHddAvoidFreqList),
Sunil Duttc69bccb2014-05-26 21:30:20 +0530626 QCA_NL80211_VENDOR_SUBCMD_AVOID_FREQUENCY_INDEX,
Rajesh Chauhan98a31f82014-01-06 20:15:25 -0800627 GFP_KERNEL);
628 if (!vendor_event)
629 {
630 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
631 "%s: cfg80211_vendor_event_alloc failed", __func__);
632 return -1;
633 }
634
635 memcpy(skb_put(vendor_event, sizeof(tHddAvoidFreqList)),
636 (void *)pAvoidFreqList, sizeof(tHddAvoidFreqList));
637
638 cfg80211_vendor_event(vendor_event, GFP_KERNEL);
639
640 EXIT();
641 return 0;
642}
643#endif /* FEATURE_WLAN_CH_AVOID */
644
Sunil Duttc69bccb2014-05-26 21:30:20 +0530645#ifdef WLAN_FEATURE_LINK_LAYER_STATS
646
647static v_BOOL_t put_wifi_rate_stat( tpSirWifiRateStat stats,
648 struct sk_buff *vendor_event)
649{
650 if (nla_put_u8(vendor_event,
651 QCA_WLAN_VENDOR_ATTR_LL_STATS_RATE_PREAMBLE,
652 stats->rate.preamble) ||
653 nla_put_u8(vendor_event,
654 QCA_WLAN_VENDOR_ATTR_LL_STATS_RATE_NSS,
655 stats->rate.nss) ||
656 nla_put_u8(vendor_event,
657 QCA_WLAN_VENDOR_ATTR_LL_STATS_RATE_BW,
658 stats->rate.bw) ||
659 nla_put_u8(vendor_event,
660 QCA_WLAN_VENDOR_ATTR_LL_STATS_RATE_MCS_INDEX,
661 stats->rate.rateMcsIdx) ||
662 nla_put_u32(vendor_event, QCA_WLAN_VENDOR_ATTR_LL_STATS_RATE_BIT_RATE,
663 stats->rate.bitrate ) ||
664 nla_put_u32(vendor_event, QCA_WLAN_VENDOR_ATTR_LL_STATS_RATE_TX_MPDU,
665 stats->txMpdu ) ||
666 nla_put_u32(vendor_event, QCA_WLAN_VENDOR_ATTR_LL_STATS_RATE_RX_MPDU,
667 stats->rxMpdu ) ||
668 nla_put_u32(vendor_event, QCA_WLAN_VENDOR_ATTR_LL_STATS_RATE_MPDU_LOST,
669 stats->mpduLost ) ||
670 nla_put_u32(vendor_event, QCA_WLAN_VENDOR_ATTR_LL_STATS_RATE_RETRIES,
671 stats->retries) ||
672 nla_put_u32(vendor_event,
673 QCA_WLAN_VENDOR_ATTR_LL_STATS_RATE_RETRIES_SHORT,
674 stats->retriesShort ) ||
675 nla_put_u32(vendor_event,
676 QCA_WLAN_VENDOR_ATTR_LL_STATS_RATE_RETRIES_LONG,
677 stats->retriesLong))
678 {
679 hddLog(VOS_TRACE_LEVEL_ERROR,
680 FL("QCA_WLAN_VENDOR_ATTR put fail"));
681 return FALSE;
682 }
683 return TRUE;
684}
685
686static v_BOOL_t put_wifi_peer_info( tpSirWifiPeerInfo stats,
687 struct sk_buff *vendor_event)
688{
689 u32 i = 0;
690 struct nlattr *rateInfo;
691 if (nla_put_u32(vendor_event, QCA_WLAN_VENDOR_ATTR_LL_STATS_PEER_INFO_TYPE,
692 stats->type) ||
693 nla_put(vendor_event,
694 QCA_WLAN_VENDOR_ATTR_LL_STATS_PEER_INFO_MAC_ADDRESS,
695 VOS_MAC_ADDR_SIZE, &stats->peerMacAddress[0]) ||
696 nla_put_u32(vendor_event,
697 QCA_WLAN_VENDOR_ATTR_LL_STATS_PEER_INFO_CAPABILITIES,
698 stats->capabilities) ||
699 nla_put_u32(vendor_event,
700 QCA_WLAN_VENDOR_ATTR_LL_STATS_PEER_INFO_NUM_RATES,
701 stats->numRate))
702 {
703 hddLog(VOS_TRACE_LEVEL_ERROR,
704 FL("QCA_WLAN_VENDOR_ATTR put fail"));
705 goto error;
706 }
707
708 rateInfo = nla_nest_start(vendor_event,
709 QCA_WLAN_VENDOR_ATTR_LL_STATS_PEER_INFO_RATE_INFO);
710 for (i = 0; i < stats->numRate; i++)
711 {
712 struct nlattr *rates;
713 tpSirWifiRateStat pRateStats = (tpSirWifiRateStat )((uint8 *)
714 stats->rateStats +
715 (i * sizeof(tSirWifiRateStat)));
716 rates = nla_nest_start(vendor_event, i);
717
718 if (FALSE == put_wifi_rate_stat(pRateStats, vendor_event))
719 {
720 hddLog(VOS_TRACE_LEVEL_ERROR,
721 FL("QCA_WLAN_VENDOR_ATTR put fail"));
722 return FALSE;
723 }
724 nla_nest_end(vendor_event, rates);
725 }
726 nla_nest_end(vendor_event, rateInfo);
727
728 return TRUE;
729error:
730 return FALSE;
731}
732
733static v_BOOL_t put_wifi_wmm_ac_stat( tpSirWifiWmmAcStat stats,
734 struct sk_buff *vendor_event)
735{
736 if (nla_put_u32(vendor_event, QCA_WLAN_VENDOR_ATTR_LL_STATS_WMM_AC_AC,
737 stats->ac ) ||
738 nla_put_u32(vendor_event,
739 QCA_WLAN_VENDOR_ATTR_LL_STATS_WMM_AC_TX_MPDU,
740 stats->txMpdu ) ||
741 nla_put_u32(vendor_event,
742 QCA_WLAN_VENDOR_ATTR_LL_STATS_WMM_AC_RX_MPDU,
743 stats->rxMpdu ) ||
744 nla_put_u32(vendor_event,
745 QCA_WLAN_VENDOR_ATTR_LL_STATS_WMM_AC_TX_MCAST,
746 stats->txMcast ) ||
747 nla_put_u32(vendor_event,
748 QCA_WLAN_VENDOR_ATTR_LL_STATS_WMM_AC_RX_MCAST,
749 stats->rxMcast ) ||
750 nla_put_u32(vendor_event,
751 QCA_WLAN_VENDOR_ATTR_LL_STATS_WMM_AC_RX_AMPDU,
752 stats->rxAmpdu ) ||
753 nla_put_u32(vendor_event,
754 QCA_WLAN_VENDOR_ATTR_LL_STATS_WMM_AC_TX_AMPDU,
755 stats->txAmpdu ) ||
756 nla_put_u32(vendor_event,
757 QCA_WLAN_VENDOR_ATTR_LL_STATS_WMM_AC_MPDU_LOST,
758 stats->mpduLost )||
759 nla_put_u32(vendor_event,
760 QCA_WLAN_VENDOR_ATTR_LL_STATS_WMM_AC_RETRIES,
761 stats->retries ) ||
762 nla_put_u32(vendor_event,
763 QCA_WLAN_VENDOR_ATTR_LL_STATS_WMM_AC_RETRIES_SHORT,
764 stats->retriesShort ) ||
765 nla_put_u32(vendor_event,
766 QCA_WLAN_VENDOR_ATTR_LL_STATS_WMM_AC_RETRIES_LONG,
767 stats->retriesLong ) ||
768 nla_put_u32(vendor_event,
769 QCA_WLAN_VENDOR_ATTR_LL_STATS_WMM_AC_CONTENTION_TIME_MIN,
770 stats->contentionTimeMin ) ||
771 nla_put_u32(vendor_event,
772 QCA_WLAN_VENDOR_ATTR_LL_STATS_WMM_AC_CONTENTION_TIME_MAX,
773 stats->contentionTimeMax ) ||
774 nla_put_u32(vendor_event,
775 QCA_WLAN_VENDOR_ATTR_LL_STATS_WMM_AC_CONTENTION_TIME_AVG,
776 stats->contentionTimeAvg ) ||
777 nla_put_u32(vendor_event,
778 QCA_WLAN_VENDOR_ATTR_LL_STATS_WMM_AC_CONTENTION_NUM_SAMPLES,
779 stats->contentionNumSamples ))
780 {
781 hddLog(VOS_TRACE_LEVEL_ERROR,
782 FL("QCA_WLAN_VENDOR_ATTR put fail") );
783 return FALSE;
784 }
785 return TRUE;
786}
787
788static v_BOOL_t put_wifi_interface_info(tpSirWifiInterfaceInfo stats,
789 struct sk_buff *vendor_event)
790{
Dino Myclec8f3f332014-07-21 16:48:27 +0530791 if (nla_put_s32(vendor_event,
Sunil Duttc69bccb2014-05-26 21:30:20 +0530792 QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_INFO_MODE, stats->mode ) ||
793 nla_put(vendor_event,
794 QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_INFO_MAC_ADDR,
795 VOS_MAC_ADDR_SIZE, stats->macAddr) ||
796 nla_put_u32(vendor_event,
797 QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_INFO_STATE,
798 stats->state ) ||
799 nla_put_u32(vendor_event,
800 QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_INFO_ROAMING,
801 stats->roaming ) ||
802 nla_put_u32(vendor_event,
803 QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_INFO_CAPABILITIES,
804 stats->capabilities ) ||
805 nla_put(vendor_event,
806 QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_INFO_SSID,
807 strlen(stats->ssid), stats->ssid) ||
808 nla_put(vendor_event,
809 QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_INFO_BSSID,
810 WNI_CFG_BSSID_LEN, stats->bssid) ||
811 nla_put(vendor_event,
812 QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_INFO_AP_COUNTRY_STR,
813 WNI_CFG_COUNTRY_CODE_LEN, stats->apCountryStr) ||
814 nla_put(vendor_event,
815 QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_INFO_COUNTRY_STR,
816 WNI_CFG_COUNTRY_CODE_LEN, stats->countryStr)
817 )
818 {
819 hddLog(VOS_TRACE_LEVEL_ERROR,
820 FL("QCA_WLAN_VENDOR_ATTR put fail") );
821 return FALSE;
822 }
823 return TRUE;
824}
825
Dino Mycle3b9536d2014-07-09 22:05:24 +0530826static v_BOOL_t put_wifi_iface_stats(hdd_adapter_t *pAdapter,
827 tpSirWifiIfaceStat pWifiIfaceStat,
Sunil Duttc69bccb2014-05-26 21:30:20 +0530828 struct sk_buff *vendor_event)
829{
830 int i = 0;
831 struct nlattr *wmmInfo;
Dino Mycle3b9536d2014-07-09 22:05:24 +0530832 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
833 WLANTL_InterfaceStatsType *pWifiIfaceStatTL = NULL;
834
Sunil Duttc69bccb2014-05-26 21:30:20 +0530835 if (FALSE == put_wifi_interface_info(
836 &pWifiIfaceStat->info,
837 vendor_event))
838 {
839 hddLog(VOS_TRACE_LEVEL_ERROR,
840 FL("QCA_WLAN_VENDOR_ATTR put fail") );
841 return FALSE;
842
843 }
Dino Mycle3b9536d2014-07-09 22:05:24 +0530844 pWifiIfaceStatTL = (WLANTL_InterfaceStatsType *)
845 vos_mem_malloc(sizeof(WLANTL_InterfaceStatsType));
846 if (NULL == pWifiIfaceStatTL)
847 {
848 hddLog(VOS_TRACE_LEVEL_ERROR, FL("vos_mem_malloc failed"));
849 return FALSE;
850 }
851
852
853 if ( pWifiIfaceStat->info.state == WIFI_ASSOCIATED)
854 {
855 if (VOS_STATUS_SUCCESS ==
856 WLANTL_CollectInterfaceStats((WLAN_HDD_GET_CTX(pAdapter))->pvosContext,
857 pHddStaCtx->conn_info.staId[0], pWifiIfaceStatTL))
858 {
859 /* mgmtRx, MgmtActionRx, rxMcast, rxMpdu, rxAmpdu, rssiData are
860 * obtained from TL structure
861 */
862
863 pWifiIfaceStat->mgmtRx = pWifiIfaceStat->beaconRx +
864 pWifiIfaceStatTL->mgmtRx;
865 pWifiIfaceStat->mgmtActionRx = pWifiIfaceStatTL->mgmtActionRx;
866 pWifiIfaceStat->mgmtActionTx = pWifiIfaceStatTL->mgmtActionTx;
867 pWifiIfaceStat->rssiData = pWifiIfaceStatTL->rssiData;
868
869 vos_mem_copy(
870 (void *) &pWifiIfaceStat->AccessclassStats[WIFI_AC_VO],
871 (void *) &pWifiIfaceStatTL->accessCategoryStats[WLANTL_AC_VO],
872 sizeof(WLANTL_AccessCategoryStatsType));
873
874 vos_mem_copy(
875 (void *) &pWifiIfaceStat->AccessclassStats[WIFI_AC_VI],
876 (void *) &pWifiIfaceStatTL->accessCategoryStats[WLANTL_AC_VI],
877 sizeof(WLANTL_AccessCategoryStatsType));
878
879 vos_mem_copy(
880 (void *) &pWifiIfaceStat->AccessclassStats[WIFI_AC_BE],
881 (void *) &pWifiIfaceStatTL->accessCategoryStats[WLANTL_AC_BE],
882 sizeof(WLANTL_AccessCategoryStatsType));
883
884 vos_mem_copy(
885 (void *) &pWifiIfaceStat->AccessclassStats[WIFI_AC_BK],
886 (void *) &pWifiIfaceStatTL->accessCategoryStats[WLANTL_AC_BK],
887 sizeof(WLANTL_AccessCategoryStatsType));
888 }
889 else
890 {
891 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Error in getting stats from TL"));
892 }
893
894 pWifiIfaceStat->AccessclassStats[WIFI_AC_VO].txMpdu =
895 pAdapter->hdd_stats.hddTxRxStats.txFetchedAC[WLANTL_AC_VO];
896 pWifiIfaceStat->AccessclassStats[WIFI_AC_VI].txMpdu =
897 pAdapter->hdd_stats.hddTxRxStats.txFetchedAC[WLANTL_AC_VI];
898 pWifiIfaceStat->AccessclassStats[WIFI_AC_BE].txMpdu =
899 pAdapter->hdd_stats.hddTxRxStats.txFetchedAC[WLANTL_AC_BE];
900 pWifiIfaceStat->AccessclassStats[WIFI_AC_BK].txMpdu =
901 pAdapter->hdd_stats.hddTxRxStats.txFetchedAC[WLANTL_AC_BK];
902
903 pWifiIfaceStat->AccessclassStats[WIFI_AC_VO].txMcast =
904 pAdapter->hdd_stats.hddTxRxStats.txMcast[WLANTL_AC_VO];
905 pWifiIfaceStat->AccessclassStats[WIFI_AC_VI].txMcast =
906 pAdapter->hdd_stats.hddTxRxStats.txMcast[WLANTL_AC_VI];
907 pWifiIfaceStat->AccessclassStats[WIFI_AC_BE].txMcast =
908 pAdapter->hdd_stats.hddTxRxStats.txMcast[WLANTL_AC_BE];
909 pWifiIfaceStat->AccessclassStats[WIFI_AC_BK].txMcast =
910 pAdapter->hdd_stats.hddTxRxStats.txMcast[WLANTL_AC_BK];
911 }
912 else
913 {
914 hddLog(VOS_TRACE_LEVEL_INFO, FL("Interface not Associated"));
915 }
916
917
Sunil Duttc69bccb2014-05-26 21:30:20 +0530918
919 if (nla_put_u32(vendor_event,
920 QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_BEACON_RX,
921 pWifiIfaceStat->beaconRx) ||
922 nla_put_u32(vendor_event,
923 QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_MGMT_RX,
924 pWifiIfaceStat->mgmtRx) ||
925 nla_put_u32(vendor_event,
926 QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_MGMT_ACTION_RX,
927 pWifiIfaceStat->mgmtActionRx) ||
928 nla_put_u32(vendor_event,
929 QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_MGMT_ACTION_TX,
930 pWifiIfaceStat->mgmtActionTx) ||
Dino Mycle3b9536d2014-07-09 22:05:24 +0530931 nla_put_s32(vendor_event,
Sunil Duttc69bccb2014-05-26 21:30:20 +0530932 QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_RSSI_MGMT,
933 pWifiIfaceStat->rssiMgmt) ||
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_DATA,
936 pWifiIfaceStat->rssiData) ||
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_ACK,
939 pWifiIfaceStat->rssiAck))
940 {
941 hddLog(VOS_TRACE_LEVEL_ERROR,
942 FL("QCA_WLAN_VENDOR_ATTR put fail"));
Dino Mycle3b9536d2014-07-09 22:05:24 +0530943 vos_mem_free(pWifiIfaceStatTL);
Sunil Duttc69bccb2014-05-26 21:30:20 +0530944 return FALSE;
945 }
946
947 wmmInfo = nla_nest_start(vendor_event,
948 QCA_WLAN_VENDOR_ATTR_LL_STATS_WMM_INFO);
949 for (i = 0; i < WIFI_AC_MAX; i++)
950 {
951 struct nlattr *wmmStats;
952 wmmStats = nla_nest_start(vendor_event, i);
953 if (FALSE == put_wifi_wmm_ac_stat(
954 &pWifiIfaceStat->AccessclassStats[i],
955 vendor_event))
956 {
957 hddLog(VOS_TRACE_LEVEL_ERROR,
958 FL("QCA_WLAN_VENDOR_ATTR put Fail"));
Dino Mycle3b9536d2014-07-09 22:05:24 +0530959 vos_mem_free(pWifiIfaceStatTL);
Sunil Duttc69bccb2014-05-26 21:30:20 +0530960 return FALSE;
961 }
962
963 nla_nest_end(vendor_event, wmmStats);
964 }
965 nla_nest_end(vendor_event, wmmInfo);
Dino Mycle3b9536d2014-07-09 22:05:24 +0530966 vos_mem_free(pWifiIfaceStatTL);
Sunil Duttc69bccb2014-05-26 21:30:20 +0530967 return TRUE;
968}
969
970static tSirWifiInterfaceMode
971 hdd_map_device_to_ll_iface_mode ( int deviceMode )
972{
973 switch (deviceMode)
974 {
975 case WLAN_HDD_INFRA_STATION:
976 return WIFI_INTERFACE_STA;
977 case WLAN_HDD_SOFTAP:
978 return WIFI_INTERFACE_SOFTAP;
979 case WLAN_HDD_P2P_CLIENT:
980 return WIFI_INTERFACE_P2P_CLIENT;
981 case WLAN_HDD_P2P_GO:
982 return WIFI_INTERFACE_P2P_GO;
983 case WLAN_HDD_IBSS:
984 return WIFI_INTERFACE_IBSS;
985 default:
Dino Myclec8f3f332014-07-21 16:48:27 +0530986 return WIFI_INTERFACE_UNKNOWN;
Sunil Duttc69bccb2014-05-26 21:30:20 +0530987 }
988}
989
990static v_BOOL_t hdd_get_interface_info(hdd_adapter_t *pAdapter,
991 tpSirWifiInterfaceInfo pInfo)
992{
993 v_U8_t *staMac = NULL;
994 hdd_station_ctx_t *pHddStaCtx;
995 tHalHandle hHal = WLAN_HDD_GET_HAL_CTX(pAdapter);
996 tpAniSirGlobal pMac = PMAC_STRUCT( hHal );
997
998 pInfo->mode = hdd_map_device_to_ll_iface_mode(pAdapter->device_mode);
999
1000 vos_mem_copy(pInfo->macAddr,
1001 pAdapter->macAddressCurrent.bytes, sizeof(v_MACADDR_t));
1002
1003 if (((WLAN_HDD_INFRA_STATION == pAdapter->device_mode) ||
1004 (WLAN_HDD_P2P_CLIENT == pAdapter->device_mode) ||
1005 (WLAN_HDD_P2P_DEVICE == pAdapter->device_mode)))
1006 {
1007 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
1008 if (eConnectionState_NotConnected == pHddStaCtx->conn_info.connState)
1009 {
1010 pInfo->state = WIFI_DISCONNECTED;
1011 }
1012 if (eConnectionState_Connecting == pHddStaCtx->conn_info.connState)
1013 {
1014 hddLog(VOS_TRACE_LEVEL_ERROR,
1015 "%s: Session ID %d, Connection is in progress", __func__,
1016 pAdapter->sessionId);
1017 pInfo->state = WIFI_ASSOCIATING;
1018 }
1019 if ((eConnectionState_Associated == pHddStaCtx->conn_info.connState) &&
1020 (VOS_FALSE == pHddStaCtx->conn_info.uIsAuthenticated))
1021 {
1022 staMac = (v_U8_t *) &(pAdapter->macAddressCurrent.bytes[0]);
1023 hddLog(VOS_TRACE_LEVEL_ERROR,
1024 "%s: client " MAC_ADDRESS_STR
1025 " is in the middle of WPS/EAPOL exchange.", __func__,
1026 MAC_ADDR_ARRAY(staMac));
1027 pInfo->state = WIFI_AUTHENTICATING;
1028 }
1029 if (eConnectionState_Associated == pHddStaCtx->conn_info.connState)
1030 {
1031 pInfo->state = WIFI_ASSOCIATED;
1032 vos_mem_copy(pInfo->bssid,
1033 &pHddStaCtx->conn_info.bssId, WNI_CFG_BSSID_LEN);
1034 vos_mem_copy(pInfo->ssid,
1035 pHddStaCtx->conn_info.SSID.SSID.ssId,
1036 pHddStaCtx->conn_info.SSID.SSID.length);
1037 //NULL Terminate the string.
1038 pInfo->ssid[pHddStaCtx->conn_info.SSID.SSID.length] = 0;
1039 }
1040 }
1041 vos_mem_copy(pInfo->countryStr,
1042 pMac->scan.countryCodeCurrent, WNI_CFG_COUNTRY_CODE_LEN);
1043
1044 vos_mem_copy(pInfo->apCountryStr,
1045 pMac->scan.countryCodeCurrent, WNI_CFG_COUNTRY_CODE_LEN);
1046
1047 return TRUE;
1048}
1049
1050/*
1051 * hdd_link_layer_process_peer_stats () - This function is called after
1052 * receiving Link Layer Peer statistics from FW.This function converts
1053 * the firmware data to the NL data and sends the same to the kernel/upper
1054 * layers.
1055 */
1056static v_VOID_t hdd_link_layer_process_peer_stats(hdd_adapter_t *pAdapter,
1057 v_VOID_t *pData)
1058{
1059 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
1060 tpSirWifiRateStat pWifiRateStat;
1061 tpSirWifiPeerStat pWifiPeerStat;
1062 tpSirWifiPeerInfo pWifiPeerInfo;
1063 struct nlattr *peerInfo;
1064 struct sk_buff *vendor_event;
1065 int status, i;
1066
1067 status = wlan_hdd_validate_context(pHddCtx);
1068 if (0 != status)
1069 {
1070 hddLog(VOS_TRACE_LEVEL_ERROR,
1071 FL("HDD context is not valid") );
1072 return;
1073 }
1074
1075 pWifiPeerStat = (tpSirWifiPeerStat) pData;
1076
1077 hddLog(VOS_TRACE_LEVEL_INFO,
1078 "LL_STATS_PEER_ALL : numPeers %u",
1079 pWifiPeerStat->numPeers);
1080 {
1081 for (i = 0; i < pWifiPeerStat->numPeers; i++)
1082 {
1083 pWifiPeerInfo = (tpSirWifiPeerInfo)
1084 ((uint8 *)pWifiPeerStat->peerInfo +
1085 ( i * sizeof(tSirWifiPeerInfo)));
1086
1087 hddLog(VOS_TRACE_LEVEL_INFO,
1088 " %d) LL_STATS Channel Stats "
1089 " Peer Type %u "
1090 " peerMacAddress %pM "
1091 " capabilities 0x%x "
1092 " numRate %u ",
1093 i,
1094 pWifiPeerInfo->type,
1095 pWifiPeerInfo->peerMacAddress,
1096 pWifiPeerInfo->capabilities,
1097 pWifiPeerInfo->numRate);
1098 {
1099 int j;
1100 for (j = 0; j < pWifiPeerInfo->numRate; j++)
1101 {
1102 pWifiRateStat = (tpSirWifiRateStat)
1103 ((tANI_U8 *) pWifiPeerInfo->rateStats +
1104 ( j * sizeof(tSirWifiRateStat)));
1105
1106 hddLog(VOS_TRACE_LEVEL_INFO,
1107 " peer Rate Stats "
1108 " preamble %u "
1109 " nss %u "
1110 " bw %u "
1111 " rateMcsIdx %u "
1112 " reserved %u "
1113 " bitrate %u "
1114 " txMpdu %u "
1115 " rxMpdu %u "
1116 " mpduLost %u "
1117 " retries %u "
1118 " retriesShort %u "
1119 " retriesLong %u",
1120 pWifiRateStat->rate.preamble,
1121 pWifiRateStat->rate.nss,
1122 pWifiRateStat->rate.bw,
1123 pWifiRateStat->rate.rateMcsIdx,
1124 pWifiRateStat->rate.reserved,
1125 pWifiRateStat->rate.bitrate,
1126 pWifiRateStat->txMpdu,
1127 pWifiRateStat->rxMpdu,
1128 pWifiRateStat->mpduLost,
1129 pWifiRateStat->retries,
1130 pWifiRateStat->retriesShort,
1131 pWifiRateStat->retriesLong);
1132 }
1133 }
1134 }
1135 }
1136
1137 /*
1138 * Allocate a size of 4096 for the peer stats comprising
1139 * each of size = sizeof (tSirWifiPeerInfo) + numRate *
1140 * sizeof (tSirWifiRateStat).Each field is put with an
1141 * NL attribute.The size of 4096 is considered assuming
1142 * that number of rates shall not exceed beyond 50 with
1143 * the sizeof (tSirWifiRateStat) being 32.
1144 */
1145 vendor_event = cfg80211_vendor_event_alloc(pHddCtx->wiphy,
1146 LL_STATS_EVENT_BUF_SIZE + NLMSG_HDRLEN,
1147 QCA_NL80211_VENDOR_SUBCMD_LL_PEER_INFO_STATS_INDEX,
1148 GFP_KERNEL);
1149 if (!vendor_event)
1150 {
1151 hddLog(VOS_TRACE_LEVEL_ERROR,
1152 "%s: cfg80211_vendor_event_alloc failed",
1153 __func__);
1154 return;
1155 }
1156 if (nla_put_u32(vendor_event,
1157 QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_NUM_PEERS,
1158 pWifiPeerStat->numPeers))
1159 {
1160 hddLog(VOS_TRACE_LEVEL_ERROR,
1161 "%s: QCA_WLAN_VENDOR_ATTR put fail", __func__);
1162 kfree_skb(vendor_event);
1163 return;
1164 }
1165
1166 peerInfo = nla_nest_start(vendor_event,
1167 QCA_WLAN_VENDOR_ATTR_LL_STATS_PEER_INFO);
1168
1169 pWifiPeerInfo = (tpSirWifiPeerInfo) ((uint8 *)
1170 pWifiPeerStat->peerInfo);
1171
1172 for (i = 1; i <= pWifiPeerStat->numPeers; i++)
1173 {
1174 struct nlattr *peers = nla_nest_start(vendor_event, i);
1175 int numRate = pWifiPeerInfo->numRate;
1176
1177 if (FALSE == put_wifi_peer_info(
1178 pWifiPeerInfo, vendor_event))
1179 {
1180 hddLog(VOS_TRACE_LEVEL_ERROR,
1181 "%s: put_wifi_peer_info put fail", __func__);
1182 kfree_skb(vendor_event);
1183 return;
1184 }
1185
1186 pWifiPeerInfo = (tpSirWifiPeerInfo) ((uint8 *)
1187 pWifiPeerStat->peerInfo +
1188 (i * sizeof(tSirWifiPeerInfo)) +
1189 (numRate * sizeof (tSirWifiRateStat)));
1190 nla_nest_end(vendor_event, peers);
1191 }
1192 nla_nest_end(vendor_event, peerInfo);
1193 cfg80211_vendor_event(vendor_event, GFP_KERNEL);
1194}
1195
1196/*
1197 * hdd_link_layer_process_iface_stats () - This function is called after
1198 * receiving Link Layer Interface statistics from FW.This function converts
1199 * the firmware data to the NL data and sends the same to the kernel/upper
1200 * layers.
1201 */
1202static v_VOID_t hdd_link_layer_process_iface_stats(hdd_adapter_t *pAdapter,
1203 v_VOID_t *pData)
1204{
1205 tpSirWifiIfaceStat pWifiIfaceStat;
1206 struct sk_buff *vendor_event;
1207 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
1208 int status;
1209
1210 status = wlan_hdd_validate_context(pHddCtx);
1211 if (0 != status)
1212 {
1213 hddLog(VOS_TRACE_LEVEL_ERROR,
1214 FL("HDD context is not valid") );
1215 return;
1216 }
1217 /*
1218 * Allocate a size of 4096 for the interface stats comprising
1219 * sizeof (tpSirWifiIfaceStat).The size of 4096 is considered
1220 * assuming that all these fit with in the limit.Please take
1221 * a call on the limit based on the data requirements on
1222 * interface statistics.
1223 */
1224 vendor_event = cfg80211_vendor_event_alloc(pHddCtx->wiphy,
1225 LL_STATS_EVENT_BUF_SIZE + NLMSG_HDRLEN,
1226 QCA_NL80211_VENDOR_SUBCMD_LL_IFACE_STATS_INDEX,
1227 GFP_KERNEL);
1228 if (!vendor_event)
1229 {
1230 hddLog(VOS_TRACE_LEVEL_ERROR,
1231 FL("cfg80211_vendor_event_alloc failed") );
1232 return;
1233 }
1234
1235 pWifiIfaceStat = (tpSirWifiIfaceStat) pData;
1236
Dino Mycle3b9536d2014-07-09 22:05:24 +05301237
1238 if (FALSE == hdd_get_interface_info( pAdapter,
1239 &pWifiIfaceStat->info))
1240 {
1241 hddLog(VOS_TRACE_LEVEL_ERROR,
1242 FL("hdd_get_interface_info get fail") );
1243 kfree_skb(vendor_event);
1244 return;
1245 }
1246
1247 if (FALSE == put_wifi_iface_stats( pAdapter, pWifiIfaceStat,
1248 vendor_event))
1249 {
1250 hddLog(VOS_TRACE_LEVEL_ERROR,
1251 FL("put_wifi_iface_stats fail") );
1252 kfree_skb(vendor_event);
1253 return;
1254 }
1255
Sunil Duttc69bccb2014-05-26 21:30:20 +05301256 hddLog(VOS_TRACE_LEVEL_INFO,
1257 "WMI_LINK_STATS_IFACE Data");
1258
1259 hddLog(VOS_TRACE_LEVEL_INFO,
1260 "LL_STATS_IFACE: "
1261 " Mode %u "
1262 " MAC %pM "
1263 " State %u "
1264 " Roaming %u "
1265 " capabilities 0x%x "
1266 " SSID %s "
1267 " BSSID %pM",
1268 pWifiIfaceStat->info.mode,
1269 pWifiIfaceStat->info.macAddr,
1270 pWifiIfaceStat->info.state,
1271 pWifiIfaceStat->info.roaming,
1272 pWifiIfaceStat->info.capabilities,
1273 pWifiIfaceStat->info.ssid,
1274 pWifiIfaceStat->info.bssid);
1275
1276 hddLog(VOS_TRACE_LEVEL_INFO,
1277 " AP country str: %c%c%c",
1278 pWifiIfaceStat->info.apCountryStr[0],
1279 pWifiIfaceStat->info.apCountryStr[1],
1280 pWifiIfaceStat->info.apCountryStr[2]);
1281
1282
1283 hddLog(VOS_TRACE_LEVEL_INFO,
1284 " Country Str Association: %c%c%c",
1285 pWifiIfaceStat->info.countryStr[0],
1286 pWifiIfaceStat->info.countryStr[1],
1287 pWifiIfaceStat->info.countryStr[2]);
1288
1289 hddLog(VOS_TRACE_LEVEL_INFO,
1290 " beaconRx %u "
1291 " mgmtRx %u "
1292 " mgmtActionRx %u "
1293 " mgmtActionTx %u "
Dino Mycle3b9536d2014-07-09 22:05:24 +05301294 " rssiMgmt %d "
1295 " rssiData %d "
1296 " rssiAck %d",
Sunil Duttc69bccb2014-05-26 21:30:20 +05301297 pWifiIfaceStat->beaconRx,
1298 pWifiIfaceStat->mgmtRx,
1299 pWifiIfaceStat->mgmtActionRx,
1300 pWifiIfaceStat->mgmtActionTx,
1301 pWifiIfaceStat->rssiMgmt,
1302 pWifiIfaceStat->rssiData,
1303 pWifiIfaceStat->rssiAck );
1304
1305
1306 {
1307 int i;
1308 for (i = 0 ; i < WIFI_AC_MAX; i ++)
1309 {
1310 hddLog(VOS_TRACE_LEVEL_INFO,
1311
1312 " %d) LL_STATS IFACE: "
1313 " ac: %u txMpdu: %u "
1314 " rxMpdu: %u txMcast: %u "
1315 " rxMcast: %u rxAmpdu: %u "
1316 " txAmpdu: %u mpduLost: %u "
1317 " retries: %u retriesShort: %u "
1318 " retriesLong: %u contentionTimeMin: %u "
1319 " contentionTimeMax: %u contentionTimeAvg: %u "
1320 " contentionNumSamples: %u",
1321 i,
1322 pWifiIfaceStat->AccessclassStats[i].ac,
1323 pWifiIfaceStat->AccessclassStats[i].txMpdu,
1324 pWifiIfaceStat->AccessclassStats[i].rxMpdu,
1325 pWifiIfaceStat->AccessclassStats[i].txMcast,
1326 pWifiIfaceStat->AccessclassStats[i].rxMcast,
1327 pWifiIfaceStat->AccessclassStats[i].rxAmpdu,
1328 pWifiIfaceStat->AccessclassStats[i].txAmpdu,
1329 pWifiIfaceStat->AccessclassStats[i].mpduLost,
1330 pWifiIfaceStat->AccessclassStats[i].retries,
1331 pWifiIfaceStat->
1332 AccessclassStats[i].retriesShort,
1333 pWifiIfaceStat->AccessclassStats[i].retriesLong,
1334 pWifiIfaceStat->
1335 AccessclassStats[i].contentionTimeMin,
1336 pWifiIfaceStat->
1337 AccessclassStats[i].contentionTimeMax,
1338 pWifiIfaceStat->
1339 AccessclassStats[i].contentionTimeAvg,
1340 pWifiIfaceStat->
1341 AccessclassStats[i].contentionNumSamples);
1342
1343 }
1344 }
1345
Sunil Duttc69bccb2014-05-26 21:30:20 +05301346 cfg80211_vendor_event(vendor_event, GFP_KERNEL);
1347}
1348
1349/*
1350 * hdd_link_layer_process_radio_stats () - This function is called after
1351 * receiving Link Layer Radio statistics from FW.This function converts
1352 * the firmware data to the NL data and sends the same to the kernel/upper
1353 * layers.
1354 */
1355static v_VOID_t hdd_link_layer_process_radio_stats(hdd_adapter_t *pAdapter,
1356 v_VOID_t *pData)
1357{
1358 int status, i;
1359 tpSirWifiRadioStat pWifiRadioStat;
1360 tpSirWifiChannelStats pWifiChannelStats;
1361 struct sk_buff *vendor_event;
1362 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
1363 struct nlattr *chList;
1364
1365 status = wlan_hdd_validate_context(pHddCtx);
1366 if (0 != status)
1367 {
1368 hddLog(VOS_TRACE_LEVEL_ERROR,
1369 FL("HDD context is not valid") );
1370 return;
1371 }
1372 pWifiRadioStat = (tpSirWifiRadioStat) pData;
1373
1374 hddLog(VOS_TRACE_LEVEL_INFO,
1375 "LL_STATS_RADIO"
1376 " radio is %d onTime is %u "
1377 " txTime is %u rxTime is %u "
1378 " onTimeScan is %u onTimeNbd is %u "
Dino Mycle6fb96c12014-06-10 11:52:40 +05301379 " onTimeEXTScan is %u onTimeRoamScan is %u "
Sunil Duttc69bccb2014-05-26 21:30:20 +05301380 " onTimePnoScan is %u onTimeHs20 is %u "
1381 " numChannels is %u",
1382 pWifiRadioStat->radio, pWifiRadioStat->onTime,
1383 pWifiRadioStat->txTime, pWifiRadioStat->rxTime,
1384 pWifiRadioStat->onTimeScan, pWifiRadioStat->onTimeNbd,
Dino Mycle6fb96c12014-06-10 11:52:40 +05301385 pWifiRadioStat->onTimeEXTScan,
Sunil Duttc69bccb2014-05-26 21:30:20 +05301386 pWifiRadioStat->onTimeRoamScan,
1387 pWifiRadioStat->onTimePnoScan,
1388 pWifiRadioStat->onTimeHs20,
1389 pWifiRadioStat->numChannels);
1390 /*
1391 * Allocate a size of 4096 for the Radio stats comprising
1392 * sizeof (tSirWifiRadioStat) + numChannels * sizeof
1393 * (tSirWifiChannelStats).Each channel data is put with an
1394 * NL attribute.The size of 4096 is considered assuming that
1395 * number of channels shall not exceed beyond 60 with the
1396 * sizeof (tSirWifiChannelStats) being 24 bytes.
1397 */
1398
1399 vendor_event = cfg80211_vendor_event_alloc(pHddCtx->wiphy,
1400 LL_STATS_EVENT_BUF_SIZE + NLMSG_HDRLEN ,
1401 QCA_NL80211_VENDOR_SUBCMD_LL_RADIO_STATS_INDEX,
1402 GFP_KERNEL);
1403
1404 if (!vendor_event)
1405 {
1406 hddLog(VOS_TRACE_LEVEL_ERROR,
1407 FL("cfg80211_vendor_event_alloc failed") );
1408 return;
1409 }
1410
1411 if (nla_put_u32(vendor_event,
1412 QCA_WLAN_VENDOR_ATTR_LL_STATS_RADIO_ID,
1413 pWifiRadioStat->radio) ||
1414 nla_put_u32(vendor_event,
1415 QCA_WLAN_VENDOR_ATTR_LL_STATS_RADIO_ON_TIME,
1416 pWifiRadioStat->onTime) ||
1417 nla_put_u32(vendor_event,
1418 QCA_WLAN_VENDOR_ATTR_LL_STATS_RADIO_TX_TIME,
1419 pWifiRadioStat->txTime) ||
1420 nla_put_u32(vendor_event,
1421 QCA_WLAN_VENDOR_ATTR_LL_STATS_RADIO_RX_TIME,
1422 pWifiRadioStat->rxTime) ||
1423 nla_put_u32(vendor_event,
1424 QCA_WLAN_VENDOR_ATTR_LL_STATS_RADIO_ON_TIME_SCAN,
1425 pWifiRadioStat->onTimeScan) ||
1426 nla_put_u32(vendor_event,
1427 QCA_WLAN_VENDOR_ATTR_LL_STATS_RADIO_ON_TIME_NBD,
1428 pWifiRadioStat->onTimeNbd) ||
1429 nla_put_u32(vendor_event,
Dino Mycle6fb96c12014-06-10 11:52:40 +05301430 QCA_WLAN_VENDOR_ATTR_LL_STATS_RADIO_ON_TIME_EXTSCAN,
1431 pWifiRadioStat->onTimeEXTScan)||
Sunil Duttc69bccb2014-05-26 21:30:20 +05301432 nla_put_u32(vendor_event,
1433 QCA_WLAN_VENDOR_ATTR_LL_STATS_RADIO_ON_TIME_ROAM_SCAN,
1434 pWifiRadioStat->onTimeRoamScan) ||
1435 nla_put_u32(vendor_event,
1436 QCA_WLAN_VENDOR_ATTR_LL_STATS_RADIO_ON_TIME_PNO_SCAN,
1437 pWifiRadioStat->onTimePnoScan) ||
1438 nla_put_u32(vendor_event,
1439 QCA_WLAN_VENDOR_ATTR_LL_STATS_RADIO_ON_TIME_HS20,
1440 pWifiRadioStat->onTimeHs20) ||
1441 nla_put_u32(vendor_event,
1442 QCA_WLAN_VENDOR_ATTR_LL_STATS_RADIO_NUM_CHANNELS,
1443 pWifiRadioStat->numChannels))
1444 {
1445 hddLog(VOS_TRACE_LEVEL_ERROR,
1446 FL("QCA_WLAN_VENDOR_ATTR put fail"));
1447 kfree_skb(vendor_event);
1448 return ;
1449 }
1450
1451 chList = nla_nest_start(vendor_event,
1452 QCA_WLAN_VENDOR_ATTR_LL_STATS_CH_INFO);
1453 for (i = 0; i < pWifiRadioStat->numChannels; i++)
1454 {
1455 struct nlattr *chInfo;
1456
1457 pWifiChannelStats = (tpSirWifiChannelStats) ((uint8*)
1458 pWifiRadioStat->channels +
1459 (i * sizeof(tSirWifiChannelStats)));
1460
1461 hddLog(VOS_TRACE_LEVEL_INFO,
1462 " %d) Channel Info"
1463 " width is %u "
1464 " CenterFreq %u "
1465 " CenterFreq0 %u "
1466 " CenterFreq1 %u "
1467 " onTime %u "
1468 " ccaBusyTime %u",
1469 i,
1470 pWifiChannelStats->channel.width,
1471 pWifiChannelStats->channel.centerFreq,
1472 pWifiChannelStats->channel.centerFreq0,
1473 pWifiChannelStats->channel.centerFreq1,
1474 pWifiChannelStats->onTime,
1475 pWifiChannelStats->ccaBusyTime);
1476
1477
1478 chInfo = nla_nest_start(vendor_event, i);
1479
1480 if (nla_put_u32(vendor_event,
1481 QCA_WLAN_VENDOR_ATTR_LL_STATS_CHANNEL_INFO_WIDTH,
1482 pWifiChannelStats->channel.width) ||
1483 nla_put_u32(vendor_event,
1484 QCA_WLAN_VENDOR_ATTR_LL_STATS_CHANNEL_INFO_CENTER_FREQ,
1485 pWifiChannelStats->channel.centerFreq) ||
1486 nla_put_u32(vendor_event,
1487 QCA_WLAN_VENDOR_ATTR_LL_STATS_CHANNEL_INFO_CENTER_FREQ0,
1488 pWifiChannelStats->channel.centerFreq0) ||
1489 nla_put_u32(vendor_event,
1490 QCA_WLAN_VENDOR_ATTR_LL_STATS_CHANNEL_INFO_CENTER_FREQ1,
1491 pWifiChannelStats->channel.centerFreq1) ||
1492 nla_put_u32(vendor_event,
1493 QCA_WLAN_VENDOR_ATTR_LL_STATS_CHANNEL_ON_TIME,
1494 pWifiChannelStats->onTime) ||
1495 nla_put_u32(vendor_event,
1496 QCA_WLAN_VENDOR_ATTR_LL_STATS_CHANNEL_CCA_BUSY_TIME,
1497 pWifiChannelStats->ccaBusyTime))
1498 {
1499 hddLog(VOS_TRACE_LEVEL_ERROR,
1500 FL("cfg80211_vendor_event_alloc failed") );
1501 kfree_skb(vendor_event);
1502 return ;
1503 }
1504 nla_nest_end(vendor_event, chInfo);
1505 }
1506 nla_nest_end(vendor_event, chList);
1507
1508 cfg80211_vendor_event(vendor_event, GFP_KERNEL);
1509 return;
1510}
1511
1512/*
1513 * hdd_link_layer_stats_ind_callback () - This function is called after
1514 * receiving Link Layer indications from FW.This callback converts the firmware
1515 * data to the NL data and send the same to the kernel/upper layers.
1516 */
1517static void hdd_link_layer_stats_ind_callback ( void *pCtx,
1518 int indType,
Dino Mycled3d50022014-07-07 12:58:25 +05301519 void *pRsp, u8 *macAddr)
Sunil Duttc69bccb2014-05-26 21:30:20 +05301520{
Dino Mycled3d50022014-07-07 12:58:25 +05301521 hdd_context_t *pHddCtx = (hdd_context_t *)pCtx;
1522 hdd_adapter_t *pAdapter = NULL;
1523 tpSirLLStatsResults linkLayerStatsResults = (tpSirLLStatsResults)pRsp;
Sunil Duttc69bccb2014-05-26 21:30:20 +05301524 int status;
1525
1526 status = wlan_hdd_validate_context(pHddCtx);
1527
1528 if (0 != status)
1529 {
1530 hddLog(VOS_TRACE_LEVEL_ERROR,
1531 FL("HDD context is not valid"));
1532 return;
1533 }
1534
Dino Mycled3d50022014-07-07 12:58:25 +05301535
1536
1537 pAdapter = hdd_get_adapter_by_macaddr(pHddCtx, macAddr);
1538 if (NULL == pAdapter)
1539 {
1540 hddLog(VOS_TRACE_LEVEL_ERROR,
1541 FL(" MAC address %pM does not exist with host"),
1542 macAddr);
1543 return;
1544 }
1545
Sunil Duttc69bccb2014-05-26 21:30:20 +05301546 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Dino Mycled3d50022014-07-07 12:58:25 +05301547 "%s: Interface: %s LLStats indType: %d", __func__,
1548 pAdapter->dev->name, indType);
1549
Sunil Duttc69bccb2014-05-26 21:30:20 +05301550 switch (indType)
1551 {
1552 case SIR_HAL_LL_STATS_RESULTS_RSP:
1553 {
Sunil Duttc69bccb2014-05-26 21:30:20 +05301554 hddLog(VOS_TRACE_LEVEL_INFO,
1555 FL("RESPONSE SIR_HAL_LL_STATS_RESULTS_RSP") );
1556 hddLog(VOS_TRACE_LEVEL_INFO,
1557 "LL_STATS RESULTS RESPONSE paramID = 0x%x",
1558 linkLayerStatsResults->paramId);
1559 hddLog(VOS_TRACE_LEVEL_INFO,
Dino Mycled3d50022014-07-07 12:58:25 +05301560 "LL_STATS RESULTS RESPONSE ifaceId = %u MAC: %pM",
1561 linkLayerStatsResults->ifaceId, macAddr);
Sunil Duttc69bccb2014-05-26 21:30:20 +05301562 hddLog(VOS_TRACE_LEVEL_INFO,
1563 "LL_STATS RESULTS RESPONSE respId = %u",
1564 linkLayerStatsResults->respId);
1565 hddLog(VOS_TRACE_LEVEL_INFO,
1566 "LL_STATS RESULTS RESPONSE moreResultToFollow = %u",
1567 linkLayerStatsResults->moreResultToFollow);
1568 hddLog(VOS_TRACE_LEVEL_INFO,
1569 "LL_STATS RESULTS RESPONSE result = %p",
1570 linkLayerStatsResults->result);
1571 if ( linkLayerStatsResults->paramId & WMI_LINK_STATS_RADIO )
1572 {
1573 hdd_link_layer_process_radio_stats(pAdapter,
1574 (v_VOID_t *)linkLayerStatsResults->result);
1575 }
1576 else if ( linkLayerStatsResults->paramId & WMI_LINK_STATS_IFACE )
1577 {
1578 hdd_link_layer_process_iface_stats(pAdapter,
1579 (v_VOID_t *)linkLayerStatsResults->result);
1580 }
1581 else if ( linkLayerStatsResults->paramId &
1582 WMI_LINK_STATS_ALL_PEER )
1583 {
1584 hdd_link_layer_process_peer_stats(pAdapter,
1585 (v_VOID_t *)linkLayerStatsResults->result);
1586 } /* WMI_LINK_STATS_ALL_PEER */
1587 else
1588 {
1589 hddLog(VOS_TRACE_LEVEL_ERROR,
1590 FL("INVALID LL_STATS_NOTIFY RESPONSE ***********"));
1591 }
1592
1593 break;
1594 }
1595 default:
1596 hddLog(VOS_TRACE_LEVEL_ERROR, "invalid event type %d", indType);
1597 break;
1598 }
1599 return;
1600}
1601
1602const struct
1603nla_policy
1604qca_wlan_vendor_ll_set_policy[QCA_WLAN_VENDOR_ATTR_LL_STATS_SET_MAX +1] =
1605{
1606 [QCA_WLAN_VENDOR_ATTR_LL_STATS_SET_CONFIG_MPDU_SIZE_THRESHOLD] =
1607 { .type = NLA_U32 },
1608 [QCA_WLAN_VENDOR_ATTR_LL_STATS_SET_CONFIG_AGGRESSIVE_STATS_GATHERING] =
1609 { .type = NLA_U32 },
1610};
1611
1612static int wlan_hdd_cfg80211_ll_stats_set(struct wiphy *wiphy,
1613 struct wireless_dev *wdev,
1614 void *data,
1615 int data_len)
1616{
1617 int status;
1618 struct nlattr *tb_vendor[QCA_WLAN_VENDOR_ATTR_LL_STATS_SET_MAX + 1];
Dino Mycledf0a5d92014-07-04 09:41:55 +05301619 tSirLLStatsSetReq linkLayerStatsSetReq;
Sunil Duttc69bccb2014-05-26 21:30:20 +05301620 struct net_device *dev = wdev->netdev;
1621 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
1622 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
1623
1624 status = wlan_hdd_validate_context(pHddCtx);
1625 if (0 != status)
1626 {
1627 hddLog(VOS_TRACE_LEVEL_ERROR,
1628 FL("HDD context is not valid"));
1629 return -EINVAL;
1630 }
1631
1632 if (NULL == pAdapter)
1633 {
1634 hddLog(VOS_TRACE_LEVEL_ERROR,
1635 FL("HDD adapter is Null"));
1636 return -ENODEV;
1637 }
Dino Mycledf0a5d92014-07-04 09:41:55 +05301638 /* check the LLStats Capability */
1639 if ( (TRUE != pHddCtx->cfg_ini->fEnableLLStats) ||
1640 (TRUE != sme_IsFeatureSupportedByFW(LINK_LAYER_STATS_MEAS)))
1641 {
1642 hddLog(VOS_TRACE_LEVEL_ERROR,
1643 FL("Link Layer Statistics not supported by Firmware"));
1644 return -EINVAL;
1645 }
Sunil Duttc69bccb2014-05-26 21:30:20 +05301646
1647 if (nla_parse(tb_vendor, QCA_WLAN_VENDOR_ATTR_LL_STATS_SET_MAX,
1648 (struct nlattr *)data,
1649 data_len, qca_wlan_vendor_ll_set_policy))
1650 {
1651 hddLog(VOS_TRACE_LEVEL_ERROR, FL() );
1652 return -EINVAL;
1653 }
1654 if (!tb_vendor
1655 [QCA_WLAN_VENDOR_ATTR_LL_STATS_SET_CONFIG_MPDU_SIZE_THRESHOLD])
1656 {
1657 hddLog(VOS_TRACE_LEVEL_ERROR, FL("MPDU size Not present"));
1658 return -EINVAL;
1659 }
1660 if (!tb_vendor[
1661 QCA_WLAN_VENDOR_ATTR_LL_STATS_SET_CONFIG_AGGRESSIVE_STATS_GATHERING])
1662 {
1663 hddLog(VOS_TRACE_LEVEL_ERROR, FL(" Stats Gathering Not Present"));
1664 return -EINVAL;
1665 }
Sunil Duttc69bccb2014-05-26 21:30:20 +05301666 // Shall take the request Id if the Upper layers pass. 1 For now.
Dino Mycledf0a5d92014-07-04 09:41:55 +05301667 linkLayerStatsSetReq.reqId = 1;
Sunil Duttc69bccb2014-05-26 21:30:20 +05301668
Dino Mycledf0a5d92014-07-04 09:41:55 +05301669 linkLayerStatsSetReq.mpduSizeThreshold =
Sunil Duttc69bccb2014-05-26 21:30:20 +05301670 nla_get_u32(
1671 tb_vendor[QCA_WLAN_VENDOR_ATTR_LL_STATS_SET_CONFIG_MPDU_SIZE_THRESHOLD]);
1672
Dino Mycledf0a5d92014-07-04 09:41:55 +05301673 linkLayerStatsSetReq.aggressiveStatisticsGathering =
Sunil Duttc69bccb2014-05-26 21:30:20 +05301674 nla_get_u32(
1675 tb_vendor[QCA_WLAN_VENDOR_ATTR_LL_STATS_SET_CONFIG_AGGRESSIVE_STATS_GATHERING]);
1676
Dino Mycled3d50022014-07-07 12:58:25 +05301677 vos_mem_copy(linkLayerStatsSetReq.macAddr,
1678 pAdapter->macAddressCurrent.bytes, sizeof(v_MACADDR_t));
Sunil Duttc69bccb2014-05-26 21:30:20 +05301679
1680
1681 hddLog(VOS_TRACE_LEVEL_INFO,
Dino Mycled3d50022014-07-07 12:58:25 +05301682 "LL_STATS_SET reqId = %d", linkLayerStatsSetReq.reqId);
Sunil Duttc69bccb2014-05-26 21:30:20 +05301683 hddLog(VOS_TRACE_LEVEL_INFO,
Dino Mycled3d50022014-07-07 12:58:25 +05301684 "LL_STATS_SET MAC = %pM", linkLayerStatsSetReq.macAddr);
Sunil Duttc69bccb2014-05-26 21:30:20 +05301685 hddLog(VOS_TRACE_LEVEL_INFO,
1686 "LL_STATS_SET mpduSizeThreshold = %d",
Dino Mycledf0a5d92014-07-04 09:41:55 +05301687 linkLayerStatsSetReq.mpduSizeThreshold);
Sunil Duttc69bccb2014-05-26 21:30:20 +05301688 hddLog(VOS_TRACE_LEVEL_INFO,
1689 "LL_STATS_SET aggressive Statistics Gathering = %d",
Dino Mycledf0a5d92014-07-04 09:41:55 +05301690 linkLayerStatsSetReq.aggressiveStatisticsGathering);
Sunil Duttc69bccb2014-05-26 21:30:20 +05301691
1692 if (eHAL_STATUS_SUCCESS != sme_SetLinkLayerStatsIndCB(
1693 pHddCtx->hHal,
Dino Mycled3d50022014-07-07 12:58:25 +05301694 hdd_link_layer_stats_ind_callback))
Sunil Duttc69bccb2014-05-26 21:30:20 +05301695 {
1696 hddLog(VOS_TRACE_LEVEL_ERROR, "%s:"
1697 "sme_SetLinkLayerStatsIndCB Failed", __func__);
Sunil Duttc69bccb2014-05-26 21:30:20 +05301698 return -EINVAL;
1699
1700 }
1701 if (eHAL_STATUS_SUCCESS != sme_LLStatsSetReq( pHddCtx->hHal,
Dino Mycledf0a5d92014-07-04 09:41:55 +05301702 &linkLayerStatsSetReq))
Sunil Duttc69bccb2014-05-26 21:30:20 +05301703 {
1704 hddLog(VOS_TRACE_LEVEL_ERROR, "%s:"
1705 "sme_LLStatsSetReq Failed", __func__);
Sunil Duttc69bccb2014-05-26 21:30:20 +05301706 return -EINVAL;
1707 }
1708
1709 pAdapter->isLinkLayerStatsSet = 1;
1710
1711 return 0;
1712}
1713
1714const struct
1715nla_policy
1716qca_wlan_vendor_ll_get_policy[QCA_WLAN_VENDOR_ATTR_LL_STATS_GET_MAX +1] =
1717{
1718 /* Unsigned 32bit value provided by the caller issuing the GET stats
1719 * command. When reporting
1720 * the stats results, the driver uses the same value to indicate
1721 * which GET request the results
1722 * correspond to.
1723 */
1724 [QCA_WLAN_VENDOR_ATTR_LL_STATS_GET_CONFIG_REQ_ID] = { .type = NLA_U32 },
1725
1726 /* Unsigned 32bit value . bit mask to identify what statistics are
1727 requested for retrieval */
1728 [QCA_WLAN_VENDOR_ATTR_LL_STATS_GET_CONFIG_REQ_MASK] = { .type = NLA_U32 },
1729};
1730
1731static int wlan_hdd_cfg80211_ll_stats_get(struct wiphy *wiphy,
1732 struct wireless_dev *wdev,
1733 void *data,
1734 int data_len)
1735{
1736 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
1737 struct nlattr *tb_vendor[QCA_WLAN_VENDOR_ATTR_LL_STATS_GET_MAX + 1];
Dino Mycledf0a5d92014-07-04 09:41:55 +05301738 tSirLLStatsGetReq linkLayerStatsGetReq;
Sunil Duttc69bccb2014-05-26 21:30:20 +05301739 struct net_device *dev = wdev->netdev;
1740 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
1741 int status;
1742
1743 status = wlan_hdd_validate_context(pHddCtx);
1744 if (0 != status)
1745 {
1746 hddLog(VOS_TRACE_LEVEL_ERROR,
1747 FL("HDD context is not valid"));
1748 return -EINVAL ;
1749 }
1750
1751 if (NULL == pAdapter)
1752 {
1753 hddLog(VOS_TRACE_LEVEL_FATAL,
1754 "%s: HDD adapter is Null", __func__);
1755 return -ENODEV;
1756 }
Dino Mycledf0a5d92014-07-04 09:41:55 +05301757 /* check the LLStats Capability */
1758 if ( (TRUE != pHddCtx->cfg_ini->fEnableLLStats) ||
1759 (TRUE != sme_IsFeatureSupportedByFW(LINK_LAYER_STATS_MEAS)))
1760 {
1761 hddLog(VOS_TRACE_LEVEL_ERROR,
1762 FL("Link Layer Statistics not supported by Firmware"));
1763 return -EINVAL;
1764 }
1765
Sunil Duttc69bccb2014-05-26 21:30:20 +05301766
1767 if (!pAdapter->isLinkLayerStatsSet)
1768 {
1769 hddLog(VOS_TRACE_LEVEL_FATAL,
1770 "%s: isLinkLayerStatsSet : %d",
1771 __func__, pAdapter->isLinkLayerStatsSet);
1772 return -EINVAL;
1773 }
1774
1775 if (nla_parse(tb_vendor, QCA_WLAN_VENDOR_ATTR_LL_STATS_GET_MAX,
1776 (struct nlattr *)data,
1777 data_len, qca_wlan_vendor_ll_get_policy))
1778 {
1779 hddLog(VOS_TRACE_LEVEL_ERROR, FL() );
1780 return -EINVAL;
1781 }
1782
1783 if (!tb_vendor
1784 [QCA_WLAN_VENDOR_ATTR_LL_STATS_GET_CONFIG_REQ_ID])
1785 {
1786 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Request Id Not present"));
1787 return -EINVAL;
1788 }
1789
1790 if (!tb_vendor
1791 [QCA_WLAN_VENDOR_ATTR_LL_STATS_GET_CONFIG_REQ_MASK])
1792 {
1793 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Req Mask Not present"));
1794 return -EINVAL;
1795 }
1796
Sunil Duttc69bccb2014-05-26 21:30:20 +05301797
Dino Mycledf0a5d92014-07-04 09:41:55 +05301798 linkLayerStatsGetReq.reqId =
Sunil Duttc69bccb2014-05-26 21:30:20 +05301799 nla_get_u32( tb_vendor[
1800 QCA_WLAN_VENDOR_ATTR_LL_STATS_GET_CONFIG_REQ_ID]);
Dino Mycledf0a5d92014-07-04 09:41:55 +05301801 linkLayerStatsGetReq.paramIdMask =
Sunil Duttc69bccb2014-05-26 21:30:20 +05301802 nla_get_u32( tb_vendor[
1803 QCA_WLAN_VENDOR_ATTR_LL_STATS_GET_CONFIG_REQ_MASK]);
1804
Dino Mycled3d50022014-07-07 12:58:25 +05301805 vos_mem_copy(linkLayerStatsGetReq.macAddr,
1806 pAdapter->macAddressCurrent.bytes, sizeof(v_MACADDR_t));
Sunil Duttc69bccb2014-05-26 21:30:20 +05301807
1808 hddLog(VOS_TRACE_LEVEL_INFO,
Dino Mycledf0a5d92014-07-04 09:41:55 +05301809 "LL_STATS_GET reqId = %d", linkLayerStatsGetReq.reqId);
Sunil Duttc69bccb2014-05-26 21:30:20 +05301810 hddLog(VOS_TRACE_LEVEL_INFO,
Dino Mycled3d50022014-07-07 12:58:25 +05301811 "LL_STATS_GET MAC = %pM", linkLayerStatsGetReq.macAddr);
Sunil Duttc69bccb2014-05-26 21:30:20 +05301812 hddLog(VOS_TRACE_LEVEL_INFO,
1813 "LL_STATS_GET paramIdMask = %d",
Dino Mycledf0a5d92014-07-04 09:41:55 +05301814 linkLayerStatsGetReq.paramIdMask);
Sunil Duttc69bccb2014-05-26 21:30:20 +05301815
1816 if (eHAL_STATUS_SUCCESS != sme_LLStatsGetReq( pHddCtx->hHal,
Dino Mycledf0a5d92014-07-04 09:41:55 +05301817 &linkLayerStatsGetReq))
Sunil Duttc69bccb2014-05-26 21:30:20 +05301818 {
1819 hddLog(VOS_TRACE_LEVEL_ERROR, "%s:"
1820 "sme_LLStatsGetReq Failed", __func__);
Sunil Duttc69bccb2014-05-26 21:30:20 +05301821 return -EINVAL;
1822 }
1823 return 0;
1824}
1825
1826const struct
1827nla_policy
1828qca_wlan_vendor_ll_clr_policy[QCA_WLAN_VENDOR_ATTR_LL_STATS_CLR_MAX +1] =
1829{
1830 [QCA_WLAN_VENDOR_ATTR_LL_STATS_CLR_CONFIG_REQ_MASK] = {.type = NLA_U32 },
1831 [QCA_WLAN_VENDOR_ATTR_LL_STATS_CLR_CONFIG_STOP_REQ] = {.type = NLA_U8 },
1832 [QCA_WLAN_VENDOR_ATTR_LL_STATS_CLR_CONFIG_RSP_MASK] = {.type = NLA_U32 },
1833 [QCA_WLAN_VENDOR_ATTR_LL_STATS_CLR_CONFIG_STOP_RSP] = {.type = NLA_U8 },
1834};
1835
1836static int wlan_hdd_cfg80211_ll_stats_clear(struct wiphy *wiphy,
1837 struct wireless_dev *wdev,
1838 void *data,
1839 int data_len)
1840{
1841 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
1842 struct nlattr *tb_vendor[QCA_WLAN_VENDOR_ATTR_LL_STATS_CLR_MAX + 1];
Dino Mycledf0a5d92014-07-04 09:41:55 +05301843 tSirLLStatsClearReq linkLayerStatsClearReq;
Sunil Duttc69bccb2014-05-26 21:30:20 +05301844 struct net_device *dev = wdev->netdev;
1845 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
1846 u32 statsClearReqMask;
1847 u8 stopReq;
1848 int status;
1849
1850 status = wlan_hdd_validate_context(pHddCtx);
1851 if (0 != status)
1852 {
1853 hddLog(VOS_TRACE_LEVEL_ERROR,
1854 FL("HDD context is not valid"));
1855 return -EINVAL;
1856 }
1857
1858 if (NULL == pAdapter)
1859 {
1860 hddLog(VOS_TRACE_LEVEL_FATAL,
1861 "%s: HDD adapter is Null", __func__);
1862 return -ENODEV;
1863 }
Dino Mycledf0a5d92014-07-04 09:41:55 +05301864 /* check the LLStats Capability */
1865 if ( (TRUE != pHddCtx->cfg_ini->fEnableLLStats) ||
1866 (TRUE != sme_IsFeatureSupportedByFW(LINK_LAYER_STATS_MEAS)))
1867 {
1868 hddLog(VOS_TRACE_LEVEL_ERROR,
1869 FL("Enable LLStats Capability"));
1870 return -EINVAL;
1871 }
Sunil Duttc69bccb2014-05-26 21:30:20 +05301872
1873 if (!pAdapter->isLinkLayerStatsSet)
1874 {
1875 hddLog(VOS_TRACE_LEVEL_FATAL,
1876 "%s: isLinkLayerStatsSet : %d",
1877 __func__, pAdapter->isLinkLayerStatsSet);
1878 return -EINVAL;
1879 }
1880
1881 if (nla_parse(tb_vendor, QCA_WLAN_VENDOR_ATTR_LL_STATS_CLR_MAX,
1882 (struct nlattr *)data,
1883 data_len, qca_wlan_vendor_ll_clr_policy))
1884 {
1885 hddLog(VOS_TRACE_LEVEL_ERROR, FL() );
1886 return -EINVAL;
1887 }
1888
1889 if (!tb_vendor[QCA_WLAN_VENDOR_ATTR_LL_STATS_CLR_CONFIG_REQ_MASK] ||
1890
1891 !tb_vendor[QCA_WLAN_VENDOR_ATTR_LL_STATS_CLR_CONFIG_STOP_REQ])
1892 {
1893 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Error in LL_STATS CLR CONFIG PARA") );
1894 return -EINVAL;
1895
1896 }
1897
Sunil Duttc69bccb2014-05-26 21:30:20 +05301898
Dino Mycledf0a5d92014-07-04 09:41:55 +05301899 statsClearReqMask = linkLayerStatsClearReq.statsClearReqMask =
Sunil Duttc69bccb2014-05-26 21:30:20 +05301900 nla_get_u32(
1901 tb_vendor[QCA_WLAN_VENDOR_ATTR_LL_STATS_CLR_CONFIG_REQ_MASK]);
1902
Dino Mycledf0a5d92014-07-04 09:41:55 +05301903 stopReq = linkLayerStatsClearReq.stopReq =
Sunil Duttc69bccb2014-05-26 21:30:20 +05301904 nla_get_u8(
1905 tb_vendor[QCA_WLAN_VENDOR_ATTR_LL_STATS_CLR_CONFIG_STOP_REQ]);
1906
1907 // Shall take the request Id if the Upper layers pass. 1 For now.
Dino Mycledf0a5d92014-07-04 09:41:55 +05301908 linkLayerStatsClearReq.reqId = 1;
Sunil Duttc69bccb2014-05-26 21:30:20 +05301909
Dino Mycled3d50022014-07-07 12:58:25 +05301910 vos_mem_copy(linkLayerStatsClearReq.macAddr,
1911 pAdapter->macAddressCurrent.bytes, sizeof(v_MACADDR_t));
Sunil Duttc69bccb2014-05-26 21:30:20 +05301912
1913 hddLog(VOS_TRACE_LEVEL_INFO,
Dino Mycledf0a5d92014-07-04 09:41:55 +05301914 "LL_STATS_CLEAR reqId = %d", linkLayerStatsClearReq.reqId);
Sunil Duttc69bccb2014-05-26 21:30:20 +05301915 hddLog(VOS_TRACE_LEVEL_INFO,
Dino Mycled3d50022014-07-07 12:58:25 +05301916 "LL_STATS_CLEAR MAC = %pM", linkLayerStatsClearReq.macAddr);
Sunil Duttc69bccb2014-05-26 21:30:20 +05301917 hddLog(VOS_TRACE_LEVEL_INFO,
1918 "LL_STATS_CLEAR statsClearReqMask = 0x%X",
Dino Mycledf0a5d92014-07-04 09:41:55 +05301919 linkLayerStatsClearReq.statsClearReqMask);
Sunil Duttc69bccb2014-05-26 21:30:20 +05301920 hddLog(VOS_TRACE_LEVEL_INFO,
1921 "LL_STATS_CLEAR stopReq = %d",
Dino Mycledf0a5d92014-07-04 09:41:55 +05301922 linkLayerStatsClearReq.stopReq);
Sunil Duttc69bccb2014-05-26 21:30:20 +05301923
1924 if (eHAL_STATUS_SUCCESS == sme_LLStatsClearReq(pHddCtx->hHal,
Dino Mycledf0a5d92014-07-04 09:41:55 +05301925 &linkLayerStatsClearReq))
Sunil Duttc69bccb2014-05-26 21:30:20 +05301926 {
1927 struct sk_buff *temp_skbuff;
1928 temp_skbuff = cfg80211_vendor_cmd_alloc_reply_skb(wiphy,
1929 2 * sizeof(u32) +
1930 NLMSG_HDRLEN);
1931
1932 if (temp_skbuff != NULL)
1933 {
1934
1935 if (nla_put_u32(temp_skbuff,
1936 QCA_WLAN_VENDOR_ATTR_LL_STATS_CLR_CONFIG_RSP_MASK,
1937 statsClearReqMask) ||
1938 nla_put_u32(temp_skbuff,
1939 QCA_WLAN_VENDOR_ATTR_LL_STATS_CLR_CONFIG_STOP_RSP,
1940 stopReq))
1941 {
1942 hddLog(VOS_TRACE_LEVEL_ERROR, FL("LL_STATS_CLR put fail"));
1943 kfree_skb(temp_skbuff);
1944 return -EINVAL;
1945 }
1946 /* If the ask is to stop the stats collection as part of clear
1947 * (stopReq = 1) , ensure that no further requests of get
1948 * go to the firmware by having isLinkLayerStatsSet set to 0.
1949 * However it the stopReq as part of the clear request is 0 ,
Dino Mycledf0a5d92014-07-04 09:41:55 +05301950 * the request to get the statistics are honoured as in this
Sunil Duttc69bccb2014-05-26 21:30:20 +05301951 * case the firmware is just asked to clear the statistics.
1952 */
Dino Mycledf0a5d92014-07-04 09:41:55 +05301953 if (linkLayerStatsClearReq.stopReq == 1)
Sunil Duttc69bccb2014-05-26 21:30:20 +05301954 pAdapter->isLinkLayerStatsSet = 0;
1955 return cfg80211_vendor_cmd_reply(temp_skbuff);
1956 }
1957 return -ENOMEM;
1958 }
Sunil Duttc69bccb2014-05-26 21:30:20 +05301959 return -EINVAL;
1960}
1961#endif /* WLAN_FEATURE_LINK_LAYER_STATS */
1962
Dino Mycle6fb96c12014-06-10 11:52:40 +05301963#ifdef WLAN_FEATURE_EXTSCAN
1964static const struct nla_policy
1965wlan_hdd_extscan_config_policy
1966 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX + 1] =
1967{
1968 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_REQUEST_ID] =
1969 { .type = NLA_U32 },
1970 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_GET_VALID_CHANNELS_CONFIG_PARAM_WIFI_BAND] =
1971 { .type = NLA_U32 },
1972 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_CHANNEL_SPEC_CHANNEL] = { .type = NLA_U32 },
1973 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_CHANNEL_SPEC_DWELL_TIME] =
1974 { .type = NLA_U32 },
1975 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_CHANNEL_SPEC_PASSIVE] = { .type = NLA_U8 },
1976 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_CHANNEL_SPEC_CLASS] = { .type = NLA_U8 },
1977
1978 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_INDEX] = { .type = NLA_U8 },
1979 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_BAND] = { .type = NLA_U8 },
1980 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_PERIOD] = { .type = NLA_U32 },
1981 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_REPORT_EVENTS] =
1982 { .type = NLA_U8 },
1983 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_NUM_CHANNEL_SPECS] =
1984 { .type = NLA_U32 },
1985 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_SCAN_CMD_PARAMS_BASE_PERIOD] =
1986 { .type = NLA_U32 },
1987 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_SCAN_CMD_PARAMS_MAX_AP_PER_SCAN] =
1988 { .type = NLA_U32 },
1989 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_SCAN_CMD_PARAMS_REPORT_THRESHOLD] =
1990 { .type = NLA_U8 },
1991 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_SCAN_CMD_PARAMS_NUM_BUCKETS] =
1992 { .type = NLA_U8 },
1993 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_GET_CACHED_SCAN_RESULTS_CONFIG_PARAM_FLUSH] =
1994 { .type = NLA_U8 },
1995
1996 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_GET_CACHED_SCAN_RESULTS_CONFIG_PARAM_MAX] =
1997 { .type = NLA_U32 },
1998 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_AP_THRESHOLD_PARAM_BSSID] =
1999 { .type = NLA_UNSPEC },
2000 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_AP_THRESHOLD_PARAM_RSSI_LOW] =
2001 { .type = NLA_S32 },
2002 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_AP_THRESHOLD_PARAM_RSSI_HIGH] =
2003 { .type = NLA_S32 },
2004 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_AP_THRESHOLD_PARAM_CHANNEL] =
2005 { .type = NLA_U32 },
2006 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_BSSID_HOTLIST_PARAMS_NUM_AP] =
2007 { .type = NLA_U32 },
2008 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_SIGNIFICANT_CHANGE_PARAMS_RSSI_SAMPLE_SIZE] =
2009 { .type = NLA_U32 },
2010 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_SIGNIFICANT_CHANGE_PARAMS_LOST_AP_SAMPLE_SIZE]
2011 = { .type = NLA_U32 },
2012 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_SIGNIFICANT_CHANGE_PARAMS_MIN_BREACHING] =
2013 { .type = NLA_U32 },
2014 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_SIGNIFICANT_CHANGE_PARAMS_NUM_AP] = { .type =
2015 NLA_U32 },
2016};
2017
2018static void wlan_hdd_cfg80211_extscan_get_capabilities_ind(void *ctx, void *pMsg)
2019{
2020 hdd_context_t *pHddCtx = (hdd_context_t *)ctx;
2021 struct sk_buff *skb = NULL;
2022 tpSirEXTScanCapabilitiesEvent pData =
2023 (tpSirEXTScanCapabilitiesEvent) pMsg;
2024
2025 if (wlan_hdd_validate_context(pHddCtx) || !pData) {
2026 hddLog(VOS_TRACE_LEVEL_ERROR, FL("HDD context is not valid "
2027 "or pData(%p) is null"), pData);
2028 return;
2029 }
2030
2031 skb = cfg80211_vendor_event_alloc(pHddCtx->wiphy,
2032 EXTSCAN_EVENT_BUF_SIZE + NLMSG_HDRLEN,
2033 QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_GET_CAPABILITIES_INDEX,
2034 GFP_KERNEL);
2035
2036 if (!skb) {
2037 hddLog(VOS_TRACE_LEVEL_ERROR,
2038 FL("cfg80211_vendor_event_alloc failed"));
2039 return;
2040 }
2041
2042 hddLog(VOS_TRACE_LEVEL_INFO, "Req Id (%u)", pData->requestId);
2043 hddLog(VOS_TRACE_LEVEL_INFO, "Scan cache size (%u)", pData->scanCacheSize);
2044 hddLog(VOS_TRACE_LEVEL_INFO, "Scan buckets (%u)", pData->scanBuckets);
2045 hddLog(VOS_TRACE_LEVEL_INFO, "Max AP per scan (%u)", pData->maxApPerScan);
2046 hddLog(VOS_TRACE_LEVEL_INFO, "maxRssiSampleSize (%u)",
2047 pData->maxRssiSampleSize);
2048 hddLog(VOS_TRACE_LEVEL_INFO, "maxScanReportingThreshold (%u)",
2049 pData->maxScanReportingThreshold);
2050 hddLog(VOS_TRACE_LEVEL_INFO, "maxHotlistAPs (%u)", pData->maxHotlistAPs);
2051 hddLog(VOS_TRACE_LEVEL_INFO, "maxSignificantWifiChangeAPs (%u)",
2052 pData->maxSignificantWifiChangeAPs);
2053 hddLog(VOS_TRACE_LEVEL_INFO, "maxBsidHistoryEntries (%u)",
2054 pData->maxBsidHistoryEntries);
2055
2056 if (nla_put_u32(skb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_REQUEST_ID,
2057 pData->requestId) ||
2058 nla_put_u32(skb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_STATUS, pData->status) ||
2059 nla_put_u32(skb,
2060 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_CAPABILITIES_MAX_SCAN_CACHE_SIZE,
2061 pData->scanCacheSize) ||
2062 nla_put_u32(skb,
2063 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_CAPABILITIES_MAX_SCAN_BUCKETS,
2064 pData->scanBuckets) ||
2065 nla_put_u32(skb,
2066 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_CAPABILITIES_MAX_AP_CACHE_PER_SCAN,
2067 pData->maxApPerScan) ||
2068 nla_put_u32(skb,
2069 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_CAPABILITIES_MAX_RSSI_SAMPLE_SIZE,
2070 pData->maxRssiSampleSize) ||
2071 nla_put_u32(skb,
2072 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_CAPABILITIES_MAX_SCAN_REPORTING_THRESHOLD,
2073 pData->maxScanReportingThreshold) ||
2074 nla_put_u32(skb,
2075 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_CAPABILITIES_MAX_HOTLIST_APS,
2076 pData->maxHotlistAPs) ||
2077 nla_put_u32(skb,
2078 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_CAPABILITIES_MAX_SIGNIFICANT_WIFI_CHANGE_APS,
2079 pData->maxSignificantWifiChangeAPs) ||
2080 nla_put_u32(skb,
2081 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_CAPABILITIES_MAX_BSSID_HISTORY_ENTRIES,
2082 pData->maxBsidHistoryEntries)) {
2083 hddLog(VOS_TRACE_LEVEL_ERROR, FL("nla put fail"));
2084 goto nla_put_failure;
2085 }
2086
2087 cfg80211_vendor_event(skb, GFP_KERNEL);
2088 return;
2089
2090nla_put_failure:
2091 kfree_skb(skb);
2092 return;
2093}
2094
2095
2096static void wlan_hdd_cfg80211_extscan_start_rsp(void *ctx, void *pMsg)
2097{
2098 tpSirEXTScanStartRspParams pData = (tpSirEXTScanStartRspParams) pMsg;
2099 hdd_context_t *pHddCtx = (hdd_context_t *)ctx;
2100 struct sk_buff *skb = NULL;
2101 tpAniSirGlobal pMac = PMAC_STRUCT( pHddCtx->hHal );
2102
2103
2104 if (wlan_hdd_validate_context(pHddCtx) || !pData) {
2105 hddLog(VOS_TRACE_LEVEL_ERROR, FL("HDD context is not valid "
2106 "or pData(%p) is null"), pData);
2107 return;
2108 }
2109
2110 skb = cfg80211_vendor_event_alloc(pHddCtx->wiphy,
2111 EXTSCAN_EVENT_BUF_SIZE + NLMSG_HDRLEN,
2112 QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_START_INDEX,
2113 GFP_KERNEL);
2114
2115 if (!skb) {
2116 hddLog(VOS_TRACE_LEVEL_ERROR,
2117 FL("cfg80211_vendor_event_alloc failed"));
2118 return;
2119 }
2120 hddLog(VOS_TRACE_LEVEL_INFO, FL("Entering "));
2121 hddLog(VOS_TRACE_LEVEL_INFO, "Req Id (%u)", pData->requestId);
2122 hddLog(VOS_TRACE_LEVEL_INFO, "Status (%u)", pData->status);
2123
2124 if (nla_put_u32(skb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_REQUEST_ID,
2125 pData->requestId) ||
2126 nla_put_u32(skb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_STATUS, pData->status)) {
2127 hddLog(VOS_TRACE_LEVEL_ERROR, FL("nla put fail"));
2128 goto nla_put_failure;
2129 }
2130
2131 /*
2132 * Store the Request ID for comparing with the requestID obtained
2133 * in other requests.HDD shall return a failure is the extscan_stop
2134 * request is issued with a different requestId as that of the
2135 * extscan_start request. Also, This requestId shall be used while
2136 * indicating the full scan results to the upper layers.
2137 * The requestId is stored with the assumption that the firmware
2138 * shall return the ext scan start request's requestId in ext scan
2139 * start response.
2140 */
2141 if (pData->status == 0)
2142 pMac->sme.extScanStartReqId = pData->requestId;
2143
2144
2145 cfg80211_vendor_event(skb, GFP_KERNEL);
2146 return;
2147
2148nla_put_failure:
2149 kfree_skb(skb);
2150 return;
2151}
2152
2153
2154static void wlan_hdd_cfg80211_extscan_stop_rsp(void *ctx, void *pMsg)
2155{
2156 tpSirEXTScanStopRspParams pData = (tpSirEXTScanStopRspParams) pMsg;
2157 hdd_context_t *pHddCtx = (hdd_context_t *)ctx;
2158 struct sk_buff *skb = NULL;
2159
2160 if (wlan_hdd_validate_context(pHddCtx) || !pData) {
2161 hddLog(VOS_TRACE_LEVEL_ERROR, FL("HDD context is not valid "
2162 "or pData(%p) is null"), pData);
2163 return;
2164 }
2165
2166 skb = cfg80211_vendor_event_alloc(pHddCtx->wiphy,
2167 EXTSCAN_EVENT_BUF_SIZE + NLMSG_HDRLEN,
2168 QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_STOP_INDEX,
2169 GFP_KERNEL);
2170
2171 if (!skb) {
2172 hddLog(VOS_TRACE_LEVEL_ERROR,
2173 FL("cfg80211_vendor_event_alloc failed"));
2174 return;
2175 }
2176 hddLog(VOS_TRACE_LEVEL_INFO, FL("Entering "));
2177 hddLog(VOS_TRACE_LEVEL_INFO, "Req Id (%u)", pData->requestId);
2178
2179 if (nla_put_u32(skb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_REQUEST_ID,
2180 pData->requestId) ||
2181 nla_put_u32(skb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_STATUS, pData->status)) {
2182 hddLog(VOS_TRACE_LEVEL_ERROR, FL("nla put fail"));
2183 goto nla_put_failure;
2184 }
2185
2186 cfg80211_vendor_event(skb, GFP_KERNEL);
2187 return;
2188
2189nla_put_failure:
2190 kfree_skb(skb);
2191 return;
2192}
2193
2194
2195static void wlan_hdd_cfg80211_extscan_set_bss_hotlist_rsp(void *ctx,
2196 void *pMsg)
2197{
2198 hdd_context_t *pHddCtx = (hdd_context_t *)ctx;
2199 struct sk_buff *skb = NULL;
2200 tpSirEXTScanSetBssidHotListRspParams pData =
2201 (tpSirEXTScanSetBssidHotListRspParams) pMsg;
2202
2203 if (wlan_hdd_validate_context(pHddCtx) || !pData) {
2204 hddLog(VOS_TRACE_LEVEL_ERROR, FL("HDD context is not valid "
2205 "or pData(%p) is null"), pData);
2206 return;
2207 }
2208 skb = cfg80211_vendor_event_alloc(pHddCtx->wiphy,
2209 EXTSCAN_EVENT_BUF_SIZE + NLMSG_HDRLEN,
2210 QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_SET_BSSID_HOTLIST_INDEX,
2211 GFP_KERNEL);
2212
2213 if (!skb) {
2214 hddLog(VOS_TRACE_LEVEL_ERROR,
2215 FL("cfg80211_vendor_event_alloc failed"));
2216 return;
2217 }
2218 hddLog(VOS_TRACE_LEVEL_INFO, FL("Entering "));
2219 hddLog(VOS_TRACE_LEVEL_INFO, "Req Id (%u)", pData->requestId);
2220 hddLog(VOS_TRACE_LEVEL_INFO, "Status (%u)", pData->status);
2221
2222 if (nla_put_u32(skb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_REQUEST_ID,
2223 pData->requestId) ||
2224 nla_put_u32(skb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_STATUS, pData->status)) {
2225 hddLog(VOS_TRACE_LEVEL_ERROR, FL("nla put fail"));
2226 goto nla_put_failure;
2227 }
2228
2229 cfg80211_vendor_event(skb, GFP_KERNEL);
2230 return;
2231
2232nla_put_failure:
2233 kfree_skb(skb);
2234 return;
2235}
2236
2237static void wlan_hdd_cfg80211_extscan_reset_bss_hotlist_rsp(void *ctx,
2238 void *pMsg)
2239{
2240 hdd_context_t *pHddCtx = (hdd_context_t *)ctx;
2241 struct sk_buff *skb = NULL;
2242 tpSirEXTScanResetBssidHotlistRspParams pData =
2243 (tpSirEXTScanResetBssidHotlistRspParams) pMsg;
2244
2245 if (wlan_hdd_validate_context(pHddCtx) || !pData) {
2246 hddLog(VOS_TRACE_LEVEL_ERROR, FL("HDD context is not valid "
2247 "or pData(%p) is null"), pData);
2248 return;
2249 }
2250
2251 skb = cfg80211_vendor_event_alloc(pHddCtx->wiphy,
2252 EXTSCAN_EVENT_BUF_SIZE + NLMSG_HDRLEN,
2253 QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_RESET_BSSID_HOTLIST_INDEX,
2254 GFP_KERNEL);
2255
2256 if (!skb) {
2257 hddLog(VOS_TRACE_LEVEL_ERROR,
2258 FL("cfg80211_vendor_event_alloc failed"));
2259 return;
2260 }
2261 hddLog(VOS_TRACE_LEVEL_INFO, FL("Entering "));
2262 hddLog(VOS_TRACE_LEVEL_INFO, "Req Id (%u)", pData->requestId);
2263
2264 if (nla_put_u32(skb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_REQUEST_ID,
2265 pData->requestId) ||
2266 nla_put_u32(skb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_STATUS, pData->status)) {
2267 hddLog(VOS_TRACE_LEVEL_ERROR, FL("nla put fail"));
2268 goto nla_put_failure;
2269 }
2270
2271 cfg80211_vendor_event(skb, GFP_KERNEL);
2272 return;
2273
2274nla_put_failure:
2275 kfree_skb(skb);
2276 return;
2277}
2278
2279
2280static void wlan_hdd_cfg80211_extscan_set_signf_wifi_change_rsp(void *ctx,
2281 void *pMsg)
2282{
2283 hdd_context_t *pHddCtx = (hdd_context_t *)ctx;
2284 struct sk_buff *skb = NULL;
2285 tpSirEXTScanSetSignificantChangeRspParams pData =
2286 (tpSirEXTScanSetSignificantChangeRspParams) pMsg;
2287
2288 if (wlan_hdd_validate_context(pHddCtx) || !pData) {
2289 hddLog(VOS_TRACE_LEVEL_ERROR, FL("HDD context is not valid "
2290 "or pData(%p) is null"), pData);
2291 return;
2292 }
2293
2294 skb = cfg80211_vendor_event_alloc(pHddCtx->wiphy,
2295 EXTSCAN_EVENT_BUF_SIZE + NLMSG_HDRLEN,
2296 QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_SET_SIGNIFICANT_CHANGE_INDEX,
2297 GFP_KERNEL);
2298
2299 if (!skb) {
2300 hddLog(VOS_TRACE_LEVEL_ERROR,
2301 FL("cfg80211_vendor_event_alloc failed"));
2302 return;
2303 }
2304 hddLog(VOS_TRACE_LEVEL_INFO, FL("Entering "));
2305 hddLog(VOS_TRACE_LEVEL_INFO, "Req Id (%u)", pData->requestId);
2306 hddLog(VOS_TRACE_LEVEL_INFO, "Status (%u)", pData->status);
2307
2308 if (nla_put_u32(skb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_REQUEST_ID,
2309 pData->requestId) ||
2310 nla_put_u32(skb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_STATUS, pData->status)) {
2311 hddLog(VOS_TRACE_LEVEL_ERROR, FL("nla put fail"));
2312 goto nla_put_failure;
2313 }
2314
2315 cfg80211_vendor_event(skb, GFP_KERNEL);
2316 return;
2317
2318nla_put_failure:
2319 kfree_skb(skb);
2320 return;
2321}
2322
2323
2324static void wlan_hdd_cfg80211_extscan_reset_signf_wifi_change_rsp(void *ctx,
2325 void *pMsg)
2326{
2327 hdd_context_t *pHddCtx = (hdd_context_t *)ctx;
2328 struct sk_buff *skb = NULL;
2329 tpSirEXTScanResetSignificantChangeRspParams pData =
2330 (tpSirEXTScanResetSignificantChangeRspParams) pMsg;
2331
2332 if (wlan_hdd_validate_context(pHddCtx) || !pData) {
2333 hddLog(VOS_TRACE_LEVEL_ERROR, FL("HDD context is not valid "
2334 "or pData(%p) is null"), pData);
2335 return;
2336 }
2337
2338 skb = cfg80211_vendor_event_alloc(pHddCtx->wiphy,
2339 EXTSCAN_EVENT_BUF_SIZE + NLMSG_HDRLEN,
2340 QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_RESET_SIGNIFICANT_CHANGE_INDEX,
2341 GFP_KERNEL);
2342
2343 if (!skb) {
2344 hddLog(VOS_TRACE_LEVEL_ERROR,
2345 FL("cfg80211_vendor_event_alloc failed"));
2346 return;
2347 }
2348 hddLog(VOS_TRACE_LEVEL_INFO, FL("Entering "));
2349 hddLog(VOS_TRACE_LEVEL_INFO, "Req Id (%u)", pData->requestId);
2350 hddLog(VOS_TRACE_LEVEL_INFO, "Status (%u)", pData->status);
2351
2352 if (nla_put_u32(skb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_REQUEST_ID,
2353 pData->requestId) ||
2354 nla_put_u32(skb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_STATUS, pData->status)) {
2355 hddLog(VOS_TRACE_LEVEL_ERROR, FL("nla put fail"));
2356 goto nla_put_failure;
2357 }
2358
2359 cfg80211_vendor_event(skb, GFP_KERNEL);
2360 return;
2361
2362nla_put_failure:
2363 kfree_skb(skb);
2364 return;
2365}
2366
2367static void wlan_hdd_cfg80211_extscan_cached_results_ind(void *ctx,
2368 void *pMsg)
2369{
2370 hdd_context_t *pHddCtx = (hdd_context_t *)ctx;
2371 struct sk_buff *skb = NULL;
2372 tANI_U32 i = 0, j, resultsPerEvent;
2373 tANI_S32 totalResults;
2374 tpSirWifiScanResultEvent pData = (tpSirWifiScanResultEvent) pMsg;
2375 tpSirWifiScanResult pSirWifiScanResult;
2376
2377 if (wlan_hdd_validate_context(pHddCtx) || !pData) {
2378 hddLog(VOS_TRACE_LEVEL_ERROR, FL("HDD context is not valid "
2379 "or pData(%p) is null"), pData);
2380 return;
2381 }
2382 totalResults = pData->numOfAps;
2383 hddLog(VOS_TRACE_LEVEL_INFO, "Req Id (%u)", pData->requestId);
2384 hddLog(VOS_TRACE_LEVEL_INFO, "Num results (%u)", pData->numOfAps);
2385 hddLog(VOS_TRACE_LEVEL_INFO, "More Data (%u)", pData->moreData);
2386
2387 do{
2388 resultsPerEvent = ((totalResults >= EXTSCAN_MAX_CACHED_RESULTS_PER_IND) ?
2389 EXTSCAN_MAX_CACHED_RESULTS_PER_IND : totalResults);
2390 totalResults -= EXTSCAN_MAX_CACHED_RESULTS_PER_IND;
2391
2392 skb = cfg80211_vendor_event_alloc(pHddCtx->wiphy,
2393 EXTSCAN_EVENT_BUF_SIZE + NLMSG_HDRLEN,
2394 QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_GET_CACHED_RESULTS_INDEX,
2395 GFP_KERNEL);
2396
2397 if (!skb) {
2398 hddLog(VOS_TRACE_LEVEL_ERROR,
2399 FL("cfg80211_vendor_event_alloc failed"));
2400 return;
2401 }
2402
2403 hddLog(VOS_TRACE_LEVEL_INFO, "resultsPerEvent (%u)", resultsPerEvent);
2404
2405 if (nla_put_u32(skb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_REQUEST_ID,
2406 pData->requestId) ||
2407 nla_put_u32(skb,
2408 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_NUM_RESULTS_AVAILABLE,
2409 resultsPerEvent)) {
2410 hddLog(VOS_TRACE_LEVEL_ERROR, FL("put fail"));
2411 goto fail;
2412 }
2413 if (nla_put_u8(skb,
2414 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_MORE_DATA,
2415 pData->moreData ? 1 : (totalResults > 0 ? 1 : 0 )))
2416 {
2417 hddLog(VOS_TRACE_LEVEL_ERROR, FL("put fail"));
2418 goto fail;
2419 }
2420
2421 if (resultsPerEvent) {
2422 struct nlattr *aps;
2423
2424 aps = nla_nest_start(skb,
2425 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_LIST);
2426 if (!aps)
2427 {
2428 hddLog(VOS_TRACE_LEVEL_ERROR, FL("put fail"));
2429 goto fail;
2430 }
2431
2432 for (j = 0; j < resultsPerEvent; j++, i++) {
2433 struct nlattr *ap;
2434 pSirWifiScanResult = (tpSirWifiScanResult) ((tANI_U8 *)
2435 pData->ap + ( i* sizeof(tSirWifiScanResult)));
2436
2437 hddLog(VOS_TRACE_LEVEL_INFO, "[index=%u] Timestamp(%llu) "
2438 "Ssid (%s)"
2439 "Bssid: %pM "
2440 "Channel (%u)"
2441 "Rssi (%d)"
2442 "RTT (%u)"
2443 "RTT_SD (%u)",
2444 i,
2445 pSirWifiScanResult->ts,
2446 pSirWifiScanResult->ssid,
2447 pSirWifiScanResult->bssid,
2448 pSirWifiScanResult->channel,
2449 pSirWifiScanResult->rssi,
2450 pSirWifiScanResult->rtt,
2451 pSirWifiScanResult->rtt_sd);
2452
2453 ap = nla_nest_start(skb, j + 1);
2454 if (!ap)
2455 {
2456 hddLog(VOS_TRACE_LEVEL_ERROR, FL("put fail"));
2457 goto fail;
2458 }
2459
2460 if (nla_put_u64(skb,
2461 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_TIME_STAMP,
2462 pSirWifiScanResult->ts) )
2463 {
2464 hddLog(VOS_TRACE_LEVEL_ERROR, FL("put fail"));
2465 goto fail;
2466 }
2467 if (nla_put(skb,
2468 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_SSID,
2469 sizeof(pSirWifiScanResult->ssid),
2470 pSirWifiScanResult->ssid) )
2471 {
2472 hddLog(VOS_TRACE_LEVEL_ERROR, FL("put fail"));
2473 goto fail;
2474 }
2475 if (nla_put(skb,
2476 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_BSSID,
2477 sizeof(pSirWifiScanResult->bssid),
2478 pSirWifiScanResult->bssid) )
2479 {
2480 hddLog(VOS_TRACE_LEVEL_ERROR, FL("put fail"));
2481 goto fail;
2482 }
2483 if (nla_put_u32(skb,
2484 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_CHANNEL,
2485 pSirWifiScanResult->channel) )
2486 {
2487 hddLog(VOS_TRACE_LEVEL_ERROR, FL("put fail"));
2488 goto fail;
2489 }
2490 if (nla_put_u32(skb,
2491 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_RSSI,
2492 pSirWifiScanResult->rssi) )
2493 {
2494 hddLog(VOS_TRACE_LEVEL_ERROR, FL("put fail"));
2495 goto fail;
2496 }
2497 if (nla_put_u32(skb,
2498 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_RTT,
2499 pSirWifiScanResult->rtt) )
2500 {
2501 hddLog(VOS_TRACE_LEVEL_ERROR, FL("put fail"));
2502 goto fail;
2503 }
2504 if (nla_put_u32(skb,
2505 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_RTT_SD,
2506 pSirWifiScanResult->rtt_sd))
2507 {
2508 hddLog(VOS_TRACE_LEVEL_ERROR, FL("put fail"));
2509 goto fail;
2510 }
2511
2512 nla_nest_end(skb, ap);
2513 }
2514 nla_nest_end(skb, aps);
2515
2516 }
2517 cfg80211_vendor_event(skb, GFP_KERNEL);
2518 } while (totalResults > 0);
2519
2520 return;
2521fail:
2522 kfree_skb(skb);
2523 return;
2524}
2525
2526static void wlan_hdd_cfg80211_extscan_hotlist_match_ind(void *ctx,
2527 void *pMsg)
2528{
2529 tpSirWifiScanResultEvent pData = (tpSirWifiScanResultEvent) pMsg;
2530 hdd_context_t *pHddCtx = (hdd_context_t *)ctx;
2531 struct sk_buff *skb = NULL;
2532 tANI_U32 i;
2533
2534 if (wlan_hdd_validate_context(pHddCtx) || !pData) {
2535 hddLog(VOS_TRACE_LEVEL_ERROR, FL("HDD context is not valid "
2536 "or pData(%p) is null"), pData);
2537 return;
2538 }
2539
2540 skb = cfg80211_vendor_event_alloc(pHddCtx->wiphy,
2541 EXTSCAN_EVENT_BUF_SIZE + NLMSG_HDRLEN,
2542 QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_HOTLIST_AP_FOUND_INDEX,
2543 GFP_KERNEL);
2544
2545 if (!skb) {
2546 hddLog(VOS_TRACE_LEVEL_ERROR,
2547 FL("cfg80211_vendor_event_alloc failed"));
2548 return;
2549 }
2550 hddLog(VOS_TRACE_LEVEL_INFO, FL("Entering "));
2551 hddLog(VOS_TRACE_LEVEL_INFO, "Req Id (%u)", pData->requestId);
2552 hddLog(VOS_TRACE_LEVEL_INFO, "Num results (%u)", pData->numOfAps);
2553 hddLog(VOS_TRACE_LEVEL_INFO, "More Data (%u)", pData->moreData);
2554
2555 for (i = 0; i < pData->numOfAps; i++) {
2556 hddLog(VOS_TRACE_LEVEL_INFO, "[index=%u] Timestamp(0x%lld) "
2557 "Ssid (%s) "
2558 "Bssid (" MAC_ADDRESS_STR ") "
2559 "Channel (%u) "
2560 "Rssi (%d) "
2561 "RTT (%u) "
2562 "RTT_SD (%u) ",
2563 i,
2564 pData->ap[i].ts,
2565 pData->ap[i].ssid,
2566 MAC_ADDR_ARRAY(pData->ap[i].bssid),
2567 pData->ap[i].channel,
2568 pData->ap[i].rssi,
2569 pData->ap[i].rtt,
2570 pData->ap[i].rtt_sd);
2571 }
2572
2573 if (nla_put_u32(skb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_REQUEST_ID,
2574 pData->requestId) ||
2575 nla_put_u32(skb,
2576 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_NUM_RESULTS_AVAILABLE,
2577 pData->numOfAps)) {
2578 hddLog(VOS_TRACE_LEVEL_ERROR, FL("put fail"));
2579 goto fail;
2580 }
2581 if (pData->numOfAps) {
2582 struct nlattr *aps;
2583
2584 aps = nla_nest_start(skb,
2585 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_LIST);
2586 if (!aps)
2587 goto fail;
2588
2589 for (i = 0; i < pData->numOfAps; i++) {
2590 struct nlattr *ap;
2591
2592 ap = nla_nest_start(skb, i + 1);
2593 if (!ap)
2594 goto fail;
2595
2596 if (nla_put_u64(skb,
2597 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_TIME_STAMP,
2598 pData->ap[i].ts) ||
2599 nla_put(skb,
2600 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_SSID,
2601 sizeof(pData->ap[i].ssid),
2602 pData->ap[i].ssid) ||
2603 nla_put(skb,
2604 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_BSSID,
2605 sizeof(pData->ap[i].bssid),
2606 pData->ap[i].bssid) ||
2607 nla_put_u32(skb,
2608 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_CHANNEL,
2609 pData->ap[i].channel) ||
2610 nla_put_s32(skb,
2611 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_RSSI,
2612 pData->ap[i].rssi) ||
2613 nla_put_u32(skb,
2614 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_RTT,
2615 pData->ap[i].rtt) ||
2616 nla_put_u32(skb,
2617 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_RTT_SD,
2618 pData->ap[i].rtt_sd))
2619 goto fail;
2620
2621 nla_nest_end(skb, ap);
2622 }
2623 nla_nest_end(skb, aps);
2624
2625 if (nla_put_u8(skb,
2626 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_MORE_DATA,
2627 pData->moreData))
2628 goto fail;
2629 }
2630
2631 cfg80211_vendor_event(skb, GFP_KERNEL);
2632 return;
2633
2634fail:
2635 kfree_skb(skb);
2636 return;
2637
2638}
2639static void wlan_hdd_cfg80211_extscan_signif_wifi_change_results_ind(void *ctx,
2640 void *pMsg)
2641{
2642 hdd_context_t *pHddCtx = (hdd_context_t *)ctx;
2643 struct sk_buff *skb = NULL;
2644 tANI_U32 i, j;
2645 tpSirWifiSignificantChangeEvent pData =
2646 (tpSirWifiSignificantChangeEvent) pMsg;
2647
2648 if (wlan_hdd_validate_context(pHddCtx) || !pData) {
2649 hddLog(VOS_TRACE_LEVEL_ERROR, FL("HDD context is not valid "
2650 "or pData(%p) is null"), pData);
2651 return;
2652 }
2653 skb = cfg80211_vendor_event_alloc(pHddCtx->wiphy,
2654 EXTSCAN_EVENT_BUF_SIZE,
2655 QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_SIGNIFICANT_CHANGE_INDEX,
2656 GFP_KERNEL);
2657
2658 if (!skb) {
2659 hddLog(VOS_TRACE_LEVEL_ERROR,
2660 FL("cfg80211_vendor_event_alloc failed"));
2661 return;
2662 }
2663 hddLog(VOS_TRACE_LEVEL_INFO, FL("Entering "));
2664 hddLog(VOS_TRACE_LEVEL_INFO, "Req Id (%u)", pData->requestId);
2665 hddLog(VOS_TRACE_LEVEL_INFO, "total List Size %u ", pData->numSigRssiBss);
2666 hddLog(VOS_TRACE_LEVEL_INFO, " CUrrent List size (%u)",
2667 pData->numSigRssiBss);
2668 hddLog(VOS_TRACE_LEVEL_INFO, "moreData (%u)", pData->moreData);
2669
2670 for (i = 0; i < pData->numSigRssiBss; i++) {
2671 hddLog(VOS_TRACE_LEVEL_INFO , "Rssi List [%d] BSSID: (%pM) Channel %u "
2672 " num RSSI %u ",
2673 i, pData->sigRssiResult[i].bssid,
2674 pData->sigRssiResult[i].channel,
2675 pData->sigRssiResult[i].numRssi);
2676
2677 for (j = 0; j < pData->sigRssiResult[i].numRssi; j++){
2678
2679 hddLog(VOS_TRACE_LEVEL_INFO,
2680 " [%d]",
Dino Myclec8f3f332014-07-21 16:48:27 +05302681 pData->sigRssiResult[i].rssi[j]);
Dino Mycle6fb96c12014-06-10 11:52:40 +05302682
2683 }
2684 }
2685
2686
2687 if (nla_put_u32(skb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_REQUEST_ID,
2688 pData->requestId) ||
2689 nla_put_u32(skb,
2690 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_NUM_RESULTS_AVAILABLE,
2691 pData->numSigRssiBss)) {
2692 hddLog(VOS_TRACE_LEVEL_ERROR, FL("put fail"));
2693 goto fail;
2694 }
2695
2696 if (pData->numSigRssiBss) {
2697 struct nlattr *aps;
2698 aps = nla_nest_start(skb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_LIST);
2699 if (!aps)
2700 goto fail;
2701 for (i = 0; i < pData->numSigRssiBss; i++) {
2702 struct nlattr *ap;
2703
2704 ap = nla_nest_start(skb, i);
2705 if (!ap)
2706 goto fail;
2707 if (nla_put(skb,
2708 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SIGNIFICANT_CHANGE_RESULT_BSSID,
2709 sizeof(tSirMacAddr), pData->sigRssiResult[i].bssid) ||
2710 nla_put_u32(skb,
2711 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SIGNIFICANT_CHANGE_RESULT_CHANNEL,
2712 pData->sigRssiResult[i].channel) ||
2713 nla_put_u32(skb,
2714 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SIGNIFICANT_CHANGE_RESULT_NUM_RSSI,
2715 pData->sigRssiResult[i].numRssi) ||
2716 nla_put(skb,
2717 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SIGNIFICANT_CHANGE_RESULT_RSSI_LIST,
2718 sizeof(s32) * pData->sigRssiResult[i].numRssi,
2719 pData->sigRssiResult[i].rssi))
2720 goto fail;
2721 nla_nest_end(skb, ap);
2722 }
2723 nla_nest_end(skb, aps);
2724 if (nla_put_u8(skb,
2725 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_MORE_DATA,
2726 pData->moreData))
2727 goto fail;
2728 }
2729 cfg80211_vendor_event(skb, GFP_KERNEL);
2730 return;
2731fail:
2732 kfree_skb(skb);
2733 return;
2734}
2735
2736static void wlan_hdd_cfg80211_extscan_full_scan_result_event(void *ctx,
2737 void *pMsg)
2738{
2739 struct sk_buff *skb;
2740 hdd_context_t *pHddCtx = (hdd_context_t *)ctx;
2741 tpSirWifiFullScanResultEvent pData =
2742 (tpSirWifiFullScanResultEvent) (pMsg);
2743
2744 if (wlan_hdd_validate_context(pHddCtx) || !pData) {
2745 hddLog(VOS_TRACE_LEVEL_ERROR, FL("HDD context is not valid "
2746 "or pData(%p) is null"), pData);
2747 return;
2748 }
2749
2750 skb = cfg80211_vendor_event_alloc(pHddCtx->wiphy,
2751 EXTSCAN_EVENT_BUF_SIZE + NLMSG_HDRLEN,
2752 QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_FULL_SCAN_RESULT_INDEX,
2753 GFP_KERNEL);
2754
2755 if (!skb) {
2756 hddLog(VOS_TRACE_LEVEL_ERROR,
2757 FL("cfg80211_vendor_event_alloc failed"));
2758 return;
2759 }
2760
2761 hddLog(VOS_TRACE_LEVEL_INFO, FL("Entering "));
2762 hddLog(VOS_TRACE_LEVEL_INFO, FL("Req Id (%u)"), pData->requestId);
2763 hddLog(VOS_TRACE_LEVEL_INFO, FL("More Data (%u)"), pData->moreData);
2764 hddLog(VOS_TRACE_LEVEL_INFO, FL("AP Info: Timestamp(0x%llX) "
2765 "Ssid (%s)"
2766 "Bssid (" MAC_ADDRESS_STR ")"
2767 "Channel (%u)"
2768 "Rssi (%d)"
2769 "RTT (%u)"
2770 "RTT_SD (%u)"),
2771 pData->ap.ts,
2772 pData->ap.ssid,
2773 MAC_ADDR_ARRAY(pData->ap.bssid),
2774 pData->ap.channel,
2775 pData->ap.rssi,
2776 pData->ap.rtt,
2777 pData->ap.rtt_sd);
2778 hddLog(VOS_TRACE_LEVEL_INFO, "IE Length (%u)", pData->ieLength);
2779 if (nla_put_u32(skb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_REQUEST_ID,
2780 pData->requestId) ||
2781 nla_put_u64(skb,
2782 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_TIME_STAMP,
2783 pData->ap.ts) ||
2784 nla_put(skb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_SSID,
2785 sizeof(pData->ap.ssid),
2786 pData->ap.ssid) ||
2787 nla_put(skb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_BSSID,
2788 WNI_CFG_BSSID_LEN,
2789 pData->ap.bssid) ||
2790 nla_put_u32(skb,
2791 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_CHANNEL,
2792 pData->ap.channel) ||
2793 nla_put_u32(skb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_RSSI,
2794 pData->ap.rssi) ||
2795 nla_put_u32(skb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_RTT,
2796 pData->ap.rtt) ||
2797 nla_put_u32(skb,
2798 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_RTT_SD,
2799 pData->ap.rtt_sd) ||
2800 nla_put_u16(skb,
2801 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_BEACON_PERIOD,
2802 pData->ap.beaconPeriod) ||
2803 nla_put_u16(skb,
2804 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_CAPABILITY,
2805 pData->ap.capability) ||
2806 nla_put_u32(skb,
2807 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_IE_LENGTH,
2808 pData->ieLength))
2809 {
2810 hddLog(VOS_TRACE_LEVEL_ERROR, FL("nla put fail"));
2811 goto nla_put_failure;
2812 }
2813 if (nla_put(skb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_IE_DATA,
2814 pData->ieLength,
2815 pData->ie))
2816 {
2817 hddLog(VOS_TRACE_LEVEL_ERROR, FL("nla put fail"));
2818 goto nla_put_failure;
2819 }
2820
2821 cfg80211_vendor_event(skb, GFP_KERNEL);
2822 return;
2823
2824nla_put_failure:
2825 kfree_skb(skb);
2826 return;
2827}
2828
2829static void wlan_hdd_cfg80211_extscan_scan_res_available_event(void *ctx,
2830 void *pMsg)
2831{
2832 hdd_context_t *pHddCtx = (hdd_context_t *)ctx;
2833 struct sk_buff *skb = NULL;
2834 tpSirEXTScanResultsAvailableIndParams pData =
2835 (tpSirEXTScanResultsAvailableIndParams) pMsg;
2836
2837 if (wlan_hdd_validate_context(pHddCtx) || !pData) {
2838 hddLog(VOS_TRACE_LEVEL_ERROR, FL("HDD context is not valid "
2839 "or pData(%p) is null"), pData);
2840 return;
2841 }
2842
2843 skb = cfg80211_vendor_event_alloc(pHddCtx->wiphy,
2844 EXTSCAN_EVENT_BUF_SIZE + NLMSG_HDRLEN,
2845 QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_SCAN_RESULTS_AVAILABLE_INDEX,
2846 GFP_KERNEL);
2847
2848 if (!skb) {
2849 hddLog(VOS_TRACE_LEVEL_ERROR,
2850 FL("cfg80211_vendor_event_alloc failed"));
2851 return;
2852 }
2853
2854 hddLog(VOS_TRACE_LEVEL_INFO, FL("Entering "));
2855 hddLog(VOS_TRACE_LEVEL_INFO, "Req Id (%u)", pData->requestId);
2856 hddLog(VOS_TRACE_LEVEL_INFO, "Num results (%u)",
2857 pData->numResultsAvailable);
2858 if (nla_put_u32(skb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_REQUEST_ID,
2859 pData->requestId) ||
2860 nla_put_u32(skb,
2861 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_NUM_RESULTS_AVAILABLE,
2862 pData->numResultsAvailable)) {
2863 hddLog(VOS_TRACE_LEVEL_ERROR, FL("nla put fail"));
2864 goto nla_put_failure;
2865 }
2866
2867 cfg80211_vendor_event(skb, GFP_KERNEL);
2868 return;
2869
2870nla_put_failure:
2871 kfree_skb(skb);
2872 return;
2873}
2874
2875static void wlan_hdd_cfg80211_extscan_scan_progress_event(void *ctx, void *pMsg)
2876{
2877 hdd_context_t *pHddCtx = (hdd_context_t *)ctx;
2878 struct sk_buff *skb = NULL;
2879 tpSirEXTScanProgressIndParams pData =
2880 (tpSirEXTScanProgressIndParams) pMsg;
2881
2882 if (wlan_hdd_validate_context(pHddCtx) || !pData) {
2883 hddLog(VOS_TRACE_LEVEL_ERROR, FL("HDD context is not valid "
2884 "or pData(%p) is null"), pData);
2885 return;
2886 }
2887
2888 skb = cfg80211_vendor_event_alloc(pHddCtx->wiphy,
2889 EXTSCAN_EVENT_BUF_SIZE + NLMSG_HDRLEN,
2890 QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_SCAN_EVENT_INDEX,
2891 GFP_KERNEL);
2892
2893 if (!skb) {
2894 hddLog(VOS_TRACE_LEVEL_ERROR,
2895 FL("cfg80211_vendor_event_alloc failed"));
2896 return;
2897 }
2898 hddLog(VOS_TRACE_LEVEL_INFO, FL("Entering "));
2899 hddLog(VOS_TRACE_LEVEL_INFO, "Scan event type (%u)",
2900 pData->extScanEventType);
2901 hddLog(VOS_TRACE_LEVEL_INFO, "Scan event status (%u)",
2902 pData->status);
2903
2904 if (nla_put_u8(skb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_EVENT_TYPE,
2905 pData->extScanEventType) ||
2906 nla_put_u32(skb,
Dasari Srinivas5a288652014-06-30 17:13:22 +05302907 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_REQUEST_ID,
2908 pData->requestId) ||
2909 nla_put_u32(skb,
Dino Mycle6fb96c12014-06-10 11:52:40 +05302910 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_EVENT_STATUS,
2911 pData->status)) {
2912 hddLog(VOS_TRACE_LEVEL_ERROR, FL("nla put fail"));
2913 goto nla_put_failure;
2914 }
2915
2916 cfg80211_vendor_event(skb, GFP_KERNEL);
2917 return;
2918
2919nla_put_failure:
2920 kfree_skb(skb);
2921 return;
2922}
2923
2924void wlan_hdd_cfg80211_extscan_callback(void *ctx, const tANI_U16 evType,
2925 void *pMsg)
2926{
2927 hdd_context_t *pHddCtx = (hdd_context_t *)ctx;
2928
2929 if (wlan_hdd_validate_context(pHddCtx)) {
2930 hddLog(VOS_TRACE_LEVEL_ERROR, FL("HDD context is not valid"));
2931 return;
2932 }
2933
2934 hddLog(VOS_TRACE_LEVEL_INFO, FL("Rcvd Event (%d)"), evType);
2935
2936
2937 switch(evType) {
2938 case SIR_HAL_EXTSCAN_START_RSP:
2939 wlan_hdd_cfg80211_extscan_start_rsp(ctx, pMsg);
2940 break;
2941
2942 case SIR_HAL_EXTSCAN_STOP_RSP:
2943 wlan_hdd_cfg80211_extscan_stop_rsp(ctx, pMsg);
2944 break;
2945 case SIR_HAL_EXTSCAN_GET_CACHED_RESULTS_RSP:
2946 /* There is no need to send this response to upper layer
2947 Just log the message */
2948 hddLog(VOS_TRACE_LEVEL_INFO,
2949 FL("Rcvd SIR_HAL_EXTSCAN_CACHED_RESULTS_RSP"));
2950 break;
2951 case SIR_HAL_EXTSCAN_SET_BSS_HOTLIST_RSP:
2952 wlan_hdd_cfg80211_extscan_set_bss_hotlist_rsp(ctx, pMsg);
2953 break;
2954
2955 case SIR_HAL_EXTSCAN_RESET_BSS_HOTLIST_RSP:
2956 wlan_hdd_cfg80211_extscan_reset_bss_hotlist_rsp(ctx, pMsg);
2957 break;
2958
2959 case SIR_HAL_EXTSCAN_SET_SIGNF_RSSI_CHANGE_RSP:
2960 wlan_hdd_cfg80211_extscan_set_signf_wifi_change_rsp(ctx, pMsg);
2961 break;
2962
2963 case SIR_HAL_EXTSCAN_RESET_SIGNF_RSSI_CHANGE_RSP:
2964 wlan_hdd_cfg80211_extscan_reset_signf_wifi_change_rsp(ctx, pMsg);
2965 break;
2966 case SIR_HAL_EXTSCAN_GET_CAPABILITIES_RSP:
2967 wlan_hdd_cfg80211_extscan_get_capabilities_ind(ctx, pMsg);
2968 break;
2969 case SIR_HAL_EXTSCAN_PROGRESS_IND:
2970 wlan_hdd_cfg80211_extscan_scan_progress_event(ctx, pMsg);
2971 break;
2972 case SIR_HAL_EXTSCAN_SCAN_AVAILABLE_IND:
2973 wlan_hdd_cfg80211_extscan_scan_res_available_event(ctx, pMsg);
2974 break;
2975 case SIR_HAL_EXTSCAN_SCAN_RESULT_IND:
2976 wlan_hdd_cfg80211_extscan_cached_results_ind(ctx, pMsg);
2977 break;
2978 case SIR_HAL_EXTSCAN_HOTLIST_MATCH_IND:
2979 wlan_hdd_cfg80211_extscan_hotlist_match_ind(ctx, pMsg);
2980 break;
2981 case SIR_HAL_EXTSCAN_SIGNF_WIFI_CHANGE_IND:
2982 wlan_hdd_cfg80211_extscan_signif_wifi_change_results_ind(ctx, pMsg);
2983 break;
2984 case SIR_HAL_EXTSCAN_FULL_SCAN_RESULT_IND:
2985 wlan_hdd_cfg80211_extscan_full_scan_result_event(ctx, pMsg);
2986 break;
2987 default:
2988 hddLog(VOS_TRACE_LEVEL_ERROR, FL("invalid event type %d "), evType);
2989 break;
2990 }
2991}
2992
2993static int wlan_hdd_cfg80211_extscan_get_capabilities(struct wiphy *wiphy,
2994 struct wireless_dev *wdev,
2995 void *data, int dataLen)
2996{
Dino Myclee8843b32014-07-04 14:21:45 +05302997 tSirGetEXTScanCapabilitiesReqParams reqMsg;
Dino Mycle6fb96c12014-06-10 11:52:40 +05302998 struct net_device *dev = wdev->netdev;
2999 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
3000 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
3001 struct nlattr
3002 *tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX + 1];
3003 eHalStatus status;
3004
3005 hddLog(VOS_TRACE_LEVEL_INFO, FL("Entering"));
3006 status = wlan_hdd_validate_context(pHddCtx);
3007 if (0 != status)
3008 {
3009 hddLog(VOS_TRACE_LEVEL_ERROR,
3010 FL("HDD context is not valid"));
3011 return -EINVAL;
3012 }
Dino Myclee8843b32014-07-04 14:21:45 +05303013 /* check the EXTScan Capability */
3014 if ( (TRUE != pHddCtx->cfg_ini->fEnableEXTScan) ||
3015 (TRUE != sme_IsFeatureSupportedByFW(EXTENDED_SCAN)))
3016 {
3017 hddLog(VOS_TRACE_LEVEL_ERROR,
3018 FL("EXTScan not enabled/supported by Firmware"));
3019 return -EINVAL;
3020 }
3021
Dino Mycle6fb96c12014-06-10 11:52:40 +05303022 if (nla_parse(tb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX,
3023 data, dataLen,
3024 wlan_hdd_extscan_config_policy)) {
3025 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Invalid ATTR"));
3026 return -EINVAL;
3027 }
3028
3029 /* Parse and fetch request Id */
3030 if (!tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_REQUEST_ID]) {
3031 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr request id failed"));
3032 return -EINVAL;
3033 }
3034
Dino Mycle6fb96c12014-06-10 11:52:40 +05303035
Dino Myclee8843b32014-07-04 14:21:45 +05303036 reqMsg.requestId = nla_get_u32(
Dino Mycle6fb96c12014-06-10 11:52:40 +05303037 tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_REQUEST_ID]);
Dino Myclee8843b32014-07-04 14:21:45 +05303038 hddLog(VOS_TRACE_LEVEL_INFO, FL("Req Id (%d)"), reqMsg.requestId);
Dino Mycle6fb96c12014-06-10 11:52:40 +05303039
Dino Myclee8843b32014-07-04 14:21:45 +05303040 reqMsg.sessionId = pAdapter->sessionId;
3041 hddLog(VOS_TRACE_LEVEL_INFO, FL("Session Id (%d)"), reqMsg.sessionId);
Dino Mycle6fb96c12014-06-10 11:52:40 +05303042
Dino Myclee8843b32014-07-04 14:21:45 +05303043 status = sme_EXTScanGetCapabilities(pHddCtx->hHal, &reqMsg);
Dino Mycle6fb96c12014-06-10 11:52:40 +05303044 if (!HAL_STATUS_SUCCESS(status)) {
3045 hddLog(VOS_TRACE_LEVEL_ERROR,
3046 FL("sme_EXTScanGetCapabilities failed(err=%d)"), status);
Dino Mycle6fb96c12014-06-10 11:52:40 +05303047 return -EINVAL;
3048 }
3049
3050 return 0;
3051}
3052
3053
3054static int wlan_hdd_cfg80211_extscan_get_cached_results(struct wiphy *wiphy,
3055 struct wireless_dev *wdev,
3056 void *data, int dataLen)
3057{
Dino Myclee8843b32014-07-04 14:21:45 +05303058 tSirEXTScanGetCachedResultsReqParams reqMsg;
Dino Mycle6fb96c12014-06-10 11:52:40 +05303059 struct net_device *dev = wdev->netdev;
3060 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
3061 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
3062 struct nlattr
3063 *tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX + 1];
3064 eHalStatus status;
3065
3066 status = wlan_hdd_validate_context(pHddCtx);
3067 if (0 != status)
3068 {
3069 hddLog(VOS_TRACE_LEVEL_ERROR,
3070 FL("HDD context is not valid"));
3071 return -EINVAL;
3072 }
Dino Myclee8843b32014-07-04 14:21:45 +05303073 /* check the EXTScan Capability */
3074 if ( (TRUE != pHddCtx->cfg_ini->fEnableEXTScan) ||
3075 (TRUE != sme_IsFeatureSupportedByFW(EXTENDED_SCAN)))
3076 {
3077 hddLog(VOS_TRACE_LEVEL_ERROR,
3078 FL("EXTScan not enabled/supported by Firmware"));
3079 return -EINVAL;
3080 }
3081
Dino Mycle6fb96c12014-06-10 11:52:40 +05303082 if (nla_parse(tb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX,
3083 data, dataLen,
3084 wlan_hdd_extscan_config_policy)) {
3085 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Invalid ATTR"));
3086 return -EINVAL;
3087 }
3088 /* Parse and fetch request Id */
3089 if (!tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_REQUEST_ID]) {
3090 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr request id failed"));
3091 return -EINVAL;
3092 }
Dino Mycle6fb96c12014-06-10 11:52:40 +05303093
Dino Myclee8843b32014-07-04 14:21:45 +05303094 reqMsg.requestId = nla_get_u32(
Dino Mycle6fb96c12014-06-10 11:52:40 +05303095 tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_REQUEST_ID]);
3096
Dino Myclee8843b32014-07-04 14:21:45 +05303097 hddLog(VOS_TRACE_LEVEL_INFO, FL("Req Id (%d)"), reqMsg.requestId);
Dino Mycle6fb96c12014-06-10 11:52:40 +05303098
Dino Myclee8843b32014-07-04 14:21:45 +05303099 reqMsg.sessionId = pAdapter->sessionId;
3100 hddLog(VOS_TRACE_LEVEL_INFO, FL("Session Id (%d)"), reqMsg.sessionId);
Dino Mycle6fb96c12014-06-10 11:52:40 +05303101
3102 /* Parse and fetch flush parameter */
3103 if (!tb
3104 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_GET_CACHED_SCAN_RESULTS_CONFIG_PARAM_FLUSH])
3105 {
3106 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr flush failed"));
3107 goto failed;
3108 }
Dino Myclee8843b32014-07-04 14:21:45 +05303109 reqMsg.flush = nla_get_u8(
Dino Mycle6fb96c12014-06-10 11:52:40 +05303110 tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_GET_CACHED_SCAN_RESULTS_CONFIG_PARAM_FLUSH]);
3111
Dino Myclee8843b32014-07-04 14:21:45 +05303112 hddLog(VOS_TRACE_LEVEL_INFO, FL("Flush (%d)"), reqMsg.flush);
Dino Mycle6fb96c12014-06-10 11:52:40 +05303113
Dino Myclee8843b32014-07-04 14:21:45 +05303114 status = sme_getCachedResults(pHddCtx->hHal, &reqMsg);
Dino Mycle6fb96c12014-06-10 11:52:40 +05303115 if (!HAL_STATUS_SUCCESS(status)) {
3116 hddLog(VOS_TRACE_LEVEL_ERROR,
3117 FL("sme_getCachedResults failed(err=%d)"), status);
Dino Mycle6fb96c12014-06-10 11:52:40 +05303118 return -EINVAL;
3119 }
3120 return 0;
3121
3122failed:
Dino Mycle6fb96c12014-06-10 11:52:40 +05303123 return -EINVAL;
3124}
3125
3126static int wlan_hdd_cfg80211_extscan_set_bssid_hotlist(struct wiphy *wiphy,
3127 struct wireless_dev *wdev,
3128 void *data, int dataLen)
3129{
3130 tpSirEXTScanSetBssidHotListReqParams pReqMsg = NULL;
3131 struct net_device *dev = wdev->netdev;
3132 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
3133 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
3134 struct nlattr
3135 *tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX + 1];
3136 struct nlattr
3137 *tb2[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX + 1];
3138 struct nlattr *apTh;
3139 eHalStatus status;
3140 tANI_U8 i = 0;
3141 int rem;
3142
3143 status = wlan_hdd_validate_context(pHddCtx);
3144 if (0 != status)
3145 {
3146 hddLog(VOS_TRACE_LEVEL_ERROR,
3147 FL("HDD context is not valid"));
3148 return -EINVAL;
3149 }
Dino Myclee8843b32014-07-04 14:21:45 +05303150 /* check the EXTScan Capability */
3151 if ( (TRUE != pHddCtx->cfg_ini->fEnableEXTScan) ||
3152 (TRUE != sme_IsFeatureSupportedByFW(EXTENDED_SCAN)))
3153 {
3154 hddLog(VOS_TRACE_LEVEL_ERROR,
3155 FL("EXTScan not enabled/supported by Firmware"));
3156 return -EINVAL;
3157 }
3158
Dino Mycle6fb96c12014-06-10 11:52:40 +05303159 if (nla_parse(tb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX,
3160 data, dataLen,
3161 wlan_hdd_extscan_config_policy)) {
3162 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Invalid ATTR"));
3163 return -EINVAL;
3164 }
3165
3166 /* Parse and fetch request Id */
3167 if (!tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_REQUEST_ID]) {
3168 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr request id failed"));
3169 return -EINVAL;
3170 }
Dino Mycle6fb96c12014-06-10 11:52:40 +05303171 pReqMsg = (tpSirEXTScanSetBssidHotListReqParams)
3172 vos_mem_malloc(sizeof(*pReqMsg));
3173 if (!pReqMsg) {
3174 hddLog(VOS_TRACE_LEVEL_ERROR, FL("vos_mem_malloc failed"));
3175 return -ENOMEM;
3176 }
3177
Dino Myclee8843b32014-07-04 14:21:45 +05303178
Dino Mycle6fb96c12014-06-10 11:52:40 +05303179 pReqMsg->requestId = nla_get_u32(
3180 tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_REQUEST_ID]);
3181 hddLog(VOS_TRACE_LEVEL_INFO, FL("Req Id (%d)"), pReqMsg->requestId);
3182
3183 /* Parse and fetch number of APs */
3184 if (!tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_BSSID_HOTLIST_PARAMS_NUM_AP]) {
3185 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr number of AP failed"));
3186 goto fail;
3187 }
3188
3189 pReqMsg->sessionId = pAdapter->sessionId;
3190 hddLog(VOS_TRACE_LEVEL_INFO, FL("Session Id (%d)"), pReqMsg->sessionId);
3191
3192 pReqMsg->numAp = nla_get_u32(
3193 tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_BSSID_HOTLIST_PARAMS_NUM_AP]);
3194 hddLog(VOS_TRACE_LEVEL_INFO, FL("Number of AP (%d)"), pReqMsg->numAp);
3195
3196 nla_for_each_nested(apTh,
3197 tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_AP_THRESHOLD_PARAM], rem) {
3198 if(nla_parse(tb2, QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX,
3199 nla_data(apTh), nla_len(apTh),
3200 NULL)) {
3201 hddLog(VOS_TRACE_LEVEL_ERROR, FL("nla_parse failed"));
3202 goto fail;
3203 }
3204
3205 /* Parse and fetch MAC address */
3206 if (!tb2[QCA_WLAN_VENDOR_ATTR_EXTSCAN_AP_THRESHOLD_PARAM_BSSID]) {
3207 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr mac address failed"));
3208 goto fail;
3209 }
3210 memcpy(pReqMsg->ap[i].bssid, nla_data(
3211 tb2[QCA_WLAN_VENDOR_ATTR_EXTSCAN_AP_THRESHOLD_PARAM_BSSID]),
3212 sizeof(tSirMacAddr));
3213 hddLog(VOS_TRACE_LEVEL_INFO, FL("BSSID: %pM "), pReqMsg->ap[i].bssid);
3214
3215 /* Parse and fetch low RSSI */
3216 if (!tb2[QCA_WLAN_VENDOR_ATTR_EXTSCAN_AP_THRESHOLD_PARAM_RSSI_LOW]) {
3217 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr low RSSI failed"));
3218 goto fail;
3219 }
3220 pReqMsg->ap[i].low = nla_get_s32(
3221 tb2[QCA_WLAN_VENDOR_ATTR_EXTSCAN_AP_THRESHOLD_PARAM_RSSI_LOW]);
3222 hddLog(VOS_TRACE_LEVEL_INFO, FL("RSSI low (%d)"), pReqMsg->ap[i].low);
3223
3224 /* Parse and fetch high RSSI */
3225 if (!tb2[QCA_WLAN_VENDOR_ATTR_EXTSCAN_AP_THRESHOLD_PARAM_RSSI_HIGH]) {
3226 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr high RSSI failed"));
3227 goto fail;
3228 }
3229 pReqMsg->ap[i].high = nla_get_s32(
3230 tb2[QCA_WLAN_VENDOR_ATTR_EXTSCAN_AP_THRESHOLD_PARAM_RSSI_HIGH]);
3231 hddLog(VOS_TRACE_LEVEL_INFO, FL("RSSI High (%d)"),
3232 pReqMsg->ap[i].high);
3233
3234 /* Parse and fetch channel */
3235 if (!tb2[QCA_WLAN_VENDOR_ATTR_EXTSCAN_AP_THRESHOLD_PARAM_CHANNEL]) {
3236 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr channel failed"));
3237 goto fail;
3238 }
3239 pReqMsg->ap[i].channel = nla_get_u32(
3240 tb2[QCA_WLAN_VENDOR_ATTR_EXTSCAN_AP_THRESHOLD_PARAM_CHANNEL]);
3241 hddLog(VOS_TRACE_LEVEL_INFO,
3242 FL("Channel (%u)"), pReqMsg->ap[i].channel);
3243 i++;
3244 }
3245 status = sme_SetBssHotlist(pHddCtx->hHal, pReqMsg);
3246 if (!HAL_STATUS_SUCCESS(status)) {
3247 hddLog(VOS_TRACE_LEVEL_ERROR,
3248 FL("sme_SetBssHotlist failed(err=%d)"), status);
3249 vos_mem_free(pReqMsg);
3250 return -EINVAL;
3251 }
3252
Dino Myclee8843b32014-07-04 14:21:45 +05303253 vos_mem_free(pReqMsg);
3254
Dino Mycle6fb96c12014-06-10 11:52:40 +05303255 return 0;
3256
3257fail:
3258 vos_mem_free(pReqMsg);
3259 return -EINVAL;
3260}
3261
3262static int wlan_hdd_cfg80211_extscan_set_significant_change(struct wiphy *wiphy,
3263 struct wireless_dev *wdev,
3264 void *data, int dataLen)
3265{
3266 tpSirEXTScanSetSignificantChangeReqParams pReqMsg = NULL;
3267 struct net_device *dev = wdev->netdev;
3268 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
3269 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
3270 struct nlattr
3271 *tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX + 1];
3272 struct nlattr
3273 *tb2[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX + 1];
3274 struct nlattr *apTh;
3275 eHalStatus status;
3276 int i = 0;
3277 int rem;
3278
3279 status = wlan_hdd_validate_context(pHddCtx);
3280 if (0 != status)
3281 {
3282 hddLog(VOS_TRACE_LEVEL_ERROR,
3283 FL("HDD context is not valid"));
3284 return -EINVAL;
3285 }
Dino Myclee8843b32014-07-04 14:21:45 +05303286 /* check the EXTScan Capability */
3287 if ( (TRUE != pHddCtx->cfg_ini->fEnableEXTScan) ||
3288 (TRUE != sme_IsFeatureSupportedByFW(EXTENDED_SCAN)))
3289 {
3290 hddLog(VOS_TRACE_LEVEL_ERROR,
3291 FL("EXTScan not enabled/supported by Firmware"));
3292 return -EINVAL;
3293 }
3294
Dino Mycle6fb96c12014-06-10 11:52:40 +05303295 if (nla_parse(tb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX,
3296 data, dataLen,
3297 wlan_hdd_extscan_config_policy)) {
3298 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Invalid ATTR"));
3299 return -EINVAL;
3300 }
3301
3302 /* Parse and fetch request Id */
3303 if (!tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_REQUEST_ID]) {
3304 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr request id failed"));
3305 return -EINVAL;
3306 }
Dino Mycle6fb96c12014-06-10 11:52:40 +05303307 pReqMsg = (tpSirEXTScanSetSignificantChangeReqParams)
Dino Myclee8843b32014-07-04 14:21:45 +05303308 vos_mem_malloc(sizeof(*pReqMsg));
Dino Mycle6fb96c12014-06-10 11:52:40 +05303309 if (!pReqMsg) {
Dino Myclee8843b32014-07-04 14:21:45 +05303310 hddLog(VOS_TRACE_LEVEL_ERROR, FL("vos_mem_malloc failed"));
3311 return -ENOMEM;
Dino Mycle6fb96c12014-06-10 11:52:40 +05303312 }
3313
Dino Myclee8843b32014-07-04 14:21:45 +05303314
3315
Dino Mycle6fb96c12014-06-10 11:52:40 +05303316 pReqMsg->requestId = nla_get_u32(
3317 tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_REQUEST_ID]);
3318 hddLog(VOS_TRACE_LEVEL_INFO, FL("Req Id (%d)"), pReqMsg->requestId);
3319
3320 /* Parse and fetch RSSI sample size */
3321 if (!tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SIGNIFICANT_CHANGE_PARAMS_RSSI_SAMPLE_SIZE])
3322 {
3323 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr RSSI sample size failed"));
3324 goto fail;
3325 }
3326 pReqMsg->rssiSampleSize = nla_get_u32(
3327 tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SIGNIFICANT_CHANGE_PARAMS_RSSI_SAMPLE_SIZE]);
3328 hddLog(VOS_TRACE_LEVEL_INFO,
3329 FL("RSSI sample size (%u)"), pReqMsg->rssiSampleSize);
3330
3331 /* Parse and fetch lost AP sample size */
3332 if (!tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SIGNIFICANT_CHANGE_PARAMS_LOST_AP_SAMPLE_SIZE])
3333 {
3334 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr lost AP sample size failed"));
3335 goto fail;
3336 }
3337 pReqMsg->lostApSampleSize = nla_get_u32(
3338 tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SIGNIFICANT_CHANGE_PARAMS_LOST_AP_SAMPLE_SIZE]);
3339 hddLog(VOS_TRACE_LEVEL_INFO,
3340 FL("Lost AP sample size (%u)"), pReqMsg->lostApSampleSize);
3341 /* Parse and fetch minimum Breaching */
3342 if (!tb
3343 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_SIGNIFICANT_CHANGE_PARAMS_MIN_BREACHING]) {
3344 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr minBreaching failed"));
3345 goto fail;
3346 }
3347 pReqMsg->minBreaching = nla_get_u32(
3348 tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SIGNIFICANT_CHANGE_PARAMS_MIN_BREACHING]);
3349 hddLog(VOS_TRACE_LEVEL_INFO, FL(" Breaching (%d)"), pReqMsg->minBreaching);
3350
3351 /* Parse and fetch number of APs */
3352 if (!tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SIGNIFICANT_CHANGE_PARAMS_NUM_AP]) {
3353 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr number of AP failed"));
3354 goto fail;
3355 }
3356 pReqMsg->numAp = nla_get_u32(
3357 tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SIGNIFICANT_CHANGE_PARAMS_NUM_AP]);
3358 hddLog(VOS_TRACE_LEVEL_INFO, FL("Number of AP (%d)"), pReqMsg->numAp);
3359
3360 pReqMsg->sessionId = pAdapter->sessionId;
3361 hddLog(VOS_TRACE_LEVEL_INFO, FL("Session Id (%d)"), pReqMsg->sessionId);
3362
3363 nla_for_each_nested(apTh,
3364 tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_AP_THRESHOLD_PARAM], rem) {
3365 if(nla_parse(tb2,
3366 QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX,
3367 nla_data(apTh), nla_len(apTh),
3368 NULL)) {
3369 hddLog(VOS_TRACE_LEVEL_ERROR, FL("nla_parse failed"));
3370 goto fail;
3371 }
3372
3373 /* Parse and fetch MAC address */
3374 if (!tb2[QCA_WLAN_VENDOR_ATTR_EXTSCAN_AP_THRESHOLD_PARAM_BSSID]) {
3375 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr mac address failed"));
3376 goto fail;
3377 }
3378 memcpy(pReqMsg->ap[i].bssid, nla_data(
3379 tb2[QCA_WLAN_VENDOR_ATTR_EXTSCAN_AP_THRESHOLD_PARAM_BSSID]),
3380 sizeof(tSirMacAddr));
3381
3382 /* Parse and fetch low RSSI */
3383 if (!tb2[QCA_WLAN_VENDOR_ATTR_EXTSCAN_AP_THRESHOLD_PARAM_RSSI_LOW]) {
3384 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr low RSSI failed"));
3385 goto fail;
3386 }
3387 pReqMsg->ap[i].low = nla_get_s32(
3388 tb2[QCA_WLAN_VENDOR_ATTR_EXTSCAN_AP_THRESHOLD_PARAM_RSSI_LOW]);
3389 hddLog(VOS_TRACE_LEVEL_INFO, FL("RSSI low (%d)"), pReqMsg->ap[i].low);
3390
3391 /* Parse and fetch high RSSI */
3392 if (!tb2[QCA_WLAN_VENDOR_ATTR_EXTSCAN_AP_THRESHOLD_PARAM_RSSI_HIGH]) {
3393 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr high RSSI failed"));
3394 goto fail;
3395 }
3396 pReqMsg->ap[i].high = nla_get_s32(
3397 tb2[QCA_WLAN_VENDOR_ATTR_EXTSCAN_AP_THRESHOLD_PARAM_RSSI_HIGH]);
3398 hddLog(VOS_TRACE_LEVEL_INFO,
3399 FL("RSSI High (%d)"), pReqMsg->ap[i].high);
3400
3401 /* Parse and fetch channel */
3402 if (!tb2[QCA_WLAN_VENDOR_ATTR_EXTSCAN_AP_THRESHOLD_PARAM_CHANNEL]) {
3403 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr channel failed"));
3404 goto fail;
3405 }
3406 pReqMsg->ap[i].channel = nla_get_u32(
3407 tb2[QCA_WLAN_VENDOR_ATTR_EXTSCAN_AP_THRESHOLD_PARAM_CHANNEL]);
3408 hddLog(VOS_TRACE_LEVEL_INFO,
3409 FL("Channel (%u)"), pReqMsg->ap[i].channel);
3410 i++;
3411 }
3412
3413 status = sme_SetSignificantChange(pHddCtx->hHal, pReqMsg);
3414 if (!HAL_STATUS_SUCCESS(status)) {
3415 hddLog(VOS_TRACE_LEVEL_ERROR,
3416 FL("sme_SetSignificantChange failed(err=%d)"), status);
3417 vos_mem_free(pReqMsg);
3418 return -EINVAL;
3419 }
Dino Myclee8843b32014-07-04 14:21:45 +05303420 vos_mem_free(pReqMsg);
Dino Mycle6fb96c12014-06-10 11:52:40 +05303421 hddLog(VOS_TRACE_LEVEL_ERROR, FL(" Exiting"));
3422 return 0;
3423
3424fail:
3425 vos_mem_free(pReqMsg);
3426 return -EINVAL;
3427}
3428
3429static int wlan_hdd_cfg80211_extscan_get_valid_channels(struct wiphy *wiphy,
3430 struct wireless_dev *wdev,
3431 void *data, int dataLen)
3432{
3433 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
3434 tANI_U32 ChannelList[WNI_CFG_VALID_CHANNEL_LIST_LEN] = {0};
3435 tANI_U8 numChannels = 0;
3436 struct nlattr *tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX + 1];
3437 tANI_U32 requestId;
3438 tWifiBand wifiBand;
3439 eHalStatus status;
3440 struct sk_buff *replySkb;
3441 tANI_U8 i;
3442
3443 hddLog(VOS_TRACE_LEVEL_INFO, FL("Entering"));
3444 status = wlan_hdd_validate_context(pHddCtx);
3445 if (0 != status)
3446 {
3447 hddLog(VOS_TRACE_LEVEL_ERROR,
3448 FL("HDD context is not valid"));
3449 return -EINVAL;
3450 }
Dino Myclee8843b32014-07-04 14:21:45 +05303451 /* check the EXTScan Capability */
3452 if ( (TRUE != pHddCtx->cfg_ini->fEnableEXTScan) ||
3453 (TRUE != sme_IsFeatureSupportedByFW(EXTENDED_SCAN)))
3454 {
3455 hddLog(VOS_TRACE_LEVEL_ERROR,
3456 FL("EXTScan not enabled/supported by Firmware"));
3457 return -EINVAL;
3458 }
3459
Dino Mycle6fb96c12014-06-10 11:52:40 +05303460 if (nla_parse(tb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX,
3461 data, dataLen,
3462 wlan_hdd_extscan_config_policy)) {
3463 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Invalid ATTR"));
3464 return -EINVAL;
3465 }
3466
3467 /* Parse and fetch request Id */
3468 if (!tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_REQUEST_ID]) {
3469 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr request id failed"));
3470 return -EINVAL;
3471 }
3472 requestId = nla_get_u32(
3473 tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_REQUEST_ID]);
3474 hddLog(VOS_TRACE_LEVEL_INFO, FL("Req Id (%d)"), requestId);
3475
3476 /* Parse and fetch wifi band */
3477 if (!tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_GET_VALID_CHANNELS_CONFIG_PARAM_WIFI_BAND])
3478 {
3479 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr wifi band failed"));
3480 return -EINVAL;
3481 }
3482 wifiBand = nla_get_u32(
3483 tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_GET_VALID_CHANNELS_CONFIG_PARAM_WIFI_BAND]);
3484 hddLog(VOS_TRACE_LEVEL_INFO, FL("Wifi band (%d)"), wifiBand);
3485
3486 status = sme_GetValidChannelsByBand((tHalHandle)(pHddCtx->hHal),
3487 wifiBand, ChannelList,
3488 &numChannels);
3489 if (eHAL_STATUS_SUCCESS != status) {
3490 hddLog(VOS_TRACE_LEVEL_ERROR,
3491 FL("sme_GetValidChannelsByBand failed (err=%d)"), status);
3492 return -EINVAL;
3493 }
3494 hddLog(VOS_TRACE_LEVEL_INFO, FL("Number of channels (%d)"), numChannels);
3495 for (i = 0; i < numChannels; i++)
3496 hddLog(VOS_TRACE_LEVEL_INFO, "Channel: %u ", ChannelList[i]);
3497
3498 replySkb = cfg80211_vendor_cmd_alloc_reply_skb(wiphy, sizeof(u32) +
3499 sizeof(u32) * numChannels +
3500 NLMSG_HDRLEN);
3501
3502 if (!replySkb) {
3503 hddLog(VOS_TRACE_LEVEL_ERROR,
3504 FL("valid channels: buffer alloc fail"));
3505 return -EINVAL;
3506 }
3507 if (nla_put_u32(replySkb,
3508 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_NUM_CHANNELS,
3509 numChannels) ||
3510 nla_put(replySkb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_CHANNELS,
3511 sizeof(u32) * numChannels, ChannelList)) {
3512
3513 hddLog(VOS_TRACE_LEVEL_ERROR, FL("nla put fail"));
3514 kfree_skb(replySkb);
3515 return -EINVAL;
3516 }
3517
3518 return cfg80211_vendor_cmd_reply(replySkb);
3519}
3520
3521static int wlan_hdd_cfg80211_extscan_start(struct wiphy *wiphy,
3522 struct wireless_dev *wdev,
3523 void *data, int dataLen)
3524{
Dino Myclee8843b32014-07-04 14:21:45 +05303525 tpSirEXTScanStartReqParams pReqMsg = NULL;
Dino Mycle6fb96c12014-06-10 11:52:40 +05303526 struct net_device *dev = wdev->netdev;
3527 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
3528 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
3529 struct nlattr *tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX + 1];
3530 struct nlattr *bucket[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX + 1];
3531 struct nlattr *channel[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX + 1];
3532 struct nlattr *buckets;
3533 struct nlattr *channels;
3534 int rem1;
3535 int rem2;
3536 eHalStatus status;
Dasari Srinivas8b2ce272014-09-16 16:57:30 +05303537 tANI_U32 j = 0, index = 0;
Dino Mycle6fb96c12014-06-10 11:52:40 +05303538
3539 status = wlan_hdd_validate_context(pHddCtx);
3540 if (0 != status)
3541 {
3542 hddLog(VOS_TRACE_LEVEL_ERROR,
3543 FL("HDD context is not valid"));
3544 return -EINVAL;
3545 }
Dino Myclee8843b32014-07-04 14:21:45 +05303546 /* check the EXTScan Capability */
3547 if ( (TRUE != pHddCtx->cfg_ini->fEnableEXTScan) ||
3548 (TRUE != sme_IsFeatureSupportedByFW(EXTENDED_SCAN)))
3549 {
3550 hddLog(VOS_TRACE_LEVEL_ERROR,
3551 FL("EXTScan not enabled/supported by Firmware"));
3552 return -EINVAL;
3553 }
3554
Dino Mycle6fb96c12014-06-10 11:52:40 +05303555 if (nla_parse(tb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX,
3556 data, dataLen,
3557 wlan_hdd_extscan_config_policy)) {
3558 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Invalid ATTR"));
3559 return -EINVAL;
3560 }
3561
3562 /* Parse and fetch request Id */
3563 if (!tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_REQUEST_ID]) {
3564 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr request id failed"));
3565 return -EINVAL;
3566 }
3567
Dino Myclee8843b32014-07-04 14:21:45 +05303568 pReqMsg = (tpSirEXTScanStartReqParams)
3569 vos_mem_malloc(sizeof(*pReqMsg));
Dino Mycle6fb96c12014-06-10 11:52:40 +05303570 if (!pReqMsg) {
Dino Myclee8843b32014-07-04 14:21:45 +05303571 hddLog(VOS_TRACE_LEVEL_ERROR, FL("vos_mem_malloc failed"));
3572 return -ENOMEM;
Dino Mycle6fb96c12014-06-10 11:52:40 +05303573 }
3574
3575 pReqMsg->requestId = nla_get_u32(
3576 tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_REQUEST_ID]);
3577 hddLog(VOS_TRACE_LEVEL_INFO, FL("Req Id (%d)"), pReqMsg->requestId);
3578
3579 pReqMsg->sessionId = pAdapter->sessionId;
3580 hddLog(VOS_TRACE_LEVEL_INFO, FL("Session Id (%d)"), pReqMsg->sessionId);
3581
3582 /* Parse and fetch base period */
3583 if (!tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SCAN_CMD_PARAMS_BASE_PERIOD]) {
3584 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr base period failed"));
3585 goto fail;
3586 }
3587 pReqMsg->basePeriod = nla_get_u32(
3588 tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SCAN_CMD_PARAMS_BASE_PERIOD]);
3589 hddLog(VOS_TRACE_LEVEL_INFO, FL("Base Period (%d)"),
3590 pReqMsg->basePeriod);
3591
3592 /* Parse and fetch max AP per scan */
3593 if (!tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SCAN_CMD_PARAMS_MAX_AP_PER_SCAN]) {
3594 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr max_ap_per_scan failed"));
3595 goto fail;
3596 }
3597 pReqMsg->maxAPperScan = nla_get_u32(
3598 tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SCAN_CMD_PARAMS_MAX_AP_PER_SCAN]);
3599 hddLog(VOS_TRACE_LEVEL_INFO, FL("Max AP per Scan (%d)"),
3600 pReqMsg->maxAPperScan);
3601
3602 /* Parse and fetch report threshold */
3603 if (!tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SCAN_CMD_PARAMS_REPORT_THRESHOLD]) {
3604 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr report_threshold failed"));
3605 goto fail;
3606 }
3607 pReqMsg->reportThreshold = nla_get_u8(
3608 tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SCAN_CMD_PARAMS_REPORT_THRESHOLD]);
3609 hddLog(VOS_TRACE_LEVEL_INFO, FL("Report Threshold (%d)"),
3610 pReqMsg->reportThreshold);
3611
3612 /* Parse and fetch number of buckets */
3613 if (!tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SCAN_CMD_PARAMS_NUM_BUCKETS]) {
3614 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr number of buckets failed"));
3615 goto fail;
3616 }
3617 pReqMsg->numBuckets = nla_get_u8(
3618 tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SCAN_CMD_PARAMS_NUM_BUCKETS]);
3619 if (pReqMsg->numBuckets > WLAN_EXTSCAN_MAX_BUCKETS) {
3620 hddLog(VOS_TRACE_LEVEL_WARN, FL("Exceeded MAX number of buckets "
3621 "Setting numBuckets to %u"), WLAN_EXTSCAN_MAX_BUCKETS);
3622 pReqMsg->numBuckets = WLAN_EXTSCAN_MAX_BUCKETS;
3623 }
3624 hddLog(VOS_TRACE_LEVEL_INFO, FL("Number of Buckets (%d)"),
3625 pReqMsg->numBuckets);
3626 if (!tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC]) {
3627 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr bucket spec failed"));
3628 goto fail;
3629 }
3630
3631 nla_for_each_nested(buckets,
3632 tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC], rem1) {
3633 if(nla_parse(bucket,
3634 QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX,
3635 nla_data(buckets), nla_len(buckets), NULL)) { //policy
3636 hddLog(VOS_TRACE_LEVEL_ERROR, FL("nla_parse failed"));
3637 goto fail;
3638 }
3639
3640 /* Parse and fetch bucket spec */
3641 if (!bucket[QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_INDEX]) {
3642 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr bucket index failed"));
3643 goto fail;
3644 }
Dasari Srinivas8b2ce272014-09-16 16:57:30 +05303645
3646 pReqMsg->buckets[index].bucket = nla_get_u8(
3647 bucket[QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_INDEX]);
3648
3649 hddLog(VOS_TRACE_LEVEL_INFO, FL("Bucket spec Index (%d)"),
3650 pReqMsg->buckets[index].bucket);
Dino Mycle6fb96c12014-06-10 11:52:40 +05303651
3652 /* Parse and fetch wifi band */
3653 if (!bucket[QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_BAND]) {
3654 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr wifi band failed"));
3655 goto fail;
3656 }
Dasari Srinivas8b2ce272014-09-16 16:57:30 +05303657 pReqMsg->buckets[index].band = nla_get_u8(
Dino Mycle6fb96c12014-06-10 11:52:40 +05303658 bucket[QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_BAND]);
3659 hddLog(VOS_TRACE_LEVEL_INFO, FL("Wifi band (%d)"),
Dasari Srinivas8b2ce272014-09-16 16:57:30 +05303660 pReqMsg->buckets[index].band);
Dino Mycle6fb96c12014-06-10 11:52:40 +05303661
3662 /* Parse and fetch period */
3663 if (!bucket[QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_PERIOD]) {
3664 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr period failed"));
3665 goto fail;
3666 }
Dasari Srinivas8b2ce272014-09-16 16:57:30 +05303667 pReqMsg->buckets[index].period = nla_get_u32(
Dino Mycle6fb96c12014-06-10 11:52:40 +05303668 bucket[QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_PERIOD]);
3669 hddLog(VOS_TRACE_LEVEL_INFO, FL("period (%d)"),
Dasari Srinivas8b2ce272014-09-16 16:57:30 +05303670 pReqMsg->buckets[index].period);
Dino Mycle6fb96c12014-06-10 11:52:40 +05303671
3672 /* Parse and fetch report events */
3673 if (!bucket[QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_REPORT_EVENTS]) {
3674 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr report events failed"));
3675 goto fail;
3676 }
Dasari Srinivas8b2ce272014-09-16 16:57:30 +05303677 pReqMsg->buckets[index].reportEvents = nla_get_u8(
Dino Mycle6fb96c12014-06-10 11:52:40 +05303678 bucket[QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_REPORT_EVENTS]);
3679 hddLog(VOS_TRACE_LEVEL_INFO, FL("report events (%d)"),
Dasari Srinivas8b2ce272014-09-16 16:57:30 +05303680 pReqMsg->buckets[index].reportEvents);
Dino Mycle6fb96c12014-06-10 11:52:40 +05303681
3682 /* Parse and fetch number of channels */
Dasari Srinivas8b2ce272014-09-16 16:57:30 +05303683 if (!bucket[QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_NUM_CHANNEL_SPECS])
3684 {
Dino Mycle6fb96c12014-06-10 11:52:40 +05303685 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr num channels failed"));
3686 goto fail;
3687 }
Dasari Srinivas8b2ce272014-09-16 16:57:30 +05303688 pReqMsg->buckets[index].numChannels = nla_get_u32(
Dino Mycle6fb96c12014-06-10 11:52:40 +05303689 bucket[QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_NUM_CHANNEL_SPECS]);
3690 hddLog(VOS_TRACE_LEVEL_INFO, FL("num channels (%d)"),
Dasari Srinivas8b2ce272014-09-16 16:57:30 +05303691 pReqMsg->buckets[index].numChannels);
Dino Mycle6fb96c12014-06-10 11:52:40 +05303692
3693 if (!bucket[QCA_WLAN_VENDOR_ATTR_EXTSCAN_CHANNEL_SPEC]) {
3694 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr channel spec failed"));
3695 goto fail;
3696 }
3697
3698 j = 0;
3699 nla_for_each_nested(channels,
3700 bucket[QCA_WLAN_VENDOR_ATTR_EXTSCAN_CHANNEL_SPEC], rem2) {
3701 if(nla_parse(channel,
3702 QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX,
3703 nla_data(channels), nla_len(channels),
3704 NULL)) { //wlan_hdd_extscan_config_policy here
3705 hddLog(VOS_TRACE_LEVEL_ERROR, FL("nla_parse failed"));
3706 goto fail;
3707 }
3708
3709 /* Parse and fetch channel */
3710 if (!channel[QCA_WLAN_VENDOR_ATTR_EXTSCAN_CHANNEL_SPEC_CHANNEL]) {
3711 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr channel failed"));
3712 goto fail;
3713 }
Dasari Srinivas8b2ce272014-09-16 16:57:30 +05303714 pReqMsg->buckets[index].channels[j].channel = nla_get_u32(
Dino Mycle6fb96c12014-06-10 11:52:40 +05303715 channel[QCA_WLAN_VENDOR_ATTR_EXTSCAN_CHANNEL_SPEC_CHANNEL]);
3716 hddLog(VOS_TRACE_LEVEL_INFO, FL("channel (%u)"),
Dasari Srinivas8b2ce272014-09-16 16:57:30 +05303717 pReqMsg->buckets[index].channels[j].channel);
Dino Mycle6fb96c12014-06-10 11:52:40 +05303718
3719 /* Parse and fetch dwell time */
3720 if (!channel[QCA_WLAN_VENDOR_ATTR_EXTSCAN_CHANNEL_SPEC_DWELL_TIME]) {
3721 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr dwelltime failed"));
3722 goto fail;
3723 }
Dasari Srinivas8b2ce272014-09-16 16:57:30 +05303724 pReqMsg->buckets[index].channels[j].dwellTimeMs = nla_get_u32(
Dino Mycle6fb96c12014-06-10 11:52:40 +05303725 channel[QCA_WLAN_VENDOR_ATTR_EXTSCAN_CHANNEL_SPEC_DWELL_TIME]);
3726 hddLog(VOS_TRACE_LEVEL_INFO, FL("Dwell time (%u ms)"),
Dasari Srinivas8b2ce272014-09-16 16:57:30 +05303727 pReqMsg->buckets[index].channels[j].dwellTimeMs);
Dino Mycle6fb96c12014-06-10 11:52:40 +05303728
3729 /* Parse and fetch channel spec passive */
3730 if (!channel[QCA_WLAN_VENDOR_ATTR_EXTSCAN_CHANNEL_SPEC_PASSIVE]) {
3731 hddLog(VOS_TRACE_LEVEL_ERROR,
3732 FL("attr channel spec passive failed"));
3733 goto fail;
3734 }
Dasari Srinivas8b2ce272014-09-16 16:57:30 +05303735 pReqMsg->buckets[index].channels[j].passive = nla_get_u8(
Dino Mycle6fb96c12014-06-10 11:52:40 +05303736 channel[QCA_WLAN_VENDOR_ATTR_EXTSCAN_CHANNEL_SPEC_PASSIVE]);
3737 hddLog(VOS_TRACE_LEVEL_INFO, FL("Chnl spec passive (%u)"),
Dasari Srinivas8b2ce272014-09-16 16:57:30 +05303738 pReqMsg->buckets[index].channels[j].passive);
Dino Mycle6fb96c12014-06-10 11:52:40 +05303739 j++;
3740 }
Dasari Srinivas8b2ce272014-09-16 16:57:30 +05303741 index++;
Dino Mycle6fb96c12014-06-10 11:52:40 +05303742 }
3743 status = sme_EXTScanStart(pHddCtx->hHal, pReqMsg);
3744 if (!HAL_STATUS_SUCCESS(status)) {
3745 hddLog(VOS_TRACE_LEVEL_ERROR,
3746 FL("sme_EXTScanStart failed(err=%d)"), status);
3747 vos_mem_free(pReqMsg);
3748 return -EINVAL;
3749 }
3750
Dino Myclee8843b32014-07-04 14:21:45 +05303751 vos_mem_free(pReqMsg);
Dino Mycle6fb96c12014-06-10 11:52:40 +05303752 return 0;
3753
3754fail:
3755 vos_mem_free(pReqMsg);
3756 return -EINVAL;
3757}
3758
3759static int wlan_hdd_cfg80211_extscan_stop(struct wiphy *wiphy,
3760 struct wireless_dev *wdev,
3761 void *data, int dataLen)
3762{
Dino Myclee8843b32014-07-04 14:21:45 +05303763 tSirEXTScanStopReqParams reqMsg;
Dino Mycle6fb96c12014-06-10 11:52:40 +05303764 struct net_device *dev = wdev->netdev;
3765 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
3766 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
3767 struct nlattr *tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX + 1];
3768 eHalStatus status;
3769
3770 status = wlan_hdd_validate_context(pHddCtx);
3771 if (0 != status)
3772 {
3773 hddLog(VOS_TRACE_LEVEL_ERROR,
3774 FL("HDD context is not valid"));
3775 return -EINVAL;
3776 }
Dino Myclee8843b32014-07-04 14:21:45 +05303777 /* check the EXTScan Capability */
3778 if ( (TRUE != pHddCtx->cfg_ini->fEnableEXTScan) ||
3779 (TRUE != sme_IsFeatureSupportedByFW(EXTENDED_SCAN)))
3780 {
3781 hddLog(VOS_TRACE_LEVEL_ERROR,
3782 FL("EXTScan not enabled/supported by Firmware"));
3783 return -EINVAL;
3784 }
3785
Dino Mycle6fb96c12014-06-10 11:52:40 +05303786 if (nla_parse(tb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX,
3787 data, dataLen,
3788 wlan_hdd_extscan_config_policy)) {
3789 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Invalid ATTR"));
3790 return -EINVAL;
3791 }
3792
3793 /* Parse and fetch request Id */
3794 if (!tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_REQUEST_ID]) {
3795 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr request id failed"));
3796 return -EINVAL;
3797 }
3798
Dino Myclee8843b32014-07-04 14:21:45 +05303799 reqMsg.requestId = nla_get_u32(
Dino Mycle6fb96c12014-06-10 11:52:40 +05303800 tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_REQUEST_ID]);
Dino Myclee8843b32014-07-04 14:21:45 +05303801 hddLog(VOS_TRACE_LEVEL_INFO, FL("Req Id (%d)"), reqMsg.requestId);
Dino Mycle6fb96c12014-06-10 11:52:40 +05303802
Dino Myclee8843b32014-07-04 14:21:45 +05303803 reqMsg.sessionId = pAdapter->sessionId;
3804 hddLog(VOS_TRACE_LEVEL_INFO, FL("Session Id (%d)"), reqMsg.sessionId);
Dino Mycle6fb96c12014-06-10 11:52:40 +05303805
Dino Myclee8843b32014-07-04 14:21:45 +05303806 status = sme_EXTScanStop(pHddCtx->hHal, &reqMsg);
Dino Mycle6fb96c12014-06-10 11:52:40 +05303807 if (!HAL_STATUS_SUCCESS(status)) {
3808 hddLog(VOS_TRACE_LEVEL_ERROR,
3809 FL("sme_EXTScanStop failed(err=%d)"), status);
Dino Mycle6fb96c12014-06-10 11:52:40 +05303810 return -EINVAL;
3811 }
3812
3813 return 0;
3814}
3815
3816static int wlan_hdd_cfg80211_extscan_reset_bssid_hotlist(struct wiphy *wiphy,
3817 struct wireless_dev *wdev,
3818 void *data, int dataLen)
3819{
Dino Myclee8843b32014-07-04 14:21:45 +05303820 tSirEXTScanResetBssidHotlistReqParams reqMsg;
Dino Mycle6fb96c12014-06-10 11:52:40 +05303821 struct net_device *dev = wdev->netdev;
3822 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
3823 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
3824 struct nlattr *tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX + 1];
3825 eHalStatus status;
3826
3827 status = wlan_hdd_validate_context(pHddCtx);
3828 if (0 != status)
3829 {
3830 hddLog(VOS_TRACE_LEVEL_ERROR,
3831 FL("HDD context is not valid"));
3832 return -EINVAL;
3833 }
Dino Myclee8843b32014-07-04 14:21:45 +05303834 /* check the EXTScan Capability */
3835 if ( (TRUE != pHddCtx->cfg_ini->fEnableEXTScan) ||
3836 (TRUE != sme_IsFeatureSupportedByFW(EXTENDED_SCAN)))
3837 {
3838 hddLog(VOS_TRACE_LEVEL_ERROR,
3839 FL("EXTScan not enabled/supported by Firmware"));
3840 return -EINVAL;
3841 }
3842
Dino Mycle6fb96c12014-06-10 11:52:40 +05303843 if (nla_parse(tb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX,
3844 data, dataLen,
3845 wlan_hdd_extscan_config_policy)) {
3846 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Invalid ATTR"));
3847 return -EINVAL;
3848 }
3849
3850 /* Parse and fetch request Id */
3851 if (!tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_REQUEST_ID]) {
3852 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr request id failed"));
3853 return -EINVAL;
3854 }
3855
Dino Myclee8843b32014-07-04 14:21:45 +05303856 reqMsg.requestId = nla_get_u32(
Dino Mycle6fb96c12014-06-10 11:52:40 +05303857 tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_REQUEST_ID]);
Dino Myclee8843b32014-07-04 14:21:45 +05303858 hddLog(VOS_TRACE_LEVEL_INFO, FL("Req Id (%d)"), reqMsg.requestId);
Dino Mycle6fb96c12014-06-10 11:52:40 +05303859
Dino Myclee8843b32014-07-04 14:21:45 +05303860 reqMsg.sessionId = pAdapter->sessionId;
3861 hddLog(VOS_TRACE_LEVEL_INFO, FL("Session Id (%d)"), reqMsg.sessionId);
Dino Mycle6fb96c12014-06-10 11:52:40 +05303862
Dino Myclee8843b32014-07-04 14:21:45 +05303863 status = sme_ResetBssHotlist(pHddCtx->hHal, &reqMsg);
Dino Mycle6fb96c12014-06-10 11:52:40 +05303864 if (!HAL_STATUS_SUCCESS(status)) {
3865 hddLog(VOS_TRACE_LEVEL_ERROR,
3866 FL("sme_ResetBssHotlist failed(err=%d)"), status);
Dino Mycle6fb96c12014-06-10 11:52:40 +05303867 return -EINVAL;
3868 }
3869
3870 return 0;
3871}
3872
3873static int wlan_hdd_cfg80211_extscan_reset_significant_change(
3874 struct wiphy *wiphy,
3875 struct wireless_dev *wdev,
3876 void *data, int dataLen)
3877{
Dino Myclee8843b32014-07-04 14:21:45 +05303878 tSirEXTScanResetSignificantChangeReqParams reqMsg;
Dino Mycle6fb96c12014-06-10 11:52:40 +05303879 struct net_device *dev = wdev->netdev;
3880 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
3881 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
3882 struct nlattr *tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX + 1];
3883 eHalStatus status;
3884
3885 hddLog(VOS_TRACE_LEVEL_INFO, FL(" Entering"));
3886 status = wlan_hdd_validate_context(pHddCtx);
3887 if (0 != status)
3888 {
3889 hddLog(VOS_TRACE_LEVEL_ERROR,
3890 FL("HDD context is not valid"));
3891 return -EINVAL;
3892 }
Dino Myclee8843b32014-07-04 14:21:45 +05303893 /* check the EXTScan Capability */
3894 if ( (TRUE != pHddCtx->cfg_ini->fEnableEXTScan) ||
3895 (TRUE != sme_IsFeatureSupportedByFW(EXTENDED_SCAN)))
3896 {
3897 hddLog(VOS_TRACE_LEVEL_ERROR,
3898 FL("EXTScan not enabled/supported by Firmware"));
3899 return -EINVAL;
3900 }
3901
Dino Mycle6fb96c12014-06-10 11:52:40 +05303902 if (nla_parse(tb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX,
3903 data, dataLen,
3904 wlan_hdd_extscan_config_policy)) {
3905 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Invalid ATTR"));
3906 return -EINVAL;
3907 }
3908
3909 /* Parse and fetch request Id */
3910 if (!tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_REQUEST_ID]) {
3911 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr request id failed"));
3912 return -EINVAL;
3913 }
3914
Dino Mycle6fb96c12014-06-10 11:52:40 +05303915
Dino Myclee8843b32014-07-04 14:21:45 +05303916 reqMsg.requestId = nla_get_u32(
Dino Mycle6fb96c12014-06-10 11:52:40 +05303917 tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_REQUEST_ID]);
Dino Myclee8843b32014-07-04 14:21:45 +05303918 hddLog(VOS_TRACE_LEVEL_INFO, FL("Req Id (%d)"), reqMsg.requestId);
Dino Mycle6fb96c12014-06-10 11:52:40 +05303919
Dino Myclee8843b32014-07-04 14:21:45 +05303920 reqMsg.sessionId = pAdapter->sessionId;
3921 hddLog(VOS_TRACE_LEVEL_INFO, FL("Session Id (%d)"), reqMsg.sessionId);
Dino Mycle6fb96c12014-06-10 11:52:40 +05303922
Dino Myclee8843b32014-07-04 14:21:45 +05303923 status = sme_ResetSignificantChange(pHddCtx->hHal, &reqMsg);
Dino Mycle6fb96c12014-06-10 11:52:40 +05303924 if (!HAL_STATUS_SUCCESS(status)) {
3925 hddLog(VOS_TRACE_LEVEL_ERROR,
3926 FL("sme_ResetSignificantChange failed(err=%d)"), status);
Dino Mycle6fb96c12014-06-10 11:52:40 +05303927 return -EINVAL;
3928 }
3929
3930 hddLog(VOS_TRACE_LEVEL_ERROR, FL(" Exiting"));
3931 return 0;
3932}
3933
3934#endif /* WLAN_FEATURE_EXTSCAN */
3935
Atul Mittal115287b2014-07-08 13:26:33 +05303936/*EXT TDLS*/
3937static const struct nla_policy
3938wlan_hdd_tdls_config_enable_policy[QCA_WLAN_VENDOR_ATTR_TDLS_ENABLE_MAX +1] =
3939{
3940 [QCA_WLAN_VENDOR_ATTR_TDLS_ENABLE_MAC_ADDR] = {.type = NLA_UNSPEC },
3941 [QCA_WLAN_VENDOR_ATTR_TDLS_ENABLE_CHANNEL] = {.type = NLA_S32 },
3942 [QCA_WLAN_VENDOR_ATTR_TDLS_ENABLE_GLOBAL_OPERATING_CLASS] =
3943 {.type = NLA_S32 },
3944 [QCA_WLAN_VENDOR_ATTR_TDLS_ENABLE_MAX_LATENCY_MS] = {.type = NLA_S32 },
3945 [QCA_WLAN_VENDOR_ATTR_TDLS_ENABLE_MIN_BANDWIDTH_KBPS] = {.type = NLA_S32 },
3946
3947};
3948
3949static const struct nla_policy
3950wlan_hdd_tdls_config_disable_policy[QCA_WLAN_VENDOR_ATTR_TDLS_DISABLE_MAX +1] =
3951{
3952 [QCA_WLAN_VENDOR_ATTR_TDLS_DISABLE_MAC_ADDR] = {.type = NLA_UNSPEC },
3953
3954};
3955
3956static const struct nla_policy
3957wlan_hdd_tdls_config_state_change_policy[
3958 QCA_WLAN_VENDOR_ATTR_TDLS_STATE_MAX +1] =
3959{
3960 [QCA_WLAN_VENDOR_ATTR_TDLS_STATE_MAC_ADDR] = {.type = NLA_UNSPEC },
3961 [QCA_WLAN_VENDOR_ATTR_TDLS_NEW_STATE] = {.type = NLA_S32 },
3962 [QCA_WLAN_VENDOR_ATTR_TDLS_STATE_REASON] = {.type = NLA_S32 },
3963
3964};
3965
3966static const struct nla_policy
3967wlan_hdd_tdls_config_get_status_policy[
3968 QCA_WLAN_VENDOR_ATTR_TDLS_GET_STATUS_MAX +1] =
3969{
3970 [QCA_WLAN_VENDOR_ATTR_TDLS_GET_STATUS_MAC_ADDR] = {.type = NLA_UNSPEC },
3971 [QCA_WLAN_VENDOR_ATTR_TDLS_GET_STATUS_STATE] = {.type = NLA_S32 },
3972 [QCA_WLAN_VENDOR_ATTR_TDLS_GET_STATUS_REASON] = {.type = NLA_S32 },
3973
3974};
3975static int wlan_hdd_cfg80211_exttdls_get_status(struct wiphy *wiphy,
3976 struct wireless_dev *wdev,
3977 void *data,
3978 int data_len)
3979{
3980 u8 peer[6] = {0};
3981 struct net_device *dev = wdev->netdev;
3982 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
3983 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
3984 struct nlattr *tb[QCA_WLAN_VENDOR_ATTR_TDLS_GET_STATUS_MAX + 1];
3985 eHalStatus ret;
3986 tANI_S32 state;
3987 tANI_S32 reason;
3988 struct sk_buff *skb = NULL;
3989
3990 ret = wlan_hdd_validate_context(pHddCtx);
3991 if (0 != ret) {
3992
3993 return -EINVAL;
3994 }
3995 if (pHddCtx->cfg_ini->fTDLSExternalControl == FALSE) {
3996
3997 return -ENOTSUPP;
3998 }
3999 if (nla_parse(tb, QCA_WLAN_VENDOR_ATTR_TDLS_GET_STATUS_MAX,
4000 data, data_len,
4001 wlan_hdd_tdls_config_get_status_policy)) {
4002 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Invalid ATTR"));
4003 return -EINVAL;
4004 }
4005
4006 /* Parse and fetch mac address */
4007 if (!tb[QCA_WLAN_VENDOR_ATTR_TDLS_GET_STATUS_MAC_ADDR]) {
4008 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr mac addr failed"));
4009 return -EINVAL;
4010 }
4011
4012 memcpy(peer, nla_data(
4013 tb[QCA_WLAN_VENDOR_ATTR_TDLS_GET_STATUS_MAC_ADDR]),
4014 sizeof(peer));
4015 hddLog(VOS_TRACE_LEVEL_INFO, FL(MAC_ADDRESS_STR),MAC_ADDR_ARRAY(peer));
4016
4017 ret = wlan_hdd_tdls_get_status(pAdapter, peer, &state, &reason);
4018
4019 if (0 != ret) {
4020 hddLog(VOS_TRACE_LEVEL_ERROR,
4021 FL("get status Failed"));
4022 return -EINVAL;
4023 }
4024 skb = cfg80211_vendor_cmd_alloc_reply_skb(wiphy,
4025 2 * sizeof(s32) +
4026 NLMSG_HDRLEN);
4027
4028 if (!skb) {
4029 hddLog(VOS_TRACE_LEVEL_ERROR,
4030 FL("cfg80211_vendor_cmd_alloc_reply_skb failed"));
4031 return -EINVAL;
4032 }
4033 hddLog(VOS_TRACE_LEVEL_INFO, FL("Reason (%d) Status (%d) tdls peer" MAC_ADDRESS_STR),
4034 reason,
4035 state,
4036 MAC_ADDR_ARRAY(peer));
4037
4038 if (nla_put_s32(skb, QCA_WLAN_VENDOR_ATTR_TDLS_GET_STATUS_STATE, state) ||
4039 nla_put_s32(skb, QCA_WLAN_VENDOR_ATTR_TDLS_GET_STATUS_REASON, reason)) {
4040
4041 hddLog(VOS_TRACE_LEVEL_ERROR, FL("nla put fail"));
4042 goto nla_put_failure;
4043 }
4044
4045 return cfg80211_vendor_cmd_reply(skb);
4046
4047nla_put_failure:
4048 kfree_skb(skb);
4049 return -EINVAL;
4050}
4051
4052static int wlan_hdd_cfg80211_exttdls_callback(tANI_U8* mac,
4053 tANI_S32 state,
4054 tANI_S32 reason,
4055 void *ctx)
4056{
4057 hdd_adapter_t* pAdapter = (hdd_adapter_t*)ctx;
4058 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
4059 struct sk_buff *skb = NULL;
4060
4061 if (wlan_hdd_validate_context(pHddCtx)) {
4062 hddLog(VOS_TRACE_LEVEL_ERROR, FL("HDD context is not valid "));
4063 return -EINVAL;
4064 }
4065
4066 if (pHddCtx->cfg_ini->fTDLSExternalControl == FALSE) {
4067
4068 return -ENOTSUPP;
4069 }
4070 skb = cfg80211_vendor_event_alloc(
4071 pHddCtx->wiphy,
4072 EXTTDLS_EVENT_BUF_SIZE + NLMSG_HDRLEN,
4073 QCA_NL80211_VENDOR_SUBCMD_TDLS_STATE_CHANGE_INDEX,
4074 GFP_KERNEL);
4075
4076 if (!skb) {
4077 hddLog(VOS_TRACE_LEVEL_ERROR,
4078 FL("cfg80211_vendor_event_alloc failed"));
4079 return -EINVAL;
4080 }
4081 hddLog(VOS_TRACE_LEVEL_INFO, FL("Entering "));
4082 hddLog(VOS_TRACE_LEVEL_INFO, "Reason (%d) Status (%d)", reason, state);
4083 hddLog(VOS_TRACE_LEVEL_WARN, "tdls peer " MAC_ADDRESS_STR,
4084 MAC_ADDR_ARRAY(mac));
4085
4086 if (nla_put(skb, QCA_WLAN_VENDOR_ATTR_TDLS_STATE_MAC_ADDR,
4087 VOS_MAC_ADDR_SIZE, mac) ||
4088 nla_put_s32(skb, QCA_WLAN_VENDOR_ATTR_TDLS_NEW_STATE, state) ||
4089 nla_put_s32(skb, QCA_WLAN_VENDOR_ATTR_TDLS_STATE_REASON, reason)
4090 ) {
4091
4092 hddLog(VOS_TRACE_LEVEL_ERROR, FL("nla put fail"));
4093 goto nla_put_failure;
4094 }
4095
4096 cfg80211_vendor_event(skb, GFP_KERNEL);
4097 return (0);
4098
4099nla_put_failure:
4100 kfree_skb(skb);
4101 return -EINVAL;
4102}
4103
4104static int wlan_hdd_cfg80211_exttdls_enable(struct wiphy *wiphy,
4105 struct wireless_dev *wdev,
4106 void *data,
4107 int data_len)
4108{
4109 u8 peer[6] = {0};
4110 struct net_device *dev = wdev->netdev;
4111 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
4112 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
4113 struct nlattr *tb[QCA_WLAN_VENDOR_ATTR_TDLS_ENABLE_MAX + 1];
4114 eHalStatus status;
4115 tdls_req_params_t pReqMsg = {0};
4116
4117 status = wlan_hdd_validate_context(pHddCtx);
4118 if (0 != status) {
4119 hddLog(VOS_TRACE_LEVEL_ERROR,
4120 FL("HDD context is not valid"));
4121 return -EINVAL;
4122 }
4123 if (pHddCtx->cfg_ini->fTDLSExternalControl == FALSE) {
4124
4125 return -ENOTSUPP;
4126 }
4127 if (nla_parse(tb, QCA_WLAN_VENDOR_ATTR_TDLS_ENABLE_MAX,
4128 data, data_len,
4129 wlan_hdd_tdls_config_enable_policy)) {
4130 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Invalid ATTR"));
4131 return -EINVAL;
4132 }
4133
4134 /* Parse and fetch mac address */
4135 if (!tb[QCA_WLAN_VENDOR_ATTR_TDLS_ENABLE_MAC_ADDR]) {
4136 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr mac addr failed"));
4137 return -EINVAL;
4138 }
4139
4140 memcpy(peer, nla_data(
4141 tb[QCA_WLAN_VENDOR_ATTR_TDLS_ENABLE_MAC_ADDR]),
4142 sizeof(peer));
4143 hddLog(VOS_TRACE_LEVEL_INFO, FL(MAC_ADDRESS_STR),MAC_ADDR_ARRAY(peer));
4144
4145 /* Parse and fetch channel */
4146 if (!tb[QCA_WLAN_VENDOR_ATTR_TDLS_ENABLE_CHANNEL]) {
4147 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr channel failed"));
4148 return -EINVAL;
4149 }
4150 pReqMsg.channel = nla_get_s32(
4151 tb[QCA_WLAN_VENDOR_ATTR_TDLS_ENABLE_CHANNEL]);
4152 hddLog(VOS_TRACE_LEVEL_INFO, FL("Channel Num (%d)"), pReqMsg.channel);
4153
4154 /* Parse and fetch global operating class */
4155 if (!tb[QCA_WLAN_VENDOR_ATTR_TDLS_ENABLE_GLOBAL_OPERATING_CLASS]) {
4156 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr operating class failed"));
4157 return -EINVAL;
4158 }
4159 pReqMsg.global_operating_class = nla_get_s32(
4160 tb[QCA_WLAN_VENDOR_ATTR_TDLS_ENABLE_GLOBAL_OPERATING_CLASS]);
4161 hddLog(VOS_TRACE_LEVEL_INFO, FL("Operating class (%d)"),
4162 pReqMsg.global_operating_class);
4163
4164 /* Parse and fetch latency ms */
4165 if (!tb[QCA_WLAN_VENDOR_ATTR_TDLS_ENABLE_MAX_LATENCY_MS]) {
4166 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr latency failed"));
4167 return -EINVAL;
4168 }
4169 pReqMsg.max_latency_ms = nla_get_s32(
4170 tb[QCA_WLAN_VENDOR_ATTR_TDLS_ENABLE_MAX_LATENCY_MS]);
4171 hddLog(VOS_TRACE_LEVEL_INFO, FL("Latency (%d)"),
4172 pReqMsg.max_latency_ms);
4173
4174 /* Parse and fetch required bandwidth kbps */
4175 if (!tb[QCA_WLAN_VENDOR_ATTR_TDLS_ENABLE_MIN_BANDWIDTH_KBPS]) {
4176 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr bandwidth failed"));
4177 return -EINVAL;
4178 }
4179
4180 pReqMsg.min_bandwidth_kbps = nla_get_s32(
4181 tb[QCA_WLAN_VENDOR_ATTR_TDLS_ENABLE_MIN_BANDWIDTH_KBPS]);
4182 hddLog(VOS_TRACE_LEVEL_INFO, FL("Bandwidth (%d)"),
4183 pReqMsg.min_bandwidth_kbps);
4184
4185 return (wlan_hdd_tdls_extctrl_config_peer(pAdapter,
4186 peer,
4187 wlan_hdd_cfg80211_exttdls_callback));
4188}
4189
4190static int wlan_hdd_cfg80211_exttdls_disable(struct wiphy *wiphy,
4191 struct wireless_dev *wdev,
4192 void *data,
4193 int data_len)
4194{
4195 u8 peer[6] = {0};
4196 struct net_device *dev = wdev->netdev;
4197 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
4198 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
4199 struct nlattr *tb[QCA_WLAN_VENDOR_ATTR_TDLS_DISABLE_MAX + 1];
4200 eHalStatus status;
4201
4202 status = wlan_hdd_validate_context(pHddCtx);
4203 if (0 != status) {
4204 hddLog(VOS_TRACE_LEVEL_ERROR,
4205 FL("HDD context is not valid"));
4206 return -EINVAL;
4207 }
4208 if (pHddCtx->cfg_ini->fTDLSExternalControl == FALSE) {
4209
4210 return -ENOTSUPP;
4211 }
4212 if (nla_parse(tb, QCA_WLAN_VENDOR_ATTR_TDLS_DISABLE_MAX,
4213 data, data_len,
4214 wlan_hdd_tdls_config_disable_policy)) {
4215 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Invalid ATTR"));
4216 return -EINVAL;
4217 }
4218 /* Parse and fetch mac address */
4219 if (!tb[QCA_WLAN_VENDOR_ATTR_TDLS_DISABLE_MAC_ADDR]) {
4220 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr mac addr failed"));
4221 return -EINVAL;
4222 }
4223
4224 memcpy(peer, nla_data(
4225 tb[QCA_WLAN_VENDOR_ATTR_TDLS_DISABLE_MAC_ADDR]),
4226 sizeof(peer));
4227 hddLog(VOS_TRACE_LEVEL_INFO, FL(MAC_ADDRESS_STR),MAC_ADDR_ARRAY(peer));
4228
4229 return (wlan_hdd_tdls_extctrl_deconfig_peer(pAdapter, peer));
4230}
4231
4232
Sunil Duttc69bccb2014-05-26 21:30:20 +05304233const struct wiphy_vendor_command hdd_wiphy_vendor_commands[] =
4234{
4235#ifdef WLAN_FEATURE_LINK_LAYER_STATS
4236 {
4237 .info.vendor_id = QCA_NL80211_VENDOR_ID,
4238 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_LL_STATS_CLR,
4239 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
4240 WIPHY_VENDOR_CMD_NEED_NETDEV |
4241 WIPHY_VENDOR_CMD_NEED_RUNNING,
4242 .doit = wlan_hdd_cfg80211_ll_stats_clear
4243 },
4244
4245 {
4246 .info.vendor_id = QCA_NL80211_VENDOR_ID,
4247 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_LL_STATS_SET,
4248 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
4249 WIPHY_VENDOR_CMD_NEED_NETDEV |
4250 WIPHY_VENDOR_CMD_NEED_RUNNING,
4251 .doit = wlan_hdd_cfg80211_ll_stats_set
4252 },
4253
4254 {
4255 .info.vendor_id = QCA_NL80211_VENDOR_ID,
4256 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_LL_STATS_GET,
4257 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
4258 WIPHY_VENDOR_CMD_NEED_NETDEV |
4259 WIPHY_VENDOR_CMD_NEED_RUNNING,
4260 .doit = wlan_hdd_cfg80211_ll_stats_get
Dino Mycle6fb96c12014-06-10 11:52:40 +05304261 },
Sunil Duttc69bccb2014-05-26 21:30:20 +05304262#endif /* WLAN_FEATURE_LINK_LAYER_STATS */
Dino Mycle6fb96c12014-06-10 11:52:40 +05304263#ifdef WLAN_FEATURE_EXTSCAN
4264 {
4265 .info.vendor_id = QCA_NL80211_VENDOR_ID,
4266 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_START,
4267 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
4268 WIPHY_VENDOR_CMD_NEED_NETDEV |
4269 WIPHY_VENDOR_CMD_NEED_RUNNING,
4270 .doit = wlan_hdd_cfg80211_extscan_start
4271 },
4272 {
4273 .info.vendor_id = QCA_NL80211_VENDOR_ID,
4274 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_STOP,
4275 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
4276 WIPHY_VENDOR_CMD_NEED_NETDEV |
4277 WIPHY_VENDOR_CMD_NEED_RUNNING,
4278 .doit = wlan_hdd_cfg80211_extscan_stop
4279 },
4280 {
4281 .info.vendor_id = QCA_NL80211_VENDOR_ID,
4282 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_GET_VALID_CHANNELS,
4283 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
4284 WIPHY_VENDOR_CMD_NEED_NETDEV,
4285 .doit = wlan_hdd_cfg80211_extscan_get_valid_channels
4286 },
4287 {
4288 .info.vendor_id = QCA_NL80211_VENDOR_ID,
4289 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_GET_CAPABILITIES,
4290 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
4291 WIPHY_VENDOR_CMD_NEED_NETDEV |
4292 WIPHY_VENDOR_CMD_NEED_RUNNING,
4293 .doit = wlan_hdd_cfg80211_extscan_get_capabilities
4294 },
4295 {
4296 .info.vendor_id = QCA_NL80211_VENDOR_ID,
4297 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_GET_CACHED_RESULTS,
4298 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
4299 WIPHY_VENDOR_CMD_NEED_NETDEV |
4300 WIPHY_VENDOR_CMD_NEED_RUNNING,
4301 .doit = wlan_hdd_cfg80211_extscan_get_cached_results
4302 },
4303 {
4304 .info.vendor_id = QCA_NL80211_VENDOR_ID,
4305 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_SET_BSSID_HOTLIST,
4306 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
4307 WIPHY_VENDOR_CMD_NEED_NETDEV |
4308 WIPHY_VENDOR_CMD_NEED_RUNNING,
4309 .doit = wlan_hdd_cfg80211_extscan_set_bssid_hotlist
4310 },
4311 {
4312 .info.vendor_id = QCA_NL80211_VENDOR_ID,
4313 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_RESET_BSSID_HOTLIST,
4314 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
4315 WIPHY_VENDOR_CMD_NEED_NETDEV |
4316 WIPHY_VENDOR_CMD_NEED_RUNNING,
4317 .doit = wlan_hdd_cfg80211_extscan_reset_bssid_hotlist
4318 },
4319 {
4320 .info.vendor_id = QCA_NL80211_VENDOR_ID,
4321 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_SET_SIGNIFICANT_CHANGE,
4322 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
4323 WIPHY_VENDOR_CMD_NEED_NETDEV |
4324 WIPHY_VENDOR_CMD_NEED_RUNNING,
4325 .doit = wlan_hdd_cfg80211_extscan_set_significant_change
4326 },
4327 {
4328 .info.vendor_id = QCA_NL80211_VENDOR_ID,
4329 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_RESET_SIGNIFICANT_CHANGE,
4330 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
4331 WIPHY_VENDOR_CMD_NEED_NETDEV |
4332 WIPHY_VENDOR_CMD_NEED_RUNNING,
4333 .doit = wlan_hdd_cfg80211_extscan_reset_significant_change
4334 },
4335#endif /* WLAN_FEATURE_EXTSCAN */
Atul Mittal115287b2014-07-08 13:26:33 +05304336/*EXT TDLS*/
4337 {
4338 .info.vendor_id = QCA_NL80211_VENDOR_ID,
4339 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_TDLS_ENABLE,
4340 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
4341 WIPHY_VENDOR_CMD_NEED_NETDEV |
4342 WIPHY_VENDOR_CMD_NEED_RUNNING,
4343 .doit = wlan_hdd_cfg80211_exttdls_enable
4344 },
4345 {
4346 .info.vendor_id = QCA_NL80211_VENDOR_ID,
4347 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_TDLS_DISABLE,
4348 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
4349 WIPHY_VENDOR_CMD_NEED_NETDEV |
4350 WIPHY_VENDOR_CMD_NEED_RUNNING,
4351 .doit = wlan_hdd_cfg80211_exttdls_disable
4352 },
4353 {
4354 .info.vendor_id = QCA_NL80211_VENDOR_ID,
4355 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_TDLS_GET_STATUS,
4356 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
4357 WIPHY_VENDOR_CMD_NEED_NETDEV,
4358 .doit = wlan_hdd_cfg80211_exttdls_get_status
4359 },
4360
Sunil Duttc69bccb2014-05-26 21:30:20 +05304361};
4362
Rajesh Chauhan98a31f82014-01-06 20:15:25 -08004363/* vendor specific events */
Sunil Duttc69bccb2014-05-26 21:30:20 +05304364static const
4365struct nl80211_vendor_cmd_info wlan_hdd_cfg80211_vendor_events[] =
Rajesh Chauhan98a31f82014-01-06 20:15:25 -08004366{
4367#ifdef FEATURE_WLAN_CH_AVOID
4368 {
Sunil Duttc69bccb2014-05-26 21:30:20 +05304369 .vendor_id = QCA_NL80211_VENDOR_ID,
4370 .subcmd = QCA_NL80211_VENDOR_SUBCMD_AVOID_FREQUENCY
Rajesh Chauhan98a31f82014-01-06 20:15:25 -08004371 },
Sunil Duttc69bccb2014-05-26 21:30:20 +05304372#endif /* FEATURE_WLAN_CH_AVOID Index = 0*/
4373#ifdef WLAN_FEATURE_LINK_LAYER_STATS
4374 {
4375 /* Index = 1*/
4376 .vendor_id = QCA_NL80211_VENDOR_ID,
4377 .subcmd = QCA_NL80211_VENDOR_SUBCMD_LL_STATS_SET
4378 },
4379 {
4380 /* Index = 2*/
4381 .vendor_id = QCA_NL80211_VENDOR_ID,
4382 .subcmd = QCA_NL80211_VENDOR_SUBCMD_LL_STATS_GET
4383 },
4384 {
4385 /* Index = 3*/
4386 .vendor_id = QCA_NL80211_VENDOR_ID,
4387 .subcmd = QCA_NL80211_VENDOR_SUBCMD_LL_STATS_CLR
4388 },
4389 {
4390 /* Index = 4*/
4391 .vendor_id = QCA_NL80211_VENDOR_ID,
4392 .subcmd = QCA_NL80211_VENDOR_SUBCMD_LL_STATS_RADIO_RESULTS
4393 },
4394 {
4395 /* Index = 5*/
4396 .vendor_id = QCA_NL80211_VENDOR_ID,
4397 .subcmd = QCA_NL80211_VENDOR_SUBCMD_LL_STATS_IFACE_RESULTS
4398 },
4399 {
4400 /* Index = 6*/
4401 .vendor_id = QCA_NL80211_VENDOR_ID,
4402 .subcmd = QCA_NL80211_VENDOR_SUBCMD_LL_STATS_PEERS_RESULTS
4403 },
4404#endif /* WLAN_FEATURE_LINK_LAYER_STATS */
Dino Mycle6fb96c12014-06-10 11:52:40 +05304405#ifdef WLAN_FEATURE_EXTSCAN
4406 {
4407 .vendor_id = QCA_NL80211_VENDOR_ID,
4408 .subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_START
4409 },
4410 {
4411 .vendor_id = QCA_NL80211_VENDOR_ID,
4412 .subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_STOP
4413 },
4414 {
4415 .vendor_id = QCA_NL80211_VENDOR_ID,
4416 .subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_GET_CAPABILITIES
4417 },
4418 {
4419 .vendor_id = QCA_NL80211_VENDOR_ID,
4420 .subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_GET_CACHED_RESULTS
4421 },
4422 {
4423 .vendor_id = QCA_NL80211_VENDOR_ID,
4424 .subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_SCAN_RESULTS_AVAILABLE
4425 },
4426 {
4427 .vendor_id = QCA_NL80211_VENDOR_ID,
4428 .subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_FULL_SCAN_RESULT
4429 },
4430 {
4431 .vendor_id = QCA_NL80211_VENDOR_ID,
4432 .subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_SCAN_EVENT
4433 },
4434 {
4435 .vendor_id = QCA_NL80211_VENDOR_ID,
4436 .subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_HOTLIST_AP_FOUND
4437 },
4438 {
4439 .vendor_id = QCA_NL80211_VENDOR_ID,
4440 .subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_SET_BSSID_HOTLIST
4441 },
4442 {
4443 .vendor_id = QCA_NL80211_VENDOR_ID,
4444 .subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_RESET_BSSID_HOTLIST
4445 },
4446 {
4447 .vendor_id = QCA_NL80211_VENDOR_ID,
4448 .subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_SIGNIFICANT_CHANGE
4449 },
4450 {
4451 .vendor_id = QCA_NL80211_VENDOR_ID,
4452 .subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_SET_SIGNIFICANT_CHANGE
4453 },
4454 {
4455 .vendor_id = QCA_NL80211_VENDOR_ID,
4456 .subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_RESET_SIGNIFICANT_CHANGE
4457 },
4458#endif /* WLAN_FEATURE_EXTSCAN */
Atul Mittal115287b2014-07-08 13:26:33 +05304459/*EXT TDLS*/
4460 {
4461 .vendor_id = QCA_NL80211_VENDOR_ID,
4462 .subcmd = QCA_NL80211_VENDOR_SUBCMD_TDLS_STATE
4463 },
Rajesh Chauhan98a31f82014-01-06 20:15:25 -08004464};
4465
Jeff Johnson295189b2012-06-20 16:38:30 -07004466/*
Madan Mohan Koyyalamudi71278262013-04-12 22:00:48 +05304467 * FUNCTION: wlan_hdd_cfg80211_wiphy_alloc
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304468 * This function is called by hdd_wlan_startup()
4469 * during initialization.
Madan Mohan Koyyalamudi71278262013-04-12 22:00:48 +05304470 * This function is used to allocate wiphy structure.
Jeff Johnson295189b2012-06-20 16:38:30 -07004471 */
Madan Mohan Koyyalamudi71278262013-04-12 22:00:48 +05304472struct wiphy *wlan_hdd_cfg80211_wiphy_alloc(int priv_size)
Jeff Johnson295189b2012-06-20 16:38:30 -07004473{
4474 struct wiphy *wiphy;
4475 ENTER();
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304476 /*
4477 * Create wiphy device
Jeff Johnson295189b2012-06-20 16:38:30 -07004478 */
4479 wiphy = wiphy_new(&wlan_hdd_cfg80211_ops, priv_size);
4480
4481 if (!wiphy)
4482 {
4483 /* Print error and jump into err label and free the memory */
4484 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: wiphy init failed", __func__);
4485 return NULL;
4486 }
4487
Sunil Duttc69bccb2014-05-26 21:30:20 +05304488
Jeff Johnson295189b2012-06-20 16:38:30 -07004489 return wiphy;
4490}
4491
4492/*
4493 * FUNCTION: wlan_hdd_cfg80211_update_band
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304494 * This function is called from the supplicant through a
Jeff Johnson295189b2012-06-20 16:38:30 -07004495 * private ioctl to change the band value
4496 */
4497int wlan_hdd_cfg80211_update_band(struct wiphy *wiphy, eCsrBand eBand)
4498{
Gopichand Nakkala1f7a64f2013-04-01 18:37:17 +05304499 int i, j;
4500 eNVChannelEnabledType channelEnabledState;
4501
Jeff Johnsone7245742012-09-05 17:12:55 -07004502 ENTER();
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05304503
Gopichand Nakkala1f7a64f2013-04-01 18:37:17 +05304504 for (i = 0; i < IEEE80211_NUM_BANDS; i++)
Jeff Johnson295189b2012-06-20 16:38:30 -07004505 {
Gopichand Nakkala1f7a64f2013-04-01 18:37:17 +05304506
4507 if (NULL == wiphy->bands[i])
4508 {
4509 hddLog(VOS_TRACE_LEVEL_ERROR,"%s: wiphy->bands[i] is NULL, i = %d",
4510 __func__, i);
4511 continue;
4512 }
4513
4514 for (j = 0; j < wiphy->bands[i]->n_channels; j++)
4515 {
4516 struct ieee80211_supported_band *band = wiphy->bands[i];
4517
4518 channelEnabledState = vos_nv_getChannelEnabledState(
4519 band->channels[j].hw_value);
4520
4521 if (IEEE80211_BAND_2GHZ == i && eCSR_BAND_5G == eBand) // 5G only
4522 {
4523 // Enable Social channels for P2P
4524 if (WLAN_HDD_IS_SOCIAL_CHANNEL(band->channels[j].center_freq) &&
4525 NV_CHANNEL_ENABLE == channelEnabledState)
4526 band->channels[j].flags &= ~IEEE80211_CHAN_DISABLED;
4527 else
4528 band->channels[j].flags |= IEEE80211_CHAN_DISABLED;
4529 continue;
4530 }
4531 else if (IEEE80211_BAND_5GHZ == i && eCSR_BAND_24 == eBand) // 2G only
4532 {
4533 band->channels[j].flags |= IEEE80211_CHAN_DISABLED;
4534 continue;
4535 }
4536
4537 if (NV_CHANNEL_DISABLE == channelEnabledState ||
4538 NV_CHANNEL_INVALID == channelEnabledState)
4539 {
4540 band->channels[j].flags |= IEEE80211_CHAN_DISABLED;
4541 }
4542 else if (NV_CHANNEL_DFS == channelEnabledState)
4543 {
4544 band->channels[j].flags &= ~IEEE80211_CHAN_DISABLED;
4545 band->channels[j].flags |= IEEE80211_CHAN_RADAR;
4546 }
4547 else
4548 {
4549 band->channels[j].flags &= ~(IEEE80211_CHAN_DISABLED
4550 |IEEE80211_CHAN_RADAR);
4551 }
4552 }
Jeff Johnson295189b2012-06-20 16:38:30 -07004553 }
4554 return 0;
4555}
4556/*
4557 * FUNCTION: wlan_hdd_cfg80211_init
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304558 * This function is called by hdd_wlan_startup()
4559 * during initialization.
Jeff Johnson295189b2012-06-20 16:38:30 -07004560 * This function is used to initialize and register wiphy structure.
4561 */
Madan Mohan Koyyalamudi71278262013-04-12 22:00:48 +05304562int wlan_hdd_cfg80211_init(struct device *dev,
Jeff Johnson295189b2012-06-20 16:38:30 -07004563 struct wiphy *wiphy,
4564 hdd_config_t *pCfg
4565 )
4566{
Gopichand Nakkala1f7a64f2013-04-01 18:37:17 +05304567 int i, j;
Vinay Krishna Erannafacf5e22014-02-24 13:16:25 +05304568 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
4569
Jeff Johnsone7245742012-09-05 17:12:55 -07004570 ENTER();
4571
Jeff Johnson295189b2012-06-20 16:38:30 -07004572 /* Now bind the underlying wlan device with wiphy */
4573 set_wiphy_dev(wiphy, dev);
4574
4575 wiphy->mgmt_stypes = wlan_hdd_txrx_stypes;
Amar Singhalfddc28c2013-09-05 13:03:40 -07004576
Kiet Lam6c583332013-10-14 05:37:09 +05304577#ifndef CONFIG_ENABLE_LINUX_REG
Amar Singhal0a402232013-10-11 20:57:16 -07004578 /* the flag for the other case would be initialzed in
4579 vos_init_wiphy_from_nv_bin */
Amar Singhal0a402232013-10-11 20:57:16 -07004580 wiphy->flags |= WIPHY_FLAG_STRICT_REGULATORY;
Kiet Lam6c583332013-10-14 05:37:09 +05304581#endif
Amar Singhala49cbc52013-10-08 18:37:44 -07004582
Amar Singhalfddc28c2013-09-05 13:03:40 -07004583 /* This will disable updating of NL channels from passive to
4584 * active if a beacon is received on passive channel. */
4585 wiphy->flags |= WIPHY_FLAG_DISABLE_BEACON_HINTS;
Amar Singhalf0073192013-09-20 12:34:56 -07004586
Amar Singhalfddc28c2013-09-05 13:03:40 -07004587
Amar Singhala49cbc52013-10-08 18:37:44 -07004588
Jeff Johnson04dd8a82012-06-29 20:41:40 -07004589#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,4,0))
Madan Mohan Koyyalamudi1b4afb02012-10-22 15:25:16 -07004590 wiphy->flags |= WIPHY_FLAG_HAVE_AP_SME
4591 | WIPHY_FLAG_AP_PROBE_RESP_OFFLOAD
4592 | WIPHY_FLAG_HAS_REMAIN_ON_CHANNEL
Jeff Johnsone7245742012-09-05 17:12:55 -07004593 | WIPHY_FLAG_OFFCHAN_TX;
Kiet Lam6c583332013-10-14 05:37:09 +05304594 wiphy->country_ie_pref = NL80211_COUNTRY_IE_IGNORE_CORE;
Jeff Johnson04dd8a82012-06-29 20:41:40 -07004595#endif
Amar Singhala49cbc52013-10-08 18:37:44 -07004596
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08004597#if defined (WLAN_FEATURE_VOWIFI_11R) || defined (FEATURE_WLAN_ESE) || defined(FEATURE_WLAN_LFR)
Srinivas Girigowda640728a2013-03-28 12:21:54 -07004598 if (pCfg->isFastTransitionEnabled
James Zmuda77fb5ae2013-01-29 08:00:17 -08004599#ifdef FEATURE_WLAN_LFR
Srinivas Girigowda640728a2013-03-28 12:21:54 -07004600 || pCfg->isFastRoamIniFeatureEnabled
4601#endif
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08004602#ifdef FEATURE_WLAN_ESE
4603 || pCfg->isEseIniFeatureEnabled
Srinivas Girigowda640728a2013-03-28 12:21:54 -07004604#endif
4605 )
4606 {
4607 wiphy->flags |= WIPHY_FLAG_SUPPORTS_FW_ROAM;
4608 }
James Zmuda77fb5ae2013-01-29 08:00:17 -08004609#endif
Mohit Khanna698ba2a2012-12-04 15:08:18 -08004610#ifdef FEATURE_WLAN_TDLS
4611 wiphy->flags |= WIPHY_FLAG_SUPPORTS_TDLS
4612 | WIPHY_FLAG_TDLS_EXTERNAL_SETUP;
4613#endif
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +05304614#ifdef FEATURE_WLAN_SCAN_PNO
Hardik Kantilal Patel3dfd8792013-11-13 20:34:57 +05304615 if (pCfg->configPNOScanSupport)
4616 {
4617 wiphy->flags |= WIPHY_FLAG_SUPPORTS_SCHED_SCAN;
4618 wiphy->max_sched_scan_ssids = SIR_PNO_MAX_SUPP_NETWORKS;
4619 wiphy->max_match_sets = SIR_PNO_MAX_SUPP_NETWORKS;
4620 wiphy->max_sched_scan_ie_len = SIR_MAC_MAX_IE_LENGTH;
4621 }
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +05304622#endif/*FEATURE_WLAN_SCAN_PNO*/
Mohit Khanna698ba2a2012-12-04 15:08:18 -08004623
Amar Singhalfddc28c2013-09-05 13:03:40 -07004624#ifdef CONFIG_ENABLE_LINUX_REG
Madan Mohan Koyyalamudic3a240c2012-09-28 15:34:08 -07004625 /* even with WIPHY_FLAG_CUSTOM_REGULATORY,
4626 driver can still register regulatory callback and
Amar Singhalfddc28c2013-09-05 13:03:40 -07004627 it will get regulatory settings in wiphy->band[], but
Madan Mohan Koyyalamudic3a240c2012-09-28 15:34:08 -07004628 driver need to determine what to do with both
4629 regulatory settings */
Amar Singhalfddc28c2013-09-05 13:03:40 -07004630
4631 wiphy->reg_notifier = wlan_hdd_linux_reg_notifier;
Amar Singhala49cbc52013-10-08 18:37:44 -07004632#else
4633 wiphy->reg_notifier = wlan_hdd_crda_reg_notifier;
Amar Singhalfddc28c2013-09-05 13:03:40 -07004634#endif
Jeff Johnson04dd8a82012-06-29 20:41:40 -07004635
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304636 wiphy->max_scan_ssids = MAX_SCAN_SSID;
4637
Madan Mohan Koyyalamudi6815b162013-07-19 17:17:46 +05304638 wiphy->max_scan_ie_len = SIR_MAC_MAX_IE_LENGTH;
Jeff Johnson295189b2012-06-20 16:38:30 -07004639
Gopichand Nakkalac005b7c2013-05-14 16:04:14 +05304640 wiphy->max_acl_mac_addrs = MAX_ACL_MAC_ADDRESS;
4641
Jeff Johnson295189b2012-06-20 16:38:30 -07004642 /* Supports STATION & AD-HOC modes right now */
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304643 wiphy->interface_modes = BIT(NL80211_IFTYPE_STATION)
Jeff Johnson295189b2012-06-20 16:38:30 -07004644 | BIT(NL80211_IFTYPE_ADHOC)
Jeff Johnson295189b2012-06-20 16:38:30 -07004645 | BIT(NL80211_IFTYPE_P2P_CLIENT)
4646 | BIT(NL80211_IFTYPE_P2P_GO)
Jeff Johnson295189b2012-06-20 16:38:30 -07004647 | BIT(NL80211_IFTYPE_AP);
4648
Rashmi Ramannabd3feb72014-02-25 16:14:48 +05304649 if( pCfg->advertiseConcurrentOperation )
Sudhir Sattayappa Kohalli278eee52013-01-16 17:35:13 -08004650 {
Rashmi Ramannabd3feb72014-02-25 16:14:48 +05304651#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,4,0))
4652 if( pCfg->enableMCC )
4653 {
4654 /* Currently, supports up to two channels */
4655 wlan_hdd_iface_combination.num_different_channels = 2;
Sudhir Sattayappa Kohalli278eee52013-01-16 17:35:13 -08004656
Rashmi Ramannabd3feb72014-02-25 16:14:48 +05304657 if( !pCfg->allowMCCGODiffBI )
4658 wlan_hdd_iface_combination.beacon_int_infra_match = true;
Sudhir Sattayappa Kohalli278eee52013-01-16 17:35:13 -08004659
Rashmi Ramannabd3feb72014-02-25 16:14:48 +05304660 }
4661 wiphy->iface_combinations = &wlan_hdd_iface_combination;
4662 wiphy->n_iface_combinations = 1;
Sudhir Sattayappa Kohalli278eee52013-01-16 17:35:13 -08004663#endif
Rashmi Ramannabd3feb72014-02-25 16:14:48 +05304664 }
Sudhir Sattayappa Kohalli278eee52013-01-16 17:35:13 -08004665
Jeff Johnson295189b2012-06-20 16:38:30 -07004666 /* Before registering we need to update the ht capabilitied based
4667 * on ini values*/
4668 if( !pCfg->ShortGI20MhzEnable )
4669 {
4670 wlan_hdd_band_2_4_GHZ.ht_cap.cap &= ~IEEE80211_HT_CAP_SGI_20;
4671 wlan_hdd_band_5_GHZ.ht_cap.cap &= ~IEEE80211_HT_CAP_SGI_20;
4672 wlan_hdd_band_p2p_2_4_GHZ.ht_cap.cap &= ~IEEE80211_HT_CAP_SGI_20;
4673 }
4674
4675 if( !pCfg->ShortGI40MhzEnable )
4676 {
4677 wlan_hdd_band_5_GHZ.ht_cap.cap &= ~IEEE80211_HT_CAP_SGI_40;
4678 }
4679
4680 if( !pCfg->nChannelBondingMode5GHz )
4681 {
4682 wlan_hdd_band_5_GHZ.ht_cap.cap &= ~IEEE80211_HT_CAP_SUP_WIDTH_20_40;
4683 }
4684
Gopichand Nakkala1f7a64f2013-04-01 18:37:17 +05304685 wiphy->bands[IEEE80211_BAND_2GHZ] = &wlan_hdd_band_2_4_GHZ;
Vinay Krishna Erannafacf5e22014-02-24 13:16:25 +05304686 if (true == hdd_is_5g_supported(pHddCtx))
4687 {
4688 wiphy->bands[IEEE80211_BAND_5GHZ] = &wlan_hdd_band_5_GHZ;
4689 }
Gopichand Nakkala1f7a64f2013-04-01 18:37:17 +05304690
4691 for (i = 0; i < IEEE80211_NUM_BANDS; i++)
4692 {
4693
4694 if (NULL == wiphy->bands[i])
4695 {
4696 hddLog(VOS_TRACE_LEVEL_ERROR,"%s: wiphy->bands[i] is NULL, i = %d",
4697 __func__, i);
4698 continue;
4699 }
4700
4701 for (j = 0; j < wiphy->bands[i]->n_channels; j++)
4702 {
4703 struct ieee80211_supported_band *band = wiphy->bands[i];
4704
4705 if (IEEE80211_BAND_2GHZ == i && eCSR_BAND_5G == pCfg->nBandCapability) // 5G only
4706 {
4707 // Enable social channels for P2P
4708 if (WLAN_HDD_IS_SOCIAL_CHANNEL(band->channels[j].center_freq))
4709 band->channels[j].flags &= ~IEEE80211_CHAN_DISABLED;
4710 else
4711 band->channels[j].flags |= IEEE80211_CHAN_DISABLED;
4712 continue;
4713 }
4714 else if (IEEE80211_BAND_5GHZ == i && eCSR_BAND_24 == pCfg->nBandCapability) // 2G only
4715 {
4716 band->channels[j].flags |= IEEE80211_CHAN_DISABLED;
4717 continue;
4718 }
4719 }
Jeff Johnson295189b2012-06-20 16:38:30 -07004720 }
4721 /*Initialise the supported cipher suite details*/
4722 wiphy->cipher_suites = hdd_cipher_suites;
4723 wiphy->n_cipher_suites = ARRAY_SIZE(hdd_cipher_suites);
4724
4725 /*signal strength in mBm (100*dBm) */
4726 wiphy->signal_type = CFG80211_SIGNAL_TYPE_MBM;
4727
4728#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
Sushant Kaushik4f640e42014-07-08 12:27:09 +05304729 wiphy->max_remain_on_channel_duration = 5000;
Jeff Johnson295189b2012-06-20 16:38:30 -07004730#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07004731
Sunil Duttc69bccb2014-05-26 21:30:20 +05304732 wiphy->n_vendor_commands = ARRAY_SIZE(hdd_wiphy_vendor_commands);
4733 wiphy->vendor_commands = hdd_wiphy_vendor_commands;
Rajesh Chauhan98a31f82014-01-06 20:15:25 -08004734 wiphy->vendor_events = wlan_hdd_cfg80211_vendor_events;
4735 wiphy->n_vendor_events = ARRAY_SIZE(wlan_hdd_cfg80211_vendor_events);
4736
Madan Mohan Koyyalamudi71278262013-04-12 22:00:48 +05304737 EXIT();
4738 return 0;
4739}
4740
4741/* In this function we are registering wiphy. */
4742int wlan_hdd_cfg80211_register(struct wiphy *wiphy)
4743{
4744 ENTER();
4745 /* Register our wiphy dev with cfg80211 */
Jeff Johnson295189b2012-06-20 16:38:30 -07004746 if (0 > wiphy_register(wiphy))
4747 {
Madan Mohan Koyyalamudi71278262013-04-12 22:00:48 +05304748 /* print error */
Jeff Johnson295189b2012-06-20 16:38:30 -07004749 hddLog(VOS_TRACE_LEVEL_ERROR,"%s: wiphy register failed", __func__);
4750 return -EIO;
4751 }
4752
4753 EXIT();
4754 return 0;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304755}
Jeff Johnson295189b2012-06-20 16:38:30 -07004756
Madan Mohan Koyyalamudi71278262013-04-12 22:00:48 +05304757/* In this function we are updating channel list when,
4758 regulatory domain is FCC and country code is US.
4759 Here In FCC standard 5GHz UNII-1 Bands are indoor only.
4760 As per FCC smart phone is not a indoor device.
4761 GO should not opeate on indoor channels */
4762void wlan_hdd_cfg80211_update_reg_info(struct wiphy *wiphy)
4763{
4764 int j;
4765 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
4766 tANI_U8 defaultCountryCode[3] = SME_INVALID_COUNTRY_CODE;
4767 //Default counrtycode from NV at the time of wiphy initialization.
4768 if (eHAL_STATUS_SUCCESS != sme_GetDefaultCountryCodeFrmNv(pHddCtx->hHal,
4769 &defaultCountryCode[0]))
4770 {
Jeff Johnson0299d0a2013-10-30 12:37:43 -07004771 hddLog(LOGE, FL("Failed to get default country code from NV"));
Madan Mohan Koyyalamudi71278262013-04-12 22:00:48 +05304772 }
4773 if ((defaultCountryCode[0]== 'U') && (defaultCountryCode[1]=='S'))
4774 {
Madan Mohan Koyyalamudi71278262013-04-12 22:00:48 +05304775 if (NULL == wiphy->bands[IEEE80211_BAND_5GHZ])
4776 {
4777 hddLog(VOS_TRACE_LEVEL_ERROR,"%s: wiphy->bands[IEEE80211_BAND_5GHZ] is NULL",__func__ );
4778 return;
4779 }
4780 for (j = 0; j < wiphy->bands[IEEE80211_BAND_5GHZ]->n_channels; j++)
4781 {
4782 struct ieee80211_supported_band *band = wiphy->bands[IEEE80211_BAND_5GHZ];
4783 // Mark UNII -1 band channel as passive
4784 if (WLAN_HDD_CHANNEL_IN_UNII_1_BAND(band->channels[j].center_freq))
4785 band->channels[j].flags |= IEEE80211_CHAN_PASSIVE_SCAN;
4786 }
4787 }
4788}
4789
Agarwal Ashish8fa0e9a2014-05-23 00:40:12 +05304790/* This function registers for all frame which supplicant is interested in */
4791void wlan_hdd_cfg80211_register_frames(hdd_adapter_t* pAdapter)
Jeff Johnson295189b2012-06-20 16:38:30 -07004792{
Jeff Johnson295189b2012-06-20 16:38:30 -07004793 tHalHandle hHal = WLAN_HDD_GET_HAL_CTX(pAdapter);
4794 /* Register for all P2P action, public action etc frames */
4795 v_U16_t type = (SIR_MAC_MGMT_FRAME << 2) | ( SIR_MAC_MGMT_ACTION << 4);
4796
Jeff Johnsone7245742012-09-05 17:12:55 -07004797 ENTER();
4798
Jeff Johnson295189b2012-06-20 16:38:30 -07004799 /* Right now we are registering these frame when driver is getting
4800 initialized. Once we will move to 2.6.37 kernel, in which we have
4801 frame register ops, we will move this code as a part of that */
4802 /* GAS Initial Request */
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304803 sme_RegisterMgmtFrame(hHal, pAdapter->sessionId, type,
Jeff Johnson295189b2012-06-20 16:38:30 -07004804 (v_U8_t*)GAS_INITIAL_REQ, GAS_INITIAL_REQ_SIZE );
4805
4806 /* GAS Initial Response */
4807 sme_RegisterMgmtFrame(hHal, pAdapter->sessionId, type,
4808 (v_U8_t*)GAS_INITIAL_RSP, GAS_INITIAL_RSP_SIZE );
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304809
Jeff Johnson295189b2012-06-20 16:38:30 -07004810 /* GAS Comeback Request */
4811 sme_RegisterMgmtFrame(hHal, pAdapter->sessionId, type,
4812 (v_U8_t*)GAS_COMEBACK_REQ, GAS_COMEBACK_REQ_SIZE );
4813
4814 /* GAS Comeback Response */
4815 sme_RegisterMgmtFrame(hHal, pAdapter->sessionId, type,
4816 (v_U8_t*)GAS_COMEBACK_RSP, GAS_COMEBACK_RSP_SIZE );
4817
4818 /* P2P Public Action */
4819 sme_RegisterMgmtFrame(hHal, pAdapter->sessionId, type,
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304820 (v_U8_t*)P2P_PUBLIC_ACTION_FRAME,
Jeff Johnson295189b2012-06-20 16:38:30 -07004821 P2P_PUBLIC_ACTION_FRAME_SIZE );
4822
4823 /* P2P Action */
4824 sme_RegisterMgmtFrame(hHal, pAdapter->sessionId, type,
4825 (v_U8_t*)P2P_ACTION_FRAME,
4826 P2P_ACTION_FRAME_SIZE );
Chet Lanctot186b5732013-03-18 10:26:30 -07004827
Gopichand Nakkalae3d56e72013-04-21 23:33:32 +05304828 /* WNM BSS Transition Request frame */
4829 sme_RegisterMgmtFrame(hHal, pAdapter->sessionId, type,
4830 (v_U8_t*)WNM_BSS_ACTION_FRAME,
4831 WNM_BSS_ACTION_FRAME_SIZE );
Leela Venkata Kiran Kumar Reddy Chiralae8e62c82013-10-29 18:23:26 -07004832
4833 /* WNM-Notification */
4834 sme_RegisterMgmtFrame(hHal, pAdapter->sessionId, type,
4835 (v_U8_t*)WNM_NOTIFICATION_FRAME,
4836 WNM_NOTIFICATION_FRAME_SIZE );
Jeff Johnson295189b2012-06-20 16:38:30 -07004837}
4838
Agarwal Ashish8fa0e9a2014-05-23 00:40:12 +05304839void wlan_hdd_cfg80211_deregister_frames(hdd_adapter_t* pAdapter)
Jeff Johnson295189b2012-06-20 16:38:30 -07004840{
Jeff Johnson295189b2012-06-20 16:38:30 -07004841 tHalHandle hHal = WLAN_HDD_GET_HAL_CTX(pAdapter);
4842 /* Register for all P2P action, public action etc frames */
4843 v_U16_t type = (SIR_MAC_MGMT_FRAME << 2) | ( SIR_MAC_MGMT_ACTION << 4);
4844
Jeff Johnsone7245742012-09-05 17:12:55 -07004845 ENTER();
4846
Jeff Johnson295189b2012-06-20 16:38:30 -07004847 /* Right now we are registering these frame when driver is getting
4848 initialized. Once we will move to 2.6.37 kernel, in which we have
4849 frame register ops, we will move this code as a part of that */
4850 /* GAS Initial Request */
4851
4852 sme_DeregisterMgmtFrame(hHal, pAdapter->sessionId, type,
4853 (v_U8_t*)GAS_INITIAL_REQ, GAS_INITIAL_REQ_SIZE );
4854
4855 /* GAS Initial Response */
4856 sme_DeregisterMgmtFrame(hHal, pAdapter->sessionId, type,
4857 (v_U8_t*)GAS_INITIAL_RSP, GAS_INITIAL_RSP_SIZE );
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304858
Jeff Johnson295189b2012-06-20 16:38:30 -07004859 /* GAS Comeback Request */
4860 sme_DeregisterMgmtFrame(hHal, pAdapter->sessionId, type,
4861 (v_U8_t*)GAS_COMEBACK_REQ, GAS_COMEBACK_REQ_SIZE );
4862
4863 /* GAS Comeback Response */
4864 sme_DeregisterMgmtFrame(hHal, pAdapter->sessionId, type,
4865 (v_U8_t*)GAS_COMEBACK_RSP, GAS_COMEBACK_RSP_SIZE );
4866
4867 /* P2P Public Action */
4868 sme_DeregisterMgmtFrame(hHal, pAdapter->sessionId, type,
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304869 (v_U8_t*)P2P_PUBLIC_ACTION_FRAME,
Jeff Johnson295189b2012-06-20 16:38:30 -07004870 P2P_PUBLIC_ACTION_FRAME_SIZE );
4871
4872 /* P2P Action */
4873 sme_DeregisterMgmtFrame(hHal, pAdapter->sessionId, type,
4874 (v_U8_t*)P2P_ACTION_FRAME,
4875 P2P_ACTION_FRAME_SIZE );
Leela Venkata Kiran Kumar Reddy Chiralae8e62c82013-10-29 18:23:26 -07004876 /* WNM-Notification */
4877 sme_DeregisterMgmtFrame(hHal, pAdapter->sessionId, type,
4878 (v_U8_t*)WNM_NOTIFICATION_FRAME,
4879 WNM_NOTIFICATION_FRAME_SIZE );
Jeff Johnson295189b2012-06-20 16:38:30 -07004880}
4881
4882#ifdef FEATURE_WLAN_WAPI
4883void wlan_hdd_cfg80211_set_key_wapi(hdd_adapter_t* pAdapter, u8 key_index,
4884 const u8 *mac_addr, u8 *key , int key_Len)
4885{
4886 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
4887 tCsrRoamSetKey setKey;
4888 v_BOOL_t isConnected = TRUE;
4889 int status = 0;
4890 v_U32_t roamId= 0xFF;
4891 tANI_U8 *pKeyPtr = NULL;
4892 int n = 0;
4893
Sushant Kaushik8bc7df22014-04-09 17:55:29 +05304894 hddLog(VOS_TRACE_LEVEL_INFO, "%s: device_mode = %s(%d)",
4895 __func__, hdd_device_modetoString(pAdapter->device_mode),
4896 pAdapter->device_mode);
Jeff Johnson295189b2012-06-20 16:38:30 -07004897
Gopichand Nakkalae7480202013-02-11 15:24:22 +05304898 vos_mem_zero(&setKey, sizeof(tCsrRoamSetKey));
Jeff Johnson295189b2012-06-20 16:38:30 -07004899 setKey.keyId = key_index; // Store Key ID
4900 setKey.encType = eCSR_ENCRYPT_TYPE_WPI; // SET WAPI Encryption
4901 setKey.keyDirection = eSIR_TX_RX; // Key Directionn both TX and RX
4902 setKey.paeRole = 0 ; // the PAE role
4903 if (!mac_addr || is_broadcast_ether_addr(mac_addr))
4904 {
4905 vos_set_macaddr_broadcast( (v_MACADDR_t *)setKey.peerMac );
4906 }
4907 else
4908 {
4909 isConnected = hdd_connIsConnected(pHddStaCtx);
4910 vos_mem_copy(setKey.peerMac,&pHddStaCtx->conn_info.bssId,WNI_CFG_BSSID_LEN);
4911 }
4912 setKey.keyLength = key_Len;
4913 pKeyPtr = setKey.Key;
4914 memcpy( pKeyPtr, key, key_Len);
4915
Arif Hussain6d2a3322013-11-17 19:50:10 -08004916 hddLog(VOS_TRACE_LEVEL_INFO,"%s: WAPI KEY LENGTH:0x%04x",
Jeff Johnson295189b2012-06-20 16:38:30 -07004917 __func__, key_Len);
4918 for (n = 0 ; n < key_Len; n++)
4919 hddLog(VOS_TRACE_LEVEL_INFO, "%s WAPI KEY Data[%d]:%02x ",
4920 __func__,n,setKey.Key[n]);
4921
4922 pHddStaCtx->roam_info.roamingState = HDD_ROAM_STATE_SETTING_KEY;
4923 if ( isConnected )
4924 {
4925 status= sme_RoamSetKey( WLAN_HDD_GET_HAL_CTX(pAdapter),
4926 pAdapter->sessionId, &setKey, &roamId );
4927 }
4928 if ( status != 0 )
4929 {
4930 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
4931 "[%4d] sme_RoamSetKey returned ERROR status= %d",
4932 __LINE__, status );
4933 pHddStaCtx->roam_info.roamingState = HDD_ROAM_STATE_NONE;
4934 }
4935}
4936#endif /* FEATURE_WLAN_WAPI*/
4937
4938#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,4,0))
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304939int wlan_hdd_cfg80211_alloc_new_beacon(hdd_adapter_t *pAdapter,
Jeff Johnson295189b2012-06-20 16:38:30 -07004940 beacon_data_t **ppBeacon,
4941 struct beacon_parameters *params)
Jeff Johnson04dd8a82012-06-29 20:41:40 -07004942#else
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304943int wlan_hdd_cfg80211_alloc_new_beacon(hdd_adapter_t *pAdapter,
Jeff Johnson04dd8a82012-06-29 20:41:40 -07004944 beacon_data_t **ppBeacon,
4945 struct cfg80211_beacon_data *params,
4946 int dtim_period)
4947#endif
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304948{
Jeff Johnson295189b2012-06-20 16:38:30 -07004949 int size;
4950 beacon_data_t *beacon = NULL;
4951 beacon_data_t *old = NULL;
4952 int head_len,tail_len;
4953
Jeff Johnsone7245742012-09-05 17:12:55 -07004954 ENTER();
Jeff Johnson295189b2012-06-20 16:38:30 -07004955 if (params->head && !params->head_len)
c_hpothu6ff1c3c2013-10-01 19:01:57 +05304956 {
4957 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
4958 FL("head_len is NULL"));
Jeff Johnson295189b2012-06-20 16:38:30 -07004959 return -EINVAL;
c_hpothu6ff1c3c2013-10-01 19:01:57 +05304960 }
Jeff Johnson295189b2012-06-20 16:38:30 -07004961
4962 old = pAdapter->sessionCtx.ap.beacon;
4963
4964 if (!params->head && !old)
c_hpothu6ff1c3c2013-10-01 19:01:57 +05304965 {
4966 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
4967 FL("session(%d) old and new heads points to NULL"),
4968 pAdapter->sessionId);
Jeff Johnson295189b2012-06-20 16:38:30 -07004969 return -EINVAL;
c_hpothu6ff1c3c2013-10-01 19:01:57 +05304970 }
4971
4972 if (params->tail && !params->tail_len)
4973 {
4974 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
4975 FL("tail_len is zero but tail is not NULL"));
4976 return -EINVAL;
4977 }
Jeff Johnson295189b2012-06-20 16:38:30 -07004978
Jeff Johnson295189b2012-06-20 16:38:30 -07004979#if (LINUX_VERSION_CODE <= KERNEL_VERSION(2,6,38))
4980 /* Kernel 3.0 is not updating dtim_period for set beacon */
4981 if (!params->dtim_period)
c_hpothu6ff1c3c2013-10-01 19:01:57 +05304982 {
4983 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
4984 FL("dtim period is 0"));
Jeff Johnson295189b2012-06-20 16:38:30 -07004985 return -EINVAL;
c_hpothu6ff1c3c2013-10-01 19:01:57 +05304986 }
Jeff Johnson295189b2012-06-20 16:38:30 -07004987#endif
4988
4989 if(params->head)
4990 head_len = params->head_len;
4991 else
4992 head_len = old->head_len;
4993
4994 if(params->tail || !old)
4995 tail_len = params->tail_len;
4996 else
4997 tail_len = old->tail_len;
4998
4999 size = sizeof(beacon_data_t) + head_len + tail_len;
5000
5001 beacon = kzalloc(size, GFP_KERNEL);
5002
5003 if( beacon == NULL )
c_hpothu6ff1c3c2013-10-01 19:01:57 +05305004 {
5005 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
5006 FL("Mem allocation for beacon failed"));
Jeff Johnson295189b2012-06-20 16:38:30 -07005007 return -ENOMEM;
c_hpothu6ff1c3c2013-10-01 19:01:57 +05305008 }
Jeff Johnson295189b2012-06-20 16:38:30 -07005009
Jeff Johnson04dd8a82012-06-29 20:41:40 -07005010#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,4,0))
Jeff Johnson295189b2012-06-20 16:38:30 -07005011 if(params->dtim_period || !old )
5012 beacon->dtim_period = params->dtim_period;
5013 else
5014 beacon->dtim_period = old->dtim_period;
Jeff Johnson04dd8a82012-06-29 20:41:40 -07005015#else
5016 if(dtim_period || !old )
5017 beacon->dtim_period = dtim_period;
5018 else
5019 beacon->dtim_period = old->dtim_period;
5020#endif
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305021
Jeff Johnson295189b2012-06-20 16:38:30 -07005022 beacon->head = ((u8 *) beacon) + sizeof(beacon_data_t);
5023 beacon->tail = beacon->head + head_len;
5024 beacon->head_len = head_len;
5025 beacon->tail_len = tail_len;
5026
5027 if(params->head) {
5028 memcpy (beacon->head,params->head,beacon->head_len);
5029 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305030 else {
Jeff Johnson295189b2012-06-20 16:38:30 -07005031 if(old)
5032 memcpy (beacon->head,old->head,beacon->head_len);
5033 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305034
Jeff Johnson295189b2012-06-20 16:38:30 -07005035 if(params->tail) {
5036 memcpy (beacon->tail,params->tail,beacon->tail_len);
5037 }
5038 else {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305039 if(old)
Jeff Johnson295189b2012-06-20 16:38:30 -07005040 memcpy (beacon->tail,old->tail,beacon->tail_len);
5041 }
5042
5043 *ppBeacon = beacon;
5044
5045 kfree(old);
5046
5047 return 0;
5048
5049}
Jeff Johnson295189b2012-06-20 16:38:30 -07005050
5051v_U8_t* wlan_hdd_cfg80211_get_ie_ptr(v_U8_t *pIes, int length, v_U8_t eid)
5052{
5053 int left = length;
5054 v_U8_t *ptr = pIes;
5055 v_U8_t elem_id,elem_len;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305056
Jeff Johnson295189b2012-06-20 16:38:30 -07005057 while(left >= 2)
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305058 {
Jeff Johnson295189b2012-06-20 16:38:30 -07005059 elem_id = ptr[0];
5060 elem_len = ptr[1];
5061 left -= 2;
5062 if(elem_len > left)
5063 {
5064 hddLog(VOS_TRACE_LEVEL_FATAL,
Madan Mohan Koyyalamudi8bdd3112012-09-24 13:55:14 -07005065 FL("****Invalid IEs eid = %d elem_len=%d left=%d*****"),
Jeff Johnson295189b2012-06-20 16:38:30 -07005066 eid,elem_len,left);
5067 return NULL;
5068 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305069 if (elem_id == eid)
Jeff Johnson295189b2012-06-20 16:38:30 -07005070 {
5071 return ptr;
5072 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305073
Jeff Johnson295189b2012-06-20 16:38:30 -07005074 left -= elem_len;
5075 ptr += (elem_len + 2);
5076 }
5077 return NULL;
5078}
5079
Jeff Johnson295189b2012-06-20 16:38:30 -07005080/* Check if rate is 11g rate or not */
5081static int wlan_hdd_rate_is_11g(u8 rate)
5082{
Sanjay Devnani28322e22013-06-21 16:13:40 -07005083 static const u8 gRateArray[8] = {12, 18, 24, 36, 48, 72, 96, 108}; /* actual rate * 2 */
Jeff Johnson295189b2012-06-20 16:38:30 -07005084 u8 i;
5085 for (i = 0; i < 8; i++)
5086 {
5087 if(rate == gRateArray[i])
5088 return TRUE;
5089 }
5090 return FALSE;
5091}
5092
5093/* Check for 11g rate and set proper 11g only mode */
5094static void wlan_hdd_check_11gmode(u8 *pIe, u8* require_ht,
5095 u8* pCheckRatesfor11g, eSapPhyMode* pSapHw_mode)
5096{
5097 u8 i, num_rates = pIe[0];
5098
5099 pIe += 1;
5100 for ( i = 0; i < num_rates; i++)
5101 {
5102 if( *pCheckRatesfor11g && (TRUE == wlan_hdd_rate_is_11g(pIe[i] & RATE_MASK)))
5103 {
5104 /* If rate set have 11g rate than change the mode to 11G */
5105 *pSapHw_mode = eSAP_DOT11_MODE_11g;
5106 if (pIe[i] & BASIC_RATE_MASK)
5107 {
5108 /* If we have 11g rate as basic rate, it means mode
5109 is 11g only mode.
5110 */
5111 *pSapHw_mode = eSAP_DOT11_MODE_11g_ONLY;
5112 *pCheckRatesfor11g = FALSE;
5113 }
5114 }
5115 else if((BASIC_RATE_MASK | WLAN_BSS_MEMBERSHIP_SELECTOR_HT_PHY) == pIe[i])
5116 {
5117 *require_ht = TRUE;
5118 }
5119 }
5120 return;
5121}
5122
5123static void wlan_hdd_set_sapHwmode(hdd_adapter_t *pHostapdAdapter)
5124{
5125 tsap_Config_t *pConfig = &pHostapdAdapter->sessionCtx.ap.sapConfig;
5126 beacon_data_t *pBeacon = pHostapdAdapter->sessionCtx.ap.beacon;
5127 struct ieee80211_mgmt *pMgmt_frame = (struct ieee80211_mgmt*)pBeacon->head;
5128 u8 checkRatesfor11g = TRUE;
5129 u8 require_ht = FALSE;
5130 u8 *pIe=NULL;
5131
5132 pConfig->SapHw_mode= eSAP_DOT11_MODE_11b;
5133
5134 pIe = wlan_hdd_cfg80211_get_ie_ptr(&pMgmt_frame->u.beacon.variable[0],
5135 pBeacon->head_len, WLAN_EID_SUPP_RATES);
5136 if (pIe != NULL)
5137 {
5138 pIe += 1;
5139 wlan_hdd_check_11gmode(pIe, &require_ht, &checkRatesfor11g,
5140 &pConfig->SapHw_mode);
5141 }
5142
5143 pIe = wlan_hdd_cfg80211_get_ie_ptr(pBeacon->tail, pBeacon->tail_len,
5144 WLAN_EID_EXT_SUPP_RATES);
5145 if (pIe != NULL)
5146 {
5147
5148 pIe += 1;
5149 wlan_hdd_check_11gmode(pIe, &require_ht, &checkRatesfor11g,
5150 &pConfig->SapHw_mode);
5151 }
5152
5153 if( pConfig->channel > 14 )
5154 {
5155 pConfig->SapHw_mode= eSAP_DOT11_MODE_11a;
5156 }
5157
5158 pIe = wlan_hdd_cfg80211_get_ie_ptr(pBeacon->tail, pBeacon->tail_len,
5159 WLAN_EID_HT_CAPABILITY);
5160
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305161 if(pIe)
Jeff Johnson295189b2012-06-20 16:38:30 -07005162 {
5163 pConfig->SapHw_mode= eSAP_DOT11_MODE_11n;
5164 if(require_ht)
5165 pConfig->SapHw_mode= eSAP_DOT11_MODE_11n_ONLY;
5166 }
5167}
5168
Gopichand Nakkala2b25f4e2013-03-21 19:14:07 +05305169static int wlan_hdd_add_ie(hdd_adapter_t* pHostapdAdapter, v_U8_t *genie,
5170 v_U8_t *total_ielen, v_U8_t *oui, v_U8_t oui_size)
5171{
Arif Hussaine7f3ea52013-09-12 21:56:36 -07005172 v_U16_t ielen = 0;
Gopichand Nakkala2b25f4e2013-03-21 19:14:07 +05305173 v_U8_t *pIe = NULL;
5174 beacon_data_t *pBeacon = pHostapdAdapter->sessionCtx.ap.beacon;
5175
5176 pIe = wlan_hdd_get_vendor_oui_ie_ptr(oui, oui_size,
5177 pBeacon->tail, pBeacon->tail_len);
5178
5179 if (pIe)
5180 {
5181 ielen = pIe[1] + 2;
5182 if ((*total_ielen + ielen) <= MAX_GENIE_LEN)
5183 {
5184 vos_mem_copy(&genie[*total_ielen], pIe, ielen);
5185 }
5186 else
5187 {
5188 hddLog( VOS_TRACE_LEVEL_ERROR, "**Ie Length is too big***");
5189 return -EINVAL;
5190 }
5191 *total_ielen += ielen;
5192 }
5193 return 0;
5194}
5195
Arif Hussaine7f3ea52013-09-12 21:56:36 -07005196static void wlan_hdd_add_hostapd_conf_vsie(hdd_adapter_t* pHostapdAdapter,
5197 v_U8_t *genie, v_U8_t *total_ielen)
5198{
5199 beacon_data_t *pBeacon = pHostapdAdapter->sessionCtx.ap.beacon;
5200 int left = pBeacon->tail_len;
5201 v_U8_t *ptr = pBeacon->tail;
5202 v_U8_t elem_id, elem_len;
5203 v_U16_t ielen = 0;
5204
5205 if ( NULL == ptr || 0 == left )
5206 return;
5207
5208 while (left >= 2)
5209 {
5210 elem_id = ptr[0];
5211 elem_len = ptr[1];
5212 left -= 2;
5213 if (elem_len > left)
5214 {
5215 hddLog( VOS_TRACE_LEVEL_ERROR,
5216 "****Invalid IEs eid = %d elem_len=%d left=%d*****",
5217 elem_id, elem_len, left);
5218 return;
5219 }
5220 if (IE_EID_VENDOR == elem_id)
5221 {
5222 /* skipping the VSIE's which we don't want to include or
5223 * it will be included by existing code
5224 */
5225 if ((memcmp( &ptr[2], WPS_OUI_TYPE, WPS_OUI_TYPE_SIZE) != 0 ) &&
5226#ifdef WLAN_FEATURE_WFD
5227 (memcmp( &ptr[2], WFD_OUI_TYPE, WFD_OUI_TYPE_SIZE) != 0) &&
5228#endif
5229 (memcmp( &ptr[2], WHITELIST_OUI_TYPE, WPA_OUI_TYPE_SIZE) != 0) &&
5230 (memcmp( &ptr[2], BLACKLIST_OUI_TYPE, WPA_OUI_TYPE_SIZE) != 0) &&
5231 (memcmp( &ptr[2], "\x00\x50\xf2\x02", WPA_OUI_TYPE_SIZE) != 0) &&
5232 (memcmp( &ptr[2], WPA_OUI_TYPE, WPA_OUI_TYPE_SIZE) != 0) &&
5233 (memcmp( &ptr[2], P2P_OUI_TYPE, P2P_OUI_TYPE_SIZE) != 0))
5234 {
5235 ielen = ptr[1] + 2;
5236 if ((*total_ielen + ielen) <= MAX_GENIE_LEN)
5237 {
5238 vos_mem_copy(&genie[*total_ielen], ptr, ielen);
5239 *total_ielen += ielen;
5240 }
5241 else
5242 {
5243 hddLog( VOS_TRACE_LEVEL_ERROR,
5244 "IE Length is too big "
5245 "IEs eid=%d elem_len=%d total_ie_lent=%d",
5246 elem_id, elem_len, *total_ielen);
5247 }
5248 }
5249 }
5250
5251 left -= elem_len;
5252 ptr += (elem_len + 2);
5253 }
5254 return;
5255}
5256
Jeff Johnson04dd8a82012-06-29 20:41:40 -07005257#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,4,0))
Jeff Johnson295189b2012-06-20 16:38:30 -07005258static int wlan_hdd_cfg80211_update_apies(hdd_adapter_t* pHostapdAdapter,
5259 struct beacon_parameters *params)
Jeff Johnson04dd8a82012-06-29 20:41:40 -07005260#else
5261static int wlan_hdd_cfg80211_update_apies(hdd_adapter_t* pHostapdAdapter,
5262 struct cfg80211_beacon_data *params)
5263#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07005264{
5265 v_U8_t *genie;
Gopichand Nakkala2b25f4e2013-03-21 19:14:07 +05305266 v_U8_t total_ielen = 0;
Jeff Johnson295189b2012-06-20 16:38:30 -07005267 v_U8_t addIE[1] = {0};
Jeff Johnsone7245742012-09-05 17:12:55 -07005268 int ret = 0;
Jeff Johnson295189b2012-06-20 16:38:30 -07005269
5270 genie = vos_mem_malloc(MAX_GENIE_LEN);
5271
5272 if(genie == NULL) {
5273
5274 return -ENOMEM;
5275 }
5276
Gopichand Nakkala2b25f4e2013-03-21 19:14:07 +05305277 if (0 != wlan_hdd_add_ie(pHostapdAdapter, genie,
5278 &total_ielen, WPS_OUI_TYPE, WPS_OUI_TYPE_SIZE))
Jeff Johnson295189b2012-06-20 16:38:30 -07005279 {
c_hpothu6ff1c3c2013-10-01 19:01:57 +05305280 hddLog(LOGE,
5281 FL("Adding WPS IE failed"));
Gopichand Nakkala2b25f4e2013-03-21 19:14:07 +05305282 ret = -EINVAL;
5283 goto done;
Jeff Johnson295189b2012-06-20 16:38:30 -07005284 }
5285
5286#ifdef WLAN_FEATURE_WFD
Gopichand Nakkala2b25f4e2013-03-21 19:14:07 +05305287 if (0 != wlan_hdd_add_ie(pHostapdAdapter, genie,
5288 &total_ielen, WFD_OUI_TYPE, WFD_OUI_TYPE_SIZE))
5289 {
c_hpothu6ff1c3c2013-10-01 19:01:57 +05305290 hddLog(LOGE,
5291 FL("Adding WFD IE failed"));
Gopichand Nakkala2b25f4e2013-03-21 19:14:07 +05305292 ret = -EINVAL;
5293 goto done;
Jeff Johnson295189b2012-06-20 16:38:30 -07005294 }
5295#endif
5296
Gopichand Nakkala2b25f4e2013-03-21 19:14:07 +05305297 if (0 != wlan_hdd_add_ie(pHostapdAdapter, genie,
5298 &total_ielen, P2P_OUI_TYPE, P2P_OUI_TYPE_SIZE))
Jeff Johnson295189b2012-06-20 16:38:30 -07005299 {
c_hpothu6ff1c3c2013-10-01 19:01:57 +05305300 hddLog(LOGE,
5301 FL("Adding P2P IE failed"));
Gopichand Nakkala2b25f4e2013-03-21 19:14:07 +05305302 ret = -EINVAL;
5303 goto done;
5304 }
5305
5306 if (WLAN_HDD_SOFTAP == pHostapdAdapter->device_mode)
5307 {
Arif Hussaine7f3ea52013-09-12 21:56:36 -07005308 wlan_hdd_add_hostapd_conf_vsie(pHostapdAdapter, genie, &total_ielen);
Jeff Johnson295189b2012-06-20 16:38:30 -07005309 }
Jeff Johnson295189b2012-06-20 16:38:30 -07005310
5311 if (ccmCfgSetStr((WLAN_HDD_GET_CTX(pHostapdAdapter))->hHal,
5312 WNI_CFG_PROBE_RSP_BCN_ADDNIE_DATA, genie, total_ielen, NULL,
5313 eANI_BOOLEAN_FALSE)==eHAL_STATUS_FAILURE)
5314 {
5315 hddLog(LOGE,
5316 "Could not pass on WNI_CFG_PROBE_RSP_BCN_ADDNIE_DATA to CCM");
Jeff Johnsone7245742012-09-05 17:12:55 -07005317 ret = -EINVAL;
5318 goto done;
Jeff Johnson295189b2012-06-20 16:38:30 -07005319 }
5320
5321 if (ccmCfgSetInt((WLAN_HDD_GET_CTX(pHostapdAdapter))->hHal,
5322 WNI_CFG_PROBE_RSP_BCN_ADDNIE_FLAG, 1,NULL,
5323 test_bit(SOFTAP_BSS_STARTED, &pHostapdAdapter->event_flags) ?
5324 eANI_BOOLEAN_TRUE : eANI_BOOLEAN_FALSE)
5325 ==eHAL_STATUS_FAILURE)
5326 {
5327 hddLog(LOGE,
5328 "Could not pass on WNI_CFG_PROBE_RSP_BCN_ADDNIE_FLAG to CCM");
Jeff Johnsone7245742012-09-05 17:12:55 -07005329 ret = -EINVAL;
5330 goto done;
Jeff Johnson295189b2012-06-20 16:38:30 -07005331 }
5332
5333 // Added for ProResp IE
5334 if ( (params->proberesp_ies != NULL) && (params->proberesp_ies_len != 0) )
5335 {
5336 u16 rem_probe_resp_ie_len = params->proberesp_ies_len;
5337 u8 probe_rsp_ie_len[3] = {0};
5338 u8 counter = 0;
5339 /* Check Probe Resp Length if it is greater then 255 then Store
5340 Probe Resp IEs into WNI_CFG_PROBE_RSP_ADDNIE_DATA1 &
5341 WNI_CFG_PROBE_RSP_ADDNIE_DATA2 CFG Variable As We are not able
5342 Store More then 255 bytes into One Variable.
5343 */
5344 while ((rem_probe_resp_ie_len > 0) && (counter < 3))
5345 {
5346 if (rem_probe_resp_ie_len > MAX_CFG_STRING_LEN)
5347 {
5348 probe_rsp_ie_len[counter++] = MAX_CFG_STRING_LEN;
5349 rem_probe_resp_ie_len -= MAX_CFG_STRING_LEN;
5350 }
5351 else
5352 {
5353 probe_rsp_ie_len[counter++] = rem_probe_resp_ie_len;
5354 rem_probe_resp_ie_len = 0;
5355 }
5356 }
5357
5358 rem_probe_resp_ie_len = 0;
5359
5360 if (probe_rsp_ie_len[0] > 0)
5361 {
5362 if (ccmCfgSetStr((WLAN_HDD_GET_CTX(pHostapdAdapter))->hHal,
5363 WNI_CFG_PROBE_RSP_ADDNIE_DATA1,
5364 (tANI_U8*)&params->proberesp_ies[rem_probe_resp_ie_len],
5365 probe_rsp_ie_len[0], NULL,
5366 eANI_BOOLEAN_FALSE) == eHAL_STATUS_FAILURE)
5367 {
5368 hddLog(LOGE,
5369 "Could not pass on WNI_CFG_PROBE_RSP_ADDNIE_DATA1 to CCM");
Jeff Johnsone7245742012-09-05 17:12:55 -07005370 ret = -EINVAL;
5371 goto done;
Jeff Johnson295189b2012-06-20 16:38:30 -07005372 }
5373 rem_probe_resp_ie_len += probe_rsp_ie_len[0];
5374 }
5375
5376 if (probe_rsp_ie_len[1] > 0)
5377 {
5378 if (ccmCfgSetStr((WLAN_HDD_GET_CTX(pHostapdAdapter))->hHal,
5379 WNI_CFG_PROBE_RSP_ADDNIE_DATA2,
5380 (tANI_U8*)&params->proberesp_ies[rem_probe_resp_ie_len],
5381 probe_rsp_ie_len[1], NULL,
5382 eANI_BOOLEAN_FALSE) == eHAL_STATUS_FAILURE)
5383 {
5384 hddLog(LOGE,
5385 "Could not pass on WNI_CFG_PROBE_RSP_ADDNIE_DATA2 to CCM");
Jeff Johnsone7245742012-09-05 17:12:55 -07005386 ret = -EINVAL;
5387 goto done;
Jeff Johnson295189b2012-06-20 16:38:30 -07005388 }
5389 rem_probe_resp_ie_len += probe_rsp_ie_len[1];
5390 }
5391
5392 if (probe_rsp_ie_len[2] > 0)
5393 {
5394 if (ccmCfgSetStr((WLAN_HDD_GET_CTX(pHostapdAdapter))->hHal,
5395 WNI_CFG_PROBE_RSP_ADDNIE_DATA3,
5396 (tANI_U8*)&params->proberesp_ies[rem_probe_resp_ie_len],
5397 probe_rsp_ie_len[2], NULL,
5398 eANI_BOOLEAN_FALSE) == eHAL_STATUS_FAILURE)
5399 {
5400 hddLog(LOGE,
5401 "Could not pass on WNI_CFG_PROBE_RSP_ADDNIE_DATA3 to CCM");
Jeff Johnsone7245742012-09-05 17:12:55 -07005402 ret = -EINVAL;
5403 goto done;
Jeff Johnson295189b2012-06-20 16:38:30 -07005404 }
5405 rem_probe_resp_ie_len += probe_rsp_ie_len[2];
5406 }
5407
5408 if (probe_rsp_ie_len[1] == 0 )
5409 {
5410 if ( eHAL_STATUS_FAILURE == ccmCfgSetStr((WLAN_HDD_GET_CTX(pHostapdAdapter))->hHal,
5411 WNI_CFG_PROBE_RSP_ADDNIE_DATA2, (tANI_U8*)addIE, 0, NULL,
5412 eANI_BOOLEAN_FALSE) )
5413 {
5414 hddLog(LOGE,
Arif Hussain6d2a3322013-11-17 19:50:10 -08005415 "Could not pass on WNI_CFG_PROBE_RSP_ADDNIE_DATA2 to CCM");
Jeff Johnson295189b2012-06-20 16:38:30 -07005416 }
5417 }
5418
5419 if (probe_rsp_ie_len[2] == 0 )
5420 {
5421 if ( eHAL_STATUS_FAILURE == ccmCfgSetStr((WLAN_HDD_GET_CTX(pHostapdAdapter))->hHal,
5422 WNI_CFG_PROBE_RSP_ADDNIE_DATA3, (tANI_U8*)addIE, 0, NULL,
5423 eANI_BOOLEAN_FALSE) )
5424 {
5425 hddLog(LOGE,
Arif Hussain6d2a3322013-11-17 19:50:10 -08005426 "Could not pass on WNI_CFG_PROBE_RSP_ADDNIE_DATA3 to CCM");
Jeff Johnson295189b2012-06-20 16:38:30 -07005427 }
5428 }
5429
5430 if (ccmCfgSetInt((WLAN_HDD_GET_CTX(pHostapdAdapter))->hHal,
5431 WNI_CFG_PROBE_RSP_ADDNIE_FLAG, 1,NULL,
5432 test_bit(SOFTAP_BSS_STARTED, &pHostapdAdapter->event_flags) ?
5433 eANI_BOOLEAN_TRUE : eANI_BOOLEAN_FALSE)
5434 == eHAL_STATUS_FAILURE)
5435 {
5436 hddLog(LOGE,
5437 "Could not pass on WNI_CFG_PROBE_RSP_ADDNIE_FLAG to CCM");
Jeff Johnsone7245742012-09-05 17:12:55 -07005438 ret = -EINVAL;
5439 goto done;
Jeff Johnson295189b2012-06-20 16:38:30 -07005440 }
5441 }
5442 else
5443 {
5444 // Reset WNI_CFG_PROBE_RSP Flags
5445 wlan_hdd_reset_prob_rspies(pHostapdAdapter);
5446
5447 hddLog(VOS_TRACE_LEVEL_INFO,
5448 "%s: No Probe Response IE received in set beacon",
5449 __func__);
5450 }
5451
5452 // Added for AssocResp IE
5453 if ( (params->assocresp_ies != NULL) && (params->assocresp_ies_len != 0) )
5454 {
5455 if (ccmCfgSetStr((WLAN_HDD_GET_CTX(pHostapdAdapter))->hHal,
5456 WNI_CFG_ASSOC_RSP_ADDNIE_DATA, (tANI_U8*)params->assocresp_ies,
5457 params->assocresp_ies_len, NULL,
5458 eANI_BOOLEAN_FALSE) == eHAL_STATUS_FAILURE)
5459 {
5460 hddLog(LOGE,
5461 "Could not pass on WNI_CFG_ASSOC_RSP_ADDNIE_DATA to CCM");
Jeff Johnsone7245742012-09-05 17:12:55 -07005462 ret = -EINVAL;
5463 goto done;
Jeff Johnson295189b2012-06-20 16:38:30 -07005464 }
5465
5466 if (ccmCfgSetInt((WLAN_HDD_GET_CTX(pHostapdAdapter))->hHal,
5467 WNI_CFG_ASSOC_RSP_ADDNIE_FLAG, 1, NULL,
5468 test_bit(SOFTAP_BSS_STARTED, &pHostapdAdapter->event_flags) ?
5469 eANI_BOOLEAN_TRUE : eANI_BOOLEAN_FALSE)
5470 == eHAL_STATUS_FAILURE)
5471 {
5472 hddLog(LOGE,
5473 "Could not pass on WNI_CFG_ASSOC_RSP_ADDNIE_FLAG to CCM");
Jeff Johnsone7245742012-09-05 17:12:55 -07005474 ret = -EINVAL;
5475 goto done;
Jeff Johnson295189b2012-06-20 16:38:30 -07005476 }
5477 }
5478 else
5479 {
5480 hddLog(VOS_TRACE_LEVEL_INFO,
5481 "%s: No Assoc Response IE received in set beacon",
5482 __func__);
5483
5484 if ( eHAL_STATUS_FAILURE == ccmCfgSetInt((WLAN_HDD_GET_CTX(pHostapdAdapter))->hHal,
5485 WNI_CFG_ASSOC_RSP_ADDNIE_FLAG, 0, NULL,
5486 eANI_BOOLEAN_FALSE) )
5487 {
5488 hddLog(LOGE,
Arif Hussain6d2a3322013-11-17 19:50:10 -08005489 "Could not pass on WNI_CFG_ASSOC_RSP_ADDNIE_FLAG to CCM");
Jeff Johnson295189b2012-06-20 16:38:30 -07005490 }
5491 }
5492
Jeff Johnsone7245742012-09-05 17:12:55 -07005493done:
Jeff Johnson295189b2012-06-20 16:38:30 -07005494 vos_mem_free(genie);
Gopichand Nakkala2b25f4e2013-03-21 19:14:07 +05305495 return ret;
Jeff Johnson295189b2012-06-20 16:38:30 -07005496}
Jeff Johnson295189b2012-06-20 16:38:30 -07005497
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305498/*
Jeff Johnson295189b2012-06-20 16:38:30 -07005499 * FUNCTION: wlan_hdd_validate_operation_channel
5500 * called by wlan_hdd_cfg80211_start_bss() and
5501 * wlan_hdd_cfg80211_set_channel()
5502 * This function validates whether given channel is part of valid
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305503 * channel list.
5504 */
Varun Reddy Yeturu920df212013-05-22 08:07:23 -07005505VOS_STATUS wlan_hdd_validate_operation_channel(hdd_adapter_t *pAdapter,int channel)
Jeff Johnson295189b2012-06-20 16:38:30 -07005506{
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305507
Jeff Johnson295189b2012-06-20 16:38:30 -07005508 v_U32_t num_ch = 0;
5509 u8 valid_ch[WNI_CFG_VALID_CHANNEL_LIST_LEN];
5510 u32 indx = 0;
5511 tHalHandle hHal = WLAN_HDD_GET_HAL_CTX(pAdapter);
Madan Mohan Koyylamudi64267f72013-02-05 14:07:08 +05305512 v_U8_t fValidChannel = FALSE, count = 0;
5513 hdd_config_t *hdd_pConfig_ini= (WLAN_HDD_GET_CTX(pAdapter))->cfg_ini;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305514
Jeff Johnson295189b2012-06-20 16:38:30 -07005515 num_ch = WNI_CFG_VALID_CHANNEL_LIST_LEN;
5516
Madan Mohan Koyylamudi64267f72013-02-05 14:07:08 +05305517 if ( hdd_pConfig_ini->sapAllowAllChannel)
Jeff Johnson295189b2012-06-20 16:38:30 -07005518 {
Madan Mohan Koyylamudi64267f72013-02-05 14:07:08 +05305519 /* Validate the channel */
5520 for (count = RF_CHAN_1 ; count <= RF_CHAN_165 ; count++)
Jeff Johnson295189b2012-06-20 16:38:30 -07005521 {
Madan Mohan Koyylamudi64267f72013-02-05 14:07:08 +05305522 if ( channel == rfChannels[count].channelNum )
5523 {
5524 fValidChannel = TRUE;
5525 break;
5526 }
5527 }
5528 if (fValidChannel != TRUE)
5529 {
5530 hddLog(VOS_TRACE_LEVEL_ERROR,
5531 "%s: Invalid Channel [%d]", __func__, channel);
5532 return VOS_STATUS_E_FAILURE;
Jeff Johnson295189b2012-06-20 16:38:30 -07005533 }
5534 }
Madan Mohan Koyylamudi64267f72013-02-05 14:07:08 +05305535 else
Jeff Johnson295189b2012-06-20 16:38:30 -07005536 {
Madan Mohan Koyylamudi64267f72013-02-05 14:07:08 +05305537 if (0 != ccmCfgGetStr(hHal, WNI_CFG_VALID_CHANNEL_LIST,
5538 valid_ch, &num_ch))
5539 {
5540 hddLog(VOS_TRACE_LEVEL_ERROR,
5541 "%s: failed to get valid channel list", __func__);
5542 return VOS_STATUS_E_FAILURE;
5543 }
5544 for (indx = 0; indx < num_ch; indx++)
5545 {
5546 if (channel == valid_ch[indx])
5547 {
5548 break;
5549 }
5550 }
5551
Rashmi Ramanna3b59e122014-04-10 14:45:13 +05305552 if (indx >= num_ch)
5553 {
5554 if (WLAN_HDD_P2P_GO == pAdapter->device_mode)
5555 {
5556 eCsrBand band;
5557 unsigned int freq;
5558
5559 sme_GetFreqBand(hHal, &band);
5560
5561 if (eCSR_BAND_5G == band)
5562 {
5563#if (LINUX_VERSION_CODE > KERNEL_VERSION(2,6,38))
5564 if (channel <= ARRAY_SIZE(hdd_channels_2_4_GHZ))
5565 {
5566 freq = ieee80211_channel_to_frequency(channel,
5567 IEEE80211_BAND_2GHZ);
5568 }
5569 else
5570 {
5571 freq = ieee80211_channel_to_frequency(channel,
5572 IEEE80211_BAND_5GHZ);
5573 }
5574#else
5575 freq = ieee80211_channel_to_frequency(channel);
5576#endif
5577 if(WLAN_HDD_IS_SOCIAL_CHANNEL(freq))
5578 return VOS_STATUS_SUCCESS;
5579 }
5580 }
5581
5582 hddLog(VOS_TRACE_LEVEL_ERROR,
5583 "%s: Invalid Channel [%d]", __func__, channel);
5584 return VOS_STATUS_E_FAILURE;
5585 }
Jeff Johnson295189b2012-06-20 16:38:30 -07005586 }
Rashmi Ramanna3b59e122014-04-10 14:45:13 +05305587
Jeff Johnson295189b2012-06-20 16:38:30 -07005588 return VOS_STATUS_SUCCESS;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305589
Jeff Johnson295189b2012-06-20 16:38:30 -07005590}
5591
Viral Modi3a32cc52013-02-08 11:14:52 -08005592/**
5593 * FUNCTION: wlan_hdd_cfg80211_set_channel
5594 * This function is used to set the channel number
5595 */
5596static int wlan_hdd_cfg80211_set_channel( struct wiphy *wiphy, struct net_device *dev,
5597 struct ieee80211_channel *chan,
5598 enum nl80211_channel_type channel_type
5599 )
5600{
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05305601 hdd_adapter_t *pAdapter = NULL;
Viral Modi3a32cc52013-02-08 11:14:52 -08005602 v_U32_t num_ch = 0;
Jeff Johnson4416a782013-03-25 14:17:50 -07005603 int channel = 0;
Viral Modi3a32cc52013-02-08 11:14:52 -08005604 int freq = chan->center_freq; /* freq is in MHZ */
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05305605 hdd_context_t *pHddCtx;
5606 int status;
Viral Modi3a32cc52013-02-08 11:14:52 -08005607
5608 ENTER();
5609
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05305610
Viral Modi3a32cc52013-02-08 11:14:52 -08005611 if( NULL == dev )
5612 {
5613 hddLog(VOS_TRACE_LEVEL_ERROR,
Arif Hussain6d2a3322013-11-17 19:50:10 -08005614 "%s: Called with dev = NULL.", __func__);
Viral Modi3a32cc52013-02-08 11:14:52 -08005615 return -ENODEV;
5616 }
5617 pAdapter = WLAN_HDD_GET_PRIV_PTR( dev );
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +05305618
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05305619 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
5620 TRACE_CODE_HDD_CFG80211_SET_CHANNEL, pAdapter->sessionId,
5621 channel_type ));
Viral Modi3a32cc52013-02-08 11:14:52 -08005622 hddLog(VOS_TRACE_LEVEL_INFO,
Sushant Kaushik8bc7df22014-04-09 17:55:29 +05305623 "%s: device_mode = %s (%d) freq = %d", __func__,
5624 hdd_device_modetoString(pAdapter->device_mode),
5625 pAdapter->device_mode, chan->center_freq);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05305626
5627 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
5628 status = wlan_hdd_validate_context(pHddCtx);
5629
5630 if (0 != status)
Viral Modi3a32cc52013-02-08 11:14:52 -08005631 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05305632 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
5633 "%s: HDD context is not valid", __func__);
5634 return status;
Viral Modi3a32cc52013-02-08 11:14:52 -08005635 }
5636
5637 /*
5638 * Do freq to chan conversion
5639 * TODO: for 11a
5640 */
5641
5642 channel = ieee80211_frequency_to_channel(freq);
5643
5644 /* Check freq range */
5645 if ((WNI_CFG_CURRENT_CHANNEL_STAMIN > channel) ||
5646 (WNI_CFG_CURRENT_CHANNEL_STAMAX < channel))
5647 {
5648 hddLog(VOS_TRACE_LEVEL_ERROR,
Arif Hussain6d2a3322013-11-17 19:50:10 -08005649 "%s: Channel [%d] is outside valid range from %d to %d",
Viral Modi3a32cc52013-02-08 11:14:52 -08005650 __func__, channel, WNI_CFG_CURRENT_CHANNEL_STAMIN,
5651 WNI_CFG_CURRENT_CHANNEL_STAMAX);
5652 return -EINVAL;
5653 }
5654
5655 num_ch = WNI_CFG_VALID_CHANNEL_LIST_LEN;
5656
Gopichand Nakkala6ab19562013-03-07 13:59:42 +05305657 if ((WLAN_HDD_SOFTAP != pAdapter->device_mode) &&
5658 (WLAN_HDD_P2P_GO != pAdapter->device_mode))
Viral Modi3a32cc52013-02-08 11:14:52 -08005659 {
5660 if(VOS_STATUS_SUCCESS != wlan_hdd_validate_operation_channel(pAdapter,channel))
5661 {
5662 hddLog(VOS_TRACE_LEVEL_ERROR,
Arif Hussain6d2a3322013-11-17 19:50:10 -08005663 "%s: Invalid Channel [%d]", __func__, channel);
Viral Modi3a32cc52013-02-08 11:14:52 -08005664 return -EINVAL;
5665 }
5666 hddLog(VOS_TRACE_LEVEL_INFO_HIGH,
5667 "%s: set channel to [%d] for device mode =%d",
5668 __func__, channel,pAdapter->device_mode);
5669 }
5670 if( (pAdapter->device_mode == WLAN_HDD_INFRA_STATION)
Viral Modi3a32cc52013-02-08 11:14:52 -08005671 || (pAdapter->device_mode == WLAN_HDD_P2P_CLIENT)
Viral Modi3a32cc52013-02-08 11:14:52 -08005672 )
5673 {
5674 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
5675 tCsrRoamProfile * pRoamProfile = &pWextState->roamProfile;
5676 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
5677
5678 if (eConnectionState_IbssConnected == pHddStaCtx->conn_info.connState)
5679 {
5680 /* Link is up then return cant set channel*/
5681 hddLog( VOS_TRACE_LEVEL_ERROR,
Arif Hussain6d2a3322013-11-17 19:50:10 -08005682 "%s: IBSS Associated, can't set the channel", __func__);
Viral Modi3a32cc52013-02-08 11:14:52 -08005683 return -EINVAL;
5684 }
5685
5686 num_ch = pRoamProfile->ChannelInfo.numOfChannels = 1;
5687 pHddStaCtx->conn_info.operationChannel = channel;
5688 pRoamProfile->ChannelInfo.ChannelList =
5689 &pHddStaCtx->conn_info.operationChannel;
5690 }
5691 else if ((pAdapter->device_mode == WLAN_HDD_SOFTAP)
Viral Modi3a32cc52013-02-08 11:14:52 -08005692 || (pAdapter->device_mode == WLAN_HDD_P2P_GO)
Viral Modi3a32cc52013-02-08 11:14:52 -08005693 )
5694 {
Gopichand Nakkalac8fa7b62013-03-11 13:56:41 +05305695 if (WLAN_HDD_P2P_GO == pAdapter->device_mode)
5696 {
5697 if(VOS_STATUS_SUCCESS !=
5698 wlan_hdd_validate_operation_channel(pAdapter,channel))
5699 {
5700 hddLog(VOS_TRACE_LEVEL_ERROR,
Arif Hussain6d2a3322013-11-17 19:50:10 -08005701 "%s: Invalid Channel [%d]", __func__, channel);
Gopichand Nakkalac8fa7b62013-03-11 13:56:41 +05305702 return -EINVAL;
5703 }
5704 (WLAN_HDD_GET_AP_CTX_PTR(pAdapter))->sapConfig.channel = channel;
5705 }
5706 else if ( WLAN_HDD_SOFTAP == pAdapter->device_mode )
Viral Modi3a32cc52013-02-08 11:14:52 -08005707 {
5708 hdd_config_t *cfg_param = (WLAN_HDD_GET_CTX(pAdapter))->cfg_ini;
5709
5710 /* If auto channel selection is configured as enable/ 1 then ignore
5711 channel set by supplicant
5712 */
5713 if ( cfg_param->apAutoChannelSelection )
5714 {
Gopichand Nakkalac8fa7b62013-03-11 13:56:41 +05305715 (WLAN_HDD_GET_AP_CTX_PTR(pAdapter))->sapConfig.channel =
5716 AUTO_CHANNEL_SELECT;
Viral Modi3a32cc52013-02-08 11:14:52 -08005717 hddLog(VOS_TRACE_LEVEL_INFO_HIGH,
Sushant Kaushik8bc7df22014-04-09 17:55:29 +05305718 "%s: set channel to auto channel (0) for device mode =%s (%d)",
5719 __func__, hdd_device_modetoString(pAdapter->device_mode),
5720 pAdapter->device_mode);
Viral Modi3a32cc52013-02-08 11:14:52 -08005721 }
Gopichand Nakkalac8fa7b62013-03-11 13:56:41 +05305722 else
5723 {
5724 if(VOS_STATUS_SUCCESS !=
5725 wlan_hdd_validate_operation_channel(pAdapter,channel))
5726 {
5727 hddLog(VOS_TRACE_LEVEL_ERROR,
Arif Hussain6d2a3322013-11-17 19:50:10 -08005728 "%s: Invalid Channel [%d]", __func__, channel);
Gopichand Nakkalac8fa7b62013-03-11 13:56:41 +05305729 return -EINVAL;
5730 }
5731 (WLAN_HDD_GET_AP_CTX_PTR(pAdapter))->sapConfig.channel = channel;
5732 }
Viral Modi3a32cc52013-02-08 11:14:52 -08005733 }
5734 }
5735 else
5736 {
5737 hddLog(VOS_TRACE_LEVEL_FATAL,
5738 "%s: Invalid device mode failed to set valid channel", __func__);
5739 return -EINVAL;
5740 }
5741 EXIT();
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05305742 return status;
Viral Modi3a32cc52013-02-08 11:14:52 -08005743}
5744
Jeff Johnson295189b2012-06-20 16:38:30 -07005745#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,4,0))
5746static int wlan_hdd_cfg80211_start_bss(hdd_adapter_t *pHostapdAdapter,
5747 struct beacon_parameters *params)
Jeff Johnson04dd8a82012-06-29 20:41:40 -07005748#else
5749static int wlan_hdd_cfg80211_start_bss(hdd_adapter_t *pHostapdAdapter,
5750 struct cfg80211_beacon_data *params,
5751 const u8 *ssid, size_t ssid_len,
5752 enum nl80211_hidden_ssid hidden_ssid)
5753#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07005754{
5755 tsap_Config_t *pConfig;
5756 beacon_data_t *pBeacon = NULL;
5757 struct ieee80211_mgmt *pMgmt_frame;
5758 v_U8_t *pIe=NULL;
5759 v_U16_t capab_info;
5760 eCsrAuthType RSNAuthType;
5761 eCsrEncryptionType RSNEncryptType;
5762 eCsrEncryptionType mcRSNEncryptType;
5763 int status = VOS_STATUS_SUCCESS;
5764 tpWLAN_SAPEventCB pSapEventCallback;
5765 hdd_hostapd_state_t *pHostapdState;
5766 v_U8_t wpaRsnIEdata[(SIR_MAC_MAX_IE_LENGTH * 2)+4]; //Max ie length 255 * 2(WPA+RSN) + 2 bytes (vendor specific ID) * 2
5767 v_CONTEXT_t pVosContext = (WLAN_HDD_GET_CTX(pHostapdAdapter))->pvosContext;
Madan Mohan Koyylamudia16d0202013-02-01 11:05:57 +05305768 tHalHandle hHal = WLAN_HDD_GET_HAL_CTX(pHostapdAdapter);
Jeff Johnson295189b2012-06-20 16:38:30 -07005769 struct qc_mac_acl_entry *acl_entry = NULL;
Siddharth Bhal5cba24e2014-05-08 18:59:39 +05305770 hdd_config_t *iniConfig;
Jeff Johnson295189b2012-06-20 16:38:30 -07005771 v_SINT_t i;
Madan Mohan Koyyalamudi543172b2012-12-05 16:40:18 -08005772 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pHostapdAdapter);
Peng Xu2446a892014-09-05 17:21:18 +05305773 tSmeConfigParams *psmeConfig;
Chet Lanctot40142442014-05-20 13:39:25 -07005774 v_BOOL_t MFPCapable = VOS_FALSE;
5775 v_BOOL_t MFPRequired = VOS_FALSE;
Abhishek Singhf0ac1752014-03-05 17:47:09 +05305776 eHddDot11Mode sapDot11Mode =
5777 (WLAN_HDD_GET_CTX(pHostapdAdapter))->cfg_ini->sapDot11Mode;
Jeff Johnson295189b2012-06-20 16:38:30 -07005778
5779 ENTER();
5780
Siddharth Bhal5cba24e2014-05-08 18:59:39 +05305781 iniConfig = pHddCtx->cfg_ini;
5782
Jeff Johnson295189b2012-06-20 16:38:30 -07005783 pHostapdState = WLAN_HDD_GET_HOSTAP_STATE_PTR(pHostapdAdapter);
5784
5785 pConfig = &pHostapdAdapter->sessionCtx.ap.sapConfig;
5786
5787 pBeacon = pHostapdAdapter->sessionCtx.ap.beacon;
5788
5789 pMgmt_frame = (struct ieee80211_mgmt*)pBeacon->head;
5790
5791 pConfig->beacon_int = pMgmt_frame->u.beacon.beacon_int;
5792
5793 //channel is already set in the set_channel Call back
5794 //pConfig->channel = pCommitConfig->channel;
5795
5796 /*Protection parameter to enable or disable*/
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305797 pConfig->protEnabled =
Jeff Johnson295189b2012-06-20 16:38:30 -07005798 (WLAN_HDD_GET_CTX(pHostapdAdapter))->cfg_ini->apProtEnabled;
5799
5800 pConfig->dtim_period = pBeacon->dtim_period;
5801
Arif Hussain6d2a3322013-11-17 19:50:10 -08005802 hddLog(VOS_TRACE_LEVEL_INFO_HIGH,"****pConfig->dtim_period=%d***",
Jeff Johnson295189b2012-06-20 16:38:30 -07005803 pConfig->dtim_period);
5804
Madan Mohan Koyyalamudie0ca11f2012-11-27 15:57:52 -08005805 if (pHostapdAdapter->device_mode == WLAN_HDD_SOFTAP)
Jeff Johnson32d95a32012-09-10 13:15:23 -07005806 {
5807 pIe = wlan_hdd_cfg80211_get_ie_ptr(pBeacon->tail, pBeacon->tail_len,
Jeff Johnson295189b2012-06-20 16:38:30 -07005808 WLAN_EID_COUNTRY);
Kiet Lam083504c2013-11-25 14:17:45 +05305809 if(memcmp(pHddCtx->cfg_ini->apCntryCode, CFG_AP_COUNTRY_CODE_DEFAULT, 3) != 0)
5810 {
5811 tANI_BOOLEAN restartNeeded;
5812 pConfig->ieee80211d = 1;
5813 vos_mem_copy(pConfig->countryCode, pHddCtx->cfg_ini->apCntryCode, 3);
5814 sme_setRegInfo(hHal, pConfig->countryCode);
5815 sme_ResetCountryCodeInformation(hHal, &restartNeeded);
5816 }
5817 else if(pIe)
Jeff Johnson295189b2012-06-20 16:38:30 -07005818 {
Jeff Johnson32d95a32012-09-10 13:15:23 -07005819 tANI_BOOLEAN restartNeeded;
Jeff Johnson32d95a32012-09-10 13:15:23 -07005820 pConfig->ieee80211d = 1;
5821 vos_mem_copy(pConfig->countryCode, &pIe[2], 3);
5822 sme_setRegInfo(hHal, pConfig->countryCode);
5823 sme_ResetCountryCodeInformation(hHal, &restartNeeded);
Jeff Johnson295189b2012-06-20 16:38:30 -07005824 }
Jeff Johnson32d95a32012-09-10 13:15:23 -07005825 else
5826 {
5827 pConfig->ieee80211d = 0;
5828 }
Madan Mohan Koyylamudia16d0202013-02-01 11:05:57 +05305829 /*
5830 * If auto channel is configured i.e. channel is 0,
5831 * so skip channel validation.
5832 */
5833 if( AUTO_CHANNEL_SELECT != pConfig->channel )
5834 {
5835 if(VOS_STATUS_SUCCESS != wlan_hdd_validate_operation_channel(pHostapdAdapter,pConfig->channel))
5836 {
5837 hddLog(VOS_TRACE_LEVEL_ERROR,
Arif Hussain6d2a3322013-11-17 19:50:10 -08005838 "%s: Invalid Channel [%d]", __func__, pConfig->channel);
Madan Mohan Koyylamudia16d0202013-02-01 11:05:57 +05305839 return -EINVAL;
5840 }
5841 }
5842 else
5843 {
5844 if(1 != pHddCtx->is_dynamic_channel_range_set)
5845 {
5846 hdd_config_t *hdd_pConfig= (WLAN_HDD_GET_CTX(pHostapdAdapter))->cfg_ini;
5847 WLANSAP_SetChannelRange(hHal, hdd_pConfig->apStartChannelNum,
5848 hdd_pConfig->apEndChannelNum,hdd_pConfig->apOperatingBand);
5849 }
5850 pHddCtx->is_dynamic_channel_range_set = 0;
5851 }
Jeff Johnson295189b2012-06-20 16:38:30 -07005852 }
Jeff Johnson32d95a32012-09-10 13:15:23 -07005853 else
Jeff Johnson295189b2012-06-20 16:38:30 -07005854 {
5855 pConfig->ieee80211d = 0;
5856 }
5857 pConfig->authType = eSAP_AUTO_SWITCH;
5858
5859 capab_info = pMgmt_frame->u.beacon.capab_info;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305860
5861 pConfig->privacy = (pMgmt_frame->u.beacon.capab_info &
Jeff Johnson295189b2012-06-20 16:38:30 -07005862 WLAN_CAPABILITY_PRIVACY) ? VOS_TRUE : VOS_FALSE;
5863
5864 (WLAN_HDD_GET_AP_CTX_PTR(pHostapdAdapter))->uPrivacy = pConfig->privacy;
5865
5866 /*Set wps station to configured*/
5867 pIe = wlan_hdd_get_wps_ie_ptr(pBeacon->tail, pBeacon->tail_len);
5868
5869 if(pIe)
5870 {
5871 if(pIe[1] < (2 + WPS_OUI_TYPE_SIZE))
5872 {
Arif Hussain6d2a3322013-11-17 19:50:10 -08005873 hddLog( VOS_TRACE_LEVEL_ERROR, "**Wps Ie Length is too small***");
Jeff Johnson295189b2012-06-20 16:38:30 -07005874 return -EINVAL;
5875 }
5876 else if(memcmp(&pIe[2], WPS_OUI_TYPE, WPS_OUI_TYPE_SIZE) == 0)
5877 {
Madan Mohan Koyyalamudi8bdd3112012-09-24 13:55:14 -07005878 hddLog( VOS_TRACE_LEVEL_INFO, "** WPS IE(len %d) ***", (pIe[1]+2));
Jeff Johnson295189b2012-06-20 16:38:30 -07005879 /* Check 15 bit of WPS IE as it contain information for wps state
5880 * WPS state
5881 */
5882 if(SAP_WPS_ENABLED_UNCONFIGURED == pIe[15])
5883 {
5884 pConfig->wps_state = SAP_WPS_ENABLED_UNCONFIGURED;
5885 } else if(SAP_WPS_ENABLED_CONFIGURED == pIe[15])
5886 {
5887 pConfig->wps_state = SAP_WPS_ENABLED_CONFIGURED;
5888 }
5889 }
5890 }
5891 else
5892 {
5893 pConfig->wps_state = SAP_WPS_DISABLED;
5894 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305895 pConfig->fwdWPSPBCProbeReq = 1; // Forward WPS PBC probe request frame up
Jeff Johnson295189b2012-06-20 16:38:30 -07005896
c_hpothufe599e92014-06-16 11:38:55 +05305897 pConfig->RSNEncryptType = eCSR_ENCRYPT_TYPE_NONE;
5898 pConfig->mcRSNEncryptType = eCSR_ENCRYPT_TYPE_NONE;
5899 (WLAN_HDD_GET_AP_CTX_PTR(pHostapdAdapter))->ucEncryptType =
5900 eCSR_ENCRYPT_TYPE_NONE;
5901
Jeff Johnson295189b2012-06-20 16:38:30 -07005902 pConfig->RSNWPAReqIELength = 0;
5903 pConfig->pRSNWPAReqIE = NULL;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305904 pIe = wlan_hdd_cfg80211_get_ie_ptr(pBeacon->tail, pBeacon->tail_len,
Jeff Johnson295189b2012-06-20 16:38:30 -07005905 WLAN_EID_RSN);
5906 if(pIe && pIe[1])
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305907 {
Jeff Johnson295189b2012-06-20 16:38:30 -07005908 pConfig->RSNWPAReqIELength = pIe[1] + 2;
5909 memcpy(&wpaRsnIEdata[0], pIe, pConfig->RSNWPAReqIELength);
5910 pConfig->pRSNWPAReqIE = &wpaRsnIEdata[0];
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305911 /* The actual processing may eventually be more extensive than
5912 * this. Right now, just consume any PMKIDs that are sent in
Jeff Johnson295189b2012-06-20 16:38:30 -07005913 * by the app.
5914 * */
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305915 status = hdd_softap_unpackIE(
Jeff Johnson295189b2012-06-20 16:38:30 -07005916 vos_get_context( VOS_MODULE_ID_SME, pVosContext),
5917 &RSNEncryptType,
5918 &mcRSNEncryptType,
5919 &RSNAuthType,
Chet Lanctot8cecea22014-02-11 19:09:36 -08005920 &MFPCapable,
5921 &MFPRequired,
Jeff Johnson295189b2012-06-20 16:38:30 -07005922 pConfig->pRSNWPAReqIE[1]+2,
5923 pConfig->pRSNWPAReqIE );
5924
5925 if( VOS_STATUS_SUCCESS == status )
5926 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305927 /* Now copy over all the security attributes you have
5928 * parsed out
Jeff Johnson295189b2012-06-20 16:38:30 -07005929 * */
5930 pConfig->RSNEncryptType = RSNEncryptType; // Use the cipher type in the RSN IE
5931 pConfig->mcRSNEncryptType = mcRSNEncryptType;
5932 (WLAN_HDD_GET_AP_CTX_PTR(pHostapdAdapter))->ucEncryptType
5933 = RSNEncryptType;
Gopichand Nakkala66c0bd02013-04-10 11:36:29 +05305934 hddLog( LOG1, FL("CSR AuthType = %d, "
Arif Hussain6d2a3322013-11-17 19:50:10 -08005935 "EncryptionType = %d mcEncryptionType = %d"),
Jeff Johnson295189b2012-06-20 16:38:30 -07005936 RSNAuthType, RSNEncryptType, mcRSNEncryptType);
5937 }
5938 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305939
Jeff Johnson295189b2012-06-20 16:38:30 -07005940 pIe = wlan_hdd_get_vendor_oui_ie_ptr(WPA_OUI_TYPE, WPA_OUI_TYPE_SIZE,
5941 pBeacon->tail, pBeacon->tail_len);
5942
5943 if(pIe && pIe[1] && (pIe[0] == DOT11F_EID_WPA))
5944 {
5945 if (pConfig->pRSNWPAReqIE)
5946 {
5947 /*Mixed mode WPA/WPA2*/
5948 memcpy((&wpaRsnIEdata[0] + pConfig->RSNWPAReqIELength), pIe, pIe[1] + 2);
5949 pConfig->RSNWPAReqIELength += pIe[1] + 2;
5950 }
5951 else
5952 {
5953 pConfig->RSNWPAReqIELength = pIe[1] + 2;
5954 memcpy(&wpaRsnIEdata[0], pIe, pConfig->RSNWPAReqIELength);
5955 pConfig->pRSNWPAReqIE = &wpaRsnIEdata[0];
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305956 status = hdd_softap_unpackIE(
Jeff Johnson295189b2012-06-20 16:38:30 -07005957 vos_get_context( VOS_MODULE_ID_SME, pVosContext),
5958 &RSNEncryptType,
5959 &mcRSNEncryptType,
5960 &RSNAuthType,
Chet Lanctot8cecea22014-02-11 19:09:36 -08005961 &MFPCapable,
5962 &MFPRequired,
Jeff Johnson295189b2012-06-20 16:38:30 -07005963 pConfig->pRSNWPAReqIE[1]+2,
5964 pConfig->pRSNWPAReqIE );
5965
5966 if( VOS_STATUS_SUCCESS == status )
5967 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305968 /* Now copy over all the security attributes you have
5969 * parsed out
Jeff Johnson295189b2012-06-20 16:38:30 -07005970 * */
5971 pConfig->RSNEncryptType = RSNEncryptType; // Use the cipher type in the RSN IE
5972 pConfig->mcRSNEncryptType = mcRSNEncryptType;
5973 (WLAN_HDD_GET_AP_CTX_PTR(pHostapdAdapter))->ucEncryptType
5974 = RSNEncryptType;
Gopichand Nakkala66c0bd02013-04-10 11:36:29 +05305975 hddLog( LOG1, FL("CSR AuthType = %d, "
Arif Hussain6d2a3322013-11-17 19:50:10 -08005976 "EncryptionType = %d mcEncryptionType = %d"),
Jeff Johnson295189b2012-06-20 16:38:30 -07005977 RSNAuthType, RSNEncryptType, mcRSNEncryptType);
5978 }
5979 }
5980 }
5981
Jeff Johnson4416a782013-03-25 14:17:50 -07005982 if (pConfig->RSNWPAReqIELength > sizeof wpaRsnIEdata) {
5983 hddLog( VOS_TRACE_LEVEL_ERROR, "**RSNWPAReqIELength is too large***");
5984 return -EINVAL;
5985 }
5986
Jeff Johnson295189b2012-06-20 16:38:30 -07005987 pConfig->SSIDinfo.ssidHidden = VOS_FALSE;
5988
Jeff Johnson04dd8a82012-06-29 20:41:40 -07005989#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,4,0))
Jeff Johnson295189b2012-06-20 16:38:30 -07005990 if (params->ssid != NULL)
5991 {
5992 memcpy(pConfig->SSIDinfo.ssid.ssId, params->ssid, params->ssid_len);
5993 pConfig->SSIDinfo.ssid.length = params->ssid_len;
5994 if (params->hidden_ssid != NL80211_HIDDEN_SSID_NOT_IN_USE)
5995 pConfig->SSIDinfo.ssidHidden = VOS_TRUE;
5996 }
Jeff Johnson04dd8a82012-06-29 20:41:40 -07005997#else
5998 if (ssid != NULL)
5999 {
6000 memcpy(pConfig->SSIDinfo.ssid.ssId, ssid, ssid_len);
6001 pConfig->SSIDinfo.ssid.length = ssid_len;
6002 if (hidden_ssid != NL80211_HIDDEN_SSID_NOT_IN_USE)
6003 pConfig->SSIDinfo.ssidHidden = VOS_TRUE;
6004 }
6005#endif
6006
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306007 vos_mem_copy(pConfig->self_macaddr.bytes,
Jeff Johnson295189b2012-06-20 16:38:30 -07006008 pHostapdAdapter->macAddressCurrent.bytes, sizeof(v_MACADDR_t));
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306009
Jeff Johnson295189b2012-06-20 16:38:30 -07006010 /* default value */
6011 pConfig->SapMacaddr_acl = eSAP_ACCEPT_UNLESS_DENIED;
6012 pConfig->num_accept_mac = 0;
6013 pConfig->num_deny_mac = 0;
6014
6015 pIe = wlan_hdd_get_vendor_oui_ie_ptr(BLACKLIST_OUI_TYPE, WPA_OUI_TYPE_SIZE,
6016 pBeacon->tail, pBeacon->tail_len);
6017
6018 /* pIe for black list is following form:
6019 type : 1 byte
6020 length : 1 byte
6021 OUI : 4 bytes
6022 acl type : 1 byte
6023 no of mac addr in black list: 1 byte
6024 list of mac_acl_entries: variable, 6 bytes per mac address + sizeof(int) for vlan id
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306025 */
6026 if ((pIe != NULL) && (pIe[1] != 0))
Jeff Johnson295189b2012-06-20 16:38:30 -07006027 {
6028 pConfig->SapMacaddr_acl = pIe[6];
6029 pConfig->num_deny_mac = pIe[7];
Arif Hussain6d2a3322013-11-17 19:50:10 -08006030 hddLog(VOS_TRACE_LEVEL_INFO,"acl type = %d no deny mac = %d",
Jeff Johnson295189b2012-06-20 16:38:30 -07006031 pIe[6], pIe[7]);
Gopichand Nakkalac005b7c2013-05-14 16:04:14 +05306032 if (pConfig->num_deny_mac > MAX_ACL_MAC_ADDRESS)
6033 pConfig->num_deny_mac = MAX_ACL_MAC_ADDRESS;
Jeff Johnson295189b2012-06-20 16:38:30 -07006034 acl_entry = (struct qc_mac_acl_entry *)(pIe + 8);
6035 for (i = 0; i < pConfig->num_deny_mac; i++)
6036 {
6037 vos_mem_copy(&pConfig->deny_mac[i], acl_entry->addr, sizeof(qcmacaddr));
6038 acl_entry++;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306039 }
Jeff Johnson295189b2012-06-20 16:38:30 -07006040 }
6041 pIe = wlan_hdd_get_vendor_oui_ie_ptr(WHITELIST_OUI_TYPE, WPA_OUI_TYPE_SIZE,
6042 pBeacon->tail, pBeacon->tail_len);
6043
6044 /* pIe for white list is following form:
6045 type : 1 byte
6046 length : 1 byte
6047 OUI : 4 bytes
6048 acl type : 1 byte
6049 no of mac addr in white list: 1 byte
6050 list of mac_acl_entries: variable, 6 bytes per mac address + sizeof(int) for vlan id
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306051 */
6052 if ((pIe != NULL) && (pIe[1] != 0))
Jeff Johnson295189b2012-06-20 16:38:30 -07006053 {
6054 pConfig->SapMacaddr_acl = pIe[6];
6055 pConfig->num_accept_mac = pIe[7];
Arif Hussain6d2a3322013-11-17 19:50:10 -08006056 hddLog(VOS_TRACE_LEVEL_INFO,"acl type = %d no accept mac = %d",
Jeff Johnson295189b2012-06-20 16:38:30 -07006057 pIe[6], pIe[7]);
Gopichand Nakkalac005b7c2013-05-14 16:04:14 +05306058 if (pConfig->num_accept_mac > MAX_ACL_MAC_ADDRESS)
6059 pConfig->num_accept_mac = MAX_ACL_MAC_ADDRESS;
Jeff Johnson295189b2012-06-20 16:38:30 -07006060 acl_entry = (struct qc_mac_acl_entry *)(pIe + 8);
6061 for (i = 0; i < pConfig->num_accept_mac; i++)
6062 {
6063 vos_mem_copy(&pConfig->accept_mac[i], acl_entry->addr, sizeof(qcmacaddr));
6064 acl_entry++;
6065 }
6066 }
Gopichand Nakkalac005b7c2013-05-14 16:04:14 +05306067
Jeff Johnson295189b2012-06-20 16:38:30 -07006068 wlan_hdd_set_sapHwmode(pHostapdAdapter);
6069
Jeff Johnsone7245742012-09-05 17:12:55 -07006070#ifdef WLAN_FEATURE_11AC
Ravi Kumar Vaishnavbbaebbe2013-01-15 17:09:48 -08006071 /* Overwrite the hostapd setting for HW mode only for 11ac.
Kiet Lam0f320422013-11-21 19:29:17 +05306072 * This is valid only if mode is set to 11n in hostapd, either AUTO or
6073 * 11ac in .ini and 11ac is supported by both host and firmware.
6074 * Otherwise, leave whatever is set in hostapd (a OR b OR g OR n mode)
6075 */
Ravi Kumar Vaishnavbbaebbe2013-01-15 17:09:48 -08006076 if( ((pConfig->SapHw_mode == eSAP_DOT11_MODE_11n) ||
6077 (pConfig->SapHw_mode == eSAP_DOT11_MODE_11n_ONLY)) &&
Abhishek Singhf0ac1752014-03-05 17:47:09 +05306078 (( sapDot11Mode == eHDD_DOT11_MODE_AUTO ) ||
6079 ( sapDot11Mode == eHDD_DOT11_MODE_11ac ) ||
6080 ( sapDot11Mode == eHDD_DOT11_MODE_11ac_ONLY ) ) &&
6081 (sme_IsFeatureSupportedByDriver(DOT11AC)) &&
6082 (sme_IsFeatureSupportedByFW(DOT11AC)) )
Jeff Johnsone7245742012-09-05 17:12:55 -07006083 {
Siddharth Bhalf42f8592014-05-15 13:39:07 +05306084 v_U32_t operatingBand = 0;
Jeff Johnsone7245742012-09-05 17:12:55 -07006085 pConfig->SapHw_mode = eSAP_DOT11_MODE_11ac;
Siddharth Bhalf42f8592014-05-15 13:39:07 +05306086 ccmCfgGetInt(hHal, WNI_CFG_SAP_CHANNEL_SELECT_OPERATING_BAND, &operatingBand);
Ravi Joshi83bfaa12013-05-28 22:12:08 -07006087
Siddharth Bhal5cba24e2014-05-08 18:59:39 +05306088 /* If ACS disable and selected channel <= 14
6089 * OR
6090 * ACS enabled and ACS operating band is choosen as 2.4
6091 * AND
6092 * VHT in 2.4G Disabled
6093 * THEN
6094 * Fallback to 11N mode
6095 */
6096 if (((AUTO_CHANNEL_SELECT != pConfig->channel && pConfig->channel <= SIR_11B_CHANNEL_END)
6097 || (AUTO_CHANNEL_SELECT == pConfig->channel &&
Siddharth Bhalf42f8592014-05-15 13:39:07 +05306098 operatingBand == RF_SUBBAND_2_4_GHZ)) &&
Siddharth Bhal5cba24e2014-05-08 18:59:39 +05306099 iniConfig->enableVhtFor24GHzBand == FALSE)
Ravi Joshi83bfaa12013-05-28 22:12:08 -07006100 {
Siddharth Bhalf42f8592014-05-15 13:39:07 +05306101 hddLog(LOGW, FL("Setting hwmode to 11n, operatingBand = %d, Channel = %d"),
6102 operatingBand, pConfig->channel);
Ravi Joshi83bfaa12013-05-28 22:12:08 -07006103 pConfig->SapHw_mode = eSAP_DOT11_MODE_11n;
6104 }
Jeff Johnsone7245742012-09-05 17:12:55 -07006105 }
6106#endif
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306107
Ravi Joshiaeb7d9e2013-05-02 12:28:14 -07006108 if ( AUTO_CHANNEL_SELECT != pConfig->channel )
6109 {
6110 sme_SelectCBMode(hHal,
6111 sapConvertSapPhyModeToCsrPhyMode(pConfig->SapHw_mode),
6112 pConfig->channel);
6113 }
Jeff Johnson295189b2012-06-20 16:38:30 -07006114 // ht_capab is not what the name conveys,this is used for protection bitmap
6115 pConfig->ht_capab =
6116 (WLAN_HDD_GET_CTX(pHostapdAdapter))->cfg_ini->apProtection;
6117
6118 if ( 0 != wlan_hdd_cfg80211_update_apies(pHostapdAdapter, params) )
6119 {
6120 hddLog(LOGE, FL("SAP Not able to set AP IEs"));
6121 return -EINVAL;
6122 }
6123
6124 //Uapsd Enabled Bit
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306125 pConfig->UapsdEnable =
Jeff Johnson295189b2012-06-20 16:38:30 -07006126 (WLAN_HDD_GET_CTX(pHostapdAdapter))->cfg_ini->apUapsdEnabled;
6127 //Enable OBSS protection
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306128 pConfig->obssProtEnabled =
6129 (WLAN_HDD_GET_CTX(pHostapdAdapter))->cfg_ini->apOBSSProtEnabled;
Jeff Johnson295189b2012-06-20 16:38:30 -07006130
Chet Lanctot8cecea22014-02-11 19:09:36 -08006131#ifdef WLAN_FEATURE_11W
6132 pConfig->mfpCapable = MFPCapable;
6133 pConfig->mfpRequired = MFPRequired;
6134 hddLog(LOGW, FL("Soft AP MFP capable %d, MFP required %d\n"),
6135 pConfig->mfpCapable, pConfig->mfpRequired);
6136#endif
6137
Arif Hussain6d2a3322013-11-17 19:50:10 -08006138 hddLog(LOGW, FL("SOftAP macaddress : "MAC_ADDRESS_STR),
Jeff Johnson295189b2012-06-20 16:38:30 -07006139 MAC_ADDR_ARRAY(pHostapdAdapter->macAddressCurrent.bytes));
Arif Hussain6d2a3322013-11-17 19:50:10 -08006140 hddLog(LOGW,FL("ssid =%s, beaconint=%d, channel=%d"),
6141 pConfig->SSIDinfo.ssid.ssId, (int)pConfig->beacon_int,
6142 (int)pConfig->channel);
6143 hddLog(LOGW,FL("hw_mode=%x, privacy=%d, authType=%d"),
6144 pConfig->SapHw_mode, pConfig->privacy,
6145 pConfig->authType);
6146 hddLog(LOGW,FL("RSN/WPALen=%d, Uapsd = %d"),
6147 (int)pConfig->RSNWPAReqIELength, pConfig->UapsdEnable);
6148 hddLog(LOGW,FL("ProtEnabled = %d, OBSSProtEnabled = %d"),
6149 pConfig->protEnabled, pConfig->obssProtEnabled);
Jeff Johnson295189b2012-06-20 16:38:30 -07006150
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306151 if(test_bit(SOFTAP_BSS_STARTED, &pHostapdAdapter->event_flags))
Jeff Johnson295189b2012-06-20 16:38:30 -07006152 {
6153 //Bss already started. just return.
6154 //TODO Probably it should update some beacon params.
6155 hddLog( LOGE, "Bss Already started...Ignore the request");
6156 EXIT();
6157 return 0;
6158 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306159
Agarwal Ashish51325b52014-06-16 16:50:49 +05306160 if (vos_max_concurrent_connections_reached()) {
6161 hddLog(VOS_TRACE_LEVEL_INFO, FL("Reached max concurrent connections"));
6162 return -EINVAL;
6163 }
6164
Jeff Johnson295189b2012-06-20 16:38:30 -07006165 pConfig->persona = pHostapdAdapter->device_mode;
6166
Peng Xu2446a892014-09-05 17:21:18 +05306167 psmeConfig = (tSmeConfigParams*) vos_mem_malloc(sizeof(tSmeConfigParams));
6168 if ( NULL != psmeConfig)
6169 {
6170 sme_GetConfigParam(hHal, psmeConfig);
6171 pConfig->scanBandPreference = psmeConfig->csrConfig.scanBandPreference;
6172 vos_mem_free(psmeConfig);
6173 }
6174
Jeff Johnson295189b2012-06-20 16:38:30 -07006175 pSapEventCallback = hdd_hostapd_SAPEventCB;
6176 if(WLANSAP_StartBss(pVosContext, pSapEventCallback, pConfig,
6177 (v_PVOID_t)pHostapdAdapter->dev) != VOS_STATUS_SUCCESS)
6178 {
Arif Hussain6d2a3322013-11-17 19:50:10 -08006179 hddLog(LOGE,FL("SAP Start Bss fail"));
Jeff Johnson295189b2012-06-20 16:38:30 -07006180 return -EINVAL;
6181 }
6182
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306183 hddLog(LOG1,
Jeff Johnson295189b2012-06-20 16:38:30 -07006184 FL("Waiting for Scan to complete(auto mode) and BSS to start"));
6185
6186 status = vos_wait_single_event(&pHostapdState->vosEvent, 10000);
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306187
Jeff Johnson295189b2012-06-20 16:38:30 -07006188 if (!VOS_IS_STATUS_SUCCESS(status))
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306189 {
6190 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Arif Hussain6d2a3322013-11-17 19:50:10 -08006191 ("ERROR: HDD vos wait for single_event failed!!"));
Tushnim Bhattacharyyaad37df12013-10-02 12:01:33 -07006192 smeGetCommandQStatus(hHal);
Jeff Johnson295189b2012-06-20 16:38:30 -07006193 VOS_ASSERT(0);
6194 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306195
Jeff Johnson295189b2012-06-20 16:38:30 -07006196 set_bit(SOFTAP_BSS_STARTED, &pHostapdAdapter->event_flags);
Agarwal Ashish51325b52014-06-16 16:50:49 +05306197 wlan_hdd_incr_active_session(pHddCtx, pHostapdAdapter->device_mode);
Jeff Johnson295189b2012-06-20 16:38:30 -07006198
Madan Mohan Koyyalamudi26bd7142012-10-30 18:14:19 -07006199#ifdef WLAN_FEATURE_P2P_DEBUG
6200 if (pHostapdAdapter->device_mode == WLAN_HDD_P2P_GO)
6201 {
6202 if(globalP2PConnectionStatus == P2P_GO_NEG_COMPLETED)
6203 {
6204 globalP2PConnectionStatus = P2P_GO_COMPLETED_STATE;
6205 hddLog(LOGE,"[P2P State] From Go nego completed to "
Jeff Johnson1250df42012-12-10 14:31:52 -08006206 "Non-autonomous Group started");
Madan Mohan Koyyalamudi26bd7142012-10-30 18:14:19 -07006207 }
6208 else if(globalP2PConnectionStatus == P2P_NOT_ACTIVE)
6209 {
6210 globalP2PConnectionStatus = P2P_GO_COMPLETED_STATE;
6211 hddLog(LOGE,"[P2P State] From Inactive to "
Jeff Johnson1250df42012-12-10 14:31:52 -08006212 "Autonomous Group started");
Madan Mohan Koyyalamudi26bd7142012-10-30 18:14:19 -07006213 }
6214 }
6215#endif
6216
Jeff Johnson295189b2012-06-20 16:38:30 -07006217 pHostapdState->bCommit = TRUE;
6218 EXIT();
6219
6220 return 0;
6221}
6222
Jeff Johnson04dd8a82012-06-29 20:41:40 -07006223#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,4,0))
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306224static int wlan_hdd_cfg80211_add_beacon(struct wiphy *wiphy,
6225 struct net_device *dev,
Jeff Johnson295189b2012-06-20 16:38:30 -07006226 struct beacon_parameters *params)
6227{
6228 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +05306229 hdd_context_t *pHddCtx;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05306230 int status;
Jeff Johnson295189b2012-06-20 16:38:30 -07006231
6232 ENTER();
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +05306233
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05306234 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
6235 TRACE_CODE_HDD_CFG80211_ADD_BEACON,
6236 pAdapter->sessionId, params->interval));
Sushant Kaushik8bc7df22014-04-09 17:55:29 +05306237 hddLog(VOS_TRACE_LEVEL_INFO_HIGH, "device mode=%s (%d)",
6238 hdd_device_modetoString(pAdapter->device_mode),
6239 pAdapter->device_mode);
Jeff Johnson295189b2012-06-20 16:38:30 -07006240
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05306241 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
6242 status = wlan_hdd_validate_context(pHddCtx);
6243
6244 if (0 != status)
Jeff Johnson04dd8a82012-06-29 20:41:40 -07006245 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05306246 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
6247 "%s: HDD context is not valid", __func__);
6248 return status;
Jeff Johnson04dd8a82012-06-29 20:41:40 -07006249 }
6250
Agarwal Ashish51325b52014-06-16 16:50:49 +05306251 if (vos_max_concurrent_connections_reached()) {
6252 hddLog(VOS_TRACE_LEVEL_INFO, FL("Reached max concurrent connections"));
6253 return -EINVAL;
6254 }
6255
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306256 if ( (pAdapter->device_mode == WLAN_HDD_SOFTAP)
Jeff Johnson295189b2012-06-20 16:38:30 -07006257 || (pAdapter->device_mode == WLAN_HDD_P2P_GO)
Jeff Johnson295189b2012-06-20 16:38:30 -07006258 )
6259 {
6260 beacon_data_t *old,*new;
6261
6262 old = pAdapter->sessionCtx.ap.beacon;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306263
Jeff Johnson295189b2012-06-20 16:38:30 -07006264 if (old)
c_hpothu6ff1c3c2013-10-01 19:01:57 +05306265 {
6266 hddLog(VOS_TRACE_LEVEL_WARN,
6267 FL("already beacon info added to session(%d)"),
6268 pAdapter->sessionId);
Jeff Johnson295189b2012-06-20 16:38:30 -07006269 return -EALREADY;
c_hpothu6ff1c3c2013-10-01 19:01:57 +05306270 }
Jeff Johnson295189b2012-06-20 16:38:30 -07006271
6272 status = wlan_hdd_cfg80211_alloc_new_beacon(pAdapter,&new,params);
6273
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306274 if(status != VOS_STATUS_SUCCESS)
Jeff Johnson295189b2012-06-20 16:38:30 -07006275 {
6276 hddLog(VOS_TRACE_LEVEL_FATAL,
Arif Hussain6d2a3322013-11-17 19:50:10 -08006277 "%s:Error!!! Allocating the new beacon",__func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07006278 return -EINVAL;
6279 }
6280
6281 pAdapter->sessionCtx.ap.beacon = new;
6282
6283 status = wlan_hdd_cfg80211_start_bss(pAdapter, params);
6284 }
6285
6286 EXIT();
6287 return status;
6288}
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306289
6290static int wlan_hdd_cfg80211_set_beacon(struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -07006291 struct net_device *dev,
6292 struct beacon_parameters *params)
6293{
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306294 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +05306295 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
6296 hdd_context_t *pHddCtx;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05306297 int status;
Jeff Johnson295189b2012-06-20 16:38:30 -07006298
6299 ENTER();
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +05306300 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
6301 TRACE_CODE_HDD_CFG80211_SET_BEACON,
6302 pAdapter->sessionId, pHddStaCtx->conn_info.authType));
6303 hddLog(VOS_TRACE_LEVEL_INFO, "%s: device_mode = %s (%d)",
6304 __func__, hdd_device_modetoString(pAdapter->device_mode),
6305 pAdapter->device_mode);
6306
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05306307 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
6308 status = wlan_hdd_validate_context(pHddCtx);
6309
6310 if (0 != status)
Jeff Johnson04dd8a82012-06-29 20:41:40 -07006311 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05306312 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
6313 "%s: HDD context is not valid", __func__);
6314 return status;
Jeff Johnson04dd8a82012-06-29 20:41:40 -07006315 }
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +05306316
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306317 if ((pAdapter->device_mode == WLAN_HDD_SOFTAP)
Jeff Johnson295189b2012-06-20 16:38:30 -07006318 || (pAdapter->device_mode == WLAN_HDD_P2P_GO)
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306319 )
Jeff Johnson295189b2012-06-20 16:38:30 -07006320 {
6321 beacon_data_t *old,*new;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306322
Jeff Johnson295189b2012-06-20 16:38:30 -07006323 old = pAdapter->sessionCtx.ap.beacon;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306324
Jeff Johnson295189b2012-06-20 16:38:30 -07006325 if (!old)
c_hpothu6ff1c3c2013-10-01 19:01:57 +05306326 {
6327 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
6328 FL("session(%d) old and new heads points to NULL"),
6329 pAdapter->sessionId);
Jeff Johnson295189b2012-06-20 16:38:30 -07006330 return -ENOENT;
c_hpothu6ff1c3c2013-10-01 19:01:57 +05306331 }
Jeff Johnson295189b2012-06-20 16:38:30 -07006332
6333 status = wlan_hdd_cfg80211_alloc_new_beacon(pAdapter,&new,params);
6334
6335 if(status != VOS_STATUS_SUCCESS) {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306336 hddLog(VOS_TRACE_LEVEL_FATAL,
Arif Hussain6d2a3322013-11-17 19:50:10 -08006337 "%s: Error!!! Allocating the new beacon",__func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07006338 return -EINVAL;
6339 }
6340
6341 pAdapter->sessionCtx.ap.beacon = new;
6342
6343 status = wlan_hdd_cfg80211_start_bss(pAdapter, params);
6344 }
6345
6346 EXIT();
6347 return status;
6348}
6349
Jeff Johnson04dd8a82012-06-29 20:41:40 -07006350#endif //(LINUX_VERSION_CODE < KERNEL_VERSION(3,4,0))
6351
6352#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,4,0))
Jeff Johnson295189b2012-06-20 16:38:30 -07006353static int wlan_hdd_cfg80211_del_beacon(struct wiphy *wiphy,
6354 struct net_device *dev)
Jeff Johnson04dd8a82012-06-29 20:41:40 -07006355#else
6356static int wlan_hdd_cfg80211_stop_ap (struct wiphy *wiphy,
6357 struct net_device *dev)
6358#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07006359{
6360 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
Jeff Johnsone7245742012-09-05 17:12:55 -07006361 hdd_context_t *pHddCtx = NULL;
6362 hdd_scaninfo_t *pScanInfo = NULL;
6363 hdd_adapter_t *staAdapter = NULL;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05306364 VOS_STATUS status;
Mahesh A Saptasagar2395ee62014-05-21 19:12:21 +05306365 long ret;
Jeff Johnson295189b2012-06-20 16:38:30 -07006366
6367 ENTER();
6368
6369 if (NULL == pAdapter)
6370 {
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +05306371 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07006372 "%s: HDD adapter context is Null", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07006373 return -ENODEV;
6374 }
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -07006375
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05306376 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
6377 TRACE_CODE_HDD_CFG80211_STOP_AP,
6378 pAdapter->sessionId, pAdapter->device_mode));
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05306379 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
6380 status = wlan_hdd_validate_context(pHddCtx);
6381
6382 if (0 != status)
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -07006383 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05306384 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
6385 "%s: HDD context is not valid", __func__);
6386 return status;
Jeff Johnson4416a782013-03-25 14:17:50 -07006387 }
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -07006388
6389 staAdapter = hdd_get_adapter(pAdapter->pHddCtx, WLAN_HDD_INFRA_STATION);
6390 if (NULL == staAdapter)
6391 {
6392 staAdapter = hdd_get_adapter(pAdapter->pHddCtx, WLAN_HDD_P2P_CLIENT);
6393 if (NULL == staAdapter)
6394 {
Rajesh Chauhan52d885b2013-11-01 10:54:25 -07006395 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO_HIGH,
6396 "%s: HDD adapter context for STA/P2P-CLI is Null",
6397 __func__);
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -07006398 }
6399 }
6400
6401 pScanInfo = &pHddCtx->scan_info;
6402
Sushant Kaushik8bc7df22014-04-09 17:55:29 +05306403 hddLog(VOS_TRACE_LEVEL_INFO, "%s: device_mode = %s (%d)",
6404 __func__, hdd_device_modetoString(pAdapter->device_mode),
6405 pAdapter->device_mode);
Jeff Johnson295189b2012-06-20 16:38:30 -07006406
Mahesh A Saptasagar2395ee62014-05-21 19:12:21 +05306407 ret = wlan_hdd_scan_abort(pAdapter);
6408
Girish Gowli4bf7a632014-06-12 13:42:11 +05306409 if (ret < 0)
Jeff Johnsone7245742012-09-05 17:12:55 -07006410 {
Mahesh A Saptasagar2395ee62014-05-21 19:12:21 +05306411 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
6412 FL("Timeout occurred while waiting for abortscan %ld"), ret);
c_hpothu6ff1c3c2013-10-01 19:01:57 +05306413
Mahesh A Saptasagar2395ee62014-05-21 19:12:21 +05306414 if (pHddCtx->isLogpInProgress)
Jeff Johnsone7245742012-09-05 17:12:55 -07006415 {
Mahesh A Saptasagar2395ee62014-05-21 19:12:21 +05306416 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
6417 "%s: LOGP in Progress. Ignore!!!", __func__);
Yue Ma4f55ef32014-01-23 16:45:33 -08006418
Jeff Johnsone7245742012-09-05 17:12:55 -07006419 VOS_ASSERT(pScanInfo->mScanPending);
Mahesh A Saptasagar2395ee62014-05-21 19:12:21 +05306420 return -EAGAIN;
Jeff Johnsone7245742012-09-05 17:12:55 -07006421 }
Mahesh A Saptasagar2395ee62014-05-21 19:12:21 +05306422 VOS_ASSERT(pScanInfo->mScanPending);
Jeff Johnsone7245742012-09-05 17:12:55 -07006423 }
6424
Rashmi Ramanna1f0948d2014-08-28 15:33:48 +05306425 /* Delete all associated STAs before stopping AP/P2P GO */
6426 hdd_del_all_sta(pAdapter);
Arun Kumar Khandavallia3bd8002014-01-17 16:21:19 +05306427 hdd_hostapd_stop(dev);
6428
Jeff Johnson295189b2012-06-20 16:38:30 -07006429 if ((pAdapter->device_mode == WLAN_HDD_SOFTAP)
Jeff Johnson295189b2012-06-20 16:38:30 -07006430 || (pAdapter->device_mode == WLAN_HDD_P2P_GO)
Jeff Johnson295189b2012-06-20 16:38:30 -07006431 )
6432 {
6433 beacon_data_t *old;
6434
6435 old = pAdapter->sessionCtx.ap.beacon;
6436
6437 if (!old)
c_hpothu6ff1c3c2013-10-01 19:01:57 +05306438 {
6439 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
6440 FL("session(%d) beacon data points to NULL"),
6441 pAdapter->sessionId);
Jeff Johnson295189b2012-06-20 16:38:30 -07006442 return -ENOENT;
c_hpothu6ff1c3c2013-10-01 19:01:57 +05306443 }
Jeff Johnson295189b2012-06-20 16:38:30 -07006444
Jeff Johnson295189b2012-06-20 16:38:30 -07006445 hdd_cleanup_actionframe(pHddCtx, pAdapter);
Jeff Johnson295189b2012-06-20 16:38:30 -07006446
6447 mutex_lock(&pHddCtx->sap_lock);
6448 if(test_bit(SOFTAP_BSS_STARTED, &pAdapter->event_flags))
6449 {
Jeff Johnson4416a782013-03-25 14:17:50 -07006450 if ( VOS_STATUS_SUCCESS == (status = WLANSAP_StopBss(pHddCtx->pvosContext) ) )
Jeff Johnson295189b2012-06-20 16:38:30 -07006451 {
6452 hdd_hostapd_state_t *pHostapdState = WLAN_HDD_GET_HOSTAP_STATE_PTR(pAdapter);
6453
6454 status = vos_wait_single_event(&pHostapdState->vosEvent, 10000);
6455
6456 if (!VOS_IS_STATUS_SUCCESS(status))
6457 {
6458 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Arif Hussain6d2a3322013-11-17 19:50:10 -08006459 ("ERROR: HDD vos wait for single_event failed!!"));
Jeff Johnson295189b2012-06-20 16:38:30 -07006460 VOS_ASSERT(0);
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05306461 }
6462 }
Jeff Johnson295189b2012-06-20 16:38:30 -07006463 clear_bit(SOFTAP_BSS_STARTED, &pAdapter->event_flags);
Agarwal Ashish51325b52014-06-16 16:50:49 +05306464 /* BSS stopped, clear the active sessions for this device mode */
6465 wlan_hdd_decr_active_session(pHddCtx, pAdapter->device_mode);
Jeff Johnson295189b2012-06-20 16:38:30 -07006466 }
6467 mutex_unlock(&pHddCtx->sap_lock);
6468
6469 if(status != VOS_STATUS_SUCCESS)
6470 {
6471 hddLog(VOS_TRACE_LEVEL_FATAL,
Arif Hussain6d2a3322013-11-17 19:50:10 -08006472 "%s:Error!!! Stopping the BSS",__func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07006473 return -EINVAL;
6474 }
6475
Jeff Johnson4416a782013-03-25 14:17:50 -07006476 if (ccmCfgSetInt(pHddCtx->hHal,
Jeff Johnson295189b2012-06-20 16:38:30 -07006477 WNI_CFG_PROBE_RSP_BCN_ADDNIE_FLAG, 0,NULL, eANI_BOOLEAN_FALSE)
6478 ==eHAL_STATUS_FAILURE)
6479 {
6480 hddLog(LOGE,
Arif Hussain6d2a3322013-11-17 19:50:10 -08006481 "Could not pass on WNI_CFG_PROBE_RSP_BCN_ADDNIE_FLAG to CCM");
Jeff Johnson295189b2012-06-20 16:38:30 -07006482 }
6483
Jeff Johnson4416a782013-03-25 14:17:50 -07006484 if ( eHAL_STATUS_FAILURE == ccmCfgSetInt(pHddCtx->hHal,
Jeff Johnson295189b2012-06-20 16:38:30 -07006485 WNI_CFG_ASSOC_RSP_ADDNIE_FLAG, 0, NULL,
6486 eANI_BOOLEAN_FALSE) )
6487 {
6488 hddLog(LOGE,
Arif Hussain6d2a3322013-11-17 19:50:10 -08006489 "Could not pass on WNI_CFG_ASSOC_RSP_ADDNIE_FLAG to CCM");
Jeff Johnson295189b2012-06-20 16:38:30 -07006490 }
6491
6492 // Reset WNI_CFG_PROBE_RSP Flags
6493 wlan_hdd_reset_prob_rspies(pAdapter);
6494
6495 pAdapter->sessionCtx.ap.beacon = NULL;
6496 kfree(old);
Madan Mohan Koyyalamudi26bd7142012-10-30 18:14:19 -07006497#ifdef WLAN_FEATURE_P2P_DEBUG
6498 if((pAdapter->device_mode == WLAN_HDD_P2P_GO) &&
6499 (globalP2PConnectionStatus == P2P_GO_COMPLETED_STATE))
6500 {
6501 hddLog(LOGE,"[P2P State] From GO completed to Inactive state "
6502 "GO got removed");
6503 globalP2PConnectionStatus = P2P_NOT_ACTIVE;
6504 }
6505#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07006506 }
6507 EXIT();
6508 return status;
6509}
Jeff Johnson04dd8a82012-06-29 20:41:40 -07006510
6511#if (LINUX_VERSION_CODE > KERNEL_VERSION(3,3,0))
6512
Pratik Bhalgata0c7f262012-11-22 17:40:24 +05306513static int wlan_hdd_cfg80211_start_ap(struct wiphy *wiphy,
6514 struct net_device *dev,
Jeff Johnson04dd8a82012-06-29 20:41:40 -07006515 struct cfg80211_ap_settings *params)
6516{
Pratik Bhalgata0c7f262012-11-22 17:40:24 +05306517 hdd_adapter_t *pAdapter;
6518 hdd_context_t *pHddCtx;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05306519 int status;
Jeff Johnson04dd8a82012-06-29 20:41:40 -07006520
6521 ENTER();
6522
Pratik Bhalgata0c7f262012-11-22 17:40:24 +05306523 if (NULL == dev)
Madan Mohan Koyyalamudib2c36892012-10-18 20:52:38 -07006524 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05306525 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Pratik Bhalgata0c7f262012-11-22 17:40:24 +05306526 "%s: Device is Null", __func__);
6527 return -ENODEV;
6528 }
6529
6530 pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
6531 if (NULL == pAdapter)
6532 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05306533 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Pratik Bhalgata0c7f262012-11-22 17:40:24 +05306534 "%s: HDD adapter is Null", __func__);
6535 return -ENODEV;
6536 }
6537
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05306538 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
6539 TRACE_CODE_HDD_CFG80211_START_AP, pAdapter->sessionId,
6540 params-> beacon_interval));
Pratik Bhalgata0c7f262012-11-22 17:40:24 +05306541 if (WLAN_HDD_ADAPTER_MAGIC != pAdapter->magic)
6542 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05306543 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Pratik Bhalgata0c7f262012-11-22 17:40:24 +05306544 "%s: HDD adapter magic is invalid", __func__);
6545 return -ENODEV;
6546 }
6547
6548 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05306549 status = wlan_hdd_validate_context(pHddCtx);
Pratik Bhalgata0c7f262012-11-22 17:40:24 +05306550
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05306551 if (0 != status)
Pratik Bhalgata0c7f262012-11-22 17:40:24 +05306552 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05306553 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
6554 "%s: HDD context is not valid", __func__);
6555 return status;
Pratik Bhalgata0c7f262012-11-22 17:40:24 +05306556 }
6557
Sushant Kaushik8bc7df22014-04-09 17:55:29 +05306558 hddLog(VOS_TRACE_LEVEL_INFO_HIGH, "%s: device mode = %s (%d)",
6559 __func__, hdd_device_modetoString(pAdapter->device_mode),
6560 pAdapter->device_mode);
Pratik Bhalgata0c7f262012-11-22 17:40:24 +05306561
6562 if ((pAdapter->device_mode == WLAN_HDD_SOFTAP)
Jeff Johnson04dd8a82012-06-29 20:41:40 -07006563 || (pAdapter->device_mode == WLAN_HDD_P2P_GO)
Jeff Johnson04dd8a82012-06-29 20:41:40 -07006564 )
6565 {
Pratik Bhalgata0c7f262012-11-22 17:40:24 +05306566 beacon_data_t *old, *new;
Jeff Johnson04dd8a82012-06-29 20:41:40 -07006567
6568 old = pAdapter->sessionCtx.ap.beacon;
Pratik Bhalgata0c7f262012-11-22 17:40:24 +05306569
Jeff Johnson04dd8a82012-06-29 20:41:40 -07006570 if (old)
c_hpothu6ff1c3c2013-10-01 19:01:57 +05306571 {
6572 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_WARN,
6573 FL("already beacon info added to session(%d)"),
6574 pAdapter->sessionId);
Jeff Johnson04dd8a82012-06-29 20:41:40 -07006575 return -EALREADY;
c_hpothu6ff1c3c2013-10-01 19:01:57 +05306576 }
Jeff Johnson04dd8a82012-06-29 20:41:40 -07006577
6578 status = wlan_hdd_cfg80211_alloc_new_beacon(pAdapter, &new, &params->beacon, params->dtim_period);
6579
Pratik Bhalgata0c7f262012-11-22 17:40:24 +05306580 if (status != 0)
Jeff Johnson04dd8a82012-06-29 20:41:40 -07006581 {
6582 hddLog(VOS_TRACE_LEVEL_FATAL,
Pratik Bhalgata0c7f262012-11-22 17:40:24 +05306583 "%s:Error!!! Allocating the new beacon", __func__);
Jeff Johnson04dd8a82012-06-29 20:41:40 -07006584 return -EINVAL;
6585 }
6586 pAdapter->sessionCtx.ap.beacon = new;
Viral Modi3a32cc52013-02-08 11:14:52 -08006587#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,6,0))
Yue Maf49ba872013-08-19 12:04:25 -07006588 wlan_hdd_cfg80211_set_channel(wiphy, dev,
6589#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,8,0))
6590 params->channel, params->channel_type);
6591#else
6592 params->chandef.chan, cfg80211_get_chandef_type(&(params->chandef)));
6593#endif
Viral Modi3a32cc52013-02-08 11:14:52 -08006594#endif
Jeff Johnson04dd8a82012-06-29 20:41:40 -07006595 status = wlan_hdd_cfg80211_start_bss(pAdapter, &params->beacon, params->ssid,
6596 params->ssid_len, params->hidden_ssid);
6597 }
6598
6599 EXIT();
6600 return status;
6601}
6602
6603
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306604static int wlan_hdd_cfg80211_change_beacon(struct wiphy *wiphy,
Jeff Johnson04dd8a82012-06-29 20:41:40 -07006605 struct net_device *dev,
6606 struct cfg80211_beacon_data *params)
6607{
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306608 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +05306609 hdd_context_t *pHddCtx;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05306610 int status;
Jeff Johnson04dd8a82012-06-29 20:41:40 -07006611
6612 ENTER();
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +05306613
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05306614 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
6615 TRACE_CODE_HDD_CFG80211_CHANGE_BEACON,
6616 pAdapter->sessionId, pAdapter->device_mode));
Arif Hussain6d2a3322013-11-17 19:50:10 -08006617 hddLog(VOS_TRACE_LEVEL_INFO, "%s: device_mode = %d",
Jeff Johnson04dd8a82012-06-29 20:41:40 -07006618 __func__, pAdapter->device_mode);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05306619
6620 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
6621 status = wlan_hdd_validate_context(pHddCtx);
6622
6623 if (0 != status)
Madan Mohan Koyyalamudib2c36892012-10-18 20:52:38 -07006624 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05306625 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
6626 "%s: HDD context is not valid", __func__);
6627 return status;
Madan Mohan Koyyalamudib2c36892012-10-18 20:52:38 -07006628 }
Jeff Johnson04dd8a82012-06-29 20:41:40 -07006629
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306630 if ((pAdapter->device_mode == WLAN_HDD_SOFTAP)
Jeff Johnson04dd8a82012-06-29 20:41:40 -07006631 || (pAdapter->device_mode == WLAN_HDD_P2P_GO)
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306632 )
Jeff Johnson04dd8a82012-06-29 20:41:40 -07006633 {
6634 beacon_data_t *old,*new;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306635
Jeff Johnson04dd8a82012-06-29 20:41:40 -07006636 old = pAdapter->sessionCtx.ap.beacon;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306637
Jeff Johnson04dd8a82012-06-29 20:41:40 -07006638 if (!old)
c_hpothu6ff1c3c2013-10-01 19:01:57 +05306639 {
6640 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
6641 FL("session(%d) beacon data points to NULL"),
6642 pAdapter->sessionId);
Jeff Johnson04dd8a82012-06-29 20:41:40 -07006643 return -ENOENT;
c_hpothu6ff1c3c2013-10-01 19:01:57 +05306644 }
Jeff Johnson04dd8a82012-06-29 20:41:40 -07006645
6646 status = wlan_hdd_cfg80211_alloc_new_beacon(pAdapter, &new, params, 0);
6647
6648 if(status != VOS_STATUS_SUCCESS) {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306649 hddLog(VOS_TRACE_LEVEL_FATAL,
Arif Hussain6d2a3322013-11-17 19:50:10 -08006650 "%s: Error!!! Allocating the new beacon",__func__);
Jeff Johnson04dd8a82012-06-29 20:41:40 -07006651 return -EINVAL;
6652 }
6653
6654 pAdapter->sessionCtx.ap.beacon = new;
6655
6656 status = wlan_hdd_cfg80211_start_bss(pAdapter, params, NULL, 0, 0);
6657 }
6658
6659 EXIT();
6660 return status;
6661}
6662
6663#endif //(LINUX_VERSION_CODE > KERNEL_VERSION(3,3,0))
6664
Jeff Johnson295189b2012-06-20 16:38:30 -07006665
Mahesh A Saptasagar179d2252014-06-02 21:32:21 +05306666static int __wlan_hdd_cfg80211_change_bss (struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -07006667 struct net_device *dev,
6668 struct bss_parameters *params)
6669{
6670 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
6671
6672 ENTER();
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +05306673
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05306674 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
6675 TRACE_CODE_HDD_CFG80211_CHANGE_BSS,
6676 pAdapter->sessionId, params->ap_isolate));
Sushant Kaushik8bc7df22014-04-09 17:55:29 +05306677 hddLog(VOS_TRACE_LEVEL_INFO, "%s: device_mode = %s (%d)",
6678 __func__, hdd_device_modetoString(pAdapter->device_mode),
6679 pAdapter->device_mode);
Jeff Johnson295189b2012-06-20 16:38:30 -07006680
6681 if((pAdapter->device_mode == WLAN_HDD_SOFTAP)
Jeff Johnson295189b2012-06-20 16:38:30 -07006682 || (pAdapter->device_mode == WLAN_HDD_P2P_GO)
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306683 )
Jeff Johnson295189b2012-06-20 16:38:30 -07006684 {
6685 /* ap_isolate == -1 means that in change bss, upper layer doesn't
6686 * want to update this parameter */
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306687 if (-1 != params->ap_isolate)
Jeff Johnson295189b2012-06-20 16:38:30 -07006688 {
6689 pAdapter->sessionCtx.ap.apDisableIntraBssFwd = !!params->ap_isolate;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306690 }
Jeff Johnson295189b2012-06-20 16:38:30 -07006691 }
6692
6693 EXIT();
6694 return 0;
6695}
6696
Mahesh A Saptasagar179d2252014-06-02 21:32:21 +05306697static int wlan_hdd_cfg80211_change_bss (struct wiphy *wiphy,
6698 struct net_device *dev,
6699 struct bss_parameters *params)
6700{
6701 int ret;
6702
6703 vos_ssr_protect(__func__);
6704 ret = __wlan_hdd_cfg80211_change_bss(wiphy, dev, params);
6705 vos_ssr_unprotect(__func__);
6706
6707 return ret;
6708}
Kiet Lam10841362013-11-01 11:36:50 +05306709/* FUNCTION: wlan_hdd_change_country_code_cd
6710* to wait for contry code completion
6711*/
6712void* wlan_hdd_change_country_code_cb(void *pAdapter)
6713{
6714 hdd_adapter_t *call_back_pAdapter = pAdapter;
6715 complete(&call_back_pAdapter->change_country_code);
6716 return NULL;
6717}
6718
Jeff Johnson295189b2012-06-20 16:38:30 -07006719/*
Mahesh A Saptasagar0e59c472014-04-14 19:17:41 +05306720 * FUNCTION: __wlan_hdd_cfg80211_change_iface
Jeff Johnson295189b2012-06-20 16:38:30 -07006721 * This function is used to set the interface type (INFRASTRUCTURE/ADHOC)
6722 */
Mahesh A Saptasagar0e59c472014-04-14 19:17:41 +05306723int __wlan_hdd_cfg80211_change_iface( struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -07006724 struct net_device *ndev,
6725 enum nl80211_iftype type,
6726 u32 *flags,
6727 struct vif_params *params
6728 )
6729{
6730 struct wireless_dev *wdev;
6731 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( ndev );
Rajesh Chauhana0516c62014-01-30 16:11:18 -08006732 hdd_context_t *pHddCtx;
Mohit Khanna0f232092012-09-11 14:46:08 -07006733 hdd_adapter_t *pP2pAdapter = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -07006734 tCsrRoamProfile *pRoamProfile = NULL;
6735 eCsrRoamBssType LastBSSType;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05306736 hdd_config_t *pConfig = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -07006737 eMib_dot11DesiredBssType connectedBssType;
6738 VOS_STATUS status;
c_hpothu6ff1c3c2013-10-01 19:01:57 +05306739 long ret;
Jeff Johnson295189b2012-06-20 16:38:30 -07006740
6741 ENTER();
6742
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05306743 if (!pAdapter)
Rajesh Chauhana0516c62014-01-30 16:11:18 -08006744 {
6745 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
6746 "%s: Adapter context is null", __func__);
6747 return VOS_STATUS_E_FAILURE;
6748 }
6749
6750 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
6751 if (!pHddCtx)
6752 {
6753 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
6754 "%s: HDD context is null", __func__);
6755 return VOS_STATUS_E_FAILURE;
6756 }
6757
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05306758 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
6759 TRACE_CODE_HDD_CFG80211_CHANGE_IFACE,
6760 pAdapter->sessionId, type));
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05306761 status = wlan_hdd_validate_context(pHddCtx);
6762
6763 if (0 != status)
Jeff Johnson295189b2012-06-20 16:38:30 -07006764 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05306765 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
6766 "%s: HDD context is not valid", __func__);
6767 return status;
Jeff Johnson295189b2012-06-20 16:38:30 -07006768 }
6769
Sushant Kaushik8bc7df22014-04-09 17:55:29 +05306770 hddLog(VOS_TRACE_LEVEL_INFO, "%s: device_mode = %s (%d)",
6771 __func__, hdd_device_modetoString(pAdapter->device_mode),
6772 pAdapter->device_mode);
Jeff Johnson295189b2012-06-20 16:38:30 -07006773
Agarwal Ashish51325b52014-06-16 16:50:49 +05306774 if (vos_max_concurrent_connections_reached()) {
6775 hddLog(VOS_TRACE_LEVEL_INFO, FL("Reached max concurrent connections"));
6776 return -EINVAL;
6777 }
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05306778 pConfig = pHddCtx->cfg_ini;
Jeff Johnson295189b2012-06-20 16:38:30 -07006779 wdev = ndev->ieee80211_ptr;
6780
6781#ifdef WLAN_BTAMP_FEATURE
6782 if((NL80211_IFTYPE_P2P_CLIENT == type)||
6783 (NL80211_IFTYPE_ADHOC == type)||
6784 (NL80211_IFTYPE_AP == type)||
6785 (NL80211_IFTYPE_P2P_GO == type))
6786 {
6787 pHddCtx->isAmpAllowed = VOS_FALSE;
6788 // stop AMP traffic
6789 status = WLANBAP_StopAmp();
6790 if(VOS_STATUS_SUCCESS != status )
6791 {
6792 pHddCtx->isAmpAllowed = VOS_TRUE;
6793 hddLog(VOS_TRACE_LEVEL_FATAL,
6794 "%s: Failed to stop AMP", __func__);
6795 return -EINVAL;
6796 }
6797 }
6798#endif //WLAN_BTAMP_FEATURE
6799 /* Reset the current device mode bit mask*/
6800 wlan_hdd_clear_concurrency_mode(pHddCtx, pAdapter->device_mode);
6801
6802 if( (pAdapter->device_mode == WLAN_HDD_INFRA_STATION)
Jeff Johnson295189b2012-06-20 16:38:30 -07006803 || (pAdapter->device_mode == WLAN_HDD_P2P_CLIENT)
Jeff Johnsone7245742012-09-05 17:12:55 -07006804 || (pAdapter->device_mode == WLAN_HDD_P2P_DEVICE)
Jeff Johnson295189b2012-06-20 16:38:30 -07006805 )
6806 {
6807 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
Rajesh Chauhana0516c62014-01-30 16:11:18 -08006808 if (!pWextState)
6809 {
6810 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
6811 "%s: pWextState is null", __func__);
6812 return VOS_STATUS_E_FAILURE;
6813 }
Jeff Johnson295189b2012-06-20 16:38:30 -07006814 pRoamProfile = &pWextState->roamProfile;
6815 LastBSSType = pRoamProfile->BSSType;
6816
6817 switch (type)
6818 {
6819 case NL80211_IFTYPE_STATION:
Jeff Johnson295189b2012-06-20 16:38:30 -07006820 case NL80211_IFTYPE_P2P_CLIENT:
Jeff Johnson295189b2012-06-20 16:38:30 -07006821 hddLog(VOS_TRACE_LEVEL_INFO,
6822 "%s: setting interface Type to INFRASTRUCTURE", __func__);
6823 pRoamProfile->BSSType = eCSR_BSS_TYPE_INFRASTRUCTURE;
Jeff Johnsone7245742012-09-05 17:12:55 -07006824#ifdef WLAN_FEATURE_11AC
6825 if(pConfig->dot11Mode == eHDD_DOT11_MODE_AUTO)
6826 {
6827 pConfig->dot11Mode = eHDD_DOT11_MODE_11ac;
6828 }
6829#endif
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306830 pRoamProfile->phyMode =
Jeff Johnsone7245742012-09-05 17:12:55 -07006831 hdd_cfg_xlate_to_csr_phy_mode(pConfig->dot11Mode);
Jeff Johnson295189b2012-06-20 16:38:30 -07006832 wdev->iftype = type;
Gopichand Nakkalaf527dc62012-12-31 16:35:10 -08006833 //Check for sub-string p2p to confirm its a p2p interface
6834 if (NULL != strstr(ndev->name,"p2p"))
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306835 {
Gopichand Nakkala864d3552012-12-31 16:08:51 -08006836 pAdapter->device_mode = (type == NL80211_IFTYPE_STATION) ?
6837 WLAN_HDD_P2P_DEVICE : WLAN_HDD_P2P_CLIENT;
6838 }
6839 else
6840 {
6841 pAdapter->device_mode = (type == NL80211_IFTYPE_STATION) ?
Jeff Johnson295189b2012-06-20 16:38:30 -07006842 WLAN_HDD_INFRA_STATION: WLAN_HDD_P2P_CLIENT;
Gopichand Nakkala864d3552012-12-31 16:08:51 -08006843 }
Madan Mohan Koyyalamudi81746922013-07-17 14:38:51 +05306844#ifdef FEATURE_WLAN_TDLS
6845 /* The open adapter for the p2p shall skip initializations in
6846 * tdls_init if the device mode is WLAN_HDD_P2P_DEVICE, for
6847 * TDLS is supported only on WLAN_HDD_P2P_CLIENT. Hence invoke
6848 * tdls_init when the change_iface sets the device mode to
6849 * WLAN_HDD_P2P_CLIENT.
6850 */
6851
6852 if ( pAdapter->device_mode == WLAN_HDD_P2P_CLIENT)
6853 {
Agarwal Ashish4b87f922014-06-18 03:03:21 +05306854 if (0 != wlan_hdd_sta_tdls_init (pAdapter))
Madan Mohan Koyyalamudi81746922013-07-17 14:38:51 +05306855 {
c_hpothu6ff1c3c2013-10-01 19:01:57 +05306856 hddLog(VOS_TRACE_LEVEL_ERROR,
6857 "%s: tdls initialization failed", __func__);
Madan Mohan Koyyalamudi81746922013-07-17 14:38:51 +05306858 return -EINVAL;
6859 }
6860 }
6861#endif
6862
Jeff Johnson295189b2012-06-20 16:38:30 -07006863 break;
6864 case NL80211_IFTYPE_ADHOC:
6865 hddLog(VOS_TRACE_LEVEL_INFO,
6866 "%s: setting interface Type to ADHOC", __func__);
6867 pRoamProfile->BSSType = eCSR_BSS_TYPE_START_IBSS;
6868 pRoamProfile->phyMode =
6869 hdd_cfg_xlate_to_csr_phy_mode(pConfig->dot11Mode);
Shailender Karmuchia734f332013-04-19 14:02:48 -07006870 pAdapter->device_mode = WLAN_HDD_IBSS;
Jeff Johnson295189b2012-06-20 16:38:30 -07006871 wdev->iftype = type;
6872 break;
6873
6874 case NL80211_IFTYPE_AP:
Jeff Johnson295189b2012-06-20 16:38:30 -07006875 case NL80211_IFTYPE_P2P_GO:
Jeff Johnson295189b2012-06-20 16:38:30 -07006876 {
6877 hddLog(VOS_TRACE_LEVEL_INFO_HIGH,
6878 "%s: setting interface Type to %s", __func__,
6879 (type == NL80211_IFTYPE_AP) ? "SoftAP" : "P2pGo");
6880
Gopichand Nakkalaf527dc62012-12-31 16:35:10 -08006881 //Cancel any remain on channel for GO mode
6882 if (NL80211_IFTYPE_P2P_GO == type)
6883 {
6884 wlan_hdd_cancel_existing_remain_on_channel(pAdapter);
6885 }
Mohit Khanna0f232092012-09-11 14:46:08 -07006886 if (NL80211_IFTYPE_AP == type)
6887 {
6888 /* As Loading WLAN Driver one interface being created for p2p device
6889 * address. This will take one HW STA and the max number of clients
6890 * that can connect to softAP will be reduced by one. so while changing
6891 * the interface type to NL80211_IFTYPE_AP (SoftAP) remove p2p0
6892 * interface as it is not required in SoftAP mode.
6893 */
6894
6895 // Get P2P Adapter
6896 pP2pAdapter = hdd_get_adapter(pHddCtx, WLAN_HDD_P2P_DEVICE);
6897
6898 if (pP2pAdapter)
6899 {
Agarwal Ashish3a38bd12014-06-12 15:16:52 +05306900 hdd_stop_adapter(pHddCtx, pP2pAdapter, VOS_TRUE);
Mohit Khanna0f232092012-09-11 14:46:08 -07006901 hdd_deinit_adapter(pHddCtx, pP2pAdapter);
6902 hdd_close_adapter(pHddCtx, pP2pAdapter, VOS_TRUE);
6903 }
6904 }
Swaroop Goltia2e32212014-04-09 23:37:33 +05306905 //Disable IMPS & BMPS for SAP/GO
6906 if(VOS_STATUS_E_FAILURE ==
6907 hdd_disable_bmps_imps(pHddCtx, WLAN_HDD_P2P_GO))
6908 {
6909 //Fail to Exit BMPS
6910 VOS_ASSERT(0);
6911 }
Deepthi Gowri500fc472014-08-11 19:53:10 +05306912
6913 hdd_stop_adapter( pHddCtx, pAdapter, VOS_TRUE );
6914
Madan Mohan Koyyalamudi96797442013-10-08 16:04:42 +05306915#ifdef FEATURE_WLAN_TDLS
Mohit Khanna0f232092012-09-11 14:46:08 -07006916
Madan Mohan Koyyalamudi96797442013-10-08 16:04:42 +05306917 /* A Mutex Lock is introduced while changing the mode to
6918 * protect the concurrent access for the Adapters by TDLS
6919 * module.
6920 */
Rajesh Chauhana34c6e62014-03-25 16:37:58 +05306921 mutex_lock(&pHddCtx->tdls_lock);
Madan Mohan Koyyalamudi96797442013-10-08 16:04:42 +05306922#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07006923 //De-init the adapter.
Jeff Johnson295189b2012-06-20 16:38:30 -07006924 hdd_deinit_adapter( pHddCtx, pAdapter );
6925 memset(&pAdapter->sessionCtx, 0, sizeof(pAdapter->sessionCtx));
Jeff Johnson295189b2012-06-20 16:38:30 -07006926 pAdapter->device_mode = (type == NL80211_IFTYPE_AP) ?
6927 WLAN_HDD_SOFTAP : WLAN_HDD_P2P_GO;
Madan Mohan Koyyalamudi96797442013-10-08 16:04:42 +05306928#ifdef FEATURE_WLAN_TDLS
6929 mutex_unlock(&pHddCtx->tdls_lock);
6930#endif
Madan Mohan Koyyalamudi3ff2a0b2012-10-15 14:33:46 -07006931 if ((WLAN_HDD_SOFTAP == pAdapter->device_mode) &&
6932 (pConfig->apRandomBssidEnabled))
6933 {
6934 /* To meet Android requirements create a randomized
6935 MAC address of the form 02:1A:11:Fx:xx:xx */
6936 get_random_bytes(&ndev->dev_addr[3], 3);
6937 ndev->dev_addr[0] = 0x02;
6938 ndev->dev_addr[1] = 0x1A;
6939 ndev->dev_addr[2] = 0x11;
6940 ndev->dev_addr[3] |= 0xF0;
6941 memcpy(pAdapter->macAddressCurrent.bytes, ndev->dev_addr,
6942 VOS_MAC_ADDR_SIZE);
Arif Hussain24bafea2013-11-15 15:10:03 -08006943 pr_info("wlan: Generated HotSpot BSSID " MAC_ADDRESS_STR"\n",
6944 MAC_ADDR_ARRAY(ndev->dev_addr));
Madan Mohan Koyyalamudi3ff2a0b2012-10-15 14:33:46 -07006945 }
6946
Jeff Johnson295189b2012-06-20 16:38:30 -07006947 hdd_set_ap_ops( pAdapter->dev );
6948
Kiet Lam10841362013-11-01 11:36:50 +05306949 /* This is for only SAP mode where users can
6950 * control country through ini.
6951 * P2P GO follows station country code
6952 * acquired during the STA scanning. */
6953 if((NL80211_IFTYPE_AP == type) &&
6954 (memcmp(pConfig->apCntryCode, CFG_AP_COUNTRY_CODE_DEFAULT, 3) != 0))
6955 {
6956 int status = 0;
6957 VOS_TRACE(VOS_MODULE_ID_HDD,VOS_TRACE_LEVEL_INFO,
6958 "%s: setting country code from INI ", __func__);
6959 init_completion(&pAdapter->change_country_code);
6960 status = (int)sme_ChangeCountryCode(pHddCtx->hHal,
6961 (void *)(tSmeChangeCountryCallback)
6962 wlan_hdd_change_country_code_cb,
6963 pConfig->apCntryCode, pAdapter,
6964 pHddCtx->pvosContext,
Abhishek Singha306a442013-11-07 18:39:01 +05306965 eSIR_FALSE,
6966 eSIR_TRUE);
Kiet Lam10841362013-11-01 11:36:50 +05306967 if (eHAL_STATUS_SUCCESS == status)
6968 {
6969 /* Wait for completion */
c_hpothu6ff1c3c2013-10-01 19:01:57 +05306970 ret = wait_for_completion_interruptible_timeout(
Kiet Lam10841362013-11-01 11:36:50 +05306971 &pAdapter->change_country_code,
6972 msecs_to_jiffies(WLAN_WAIT_TIME_COUNTRY));
c_hpothu6ff1c3c2013-10-01 19:01:57 +05306973 if (ret <= 0)
Kiet Lam10841362013-11-01 11:36:50 +05306974 {
6975 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
c_hpothu6ff1c3c2013-10-01 19:01:57 +05306976 FL("SME Timed out while setting country code %ld"),
6977 ret);
Yue Ma4f55ef32014-01-23 16:45:33 -08006978
6979 if (pHddCtx->isLogpInProgress)
6980 {
6981 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
6982 "%s: LOGP in Progress. Ignore!!!", __func__);
6983 return -EAGAIN;
6984 }
Kiet Lam10841362013-11-01 11:36:50 +05306985 }
6986 }
6987 else
6988 {
6989 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Arif Hussain6d2a3322013-11-17 19:50:10 -08006990 "%s: SME Change Country code failed",__func__);
Kiet Lam10841362013-11-01 11:36:50 +05306991 return -EINVAL;
6992 }
6993 }
Jeff Johnson295189b2012-06-20 16:38:30 -07006994 status = hdd_init_ap_mode(pAdapter);
6995 if(status != VOS_STATUS_SUCCESS)
6996 {
6997 hddLog(VOS_TRACE_LEVEL_FATAL,
6998 "%s: Error initializing the ap mode", __func__);
6999 return -EINVAL;
7000 }
7001 hdd_set_conparam(1);
7002
Jeff Johnson295189b2012-06-20 16:38:30 -07007003 /*interface type changed update in wiphy structure*/
7004 if(wdev)
7005 {
7006 wdev->iftype = type;
7007 pHddCtx->change_iface = type;
7008 }
7009 else
7010 {
7011 hddLog(VOS_TRACE_LEVEL_ERROR,
7012 "%s: ERROR !!!! Wireless dev is NULL", __func__);
7013 return -EINVAL;
7014 }
7015 goto done;
7016 }
7017
7018 default:
7019 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Unsupported interface Type",
7020 __func__);
7021 return -EOPNOTSUPP;
7022 }
7023 }
7024 else if ( (pAdapter->device_mode == WLAN_HDD_SOFTAP)
Jeff Johnson295189b2012-06-20 16:38:30 -07007025 || (pAdapter->device_mode == WLAN_HDD_P2P_GO)
Jeff Johnson295189b2012-06-20 16:38:30 -07007026 )
7027 {
7028 switch(type)
7029 {
7030 case NL80211_IFTYPE_STATION:
Jeff Johnson295189b2012-06-20 16:38:30 -07007031 case NL80211_IFTYPE_P2P_CLIENT:
Jeff Johnson295189b2012-06-20 16:38:30 -07007032 case NL80211_IFTYPE_ADHOC:
Deepthi Gowri500fc472014-08-11 19:53:10 +05307033
7034 hdd_stop_adapter( pHddCtx, pAdapter, VOS_TRUE );
Madan Mohan Koyyalamudi96797442013-10-08 16:04:42 +05307035#ifdef FEATURE_WLAN_TDLS
7036
7037 /* A Mutex Lock is introduced while changing the mode to
7038 * protect the concurrent access for the Adapters by TDLS
7039 * module.
7040 */
Rajesh Chauhana34c6e62014-03-25 16:37:58 +05307041 mutex_lock(&pHddCtx->tdls_lock);
Madan Mohan Koyyalamudi96797442013-10-08 16:04:42 +05307042#endif
Jeff Johnson32d95a32012-09-10 13:15:23 -07007043 hdd_deinit_adapter( pHddCtx, pAdapter );
Jeff Johnson295189b2012-06-20 16:38:30 -07007044 wdev->iftype = type;
Gopichand Nakkalaf527dc62012-12-31 16:35:10 -08007045 //Check for sub-string p2p to confirm its a p2p interface
7046 if (NULL != strstr(ndev->name,"p2p"))
Gopichand Nakkala864d3552012-12-31 16:08:51 -08007047 {
7048 pAdapter->device_mode = (type == NL80211_IFTYPE_STATION) ?
7049 WLAN_HDD_P2P_DEVICE : WLAN_HDD_P2P_CLIENT;
7050 }
7051 else
7052 {
7053 pAdapter->device_mode = (type == NL80211_IFTYPE_STATION) ?
Jeff Johnson295189b2012-06-20 16:38:30 -07007054 WLAN_HDD_INFRA_STATION: WLAN_HDD_P2P_CLIENT;
Gopichand Nakkala864d3552012-12-31 16:08:51 -08007055 }
Jeff Johnson295189b2012-06-20 16:38:30 -07007056 hdd_set_conparam(0);
7057 pHddCtx->change_iface = type;
Jeff Johnson295189b2012-06-20 16:38:30 -07007058 memset(&pAdapter->sessionCtx, 0, sizeof(pAdapter->sessionCtx));
7059 hdd_set_station_ops( pAdapter->dev );
Madan Mohan Koyyalamudi96797442013-10-08 16:04:42 +05307060#ifdef FEATURE_WLAN_TDLS
7061 mutex_unlock(&pHddCtx->tdls_lock);
7062#endif
Sunil Dutt66485cb2013-12-19 19:05:03 +05307063 status = hdd_init_station_mode( pAdapter );
Jeff Johnson295189b2012-06-20 16:38:30 -07007064 if( VOS_STATUS_SUCCESS != status )
7065 return -EOPNOTSUPP;
Jeff Johnsone7245742012-09-05 17:12:55 -07007066 /* In case of JB, for P2P-GO, only change interface will be called,
7067 * This is the right place to enable back bmps_imps()
7068 */
Gopichand Nakkalaa2fe5b02013-06-06 16:32:28 +05307069 if (pHddCtx->hdd_wlan_suspended)
7070 {
7071 hdd_set_pwrparams(pHddCtx);
7072 }
Jeff Johnsone7245742012-09-05 17:12:55 -07007073 hdd_enable_bmps_imps(pHddCtx);
Jeff Johnson295189b2012-06-20 16:38:30 -07007074 goto done;
7075 case NL80211_IFTYPE_AP:
Jeff Johnson295189b2012-06-20 16:38:30 -07007076 case NL80211_IFTYPE_P2P_GO:
Jeff Johnson295189b2012-06-20 16:38:30 -07007077 wdev->iftype = type;
Jeff Johnson295189b2012-06-20 16:38:30 -07007078 pAdapter->device_mode = (type == NL80211_IFTYPE_AP) ?
7079 WLAN_HDD_SOFTAP : WLAN_HDD_P2P_GO;
Jeff Johnson295189b2012-06-20 16:38:30 -07007080 goto done;
7081 default:
7082 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Unsupported interface Type",
7083 __func__);
7084 return -EOPNOTSUPP;
7085
7086 }
7087
7088 }
7089 else
7090 {
Sushant Kaushik8bc7df22014-04-09 17:55:29 +05307091 hddLog(VOS_TRACE_LEVEL_ERROR,"%s: unsupported device mode(%s (%d))",
7092 __func__, hdd_device_modetoString(pAdapter->device_mode),
7093 pAdapter->device_mode);
Jeff Johnson295189b2012-06-20 16:38:30 -07007094 return -EOPNOTSUPP;
7095 }
7096
7097
7098 if(pRoamProfile)
7099 {
7100 if ( LastBSSType != pRoamProfile->BSSType )
7101 {
7102 /*interface type changed update in wiphy structure*/
7103 wdev->iftype = type;
7104
7105 /*the BSS mode changed, We need to issue disconnect
7106 if connected or in IBSS disconnect state*/
7107 if ( hdd_connGetConnectedBssType(
7108 WLAN_HDD_GET_STATION_CTX_PTR(pAdapter), &connectedBssType ) ||
7109 ( eCSR_BSS_TYPE_START_IBSS == LastBSSType ) )
7110 {
7111 /*need to issue a disconnect to CSR.*/
7112 INIT_COMPLETION(pAdapter->disconnect_comp_var);
7113 if( eHAL_STATUS_SUCCESS ==
7114 sme_RoamDisconnect( WLAN_HDD_GET_HAL_CTX(pAdapter),
7115 pAdapter->sessionId,
7116 eCSR_DISCONNECT_REASON_UNSPECIFIED ) )
7117 {
c_hpothu6ff1c3c2013-10-01 19:01:57 +05307118 ret = wait_for_completion_interruptible_timeout(
7119 &pAdapter->disconnect_comp_var,
7120 msecs_to_jiffies(WLAN_WAIT_TIME_DISCONNECT));
7121 if (ret <= 0)
7122 {
7123 hddLog(VOS_TRACE_LEVEL_ERROR,
7124 FL("wait on disconnect_comp_var failed %ld"), ret);
7125 }
Jeff Johnson295189b2012-06-20 16:38:30 -07007126 }
7127 }
7128 }
7129 }
7130
7131done:
7132 /*set bitmask based on updated value*/
7133 wlan_hdd_set_concurrency_mode(pHddCtx, pAdapter->device_mode);
Leo Chang6fe1f922013-06-07 19:21:24 -07007134
7135 /* Only STA mode support TM now
7136 * all other mode, TM feature should be disabled */
7137 if ( (pHddCtx->cfg_ini->thermalMitigationEnable) &&
7138 (~VOS_STA & pHddCtx->concurrency_mode) )
7139 {
7140 hddDevTmLevelChangedHandler(pHddCtx->parent_dev, 0);
7141 }
7142
Jeff Johnson295189b2012-06-20 16:38:30 -07007143#ifdef WLAN_BTAMP_FEATURE
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307144 if((NL80211_IFTYPE_STATION == type) && (pHddCtx->concurrency_mode <= 1) &&
Agarwal Ashish51325b52014-06-16 16:50:49 +05307145 (pHddCtx->no_of_open_sessions[WLAN_HDD_INFRA_STATION] <=1))
Jeff Johnson295189b2012-06-20 16:38:30 -07007146 {
7147 //we are ok to do AMP
7148 pHddCtx->isAmpAllowed = VOS_TRUE;
7149 }
7150#endif //WLAN_BTAMP_FEATURE
7151 EXIT();
7152 return 0;
7153}
7154
Mahesh A Saptasagar0e59c472014-04-14 19:17:41 +05307155/*
7156 * FUNCTION: wlan_hdd_cfg80211_change_iface
7157 * wrapper function to protect the actual implementation from SSR.
7158 */
7159int wlan_hdd_cfg80211_change_iface( struct wiphy *wiphy,
7160 struct net_device *ndev,
7161 enum nl80211_iftype type,
7162 u32 *flags,
7163 struct vif_params *params
7164 )
7165{
7166 int ret;
7167
7168 vos_ssr_protect(__func__);
7169 ret = __wlan_hdd_cfg80211_change_iface(wiphy, ndev, type, flags, params);
7170 vos_ssr_unprotect(__func__);
7171
7172 return ret;
7173}
7174
Gopichand Nakkala681989c2013-03-06 22:27:48 -08007175#ifdef FEATURE_WLAN_TDLS
7176static int wlan_hdd_tdls_add_station(struct wiphy *wiphy,
7177 struct net_device *dev, u8 *mac, bool update, tCsrStaParams *StaParams)
7178{
7179 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
7180 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
7181 VOS_STATUS status;
Hoonki Lee5305c3a2013-04-29 23:28:59 -07007182 hddTdlsPeer_t *pTdlsPeer;
c_hpothu6ff1c3c2013-10-01 19:01:57 +05307183 long ret;
Rajesh Chauhana34c6e62014-03-25 16:37:58 +05307184 tANI_U16 numCurrTdlsPeers;
Gopichand Nakkala681989c2013-03-06 22:27:48 -08007185
7186 ENTER();
7187
Gopichand Nakkala838be5d2013-04-10 22:41:51 +05307188 if (NULL == pHddCtx || NULL == pHddCtx->cfg_ini)
Gopichand Nakkala681989c2013-03-06 22:27:48 -08007189 {
7190 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
7191 "Invalid arguments");
7192 return -EINVAL;
7193 }
Hoonki Lee27511902013-03-14 18:19:06 -07007194
7195 if ((eTDLS_SUPPORT_NOT_ENABLED == pHddCtx->tdls_mode) ||
7196 (eTDLS_SUPPORT_DISABLED == pHddCtx->tdls_mode))
7197 {
7198 VOS_TRACE( VOS_MODULE_ID_HDD, TDLS_LOG_LEVEL,
7199 "%s: TDLS mode is disabled OR not enabled in FW."
7200 MAC_ADDRESS_STR " Request declined.",
7201 __func__, MAC_ADDR_ARRAY(mac));
7202 return -ENOTSUPP;
7203 }
7204
Gopichand Nakkala681989c2013-03-06 22:27:48 -08007205 if (pHddCtx->isLogpInProgress)
7206 {
7207 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
7208 "%s:LOGP in Progress. Ignore!!!", __func__);
Atul Mittal115287b2014-07-08 13:26:33 +05307209 wlan_hdd_tdls_set_link_status(pAdapter,
7210 mac,
7211 eTDLS_LINK_IDLE,
7212 eTDLS_LINK_UNSPECIFIED);
Gopichand Nakkala681989c2013-03-06 22:27:48 -08007213 return -EBUSY;
7214 }
7215
Naresh Jayaram9c6f4462014-02-13 12:20:31 +05307216 pTdlsPeer = wlan_hdd_tdls_get_peer(pAdapter, mac);
Hoonki Lee5305c3a2013-04-29 23:28:59 -07007217
7218 if ( NULL == pTdlsPeer ) {
7219 VOS_TRACE( VOS_MODULE_ID_HDD, TDLS_LOG_LEVEL,
7220 "%s: " MAC_ADDRESS_STR " (update %d) not exist. return invalid",
7221 __func__, MAC_ADDR_ARRAY(mac), update);
7222 return -EINVAL;
Gopichand Nakkala34d1b062013-03-19 15:28:33 -07007223 }
Hoonki Lee5305c3a2013-04-29 23:28:59 -07007224
7225 /* in add station, we accept existing valid staId if there is */
7226 if ((0 == update) &&
7227 ((pTdlsPeer->link_status >= eTDLS_LINK_CONNECTING) ||
7228 (TDLS_STA_INDEX_VALID(pTdlsPeer->staId))))
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -07007229 {
Hoonki Lee5305c3a2013-04-29 23:28:59 -07007230 VOS_TRACE( VOS_MODULE_ID_HDD, TDLS_LOG_LEVEL,
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -07007231 "%s: " MAC_ADDRESS_STR
Hoonki Lee5305c3a2013-04-29 23:28:59 -07007232 " link_status %d. staId %d. add station ignored.",
7233 __func__, MAC_ADDR_ARRAY(mac), pTdlsPeer->link_status, pTdlsPeer->staId);
7234 return 0;
7235 }
7236 /* in change station, we accept only when staId is valid */
7237 if ((1 == update) &&
7238 ((pTdlsPeer->link_status > eTDLS_LINK_CONNECTING) ||
7239 (!TDLS_STA_INDEX_VALID(pTdlsPeer->staId))))
7240 {
7241 VOS_TRACE( VOS_MODULE_ID_HDD, TDLS_LOG_LEVEL,
7242 "%s: " MAC_ADDRESS_STR
7243 " link status %d. staId %d. change station %s.",
7244 __func__, MAC_ADDR_ARRAY(mac), pTdlsPeer->link_status, pTdlsPeer->staId,
7245 (TDLS_STA_INDEX_VALID(pTdlsPeer->staId)) ? "ignored" : "declined");
7246 return (TDLS_STA_INDEX_VALID(pTdlsPeer->staId)) ? 0 : -EPERM;
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -07007247 }
Gopichand Nakkala34d1b062013-03-19 15:28:33 -07007248
7249 /* when others are on-going, we want to change link_status to idle */
Madan Mohan Koyyalamudi96797442013-10-08 16:04:42 +05307250 if (NULL != wlan_hdd_tdls_is_progress(pHddCtx, mac, TRUE))
Gopichand Nakkala681989c2013-03-06 22:27:48 -08007251 {
Gopichand Nakkalac87400e2013-03-13 18:51:00 -07007252 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
7253 "%s: " MAC_ADDRESS_STR
7254 " TDLS setup is ongoing. Request declined.",
7255 __func__, MAC_ADDR_ARRAY(mac));
Gopichand Nakkala05922802013-03-14 12:23:19 -07007256 goto error;
Gopichand Nakkala681989c2013-03-06 22:27:48 -08007257 }
7258
7259 /* first to check if we reached to maximum supported TDLS peer.
7260 TODO: for now, return -EPERM looks working fine,
7261 but need to check if any other errno fit into this category.*/
Rajesh Chauhana34c6e62014-03-25 16:37:58 +05307262 numCurrTdlsPeers = wlan_hdd_tdlsConnectedPeers(pAdapter);
7263 if (HDD_MAX_NUM_TDLS_STA <= numCurrTdlsPeers)
Gopichand Nakkala681989c2013-03-06 22:27:48 -08007264 {
Gopichand Nakkalac87400e2013-03-13 18:51:00 -07007265 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
7266 "%s: " MAC_ADDRESS_STR
Rajesh Chauhana34c6e62014-03-25 16:37:58 +05307267 " TDLS Max peer already connected. Request declined."
7268 " Num of peers (%d), Max allowed (%d).",
7269 __func__, MAC_ADDR_ARRAY(mac), numCurrTdlsPeers,
7270 HDD_MAX_NUM_TDLS_STA);
Gopichand Nakkala05922802013-03-14 12:23:19 -07007271 goto error;
Gopichand Nakkala681989c2013-03-06 22:27:48 -08007272 }
7273 else
7274 {
7275 hddTdlsPeer_t *pTdlsPeer;
Madan Mohan Koyyalamudi96797442013-10-08 16:04:42 +05307276 pTdlsPeer = wlan_hdd_tdls_find_peer(pAdapter, mac, TRUE);
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -07007277 if (pTdlsPeer && TDLS_IS_CONNECTED(pTdlsPeer))
Gopichand Nakkala681989c2013-03-06 22:27:48 -08007278 {
Gopichand Nakkalac87400e2013-03-13 18:51:00 -07007279 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
7280 "%s: " MAC_ADDRESS_STR " already connected. Request declined.",
7281 __func__, MAC_ADDR_ARRAY(mac));
Gopichand Nakkala681989c2013-03-06 22:27:48 -08007282 return -EPERM;
7283 }
7284 }
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -07007285 if (0 == update)
Atul Mittal115287b2014-07-08 13:26:33 +05307286 wlan_hdd_tdls_set_link_status(pAdapter,
7287 mac,
7288 eTDLS_LINK_CONNECTING,
7289 eTDLS_LINK_SUCCESS);
Gopichand Nakkala681989c2013-03-06 22:27:48 -08007290
Jeff Johnsond75fe012013-04-06 10:53:06 -07007291 /* debug code */
Gopichand Nakkala838be5d2013-04-10 22:41:51 +05307292 if (NULL != StaParams)
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -07007293 {
7294 VOS_TRACE(VOS_MODULE_ID_HDD, TDLS_LOG_LEVEL,
7295 "%s: TDLS Peer Parameters.", __func__);
Hoonki Lee66b75f32013-04-16 18:30:07 -07007296 if(StaParams->htcap_present)
7297 {
7298 VOS_TRACE(VOS_MODULE_ID_HDD, TDLS_LOG_LEVEL,
7299 "ht_capa->cap_info: %0x", StaParams->HTCap.capInfo);
7300 VOS_TRACE(VOS_MODULE_ID_HDD, TDLS_LOG_LEVEL,
7301 "ht_capa->extended_capabilities: %0x",
7302 StaParams->HTCap.extendedHtCapInfo);
7303 }
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -07007304 VOS_TRACE(VOS_MODULE_ID_HDD, TDLS_LOG_LEVEL,
7305 "params->capability: %0x",StaParams->capability);
7306 VOS_TRACE(VOS_MODULE_ID_HDD, TDLS_LOG_LEVEL,
Jeff Johnson0299d0a2013-10-30 12:37:43 -07007307 "params->ext_capab_len: %0x",StaParams->extn_capability[0]);
Hoonki Lee66b75f32013-04-16 18:30:07 -07007308 if(StaParams->vhtcap_present)
7309 {
7310 VOS_TRACE(VOS_MODULE_ID_HDD, TDLS_LOG_LEVEL,
7311 "rxMcsMap %x rxHighest %x txMcsMap %x txHighest %x",
7312 StaParams->VHTCap.suppMcs.rxMcsMap, StaParams->VHTCap.suppMcs.rxHighest,
7313 StaParams->VHTCap.suppMcs.txMcsMap, StaParams->VHTCap.suppMcs.txHighest);
7314 }
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -07007315 {
7316 int i = 0;
Hoonki Lee5305c3a2013-04-29 23:28:59 -07007317 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO, "Supported rates:");
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -07007318 for (i = 0; i < sizeof(StaParams->supported_rates); i++)
7319 VOS_TRACE(VOS_MODULE_ID_HDD, TDLS_LOG_LEVEL,
7320 "[%d]: %x ", i, StaParams->supported_rates[i]);
7321 }
Jeff Johnsond75fe012013-04-06 10:53:06 -07007322 } /* end debug code */
Gopichand Nakkala838be5d2013-04-10 22:41:51 +05307323 else if ((1 == update) && (NULL == StaParams))
7324 {
7325 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
7326 "%s : update is true, but staParams is NULL. Error!", __func__);
7327 return -EPERM;
7328 }
Gopichand Nakkala681989c2013-03-06 22:27:48 -08007329
7330 INIT_COMPLETION(pAdapter->tdls_add_station_comp);
7331
7332 if (!update)
7333 {
7334 status = sme_AddTdlsPeerSta(WLAN_HDD_GET_HAL_CTX(pAdapter),
7335 pAdapter->sessionId, mac);
7336 }
7337 else
7338 {
7339 status = sme_ChangeTdlsPeerSta(WLAN_HDD_GET_HAL_CTX(pAdapter),
7340 pAdapter->sessionId, mac, StaParams);
7341 }
7342
c_hpothu6ff1c3c2013-10-01 19:01:57 +05307343 ret = wait_for_completion_interruptible_timeout(&pAdapter->tdls_add_station_comp,
Gopichand Nakkala681989c2013-03-06 22:27:48 -08007344 msecs_to_jiffies(WAIT_TIME_TDLS_ADD_STA));
7345
c_hpothu6ff1c3c2013-10-01 19:01:57 +05307346 if (ret <= 0)
Gopichand Nakkala681989c2013-03-06 22:27:48 -08007347 {
Gopichand Nakkalac87400e2013-03-13 18:51:00 -07007348 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
c_hpothu6ff1c3c2013-10-01 19:01:57 +05307349 "%s: timeout waiting for tdls add station indication %ld",
7350 __func__, ret);
Gopichand Nakkala34d1b062013-03-19 15:28:33 -07007351 return -EPERM;
Gopichand Nakkala681989c2013-03-06 22:27:48 -08007352 }
c_hpothu6ff1c3c2013-10-01 19:01:57 +05307353
Gopichand Nakkala681989c2013-03-06 22:27:48 -08007354 if ( eHAL_STATUS_SUCCESS != pAdapter->tdlsAddStaStatus)
7355 {
Gopichand Nakkalac87400e2013-03-13 18:51:00 -07007356 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Gopichand Nakkala681989c2013-03-06 22:27:48 -08007357 "%s: Add Station is unsucessful", __func__);
Gopichand Nakkala34d1b062013-03-19 15:28:33 -07007358 return -EPERM;
Gopichand Nakkala681989c2013-03-06 22:27:48 -08007359 }
7360
7361 return 0;
Gopichand Nakkala05922802013-03-14 12:23:19 -07007362
7363error:
Atul Mittal115287b2014-07-08 13:26:33 +05307364 wlan_hdd_tdls_set_link_status(pAdapter,
7365 mac,
7366 eTDLS_LINK_IDLE,
7367 eTDLS_LINK_UNSPECIFIED);
Gopichand Nakkala05922802013-03-14 12:23:19 -07007368 return -EPERM;
7369
Gopichand Nakkala681989c2013-03-06 22:27:48 -08007370}
7371#endif
7372
Jeff Johnson295189b2012-06-20 16:38:30 -07007373static int wlan_hdd_change_station(struct wiphy *wiphy,
7374 struct net_device *dev,
7375 u8 *mac,
7376 struct station_parameters *params)
7377{
7378 VOS_STATUS status = VOS_STATUS_SUCCESS;
7379 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( dev );
Gopichand Nakkala29149562013-05-10 21:43:41 +05307380 hdd_context_t *pHddCtx;
7381 hdd_station_ctx_t *pHddStaCtx;
Jeff Johnson295189b2012-06-20 16:38:30 -07007382 v_MACADDR_t STAMacAddress;
Gopichand Nakkalab0856222013-03-12 22:39:05 -07007383#ifdef FEATURE_WLAN_TDLS
Gopichand Nakkala681989c2013-03-06 22:27:48 -08007384 tCsrStaParams StaParams = {0};
Gopichand Nakkala681989c2013-03-06 22:27:48 -08007385 tANI_U8 isBufSta = 0;
Naresh Jayaram3180aa42014-02-12 21:47:26 +05307386 tANI_U8 isOffChannelSupported = 0;
Gopichand Nakkalab0856222013-03-12 22:39:05 -07007387#endif
Jeff Johnsone7245742012-09-05 17:12:55 -07007388 ENTER();
7389
Gopichand Nakkala29149562013-05-10 21:43:41 +05307390 if ((NULL == pAdapter))
7391 {
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +05307392 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
Gopichand Nakkala29149562013-05-10 21:43:41 +05307393 "invalid adapter ");
7394 return -EINVAL;
7395 }
7396
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05307397 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
7398 TRACE_CODE_HDD_CHANGE_STATION,
7399 pAdapter->sessionId, params->listen_interval));
Gopichand Nakkala29149562013-05-10 21:43:41 +05307400 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
7401 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
7402
7403 if ((NULL == pHddCtx) || (NULL == pHddStaCtx))
7404 {
7405 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
7406 "invalid HDD state or HDD station context");
7407 return -EINVAL;
7408 }
7409
7410 if (pHddCtx->isLogpInProgress)
Jeff Johnson04dd8a82012-06-29 20:41:40 -07007411 {
7412 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
7413 "%s:LOGP in Progress. Ignore!!!", __func__);
7414 return -EAGAIN;
7415 }
7416
Jeff Johnson295189b2012-06-20 16:38:30 -07007417 vos_mem_copy(STAMacAddress.bytes, mac, sizeof(v_MACADDR_t));
7418
Gopichand Nakkala681989c2013-03-06 22:27:48 -08007419 if ((pAdapter->device_mode == WLAN_HDD_SOFTAP)
7420 || (pAdapter->device_mode == WLAN_HDD_P2P_GO))
Jeff Johnson295189b2012-06-20 16:38:30 -07007421 {
Gopichand Nakkala681989c2013-03-06 22:27:48 -08007422 if (params->sta_flags_set & BIT(NL80211_STA_FLAG_AUTHORIZED))
Jeff Johnson295189b2012-06-20 16:38:30 -07007423 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307424 status = hdd_softap_change_STA_state( pAdapter, &STAMacAddress,
Jeff Johnson295189b2012-06-20 16:38:30 -07007425 WLANTL_STA_AUTHENTICATED);
7426
Gopichand Nakkala29149562013-05-10 21:43:41 +05307427 if (status != VOS_STATUS_SUCCESS)
7428 {
7429 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
7430 "%s: Not able to change TL state to AUTHENTICATED", __func__);
7431 return -EINVAL;
7432 }
Jeff Johnson295189b2012-06-20 16:38:30 -07007433 }
7434 }
Hoonki Leea6d49be2013-04-05 09:43:25 -07007435 else if ((pAdapter->device_mode == WLAN_HDD_INFRA_STATION)
7436 || (pAdapter->device_mode == WLAN_HDD_P2P_CLIENT)) {
Gopichand Nakkala29149562013-05-10 21:43:41 +05307437#ifdef FEATURE_WLAN_TDLS
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -07007438 if (params->sta_flags_set & BIT(NL80211_STA_FLAG_TDLS_PEER)) {
7439 StaParams.capability = params->capability;
7440 StaParams.uapsd_queues = params->uapsd_queues;
7441 StaParams.max_sp = params->max_sp;
7442
Naresh Jayaram3180aa42014-02-12 21:47:26 +05307443 /* Convert (first channel , number of channels) tuple to
7444 * the total list of channels. This goes with the assumption
7445 * that if the first channel is < 14, then the next channels
7446 * are an incremental of 1 else an incremental of 4 till the number
7447 * of channels.
7448 */
7449 if (0 != params->supported_channels_len) {
7450 int i = 0,j = 0,k = 0, no_of_channels = 0 ;
7451 for ( i = 0 ; i < params->supported_channels_len ; i+=2)
7452 {
7453 int wifi_chan_index;
7454 StaParams.supported_channels[j] = params->supported_channels[i];
7455 wifi_chan_index =
7456 ((StaParams.supported_channels[j] <= HDD_CHANNEL_14 ) ? 1 : 4 );
7457 no_of_channels = params->supported_channels[i+1];
7458 for(k=1; k <= no_of_channels; k++)
7459 {
7460 StaParams.supported_channels[j+1] =
7461 StaParams.supported_channels[j] + wifi_chan_index;
7462 j+=1;
7463 }
7464 }
7465 StaParams.supported_channels_len = j;
7466 }
7467 vos_mem_copy(StaParams.supported_oper_classes,
7468 params->supported_oper_classes,
7469 params->supported_oper_classes_len);
7470 StaParams.supported_oper_classes_len =
7471 params->supported_oper_classes_len;
7472
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -07007473 if (0 != params->ext_capab_len)
7474 vos_mem_copy(StaParams.extn_capability, params->ext_capab,
7475 sizeof(StaParams.extn_capability));
7476
7477 if (NULL != params->ht_capa)
Hoonki Lee66b75f32013-04-16 18:30:07 -07007478 {
7479 StaParams.htcap_present = 1;
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -07007480 vos_mem_copy(&StaParams.HTCap, params->ht_capa, sizeof(tSirHTCap));
Hoonki Lee66b75f32013-04-16 18:30:07 -07007481 }
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -07007482
7483 StaParams.supported_rates_len = params->supported_rates_len;
7484
7485 /* Note : The Maximum sizeof supported_rates sent by the Supplicant is 32.
7486 * The supported_rates array , for all the structures propogating till Add Sta
7487 * to the firmware has to be modified , if the supplicant (ieee80211) is
7488 * modified to send more rates.
7489 */
7490
7491 /* To avoid Data Currption , set to max length to SIR_MAC_MAX_SUPP_RATES
7492 */
7493 if (StaParams.supported_rates_len > SIR_MAC_MAX_SUPP_RATES)
7494 StaParams.supported_rates_len = SIR_MAC_MAX_SUPP_RATES;
7495
7496 if (0 != StaParams.supported_rates_len) {
7497 int i = 0;
7498 vos_mem_copy(StaParams.supported_rates, params->supported_rates,
7499 StaParams.supported_rates_len);
Hoonki Lee5305c3a2013-04-29 23:28:59 -07007500 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -07007501 "Supported Rates with Length %d", StaParams.supported_rates_len);
7502 for (i=0; i < StaParams.supported_rates_len; i++)
Hoonki Lee5305c3a2013-04-29 23:28:59 -07007503 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -07007504 "[%d]: %0x", i, StaParams.supported_rates[i]);
7505 }
7506
7507 if (NULL != params->vht_capa)
Hoonki Lee66b75f32013-04-16 18:30:07 -07007508 {
7509 StaParams.vhtcap_present = 1;
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -07007510 vos_mem_copy(&StaParams.VHTCap, params->vht_capa, sizeof(tSirVHTCap));
Hoonki Lee66b75f32013-04-16 18:30:07 -07007511 }
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -07007512
Gopichand Nakkala681989c2013-03-06 22:27:48 -08007513 if (0 != params->ext_capab_len ) {
7514 /*Define A Macro : TODO Sunil*/
7515 if ((1<<4) & StaParams.extn_capability[3]) {
7516 isBufSta = 1;
7517 }
Naresh Jayaram3180aa42014-02-12 21:47:26 +05307518 /* TDLS Channel Switching Support */
7519 if ((1<<6) & StaParams.extn_capability[3]) {
7520 isOffChannelSupported = 1;
7521 }
Gopichand Nakkala681989c2013-03-06 22:27:48 -08007522 }
Naresh Jayaram3180aa42014-02-12 21:47:26 +05307523 status = wlan_hdd_tdls_set_peer_caps( pAdapter, mac,
7524 &StaParams, isBufSta,
7525 isOffChannelSupported);
7526
Gopichand Nakkala79ff85d2013-05-27 17:05:29 +05307527 if (VOS_STATUS_SUCCESS != status) {
7528 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
7529 "%s: wlan_hdd_tdls_set_peer_caps failed!", __func__);
7530 return -EINVAL;
7531 }
Gopichand Nakkala681989c2013-03-06 22:27:48 -08007532 status = wlan_hdd_tdls_add_station(wiphy, dev, mac, 1, &StaParams);
7533
7534 if (VOS_STATUS_SUCCESS != status) {
7535 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
7536 "%s: sme_ChangeTdlsPeerSta failed!", __func__);
7537 return -EINVAL;
7538 }
7539 }
Gopichand Nakkalab0856222013-03-12 22:39:05 -07007540#endif
Gopichand Nakkala6239acd2013-06-14 14:48:00 +05307541 }
Jeff Johnsone7245742012-09-05 17:12:55 -07007542 EXIT();
Jeff Johnson295189b2012-06-20 16:38:30 -07007543 return status;
7544}
7545
7546/*
Mahesh A Saptasagar1a51bc02014-06-02 18:28:08 +05307547 * FUNCTION: __wlan_hdd_cfg80211_add_key
Jeff Johnson295189b2012-06-20 16:38:30 -07007548 * This function is used to initialize the key information
7549 */
7550#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
Mahesh A Saptasagar1a51bc02014-06-02 18:28:08 +05307551static int __wlan_hdd_cfg80211_add_key( struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -07007552 struct net_device *ndev,
7553 u8 key_index, bool pairwise,
7554 const u8 *mac_addr,
7555 struct key_params *params
7556 )
7557#else
Mahesh A Saptasagar1a51bc02014-06-02 18:28:08 +05307558static int __wlan_hdd_cfg80211_add_key( struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -07007559 struct net_device *ndev,
7560 u8 key_index, const u8 *mac_addr,
7561 struct key_params *params
7562 )
7563#endif
7564{
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -07007565 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( ndev );
Jeff Johnson295189b2012-06-20 16:38:30 -07007566 tCsrRoamSetKey setKey;
7567 u8 groupmacaddr[WNI_CFG_BSSID_LEN] = {0xFF,0xFF,0xFF,0xFF,0xFF,0xFF};
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05307568 int status;
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -07007569 v_U32_t roamId= 0xFF;
7570 v_CONTEXT_t pVosContext = (WLAN_HDD_GET_CTX(pAdapter))->pvosContext;
Jeff Johnson295189b2012-06-20 16:38:30 -07007571 hdd_hostapd_state_t *pHostapdState;
7572 VOS_STATUS vos_status;
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -07007573 eHalStatus halStatus;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05307574 hdd_context_t *pHddCtx;
Jeff Johnson295189b2012-06-20 16:38:30 -07007575
7576 ENTER();
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +05307577
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05307578 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
7579 TRACE_CODE_HDD_CFG80211_ADD_KEY,
7580 pAdapter->sessionId, params->key_len));
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05307581 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
7582 status = wlan_hdd_validate_context(pHddCtx);
7583
7584 if (0 != status)
Jeff Johnson04dd8a82012-06-29 20:41:40 -07007585 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05307586 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
7587 "%s: HDD context is not valid", __func__);
7588 return status;
Jeff Johnson04dd8a82012-06-29 20:41:40 -07007589 }
7590
Sushant Kaushik8bc7df22014-04-09 17:55:29 +05307591 hddLog(VOS_TRACE_LEVEL_INFO, "%s: device_mode = %s (%d)",
7592 __func__, hdd_device_modetoString(pAdapter->device_mode),
7593 pAdapter->device_mode);
Jeff Johnson295189b2012-06-20 16:38:30 -07007594
7595 if (CSR_MAX_NUM_KEY <= key_index)
7596 {
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -07007597 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Invalid key index %d", __func__,
Jeff Johnson295189b2012-06-20 16:38:30 -07007598 key_index);
7599
7600 return -EINVAL;
7601 }
7602
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -07007603 if (CSR_MAX_KEY_LEN < params->key_len)
7604 {
7605 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Invalid key length %d", __func__,
7606 params->key_len);
7607
7608 return -EINVAL;
7609 }
7610
7611 hddLog(VOS_TRACE_LEVEL_INFO,
7612 "%s: called with key index = %d & key length %d",
7613 __func__, key_index, params->key_len);
Jeff Johnson295189b2012-06-20 16:38:30 -07007614
7615 /*extract key idx, key len and key*/
7616 vos_mem_zero(&setKey,sizeof(tCsrRoamSetKey));
7617 setKey.keyId = key_index;
7618 setKey.keyLength = params->key_len;
7619 vos_mem_copy(&setKey.Key[0],params->key, params->key_len);
7620
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -07007621 switch (params->cipher)
Jeff Johnson295189b2012-06-20 16:38:30 -07007622 {
7623 case WLAN_CIPHER_SUITE_WEP40:
7624 setKey.encType = eCSR_ENCRYPT_TYPE_WEP40_STATICKEY;
7625 break;
7626
7627 case WLAN_CIPHER_SUITE_WEP104:
7628 setKey.encType = eCSR_ENCRYPT_TYPE_WEP104_STATICKEY;
7629 break;
7630
7631 case WLAN_CIPHER_SUITE_TKIP:
7632 {
7633 u8 *pKey = &setKey.Key[0];
7634 setKey.encType = eCSR_ENCRYPT_TYPE_TKIP;
7635
7636 vos_mem_zero(pKey, CSR_MAX_KEY_LEN);
7637
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -07007638 /*Supplicant sends the 32bytes key in this order
Jeff Johnson295189b2012-06-20 16:38:30 -07007639
7640 |--------------|----------|----------|
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -07007641 | Tk1 |TX-MIC | RX Mic |
Jeff Johnson295189b2012-06-20 16:38:30 -07007642 |--------------|----------|----------|
7643 <---16bytes---><--8bytes--><--8bytes-->
7644
7645 */
7646 /*Sme expects the 32 bytes key to be in the below order
7647
7648 |--------------|----------|----------|
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -07007649 | Tk1 |RX-MIC | TX Mic |
Jeff Johnson295189b2012-06-20 16:38:30 -07007650 |--------------|----------|----------|
7651 <---16bytes---><--8bytes--><--8bytes-->
7652 */
7653 /* Copy the Temporal Key 1 (TK1) */
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -07007654 vos_mem_copy(pKey, params->key, 16);
Jeff Johnson295189b2012-06-20 16:38:30 -07007655
7656 /*Copy the rx mic first*/
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -07007657 vos_mem_copy(&pKey[16], &params->key[24], 8);
Jeff Johnson295189b2012-06-20 16:38:30 -07007658
7659 /*Copy the tx mic */
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -07007660 vos_mem_copy(&pKey[24], &params->key[16], 8);
Jeff Johnson295189b2012-06-20 16:38:30 -07007661
7662
7663 break;
7664 }
7665
7666 case WLAN_CIPHER_SUITE_CCMP:
7667 setKey.encType = eCSR_ENCRYPT_TYPE_AES;
7668 break;
7669
7670#ifdef FEATURE_WLAN_WAPI
7671 case WLAN_CIPHER_SUITE_SMS4:
7672 {
7673 vos_mem_zero(&setKey,sizeof(tCsrRoamSetKey));
7674 wlan_hdd_cfg80211_set_key_wapi(pAdapter, key_index, mac_addr,
7675 params->key, params->key_len);
7676 return 0;
7677 }
7678#endif
Chet Lanctot186b5732013-03-18 10:26:30 -07007679
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08007680#ifdef FEATURE_WLAN_ESE
Jeff Johnson295189b2012-06-20 16:38:30 -07007681 case WLAN_CIPHER_SUITE_KRK:
7682 setKey.encType = eCSR_ENCRYPT_TYPE_KRK;
7683 break;
7684#endif
Chet Lanctot186b5732013-03-18 10:26:30 -07007685
7686#ifdef WLAN_FEATURE_11W
7687 case WLAN_CIPHER_SUITE_AES_CMAC:
7688 setKey.encType = eCSR_ENCRYPT_TYPE_AES_CMAC;
Chet Lanctot3b5158a2013-03-31 16:45:21 -07007689 break;
Chet Lanctot186b5732013-03-18 10:26:30 -07007690#endif
7691
Jeff Johnson295189b2012-06-20 16:38:30 -07007692 default:
Jeff Johnson0299d0a2013-10-30 12:37:43 -07007693 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: unsupported cipher type %u",
Jeff Johnson295189b2012-06-20 16:38:30 -07007694 __func__, params->cipher);
7695 return -EOPNOTSUPP;
7696 }
7697
7698 hddLog(VOS_TRACE_LEVEL_INFO_MED, "%s: encryption type %d",
7699 __func__, setKey.encType);
7700
Shailender Karmuchi642e9812013-05-30 14:34:49 -07007701 if (
Jeff Johnson295189b2012-06-20 16:38:30 -07007702#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
7703 (!pairwise)
7704#else
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -07007705 (!mac_addr || is_broadcast_ether_addr(mac_addr))
Jeff Johnson295189b2012-06-20 16:38:30 -07007706#endif
Shailender Karmuchi642e9812013-05-30 14:34:49 -07007707 )
7708 {
7709 /* set group key*/
7710 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
7711 "%s- %d: setting Broadcast key",
7712 __func__, __LINE__);
7713 setKey.keyDirection = eSIR_RX_ONLY;
7714 vos_mem_copy(setKey.peerMac,groupmacaddr,WNI_CFG_BSSID_LEN);
7715 }
7716 else
7717 {
7718 /* set pairwise key*/
7719 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
7720 "%s- %d: setting pairwise key",
7721 __func__, __LINE__);
7722 setKey.keyDirection = eSIR_TX_RX;
7723 vos_mem_copy(setKey.peerMac, mac_addr,WNI_CFG_BSSID_LEN);
7724 }
7725 if ((WLAN_HDD_IBSS == pAdapter->device_mode) && !pairwise)
7726 {
7727 setKey.keyDirection = eSIR_TX_RX;
7728 /*Set the group key*/
7729 status = sme_RoamSetKey( WLAN_HDD_GET_HAL_CTX(pAdapter),
7730 pAdapter->sessionId, &setKey, &roamId );
Jeff Johnson295189b2012-06-20 16:38:30 -07007731
Shailender Karmuchi642e9812013-05-30 14:34:49 -07007732 if ( 0 != status )
7733 {
7734 hddLog(VOS_TRACE_LEVEL_ERROR,
7735 "%s: sme_RoamSetKey failed, returned %d", __func__, status);
7736 return -EINVAL;
7737 }
7738 /*Save the keys here and call sme_RoamSetKey for setting
7739 the PTK after peer joins the IBSS network*/
7740 vos_mem_copy(&pAdapter->sessionCtx.station.ibss_enc_key,
7741 &setKey, sizeof(tCsrRoamSetKey));
7742 return status;
7743 }
Gopichand Nakkala29149562013-05-10 21:43:41 +05307744 if ((pAdapter->device_mode == WLAN_HDD_SOFTAP) ||
7745 (pAdapter->device_mode == WLAN_HDD_P2P_GO))
7746 {
Jeff Johnson295189b2012-06-20 16:38:30 -07007747 pHostapdState = WLAN_HDD_GET_HOSTAP_STATE_PTR(pAdapter);
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -07007748 if( pHostapdState->bssState == BSS_START )
7749 {
c_hpothu7c55da62014-01-23 18:34:02 +05307750 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
7751 vos_status = wlan_hdd_check_ula_done(pAdapter);
7752
7753 if ( vos_status != VOS_STATUS_SUCCESS )
7754 {
7755 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
7756 "[%4d] wlan_hdd_check_ula_done returned ERROR status= %d",
7757 __LINE__, vos_status );
7758
7759 pHddStaCtx->roam_info.roamingState = HDD_ROAM_STATE_NONE;
7760
7761 return -EINVAL;
7762 }
7763
Jeff Johnson295189b2012-06-20 16:38:30 -07007764 status = WLANSAP_SetKeySta( pVosContext, &setKey);
7765
7766 if ( status != eHAL_STATUS_SUCCESS )
7767 {
7768 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
7769 "[%4d] WLANSAP_SetKeySta returned ERROR status= %d",
7770 __LINE__, status );
7771 }
7772 }
7773
7774 /* Saving WEP keys */
7775 else if( eCSR_ENCRYPT_TYPE_WEP40_STATICKEY == setKey.encType ||
7776 eCSR_ENCRYPT_TYPE_WEP104_STATICKEY == setKey.encType )
7777 {
7778 //Save the wep key in ap context. Issue setkey after the BSS is started.
7779 hdd_ap_ctx_t *pAPCtx = WLAN_HDD_GET_AP_CTX_PTR(pAdapter);
7780 vos_mem_copy(&pAPCtx->wepKey[key_index], &setKey, sizeof(tCsrRoamSetKey));
7781 }
7782 else
7783 {
7784 //Save the key in ap context. Issue setkey after the BSS is started.
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -07007785 hdd_ap_ctx_t *pAPCtx = WLAN_HDD_GET_AP_CTX_PTR(pAdapter);
Jeff Johnson295189b2012-06-20 16:38:30 -07007786 vos_mem_copy(&pAPCtx->groupKey, &setKey, sizeof(tCsrRoamSetKey));
7787 }
7788 }
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -07007789 else if ( (pAdapter->device_mode == WLAN_HDD_INFRA_STATION) ||
7790 (pAdapter->device_mode == WLAN_HDD_P2P_CLIENT) )
Jeff Johnson295189b2012-06-20 16:38:30 -07007791 {
7792 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
7793 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
7794
Gopichand Nakkala3d295922013-05-07 16:19:14 +05307795#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
7796 if (!pairwise)
7797#else
7798 if (!mac_addr || is_broadcast_ether_addr(mac_addr))
7799#endif
7800 {
7801 /* set group key*/
7802 if (pHddStaCtx->roam_info.deferKeyComplete)
7803 {
7804 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
7805 "%s- %d: Perform Set key Complete",
7806 __func__, __LINE__);
7807 hdd_PerformRoamSetKeyComplete(pAdapter);
7808 }
7809 }
7810
Jeff Johnson295189b2012-06-20 16:38:30 -07007811 pWextState->roamProfile.Keys.KeyLength[key_index] = (u8)params->key_len;
7812
Venkata Prathyusha Kuntupalliee2ce712013-01-17 14:09:24 -08007813 pWextState->roamProfile.Keys.defaultIndex = key_index;
7814
7815
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -07007816 vos_mem_copy(&pWextState->roamProfile.Keys.KeyMaterial[key_index][0],
Jeff Johnson295189b2012-06-20 16:38:30 -07007817 params->key, params->key_len);
7818
Gopichand Nakkala3d295922013-05-07 16:19:14 +05307819
Jeff Johnson295189b2012-06-20 16:38:30 -07007820 pHddStaCtx->roam_info.roamingState = HDD_ROAM_STATE_SETTING_KEY;
7821
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307822 hddLog(VOS_TRACE_LEVEL_INFO_MED,
Jeff Johnson295189b2012-06-20 16:38:30 -07007823 "%s: set key for peerMac %2x:%2x:%2x:%2x:%2x:%2x, direction %d",
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307824 __func__, setKey.peerMac[0], setKey.peerMac[1],
7825 setKey.peerMac[2], setKey.peerMac[3],
7826 setKey.peerMac[4], setKey.peerMac[5],
Jeff Johnson295189b2012-06-20 16:38:30 -07007827 setKey.keyDirection);
7828
7829 vos_status = wlan_hdd_check_ula_done(pAdapter);
7830
7831 if ( vos_status != VOS_STATUS_SUCCESS )
7832 {
7833 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
7834 "[%4d] wlan_hdd_check_ula_done returned ERROR status= %d",
7835 __LINE__, vos_status );
7836
7837 pHddStaCtx->roam_info.roamingState = HDD_ROAM_STATE_NONE;
7838
7839 return -EINVAL;
7840
7841 }
7842
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -07007843#ifdef WLAN_FEATURE_VOWIFI_11R
Gopichand Nakkala3d295922013-05-07 16:19:14 +05307844 /* The supplicant may attempt to set the PTK once pre-authentication
7845 is done. Save the key in the UMAC and include it in the ADD BSS
7846 request */
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -07007847 halStatus = sme_FTUpdateKey( WLAN_HDD_GET_HAL_CTX(pAdapter), &setKey);
Gopichand Nakkala3d295922013-05-07 16:19:14 +05307848 if ( halStatus == eHAL_STATUS_FT_PREAUTH_KEY_SUCCESS )
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -07007849 {
Gopichand Nakkala3d295922013-05-07 16:19:14 +05307850 hddLog(VOS_TRACE_LEVEL_INFO_MED,
7851 "%s: Update PreAuth Key success", __func__);
7852 return 0;
7853 }
7854 else if ( halStatus == eHAL_STATUS_FT_PREAUTH_KEY_FAILED )
7855 {
7856 hddLog(VOS_TRACE_LEVEL_ERROR,
7857 "%s: Update PreAuth Key failed", __func__);
Gopichand Nakkalad7d13652013-02-15 01:48:00 +05307858 return -EINVAL;
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -07007859 }
7860#endif /* WLAN_FEATURE_VOWIFI_11R */
Jeff Johnson295189b2012-06-20 16:38:30 -07007861
7862 /* issue set key request to SME*/
7863 status = sme_RoamSetKey( WLAN_HDD_GET_HAL_CTX(pAdapter),
7864 pAdapter->sessionId, &setKey, &roamId );
7865
7866 if ( 0 != status )
7867 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307868 hddLog(VOS_TRACE_LEVEL_ERROR,
Jeff Johnson295189b2012-06-20 16:38:30 -07007869 "%s: sme_RoamSetKey failed, returned %d", __func__, status);
7870 pHddStaCtx->roam_info.roamingState = HDD_ROAM_STATE_NONE;
7871 return -EINVAL;
7872 }
7873
7874
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307875 /* in case of IBSS as there was no information available about WEP keys during
7876 * IBSS join, group key intialized with NULL key, so re-initialize group key
Jeff Johnson295189b2012-06-20 16:38:30 -07007877 * with correct value*/
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307878 if ( (eCSR_BSS_TYPE_START_IBSS == pWextState->roamProfile.BSSType) &&
7879 !( ( IW_AUTH_KEY_MGMT_802_1X
7880 == (pWextState->authKeyMgmt & IW_AUTH_KEY_MGMT_802_1X))
Jeff Johnson295189b2012-06-20 16:38:30 -07007881 && (eCSR_AUTH_TYPE_OPEN_SYSTEM == pHddStaCtx->conn_info.authType)
7882 )
7883 &&
7884 ( (WLAN_CIPHER_SUITE_WEP40 == params->cipher)
7885 || (WLAN_CIPHER_SUITE_WEP104 == params->cipher)
7886 )
7887 )
7888 {
7889 setKey.keyDirection = eSIR_RX_ONLY;
7890 vos_mem_copy(setKey.peerMac,groupmacaddr,WNI_CFG_BSSID_LEN);
7891
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307892 hddLog(VOS_TRACE_LEVEL_INFO_MED,
Jeff Johnson295189b2012-06-20 16:38:30 -07007893 "%s: set key peerMac %2x:%2x:%2x:%2x:%2x:%2x, direction %d",
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307894 __func__, setKey.peerMac[0], setKey.peerMac[1],
7895 setKey.peerMac[2], setKey.peerMac[3],
7896 setKey.peerMac[4], setKey.peerMac[5],
Jeff Johnson295189b2012-06-20 16:38:30 -07007897 setKey.keyDirection);
7898
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307899 status = sme_RoamSetKey( WLAN_HDD_GET_HAL_CTX(pAdapter),
Jeff Johnson295189b2012-06-20 16:38:30 -07007900 pAdapter->sessionId, &setKey, &roamId );
7901
7902 if ( 0 != status )
7903 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307904 hddLog(VOS_TRACE_LEVEL_ERROR,
7905 "%s: sme_RoamSetKey failed for group key (IBSS), returned %d",
Jeff Johnson295189b2012-06-20 16:38:30 -07007906 __func__, status);
7907 pHddStaCtx->roam_info.roamingState = HDD_ROAM_STATE_NONE;
7908 return -EINVAL;
7909 }
7910 }
7911 }
7912
7913 return 0;
7914}
7915
Mahesh A Saptasagar1a51bc02014-06-02 18:28:08 +05307916#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
7917static int wlan_hdd_cfg80211_add_key( struct wiphy *wiphy,
7918 struct net_device *ndev,
7919 u8 key_index, bool pairwise,
7920 const u8 *mac_addr,
7921 struct key_params *params
7922 )
7923#else
7924static int wlan_hdd_cfg80211_add_key( struct wiphy *wiphy,
7925 struct net_device *ndev,
7926 u8 key_index, const u8 *mac_addr,
7927 struct key_params *params
7928 )
7929#endif
7930{
7931 int ret;
7932 vos_ssr_protect(__func__);
7933#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
7934 ret = __wlan_hdd_cfg80211_add_key(wiphy, ndev, key_index, pairwise,
7935 mac_addr, params);
7936#else
7937 ret = __wlan_hdd_cfg80211_add_key(wiphy, ndev, key_index, mac_addr,
7938 params);
7939#endif
7940 vos_ssr_unprotect(__func__);
7941
7942 return ret;
7943}
7944
Jeff Johnson295189b2012-06-20 16:38:30 -07007945/*
Mahesh A Saptasagar1a51bc02014-06-02 18:28:08 +05307946 * FUNCTION: __wlan_hdd_cfg80211_get_key
Jeff Johnson295189b2012-06-20 16:38:30 -07007947 * This function is used to get the key information
7948 */
7949#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
Mahesh A Saptasagar1a51bc02014-06-02 18:28:08 +05307950static int __wlan_hdd_cfg80211_get_key(
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307951 struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -07007952 struct net_device *ndev,
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307953 u8 key_index, bool pairwise,
Jeff Johnson295189b2012-06-20 16:38:30 -07007954 const u8 *mac_addr, void *cookie,
7955 void (*callback)(void *cookie, struct key_params*)
7956 )
7957#else
Mahesh A Saptasagar1a51bc02014-06-02 18:28:08 +05307958static int __wlan_hdd_cfg80211_get_key(
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307959 struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -07007960 struct net_device *ndev,
7961 u8 key_index, const u8 *mac_addr, void *cookie,
7962 void (*callback)(void *cookie, struct key_params*)
7963 )
7964#endif
7965{
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307966 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( ndev );
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +05307967 hdd_wext_state_t *pWextState= WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
7968 tCsrRoamProfile *pRoamProfile = &(pWextState->roamProfile);
Jeff Johnson295189b2012-06-20 16:38:30 -07007969 struct key_params params;
7970
7971 ENTER();
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307972
Sushant Kaushik8bc7df22014-04-09 17:55:29 +05307973 hddLog(VOS_TRACE_LEVEL_INFO, "%s: device_mode = %s (%d)",
7974 __func__, hdd_device_modetoString(pAdapter->device_mode),
7975 pAdapter->device_mode);
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +05307976
Jeff Johnson295189b2012-06-20 16:38:30 -07007977 memset(&params, 0, sizeof(params));
7978
7979 if (CSR_MAX_NUM_KEY <= key_index)
7980 {
c_hpothu6ff1c3c2013-10-01 19:01:57 +05307981 hddLog(VOS_TRACE_LEVEL_ERROR, FL("invalid key index %d"), key_index);
Jeff Johnson295189b2012-06-20 16:38:30 -07007982 return -EINVAL;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307983 }
Jeff Johnson295189b2012-06-20 16:38:30 -07007984
7985 switch(pRoamProfile->EncryptionType.encryptionType[0])
7986 {
7987 case eCSR_ENCRYPT_TYPE_NONE:
7988 params.cipher = IW_AUTH_CIPHER_NONE;
7989 break;
7990
7991 case eCSR_ENCRYPT_TYPE_WEP40_STATICKEY:
7992 case eCSR_ENCRYPT_TYPE_WEP40:
7993 params.cipher = WLAN_CIPHER_SUITE_WEP40;
7994 break;
7995
7996 case eCSR_ENCRYPT_TYPE_WEP104_STATICKEY:
7997 case eCSR_ENCRYPT_TYPE_WEP104:
7998 params.cipher = WLAN_CIPHER_SUITE_WEP104;
7999 break;
8000
8001 case eCSR_ENCRYPT_TYPE_TKIP:
8002 params.cipher = WLAN_CIPHER_SUITE_TKIP;
8003 break;
8004
8005 case eCSR_ENCRYPT_TYPE_AES:
8006 params.cipher = WLAN_CIPHER_SUITE_AES_CMAC;
8007 break;
8008
8009 default:
8010 params.cipher = IW_AUTH_CIPHER_NONE;
8011 break;
8012 }
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +05308013
c_hpothuaaf19692014-05-17 17:01:48 +05308014 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
8015 TRACE_CODE_HDD_CFG80211_GET_KEY,
8016 pAdapter->sessionId, params.cipher));
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +05308017
Jeff Johnson295189b2012-06-20 16:38:30 -07008018 params.key_len = pRoamProfile->Keys.KeyLength[key_index];
8019 params.seq_len = 0;
8020 params.seq = NULL;
8021 params.key = &pRoamProfile->Keys.KeyMaterial[key_index][0];
8022 callback(cookie, &params);
8023 return 0;
8024}
8025
Mahesh A Saptasagar1a51bc02014-06-02 18:28:08 +05308026#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
8027static int wlan_hdd_cfg80211_get_key(
8028 struct wiphy *wiphy,
8029 struct net_device *ndev,
8030 u8 key_index, bool pairwise,
8031 const u8 *mac_addr, void *cookie,
8032 void (*callback)(void *cookie, struct key_params*)
8033 )
8034#else
8035static int wlan_hdd_cfg80211_get_key(
8036 struct wiphy *wiphy,
8037 struct net_device *ndev,
8038 u8 key_index, const u8 *mac_addr, void *cookie,
8039 void (*callback)(void *cookie, struct key_params*)
8040 )
8041#endif
8042{
8043 int ret;
8044
8045 vos_ssr_protect(__func__);
8046#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
8047 ret = __wlan_hdd_cfg80211_get_key(wiphy, ndev, key_index, pairwise,
8048 mac_addr, cookie, callback);
8049#else
8050 ret = __wlan_hdd_cfg80211_get_key(wiphy, ndev, key_index, mac_addr,
8051 callback);
8052#endif
8053 vos_ssr_unprotect(__func__);
8054
8055 return ret;
8056}
8057
Jeff Johnson295189b2012-06-20 16:38:30 -07008058/*
8059 * FUNCTION: wlan_hdd_cfg80211_del_key
8060 * This function is used to delete the key information
8061 */
8062#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308063static int wlan_hdd_cfg80211_del_key( struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -07008064 struct net_device *ndev,
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308065 u8 key_index,
8066 bool pairwise,
Jeff Johnson295189b2012-06-20 16:38:30 -07008067 const u8 *mac_addr
8068 )
8069#else
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308070static int wlan_hdd_cfg80211_del_key( struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -07008071 struct net_device *ndev,
8072 u8 key_index,
8073 const u8 *mac_addr
8074 )
8075#endif
8076{
8077 int status = 0;
8078
8079 //This code needs to be revisited. There is sme_removeKey API, we should
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308080 //plan to use that. After the change to use correct index in setkey,
Jeff Johnson295189b2012-06-20 16:38:30 -07008081 //it is observed that this is invalidating peer
8082 //key index whenever re-key is done. This is affecting data link.
8083 //It should be ok to ignore del_key.
8084#if 0
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308085 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( ndev );
8086 v_CONTEXT_t pVosContext = (WLAN_HDD_GET_CTX(pAdapter))->pvosContext;
Jeff Johnson295189b2012-06-20 16:38:30 -07008087 u8 groupmacaddr[WNI_CFG_BSSID_LEN] = {0xFF,0xFF,0xFF,0xFF,0xFF,0xFF};
8088 tCsrRoamSetKey setKey;
8089 v_U32_t roamId= 0xFF;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308090
Jeff Johnson295189b2012-06-20 16:38:30 -07008091 ENTER();
8092
8093 hddLog(VOS_TRACE_LEVEL_INFO_HIGH, "%s: device_mode = %d\n",
8094 __func__,pAdapter->device_mode);
8095
8096 if (CSR_MAX_NUM_KEY <= key_index)
8097 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308098 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Invalid key index %d", __func__,
Jeff Johnson295189b2012-06-20 16:38:30 -07008099 key_index);
8100
8101 return -EINVAL;
8102 }
8103
8104 vos_mem_zero(&setKey,sizeof(tCsrRoamSetKey));
8105 setKey.keyId = key_index;
8106
8107 if (mac_addr)
8108 vos_mem_copy(setKey.peerMac, mac_addr,WNI_CFG_BSSID_LEN);
8109 else
8110 vos_mem_copy(setKey.peerMac, groupmacaddr, WNI_CFG_BSSID_LEN);
8111
8112 setKey.encType = eCSR_ENCRYPT_TYPE_NONE;
8113
8114 if ((pAdapter->device_mode == WLAN_HDD_SOFTAP)
Jeff Johnson295189b2012-06-20 16:38:30 -07008115 || (pAdapter->device_mode == WLAN_HDD_P2P_GO)
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308116 )
8117 {
8118
8119 hdd_hostapd_state_t *pHostapdState =
Jeff Johnson295189b2012-06-20 16:38:30 -07008120 WLAN_HDD_GET_HOSTAP_STATE_PTR(pAdapter);
8121 if( pHostapdState->bssState == BSS_START)
8122 {
8123 status = WLANSAP_SetKeySta( pVosContext, &setKey);
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308124
Jeff Johnson295189b2012-06-20 16:38:30 -07008125 if ( status != eHAL_STATUS_SUCCESS )
8126 {
8127 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
8128 "[%4d] WLANSAP_SetKeySta returned ERROR status= %d",
8129 __LINE__, status );
8130 }
8131 }
8132 }
8133 else if ( (pAdapter->device_mode == WLAN_HDD_INFRA_STATION)
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308134 || (pAdapter->device_mode == WLAN_HDD_P2P_CLIENT)
Jeff Johnson295189b2012-06-20 16:38:30 -07008135 )
8136 {
8137 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
8138
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308139 pHddStaCtx->roam_info.roamingState = HDD_ROAM_STATE_SETTING_KEY;
8140
8141 hddLog(VOS_TRACE_LEVEL_INFO_MED,
Jeff Johnson295189b2012-06-20 16:38:30 -07008142 "%s: delete key for peerMac %2x:%2x:%2x:%2x:%2x:%2x",
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308143 __func__, setKey.peerMac[0], setKey.peerMac[1],
8144 setKey.peerMac[2], setKey.peerMac[3],
Jeff Johnson295189b2012-06-20 16:38:30 -07008145 setKey.peerMac[4], setKey.peerMac[5]);
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308146 if(pAdapter->sessionCtx.station.conn_info.connState ==
8147 eConnectionState_Associated)
Jeff Johnson295189b2012-06-20 16:38:30 -07008148 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308149 status = sme_RoamSetKey( WLAN_HDD_GET_HAL_CTX(pAdapter),
Jeff Johnson295189b2012-06-20 16:38:30 -07008150 pAdapter->sessionId, &setKey, &roamId );
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308151
Jeff Johnson295189b2012-06-20 16:38:30 -07008152 if ( 0 != status )
8153 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308154 hddLog(VOS_TRACE_LEVEL_ERROR,
Jeff Johnson295189b2012-06-20 16:38:30 -07008155 "%s: sme_RoamSetKey failure, returned %d",
8156 __func__, status);
8157 pHddStaCtx->roam_info.roamingState = HDD_ROAM_STATE_NONE;
8158 return -EINVAL;
8159 }
8160 }
8161 }
8162#endif
Jeff Johnsone7245742012-09-05 17:12:55 -07008163 EXIT();
Jeff Johnson295189b2012-06-20 16:38:30 -07008164 return status;
8165}
8166
8167/*
Mahesh A Saptasagar1a51bc02014-06-02 18:28:08 +05308168 * FUNCTION: __wlan_hdd_cfg80211_set_default_key
Jeff Johnson295189b2012-06-20 16:38:30 -07008169 * This function is used to set the default tx key index
8170 */
8171#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
Mahesh A Saptasagar1a51bc02014-06-02 18:28:08 +05308172static int __wlan_hdd_cfg80211_set_default_key( struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -07008173 struct net_device *ndev,
8174 u8 key_index,
8175 bool unicast, bool multicast)
8176#else
Mahesh A Saptasagar1a51bc02014-06-02 18:28:08 +05308177static int __wlan_hdd_cfg80211_set_default_key( struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -07008178 struct net_device *ndev,
8179 u8 key_index)
8180#endif
8181{
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308182 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( ndev );
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05308183 int status;
Gopichand Nakkala29149562013-05-10 21:43:41 +05308184 hdd_wext_state_t *pWextState;
8185 hdd_station_ctx_t *pHddStaCtx;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05308186 hdd_context_t *pHddCtx;
Jeff Johnson295189b2012-06-20 16:38:30 -07008187
8188 ENTER();
8189
Gopichand Nakkala29149562013-05-10 21:43:41 +05308190 if ((NULL == pAdapter))
8191 {
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +05308192 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
Gopichand Nakkala29149562013-05-10 21:43:41 +05308193 "invalid adapter");
8194 return -EINVAL;
8195 }
8196
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05308197 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
8198 TRACE_CODE_HDD_CFG80211_SET_DEFAULT_KEY,
8199 pAdapter->sessionId, key_index));
8200
Gopichand Nakkala29149562013-05-10 21:43:41 +05308201 pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
8202 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
8203
8204 if ((NULL == pWextState) || (NULL == pHddStaCtx))
8205 {
8206 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
8207 "invalid Wext state or HDD context");
8208 return -EINVAL;
8209 }
8210
Arif Hussain6d2a3322013-11-17 19:50:10 -08008211 hddLog(VOS_TRACE_LEVEL_INFO, "%s: device_mode = %d key_index = %d",
Jeff Johnson295189b2012-06-20 16:38:30 -07008212 __func__,pAdapter->device_mode, key_index);
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308213
Jeff Johnson295189b2012-06-20 16:38:30 -07008214 if (CSR_MAX_NUM_KEY <= key_index)
8215 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308216 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Invalid key index %d", __func__,
Jeff Johnson295189b2012-06-20 16:38:30 -07008217 key_index);
8218
8219 return -EINVAL;
8220 }
8221
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05308222 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
8223 status = wlan_hdd_validate_context(pHddCtx);
8224
8225 if (0 != status)
Jeff Johnson04dd8a82012-06-29 20:41:40 -07008226 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05308227 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
8228 "%s: HDD context is not valid", __func__);
8229 return status;
Jeff Johnson04dd8a82012-06-29 20:41:40 -07008230 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308231
Jeff Johnson295189b2012-06-20 16:38:30 -07008232 if ((pAdapter->device_mode == WLAN_HDD_INFRA_STATION)
Jeff Johnson295189b2012-06-20 16:38:30 -07008233 || (pAdapter->device_mode == WLAN_HDD_P2P_CLIENT)
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308234 )
Jeff Johnson295189b2012-06-20 16:38:30 -07008235 {
Gopichand Nakkala29149562013-05-10 21:43:41 +05308236 if ( (eCSR_ENCRYPT_TYPE_TKIP !=
Arif Hussain6943f522013-11-04 20:10:10 -08008237 pHddStaCtx->conn_info.ucEncryptionType) &&
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308238 (eCSR_ENCRYPT_TYPE_AES !=
Arif Hussain6943f522013-11-04 20:10:10 -08008239 pHddStaCtx->conn_info.ucEncryptionType)
Jeff Johnson295189b2012-06-20 16:38:30 -07008240 )
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308241 {
8242 /* if default key index is not same as previous one,
Jeff Johnson295189b2012-06-20 16:38:30 -07008243 * then update the default key index */
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308244
Jeff Johnson295189b2012-06-20 16:38:30 -07008245 tCsrRoamSetKey setKey;
8246 v_U32_t roamId= 0xFF;
8247 tCsrKeys *Keys = &pWextState->roamProfile.Keys;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308248
8249 hddLog(VOS_TRACE_LEVEL_INFO_HIGH, "%s: default tx key index %d",
Jeff Johnson295189b2012-06-20 16:38:30 -07008250 __func__, key_index);
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308251
Jeff Johnson295189b2012-06-20 16:38:30 -07008252 Keys->defaultIndex = (u8)key_index;
8253 vos_mem_zero(&setKey,sizeof(tCsrRoamSetKey));
8254 setKey.keyId = key_index;
8255 setKey.keyLength = Keys->KeyLength[key_index];
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308256
8257 vos_mem_copy(&setKey.Key[0],
8258 &Keys->KeyMaterial[key_index][0],
Jeff Johnson295189b2012-06-20 16:38:30 -07008259 Keys->KeyLength[key_index]);
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308260
Gopichand Nakkala29149562013-05-10 21:43:41 +05308261 setKey.keyDirection = eSIR_TX_RX;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308262
8263 vos_mem_copy(setKey.peerMac,
Jeff Johnson295189b2012-06-20 16:38:30 -07008264 &pHddStaCtx->conn_info.bssId[0],
8265 WNI_CFG_BSSID_LEN);
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308266
Gopichand Nakkala29149562013-05-10 21:43:41 +05308267 if (Keys->KeyLength[key_index] == CSR_WEP40_KEY_LEN &&
8268 pWextState->roamProfile.EncryptionType.encryptionType[0] ==
8269 eCSR_ENCRYPT_TYPE_WEP104)
8270 {
8271 /*In the case of dynamic wep supplicant hardcodes DWEP type to eCSR_ENCRYPT_TYPE_WEP104
8272 even though ap is configured for WEP-40 encryption. In this canse the key length
8273 is 5 but the encryption type is 104 hence checking the key langht(5) and encryption
8274 type(104) and switching encryption type to 40*/
8275 pWextState->roamProfile.EncryptionType.encryptionType[0] =
8276 eCSR_ENCRYPT_TYPE_WEP40;
8277 pWextState->roamProfile.mcEncryptionType.encryptionType[0] =
8278 eCSR_ENCRYPT_TYPE_WEP40;
8279 }
8280
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308281 setKey.encType =
Jeff Johnson295189b2012-06-20 16:38:30 -07008282 pWextState->roamProfile.EncryptionType.encryptionType[0];
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308283
Jeff Johnson295189b2012-06-20 16:38:30 -07008284 /* issue set key request */
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308285 status = sme_RoamSetKey( WLAN_HDD_GET_HAL_CTX(pAdapter),
Jeff Johnson295189b2012-06-20 16:38:30 -07008286 pAdapter->sessionId, &setKey, &roamId );
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308287
Jeff Johnson295189b2012-06-20 16:38:30 -07008288 if ( 0 != status )
8289 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308290 hddLog(VOS_TRACE_LEVEL_ERROR,
8291 "%s: sme_RoamSetKey failed, returned %d", __func__,
Jeff Johnson295189b2012-06-20 16:38:30 -07008292 status);
8293 return -EINVAL;
8294 }
8295 }
8296 }
8297
8298 /* In SoftAp mode setting key direction for default mode */
8299 else if ( WLAN_HDD_SOFTAP == pAdapter->device_mode )
8300 {
8301 if ( (eCSR_ENCRYPT_TYPE_TKIP !=
8302 pWextState->roamProfile.EncryptionType.encryptionType[0]) &&
8303 (eCSR_ENCRYPT_TYPE_AES !=
8304 pWextState->roamProfile.EncryptionType.encryptionType[0])
8305 )
8306 {
8307 /* Saving key direction for default key index to TX default */
8308 hdd_ap_ctx_t *pAPCtx = WLAN_HDD_GET_AP_CTX_PTR(pAdapter);
8309 pAPCtx->wepKey[key_index].keyDirection = eSIR_TX_DEFAULT;
8310 }
8311 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308312
Jeff Johnson295189b2012-06-20 16:38:30 -07008313 return status;
8314}
8315
Mahesh A Saptasagar1a51bc02014-06-02 18:28:08 +05308316#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
8317static int wlan_hdd_cfg80211_set_default_key( struct wiphy *wiphy,
8318 struct net_device *ndev,
8319 u8 key_index,
8320 bool unicast, bool multicast)
8321#else
8322static int wlan_hdd_cfg80211_set_default_key( struct wiphy *wiphy,
8323 struct net_device *ndev,
8324 u8 key_index)
8325#endif
8326{
8327 int ret;
8328 vos_ssr_protect(__func__);
8329#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
8330 ret = __wlan_hdd_cfg80211_set_default_key(wiphy, ndev, key_index, unicast,
8331 multicast);
8332#else
8333 ret = __wlan_hdd_cfg80211_set_default_key(wiphy, ndev, key_index);
8334#endif
8335 vos_ssr_unprotect(__func__);
8336
8337 return ret;
8338}
8339
Jeff Johnson295189b2012-06-20 16:38:30 -07008340/*
8341 * FUNCTION: wlan_hdd_cfg80211_inform_bss
8342 * This function is used to inform the BSS details to nl80211 interface.
8343 */
8344static struct cfg80211_bss* wlan_hdd_cfg80211_inform_bss(
8345 hdd_adapter_t *pAdapter, tCsrRoamConnectedProfile *roamProfile)
8346{
8347 struct net_device *dev = pAdapter->dev;
8348 struct wireless_dev *wdev = dev->ieee80211_ptr;
8349 struct wiphy *wiphy = wdev->wiphy;
8350 tSirBssDescription *pBssDesc = roamProfile->pBssDesc;
8351 int chan_no;
8352 int ie_length;
8353 const char *ie;
8354 unsigned int freq;
8355 struct ieee80211_channel *chan;
8356 int rssi = 0;
8357 struct cfg80211_bss *bss = NULL;
8358
8359 ENTER();
8360
8361 if( NULL == pBssDesc )
8362 {
Arif Hussain6d2a3322013-11-17 19:50:10 -08008363 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: pBssDesc is NULL", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07008364 return bss;
8365 }
8366
8367 chan_no = pBssDesc->channelId;
8368 ie_length = GET_IE_LEN_IN_BSS_DESC( pBssDesc->length );
8369 ie = ((ie_length != 0) ? (const char *)&pBssDesc->ieFields: NULL);
8370
8371 if( NULL == ie )
8372 {
Arif Hussain6d2a3322013-11-17 19:50:10 -08008373 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: IE of BSS descriptor is NULL", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07008374 return bss;
8375 }
8376
8377#if (LINUX_VERSION_CODE > KERNEL_VERSION(2,6,38))
8378 if (chan_no <= ARRAY_SIZE(hdd_channels_2_4_GHZ))
8379 {
8380 freq = ieee80211_channel_to_frequency(chan_no, IEEE80211_BAND_2GHZ);
8381 }
8382 else
8383 {
8384 freq = ieee80211_channel_to_frequency(chan_no, IEEE80211_BAND_5GHZ);
8385 }
8386#else
8387 freq = ieee80211_channel_to_frequency(chan_no);
8388#endif
8389
8390 chan = __ieee80211_get_channel(wiphy, freq);
8391
Santhosh Kumar Padmaa45fdb12014-04-15 15:54:38 +05308392 if (!chan) {
8393 hddLog(VOS_TRACE_LEVEL_ERROR, "%s chan pointer is NULL", __func__);
8394 return NULL;
8395 }
8396
Abhishek Singhaee43942014-06-16 18:55:47 +05308397 rssi = (VOS_MIN ((pBssDesc->rssi + pBssDesc->sinr), 0))*100;
Jeff Johnson295189b2012-06-20 16:38:30 -07008398
Abhishek Singhaee43942014-06-16 18:55:47 +05308399 return cfg80211_inform_bss(wiphy, chan, pBssDesc->bssId,
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308400 le64_to_cpu(*(__le64 *)pBssDesc->timeStamp),
Jeff Johnson295189b2012-06-20 16:38:30 -07008401 pBssDesc->capabilityInfo,
8402 pBssDesc->beaconInterval, ie, ie_length,
Abhishek Singhaee43942014-06-16 18:55:47 +05308403 rssi, GFP_KERNEL );
Jeff Johnson295189b2012-06-20 16:38:30 -07008404}
8405
8406
8407
8408/*
8409 * FUNCTION: wlan_hdd_cfg80211_inform_bss_frame
8410 * This function is used to inform the BSS details to nl80211 interface.
8411 */
8412struct cfg80211_bss*
8413wlan_hdd_cfg80211_inform_bss_frame( hdd_adapter_t *pAdapter,
8414 tSirBssDescription *bss_desc
8415 )
8416{
8417 /*
8418 cfg80211_inform_bss() is not updating ie field of bss entry, if entry
8419 already exists in bss data base of cfg80211 for that particular BSS ID.
8420 Using cfg80211_inform_bss_frame to update the bss entry instead of
8421 cfg80211_inform_bss, But this call expects mgmt packet as input. As of
8422 now there is no possibility to get the mgmt(probe response) frame from PE,
8423 converting bss_desc to ieee80211_mgmt(probe response) and passing to
8424 cfg80211_inform_bss_frame.
8425 */
8426 struct net_device *dev = pAdapter->dev;
8427 struct wireless_dev *wdev = dev->ieee80211_ptr;
8428 struct wiphy *wiphy = wdev->wiphy;
8429 int chan_no = bss_desc->channelId;
Madan Mohan Koyyalamudi86f629e2012-11-09 16:27:29 -08008430#ifdef WLAN_ENABLE_AGEIE_ON_SCAN_RESULTS
8431 qcom_ie_age *qie_age = NULL;
8432 int ie_length = GET_IE_LEN_IN_BSS_DESC( bss_desc->length ) + sizeof(qcom_ie_age);
8433#else
Jeff Johnson295189b2012-06-20 16:38:30 -07008434 int ie_length = GET_IE_LEN_IN_BSS_DESC( bss_desc->length );
Madan Mohan Koyyalamudi86f629e2012-11-09 16:27:29 -08008435#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07008436 const char *ie =
8437 ((ie_length != 0) ? (const char *)&bss_desc->ieFields: NULL);
8438 unsigned int freq;
8439 struct ieee80211_channel *chan;
Abhishek Singh1e2bfa32014-01-02 15:44:15 +05308440 struct ieee80211_mgmt *mgmt = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -07008441 struct cfg80211_bss *bss_status = NULL;
8442 size_t frame_len = sizeof (struct ieee80211_mgmt) + ie_length;
8443 int rssi = 0;
Wilson Yangf80a0542013-10-07 13:02:37 -07008444 hdd_context_t *pHddCtx;
8445 int status;
Jeff Johnsone7245742012-09-05 17:12:55 -07008446#ifdef WLAN_OPEN_SOURCE
8447 struct timespec ts;
8448#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07008449
Wilson Yangf80a0542013-10-07 13:02:37 -07008450 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
8451 status = wlan_hdd_validate_context(pHddCtx);
8452
8453 /*bss_update is not allowed during wlan driver loading or unloading*/
Mihir Shete18156292014-03-11 15:38:30 +05308454 if (WLAN_HDD_IS_LOAD_UNLOAD_IN_PROGRESS(pHddCtx))
Wilson Yangf80a0542013-10-07 13:02:37 -07008455 {
8456 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
8457 "%s:Loading_unloading in Progress. Ignore!!!",__func__);
8458 return NULL;
8459 }
8460
8461
8462 if (0 != status)
8463 {
8464 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
8465 "%s: HDD context is not valid", __func__);
Madan Mohan Koyyalamudi2e5c9142012-11-02 13:17:48 -07008466 return NULL;
Wilson Yangf80a0542013-10-07 13:02:37 -07008467 }
8468
Abhishek Singh1e2bfa32014-01-02 15:44:15 +05308469 mgmt = kzalloc((sizeof (struct ieee80211_mgmt) + ie_length), GFP_KERNEL);
Wilson Yangf80a0542013-10-07 13:02:37 -07008470 if (!mgmt)
8471 {
8472 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
8473 "%s: memory allocation failed ", __func__);
8474 return NULL;
8475 }
Madan Mohan Koyyalamudi2e5c9142012-11-02 13:17:48 -07008476
Jeff Johnson295189b2012-06-20 16:38:30 -07008477 memcpy(mgmt->bssid, bss_desc->bssId, ETH_ALEN);
Jeff Johnsone7245742012-09-05 17:12:55 -07008478
8479#ifdef WLAN_OPEN_SOURCE
8480 /* Android does not want the timestamp from the frame.
8481 Instead it wants a monotonic increasing value */
8482 get_monotonic_boottime(&ts);
8483 mgmt->u.probe_resp.timestamp =
8484 ((u64)ts.tv_sec * 1000000) + (ts.tv_nsec / 1000);
8485#else
8486 /* keep old behavior for non-open source (for now) */
Jeff Johnson295189b2012-06-20 16:38:30 -07008487 memcpy(&mgmt->u.probe_resp.timestamp, bss_desc->timeStamp,
8488 sizeof (bss_desc->timeStamp));
Jeff Johnsone7245742012-09-05 17:12:55 -07008489
8490#endif
8491
Jeff Johnson295189b2012-06-20 16:38:30 -07008492 mgmt->u.probe_resp.beacon_int = bss_desc->beaconInterval;
8493 mgmt->u.probe_resp.capab_info = bss_desc->capabilityInfo;
Madan Mohan Koyyalamudi86f629e2012-11-09 16:27:29 -08008494
8495#ifdef WLAN_ENABLE_AGEIE_ON_SCAN_RESULTS
8496 /* GPS Requirement: need age ie per entry. Using vendor specific. */
8497 /* Assuming this is the last IE, copy at the end */
8498 ie_length -=sizeof(qcom_ie_age);
8499 qie_age = (qcom_ie_age *)(mgmt->u.probe_resp.variable + ie_length);
8500 qie_age->element_id = QCOM_VENDOR_IE_ID;
8501 qie_age->len = QCOM_VENDOR_IE_AGE_LEN;
8502 qie_age->oui_1 = QCOM_OUI1;
8503 qie_age->oui_2 = QCOM_OUI2;
8504 qie_age->oui_3 = QCOM_OUI3;
8505 qie_age->type = QCOM_VENDOR_IE_AGE_TYPE;
8506 qie_age->age = vos_timer_get_system_ticks() - bss_desc->nReceivedTime;
8507#endif
8508
Jeff Johnson295189b2012-06-20 16:38:30 -07008509 memcpy(mgmt->u.probe_resp.variable, ie, ie_length);
Gopichand Nakkalad908ec82013-05-16 19:32:19 +05308510 if (bss_desc->fProbeRsp)
8511 {
8512 mgmt->frame_control |=
8513 (u16)(IEEE80211_FTYPE_MGMT | IEEE80211_STYPE_PROBE_RESP);
8514 }
8515 else
8516 {
8517 mgmt->frame_control |=
8518 (u16)(IEEE80211_FTYPE_MGMT | IEEE80211_STYPE_BEACON);
8519 }
Jeff Johnson295189b2012-06-20 16:38:30 -07008520
8521#if (LINUX_VERSION_CODE > KERNEL_VERSION(2,6,38))
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308522 if (chan_no <= ARRAY_SIZE(hdd_channels_2_4_GHZ) &&
Jeff Johnson295189b2012-06-20 16:38:30 -07008523 (wiphy->bands[IEEE80211_BAND_2GHZ] != NULL))
8524 {
8525 freq = ieee80211_channel_to_frequency(chan_no, IEEE80211_BAND_2GHZ);
8526 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308527 else if ((chan_no > ARRAY_SIZE(hdd_channels_2_4_GHZ)) &&
Jeff Johnson295189b2012-06-20 16:38:30 -07008528 (wiphy->bands[IEEE80211_BAND_5GHZ] != NULL))
8529
8530 {
8531 freq = ieee80211_channel_to_frequency(chan_no, IEEE80211_BAND_5GHZ);
8532 }
8533 else
8534 {
Nirav Shah20ac06f2013-12-12 18:14:06 +05308535 hddLog(VOS_TRACE_LEVEL_ERROR, "%s Invalid chan_no:%d",
8536 __func__, chan_no);
Jeff Johnson295189b2012-06-20 16:38:30 -07008537 kfree(mgmt);
8538 return NULL;
8539 }
8540#else
8541 freq = ieee80211_channel_to_frequency(chan_no);
8542#endif
8543 chan = __ieee80211_get_channel(wiphy, freq);
Leela V Kiran Kumar Reddy90032de2013-01-24 18:33:30 -08008544 /*when the band is changed on the fly using the GUI, three things are done
8545 * 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)
8546 * as part of the scan abort, message willbe queued to PE and we proceed with flushing and changinh the band.
8547 * pe will stop the scanning further and report back the results what ever it had till now by calling the call back function.
8548 * if the time between update band and scandone call back is sufficent enough the band change reflects in SME, SME validates the channels
8549 * and discards the channels correponding to previous band and calls back with zero bss results.
8550 * 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
8551 * all the channels correponding to previous band.this is due to race condition.but those channels are invalid to the new band and so
8552 * this function __ieee80211_get_channel will return NULL.Each time we report scan result with this pointer null warning kernel trace is printed.
8553 * if the scan results contain large number of APs continuosly kernel warning trace is printed and it will lead to apps watch dog bark.
8554 * So drop the bss and continue to next bss.
8555 */
8556 if(chan == NULL)
8557 {
Nirav Shah20ac06f2013-12-12 18:14:06 +05308558 hddLog(VOS_TRACE_LEVEL_ERROR, "%s chan pointer is NULL", __func__);
Chilam Ngc4244af2013-04-01 15:37:32 -07008559 kfree(mgmt);
Leela V Kiran Kumar Reddy90032de2013-01-24 18:33:30 -08008560 return NULL;
8561 }
Jeff Johnson295189b2012-06-20 16:38:30 -07008562 /*To keep the rssi icon of the connected AP in the scan window
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308563 *and the rssi icon of the wireless networks in sync
Jeff Johnson295189b2012-06-20 16:38:30 -07008564 * */
8565 if (( eConnectionState_Associated ==
8566 pAdapter->sessionCtx.station.conn_info.connState ) &&
8567 ( VOS_TRUE == vos_mem_compare(bss_desc->bssId,
8568 pAdapter->sessionCtx.station.conn_info.bssId,
8569 WNI_CFG_BSSID_LEN)))
8570 {
8571 /* supplicant takes the signal strength in terms of mBm(100*dBm) */
8572 rssi = (pAdapter->rssi * 100);
8573 }
8574 else
8575 {
8576 rssi = (VOS_MIN ((bss_desc->rssi + bss_desc->sinr), 0))*100;
8577 }
8578
Nirav Shah20ac06f2013-12-12 18:14:06 +05308579 hddLog(VOS_TRACE_LEVEL_INFO, "%s: BSSID:" MAC_ADDRESS_STR " Channel:%d"
8580 "RSSI:%d", __func__, MAC_ADDR_ARRAY(mgmt->bssid),
8581 chan->center_freq, (int)(rssi/100));
8582
Jeff Johnson295189b2012-06-20 16:38:30 -07008583 bss_status = cfg80211_inform_bss_frame(wiphy, chan, mgmt,
8584 frame_len, rssi, GFP_KERNEL);
8585 kfree(mgmt);
8586 return bss_status;
8587}
8588
8589/*
8590 * FUNCTION: wlan_hdd_cfg80211_update_bss_db
8591 * This function is used to update the BSS data base of CFG8011
8592 */
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308593struct cfg80211_bss* wlan_hdd_cfg80211_update_bss_db( hdd_adapter_t *pAdapter,
Jeff Johnson295189b2012-06-20 16:38:30 -07008594 tCsrRoamInfo *pRoamInfo
8595 )
8596{
8597 tCsrRoamConnectedProfile roamProfile;
8598 tHalHandle hHal = WLAN_HDD_GET_HAL_CTX(pAdapter);
8599 struct cfg80211_bss *bss = NULL;
8600
8601 ENTER();
8602
8603 memset(&roamProfile, 0, sizeof(tCsrRoamConnectedProfile));
8604 sme_RoamGetConnectProfile(hHal, pAdapter->sessionId, &roamProfile);
8605
8606 if (NULL != roamProfile.pBssDesc)
8607 {
Girish Gowlif4b68022014-08-28 23:18:57 +05308608 bss = wlan_hdd_cfg80211_inform_bss_frame(pAdapter,
8609 roamProfile.pBssDesc);
Jeff Johnson295189b2012-06-20 16:38:30 -07008610
8611 if (NULL == bss)
8612 {
8613 hddLog(VOS_TRACE_LEVEL_INFO, "%s: cfg80211_inform_bss return NULL",
8614 __func__);
8615 }
8616
8617 sme_RoamFreeConnectProfile(hHal, &roamProfile);
8618 }
8619 else
8620 {
8621 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: roamProfile.pBssDesc is NULL",
8622 __func__);
8623 }
8624 return bss;
8625}
8626
8627/*
8628 * FUNCTION: wlan_hdd_cfg80211_update_bss
8629 */
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308630static int wlan_hdd_cfg80211_update_bss( struct wiphy *wiphy,
8631 hdd_adapter_t *pAdapter
Jeff Johnson295189b2012-06-20 16:38:30 -07008632 )
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308633{
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +05308634 tHalHandle hHal = WLAN_HDD_GET_HAL_CTX(pAdapter);
Jeff Johnson295189b2012-06-20 16:38:30 -07008635 tCsrScanResultInfo *pScanResult;
8636 eHalStatus status = 0;
8637 tScanResultHandle pResult;
8638 struct cfg80211_bss *bss_status = NULL;
Wilson Yangf80a0542013-10-07 13:02:37 -07008639 hdd_context_t *pHddCtx;
Jeff Johnson295189b2012-06-20 16:38:30 -07008640
8641 ENTER();
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +05308642
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05308643 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
8644 TRACE_CODE_HDD_CFG80211_UPDATE_BSS,
8645 NO_SESSION, pAdapter->sessionId));
8646
Wilson Yangf80a0542013-10-07 13:02:37 -07008647 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
8648
8649 if (pHddCtx->isLogpInProgress)
Jeff Johnson295189b2012-06-20 16:38:30 -07008650 {
Wilson Yangf80a0542013-10-07 13:02:37 -07008651 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
8652 "%s:LOGP in Progress. Ignore!!!",__func__);
8653 return -EAGAIN;
Jeff Johnson295189b2012-06-20 16:38:30 -07008654 }
8655
Wilson Yangf80a0542013-10-07 13:02:37 -07008656
8657 /*bss_update is not allowed during wlan driver loading or unloading*/
Mihir Shete18156292014-03-11 15:38:30 +05308658 if (WLAN_HDD_IS_LOAD_UNLOAD_IN_PROGRESS(pHddCtx))
Wilson Yangf80a0542013-10-07 13:02:37 -07008659 {
8660 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
8661 "%s:Loading_unloading in Progress. Ignore!!!",__func__);
8662 return VOS_STATUS_E_PERM;
8663 }
8664
8665
Jeff Johnson295189b2012-06-20 16:38:30 -07008666 /*
8667 * start getting scan results and populate cgf80211 BSS database
8668 */
8669 status = sme_ScanGetResult(hHal, pAdapter->sessionId, NULL, &pResult);
8670
8671 /* no scan results */
8672 if (NULL == pResult)
8673 {
Nirav Shah20ac06f2013-12-12 18:14:06 +05308674 hddLog(VOS_TRACE_LEVEL_INFO, "%s: No scan result Status %d",
8675 __func__, status);
Jeff Johnson295189b2012-06-20 16:38:30 -07008676 return status;
8677 }
8678
8679 pScanResult = sme_ScanResultGetFirst(hHal, pResult);
8680
8681 while (pScanResult)
8682 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308683 /*
8684 * cfg80211_inform_bss() is not updating ie field of bss entry, if
8685 * entry already exists in bss data base of cfg80211 for that
8686 * particular BSS ID. Using cfg80211_inform_bss_frame to update the
8687 * bss entry instead of cfg80211_inform_bss, But this call expects
8688 * mgmt packet as input. As of now there is no possibility to get
8689 * the mgmt(probe response) frame from PE, converting bss_desc to
Jeff Johnson295189b2012-06-20 16:38:30 -07008690 * ieee80211_mgmt(probe response) and passing to c
8691 * fg80211_inform_bss_frame.
8692 * */
8693
8694 bss_status = wlan_hdd_cfg80211_inform_bss_frame(pAdapter,
8695 &pScanResult->BssDescriptor);
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308696
Jeff Johnson295189b2012-06-20 16:38:30 -07008697
8698 if (NULL == bss_status)
8699 {
8700 hddLog(VOS_TRACE_LEVEL_INFO,
Arif Hussain6d2a3322013-11-17 19:50:10 -08008701 "%s: NULL returned by cfg80211_inform_bss", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07008702 }
8703 else
8704 {
Yue Maf49ba872013-08-19 12:04:25 -07008705 cfg80211_put_bss(
8706#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,9,0))
8707 wiphy,
8708#endif
8709 bss_status);
Jeff Johnson295189b2012-06-20 16:38:30 -07008710 }
8711
8712 pScanResult = sme_ScanResultGetNext(hHal, pResult);
8713 }
8714
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308715 sme_ScanResultPurge(hHal, pResult);
Jeff Johnson295189b2012-06-20 16:38:30 -07008716
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308717 return 0;
Jeff Johnson295189b2012-06-20 16:38:30 -07008718}
8719
Jeff Johnson04dd8a82012-06-29 20:41:40 -07008720void
8721hddPrintMacAddr(tCsrBssid macAddr, tANI_U8 logLevel)
8722{
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308723 VOS_TRACE(VOS_MODULE_ID_HDD, logLevel,
Arif Hussaina7c8e412013-11-20 11:06:42 -08008724 MAC_ADDRESS_STR, MAC_ADDR_ARRAY(macAddr));
Jeff Johnson04dd8a82012-06-29 20:41:40 -07008725} /****** end hddPrintMacAddr() ******/
8726
8727void
Madan Mohan Koyyalamudic75be962012-10-18 19:19:03 -07008728hddPrintPmkId(tANI_U8 *pmkId, tANI_U8 logLevel)
Jeff Johnson04dd8a82012-06-29 20:41:40 -07008729{
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308730 VOS_TRACE(VOS_MODULE_ID_HDD, logLevel,
Arif Hussain6d2a3322013-11-17 19:50:10 -08008731 "%02X:%02X:%02X:%02X:%02X:%02X:%02X:%02X:%02X:%02X:%02X:%02X:%02X:%02X:%02X:%02X",
Madan Mohan Koyyalamudic75be962012-10-18 19:19:03 -07008732 pmkId[0], pmkId[1], pmkId[2], pmkId[3], pmkId[4],
8733 pmkId[5], pmkId[6], pmkId[7], pmkId[8], pmkId[9], pmkId[10],
8734 pmkId[11], pmkId[12], pmkId[13], pmkId[14], pmkId[15]);
Jeff Johnson04dd8a82012-06-29 20:41:40 -07008735} /****** end hddPrintPmkId() ******/
8736
8737//hddPrintMacAddr(tCsrBssid macAddr, tANI_U8 logLevel);
8738//hddPrintMacAddr(macAddr, VOS_TRACE_LEVEL_FATAL);
8739
8740//void sirDumpBuf(tpAniSirGlobal pMac, tANI_U8 modId, tANI_U32 level, tANI_U8 *buf, tANI_U32 size);
8741//sirDumpBuf(pMac, VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL, pmkid, 16);
8742
8743#define dump_bssid(bssid) \
8744 { \
Jeff Johnsone7245742012-09-05 17:12:55 -07008745 hddLog(VOS_TRACE_LEVEL_INFO, "BSSID (MAC) address:\t"); \
8746 hddPrintMacAddr(bssid, VOS_TRACE_LEVEL_INFO);\
Jeff Johnson04dd8a82012-06-29 20:41:40 -07008747 }
8748
8749#define dump_pmkid(pMac, pmkid) \
8750 { \
Jeff Johnsone7245742012-09-05 17:12:55 -07008751 hddLog(VOS_TRACE_LEVEL_INFO, "PMKSA-ID:\t"); \
8752 hddPrintPmkId(pmkid, VOS_TRACE_LEVEL_INFO);\
Jeff Johnson04dd8a82012-06-29 20:41:40 -07008753 }
8754
Madan Mohan Koyyalamudi1b4afb02012-10-22 15:25:16 -07008755#if defined(FEATURE_WLAN_LFR) && (LINUX_VERSION_CODE >= KERNEL_VERSION(3,4,0))
Jeff Johnson04dd8a82012-06-29 20:41:40 -07008756/*
8757 * FUNCTION: wlan_hdd_cfg80211_pmksa_candidate_notify
8758 * This function is used to notify the supplicant of a new PMKSA candidate.
8759 */
8760int wlan_hdd_cfg80211_pmksa_candidate_notify(
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308761 hdd_adapter_t *pAdapter, tCsrRoamInfo *pRoamInfo,
Jeff Johnson04dd8a82012-06-29 20:41:40 -07008762 int index, bool preauth )
8763{
Jeff Johnsone7245742012-09-05 17:12:55 -07008764#ifdef FEATURE_WLAN_OKC
Jeff Johnson04dd8a82012-06-29 20:41:40 -07008765 struct net_device *dev = pAdapter->dev;
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07008766 hdd_context_t *pHddCtx = (hdd_context_t*)pAdapter->pHddCtx;
Jeff Johnson04dd8a82012-06-29 20:41:40 -07008767
8768 ENTER();
Jeff Johnsone7245742012-09-05 17:12:55 -07008769 hddLog(VOS_TRACE_LEVEL_INFO, "%s is going to notify supplicant of:", __func__);
Jeff Johnson04dd8a82012-06-29 20:41:40 -07008770
8771 if( NULL == pRoamInfo )
8772 {
Arif Hussain6d2a3322013-11-17 19:50:10 -08008773 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: pRoamInfo is NULL", __func__);
Jeff Johnson04dd8a82012-06-29 20:41:40 -07008774 return -EINVAL;
8775 }
8776
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07008777 if (eANI_BOOLEAN_TRUE == hdd_is_okc_mode_enabled(pHddCtx))
8778 {
8779 dump_bssid(pRoamInfo->bssid);
8780 cfg80211_pmksa_candidate_notify(dev, index,
Jeff Johnson04dd8a82012-06-29 20:41:40 -07008781 pRoamInfo->bssid, preauth, GFP_KERNEL);
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07008782 }
Jeff Johnsone7245742012-09-05 17:12:55 -07008783#endif /* FEATURE_WLAN_OKC */
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308784 return 0;
Jeff Johnson04dd8a82012-06-29 20:41:40 -07008785}
8786#endif //FEATURE_WLAN_LFR
8787
Yue Maef608272013-04-08 23:09:17 -07008788#ifdef FEATURE_WLAN_LFR_METRICS
8789/*
8790 * FUNCTION: wlan_hdd_cfg80211_roam_metrics_preauth
8791 * 802.11r/LFR metrics reporting function to report preauth initiation
8792 *
8793 */
8794#define MAX_LFR_METRICS_EVENT_LENGTH 100
8795VOS_STATUS wlan_hdd_cfg80211_roam_metrics_preauth(hdd_adapter_t *pAdapter,
8796 tCsrRoamInfo *pRoamInfo)
8797{
8798 unsigned char metrics_notification[MAX_LFR_METRICS_EVENT_LENGTH + 1];
8799 union iwreq_data wrqu;
8800
8801 ENTER();
8802
8803 if (NULL == pAdapter)
8804 {
8805 hddLog(LOGE, "%s: pAdapter is NULL!", __func__);
8806 return VOS_STATUS_E_FAILURE;
8807 }
8808
8809 /* create the event */
8810 memset(&wrqu, 0, sizeof(wrqu));
8811 memset(metrics_notification, 0, sizeof(metrics_notification));
8812
8813 wrqu.data.pointer = metrics_notification;
8814 wrqu.data.length = scnprintf(metrics_notification,
8815 sizeof(metrics_notification), "QCOM: LFR_PREAUTH_INIT "
8816 MAC_ADDRESS_STR, MAC_ADDR_ARRAY(pRoamInfo->bssid));
8817
8818 wireless_send_event(pAdapter->dev, IWEVCUSTOM, &wrqu, metrics_notification);
8819
8820 EXIT();
8821
8822 return VOS_STATUS_SUCCESS;
8823}
8824
8825/*
8826 * FUNCTION: wlan_hdd_cfg80211_roam_metrics_preauth_status
8827 * 802.11r/LFR metrics reporting function to report preauth completion
8828 * or failure
8829 */
8830VOS_STATUS wlan_hdd_cfg80211_roam_metrics_preauth_status(
8831 hdd_adapter_t *pAdapter, tCsrRoamInfo *pRoamInfo, bool preauth_status)
8832{
8833 unsigned char metrics_notification[MAX_LFR_METRICS_EVENT_LENGTH + 1];
8834 union iwreq_data wrqu;
8835
8836 ENTER();
8837
8838 if (NULL == pAdapter)
8839 {
8840 hddLog(LOGE, "%s: pAdapter is NULL!", __func__);
8841 return VOS_STATUS_E_FAILURE;
8842 }
8843
8844 /* create the event */
8845 memset(&wrqu, 0, sizeof(wrqu));
8846 memset(metrics_notification, 0, sizeof(metrics_notification));
8847
8848 scnprintf(metrics_notification, sizeof(metrics_notification),
8849 "QCOM: LFR_PREAUTH_STATUS "MAC_ADDRESS_STR,
8850 MAC_ADDR_ARRAY(pRoamInfo->bssid));
8851
8852 if (1 == preauth_status)
8853 strncat(metrics_notification, " TRUE", 5);
8854 else
8855 strncat(metrics_notification, " FALSE", 6);
8856
8857 wrqu.data.pointer = metrics_notification;
8858 wrqu.data.length = strlen(metrics_notification);
8859
8860 wireless_send_event(pAdapter->dev, IWEVCUSTOM, &wrqu, metrics_notification);
8861
8862 EXIT();
8863
8864 return VOS_STATUS_SUCCESS;
8865}
8866
8867/*
8868 * FUNCTION: wlan_hdd_cfg80211_roam_metrics_handover
8869 * 802.11r/LFR metrics reporting function to report handover initiation
8870 *
8871 */
8872VOS_STATUS wlan_hdd_cfg80211_roam_metrics_handover(hdd_adapter_t * pAdapter,
8873 tCsrRoamInfo *pRoamInfo)
8874{
8875 unsigned char metrics_notification[MAX_LFR_METRICS_EVENT_LENGTH + 1];
8876 union iwreq_data wrqu;
8877
8878 ENTER();
8879
8880 if (NULL == pAdapter)
8881 {
8882 hddLog(LOGE, "%s: pAdapter is NULL!", __func__);
8883 return VOS_STATUS_E_FAILURE;
8884 }
8885
8886 /* create the event */
8887 memset(&wrqu, 0, sizeof(wrqu));
8888 memset(metrics_notification, 0, sizeof(metrics_notification));
8889
8890 wrqu.data.pointer = metrics_notification;
8891 wrqu.data.length = scnprintf(metrics_notification,
8892 sizeof(metrics_notification), "QCOM: LFR_PREAUTH_HANDOVER "
8893 MAC_ADDRESS_STR, MAC_ADDR_ARRAY(pRoamInfo->bssid));
8894
8895 wireless_send_event(pAdapter->dev, IWEVCUSTOM, &wrqu, metrics_notification);
8896
8897 EXIT();
8898
8899 return VOS_STATUS_SUCCESS;
8900}
8901#endif
8902
Jeff Johnson295189b2012-06-20 16:38:30 -07008903/*
8904 * FUNCTION: hdd_cfg80211_scan_done_callback
8905 * scanning callback function, called after finishing scan
8906 *
8907 */
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308908static eHalStatus hdd_cfg80211_scan_done_callback(tHalHandle halHandle,
Jeff Johnson295189b2012-06-20 16:38:30 -07008909 void *pContext, tANI_U32 scanId, eCsrScanStatus status)
8910{
8911 struct net_device *dev = (struct net_device *) pContext;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308912 //struct wireless_dev *wdev = dev->ieee80211_ptr;
Jeff Johnson295189b2012-06-20 16:38:30 -07008913 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( dev );
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -07008914 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
8915 hdd_scaninfo_t *pScanInfo = &pHddCtx->scan_info;
Jeff Johnson295189b2012-06-20 16:38:30 -07008916 struct cfg80211_scan_request *req = NULL;
8917 int ret = 0;
Mahesh A Saptasagar05a357e2014-02-26 16:28:06 +05308918 bool aborted = false;
c_hpothu6ff1c3c2013-10-01 19:01:57 +05308919 long waitRet = 0;
Jeff Johnson295189b2012-06-20 16:38:30 -07008920
8921 ENTER();
8922
8923 hddLog(VOS_TRACE_LEVEL_INFO,
8924 "%s called with halHandle = %p, pContext = %p,"
Arif Hussain6d2a3322013-11-17 19:50:10 -08008925 "scanID = %d, returned status = %d",
Jeff Johnson295189b2012-06-20 16:38:30 -07008926 __func__, halHandle, pContext, (int) scanId, (int) status);
8927
Kiet Lamac06e2c2013-10-23 16:25:07 +05308928 pScanInfo->mScanPendingCounter = 0;
8929
Jeff Johnson295189b2012-06-20 16:38:30 -07008930 //Block on scan req completion variable. Can't wait forever though.
c_hpothu6ff1c3c2013-10-01 19:01:57 +05308931 waitRet = wait_for_completion_interruptible_timeout(
Jeff Johnson295189b2012-06-20 16:38:30 -07008932 &pScanInfo->scan_req_completion_event,
8933 msecs_to_jiffies(WLAN_WAIT_TIME_SCAN_REQ));
c_hpothu6ff1c3c2013-10-01 19:01:57 +05308934 if (waitRet <= 0)
Jeff Johnson295189b2012-06-20 16:38:30 -07008935 {
c_hpothu6ff1c3c2013-10-01 19:01:57 +05308936 hddLog(VOS_TRACE_LEVEL_ERROR,
8937 "%s wait on scan_req_completion_event failed %ld",__func__, waitRet);
Jeff Johnson295189b2012-06-20 16:38:30 -07008938 VOS_ASSERT(pScanInfo->mScanPending);
Jeff Johnsone7245742012-09-05 17:12:55 -07008939 goto allow_suspend;
Jeff Johnson295189b2012-06-20 16:38:30 -07008940 }
8941
Yue Maef608272013-04-08 23:09:17 -07008942 if (pScanInfo->mScanPending != VOS_TRUE)
Jeff Johnson295189b2012-06-20 16:38:30 -07008943 {
8944 VOS_ASSERT(pScanInfo->mScanPending);
Jeff Johnsone7245742012-09-05 17:12:55 -07008945 goto allow_suspend;
Jeff Johnson295189b2012-06-20 16:38:30 -07008946 }
8947
8948 /* Check the scanId */
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308949 if (pScanInfo->scanId != scanId)
Jeff Johnson295189b2012-06-20 16:38:30 -07008950 {
8951 hddLog(VOS_TRACE_LEVEL_INFO,
8952 "%s called with mismatched scanId pScanInfo->scanId = %d "
Arif Hussain6d2a3322013-11-17 19:50:10 -08008953 "scanId = %d", __func__, (int) pScanInfo->scanId,
Jeff Johnson295189b2012-06-20 16:38:30 -07008954 (int) scanId);
8955 }
8956
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308957 ret = wlan_hdd_cfg80211_update_bss((WLAN_HDD_GET_CTX(pAdapter))->wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -07008958 pAdapter);
8959
8960 if (0 > ret)
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308961 hddLog(VOS_TRACE_LEVEL_INFO, "%s: NO SCAN result", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07008962
8963
8964 /* If any client wait scan result through WEXT
8965 * send scan done event to client */
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -07008966 if (pHddCtx->scan_info.waitScanResult)
Jeff Johnson295189b2012-06-20 16:38:30 -07008967 {
8968 /* The other scan request waiting for current scan finish
8969 * Send event to notify current scan finished */
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -07008970 if(WEXT_SCAN_PENDING_DELAY == pHddCtx->scan_info.scan_pending_option)
Jeff Johnson295189b2012-06-20 16:38:30 -07008971 {
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -07008972 vos_event_set(&pHddCtx->scan_info.scan_finished_event);
Jeff Johnson295189b2012-06-20 16:38:30 -07008973 }
8974 /* Send notify to WEXT client */
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -07008975 else if(WEXT_SCAN_PENDING_PIGGYBACK == pHddCtx->scan_info.scan_pending_option)
Jeff Johnson295189b2012-06-20 16:38:30 -07008976 {
8977 struct net_device *dev = pAdapter->dev;
8978 union iwreq_data wrqu;
8979 int we_event;
8980 char *msg;
8981
8982 memset(&wrqu, '\0', sizeof(wrqu));
8983 we_event = SIOCGIWSCAN;
8984 msg = NULL;
8985 wireless_send_event(dev, we_event, &wrqu, msg);
8986 }
8987 }
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -07008988 pHddCtx->scan_info.waitScanResult = FALSE;
Jeff Johnson295189b2012-06-20 16:38:30 -07008989
8990 /* Get the Scan Req */
8991 req = pAdapter->request;
8992
8993 if (!req)
8994 {
Arif Hussain6d2a3322013-11-17 19:50:10 -08008995 hddLog(VOS_TRACE_LEVEL_ERROR, "request is became NULL");
Madan Mohan Koyyalamudi9f5a10c2012-09-28 14:46:16 -07008996 pScanInfo->mScanPending = VOS_FALSE;
Jeff Johnsone7245742012-09-05 17:12:55 -07008997 goto allow_suspend;
Jeff Johnson295189b2012-06-20 16:38:30 -07008998 }
8999
9000 /*
9001 * setting up 0, just in case.
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309002 */
Jeff Johnson295189b2012-06-20 16:38:30 -07009003 req->n_ssids = 0;
9004 req->n_channels = 0;
9005 req->ie = 0;
9006
Jeff Johnson295189b2012-06-20 16:38:30 -07009007 pAdapter->request = NULL;
Jeff Johnsone7245742012-09-05 17:12:55 -07009008 /* Scan is no longer pending */
9009 pScanInfo->mScanPending = VOS_FALSE;
Jeff Johnson295189b2012-06-20 16:38:30 -07009010
Madan Mohan Koyyalamudib764bf82012-10-11 16:38:51 -07009011 /*
9012 * cfg80211_scan_done informing NL80211 about completion
9013 * of scanning
9014 */
Mahesh A Saptasagar05a357e2014-02-26 16:28:06 +05309015 if (status == eCSR_SCAN_ABORT || status == eCSR_SCAN_FAILURE)
9016 {
9017 aborted = true;
9018 }
9019 cfg80211_scan_done(req, aborted);
Madan Mohan Koyyalamudif4e81002012-11-13 10:46:38 -08009020 complete(&pScanInfo->abortscan_event_var);
Jeff Johnson295189b2012-06-20 16:38:30 -07009021
Jeff Johnsone7245742012-09-05 17:12:55 -07009022allow_suspend:
Madan Mohan Koyyalamudi9f5a10c2012-09-28 14:46:16 -07009023 /* release the wake lock at the end of the scan*/
9024 hdd_allow_suspend();
Jeff Johnsone7245742012-09-05 17:12:55 -07009025
Madan Mohan Koyyalamudi10d83a92012-09-28 15:47:05 -07009026 /* Acquire wakelock to handle the case where APP's tries to suspend
9027 * immediatly after the driver gets connect request(i.e after scan)
9028 * from supplicant, this result in app's is suspending and not able
9029 * to process the connect request to AP */
Mahesh A Saptasagarb9c50402014-01-16 15:49:22 +05309030 hdd_prevent_suspend_timeout(1000);
Madan Mohan Koyyalamudi10d83a92012-09-28 15:47:05 -07009031
Gopichand Nakkala638ebc72013-03-21 18:04:02 -07009032#ifdef FEATURE_WLAN_TDLS
c_hpothu3c8f8e82014-06-02 18:01:50 +05309033 if (!(eTDLS_SUPPORT_NOT_ENABLED == pHddCtx->tdls_mode))
9034 {
9035 wlan_hdd_tdls_scan_done_callback(pAdapter);
9036 }
Gopichand Nakkala638ebc72013-03-21 18:04:02 -07009037#endif
9038
Jeff Johnson295189b2012-06-20 16:38:30 -07009039 EXIT();
9040 return 0;
9041}
9042
9043/*
Rashmi Ramannab1429032014-04-26 14:59:09 +05309044 * FUNCTION: hdd_isConnectionInProgress
9045 * Go through each adapter and check if Connection is in progress
Madan Mohan Koyyalamudicfd53742013-01-11 15:29:03 -08009046 *
9047 */
Ganesh Kondabattiniaeb7b772014-08-11 20:00:36 +05309048v_BOOL_t hdd_isConnectionInProgress( hdd_context_t *pHddCtx, v_BOOL_t isRoC )
Madan Mohan Koyyalamudicfd53742013-01-11 15:29:03 -08009049{
9050 hdd_adapter_list_node_t *pAdapterNode = NULL, *pNext = NULL;
9051 hdd_station_ctx_t *pHddStaCtx = NULL;
9052 hdd_adapter_t *pAdapter = NULL;
9053 VOS_STATUS status = 0;
9054 v_U8_t staId = 0;
9055 v_U8_t *staMac = NULL;
9056
c_hpothu9b781ba2013-12-30 20:57:45 +05309057 if (TRUE == pHddCtx->btCoexModeSet)
9058 {
9059 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Rashmi Ramannab1429032014-04-26 14:59:09 +05309060 FL("BTCoex Mode operation in progress"));
9061 return VOS_TRUE;
c_hpothu9b781ba2013-12-30 20:57:45 +05309062 }
9063
Madan Mohan Koyyalamudicfd53742013-01-11 15:29:03 -08009064 status = hdd_get_front_adapter ( pHddCtx, &pAdapterNode );
9065
9066 while ( NULL != pAdapterNode && VOS_STATUS_SUCCESS == status )
9067 {
9068 pAdapter = pAdapterNode->pAdapter;
9069
9070 if( pAdapter )
9071 {
9072 hddLog(VOS_TRACE_LEVEL_INFO,
Sushant Kaushik8bc7df22014-04-09 17:55:29 +05309073 "%s: Adapter with device mode %s (%d) exists",
9074 __func__, hdd_device_modetoString(pAdapter->device_mode),
9075 pAdapter->device_mode);
Ganesh Kondabattiniaeb7b772014-08-11 20:00:36 +05309076 if ((((!isRoC) && (WLAN_HDD_INFRA_STATION == pAdapter->device_mode)) ||
Rashmi Ramannab1429032014-04-26 14:59:09 +05309077 (WLAN_HDD_P2P_CLIENT == pAdapter->device_mode) ||
9078 (WLAN_HDD_P2P_DEVICE == pAdapter->device_mode)) &&
9079 (eConnectionState_Connecting ==
9080 (WLAN_HDD_GET_STATION_CTX_PTR(pAdapter))->conn_info.connState))
9081 {
9082 hddLog(VOS_TRACE_LEVEL_ERROR,
9083 "%s: %p(%d) Connection is in progress", __func__,
9084 WLAN_HDD_GET_STATION_CTX_PTR(pAdapter), pAdapter->sessionId);
9085 return VOS_TRUE;
9086 }
Ganesh Kondabattiniaeb7b772014-08-11 20:00:36 +05309087 if (((!isRoC) && (WLAN_HDD_INFRA_STATION == pAdapter->device_mode)) ||
Sushant Kaushik8bc7df22014-04-09 17:55:29 +05309088 (WLAN_HDD_P2P_CLIENT == pAdapter->device_mode) ||
9089 (WLAN_HDD_P2P_DEVICE == pAdapter->device_mode))
Madan Mohan Koyyalamudicfd53742013-01-11 15:29:03 -08009090 {
9091 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
9092 if ((eConnectionState_Associated == pHddStaCtx->conn_info.connState) &&
Sushant Kaushik8bc7df22014-04-09 17:55:29 +05309093 (VOS_FALSE == pHddStaCtx->conn_info.uIsAuthenticated))
Madan Mohan Koyyalamudicfd53742013-01-11 15:29:03 -08009094 {
9095 staMac = (v_U8_t *) &(pAdapter->macAddressCurrent.bytes[0]);
9096 hddLog(VOS_TRACE_LEVEL_ERROR,
Arif Hussain24bafea2013-11-15 15:10:03 -08009097 "%s: client " MAC_ADDRESS_STR
9098 " is in the middle of WPS/EAPOL exchange.", __func__,
9099 MAC_ADDR_ARRAY(staMac));
Rashmi Ramannab1429032014-04-26 14:59:09 +05309100 return VOS_TRUE;
Madan Mohan Koyyalamudicfd53742013-01-11 15:29:03 -08009101 }
9102 }
9103 else if ((WLAN_HDD_SOFTAP == pAdapter->device_mode) ||
9104 (WLAN_HDD_P2P_GO == pAdapter->device_mode))
9105 {
9106 for (staId = 0; staId < WLAN_MAX_STA_COUNT; staId++)
9107 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309108 if ((pAdapter->aStaInfo[staId].isUsed) &&
Madan Mohan Koyyalamudicfd53742013-01-11 15:29:03 -08009109 (WLANTL_STA_CONNECTED == pAdapter->aStaInfo[staId].tlSTAState))
9110 {
9111 staMac = (v_U8_t *) &(pAdapter->aStaInfo[staId].macAddrSTA.bytes[0]);
9112
9113 hddLog(VOS_TRACE_LEVEL_ERROR,
Arif Hussain24bafea2013-11-15 15:10:03 -08009114 "%s: client " MAC_ADDRESS_STR " of SoftAP/P2P-GO is in the "
9115 "middle of WPS/EAPOL exchange.", __func__,
9116 MAC_ADDR_ARRAY(staMac));
Rashmi Ramannab1429032014-04-26 14:59:09 +05309117 return VOS_TRUE;
Madan Mohan Koyyalamudicfd53742013-01-11 15:29:03 -08009118 }
9119 }
9120 }
9121 }
9122 status = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
9123 pAdapterNode = pNext;
9124 }
Rashmi Ramannab1429032014-04-26 14:59:09 +05309125 return VOS_FALSE;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309126}
Madan Mohan Koyyalamudicfd53742013-01-11 15:29:03 -08009127
9128/*
Mahesh A Saptasagarfafb7fe2014-05-16 13:19:37 +05309129 * FUNCTION: __wlan_hdd_cfg80211_scan
Jeff Johnson295189b2012-06-20 16:38:30 -07009130 * this scan respond to scan trigger and update cfg80211 scan database
9131 * later, scan dump command can be used to recieve scan results
9132 */
Mahesh A Saptasagarfafb7fe2014-05-16 13:19:37 +05309133int __wlan_hdd_cfg80211_scan( struct wiphy *wiphy,
Jeff Johnson3bbe4bf2013-01-18 17:05:29 -08009134#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,6,0))
9135 struct net_device *dev,
9136#endif
9137 struct cfg80211_scan_request *request)
9138{
Siddharth Bhal0c162d02014-05-06 19:50:42 +05309139 hdd_adapter_t *pAdapter = NULL;
9140 hdd_context_t *pHddCtx = NULL;
9141 hdd_wext_state_t *pwextBuf = NULL;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05309142 hdd_config_t *cfg_param = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -07009143 tCsrScanRequest scanRequest;
9144 tANI_U8 *channelList = NULL, i;
9145 v_U32_t scanId = 0;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05309146 int status;
9147 hdd_scaninfo_t *pScanInfo = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -07009148 v_U8_t* pP2pIe = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -07009149
Siddharth Bhal0c162d02014-05-06 19:50:42 +05309150#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,6,0))
9151 struct net_device *dev = NULL;
9152 if (NULL == request)
9153 {
9154 hddLog(VOS_TRACE_LEVEL_ERROR,
9155 "%s: scan req param null", __func__);
9156 return -EINVAL;
9157 }
9158 dev = request->wdev->netdev;
9159#endif
9160
9161 pAdapter = WLAN_HDD_GET_PRIV_PTR( dev );
9162 pHddCtx = WLAN_HDD_GET_CTX( pAdapter );
9163 pwextBuf = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
9164
Jeff Johnson295189b2012-06-20 16:38:30 -07009165 ENTER();
9166
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +05309167
Sushant Kaushik8bc7df22014-04-09 17:55:29 +05309168 hddLog(VOS_TRACE_LEVEL_INFO, "%s: device_mode = %s (%d)",
9169 __func__, hdd_device_modetoString(pAdapter->device_mode),
9170 pAdapter->device_mode);
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +05309171
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05309172 status = wlan_hdd_validate_context(pHddCtx);
9173
9174 if (0 != status)
9175 {
9176 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
9177 "%s: HDD context is not valid", __func__);
9178 return status;
9179 }
9180
Siddharth Bhal0c162d02014-05-06 19:50:42 +05309181 if (NULL == pwextBuf)
9182 {
9183 hddLog (VOS_TRACE_LEVEL_ERROR, "%s ERROR: invalid WEXT state\n",
9184 __func__);
9185 return -EIO;
9186 }
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05309187 cfg_param = pHddCtx->cfg_ini;
9188 pScanInfo = &pHddCtx->scan_info;
9189
Jeff Johnson295189b2012-06-20 16:38:30 -07009190#ifdef WLAN_BTAMP_FEATURE
9191 //Scan not supported when AMP traffic is on.
Gopichand Nakkala681989c2013-03-06 22:27:48 -08009192 if (VOS_TRUE == WLANBAP_AmpSessionOn())
Jeff Johnson295189b2012-06-20 16:38:30 -07009193 {
Madan Mohan Koyyalamudifd4e1da2012-11-09 17:50:19 -08009194 hddLog(VOS_TRACE_LEVEL_ERROR,
Jeff Johnson295189b2012-06-20 16:38:30 -07009195 "%s: No scanning when AMP is on", __func__);
9196 return -EOPNOTSUPP;
9197 }
9198#endif
9199 //Scan on any other interface is not supported.
Gopichand Nakkala681989c2013-03-06 22:27:48 -08009200 if (pAdapter->device_mode == WLAN_HDD_SOFTAP)
Jeff Johnson295189b2012-06-20 16:38:30 -07009201 {
Gopichand Nakkala681989c2013-03-06 22:27:48 -08009202 hddLog(VOS_TRACE_LEVEL_ERROR,
Sushant Kaushik8bc7df22014-04-09 17:55:29 +05309203 "%s: Not scanning on device_mode = %s (%d)",
9204 __func__, hdd_device_modetoString(pAdapter->device_mode),
9205 pAdapter->device_mode);
Jeff Johnson295189b2012-06-20 16:38:30 -07009206 return -EOPNOTSUPP;
9207 }
9208
9209 if (TRUE == pScanInfo->mScanPending)
9210 {
Kiet Lamac06e2c2013-10-23 16:25:07 +05309211 if ( MAX_PENDING_LOG > pScanInfo->mScanPendingCounter++ )
9212 {
9213 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: mScanPending is TRUE", __func__);
9214 }
Gopichand Nakkala681989c2013-03-06 22:27:48 -08009215 return -EBUSY;
Jeff Johnson295189b2012-06-20 16:38:30 -07009216 }
9217
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309218 //Don't Allow Scan and return busy if Remain On
Jeff Johnson32d95a32012-09-10 13:15:23 -07009219 //Channel and action frame is pending
9220 //Otherwise Cancel Remain On Channel and allow Scan
9221 //If no action frame pending
Gopichand Nakkala681989c2013-03-06 22:27:48 -08009222 if (0 != wlan_hdd_check_remain_on_channel(pAdapter))
Jeff Johnson32d95a32012-09-10 13:15:23 -07009223 {
Kiet Lamac06e2c2013-10-23 16:25:07 +05309224 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Remain On Channel Pending", __func__);
Jeff Johnson32d95a32012-09-10 13:15:23 -07009225 return -EBUSY;
9226 }
Gopichand Nakkala681989c2013-03-06 22:27:48 -08009227#ifdef FEATURE_WLAN_TDLS
Gopichand Nakkala638ebc72013-03-21 18:04:02 -07009228 /* if tdls disagree scan right now, return immediately.
9229 tdls will schedule the scan when scan is allowed. (return SUCCESS)
9230 or will reject the scan if any TDLS is in progress. (return -EBUSY)
9231 */
9232 status = wlan_hdd_tdls_scan_callback (pAdapter,
9233 wiphy,
9234#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,6,0))
9235 dev,
Gopichand Nakkalac3c42b92013-03-20 19:42:34 -07009236#endif
Gopichand Nakkala638ebc72013-03-21 18:04:02 -07009237 request);
9238 if(status <= 0)
9239 {
Nirav Shah20ac06f2013-12-12 18:14:06 +05309240 if(!status)
9241 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: TDLS in progress."
9242 "scan rejected %d", __func__, status);
9243 else
9244 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: TDLS teardown is ongoing %d",
9245 __func__, status);
9246
Gopichand Nakkala638ebc72013-03-21 18:04:02 -07009247 return status;
Gopichand Nakkala681989c2013-03-06 22:27:48 -08009248 }
9249#endif
Jeff Johnson32d95a32012-09-10 13:15:23 -07009250
Jeff Johnson295189b2012-06-20 16:38:30 -07009251 if (mutex_lock_interruptible(&pHddCtx->tmInfo.tmOperationLock))
9252 {
9253 VOS_TRACE(VOS_MODULE_ID_HDD,VOS_TRACE_LEVEL_ERROR,
Jeff Johnson1250df42012-12-10 14:31:52 -08009254 "%s: Acquire lock fail", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07009255 return -EAGAIN;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309256 }
Jeff Johnson295189b2012-06-20 16:38:30 -07009257 if (TRUE == pHddCtx->tmInfo.tmAction.enterImps)
9258 {
Nirav Shah20ac06f2013-12-12 18:14:06 +05309259 hddLog(VOS_TRACE_LEVEL_ERROR,
Jeff Johnson295189b2012-06-20 16:38:30 -07009260 "%s: MAX TM Level Scan not allowed", __func__);
9261 mutex_unlock(&pHddCtx->tmInfo.tmOperationLock);
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309262 return -EBUSY;
Jeff Johnson295189b2012-06-20 16:38:30 -07009263 }
9264 mutex_unlock(&pHddCtx->tmInfo.tmOperationLock);
9265
Madan Mohan Koyyalamudicfd53742013-01-11 15:29:03 -08009266 /* Check if scan is allowed at this point of time.
9267 */
Ganesh Kondabattiniaeb7b772014-08-11 20:00:36 +05309268 if (hdd_isConnectionInProgress(pHddCtx, VOS_FALSE))
Madan Mohan Koyyalamudicfd53742013-01-11 15:29:03 -08009269 {
9270 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Scan not allowed", __func__);
9271 return -EBUSY;
9272 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309273
Jeff Johnson295189b2012-06-20 16:38:30 -07009274 vos_mem_zero( &scanRequest, sizeof(scanRequest));
9275
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +05309276 hddLog(VOS_TRACE_LEVEL_INFO, "scan request for ssid = %d",
9277 (int)request->n_ssids);
9278
9279 /* Even though supplicant doesn't provide any SSIDs, n_ssids is set to 1.
9280 * Becasue of this, driver is assuming that this is not wildcard scan and so
9281 * is not aging out the scan results.
9282 */
9283 if (request->ssids && '\0' == request->ssids->ssid[0])
Jeff Johnson295189b2012-06-20 16:38:30 -07009284 {
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +05309285 request->n_ssids = 0;
Jeff Johnson295189b2012-06-20 16:38:30 -07009286 }
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +05309287
9288 if ((request->ssids) && (0 < request->n_ssids))
9289 {
9290 tCsrSSIDInfo *SsidInfo;
9291 int j;
9292 scanRequest.SSIDs.numOfSSIDs = request->n_ssids;
9293 /* Allocate num_ssid tCsrSSIDInfo structure */
9294 SsidInfo = scanRequest.SSIDs.SSIDList =
9295 ( tCsrSSIDInfo *)vos_mem_malloc(
9296 request->n_ssids*sizeof(tCsrSSIDInfo));
9297
9298 if(NULL == scanRequest.SSIDs.SSIDList)
9299 {
9300 hddLog(VOS_TRACE_LEVEL_ERROR,
9301 "%s: memory alloc failed SSIDInfo buffer", __func__);
9302 return -ENOMEM;
9303 }
9304
9305 /* copy all the ssid's and their length */
9306 for(j = 0; j < request->n_ssids; j++, SsidInfo++)
9307 {
9308 /* get the ssid length */
9309 SsidInfo->SSID.length = request->ssids[j].ssid_len;
9310 vos_mem_copy(SsidInfo->SSID.ssId, &request->ssids[j].ssid[0],
9311 SsidInfo->SSID.length);
9312 SsidInfo->SSID.ssId[SsidInfo->SSID.length] = '\0';
9313 hddLog(VOS_TRACE_LEVEL_INFO, "SSID number %d: %s",
9314 j, SsidInfo->SSID.ssId);
9315 }
9316 /* set the scan type to active */
9317 scanRequest.scanType = eSIR_ACTIVE_SCAN;
9318 }
9319 else if(WLAN_HDD_P2P_GO == pAdapter->device_mode)
Jeff Johnson295189b2012-06-20 16:38:30 -07009320 {
Siddharth Bhal0c162d02014-05-06 19:50:42 +05309321 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
9322 TRACE_CODE_HDD_CFG80211_SCAN,
9323 pAdapter->sessionId, 0));
Jeff Johnson295189b2012-06-20 16:38:30 -07009324 /* set the scan type to active */
9325 scanRequest.scanType = eSIR_ACTIVE_SCAN;
Jeff Johnson295189b2012-06-20 16:38:30 -07009326 }
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +05309327 else
9328 {
9329 /*Set the scan type to default type, in this case it is ACTIVE*/
9330 scanRequest.scanType = pScanInfo->scan_mode;
9331 }
9332 scanRequest.minChnTime = cfg_param->nActiveMinChnTime;
9333 scanRequest.maxChnTime = cfg_param->nActiveMaxChnTime;
Jeff Johnson295189b2012-06-20 16:38:30 -07009334
9335 /* set BSSType to default type */
9336 scanRequest.BSSType = eCSR_BSS_TYPE_ANY;
9337
9338 /*TODO: scan the requested channels only*/
9339
9340 /*Right now scanning all the channels */
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +05309341 if (MAX_CHANNEL < request->n_channels)
Jeff Johnson295189b2012-06-20 16:38:30 -07009342 {
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +05309343 hddLog(VOS_TRACE_LEVEL_WARN,
9344 "No of Scan Channels exceeded limit: %d", request->n_channels);
9345 request->n_channels = MAX_CHANNEL;
9346 }
9347
9348 hddLog(VOS_TRACE_LEVEL_INFO,
9349 "No of Scan Channels: %d", request->n_channels);
9350
9351
9352 if( request->n_channels )
9353 {
9354 char chList [(request->n_channels*5)+1];
9355 int len;
9356 channelList = vos_mem_malloc( request->n_channels );
9357 if( NULL == channelList )
c_hpothu53512302014-04-15 18:49:53 +05309358 {
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +05309359 hddLog(VOS_TRACE_LEVEL_ERROR,
9360 "%s: memory alloc failed channelList", __func__);
9361 status = -ENOMEM;
9362 goto free_mem;
c_hpothu53512302014-04-15 18:49:53 +05309363 }
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +05309364
9365 for( i = 0, len = 0; i < request->n_channels ; i++ )
9366 {
9367 channelList[i] = request->channels[i]->hw_value;
9368 len += snprintf(chList+len, 5, "%d ", channelList[i]);
9369 }
9370
Nirav Shah20ac06f2013-12-12 18:14:06 +05309371 hddLog(VOS_TRACE_LEVEL_INFO,
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +05309372 "Channel-List: %s ", chList);
9373 }
c_hpothu53512302014-04-15 18:49:53 +05309374
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +05309375 scanRequest.ChannelInfo.numOfChannels = request->n_channels;
9376 scanRequest.ChannelInfo.ChannelList = channelList;
9377
9378 /* set requestType to full scan */
9379 scanRequest.requestType = eCSR_SCAN_REQUEST_FULL_SCAN;
9380
9381 /* Flush the scan results(only p2p beacons) for STA scan and P2P
9382 * search (Flush on both full scan and social scan but not on single
9383 * channel scan).P2P search happens on 3 social channels (1, 6, 11)
9384 */
9385
9386 /* Supplicant does single channel scan after 8-way handshake
9387 * and in that case driver shoudnt flush scan results. If
9388 * driver flushes the scan results here and unfortunately if
9389 * the AP doesnt respond to our probe req then association
9390 * fails which is not desired
9391 */
9392
9393 if( request->n_channels != WLAN_HDD_P2P_SINGLE_CHANNEL_SCAN )
9394 {
9395 hddLog(VOS_TRACE_LEVEL_DEBUG, "Flushing P2P Results");
9396 sme_ScanFlushP2PResult( WLAN_HDD_GET_HAL_CTX(pAdapter),
9397 pAdapter->sessionId );
9398 }
9399
9400 if( request->ie_len )
9401 {
9402 /* save this for future association (join requires this) */
9403 /*TODO: Array needs to be converted to dynamic allocation,
9404 * as multiple ie.s can be sent in cfg80211_scan_request structure
9405 * CR 597966
9406 */
9407 memset( &pScanInfo->scanAddIE, 0, sizeof(pScanInfo->scanAddIE) );
9408 memcpy( pScanInfo->scanAddIE.addIEdata, request->ie, request->ie_len);
9409 pScanInfo->scanAddIE.length = request->ie_len;
9410
9411 if ((WLAN_HDD_INFRA_STATION == pAdapter->device_mode) ||
9412 (WLAN_HDD_P2P_CLIENT == pAdapter->device_mode) ||
9413 (WLAN_HDD_P2P_DEVICE == pAdapter->device_mode))
Jeff Johnson295189b2012-06-20 16:38:30 -07009414 {
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +05309415 if ( request->ie_len <= SIR_MAC_MAX_IE_LENGTH)
Jeff Johnson295189b2012-06-20 16:38:30 -07009416 {
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +05309417 pwextBuf->roamProfile.nAddIEScanLength = request->ie_len;
9418 memcpy( pwextBuf->roamProfile.addIEScan,
9419 request->ie, request->ie_len);
9420 }
9421 else
9422 {
9423 hddLog(VOS_TRACE_LEVEL_ERROR, "Scan Ie length is invalid:"
9424 "%zu", request->ie_len);
Jeff Johnson295189b2012-06-20 16:38:30 -07009425 }
9426
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +05309427 }
9428 scanRequest.uIEFieldLen = pScanInfo->scanAddIE.length;
9429 scanRequest.pIEField = pScanInfo->scanAddIE.addIEdata;
9430
9431 pP2pIe = wlan_hdd_get_p2p_ie_ptr((v_U8_t*)request->ie,
9432 request->ie_len);
9433 if (pP2pIe != NULL)
9434 {
9435#ifdef WLAN_FEATURE_P2P_DEBUG
9436 if (((globalP2PConnectionStatus == P2P_GO_NEG_COMPLETED) ||
9437 (globalP2PConnectionStatus == P2P_GO_NEG_PROCESS)) &&
9438 (WLAN_HDD_P2P_CLIENT == pAdapter->device_mode))
Nirav Shah20ac06f2013-12-12 18:14:06 +05309439 {
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +05309440 globalP2PConnectionStatus = P2P_CLIENT_CONNECTING_STATE_1;
9441 hddLog(VOS_TRACE_LEVEL_ERROR,"[P2P State] Changing state from "
9442 "Go nego completed to Connection is started");
9443 hddLog(VOS_TRACE_LEVEL_ERROR,"[P2P]P2P Scanning is started "
9444 "for 8way Handshake");
Nirav Shah20ac06f2013-12-12 18:14:06 +05309445 }
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +05309446 else if((globalP2PConnectionStatus == P2P_CLIENT_DISCONNECTED_STATE) &&
9447 (WLAN_HDD_P2P_CLIENT == pAdapter->device_mode))
Jeff Johnson295189b2012-06-20 16:38:30 -07009448 {
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +05309449 globalP2PConnectionStatus = P2P_CLIENT_CONNECTING_STATE_2;
9450 hddLog(VOS_TRACE_LEVEL_ERROR,"[P2P State] Changing state from "
9451 "Disconnected state to Connection is started");
9452 hddLog(VOS_TRACE_LEVEL_ERROR,"[P2P]P2P Scanning is started "
9453 "for 4way Handshake");
9454 }
9455#endif
9456
9457 /* no_cck will be set during p2p find to disable 11b rates */
9458 if(TRUE == request->no_cck)
9459 {
9460 hddLog(VOS_TRACE_LEVEL_INFO,
9461 "%s: This is a P2P Search", __func__);
9462 scanRequest.p2pSearch = 1;
9463
9464 if( request->n_channels == WLAN_HDD_P2P_SOCIAL_CHANNELS )
Agarwal Ashish4f616132013-12-30 23:32:50 +05309465 {
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +05309466 /* set requestType to P2P Discovery */
9467 scanRequest.requestType = eCSR_SCAN_P2P_DISCOVERY;
9468 }
9469
9470 /*
9471 Skip Dfs Channel in case of P2P Search
9472 if it is set in ini file
9473 */
9474 if(cfg_param->skipDfsChnlInP2pSearch)
9475 {
9476 scanRequest.skipDfsChnlInP2pSearch = 1;
Agarwal Ashish4f616132013-12-30 23:32:50 +05309477 }
9478 else
9479 {
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +05309480 scanRequest.skipDfsChnlInP2pSearch = 0;
Agarwal Ashish4f616132013-12-30 23:32:50 +05309481 }
Jeff Johnson295189b2012-06-20 16:38:30 -07009482
Agarwal Ashish4f616132013-12-30 23:32:50 +05309483 }
Jeff Johnson295189b2012-06-20 16:38:30 -07009484 }
9485 }
9486
9487 INIT_COMPLETION(pScanInfo->scan_req_completion_event);
9488
Madan Mohan Koyyalamudi9f5a10c2012-09-28 14:46:16 -07009489 /* acquire the wakelock to avoid the apps suspend during the scan. To
9490 * address the following issues.
9491 * 1) Disconnected scenario: we are not allowing the suspend as WLAN is not in
9492 * BMPS/IMPS this result in android trying to suspend aggressively and backing off
9493 * for long time, this result in apps running at full power for long time.
9494 * 2) Connected scenario: If we allow the suspend during the scan, RIVA will
9495 * be stuck in full power because of resume BMPS
9496 */
9497 hdd_prevent_suspend();
Jeff Johnsone7245742012-09-05 17:12:55 -07009498
Nirav Shah20ac06f2013-12-12 18:14:06 +05309499 hddLog(VOS_TRACE_LEVEL_INFO_HIGH,
9500 "requestType %d, scanType %d, minChnTime %d, maxChnTime %d,"
Sushant Kaushik8bc7df22014-04-09 17:55:29 +05309501 "p2pSearch %d, skipDfsChnlInP2pSearch %d",
9502 scanRequest.requestType, scanRequest.scanType,
9503 scanRequest.minChnTime, scanRequest.maxChnTime,
Nirav Shah20ac06f2013-12-12 18:14:06 +05309504 scanRequest.p2pSearch, scanRequest.skipDfsChnlInP2pSearch);
9505
Jeff Johnsone7245742012-09-05 17:12:55 -07009506 status = sme_ScanRequest( WLAN_HDD_GET_HAL_CTX(pAdapter),
Jeff Johnson295189b2012-06-20 16:38:30 -07009507 pAdapter->sessionId, &scanRequest, &scanId,
9508 &hdd_cfg80211_scan_done_callback, dev );
Jeff Johnsone7245742012-09-05 17:12:55 -07009509
Jeff Johnson295189b2012-06-20 16:38:30 -07009510 if (eHAL_STATUS_SUCCESS != status)
9511 {
9512 hddLog(VOS_TRACE_LEVEL_ERROR,
9513 "%s: sme_ScanRequest returned error %d", __func__, status);
9514 complete(&pScanInfo->scan_req_completion_event);
Madan Mohan Koyyalamudi3b230fe2012-10-18 14:46:32 -07009515 if(eHAL_STATUS_RESOURCES == status)
9516 {
Nirav Shah20ac06f2013-12-12 18:14:06 +05309517 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: HO is in progress."
9518 "So defer the scan by informing busy",__func__);
Madan Mohan Koyyalamudi3b230fe2012-10-18 14:46:32 -07009519 status = -EBUSY;
9520 } else {
9521 status = -EIO;
9522 }
Madan Mohan Koyyalamudi9f5a10c2012-09-28 14:46:16 -07009523 hdd_allow_suspend();
Jeff Johnson295189b2012-06-20 16:38:30 -07009524 goto free_mem;
9525 }
9526
9527 pScanInfo->mScanPending = TRUE;
9528 pAdapter->request = request;
9529 pScanInfo->scanId = scanId;
9530
9531 complete(&pScanInfo->scan_req_completion_event);
9532
9533free_mem:
9534 if( scanRequest.SSIDs.SSIDList )
9535 {
9536 vos_mem_free(scanRequest.SSIDs.SSIDList);
9537 }
9538
9539 if( channelList )
9540 vos_mem_free( channelList );
9541
9542 EXIT();
9543
9544 return status;
9545}
9546
Mahesh A Saptasagarfafb7fe2014-05-16 13:19:37 +05309547int wlan_hdd_cfg80211_scan( struct wiphy *wiphy,
9548#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,6,0))
9549 struct net_device *dev,
9550#endif
9551 struct cfg80211_scan_request *request)
9552{
9553 int ret;
9554
9555 vos_ssr_protect(__func__);
9556 ret = __wlan_hdd_cfg80211_scan(wiphy,
9557#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,6,0))
9558 dev,
9559#endif
9560 request);
9561 vos_ssr_unprotect(__func__);
9562
9563 return ret;
9564}
Shailender Karmuchi15cd0672013-05-15 19:50:04 -07009565
9566void hdd_select_cbmode( hdd_adapter_t *pAdapter,v_U8_t operationChannel)
9567{
9568 v_U8_t iniDot11Mode =
9569 (WLAN_HDD_GET_CTX(pAdapter))->cfg_ini->dot11Mode;
9570 eHddDot11Mode hddDot11Mode = iniDot11Mode;
9571
Arun Kumar Khandavalli94a2bb02013-12-28 19:17:25 +05309572 hddLog(LOG1, FL("Channel Bonding Mode Selected is %u"),
9573 iniDot11Mode);
Shailender Karmuchi15cd0672013-05-15 19:50:04 -07009574 switch ( iniDot11Mode )
9575 {
9576 case eHDD_DOT11_MODE_AUTO:
9577 case eHDD_DOT11_MODE_11ac:
9578 case eHDD_DOT11_MODE_11ac_ONLY:
9579#ifdef WLAN_FEATURE_11AC
Abhishek Singh4b1d2352014-08-01 21:59:28 +05309580 if ( sme_IsFeatureSupportedByDriver(DOT11AC) &&
9581 sme_IsFeatureSupportedByFW(DOT11AC) )
9582 hddDot11Mode = eHDD_DOT11_MODE_11ac;
9583 else
9584 hddDot11Mode = eHDD_DOT11_MODE_11n;
Shailender Karmuchi15cd0672013-05-15 19:50:04 -07009585#else
9586 hddDot11Mode = eHDD_DOT11_MODE_11n;
9587#endif
9588 break;
9589 case eHDD_DOT11_MODE_11n:
9590 case eHDD_DOT11_MODE_11n_ONLY:
9591 hddDot11Mode = eHDD_DOT11_MODE_11n;
9592 break;
9593 default:
9594 hddDot11Mode = iniDot11Mode;
9595 break;
9596 }
9597 /* This call decides required channel bonding mode */
9598 sme_SelectCBMode((WLAN_HDD_GET_CTX(pAdapter)->hHal),
9599 hdd_cfg_xlate_to_csr_phy_mode(hddDot11Mode),
9600 operationChannel);
9601}
9602
Jeff Johnson295189b2012-06-20 16:38:30 -07009603/*
9604 * FUNCTION: wlan_hdd_cfg80211_connect_start
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309605 * This function is used to start the association process
Jeff Johnson295189b2012-06-20 16:38:30 -07009606 */
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309607int wlan_hdd_cfg80211_connect_start( hdd_adapter_t *pAdapter,
Jeff Johnson32d95a32012-09-10 13:15:23 -07009608 const u8 *ssid, size_t ssid_len, const u8 *bssid, u8 operatingChannel)
Jeff Johnson295189b2012-06-20 16:38:30 -07009609{
9610 int status = 0;
9611 hdd_wext_state_t *pWextState;
Yue Mae36e3552014-03-05 17:06:20 -08009612 hdd_context_t *pHddCtx;
Jeff Johnson295189b2012-06-20 16:38:30 -07009613 v_U32_t roamId;
9614 tCsrRoamProfile *pRoamProfile;
Jeff Johnson295189b2012-06-20 16:38:30 -07009615 eCsrAuthType RSNAuthType;
9616
9617 ENTER();
9618
9619 pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
Yue Mae36e3552014-03-05 17:06:20 -08009620 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
9621
9622 status = wlan_hdd_validate_context(pHddCtx);
9623 if (status)
9624 {
9625 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
9626 "%s: HDD context is not valid!", __func__);
9627 return status;
9628 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309629
Jeff Johnson295189b2012-06-20 16:38:30 -07009630 if (SIR_MAC_MAX_SSID_LENGTH < ssid_len)
9631 {
9632 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: wrong SSID len", __func__);
9633 return -EINVAL;
9634 }
9635
9636 pRoamProfile = &pWextState->roamProfile;
9637
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309638 if (pRoamProfile)
Jeff Johnson295189b2012-06-20 16:38:30 -07009639 {
Jeff Johnsone7245742012-09-05 17:12:55 -07009640 hdd_station_ctx_t *pHddStaCtx;
9641 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
Jeff Johnson295189b2012-06-20 16:38:30 -07009642
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309643 if (HDD_WMM_USER_MODE_NO_QOS ==
Jeff Johnson295189b2012-06-20 16:38:30 -07009644 (WLAN_HDD_GET_CTX(pAdapter))->cfg_ini->WmmMode)
9645 {
9646 /*QoS not enabled in cfg file*/
9647 pRoamProfile->uapsd_mask = 0;
9648 }
9649 else
9650 {
9651 /*QoS enabled, update uapsd mask from cfg file*/
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309652 pRoamProfile->uapsd_mask =
Jeff Johnson295189b2012-06-20 16:38:30 -07009653 (WLAN_HDD_GET_CTX(pAdapter))->cfg_ini->UapsdMask;
9654 }
9655
9656 pRoamProfile->SSIDs.numOfSSIDs = 1;
9657 pRoamProfile->SSIDs.SSIDList->SSID.length = ssid_len;
9658 vos_mem_zero(pRoamProfile->SSIDs.SSIDList->SSID.ssId,
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309659 sizeof(pRoamProfile->SSIDs.SSIDList->SSID.ssId));
Jeff Johnson295189b2012-06-20 16:38:30 -07009660 vos_mem_copy((void *)(pRoamProfile->SSIDs.SSIDList->SSID.ssId),
9661 ssid, ssid_len);
9662
9663 if (bssid)
9664 {
9665 pRoamProfile->BSSIDs.numOfBSSIDs = 1;
9666 vos_mem_copy((void *)(pRoamProfile->BSSIDs.bssid), bssid,
9667 WNI_CFG_BSSID_LEN);
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309668 /* Save BSSID in seperate variable as well, as RoamProfile
9669 BSSID is getting zeroed out in the association process. And in
Jeff Johnson295189b2012-06-20 16:38:30 -07009670 case of join failure we should send valid BSSID to supplicant
9671 */
9672 vos_mem_copy((void *)(pWextState->req_bssId), bssid,
9673 WNI_CFG_BSSID_LEN);
9674 }
Dhanashri Atre51981c62013-06-13 11:47:57 -07009675 else
9676 {
9677 vos_mem_zero((void *)(pRoamProfile->BSSIDs.bssid),WNI_CFG_BSSID_LEN);
9678 }
Jeff Johnson295189b2012-06-20 16:38:30 -07009679
Arun Kumar Khandavalli94a2bb02013-12-28 19:17:25 +05309680 hddLog(LOG1, FL("Connect to SSID: %s opertating Channel: %u"),
9681 pRoamProfile->SSIDs.SSIDList->SSID.ssId, operatingChannel);
Jeff Johnson295189b2012-06-20 16:38:30 -07009682 if ((IW_AUTH_WPA_VERSION_WPA == pWextState->wpaVersion) ||
9683 (IW_AUTH_WPA_VERSION_WPA2 == pWextState->wpaVersion))
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309684 {
Jeff Johnson295189b2012-06-20 16:38:30 -07009685 /*set gen ie*/
9686 hdd_SetGENIEToCsr(pAdapter, &RSNAuthType);
9687 /*set auth*/
9688 hdd_set_csr_auth_type(pAdapter, RSNAuthType);
9689 }
Jeff Johnson295189b2012-06-20 16:38:30 -07009690#ifdef FEATURE_WLAN_WAPI
9691 if (pAdapter->wapi_info.nWapiMode)
9692 {
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07009693 hddLog(LOG1, "%s: Setting WAPI AUTH Type and Encryption Mode values", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07009694 switch (pAdapter->wapi_info.wapiAuthMode)
9695 {
9696 case WAPI_AUTH_MODE_PSK:
9697 {
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07009698 hddLog(LOG1, "%s: WAPI AUTH TYPE: PSK: %d", __func__,
Jeff Johnson295189b2012-06-20 16:38:30 -07009699 pAdapter->wapi_info.wapiAuthMode);
9700 pRoamProfile->AuthType.authType[0] = eCSR_AUTH_TYPE_WAPI_WAI_PSK;
9701 break;
9702 }
9703 case WAPI_AUTH_MODE_CERT:
9704 {
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07009705 hddLog(LOG1, "%s: WAPI AUTH TYPE: CERT: %d", __func__,
Jeff Johnson295189b2012-06-20 16:38:30 -07009706 pAdapter->wapi_info.wapiAuthMode);
9707 pRoamProfile->AuthType.authType[0] = eCSR_AUTH_TYPE_WAPI_WAI_CERTIFICATE;
9708 break;
9709 }
9710 } // End of switch
9711 if ( pAdapter->wapi_info.wapiAuthMode == WAPI_AUTH_MODE_PSK ||
9712 pAdapter->wapi_info.wapiAuthMode == WAPI_AUTH_MODE_CERT)
9713 {
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07009714 hddLog(LOG1, "%s: WAPI PAIRWISE/GROUP ENCRYPTION: WPI", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07009715 pRoamProfile->AuthType.numEntries = 1;
9716 pRoamProfile->EncryptionType.numEntries = 1;
9717 pRoamProfile->EncryptionType.encryptionType[0] = eCSR_ENCRYPT_TYPE_WPI;
9718 pRoamProfile->mcEncryptionType.numEntries = 1;
9719 pRoamProfile->mcEncryptionType.encryptionType[0] = eCSR_ENCRYPT_TYPE_WPI;
9720 }
9721 }
9722#endif /* FEATURE_WLAN_WAPI */
Gopichand Nakkala870cbae2013-03-15 21:16:09 +05309723#ifdef WLAN_FEATURE_GTK_OFFLOAD
Gopichand Nakkalad36ee622013-05-07 14:13:27 +05309724 /* Initializing gtkOffloadReqParams */
Gopichand Nakkala870cbae2013-03-15 21:16:09 +05309725 if ((WLAN_HDD_INFRA_STATION == pAdapter->device_mode) ||
9726 (WLAN_HDD_P2P_CLIENT == pAdapter->device_mode))
9727 {
Gopichand Nakkalad36ee622013-05-07 14:13:27 +05309728 memset(&pHddStaCtx->gtkOffloadReqParams, 0,
9729 sizeof (tSirGtkOffloadParams));
9730 pHddStaCtx->gtkOffloadReqParams.ulFlags = GTK_OFFLOAD_DISABLE;
Gopichand Nakkala870cbae2013-03-15 21:16:09 +05309731 }
9732#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07009733 pRoamProfile->csrPersona = pAdapter->device_mode;
9734
Jeff Johnson32d95a32012-09-10 13:15:23 -07009735 if( operatingChannel )
9736 {
9737 pRoamProfile->ChannelInfo.ChannelList = &operatingChannel;
9738 pRoamProfile->ChannelInfo.numOfChannels = 1;
9739 }
Chet Lanctot186b5732013-03-18 10:26:30 -07009740 else
9741 {
9742 pRoamProfile->ChannelInfo.ChannelList = NULL;
9743 pRoamProfile->ChannelInfo.numOfChannels = 0;
9744 }
Shailender Karmuchi15cd0672013-05-15 19:50:04 -07009745 if ( (WLAN_HDD_IBSS == pAdapter->device_mode) && operatingChannel)
9746 {
9747 hdd_select_cbmode(pAdapter,operatingChannel);
9748 }
Arun Kumar Khandavalli94a2bb02013-12-28 19:17:25 +05309749
Madan Mohan Koyyalamudi42dcd162012-12-03 16:34:04 -08009750 /* change conn_state to connecting before sme_RoamConnect(), because sme_RoamConnect()
9751 * has a direct path to call hdd_smeRoamCallback(), which will change the conn_state
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309752 * If direct path, conn_state will be accordingly changed to NotConnected or Associated
Madan Mohan Koyyalamudi42dcd162012-12-03 16:34:04 -08009753 * by either hdd_AssociationCompletionHandler() or hdd_DisConnectHandler() in sme_RoamCallback()
Madan Mohan Koyyalamudidf86c422012-12-04 17:03:44 -08009754 * if sme_RomConnect is to be queued, Connecting state will remain until it is completed.
9755 */
Gopichand Nakkalaa3c8fb62013-06-21 15:36:42 +05309756 if (WLAN_HDD_INFRA_STATION == pAdapter->device_mode ||
9757 WLAN_HDD_P2P_CLIENT == pAdapter->device_mode)
Abhishek Singhf4669da2014-05-26 15:07:49 +05309758 {
9759 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
9760 "%s: Set HDD connState to eConnectionState_Connecting",
9761 __func__);
Madan Mohan Koyyalamudidf86c422012-12-04 17:03:44 -08009762 hdd_connSetConnectionState(WLAN_HDD_GET_STATION_CTX_PTR(pAdapter),
9763 eConnectionState_Connecting);
Abhishek Singhf4669da2014-05-26 15:07:49 +05309764 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309765 status = sme_RoamConnect( WLAN_HDD_GET_HAL_CTX(pAdapter),
Jeff Johnson295189b2012-06-20 16:38:30 -07009766 pAdapter->sessionId, pRoamProfile, &roamId);
9767
Gopichand Nakkalaa3c8fb62013-06-21 15:36:42 +05309768 if ((eHAL_STATUS_SUCCESS != status) &&
9769 (WLAN_HDD_INFRA_STATION == pAdapter->device_mode ||
9770 WLAN_HDD_P2P_CLIENT == pAdapter->device_mode))
Madan Mohan Koyyalamudid5acbf52012-11-28 01:45:08 +05309771
9772 {
Madan Mohan Koyyalamudi42dcd162012-12-03 16:34:04 -08009773 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: sme_RoamConnect (session %d) failed with "
9774 "status %d. -> NotConnected", __func__, pAdapter->sessionId, status);
9775 /* change back to NotAssociated */
Madan Mohan Koyyalamudid5acbf52012-11-28 01:45:08 +05309776 hdd_connSetConnectionState(WLAN_HDD_GET_STATION_CTX_PTR(pAdapter),
Madan Mohan Koyyalamudi42dcd162012-12-03 16:34:04 -08009777 eConnectionState_NotConnected);
Madan Mohan Koyyalamudid5acbf52012-11-28 01:45:08 +05309778 }
Madan Mohan Koyyalamudidf86c422012-12-04 17:03:44 -08009779
9780 pRoamProfile->ChannelInfo.ChannelList = NULL;
9781 pRoamProfile->ChannelInfo.numOfChannels = 0;
9782
Jeff Johnson295189b2012-06-20 16:38:30 -07009783 }
9784 else
9785 {
9786 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: No valid Roam profile", __func__);
9787 return -EINVAL;
9788 }
Madan Mohan Koyyalamudifd4e1da2012-11-09 17:50:19 -08009789 EXIT();
Jeff Johnson295189b2012-06-20 16:38:30 -07009790 return status;
9791}
9792
9793/*
9794 * FUNCTION: wlan_hdd_set_cfg80211_auth_type
9795 * This function is used to set the authentication type (OPEN/SHARED).
9796 *
9797 */
9798static int wlan_hdd_cfg80211_set_auth_type(hdd_adapter_t *pAdapter,
9799 enum nl80211_auth_type auth_type)
9800{
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309801 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
Jeff Johnson295189b2012-06-20 16:38:30 -07009802 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
9803
9804 ENTER();
9805
9806 /*set authentication type*/
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309807 switch (auth_type)
Jeff Johnson295189b2012-06-20 16:38:30 -07009808 {
Jeff Johnson295189b2012-06-20 16:38:30 -07009809 case NL80211_AUTHTYPE_AUTOMATIC:
Gopichand Nakkala29149562013-05-10 21:43:41 +05309810 hddLog(VOS_TRACE_LEVEL_INFO,
9811 "%s: set authentication type to AUTOSWITCH", __func__);
9812 pHddStaCtx->conn_info.authType = eCSR_AUTH_TYPE_AUTOSWITCH;
9813 break;
9814
9815 case NL80211_AUTHTYPE_OPEN_SYSTEM:
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -07009816#ifdef WLAN_FEATURE_VOWIFI_11R
9817 case NL80211_AUTHTYPE_FT:
9818#endif /* WLAN_FEATURE_VOWIFI_11R */
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309819 hddLog(VOS_TRACE_LEVEL_INFO,
Jeff Johnson295189b2012-06-20 16:38:30 -07009820 "%s: set authentication type to OPEN", __func__);
9821 pHddStaCtx->conn_info.authType = eCSR_AUTH_TYPE_OPEN_SYSTEM;
9822 break;
9823
9824 case NL80211_AUTHTYPE_SHARED_KEY:
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309825 hddLog(VOS_TRACE_LEVEL_INFO,
Jeff Johnson295189b2012-06-20 16:38:30 -07009826 "%s: set authentication type to SHARED", __func__);
9827 pHddStaCtx->conn_info.authType = eCSR_AUTH_TYPE_SHARED_KEY;
9828 break;
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08009829#ifdef FEATURE_WLAN_ESE
Jeff Johnson295189b2012-06-20 16:38:30 -07009830 case NL80211_AUTHTYPE_NETWORK_EAP:
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309831 hddLog(VOS_TRACE_LEVEL_INFO,
Jeff Johnson295189b2012-06-20 16:38:30 -07009832 "%s: set authentication type to CCKM WPA", __func__);
9833 pHddStaCtx->conn_info.authType = eCSR_AUTH_TYPE_CCKM_WPA;//eCSR_AUTH_TYPE_CCKM_RSN needs to be handled as well if required.
9834 break;
9835#endif
9836
9837
9838 default:
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309839 hddLog(VOS_TRACE_LEVEL_ERROR,
9840 "%s: Unsupported authentication type %d", __func__,
Jeff Johnson295189b2012-06-20 16:38:30 -07009841 auth_type);
9842 pHddStaCtx->conn_info.authType = eCSR_AUTH_TYPE_UNKNOWN;
9843 return -EINVAL;
9844 }
9845
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309846 pWextState->roamProfile.AuthType.authType[0] =
Jeff Johnson295189b2012-06-20 16:38:30 -07009847 pHddStaCtx->conn_info.authType;
9848 return 0;
9849}
9850
9851/*
9852 * FUNCTION: wlan_hdd_set_akm_suite
9853 * This function is used to set the key mgmt type(PSK/8021x).
9854 *
9855 */
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309856static int wlan_hdd_set_akm_suite( hdd_adapter_t *pAdapter,
Jeff Johnson295189b2012-06-20 16:38:30 -07009857 u32 key_mgmt
9858 )
9859{
9860 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
9861 ENTER();
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309862
Jeff Johnson295189b2012-06-20 16:38:30 -07009863 /*set key mgmt type*/
9864 switch(key_mgmt)
9865 {
9866 case WLAN_AKM_SUITE_PSK:
Gopichand Nakkala356fb102013-03-06 12:34:04 +05309867#ifdef WLAN_FEATURE_VOWIFI_11R
9868 case WLAN_AKM_SUITE_FT_PSK:
9869#endif
9870 hddLog(VOS_TRACE_LEVEL_INFO, "%s: setting key mgmt type to PSK",
Jeff Johnson295189b2012-06-20 16:38:30 -07009871 __func__);
9872 pWextState->authKeyMgmt |= IW_AUTH_KEY_MGMT_PSK;
9873 break;
9874
9875 case WLAN_AKM_SUITE_8021X:
Gopichand Nakkala356fb102013-03-06 12:34:04 +05309876#ifdef WLAN_FEATURE_VOWIFI_11R
9877 case WLAN_AKM_SUITE_FT_8021X:
9878#endif
9879 hddLog(VOS_TRACE_LEVEL_INFO, "%s: setting key mgmt type to 8021x",
Jeff Johnson295189b2012-06-20 16:38:30 -07009880 __func__);
9881 pWextState->authKeyMgmt |= IW_AUTH_KEY_MGMT_802_1X;
9882 break;
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08009883#ifdef FEATURE_WLAN_ESE
Jeff Johnson295189b2012-06-20 16:38:30 -07009884#define WLAN_AKM_SUITE_CCKM 0x00409600 /* Should be in ieee802_11_defs.h */
9885#define IW_AUTH_KEY_MGMT_CCKM 8 /* Should be in linux/wireless.h */
9886 case WLAN_AKM_SUITE_CCKM:
9887 hddLog(VOS_TRACE_LEVEL_INFO, "%s: setting key mgmt type to CCKM",
9888 __func__);
9889 pWextState->authKeyMgmt |= IW_AUTH_KEY_MGMT_CCKM;
9890 break;
9891#endif
Leela Venkata Kiran Kumar Reddy Chiralae208a832014-04-27 22:34:25 -07009892#ifndef WLAN_AKM_SUITE_OSEN
9893#define WLAN_AKM_SUITE_OSEN 0x506f9a01 /* Should be in ieee802_11_defs.h */
9894 case WLAN_AKM_SUITE_OSEN:
9895 hddLog(VOS_TRACE_LEVEL_INFO, "%s: setting key mgmt type to OSEN",
9896 __func__);
9897 pWextState->authKeyMgmt |= IW_AUTH_KEY_MGMT_802_1X;
9898 break;
9899#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07009900
9901 default:
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309902 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Unsupported key mgmt type %d",
Jeff Johnson295189b2012-06-20 16:38:30 -07009903 __func__, key_mgmt);
9904 return -EINVAL;
9905
9906 }
9907 return 0;
9908}
9909
9910/*
9911 * FUNCTION: wlan_hdd_cfg80211_set_cipher
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309912 * This function is used to set the encryption type
Jeff Johnson295189b2012-06-20 16:38:30 -07009913 * (NONE/WEP40/WEP104/TKIP/CCMP).
9914 */
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309915static int wlan_hdd_cfg80211_set_cipher( hdd_adapter_t *pAdapter,
9916 u32 cipher,
Jeff Johnson295189b2012-06-20 16:38:30 -07009917 bool ucast
9918 )
9919{
9920 eCsrEncryptionType encryptionType = eCSR_ENCRYPT_TYPE_NONE;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309921 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
Jeff Johnson295189b2012-06-20 16:38:30 -07009922 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
9923
9924 ENTER();
9925
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309926 if (!cipher)
Jeff Johnson295189b2012-06-20 16:38:30 -07009927 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309928 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: received cipher %d - considering none",
Jeff Johnson295189b2012-06-20 16:38:30 -07009929 __func__, cipher);
9930 encryptionType = eCSR_ENCRYPT_TYPE_NONE;
9931 }
9932 else
9933 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309934
Jeff Johnson295189b2012-06-20 16:38:30 -07009935 /*set encryption method*/
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309936 switch (cipher)
Jeff Johnson295189b2012-06-20 16:38:30 -07009937 {
9938 case IW_AUTH_CIPHER_NONE:
9939 encryptionType = eCSR_ENCRYPT_TYPE_NONE;
9940 break;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309941
Jeff Johnson295189b2012-06-20 16:38:30 -07009942 case WLAN_CIPHER_SUITE_WEP40:
Gopichand Nakkala29149562013-05-10 21:43:41 +05309943 encryptionType = eCSR_ENCRYPT_TYPE_WEP40;
Jeff Johnson295189b2012-06-20 16:38:30 -07009944 break;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309945
Jeff Johnson295189b2012-06-20 16:38:30 -07009946 case WLAN_CIPHER_SUITE_WEP104:
Gopichand Nakkala29149562013-05-10 21:43:41 +05309947 encryptionType = eCSR_ENCRYPT_TYPE_WEP104;
Jeff Johnson295189b2012-06-20 16:38:30 -07009948 break;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309949
Jeff Johnson295189b2012-06-20 16:38:30 -07009950 case WLAN_CIPHER_SUITE_TKIP:
9951 encryptionType = eCSR_ENCRYPT_TYPE_TKIP;
9952 break;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309953
Jeff Johnson295189b2012-06-20 16:38:30 -07009954 case WLAN_CIPHER_SUITE_CCMP:
9955 encryptionType = eCSR_ENCRYPT_TYPE_AES;
9956 break;
9957#ifdef FEATURE_WLAN_WAPI
9958 case WLAN_CIPHER_SUITE_SMS4:
9959 encryptionType = eCSR_ENCRYPT_TYPE_WPI;
9960 break;
9961#endif
9962
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08009963#ifdef FEATURE_WLAN_ESE
Jeff Johnson295189b2012-06-20 16:38:30 -07009964 case WLAN_CIPHER_SUITE_KRK:
9965 encryptionType = eCSR_ENCRYPT_TYPE_KRK;
9966 break;
9967#endif
9968 default:
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309969 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Unsupported cipher type %d",
Jeff Johnson295189b2012-06-20 16:38:30 -07009970 __func__, cipher);
9971 return -EOPNOTSUPP;
9972 }
9973 }
9974
9975 if (ucast)
9976 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309977 hddLog(VOS_TRACE_LEVEL_INFO, "%s: setting unicast cipher type to %d",
Jeff Johnson295189b2012-06-20 16:38:30 -07009978 __func__, encryptionType);
9979 pHddStaCtx->conn_info.ucEncryptionType = encryptionType;
9980 pWextState->roamProfile.EncryptionType.numEntries = 1;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309981 pWextState->roamProfile.EncryptionType.encryptionType[0] =
Jeff Johnson295189b2012-06-20 16:38:30 -07009982 encryptionType;
9983 }
9984 else
9985 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309986 hddLog(VOS_TRACE_LEVEL_INFO, "%s: setting mcast cipher type to %d",
Jeff Johnson295189b2012-06-20 16:38:30 -07009987 __func__, encryptionType);
9988 pHddStaCtx->conn_info.mcEncryptionType = encryptionType;
9989 pWextState->roamProfile.mcEncryptionType.numEntries = 1;
9990 pWextState->roamProfile.mcEncryptionType.encryptionType[0] = encryptionType;
9991 }
9992
9993 return 0;
9994}
9995
9996
9997/*
9998 * FUNCTION: wlan_hdd_cfg80211_set_ie
9999 * This function is used to parse WPA/RSN IE's.
10000 */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010001int wlan_hdd_cfg80211_set_ie( hdd_adapter_t *pAdapter,
10002 u8 *ie,
Jeff Johnson295189b2012-06-20 16:38:30 -070010003 size_t ie_len
10004 )
10005{
10006 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
10007 u8 *genie = ie;
10008 v_U16_t remLen = ie_len;
10009#ifdef FEATURE_WLAN_WAPI
10010 v_U32_t akmsuite[MAX_NUM_AKM_SUITES];
10011 u16 *tmp;
10012 v_U16_t akmsuiteCount;
10013 int *akmlist;
10014#endif
10015 ENTER();
10016
10017 /* clear previous assocAddIE */
10018 pWextState->assocAddIE.length = 0;
10019 pWextState->roamProfile.bWPSAssociation = VOS_FALSE;
Leela Venkata Kiran Kumar Reddy Chiralaf257bef2014-04-11 18:48:12 -070010020 pWextState->roamProfile.bOSENAssociation = VOS_FALSE;
Jeff Johnson295189b2012-06-20 16:38:30 -070010021
10022 while (remLen >= 2)
10023 {
10024 v_U16_t eLen = 0;
10025 v_U8_t elementId;
10026 elementId = *genie++;
10027 eLen = *genie++;
10028 remLen -= 2;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010029
Arif Hussain6d2a3322013-11-17 19:50:10 -080010030 hddLog(VOS_TRACE_LEVEL_INFO, "%s: IE[0x%X], LEN[%d]",
Jeff Johnson295189b2012-06-20 16:38:30 -070010031 __func__, elementId, eLen);
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010032
10033 switch ( elementId )
Jeff Johnson295189b2012-06-20 16:38:30 -070010034 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010035 case DOT11F_EID_WPA:
Madan Mohan Koyyalamudief3b66e2012-10-11 14:29:42 -070010036 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 -070010037 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010038 hddLog(VOS_TRACE_LEVEL_ERROR,
Jeff Johnson295189b2012-06-20 16:38:30 -070010039 "%s: Invalid WPA IE", __func__);
10040 return -EINVAL;
10041 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010042 else if (0 == memcmp(&genie[0], "\x00\x50\xf2\x04", 4))
Jeff Johnson295189b2012-06-20 16:38:30 -070010043 {
10044 v_U16_t curAddIELen = pWextState->assocAddIE.length;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010045 hddLog (VOS_TRACE_LEVEL_INFO, "%s Set WPS IE(len %d)",
Jeff Johnson295189b2012-06-20 16:38:30 -070010046 __func__, eLen + 2);
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010047
Jeff Johnson295189b2012-06-20 16:38:30 -070010048 if( SIR_MAC_MAX_IE_LENGTH < (pWextState->assocAddIE.length + eLen) )
10049 {
Jeff Johnson902c9832012-12-10 14:28:09 -080010050 hddLog(VOS_TRACE_LEVEL_FATAL, "Cannot accommodate assocAddIE. "
10051 "Need bigger buffer space");
Jeff Johnson295189b2012-06-20 16:38:30 -070010052 VOS_ASSERT(0);
10053 return -ENOMEM;
10054 }
10055 // WSC IE is saved to Additional IE ; it should be accumulated to handle WPS IE + P2P IE
10056 memcpy( pWextState->assocAddIE.addIEdata + curAddIELen, genie - 2, eLen + 2);
10057 pWextState->assocAddIE.length += eLen + 2;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010058
Jeff Johnson295189b2012-06-20 16:38:30 -070010059 pWextState->roamProfile.bWPSAssociation = VOS_TRUE;
10060 pWextState->roamProfile.pAddIEAssoc = pWextState->assocAddIE.addIEdata;
10061 pWextState->roamProfile.nAddIEAssocLength = pWextState->assocAddIE.length;
10062 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010063 else if (0 == memcmp(&genie[0], "\x00\x50\xf2", 3))
10064 {
Jeff Johnson295189b2012-06-20 16:38:30 -070010065 hddLog (VOS_TRACE_LEVEL_INFO, "%s Set WPA IE (len %d)",__func__, eLen + 2);
10066 memset( pWextState->WPARSNIE, 0, MAX_WPA_RSN_IE_LEN );
10067 memcpy( pWextState->WPARSNIE, genie - 2, (eLen + 2) /*ie_len*/);
10068 pWextState->roamProfile.pWPAReqIE = pWextState->WPARSNIE;
10069 pWextState->roamProfile.nWPAReqIELength = eLen + 2;//ie_len;
10070 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010071 else if ( (0 == memcmp(&genie[0], P2P_OUI_TYPE,
Kiet Lam8da98992013-11-21 15:59:07 +053010072 P2P_OUI_TYPE_SIZE)))
Jeff Johnson295189b2012-06-20 16:38:30 -070010073 {
10074 v_U16_t curAddIELen = pWextState->assocAddIE.length;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010075 hddLog (VOS_TRACE_LEVEL_INFO, "%s Set P2P IE(len %d)",
Jeff Johnson295189b2012-06-20 16:38:30 -070010076 __func__, eLen + 2);
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010077
Jeff Johnson295189b2012-06-20 16:38:30 -070010078 if( SIR_MAC_MAX_IE_LENGTH < (pWextState->assocAddIE.length + eLen) )
10079 {
Jeff Johnson902c9832012-12-10 14:28:09 -080010080 hddLog(VOS_TRACE_LEVEL_FATAL, "Cannot accommodate assocAddIE "
10081 "Need bigger buffer space");
Jeff Johnson295189b2012-06-20 16:38:30 -070010082 VOS_ASSERT(0);
10083 return -ENOMEM;
10084 }
10085 // P2P IE is saved to Additional IE ; it should be accumulated to handle WPS IE + P2P IE
10086 memcpy( pWextState->assocAddIE.addIEdata + curAddIELen, genie - 2, eLen + 2);
10087 pWextState->assocAddIE.length += eLen + 2;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010088
Jeff Johnson295189b2012-06-20 16:38:30 -070010089 pWextState->roamProfile.pAddIEAssoc = pWextState->assocAddIE.addIEdata;
10090 pWextState->roamProfile.nAddIEAssocLength = pWextState->assocAddIE.length;
10091 }
Jeff Johnson295189b2012-06-20 16:38:30 -070010092#ifdef WLAN_FEATURE_WFD
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010093 else if ( (0 == memcmp(&genie[0], WFD_OUI_TYPE,
10094 WFD_OUI_TYPE_SIZE))
Jeff Johnson295189b2012-06-20 16:38:30 -070010095 /*Consider WFD IE, only for P2P Client */
10096 && (WLAN_HDD_P2P_CLIENT == pAdapter->device_mode) )
10097 {
10098 v_U16_t curAddIELen = pWextState->assocAddIE.length;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010099 hddLog (VOS_TRACE_LEVEL_INFO, "%s Set WFD IE(len %d)",
Jeff Johnson295189b2012-06-20 16:38:30 -070010100 __func__, eLen + 2);
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010101
Jeff Johnson295189b2012-06-20 16:38:30 -070010102 if( SIR_MAC_MAX_IE_LENGTH < (pWextState->assocAddIE.length + eLen) )
10103 {
Jeff Johnson902c9832012-12-10 14:28:09 -080010104 hddLog(VOS_TRACE_LEVEL_FATAL, "Cannot accommodate assocAddIE "
10105 "Need bigger buffer space");
Jeff Johnson295189b2012-06-20 16:38:30 -070010106 VOS_ASSERT(0);
10107 return -ENOMEM;
10108 }
10109 // WFD IE is saved to Additional IE ; it should be accumulated to handle
10110 // WPS IE + P2P IE + WFD IE
10111 memcpy( pWextState->assocAddIE.addIEdata + curAddIELen, genie - 2, eLen + 2);
10112 pWextState->assocAddIE.length += eLen + 2;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010113
Jeff Johnson295189b2012-06-20 16:38:30 -070010114 pWextState->roamProfile.pAddIEAssoc = pWextState->assocAddIE.addIEdata;
10115 pWextState->roamProfile.nAddIEAssocLength = pWextState->assocAddIE.length;
10116 }
10117#endif
Madan Mohan Koyyalamudief3b66e2012-10-11 14:29:42 -070010118 /* Appending HS 2.0 Indication Element in Assiciation Request */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010119 else if ( (0 == memcmp(&genie[0], HS20_OUI_TYPE,
Madan Mohan Koyyalamudi1bed5982012-10-22 14:38:06 -070010120 HS20_OUI_TYPE_SIZE)) )
10121 {
10122 v_U16_t curAddIELen = pWextState->assocAddIE.length;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010123 hddLog (VOS_TRACE_LEVEL_INFO, "%s Set HS20 IE(len %d)",
Madan Mohan Koyyalamudi1bed5982012-10-22 14:38:06 -070010124 __func__, eLen + 2);
Madan Mohan Koyyalamudief3b66e2012-10-11 14:29:42 -070010125
Madan Mohan Koyyalamudi1bed5982012-10-22 14:38:06 -070010126 if( SIR_MAC_MAX_IE_LENGTH < (pWextState->assocAddIE.length + eLen) )
10127 {
Jeff Johnson902c9832012-12-10 14:28:09 -080010128 hddLog(VOS_TRACE_LEVEL_FATAL, "Cannot accommodate assocAddIE "
10129 "Need bigger buffer space");
Madan Mohan Koyyalamudi1bed5982012-10-22 14:38:06 -070010130 VOS_ASSERT(0);
10131 return -ENOMEM;
10132 }
10133 memcpy( pWextState->assocAddIE.addIEdata + curAddIELen, genie - 2, eLen + 2);
10134 pWextState->assocAddIE.length += eLen + 2;
Madan Mohan Koyyalamudief3b66e2012-10-11 14:29:42 -070010135
Madan Mohan Koyyalamudi1bed5982012-10-22 14:38:06 -070010136 pWextState->roamProfile.pAddIEAssoc = pWextState->assocAddIE.addIEdata;
10137 pWextState->roamProfile.nAddIEAssocLength = pWextState->assocAddIE.length;
10138 }
Leela Venkata Kiran Kumar Reddy Chiralaf257bef2014-04-11 18:48:12 -070010139 /* Appending OSEN Information Element in Assiciation Request */
10140 else if ( (0 == memcmp(&genie[0], OSEN_OUI_TYPE,
10141 OSEN_OUI_TYPE_SIZE)) )
10142 {
10143 v_U16_t curAddIELen = pWextState->assocAddIE.length;
10144 hddLog (VOS_TRACE_LEVEL_INFO, "%s Set OSEN IE(len %d)",
10145 __func__, eLen + 2);
Madan Mohan Koyyalamudief3b66e2012-10-11 14:29:42 -070010146
Leela Venkata Kiran Kumar Reddy Chiralaf257bef2014-04-11 18:48:12 -070010147 if( SIR_MAC_MAX_IE_LENGTH < (pWextState->assocAddIE.length + eLen) )
10148 {
10149 hddLog(VOS_TRACE_LEVEL_FATAL, "Cannot accommodate assocAddIE "
10150 "Need bigger buffer space");
10151 VOS_ASSERT(0);
10152 return -ENOMEM;
10153 }
10154 memcpy( pWextState->assocAddIE.addIEdata + curAddIELen, genie - 2, eLen + 2);
10155 pWextState->assocAddIE.length += eLen + 2;
10156
10157 pWextState->roamProfile.bOSENAssociation = VOS_TRUE;
10158 pWextState->roamProfile.pAddIEAssoc = pWextState->assocAddIE.addIEdata;
10159 pWextState->roamProfile.nAddIEAssocLength = pWextState->assocAddIE.length;
10160 }
10161
10162 break;
Praveen Kumar Sirisilla7d68b7b2013-09-22 14:01:42 -070010163 if (WLAN_HDD_IBSS == pAdapter->device_mode) {
10164
10165 /* populating as ADDIE in beacon frames */
10166 if (ccmCfgSetStr(WLAN_HDD_GET_HAL_CTX(pAdapter),
10167 WNI_CFG_PROBE_RSP_BCN_ADDNIE_DATA, genie - 2, eLen + 2,
10168 NULL, eANI_BOOLEAN_FALSE)== eHAL_STATUS_SUCCESS)
10169 {
10170 if (ccmCfgSetInt(WLAN_HDD_GET_HAL_CTX(pAdapter),
10171 WNI_CFG_PROBE_RSP_BCN_ADDNIE_FLAG, 1,NULL,
10172 eANI_BOOLEAN_FALSE) == eHAL_STATUS_FAILURE)
10173 {
10174 hddLog(LOGE,
10175 "Coldn't pass "
10176 "WNI_CFG_PROBE_RSP_BCN_ADDNIE_FLAG to CCM");
10177 }
10178 }/* ccmCfgSetStr(,WNI_CFG_PROBE_RSP_BCN_ADDNIE_DATA, , )*/
10179 else
10180 hddLog(LOGE,
10181 "Could not pass on "
10182 "WNI_CFG_PROBE_RSP_BCN_ADDNIE_DATA to CCM");
10183
10184 /* IBSS mode doesn't contain params->proberesp_ies still
10185 beaconIE's need to be populated in probe response frames */
10186 if ( (NULL != (genie - 2)) && (0 != eLen + 2) )
10187 {
10188 u16 rem_probe_resp_ie_len = eLen + 2;
10189 u8 probe_rsp_ie_len[3] = {0};
10190 u8 counter = 0;
10191
10192 /* Check Probe Resp Length if it is greater then 255 then
10193 Store Probe Rsp IEs into WNI_CFG_PROBE_RSP_ADDNIE_DATA1
10194 & WNI_CFG_PROBE_RSP_ADDNIE_DATA2 CFG Variable As We are
10195 not able Store More then 255 bytes into One Variable */
10196
10197 while ((rem_probe_resp_ie_len > 0) && (counter < 3))
10198 {
10199 if (rem_probe_resp_ie_len > MAX_CFG_STRING_LEN)
10200 {
10201 probe_rsp_ie_len[counter++] = MAX_CFG_STRING_LEN;
10202 rem_probe_resp_ie_len -= MAX_CFG_STRING_LEN;
10203 }
10204 else
10205 {
10206 probe_rsp_ie_len[counter++] = rem_probe_resp_ie_len;
10207 rem_probe_resp_ie_len = 0;
10208 }
10209 }
10210
10211 rem_probe_resp_ie_len = 0;
10212
10213 if (probe_rsp_ie_len[0] > 0)
10214 {
10215 if (ccmCfgSetStr(WLAN_HDD_GET_HAL_CTX(pAdapter),
10216 WNI_CFG_PROBE_RSP_ADDNIE_DATA1,
10217 (tANI_U8*)(genie - 2),
10218 probe_rsp_ie_len[0], NULL,
10219 eANI_BOOLEAN_FALSE)
10220 == eHAL_STATUS_FAILURE)
10221 {
10222 hddLog(LOGE,
10223 "Could not pass"
10224 "on WNI_CFG_PROBE_RSP_ADDNIE_DATA1 to CCM");
10225 }
10226 rem_probe_resp_ie_len += probe_rsp_ie_len[0];
10227 }
10228
10229 if (probe_rsp_ie_len[1] > 0)
10230 {
10231 if (ccmCfgSetStr(WLAN_HDD_GET_HAL_CTX(pAdapter),
10232 WNI_CFG_PROBE_RSP_ADDNIE_DATA2,
10233 (tANI_U8*)(genie - (2 + rem_probe_resp_ie_len)),
10234 probe_rsp_ie_len[1], NULL,
10235 eANI_BOOLEAN_FALSE)
10236 == eHAL_STATUS_FAILURE)
10237 {
10238 hddLog(LOGE,
10239 "Could not pass"
10240 "on WNI_CFG_PROBE_RSP_ADDNIE_DATA2 to CCM");
10241 }
10242 rem_probe_resp_ie_len += probe_rsp_ie_len[1];
10243 }
10244
10245 if (probe_rsp_ie_len[2] > 0)
10246 {
10247 if (ccmCfgSetStr(WLAN_HDD_GET_HAL_CTX(pAdapter),
10248 WNI_CFG_PROBE_RSP_ADDNIE_DATA3,
10249 (tANI_U8*)(genie - (2 + rem_probe_resp_ie_len)),
10250 probe_rsp_ie_len[2], NULL,
10251 eANI_BOOLEAN_FALSE)
10252 == eHAL_STATUS_FAILURE)
10253 {
10254 hddLog(LOGE,
10255 "Could not pass"
10256 "on WNI_CFG_PROBE_RSP_ADDNIE_DATA3 to CCM");
10257 }
10258 rem_probe_resp_ie_len += probe_rsp_ie_len[2];
10259 }
10260
10261 if (ccmCfgSetInt(WLAN_HDD_GET_HAL_CTX(pAdapter),
10262 WNI_CFG_PROBE_RSP_ADDNIE_FLAG, 1,NULL,
10263 eANI_BOOLEAN_FALSE) == eHAL_STATUS_FAILURE)
10264 {
10265 hddLog(LOGE,
10266 "Could not pass"
10267 "on WNI_CFG_PROBE_RSP_ADDNIE_FLAG to CCM");
10268 }
10269 }
10270 else
10271 {
10272 // Reset WNI_CFG_PROBE_RSP Flags
10273 wlan_hdd_reset_prob_rspies(pAdapter);
10274
10275 hddLog(VOS_TRACE_LEVEL_INFO,
10276 "%s: No Probe Response IE received in set beacon",
10277 __func__);
10278 }
10279 } /* end of if (WLAN_HDD_IBSS == pAdapter->device_mode) */
Jeff Johnson295189b2012-06-20 16:38:30 -070010280 break;
10281 case DOT11F_EID_RSN:
10282 hddLog (VOS_TRACE_LEVEL_INFO, "%s Set RSN IE(len %d)",__func__, eLen + 2);
10283 memset( pWextState->WPARSNIE, 0, MAX_WPA_RSN_IE_LEN );
10284 memcpy( pWextState->WPARSNIE, genie - 2, (eLen + 2)/*ie_len*/);
10285 pWextState->roamProfile.pRSNReqIE = pWextState->WPARSNIE;
10286 pWextState->roamProfile.nRSNReqIELength = eLen + 2; //ie_len;
10287 break;
Madan Mohan Koyyalamudief3b66e2012-10-11 14:29:42 -070010288 /* Appending Extended Capabilities with Interworking bit set in Assoc Req */
10289 case DOT11F_EID_EXTCAP:
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010290 {
Madan Mohan Koyyalamudief3b66e2012-10-11 14:29:42 -070010291 v_U16_t curAddIELen = pWextState->assocAddIE.length;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010292 hddLog (VOS_TRACE_LEVEL_INFO, "%s Set Extended CAPS IE(len %d)",
Madan Mohan Koyyalamudief3b66e2012-10-11 14:29:42 -070010293 __func__, eLen + 2);
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010294
Madan Mohan Koyyalamudief3b66e2012-10-11 14:29:42 -070010295 if( SIR_MAC_MAX_IE_LENGTH < (pWextState->assocAddIE.length + eLen) )
10296 {
Jeff Johnson902c9832012-12-10 14:28:09 -080010297 hddLog(VOS_TRACE_LEVEL_FATAL, "Cannot accommodate assocAddIE "
10298 "Need bigger buffer space");
Madan Mohan Koyyalamudief3b66e2012-10-11 14:29:42 -070010299 VOS_ASSERT(0);
10300 return -ENOMEM;
10301 }
10302 memcpy( pWextState->assocAddIE.addIEdata + curAddIELen, genie - 2, eLen + 2);
10303 pWextState->assocAddIE.length += eLen + 2;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010304
Madan Mohan Koyyalamudief3b66e2012-10-11 14:29:42 -070010305 pWextState->roamProfile.pAddIEAssoc = pWextState->assocAddIE.addIEdata;
10306 pWextState->roamProfile.nAddIEAssocLength = pWextState->assocAddIE.length;
10307 break;
10308 }
Jeff Johnson295189b2012-06-20 16:38:30 -070010309#ifdef FEATURE_WLAN_WAPI
10310 case WLAN_EID_WAPI:
10311 pAdapter->wapi_info.nWapiMode = 1; //Setting WAPI Mode to ON=1
Jeff Johnson0299d0a2013-10-30 12:37:43 -070010312 hddLog(VOS_TRACE_LEVEL_INFO, "WAPI MODE IS %u",
Jeff Johnson295189b2012-06-20 16:38:30 -070010313 pAdapter->wapi_info.nWapiMode);
10314 tmp = (u16 *)ie;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010315 tmp = tmp + 2; // Skip element Id and Len, Version
Jeff Johnson295189b2012-06-20 16:38:30 -070010316 akmsuiteCount = WPA_GET_LE16(tmp);
10317 tmp = tmp + 1;
10318 akmlist = (int *)(tmp);
10319 if(akmsuiteCount <= MAX_NUM_AKM_SUITES)
10320 {
10321 memcpy(akmsuite, akmlist, (4*akmsuiteCount));
10322 }
10323 else
10324 {
Arif Hussain6d2a3322013-11-17 19:50:10 -080010325 hddLog(VOS_TRACE_LEVEL_FATAL, "Invalid akmSuite count");
Jeff Johnson295189b2012-06-20 16:38:30 -070010326 VOS_ASSERT(0);
10327 return -EINVAL;
10328 }
10329
10330 if (WAPI_PSK_AKM_SUITE == akmsuite[0])
10331 {
10332 hddLog(VOS_TRACE_LEVEL_INFO, "%s: WAPI AUTH MODE SET TO PSK",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -070010333 __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -070010334 pAdapter->wapi_info.wapiAuthMode = WAPI_AUTH_MODE_PSK;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010335 }
Jeff Johnson295189b2012-06-20 16:38:30 -070010336 if (WAPI_CERT_AKM_SUITE == akmsuite[0])
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010337 {
Jeff Johnson295189b2012-06-20 16:38:30 -070010338 hddLog(VOS_TRACE_LEVEL_INFO, "%s: WAPI AUTH MODE SET TO CERTIFICATE",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -070010339 __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -070010340 pAdapter->wapi_info.wapiAuthMode = WAPI_AUTH_MODE_CERT;
10341 }
10342 break;
10343#endif
10344 default:
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010345 hddLog (VOS_TRACE_LEVEL_ERROR,
Jeff Johnson295189b2012-06-20 16:38:30 -070010346 "%s Set UNKNOWN IE %X", __func__, elementId);
Madan Mohan Koyyalamudief3b66e2012-10-11 14:29:42 -070010347 /* when Unknown IE is received we should break and continue
10348 * to the next IE in the buffer instead we were returning
10349 * so changing this to break */
10350 break;
Jeff Johnson295189b2012-06-20 16:38:30 -070010351 }
10352 genie += eLen;
10353 remLen -= eLen;
10354 }
10355 EXIT();
10356 return 0;
10357}
10358
10359/*
Gopichand Nakkala18f0c262013-05-07 23:25:08 +053010360 * FUNCTION: hdd_isWPAIEPresent
10361 * Parse the received IE to find the WPA IE
10362 *
10363 */
10364static bool hdd_isWPAIEPresent(u8 *ie, u8 ie_len)
10365{
10366 v_U8_t eLen = 0;
10367 v_U16_t remLen = ie_len;
10368 v_U8_t elementId = 0;
10369
10370 while (remLen >= 2)
10371 {
10372 elementId = *ie++;
10373 eLen = *ie++;
10374 remLen -= 2;
10375 if (eLen > remLen)
10376 {
10377 hddLog(VOS_TRACE_LEVEL_ERROR,
10378 "%s: IE length is wrong %d", __func__, eLen);
10379 return FALSE;
10380 }
10381 if ((elementId == DOT11F_EID_WPA) && (remLen > 5))
10382 {
10383 /* OUI - 0x00 0X50 0XF2
10384 WPA Information Element - 0x01
10385 WPA version - 0x01*/
10386 if (0 == memcmp(&ie[0], "\x00\x50\xf2\x01\x01", 5))
10387 return TRUE;
10388 }
10389 ie += eLen;
10390 remLen -= eLen;
10391 }
10392 return FALSE;
10393}
10394
10395/*
Jeff Johnson295189b2012-06-20 16:38:30 -070010396 * FUNCTION: wlan_hdd_cfg80211_set_privacy
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010397 * This function is used to initialize the security
Jeff Johnson295189b2012-06-20 16:38:30 -070010398 * parameters during connect operation.
10399 */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010400int wlan_hdd_cfg80211_set_privacy( hdd_adapter_t *pAdapter,
Jeff Johnson295189b2012-06-20 16:38:30 -070010401 struct cfg80211_connect_params *req
10402 )
10403{
10404 int status = 0;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010405 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
Jeff Johnson295189b2012-06-20 16:38:30 -070010406 ENTER();
10407
10408 /*set wpa version*/
10409 pWextState->wpaVersion = IW_AUTH_WPA_VERSION_DISABLED;
10410
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010411 if (req->crypto.wpa_versions)
Jeff Johnson295189b2012-06-20 16:38:30 -070010412 {
Gopichand Nakkala781ded42013-06-28 12:10:45 +053010413 if (NL80211_WPA_VERSION_1 == req->crypto.wpa_versions)
Jeff Johnson295189b2012-06-20 16:38:30 -070010414 {
10415 pWextState->wpaVersion = IW_AUTH_WPA_VERSION_WPA;
10416 }
10417 else if (NL80211_WPA_VERSION_2 == req->crypto.wpa_versions)
10418 {
10419 pWextState->wpaVersion = IW_AUTH_WPA_VERSION_WPA2;
10420 }
10421 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010422
10423 hddLog(VOS_TRACE_LEVEL_INFO, "%s: set wpa version to %d", __func__,
Jeff Johnson295189b2012-06-20 16:38:30 -070010424 pWextState->wpaVersion);
10425
10426 /*set authentication type*/
10427 status = wlan_hdd_cfg80211_set_auth_type(pAdapter, req->auth_type);
10428
10429 if (0 > status)
10430 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010431 hddLog(VOS_TRACE_LEVEL_ERROR,
Jeff Johnson295189b2012-06-20 16:38:30 -070010432 "%s: failed to set authentication type ", __func__);
10433 return status;
10434 }
10435
10436 /*set key mgmt type*/
10437 if (req->crypto.n_akm_suites)
10438 {
10439 status = wlan_hdd_set_akm_suite(pAdapter, req->crypto.akm_suites[0]);
10440 if (0 > status)
10441 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010442 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: failed to set akm suite",
Jeff Johnson295189b2012-06-20 16:38:30 -070010443 __func__);
10444 return status;
10445 }
10446 }
10447
10448 /*set pairwise cipher type*/
10449 if (req->crypto.n_ciphers_pairwise)
10450 {
10451 status = wlan_hdd_cfg80211_set_cipher(pAdapter,
10452 req->crypto.ciphers_pairwise[0], true);
10453 if (0 > status)
10454 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010455 hddLog(VOS_TRACE_LEVEL_ERROR,
Jeff Johnson295189b2012-06-20 16:38:30 -070010456 "%s: failed to set unicast cipher type", __func__);
10457 return status;
10458 }
10459 }
10460 else
10461 {
10462 /*Reset previous cipher suite to none*/
10463 status = wlan_hdd_cfg80211_set_cipher(pAdapter, 0, true);
10464 if (0 > status)
10465 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010466 hddLog(VOS_TRACE_LEVEL_ERROR,
Jeff Johnson295189b2012-06-20 16:38:30 -070010467 "%s: failed to set unicast cipher type", __func__);
10468 return status;
10469 }
10470 }
10471
10472 /*set group cipher type*/
10473 status = wlan_hdd_cfg80211_set_cipher(pAdapter, req->crypto.cipher_group,
10474 false);
10475
10476 if (0 > status)
10477 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010478 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: failed to set mcast cipher type",
Jeff Johnson295189b2012-06-20 16:38:30 -070010479 __func__);
10480 return status;
10481 }
10482
Chet Lanctot186b5732013-03-18 10:26:30 -070010483#ifdef WLAN_FEATURE_11W
10484 pWextState->roamProfile.MFPEnabled = (req->mfp == NL80211_MFP_REQUIRED);
10485#endif
10486
Jeff Johnson295189b2012-06-20 16:38:30 -070010487 /*parse WPA/RSN IE, and set the correspoing fileds in Roam profile*/
10488 if (req->ie_len)
10489 {
10490 status = wlan_hdd_cfg80211_set_ie(pAdapter, req->ie, req->ie_len);
10491 if ( 0 > status)
10492 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010493 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: failed to parse the WPA/RSN IE",
Jeff Johnson295189b2012-06-20 16:38:30 -070010494 __func__);
10495 return status;
10496 }
10497 }
10498
10499 /*incase of WEP set default key information*/
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010500 if (req->key && req->key_len)
Jeff Johnson295189b2012-06-20 16:38:30 -070010501 {
10502 if ( (WLAN_CIPHER_SUITE_WEP40 == req->crypto.ciphers_pairwise[0])
10503 || (WLAN_CIPHER_SUITE_WEP104 == req->crypto.ciphers_pairwise[0])
10504 )
10505 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010506 if ( IW_AUTH_KEY_MGMT_802_1X
Jeff Johnson295189b2012-06-20 16:38:30 -070010507 == (pWextState->authKeyMgmt & IW_AUTH_KEY_MGMT_802_1X ))
10508 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010509 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Dynamic WEP not supported",
Jeff Johnson295189b2012-06-20 16:38:30 -070010510 __func__);
10511 return -EOPNOTSUPP;
10512 }
10513 else
10514 {
10515 u8 key_len = req->key_len;
10516 u8 key_idx = req->key_idx;
10517
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010518 if ((eCSR_SECURITY_WEP_KEYSIZE_MAX_BYTES >= key_len)
Jeff Johnson295189b2012-06-20 16:38:30 -070010519 && (CSR_MAX_NUM_KEY > key_idx)
10520 )
10521 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010522 hddLog(VOS_TRACE_LEVEL_INFO,
10523 "%s: setting default wep key, key_idx = %hu key_len %hu",
Jeff Johnson295189b2012-06-20 16:38:30 -070010524 __func__, key_idx, key_len);
10525 vos_mem_copy(
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010526 &pWextState->roamProfile.Keys.KeyMaterial[key_idx][0],
Jeff Johnson295189b2012-06-20 16:38:30 -070010527 req->key, key_len);
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010528 pWextState->roamProfile.Keys.KeyLength[key_idx] =
Jeff Johnson295189b2012-06-20 16:38:30 -070010529 (u8)key_len;
10530 pWextState->roamProfile.Keys.defaultIndex = (u8)key_idx;
10531 }
10532 }
10533 }
10534 }
10535
10536 return status;
10537}
10538
10539/*
Vinay Krishna Eranna21042322014-01-08 19:21:39 +053010540 * FUNCTION: wlan_hdd_try_disconnect
10541 * This function is used to disconnect from previous
10542 * connection
10543 */
10544static int wlan_hdd_try_disconnect( hdd_adapter_t *pAdapter )
10545{
10546 long ret = 0;
10547 hdd_station_ctx_t *pHddStaCtx;
10548 eMib_dot11DesiredBssType connectedBssType;
10549
10550 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
10551
10552 hdd_connGetConnectedBssType(pHddStaCtx,&connectedBssType );
10553
10554 if((eMib_dot11DesiredBssType_independent == connectedBssType) ||
10555 (eConnectionState_Associated == pHddStaCtx->conn_info.connState) ||
10556 (eConnectionState_IbssConnected == pHddStaCtx->conn_info.connState))
10557 {
10558 /* Issue disconnect to CSR */
10559 INIT_COMPLETION(pAdapter->disconnect_comp_var);
10560 if( eHAL_STATUS_SUCCESS ==
10561 sme_RoamDisconnect( WLAN_HDD_GET_HAL_CTX(pAdapter),
10562 pAdapter->sessionId,
10563 eCSR_DISCONNECT_REASON_UNSPECIFIED ) )
10564 {
10565 ret = wait_for_completion_interruptible_timeout(
10566 &pAdapter->disconnect_comp_var,
10567 msecs_to_jiffies(WLAN_WAIT_TIME_DISCONNECT));
10568 if (0 >= ret)
10569 {
10570 hddLog(LOGE, FL("Failed to receive disconnect event"));
10571 return -EALREADY;
10572 }
10573 }
10574 }
10575 else if(eConnectionState_Disconnecting == pHddStaCtx->conn_info.connState)
10576 {
10577 ret = wait_for_completion_interruptible_timeout(
10578 &pAdapter->disconnect_comp_var,
10579 msecs_to_jiffies(WLAN_WAIT_TIME_DISCONNECT));
10580 if (0 >= ret)
10581 {
10582 hddLog(LOGE, FL("Failed to receive disconnect event"));
10583 return -EALREADY;
10584 }
10585 }
10586
10587 return 0;
10588}
10589
10590/*
Agarwal Ashish51325b52014-06-16 16:50:49 +053010591 * FUNCTION: __wlan_hdd_cfg80211_connect
10592 * This function is used to start the association process
Jeff Johnson295189b2012-06-20 16:38:30 -070010593 */
Mahesh A Saptasagarfafb7fe2014-05-16 13:19:37 +053010594static int __wlan_hdd_cfg80211_connect( struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -070010595 struct net_device *ndev,
10596 struct cfg80211_connect_params *req
10597 )
10598{
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053010599 int status;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010600 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( ndev );
Jeff Johnson295189b2012-06-20 16:38:30 -070010601 VOS_STATUS exitbmpsStatus = VOS_STATUS_E_INVAL;
Sushant Kaushikba6764e2014-06-30 19:52:09 +053010602 hdd_context_t *pHddCtx = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -070010603
10604 ENTER();
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053010605
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053010606 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
10607 TRACE_CODE_HDD_CFG80211_CONNECT,
10608 pAdapter->sessionId, pAdapter->device_mode));
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010609 hddLog(VOS_TRACE_LEVEL_INFO,
Sushant Kaushik8bc7df22014-04-09 17:55:29 +053010610 "%s: device_mode = %s (%d)", __func__,
10611 hdd_device_modetoString(pAdapter->device_mode),
10612 pAdapter->device_mode);
Jeff Johnson295189b2012-06-20 16:38:30 -070010613
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053010614 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Rajesh Chauhana0516c62014-01-30 16:11:18 -080010615 if (!pHddCtx)
10616 {
10617 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
10618 "%s: HDD context is null", __func__);
Agarwal Ashish51325b52014-06-16 16:50:49 +053010619 return -EINVAL;
Rajesh Chauhana0516c62014-01-30 16:11:18 -080010620 }
10621
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053010622 status = wlan_hdd_validate_context(pHddCtx);
10623
10624 if (0 != status)
Jeff Johnson295189b2012-06-20 16:38:30 -070010625 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053010626 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
10627 "%s: HDD context is not valid", __func__);
10628 return status;
Jeff Johnson295189b2012-06-20 16:38:30 -070010629 }
10630
Agarwal Ashish51325b52014-06-16 16:50:49 +053010631 if (vos_max_concurrent_connections_reached()) {
10632 hddLog(VOS_TRACE_LEVEL_INFO, FL("Reached max concurrent connections"));
10633 return -ECONNREFUSED;
10634 }
10635
Jeff Johnson295189b2012-06-20 16:38:30 -070010636#ifdef WLAN_BTAMP_FEATURE
10637 //Infra connect not supported when AMP traffic is on.
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010638 if( VOS_TRUE == WLANBAP_AmpSessionOn() )
Jeff Johnson295189b2012-06-20 16:38:30 -070010639 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010640 hddLog(VOS_TRACE_LEVEL_ERROR,
Jeff Johnson295189b2012-06-20 16:38:30 -070010641 "%s: No connection when AMP is on", __func__);
Madan Mohan Koyyalamudicae253a2012-11-06 19:10:35 -080010642 return -ECONNREFUSED;
Jeff Johnson295189b2012-06-20 16:38:30 -070010643 }
10644#endif
Vinay Krishna Eranna21042322014-01-08 19:21:39 +053010645
10646 //If Device Mode is Station Concurrent Sessions Exit BMps
10647 //P2P Mode will be taken care in Open/close adapter
10648 if((WLAN_HDD_INFRA_STATION == pAdapter->device_mode) &&
Agarwal Ashish51325b52014-06-16 16:50:49 +053010649 (vos_concurrent_open_sessions_running())) {
10650 exitbmpsStatus = hdd_disable_bmps_imps(pHddCtx,
10651 WLAN_HDD_INFRA_STATION);
Vinay Krishna Eranna21042322014-01-08 19:21:39 +053010652 }
10653
10654 /*Try disconnecting if already in connected state*/
10655 status = wlan_hdd_try_disconnect(pAdapter);
10656 if ( 0 > status)
10657 {
10658 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Failed to disconnect the existing"
10659 " connection"));
10660 return -EALREADY;
10661 }
10662
Jeff Johnson295189b2012-06-20 16:38:30 -070010663 /*initialise security parameters*/
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010664 status = wlan_hdd_cfg80211_set_privacy(pAdapter, req);
Jeff Johnson295189b2012-06-20 16:38:30 -070010665
10666 if ( 0 > status)
10667 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010668 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: failed to set security params",
Jeff Johnson295189b2012-06-20 16:38:30 -070010669 __func__);
10670 return status;
10671 }
Mohit Khanna765234a2012-09-11 15:08:35 -070010672 if ( req->channel )
10673 {
10674 status = wlan_hdd_cfg80211_connect_start(pAdapter, req->ssid,
10675 req->ssid_len, req->bssid,
10676 req->channel->hw_value);
10677 }
10678 else
10679 {
10680 status = wlan_hdd_cfg80211_connect_start(pAdapter, req->ssid,
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053010681 req->ssid_len, req->bssid, 0);
Mohit Khanna765234a2012-09-11 15:08:35 -070010682 }
Jeff Johnson295189b2012-06-20 16:38:30 -070010683
10684 if (0 > status)
10685 {
10686 //ReEnable BMPS if disabled
10687 if((VOS_STATUS_SUCCESS == exitbmpsStatus) &&
10688 (NULL != pHddCtx))
10689 {
Gopichand Nakkalaa2fe5b02013-06-06 16:32:28 +053010690 if (pHddCtx->hdd_wlan_suspended)
10691 {
10692 hdd_set_pwrparams(pHddCtx);
10693 }
Jeff Johnson295189b2012-06-20 16:38:30 -070010694 //ReEnable Bmps and Imps back
10695 hdd_enable_bmps_imps(pHddCtx);
10696 }
Agarwal Ashish51325b52014-06-16 16:50:49 +053010697 hddLog(VOS_TRACE_LEVEL_ERROR, FL("connect failed"));
Jeff Johnson295189b2012-06-20 16:38:30 -070010698 return status;
10699 }
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053010700 pHddCtx->isAmpAllowed = VOS_FALSE;
Jeff Johnson295189b2012-06-20 16:38:30 -070010701 EXIT();
10702 return status;
10703}
10704
Mahesh A Saptasagarfafb7fe2014-05-16 13:19:37 +053010705static int wlan_hdd_cfg80211_connect( struct wiphy *wiphy,
10706 struct net_device *ndev,
10707 struct cfg80211_connect_params *req)
10708{
10709 int ret;
10710 vos_ssr_protect(__func__);
10711 ret = __wlan_hdd_cfg80211_connect(wiphy, ndev, req);
10712 vos_ssr_unprotect(__func__);
10713
10714 return ret;
10715}
Jeff Johnson295189b2012-06-20 16:38:30 -070010716
10717/*
Gopichand Nakkala78a6c812013-05-13 16:39:49 +053010718 * FUNCTION: wlan_hdd_disconnect
10719 * This function is used to issue a disconnect request to SME
10720 */
10721int wlan_hdd_disconnect( hdd_adapter_t *pAdapter, u16 reason )
10722{
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053010723 int status;
Gopichand Nakkala78a6c812013-05-13 16:39:49 +053010724 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053010725 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Abhishek Singhdc2bfd42014-06-19 17:59:05 +053010726 long ret;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053010727
10728 status = wlan_hdd_validate_context(pHddCtx);
10729
10730 if (0 != status)
10731 {
10732 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
10733 "%s: HDD context is not valid", __func__);
10734 return status;
10735 }
10736
10737 pHddCtx->isAmpAllowed = VOS_TRUE;
Agarwal Ashishc65b5ca2014-07-28 21:02:57 +053010738
Agarwal Ashish47d18112014-08-04 19:55:07 +053010739 /* Need to apply spin lock before decreasing active sessions
10740 * as there can be chance for double decrement if context switch
10741 * Calls hdd_DisConnectHandler.
10742 */
10743
10744 spin_lock_bh(&pAdapter->lock_for_active_session);
Agarwal Ashishc65b5ca2014-07-28 21:02:57 +053010745 if (eConnectionState_Associated == pHddStaCtx->conn_info.connState)
10746 {
Agarwal Ashishc65b5ca2014-07-28 21:02:57 +053010747 wlan_hdd_decr_active_session(pHddCtx, pAdapter->device_mode);
10748 }
Agarwal Ashish47d18112014-08-04 19:55:07 +053010749 hdd_connSetConnectionState( pHddStaCtx, eConnectionState_Disconnecting );
10750 spin_unlock_bh(&pAdapter->lock_for_active_session);
Agarwal Ashishc65b5ca2014-07-28 21:02:57 +053010751
Abhishek Singhf4669da2014-05-26 15:07:49 +053010752 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Agarwal Ashish47d18112014-08-04 19:55:07 +053010753 FL( "Set HDD connState to eConnectionState_Disconnecting" ));
10754
Gopichand Nakkala78a6c812013-05-13 16:39:49 +053010755 INIT_COMPLETION(pAdapter->disconnect_comp_var);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053010756
Mihir Shete182a0b22014-08-18 16:08:48 +053010757 /*
10758 * stop tx queues before deleting STA/BSS context from the firmware.
10759 * tx has to be disabled because the firmware can get busy dropping
10760 * the tx frames after BSS/STA has been deleted and will not send
10761 * back a response resulting in WDI timeout
10762 */
10763 netif_tx_disable(pAdapter->dev);
10764 netif_carrier_off(pAdapter->dev);
Arun Kumar Khandavalli94a2bb02013-12-28 19:17:25 +053010765
Mihir Shete182a0b22014-08-18 16:08:48 +053010766 /*issue disconnect*/
Gopichand Nakkala78a6c812013-05-13 16:39:49 +053010767 status = sme_RoamDisconnect( WLAN_HDD_GET_HAL_CTX(pAdapter),
10768 pAdapter->sessionId, reason);
Abhishek Singhdc2bfd42014-06-19 17:59:05 +053010769 if(eHAL_STATUS_CMD_NOT_QUEUED == status)
10770 {
10771 hddLog(VOS_TRACE_LEVEL_INFO,
10772 FL("status = %d, already disconnected"),
10773 (int)status );
Gopichand Nakkala78a6c812013-05-13 16:39:49 +053010774
Abhishek Singhdc2bfd42014-06-19 17:59:05 +053010775 }
10776 else if ( 0 != status )
Gopichand Nakkala78a6c812013-05-13 16:39:49 +053010777 {
10778 hddLog(VOS_TRACE_LEVEL_ERROR,
Arif Hussain6d2a3322013-11-17 19:50:10 -080010779 "%s csrRoamDisconnect failure, returned %d",
Gopichand Nakkala78a6c812013-05-13 16:39:49 +053010780 __func__, (int)status );
10781 return -EINVAL;
10782 }
Abhishek Singhdc2bfd42014-06-19 17:59:05 +053010783 ret = wait_for_completion_interruptible_timeout(
Gopichand Nakkala78a6c812013-05-13 16:39:49 +053010784 &pAdapter->disconnect_comp_var,
10785 msecs_to_jiffies(WLAN_WAIT_TIME_DISCONNECT));
Abhishek Singhdc2bfd42014-06-19 17:59:05 +053010786 if (!ret && ( eHAL_STATUS_CMD_NOT_QUEUED != status ))
c_hpothu6ff1c3c2013-10-01 19:01:57 +053010787 {
10788 hddLog(VOS_TRACE_LEVEL_ERROR,
Mahesh A Saptasagar05a357e2014-02-26 16:28:06 +053010789 "%s: Failed to disconnect, timed out", __func__);
10790 return -ETIMEDOUT;
10791 }
Abhishek Singhdc2bfd42014-06-19 17:59:05 +053010792 else if (ret == -ERESTARTSYS)
Mahesh A Saptasagar05a357e2014-02-26 16:28:06 +053010793 {
10794 hddLog(VOS_TRACE_LEVEL_ERROR,
10795 "%s: Failed to disconnect, wait interrupted", __func__);
Abhishek Singhdc2bfd42014-06-19 17:59:05 +053010796 return ret;
c_hpothu6ff1c3c2013-10-01 19:01:57 +053010797 }
Abhishek Singhdc2bfd42014-06-19 17:59:05 +053010798 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
10799 FL("Set HDD connState to eConnectionState_NotConnected"));
10800 pHddStaCtx->conn_info.connState = eConnectionState_NotConnected;
10801
Mahesh A Saptasagar05a357e2014-02-26 16:28:06 +053010802 return 0;
Gopichand Nakkala78a6c812013-05-13 16:39:49 +053010803}
10804
10805
10806/*
Mahesh A Saptasagarfafb7fe2014-05-16 13:19:37 +053010807 * FUNCTION: __wlan_hdd_cfg80211_disconnect
Jeff Johnson295189b2012-06-20 16:38:30 -070010808 * This function is used to issue a disconnect request to SME
10809 */
Mahesh A Saptasagarfafb7fe2014-05-16 13:19:37 +053010810static int __wlan_hdd_cfg80211_disconnect( struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -070010811 struct net_device *dev,
10812 u16 reason
10813 )
10814{
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010815 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( dev );
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053010816 tCsrRoamProfile *pRoamProfile =
10817 &(WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter))->roamProfile;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053010818 int status;
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053010819 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
10820 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Gopichand Nakkalaaa353782013-05-17 20:36:22 +053010821#ifdef FEATURE_WLAN_TDLS
Gopichand Nakkala2a0a1572013-02-10 21:39:16 -080010822 tANI_U8 staIdx;
10823#endif
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010824
Jeff Johnson295189b2012-06-20 16:38:30 -070010825 ENTER();
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053010826
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053010827 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
10828 TRACE_CODE_HDD_CFG80211_DISCONNECT,
10829 pAdapter->sessionId, reason));
Sushant Kaushik8bc7df22014-04-09 17:55:29 +053010830 hddLog(VOS_TRACE_LEVEL_INFO, "%s: device_mode = %s(%d)",
10831 __func__, hdd_device_modetoString(pAdapter->device_mode),
10832 pAdapter->device_mode);
Jeff Johnson295189b2012-06-20 16:38:30 -070010833
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010834 hddLog(VOS_TRACE_LEVEL_INFO, "%s: Disconnect called with reason code %d",
10835 __func__, reason);
Jeff Johnson295189b2012-06-20 16:38:30 -070010836
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053010837 status = wlan_hdd_validate_context(pHddCtx);
10838
10839 if (0 != status)
Jeff Johnson295189b2012-06-20 16:38:30 -070010840 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053010841 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
10842 "%s: HDD context is not valid", __func__);
10843 return status;
Jeff Johnson295189b2012-06-20 16:38:30 -070010844 }
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053010845
Jeff Johnson295189b2012-06-20 16:38:30 -070010846 if (NULL != pRoamProfile)
10847 {
10848 /*issue disconnect request to SME, if station is in connected state*/
Mahesh A Saptasagar280fd5a2013-12-05 15:38:31 +053010849 if ((pHddStaCtx->conn_info.connState == eConnectionState_Associated) ||
10850 (pHddStaCtx->conn_info.connState == eConnectionState_Connecting))
Jeff Johnson295189b2012-06-20 16:38:30 -070010851 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010852 eCsrRoamDisconnectReason reasonCode =
Jeff Johnson295189b2012-06-20 16:38:30 -070010853 eCSR_DISCONNECT_REASON_UNSPECIFIED;
Gopichand Nakkalaaa353782013-05-17 20:36:22 +053010854 hdd_scaninfo_t *pScanInfo;
Jeff Johnson295189b2012-06-20 16:38:30 -070010855 switch(reason)
10856 {
10857 case WLAN_REASON_MIC_FAILURE:
10858 reasonCode = eCSR_DISCONNECT_REASON_MIC_ERROR;
10859 break;
10860
10861 case WLAN_REASON_DISASSOC_DUE_TO_INACTIVITY:
10862 case WLAN_REASON_DISASSOC_AP_BUSY:
10863 case WLAN_REASON_CLASS3_FRAME_FROM_NONASSOC_STA:
10864 reasonCode = eCSR_DISCONNECT_REASON_DISASSOC;
10865 break;
10866
10867 case WLAN_REASON_PREV_AUTH_NOT_VALID:
10868 case WLAN_REASON_CLASS2_FRAME_FROM_NONAUTH_STA:
Abhishek Singhc3269a52014-05-21 17:22:24 +053010869 case WLAN_REASON_DEAUTH_LEAVING:
Jeff Johnson295189b2012-06-20 16:38:30 -070010870 reasonCode = eCSR_DISCONNECT_REASON_DEAUTH;
10871 break;
10872
Jeff Johnson295189b2012-06-20 16:38:30 -070010873 default:
10874 reasonCode = eCSR_DISCONNECT_REASON_UNSPECIFIED;
10875 break;
10876 }
Gopichand Nakkalaaa353782013-05-17 20:36:22 +053010877 pScanInfo = &pHddCtx->scan_info;
10878 if (pScanInfo->mScanPending)
10879 {
Srinivas, Dasari138af4f2014-02-07 11:13:45 +053010880 hddLog(VOS_TRACE_LEVEL_INFO, "Disconnect is in progress, "
Gopichand Nakkalaaa353782013-05-17 20:36:22 +053010881 "Aborting Scan");
Srinivas, Dasari138af4f2014-02-07 11:13:45 +053010882 hdd_abort_mac_scan(pHddCtx, pAdapter->sessionId,
10883 eCSR_SCAN_ABORT_DEFAULT);
Gopichand Nakkalaaa353782013-05-17 20:36:22 +053010884 }
Jeff Johnson295189b2012-06-20 16:38:30 -070010885
Gopichand Nakkala2a0a1572013-02-10 21:39:16 -080010886#ifdef FEATURE_WLAN_TDLS
10887 /* First clean up the tdls peers if any */
Gopichand Nakkala4327a152013-03-04 23:22:42 -080010888 for (staIdx = 0 ; staIdx < HDD_MAX_NUM_TDLS_STA; staIdx++)
Gopichand Nakkala2a0a1572013-02-10 21:39:16 -080010889 {
Gopichand Nakkala4327a152013-03-04 23:22:42 -080010890 if ((pHddCtx->tdlsConnInfo[staIdx].sessionId == pAdapter->sessionId) &&
10891 (pHddCtx->tdlsConnInfo[staIdx].staId))
Gopichand Nakkala2a0a1572013-02-10 21:39:16 -080010892 {
Hoonki Lee11f7dda2013-02-14 16:55:44 -080010893 uint8 *mac;
Gopichand Nakkala4327a152013-03-04 23:22:42 -080010894 mac = pHddCtx->tdlsConnInfo[staIdx].peerMac.bytes;
Hoonki Lee11f7dda2013-02-14 16:55:44 -080010895 VOS_TRACE(VOS_MODULE_ID_HDD, TDLS_LOG_LEVEL,
Gopichand Nakkalac87400e2013-03-13 18:51:00 -070010896 "%s: call sme_DeleteTdlsPeerSta staId %d sessionId %d " MAC_ADDRESS_STR,
Gopichand Nakkala4327a152013-03-04 23:22:42 -080010897 __func__, pHddCtx->tdlsConnInfo[staIdx].staId, pAdapter->sessionId,
Gopichand Nakkalac87400e2013-03-13 18:51:00 -070010898 MAC_ADDR_ARRAY(mac));
Gopichand Nakkala2a0a1572013-02-10 21:39:16 -080010899 sme_DeleteTdlsPeerSta(WLAN_HDD_GET_HAL_CTX(pAdapter),
Gopichand Nakkala4327a152013-03-04 23:22:42 -080010900 pAdapter->sessionId,
10901 mac);
Gopichand Nakkala2a0a1572013-02-10 21:39:16 -080010902 }
10903 }
10904#endif
Arun Kumar Khandavalli94a2bb02013-12-28 19:17:25 +053010905 hddLog(LOG1, FL("Disconnecting with reasoncode:%u"), reasonCode);
Gopichand Nakkala78a6c812013-05-13 16:39:49 +053010906 status = wlan_hdd_disconnect(pAdapter, reasonCode);
10907 if ( 0 != status )
Jeff Johnson295189b2012-06-20 16:38:30 -070010908 {
10909 hddLog(VOS_TRACE_LEVEL_ERROR,
Arif Hussain6d2a3322013-11-17 19:50:10 -080010910 "%s wlan_hdd_disconnect failure, returned %d",
Jeff Johnson295189b2012-06-20 16:38:30 -070010911 __func__, (int)status );
10912 return -EINVAL;
10913 }
Jeff Johnson295189b2012-06-20 16:38:30 -070010914 }
Mahesh A Saptasagar280fd5a2013-12-05 15:38:31 +053010915 else
10916 {
10917 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: unexpected cfg disconnect API"
10918 "called while in %d state", __func__,
10919 pHddStaCtx->conn_info.connState);
10920 }
Jeff Johnson295189b2012-06-20 16:38:30 -070010921 }
10922 else
10923 {
10924 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: No valid roam profile", __func__);
10925 }
10926
10927 return status;
10928}
10929
Mahesh A Saptasagarfafb7fe2014-05-16 13:19:37 +053010930static int wlan_hdd_cfg80211_disconnect( struct wiphy *wiphy,
10931 struct net_device *dev,
10932 u16 reason
10933 )
10934{
10935 int ret;
10936 vos_ssr_protect(__func__);
10937 ret = __wlan_hdd_cfg80211_disconnect(wiphy, dev, reason);
10938 vos_ssr_unprotect(__func__);
10939
10940 return ret;
10941}
Gopichand Nakkala78a6c812013-05-13 16:39:49 +053010942
Jeff Johnson295189b2012-06-20 16:38:30 -070010943/*
10944 * FUNCTION: wlan_hdd_cfg80211_set_privacy_ibss
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010945 * This function is used to initialize the security
Jeff Johnson295189b2012-06-20 16:38:30 -070010946 * settings in IBSS mode.
10947 */
10948static int wlan_hdd_cfg80211_set_privacy_ibss(
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010949 hdd_adapter_t *pAdapter,
Jeff Johnson295189b2012-06-20 16:38:30 -070010950 struct cfg80211_ibss_params *params
10951 )
10952{
10953 int status = 0;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010954 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
Jeff Johnson295189b2012-06-20 16:38:30 -070010955 eCsrEncryptionType encryptionType = eCSR_ENCRYPT_TYPE_NONE;
10956 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010957
Jeff Johnson295189b2012-06-20 16:38:30 -070010958 ENTER();
10959
10960 pWextState->wpaVersion = IW_AUTH_WPA_VERSION_DISABLED;
Ravi Joshib58ca0d2013-10-29 09:50:23 -070010961 vos_mem_zero(&pHddStaCtx->ibss_enc_key, sizeof(tCsrRoamSetKey));
Jeff Johnson295189b2012-06-20 16:38:30 -070010962
10963 if (params->ie_len && ( NULL != params->ie) )
10964 {
Shailender Karmuchi67edd312013-06-18 16:30:48 -070010965 if (wlan_hdd_cfg80211_get_ie_ptr (params->ie,
10966 params->ie_len, WLAN_EID_RSN ))
Jeff Johnson295189b2012-06-20 16:38:30 -070010967 {
10968 pWextState->wpaVersion = IW_AUTH_WPA_VERSION_WPA2;
10969 encryptionType = eCSR_ENCRYPT_TYPE_AES;
10970 }
Shailender Karmuchi67edd312013-06-18 16:30:48 -070010971 else if ( hdd_isWPAIEPresent (params->ie, params->ie_len ))
Jeff Johnson295189b2012-06-20 16:38:30 -070010972 {
Shailender Karmuchi642e9812013-05-30 14:34:49 -070010973 tDot11fIEWPA dot11WPAIE;
10974 tHalHandle halHandle = WLAN_HDD_GET_HAL_CTX(pAdapter);
Shailender Karmuchi67edd312013-06-18 16:30:48 -070010975 u8 *ie;
Shailender Karmuchi642e9812013-05-30 14:34:49 -070010976
Wilson Yang00256342013-10-10 23:13:38 -070010977 memset(&dot11WPAIE, 0, sizeof(dot11WPAIE));
Shailender Karmuchi67edd312013-06-18 16:30:48 -070010978 ie = wlan_hdd_cfg80211_get_ie_ptr (params->ie,
10979 params->ie_len, DOT11F_EID_WPA);
10980 if ( NULL != ie )
10981 {
10982 pWextState->wpaVersion = IW_AUTH_WPA_VERSION_WPA;
10983 // Unpack the WPA IE
10984 //Skip past the EID byte and length byte - and four byte WiFi OUI
10985 dot11fUnpackIeWPA((tpAniSirGlobal) halHandle,
10986 &ie[2+4],
10987 ie[1] - 4,
10988 &dot11WPAIE);
10989 /*Extract the multicast cipher, the encType for unicast
10990 cipher for wpa-none is none*/
10991 encryptionType =
10992 hdd_TranslateWPAToCsrEncryptionType(dot11WPAIE.multicast_cipher);
10993 }
Jeff Johnson295189b2012-06-20 16:38:30 -070010994 }
Shailender Karmuchi67edd312013-06-18 16:30:48 -070010995
Jeff Johnson295189b2012-06-20 16:38:30 -070010996 status = wlan_hdd_cfg80211_set_ie(pAdapter, params->ie, params->ie_len);
10997
10998 if (0 > status)
10999 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011000 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: failed to parse WPA/RSN IE",
Jeff Johnson295189b2012-06-20 16:38:30 -070011001 __func__);
11002 return status;
11003 }
11004 }
11005
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011006 pWextState->roamProfile.AuthType.authType[0] =
11007 pHddStaCtx->conn_info.authType =
Jeff Johnson295189b2012-06-20 16:38:30 -070011008 eCSR_AUTH_TYPE_OPEN_SYSTEM;
11009
11010 if (params->privacy)
11011 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011012 /* Security enabled IBSS, At this time there is no information available
11013 * about the security paramters, so initialise the encryption type to
Jeff Johnson295189b2012-06-20 16:38:30 -070011014 * eCSR_ENCRYPT_TYPE_WEP40_STATICKEY.
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011015 * The correct security parameters will be updated later in
Jeff Johnson295189b2012-06-20 16:38:30 -070011016 * wlan_hdd_cfg80211_add_key */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011017 /* Hal expects encryption type to be set inorder
Jeff Johnson295189b2012-06-20 16:38:30 -070011018 *enable privacy bit in beacons */
11019
11020 encryptionType = eCSR_ENCRYPT_TYPE_WEP40_STATICKEY;
11021 }
Shailender Karmuchi642e9812013-05-30 14:34:49 -070011022 VOS_TRACE (VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO_HIGH,
11023 "encryptionType=%d", encryptionType);
Jeff Johnson295189b2012-06-20 16:38:30 -070011024 pHddStaCtx->conn_info.ucEncryptionType = encryptionType;
11025 pWextState->roamProfile.EncryptionType.numEntries = 1;
11026 pWextState->roamProfile.EncryptionType.encryptionType[0] = encryptionType;
Jeff Johnson295189b2012-06-20 16:38:30 -070011027 return status;
11028}
11029
11030/*
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053011031 * FUNCTION: __wlan_hdd_cfg80211_join_ibss
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011032 * This function is used to create/join an IBSS
Jeff Johnson295189b2012-06-20 16:38:30 -070011033 */
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053011034static int __wlan_hdd_cfg80211_join_ibss( struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -070011035 struct net_device *dev,
11036 struct cfg80211_ibss_params *params
11037 )
11038{
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011039 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( dev );
Jeff Johnson295189b2012-06-20 16:38:30 -070011040 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
11041 tCsrRoamProfile *pRoamProfile;
11042 int status;
krunal sonie9002db2013-11-25 14:24:17 -080011043 bool alloc_bssid = VOS_FALSE;
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053011044 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
11045 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Jeff Johnson295189b2012-06-20 16:38:30 -070011046
11047 ENTER();
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053011048
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053011049 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
11050 TRACE_CODE_HDD_CFG80211_JOIN_IBSS,
11051 pAdapter->sessionId, pAdapter->device_mode));
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011052 hddLog(VOS_TRACE_LEVEL_INFO,
Sushant Kaushik8bc7df22014-04-09 17:55:29 +053011053 "%s: device_mode = %s (%d)", __func__,
11054 hdd_device_modetoString(pAdapter->device_mode),
11055 pAdapter->device_mode);
Jeff Johnson295189b2012-06-20 16:38:30 -070011056
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053011057 status = wlan_hdd_validate_context(pHddCtx);
11058
11059 if (0 != status)
Jeff Johnson295189b2012-06-20 16:38:30 -070011060 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053011061 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
11062 "%s: HDD context is not valid", __func__);
11063 return status;
Jeff Johnson295189b2012-06-20 16:38:30 -070011064 }
11065
11066 if (NULL == pWextState)
11067 {
Arif Hussain6d2a3322013-11-17 19:50:10 -080011068 hddLog (VOS_TRACE_LEVEL_ERROR, "%s ERROR: Data Storage Corruption",
Jeff Johnson295189b2012-06-20 16:38:30 -070011069 __func__);
11070 return -EIO;
11071 }
11072
Agarwal Ashish51325b52014-06-16 16:50:49 +053011073 if (vos_max_concurrent_connections_reached()) {
11074 hddLog(VOS_TRACE_LEVEL_INFO, FL("Reached max concurrent connections"));
11075 return -ECONNREFUSED;
11076 }
11077
Vinay Krishna Eranna21042322014-01-08 19:21:39 +053011078 /*Try disconnecting if already in connected state*/
11079 status = wlan_hdd_try_disconnect(pAdapter);
11080 if ( 0 > status)
11081 {
11082 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Failed to disconnect the existing"
11083 " IBSS connection"));
11084 return -EALREADY;
11085 }
11086
Jeff Johnson295189b2012-06-20 16:38:30 -070011087 pRoamProfile = &pWextState->roamProfile;
11088
11089 if ( eCSR_BSS_TYPE_START_IBSS != pRoamProfile->BSSType )
11090 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011091 hddLog (VOS_TRACE_LEVEL_ERROR,
Arif Hussain6d2a3322013-11-17 19:50:10 -080011092 "%s Interface type is not set to IBSS", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -070011093 return -EINVAL;
11094 }
11095
Praveen Kumar Sirisillad123d142013-09-24 16:50:13 -070011096 /* BSSID is provided by upper layers hence no need to AUTO generate */
11097 if (NULL != params->bssid) {
11098 if (ccmCfgSetInt(pHddCtx->hHal, WNI_CFG_IBSS_AUTO_BSSID, 0,
11099 NULL, eANI_BOOLEAN_FALSE)==eHAL_STATUS_FAILURE) {
11100 hddLog (VOS_TRACE_LEVEL_ERROR,
11101 "%s:ccmCfgStInt faild for WNI_CFG_IBSS_AUTO_BSSID", __func__);
11102 return -EIO;
11103 }
11104 }
krunal sonie9002db2013-11-25 14:24:17 -080011105 else if(pHddCtx->cfg_ini->isCoalesingInIBSSAllowed == 0)
11106 {
11107 if (ccmCfgSetInt(pHddCtx->hHal, WNI_CFG_IBSS_AUTO_BSSID, 0,
11108 NULL, eANI_BOOLEAN_FALSE)==eHAL_STATUS_FAILURE)
11109 {
11110 hddLog (VOS_TRACE_LEVEL_ERROR,
11111 "%s:ccmCfgStInt faild for WNI_CFG_IBSS_AUTO_BSSID", __func__);
11112 return -EIO;
11113 }
11114 params->bssid = vos_mem_malloc(sizeof(VOS_MAC_ADDR_SIZE));
11115 if (!params->bssid)
11116 {
11117 hddLog (VOS_TRACE_LEVEL_ERROR,
11118 "%s:Failed memory allocation", __func__);
11119 return -EIO;
11120 }
11121 vos_mem_copy((v_U8_t *)params->bssid,
11122 (v_U8_t *)&pHddCtx->cfg_ini->IbssBssid.bytes[0],
11123 VOS_MAC_ADDR_SIZE);
11124 alloc_bssid = VOS_TRUE;
11125 }
Praveen Kumar Sirisillad123d142013-09-24 16:50:13 -070011126
Jeff Johnson295189b2012-06-20 16:38:30 -070011127 /* Set Channel */
Yue Maf49ba872013-08-19 12:04:25 -070011128 if (NULL !=
11129#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,8,0))
11130 params->chandef.chan)
11131#else
11132 params->channel)
11133#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070011134 {
11135 u8 channelNum;
Shailender Karmuchi15cd0672013-05-15 19:50:04 -070011136 v_U32_t numChans = WNI_CFG_VALID_CHANNEL_LIST_LEN;
11137 v_U8_t validChan[WNI_CFG_VALID_CHANNEL_LIST_LEN];
11138 tHalHandle hHal = WLAN_HDD_GET_HAL_CTX(pAdapter);
11139 int indx;
Jeff Johnson295189b2012-06-20 16:38:30 -070011140
11141 /* Get channel number */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011142 channelNum =
Yue Maf49ba872013-08-19 12:04:25 -070011143 ieee80211_frequency_to_channel(
11144#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,8,0))
11145 params->chandef.chan->center_freq);
11146#else
11147 params->channel->center_freq);
11148#endif
Shailender Karmuchi15cd0672013-05-15 19:50:04 -070011149
11150 if (0 != ccmCfgGetStr(hHal, WNI_CFG_VALID_CHANNEL_LIST,
11151 validChan, &numChans))
Jeff Johnson295189b2012-06-20 16:38:30 -070011152 {
Shailender Karmuchi15cd0672013-05-15 19:50:04 -070011153 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: No valid channel list",
11154 __func__);
11155 return -EOPNOTSUPP;
Jeff Johnson295189b2012-06-20 16:38:30 -070011156 }
Shailender Karmuchi15cd0672013-05-15 19:50:04 -070011157
11158 for (indx = 0; indx < numChans; indx++)
Jeff Johnson295189b2012-06-20 16:38:30 -070011159 {
Shailender Karmuchi15cd0672013-05-15 19:50:04 -070011160 if (channelNum == validChan[indx])
11161 {
11162 break;
11163 }
11164 }
11165 if (indx >= numChans)
11166 {
11167 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Not valid Channel %d",
Jeff Johnson295189b2012-06-20 16:38:30 -070011168 __func__, channelNum);
11169 return -EINVAL;
11170 }
Shailender Karmuchi15cd0672013-05-15 19:50:04 -070011171 /* Set the Operational Channel */
11172 hddLog(VOS_TRACE_LEVEL_INFO_HIGH, "%s: set channel %d", __func__,
11173 channelNum);
11174 pRoamProfile->ChannelInfo.numOfChannels = 1;
11175 pHddStaCtx->conn_info.operationChannel = channelNum;
11176 pRoamProfile->ChannelInfo.ChannelList =
11177 &pHddStaCtx->conn_info.operationChannel;
Jeff Johnson295189b2012-06-20 16:38:30 -070011178 }
11179
11180 /* Initialize security parameters */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011181 status = wlan_hdd_cfg80211_set_privacy_ibss(pAdapter, params);
Jeff Johnson295189b2012-06-20 16:38:30 -070011182 if (status < 0)
11183 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011184 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: failed to set security parameters",
Jeff Johnson295189b2012-06-20 16:38:30 -070011185 __func__);
11186 return status;
11187 }
11188
11189 /* Issue connect start */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011190 status = wlan_hdd_cfg80211_connect_start(pAdapter, params->ssid,
Shailender Karmuchi15cd0672013-05-15 19:50:04 -070011191 params->ssid_len, params->bssid,
11192 pHddStaCtx->conn_info.operationChannel);
Jeff Johnson295189b2012-06-20 16:38:30 -070011193
11194 if (0 > status)
11195 {
11196 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: connect failed", __func__);
11197 return status;
11198 }
11199
krunal sonie9002db2013-11-25 14:24:17 -080011200 if (NULL != params->bssid &&
11201 pHddCtx->cfg_ini->isCoalesingInIBSSAllowed == 0 &&
11202 alloc_bssid == VOS_TRUE)
11203 {
11204 vos_mem_free(params->bssid);
11205 }
Jeff Johnson295189b2012-06-20 16:38:30 -070011206 return 0;
11207}
11208
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053011209static int wlan_hdd_cfg80211_join_ibss( struct wiphy *wiphy,
11210 struct net_device *dev,
11211 struct cfg80211_ibss_params *params
11212 )
11213{
11214 int ret = 0;
11215
11216 vos_ssr_protect(__func__);
11217 ret = __wlan_hdd_cfg80211_join_ibss(wiphy, dev, params);
11218 vos_ssr_unprotect(__func__);
11219
11220 return ret;
11221}
11222
Jeff Johnson295189b2012-06-20 16:38:30 -070011223/*
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053011224 * FUNCTION: __wlan_hdd_cfg80211_leave_ibss
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011225 * This function is used to leave an IBSS
Jeff Johnson295189b2012-06-20 16:38:30 -070011226 */
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053011227static int __wlan_hdd_cfg80211_leave_ibss( struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -070011228 struct net_device *dev
11229 )
11230{
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011231 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( dev );
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053011232 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
11233 tCsrRoamProfile *pRoamProfile;
11234 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053011235 int status;
Jeff Johnson295189b2012-06-20 16:38:30 -070011236
11237 ENTER();
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053011238
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053011239 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
11240 TRACE_CODE_HDD_CFG80211_LEAVE_IBSS,
11241 pAdapter->sessionId, eCSR_DISCONNECT_REASON_IBSS_LEAVE));
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053011242 status = wlan_hdd_validate_context(pHddCtx);
11243
11244 if (0 != status)
Jeff Johnson04dd8a82012-06-29 20:41:40 -070011245 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053011246 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
11247 "%s: HDD context is not valid", __func__);
11248 return status;
Jeff Johnson04dd8a82012-06-29 20:41:40 -070011249 }
11250
Sushant Kaushik8bc7df22014-04-09 17:55:29 +053011251 hddLog(VOS_TRACE_LEVEL_INFO, "%s: device_mode = %s (%d)", __func__,
11252 hdd_device_modetoString(pAdapter->device_mode),
11253 pAdapter->device_mode);
Jeff Johnson295189b2012-06-20 16:38:30 -070011254 if (NULL == pWextState)
11255 {
Arif Hussain6d2a3322013-11-17 19:50:10 -080011256 hddLog (VOS_TRACE_LEVEL_ERROR, "%s ERROR: Data Storage Corruption",
Jeff Johnson295189b2012-06-20 16:38:30 -070011257 __func__);
11258 return -EIO;
11259 }
11260
11261 pRoamProfile = &pWextState->roamProfile;
11262
11263 /* Issue disconnect only if interface type is set to IBSS */
11264 if (eCSR_BSS_TYPE_START_IBSS != pRoamProfile->BSSType)
11265 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011266 hddLog (VOS_TRACE_LEVEL_ERROR, "%s: BSS Type is not set to IBSS",
Jeff Johnson295189b2012-06-20 16:38:30 -070011267 __func__);
11268 return -EINVAL;
11269 }
11270
11271 /* Issue Disconnect request */
11272 INIT_COMPLETION(pAdapter->disconnect_comp_var);
11273 sme_RoamDisconnect( WLAN_HDD_GET_HAL_CTX(pAdapter), pAdapter->sessionId,
11274 eCSR_DISCONNECT_REASON_IBSS_LEAVE);
11275
11276 return 0;
11277}
11278
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053011279static int wlan_hdd_cfg80211_leave_ibss( struct wiphy *wiphy,
11280 struct net_device *dev
11281 )
11282{
11283 int ret = 0;
11284
11285 vos_ssr_protect(__func__);
11286 ret = __wlan_hdd_cfg80211_leave_ibss(wiphy, dev);
11287 vos_ssr_unprotect(__func__);
11288
11289 return ret;
11290}
11291
Jeff Johnson295189b2012-06-20 16:38:30 -070011292/*
Mahesh A Saptasagar179d2252014-06-02 21:32:21 +053011293 * FUNCTION: __wlan_hdd_cfg80211_set_wiphy_params
Jeff Johnson295189b2012-06-20 16:38:30 -070011294 * This function is used to set the phy parameters
11295 * (RTS Threshold/FRAG Threshold/Retry Count etc ...)
11296 */
Mahesh A Saptasagar179d2252014-06-02 21:32:21 +053011297static int __wlan_hdd_cfg80211_set_wiphy_params(struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -070011298 u32 changed)
11299{
11300 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
11301 tHalHandle hHal = pHddCtx->hHal;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053011302 int status;
Jeff Johnson295189b2012-06-20 16:38:30 -070011303
11304 ENTER();
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053011305 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
11306 TRACE_CODE_HDD_CFG80211_SET_WIPHY_PARAMS,
11307 NO_SESSION, wiphy->rts_threshold));
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053011308 status = wlan_hdd_validate_context(pHddCtx);
11309
11310 if (0 != status)
Jeff Johnson04dd8a82012-06-29 20:41:40 -070011311 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053011312 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
11313 "%s: HDD context is not valid", __func__);
11314 return status;
Jeff Johnson04dd8a82012-06-29 20:41:40 -070011315 }
11316
Jeff Johnson295189b2012-06-20 16:38:30 -070011317 if (changed & WIPHY_PARAM_RTS_THRESHOLD)
11318 {
11319 u16 rts_threshold = (wiphy->rts_threshold == -1) ?
11320 WNI_CFG_RTS_THRESHOLD_STAMAX :
11321 wiphy->rts_threshold;
11322
11323 if ((WNI_CFG_RTS_THRESHOLD_STAMIN > rts_threshold) ||
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011324 (WNI_CFG_RTS_THRESHOLD_STAMAX < rts_threshold))
Jeff Johnson295189b2012-06-20 16:38:30 -070011325 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011326 hddLog(VOS_TRACE_LEVEL_ERROR,
11327 "%s: Invalid RTS Threshold value %hu",
Jeff Johnson295189b2012-06-20 16:38:30 -070011328 __func__, rts_threshold);
11329 return -EINVAL;
11330 }
11331
11332 if (0 != ccmCfgSetInt(hHal, WNI_CFG_RTS_THRESHOLD,
11333 rts_threshold, ccmCfgSetCallback,
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011334 eANI_BOOLEAN_TRUE))
Jeff Johnson295189b2012-06-20 16:38:30 -070011335 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011336 hddLog(VOS_TRACE_LEVEL_ERROR,
11337 "%s: ccmCfgSetInt failed for rts_threshold value %hu",
Jeff Johnson295189b2012-06-20 16:38:30 -070011338 __func__, rts_threshold);
11339 return -EIO;
11340 }
11341
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011342 hddLog(VOS_TRACE_LEVEL_INFO_MED, "%s: set rts threshold %hu", __func__,
Jeff Johnson295189b2012-06-20 16:38:30 -070011343 rts_threshold);
11344 }
11345
11346 if (changed & WIPHY_PARAM_FRAG_THRESHOLD)
11347 {
11348 u16 frag_threshold = (wiphy->frag_threshold == -1) ?
11349 WNI_CFG_FRAGMENTATION_THRESHOLD_STAMAX :
11350 wiphy->frag_threshold;
11351
11352 if ((WNI_CFG_FRAGMENTATION_THRESHOLD_STAMIN > frag_threshold)||
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011353 (WNI_CFG_FRAGMENTATION_THRESHOLD_STAMAX < frag_threshold) )
Jeff Johnson295189b2012-06-20 16:38:30 -070011354 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011355 hddLog(VOS_TRACE_LEVEL_ERROR,
11356 "%s: Invalid frag_threshold value %hu", __func__,
Jeff Johnson295189b2012-06-20 16:38:30 -070011357 frag_threshold);
11358 return -EINVAL;
11359 }
11360
11361 if (0 != ccmCfgSetInt(hHal, WNI_CFG_FRAGMENTATION_THRESHOLD,
11362 frag_threshold, ccmCfgSetCallback,
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011363 eANI_BOOLEAN_TRUE))
Jeff Johnson295189b2012-06-20 16:38:30 -070011364 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011365 hddLog(VOS_TRACE_LEVEL_ERROR,
11366 "%s: ccmCfgSetInt failed for frag_threshold value %hu",
Jeff Johnson295189b2012-06-20 16:38:30 -070011367 __func__, frag_threshold);
11368 return -EIO;
11369 }
11370
11371 hddLog(VOS_TRACE_LEVEL_INFO_MED, "%s: set frag threshold %hu", __func__,
11372 frag_threshold);
11373 }
11374
11375 if ((changed & WIPHY_PARAM_RETRY_SHORT)
11376 || (changed & WIPHY_PARAM_RETRY_LONG))
11377 {
11378 u8 retry_value = (changed & WIPHY_PARAM_RETRY_SHORT) ?
11379 wiphy->retry_short :
11380 wiphy->retry_long;
11381
11382 if ((WNI_CFG_LONG_RETRY_LIMIT_STAMIN > retry_value) ||
11383 (WNI_CFG_LONG_RETRY_LIMIT_STAMAX < retry_value))
11384 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011385 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Invalid Retry count %hu",
Jeff Johnson295189b2012-06-20 16:38:30 -070011386 __func__, retry_value);
11387 return -EINVAL;
11388 }
11389
11390 if (changed & WIPHY_PARAM_RETRY_SHORT)
11391 {
11392 if (0 != ccmCfgSetInt(hHal, WNI_CFG_LONG_RETRY_LIMIT,
11393 retry_value, ccmCfgSetCallback,
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011394 eANI_BOOLEAN_TRUE))
Jeff Johnson295189b2012-06-20 16:38:30 -070011395 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011396 hddLog(VOS_TRACE_LEVEL_ERROR,
11397 "%s: ccmCfgSetInt failed for long retry count %hu",
Jeff Johnson295189b2012-06-20 16:38:30 -070011398 __func__, retry_value);
11399 return -EIO;
11400 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011401 hddLog(VOS_TRACE_LEVEL_INFO_MED, "%s: set long retry count %hu",
Jeff Johnson295189b2012-06-20 16:38:30 -070011402 __func__, retry_value);
11403 }
11404 else if (changed & WIPHY_PARAM_RETRY_SHORT)
11405 {
11406 if (0 != ccmCfgSetInt(hHal, WNI_CFG_SHORT_RETRY_LIMIT,
11407 retry_value, ccmCfgSetCallback,
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011408 eANI_BOOLEAN_TRUE))
Jeff Johnson295189b2012-06-20 16:38:30 -070011409 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011410 hddLog(VOS_TRACE_LEVEL_ERROR,
11411 "%s: ccmCfgSetInt failed for short retry count %hu",
Jeff Johnson295189b2012-06-20 16:38:30 -070011412 __func__, retry_value);
11413 return -EIO;
11414 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011415 hddLog(VOS_TRACE_LEVEL_INFO_MED, "%s: set short retry count %hu",
Jeff Johnson295189b2012-06-20 16:38:30 -070011416 __func__, retry_value);
11417 }
11418 }
11419
11420 return 0;
11421}
11422
Mahesh A Saptasagar179d2252014-06-02 21:32:21 +053011423static int wlan_hdd_cfg80211_set_wiphy_params(struct wiphy *wiphy,
11424 u32 changed)
11425{
11426 int ret;
11427
11428 vos_ssr_protect(__func__);
11429 ret = __wlan_hdd_cfg80211_set_wiphy_params(wiphy, changed);
11430 vos_ssr_unprotect(__func__);
11431
11432 return ret;
11433}
11434
Jeff Johnson295189b2012-06-20 16:38:30 -070011435/*
Mahesh A Saptasagar179d2252014-06-02 21:32:21 +053011436 * FUNCTION: __wlan_hdd_cfg80211_set_txpower
Jeff Johnson295189b2012-06-20 16:38:30 -070011437 * This function is used to set the txpower
11438 */
Mahesh A Saptasagar179d2252014-06-02 21:32:21 +053011439static int __wlan_hdd_cfg80211_set_txpower(struct wiphy *wiphy,
Yue Maf49ba872013-08-19 12:04:25 -070011440#if LINUX_VERSION_CODE >= KERNEL_VERSION(3,8,0)
11441 struct wireless_dev *wdev,
11442#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070011443#if LINUX_VERSION_CODE <= KERNEL_VERSION(2,6,35)
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011444 enum tx_power_setting type,
Jeff Johnson295189b2012-06-20 16:38:30 -070011445#else
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011446 enum nl80211_tx_power_setting type,
Jeff Johnson295189b2012-06-20 16:38:30 -070011447#endif
11448 int dbm)
11449{
11450 hdd_context_t *pHddCtx = (hdd_context_t*) wiphy_priv(wiphy);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053011451 tHalHandle hHal = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -070011452 tSirMacAddr bssid = {0xFF,0xFF,0xFF,0xFF,0xFF,0xFF};
11453 tSirMacAddr selfMac = {0xFF,0xFF,0xFF,0xFF,0xFF,0xFF};
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053011454 int status;
Jeff Johnson295189b2012-06-20 16:38:30 -070011455
11456 ENTER();
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053011457 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
11458 TRACE_CODE_HDD_CFG80211_SET_TXPOWER,
11459 NO_SESSION, type ));
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053011460 status = wlan_hdd_validate_context(pHddCtx);
11461
11462 if (0 != status)
11463 {
11464 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
11465 "%s: HDD context is not valid", __func__);
11466 return status;
11467 }
11468
11469 hHal = pHddCtx->hHal;
11470
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011471 if (0 != ccmCfgSetInt(hHal, WNI_CFG_CURRENT_TX_POWER_LEVEL,
11472 dbm, ccmCfgSetCallback,
11473 eANI_BOOLEAN_TRUE))
Jeff Johnson295189b2012-06-20 16:38:30 -070011474 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011475 hddLog(VOS_TRACE_LEVEL_ERROR,
Jeff Johnson295189b2012-06-20 16:38:30 -070011476 "%s: ccmCfgSetInt failed for tx power %hu", __func__, dbm);
11477 return -EIO;
11478 }
11479
11480 hddLog(VOS_TRACE_LEVEL_INFO_MED, "%s: set tx power level %d dbm", __func__,
11481 dbm);
11482
11483 switch(type)
11484 {
11485 case NL80211_TX_POWER_AUTOMATIC: /*automatically determine transmit power*/
11486 /* Fall through */
11487 case NL80211_TX_POWER_LIMITED: /*limit TX power by the mBm parameter*/
11488 if( sme_SetMaxTxPower(hHal, bssid, selfMac, dbm) != eHAL_STATUS_SUCCESS )
11489 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011490 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Setting maximum tx power failed",
11491 __func__);
11492 return -EIO;
Jeff Johnson295189b2012-06-20 16:38:30 -070011493 }
11494 break;
11495 case NL80211_TX_POWER_FIXED: /*fix TX power to the mBm parameter*/
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011496 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: NL80211_TX_POWER_FIXED not supported",
Jeff Johnson295189b2012-06-20 16:38:30 -070011497 __func__);
11498 return -EOPNOTSUPP;
11499 break;
11500 default:
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011501 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Invalid power setting type %d",
11502 __func__, type);
Jeff Johnson295189b2012-06-20 16:38:30 -070011503 return -EIO;
11504 }
11505
11506 return 0;
11507}
11508
Mahesh A Saptasagar179d2252014-06-02 21:32:21 +053011509static int wlan_hdd_cfg80211_set_txpower(struct wiphy *wiphy,
11510#if LINUX_VERSION_CODE >= KERNEL_VERSION(3,8,0)
11511 struct wireless_dev *wdev,
11512#endif
11513#if LINUX_VERSION_CODE <= KERNEL_VERSION(2,6,35)
11514 enum tx_power_setting type,
11515#else
11516 enum nl80211_tx_power_setting type,
11517#endif
11518 int dbm)
11519{
11520 int ret;
11521 vos_ssr_protect(__func__);
11522 ret = __wlan_hdd_cfg80211_set_txpower(wiphy,
11523#if LINUX_VERSION_CODE >= KERNEL_VERSION(3,8,0)
11524 wdev,
11525#endif
11526#if LINUX_VERSION_CODE <= KERNEL_VERSION(2,6,35)
11527 type,
11528#else
11529 type,
11530#endif
11531 dbm);
11532 vos_ssr_unprotect(__func__);
11533
11534 return ret;
11535}
11536
Jeff Johnson295189b2012-06-20 16:38:30 -070011537/*
11538 * FUNCTION: wlan_hdd_cfg80211_get_txpower
11539 * This function is used to read the txpower
11540 */
Yue Maf49ba872013-08-19 12:04:25 -070011541static int wlan_hdd_cfg80211_get_txpower(struct wiphy *wiphy,
11542#if LINUX_VERSION_CODE >= KERNEL_VERSION(3,8,0)
11543 struct wireless_dev *wdev,
11544#endif
11545 int *dbm)
Jeff Johnson295189b2012-06-20 16:38:30 -070011546{
11547
11548 hdd_adapter_t *pAdapter;
11549 hdd_context_t *pHddCtx = (hdd_context_t*) wiphy_priv(wiphy);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053011550 int status;
Jeff Johnson295189b2012-06-20 16:38:30 -070011551
Jeff Johnsone7245742012-09-05 17:12:55 -070011552 ENTER();
11553
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053011554 status = wlan_hdd_validate_context(pHddCtx);
Jeff Johnson295189b2012-06-20 16:38:30 -070011555
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053011556 if (0 != status)
Jeff Johnson04dd8a82012-06-29 20:41:40 -070011557 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053011558 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
11559 "%s: HDD context is not valid", __func__);
11560 *dbm = 0;
11561 return status;
Jeff Johnson04dd8a82012-06-29 20:41:40 -070011562 }
11563
Jeff Johnson295189b2012-06-20 16:38:30 -070011564 pAdapter = hdd_get_adapter(pHddCtx, WLAN_HDD_INFRA_STATION);
11565 if (NULL == pAdapter)
11566 {
11567 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: Not in station context " ,__func__);
11568 return -ENOENT;
11569 }
11570
11571 wlan_hdd_get_classAstats(pAdapter);
11572 *dbm = pAdapter->hdd_stats.ClassA_stat.max_pwr;
11573
Jeff Johnsone7245742012-09-05 17:12:55 -070011574 EXIT();
Jeff Johnson295189b2012-06-20 16:38:30 -070011575 return 0;
11576}
11577
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053011578static int __wlan_hdd_cfg80211_get_station(struct wiphy *wiphy, struct net_device *dev,
Jeff Johnson295189b2012-06-20 16:38:30 -070011579 u8* mac, struct station_info *sinfo)
11580{
11581 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( dev );
11582 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
11583 int ssidlen = pHddStaCtx->conn_info.SSID.SSID.length;
c_hpothu44ff4e02014-05-08 00:13:57 +053011584 tANI_U32 rate_flags;
Jeff Johnson295189b2012-06-20 16:38:30 -070011585
11586 hdd_context_t *pHddCtx = (hdd_context_t*) wiphy_priv(wiphy);
11587 hdd_config_t *pCfg = pHddCtx->cfg_ini;
Jeff Johnson295189b2012-06-20 16:38:30 -070011588
11589 tANI_U8 OperationalRates[CSR_DOT11_SUPPORTED_RATES_MAX];
11590 tANI_U32 ORLeng = CSR_DOT11_SUPPORTED_RATES_MAX;
11591 tANI_U8 ExtendedRates[CSR_DOT11_EXTENDED_SUPPORTED_RATES_MAX];
11592 tANI_U32 ERLeng = CSR_DOT11_EXTENDED_SUPPORTED_RATES_MAX;
11593 tANI_U8 MCSRates[SIZE_OF_BASIC_MCS_SET];
11594 tANI_U32 MCSLeng = SIZE_OF_BASIC_MCS_SET;
11595 tANI_U16 maxRate = 0;
11596 tANI_U16 myRate;
11597 tANI_U16 currentRate = 0;
11598 tANI_U8 maxSpeedMCS = 0;
11599 tANI_U8 maxMCSIdx = 0;
11600 tANI_U8 rateFlag = 1;
c_hpothu79aab322014-07-14 21:11:01 +053011601 tANI_U8 i, j, rssidx, mode=0;
Madan Mohan Koyyalamudic75be962012-10-18 19:19:03 -070011602 tANI_U16 temp;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053011603 int status;
Jeff Johnson295189b2012-06-20 16:38:30 -070011604
Leo Chang6f8870f2013-03-26 18:11:36 -070011605#ifdef WLAN_FEATURE_11AC
11606 tANI_U32 vht_mcs_map;
11607 eDataRate11ACMaxMcs vhtMaxMcs;
11608#endif /* WLAN_FEATURE_11AC */
11609
Jeff Johnsone7245742012-09-05 17:12:55 -070011610 ENTER();
11611
Jeff Johnson295189b2012-06-20 16:38:30 -070011612 if ((eConnectionState_Associated != pHddStaCtx->conn_info.connState) ||
11613 (0 == ssidlen))
11614 {
11615 hddLog(VOS_TRACE_LEVEL_INFO, "%s: Not associated or"
11616 " Invalid ssidlen, %d", __func__, ssidlen);
11617 /*To keep GUI happy*/
11618 return 0;
11619 }
11620
Mukul Sharma811205f2014-07-09 21:07:30 +053011621 if (VOS_TRUE == pHddStaCtx->hdd_ReassocScenario)
11622 {
11623 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
11624 "%s: Roaming in progress, so unable to proceed this request", __func__);
11625 return 0;
11626 }
11627
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053011628 status = wlan_hdd_validate_context(pHddCtx);
11629
11630 if (0 != status)
Jeff Johnson04dd8a82012-06-29 20:41:40 -070011631 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053011632 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
11633 "%s: HDD context is not valid", __func__);
11634 return status;
Jeff Johnson04dd8a82012-06-29 20:41:40 -070011635 }
11636
Jeff Johnson295189b2012-06-20 16:38:30 -070011637
Kiet Lam3b17fc82013-09-27 05:24:08 +053011638 wlan_hdd_get_rssi(pAdapter, &sinfo->signal);
11639 sinfo->filled |= STATION_INFO_SIGNAL;
11640
c_hpothu09f19542014-05-30 21:53:31 +053011641 wlan_hdd_get_station_stats(pAdapter);
11642 rate_flags = pAdapter->hdd_stats.ClassA_stat.tx_rate_flags;
11643
11644 /*overwrite rate_flags if MAX link-speed need to be reported*/
c_hpothu44ff4e02014-05-08 00:13:57 +053011645 if ((eHDD_LINK_SPEED_REPORT_MAX == pCfg->reportMaxLinkSpeed) ||
11646 (eHDD_LINK_SPEED_REPORT_MAX_SCALED == pCfg->reportMaxLinkSpeed &&
c_hpothu79aab322014-07-14 21:11:01 +053011647 sinfo->signal >= pCfg->linkSpeedRssiLow))
c_hpothu44ff4e02014-05-08 00:13:57 +053011648 {
11649 rate_flags = pAdapter->maxRateFlags;
11650 }
c_hpothu44ff4e02014-05-08 00:13:57 +053011651
Jeff Johnson295189b2012-06-20 16:38:30 -070011652 //convert to the UI units of 100kbps
11653 myRate = pAdapter->hdd_stats.ClassA_stat.tx_rate * 5;
11654
11655#ifdef LINKSPEED_DEBUG_ENABLED
Leo Chang6f8870f2013-03-26 18:11:36 -070011656 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 -070011657 sinfo->signal,
11658 pCfg->reportMaxLinkSpeed,
11659 myRate,
11660 (int) pCfg->linkSpeedRssiHigh,
Madan Mohan Koyyalamudi8df78d52012-11-02 12:30:06 -070011661 (int) pCfg->linkSpeedRssiMid,
11662 (int) pCfg->linkSpeedRssiLow,
Leo Chang6f8870f2013-03-26 18:11:36 -070011663 (int) rate_flags,
11664 (int) pAdapter->hdd_stats.ClassA_stat.mcs_index);
Jeff Johnson295189b2012-06-20 16:38:30 -070011665#endif //LINKSPEED_DEBUG_ENABLED
11666
11667 if (eHDD_LINK_SPEED_REPORT_ACTUAL != pCfg->reportMaxLinkSpeed)
11668 {
11669 // we do not want to necessarily report the current speed
11670 if (eHDD_LINK_SPEED_REPORT_MAX == pCfg->reportMaxLinkSpeed)
11671 {
11672 // report the max possible speed
11673 rssidx = 0;
11674 }
11675 else if (eHDD_LINK_SPEED_REPORT_MAX_SCALED == pCfg->reportMaxLinkSpeed)
11676 {
11677 // report the max possible speed with RSSI scaling
11678 if (sinfo->signal >= pCfg->linkSpeedRssiHigh)
11679 {
11680 // report the max possible speed
11681 rssidx = 0;
11682 }
Madan Mohan Koyyalamudi8df78d52012-11-02 12:30:06 -070011683 else if (sinfo->signal >= pCfg->linkSpeedRssiMid)
Jeff Johnson295189b2012-06-20 16:38:30 -070011684 {
11685 // report middle speed
11686 rssidx = 1;
11687 }
Madan Mohan Koyyalamudi8df78d52012-11-02 12:30:06 -070011688 else if (sinfo->signal >= pCfg->linkSpeedRssiLow)
11689 {
11690 // report middle speed
11691 rssidx = 2;
11692 }
Jeff Johnson295189b2012-06-20 16:38:30 -070011693 else
11694 {
11695 // report actual speed
Madan Mohan Koyyalamudi8df78d52012-11-02 12:30:06 -070011696 rssidx = 3;
Jeff Johnson295189b2012-06-20 16:38:30 -070011697 }
11698 }
11699 else
11700 {
11701 // unknown, treat as eHDD_LINK_SPEED_REPORT_MAX
11702 hddLog(VOS_TRACE_LEVEL_ERROR,
11703 "%s: Invalid value for reportMaxLinkSpeed: %u",
11704 __func__, pCfg->reportMaxLinkSpeed);
11705 rssidx = 0;
11706 }
11707
11708 maxRate = 0;
11709
11710 /* Get Basic Rate Set */
Gopichand Nakkala05ab1322013-02-15 11:28:38 +053011711 if (0 != ccmCfgGetStr(WLAN_HDD_GET_HAL_CTX(pAdapter), WNI_CFG_OPERATIONAL_RATE_SET,
11712 OperationalRates, &ORLeng))
11713 {
11714 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: ccm api returned failure", __func__);
11715 /*To keep GUI happy*/
11716 return 0;
11717 }
11718
Jeff Johnson295189b2012-06-20 16:38:30 -070011719 for (i = 0; i < ORLeng; i++)
11720 {
Jeff Johnsone7245742012-09-05 17:12:55 -070011721 for (j = 0; j < (sizeof(supported_data_rate) / sizeof(supported_data_rate[0])); j ++)
Jeff Johnson295189b2012-06-20 16:38:30 -070011722 {
11723 /* Validate Rate Set */
11724 if (supported_data_rate[j].beacon_rate_index == (OperationalRates[i] & 0x7F))
11725 {
11726 currentRate = supported_data_rate[j].supported_rate[rssidx];
11727 break;
11728 }
11729 }
11730 /* Update MAX rate */
11731 maxRate = (currentRate > maxRate)?currentRate:maxRate;
11732 }
11733
11734 /* Get Extended Rate Set */
Gopichand Nakkala05ab1322013-02-15 11:28:38 +053011735 if (0 != ccmCfgGetStr(WLAN_HDD_GET_HAL_CTX(pAdapter), WNI_CFG_EXTENDED_OPERATIONAL_RATE_SET,
11736 ExtendedRates, &ERLeng))
11737 {
11738 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: ccm api returned failure", __func__);
11739 /*To keep GUI happy*/
11740 return 0;
11741 }
11742
Jeff Johnson295189b2012-06-20 16:38:30 -070011743 for (i = 0; i < ERLeng; i++)
11744 {
Jeff Johnsone7245742012-09-05 17:12:55 -070011745 for (j = 0; j < (sizeof(supported_data_rate) / sizeof(supported_data_rate[0])); j ++)
Jeff Johnson295189b2012-06-20 16:38:30 -070011746 {
11747 if (supported_data_rate[j].beacon_rate_index == (ExtendedRates[i] & 0x7F))
11748 {
11749 currentRate = supported_data_rate[j].supported_rate[rssidx];
11750 break;
11751 }
11752 }
11753 /* Update MAX rate */
11754 maxRate = (currentRate > maxRate)?currentRate:maxRate;
11755 }
c_hpothu79aab322014-07-14 21:11:01 +053011756
Kiet Lamb69f8dc2013-11-15 15:34:27 +053011757 /* Get MCS Rate Set --
Kaushik, Sushantdc304d82014-01-22 10:58:37 +053011758 Only if we are always reporting max speed (or)
Kiet Lamb69f8dc2013-11-15 15:34:27 +053011759 if we have good rssi */
c_hpothu79aab322014-07-14 21:11:01 +053011760 if ((3 != rssidx) && !(rate_flags & eHAL_TX_RATE_LEGACY))
Jeff Johnson295189b2012-06-20 16:38:30 -070011761 {
c_hpothu79aab322014-07-14 21:11:01 +053011762 if (rate_flags & eHAL_TX_RATE_VHT80)
11763 mode = 2;
11764 else if (rate_flags & (eHAL_TX_RATE_VHT40 | eHAL_TX_RATE_HT40))
11765 mode = 1;
11766 else
11767 mode = 0;
11768
Gopichand Nakkala05ab1322013-02-15 11:28:38 +053011769 if (0 != ccmCfgGetStr(WLAN_HDD_GET_HAL_CTX(pAdapter), WNI_CFG_CURRENT_MCS_SET,
11770 MCSRates, &MCSLeng))
11771 {
11772 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: ccm api returned failure", __func__);
11773 /*To keep GUI happy*/
11774 return 0;
11775 }
Jeff Johnson295189b2012-06-20 16:38:30 -070011776 rateFlag = 0;
Leo Chang6f8870f2013-03-26 18:11:36 -070011777#ifdef WLAN_FEATURE_11AC
11778 /* VHT80 rate has seperate rate table */
Gopichand Nakkala4c705372013-04-24 13:20:33 +053011779 if (rate_flags & (eHAL_TX_RATE_VHT20|eHAL_TX_RATE_VHT40|eHAL_TX_RATE_VHT80))
Jeff Johnson295189b2012-06-20 16:38:30 -070011780 {
Leo Chang6f8870f2013-03-26 18:11:36 -070011781 ccmCfgGetInt(WLAN_HDD_GET_HAL_CTX(pAdapter), WNI_CFG_VHT_TX_MCS_MAP, &vht_mcs_map);
Gopichand Nakkala4c705372013-04-24 13:20:33 +053011782 vhtMaxMcs = (eDataRate11ACMaxMcs)(vht_mcs_map & DATA_RATE_11AC_MCS_MASK );
Leo Chang6f8870f2013-03-26 18:11:36 -070011783 if (rate_flags & eHAL_TX_RATE_SGI)
Jeff Johnson295189b2012-06-20 16:38:30 -070011784 {
Leo Chang6f8870f2013-03-26 18:11:36 -070011785 rateFlag |= 1;
Jeff Johnson295189b2012-06-20 16:38:30 -070011786 }
Leo Chang6f8870f2013-03-26 18:11:36 -070011787 if (DATA_RATE_11AC_MAX_MCS_7 == vhtMaxMcs)
Jeff Johnson295189b2012-06-20 16:38:30 -070011788 {
Leo Chang6f8870f2013-03-26 18:11:36 -070011789 maxMCSIdx = 7;
11790 }
11791 else if (DATA_RATE_11AC_MAX_MCS_8 == vhtMaxMcs)
11792 {
11793 maxMCSIdx = 8;
11794 }
11795 else if (DATA_RATE_11AC_MAX_MCS_9 == vhtMaxMcs)
11796 {
Gopichand Nakkala4c705372013-04-24 13:20:33 +053011797 //VHT20 is supporting 0~8
11798 if (rate_flags & eHAL_TX_RATE_VHT20)
11799 maxMCSIdx = 8;
11800 else
11801 maxMCSIdx = 9;
Leo Chang6f8870f2013-03-26 18:11:36 -070011802 }
Gopichand Nakkala4c705372013-04-24 13:20:33 +053011803
c_hpothu79aab322014-07-14 21:11:01 +053011804 if (0 != rssidx)/*check for scaled */
11805 {
11806 //get middle rate MCS index if rssi=1/2
11807 for (i=0; i <= maxMCSIdx; i++)
11808 {
11809 if (sinfo->signal <= rssiMcsTbl[mode][i])
11810 {
11811 maxMCSIdx = i;
11812 break;
11813 }
11814 }
11815 }
11816
Gopichand Nakkala4c705372013-04-24 13:20:33 +053011817 if (rate_flags & eHAL_TX_RATE_VHT80)
11818 {
11819 currentRate = supported_vht_mcs_rate[pAdapter->hdd_stats.ClassA_stat.mcs_index].supported_VHT80_rate[rateFlag];
11820 maxRate = supported_vht_mcs_rate[maxMCSIdx].supported_VHT80_rate[rateFlag];
11821 }
11822 else if (rate_flags & eHAL_TX_RATE_VHT40)
11823 {
11824 currentRate = supported_vht_mcs_rate[pAdapter->hdd_stats.ClassA_stat.mcs_index].supported_VHT40_rate[rateFlag];
11825 maxRate = supported_vht_mcs_rate[maxMCSIdx].supported_VHT40_rate[rateFlag];
11826 }
11827 else if (rate_flags & eHAL_TX_RATE_VHT20)
11828 {
11829 currentRate = supported_vht_mcs_rate[pAdapter->hdd_stats.ClassA_stat.mcs_index].supported_VHT20_rate[rateFlag];
11830 maxRate = supported_vht_mcs_rate[maxMCSIdx].supported_VHT20_rate[rateFlag];
11831 }
11832
Leo Chang6f8870f2013-03-26 18:11:36 -070011833 maxSpeedMCS = 1;
11834 if (currentRate > maxRate)
11835 {
11836 maxRate = currentRate;
11837 }
Gopichand Nakkala4c705372013-04-24 13:20:33 +053011838
Leo Chang6f8870f2013-03-26 18:11:36 -070011839 }
11840 else
11841#endif /* WLAN_FEATURE_11AC */
11842 {
11843 if (rate_flags & eHAL_TX_RATE_HT40)
11844 {
11845 rateFlag |= 1;
11846 }
11847 if (rate_flags & eHAL_TX_RATE_SGI)
11848 {
11849 rateFlag |= 2;
11850 }
11851
Girish Gowli01abcee2014-07-31 20:18:55 +053011852 temp = sizeof(supported_mcs_rate) / sizeof(supported_mcs_rate[0]);
c_hpothu79aab322014-07-14 21:11:01 +053011853 if (rssidx == 1 || rssidx == 2)
11854 {
11855 //get middle rate MCS index if rssi=1/2
11856 for (i=0; i <= 7; i++)
11857 {
11858 if (sinfo->signal <= rssiMcsTbl[mode][i])
11859 {
11860 temp = i+1;
11861 break;
11862 }
11863 }
11864 }
c_hpothu79aab322014-07-14 21:11:01 +053011865
11866 for (i = 0; i < MCSLeng; i++)
11867 {
Leo Chang6f8870f2013-03-26 18:11:36 -070011868 for (j = 0; j < temp; j++)
11869 {
11870 if (supported_mcs_rate[j].beacon_rate_index == MCSRates[i])
11871 {
11872 currentRate = supported_mcs_rate[j].supported_rate[rateFlag];
11873 break;
11874 }
11875 }
11876 if ((j < temp) && (currentRate > maxRate))
11877 {
11878 maxRate = currentRate;
11879 maxSpeedMCS = 1;
11880 maxMCSIdx = supported_mcs_rate[j].beacon_rate_index;
11881 }
Jeff Johnson295189b2012-06-20 16:38:30 -070011882 }
11883 }
11884 }
11885
Gopichand Nakkala4c705372013-04-24 13:20:33 +053011886 else if (!(rate_flags & eHAL_TX_RATE_LEGACY))
11887 {
11888 maxRate = myRate;
11889 maxSpeedMCS = 1;
11890 maxMCSIdx = pAdapter->hdd_stats.ClassA_stat.mcs_index;
11891 }
Jeff Johnson295189b2012-06-20 16:38:30 -070011892 // make sure we report a value at least as big as our current rate
c_hpothu79aab322014-07-14 21:11:01 +053011893 if ((maxRate < myRate) || (0 == maxRate))
Jeff Johnson295189b2012-06-20 16:38:30 -070011894 {
11895 maxRate = myRate;
11896 if (rate_flags & eHAL_TX_RATE_LEGACY)
11897 {
11898 maxSpeedMCS = 0;
11899 }
11900 else
11901 {
11902 maxSpeedMCS = 1;
11903 maxMCSIdx = pAdapter->hdd_stats.ClassA_stat.mcs_index;
11904 }
11905 }
11906
Gopichand Nakkala4c705372013-04-24 13:20:33 +053011907 if (rate_flags & eHAL_TX_RATE_LEGACY)
Jeff Johnson295189b2012-06-20 16:38:30 -070011908 {
11909 sinfo->txrate.legacy = maxRate;
11910#ifdef LINKSPEED_DEBUG_ENABLED
11911 pr_info("Reporting legacy rate %d\n", sinfo->txrate.legacy);
11912#endif //LINKSPEED_DEBUG_ENABLED
11913 }
11914 else
11915 {
11916 sinfo->txrate.mcs = maxMCSIdx;
Leo Chang6f8870f2013-03-26 18:11:36 -070011917#ifdef WLAN_FEATURE_11AC
11918 sinfo->txrate.nss = 1;
11919 if (rate_flags & eHAL_TX_RATE_VHT80)
11920 {
11921 sinfo->txrate.flags |= RATE_INFO_FLAGS_VHT_MCS;
Gopichand Nakkala4c705372013-04-24 13:20:33 +053011922 sinfo->txrate.flags |= RATE_INFO_FLAGS_80_MHZ_WIDTH;
Leo Chang6f8870f2013-03-26 18:11:36 -070011923 }
Gopichand Nakkala4c705372013-04-24 13:20:33 +053011924 else if (rate_flags & eHAL_TX_RATE_VHT40)
Leo Chang6f8870f2013-03-26 18:11:36 -070011925 {
Gopichand Nakkala4c705372013-04-24 13:20:33 +053011926 sinfo->txrate.flags |= RATE_INFO_FLAGS_VHT_MCS;
11927 sinfo->txrate.flags |= RATE_INFO_FLAGS_40_MHZ_WIDTH;
11928 }
11929 else if (rate_flags & eHAL_TX_RATE_VHT20)
11930 {
11931 sinfo->txrate.flags |= RATE_INFO_FLAGS_VHT_MCS;
11932 }
11933#endif /* WLAN_FEATURE_11AC */
11934 if (rate_flags & (eHAL_TX_RATE_HT20 | eHAL_TX_RATE_HT40))
11935 {
11936 sinfo->txrate.flags |= RATE_INFO_FLAGS_MCS;
11937 if (rate_flags & eHAL_TX_RATE_HT40)
11938 {
11939 sinfo->txrate.flags |= RATE_INFO_FLAGS_40_MHZ_WIDTH;
11940 }
Leo Chang6f8870f2013-03-26 18:11:36 -070011941 }
Jeff Johnson295189b2012-06-20 16:38:30 -070011942 if (rate_flags & eHAL_TX_RATE_SGI)
11943 {
11944 sinfo->txrate.flags |= RATE_INFO_FLAGS_SHORT_GI;
11945 }
Gopichand Nakkala4c705372013-04-24 13:20:33 +053011946
Jeff Johnson295189b2012-06-20 16:38:30 -070011947#ifdef LINKSPEED_DEBUG_ENABLED
11948 pr_info("Reporting MCS rate %d flags %x\n",
11949 sinfo->txrate.mcs,
11950 sinfo->txrate.flags );
11951#endif //LINKSPEED_DEBUG_ENABLED
11952 }
11953 }
11954 else
11955 {
11956 // report current rate instead of max rate
11957
11958 if (rate_flags & eHAL_TX_RATE_LEGACY)
11959 {
11960 //provide to the UI in units of 100kbps
11961 sinfo->txrate.legacy = myRate;
11962#ifdef LINKSPEED_DEBUG_ENABLED
11963 pr_info("Reporting actual legacy rate %d\n", sinfo->txrate.legacy);
11964#endif //LINKSPEED_DEBUG_ENABLED
11965 }
11966 else
11967 {
11968 //must be MCS
11969 sinfo->txrate.mcs = pAdapter->hdd_stats.ClassA_stat.mcs_index;
Leo Chang6f8870f2013-03-26 18:11:36 -070011970#ifdef WLAN_FEATURE_11AC
11971 sinfo->txrate.nss = 1;
11972 if (rate_flags & eHAL_TX_RATE_VHT80)
11973 {
11974 sinfo->txrate.flags |= RATE_INFO_FLAGS_VHT_MCS;
11975 }
11976 else
11977#endif /* WLAN_FEATURE_11AC */
11978 {
11979 sinfo->txrate.flags |= RATE_INFO_FLAGS_MCS;
11980 }
Jeff Johnson295189b2012-06-20 16:38:30 -070011981 if (rate_flags & eHAL_TX_RATE_SGI)
11982 {
11983 sinfo->txrate.flags |= RATE_INFO_FLAGS_SHORT_GI;
11984 }
11985 if (rate_flags & eHAL_TX_RATE_HT40)
11986 {
11987 sinfo->txrate.flags |= RATE_INFO_FLAGS_40_MHZ_WIDTH;
11988 }
Leo Chang6f8870f2013-03-26 18:11:36 -070011989#ifdef WLAN_FEATURE_11AC
11990 else if (rate_flags & eHAL_TX_RATE_VHT80)
11991 {
11992 sinfo->txrate.flags |= RATE_INFO_FLAGS_80_MHZ_WIDTH;
11993 }
11994#endif /* WLAN_FEATURE_11AC */
Jeff Johnson295189b2012-06-20 16:38:30 -070011995#ifdef LINKSPEED_DEBUG_ENABLED
11996 pr_info("Reporting actual MCS rate %d flags %x\n",
11997 sinfo->txrate.mcs,
11998 sinfo->txrate.flags );
11999#endif //LINKSPEED_DEBUG_ENABLED
12000 }
12001 }
12002 sinfo->filled |= STATION_INFO_TX_BITRATE;
12003
Madan Mohan Koyyalamudi4d4d2812012-09-24 14:08:29 -070012004 sinfo->tx_packets =
12005 pAdapter->hdd_stats.summary_stat.tx_frm_cnt[0] +
12006 pAdapter->hdd_stats.summary_stat.tx_frm_cnt[1] +
12007 pAdapter->hdd_stats.summary_stat.tx_frm_cnt[2] +
12008 pAdapter->hdd_stats.summary_stat.tx_frm_cnt[3];
12009
12010 sinfo->tx_retries =
12011 pAdapter->hdd_stats.summary_stat.retry_cnt[0] +
12012 pAdapter->hdd_stats.summary_stat.retry_cnt[1] +
12013 pAdapter->hdd_stats.summary_stat.retry_cnt[2] +
12014 pAdapter->hdd_stats.summary_stat.retry_cnt[3];
12015
12016 sinfo->tx_failed =
12017 pAdapter->hdd_stats.summary_stat.fail_cnt[0] +
12018 pAdapter->hdd_stats.summary_stat.fail_cnt[1] +
12019 pAdapter->hdd_stats.summary_stat.fail_cnt[2] +
12020 pAdapter->hdd_stats.summary_stat.fail_cnt[3];
12021
12022 sinfo->filled |=
12023 STATION_INFO_TX_PACKETS |
12024 STATION_INFO_TX_RETRIES |
12025 STATION_INFO_TX_FAILED;
12026
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053012027 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
12028 TRACE_CODE_HDD_CFG80211_GET_STA,
12029 pAdapter->sessionId, maxRate));
Madan Mohan Koyyalamudi4d4d2812012-09-24 14:08:29 -070012030 EXIT();
12031 return 0;
Jeff Johnson295189b2012-06-20 16:38:30 -070012032}
12033
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053012034static int wlan_hdd_cfg80211_get_station(struct wiphy *wiphy, struct net_device *dev,
12035 u8* mac, struct station_info *sinfo)
12036{
12037 int ret;
12038
12039 vos_ssr_protect(__func__);
12040 ret = __wlan_hdd_cfg80211_get_station(wiphy, dev, mac, sinfo);
12041 vos_ssr_unprotect(__func__);
12042
12043 return ret;
12044}
12045
12046static int __wlan_hdd_cfg80211_set_power_mgmt(struct wiphy *wiphy,
Sameer Thalappilc9f26e92013-06-07 10:11:06 -070012047 struct net_device *dev, bool mode, int timeout)
Jeff Johnson295189b2012-06-20 16:38:30 -070012048{
12049 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
Gopichand Nakkala20c4c042013-04-19 22:08:55 +053012050 hdd_context_t *pHddCtx;
Jeff Johnson295189b2012-06-20 16:38:30 -070012051 VOS_STATUS vos_status;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053012052 int status;
Jeff Johnson295189b2012-06-20 16:38:30 -070012053
Jeff Johnsone7245742012-09-05 17:12:55 -070012054 ENTER();
12055
Jeff Johnson295189b2012-06-20 16:38:30 -070012056 if (NULL == pAdapter)
12057 {
Arif Hussain6d2a3322013-11-17 19:50:10 -080012058 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Adapter is NULL", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -070012059 return -ENODEV;
12060 }
12061
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053012062 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
12063 TRACE_CODE_HDD_CFG80211_SET_POWER_MGMT,
12064 pAdapter->sessionId, timeout));
12065
Gopichand Nakkala20c4c042013-04-19 22:08:55 +053012066 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053012067 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkala20c4c042013-04-19 22:08:55 +053012068
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053012069 if (0 != status)
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012070 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053012071 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
12072 "%s: HDD context is not valid", __func__);
12073 return status;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012074 }
12075
Gopichand Nakkala20c4c042013-04-19 22:08:55 +053012076 if ((DRIVER_POWER_MODE_AUTO == !mode) &&
12077 (TRUE == pHddCtx->hdd_wlan_suspended) &&
12078 (pHddCtx->cfg_ini->fhostArpOffload) &&
12079 (eConnectionState_Associated ==
12080 (WLAN_HDD_GET_STATION_CTX_PTR(pAdapter))->conn_info.connState))
12081 {
Amar Singhald53568e2013-09-26 11:03:45 -070012082
12083 hddLog(VOS_TRACE_LEVEL_INFO,
12084 "offload: in cfg80211_set_power_mgmt, calling arp offload");
Gopichand Nakkalab03e8082013-05-30 18:09:25 +053012085 vos_status = hdd_conf_arp_offload(pAdapter, TRUE);
Gopichand Nakkala20c4c042013-04-19 22:08:55 +053012086 if (!VOS_IS_STATUS_SUCCESS(vos_status))
12087 {
12088 hddLog(VOS_TRACE_LEVEL_INFO,
Arif Hussain6d2a3322013-11-17 19:50:10 -080012089 "%s:Failed to enable ARPOFFLOAD Feature %d",
Gopichand Nakkala20c4c042013-04-19 22:08:55 +053012090 __func__, vos_status);
12091 }
12092 }
12093
Jeff Johnson295189b2012-06-20 16:38:30 -070012094 /**The get power cmd from the supplicant gets updated by the nl only
12095 *on successful execution of the function call
12096 *we are oppositely mapped w.r.t mode in the driver
12097 **/
12098 vos_status = wlan_hdd_enter_bmps(pAdapter, !mode);
12099
Jeff Johnsone7245742012-09-05 17:12:55 -070012100 EXIT();
Jeff Johnson295189b2012-06-20 16:38:30 -070012101 if (VOS_STATUS_E_FAILURE == vos_status)
12102 {
c_hpothu6ff1c3c2013-10-01 19:01:57 +053012103 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
12104 "%s: failed to enter bmps mode", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -070012105 return -EINVAL;
12106 }
12107 return 0;
12108}
12109
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053012110static int wlan_hdd_cfg80211_set_power_mgmt(struct wiphy *wiphy,
12111 struct net_device *dev, bool mode, int timeout)
12112{
12113 int ret;
Jeff Johnson295189b2012-06-20 16:38:30 -070012114
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053012115 vos_ssr_protect(__func__);
12116 ret = __wlan_hdd_cfg80211_set_power_mgmt(wiphy, dev, mode, timeout);
12117 vos_ssr_unprotect(__func__);
12118
12119 return ret;
12120}
Jeff Johnson295189b2012-06-20 16:38:30 -070012121#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
12122static int wlan_hdd_set_default_mgmt_key(struct wiphy *wiphy,
12123 struct net_device *netdev,
12124 u8 key_index)
12125{
Jeff Johnsone7245742012-09-05 17:12:55 -070012126 ENTER();
Jeff Johnson295189b2012-06-20 16:38:30 -070012127 return 0;
12128}
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012129#endif //LINUX_VERSION_CODE
Jeff Johnson295189b2012-06-20 16:38:30 -070012130
12131#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,4,0))
12132static int wlan_hdd_set_txq_params(struct wiphy *wiphy,
12133 struct net_device *dev,
12134 struct ieee80211_txq_params *params)
12135{
Jeff Johnsone7245742012-09-05 17:12:55 -070012136 ENTER();
Jeff Johnson295189b2012-06-20 16:38:30 -070012137 return 0;
12138}
12139#elif (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
12140static int wlan_hdd_set_txq_params(struct wiphy *wiphy,
12141 struct ieee80211_txq_params *params)
12142{
Jeff Johnsone7245742012-09-05 17:12:55 -070012143 ENTER();
Jeff Johnson295189b2012-06-20 16:38:30 -070012144 return 0;
12145}
12146#endif //LINUX_VERSION_CODE
12147
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053012148static int __wlan_hdd_cfg80211_del_station(struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -070012149 struct net_device *dev, u8 *mac)
12150{
12151 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053012152 hdd_context_t *pHddCtx;
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -080012153 VOS_STATUS vos_status;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053012154 int status;
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -080012155 v_U8_t staId;
Jeff Johnson295189b2012-06-20 16:38:30 -070012156
Jeff Johnsone7245742012-09-05 17:12:55 -070012157 ENTER();
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053012158
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053012159 if ( NULL == pAdapter )
Jeff Johnson295189b2012-06-20 16:38:30 -070012160 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053012161 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Invalid Adapter" ,__func__);
Jeff Johnson295189b2012-06-20 16:38:30 -070012162 return -EINVAL;
12163 }
12164
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053012165 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
12166 TRACE_CODE_HDD_CFG80211_DEL_STA,
12167 pAdapter->sessionId, pAdapter->device_mode));
12168
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053012169 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
12170 status = wlan_hdd_validate_context(pHddCtx);
Jeff Johnson295189b2012-06-20 16:38:30 -070012171
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053012172 if (0 != status)
Jeff Johnson04dd8a82012-06-29 20:41:40 -070012173 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053012174 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
12175 "%s: HDD context is not valid", __func__);
12176 return status;
Jeff Johnson04dd8a82012-06-29 20:41:40 -070012177 }
12178
Jeff Johnson295189b2012-06-20 16:38:30 -070012179 if ( (WLAN_HDD_SOFTAP == pAdapter->device_mode)
Jeff Johnson295189b2012-06-20 16:38:30 -070012180 || (WLAN_HDD_P2P_GO == pAdapter->device_mode)
Jeff Johnson295189b2012-06-20 16:38:30 -070012181 )
12182 {
12183 if( NULL == mac )
12184 {
12185 v_U16_t i;
12186 for(i = 0; i < WLAN_MAX_STA_COUNT; i++)
12187 {
Rajesh Chauhan18488fc2013-08-22 10:15:03 -070012188 if ((pAdapter->aStaInfo[i].isUsed) &&
12189 (!pAdapter->aStaInfo[i].isDeauthInProgress))
Jeff Johnson295189b2012-06-20 16:38:30 -070012190 {
12191 u8 *macAddr = pAdapter->aStaInfo[i].macAddrSTA.bytes;
12192 hddLog(VOS_TRACE_LEVEL_INFO,
Arif Hussain24bafea2013-11-15 15:10:03 -080012193 "%s: Delete STA with MAC::"
12194 MAC_ADDRESS_STR,
12195 __func__, MAC_ADDR_ARRAY(macAddr));
Rajesh Chauhan18488fc2013-08-22 10:15:03 -070012196 vos_status = hdd_softap_sta_deauth(pAdapter, macAddr);
12197 if (VOS_IS_STATUS_SUCCESS(vos_status))
12198 pAdapter->aStaInfo[i].isDeauthInProgress = TRUE;
Jeff Johnson295189b2012-06-20 16:38:30 -070012199 }
12200 }
12201 }
12202 else
12203 {
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -080012204
12205 vos_status = hdd_softap_GetStaId(pAdapter,(v_MACADDR_t *)mac, &staId);
12206 if (!VOS_IS_STATUS_SUCCESS(vos_status))
12207 {
12208 hddLog(VOS_TRACE_LEVEL_INFO,
Arif Hussain24bafea2013-11-15 15:10:03 -080012209 "%s: Skip this DEL STA as this is not used::"
12210 MAC_ADDRESS_STR,
12211 __func__, MAC_ADDR_ARRAY(mac));
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -080012212 return -ENOENT;
12213 }
12214
12215 if( pAdapter->aStaInfo[staId].isDeauthInProgress == TRUE)
12216 {
12217 hddLog(VOS_TRACE_LEVEL_INFO,
Arif Hussain24bafea2013-11-15 15:10:03 -080012218 "%s: Skip this DEL STA as deauth is in progress::"
12219 MAC_ADDRESS_STR,
12220 __func__, MAC_ADDR_ARRAY(mac));
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -080012221 return -ENOENT;
12222 }
12223
12224 pAdapter->aStaInfo[staId].isDeauthInProgress = TRUE;
12225
Jeff Johnson295189b2012-06-20 16:38:30 -070012226 hddLog(VOS_TRACE_LEVEL_INFO,
12227 "%s: Delete STA with MAC::"
Arif Hussain24bafea2013-11-15 15:10:03 -080012228 MAC_ADDRESS_STR,
Jeff Johnson295189b2012-06-20 16:38:30 -070012229 __func__,
Arif Hussain24bafea2013-11-15 15:10:03 -080012230 MAC_ADDR_ARRAY(mac));
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -080012231
12232 vos_status = hdd_softap_sta_deauth(pAdapter, mac);
12233 if (!VOS_IS_STATUS_SUCCESS(vos_status))
12234 {
12235 pAdapter->aStaInfo[staId].isDeauthInProgress = FALSE;
12236 hddLog(VOS_TRACE_LEVEL_INFO,
12237 "%s: STA removal failed for ::"
Arif Hussain24bafea2013-11-15 15:10:03 -080012238 MAC_ADDRESS_STR,
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -080012239 __func__,
Arif Hussain24bafea2013-11-15 15:10:03 -080012240 MAC_ADDR_ARRAY(mac));
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -080012241 return -ENOENT;
12242 }
12243
Jeff Johnson295189b2012-06-20 16:38:30 -070012244 }
12245 }
12246
12247 EXIT();
12248
12249 return 0;
12250}
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053012251static int wlan_hdd_cfg80211_del_station(struct wiphy *wiphy,
12252 struct net_device *dev, u8 *mac)
12253{
12254 int ret;
Jeff Johnson295189b2012-06-20 16:38:30 -070012255
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053012256 vos_ssr_protect(__func__);
12257 ret = __wlan_hdd_cfg80211_del_station(wiphy, dev, mac);
12258 vos_ssr_unprotect(__func__);
12259
12260 return ret;
12261}
12262
12263static int __wlan_hdd_cfg80211_add_station(struct wiphy *wiphy,
Hoonki Lee11f7dda2013-02-14 16:55:44 -080012264 struct net_device *dev, u8 *mac, struct station_parameters *params)
12265{
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053012266 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
Gopichand Nakkalab977a972013-02-18 19:15:09 -080012267 int status = -EPERM;
Hoonki Lee11f7dda2013-02-14 16:55:44 -080012268#ifdef FEATURE_WLAN_TDLS
12269 u32 mask, set;
Hoonki Lee11f7dda2013-02-14 16:55:44 -080012270 ENTER();
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053012271
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053012272 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
12273 TRACE_CODE_HDD_CFG80211_ADD_STA,
12274 pAdapter->sessionId, params->listen_interval));
Mohit Khanna698ba2a2012-12-04 15:08:18 -080012275 mask = params->sta_flags_mask;
12276
12277 set = params->sta_flags_set;
12278
Gopichand Nakkalac87400e2013-03-13 18:51:00 -070012279#ifdef WLAN_FEATURE_TDLS_DEBUG
12280 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
12281 "%s: mask 0x%x set 0x%x " MAC_ADDRESS_STR,
12282 __func__, mask, set, MAC_ADDR_ARRAY(mac));
12283#endif
Mohit Khanna698ba2a2012-12-04 15:08:18 -080012284
12285 if (mask & BIT(NL80211_STA_FLAG_TDLS_PEER)) {
12286 if (set & BIT(NL80211_STA_FLAG_TDLS_PEER)) {
Gopichand Nakkala681989c2013-03-06 22:27:48 -080012287 status = wlan_hdd_tdls_add_station(wiphy, dev, mac, 0, NULL);
Mohit Khanna698ba2a2012-12-04 15:08:18 -080012288 }
12289 }
12290#endif
Gopichand Nakkalab977a972013-02-18 19:15:09 -080012291 return status;
Jeff Johnson295189b2012-06-20 16:38:30 -070012292}
12293
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053012294static int wlan_hdd_cfg80211_add_station(struct wiphy *wiphy,
12295 struct net_device *dev, u8 *mac, struct station_parameters *params)
12296{
12297 int ret;
Jeff Johnson04dd8a82012-06-29 20:41:40 -070012298
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053012299 vos_ssr_protect(__func__);
12300 ret = __wlan_hdd_cfg80211_add_station(wiphy, dev, mac, params);
12301 vos_ssr_unprotect(__func__);
12302
12303 return ret;
12304}
Jeff Johnson04dd8a82012-06-29 20:41:40 -070012305#ifdef FEATURE_WLAN_LFR
Wilson Yang6507c4e2013-10-01 20:11:19 -070012306
Mahesh A Saptasagarf7418d72014-06-02 14:48:54 +053012307static int __wlan_hdd_cfg80211_set_pmksa(struct wiphy *wiphy, struct net_device *dev,
Jeff Johnsond13512a2012-07-17 11:42:19 -070012308 struct cfg80211_pmksa *pmksa)
Jeff Johnson04dd8a82012-06-29 20:41:40 -070012309{
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012310 tANI_U32 j=0;
Jeff Johnson04dd8a82012-06-29 20:41:40 -070012311 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
Agarwal Ashish3da95242014-05-21 14:57:17 +053012312 hdd_station_ctx_t *pHddStaCtx;
Jeff Johnson04dd8a82012-06-29 20:41:40 -070012313 tHalHandle halHandle;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012314 eHalStatus result;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053012315 int status;
Jeff Johnson04dd8a82012-06-29 20:41:40 -070012316 tANI_U8 BSSIDMatched = 0;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053012317 hdd_context_t *pHddCtx;
Jeff Johnson0299d0a2013-10-30 12:37:43 -070012318 hddLog(VOS_TRACE_LEVEL_DEBUG, "%s: set PMKSA for " MAC_ADDRESS_STR,
12319 __func__, MAC_ADDR_ARRAY(pmksa->bssid));
Jeff Johnsone7245742012-09-05 17:12:55 -070012320
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012321 // Validate pAdapter
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053012322 if ( NULL == pAdapter )
Jeff Johnson04dd8a82012-06-29 20:41:40 -070012323 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053012324 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Invalid Adapter" ,__func__);
Jeff Johnson04dd8a82012-06-29 20:41:40 -070012325 return -EINVAL;
12326 }
12327
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053012328 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
12329 status = wlan_hdd_validate_context(pHddCtx);
Jeff Johnson04dd8a82012-06-29 20:41:40 -070012330
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053012331 if (0 != status)
Jeff Johnson04dd8a82012-06-29 20:41:40 -070012332 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053012333 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
12334 "%s: HDD context is not valid", __func__);
12335 return status;
Jeff Johnson04dd8a82012-06-29 20:41:40 -070012336 }
12337
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012338 // Retrieve halHandle
Jeff Johnson04dd8a82012-06-29 20:41:40 -070012339 halHandle = WLAN_HDD_GET_HAL_CTX(pAdapter);
Agarwal Ashish3da95242014-05-21 14:57:17 +053012340 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
Jeff Johnson04dd8a82012-06-29 20:41:40 -070012341
Agarwal Ashish3da95242014-05-21 14:57:17 +053012342 for (j = 0; j < pHddStaCtx->PMKIDCacheIndex; j++)
Jeff Johnson04dd8a82012-06-29 20:41:40 -070012343 {
Agarwal Ashish3da95242014-05-21 14:57:17 +053012344 if (vos_mem_compare(pHddStaCtx->PMKIDCache[j].BSSID,
Jeff Johnson04dd8a82012-06-29 20:41:40 -070012345 pmksa->bssid, WNI_CFG_BSSID_LEN))
12346 {
12347 /* BSSID matched previous entry. Overwrite it. */
12348 BSSIDMatched = 1;
Agarwal Ashish3da95242014-05-21 14:57:17 +053012349 vos_mem_copy(pHddStaCtx->PMKIDCache[j].BSSID,
Jeff Johnson04dd8a82012-06-29 20:41:40 -070012350 pmksa->bssid, WNI_CFG_BSSID_LEN);
Agarwal Ashish3da95242014-05-21 14:57:17 +053012351 vos_mem_copy(pHddStaCtx->PMKIDCache[j].PMKID,
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012352 pmksa->pmkid,
Jeff Johnson04dd8a82012-06-29 20:41:40 -070012353 CSR_RSN_PMKID_SIZE);
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012354 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: Reusing cache entry %d.",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -070012355 __func__, j );
Jeff Johnson04dd8a82012-06-29 20:41:40 -070012356 dump_bssid(pmksa->bssid);
12357 dump_pmkid(halHandle, pmksa->pmkid);
12358 break;
12359 }
12360 }
12361
Madan Mohan Koyyalamudic4b317d2012-10-18 19:43:08 -070012362 /* Check we compared all entries,if then take the first slot now */
Agarwal Ashish3da95242014-05-21 14:57:17 +053012363 if (j == MAX_PMKSAIDS_IN_CACHE) pHddStaCtx->PMKIDCacheIndex=0;
Madan Mohan Koyyalamudic4b317d2012-10-18 19:43:08 -070012364
Jeff Johnson04dd8a82012-06-29 20:41:40 -070012365 if (!BSSIDMatched)
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012366 {
12367 // Now, we DON'T have a BSSID match, so take a new entry in the cache.
Agarwal Ashish3da95242014-05-21 14:57:17 +053012368 vos_mem_copy(pHddStaCtx->PMKIDCache[pHddStaCtx->PMKIDCacheIndex].BSSID,
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012369 pmksa->bssid, ETHER_ADDR_LEN);
Agarwal Ashish3da95242014-05-21 14:57:17 +053012370 vos_mem_copy(pHddStaCtx->PMKIDCache[pHddStaCtx->PMKIDCacheIndex].PMKID,
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012371 pmksa->pmkid,
Jeff Johnson04dd8a82012-06-29 20:41:40 -070012372 CSR_RSN_PMKID_SIZE);
Agarwal Ashish3da95242014-05-21 14:57:17 +053012373 hddLog(VOS_TRACE_LEVEL_DEBUG, "%s: Adding a new cache entry %d.",
12374 __func__, pHddStaCtx->PMKIDCacheIndex );
Jeff Johnson04dd8a82012-06-29 20:41:40 -070012375 dump_bssid(pmksa->bssid);
12376 dump_pmkid(halHandle, pmksa->pmkid);
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012377 // Increment the HDD Local Cache index
Jeff Johnson04dd8a82012-06-29 20:41:40 -070012378 // The "i=0" doesn't work for the call to sme_RoamSetPMKIDCache() - LFR FIXME
Agarwal Ashish3da95242014-05-21 14:57:17 +053012379 if (pHddStaCtx->PMKIDCacheIndex <= (MAX_PMKSAIDS_IN_CACHE-1))
12380 pHddStaCtx->PMKIDCacheIndex++;
12381 else
12382 pHddStaCtx->PMKIDCacheIndex = 0;
Jeff Johnson04dd8a82012-06-29 20:41:40 -070012383 }
12384
12385
12386 // Calling csrRoamSetPMKIDCache to configure the PMKIDs into the cache
Agarwal Ashish3da95242014-05-21 14:57:17 +053012387 hddLog(VOS_TRACE_LEVEL_DEBUG, "%s: Calling csrRoamSetPMKIDCache with %d cache entries.",
12388 __func__, pHddStaCtx->PMKIDCacheIndex );
12389
Jeff Johnson04dd8a82012-06-29 20:41:40 -070012390 // Finally set the PMKSA ID Cache in CSR
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012391 result = sme_RoamSetPMKIDCache(halHandle,pAdapter->sessionId,
Agarwal Ashish3da95242014-05-21 14:57:17 +053012392 pHddStaCtx->PMKIDCache,
12393 pHddStaCtx->PMKIDCacheIndex);
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053012394 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
12395 TRACE_CODE_HDD_CFG80211_SET_PMKSA,
12396 pAdapter->sessionId, result));
Jeff Johnson04dd8a82012-06-29 20:41:40 -070012397 return 0;
12398}
12399
Mahesh A Saptasagarf7418d72014-06-02 14:48:54 +053012400static int wlan_hdd_cfg80211_set_pmksa(struct wiphy *wiphy, struct net_device *dev,
12401 struct cfg80211_pmksa *pmksa)
12402{
12403 int ret;
12404
12405 vos_ssr_protect(__func__);
12406 ret = __wlan_hdd_cfg80211_set_pmksa(wiphy, dev, pmksa);
12407 vos_ssr_unprotect(__func__);
12408
12409 return ret;
12410}
Jeff Johnson04dd8a82012-06-29 20:41:40 -070012411
Wilson Yang6507c4e2013-10-01 20:11:19 -070012412
Mahesh A Saptasagarf7418d72014-06-02 14:48:54 +053012413static int __wlan_hdd_cfg80211_del_pmksa(struct wiphy *wiphy, struct net_device *dev,
Wilson Yang6507c4e2013-10-01 20:11:19 -070012414 struct cfg80211_pmksa *pmksa)
Jeff Johnson04dd8a82012-06-29 20:41:40 -070012415{
Wilson Yang6507c4e2013-10-01 20:11:19 -070012416 tANI_U32 j=0;
12417 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
Agarwal Ashish3da95242014-05-21 14:57:17 +053012418 hdd_station_ctx_t *pHddStaCtx;
Wilson Yang6507c4e2013-10-01 20:11:19 -070012419 tHalHandle halHandle;
Wilson Yang6507c4e2013-10-01 20:11:19 -070012420 tANI_U8 BSSIDMatched = 0;
Wilson Yang6507c4e2013-10-01 20:11:19 -070012421 hdd_context_t *pHddCtx;
Wilson Yangef657d32014-01-15 19:19:23 -080012422 int status = 0;
Wilson Yang6507c4e2013-10-01 20:11:19 -070012423
Jeff Johnson0299d0a2013-10-30 12:37:43 -070012424 hddLog(VOS_TRACE_LEVEL_DEBUG, "%s: deleting PMKSA for " MAC_ADDRESS_STR,
12425 __func__, MAC_ADDR_ARRAY(pmksa->bssid));
Wilson Yang6507c4e2013-10-01 20:11:19 -070012426
12427 /* Validate pAdapter */
12428 if (NULL == pAdapter)
12429 {
12430 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Invalid Adapter" ,__func__);
12431 return -EINVAL;
12432 }
12433
12434 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
12435 status = wlan_hdd_validate_context(pHddCtx);
12436
12437 if (0 != status)
12438 {
12439 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
12440 "%s: HDD context is not valid", __func__);
12441 return status;
12442 }
12443
12444 /*Retrieve halHandle*/
12445 halHandle = WLAN_HDD_GET_HAL_CTX(pAdapter);
Agarwal Ashish3da95242014-05-21 14:57:17 +053012446 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
Wilson Yang6507c4e2013-10-01 20:11:19 -070012447
12448 /*in case index is 0,no entry to delete*/
Agarwal Ashish3da95242014-05-21 14:57:17 +053012449 if (0 == pHddStaCtx->PMKIDCacheIndex)
Wilson Yang6507c4e2013-10-01 20:11:19 -070012450 {
Agarwal Ashish3da95242014-05-21 14:57:17 +053012451 hddLog(VOS_TRACE_LEVEL_INFO, FL("No entries to flush"));
12452 return 0;
Wilson Yang6507c4e2013-10-01 20:11:19 -070012453 }
12454
12455 /*find the matching PMKSA entry from j=0 to (index-1),
12456 * and delete the matched one
12457 */
Agarwal Ashish3da95242014-05-21 14:57:17 +053012458 for (j = 0; j < pHddStaCtx->PMKIDCacheIndex; j++)
Wilson Yang6507c4e2013-10-01 20:11:19 -070012459 {
Agarwal Ashish3da95242014-05-21 14:57:17 +053012460 if (vos_mem_compare(pHddStaCtx->PMKIDCache[j].BSSID,
Wilson Yang6507c4e2013-10-01 20:11:19 -070012461 pmksa->bssid,
12462 WNI_CFG_BSSID_LEN))
12463 {
12464 /* BSSID matched entry */
12465 BSSIDMatched = 1;
Agarwal Ashish3da95242014-05-21 14:57:17 +053012466 if (j < pHddStaCtx->PMKIDCacheIndex-1)
Wilson Yang6507c4e2013-10-01 20:11:19 -070012467 {
12468 /*replace the matching entry with the last entry in HDD local cache*/
Agarwal Ashish3da95242014-05-21 14:57:17 +053012469 vos_mem_copy(pHddStaCtx->PMKIDCache[j].BSSID,
12470 pHddStaCtx->PMKIDCache[pHddStaCtx->PMKIDCacheIndex-1].BSSID,
12471 VOS_MAC_ADDR_SIZE);
12472 vos_mem_copy(pHddStaCtx->PMKIDCache[j].PMKID,
12473 pHddStaCtx->PMKIDCache[pHddStaCtx->PMKIDCacheIndex-1].PMKID,
12474 CSR_RSN_PMKID_SIZE);
12475 }
Wilson Yang6507c4e2013-10-01 20:11:19 -070012476
12477 /*clear the last entry in HDD cache ---[index-1]*/
Agarwal Ashish3da95242014-05-21 14:57:17 +053012478 vos_mem_zero(pHddStaCtx->PMKIDCache[pHddStaCtx->PMKIDCacheIndex-1].BSSID,
12479 VOS_MAC_ADDR_SIZE);
12480 vos_mem_zero(pHddStaCtx->PMKIDCache[pHddStaCtx->PMKIDCacheIndex-1].PMKID,
12481 CSR_RSN_PMKID_SIZE);
Wilson Yang6507c4e2013-10-01 20:11:19 -070012482 /*reduce the PMKID array index*/
Agarwal Ashish3da95242014-05-21 14:57:17 +053012483 pHddStaCtx->PMKIDCacheIndex--;
Wilson Yang6507c4e2013-10-01 20:11:19 -070012484 /*delete the last PMKID cache in CSR*/
Wilson Yangef657d32014-01-15 19:19:23 -080012485 if (eHAL_STATUS_SUCCESS !=
12486 sme_RoamDelPMKIDfromCache(halHandle, pAdapter->sessionId, pmksa->bssid))
Wilson Yang6507c4e2013-10-01 20:11:19 -070012487 {
12488 hddLog(VOS_TRACE_LEVEL_ERROR,"%s: cannot delete PMKSA %d CONTENT.",
Agarwal Ashish3da95242014-05-21 14:57:17 +053012489 __func__, pHddStaCtx->PMKIDCacheIndex);
Wilson Yangef657d32014-01-15 19:19:23 -080012490 status = -EINVAL;
Wilson Yang6507c4e2013-10-01 20:11:19 -070012491 }
12492
12493 dump_bssid(pmksa->bssid);
12494 dump_pmkid(halHandle,pmksa->pmkid);
12495
12496 break;
12497 }
12498 }
12499
12500 /* we compare all entries,but cannot find matching entry */
12501 if (j == MAX_PMKSAIDS_IN_CACHE && !BSSIDMatched)
12502 {
Jeff Johnson0299d0a2013-10-30 12:37:43 -070012503 hddLog(VOS_TRACE_LEVEL_FATAL,
12504 "%s: No such PMKSA entry existed " MAC_ADDRESS_STR,
12505 __func__, MAC_ADDR_ARRAY(pmksa->bssid));
Wilson Yang6507c4e2013-10-01 20:11:19 -070012506 dump_bssid(pmksa->bssid);
12507 dump_pmkid(halHandle, pmksa->pmkid);
12508 return -EINVAL;
12509 }
Wilson Yangef657d32014-01-15 19:19:23 -080012510 return status;
Jeff Johnson04dd8a82012-06-29 20:41:40 -070012511}
12512
Wilson Yang6507c4e2013-10-01 20:11:19 -070012513
Mahesh A Saptasagarf7418d72014-06-02 14:48:54 +053012514static int wlan_hdd_cfg80211_del_pmksa(struct wiphy *wiphy, struct net_device *dev,
12515 struct cfg80211_pmksa *pmksa)
12516{
12517 int ret;
Wilson Yang6507c4e2013-10-01 20:11:19 -070012518
Mahesh A Saptasagarf7418d72014-06-02 14:48:54 +053012519 vos_ssr_protect(__func__);
12520 ret = __wlan_hdd_cfg80211_del_pmksa(wiphy, dev, pmksa);
12521 vos_ssr_unprotect(__func__);
12522
12523 return ret;
12524
12525}
12526
12527static int __wlan_hdd_cfg80211_flush_pmksa(struct wiphy *wiphy, struct net_device *dev)
Jeff Johnson04dd8a82012-06-29 20:41:40 -070012528{
Wilson Yang6507c4e2013-10-01 20:11:19 -070012529 tANI_U32 j=0;
12530 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
Agarwal Ashish3da95242014-05-21 14:57:17 +053012531 hdd_station_ctx_t *pHddStaCtx;
Wilson Yang6507c4e2013-10-01 20:11:19 -070012532 tHalHandle halHandle;
12533 hdd_context_t *pHddCtx;
12534 tANI_U8 *pBSSId;
Wilson Yangef657d32014-01-15 19:19:23 -080012535 int status = 0;
Wilson Yang6507c4e2013-10-01 20:11:19 -070012536
12537 hddLog(VOS_TRACE_LEVEL_DEBUG, "%s: flushing PMKSA ",__func__);
12538
12539 /* Validate pAdapter */
12540 if (NULL == pAdapter)
12541 {
12542 hddLog(VOS_TRACE_LEVEL_ERROR,
12543 "%s: Invalid Adapter" ,__func__);
12544 return -EINVAL;
12545 }
12546
12547 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
12548 status = wlan_hdd_validate_context(pHddCtx);
12549
12550 if (0 != status)
12551 {
12552 hddLog(VOS_TRACE_LEVEL_ERROR,
12553 "%s: HDD context is not valid", __func__);
12554 return status;
12555 }
12556
12557 /*Retrieve halHandle*/
12558 halHandle = WLAN_HDD_GET_HAL_CTX(pAdapter);
Agarwal Ashish3da95242014-05-21 14:57:17 +053012559 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
Wilson Yang6507c4e2013-10-01 20:11:19 -070012560
12561 /*in case index is 0,no entry to delete*/
Agarwal Ashish3da95242014-05-21 14:57:17 +053012562 if (0 == pHddStaCtx->PMKIDCacheIndex)
Wilson Yang6507c4e2013-10-01 20:11:19 -070012563 {
Vinay Krishna Erannacbf75f42014-02-26 17:35:20 +053012564 hddLog(VOS_TRACE_LEVEL_ERROR, FL("No entries to flush"));
Agarwal Ashish3da95242014-05-21 14:57:17 +053012565 return 0;
Wilson Yang6507c4e2013-10-01 20:11:19 -070012566 }
12567
12568 /*delete all the PMKSA one by one */
Agarwal Ashish3da95242014-05-21 14:57:17 +053012569 for (j = 0; j < pHddStaCtx->PMKIDCacheIndex; j++)
Wilson Yang6507c4e2013-10-01 20:11:19 -070012570 {
Agarwal Ashish3da95242014-05-21 14:57:17 +053012571 pBSSId =(tANI_U8 *)(pHddStaCtx->PMKIDCache[j].BSSID);
Wilson Yang6507c4e2013-10-01 20:11:19 -070012572 /*delete the PMKID in CSR*/
Wilson Yangef657d32014-01-15 19:19:23 -080012573 if (eHAL_STATUS_SUCCESS !=
12574 sme_RoamDelPMKIDfromCache(halHandle, pAdapter->sessionId, pBSSId))
Wilson Yang6507c4e2013-10-01 20:11:19 -070012575 {
12576 hddLog(VOS_TRACE_LEVEL_ERROR ,"%s cannot flush PMKIDCache %d.",
12577 __func__,j);
Wilson Yangef657d32014-01-15 19:19:23 -080012578 status = -EINVAL;
Wilson Yang6507c4e2013-10-01 20:11:19 -070012579 }
Kiet Lam8d21d5b2013-10-31 17:18:29 +053012580 /*clear the entry in HDD cache 0--index-1 */
Agarwal Ashish3da95242014-05-21 14:57:17 +053012581 vos_mem_zero(pHddStaCtx->PMKIDCache[j].BSSID, VOS_MAC_ADDR_SIZE);
12582 vos_mem_zero(pHddStaCtx->PMKIDCache[j].PMKID, CSR_RSN_PMKID_SIZE);
12583 }
Wilson Yang6507c4e2013-10-01 20:11:19 -070012584
Agarwal Ashish3da95242014-05-21 14:57:17 +053012585 pHddStaCtx->PMKIDCacheIndex = 0;
Wilson Yangef657d32014-01-15 19:19:23 -080012586 return status;
Jeff Johnson04dd8a82012-06-29 20:41:40 -070012587}
Mahesh A Saptasagarf7418d72014-06-02 14:48:54 +053012588
12589static int wlan_hdd_cfg80211_flush_pmksa(struct wiphy *wiphy, struct net_device *dev)
12590{
12591 int ret;
12592
12593 vos_ssr_protect(__func__);
12594 ret = __wlan_hdd_cfg80211_flush_pmksa(wiphy, dev);
12595 vos_ssr_unprotect(__func__);
12596
12597 return ret;
12598}
Jeff Johnson04dd8a82012-06-29 20:41:40 -070012599#endif
12600
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070012601#if defined(WLAN_FEATURE_VOWIFI_11R) && defined(KERNEL_SUPPORT_11R_CFG80211)
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053012602static int __wlan_hdd_cfg80211_update_ft_ies(struct wiphy *wiphy,
12603 struct net_device *dev,
12604 struct cfg80211_update_ft_ies_params *ftie)
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070012605{
12606 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
12607 hdd_station_ctx_t *pHddStaCtx;
12608
12609 if (NULL == pAdapter)
12610 {
Arif Hussain6d2a3322013-11-17 19:50:10 -080012611 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Adapter is NULL", __func__);
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070012612 return -ENODEV;
12613 }
12614
12615 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
12616
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053012617 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
12618 TRACE_CODE_HDD_CFG80211_UPDATE_FT_IES,
12619 pAdapter->sessionId, pHddStaCtx->conn_info.connState));
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070012620 // Added for debug on reception of Re-assoc Req.
12621 if (eConnectionState_Associated != pHddStaCtx->conn_info.connState)
12622 {
Arif Hussain6d2a3322013-11-17 19:50:10 -080012623 hddLog(LOGE, FL("Called with Ie of length = %zu when not associated"),
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070012624 ftie->ie_len);
Arif Hussain6d2a3322013-11-17 19:50:10 -080012625 hddLog(LOGE, FL("Should be Re-assoc Req IEs"));
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070012626 }
12627
12628#ifdef WLAN_FEATURE_VOWIFI_11R_DEBUG
Arif Hussain6d2a3322013-11-17 19:50:10 -080012629 hddLog(LOGE, FL("%s called with Ie of length = %zu"), __func__,
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070012630 ftie->ie_len);
12631#endif
12632
12633 // Pass the received FT IEs to SME
Gopichand Nakkala356fb102013-03-06 12:34:04 +053012634 sme_SetFTIEs( WLAN_HDD_GET_HAL_CTX(pAdapter), pAdapter->sessionId,
12635 (const u8 *)ftie->ie,
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070012636 ftie->ie_len);
12637 return 0;
12638}
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053012639
12640static int wlan_hdd_cfg80211_update_ft_ies(struct wiphy *wiphy,
12641 struct net_device *dev,
12642 struct cfg80211_update_ft_ies_params *ftie)
12643{
12644 int ret;
12645
12646 vos_ssr_protect(__func__);
12647 ret = __wlan_hdd_cfg80211_update_ft_ies(wiphy, dev, ftie);
12648 vos_ssr_unprotect(__func__);
12649
12650 return ret;
12651}
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070012652#endif
Jeff Johnson04dd8a82012-06-29 20:41:40 -070012653
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053012654#ifdef FEATURE_WLAN_SCAN_PNO
12655
12656void hdd_cfg80211_sched_scan_done_callback(void *callbackContext,
12657 tSirPrefNetworkFoundInd *pPrefNetworkFoundInd)
12658{
12659 int ret;
12660 hdd_adapter_t* pAdapter = (hdd_adapter_t*)callbackContext;
12661 hdd_context_t *pHddCtx;
12662
Nirav Shah80830bf2013-12-31 16:35:12 +053012663 ENTER();
12664
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053012665 if (NULL == pAdapter)
12666 {
Agarwal Ashish971c2882013-10-30 20:11:12 +053012667 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053012668 "%s: HDD adapter is Null", __func__);
12669 return ;
12670 }
12671
12672 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
12673 if (NULL == pHddCtx)
12674 {
12675 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
12676 "%s: HDD context is Null!!!", __func__);
12677 return ;
12678 }
12679
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053012680 spin_lock(&pHddCtx->schedScan_lock);
12681 if (TRUE == pHddCtx->isWiphySuspended)
12682 {
12683 pHddCtx->isSchedScanUpdatePending = TRUE;
12684 spin_unlock(&pHddCtx->schedScan_lock);
12685 hddLog(VOS_TRACE_LEVEL_INFO,
12686 "%s: Update cfg80211 scan database after it resume", __func__);
12687 return ;
12688 }
12689 spin_unlock(&pHddCtx->schedScan_lock);
12690
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053012691 ret = wlan_hdd_cfg80211_update_bss(pHddCtx->wiphy, pAdapter);
12692
12693 if (0 > ret)
12694 hddLog(VOS_TRACE_LEVEL_INFO, "%s: NO SCAN result", __func__);
12695
12696 cfg80211_sched_scan_results(pHddCtx->wiphy);
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053012697 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
12698 "%s: cfg80211 scan result database updated", __func__);
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053012699}
12700
12701/*
Mahesh A Saptasagar0f7b0372013-11-28 23:23:07 +053012702 * FUNCTION: wlan_hdd_is_pno_allowed
Vinay Krishna Erannacbf75f42014-02-26 17:35:20 +053012703 * Disallow pno if any session is active
Mahesh A Saptasagar0f7b0372013-11-28 23:23:07 +053012704 */
12705static eHalStatus wlan_hdd_is_pno_allowed(hdd_adapter_t *pAdapter)
12706{
12707 hdd_adapter_list_node_t *pAdapterNode = NULL, *pNext = NULL;
12708 hdd_adapter_t *pTempAdapter = NULL;
Vinay Krishna Eranna23ffd182013-12-26 19:16:55 +053012709 hdd_station_ctx_t *pStaCtx;
Mahesh A Saptasagar0f7b0372013-11-28 23:23:07 +053012710 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
12711 int status = 0;
12712 status = hdd_get_front_adapter(pHddCtx, &pAdapterNode);
12713
Vinay Krishna Erannacbf75f42014-02-26 17:35:20 +053012714 /* The current firmware design does not allow PNO during any
12715 * active sessions. Hence, determine the active sessions
12716 * and return a failure.
12717 */
Mahesh A Saptasagar0f7b0372013-11-28 23:23:07 +053012718 while ((NULL != pAdapterNode) && (VOS_STATUS_SUCCESS == status))
12719 {
12720 pTempAdapter = pAdapterNode->pAdapter;
Vinay Krishna Eranna23ffd182013-12-26 19:16:55 +053012721 pStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pTempAdapter);
Mahesh A Saptasagar0f7b0372013-11-28 23:23:07 +053012722
Vinay Krishna Eranna23ffd182013-12-26 19:16:55 +053012723 if (((WLAN_HDD_INFRA_STATION == pTempAdapter->device_mode)
12724 && (eConnectionState_NotConnected != pStaCtx->conn_info.connState))
12725 || (WLAN_HDD_P2P_CLIENT == pTempAdapter->device_mode)
12726 || (WLAN_HDD_P2P_GO == pTempAdapter->device_mode)
12727 || (WLAN_HDD_SOFTAP == pTempAdapter->device_mode)
12728 )
Mahesh A Saptasagar0f7b0372013-11-28 23:23:07 +053012729 {
Vinay Krishna Eranna23ffd182013-12-26 19:16:55 +053012730 return eHAL_STATUS_FAILURE;
Mahesh A Saptasagar0f7b0372013-11-28 23:23:07 +053012731 }
12732 status = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
12733 pAdapterNode = pNext;
12734 }
Vinay Krishna Eranna23ffd182013-12-26 19:16:55 +053012735 return eHAL_STATUS_SUCCESS;
Mahesh A Saptasagar0f7b0372013-11-28 23:23:07 +053012736}
12737
Vinay Krishna Erannaf0e523b2014-03-01 21:00:16 +053012738void hdd_cfg80211_sched_scan_start_status_cb(void *callbackContext, VOS_STATUS status)
12739{
12740 hdd_adapter_t *pAdapter = callbackContext;
12741 hdd_context_t *pHddCtx;
12742
12743 if ((NULL == pAdapter) || (WLAN_HDD_ADAPTER_MAGIC != pAdapter->magic))
12744 {
12745 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
12746 FL("Invalid adapter or adapter has invalid magic"));
12747 return;
12748 }
12749
12750 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
12751 if (0 != wlan_hdd_validate_context(pHddCtx))
12752 {
12753 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
12754 FL("HDD context is not valid"));
12755 return;
12756 }
12757
c_hpothub53c45d2014-08-18 16:53:14 +053012758 if (VOS_STATUS_SUCCESS != status)
12759 {
12760 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Vinay Krishna Erannaf0e523b2014-03-01 21:00:16 +053012761 FL("PNO enable response status = %d"), status);
c_hpothub53c45d2014-08-18 16:53:14 +053012762 pHddCtx->isPnoEnable = FALSE;
12763 }
Vinay Krishna Erannaf0e523b2014-03-01 21:00:16 +053012764
12765 pAdapter->pno_req_status = (status == VOS_STATUS_SUCCESS) ? 0 : -EBUSY;
12766 complete(&pAdapter->pno_comp_var);
12767}
12768
Mahesh A Saptasagar0f7b0372013-11-28 23:23:07 +053012769/*
Mahesh A Saptasagar6cc38562014-05-23 21:22:17 +053012770 * FUNCTION: __wlan_hdd_cfg80211_sched_scan_start
12771 * Function to enable PNO
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053012772 */
Mahesh A Saptasagar6cc38562014-05-23 21:22:17 +053012773static int __wlan_hdd_cfg80211_sched_scan_start(struct wiphy *wiphy,
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053012774 struct net_device *dev, struct cfg80211_sched_scan_request *request)
12775{
12776 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
12777 tpSirPNOScanReq pPnoRequest = NULL;
12778 hdd_context_t *pHddCtx;
12779 tHalHandle hHal;
Mahesh A Saptasagar7bd6ad42014-07-21 18:56:33 +053012780 v_U32_t i, indx, num_ch, tempInterval, j;
Sushant Kaushikd62d9782014-02-19 15:39:40 +053012781 u8 valid_ch[WNI_CFG_VALID_CHANNEL_LIST_LEN] = {0};
12782 u8 channels_allowed[WNI_CFG_VALID_CHANNEL_LIST_LEN] = {0};
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053012783 v_U32_t num_channels_allowed = WNI_CFG_VALID_CHANNEL_LIST_LEN;
12784 eHalStatus status = eHAL_STATUS_FAILURE;
Kamath Vinayakba5313f2013-08-22 15:52:39 +053012785 int ret = 0;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053012786
12787 if (NULL == pAdapter)
12788 {
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053012789 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053012790 "%s: HDD adapter is Null", __func__);
12791 return -ENODEV;
12792 }
12793
12794 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053012795 ret = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053012796
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053012797 if (0 != ret)
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053012798 {
Gopichand Nakkalac005b7c2013-05-14 16:04:14 +053012799 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
12800 "%s: HDD context is not valid", __func__);
Kamath Vinayakba5313f2013-08-22 15:52:39 +053012801 return -EINVAL;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053012802 }
12803
12804 hHal = WLAN_HDD_GET_HAL_CTX(pAdapter);
12805 if (NULL == hHal)
12806 {
12807 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
12808 "%s: HAL context is Null!!!", __func__);
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053012809 return -EINVAL;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053012810 }
Sushant Kaushik2fe89932014-09-03 10:58:09 +053012811 sme_ScanFlushResult(hHal, pAdapter->sessionId);
Mahesh A Saptasagar2395ee62014-05-21 19:12:21 +053012812 ret = wlan_hdd_scan_abort(pAdapter);
Girish Gowli4bf7a632014-06-12 13:42:11 +053012813 if (ret < 0)
Mahesh A Saptasagar2395ee62014-05-21 19:12:21 +053012814 {
12815 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
12816 "%s: aborting the existing scan is unsuccessfull", __func__);
12817 return -EBUSY;
12818 }
12819
Vinay Krishna Eranna23ffd182013-12-26 19:16:55 +053012820 if (eHAL_STATUS_SUCCESS != wlan_hdd_is_pno_allowed(pAdapter))
Mahesh A Saptasagar0f7b0372013-11-28 23:23:07 +053012821 {
Vinay Krishna Erannacbf75f42014-02-26 17:35:20 +053012822 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_WARN,
Vinay Krishna Eranna23ffd182013-12-26 19:16:55 +053012823 FL("Cannot handle sched_scan"));
Mahesh A Saptasagar0f7b0372013-11-28 23:23:07 +053012824 return -EBUSY;
12825 }
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053012826
c_hpothu37f21312014-04-09 21:49:54 +053012827 if (TRUE == pHddCtx->isPnoEnable)
12828 {
12829 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_WARN,
12830 FL("already PNO is enabled"));
12831 return -EBUSY;
12832 }
12833 pHddCtx->isPnoEnable = TRUE;
12834
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053012835 pPnoRequest = (tpSirPNOScanReq) vos_mem_malloc(sizeof (tSirPNOScanReq));
12836 if (NULL == pPnoRequest)
12837 {
12838 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
12839 "%s: vos_mem_malloc failed", __func__);
c_hpothu37f21312014-04-09 21:49:54 +053012840 pHddCtx->isPnoEnable = FALSE;
Kamath Vinayakba5313f2013-08-22 15:52:39 +053012841 return -ENOMEM;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053012842 }
12843
Madan Mohan Koyyalamudic3f04352013-09-26 19:21:48 +053012844 memset(pPnoRequest, 0, sizeof (tSirPNOScanReq));
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053012845 pPnoRequest->enable = 1; /*Enable PNO */
12846 pPnoRequest->ucNetworksCount = request->n_match_sets;
12847
12848 if (( !pPnoRequest->ucNetworksCount ) ||
12849 ( pPnoRequest->ucNetworksCount > SIR_PNO_MAX_SUPP_NETWORKS ))
12850 {
12851 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Sushant Kaushik1e406c32014-05-09 15:57:52 +053012852 "%s: Network input is not correct %d Max Network supported is %d",
12853 __func__, pPnoRequest->ucNetworksCount,
12854 SIR_PNO_MAX_SUPP_NETWORKS);
Kamath Vinayakba5313f2013-08-22 15:52:39 +053012855 ret = -EINVAL;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053012856 goto error;
12857 }
12858
12859 if ( SIR_PNO_MAX_NETW_CHANNELS_EX < request->n_channels )
12860 {
12861 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Nirav Shah80830bf2013-12-31 16:35:12 +053012862 "%s: Incorrect number of channels %d",
12863 __func__, request->n_channels);
Kamath Vinayakba5313f2013-08-22 15:52:39 +053012864 ret = -EINVAL;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053012865 goto error;
12866 }
12867
12868 /* Framework provides one set of channels(all)
12869 * common for all saved profile */
12870 if (0 != ccmCfgGetStr(hHal, WNI_CFG_VALID_CHANNEL_LIST,
12871 channels_allowed, &num_channels_allowed))
12872 {
12873 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
12874 "%s: failed to get valid channel list", __func__);
Kamath Vinayakba5313f2013-08-22 15:52:39 +053012875 ret = -EINVAL;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053012876 goto error;
12877 }
12878 /* Checking each channel against allowed channel list */
12879 num_ch = 0;
Nirav Shah80830bf2013-12-31 16:35:12 +053012880 if (request->n_channels)
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053012881 {
Nirav Shah80830bf2013-12-31 16:35:12 +053012882 char chList [(request->n_channels*5)+1];
12883 int len;
12884 for (i = 0, len = 0; i < request->n_channels; i++)
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053012885 {
Nirav Shah80830bf2013-12-31 16:35:12 +053012886 for (indx = 0; indx < num_channels_allowed; indx++)
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053012887 {
Nirav Shah80830bf2013-12-31 16:35:12 +053012888 if (request->channels[i]->hw_value == channels_allowed[indx])
12889 {
12890 valid_ch[num_ch++] = request->channels[i]->hw_value;
12891 len += snprintf(chList+len, 5, "%d ",
12892 request->channels[i]->hw_value);
12893 break ;
12894 }
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053012895 }
12896 }
Nirav Shah80830bf2013-12-31 16:35:12 +053012897 hddLog(VOS_TRACE_LEVEL_INFO,"Channel-List: %s ", chList);
12898 }
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053012899
12900 /* Filling per profile params */
12901 for (i = 0; i < pPnoRequest->ucNetworksCount; i++)
12902 {
12903 pPnoRequest->aNetworks[i].ssId.length =
12904 request->match_sets[i].ssid.ssid_len;
12905
12906 if (( 0 == pPnoRequest->aNetworks[i].ssId.length ) ||
12907 ( pPnoRequest->aNetworks[i].ssId.length > 32 ) )
12908 {
12909 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Nirav Shah80830bf2013-12-31 16:35:12 +053012910 "%s: SSID Len %d is not correct for network %d",
12911 __func__, pPnoRequest->aNetworks[i].ssId.length, i);
Kamath Vinayakba5313f2013-08-22 15:52:39 +053012912 ret = -EINVAL;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053012913 goto error;
12914 }
12915
12916 memcpy(pPnoRequest->aNetworks[i].ssId.ssId,
12917 request->match_sets[i].ssid.ssid,
12918 request->match_sets[i].ssid.ssid_len);
Sushant Kaushik1e406c32014-05-09 15:57:52 +053012919 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
12920 "%s: SSID of network %d is %s ", __func__,
12921 i, pPnoRequest->aNetworks[i].ssId.ssId);
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053012922 pPnoRequest->aNetworks[i].authentication = 0; /*eAUTH_TYPE_ANY*/
12923 pPnoRequest->aNetworks[i].encryption = 0; /*eED_ANY*/
12924 pPnoRequest->aNetworks[i].bcastNetwType = 0; /*eBCAST_UNKNOWN*/
12925
12926 /*Copying list of valid channel into request */
12927 memcpy(pPnoRequest->aNetworks[i].aChannels, valid_ch, num_ch);
12928 pPnoRequest->aNetworks[i].ucChannelCount = num_ch;
12929
12930 pPnoRequest->aNetworks[i].rssiThreshold = 0; //Default value
12931 }
12932
Mahesh A Saptasagar7bd6ad42014-07-21 18:56:33 +053012933 for (i = 0; i < request->n_ssids; i++)
12934 {
12935 j = 0;
12936 while (j < pPnoRequest->ucNetworksCount)
12937 {
12938 if ((pPnoRequest->aNetworks[j].ssId.length ==
12939 request->ssids[i].ssid_len) &&
12940 (0 == memcmp(pPnoRequest->aNetworks[j].ssId.ssId,
12941 request->ssids[i].ssid,
12942 pPnoRequest->aNetworks[j].ssId.length)))
12943 {
12944 pPnoRequest->aNetworks[j].bcastNetwType = eBCAST_HIDDEN;
12945 break;
12946 }
12947 j++;
12948 }
12949 }
12950 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
12951 "Number of hidden networks being Configured = %d",
12952 request->n_ssids);
Madan Mohan Koyyalamudia7765d52013-09-18 16:49:56 +053012953 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Jeff Johnson59a121e2013-11-30 09:46:08 -080012954 "request->ie_len = %zu", request->ie_len);
Madan Mohan Koyyalamudia7765d52013-09-18 16:49:56 +053012955 if ((0 < request->ie_len) && (NULL != request->ie))
12956 {
12957 pPnoRequest->us24GProbeTemplateLen = request->ie_len;
12958 memcpy(&pPnoRequest->p24GProbeTemplate, request->ie,
12959 pPnoRequest->us24GProbeTemplateLen);
12960
12961 pPnoRequest->us5GProbeTemplateLen = request->ie_len;
12962 memcpy(&pPnoRequest->p5GProbeTemplate, request->ie,
12963 pPnoRequest->us5GProbeTemplateLen);
12964 }
12965
Madan Mohan Koyyalamudi1d16f462013-08-27 16:25:34 +053012966 /* Driver gets only one time interval which is hardcoded in
12967 * supplicant for 10000ms. Taking power consumption into account 6 timers
12968 * will be used, Timervalue is increased exponentially i.e 10,20,40,
12969 * 80,160,320 secs. And number of scan cycle for each timer
12970 * is configurable through INI param gPNOScanTimerRepeatValue.
12971 * If it is set to 0 only one timer will be used and PNO scan cycle
12972 * will be repeated after each interval specified by supplicant
12973 * till PNO is disabled.
12974 */
12975 if (0 == pHddCtx->cfg_ini->configPNOScanTimerRepeatValue)
12976 pPnoRequest->scanTimers.ucScanTimersCount = HDD_PNO_SCAN_TIMERS_SET_ONE;
12977 else
12978 pPnoRequest->scanTimers.ucScanTimersCount =
12979 HDD_PNO_SCAN_TIMERS_SET_MULTIPLE;
12980
12981 tempInterval = (request->interval)/1000;
12982 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
12983 "Base scan interval = %d PNOScanTimerRepeatValue = %d",
12984 tempInterval, pHddCtx->cfg_ini->configPNOScanTimerRepeatValue);
12985 for ( i = 0; i < pPnoRequest->scanTimers.ucScanTimersCount; i++)
12986 {
12987 pPnoRequest->scanTimers.aTimerValues[i].uTimerRepeat =
12988 pHddCtx->cfg_ini->configPNOScanTimerRepeatValue;
12989 pPnoRequest->scanTimers.aTimerValues[i].uTimerValue = tempInterval;
12990 tempInterval *= 2;
12991 }
12992 //Repeat last timer until pno disabled.
12993 pPnoRequest->scanTimers.aTimerValues[i-1].uTimerRepeat = 0;
12994
Madan Mohan Koyyalamudid206c7b2013-09-26 22:54:51 +053012995 pPnoRequest->modePNO = SIR_PNO_MODE_IMMEDIATE;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053012996
Vinay Krishna Erannaf0e523b2014-03-01 21:00:16 +053012997 INIT_COMPLETION(pAdapter->pno_comp_var);
12998 pPnoRequest->statusCallback = hdd_cfg80211_sched_scan_start_status_cb;
12999 pPnoRequest->callbackContext = pAdapter;
13000 pAdapter->pno_req_status = 0;
13001
Nirav Shah80830bf2013-12-31 16:35:12 +053013002 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
13003 "SessionId %d, enable %d, modePNO %d, ucScanTimersCount %d",
13004 pAdapter->sessionId, pPnoRequest->enable, pPnoRequest->modePNO,
13005 pPnoRequest->scanTimers.ucScanTimersCount);
13006
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053013007 status = sme_SetPreferredNetworkList(WLAN_HDD_GET_HAL_CTX(pAdapter),
13008 pPnoRequest, pAdapter->sessionId,
13009 hdd_cfg80211_sched_scan_done_callback, pAdapter);
13010 if (eHAL_STATUS_SUCCESS != status)
13011 {
13012 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Nirav Shah80830bf2013-12-31 16:35:12 +053013013 "%s: Failed to enable PNO", __func__);
Kamath Vinayakba5313f2013-08-22 15:52:39 +053013014 ret = -EINVAL;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053013015 goto error;
13016 }
13017
Vinay Krishna Erannaf0e523b2014-03-01 21:00:16 +053013018 ret = wait_for_completion_timeout(
13019 &pAdapter->pno_comp_var,
13020 msecs_to_jiffies(WLAN_WAIT_TIME_PNO));
13021 if (0 >= ret)
13022 {
13023 // Did not receive the response for PNO enable in time.
13024 // Assuming the PNO enable was success.
13025 // Returning error from here, because we timeout, results
13026 // in side effect of Wifi (Wifi Setting) not to work.
13027 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
13028 FL("Timed out waiting for PNO to be Enabled"));
13029 ret = 0;
13030 goto error;
13031 }
13032
c_hpothu3c986b22014-07-09 14:45:09 +053013033 vos_mem_free(pPnoRequest);
Vinay Krishna Erannaf0e523b2014-03-01 21:00:16 +053013034 ret = pAdapter->pno_req_status;
c_hpothu37f21312014-04-09 21:49:54 +053013035 return ret;
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053013036
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053013037error:
Vinay Krishna Erannaf0e523b2014-03-01 21:00:16 +053013038 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
13039 FL("PNO scanRequest offloaded ret = %d"), ret);
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053013040 vos_mem_free(pPnoRequest);
c_hpothu37f21312014-04-09 21:49:54 +053013041 pHddCtx->isPnoEnable = FALSE;
Kamath Vinayakba5313f2013-08-22 15:52:39 +053013042 return ret;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053013043}
13044
13045/*
Mahesh A Saptasagar6cc38562014-05-23 21:22:17 +053013046 * FUNCTION: wlan_hdd_cfg80211_sched_scan_start
13047 * NL interface to enable PNO
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053013048 */
Mahesh A Saptasagar6cc38562014-05-23 21:22:17 +053013049static int wlan_hdd_cfg80211_sched_scan_start(struct wiphy *wiphy,
13050 struct net_device *dev, struct cfg80211_sched_scan_request *request)
13051{
13052 int ret;
13053
13054 vos_ssr_protect(__func__);
13055 ret = __wlan_hdd_cfg80211_sched_scan_start(wiphy, dev, request);
13056 vos_ssr_unprotect(__func__);
13057
13058 return ret;
13059}
13060
13061/*
13062 * FUNCTION: __wlan_hdd_cfg80211_sched_scan_stop
13063 * Function to disable PNO
13064 */
13065static int __wlan_hdd_cfg80211_sched_scan_stop(struct wiphy *wiphy,
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053013066 struct net_device *dev)
13067{
13068 eHalStatus status = eHAL_STATUS_FAILURE;
13069 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
13070 hdd_context_t *pHddCtx;
13071 tHalHandle hHal;
13072 tpSirPNOScanReq pPnoRequest = NULL;
Kamath Vinayakba5313f2013-08-22 15:52:39 +053013073 int ret = 0;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053013074
13075 ENTER();
13076
13077 if (NULL == pAdapter)
13078 {
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053013079 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053013080 "%s: HDD adapter is Null", __func__);
13081 return -ENODEV;
13082 }
13083
13084 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053013085
Kamath Vinayakba5313f2013-08-22 15:52:39 +053013086 if (NULL == pHddCtx)
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053013087 {
Gopichand Nakkalac005b7c2013-05-14 16:04:14 +053013088 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Kamath Vinayakba5313f2013-08-22 15:52:39 +053013089 "%s: HDD context is Null", __func__);
13090 return -ENODEV;
13091 }
13092
13093 /* The return 0 is intentional when isLogpInProgress and
13094 * isLoadUnloadInProgress. We did observe a crash due to a return of
13095 * failure in sched_scan_stop , especially for a case where the unload
13096 * of the happens at the same time. The function __cfg80211_stop_sched_scan
13097 * was clearing rdev->sched_scan_req only when the sched_scan_stop returns
13098 * success. If it returns a failure , then its next invocation due to the
13099 * clean up of the second interface will have the dev pointer corresponding
13100 * to the first one leading to a crash.
13101 */
13102 if (pHddCtx->isLogpInProgress)
13103 {
13104 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
13105 "%s: LOGP in Progress. Ignore!!!", __func__);
13106 return ret;
13107 }
13108
Mihir Shete18156292014-03-11 15:38:30 +053013109 if (WLAN_HDD_IS_LOAD_UNLOAD_IN_PROGRESS(pHddCtx))
Kamath Vinayakba5313f2013-08-22 15:52:39 +053013110 {
13111 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
13112 "%s: Unloading/Loading in Progress. Ignore!!!", __func__);
13113 return ret;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053013114 }
13115
13116 hHal = WLAN_HDD_GET_HAL_CTX(pAdapter);
13117 if (NULL == hHal)
13118 {
13119 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
13120 "%s: HAL context is Null!!!", __func__);
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053013121 return -EINVAL;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053013122 }
13123
13124 pPnoRequest = (tpSirPNOScanReq) vos_mem_malloc(sizeof (tSirPNOScanReq));
13125 if (NULL == pPnoRequest)
13126 {
13127 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
13128 "%s: vos_mem_malloc failed", __func__);
Kamath Vinayakba5313f2013-08-22 15:52:39 +053013129 return -ENOMEM;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053013130 }
13131
13132 memset(pPnoRequest, 0, sizeof (tSirPNOScanReq));
13133 pPnoRequest->enable = 0; /* Disable PNO */
13134 pPnoRequest->ucNetworksCount = 0;
13135
13136 status = sme_SetPreferredNetworkList(hHal, pPnoRequest,
13137 pAdapter->sessionId,
13138 NULL, pAdapter);
13139 if (eHAL_STATUS_SUCCESS != status)
13140 {
13141 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
13142 "Failed to disabled PNO");
Kamath Vinayakba5313f2013-08-22 15:52:39 +053013143 ret = -EINVAL;
Vinay Krishna Erannaf0e523b2014-03-01 21:00:16 +053013144 goto error;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053013145 }
c_hpothu37f21312014-04-09 21:49:54 +053013146 pHddCtx->isPnoEnable = FALSE;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053013147
Vinay Krishna Erannaf0e523b2014-03-01 21:00:16 +053013148error:
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053013149 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Vinay Krishna Erannaf0e523b2014-03-01 21:00:16 +053013150 FL("PNO scan disabled ret = %d"), ret);
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053013151 vos_mem_free(pPnoRequest);
13152
13153 EXIT();
Kamath Vinayakba5313f2013-08-22 15:52:39 +053013154 return ret;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053013155}
13156
Mahesh A Saptasagar6cc38562014-05-23 21:22:17 +053013157/*
13158 * FUNCTION: wlan_hdd_cfg80211_sched_scan_stop
13159 * NL interface to disable PNO
13160 */
13161static int wlan_hdd_cfg80211_sched_scan_stop(struct wiphy *wiphy,
13162 struct net_device *dev)
13163{
13164 int ret;
13165
13166 vos_ssr_protect(__func__);
13167 ret = __wlan_hdd_cfg80211_sched_scan_stop(wiphy, dev);
13168 vos_ssr_unprotect(__func__);
13169
13170 return ret;
13171}
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053013172#endif /*FEATURE_WLAN_SCAN_PNO*/
13173
13174
Mohit Khanna698ba2a2012-12-04 15:08:18 -080013175#ifdef FEATURE_WLAN_TDLS
Sunil Dutt Undekarieacac6f2014-03-21 14:08:53 +053013176#if TDLS_MGMT_VERSION2
Mohit Khanna698ba2a2012-12-04 15:08:18 -080013177static int wlan_hdd_cfg80211_tdls_mgmt(struct wiphy *wiphy, struct net_device *dev,
13178 u8 *peer, u8 action_code, u8 dialog_token,
Sunil Dutt Undekarieacac6f2014-03-21 14:08:53 +053013179 u16 status_code, u32 peer_capability, const u8 *buf, size_t len)
13180#else
13181static int wlan_hdd_cfg80211_tdls_mgmt(struct wiphy *wiphy, struct net_device *dev,
13182 u8 *peer, u8 action_code, u8 dialog_token,
13183 u16 status_code, const u8 *buf, size_t len)
13184#endif
Mohit Khanna698ba2a2012-12-04 15:08:18 -080013185{
13186
13187 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
13188 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
Mohit Khanna698ba2a2012-12-04 15:08:18 -080013189 u8 peerMac[6];
13190 VOS_STATUS status;
Gopichand Nakkala05922802013-03-14 12:23:19 -070013191 int max_sta_failed = 0;
Hoonki Leea34dd892013-02-05 22:56:02 -080013192 int responder;
Hoonki Leed37cbb32013-04-20 00:31:14 -070013193 long rc;
Sunil Dutt Undekarieacac6f2014-03-21 14:08:53 +053013194#if !(TDLS_MGMT_VERSION2)
13195 u32 peer_capability = 0;
13196#endif
Rajesh Chauhana34c6e62014-03-25 16:37:58 +053013197 tANI_U16 numCurrTdlsPeers;
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053013198
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053013199 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
13200 TRACE_CODE_HDD_CFG80211_TDLS_MGMT,
13201 pAdapter->sessionId, action_code));
Hoonki Lee11f7dda2013-02-14 16:55:44 -080013202 if (NULL == pHddCtx || NULL == pHddCtx->cfg_ini)
Mohit Khanna698ba2a2012-12-04 15:08:18 -080013203 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013204 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Mohit Khanna698ba2a2012-12-04 15:08:18 -080013205 "Invalid arguments");
13206 return -EINVAL;
13207 }
13208
Sameer Thalappil75ea31a2013-02-21 19:38:16 -080013209 if (pHddCtx->isLogpInProgress)
13210 {
13211 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
13212 "%s:LOGP in Progress. Ignore!!!", __func__);
Atul Mittal115287b2014-07-08 13:26:33 +053013213 wlan_hdd_tdls_set_link_status(pAdapter,
13214 peer,
13215 eTDLS_LINK_IDLE,
13216 eTDLS_LINK_UNSPECIFIED);
Sameer Thalappil75ea31a2013-02-21 19:38:16 -080013217 return -EBUSY;
13218 }
13219
Hoonki Lee27511902013-03-14 18:19:06 -070013220 if (eTDLS_SUPPORT_NOT_ENABLED == pHddCtx->tdls_mode)
Mohit Khanna698ba2a2012-12-04 15:08:18 -080013221 {
Hoonki Lee27511902013-03-14 18:19:06 -070013222 VOS_TRACE( VOS_MODULE_ID_HDD, TDLS_LOG_LEVEL,
13223 "%s: TDLS mode is disabled OR not enabled in FW."
13224 MAC_ADDRESS_STR " action %d declined.",
13225 __func__, MAC_ADDR_ARRAY(peer), action_code);
Mohit Khanna698ba2a2012-12-04 15:08:18 -080013226 return -ENOTSUPP;
13227 }
Lee Hoonkic1262f22013-01-24 21:59:00 -080013228
Hoonki Lee27511902013-03-14 18:19:06 -070013229 /* other than teardown frame, other mgmt frames are not sent if disabled */
13230 if (SIR_MAC_TDLS_TEARDOWN != action_code)
13231 {
13232 /* if tdls_mode is disabled to respond to peer's request */
13233 if (eTDLS_SUPPORT_DISABLED == pHddCtx->tdls_mode)
13234 {
13235 VOS_TRACE( VOS_MODULE_ID_HDD, TDLS_LOG_LEVEL,
13236 "%s: " MAC_ADDRESS_STR
Gopichand Nakkala34d1b062013-03-19 15:28:33 -070013237 " TDLS mode is disabled. action %d declined.",
13238 __func__, MAC_ADDR_ARRAY(peer), action_code);
Hoonki Lee27511902013-03-14 18:19:06 -070013239
13240 return -ENOTSUPP;
13241 }
Agarwal Ashish4b87f922014-06-18 03:03:21 +053013242
13243 if (vos_max_concurrent_connections_reached())
13244 {
13245 hddLog(VOS_TRACE_LEVEL_INFO, FL("Reached max concurrent connections"));
13246 return -EINVAL;
13247 }
Hoonki Lee27511902013-03-14 18:19:06 -070013248 }
13249
Gopichand Nakkalab977a972013-02-18 19:15:09 -080013250 if (WLAN_IS_TDLS_SETUP_ACTION(action_code))
13251 {
Madan Mohan Koyyalamudi96797442013-10-08 16:04:42 +053013252 if (NULL != wlan_hdd_tdls_is_progress(pHddCtx, peer, TRUE))
Gopichand Nakkalab977a972013-02-18 19:15:09 -080013253 {
13254 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Gopichand Nakkalac87400e2013-03-13 18:51:00 -070013255 "%s: " MAC_ADDRESS_STR
Gopichand Nakkala34d1b062013-03-19 15:28:33 -070013256 " TDLS setup is ongoing. action %d declined.",
13257 __func__, MAC_ADDR_ARRAY(peer), action_code);
13258 return -EPERM;
Gopichand Nakkalab977a972013-02-18 19:15:09 -080013259 }
13260 }
13261
Hoonki Lee11f7dda2013-02-14 16:55:44 -080013262 if (SIR_MAC_TDLS_SETUP_REQ == action_code ||
13263 SIR_MAC_TDLS_SETUP_RSP == action_code )
Lee Hoonkic1262f22013-01-24 21:59:00 -080013264 {
Rajesh Chauhana34c6e62014-03-25 16:37:58 +053013265 numCurrTdlsPeers = wlan_hdd_tdlsConnectedPeers(pAdapter);
13266 if (HDD_MAX_NUM_TDLS_STA <= numCurrTdlsPeers)
Lee Hoonkic1262f22013-01-24 21:59:00 -080013267 {
13268 /* supplicant still sends tdls_mgmt(SETUP_REQ) even after
13269 we return error code at 'add_station()'. Hence we have this
13270 check again in addtion to add_station().
13271 Anyway, there is no hard to double-check. */
Hoonki Lee11f7dda2013-02-14 16:55:44 -080013272 if (SIR_MAC_TDLS_SETUP_REQ == action_code)
Lee Hoonkic1262f22013-01-24 21:59:00 -080013273 {
Gopichand Nakkalac87400e2013-03-13 18:51:00 -070013274 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
13275 "%s: " MAC_ADDRESS_STR
Rajesh Chauhana34c6e62014-03-25 16:37:58 +053013276 " TDLS Max peer already connected. action (%d) declined. Num of peers (%d), Max allowed (%d).",
13277 __func__, MAC_ADDR_ARRAY(peer), action_code,
13278 numCurrTdlsPeers, HDD_MAX_NUM_TDLS_STA);
Sunil Dutt388ac8f2013-11-28 18:06:52 +053013279 return -EINVAL;
Lee Hoonkic1262f22013-01-24 21:59:00 -080013280 }
13281 else
13282 {
Gopichand Nakkalab977a972013-02-18 19:15:09 -080013283 /* maximum reached. tweak to send error code to peer and return
13284 error code to supplicant */
Lee Hoonkic1262f22013-01-24 21:59:00 -080013285 status_code = eSIR_MAC_UNSPEC_FAILURE_STATUS;
Gopichand Nakkalac87400e2013-03-13 18:51:00 -070013286 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
13287 "%s: " MAC_ADDRESS_STR
Rajesh Chauhana34c6e62014-03-25 16:37:58 +053013288 " TDLS Max peer already connected, send response status (%d). Num of peers (%d), Max allowed (%d).",
13289 __func__, MAC_ADDR_ARRAY(peer), status_code,
13290 numCurrTdlsPeers, HDD_MAX_NUM_TDLS_STA);
Gopichand Nakkala05922802013-03-14 12:23:19 -070013291 max_sta_failed = -EPERM;
Gopichand Nakkalab977a972013-02-18 19:15:09 -080013292 /* fall through to send setup resp with failure status
13293 code */
Lee Hoonkic1262f22013-01-24 21:59:00 -080013294 }
13295 }
Hoonki Lee11f7dda2013-02-14 16:55:44 -080013296 else
13297 {
13298 hddTdlsPeer_t *pTdlsPeer;
Madan Mohan Koyyalamudi96797442013-10-08 16:04:42 +053013299 pTdlsPeer = wlan_hdd_tdls_find_peer(pAdapter, peer, TRUE);
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -070013300 if (pTdlsPeer && TDLS_IS_CONNECTED(pTdlsPeer))
Hoonki Lee11f7dda2013-02-14 16:55:44 -080013301 {
Gopichand Nakkalac87400e2013-03-13 18:51:00 -070013302 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Gopichand Nakkala34d1b062013-03-19 15:28:33 -070013303 "%s:" MAC_ADDRESS_STR " already connected. action %d declined.",
13304 __func__, MAC_ADDR_ARRAY(peer), action_code);
Hoonki Lee11f7dda2013-02-14 16:55:44 -080013305 return -EPERM;
13306 }
13307 }
Lee Hoonkic1262f22013-01-24 21:59:00 -080013308 }
Hoonki Lee11f7dda2013-02-14 16:55:44 -080013309 vos_mem_copy(peerMac, peer, 6);
Mohit Khanna698ba2a2012-12-04 15:08:18 -080013310
Hoonki Lee1090c6a2013-01-16 17:40:54 -080013311#ifdef WLAN_FEATURE_TDLS_DEBUG
13312 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Arun Kumar Khandavalli9fb625e2014-03-17 16:07:40 +053013313 "%s: " MAC_ADDRESS_STR " action %d, dialog_token %d status %d, len = %zu",
Gopichand Nakkalac87400e2013-03-13 18:51:00 -070013314 "tdls_mgmt", MAC_ADDR_ARRAY(peer),
13315 action_code, dialog_token, status_code, len);
Hoonki Lee1090c6a2013-01-16 17:40:54 -080013316#endif
Mohit Khanna698ba2a2012-12-04 15:08:18 -080013317
Hoonki Leea34dd892013-02-05 22:56:02 -080013318 /*Except teardown responder will not be used so just make 0*/
13319 responder = 0;
Hoonki Lee11f7dda2013-02-14 16:55:44 -080013320 if (SIR_MAC_TDLS_TEARDOWN == action_code)
Hoonki Leea34dd892013-02-05 22:56:02 -080013321 {
Gopichand Nakkala97a65fd2013-04-16 16:59:38 -070013322
13323 hddTdlsPeer_t *pTdlsPeer;
Madan Mohan Koyyalamudi96797442013-10-08 16:04:42 +053013324 pTdlsPeer = wlan_hdd_tdls_find_peer(pAdapter, peerMac, TRUE);
Gopichand Nakkala97a65fd2013-04-16 16:59:38 -070013325
13326 if(pTdlsPeer && TDLS_IS_CONNECTED(pTdlsPeer))
13327 responder = pTdlsPeer->is_responder;
13328 else
Hoonki Leea34dd892013-02-05 22:56:02 -080013329 {
Gopichand Nakkala97a65fd2013-04-16 16:59:38 -070013330 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Arun Kumar Khandavalli9fb625e2014-03-17 16:07:40 +053013331 "%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 -070013332 __func__, MAC_ADDR_ARRAY(peer), (NULL == pTdlsPeer) ? -1 : pTdlsPeer->link_status,
13333 dialog_token, status_code, len);
13334 return -EPERM;
Hoonki Leea34dd892013-02-05 22:56:02 -080013335 }
Mohit Khanna698ba2a2012-12-04 15:08:18 -080013336 }
Mohit Khanna698ba2a2012-12-04 15:08:18 -080013337
Gopichand Nakkala2f1ff152013-07-01 11:27:43 +053013338 /* For explicit trigger of DIS_REQ come out of BMPS for
13339 successfully receiving DIS_RSP from peer. */
Hoonki Lee14621352013-04-16 17:51:19 -070013340 if ((SIR_MAC_TDLS_SETUP_RSP == action_code) ||
Gopichand Nakkala2f1ff152013-07-01 11:27:43 +053013341 (SIR_MAC_TDLS_DIS_RSP == action_code) ||
13342 (SIR_MAC_TDLS_DIS_REQ == action_code))
Hoonki Lee14621352013-04-16 17:51:19 -070013343 {
13344 if (TRUE == sme_IsPmcBmps(WLAN_HDD_GET_HAL_CTX(pAdapter)))
13345 {
13346 VOS_TRACE( VOS_MODULE_ID_HDD, TDLS_LOG_LEVEL,
Gopichand Nakkala2f1ff152013-07-01 11:27:43 +053013347 "%s: Sending frame action_code %u.Disable BMPS", __func__, action_code);
Hoonki Lee14621352013-04-16 17:51:19 -070013348 hdd_disable_bmps_imps(pHddCtx, WLAN_HDD_INFRA_STATION);
13349 }
Gopichand Nakkala2f1ff152013-07-01 11:27:43 +053013350 if (SIR_MAC_TDLS_DIS_REQ != action_code)
13351 wlan_hdd_tdls_set_cap(pAdapter, peerMac, eTDLS_CAP_SUPPORTED);
Hoonki Lee14621352013-04-16 17:51:19 -070013352 }
13353
Hoonki Lee5305c3a2013-04-29 23:28:59 -070013354 /* make sure doesn't call send_mgmt() while it is pending */
13355 if (TDLS_CTX_MAGIC == pAdapter->mgmtTxCompletionStatus)
13356 {
13357 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Arif Hussain6d2a3322013-11-17 19:50:10 -080013358 "%s: " MAC_ADDRESS_STR " action %d couldn't sent, as one is pending. return EBUSY",
Hoonki Lee5305c3a2013-04-29 23:28:59 -070013359 __func__, MAC_ADDR_ARRAY(peer), action_code);
13360 return -EBUSY;
13361 }
13362
13363 pAdapter->mgmtTxCompletionStatus = TDLS_CTX_MAGIC;
Gopichand Nakkalab977a972013-02-18 19:15:09 -080013364 INIT_COMPLETION(pAdapter->tdls_mgmt_comp);
13365
Mohit Khanna698ba2a2012-12-04 15:08:18 -080013366 status = sme_SendTdlsMgmtFrame(WLAN_HDD_GET_HAL_CTX(pAdapter), pAdapter->sessionId,
Pradeep Reddy POTTETIca171f82014-03-21 14:17:35 +053013367 peerMac, action_code, dialog_token, status_code, peer_capability, (tANI_U8 *)buf, len, responder);
Mohit Khanna698ba2a2012-12-04 15:08:18 -080013368
Gopichand Nakkalab977a972013-02-18 19:15:09 -080013369 if (VOS_STATUS_SUCCESS != status)
13370 {
Mohit Khanna698ba2a2012-12-04 15:08:18 -080013371 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
13372 "%s: sme_SendTdlsMgmtFrame failed!", __func__);
Hoonki Lee5305c3a2013-04-29 23:28:59 -070013373 pAdapter->mgmtTxCompletionStatus = FALSE;
Hoonki Lee14621352013-04-16 17:51:19 -070013374 wlan_hdd_tdls_check_bmps(pAdapter);
Sunil Dutt388ac8f2013-11-28 18:06:52 +053013375 return -EINVAL;
Mohit Khanna698ba2a2012-12-04 15:08:18 -080013376 }
13377
Hoonki Leed37cbb32013-04-20 00:31:14 -070013378 rc = wait_for_completion_interruptible_timeout(&pAdapter->tdls_mgmt_comp,
13379 msecs_to_jiffies(WAIT_TIME_TDLS_MGMT));
13380
13381 if ((rc <= 0) || (TRUE != pAdapter->mgmtTxCompletionStatus))
Gopichand Nakkalab977a972013-02-18 19:15:09 -080013382 {
Hoonki Leed37cbb32013-04-20 00:31:14 -070013383 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Jeff Johnson0299d0a2013-10-30 12:37:43 -070013384 "%s: Mgmt Tx Completion failed status %ld TxCompletion %u",
Hoonki Leed37cbb32013-04-20 00:31:14 -070013385 __func__, rc, pAdapter->mgmtTxCompletionStatus);
Hoonki Lee5305c3a2013-04-29 23:28:59 -070013386 pAdapter->mgmtTxCompletionStatus = FALSE;
Yue Ma4f55ef32014-01-23 16:45:33 -080013387
13388 if (pHddCtx->isLogpInProgress)
13389 {
13390 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
13391 "%s: LOGP in Progress. Ignore!!!", __func__);
13392 return -EAGAIN;
13393 }
13394
Hoonki Leed37cbb32013-04-20 00:31:14 -070013395 wlan_hdd_tdls_check_bmps(pAdapter);
Sunil Dutt388ac8f2013-11-28 18:06:52 +053013396 return -EINVAL;
Gopichand Nakkalab977a972013-02-18 19:15:09 -080013397 }
13398
Gopichand Nakkala05922802013-03-14 12:23:19 -070013399 if (max_sta_failed)
Hoonki Lee14621352013-04-16 17:51:19 -070013400 {
13401 wlan_hdd_tdls_check_bmps(pAdapter);
Gopichand Nakkala05922802013-03-14 12:23:19 -070013402 return max_sta_failed;
Hoonki Lee14621352013-04-16 17:51:19 -070013403 }
Gopichand Nakkalab977a972013-02-18 19:15:09 -080013404
Hoonki Leea34dd892013-02-05 22:56:02 -080013405 if (SIR_MAC_TDLS_SETUP_RSP == action_code)
13406 {
Gopichand Nakkala4327a152013-03-04 23:22:42 -080013407 wlan_hdd_tdls_set_responder(pAdapter, peerMac, TRUE);
Hoonki Leea34dd892013-02-05 22:56:02 -080013408 }
13409 else if (SIR_MAC_TDLS_SETUP_CNF == action_code)
13410 {
Gopichand Nakkala4327a152013-03-04 23:22:42 -080013411 wlan_hdd_tdls_set_responder(pAdapter, peerMac, FALSE);
Hoonki Leea34dd892013-02-05 22:56:02 -080013412 }
Mohit Khanna698ba2a2012-12-04 15:08:18 -080013413
13414 return 0;
13415}
13416
Atul Mittal115287b2014-07-08 13:26:33 +053013417
13418int wlan_hdd_tdls_extctrl_config_peer(hdd_adapter_t *pAdapter,
13419 u8 *peer,
13420 cfg80211_exttdls_callback callback)
13421{
13422
13423 hddTdlsPeer_t *pTdlsPeer;
13424 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
13425 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
13426 " %s : NL80211_TDLS_SETUP for " MAC_ADDRESS_STR,
13427 __func__, MAC_ADDR_ARRAY(peer));
13428
13429 if ( (FALSE == pHddCtx->cfg_ini->fTDLSExternalControl) ||
13430 (FALSE == pHddCtx->cfg_ini->fEnableTDLSImplicitTrigger) ) {
13431
13432 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
13433 " %s TDLS External control and Implicit Trigger not enabled ",
13434 __func__);
13435 return -ENOTSUPP;
13436 }
13437
13438 /* To cater the requirement of establishing the TDLS link
13439 * irrespective of the data traffic , get an entry of TDLS peer.
13440 */
13441 pTdlsPeer = wlan_hdd_tdls_get_peer(pAdapter, peer);
13442 if (pTdlsPeer == NULL) {
13443 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
13444 "%s: peer " MAC_ADDRESS_STR " not existing",
13445 __func__, MAC_ADDR_ARRAY(peer));
13446 return -EINVAL;
13447 }
13448
13449 if ( 0 != wlan_hdd_tdls_set_force_peer(pAdapter, peer, TRUE) ) {
13450
13451 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
13452 " %s TDLS Add Force Peer Failed",
13453 __func__);
13454 return -EINVAL;
13455 }
13456 /*EXT TDLS*/
13457
13458 if ( 0 != wlan_hdd_set_callback(pTdlsPeer, callback) ) {
13459 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
13460 " %s TDLS set callback Failed",
13461 __func__);
13462 return -EINVAL;
13463 }
13464
13465 return(0);
13466
13467}
13468
13469int wlan_hdd_tdls_extctrl_deconfig_peer(hdd_adapter_t *pAdapter, u8 *peer)
13470{
13471
13472 hddTdlsPeer_t *pTdlsPeer;
13473 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
13474 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
13475 " %s : NL80211_TDLS_TEARDOWN for " MAC_ADDRESS_STR,
13476 __func__, MAC_ADDR_ARRAY(peer));
13477
13478 if ( (FALSE == pHddCtx->cfg_ini->fTDLSExternalControl) ||
13479 (FALSE == pHddCtx->cfg_ini->fEnableTDLSImplicitTrigger) ) {
13480
13481 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
13482 " %s TDLS External control and Implicit Trigger not enabled ",
13483 __func__);
13484 return -ENOTSUPP;
13485 }
13486
13487
13488 pTdlsPeer = wlan_hdd_tdls_find_peer(pAdapter, peer, TRUE);
13489
13490 if ( NULL == pTdlsPeer ) {
13491 hddLog(VOS_TRACE_LEVEL_INFO, "%s: " MAC_ADDRESS_STR
13492 " peer not exsting",
13493 __func__, MAC_ADDR_ARRAY(peer));
13494 return -EINVAL;
13495 }
13496 else {
13497 wlan_hdd_tdls_indicate_teardown(pAdapter, pTdlsPeer,
13498 eSIR_MAC_TDLS_TEARDOWN_UNSPEC_REASON);
13499 }
13500
13501 if ( 0 != wlan_hdd_tdls_set_force_peer(pAdapter, peer, FALSE) )
13502 return -EINVAL;
13503
13504 /*EXT TDLS*/
13505
13506 if ( 0 != wlan_hdd_set_callback(pTdlsPeer, NULL )) {
13507
13508 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
13509 " %s TDLS set callback Failed",
13510 __func__);
13511 return -EINVAL;
13512 }
13513 return(0);
13514
13515}
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053013516static int __wlan_hdd_cfg80211_tdls_oper(struct wiphy *wiphy, struct net_device *dev,
Mohit Khanna698ba2a2012-12-04 15:08:18 -080013517 u8 *peer, enum nl80211_tdls_operation oper)
13518{
13519 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
13520 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053013521 int status;
Hoonki Lee5305c3a2013-04-29 23:28:59 -070013522 hddTdlsPeer_t *pTdlsPeer;
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053013523
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053013524 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
13525 TRACE_CODE_HDD_CFG80211_TDLS_OPER,
13526 pAdapter->sessionId, oper));
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053013527 if ( NULL == peer )
Mohit Khanna698ba2a2012-12-04 15:08:18 -080013528 {
Gopichand Nakkalab977a972013-02-18 19:15:09 -080013529 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Chilam Ngc4244af2013-04-01 15:37:32 -070013530 "%s: Invalid arguments", __func__);
Mohit Khanna698ba2a2012-12-04 15:08:18 -080013531 return -EINVAL;
13532 }
Hoonki Lee1090c6a2013-01-16 17:40:54 -080013533
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053013534 status = wlan_hdd_validate_context(pHddCtx);
13535
13536 if (0 != status)
Sameer Thalappil75ea31a2013-02-21 19:38:16 -080013537 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053013538 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
13539 "%s: HDD context is not valid", __func__);
13540 return status;
Sameer Thalappil75ea31a2013-02-21 19:38:16 -080013541 }
13542
Mohit Khanna698ba2a2012-12-04 15:08:18 -080013543
13544 if( FALSE == pHddCtx->cfg_ini->fEnableTDLSSupport ||
Hoonki Lee1090c6a2013-01-16 17:40:54 -080013545 FALSE == sme_IsFeatureSupportedByFW(TDLS))
Mohit Khanna698ba2a2012-12-04 15:08:18 -080013546 {
Hoonki Lee1090c6a2013-01-16 17:40:54 -080013547 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Chilam Ngc4244af2013-04-01 15:37:32 -070013548 "TDLS Disabled in INI OR not enabled in FW. "
13549 "Cannot process TDLS commands");
Mohit Khanna698ba2a2012-12-04 15:08:18 -080013550 return -ENOTSUPP;
13551 }
13552
13553 switch (oper) {
13554 case NL80211_TDLS_ENABLE_LINK:
13555 {
Mohit Khanna698ba2a2012-12-04 15:08:18 -080013556 VOS_STATUS status;
c_hpothu6ff1c3c2013-10-01 19:01:57 +053013557 long ret;
Gopichand Nakkala79ff85d2013-05-27 17:05:29 +053013558 tCsrTdlsLinkEstablishParams tdlsLinkEstablishParams;
Mohit Khanna698ba2a2012-12-04 15:08:18 -080013559
Sunil Dutt41de4e22013-11-14 18:09:02 +053013560 pTdlsPeer = wlan_hdd_tdls_find_peer(pAdapter, peer, TRUE);
13561
13562 if ( NULL == pTdlsPeer ) {
13563 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: " MAC_ADDRESS_STR
13564 " (oper %d) not exsting. ignored",
13565 __func__, MAC_ADDR_ARRAY(peer), (int)oper);
13566 return -EINVAL;
13567 }
13568
13569 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
13570 "%s: " MAC_ADDRESS_STR " link_status %d (%s) ", "tdls_oper",
13571 MAC_ADDR_ARRAY(peer), pTdlsPeer->link_status,
13572 "NL80211_TDLS_ENABLE_LINK");
13573
Gopichand Nakkala2f4a2822013-04-17 11:22:01 -070013574 if (!TDLS_STA_INDEX_VALID(pTdlsPeer->staId))
13575 {
13576 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Invalid Staion Index %u "
13577 MAC_ADDRESS_STR " failed",
13578 __func__, pTdlsPeer->staId, MAC_ADDR_ARRAY(peer));
13579 return -EINVAL;
13580 }
13581
Hoonki Lee5305c3a2013-04-29 23:28:59 -070013582 if (eTDLS_LINK_CONNECTED != pTdlsPeer->link_status)
Gopichand Nakkalac87400e2013-03-13 18:51:00 -070013583 {
Madan Mohan Koyyalamudice419872013-09-13 19:36:52 +053013584 if (IS_ADVANCE_TDLS_ENABLE) {
Gopichand Nakkala24be5312013-07-02 16:47:12 +053013585
Madan Mohan Koyyalamudice419872013-09-13 19:36:52 +053013586 if (0 != wlan_hdd_tdls_get_link_establish_params(
13587 pAdapter, peer,&tdlsLinkEstablishParams)) {
13588 return -EINVAL;
13589 }
13590 INIT_COMPLETION(pAdapter->tdls_link_establish_req_comp);
Gopichand Nakkala79ff85d2013-05-27 17:05:29 +053013591
Madan Mohan Koyyalamudice419872013-09-13 19:36:52 +053013592 sme_SendTdlsLinkEstablishParams(WLAN_HDD_GET_HAL_CTX(pAdapter),
13593 pAdapter->sessionId, peer, &tdlsLinkEstablishParams);
13594 /* Send TDLS peer UAPSD capabilities to the firmware and
13595 * register with the TL on after the response for this operation
13596 * is received .
13597 */
13598 ret = wait_for_completion_interruptible_timeout(
13599 &pAdapter->tdls_link_establish_req_comp,
13600 msecs_to_jiffies(WAIT_TIME_TDLS_LINK_ESTABLISH_REQ));
13601 if (ret <= 0)
13602 {
13603 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
13604 "%s: Link Establish Request Faled Status %ld",
13605 __func__, ret);
13606 return -EINVAL;
13607 }
Gopichand Nakkala79ff85d2013-05-27 17:05:29 +053013608 }
Atul Mittal115287b2014-07-08 13:26:33 +053013609 wlan_hdd_tdls_set_peer_link_status(pTdlsPeer,
13610 eTDLS_LINK_CONNECTED,
13611 eTDLS_LINK_SUCCESS);
Gopichand Nakkala471708b2013-06-04 20:03:01 +053013612 /* Mark TDLS client Authenticated .*/
13613 status = WLANTL_ChangeSTAState( pHddCtx->pvosContext,
13614 pTdlsPeer->staId,
13615 WLANTL_STA_AUTHENTICATED);
Gopichand Nakkalaccd3a382013-03-19 13:56:10 -070013616 if (VOS_STATUS_SUCCESS == status)
13617 {
Hoonki Lee14621352013-04-16 17:51:19 -070013618 if (pTdlsPeer->is_responder == 0)
13619 {
13620 v_U8_t staId = (v_U8_t)pTdlsPeer->staId;
13621
13622 wlan_hdd_tdls_timer_restart(pAdapter,
13623 &pTdlsPeer->initiatorWaitTimeoutTimer,
13624 WAIT_TIME_TDLS_INITIATOR);
13625 /* suspend initiator TX until it receives direct packet from the
13626 reponder or WAIT_TIME_TDLS_INITIATOR timer expires */
13627 WLANTL_SuspendDataTx( (WLAN_HDD_GET_CTX(pAdapter))->pvosContext,
13628 &staId, NULL);
13629 }
Gopichand Nakkalaccd3a382013-03-19 13:56:10 -070013630 wlan_hdd_tdls_increment_peer_count(pAdapter);
13631 }
Gopichand Nakkalac87400e2013-03-13 18:51:00 -070013632 wlan_hdd_tdls_check_bmps(pAdapter);
Gopichand Nakkala79ff85d2013-05-27 17:05:29 +053013633
13634 /* Update TL about the UAPSD masks , to route the packets to firmware */
Gopichand Nakkala574f6d12013-06-27 19:38:43 +053013635 if ((TRUE == pHddCtx->cfg_ini->fEnableTDLSBufferSta)
13636 || pHddCtx->cfg_ini->fTDLSUapsdMask )
Gopichand Nakkala79ff85d2013-05-27 17:05:29 +053013637 {
Gopichand Nakkala574f6d12013-06-27 19:38:43 +053013638 int ac;
13639 uint8 ucAc[4] = { WLANTL_AC_VO,
13640 WLANTL_AC_VI,
13641 WLANTL_AC_BK,
13642 WLANTL_AC_BE };
13643 uint8 tlTid[4] = { 7, 5, 2, 3 } ;
13644 for(ac=0; ac < 4; ac++)
13645 {
13646 status = WLANTL_EnableUAPSDForAC( (WLAN_HDD_GET_CTX(pAdapter))->pvosContext,
13647 pTdlsPeer->staId, ucAc[ac],
13648 tlTid[ac], tlTid[ac], 0, 0,
13649 WLANTL_BI_DIR );
13650 }
Gopichand Nakkala79ff85d2013-05-27 17:05:29 +053013651 }
Gopichand Nakkalac87400e2013-03-13 18:51:00 -070013652 }
13653
Mohit Khanna698ba2a2012-12-04 15:08:18 -080013654 }
13655 break;
13656 case NL80211_TDLS_DISABLE_LINK:
Lee Hoonkic1262f22013-01-24 21:59:00 -080013657 {
Sunil Dutt41de4e22013-11-14 18:09:02 +053013658 pTdlsPeer = wlan_hdd_tdls_find_peer(pAdapter, peer, TRUE);
13659
13660 if ( NULL == pTdlsPeer ) {
13661 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: " MAC_ADDRESS_STR
13662 " (oper %d) not exsting. ignored",
13663 __func__, MAC_ADDR_ARRAY(peer), (int)oper);
13664 return -EINVAL;
13665 }
13666
13667 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
13668 "%s: " MAC_ADDRESS_STR " link_status %d (%s) ", "tdls_oper",
13669 MAC_ADDR_ARRAY(peer), pTdlsPeer->link_status,
13670 "NL80211_TDLS_DISABLE_LINK");
13671
Hoonki Lee5305c3a2013-04-29 23:28:59 -070013672 if(TDLS_STA_INDEX_VALID(pTdlsPeer->staId))
Lee Hoonkic1262f22013-01-24 21:59:00 -080013673 {
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -070013674 long status;
13675
Atul Mittal271a7652014-09-12 13:18:22 +053013676
13677 wlan_hdd_tdls_set_peer_link_status(pTdlsPeer,
13678 eTDLS_LINK_TEARING,
13679 (pTdlsPeer->link_status == eTDLS_LINK_TEARING)?
13680 eTDLS_LINK_UNSPECIFIED:
13681 eTDLS_LINK_DROPPED_BY_REMOTE);
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -070013682 INIT_COMPLETION(pAdapter->tdls_del_station_comp);
13683
Lee Hoonkic1262f22013-01-24 21:59:00 -080013684 sme_DeleteTdlsPeerSta( WLAN_HDD_GET_HAL_CTX(pAdapter),
13685 pAdapter->sessionId, peer );
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -070013686
13687 status = wait_for_completion_interruptible_timeout(&pAdapter->tdls_del_station_comp,
13688 msecs_to_jiffies(WAIT_TIME_TDLS_DEL_STA));
Atul Mittal271a7652014-09-12 13:18:22 +053013689 wlan_hdd_tdls_set_peer_link_status(pTdlsPeer,
13690 eTDLS_LINK_IDLE,
13691 (pTdlsPeer->link_status == eTDLS_LINK_TEARING)?
13692 eTDLS_LINK_UNSPECIFIED:
13693 eTDLS_LINK_DROPPED_BY_REMOTE);
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -070013694 if (status <= 0)
13695 {
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -070013696 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
13697 "%s: Del station failed status %ld",
13698 __func__, status);
13699 return -EPERM;
13700 }
Lee Hoonkic1262f22013-01-24 21:59:00 -080013701 }
13702 else
13703 {
Gopichand Nakkalac87400e2013-03-13 18:51:00 -070013704 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
13705 "%s: TDLS Peer Station doesn't exist.", __func__);
Lee Hoonkic1262f22013-01-24 21:59:00 -080013706 }
Lee Hoonkic1262f22013-01-24 21:59:00 -080013707 }
Gopichand Nakkalac87400e2013-03-13 18:51:00 -070013708 break;
Mohit Khanna698ba2a2012-12-04 15:08:18 -080013709 case NL80211_TDLS_TEARDOWN:
Sunil Dutt41de4e22013-11-14 18:09:02 +053013710 {
Atul Mittal115287b2014-07-08 13:26:33 +053013711 status = wlan_hdd_tdls_extctrl_deconfig_peer(pAdapter, peer);
Sunil Dutt41de4e22013-11-14 18:09:02 +053013712
Atul Mittal115287b2014-07-08 13:26:33 +053013713 if (0 != status)
13714 {
13715 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
13716 "%s: Error in TDLS Teardown", __func__);
13717 return status;
Sunil Dutt41de4e22013-11-14 18:09:02 +053013718 }
Sunil Dutt41de4e22013-11-14 18:09:02 +053013719 break;
13720 }
Mohit Khanna698ba2a2012-12-04 15:08:18 -080013721 case NL80211_TDLS_SETUP:
Sunil Dutt41de4e22013-11-14 18:09:02 +053013722 {
Atul Mittal115287b2014-07-08 13:26:33 +053013723 status = wlan_hdd_tdls_extctrl_config_peer(pAdapter,
13724 peer,
13725 NULL);
Sunil Dutt41de4e22013-11-14 18:09:02 +053013726
Atul Mittal115287b2014-07-08 13:26:33 +053013727 if (0 != status)
13728 {
13729 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
13730 "%s: Error in TDLS Setup", __func__);
13731 return status;
Naresh Jayaram937abdf2013-11-26 19:50:25 +053013732 }
Naresh Jayaramdb4514b2013-11-25 18:08:10 +053013733 break;
Sunil Dutt41de4e22013-11-14 18:09:02 +053013734 }
Mohit Khanna698ba2a2012-12-04 15:08:18 -080013735 case NL80211_TDLS_DISCOVERY_REQ:
13736 /* We don't support in-driver setup/teardown/discovery */
c_hpothu6ff1c3c2013-10-01 19:01:57 +053013737 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_WARN,
13738 "%s: We don't support in-driver setup/teardown/discovery "
13739 ,__func__);
Mohit Khanna698ba2a2012-12-04 15:08:18 -080013740 return -ENOTSUPP;
13741 default:
c_hpothu6ff1c3c2013-10-01 19:01:57 +053013742 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
13743 "%s: unsupported event",__func__);
Mohit Khanna698ba2a2012-12-04 15:08:18 -080013744 return -ENOTSUPP;
13745 }
13746 return 0;
13747}
Chilam NG571c65a2013-01-19 12:27:36 +053013748
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053013749static int wlan_hdd_cfg80211_tdls_oper(struct wiphy *wiphy, struct net_device *dev,
13750 u8 *peer, enum nl80211_tdls_operation oper)
13751{
13752 int ret;
13753
13754 vos_ssr_protect(__func__);
13755 ret = __wlan_hdd_cfg80211_tdls_oper(wiphy, dev, peer, oper);
13756 vos_ssr_unprotect(__func__);
13757
13758 return ret;
13759}
13760
Chilam NG571c65a2013-01-19 12:27:36 +053013761int wlan_hdd_cfg80211_send_tdls_discover_req(struct wiphy *wiphy,
13762 struct net_device *dev, u8 *peer)
13763{
Arif Hussaina7c8e412013-11-20 11:06:42 -080013764 hddLog(VOS_TRACE_LEVEL_INFO,
13765 "tdls send discover req: "MAC_ADDRESS_STR,
13766 MAC_ADDR_ARRAY(peer));
Chilam NG571c65a2013-01-19 12:27:36 +053013767
Sunil Dutt Undekarieacac6f2014-03-21 14:08:53 +053013768#if TDLS_MGMT_VERSION2
13769 return wlan_hdd_cfg80211_tdls_mgmt(wiphy, dev, peer,
13770 WLAN_TDLS_DISCOVERY_REQUEST, 1, 0, 0, NULL, 0);
13771#else
Chilam NG571c65a2013-01-19 12:27:36 +053013772 return wlan_hdd_cfg80211_tdls_mgmt(wiphy, dev, peer,
13773 WLAN_TDLS_DISCOVERY_REQUEST, 1, 0, NULL, 0);
Sunil Dutt Undekarieacac6f2014-03-21 14:08:53 +053013774#endif
Chilam NG571c65a2013-01-19 12:27:36 +053013775}
Mohit Khanna698ba2a2012-12-04 15:08:18 -080013776#endif
13777
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053013778#ifdef WLAN_FEATURE_GTK_OFFLOAD
13779/*
13780 * FUNCTION: wlan_hdd_cfg80211_update_replayCounterCallback
13781 * Callback rountine called upon receiving response for
13782 * get offload info
13783 */
13784void wlan_hdd_cfg80211_update_replayCounterCallback(void *callbackContext,
13785 tpSirGtkOffloadGetInfoRspParams pGtkOffloadGetInfoRsp)
13786{
13787
13788 hdd_adapter_t *pAdapter = (hdd_adapter_t *)callbackContext;
Gopichand Nakkalad36ee622013-05-07 14:13:27 +053013789 tANI_U8 tempReplayCounter[8];
13790 hdd_station_ctx_t *pHddStaCtx;
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053013791
13792 ENTER();
13793
13794 if (NULL == pAdapter)
13795 {
Agarwal Ashish971c2882013-10-30 20:11:12 +053013796 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053013797 "%s: HDD adapter is Null", __func__);
13798 return ;
13799 }
13800
13801 if (NULL == pGtkOffloadGetInfoRsp)
13802 {
13803 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
13804 "%s: pGtkOffloadGetInfoRsp is Null", __func__);
13805 return ;
13806 }
13807
13808 if (VOS_STATUS_SUCCESS != pGtkOffloadGetInfoRsp->ulStatus)
13809 {
13810 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
13811 "%s: wlan Failed to get replay counter value",
13812 __func__);
13813 return ;
13814 }
13815
Gopichand Nakkalad36ee622013-05-07 14:13:27 +053013816 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
13817 /* Update replay counter */
13818 pHddStaCtx->gtkOffloadReqParams.ullKeyReplayCounter =
13819 pGtkOffloadGetInfoRsp->ullKeyReplayCounter;
13820
13821 {
13822 /* changing from little to big endian since supplicant
13823 * works on big endian format
13824 */
13825 int i;
13826 tANI_U8 *p = (tANI_U8 *)&pGtkOffloadGetInfoRsp->ullKeyReplayCounter;
13827
13828 for (i = 0; i < 8; i++)
13829 {
13830 tempReplayCounter[7-i] = (tANI_U8)p[i];
13831 }
13832 }
13833
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053013834 /* Update replay counter to NL */
13835 cfg80211_gtk_rekey_notify(pAdapter->dev, pGtkOffloadGetInfoRsp->bssId,
Gopichand Nakkalad36ee622013-05-07 14:13:27 +053013836 tempReplayCounter, GFP_KERNEL);
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053013837}
13838
13839/*
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053013840 * FUNCTION: __wlan_hdd_cfg80211_set_rekey_data
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053013841 * This function is used to offload GTK rekeying job to the firmware.
13842 */
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053013843int __wlan_hdd_cfg80211_set_rekey_data(struct wiphy *wiphy, struct net_device *dev,
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053013844 struct cfg80211_gtk_rekey_data *data)
13845{
13846 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
13847 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
13848 hdd_station_ctx_t *pHddStaCtx;
13849 tHalHandle hHal;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053013850 int result;
Gopichand Nakkalad36ee622013-05-07 14:13:27 +053013851 tSirGtkOffloadParams hddGtkOffloadReqParams;
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053013852 eHalStatus status = eHAL_STATUS_FAILURE;
13853
13854 ENTER();
13855
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053013856
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053013857 if (NULL == pAdapter)
13858 {
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053013859 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053013860 "%s: HDD adapter is Null", __func__);
13861 return -ENODEV;
13862 }
13863
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053013864 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
13865 TRACE_CODE_HDD_CFG80211_SET_REKEY_DATA,
13866 pAdapter->sessionId, pAdapter->device_mode));
13867
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053013868 result = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053013869
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053013870 if (0 != result)
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053013871 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053013872 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
13873 "%s: HDD context is not valid", __func__);
13874 return result;
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053013875 }
13876
13877 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
13878 hHal = WLAN_HDD_GET_HAL_CTX(pAdapter);
13879 if (NULL == hHal)
13880 {
13881 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
13882 "%s: HAL context is Null!!!", __func__);
13883 return -EAGAIN;
13884 }
13885
Gopichand Nakkalad36ee622013-05-07 14:13:27 +053013886 pHddStaCtx->gtkOffloadReqParams.ulFlags = GTK_OFFLOAD_ENABLE;
13887 memcpy(pHddStaCtx->gtkOffloadReqParams.aKCK, data->kck, NL80211_KCK_LEN);
13888 memcpy(pHddStaCtx->gtkOffloadReqParams.aKEK, data->kek, NL80211_KEK_LEN);
13889 memcpy(pHddStaCtx->gtkOffloadReqParams.bssId, &pHddStaCtx->conn_info.bssId,
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053013890 WNI_CFG_BSSID_LEN);
Gopichand Nakkalad36ee622013-05-07 14:13:27 +053013891 {
13892 /* changing from big to little endian since driver
13893 * works on little endian format
13894 */
13895 tANI_U8 *p =
13896 (tANI_U8 *)&pHddStaCtx->gtkOffloadReqParams.ullKeyReplayCounter;
13897 int i;
13898
13899 for (i = 0; i < 8; i++)
13900 {
13901 p[7-i] = data->replay_ctr[i];
13902 }
13903 }
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053013904
13905 if (TRUE == pHddCtx->hdd_wlan_suspended)
13906 {
13907 /* if wlan is suspended, enable GTK offload directly from here */
Gopichand Nakkalad36ee622013-05-07 14:13:27 +053013908 memcpy(&hddGtkOffloadReqParams, &pHddStaCtx->gtkOffloadReqParams,
13909 sizeof (tSirGtkOffloadParams));
13910 status = sme_SetGTKOffload(hHal, &hddGtkOffloadReqParams,
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053013911 pAdapter->sessionId);
13912
13913 if (eHAL_STATUS_SUCCESS != status)
13914 {
13915 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
13916 "%s: sme_SetGTKOffload failed, returned %d",
13917 __func__, status);
13918 return status;
13919 }
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053013920 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
13921 "%s: sme_SetGTKOffload successfull", __func__);
13922 }
13923 else
13924 {
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053013925 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
13926 "%s: wlan not suspended GTKOffload request is stored",
13927 __func__);
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053013928 }
Gopichand Nakkalad36ee622013-05-07 14:13:27 +053013929
13930 return eHAL_STATUS_SUCCESS;
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053013931}
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053013932
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053013933int wlan_hdd_cfg80211_set_rekey_data(struct wiphy *wiphy, struct net_device *dev,
13934 struct cfg80211_gtk_rekey_data *data)
13935{
13936 int ret;
13937
13938 vos_ssr_protect(__func__);
13939 ret = __wlan_hdd_cfg80211_set_rekey_data(wiphy, dev, data);
13940 vos_ssr_unprotect(__func__);
13941
13942 return ret;
13943}
13944#endif /*WLAN_FEATURE_GTK_OFFLOAD*/
Gopichand Nakkalac005b7c2013-05-14 16:04:14 +053013945/*
13946 * FUNCTION: wlan_hdd_cfg80211_set_mac_acl
13947 * This function is used to set access control policy
13948 */
13949static int wlan_hdd_cfg80211_set_mac_acl(struct wiphy *wiphy,
13950 struct net_device *dev, const struct cfg80211_acl_data *params)
13951{
13952 int i;
13953 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
13954 hdd_hostapd_state_t *pHostapdState;
13955 tsap_Config_t *pConfig;
13956 v_CONTEXT_t pVosContext = NULL;
13957 hdd_context_t *pHddCtx;
13958 int status;
13959
13960 ENTER();
13961
13962 if (NULL == pAdapter)
13963 {
13964 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
13965 "%s: HDD adapter is Null", __func__);
13966 return -ENODEV;
13967 }
13968
13969 if (NULL == params)
13970 {
13971 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
13972 "%s: params is Null", __func__);
13973 return -EINVAL;
13974 }
13975
13976 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
13977 status = wlan_hdd_validate_context(pHddCtx);
13978
13979 if (0 != status)
13980 {
13981 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
13982 "%s: HDD context is not valid", __func__);
13983 return status;
13984 }
13985
13986 pVosContext = pHddCtx->pvosContext;
13987 pHostapdState = WLAN_HDD_GET_HOSTAP_STATE_PTR(pAdapter);
13988
13989 if (NULL == pHostapdState)
13990 {
13991 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
13992 "%s: pHostapdState is Null", __func__);
13993 return -EINVAL;
13994 }
13995
13996 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,"acl policy: = %d"
13997 "no acl entries = %d", params->acl_policy, params->n_acl_entries);
13998
13999 if (WLAN_HDD_SOFTAP == pAdapter->device_mode)
14000 {
14001 pConfig = &pAdapter->sessionCtx.ap.sapConfig;
14002
14003 /* default value */
14004 pConfig->num_accept_mac = 0;
14005 pConfig->num_deny_mac = 0;
14006
14007 /**
14008 * access control policy
14009 * @NL80211_ACL_POLICY_ACCEPT_UNLESS_LISTED: Deny stations which are
14010 * listed in hostapd.deny file.
14011 * @NL80211_ACL_POLICY_DENY_UNLESS_LISTED: Allow stations which are
14012 * listed in hostapd.accept file.
14013 */
14014 if (NL80211_ACL_POLICY_DENY_UNLESS_LISTED == params->acl_policy)
14015 {
14016 pConfig->SapMacaddr_acl = eSAP_DENY_UNLESS_ACCEPTED;
14017 }
14018 else if (NL80211_ACL_POLICY_ACCEPT_UNLESS_LISTED == params->acl_policy)
14019 {
14020 pConfig->SapMacaddr_acl = eSAP_ACCEPT_UNLESS_DENIED;
14021 }
14022 else
14023 {
14024 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
14025 "%s:Acl Policy : %d is not supported",
14026 __func__, params->acl_policy);
14027 return -ENOTSUPP;
14028 }
14029
14030 if (eSAP_DENY_UNLESS_ACCEPTED == pConfig->SapMacaddr_acl)
14031 {
14032 pConfig->num_accept_mac = params->n_acl_entries;
14033 for (i = 0; i < params->n_acl_entries; i++)
14034 {
14035 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
14036 "** Add ACL MAC entry %i in WhiletList :"
14037 MAC_ADDRESS_STR, i,
14038 MAC_ADDR_ARRAY(params->mac_addrs[i].addr));
14039
14040 vos_mem_copy(&pConfig->accept_mac[i], params->mac_addrs[i].addr,
14041 sizeof(qcmacaddr));
14042 }
14043 }
14044 else if (eSAP_ACCEPT_UNLESS_DENIED == pConfig->SapMacaddr_acl)
14045 {
14046 pConfig->num_deny_mac = params->n_acl_entries;
14047 for (i = 0; i < params->n_acl_entries; i++)
14048 {
14049 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
14050 "** Add ACL MAC entry %i in BlackList :"
14051 MAC_ADDRESS_STR, i,
14052 MAC_ADDR_ARRAY(params->mac_addrs[i].addr));
14053
14054 vos_mem_copy(&pConfig->deny_mac[i], params->mac_addrs[i].addr,
14055 sizeof(qcmacaddr));
14056 }
14057 }
14058
14059 if (VOS_STATUS_SUCCESS != WLANSAP_SetMacACL(pVosContext, pConfig))
14060 {
14061 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
14062 "%s: SAP Set Mac Acl fail", __func__);
14063 return -EINVAL;
14064 }
14065 }
14066 else
14067 {
14068 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Sushant Kaushik8bc7df22014-04-09 17:55:29 +053014069 "%s: Invalid device_mode = %s (%d)",
14070 __func__, hdd_device_modetoString(pAdapter->device_mode),
14071 pAdapter->device_mode);
Gopichand Nakkalac005b7c2013-05-14 16:04:14 +053014072 return -EINVAL;
14073 }
14074
14075 return 0;
14076}
14077
Leo Chang9056f462013-08-01 19:21:11 -070014078#ifdef WLAN_NL80211_TESTMODE
14079#ifdef FEATURE_WLAN_LPHB
Leo Changd9df8aa2013-09-26 13:32:26 -070014080void wlan_hdd_cfg80211_lphb_ind_handler
Leo Chang9056f462013-08-01 19:21:11 -070014081(
14082 void *pAdapter,
14083 void *indCont
14084)
14085{
Leo Changd9df8aa2013-09-26 13:32:26 -070014086 tSirLPHBInd *lphbInd;
14087 struct sk_buff *skb;
c_hpothu73f35e62014-04-18 13:40:08 +053014088 hdd_context_t *pHddCtxt;
Leo Chang9056f462013-08-01 19:21:11 -070014089
14090 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Leo Changd9df8aa2013-09-26 13:32:26 -070014091 "LPHB indication arrived");
Leo Chang9056f462013-08-01 19:21:11 -070014092
c_hpothu73f35e62014-04-18 13:40:08 +053014093 if (pAdapter == NULL)
14094 {
14095 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
14096 "%s: pAdapter is NULL\n",__func__);
14097 return;
14098 }
14099
Leo Chang9056f462013-08-01 19:21:11 -070014100 if (NULL == indCont)
14101 {
14102 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Leo Changd9df8aa2013-09-26 13:32:26 -070014103 "LPHB IND, invalid argument");
Leo Chang9056f462013-08-01 19:21:11 -070014104 return;
14105 }
14106
c_hpothu73f35e62014-04-18 13:40:08 +053014107 pHddCtxt = (hdd_context_t *)pAdapter;
Leo Changd9df8aa2013-09-26 13:32:26 -070014108 lphbInd = (tSirLPHBInd *)indCont;
Leo Chang9056f462013-08-01 19:21:11 -070014109 skb = cfg80211_testmode_alloc_event_skb(
c_hpothu73f35e62014-04-18 13:40:08 +053014110 pHddCtxt->wiphy,
Leo Changd9df8aa2013-09-26 13:32:26 -070014111 sizeof(tSirLPHBInd),
Leo Chang9056f462013-08-01 19:21:11 -070014112 GFP_ATOMIC);
14113 if (!skb)
14114 {
14115 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
14116 "LPHB timeout, NL buffer alloc fail");
14117 return;
14118 }
14119
Leo Changac3ba772013-10-07 09:47:04 -070014120 if(nla_put_u32(skb, WLAN_HDD_TM_ATTR_CMD, WLAN_HDD_TM_CMD_WLAN_HB))
Leo Changd9df8aa2013-09-26 13:32:26 -070014121 {
14122 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
14123 "WLAN_HDD_TM_ATTR_CMD put fail");
14124 goto nla_put_failure;
14125 }
Leo Changac3ba772013-10-07 09:47:04 -070014126 if(nla_put_u32(skb, WLAN_HDD_TM_ATTR_TYPE, lphbInd->protocolType))
Leo Changd9df8aa2013-09-26 13:32:26 -070014127 {
14128 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
14129 "WLAN_HDD_TM_ATTR_TYPE put fail");
14130 goto nla_put_failure;
14131 }
Leo Changac3ba772013-10-07 09:47:04 -070014132 if(nla_put(skb, WLAN_HDD_TM_ATTR_DATA,
Leo Changd9df8aa2013-09-26 13:32:26 -070014133 sizeof(tSirLPHBInd), lphbInd))
14134 {
14135 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
14136 "WLAN_HDD_TM_ATTR_DATA put fail");
14137 goto nla_put_failure;
14138 }
Leo Chang9056f462013-08-01 19:21:11 -070014139 cfg80211_testmode_event(skb, GFP_ATOMIC);
14140 return;
14141
14142nla_put_failure:
14143 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
14144 "NLA Put fail");
14145 kfree_skb(skb);
14146
14147 return;
14148}
14149#endif /* FEATURE_WLAN_LPHB */
14150
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053014151static int __wlan_hdd_cfg80211_testmode(struct wiphy *wiphy, void *data, int len)
Leo Chang9056f462013-08-01 19:21:11 -070014152{
14153 struct nlattr *tb[WLAN_HDD_TM_ATTR_MAX + 1];
14154 int err = 0;
14155#ifdef FEATURE_WLAN_LPHB
14156 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
Leo Changd9df8aa2013-09-26 13:32:26 -070014157 eHalStatus smeStatus;
Leo Chang9056f462013-08-01 19:21:11 -070014158#endif /* FEATURE_WLAN_LPHB */
14159
14160 err = nla_parse(tb, WLAN_HDD_TM_ATTR_MAX, data, len, wlan_hdd_tm_policy);
14161 if (err)
14162 {
14163 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
14164 "%s Testmode INV ATTR", __func__);
14165 return err;
14166 }
14167
14168 if (!tb[WLAN_HDD_TM_ATTR_CMD])
14169 {
14170 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
14171 "%s Testmode INV CMD", __func__);
14172 return -EINVAL;
14173 }
14174
14175 switch (nla_get_u32(tb[WLAN_HDD_TM_ATTR_CMD]))
14176 {
14177#ifdef FEATURE_WLAN_LPHB
14178 /* Low Power Heartbeat configuration request */
14179 case WLAN_HDD_TM_CMD_WLAN_HB:
14180 {
14181 int buf_len;
14182 void *buf;
14183 tSirLPHBReq *hb_params = NULL;
Amar Singhal05852702014-02-04 14:40:00 -080014184 tSirLPHBReq *hb_params_temp = NULL;
Leo Chang9056f462013-08-01 19:21:11 -070014185
14186 if (!tb[WLAN_HDD_TM_ATTR_DATA])
14187 {
14188 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
14189 "%s Testmode INV DATA", __func__);
14190 return -EINVAL;
14191 }
14192
14193 buf = nla_data(tb[WLAN_HDD_TM_ATTR_DATA]);
14194 buf_len = nla_len(tb[WLAN_HDD_TM_ATTR_DATA]);
Amar Singhal05852702014-02-04 14:40:00 -080014195
14196 hb_params_temp =(tSirLPHBReq *)buf;
14197 if ((hb_params_temp->cmd == LPHB_SET_TCP_PARAMS_INDID) &&
14198 (hb_params_temp->params.lphbTcpParamReq.timePeriodSec == 0))
14199 return -EINVAL;
14200
Leo Chang9056f462013-08-01 19:21:11 -070014201 hb_params = (tSirLPHBReq *)vos_mem_malloc(sizeof(tSirLPHBReq));
14202 if (NULL == hb_params)
14203 {
14204 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
14205 "%s Request Buffer Alloc Fail", __func__);
14206 return -EINVAL;
14207 }
14208
14209 vos_mem_copy(hb_params, buf, buf_len);
Leo Changd9df8aa2013-09-26 13:32:26 -070014210 smeStatus = sme_LPHBConfigReq((tHalHandle)(pHddCtx->hHal),
14211 hb_params,
14212 wlan_hdd_cfg80211_lphb_ind_handler);
14213 if (eHAL_STATUS_SUCCESS != smeStatus)
Leo Chang9056f462013-08-01 19:21:11 -070014214 {
Leo Changd9df8aa2013-09-26 13:32:26 -070014215 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
14216 "LPHB Config Fail, disable");
Leo Chang9056f462013-08-01 19:21:11 -070014217 vos_mem_free(hb_params);
14218 }
Leo Chang9056f462013-08-01 19:21:11 -070014219 return 0;
14220 }
14221#endif /* FEATURE_WLAN_LPHB */
14222 default:
c_hpothu6ff1c3c2013-10-01 19:01:57 +053014223 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
14224 "%s: unsupported event",__func__);
Leo Chang9056f462013-08-01 19:21:11 -070014225 return -EOPNOTSUPP;
14226 }
14227
14228 return err;
14229}
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053014230
14231static int wlan_hdd_cfg80211_testmode(struct wiphy *wiphy, void *data, int len)
14232{
14233 int ret;
14234
14235 vos_ssr_protect(__func__);
14236 ret = __wlan_hdd_cfg80211_testmode(wiphy, data, len);
14237 vos_ssr_unprotect(__func__);
14238
14239 return ret;
14240}
Leo Chang9056f462013-08-01 19:21:11 -070014241#endif /* CONFIG_NL80211_TESTMODE */
14242
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053014243static int __wlan_hdd_cfg80211_dump_survey(struct wiphy *wiphy,
Madan Mohan Koyyalamudid9383fd2013-08-13 09:27:30 +053014244 struct net_device *dev,
14245 int idx, struct survey_info *survey)
14246{
14247 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
14248 hdd_context_t *pHddCtx;
Mihir Sheted9072e02013-08-21 17:02:29 +053014249 hdd_station_ctx_t *pHddStaCtx;
Madan Mohan Koyyalamudid9383fd2013-08-13 09:27:30 +053014250 tHalHandle halHandle;
Mihir Sheted9072e02013-08-21 17:02:29 +053014251 v_U32_t channel = 0, freq = 0; /* Initialization Required */
Madan Mohan Koyyalamudid9383fd2013-08-13 09:27:30 +053014252 v_S7_t snr,rssi;
14253 int status, i, j, filled = 0;
14254
14255 ENTER();
14256
Madan Mohan Koyyalamudid9383fd2013-08-13 09:27:30 +053014257 if (NULL == pAdapter)
14258 {
14259 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
14260 "%s: HDD adapter is Null", __func__);
14261 return -ENODEV;
14262 }
14263
14264 if (NULL == wiphy)
14265 {
14266 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
14267 "%s: wiphy is Null", __func__);
14268 return -ENODEV;
14269 }
14270
14271 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
14272 status = wlan_hdd_validate_context(pHddCtx);
14273
14274 if (0 != status)
14275 {
14276 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
14277 "%s: HDD context is not valid", __func__);
14278 return status;
14279 }
14280
Mihir Sheted9072e02013-08-21 17:02:29 +053014281 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
14282
Madan Mohan Koyyalamudid9383fd2013-08-13 09:27:30 +053014283 if (0 == pHddCtx->cfg_ini->fEnableSNRMonitoring ||
Mihir Sheted9072e02013-08-21 17:02:29 +053014284 0 != pAdapter->survey_idx ||
14285 eConnectionState_Associated != pHddStaCtx->conn_info.connState)
Madan Mohan Koyyalamudid9383fd2013-08-13 09:27:30 +053014286 {
14287 /* The survey dump ops when implemented completely is expected to
14288 * return a survey of all channels and the ops is called by the
14289 * kernel with incremental values of the argument 'idx' till it
14290 * returns -ENONET. But we can only support the survey for the
14291 * operating channel for now. survey_idx is used to track
14292 * that the ops is called only once and then return -ENONET for
14293 * the next iteration
14294 */
14295 pAdapter->survey_idx = 0;
14296 return -ENONET;
14297 }
14298
14299 halHandle = WLAN_HDD_GET_HAL_CTX(pAdapter);
14300
14301 wlan_hdd_get_snr(pAdapter, &snr);
14302 wlan_hdd_get_rssi(pAdapter, &rssi);
14303
14304 sme_GetOperationChannel(halHandle, &channel, pAdapter->sessionId);
14305 hdd_wlan_get_freq(channel, &freq);
14306
14307
14308 for (i = 0; i < IEEE80211_NUM_BANDS; i++)
14309 {
14310 if (NULL == wiphy->bands[i])
14311 {
14312 VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_INFO,
14313 "%s: wiphy->bands[i] is NULL, i = %d", __func__, i);
14314 continue;
14315 }
14316
14317 for (j = 0; j < wiphy->bands[i]->n_channels; j++)
14318 {
14319 struct ieee80211_supported_band *band = wiphy->bands[i];
14320
14321 if (band->channels[j].center_freq == (v_U16_t)freq)
14322 {
14323 survey->channel = &band->channels[j];
14324 /* The Rx BDs contain SNR values in dB for the received frames
14325 * while the supplicant expects noise. So we calculate and
14326 * return the value of noise (dBm)
14327 * SNR (dB) = RSSI (dBm) - NOISE (dBm)
14328 */
14329 survey->noise = rssi - snr;
14330 survey->filled = SURVEY_INFO_NOISE_DBM;
14331 filled = 1;
14332 }
14333 }
14334 }
14335
14336 if (filled)
14337 pAdapter->survey_idx = 1;
14338 else
14339 {
14340 pAdapter->survey_idx = 0;
14341 return -ENONET;
14342 }
14343
14344 return 0;
14345}
14346
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053014347static int wlan_hdd_cfg80211_dump_survey(struct wiphy *wiphy,
14348 struct net_device *dev,
14349 int idx, struct survey_info *survey)
14350{
14351 int ret;
14352
14353 vos_ssr_protect(__func__);
14354 ret = __wlan_hdd_cfg80211_dump_survey(wiphy, dev, idx, survey);
14355 vos_ssr_unprotect(__func__);
14356
14357 return ret;
14358}
14359
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053014360/*
Mahesh A Saptasagarbcc5b662014-06-02 21:46:23 +053014361 * FUNCTION: __wlan_hdd_cfg80211_resume_wlan
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053014362 * this is called when cfg80211 driver resume
14363 * driver updates latest sched_scan scan result(if any) to cfg80211 database
14364 */
Mahesh A Saptasagarbcc5b662014-06-02 21:46:23 +053014365int __wlan_hdd_cfg80211_resume_wlan(struct wiphy *wiphy)
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053014366{
14367 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
14368 hdd_adapter_t *pAdapter;
14369 hdd_adapter_list_node_t *pAdapterNode, *pNext;
14370 VOS_STATUS status = VOS_STATUS_SUCCESS;
14371
14372 ENTER();
14373
14374 if ( NULL == pHddCtx )
14375 {
14376 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
14377 "%s: HddCtx validation failed", __func__);
14378 return 0;
14379 }
14380
14381 if (pHddCtx->isLogpInProgress)
14382 {
14383 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
14384 "%s: LOGP in Progress. Ignore!!!", __func__);
14385 return 0;
14386 }
14387
Mihir Shete18156292014-03-11 15:38:30 +053014388 if (WLAN_HDD_IS_LOAD_UNLOAD_IN_PROGRESS(pHddCtx))
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053014389 {
14390 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
14391 "%s: Unloading/Loading in Progress. Ignore!!!", __func__);
14392 return 0;
14393 }
14394
14395 spin_lock(&pHddCtx->schedScan_lock);
14396 pHddCtx->isWiphySuspended = FALSE;
14397 if (TRUE != pHddCtx->isSchedScanUpdatePending)
14398 {
14399 spin_unlock(&pHddCtx->schedScan_lock);
14400 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
14401 "%s: Return resume is not due to PNO indication", __func__);
14402 return 0;
14403 }
14404 // Reset flag to avoid updatating cfg80211 data old results again
14405 pHddCtx->isSchedScanUpdatePending = FALSE;
14406 spin_unlock(&pHddCtx->schedScan_lock);
14407
Mahesh A Saptasagarb9c50402014-01-16 15:49:22 +053014408
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053014409 status = hdd_get_front_adapter ( pHddCtx, &pAdapterNode );
14410
14411 while ( NULL != pAdapterNode && VOS_STATUS_SUCCESS == status )
14412 {
14413 pAdapter = pAdapterNode->pAdapter;
14414 if ( (NULL != pAdapter) &&
14415 (WLAN_HDD_INFRA_STATION == pAdapter->device_mode) )
14416 {
14417 if (0 != wlan_hdd_cfg80211_update_bss(pHddCtx->wiphy, pAdapter))
Mahesh A Saptasagarb9c50402014-01-16 15:49:22 +053014418 {
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053014419 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_WARN,
14420 "%s: NO SCAN result", __func__);
Mahesh A Saptasagarb9c50402014-01-16 15:49:22 +053014421 }
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053014422 else
Mahesh A Saptasagarb9c50402014-01-16 15:49:22 +053014423 {
14424 /* Acquire wakelock to handle the case where APP's tries to
14425 * suspend immediately after updating the scan results. Whis
14426 * results in app's is in suspended state and not able to
14427 * process the connect request to AP
14428 */
14429 hdd_prevent_suspend_timeout(2000);
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053014430 cfg80211_sched_scan_results(pHddCtx->wiphy);
Mahesh A Saptasagarb9c50402014-01-16 15:49:22 +053014431 }
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053014432
14433 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
14434 "%s : cfg80211 scan result database updated", __func__);
14435
14436 return 0;
14437
14438 }
14439 status = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
14440 pAdapterNode = pNext;
14441 }
14442
14443 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
14444 "%s: Failed to find Adapter", __func__);
14445 return 0;
14446}
14447
Mahesh A Saptasagarbcc5b662014-06-02 21:46:23 +053014448int wlan_hdd_cfg80211_resume_wlan(struct wiphy *wiphy)
14449{
14450 int ret;
14451
14452 vos_ssr_protect(__func__);
14453 ret = __wlan_hdd_cfg80211_resume_wlan(wiphy);
14454 vos_ssr_unprotect(__func__);
14455
14456 return ret;
14457}
14458
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053014459/*
Mahesh A Saptasagarbcc5b662014-06-02 21:46:23 +053014460 * FUNCTION: __wlan_hdd_cfg80211_suspend_wlan
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053014461 * this is called when cfg80211 driver suspends
14462 */
Mahesh A Saptasagarbcc5b662014-06-02 21:46:23 +053014463int __wlan_hdd_cfg80211_suspend_wlan(struct wiphy *wiphy,
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053014464 struct cfg80211_wowlan *wow)
14465{
14466 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
14467
14468 ENTER();
14469 if (NULL == pHddCtx)
14470 {
14471 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
14472 "%s: HddCtx validation failed", __func__);
14473 return 0;
14474 }
14475
14476 pHddCtx->isWiphySuspended = TRUE;
14477
14478 EXIT();
14479
14480 return 0;
14481}
14482
Mahesh A Saptasagarbcc5b662014-06-02 21:46:23 +053014483int wlan_hdd_cfg80211_suspend_wlan(struct wiphy *wiphy,
14484 struct cfg80211_wowlan *wow)
14485{
14486 int ret;
14487
14488 vos_ssr_protect(__func__);
14489 ret = __wlan_hdd_cfg80211_suspend_wlan(wiphy, wow);
14490 vos_ssr_unprotect(__func__);
14491
14492 return ret;
14493}
Jeff Johnson295189b2012-06-20 16:38:30 -070014494/* cfg80211_ops */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014495static struct cfg80211_ops wlan_hdd_cfg80211_ops =
Jeff Johnson295189b2012-06-20 16:38:30 -070014496{
14497 .add_virtual_intf = wlan_hdd_add_virtual_intf,
14498 .del_virtual_intf = wlan_hdd_del_virtual_intf,
14499 .change_virtual_intf = wlan_hdd_cfg80211_change_iface,
14500 .change_station = wlan_hdd_change_station,
14501#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,4,0))
14502 .add_beacon = wlan_hdd_cfg80211_add_beacon,
14503 .del_beacon = wlan_hdd_cfg80211_del_beacon,
14504 .set_beacon = wlan_hdd_cfg80211_set_beacon,
Jeff Johnson04dd8a82012-06-29 20:41:40 -070014505#else
14506 .start_ap = wlan_hdd_cfg80211_start_ap,
14507 .change_beacon = wlan_hdd_cfg80211_change_beacon,
14508 .stop_ap = wlan_hdd_cfg80211_stop_ap,
Jeff Johnson295189b2012-06-20 16:38:30 -070014509#endif
14510 .change_bss = wlan_hdd_cfg80211_change_bss,
14511 .add_key = wlan_hdd_cfg80211_add_key,
14512 .get_key = wlan_hdd_cfg80211_get_key,
14513 .del_key = wlan_hdd_cfg80211_del_key,
14514 .set_default_key = wlan_hdd_cfg80211_set_default_key,
Jeff Johnson3bbe4bf2013-01-18 17:05:29 -080014515#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,6,0))
Jeff Johnson295189b2012-06-20 16:38:30 -070014516 .set_channel = wlan_hdd_cfg80211_set_channel,
Jeff Johnson3bbe4bf2013-01-18 17:05:29 -080014517#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070014518 .scan = wlan_hdd_cfg80211_scan,
14519 .connect = wlan_hdd_cfg80211_connect,
14520 .disconnect = wlan_hdd_cfg80211_disconnect,
14521 .join_ibss = wlan_hdd_cfg80211_join_ibss,
14522 .leave_ibss = wlan_hdd_cfg80211_leave_ibss,
14523 .set_wiphy_params = wlan_hdd_cfg80211_set_wiphy_params,
14524 .set_tx_power = wlan_hdd_cfg80211_set_txpower,
14525 .get_tx_power = wlan_hdd_cfg80211_get_txpower,
Jeff Johnson295189b2012-06-20 16:38:30 -070014526 .remain_on_channel = wlan_hdd_cfg80211_remain_on_channel,
14527 .cancel_remain_on_channel = wlan_hdd_cfg80211_cancel_remain_on_channel,
DARAM SUDHA39eede62014-02-12 11:16:40 +053014528 .mgmt_tx = wlan_hdd_mgmt_tx,
Jeff Johnson295189b2012-06-20 16:38:30 -070014529#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
14530 .mgmt_tx_cancel_wait = wlan_hdd_cfg80211_mgmt_tx_cancel_wait,
14531 .set_default_mgmt_key = wlan_hdd_set_default_mgmt_key,
14532 .set_txq_params = wlan_hdd_set_txq_params,
14533#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070014534 .get_station = wlan_hdd_cfg80211_get_station,
14535 .set_power_mgmt = wlan_hdd_cfg80211_set_power_mgmt,
14536 .del_station = wlan_hdd_cfg80211_del_station,
Jeff Johnson04dd8a82012-06-29 20:41:40 -070014537 .add_station = wlan_hdd_cfg80211_add_station,
14538#ifdef FEATURE_WLAN_LFR
14539 .set_pmksa = wlan_hdd_cfg80211_set_pmksa,
14540 .del_pmksa = wlan_hdd_cfg80211_del_pmksa,
14541 .flush_pmksa = wlan_hdd_cfg80211_flush_pmksa,
14542#endif
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070014543#if defined(WLAN_FEATURE_VOWIFI_11R) && defined(KERNEL_SUPPORT_11R_CFG80211)
14544 .update_ft_ies = wlan_hdd_cfg80211_update_ft_ies,
14545#endif
Mohit Khanna698ba2a2012-12-04 15:08:18 -080014546#ifdef FEATURE_WLAN_TDLS
14547 .tdls_mgmt = wlan_hdd_cfg80211_tdls_mgmt,
14548 .tdls_oper = wlan_hdd_cfg80211_tdls_oper,
14549#endif
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053014550#ifdef WLAN_FEATURE_GTK_OFFLOAD
14551 .set_rekey_data = wlan_hdd_cfg80211_set_rekey_data,
14552#endif /* WLAN_FEATURE_GTK_OFFLOAD */
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053014553#ifdef FEATURE_WLAN_SCAN_PNO
14554 .sched_scan_start = wlan_hdd_cfg80211_sched_scan_start,
14555 .sched_scan_stop = wlan_hdd_cfg80211_sched_scan_stop,
14556#endif /*FEATURE_WLAN_SCAN_PNO */
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053014557 .resume = wlan_hdd_cfg80211_resume_wlan,
14558 .suspend = wlan_hdd_cfg80211_suspend_wlan,
Gopichand Nakkalac005b7c2013-05-14 16:04:14 +053014559 .set_mac_acl = wlan_hdd_cfg80211_set_mac_acl,
Leo Chang9056f462013-08-01 19:21:11 -070014560#ifdef WLAN_NL80211_TESTMODE
14561 .testmode_cmd = wlan_hdd_cfg80211_testmode,
14562#endif
Madan Mohan Koyyalamudid9383fd2013-08-13 09:27:30 +053014563 .dump_survey = wlan_hdd_cfg80211_dump_survey,
Jeff Johnson295189b2012-06-20 16:38:30 -070014564};
14565