blob: f14b1f8b3d2f0dbbd6bc5783a45bed58132aa43c [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{
791 if (nla_put_u32(vendor_event,
792 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
826static v_BOOL_t put_wifi_iface_stats(tpSirWifiIfaceStat pWifiIfaceStat,
827 struct sk_buff *vendor_event)
828{
829 int i = 0;
830 struct nlattr *wmmInfo;
831 if (FALSE == put_wifi_interface_info(
832 &pWifiIfaceStat->info,
833 vendor_event))
834 {
835 hddLog(VOS_TRACE_LEVEL_ERROR,
836 FL("QCA_WLAN_VENDOR_ATTR put fail") );
837 return FALSE;
838
839 }
840
841 if (nla_put_u32(vendor_event,
842 QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_BEACON_RX,
843 pWifiIfaceStat->beaconRx) ||
844 nla_put_u32(vendor_event,
845 QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_MGMT_RX,
846 pWifiIfaceStat->mgmtRx) ||
847 nla_put_u32(vendor_event,
848 QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_MGMT_ACTION_RX,
849 pWifiIfaceStat->mgmtActionRx) ||
850 nla_put_u32(vendor_event,
851 QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_MGMT_ACTION_TX,
852 pWifiIfaceStat->mgmtActionTx) ||
853 nla_put_u32(vendor_event,
854 QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_RSSI_MGMT,
855 pWifiIfaceStat->rssiMgmt) ||
856 nla_put_u32(vendor_event,
857 QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_RSSI_DATA,
858 pWifiIfaceStat->rssiData) ||
859 nla_put_u32(vendor_event,
860 QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_RSSI_ACK,
861 pWifiIfaceStat->rssiAck))
862 {
863 hddLog(VOS_TRACE_LEVEL_ERROR,
864 FL("QCA_WLAN_VENDOR_ATTR put fail"));
865 return FALSE;
866 }
867
868 wmmInfo = nla_nest_start(vendor_event,
869 QCA_WLAN_VENDOR_ATTR_LL_STATS_WMM_INFO);
870 for (i = 0; i < WIFI_AC_MAX; i++)
871 {
872 struct nlattr *wmmStats;
873 wmmStats = nla_nest_start(vendor_event, i);
874 if (FALSE == put_wifi_wmm_ac_stat(
875 &pWifiIfaceStat->AccessclassStats[i],
876 vendor_event))
877 {
878 hddLog(VOS_TRACE_LEVEL_ERROR,
879 FL("QCA_WLAN_VENDOR_ATTR put Fail"));
880 return FALSE;
881 }
882
883 nla_nest_end(vendor_event, wmmStats);
884 }
885 nla_nest_end(vendor_event, wmmInfo);
886 return TRUE;
887}
888
889static tSirWifiInterfaceMode
890 hdd_map_device_to_ll_iface_mode ( int deviceMode )
891{
892 switch (deviceMode)
893 {
894 case WLAN_HDD_INFRA_STATION:
895 return WIFI_INTERFACE_STA;
896 case WLAN_HDD_SOFTAP:
897 return WIFI_INTERFACE_SOFTAP;
898 case WLAN_HDD_P2P_CLIENT:
899 return WIFI_INTERFACE_P2P_CLIENT;
900 case WLAN_HDD_P2P_GO:
901 return WIFI_INTERFACE_P2P_GO;
902 case WLAN_HDD_IBSS:
903 return WIFI_INTERFACE_IBSS;
904 default:
905 /* Return Interface Mode as STA for all the unsupported modes */
906 return WIFI_INTERFACE_STA;
907 }
908}
909
910static v_BOOL_t hdd_get_interface_info(hdd_adapter_t *pAdapter,
911 tpSirWifiInterfaceInfo pInfo)
912{
913 v_U8_t *staMac = NULL;
914 hdd_station_ctx_t *pHddStaCtx;
915 tHalHandle hHal = WLAN_HDD_GET_HAL_CTX(pAdapter);
916 tpAniSirGlobal pMac = PMAC_STRUCT( hHal );
917
918 pInfo->mode = hdd_map_device_to_ll_iface_mode(pAdapter->device_mode);
919
920 vos_mem_copy(pInfo->macAddr,
921 pAdapter->macAddressCurrent.bytes, sizeof(v_MACADDR_t));
922
923 if (((WLAN_HDD_INFRA_STATION == pAdapter->device_mode) ||
924 (WLAN_HDD_P2P_CLIENT == pAdapter->device_mode) ||
925 (WLAN_HDD_P2P_DEVICE == pAdapter->device_mode)))
926 {
927 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
928 if (eConnectionState_NotConnected == pHddStaCtx->conn_info.connState)
929 {
930 pInfo->state = WIFI_DISCONNECTED;
931 }
932 if (eConnectionState_Connecting == pHddStaCtx->conn_info.connState)
933 {
934 hddLog(VOS_TRACE_LEVEL_ERROR,
935 "%s: Session ID %d, Connection is in progress", __func__,
936 pAdapter->sessionId);
937 pInfo->state = WIFI_ASSOCIATING;
938 }
939 if ((eConnectionState_Associated == pHddStaCtx->conn_info.connState) &&
940 (VOS_FALSE == pHddStaCtx->conn_info.uIsAuthenticated))
941 {
942 staMac = (v_U8_t *) &(pAdapter->macAddressCurrent.bytes[0]);
943 hddLog(VOS_TRACE_LEVEL_ERROR,
944 "%s: client " MAC_ADDRESS_STR
945 " is in the middle of WPS/EAPOL exchange.", __func__,
946 MAC_ADDR_ARRAY(staMac));
947 pInfo->state = WIFI_AUTHENTICATING;
948 }
949 if (eConnectionState_Associated == pHddStaCtx->conn_info.connState)
950 {
951 pInfo->state = WIFI_ASSOCIATED;
952 vos_mem_copy(pInfo->bssid,
953 &pHddStaCtx->conn_info.bssId, WNI_CFG_BSSID_LEN);
954 vos_mem_copy(pInfo->ssid,
955 pHddStaCtx->conn_info.SSID.SSID.ssId,
956 pHddStaCtx->conn_info.SSID.SSID.length);
957 //NULL Terminate the string.
958 pInfo->ssid[pHddStaCtx->conn_info.SSID.SSID.length] = 0;
959 }
960 }
961 vos_mem_copy(pInfo->countryStr,
962 pMac->scan.countryCodeCurrent, WNI_CFG_COUNTRY_CODE_LEN);
963
964 vos_mem_copy(pInfo->apCountryStr,
965 pMac->scan.countryCodeCurrent, WNI_CFG_COUNTRY_CODE_LEN);
966
967 return TRUE;
968}
969
970/*
971 * hdd_link_layer_process_peer_stats () - This function is called after
972 * receiving Link Layer Peer statistics from FW.This function converts
973 * the firmware data to the NL data and sends the same to the kernel/upper
974 * layers.
975 */
976static v_VOID_t hdd_link_layer_process_peer_stats(hdd_adapter_t *pAdapter,
977 v_VOID_t *pData)
978{
979 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
980 tpSirWifiRateStat pWifiRateStat;
981 tpSirWifiPeerStat pWifiPeerStat;
982 tpSirWifiPeerInfo pWifiPeerInfo;
983 struct nlattr *peerInfo;
984 struct sk_buff *vendor_event;
985 int status, i;
986
987 status = wlan_hdd_validate_context(pHddCtx);
988 if (0 != status)
989 {
990 hddLog(VOS_TRACE_LEVEL_ERROR,
991 FL("HDD context is not valid") );
992 return;
993 }
994
995 pWifiPeerStat = (tpSirWifiPeerStat) pData;
996
997 hddLog(VOS_TRACE_LEVEL_INFO,
998 "LL_STATS_PEER_ALL : numPeers %u",
999 pWifiPeerStat->numPeers);
1000 {
1001 for (i = 0; i < pWifiPeerStat->numPeers; i++)
1002 {
1003 pWifiPeerInfo = (tpSirWifiPeerInfo)
1004 ((uint8 *)pWifiPeerStat->peerInfo +
1005 ( i * sizeof(tSirWifiPeerInfo)));
1006
1007 hddLog(VOS_TRACE_LEVEL_INFO,
1008 " %d) LL_STATS Channel Stats "
1009 " Peer Type %u "
1010 " peerMacAddress %pM "
1011 " capabilities 0x%x "
1012 " numRate %u ",
1013 i,
1014 pWifiPeerInfo->type,
1015 pWifiPeerInfo->peerMacAddress,
1016 pWifiPeerInfo->capabilities,
1017 pWifiPeerInfo->numRate);
1018 {
1019 int j;
1020 for (j = 0; j < pWifiPeerInfo->numRate; j++)
1021 {
1022 pWifiRateStat = (tpSirWifiRateStat)
1023 ((tANI_U8 *) pWifiPeerInfo->rateStats +
1024 ( j * sizeof(tSirWifiRateStat)));
1025
1026 hddLog(VOS_TRACE_LEVEL_INFO,
1027 " peer Rate Stats "
1028 " preamble %u "
1029 " nss %u "
1030 " bw %u "
1031 " rateMcsIdx %u "
1032 " reserved %u "
1033 " bitrate %u "
1034 " txMpdu %u "
1035 " rxMpdu %u "
1036 " mpduLost %u "
1037 " retries %u "
1038 " retriesShort %u "
1039 " retriesLong %u",
1040 pWifiRateStat->rate.preamble,
1041 pWifiRateStat->rate.nss,
1042 pWifiRateStat->rate.bw,
1043 pWifiRateStat->rate.rateMcsIdx,
1044 pWifiRateStat->rate.reserved,
1045 pWifiRateStat->rate.bitrate,
1046 pWifiRateStat->txMpdu,
1047 pWifiRateStat->rxMpdu,
1048 pWifiRateStat->mpduLost,
1049 pWifiRateStat->retries,
1050 pWifiRateStat->retriesShort,
1051 pWifiRateStat->retriesLong);
1052 }
1053 }
1054 }
1055 }
1056
1057 /*
1058 * Allocate a size of 4096 for the peer stats comprising
1059 * each of size = sizeof (tSirWifiPeerInfo) + numRate *
1060 * sizeof (tSirWifiRateStat).Each field is put with an
1061 * NL attribute.The size of 4096 is considered assuming
1062 * that number of rates shall not exceed beyond 50 with
1063 * the sizeof (tSirWifiRateStat) being 32.
1064 */
1065 vendor_event = cfg80211_vendor_event_alloc(pHddCtx->wiphy,
1066 LL_STATS_EVENT_BUF_SIZE + NLMSG_HDRLEN,
1067 QCA_NL80211_VENDOR_SUBCMD_LL_PEER_INFO_STATS_INDEX,
1068 GFP_KERNEL);
1069 if (!vendor_event)
1070 {
1071 hddLog(VOS_TRACE_LEVEL_ERROR,
1072 "%s: cfg80211_vendor_event_alloc failed",
1073 __func__);
1074 return;
1075 }
1076 if (nla_put_u32(vendor_event,
1077 QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_NUM_PEERS,
1078 pWifiPeerStat->numPeers))
1079 {
1080 hddLog(VOS_TRACE_LEVEL_ERROR,
1081 "%s: QCA_WLAN_VENDOR_ATTR put fail", __func__);
1082 kfree_skb(vendor_event);
1083 return;
1084 }
1085
1086 peerInfo = nla_nest_start(vendor_event,
1087 QCA_WLAN_VENDOR_ATTR_LL_STATS_PEER_INFO);
1088
1089 pWifiPeerInfo = (tpSirWifiPeerInfo) ((uint8 *)
1090 pWifiPeerStat->peerInfo);
1091
1092 for (i = 1; i <= pWifiPeerStat->numPeers; i++)
1093 {
1094 struct nlattr *peers = nla_nest_start(vendor_event, i);
1095 int numRate = pWifiPeerInfo->numRate;
1096
1097 if (FALSE == put_wifi_peer_info(
1098 pWifiPeerInfo, vendor_event))
1099 {
1100 hddLog(VOS_TRACE_LEVEL_ERROR,
1101 "%s: put_wifi_peer_info put fail", __func__);
1102 kfree_skb(vendor_event);
1103 return;
1104 }
1105
1106 pWifiPeerInfo = (tpSirWifiPeerInfo) ((uint8 *)
1107 pWifiPeerStat->peerInfo +
1108 (i * sizeof(tSirWifiPeerInfo)) +
1109 (numRate * sizeof (tSirWifiRateStat)));
1110 nla_nest_end(vendor_event, peers);
1111 }
1112 nla_nest_end(vendor_event, peerInfo);
1113 cfg80211_vendor_event(vendor_event, GFP_KERNEL);
1114}
1115
1116/*
1117 * hdd_link_layer_process_iface_stats () - This function is called after
1118 * receiving Link Layer Interface statistics from FW.This function converts
1119 * the firmware data to the NL data and sends the same to the kernel/upper
1120 * layers.
1121 */
1122static v_VOID_t hdd_link_layer_process_iface_stats(hdd_adapter_t *pAdapter,
1123 v_VOID_t *pData)
1124{
1125 tpSirWifiIfaceStat pWifiIfaceStat;
1126 struct sk_buff *vendor_event;
1127 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
1128 int status;
1129
1130 status = wlan_hdd_validate_context(pHddCtx);
1131 if (0 != status)
1132 {
1133 hddLog(VOS_TRACE_LEVEL_ERROR,
1134 FL("HDD context is not valid") );
1135 return;
1136 }
1137 /*
1138 * Allocate a size of 4096 for the interface stats comprising
1139 * sizeof (tpSirWifiIfaceStat).The size of 4096 is considered
1140 * assuming that all these fit with in the limit.Please take
1141 * a call on the limit based on the data requirements on
1142 * interface statistics.
1143 */
1144 vendor_event = cfg80211_vendor_event_alloc(pHddCtx->wiphy,
1145 LL_STATS_EVENT_BUF_SIZE + NLMSG_HDRLEN,
1146 QCA_NL80211_VENDOR_SUBCMD_LL_IFACE_STATS_INDEX,
1147 GFP_KERNEL);
1148 if (!vendor_event)
1149 {
1150 hddLog(VOS_TRACE_LEVEL_ERROR,
1151 FL("cfg80211_vendor_event_alloc failed") );
1152 return;
1153 }
1154
1155 pWifiIfaceStat = (tpSirWifiIfaceStat) pData;
1156
1157 hddLog(VOS_TRACE_LEVEL_INFO,
1158 "WMI_LINK_STATS_IFACE Data");
1159
1160 hddLog(VOS_TRACE_LEVEL_INFO,
1161 "LL_STATS_IFACE: "
1162 " Mode %u "
1163 " MAC %pM "
1164 " State %u "
1165 " Roaming %u "
1166 " capabilities 0x%x "
1167 " SSID %s "
1168 " BSSID %pM",
1169 pWifiIfaceStat->info.mode,
1170 pWifiIfaceStat->info.macAddr,
1171 pWifiIfaceStat->info.state,
1172 pWifiIfaceStat->info.roaming,
1173 pWifiIfaceStat->info.capabilities,
1174 pWifiIfaceStat->info.ssid,
1175 pWifiIfaceStat->info.bssid);
1176
1177 hddLog(VOS_TRACE_LEVEL_INFO,
1178 " AP country str: %c%c%c",
1179 pWifiIfaceStat->info.apCountryStr[0],
1180 pWifiIfaceStat->info.apCountryStr[1],
1181 pWifiIfaceStat->info.apCountryStr[2]);
1182
1183
1184 hddLog(VOS_TRACE_LEVEL_INFO,
1185 " Country Str Association: %c%c%c",
1186 pWifiIfaceStat->info.countryStr[0],
1187 pWifiIfaceStat->info.countryStr[1],
1188 pWifiIfaceStat->info.countryStr[2]);
1189
1190 hddLog(VOS_TRACE_LEVEL_INFO,
1191 " beaconRx %u "
1192 " mgmtRx %u "
1193 " mgmtActionRx %u "
1194 " mgmtActionTx %u "
1195 " rssiMgmt %u "
1196 " rssiData %u "
1197 " rssiAck %u",
1198 pWifiIfaceStat->beaconRx,
1199 pWifiIfaceStat->mgmtRx,
1200 pWifiIfaceStat->mgmtActionRx,
1201 pWifiIfaceStat->mgmtActionTx,
1202 pWifiIfaceStat->rssiMgmt,
1203 pWifiIfaceStat->rssiData,
1204 pWifiIfaceStat->rssiAck );
1205
1206
1207 {
1208 int i;
1209 for (i = 0 ; i < WIFI_AC_MAX; i ++)
1210 {
1211 hddLog(VOS_TRACE_LEVEL_INFO,
1212
1213 " %d) LL_STATS IFACE: "
1214 " ac: %u txMpdu: %u "
1215 " rxMpdu: %u txMcast: %u "
1216 " rxMcast: %u rxAmpdu: %u "
1217 " txAmpdu: %u mpduLost: %u "
1218 " retries: %u retriesShort: %u "
1219 " retriesLong: %u contentionTimeMin: %u "
1220 " contentionTimeMax: %u contentionTimeAvg: %u "
1221 " contentionNumSamples: %u",
1222 i,
1223 pWifiIfaceStat->AccessclassStats[i].ac,
1224 pWifiIfaceStat->AccessclassStats[i].txMpdu,
1225 pWifiIfaceStat->AccessclassStats[i].rxMpdu,
1226 pWifiIfaceStat->AccessclassStats[i].txMcast,
1227 pWifiIfaceStat->AccessclassStats[i].rxMcast,
1228 pWifiIfaceStat->AccessclassStats[i].rxAmpdu,
1229 pWifiIfaceStat->AccessclassStats[i].txAmpdu,
1230 pWifiIfaceStat->AccessclassStats[i].mpduLost,
1231 pWifiIfaceStat->AccessclassStats[i].retries,
1232 pWifiIfaceStat->
1233 AccessclassStats[i].retriesShort,
1234 pWifiIfaceStat->AccessclassStats[i].retriesLong,
1235 pWifiIfaceStat->
1236 AccessclassStats[i].contentionTimeMin,
1237 pWifiIfaceStat->
1238 AccessclassStats[i].contentionTimeMax,
1239 pWifiIfaceStat->
1240 AccessclassStats[i].contentionTimeAvg,
1241 pWifiIfaceStat->
1242 AccessclassStats[i].contentionNumSamples);
1243
1244 }
1245 }
1246
1247 if (FALSE == hdd_get_interface_info( pAdapter,
1248 &pWifiIfaceStat->info))
1249 {
1250 hddLog(VOS_TRACE_LEVEL_ERROR,
1251 FL("hdd_get_interface_info get fail") );
1252 kfree_skb(vendor_event);
1253 return;
1254 }
1255
1256 if (FALSE == put_wifi_iface_stats( pWifiIfaceStat,
1257 vendor_event))
1258 {
1259 hddLog(VOS_TRACE_LEVEL_ERROR,
1260 FL("put_wifi_iface_stats fail") );
1261 kfree_skb(vendor_event);
1262 return;
1263 }
1264 cfg80211_vendor_event(vendor_event, GFP_KERNEL);
1265}
1266
1267/*
1268 * hdd_link_layer_process_radio_stats () - This function is called after
1269 * receiving Link Layer Radio statistics from FW.This function converts
1270 * the firmware data to the NL data and sends the same to the kernel/upper
1271 * layers.
1272 */
1273static v_VOID_t hdd_link_layer_process_radio_stats(hdd_adapter_t *pAdapter,
1274 v_VOID_t *pData)
1275{
1276 int status, i;
1277 tpSirWifiRadioStat pWifiRadioStat;
1278 tpSirWifiChannelStats pWifiChannelStats;
1279 struct sk_buff *vendor_event;
1280 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
1281 struct nlattr *chList;
1282
1283 status = wlan_hdd_validate_context(pHddCtx);
1284 if (0 != status)
1285 {
1286 hddLog(VOS_TRACE_LEVEL_ERROR,
1287 FL("HDD context is not valid") );
1288 return;
1289 }
1290 pWifiRadioStat = (tpSirWifiRadioStat) pData;
1291
1292 hddLog(VOS_TRACE_LEVEL_INFO,
1293 "LL_STATS_RADIO"
1294 " radio is %d onTime is %u "
1295 " txTime is %u rxTime is %u "
1296 " onTimeScan is %u onTimeNbd is %u "
Dino Mycle6fb96c12014-06-10 11:52:40 +05301297 " onTimeEXTScan is %u onTimeRoamScan is %u "
Sunil Duttc69bccb2014-05-26 21:30:20 +05301298 " onTimePnoScan is %u onTimeHs20 is %u "
1299 " numChannels is %u",
1300 pWifiRadioStat->radio, pWifiRadioStat->onTime,
1301 pWifiRadioStat->txTime, pWifiRadioStat->rxTime,
1302 pWifiRadioStat->onTimeScan, pWifiRadioStat->onTimeNbd,
Dino Mycle6fb96c12014-06-10 11:52:40 +05301303 pWifiRadioStat->onTimeEXTScan,
Sunil Duttc69bccb2014-05-26 21:30:20 +05301304 pWifiRadioStat->onTimeRoamScan,
1305 pWifiRadioStat->onTimePnoScan,
1306 pWifiRadioStat->onTimeHs20,
1307 pWifiRadioStat->numChannels);
1308 /*
1309 * Allocate a size of 4096 for the Radio stats comprising
1310 * sizeof (tSirWifiRadioStat) + numChannels * sizeof
1311 * (tSirWifiChannelStats).Each channel data is put with an
1312 * NL attribute.The size of 4096 is considered assuming that
1313 * number of channels shall not exceed beyond 60 with the
1314 * sizeof (tSirWifiChannelStats) being 24 bytes.
1315 */
1316
1317 vendor_event = cfg80211_vendor_event_alloc(pHddCtx->wiphy,
1318 LL_STATS_EVENT_BUF_SIZE + NLMSG_HDRLEN ,
1319 QCA_NL80211_VENDOR_SUBCMD_LL_RADIO_STATS_INDEX,
1320 GFP_KERNEL);
1321
1322 if (!vendor_event)
1323 {
1324 hddLog(VOS_TRACE_LEVEL_ERROR,
1325 FL("cfg80211_vendor_event_alloc failed") );
1326 return;
1327 }
1328
1329 if (nla_put_u32(vendor_event,
1330 QCA_WLAN_VENDOR_ATTR_LL_STATS_RADIO_ID,
1331 pWifiRadioStat->radio) ||
1332 nla_put_u32(vendor_event,
1333 QCA_WLAN_VENDOR_ATTR_LL_STATS_RADIO_ON_TIME,
1334 pWifiRadioStat->onTime) ||
1335 nla_put_u32(vendor_event,
1336 QCA_WLAN_VENDOR_ATTR_LL_STATS_RADIO_TX_TIME,
1337 pWifiRadioStat->txTime) ||
1338 nla_put_u32(vendor_event,
1339 QCA_WLAN_VENDOR_ATTR_LL_STATS_RADIO_RX_TIME,
1340 pWifiRadioStat->rxTime) ||
1341 nla_put_u32(vendor_event,
1342 QCA_WLAN_VENDOR_ATTR_LL_STATS_RADIO_ON_TIME_SCAN,
1343 pWifiRadioStat->onTimeScan) ||
1344 nla_put_u32(vendor_event,
1345 QCA_WLAN_VENDOR_ATTR_LL_STATS_RADIO_ON_TIME_NBD,
1346 pWifiRadioStat->onTimeNbd) ||
1347 nla_put_u32(vendor_event,
Dino Mycle6fb96c12014-06-10 11:52:40 +05301348 QCA_WLAN_VENDOR_ATTR_LL_STATS_RADIO_ON_TIME_EXTSCAN,
1349 pWifiRadioStat->onTimeEXTScan)||
Sunil Duttc69bccb2014-05-26 21:30:20 +05301350 nla_put_u32(vendor_event,
1351 QCA_WLAN_VENDOR_ATTR_LL_STATS_RADIO_ON_TIME_ROAM_SCAN,
1352 pWifiRadioStat->onTimeRoamScan) ||
1353 nla_put_u32(vendor_event,
1354 QCA_WLAN_VENDOR_ATTR_LL_STATS_RADIO_ON_TIME_PNO_SCAN,
1355 pWifiRadioStat->onTimePnoScan) ||
1356 nla_put_u32(vendor_event,
1357 QCA_WLAN_VENDOR_ATTR_LL_STATS_RADIO_ON_TIME_HS20,
1358 pWifiRadioStat->onTimeHs20) ||
1359 nla_put_u32(vendor_event,
1360 QCA_WLAN_VENDOR_ATTR_LL_STATS_RADIO_NUM_CHANNELS,
1361 pWifiRadioStat->numChannels))
1362 {
1363 hddLog(VOS_TRACE_LEVEL_ERROR,
1364 FL("QCA_WLAN_VENDOR_ATTR put fail"));
1365 kfree_skb(vendor_event);
1366 return ;
1367 }
1368
1369 chList = nla_nest_start(vendor_event,
1370 QCA_WLAN_VENDOR_ATTR_LL_STATS_CH_INFO);
1371 for (i = 0; i < pWifiRadioStat->numChannels; i++)
1372 {
1373 struct nlattr *chInfo;
1374
1375 pWifiChannelStats = (tpSirWifiChannelStats) ((uint8*)
1376 pWifiRadioStat->channels +
1377 (i * sizeof(tSirWifiChannelStats)));
1378
1379 hddLog(VOS_TRACE_LEVEL_INFO,
1380 " %d) Channel Info"
1381 " width is %u "
1382 " CenterFreq %u "
1383 " CenterFreq0 %u "
1384 " CenterFreq1 %u "
1385 " onTime %u "
1386 " ccaBusyTime %u",
1387 i,
1388 pWifiChannelStats->channel.width,
1389 pWifiChannelStats->channel.centerFreq,
1390 pWifiChannelStats->channel.centerFreq0,
1391 pWifiChannelStats->channel.centerFreq1,
1392 pWifiChannelStats->onTime,
1393 pWifiChannelStats->ccaBusyTime);
1394
1395
1396 chInfo = nla_nest_start(vendor_event, i);
1397
1398 if (nla_put_u32(vendor_event,
1399 QCA_WLAN_VENDOR_ATTR_LL_STATS_CHANNEL_INFO_WIDTH,
1400 pWifiChannelStats->channel.width) ||
1401 nla_put_u32(vendor_event,
1402 QCA_WLAN_VENDOR_ATTR_LL_STATS_CHANNEL_INFO_CENTER_FREQ,
1403 pWifiChannelStats->channel.centerFreq) ||
1404 nla_put_u32(vendor_event,
1405 QCA_WLAN_VENDOR_ATTR_LL_STATS_CHANNEL_INFO_CENTER_FREQ0,
1406 pWifiChannelStats->channel.centerFreq0) ||
1407 nla_put_u32(vendor_event,
1408 QCA_WLAN_VENDOR_ATTR_LL_STATS_CHANNEL_INFO_CENTER_FREQ1,
1409 pWifiChannelStats->channel.centerFreq1) ||
1410 nla_put_u32(vendor_event,
1411 QCA_WLAN_VENDOR_ATTR_LL_STATS_CHANNEL_ON_TIME,
1412 pWifiChannelStats->onTime) ||
1413 nla_put_u32(vendor_event,
1414 QCA_WLAN_VENDOR_ATTR_LL_STATS_CHANNEL_CCA_BUSY_TIME,
1415 pWifiChannelStats->ccaBusyTime))
1416 {
1417 hddLog(VOS_TRACE_LEVEL_ERROR,
1418 FL("cfg80211_vendor_event_alloc failed") );
1419 kfree_skb(vendor_event);
1420 return ;
1421 }
1422 nla_nest_end(vendor_event, chInfo);
1423 }
1424 nla_nest_end(vendor_event, chList);
1425
1426 cfg80211_vendor_event(vendor_event, GFP_KERNEL);
1427 return;
1428}
1429
1430/*
1431 * hdd_link_layer_stats_ind_callback () - This function is called after
1432 * receiving Link Layer indications from FW.This callback converts the firmware
1433 * data to the NL data and send the same to the kernel/upper layers.
1434 */
1435static void hdd_link_layer_stats_ind_callback ( void *pCtx,
1436 int indType,
Dino Mycled3d50022014-07-07 12:58:25 +05301437 void *pRsp, u8 *macAddr)
Sunil Duttc69bccb2014-05-26 21:30:20 +05301438{
Dino Mycled3d50022014-07-07 12:58:25 +05301439 hdd_context_t *pHddCtx = (hdd_context_t *)pCtx;
1440 hdd_adapter_t *pAdapter = NULL;
1441 tpSirLLStatsResults linkLayerStatsResults = (tpSirLLStatsResults)pRsp;
Sunil Duttc69bccb2014-05-26 21:30:20 +05301442 int status;
1443
1444 status = wlan_hdd_validate_context(pHddCtx);
1445
1446 if (0 != status)
1447 {
1448 hddLog(VOS_TRACE_LEVEL_ERROR,
1449 FL("HDD context is not valid"));
1450 return;
1451 }
1452
Dino Mycled3d50022014-07-07 12:58:25 +05301453
1454
1455 pAdapter = hdd_get_adapter_by_macaddr(pHddCtx, macAddr);
1456 if (NULL == pAdapter)
1457 {
1458 hddLog(VOS_TRACE_LEVEL_ERROR,
1459 FL(" MAC address %pM does not exist with host"),
1460 macAddr);
1461 return;
1462 }
1463
Sunil Duttc69bccb2014-05-26 21:30:20 +05301464 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Dino Mycled3d50022014-07-07 12:58:25 +05301465 "%s: Interface: %s LLStats indType: %d", __func__,
1466 pAdapter->dev->name, indType);
1467
Sunil Duttc69bccb2014-05-26 21:30:20 +05301468 switch (indType)
1469 {
1470 case SIR_HAL_LL_STATS_RESULTS_RSP:
1471 {
Sunil Duttc69bccb2014-05-26 21:30:20 +05301472 hddLog(VOS_TRACE_LEVEL_INFO,
1473 FL("RESPONSE SIR_HAL_LL_STATS_RESULTS_RSP") );
1474 hddLog(VOS_TRACE_LEVEL_INFO,
1475 "LL_STATS RESULTS RESPONSE paramID = 0x%x",
1476 linkLayerStatsResults->paramId);
1477 hddLog(VOS_TRACE_LEVEL_INFO,
Dino Mycled3d50022014-07-07 12:58:25 +05301478 "LL_STATS RESULTS RESPONSE ifaceId = %u MAC: %pM",
1479 linkLayerStatsResults->ifaceId, macAddr);
Sunil Duttc69bccb2014-05-26 21:30:20 +05301480 hddLog(VOS_TRACE_LEVEL_INFO,
1481 "LL_STATS RESULTS RESPONSE respId = %u",
1482 linkLayerStatsResults->respId);
1483 hddLog(VOS_TRACE_LEVEL_INFO,
1484 "LL_STATS RESULTS RESPONSE moreResultToFollow = %u",
1485 linkLayerStatsResults->moreResultToFollow);
1486 hddLog(VOS_TRACE_LEVEL_INFO,
1487 "LL_STATS RESULTS RESPONSE result = %p",
1488 linkLayerStatsResults->result);
1489 if ( linkLayerStatsResults->paramId & WMI_LINK_STATS_RADIO )
1490 {
1491 hdd_link_layer_process_radio_stats(pAdapter,
1492 (v_VOID_t *)linkLayerStatsResults->result);
1493 }
1494 else if ( linkLayerStatsResults->paramId & WMI_LINK_STATS_IFACE )
1495 {
1496 hdd_link_layer_process_iface_stats(pAdapter,
1497 (v_VOID_t *)linkLayerStatsResults->result);
1498 }
1499 else if ( linkLayerStatsResults->paramId &
1500 WMI_LINK_STATS_ALL_PEER )
1501 {
1502 hdd_link_layer_process_peer_stats(pAdapter,
1503 (v_VOID_t *)linkLayerStatsResults->result);
1504 } /* WMI_LINK_STATS_ALL_PEER */
1505 else
1506 {
1507 hddLog(VOS_TRACE_LEVEL_ERROR,
1508 FL("INVALID LL_STATS_NOTIFY RESPONSE ***********"));
1509 }
1510
1511 break;
1512 }
1513 default:
1514 hddLog(VOS_TRACE_LEVEL_ERROR, "invalid event type %d", indType);
1515 break;
1516 }
1517 return;
1518}
1519
1520const struct
1521nla_policy
1522qca_wlan_vendor_ll_set_policy[QCA_WLAN_VENDOR_ATTR_LL_STATS_SET_MAX +1] =
1523{
1524 [QCA_WLAN_VENDOR_ATTR_LL_STATS_SET_CONFIG_MPDU_SIZE_THRESHOLD] =
1525 { .type = NLA_U32 },
1526 [QCA_WLAN_VENDOR_ATTR_LL_STATS_SET_CONFIG_AGGRESSIVE_STATS_GATHERING] =
1527 { .type = NLA_U32 },
1528};
1529
1530static int wlan_hdd_cfg80211_ll_stats_set(struct wiphy *wiphy,
1531 struct wireless_dev *wdev,
1532 void *data,
1533 int data_len)
1534{
1535 int status;
1536 struct nlattr *tb_vendor[QCA_WLAN_VENDOR_ATTR_LL_STATS_SET_MAX + 1];
Dino Mycledf0a5d92014-07-04 09:41:55 +05301537 tSirLLStatsSetReq linkLayerStatsSetReq;
Sunil Duttc69bccb2014-05-26 21:30:20 +05301538 struct net_device *dev = wdev->netdev;
1539 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
1540 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
1541
1542 status = wlan_hdd_validate_context(pHddCtx);
1543 if (0 != status)
1544 {
1545 hddLog(VOS_TRACE_LEVEL_ERROR,
1546 FL("HDD context is not valid"));
1547 return -EINVAL;
1548 }
1549
1550 if (NULL == pAdapter)
1551 {
1552 hddLog(VOS_TRACE_LEVEL_ERROR,
1553 FL("HDD adapter is Null"));
1554 return -ENODEV;
1555 }
Dino Mycledf0a5d92014-07-04 09:41:55 +05301556 /* check the LLStats Capability */
1557 if ( (TRUE != pHddCtx->cfg_ini->fEnableLLStats) ||
1558 (TRUE != sme_IsFeatureSupportedByFW(LINK_LAYER_STATS_MEAS)))
1559 {
1560 hddLog(VOS_TRACE_LEVEL_ERROR,
1561 FL("Link Layer Statistics not supported by Firmware"));
1562 return -EINVAL;
1563 }
Sunil Duttc69bccb2014-05-26 21:30:20 +05301564
1565 if (nla_parse(tb_vendor, QCA_WLAN_VENDOR_ATTR_LL_STATS_SET_MAX,
1566 (struct nlattr *)data,
1567 data_len, qca_wlan_vendor_ll_set_policy))
1568 {
1569 hddLog(VOS_TRACE_LEVEL_ERROR, FL() );
1570 return -EINVAL;
1571 }
1572 if (!tb_vendor
1573 [QCA_WLAN_VENDOR_ATTR_LL_STATS_SET_CONFIG_MPDU_SIZE_THRESHOLD])
1574 {
1575 hddLog(VOS_TRACE_LEVEL_ERROR, FL("MPDU size Not present"));
1576 return -EINVAL;
1577 }
1578 if (!tb_vendor[
1579 QCA_WLAN_VENDOR_ATTR_LL_STATS_SET_CONFIG_AGGRESSIVE_STATS_GATHERING])
1580 {
1581 hddLog(VOS_TRACE_LEVEL_ERROR, FL(" Stats Gathering Not Present"));
1582 return -EINVAL;
1583 }
Sunil Duttc69bccb2014-05-26 21:30:20 +05301584 // Shall take the request Id if the Upper layers pass. 1 For now.
Dino Mycledf0a5d92014-07-04 09:41:55 +05301585 linkLayerStatsSetReq.reqId = 1;
Sunil Duttc69bccb2014-05-26 21:30:20 +05301586
Dino Mycledf0a5d92014-07-04 09:41:55 +05301587 linkLayerStatsSetReq.mpduSizeThreshold =
Sunil Duttc69bccb2014-05-26 21:30:20 +05301588 nla_get_u32(
1589 tb_vendor[QCA_WLAN_VENDOR_ATTR_LL_STATS_SET_CONFIG_MPDU_SIZE_THRESHOLD]);
1590
Dino Mycledf0a5d92014-07-04 09:41:55 +05301591 linkLayerStatsSetReq.aggressiveStatisticsGathering =
Sunil Duttc69bccb2014-05-26 21:30:20 +05301592 nla_get_u32(
1593 tb_vendor[QCA_WLAN_VENDOR_ATTR_LL_STATS_SET_CONFIG_AGGRESSIVE_STATS_GATHERING]);
1594
Dino Mycled3d50022014-07-07 12:58:25 +05301595 vos_mem_copy(linkLayerStatsSetReq.macAddr,
1596 pAdapter->macAddressCurrent.bytes, sizeof(v_MACADDR_t));
Sunil Duttc69bccb2014-05-26 21:30:20 +05301597
1598
1599 hddLog(VOS_TRACE_LEVEL_INFO,
Dino Mycled3d50022014-07-07 12:58:25 +05301600 "LL_STATS_SET reqId = %d", linkLayerStatsSetReq.reqId);
Sunil Duttc69bccb2014-05-26 21:30:20 +05301601 hddLog(VOS_TRACE_LEVEL_INFO,
Dino Mycled3d50022014-07-07 12:58:25 +05301602 "LL_STATS_SET MAC = %pM", linkLayerStatsSetReq.macAddr);
Sunil Duttc69bccb2014-05-26 21:30:20 +05301603 hddLog(VOS_TRACE_LEVEL_INFO,
1604 "LL_STATS_SET mpduSizeThreshold = %d",
Dino Mycledf0a5d92014-07-04 09:41:55 +05301605 linkLayerStatsSetReq.mpduSizeThreshold);
Sunil Duttc69bccb2014-05-26 21:30:20 +05301606 hddLog(VOS_TRACE_LEVEL_INFO,
1607 "LL_STATS_SET aggressive Statistics Gathering = %d",
Dino Mycledf0a5d92014-07-04 09:41:55 +05301608 linkLayerStatsSetReq.aggressiveStatisticsGathering);
Sunil Duttc69bccb2014-05-26 21:30:20 +05301609
1610 if (eHAL_STATUS_SUCCESS != sme_SetLinkLayerStatsIndCB(
1611 pHddCtx->hHal,
Dino Mycled3d50022014-07-07 12:58:25 +05301612 hdd_link_layer_stats_ind_callback))
Sunil Duttc69bccb2014-05-26 21:30:20 +05301613 {
1614 hddLog(VOS_TRACE_LEVEL_ERROR, "%s:"
1615 "sme_SetLinkLayerStatsIndCB Failed", __func__);
Sunil Duttc69bccb2014-05-26 21:30:20 +05301616 return -EINVAL;
1617
1618 }
1619 if (eHAL_STATUS_SUCCESS != sme_LLStatsSetReq( pHddCtx->hHal,
Dino Mycledf0a5d92014-07-04 09:41:55 +05301620 &linkLayerStatsSetReq))
Sunil Duttc69bccb2014-05-26 21:30:20 +05301621 {
1622 hddLog(VOS_TRACE_LEVEL_ERROR, "%s:"
1623 "sme_LLStatsSetReq Failed", __func__);
Sunil Duttc69bccb2014-05-26 21:30:20 +05301624 return -EINVAL;
1625 }
1626
1627 pAdapter->isLinkLayerStatsSet = 1;
1628
1629 return 0;
1630}
1631
1632const struct
1633nla_policy
1634qca_wlan_vendor_ll_get_policy[QCA_WLAN_VENDOR_ATTR_LL_STATS_GET_MAX +1] =
1635{
1636 /* Unsigned 32bit value provided by the caller issuing the GET stats
1637 * command. When reporting
1638 * the stats results, the driver uses the same value to indicate
1639 * which GET request the results
1640 * correspond to.
1641 */
1642 [QCA_WLAN_VENDOR_ATTR_LL_STATS_GET_CONFIG_REQ_ID] = { .type = NLA_U32 },
1643
1644 /* Unsigned 32bit value . bit mask to identify what statistics are
1645 requested for retrieval */
1646 [QCA_WLAN_VENDOR_ATTR_LL_STATS_GET_CONFIG_REQ_MASK] = { .type = NLA_U32 },
1647};
1648
1649static int wlan_hdd_cfg80211_ll_stats_get(struct wiphy *wiphy,
1650 struct wireless_dev *wdev,
1651 void *data,
1652 int data_len)
1653{
1654 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
1655 struct nlattr *tb_vendor[QCA_WLAN_VENDOR_ATTR_LL_STATS_GET_MAX + 1];
Dino Mycledf0a5d92014-07-04 09:41:55 +05301656 tSirLLStatsGetReq linkLayerStatsGetReq;
Sunil Duttc69bccb2014-05-26 21:30:20 +05301657 struct net_device *dev = wdev->netdev;
1658 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
1659 int status;
1660
1661 status = wlan_hdd_validate_context(pHddCtx);
1662 if (0 != status)
1663 {
1664 hddLog(VOS_TRACE_LEVEL_ERROR,
1665 FL("HDD context is not valid"));
1666 return -EINVAL ;
1667 }
1668
1669 if (NULL == pAdapter)
1670 {
1671 hddLog(VOS_TRACE_LEVEL_FATAL,
1672 "%s: HDD adapter is Null", __func__);
1673 return -ENODEV;
1674 }
Dino Mycledf0a5d92014-07-04 09:41:55 +05301675 /* check the LLStats Capability */
1676 if ( (TRUE != pHddCtx->cfg_ini->fEnableLLStats) ||
1677 (TRUE != sme_IsFeatureSupportedByFW(LINK_LAYER_STATS_MEAS)))
1678 {
1679 hddLog(VOS_TRACE_LEVEL_ERROR,
1680 FL("Link Layer Statistics not supported by Firmware"));
1681 return -EINVAL;
1682 }
1683
Sunil Duttc69bccb2014-05-26 21:30:20 +05301684
1685 if (!pAdapter->isLinkLayerStatsSet)
1686 {
1687 hddLog(VOS_TRACE_LEVEL_FATAL,
1688 "%s: isLinkLayerStatsSet : %d",
1689 __func__, pAdapter->isLinkLayerStatsSet);
1690 return -EINVAL;
1691 }
1692
1693 if (nla_parse(tb_vendor, QCA_WLAN_VENDOR_ATTR_LL_STATS_GET_MAX,
1694 (struct nlattr *)data,
1695 data_len, qca_wlan_vendor_ll_get_policy))
1696 {
1697 hddLog(VOS_TRACE_LEVEL_ERROR, FL() );
1698 return -EINVAL;
1699 }
1700
1701 if (!tb_vendor
1702 [QCA_WLAN_VENDOR_ATTR_LL_STATS_GET_CONFIG_REQ_ID])
1703 {
1704 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Request Id Not present"));
1705 return -EINVAL;
1706 }
1707
1708 if (!tb_vendor
1709 [QCA_WLAN_VENDOR_ATTR_LL_STATS_GET_CONFIG_REQ_MASK])
1710 {
1711 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Req Mask Not present"));
1712 return -EINVAL;
1713 }
1714
Sunil Duttc69bccb2014-05-26 21:30:20 +05301715
Dino Mycledf0a5d92014-07-04 09:41:55 +05301716 linkLayerStatsGetReq.reqId =
Sunil Duttc69bccb2014-05-26 21:30:20 +05301717 nla_get_u32( tb_vendor[
1718 QCA_WLAN_VENDOR_ATTR_LL_STATS_GET_CONFIG_REQ_ID]);
Dino Mycledf0a5d92014-07-04 09:41:55 +05301719 linkLayerStatsGetReq.paramIdMask =
Sunil Duttc69bccb2014-05-26 21:30:20 +05301720 nla_get_u32( tb_vendor[
1721 QCA_WLAN_VENDOR_ATTR_LL_STATS_GET_CONFIG_REQ_MASK]);
1722
Dino Mycled3d50022014-07-07 12:58:25 +05301723 vos_mem_copy(linkLayerStatsGetReq.macAddr,
1724 pAdapter->macAddressCurrent.bytes, sizeof(v_MACADDR_t));
Sunil Duttc69bccb2014-05-26 21:30:20 +05301725
1726 hddLog(VOS_TRACE_LEVEL_INFO,
Dino Mycledf0a5d92014-07-04 09:41:55 +05301727 "LL_STATS_GET reqId = %d", linkLayerStatsGetReq.reqId);
Sunil Duttc69bccb2014-05-26 21:30:20 +05301728 hddLog(VOS_TRACE_LEVEL_INFO,
Dino Mycled3d50022014-07-07 12:58:25 +05301729 "LL_STATS_GET MAC = %pM", linkLayerStatsGetReq.macAddr);
Sunil Duttc69bccb2014-05-26 21:30:20 +05301730 hddLog(VOS_TRACE_LEVEL_INFO,
1731 "LL_STATS_GET paramIdMask = %d",
Dino Mycledf0a5d92014-07-04 09:41:55 +05301732 linkLayerStatsGetReq.paramIdMask);
Sunil Duttc69bccb2014-05-26 21:30:20 +05301733
1734 if (eHAL_STATUS_SUCCESS != sme_LLStatsGetReq( pHddCtx->hHal,
Dino Mycledf0a5d92014-07-04 09:41:55 +05301735 &linkLayerStatsGetReq))
Sunil Duttc69bccb2014-05-26 21:30:20 +05301736 {
1737 hddLog(VOS_TRACE_LEVEL_ERROR, "%s:"
1738 "sme_LLStatsGetReq Failed", __func__);
Sunil Duttc69bccb2014-05-26 21:30:20 +05301739 return -EINVAL;
1740 }
1741 return 0;
1742}
1743
1744const struct
1745nla_policy
1746qca_wlan_vendor_ll_clr_policy[QCA_WLAN_VENDOR_ATTR_LL_STATS_CLR_MAX +1] =
1747{
1748 [QCA_WLAN_VENDOR_ATTR_LL_STATS_CLR_CONFIG_REQ_MASK] = {.type = NLA_U32 },
1749 [QCA_WLAN_VENDOR_ATTR_LL_STATS_CLR_CONFIG_STOP_REQ] = {.type = NLA_U8 },
1750 [QCA_WLAN_VENDOR_ATTR_LL_STATS_CLR_CONFIG_RSP_MASK] = {.type = NLA_U32 },
1751 [QCA_WLAN_VENDOR_ATTR_LL_STATS_CLR_CONFIG_STOP_RSP] = {.type = NLA_U8 },
1752};
1753
1754static int wlan_hdd_cfg80211_ll_stats_clear(struct wiphy *wiphy,
1755 struct wireless_dev *wdev,
1756 void *data,
1757 int data_len)
1758{
1759 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
1760 struct nlattr *tb_vendor[QCA_WLAN_VENDOR_ATTR_LL_STATS_CLR_MAX + 1];
Dino Mycledf0a5d92014-07-04 09:41:55 +05301761 tSirLLStatsClearReq linkLayerStatsClearReq;
Sunil Duttc69bccb2014-05-26 21:30:20 +05301762 struct net_device *dev = wdev->netdev;
1763 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
1764 u32 statsClearReqMask;
1765 u8 stopReq;
1766 int status;
1767
1768 status = wlan_hdd_validate_context(pHddCtx);
1769 if (0 != status)
1770 {
1771 hddLog(VOS_TRACE_LEVEL_ERROR,
1772 FL("HDD context is not valid"));
1773 return -EINVAL;
1774 }
1775
1776 if (NULL == pAdapter)
1777 {
1778 hddLog(VOS_TRACE_LEVEL_FATAL,
1779 "%s: HDD adapter is Null", __func__);
1780 return -ENODEV;
1781 }
Dino Mycledf0a5d92014-07-04 09:41:55 +05301782 /* check the LLStats Capability */
1783 if ( (TRUE != pHddCtx->cfg_ini->fEnableLLStats) ||
1784 (TRUE != sme_IsFeatureSupportedByFW(LINK_LAYER_STATS_MEAS)))
1785 {
1786 hddLog(VOS_TRACE_LEVEL_ERROR,
1787 FL("Enable LLStats Capability"));
1788 return -EINVAL;
1789 }
Sunil Duttc69bccb2014-05-26 21:30:20 +05301790
1791 if (!pAdapter->isLinkLayerStatsSet)
1792 {
1793 hddLog(VOS_TRACE_LEVEL_FATAL,
1794 "%s: isLinkLayerStatsSet : %d",
1795 __func__, pAdapter->isLinkLayerStatsSet);
1796 return -EINVAL;
1797 }
1798
1799 if (nla_parse(tb_vendor, QCA_WLAN_VENDOR_ATTR_LL_STATS_CLR_MAX,
1800 (struct nlattr *)data,
1801 data_len, qca_wlan_vendor_ll_clr_policy))
1802 {
1803 hddLog(VOS_TRACE_LEVEL_ERROR, FL() );
1804 return -EINVAL;
1805 }
1806
1807 if (!tb_vendor[QCA_WLAN_VENDOR_ATTR_LL_STATS_CLR_CONFIG_REQ_MASK] ||
1808
1809 !tb_vendor[QCA_WLAN_VENDOR_ATTR_LL_STATS_CLR_CONFIG_STOP_REQ])
1810 {
1811 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Error in LL_STATS CLR CONFIG PARA") );
1812 return -EINVAL;
1813
1814 }
1815
Sunil Duttc69bccb2014-05-26 21:30:20 +05301816
Dino Mycledf0a5d92014-07-04 09:41:55 +05301817 statsClearReqMask = linkLayerStatsClearReq.statsClearReqMask =
Sunil Duttc69bccb2014-05-26 21:30:20 +05301818 nla_get_u32(
1819 tb_vendor[QCA_WLAN_VENDOR_ATTR_LL_STATS_CLR_CONFIG_REQ_MASK]);
1820
Dino Mycledf0a5d92014-07-04 09:41:55 +05301821 stopReq = linkLayerStatsClearReq.stopReq =
Sunil Duttc69bccb2014-05-26 21:30:20 +05301822 nla_get_u8(
1823 tb_vendor[QCA_WLAN_VENDOR_ATTR_LL_STATS_CLR_CONFIG_STOP_REQ]);
1824
1825 // Shall take the request Id if the Upper layers pass. 1 For now.
Dino Mycledf0a5d92014-07-04 09:41:55 +05301826 linkLayerStatsClearReq.reqId = 1;
Sunil Duttc69bccb2014-05-26 21:30:20 +05301827
Dino Mycled3d50022014-07-07 12:58:25 +05301828 vos_mem_copy(linkLayerStatsClearReq.macAddr,
1829 pAdapter->macAddressCurrent.bytes, sizeof(v_MACADDR_t));
Sunil Duttc69bccb2014-05-26 21:30:20 +05301830
1831 hddLog(VOS_TRACE_LEVEL_INFO,
Dino Mycledf0a5d92014-07-04 09:41:55 +05301832 "LL_STATS_CLEAR reqId = %d", linkLayerStatsClearReq.reqId);
Sunil Duttc69bccb2014-05-26 21:30:20 +05301833 hddLog(VOS_TRACE_LEVEL_INFO,
Dino Mycled3d50022014-07-07 12:58:25 +05301834 "LL_STATS_CLEAR MAC = %pM", linkLayerStatsClearReq.macAddr);
Sunil Duttc69bccb2014-05-26 21:30:20 +05301835 hddLog(VOS_TRACE_LEVEL_INFO,
1836 "LL_STATS_CLEAR statsClearReqMask = 0x%X",
Dino Mycledf0a5d92014-07-04 09:41:55 +05301837 linkLayerStatsClearReq.statsClearReqMask);
Sunil Duttc69bccb2014-05-26 21:30:20 +05301838 hddLog(VOS_TRACE_LEVEL_INFO,
1839 "LL_STATS_CLEAR stopReq = %d",
Dino Mycledf0a5d92014-07-04 09:41:55 +05301840 linkLayerStatsClearReq.stopReq);
Sunil Duttc69bccb2014-05-26 21:30:20 +05301841
1842 if (eHAL_STATUS_SUCCESS == sme_LLStatsClearReq(pHddCtx->hHal,
Dino Mycledf0a5d92014-07-04 09:41:55 +05301843 &linkLayerStatsClearReq))
Sunil Duttc69bccb2014-05-26 21:30:20 +05301844 {
1845 struct sk_buff *temp_skbuff;
1846 temp_skbuff = cfg80211_vendor_cmd_alloc_reply_skb(wiphy,
1847 2 * sizeof(u32) +
1848 NLMSG_HDRLEN);
1849
1850 if (temp_skbuff != NULL)
1851 {
1852
1853 if (nla_put_u32(temp_skbuff,
1854 QCA_WLAN_VENDOR_ATTR_LL_STATS_CLR_CONFIG_RSP_MASK,
1855 statsClearReqMask) ||
1856 nla_put_u32(temp_skbuff,
1857 QCA_WLAN_VENDOR_ATTR_LL_STATS_CLR_CONFIG_STOP_RSP,
1858 stopReq))
1859 {
1860 hddLog(VOS_TRACE_LEVEL_ERROR, FL("LL_STATS_CLR put fail"));
1861 kfree_skb(temp_skbuff);
1862 return -EINVAL;
1863 }
1864 /* If the ask is to stop the stats collection as part of clear
1865 * (stopReq = 1) , ensure that no further requests of get
1866 * go to the firmware by having isLinkLayerStatsSet set to 0.
1867 * However it the stopReq as part of the clear request is 0 ,
Dino Mycledf0a5d92014-07-04 09:41:55 +05301868 * the request to get the statistics are honoured as in this
Sunil Duttc69bccb2014-05-26 21:30:20 +05301869 * case the firmware is just asked to clear the statistics.
1870 */
Dino Mycledf0a5d92014-07-04 09:41:55 +05301871 if (linkLayerStatsClearReq.stopReq == 1)
Sunil Duttc69bccb2014-05-26 21:30:20 +05301872 pAdapter->isLinkLayerStatsSet = 0;
1873 return cfg80211_vendor_cmd_reply(temp_skbuff);
1874 }
1875 return -ENOMEM;
1876 }
Sunil Duttc69bccb2014-05-26 21:30:20 +05301877 return -EINVAL;
1878}
1879#endif /* WLAN_FEATURE_LINK_LAYER_STATS */
1880
Dino Mycle6fb96c12014-06-10 11:52:40 +05301881#ifdef WLAN_FEATURE_EXTSCAN
1882static const struct nla_policy
1883wlan_hdd_extscan_config_policy
1884 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX + 1] =
1885{
1886 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_REQUEST_ID] =
1887 { .type = NLA_U32 },
1888 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_GET_VALID_CHANNELS_CONFIG_PARAM_WIFI_BAND] =
1889 { .type = NLA_U32 },
1890 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_CHANNEL_SPEC_CHANNEL] = { .type = NLA_U32 },
1891 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_CHANNEL_SPEC_DWELL_TIME] =
1892 { .type = NLA_U32 },
1893 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_CHANNEL_SPEC_PASSIVE] = { .type = NLA_U8 },
1894 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_CHANNEL_SPEC_CLASS] = { .type = NLA_U8 },
1895
1896 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_INDEX] = { .type = NLA_U8 },
1897 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_BAND] = { .type = NLA_U8 },
1898 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_PERIOD] = { .type = NLA_U32 },
1899 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_REPORT_EVENTS] =
1900 { .type = NLA_U8 },
1901 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_NUM_CHANNEL_SPECS] =
1902 { .type = NLA_U32 },
1903 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_SCAN_CMD_PARAMS_BASE_PERIOD] =
1904 { .type = NLA_U32 },
1905 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_SCAN_CMD_PARAMS_MAX_AP_PER_SCAN] =
1906 { .type = NLA_U32 },
1907 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_SCAN_CMD_PARAMS_REPORT_THRESHOLD] =
1908 { .type = NLA_U8 },
1909 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_SCAN_CMD_PARAMS_NUM_BUCKETS] =
1910 { .type = NLA_U8 },
1911 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_GET_CACHED_SCAN_RESULTS_CONFIG_PARAM_FLUSH] =
1912 { .type = NLA_U8 },
1913
1914 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_GET_CACHED_SCAN_RESULTS_CONFIG_PARAM_MAX] =
1915 { .type = NLA_U32 },
1916 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_AP_THRESHOLD_PARAM_BSSID] =
1917 { .type = NLA_UNSPEC },
1918 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_AP_THRESHOLD_PARAM_RSSI_LOW] =
1919 { .type = NLA_S32 },
1920 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_AP_THRESHOLD_PARAM_RSSI_HIGH] =
1921 { .type = NLA_S32 },
1922 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_AP_THRESHOLD_PARAM_CHANNEL] =
1923 { .type = NLA_U32 },
1924 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_BSSID_HOTLIST_PARAMS_NUM_AP] =
1925 { .type = NLA_U32 },
1926 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_SIGNIFICANT_CHANGE_PARAMS_RSSI_SAMPLE_SIZE] =
1927 { .type = NLA_U32 },
1928 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_SIGNIFICANT_CHANGE_PARAMS_LOST_AP_SAMPLE_SIZE]
1929 = { .type = NLA_U32 },
1930 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_SIGNIFICANT_CHANGE_PARAMS_MIN_BREACHING] =
1931 { .type = NLA_U32 },
1932 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_SIGNIFICANT_CHANGE_PARAMS_NUM_AP] = { .type =
1933 NLA_U32 },
1934};
1935
1936static void wlan_hdd_cfg80211_extscan_get_capabilities_ind(void *ctx, void *pMsg)
1937{
1938 hdd_context_t *pHddCtx = (hdd_context_t *)ctx;
1939 struct sk_buff *skb = NULL;
1940 tpSirEXTScanCapabilitiesEvent pData =
1941 (tpSirEXTScanCapabilitiesEvent) pMsg;
1942
1943 if (wlan_hdd_validate_context(pHddCtx) || !pData) {
1944 hddLog(VOS_TRACE_LEVEL_ERROR, FL("HDD context is not valid "
1945 "or pData(%p) is null"), pData);
1946 return;
1947 }
1948
1949 skb = cfg80211_vendor_event_alloc(pHddCtx->wiphy,
1950 EXTSCAN_EVENT_BUF_SIZE + NLMSG_HDRLEN,
1951 QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_GET_CAPABILITIES_INDEX,
1952 GFP_KERNEL);
1953
1954 if (!skb) {
1955 hddLog(VOS_TRACE_LEVEL_ERROR,
1956 FL("cfg80211_vendor_event_alloc failed"));
1957 return;
1958 }
1959
1960 hddLog(VOS_TRACE_LEVEL_INFO, "Req Id (%u)", pData->requestId);
1961 hddLog(VOS_TRACE_LEVEL_INFO, "Scan cache size (%u)", pData->scanCacheSize);
1962 hddLog(VOS_TRACE_LEVEL_INFO, "Scan buckets (%u)", pData->scanBuckets);
1963 hddLog(VOS_TRACE_LEVEL_INFO, "Max AP per scan (%u)", pData->maxApPerScan);
1964 hddLog(VOS_TRACE_LEVEL_INFO, "maxRssiSampleSize (%u)",
1965 pData->maxRssiSampleSize);
1966 hddLog(VOS_TRACE_LEVEL_INFO, "maxScanReportingThreshold (%u)",
1967 pData->maxScanReportingThreshold);
1968 hddLog(VOS_TRACE_LEVEL_INFO, "maxHotlistAPs (%u)", pData->maxHotlistAPs);
1969 hddLog(VOS_TRACE_LEVEL_INFO, "maxSignificantWifiChangeAPs (%u)",
1970 pData->maxSignificantWifiChangeAPs);
1971 hddLog(VOS_TRACE_LEVEL_INFO, "maxBsidHistoryEntries (%u)",
1972 pData->maxBsidHistoryEntries);
1973
1974 if (nla_put_u32(skb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_REQUEST_ID,
1975 pData->requestId) ||
1976 nla_put_u32(skb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_STATUS, pData->status) ||
1977 nla_put_u32(skb,
1978 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_CAPABILITIES_MAX_SCAN_CACHE_SIZE,
1979 pData->scanCacheSize) ||
1980 nla_put_u32(skb,
1981 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_CAPABILITIES_MAX_SCAN_BUCKETS,
1982 pData->scanBuckets) ||
1983 nla_put_u32(skb,
1984 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_CAPABILITIES_MAX_AP_CACHE_PER_SCAN,
1985 pData->maxApPerScan) ||
1986 nla_put_u32(skb,
1987 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_CAPABILITIES_MAX_RSSI_SAMPLE_SIZE,
1988 pData->maxRssiSampleSize) ||
1989 nla_put_u32(skb,
1990 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_CAPABILITIES_MAX_SCAN_REPORTING_THRESHOLD,
1991 pData->maxScanReportingThreshold) ||
1992 nla_put_u32(skb,
1993 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_CAPABILITIES_MAX_HOTLIST_APS,
1994 pData->maxHotlistAPs) ||
1995 nla_put_u32(skb,
1996 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_CAPABILITIES_MAX_SIGNIFICANT_WIFI_CHANGE_APS,
1997 pData->maxSignificantWifiChangeAPs) ||
1998 nla_put_u32(skb,
1999 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_CAPABILITIES_MAX_BSSID_HISTORY_ENTRIES,
2000 pData->maxBsidHistoryEntries)) {
2001 hddLog(VOS_TRACE_LEVEL_ERROR, FL("nla put fail"));
2002 goto nla_put_failure;
2003 }
2004
2005 cfg80211_vendor_event(skb, GFP_KERNEL);
2006 return;
2007
2008nla_put_failure:
2009 kfree_skb(skb);
2010 return;
2011}
2012
2013
2014static void wlan_hdd_cfg80211_extscan_start_rsp(void *ctx, void *pMsg)
2015{
2016 tpSirEXTScanStartRspParams pData = (tpSirEXTScanStartRspParams) pMsg;
2017 hdd_context_t *pHddCtx = (hdd_context_t *)ctx;
2018 struct sk_buff *skb = NULL;
2019 tpAniSirGlobal pMac = PMAC_STRUCT( pHddCtx->hHal );
2020
2021
2022 if (wlan_hdd_validate_context(pHddCtx) || !pData) {
2023 hddLog(VOS_TRACE_LEVEL_ERROR, FL("HDD context is not valid "
2024 "or pData(%p) is null"), pData);
2025 return;
2026 }
2027
2028 skb = cfg80211_vendor_event_alloc(pHddCtx->wiphy,
2029 EXTSCAN_EVENT_BUF_SIZE + NLMSG_HDRLEN,
2030 QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_START_INDEX,
2031 GFP_KERNEL);
2032
2033 if (!skb) {
2034 hddLog(VOS_TRACE_LEVEL_ERROR,
2035 FL("cfg80211_vendor_event_alloc failed"));
2036 return;
2037 }
2038 hddLog(VOS_TRACE_LEVEL_INFO, FL("Entering "));
2039 hddLog(VOS_TRACE_LEVEL_INFO, "Req Id (%u)", pData->requestId);
2040 hddLog(VOS_TRACE_LEVEL_INFO, "Status (%u)", pData->status);
2041
2042 if (nla_put_u32(skb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_REQUEST_ID,
2043 pData->requestId) ||
2044 nla_put_u32(skb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_STATUS, pData->status)) {
2045 hddLog(VOS_TRACE_LEVEL_ERROR, FL("nla put fail"));
2046 goto nla_put_failure;
2047 }
2048
2049 /*
2050 * Store the Request ID for comparing with the requestID obtained
2051 * in other requests.HDD shall return a failure is the extscan_stop
2052 * request is issued with a different requestId as that of the
2053 * extscan_start request. Also, This requestId shall be used while
2054 * indicating the full scan results to the upper layers.
2055 * The requestId is stored with the assumption that the firmware
2056 * shall return the ext scan start request's requestId in ext scan
2057 * start response.
2058 */
2059 if (pData->status == 0)
2060 pMac->sme.extScanStartReqId = pData->requestId;
2061
2062
2063 cfg80211_vendor_event(skb, GFP_KERNEL);
2064 return;
2065
2066nla_put_failure:
2067 kfree_skb(skb);
2068 return;
2069}
2070
2071
2072static void wlan_hdd_cfg80211_extscan_stop_rsp(void *ctx, void *pMsg)
2073{
2074 tpSirEXTScanStopRspParams pData = (tpSirEXTScanStopRspParams) pMsg;
2075 hdd_context_t *pHddCtx = (hdd_context_t *)ctx;
2076 struct sk_buff *skb = NULL;
2077
2078 if (wlan_hdd_validate_context(pHddCtx) || !pData) {
2079 hddLog(VOS_TRACE_LEVEL_ERROR, FL("HDD context is not valid "
2080 "or pData(%p) is null"), pData);
2081 return;
2082 }
2083
2084 skb = cfg80211_vendor_event_alloc(pHddCtx->wiphy,
2085 EXTSCAN_EVENT_BUF_SIZE + NLMSG_HDRLEN,
2086 QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_STOP_INDEX,
2087 GFP_KERNEL);
2088
2089 if (!skb) {
2090 hddLog(VOS_TRACE_LEVEL_ERROR,
2091 FL("cfg80211_vendor_event_alloc failed"));
2092 return;
2093 }
2094 hddLog(VOS_TRACE_LEVEL_INFO, FL("Entering "));
2095 hddLog(VOS_TRACE_LEVEL_INFO, "Req Id (%u)", pData->requestId);
2096
2097 if (nla_put_u32(skb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_REQUEST_ID,
2098 pData->requestId) ||
2099 nla_put_u32(skb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_STATUS, pData->status)) {
2100 hddLog(VOS_TRACE_LEVEL_ERROR, FL("nla put fail"));
2101 goto nla_put_failure;
2102 }
2103
2104 cfg80211_vendor_event(skb, GFP_KERNEL);
2105 return;
2106
2107nla_put_failure:
2108 kfree_skb(skb);
2109 return;
2110}
2111
2112
2113static void wlan_hdd_cfg80211_extscan_set_bss_hotlist_rsp(void *ctx,
2114 void *pMsg)
2115{
2116 hdd_context_t *pHddCtx = (hdd_context_t *)ctx;
2117 struct sk_buff *skb = NULL;
2118 tpSirEXTScanSetBssidHotListRspParams pData =
2119 (tpSirEXTScanSetBssidHotListRspParams) pMsg;
2120
2121 if (wlan_hdd_validate_context(pHddCtx) || !pData) {
2122 hddLog(VOS_TRACE_LEVEL_ERROR, FL("HDD context is not valid "
2123 "or pData(%p) is null"), pData);
2124 return;
2125 }
2126 skb = cfg80211_vendor_event_alloc(pHddCtx->wiphy,
2127 EXTSCAN_EVENT_BUF_SIZE + NLMSG_HDRLEN,
2128 QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_SET_BSSID_HOTLIST_INDEX,
2129 GFP_KERNEL);
2130
2131 if (!skb) {
2132 hddLog(VOS_TRACE_LEVEL_ERROR,
2133 FL("cfg80211_vendor_event_alloc failed"));
2134 return;
2135 }
2136 hddLog(VOS_TRACE_LEVEL_INFO, FL("Entering "));
2137 hddLog(VOS_TRACE_LEVEL_INFO, "Req Id (%u)", pData->requestId);
2138 hddLog(VOS_TRACE_LEVEL_INFO, "Status (%u)", pData->status);
2139
2140 if (nla_put_u32(skb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_REQUEST_ID,
2141 pData->requestId) ||
2142 nla_put_u32(skb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_STATUS, pData->status)) {
2143 hddLog(VOS_TRACE_LEVEL_ERROR, FL("nla put fail"));
2144 goto nla_put_failure;
2145 }
2146
2147 cfg80211_vendor_event(skb, GFP_KERNEL);
2148 return;
2149
2150nla_put_failure:
2151 kfree_skb(skb);
2152 return;
2153}
2154
2155static void wlan_hdd_cfg80211_extscan_reset_bss_hotlist_rsp(void *ctx,
2156 void *pMsg)
2157{
2158 hdd_context_t *pHddCtx = (hdd_context_t *)ctx;
2159 struct sk_buff *skb = NULL;
2160 tpSirEXTScanResetBssidHotlistRspParams pData =
2161 (tpSirEXTScanResetBssidHotlistRspParams) pMsg;
2162
2163 if (wlan_hdd_validate_context(pHddCtx) || !pData) {
2164 hddLog(VOS_TRACE_LEVEL_ERROR, FL("HDD context is not valid "
2165 "or pData(%p) is null"), pData);
2166 return;
2167 }
2168
2169 skb = cfg80211_vendor_event_alloc(pHddCtx->wiphy,
2170 EXTSCAN_EVENT_BUF_SIZE + NLMSG_HDRLEN,
2171 QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_RESET_BSSID_HOTLIST_INDEX,
2172 GFP_KERNEL);
2173
2174 if (!skb) {
2175 hddLog(VOS_TRACE_LEVEL_ERROR,
2176 FL("cfg80211_vendor_event_alloc failed"));
2177 return;
2178 }
2179 hddLog(VOS_TRACE_LEVEL_INFO, FL("Entering "));
2180 hddLog(VOS_TRACE_LEVEL_INFO, "Req Id (%u)", pData->requestId);
2181
2182 if (nla_put_u32(skb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_REQUEST_ID,
2183 pData->requestId) ||
2184 nla_put_u32(skb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_STATUS, pData->status)) {
2185 hddLog(VOS_TRACE_LEVEL_ERROR, FL("nla put fail"));
2186 goto nla_put_failure;
2187 }
2188
2189 cfg80211_vendor_event(skb, GFP_KERNEL);
2190 return;
2191
2192nla_put_failure:
2193 kfree_skb(skb);
2194 return;
2195}
2196
2197
2198static void wlan_hdd_cfg80211_extscan_set_signf_wifi_change_rsp(void *ctx,
2199 void *pMsg)
2200{
2201 hdd_context_t *pHddCtx = (hdd_context_t *)ctx;
2202 struct sk_buff *skb = NULL;
2203 tpSirEXTScanSetSignificantChangeRspParams pData =
2204 (tpSirEXTScanSetSignificantChangeRspParams) pMsg;
2205
2206 if (wlan_hdd_validate_context(pHddCtx) || !pData) {
2207 hddLog(VOS_TRACE_LEVEL_ERROR, FL("HDD context is not valid "
2208 "or pData(%p) is null"), pData);
2209 return;
2210 }
2211
2212 skb = cfg80211_vendor_event_alloc(pHddCtx->wiphy,
2213 EXTSCAN_EVENT_BUF_SIZE + NLMSG_HDRLEN,
2214 QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_SET_SIGNIFICANT_CHANGE_INDEX,
2215 GFP_KERNEL);
2216
2217 if (!skb) {
2218 hddLog(VOS_TRACE_LEVEL_ERROR,
2219 FL("cfg80211_vendor_event_alloc failed"));
2220 return;
2221 }
2222 hddLog(VOS_TRACE_LEVEL_INFO, FL("Entering "));
2223 hddLog(VOS_TRACE_LEVEL_INFO, "Req Id (%u)", pData->requestId);
2224 hddLog(VOS_TRACE_LEVEL_INFO, "Status (%u)", pData->status);
2225
2226 if (nla_put_u32(skb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_REQUEST_ID,
2227 pData->requestId) ||
2228 nla_put_u32(skb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_STATUS, pData->status)) {
2229 hddLog(VOS_TRACE_LEVEL_ERROR, FL("nla put fail"));
2230 goto nla_put_failure;
2231 }
2232
2233 cfg80211_vendor_event(skb, GFP_KERNEL);
2234 return;
2235
2236nla_put_failure:
2237 kfree_skb(skb);
2238 return;
2239}
2240
2241
2242static void wlan_hdd_cfg80211_extscan_reset_signf_wifi_change_rsp(void *ctx,
2243 void *pMsg)
2244{
2245 hdd_context_t *pHddCtx = (hdd_context_t *)ctx;
2246 struct sk_buff *skb = NULL;
2247 tpSirEXTScanResetSignificantChangeRspParams pData =
2248 (tpSirEXTScanResetSignificantChangeRspParams) pMsg;
2249
2250 if (wlan_hdd_validate_context(pHddCtx) || !pData) {
2251 hddLog(VOS_TRACE_LEVEL_ERROR, FL("HDD context is not valid "
2252 "or pData(%p) is null"), pData);
2253 return;
2254 }
2255
2256 skb = cfg80211_vendor_event_alloc(pHddCtx->wiphy,
2257 EXTSCAN_EVENT_BUF_SIZE + NLMSG_HDRLEN,
2258 QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_RESET_SIGNIFICANT_CHANGE_INDEX,
2259 GFP_KERNEL);
2260
2261 if (!skb) {
2262 hddLog(VOS_TRACE_LEVEL_ERROR,
2263 FL("cfg80211_vendor_event_alloc failed"));
2264 return;
2265 }
2266 hddLog(VOS_TRACE_LEVEL_INFO, FL("Entering "));
2267 hddLog(VOS_TRACE_LEVEL_INFO, "Req Id (%u)", pData->requestId);
2268 hddLog(VOS_TRACE_LEVEL_INFO, "Status (%u)", pData->status);
2269
2270 if (nla_put_u32(skb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_REQUEST_ID,
2271 pData->requestId) ||
2272 nla_put_u32(skb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_STATUS, pData->status)) {
2273 hddLog(VOS_TRACE_LEVEL_ERROR, FL("nla put fail"));
2274 goto nla_put_failure;
2275 }
2276
2277 cfg80211_vendor_event(skb, GFP_KERNEL);
2278 return;
2279
2280nla_put_failure:
2281 kfree_skb(skb);
2282 return;
2283}
2284
2285static void wlan_hdd_cfg80211_extscan_cached_results_ind(void *ctx,
2286 void *pMsg)
2287{
2288 hdd_context_t *pHddCtx = (hdd_context_t *)ctx;
2289 struct sk_buff *skb = NULL;
2290 tANI_U32 i = 0, j, resultsPerEvent;
2291 tANI_S32 totalResults;
2292 tpSirWifiScanResultEvent pData = (tpSirWifiScanResultEvent) pMsg;
2293 tpSirWifiScanResult pSirWifiScanResult;
2294
2295 if (wlan_hdd_validate_context(pHddCtx) || !pData) {
2296 hddLog(VOS_TRACE_LEVEL_ERROR, FL("HDD context is not valid "
2297 "or pData(%p) is null"), pData);
2298 return;
2299 }
2300 totalResults = pData->numOfAps;
2301 hddLog(VOS_TRACE_LEVEL_INFO, "Req Id (%u)", pData->requestId);
2302 hddLog(VOS_TRACE_LEVEL_INFO, "Num results (%u)", pData->numOfAps);
2303 hddLog(VOS_TRACE_LEVEL_INFO, "More Data (%u)", pData->moreData);
2304
2305 do{
2306 resultsPerEvent = ((totalResults >= EXTSCAN_MAX_CACHED_RESULTS_PER_IND) ?
2307 EXTSCAN_MAX_CACHED_RESULTS_PER_IND : totalResults);
2308 totalResults -= EXTSCAN_MAX_CACHED_RESULTS_PER_IND;
2309
2310 skb = cfg80211_vendor_event_alloc(pHddCtx->wiphy,
2311 EXTSCAN_EVENT_BUF_SIZE + NLMSG_HDRLEN,
2312 QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_GET_CACHED_RESULTS_INDEX,
2313 GFP_KERNEL);
2314
2315 if (!skb) {
2316 hddLog(VOS_TRACE_LEVEL_ERROR,
2317 FL("cfg80211_vendor_event_alloc failed"));
2318 return;
2319 }
2320
2321 hddLog(VOS_TRACE_LEVEL_INFO, "resultsPerEvent (%u)", resultsPerEvent);
2322
2323 if (nla_put_u32(skb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_REQUEST_ID,
2324 pData->requestId) ||
2325 nla_put_u32(skb,
2326 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_NUM_RESULTS_AVAILABLE,
2327 resultsPerEvent)) {
2328 hddLog(VOS_TRACE_LEVEL_ERROR, FL("put fail"));
2329 goto fail;
2330 }
2331 if (nla_put_u8(skb,
2332 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_MORE_DATA,
2333 pData->moreData ? 1 : (totalResults > 0 ? 1 : 0 )))
2334 {
2335 hddLog(VOS_TRACE_LEVEL_ERROR, FL("put fail"));
2336 goto fail;
2337 }
2338
2339 if (resultsPerEvent) {
2340 struct nlattr *aps;
2341
2342 aps = nla_nest_start(skb,
2343 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_LIST);
2344 if (!aps)
2345 {
2346 hddLog(VOS_TRACE_LEVEL_ERROR, FL("put fail"));
2347 goto fail;
2348 }
2349
2350 for (j = 0; j < resultsPerEvent; j++, i++) {
2351 struct nlattr *ap;
2352 pSirWifiScanResult = (tpSirWifiScanResult) ((tANI_U8 *)
2353 pData->ap + ( i* sizeof(tSirWifiScanResult)));
2354
2355 hddLog(VOS_TRACE_LEVEL_INFO, "[index=%u] Timestamp(%llu) "
2356 "Ssid (%s)"
2357 "Bssid: %pM "
2358 "Channel (%u)"
2359 "Rssi (%d)"
2360 "RTT (%u)"
2361 "RTT_SD (%u)",
2362 i,
2363 pSirWifiScanResult->ts,
2364 pSirWifiScanResult->ssid,
2365 pSirWifiScanResult->bssid,
2366 pSirWifiScanResult->channel,
2367 pSirWifiScanResult->rssi,
2368 pSirWifiScanResult->rtt,
2369 pSirWifiScanResult->rtt_sd);
2370
2371 ap = nla_nest_start(skb, j + 1);
2372 if (!ap)
2373 {
2374 hddLog(VOS_TRACE_LEVEL_ERROR, FL("put fail"));
2375 goto fail;
2376 }
2377
2378 if (nla_put_u64(skb,
2379 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_TIME_STAMP,
2380 pSirWifiScanResult->ts) )
2381 {
2382 hddLog(VOS_TRACE_LEVEL_ERROR, FL("put fail"));
2383 goto fail;
2384 }
2385 if (nla_put(skb,
2386 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_SSID,
2387 sizeof(pSirWifiScanResult->ssid),
2388 pSirWifiScanResult->ssid) )
2389 {
2390 hddLog(VOS_TRACE_LEVEL_ERROR, FL("put fail"));
2391 goto fail;
2392 }
2393 if (nla_put(skb,
2394 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_BSSID,
2395 sizeof(pSirWifiScanResult->bssid),
2396 pSirWifiScanResult->bssid) )
2397 {
2398 hddLog(VOS_TRACE_LEVEL_ERROR, FL("put fail"));
2399 goto fail;
2400 }
2401 if (nla_put_u32(skb,
2402 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_CHANNEL,
2403 pSirWifiScanResult->channel) )
2404 {
2405 hddLog(VOS_TRACE_LEVEL_ERROR, FL("put fail"));
2406 goto fail;
2407 }
2408 if (nla_put_u32(skb,
2409 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_RSSI,
2410 pSirWifiScanResult->rssi) )
2411 {
2412 hddLog(VOS_TRACE_LEVEL_ERROR, FL("put fail"));
2413 goto fail;
2414 }
2415 if (nla_put_u32(skb,
2416 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_RTT,
2417 pSirWifiScanResult->rtt) )
2418 {
2419 hddLog(VOS_TRACE_LEVEL_ERROR, FL("put fail"));
2420 goto fail;
2421 }
2422 if (nla_put_u32(skb,
2423 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_RTT_SD,
2424 pSirWifiScanResult->rtt_sd))
2425 {
2426 hddLog(VOS_TRACE_LEVEL_ERROR, FL("put fail"));
2427 goto fail;
2428 }
2429
2430 nla_nest_end(skb, ap);
2431 }
2432 nla_nest_end(skb, aps);
2433
2434 }
2435 cfg80211_vendor_event(skb, GFP_KERNEL);
2436 } while (totalResults > 0);
2437
2438 return;
2439fail:
2440 kfree_skb(skb);
2441 return;
2442}
2443
2444static void wlan_hdd_cfg80211_extscan_hotlist_match_ind(void *ctx,
2445 void *pMsg)
2446{
2447 tpSirWifiScanResultEvent pData = (tpSirWifiScanResultEvent) pMsg;
2448 hdd_context_t *pHddCtx = (hdd_context_t *)ctx;
2449 struct sk_buff *skb = NULL;
2450 tANI_U32 i;
2451
2452 if (wlan_hdd_validate_context(pHddCtx) || !pData) {
2453 hddLog(VOS_TRACE_LEVEL_ERROR, FL("HDD context is not valid "
2454 "or pData(%p) is null"), pData);
2455 return;
2456 }
2457
2458 skb = cfg80211_vendor_event_alloc(pHddCtx->wiphy,
2459 EXTSCAN_EVENT_BUF_SIZE + NLMSG_HDRLEN,
2460 QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_HOTLIST_AP_FOUND_INDEX,
2461 GFP_KERNEL);
2462
2463 if (!skb) {
2464 hddLog(VOS_TRACE_LEVEL_ERROR,
2465 FL("cfg80211_vendor_event_alloc failed"));
2466 return;
2467 }
2468 hddLog(VOS_TRACE_LEVEL_INFO, FL("Entering "));
2469 hddLog(VOS_TRACE_LEVEL_INFO, "Req Id (%u)", pData->requestId);
2470 hddLog(VOS_TRACE_LEVEL_INFO, "Num results (%u)", pData->numOfAps);
2471 hddLog(VOS_TRACE_LEVEL_INFO, "More Data (%u)", pData->moreData);
2472
2473 for (i = 0; i < pData->numOfAps; i++) {
2474 hddLog(VOS_TRACE_LEVEL_INFO, "[index=%u] Timestamp(0x%lld) "
2475 "Ssid (%s) "
2476 "Bssid (" MAC_ADDRESS_STR ") "
2477 "Channel (%u) "
2478 "Rssi (%d) "
2479 "RTT (%u) "
2480 "RTT_SD (%u) ",
2481 i,
2482 pData->ap[i].ts,
2483 pData->ap[i].ssid,
2484 MAC_ADDR_ARRAY(pData->ap[i].bssid),
2485 pData->ap[i].channel,
2486 pData->ap[i].rssi,
2487 pData->ap[i].rtt,
2488 pData->ap[i].rtt_sd);
2489 }
2490
2491 if (nla_put_u32(skb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_REQUEST_ID,
2492 pData->requestId) ||
2493 nla_put_u32(skb,
2494 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_NUM_RESULTS_AVAILABLE,
2495 pData->numOfAps)) {
2496 hddLog(VOS_TRACE_LEVEL_ERROR, FL("put fail"));
2497 goto fail;
2498 }
2499 if (pData->numOfAps) {
2500 struct nlattr *aps;
2501
2502 aps = nla_nest_start(skb,
2503 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_LIST);
2504 if (!aps)
2505 goto fail;
2506
2507 for (i = 0; i < pData->numOfAps; i++) {
2508 struct nlattr *ap;
2509
2510 ap = nla_nest_start(skb, i + 1);
2511 if (!ap)
2512 goto fail;
2513
2514 if (nla_put_u64(skb,
2515 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_TIME_STAMP,
2516 pData->ap[i].ts) ||
2517 nla_put(skb,
2518 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_SSID,
2519 sizeof(pData->ap[i].ssid),
2520 pData->ap[i].ssid) ||
2521 nla_put(skb,
2522 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_BSSID,
2523 sizeof(pData->ap[i].bssid),
2524 pData->ap[i].bssid) ||
2525 nla_put_u32(skb,
2526 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_CHANNEL,
2527 pData->ap[i].channel) ||
2528 nla_put_s32(skb,
2529 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_RSSI,
2530 pData->ap[i].rssi) ||
2531 nla_put_u32(skb,
2532 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_RTT,
2533 pData->ap[i].rtt) ||
2534 nla_put_u32(skb,
2535 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_RTT_SD,
2536 pData->ap[i].rtt_sd))
2537 goto fail;
2538
2539 nla_nest_end(skb, ap);
2540 }
2541 nla_nest_end(skb, aps);
2542
2543 if (nla_put_u8(skb,
2544 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_MORE_DATA,
2545 pData->moreData))
2546 goto fail;
2547 }
2548
2549 cfg80211_vendor_event(skb, GFP_KERNEL);
2550 return;
2551
2552fail:
2553 kfree_skb(skb);
2554 return;
2555
2556}
2557static void wlan_hdd_cfg80211_extscan_signif_wifi_change_results_ind(void *ctx,
2558 void *pMsg)
2559{
2560 hdd_context_t *pHddCtx = (hdd_context_t *)ctx;
2561 struct sk_buff *skb = NULL;
2562 tANI_U32 i, j;
2563 tpSirWifiSignificantChangeEvent pData =
2564 (tpSirWifiSignificantChangeEvent) pMsg;
2565
2566 if (wlan_hdd_validate_context(pHddCtx) || !pData) {
2567 hddLog(VOS_TRACE_LEVEL_ERROR, FL("HDD context is not valid "
2568 "or pData(%p) is null"), pData);
2569 return;
2570 }
2571 skb = cfg80211_vendor_event_alloc(pHddCtx->wiphy,
2572 EXTSCAN_EVENT_BUF_SIZE,
2573 QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_SIGNIFICANT_CHANGE_INDEX,
2574 GFP_KERNEL);
2575
2576 if (!skb) {
2577 hddLog(VOS_TRACE_LEVEL_ERROR,
2578 FL("cfg80211_vendor_event_alloc failed"));
2579 return;
2580 }
2581 hddLog(VOS_TRACE_LEVEL_INFO, FL("Entering "));
2582 hddLog(VOS_TRACE_LEVEL_INFO, "Req Id (%u)", pData->requestId);
2583 hddLog(VOS_TRACE_LEVEL_INFO, "total List Size %u ", pData->numSigRssiBss);
2584 hddLog(VOS_TRACE_LEVEL_INFO, " CUrrent List size (%u)",
2585 pData->numSigRssiBss);
2586 hddLog(VOS_TRACE_LEVEL_INFO, "moreData (%u)", pData->moreData);
2587
2588 for (i = 0; i < pData->numSigRssiBss; i++) {
2589 hddLog(VOS_TRACE_LEVEL_INFO , "Rssi List [%d] BSSID: (%pM) Channel %u "
2590 " num RSSI %u ",
2591 i, pData->sigRssiResult[i].bssid,
2592 pData->sigRssiResult[i].channel,
2593 pData->sigRssiResult[i].numRssi);
2594
2595 for (j = 0; j < pData->sigRssiResult[i].numRssi; j++){
2596
2597 hddLog(VOS_TRACE_LEVEL_INFO,
2598 " [%d]",
2599 pData->sigRssiResult[i].rssi[0]);
2600
2601 }
2602 }
2603
2604
2605 if (nla_put_u32(skb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_REQUEST_ID,
2606 pData->requestId) ||
2607 nla_put_u32(skb,
2608 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_NUM_RESULTS_AVAILABLE,
2609 pData->numSigRssiBss)) {
2610 hddLog(VOS_TRACE_LEVEL_ERROR, FL("put fail"));
2611 goto fail;
2612 }
2613
2614 if (pData->numSigRssiBss) {
2615 struct nlattr *aps;
2616 aps = nla_nest_start(skb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_LIST);
2617 if (!aps)
2618 goto fail;
2619 for (i = 0; i < pData->numSigRssiBss; i++) {
2620 struct nlattr *ap;
2621
2622 ap = nla_nest_start(skb, i);
2623 if (!ap)
2624 goto fail;
2625 if (nla_put(skb,
2626 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SIGNIFICANT_CHANGE_RESULT_BSSID,
2627 sizeof(tSirMacAddr), pData->sigRssiResult[i].bssid) ||
2628 nla_put_u32(skb,
2629 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SIGNIFICANT_CHANGE_RESULT_CHANNEL,
2630 pData->sigRssiResult[i].channel) ||
2631 nla_put_u32(skb,
2632 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SIGNIFICANT_CHANGE_RESULT_NUM_RSSI,
2633 pData->sigRssiResult[i].numRssi) ||
2634 nla_put(skb,
2635 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SIGNIFICANT_CHANGE_RESULT_RSSI_LIST,
2636 sizeof(s32) * pData->sigRssiResult[i].numRssi,
2637 pData->sigRssiResult[i].rssi))
2638 goto fail;
2639 nla_nest_end(skb, ap);
2640 }
2641 nla_nest_end(skb, aps);
2642 if (nla_put_u8(skb,
2643 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_MORE_DATA,
2644 pData->moreData))
2645 goto fail;
2646 }
2647 cfg80211_vendor_event(skb, GFP_KERNEL);
2648 return;
2649fail:
2650 kfree_skb(skb);
2651 return;
2652}
2653
2654static void wlan_hdd_cfg80211_extscan_full_scan_result_event(void *ctx,
2655 void *pMsg)
2656{
2657 struct sk_buff *skb;
2658 hdd_context_t *pHddCtx = (hdd_context_t *)ctx;
2659 tpSirWifiFullScanResultEvent pData =
2660 (tpSirWifiFullScanResultEvent) (pMsg);
2661
2662 if (wlan_hdd_validate_context(pHddCtx) || !pData) {
2663 hddLog(VOS_TRACE_LEVEL_ERROR, FL("HDD context is not valid "
2664 "or pData(%p) is null"), pData);
2665 return;
2666 }
2667
2668 skb = cfg80211_vendor_event_alloc(pHddCtx->wiphy,
2669 EXTSCAN_EVENT_BUF_SIZE + NLMSG_HDRLEN,
2670 QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_FULL_SCAN_RESULT_INDEX,
2671 GFP_KERNEL);
2672
2673 if (!skb) {
2674 hddLog(VOS_TRACE_LEVEL_ERROR,
2675 FL("cfg80211_vendor_event_alloc failed"));
2676 return;
2677 }
2678
2679 hddLog(VOS_TRACE_LEVEL_INFO, FL("Entering "));
2680 hddLog(VOS_TRACE_LEVEL_INFO, FL("Req Id (%u)"), pData->requestId);
2681 hddLog(VOS_TRACE_LEVEL_INFO, FL("More Data (%u)"), pData->moreData);
2682 hddLog(VOS_TRACE_LEVEL_INFO, FL("AP Info: Timestamp(0x%llX) "
2683 "Ssid (%s)"
2684 "Bssid (" MAC_ADDRESS_STR ")"
2685 "Channel (%u)"
2686 "Rssi (%d)"
2687 "RTT (%u)"
2688 "RTT_SD (%u)"),
2689 pData->ap.ts,
2690 pData->ap.ssid,
2691 MAC_ADDR_ARRAY(pData->ap.bssid),
2692 pData->ap.channel,
2693 pData->ap.rssi,
2694 pData->ap.rtt,
2695 pData->ap.rtt_sd);
2696 hddLog(VOS_TRACE_LEVEL_INFO, "IE Length (%u)", pData->ieLength);
2697 if (nla_put_u32(skb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_REQUEST_ID,
2698 pData->requestId) ||
2699 nla_put_u64(skb,
2700 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_TIME_STAMP,
2701 pData->ap.ts) ||
2702 nla_put(skb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_SSID,
2703 sizeof(pData->ap.ssid),
2704 pData->ap.ssid) ||
2705 nla_put(skb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_BSSID,
2706 WNI_CFG_BSSID_LEN,
2707 pData->ap.bssid) ||
2708 nla_put_u32(skb,
2709 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_CHANNEL,
2710 pData->ap.channel) ||
2711 nla_put_u32(skb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_RSSI,
2712 pData->ap.rssi) ||
2713 nla_put_u32(skb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_RTT,
2714 pData->ap.rtt) ||
2715 nla_put_u32(skb,
2716 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_RTT_SD,
2717 pData->ap.rtt_sd) ||
2718 nla_put_u16(skb,
2719 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_BEACON_PERIOD,
2720 pData->ap.beaconPeriod) ||
2721 nla_put_u16(skb,
2722 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_CAPABILITY,
2723 pData->ap.capability) ||
2724 nla_put_u32(skb,
2725 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_IE_LENGTH,
2726 pData->ieLength))
2727 {
2728 hddLog(VOS_TRACE_LEVEL_ERROR, FL("nla put fail"));
2729 goto nla_put_failure;
2730 }
2731 if (nla_put(skb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_IE_DATA,
2732 pData->ieLength,
2733 pData->ie))
2734 {
2735 hddLog(VOS_TRACE_LEVEL_ERROR, FL("nla put fail"));
2736 goto nla_put_failure;
2737 }
2738
2739 cfg80211_vendor_event(skb, GFP_KERNEL);
2740 return;
2741
2742nla_put_failure:
2743 kfree_skb(skb);
2744 return;
2745}
2746
2747static void wlan_hdd_cfg80211_extscan_scan_res_available_event(void *ctx,
2748 void *pMsg)
2749{
2750 hdd_context_t *pHddCtx = (hdd_context_t *)ctx;
2751 struct sk_buff *skb = NULL;
2752 tpSirEXTScanResultsAvailableIndParams pData =
2753 (tpSirEXTScanResultsAvailableIndParams) pMsg;
2754
2755 if (wlan_hdd_validate_context(pHddCtx) || !pData) {
2756 hddLog(VOS_TRACE_LEVEL_ERROR, FL("HDD context is not valid "
2757 "or pData(%p) is null"), pData);
2758 return;
2759 }
2760
2761 skb = cfg80211_vendor_event_alloc(pHddCtx->wiphy,
2762 EXTSCAN_EVENT_BUF_SIZE + NLMSG_HDRLEN,
2763 QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_SCAN_RESULTS_AVAILABLE_INDEX,
2764 GFP_KERNEL);
2765
2766 if (!skb) {
2767 hddLog(VOS_TRACE_LEVEL_ERROR,
2768 FL("cfg80211_vendor_event_alloc failed"));
2769 return;
2770 }
2771
2772 hddLog(VOS_TRACE_LEVEL_INFO, FL("Entering "));
2773 hddLog(VOS_TRACE_LEVEL_INFO, "Req Id (%u)", pData->requestId);
2774 hddLog(VOS_TRACE_LEVEL_INFO, "Num results (%u)",
2775 pData->numResultsAvailable);
2776 if (nla_put_u32(skb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_REQUEST_ID,
2777 pData->requestId) ||
2778 nla_put_u32(skb,
2779 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_NUM_RESULTS_AVAILABLE,
2780 pData->numResultsAvailable)) {
2781 hddLog(VOS_TRACE_LEVEL_ERROR, FL("nla put fail"));
2782 goto nla_put_failure;
2783 }
2784
2785 cfg80211_vendor_event(skb, GFP_KERNEL);
2786 return;
2787
2788nla_put_failure:
2789 kfree_skb(skb);
2790 return;
2791}
2792
2793static void wlan_hdd_cfg80211_extscan_scan_progress_event(void *ctx, void *pMsg)
2794{
2795 hdd_context_t *pHddCtx = (hdd_context_t *)ctx;
2796 struct sk_buff *skb = NULL;
2797 tpSirEXTScanProgressIndParams pData =
2798 (tpSirEXTScanProgressIndParams) pMsg;
2799
2800 if (wlan_hdd_validate_context(pHddCtx) || !pData) {
2801 hddLog(VOS_TRACE_LEVEL_ERROR, FL("HDD context is not valid "
2802 "or pData(%p) is null"), pData);
2803 return;
2804 }
2805
2806 skb = cfg80211_vendor_event_alloc(pHddCtx->wiphy,
2807 EXTSCAN_EVENT_BUF_SIZE + NLMSG_HDRLEN,
2808 QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_SCAN_EVENT_INDEX,
2809 GFP_KERNEL);
2810
2811 if (!skb) {
2812 hddLog(VOS_TRACE_LEVEL_ERROR,
2813 FL("cfg80211_vendor_event_alloc failed"));
2814 return;
2815 }
2816 hddLog(VOS_TRACE_LEVEL_INFO, FL("Entering "));
2817 hddLog(VOS_TRACE_LEVEL_INFO, "Scan event type (%u)",
2818 pData->extScanEventType);
2819 hddLog(VOS_TRACE_LEVEL_INFO, "Scan event status (%u)",
2820 pData->status);
2821
2822 if (nla_put_u8(skb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_EVENT_TYPE,
2823 pData->extScanEventType) ||
2824 nla_put_u32(skb,
Dasari Srinivas5a288652014-06-30 17:13:22 +05302825 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_REQUEST_ID,
2826 pData->requestId) ||
2827 nla_put_u32(skb,
Dino Mycle6fb96c12014-06-10 11:52:40 +05302828 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_EVENT_STATUS,
2829 pData->status)) {
2830 hddLog(VOS_TRACE_LEVEL_ERROR, FL("nla put fail"));
2831 goto nla_put_failure;
2832 }
2833
2834 cfg80211_vendor_event(skb, GFP_KERNEL);
2835 return;
2836
2837nla_put_failure:
2838 kfree_skb(skb);
2839 return;
2840}
2841
2842void wlan_hdd_cfg80211_extscan_callback(void *ctx, const tANI_U16 evType,
2843 void *pMsg)
2844{
2845 hdd_context_t *pHddCtx = (hdd_context_t *)ctx;
2846
2847 if (wlan_hdd_validate_context(pHddCtx)) {
2848 hddLog(VOS_TRACE_LEVEL_ERROR, FL("HDD context is not valid"));
2849 return;
2850 }
2851
2852 hddLog(VOS_TRACE_LEVEL_INFO, FL("Rcvd Event (%d)"), evType);
2853
2854
2855 switch(evType) {
2856 case SIR_HAL_EXTSCAN_START_RSP:
2857 wlan_hdd_cfg80211_extscan_start_rsp(ctx, pMsg);
2858 break;
2859
2860 case SIR_HAL_EXTSCAN_STOP_RSP:
2861 wlan_hdd_cfg80211_extscan_stop_rsp(ctx, pMsg);
2862 break;
2863 case SIR_HAL_EXTSCAN_GET_CACHED_RESULTS_RSP:
2864 /* There is no need to send this response to upper layer
2865 Just log the message */
2866 hddLog(VOS_TRACE_LEVEL_INFO,
2867 FL("Rcvd SIR_HAL_EXTSCAN_CACHED_RESULTS_RSP"));
2868 break;
2869 case SIR_HAL_EXTSCAN_SET_BSS_HOTLIST_RSP:
2870 wlan_hdd_cfg80211_extscan_set_bss_hotlist_rsp(ctx, pMsg);
2871 break;
2872
2873 case SIR_HAL_EXTSCAN_RESET_BSS_HOTLIST_RSP:
2874 wlan_hdd_cfg80211_extscan_reset_bss_hotlist_rsp(ctx, pMsg);
2875 break;
2876
2877 case SIR_HAL_EXTSCAN_SET_SIGNF_RSSI_CHANGE_RSP:
2878 wlan_hdd_cfg80211_extscan_set_signf_wifi_change_rsp(ctx, pMsg);
2879 break;
2880
2881 case SIR_HAL_EXTSCAN_RESET_SIGNF_RSSI_CHANGE_RSP:
2882 wlan_hdd_cfg80211_extscan_reset_signf_wifi_change_rsp(ctx, pMsg);
2883 break;
2884 case SIR_HAL_EXTSCAN_GET_CAPABILITIES_RSP:
2885 wlan_hdd_cfg80211_extscan_get_capabilities_ind(ctx, pMsg);
2886 break;
2887 case SIR_HAL_EXTSCAN_PROGRESS_IND:
2888 wlan_hdd_cfg80211_extscan_scan_progress_event(ctx, pMsg);
2889 break;
2890 case SIR_HAL_EXTSCAN_SCAN_AVAILABLE_IND:
2891 wlan_hdd_cfg80211_extscan_scan_res_available_event(ctx, pMsg);
2892 break;
2893 case SIR_HAL_EXTSCAN_SCAN_RESULT_IND:
2894 wlan_hdd_cfg80211_extscan_cached_results_ind(ctx, pMsg);
2895 break;
2896 case SIR_HAL_EXTSCAN_HOTLIST_MATCH_IND:
2897 wlan_hdd_cfg80211_extscan_hotlist_match_ind(ctx, pMsg);
2898 break;
2899 case SIR_HAL_EXTSCAN_SIGNF_WIFI_CHANGE_IND:
2900 wlan_hdd_cfg80211_extscan_signif_wifi_change_results_ind(ctx, pMsg);
2901 break;
2902 case SIR_HAL_EXTSCAN_FULL_SCAN_RESULT_IND:
2903 wlan_hdd_cfg80211_extscan_full_scan_result_event(ctx, pMsg);
2904 break;
2905 default:
2906 hddLog(VOS_TRACE_LEVEL_ERROR, FL("invalid event type %d "), evType);
2907 break;
2908 }
2909}
2910
2911static int wlan_hdd_cfg80211_extscan_get_capabilities(struct wiphy *wiphy,
2912 struct wireless_dev *wdev,
2913 void *data, int dataLen)
2914{
Dino Myclee8843b32014-07-04 14:21:45 +05302915 tSirGetEXTScanCapabilitiesReqParams reqMsg;
Dino Mycle6fb96c12014-06-10 11:52:40 +05302916 struct net_device *dev = wdev->netdev;
2917 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
2918 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
2919 struct nlattr
2920 *tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX + 1];
2921 eHalStatus status;
2922
2923 hddLog(VOS_TRACE_LEVEL_INFO, FL("Entering"));
2924 status = wlan_hdd_validate_context(pHddCtx);
2925 if (0 != status)
2926 {
2927 hddLog(VOS_TRACE_LEVEL_ERROR,
2928 FL("HDD context is not valid"));
2929 return -EINVAL;
2930 }
Dino Myclee8843b32014-07-04 14:21:45 +05302931 /* check the EXTScan Capability */
2932 if ( (TRUE != pHddCtx->cfg_ini->fEnableEXTScan) ||
2933 (TRUE != sme_IsFeatureSupportedByFW(EXTENDED_SCAN)))
2934 {
2935 hddLog(VOS_TRACE_LEVEL_ERROR,
2936 FL("EXTScan not enabled/supported by Firmware"));
2937 return -EINVAL;
2938 }
2939
Dino Mycle6fb96c12014-06-10 11:52:40 +05302940 if (nla_parse(tb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX,
2941 data, dataLen,
2942 wlan_hdd_extscan_config_policy)) {
2943 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Invalid ATTR"));
2944 return -EINVAL;
2945 }
2946
2947 /* Parse and fetch request Id */
2948 if (!tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_REQUEST_ID]) {
2949 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr request id failed"));
2950 return -EINVAL;
2951 }
2952
Dino Mycle6fb96c12014-06-10 11:52:40 +05302953
Dino Myclee8843b32014-07-04 14:21:45 +05302954 reqMsg.requestId = nla_get_u32(
Dino Mycle6fb96c12014-06-10 11:52:40 +05302955 tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_REQUEST_ID]);
Dino Myclee8843b32014-07-04 14:21:45 +05302956 hddLog(VOS_TRACE_LEVEL_INFO, FL("Req Id (%d)"), reqMsg.requestId);
Dino Mycle6fb96c12014-06-10 11:52:40 +05302957
Dino Myclee8843b32014-07-04 14:21:45 +05302958 reqMsg.sessionId = pAdapter->sessionId;
2959 hddLog(VOS_TRACE_LEVEL_INFO, FL("Session Id (%d)"), reqMsg.sessionId);
Dino Mycle6fb96c12014-06-10 11:52:40 +05302960
Dino Myclee8843b32014-07-04 14:21:45 +05302961 status = sme_EXTScanGetCapabilities(pHddCtx->hHal, &reqMsg);
Dino Mycle6fb96c12014-06-10 11:52:40 +05302962 if (!HAL_STATUS_SUCCESS(status)) {
2963 hddLog(VOS_TRACE_LEVEL_ERROR,
2964 FL("sme_EXTScanGetCapabilities failed(err=%d)"), status);
Dino Mycle6fb96c12014-06-10 11:52:40 +05302965 return -EINVAL;
2966 }
2967
2968 return 0;
2969}
2970
2971
2972static int wlan_hdd_cfg80211_extscan_get_cached_results(struct wiphy *wiphy,
2973 struct wireless_dev *wdev,
2974 void *data, int dataLen)
2975{
Dino Myclee8843b32014-07-04 14:21:45 +05302976 tSirEXTScanGetCachedResultsReqParams reqMsg;
Dino Mycle6fb96c12014-06-10 11:52:40 +05302977 struct net_device *dev = wdev->netdev;
2978 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
2979 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
2980 struct nlattr
2981 *tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX + 1];
2982 eHalStatus status;
2983
2984 status = wlan_hdd_validate_context(pHddCtx);
2985 if (0 != status)
2986 {
2987 hddLog(VOS_TRACE_LEVEL_ERROR,
2988 FL("HDD context is not valid"));
2989 return -EINVAL;
2990 }
Dino Myclee8843b32014-07-04 14:21:45 +05302991 /* check the EXTScan Capability */
2992 if ( (TRUE != pHddCtx->cfg_ini->fEnableEXTScan) ||
2993 (TRUE != sme_IsFeatureSupportedByFW(EXTENDED_SCAN)))
2994 {
2995 hddLog(VOS_TRACE_LEVEL_ERROR,
2996 FL("EXTScan not enabled/supported by Firmware"));
2997 return -EINVAL;
2998 }
2999
Dino Mycle6fb96c12014-06-10 11:52:40 +05303000 if (nla_parse(tb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX,
3001 data, dataLen,
3002 wlan_hdd_extscan_config_policy)) {
3003 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Invalid ATTR"));
3004 return -EINVAL;
3005 }
3006 /* Parse and fetch request Id */
3007 if (!tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_REQUEST_ID]) {
3008 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr request id failed"));
3009 return -EINVAL;
3010 }
Dino Mycle6fb96c12014-06-10 11:52:40 +05303011
Dino Myclee8843b32014-07-04 14:21:45 +05303012 reqMsg.requestId = nla_get_u32(
Dino Mycle6fb96c12014-06-10 11:52:40 +05303013 tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_REQUEST_ID]);
3014
Dino Myclee8843b32014-07-04 14:21:45 +05303015 hddLog(VOS_TRACE_LEVEL_INFO, FL("Req Id (%d)"), reqMsg.requestId);
Dino Mycle6fb96c12014-06-10 11:52:40 +05303016
Dino Myclee8843b32014-07-04 14:21:45 +05303017 reqMsg.sessionId = pAdapter->sessionId;
3018 hddLog(VOS_TRACE_LEVEL_INFO, FL("Session Id (%d)"), reqMsg.sessionId);
Dino Mycle6fb96c12014-06-10 11:52:40 +05303019
3020 /* Parse and fetch flush parameter */
3021 if (!tb
3022 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_GET_CACHED_SCAN_RESULTS_CONFIG_PARAM_FLUSH])
3023 {
3024 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr flush failed"));
3025 goto failed;
3026 }
Dino Myclee8843b32014-07-04 14:21:45 +05303027 reqMsg.flush = nla_get_u8(
Dino Mycle6fb96c12014-06-10 11:52:40 +05303028 tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_GET_CACHED_SCAN_RESULTS_CONFIG_PARAM_FLUSH]);
3029
Dino Myclee8843b32014-07-04 14:21:45 +05303030 hddLog(VOS_TRACE_LEVEL_INFO, FL("Flush (%d)"), reqMsg.flush);
Dino Mycle6fb96c12014-06-10 11:52:40 +05303031
Dino Myclee8843b32014-07-04 14:21:45 +05303032 status = sme_getCachedResults(pHddCtx->hHal, &reqMsg);
Dino Mycle6fb96c12014-06-10 11:52:40 +05303033 if (!HAL_STATUS_SUCCESS(status)) {
3034 hddLog(VOS_TRACE_LEVEL_ERROR,
3035 FL("sme_getCachedResults failed(err=%d)"), status);
Dino Mycle6fb96c12014-06-10 11:52:40 +05303036 return -EINVAL;
3037 }
3038 return 0;
3039
3040failed:
Dino Mycle6fb96c12014-06-10 11:52:40 +05303041 return -EINVAL;
3042}
3043
3044static int wlan_hdd_cfg80211_extscan_set_bssid_hotlist(struct wiphy *wiphy,
3045 struct wireless_dev *wdev,
3046 void *data, int dataLen)
3047{
3048 tpSirEXTScanSetBssidHotListReqParams pReqMsg = NULL;
3049 struct net_device *dev = wdev->netdev;
3050 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
3051 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
3052 struct nlattr
3053 *tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX + 1];
3054 struct nlattr
3055 *tb2[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX + 1];
3056 struct nlattr *apTh;
3057 eHalStatus status;
3058 tANI_U8 i = 0;
3059 int rem;
3060
3061 status = wlan_hdd_validate_context(pHddCtx);
3062 if (0 != status)
3063 {
3064 hddLog(VOS_TRACE_LEVEL_ERROR,
3065 FL("HDD context is not valid"));
3066 return -EINVAL;
3067 }
Dino Myclee8843b32014-07-04 14:21:45 +05303068 /* check the EXTScan Capability */
3069 if ( (TRUE != pHddCtx->cfg_ini->fEnableEXTScan) ||
3070 (TRUE != sme_IsFeatureSupportedByFW(EXTENDED_SCAN)))
3071 {
3072 hddLog(VOS_TRACE_LEVEL_ERROR,
3073 FL("EXTScan not enabled/supported by Firmware"));
3074 return -EINVAL;
3075 }
3076
Dino Mycle6fb96c12014-06-10 11:52:40 +05303077 if (nla_parse(tb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX,
3078 data, dataLen,
3079 wlan_hdd_extscan_config_policy)) {
3080 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Invalid ATTR"));
3081 return -EINVAL;
3082 }
3083
3084 /* Parse and fetch request Id */
3085 if (!tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_REQUEST_ID]) {
3086 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr request id failed"));
3087 return -EINVAL;
3088 }
Dino Mycle6fb96c12014-06-10 11:52:40 +05303089 pReqMsg = (tpSirEXTScanSetBssidHotListReqParams)
3090 vos_mem_malloc(sizeof(*pReqMsg));
3091 if (!pReqMsg) {
3092 hddLog(VOS_TRACE_LEVEL_ERROR, FL("vos_mem_malloc failed"));
3093 return -ENOMEM;
3094 }
3095
Dino Myclee8843b32014-07-04 14:21:45 +05303096
Dino Mycle6fb96c12014-06-10 11:52:40 +05303097 pReqMsg->requestId = nla_get_u32(
3098 tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_REQUEST_ID]);
3099 hddLog(VOS_TRACE_LEVEL_INFO, FL("Req Id (%d)"), pReqMsg->requestId);
3100
3101 /* Parse and fetch number of APs */
3102 if (!tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_BSSID_HOTLIST_PARAMS_NUM_AP]) {
3103 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr number of AP failed"));
3104 goto fail;
3105 }
3106
3107 pReqMsg->sessionId = pAdapter->sessionId;
3108 hddLog(VOS_TRACE_LEVEL_INFO, FL("Session Id (%d)"), pReqMsg->sessionId);
3109
3110 pReqMsg->numAp = nla_get_u32(
3111 tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_BSSID_HOTLIST_PARAMS_NUM_AP]);
3112 hddLog(VOS_TRACE_LEVEL_INFO, FL("Number of AP (%d)"), pReqMsg->numAp);
3113
3114 nla_for_each_nested(apTh,
3115 tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_AP_THRESHOLD_PARAM], rem) {
3116 if(nla_parse(tb2, QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX,
3117 nla_data(apTh), nla_len(apTh),
3118 NULL)) {
3119 hddLog(VOS_TRACE_LEVEL_ERROR, FL("nla_parse failed"));
3120 goto fail;
3121 }
3122
3123 /* Parse and fetch MAC address */
3124 if (!tb2[QCA_WLAN_VENDOR_ATTR_EXTSCAN_AP_THRESHOLD_PARAM_BSSID]) {
3125 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr mac address failed"));
3126 goto fail;
3127 }
3128 memcpy(pReqMsg->ap[i].bssid, nla_data(
3129 tb2[QCA_WLAN_VENDOR_ATTR_EXTSCAN_AP_THRESHOLD_PARAM_BSSID]),
3130 sizeof(tSirMacAddr));
3131 hddLog(VOS_TRACE_LEVEL_INFO, FL("BSSID: %pM "), pReqMsg->ap[i].bssid);
3132
3133 /* Parse and fetch low RSSI */
3134 if (!tb2[QCA_WLAN_VENDOR_ATTR_EXTSCAN_AP_THRESHOLD_PARAM_RSSI_LOW]) {
3135 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr low RSSI failed"));
3136 goto fail;
3137 }
3138 pReqMsg->ap[i].low = nla_get_s32(
3139 tb2[QCA_WLAN_VENDOR_ATTR_EXTSCAN_AP_THRESHOLD_PARAM_RSSI_LOW]);
3140 hddLog(VOS_TRACE_LEVEL_INFO, FL("RSSI low (%d)"), pReqMsg->ap[i].low);
3141
3142 /* Parse and fetch high RSSI */
3143 if (!tb2[QCA_WLAN_VENDOR_ATTR_EXTSCAN_AP_THRESHOLD_PARAM_RSSI_HIGH]) {
3144 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr high RSSI failed"));
3145 goto fail;
3146 }
3147 pReqMsg->ap[i].high = nla_get_s32(
3148 tb2[QCA_WLAN_VENDOR_ATTR_EXTSCAN_AP_THRESHOLD_PARAM_RSSI_HIGH]);
3149 hddLog(VOS_TRACE_LEVEL_INFO, FL("RSSI High (%d)"),
3150 pReqMsg->ap[i].high);
3151
3152 /* Parse and fetch channel */
3153 if (!tb2[QCA_WLAN_VENDOR_ATTR_EXTSCAN_AP_THRESHOLD_PARAM_CHANNEL]) {
3154 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr channel failed"));
3155 goto fail;
3156 }
3157 pReqMsg->ap[i].channel = nla_get_u32(
3158 tb2[QCA_WLAN_VENDOR_ATTR_EXTSCAN_AP_THRESHOLD_PARAM_CHANNEL]);
3159 hddLog(VOS_TRACE_LEVEL_INFO,
3160 FL("Channel (%u)"), pReqMsg->ap[i].channel);
3161 i++;
3162 }
3163 status = sme_SetBssHotlist(pHddCtx->hHal, pReqMsg);
3164 if (!HAL_STATUS_SUCCESS(status)) {
3165 hddLog(VOS_TRACE_LEVEL_ERROR,
3166 FL("sme_SetBssHotlist failed(err=%d)"), status);
3167 vos_mem_free(pReqMsg);
3168 return -EINVAL;
3169 }
3170
Dino Myclee8843b32014-07-04 14:21:45 +05303171 vos_mem_free(pReqMsg);
3172
Dino Mycle6fb96c12014-06-10 11:52:40 +05303173 return 0;
3174
3175fail:
3176 vos_mem_free(pReqMsg);
3177 return -EINVAL;
3178}
3179
3180static int wlan_hdd_cfg80211_extscan_set_significant_change(struct wiphy *wiphy,
3181 struct wireless_dev *wdev,
3182 void *data, int dataLen)
3183{
3184 tpSirEXTScanSetSignificantChangeReqParams pReqMsg = NULL;
3185 struct net_device *dev = wdev->netdev;
3186 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
3187 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
3188 struct nlattr
3189 *tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX + 1];
3190 struct nlattr
3191 *tb2[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX + 1];
3192 struct nlattr *apTh;
3193 eHalStatus status;
3194 int i = 0;
3195 int rem;
3196
3197 status = wlan_hdd_validate_context(pHddCtx);
3198 if (0 != status)
3199 {
3200 hddLog(VOS_TRACE_LEVEL_ERROR,
3201 FL("HDD context is not valid"));
3202 return -EINVAL;
3203 }
Dino Myclee8843b32014-07-04 14:21:45 +05303204 /* check the EXTScan Capability */
3205 if ( (TRUE != pHddCtx->cfg_ini->fEnableEXTScan) ||
3206 (TRUE != sme_IsFeatureSupportedByFW(EXTENDED_SCAN)))
3207 {
3208 hddLog(VOS_TRACE_LEVEL_ERROR,
3209 FL("EXTScan not enabled/supported by Firmware"));
3210 return -EINVAL;
3211 }
3212
Dino Mycle6fb96c12014-06-10 11:52:40 +05303213 if (nla_parse(tb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX,
3214 data, dataLen,
3215 wlan_hdd_extscan_config_policy)) {
3216 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Invalid ATTR"));
3217 return -EINVAL;
3218 }
3219
3220 /* Parse and fetch request Id */
3221 if (!tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_REQUEST_ID]) {
3222 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr request id failed"));
3223 return -EINVAL;
3224 }
Dino Mycle6fb96c12014-06-10 11:52:40 +05303225 pReqMsg = (tpSirEXTScanSetSignificantChangeReqParams)
Dino Myclee8843b32014-07-04 14:21:45 +05303226 vos_mem_malloc(sizeof(*pReqMsg));
Dino Mycle6fb96c12014-06-10 11:52:40 +05303227 if (!pReqMsg) {
Dino Myclee8843b32014-07-04 14:21:45 +05303228 hddLog(VOS_TRACE_LEVEL_ERROR, FL("vos_mem_malloc failed"));
3229 return -ENOMEM;
Dino Mycle6fb96c12014-06-10 11:52:40 +05303230 }
3231
Dino Myclee8843b32014-07-04 14:21:45 +05303232
3233
Dino Mycle6fb96c12014-06-10 11:52:40 +05303234 pReqMsg->requestId = nla_get_u32(
3235 tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_REQUEST_ID]);
3236 hddLog(VOS_TRACE_LEVEL_INFO, FL("Req Id (%d)"), pReqMsg->requestId);
3237
3238 /* Parse and fetch RSSI sample size */
3239 if (!tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SIGNIFICANT_CHANGE_PARAMS_RSSI_SAMPLE_SIZE])
3240 {
3241 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr RSSI sample size failed"));
3242 goto fail;
3243 }
3244 pReqMsg->rssiSampleSize = nla_get_u32(
3245 tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SIGNIFICANT_CHANGE_PARAMS_RSSI_SAMPLE_SIZE]);
3246 hddLog(VOS_TRACE_LEVEL_INFO,
3247 FL("RSSI sample size (%u)"), pReqMsg->rssiSampleSize);
3248
3249 /* Parse and fetch lost AP sample size */
3250 if (!tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SIGNIFICANT_CHANGE_PARAMS_LOST_AP_SAMPLE_SIZE])
3251 {
3252 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr lost AP sample size failed"));
3253 goto fail;
3254 }
3255 pReqMsg->lostApSampleSize = nla_get_u32(
3256 tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SIGNIFICANT_CHANGE_PARAMS_LOST_AP_SAMPLE_SIZE]);
3257 hddLog(VOS_TRACE_LEVEL_INFO,
3258 FL("Lost AP sample size (%u)"), pReqMsg->lostApSampleSize);
3259 /* Parse and fetch minimum Breaching */
3260 if (!tb
3261 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_SIGNIFICANT_CHANGE_PARAMS_MIN_BREACHING]) {
3262 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr minBreaching failed"));
3263 goto fail;
3264 }
3265 pReqMsg->minBreaching = nla_get_u32(
3266 tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SIGNIFICANT_CHANGE_PARAMS_MIN_BREACHING]);
3267 hddLog(VOS_TRACE_LEVEL_INFO, FL(" Breaching (%d)"), pReqMsg->minBreaching);
3268
3269 /* Parse and fetch number of APs */
3270 if (!tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SIGNIFICANT_CHANGE_PARAMS_NUM_AP]) {
3271 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr number of AP failed"));
3272 goto fail;
3273 }
3274 pReqMsg->numAp = nla_get_u32(
3275 tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SIGNIFICANT_CHANGE_PARAMS_NUM_AP]);
3276 hddLog(VOS_TRACE_LEVEL_INFO, FL("Number of AP (%d)"), pReqMsg->numAp);
3277
3278 pReqMsg->sessionId = pAdapter->sessionId;
3279 hddLog(VOS_TRACE_LEVEL_INFO, FL("Session Id (%d)"), pReqMsg->sessionId);
3280
3281 nla_for_each_nested(apTh,
3282 tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_AP_THRESHOLD_PARAM], rem) {
3283 if(nla_parse(tb2,
3284 QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX,
3285 nla_data(apTh), nla_len(apTh),
3286 NULL)) {
3287 hddLog(VOS_TRACE_LEVEL_ERROR, FL("nla_parse failed"));
3288 goto fail;
3289 }
3290
3291 /* Parse and fetch MAC address */
3292 if (!tb2[QCA_WLAN_VENDOR_ATTR_EXTSCAN_AP_THRESHOLD_PARAM_BSSID]) {
3293 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr mac address failed"));
3294 goto fail;
3295 }
3296 memcpy(pReqMsg->ap[i].bssid, nla_data(
3297 tb2[QCA_WLAN_VENDOR_ATTR_EXTSCAN_AP_THRESHOLD_PARAM_BSSID]),
3298 sizeof(tSirMacAddr));
3299
3300 /* Parse and fetch low RSSI */
3301 if (!tb2[QCA_WLAN_VENDOR_ATTR_EXTSCAN_AP_THRESHOLD_PARAM_RSSI_LOW]) {
3302 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr low RSSI failed"));
3303 goto fail;
3304 }
3305 pReqMsg->ap[i].low = nla_get_s32(
3306 tb2[QCA_WLAN_VENDOR_ATTR_EXTSCAN_AP_THRESHOLD_PARAM_RSSI_LOW]);
3307 hddLog(VOS_TRACE_LEVEL_INFO, FL("RSSI low (%d)"), pReqMsg->ap[i].low);
3308
3309 /* Parse and fetch high RSSI */
3310 if (!tb2[QCA_WLAN_VENDOR_ATTR_EXTSCAN_AP_THRESHOLD_PARAM_RSSI_HIGH]) {
3311 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr high RSSI failed"));
3312 goto fail;
3313 }
3314 pReqMsg->ap[i].high = nla_get_s32(
3315 tb2[QCA_WLAN_VENDOR_ATTR_EXTSCAN_AP_THRESHOLD_PARAM_RSSI_HIGH]);
3316 hddLog(VOS_TRACE_LEVEL_INFO,
3317 FL("RSSI High (%d)"), pReqMsg->ap[i].high);
3318
3319 /* Parse and fetch channel */
3320 if (!tb2[QCA_WLAN_VENDOR_ATTR_EXTSCAN_AP_THRESHOLD_PARAM_CHANNEL]) {
3321 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr channel failed"));
3322 goto fail;
3323 }
3324 pReqMsg->ap[i].channel = nla_get_u32(
3325 tb2[QCA_WLAN_VENDOR_ATTR_EXTSCAN_AP_THRESHOLD_PARAM_CHANNEL]);
3326 hddLog(VOS_TRACE_LEVEL_INFO,
3327 FL("Channel (%u)"), pReqMsg->ap[i].channel);
3328 i++;
3329 }
3330
3331 status = sme_SetSignificantChange(pHddCtx->hHal, pReqMsg);
3332 if (!HAL_STATUS_SUCCESS(status)) {
3333 hddLog(VOS_TRACE_LEVEL_ERROR,
3334 FL("sme_SetSignificantChange failed(err=%d)"), status);
3335 vos_mem_free(pReqMsg);
3336 return -EINVAL;
3337 }
Dino Myclee8843b32014-07-04 14:21:45 +05303338 vos_mem_free(pReqMsg);
Dino Mycle6fb96c12014-06-10 11:52:40 +05303339 hddLog(VOS_TRACE_LEVEL_ERROR, FL(" Exiting"));
3340 return 0;
3341
3342fail:
3343 vos_mem_free(pReqMsg);
3344 return -EINVAL;
3345}
3346
3347static int wlan_hdd_cfg80211_extscan_get_valid_channels(struct wiphy *wiphy,
3348 struct wireless_dev *wdev,
3349 void *data, int dataLen)
3350{
3351 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
3352 tANI_U32 ChannelList[WNI_CFG_VALID_CHANNEL_LIST_LEN] = {0};
3353 tANI_U8 numChannels = 0;
3354 struct nlattr *tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX + 1];
3355 tANI_U32 requestId;
3356 tWifiBand wifiBand;
3357 eHalStatus status;
3358 struct sk_buff *replySkb;
3359 tANI_U8 i;
3360
3361 hddLog(VOS_TRACE_LEVEL_INFO, FL("Entering"));
3362 status = wlan_hdd_validate_context(pHddCtx);
3363 if (0 != status)
3364 {
3365 hddLog(VOS_TRACE_LEVEL_ERROR,
3366 FL("HDD context is not valid"));
3367 return -EINVAL;
3368 }
Dino Myclee8843b32014-07-04 14:21:45 +05303369 /* check the EXTScan Capability */
3370 if ( (TRUE != pHddCtx->cfg_ini->fEnableEXTScan) ||
3371 (TRUE != sme_IsFeatureSupportedByFW(EXTENDED_SCAN)))
3372 {
3373 hddLog(VOS_TRACE_LEVEL_ERROR,
3374 FL("EXTScan not enabled/supported by Firmware"));
3375 return -EINVAL;
3376 }
3377
Dino Mycle6fb96c12014-06-10 11:52:40 +05303378 if (nla_parse(tb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX,
3379 data, dataLen,
3380 wlan_hdd_extscan_config_policy)) {
3381 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Invalid ATTR"));
3382 return -EINVAL;
3383 }
3384
3385 /* Parse and fetch request Id */
3386 if (!tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_REQUEST_ID]) {
3387 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr request id failed"));
3388 return -EINVAL;
3389 }
3390 requestId = nla_get_u32(
3391 tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_REQUEST_ID]);
3392 hddLog(VOS_TRACE_LEVEL_INFO, FL("Req Id (%d)"), requestId);
3393
3394 /* Parse and fetch wifi band */
3395 if (!tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_GET_VALID_CHANNELS_CONFIG_PARAM_WIFI_BAND])
3396 {
3397 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr wifi band failed"));
3398 return -EINVAL;
3399 }
3400 wifiBand = nla_get_u32(
3401 tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_GET_VALID_CHANNELS_CONFIG_PARAM_WIFI_BAND]);
3402 hddLog(VOS_TRACE_LEVEL_INFO, FL("Wifi band (%d)"), wifiBand);
3403
3404 status = sme_GetValidChannelsByBand((tHalHandle)(pHddCtx->hHal),
3405 wifiBand, ChannelList,
3406 &numChannels);
3407 if (eHAL_STATUS_SUCCESS != status) {
3408 hddLog(VOS_TRACE_LEVEL_ERROR,
3409 FL("sme_GetValidChannelsByBand failed (err=%d)"), status);
3410 return -EINVAL;
3411 }
3412 hddLog(VOS_TRACE_LEVEL_INFO, FL("Number of channels (%d)"), numChannels);
3413 for (i = 0; i < numChannels; i++)
3414 hddLog(VOS_TRACE_LEVEL_INFO, "Channel: %u ", ChannelList[i]);
3415
3416 replySkb = cfg80211_vendor_cmd_alloc_reply_skb(wiphy, sizeof(u32) +
3417 sizeof(u32) * numChannels +
3418 NLMSG_HDRLEN);
3419
3420 if (!replySkb) {
3421 hddLog(VOS_TRACE_LEVEL_ERROR,
3422 FL("valid channels: buffer alloc fail"));
3423 return -EINVAL;
3424 }
3425 if (nla_put_u32(replySkb,
3426 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_NUM_CHANNELS,
3427 numChannels) ||
3428 nla_put(replySkb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_CHANNELS,
3429 sizeof(u32) * numChannels, ChannelList)) {
3430
3431 hddLog(VOS_TRACE_LEVEL_ERROR, FL("nla put fail"));
3432 kfree_skb(replySkb);
3433 return -EINVAL;
3434 }
3435
3436 return cfg80211_vendor_cmd_reply(replySkb);
3437}
3438
3439static int wlan_hdd_cfg80211_extscan_start(struct wiphy *wiphy,
3440 struct wireless_dev *wdev,
3441 void *data, int dataLen)
3442{
Dino Myclee8843b32014-07-04 14:21:45 +05303443 tpSirEXTScanStartReqParams pReqMsg = NULL;
Dino Mycle6fb96c12014-06-10 11:52:40 +05303444 struct net_device *dev = wdev->netdev;
3445 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
3446 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
3447 struct nlattr *tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX + 1];
3448 struct nlattr *bucket[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX + 1];
3449 struct nlattr *channel[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX + 1];
3450 struct nlattr *buckets;
3451 struct nlattr *channels;
3452 int rem1;
3453 int rem2;
3454 eHalStatus status;
3455 tANI_U8 bktIndex;
3456 tANI_U32 i = 0, j = 0;
3457
3458 status = wlan_hdd_validate_context(pHddCtx);
3459 if (0 != status)
3460 {
3461 hddLog(VOS_TRACE_LEVEL_ERROR,
3462 FL("HDD context is not valid"));
3463 return -EINVAL;
3464 }
Dino Myclee8843b32014-07-04 14:21:45 +05303465 /* check the EXTScan Capability */
3466 if ( (TRUE != pHddCtx->cfg_ini->fEnableEXTScan) ||
3467 (TRUE != sme_IsFeatureSupportedByFW(EXTENDED_SCAN)))
3468 {
3469 hddLog(VOS_TRACE_LEVEL_ERROR,
3470 FL("EXTScan not enabled/supported by Firmware"));
3471 return -EINVAL;
3472 }
3473
Dino Mycle6fb96c12014-06-10 11:52:40 +05303474 if (nla_parse(tb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX,
3475 data, dataLen,
3476 wlan_hdd_extscan_config_policy)) {
3477 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Invalid ATTR"));
3478 return -EINVAL;
3479 }
3480
3481 /* Parse and fetch request Id */
3482 if (!tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_REQUEST_ID]) {
3483 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr request id failed"));
3484 return -EINVAL;
3485 }
3486
Dino Myclee8843b32014-07-04 14:21:45 +05303487 pReqMsg = (tpSirEXTScanStartReqParams)
3488 vos_mem_malloc(sizeof(*pReqMsg));
Dino Mycle6fb96c12014-06-10 11:52:40 +05303489 if (!pReqMsg) {
Dino Myclee8843b32014-07-04 14:21:45 +05303490 hddLog(VOS_TRACE_LEVEL_ERROR, FL("vos_mem_malloc failed"));
3491 return -ENOMEM;
Dino Mycle6fb96c12014-06-10 11:52:40 +05303492 }
3493
3494 pReqMsg->requestId = nla_get_u32(
3495 tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_REQUEST_ID]);
3496 hddLog(VOS_TRACE_LEVEL_INFO, FL("Req Id (%d)"), pReqMsg->requestId);
3497
3498 pReqMsg->sessionId = pAdapter->sessionId;
3499 hddLog(VOS_TRACE_LEVEL_INFO, FL("Session Id (%d)"), pReqMsg->sessionId);
3500
3501 /* Parse and fetch base period */
3502 if (!tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SCAN_CMD_PARAMS_BASE_PERIOD]) {
3503 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr base period failed"));
3504 goto fail;
3505 }
3506 pReqMsg->basePeriod = nla_get_u32(
3507 tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SCAN_CMD_PARAMS_BASE_PERIOD]);
3508 hddLog(VOS_TRACE_LEVEL_INFO, FL("Base Period (%d)"),
3509 pReqMsg->basePeriod);
3510
3511 /* Parse and fetch max AP per scan */
3512 if (!tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SCAN_CMD_PARAMS_MAX_AP_PER_SCAN]) {
3513 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr max_ap_per_scan failed"));
3514 goto fail;
3515 }
3516 pReqMsg->maxAPperScan = nla_get_u32(
3517 tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SCAN_CMD_PARAMS_MAX_AP_PER_SCAN]);
3518 hddLog(VOS_TRACE_LEVEL_INFO, FL("Max AP per Scan (%d)"),
3519 pReqMsg->maxAPperScan);
3520
3521 /* Parse and fetch report threshold */
3522 if (!tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SCAN_CMD_PARAMS_REPORT_THRESHOLD]) {
3523 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr report_threshold failed"));
3524 goto fail;
3525 }
3526 pReqMsg->reportThreshold = nla_get_u8(
3527 tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SCAN_CMD_PARAMS_REPORT_THRESHOLD]);
3528 hddLog(VOS_TRACE_LEVEL_INFO, FL("Report Threshold (%d)"),
3529 pReqMsg->reportThreshold);
3530
3531 /* Parse and fetch number of buckets */
3532 if (!tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SCAN_CMD_PARAMS_NUM_BUCKETS]) {
3533 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr number of buckets failed"));
3534 goto fail;
3535 }
3536 pReqMsg->numBuckets = nla_get_u8(
3537 tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SCAN_CMD_PARAMS_NUM_BUCKETS]);
3538 if (pReqMsg->numBuckets > WLAN_EXTSCAN_MAX_BUCKETS) {
3539 hddLog(VOS_TRACE_LEVEL_WARN, FL("Exceeded MAX number of buckets "
3540 "Setting numBuckets to %u"), WLAN_EXTSCAN_MAX_BUCKETS);
3541 pReqMsg->numBuckets = WLAN_EXTSCAN_MAX_BUCKETS;
3542 }
3543 hddLog(VOS_TRACE_LEVEL_INFO, FL("Number of Buckets (%d)"),
3544 pReqMsg->numBuckets);
3545 if (!tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC]) {
3546 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr bucket spec failed"));
3547 goto fail;
3548 }
3549
3550 nla_for_each_nested(buckets,
3551 tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC], rem1) {
3552 if(nla_parse(bucket,
3553 QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX,
3554 nla_data(buckets), nla_len(buckets), NULL)) { //policy
3555 hddLog(VOS_TRACE_LEVEL_ERROR, FL("nla_parse failed"));
3556 goto fail;
3557 }
3558
3559 /* Parse and fetch bucket spec */
3560 if (!bucket[QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_INDEX]) {
3561 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr bucket index failed"));
3562 goto fail;
3563 }
3564 bktIndex = nla_get_u8(
3565 bucket[QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_INDEX]);
3566 hddLog(VOS_TRACE_LEVEL_INFO, FL("Bucket spec Index (%d)"), bktIndex);
3567 pReqMsg->buckets[bktIndex].bucket = bktIndex;
3568
3569 /* Parse and fetch wifi band */
3570 if (!bucket[QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_BAND]) {
3571 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr wifi band failed"));
3572 goto fail;
3573 }
3574 pReqMsg->buckets[bktIndex].band = nla_get_u8(
3575 bucket[QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_BAND]);
3576 hddLog(VOS_TRACE_LEVEL_INFO, FL("Wifi band (%d)"),
3577 pReqMsg->buckets[bktIndex].band);
3578
3579 /* Parse and fetch period */
3580 if (!bucket[QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_PERIOD]) {
3581 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr period failed"));
3582 goto fail;
3583 }
3584 pReqMsg->buckets[bktIndex].period = nla_get_u32(
3585 bucket[QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_PERIOD]);
3586 hddLog(VOS_TRACE_LEVEL_INFO, FL("period (%d)"),
3587 pReqMsg->buckets[bktIndex].period);
3588
3589 /* Parse and fetch report events */
3590 if (!bucket[QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_REPORT_EVENTS]) {
3591 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr report events failed"));
3592 goto fail;
3593 }
3594 pReqMsg->buckets[bktIndex].reportEvents = nla_get_u8(
3595 bucket[QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_REPORT_EVENTS]);
3596 hddLog(VOS_TRACE_LEVEL_INFO, FL("report events (%d)"),
3597 pReqMsg->buckets[bktIndex].reportEvents);
3598
3599 /* Parse and fetch number of channels */
3600 if (!bucket[QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_NUM_CHANNEL_SPECS]) {
3601 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr num channels failed"));
3602 goto fail;
3603 }
3604 pReqMsg->buckets[bktIndex].numChannels = nla_get_u32(
3605 bucket[QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_NUM_CHANNEL_SPECS]);
3606 hddLog(VOS_TRACE_LEVEL_INFO, FL("num channels (%d)"),
3607 pReqMsg->buckets[bktIndex].numChannels);
3608
3609 if (!bucket[QCA_WLAN_VENDOR_ATTR_EXTSCAN_CHANNEL_SPEC]) {
3610 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr channel spec failed"));
3611 goto fail;
3612 }
3613
3614 j = 0;
3615 nla_for_each_nested(channels,
3616 bucket[QCA_WLAN_VENDOR_ATTR_EXTSCAN_CHANNEL_SPEC], rem2) {
3617 if(nla_parse(channel,
3618 QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX,
3619 nla_data(channels), nla_len(channels),
3620 NULL)) { //wlan_hdd_extscan_config_policy here
3621 hddLog(VOS_TRACE_LEVEL_ERROR, FL("nla_parse failed"));
3622 goto fail;
3623 }
3624
3625 /* Parse and fetch channel */
3626 if (!channel[QCA_WLAN_VENDOR_ATTR_EXTSCAN_CHANNEL_SPEC_CHANNEL]) {
3627 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr channel failed"));
3628 goto fail;
3629 }
3630 pReqMsg->buckets[bktIndex].channels[j].channel = nla_get_u32(
3631 channel[QCA_WLAN_VENDOR_ATTR_EXTSCAN_CHANNEL_SPEC_CHANNEL]);
3632 hddLog(VOS_TRACE_LEVEL_INFO, FL("channel (%u)"),
3633 pReqMsg->buckets[bktIndex].channels[j].channel);
3634
3635 /* Parse and fetch dwell time */
3636 if (!channel[QCA_WLAN_VENDOR_ATTR_EXTSCAN_CHANNEL_SPEC_DWELL_TIME]) {
3637 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr dwelltime failed"));
3638 goto fail;
3639 }
3640 pReqMsg->buckets[bktIndex].channels[j].dwellTimeMs = nla_get_u32(
3641 channel[QCA_WLAN_VENDOR_ATTR_EXTSCAN_CHANNEL_SPEC_DWELL_TIME]);
3642 hddLog(VOS_TRACE_LEVEL_INFO, FL("Dwell time (%u ms)"),
3643 pReqMsg->buckets[bktIndex].channels[j].dwellTimeMs);
3644
3645 /* Parse and fetch channel spec passive */
3646 if (!channel[QCA_WLAN_VENDOR_ATTR_EXTSCAN_CHANNEL_SPEC_PASSIVE]) {
3647 hddLog(VOS_TRACE_LEVEL_ERROR,
3648 FL("attr channel spec passive failed"));
3649 goto fail;
3650 }
3651 pReqMsg->buckets[bktIndex].channels[j].passive = nla_get_u8(
3652 channel[QCA_WLAN_VENDOR_ATTR_EXTSCAN_CHANNEL_SPEC_PASSIVE]);
3653 hddLog(VOS_TRACE_LEVEL_INFO, FL("Chnl spec passive (%u)"),
3654 pReqMsg->buckets[bktIndex].channels[j].passive);
3655 j++;
3656 }
3657 i++;
3658 }
3659 status = sme_EXTScanStart(pHddCtx->hHal, pReqMsg);
3660 if (!HAL_STATUS_SUCCESS(status)) {
3661 hddLog(VOS_TRACE_LEVEL_ERROR,
3662 FL("sme_EXTScanStart failed(err=%d)"), status);
3663 vos_mem_free(pReqMsg);
3664 return -EINVAL;
3665 }
3666
Dino Myclee8843b32014-07-04 14:21:45 +05303667 vos_mem_free(pReqMsg);
Dino Mycle6fb96c12014-06-10 11:52:40 +05303668 return 0;
3669
3670fail:
3671 vos_mem_free(pReqMsg);
3672 return -EINVAL;
3673}
3674
3675static int wlan_hdd_cfg80211_extscan_stop(struct wiphy *wiphy,
3676 struct wireless_dev *wdev,
3677 void *data, int dataLen)
3678{
Dino Myclee8843b32014-07-04 14:21:45 +05303679 tSirEXTScanStopReqParams reqMsg;
Dino Mycle6fb96c12014-06-10 11:52:40 +05303680 struct net_device *dev = wdev->netdev;
3681 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
3682 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
3683 struct nlattr *tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX + 1];
3684 eHalStatus status;
3685
3686 status = wlan_hdd_validate_context(pHddCtx);
3687 if (0 != status)
3688 {
3689 hddLog(VOS_TRACE_LEVEL_ERROR,
3690 FL("HDD context is not valid"));
3691 return -EINVAL;
3692 }
Dino Myclee8843b32014-07-04 14:21:45 +05303693 /* check the EXTScan Capability */
3694 if ( (TRUE != pHddCtx->cfg_ini->fEnableEXTScan) ||
3695 (TRUE != sme_IsFeatureSupportedByFW(EXTENDED_SCAN)))
3696 {
3697 hddLog(VOS_TRACE_LEVEL_ERROR,
3698 FL("EXTScan not enabled/supported by Firmware"));
3699 return -EINVAL;
3700 }
3701
Dino Mycle6fb96c12014-06-10 11:52:40 +05303702 if (nla_parse(tb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX,
3703 data, dataLen,
3704 wlan_hdd_extscan_config_policy)) {
3705 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Invalid ATTR"));
3706 return -EINVAL;
3707 }
3708
3709 /* Parse and fetch request Id */
3710 if (!tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_REQUEST_ID]) {
3711 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr request id failed"));
3712 return -EINVAL;
3713 }
3714
Dino Myclee8843b32014-07-04 14:21:45 +05303715 reqMsg.requestId = nla_get_u32(
Dino Mycle6fb96c12014-06-10 11:52:40 +05303716 tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_REQUEST_ID]);
Dino Myclee8843b32014-07-04 14:21:45 +05303717 hddLog(VOS_TRACE_LEVEL_INFO, FL("Req Id (%d)"), reqMsg.requestId);
Dino Mycle6fb96c12014-06-10 11:52:40 +05303718
Dino Myclee8843b32014-07-04 14:21:45 +05303719 reqMsg.sessionId = pAdapter->sessionId;
3720 hddLog(VOS_TRACE_LEVEL_INFO, FL("Session Id (%d)"), reqMsg.sessionId);
Dino Mycle6fb96c12014-06-10 11:52:40 +05303721
Dino Myclee8843b32014-07-04 14:21:45 +05303722 status = sme_EXTScanStop(pHddCtx->hHal, &reqMsg);
Dino Mycle6fb96c12014-06-10 11:52:40 +05303723 if (!HAL_STATUS_SUCCESS(status)) {
3724 hddLog(VOS_TRACE_LEVEL_ERROR,
3725 FL("sme_EXTScanStop failed(err=%d)"), status);
Dino Mycle6fb96c12014-06-10 11:52:40 +05303726 return -EINVAL;
3727 }
3728
3729 return 0;
3730}
3731
3732static int wlan_hdd_cfg80211_extscan_reset_bssid_hotlist(struct wiphy *wiphy,
3733 struct wireless_dev *wdev,
3734 void *data, int dataLen)
3735{
Dino Myclee8843b32014-07-04 14:21:45 +05303736 tSirEXTScanResetBssidHotlistReqParams reqMsg;
Dino Mycle6fb96c12014-06-10 11:52:40 +05303737 struct net_device *dev = wdev->netdev;
3738 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
3739 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
3740 struct nlattr *tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX + 1];
3741 eHalStatus status;
3742
3743 status = wlan_hdd_validate_context(pHddCtx);
3744 if (0 != status)
3745 {
3746 hddLog(VOS_TRACE_LEVEL_ERROR,
3747 FL("HDD context is not valid"));
3748 return -EINVAL;
3749 }
Dino Myclee8843b32014-07-04 14:21:45 +05303750 /* check the EXTScan Capability */
3751 if ( (TRUE != pHddCtx->cfg_ini->fEnableEXTScan) ||
3752 (TRUE != sme_IsFeatureSupportedByFW(EXTENDED_SCAN)))
3753 {
3754 hddLog(VOS_TRACE_LEVEL_ERROR,
3755 FL("EXTScan not enabled/supported by Firmware"));
3756 return -EINVAL;
3757 }
3758
Dino Mycle6fb96c12014-06-10 11:52:40 +05303759 if (nla_parse(tb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX,
3760 data, dataLen,
3761 wlan_hdd_extscan_config_policy)) {
3762 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Invalid ATTR"));
3763 return -EINVAL;
3764 }
3765
3766 /* Parse and fetch request Id */
3767 if (!tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_REQUEST_ID]) {
3768 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr request id failed"));
3769 return -EINVAL;
3770 }
3771
Dino Myclee8843b32014-07-04 14:21:45 +05303772 reqMsg.requestId = nla_get_u32(
Dino Mycle6fb96c12014-06-10 11:52:40 +05303773 tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_REQUEST_ID]);
Dino Myclee8843b32014-07-04 14:21:45 +05303774 hddLog(VOS_TRACE_LEVEL_INFO, FL("Req Id (%d)"), reqMsg.requestId);
Dino Mycle6fb96c12014-06-10 11:52:40 +05303775
Dino Myclee8843b32014-07-04 14:21:45 +05303776 reqMsg.sessionId = pAdapter->sessionId;
3777 hddLog(VOS_TRACE_LEVEL_INFO, FL("Session Id (%d)"), reqMsg.sessionId);
Dino Mycle6fb96c12014-06-10 11:52:40 +05303778
Dino Myclee8843b32014-07-04 14:21:45 +05303779 status = sme_ResetBssHotlist(pHddCtx->hHal, &reqMsg);
Dino Mycle6fb96c12014-06-10 11:52:40 +05303780 if (!HAL_STATUS_SUCCESS(status)) {
3781 hddLog(VOS_TRACE_LEVEL_ERROR,
3782 FL("sme_ResetBssHotlist failed(err=%d)"), status);
Dino Mycle6fb96c12014-06-10 11:52:40 +05303783 return -EINVAL;
3784 }
3785
3786 return 0;
3787}
3788
3789static int wlan_hdd_cfg80211_extscan_reset_significant_change(
3790 struct wiphy *wiphy,
3791 struct wireless_dev *wdev,
3792 void *data, int dataLen)
3793{
Dino Myclee8843b32014-07-04 14:21:45 +05303794 tSirEXTScanResetSignificantChangeReqParams reqMsg;
Dino Mycle6fb96c12014-06-10 11:52:40 +05303795 struct net_device *dev = wdev->netdev;
3796 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
3797 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
3798 struct nlattr *tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX + 1];
3799 eHalStatus status;
3800
3801 hddLog(VOS_TRACE_LEVEL_INFO, FL(" Entering"));
3802 status = wlan_hdd_validate_context(pHddCtx);
3803 if (0 != status)
3804 {
3805 hddLog(VOS_TRACE_LEVEL_ERROR,
3806 FL("HDD context is not valid"));
3807 return -EINVAL;
3808 }
Dino Myclee8843b32014-07-04 14:21:45 +05303809 /* check the EXTScan Capability */
3810 if ( (TRUE != pHddCtx->cfg_ini->fEnableEXTScan) ||
3811 (TRUE != sme_IsFeatureSupportedByFW(EXTENDED_SCAN)))
3812 {
3813 hddLog(VOS_TRACE_LEVEL_ERROR,
3814 FL("EXTScan not enabled/supported by Firmware"));
3815 return -EINVAL;
3816 }
3817
Dino Mycle6fb96c12014-06-10 11:52:40 +05303818 if (nla_parse(tb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX,
3819 data, dataLen,
3820 wlan_hdd_extscan_config_policy)) {
3821 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Invalid ATTR"));
3822 return -EINVAL;
3823 }
3824
3825 /* Parse and fetch request Id */
3826 if (!tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_REQUEST_ID]) {
3827 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr request id failed"));
3828 return -EINVAL;
3829 }
3830
Dino Mycle6fb96c12014-06-10 11:52:40 +05303831
Dino Myclee8843b32014-07-04 14:21:45 +05303832 reqMsg.requestId = nla_get_u32(
Dino Mycle6fb96c12014-06-10 11:52:40 +05303833 tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_REQUEST_ID]);
Dino Myclee8843b32014-07-04 14:21:45 +05303834 hddLog(VOS_TRACE_LEVEL_INFO, FL("Req Id (%d)"), reqMsg.requestId);
Dino Mycle6fb96c12014-06-10 11:52:40 +05303835
Dino Myclee8843b32014-07-04 14:21:45 +05303836 reqMsg.sessionId = pAdapter->sessionId;
3837 hddLog(VOS_TRACE_LEVEL_INFO, FL("Session Id (%d)"), reqMsg.sessionId);
Dino Mycle6fb96c12014-06-10 11:52:40 +05303838
Dino Myclee8843b32014-07-04 14:21:45 +05303839 status = sme_ResetSignificantChange(pHddCtx->hHal, &reqMsg);
Dino Mycle6fb96c12014-06-10 11:52:40 +05303840 if (!HAL_STATUS_SUCCESS(status)) {
3841 hddLog(VOS_TRACE_LEVEL_ERROR,
3842 FL("sme_ResetSignificantChange failed(err=%d)"), status);
Dino Mycle6fb96c12014-06-10 11:52:40 +05303843 return -EINVAL;
3844 }
3845
3846 hddLog(VOS_TRACE_LEVEL_ERROR, FL(" Exiting"));
3847 return 0;
3848}
3849
3850#endif /* WLAN_FEATURE_EXTSCAN */
3851
Atul Mittal115287b2014-07-08 13:26:33 +05303852/*EXT TDLS*/
3853static const struct nla_policy
3854wlan_hdd_tdls_config_enable_policy[QCA_WLAN_VENDOR_ATTR_TDLS_ENABLE_MAX +1] =
3855{
3856 [QCA_WLAN_VENDOR_ATTR_TDLS_ENABLE_MAC_ADDR] = {.type = NLA_UNSPEC },
3857 [QCA_WLAN_VENDOR_ATTR_TDLS_ENABLE_CHANNEL] = {.type = NLA_S32 },
3858 [QCA_WLAN_VENDOR_ATTR_TDLS_ENABLE_GLOBAL_OPERATING_CLASS] =
3859 {.type = NLA_S32 },
3860 [QCA_WLAN_VENDOR_ATTR_TDLS_ENABLE_MAX_LATENCY_MS] = {.type = NLA_S32 },
3861 [QCA_WLAN_VENDOR_ATTR_TDLS_ENABLE_MIN_BANDWIDTH_KBPS] = {.type = NLA_S32 },
3862
3863};
3864
3865static const struct nla_policy
3866wlan_hdd_tdls_config_disable_policy[QCA_WLAN_VENDOR_ATTR_TDLS_DISABLE_MAX +1] =
3867{
3868 [QCA_WLAN_VENDOR_ATTR_TDLS_DISABLE_MAC_ADDR] = {.type = NLA_UNSPEC },
3869
3870};
3871
3872static const struct nla_policy
3873wlan_hdd_tdls_config_state_change_policy[
3874 QCA_WLAN_VENDOR_ATTR_TDLS_STATE_MAX +1] =
3875{
3876 [QCA_WLAN_VENDOR_ATTR_TDLS_STATE_MAC_ADDR] = {.type = NLA_UNSPEC },
3877 [QCA_WLAN_VENDOR_ATTR_TDLS_NEW_STATE] = {.type = NLA_S32 },
3878 [QCA_WLAN_VENDOR_ATTR_TDLS_STATE_REASON] = {.type = NLA_S32 },
3879
3880};
3881
3882static const struct nla_policy
3883wlan_hdd_tdls_config_get_status_policy[
3884 QCA_WLAN_VENDOR_ATTR_TDLS_GET_STATUS_MAX +1] =
3885{
3886 [QCA_WLAN_VENDOR_ATTR_TDLS_GET_STATUS_MAC_ADDR] = {.type = NLA_UNSPEC },
3887 [QCA_WLAN_VENDOR_ATTR_TDLS_GET_STATUS_STATE] = {.type = NLA_S32 },
3888 [QCA_WLAN_VENDOR_ATTR_TDLS_GET_STATUS_REASON] = {.type = NLA_S32 },
3889
3890};
3891static int wlan_hdd_cfg80211_exttdls_get_status(struct wiphy *wiphy,
3892 struct wireless_dev *wdev,
3893 void *data,
3894 int data_len)
3895{
3896 u8 peer[6] = {0};
3897 struct net_device *dev = wdev->netdev;
3898 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
3899 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
3900 struct nlattr *tb[QCA_WLAN_VENDOR_ATTR_TDLS_GET_STATUS_MAX + 1];
3901 eHalStatus ret;
3902 tANI_S32 state;
3903 tANI_S32 reason;
3904 struct sk_buff *skb = NULL;
3905
3906 ret = wlan_hdd_validate_context(pHddCtx);
3907 if (0 != ret) {
3908
3909 return -EINVAL;
3910 }
3911 if (pHddCtx->cfg_ini->fTDLSExternalControl == FALSE) {
3912
3913 return -ENOTSUPP;
3914 }
3915 if (nla_parse(tb, QCA_WLAN_VENDOR_ATTR_TDLS_GET_STATUS_MAX,
3916 data, data_len,
3917 wlan_hdd_tdls_config_get_status_policy)) {
3918 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Invalid ATTR"));
3919 return -EINVAL;
3920 }
3921
3922 /* Parse and fetch mac address */
3923 if (!tb[QCA_WLAN_VENDOR_ATTR_TDLS_GET_STATUS_MAC_ADDR]) {
3924 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr mac addr failed"));
3925 return -EINVAL;
3926 }
3927
3928 memcpy(peer, nla_data(
3929 tb[QCA_WLAN_VENDOR_ATTR_TDLS_GET_STATUS_MAC_ADDR]),
3930 sizeof(peer));
3931 hddLog(VOS_TRACE_LEVEL_INFO, FL(MAC_ADDRESS_STR),MAC_ADDR_ARRAY(peer));
3932
3933 ret = wlan_hdd_tdls_get_status(pAdapter, peer, &state, &reason);
3934
3935 if (0 != ret) {
3936 hddLog(VOS_TRACE_LEVEL_ERROR,
3937 FL("get status Failed"));
3938 return -EINVAL;
3939 }
3940 skb = cfg80211_vendor_cmd_alloc_reply_skb(wiphy,
3941 2 * sizeof(s32) +
3942 NLMSG_HDRLEN);
3943
3944 if (!skb) {
3945 hddLog(VOS_TRACE_LEVEL_ERROR,
3946 FL("cfg80211_vendor_cmd_alloc_reply_skb failed"));
3947 return -EINVAL;
3948 }
3949 hddLog(VOS_TRACE_LEVEL_INFO, FL("Reason (%d) Status (%d) tdls peer" MAC_ADDRESS_STR),
3950 reason,
3951 state,
3952 MAC_ADDR_ARRAY(peer));
3953
3954 if (nla_put_s32(skb, QCA_WLAN_VENDOR_ATTR_TDLS_GET_STATUS_STATE, state) ||
3955 nla_put_s32(skb, QCA_WLAN_VENDOR_ATTR_TDLS_GET_STATUS_REASON, reason)) {
3956
3957 hddLog(VOS_TRACE_LEVEL_ERROR, FL("nla put fail"));
3958 goto nla_put_failure;
3959 }
3960
3961 return cfg80211_vendor_cmd_reply(skb);
3962
3963nla_put_failure:
3964 kfree_skb(skb);
3965 return -EINVAL;
3966}
3967
3968static int wlan_hdd_cfg80211_exttdls_callback(tANI_U8* mac,
3969 tANI_S32 state,
3970 tANI_S32 reason,
3971 void *ctx)
3972{
3973 hdd_adapter_t* pAdapter = (hdd_adapter_t*)ctx;
3974 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
3975 struct sk_buff *skb = NULL;
3976
3977 if (wlan_hdd_validate_context(pHddCtx)) {
3978 hddLog(VOS_TRACE_LEVEL_ERROR, FL("HDD context is not valid "));
3979 return -EINVAL;
3980 }
3981
3982 if (pHddCtx->cfg_ini->fTDLSExternalControl == FALSE) {
3983
3984 return -ENOTSUPP;
3985 }
3986 skb = cfg80211_vendor_event_alloc(
3987 pHddCtx->wiphy,
3988 EXTTDLS_EVENT_BUF_SIZE + NLMSG_HDRLEN,
3989 QCA_NL80211_VENDOR_SUBCMD_TDLS_STATE_CHANGE_INDEX,
3990 GFP_KERNEL);
3991
3992 if (!skb) {
3993 hddLog(VOS_TRACE_LEVEL_ERROR,
3994 FL("cfg80211_vendor_event_alloc failed"));
3995 return -EINVAL;
3996 }
3997 hddLog(VOS_TRACE_LEVEL_INFO, FL("Entering "));
3998 hddLog(VOS_TRACE_LEVEL_INFO, "Reason (%d) Status (%d)", reason, state);
3999 hddLog(VOS_TRACE_LEVEL_WARN, "tdls peer " MAC_ADDRESS_STR,
4000 MAC_ADDR_ARRAY(mac));
4001
4002 if (nla_put(skb, QCA_WLAN_VENDOR_ATTR_TDLS_STATE_MAC_ADDR,
4003 VOS_MAC_ADDR_SIZE, mac) ||
4004 nla_put_s32(skb, QCA_WLAN_VENDOR_ATTR_TDLS_NEW_STATE, state) ||
4005 nla_put_s32(skb, QCA_WLAN_VENDOR_ATTR_TDLS_STATE_REASON, reason)
4006 ) {
4007
4008 hddLog(VOS_TRACE_LEVEL_ERROR, FL("nla put fail"));
4009 goto nla_put_failure;
4010 }
4011
4012 cfg80211_vendor_event(skb, GFP_KERNEL);
4013 return (0);
4014
4015nla_put_failure:
4016 kfree_skb(skb);
4017 return -EINVAL;
4018}
4019
4020static int wlan_hdd_cfg80211_exttdls_enable(struct wiphy *wiphy,
4021 struct wireless_dev *wdev,
4022 void *data,
4023 int data_len)
4024{
4025 u8 peer[6] = {0};
4026 struct net_device *dev = wdev->netdev;
4027 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
4028 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
4029 struct nlattr *tb[QCA_WLAN_VENDOR_ATTR_TDLS_ENABLE_MAX + 1];
4030 eHalStatus status;
4031 tdls_req_params_t pReqMsg = {0};
4032
4033 status = wlan_hdd_validate_context(pHddCtx);
4034 if (0 != status) {
4035 hddLog(VOS_TRACE_LEVEL_ERROR,
4036 FL("HDD context is not valid"));
4037 return -EINVAL;
4038 }
4039 if (pHddCtx->cfg_ini->fTDLSExternalControl == FALSE) {
4040
4041 return -ENOTSUPP;
4042 }
4043 if (nla_parse(tb, QCA_WLAN_VENDOR_ATTR_TDLS_ENABLE_MAX,
4044 data, data_len,
4045 wlan_hdd_tdls_config_enable_policy)) {
4046 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Invalid ATTR"));
4047 return -EINVAL;
4048 }
4049
4050 /* Parse and fetch mac address */
4051 if (!tb[QCA_WLAN_VENDOR_ATTR_TDLS_ENABLE_MAC_ADDR]) {
4052 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr mac addr failed"));
4053 return -EINVAL;
4054 }
4055
4056 memcpy(peer, nla_data(
4057 tb[QCA_WLAN_VENDOR_ATTR_TDLS_ENABLE_MAC_ADDR]),
4058 sizeof(peer));
4059 hddLog(VOS_TRACE_LEVEL_INFO, FL(MAC_ADDRESS_STR),MAC_ADDR_ARRAY(peer));
4060
4061 /* Parse and fetch channel */
4062 if (!tb[QCA_WLAN_VENDOR_ATTR_TDLS_ENABLE_CHANNEL]) {
4063 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr channel failed"));
4064 return -EINVAL;
4065 }
4066 pReqMsg.channel = nla_get_s32(
4067 tb[QCA_WLAN_VENDOR_ATTR_TDLS_ENABLE_CHANNEL]);
4068 hddLog(VOS_TRACE_LEVEL_INFO, FL("Channel Num (%d)"), pReqMsg.channel);
4069
4070 /* Parse and fetch global operating class */
4071 if (!tb[QCA_WLAN_VENDOR_ATTR_TDLS_ENABLE_GLOBAL_OPERATING_CLASS]) {
4072 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr operating class failed"));
4073 return -EINVAL;
4074 }
4075 pReqMsg.global_operating_class = nla_get_s32(
4076 tb[QCA_WLAN_VENDOR_ATTR_TDLS_ENABLE_GLOBAL_OPERATING_CLASS]);
4077 hddLog(VOS_TRACE_LEVEL_INFO, FL("Operating class (%d)"),
4078 pReqMsg.global_operating_class);
4079
4080 /* Parse and fetch latency ms */
4081 if (!tb[QCA_WLAN_VENDOR_ATTR_TDLS_ENABLE_MAX_LATENCY_MS]) {
4082 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr latency failed"));
4083 return -EINVAL;
4084 }
4085 pReqMsg.max_latency_ms = nla_get_s32(
4086 tb[QCA_WLAN_VENDOR_ATTR_TDLS_ENABLE_MAX_LATENCY_MS]);
4087 hddLog(VOS_TRACE_LEVEL_INFO, FL("Latency (%d)"),
4088 pReqMsg.max_latency_ms);
4089
4090 /* Parse and fetch required bandwidth kbps */
4091 if (!tb[QCA_WLAN_VENDOR_ATTR_TDLS_ENABLE_MIN_BANDWIDTH_KBPS]) {
4092 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr bandwidth failed"));
4093 return -EINVAL;
4094 }
4095
4096 pReqMsg.min_bandwidth_kbps = nla_get_s32(
4097 tb[QCA_WLAN_VENDOR_ATTR_TDLS_ENABLE_MIN_BANDWIDTH_KBPS]);
4098 hddLog(VOS_TRACE_LEVEL_INFO, FL("Bandwidth (%d)"),
4099 pReqMsg.min_bandwidth_kbps);
4100
4101 return (wlan_hdd_tdls_extctrl_config_peer(pAdapter,
4102 peer,
4103 wlan_hdd_cfg80211_exttdls_callback));
4104}
4105
4106static int wlan_hdd_cfg80211_exttdls_disable(struct wiphy *wiphy,
4107 struct wireless_dev *wdev,
4108 void *data,
4109 int data_len)
4110{
4111 u8 peer[6] = {0};
4112 struct net_device *dev = wdev->netdev;
4113 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
4114 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
4115 struct nlattr *tb[QCA_WLAN_VENDOR_ATTR_TDLS_DISABLE_MAX + 1];
4116 eHalStatus status;
4117
4118 status = wlan_hdd_validate_context(pHddCtx);
4119 if (0 != status) {
4120 hddLog(VOS_TRACE_LEVEL_ERROR,
4121 FL("HDD context is not valid"));
4122 return -EINVAL;
4123 }
4124 if (pHddCtx->cfg_ini->fTDLSExternalControl == FALSE) {
4125
4126 return -ENOTSUPP;
4127 }
4128 if (nla_parse(tb, QCA_WLAN_VENDOR_ATTR_TDLS_DISABLE_MAX,
4129 data, data_len,
4130 wlan_hdd_tdls_config_disable_policy)) {
4131 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Invalid ATTR"));
4132 return -EINVAL;
4133 }
4134 /* Parse and fetch mac address */
4135 if (!tb[QCA_WLAN_VENDOR_ATTR_TDLS_DISABLE_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_DISABLE_MAC_ADDR]),
4142 sizeof(peer));
4143 hddLog(VOS_TRACE_LEVEL_INFO, FL(MAC_ADDRESS_STR),MAC_ADDR_ARRAY(peer));
4144
4145 return (wlan_hdd_tdls_extctrl_deconfig_peer(pAdapter, peer));
4146}
4147
4148
Sunil Duttc69bccb2014-05-26 21:30:20 +05304149const struct wiphy_vendor_command hdd_wiphy_vendor_commands[] =
4150{
4151#ifdef WLAN_FEATURE_LINK_LAYER_STATS
4152 {
4153 .info.vendor_id = QCA_NL80211_VENDOR_ID,
4154 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_LL_STATS_CLR,
4155 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
4156 WIPHY_VENDOR_CMD_NEED_NETDEV |
4157 WIPHY_VENDOR_CMD_NEED_RUNNING,
4158 .doit = wlan_hdd_cfg80211_ll_stats_clear
4159 },
4160
4161 {
4162 .info.vendor_id = QCA_NL80211_VENDOR_ID,
4163 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_LL_STATS_SET,
4164 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
4165 WIPHY_VENDOR_CMD_NEED_NETDEV |
4166 WIPHY_VENDOR_CMD_NEED_RUNNING,
4167 .doit = wlan_hdd_cfg80211_ll_stats_set
4168 },
4169
4170 {
4171 .info.vendor_id = QCA_NL80211_VENDOR_ID,
4172 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_LL_STATS_GET,
4173 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
4174 WIPHY_VENDOR_CMD_NEED_NETDEV |
4175 WIPHY_VENDOR_CMD_NEED_RUNNING,
4176 .doit = wlan_hdd_cfg80211_ll_stats_get
Dino Mycle6fb96c12014-06-10 11:52:40 +05304177 },
Sunil Duttc69bccb2014-05-26 21:30:20 +05304178#endif /* WLAN_FEATURE_LINK_LAYER_STATS */
Dino Mycle6fb96c12014-06-10 11:52:40 +05304179#ifdef WLAN_FEATURE_EXTSCAN
4180 {
4181 .info.vendor_id = QCA_NL80211_VENDOR_ID,
4182 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_START,
4183 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
4184 WIPHY_VENDOR_CMD_NEED_NETDEV |
4185 WIPHY_VENDOR_CMD_NEED_RUNNING,
4186 .doit = wlan_hdd_cfg80211_extscan_start
4187 },
4188 {
4189 .info.vendor_id = QCA_NL80211_VENDOR_ID,
4190 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_STOP,
4191 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
4192 WIPHY_VENDOR_CMD_NEED_NETDEV |
4193 WIPHY_VENDOR_CMD_NEED_RUNNING,
4194 .doit = wlan_hdd_cfg80211_extscan_stop
4195 },
4196 {
4197 .info.vendor_id = QCA_NL80211_VENDOR_ID,
4198 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_GET_VALID_CHANNELS,
4199 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
4200 WIPHY_VENDOR_CMD_NEED_NETDEV,
4201 .doit = wlan_hdd_cfg80211_extscan_get_valid_channels
4202 },
4203 {
4204 .info.vendor_id = QCA_NL80211_VENDOR_ID,
4205 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_GET_CAPABILITIES,
4206 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
4207 WIPHY_VENDOR_CMD_NEED_NETDEV |
4208 WIPHY_VENDOR_CMD_NEED_RUNNING,
4209 .doit = wlan_hdd_cfg80211_extscan_get_capabilities
4210 },
4211 {
4212 .info.vendor_id = QCA_NL80211_VENDOR_ID,
4213 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_GET_CACHED_RESULTS,
4214 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
4215 WIPHY_VENDOR_CMD_NEED_NETDEV |
4216 WIPHY_VENDOR_CMD_NEED_RUNNING,
4217 .doit = wlan_hdd_cfg80211_extscan_get_cached_results
4218 },
4219 {
4220 .info.vendor_id = QCA_NL80211_VENDOR_ID,
4221 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_SET_BSSID_HOTLIST,
4222 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
4223 WIPHY_VENDOR_CMD_NEED_NETDEV |
4224 WIPHY_VENDOR_CMD_NEED_RUNNING,
4225 .doit = wlan_hdd_cfg80211_extscan_set_bssid_hotlist
4226 },
4227 {
4228 .info.vendor_id = QCA_NL80211_VENDOR_ID,
4229 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_RESET_BSSID_HOTLIST,
4230 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
4231 WIPHY_VENDOR_CMD_NEED_NETDEV |
4232 WIPHY_VENDOR_CMD_NEED_RUNNING,
4233 .doit = wlan_hdd_cfg80211_extscan_reset_bssid_hotlist
4234 },
4235 {
4236 .info.vendor_id = QCA_NL80211_VENDOR_ID,
4237 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_SET_SIGNIFICANT_CHANGE,
4238 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
4239 WIPHY_VENDOR_CMD_NEED_NETDEV |
4240 WIPHY_VENDOR_CMD_NEED_RUNNING,
4241 .doit = wlan_hdd_cfg80211_extscan_set_significant_change
4242 },
4243 {
4244 .info.vendor_id = QCA_NL80211_VENDOR_ID,
4245 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_RESET_SIGNIFICANT_CHANGE,
4246 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
4247 WIPHY_VENDOR_CMD_NEED_NETDEV |
4248 WIPHY_VENDOR_CMD_NEED_RUNNING,
4249 .doit = wlan_hdd_cfg80211_extscan_reset_significant_change
4250 },
4251#endif /* WLAN_FEATURE_EXTSCAN */
Atul Mittal115287b2014-07-08 13:26:33 +05304252/*EXT TDLS*/
4253 {
4254 .info.vendor_id = QCA_NL80211_VENDOR_ID,
4255 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_TDLS_ENABLE,
4256 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
4257 WIPHY_VENDOR_CMD_NEED_NETDEV |
4258 WIPHY_VENDOR_CMD_NEED_RUNNING,
4259 .doit = wlan_hdd_cfg80211_exttdls_enable
4260 },
4261 {
4262 .info.vendor_id = QCA_NL80211_VENDOR_ID,
4263 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_TDLS_DISABLE,
4264 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
4265 WIPHY_VENDOR_CMD_NEED_NETDEV |
4266 WIPHY_VENDOR_CMD_NEED_RUNNING,
4267 .doit = wlan_hdd_cfg80211_exttdls_disable
4268 },
4269 {
4270 .info.vendor_id = QCA_NL80211_VENDOR_ID,
4271 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_TDLS_GET_STATUS,
4272 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
4273 WIPHY_VENDOR_CMD_NEED_NETDEV,
4274 .doit = wlan_hdd_cfg80211_exttdls_get_status
4275 },
4276
Sunil Duttc69bccb2014-05-26 21:30:20 +05304277};
4278
Rajesh Chauhan98a31f82014-01-06 20:15:25 -08004279/* vendor specific events */
Sunil Duttc69bccb2014-05-26 21:30:20 +05304280static const
4281struct nl80211_vendor_cmd_info wlan_hdd_cfg80211_vendor_events[] =
Rajesh Chauhan98a31f82014-01-06 20:15:25 -08004282{
4283#ifdef FEATURE_WLAN_CH_AVOID
4284 {
Sunil Duttc69bccb2014-05-26 21:30:20 +05304285 .vendor_id = QCA_NL80211_VENDOR_ID,
4286 .subcmd = QCA_NL80211_VENDOR_SUBCMD_AVOID_FREQUENCY
Rajesh Chauhan98a31f82014-01-06 20:15:25 -08004287 },
Sunil Duttc69bccb2014-05-26 21:30:20 +05304288#endif /* FEATURE_WLAN_CH_AVOID Index = 0*/
4289#ifdef WLAN_FEATURE_LINK_LAYER_STATS
4290 {
4291 /* Index = 1*/
4292 .vendor_id = QCA_NL80211_VENDOR_ID,
4293 .subcmd = QCA_NL80211_VENDOR_SUBCMD_LL_STATS_SET
4294 },
4295 {
4296 /* Index = 2*/
4297 .vendor_id = QCA_NL80211_VENDOR_ID,
4298 .subcmd = QCA_NL80211_VENDOR_SUBCMD_LL_STATS_GET
4299 },
4300 {
4301 /* Index = 3*/
4302 .vendor_id = QCA_NL80211_VENDOR_ID,
4303 .subcmd = QCA_NL80211_VENDOR_SUBCMD_LL_STATS_CLR
4304 },
4305 {
4306 /* Index = 4*/
4307 .vendor_id = QCA_NL80211_VENDOR_ID,
4308 .subcmd = QCA_NL80211_VENDOR_SUBCMD_LL_STATS_RADIO_RESULTS
4309 },
4310 {
4311 /* Index = 5*/
4312 .vendor_id = QCA_NL80211_VENDOR_ID,
4313 .subcmd = QCA_NL80211_VENDOR_SUBCMD_LL_STATS_IFACE_RESULTS
4314 },
4315 {
4316 /* Index = 6*/
4317 .vendor_id = QCA_NL80211_VENDOR_ID,
4318 .subcmd = QCA_NL80211_VENDOR_SUBCMD_LL_STATS_PEERS_RESULTS
4319 },
4320#endif /* WLAN_FEATURE_LINK_LAYER_STATS */
Dino Mycle6fb96c12014-06-10 11:52:40 +05304321#ifdef WLAN_FEATURE_EXTSCAN
4322 {
4323 .vendor_id = QCA_NL80211_VENDOR_ID,
4324 .subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_START
4325 },
4326 {
4327 .vendor_id = QCA_NL80211_VENDOR_ID,
4328 .subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_STOP
4329 },
4330 {
4331 .vendor_id = QCA_NL80211_VENDOR_ID,
4332 .subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_GET_CAPABILITIES
4333 },
4334 {
4335 .vendor_id = QCA_NL80211_VENDOR_ID,
4336 .subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_GET_CACHED_RESULTS
4337 },
4338 {
4339 .vendor_id = QCA_NL80211_VENDOR_ID,
4340 .subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_SCAN_RESULTS_AVAILABLE
4341 },
4342 {
4343 .vendor_id = QCA_NL80211_VENDOR_ID,
4344 .subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_FULL_SCAN_RESULT
4345 },
4346 {
4347 .vendor_id = QCA_NL80211_VENDOR_ID,
4348 .subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_SCAN_EVENT
4349 },
4350 {
4351 .vendor_id = QCA_NL80211_VENDOR_ID,
4352 .subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_HOTLIST_AP_FOUND
4353 },
4354 {
4355 .vendor_id = QCA_NL80211_VENDOR_ID,
4356 .subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_SET_BSSID_HOTLIST
4357 },
4358 {
4359 .vendor_id = QCA_NL80211_VENDOR_ID,
4360 .subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_RESET_BSSID_HOTLIST
4361 },
4362 {
4363 .vendor_id = QCA_NL80211_VENDOR_ID,
4364 .subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_SIGNIFICANT_CHANGE
4365 },
4366 {
4367 .vendor_id = QCA_NL80211_VENDOR_ID,
4368 .subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_SET_SIGNIFICANT_CHANGE
4369 },
4370 {
4371 .vendor_id = QCA_NL80211_VENDOR_ID,
4372 .subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_RESET_SIGNIFICANT_CHANGE
4373 },
4374#endif /* WLAN_FEATURE_EXTSCAN */
Atul Mittal115287b2014-07-08 13:26:33 +05304375/*EXT TDLS*/
4376 {
4377 .vendor_id = QCA_NL80211_VENDOR_ID,
4378 .subcmd = QCA_NL80211_VENDOR_SUBCMD_TDLS_STATE
4379 },
Rajesh Chauhan98a31f82014-01-06 20:15:25 -08004380};
4381
Jeff Johnson295189b2012-06-20 16:38:30 -07004382/*
Madan Mohan Koyyalamudi71278262013-04-12 22:00:48 +05304383 * FUNCTION: wlan_hdd_cfg80211_wiphy_alloc
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304384 * This function is called by hdd_wlan_startup()
4385 * during initialization.
Madan Mohan Koyyalamudi71278262013-04-12 22:00:48 +05304386 * This function is used to allocate wiphy structure.
Jeff Johnson295189b2012-06-20 16:38:30 -07004387 */
Madan Mohan Koyyalamudi71278262013-04-12 22:00:48 +05304388struct wiphy *wlan_hdd_cfg80211_wiphy_alloc(int priv_size)
Jeff Johnson295189b2012-06-20 16:38:30 -07004389{
4390 struct wiphy *wiphy;
4391 ENTER();
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304392 /*
4393 * Create wiphy device
Jeff Johnson295189b2012-06-20 16:38:30 -07004394 */
4395 wiphy = wiphy_new(&wlan_hdd_cfg80211_ops, priv_size);
4396
4397 if (!wiphy)
4398 {
4399 /* Print error and jump into err label and free the memory */
4400 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: wiphy init failed", __func__);
4401 return NULL;
4402 }
4403
Sunil Duttc69bccb2014-05-26 21:30:20 +05304404
Jeff Johnson295189b2012-06-20 16:38:30 -07004405 return wiphy;
4406}
4407
4408/*
4409 * FUNCTION: wlan_hdd_cfg80211_update_band
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304410 * This function is called from the supplicant through a
Jeff Johnson295189b2012-06-20 16:38:30 -07004411 * private ioctl to change the band value
4412 */
4413int wlan_hdd_cfg80211_update_band(struct wiphy *wiphy, eCsrBand eBand)
4414{
Gopichand Nakkala1f7a64f2013-04-01 18:37:17 +05304415 int i, j;
4416 eNVChannelEnabledType channelEnabledState;
4417
Jeff Johnsone7245742012-09-05 17:12:55 -07004418 ENTER();
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05304419
Gopichand Nakkala1f7a64f2013-04-01 18:37:17 +05304420 for (i = 0; i < IEEE80211_NUM_BANDS; i++)
Jeff Johnson295189b2012-06-20 16:38:30 -07004421 {
Gopichand Nakkala1f7a64f2013-04-01 18:37:17 +05304422
4423 if (NULL == wiphy->bands[i])
4424 {
4425 hddLog(VOS_TRACE_LEVEL_ERROR,"%s: wiphy->bands[i] is NULL, i = %d",
4426 __func__, i);
4427 continue;
4428 }
4429
4430 for (j = 0; j < wiphy->bands[i]->n_channels; j++)
4431 {
4432 struct ieee80211_supported_band *band = wiphy->bands[i];
4433
4434 channelEnabledState = vos_nv_getChannelEnabledState(
4435 band->channels[j].hw_value);
4436
4437 if (IEEE80211_BAND_2GHZ == i && eCSR_BAND_5G == eBand) // 5G only
4438 {
4439 // Enable Social channels for P2P
4440 if (WLAN_HDD_IS_SOCIAL_CHANNEL(band->channels[j].center_freq) &&
4441 NV_CHANNEL_ENABLE == channelEnabledState)
4442 band->channels[j].flags &= ~IEEE80211_CHAN_DISABLED;
4443 else
4444 band->channels[j].flags |= IEEE80211_CHAN_DISABLED;
4445 continue;
4446 }
4447 else if (IEEE80211_BAND_5GHZ == i && eCSR_BAND_24 == eBand) // 2G only
4448 {
4449 band->channels[j].flags |= IEEE80211_CHAN_DISABLED;
4450 continue;
4451 }
4452
4453 if (NV_CHANNEL_DISABLE == channelEnabledState ||
4454 NV_CHANNEL_INVALID == channelEnabledState)
4455 {
4456 band->channels[j].flags |= IEEE80211_CHAN_DISABLED;
4457 }
4458 else if (NV_CHANNEL_DFS == channelEnabledState)
4459 {
4460 band->channels[j].flags &= ~IEEE80211_CHAN_DISABLED;
4461 band->channels[j].flags |= IEEE80211_CHAN_RADAR;
4462 }
4463 else
4464 {
4465 band->channels[j].flags &= ~(IEEE80211_CHAN_DISABLED
4466 |IEEE80211_CHAN_RADAR);
4467 }
4468 }
Jeff Johnson295189b2012-06-20 16:38:30 -07004469 }
4470 return 0;
4471}
4472/*
4473 * FUNCTION: wlan_hdd_cfg80211_init
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304474 * This function is called by hdd_wlan_startup()
4475 * during initialization.
Jeff Johnson295189b2012-06-20 16:38:30 -07004476 * This function is used to initialize and register wiphy structure.
4477 */
Madan Mohan Koyyalamudi71278262013-04-12 22:00:48 +05304478int wlan_hdd_cfg80211_init(struct device *dev,
Jeff Johnson295189b2012-06-20 16:38:30 -07004479 struct wiphy *wiphy,
4480 hdd_config_t *pCfg
4481 )
4482{
Gopichand Nakkala1f7a64f2013-04-01 18:37:17 +05304483 int i, j;
Vinay Krishna Erannafacf5e22014-02-24 13:16:25 +05304484 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
4485
Jeff Johnsone7245742012-09-05 17:12:55 -07004486 ENTER();
4487
Jeff Johnson295189b2012-06-20 16:38:30 -07004488 /* Now bind the underlying wlan device with wiphy */
4489 set_wiphy_dev(wiphy, dev);
4490
4491 wiphy->mgmt_stypes = wlan_hdd_txrx_stypes;
Amar Singhalfddc28c2013-09-05 13:03:40 -07004492
Kiet Lam6c583332013-10-14 05:37:09 +05304493#ifndef CONFIG_ENABLE_LINUX_REG
Amar Singhal0a402232013-10-11 20:57:16 -07004494 /* the flag for the other case would be initialzed in
4495 vos_init_wiphy_from_nv_bin */
Amar Singhal0a402232013-10-11 20:57:16 -07004496 wiphy->flags |= WIPHY_FLAG_STRICT_REGULATORY;
Kiet Lam6c583332013-10-14 05:37:09 +05304497#endif
Amar Singhala49cbc52013-10-08 18:37:44 -07004498
Amar Singhalfddc28c2013-09-05 13:03:40 -07004499 /* This will disable updating of NL channels from passive to
4500 * active if a beacon is received on passive channel. */
4501 wiphy->flags |= WIPHY_FLAG_DISABLE_BEACON_HINTS;
Amar Singhalf0073192013-09-20 12:34:56 -07004502
Amar Singhalfddc28c2013-09-05 13:03:40 -07004503
Amar Singhala49cbc52013-10-08 18:37:44 -07004504
Jeff Johnson04dd8a82012-06-29 20:41:40 -07004505#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,4,0))
Madan Mohan Koyyalamudi1b4afb02012-10-22 15:25:16 -07004506 wiphy->flags |= WIPHY_FLAG_HAVE_AP_SME
4507 | WIPHY_FLAG_AP_PROBE_RESP_OFFLOAD
4508 | WIPHY_FLAG_HAS_REMAIN_ON_CHANNEL
Jeff Johnsone7245742012-09-05 17:12:55 -07004509 | WIPHY_FLAG_OFFCHAN_TX;
Kiet Lam6c583332013-10-14 05:37:09 +05304510 wiphy->country_ie_pref = NL80211_COUNTRY_IE_IGNORE_CORE;
Jeff Johnson04dd8a82012-06-29 20:41:40 -07004511#endif
Amar Singhala49cbc52013-10-08 18:37:44 -07004512
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08004513#if defined (WLAN_FEATURE_VOWIFI_11R) || defined (FEATURE_WLAN_ESE) || defined(FEATURE_WLAN_LFR)
Srinivas Girigowda640728a2013-03-28 12:21:54 -07004514 if (pCfg->isFastTransitionEnabled
James Zmuda77fb5ae2013-01-29 08:00:17 -08004515#ifdef FEATURE_WLAN_LFR
Srinivas Girigowda640728a2013-03-28 12:21:54 -07004516 || pCfg->isFastRoamIniFeatureEnabled
4517#endif
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08004518#ifdef FEATURE_WLAN_ESE
4519 || pCfg->isEseIniFeatureEnabled
Srinivas Girigowda640728a2013-03-28 12:21:54 -07004520#endif
4521 )
4522 {
4523 wiphy->flags |= WIPHY_FLAG_SUPPORTS_FW_ROAM;
4524 }
James Zmuda77fb5ae2013-01-29 08:00:17 -08004525#endif
Mohit Khanna698ba2a2012-12-04 15:08:18 -08004526#ifdef FEATURE_WLAN_TDLS
4527 wiphy->flags |= WIPHY_FLAG_SUPPORTS_TDLS
4528 | WIPHY_FLAG_TDLS_EXTERNAL_SETUP;
4529#endif
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +05304530#ifdef FEATURE_WLAN_SCAN_PNO
Hardik Kantilal Patel3dfd8792013-11-13 20:34:57 +05304531 if (pCfg->configPNOScanSupport)
4532 {
4533 wiphy->flags |= WIPHY_FLAG_SUPPORTS_SCHED_SCAN;
4534 wiphy->max_sched_scan_ssids = SIR_PNO_MAX_SUPP_NETWORKS;
4535 wiphy->max_match_sets = SIR_PNO_MAX_SUPP_NETWORKS;
4536 wiphy->max_sched_scan_ie_len = SIR_MAC_MAX_IE_LENGTH;
4537 }
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +05304538#endif/*FEATURE_WLAN_SCAN_PNO*/
Mohit Khanna698ba2a2012-12-04 15:08:18 -08004539
Amar Singhalfddc28c2013-09-05 13:03:40 -07004540#ifdef CONFIG_ENABLE_LINUX_REG
Madan Mohan Koyyalamudic3a240c2012-09-28 15:34:08 -07004541 /* even with WIPHY_FLAG_CUSTOM_REGULATORY,
4542 driver can still register regulatory callback and
Amar Singhalfddc28c2013-09-05 13:03:40 -07004543 it will get regulatory settings in wiphy->band[], but
Madan Mohan Koyyalamudic3a240c2012-09-28 15:34:08 -07004544 driver need to determine what to do with both
4545 regulatory settings */
Amar Singhalfddc28c2013-09-05 13:03:40 -07004546
4547 wiphy->reg_notifier = wlan_hdd_linux_reg_notifier;
Amar Singhala49cbc52013-10-08 18:37:44 -07004548#else
4549 wiphy->reg_notifier = wlan_hdd_crda_reg_notifier;
Amar Singhalfddc28c2013-09-05 13:03:40 -07004550#endif
Jeff Johnson04dd8a82012-06-29 20:41:40 -07004551
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304552 wiphy->max_scan_ssids = MAX_SCAN_SSID;
4553
Madan Mohan Koyyalamudi6815b162013-07-19 17:17:46 +05304554 wiphy->max_scan_ie_len = SIR_MAC_MAX_IE_LENGTH;
Jeff Johnson295189b2012-06-20 16:38:30 -07004555
Gopichand Nakkalac005b7c2013-05-14 16:04:14 +05304556 wiphy->max_acl_mac_addrs = MAX_ACL_MAC_ADDRESS;
4557
Jeff Johnson295189b2012-06-20 16:38:30 -07004558 /* Supports STATION & AD-HOC modes right now */
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304559 wiphy->interface_modes = BIT(NL80211_IFTYPE_STATION)
Jeff Johnson295189b2012-06-20 16:38:30 -07004560 | BIT(NL80211_IFTYPE_ADHOC)
Jeff Johnson295189b2012-06-20 16:38:30 -07004561 | BIT(NL80211_IFTYPE_P2P_CLIENT)
4562 | BIT(NL80211_IFTYPE_P2P_GO)
Jeff Johnson295189b2012-06-20 16:38:30 -07004563 | BIT(NL80211_IFTYPE_AP);
4564
Rashmi Ramannabd3feb72014-02-25 16:14:48 +05304565 if( pCfg->advertiseConcurrentOperation )
Sudhir Sattayappa Kohalli278eee52013-01-16 17:35:13 -08004566 {
Rashmi Ramannabd3feb72014-02-25 16:14:48 +05304567#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,4,0))
4568 if( pCfg->enableMCC )
4569 {
4570 /* Currently, supports up to two channels */
4571 wlan_hdd_iface_combination.num_different_channels = 2;
Sudhir Sattayappa Kohalli278eee52013-01-16 17:35:13 -08004572
Rashmi Ramannabd3feb72014-02-25 16:14:48 +05304573 if( !pCfg->allowMCCGODiffBI )
4574 wlan_hdd_iface_combination.beacon_int_infra_match = true;
Sudhir Sattayappa Kohalli278eee52013-01-16 17:35:13 -08004575
Rashmi Ramannabd3feb72014-02-25 16:14:48 +05304576 }
4577 wiphy->iface_combinations = &wlan_hdd_iface_combination;
4578 wiphy->n_iface_combinations = 1;
Sudhir Sattayappa Kohalli278eee52013-01-16 17:35:13 -08004579#endif
Rashmi Ramannabd3feb72014-02-25 16:14:48 +05304580 }
Sudhir Sattayappa Kohalli278eee52013-01-16 17:35:13 -08004581
Jeff Johnson295189b2012-06-20 16:38:30 -07004582 /* Before registering we need to update the ht capabilitied based
4583 * on ini values*/
4584 if( !pCfg->ShortGI20MhzEnable )
4585 {
4586 wlan_hdd_band_2_4_GHZ.ht_cap.cap &= ~IEEE80211_HT_CAP_SGI_20;
4587 wlan_hdd_band_5_GHZ.ht_cap.cap &= ~IEEE80211_HT_CAP_SGI_20;
4588 wlan_hdd_band_p2p_2_4_GHZ.ht_cap.cap &= ~IEEE80211_HT_CAP_SGI_20;
4589 }
4590
4591 if( !pCfg->ShortGI40MhzEnable )
4592 {
4593 wlan_hdd_band_5_GHZ.ht_cap.cap &= ~IEEE80211_HT_CAP_SGI_40;
4594 }
4595
4596 if( !pCfg->nChannelBondingMode5GHz )
4597 {
4598 wlan_hdd_band_5_GHZ.ht_cap.cap &= ~IEEE80211_HT_CAP_SUP_WIDTH_20_40;
4599 }
4600
Gopichand Nakkala1f7a64f2013-04-01 18:37:17 +05304601 wiphy->bands[IEEE80211_BAND_2GHZ] = &wlan_hdd_band_2_4_GHZ;
Vinay Krishna Erannafacf5e22014-02-24 13:16:25 +05304602 if (true == hdd_is_5g_supported(pHddCtx))
4603 {
4604 wiphy->bands[IEEE80211_BAND_5GHZ] = &wlan_hdd_band_5_GHZ;
4605 }
Gopichand Nakkala1f7a64f2013-04-01 18:37:17 +05304606
4607 for (i = 0; i < IEEE80211_NUM_BANDS; i++)
4608 {
4609
4610 if (NULL == wiphy->bands[i])
4611 {
4612 hddLog(VOS_TRACE_LEVEL_ERROR,"%s: wiphy->bands[i] is NULL, i = %d",
4613 __func__, i);
4614 continue;
4615 }
4616
4617 for (j = 0; j < wiphy->bands[i]->n_channels; j++)
4618 {
4619 struct ieee80211_supported_band *band = wiphy->bands[i];
4620
4621 if (IEEE80211_BAND_2GHZ == i && eCSR_BAND_5G == pCfg->nBandCapability) // 5G only
4622 {
4623 // Enable social channels for P2P
4624 if (WLAN_HDD_IS_SOCIAL_CHANNEL(band->channels[j].center_freq))
4625 band->channels[j].flags &= ~IEEE80211_CHAN_DISABLED;
4626 else
4627 band->channels[j].flags |= IEEE80211_CHAN_DISABLED;
4628 continue;
4629 }
4630 else if (IEEE80211_BAND_5GHZ == i && eCSR_BAND_24 == pCfg->nBandCapability) // 2G only
4631 {
4632 band->channels[j].flags |= IEEE80211_CHAN_DISABLED;
4633 continue;
4634 }
4635 }
Jeff Johnson295189b2012-06-20 16:38:30 -07004636 }
4637 /*Initialise the supported cipher suite details*/
4638 wiphy->cipher_suites = hdd_cipher_suites;
4639 wiphy->n_cipher_suites = ARRAY_SIZE(hdd_cipher_suites);
4640
4641 /*signal strength in mBm (100*dBm) */
4642 wiphy->signal_type = CFG80211_SIGNAL_TYPE_MBM;
4643
4644#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
Sushant Kaushik4f640e42014-07-08 12:27:09 +05304645 wiphy->max_remain_on_channel_duration = 5000;
Jeff Johnson295189b2012-06-20 16:38:30 -07004646#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07004647
Sunil Duttc69bccb2014-05-26 21:30:20 +05304648 wiphy->n_vendor_commands = ARRAY_SIZE(hdd_wiphy_vendor_commands);
4649 wiphy->vendor_commands = hdd_wiphy_vendor_commands;
Rajesh Chauhan98a31f82014-01-06 20:15:25 -08004650 wiphy->vendor_events = wlan_hdd_cfg80211_vendor_events;
4651 wiphy->n_vendor_events = ARRAY_SIZE(wlan_hdd_cfg80211_vendor_events);
4652
Madan Mohan Koyyalamudi71278262013-04-12 22:00:48 +05304653 EXIT();
4654 return 0;
4655}
4656
4657/* In this function we are registering wiphy. */
4658int wlan_hdd_cfg80211_register(struct wiphy *wiphy)
4659{
4660 ENTER();
4661 /* Register our wiphy dev with cfg80211 */
Jeff Johnson295189b2012-06-20 16:38:30 -07004662 if (0 > wiphy_register(wiphy))
4663 {
Madan Mohan Koyyalamudi71278262013-04-12 22:00:48 +05304664 /* print error */
Jeff Johnson295189b2012-06-20 16:38:30 -07004665 hddLog(VOS_TRACE_LEVEL_ERROR,"%s: wiphy register failed", __func__);
4666 return -EIO;
4667 }
4668
4669 EXIT();
4670 return 0;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304671}
Jeff Johnson295189b2012-06-20 16:38:30 -07004672
Madan Mohan Koyyalamudi71278262013-04-12 22:00:48 +05304673/* In this function we are updating channel list when,
4674 regulatory domain is FCC and country code is US.
4675 Here In FCC standard 5GHz UNII-1 Bands are indoor only.
4676 As per FCC smart phone is not a indoor device.
4677 GO should not opeate on indoor channels */
4678void wlan_hdd_cfg80211_update_reg_info(struct wiphy *wiphy)
4679{
4680 int j;
4681 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
4682 tANI_U8 defaultCountryCode[3] = SME_INVALID_COUNTRY_CODE;
4683 //Default counrtycode from NV at the time of wiphy initialization.
4684 if (eHAL_STATUS_SUCCESS != sme_GetDefaultCountryCodeFrmNv(pHddCtx->hHal,
4685 &defaultCountryCode[0]))
4686 {
Jeff Johnson0299d0a2013-10-30 12:37:43 -07004687 hddLog(LOGE, FL("Failed to get default country code from NV"));
Madan Mohan Koyyalamudi71278262013-04-12 22:00:48 +05304688 }
4689 if ((defaultCountryCode[0]== 'U') && (defaultCountryCode[1]=='S'))
4690 {
Madan Mohan Koyyalamudi71278262013-04-12 22:00:48 +05304691 if (NULL == wiphy->bands[IEEE80211_BAND_5GHZ])
4692 {
4693 hddLog(VOS_TRACE_LEVEL_ERROR,"%s: wiphy->bands[IEEE80211_BAND_5GHZ] is NULL",__func__ );
4694 return;
4695 }
4696 for (j = 0; j < wiphy->bands[IEEE80211_BAND_5GHZ]->n_channels; j++)
4697 {
4698 struct ieee80211_supported_band *band = wiphy->bands[IEEE80211_BAND_5GHZ];
4699 // Mark UNII -1 band channel as passive
4700 if (WLAN_HDD_CHANNEL_IN_UNII_1_BAND(band->channels[j].center_freq))
4701 band->channels[j].flags |= IEEE80211_CHAN_PASSIVE_SCAN;
4702 }
4703 }
4704}
4705
Agarwal Ashish8fa0e9a2014-05-23 00:40:12 +05304706/* This function registers for all frame which supplicant is interested in */
4707void wlan_hdd_cfg80211_register_frames(hdd_adapter_t* pAdapter)
Jeff Johnson295189b2012-06-20 16:38:30 -07004708{
Jeff Johnson295189b2012-06-20 16:38:30 -07004709 tHalHandle hHal = WLAN_HDD_GET_HAL_CTX(pAdapter);
4710 /* Register for all P2P action, public action etc frames */
4711 v_U16_t type = (SIR_MAC_MGMT_FRAME << 2) | ( SIR_MAC_MGMT_ACTION << 4);
4712
Jeff Johnsone7245742012-09-05 17:12:55 -07004713 ENTER();
4714
Jeff Johnson295189b2012-06-20 16:38:30 -07004715 /* Right now we are registering these frame when driver is getting
4716 initialized. Once we will move to 2.6.37 kernel, in which we have
4717 frame register ops, we will move this code as a part of that */
4718 /* GAS Initial Request */
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304719 sme_RegisterMgmtFrame(hHal, pAdapter->sessionId, type,
Jeff Johnson295189b2012-06-20 16:38:30 -07004720 (v_U8_t*)GAS_INITIAL_REQ, GAS_INITIAL_REQ_SIZE );
4721
4722 /* GAS Initial Response */
4723 sme_RegisterMgmtFrame(hHal, pAdapter->sessionId, type,
4724 (v_U8_t*)GAS_INITIAL_RSP, GAS_INITIAL_RSP_SIZE );
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304725
Jeff Johnson295189b2012-06-20 16:38:30 -07004726 /* GAS Comeback Request */
4727 sme_RegisterMgmtFrame(hHal, pAdapter->sessionId, type,
4728 (v_U8_t*)GAS_COMEBACK_REQ, GAS_COMEBACK_REQ_SIZE );
4729
4730 /* GAS Comeback Response */
4731 sme_RegisterMgmtFrame(hHal, pAdapter->sessionId, type,
4732 (v_U8_t*)GAS_COMEBACK_RSP, GAS_COMEBACK_RSP_SIZE );
4733
4734 /* P2P Public Action */
4735 sme_RegisterMgmtFrame(hHal, pAdapter->sessionId, type,
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304736 (v_U8_t*)P2P_PUBLIC_ACTION_FRAME,
Jeff Johnson295189b2012-06-20 16:38:30 -07004737 P2P_PUBLIC_ACTION_FRAME_SIZE );
4738
4739 /* P2P Action */
4740 sme_RegisterMgmtFrame(hHal, pAdapter->sessionId, type,
4741 (v_U8_t*)P2P_ACTION_FRAME,
4742 P2P_ACTION_FRAME_SIZE );
Chet Lanctot186b5732013-03-18 10:26:30 -07004743
Gopichand Nakkalae3d56e72013-04-21 23:33:32 +05304744 /* WNM BSS Transition Request frame */
4745 sme_RegisterMgmtFrame(hHal, pAdapter->sessionId, type,
4746 (v_U8_t*)WNM_BSS_ACTION_FRAME,
4747 WNM_BSS_ACTION_FRAME_SIZE );
Leela Venkata Kiran Kumar Reddy Chiralae8e62c82013-10-29 18:23:26 -07004748
4749 /* WNM-Notification */
4750 sme_RegisterMgmtFrame(hHal, pAdapter->sessionId, type,
4751 (v_U8_t*)WNM_NOTIFICATION_FRAME,
4752 WNM_NOTIFICATION_FRAME_SIZE );
Jeff Johnson295189b2012-06-20 16:38:30 -07004753}
4754
Agarwal Ashish8fa0e9a2014-05-23 00:40:12 +05304755void wlan_hdd_cfg80211_deregister_frames(hdd_adapter_t* pAdapter)
Jeff Johnson295189b2012-06-20 16:38:30 -07004756{
Jeff Johnson295189b2012-06-20 16:38:30 -07004757 tHalHandle hHal = WLAN_HDD_GET_HAL_CTX(pAdapter);
4758 /* Register for all P2P action, public action etc frames */
4759 v_U16_t type = (SIR_MAC_MGMT_FRAME << 2) | ( SIR_MAC_MGMT_ACTION << 4);
4760
Jeff Johnsone7245742012-09-05 17:12:55 -07004761 ENTER();
4762
Jeff Johnson295189b2012-06-20 16:38:30 -07004763 /* Right now we are registering these frame when driver is getting
4764 initialized. Once we will move to 2.6.37 kernel, in which we have
4765 frame register ops, we will move this code as a part of that */
4766 /* GAS Initial Request */
4767
4768 sme_DeregisterMgmtFrame(hHal, pAdapter->sessionId, type,
4769 (v_U8_t*)GAS_INITIAL_REQ, GAS_INITIAL_REQ_SIZE );
4770
4771 /* GAS Initial Response */
4772 sme_DeregisterMgmtFrame(hHal, pAdapter->sessionId, type,
4773 (v_U8_t*)GAS_INITIAL_RSP, GAS_INITIAL_RSP_SIZE );
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304774
Jeff Johnson295189b2012-06-20 16:38:30 -07004775 /* GAS Comeback Request */
4776 sme_DeregisterMgmtFrame(hHal, pAdapter->sessionId, type,
4777 (v_U8_t*)GAS_COMEBACK_REQ, GAS_COMEBACK_REQ_SIZE );
4778
4779 /* GAS Comeback Response */
4780 sme_DeregisterMgmtFrame(hHal, pAdapter->sessionId, type,
4781 (v_U8_t*)GAS_COMEBACK_RSP, GAS_COMEBACK_RSP_SIZE );
4782
4783 /* P2P Public Action */
4784 sme_DeregisterMgmtFrame(hHal, pAdapter->sessionId, type,
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304785 (v_U8_t*)P2P_PUBLIC_ACTION_FRAME,
Jeff Johnson295189b2012-06-20 16:38:30 -07004786 P2P_PUBLIC_ACTION_FRAME_SIZE );
4787
4788 /* P2P Action */
4789 sme_DeregisterMgmtFrame(hHal, pAdapter->sessionId, type,
4790 (v_U8_t*)P2P_ACTION_FRAME,
4791 P2P_ACTION_FRAME_SIZE );
Leela Venkata Kiran Kumar Reddy Chiralae8e62c82013-10-29 18:23:26 -07004792 /* WNM-Notification */
4793 sme_DeregisterMgmtFrame(hHal, pAdapter->sessionId, type,
4794 (v_U8_t*)WNM_NOTIFICATION_FRAME,
4795 WNM_NOTIFICATION_FRAME_SIZE );
Jeff Johnson295189b2012-06-20 16:38:30 -07004796}
4797
4798#ifdef FEATURE_WLAN_WAPI
4799void wlan_hdd_cfg80211_set_key_wapi(hdd_adapter_t* pAdapter, u8 key_index,
4800 const u8 *mac_addr, u8 *key , int key_Len)
4801{
4802 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
4803 tCsrRoamSetKey setKey;
4804 v_BOOL_t isConnected = TRUE;
4805 int status = 0;
4806 v_U32_t roamId= 0xFF;
4807 tANI_U8 *pKeyPtr = NULL;
4808 int n = 0;
4809
Sushant Kaushik8bc7df22014-04-09 17:55:29 +05304810 hddLog(VOS_TRACE_LEVEL_INFO, "%s: device_mode = %s(%d)",
4811 __func__, hdd_device_modetoString(pAdapter->device_mode),
4812 pAdapter->device_mode);
Jeff Johnson295189b2012-06-20 16:38:30 -07004813
Gopichand Nakkalae7480202013-02-11 15:24:22 +05304814 vos_mem_zero(&setKey, sizeof(tCsrRoamSetKey));
Jeff Johnson295189b2012-06-20 16:38:30 -07004815 setKey.keyId = key_index; // Store Key ID
4816 setKey.encType = eCSR_ENCRYPT_TYPE_WPI; // SET WAPI Encryption
4817 setKey.keyDirection = eSIR_TX_RX; // Key Directionn both TX and RX
4818 setKey.paeRole = 0 ; // the PAE role
4819 if (!mac_addr || is_broadcast_ether_addr(mac_addr))
4820 {
4821 vos_set_macaddr_broadcast( (v_MACADDR_t *)setKey.peerMac );
4822 }
4823 else
4824 {
4825 isConnected = hdd_connIsConnected(pHddStaCtx);
4826 vos_mem_copy(setKey.peerMac,&pHddStaCtx->conn_info.bssId,WNI_CFG_BSSID_LEN);
4827 }
4828 setKey.keyLength = key_Len;
4829 pKeyPtr = setKey.Key;
4830 memcpy( pKeyPtr, key, key_Len);
4831
Arif Hussain6d2a3322013-11-17 19:50:10 -08004832 hddLog(VOS_TRACE_LEVEL_INFO,"%s: WAPI KEY LENGTH:0x%04x",
Jeff Johnson295189b2012-06-20 16:38:30 -07004833 __func__, key_Len);
4834 for (n = 0 ; n < key_Len; n++)
4835 hddLog(VOS_TRACE_LEVEL_INFO, "%s WAPI KEY Data[%d]:%02x ",
4836 __func__,n,setKey.Key[n]);
4837
4838 pHddStaCtx->roam_info.roamingState = HDD_ROAM_STATE_SETTING_KEY;
4839 if ( isConnected )
4840 {
4841 status= sme_RoamSetKey( WLAN_HDD_GET_HAL_CTX(pAdapter),
4842 pAdapter->sessionId, &setKey, &roamId );
4843 }
4844 if ( status != 0 )
4845 {
4846 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
4847 "[%4d] sme_RoamSetKey returned ERROR status= %d",
4848 __LINE__, status );
4849 pHddStaCtx->roam_info.roamingState = HDD_ROAM_STATE_NONE;
4850 }
4851}
4852#endif /* FEATURE_WLAN_WAPI*/
4853
4854#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,4,0))
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304855int wlan_hdd_cfg80211_alloc_new_beacon(hdd_adapter_t *pAdapter,
Jeff Johnson295189b2012-06-20 16:38:30 -07004856 beacon_data_t **ppBeacon,
4857 struct beacon_parameters *params)
Jeff Johnson04dd8a82012-06-29 20:41:40 -07004858#else
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304859int wlan_hdd_cfg80211_alloc_new_beacon(hdd_adapter_t *pAdapter,
Jeff Johnson04dd8a82012-06-29 20:41:40 -07004860 beacon_data_t **ppBeacon,
4861 struct cfg80211_beacon_data *params,
4862 int dtim_period)
4863#endif
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304864{
Jeff Johnson295189b2012-06-20 16:38:30 -07004865 int size;
4866 beacon_data_t *beacon = NULL;
4867 beacon_data_t *old = NULL;
4868 int head_len,tail_len;
4869
Jeff Johnsone7245742012-09-05 17:12:55 -07004870 ENTER();
Jeff Johnson295189b2012-06-20 16:38:30 -07004871 if (params->head && !params->head_len)
c_hpothu6ff1c3c2013-10-01 19:01:57 +05304872 {
4873 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
4874 FL("head_len is NULL"));
Jeff Johnson295189b2012-06-20 16:38:30 -07004875 return -EINVAL;
c_hpothu6ff1c3c2013-10-01 19:01:57 +05304876 }
Jeff Johnson295189b2012-06-20 16:38:30 -07004877
4878 old = pAdapter->sessionCtx.ap.beacon;
4879
4880 if (!params->head && !old)
c_hpothu6ff1c3c2013-10-01 19:01:57 +05304881 {
4882 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
4883 FL("session(%d) old and new heads points to NULL"),
4884 pAdapter->sessionId);
Jeff Johnson295189b2012-06-20 16:38:30 -07004885 return -EINVAL;
c_hpothu6ff1c3c2013-10-01 19:01:57 +05304886 }
4887
4888 if (params->tail && !params->tail_len)
4889 {
4890 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
4891 FL("tail_len is zero but tail is not NULL"));
4892 return -EINVAL;
4893 }
Jeff Johnson295189b2012-06-20 16:38:30 -07004894
Jeff Johnson295189b2012-06-20 16:38:30 -07004895#if (LINUX_VERSION_CODE <= KERNEL_VERSION(2,6,38))
4896 /* Kernel 3.0 is not updating dtim_period for set beacon */
4897 if (!params->dtim_period)
c_hpothu6ff1c3c2013-10-01 19:01:57 +05304898 {
4899 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
4900 FL("dtim period is 0"));
Jeff Johnson295189b2012-06-20 16:38:30 -07004901 return -EINVAL;
c_hpothu6ff1c3c2013-10-01 19:01:57 +05304902 }
Jeff Johnson295189b2012-06-20 16:38:30 -07004903#endif
4904
4905 if(params->head)
4906 head_len = params->head_len;
4907 else
4908 head_len = old->head_len;
4909
4910 if(params->tail || !old)
4911 tail_len = params->tail_len;
4912 else
4913 tail_len = old->tail_len;
4914
4915 size = sizeof(beacon_data_t) + head_len + tail_len;
4916
4917 beacon = kzalloc(size, GFP_KERNEL);
4918
4919 if( beacon == NULL )
c_hpothu6ff1c3c2013-10-01 19:01:57 +05304920 {
4921 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
4922 FL("Mem allocation for beacon failed"));
Jeff Johnson295189b2012-06-20 16:38:30 -07004923 return -ENOMEM;
c_hpothu6ff1c3c2013-10-01 19:01:57 +05304924 }
Jeff Johnson295189b2012-06-20 16:38:30 -07004925
Jeff Johnson04dd8a82012-06-29 20:41:40 -07004926#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,4,0))
Jeff Johnson295189b2012-06-20 16:38:30 -07004927 if(params->dtim_period || !old )
4928 beacon->dtim_period = params->dtim_period;
4929 else
4930 beacon->dtim_period = old->dtim_period;
Jeff Johnson04dd8a82012-06-29 20:41:40 -07004931#else
4932 if(dtim_period || !old )
4933 beacon->dtim_period = dtim_period;
4934 else
4935 beacon->dtim_period = old->dtim_period;
4936#endif
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304937
Jeff Johnson295189b2012-06-20 16:38:30 -07004938 beacon->head = ((u8 *) beacon) + sizeof(beacon_data_t);
4939 beacon->tail = beacon->head + head_len;
4940 beacon->head_len = head_len;
4941 beacon->tail_len = tail_len;
4942
4943 if(params->head) {
4944 memcpy (beacon->head,params->head,beacon->head_len);
4945 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304946 else {
Jeff Johnson295189b2012-06-20 16:38:30 -07004947 if(old)
4948 memcpy (beacon->head,old->head,beacon->head_len);
4949 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304950
Jeff Johnson295189b2012-06-20 16:38:30 -07004951 if(params->tail) {
4952 memcpy (beacon->tail,params->tail,beacon->tail_len);
4953 }
4954 else {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304955 if(old)
Jeff Johnson295189b2012-06-20 16:38:30 -07004956 memcpy (beacon->tail,old->tail,beacon->tail_len);
4957 }
4958
4959 *ppBeacon = beacon;
4960
4961 kfree(old);
4962
4963 return 0;
4964
4965}
Jeff Johnson295189b2012-06-20 16:38:30 -07004966
4967v_U8_t* wlan_hdd_cfg80211_get_ie_ptr(v_U8_t *pIes, int length, v_U8_t eid)
4968{
4969 int left = length;
4970 v_U8_t *ptr = pIes;
4971 v_U8_t elem_id,elem_len;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304972
Jeff Johnson295189b2012-06-20 16:38:30 -07004973 while(left >= 2)
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304974 {
Jeff Johnson295189b2012-06-20 16:38:30 -07004975 elem_id = ptr[0];
4976 elem_len = ptr[1];
4977 left -= 2;
4978 if(elem_len > left)
4979 {
4980 hddLog(VOS_TRACE_LEVEL_FATAL,
Madan Mohan Koyyalamudi8bdd3112012-09-24 13:55:14 -07004981 FL("****Invalid IEs eid = %d elem_len=%d left=%d*****"),
Jeff Johnson295189b2012-06-20 16:38:30 -07004982 eid,elem_len,left);
4983 return NULL;
4984 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304985 if (elem_id == eid)
Jeff Johnson295189b2012-06-20 16:38:30 -07004986 {
4987 return ptr;
4988 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304989
Jeff Johnson295189b2012-06-20 16:38:30 -07004990 left -= elem_len;
4991 ptr += (elem_len + 2);
4992 }
4993 return NULL;
4994}
4995
Jeff Johnson295189b2012-06-20 16:38:30 -07004996/* Check if rate is 11g rate or not */
4997static int wlan_hdd_rate_is_11g(u8 rate)
4998{
Sanjay Devnani28322e22013-06-21 16:13:40 -07004999 static const u8 gRateArray[8] = {12, 18, 24, 36, 48, 72, 96, 108}; /* actual rate * 2 */
Jeff Johnson295189b2012-06-20 16:38:30 -07005000 u8 i;
5001 for (i = 0; i < 8; i++)
5002 {
5003 if(rate == gRateArray[i])
5004 return TRUE;
5005 }
5006 return FALSE;
5007}
5008
5009/* Check for 11g rate and set proper 11g only mode */
5010static void wlan_hdd_check_11gmode(u8 *pIe, u8* require_ht,
5011 u8* pCheckRatesfor11g, eSapPhyMode* pSapHw_mode)
5012{
5013 u8 i, num_rates = pIe[0];
5014
5015 pIe += 1;
5016 for ( i = 0; i < num_rates; i++)
5017 {
5018 if( *pCheckRatesfor11g && (TRUE == wlan_hdd_rate_is_11g(pIe[i] & RATE_MASK)))
5019 {
5020 /* If rate set have 11g rate than change the mode to 11G */
5021 *pSapHw_mode = eSAP_DOT11_MODE_11g;
5022 if (pIe[i] & BASIC_RATE_MASK)
5023 {
5024 /* If we have 11g rate as basic rate, it means mode
5025 is 11g only mode.
5026 */
5027 *pSapHw_mode = eSAP_DOT11_MODE_11g_ONLY;
5028 *pCheckRatesfor11g = FALSE;
5029 }
5030 }
5031 else if((BASIC_RATE_MASK | WLAN_BSS_MEMBERSHIP_SELECTOR_HT_PHY) == pIe[i])
5032 {
5033 *require_ht = TRUE;
5034 }
5035 }
5036 return;
5037}
5038
5039static void wlan_hdd_set_sapHwmode(hdd_adapter_t *pHostapdAdapter)
5040{
5041 tsap_Config_t *pConfig = &pHostapdAdapter->sessionCtx.ap.sapConfig;
5042 beacon_data_t *pBeacon = pHostapdAdapter->sessionCtx.ap.beacon;
5043 struct ieee80211_mgmt *pMgmt_frame = (struct ieee80211_mgmt*)pBeacon->head;
5044 u8 checkRatesfor11g = TRUE;
5045 u8 require_ht = FALSE;
5046 u8 *pIe=NULL;
5047
5048 pConfig->SapHw_mode= eSAP_DOT11_MODE_11b;
5049
5050 pIe = wlan_hdd_cfg80211_get_ie_ptr(&pMgmt_frame->u.beacon.variable[0],
5051 pBeacon->head_len, WLAN_EID_SUPP_RATES);
5052 if (pIe != NULL)
5053 {
5054 pIe += 1;
5055 wlan_hdd_check_11gmode(pIe, &require_ht, &checkRatesfor11g,
5056 &pConfig->SapHw_mode);
5057 }
5058
5059 pIe = wlan_hdd_cfg80211_get_ie_ptr(pBeacon->tail, pBeacon->tail_len,
5060 WLAN_EID_EXT_SUPP_RATES);
5061 if (pIe != NULL)
5062 {
5063
5064 pIe += 1;
5065 wlan_hdd_check_11gmode(pIe, &require_ht, &checkRatesfor11g,
5066 &pConfig->SapHw_mode);
5067 }
5068
5069 if( pConfig->channel > 14 )
5070 {
5071 pConfig->SapHw_mode= eSAP_DOT11_MODE_11a;
5072 }
5073
5074 pIe = wlan_hdd_cfg80211_get_ie_ptr(pBeacon->tail, pBeacon->tail_len,
5075 WLAN_EID_HT_CAPABILITY);
5076
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305077 if(pIe)
Jeff Johnson295189b2012-06-20 16:38:30 -07005078 {
5079 pConfig->SapHw_mode= eSAP_DOT11_MODE_11n;
5080 if(require_ht)
5081 pConfig->SapHw_mode= eSAP_DOT11_MODE_11n_ONLY;
5082 }
5083}
5084
Gopichand Nakkala2b25f4e2013-03-21 19:14:07 +05305085static int wlan_hdd_add_ie(hdd_adapter_t* pHostapdAdapter, v_U8_t *genie,
5086 v_U8_t *total_ielen, v_U8_t *oui, v_U8_t oui_size)
5087{
Arif Hussaine7f3ea52013-09-12 21:56:36 -07005088 v_U16_t ielen = 0;
Gopichand Nakkala2b25f4e2013-03-21 19:14:07 +05305089 v_U8_t *pIe = NULL;
5090 beacon_data_t *pBeacon = pHostapdAdapter->sessionCtx.ap.beacon;
5091
5092 pIe = wlan_hdd_get_vendor_oui_ie_ptr(oui, oui_size,
5093 pBeacon->tail, pBeacon->tail_len);
5094
5095 if (pIe)
5096 {
5097 ielen = pIe[1] + 2;
5098 if ((*total_ielen + ielen) <= MAX_GENIE_LEN)
5099 {
5100 vos_mem_copy(&genie[*total_ielen], pIe, ielen);
5101 }
5102 else
5103 {
5104 hddLog( VOS_TRACE_LEVEL_ERROR, "**Ie Length is too big***");
5105 return -EINVAL;
5106 }
5107 *total_ielen += ielen;
5108 }
5109 return 0;
5110}
5111
Arif Hussaine7f3ea52013-09-12 21:56:36 -07005112static void wlan_hdd_add_hostapd_conf_vsie(hdd_adapter_t* pHostapdAdapter,
5113 v_U8_t *genie, v_U8_t *total_ielen)
5114{
5115 beacon_data_t *pBeacon = pHostapdAdapter->sessionCtx.ap.beacon;
5116 int left = pBeacon->tail_len;
5117 v_U8_t *ptr = pBeacon->tail;
5118 v_U8_t elem_id, elem_len;
5119 v_U16_t ielen = 0;
5120
5121 if ( NULL == ptr || 0 == left )
5122 return;
5123
5124 while (left >= 2)
5125 {
5126 elem_id = ptr[0];
5127 elem_len = ptr[1];
5128 left -= 2;
5129 if (elem_len > left)
5130 {
5131 hddLog( VOS_TRACE_LEVEL_ERROR,
5132 "****Invalid IEs eid = %d elem_len=%d left=%d*****",
5133 elem_id, elem_len, left);
5134 return;
5135 }
5136 if (IE_EID_VENDOR == elem_id)
5137 {
5138 /* skipping the VSIE's which we don't want to include or
5139 * it will be included by existing code
5140 */
5141 if ((memcmp( &ptr[2], WPS_OUI_TYPE, WPS_OUI_TYPE_SIZE) != 0 ) &&
5142#ifdef WLAN_FEATURE_WFD
5143 (memcmp( &ptr[2], WFD_OUI_TYPE, WFD_OUI_TYPE_SIZE) != 0) &&
5144#endif
5145 (memcmp( &ptr[2], WHITELIST_OUI_TYPE, WPA_OUI_TYPE_SIZE) != 0) &&
5146 (memcmp( &ptr[2], BLACKLIST_OUI_TYPE, WPA_OUI_TYPE_SIZE) != 0) &&
5147 (memcmp( &ptr[2], "\x00\x50\xf2\x02", WPA_OUI_TYPE_SIZE) != 0) &&
5148 (memcmp( &ptr[2], WPA_OUI_TYPE, WPA_OUI_TYPE_SIZE) != 0) &&
5149 (memcmp( &ptr[2], P2P_OUI_TYPE, P2P_OUI_TYPE_SIZE) != 0))
5150 {
5151 ielen = ptr[1] + 2;
5152 if ((*total_ielen + ielen) <= MAX_GENIE_LEN)
5153 {
5154 vos_mem_copy(&genie[*total_ielen], ptr, ielen);
5155 *total_ielen += ielen;
5156 }
5157 else
5158 {
5159 hddLog( VOS_TRACE_LEVEL_ERROR,
5160 "IE Length is too big "
5161 "IEs eid=%d elem_len=%d total_ie_lent=%d",
5162 elem_id, elem_len, *total_ielen);
5163 }
5164 }
5165 }
5166
5167 left -= elem_len;
5168 ptr += (elem_len + 2);
5169 }
5170 return;
5171}
5172
Jeff Johnson04dd8a82012-06-29 20:41:40 -07005173#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,4,0))
Jeff Johnson295189b2012-06-20 16:38:30 -07005174static int wlan_hdd_cfg80211_update_apies(hdd_adapter_t* pHostapdAdapter,
5175 struct beacon_parameters *params)
Jeff Johnson04dd8a82012-06-29 20:41:40 -07005176#else
5177static int wlan_hdd_cfg80211_update_apies(hdd_adapter_t* pHostapdAdapter,
5178 struct cfg80211_beacon_data *params)
5179#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07005180{
5181 v_U8_t *genie;
Gopichand Nakkala2b25f4e2013-03-21 19:14:07 +05305182 v_U8_t total_ielen = 0;
Jeff Johnson295189b2012-06-20 16:38:30 -07005183 v_U8_t addIE[1] = {0};
Jeff Johnsone7245742012-09-05 17:12:55 -07005184 int ret = 0;
Jeff Johnson295189b2012-06-20 16:38:30 -07005185
5186 genie = vos_mem_malloc(MAX_GENIE_LEN);
5187
5188 if(genie == NULL) {
5189
5190 return -ENOMEM;
5191 }
5192
Gopichand Nakkala2b25f4e2013-03-21 19:14:07 +05305193 if (0 != wlan_hdd_add_ie(pHostapdAdapter, genie,
5194 &total_ielen, WPS_OUI_TYPE, WPS_OUI_TYPE_SIZE))
Jeff Johnson295189b2012-06-20 16:38:30 -07005195 {
c_hpothu6ff1c3c2013-10-01 19:01:57 +05305196 hddLog(LOGE,
5197 FL("Adding WPS IE failed"));
Gopichand Nakkala2b25f4e2013-03-21 19:14:07 +05305198 ret = -EINVAL;
5199 goto done;
Jeff Johnson295189b2012-06-20 16:38:30 -07005200 }
5201
5202#ifdef WLAN_FEATURE_WFD
Gopichand Nakkala2b25f4e2013-03-21 19:14:07 +05305203 if (0 != wlan_hdd_add_ie(pHostapdAdapter, genie,
5204 &total_ielen, WFD_OUI_TYPE, WFD_OUI_TYPE_SIZE))
5205 {
c_hpothu6ff1c3c2013-10-01 19:01:57 +05305206 hddLog(LOGE,
5207 FL("Adding WFD IE failed"));
Gopichand Nakkala2b25f4e2013-03-21 19:14:07 +05305208 ret = -EINVAL;
5209 goto done;
Jeff Johnson295189b2012-06-20 16:38:30 -07005210 }
5211#endif
5212
Gopichand Nakkala2b25f4e2013-03-21 19:14:07 +05305213 if (0 != wlan_hdd_add_ie(pHostapdAdapter, genie,
5214 &total_ielen, P2P_OUI_TYPE, P2P_OUI_TYPE_SIZE))
Jeff Johnson295189b2012-06-20 16:38:30 -07005215 {
c_hpothu6ff1c3c2013-10-01 19:01:57 +05305216 hddLog(LOGE,
5217 FL("Adding P2P IE failed"));
Gopichand Nakkala2b25f4e2013-03-21 19:14:07 +05305218 ret = -EINVAL;
5219 goto done;
5220 }
5221
5222 if (WLAN_HDD_SOFTAP == pHostapdAdapter->device_mode)
5223 {
Arif Hussaine7f3ea52013-09-12 21:56:36 -07005224 wlan_hdd_add_hostapd_conf_vsie(pHostapdAdapter, genie, &total_ielen);
Jeff Johnson295189b2012-06-20 16:38:30 -07005225 }
Jeff Johnson295189b2012-06-20 16:38:30 -07005226
5227 if (ccmCfgSetStr((WLAN_HDD_GET_CTX(pHostapdAdapter))->hHal,
5228 WNI_CFG_PROBE_RSP_BCN_ADDNIE_DATA, genie, total_ielen, NULL,
5229 eANI_BOOLEAN_FALSE)==eHAL_STATUS_FAILURE)
5230 {
5231 hddLog(LOGE,
5232 "Could not pass on WNI_CFG_PROBE_RSP_BCN_ADDNIE_DATA to CCM");
Jeff Johnsone7245742012-09-05 17:12:55 -07005233 ret = -EINVAL;
5234 goto done;
Jeff Johnson295189b2012-06-20 16:38:30 -07005235 }
5236
5237 if (ccmCfgSetInt((WLAN_HDD_GET_CTX(pHostapdAdapter))->hHal,
5238 WNI_CFG_PROBE_RSP_BCN_ADDNIE_FLAG, 1,NULL,
5239 test_bit(SOFTAP_BSS_STARTED, &pHostapdAdapter->event_flags) ?
5240 eANI_BOOLEAN_TRUE : eANI_BOOLEAN_FALSE)
5241 ==eHAL_STATUS_FAILURE)
5242 {
5243 hddLog(LOGE,
5244 "Could not pass on WNI_CFG_PROBE_RSP_BCN_ADDNIE_FLAG to CCM");
Jeff Johnsone7245742012-09-05 17:12:55 -07005245 ret = -EINVAL;
5246 goto done;
Jeff Johnson295189b2012-06-20 16:38:30 -07005247 }
5248
5249 // Added for ProResp IE
5250 if ( (params->proberesp_ies != NULL) && (params->proberesp_ies_len != 0) )
5251 {
5252 u16 rem_probe_resp_ie_len = params->proberesp_ies_len;
5253 u8 probe_rsp_ie_len[3] = {0};
5254 u8 counter = 0;
5255 /* Check Probe Resp Length if it is greater then 255 then Store
5256 Probe Resp IEs into WNI_CFG_PROBE_RSP_ADDNIE_DATA1 &
5257 WNI_CFG_PROBE_RSP_ADDNIE_DATA2 CFG Variable As We are not able
5258 Store More then 255 bytes into One Variable.
5259 */
5260 while ((rem_probe_resp_ie_len > 0) && (counter < 3))
5261 {
5262 if (rem_probe_resp_ie_len > MAX_CFG_STRING_LEN)
5263 {
5264 probe_rsp_ie_len[counter++] = MAX_CFG_STRING_LEN;
5265 rem_probe_resp_ie_len -= MAX_CFG_STRING_LEN;
5266 }
5267 else
5268 {
5269 probe_rsp_ie_len[counter++] = rem_probe_resp_ie_len;
5270 rem_probe_resp_ie_len = 0;
5271 }
5272 }
5273
5274 rem_probe_resp_ie_len = 0;
5275
5276 if (probe_rsp_ie_len[0] > 0)
5277 {
5278 if (ccmCfgSetStr((WLAN_HDD_GET_CTX(pHostapdAdapter))->hHal,
5279 WNI_CFG_PROBE_RSP_ADDNIE_DATA1,
5280 (tANI_U8*)&params->proberesp_ies[rem_probe_resp_ie_len],
5281 probe_rsp_ie_len[0], NULL,
5282 eANI_BOOLEAN_FALSE) == eHAL_STATUS_FAILURE)
5283 {
5284 hddLog(LOGE,
5285 "Could not pass on WNI_CFG_PROBE_RSP_ADDNIE_DATA1 to CCM");
Jeff Johnsone7245742012-09-05 17:12:55 -07005286 ret = -EINVAL;
5287 goto done;
Jeff Johnson295189b2012-06-20 16:38:30 -07005288 }
5289 rem_probe_resp_ie_len += probe_rsp_ie_len[0];
5290 }
5291
5292 if (probe_rsp_ie_len[1] > 0)
5293 {
5294 if (ccmCfgSetStr((WLAN_HDD_GET_CTX(pHostapdAdapter))->hHal,
5295 WNI_CFG_PROBE_RSP_ADDNIE_DATA2,
5296 (tANI_U8*)&params->proberesp_ies[rem_probe_resp_ie_len],
5297 probe_rsp_ie_len[1], NULL,
5298 eANI_BOOLEAN_FALSE) == eHAL_STATUS_FAILURE)
5299 {
5300 hddLog(LOGE,
5301 "Could not pass on WNI_CFG_PROBE_RSP_ADDNIE_DATA2 to CCM");
Jeff Johnsone7245742012-09-05 17:12:55 -07005302 ret = -EINVAL;
5303 goto done;
Jeff Johnson295189b2012-06-20 16:38:30 -07005304 }
5305 rem_probe_resp_ie_len += probe_rsp_ie_len[1];
5306 }
5307
5308 if (probe_rsp_ie_len[2] > 0)
5309 {
5310 if (ccmCfgSetStr((WLAN_HDD_GET_CTX(pHostapdAdapter))->hHal,
5311 WNI_CFG_PROBE_RSP_ADDNIE_DATA3,
5312 (tANI_U8*)&params->proberesp_ies[rem_probe_resp_ie_len],
5313 probe_rsp_ie_len[2], NULL,
5314 eANI_BOOLEAN_FALSE) == eHAL_STATUS_FAILURE)
5315 {
5316 hddLog(LOGE,
5317 "Could not pass on WNI_CFG_PROBE_RSP_ADDNIE_DATA3 to CCM");
Jeff Johnsone7245742012-09-05 17:12:55 -07005318 ret = -EINVAL;
5319 goto done;
Jeff Johnson295189b2012-06-20 16:38:30 -07005320 }
5321 rem_probe_resp_ie_len += probe_rsp_ie_len[2];
5322 }
5323
5324 if (probe_rsp_ie_len[1] == 0 )
5325 {
5326 if ( eHAL_STATUS_FAILURE == ccmCfgSetStr((WLAN_HDD_GET_CTX(pHostapdAdapter))->hHal,
5327 WNI_CFG_PROBE_RSP_ADDNIE_DATA2, (tANI_U8*)addIE, 0, NULL,
5328 eANI_BOOLEAN_FALSE) )
5329 {
5330 hddLog(LOGE,
Arif Hussain6d2a3322013-11-17 19:50:10 -08005331 "Could not pass on WNI_CFG_PROBE_RSP_ADDNIE_DATA2 to CCM");
Jeff Johnson295189b2012-06-20 16:38:30 -07005332 }
5333 }
5334
5335 if (probe_rsp_ie_len[2] == 0 )
5336 {
5337 if ( eHAL_STATUS_FAILURE == ccmCfgSetStr((WLAN_HDD_GET_CTX(pHostapdAdapter))->hHal,
5338 WNI_CFG_PROBE_RSP_ADDNIE_DATA3, (tANI_U8*)addIE, 0, NULL,
5339 eANI_BOOLEAN_FALSE) )
5340 {
5341 hddLog(LOGE,
Arif Hussain6d2a3322013-11-17 19:50:10 -08005342 "Could not pass on WNI_CFG_PROBE_RSP_ADDNIE_DATA3 to CCM");
Jeff Johnson295189b2012-06-20 16:38:30 -07005343 }
5344 }
5345
5346 if (ccmCfgSetInt((WLAN_HDD_GET_CTX(pHostapdAdapter))->hHal,
5347 WNI_CFG_PROBE_RSP_ADDNIE_FLAG, 1,NULL,
5348 test_bit(SOFTAP_BSS_STARTED, &pHostapdAdapter->event_flags) ?
5349 eANI_BOOLEAN_TRUE : eANI_BOOLEAN_FALSE)
5350 == eHAL_STATUS_FAILURE)
5351 {
5352 hddLog(LOGE,
5353 "Could not pass on WNI_CFG_PROBE_RSP_ADDNIE_FLAG to CCM");
Jeff Johnsone7245742012-09-05 17:12:55 -07005354 ret = -EINVAL;
5355 goto done;
Jeff Johnson295189b2012-06-20 16:38:30 -07005356 }
5357 }
5358 else
5359 {
5360 // Reset WNI_CFG_PROBE_RSP Flags
5361 wlan_hdd_reset_prob_rspies(pHostapdAdapter);
5362
5363 hddLog(VOS_TRACE_LEVEL_INFO,
5364 "%s: No Probe Response IE received in set beacon",
5365 __func__);
5366 }
5367
5368 // Added for AssocResp IE
5369 if ( (params->assocresp_ies != NULL) && (params->assocresp_ies_len != 0) )
5370 {
5371 if (ccmCfgSetStr((WLAN_HDD_GET_CTX(pHostapdAdapter))->hHal,
5372 WNI_CFG_ASSOC_RSP_ADDNIE_DATA, (tANI_U8*)params->assocresp_ies,
5373 params->assocresp_ies_len, NULL,
5374 eANI_BOOLEAN_FALSE) == eHAL_STATUS_FAILURE)
5375 {
5376 hddLog(LOGE,
5377 "Could not pass on WNI_CFG_ASSOC_RSP_ADDNIE_DATA to CCM");
Jeff Johnsone7245742012-09-05 17:12:55 -07005378 ret = -EINVAL;
5379 goto done;
Jeff Johnson295189b2012-06-20 16:38:30 -07005380 }
5381
5382 if (ccmCfgSetInt((WLAN_HDD_GET_CTX(pHostapdAdapter))->hHal,
5383 WNI_CFG_ASSOC_RSP_ADDNIE_FLAG, 1, NULL,
5384 test_bit(SOFTAP_BSS_STARTED, &pHostapdAdapter->event_flags) ?
5385 eANI_BOOLEAN_TRUE : eANI_BOOLEAN_FALSE)
5386 == eHAL_STATUS_FAILURE)
5387 {
5388 hddLog(LOGE,
5389 "Could not pass on WNI_CFG_ASSOC_RSP_ADDNIE_FLAG to CCM");
Jeff Johnsone7245742012-09-05 17:12:55 -07005390 ret = -EINVAL;
5391 goto done;
Jeff Johnson295189b2012-06-20 16:38:30 -07005392 }
5393 }
5394 else
5395 {
5396 hddLog(VOS_TRACE_LEVEL_INFO,
5397 "%s: No Assoc Response IE received in set beacon",
5398 __func__);
5399
5400 if ( eHAL_STATUS_FAILURE == ccmCfgSetInt((WLAN_HDD_GET_CTX(pHostapdAdapter))->hHal,
5401 WNI_CFG_ASSOC_RSP_ADDNIE_FLAG, 0, NULL,
5402 eANI_BOOLEAN_FALSE) )
5403 {
5404 hddLog(LOGE,
Arif Hussain6d2a3322013-11-17 19:50:10 -08005405 "Could not pass on WNI_CFG_ASSOC_RSP_ADDNIE_FLAG to CCM");
Jeff Johnson295189b2012-06-20 16:38:30 -07005406 }
5407 }
5408
Jeff Johnsone7245742012-09-05 17:12:55 -07005409done:
Jeff Johnson295189b2012-06-20 16:38:30 -07005410 vos_mem_free(genie);
Gopichand Nakkala2b25f4e2013-03-21 19:14:07 +05305411 return ret;
Jeff Johnson295189b2012-06-20 16:38:30 -07005412}
Jeff Johnson295189b2012-06-20 16:38:30 -07005413
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305414/*
Jeff Johnson295189b2012-06-20 16:38:30 -07005415 * FUNCTION: wlan_hdd_validate_operation_channel
5416 * called by wlan_hdd_cfg80211_start_bss() and
5417 * wlan_hdd_cfg80211_set_channel()
5418 * This function validates whether given channel is part of valid
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305419 * channel list.
5420 */
Varun Reddy Yeturu920df212013-05-22 08:07:23 -07005421VOS_STATUS wlan_hdd_validate_operation_channel(hdd_adapter_t *pAdapter,int channel)
Jeff Johnson295189b2012-06-20 16:38:30 -07005422{
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305423
Jeff Johnson295189b2012-06-20 16:38:30 -07005424 v_U32_t num_ch = 0;
5425 u8 valid_ch[WNI_CFG_VALID_CHANNEL_LIST_LEN];
5426 u32 indx = 0;
5427 tHalHandle hHal = WLAN_HDD_GET_HAL_CTX(pAdapter);
Madan Mohan Koyylamudi64267f72013-02-05 14:07:08 +05305428 v_U8_t fValidChannel = FALSE, count = 0;
5429 hdd_config_t *hdd_pConfig_ini= (WLAN_HDD_GET_CTX(pAdapter))->cfg_ini;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305430
Jeff Johnson295189b2012-06-20 16:38:30 -07005431 num_ch = WNI_CFG_VALID_CHANNEL_LIST_LEN;
5432
Madan Mohan Koyylamudi64267f72013-02-05 14:07:08 +05305433 if ( hdd_pConfig_ini->sapAllowAllChannel)
Jeff Johnson295189b2012-06-20 16:38:30 -07005434 {
Madan Mohan Koyylamudi64267f72013-02-05 14:07:08 +05305435 /* Validate the channel */
5436 for (count = RF_CHAN_1 ; count <= RF_CHAN_165 ; count++)
Jeff Johnson295189b2012-06-20 16:38:30 -07005437 {
Madan Mohan Koyylamudi64267f72013-02-05 14:07:08 +05305438 if ( channel == rfChannels[count].channelNum )
5439 {
5440 fValidChannel = TRUE;
5441 break;
5442 }
5443 }
5444 if (fValidChannel != TRUE)
5445 {
5446 hddLog(VOS_TRACE_LEVEL_ERROR,
5447 "%s: Invalid Channel [%d]", __func__, channel);
5448 return VOS_STATUS_E_FAILURE;
Jeff Johnson295189b2012-06-20 16:38:30 -07005449 }
5450 }
Madan Mohan Koyylamudi64267f72013-02-05 14:07:08 +05305451 else
Jeff Johnson295189b2012-06-20 16:38:30 -07005452 {
Madan Mohan Koyylamudi64267f72013-02-05 14:07:08 +05305453 if (0 != ccmCfgGetStr(hHal, WNI_CFG_VALID_CHANNEL_LIST,
5454 valid_ch, &num_ch))
5455 {
5456 hddLog(VOS_TRACE_LEVEL_ERROR,
5457 "%s: failed to get valid channel list", __func__);
5458 return VOS_STATUS_E_FAILURE;
5459 }
5460 for (indx = 0; indx < num_ch; indx++)
5461 {
5462 if (channel == valid_ch[indx])
5463 {
5464 break;
5465 }
5466 }
5467
Rashmi Ramanna3b59e122014-04-10 14:45:13 +05305468 if (indx >= num_ch)
5469 {
5470 if (WLAN_HDD_P2P_GO == pAdapter->device_mode)
5471 {
5472 eCsrBand band;
5473 unsigned int freq;
5474
5475 sme_GetFreqBand(hHal, &band);
5476
5477 if (eCSR_BAND_5G == band)
5478 {
5479#if (LINUX_VERSION_CODE > KERNEL_VERSION(2,6,38))
5480 if (channel <= ARRAY_SIZE(hdd_channels_2_4_GHZ))
5481 {
5482 freq = ieee80211_channel_to_frequency(channel,
5483 IEEE80211_BAND_2GHZ);
5484 }
5485 else
5486 {
5487 freq = ieee80211_channel_to_frequency(channel,
5488 IEEE80211_BAND_5GHZ);
5489 }
5490#else
5491 freq = ieee80211_channel_to_frequency(channel);
5492#endif
5493 if(WLAN_HDD_IS_SOCIAL_CHANNEL(freq))
5494 return VOS_STATUS_SUCCESS;
5495 }
5496 }
5497
5498 hddLog(VOS_TRACE_LEVEL_ERROR,
5499 "%s: Invalid Channel [%d]", __func__, channel);
5500 return VOS_STATUS_E_FAILURE;
5501 }
Jeff Johnson295189b2012-06-20 16:38:30 -07005502 }
Rashmi Ramanna3b59e122014-04-10 14:45:13 +05305503
Jeff Johnson295189b2012-06-20 16:38:30 -07005504 return VOS_STATUS_SUCCESS;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305505
Jeff Johnson295189b2012-06-20 16:38:30 -07005506}
5507
Viral Modi3a32cc52013-02-08 11:14:52 -08005508/**
5509 * FUNCTION: wlan_hdd_cfg80211_set_channel
5510 * This function is used to set the channel number
5511 */
5512static int wlan_hdd_cfg80211_set_channel( struct wiphy *wiphy, struct net_device *dev,
5513 struct ieee80211_channel *chan,
5514 enum nl80211_channel_type channel_type
5515 )
5516{
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05305517 hdd_adapter_t *pAdapter = NULL;
Viral Modi3a32cc52013-02-08 11:14:52 -08005518 v_U32_t num_ch = 0;
Jeff Johnson4416a782013-03-25 14:17:50 -07005519 int channel = 0;
Viral Modi3a32cc52013-02-08 11:14:52 -08005520 int freq = chan->center_freq; /* freq is in MHZ */
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05305521 hdd_context_t *pHddCtx;
5522 int status;
Viral Modi3a32cc52013-02-08 11:14:52 -08005523
5524 ENTER();
5525
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05305526
Viral Modi3a32cc52013-02-08 11:14:52 -08005527 if( NULL == dev )
5528 {
5529 hddLog(VOS_TRACE_LEVEL_ERROR,
Arif Hussain6d2a3322013-11-17 19:50:10 -08005530 "%s: Called with dev = NULL.", __func__);
Viral Modi3a32cc52013-02-08 11:14:52 -08005531 return -ENODEV;
5532 }
5533 pAdapter = WLAN_HDD_GET_PRIV_PTR( dev );
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +05305534
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05305535 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
5536 TRACE_CODE_HDD_CFG80211_SET_CHANNEL, pAdapter->sessionId,
5537 channel_type ));
Viral Modi3a32cc52013-02-08 11:14:52 -08005538 hddLog(VOS_TRACE_LEVEL_INFO,
Sushant Kaushik8bc7df22014-04-09 17:55:29 +05305539 "%s: device_mode = %s (%d) freq = %d", __func__,
5540 hdd_device_modetoString(pAdapter->device_mode),
5541 pAdapter->device_mode, chan->center_freq);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05305542
5543 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
5544 status = wlan_hdd_validate_context(pHddCtx);
5545
5546 if (0 != status)
Viral Modi3a32cc52013-02-08 11:14:52 -08005547 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05305548 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
5549 "%s: HDD context is not valid", __func__);
5550 return status;
Viral Modi3a32cc52013-02-08 11:14:52 -08005551 }
5552
5553 /*
5554 * Do freq to chan conversion
5555 * TODO: for 11a
5556 */
5557
5558 channel = ieee80211_frequency_to_channel(freq);
5559
5560 /* Check freq range */
5561 if ((WNI_CFG_CURRENT_CHANNEL_STAMIN > channel) ||
5562 (WNI_CFG_CURRENT_CHANNEL_STAMAX < channel))
5563 {
5564 hddLog(VOS_TRACE_LEVEL_ERROR,
Arif Hussain6d2a3322013-11-17 19:50:10 -08005565 "%s: Channel [%d] is outside valid range from %d to %d",
Viral Modi3a32cc52013-02-08 11:14:52 -08005566 __func__, channel, WNI_CFG_CURRENT_CHANNEL_STAMIN,
5567 WNI_CFG_CURRENT_CHANNEL_STAMAX);
5568 return -EINVAL;
5569 }
5570
5571 num_ch = WNI_CFG_VALID_CHANNEL_LIST_LEN;
5572
Gopichand Nakkala6ab19562013-03-07 13:59:42 +05305573 if ((WLAN_HDD_SOFTAP != pAdapter->device_mode) &&
5574 (WLAN_HDD_P2P_GO != pAdapter->device_mode))
Viral Modi3a32cc52013-02-08 11:14:52 -08005575 {
5576 if(VOS_STATUS_SUCCESS != wlan_hdd_validate_operation_channel(pAdapter,channel))
5577 {
5578 hddLog(VOS_TRACE_LEVEL_ERROR,
Arif Hussain6d2a3322013-11-17 19:50:10 -08005579 "%s: Invalid Channel [%d]", __func__, channel);
Viral Modi3a32cc52013-02-08 11:14:52 -08005580 return -EINVAL;
5581 }
5582 hddLog(VOS_TRACE_LEVEL_INFO_HIGH,
5583 "%s: set channel to [%d] for device mode =%d",
5584 __func__, channel,pAdapter->device_mode);
5585 }
5586 if( (pAdapter->device_mode == WLAN_HDD_INFRA_STATION)
Viral Modi3a32cc52013-02-08 11:14:52 -08005587 || (pAdapter->device_mode == WLAN_HDD_P2P_CLIENT)
Viral Modi3a32cc52013-02-08 11:14:52 -08005588 )
5589 {
5590 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
5591 tCsrRoamProfile * pRoamProfile = &pWextState->roamProfile;
5592 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
5593
5594 if (eConnectionState_IbssConnected == pHddStaCtx->conn_info.connState)
5595 {
5596 /* Link is up then return cant set channel*/
5597 hddLog( VOS_TRACE_LEVEL_ERROR,
Arif Hussain6d2a3322013-11-17 19:50:10 -08005598 "%s: IBSS Associated, can't set the channel", __func__);
Viral Modi3a32cc52013-02-08 11:14:52 -08005599 return -EINVAL;
5600 }
5601
5602 num_ch = pRoamProfile->ChannelInfo.numOfChannels = 1;
5603 pHddStaCtx->conn_info.operationChannel = channel;
5604 pRoamProfile->ChannelInfo.ChannelList =
5605 &pHddStaCtx->conn_info.operationChannel;
5606 }
5607 else if ((pAdapter->device_mode == WLAN_HDD_SOFTAP)
Viral Modi3a32cc52013-02-08 11:14:52 -08005608 || (pAdapter->device_mode == WLAN_HDD_P2P_GO)
Viral Modi3a32cc52013-02-08 11:14:52 -08005609 )
5610 {
Gopichand Nakkalac8fa7b62013-03-11 13:56:41 +05305611 if (WLAN_HDD_P2P_GO == pAdapter->device_mode)
5612 {
5613 if(VOS_STATUS_SUCCESS !=
5614 wlan_hdd_validate_operation_channel(pAdapter,channel))
5615 {
5616 hddLog(VOS_TRACE_LEVEL_ERROR,
Arif Hussain6d2a3322013-11-17 19:50:10 -08005617 "%s: Invalid Channel [%d]", __func__, channel);
Gopichand Nakkalac8fa7b62013-03-11 13:56:41 +05305618 return -EINVAL;
5619 }
5620 (WLAN_HDD_GET_AP_CTX_PTR(pAdapter))->sapConfig.channel = channel;
5621 }
5622 else if ( WLAN_HDD_SOFTAP == pAdapter->device_mode )
Viral Modi3a32cc52013-02-08 11:14:52 -08005623 {
5624 hdd_config_t *cfg_param = (WLAN_HDD_GET_CTX(pAdapter))->cfg_ini;
5625
5626 /* If auto channel selection is configured as enable/ 1 then ignore
5627 channel set by supplicant
5628 */
5629 if ( cfg_param->apAutoChannelSelection )
5630 {
Gopichand Nakkalac8fa7b62013-03-11 13:56:41 +05305631 (WLAN_HDD_GET_AP_CTX_PTR(pAdapter))->sapConfig.channel =
5632 AUTO_CHANNEL_SELECT;
Viral Modi3a32cc52013-02-08 11:14:52 -08005633 hddLog(VOS_TRACE_LEVEL_INFO_HIGH,
Sushant Kaushik8bc7df22014-04-09 17:55:29 +05305634 "%s: set channel to auto channel (0) for device mode =%s (%d)",
5635 __func__, hdd_device_modetoString(pAdapter->device_mode),
5636 pAdapter->device_mode);
Viral Modi3a32cc52013-02-08 11:14:52 -08005637 }
Gopichand Nakkalac8fa7b62013-03-11 13:56:41 +05305638 else
5639 {
5640 if(VOS_STATUS_SUCCESS !=
5641 wlan_hdd_validate_operation_channel(pAdapter,channel))
5642 {
5643 hddLog(VOS_TRACE_LEVEL_ERROR,
Arif Hussain6d2a3322013-11-17 19:50:10 -08005644 "%s: Invalid Channel [%d]", __func__, channel);
Gopichand Nakkalac8fa7b62013-03-11 13:56:41 +05305645 return -EINVAL;
5646 }
5647 (WLAN_HDD_GET_AP_CTX_PTR(pAdapter))->sapConfig.channel = channel;
5648 }
Viral Modi3a32cc52013-02-08 11:14:52 -08005649 }
5650 }
5651 else
5652 {
5653 hddLog(VOS_TRACE_LEVEL_FATAL,
5654 "%s: Invalid device mode failed to set valid channel", __func__);
5655 return -EINVAL;
5656 }
5657 EXIT();
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05305658 return status;
Viral Modi3a32cc52013-02-08 11:14:52 -08005659}
5660
Jeff Johnson295189b2012-06-20 16:38:30 -07005661#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,4,0))
5662static int wlan_hdd_cfg80211_start_bss(hdd_adapter_t *pHostapdAdapter,
5663 struct beacon_parameters *params)
Jeff Johnson04dd8a82012-06-29 20:41:40 -07005664#else
5665static int wlan_hdd_cfg80211_start_bss(hdd_adapter_t *pHostapdAdapter,
5666 struct cfg80211_beacon_data *params,
5667 const u8 *ssid, size_t ssid_len,
5668 enum nl80211_hidden_ssid hidden_ssid)
5669#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07005670{
5671 tsap_Config_t *pConfig;
5672 beacon_data_t *pBeacon = NULL;
5673 struct ieee80211_mgmt *pMgmt_frame;
5674 v_U8_t *pIe=NULL;
5675 v_U16_t capab_info;
5676 eCsrAuthType RSNAuthType;
5677 eCsrEncryptionType RSNEncryptType;
5678 eCsrEncryptionType mcRSNEncryptType;
5679 int status = VOS_STATUS_SUCCESS;
5680 tpWLAN_SAPEventCB pSapEventCallback;
5681 hdd_hostapd_state_t *pHostapdState;
5682 v_U8_t wpaRsnIEdata[(SIR_MAC_MAX_IE_LENGTH * 2)+4]; //Max ie length 255 * 2(WPA+RSN) + 2 bytes (vendor specific ID) * 2
5683 v_CONTEXT_t pVosContext = (WLAN_HDD_GET_CTX(pHostapdAdapter))->pvosContext;
Madan Mohan Koyylamudia16d0202013-02-01 11:05:57 +05305684 tHalHandle hHal = WLAN_HDD_GET_HAL_CTX(pHostapdAdapter);
Jeff Johnson295189b2012-06-20 16:38:30 -07005685 struct qc_mac_acl_entry *acl_entry = NULL;
Siddharth Bhal5cba24e2014-05-08 18:59:39 +05305686 hdd_config_t *iniConfig;
Jeff Johnson295189b2012-06-20 16:38:30 -07005687 v_SINT_t i;
Madan Mohan Koyyalamudi543172b2012-12-05 16:40:18 -08005688 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pHostapdAdapter);
Chet Lanctot40142442014-05-20 13:39:25 -07005689 v_BOOL_t MFPCapable = VOS_FALSE;
5690 v_BOOL_t MFPRequired = VOS_FALSE;
Abhishek Singhf0ac1752014-03-05 17:47:09 +05305691 eHddDot11Mode sapDot11Mode =
5692 (WLAN_HDD_GET_CTX(pHostapdAdapter))->cfg_ini->sapDot11Mode;
Jeff Johnson295189b2012-06-20 16:38:30 -07005693
5694 ENTER();
5695
Siddharth Bhal5cba24e2014-05-08 18:59:39 +05305696 iniConfig = pHddCtx->cfg_ini;
5697
Jeff Johnson295189b2012-06-20 16:38:30 -07005698 pHostapdState = WLAN_HDD_GET_HOSTAP_STATE_PTR(pHostapdAdapter);
5699
5700 pConfig = &pHostapdAdapter->sessionCtx.ap.sapConfig;
5701
5702 pBeacon = pHostapdAdapter->sessionCtx.ap.beacon;
5703
5704 pMgmt_frame = (struct ieee80211_mgmt*)pBeacon->head;
5705
5706 pConfig->beacon_int = pMgmt_frame->u.beacon.beacon_int;
5707
5708 //channel is already set in the set_channel Call back
5709 //pConfig->channel = pCommitConfig->channel;
5710
5711 /*Protection parameter to enable or disable*/
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305712 pConfig->protEnabled =
Jeff Johnson295189b2012-06-20 16:38:30 -07005713 (WLAN_HDD_GET_CTX(pHostapdAdapter))->cfg_ini->apProtEnabled;
5714
5715 pConfig->dtim_period = pBeacon->dtim_period;
5716
Arif Hussain6d2a3322013-11-17 19:50:10 -08005717 hddLog(VOS_TRACE_LEVEL_INFO_HIGH,"****pConfig->dtim_period=%d***",
Jeff Johnson295189b2012-06-20 16:38:30 -07005718 pConfig->dtim_period);
5719
5720
Madan Mohan Koyyalamudie0ca11f2012-11-27 15:57:52 -08005721 if (pHostapdAdapter->device_mode == WLAN_HDD_SOFTAP)
Jeff Johnson32d95a32012-09-10 13:15:23 -07005722 {
5723 pIe = wlan_hdd_cfg80211_get_ie_ptr(pBeacon->tail, pBeacon->tail_len,
Jeff Johnson295189b2012-06-20 16:38:30 -07005724 WLAN_EID_COUNTRY);
Kiet Lam083504c2013-11-25 14:17:45 +05305725 if(memcmp(pHddCtx->cfg_ini->apCntryCode, CFG_AP_COUNTRY_CODE_DEFAULT, 3) != 0)
5726 {
5727 tANI_BOOLEAN restartNeeded;
5728 pConfig->ieee80211d = 1;
5729 vos_mem_copy(pConfig->countryCode, pHddCtx->cfg_ini->apCntryCode, 3);
5730 sme_setRegInfo(hHal, pConfig->countryCode);
5731 sme_ResetCountryCodeInformation(hHal, &restartNeeded);
5732 }
5733 else if(pIe)
Jeff Johnson295189b2012-06-20 16:38:30 -07005734 {
Jeff Johnson32d95a32012-09-10 13:15:23 -07005735 tANI_BOOLEAN restartNeeded;
Jeff Johnson32d95a32012-09-10 13:15:23 -07005736 pConfig->ieee80211d = 1;
5737 vos_mem_copy(pConfig->countryCode, &pIe[2], 3);
5738 sme_setRegInfo(hHal, pConfig->countryCode);
5739 sme_ResetCountryCodeInformation(hHal, &restartNeeded);
Jeff Johnson295189b2012-06-20 16:38:30 -07005740 }
Jeff Johnson32d95a32012-09-10 13:15:23 -07005741 else
5742 {
5743 pConfig->ieee80211d = 0;
5744 }
Madan Mohan Koyylamudia16d0202013-02-01 11:05:57 +05305745 /*
5746 * If auto channel is configured i.e. channel is 0,
5747 * so skip channel validation.
5748 */
5749 if( AUTO_CHANNEL_SELECT != pConfig->channel )
5750 {
5751 if(VOS_STATUS_SUCCESS != wlan_hdd_validate_operation_channel(pHostapdAdapter,pConfig->channel))
5752 {
5753 hddLog(VOS_TRACE_LEVEL_ERROR,
Arif Hussain6d2a3322013-11-17 19:50:10 -08005754 "%s: Invalid Channel [%d]", __func__, pConfig->channel);
Madan Mohan Koyylamudia16d0202013-02-01 11:05:57 +05305755 return -EINVAL;
5756 }
5757 }
5758 else
5759 {
5760 if(1 != pHddCtx->is_dynamic_channel_range_set)
5761 {
5762 hdd_config_t *hdd_pConfig= (WLAN_HDD_GET_CTX(pHostapdAdapter))->cfg_ini;
5763 WLANSAP_SetChannelRange(hHal, hdd_pConfig->apStartChannelNum,
5764 hdd_pConfig->apEndChannelNum,hdd_pConfig->apOperatingBand);
5765 }
5766 pHddCtx->is_dynamic_channel_range_set = 0;
5767 }
Jeff Johnson295189b2012-06-20 16:38:30 -07005768 }
Jeff Johnson32d95a32012-09-10 13:15:23 -07005769 else
Jeff Johnson295189b2012-06-20 16:38:30 -07005770 {
5771 pConfig->ieee80211d = 0;
5772 }
5773 pConfig->authType = eSAP_AUTO_SWITCH;
5774
5775 capab_info = pMgmt_frame->u.beacon.capab_info;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305776
5777 pConfig->privacy = (pMgmt_frame->u.beacon.capab_info &
Jeff Johnson295189b2012-06-20 16:38:30 -07005778 WLAN_CAPABILITY_PRIVACY) ? VOS_TRUE : VOS_FALSE;
5779
5780 (WLAN_HDD_GET_AP_CTX_PTR(pHostapdAdapter))->uPrivacy = pConfig->privacy;
5781
5782 /*Set wps station to configured*/
5783 pIe = wlan_hdd_get_wps_ie_ptr(pBeacon->tail, pBeacon->tail_len);
5784
5785 if(pIe)
5786 {
5787 if(pIe[1] < (2 + WPS_OUI_TYPE_SIZE))
5788 {
Arif Hussain6d2a3322013-11-17 19:50:10 -08005789 hddLog( VOS_TRACE_LEVEL_ERROR, "**Wps Ie Length is too small***");
Jeff Johnson295189b2012-06-20 16:38:30 -07005790 return -EINVAL;
5791 }
5792 else if(memcmp(&pIe[2], WPS_OUI_TYPE, WPS_OUI_TYPE_SIZE) == 0)
5793 {
Madan Mohan Koyyalamudi8bdd3112012-09-24 13:55:14 -07005794 hddLog( VOS_TRACE_LEVEL_INFO, "** WPS IE(len %d) ***", (pIe[1]+2));
Jeff Johnson295189b2012-06-20 16:38:30 -07005795 /* Check 15 bit of WPS IE as it contain information for wps state
5796 * WPS state
5797 */
5798 if(SAP_WPS_ENABLED_UNCONFIGURED == pIe[15])
5799 {
5800 pConfig->wps_state = SAP_WPS_ENABLED_UNCONFIGURED;
5801 } else if(SAP_WPS_ENABLED_CONFIGURED == pIe[15])
5802 {
5803 pConfig->wps_state = SAP_WPS_ENABLED_CONFIGURED;
5804 }
5805 }
5806 }
5807 else
5808 {
5809 pConfig->wps_state = SAP_WPS_DISABLED;
5810 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305811 pConfig->fwdWPSPBCProbeReq = 1; // Forward WPS PBC probe request frame up
Jeff Johnson295189b2012-06-20 16:38:30 -07005812
c_hpothufe599e92014-06-16 11:38:55 +05305813 pConfig->RSNEncryptType = eCSR_ENCRYPT_TYPE_NONE;
5814 pConfig->mcRSNEncryptType = eCSR_ENCRYPT_TYPE_NONE;
5815 (WLAN_HDD_GET_AP_CTX_PTR(pHostapdAdapter))->ucEncryptType =
5816 eCSR_ENCRYPT_TYPE_NONE;
5817
Jeff Johnson295189b2012-06-20 16:38:30 -07005818 pConfig->RSNWPAReqIELength = 0;
5819 pConfig->pRSNWPAReqIE = NULL;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305820 pIe = wlan_hdd_cfg80211_get_ie_ptr(pBeacon->tail, pBeacon->tail_len,
Jeff Johnson295189b2012-06-20 16:38:30 -07005821 WLAN_EID_RSN);
5822 if(pIe && pIe[1])
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305823 {
Jeff Johnson295189b2012-06-20 16:38:30 -07005824 pConfig->RSNWPAReqIELength = pIe[1] + 2;
5825 memcpy(&wpaRsnIEdata[0], pIe, pConfig->RSNWPAReqIELength);
5826 pConfig->pRSNWPAReqIE = &wpaRsnIEdata[0];
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305827 /* The actual processing may eventually be more extensive than
5828 * this. Right now, just consume any PMKIDs that are sent in
Jeff Johnson295189b2012-06-20 16:38:30 -07005829 * by the app.
5830 * */
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305831 status = hdd_softap_unpackIE(
Jeff Johnson295189b2012-06-20 16:38:30 -07005832 vos_get_context( VOS_MODULE_ID_SME, pVosContext),
5833 &RSNEncryptType,
5834 &mcRSNEncryptType,
5835 &RSNAuthType,
Chet Lanctot8cecea22014-02-11 19:09:36 -08005836 &MFPCapable,
5837 &MFPRequired,
Jeff Johnson295189b2012-06-20 16:38:30 -07005838 pConfig->pRSNWPAReqIE[1]+2,
5839 pConfig->pRSNWPAReqIE );
5840
5841 if( VOS_STATUS_SUCCESS == status )
5842 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305843 /* Now copy over all the security attributes you have
5844 * parsed out
Jeff Johnson295189b2012-06-20 16:38:30 -07005845 * */
5846 pConfig->RSNEncryptType = RSNEncryptType; // Use the cipher type in the RSN IE
5847 pConfig->mcRSNEncryptType = mcRSNEncryptType;
5848 (WLAN_HDD_GET_AP_CTX_PTR(pHostapdAdapter))->ucEncryptType
5849 = RSNEncryptType;
Gopichand Nakkala66c0bd02013-04-10 11:36:29 +05305850 hddLog( LOG1, FL("CSR AuthType = %d, "
Arif Hussain6d2a3322013-11-17 19:50:10 -08005851 "EncryptionType = %d mcEncryptionType = %d"),
Jeff Johnson295189b2012-06-20 16:38:30 -07005852 RSNAuthType, RSNEncryptType, mcRSNEncryptType);
5853 }
5854 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305855
Jeff Johnson295189b2012-06-20 16:38:30 -07005856 pIe = wlan_hdd_get_vendor_oui_ie_ptr(WPA_OUI_TYPE, WPA_OUI_TYPE_SIZE,
5857 pBeacon->tail, pBeacon->tail_len);
5858
5859 if(pIe && pIe[1] && (pIe[0] == DOT11F_EID_WPA))
5860 {
5861 if (pConfig->pRSNWPAReqIE)
5862 {
5863 /*Mixed mode WPA/WPA2*/
5864 memcpy((&wpaRsnIEdata[0] + pConfig->RSNWPAReqIELength), pIe, pIe[1] + 2);
5865 pConfig->RSNWPAReqIELength += pIe[1] + 2;
5866 }
5867 else
5868 {
5869 pConfig->RSNWPAReqIELength = pIe[1] + 2;
5870 memcpy(&wpaRsnIEdata[0], pIe, pConfig->RSNWPAReqIELength);
5871 pConfig->pRSNWPAReqIE = &wpaRsnIEdata[0];
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305872 status = hdd_softap_unpackIE(
Jeff Johnson295189b2012-06-20 16:38:30 -07005873 vos_get_context( VOS_MODULE_ID_SME, pVosContext),
5874 &RSNEncryptType,
5875 &mcRSNEncryptType,
5876 &RSNAuthType,
Chet Lanctot8cecea22014-02-11 19:09:36 -08005877 &MFPCapable,
5878 &MFPRequired,
Jeff Johnson295189b2012-06-20 16:38:30 -07005879 pConfig->pRSNWPAReqIE[1]+2,
5880 pConfig->pRSNWPAReqIE );
5881
5882 if( VOS_STATUS_SUCCESS == status )
5883 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305884 /* Now copy over all the security attributes you have
5885 * parsed out
Jeff Johnson295189b2012-06-20 16:38:30 -07005886 * */
5887 pConfig->RSNEncryptType = RSNEncryptType; // Use the cipher type in the RSN IE
5888 pConfig->mcRSNEncryptType = mcRSNEncryptType;
5889 (WLAN_HDD_GET_AP_CTX_PTR(pHostapdAdapter))->ucEncryptType
5890 = RSNEncryptType;
Gopichand Nakkala66c0bd02013-04-10 11:36:29 +05305891 hddLog( LOG1, FL("CSR AuthType = %d, "
Arif Hussain6d2a3322013-11-17 19:50:10 -08005892 "EncryptionType = %d mcEncryptionType = %d"),
Jeff Johnson295189b2012-06-20 16:38:30 -07005893 RSNAuthType, RSNEncryptType, mcRSNEncryptType);
5894 }
5895 }
5896 }
5897
Jeff Johnson4416a782013-03-25 14:17:50 -07005898 if (pConfig->RSNWPAReqIELength > sizeof wpaRsnIEdata) {
5899 hddLog( VOS_TRACE_LEVEL_ERROR, "**RSNWPAReqIELength is too large***");
5900 return -EINVAL;
5901 }
5902
Jeff Johnson295189b2012-06-20 16:38:30 -07005903 pConfig->SSIDinfo.ssidHidden = VOS_FALSE;
5904
Jeff Johnson04dd8a82012-06-29 20:41:40 -07005905#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,4,0))
Jeff Johnson295189b2012-06-20 16:38:30 -07005906 if (params->ssid != NULL)
5907 {
5908 memcpy(pConfig->SSIDinfo.ssid.ssId, params->ssid, params->ssid_len);
5909 pConfig->SSIDinfo.ssid.length = params->ssid_len;
5910 if (params->hidden_ssid != NL80211_HIDDEN_SSID_NOT_IN_USE)
5911 pConfig->SSIDinfo.ssidHidden = VOS_TRUE;
5912 }
Jeff Johnson04dd8a82012-06-29 20:41:40 -07005913#else
5914 if (ssid != NULL)
5915 {
5916 memcpy(pConfig->SSIDinfo.ssid.ssId, ssid, ssid_len);
5917 pConfig->SSIDinfo.ssid.length = ssid_len;
5918 if (hidden_ssid != NL80211_HIDDEN_SSID_NOT_IN_USE)
5919 pConfig->SSIDinfo.ssidHidden = VOS_TRUE;
5920 }
5921#endif
5922
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305923 vos_mem_copy(pConfig->self_macaddr.bytes,
Jeff Johnson295189b2012-06-20 16:38:30 -07005924 pHostapdAdapter->macAddressCurrent.bytes, sizeof(v_MACADDR_t));
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305925
Jeff Johnson295189b2012-06-20 16:38:30 -07005926 /* default value */
5927 pConfig->SapMacaddr_acl = eSAP_ACCEPT_UNLESS_DENIED;
5928 pConfig->num_accept_mac = 0;
5929 pConfig->num_deny_mac = 0;
5930
5931 pIe = wlan_hdd_get_vendor_oui_ie_ptr(BLACKLIST_OUI_TYPE, WPA_OUI_TYPE_SIZE,
5932 pBeacon->tail, pBeacon->tail_len);
5933
5934 /* pIe for black list is following form:
5935 type : 1 byte
5936 length : 1 byte
5937 OUI : 4 bytes
5938 acl type : 1 byte
5939 no of mac addr in black list: 1 byte
5940 list of mac_acl_entries: variable, 6 bytes per mac address + sizeof(int) for vlan id
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305941 */
5942 if ((pIe != NULL) && (pIe[1] != 0))
Jeff Johnson295189b2012-06-20 16:38:30 -07005943 {
5944 pConfig->SapMacaddr_acl = pIe[6];
5945 pConfig->num_deny_mac = pIe[7];
Arif Hussain6d2a3322013-11-17 19:50:10 -08005946 hddLog(VOS_TRACE_LEVEL_INFO,"acl type = %d no deny mac = %d",
Jeff Johnson295189b2012-06-20 16:38:30 -07005947 pIe[6], pIe[7]);
Gopichand Nakkalac005b7c2013-05-14 16:04:14 +05305948 if (pConfig->num_deny_mac > MAX_ACL_MAC_ADDRESS)
5949 pConfig->num_deny_mac = MAX_ACL_MAC_ADDRESS;
Jeff Johnson295189b2012-06-20 16:38:30 -07005950 acl_entry = (struct qc_mac_acl_entry *)(pIe + 8);
5951 for (i = 0; i < pConfig->num_deny_mac; i++)
5952 {
5953 vos_mem_copy(&pConfig->deny_mac[i], acl_entry->addr, sizeof(qcmacaddr));
5954 acl_entry++;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305955 }
Jeff Johnson295189b2012-06-20 16:38:30 -07005956 }
5957 pIe = wlan_hdd_get_vendor_oui_ie_ptr(WHITELIST_OUI_TYPE, WPA_OUI_TYPE_SIZE,
5958 pBeacon->tail, pBeacon->tail_len);
5959
5960 /* pIe for white list is following form:
5961 type : 1 byte
5962 length : 1 byte
5963 OUI : 4 bytes
5964 acl type : 1 byte
5965 no of mac addr in white list: 1 byte
5966 list of mac_acl_entries: variable, 6 bytes per mac address + sizeof(int) for vlan id
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305967 */
5968 if ((pIe != NULL) && (pIe[1] != 0))
Jeff Johnson295189b2012-06-20 16:38:30 -07005969 {
5970 pConfig->SapMacaddr_acl = pIe[6];
5971 pConfig->num_accept_mac = pIe[7];
Arif Hussain6d2a3322013-11-17 19:50:10 -08005972 hddLog(VOS_TRACE_LEVEL_INFO,"acl type = %d no accept mac = %d",
Jeff Johnson295189b2012-06-20 16:38:30 -07005973 pIe[6], pIe[7]);
Gopichand Nakkalac005b7c2013-05-14 16:04:14 +05305974 if (pConfig->num_accept_mac > MAX_ACL_MAC_ADDRESS)
5975 pConfig->num_accept_mac = MAX_ACL_MAC_ADDRESS;
Jeff Johnson295189b2012-06-20 16:38:30 -07005976 acl_entry = (struct qc_mac_acl_entry *)(pIe + 8);
5977 for (i = 0; i < pConfig->num_accept_mac; i++)
5978 {
5979 vos_mem_copy(&pConfig->accept_mac[i], acl_entry->addr, sizeof(qcmacaddr));
5980 acl_entry++;
5981 }
5982 }
Gopichand Nakkalac005b7c2013-05-14 16:04:14 +05305983
Jeff Johnson295189b2012-06-20 16:38:30 -07005984 wlan_hdd_set_sapHwmode(pHostapdAdapter);
5985
Jeff Johnsone7245742012-09-05 17:12:55 -07005986#ifdef WLAN_FEATURE_11AC
Ravi Kumar Vaishnavbbaebbe2013-01-15 17:09:48 -08005987 /* Overwrite the hostapd setting for HW mode only for 11ac.
Kiet Lam0f320422013-11-21 19:29:17 +05305988 * This is valid only if mode is set to 11n in hostapd, either AUTO or
5989 * 11ac in .ini and 11ac is supported by both host and firmware.
5990 * Otherwise, leave whatever is set in hostapd (a OR b OR g OR n mode)
5991 */
Ravi Kumar Vaishnavbbaebbe2013-01-15 17:09:48 -08005992 if( ((pConfig->SapHw_mode == eSAP_DOT11_MODE_11n) ||
5993 (pConfig->SapHw_mode == eSAP_DOT11_MODE_11n_ONLY)) &&
Abhishek Singhf0ac1752014-03-05 17:47:09 +05305994 (( sapDot11Mode == eHDD_DOT11_MODE_AUTO ) ||
5995 ( sapDot11Mode == eHDD_DOT11_MODE_11ac ) ||
5996 ( sapDot11Mode == eHDD_DOT11_MODE_11ac_ONLY ) ) &&
5997 (sme_IsFeatureSupportedByDriver(DOT11AC)) &&
5998 (sme_IsFeatureSupportedByFW(DOT11AC)) )
Jeff Johnsone7245742012-09-05 17:12:55 -07005999 {
Siddharth Bhalf42f8592014-05-15 13:39:07 +05306000 v_U32_t operatingBand = 0;
Jeff Johnsone7245742012-09-05 17:12:55 -07006001 pConfig->SapHw_mode = eSAP_DOT11_MODE_11ac;
Siddharth Bhalf42f8592014-05-15 13:39:07 +05306002 ccmCfgGetInt(hHal, WNI_CFG_SAP_CHANNEL_SELECT_OPERATING_BAND, &operatingBand);
Ravi Joshi83bfaa12013-05-28 22:12:08 -07006003
Siddharth Bhal5cba24e2014-05-08 18:59:39 +05306004 /* If ACS disable and selected channel <= 14
6005 * OR
6006 * ACS enabled and ACS operating band is choosen as 2.4
6007 * AND
6008 * VHT in 2.4G Disabled
6009 * THEN
6010 * Fallback to 11N mode
6011 */
6012 if (((AUTO_CHANNEL_SELECT != pConfig->channel && pConfig->channel <= SIR_11B_CHANNEL_END)
6013 || (AUTO_CHANNEL_SELECT == pConfig->channel &&
Siddharth Bhalf42f8592014-05-15 13:39:07 +05306014 operatingBand == RF_SUBBAND_2_4_GHZ)) &&
Siddharth Bhal5cba24e2014-05-08 18:59:39 +05306015 iniConfig->enableVhtFor24GHzBand == FALSE)
Ravi Joshi83bfaa12013-05-28 22:12:08 -07006016 {
Siddharth Bhalf42f8592014-05-15 13:39:07 +05306017 hddLog(LOGW, FL("Setting hwmode to 11n, operatingBand = %d, Channel = %d"),
6018 operatingBand, pConfig->channel);
Ravi Joshi83bfaa12013-05-28 22:12:08 -07006019 pConfig->SapHw_mode = eSAP_DOT11_MODE_11n;
6020 }
Jeff Johnsone7245742012-09-05 17:12:55 -07006021 }
6022#endif
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306023
Ravi Joshiaeb7d9e2013-05-02 12:28:14 -07006024 if ( AUTO_CHANNEL_SELECT != pConfig->channel )
6025 {
6026 sme_SelectCBMode(hHal,
6027 sapConvertSapPhyModeToCsrPhyMode(pConfig->SapHw_mode),
6028 pConfig->channel);
6029 }
Jeff Johnson295189b2012-06-20 16:38:30 -07006030 // ht_capab is not what the name conveys,this is used for protection bitmap
6031 pConfig->ht_capab =
6032 (WLAN_HDD_GET_CTX(pHostapdAdapter))->cfg_ini->apProtection;
6033
6034 if ( 0 != wlan_hdd_cfg80211_update_apies(pHostapdAdapter, params) )
6035 {
6036 hddLog(LOGE, FL("SAP Not able to set AP IEs"));
6037 return -EINVAL;
6038 }
6039
6040 //Uapsd Enabled Bit
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306041 pConfig->UapsdEnable =
Jeff Johnson295189b2012-06-20 16:38:30 -07006042 (WLAN_HDD_GET_CTX(pHostapdAdapter))->cfg_ini->apUapsdEnabled;
6043 //Enable OBSS protection
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306044 pConfig->obssProtEnabled =
6045 (WLAN_HDD_GET_CTX(pHostapdAdapter))->cfg_ini->apOBSSProtEnabled;
Jeff Johnson295189b2012-06-20 16:38:30 -07006046
Chet Lanctot8cecea22014-02-11 19:09:36 -08006047#ifdef WLAN_FEATURE_11W
6048 pConfig->mfpCapable = MFPCapable;
6049 pConfig->mfpRequired = MFPRequired;
6050 hddLog(LOGW, FL("Soft AP MFP capable %d, MFP required %d\n"),
6051 pConfig->mfpCapable, pConfig->mfpRequired);
6052#endif
6053
Arif Hussain6d2a3322013-11-17 19:50:10 -08006054 hddLog(LOGW, FL("SOftAP macaddress : "MAC_ADDRESS_STR),
Jeff Johnson295189b2012-06-20 16:38:30 -07006055 MAC_ADDR_ARRAY(pHostapdAdapter->macAddressCurrent.bytes));
Arif Hussain6d2a3322013-11-17 19:50:10 -08006056 hddLog(LOGW,FL("ssid =%s, beaconint=%d, channel=%d"),
6057 pConfig->SSIDinfo.ssid.ssId, (int)pConfig->beacon_int,
6058 (int)pConfig->channel);
6059 hddLog(LOGW,FL("hw_mode=%x, privacy=%d, authType=%d"),
6060 pConfig->SapHw_mode, pConfig->privacy,
6061 pConfig->authType);
6062 hddLog(LOGW,FL("RSN/WPALen=%d, Uapsd = %d"),
6063 (int)pConfig->RSNWPAReqIELength, pConfig->UapsdEnable);
6064 hddLog(LOGW,FL("ProtEnabled = %d, OBSSProtEnabled = %d"),
6065 pConfig->protEnabled, pConfig->obssProtEnabled);
Jeff Johnson295189b2012-06-20 16:38:30 -07006066
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306067 if(test_bit(SOFTAP_BSS_STARTED, &pHostapdAdapter->event_flags))
Jeff Johnson295189b2012-06-20 16:38:30 -07006068 {
6069 //Bss already started. just return.
6070 //TODO Probably it should update some beacon params.
6071 hddLog( LOGE, "Bss Already started...Ignore the request");
6072 EXIT();
6073 return 0;
6074 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306075
Agarwal Ashish51325b52014-06-16 16:50:49 +05306076 if (vos_max_concurrent_connections_reached()) {
6077 hddLog(VOS_TRACE_LEVEL_INFO, FL("Reached max concurrent connections"));
6078 return -EINVAL;
6079 }
6080
Jeff Johnson295189b2012-06-20 16:38:30 -07006081 pConfig->persona = pHostapdAdapter->device_mode;
6082
6083 pSapEventCallback = hdd_hostapd_SAPEventCB;
6084 if(WLANSAP_StartBss(pVosContext, pSapEventCallback, pConfig,
6085 (v_PVOID_t)pHostapdAdapter->dev) != VOS_STATUS_SUCCESS)
6086 {
Arif Hussain6d2a3322013-11-17 19:50:10 -08006087 hddLog(LOGE,FL("SAP Start Bss fail"));
Jeff Johnson295189b2012-06-20 16:38:30 -07006088 return -EINVAL;
6089 }
6090
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306091 hddLog(LOG1,
Jeff Johnson295189b2012-06-20 16:38:30 -07006092 FL("Waiting for Scan to complete(auto mode) and BSS to start"));
6093
6094 status = vos_wait_single_event(&pHostapdState->vosEvent, 10000);
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306095
Jeff Johnson295189b2012-06-20 16:38:30 -07006096 if (!VOS_IS_STATUS_SUCCESS(status))
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306097 {
6098 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Arif Hussain6d2a3322013-11-17 19:50:10 -08006099 ("ERROR: HDD vos wait for single_event failed!!"));
Tushnim Bhattacharyyaad37df12013-10-02 12:01:33 -07006100 smeGetCommandQStatus(hHal);
Jeff Johnson295189b2012-06-20 16:38:30 -07006101 VOS_ASSERT(0);
6102 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306103
Jeff Johnson295189b2012-06-20 16:38:30 -07006104 set_bit(SOFTAP_BSS_STARTED, &pHostapdAdapter->event_flags);
Agarwal Ashish51325b52014-06-16 16:50:49 +05306105 wlan_hdd_incr_active_session(pHddCtx, pHostapdAdapter->device_mode);
Jeff Johnson295189b2012-06-20 16:38:30 -07006106
Madan Mohan Koyyalamudi26bd7142012-10-30 18:14:19 -07006107#ifdef WLAN_FEATURE_P2P_DEBUG
6108 if (pHostapdAdapter->device_mode == WLAN_HDD_P2P_GO)
6109 {
6110 if(globalP2PConnectionStatus == P2P_GO_NEG_COMPLETED)
6111 {
6112 globalP2PConnectionStatus = P2P_GO_COMPLETED_STATE;
6113 hddLog(LOGE,"[P2P State] From Go nego completed to "
Jeff Johnson1250df42012-12-10 14:31:52 -08006114 "Non-autonomous Group started");
Madan Mohan Koyyalamudi26bd7142012-10-30 18:14:19 -07006115 }
6116 else if(globalP2PConnectionStatus == P2P_NOT_ACTIVE)
6117 {
6118 globalP2PConnectionStatus = P2P_GO_COMPLETED_STATE;
6119 hddLog(LOGE,"[P2P State] From Inactive to "
Jeff Johnson1250df42012-12-10 14:31:52 -08006120 "Autonomous Group started");
Madan Mohan Koyyalamudi26bd7142012-10-30 18:14:19 -07006121 }
6122 }
6123#endif
6124
Jeff Johnson295189b2012-06-20 16:38:30 -07006125 pHostapdState->bCommit = TRUE;
6126 EXIT();
6127
6128 return 0;
6129}
6130
Jeff Johnson04dd8a82012-06-29 20:41:40 -07006131#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,4,0))
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306132static int wlan_hdd_cfg80211_add_beacon(struct wiphy *wiphy,
6133 struct net_device *dev,
Jeff Johnson295189b2012-06-20 16:38:30 -07006134 struct beacon_parameters *params)
6135{
6136 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +05306137 hdd_context_t *pHddCtx;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05306138 int status;
Jeff Johnson295189b2012-06-20 16:38:30 -07006139
6140 ENTER();
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +05306141
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05306142 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
6143 TRACE_CODE_HDD_CFG80211_ADD_BEACON,
6144 pAdapter->sessionId, params->interval));
Sushant Kaushik8bc7df22014-04-09 17:55:29 +05306145 hddLog(VOS_TRACE_LEVEL_INFO_HIGH, "device mode=%s (%d)",
6146 hdd_device_modetoString(pAdapter->device_mode),
6147 pAdapter->device_mode);
Jeff Johnson295189b2012-06-20 16:38:30 -07006148
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05306149 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
6150 status = wlan_hdd_validate_context(pHddCtx);
6151
6152 if (0 != status)
Jeff Johnson04dd8a82012-06-29 20:41:40 -07006153 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05306154 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
6155 "%s: HDD context is not valid", __func__);
6156 return status;
Jeff Johnson04dd8a82012-06-29 20:41:40 -07006157 }
6158
Agarwal Ashish51325b52014-06-16 16:50:49 +05306159 if (vos_max_concurrent_connections_reached()) {
6160 hddLog(VOS_TRACE_LEVEL_INFO, FL("Reached max concurrent connections"));
6161 return -EINVAL;
6162 }
6163
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306164 if ( (pAdapter->device_mode == WLAN_HDD_SOFTAP)
Jeff Johnson295189b2012-06-20 16:38:30 -07006165 || (pAdapter->device_mode == WLAN_HDD_P2P_GO)
Jeff Johnson295189b2012-06-20 16:38:30 -07006166 )
6167 {
6168 beacon_data_t *old,*new;
6169
6170 old = pAdapter->sessionCtx.ap.beacon;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306171
Jeff Johnson295189b2012-06-20 16:38:30 -07006172 if (old)
c_hpothu6ff1c3c2013-10-01 19:01:57 +05306173 {
6174 hddLog(VOS_TRACE_LEVEL_WARN,
6175 FL("already beacon info added to session(%d)"),
6176 pAdapter->sessionId);
Jeff Johnson295189b2012-06-20 16:38:30 -07006177 return -EALREADY;
c_hpothu6ff1c3c2013-10-01 19:01:57 +05306178 }
Jeff Johnson295189b2012-06-20 16:38:30 -07006179
6180 status = wlan_hdd_cfg80211_alloc_new_beacon(pAdapter,&new,params);
6181
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306182 if(status != VOS_STATUS_SUCCESS)
Jeff Johnson295189b2012-06-20 16:38:30 -07006183 {
6184 hddLog(VOS_TRACE_LEVEL_FATAL,
Arif Hussain6d2a3322013-11-17 19:50:10 -08006185 "%s:Error!!! Allocating the new beacon",__func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07006186 return -EINVAL;
6187 }
6188
6189 pAdapter->sessionCtx.ap.beacon = new;
6190
6191 status = wlan_hdd_cfg80211_start_bss(pAdapter, params);
6192 }
6193
6194 EXIT();
6195 return status;
6196}
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306197
6198static int wlan_hdd_cfg80211_set_beacon(struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -07006199 struct net_device *dev,
6200 struct beacon_parameters *params)
6201{
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306202 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +05306203 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
6204 hdd_context_t *pHddCtx;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05306205 int status;
Jeff Johnson295189b2012-06-20 16:38:30 -07006206
6207 ENTER();
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +05306208 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
6209 TRACE_CODE_HDD_CFG80211_SET_BEACON,
6210 pAdapter->sessionId, pHddStaCtx->conn_info.authType));
6211 hddLog(VOS_TRACE_LEVEL_INFO, "%s: device_mode = %s (%d)",
6212 __func__, hdd_device_modetoString(pAdapter->device_mode),
6213 pAdapter->device_mode);
6214
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05306215 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
6216 status = wlan_hdd_validate_context(pHddCtx);
6217
6218 if (0 != status)
Jeff Johnson04dd8a82012-06-29 20:41:40 -07006219 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05306220 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
6221 "%s: HDD context is not valid", __func__);
6222 return status;
Jeff Johnson04dd8a82012-06-29 20:41:40 -07006223 }
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +05306224
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306225 if ((pAdapter->device_mode == WLAN_HDD_SOFTAP)
Jeff Johnson295189b2012-06-20 16:38:30 -07006226 || (pAdapter->device_mode == WLAN_HDD_P2P_GO)
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306227 )
Jeff Johnson295189b2012-06-20 16:38:30 -07006228 {
6229 beacon_data_t *old,*new;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306230
Jeff Johnson295189b2012-06-20 16:38:30 -07006231 old = pAdapter->sessionCtx.ap.beacon;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306232
Jeff Johnson295189b2012-06-20 16:38:30 -07006233 if (!old)
c_hpothu6ff1c3c2013-10-01 19:01:57 +05306234 {
6235 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
6236 FL("session(%d) old and new heads points to NULL"),
6237 pAdapter->sessionId);
Jeff Johnson295189b2012-06-20 16:38:30 -07006238 return -ENOENT;
c_hpothu6ff1c3c2013-10-01 19:01:57 +05306239 }
Jeff Johnson295189b2012-06-20 16:38:30 -07006240
6241 status = wlan_hdd_cfg80211_alloc_new_beacon(pAdapter,&new,params);
6242
6243 if(status != VOS_STATUS_SUCCESS) {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306244 hddLog(VOS_TRACE_LEVEL_FATAL,
Arif Hussain6d2a3322013-11-17 19:50:10 -08006245 "%s: Error!!! Allocating the new beacon",__func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07006246 return -EINVAL;
6247 }
6248
6249 pAdapter->sessionCtx.ap.beacon = new;
6250
6251 status = wlan_hdd_cfg80211_start_bss(pAdapter, params);
6252 }
6253
6254 EXIT();
6255 return status;
6256}
6257
Jeff Johnson04dd8a82012-06-29 20:41:40 -07006258#endif //(LINUX_VERSION_CODE < KERNEL_VERSION(3,4,0))
6259
6260#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,4,0))
Jeff Johnson295189b2012-06-20 16:38:30 -07006261static int wlan_hdd_cfg80211_del_beacon(struct wiphy *wiphy,
6262 struct net_device *dev)
Jeff Johnson04dd8a82012-06-29 20:41:40 -07006263#else
6264static int wlan_hdd_cfg80211_stop_ap (struct wiphy *wiphy,
6265 struct net_device *dev)
6266#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07006267{
6268 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
Jeff Johnsone7245742012-09-05 17:12:55 -07006269 hdd_context_t *pHddCtx = NULL;
6270 hdd_scaninfo_t *pScanInfo = NULL;
6271 hdd_adapter_t *staAdapter = NULL;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05306272 VOS_STATUS status;
Mahesh A Saptasagar2395ee62014-05-21 19:12:21 +05306273 long ret;
Jeff Johnson295189b2012-06-20 16:38:30 -07006274
6275 ENTER();
6276
6277 if (NULL == pAdapter)
6278 {
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +05306279 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07006280 "%s: HDD adapter context is Null", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07006281 return -ENODEV;
6282 }
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -07006283
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05306284 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
6285 TRACE_CODE_HDD_CFG80211_STOP_AP,
6286 pAdapter->sessionId, pAdapter->device_mode));
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05306287 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
6288 status = wlan_hdd_validate_context(pHddCtx);
6289
6290 if (0 != status)
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -07006291 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05306292 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
6293 "%s: HDD context is not valid", __func__);
6294 return status;
Jeff Johnson4416a782013-03-25 14:17:50 -07006295 }
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -07006296
6297 staAdapter = hdd_get_adapter(pAdapter->pHddCtx, WLAN_HDD_INFRA_STATION);
6298 if (NULL == staAdapter)
6299 {
6300 staAdapter = hdd_get_adapter(pAdapter->pHddCtx, WLAN_HDD_P2P_CLIENT);
6301 if (NULL == staAdapter)
6302 {
Rajesh Chauhan52d885b2013-11-01 10:54:25 -07006303 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO_HIGH,
6304 "%s: HDD adapter context for STA/P2P-CLI is Null",
6305 __func__);
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -07006306 }
6307 }
6308
6309 pScanInfo = &pHddCtx->scan_info;
6310
Sushant Kaushik8bc7df22014-04-09 17:55:29 +05306311 hddLog(VOS_TRACE_LEVEL_INFO, "%s: device_mode = %s (%d)",
6312 __func__, hdd_device_modetoString(pAdapter->device_mode),
6313 pAdapter->device_mode);
Jeff Johnson295189b2012-06-20 16:38:30 -07006314
Mahesh A Saptasagar2395ee62014-05-21 19:12:21 +05306315 ret = wlan_hdd_scan_abort(pAdapter);
6316
Girish Gowli4bf7a632014-06-12 13:42:11 +05306317 if (ret < 0)
Jeff Johnsone7245742012-09-05 17:12:55 -07006318 {
Mahesh A Saptasagar2395ee62014-05-21 19:12:21 +05306319 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
6320 FL("Timeout occurred while waiting for abortscan %ld"), ret);
c_hpothu6ff1c3c2013-10-01 19:01:57 +05306321
Mahesh A Saptasagar2395ee62014-05-21 19:12:21 +05306322 if (pHddCtx->isLogpInProgress)
Jeff Johnsone7245742012-09-05 17:12:55 -07006323 {
Mahesh A Saptasagar2395ee62014-05-21 19:12:21 +05306324 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
6325 "%s: LOGP in Progress. Ignore!!!", __func__);
Yue Ma4f55ef32014-01-23 16:45:33 -08006326
Jeff Johnsone7245742012-09-05 17:12:55 -07006327 VOS_ASSERT(pScanInfo->mScanPending);
Mahesh A Saptasagar2395ee62014-05-21 19:12:21 +05306328 return -EAGAIN;
Jeff Johnsone7245742012-09-05 17:12:55 -07006329 }
Mahesh A Saptasagar2395ee62014-05-21 19:12:21 +05306330 VOS_ASSERT(pScanInfo->mScanPending);
Jeff Johnsone7245742012-09-05 17:12:55 -07006331 }
6332
Arun Kumar Khandavallia3bd8002014-01-17 16:21:19 +05306333 hdd_hostapd_stop(dev);
6334
Jeff Johnson295189b2012-06-20 16:38:30 -07006335 if ((pAdapter->device_mode == WLAN_HDD_SOFTAP)
Jeff Johnson295189b2012-06-20 16:38:30 -07006336 || (pAdapter->device_mode == WLAN_HDD_P2P_GO)
Jeff Johnson295189b2012-06-20 16:38:30 -07006337 )
6338 {
6339 beacon_data_t *old;
6340
6341 old = pAdapter->sessionCtx.ap.beacon;
6342
6343 if (!old)
c_hpothu6ff1c3c2013-10-01 19:01:57 +05306344 {
6345 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
6346 FL("session(%d) beacon data points to NULL"),
6347 pAdapter->sessionId);
Jeff Johnson295189b2012-06-20 16:38:30 -07006348 return -ENOENT;
c_hpothu6ff1c3c2013-10-01 19:01:57 +05306349 }
Jeff Johnson295189b2012-06-20 16:38:30 -07006350
Jeff Johnson295189b2012-06-20 16:38:30 -07006351 hdd_cleanup_actionframe(pHddCtx, pAdapter);
Jeff Johnson295189b2012-06-20 16:38:30 -07006352
6353 mutex_lock(&pHddCtx->sap_lock);
6354 if(test_bit(SOFTAP_BSS_STARTED, &pAdapter->event_flags))
6355 {
Jeff Johnson4416a782013-03-25 14:17:50 -07006356 if ( VOS_STATUS_SUCCESS == (status = WLANSAP_StopBss(pHddCtx->pvosContext) ) )
Jeff Johnson295189b2012-06-20 16:38:30 -07006357 {
6358 hdd_hostapd_state_t *pHostapdState = WLAN_HDD_GET_HOSTAP_STATE_PTR(pAdapter);
6359
6360 status = vos_wait_single_event(&pHostapdState->vosEvent, 10000);
6361
6362 if (!VOS_IS_STATUS_SUCCESS(status))
6363 {
6364 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Arif Hussain6d2a3322013-11-17 19:50:10 -08006365 ("ERROR: HDD vos wait for single_event failed!!"));
Jeff Johnson295189b2012-06-20 16:38:30 -07006366 VOS_ASSERT(0);
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05306367 }
6368 }
Jeff Johnson295189b2012-06-20 16:38:30 -07006369 clear_bit(SOFTAP_BSS_STARTED, &pAdapter->event_flags);
Agarwal Ashish51325b52014-06-16 16:50:49 +05306370 /* BSS stopped, clear the active sessions for this device mode */
6371 wlan_hdd_decr_active_session(pHddCtx, pAdapter->device_mode);
Jeff Johnson295189b2012-06-20 16:38:30 -07006372 }
6373 mutex_unlock(&pHddCtx->sap_lock);
6374
6375 if(status != VOS_STATUS_SUCCESS)
6376 {
6377 hddLog(VOS_TRACE_LEVEL_FATAL,
Arif Hussain6d2a3322013-11-17 19:50:10 -08006378 "%s:Error!!! Stopping the BSS",__func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07006379 return -EINVAL;
6380 }
6381
Jeff Johnson4416a782013-03-25 14:17:50 -07006382 if (ccmCfgSetInt(pHddCtx->hHal,
Jeff Johnson295189b2012-06-20 16:38:30 -07006383 WNI_CFG_PROBE_RSP_BCN_ADDNIE_FLAG, 0,NULL, eANI_BOOLEAN_FALSE)
6384 ==eHAL_STATUS_FAILURE)
6385 {
6386 hddLog(LOGE,
Arif Hussain6d2a3322013-11-17 19:50:10 -08006387 "Could not pass on WNI_CFG_PROBE_RSP_BCN_ADDNIE_FLAG to CCM");
Jeff Johnson295189b2012-06-20 16:38:30 -07006388 }
6389
Jeff Johnson4416a782013-03-25 14:17:50 -07006390 if ( eHAL_STATUS_FAILURE == ccmCfgSetInt(pHddCtx->hHal,
Jeff Johnson295189b2012-06-20 16:38:30 -07006391 WNI_CFG_ASSOC_RSP_ADDNIE_FLAG, 0, NULL,
6392 eANI_BOOLEAN_FALSE) )
6393 {
6394 hddLog(LOGE,
Arif Hussain6d2a3322013-11-17 19:50:10 -08006395 "Could not pass on WNI_CFG_ASSOC_RSP_ADDNIE_FLAG to CCM");
Jeff Johnson295189b2012-06-20 16:38:30 -07006396 }
6397
6398 // Reset WNI_CFG_PROBE_RSP Flags
6399 wlan_hdd_reset_prob_rspies(pAdapter);
6400
6401 pAdapter->sessionCtx.ap.beacon = NULL;
6402 kfree(old);
Madan Mohan Koyyalamudi26bd7142012-10-30 18:14:19 -07006403#ifdef WLAN_FEATURE_P2P_DEBUG
6404 if((pAdapter->device_mode == WLAN_HDD_P2P_GO) &&
6405 (globalP2PConnectionStatus == P2P_GO_COMPLETED_STATE))
6406 {
6407 hddLog(LOGE,"[P2P State] From GO completed to Inactive state "
6408 "GO got removed");
6409 globalP2PConnectionStatus = P2P_NOT_ACTIVE;
6410 }
6411#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07006412 }
6413 EXIT();
6414 return status;
6415}
Jeff Johnson04dd8a82012-06-29 20:41:40 -07006416
6417#if (LINUX_VERSION_CODE > KERNEL_VERSION(3,3,0))
6418
Pratik Bhalgata0c7f262012-11-22 17:40:24 +05306419static int wlan_hdd_cfg80211_start_ap(struct wiphy *wiphy,
6420 struct net_device *dev,
Jeff Johnson04dd8a82012-06-29 20:41:40 -07006421 struct cfg80211_ap_settings *params)
6422{
Pratik Bhalgata0c7f262012-11-22 17:40:24 +05306423 hdd_adapter_t *pAdapter;
6424 hdd_context_t *pHddCtx;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05306425 int status;
Jeff Johnson04dd8a82012-06-29 20:41:40 -07006426
6427 ENTER();
6428
Pratik Bhalgata0c7f262012-11-22 17:40:24 +05306429 if (NULL == dev)
Madan Mohan Koyyalamudib2c36892012-10-18 20:52:38 -07006430 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05306431 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Pratik Bhalgata0c7f262012-11-22 17:40:24 +05306432 "%s: Device is Null", __func__);
6433 return -ENODEV;
6434 }
6435
6436 pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
6437 if (NULL == pAdapter)
6438 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05306439 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Pratik Bhalgata0c7f262012-11-22 17:40:24 +05306440 "%s: HDD adapter is Null", __func__);
6441 return -ENODEV;
6442 }
6443
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05306444 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
6445 TRACE_CODE_HDD_CFG80211_START_AP, pAdapter->sessionId,
6446 params-> beacon_interval));
Pratik Bhalgata0c7f262012-11-22 17:40:24 +05306447 if (WLAN_HDD_ADAPTER_MAGIC != pAdapter->magic)
6448 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05306449 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Pratik Bhalgata0c7f262012-11-22 17:40:24 +05306450 "%s: HDD adapter magic is invalid", __func__);
6451 return -ENODEV;
6452 }
6453
6454 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05306455 status = wlan_hdd_validate_context(pHddCtx);
Pratik Bhalgata0c7f262012-11-22 17:40:24 +05306456
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05306457 if (0 != status)
Pratik Bhalgata0c7f262012-11-22 17:40:24 +05306458 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05306459 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
6460 "%s: HDD context is not valid", __func__);
6461 return status;
Pratik Bhalgata0c7f262012-11-22 17:40:24 +05306462 }
6463
Sushant Kaushik8bc7df22014-04-09 17:55:29 +05306464 hddLog(VOS_TRACE_LEVEL_INFO_HIGH, "%s: device mode = %s (%d)",
6465 __func__, hdd_device_modetoString(pAdapter->device_mode),
6466 pAdapter->device_mode);
Pratik Bhalgata0c7f262012-11-22 17:40:24 +05306467
6468 if ((pAdapter->device_mode == WLAN_HDD_SOFTAP)
Jeff Johnson04dd8a82012-06-29 20:41:40 -07006469 || (pAdapter->device_mode == WLAN_HDD_P2P_GO)
Jeff Johnson04dd8a82012-06-29 20:41:40 -07006470 )
6471 {
Pratik Bhalgata0c7f262012-11-22 17:40:24 +05306472 beacon_data_t *old, *new;
Jeff Johnson04dd8a82012-06-29 20:41:40 -07006473
6474 old = pAdapter->sessionCtx.ap.beacon;
Pratik Bhalgata0c7f262012-11-22 17:40:24 +05306475
Jeff Johnson04dd8a82012-06-29 20:41:40 -07006476 if (old)
c_hpothu6ff1c3c2013-10-01 19:01:57 +05306477 {
6478 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_WARN,
6479 FL("already beacon info added to session(%d)"),
6480 pAdapter->sessionId);
Jeff Johnson04dd8a82012-06-29 20:41:40 -07006481 return -EALREADY;
c_hpothu6ff1c3c2013-10-01 19:01:57 +05306482 }
Jeff Johnson04dd8a82012-06-29 20:41:40 -07006483
6484 status = wlan_hdd_cfg80211_alloc_new_beacon(pAdapter, &new, &params->beacon, params->dtim_period);
6485
Pratik Bhalgata0c7f262012-11-22 17:40:24 +05306486 if (status != 0)
Jeff Johnson04dd8a82012-06-29 20:41:40 -07006487 {
6488 hddLog(VOS_TRACE_LEVEL_FATAL,
Pratik Bhalgata0c7f262012-11-22 17:40:24 +05306489 "%s:Error!!! Allocating the new beacon", __func__);
Jeff Johnson04dd8a82012-06-29 20:41:40 -07006490 return -EINVAL;
6491 }
6492 pAdapter->sessionCtx.ap.beacon = new;
Viral Modi3a32cc52013-02-08 11:14:52 -08006493#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,6,0))
Yue Maf49ba872013-08-19 12:04:25 -07006494 wlan_hdd_cfg80211_set_channel(wiphy, dev,
6495#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,8,0))
6496 params->channel, params->channel_type);
6497#else
6498 params->chandef.chan, cfg80211_get_chandef_type(&(params->chandef)));
6499#endif
Viral Modi3a32cc52013-02-08 11:14:52 -08006500#endif
Jeff Johnson04dd8a82012-06-29 20:41:40 -07006501 status = wlan_hdd_cfg80211_start_bss(pAdapter, &params->beacon, params->ssid,
6502 params->ssid_len, params->hidden_ssid);
6503 }
6504
6505 EXIT();
6506 return status;
6507}
6508
6509
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306510static int wlan_hdd_cfg80211_change_beacon(struct wiphy *wiphy,
Jeff Johnson04dd8a82012-06-29 20:41:40 -07006511 struct net_device *dev,
6512 struct cfg80211_beacon_data *params)
6513{
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306514 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +05306515 hdd_context_t *pHddCtx;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05306516 int status;
Jeff Johnson04dd8a82012-06-29 20:41:40 -07006517
6518 ENTER();
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +05306519
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05306520 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
6521 TRACE_CODE_HDD_CFG80211_CHANGE_BEACON,
6522 pAdapter->sessionId, pAdapter->device_mode));
Arif Hussain6d2a3322013-11-17 19:50:10 -08006523 hddLog(VOS_TRACE_LEVEL_INFO, "%s: device_mode = %d",
Jeff Johnson04dd8a82012-06-29 20:41:40 -07006524 __func__, pAdapter->device_mode);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05306525
6526 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
6527 status = wlan_hdd_validate_context(pHddCtx);
6528
6529 if (0 != status)
Madan Mohan Koyyalamudib2c36892012-10-18 20:52:38 -07006530 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05306531 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
6532 "%s: HDD context is not valid", __func__);
6533 return status;
Madan Mohan Koyyalamudib2c36892012-10-18 20:52:38 -07006534 }
Jeff Johnson04dd8a82012-06-29 20:41:40 -07006535
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306536 if ((pAdapter->device_mode == WLAN_HDD_SOFTAP)
Jeff Johnson04dd8a82012-06-29 20:41:40 -07006537 || (pAdapter->device_mode == WLAN_HDD_P2P_GO)
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306538 )
Jeff Johnson04dd8a82012-06-29 20:41:40 -07006539 {
6540 beacon_data_t *old,*new;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306541
Jeff Johnson04dd8a82012-06-29 20:41:40 -07006542 old = pAdapter->sessionCtx.ap.beacon;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306543
Jeff Johnson04dd8a82012-06-29 20:41:40 -07006544 if (!old)
c_hpothu6ff1c3c2013-10-01 19:01:57 +05306545 {
6546 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
6547 FL("session(%d) beacon data points to NULL"),
6548 pAdapter->sessionId);
Jeff Johnson04dd8a82012-06-29 20:41:40 -07006549 return -ENOENT;
c_hpothu6ff1c3c2013-10-01 19:01:57 +05306550 }
Jeff Johnson04dd8a82012-06-29 20:41:40 -07006551
6552 status = wlan_hdd_cfg80211_alloc_new_beacon(pAdapter, &new, params, 0);
6553
6554 if(status != VOS_STATUS_SUCCESS) {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306555 hddLog(VOS_TRACE_LEVEL_FATAL,
Arif Hussain6d2a3322013-11-17 19:50:10 -08006556 "%s: Error!!! Allocating the new beacon",__func__);
Jeff Johnson04dd8a82012-06-29 20:41:40 -07006557 return -EINVAL;
6558 }
6559
6560 pAdapter->sessionCtx.ap.beacon = new;
6561
6562 status = wlan_hdd_cfg80211_start_bss(pAdapter, params, NULL, 0, 0);
6563 }
6564
6565 EXIT();
6566 return status;
6567}
6568
6569#endif //(LINUX_VERSION_CODE > KERNEL_VERSION(3,3,0))
6570
Jeff Johnson295189b2012-06-20 16:38:30 -07006571
Mahesh A Saptasagar179d2252014-06-02 21:32:21 +05306572static int __wlan_hdd_cfg80211_change_bss (struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -07006573 struct net_device *dev,
6574 struct bss_parameters *params)
6575{
6576 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
6577
6578 ENTER();
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +05306579
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05306580 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
6581 TRACE_CODE_HDD_CFG80211_CHANGE_BSS,
6582 pAdapter->sessionId, params->ap_isolate));
Sushant Kaushik8bc7df22014-04-09 17:55:29 +05306583 hddLog(VOS_TRACE_LEVEL_INFO, "%s: device_mode = %s (%d)",
6584 __func__, hdd_device_modetoString(pAdapter->device_mode),
6585 pAdapter->device_mode);
Jeff Johnson295189b2012-06-20 16:38:30 -07006586
6587 if((pAdapter->device_mode == WLAN_HDD_SOFTAP)
Jeff Johnson295189b2012-06-20 16:38:30 -07006588 || (pAdapter->device_mode == WLAN_HDD_P2P_GO)
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306589 )
Jeff Johnson295189b2012-06-20 16:38:30 -07006590 {
6591 /* ap_isolate == -1 means that in change bss, upper layer doesn't
6592 * want to update this parameter */
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306593 if (-1 != params->ap_isolate)
Jeff Johnson295189b2012-06-20 16:38:30 -07006594 {
6595 pAdapter->sessionCtx.ap.apDisableIntraBssFwd = !!params->ap_isolate;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306596 }
Jeff Johnson295189b2012-06-20 16:38:30 -07006597 }
6598
6599 EXIT();
6600 return 0;
6601}
6602
Mahesh A Saptasagar179d2252014-06-02 21:32:21 +05306603static int wlan_hdd_cfg80211_change_bss (struct wiphy *wiphy,
6604 struct net_device *dev,
6605 struct bss_parameters *params)
6606{
6607 int ret;
6608
6609 vos_ssr_protect(__func__);
6610 ret = __wlan_hdd_cfg80211_change_bss(wiphy, dev, params);
6611 vos_ssr_unprotect(__func__);
6612
6613 return ret;
6614}
Kiet Lam10841362013-11-01 11:36:50 +05306615/* FUNCTION: wlan_hdd_change_country_code_cd
6616* to wait for contry code completion
6617*/
6618void* wlan_hdd_change_country_code_cb(void *pAdapter)
6619{
6620 hdd_adapter_t *call_back_pAdapter = pAdapter;
6621 complete(&call_back_pAdapter->change_country_code);
6622 return NULL;
6623}
6624
Jeff Johnson295189b2012-06-20 16:38:30 -07006625/*
Mahesh A Saptasagar0e59c472014-04-14 19:17:41 +05306626 * FUNCTION: __wlan_hdd_cfg80211_change_iface
Jeff Johnson295189b2012-06-20 16:38:30 -07006627 * This function is used to set the interface type (INFRASTRUCTURE/ADHOC)
6628 */
Mahesh A Saptasagar0e59c472014-04-14 19:17:41 +05306629int __wlan_hdd_cfg80211_change_iface( struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -07006630 struct net_device *ndev,
6631 enum nl80211_iftype type,
6632 u32 *flags,
6633 struct vif_params *params
6634 )
6635{
6636 struct wireless_dev *wdev;
6637 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( ndev );
Rajesh Chauhana0516c62014-01-30 16:11:18 -08006638 hdd_context_t *pHddCtx;
Mohit Khanna0f232092012-09-11 14:46:08 -07006639 hdd_adapter_t *pP2pAdapter = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -07006640 tCsrRoamProfile *pRoamProfile = NULL;
6641 eCsrRoamBssType LastBSSType;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05306642 hdd_config_t *pConfig = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -07006643 eMib_dot11DesiredBssType connectedBssType;
6644 VOS_STATUS status;
c_hpothu6ff1c3c2013-10-01 19:01:57 +05306645 long ret;
Jeff Johnson295189b2012-06-20 16:38:30 -07006646
6647 ENTER();
6648
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05306649 if (!pAdapter)
Rajesh Chauhana0516c62014-01-30 16:11:18 -08006650 {
6651 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
6652 "%s: Adapter context is null", __func__);
6653 return VOS_STATUS_E_FAILURE;
6654 }
6655
6656 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
6657 if (!pHddCtx)
6658 {
6659 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
6660 "%s: HDD context is null", __func__);
6661 return VOS_STATUS_E_FAILURE;
6662 }
6663
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05306664 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
6665 TRACE_CODE_HDD_CFG80211_CHANGE_IFACE,
6666 pAdapter->sessionId, type));
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05306667 status = wlan_hdd_validate_context(pHddCtx);
6668
6669 if (0 != status)
Jeff Johnson295189b2012-06-20 16:38:30 -07006670 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05306671 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
6672 "%s: HDD context is not valid", __func__);
6673 return status;
Jeff Johnson295189b2012-06-20 16:38:30 -07006674 }
6675
Sushant Kaushik8bc7df22014-04-09 17:55:29 +05306676 hddLog(VOS_TRACE_LEVEL_INFO, "%s: device_mode = %s (%d)",
6677 __func__, hdd_device_modetoString(pAdapter->device_mode),
6678 pAdapter->device_mode);
Jeff Johnson295189b2012-06-20 16:38:30 -07006679
Agarwal Ashish51325b52014-06-16 16:50:49 +05306680 if (vos_max_concurrent_connections_reached()) {
6681 hddLog(VOS_TRACE_LEVEL_INFO, FL("Reached max concurrent connections"));
6682 return -EINVAL;
6683 }
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05306684 pConfig = pHddCtx->cfg_ini;
Jeff Johnson295189b2012-06-20 16:38:30 -07006685 wdev = ndev->ieee80211_ptr;
6686
6687#ifdef WLAN_BTAMP_FEATURE
6688 if((NL80211_IFTYPE_P2P_CLIENT == type)||
6689 (NL80211_IFTYPE_ADHOC == type)||
6690 (NL80211_IFTYPE_AP == type)||
6691 (NL80211_IFTYPE_P2P_GO == type))
6692 {
6693 pHddCtx->isAmpAllowed = VOS_FALSE;
6694 // stop AMP traffic
6695 status = WLANBAP_StopAmp();
6696 if(VOS_STATUS_SUCCESS != status )
6697 {
6698 pHddCtx->isAmpAllowed = VOS_TRUE;
6699 hddLog(VOS_TRACE_LEVEL_FATAL,
6700 "%s: Failed to stop AMP", __func__);
6701 return -EINVAL;
6702 }
6703 }
6704#endif //WLAN_BTAMP_FEATURE
6705 /* Reset the current device mode bit mask*/
6706 wlan_hdd_clear_concurrency_mode(pHddCtx, pAdapter->device_mode);
6707
6708 if( (pAdapter->device_mode == WLAN_HDD_INFRA_STATION)
Jeff Johnson295189b2012-06-20 16:38:30 -07006709 || (pAdapter->device_mode == WLAN_HDD_P2P_CLIENT)
Jeff Johnsone7245742012-09-05 17:12:55 -07006710 || (pAdapter->device_mode == WLAN_HDD_P2P_DEVICE)
Jeff Johnson295189b2012-06-20 16:38:30 -07006711 )
6712 {
6713 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
Rajesh Chauhana0516c62014-01-30 16:11:18 -08006714 if (!pWextState)
6715 {
6716 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
6717 "%s: pWextState is null", __func__);
6718 return VOS_STATUS_E_FAILURE;
6719 }
Jeff Johnson295189b2012-06-20 16:38:30 -07006720 pRoamProfile = &pWextState->roamProfile;
6721 LastBSSType = pRoamProfile->BSSType;
6722
6723 switch (type)
6724 {
6725 case NL80211_IFTYPE_STATION:
Jeff Johnson295189b2012-06-20 16:38:30 -07006726 case NL80211_IFTYPE_P2P_CLIENT:
Jeff Johnson295189b2012-06-20 16:38:30 -07006727 hddLog(VOS_TRACE_LEVEL_INFO,
6728 "%s: setting interface Type to INFRASTRUCTURE", __func__);
6729 pRoamProfile->BSSType = eCSR_BSS_TYPE_INFRASTRUCTURE;
Jeff Johnsone7245742012-09-05 17:12:55 -07006730#ifdef WLAN_FEATURE_11AC
6731 if(pConfig->dot11Mode == eHDD_DOT11_MODE_AUTO)
6732 {
6733 pConfig->dot11Mode = eHDD_DOT11_MODE_11ac;
6734 }
6735#endif
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306736 pRoamProfile->phyMode =
Jeff Johnsone7245742012-09-05 17:12:55 -07006737 hdd_cfg_xlate_to_csr_phy_mode(pConfig->dot11Mode);
Jeff Johnson295189b2012-06-20 16:38:30 -07006738 wdev->iftype = type;
Gopichand Nakkalaf527dc62012-12-31 16:35:10 -08006739 //Check for sub-string p2p to confirm its a p2p interface
6740 if (NULL != strstr(ndev->name,"p2p"))
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306741 {
Gopichand Nakkala864d3552012-12-31 16:08:51 -08006742 pAdapter->device_mode = (type == NL80211_IFTYPE_STATION) ?
6743 WLAN_HDD_P2P_DEVICE : WLAN_HDD_P2P_CLIENT;
6744 }
6745 else
6746 {
6747 pAdapter->device_mode = (type == NL80211_IFTYPE_STATION) ?
Jeff Johnson295189b2012-06-20 16:38:30 -07006748 WLAN_HDD_INFRA_STATION: WLAN_HDD_P2P_CLIENT;
Gopichand Nakkala864d3552012-12-31 16:08:51 -08006749 }
Madan Mohan Koyyalamudi81746922013-07-17 14:38:51 +05306750#ifdef FEATURE_WLAN_TDLS
6751 /* The open adapter for the p2p shall skip initializations in
6752 * tdls_init if the device mode is WLAN_HDD_P2P_DEVICE, for
6753 * TDLS is supported only on WLAN_HDD_P2P_CLIENT. Hence invoke
6754 * tdls_init when the change_iface sets the device mode to
6755 * WLAN_HDD_P2P_CLIENT.
6756 */
6757
6758 if ( pAdapter->device_mode == WLAN_HDD_P2P_CLIENT)
6759 {
Agarwal Ashish4b87f922014-06-18 03:03:21 +05306760 if (0 != wlan_hdd_sta_tdls_init (pAdapter))
Madan Mohan Koyyalamudi81746922013-07-17 14:38:51 +05306761 {
c_hpothu6ff1c3c2013-10-01 19:01:57 +05306762 hddLog(VOS_TRACE_LEVEL_ERROR,
6763 "%s: tdls initialization failed", __func__);
Madan Mohan Koyyalamudi81746922013-07-17 14:38:51 +05306764 return -EINVAL;
6765 }
6766 }
6767#endif
6768
Jeff Johnson295189b2012-06-20 16:38:30 -07006769 break;
6770 case NL80211_IFTYPE_ADHOC:
6771 hddLog(VOS_TRACE_LEVEL_INFO,
6772 "%s: setting interface Type to ADHOC", __func__);
6773 pRoamProfile->BSSType = eCSR_BSS_TYPE_START_IBSS;
6774 pRoamProfile->phyMode =
6775 hdd_cfg_xlate_to_csr_phy_mode(pConfig->dot11Mode);
Shailender Karmuchia734f332013-04-19 14:02:48 -07006776 pAdapter->device_mode = WLAN_HDD_IBSS;
Jeff Johnson295189b2012-06-20 16:38:30 -07006777 wdev->iftype = type;
6778 break;
6779
6780 case NL80211_IFTYPE_AP:
Jeff Johnson295189b2012-06-20 16:38:30 -07006781 case NL80211_IFTYPE_P2P_GO:
Jeff Johnson295189b2012-06-20 16:38:30 -07006782 {
6783 hddLog(VOS_TRACE_LEVEL_INFO_HIGH,
6784 "%s: setting interface Type to %s", __func__,
6785 (type == NL80211_IFTYPE_AP) ? "SoftAP" : "P2pGo");
6786
Gopichand Nakkalaf527dc62012-12-31 16:35:10 -08006787 //Cancel any remain on channel for GO mode
6788 if (NL80211_IFTYPE_P2P_GO == type)
6789 {
6790 wlan_hdd_cancel_existing_remain_on_channel(pAdapter);
6791 }
Mohit Khanna0f232092012-09-11 14:46:08 -07006792 if (NL80211_IFTYPE_AP == type)
6793 {
6794 /* As Loading WLAN Driver one interface being created for p2p device
6795 * address. This will take one HW STA and the max number of clients
6796 * that can connect to softAP will be reduced by one. so while changing
6797 * the interface type to NL80211_IFTYPE_AP (SoftAP) remove p2p0
6798 * interface as it is not required in SoftAP mode.
6799 */
6800
6801 // Get P2P Adapter
6802 pP2pAdapter = hdd_get_adapter(pHddCtx, WLAN_HDD_P2P_DEVICE);
6803
6804 if (pP2pAdapter)
6805 {
Agarwal Ashish3a38bd12014-06-12 15:16:52 +05306806 hdd_stop_adapter(pHddCtx, pP2pAdapter, VOS_TRUE);
Mohit Khanna0f232092012-09-11 14:46:08 -07006807 hdd_deinit_adapter(pHddCtx, pP2pAdapter);
6808 hdd_close_adapter(pHddCtx, pP2pAdapter, VOS_TRUE);
6809 }
6810 }
Swaroop Goltia2e32212014-04-09 23:37:33 +05306811 //Disable IMPS & BMPS for SAP/GO
6812 if(VOS_STATUS_E_FAILURE ==
6813 hdd_disable_bmps_imps(pHddCtx, WLAN_HDD_P2P_GO))
6814 {
6815 //Fail to Exit BMPS
6816 VOS_ASSERT(0);
6817 }
Madan Mohan Koyyalamudi96797442013-10-08 16:04:42 +05306818#ifdef FEATURE_WLAN_TDLS
Mohit Khanna0f232092012-09-11 14:46:08 -07006819
Madan Mohan Koyyalamudi96797442013-10-08 16:04:42 +05306820 /* A Mutex Lock is introduced while changing the mode to
6821 * protect the concurrent access for the Adapters by TDLS
6822 * module.
6823 */
Rajesh Chauhana34c6e62014-03-25 16:37:58 +05306824 mutex_lock(&pHddCtx->tdls_lock);
Madan Mohan Koyyalamudi96797442013-10-08 16:04:42 +05306825#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07006826 //De-init the adapter.
Agarwal Ashish3a38bd12014-06-12 15:16:52 +05306827 hdd_stop_adapter( pHddCtx, pAdapter, VOS_TRUE );
Jeff Johnson295189b2012-06-20 16:38:30 -07006828 hdd_deinit_adapter( pHddCtx, pAdapter );
6829 memset(&pAdapter->sessionCtx, 0, sizeof(pAdapter->sessionCtx));
Jeff Johnson295189b2012-06-20 16:38:30 -07006830 pAdapter->device_mode = (type == NL80211_IFTYPE_AP) ?
6831 WLAN_HDD_SOFTAP : WLAN_HDD_P2P_GO;
Madan Mohan Koyyalamudi96797442013-10-08 16:04:42 +05306832#ifdef FEATURE_WLAN_TDLS
6833 mutex_unlock(&pHddCtx->tdls_lock);
6834#endif
Madan Mohan Koyyalamudi3ff2a0b2012-10-15 14:33:46 -07006835 if ((WLAN_HDD_SOFTAP == pAdapter->device_mode) &&
6836 (pConfig->apRandomBssidEnabled))
6837 {
6838 /* To meet Android requirements create a randomized
6839 MAC address of the form 02:1A:11:Fx:xx:xx */
6840 get_random_bytes(&ndev->dev_addr[3], 3);
6841 ndev->dev_addr[0] = 0x02;
6842 ndev->dev_addr[1] = 0x1A;
6843 ndev->dev_addr[2] = 0x11;
6844 ndev->dev_addr[3] |= 0xF0;
6845 memcpy(pAdapter->macAddressCurrent.bytes, ndev->dev_addr,
6846 VOS_MAC_ADDR_SIZE);
Arif Hussain24bafea2013-11-15 15:10:03 -08006847 pr_info("wlan: Generated HotSpot BSSID " MAC_ADDRESS_STR"\n",
6848 MAC_ADDR_ARRAY(ndev->dev_addr));
Madan Mohan Koyyalamudi3ff2a0b2012-10-15 14:33:46 -07006849 }
6850
Jeff Johnson295189b2012-06-20 16:38:30 -07006851 hdd_set_ap_ops( pAdapter->dev );
6852
Kiet Lam10841362013-11-01 11:36:50 +05306853 /* This is for only SAP mode where users can
6854 * control country through ini.
6855 * P2P GO follows station country code
6856 * acquired during the STA scanning. */
6857 if((NL80211_IFTYPE_AP == type) &&
6858 (memcmp(pConfig->apCntryCode, CFG_AP_COUNTRY_CODE_DEFAULT, 3) != 0))
6859 {
6860 int status = 0;
6861 VOS_TRACE(VOS_MODULE_ID_HDD,VOS_TRACE_LEVEL_INFO,
6862 "%s: setting country code from INI ", __func__);
6863 init_completion(&pAdapter->change_country_code);
6864 status = (int)sme_ChangeCountryCode(pHddCtx->hHal,
6865 (void *)(tSmeChangeCountryCallback)
6866 wlan_hdd_change_country_code_cb,
6867 pConfig->apCntryCode, pAdapter,
6868 pHddCtx->pvosContext,
Abhishek Singha306a442013-11-07 18:39:01 +05306869 eSIR_FALSE,
6870 eSIR_TRUE);
Kiet Lam10841362013-11-01 11:36:50 +05306871 if (eHAL_STATUS_SUCCESS == status)
6872 {
6873 /* Wait for completion */
c_hpothu6ff1c3c2013-10-01 19:01:57 +05306874 ret = wait_for_completion_interruptible_timeout(
Kiet Lam10841362013-11-01 11:36:50 +05306875 &pAdapter->change_country_code,
6876 msecs_to_jiffies(WLAN_WAIT_TIME_COUNTRY));
c_hpothu6ff1c3c2013-10-01 19:01:57 +05306877 if (ret <= 0)
Kiet Lam10841362013-11-01 11:36:50 +05306878 {
6879 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
c_hpothu6ff1c3c2013-10-01 19:01:57 +05306880 FL("SME Timed out while setting country code %ld"),
6881 ret);
Yue Ma4f55ef32014-01-23 16:45:33 -08006882
6883 if (pHddCtx->isLogpInProgress)
6884 {
6885 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
6886 "%s: LOGP in Progress. Ignore!!!", __func__);
6887 return -EAGAIN;
6888 }
Kiet Lam10841362013-11-01 11:36:50 +05306889 }
6890 }
6891 else
6892 {
6893 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Arif Hussain6d2a3322013-11-17 19:50:10 -08006894 "%s: SME Change Country code failed",__func__);
Kiet Lam10841362013-11-01 11:36:50 +05306895 return -EINVAL;
6896 }
6897 }
Jeff Johnson295189b2012-06-20 16:38:30 -07006898 status = hdd_init_ap_mode(pAdapter);
6899 if(status != VOS_STATUS_SUCCESS)
6900 {
6901 hddLog(VOS_TRACE_LEVEL_FATAL,
6902 "%s: Error initializing the ap mode", __func__);
6903 return -EINVAL;
6904 }
6905 hdd_set_conparam(1);
6906
Jeff Johnson295189b2012-06-20 16:38:30 -07006907 /*interface type changed update in wiphy structure*/
6908 if(wdev)
6909 {
6910 wdev->iftype = type;
6911 pHddCtx->change_iface = type;
6912 }
6913 else
6914 {
6915 hddLog(VOS_TRACE_LEVEL_ERROR,
6916 "%s: ERROR !!!! Wireless dev is NULL", __func__);
6917 return -EINVAL;
6918 }
6919 goto done;
6920 }
6921
6922 default:
6923 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Unsupported interface Type",
6924 __func__);
6925 return -EOPNOTSUPP;
6926 }
6927 }
6928 else if ( (pAdapter->device_mode == WLAN_HDD_SOFTAP)
Jeff Johnson295189b2012-06-20 16:38:30 -07006929 || (pAdapter->device_mode == WLAN_HDD_P2P_GO)
Jeff Johnson295189b2012-06-20 16:38:30 -07006930 )
6931 {
6932 switch(type)
6933 {
6934 case NL80211_IFTYPE_STATION:
Jeff Johnson295189b2012-06-20 16:38:30 -07006935 case NL80211_IFTYPE_P2P_CLIENT:
Jeff Johnson295189b2012-06-20 16:38:30 -07006936 case NL80211_IFTYPE_ADHOC:
Madan Mohan Koyyalamudi96797442013-10-08 16:04:42 +05306937#ifdef FEATURE_WLAN_TDLS
6938
6939 /* A Mutex Lock is introduced while changing the mode to
6940 * protect the concurrent access for the Adapters by TDLS
6941 * module.
6942 */
Rajesh Chauhana34c6e62014-03-25 16:37:58 +05306943 mutex_lock(&pHddCtx->tdls_lock);
Madan Mohan Koyyalamudi96797442013-10-08 16:04:42 +05306944#endif
Agarwal Ashish3a38bd12014-06-12 15:16:52 +05306945 hdd_stop_adapter( pHddCtx, pAdapter, VOS_TRUE );
Jeff Johnson32d95a32012-09-10 13:15:23 -07006946 hdd_deinit_adapter( pHddCtx, pAdapter );
Jeff Johnson295189b2012-06-20 16:38:30 -07006947 wdev->iftype = type;
Gopichand Nakkalaf527dc62012-12-31 16:35:10 -08006948 //Check for sub-string p2p to confirm its a p2p interface
6949 if (NULL != strstr(ndev->name,"p2p"))
Gopichand Nakkala864d3552012-12-31 16:08:51 -08006950 {
6951 pAdapter->device_mode = (type == NL80211_IFTYPE_STATION) ?
6952 WLAN_HDD_P2P_DEVICE : WLAN_HDD_P2P_CLIENT;
6953 }
6954 else
6955 {
6956 pAdapter->device_mode = (type == NL80211_IFTYPE_STATION) ?
Jeff Johnson295189b2012-06-20 16:38:30 -07006957 WLAN_HDD_INFRA_STATION: WLAN_HDD_P2P_CLIENT;
Gopichand Nakkala864d3552012-12-31 16:08:51 -08006958 }
Jeff Johnson295189b2012-06-20 16:38:30 -07006959 hdd_set_conparam(0);
6960 pHddCtx->change_iface = type;
Jeff Johnson295189b2012-06-20 16:38:30 -07006961 memset(&pAdapter->sessionCtx, 0, sizeof(pAdapter->sessionCtx));
6962 hdd_set_station_ops( pAdapter->dev );
Madan Mohan Koyyalamudi96797442013-10-08 16:04:42 +05306963#ifdef FEATURE_WLAN_TDLS
6964 mutex_unlock(&pHddCtx->tdls_lock);
6965#endif
Sunil Dutt66485cb2013-12-19 19:05:03 +05306966 status = hdd_init_station_mode( pAdapter );
Jeff Johnson295189b2012-06-20 16:38:30 -07006967 if( VOS_STATUS_SUCCESS != status )
6968 return -EOPNOTSUPP;
Jeff Johnsone7245742012-09-05 17:12:55 -07006969 /* In case of JB, for P2P-GO, only change interface will be called,
6970 * This is the right place to enable back bmps_imps()
6971 */
Gopichand Nakkalaa2fe5b02013-06-06 16:32:28 +05306972 if (pHddCtx->hdd_wlan_suspended)
6973 {
6974 hdd_set_pwrparams(pHddCtx);
6975 }
Jeff Johnsone7245742012-09-05 17:12:55 -07006976 hdd_enable_bmps_imps(pHddCtx);
Jeff Johnson295189b2012-06-20 16:38:30 -07006977 goto done;
6978 case NL80211_IFTYPE_AP:
Jeff Johnson295189b2012-06-20 16:38:30 -07006979 case NL80211_IFTYPE_P2P_GO:
Jeff Johnson295189b2012-06-20 16:38:30 -07006980 wdev->iftype = type;
Jeff Johnson295189b2012-06-20 16:38:30 -07006981 pAdapter->device_mode = (type == NL80211_IFTYPE_AP) ?
6982 WLAN_HDD_SOFTAP : WLAN_HDD_P2P_GO;
Jeff Johnson295189b2012-06-20 16:38:30 -07006983 goto done;
6984 default:
6985 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Unsupported interface Type",
6986 __func__);
6987 return -EOPNOTSUPP;
6988
6989 }
6990
6991 }
6992 else
6993 {
Sushant Kaushik8bc7df22014-04-09 17:55:29 +05306994 hddLog(VOS_TRACE_LEVEL_ERROR,"%s: unsupported device mode(%s (%d))",
6995 __func__, hdd_device_modetoString(pAdapter->device_mode),
6996 pAdapter->device_mode);
Jeff Johnson295189b2012-06-20 16:38:30 -07006997 return -EOPNOTSUPP;
6998 }
6999
7000
7001 if(pRoamProfile)
7002 {
7003 if ( LastBSSType != pRoamProfile->BSSType )
7004 {
7005 /*interface type changed update in wiphy structure*/
7006 wdev->iftype = type;
7007
7008 /*the BSS mode changed, We need to issue disconnect
7009 if connected or in IBSS disconnect state*/
7010 if ( hdd_connGetConnectedBssType(
7011 WLAN_HDD_GET_STATION_CTX_PTR(pAdapter), &connectedBssType ) ||
7012 ( eCSR_BSS_TYPE_START_IBSS == LastBSSType ) )
7013 {
7014 /*need to issue a disconnect to CSR.*/
7015 INIT_COMPLETION(pAdapter->disconnect_comp_var);
7016 if( eHAL_STATUS_SUCCESS ==
7017 sme_RoamDisconnect( WLAN_HDD_GET_HAL_CTX(pAdapter),
7018 pAdapter->sessionId,
7019 eCSR_DISCONNECT_REASON_UNSPECIFIED ) )
7020 {
c_hpothu6ff1c3c2013-10-01 19:01:57 +05307021 ret = wait_for_completion_interruptible_timeout(
7022 &pAdapter->disconnect_comp_var,
7023 msecs_to_jiffies(WLAN_WAIT_TIME_DISCONNECT));
7024 if (ret <= 0)
7025 {
7026 hddLog(VOS_TRACE_LEVEL_ERROR,
7027 FL("wait on disconnect_comp_var failed %ld"), ret);
7028 }
Jeff Johnson295189b2012-06-20 16:38:30 -07007029 }
7030 }
7031 }
7032 }
7033
7034done:
7035 /*set bitmask based on updated value*/
7036 wlan_hdd_set_concurrency_mode(pHddCtx, pAdapter->device_mode);
Leo Chang6fe1f922013-06-07 19:21:24 -07007037
7038 /* Only STA mode support TM now
7039 * all other mode, TM feature should be disabled */
7040 if ( (pHddCtx->cfg_ini->thermalMitigationEnable) &&
7041 (~VOS_STA & pHddCtx->concurrency_mode) )
7042 {
7043 hddDevTmLevelChangedHandler(pHddCtx->parent_dev, 0);
7044 }
7045
Jeff Johnson295189b2012-06-20 16:38:30 -07007046#ifdef WLAN_BTAMP_FEATURE
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307047 if((NL80211_IFTYPE_STATION == type) && (pHddCtx->concurrency_mode <= 1) &&
Agarwal Ashish51325b52014-06-16 16:50:49 +05307048 (pHddCtx->no_of_open_sessions[WLAN_HDD_INFRA_STATION] <=1))
Jeff Johnson295189b2012-06-20 16:38:30 -07007049 {
7050 //we are ok to do AMP
7051 pHddCtx->isAmpAllowed = VOS_TRUE;
7052 }
7053#endif //WLAN_BTAMP_FEATURE
7054 EXIT();
7055 return 0;
7056}
7057
Mahesh A Saptasagar0e59c472014-04-14 19:17:41 +05307058/*
7059 * FUNCTION: wlan_hdd_cfg80211_change_iface
7060 * wrapper function to protect the actual implementation from SSR.
7061 */
7062int wlan_hdd_cfg80211_change_iface( struct wiphy *wiphy,
7063 struct net_device *ndev,
7064 enum nl80211_iftype type,
7065 u32 *flags,
7066 struct vif_params *params
7067 )
7068{
7069 int ret;
7070
7071 vos_ssr_protect(__func__);
7072 ret = __wlan_hdd_cfg80211_change_iface(wiphy, ndev, type, flags, params);
7073 vos_ssr_unprotect(__func__);
7074
7075 return ret;
7076}
7077
Gopichand Nakkala681989c2013-03-06 22:27:48 -08007078#ifdef FEATURE_WLAN_TDLS
7079static int wlan_hdd_tdls_add_station(struct wiphy *wiphy,
7080 struct net_device *dev, u8 *mac, bool update, tCsrStaParams *StaParams)
7081{
7082 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
7083 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
7084 VOS_STATUS status;
Hoonki Lee5305c3a2013-04-29 23:28:59 -07007085 hddTdlsPeer_t *pTdlsPeer;
c_hpothu6ff1c3c2013-10-01 19:01:57 +05307086 long ret;
Rajesh Chauhana34c6e62014-03-25 16:37:58 +05307087 tANI_U16 numCurrTdlsPeers;
Gopichand Nakkala681989c2013-03-06 22:27:48 -08007088
7089 ENTER();
7090
Gopichand Nakkala838be5d2013-04-10 22:41:51 +05307091 if (NULL == pHddCtx || NULL == pHddCtx->cfg_ini)
Gopichand Nakkala681989c2013-03-06 22:27:48 -08007092 {
7093 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
7094 "Invalid arguments");
7095 return -EINVAL;
7096 }
Hoonki Lee27511902013-03-14 18:19:06 -07007097
7098 if ((eTDLS_SUPPORT_NOT_ENABLED == pHddCtx->tdls_mode) ||
7099 (eTDLS_SUPPORT_DISABLED == pHddCtx->tdls_mode))
7100 {
7101 VOS_TRACE( VOS_MODULE_ID_HDD, TDLS_LOG_LEVEL,
7102 "%s: TDLS mode is disabled OR not enabled in FW."
7103 MAC_ADDRESS_STR " Request declined.",
7104 __func__, MAC_ADDR_ARRAY(mac));
7105 return -ENOTSUPP;
7106 }
7107
Gopichand Nakkala681989c2013-03-06 22:27:48 -08007108 if (pHddCtx->isLogpInProgress)
7109 {
7110 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
7111 "%s:LOGP in Progress. Ignore!!!", __func__);
Atul Mittal115287b2014-07-08 13:26:33 +05307112 wlan_hdd_tdls_set_link_status(pAdapter,
7113 mac,
7114 eTDLS_LINK_IDLE,
7115 eTDLS_LINK_UNSPECIFIED);
Gopichand Nakkala681989c2013-03-06 22:27:48 -08007116 return -EBUSY;
7117 }
7118
Naresh Jayaram9c6f4462014-02-13 12:20:31 +05307119 pTdlsPeer = wlan_hdd_tdls_get_peer(pAdapter, mac);
Hoonki Lee5305c3a2013-04-29 23:28:59 -07007120
7121 if ( NULL == pTdlsPeer ) {
7122 VOS_TRACE( VOS_MODULE_ID_HDD, TDLS_LOG_LEVEL,
7123 "%s: " MAC_ADDRESS_STR " (update %d) not exist. return invalid",
7124 __func__, MAC_ADDR_ARRAY(mac), update);
7125 return -EINVAL;
Gopichand Nakkala34d1b062013-03-19 15:28:33 -07007126 }
Hoonki Lee5305c3a2013-04-29 23:28:59 -07007127
7128 /* in add station, we accept existing valid staId if there is */
7129 if ((0 == update) &&
7130 ((pTdlsPeer->link_status >= eTDLS_LINK_CONNECTING) ||
7131 (TDLS_STA_INDEX_VALID(pTdlsPeer->staId))))
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -07007132 {
Hoonki Lee5305c3a2013-04-29 23:28:59 -07007133 VOS_TRACE( VOS_MODULE_ID_HDD, TDLS_LOG_LEVEL,
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -07007134 "%s: " MAC_ADDRESS_STR
Hoonki Lee5305c3a2013-04-29 23:28:59 -07007135 " link_status %d. staId %d. add station ignored.",
7136 __func__, MAC_ADDR_ARRAY(mac), pTdlsPeer->link_status, pTdlsPeer->staId);
7137 return 0;
7138 }
7139 /* in change station, we accept only when staId is valid */
7140 if ((1 == update) &&
7141 ((pTdlsPeer->link_status > eTDLS_LINK_CONNECTING) ||
7142 (!TDLS_STA_INDEX_VALID(pTdlsPeer->staId))))
7143 {
7144 VOS_TRACE( VOS_MODULE_ID_HDD, TDLS_LOG_LEVEL,
7145 "%s: " MAC_ADDRESS_STR
7146 " link status %d. staId %d. change station %s.",
7147 __func__, MAC_ADDR_ARRAY(mac), pTdlsPeer->link_status, pTdlsPeer->staId,
7148 (TDLS_STA_INDEX_VALID(pTdlsPeer->staId)) ? "ignored" : "declined");
7149 return (TDLS_STA_INDEX_VALID(pTdlsPeer->staId)) ? 0 : -EPERM;
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -07007150 }
Gopichand Nakkala34d1b062013-03-19 15:28:33 -07007151
7152 /* when others are on-going, we want to change link_status to idle */
Madan Mohan Koyyalamudi96797442013-10-08 16:04:42 +05307153 if (NULL != wlan_hdd_tdls_is_progress(pHddCtx, mac, TRUE))
Gopichand Nakkala681989c2013-03-06 22:27:48 -08007154 {
Gopichand Nakkalac87400e2013-03-13 18:51:00 -07007155 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
7156 "%s: " MAC_ADDRESS_STR
7157 " TDLS setup is ongoing. Request declined.",
7158 __func__, MAC_ADDR_ARRAY(mac));
Gopichand Nakkala05922802013-03-14 12:23:19 -07007159 goto error;
Gopichand Nakkala681989c2013-03-06 22:27:48 -08007160 }
7161
7162 /* first to check if we reached to maximum supported TDLS peer.
7163 TODO: for now, return -EPERM looks working fine,
7164 but need to check if any other errno fit into this category.*/
Rajesh Chauhana34c6e62014-03-25 16:37:58 +05307165 numCurrTdlsPeers = wlan_hdd_tdlsConnectedPeers(pAdapter);
7166 if (HDD_MAX_NUM_TDLS_STA <= numCurrTdlsPeers)
Gopichand Nakkala681989c2013-03-06 22:27:48 -08007167 {
Gopichand Nakkalac87400e2013-03-13 18:51:00 -07007168 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
7169 "%s: " MAC_ADDRESS_STR
Rajesh Chauhana34c6e62014-03-25 16:37:58 +05307170 " TDLS Max peer already connected. Request declined."
7171 " Num of peers (%d), Max allowed (%d).",
7172 __func__, MAC_ADDR_ARRAY(mac), numCurrTdlsPeers,
7173 HDD_MAX_NUM_TDLS_STA);
Gopichand Nakkala05922802013-03-14 12:23:19 -07007174 goto error;
Gopichand Nakkala681989c2013-03-06 22:27:48 -08007175 }
7176 else
7177 {
7178 hddTdlsPeer_t *pTdlsPeer;
Madan Mohan Koyyalamudi96797442013-10-08 16:04:42 +05307179 pTdlsPeer = wlan_hdd_tdls_find_peer(pAdapter, mac, TRUE);
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -07007180 if (pTdlsPeer && TDLS_IS_CONNECTED(pTdlsPeer))
Gopichand Nakkala681989c2013-03-06 22:27:48 -08007181 {
Gopichand Nakkalac87400e2013-03-13 18:51:00 -07007182 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
7183 "%s: " MAC_ADDRESS_STR " already connected. Request declined.",
7184 __func__, MAC_ADDR_ARRAY(mac));
Gopichand Nakkala681989c2013-03-06 22:27:48 -08007185 return -EPERM;
7186 }
7187 }
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -07007188 if (0 == update)
Atul Mittal115287b2014-07-08 13:26:33 +05307189 wlan_hdd_tdls_set_link_status(pAdapter,
7190 mac,
7191 eTDLS_LINK_CONNECTING,
7192 eTDLS_LINK_SUCCESS);
Gopichand Nakkala681989c2013-03-06 22:27:48 -08007193
Jeff Johnsond75fe012013-04-06 10:53:06 -07007194 /* debug code */
Gopichand Nakkala838be5d2013-04-10 22:41:51 +05307195 if (NULL != StaParams)
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -07007196 {
7197 VOS_TRACE(VOS_MODULE_ID_HDD, TDLS_LOG_LEVEL,
7198 "%s: TDLS Peer Parameters.", __func__);
Hoonki Lee66b75f32013-04-16 18:30:07 -07007199 if(StaParams->htcap_present)
7200 {
7201 VOS_TRACE(VOS_MODULE_ID_HDD, TDLS_LOG_LEVEL,
7202 "ht_capa->cap_info: %0x", StaParams->HTCap.capInfo);
7203 VOS_TRACE(VOS_MODULE_ID_HDD, TDLS_LOG_LEVEL,
7204 "ht_capa->extended_capabilities: %0x",
7205 StaParams->HTCap.extendedHtCapInfo);
7206 }
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -07007207 VOS_TRACE(VOS_MODULE_ID_HDD, TDLS_LOG_LEVEL,
7208 "params->capability: %0x",StaParams->capability);
7209 VOS_TRACE(VOS_MODULE_ID_HDD, TDLS_LOG_LEVEL,
Jeff Johnson0299d0a2013-10-30 12:37:43 -07007210 "params->ext_capab_len: %0x",StaParams->extn_capability[0]);
Hoonki Lee66b75f32013-04-16 18:30:07 -07007211 if(StaParams->vhtcap_present)
7212 {
7213 VOS_TRACE(VOS_MODULE_ID_HDD, TDLS_LOG_LEVEL,
7214 "rxMcsMap %x rxHighest %x txMcsMap %x txHighest %x",
7215 StaParams->VHTCap.suppMcs.rxMcsMap, StaParams->VHTCap.suppMcs.rxHighest,
7216 StaParams->VHTCap.suppMcs.txMcsMap, StaParams->VHTCap.suppMcs.txHighest);
7217 }
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -07007218 {
7219 int i = 0;
Hoonki Lee5305c3a2013-04-29 23:28:59 -07007220 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO, "Supported rates:");
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -07007221 for (i = 0; i < sizeof(StaParams->supported_rates); i++)
7222 VOS_TRACE(VOS_MODULE_ID_HDD, TDLS_LOG_LEVEL,
7223 "[%d]: %x ", i, StaParams->supported_rates[i]);
7224 }
Jeff Johnsond75fe012013-04-06 10:53:06 -07007225 } /* end debug code */
Gopichand Nakkala838be5d2013-04-10 22:41:51 +05307226 else if ((1 == update) && (NULL == StaParams))
7227 {
7228 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
7229 "%s : update is true, but staParams is NULL. Error!", __func__);
7230 return -EPERM;
7231 }
Gopichand Nakkala681989c2013-03-06 22:27:48 -08007232
7233 INIT_COMPLETION(pAdapter->tdls_add_station_comp);
7234
7235 if (!update)
7236 {
7237 status = sme_AddTdlsPeerSta(WLAN_HDD_GET_HAL_CTX(pAdapter),
7238 pAdapter->sessionId, mac);
7239 }
7240 else
7241 {
7242 status = sme_ChangeTdlsPeerSta(WLAN_HDD_GET_HAL_CTX(pAdapter),
7243 pAdapter->sessionId, mac, StaParams);
7244 }
7245
c_hpothu6ff1c3c2013-10-01 19:01:57 +05307246 ret = wait_for_completion_interruptible_timeout(&pAdapter->tdls_add_station_comp,
Gopichand Nakkala681989c2013-03-06 22:27:48 -08007247 msecs_to_jiffies(WAIT_TIME_TDLS_ADD_STA));
7248
c_hpothu6ff1c3c2013-10-01 19:01:57 +05307249 if (ret <= 0)
Gopichand Nakkala681989c2013-03-06 22:27:48 -08007250 {
Gopichand Nakkalac87400e2013-03-13 18:51:00 -07007251 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
c_hpothu6ff1c3c2013-10-01 19:01:57 +05307252 "%s: timeout waiting for tdls add station indication %ld",
7253 __func__, ret);
Gopichand Nakkala34d1b062013-03-19 15:28:33 -07007254 return -EPERM;
Gopichand Nakkala681989c2013-03-06 22:27:48 -08007255 }
c_hpothu6ff1c3c2013-10-01 19:01:57 +05307256
Gopichand Nakkala681989c2013-03-06 22:27:48 -08007257 if ( eHAL_STATUS_SUCCESS != pAdapter->tdlsAddStaStatus)
7258 {
Gopichand Nakkalac87400e2013-03-13 18:51:00 -07007259 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Gopichand Nakkala681989c2013-03-06 22:27:48 -08007260 "%s: Add Station is unsucessful", __func__);
Gopichand Nakkala34d1b062013-03-19 15:28:33 -07007261 return -EPERM;
Gopichand Nakkala681989c2013-03-06 22:27:48 -08007262 }
7263
7264 return 0;
Gopichand Nakkala05922802013-03-14 12:23:19 -07007265
7266error:
Atul Mittal115287b2014-07-08 13:26:33 +05307267 wlan_hdd_tdls_set_link_status(pAdapter,
7268 mac,
7269 eTDLS_LINK_IDLE,
7270 eTDLS_LINK_UNSPECIFIED);
Gopichand Nakkala05922802013-03-14 12:23:19 -07007271 return -EPERM;
7272
Gopichand Nakkala681989c2013-03-06 22:27:48 -08007273}
7274#endif
7275
Jeff Johnson295189b2012-06-20 16:38:30 -07007276static int wlan_hdd_change_station(struct wiphy *wiphy,
7277 struct net_device *dev,
7278 u8 *mac,
7279 struct station_parameters *params)
7280{
7281 VOS_STATUS status = VOS_STATUS_SUCCESS;
7282 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( dev );
Gopichand Nakkala29149562013-05-10 21:43:41 +05307283 hdd_context_t *pHddCtx;
7284 hdd_station_ctx_t *pHddStaCtx;
Jeff Johnson295189b2012-06-20 16:38:30 -07007285 v_MACADDR_t STAMacAddress;
Gopichand Nakkalab0856222013-03-12 22:39:05 -07007286#ifdef FEATURE_WLAN_TDLS
Gopichand Nakkala681989c2013-03-06 22:27:48 -08007287 tCsrStaParams StaParams = {0};
Gopichand Nakkala681989c2013-03-06 22:27:48 -08007288 tANI_U8 isBufSta = 0;
Naresh Jayaram3180aa42014-02-12 21:47:26 +05307289 tANI_U8 isOffChannelSupported = 0;
Gopichand Nakkalab0856222013-03-12 22:39:05 -07007290#endif
Jeff Johnsone7245742012-09-05 17:12:55 -07007291 ENTER();
7292
Gopichand Nakkala29149562013-05-10 21:43:41 +05307293 if ((NULL == pAdapter))
7294 {
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +05307295 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
Gopichand Nakkala29149562013-05-10 21:43:41 +05307296 "invalid adapter ");
7297 return -EINVAL;
7298 }
7299
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05307300 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
7301 TRACE_CODE_HDD_CHANGE_STATION,
7302 pAdapter->sessionId, params->listen_interval));
Gopichand Nakkala29149562013-05-10 21:43:41 +05307303 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
7304 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
7305
7306 if ((NULL == pHddCtx) || (NULL == pHddStaCtx))
7307 {
7308 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
7309 "invalid HDD state or HDD station context");
7310 return -EINVAL;
7311 }
7312
7313 if (pHddCtx->isLogpInProgress)
Jeff Johnson04dd8a82012-06-29 20:41:40 -07007314 {
7315 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
7316 "%s:LOGP in Progress. Ignore!!!", __func__);
7317 return -EAGAIN;
7318 }
7319
Jeff Johnson295189b2012-06-20 16:38:30 -07007320 vos_mem_copy(STAMacAddress.bytes, mac, sizeof(v_MACADDR_t));
7321
Gopichand Nakkala681989c2013-03-06 22:27:48 -08007322 if ((pAdapter->device_mode == WLAN_HDD_SOFTAP)
7323 || (pAdapter->device_mode == WLAN_HDD_P2P_GO))
Jeff Johnson295189b2012-06-20 16:38:30 -07007324 {
Gopichand Nakkala681989c2013-03-06 22:27:48 -08007325 if (params->sta_flags_set & BIT(NL80211_STA_FLAG_AUTHORIZED))
Jeff Johnson295189b2012-06-20 16:38:30 -07007326 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307327 status = hdd_softap_change_STA_state( pAdapter, &STAMacAddress,
Jeff Johnson295189b2012-06-20 16:38:30 -07007328 WLANTL_STA_AUTHENTICATED);
7329
Gopichand Nakkala29149562013-05-10 21:43:41 +05307330 if (status != VOS_STATUS_SUCCESS)
7331 {
7332 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
7333 "%s: Not able to change TL state to AUTHENTICATED", __func__);
7334 return -EINVAL;
7335 }
Jeff Johnson295189b2012-06-20 16:38:30 -07007336 }
7337 }
Hoonki Leea6d49be2013-04-05 09:43:25 -07007338 else if ((pAdapter->device_mode == WLAN_HDD_INFRA_STATION)
7339 || (pAdapter->device_mode == WLAN_HDD_P2P_CLIENT)) {
Gopichand Nakkala29149562013-05-10 21:43:41 +05307340#ifdef FEATURE_WLAN_TDLS
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -07007341 if (params->sta_flags_set & BIT(NL80211_STA_FLAG_TDLS_PEER)) {
7342 StaParams.capability = params->capability;
7343 StaParams.uapsd_queues = params->uapsd_queues;
7344 StaParams.max_sp = params->max_sp;
7345
Naresh Jayaram3180aa42014-02-12 21:47:26 +05307346 /* Convert (first channel , number of channels) tuple to
7347 * the total list of channels. This goes with the assumption
7348 * that if the first channel is < 14, then the next channels
7349 * are an incremental of 1 else an incremental of 4 till the number
7350 * of channels.
7351 */
7352 if (0 != params->supported_channels_len) {
7353 int i = 0,j = 0,k = 0, no_of_channels = 0 ;
7354 for ( i = 0 ; i < params->supported_channels_len ; i+=2)
7355 {
7356 int wifi_chan_index;
7357 StaParams.supported_channels[j] = params->supported_channels[i];
7358 wifi_chan_index =
7359 ((StaParams.supported_channels[j] <= HDD_CHANNEL_14 ) ? 1 : 4 );
7360 no_of_channels = params->supported_channels[i+1];
7361 for(k=1; k <= no_of_channels; k++)
7362 {
7363 StaParams.supported_channels[j+1] =
7364 StaParams.supported_channels[j] + wifi_chan_index;
7365 j+=1;
7366 }
7367 }
7368 StaParams.supported_channels_len = j;
7369 }
7370 vos_mem_copy(StaParams.supported_oper_classes,
7371 params->supported_oper_classes,
7372 params->supported_oper_classes_len);
7373 StaParams.supported_oper_classes_len =
7374 params->supported_oper_classes_len;
7375
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -07007376 if (0 != params->ext_capab_len)
7377 vos_mem_copy(StaParams.extn_capability, params->ext_capab,
7378 sizeof(StaParams.extn_capability));
7379
7380 if (NULL != params->ht_capa)
Hoonki Lee66b75f32013-04-16 18:30:07 -07007381 {
7382 StaParams.htcap_present = 1;
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -07007383 vos_mem_copy(&StaParams.HTCap, params->ht_capa, sizeof(tSirHTCap));
Hoonki Lee66b75f32013-04-16 18:30:07 -07007384 }
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -07007385
7386 StaParams.supported_rates_len = params->supported_rates_len;
7387
7388 /* Note : The Maximum sizeof supported_rates sent by the Supplicant is 32.
7389 * The supported_rates array , for all the structures propogating till Add Sta
7390 * to the firmware has to be modified , if the supplicant (ieee80211) is
7391 * modified to send more rates.
7392 */
7393
7394 /* To avoid Data Currption , set to max length to SIR_MAC_MAX_SUPP_RATES
7395 */
7396 if (StaParams.supported_rates_len > SIR_MAC_MAX_SUPP_RATES)
7397 StaParams.supported_rates_len = SIR_MAC_MAX_SUPP_RATES;
7398
7399 if (0 != StaParams.supported_rates_len) {
7400 int i = 0;
7401 vos_mem_copy(StaParams.supported_rates, params->supported_rates,
7402 StaParams.supported_rates_len);
Hoonki Lee5305c3a2013-04-29 23:28:59 -07007403 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -07007404 "Supported Rates with Length %d", StaParams.supported_rates_len);
7405 for (i=0; i < StaParams.supported_rates_len; i++)
Hoonki Lee5305c3a2013-04-29 23:28:59 -07007406 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -07007407 "[%d]: %0x", i, StaParams.supported_rates[i]);
7408 }
7409
7410 if (NULL != params->vht_capa)
Hoonki Lee66b75f32013-04-16 18:30:07 -07007411 {
7412 StaParams.vhtcap_present = 1;
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -07007413 vos_mem_copy(&StaParams.VHTCap, params->vht_capa, sizeof(tSirVHTCap));
Hoonki Lee66b75f32013-04-16 18:30:07 -07007414 }
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -07007415
Gopichand Nakkala681989c2013-03-06 22:27:48 -08007416 if (0 != params->ext_capab_len ) {
7417 /*Define A Macro : TODO Sunil*/
7418 if ((1<<4) & StaParams.extn_capability[3]) {
7419 isBufSta = 1;
7420 }
Naresh Jayaram3180aa42014-02-12 21:47:26 +05307421 /* TDLS Channel Switching Support */
7422 if ((1<<6) & StaParams.extn_capability[3]) {
7423 isOffChannelSupported = 1;
7424 }
Gopichand Nakkala681989c2013-03-06 22:27:48 -08007425 }
Naresh Jayaram3180aa42014-02-12 21:47:26 +05307426 status = wlan_hdd_tdls_set_peer_caps( pAdapter, mac,
7427 &StaParams, isBufSta,
7428 isOffChannelSupported);
7429
Gopichand Nakkala79ff85d2013-05-27 17:05:29 +05307430 if (VOS_STATUS_SUCCESS != status) {
7431 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
7432 "%s: wlan_hdd_tdls_set_peer_caps failed!", __func__);
7433 return -EINVAL;
7434 }
Gopichand Nakkala681989c2013-03-06 22:27:48 -08007435 status = wlan_hdd_tdls_add_station(wiphy, dev, mac, 1, &StaParams);
7436
7437 if (VOS_STATUS_SUCCESS != status) {
7438 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
7439 "%s: sme_ChangeTdlsPeerSta failed!", __func__);
7440 return -EINVAL;
7441 }
7442 }
Gopichand Nakkalab0856222013-03-12 22:39:05 -07007443#endif
Gopichand Nakkala6239acd2013-06-14 14:48:00 +05307444 }
Jeff Johnsone7245742012-09-05 17:12:55 -07007445 EXIT();
Jeff Johnson295189b2012-06-20 16:38:30 -07007446 return status;
7447}
7448
7449/*
Mahesh A Saptasagar1a51bc02014-06-02 18:28:08 +05307450 * FUNCTION: __wlan_hdd_cfg80211_add_key
Jeff Johnson295189b2012-06-20 16:38:30 -07007451 * This function is used to initialize the key information
7452 */
7453#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
Mahesh A Saptasagar1a51bc02014-06-02 18:28:08 +05307454static int __wlan_hdd_cfg80211_add_key( struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -07007455 struct net_device *ndev,
7456 u8 key_index, bool pairwise,
7457 const u8 *mac_addr,
7458 struct key_params *params
7459 )
7460#else
Mahesh A Saptasagar1a51bc02014-06-02 18:28:08 +05307461static int __wlan_hdd_cfg80211_add_key( struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -07007462 struct net_device *ndev,
7463 u8 key_index, const u8 *mac_addr,
7464 struct key_params *params
7465 )
7466#endif
7467{
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -07007468 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( ndev );
Jeff Johnson295189b2012-06-20 16:38:30 -07007469 tCsrRoamSetKey setKey;
7470 u8 groupmacaddr[WNI_CFG_BSSID_LEN] = {0xFF,0xFF,0xFF,0xFF,0xFF,0xFF};
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05307471 int status;
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -07007472 v_U32_t roamId= 0xFF;
7473 v_CONTEXT_t pVosContext = (WLAN_HDD_GET_CTX(pAdapter))->pvosContext;
Jeff Johnson295189b2012-06-20 16:38:30 -07007474 hdd_hostapd_state_t *pHostapdState;
7475 VOS_STATUS vos_status;
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -07007476 eHalStatus halStatus;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05307477 hdd_context_t *pHddCtx;
Jeff Johnson295189b2012-06-20 16:38:30 -07007478
7479 ENTER();
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +05307480
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05307481 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
7482 TRACE_CODE_HDD_CFG80211_ADD_KEY,
7483 pAdapter->sessionId, params->key_len));
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05307484 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
7485 status = wlan_hdd_validate_context(pHddCtx);
7486
7487 if (0 != status)
Jeff Johnson04dd8a82012-06-29 20:41:40 -07007488 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05307489 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
7490 "%s: HDD context is not valid", __func__);
7491 return status;
Jeff Johnson04dd8a82012-06-29 20:41:40 -07007492 }
7493
Sushant Kaushik8bc7df22014-04-09 17:55:29 +05307494 hddLog(VOS_TRACE_LEVEL_INFO, "%s: device_mode = %s (%d)",
7495 __func__, hdd_device_modetoString(pAdapter->device_mode),
7496 pAdapter->device_mode);
Jeff Johnson295189b2012-06-20 16:38:30 -07007497
7498 if (CSR_MAX_NUM_KEY <= key_index)
7499 {
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -07007500 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Invalid key index %d", __func__,
Jeff Johnson295189b2012-06-20 16:38:30 -07007501 key_index);
7502
7503 return -EINVAL;
7504 }
7505
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -07007506 if (CSR_MAX_KEY_LEN < params->key_len)
7507 {
7508 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Invalid key length %d", __func__,
7509 params->key_len);
7510
7511 return -EINVAL;
7512 }
7513
7514 hddLog(VOS_TRACE_LEVEL_INFO,
7515 "%s: called with key index = %d & key length %d",
7516 __func__, key_index, params->key_len);
Jeff Johnson295189b2012-06-20 16:38:30 -07007517
7518 /*extract key idx, key len and key*/
7519 vos_mem_zero(&setKey,sizeof(tCsrRoamSetKey));
7520 setKey.keyId = key_index;
7521 setKey.keyLength = params->key_len;
7522 vos_mem_copy(&setKey.Key[0],params->key, params->key_len);
7523
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -07007524 switch (params->cipher)
Jeff Johnson295189b2012-06-20 16:38:30 -07007525 {
7526 case WLAN_CIPHER_SUITE_WEP40:
7527 setKey.encType = eCSR_ENCRYPT_TYPE_WEP40_STATICKEY;
7528 break;
7529
7530 case WLAN_CIPHER_SUITE_WEP104:
7531 setKey.encType = eCSR_ENCRYPT_TYPE_WEP104_STATICKEY;
7532 break;
7533
7534 case WLAN_CIPHER_SUITE_TKIP:
7535 {
7536 u8 *pKey = &setKey.Key[0];
7537 setKey.encType = eCSR_ENCRYPT_TYPE_TKIP;
7538
7539 vos_mem_zero(pKey, CSR_MAX_KEY_LEN);
7540
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -07007541 /*Supplicant sends the 32bytes key in this order
Jeff Johnson295189b2012-06-20 16:38:30 -07007542
7543 |--------------|----------|----------|
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -07007544 | Tk1 |TX-MIC | RX Mic |
Jeff Johnson295189b2012-06-20 16:38:30 -07007545 |--------------|----------|----------|
7546 <---16bytes---><--8bytes--><--8bytes-->
7547
7548 */
7549 /*Sme expects the 32 bytes key to be in the below order
7550
7551 |--------------|----------|----------|
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -07007552 | Tk1 |RX-MIC | TX Mic |
Jeff Johnson295189b2012-06-20 16:38:30 -07007553 |--------------|----------|----------|
7554 <---16bytes---><--8bytes--><--8bytes-->
7555 */
7556 /* Copy the Temporal Key 1 (TK1) */
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -07007557 vos_mem_copy(pKey, params->key, 16);
Jeff Johnson295189b2012-06-20 16:38:30 -07007558
7559 /*Copy the rx mic first*/
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -07007560 vos_mem_copy(&pKey[16], &params->key[24], 8);
Jeff Johnson295189b2012-06-20 16:38:30 -07007561
7562 /*Copy the tx mic */
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -07007563 vos_mem_copy(&pKey[24], &params->key[16], 8);
Jeff Johnson295189b2012-06-20 16:38:30 -07007564
7565
7566 break;
7567 }
7568
7569 case WLAN_CIPHER_SUITE_CCMP:
7570 setKey.encType = eCSR_ENCRYPT_TYPE_AES;
7571 break;
7572
7573#ifdef FEATURE_WLAN_WAPI
7574 case WLAN_CIPHER_SUITE_SMS4:
7575 {
7576 vos_mem_zero(&setKey,sizeof(tCsrRoamSetKey));
7577 wlan_hdd_cfg80211_set_key_wapi(pAdapter, key_index, mac_addr,
7578 params->key, params->key_len);
7579 return 0;
7580 }
7581#endif
Chet Lanctot186b5732013-03-18 10:26:30 -07007582
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08007583#ifdef FEATURE_WLAN_ESE
Jeff Johnson295189b2012-06-20 16:38:30 -07007584 case WLAN_CIPHER_SUITE_KRK:
7585 setKey.encType = eCSR_ENCRYPT_TYPE_KRK;
7586 break;
7587#endif
Chet Lanctot186b5732013-03-18 10:26:30 -07007588
7589#ifdef WLAN_FEATURE_11W
7590 case WLAN_CIPHER_SUITE_AES_CMAC:
7591 setKey.encType = eCSR_ENCRYPT_TYPE_AES_CMAC;
Chet Lanctot3b5158a2013-03-31 16:45:21 -07007592 break;
Chet Lanctot186b5732013-03-18 10:26:30 -07007593#endif
7594
Jeff Johnson295189b2012-06-20 16:38:30 -07007595 default:
Jeff Johnson0299d0a2013-10-30 12:37:43 -07007596 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: unsupported cipher type %u",
Jeff Johnson295189b2012-06-20 16:38:30 -07007597 __func__, params->cipher);
7598 return -EOPNOTSUPP;
7599 }
7600
7601 hddLog(VOS_TRACE_LEVEL_INFO_MED, "%s: encryption type %d",
7602 __func__, setKey.encType);
7603
Shailender Karmuchi642e9812013-05-30 14:34:49 -07007604 if (
Jeff Johnson295189b2012-06-20 16:38:30 -07007605#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
7606 (!pairwise)
7607#else
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -07007608 (!mac_addr || is_broadcast_ether_addr(mac_addr))
Jeff Johnson295189b2012-06-20 16:38:30 -07007609#endif
Shailender Karmuchi642e9812013-05-30 14:34:49 -07007610 )
7611 {
7612 /* set group key*/
7613 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
7614 "%s- %d: setting Broadcast key",
7615 __func__, __LINE__);
7616 setKey.keyDirection = eSIR_RX_ONLY;
7617 vos_mem_copy(setKey.peerMac,groupmacaddr,WNI_CFG_BSSID_LEN);
7618 }
7619 else
7620 {
7621 /* set pairwise key*/
7622 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
7623 "%s- %d: setting pairwise key",
7624 __func__, __LINE__);
7625 setKey.keyDirection = eSIR_TX_RX;
7626 vos_mem_copy(setKey.peerMac, mac_addr,WNI_CFG_BSSID_LEN);
7627 }
7628 if ((WLAN_HDD_IBSS == pAdapter->device_mode) && !pairwise)
7629 {
7630 setKey.keyDirection = eSIR_TX_RX;
7631 /*Set the group key*/
7632 status = sme_RoamSetKey( WLAN_HDD_GET_HAL_CTX(pAdapter),
7633 pAdapter->sessionId, &setKey, &roamId );
Jeff Johnson295189b2012-06-20 16:38:30 -07007634
Shailender Karmuchi642e9812013-05-30 14:34:49 -07007635 if ( 0 != status )
7636 {
7637 hddLog(VOS_TRACE_LEVEL_ERROR,
7638 "%s: sme_RoamSetKey failed, returned %d", __func__, status);
7639 return -EINVAL;
7640 }
7641 /*Save the keys here and call sme_RoamSetKey for setting
7642 the PTK after peer joins the IBSS network*/
7643 vos_mem_copy(&pAdapter->sessionCtx.station.ibss_enc_key,
7644 &setKey, sizeof(tCsrRoamSetKey));
7645 return status;
7646 }
Gopichand Nakkala29149562013-05-10 21:43:41 +05307647 if ((pAdapter->device_mode == WLAN_HDD_SOFTAP) ||
7648 (pAdapter->device_mode == WLAN_HDD_P2P_GO))
7649 {
Jeff Johnson295189b2012-06-20 16:38:30 -07007650 pHostapdState = WLAN_HDD_GET_HOSTAP_STATE_PTR(pAdapter);
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -07007651 if( pHostapdState->bssState == BSS_START )
7652 {
c_hpothu7c55da62014-01-23 18:34:02 +05307653 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
7654 vos_status = wlan_hdd_check_ula_done(pAdapter);
7655
7656 if ( vos_status != VOS_STATUS_SUCCESS )
7657 {
7658 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
7659 "[%4d] wlan_hdd_check_ula_done returned ERROR status= %d",
7660 __LINE__, vos_status );
7661
7662 pHddStaCtx->roam_info.roamingState = HDD_ROAM_STATE_NONE;
7663
7664 return -EINVAL;
7665 }
7666
Jeff Johnson295189b2012-06-20 16:38:30 -07007667 status = WLANSAP_SetKeySta( pVosContext, &setKey);
7668
7669 if ( status != eHAL_STATUS_SUCCESS )
7670 {
7671 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
7672 "[%4d] WLANSAP_SetKeySta returned ERROR status= %d",
7673 __LINE__, status );
7674 }
7675 }
7676
7677 /* Saving WEP keys */
7678 else if( eCSR_ENCRYPT_TYPE_WEP40_STATICKEY == setKey.encType ||
7679 eCSR_ENCRYPT_TYPE_WEP104_STATICKEY == setKey.encType )
7680 {
7681 //Save the wep key in ap context. Issue setkey after the BSS is started.
7682 hdd_ap_ctx_t *pAPCtx = WLAN_HDD_GET_AP_CTX_PTR(pAdapter);
7683 vos_mem_copy(&pAPCtx->wepKey[key_index], &setKey, sizeof(tCsrRoamSetKey));
7684 }
7685 else
7686 {
7687 //Save the key in ap context. Issue setkey after the BSS is started.
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -07007688 hdd_ap_ctx_t *pAPCtx = WLAN_HDD_GET_AP_CTX_PTR(pAdapter);
Jeff Johnson295189b2012-06-20 16:38:30 -07007689 vos_mem_copy(&pAPCtx->groupKey, &setKey, sizeof(tCsrRoamSetKey));
7690 }
7691 }
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -07007692 else if ( (pAdapter->device_mode == WLAN_HDD_INFRA_STATION) ||
7693 (pAdapter->device_mode == WLAN_HDD_P2P_CLIENT) )
Jeff Johnson295189b2012-06-20 16:38:30 -07007694 {
7695 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
7696 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
7697
Gopichand Nakkala3d295922013-05-07 16:19:14 +05307698#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
7699 if (!pairwise)
7700#else
7701 if (!mac_addr || is_broadcast_ether_addr(mac_addr))
7702#endif
7703 {
7704 /* set group key*/
7705 if (pHddStaCtx->roam_info.deferKeyComplete)
7706 {
7707 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
7708 "%s- %d: Perform Set key Complete",
7709 __func__, __LINE__);
7710 hdd_PerformRoamSetKeyComplete(pAdapter);
7711 }
7712 }
7713
Jeff Johnson295189b2012-06-20 16:38:30 -07007714 pWextState->roamProfile.Keys.KeyLength[key_index] = (u8)params->key_len;
7715
Venkata Prathyusha Kuntupalliee2ce712013-01-17 14:09:24 -08007716 pWextState->roamProfile.Keys.defaultIndex = key_index;
7717
7718
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -07007719 vos_mem_copy(&pWextState->roamProfile.Keys.KeyMaterial[key_index][0],
Jeff Johnson295189b2012-06-20 16:38:30 -07007720 params->key, params->key_len);
7721
Gopichand Nakkala3d295922013-05-07 16:19:14 +05307722
Jeff Johnson295189b2012-06-20 16:38:30 -07007723 pHddStaCtx->roam_info.roamingState = HDD_ROAM_STATE_SETTING_KEY;
7724
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307725 hddLog(VOS_TRACE_LEVEL_INFO_MED,
Jeff Johnson295189b2012-06-20 16:38:30 -07007726 "%s: set key for peerMac %2x:%2x:%2x:%2x:%2x:%2x, direction %d",
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307727 __func__, setKey.peerMac[0], setKey.peerMac[1],
7728 setKey.peerMac[2], setKey.peerMac[3],
7729 setKey.peerMac[4], setKey.peerMac[5],
Jeff Johnson295189b2012-06-20 16:38:30 -07007730 setKey.keyDirection);
7731
7732 vos_status = wlan_hdd_check_ula_done(pAdapter);
7733
7734 if ( vos_status != VOS_STATUS_SUCCESS )
7735 {
7736 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
7737 "[%4d] wlan_hdd_check_ula_done returned ERROR status= %d",
7738 __LINE__, vos_status );
7739
7740 pHddStaCtx->roam_info.roamingState = HDD_ROAM_STATE_NONE;
7741
7742 return -EINVAL;
7743
7744 }
7745
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -07007746#ifdef WLAN_FEATURE_VOWIFI_11R
Gopichand Nakkala3d295922013-05-07 16:19:14 +05307747 /* The supplicant may attempt to set the PTK once pre-authentication
7748 is done. Save the key in the UMAC and include it in the ADD BSS
7749 request */
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -07007750 halStatus = sme_FTUpdateKey( WLAN_HDD_GET_HAL_CTX(pAdapter), &setKey);
Gopichand Nakkala3d295922013-05-07 16:19:14 +05307751 if ( halStatus == eHAL_STATUS_FT_PREAUTH_KEY_SUCCESS )
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -07007752 {
Gopichand Nakkala3d295922013-05-07 16:19:14 +05307753 hddLog(VOS_TRACE_LEVEL_INFO_MED,
7754 "%s: Update PreAuth Key success", __func__);
7755 return 0;
7756 }
7757 else if ( halStatus == eHAL_STATUS_FT_PREAUTH_KEY_FAILED )
7758 {
7759 hddLog(VOS_TRACE_LEVEL_ERROR,
7760 "%s: Update PreAuth Key failed", __func__);
Gopichand Nakkalad7d13652013-02-15 01:48:00 +05307761 return -EINVAL;
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -07007762 }
7763#endif /* WLAN_FEATURE_VOWIFI_11R */
Jeff Johnson295189b2012-06-20 16:38:30 -07007764
7765 /* issue set key request to SME*/
7766 status = sme_RoamSetKey( WLAN_HDD_GET_HAL_CTX(pAdapter),
7767 pAdapter->sessionId, &setKey, &roamId );
7768
7769 if ( 0 != status )
7770 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307771 hddLog(VOS_TRACE_LEVEL_ERROR,
Jeff Johnson295189b2012-06-20 16:38:30 -07007772 "%s: sme_RoamSetKey failed, returned %d", __func__, status);
7773 pHddStaCtx->roam_info.roamingState = HDD_ROAM_STATE_NONE;
7774 return -EINVAL;
7775 }
7776
7777
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307778 /* in case of IBSS as there was no information available about WEP keys during
7779 * IBSS join, group key intialized with NULL key, so re-initialize group key
Jeff Johnson295189b2012-06-20 16:38:30 -07007780 * with correct value*/
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307781 if ( (eCSR_BSS_TYPE_START_IBSS == pWextState->roamProfile.BSSType) &&
7782 !( ( IW_AUTH_KEY_MGMT_802_1X
7783 == (pWextState->authKeyMgmt & IW_AUTH_KEY_MGMT_802_1X))
Jeff Johnson295189b2012-06-20 16:38:30 -07007784 && (eCSR_AUTH_TYPE_OPEN_SYSTEM == pHddStaCtx->conn_info.authType)
7785 )
7786 &&
7787 ( (WLAN_CIPHER_SUITE_WEP40 == params->cipher)
7788 || (WLAN_CIPHER_SUITE_WEP104 == params->cipher)
7789 )
7790 )
7791 {
7792 setKey.keyDirection = eSIR_RX_ONLY;
7793 vos_mem_copy(setKey.peerMac,groupmacaddr,WNI_CFG_BSSID_LEN);
7794
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307795 hddLog(VOS_TRACE_LEVEL_INFO_MED,
Jeff Johnson295189b2012-06-20 16:38:30 -07007796 "%s: set key peerMac %2x:%2x:%2x:%2x:%2x:%2x, direction %d",
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307797 __func__, setKey.peerMac[0], setKey.peerMac[1],
7798 setKey.peerMac[2], setKey.peerMac[3],
7799 setKey.peerMac[4], setKey.peerMac[5],
Jeff Johnson295189b2012-06-20 16:38:30 -07007800 setKey.keyDirection);
7801
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307802 status = sme_RoamSetKey( WLAN_HDD_GET_HAL_CTX(pAdapter),
Jeff Johnson295189b2012-06-20 16:38:30 -07007803 pAdapter->sessionId, &setKey, &roamId );
7804
7805 if ( 0 != status )
7806 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307807 hddLog(VOS_TRACE_LEVEL_ERROR,
7808 "%s: sme_RoamSetKey failed for group key (IBSS), returned %d",
Jeff Johnson295189b2012-06-20 16:38:30 -07007809 __func__, status);
7810 pHddStaCtx->roam_info.roamingState = HDD_ROAM_STATE_NONE;
7811 return -EINVAL;
7812 }
7813 }
7814 }
7815
7816 return 0;
7817}
7818
Mahesh A Saptasagar1a51bc02014-06-02 18:28:08 +05307819#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
7820static int wlan_hdd_cfg80211_add_key( struct wiphy *wiphy,
7821 struct net_device *ndev,
7822 u8 key_index, bool pairwise,
7823 const u8 *mac_addr,
7824 struct key_params *params
7825 )
7826#else
7827static int wlan_hdd_cfg80211_add_key( struct wiphy *wiphy,
7828 struct net_device *ndev,
7829 u8 key_index, const u8 *mac_addr,
7830 struct key_params *params
7831 )
7832#endif
7833{
7834 int ret;
7835 vos_ssr_protect(__func__);
7836#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
7837 ret = __wlan_hdd_cfg80211_add_key(wiphy, ndev, key_index, pairwise,
7838 mac_addr, params);
7839#else
7840 ret = __wlan_hdd_cfg80211_add_key(wiphy, ndev, key_index, mac_addr,
7841 params);
7842#endif
7843 vos_ssr_unprotect(__func__);
7844
7845 return ret;
7846}
7847
Jeff Johnson295189b2012-06-20 16:38:30 -07007848/*
Mahesh A Saptasagar1a51bc02014-06-02 18:28:08 +05307849 * FUNCTION: __wlan_hdd_cfg80211_get_key
Jeff Johnson295189b2012-06-20 16:38:30 -07007850 * This function is used to get the key information
7851 */
7852#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
Mahesh A Saptasagar1a51bc02014-06-02 18:28:08 +05307853static int __wlan_hdd_cfg80211_get_key(
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307854 struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -07007855 struct net_device *ndev,
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307856 u8 key_index, bool pairwise,
Jeff Johnson295189b2012-06-20 16:38:30 -07007857 const u8 *mac_addr, void *cookie,
7858 void (*callback)(void *cookie, struct key_params*)
7859 )
7860#else
Mahesh A Saptasagar1a51bc02014-06-02 18:28:08 +05307861static int __wlan_hdd_cfg80211_get_key(
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307862 struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -07007863 struct net_device *ndev,
7864 u8 key_index, const u8 *mac_addr, void *cookie,
7865 void (*callback)(void *cookie, struct key_params*)
7866 )
7867#endif
7868{
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307869 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( ndev );
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +05307870 hdd_wext_state_t *pWextState= WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
7871 tCsrRoamProfile *pRoamProfile = &(pWextState->roamProfile);
Jeff Johnson295189b2012-06-20 16:38:30 -07007872 struct key_params params;
7873
7874 ENTER();
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307875
Sushant Kaushik8bc7df22014-04-09 17:55:29 +05307876 hddLog(VOS_TRACE_LEVEL_INFO, "%s: device_mode = %s (%d)",
7877 __func__, hdd_device_modetoString(pAdapter->device_mode),
7878 pAdapter->device_mode);
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +05307879
Jeff Johnson295189b2012-06-20 16:38:30 -07007880 memset(&params, 0, sizeof(params));
7881
7882 if (CSR_MAX_NUM_KEY <= key_index)
7883 {
c_hpothu6ff1c3c2013-10-01 19:01:57 +05307884 hddLog(VOS_TRACE_LEVEL_ERROR, FL("invalid key index %d"), key_index);
Jeff Johnson295189b2012-06-20 16:38:30 -07007885 return -EINVAL;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307886 }
Jeff Johnson295189b2012-06-20 16:38:30 -07007887
7888 switch(pRoamProfile->EncryptionType.encryptionType[0])
7889 {
7890 case eCSR_ENCRYPT_TYPE_NONE:
7891 params.cipher = IW_AUTH_CIPHER_NONE;
7892 break;
7893
7894 case eCSR_ENCRYPT_TYPE_WEP40_STATICKEY:
7895 case eCSR_ENCRYPT_TYPE_WEP40:
7896 params.cipher = WLAN_CIPHER_SUITE_WEP40;
7897 break;
7898
7899 case eCSR_ENCRYPT_TYPE_WEP104_STATICKEY:
7900 case eCSR_ENCRYPT_TYPE_WEP104:
7901 params.cipher = WLAN_CIPHER_SUITE_WEP104;
7902 break;
7903
7904 case eCSR_ENCRYPT_TYPE_TKIP:
7905 params.cipher = WLAN_CIPHER_SUITE_TKIP;
7906 break;
7907
7908 case eCSR_ENCRYPT_TYPE_AES:
7909 params.cipher = WLAN_CIPHER_SUITE_AES_CMAC;
7910 break;
7911
7912 default:
7913 params.cipher = IW_AUTH_CIPHER_NONE;
7914 break;
7915 }
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +05307916
c_hpothuaaf19692014-05-17 17:01:48 +05307917 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
7918 TRACE_CODE_HDD_CFG80211_GET_KEY,
7919 pAdapter->sessionId, params.cipher));
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +05307920
Jeff Johnson295189b2012-06-20 16:38:30 -07007921 params.key_len = pRoamProfile->Keys.KeyLength[key_index];
7922 params.seq_len = 0;
7923 params.seq = NULL;
7924 params.key = &pRoamProfile->Keys.KeyMaterial[key_index][0];
7925 callback(cookie, &params);
7926 return 0;
7927}
7928
Mahesh A Saptasagar1a51bc02014-06-02 18:28:08 +05307929#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
7930static int wlan_hdd_cfg80211_get_key(
7931 struct wiphy *wiphy,
7932 struct net_device *ndev,
7933 u8 key_index, bool pairwise,
7934 const u8 *mac_addr, void *cookie,
7935 void (*callback)(void *cookie, struct key_params*)
7936 )
7937#else
7938static int wlan_hdd_cfg80211_get_key(
7939 struct wiphy *wiphy,
7940 struct net_device *ndev,
7941 u8 key_index, const u8 *mac_addr, void *cookie,
7942 void (*callback)(void *cookie, struct key_params*)
7943 )
7944#endif
7945{
7946 int ret;
7947
7948 vos_ssr_protect(__func__);
7949#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
7950 ret = __wlan_hdd_cfg80211_get_key(wiphy, ndev, key_index, pairwise,
7951 mac_addr, cookie, callback);
7952#else
7953 ret = __wlan_hdd_cfg80211_get_key(wiphy, ndev, key_index, mac_addr,
7954 callback);
7955#endif
7956 vos_ssr_unprotect(__func__);
7957
7958 return ret;
7959}
7960
Jeff Johnson295189b2012-06-20 16:38:30 -07007961/*
7962 * FUNCTION: wlan_hdd_cfg80211_del_key
7963 * This function is used to delete the key information
7964 */
7965#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307966static int wlan_hdd_cfg80211_del_key( struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -07007967 struct net_device *ndev,
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307968 u8 key_index,
7969 bool pairwise,
Jeff Johnson295189b2012-06-20 16:38:30 -07007970 const u8 *mac_addr
7971 )
7972#else
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307973static int wlan_hdd_cfg80211_del_key( struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -07007974 struct net_device *ndev,
7975 u8 key_index,
7976 const u8 *mac_addr
7977 )
7978#endif
7979{
7980 int status = 0;
7981
7982 //This code needs to be revisited. There is sme_removeKey API, we should
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307983 //plan to use that. After the change to use correct index in setkey,
Jeff Johnson295189b2012-06-20 16:38:30 -07007984 //it is observed that this is invalidating peer
7985 //key index whenever re-key is done. This is affecting data link.
7986 //It should be ok to ignore del_key.
7987#if 0
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307988 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( ndev );
7989 v_CONTEXT_t pVosContext = (WLAN_HDD_GET_CTX(pAdapter))->pvosContext;
Jeff Johnson295189b2012-06-20 16:38:30 -07007990 u8 groupmacaddr[WNI_CFG_BSSID_LEN] = {0xFF,0xFF,0xFF,0xFF,0xFF,0xFF};
7991 tCsrRoamSetKey setKey;
7992 v_U32_t roamId= 0xFF;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307993
Jeff Johnson295189b2012-06-20 16:38:30 -07007994 ENTER();
7995
7996 hddLog(VOS_TRACE_LEVEL_INFO_HIGH, "%s: device_mode = %d\n",
7997 __func__,pAdapter->device_mode);
7998
7999 if (CSR_MAX_NUM_KEY <= key_index)
8000 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308001 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Invalid key index %d", __func__,
Jeff Johnson295189b2012-06-20 16:38:30 -07008002 key_index);
8003
8004 return -EINVAL;
8005 }
8006
8007 vos_mem_zero(&setKey,sizeof(tCsrRoamSetKey));
8008 setKey.keyId = key_index;
8009
8010 if (mac_addr)
8011 vos_mem_copy(setKey.peerMac, mac_addr,WNI_CFG_BSSID_LEN);
8012 else
8013 vos_mem_copy(setKey.peerMac, groupmacaddr, WNI_CFG_BSSID_LEN);
8014
8015 setKey.encType = eCSR_ENCRYPT_TYPE_NONE;
8016
8017 if ((pAdapter->device_mode == WLAN_HDD_SOFTAP)
Jeff Johnson295189b2012-06-20 16:38:30 -07008018 || (pAdapter->device_mode == WLAN_HDD_P2P_GO)
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308019 )
8020 {
8021
8022 hdd_hostapd_state_t *pHostapdState =
Jeff Johnson295189b2012-06-20 16:38:30 -07008023 WLAN_HDD_GET_HOSTAP_STATE_PTR(pAdapter);
8024 if( pHostapdState->bssState == BSS_START)
8025 {
8026 status = WLANSAP_SetKeySta( pVosContext, &setKey);
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308027
Jeff Johnson295189b2012-06-20 16:38:30 -07008028 if ( status != eHAL_STATUS_SUCCESS )
8029 {
8030 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
8031 "[%4d] WLANSAP_SetKeySta returned ERROR status= %d",
8032 __LINE__, status );
8033 }
8034 }
8035 }
8036 else if ( (pAdapter->device_mode == WLAN_HDD_INFRA_STATION)
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308037 || (pAdapter->device_mode == WLAN_HDD_P2P_CLIENT)
Jeff Johnson295189b2012-06-20 16:38:30 -07008038 )
8039 {
8040 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
8041
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308042 pHddStaCtx->roam_info.roamingState = HDD_ROAM_STATE_SETTING_KEY;
8043
8044 hddLog(VOS_TRACE_LEVEL_INFO_MED,
Jeff Johnson295189b2012-06-20 16:38:30 -07008045 "%s: delete key for peerMac %2x:%2x:%2x:%2x:%2x:%2x",
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308046 __func__, setKey.peerMac[0], setKey.peerMac[1],
8047 setKey.peerMac[2], setKey.peerMac[3],
Jeff Johnson295189b2012-06-20 16:38:30 -07008048 setKey.peerMac[4], setKey.peerMac[5]);
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308049 if(pAdapter->sessionCtx.station.conn_info.connState ==
8050 eConnectionState_Associated)
Jeff Johnson295189b2012-06-20 16:38:30 -07008051 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308052 status = sme_RoamSetKey( WLAN_HDD_GET_HAL_CTX(pAdapter),
Jeff Johnson295189b2012-06-20 16:38:30 -07008053 pAdapter->sessionId, &setKey, &roamId );
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308054
Jeff Johnson295189b2012-06-20 16:38:30 -07008055 if ( 0 != status )
8056 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308057 hddLog(VOS_TRACE_LEVEL_ERROR,
Jeff Johnson295189b2012-06-20 16:38:30 -07008058 "%s: sme_RoamSetKey failure, returned %d",
8059 __func__, status);
8060 pHddStaCtx->roam_info.roamingState = HDD_ROAM_STATE_NONE;
8061 return -EINVAL;
8062 }
8063 }
8064 }
8065#endif
Jeff Johnsone7245742012-09-05 17:12:55 -07008066 EXIT();
Jeff Johnson295189b2012-06-20 16:38:30 -07008067 return status;
8068}
8069
8070/*
Mahesh A Saptasagar1a51bc02014-06-02 18:28:08 +05308071 * FUNCTION: __wlan_hdd_cfg80211_set_default_key
Jeff Johnson295189b2012-06-20 16:38:30 -07008072 * This function is used to set the default tx key index
8073 */
8074#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
Mahesh A Saptasagar1a51bc02014-06-02 18:28:08 +05308075static int __wlan_hdd_cfg80211_set_default_key( struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -07008076 struct net_device *ndev,
8077 u8 key_index,
8078 bool unicast, bool multicast)
8079#else
Mahesh A Saptasagar1a51bc02014-06-02 18:28:08 +05308080static int __wlan_hdd_cfg80211_set_default_key( struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -07008081 struct net_device *ndev,
8082 u8 key_index)
8083#endif
8084{
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308085 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( ndev );
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05308086 int status;
Gopichand Nakkala29149562013-05-10 21:43:41 +05308087 hdd_wext_state_t *pWextState;
8088 hdd_station_ctx_t *pHddStaCtx;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05308089 hdd_context_t *pHddCtx;
Jeff Johnson295189b2012-06-20 16:38:30 -07008090
8091 ENTER();
8092
Gopichand Nakkala29149562013-05-10 21:43:41 +05308093 if ((NULL == pAdapter))
8094 {
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +05308095 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
Gopichand Nakkala29149562013-05-10 21:43:41 +05308096 "invalid adapter");
8097 return -EINVAL;
8098 }
8099
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05308100 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
8101 TRACE_CODE_HDD_CFG80211_SET_DEFAULT_KEY,
8102 pAdapter->sessionId, key_index));
8103
Gopichand Nakkala29149562013-05-10 21:43:41 +05308104 pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
8105 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
8106
8107 if ((NULL == pWextState) || (NULL == pHddStaCtx))
8108 {
8109 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
8110 "invalid Wext state or HDD context");
8111 return -EINVAL;
8112 }
8113
Arif Hussain6d2a3322013-11-17 19:50:10 -08008114 hddLog(VOS_TRACE_LEVEL_INFO, "%s: device_mode = %d key_index = %d",
Jeff Johnson295189b2012-06-20 16:38:30 -07008115 __func__,pAdapter->device_mode, key_index);
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308116
Jeff Johnson295189b2012-06-20 16:38:30 -07008117 if (CSR_MAX_NUM_KEY <= key_index)
8118 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308119 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Invalid key index %d", __func__,
Jeff Johnson295189b2012-06-20 16:38:30 -07008120 key_index);
8121
8122 return -EINVAL;
8123 }
8124
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05308125 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
8126 status = wlan_hdd_validate_context(pHddCtx);
8127
8128 if (0 != status)
Jeff Johnson04dd8a82012-06-29 20:41:40 -07008129 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05308130 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
8131 "%s: HDD context is not valid", __func__);
8132 return status;
Jeff Johnson04dd8a82012-06-29 20:41:40 -07008133 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308134
Jeff Johnson295189b2012-06-20 16:38:30 -07008135 if ((pAdapter->device_mode == WLAN_HDD_INFRA_STATION)
Jeff Johnson295189b2012-06-20 16:38:30 -07008136 || (pAdapter->device_mode == WLAN_HDD_P2P_CLIENT)
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308137 )
Jeff Johnson295189b2012-06-20 16:38:30 -07008138 {
Gopichand Nakkala29149562013-05-10 21:43:41 +05308139 if ( (eCSR_ENCRYPT_TYPE_TKIP !=
Arif Hussain6943f522013-11-04 20:10:10 -08008140 pHddStaCtx->conn_info.ucEncryptionType) &&
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308141 (eCSR_ENCRYPT_TYPE_AES !=
Arif Hussain6943f522013-11-04 20:10:10 -08008142 pHddStaCtx->conn_info.ucEncryptionType)
Jeff Johnson295189b2012-06-20 16:38:30 -07008143 )
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308144 {
8145 /* if default key index is not same as previous one,
Jeff Johnson295189b2012-06-20 16:38:30 -07008146 * then update the default key index */
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308147
Jeff Johnson295189b2012-06-20 16:38:30 -07008148 tCsrRoamSetKey setKey;
8149 v_U32_t roamId= 0xFF;
8150 tCsrKeys *Keys = &pWextState->roamProfile.Keys;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308151
8152 hddLog(VOS_TRACE_LEVEL_INFO_HIGH, "%s: default tx key index %d",
Jeff Johnson295189b2012-06-20 16:38:30 -07008153 __func__, key_index);
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308154
Jeff Johnson295189b2012-06-20 16:38:30 -07008155 Keys->defaultIndex = (u8)key_index;
8156 vos_mem_zero(&setKey,sizeof(tCsrRoamSetKey));
8157 setKey.keyId = key_index;
8158 setKey.keyLength = Keys->KeyLength[key_index];
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308159
8160 vos_mem_copy(&setKey.Key[0],
8161 &Keys->KeyMaterial[key_index][0],
Jeff Johnson295189b2012-06-20 16:38:30 -07008162 Keys->KeyLength[key_index]);
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308163
Gopichand Nakkala29149562013-05-10 21:43:41 +05308164 setKey.keyDirection = eSIR_TX_RX;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308165
8166 vos_mem_copy(setKey.peerMac,
Jeff Johnson295189b2012-06-20 16:38:30 -07008167 &pHddStaCtx->conn_info.bssId[0],
8168 WNI_CFG_BSSID_LEN);
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308169
Gopichand Nakkala29149562013-05-10 21:43:41 +05308170 if (Keys->KeyLength[key_index] == CSR_WEP40_KEY_LEN &&
8171 pWextState->roamProfile.EncryptionType.encryptionType[0] ==
8172 eCSR_ENCRYPT_TYPE_WEP104)
8173 {
8174 /*In the case of dynamic wep supplicant hardcodes DWEP type to eCSR_ENCRYPT_TYPE_WEP104
8175 even though ap is configured for WEP-40 encryption. In this canse the key length
8176 is 5 but the encryption type is 104 hence checking the key langht(5) and encryption
8177 type(104) and switching encryption type to 40*/
8178 pWextState->roamProfile.EncryptionType.encryptionType[0] =
8179 eCSR_ENCRYPT_TYPE_WEP40;
8180 pWextState->roamProfile.mcEncryptionType.encryptionType[0] =
8181 eCSR_ENCRYPT_TYPE_WEP40;
8182 }
8183
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308184 setKey.encType =
Jeff Johnson295189b2012-06-20 16:38:30 -07008185 pWextState->roamProfile.EncryptionType.encryptionType[0];
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308186
Jeff Johnson295189b2012-06-20 16:38:30 -07008187 /* issue set key request */
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308188 status = sme_RoamSetKey( WLAN_HDD_GET_HAL_CTX(pAdapter),
Jeff Johnson295189b2012-06-20 16:38:30 -07008189 pAdapter->sessionId, &setKey, &roamId );
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308190
Jeff Johnson295189b2012-06-20 16:38:30 -07008191 if ( 0 != status )
8192 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308193 hddLog(VOS_TRACE_LEVEL_ERROR,
8194 "%s: sme_RoamSetKey failed, returned %d", __func__,
Jeff Johnson295189b2012-06-20 16:38:30 -07008195 status);
8196 return -EINVAL;
8197 }
8198 }
8199 }
8200
8201 /* In SoftAp mode setting key direction for default mode */
8202 else if ( WLAN_HDD_SOFTAP == pAdapter->device_mode )
8203 {
8204 if ( (eCSR_ENCRYPT_TYPE_TKIP !=
8205 pWextState->roamProfile.EncryptionType.encryptionType[0]) &&
8206 (eCSR_ENCRYPT_TYPE_AES !=
8207 pWextState->roamProfile.EncryptionType.encryptionType[0])
8208 )
8209 {
8210 /* Saving key direction for default key index to TX default */
8211 hdd_ap_ctx_t *pAPCtx = WLAN_HDD_GET_AP_CTX_PTR(pAdapter);
8212 pAPCtx->wepKey[key_index].keyDirection = eSIR_TX_DEFAULT;
8213 }
8214 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308215
Jeff Johnson295189b2012-06-20 16:38:30 -07008216 return status;
8217}
8218
Mahesh A Saptasagar1a51bc02014-06-02 18:28:08 +05308219#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
8220static int wlan_hdd_cfg80211_set_default_key( struct wiphy *wiphy,
8221 struct net_device *ndev,
8222 u8 key_index,
8223 bool unicast, bool multicast)
8224#else
8225static int wlan_hdd_cfg80211_set_default_key( struct wiphy *wiphy,
8226 struct net_device *ndev,
8227 u8 key_index)
8228#endif
8229{
8230 int ret;
8231 vos_ssr_protect(__func__);
8232#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
8233 ret = __wlan_hdd_cfg80211_set_default_key(wiphy, ndev, key_index, unicast,
8234 multicast);
8235#else
8236 ret = __wlan_hdd_cfg80211_set_default_key(wiphy, ndev, key_index);
8237#endif
8238 vos_ssr_unprotect(__func__);
8239
8240 return ret;
8241}
8242
Jeff Johnson295189b2012-06-20 16:38:30 -07008243/*
8244 * FUNCTION: wlan_hdd_cfg80211_inform_bss
8245 * This function is used to inform the BSS details to nl80211 interface.
8246 */
8247static struct cfg80211_bss* wlan_hdd_cfg80211_inform_bss(
8248 hdd_adapter_t *pAdapter, tCsrRoamConnectedProfile *roamProfile)
8249{
8250 struct net_device *dev = pAdapter->dev;
8251 struct wireless_dev *wdev = dev->ieee80211_ptr;
8252 struct wiphy *wiphy = wdev->wiphy;
8253 tSirBssDescription *pBssDesc = roamProfile->pBssDesc;
8254 int chan_no;
8255 int ie_length;
8256 const char *ie;
8257 unsigned int freq;
8258 struct ieee80211_channel *chan;
8259 int rssi = 0;
8260 struct cfg80211_bss *bss = NULL;
8261
8262 ENTER();
8263
8264 if( NULL == pBssDesc )
8265 {
Arif Hussain6d2a3322013-11-17 19:50:10 -08008266 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: pBssDesc is NULL", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07008267 return bss;
8268 }
8269
8270 chan_no = pBssDesc->channelId;
8271 ie_length = GET_IE_LEN_IN_BSS_DESC( pBssDesc->length );
8272 ie = ((ie_length != 0) ? (const char *)&pBssDesc->ieFields: NULL);
8273
8274 if( NULL == ie )
8275 {
Arif Hussain6d2a3322013-11-17 19:50:10 -08008276 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: IE of BSS descriptor is NULL", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07008277 return bss;
8278 }
8279
8280#if (LINUX_VERSION_CODE > KERNEL_VERSION(2,6,38))
8281 if (chan_no <= ARRAY_SIZE(hdd_channels_2_4_GHZ))
8282 {
8283 freq = ieee80211_channel_to_frequency(chan_no, IEEE80211_BAND_2GHZ);
8284 }
8285 else
8286 {
8287 freq = ieee80211_channel_to_frequency(chan_no, IEEE80211_BAND_5GHZ);
8288 }
8289#else
8290 freq = ieee80211_channel_to_frequency(chan_no);
8291#endif
8292
8293 chan = __ieee80211_get_channel(wiphy, freq);
8294
Santhosh Kumar Padmaa45fdb12014-04-15 15:54:38 +05308295 if (!chan) {
8296 hddLog(VOS_TRACE_LEVEL_ERROR, "%s chan pointer is NULL", __func__);
8297 return NULL;
8298 }
8299
Abhishek Singhaee43942014-06-16 18:55:47 +05308300 rssi = (VOS_MIN ((pBssDesc->rssi + pBssDesc->sinr), 0))*100;
Jeff Johnson295189b2012-06-20 16:38:30 -07008301
Abhishek Singhaee43942014-06-16 18:55:47 +05308302 return cfg80211_inform_bss(wiphy, chan, pBssDesc->bssId,
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308303 le64_to_cpu(*(__le64 *)pBssDesc->timeStamp),
Jeff Johnson295189b2012-06-20 16:38:30 -07008304 pBssDesc->capabilityInfo,
8305 pBssDesc->beaconInterval, ie, ie_length,
Abhishek Singhaee43942014-06-16 18:55:47 +05308306 rssi, GFP_KERNEL );
Jeff Johnson295189b2012-06-20 16:38:30 -07008307}
8308
8309
8310
8311/*
8312 * FUNCTION: wlan_hdd_cfg80211_inform_bss_frame
8313 * This function is used to inform the BSS details to nl80211 interface.
8314 */
8315struct cfg80211_bss*
8316wlan_hdd_cfg80211_inform_bss_frame( hdd_adapter_t *pAdapter,
8317 tSirBssDescription *bss_desc
8318 )
8319{
8320 /*
8321 cfg80211_inform_bss() is not updating ie field of bss entry, if entry
8322 already exists in bss data base of cfg80211 for that particular BSS ID.
8323 Using cfg80211_inform_bss_frame to update the bss entry instead of
8324 cfg80211_inform_bss, But this call expects mgmt packet as input. As of
8325 now there is no possibility to get the mgmt(probe response) frame from PE,
8326 converting bss_desc to ieee80211_mgmt(probe response) and passing to
8327 cfg80211_inform_bss_frame.
8328 */
8329 struct net_device *dev = pAdapter->dev;
8330 struct wireless_dev *wdev = dev->ieee80211_ptr;
8331 struct wiphy *wiphy = wdev->wiphy;
8332 int chan_no = bss_desc->channelId;
Madan Mohan Koyyalamudi86f629e2012-11-09 16:27:29 -08008333#ifdef WLAN_ENABLE_AGEIE_ON_SCAN_RESULTS
8334 qcom_ie_age *qie_age = NULL;
8335 int ie_length = GET_IE_LEN_IN_BSS_DESC( bss_desc->length ) + sizeof(qcom_ie_age);
8336#else
Jeff Johnson295189b2012-06-20 16:38:30 -07008337 int ie_length = GET_IE_LEN_IN_BSS_DESC( bss_desc->length );
Madan Mohan Koyyalamudi86f629e2012-11-09 16:27:29 -08008338#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07008339 const char *ie =
8340 ((ie_length != 0) ? (const char *)&bss_desc->ieFields: NULL);
8341 unsigned int freq;
8342 struct ieee80211_channel *chan;
Abhishek Singh1e2bfa32014-01-02 15:44:15 +05308343 struct ieee80211_mgmt *mgmt = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -07008344 struct cfg80211_bss *bss_status = NULL;
8345 size_t frame_len = sizeof (struct ieee80211_mgmt) + ie_length;
8346 int rssi = 0;
Wilson Yangf80a0542013-10-07 13:02:37 -07008347 hdd_context_t *pHddCtx;
8348 int status;
Jeff Johnsone7245742012-09-05 17:12:55 -07008349#ifdef WLAN_OPEN_SOURCE
8350 struct timespec ts;
8351#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07008352
Wilson Yangf80a0542013-10-07 13:02:37 -07008353 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
8354 status = wlan_hdd_validate_context(pHddCtx);
8355
8356 /*bss_update is not allowed during wlan driver loading or unloading*/
Mihir Shete18156292014-03-11 15:38:30 +05308357 if (WLAN_HDD_IS_LOAD_UNLOAD_IN_PROGRESS(pHddCtx))
Wilson Yangf80a0542013-10-07 13:02:37 -07008358 {
8359 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
8360 "%s:Loading_unloading in Progress. Ignore!!!",__func__);
8361 return NULL;
8362 }
8363
8364
8365 if (0 != status)
8366 {
8367 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
8368 "%s: HDD context is not valid", __func__);
Madan Mohan Koyyalamudi2e5c9142012-11-02 13:17:48 -07008369 return NULL;
Wilson Yangf80a0542013-10-07 13:02:37 -07008370 }
8371
Abhishek Singh1e2bfa32014-01-02 15:44:15 +05308372 mgmt = kzalloc((sizeof (struct ieee80211_mgmt) + ie_length), GFP_KERNEL);
Wilson Yangf80a0542013-10-07 13:02:37 -07008373 if (!mgmt)
8374 {
8375 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
8376 "%s: memory allocation failed ", __func__);
8377 return NULL;
8378 }
Madan Mohan Koyyalamudi2e5c9142012-11-02 13:17:48 -07008379
Jeff Johnson295189b2012-06-20 16:38:30 -07008380 memcpy(mgmt->bssid, bss_desc->bssId, ETH_ALEN);
Jeff Johnsone7245742012-09-05 17:12:55 -07008381
8382#ifdef WLAN_OPEN_SOURCE
8383 /* Android does not want the timestamp from the frame.
8384 Instead it wants a monotonic increasing value */
8385 get_monotonic_boottime(&ts);
8386 mgmt->u.probe_resp.timestamp =
8387 ((u64)ts.tv_sec * 1000000) + (ts.tv_nsec / 1000);
8388#else
8389 /* keep old behavior for non-open source (for now) */
Jeff Johnson295189b2012-06-20 16:38:30 -07008390 memcpy(&mgmt->u.probe_resp.timestamp, bss_desc->timeStamp,
8391 sizeof (bss_desc->timeStamp));
Jeff Johnsone7245742012-09-05 17:12:55 -07008392
8393#endif
8394
Jeff Johnson295189b2012-06-20 16:38:30 -07008395 mgmt->u.probe_resp.beacon_int = bss_desc->beaconInterval;
8396 mgmt->u.probe_resp.capab_info = bss_desc->capabilityInfo;
Madan Mohan Koyyalamudi86f629e2012-11-09 16:27:29 -08008397
8398#ifdef WLAN_ENABLE_AGEIE_ON_SCAN_RESULTS
8399 /* GPS Requirement: need age ie per entry. Using vendor specific. */
8400 /* Assuming this is the last IE, copy at the end */
8401 ie_length -=sizeof(qcom_ie_age);
8402 qie_age = (qcom_ie_age *)(mgmt->u.probe_resp.variable + ie_length);
8403 qie_age->element_id = QCOM_VENDOR_IE_ID;
8404 qie_age->len = QCOM_VENDOR_IE_AGE_LEN;
8405 qie_age->oui_1 = QCOM_OUI1;
8406 qie_age->oui_2 = QCOM_OUI2;
8407 qie_age->oui_3 = QCOM_OUI3;
8408 qie_age->type = QCOM_VENDOR_IE_AGE_TYPE;
8409 qie_age->age = vos_timer_get_system_ticks() - bss_desc->nReceivedTime;
8410#endif
8411
Jeff Johnson295189b2012-06-20 16:38:30 -07008412 memcpy(mgmt->u.probe_resp.variable, ie, ie_length);
Gopichand Nakkalad908ec82013-05-16 19:32:19 +05308413 if (bss_desc->fProbeRsp)
8414 {
8415 mgmt->frame_control |=
8416 (u16)(IEEE80211_FTYPE_MGMT | IEEE80211_STYPE_PROBE_RESP);
8417 }
8418 else
8419 {
8420 mgmt->frame_control |=
8421 (u16)(IEEE80211_FTYPE_MGMT | IEEE80211_STYPE_BEACON);
8422 }
Jeff Johnson295189b2012-06-20 16:38:30 -07008423
8424#if (LINUX_VERSION_CODE > KERNEL_VERSION(2,6,38))
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308425 if (chan_no <= ARRAY_SIZE(hdd_channels_2_4_GHZ) &&
Jeff Johnson295189b2012-06-20 16:38:30 -07008426 (wiphy->bands[IEEE80211_BAND_2GHZ] != NULL))
8427 {
8428 freq = ieee80211_channel_to_frequency(chan_no, IEEE80211_BAND_2GHZ);
8429 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308430 else if ((chan_no > ARRAY_SIZE(hdd_channels_2_4_GHZ)) &&
Jeff Johnson295189b2012-06-20 16:38:30 -07008431 (wiphy->bands[IEEE80211_BAND_5GHZ] != NULL))
8432
8433 {
8434 freq = ieee80211_channel_to_frequency(chan_no, IEEE80211_BAND_5GHZ);
8435 }
8436 else
8437 {
Nirav Shah20ac06f2013-12-12 18:14:06 +05308438 hddLog(VOS_TRACE_LEVEL_ERROR, "%s Invalid chan_no:%d",
8439 __func__, chan_no);
Jeff Johnson295189b2012-06-20 16:38:30 -07008440 kfree(mgmt);
8441 return NULL;
8442 }
8443#else
8444 freq = ieee80211_channel_to_frequency(chan_no);
8445#endif
8446 chan = __ieee80211_get_channel(wiphy, freq);
Leela V Kiran Kumar Reddy90032de2013-01-24 18:33:30 -08008447 /*when the band is changed on the fly using the GUI, three things are done
8448 * 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)
8449 * as part of the scan abort, message willbe queued to PE and we proceed with flushing and changinh the band.
8450 * pe will stop the scanning further and report back the results what ever it had till now by calling the call back function.
8451 * if the time between update band and scandone call back is sufficent enough the band change reflects in SME, SME validates the channels
8452 * and discards the channels correponding to previous band and calls back with zero bss results.
8453 * 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
8454 * all the channels correponding to previous band.this is due to race condition.but those channels are invalid to the new band and so
8455 * this function __ieee80211_get_channel will return NULL.Each time we report scan result with this pointer null warning kernel trace is printed.
8456 * if the scan results contain large number of APs continuosly kernel warning trace is printed and it will lead to apps watch dog bark.
8457 * So drop the bss and continue to next bss.
8458 */
8459 if(chan == NULL)
8460 {
Nirav Shah20ac06f2013-12-12 18:14:06 +05308461 hddLog(VOS_TRACE_LEVEL_ERROR, "%s chan pointer is NULL", __func__);
Chilam Ngc4244af2013-04-01 15:37:32 -07008462 kfree(mgmt);
Leela V Kiran Kumar Reddy90032de2013-01-24 18:33:30 -08008463 return NULL;
8464 }
Jeff Johnson295189b2012-06-20 16:38:30 -07008465 /*To keep the rssi icon of the connected AP in the scan window
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308466 *and the rssi icon of the wireless networks in sync
Jeff Johnson295189b2012-06-20 16:38:30 -07008467 * */
8468 if (( eConnectionState_Associated ==
8469 pAdapter->sessionCtx.station.conn_info.connState ) &&
8470 ( VOS_TRUE == vos_mem_compare(bss_desc->bssId,
8471 pAdapter->sessionCtx.station.conn_info.bssId,
8472 WNI_CFG_BSSID_LEN)))
8473 {
8474 /* supplicant takes the signal strength in terms of mBm(100*dBm) */
8475 rssi = (pAdapter->rssi * 100);
8476 }
8477 else
8478 {
8479 rssi = (VOS_MIN ((bss_desc->rssi + bss_desc->sinr), 0))*100;
8480 }
8481
Nirav Shah20ac06f2013-12-12 18:14:06 +05308482 hddLog(VOS_TRACE_LEVEL_INFO, "%s: BSSID:" MAC_ADDRESS_STR " Channel:%d"
8483 "RSSI:%d", __func__, MAC_ADDR_ARRAY(mgmt->bssid),
8484 chan->center_freq, (int)(rssi/100));
8485
Jeff Johnson295189b2012-06-20 16:38:30 -07008486 bss_status = cfg80211_inform_bss_frame(wiphy, chan, mgmt,
8487 frame_len, rssi, GFP_KERNEL);
8488 kfree(mgmt);
8489 return bss_status;
8490}
8491
8492/*
8493 * FUNCTION: wlan_hdd_cfg80211_update_bss_db
8494 * This function is used to update the BSS data base of CFG8011
8495 */
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308496struct cfg80211_bss* wlan_hdd_cfg80211_update_bss_db( hdd_adapter_t *pAdapter,
Jeff Johnson295189b2012-06-20 16:38:30 -07008497 tCsrRoamInfo *pRoamInfo
8498 )
8499{
8500 tCsrRoamConnectedProfile roamProfile;
8501 tHalHandle hHal = WLAN_HDD_GET_HAL_CTX(pAdapter);
8502 struct cfg80211_bss *bss = NULL;
8503
8504 ENTER();
8505
8506 memset(&roamProfile, 0, sizeof(tCsrRoamConnectedProfile));
8507 sme_RoamGetConnectProfile(hHal, pAdapter->sessionId, &roamProfile);
8508
8509 if (NULL != roamProfile.pBssDesc)
8510 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308511 bss = wlan_hdd_cfg80211_inform_bss(pAdapter,
Jeff Johnson295189b2012-06-20 16:38:30 -07008512 &roamProfile);
8513
8514 if (NULL == bss)
8515 {
8516 hddLog(VOS_TRACE_LEVEL_INFO, "%s: cfg80211_inform_bss return NULL",
8517 __func__);
8518 }
8519
8520 sme_RoamFreeConnectProfile(hHal, &roamProfile);
8521 }
8522 else
8523 {
8524 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: roamProfile.pBssDesc is NULL",
8525 __func__);
8526 }
8527 return bss;
8528}
8529
8530/*
8531 * FUNCTION: wlan_hdd_cfg80211_update_bss
8532 */
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308533static int wlan_hdd_cfg80211_update_bss( struct wiphy *wiphy,
8534 hdd_adapter_t *pAdapter
Jeff Johnson295189b2012-06-20 16:38:30 -07008535 )
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308536{
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +05308537 tHalHandle hHal = WLAN_HDD_GET_HAL_CTX(pAdapter);
Jeff Johnson295189b2012-06-20 16:38:30 -07008538 tCsrScanResultInfo *pScanResult;
8539 eHalStatus status = 0;
8540 tScanResultHandle pResult;
8541 struct cfg80211_bss *bss_status = NULL;
Wilson Yangf80a0542013-10-07 13:02:37 -07008542 hdd_context_t *pHddCtx;
Jeff Johnson295189b2012-06-20 16:38:30 -07008543
8544 ENTER();
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +05308545
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05308546 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
8547 TRACE_CODE_HDD_CFG80211_UPDATE_BSS,
8548 NO_SESSION, pAdapter->sessionId));
8549
Wilson Yangf80a0542013-10-07 13:02:37 -07008550 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
8551
8552 if (pHddCtx->isLogpInProgress)
Jeff Johnson295189b2012-06-20 16:38:30 -07008553 {
Wilson Yangf80a0542013-10-07 13:02:37 -07008554 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
8555 "%s:LOGP in Progress. Ignore!!!",__func__);
8556 return -EAGAIN;
Jeff Johnson295189b2012-06-20 16:38:30 -07008557 }
8558
Wilson Yangf80a0542013-10-07 13:02:37 -07008559
8560 /*bss_update is not allowed during wlan driver loading or unloading*/
Mihir Shete18156292014-03-11 15:38:30 +05308561 if (WLAN_HDD_IS_LOAD_UNLOAD_IN_PROGRESS(pHddCtx))
Wilson Yangf80a0542013-10-07 13:02:37 -07008562 {
8563 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
8564 "%s:Loading_unloading in Progress. Ignore!!!",__func__);
8565 return VOS_STATUS_E_PERM;
8566 }
8567
8568
Jeff Johnson295189b2012-06-20 16:38:30 -07008569 /*
8570 * start getting scan results and populate cgf80211 BSS database
8571 */
8572 status = sme_ScanGetResult(hHal, pAdapter->sessionId, NULL, &pResult);
8573
8574 /* no scan results */
8575 if (NULL == pResult)
8576 {
Nirav Shah20ac06f2013-12-12 18:14:06 +05308577 hddLog(VOS_TRACE_LEVEL_INFO, "%s: No scan result Status %d",
8578 __func__, status);
Jeff Johnson295189b2012-06-20 16:38:30 -07008579 return status;
8580 }
8581
8582 pScanResult = sme_ScanResultGetFirst(hHal, pResult);
8583
8584 while (pScanResult)
8585 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308586 /*
8587 * cfg80211_inform_bss() is not updating ie field of bss entry, if
8588 * entry already exists in bss data base of cfg80211 for that
8589 * particular BSS ID. Using cfg80211_inform_bss_frame to update the
8590 * bss entry instead of cfg80211_inform_bss, But this call expects
8591 * mgmt packet as input. As of now there is no possibility to get
8592 * the mgmt(probe response) frame from PE, converting bss_desc to
Jeff Johnson295189b2012-06-20 16:38:30 -07008593 * ieee80211_mgmt(probe response) and passing to c
8594 * fg80211_inform_bss_frame.
8595 * */
8596
8597 bss_status = wlan_hdd_cfg80211_inform_bss_frame(pAdapter,
8598 &pScanResult->BssDescriptor);
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308599
Jeff Johnson295189b2012-06-20 16:38:30 -07008600
8601 if (NULL == bss_status)
8602 {
8603 hddLog(VOS_TRACE_LEVEL_INFO,
Arif Hussain6d2a3322013-11-17 19:50:10 -08008604 "%s: NULL returned by cfg80211_inform_bss", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07008605 }
8606 else
8607 {
Yue Maf49ba872013-08-19 12:04:25 -07008608 cfg80211_put_bss(
8609#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,9,0))
8610 wiphy,
8611#endif
8612 bss_status);
Jeff Johnson295189b2012-06-20 16:38:30 -07008613 }
8614
8615 pScanResult = sme_ScanResultGetNext(hHal, pResult);
8616 }
8617
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308618 sme_ScanResultPurge(hHal, pResult);
Jeff Johnson295189b2012-06-20 16:38:30 -07008619
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308620 return 0;
Jeff Johnson295189b2012-06-20 16:38:30 -07008621}
8622
Jeff Johnson04dd8a82012-06-29 20:41:40 -07008623void
8624hddPrintMacAddr(tCsrBssid macAddr, tANI_U8 logLevel)
8625{
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308626 VOS_TRACE(VOS_MODULE_ID_HDD, logLevel,
Arif Hussaina7c8e412013-11-20 11:06:42 -08008627 MAC_ADDRESS_STR, MAC_ADDR_ARRAY(macAddr));
Jeff Johnson04dd8a82012-06-29 20:41:40 -07008628} /****** end hddPrintMacAddr() ******/
8629
8630void
Madan Mohan Koyyalamudic75be962012-10-18 19:19:03 -07008631hddPrintPmkId(tANI_U8 *pmkId, tANI_U8 logLevel)
Jeff Johnson04dd8a82012-06-29 20:41:40 -07008632{
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308633 VOS_TRACE(VOS_MODULE_ID_HDD, logLevel,
Arif Hussain6d2a3322013-11-17 19:50:10 -08008634 "%02X:%02X:%02X:%02X:%02X:%02X:%02X:%02X:%02X:%02X:%02X:%02X:%02X:%02X:%02X:%02X",
Madan Mohan Koyyalamudic75be962012-10-18 19:19:03 -07008635 pmkId[0], pmkId[1], pmkId[2], pmkId[3], pmkId[4],
8636 pmkId[5], pmkId[6], pmkId[7], pmkId[8], pmkId[9], pmkId[10],
8637 pmkId[11], pmkId[12], pmkId[13], pmkId[14], pmkId[15]);
Jeff Johnson04dd8a82012-06-29 20:41:40 -07008638} /****** end hddPrintPmkId() ******/
8639
8640//hddPrintMacAddr(tCsrBssid macAddr, tANI_U8 logLevel);
8641//hddPrintMacAddr(macAddr, VOS_TRACE_LEVEL_FATAL);
8642
8643//void sirDumpBuf(tpAniSirGlobal pMac, tANI_U8 modId, tANI_U32 level, tANI_U8 *buf, tANI_U32 size);
8644//sirDumpBuf(pMac, VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL, pmkid, 16);
8645
8646#define dump_bssid(bssid) \
8647 { \
Jeff Johnsone7245742012-09-05 17:12:55 -07008648 hddLog(VOS_TRACE_LEVEL_INFO, "BSSID (MAC) address:\t"); \
8649 hddPrintMacAddr(bssid, VOS_TRACE_LEVEL_INFO);\
Jeff Johnson04dd8a82012-06-29 20:41:40 -07008650 }
8651
8652#define dump_pmkid(pMac, pmkid) \
8653 { \
Jeff Johnsone7245742012-09-05 17:12:55 -07008654 hddLog(VOS_TRACE_LEVEL_INFO, "PMKSA-ID:\t"); \
8655 hddPrintPmkId(pmkid, VOS_TRACE_LEVEL_INFO);\
Jeff Johnson04dd8a82012-06-29 20:41:40 -07008656 }
8657
Madan Mohan Koyyalamudi1b4afb02012-10-22 15:25:16 -07008658#if defined(FEATURE_WLAN_LFR) && (LINUX_VERSION_CODE >= KERNEL_VERSION(3,4,0))
Jeff Johnson04dd8a82012-06-29 20:41:40 -07008659/*
8660 * FUNCTION: wlan_hdd_cfg80211_pmksa_candidate_notify
8661 * This function is used to notify the supplicant of a new PMKSA candidate.
8662 */
8663int wlan_hdd_cfg80211_pmksa_candidate_notify(
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308664 hdd_adapter_t *pAdapter, tCsrRoamInfo *pRoamInfo,
Jeff Johnson04dd8a82012-06-29 20:41:40 -07008665 int index, bool preauth )
8666{
Jeff Johnsone7245742012-09-05 17:12:55 -07008667#ifdef FEATURE_WLAN_OKC
Jeff Johnson04dd8a82012-06-29 20:41:40 -07008668 struct net_device *dev = pAdapter->dev;
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07008669 hdd_context_t *pHddCtx = (hdd_context_t*)pAdapter->pHddCtx;
Jeff Johnson04dd8a82012-06-29 20:41:40 -07008670
8671 ENTER();
Jeff Johnsone7245742012-09-05 17:12:55 -07008672 hddLog(VOS_TRACE_LEVEL_INFO, "%s is going to notify supplicant of:", __func__);
Jeff Johnson04dd8a82012-06-29 20:41:40 -07008673
8674 if( NULL == pRoamInfo )
8675 {
Arif Hussain6d2a3322013-11-17 19:50:10 -08008676 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: pRoamInfo is NULL", __func__);
Jeff Johnson04dd8a82012-06-29 20:41:40 -07008677 return -EINVAL;
8678 }
8679
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07008680 if (eANI_BOOLEAN_TRUE == hdd_is_okc_mode_enabled(pHddCtx))
8681 {
8682 dump_bssid(pRoamInfo->bssid);
8683 cfg80211_pmksa_candidate_notify(dev, index,
Jeff Johnson04dd8a82012-06-29 20:41:40 -07008684 pRoamInfo->bssid, preauth, GFP_KERNEL);
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07008685 }
Jeff Johnsone7245742012-09-05 17:12:55 -07008686#endif /* FEATURE_WLAN_OKC */
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308687 return 0;
Jeff Johnson04dd8a82012-06-29 20:41:40 -07008688}
8689#endif //FEATURE_WLAN_LFR
8690
Yue Maef608272013-04-08 23:09:17 -07008691#ifdef FEATURE_WLAN_LFR_METRICS
8692/*
8693 * FUNCTION: wlan_hdd_cfg80211_roam_metrics_preauth
8694 * 802.11r/LFR metrics reporting function to report preauth initiation
8695 *
8696 */
8697#define MAX_LFR_METRICS_EVENT_LENGTH 100
8698VOS_STATUS wlan_hdd_cfg80211_roam_metrics_preauth(hdd_adapter_t *pAdapter,
8699 tCsrRoamInfo *pRoamInfo)
8700{
8701 unsigned char metrics_notification[MAX_LFR_METRICS_EVENT_LENGTH + 1];
8702 union iwreq_data wrqu;
8703
8704 ENTER();
8705
8706 if (NULL == pAdapter)
8707 {
8708 hddLog(LOGE, "%s: pAdapter is NULL!", __func__);
8709 return VOS_STATUS_E_FAILURE;
8710 }
8711
8712 /* create the event */
8713 memset(&wrqu, 0, sizeof(wrqu));
8714 memset(metrics_notification, 0, sizeof(metrics_notification));
8715
8716 wrqu.data.pointer = metrics_notification;
8717 wrqu.data.length = scnprintf(metrics_notification,
8718 sizeof(metrics_notification), "QCOM: LFR_PREAUTH_INIT "
8719 MAC_ADDRESS_STR, MAC_ADDR_ARRAY(pRoamInfo->bssid));
8720
8721 wireless_send_event(pAdapter->dev, IWEVCUSTOM, &wrqu, metrics_notification);
8722
8723 EXIT();
8724
8725 return VOS_STATUS_SUCCESS;
8726}
8727
8728/*
8729 * FUNCTION: wlan_hdd_cfg80211_roam_metrics_preauth_status
8730 * 802.11r/LFR metrics reporting function to report preauth completion
8731 * or failure
8732 */
8733VOS_STATUS wlan_hdd_cfg80211_roam_metrics_preauth_status(
8734 hdd_adapter_t *pAdapter, tCsrRoamInfo *pRoamInfo, bool preauth_status)
8735{
8736 unsigned char metrics_notification[MAX_LFR_METRICS_EVENT_LENGTH + 1];
8737 union iwreq_data wrqu;
8738
8739 ENTER();
8740
8741 if (NULL == pAdapter)
8742 {
8743 hddLog(LOGE, "%s: pAdapter is NULL!", __func__);
8744 return VOS_STATUS_E_FAILURE;
8745 }
8746
8747 /* create the event */
8748 memset(&wrqu, 0, sizeof(wrqu));
8749 memset(metrics_notification, 0, sizeof(metrics_notification));
8750
8751 scnprintf(metrics_notification, sizeof(metrics_notification),
8752 "QCOM: LFR_PREAUTH_STATUS "MAC_ADDRESS_STR,
8753 MAC_ADDR_ARRAY(pRoamInfo->bssid));
8754
8755 if (1 == preauth_status)
8756 strncat(metrics_notification, " TRUE", 5);
8757 else
8758 strncat(metrics_notification, " FALSE", 6);
8759
8760 wrqu.data.pointer = metrics_notification;
8761 wrqu.data.length = strlen(metrics_notification);
8762
8763 wireless_send_event(pAdapter->dev, IWEVCUSTOM, &wrqu, metrics_notification);
8764
8765 EXIT();
8766
8767 return VOS_STATUS_SUCCESS;
8768}
8769
8770/*
8771 * FUNCTION: wlan_hdd_cfg80211_roam_metrics_handover
8772 * 802.11r/LFR metrics reporting function to report handover initiation
8773 *
8774 */
8775VOS_STATUS wlan_hdd_cfg80211_roam_metrics_handover(hdd_adapter_t * pAdapter,
8776 tCsrRoamInfo *pRoamInfo)
8777{
8778 unsigned char metrics_notification[MAX_LFR_METRICS_EVENT_LENGTH + 1];
8779 union iwreq_data wrqu;
8780
8781 ENTER();
8782
8783 if (NULL == pAdapter)
8784 {
8785 hddLog(LOGE, "%s: pAdapter is NULL!", __func__);
8786 return VOS_STATUS_E_FAILURE;
8787 }
8788
8789 /* create the event */
8790 memset(&wrqu, 0, sizeof(wrqu));
8791 memset(metrics_notification, 0, sizeof(metrics_notification));
8792
8793 wrqu.data.pointer = metrics_notification;
8794 wrqu.data.length = scnprintf(metrics_notification,
8795 sizeof(metrics_notification), "QCOM: LFR_PREAUTH_HANDOVER "
8796 MAC_ADDRESS_STR, MAC_ADDR_ARRAY(pRoamInfo->bssid));
8797
8798 wireless_send_event(pAdapter->dev, IWEVCUSTOM, &wrqu, metrics_notification);
8799
8800 EXIT();
8801
8802 return VOS_STATUS_SUCCESS;
8803}
8804#endif
8805
Jeff Johnson295189b2012-06-20 16:38:30 -07008806/*
8807 * FUNCTION: hdd_cfg80211_scan_done_callback
8808 * scanning callback function, called after finishing scan
8809 *
8810 */
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308811static eHalStatus hdd_cfg80211_scan_done_callback(tHalHandle halHandle,
Jeff Johnson295189b2012-06-20 16:38:30 -07008812 void *pContext, tANI_U32 scanId, eCsrScanStatus status)
8813{
8814 struct net_device *dev = (struct net_device *) pContext;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308815 //struct wireless_dev *wdev = dev->ieee80211_ptr;
Jeff Johnson295189b2012-06-20 16:38:30 -07008816 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( dev );
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -07008817 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
8818 hdd_scaninfo_t *pScanInfo = &pHddCtx->scan_info;
Jeff Johnson295189b2012-06-20 16:38:30 -07008819 struct cfg80211_scan_request *req = NULL;
8820 int ret = 0;
Mahesh A Saptasagar05a357e2014-02-26 16:28:06 +05308821 bool aborted = false;
c_hpothu6ff1c3c2013-10-01 19:01:57 +05308822 long waitRet = 0;
Jeff Johnson295189b2012-06-20 16:38:30 -07008823
8824 ENTER();
8825
8826 hddLog(VOS_TRACE_LEVEL_INFO,
8827 "%s called with halHandle = %p, pContext = %p,"
Arif Hussain6d2a3322013-11-17 19:50:10 -08008828 "scanID = %d, returned status = %d",
Jeff Johnson295189b2012-06-20 16:38:30 -07008829 __func__, halHandle, pContext, (int) scanId, (int) status);
8830
Kiet Lamac06e2c2013-10-23 16:25:07 +05308831 pScanInfo->mScanPendingCounter = 0;
8832
Jeff Johnson295189b2012-06-20 16:38:30 -07008833 //Block on scan req completion variable. Can't wait forever though.
c_hpothu6ff1c3c2013-10-01 19:01:57 +05308834 waitRet = wait_for_completion_interruptible_timeout(
Jeff Johnson295189b2012-06-20 16:38:30 -07008835 &pScanInfo->scan_req_completion_event,
8836 msecs_to_jiffies(WLAN_WAIT_TIME_SCAN_REQ));
c_hpothu6ff1c3c2013-10-01 19:01:57 +05308837 if (waitRet <= 0)
Jeff Johnson295189b2012-06-20 16:38:30 -07008838 {
c_hpothu6ff1c3c2013-10-01 19:01:57 +05308839 hddLog(VOS_TRACE_LEVEL_ERROR,
8840 "%s wait on scan_req_completion_event failed %ld",__func__, waitRet);
Jeff Johnson295189b2012-06-20 16:38:30 -07008841 VOS_ASSERT(pScanInfo->mScanPending);
Jeff Johnsone7245742012-09-05 17:12:55 -07008842 goto allow_suspend;
Jeff Johnson295189b2012-06-20 16:38:30 -07008843 }
8844
Yue Maef608272013-04-08 23:09:17 -07008845 if (pScanInfo->mScanPending != VOS_TRUE)
Jeff Johnson295189b2012-06-20 16:38:30 -07008846 {
8847 VOS_ASSERT(pScanInfo->mScanPending);
Jeff Johnsone7245742012-09-05 17:12:55 -07008848 goto allow_suspend;
Jeff Johnson295189b2012-06-20 16:38:30 -07008849 }
8850
8851 /* Check the scanId */
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308852 if (pScanInfo->scanId != scanId)
Jeff Johnson295189b2012-06-20 16:38:30 -07008853 {
8854 hddLog(VOS_TRACE_LEVEL_INFO,
8855 "%s called with mismatched scanId pScanInfo->scanId = %d "
Arif Hussain6d2a3322013-11-17 19:50:10 -08008856 "scanId = %d", __func__, (int) pScanInfo->scanId,
Jeff Johnson295189b2012-06-20 16:38:30 -07008857 (int) scanId);
8858 }
8859
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308860 ret = wlan_hdd_cfg80211_update_bss((WLAN_HDD_GET_CTX(pAdapter))->wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -07008861 pAdapter);
8862
8863 if (0 > ret)
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308864 hddLog(VOS_TRACE_LEVEL_INFO, "%s: NO SCAN result", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07008865
8866
8867 /* If any client wait scan result through WEXT
8868 * send scan done event to client */
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -07008869 if (pHddCtx->scan_info.waitScanResult)
Jeff Johnson295189b2012-06-20 16:38:30 -07008870 {
8871 /* The other scan request waiting for current scan finish
8872 * Send event to notify current scan finished */
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -07008873 if(WEXT_SCAN_PENDING_DELAY == pHddCtx->scan_info.scan_pending_option)
Jeff Johnson295189b2012-06-20 16:38:30 -07008874 {
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -07008875 vos_event_set(&pHddCtx->scan_info.scan_finished_event);
Jeff Johnson295189b2012-06-20 16:38:30 -07008876 }
8877 /* Send notify to WEXT client */
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -07008878 else if(WEXT_SCAN_PENDING_PIGGYBACK == pHddCtx->scan_info.scan_pending_option)
Jeff Johnson295189b2012-06-20 16:38:30 -07008879 {
8880 struct net_device *dev = pAdapter->dev;
8881 union iwreq_data wrqu;
8882 int we_event;
8883 char *msg;
8884
8885 memset(&wrqu, '\0', sizeof(wrqu));
8886 we_event = SIOCGIWSCAN;
8887 msg = NULL;
8888 wireless_send_event(dev, we_event, &wrqu, msg);
8889 }
8890 }
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -07008891 pHddCtx->scan_info.waitScanResult = FALSE;
Jeff Johnson295189b2012-06-20 16:38:30 -07008892
8893 /* Get the Scan Req */
8894 req = pAdapter->request;
8895
8896 if (!req)
8897 {
Arif Hussain6d2a3322013-11-17 19:50:10 -08008898 hddLog(VOS_TRACE_LEVEL_ERROR, "request is became NULL");
Madan Mohan Koyyalamudi9f5a10c2012-09-28 14:46:16 -07008899 pScanInfo->mScanPending = VOS_FALSE;
Jeff Johnsone7245742012-09-05 17:12:55 -07008900 goto allow_suspend;
Jeff Johnson295189b2012-06-20 16:38:30 -07008901 }
8902
8903 /*
8904 * setting up 0, just in case.
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308905 */
Jeff Johnson295189b2012-06-20 16:38:30 -07008906 req->n_ssids = 0;
8907 req->n_channels = 0;
8908 req->ie = 0;
8909
Jeff Johnson295189b2012-06-20 16:38:30 -07008910 pAdapter->request = NULL;
Jeff Johnsone7245742012-09-05 17:12:55 -07008911 /* Scan is no longer pending */
8912 pScanInfo->mScanPending = VOS_FALSE;
Jeff Johnson295189b2012-06-20 16:38:30 -07008913
Madan Mohan Koyyalamudib764bf82012-10-11 16:38:51 -07008914 /*
8915 * cfg80211_scan_done informing NL80211 about completion
8916 * of scanning
8917 */
Mahesh A Saptasagar05a357e2014-02-26 16:28:06 +05308918 if (status == eCSR_SCAN_ABORT || status == eCSR_SCAN_FAILURE)
8919 {
8920 aborted = true;
8921 }
8922 cfg80211_scan_done(req, aborted);
Madan Mohan Koyyalamudif4e81002012-11-13 10:46:38 -08008923 complete(&pScanInfo->abortscan_event_var);
Jeff Johnson295189b2012-06-20 16:38:30 -07008924
Jeff Johnsone7245742012-09-05 17:12:55 -07008925allow_suspend:
Madan Mohan Koyyalamudi9f5a10c2012-09-28 14:46:16 -07008926 /* release the wake lock at the end of the scan*/
8927 hdd_allow_suspend();
Jeff Johnsone7245742012-09-05 17:12:55 -07008928
Madan Mohan Koyyalamudi10d83a92012-09-28 15:47:05 -07008929 /* Acquire wakelock to handle the case where APP's tries to suspend
8930 * immediatly after the driver gets connect request(i.e after scan)
8931 * from supplicant, this result in app's is suspending and not able
8932 * to process the connect request to AP */
Mahesh A Saptasagarb9c50402014-01-16 15:49:22 +05308933 hdd_prevent_suspend_timeout(1000);
Madan Mohan Koyyalamudi10d83a92012-09-28 15:47:05 -07008934
Gopichand Nakkala638ebc72013-03-21 18:04:02 -07008935#ifdef FEATURE_WLAN_TDLS
c_hpothu3c8f8e82014-06-02 18:01:50 +05308936 if (!(eTDLS_SUPPORT_NOT_ENABLED == pHddCtx->tdls_mode))
8937 {
8938 wlan_hdd_tdls_scan_done_callback(pAdapter);
8939 }
Gopichand Nakkala638ebc72013-03-21 18:04:02 -07008940#endif
8941
Jeff Johnson295189b2012-06-20 16:38:30 -07008942 EXIT();
8943 return 0;
8944}
8945
8946/*
Rashmi Ramannab1429032014-04-26 14:59:09 +05308947 * FUNCTION: hdd_isConnectionInProgress
8948 * Go through each adapter and check if Connection is in progress
Madan Mohan Koyyalamudicfd53742013-01-11 15:29:03 -08008949 *
8950 */
Rashmi Ramannab1429032014-04-26 14:59:09 +05308951v_BOOL_t hdd_isConnectionInProgress( hdd_context_t *pHddCtx )
Madan Mohan Koyyalamudicfd53742013-01-11 15:29:03 -08008952{
8953 hdd_adapter_list_node_t *pAdapterNode = NULL, *pNext = NULL;
8954 hdd_station_ctx_t *pHddStaCtx = NULL;
8955 hdd_adapter_t *pAdapter = NULL;
8956 VOS_STATUS status = 0;
8957 v_U8_t staId = 0;
8958 v_U8_t *staMac = NULL;
8959
c_hpothu9b781ba2013-12-30 20:57:45 +05308960 if (TRUE == pHddCtx->btCoexModeSet)
8961 {
8962 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Rashmi Ramannab1429032014-04-26 14:59:09 +05308963 FL("BTCoex Mode operation in progress"));
8964 return VOS_TRUE;
c_hpothu9b781ba2013-12-30 20:57:45 +05308965 }
8966
Madan Mohan Koyyalamudicfd53742013-01-11 15:29:03 -08008967 status = hdd_get_front_adapter ( pHddCtx, &pAdapterNode );
8968
8969 while ( NULL != pAdapterNode && VOS_STATUS_SUCCESS == status )
8970 {
8971 pAdapter = pAdapterNode->pAdapter;
8972
8973 if( pAdapter )
8974 {
8975 hddLog(VOS_TRACE_LEVEL_INFO,
Sushant Kaushik8bc7df22014-04-09 17:55:29 +05308976 "%s: Adapter with device mode %s (%d) exists",
8977 __func__, hdd_device_modetoString(pAdapter->device_mode),
8978 pAdapter->device_mode);
Rashmi Ramannab1429032014-04-26 14:59:09 +05308979 if (((WLAN_HDD_INFRA_STATION == pAdapter->device_mode) ||
8980 (WLAN_HDD_P2P_CLIENT == pAdapter->device_mode) ||
8981 (WLAN_HDD_P2P_DEVICE == pAdapter->device_mode)) &&
8982 (eConnectionState_Connecting ==
8983 (WLAN_HDD_GET_STATION_CTX_PTR(pAdapter))->conn_info.connState))
8984 {
8985 hddLog(VOS_TRACE_LEVEL_ERROR,
8986 "%s: %p(%d) Connection is in progress", __func__,
8987 WLAN_HDD_GET_STATION_CTX_PTR(pAdapter), pAdapter->sessionId);
8988 return VOS_TRUE;
8989 }
Madan Mohan Koyyalamudicfd53742013-01-11 15:29:03 -08008990 if ((WLAN_HDD_INFRA_STATION == pAdapter->device_mode) ||
Sushant Kaushik8bc7df22014-04-09 17:55:29 +05308991 (WLAN_HDD_P2P_CLIENT == pAdapter->device_mode) ||
8992 (WLAN_HDD_P2P_DEVICE == pAdapter->device_mode))
Madan Mohan Koyyalamudicfd53742013-01-11 15:29:03 -08008993 {
8994 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
8995 if ((eConnectionState_Associated == pHddStaCtx->conn_info.connState) &&
Sushant Kaushik8bc7df22014-04-09 17:55:29 +05308996 (VOS_FALSE == pHddStaCtx->conn_info.uIsAuthenticated))
Madan Mohan Koyyalamudicfd53742013-01-11 15:29:03 -08008997 {
8998 staMac = (v_U8_t *) &(pAdapter->macAddressCurrent.bytes[0]);
8999 hddLog(VOS_TRACE_LEVEL_ERROR,
Arif Hussain24bafea2013-11-15 15:10:03 -08009000 "%s: client " MAC_ADDRESS_STR
9001 " is in the middle of WPS/EAPOL exchange.", __func__,
9002 MAC_ADDR_ARRAY(staMac));
Rashmi Ramannab1429032014-04-26 14:59:09 +05309003 return VOS_TRUE;
Madan Mohan Koyyalamudicfd53742013-01-11 15:29:03 -08009004 }
9005 }
9006 else if ((WLAN_HDD_SOFTAP == pAdapter->device_mode) ||
9007 (WLAN_HDD_P2P_GO == pAdapter->device_mode))
9008 {
9009 for (staId = 0; staId < WLAN_MAX_STA_COUNT; staId++)
9010 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309011 if ((pAdapter->aStaInfo[staId].isUsed) &&
Madan Mohan Koyyalamudicfd53742013-01-11 15:29:03 -08009012 (WLANTL_STA_CONNECTED == pAdapter->aStaInfo[staId].tlSTAState))
9013 {
9014 staMac = (v_U8_t *) &(pAdapter->aStaInfo[staId].macAddrSTA.bytes[0]);
9015
9016 hddLog(VOS_TRACE_LEVEL_ERROR,
Arif Hussain24bafea2013-11-15 15:10:03 -08009017 "%s: client " MAC_ADDRESS_STR " of SoftAP/P2P-GO is in the "
9018 "middle of WPS/EAPOL exchange.", __func__,
9019 MAC_ADDR_ARRAY(staMac));
Rashmi Ramannab1429032014-04-26 14:59:09 +05309020 return VOS_TRUE;
Madan Mohan Koyyalamudicfd53742013-01-11 15:29:03 -08009021 }
9022 }
9023 }
9024 }
9025 status = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
9026 pAdapterNode = pNext;
9027 }
Rashmi Ramannab1429032014-04-26 14:59:09 +05309028 return VOS_FALSE;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309029}
Madan Mohan Koyyalamudicfd53742013-01-11 15:29:03 -08009030
9031/*
Mahesh A Saptasagarfafb7fe2014-05-16 13:19:37 +05309032 * FUNCTION: __wlan_hdd_cfg80211_scan
Jeff Johnson295189b2012-06-20 16:38:30 -07009033 * this scan respond to scan trigger and update cfg80211 scan database
9034 * later, scan dump command can be used to recieve scan results
9035 */
Mahesh A Saptasagarfafb7fe2014-05-16 13:19:37 +05309036int __wlan_hdd_cfg80211_scan( struct wiphy *wiphy,
Jeff Johnson3bbe4bf2013-01-18 17:05:29 -08009037#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,6,0))
9038 struct net_device *dev,
9039#endif
9040 struct cfg80211_scan_request *request)
9041{
Siddharth Bhal0c162d02014-05-06 19:50:42 +05309042 hdd_adapter_t *pAdapter = NULL;
9043 hdd_context_t *pHddCtx = NULL;
9044 hdd_wext_state_t *pwextBuf = NULL;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05309045 hdd_config_t *cfg_param = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -07009046 tCsrScanRequest scanRequest;
9047 tANI_U8 *channelList = NULL, i;
9048 v_U32_t scanId = 0;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05309049 int status;
9050 hdd_scaninfo_t *pScanInfo = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -07009051 v_U8_t* pP2pIe = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -07009052
Siddharth Bhal0c162d02014-05-06 19:50:42 +05309053#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,6,0))
9054 struct net_device *dev = NULL;
9055 if (NULL == request)
9056 {
9057 hddLog(VOS_TRACE_LEVEL_ERROR,
9058 "%s: scan req param null", __func__);
9059 return -EINVAL;
9060 }
9061 dev = request->wdev->netdev;
9062#endif
9063
9064 pAdapter = WLAN_HDD_GET_PRIV_PTR( dev );
9065 pHddCtx = WLAN_HDD_GET_CTX( pAdapter );
9066 pwextBuf = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
9067
Jeff Johnson295189b2012-06-20 16:38:30 -07009068 ENTER();
9069
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +05309070
Sushant Kaushik8bc7df22014-04-09 17:55:29 +05309071 hddLog(VOS_TRACE_LEVEL_INFO, "%s: device_mode = %s (%d)",
9072 __func__, hdd_device_modetoString(pAdapter->device_mode),
9073 pAdapter->device_mode);
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +05309074
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05309075 status = wlan_hdd_validate_context(pHddCtx);
9076
9077 if (0 != status)
9078 {
9079 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
9080 "%s: HDD context is not valid", __func__);
9081 return status;
9082 }
9083
Siddharth Bhal0c162d02014-05-06 19:50:42 +05309084 if (NULL == pwextBuf)
9085 {
9086 hddLog (VOS_TRACE_LEVEL_ERROR, "%s ERROR: invalid WEXT state\n",
9087 __func__);
9088 return -EIO;
9089 }
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05309090 cfg_param = pHddCtx->cfg_ini;
9091 pScanInfo = &pHddCtx->scan_info;
9092
Jeff Johnson295189b2012-06-20 16:38:30 -07009093#ifdef WLAN_BTAMP_FEATURE
9094 //Scan not supported when AMP traffic is on.
Gopichand Nakkala681989c2013-03-06 22:27:48 -08009095 if (VOS_TRUE == WLANBAP_AmpSessionOn())
Jeff Johnson295189b2012-06-20 16:38:30 -07009096 {
Madan Mohan Koyyalamudifd4e1da2012-11-09 17:50:19 -08009097 hddLog(VOS_TRACE_LEVEL_ERROR,
Jeff Johnson295189b2012-06-20 16:38:30 -07009098 "%s: No scanning when AMP is on", __func__);
9099 return -EOPNOTSUPP;
9100 }
9101#endif
9102 //Scan on any other interface is not supported.
Gopichand Nakkala681989c2013-03-06 22:27:48 -08009103 if (pAdapter->device_mode == WLAN_HDD_SOFTAP)
Jeff Johnson295189b2012-06-20 16:38:30 -07009104 {
Gopichand Nakkala681989c2013-03-06 22:27:48 -08009105 hddLog(VOS_TRACE_LEVEL_ERROR,
Sushant Kaushik8bc7df22014-04-09 17:55:29 +05309106 "%s: Not scanning on device_mode = %s (%d)",
9107 __func__, hdd_device_modetoString(pAdapter->device_mode),
9108 pAdapter->device_mode);
Jeff Johnson295189b2012-06-20 16:38:30 -07009109 return -EOPNOTSUPP;
9110 }
9111
9112 if (TRUE == pScanInfo->mScanPending)
9113 {
Kiet Lamac06e2c2013-10-23 16:25:07 +05309114 if ( MAX_PENDING_LOG > pScanInfo->mScanPendingCounter++ )
9115 {
9116 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: mScanPending is TRUE", __func__);
9117 }
Gopichand Nakkala681989c2013-03-06 22:27:48 -08009118 return -EBUSY;
Jeff Johnson295189b2012-06-20 16:38:30 -07009119 }
9120
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309121 //Don't Allow Scan and return busy if Remain On
Jeff Johnson32d95a32012-09-10 13:15:23 -07009122 //Channel and action frame is pending
9123 //Otherwise Cancel Remain On Channel and allow Scan
9124 //If no action frame pending
Gopichand Nakkala681989c2013-03-06 22:27:48 -08009125 if (0 != wlan_hdd_check_remain_on_channel(pAdapter))
Jeff Johnson32d95a32012-09-10 13:15:23 -07009126 {
Kiet Lamac06e2c2013-10-23 16:25:07 +05309127 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Remain On Channel Pending", __func__);
Jeff Johnson32d95a32012-09-10 13:15:23 -07009128 return -EBUSY;
9129 }
Gopichand Nakkala681989c2013-03-06 22:27:48 -08009130#ifdef FEATURE_WLAN_TDLS
Gopichand Nakkala638ebc72013-03-21 18:04:02 -07009131 /* if tdls disagree scan right now, return immediately.
9132 tdls will schedule the scan when scan is allowed. (return SUCCESS)
9133 or will reject the scan if any TDLS is in progress. (return -EBUSY)
9134 */
9135 status = wlan_hdd_tdls_scan_callback (pAdapter,
9136 wiphy,
9137#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,6,0))
9138 dev,
Gopichand Nakkalac3c42b92013-03-20 19:42:34 -07009139#endif
Gopichand Nakkala638ebc72013-03-21 18:04:02 -07009140 request);
9141 if(status <= 0)
9142 {
Nirav Shah20ac06f2013-12-12 18:14:06 +05309143 if(!status)
9144 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: TDLS in progress."
9145 "scan rejected %d", __func__, status);
9146 else
9147 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: TDLS teardown is ongoing %d",
9148 __func__, status);
9149
Gopichand Nakkala638ebc72013-03-21 18:04:02 -07009150 return status;
Gopichand Nakkala681989c2013-03-06 22:27:48 -08009151 }
9152#endif
Jeff Johnson32d95a32012-09-10 13:15:23 -07009153
Jeff Johnson295189b2012-06-20 16:38:30 -07009154 if (mutex_lock_interruptible(&pHddCtx->tmInfo.tmOperationLock))
9155 {
9156 VOS_TRACE(VOS_MODULE_ID_HDD,VOS_TRACE_LEVEL_ERROR,
Jeff Johnson1250df42012-12-10 14:31:52 -08009157 "%s: Acquire lock fail", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07009158 return -EAGAIN;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309159 }
Jeff Johnson295189b2012-06-20 16:38:30 -07009160 if (TRUE == pHddCtx->tmInfo.tmAction.enterImps)
9161 {
Nirav Shah20ac06f2013-12-12 18:14:06 +05309162 hddLog(VOS_TRACE_LEVEL_ERROR,
Jeff Johnson295189b2012-06-20 16:38:30 -07009163 "%s: MAX TM Level Scan not allowed", __func__);
9164 mutex_unlock(&pHddCtx->tmInfo.tmOperationLock);
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309165 return -EBUSY;
Jeff Johnson295189b2012-06-20 16:38:30 -07009166 }
9167 mutex_unlock(&pHddCtx->tmInfo.tmOperationLock);
9168
Madan Mohan Koyyalamudicfd53742013-01-11 15:29:03 -08009169 /* Check if scan is allowed at this point of time.
9170 */
Rashmi Ramannab1429032014-04-26 14:59:09 +05309171 if (hdd_isConnectionInProgress(pHddCtx))
Madan Mohan Koyyalamudicfd53742013-01-11 15:29:03 -08009172 {
9173 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Scan not allowed", __func__);
9174 return -EBUSY;
9175 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309176
Jeff Johnson295189b2012-06-20 16:38:30 -07009177 vos_mem_zero( &scanRequest, sizeof(scanRequest));
9178
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +05309179 hddLog(VOS_TRACE_LEVEL_INFO, "scan request for ssid = %d",
9180 (int)request->n_ssids);
9181
9182 /* Even though supplicant doesn't provide any SSIDs, n_ssids is set to 1.
9183 * Becasue of this, driver is assuming that this is not wildcard scan and so
9184 * is not aging out the scan results.
9185 */
9186 if (request->ssids && '\0' == request->ssids->ssid[0])
Jeff Johnson295189b2012-06-20 16:38:30 -07009187 {
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +05309188 request->n_ssids = 0;
Jeff Johnson295189b2012-06-20 16:38:30 -07009189 }
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +05309190
9191 if ((request->ssids) && (0 < request->n_ssids))
9192 {
9193 tCsrSSIDInfo *SsidInfo;
9194 int j;
9195 scanRequest.SSIDs.numOfSSIDs = request->n_ssids;
9196 /* Allocate num_ssid tCsrSSIDInfo structure */
9197 SsidInfo = scanRequest.SSIDs.SSIDList =
9198 ( tCsrSSIDInfo *)vos_mem_malloc(
9199 request->n_ssids*sizeof(tCsrSSIDInfo));
9200
9201 if(NULL == scanRequest.SSIDs.SSIDList)
9202 {
9203 hddLog(VOS_TRACE_LEVEL_ERROR,
9204 "%s: memory alloc failed SSIDInfo buffer", __func__);
9205 return -ENOMEM;
9206 }
9207
9208 /* copy all the ssid's and their length */
9209 for(j = 0; j < request->n_ssids; j++, SsidInfo++)
9210 {
9211 /* get the ssid length */
9212 SsidInfo->SSID.length = request->ssids[j].ssid_len;
9213 vos_mem_copy(SsidInfo->SSID.ssId, &request->ssids[j].ssid[0],
9214 SsidInfo->SSID.length);
9215 SsidInfo->SSID.ssId[SsidInfo->SSID.length] = '\0';
9216 hddLog(VOS_TRACE_LEVEL_INFO, "SSID number %d: %s",
9217 j, SsidInfo->SSID.ssId);
9218 }
9219 /* set the scan type to active */
9220 scanRequest.scanType = eSIR_ACTIVE_SCAN;
9221 }
9222 else if(WLAN_HDD_P2P_GO == pAdapter->device_mode)
Jeff Johnson295189b2012-06-20 16:38:30 -07009223 {
Siddharth Bhal0c162d02014-05-06 19:50:42 +05309224 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
9225 TRACE_CODE_HDD_CFG80211_SCAN,
9226 pAdapter->sessionId, 0));
Jeff Johnson295189b2012-06-20 16:38:30 -07009227 /* set the scan type to active */
9228 scanRequest.scanType = eSIR_ACTIVE_SCAN;
Jeff Johnson295189b2012-06-20 16:38:30 -07009229 }
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +05309230 else
9231 {
9232 /*Set the scan type to default type, in this case it is ACTIVE*/
9233 scanRequest.scanType = pScanInfo->scan_mode;
9234 }
9235 scanRequest.minChnTime = cfg_param->nActiveMinChnTime;
9236 scanRequest.maxChnTime = cfg_param->nActiveMaxChnTime;
Jeff Johnson295189b2012-06-20 16:38:30 -07009237
9238 /* set BSSType to default type */
9239 scanRequest.BSSType = eCSR_BSS_TYPE_ANY;
9240
9241 /*TODO: scan the requested channels only*/
9242
9243 /*Right now scanning all the channels */
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +05309244 if (MAX_CHANNEL < request->n_channels)
Jeff Johnson295189b2012-06-20 16:38:30 -07009245 {
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +05309246 hddLog(VOS_TRACE_LEVEL_WARN,
9247 "No of Scan Channels exceeded limit: %d", request->n_channels);
9248 request->n_channels = MAX_CHANNEL;
9249 }
9250
9251 hddLog(VOS_TRACE_LEVEL_INFO,
9252 "No of Scan Channels: %d", request->n_channels);
9253
9254
9255 if( request->n_channels )
9256 {
9257 char chList [(request->n_channels*5)+1];
9258 int len;
9259 channelList = vos_mem_malloc( request->n_channels );
9260 if( NULL == channelList )
c_hpothu53512302014-04-15 18:49:53 +05309261 {
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +05309262 hddLog(VOS_TRACE_LEVEL_ERROR,
9263 "%s: memory alloc failed channelList", __func__);
9264 status = -ENOMEM;
9265 goto free_mem;
c_hpothu53512302014-04-15 18:49:53 +05309266 }
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +05309267
9268 for( i = 0, len = 0; i < request->n_channels ; i++ )
9269 {
9270 channelList[i] = request->channels[i]->hw_value;
9271 len += snprintf(chList+len, 5, "%d ", channelList[i]);
9272 }
9273
Nirav Shah20ac06f2013-12-12 18:14:06 +05309274 hddLog(VOS_TRACE_LEVEL_INFO,
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +05309275 "Channel-List: %s ", chList);
9276 }
c_hpothu53512302014-04-15 18:49:53 +05309277
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +05309278 scanRequest.ChannelInfo.numOfChannels = request->n_channels;
9279 scanRequest.ChannelInfo.ChannelList = channelList;
9280
9281 /* set requestType to full scan */
9282 scanRequest.requestType = eCSR_SCAN_REQUEST_FULL_SCAN;
9283
9284 /* Flush the scan results(only p2p beacons) for STA scan and P2P
9285 * search (Flush on both full scan and social scan but not on single
9286 * channel scan).P2P search happens on 3 social channels (1, 6, 11)
9287 */
9288
9289 /* Supplicant does single channel scan after 8-way handshake
9290 * and in that case driver shoudnt flush scan results. If
9291 * driver flushes the scan results here and unfortunately if
9292 * the AP doesnt respond to our probe req then association
9293 * fails which is not desired
9294 */
9295
9296 if( request->n_channels != WLAN_HDD_P2P_SINGLE_CHANNEL_SCAN )
9297 {
9298 hddLog(VOS_TRACE_LEVEL_DEBUG, "Flushing P2P Results");
9299 sme_ScanFlushP2PResult( WLAN_HDD_GET_HAL_CTX(pAdapter),
9300 pAdapter->sessionId );
9301 }
9302
9303 if( request->ie_len )
9304 {
9305 /* save this for future association (join requires this) */
9306 /*TODO: Array needs to be converted to dynamic allocation,
9307 * as multiple ie.s can be sent in cfg80211_scan_request structure
9308 * CR 597966
9309 */
9310 memset( &pScanInfo->scanAddIE, 0, sizeof(pScanInfo->scanAddIE) );
9311 memcpy( pScanInfo->scanAddIE.addIEdata, request->ie, request->ie_len);
9312 pScanInfo->scanAddIE.length = request->ie_len;
9313
9314 if ((WLAN_HDD_INFRA_STATION == pAdapter->device_mode) ||
9315 (WLAN_HDD_P2P_CLIENT == pAdapter->device_mode) ||
9316 (WLAN_HDD_P2P_DEVICE == pAdapter->device_mode))
Jeff Johnson295189b2012-06-20 16:38:30 -07009317 {
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +05309318 if ( request->ie_len <= SIR_MAC_MAX_IE_LENGTH)
Jeff Johnson295189b2012-06-20 16:38:30 -07009319 {
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +05309320 pwextBuf->roamProfile.nAddIEScanLength = request->ie_len;
9321 memcpy( pwextBuf->roamProfile.addIEScan,
9322 request->ie, request->ie_len);
9323 }
9324 else
9325 {
9326 hddLog(VOS_TRACE_LEVEL_ERROR, "Scan Ie length is invalid:"
9327 "%zu", request->ie_len);
Jeff Johnson295189b2012-06-20 16:38:30 -07009328 }
9329
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +05309330 }
9331 scanRequest.uIEFieldLen = pScanInfo->scanAddIE.length;
9332 scanRequest.pIEField = pScanInfo->scanAddIE.addIEdata;
9333
9334 pP2pIe = wlan_hdd_get_p2p_ie_ptr((v_U8_t*)request->ie,
9335 request->ie_len);
9336 if (pP2pIe != NULL)
9337 {
9338#ifdef WLAN_FEATURE_P2P_DEBUG
9339 if (((globalP2PConnectionStatus == P2P_GO_NEG_COMPLETED) ||
9340 (globalP2PConnectionStatus == P2P_GO_NEG_PROCESS)) &&
9341 (WLAN_HDD_P2P_CLIENT == pAdapter->device_mode))
Nirav Shah20ac06f2013-12-12 18:14:06 +05309342 {
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +05309343 globalP2PConnectionStatus = P2P_CLIENT_CONNECTING_STATE_1;
9344 hddLog(VOS_TRACE_LEVEL_ERROR,"[P2P State] Changing state from "
9345 "Go nego completed to Connection is started");
9346 hddLog(VOS_TRACE_LEVEL_ERROR,"[P2P]P2P Scanning is started "
9347 "for 8way Handshake");
Nirav Shah20ac06f2013-12-12 18:14:06 +05309348 }
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +05309349 else if((globalP2PConnectionStatus == P2P_CLIENT_DISCONNECTED_STATE) &&
9350 (WLAN_HDD_P2P_CLIENT == pAdapter->device_mode))
Jeff Johnson295189b2012-06-20 16:38:30 -07009351 {
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +05309352 globalP2PConnectionStatus = P2P_CLIENT_CONNECTING_STATE_2;
9353 hddLog(VOS_TRACE_LEVEL_ERROR,"[P2P State] Changing state from "
9354 "Disconnected state to Connection is started");
9355 hddLog(VOS_TRACE_LEVEL_ERROR,"[P2P]P2P Scanning is started "
9356 "for 4way Handshake");
9357 }
9358#endif
9359
9360 /* no_cck will be set during p2p find to disable 11b rates */
9361 if(TRUE == request->no_cck)
9362 {
9363 hddLog(VOS_TRACE_LEVEL_INFO,
9364 "%s: This is a P2P Search", __func__);
9365 scanRequest.p2pSearch = 1;
9366
9367 if( request->n_channels == WLAN_HDD_P2P_SOCIAL_CHANNELS )
Agarwal Ashish4f616132013-12-30 23:32:50 +05309368 {
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +05309369 /* set requestType to P2P Discovery */
9370 scanRequest.requestType = eCSR_SCAN_P2P_DISCOVERY;
9371 }
9372
9373 /*
9374 Skip Dfs Channel in case of P2P Search
9375 if it is set in ini file
9376 */
9377 if(cfg_param->skipDfsChnlInP2pSearch)
9378 {
9379 scanRequest.skipDfsChnlInP2pSearch = 1;
Agarwal Ashish4f616132013-12-30 23:32:50 +05309380 }
9381 else
9382 {
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +05309383 scanRequest.skipDfsChnlInP2pSearch = 0;
Agarwal Ashish4f616132013-12-30 23:32:50 +05309384 }
Jeff Johnson295189b2012-06-20 16:38:30 -07009385
Agarwal Ashish4f616132013-12-30 23:32:50 +05309386 }
Jeff Johnson295189b2012-06-20 16:38:30 -07009387 }
9388 }
9389
9390 INIT_COMPLETION(pScanInfo->scan_req_completion_event);
9391
Madan Mohan Koyyalamudi9f5a10c2012-09-28 14:46:16 -07009392 /* acquire the wakelock to avoid the apps suspend during the scan. To
9393 * address the following issues.
9394 * 1) Disconnected scenario: we are not allowing the suspend as WLAN is not in
9395 * BMPS/IMPS this result in android trying to suspend aggressively and backing off
9396 * for long time, this result in apps running at full power for long time.
9397 * 2) Connected scenario: If we allow the suspend during the scan, RIVA will
9398 * be stuck in full power because of resume BMPS
9399 */
9400 hdd_prevent_suspend();
Jeff Johnsone7245742012-09-05 17:12:55 -07009401
Nirav Shah20ac06f2013-12-12 18:14:06 +05309402 hddLog(VOS_TRACE_LEVEL_INFO_HIGH,
9403 "requestType %d, scanType %d, minChnTime %d, maxChnTime %d,"
Sushant Kaushik8bc7df22014-04-09 17:55:29 +05309404 "p2pSearch %d, skipDfsChnlInP2pSearch %d",
9405 scanRequest.requestType, scanRequest.scanType,
9406 scanRequest.minChnTime, scanRequest.maxChnTime,
Nirav Shah20ac06f2013-12-12 18:14:06 +05309407 scanRequest.p2pSearch, scanRequest.skipDfsChnlInP2pSearch);
9408
Jeff Johnsone7245742012-09-05 17:12:55 -07009409 status = sme_ScanRequest( WLAN_HDD_GET_HAL_CTX(pAdapter),
Jeff Johnson295189b2012-06-20 16:38:30 -07009410 pAdapter->sessionId, &scanRequest, &scanId,
9411 &hdd_cfg80211_scan_done_callback, dev );
Jeff Johnsone7245742012-09-05 17:12:55 -07009412
Jeff Johnson295189b2012-06-20 16:38:30 -07009413 if (eHAL_STATUS_SUCCESS != status)
9414 {
9415 hddLog(VOS_TRACE_LEVEL_ERROR,
9416 "%s: sme_ScanRequest returned error %d", __func__, status);
9417 complete(&pScanInfo->scan_req_completion_event);
Madan Mohan Koyyalamudi3b230fe2012-10-18 14:46:32 -07009418 if(eHAL_STATUS_RESOURCES == status)
9419 {
Nirav Shah20ac06f2013-12-12 18:14:06 +05309420 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: HO is in progress."
9421 "So defer the scan by informing busy",__func__);
Madan Mohan Koyyalamudi3b230fe2012-10-18 14:46:32 -07009422 status = -EBUSY;
9423 } else {
9424 status = -EIO;
9425 }
Madan Mohan Koyyalamudi9f5a10c2012-09-28 14:46:16 -07009426 hdd_allow_suspend();
Jeff Johnson295189b2012-06-20 16:38:30 -07009427 goto free_mem;
9428 }
9429
9430 pScanInfo->mScanPending = TRUE;
9431 pAdapter->request = request;
9432 pScanInfo->scanId = scanId;
9433
9434 complete(&pScanInfo->scan_req_completion_event);
9435
9436free_mem:
9437 if( scanRequest.SSIDs.SSIDList )
9438 {
9439 vos_mem_free(scanRequest.SSIDs.SSIDList);
9440 }
9441
9442 if( channelList )
9443 vos_mem_free( channelList );
9444
9445 EXIT();
9446
9447 return status;
9448}
9449
Mahesh A Saptasagarfafb7fe2014-05-16 13:19:37 +05309450int wlan_hdd_cfg80211_scan( struct wiphy *wiphy,
9451#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,6,0))
9452 struct net_device *dev,
9453#endif
9454 struct cfg80211_scan_request *request)
9455{
9456 int ret;
9457
9458 vos_ssr_protect(__func__);
9459 ret = __wlan_hdd_cfg80211_scan(wiphy,
9460#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,6,0))
9461 dev,
9462#endif
9463 request);
9464 vos_ssr_unprotect(__func__);
9465
9466 return ret;
9467}
Shailender Karmuchi15cd0672013-05-15 19:50:04 -07009468
9469void hdd_select_cbmode( hdd_adapter_t *pAdapter,v_U8_t operationChannel)
9470{
9471 v_U8_t iniDot11Mode =
9472 (WLAN_HDD_GET_CTX(pAdapter))->cfg_ini->dot11Mode;
9473 eHddDot11Mode hddDot11Mode = iniDot11Mode;
9474
Arun Kumar Khandavalli94a2bb02013-12-28 19:17:25 +05309475 hddLog(LOG1, FL("Channel Bonding Mode Selected is %u"),
9476 iniDot11Mode);
Shailender Karmuchi15cd0672013-05-15 19:50:04 -07009477 switch ( iniDot11Mode )
9478 {
9479 case eHDD_DOT11_MODE_AUTO:
9480 case eHDD_DOT11_MODE_11ac:
9481 case eHDD_DOT11_MODE_11ac_ONLY:
9482#ifdef WLAN_FEATURE_11AC
9483 hddDot11Mode = eHDD_DOT11_MODE_11ac;
9484#else
9485 hddDot11Mode = eHDD_DOT11_MODE_11n;
9486#endif
9487 break;
9488 case eHDD_DOT11_MODE_11n:
9489 case eHDD_DOT11_MODE_11n_ONLY:
9490 hddDot11Mode = eHDD_DOT11_MODE_11n;
9491 break;
9492 default:
9493 hddDot11Mode = iniDot11Mode;
9494 break;
9495 }
9496 /* This call decides required channel bonding mode */
9497 sme_SelectCBMode((WLAN_HDD_GET_CTX(pAdapter)->hHal),
9498 hdd_cfg_xlate_to_csr_phy_mode(hddDot11Mode),
9499 operationChannel);
9500}
9501
Jeff Johnson295189b2012-06-20 16:38:30 -07009502/*
9503 * FUNCTION: wlan_hdd_cfg80211_connect_start
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309504 * This function is used to start the association process
Jeff Johnson295189b2012-06-20 16:38:30 -07009505 */
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309506int wlan_hdd_cfg80211_connect_start( hdd_adapter_t *pAdapter,
Jeff Johnson32d95a32012-09-10 13:15:23 -07009507 const u8 *ssid, size_t ssid_len, const u8 *bssid, u8 operatingChannel)
Jeff Johnson295189b2012-06-20 16:38:30 -07009508{
9509 int status = 0;
9510 hdd_wext_state_t *pWextState;
Yue Mae36e3552014-03-05 17:06:20 -08009511 hdd_context_t *pHddCtx;
Jeff Johnson295189b2012-06-20 16:38:30 -07009512 v_U32_t roamId;
9513 tCsrRoamProfile *pRoamProfile;
Jeff Johnson295189b2012-06-20 16:38:30 -07009514 eCsrAuthType RSNAuthType;
9515
9516 ENTER();
9517
9518 pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
Yue Mae36e3552014-03-05 17:06:20 -08009519 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
9520
9521 status = wlan_hdd_validate_context(pHddCtx);
9522 if (status)
9523 {
9524 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
9525 "%s: HDD context is not valid!", __func__);
9526 return status;
9527 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309528
Jeff Johnson295189b2012-06-20 16:38:30 -07009529 if (SIR_MAC_MAX_SSID_LENGTH < ssid_len)
9530 {
9531 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: wrong SSID len", __func__);
9532 return -EINVAL;
9533 }
9534
9535 pRoamProfile = &pWextState->roamProfile;
9536
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309537 if (pRoamProfile)
Jeff Johnson295189b2012-06-20 16:38:30 -07009538 {
Jeff Johnsone7245742012-09-05 17:12:55 -07009539 hdd_station_ctx_t *pHddStaCtx;
9540 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
Jeff Johnson295189b2012-06-20 16:38:30 -07009541
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309542 if (HDD_WMM_USER_MODE_NO_QOS ==
Jeff Johnson295189b2012-06-20 16:38:30 -07009543 (WLAN_HDD_GET_CTX(pAdapter))->cfg_ini->WmmMode)
9544 {
9545 /*QoS not enabled in cfg file*/
9546 pRoamProfile->uapsd_mask = 0;
9547 }
9548 else
9549 {
9550 /*QoS enabled, update uapsd mask from cfg file*/
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309551 pRoamProfile->uapsd_mask =
Jeff Johnson295189b2012-06-20 16:38:30 -07009552 (WLAN_HDD_GET_CTX(pAdapter))->cfg_ini->UapsdMask;
9553 }
9554
9555 pRoamProfile->SSIDs.numOfSSIDs = 1;
9556 pRoamProfile->SSIDs.SSIDList->SSID.length = ssid_len;
9557 vos_mem_zero(pRoamProfile->SSIDs.SSIDList->SSID.ssId,
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309558 sizeof(pRoamProfile->SSIDs.SSIDList->SSID.ssId));
Jeff Johnson295189b2012-06-20 16:38:30 -07009559 vos_mem_copy((void *)(pRoamProfile->SSIDs.SSIDList->SSID.ssId),
9560 ssid, ssid_len);
9561
9562 if (bssid)
9563 {
9564 pRoamProfile->BSSIDs.numOfBSSIDs = 1;
9565 vos_mem_copy((void *)(pRoamProfile->BSSIDs.bssid), bssid,
9566 WNI_CFG_BSSID_LEN);
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309567 /* Save BSSID in seperate variable as well, as RoamProfile
9568 BSSID is getting zeroed out in the association process. And in
Jeff Johnson295189b2012-06-20 16:38:30 -07009569 case of join failure we should send valid BSSID to supplicant
9570 */
9571 vos_mem_copy((void *)(pWextState->req_bssId), bssid,
9572 WNI_CFG_BSSID_LEN);
9573 }
Dhanashri Atre51981c62013-06-13 11:47:57 -07009574 else
9575 {
9576 vos_mem_zero((void *)(pRoamProfile->BSSIDs.bssid),WNI_CFG_BSSID_LEN);
9577 }
Jeff Johnson295189b2012-06-20 16:38:30 -07009578
Arun Kumar Khandavalli94a2bb02013-12-28 19:17:25 +05309579 hddLog(LOG1, FL("Connect to SSID: %s opertating Channel: %u"),
9580 pRoamProfile->SSIDs.SSIDList->SSID.ssId, operatingChannel);
Jeff Johnson295189b2012-06-20 16:38:30 -07009581 if ((IW_AUTH_WPA_VERSION_WPA == pWextState->wpaVersion) ||
9582 (IW_AUTH_WPA_VERSION_WPA2 == pWextState->wpaVersion))
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309583 {
Jeff Johnson295189b2012-06-20 16:38:30 -07009584 /*set gen ie*/
9585 hdd_SetGENIEToCsr(pAdapter, &RSNAuthType);
9586 /*set auth*/
9587 hdd_set_csr_auth_type(pAdapter, RSNAuthType);
9588 }
Jeff Johnson295189b2012-06-20 16:38:30 -07009589#ifdef FEATURE_WLAN_WAPI
9590 if (pAdapter->wapi_info.nWapiMode)
9591 {
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07009592 hddLog(LOG1, "%s: Setting WAPI AUTH Type and Encryption Mode values", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07009593 switch (pAdapter->wapi_info.wapiAuthMode)
9594 {
9595 case WAPI_AUTH_MODE_PSK:
9596 {
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07009597 hddLog(LOG1, "%s: WAPI AUTH TYPE: PSK: %d", __func__,
Jeff Johnson295189b2012-06-20 16:38:30 -07009598 pAdapter->wapi_info.wapiAuthMode);
9599 pRoamProfile->AuthType.authType[0] = eCSR_AUTH_TYPE_WAPI_WAI_PSK;
9600 break;
9601 }
9602 case WAPI_AUTH_MODE_CERT:
9603 {
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07009604 hddLog(LOG1, "%s: WAPI AUTH TYPE: CERT: %d", __func__,
Jeff Johnson295189b2012-06-20 16:38:30 -07009605 pAdapter->wapi_info.wapiAuthMode);
9606 pRoamProfile->AuthType.authType[0] = eCSR_AUTH_TYPE_WAPI_WAI_CERTIFICATE;
9607 break;
9608 }
9609 } // End of switch
9610 if ( pAdapter->wapi_info.wapiAuthMode == WAPI_AUTH_MODE_PSK ||
9611 pAdapter->wapi_info.wapiAuthMode == WAPI_AUTH_MODE_CERT)
9612 {
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07009613 hddLog(LOG1, "%s: WAPI PAIRWISE/GROUP ENCRYPTION: WPI", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07009614 pRoamProfile->AuthType.numEntries = 1;
9615 pRoamProfile->EncryptionType.numEntries = 1;
9616 pRoamProfile->EncryptionType.encryptionType[0] = eCSR_ENCRYPT_TYPE_WPI;
9617 pRoamProfile->mcEncryptionType.numEntries = 1;
9618 pRoamProfile->mcEncryptionType.encryptionType[0] = eCSR_ENCRYPT_TYPE_WPI;
9619 }
9620 }
9621#endif /* FEATURE_WLAN_WAPI */
Gopichand Nakkala870cbae2013-03-15 21:16:09 +05309622#ifdef WLAN_FEATURE_GTK_OFFLOAD
Gopichand Nakkalad36ee622013-05-07 14:13:27 +05309623 /* Initializing gtkOffloadReqParams */
Gopichand Nakkala870cbae2013-03-15 21:16:09 +05309624 if ((WLAN_HDD_INFRA_STATION == pAdapter->device_mode) ||
9625 (WLAN_HDD_P2P_CLIENT == pAdapter->device_mode))
9626 {
Gopichand Nakkalad36ee622013-05-07 14:13:27 +05309627 memset(&pHddStaCtx->gtkOffloadReqParams, 0,
9628 sizeof (tSirGtkOffloadParams));
9629 pHddStaCtx->gtkOffloadReqParams.ulFlags = GTK_OFFLOAD_DISABLE;
Gopichand Nakkala870cbae2013-03-15 21:16:09 +05309630 }
9631#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07009632 pRoamProfile->csrPersona = pAdapter->device_mode;
9633
Jeff Johnson32d95a32012-09-10 13:15:23 -07009634 if( operatingChannel )
9635 {
9636 pRoamProfile->ChannelInfo.ChannelList = &operatingChannel;
9637 pRoamProfile->ChannelInfo.numOfChannels = 1;
9638 }
Chet Lanctot186b5732013-03-18 10:26:30 -07009639 else
9640 {
9641 pRoamProfile->ChannelInfo.ChannelList = NULL;
9642 pRoamProfile->ChannelInfo.numOfChannels = 0;
9643 }
Shailender Karmuchi15cd0672013-05-15 19:50:04 -07009644 if ( (WLAN_HDD_IBSS == pAdapter->device_mode) && operatingChannel)
9645 {
9646 hdd_select_cbmode(pAdapter,operatingChannel);
9647 }
Arun Kumar Khandavalli94a2bb02013-12-28 19:17:25 +05309648
Madan Mohan Koyyalamudi42dcd162012-12-03 16:34:04 -08009649 /* change conn_state to connecting before sme_RoamConnect(), because sme_RoamConnect()
9650 * has a direct path to call hdd_smeRoamCallback(), which will change the conn_state
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309651 * If direct path, conn_state will be accordingly changed to NotConnected or Associated
Madan Mohan Koyyalamudi42dcd162012-12-03 16:34:04 -08009652 * by either hdd_AssociationCompletionHandler() or hdd_DisConnectHandler() in sme_RoamCallback()
Madan Mohan Koyyalamudidf86c422012-12-04 17:03:44 -08009653 * if sme_RomConnect is to be queued, Connecting state will remain until it is completed.
9654 */
Gopichand Nakkalaa3c8fb62013-06-21 15:36:42 +05309655 if (WLAN_HDD_INFRA_STATION == pAdapter->device_mode ||
9656 WLAN_HDD_P2P_CLIENT == pAdapter->device_mode)
Abhishek Singhf4669da2014-05-26 15:07:49 +05309657 {
9658 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
9659 "%s: Set HDD connState to eConnectionState_Connecting",
9660 __func__);
Madan Mohan Koyyalamudidf86c422012-12-04 17:03:44 -08009661 hdd_connSetConnectionState(WLAN_HDD_GET_STATION_CTX_PTR(pAdapter),
9662 eConnectionState_Connecting);
Abhishek Singhf4669da2014-05-26 15:07:49 +05309663 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309664 status = sme_RoamConnect( WLAN_HDD_GET_HAL_CTX(pAdapter),
Jeff Johnson295189b2012-06-20 16:38:30 -07009665 pAdapter->sessionId, pRoamProfile, &roamId);
9666
Gopichand Nakkalaa3c8fb62013-06-21 15:36:42 +05309667 if ((eHAL_STATUS_SUCCESS != status) &&
9668 (WLAN_HDD_INFRA_STATION == pAdapter->device_mode ||
9669 WLAN_HDD_P2P_CLIENT == pAdapter->device_mode))
Madan Mohan Koyyalamudid5acbf52012-11-28 01:45:08 +05309670
9671 {
Madan Mohan Koyyalamudi42dcd162012-12-03 16:34:04 -08009672 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: sme_RoamConnect (session %d) failed with "
9673 "status %d. -> NotConnected", __func__, pAdapter->sessionId, status);
9674 /* change back to NotAssociated */
Madan Mohan Koyyalamudid5acbf52012-11-28 01:45:08 +05309675 hdd_connSetConnectionState(WLAN_HDD_GET_STATION_CTX_PTR(pAdapter),
Madan Mohan Koyyalamudi42dcd162012-12-03 16:34:04 -08009676 eConnectionState_NotConnected);
Madan Mohan Koyyalamudid5acbf52012-11-28 01:45:08 +05309677 }
Madan Mohan Koyyalamudidf86c422012-12-04 17:03:44 -08009678
9679 pRoamProfile->ChannelInfo.ChannelList = NULL;
9680 pRoamProfile->ChannelInfo.numOfChannels = 0;
9681
Jeff Johnson295189b2012-06-20 16:38:30 -07009682 }
9683 else
9684 {
9685 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: No valid Roam profile", __func__);
9686 return -EINVAL;
9687 }
Madan Mohan Koyyalamudifd4e1da2012-11-09 17:50:19 -08009688 EXIT();
Jeff Johnson295189b2012-06-20 16:38:30 -07009689 return status;
9690}
9691
9692/*
9693 * FUNCTION: wlan_hdd_set_cfg80211_auth_type
9694 * This function is used to set the authentication type (OPEN/SHARED).
9695 *
9696 */
9697static int wlan_hdd_cfg80211_set_auth_type(hdd_adapter_t *pAdapter,
9698 enum nl80211_auth_type auth_type)
9699{
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309700 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
Jeff Johnson295189b2012-06-20 16:38:30 -07009701 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
9702
9703 ENTER();
9704
9705 /*set authentication type*/
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309706 switch (auth_type)
Jeff Johnson295189b2012-06-20 16:38:30 -07009707 {
Jeff Johnson295189b2012-06-20 16:38:30 -07009708 case NL80211_AUTHTYPE_AUTOMATIC:
Gopichand Nakkala29149562013-05-10 21:43:41 +05309709 hddLog(VOS_TRACE_LEVEL_INFO,
9710 "%s: set authentication type to AUTOSWITCH", __func__);
9711 pHddStaCtx->conn_info.authType = eCSR_AUTH_TYPE_AUTOSWITCH;
9712 break;
9713
9714 case NL80211_AUTHTYPE_OPEN_SYSTEM:
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -07009715#ifdef WLAN_FEATURE_VOWIFI_11R
9716 case NL80211_AUTHTYPE_FT:
9717#endif /* WLAN_FEATURE_VOWIFI_11R */
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309718 hddLog(VOS_TRACE_LEVEL_INFO,
Jeff Johnson295189b2012-06-20 16:38:30 -07009719 "%s: set authentication type to OPEN", __func__);
9720 pHddStaCtx->conn_info.authType = eCSR_AUTH_TYPE_OPEN_SYSTEM;
9721 break;
9722
9723 case NL80211_AUTHTYPE_SHARED_KEY:
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309724 hddLog(VOS_TRACE_LEVEL_INFO,
Jeff Johnson295189b2012-06-20 16:38:30 -07009725 "%s: set authentication type to SHARED", __func__);
9726 pHddStaCtx->conn_info.authType = eCSR_AUTH_TYPE_SHARED_KEY;
9727 break;
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08009728#ifdef FEATURE_WLAN_ESE
Jeff Johnson295189b2012-06-20 16:38:30 -07009729 case NL80211_AUTHTYPE_NETWORK_EAP:
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309730 hddLog(VOS_TRACE_LEVEL_INFO,
Jeff Johnson295189b2012-06-20 16:38:30 -07009731 "%s: set authentication type to CCKM WPA", __func__);
9732 pHddStaCtx->conn_info.authType = eCSR_AUTH_TYPE_CCKM_WPA;//eCSR_AUTH_TYPE_CCKM_RSN needs to be handled as well if required.
9733 break;
9734#endif
9735
9736
9737 default:
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309738 hddLog(VOS_TRACE_LEVEL_ERROR,
9739 "%s: Unsupported authentication type %d", __func__,
Jeff Johnson295189b2012-06-20 16:38:30 -07009740 auth_type);
9741 pHddStaCtx->conn_info.authType = eCSR_AUTH_TYPE_UNKNOWN;
9742 return -EINVAL;
9743 }
9744
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309745 pWextState->roamProfile.AuthType.authType[0] =
Jeff Johnson295189b2012-06-20 16:38:30 -07009746 pHddStaCtx->conn_info.authType;
9747 return 0;
9748}
9749
9750/*
9751 * FUNCTION: wlan_hdd_set_akm_suite
9752 * This function is used to set the key mgmt type(PSK/8021x).
9753 *
9754 */
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309755static int wlan_hdd_set_akm_suite( hdd_adapter_t *pAdapter,
Jeff Johnson295189b2012-06-20 16:38:30 -07009756 u32 key_mgmt
9757 )
9758{
9759 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
9760 ENTER();
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309761
Jeff Johnson295189b2012-06-20 16:38:30 -07009762 /*set key mgmt type*/
9763 switch(key_mgmt)
9764 {
9765 case WLAN_AKM_SUITE_PSK:
Gopichand Nakkala356fb102013-03-06 12:34:04 +05309766#ifdef WLAN_FEATURE_VOWIFI_11R
9767 case WLAN_AKM_SUITE_FT_PSK:
9768#endif
9769 hddLog(VOS_TRACE_LEVEL_INFO, "%s: setting key mgmt type to PSK",
Jeff Johnson295189b2012-06-20 16:38:30 -07009770 __func__);
9771 pWextState->authKeyMgmt |= IW_AUTH_KEY_MGMT_PSK;
9772 break;
9773
9774 case WLAN_AKM_SUITE_8021X:
Gopichand Nakkala356fb102013-03-06 12:34:04 +05309775#ifdef WLAN_FEATURE_VOWIFI_11R
9776 case WLAN_AKM_SUITE_FT_8021X:
9777#endif
9778 hddLog(VOS_TRACE_LEVEL_INFO, "%s: setting key mgmt type to 8021x",
Jeff Johnson295189b2012-06-20 16:38:30 -07009779 __func__);
9780 pWextState->authKeyMgmt |= IW_AUTH_KEY_MGMT_802_1X;
9781 break;
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08009782#ifdef FEATURE_WLAN_ESE
Jeff Johnson295189b2012-06-20 16:38:30 -07009783#define WLAN_AKM_SUITE_CCKM 0x00409600 /* Should be in ieee802_11_defs.h */
9784#define IW_AUTH_KEY_MGMT_CCKM 8 /* Should be in linux/wireless.h */
9785 case WLAN_AKM_SUITE_CCKM:
9786 hddLog(VOS_TRACE_LEVEL_INFO, "%s: setting key mgmt type to CCKM",
9787 __func__);
9788 pWextState->authKeyMgmt |= IW_AUTH_KEY_MGMT_CCKM;
9789 break;
9790#endif
Leela Venkata Kiran Kumar Reddy Chiralae208a832014-04-27 22:34:25 -07009791#ifndef WLAN_AKM_SUITE_OSEN
9792#define WLAN_AKM_SUITE_OSEN 0x506f9a01 /* Should be in ieee802_11_defs.h */
9793 case WLAN_AKM_SUITE_OSEN:
9794 hddLog(VOS_TRACE_LEVEL_INFO, "%s: setting key mgmt type to OSEN",
9795 __func__);
9796 pWextState->authKeyMgmt |= IW_AUTH_KEY_MGMT_802_1X;
9797 break;
9798#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07009799
9800 default:
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309801 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Unsupported key mgmt type %d",
Jeff Johnson295189b2012-06-20 16:38:30 -07009802 __func__, key_mgmt);
9803 return -EINVAL;
9804
9805 }
9806 return 0;
9807}
9808
9809/*
9810 * FUNCTION: wlan_hdd_cfg80211_set_cipher
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309811 * This function is used to set the encryption type
Jeff Johnson295189b2012-06-20 16:38:30 -07009812 * (NONE/WEP40/WEP104/TKIP/CCMP).
9813 */
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309814static int wlan_hdd_cfg80211_set_cipher( hdd_adapter_t *pAdapter,
9815 u32 cipher,
Jeff Johnson295189b2012-06-20 16:38:30 -07009816 bool ucast
9817 )
9818{
9819 eCsrEncryptionType encryptionType = eCSR_ENCRYPT_TYPE_NONE;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309820 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
Jeff Johnson295189b2012-06-20 16:38:30 -07009821 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
9822
9823 ENTER();
9824
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309825 if (!cipher)
Jeff Johnson295189b2012-06-20 16:38:30 -07009826 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309827 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: received cipher %d - considering none",
Jeff Johnson295189b2012-06-20 16:38:30 -07009828 __func__, cipher);
9829 encryptionType = eCSR_ENCRYPT_TYPE_NONE;
9830 }
9831 else
9832 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309833
Jeff Johnson295189b2012-06-20 16:38:30 -07009834 /*set encryption method*/
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309835 switch (cipher)
Jeff Johnson295189b2012-06-20 16:38:30 -07009836 {
9837 case IW_AUTH_CIPHER_NONE:
9838 encryptionType = eCSR_ENCRYPT_TYPE_NONE;
9839 break;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309840
Jeff Johnson295189b2012-06-20 16:38:30 -07009841 case WLAN_CIPHER_SUITE_WEP40:
Gopichand Nakkala29149562013-05-10 21:43:41 +05309842 encryptionType = eCSR_ENCRYPT_TYPE_WEP40;
Jeff Johnson295189b2012-06-20 16:38:30 -07009843 break;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309844
Jeff Johnson295189b2012-06-20 16:38:30 -07009845 case WLAN_CIPHER_SUITE_WEP104:
Gopichand Nakkala29149562013-05-10 21:43:41 +05309846 encryptionType = eCSR_ENCRYPT_TYPE_WEP104;
Jeff Johnson295189b2012-06-20 16:38:30 -07009847 break;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309848
Jeff Johnson295189b2012-06-20 16:38:30 -07009849 case WLAN_CIPHER_SUITE_TKIP:
9850 encryptionType = eCSR_ENCRYPT_TYPE_TKIP;
9851 break;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309852
Jeff Johnson295189b2012-06-20 16:38:30 -07009853 case WLAN_CIPHER_SUITE_CCMP:
9854 encryptionType = eCSR_ENCRYPT_TYPE_AES;
9855 break;
9856#ifdef FEATURE_WLAN_WAPI
9857 case WLAN_CIPHER_SUITE_SMS4:
9858 encryptionType = eCSR_ENCRYPT_TYPE_WPI;
9859 break;
9860#endif
9861
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08009862#ifdef FEATURE_WLAN_ESE
Jeff Johnson295189b2012-06-20 16:38:30 -07009863 case WLAN_CIPHER_SUITE_KRK:
9864 encryptionType = eCSR_ENCRYPT_TYPE_KRK;
9865 break;
9866#endif
9867 default:
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309868 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Unsupported cipher type %d",
Jeff Johnson295189b2012-06-20 16:38:30 -07009869 __func__, cipher);
9870 return -EOPNOTSUPP;
9871 }
9872 }
9873
9874 if (ucast)
9875 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309876 hddLog(VOS_TRACE_LEVEL_INFO, "%s: setting unicast cipher type to %d",
Jeff Johnson295189b2012-06-20 16:38:30 -07009877 __func__, encryptionType);
9878 pHddStaCtx->conn_info.ucEncryptionType = encryptionType;
9879 pWextState->roamProfile.EncryptionType.numEntries = 1;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309880 pWextState->roamProfile.EncryptionType.encryptionType[0] =
Jeff Johnson295189b2012-06-20 16:38:30 -07009881 encryptionType;
9882 }
9883 else
9884 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309885 hddLog(VOS_TRACE_LEVEL_INFO, "%s: setting mcast cipher type to %d",
Jeff Johnson295189b2012-06-20 16:38:30 -07009886 __func__, encryptionType);
9887 pHddStaCtx->conn_info.mcEncryptionType = encryptionType;
9888 pWextState->roamProfile.mcEncryptionType.numEntries = 1;
9889 pWextState->roamProfile.mcEncryptionType.encryptionType[0] = encryptionType;
9890 }
9891
9892 return 0;
9893}
9894
9895
9896/*
9897 * FUNCTION: wlan_hdd_cfg80211_set_ie
9898 * This function is used to parse WPA/RSN IE's.
9899 */
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309900int wlan_hdd_cfg80211_set_ie( hdd_adapter_t *pAdapter,
9901 u8 *ie,
Jeff Johnson295189b2012-06-20 16:38:30 -07009902 size_t ie_len
9903 )
9904{
9905 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
9906 u8 *genie = ie;
9907 v_U16_t remLen = ie_len;
9908#ifdef FEATURE_WLAN_WAPI
9909 v_U32_t akmsuite[MAX_NUM_AKM_SUITES];
9910 u16 *tmp;
9911 v_U16_t akmsuiteCount;
9912 int *akmlist;
9913#endif
9914 ENTER();
9915
9916 /* clear previous assocAddIE */
9917 pWextState->assocAddIE.length = 0;
9918 pWextState->roamProfile.bWPSAssociation = VOS_FALSE;
Leela Venkata Kiran Kumar Reddy Chiralaf257bef2014-04-11 18:48:12 -07009919 pWextState->roamProfile.bOSENAssociation = VOS_FALSE;
Jeff Johnson295189b2012-06-20 16:38:30 -07009920
9921 while (remLen >= 2)
9922 {
9923 v_U16_t eLen = 0;
9924 v_U8_t elementId;
9925 elementId = *genie++;
9926 eLen = *genie++;
9927 remLen -= 2;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309928
Arif Hussain6d2a3322013-11-17 19:50:10 -08009929 hddLog(VOS_TRACE_LEVEL_INFO, "%s: IE[0x%X], LEN[%d]",
Jeff Johnson295189b2012-06-20 16:38:30 -07009930 __func__, elementId, eLen);
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309931
9932 switch ( elementId )
Jeff Johnson295189b2012-06-20 16:38:30 -07009933 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309934 case DOT11F_EID_WPA:
Madan Mohan Koyyalamudief3b66e2012-10-11 14:29:42 -07009935 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 -07009936 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309937 hddLog(VOS_TRACE_LEVEL_ERROR,
Jeff Johnson295189b2012-06-20 16:38:30 -07009938 "%s: Invalid WPA IE", __func__);
9939 return -EINVAL;
9940 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309941 else if (0 == memcmp(&genie[0], "\x00\x50\xf2\x04", 4))
Jeff Johnson295189b2012-06-20 16:38:30 -07009942 {
9943 v_U16_t curAddIELen = pWextState->assocAddIE.length;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309944 hddLog (VOS_TRACE_LEVEL_INFO, "%s Set WPS IE(len %d)",
Jeff Johnson295189b2012-06-20 16:38:30 -07009945 __func__, eLen + 2);
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309946
Jeff Johnson295189b2012-06-20 16:38:30 -07009947 if( SIR_MAC_MAX_IE_LENGTH < (pWextState->assocAddIE.length + eLen) )
9948 {
Jeff Johnson902c9832012-12-10 14:28:09 -08009949 hddLog(VOS_TRACE_LEVEL_FATAL, "Cannot accommodate assocAddIE. "
9950 "Need bigger buffer space");
Jeff Johnson295189b2012-06-20 16:38:30 -07009951 VOS_ASSERT(0);
9952 return -ENOMEM;
9953 }
9954 // WSC IE is saved to Additional IE ; it should be accumulated to handle WPS IE + P2P IE
9955 memcpy( pWextState->assocAddIE.addIEdata + curAddIELen, genie - 2, eLen + 2);
9956 pWextState->assocAddIE.length += eLen + 2;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309957
Jeff Johnson295189b2012-06-20 16:38:30 -07009958 pWextState->roamProfile.bWPSAssociation = VOS_TRUE;
9959 pWextState->roamProfile.pAddIEAssoc = pWextState->assocAddIE.addIEdata;
9960 pWextState->roamProfile.nAddIEAssocLength = pWextState->assocAddIE.length;
9961 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309962 else if (0 == memcmp(&genie[0], "\x00\x50\xf2", 3))
9963 {
Jeff Johnson295189b2012-06-20 16:38:30 -07009964 hddLog (VOS_TRACE_LEVEL_INFO, "%s Set WPA IE (len %d)",__func__, eLen + 2);
9965 memset( pWextState->WPARSNIE, 0, MAX_WPA_RSN_IE_LEN );
9966 memcpy( pWextState->WPARSNIE, genie - 2, (eLen + 2) /*ie_len*/);
9967 pWextState->roamProfile.pWPAReqIE = pWextState->WPARSNIE;
9968 pWextState->roamProfile.nWPAReqIELength = eLen + 2;//ie_len;
9969 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309970 else if ( (0 == memcmp(&genie[0], P2P_OUI_TYPE,
Kiet Lam8da98992013-11-21 15:59:07 +05309971 P2P_OUI_TYPE_SIZE)))
Jeff Johnson295189b2012-06-20 16:38:30 -07009972 {
9973 v_U16_t curAddIELen = pWextState->assocAddIE.length;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309974 hddLog (VOS_TRACE_LEVEL_INFO, "%s Set P2P IE(len %d)",
Jeff Johnson295189b2012-06-20 16:38:30 -07009975 __func__, eLen + 2);
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309976
Jeff Johnson295189b2012-06-20 16:38:30 -07009977 if( SIR_MAC_MAX_IE_LENGTH < (pWextState->assocAddIE.length + eLen) )
9978 {
Jeff Johnson902c9832012-12-10 14:28:09 -08009979 hddLog(VOS_TRACE_LEVEL_FATAL, "Cannot accommodate assocAddIE "
9980 "Need bigger buffer space");
Jeff Johnson295189b2012-06-20 16:38:30 -07009981 VOS_ASSERT(0);
9982 return -ENOMEM;
9983 }
9984 // P2P IE is saved to Additional IE ; it should be accumulated to handle WPS IE + P2P IE
9985 memcpy( pWextState->assocAddIE.addIEdata + curAddIELen, genie - 2, eLen + 2);
9986 pWextState->assocAddIE.length += eLen + 2;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309987
Jeff Johnson295189b2012-06-20 16:38:30 -07009988 pWextState->roamProfile.pAddIEAssoc = pWextState->assocAddIE.addIEdata;
9989 pWextState->roamProfile.nAddIEAssocLength = pWextState->assocAddIE.length;
9990 }
Jeff Johnson295189b2012-06-20 16:38:30 -07009991#ifdef WLAN_FEATURE_WFD
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309992 else if ( (0 == memcmp(&genie[0], WFD_OUI_TYPE,
9993 WFD_OUI_TYPE_SIZE))
Jeff Johnson295189b2012-06-20 16:38:30 -07009994 /*Consider WFD IE, only for P2P Client */
9995 && (WLAN_HDD_P2P_CLIENT == pAdapter->device_mode) )
9996 {
9997 v_U16_t curAddIELen = pWextState->assocAddIE.length;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309998 hddLog (VOS_TRACE_LEVEL_INFO, "%s Set WFD IE(len %d)",
Jeff Johnson295189b2012-06-20 16:38:30 -07009999 __func__, eLen + 2);
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010000
Jeff Johnson295189b2012-06-20 16:38:30 -070010001 if( SIR_MAC_MAX_IE_LENGTH < (pWextState->assocAddIE.length + eLen) )
10002 {
Jeff Johnson902c9832012-12-10 14:28:09 -080010003 hddLog(VOS_TRACE_LEVEL_FATAL, "Cannot accommodate assocAddIE "
10004 "Need bigger buffer space");
Jeff Johnson295189b2012-06-20 16:38:30 -070010005 VOS_ASSERT(0);
10006 return -ENOMEM;
10007 }
10008 // WFD IE is saved to Additional IE ; it should be accumulated to handle
10009 // WPS IE + P2P IE + WFD IE
10010 memcpy( pWextState->assocAddIE.addIEdata + curAddIELen, genie - 2, eLen + 2);
10011 pWextState->assocAddIE.length += eLen + 2;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010012
Jeff Johnson295189b2012-06-20 16:38:30 -070010013 pWextState->roamProfile.pAddIEAssoc = pWextState->assocAddIE.addIEdata;
10014 pWextState->roamProfile.nAddIEAssocLength = pWextState->assocAddIE.length;
10015 }
10016#endif
Madan Mohan Koyyalamudief3b66e2012-10-11 14:29:42 -070010017 /* Appending HS 2.0 Indication Element in Assiciation Request */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010018 else if ( (0 == memcmp(&genie[0], HS20_OUI_TYPE,
Madan Mohan Koyyalamudi1bed5982012-10-22 14:38:06 -070010019 HS20_OUI_TYPE_SIZE)) )
10020 {
10021 v_U16_t curAddIELen = pWextState->assocAddIE.length;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010022 hddLog (VOS_TRACE_LEVEL_INFO, "%s Set HS20 IE(len %d)",
Madan Mohan Koyyalamudi1bed5982012-10-22 14:38:06 -070010023 __func__, eLen + 2);
Madan Mohan Koyyalamudief3b66e2012-10-11 14:29:42 -070010024
Madan Mohan Koyyalamudi1bed5982012-10-22 14:38:06 -070010025 if( SIR_MAC_MAX_IE_LENGTH < (pWextState->assocAddIE.length + eLen) )
10026 {
Jeff Johnson902c9832012-12-10 14:28:09 -080010027 hddLog(VOS_TRACE_LEVEL_FATAL, "Cannot accommodate assocAddIE "
10028 "Need bigger buffer space");
Madan Mohan Koyyalamudi1bed5982012-10-22 14:38:06 -070010029 VOS_ASSERT(0);
10030 return -ENOMEM;
10031 }
10032 memcpy( pWextState->assocAddIE.addIEdata + curAddIELen, genie - 2, eLen + 2);
10033 pWextState->assocAddIE.length += eLen + 2;
Madan Mohan Koyyalamudief3b66e2012-10-11 14:29:42 -070010034
Madan Mohan Koyyalamudi1bed5982012-10-22 14:38:06 -070010035 pWextState->roamProfile.pAddIEAssoc = pWextState->assocAddIE.addIEdata;
10036 pWextState->roamProfile.nAddIEAssocLength = pWextState->assocAddIE.length;
10037 }
Leela Venkata Kiran Kumar Reddy Chiralaf257bef2014-04-11 18:48:12 -070010038 /* Appending OSEN Information Element in Assiciation Request */
10039 else if ( (0 == memcmp(&genie[0], OSEN_OUI_TYPE,
10040 OSEN_OUI_TYPE_SIZE)) )
10041 {
10042 v_U16_t curAddIELen = pWextState->assocAddIE.length;
10043 hddLog (VOS_TRACE_LEVEL_INFO, "%s Set OSEN IE(len %d)",
10044 __func__, eLen + 2);
Madan Mohan Koyyalamudief3b66e2012-10-11 14:29:42 -070010045
Leela Venkata Kiran Kumar Reddy Chiralaf257bef2014-04-11 18:48:12 -070010046 if( SIR_MAC_MAX_IE_LENGTH < (pWextState->assocAddIE.length + eLen) )
10047 {
10048 hddLog(VOS_TRACE_LEVEL_FATAL, "Cannot accommodate assocAddIE "
10049 "Need bigger buffer space");
10050 VOS_ASSERT(0);
10051 return -ENOMEM;
10052 }
10053 memcpy( pWextState->assocAddIE.addIEdata + curAddIELen, genie - 2, eLen + 2);
10054 pWextState->assocAddIE.length += eLen + 2;
10055
10056 pWextState->roamProfile.bOSENAssociation = VOS_TRUE;
10057 pWextState->roamProfile.pAddIEAssoc = pWextState->assocAddIE.addIEdata;
10058 pWextState->roamProfile.nAddIEAssocLength = pWextState->assocAddIE.length;
10059 }
10060
10061 break;
Praveen Kumar Sirisilla7d68b7b2013-09-22 14:01:42 -070010062 if (WLAN_HDD_IBSS == pAdapter->device_mode) {
10063
10064 /* populating as ADDIE in beacon frames */
10065 if (ccmCfgSetStr(WLAN_HDD_GET_HAL_CTX(pAdapter),
10066 WNI_CFG_PROBE_RSP_BCN_ADDNIE_DATA, genie - 2, eLen + 2,
10067 NULL, eANI_BOOLEAN_FALSE)== eHAL_STATUS_SUCCESS)
10068 {
10069 if (ccmCfgSetInt(WLAN_HDD_GET_HAL_CTX(pAdapter),
10070 WNI_CFG_PROBE_RSP_BCN_ADDNIE_FLAG, 1,NULL,
10071 eANI_BOOLEAN_FALSE) == eHAL_STATUS_FAILURE)
10072 {
10073 hddLog(LOGE,
10074 "Coldn't pass "
10075 "WNI_CFG_PROBE_RSP_BCN_ADDNIE_FLAG to CCM");
10076 }
10077 }/* ccmCfgSetStr(,WNI_CFG_PROBE_RSP_BCN_ADDNIE_DATA, , )*/
10078 else
10079 hddLog(LOGE,
10080 "Could not pass on "
10081 "WNI_CFG_PROBE_RSP_BCN_ADDNIE_DATA to CCM");
10082
10083 /* IBSS mode doesn't contain params->proberesp_ies still
10084 beaconIE's need to be populated in probe response frames */
10085 if ( (NULL != (genie - 2)) && (0 != eLen + 2) )
10086 {
10087 u16 rem_probe_resp_ie_len = eLen + 2;
10088 u8 probe_rsp_ie_len[3] = {0};
10089 u8 counter = 0;
10090
10091 /* Check Probe Resp Length if it is greater then 255 then
10092 Store Probe Rsp IEs into WNI_CFG_PROBE_RSP_ADDNIE_DATA1
10093 & WNI_CFG_PROBE_RSP_ADDNIE_DATA2 CFG Variable As We are
10094 not able Store More then 255 bytes into One Variable */
10095
10096 while ((rem_probe_resp_ie_len > 0) && (counter < 3))
10097 {
10098 if (rem_probe_resp_ie_len > MAX_CFG_STRING_LEN)
10099 {
10100 probe_rsp_ie_len[counter++] = MAX_CFG_STRING_LEN;
10101 rem_probe_resp_ie_len -= MAX_CFG_STRING_LEN;
10102 }
10103 else
10104 {
10105 probe_rsp_ie_len[counter++] = rem_probe_resp_ie_len;
10106 rem_probe_resp_ie_len = 0;
10107 }
10108 }
10109
10110 rem_probe_resp_ie_len = 0;
10111
10112 if (probe_rsp_ie_len[0] > 0)
10113 {
10114 if (ccmCfgSetStr(WLAN_HDD_GET_HAL_CTX(pAdapter),
10115 WNI_CFG_PROBE_RSP_ADDNIE_DATA1,
10116 (tANI_U8*)(genie - 2),
10117 probe_rsp_ie_len[0], NULL,
10118 eANI_BOOLEAN_FALSE)
10119 == eHAL_STATUS_FAILURE)
10120 {
10121 hddLog(LOGE,
10122 "Could not pass"
10123 "on WNI_CFG_PROBE_RSP_ADDNIE_DATA1 to CCM");
10124 }
10125 rem_probe_resp_ie_len += probe_rsp_ie_len[0];
10126 }
10127
10128 if (probe_rsp_ie_len[1] > 0)
10129 {
10130 if (ccmCfgSetStr(WLAN_HDD_GET_HAL_CTX(pAdapter),
10131 WNI_CFG_PROBE_RSP_ADDNIE_DATA2,
10132 (tANI_U8*)(genie - (2 + rem_probe_resp_ie_len)),
10133 probe_rsp_ie_len[1], NULL,
10134 eANI_BOOLEAN_FALSE)
10135 == eHAL_STATUS_FAILURE)
10136 {
10137 hddLog(LOGE,
10138 "Could not pass"
10139 "on WNI_CFG_PROBE_RSP_ADDNIE_DATA2 to CCM");
10140 }
10141 rem_probe_resp_ie_len += probe_rsp_ie_len[1];
10142 }
10143
10144 if (probe_rsp_ie_len[2] > 0)
10145 {
10146 if (ccmCfgSetStr(WLAN_HDD_GET_HAL_CTX(pAdapter),
10147 WNI_CFG_PROBE_RSP_ADDNIE_DATA3,
10148 (tANI_U8*)(genie - (2 + rem_probe_resp_ie_len)),
10149 probe_rsp_ie_len[2], NULL,
10150 eANI_BOOLEAN_FALSE)
10151 == eHAL_STATUS_FAILURE)
10152 {
10153 hddLog(LOGE,
10154 "Could not pass"
10155 "on WNI_CFG_PROBE_RSP_ADDNIE_DATA3 to CCM");
10156 }
10157 rem_probe_resp_ie_len += probe_rsp_ie_len[2];
10158 }
10159
10160 if (ccmCfgSetInt(WLAN_HDD_GET_HAL_CTX(pAdapter),
10161 WNI_CFG_PROBE_RSP_ADDNIE_FLAG, 1,NULL,
10162 eANI_BOOLEAN_FALSE) == eHAL_STATUS_FAILURE)
10163 {
10164 hddLog(LOGE,
10165 "Could not pass"
10166 "on WNI_CFG_PROBE_RSP_ADDNIE_FLAG to CCM");
10167 }
10168 }
10169 else
10170 {
10171 // Reset WNI_CFG_PROBE_RSP Flags
10172 wlan_hdd_reset_prob_rspies(pAdapter);
10173
10174 hddLog(VOS_TRACE_LEVEL_INFO,
10175 "%s: No Probe Response IE received in set beacon",
10176 __func__);
10177 }
10178 } /* end of if (WLAN_HDD_IBSS == pAdapter->device_mode) */
Jeff Johnson295189b2012-06-20 16:38:30 -070010179 break;
10180 case DOT11F_EID_RSN:
10181 hddLog (VOS_TRACE_LEVEL_INFO, "%s Set RSN IE(len %d)",__func__, eLen + 2);
10182 memset( pWextState->WPARSNIE, 0, MAX_WPA_RSN_IE_LEN );
10183 memcpy( pWextState->WPARSNIE, genie - 2, (eLen + 2)/*ie_len*/);
10184 pWextState->roamProfile.pRSNReqIE = pWextState->WPARSNIE;
10185 pWextState->roamProfile.nRSNReqIELength = eLen + 2; //ie_len;
10186 break;
Madan Mohan Koyyalamudief3b66e2012-10-11 14:29:42 -070010187 /* Appending Extended Capabilities with Interworking bit set in Assoc Req */
10188 case DOT11F_EID_EXTCAP:
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010189 {
Madan Mohan Koyyalamudief3b66e2012-10-11 14:29:42 -070010190 v_U16_t curAddIELen = pWextState->assocAddIE.length;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010191 hddLog (VOS_TRACE_LEVEL_INFO, "%s Set Extended CAPS IE(len %d)",
Madan Mohan Koyyalamudief3b66e2012-10-11 14:29:42 -070010192 __func__, eLen + 2);
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010193
Madan Mohan Koyyalamudief3b66e2012-10-11 14:29:42 -070010194 if( SIR_MAC_MAX_IE_LENGTH < (pWextState->assocAddIE.length + eLen) )
10195 {
Jeff Johnson902c9832012-12-10 14:28:09 -080010196 hddLog(VOS_TRACE_LEVEL_FATAL, "Cannot accommodate assocAddIE "
10197 "Need bigger buffer space");
Madan Mohan Koyyalamudief3b66e2012-10-11 14:29:42 -070010198 VOS_ASSERT(0);
10199 return -ENOMEM;
10200 }
10201 memcpy( pWextState->assocAddIE.addIEdata + curAddIELen, genie - 2, eLen + 2);
10202 pWextState->assocAddIE.length += eLen + 2;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010203
Madan Mohan Koyyalamudief3b66e2012-10-11 14:29:42 -070010204 pWextState->roamProfile.pAddIEAssoc = pWextState->assocAddIE.addIEdata;
10205 pWextState->roamProfile.nAddIEAssocLength = pWextState->assocAddIE.length;
10206 break;
10207 }
Jeff Johnson295189b2012-06-20 16:38:30 -070010208#ifdef FEATURE_WLAN_WAPI
10209 case WLAN_EID_WAPI:
10210 pAdapter->wapi_info.nWapiMode = 1; //Setting WAPI Mode to ON=1
Jeff Johnson0299d0a2013-10-30 12:37:43 -070010211 hddLog(VOS_TRACE_LEVEL_INFO, "WAPI MODE IS %u",
Jeff Johnson295189b2012-06-20 16:38:30 -070010212 pAdapter->wapi_info.nWapiMode);
10213 tmp = (u16 *)ie;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010214 tmp = tmp + 2; // Skip element Id and Len, Version
Jeff Johnson295189b2012-06-20 16:38:30 -070010215 akmsuiteCount = WPA_GET_LE16(tmp);
10216 tmp = tmp + 1;
10217 akmlist = (int *)(tmp);
10218 if(akmsuiteCount <= MAX_NUM_AKM_SUITES)
10219 {
10220 memcpy(akmsuite, akmlist, (4*akmsuiteCount));
10221 }
10222 else
10223 {
Arif Hussain6d2a3322013-11-17 19:50:10 -080010224 hddLog(VOS_TRACE_LEVEL_FATAL, "Invalid akmSuite count");
Jeff Johnson295189b2012-06-20 16:38:30 -070010225 VOS_ASSERT(0);
10226 return -EINVAL;
10227 }
10228
10229 if (WAPI_PSK_AKM_SUITE == akmsuite[0])
10230 {
10231 hddLog(VOS_TRACE_LEVEL_INFO, "%s: WAPI AUTH MODE SET TO PSK",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -070010232 __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -070010233 pAdapter->wapi_info.wapiAuthMode = WAPI_AUTH_MODE_PSK;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010234 }
Jeff Johnson295189b2012-06-20 16:38:30 -070010235 if (WAPI_CERT_AKM_SUITE == akmsuite[0])
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010236 {
Jeff Johnson295189b2012-06-20 16:38:30 -070010237 hddLog(VOS_TRACE_LEVEL_INFO, "%s: WAPI AUTH MODE SET TO CERTIFICATE",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -070010238 __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -070010239 pAdapter->wapi_info.wapiAuthMode = WAPI_AUTH_MODE_CERT;
10240 }
10241 break;
10242#endif
10243 default:
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010244 hddLog (VOS_TRACE_LEVEL_ERROR,
Jeff Johnson295189b2012-06-20 16:38:30 -070010245 "%s Set UNKNOWN IE %X", __func__, elementId);
Madan Mohan Koyyalamudief3b66e2012-10-11 14:29:42 -070010246 /* when Unknown IE is received we should break and continue
10247 * to the next IE in the buffer instead we were returning
10248 * so changing this to break */
10249 break;
Jeff Johnson295189b2012-06-20 16:38:30 -070010250 }
10251 genie += eLen;
10252 remLen -= eLen;
10253 }
10254 EXIT();
10255 return 0;
10256}
10257
10258/*
Gopichand Nakkala18f0c262013-05-07 23:25:08 +053010259 * FUNCTION: hdd_isWPAIEPresent
10260 * Parse the received IE to find the WPA IE
10261 *
10262 */
10263static bool hdd_isWPAIEPresent(u8 *ie, u8 ie_len)
10264{
10265 v_U8_t eLen = 0;
10266 v_U16_t remLen = ie_len;
10267 v_U8_t elementId = 0;
10268
10269 while (remLen >= 2)
10270 {
10271 elementId = *ie++;
10272 eLen = *ie++;
10273 remLen -= 2;
10274 if (eLen > remLen)
10275 {
10276 hddLog(VOS_TRACE_LEVEL_ERROR,
10277 "%s: IE length is wrong %d", __func__, eLen);
10278 return FALSE;
10279 }
10280 if ((elementId == DOT11F_EID_WPA) && (remLen > 5))
10281 {
10282 /* OUI - 0x00 0X50 0XF2
10283 WPA Information Element - 0x01
10284 WPA version - 0x01*/
10285 if (0 == memcmp(&ie[0], "\x00\x50\xf2\x01\x01", 5))
10286 return TRUE;
10287 }
10288 ie += eLen;
10289 remLen -= eLen;
10290 }
10291 return FALSE;
10292}
10293
10294/*
Jeff Johnson295189b2012-06-20 16:38:30 -070010295 * FUNCTION: wlan_hdd_cfg80211_set_privacy
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010296 * This function is used to initialize the security
Jeff Johnson295189b2012-06-20 16:38:30 -070010297 * parameters during connect operation.
10298 */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010299int wlan_hdd_cfg80211_set_privacy( hdd_adapter_t *pAdapter,
Jeff Johnson295189b2012-06-20 16:38:30 -070010300 struct cfg80211_connect_params *req
10301 )
10302{
10303 int status = 0;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010304 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
Jeff Johnson295189b2012-06-20 16:38:30 -070010305 ENTER();
10306
10307 /*set wpa version*/
10308 pWextState->wpaVersion = IW_AUTH_WPA_VERSION_DISABLED;
10309
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010310 if (req->crypto.wpa_versions)
Jeff Johnson295189b2012-06-20 16:38:30 -070010311 {
Gopichand Nakkala781ded42013-06-28 12:10:45 +053010312 if (NL80211_WPA_VERSION_1 == req->crypto.wpa_versions)
Jeff Johnson295189b2012-06-20 16:38:30 -070010313 {
10314 pWextState->wpaVersion = IW_AUTH_WPA_VERSION_WPA;
10315 }
10316 else if (NL80211_WPA_VERSION_2 == req->crypto.wpa_versions)
10317 {
10318 pWextState->wpaVersion = IW_AUTH_WPA_VERSION_WPA2;
10319 }
10320 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010321
10322 hddLog(VOS_TRACE_LEVEL_INFO, "%s: set wpa version to %d", __func__,
Jeff Johnson295189b2012-06-20 16:38:30 -070010323 pWextState->wpaVersion);
10324
10325 /*set authentication type*/
10326 status = wlan_hdd_cfg80211_set_auth_type(pAdapter, req->auth_type);
10327
10328 if (0 > status)
10329 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010330 hddLog(VOS_TRACE_LEVEL_ERROR,
Jeff Johnson295189b2012-06-20 16:38:30 -070010331 "%s: failed to set authentication type ", __func__);
10332 return status;
10333 }
10334
10335 /*set key mgmt type*/
10336 if (req->crypto.n_akm_suites)
10337 {
10338 status = wlan_hdd_set_akm_suite(pAdapter, req->crypto.akm_suites[0]);
10339 if (0 > status)
10340 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010341 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: failed to set akm suite",
Jeff Johnson295189b2012-06-20 16:38:30 -070010342 __func__);
10343 return status;
10344 }
10345 }
10346
10347 /*set pairwise cipher type*/
10348 if (req->crypto.n_ciphers_pairwise)
10349 {
10350 status = wlan_hdd_cfg80211_set_cipher(pAdapter,
10351 req->crypto.ciphers_pairwise[0], true);
10352 if (0 > status)
10353 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010354 hddLog(VOS_TRACE_LEVEL_ERROR,
Jeff Johnson295189b2012-06-20 16:38:30 -070010355 "%s: failed to set unicast cipher type", __func__);
10356 return status;
10357 }
10358 }
10359 else
10360 {
10361 /*Reset previous cipher suite to none*/
10362 status = wlan_hdd_cfg80211_set_cipher(pAdapter, 0, true);
10363 if (0 > status)
10364 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010365 hddLog(VOS_TRACE_LEVEL_ERROR,
Jeff Johnson295189b2012-06-20 16:38:30 -070010366 "%s: failed to set unicast cipher type", __func__);
10367 return status;
10368 }
10369 }
10370
10371 /*set group cipher type*/
10372 status = wlan_hdd_cfg80211_set_cipher(pAdapter, req->crypto.cipher_group,
10373 false);
10374
10375 if (0 > status)
10376 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010377 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: failed to set mcast cipher type",
Jeff Johnson295189b2012-06-20 16:38:30 -070010378 __func__);
10379 return status;
10380 }
10381
Chet Lanctot186b5732013-03-18 10:26:30 -070010382#ifdef WLAN_FEATURE_11W
10383 pWextState->roamProfile.MFPEnabled = (req->mfp == NL80211_MFP_REQUIRED);
10384#endif
10385
Jeff Johnson295189b2012-06-20 16:38:30 -070010386 /*parse WPA/RSN IE, and set the correspoing fileds in Roam profile*/
10387 if (req->ie_len)
10388 {
10389 status = wlan_hdd_cfg80211_set_ie(pAdapter, req->ie, req->ie_len);
10390 if ( 0 > status)
10391 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010392 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: failed to parse the WPA/RSN IE",
Jeff Johnson295189b2012-06-20 16:38:30 -070010393 __func__);
10394 return status;
10395 }
10396 }
10397
10398 /*incase of WEP set default key information*/
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010399 if (req->key && req->key_len)
Jeff Johnson295189b2012-06-20 16:38:30 -070010400 {
10401 if ( (WLAN_CIPHER_SUITE_WEP40 == req->crypto.ciphers_pairwise[0])
10402 || (WLAN_CIPHER_SUITE_WEP104 == req->crypto.ciphers_pairwise[0])
10403 )
10404 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010405 if ( IW_AUTH_KEY_MGMT_802_1X
Jeff Johnson295189b2012-06-20 16:38:30 -070010406 == (pWextState->authKeyMgmt & IW_AUTH_KEY_MGMT_802_1X ))
10407 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010408 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Dynamic WEP not supported",
Jeff Johnson295189b2012-06-20 16:38:30 -070010409 __func__);
10410 return -EOPNOTSUPP;
10411 }
10412 else
10413 {
10414 u8 key_len = req->key_len;
10415 u8 key_idx = req->key_idx;
10416
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010417 if ((eCSR_SECURITY_WEP_KEYSIZE_MAX_BYTES >= key_len)
Jeff Johnson295189b2012-06-20 16:38:30 -070010418 && (CSR_MAX_NUM_KEY > key_idx)
10419 )
10420 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010421 hddLog(VOS_TRACE_LEVEL_INFO,
10422 "%s: setting default wep key, key_idx = %hu key_len %hu",
Jeff Johnson295189b2012-06-20 16:38:30 -070010423 __func__, key_idx, key_len);
10424 vos_mem_copy(
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010425 &pWextState->roamProfile.Keys.KeyMaterial[key_idx][0],
Jeff Johnson295189b2012-06-20 16:38:30 -070010426 req->key, key_len);
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010427 pWextState->roamProfile.Keys.KeyLength[key_idx] =
Jeff Johnson295189b2012-06-20 16:38:30 -070010428 (u8)key_len;
10429 pWextState->roamProfile.Keys.defaultIndex = (u8)key_idx;
10430 }
10431 }
10432 }
10433 }
10434
10435 return status;
10436}
10437
10438/*
Vinay Krishna Eranna21042322014-01-08 19:21:39 +053010439 * FUNCTION: wlan_hdd_try_disconnect
10440 * This function is used to disconnect from previous
10441 * connection
10442 */
10443static int wlan_hdd_try_disconnect( hdd_adapter_t *pAdapter )
10444{
10445 long ret = 0;
10446 hdd_station_ctx_t *pHddStaCtx;
10447 eMib_dot11DesiredBssType connectedBssType;
10448
10449 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
10450
10451 hdd_connGetConnectedBssType(pHddStaCtx,&connectedBssType );
10452
10453 if((eMib_dot11DesiredBssType_independent == connectedBssType) ||
10454 (eConnectionState_Associated == pHddStaCtx->conn_info.connState) ||
10455 (eConnectionState_IbssConnected == pHddStaCtx->conn_info.connState))
10456 {
10457 /* Issue disconnect to CSR */
10458 INIT_COMPLETION(pAdapter->disconnect_comp_var);
10459 if( eHAL_STATUS_SUCCESS ==
10460 sme_RoamDisconnect( WLAN_HDD_GET_HAL_CTX(pAdapter),
10461 pAdapter->sessionId,
10462 eCSR_DISCONNECT_REASON_UNSPECIFIED ) )
10463 {
10464 ret = wait_for_completion_interruptible_timeout(
10465 &pAdapter->disconnect_comp_var,
10466 msecs_to_jiffies(WLAN_WAIT_TIME_DISCONNECT));
10467 if (0 >= ret)
10468 {
10469 hddLog(LOGE, FL("Failed to receive disconnect event"));
10470 return -EALREADY;
10471 }
10472 }
10473 }
10474 else if(eConnectionState_Disconnecting == pHddStaCtx->conn_info.connState)
10475 {
10476 ret = wait_for_completion_interruptible_timeout(
10477 &pAdapter->disconnect_comp_var,
10478 msecs_to_jiffies(WLAN_WAIT_TIME_DISCONNECT));
10479 if (0 >= ret)
10480 {
10481 hddLog(LOGE, FL("Failed to receive disconnect event"));
10482 return -EALREADY;
10483 }
10484 }
10485
10486 return 0;
10487}
10488
10489/*
Agarwal Ashish51325b52014-06-16 16:50:49 +053010490 * FUNCTION: __wlan_hdd_cfg80211_connect
10491 * This function is used to start the association process
Jeff Johnson295189b2012-06-20 16:38:30 -070010492 */
Mahesh A Saptasagarfafb7fe2014-05-16 13:19:37 +053010493static int __wlan_hdd_cfg80211_connect( struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -070010494 struct net_device *ndev,
10495 struct cfg80211_connect_params *req
10496 )
10497{
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053010498 int status;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010499 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( ndev );
Sushant Kaushikba6764e2014-06-30 19:52:09 +053010500 hdd_adapter_t *pHostapdAdapter = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -070010501 VOS_STATUS exitbmpsStatus = VOS_STATUS_E_INVAL;
Sushant Kaushikba6764e2014-06-30 19:52:09 +053010502 hdd_context_t *pHddCtx = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -070010503
10504 ENTER();
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053010505
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053010506 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
10507 TRACE_CODE_HDD_CFG80211_CONNECT,
10508 pAdapter->sessionId, pAdapter->device_mode));
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010509 hddLog(VOS_TRACE_LEVEL_INFO,
Sushant Kaushik8bc7df22014-04-09 17:55:29 +053010510 "%s: device_mode = %s (%d)", __func__,
10511 hdd_device_modetoString(pAdapter->device_mode),
10512 pAdapter->device_mode);
Jeff Johnson295189b2012-06-20 16:38:30 -070010513
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053010514 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Rajesh Chauhana0516c62014-01-30 16:11:18 -080010515 if (!pHddCtx)
10516 {
10517 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
10518 "%s: HDD context is null", __func__);
Agarwal Ashish51325b52014-06-16 16:50:49 +053010519 return -EINVAL;
Rajesh Chauhana0516c62014-01-30 16:11:18 -080010520 }
10521
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053010522 status = wlan_hdd_validate_context(pHddCtx);
10523
10524 if (0 != status)
Jeff Johnson295189b2012-06-20 16:38:30 -070010525 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053010526 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
10527 "%s: HDD context is not valid", __func__);
10528 return status;
Jeff Johnson295189b2012-06-20 16:38:30 -070010529 }
10530
Agarwal Ashish51325b52014-06-16 16:50:49 +053010531 if (vos_max_concurrent_connections_reached()) {
10532 hddLog(VOS_TRACE_LEVEL_INFO, FL("Reached max concurrent connections"));
10533 return -ECONNREFUSED;
10534 }
10535
Jeff Johnson295189b2012-06-20 16:38:30 -070010536#ifdef WLAN_BTAMP_FEATURE
10537 //Infra connect not supported when AMP traffic is on.
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010538 if( VOS_TRUE == WLANBAP_AmpSessionOn() )
Jeff Johnson295189b2012-06-20 16:38:30 -070010539 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010540 hddLog(VOS_TRACE_LEVEL_ERROR,
Jeff Johnson295189b2012-06-20 16:38:30 -070010541 "%s: No connection when AMP is on", __func__);
Madan Mohan Koyyalamudicae253a2012-11-06 19:10:35 -080010542 return -ECONNREFUSED;
Jeff Johnson295189b2012-06-20 16:38:30 -070010543 }
10544#endif
Vinay Krishna Eranna21042322014-01-08 19:21:39 +053010545
10546 //If Device Mode is Station Concurrent Sessions Exit BMps
10547 //P2P Mode will be taken care in Open/close adapter
10548 if((WLAN_HDD_INFRA_STATION == pAdapter->device_mode) &&
Agarwal Ashish51325b52014-06-16 16:50:49 +053010549 (vos_concurrent_open_sessions_running())) {
10550 exitbmpsStatus = hdd_disable_bmps_imps(pHddCtx,
10551 WLAN_HDD_INFRA_STATION);
Vinay Krishna Eranna21042322014-01-08 19:21:39 +053010552 }
10553
10554 /*Try disconnecting if already in connected state*/
10555 status = wlan_hdd_try_disconnect(pAdapter);
10556 if ( 0 > status)
10557 {
10558 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Failed to disconnect the existing"
10559 " connection"));
10560 return -EALREADY;
10561 }
10562
Jeff Johnson295189b2012-06-20 16:38:30 -070010563 /*initialise security parameters*/
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010564 status = wlan_hdd_cfg80211_set_privacy(pAdapter, req);
Jeff Johnson295189b2012-06-20 16:38:30 -070010565
10566 if ( 0 > status)
10567 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010568 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: failed to set security params",
Jeff Johnson295189b2012-06-20 16:38:30 -070010569 __func__);
10570 return status;
10571 }
Sushant Kaushikba6764e2014-06-30 19:52:09 +053010572 /* For SAP + STA concurrency , driver only supports SCC.
10573 * if SAP is ON, driver will stop it and after assoc completion,
10574 * or failure, SAP will be started on STA channel to force SCC.
10575 */
10576 pHostapdAdapter = hdd_get_adapter(pHddCtx, WLAN_HDD_SOFTAP);
10577 if (pHostapdAdapter != NULL)
10578 {
10579 hddLog(VOS_TRACE_LEVEL_INFO, "Close SAP until STA is connected");
10580 if (test_bit(SOFTAP_BSS_STARTED, &pHostapdAdapter->event_flags))
10581 {
10582 WLANSAP_StopBss((WLAN_HDD_GET_CTX(pHostapdAdapter))->pvosContext);
10583 clear_bit(SOFTAP_BSS_STARTED, &pHostapdAdapter->event_flags);
10584 }
10585 }
Mohit Khanna765234a2012-09-11 15:08:35 -070010586 if ( req->channel )
10587 {
10588 status = wlan_hdd_cfg80211_connect_start(pAdapter, req->ssid,
10589 req->ssid_len, req->bssid,
10590 req->channel->hw_value);
10591 }
10592 else
10593 {
10594 status = wlan_hdd_cfg80211_connect_start(pAdapter, req->ssid,
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053010595 req->ssid_len, req->bssid, 0);
Mohit Khanna765234a2012-09-11 15:08:35 -070010596 }
Jeff Johnson295189b2012-06-20 16:38:30 -070010597
10598 if (0 > status)
10599 {
10600 //ReEnable BMPS if disabled
10601 if((VOS_STATUS_SUCCESS == exitbmpsStatus) &&
10602 (NULL != pHddCtx))
10603 {
Gopichand Nakkalaa2fe5b02013-06-06 16:32:28 +053010604 if (pHddCtx->hdd_wlan_suspended)
10605 {
10606 hdd_set_pwrparams(pHddCtx);
10607 }
Jeff Johnson295189b2012-06-20 16:38:30 -070010608 //ReEnable Bmps and Imps back
10609 hdd_enable_bmps_imps(pHddCtx);
10610 }
Agarwal Ashish51325b52014-06-16 16:50:49 +053010611 hddLog(VOS_TRACE_LEVEL_ERROR, FL("connect failed"));
Jeff Johnson295189b2012-06-20 16:38:30 -070010612 return status;
10613 }
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053010614 pHddCtx->isAmpAllowed = VOS_FALSE;
Jeff Johnson295189b2012-06-20 16:38:30 -070010615 EXIT();
10616 return status;
10617}
10618
Mahesh A Saptasagarfafb7fe2014-05-16 13:19:37 +053010619static int wlan_hdd_cfg80211_connect( struct wiphy *wiphy,
10620 struct net_device *ndev,
10621 struct cfg80211_connect_params *req)
10622{
10623 int ret;
10624 vos_ssr_protect(__func__);
10625 ret = __wlan_hdd_cfg80211_connect(wiphy, ndev, req);
10626 vos_ssr_unprotect(__func__);
10627
10628 return ret;
10629}
Jeff Johnson295189b2012-06-20 16:38:30 -070010630
10631/*
Gopichand Nakkala78a6c812013-05-13 16:39:49 +053010632 * FUNCTION: wlan_hdd_disconnect
10633 * This function is used to issue a disconnect request to SME
10634 */
10635int wlan_hdd_disconnect( hdd_adapter_t *pAdapter, u16 reason )
10636{
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053010637 int status;
Gopichand Nakkala78a6c812013-05-13 16:39:49 +053010638 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053010639 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Abhishek Singhdc2bfd42014-06-19 17:59:05 +053010640 long ret;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053010641
10642 status = wlan_hdd_validate_context(pHddCtx);
10643
10644 if (0 != status)
10645 {
10646 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
10647 "%s: HDD context is not valid", __func__);
10648 return status;
10649 }
10650
10651 pHddCtx->isAmpAllowed = VOS_TRUE;
Agarwal Ashishc65b5ca2014-07-28 21:02:57 +053010652
10653 if (eConnectionState_Associated == pHddStaCtx->conn_info.connState)
10654 {
10655 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
10656 "%s: Set HDD connState to eConnectionState_Disconnecting",
10657 __func__);
10658 wlan_hdd_decr_active_session(pHddCtx, pAdapter->device_mode);
10659 }
10660
Abhishek Singhf4669da2014-05-26 15:07:49 +053010661 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
10662 "%s: Set HDD connState to eConnectionState_Disconnecting",
10663 __func__);
Vinay Krishna Erannab09d3e72014-03-26 21:23:55 +053010664 pHddStaCtx->conn_info.connState = eConnectionState_Disconnecting;
Gopichand Nakkala78a6c812013-05-13 16:39:49 +053010665 INIT_COMPLETION(pAdapter->disconnect_comp_var);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053010666
Gopichand Nakkala78a6c812013-05-13 16:39:49 +053010667 /*issue disconnect*/
Arun Kumar Khandavalli94a2bb02013-12-28 19:17:25 +053010668
Gopichand Nakkala78a6c812013-05-13 16:39:49 +053010669 status = sme_RoamDisconnect( WLAN_HDD_GET_HAL_CTX(pAdapter),
10670 pAdapter->sessionId, reason);
Abhishek Singhdc2bfd42014-06-19 17:59:05 +053010671 if(eHAL_STATUS_CMD_NOT_QUEUED == status)
10672 {
10673 hddLog(VOS_TRACE_LEVEL_INFO,
10674 FL("status = %d, already disconnected"),
10675 (int)status );
Gopichand Nakkala78a6c812013-05-13 16:39:49 +053010676
Abhishek Singhdc2bfd42014-06-19 17:59:05 +053010677 }
10678 else if ( 0 != status )
Gopichand Nakkala78a6c812013-05-13 16:39:49 +053010679 {
10680 hddLog(VOS_TRACE_LEVEL_ERROR,
Arif Hussain6d2a3322013-11-17 19:50:10 -080010681 "%s csrRoamDisconnect failure, returned %d",
Gopichand Nakkala78a6c812013-05-13 16:39:49 +053010682 __func__, (int)status );
10683 return -EINVAL;
10684 }
Abhishek Singhdc2bfd42014-06-19 17:59:05 +053010685 ret = wait_for_completion_interruptible_timeout(
Gopichand Nakkala78a6c812013-05-13 16:39:49 +053010686 &pAdapter->disconnect_comp_var,
10687 msecs_to_jiffies(WLAN_WAIT_TIME_DISCONNECT));
Abhishek Singhdc2bfd42014-06-19 17:59:05 +053010688 if (!ret && ( eHAL_STATUS_CMD_NOT_QUEUED != status ))
c_hpothu6ff1c3c2013-10-01 19:01:57 +053010689 {
10690 hddLog(VOS_TRACE_LEVEL_ERROR,
Mahesh A Saptasagar05a357e2014-02-26 16:28:06 +053010691 "%s: Failed to disconnect, timed out", __func__);
10692 return -ETIMEDOUT;
10693 }
Abhishek Singhdc2bfd42014-06-19 17:59:05 +053010694 else if (ret == -ERESTARTSYS)
Mahesh A Saptasagar05a357e2014-02-26 16:28:06 +053010695 {
10696 hddLog(VOS_TRACE_LEVEL_ERROR,
10697 "%s: Failed to disconnect, wait interrupted", __func__);
Abhishek Singhdc2bfd42014-06-19 17:59:05 +053010698 return ret;
c_hpothu6ff1c3c2013-10-01 19:01:57 +053010699 }
Abhishek Singhdc2bfd42014-06-19 17:59:05 +053010700 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
10701 FL("Set HDD connState to eConnectionState_NotConnected"));
10702 pHddStaCtx->conn_info.connState = eConnectionState_NotConnected;
10703
Gopichand Nakkala78a6c812013-05-13 16:39:49 +053010704 /*stop tx queues*/
10705 netif_tx_disable(pAdapter->dev);
10706 netif_carrier_off(pAdapter->dev);
Mahesh A Saptasagar05a357e2014-02-26 16:28:06 +053010707 return 0;
Gopichand Nakkala78a6c812013-05-13 16:39:49 +053010708}
10709
10710
10711/*
Mahesh A Saptasagarfafb7fe2014-05-16 13:19:37 +053010712 * FUNCTION: __wlan_hdd_cfg80211_disconnect
Jeff Johnson295189b2012-06-20 16:38:30 -070010713 * This function is used to issue a disconnect request to SME
10714 */
Mahesh A Saptasagarfafb7fe2014-05-16 13:19:37 +053010715static int __wlan_hdd_cfg80211_disconnect( struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -070010716 struct net_device *dev,
10717 u16 reason
10718 )
10719{
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010720 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( dev );
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053010721 tCsrRoamProfile *pRoamProfile =
10722 &(WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter))->roamProfile;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053010723 int status;
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053010724 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
10725 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Gopichand Nakkalaaa353782013-05-17 20:36:22 +053010726#ifdef FEATURE_WLAN_TDLS
Gopichand Nakkala2a0a1572013-02-10 21:39:16 -080010727 tANI_U8 staIdx;
10728#endif
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010729
Jeff Johnson295189b2012-06-20 16:38:30 -070010730 ENTER();
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053010731
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053010732 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
10733 TRACE_CODE_HDD_CFG80211_DISCONNECT,
10734 pAdapter->sessionId, reason));
Sushant Kaushik8bc7df22014-04-09 17:55:29 +053010735 hddLog(VOS_TRACE_LEVEL_INFO, "%s: device_mode = %s(%d)",
10736 __func__, hdd_device_modetoString(pAdapter->device_mode),
10737 pAdapter->device_mode);
Jeff Johnson295189b2012-06-20 16:38:30 -070010738
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010739 hddLog(VOS_TRACE_LEVEL_INFO, "%s: Disconnect called with reason code %d",
10740 __func__, reason);
Jeff Johnson295189b2012-06-20 16:38:30 -070010741
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053010742 status = wlan_hdd_validate_context(pHddCtx);
10743
10744 if (0 != status)
Jeff Johnson295189b2012-06-20 16:38:30 -070010745 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053010746 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
10747 "%s: HDD context is not valid", __func__);
10748 return status;
Jeff Johnson295189b2012-06-20 16:38:30 -070010749 }
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053010750
Jeff Johnson295189b2012-06-20 16:38:30 -070010751 if (NULL != pRoamProfile)
10752 {
10753 /*issue disconnect request to SME, if station is in connected state*/
Mahesh A Saptasagar280fd5a2013-12-05 15:38:31 +053010754 if ((pHddStaCtx->conn_info.connState == eConnectionState_Associated) ||
10755 (pHddStaCtx->conn_info.connState == eConnectionState_Connecting))
Jeff Johnson295189b2012-06-20 16:38:30 -070010756 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010757 eCsrRoamDisconnectReason reasonCode =
Jeff Johnson295189b2012-06-20 16:38:30 -070010758 eCSR_DISCONNECT_REASON_UNSPECIFIED;
Gopichand Nakkalaaa353782013-05-17 20:36:22 +053010759 hdd_scaninfo_t *pScanInfo;
Jeff Johnson295189b2012-06-20 16:38:30 -070010760 switch(reason)
10761 {
10762 case WLAN_REASON_MIC_FAILURE:
10763 reasonCode = eCSR_DISCONNECT_REASON_MIC_ERROR;
10764 break;
10765
10766 case WLAN_REASON_DISASSOC_DUE_TO_INACTIVITY:
10767 case WLAN_REASON_DISASSOC_AP_BUSY:
10768 case WLAN_REASON_CLASS3_FRAME_FROM_NONASSOC_STA:
10769 reasonCode = eCSR_DISCONNECT_REASON_DISASSOC;
10770 break;
10771
10772 case WLAN_REASON_PREV_AUTH_NOT_VALID:
10773 case WLAN_REASON_CLASS2_FRAME_FROM_NONAUTH_STA:
Abhishek Singhc3269a52014-05-21 17:22:24 +053010774 case WLAN_REASON_DEAUTH_LEAVING:
Jeff Johnson295189b2012-06-20 16:38:30 -070010775 reasonCode = eCSR_DISCONNECT_REASON_DEAUTH;
10776 break;
10777
Jeff Johnson295189b2012-06-20 16:38:30 -070010778 default:
10779 reasonCode = eCSR_DISCONNECT_REASON_UNSPECIFIED;
10780 break;
10781 }
Gopichand Nakkalaaa353782013-05-17 20:36:22 +053010782 pScanInfo = &pHddCtx->scan_info;
10783 if (pScanInfo->mScanPending)
10784 {
Srinivas, Dasari138af4f2014-02-07 11:13:45 +053010785 hddLog(VOS_TRACE_LEVEL_INFO, "Disconnect is in progress, "
Gopichand Nakkalaaa353782013-05-17 20:36:22 +053010786 "Aborting Scan");
Srinivas, Dasari138af4f2014-02-07 11:13:45 +053010787 hdd_abort_mac_scan(pHddCtx, pAdapter->sessionId,
10788 eCSR_SCAN_ABORT_DEFAULT);
Gopichand Nakkalaaa353782013-05-17 20:36:22 +053010789 }
Jeff Johnson295189b2012-06-20 16:38:30 -070010790
Gopichand Nakkala2a0a1572013-02-10 21:39:16 -080010791#ifdef FEATURE_WLAN_TDLS
10792 /* First clean up the tdls peers if any */
Gopichand Nakkala4327a152013-03-04 23:22:42 -080010793 for (staIdx = 0 ; staIdx < HDD_MAX_NUM_TDLS_STA; staIdx++)
Gopichand Nakkala2a0a1572013-02-10 21:39:16 -080010794 {
Gopichand Nakkala4327a152013-03-04 23:22:42 -080010795 if ((pHddCtx->tdlsConnInfo[staIdx].sessionId == pAdapter->sessionId) &&
10796 (pHddCtx->tdlsConnInfo[staIdx].staId))
Gopichand Nakkala2a0a1572013-02-10 21:39:16 -080010797 {
Hoonki Lee11f7dda2013-02-14 16:55:44 -080010798 uint8 *mac;
Gopichand Nakkala4327a152013-03-04 23:22:42 -080010799 mac = pHddCtx->tdlsConnInfo[staIdx].peerMac.bytes;
Hoonki Lee11f7dda2013-02-14 16:55:44 -080010800 VOS_TRACE(VOS_MODULE_ID_HDD, TDLS_LOG_LEVEL,
Gopichand Nakkalac87400e2013-03-13 18:51:00 -070010801 "%s: call sme_DeleteTdlsPeerSta staId %d sessionId %d " MAC_ADDRESS_STR,
Gopichand Nakkala4327a152013-03-04 23:22:42 -080010802 __func__, pHddCtx->tdlsConnInfo[staIdx].staId, pAdapter->sessionId,
Gopichand Nakkalac87400e2013-03-13 18:51:00 -070010803 MAC_ADDR_ARRAY(mac));
Gopichand Nakkala2a0a1572013-02-10 21:39:16 -080010804 sme_DeleteTdlsPeerSta(WLAN_HDD_GET_HAL_CTX(pAdapter),
Gopichand Nakkala4327a152013-03-04 23:22:42 -080010805 pAdapter->sessionId,
10806 mac);
Gopichand Nakkala2a0a1572013-02-10 21:39:16 -080010807 }
10808 }
10809#endif
Arun Kumar Khandavalli94a2bb02013-12-28 19:17:25 +053010810 hddLog(LOG1, FL("Disconnecting with reasoncode:%u"), reasonCode);
Gopichand Nakkala78a6c812013-05-13 16:39:49 +053010811 status = wlan_hdd_disconnect(pAdapter, reasonCode);
10812 if ( 0 != status )
Jeff Johnson295189b2012-06-20 16:38:30 -070010813 {
10814 hddLog(VOS_TRACE_LEVEL_ERROR,
Arif Hussain6d2a3322013-11-17 19:50:10 -080010815 "%s wlan_hdd_disconnect failure, returned %d",
Jeff Johnson295189b2012-06-20 16:38:30 -070010816 __func__, (int)status );
10817 return -EINVAL;
10818 }
Jeff Johnson295189b2012-06-20 16:38:30 -070010819 }
Mahesh A Saptasagar280fd5a2013-12-05 15:38:31 +053010820 else
10821 {
10822 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: unexpected cfg disconnect API"
10823 "called while in %d state", __func__,
10824 pHddStaCtx->conn_info.connState);
10825 }
Jeff Johnson295189b2012-06-20 16:38:30 -070010826 }
10827 else
10828 {
10829 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: No valid roam profile", __func__);
10830 }
10831
10832 return status;
10833}
10834
Mahesh A Saptasagarfafb7fe2014-05-16 13:19:37 +053010835static int wlan_hdd_cfg80211_disconnect( struct wiphy *wiphy,
10836 struct net_device *dev,
10837 u16 reason
10838 )
10839{
10840 int ret;
10841 vos_ssr_protect(__func__);
10842 ret = __wlan_hdd_cfg80211_disconnect(wiphy, dev, reason);
10843 vos_ssr_unprotect(__func__);
10844
10845 return ret;
10846}
Gopichand Nakkala78a6c812013-05-13 16:39:49 +053010847
Jeff Johnson295189b2012-06-20 16:38:30 -070010848/*
10849 * FUNCTION: wlan_hdd_cfg80211_set_privacy_ibss
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010850 * This function is used to initialize the security
Jeff Johnson295189b2012-06-20 16:38:30 -070010851 * settings in IBSS mode.
10852 */
10853static int wlan_hdd_cfg80211_set_privacy_ibss(
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010854 hdd_adapter_t *pAdapter,
Jeff Johnson295189b2012-06-20 16:38:30 -070010855 struct cfg80211_ibss_params *params
10856 )
10857{
10858 int status = 0;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010859 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
Jeff Johnson295189b2012-06-20 16:38:30 -070010860 eCsrEncryptionType encryptionType = eCSR_ENCRYPT_TYPE_NONE;
10861 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010862
Jeff Johnson295189b2012-06-20 16:38:30 -070010863 ENTER();
10864
10865 pWextState->wpaVersion = IW_AUTH_WPA_VERSION_DISABLED;
Ravi Joshib58ca0d2013-10-29 09:50:23 -070010866 vos_mem_zero(&pHddStaCtx->ibss_enc_key, sizeof(tCsrRoamSetKey));
Jeff Johnson295189b2012-06-20 16:38:30 -070010867
10868 if (params->ie_len && ( NULL != params->ie) )
10869 {
Shailender Karmuchi67edd312013-06-18 16:30:48 -070010870 if (wlan_hdd_cfg80211_get_ie_ptr (params->ie,
10871 params->ie_len, WLAN_EID_RSN ))
Jeff Johnson295189b2012-06-20 16:38:30 -070010872 {
10873 pWextState->wpaVersion = IW_AUTH_WPA_VERSION_WPA2;
10874 encryptionType = eCSR_ENCRYPT_TYPE_AES;
10875 }
Shailender Karmuchi67edd312013-06-18 16:30:48 -070010876 else if ( hdd_isWPAIEPresent (params->ie, params->ie_len ))
Jeff Johnson295189b2012-06-20 16:38:30 -070010877 {
Shailender Karmuchi642e9812013-05-30 14:34:49 -070010878 tDot11fIEWPA dot11WPAIE;
10879 tHalHandle halHandle = WLAN_HDD_GET_HAL_CTX(pAdapter);
Shailender Karmuchi67edd312013-06-18 16:30:48 -070010880 u8 *ie;
Shailender Karmuchi642e9812013-05-30 14:34:49 -070010881
Wilson Yang00256342013-10-10 23:13:38 -070010882 memset(&dot11WPAIE, 0, sizeof(dot11WPAIE));
Shailender Karmuchi67edd312013-06-18 16:30:48 -070010883 ie = wlan_hdd_cfg80211_get_ie_ptr (params->ie,
10884 params->ie_len, DOT11F_EID_WPA);
10885 if ( NULL != ie )
10886 {
10887 pWextState->wpaVersion = IW_AUTH_WPA_VERSION_WPA;
10888 // Unpack the WPA IE
10889 //Skip past the EID byte and length byte - and four byte WiFi OUI
10890 dot11fUnpackIeWPA((tpAniSirGlobal) halHandle,
10891 &ie[2+4],
10892 ie[1] - 4,
10893 &dot11WPAIE);
10894 /*Extract the multicast cipher, the encType for unicast
10895 cipher for wpa-none is none*/
10896 encryptionType =
10897 hdd_TranslateWPAToCsrEncryptionType(dot11WPAIE.multicast_cipher);
10898 }
Jeff Johnson295189b2012-06-20 16:38:30 -070010899 }
Shailender Karmuchi67edd312013-06-18 16:30:48 -070010900
Jeff Johnson295189b2012-06-20 16:38:30 -070010901 status = wlan_hdd_cfg80211_set_ie(pAdapter, params->ie, params->ie_len);
10902
10903 if (0 > status)
10904 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010905 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: failed to parse WPA/RSN IE",
Jeff Johnson295189b2012-06-20 16:38:30 -070010906 __func__);
10907 return status;
10908 }
10909 }
10910
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010911 pWextState->roamProfile.AuthType.authType[0] =
10912 pHddStaCtx->conn_info.authType =
Jeff Johnson295189b2012-06-20 16:38:30 -070010913 eCSR_AUTH_TYPE_OPEN_SYSTEM;
10914
10915 if (params->privacy)
10916 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010917 /* Security enabled IBSS, At this time there is no information available
10918 * about the security paramters, so initialise the encryption type to
Jeff Johnson295189b2012-06-20 16:38:30 -070010919 * eCSR_ENCRYPT_TYPE_WEP40_STATICKEY.
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010920 * The correct security parameters will be updated later in
Jeff Johnson295189b2012-06-20 16:38:30 -070010921 * wlan_hdd_cfg80211_add_key */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010922 /* Hal expects encryption type to be set inorder
Jeff Johnson295189b2012-06-20 16:38:30 -070010923 *enable privacy bit in beacons */
10924
10925 encryptionType = eCSR_ENCRYPT_TYPE_WEP40_STATICKEY;
10926 }
Shailender Karmuchi642e9812013-05-30 14:34:49 -070010927 VOS_TRACE (VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO_HIGH,
10928 "encryptionType=%d", encryptionType);
Jeff Johnson295189b2012-06-20 16:38:30 -070010929 pHddStaCtx->conn_info.ucEncryptionType = encryptionType;
10930 pWextState->roamProfile.EncryptionType.numEntries = 1;
10931 pWextState->roamProfile.EncryptionType.encryptionType[0] = encryptionType;
Jeff Johnson295189b2012-06-20 16:38:30 -070010932 return status;
10933}
10934
10935/*
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053010936 * FUNCTION: __wlan_hdd_cfg80211_join_ibss
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010937 * This function is used to create/join an IBSS
Jeff Johnson295189b2012-06-20 16:38:30 -070010938 */
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053010939static int __wlan_hdd_cfg80211_join_ibss( struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -070010940 struct net_device *dev,
10941 struct cfg80211_ibss_params *params
10942 )
10943{
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010944 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( dev );
Jeff Johnson295189b2012-06-20 16:38:30 -070010945 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
10946 tCsrRoamProfile *pRoamProfile;
10947 int status;
krunal sonie9002db2013-11-25 14:24:17 -080010948 bool alloc_bssid = VOS_FALSE;
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053010949 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
10950 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Jeff Johnson295189b2012-06-20 16:38:30 -070010951
10952 ENTER();
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053010953
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053010954 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
10955 TRACE_CODE_HDD_CFG80211_JOIN_IBSS,
10956 pAdapter->sessionId, pAdapter->device_mode));
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010957 hddLog(VOS_TRACE_LEVEL_INFO,
Sushant Kaushik8bc7df22014-04-09 17:55:29 +053010958 "%s: device_mode = %s (%d)", __func__,
10959 hdd_device_modetoString(pAdapter->device_mode),
10960 pAdapter->device_mode);
Jeff Johnson295189b2012-06-20 16:38:30 -070010961
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053010962 status = wlan_hdd_validate_context(pHddCtx);
10963
10964 if (0 != status)
Jeff Johnson295189b2012-06-20 16:38:30 -070010965 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053010966 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
10967 "%s: HDD context is not valid", __func__);
10968 return status;
Jeff Johnson295189b2012-06-20 16:38:30 -070010969 }
10970
10971 if (NULL == pWextState)
10972 {
Arif Hussain6d2a3322013-11-17 19:50:10 -080010973 hddLog (VOS_TRACE_LEVEL_ERROR, "%s ERROR: Data Storage Corruption",
Jeff Johnson295189b2012-06-20 16:38:30 -070010974 __func__);
10975 return -EIO;
10976 }
10977
Agarwal Ashish51325b52014-06-16 16:50:49 +053010978 if (vos_max_concurrent_connections_reached()) {
10979 hddLog(VOS_TRACE_LEVEL_INFO, FL("Reached max concurrent connections"));
10980 return -ECONNREFUSED;
10981 }
10982
Vinay Krishna Eranna21042322014-01-08 19:21:39 +053010983 /*Try disconnecting if already in connected state*/
10984 status = wlan_hdd_try_disconnect(pAdapter);
10985 if ( 0 > status)
10986 {
10987 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Failed to disconnect the existing"
10988 " IBSS connection"));
10989 return -EALREADY;
10990 }
10991
Jeff Johnson295189b2012-06-20 16:38:30 -070010992 pRoamProfile = &pWextState->roamProfile;
10993
10994 if ( eCSR_BSS_TYPE_START_IBSS != pRoamProfile->BSSType )
10995 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010996 hddLog (VOS_TRACE_LEVEL_ERROR,
Arif Hussain6d2a3322013-11-17 19:50:10 -080010997 "%s Interface type is not set to IBSS", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -070010998 return -EINVAL;
10999 }
11000
Praveen Kumar Sirisillad123d142013-09-24 16:50:13 -070011001 /* BSSID is provided by upper layers hence no need to AUTO generate */
11002 if (NULL != params->bssid) {
11003 if (ccmCfgSetInt(pHddCtx->hHal, WNI_CFG_IBSS_AUTO_BSSID, 0,
11004 NULL, eANI_BOOLEAN_FALSE)==eHAL_STATUS_FAILURE) {
11005 hddLog (VOS_TRACE_LEVEL_ERROR,
11006 "%s:ccmCfgStInt faild for WNI_CFG_IBSS_AUTO_BSSID", __func__);
11007 return -EIO;
11008 }
11009 }
krunal sonie9002db2013-11-25 14:24:17 -080011010 else if(pHddCtx->cfg_ini->isCoalesingInIBSSAllowed == 0)
11011 {
11012 if (ccmCfgSetInt(pHddCtx->hHal, WNI_CFG_IBSS_AUTO_BSSID, 0,
11013 NULL, eANI_BOOLEAN_FALSE)==eHAL_STATUS_FAILURE)
11014 {
11015 hddLog (VOS_TRACE_LEVEL_ERROR,
11016 "%s:ccmCfgStInt faild for WNI_CFG_IBSS_AUTO_BSSID", __func__);
11017 return -EIO;
11018 }
11019 params->bssid = vos_mem_malloc(sizeof(VOS_MAC_ADDR_SIZE));
11020 if (!params->bssid)
11021 {
11022 hddLog (VOS_TRACE_LEVEL_ERROR,
11023 "%s:Failed memory allocation", __func__);
11024 return -EIO;
11025 }
11026 vos_mem_copy((v_U8_t *)params->bssid,
11027 (v_U8_t *)&pHddCtx->cfg_ini->IbssBssid.bytes[0],
11028 VOS_MAC_ADDR_SIZE);
11029 alloc_bssid = VOS_TRUE;
11030 }
Praveen Kumar Sirisillad123d142013-09-24 16:50:13 -070011031
Jeff Johnson295189b2012-06-20 16:38:30 -070011032 /* Set Channel */
Yue Maf49ba872013-08-19 12:04:25 -070011033 if (NULL !=
11034#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,8,0))
11035 params->chandef.chan)
11036#else
11037 params->channel)
11038#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070011039 {
11040 u8 channelNum;
Shailender Karmuchi15cd0672013-05-15 19:50:04 -070011041 v_U32_t numChans = WNI_CFG_VALID_CHANNEL_LIST_LEN;
11042 v_U8_t validChan[WNI_CFG_VALID_CHANNEL_LIST_LEN];
11043 tHalHandle hHal = WLAN_HDD_GET_HAL_CTX(pAdapter);
11044 int indx;
Jeff Johnson295189b2012-06-20 16:38:30 -070011045
11046 /* Get channel number */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011047 channelNum =
Yue Maf49ba872013-08-19 12:04:25 -070011048 ieee80211_frequency_to_channel(
11049#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,8,0))
11050 params->chandef.chan->center_freq);
11051#else
11052 params->channel->center_freq);
11053#endif
Shailender Karmuchi15cd0672013-05-15 19:50:04 -070011054
11055 if (0 != ccmCfgGetStr(hHal, WNI_CFG_VALID_CHANNEL_LIST,
11056 validChan, &numChans))
Jeff Johnson295189b2012-06-20 16:38:30 -070011057 {
Shailender Karmuchi15cd0672013-05-15 19:50:04 -070011058 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: No valid channel list",
11059 __func__);
11060 return -EOPNOTSUPP;
Jeff Johnson295189b2012-06-20 16:38:30 -070011061 }
Shailender Karmuchi15cd0672013-05-15 19:50:04 -070011062
11063 for (indx = 0; indx < numChans; indx++)
Jeff Johnson295189b2012-06-20 16:38:30 -070011064 {
Shailender Karmuchi15cd0672013-05-15 19:50:04 -070011065 if (channelNum == validChan[indx])
11066 {
11067 break;
11068 }
11069 }
11070 if (indx >= numChans)
11071 {
11072 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Not valid Channel %d",
Jeff Johnson295189b2012-06-20 16:38:30 -070011073 __func__, channelNum);
11074 return -EINVAL;
11075 }
Shailender Karmuchi15cd0672013-05-15 19:50:04 -070011076 /* Set the Operational Channel */
11077 hddLog(VOS_TRACE_LEVEL_INFO_HIGH, "%s: set channel %d", __func__,
11078 channelNum);
11079 pRoamProfile->ChannelInfo.numOfChannels = 1;
11080 pHddStaCtx->conn_info.operationChannel = channelNum;
11081 pRoamProfile->ChannelInfo.ChannelList =
11082 &pHddStaCtx->conn_info.operationChannel;
Jeff Johnson295189b2012-06-20 16:38:30 -070011083 }
11084
11085 /* Initialize security parameters */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011086 status = wlan_hdd_cfg80211_set_privacy_ibss(pAdapter, params);
Jeff Johnson295189b2012-06-20 16:38:30 -070011087 if (status < 0)
11088 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011089 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: failed to set security parameters",
Jeff Johnson295189b2012-06-20 16:38:30 -070011090 __func__);
11091 return status;
11092 }
11093
11094 /* Issue connect start */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011095 status = wlan_hdd_cfg80211_connect_start(pAdapter, params->ssid,
Shailender Karmuchi15cd0672013-05-15 19:50:04 -070011096 params->ssid_len, params->bssid,
11097 pHddStaCtx->conn_info.operationChannel);
Jeff Johnson295189b2012-06-20 16:38:30 -070011098
11099 if (0 > status)
11100 {
11101 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: connect failed", __func__);
11102 return status;
11103 }
11104
krunal sonie9002db2013-11-25 14:24:17 -080011105 if (NULL != params->bssid &&
11106 pHddCtx->cfg_ini->isCoalesingInIBSSAllowed == 0 &&
11107 alloc_bssid == VOS_TRUE)
11108 {
11109 vos_mem_free(params->bssid);
11110 }
Jeff Johnson295189b2012-06-20 16:38:30 -070011111 return 0;
11112}
11113
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053011114static int wlan_hdd_cfg80211_join_ibss( struct wiphy *wiphy,
11115 struct net_device *dev,
11116 struct cfg80211_ibss_params *params
11117 )
11118{
11119 int ret = 0;
11120
11121 vos_ssr_protect(__func__);
11122 ret = __wlan_hdd_cfg80211_join_ibss(wiphy, dev, params);
11123 vos_ssr_unprotect(__func__);
11124
11125 return ret;
11126}
11127
Jeff Johnson295189b2012-06-20 16:38:30 -070011128/*
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053011129 * FUNCTION: __wlan_hdd_cfg80211_leave_ibss
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011130 * This function is used to leave an IBSS
Jeff Johnson295189b2012-06-20 16:38:30 -070011131 */
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053011132static int __wlan_hdd_cfg80211_leave_ibss( struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -070011133 struct net_device *dev
11134 )
11135{
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011136 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( dev );
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053011137 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
11138 tCsrRoamProfile *pRoamProfile;
11139 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053011140 int status;
Jeff Johnson295189b2012-06-20 16:38:30 -070011141
11142 ENTER();
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053011143
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053011144 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
11145 TRACE_CODE_HDD_CFG80211_LEAVE_IBSS,
11146 pAdapter->sessionId, eCSR_DISCONNECT_REASON_IBSS_LEAVE));
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053011147 status = wlan_hdd_validate_context(pHddCtx);
11148
11149 if (0 != status)
Jeff Johnson04dd8a82012-06-29 20:41:40 -070011150 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053011151 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
11152 "%s: HDD context is not valid", __func__);
11153 return status;
Jeff Johnson04dd8a82012-06-29 20:41:40 -070011154 }
11155
Sushant Kaushik8bc7df22014-04-09 17:55:29 +053011156 hddLog(VOS_TRACE_LEVEL_INFO, "%s: device_mode = %s (%d)", __func__,
11157 hdd_device_modetoString(pAdapter->device_mode),
11158 pAdapter->device_mode);
Jeff Johnson295189b2012-06-20 16:38:30 -070011159 if (NULL == pWextState)
11160 {
Arif Hussain6d2a3322013-11-17 19:50:10 -080011161 hddLog (VOS_TRACE_LEVEL_ERROR, "%s ERROR: Data Storage Corruption",
Jeff Johnson295189b2012-06-20 16:38:30 -070011162 __func__);
11163 return -EIO;
11164 }
11165
11166 pRoamProfile = &pWextState->roamProfile;
11167
11168 /* Issue disconnect only if interface type is set to IBSS */
11169 if (eCSR_BSS_TYPE_START_IBSS != pRoamProfile->BSSType)
11170 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011171 hddLog (VOS_TRACE_LEVEL_ERROR, "%s: BSS Type is not set to IBSS",
Jeff Johnson295189b2012-06-20 16:38:30 -070011172 __func__);
11173 return -EINVAL;
11174 }
11175
11176 /* Issue Disconnect request */
11177 INIT_COMPLETION(pAdapter->disconnect_comp_var);
11178 sme_RoamDisconnect( WLAN_HDD_GET_HAL_CTX(pAdapter), pAdapter->sessionId,
11179 eCSR_DISCONNECT_REASON_IBSS_LEAVE);
11180
11181 return 0;
11182}
11183
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053011184static int wlan_hdd_cfg80211_leave_ibss( struct wiphy *wiphy,
11185 struct net_device *dev
11186 )
11187{
11188 int ret = 0;
11189
11190 vos_ssr_protect(__func__);
11191 ret = __wlan_hdd_cfg80211_leave_ibss(wiphy, dev);
11192 vos_ssr_unprotect(__func__);
11193
11194 return ret;
11195}
11196
Jeff Johnson295189b2012-06-20 16:38:30 -070011197/*
Mahesh A Saptasagar179d2252014-06-02 21:32:21 +053011198 * FUNCTION: __wlan_hdd_cfg80211_set_wiphy_params
Jeff Johnson295189b2012-06-20 16:38:30 -070011199 * This function is used to set the phy parameters
11200 * (RTS Threshold/FRAG Threshold/Retry Count etc ...)
11201 */
Mahesh A Saptasagar179d2252014-06-02 21:32:21 +053011202static int __wlan_hdd_cfg80211_set_wiphy_params(struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -070011203 u32 changed)
11204{
11205 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
11206 tHalHandle hHal = pHddCtx->hHal;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053011207 int status;
Jeff Johnson295189b2012-06-20 16:38:30 -070011208
11209 ENTER();
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053011210 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
11211 TRACE_CODE_HDD_CFG80211_SET_WIPHY_PARAMS,
11212 NO_SESSION, wiphy->rts_threshold));
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053011213 status = wlan_hdd_validate_context(pHddCtx);
11214
11215 if (0 != status)
Jeff Johnson04dd8a82012-06-29 20:41:40 -070011216 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053011217 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
11218 "%s: HDD context is not valid", __func__);
11219 return status;
Jeff Johnson04dd8a82012-06-29 20:41:40 -070011220 }
11221
Jeff Johnson295189b2012-06-20 16:38:30 -070011222 if (changed & WIPHY_PARAM_RTS_THRESHOLD)
11223 {
11224 u16 rts_threshold = (wiphy->rts_threshold == -1) ?
11225 WNI_CFG_RTS_THRESHOLD_STAMAX :
11226 wiphy->rts_threshold;
11227
11228 if ((WNI_CFG_RTS_THRESHOLD_STAMIN > rts_threshold) ||
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011229 (WNI_CFG_RTS_THRESHOLD_STAMAX < rts_threshold))
Jeff Johnson295189b2012-06-20 16:38:30 -070011230 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011231 hddLog(VOS_TRACE_LEVEL_ERROR,
11232 "%s: Invalid RTS Threshold value %hu",
Jeff Johnson295189b2012-06-20 16:38:30 -070011233 __func__, rts_threshold);
11234 return -EINVAL;
11235 }
11236
11237 if (0 != ccmCfgSetInt(hHal, WNI_CFG_RTS_THRESHOLD,
11238 rts_threshold, ccmCfgSetCallback,
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011239 eANI_BOOLEAN_TRUE))
Jeff Johnson295189b2012-06-20 16:38:30 -070011240 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011241 hddLog(VOS_TRACE_LEVEL_ERROR,
11242 "%s: ccmCfgSetInt failed for rts_threshold value %hu",
Jeff Johnson295189b2012-06-20 16:38:30 -070011243 __func__, rts_threshold);
11244 return -EIO;
11245 }
11246
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011247 hddLog(VOS_TRACE_LEVEL_INFO_MED, "%s: set rts threshold %hu", __func__,
Jeff Johnson295189b2012-06-20 16:38:30 -070011248 rts_threshold);
11249 }
11250
11251 if (changed & WIPHY_PARAM_FRAG_THRESHOLD)
11252 {
11253 u16 frag_threshold = (wiphy->frag_threshold == -1) ?
11254 WNI_CFG_FRAGMENTATION_THRESHOLD_STAMAX :
11255 wiphy->frag_threshold;
11256
11257 if ((WNI_CFG_FRAGMENTATION_THRESHOLD_STAMIN > frag_threshold)||
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011258 (WNI_CFG_FRAGMENTATION_THRESHOLD_STAMAX < frag_threshold) )
Jeff Johnson295189b2012-06-20 16:38:30 -070011259 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011260 hddLog(VOS_TRACE_LEVEL_ERROR,
11261 "%s: Invalid frag_threshold value %hu", __func__,
Jeff Johnson295189b2012-06-20 16:38:30 -070011262 frag_threshold);
11263 return -EINVAL;
11264 }
11265
11266 if (0 != ccmCfgSetInt(hHal, WNI_CFG_FRAGMENTATION_THRESHOLD,
11267 frag_threshold, ccmCfgSetCallback,
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011268 eANI_BOOLEAN_TRUE))
Jeff Johnson295189b2012-06-20 16:38:30 -070011269 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011270 hddLog(VOS_TRACE_LEVEL_ERROR,
11271 "%s: ccmCfgSetInt failed for frag_threshold value %hu",
Jeff Johnson295189b2012-06-20 16:38:30 -070011272 __func__, frag_threshold);
11273 return -EIO;
11274 }
11275
11276 hddLog(VOS_TRACE_LEVEL_INFO_MED, "%s: set frag threshold %hu", __func__,
11277 frag_threshold);
11278 }
11279
11280 if ((changed & WIPHY_PARAM_RETRY_SHORT)
11281 || (changed & WIPHY_PARAM_RETRY_LONG))
11282 {
11283 u8 retry_value = (changed & WIPHY_PARAM_RETRY_SHORT) ?
11284 wiphy->retry_short :
11285 wiphy->retry_long;
11286
11287 if ((WNI_CFG_LONG_RETRY_LIMIT_STAMIN > retry_value) ||
11288 (WNI_CFG_LONG_RETRY_LIMIT_STAMAX < retry_value))
11289 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011290 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Invalid Retry count %hu",
Jeff Johnson295189b2012-06-20 16:38:30 -070011291 __func__, retry_value);
11292 return -EINVAL;
11293 }
11294
11295 if (changed & WIPHY_PARAM_RETRY_SHORT)
11296 {
11297 if (0 != ccmCfgSetInt(hHal, WNI_CFG_LONG_RETRY_LIMIT,
11298 retry_value, ccmCfgSetCallback,
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011299 eANI_BOOLEAN_TRUE))
Jeff Johnson295189b2012-06-20 16:38:30 -070011300 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011301 hddLog(VOS_TRACE_LEVEL_ERROR,
11302 "%s: ccmCfgSetInt failed for long retry count %hu",
Jeff Johnson295189b2012-06-20 16:38:30 -070011303 __func__, retry_value);
11304 return -EIO;
11305 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011306 hddLog(VOS_TRACE_LEVEL_INFO_MED, "%s: set long retry count %hu",
Jeff Johnson295189b2012-06-20 16:38:30 -070011307 __func__, retry_value);
11308 }
11309 else if (changed & WIPHY_PARAM_RETRY_SHORT)
11310 {
11311 if (0 != ccmCfgSetInt(hHal, WNI_CFG_SHORT_RETRY_LIMIT,
11312 retry_value, ccmCfgSetCallback,
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011313 eANI_BOOLEAN_TRUE))
Jeff Johnson295189b2012-06-20 16:38:30 -070011314 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011315 hddLog(VOS_TRACE_LEVEL_ERROR,
11316 "%s: ccmCfgSetInt failed for short retry count %hu",
Jeff Johnson295189b2012-06-20 16:38:30 -070011317 __func__, retry_value);
11318 return -EIO;
11319 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011320 hddLog(VOS_TRACE_LEVEL_INFO_MED, "%s: set short retry count %hu",
Jeff Johnson295189b2012-06-20 16:38:30 -070011321 __func__, retry_value);
11322 }
11323 }
11324
11325 return 0;
11326}
11327
Mahesh A Saptasagar179d2252014-06-02 21:32:21 +053011328static int wlan_hdd_cfg80211_set_wiphy_params(struct wiphy *wiphy,
11329 u32 changed)
11330{
11331 int ret;
11332
11333 vos_ssr_protect(__func__);
11334 ret = __wlan_hdd_cfg80211_set_wiphy_params(wiphy, changed);
11335 vos_ssr_unprotect(__func__);
11336
11337 return ret;
11338}
11339
Jeff Johnson295189b2012-06-20 16:38:30 -070011340/*
Mahesh A Saptasagar179d2252014-06-02 21:32:21 +053011341 * FUNCTION: __wlan_hdd_cfg80211_set_txpower
Jeff Johnson295189b2012-06-20 16:38:30 -070011342 * This function is used to set the txpower
11343 */
Mahesh A Saptasagar179d2252014-06-02 21:32:21 +053011344static int __wlan_hdd_cfg80211_set_txpower(struct wiphy *wiphy,
Yue Maf49ba872013-08-19 12:04:25 -070011345#if LINUX_VERSION_CODE >= KERNEL_VERSION(3,8,0)
11346 struct wireless_dev *wdev,
11347#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070011348#if LINUX_VERSION_CODE <= KERNEL_VERSION(2,6,35)
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011349 enum tx_power_setting type,
Jeff Johnson295189b2012-06-20 16:38:30 -070011350#else
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011351 enum nl80211_tx_power_setting type,
Jeff Johnson295189b2012-06-20 16:38:30 -070011352#endif
11353 int dbm)
11354{
11355 hdd_context_t *pHddCtx = (hdd_context_t*) wiphy_priv(wiphy);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053011356 tHalHandle hHal = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -070011357 tSirMacAddr bssid = {0xFF,0xFF,0xFF,0xFF,0xFF,0xFF};
11358 tSirMacAddr selfMac = {0xFF,0xFF,0xFF,0xFF,0xFF,0xFF};
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053011359 int status;
Jeff Johnson295189b2012-06-20 16:38:30 -070011360
11361 ENTER();
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053011362 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
11363 TRACE_CODE_HDD_CFG80211_SET_TXPOWER,
11364 NO_SESSION, type ));
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053011365 status = wlan_hdd_validate_context(pHddCtx);
11366
11367 if (0 != status)
11368 {
11369 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
11370 "%s: HDD context is not valid", __func__);
11371 return status;
11372 }
11373
11374 hHal = pHddCtx->hHal;
11375
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011376 if (0 != ccmCfgSetInt(hHal, WNI_CFG_CURRENT_TX_POWER_LEVEL,
11377 dbm, ccmCfgSetCallback,
11378 eANI_BOOLEAN_TRUE))
Jeff Johnson295189b2012-06-20 16:38:30 -070011379 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011380 hddLog(VOS_TRACE_LEVEL_ERROR,
Jeff Johnson295189b2012-06-20 16:38:30 -070011381 "%s: ccmCfgSetInt failed for tx power %hu", __func__, dbm);
11382 return -EIO;
11383 }
11384
11385 hddLog(VOS_TRACE_LEVEL_INFO_MED, "%s: set tx power level %d dbm", __func__,
11386 dbm);
11387
11388 switch(type)
11389 {
11390 case NL80211_TX_POWER_AUTOMATIC: /*automatically determine transmit power*/
11391 /* Fall through */
11392 case NL80211_TX_POWER_LIMITED: /*limit TX power by the mBm parameter*/
11393 if( sme_SetMaxTxPower(hHal, bssid, selfMac, dbm) != eHAL_STATUS_SUCCESS )
11394 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011395 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Setting maximum tx power failed",
11396 __func__);
11397 return -EIO;
Jeff Johnson295189b2012-06-20 16:38:30 -070011398 }
11399 break;
11400 case NL80211_TX_POWER_FIXED: /*fix TX power to the mBm parameter*/
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011401 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: NL80211_TX_POWER_FIXED not supported",
Jeff Johnson295189b2012-06-20 16:38:30 -070011402 __func__);
11403 return -EOPNOTSUPP;
11404 break;
11405 default:
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011406 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Invalid power setting type %d",
11407 __func__, type);
Jeff Johnson295189b2012-06-20 16:38:30 -070011408 return -EIO;
11409 }
11410
11411 return 0;
11412}
11413
Mahesh A Saptasagar179d2252014-06-02 21:32:21 +053011414static int wlan_hdd_cfg80211_set_txpower(struct wiphy *wiphy,
11415#if LINUX_VERSION_CODE >= KERNEL_VERSION(3,8,0)
11416 struct wireless_dev *wdev,
11417#endif
11418#if LINUX_VERSION_CODE <= KERNEL_VERSION(2,6,35)
11419 enum tx_power_setting type,
11420#else
11421 enum nl80211_tx_power_setting type,
11422#endif
11423 int dbm)
11424{
11425 int ret;
11426 vos_ssr_protect(__func__);
11427 ret = __wlan_hdd_cfg80211_set_txpower(wiphy,
11428#if LINUX_VERSION_CODE >= KERNEL_VERSION(3,8,0)
11429 wdev,
11430#endif
11431#if LINUX_VERSION_CODE <= KERNEL_VERSION(2,6,35)
11432 type,
11433#else
11434 type,
11435#endif
11436 dbm);
11437 vos_ssr_unprotect(__func__);
11438
11439 return ret;
11440}
11441
Jeff Johnson295189b2012-06-20 16:38:30 -070011442/*
11443 * FUNCTION: wlan_hdd_cfg80211_get_txpower
11444 * This function is used to read the txpower
11445 */
Yue Maf49ba872013-08-19 12:04:25 -070011446static int wlan_hdd_cfg80211_get_txpower(struct wiphy *wiphy,
11447#if LINUX_VERSION_CODE >= KERNEL_VERSION(3,8,0)
11448 struct wireless_dev *wdev,
11449#endif
11450 int *dbm)
Jeff Johnson295189b2012-06-20 16:38:30 -070011451{
11452
11453 hdd_adapter_t *pAdapter;
11454 hdd_context_t *pHddCtx = (hdd_context_t*) wiphy_priv(wiphy);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053011455 int status;
Jeff Johnson295189b2012-06-20 16:38:30 -070011456
Jeff Johnsone7245742012-09-05 17:12:55 -070011457 ENTER();
11458
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053011459 status = wlan_hdd_validate_context(pHddCtx);
Jeff Johnson295189b2012-06-20 16:38:30 -070011460
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053011461 if (0 != status)
Jeff Johnson04dd8a82012-06-29 20:41:40 -070011462 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053011463 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
11464 "%s: HDD context is not valid", __func__);
11465 *dbm = 0;
11466 return status;
Jeff Johnson04dd8a82012-06-29 20:41:40 -070011467 }
11468
Jeff Johnson295189b2012-06-20 16:38:30 -070011469 pAdapter = hdd_get_adapter(pHddCtx, WLAN_HDD_INFRA_STATION);
11470 if (NULL == pAdapter)
11471 {
11472 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: Not in station context " ,__func__);
11473 return -ENOENT;
11474 }
11475
11476 wlan_hdd_get_classAstats(pAdapter);
11477 *dbm = pAdapter->hdd_stats.ClassA_stat.max_pwr;
11478
Jeff Johnsone7245742012-09-05 17:12:55 -070011479 EXIT();
Jeff Johnson295189b2012-06-20 16:38:30 -070011480 return 0;
11481}
11482
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053011483static int __wlan_hdd_cfg80211_get_station(struct wiphy *wiphy, struct net_device *dev,
Jeff Johnson295189b2012-06-20 16:38:30 -070011484 u8* mac, struct station_info *sinfo)
11485{
11486 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( dev );
11487 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
11488 int ssidlen = pHddStaCtx->conn_info.SSID.SSID.length;
c_hpothu44ff4e02014-05-08 00:13:57 +053011489 tANI_U32 rate_flags;
Jeff Johnson295189b2012-06-20 16:38:30 -070011490
11491 hdd_context_t *pHddCtx = (hdd_context_t*) wiphy_priv(wiphy);
11492 hdd_config_t *pCfg = pHddCtx->cfg_ini;
Jeff Johnson295189b2012-06-20 16:38:30 -070011493
11494 tANI_U8 OperationalRates[CSR_DOT11_SUPPORTED_RATES_MAX];
11495 tANI_U32 ORLeng = CSR_DOT11_SUPPORTED_RATES_MAX;
11496 tANI_U8 ExtendedRates[CSR_DOT11_EXTENDED_SUPPORTED_RATES_MAX];
11497 tANI_U32 ERLeng = CSR_DOT11_EXTENDED_SUPPORTED_RATES_MAX;
11498 tANI_U8 MCSRates[SIZE_OF_BASIC_MCS_SET];
11499 tANI_U32 MCSLeng = SIZE_OF_BASIC_MCS_SET;
11500 tANI_U16 maxRate = 0;
11501 tANI_U16 myRate;
11502 tANI_U16 currentRate = 0;
11503 tANI_U8 maxSpeedMCS = 0;
11504 tANI_U8 maxMCSIdx = 0;
11505 tANI_U8 rateFlag = 1;
c_hpothu79aab322014-07-14 21:11:01 +053011506 tANI_U8 i, j, rssidx, mode=0;
Madan Mohan Koyyalamudic75be962012-10-18 19:19:03 -070011507 tANI_U16 temp;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053011508 int status;
Jeff Johnson295189b2012-06-20 16:38:30 -070011509
Leo Chang6f8870f2013-03-26 18:11:36 -070011510#ifdef WLAN_FEATURE_11AC
11511 tANI_U32 vht_mcs_map;
11512 eDataRate11ACMaxMcs vhtMaxMcs;
11513#endif /* WLAN_FEATURE_11AC */
11514
Jeff Johnsone7245742012-09-05 17:12:55 -070011515 ENTER();
11516
Jeff Johnson295189b2012-06-20 16:38:30 -070011517 if ((eConnectionState_Associated != pHddStaCtx->conn_info.connState) ||
11518 (0 == ssidlen))
11519 {
11520 hddLog(VOS_TRACE_LEVEL_INFO, "%s: Not associated or"
11521 " Invalid ssidlen, %d", __func__, ssidlen);
11522 /*To keep GUI happy*/
11523 return 0;
11524 }
11525
Mukul Sharma811205f2014-07-09 21:07:30 +053011526 if (VOS_TRUE == pHddStaCtx->hdd_ReassocScenario)
11527 {
11528 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
11529 "%s: Roaming in progress, so unable to proceed this request", __func__);
11530 return 0;
11531 }
11532
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053011533 status = wlan_hdd_validate_context(pHddCtx);
11534
11535 if (0 != status)
Jeff Johnson04dd8a82012-06-29 20:41:40 -070011536 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053011537 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
11538 "%s: HDD context is not valid", __func__);
11539 return status;
Jeff Johnson04dd8a82012-06-29 20:41:40 -070011540 }
11541
Jeff Johnson295189b2012-06-20 16:38:30 -070011542
Kiet Lam3b17fc82013-09-27 05:24:08 +053011543 wlan_hdd_get_rssi(pAdapter, &sinfo->signal);
11544 sinfo->filled |= STATION_INFO_SIGNAL;
11545
c_hpothu09f19542014-05-30 21:53:31 +053011546 wlan_hdd_get_station_stats(pAdapter);
11547 rate_flags = pAdapter->hdd_stats.ClassA_stat.tx_rate_flags;
11548
11549 /*overwrite rate_flags if MAX link-speed need to be reported*/
c_hpothu44ff4e02014-05-08 00:13:57 +053011550 if ((eHDD_LINK_SPEED_REPORT_MAX == pCfg->reportMaxLinkSpeed) ||
11551 (eHDD_LINK_SPEED_REPORT_MAX_SCALED == pCfg->reportMaxLinkSpeed &&
c_hpothu79aab322014-07-14 21:11:01 +053011552 sinfo->signal >= pCfg->linkSpeedRssiLow))
c_hpothu44ff4e02014-05-08 00:13:57 +053011553 {
11554 rate_flags = pAdapter->maxRateFlags;
11555 }
c_hpothu44ff4e02014-05-08 00:13:57 +053011556
Jeff Johnson295189b2012-06-20 16:38:30 -070011557 //convert to the UI units of 100kbps
11558 myRate = pAdapter->hdd_stats.ClassA_stat.tx_rate * 5;
11559
11560#ifdef LINKSPEED_DEBUG_ENABLED
Leo Chang6f8870f2013-03-26 18:11:36 -070011561 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 -070011562 sinfo->signal,
11563 pCfg->reportMaxLinkSpeed,
11564 myRate,
11565 (int) pCfg->linkSpeedRssiHigh,
Madan Mohan Koyyalamudi8df78d52012-11-02 12:30:06 -070011566 (int) pCfg->linkSpeedRssiMid,
11567 (int) pCfg->linkSpeedRssiLow,
Leo Chang6f8870f2013-03-26 18:11:36 -070011568 (int) rate_flags,
11569 (int) pAdapter->hdd_stats.ClassA_stat.mcs_index);
Jeff Johnson295189b2012-06-20 16:38:30 -070011570#endif //LINKSPEED_DEBUG_ENABLED
11571
11572 if (eHDD_LINK_SPEED_REPORT_ACTUAL != pCfg->reportMaxLinkSpeed)
11573 {
11574 // we do not want to necessarily report the current speed
11575 if (eHDD_LINK_SPEED_REPORT_MAX == pCfg->reportMaxLinkSpeed)
11576 {
11577 // report the max possible speed
11578 rssidx = 0;
11579 }
11580 else if (eHDD_LINK_SPEED_REPORT_MAX_SCALED == pCfg->reportMaxLinkSpeed)
11581 {
11582 // report the max possible speed with RSSI scaling
11583 if (sinfo->signal >= pCfg->linkSpeedRssiHigh)
11584 {
11585 // report the max possible speed
11586 rssidx = 0;
11587 }
Madan Mohan Koyyalamudi8df78d52012-11-02 12:30:06 -070011588 else if (sinfo->signal >= pCfg->linkSpeedRssiMid)
Jeff Johnson295189b2012-06-20 16:38:30 -070011589 {
11590 // report middle speed
11591 rssidx = 1;
11592 }
Madan Mohan Koyyalamudi8df78d52012-11-02 12:30:06 -070011593 else if (sinfo->signal >= pCfg->linkSpeedRssiLow)
11594 {
11595 // report middle speed
11596 rssidx = 2;
11597 }
Jeff Johnson295189b2012-06-20 16:38:30 -070011598 else
11599 {
11600 // report actual speed
Madan Mohan Koyyalamudi8df78d52012-11-02 12:30:06 -070011601 rssidx = 3;
Jeff Johnson295189b2012-06-20 16:38:30 -070011602 }
11603 }
11604 else
11605 {
11606 // unknown, treat as eHDD_LINK_SPEED_REPORT_MAX
11607 hddLog(VOS_TRACE_LEVEL_ERROR,
11608 "%s: Invalid value for reportMaxLinkSpeed: %u",
11609 __func__, pCfg->reportMaxLinkSpeed);
11610 rssidx = 0;
11611 }
11612
11613 maxRate = 0;
11614
11615 /* Get Basic Rate Set */
Gopichand Nakkala05ab1322013-02-15 11:28:38 +053011616 if (0 != ccmCfgGetStr(WLAN_HDD_GET_HAL_CTX(pAdapter), WNI_CFG_OPERATIONAL_RATE_SET,
11617 OperationalRates, &ORLeng))
11618 {
11619 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: ccm api returned failure", __func__);
11620 /*To keep GUI happy*/
11621 return 0;
11622 }
11623
Jeff Johnson295189b2012-06-20 16:38:30 -070011624 for (i = 0; i < ORLeng; i++)
11625 {
Jeff Johnsone7245742012-09-05 17:12:55 -070011626 for (j = 0; j < (sizeof(supported_data_rate) / sizeof(supported_data_rate[0])); j ++)
Jeff Johnson295189b2012-06-20 16:38:30 -070011627 {
11628 /* Validate Rate Set */
11629 if (supported_data_rate[j].beacon_rate_index == (OperationalRates[i] & 0x7F))
11630 {
11631 currentRate = supported_data_rate[j].supported_rate[rssidx];
11632 break;
11633 }
11634 }
11635 /* Update MAX rate */
11636 maxRate = (currentRate > maxRate)?currentRate:maxRate;
11637 }
11638
11639 /* Get Extended Rate Set */
Gopichand Nakkala05ab1322013-02-15 11:28:38 +053011640 if (0 != ccmCfgGetStr(WLAN_HDD_GET_HAL_CTX(pAdapter), WNI_CFG_EXTENDED_OPERATIONAL_RATE_SET,
11641 ExtendedRates, &ERLeng))
11642 {
11643 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: ccm api returned failure", __func__);
11644 /*To keep GUI happy*/
11645 return 0;
11646 }
11647
Jeff Johnson295189b2012-06-20 16:38:30 -070011648 for (i = 0; i < ERLeng; i++)
11649 {
Jeff Johnsone7245742012-09-05 17:12:55 -070011650 for (j = 0; j < (sizeof(supported_data_rate) / sizeof(supported_data_rate[0])); j ++)
Jeff Johnson295189b2012-06-20 16:38:30 -070011651 {
11652 if (supported_data_rate[j].beacon_rate_index == (ExtendedRates[i] & 0x7F))
11653 {
11654 currentRate = supported_data_rate[j].supported_rate[rssidx];
11655 break;
11656 }
11657 }
11658 /* Update MAX rate */
11659 maxRate = (currentRate > maxRate)?currentRate:maxRate;
11660 }
c_hpothu79aab322014-07-14 21:11:01 +053011661
Kiet Lamb69f8dc2013-11-15 15:34:27 +053011662 /* Get MCS Rate Set --
Kaushik, Sushantdc304d82014-01-22 10:58:37 +053011663 Only if we are always reporting max speed (or)
Kiet Lamb69f8dc2013-11-15 15:34:27 +053011664 if we have good rssi */
c_hpothu79aab322014-07-14 21:11:01 +053011665 if ((3 != rssidx) && !(rate_flags & eHAL_TX_RATE_LEGACY))
Jeff Johnson295189b2012-06-20 16:38:30 -070011666 {
c_hpothu79aab322014-07-14 21:11:01 +053011667 if (rate_flags & eHAL_TX_RATE_VHT80)
11668 mode = 2;
11669 else if (rate_flags & (eHAL_TX_RATE_VHT40 | eHAL_TX_RATE_HT40))
11670 mode = 1;
11671 else
11672 mode = 0;
11673
Gopichand Nakkala05ab1322013-02-15 11:28:38 +053011674 if (0 != ccmCfgGetStr(WLAN_HDD_GET_HAL_CTX(pAdapter), WNI_CFG_CURRENT_MCS_SET,
11675 MCSRates, &MCSLeng))
11676 {
11677 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: ccm api returned failure", __func__);
11678 /*To keep GUI happy*/
11679 return 0;
11680 }
Jeff Johnson295189b2012-06-20 16:38:30 -070011681 rateFlag = 0;
Leo Chang6f8870f2013-03-26 18:11:36 -070011682#ifdef WLAN_FEATURE_11AC
11683 /* VHT80 rate has seperate rate table */
Gopichand Nakkala4c705372013-04-24 13:20:33 +053011684 if (rate_flags & (eHAL_TX_RATE_VHT20|eHAL_TX_RATE_VHT40|eHAL_TX_RATE_VHT80))
Jeff Johnson295189b2012-06-20 16:38:30 -070011685 {
Leo Chang6f8870f2013-03-26 18:11:36 -070011686 ccmCfgGetInt(WLAN_HDD_GET_HAL_CTX(pAdapter), WNI_CFG_VHT_TX_MCS_MAP, &vht_mcs_map);
Gopichand Nakkala4c705372013-04-24 13:20:33 +053011687 vhtMaxMcs = (eDataRate11ACMaxMcs)(vht_mcs_map & DATA_RATE_11AC_MCS_MASK );
Leo Chang6f8870f2013-03-26 18:11:36 -070011688 if (rate_flags & eHAL_TX_RATE_SGI)
Jeff Johnson295189b2012-06-20 16:38:30 -070011689 {
Leo Chang6f8870f2013-03-26 18:11:36 -070011690 rateFlag |= 1;
Jeff Johnson295189b2012-06-20 16:38:30 -070011691 }
Leo Chang6f8870f2013-03-26 18:11:36 -070011692 if (DATA_RATE_11AC_MAX_MCS_7 == vhtMaxMcs)
Jeff Johnson295189b2012-06-20 16:38:30 -070011693 {
Leo Chang6f8870f2013-03-26 18:11:36 -070011694 maxMCSIdx = 7;
11695 }
11696 else if (DATA_RATE_11AC_MAX_MCS_8 == vhtMaxMcs)
11697 {
11698 maxMCSIdx = 8;
11699 }
11700 else if (DATA_RATE_11AC_MAX_MCS_9 == vhtMaxMcs)
11701 {
Gopichand Nakkala4c705372013-04-24 13:20:33 +053011702 //VHT20 is supporting 0~8
11703 if (rate_flags & eHAL_TX_RATE_VHT20)
11704 maxMCSIdx = 8;
11705 else
11706 maxMCSIdx = 9;
Leo Chang6f8870f2013-03-26 18:11:36 -070011707 }
Gopichand Nakkala4c705372013-04-24 13:20:33 +053011708
c_hpothu79aab322014-07-14 21:11:01 +053011709 if (0 != rssidx)/*check for scaled */
11710 {
11711 //get middle rate MCS index if rssi=1/2
11712 for (i=0; i <= maxMCSIdx; i++)
11713 {
11714 if (sinfo->signal <= rssiMcsTbl[mode][i])
11715 {
11716 maxMCSIdx = i;
11717 break;
11718 }
11719 }
11720 }
11721
Gopichand Nakkala4c705372013-04-24 13:20:33 +053011722 if (rate_flags & eHAL_TX_RATE_VHT80)
11723 {
11724 currentRate = supported_vht_mcs_rate[pAdapter->hdd_stats.ClassA_stat.mcs_index].supported_VHT80_rate[rateFlag];
11725 maxRate = supported_vht_mcs_rate[maxMCSIdx].supported_VHT80_rate[rateFlag];
11726 }
11727 else if (rate_flags & eHAL_TX_RATE_VHT40)
11728 {
11729 currentRate = supported_vht_mcs_rate[pAdapter->hdd_stats.ClassA_stat.mcs_index].supported_VHT40_rate[rateFlag];
11730 maxRate = supported_vht_mcs_rate[maxMCSIdx].supported_VHT40_rate[rateFlag];
11731 }
11732 else if (rate_flags & eHAL_TX_RATE_VHT20)
11733 {
11734 currentRate = supported_vht_mcs_rate[pAdapter->hdd_stats.ClassA_stat.mcs_index].supported_VHT20_rate[rateFlag];
11735 maxRate = supported_vht_mcs_rate[maxMCSIdx].supported_VHT20_rate[rateFlag];
11736 }
11737
Leo Chang6f8870f2013-03-26 18:11:36 -070011738 maxSpeedMCS = 1;
11739 if (currentRate > maxRate)
11740 {
11741 maxRate = currentRate;
11742 }
Gopichand Nakkala4c705372013-04-24 13:20:33 +053011743
Leo Chang6f8870f2013-03-26 18:11:36 -070011744 }
11745 else
11746#endif /* WLAN_FEATURE_11AC */
11747 {
11748 if (rate_flags & eHAL_TX_RATE_HT40)
11749 {
11750 rateFlag |= 1;
11751 }
11752 if (rate_flags & eHAL_TX_RATE_SGI)
11753 {
11754 rateFlag |= 2;
11755 }
11756
c_hpothu79aab322014-07-14 21:11:01 +053011757 if (rssidx == 1 || rssidx == 2)
11758 {
11759 //get middle rate MCS index if rssi=1/2
11760 for (i=0; i <= 7; i++)
11761 {
11762 if (sinfo->signal <= rssiMcsTbl[mode][i])
11763 {
11764 temp = i+1;
11765 break;
11766 }
11767 }
11768 }
11769 else
Leo Chang6f8870f2013-03-26 18:11:36 -070011770 {
11771 temp = sizeof(supported_mcs_rate) / sizeof(supported_mcs_rate[0]);
c_hpothu79aab322014-07-14 21:11:01 +053011772 }
11773
11774 for (i = 0; i < MCSLeng; i++)
11775 {
Leo Chang6f8870f2013-03-26 18:11:36 -070011776 for (j = 0; j < temp; j++)
11777 {
11778 if (supported_mcs_rate[j].beacon_rate_index == MCSRates[i])
11779 {
11780 currentRate = supported_mcs_rate[j].supported_rate[rateFlag];
11781 break;
11782 }
11783 }
11784 if ((j < temp) && (currentRate > maxRate))
11785 {
11786 maxRate = currentRate;
11787 maxSpeedMCS = 1;
11788 maxMCSIdx = supported_mcs_rate[j].beacon_rate_index;
11789 }
Jeff Johnson295189b2012-06-20 16:38:30 -070011790 }
11791 }
11792 }
11793
Gopichand Nakkala4c705372013-04-24 13:20:33 +053011794 else if (!(rate_flags & eHAL_TX_RATE_LEGACY))
11795 {
11796 maxRate = myRate;
11797 maxSpeedMCS = 1;
11798 maxMCSIdx = pAdapter->hdd_stats.ClassA_stat.mcs_index;
11799 }
Jeff Johnson295189b2012-06-20 16:38:30 -070011800 // make sure we report a value at least as big as our current rate
c_hpothu79aab322014-07-14 21:11:01 +053011801 if ((maxRate < myRate) || (0 == maxRate))
Jeff Johnson295189b2012-06-20 16:38:30 -070011802 {
11803 maxRate = myRate;
11804 if (rate_flags & eHAL_TX_RATE_LEGACY)
11805 {
11806 maxSpeedMCS = 0;
11807 }
11808 else
11809 {
11810 maxSpeedMCS = 1;
11811 maxMCSIdx = pAdapter->hdd_stats.ClassA_stat.mcs_index;
11812 }
11813 }
11814
Gopichand Nakkala4c705372013-04-24 13:20:33 +053011815 if (rate_flags & eHAL_TX_RATE_LEGACY)
Jeff Johnson295189b2012-06-20 16:38:30 -070011816 {
11817 sinfo->txrate.legacy = maxRate;
11818#ifdef LINKSPEED_DEBUG_ENABLED
11819 pr_info("Reporting legacy rate %d\n", sinfo->txrate.legacy);
11820#endif //LINKSPEED_DEBUG_ENABLED
11821 }
11822 else
11823 {
11824 sinfo->txrate.mcs = maxMCSIdx;
Leo Chang6f8870f2013-03-26 18:11:36 -070011825#ifdef WLAN_FEATURE_11AC
11826 sinfo->txrate.nss = 1;
11827 if (rate_flags & eHAL_TX_RATE_VHT80)
11828 {
11829 sinfo->txrate.flags |= RATE_INFO_FLAGS_VHT_MCS;
Gopichand Nakkala4c705372013-04-24 13:20:33 +053011830 sinfo->txrate.flags |= RATE_INFO_FLAGS_80_MHZ_WIDTH;
Leo Chang6f8870f2013-03-26 18:11:36 -070011831 }
Gopichand Nakkala4c705372013-04-24 13:20:33 +053011832 else if (rate_flags & eHAL_TX_RATE_VHT40)
Leo Chang6f8870f2013-03-26 18:11:36 -070011833 {
Gopichand Nakkala4c705372013-04-24 13:20:33 +053011834 sinfo->txrate.flags |= RATE_INFO_FLAGS_VHT_MCS;
11835 sinfo->txrate.flags |= RATE_INFO_FLAGS_40_MHZ_WIDTH;
11836 }
11837 else if (rate_flags & eHAL_TX_RATE_VHT20)
11838 {
11839 sinfo->txrate.flags |= RATE_INFO_FLAGS_VHT_MCS;
11840 }
11841#endif /* WLAN_FEATURE_11AC */
11842 if (rate_flags & (eHAL_TX_RATE_HT20 | eHAL_TX_RATE_HT40))
11843 {
11844 sinfo->txrate.flags |= RATE_INFO_FLAGS_MCS;
11845 if (rate_flags & eHAL_TX_RATE_HT40)
11846 {
11847 sinfo->txrate.flags |= RATE_INFO_FLAGS_40_MHZ_WIDTH;
11848 }
Leo Chang6f8870f2013-03-26 18:11:36 -070011849 }
Jeff Johnson295189b2012-06-20 16:38:30 -070011850 if (rate_flags & eHAL_TX_RATE_SGI)
11851 {
11852 sinfo->txrate.flags |= RATE_INFO_FLAGS_SHORT_GI;
11853 }
Gopichand Nakkala4c705372013-04-24 13:20:33 +053011854
Jeff Johnson295189b2012-06-20 16:38:30 -070011855#ifdef LINKSPEED_DEBUG_ENABLED
11856 pr_info("Reporting MCS rate %d flags %x\n",
11857 sinfo->txrate.mcs,
11858 sinfo->txrate.flags );
11859#endif //LINKSPEED_DEBUG_ENABLED
11860 }
11861 }
11862 else
11863 {
11864 // report current rate instead of max rate
11865
11866 if (rate_flags & eHAL_TX_RATE_LEGACY)
11867 {
11868 //provide to the UI in units of 100kbps
11869 sinfo->txrate.legacy = myRate;
11870#ifdef LINKSPEED_DEBUG_ENABLED
11871 pr_info("Reporting actual legacy rate %d\n", sinfo->txrate.legacy);
11872#endif //LINKSPEED_DEBUG_ENABLED
11873 }
11874 else
11875 {
11876 //must be MCS
11877 sinfo->txrate.mcs = pAdapter->hdd_stats.ClassA_stat.mcs_index;
Leo Chang6f8870f2013-03-26 18:11:36 -070011878#ifdef WLAN_FEATURE_11AC
11879 sinfo->txrate.nss = 1;
11880 if (rate_flags & eHAL_TX_RATE_VHT80)
11881 {
11882 sinfo->txrate.flags |= RATE_INFO_FLAGS_VHT_MCS;
11883 }
11884 else
11885#endif /* WLAN_FEATURE_11AC */
11886 {
11887 sinfo->txrate.flags |= RATE_INFO_FLAGS_MCS;
11888 }
Jeff Johnson295189b2012-06-20 16:38:30 -070011889 if (rate_flags & eHAL_TX_RATE_SGI)
11890 {
11891 sinfo->txrate.flags |= RATE_INFO_FLAGS_SHORT_GI;
11892 }
11893 if (rate_flags & eHAL_TX_RATE_HT40)
11894 {
11895 sinfo->txrate.flags |= RATE_INFO_FLAGS_40_MHZ_WIDTH;
11896 }
Leo Chang6f8870f2013-03-26 18:11:36 -070011897#ifdef WLAN_FEATURE_11AC
11898 else if (rate_flags & eHAL_TX_RATE_VHT80)
11899 {
11900 sinfo->txrate.flags |= RATE_INFO_FLAGS_80_MHZ_WIDTH;
11901 }
11902#endif /* WLAN_FEATURE_11AC */
Jeff Johnson295189b2012-06-20 16:38:30 -070011903#ifdef LINKSPEED_DEBUG_ENABLED
11904 pr_info("Reporting actual MCS rate %d flags %x\n",
11905 sinfo->txrate.mcs,
11906 sinfo->txrate.flags );
11907#endif //LINKSPEED_DEBUG_ENABLED
11908 }
11909 }
11910 sinfo->filled |= STATION_INFO_TX_BITRATE;
11911
Madan Mohan Koyyalamudi4d4d2812012-09-24 14:08:29 -070011912 sinfo->tx_packets =
11913 pAdapter->hdd_stats.summary_stat.tx_frm_cnt[0] +
11914 pAdapter->hdd_stats.summary_stat.tx_frm_cnt[1] +
11915 pAdapter->hdd_stats.summary_stat.tx_frm_cnt[2] +
11916 pAdapter->hdd_stats.summary_stat.tx_frm_cnt[3];
11917
11918 sinfo->tx_retries =
11919 pAdapter->hdd_stats.summary_stat.retry_cnt[0] +
11920 pAdapter->hdd_stats.summary_stat.retry_cnt[1] +
11921 pAdapter->hdd_stats.summary_stat.retry_cnt[2] +
11922 pAdapter->hdd_stats.summary_stat.retry_cnt[3];
11923
11924 sinfo->tx_failed =
11925 pAdapter->hdd_stats.summary_stat.fail_cnt[0] +
11926 pAdapter->hdd_stats.summary_stat.fail_cnt[1] +
11927 pAdapter->hdd_stats.summary_stat.fail_cnt[2] +
11928 pAdapter->hdd_stats.summary_stat.fail_cnt[3];
11929
11930 sinfo->filled |=
11931 STATION_INFO_TX_PACKETS |
11932 STATION_INFO_TX_RETRIES |
11933 STATION_INFO_TX_FAILED;
11934
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053011935 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
11936 TRACE_CODE_HDD_CFG80211_GET_STA,
11937 pAdapter->sessionId, maxRate));
Madan Mohan Koyyalamudi4d4d2812012-09-24 14:08:29 -070011938 EXIT();
11939 return 0;
Jeff Johnson295189b2012-06-20 16:38:30 -070011940}
11941
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053011942static int wlan_hdd_cfg80211_get_station(struct wiphy *wiphy, struct net_device *dev,
11943 u8* mac, struct station_info *sinfo)
11944{
11945 int ret;
11946
11947 vos_ssr_protect(__func__);
11948 ret = __wlan_hdd_cfg80211_get_station(wiphy, dev, mac, sinfo);
11949 vos_ssr_unprotect(__func__);
11950
11951 return ret;
11952}
11953
11954static int __wlan_hdd_cfg80211_set_power_mgmt(struct wiphy *wiphy,
Sameer Thalappilc9f26e92013-06-07 10:11:06 -070011955 struct net_device *dev, bool mode, int timeout)
Jeff Johnson295189b2012-06-20 16:38:30 -070011956{
11957 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
Gopichand Nakkala20c4c042013-04-19 22:08:55 +053011958 hdd_context_t *pHddCtx;
Jeff Johnson295189b2012-06-20 16:38:30 -070011959 VOS_STATUS vos_status;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053011960 int status;
Jeff Johnson295189b2012-06-20 16:38:30 -070011961
Jeff Johnsone7245742012-09-05 17:12:55 -070011962 ENTER();
11963
Jeff Johnson295189b2012-06-20 16:38:30 -070011964 if (NULL == pAdapter)
11965 {
Arif Hussain6d2a3322013-11-17 19:50:10 -080011966 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Adapter is NULL", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -070011967 return -ENODEV;
11968 }
11969
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053011970 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
11971 TRACE_CODE_HDD_CFG80211_SET_POWER_MGMT,
11972 pAdapter->sessionId, timeout));
11973
Gopichand Nakkala20c4c042013-04-19 22:08:55 +053011974 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053011975 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkala20c4c042013-04-19 22:08:55 +053011976
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053011977 if (0 != status)
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011978 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053011979 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
11980 "%s: HDD context is not valid", __func__);
11981 return status;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011982 }
11983
Gopichand Nakkala20c4c042013-04-19 22:08:55 +053011984 if ((DRIVER_POWER_MODE_AUTO == !mode) &&
11985 (TRUE == pHddCtx->hdd_wlan_suspended) &&
11986 (pHddCtx->cfg_ini->fhostArpOffload) &&
11987 (eConnectionState_Associated ==
11988 (WLAN_HDD_GET_STATION_CTX_PTR(pAdapter))->conn_info.connState))
11989 {
Amar Singhald53568e2013-09-26 11:03:45 -070011990
11991 hddLog(VOS_TRACE_LEVEL_INFO,
11992 "offload: in cfg80211_set_power_mgmt, calling arp offload");
Gopichand Nakkalab03e8082013-05-30 18:09:25 +053011993 vos_status = hdd_conf_arp_offload(pAdapter, TRUE);
Gopichand Nakkala20c4c042013-04-19 22:08:55 +053011994 if (!VOS_IS_STATUS_SUCCESS(vos_status))
11995 {
11996 hddLog(VOS_TRACE_LEVEL_INFO,
Arif Hussain6d2a3322013-11-17 19:50:10 -080011997 "%s:Failed to enable ARPOFFLOAD Feature %d",
Gopichand Nakkala20c4c042013-04-19 22:08:55 +053011998 __func__, vos_status);
11999 }
12000 }
12001
Jeff Johnson295189b2012-06-20 16:38:30 -070012002 /**The get power cmd from the supplicant gets updated by the nl only
12003 *on successful execution of the function call
12004 *we are oppositely mapped w.r.t mode in the driver
12005 **/
12006 vos_status = wlan_hdd_enter_bmps(pAdapter, !mode);
12007
Jeff Johnsone7245742012-09-05 17:12:55 -070012008 EXIT();
Jeff Johnson295189b2012-06-20 16:38:30 -070012009 if (VOS_STATUS_E_FAILURE == vos_status)
12010 {
c_hpothu6ff1c3c2013-10-01 19:01:57 +053012011 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
12012 "%s: failed to enter bmps mode", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -070012013 return -EINVAL;
12014 }
12015 return 0;
12016}
12017
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053012018static int wlan_hdd_cfg80211_set_power_mgmt(struct wiphy *wiphy,
12019 struct net_device *dev, bool mode, int timeout)
12020{
12021 int ret;
Jeff Johnson295189b2012-06-20 16:38:30 -070012022
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053012023 vos_ssr_protect(__func__);
12024 ret = __wlan_hdd_cfg80211_set_power_mgmt(wiphy, dev, mode, timeout);
12025 vos_ssr_unprotect(__func__);
12026
12027 return ret;
12028}
Jeff Johnson295189b2012-06-20 16:38:30 -070012029#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
12030static int wlan_hdd_set_default_mgmt_key(struct wiphy *wiphy,
12031 struct net_device *netdev,
12032 u8 key_index)
12033{
Jeff Johnsone7245742012-09-05 17:12:55 -070012034 ENTER();
Jeff Johnson295189b2012-06-20 16:38:30 -070012035 return 0;
12036}
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012037#endif //LINUX_VERSION_CODE
Jeff Johnson295189b2012-06-20 16:38:30 -070012038
12039#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,4,0))
12040static int wlan_hdd_set_txq_params(struct wiphy *wiphy,
12041 struct net_device *dev,
12042 struct ieee80211_txq_params *params)
12043{
Jeff Johnsone7245742012-09-05 17:12:55 -070012044 ENTER();
Jeff Johnson295189b2012-06-20 16:38:30 -070012045 return 0;
12046}
12047#elif (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
12048static int wlan_hdd_set_txq_params(struct wiphy *wiphy,
12049 struct ieee80211_txq_params *params)
12050{
Jeff Johnsone7245742012-09-05 17:12:55 -070012051 ENTER();
Jeff Johnson295189b2012-06-20 16:38:30 -070012052 return 0;
12053}
12054#endif //LINUX_VERSION_CODE
12055
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053012056static int __wlan_hdd_cfg80211_del_station(struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -070012057 struct net_device *dev, u8 *mac)
12058{
12059 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053012060 hdd_context_t *pHddCtx;
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -080012061 VOS_STATUS vos_status;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053012062 int status;
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -080012063 v_U8_t staId;
Jeff Johnson295189b2012-06-20 16:38:30 -070012064
Jeff Johnsone7245742012-09-05 17:12:55 -070012065 ENTER();
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053012066
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053012067 if ( NULL == pAdapter )
Jeff Johnson295189b2012-06-20 16:38:30 -070012068 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053012069 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Invalid Adapter" ,__func__);
Jeff Johnson295189b2012-06-20 16:38:30 -070012070 return -EINVAL;
12071 }
12072
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053012073 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
12074 TRACE_CODE_HDD_CFG80211_DEL_STA,
12075 pAdapter->sessionId, pAdapter->device_mode));
12076
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053012077 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
12078 status = wlan_hdd_validate_context(pHddCtx);
Jeff Johnson295189b2012-06-20 16:38:30 -070012079
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053012080 if (0 != status)
Jeff Johnson04dd8a82012-06-29 20:41:40 -070012081 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053012082 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
12083 "%s: HDD context is not valid", __func__);
12084 return status;
Jeff Johnson04dd8a82012-06-29 20:41:40 -070012085 }
12086
Jeff Johnson295189b2012-06-20 16:38:30 -070012087 if ( (WLAN_HDD_SOFTAP == pAdapter->device_mode)
Jeff Johnson295189b2012-06-20 16:38:30 -070012088 || (WLAN_HDD_P2P_GO == pAdapter->device_mode)
Jeff Johnson295189b2012-06-20 16:38:30 -070012089 )
12090 {
12091 if( NULL == mac )
12092 {
12093 v_U16_t i;
12094 for(i = 0; i < WLAN_MAX_STA_COUNT; i++)
12095 {
Rajesh Chauhan18488fc2013-08-22 10:15:03 -070012096 if ((pAdapter->aStaInfo[i].isUsed) &&
12097 (!pAdapter->aStaInfo[i].isDeauthInProgress))
Jeff Johnson295189b2012-06-20 16:38:30 -070012098 {
12099 u8 *macAddr = pAdapter->aStaInfo[i].macAddrSTA.bytes;
12100 hddLog(VOS_TRACE_LEVEL_INFO,
Arif Hussain24bafea2013-11-15 15:10:03 -080012101 "%s: Delete STA with MAC::"
12102 MAC_ADDRESS_STR,
12103 __func__, MAC_ADDR_ARRAY(macAddr));
Rajesh Chauhan18488fc2013-08-22 10:15:03 -070012104 vos_status = hdd_softap_sta_deauth(pAdapter, macAddr);
12105 if (VOS_IS_STATUS_SUCCESS(vos_status))
12106 pAdapter->aStaInfo[i].isDeauthInProgress = TRUE;
Jeff Johnson295189b2012-06-20 16:38:30 -070012107 }
12108 }
12109 }
12110 else
12111 {
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -080012112
12113 vos_status = hdd_softap_GetStaId(pAdapter,(v_MACADDR_t *)mac, &staId);
12114 if (!VOS_IS_STATUS_SUCCESS(vos_status))
12115 {
12116 hddLog(VOS_TRACE_LEVEL_INFO,
Arif Hussain24bafea2013-11-15 15:10:03 -080012117 "%s: Skip this DEL STA as this is not used::"
12118 MAC_ADDRESS_STR,
12119 __func__, MAC_ADDR_ARRAY(mac));
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -080012120 return -ENOENT;
12121 }
12122
12123 if( pAdapter->aStaInfo[staId].isDeauthInProgress == TRUE)
12124 {
12125 hddLog(VOS_TRACE_LEVEL_INFO,
Arif Hussain24bafea2013-11-15 15:10:03 -080012126 "%s: Skip this DEL STA as deauth is in progress::"
12127 MAC_ADDRESS_STR,
12128 __func__, MAC_ADDR_ARRAY(mac));
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -080012129 return -ENOENT;
12130 }
12131
12132 pAdapter->aStaInfo[staId].isDeauthInProgress = TRUE;
12133
Jeff Johnson295189b2012-06-20 16:38:30 -070012134 hddLog(VOS_TRACE_LEVEL_INFO,
12135 "%s: Delete STA with MAC::"
Arif Hussain24bafea2013-11-15 15:10:03 -080012136 MAC_ADDRESS_STR,
Jeff Johnson295189b2012-06-20 16:38:30 -070012137 __func__,
Arif Hussain24bafea2013-11-15 15:10:03 -080012138 MAC_ADDR_ARRAY(mac));
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -080012139
12140 vos_status = hdd_softap_sta_deauth(pAdapter, mac);
12141 if (!VOS_IS_STATUS_SUCCESS(vos_status))
12142 {
12143 pAdapter->aStaInfo[staId].isDeauthInProgress = FALSE;
12144 hddLog(VOS_TRACE_LEVEL_INFO,
12145 "%s: STA removal failed for ::"
Arif Hussain24bafea2013-11-15 15:10:03 -080012146 MAC_ADDRESS_STR,
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -080012147 __func__,
Arif Hussain24bafea2013-11-15 15:10:03 -080012148 MAC_ADDR_ARRAY(mac));
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -080012149 return -ENOENT;
12150 }
12151
Jeff Johnson295189b2012-06-20 16:38:30 -070012152 }
12153 }
12154
12155 EXIT();
12156
12157 return 0;
12158}
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053012159static int wlan_hdd_cfg80211_del_station(struct wiphy *wiphy,
12160 struct net_device *dev, u8 *mac)
12161{
12162 int ret;
Jeff Johnson295189b2012-06-20 16:38:30 -070012163
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053012164 vos_ssr_protect(__func__);
12165 ret = __wlan_hdd_cfg80211_del_station(wiphy, dev, mac);
12166 vos_ssr_unprotect(__func__);
12167
12168 return ret;
12169}
12170
12171static int __wlan_hdd_cfg80211_add_station(struct wiphy *wiphy,
Hoonki Lee11f7dda2013-02-14 16:55:44 -080012172 struct net_device *dev, u8 *mac, struct station_parameters *params)
12173{
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053012174 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
Gopichand Nakkalab977a972013-02-18 19:15:09 -080012175 int status = -EPERM;
Hoonki Lee11f7dda2013-02-14 16:55:44 -080012176#ifdef FEATURE_WLAN_TDLS
12177 u32 mask, set;
Hoonki Lee11f7dda2013-02-14 16:55:44 -080012178 ENTER();
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053012179
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053012180 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
12181 TRACE_CODE_HDD_CFG80211_ADD_STA,
12182 pAdapter->sessionId, params->listen_interval));
Mohit Khanna698ba2a2012-12-04 15:08:18 -080012183 mask = params->sta_flags_mask;
12184
12185 set = params->sta_flags_set;
12186
Gopichand Nakkalac87400e2013-03-13 18:51:00 -070012187#ifdef WLAN_FEATURE_TDLS_DEBUG
12188 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
12189 "%s: mask 0x%x set 0x%x " MAC_ADDRESS_STR,
12190 __func__, mask, set, MAC_ADDR_ARRAY(mac));
12191#endif
Mohit Khanna698ba2a2012-12-04 15:08:18 -080012192
12193 if (mask & BIT(NL80211_STA_FLAG_TDLS_PEER)) {
12194 if (set & BIT(NL80211_STA_FLAG_TDLS_PEER)) {
Gopichand Nakkala681989c2013-03-06 22:27:48 -080012195 status = wlan_hdd_tdls_add_station(wiphy, dev, mac, 0, NULL);
Mohit Khanna698ba2a2012-12-04 15:08:18 -080012196 }
12197 }
12198#endif
Gopichand Nakkalab977a972013-02-18 19:15:09 -080012199 return status;
Jeff Johnson295189b2012-06-20 16:38:30 -070012200}
12201
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053012202static int wlan_hdd_cfg80211_add_station(struct wiphy *wiphy,
12203 struct net_device *dev, u8 *mac, struct station_parameters *params)
12204{
12205 int ret;
Jeff Johnson04dd8a82012-06-29 20:41:40 -070012206
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053012207 vos_ssr_protect(__func__);
12208 ret = __wlan_hdd_cfg80211_add_station(wiphy, dev, mac, params);
12209 vos_ssr_unprotect(__func__);
12210
12211 return ret;
12212}
Jeff Johnson04dd8a82012-06-29 20:41:40 -070012213#ifdef FEATURE_WLAN_LFR
Wilson Yang6507c4e2013-10-01 20:11:19 -070012214
Mahesh A Saptasagarf7418d72014-06-02 14:48:54 +053012215static int __wlan_hdd_cfg80211_set_pmksa(struct wiphy *wiphy, struct net_device *dev,
Jeff Johnsond13512a2012-07-17 11:42:19 -070012216 struct cfg80211_pmksa *pmksa)
Jeff Johnson04dd8a82012-06-29 20:41:40 -070012217{
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012218 tANI_U32 j=0;
Jeff Johnson04dd8a82012-06-29 20:41:40 -070012219 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
Agarwal Ashish3da95242014-05-21 14:57:17 +053012220 hdd_station_ctx_t *pHddStaCtx;
Jeff Johnson04dd8a82012-06-29 20:41:40 -070012221 tHalHandle halHandle;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012222 eHalStatus result;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053012223 int status;
Jeff Johnson04dd8a82012-06-29 20:41:40 -070012224 tANI_U8 BSSIDMatched = 0;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053012225 hdd_context_t *pHddCtx;
Jeff Johnson0299d0a2013-10-30 12:37:43 -070012226 hddLog(VOS_TRACE_LEVEL_DEBUG, "%s: set PMKSA for " MAC_ADDRESS_STR,
12227 __func__, MAC_ADDR_ARRAY(pmksa->bssid));
Jeff Johnsone7245742012-09-05 17:12:55 -070012228
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012229 // Validate pAdapter
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053012230 if ( NULL == pAdapter )
Jeff Johnson04dd8a82012-06-29 20:41:40 -070012231 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053012232 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Invalid Adapter" ,__func__);
Jeff Johnson04dd8a82012-06-29 20:41:40 -070012233 return -EINVAL;
12234 }
12235
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053012236 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
12237 status = wlan_hdd_validate_context(pHddCtx);
Jeff Johnson04dd8a82012-06-29 20:41:40 -070012238
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053012239 if (0 != status)
Jeff Johnson04dd8a82012-06-29 20:41:40 -070012240 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053012241 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
12242 "%s: HDD context is not valid", __func__);
12243 return status;
Jeff Johnson04dd8a82012-06-29 20:41:40 -070012244 }
12245
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012246 // Retrieve halHandle
Jeff Johnson04dd8a82012-06-29 20:41:40 -070012247 halHandle = WLAN_HDD_GET_HAL_CTX(pAdapter);
Agarwal Ashish3da95242014-05-21 14:57:17 +053012248 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
Jeff Johnson04dd8a82012-06-29 20:41:40 -070012249
Agarwal Ashish3da95242014-05-21 14:57:17 +053012250 for (j = 0; j < pHddStaCtx->PMKIDCacheIndex; j++)
Jeff Johnson04dd8a82012-06-29 20:41:40 -070012251 {
Agarwal Ashish3da95242014-05-21 14:57:17 +053012252 if (vos_mem_compare(pHddStaCtx->PMKIDCache[j].BSSID,
Jeff Johnson04dd8a82012-06-29 20:41:40 -070012253 pmksa->bssid, WNI_CFG_BSSID_LEN))
12254 {
12255 /* BSSID matched previous entry. Overwrite it. */
12256 BSSIDMatched = 1;
Agarwal Ashish3da95242014-05-21 14:57:17 +053012257 vos_mem_copy(pHddStaCtx->PMKIDCache[j].BSSID,
Jeff Johnson04dd8a82012-06-29 20:41:40 -070012258 pmksa->bssid, WNI_CFG_BSSID_LEN);
Agarwal Ashish3da95242014-05-21 14:57:17 +053012259 vos_mem_copy(pHddStaCtx->PMKIDCache[j].PMKID,
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012260 pmksa->pmkid,
Jeff Johnson04dd8a82012-06-29 20:41:40 -070012261 CSR_RSN_PMKID_SIZE);
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012262 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: Reusing cache entry %d.",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -070012263 __func__, j );
Jeff Johnson04dd8a82012-06-29 20:41:40 -070012264 dump_bssid(pmksa->bssid);
12265 dump_pmkid(halHandle, pmksa->pmkid);
12266 break;
12267 }
12268 }
12269
Madan Mohan Koyyalamudic4b317d2012-10-18 19:43:08 -070012270 /* Check we compared all entries,if then take the first slot now */
Agarwal Ashish3da95242014-05-21 14:57:17 +053012271 if (j == MAX_PMKSAIDS_IN_CACHE) pHddStaCtx->PMKIDCacheIndex=0;
Madan Mohan Koyyalamudic4b317d2012-10-18 19:43:08 -070012272
Jeff Johnson04dd8a82012-06-29 20:41:40 -070012273 if (!BSSIDMatched)
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012274 {
12275 // Now, we DON'T have a BSSID match, so take a new entry in the cache.
Agarwal Ashish3da95242014-05-21 14:57:17 +053012276 vos_mem_copy(pHddStaCtx->PMKIDCache[pHddStaCtx->PMKIDCacheIndex].BSSID,
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012277 pmksa->bssid, ETHER_ADDR_LEN);
Agarwal Ashish3da95242014-05-21 14:57:17 +053012278 vos_mem_copy(pHddStaCtx->PMKIDCache[pHddStaCtx->PMKIDCacheIndex].PMKID,
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012279 pmksa->pmkid,
Jeff Johnson04dd8a82012-06-29 20:41:40 -070012280 CSR_RSN_PMKID_SIZE);
Agarwal Ashish3da95242014-05-21 14:57:17 +053012281 hddLog(VOS_TRACE_LEVEL_DEBUG, "%s: Adding a new cache entry %d.",
12282 __func__, pHddStaCtx->PMKIDCacheIndex );
Jeff Johnson04dd8a82012-06-29 20:41:40 -070012283 dump_bssid(pmksa->bssid);
12284 dump_pmkid(halHandle, pmksa->pmkid);
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012285 // Increment the HDD Local Cache index
Jeff Johnson04dd8a82012-06-29 20:41:40 -070012286 // The "i=0" doesn't work for the call to sme_RoamSetPMKIDCache() - LFR FIXME
Agarwal Ashish3da95242014-05-21 14:57:17 +053012287 if (pHddStaCtx->PMKIDCacheIndex <= (MAX_PMKSAIDS_IN_CACHE-1))
12288 pHddStaCtx->PMKIDCacheIndex++;
12289 else
12290 pHddStaCtx->PMKIDCacheIndex = 0;
Jeff Johnson04dd8a82012-06-29 20:41:40 -070012291 }
12292
12293
12294 // Calling csrRoamSetPMKIDCache to configure the PMKIDs into the cache
Agarwal Ashish3da95242014-05-21 14:57:17 +053012295 hddLog(VOS_TRACE_LEVEL_DEBUG, "%s: Calling csrRoamSetPMKIDCache with %d cache entries.",
12296 __func__, pHddStaCtx->PMKIDCacheIndex );
12297
Jeff Johnson04dd8a82012-06-29 20:41:40 -070012298 // Finally set the PMKSA ID Cache in CSR
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012299 result = sme_RoamSetPMKIDCache(halHandle,pAdapter->sessionId,
Agarwal Ashish3da95242014-05-21 14:57:17 +053012300 pHddStaCtx->PMKIDCache,
12301 pHddStaCtx->PMKIDCacheIndex);
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053012302 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
12303 TRACE_CODE_HDD_CFG80211_SET_PMKSA,
12304 pAdapter->sessionId, result));
Jeff Johnson04dd8a82012-06-29 20:41:40 -070012305 return 0;
12306}
12307
Mahesh A Saptasagarf7418d72014-06-02 14:48:54 +053012308static int wlan_hdd_cfg80211_set_pmksa(struct wiphy *wiphy, struct net_device *dev,
12309 struct cfg80211_pmksa *pmksa)
12310{
12311 int ret;
12312
12313 vos_ssr_protect(__func__);
12314 ret = __wlan_hdd_cfg80211_set_pmksa(wiphy, dev, pmksa);
12315 vos_ssr_unprotect(__func__);
12316
12317 return ret;
12318}
Jeff Johnson04dd8a82012-06-29 20:41:40 -070012319
Wilson Yang6507c4e2013-10-01 20:11:19 -070012320
Mahesh A Saptasagarf7418d72014-06-02 14:48:54 +053012321static int __wlan_hdd_cfg80211_del_pmksa(struct wiphy *wiphy, struct net_device *dev,
Wilson Yang6507c4e2013-10-01 20:11:19 -070012322 struct cfg80211_pmksa *pmksa)
Jeff Johnson04dd8a82012-06-29 20:41:40 -070012323{
Wilson Yang6507c4e2013-10-01 20:11:19 -070012324 tANI_U32 j=0;
12325 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
Agarwal Ashish3da95242014-05-21 14:57:17 +053012326 hdd_station_ctx_t *pHddStaCtx;
Wilson Yang6507c4e2013-10-01 20:11:19 -070012327 tHalHandle halHandle;
Wilson Yang6507c4e2013-10-01 20:11:19 -070012328 tANI_U8 BSSIDMatched = 0;
Wilson Yang6507c4e2013-10-01 20:11:19 -070012329 hdd_context_t *pHddCtx;
Wilson Yangef657d32014-01-15 19:19:23 -080012330 int status = 0;
Wilson Yang6507c4e2013-10-01 20:11:19 -070012331
Jeff Johnson0299d0a2013-10-30 12:37:43 -070012332 hddLog(VOS_TRACE_LEVEL_DEBUG, "%s: deleting PMKSA for " MAC_ADDRESS_STR,
12333 __func__, MAC_ADDR_ARRAY(pmksa->bssid));
Wilson Yang6507c4e2013-10-01 20:11:19 -070012334
12335 /* Validate pAdapter */
12336 if (NULL == pAdapter)
12337 {
12338 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Invalid Adapter" ,__func__);
12339 return -EINVAL;
12340 }
12341
12342 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
12343 status = wlan_hdd_validate_context(pHddCtx);
12344
12345 if (0 != status)
12346 {
12347 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
12348 "%s: HDD context is not valid", __func__);
12349 return status;
12350 }
12351
12352 /*Retrieve halHandle*/
12353 halHandle = WLAN_HDD_GET_HAL_CTX(pAdapter);
Agarwal Ashish3da95242014-05-21 14:57:17 +053012354 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
Wilson Yang6507c4e2013-10-01 20:11:19 -070012355
12356 /*in case index is 0,no entry to delete*/
Agarwal Ashish3da95242014-05-21 14:57:17 +053012357 if (0 == pHddStaCtx->PMKIDCacheIndex)
Wilson Yang6507c4e2013-10-01 20:11:19 -070012358 {
Agarwal Ashish3da95242014-05-21 14:57:17 +053012359 hddLog(VOS_TRACE_LEVEL_INFO, FL("No entries to flush"));
12360 return 0;
Wilson Yang6507c4e2013-10-01 20:11:19 -070012361 }
12362
12363 /*find the matching PMKSA entry from j=0 to (index-1),
12364 * and delete the matched one
12365 */
Agarwal Ashish3da95242014-05-21 14:57:17 +053012366 for (j = 0; j < pHddStaCtx->PMKIDCacheIndex; j++)
Wilson Yang6507c4e2013-10-01 20:11:19 -070012367 {
Agarwal Ashish3da95242014-05-21 14:57:17 +053012368 if (vos_mem_compare(pHddStaCtx->PMKIDCache[j].BSSID,
Wilson Yang6507c4e2013-10-01 20:11:19 -070012369 pmksa->bssid,
12370 WNI_CFG_BSSID_LEN))
12371 {
12372 /* BSSID matched entry */
12373 BSSIDMatched = 1;
Agarwal Ashish3da95242014-05-21 14:57:17 +053012374 if (j < pHddStaCtx->PMKIDCacheIndex-1)
Wilson Yang6507c4e2013-10-01 20:11:19 -070012375 {
12376 /*replace the matching entry with the last entry in HDD local cache*/
Agarwal Ashish3da95242014-05-21 14:57:17 +053012377 vos_mem_copy(pHddStaCtx->PMKIDCache[j].BSSID,
12378 pHddStaCtx->PMKIDCache[pHddStaCtx->PMKIDCacheIndex-1].BSSID,
12379 VOS_MAC_ADDR_SIZE);
12380 vos_mem_copy(pHddStaCtx->PMKIDCache[j].PMKID,
12381 pHddStaCtx->PMKIDCache[pHddStaCtx->PMKIDCacheIndex-1].PMKID,
12382 CSR_RSN_PMKID_SIZE);
12383 }
Wilson Yang6507c4e2013-10-01 20:11:19 -070012384
12385 /*clear the last entry in HDD cache ---[index-1]*/
Agarwal Ashish3da95242014-05-21 14:57:17 +053012386 vos_mem_zero(pHddStaCtx->PMKIDCache[pHddStaCtx->PMKIDCacheIndex-1].BSSID,
12387 VOS_MAC_ADDR_SIZE);
12388 vos_mem_zero(pHddStaCtx->PMKIDCache[pHddStaCtx->PMKIDCacheIndex-1].PMKID,
12389 CSR_RSN_PMKID_SIZE);
Wilson Yang6507c4e2013-10-01 20:11:19 -070012390 /*reduce the PMKID array index*/
Agarwal Ashish3da95242014-05-21 14:57:17 +053012391 pHddStaCtx->PMKIDCacheIndex--;
Wilson Yang6507c4e2013-10-01 20:11:19 -070012392 /*delete the last PMKID cache in CSR*/
Wilson Yangef657d32014-01-15 19:19:23 -080012393 if (eHAL_STATUS_SUCCESS !=
12394 sme_RoamDelPMKIDfromCache(halHandle, pAdapter->sessionId, pmksa->bssid))
Wilson Yang6507c4e2013-10-01 20:11:19 -070012395 {
12396 hddLog(VOS_TRACE_LEVEL_ERROR,"%s: cannot delete PMKSA %d CONTENT.",
Agarwal Ashish3da95242014-05-21 14:57:17 +053012397 __func__, pHddStaCtx->PMKIDCacheIndex);
Wilson Yangef657d32014-01-15 19:19:23 -080012398 status = -EINVAL;
Wilson Yang6507c4e2013-10-01 20:11:19 -070012399 }
12400
12401 dump_bssid(pmksa->bssid);
12402 dump_pmkid(halHandle,pmksa->pmkid);
12403
12404 break;
12405 }
12406 }
12407
12408 /* we compare all entries,but cannot find matching entry */
12409 if (j == MAX_PMKSAIDS_IN_CACHE && !BSSIDMatched)
12410 {
Jeff Johnson0299d0a2013-10-30 12:37:43 -070012411 hddLog(VOS_TRACE_LEVEL_FATAL,
12412 "%s: No such PMKSA entry existed " MAC_ADDRESS_STR,
12413 __func__, MAC_ADDR_ARRAY(pmksa->bssid));
Wilson Yang6507c4e2013-10-01 20:11:19 -070012414 dump_bssid(pmksa->bssid);
12415 dump_pmkid(halHandle, pmksa->pmkid);
12416 return -EINVAL;
12417 }
Wilson Yangef657d32014-01-15 19:19:23 -080012418 return status;
Jeff Johnson04dd8a82012-06-29 20:41:40 -070012419}
12420
Wilson Yang6507c4e2013-10-01 20:11:19 -070012421
Mahesh A Saptasagarf7418d72014-06-02 14:48:54 +053012422static int wlan_hdd_cfg80211_del_pmksa(struct wiphy *wiphy, struct net_device *dev,
12423 struct cfg80211_pmksa *pmksa)
12424{
12425 int ret;
Wilson Yang6507c4e2013-10-01 20:11:19 -070012426
Mahesh A Saptasagarf7418d72014-06-02 14:48:54 +053012427 vos_ssr_protect(__func__);
12428 ret = __wlan_hdd_cfg80211_del_pmksa(wiphy, dev, pmksa);
12429 vos_ssr_unprotect(__func__);
12430
12431 return ret;
12432
12433}
12434
12435static int __wlan_hdd_cfg80211_flush_pmksa(struct wiphy *wiphy, struct net_device *dev)
Jeff Johnson04dd8a82012-06-29 20:41:40 -070012436{
Wilson Yang6507c4e2013-10-01 20:11:19 -070012437 tANI_U32 j=0;
12438 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
Agarwal Ashish3da95242014-05-21 14:57:17 +053012439 hdd_station_ctx_t *pHddStaCtx;
Wilson Yang6507c4e2013-10-01 20:11:19 -070012440 tHalHandle halHandle;
12441 hdd_context_t *pHddCtx;
12442 tANI_U8 *pBSSId;
Wilson Yangef657d32014-01-15 19:19:23 -080012443 int status = 0;
Wilson Yang6507c4e2013-10-01 20:11:19 -070012444
12445 hddLog(VOS_TRACE_LEVEL_DEBUG, "%s: flushing PMKSA ",__func__);
12446
12447 /* Validate pAdapter */
12448 if (NULL == pAdapter)
12449 {
12450 hddLog(VOS_TRACE_LEVEL_ERROR,
12451 "%s: Invalid Adapter" ,__func__);
12452 return -EINVAL;
12453 }
12454
12455 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
12456 status = wlan_hdd_validate_context(pHddCtx);
12457
12458 if (0 != status)
12459 {
12460 hddLog(VOS_TRACE_LEVEL_ERROR,
12461 "%s: HDD context is not valid", __func__);
12462 return status;
12463 }
12464
12465 /*Retrieve halHandle*/
12466 halHandle = WLAN_HDD_GET_HAL_CTX(pAdapter);
Agarwal Ashish3da95242014-05-21 14:57:17 +053012467 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
Wilson Yang6507c4e2013-10-01 20:11:19 -070012468
12469 /*in case index is 0,no entry to delete*/
Agarwal Ashish3da95242014-05-21 14:57:17 +053012470 if (0 == pHddStaCtx->PMKIDCacheIndex)
Wilson Yang6507c4e2013-10-01 20:11:19 -070012471 {
Vinay Krishna Erannacbf75f42014-02-26 17:35:20 +053012472 hddLog(VOS_TRACE_LEVEL_ERROR, FL("No entries to flush"));
Agarwal Ashish3da95242014-05-21 14:57:17 +053012473 return 0;
Wilson Yang6507c4e2013-10-01 20:11:19 -070012474 }
12475
12476 /*delete all the PMKSA one by one */
Agarwal Ashish3da95242014-05-21 14:57:17 +053012477 for (j = 0; j < pHddStaCtx->PMKIDCacheIndex; j++)
Wilson Yang6507c4e2013-10-01 20:11:19 -070012478 {
Agarwal Ashish3da95242014-05-21 14:57:17 +053012479 pBSSId =(tANI_U8 *)(pHddStaCtx->PMKIDCache[j].BSSID);
Wilson Yang6507c4e2013-10-01 20:11:19 -070012480 /*delete the PMKID in CSR*/
Wilson Yangef657d32014-01-15 19:19:23 -080012481 if (eHAL_STATUS_SUCCESS !=
12482 sme_RoamDelPMKIDfromCache(halHandle, pAdapter->sessionId, pBSSId))
Wilson Yang6507c4e2013-10-01 20:11:19 -070012483 {
12484 hddLog(VOS_TRACE_LEVEL_ERROR ,"%s cannot flush PMKIDCache %d.",
12485 __func__,j);
Wilson Yangef657d32014-01-15 19:19:23 -080012486 status = -EINVAL;
Wilson Yang6507c4e2013-10-01 20:11:19 -070012487 }
Kiet Lam8d21d5b2013-10-31 17:18:29 +053012488 /*clear the entry in HDD cache 0--index-1 */
Agarwal Ashish3da95242014-05-21 14:57:17 +053012489 vos_mem_zero(pHddStaCtx->PMKIDCache[j].BSSID, VOS_MAC_ADDR_SIZE);
12490 vos_mem_zero(pHddStaCtx->PMKIDCache[j].PMKID, CSR_RSN_PMKID_SIZE);
12491 }
Wilson Yang6507c4e2013-10-01 20:11:19 -070012492
Agarwal Ashish3da95242014-05-21 14:57:17 +053012493 pHddStaCtx->PMKIDCacheIndex = 0;
Wilson Yangef657d32014-01-15 19:19:23 -080012494 return status;
Jeff Johnson04dd8a82012-06-29 20:41:40 -070012495}
Mahesh A Saptasagarf7418d72014-06-02 14:48:54 +053012496
12497static int wlan_hdd_cfg80211_flush_pmksa(struct wiphy *wiphy, struct net_device *dev)
12498{
12499 int ret;
12500
12501 vos_ssr_protect(__func__);
12502 ret = __wlan_hdd_cfg80211_flush_pmksa(wiphy, dev);
12503 vos_ssr_unprotect(__func__);
12504
12505 return ret;
12506}
Jeff Johnson04dd8a82012-06-29 20:41:40 -070012507#endif
12508
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070012509#if defined(WLAN_FEATURE_VOWIFI_11R) && defined(KERNEL_SUPPORT_11R_CFG80211)
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053012510static int __wlan_hdd_cfg80211_update_ft_ies(struct wiphy *wiphy,
12511 struct net_device *dev,
12512 struct cfg80211_update_ft_ies_params *ftie)
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070012513{
12514 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
12515 hdd_station_ctx_t *pHddStaCtx;
12516
12517 if (NULL == pAdapter)
12518 {
Arif Hussain6d2a3322013-11-17 19:50:10 -080012519 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Adapter is NULL", __func__);
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070012520 return -ENODEV;
12521 }
12522
12523 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
12524
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053012525 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
12526 TRACE_CODE_HDD_CFG80211_UPDATE_FT_IES,
12527 pAdapter->sessionId, pHddStaCtx->conn_info.connState));
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070012528 // Added for debug on reception of Re-assoc Req.
12529 if (eConnectionState_Associated != pHddStaCtx->conn_info.connState)
12530 {
Arif Hussain6d2a3322013-11-17 19:50:10 -080012531 hddLog(LOGE, FL("Called with Ie of length = %zu when not associated"),
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070012532 ftie->ie_len);
Arif Hussain6d2a3322013-11-17 19:50:10 -080012533 hddLog(LOGE, FL("Should be Re-assoc Req IEs"));
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070012534 }
12535
12536#ifdef WLAN_FEATURE_VOWIFI_11R_DEBUG
Arif Hussain6d2a3322013-11-17 19:50:10 -080012537 hddLog(LOGE, FL("%s called with Ie of length = %zu"), __func__,
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070012538 ftie->ie_len);
12539#endif
12540
12541 // Pass the received FT IEs to SME
Gopichand Nakkala356fb102013-03-06 12:34:04 +053012542 sme_SetFTIEs( WLAN_HDD_GET_HAL_CTX(pAdapter), pAdapter->sessionId,
12543 (const u8 *)ftie->ie,
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070012544 ftie->ie_len);
12545 return 0;
12546}
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053012547
12548static int wlan_hdd_cfg80211_update_ft_ies(struct wiphy *wiphy,
12549 struct net_device *dev,
12550 struct cfg80211_update_ft_ies_params *ftie)
12551{
12552 int ret;
12553
12554 vos_ssr_protect(__func__);
12555 ret = __wlan_hdd_cfg80211_update_ft_ies(wiphy, dev, ftie);
12556 vos_ssr_unprotect(__func__);
12557
12558 return ret;
12559}
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070012560#endif
Jeff Johnson04dd8a82012-06-29 20:41:40 -070012561
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053012562#ifdef FEATURE_WLAN_SCAN_PNO
12563
12564void hdd_cfg80211_sched_scan_done_callback(void *callbackContext,
12565 tSirPrefNetworkFoundInd *pPrefNetworkFoundInd)
12566{
12567 int ret;
12568 hdd_adapter_t* pAdapter = (hdd_adapter_t*)callbackContext;
12569 hdd_context_t *pHddCtx;
12570
Nirav Shah80830bf2013-12-31 16:35:12 +053012571 ENTER();
12572
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053012573 if (NULL == pAdapter)
12574 {
Agarwal Ashish971c2882013-10-30 20:11:12 +053012575 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053012576 "%s: HDD adapter is Null", __func__);
12577 return ;
12578 }
12579
12580 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
12581 if (NULL == pHddCtx)
12582 {
12583 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
12584 "%s: HDD context is Null!!!", __func__);
12585 return ;
12586 }
12587
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053012588 spin_lock(&pHddCtx->schedScan_lock);
12589 if (TRUE == pHddCtx->isWiphySuspended)
12590 {
12591 pHddCtx->isSchedScanUpdatePending = TRUE;
12592 spin_unlock(&pHddCtx->schedScan_lock);
12593 hddLog(VOS_TRACE_LEVEL_INFO,
12594 "%s: Update cfg80211 scan database after it resume", __func__);
12595 return ;
12596 }
12597 spin_unlock(&pHddCtx->schedScan_lock);
12598
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053012599 ret = wlan_hdd_cfg80211_update_bss(pHddCtx->wiphy, pAdapter);
12600
12601 if (0 > ret)
12602 hddLog(VOS_TRACE_LEVEL_INFO, "%s: NO SCAN result", __func__);
12603
12604 cfg80211_sched_scan_results(pHddCtx->wiphy);
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053012605 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
12606 "%s: cfg80211 scan result database updated", __func__);
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053012607}
12608
12609/*
Mahesh A Saptasagar0f7b0372013-11-28 23:23:07 +053012610 * FUNCTION: wlan_hdd_is_pno_allowed
Vinay Krishna Erannacbf75f42014-02-26 17:35:20 +053012611 * Disallow pno if any session is active
Mahesh A Saptasagar0f7b0372013-11-28 23:23:07 +053012612 */
12613static eHalStatus wlan_hdd_is_pno_allowed(hdd_adapter_t *pAdapter)
12614{
12615 hdd_adapter_list_node_t *pAdapterNode = NULL, *pNext = NULL;
12616 hdd_adapter_t *pTempAdapter = NULL;
Vinay Krishna Eranna23ffd182013-12-26 19:16:55 +053012617 hdd_station_ctx_t *pStaCtx;
Mahesh A Saptasagar0f7b0372013-11-28 23:23:07 +053012618 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
12619 int status = 0;
12620 status = hdd_get_front_adapter(pHddCtx, &pAdapterNode);
12621
Vinay Krishna Erannacbf75f42014-02-26 17:35:20 +053012622 /* The current firmware design does not allow PNO during any
12623 * active sessions. Hence, determine the active sessions
12624 * and return a failure.
12625 */
Mahesh A Saptasagar0f7b0372013-11-28 23:23:07 +053012626 while ((NULL != pAdapterNode) && (VOS_STATUS_SUCCESS == status))
12627 {
12628 pTempAdapter = pAdapterNode->pAdapter;
Vinay Krishna Eranna23ffd182013-12-26 19:16:55 +053012629 pStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pTempAdapter);
Mahesh A Saptasagar0f7b0372013-11-28 23:23:07 +053012630
Vinay Krishna Eranna23ffd182013-12-26 19:16:55 +053012631 if (((WLAN_HDD_INFRA_STATION == pTempAdapter->device_mode)
12632 && (eConnectionState_NotConnected != pStaCtx->conn_info.connState))
12633 || (WLAN_HDD_P2P_CLIENT == pTempAdapter->device_mode)
12634 || (WLAN_HDD_P2P_GO == pTempAdapter->device_mode)
12635 || (WLAN_HDD_SOFTAP == pTempAdapter->device_mode)
12636 )
Mahesh A Saptasagar0f7b0372013-11-28 23:23:07 +053012637 {
Vinay Krishna Eranna23ffd182013-12-26 19:16:55 +053012638 return eHAL_STATUS_FAILURE;
Mahesh A Saptasagar0f7b0372013-11-28 23:23:07 +053012639 }
12640 status = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
12641 pAdapterNode = pNext;
12642 }
Vinay Krishna Eranna23ffd182013-12-26 19:16:55 +053012643 return eHAL_STATUS_SUCCESS;
Mahesh A Saptasagar0f7b0372013-11-28 23:23:07 +053012644}
12645
Vinay Krishna Erannaf0e523b2014-03-01 21:00:16 +053012646void hdd_cfg80211_sched_scan_start_status_cb(void *callbackContext, VOS_STATUS status)
12647{
12648 hdd_adapter_t *pAdapter = callbackContext;
12649 hdd_context_t *pHddCtx;
12650
12651 if ((NULL == pAdapter) || (WLAN_HDD_ADAPTER_MAGIC != pAdapter->magic))
12652 {
12653 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
12654 FL("Invalid adapter or adapter has invalid magic"));
12655 return;
12656 }
12657
12658 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
12659 if (0 != wlan_hdd_validate_context(pHddCtx))
12660 {
12661 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
12662 FL("HDD context is not valid"));
12663 return;
12664 }
12665
12666 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
12667 FL("PNO enable response status = %d"), status);
12668
12669 pAdapter->pno_req_status = (status == VOS_STATUS_SUCCESS) ? 0 : -EBUSY;
12670 complete(&pAdapter->pno_comp_var);
12671}
12672
Mahesh A Saptasagar0f7b0372013-11-28 23:23:07 +053012673/*
Mahesh A Saptasagar6cc38562014-05-23 21:22:17 +053012674 * FUNCTION: __wlan_hdd_cfg80211_sched_scan_start
12675 * Function to enable PNO
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053012676 */
Mahesh A Saptasagar6cc38562014-05-23 21:22:17 +053012677static int __wlan_hdd_cfg80211_sched_scan_start(struct wiphy *wiphy,
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053012678 struct net_device *dev, struct cfg80211_sched_scan_request *request)
12679{
12680 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
12681 tpSirPNOScanReq pPnoRequest = NULL;
12682 hdd_context_t *pHddCtx;
12683 tHalHandle hHal;
Mahesh A Saptasagar7bd6ad42014-07-21 18:56:33 +053012684 v_U32_t i, indx, num_ch, tempInterval, j;
Sushant Kaushikd62d9782014-02-19 15:39:40 +053012685 u8 valid_ch[WNI_CFG_VALID_CHANNEL_LIST_LEN] = {0};
12686 u8 channels_allowed[WNI_CFG_VALID_CHANNEL_LIST_LEN] = {0};
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053012687 v_U32_t num_channels_allowed = WNI_CFG_VALID_CHANNEL_LIST_LEN;
12688 eHalStatus status = eHAL_STATUS_FAILURE;
Kamath Vinayakba5313f2013-08-22 15:52:39 +053012689 int ret = 0;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053012690
12691 if (NULL == pAdapter)
12692 {
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053012693 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053012694 "%s: HDD adapter is Null", __func__);
12695 return -ENODEV;
12696 }
12697
12698 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053012699 ret = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053012700
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053012701 if (0 != ret)
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053012702 {
Gopichand Nakkalac005b7c2013-05-14 16:04:14 +053012703 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
12704 "%s: HDD context is not valid", __func__);
Kamath Vinayakba5313f2013-08-22 15:52:39 +053012705 return -EINVAL;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053012706 }
12707
12708 hHal = WLAN_HDD_GET_HAL_CTX(pAdapter);
12709 if (NULL == hHal)
12710 {
12711 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
12712 "%s: HAL context is Null!!!", __func__);
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053012713 return -EINVAL;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053012714 }
Vinay Krishna Eranna23ffd182013-12-26 19:16:55 +053012715
Mahesh A Saptasagar2395ee62014-05-21 19:12:21 +053012716 ret = wlan_hdd_scan_abort(pAdapter);
Girish Gowli4bf7a632014-06-12 13:42:11 +053012717 if (ret < 0)
Mahesh A Saptasagar2395ee62014-05-21 19:12:21 +053012718 {
12719 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
12720 "%s: aborting the existing scan is unsuccessfull", __func__);
12721 return -EBUSY;
12722 }
12723
Vinay Krishna Eranna23ffd182013-12-26 19:16:55 +053012724 if (eHAL_STATUS_SUCCESS != wlan_hdd_is_pno_allowed(pAdapter))
Mahesh A Saptasagar0f7b0372013-11-28 23:23:07 +053012725 {
Vinay Krishna Erannacbf75f42014-02-26 17:35:20 +053012726 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_WARN,
Vinay Krishna Eranna23ffd182013-12-26 19:16:55 +053012727 FL("Cannot handle sched_scan"));
Mahesh A Saptasagar0f7b0372013-11-28 23:23:07 +053012728 return -EBUSY;
12729 }
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053012730
c_hpothu37f21312014-04-09 21:49:54 +053012731 if (TRUE == pHddCtx->isPnoEnable)
12732 {
12733 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_WARN,
12734 FL("already PNO is enabled"));
12735 return -EBUSY;
12736 }
12737 pHddCtx->isPnoEnable = TRUE;
12738
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053012739 pPnoRequest = (tpSirPNOScanReq) vos_mem_malloc(sizeof (tSirPNOScanReq));
12740 if (NULL == pPnoRequest)
12741 {
12742 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
12743 "%s: vos_mem_malloc failed", __func__);
c_hpothu37f21312014-04-09 21:49:54 +053012744 pHddCtx->isPnoEnable = FALSE;
Kamath Vinayakba5313f2013-08-22 15:52:39 +053012745 return -ENOMEM;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053012746 }
12747
Madan Mohan Koyyalamudic3f04352013-09-26 19:21:48 +053012748 memset(pPnoRequest, 0, sizeof (tSirPNOScanReq));
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053012749 pPnoRequest->enable = 1; /*Enable PNO */
12750 pPnoRequest->ucNetworksCount = request->n_match_sets;
12751
12752 if (( !pPnoRequest->ucNetworksCount ) ||
12753 ( pPnoRequest->ucNetworksCount > SIR_PNO_MAX_SUPP_NETWORKS ))
12754 {
12755 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Sushant Kaushik1e406c32014-05-09 15:57:52 +053012756 "%s: Network input is not correct %d Max Network supported is %d",
12757 __func__, pPnoRequest->ucNetworksCount,
12758 SIR_PNO_MAX_SUPP_NETWORKS);
Kamath Vinayakba5313f2013-08-22 15:52:39 +053012759 ret = -EINVAL;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053012760 goto error;
12761 }
12762
12763 if ( SIR_PNO_MAX_NETW_CHANNELS_EX < request->n_channels )
12764 {
12765 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Nirav Shah80830bf2013-12-31 16:35:12 +053012766 "%s: Incorrect number of channels %d",
12767 __func__, request->n_channels);
Kamath Vinayakba5313f2013-08-22 15:52:39 +053012768 ret = -EINVAL;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053012769 goto error;
12770 }
12771
12772 /* Framework provides one set of channels(all)
12773 * common for all saved profile */
12774 if (0 != ccmCfgGetStr(hHal, WNI_CFG_VALID_CHANNEL_LIST,
12775 channels_allowed, &num_channels_allowed))
12776 {
12777 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
12778 "%s: failed to get valid channel list", __func__);
Kamath Vinayakba5313f2013-08-22 15:52:39 +053012779 ret = -EINVAL;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053012780 goto error;
12781 }
12782 /* Checking each channel against allowed channel list */
12783 num_ch = 0;
Nirav Shah80830bf2013-12-31 16:35:12 +053012784 if (request->n_channels)
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053012785 {
Nirav Shah80830bf2013-12-31 16:35:12 +053012786 char chList [(request->n_channels*5)+1];
12787 int len;
12788 for (i = 0, len = 0; i < request->n_channels; i++)
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053012789 {
Nirav Shah80830bf2013-12-31 16:35:12 +053012790 for (indx = 0; indx < num_channels_allowed; indx++)
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053012791 {
Nirav Shah80830bf2013-12-31 16:35:12 +053012792 if (request->channels[i]->hw_value == channels_allowed[indx])
12793 {
12794 valid_ch[num_ch++] = request->channels[i]->hw_value;
12795 len += snprintf(chList+len, 5, "%d ",
12796 request->channels[i]->hw_value);
12797 break ;
12798 }
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053012799 }
12800 }
Nirav Shah80830bf2013-12-31 16:35:12 +053012801 hddLog(VOS_TRACE_LEVEL_INFO,"Channel-List: %s ", chList);
12802 }
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053012803
12804 /* Filling per profile params */
12805 for (i = 0; i < pPnoRequest->ucNetworksCount; i++)
12806 {
12807 pPnoRequest->aNetworks[i].ssId.length =
12808 request->match_sets[i].ssid.ssid_len;
12809
12810 if (( 0 == pPnoRequest->aNetworks[i].ssId.length ) ||
12811 ( pPnoRequest->aNetworks[i].ssId.length > 32 ) )
12812 {
12813 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Nirav Shah80830bf2013-12-31 16:35:12 +053012814 "%s: SSID Len %d is not correct for network %d",
12815 __func__, pPnoRequest->aNetworks[i].ssId.length, i);
Kamath Vinayakba5313f2013-08-22 15:52:39 +053012816 ret = -EINVAL;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053012817 goto error;
12818 }
12819
12820 memcpy(pPnoRequest->aNetworks[i].ssId.ssId,
12821 request->match_sets[i].ssid.ssid,
12822 request->match_sets[i].ssid.ssid_len);
Sushant Kaushik1e406c32014-05-09 15:57:52 +053012823 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
12824 "%s: SSID of network %d is %s ", __func__,
12825 i, pPnoRequest->aNetworks[i].ssId.ssId);
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053012826 pPnoRequest->aNetworks[i].authentication = 0; /*eAUTH_TYPE_ANY*/
12827 pPnoRequest->aNetworks[i].encryption = 0; /*eED_ANY*/
12828 pPnoRequest->aNetworks[i].bcastNetwType = 0; /*eBCAST_UNKNOWN*/
12829
12830 /*Copying list of valid channel into request */
12831 memcpy(pPnoRequest->aNetworks[i].aChannels, valid_ch, num_ch);
12832 pPnoRequest->aNetworks[i].ucChannelCount = num_ch;
12833
12834 pPnoRequest->aNetworks[i].rssiThreshold = 0; //Default value
12835 }
12836
Mahesh A Saptasagar7bd6ad42014-07-21 18:56:33 +053012837 for (i = 0; i < request->n_ssids; i++)
12838 {
12839 j = 0;
12840 while (j < pPnoRequest->ucNetworksCount)
12841 {
12842 if ((pPnoRequest->aNetworks[j].ssId.length ==
12843 request->ssids[i].ssid_len) &&
12844 (0 == memcmp(pPnoRequest->aNetworks[j].ssId.ssId,
12845 request->ssids[i].ssid,
12846 pPnoRequest->aNetworks[j].ssId.length)))
12847 {
12848 pPnoRequest->aNetworks[j].bcastNetwType = eBCAST_HIDDEN;
12849 break;
12850 }
12851 j++;
12852 }
12853 }
12854 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
12855 "Number of hidden networks being Configured = %d",
12856 request->n_ssids);
Madan Mohan Koyyalamudia7765d52013-09-18 16:49:56 +053012857 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Jeff Johnson59a121e2013-11-30 09:46:08 -080012858 "request->ie_len = %zu", request->ie_len);
Madan Mohan Koyyalamudia7765d52013-09-18 16:49:56 +053012859 if ((0 < request->ie_len) && (NULL != request->ie))
12860 {
12861 pPnoRequest->us24GProbeTemplateLen = request->ie_len;
12862 memcpy(&pPnoRequest->p24GProbeTemplate, request->ie,
12863 pPnoRequest->us24GProbeTemplateLen);
12864
12865 pPnoRequest->us5GProbeTemplateLen = request->ie_len;
12866 memcpy(&pPnoRequest->p5GProbeTemplate, request->ie,
12867 pPnoRequest->us5GProbeTemplateLen);
12868 }
12869
Madan Mohan Koyyalamudi1d16f462013-08-27 16:25:34 +053012870 /* Driver gets only one time interval which is hardcoded in
12871 * supplicant for 10000ms. Taking power consumption into account 6 timers
12872 * will be used, Timervalue is increased exponentially i.e 10,20,40,
12873 * 80,160,320 secs. And number of scan cycle for each timer
12874 * is configurable through INI param gPNOScanTimerRepeatValue.
12875 * If it is set to 0 only one timer will be used and PNO scan cycle
12876 * will be repeated after each interval specified by supplicant
12877 * till PNO is disabled.
12878 */
12879 if (0 == pHddCtx->cfg_ini->configPNOScanTimerRepeatValue)
12880 pPnoRequest->scanTimers.ucScanTimersCount = HDD_PNO_SCAN_TIMERS_SET_ONE;
12881 else
12882 pPnoRequest->scanTimers.ucScanTimersCount =
12883 HDD_PNO_SCAN_TIMERS_SET_MULTIPLE;
12884
12885 tempInterval = (request->interval)/1000;
12886 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
12887 "Base scan interval = %d PNOScanTimerRepeatValue = %d",
12888 tempInterval, pHddCtx->cfg_ini->configPNOScanTimerRepeatValue);
12889 for ( i = 0; i < pPnoRequest->scanTimers.ucScanTimersCount; i++)
12890 {
12891 pPnoRequest->scanTimers.aTimerValues[i].uTimerRepeat =
12892 pHddCtx->cfg_ini->configPNOScanTimerRepeatValue;
12893 pPnoRequest->scanTimers.aTimerValues[i].uTimerValue = tempInterval;
12894 tempInterval *= 2;
12895 }
12896 //Repeat last timer until pno disabled.
12897 pPnoRequest->scanTimers.aTimerValues[i-1].uTimerRepeat = 0;
12898
Madan Mohan Koyyalamudid206c7b2013-09-26 22:54:51 +053012899 pPnoRequest->modePNO = SIR_PNO_MODE_IMMEDIATE;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053012900
Vinay Krishna Erannaf0e523b2014-03-01 21:00:16 +053012901 INIT_COMPLETION(pAdapter->pno_comp_var);
12902 pPnoRequest->statusCallback = hdd_cfg80211_sched_scan_start_status_cb;
12903 pPnoRequest->callbackContext = pAdapter;
12904 pAdapter->pno_req_status = 0;
12905
Nirav Shah80830bf2013-12-31 16:35:12 +053012906 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
12907 "SessionId %d, enable %d, modePNO %d, ucScanTimersCount %d",
12908 pAdapter->sessionId, pPnoRequest->enable, pPnoRequest->modePNO,
12909 pPnoRequest->scanTimers.ucScanTimersCount);
12910
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053012911 status = sme_SetPreferredNetworkList(WLAN_HDD_GET_HAL_CTX(pAdapter),
12912 pPnoRequest, pAdapter->sessionId,
12913 hdd_cfg80211_sched_scan_done_callback, pAdapter);
12914 if (eHAL_STATUS_SUCCESS != status)
12915 {
12916 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Nirav Shah80830bf2013-12-31 16:35:12 +053012917 "%s: Failed to enable PNO", __func__);
Kamath Vinayakba5313f2013-08-22 15:52:39 +053012918 ret = -EINVAL;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053012919 goto error;
12920 }
12921
Vinay Krishna Erannaf0e523b2014-03-01 21:00:16 +053012922 ret = wait_for_completion_timeout(
12923 &pAdapter->pno_comp_var,
12924 msecs_to_jiffies(WLAN_WAIT_TIME_PNO));
12925 if (0 >= ret)
12926 {
12927 // Did not receive the response for PNO enable in time.
12928 // Assuming the PNO enable was success.
12929 // Returning error from here, because we timeout, results
12930 // in side effect of Wifi (Wifi Setting) not to work.
12931 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
12932 FL("Timed out waiting for PNO to be Enabled"));
12933 ret = 0;
12934 goto error;
12935 }
12936
c_hpothu3c986b22014-07-09 14:45:09 +053012937 vos_mem_free(pPnoRequest);
Vinay Krishna Erannaf0e523b2014-03-01 21:00:16 +053012938 ret = pAdapter->pno_req_status;
c_hpothu37f21312014-04-09 21:49:54 +053012939 return ret;
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053012940
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053012941error:
Vinay Krishna Erannaf0e523b2014-03-01 21:00:16 +053012942 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
12943 FL("PNO scanRequest offloaded ret = %d"), ret);
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053012944 vos_mem_free(pPnoRequest);
c_hpothu37f21312014-04-09 21:49:54 +053012945 pHddCtx->isPnoEnable = FALSE;
Kamath Vinayakba5313f2013-08-22 15:52:39 +053012946 return ret;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053012947}
12948
12949/*
Mahesh A Saptasagar6cc38562014-05-23 21:22:17 +053012950 * FUNCTION: wlan_hdd_cfg80211_sched_scan_start
12951 * NL interface to enable PNO
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053012952 */
Mahesh A Saptasagar6cc38562014-05-23 21:22:17 +053012953static int wlan_hdd_cfg80211_sched_scan_start(struct wiphy *wiphy,
12954 struct net_device *dev, struct cfg80211_sched_scan_request *request)
12955{
12956 int ret;
12957
12958 vos_ssr_protect(__func__);
12959 ret = __wlan_hdd_cfg80211_sched_scan_start(wiphy, dev, request);
12960 vos_ssr_unprotect(__func__);
12961
12962 return ret;
12963}
12964
12965/*
12966 * FUNCTION: __wlan_hdd_cfg80211_sched_scan_stop
12967 * Function to disable PNO
12968 */
12969static int __wlan_hdd_cfg80211_sched_scan_stop(struct wiphy *wiphy,
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053012970 struct net_device *dev)
12971{
12972 eHalStatus status = eHAL_STATUS_FAILURE;
12973 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
12974 hdd_context_t *pHddCtx;
12975 tHalHandle hHal;
12976 tpSirPNOScanReq pPnoRequest = NULL;
Kamath Vinayakba5313f2013-08-22 15:52:39 +053012977 int ret = 0;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053012978
12979 ENTER();
12980
12981 if (NULL == pAdapter)
12982 {
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053012983 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053012984 "%s: HDD adapter is Null", __func__);
12985 return -ENODEV;
12986 }
12987
12988 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053012989
Kamath Vinayakba5313f2013-08-22 15:52:39 +053012990 if (NULL == pHddCtx)
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053012991 {
Gopichand Nakkalac005b7c2013-05-14 16:04:14 +053012992 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Kamath Vinayakba5313f2013-08-22 15:52:39 +053012993 "%s: HDD context is Null", __func__);
12994 return -ENODEV;
12995 }
12996
12997 /* The return 0 is intentional when isLogpInProgress and
12998 * isLoadUnloadInProgress. We did observe a crash due to a return of
12999 * failure in sched_scan_stop , especially for a case where the unload
13000 * of the happens at the same time. The function __cfg80211_stop_sched_scan
13001 * was clearing rdev->sched_scan_req only when the sched_scan_stop returns
13002 * success. If it returns a failure , then its next invocation due to the
13003 * clean up of the second interface will have the dev pointer corresponding
13004 * to the first one leading to a crash.
13005 */
13006 if (pHddCtx->isLogpInProgress)
13007 {
13008 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
13009 "%s: LOGP in Progress. Ignore!!!", __func__);
13010 return ret;
13011 }
13012
Mihir Shete18156292014-03-11 15:38:30 +053013013 if (WLAN_HDD_IS_LOAD_UNLOAD_IN_PROGRESS(pHddCtx))
Kamath Vinayakba5313f2013-08-22 15:52:39 +053013014 {
13015 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
13016 "%s: Unloading/Loading in Progress. Ignore!!!", __func__);
13017 return ret;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053013018 }
13019
13020 hHal = WLAN_HDD_GET_HAL_CTX(pAdapter);
13021 if (NULL == hHal)
13022 {
13023 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
13024 "%s: HAL context is Null!!!", __func__);
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053013025 return -EINVAL;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053013026 }
13027
13028 pPnoRequest = (tpSirPNOScanReq) vos_mem_malloc(sizeof (tSirPNOScanReq));
13029 if (NULL == pPnoRequest)
13030 {
13031 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
13032 "%s: vos_mem_malloc failed", __func__);
Kamath Vinayakba5313f2013-08-22 15:52:39 +053013033 return -ENOMEM;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053013034 }
13035
13036 memset(pPnoRequest, 0, sizeof (tSirPNOScanReq));
13037 pPnoRequest->enable = 0; /* Disable PNO */
13038 pPnoRequest->ucNetworksCount = 0;
13039
13040 status = sme_SetPreferredNetworkList(hHal, pPnoRequest,
13041 pAdapter->sessionId,
13042 NULL, pAdapter);
13043 if (eHAL_STATUS_SUCCESS != status)
13044 {
13045 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
13046 "Failed to disabled PNO");
Kamath Vinayakba5313f2013-08-22 15:52:39 +053013047 ret = -EINVAL;
Vinay Krishna Erannaf0e523b2014-03-01 21:00:16 +053013048 goto error;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053013049 }
c_hpothu37f21312014-04-09 21:49:54 +053013050 pHddCtx->isPnoEnable = FALSE;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053013051
Vinay Krishna Erannaf0e523b2014-03-01 21:00:16 +053013052error:
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053013053 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Vinay Krishna Erannaf0e523b2014-03-01 21:00:16 +053013054 FL("PNO scan disabled ret = %d"), ret);
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053013055 vos_mem_free(pPnoRequest);
13056
13057 EXIT();
Kamath Vinayakba5313f2013-08-22 15:52:39 +053013058 return ret;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053013059}
13060
Mahesh A Saptasagar6cc38562014-05-23 21:22:17 +053013061/*
13062 * FUNCTION: wlan_hdd_cfg80211_sched_scan_stop
13063 * NL interface to disable PNO
13064 */
13065static int wlan_hdd_cfg80211_sched_scan_stop(struct wiphy *wiphy,
13066 struct net_device *dev)
13067{
13068 int ret;
13069
13070 vos_ssr_protect(__func__);
13071 ret = __wlan_hdd_cfg80211_sched_scan_stop(wiphy, dev);
13072 vos_ssr_unprotect(__func__);
13073
13074 return ret;
13075}
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053013076#endif /*FEATURE_WLAN_SCAN_PNO*/
13077
13078
Mohit Khanna698ba2a2012-12-04 15:08:18 -080013079#ifdef FEATURE_WLAN_TDLS
Sunil Dutt Undekarieacac6f2014-03-21 14:08:53 +053013080#if TDLS_MGMT_VERSION2
Mohit Khanna698ba2a2012-12-04 15:08:18 -080013081static int wlan_hdd_cfg80211_tdls_mgmt(struct wiphy *wiphy, struct net_device *dev,
13082 u8 *peer, u8 action_code, u8 dialog_token,
Sunil Dutt Undekarieacac6f2014-03-21 14:08:53 +053013083 u16 status_code, u32 peer_capability, const u8 *buf, size_t len)
13084#else
13085static int wlan_hdd_cfg80211_tdls_mgmt(struct wiphy *wiphy, struct net_device *dev,
13086 u8 *peer, u8 action_code, u8 dialog_token,
13087 u16 status_code, const u8 *buf, size_t len)
13088#endif
Mohit Khanna698ba2a2012-12-04 15:08:18 -080013089{
13090
13091 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
13092 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
Mohit Khanna698ba2a2012-12-04 15:08:18 -080013093 u8 peerMac[6];
13094 VOS_STATUS status;
Gopichand Nakkala05922802013-03-14 12:23:19 -070013095 int max_sta_failed = 0;
Hoonki Leea34dd892013-02-05 22:56:02 -080013096 int responder;
Hoonki Leed37cbb32013-04-20 00:31:14 -070013097 long rc;
Sunil Dutt Undekarieacac6f2014-03-21 14:08:53 +053013098#if !(TDLS_MGMT_VERSION2)
13099 u32 peer_capability = 0;
13100#endif
Rajesh Chauhana34c6e62014-03-25 16:37:58 +053013101 tANI_U16 numCurrTdlsPeers;
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053013102
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053013103 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
13104 TRACE_CODE_HDD_CFG80211_TDLS_MGMT,
13105 pAdapter->sessionId, action_code));
Hoonki Lee11f7dda2013-02-14 16:55:44 -080013106 if (NULL == pHddCtx || NULL == pHddCtx->cfg_ini)
Mohit Khanna698ba2a2012-12-04 15:08:18 -080013107 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013108 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Mohit Khanna698ba2a2012-12-04 15:08:18 -080013109 "Invalid arguments");
13110 return -EINVAL;
13111 }
13112
Sameer Thalappil75ea31a2013-02-21 19:38:16 -080013113 if (pHddCtx->isLogpInProgress)
13114 {
13115 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
13116 "%s:LOGP in Progress. Ignore!!!", __func__);
Atul Mittal115287b2014-07-08 13:26:33 +053013117 wlan_hdd_tdls_set_link_status(pAdapter,
13118 peer,
13119 eTDLS_LINK_IDLE,
13120 eTDLS_LINK_UNSPECIFIED);
Sameer Thalappil75ea31a2013-02-21 19:38:16 -080013121 return -EBUSY;
13122 }
13123
Hoonki Lee27511902013-03-14 18:19:06 -070013124 if (eTDLS_SUPPORT_NOT_ENABLED == pHddCtx->tdls_mode)
Mohit Khanna698ba2a2012-12-04 15:08:18 -080013125 {
Hoonki Lee27511902013-03-14 18:19:06 -070013126 VOS_TRACE( VOS_MODULE_ID_HDD, TDLS_LOG_LEVEL,
13127 "%s: TDLS mode is disabled OR not enabled in FW."
13128 MAC_ADDRESS_STR " action %d declined.",
13129 __func__, MAC_ADDR_ARRAY(peer), action_code);
Mohit Khanna698ba2a2012-12-04 15:08:18 -080013130 return -ENOTSUPP;
13131 }
Lee Hoonkic1262f22013-01-24 21:59:00 -080013132
Hoonki Lee27511902013-03-14 18:19:06 -070013133 /* other than teardown frame, other mgmt frames are not sent if disabled */
13134 if (SIR_MAC_TDLS_TEARDOWN != action_code)
13135 {
13136 /* if tdls_mode is disabled to respond to peer's request */
13137 if (eTDLS_SUPPORT_DISABLED == pHddCtx->tdls_mode)
13138 {
13139 VOS_TRACE( VOS_MODULE_ID_HDD, TDLS_LOG_LEVEL,
13140 "%s: " MAC_ADDRESS_STR
Gopichand Nakkala34d1b062013-03-19 15:28:33 -070013141 " TDLS mode is disabled. action %d declined.",
13142 __func__, MAC_ADDR_ARRAY(peer), action_code);
Hoonki Lee27511902013-03-14 18:19:06 -070013143
13144 return -ENOTSUPP;
13145 }
Agarwal Ashish4b87f922014-06-18 03:03:21 +053013146
13147 if (vos_max_concurrent_connections_reached())
13148 {
13149 hddLog(VOS_TRACE_LEVEL_INFO, FL("Reached max concurrent connections"));
13150 return -EINVAL;
13151 }
Hoonki Lee27511902013-03-14 18:19:06 -070013152 }
13153
Gopichand Nakkalab977a972013-02-18 19:15:09 -080013154 if (WLAN_IS_TDLS_SETUP_ACTION(action_code))
13155 {
Madan Mohan Koyyalamudi96797442013-10-08 16:04:42 +053013156 if (NULL != wlan_hdd_tdls_is_progress(pHddCtx, peer, TRUE))
Gopichand Nakkalab977a972013-02-18 19:15:09 -080013157 {
13158 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Gopichand Nakkalac87400e2013-03-13 18:51:00 -070013159 "%s: " MAC_ADDRESS_STR
Gopichand Nakkala34d1b062013-03-19 15:28:33 -070013160 " TDLS setup is ongoing. action %d declined.",
13161 __func__, MAC_ADDR_ARRAY(peer), action_code);
13162 return -EPERM;
Gopichand Nakkalab977a972013-02-18 19:15:09 -080013163 }
13164 }
13165
Hoonki Lee11f7dda2013-02-14 16:55:44 -080013166 if (SIR_MAC_TDLS_SETUP_REQ == action_code ||
13167 SIR_MAC_TDLS_SETUP_RSP == action_code )
Lee Hoonkic1262f22013-01-24 21:59:00 -080013168 {
Rajesh Chauhana34c6e62014-03-25 16:37:58 +053013169 numCurrTdlsPeers = wlan_hdd_tdlsConnectedPeers(pAdapter);
13170 if (HDD_MAX_NUM_TDLS_STA <= numCurrTdlsPeers)
Lee Hoonkic1262f22013-01-24 21:59:00 -080013171 {
13172 /* supplicant still sends tdls_mgmt(SETUP_REQ) even after
13173 we return error code at 'add_station()'. Hence we have this
13174 check again in addtion to add_station().
13175 Anyway, there is no hard to double-check. */
Hoonki Lee11f7dda2013-02-14 16:55:44 -080013176 if (SIR_MAC_TDLS_SETUP_REQ == action_code)
Lee Hoonkic1262f22013-01-24 21:59:00 -080013177 {
Gopichand Nakkalac87400e2013-03-13 18:51:00 -070013178 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
13179 "%s: " MAC_ADDRESS_STR
Rajesh Chauhana34c6e62014-03-25 16:37:58 +053013180 " TDLS Max peer already connected. action (%d) declined. Num of peers (%d), Max allowed (%d).",
13181 __func__, MAC_ADDR_ARRAY(peer), action_code,
13182 numCurrTdlsPeers, HDD_MAX_NUM_TDLS_STA);
Sunil Dutt388ac8f2013-11-28 18:06:52 +053013183 return -EINVAL;
Lee Hoonkic1262f22013-01-24 21:59:00 -080013184 }
13185 else
13186 {
Gopichand Nakkalab977a972013-02-18 19:15:09 -080013187 /* maximum reached. tweak to send error code to peer and return
13188 error code to supplicant */
Lee Hoonkic1262f22013-01-24 21:59:00 -080013189 status_code = eSIR_MAC_UNSPEC_FAILURE_STATUS;
Gopichand Nakkalac87400e2013-03-13 18:51:00 -070013190 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
13191 "%s: " MAC_ADDRESS_STR
Rajesh Chauhana34c6e62014-03-25 16:37:58 +053013192 " TDLS Max peer already connected, send response status (%d). Num of peers (%d), Max allowed (%d).",
13193 __func__, MAC_ADDR_ARRAY(peer), status_code,
13194 numCurrTdlsPeers, HDD_MAX_NUM_TDLS_STA);
Gopichand Nakkala05922802013-03-14 12:23:19 -070013195 max_sta_failed = -EPERM;
Gopichand Nakkalab977a972013-02-18 19:15:09 -080013196 /* fall through to send setup resp with failure status
13197 code */
Lee Hoonkic1262f22013-01-24 21:59:00 -080013198 }
13199 }
Hoonki Lee11f7dda2013-02-14 16:55:44 -080013200 else
13201 {
13202 hddTdlsPeer_t *pTdlsPeer;
Madan Mohan Koyyalamudi96797442013-10-08 16:04:42 +053013203 pTdlsPeer = wlan_hdd_tdls_find_peer(pAdapter, peer, TRUE);
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -070013204 if (pTdlsPeer && TDLS_IS_CONNECTED(pTdlsPeer))
Hoonki Lee11f7dda2013-02-14 16:55:44 -080013205 {
Gopichand Nakkalac87400e2013-03-13 18:51:00 -070013206 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Gopichand Nakkala34d1b062013-03-19 15:28:33 -070013207 "%s:" MAC_ADDRESS_STR " already connected. action %d declined.",
13208 __func__, MAC_ADDR_ARRAY(peer), action_code);
Hoonki Lee11f7dda2013-02-14 16:55:44 -080013209 return -EPERM;
13210 }
13211 }
Lee Hoonkic1262f22013-01-24 21:59:00 -080013212 }
Hoonki Lee11f7dda2013-02-14 16:55:44 -080013213 vos_mem_copy(peerMac, peer, 6);
Mohit Khanna698ba2a2012-12-04 15:08:18 -080013214
Hoonki Lee1090c6a2013-01-16 17:40:54 -080013215#ifdef WLAN_FEATURE_TDLS_DEBUG
13216 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Arun Kumar Khandavalli9fb625e2014-03-17 16:07:40 +053013217 "%s: " MAC_ADDRESS_STR " action %d, dialog_token %d status %d, len = %zu",
Gopichand Nakkalac87400e2013-03-13 18:51:00 -070013218 "tdls_mgmt", MAC_ADDR_ARRAY(peer),
13219 action_code, dialog_token, status_code, len);
Hoonki Lee1090c6a2013-01-16 17:40:54 -080013220#endif
Mohit Khanna698ba2a2012-12-04 15:08:18 -080013221
Hoonki Leea34dd892013-02-05 22:56:02 -080013222 /*Except teardown responder will not be used so just make 0*/
13223 responder = 0;
Hoonki Lee11f7dda2013-02-14 16:55:44 -080013224 if (SIR_MAC_TDLS_TEARDOWN == action_code)
Hoonki Leea34dd892013-02-05 22:56:02 -080013225 {
Gopichand Nakkala97a65fd2013-04-16 16:59:38 -070013226
13227 hddTdlsPeer_t *pTdlsPeer;
Madan Mohan Koyyalamudi96797442013-10-08 16:04:42 +053013228 pTdlsPeer = wlan_hdd_tdls_find_peer(pAdapter, peerMac, TRUE);
Gopichand Nakkala97a65fd2013-04-16 16:59:38 -070013229
13230 if(pTdlsPeer && TDLS_IS_CONNECTED(pTdlsPeer))
13231 responder = pTdlsPeer->is_responder;
13232 else
Hoonki Leea34dd892013-02-05 22:56:02 -080013233 {
Gopichand Nakkala97a65fd2013-04-16 16:59:38 -070013234 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Arun Kumar Khandavalli9fb625e2014-03-17 16:07:40 +053013235 "%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 -070013236 __func__, MAC_ADDR_ARRAY(peer), (NULL == pTdlsPeer) ? -1 : pTdlsPeer->link_status,
13237 dialog_token, status_code, len);
13238 return -EPERM;
Hoonki Leea34dd892013-02-05 22:56:02 -080013239 }
Mohit Khanna698ba2a2012-12-04 15:08:18 -080013240 }
Mohit Khanna698ba2a2012-12-04 15:08:18 -080013241
Gopichand Nakkala2f1ff152013-07-01 11:27:43 +053013242 /* For explicit trigger of DIS_REQ come out of BMPS for
13243 successfully receiving DIS_RSP from peer. */
Hoonki Lee14621352013-04-16 17:51:19 -070013244 if ((SIR_MAC_TDLS_SETUP_RSP == action_code) ||
Gopichand Nakkala2f1ff152013-07-01 11:27:43 +053013245 (SIR_MAC_TDLS_DIS_RSP == action_code) ||
13246 (SIR_MAC_TDLS_DIS_REQ == action_code))
Hoonki Lee14621352013-04-16 17:51:19 -070013247 {
13248 if (TRUE == sme_IsPmcBmps(WLAN_HDD_GET_HAL_CTX(pAdapter)))
13249 {
13250 VOS_TRACE( VOS_MODULE_ID_HDD, TDLS_LOG_LEVEL,
Gopichand Nakkala2f1ff152013-07-01 11:27:43 +053013251 "%s: Sending frame action_code %u.Disable BMPS", __func__, action_code);
Hoonki Lee14621352013-04-16 17:51:19 -070013252 hdd_disable_bmps_imps(pHddCtx, WLAN_HDD_INFRA_STATION);
13253 }
Gopichand Nakkala2f1ff152013-07-01 11:27:43 +053013254 if (SIR_MAC_TDLS_DIS_REQ != action_code)
13255 wlan_hdd_tdls_set_cap(pAdapter, peerMac, eTDLS_CAP_SUPPORTED);
Hoonki Lee14621352013-04-16 17:51:19 -070013256 }
13257
Hoonki Lee5305c3a2013-04-29 23:28:59 -070013258 /* make sure doesn't call send_mgmt() while it is pending */
13259 if (TDLS_CTX_MAGIC == pAdapter->mgmtTxCompletionStatus)
13260 {
13261 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Arif Hussain6d2a3322013-11-17 19:50:10 -080013262 "%s: " MAC_ADDRESS_STR " action %d couldn't sent, as one is pending. return EBUSY",
Hoonki Lee5305c3a2013-04-29 23:28:59 -070013263 __func__, MAC_ADDR_ARRAY(peer), action_code);
13264 return -EBUSY;
13265 }
13266
13267 pAdapter->mgmtTxCompletionStatus = TDLS_CTX_MAGIC;
Gopichand Nakkalab977a972013-02-18 19:15:09 -080013268 INIT_COMPLETION(pAdapter->tdls_mgmt_comp);
13269
Mohit Khanna698ba2a2012-12-04 15:08:18 -080013270 status = sme_SendTdlsMgmtFrame(WLAN_HDD_GET_HAL_CTX(pAdapter), pAdapter->sessionId,
Pradeep Reddy POTTETIca171f82014-03-21 14:17:35 +053013271 peerMac, action_code, dialog_token, status_code, peer_capability, (tANI_U8 *)buf, len, responder);
Mohit Khanna698ba2a2012-12-04 15:08:18 -080013272
Gopichand Nakkalab977a972013-02-18 19:15:09 -080013273 if (VOS_STATUS_SUCCESS != status)
13274 {
Mohit Khanna698ba2a2012-12-04 15:08:18 -080013275 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
13276 "%s: sme_SendTdlsMgmtFrame failed!", __func__);
Hoonki Lee5305c3a2013-04-29 23:28:59 -070013277 pAdapter->mgmtTxCompletionStatus = FALSE;
Hoonki Lee14621352013-04-16 17:51:19 -070013278 wlan_hdd_tdls_check_bmps(pAdapter);
Sunil Dutt388ac8f2013-11-28 18:06:52 +053013279 return -EINVAL;
Mohit Khanna698ba2a2012-12-04 15:08:18 -080013280 }
13281
Hoonki Leed37cbb32013-04-20 00:31:14 -070013282 rc = wait_for_completion_interruptible_timeout(&pAdapter->tdls_mgmt_comp,
13283 msecs_to_jiffies(WAIT_TIME_TDLS_MGMT));
13284
13285 if ((rc <= 0) || (TRUE != pAdapter->mgmtTxCompletionStatus))
Gopichand Nakkalab977a972013-02-18 19:15:09 -080013286 {
Hoonki Leed37cbb32013-04-20 00:31:14 -070013287 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Jeff Johnson0299d0a2013-10-30 12:37:43 -070013288 "%s: Mgmt Tx Completion failed status %ld TxCompletion %u",
Hoonki Leed37cbb32013-04-20 00:31:14 -070013289 __func__, rc, pAdapter->mgmtTxCompletionStatus);
Hoonki Lee5305c3a2013-04-29 23:28:59 -070013290 pAdapter->mgmtTxCompletionStatus = FALSE;
Yue Ma4f55ef32014-01-23 16:45:33 -080013291
13292 if (pHddCtx->isLogpInProgress)
13293 {
13294 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
13295 "%s: LOGP in Progress. Ignore!!!", __func__);
13296 return -EAGAIN;
13297 }
13298
Hoonki Leed37cbb32013-04-20 00:31:14 -070013299 wlan_hdd_tdls_check_bmps(pAdapter);
Sunil Dutt388ac8f2013-11-28 18:06:52 +053013300 return -EINVAL;
Gopichand Nakkalab977a972013-02-18 19:15:09 -080013301 }
13302
Gopichand Nakkala05922802013-03-14 12:23:19 -070013303 if (max_sta_failed)
Hoonki Lee14621352013-04-16 17:51:19 -070013304 {
13305 wlan_hdd_tdls_check_bmps(pAdapter);
Gopichand Nakkala05922802013-03-14 12:23:19 -070013306 return max_sta_failed;
Hoonki Lee14621352013-04-16 17:51:19 -070013307 }
Gopichand Nakkalab977a972013-02-18 19:15:09 -080013308
Hoonki Leea34dd892013-02-05 22:56:02 -080013309 if (SIR_MAC_TDLS_SETUP_RSP == action_code)
13310 {
Gopichand Nakkala4327a152013-03-04 23:22:42 -080013311 wlan_hdd_tdls_set_responder(pAdapter, peerMac, TRUE);
Hoonki Leea34dd892013-02-05 22:56:02 -080013312 }
13313 else if (SIR_MAC_TDLS_SETUP_CNF == action_code)
13314 {
Gopichand Nakkala4327a152013-03-04 23:22:42 -080013315 wlan_hdd_tdls_set_responder(pAdapter, peerMac, FALSE);
Hoonki Leea34dd892013-02-05 22:56:02 -080013316 }
Mohit Khanna698ba2a2012-12-04 15:08:18 -080013317
13318 return 0;
13319}
13320
Atul Mittal115287b2014-07-08 13:26:33 +053013321
13322int wlan_hdd_tdls_extctrl_config_peer(hdd_adapter_t *pAdapter,
13323 u8 *peer,
13324 cfg80211_exttdls_callback callback)
13325{
13326
13327 hddTdlsPeer_t *pTdlsPeer;
13328 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
13329 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
13330 " %s : NL80211_TDLS_SETUP for " MAC_ADDRESS_STR,
13331 __func__, MAC_ADDR_ARRAY(peer));
13332
13333 if ( (FALSE == pHddCtx->cfg_ini->fTDLSExternalControl) ||
13334 (FALSE == pHddCtx->cfg_ini->fEnableTDLSImplicitTrigger) ) {
13335
13336 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
13337 " %s TDLS External control and Implicit Trigger not enabled ",
13338 __func__);
13339 return -ENOTSUPP;
13340 }
13341
13342 /* To cater the requirement of establishing the TDLS link
13343 * irrespective of the data traffic , get an entry of TDLS peer.
13344 */
13345 pTdlsPeer = wlan_hdd_tdls_get_peer(pAdapter, peer);
13346 if (pTdlsPeer == NULL) {
13347 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
13348 "%s: peer " MAC_ADDRESS_STR " not existing",
13349 __func__, MAC_ADDR_ARRAY(peer));
13350 return -EINVAL;
13351 }
13352
13353 if ( 0 != wlan_hdd_tdls_set_force_peer(pAdapter, peer, TRUE) ) {
13354
13355 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
13356 " %s TDLS Add Force Peer Failed",
13357 __func__);
13358 return -EINVAL;
13359 }
13360 /*EXT TDLS*/
13361
13362 if ( 0 != wlan_hdd_set_callback(pTdlsPeer, callback) ) {
13363 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
13364 " %s TDLS set callback Failed",
13365 __func__);
13366 return -EINVAL;
13367 }
13368
13369 return(0);
13370
13371}
13372
13373int wlan_hdd_tdls_extctrl_deconfig_peer(hdd_adapter_t *pAdapter, u8 *peer)
13374{
13375
13376 hddTdlsPeer_t *pTdlsPeer;
13377 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
13378 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
13379 " %s : NL80211_TDLS_TEARDOWN for " MAC_ADDRESS_STR,
13380 __func__, MAC_ADDR_ARRAY(peer));
13381
13382 if ( (FALSE == pHddCtx->cfg_ini->fTDLSExternalControl) ||
13383 (FALSE == pHddCtx->cfg_ini->fEnableTDLSImplicitTrigger) ) {
13384
13385 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
13386 " %s TDLS External control and Implicit Trigger not enabled ",
13387 __func__);
13388 return -ENOTSUPP;
13389 }
13390
13391
13392 pTdlsPeer = wlan_hdd_tdls_find_peer(pAdapter, peer, TRUE);
13393
13394 if ( NULL == pTdlsPeer ) {
13395 hddLog(VOS_TRACE_LEVEL_INFO, "%s: " MAC_ADDRESS_STR
13396 " peer not exsting",
13397 __func__, MAC_ADDR_ARRAY(peer));
13398 return -EINVAL;
13399 }
13400 else {
13401 wlan_hdd_tdls_indicate_teardown(pAdapter, pTdlsPeer,
13402 eSIR_MAC_TDLS_TEARDOWN_UNSPEC_REASON);
13403 }
13404
13405 if ( 0 != wlan_hdd_tdls_set_force_peer(pAdapter, peer, FALSE) )
13406 return -EINVAL;
13407
13408 /*EXT TDLS*/
13409
13410 if ( 0 != wlan_hdd_set_callback(pTdlsPeer, NULL )) {
13411
13412 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
13413 " %s TDLS set callback Failed",
13414 __func__);
13415 return -EINVAL;
13416 }
13417 return(0);
13418
13419}
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053013420static int __wlan_hdd_cfg80211_tdls_oper(struct wiphy *wiphy, struct net_device *dev,
Mohit Khanna698ba2a2012-12-04 15:08:18 -080013421 u8 *peer, enum nl80211_tdls_operation oper)
13422{
13423 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
13424 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053013425 int status;
Hoonki Lee5305c3a2013-04-29 23:28:59 -070013426 hddTdlsPeer_t *pTdlsPeer;
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053013427
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053013428 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
13429 TRACE_CODE_HDD_CFG80211_TDLS_OPER,
13430 pAdapter->sessionId, oper));
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053013431 if ( NULL == peer )
Mohit Khanna698ba2a2012-12-04 15:08:18 -080013432 {
Gopichand Nakkalab977a972013-02-18 19:15:09 -080013433 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Chilam Ngc4244af2013-04-01 15:37:32 -070013434 "%s: Invalid arguments", __func__);
Mohit Khanna698ba2a2012-12-04 15:08:18 -080013435 return -EINVAL;
13436 }
Hoonki Lee1090c6a2013-01-16 17:40:54 -080013437
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053013438 status = wlan_hdd_validate_context(pHddCtx);
13439
13440 if (0 != status)
Sameer Thalappil75ea31a2013-02-21 19:38:16 -080013441 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053013442 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
13443 "%s: HDD context is not valid", __func__);
13444 return status;
Sameer Thalappil75ea31a2013-02-21 19:38:16 -080013445 }
13446
Mohit Khanna698ba2a2012-12-04 15:08:18 -080013447
13448 if( FALSE == pHddCtx->cfg_ini->fEnableTDLSSupport ||
Hoonki Lee1090c6a2013-01-16 17:40:54 -080013449 FALSE == sme_IsFeatureSupportedByFW(TDLS))
Mohit Khanna698ba2a2012-12-04 15:08:18 -080013450 {
Hoonki Lee1090c6a2013-01-16 17:40:54 -080013451 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Chilam Ngc4244af2013-04-01 15:37:32 -070013452 "TDLS Disabled in INI OR not enabled in FW. "
13453 "Cannot process TDLS commands");
Mohit Khanna698ba2a2012-12-04 15:08:18 -080013454 return -ENOTSUPP;
13455 }
13456
13457 switch (oper) {
13458 case NL80211_TDLS_ENABLE_LINK:
13459 {
Mohit Khanna698ba2a2012-12-04 15:08:18 -080013460 VOS_STATUS status;
c_hpothu6ff1c3c2013-10-01 19:01:57 +053013461 long ret;
Gopichand Nakkala79ff85d2013-05-27 17:05:29 +053013462 tCsrTdlsLinkEstablishParams tdlsLinkEstablishParams;
Mohit Khanna698ba2a2012-12-04 15:08:18 -080013463
Sunil Dutt41de4e22013-11-14 18:09:02 +053013464 pTdlsPeer = wlan_hdd_tdls_find_peer(pAdapter, peer, TRUE);
13465
13466 if ( NULL == pTdlsPeer ) {
13467 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: " MAC_ADDRESS_STR
13468 " (oper %d) not exsting. ignored",
13469 __func__, MAC_ADDR_ARRAY(peer), (int)oper);
13470 return -EINVAL;
13471 }
13472
13473 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
13474 "%s: " MAC_ADDRESS_STR " link_status %d (%s) ", "tdls_oper",
13475 MAC_ADDR_ARRAY(peer), pTdlsPeer->link_status,
13476 "NL80211_TDLS_ENABLE_LINK");
13477
Gopichand Nakkala2f4a2822013-04-17 11:22:01 -070013478 if (!TDLS_STA_INDEX_VALID(pTdlsPeer->staId))
13479 {
13480 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Invalid Staion Index %u "
13481 MAC_ADDRESS_STR " failed",
13482 __func__, pTdlsPeer->staId, MAC_ADDR_ARRAY(peer));
13483 return -EINVAL;
13484 }
13485
Hoonki Lee5305c3a2013-04-29 23:28:59 -070013486 if (eTDLS_LINK_CONNECTED != pTdlsPeer->link_status)
Gopichand Nakkalac87400e2013-03-13 18:51:00 -070013487 {
Madan Mohan Koyyalamudice419872013-09-13 19:36:52 +053013488 if (IS_ADVANCE_TDLS_ENABLE) {
Gopichand Nakkala24be5312013-07-02 16:47:12 +053013489
Madan Mohan Koyyalamudice419872013-09-13 19:36:52 +053013490 if (0 != wlan_hdd_tdls_get_link_establish_params(
13491 pAdapter, peer,&tdlsLinkEstablishParams)) {
13492 return -EINVAL;
13493 }
13494 INIT_COMPLETION(pAdapter->tdls_link_establish_req_comp);
Gopichand Nakkala79ff85d2013-05-27 17:05:29 +053013495
Madan Mohan Koyyalamudice419872013-09-13 19:36:52 +053013496 sme_SendTdlsLinkEstablishParams(WLAN_HDD_GET_HAL_CTX(pAdapter),
13497 pAdapter->sessionId, peer, &tdlsLinkEstablishParams);
13498 /* Send TDLS peer UAPSD capabilities to the firmware and
13499 * register with the TL on after the response for this operation
13500 * is received .
13501 */
13502 ret = wait_for_completion_interruptible_timeout(
13503 &pAdapter->tdls_link_establish_req_comp,
13504 msecs_to_jiffies(WAIT_TIME_TDLS_LINK_ESTABLISH_REQ));
13505 if (ret <= 0)
13506 {
13507 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
13508 "%s: Link Establish Request Faled Status %ld",
13509 __func__, ret);
13510 return -EINVAL;
13511 }
Gopichand Nakkala79ff85d2013-05-27 17:05:29 +053013512 }
Atul Mittal115287b2014-07-08 13:26:33 +053013513 wlan_hdd_tdls_set_peer_link_status(pTdlsPeer,
13514 eTDLS_LINK_CONNECTED,
13515 eTDLS_LINK_SUCCESS);
Gopichand Nakkala471708b2013-06-04 20:03:01 +053013516 /* Mark TDLS client Authenticated .*/
13517 status = WLANTL_ChangeSTAState( pHddCtx->pvosContext,
13518 pTdlsPeer->staId,
13519 WLANTL_STA_AUTHENTICATED);
Gopichand Nakkalaccd3a382013-03-19 13:56:10 -070013520 if (VOS_STATUS_SUCCESS == status)
13521 {
Hoonki Lee14621352013-04-16 17:51:19 -070013522 if (pTdlsPeer->is_responder == 0)
13523 {
13524 v_U8_t staId = (v_U8_t)pTdlsPeer->staId;
13525
13526 wlan_hdd_tdls_timer_restart(pAdapter,
13527 &pTdlsPeer->initiatorWaitTimeoutTimer,
13528 WAIT_TIME_TDLS_INITIATOR);
13529 /* suspend initiator TX until it receives direct packet from the
13530 reponder or WAIT_TIME_TDLS_INITIATOR timer expires */
13531 WLANTL_SuspendDataTx( (WLAN_HDD_GET_CTX(pAdapter))->pvosContext,
13532 &staId, NULL);
13533 }
Gopichand Nakkalaccd3a382013-03-19 13:56:10 -070013534 wlan_hdd_tdls_increment_peer_count(pAdapter);
13535 }
Gopichand Nakkalac87400e2013-03-13 18:51:00 -070013536 wlan_hdd_tdls_check_bmps(pAdapter);
Gopichand Nakkala79ff85d2013-05-27 17:05:29 +053013537
13538 /* Update TL about the UAPSD masks , to route the packets to firmware */
Gopichand Nakkala574f6d12013-06-27 19:38:43 +053013539 if ((TRUE == pHddCtx->cfg_ini->fEnableTDLSBufferSta)
13540 || pHddCtx->cfg_ini->fTDLSUapsdMask )
Gopichand Nakkala79ff85d2013-05-27 17:05:29 +053013541 {
Gopichand Nakkala574f6d12013-06-27 19:38:43 +053013542 int ac;
13543 uint8 ucAc[4] = { WLANTL_AC_VO,
13544 WLANTL_AC_VI,
13545 WLANTL_AC_BK,
13546 WLANTL_AC_BE };
13547 uint8 tlTid[4] = { 7, 5, 2, 3 } ;
13548 for(ac=0; ac < 4; ac++)
13549 {
13550 status = WLANTL_EnableUAPSDForAC( (WLAN_HDD_GET_CTX(pAdapter))->pvosContext,
13551 pTdlsPeer->staId, ucAc[ac],
13552 tlTid[ac], tlTid[ac], 0, 0,
13553 WLANTL_BI_DIR );
13554 }
Gopichand Nakkala79ff85d2013-05-27 17:05:29 +053013555 }
Gopichand Nakkalac87400e2013-03-13 18:51:00 -070013556 }
13557
Mohit Khanna698ba2a2012-12-04 15:08:18 -080013558 }
13559 break;
13560 case NL80211_TDLS_DISABLE_LINK:
Lee Hoonkic1262f22013-01-24 21:59:00 -080013561 {
Sunil Dutt41de4e22013-11-14 18:09:02 +053013562 pTdlsPeer = wlan_hdd_tdls_find_peer(pAdapter, peer, TRUE);
13563
13564 if ( NULL == pTdlsPeer ) {
13565 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: " MAC_ADDRESS_STR
13566 " (oper %d) not exsting. ignored",
13567 __func__, MAC_ADDR_ARRAY(peer), (int)oper);
13568 return -EINVAL;
13569 }
13570
13571 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
13572 "%s: " MAC_ADDRESS_STR " link_status %d (%s) ", "tdls_oper",
13573 MAC_ADDR_ARRAY(peer), pTdlsPeer->link_status,
13574 "NL80211_TDLS_DISABLE_LINK");
13575
Hoonki Lee5305c3a2013-04-29 23:28:59 -070013576 if(TDLS_STA_INDEX_VALID(pTdlsPeer->staId))
Lee Hoonkic1262f22013-01-24 21:59:00 -080013577 {
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -070013578 long status;
13579
13580 INIT_COMPLETION(pAdapter->tdls_del_station_comp);
13581
Lee Hoonkic1262f22013-01-24 21:59:00 -080013582 sme_DeleteTdlsPeerSta( WLAN_HDD_GET_HAL_CTX(pAdapter),
13583 pAdapter->sessionId, peer );
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -070013584
13585 status = wait_for_completion_interruptible_timeout(&pAdapter->tdls_del_station_comp,
13586 msecs_to_jiffies(WAIT_TIME_TDLS_DEL_STA));
13587 if (status <= 0)
13588 {
Atul Mittal115287b2014-07-08 13:26:33 +053013589 wlan_hdd_tdls_set_peer_link_status(pTdlsPeer,
13590 eTDLS_LINK_IDLE,
13591 eTDLS_LINK_UNSPECIFIED);
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -070013592 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
13593 "%s: Del station failed status %ld",
13594 __func__, status);
13595 return -EPERM;
13596 }
Atul Mittal115287b2014-07-08 13:26:33 +053013597 wlan_hdd_tdls_set_peer_link_status(pTdlsPeer,
13598 eTDLS_LINK_IDLE,
13599 eTDLS_LINK_UNSPECIFIED);
Lee Hoonkic1262f22013-01-24 21:59:00 -080013600 }
13601 else
13602 {
Gopichand Nakkalac87400e2013-03-13 18:51:00 -070013603 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
13604 "%s: TDLS Peer Station doesn't exist.", __func__);
Lee Hoonkic1262f22013-01-24 21:59:00 -080013605 }
Lee Hoonkic1262f22013-01-24 21:59:00 -080013606 }
Gopichand Nakkalac87400e2013-03-13 18:51:00 -070013607 break;
Mohit Khanna698ba2a2012-12-04 15:08:18 -080013608 case NL80211_TDLS_TEARDOWN:
Sunil Dutt41de4e22013-11-14 18:09:02 +053013609 {
Atul Mittal115287b2014-07-08 13:26:33 +053013610 status = wlan_hdd_tdls_extctrl_deconfig_peer(pAdapter, peer);
Sunil Dutt41de4e22013-11-14 18:09:02 +053013611
Atul Mittal115287b2014-07-08 13:26:33 +053013612 if (0 != status)
13613 {
13614 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
13615 "%s: Error in TDLS Teardown", __func__);
13616 return status;
Sunil Dutt41de4e22013-11-14 18:09:02 +053013617 }
Sunil Dutt41de4e22013-11-14 18:09:02 +053013618 break;
13619 }
Mohit Khanna698ba2a2012-12-04 15:08:18 -080013620 case NL80211_TDLS_SETUP:
Sunil Dutt41de4e22013-11-14 18:09:02 +053013621 {
Atul Mittal115287b2014-07-08 13:26:33 +053013622 status = wlan_hdd_tdls_extctrl_config_peer(pAdapter,
13623 peer,
13624 NULL);
Sunil Dutt41de4e22013-11-14 18:09:02 +053013625
Atul Mittal115287b2014-07-08 13:26:33 +053013626 if (0 != status)
13627 {
13628 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
13629 "%s: Error in TDLS Setup", __func__);
13630 return status;
Naresh Jayaram937abdf2013-11-26 19:50:25 +053013631 }
Naresh Jayaramdb4514b2013-11-25 18:08:10 +053013632 break;
Sunil Dutt41de4e22013-11-14 18:09:02 +053013633 }
Mohit Khanna698ba2a2012-12-04 15:08:18 -080013634 case NL80211_TDLS_DISCOVERY_REQ:
13635 /* We don't support in-driver setup/teardown/discovery */
c_hpothu6ff1c3c2013-10-01 19:01:57 +053013636 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_WARN,
13637 "%s: We don't support in-driver setup/teardown/discovery "
13638 ,__func__);
Mohit Khanna698ba2a2012-12-04 15:08:18 -080013639 return -ENOTSUPP;
13640 default:
c_hpothu6ff1c3c2013-10-01 19:01:57 +053013641 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
13642 "%s: unsupported event",__func__);
Mohit Khanna698ba2a2012-12-04 15:08:18 -080013643 return -ENOTSUPP;
13644 }
13645 return 0;
13646}
Chilam NG571c65a2013-01-19 12:27:36 +053013647
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053013648static int wlan_hdd_cfg80211_tdls_oper(struct wiphy *wiphy, struct net_device *dev,
13649 u8 *peer, enum nl80211_tdls_operation oper)
13650{
13651 int ret;
13652
13653 vos_ssr_protect(__func__);
13654 ret = __wlan_hdd_cfg80211_tdls_oper(wiphy, dev, peer, oper);
13655 vos_ssr_unprotect(__func__);
13656
13657 return ret;
13658}
13659
Chilam NG571c65a2013-01-19 12:27:36 +053013660int wlan_hdd_cfg80211_send_tdls_discover_req(struct wiphy *wiphy,
13661 struct net_device *dev, u8 *peer)
13662{
Arif Hussaina7c8e412013-11-20 11:06:42 -080013663 hddLog(VOS_TRACE_LEVEL_INFO,
13664 "tdls send discover req: "MAC_ADDRESS_STR,
13665 MAC_ADDR_ARRAY(peer));
Chilam NG571c65a2013-01-19 12:27:36 +053013666
Sunil Dutt Undekarieacac6f2014-03-21 14:08:53 +053013667#if TDLS_MGMT_VERSION2
13668 return wlan_hdd_cfg80211_tdls_mgmt(wiphy, dev, peer,
13669 WLAN_TDLS_DISCOVERY_REQUEST, 1, 0, 0, NULL, 0);
13670#else
Chilam NG571c65a2013-01-19 12:27:36 +053013671 return wlan_hdd_cfg80211_tdls_mgmt(wiphy, dev, peer,
13672 WLAN_TDLS_DISCOVERY_REQUEST, 1, 0, NULL, 0);
Sunil Dutt Undekarieacac6f2014-03-21 14:08:53 +053013673#endif
Chilam NG571c65a2013-01-19 12:27:36 +053013674}
Mohit Khanna698ba2a2012-12-04 15:08:18 -080013675#endif
13676
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053013677#ifdef WLAN_FEATURE_GTK_OFFLOAD
13678/*
13679 * FUNCTION: wlan_hdd_cfg80211_update_replayCounterCallback
13680 * Callback rountine called upon receiving response for
13681 * get offload info
13682 */
13683void wlan_hdd_cfg80211_update_replayCounterCallback(void *callbackContext,
13684 tpSirGtkOffloadGetInfoRspParams pGtkOffloadGetInfoRsp)
13685{
13686
13687 hdd_adapter_t *pAdapter = (hdd_adapter_t *)callbackContext;
Gopichand Nakkalad36ee622013-05-07 14:13:27 +053013688 tANI_U8 tempReplayCounter[8];
13689 hdd_station_ctx_t *pHddStaCtx;
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053013690
13691 ENTER();
13692
13693 if (NULL == pAdapter)
13694 {
Agarwal Ashish971c2882013-10-30 20:11:12 +053013695 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053013696 "%s: HDD adapter is Null", __func__);
13697 return ;
13698 }
13699
13700 if (NULL == pGtkOffloadGetInfoRsp)
13701 {
13702 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
13703 "%s: pGtkOffloadGetInfoRsp is Null", __func__);
13704 return ;
13705 }
13706
13707 if (VOS_STATUS_SUCCESS != pGtkOffloadGetInfoRsp->ulStatus)
13708 {
13709 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
13710 "%s: wlan Failed to get replay counter value",
13711 __func__);
13712 return ;
13713 }
13714
Gopichand Nakkalad36ee622013-05-07 14:13:27 +053013715 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
13716 /* Update replay counter */
13717 pHddStaCtx->gtkOffloadReqParams.ullKeyReplayCounter =
13718 pGtkOffloadGetInfoRsp->ullKeyReplayCounter;
13719
13720 {
13721 /* changing from little to big endian since supplicant
13722 * works on big endian format
13723 */
13724 int i;
13725 tANI_U8 *p = (tANI_U8 *)&pGtkOffloadGetInfoRsp->ullKeyReplayCounter;
13726
13727 for (i = 0; i < 8; i++)
13728 {
13729 tempReplayCounter[7-i] = (tANI_U8)p[i];
13730 }
13731 }
13732
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053013733 /* Update replay counter to NL */
13734 cfg80211_gtk_rekey_notify(pAdapter->dev, pGtkOffloadGetInfoRsp->bssId,
Gopichand Nakkalad36ee622013-05-07 14:13:27 +053013735 tempReplayCounter, GFP_KERNEL);
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053013736}
13737
13738/*
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053013739 * FUNCTION: __wlan_hdd_cfg80211_set_rekey_data
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053013740 * This function is used to offload GTK rekeying job to the firmware.
13741 */
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053013742int __wlan_hdd_cfg80211_set_rekey_data(struct wiphy *wiphy, struct net_device *dev,
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053013743 struct cfg80211_gtk_rekey_data *data)
13744{
13745 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
13746 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
13747 hdd_station_ctx_t *pHddStaCtx;
13748 tHalHandle hHal;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053013749 int result;
Gopichand Nakkalad36ee622013-05-07 14:13:27 +053013750 tSirGtkOffloadParams hddGtkOffloadReqParams;
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053013751 eHalStatus status = eHAL_STATUS_FAILURE;
13752
13753 ENTER();
13754
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053013755
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053013756 if (NULL == pAdapter)
13757 {
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053013758 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053013759 "%s: HDD adapter is Null", __func__);
13760 return -ENODEV;
13761 }
13762
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053013763 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
13764 TRACE_CODE_HDD_CFG80211_SET_REKEY_DATA,
13765 pAdapter->sessionId, pAdapter->device_mode));
13766
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053013767 result = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053013768
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053013769 if (0 != result)
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053013770 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053013771 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
13772 "%s: HDD context is not valid", __func__);
13773 return result;
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053013774 }
13775
13776 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
13777 hHal = WLAN_HDD_GET_HAL_CTX(pAdapter);
13778 if (NULL == hHal)
13779 {
13780 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
13781 "%s: HAL context is Null!!!", __func__);
13782 return -EAGAIN;
13783 }
13784
Gopichand Nakkalad36ee622013-05-07 14:13:27 +053013785 pHddStaCtx->gtkOffloadReqParams.ulFlags = GTK_OFFLOAD_ENABLE;
13786 memcpy(pHddStaCtx->gtkOffloadReqParams.aKCK, data->kck, NL80211_KCK_LEN);
13787 memcpy(pHddStaCtx->gtkOffloadReqParams.aKEK, data->kek, NL80211_KEK_LEN);
13788 memcpy(pHddStaCtx->gtkOffloadReqParams.bssId, &pHddStaCtx->conn_info.bssId,
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053013789 WNI_CFG_BSSID_LEN);
Gopichand Nakkalad36ee622013-05-07 14:13:27 +053013790 {
13791 /* changing from big to little endian since driver
13792 * works on little endian format
13793 */
13794 tANI_U8 *p =
13795 (tANI_U8 *)&pHddStaCtx->gtkOffloadReqParams.ullKeyReplayCounter;
13796 int i;
13797
13798 for (i = 0; i < 8; i++)
13799 {
13800 p[7-i] = data->replay_ctr[i];
13801 }
13802 }
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053013803
13804 if (TRUE == pHddCtx->hdd_wlan_suspended)
13805 {
13806 /* if wlan is suspended, enable GTK offload directly from here */
Gopichand Nakkalad36ee622013-05-07 14:13:27 +053013807 memcpy(&hddGtkOffloadReqParams, &pHddStaCtx->gtkOffloadReqParams,
13808 sizeof (tSirGtkOffloadParams));
13809 status = sme_SetGTKOffload(hHal, &hddGtkOffloadReqParams,
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053013810 pAdapter->sessionId);
13811
13812 if (eHAL_STATUS_SUCCESS != status)
13813 {
13814 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
13815 "%s: sme_SetGTKOffload failed, returned %d",
13816 __func__, status);
13817 return status;
13818 }
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053013819 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
13820 "%s: sme_SetGTKOffload successfull", __func__);
13821 }
13822 else
13823 {
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053013824 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
13825 "%s: wlan not suspended GTKOffload request is stored",
13826 __func__);
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053013827 }
Gopichand Nakkalad36ee622013-05-07 14:13:27 +053013828
13829 return eHAL_STATUS_SUCCESS;
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053013830}
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053013831
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053013832int wlan_hdd_cfg80211_set_rekey_data(struct wiphy *wiphy, struct net_device *dev,
13833 struct cfg80211_gtk_rekey_data *data)
13834{
13835 int ret;
13836
13837 vos_ssr_protect(__func__);
13838 ret = __wlan_hdd_cfg80211_set_rekey_data(wiphy, dev, data);
13839 vos_ssr_unprotect(__func__);
13840
13841 return ret;
13842}
13843#endif /*WLAN_FEATURE_GTK_OFFLOAD*/
Gopichand Nakkalac005b7c2013-05-14 16:04:14 +053013844/*
13845 * FUNCTION: wlan_hdd_cfg80211_set_mac_acl
13846 * This function is used to set access control policy
13847 */
13848static int wlan_hdd_cfg80211_set_mac_acl(struct wiphy *wiphy,
13849 struct net_device *dev, const struct cfg80211_acl_data *params)
13850{
13851 int i;
13852 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
13853 hdd_hostapd_state_t *pHostapdState;
13854 tsap_Config_t *pConfig;
13855 v_CONTEXT_t pVosContext = NULL;
13856 hdd_context_t *pHddCtx;
13857 int status;
13858
13859 ENTER();
13860
13861 if (NULL == pAdapter)
13862 {
13863 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
13864 "%s: HDD adapter is Null", __func__);
13865 return -ENODEV;
13866 }
13867
13868 if (NULL == params)
13869 {
13870 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
13871 "%s: params is Null", __func__);
13872 return -EINVAL;
13873 }
13874
13875 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
13876 status = wlan_hdd_validate_context(pHddCtx);
13877
13878 if (0 != status)
13879 {
13880 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
13881 "%s: HDD context is not valid", __func__);
13882 return status;
13883 }
13884
13885 pVosContext = pHddCtx->pvosContext;
13886 pHostapdState = WLAN_HDD_GET_HOSTAP_STATE_PTR(pAdapter);
13887
13888 if (NULL == pHostapdState)
13889 {
13890 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
13891 "%s: pHostapdState is Null", __func__);
13892 return -EINVAL;
13893 }
13894
13895 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,"acl policy: = %d"
13896 "no acl entries = %d", params->acl_policy, params->n_acl_entries);
13897
13898 if (WLAN_HDD_SOFTAP == pAdapter->device_mode)
13899 {
13900 pConfig = &pAdapter->sessionCtx.ap.sapConfig;
13901
13902 /* default value */
13903 pConfig->num_accept_mac = 0;
13904 pConfig->num_deny_mac = 0;
13905
13906 /**
13907 * access control policy
13908 * @NL80211_ACL_POLICY_ACCEPT_UNLESS_LISTED: Deny stations which are
13909 * listed in hostapd.deny file.
13910 * @NL80211_ACL_POLICY_DENY_UNLESS_LISTED: Allow stations which are
13911 * listed in hostapd.accept file.
13912 */
13913 if (NL80211_ACL_POLICY_DENY_UNLESS_LISTED == params->acl_policy)
13914 {
13915 pConfig->SapMacaddr_acl = eSAP_DENY_UNLESS_ACCEPTED;
13916 }
13917 else if (NL80211_ACL_POLICY_ACCEPT_UNLESS_LISTED == params->acl_policy)
13918 {
13919 pConfig->SapMacaddr_acl = eSAP_ACCEPT_UNLESS_DENIED;
13920 }
13921 else
13922 {
13923 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
13924 "%s:Acl Policy : %d is not supported",
13925 __func__, params->acl_policy);
13926 return -ENOTSUPP;
13927 }
13928
13929 if (eSAP_DENY_UNLESS_ACCEPTED == pConfig->SapMacaddr_acl)
13930 {
13931 pConfig->num_accept_mac = params->n_acl_entries;
13932 for (i = 0; i < params->n_acl_entries; i++)
13933 {
13934 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
13935 "** Add ACL MAC entry %i in WhiletList :"
13936 MAC_ADDRESS_STR, i,
13937 MAC_ADDR_ARRAY(params->mac_addrs[i].addr));
13938
13939 vos_mem_copy(&pConfig->accept_mac[i], params->mac_addrs[i].addr,
13940 sizeof(qcmacaddr));
13941 }
13942 }
13943 else if (eSAP_ACCEPT_UNLESS_DENIED == pConfig->SapMacaddr_acl)
13944 {
13945 pConfig->num_deny_mac = params->n_acl_entries;
13946 for (i = 0; i < params->n_acl_entries; i++)
13947 {
13948 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
13949 "** Add ACL MAC entry %i in BlackList :"
13950 MAC_ADDRESS_STR, i,
13951 MAC_ADDR_ARRAY(params->mac_addrs[i].addr));
13952
13953 vos_mem_copy(&pConfig->deny_mac[i], params->mac_addrs[i].addr,
13954 sizeof(qcmacaddr));
13955 }
13956 }
13957
13958 if (VOS_STATUS_SUCCESS != WLANSAP_SetMacACL(pVosContext, pConfig))
13959 {
13960 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
13961 "%s: SAP Set Mac Acl fail", __func__);
13962 return -EINVAL;
13963 }
13964 }
13965 else
13966 {
13967 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Sushant Kaushik8bc7df22014-04-09 17:55:29 +053013968 "%s: Invalid device_mode = %s (%d)",
13969 __func__, hdd_device_modetoString(pAdapter->device_mode),
13970 pAdapter->device_mode);
Gopichand Nakkalac005b7c2013-05-14 16:04:14 +053013971 return -EINVAL;
13972 }
13973
13974 return 0;
13975}
13976
Leo Chang9056f462013-08-01 19:21:11 -070013977#ifdef WLAN_NL80211_TESTMODE
13978#ifdef FEATURE_WLAN_LPHB
Leo Changd9df8aa2013-09-26 13:32:26 -070013979void wlan_hdd_cfg80211_lphb_ind_handler
Leo Chang9056f462013-08-01 19:21:11 -070013980(
13981 void *pAdapter,
13982 void *indCont
13983)
13984{
Leo Changd9df8aa2013-09-26 13:32:26 -070013985 tSirLPHBInd *lphbInd;
13986 struct sk_buff *skb;
c_hpothu73f35e62014-04-18 13:40:08 +053013987 hdd_context_t *pHddCtxt;
Leo Chang9056f462013-08-01 19:21:11 -070013988
13989 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Leo Changd9df8aa2013-09-26 13:32:26 -070013990 "LPHB indication arrived");
Leo Chang9056f462013-08-01 19:21:11 -070013991
c_hpothu73f35e62014-04-18 13:40:08 +053013992 if (pAdapter == NULL)
13993 {
13994 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
13995 "%s: pAdapter is NULL\n",__func__);
13996 return;
13997 }
13998
Leo Chang9056f462013-08-01 19:21:11 -070013999 if (NULL == indCont)
14000 {
14001 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Leo Changd9df8aa2013-09-26 13:32:26 -070014002 "LPHB IND, invalid argument");
Leo Chang9056f462013-08-01 19:21:11 -070014003 return;
14004 }
14005
c_hpothu73f35e62014-04-18 13:40:08 +053014006 pHddCtxt = (hdd_context_t *)pAdapter;
Leo Changd9df8aa2013-09-26 13:32:26 -070014007 lphbInd = (tSirLPHBInd *)indCont;
Leo Chang9056f462013-08-01 19:21:11 -070014008 skb = cfg80211_testmode_alloc_event_skb(
c_hpothu73f35e62014-04-18 13:40:08 +053014009 pHddCtxt->wiphy,
Leo Changd9df8aa2013-09-26 13:32:26 -070014010 sizeof(tSirLPHBInd),
Leo Chang9056f462013-08-01 19:21:11 -070014011 GFP_ATOMIC);
14012 if (!skb)
14013 {
14014 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
14015 "LPHB timeout, NL buffer alloc fail");
14016 return;
14017 }
14018
Leo Changac3ba772013-10-07 09:47:04 -070014019 if(nla_put_u32(skb, WLAN_HDD_TM_ATTR_CMD, WLAN_HDD_TM_CMD_WLAN_HB))
Leo Changd9df8aa2013-09-26 13:32:26 -070014020 {
14021 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
14022 "WLAN_HDD_TM_ATTR_CMD put fail");
14023 goto nla_put_failure;
14024 }
Leo Changac3ba772013-10-07 09:47:04 -070014025 if(nla_put_u32(skb, WLAN_HDD_TM_ATTR_TYPE, lphbInd->protocolType))
Leo Changd9df8aa2013-09-26 13:32:26 -070014026 {
14027 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
14028 "WLAN_HDD_TM_ATTR_TYPE put fail");
14029 goto nla_put_failure;
14030 }
Leo Changac3ba772013-10-07 09:47:04 -070014031 if(nla_put(skb, WLAN_HDD_TM_ATTR_DATA,
Leo Changd9df8aa2013-09-26 13:32:26 -070014032 sizeof(tSirLPHBInd), lphbInd))
14033 {
14034 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
14035 "WLAN_HDD_TM_ATTR_DATA put fail");
14036 goto nla_put_failure;
14037 }
Leo Chang9056f462013-08-01 19:21:11 -070014038 cfg80211_testmode_event(skb, GFP_ATOMIC);
14039 return;
14040
14041nla_put_failure:
14042 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
14043 "NLA Put fail");
14044 kfree_skb(skb);
14045
14046 return;
14047}
14048#endif /* FEATURE_WLAN_LPHB */
14049
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053014050static int __wlan_hdd_cfg80211_testmode(struct wiphy *wiphy, void *data, int len)
Leo Chang9056f462013-08-01 19:21:11 -070014051{
14052 struct nlattr *tb[WLAN_HDD_TM_ATTR_MAX + 1];
14053 int err = 0;
14054#ifdef FEATURE_WLAN_LPHB
14055 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
Leo Changd9df8aa2013-09-26 13:32:26 -070014056 eHalStatus smeStatus;
Leo Chang9056f462013-08-01 19:21:11 -070014057#endif /* FEATURE_WLAN_LPHB */
14058
14059 err = nla_parse(tb, WLAN_HDD_TM_ATTR_MAX, data, len, wlan_hdd_tm_policy);
14060 if (err)
14061 {
14062 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
14063 "%s Testmode INV ATTR", __func__);
14064 return err;
14065 }
14066
14067 if (!tb[WLAN_HDD_TM_ATTR_CMD])
14068 {
14069 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
14070 "%s Testmode INV CMD", __func__);
14071 return -EINVAL;
14072 }
14073
14074 switch (nla_get_u32(tb[WLAN_HDD_TM_ATTR_CMD]))
14075 {
14076#ifdef FEATURE_WLAN_LPHB
14077 /* Low Power Heartbeat configuration request */
14078 case WLAN_HDD_TM_CMD_WLAN_HB:
14079 {
14080 int buf_len;
14081 void *buf;
14082 tSirLPHBReq *hb_params = NULL;
Amar Singhal05852702014-02-04 14:40:00 -080014083 tSirLPHBReq *hb_params_temp = NULL;
Leo Chang9056f462013-08-01 19:21:11 -070014084
14085 if (!tb[WLAN_HDD_TM_ATTR_DATA])
14086 {
14087 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
14088 "%s Testmode INV DATA", __func__);
14089 return -EINVAL;
14090 }
14091
14092 buf = nla_data(tb[WLAN_HDD_TM_ATTR_DATA]);
14093 buf_len = nla_len(tb[WLAN_HDD_TM_ATTR_DATA]);
Amar Singhal05852702014-02-04 14:40:00 -080014094
14095 hb_params_temp =(tSirLPHBReq *)buf;
14096 if ((hb_params_temp->cmd == LPHB_SET_TCP_PARAMS_INDID) &&
14097 (hb_params_temp->params.lphbTcpParamReq.timePeriodSec == 0))
14098 return -EINVAL;
14099
Leo Chang9056f462013-08-01 19:21:11 -070014100 hb_params = (tSirLPHBReq *)vos_mem_malloc(sizeof(tSirLPHBReq));
14101 if (NULL == hb_params)
14102 {
14103 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
14104 "%s Request Buffer Alloc Fail", __func__);
14105 return -EINVAL;
14106 }
14107
14108 vos_mem_copy(hb_params, buf, buf_len);
Leo Changd9df8aa2013-09-26 13:32:26 -070014109 smeStatus = sme_LPHBConfigReq((tHalHandle)(pHddCtx->hHal),
14110 hb_params,
14111 wlan_hdd_cfg80211_lphb_ind_handler);
14112 if (eHAL_STATUS_SUCCESS != smeStatus)
Leo Chang9056f462013-08-01 19:21:11 -070014113 {
Leo Changd9df8aa2013-09-26 13:32:26 -070014114 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
14115 "LPHB Config Fail, disable");
Leo Chang9056f462013-08-01 19:21:11 -070014116 vos_mem_free(hb_params);
14117 }
Leo Chang9056f462013-08-01 19:21:11 -070014118 return 0;
14119 }
14120#endif /* FEATURE_WLAN_LPHB */
14121 default:
c_hpothu6ff1c3c2013-10-01 19:01:57 +053014122 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
14123 "%s: unsupported event",__func__);
Leo Chang9056f462013-08-01 19:21:11 -070014124 return -EOPNOTSUPP;
14125 }
14126
14127 return err;
14128}
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053014129
14130static int wlan_hdd_cfg80211_testmode(struct wiphy *wiphy, void *data, int len)
14131{
14132 int ret;
14133
14134 vos_ssr_protect(__func__);
14135 ret = __wlan_hdd_cfg80211_testmode(wiphy, data, len);
14136 vos_ssr_unprotect(__func__);
14137
14138 return ret;
14139}
Leo Chang9056f462013-08-01 19:21:11 -070014140#endif /* CONFIG_NL80211_TESTMODE */
14141
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053014142static int __wlan_hdd_cfg80211_dump_survey(struct wiphy *wiphy,
Madan Mohan Koyyalamudid9383fd2013-08-13 09:27:30 +053014143 struct net_device *dev,
14144 int idx, struct survey_info *survey)
14145{
14146 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
14147 hdd_context_t *pHddCtx;
Mihir Sheted9072e02013-08-21 17:02:29 +053014148 hdd_station_ctx_t *pHddStaCtx;
Madan Mohan Koyyalamudid9383fd2013-08-13 09:27:30 +053014149 tHalHandle halHandle;
Mihir Sheted9072e02013-08-21 17:02:29 +053014150 v_U32_t channel = 0, freq = 0; /* Initialization Required */
Madan Mohan Koyyalamudid9383fd2013-08-13 09:27:30 +053014151 v_S7_t snr,rssi;
14152 int status, i, j, filled = 0;
14153
14154 ENTER();
14155
Madan Mohan Koyyalamudid9383fd2013-08-13 09:27:30 +053014156 if (NULL == pAdapter)
14157 {
14158 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
14159 "%s: HDD adapter is Null", __func__);
14160 return -ENODEV;
14161 }
14162
14163 if (NULL == wiphy)
14164 {
14165 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
14166 "%s: wiphy is Null", __func__);
14167 return -ENODEV;
14168 }
14169
14170 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
14171 status = wlan_hdd_validate_context(pHddCtx);
14172
14173 if (0 != status)
14174 {
14175 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
14176 "%s: HDD context is not valid", __func__);
14177 return status;
14178 }
14179
Mihir Sheted9072e02013-08-21 17:02:29 +053014180 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
14181
Madan Mohan Koyyalamudid9383fd2013-08-13 09:27:30 +053014182 if (0 == pHddCtx->cfg_ini->fEnableSNRMonitoring ||
Mihir Sheted9072e02013-08-21 17:02:29 +053014183 0 != pAdapter->survey_idx ||
14184 eConnectionState_Associated != pHddStaCtx->conn_info.connState)
Madan Mohan Koyyalamudid9383fd2013-08-13 09:27:30 +053014185 {
14186 /* The survey dump ops when implemented completely is expected to
14187 * return a survey of all channels and the ops is called by the
14188 * kernel with incremental values of the argument 'idx' till it
14189 * returns -ENONET. But we can only support the survey for the
14190 * operating channel for now. survey_idx is used to track
14191 * that the ops is called only once and then return -ENONET for
14192 * the next iteration
14193 */
14194 pAdapter->survey_idx = 0;
14195 return -ENONET;
14196 }
14197
14198 halHandle = WLAN_HDD_GET_HAL_CTX(pAdapter);
14199
14200 wlan_hdd_get_snr(pAdapter, &snr);
14201 wlan_hdd_get_rssi(pAdapter, &rssi);
14202
14203 sme_GetOperationChannel(halHandle, &channel, pAdapter->sessionId);
14204 hdd_wlan_get_freq(channel, &freq);
14205
14206
14207 for (i = 0; i < IEEE80211_NUM_BANDS; i++)
14208 {
14209 if (NULL == wiphy->bands[i])
14210 {
14211 VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_INFO,
14212 "%s: wiphy->bands[i] is NULL, i = %d", __func__, i);
14213 continue;
14214 }
14215
14216 for (j = 0; j < wiphy->bands[i]->n_channels; j++)
14217 {
14218 struct ieee80211_supported_band *band = wiphy->bands[i];
14219
14220 if (band->channels[j].center_freq == (v_U16_t)freq)
14221 {
14222 survey->channel = &band->channels[j];
14223 /* The Rx BDs contain SNR values in dB for the received frames
14224 * while the supplicant expects noise. So we calculate and
14225 * return the value of noise (dBm)
14226 * SNR (dB) = RSSI (dBm) - NOISE (dBm)
14227 */
14228 survey->noise = rssi - snr;
14229 survey->filled = SURVEY_INFO_NOISE_DBM;
14230 filled = 1;
14231 }
14232 }
14233 }
14234
14235 if (filled)
14236 pAdapter->survey_idx = 1;
14237 else
14238 {
14239 pAdapter->survey_idx = 0;
14240 return -ENONET;
14241 }
14242
14243 return 0;
14244}
14245
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053014246static int wlan_hdd_cfg80211_dump_survey(struct wiphy *wiphy,
14247 struct net_device *dev,
14248 int idx, struct survey_info *survey)
14249{
14250 int ret;
14251
14252 vos_ssr_protect(__func__);
14253 ret = __wlan_hdd_cfg80211_dump_survey(wiphy, dev, idx, survey);
14254 vos_ssr_unprotect(__func__);
14255
14256 return ret;
14257}
14258
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053014259/*
Mahesh A Saptasagarbcc5b662014-06-02 21:46:23 +053014260 * FUNCTION: __wlan_hdd_cfg80211_resume_wlan
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053014261 * this is called when cfg80211 driver resume
14262 * driver updates latest sched_scan scan result(if any) to cfg80211 database
14263 */
Mahesh A Saptasagarbcc5b662014-06-02 21:46:23 +053014264int __wlan_hdd_cfg80211_resume_wlan(struct wiphy *wiphy)
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053014265{
14266 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
14267 hdd_adapter_t *pAdapter;
14268 hdd_adapter_list_node_t *pAdapterNode, *pNext;
14269 VOS_STATUS status = VOS_STATUS_SUCCESS;
14270
14271 ENTER();
14272
14273 if ( NULL == pHddCtx )
14274 {
14275 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
14276 "%s: HddCtx validation failed", __func__);
14277 return 0;
14278 }
14279
14280 if (pHddCtx->isLogpInProgress)
14281 {
14282 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
14283 "%s: LOGP in Progress. Ignore!!!", __func__);
14284 return 0;
14285 }
14286
Mihir Shete18156292014-03-11 15:38:30 +053014287 if (WLAN_HDD_IS_LOAD_UNLOAD_IN_PROGRESS(pHddCtx))
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053014288 {
14289 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
14290 "%s: Unloading/Loading in Progress. Ignore!!!", __func__);
14291 return 0;
14292 }
14293
14294 spin_lock(&pHddCtx->schedScan_lock);
14295 pHddCtx->isWiphySuspended = FALSE;
14296 if (TRUE != pHddCtx->isSchedScanUpdatePending)
14297 {
14298 spin_unlock(&pHddCtx->schedScan_lock);
14299 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
14300 "%s: Return resume is not due to PNO indication", __func__);
14301 return 0;
14302 }
14303 // Reset flag to avoid updatating cfg80211 data old results again
14304 pHddCtx->isSchedScanUpdatePending = FALSE;
14305 spin_unlock(&pHddCtx->schedScan_lock);
14306
Mahesh A Saptasagarb9c50402014-01-16 15:49:22 +053014307
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053014308 status = hdd_get_front_adapter ( pHddCtx, &pAdapterNode );
14309
14310 while ( NULL != pAdapterNode && VOS_STATUS_SUCCESS == status )
14311 {
14312 pAdapter = pAdapterNode->pAdapter;
14313 if ( (NULL != pAdapter) &&
14314 (WLAN_HDD_INFRA_STATION == pAdapter->device_mode) )
14315 {
14316 if (0 != wlan_hdd_cfg80211_update_bss(pHddCtx->wiphy, pAdapter))
Mahesh A Saptasagarb9c50402014-01-16 15:49:22 +053014317 {
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053014318 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_WARN,
14319 "%s: NO SCAN result", __func__);
Mahesh A Saptasagarb9c50402014-01-16 15:49:22 +053014320 }
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053014321 else
Mahesh A Saptasagarb9c50402014-01-16 15:49:22 +053014322 {
14323 /* Acquire wakelock to handle the case where APP's tries to
14324 * suspend immediately after updating the scan results. Whis
14325 * results in app's is in suspended state and not able to
14326 * process the connect request to AP
14327 */
14328 hdd_prevent_suspend_timeout(2000);
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053014329 cfg80211_sched_scan_results(pHddCtx->wiphy);
Mahesh A Saptasagarb9c50402014-01-16 15:49:22 +053014330 }
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053014331
14332 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
14333 "%s : cfg80211 scan result database updated", __func__);
14334
14335 return 0;
14336
14337 }
14338 status = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
14339 pAdapterNode = pNext;
14340 }
14341
14342 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
14343 "%s: Failed to find Adapter", __func__);
14344 return 0;
14345}
14346
Mahesh A Saptasagarbcc5b662014-06-02 21:46:23 +053014347int wlan_hdd_cfg80211_resume_wlan(struct wiphy *wiphy)
14348{
14349 int ret;
14350
14351 vos_ssr_protect(__func__);
14352 ret = __wlan_hdd_cfg80211_resume_wlan(wiphy);
14353 vos_ssr_unprotect(__func__);
14354
14355 return ret;
14356}
14357
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053014358/*
Mahesh A Saptasagarbcc5b662014-06-02 21:46:23 +053014359 * FUNCTION: __wlan_hdd_cfg80211_suspend_wlan
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053014360 * this is called when cfg80211 driver suspends
14361 */
Mahesh A Saptasagarbcc5b662014-06-02 21:46:23 +053014362int __wlan_hdd_cfg80211_suspend_wlan(struct wiphy *wiphy,
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053014363 struct cfg80211_wowlan *wow)
14364{
14365 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
14366
14367 ENTER();
14368 if (NULL == pHddCtx)
14369 {
14370 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
14371 "%s: HddCtx validation failed", __func__);
14372 return 0;
14373 }
14374
14375 pHddCtx->isWiphySuspended = TRUE;
14376
14377 EXIT();
14378
14379 return 0;
14380}
14381
Mahesh A Saptasagarbcc5b662014-06-02 21:46:23 +053014382int wlan_hdd_cfg80211_suspend_wlan(struct wiphy *wiphy,
14383 struct cfg80211_wowlan *wow)
14384{
14385 int ret;
14386
14387 vos_ssr_protect(__func__);
14388 ret = __wlan_hdd_cfg80211_suspend_wlan(wiphy, wow);
14389 vos_ssr_unprotect(__func__);
14390
14391 return ret;
14392}
Jeff Johnson295189b2012-06-20 16:38:30 -070014393/* cfg80211_ops */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014394static struct cfg80211_ops wlan_hdd_cfg80211_ops =
Jeff Johnson295189b2012-06-20 16:38:30 -070014395{
14396 .add_virtual_intf = wlan_hdd_add_virtual_intf,
14397 .del_virtual_intf = wlan_hdd_del_virtual_intf,
14398 .change_virtual_intf = wlan_hdd_cfg80211_change_iface,
14399 .change_station = wlan_hdd_change_station,
14400#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,4,0))
14401 .add_beacon = wlan_hdd_cfg80211_add_beacon,
14402 .del_beacon = wlan_hdd_cfg80211_del_beacon,
14403 .set_beacon = wlan_hdd_cfg80211_set_beacon,
Jeff Johnson04dd8a82012-06-29 20:41:40 -070014404#else
14405 .start_ap = wlan_hdd_cfg80211_start_ap,
14406 .change_beacon = wlan_hdd_cfg80211_change_beacon,
14407 .stop_ap = wlan_hdd_cfg80211_stop_ap,
Jeff Johnson295189b2012-06-20 16:38:30 -070014408#endif
14409 .change_bss = wlan_hdd_cfg80211_change_bss,
14410 .add_key = wlan_hdd_cfg80211_add_key,
14411 .get_key = wlan_hdd_cfg80211_get_key,
14412 .del_key = wlan_hdd_cfg80211_del_key,
14413 .set_default_key = wlan_hdd_cfg80211_set_default_key,
Jeff Johnson3bbe4bf2013-01-18 17:05:29 -080014414#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,6,0))
Jeff Johnson295189b2012-06-20 16:38:30 -070014415 .set_channel = wlan_hdd_cfg80211_set_channel,
Jeff Johnson3bbe4bf2013-01-18 17:05:29 -080014416#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070014417 .scan = wlan_hdd_cfg80211_scan,
14418 .connect = wlan_hdd_cfg80211_connect,
14419 .disconnect = wlan_hdd_cfg80211_disconnect,
14420 .join_ibss = wlan_hdd_cfg80211_join_ibss,
14421 .leave_ibss = wlan_hdd_cfg80211_leave_ibss,
14422 .set_wiphy_params = wlan_hdd_cfg80211_set_wiphy_params,
14423 .set_tx_power = wlan_hdd_cfg80211_set_txpower,
14424 .get_tx_power = wlan_hdd_cfg80211_get_txpower,
Jeff Johnson295189b2012-06-20 16:38:30 -070014425 .remain_on_channel = wlan_hdd_cfg80211_remain_on_channel,
14426 .cancel_remain_on_channel = wlan_hdd_cfg80211_cancel_remain_on_channel,
DARAM SUDHA39eede62014-02-12 11:16:40 +053014427 .mgmt_tx = wlan_hdd_mgmt_tx,
Jeff Johnson295189b2012-06-20 16:38:30 -070014428#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
14429 .mgmt_tx_cancel_wait = wlan_hdd_cfg80211_mgmt_tx_cancel_wait,
14430 .set_default_mgmt_key = wlan_hdd_set_default_mgmt_key,
14431 .set_txq_params = wlan_hdd_set_txq_params,
14432#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070014433 .get_station = wlan_hdd_cfg80211_get_station,
14434 .set_power_mgmt = wlan_hdd_cfg80211_set_power_mgmt,
14435 .del_station = wlan_hdd_cfg80211_del_station,
Jeff Johnson04dd8a82012-06-29 20:41:40 -070014436 .add_station = wlan_hdd_cfg80211_add_station,
14437#ifdef FEATURE_WLAN_LFR
14438 .set_pmksa = wlan_hdd_cfg80211_set_pmksa,
14439 .del_pmksa = wlan_hdd_cfg80211_del_pmksa,
14440 .flush_pmksa = wlan_hdd_cfg80211_flush_pmksa,
14441#endif
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070014442#if defined(WLAN_FEATURE_VOWIFI_11R) && defined(KERNEL_SUPPORT_11R_CFG80211)
14443 .update_ft_ies = wlan_hdd_cfg80211_update_ft_ies,
14444#endif
Mohit Khanna698ba2a2012-12-04 15:08:18 -080014445#ifdef FEATURE_WLAN_TDLS
14446 .tdls_mgmt = wlan_hdd_cfg80211_tdls_mgmt,
14447 .tdls_oper = wlan_hdd_cfg80211_tdls_oper,
14448#endif
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053014449#ifdef WLAN_FEATURE_GTK_OFFLOAD
14450 .set_rekey_data = wlan_hdd_cfg80211_set_rekey_data,
14451#endif /* WLAN_FEATURE_GTK_OFFLOAD */
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053014452#ifdef FEATURE_WLAN_SCAN_PNO
14453 .sched_scan_start = wlan_hdd_cfg80211_sched_scan_start,
14454 .sched_scan_stop = wlan_hdd_cfg80211_sched_scan_stop,
14455#endif /*FEATURE_WLAN_SCAN_PNO */
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053014456 .resume = wlan_hdd_cfg80211_resume_wlan,
14457 .suspend = wlan_hdd_cfg80211_suspend_wlan,
Gopichand Nakkalac005b7c2013-05-14 16:04:14 +053014458 .set_mac_acl = wlan_hdd_cfg80211_set_mac_acl,
Leo Chang9056f462013-08-01 19:21:11 -070014459#ifdef WLAN_NL80211_TESTMODE
14460 .testmode_cmd = wlan_hdd_cfg80211_testmode,
14461#endif
Madan Mohan Koyyalamudid9383fd2013-08-13 09:27:30 +053014462 .dump_survey = wlan_hdd_cfg80211_dump_survey,
Jeff Johnson295189b2012-06-20 16:38:30 -070014463};
14464