blob: b0918c1c3a72c91e40d5ff1f28f0847b64401512 [file] [log] [blame]
Jeff Johnson295189b2012-06-20 16:38:30 -07001/*
Kiet Lam842dad02014-02-18 18:44:02 -08002 * Copyright (c) 2012-2014 The Linux Foundation. All rights reserved.
3 *
4 * Previously licensed under the ISC license by Qualcomm Atheros, Inc.
5 *
6 *
7 * Permission to use, copy, modify, and/or distribute this software for
8 * any purpose with or without fee is hereby granted, provided that the
9 * above copyright notice and this permission notice appear in all
10 * copies.
11 *
12 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL
13 * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED
14 * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE
15 * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL
16 * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
17 * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
18 * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
19 * PERFORMANCE OF THIS SOFTWARE.
20 */
21
22/*
Kiet Lama7f454d2014-07-24 12:04:06 -070023 * This file was originally distributed by Qualcomm Atheros, Inc.
24 * under proprietary terms before Copyright ownership was assigned
25 * to the Linux Foundation.
Kiet Lamaa8e15a2014-02-11 23:30:06 -080026 */
Kiet Lam842dad02014-02-18 18:44:02 -080027
28
Kiet Lama7f454d2014-07-24 12:04:06 -070029
30
Jeff Johnson295189b2012-06-20 16:38:30 -070031/**========================================================================
32
33 \file wlan_hdd_cfg80211.c
34
35 \brief WLAN Host Device Driver implementation
36
Jeff Johnson295189b2012-06-20 16:38:30 -070037 ========================================================================*/
38
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -070039/**=========================================================================
Jeff Johnson295189b2012-06-20 16:38:30 -070040
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -070041 EDIT HISTORY FOR FILE
Jeff Johnson295189b2012-06-20 16:38:30 -070042
43
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -070044 This section contains comments describing changes made to the module.
45 Notice that changes are listed in reverse chronological order.
Jeff Johnson295189b2012-06-20 16:38:30 -070046
47
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -070048 $Header:$ $DateTime: $ $Author: $
Jeff Johnson295189b2012-06-20 16:38:30 -070049
50
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -070051 when who what, where, why
Jeff Johnson295189b2012-06-20 16:38:30 -070052 -------- --- --------------------------------------------------------
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -070053 21/12/09 Ashwani Created module.
Jeff Johnson295189b2012-06-20 16:38:30 -070054
55 07/06/10 Kumar Deepak Implemented cfg80211 callbacks for ANDROID
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -070056 Ganesh K
Jeff Johnson295189b2012-06-20 16:38:30 -070057 ==========================================================================*/
58
Jeff Johnson295189b2012-06-20 16:38:30 -070059
60#include <linux/version.h>
61#include <linux/module.h>
62#include <linux/kernel.h>
63#include <linux/init.h>
64#include <linux/wireless.h>
65#include <wlan_hdd_includes.h>
66#include <net/arp.h>
67#include <net/cfg80211.h>
68#include <linux/wireless.h>
69#include <wlan_hdd_wowl.h>
70#include <aniGlobal.h>
71#include "ccmApi.h"
72#include "sirParams.h"
73#include "dot11f.h"
74#include "wlan_hdd_assoc.h"
75#include "wlan_hdd_wext.h"
76#include "sme_Api.h"
77#include "wlan_hdd_p2p.h"
78#include "wlan_hdd_cfg80211.h"
79#include "wlan_hdd_hostapd.h"
80#include "sapInternal.h"
81#include "wlan_hdd_softap_tx_rx.h"
82#include "wlan_hdd_main.h"
Madan Mohan Koyyalamudid5acbf52012-11-28 01:45:08 +053083#include "wlan_hdd_assoc.h"
Gopichand Nakkala20c4c042013-04-19 22:08:55 +053084#include "wlan_hdd_power.h"
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053085#include "wlan_hdd_trace.h"
86#include "vos_types.h"
87#include "vos_trace.h"
Jeff Johnson295189b2012-06-20 16:38:30 -070088#ifdef WLAN_BTAMP_FEATURE
89#include "bap_hdd_misc.h"
90#endif
91#include <qc_sap_ioctl.h>
Mohit Khanna698ba2a2012-12-04 15:08:18 -080092#ifdef FEATURE_WLAN_TDLS
93#include "wlan_hdd_tdls.h"
Gopichand Nakkala79ff85d2013-05-27 17:05:29 +053094#include "wlan_hdd_wmm.h"
Madan Mohan Koyyalamudice419872013-09-13 19:36:52 +053095#include "wlan_qct_wda.h"
Mohit Khanna698ba2a2012-12-04 15:08:18 -080096#endif
Madan Mohan Koyylamudi64267f72013-02-05 14:07:08 +053097#include "wlan_nv.h"
Leo Chang6fe1f922013-06-07 19:21:24 -070098#include "wlan_hdd_dev_pwr.h"
Jeff Johnson295189b2012-06-20 16:38:30 -070099
100#define g_mode_rates_size (12)
101#define a_mode_rates_size (8)
102#define FREQ_BASE_80211G (2407)
103#define FREQ_BAND_DIFF_80211G (5)
Jeff Johnson04dd8a82012-06-29 20:41:40 -0700104#define MAX_SCAN_SSID 9
Kiet Lamac06e2c2013-10-23 16:25:07 +0530105#define MAX_PENDING_LOG 5
Jeff Johnson295189b2012-06-20 16:38:30 -0700106#define GET_IE_LEN_IN_BSS_DESC(lenInBss) ( lenInBss + sizeof(lenInBss) - \
krunal soni2a6a9062014-02-11 14:14:23 -0800107 ((uintptr_t)OFFSET_OF( tSirBssDescription, ieFields)))
Jeff Johnson295189b2012-06-20 16:38:30 -0700108
109#define HDD2GHZCHAN(freq, chan, flag) { \
110 .band = IEEE80211_BAND_2GHZ, \
111 .center_freq = (freq), \
112 .hw_value = (chan),\
113 .flags = (flag), \
114 .max_antenna_gain = 0 ,\
115 .max_power = 30, \
116}
117
118#define HDD5GHZCHAN(freq, chan, flag) { \
119 .band = IEEE80211_BAND_5GHZ, \
120 .center_freq = (freq), \
121 .hw_value = (chan),\
122 .flags = (flag), \
123 .max_antenna_gain = 0 ,\
124 .max_power = 30, \
125}
126
127#define HDD_G_MODE_RATETAB(rate, rate_id, flag)\
128{\
129 .bitrate = rate, \
130 .hw_value = rate_id, \
131 .flags = flag, \
132}
133
Lee Hoonkic1262f22013-01-24 21:59:00 -0800134#ifndef WLAN_FEATURE_TDLS_DEBUG
135#define TDLS_LOG_LEVEL VOS_TRACE_LEVEL_INFO
136#else
137#define TDLS_LOG_LEVEL VOS_TRACE_LEVEL_ERROR
138#endif
139
Gopichand Nakkala356fb102013-03-06 12:34:04 +0530140#ifdef WLAN_FEATURE_VOWIFI_11R
141#define WLAN_AKM_SUITE_FT_8021X 0x000FAC03
142#define WLAN_AKM_SUITE_FT_PSK 0x000FAC04
143#endif
144
Naresh Jayaram3180aa42014-02-12 21:47:26 +0530145#define HDD_CHANNEL_14 14
146
Sunil Duttc69bccb2014-05-26 21:30:20 +0530147#ifdef WLAN_FEATURE_LINK_LAYER_STATS
148/*
149 * Used to allocate the size of 4096 for the link layer stats.
150 * The size of 4096 is considered assuming that all data per
151 * respective event fit with in the limit.Please take a call
152 * on the limit based on the data requirements on link layer
153 * statistics.
154 */
155#define LL_STATS_EVENT_BUF_SIZE 4096
156#endif
Dino Mycle6fb96c12014-06-10 11:52:40 +0530157#ifdef WLAN_FEATURE_EXTSCAN
158/*
159 * Used to allocate the size of 4096 for the EXTScan NL data.
160 * The size of 4096 is considered assuming that all data per
161 * respective event fit with in the limit.Please take a call
162 * on the limit based on the data requirements.
163 */
164
165#define EXTSCAN_EVENT_BUF_SIZE 4096
166#define EXTSCAN_MAX_CACHED_RESULTS_PER_IND 32
167#endif
Sunil Duttc69bccb2014-05-26 21:30:20 +0530168
Atul Mittal115287b2014-07-08 13:26:33 +0530169/*EXT TDLS*/
170/*
171 * Used to allocate the size of 4096 for the TDLS.
172 * The size of 4096 is considered assuming that all data per
173 * respective event fit with in the limit.Please take a call
174 * on the limit based on the data requirements on link layer
175 * statistics.
176 */
177#define EXTTDLS_EVENT_BUF_SIZE 4096
178
Gopichand Nakkala747461f2013-04-24 19:24:45 +0530179static const u32 hdd_cipher_suites[] =
Jeff Johnson295189b2012-06-20 16:38:30 -0700180{
181 WLAN_CIPHER_SUITE_WEP40,
182 WLAN_CIPHER_SUITE_WEP104,
183 WLAN_CIPHER_SUITE_TKIP,
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -0800184#ifdef FEATURE_WLAN_ESE
Jeff Johnson295189b2012-06-20 16:38:30 -0700185#define WLAN_CIPHER_SUITE_KRK 0x004096ff /* use for KRK */
186 WLAN_CIPHER_SUITE_KRK,
187 WLAN_CIPHER_SUITE_CCMP,
188#else
189 WLAN_CIPHER_SUITE_CCMP,
190#endif
191#ifdef FEATURE_WLAN_WAPI
192 WLAN_CIPHER_SUITE_SMS4,
193#endif
Chet Lanctot186b5732013-03-18 10:26:30 -0700194#ifdef WLAN_FEATURE_11W
195 WLAN_CIPHER_SUITE_AES_CMAC,
196#endif
Jeff Johnson295189b2012-06-20 16:38:30 -0700197};
198
199static inline int is_broadcast_ether_addr(const u8 *addr)
200{
201 return ((addr[0] == 0xff) && (addr[1] == 0xff) && (addr[2] == 0xff) &&
202 (addr[3] == 0xff) && (addr[4] == 0xff) && (addr[5] == 0xff));
203}
204
205static struct ieee80211_channel hdd_channels_2_4_GHZ[] =
Gopichand Nakkala747461f2013-04-24 19:24:45 +0530206{
Jeff Johnson295189b2012-06-20 16:38:30 -0700207 HDD2GHZCHAN(2412, 1, 0) ,
208 HDD2GHZCHAN(2417, 2, 0) ,
209 HDD2GHZCHAN(2422, 3, 0) ,
210 HDD2GHZCHAN(2427, 4, 0) ,
211 HDD2GHZCHAN(2432, 5, 0) ,
212 HDD2GHZCHAN(2437, 6, 0) ,
213 HDD2GHZCHAN(2442, 7, 0) ,
214 HDD2GHZCHAN(2447, 8, 0) ,
215 HDD2GHZCHAN(2452, 9, 0) ,
216 HDD2GHZCHAN(2457, 10, 0) ,
217 HDD2GHZCHAN(2462, 11, 0) ,
218 HDD2GHZCHAN(2467, 12, 0) ,
219 HDD2GHZCHAN(2472, 13, 0) ,
220 HDD2GHZCHAN(2484, 14, 0) ,
221};
222
Jeff Johnson295189b2012-06-20 16:38:30 -0700223static struct ieee80211_channel hdd_social_channels_2_4_GHZ[] =
224{
225 HDD2GHZCHAN(2412, 1, 0) ,
226 HDD2GHZCHAN(2437, 6, 0) ,
227 HDD2GHZCHAN(2462, 11, 0) ,
228};
Jeff Johnson295189b2012-06-20 16:38:30 -0700229
230static struct ieee80211_channel hdd_channels_5_GHZ[] =
231{
Madan Mohan Koyyalamudic3a240c2012-09-28 15:34:08 -0700232 HDD5GHZCHAN(4920, 240, 0) ,
233 HDD5GHZCHAN(4940, 244, 0) ,
234 HDD5GHZCHAN(4960, 248, 0) ,
235 HDD5GHZCHAN(4980, 252, 0) ,
236 HDD5GHZCHAN(5040, 208, 0) ,
237 HDD5GHZCHAN(5060, 212, 0) ,
238 HDD5GHZCHAN(5080, 216, 0) ,
Jeff Johnson295189b2012-06-20 16:38:30 -0700239 HDD5GHZCHAN(5180, 36, 0) ,
240 HDD5GHZCHAN(5200, 40, 0) ,
241 HDD5GHZCHAN(5220, 44, 0) ,
242 HDD5GHZCHAN(5240, 48, 0) ,
243 HDD5GHZCHAN(5260, 52, 0) ,
244 HDD5GHZCHAN(5280, 56, 0) ,
245 HDD5GHZCHAN(5300, 60, 0) ,
246 HDD5GHZCHAN(5320, 64, 0) ,
247 HDD5GHZCHAN(5500,100, 0) ,
248 HDD5GHZCHAN(5520,104, 0) ,
249 HDD5GHZCHAN(5540,108, 0) ,
250 HDD5GHZCHAN(5560,112, 0) ,
251 HDD5GHZCHAN(5580,116, 0) ,
252 HDD5GHZCHAN(5600,120, 0) ,
253 HDD5GHZCHAN(5620,124, 0) ,
254 HDD5GHZCHAN(5640,128, 0) ,
255 HDD5GHZCHAN(5660,132, 0) ,
256 HDD5GHZCHAN(5680,136, 0) ,
257 HDD5GHZCHAN(5700,140, 0) ,
Leo Chang80de3c22013-11-26 10:52:12 -0800258#ifdef FEATURE_WLAN_CH144
259 HDD5GHZCHAN(5720,144, 0) ,
260#endif /* FEATURE_WLAN_CH144 */
Jeff Johnson295189b2012-06-20 16:38:30 -0700261 HDD5GHZCHAN(5745,149, 0) ,
262 HDD5GHZCHAN(5765,153, 0) ,
263 HDD5GHZCHAN(5785,157, 0) ,
264 HDD5GHZCHAN(5805,161, 0) ,
265 HDD5GHZCHAN(5825,165, 0) ,
266};
267
268static struct ieee80211_rate g_mode_rates[] =
269{
Gopichand Nakkala747461f2013-04-24 19:24:45 +0530270 HDD_G_MODE_RATETAB(10, 0x1, 0),
271 HDD_G_MODE_RATETAB(20, 0x2, 0),
272 HDD_G_MODE_RATETAB(55, 0x4, 0),
273 HDD_G_MODE_RATETAB(110, 0x8, 0),
274 HDD_G_MODE_RATETAB(60, 0x10, 0),
275 HDD_G_MODE_RATETAB(90, 0x20, 0),
276 HDD_G_MODE_RATETAB(120, 0x40, 0),
277 HDD_G_MODE_RATETAB(180, 0x80, 0),
278 HDD_G_MODE_RATETAB(240, 0x100, 0),
279 HDD_G_MODE_RATETAB(360, 0x200, 0),
280 HDD_G_MODE_RATETAB(480, 0x400, 0),
Jeff Johnson295189b2012-06-20 16:38:30 -0700281 HDD_G_MODE_RATETAB(540, 0x800, 0),
Gopichand Nakkala747461f2013-04-24 19:24:45 +0530282};
Jeff Johnson295189b2012-06-20 16:38:30 -0700283
284static struct ieee80211_rate a_mode_rates[] =
285{
Gopichand Nakkala747461f2013-04-24 19:24:45 +0530286 HDD_G_MODE_RATETAB(60, 0x10, 0),
287 HDD_G_MODE_RATETAB(90, 0x20, 0),
288 HDD_G_MODE_RATETAB(120, 0x40, 0),
289 HDD_G_MODE_RATETAB(180, 0x80, 0),
290 HDD_G_MODE_RATETAB(240, 0x100, 0),
291 HDD_G_MODE_RATETAB(360, 0x200, 0),
292 HDD_G_MODE_RATETAB(480, 0x400, 0),
Jeff Johnson295189b2012-06-20 16:38:30 -0700293 HDD_G_MODE_RATETAB(540, 0x800, 0),
294};
295
296static struct ieee80211_supported_band wlan_hdd_band_2_4_GHZ =
297{
298 .channels = hdd_channels_2_4_GHZ,
299 .n_channels = ARRAY_SIZE(hdd_channels_2_4_GHZ),
300 .band = IEEE80211_BAND_2GHZ,
301 .bitrates = g_mode_rates,
302 .n_bitrates = g_mode_rates_size,
303 .ht_cap.ht_supported = 1,
304 .ht_cap.cap = IEEE80211_HT_CAP_SGI_20
305 | IEEE80211_HT_CAP_GRN_FLD
306 | IEEE80211_HT_CAP_DSSSCCK40
307 | IEEE80211_HT_CAP_LSIG_TXOP_PROT,
308 .ht_cap.ampdu_factor = IEEE80211_HT_MAX_AMPDU_64K,
309 .ht_cap.ampdu_density = IEEE80211_HT_MPDU_DENSITY_16,
310 .ht_cap.mcs.rx_mask = { 0xff, 0, 0, 0, 0, 0, 0, 0, 0, 0, },
311 .ht_cap.mcs.rx_highest = cpu_to_le16( 72 ),
312 .ht_cap.mcs.tx_params = IEEE80211_HT_MCS_TX_DEFINED,
313};
314
Jeff Johnson295189b2012-06-20 16:38:30 -0700315static struct ieee80211_supported_band wlan_hdd_band_p2p_2_4_GHZ =
316{
317 .channels = hdd_social_channels_2_4_GHZ,
318 .n_channels = ARRAY_SIZE(hdd_social_channels_2_4_GHZ),
319 .band = IEEE80211_BAND_2GHZ,
320 .bitrates = g_mode_rates,
321 .n_bitrates = g_mode_rates_size,
322 .ht_cap.ht_supported = 1,
323 .ht_cap.cap = IEEE80211_HT_CAP_SGI_20
324 | IEEE80211_HT_CAP_GRN_FLD
325 | IEEE80211_HT_CAP_DSSSCCK40
326 | IEEE80211_HT_CAP_LSIG_TXOP_PROT,
327 .ht_cap.ampdu_factor = IEEE80211_HT_MAX_AMPDU_64K,
328 .ht_cap.ampdu_density = IEEE80211_HT_MPDU_DENSITY_16,
329 .ht_cap.mcs.rx_mask = { 0xff, 0, 0, 0, 0, 0, 0, 0, 0, 0, },
330 .ht_cap.mcs.rx_highest = cpu_to_le16( 72 ),
331 .ht_cap.mcs.tx_params = IEEE80211_HT_MCS_TX_DEFINED,
332};
Jeff Johnson295189b2012-06-20 16:38:30 -0700333
334static struct ieee80211_supported_band wlan_hdd_band_5_GHZ =
335{
336 .channels = hdd_channels_5_GHZ,
337 .n_channels = ARRAY_SIZE(hdd_channels_5_GHZ),
338 .band = IEEE80211_BAND_5GHZ,
339 .bitrates = a_mode_rates,
340 .n_bitrates = a_mode_rates_size,
341 .ht_cap.ht_supported = 1,
342 .ht_cap.cap = IEEE80211_HT_CAP_SGI_20
343 | IEEE80211_HT_CAP_GRN_FLD
344 | IEEE80211_HT_CAP_DSSSCCK40
345 | IEEE80211_HT_CAP_LSIG_TXOP_PROT
346 | IEEE80211_HT_CAP_SGI_40
347 | IEEE80211_HT_CAP_SUP_WIDTH_20_40,
348 .ht_cap.ampdu_factor = IEEE80211_HT_MAX_AMPDU_64K,
349 .ht_cap.ampdu_density = IEEE80211_HT_MPDU_DENSITY_16,
350 .ht_cap.mcs.rx_mask = { 0xff, 0, 0, 0, 0, 0, 0, 0, 0, 0, },
351 .ht_cap.mcs.rx_highest = cpu_to_le16( 72 ),
352 .ht_cap.mcs.tx_params = IEEE80211_HT_MCS_TX_DEFINED,
353};
354
Gopichand Nakkala747461f2013-04-24 19:24:45 +0530355/* This structure contain information what kind of frame are expected in
Jeff Johnson295189b2012-06-20 16:38:30 -0700356 TX/RX direction for each kind of interface */
357static const struct ieee80211_txrx_stypes
358wlan_hdd_txrx_stypes[NUM_NL80211_IFTYPES] = {
359 [NL80211_IFTYPE_STATION] = {
360 .tx = 0xffff,
361 .rx = BIT(SIR_MAC_MGMT_ACTION) |
362 BIT(SIR_MAC_MGMT_PROBE_REQ),
363 },
364 [NL80211_IFTYPE_AP] = {
365 .tx = 0xffff,
366 .rx = BIT(SIR_MAC_MGMT_ASSOC_REQ) |
367 BIT(SIR_MAC_MGMT_REASSOC_REQ) |
368 BIT(SIR_MAC_MGMT_PROBE_REQ) |
369 BIT(SIR_MAC_MGMT_DISASSOC) |
370 BIT(SIR_MAC_MGMT_AUTH) |
371 BIT(SIR_MAC_MGMT_DEAUTH) |
372 BIT(SIR_MAC_MGMT_ACTION),
373 },
Jeff Johnsonbc006202013-04-29 14:05:30 -0700374 [NL80211_IFTYPE_ADHOC] = {
375 .tx = 0xffff,
376 .rx = BIT(SIR_MAC_MGMT_ASSOC_REQ) |
377 BIT(SIR_MAC_MGMT_REASSOC_REQ) |
378 BIT(SIR_MAC_MGMT_PROBE_REQ) |
379 BIT(SIR_MAC_MGMT_DISASSOC) |
380 BIT(SIR_MAC_MGMT_AUTH) |
381 BIT(SIR_MAC_MGMT_DEAUTH) |
382 BIT(SIR_MAC_MGMT_ACTION),
383 },
Jeff Johnson295189b2012-06-20 16:38:30 -0700384 [NL80211_IFTYPE_P2P_CLIENT] = {
385 .tx = 0xffff,
386 .rx = BIT(SIR_MAC_MGMT_ACTION) |
387 BIT(SIR_MAC_MGMT_PROBE_REQ),
388 },
389 [NL80211_IFTYPE_P2P_GO] = {
390 /* This is also same as for SoftAP */
391 .tx = 0xffff,
392 .rx = BIT(SIR_MAC_MGMT_ASSOC_REQ) |
393 BIT(SIR_MAC_MGMT_REASSOC_REQ) |
394 BIT(SIR_MAC_MGMT_PROBE_REQ) |
395 BIT(SIR_MAC_MGMT_DISASSOC) |
396 BIT(SIR_MAC_MGMT_AUTH) |
397 BIT(SIR_MAC_MGMT_DEAUTH) |
398 BIT(SIR_MAC_MGMT_ACTION),
399 },
Jeff Johnson295189b2012-06-20 16:38:30 -0700400};
401
Sudhir Sattayappa Kohalli278eee52013-01-16 17:35:13 -0800402#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,4,0))
Sudhir Sattayappa Kohalli278eee52013-01-16 17:35:13 -0800403static const struct ieee80211_iface_limit
404wlan_hdd_iface_limit[] = {
405 {
Sunil Ravia72c3992013-01-31 06:12:22 -0800406 /* max = 3 ; Our driver create two interfaces during driver init
407 * wlan0 and p2p0 interfaces. p2p0 is considered as station
408 * interface until a group is formed. In JB architecture, once the
409 * group is formed, interface type of p2p0 is changed to P2P GO or
410 * Client.
411 * When supplicant remove the group, it first issue a set interface
412 * cmd to change the mode back to Station. In JB this works fine as
413 * we advertize two station type interface during driver init.
414 * Some vendors create separate interface for P2P GO/Client,
415 * after group formation(Third one). But while group remove
416 * supplicant first tries to change the mode(3rd interface) to STATION
417 * But as we advertized only two sta type interfaces nl80211 was
418 * returning error for the third one which was leading to failure in
419 * delete interface. Ideally while removing the group, supplicant
420 * should not try to change the 3rd interface mode to Station type.
421 * Till we get a fix in wpa_supplicant, we advertize max STA
422 * interface type to 3
423 */
424 .max = 3,
Sudhir Sattayappa Kohalli278eee52013-01-16 17:35:13 -0800425 .types = BIT(NL80211_IFTYPE_STATION),
426 },
427 {
428 .max = 1,
Jeff Johnsonbc006202013-04-29 14:05:30 -0700429 .types = BIT(NL80211_IFTYPE_ADHOC) | BIT(NL80211_IFTYPE_AP),
Sudhir Sattayappa Kohalli278eee52013-01-16 17:35:13 -0800430 },
431 {
432 .max = 1,
433 .types = BIT(NL80211_IFTYPE_P2P_GO) |
434 BIT(NL80211_IFTYPE_P2P_CLIENT),
435 },
436};
437
438/* By default, only single channel concurrency is allowed */
439static struct ieee80211_iface_combination
440wlan_hdd_iface_combination = {
441 .limits = wlan_hdd_iface_limit,
442 .num_different_channels = 1,
Sunil Ravia72c3992013-01-31 06:12:22 -0800443 /*
444 * max = WLAN_MAX_INTERFACES ; JellyBean architecture creates wlan0
445 * and p2p0 interfaces during driver init
446 * Some vendors create separate interface for P2P operations.
447 * wlan0: STA interface
448 * p2p0: P2P Device interface, action frames goes
449 * through this interface.
450 * p2p-xx: P2P interface, After GO negotiation this interface is
451 * created for p2p operations(GO/CLIENT interface).
452 */
453 .max_interfaces = WLAN_MAX_INTERFACES,
Sudhir Sattayappa Kohalli278eee52013-01-16 17:35:13 -0800454 .n_limits = ARRAY_SIZE(wlan_hdd_iface_limit),
455 .beacon_int_infra_match = false,
456};
457#endif
Sudhir Sattayappa Kohalli278eee52013-01-16 17:35:13 -0800458
Jeff Johnson295189b2012-06-20 16:38:30 -0700459static struct cfg80211_ops wlan_hdd_cfg80211_ops;
460
461/* Data rate 100KBPS based on IE Index */
462struct index_data_rate_type
463{
464 v_U8_t beacon_rate_index;
465 v_U16_t supported_rate[4];
466};
467
468/* 11B, 11G Rate table include Basic rate and Extended rate
469 The IDX field is the rate index
470 The HI field is the rate when RSSI is strong or being ignored
471 (in this case we report actual rate)
472 The MID field is the rate when RSSI is moderate
473 (in this case we cap 11b rates at 5.5 and 11g rates at 24)
474 The LO field is the rate when RSSI is low
475 (in this case we don't report rates, actual current rate used)
476 */
477static const struct
478{
479 v_U8_t beacon_rate_index;
Madan Mohan Koyyalamudi8df78d52012-11-02 12:30:06 -0700480 v_U16_t supported_rate[4];
Jeff Johnson295189b2012-06-20 16:38:30 -0700481} supported_data_rate[] =
482{
Madan Mohan Koyyalamudi8df78d52012-11-02 12:30:06 -0700483/* IDX HI HM LM LO (RSSI-based index */
484 {2, { 10, 10, 10, 0}},
485 {4, { 20, 20, 10, 0}},
486 {11, { 55, 20, 10, 0}},
487 {12, { 60, 55, 20, 0}},
488 {18, { 90, 55, 20, 0}},
489 {22, {110, 55, 20, 0}},
490 {24, {120, 90, 60, 0}},
491 {36, {180, 120, 60, 0}},
492 {44, {220, 180, 60, 0}},
493 {48, {240, 180, 90, 0}},
494 {66, {330, 180, 90, 0}},
495 {72, {360, 240, 90, 0}},
496 {96, {480, 240, 120, 0}},
497 {108, {540, 240, 120, 0}}
Jeff Johnson295189b2012-06-20 16:38:30 -0700498};
499
500/* MCS Based rate table */
501static struct index_data_rate_type supported_mcs_rate[] =
502{
503/* MCS L20 L40 S20 S40 */
504 {0, {65, 135, 72, 150}},
505 {1, {130, 270, 144, 300}},
506 {2, {195, 405, 217, 450}},
507 {3, {260, 540, 289, 600}},
508 {4, {390, 810, 433, 900}},
509 {5, {520, 1080, 578, 1200}},
510 {6, {585, 1215, 650, 1350}},
511 {7, {650, 1350, 722, 1500}}
512};
513
Leo Chang6f8870f2013-03-26 18:11:36 -0700514#ifdef WLAN_FEATURE_11AC
515
Gopichand Nakkala4c705372013-04-24 13:20:33 +0530516#define DATA_RATE_11AC_MCS_MASK 0x03
Leo Chang6f8870f2013-03-26 18:11:36 -0700517
518struct index_vht_data_rate_type
519{
520 v_U8_t beacon_rate_index;
Gopichand Nakkala4c705372013-04-24 13:20:33 +0530521 v_U16_t supported_VHT80_rate[2];
522 v_U16_t supported_VHT40_rate[2];
523 v_U16_t supported_VHT20_rate[2];
Leo Chang6f8870f2013-03-26 18:11:36 -0700524};
525
526typedef enum
527{
528 DATA_RATE_11AC_MAX_MCS_7,
529 DATA_RATE_11AC_MAX_MCS_8,
530 DATA_RATE_11AC_MAX_MCS_9,
531 DATA_RATE_11AC_MAX_MCS_NA
532} eDataRate11ACMaxMcs;
533
Mahesh A Saptasagar7bd6ad42014-07-21 18:56:33 +0530534/* SSID broadcast type */
535typedef enum eSSIDBcastType
536{
537 eBCAST_UNKNOWN = 0,
538 eBCAST_NORMAL = 1,
539 eBCAST_HIDDEN = 2,
540} tSSIDBcastType;
541
Leo Chang6f8870f2013-03-26 18:11:36 -0700542/* MCS Based VHT rate table */
543static struct index_vht_data_rate_type supported_vht_mcs_rate[] =
544{
Gopichand Nakkala4c705372013-04-24 13:20:33 +0530545/* MCS L80 S80 L40 S40 L20 S40*/
546 {0, {293, 325}, {135, 150}, {65, 72}},
547 {1, {585, 650}, {270, 300}, {130, 144}},
548 {2, {878, 975}, {405, 450}, {195, 217}},
549 {3, {1170, 1300}, {540, 600}, {260, 289}},
550 {4, {1755, 1950}, {810, 900}, {390, 433}},
551 {5, {2340, 2600}, {1080, 1200}, {520, 578}},
552 {6, {2633, 2925}, {1215, 1350}, {585, 650}},
553 {7, {2925, 3250}, {1350, 1500}, {650, 722}},
554 {8, {3510, 3900}, {1620, 1800}, {780, 867}},
555 {9, {3900, 4333}, {1800, 2000}, {780, 867}}
Leo Chang6f8870f2013-03-26 18:11:36 -0700556};
557#endif /* WLAN_FEATURE_11AC */
558
c_hpothu79aab322014-07-14 21:11:01 +0530559/*array index points to MCS and array value points respective rssi*/
560static int rssiMcsTbl[][10] =
561{
562/*MCS 0 1 2 3 4 5 6 7 8 9*/
563 {-82, -79, -77, -74, -70, -66, -65, -64, -59, -57}, //20
564 {-79, -76, -74, -71, -67, -63, -62, -61, -56, -54}, //40
565 {-76, -73, -71, -68, -64, -60, -59, -58, -53, -51} //80
566};
567
Jeff Johnson295189b2012-06-20 16:38:30 -0700568extern struct net_device_ops net_ops_struct;
569
Leo Chang9056f462013-08-01 19:21:11 -0700570#ifdef WLAN_NL80211_TESTMODE
571enum wlan_hdd_tm_attr
572{
573 WLAN_HDD_TM_ATTR_INVALID = 0,
574 WLAN_HDD_TM_ATTR_CMD = 1,
575 WLAN_HDD_TM_ATTR_DATA = 2,
576 WLAN_HDD_TM_ATTR_TYPE = 3,
577 /* keep last */
578 WLAN_HDD_TM_ATTR_AFTER_LAST,
579 WLAN_HDD_TM_ATTR_MAX = WLAN_HDD_TM_ATTR_AFTER_LAST - 1,
580};
581
582enum wlan_hdd_tm_cmd
583{
584 WLAN_HDD_TM_CMD_WLAN_HB = 1,
585};
586
587#define WLAN_HDD_TM_DATA_MAX_LEN 5000
588
589static const struct nla_policy wlan_hdd_tm_policy[WLAN_HDD_TM_ATTR_MAX + 1] =
590{
591 [WLAN_HDD_TM_ATTR_CMD] = { .type = NLA_U32 },
592 [WLAN_HDD_TM_ATTR_DATA] = { .type = NLA_BINARY,
593 .len = WLAN_HDD_TM_DATA_MAX_LEN },
594};
595#endif /* WLAN_NL80211_TESTMODE */
596
Rajesh Chauhan98a31f82014-01-06 20:15:25 -0800597#ifdef FEATURE_WLAN_CH_AVOID
598/*
599 * FUNCTION: wlan_hdd_send_avoid_freq_event
600 * This is called when wlan driver needs to send vendor specific
601 * avoid frequency range event to userspace
602 */
603int wlan_hdd_send_avoid_freq_event(hdd_context_t *pHddCtx,
604 tHddAvoidFreqList *pAvoidFreqList)
605{
606 struct sk_buff *vendor_event;
607
608 ENTER();
609
610 if (!pHddCtx)
611 {
612 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
613 "%s: HDD context is null", __func__);
614 return -1;
615 }
616
617 if (!pAvoidFreqList)
618 {
619 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
620 "%s: pAvoidFreqList is null", __func__);
621 return -1;
622 }
623
624 vendor_event = cfg80211_vendor_event_alloc(pHddCtx->wiphy,
625 sizeof(tHddAvoidFreqList),
Sunil Duttc69bccb2014-05-26 21:30:20 +0530626 QCA_NL80211_VENDOR_SUBCMD_AVOID_FREQUENCY_INDEX,
Rajesh Chauhan98a31f82014-01-06 20:15:25 -0800627 GFP_KERNEL);
628 if (!vendor_event)
629 {
630 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
631 "%s: cfg80211_vendor_event_alloc failed", __func__);
632 return -1;
633 }
634
635 memcpy(skb_put(vendor_event, sizeof(tHddAvoidFreqList)),
636 (void *)pAvoidFreqList, sizeof(tHddAvoidFreqList));
637
638 cfg80211_vendor_event(vendor_event, GFP_KERNEL);
639
640 EXIT();
641 return 0;
642}
643#endif /* FEATURE_WLAN_CH_AVOID */
644
Sunil Duttc69bccb2014-05-26 21:30:20 +0530645#ifdef WLAN_FEATURE_LINK_LAYER_STATS
646
647static v_BOOL_t put_wifi_rate_stat( tpSirWifiRateStat stats,
648 struct sk_buff *vendor_event)
649{
650 if (nla_put_u8(vendor_event,
651 QCA_WLAN_VENDOR_ATTR_LL_STATS_RATE_PREAMBLE,
652 stats->rate.preamble) ||
653 nla_put_u8(vendor_event,
654 QCA_WLAN_VENDOR_ATTR_LL_STATS_RATE_NSS,
655 stats->rate.nss) ||
656 nla_put_u8(vendor_event,
657 QCA_WLAN_VENDOR_ATTR_LL_STATS_RATE_BW,
658 stats->rate.bw) ||
659 nla_put_u8(vendor_event,
660 QCA_WLAN_VENDOR_ATTR_LL_STATS_RATE_MCS_INDEX,
661 stats->rate.rateMcsIdx) ||
662 nla_put_u32(vendor_event, QCA_WLAN_VENDOR_ATTR_LL_STATS_RATE_BIT_RATE,
663 stats->rate.bitrate ) ||
664 nla_put_u32(vendor_event, QCA_WLAN_VENDOR_ATTR_LL_STATS_RATE_TX_MPDU,
665 stats->txMpdu ) ||
666 nla_put_u32(vendor_event, QCA_WLAN_VENDOR_ATTR_LL_STATS_RATE_RX_MPDU,
667 stats->rxMpdu ) ||
668 nla_put_u32(vendor_event, QCA_WLAN_VENDOR_ATTR_LL_STATS_RATE_MPDU_LOST,
669 stats->mpduLost ) ||
670 nla_put_u32(vendor_event, QCA_WLAN_VENDOR_ATTR_LL_STATS_RATE_RETRIES,
671 stats->retries) ||
672 nla_put_u32(vendor_event,
673 QCA_WLAN_VENDOR_ATTR_LL_STATS_RATE_RETRIES_SHORT,
674 stats->retriesShort ) ||
675 nla_put_u32(vendor_event,
676 QCA_WLAN_VENDOR_ATTR_LL_STATS_RATE_RETRIES_LONG,
677 stats->retriesLong))
678 {
679 hddLog(VOS_TRACE_LEVEL_ERROR,
680 FL("QCA_WLAN_VENDOR_ATTR put fail"));
681 return FALSE;
682 }
683 return TRUE;
684}
685
686static v_BOOL_t put_wifi_peer_info( tpSirWifiPeerInfo stats,
687 struct sk_buff *vendor_event)
688{
689 u32 i = 0;
690 struct nlattr *rateInfo;
691 if (nla_put_u32(vendor_event, QCA_WLAN_VENDOR_ATTR_LL_STATS_PEER_INFO_TYPE,
692 stats->type) ||
693 nla_put(vendor_event,
694 QCA_WLAN_VENDOR_ATTR_LL_STATS_PEER_INFO_MAC_ADDRESS,
695 VOS_MAC_ADDR_SIZE, &stats->peerMacAddress[0]) ||
696 nla_put_u32(vendor_event,
697 QCA_WLAN_VENDOR_ATTR_LL_STATS_PEER_INFO_CAPABILITIES,
698 stats->capabilities) ||
699 nla_put_u32(vendor_event,
700 QCA_WLAN_VENDOR_ATTR_LL_STATS_PEER_INFO_NUM_RATES,
701 stats->numRate))
702 {
703 hddLog(VOS_TRACE_LEVEL_ERROR,
704 FL("QCA_WLAN_VENDOR_ATTR put fail"));
705 goto error;
706 }
707
708 rateInfo = nla_nest_start(vendor_event,
709 QCA_WLAN_VENDOR_ATTR_LL_STATS_PEER_INFO_RATE_INFO);
710 for (i = 0; i < stats->numRate; i++)
711 {
712 struct nlattr *rates;
713 tpSirWifiRateStat pRateStats = (tpSirWifiRateStat )((uint8 *)
714 stats->rateStats +
715 (i * sizeof(tSirWifiRateStat)));
716 rates = nla_nest_start(vendor_event, i);
717
718 if (FALSE == put_wifi_rate_stat(pRateStats, vendor_event))
719 {
720 hddLog(VOS_TRACE_LEVEL_ERROR,
721 FL("QCA_WLAN_VENDOR_ATTR put fail"));
722 return FALSE;
723 }
724 nla_nest_end(vendor_event, rates);
725 }
726 nla_nest_end(vendor_event, rateInfo);
727
728 return TRUE;
729error:
730 return FALSE;
731}
732
733static v_BOOL_t put_wifi_wmm_ac_stat( tpSirWifiWmmAcStat stats,
734 struct sk_buff *vendor_event)
735{
736 if (nla_put_u32(vendor_event, QCA_WLAN_VENDOR_ATTR_LL_STATS_WMM_AC_AC,
737 stats->ac ) ||
738 nla_put_u32(vendor_event,
739 QCA_WLAN_VENDOR_ATTR_LL_STATS_WMM_AC_TX_MPDU,
740 stats->txMpdu ) ||
741 nla_put_u32(vendor_event,
742 QCA_WLAN_VENDOR_ATTR_LL_STATS_WMM_AC_RX_MPDU,
743 stats->rxMpdu ) ||
744 nla_put_u32(vendor_event,
745 QCA_WLAN_VENDOR_ATTR_LL_STATS_WMM_AC_TX_MCAST,
746 stats->txMcast ) ||
747 nla_put_u32(vendor_event,
748 QCA_WLAN_VENDOR_ATTR_LL_STATS_WMM_AC_RX_MCAST,
749 stats->rxMcast ) ||
750 nla_put_u32(vendor_event,
751 QCA_WLAN_VENDOR_ATTR_LL_STATS_WMM_AC_RX_AMPDU,
752 stats->rxAmpdu ) ||
753 nla_put_u32(vendor_event,
754 QCA_WLAN_VENDOR_ATTR_LL_STATS_WMM_AC_TX_AMPDU,
755 stats->txAmpdu ) ||
756 nla_put_u32(vendor_event,
757 QCA_WLAN_VENDOR_ATTR_LL_STATS_WMM_AC_MPDU_LOST,
758 stats->mpduLost )||
759 nla_put_u32(vendor_event,
760 QCA_WLAN_VENDOR_ATTR_LL_STATS_WMM_AC_RETRIES,
761 stats->retries ) ||
762 nla_put_u32(vendor_event,
763 QCA_WLAN_VENDOR_ATTR_LL_STATS_WMM_AC_RETRIES_SHORT,
764 stats->retriesShort ) ||
765 nla_put_u32(vendor_event,
766 QCA_WLAN_VENDOR_ATTR_LL_STATS_WMM_AC_RETRIES_LONG,
767 stats->retriesLong ) ||
768 nla_put_u32(vendor_event,
769 QCA_WLAN_VENDOR_ATTR_LL_STATS_WMM_AC_CONTENTION_TIME_MIN,
770 stats->contentionTimeMin ) ||
771 nla_put_u32(vendor_event,
772 QCA_WLAN_VENDOR_ATTR_LL_STATS_WMM_AC_CONTENTION_TIME_MAX,
773 stats->contentionTimeMax ) ||
774 nla_put_u32(vendor_event,
775 QCA_WLAN_VENDOR_ATTR_LL_STATS_WMM_AC_CONTENTION_TIME_AVG,
776 stats->contentionTimeAvg ) ||
777 nla_put_u32(vendor_event,
778 QCA_WLAN_VENDOR_ATTR_LL_STATS_WMM_AC_CONTENTION_NUM_SAMPLES,
779 stats->contentionNumSamples ))
780 {
781 hddLog(VOS_TRACE_LEVEL_ERROR,
782 FL("QCA_WLAN_VENDOR_ATTR put fail") );
783 return FALSE;
784 }
785 return TRUE;
786}
787
788static v_BOOL_t put_wifi_interface_info(tpSirWifiInterfaceInfo stats,
789 struct sk_buff *vendor_event)
790{
Dino Myclec8f3f332014-07-21 16:48:27 +0530791 if (nla_put_s32(vendor_event,
Sunil Duttc69bccb2014-05-26 21:30:20 +0530792 QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_INFO_MODE, stats->mode ) ||
793 nla_put(vendor_event,
794 QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_INFO_MAC_ADDR,
795 VOS_MAC_ADDR_SIZE, stats->macAddr) ||
796 nla_put_u32(vendor_event,
797 QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_INFO_STATE,
798 stats->state ) ||
799 nla_put_u32(vendor_event,
800 QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_INFO_ROAMING,
801 stats->roaming ) ||
802 nla_put_u32(vendor_event,
803 QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_INFO_CAPABILITIES,
804 stats->capabilities ) ||
805 nla_put(vendor_event,
806 QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_INFO_SSID,
807 strlen(stats->ssid), stats->ssid) ||
808 nla_put(vendor_event,
809 QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_INFO_BSSID,
810 WNI_CFG_BSSID_LEN, stats->bssid) ||
811 nla_put(vendor_event,
812 QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_INFO_AP_COUNTRY_STR,
813 WNI_CFG_COUNTRY_CODE_LEN, stats->apCountryStr) ||
814 nla_put(vendor_event,
815 QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_INFO_COUNTRY_STR,
816 WNI_CFG_COUNTRY_CODE_LEN, stats->countryStr)
817 )
818 {
819 hddLog(VOS_TRACE_LEVEL_ERROR,
820 FL("QCA_WLAN_VENDOR_ATTR put fail") );
821 return FALSE;
822 }
823 return TRUE;
824}
825
Dino Mycle3b9536d2014-07-09 22:05:24 +0530826static v_BOOL_t put_wifi_iface_stats(hdd_adapter_t *pAdapter,
827 tpSirWifiIfaceStat pWifiIfaceStat,
Sunil Duttc69bccb2014-05-26 21:30:20 +0530828 struct sk_buff *vendor_event)
829{
830 int i = 0;
831 struct nlattr *wmmInfo;
Dino Mycle3b9536d2014-07-09 22:05:24 +0530832 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
833 WLANTL_InterfaceStatsType *pWifiIfaceStatTL = NULL;
834
Sunil Duttc69bccb2014-05-26 21:30:20 +0530835 if (FALSE == put_wifi_interface_info(
836 &pWifiIfaceStat->info,
837 vendor_event))
838 {
839 hddLog(VOS_TRACE_LEVEL_ERROR,
840 FL("QCA_WLAN_VENDOR_ATTR put fail") );
841 return FALSE;
842
843 }
Dino Mycle3b9536d2014-07-09 22:05:24 +0530844 pWifiIfaceStatTL = (WLANTL_InterfaceStatsType *)
845 vos_mem_malloc(sizeof(WLANTL_InterfaceStatsType));
846 if (NULL == pWifiIfaceStatTL)
847 {
848 hddLog(VOS_TRACE_LEVEL_ERROR, FL("vos_mem_malloc failed"));
849 return FALSE;
850 }
851
852
853 if ( pWifiIfaceStat->info.state == WIFI_ASSOCIATED)
854 {
855 if (VOS_STATUS_SUCCESS ==
856 WLANTL_CollectInterfaceStats((WLAN_HDD_GET_CTX(pAdapter))->pvosContext,
857 pHddStaCtx->conn_info.staId[0], pWifiIfaceStatTL))
858 {
859 /* mgmtRx, MgmtActionRx, rxMcast, rxMpdu, rxAmpdu, rssiData are
860 * obtained from TL structure
861 */
862
863 pWifiIfaceStat->mgmtRx = pWifiIfaceStat->beaconRx +
864 pWifiIfaceStatTL->mgmtRx;
865 pWifiIfaceStat->mgmtActionRx = pWifiIfaceStatTL->mgmtActionRx;
866 pWifiIfaceStat->mgmtActionTx = pWifiIfaceStatTL->mgmtActionTx;
867 pWifiIfaceStat->rssiData = pWifiIfaceStatTL->rssiData;
868
869 vos_mem_copy(
870 (void *) &pWifiIfaceStat->AccessclassStats[WIFI_AC_VO],
871 (void *) &pWifiIfaceStatTL->accessCategoryStats[WLANTL_AC_VO],
872 sizeof(WLANTL_AccessCategoryStatsType));
873
874 vos_mem_copy(
875 (void *) &pWifiIfaceStat->AccessclassStats[WIFI_AC_VI],
876 (void *) &pWifiIfaceStatTL->accessCategoryStats[WLANTL_AC_VI],
877 sizeof(WLANTL_AccessCategoryStatsType));
878
879 vos_mem_copy(
880 (void *) &pWifiIfaceStat->AccessclassStats[WIFI_AC_BE],
881 (void *) &pWifiIfaceStatTL->accessCategoryStats[WLANTL_AC_BE],
882 sizeof(WLANTL_AccessCategoryStatsType));
883
884 vos_mem_copy(
885 (void *) &pWifiIfaceStat->AccessclassStats[WIFI_AC_BK],
886 (void *) &pWifiIfaceStatTL->accessCategoryStats[WLANTL_AC_BK],
887 sizeof(WLANTL_AccessCategoryStatsType));
888 }
889 else
890 {
891 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Error in getting stats from TL"));
892 }
893
894 pWifiIfaceStat->AccessclassStats[WIFI_AC_VO].txMpdu =
895 pAdapter->hdd_stats.hddTxRxStats.txFetchedAC[WLANTL_AC_VO];
896 pWifiIfaceStat->AccessclassStats[WIFI_AC_VI].txMpdu =
897 pAdapter->hdd_stats.hddTxRxStats.txFetchedAC[WLANTL_AC_VI];
898 pWifiIfaceStat->AccessclassStats[WIFI_AC_BE].txMpdu =
899 pAdapter->hdd_stats.hddTxRxStats.txFetchedAC[WLANTL_AC_BE];
900 pWifiIfaceStat->AccessclassStats[WIFI_AC_BK].txMpdu =
901 pAdapter->hdd_stats.hddTxRxStats.txFetchedAC[WLANTL_AC_BK];
902
903 pWifiIfaceStat->AccessclassStats[WIFI_AC_VO].txMcast =
904 pAdapter->hdd_stats.hddTxRxStats.txMcast[WLANTL_AC_VO];
905 pWifiIfaceStat->AccessclassStats[WIFI_AC_VI].txMcast =
906 pAdapter->hdd_stats.hddTxRxStats.txMcast[WLANTL_AC_VI];
907 pWifiIfaceStat->AccessclassStats[WIFI_AC_BE].txMcast =
908 pAdapter->hdd_stats.hddTxRxStats.txMcast[WLANTL_AC_BE];
909 pWifiIfaceStat->AccessclassStats[WIFI_AC_BK].txMcast =
910 pAdapter->hdd_stats.hddTxRxStats.txMcast[WLANTL_AC_BK];
911 }
912 else
913 {
914 hddLog(VOS_TRACE_LEVEL_INFO, FL("Interface not Associated"));
915 }
916
917
Sunil Duttc69bccb2014-05-26 21:30:20 +0530918
919 if (nla_put_u32(vendor_event,
920 QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_BEACON_RX,
921 pWifiIfaceStat->beaconRx) ||
922 nla_put_u32(vendor_event,
923 QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_MGMT_RX,
924 pWifiIfaceStat->mgmtRx) ||
925 nla_put_u32(vendor_event,
926 QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_MGMT_ACTION_RX,
927 pWifiIfaceStat->mgmtActionRx) ||
928 nla_put_u32(vendor_event,
929 QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_MGMT_ACTION_TX,
930 pWifiIfaceStat->mgmtActionTx) ||
Dino Mycle3b9536d2014-07-09 22:05:24 +0530931 nla_put_s32(vendor_event,
Sunil Duttc69bccb2014-05-26 21:30:20 +0530932 QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_RSSI_MGMT,
933 pWifiIfaceStat->rssiMgmt) ||
Dino Mycle3b9536d2014-07-09 22:05:24 +0530934 nla_put_s32(vendor_event,
Sunil Duttc69bccb2014-05-26 21:30:20 +0530935 QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_RSSI_DATA,
936 pWifiIfaceStat->rssiData) ||
Dino Mycle3b9536d2014-07-09 22:05:24 +0530937 nla_put_s32(vendor_event,
Sunil Duttc69bccb2014-05-26 21:30:20 +0530938 QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_RSSI_ACK,
939 pWifiIfaceStat->rssiAck))
940 {
941 hddLog(VOS_TRACE_LEVEL_ERROR,
942 FL("QCA_WLAN_VENDOR_ATTR put fail"));
Dino Mycle3b9536d2014-07-09 22:05:24 +0530943 vos_mem_free(pWifiIfaceStatTL);
Sunil Duttc69bccb2014-05-26 21:30:20 +0530944 return FALSE;
945 }
946
947 wmmInfo = nla_nest_start(vendor_event,
948 QCA_WLAN_VENDOR_ATTR_LL_STATS_WMM_INFO);
949 for (i = 0; i < WIFI_AC_MAX; i++)
950 {
951 struct nlattr *wmmStats;
952 wmmStats = nla_nest_start(vendor_event, i);
953 if (FALSE == put_wifi_wmm_ac_stat(
954 &pWifiIfaceStat->AccessclassStats[i],
955 vendor_event))
956 {
957 hddLog(VOS_TRACE_LEVEL_ERROR,
958 FL("QCA_WLAN_VENDOR_ATTR put Fail"));
Dino Mycle3b9536d2014-07-09 22:05:24 +0530959 vos_mem_free(pWifiIfaceStatTL);
Sunil Duttc69bccb2014-05-26 21:30:20 +0530960 return FALSE;
961 }
962
963 nla_nest_end(vendor_event, wmmStats);
964 }
965 nla_nest_end(vendor_event, wmmInfo);
Dino Mycle3b9536d2014-07-09 22:05:24 +0530966 vos_mem_free(pWifiIfaceStatTL);
Sunil Duttc69bccb2014-05-26 21:30:20 +0530967 return TRUE;
968}
969
970static tSirWifiInterfaceMode
971 hdd_map_device_to_ll_iface_mode ( int deviceMode )
972{
973 switch (deviceMode)
974 {
975 case WLAN_HDD_INFRA_STATION:
976 return WIFI_INTERFACE_STA;
977 case WLAN_HDD_SOFTAP:
978 return WIFI_INTERFACE_SOFTAP;
979 case WLAN_HDD_P2P_CLIENT:
980 return WIFI_INTERFACE_P2P_CLIENT;
981 case WLAN_HDD_P2P_GO:
982 return WIFI_INTERFACE_P2P_GO;
983 case WLAN_HDD_IBSS:
984 return WIFI_INTERFACE_IBSS;
985 default:
Dino Myclec8f3f332014-07-21 16:48:27 +0530986 return WIFI_INTERFACE_UNKNOWN;
Sunil Duttc69bccb2014-05-26 21:30:20 +0530987 }
988}
989
990static v_BOOL_t hdd_get_interface_info(hdd_adapter_t *pAdapter,
991 tpSirWifiInterfaceInfo pInfo)
992{
993 v_U8_t *staMac = NULL;
994 hdd_station_ctx_t *pHddStaCtx;
995 tHalHandle hHal = WLAN_HDD_GET_HAL_CTX(pAdapter);
996 tpAniSirGlobal pMac = PMAC_STRUCT( hHal );
997
998 pInfo->mode = hdd_map_device_to_ll_iface_mode(pAdapter->device_mode);
999
1000 vos_mem_copy(pInfo->macAddr,
1001 pAdapter->macAddressCurrent.bytes, sizeof(v_MACADDR_t));
1002
1003 if (((WLAN_HDD_INFRA_STATION == pAdapter->device_mode) ||
1004 (WLAN_HDD_P2P_CLIENT == pAdapter->device_mode) ||
1005 (WLAN_HDD_P2P_DEVICE == pAdapter->device_mode)))
1006 {
1007 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
1008 if (eConnectionState_NotConnected == pHddStaCtx->conn_info.connState)
1009 {
1010 pInfo->state = WIFI_DISCONNECTED;
1011 }
1012 if (eConnectionState_Connecting == pHddStaCtx->conn_info.connState)
1013 {
1014 hddLog(VOS_TRACE_LEVEL_ERROR,
1015 "%s: Session ID %d, Connection is in progress", __func__,
1016 pAdapter->sessionId);
1017 pInfo->state = WIFI_ASSOCIATING;
1018 }
1019 if ((eConnectionState_Associated == pHddStaCtx->conn_info.connState) &&
1020 (VOS_FALSE == pHddStaCtx->conn_info.uIsAuthenticated))
1021 {
1022 staMac = (v_U8_t *) &(pAdapter->macAddressCurrent.bytes[0]);
1023 hddLog(VOS_TRACE_LEVEL_ERROR,
1024 "%s: client " MAC_ADDRESS_STR
1025 " is in the middle of WPS/EAPOL exchange.", __func__,
1026 MAC_ADDR_ARRAY(staMac));
1027 pInfo->state = WIFI_AUTHENTICATING;
1028 }
1029 if (eConnectionState_Associated == pHddStaCtx->conn_info.connState)
1030 {
1031 pInfo->state = WIFI_ASSOCIATED;
1032 vos_mem_copy(pInfo->bssid,
1033 &pHddStaCtx->conn_info.bssId, WNI_CFG_BSSID_LEN);
1034 vos_mem_copy(pInfo->ssid,
1035 pHddStaCtx->conn_info.SSID.SSID.ssId,
1036 pHddStaCtx->conn_info.SSID.SSID.length);
1037 //NULL Terminate the string.
1038 pInfo->ssid[pHddStaCtx->conn_info.SSID.SSID.length] = 0;
1039 }
1040 }
1041 vos_mem_copy(pInfo->countryStr,
1042 pMac->scan.countryCodeCurrent, WNI_CFG_COUNTRY_CODE_LEN);
1043
1044 vos_mem_copy(pInfo->apCountryStr,
1045 pMac->scan.countryCodeCurrent, WNI_CFG_COUNTRY_CODE_LEN);
1046
1047 return TRUE;
1048}
1049
1050/*
1051 * hdd_link_layer_process_peer_stats () - This function is called after
1052 * receiving Link Layer Peer statistics from FW.This function converts
1053 * the firmware data to the NL data and sends the same to the kernel/upper
1054 * layers.
1055 */
1056static v_VOID_t hdd_link_layer_process_peer_stats(hdd_adapter_t *pAdapter,
1057 v_VOID_t *pData)
1058{
1059 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
1060 tpSirWifiRateStat pWifiRateStat;
1061 tpSirWifiPeerStat pWifiPeerStat;
1062 tpSirWifiPeerInfo pWifiPeerInfo;
1063 struct nlattr *peerInfo;
1064 struct sk_buff *vendor_event;
1065 int status, i;
1066
1067 status = wlan_hdd_validate_context(pHddCtx);
1068 if (0 != status)
1069 {
1070 hddLog(VOS_TRACE_LEVEL_ERROR,
1071 FL("HDD context is not valid") );
1072 return;
1073 }
1074
1075 pWifiPeerStat = (tpSirWifiPeerStat) pData;
1076
1077 hddLog(VOS_TRACE_LEVEL_INFO,
1078 "LL_STATS_PEER_ALL : numPeers %u",
1079 pWifiPeerStat->numPeers);
1080 {
1081 for (i = 0; i < pWifiPeerStat->numPeers; i++)
1082 {
1083 pWifiPeerInfo = (tpSirWifiPeerInfo)
1084 ((uint8 *)pWifiPeerStat->peerInfo +
1085 ( i * sizeof(tSirWifiPeerInfo)));
1086
1087 hddLog(VOS_TRACE_LEVEL_INFO,
1088 " %d) LL_STATS Channel Stats "
1089 " Peer Type %u "
1090 " peerMacAddress %pM "
1091 " capabilities 0x%x "
1092 " numRate %u ",
1093 i,
1094 pWifiPeerInfo->type,
1095 pWifiPeerInfo->peerMacAddress,
1096 pWifiPeerInfo->capabilities,
1097 pWifiPeerInfo->numRate);
1098 {
1099 int j;
1100 for (j = 0; j < pWifiPeerInfo->numRate; j++)
1101 {
1102 pWifiRateStat = (tpSirWifiRateStat)
1103 ((tANI_U8 *) pWifiPeerInfo->rateStats +
1104 ( j * sizeof(tSirWifiRateStat)));
1105
1106 hddLog(VOS_TRACE_LEVEL_INFO,
1107 " peer Rate Stats "
1108 " preamble %u "
1109 " nss %u "
1110 " bw %u "
1111 " rateMcsIdx %u "
1112 " reserved %u "
1113 " bitrate %u "
1114 " txMpdu %u "
1115 " rxMpdu %u "
1116 " mpduLost %u "
1117 " retries %u "
1118 " retriesShort %u "
1119 " retriesLong %u",
1120 pWifiRateStat->rate.preamble,
1121 pWifiRateStat->rate.nss,
1122 pWifiRateStat->rate.bw,
1123 pWifiRateStat->rate.rateMcsIdx,
1124 pWifiRateStat->rate.reserved,
1125 pWifiRateStat->rate.bitrate,
1126 pWifiRateStat->txMpdu,
1127 pWifiRateStat->rxMpdu,
1128 pWifiRateStat->mpduLost,
1129 pWifiRateStat->retries,
1130 pWifiRateStat->retriesShort,
1131 pWifiRateStat->retriesLong);
1132 }
1133 }
1134 }
1135 }
1136
1137 /*
1138 * Allocate a size of 4096 for the peer stats comprising
1139 * each of size = sizeof (tSirWifiPeerInfo) + numRate *
1140 * sizeof (tSirWifiRateStat).Each field is put with an
1141 * NL attribute.The size of 4096 is considered assuming
1142 * that number of rates shall not exceed beyond 50 with
1143 * the sizeof (tSirWifiRateStat) being 32.
1144 */
1145 vendor_event = cfg80211_vendor_event_alloc(pHddCtx->wiphy,
1146 LL_STATS_EVENT_BUF_SIZE + NLMSG_HDRLEN,
1147 QCA_NL80211_VENDOR_SUBCMD_LL_PEER_INFO_STATS_INDEX,
1148 GFP_KERNEL);
1149 if (!vendor_event)
1150 {
1151 hddLog(VOS_TRACE_LEVEL_ERROR,
1152 "%s: cfg80211_vendor_event_alloc failed",
1153 __func__);
1154 return;
1155 }
1156 if (nla_put_u32(vendor_event,
1157 QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_NUM_PEERS,
1158 pWifiPeerStat->numPeers))
1159 {
1160 hddLog(VOS_TRACE_LEVEL_ERROR,
1161 "%s: QCA_WLAN_VENDOR_ATTR put fail", __func__);
1162 kfree_skb(vendor_event);
1163 return;
1164 }
1165
1166 peerInfo = nla_nest_start(vendor_event,
1167 QCA_WLAN_VENDOR_ATTR_LL_STATS_PEER_INFO);
1168
1169 pWifiPeerInfo = (tpSirWifiPeerInfo) ((uint8 *)
1170 pWifiPeerStat->peerInfo);
1171
1172 for (i = 1; i <= pWifiPeerStat->numPeers; i++)
1173 {
1174 struct nlattr *peers = nla_nest_start(vendor_event, i);
1175 int numRate = pWifiPeerInfo->numRate;
1176
1177 if (FALSE == put_wifi_peer_info(
1178 pWifiPeerInfo, vendor_event))
1179 {
1180 hddLog(VOS_TRACE_LEVEL_ERROR,
1181 "%s: put_wifi_peer_info put fail", __func__);
1182 kfree_skb(vendor_event);
1183 return;
1184 }
1185
1186 pWifiPeerInfo = (tpSirWifiPeerInfo) ((uint8 *)
1187 pWifiPeerStat->peerInfo +
1188 (i * sizeof(tSirWifiPeerInfo)) +
1189 (numRate * sizeof (tSirWifiRateStat)));
1190 nla_nest_end(vendor_event, peers);
1191 }
1192 nla_nest_end(vendor_event, peerInfo);
1193 cfg80211_vendor_event(vendor_event, GFP_KERNEL);
1194}
1195
1196/*
1197 * hdd_link_layer_process_iface_stats () - This function is called after
1198 * receiving Link Layer Interface statistics from FW.This function converts
1199 * the firmware data to the NL data and sends the same to the kernel/upper
1200 * layers.
1201 */
1202static v_VOID_t hdd_link_layer_process_iface_stats(hdd_adapter_t *pAdapter,
1203 v_VOID_t *pData)
1204{
1205 tpSirWifiIfaceStat pWifiIfaceStat;
1206 struct sk_buff *vendor_event;
1207 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
1208 int status;
1209
1210 status = wlan_hdd_validate_context(pHddCtx);
1211 if (0 != status)
1212 {
1213 hddLog(VOS_TRACE_LEVEL_ERROR,
1214 FL("HDD context is not valid") );
1215 return;
1216 }
1217 /*
1218 * Allocate a size of 4096 for the interface stats comprising
1219 * sizeof (tpSirWifiIfaceStat).The size of 4096 is considered
1220 * assuming that all these fit with in the limit.Please take
1221 * a call on the limit based on the data requirements on
1222 * interface statistics.
1223 */
1224 vendor_event = cfg80211_vendor_event_alloc(pHddCtx->wiphy,
1225 LL_STATS_EVENT_BUF_SIZE + NLMSG_HDRLEN,
1226 QCA_NL80211_VENDOR_SUBCMD_LL_IFACE_STATS_INDEX,
1227 GFP_KERNEL);
1228 if (!vendor_event)
1229 {
1230 hddLog(VOS_TRACE_LEVEL_ERROR,
1231 FL("cfg80211_vendor_event_alloc failed") );
1232 return;
1233 }
1234
1235 pWifiIfaceStat = (tpSirWifiIfaceStat) pData;
1236
Dino Mycle3b9536d2014-07-09 22:05:24 +05301237
1238 if (FALSE == hdd_get_interface_info( pAdapter,
1239 &pWifiIfaceStat->info))
1240 {
1241 hddLog(VOS_TRACE_LEVEL_ERROR,
1242 FL("hdd_get_interface_info get fail") );
1243 kfree_skb(vendor_event);
1244 return;
1245 }
1246
1247 if (FALSE == put_wifi_iface_stats( pAdapter, pWifiIfaceStat,
1248 vendor_event))
1249 {
1250 hddLog(VOS_TRACE_LEVEL_ERROR,
1251 FL("put_wifi_iface_stats fail") );
1252 kfree_skb(vendor_event);
1253 return;
1254 }
1255
Sunil Duttc69bccb2014-05-26 21:30:20 +05301256 hddLog(VOS_TRACE_LEVEL_INFO,
1257 "WMI_LINK_STATS_IFACE Data");
1258
1259 hddLog(VOS_TRACE_LEVEL_INFO,
1260 "LL_STATS_IFACE: "
1261 " Mode %u "
1262 " MAC %pM "
1263 " State %u "
1264 " Roaming %u "
1265 " capabilities 0x%x "
1266 " SSID %s "
1267 " BSSID %pM",
1268 pWifiIfaceStat->info.mode,
1269 pWifiIfaceStat->info.macAddr,
1270 pWifiIfaceStat->info.state,
1271 pWifiIfaceStat->info.roaming,
1272 pWifiIfaceStat->info.capabilities,
1273 pWifiIfaceStat->info.ssid,
1274 pWifiIfaceStat->info.bssid);
1275
1276 hddLog(VOS_TRACE_LEVEL_INFO,
1277 " AP country str: %c%c%c",
1278 pWifiIfaceStat->info.apCountryStr[0],
1279 pWifiIfaceStat->info.apCountryStr[1],
1280 pWifiIfaceStat->info.apCountryStr[2]);
1281
1282
1283 hddLog(VOS_TRACE_LEVEL_INFO,
1284 " Country Str Association: %c%c%c",
1285 pWifiIfaceStat->info.countryStr[0],
1286 pWifiIfaceStat->info.countryStr[1],
1287 pWifiIfaceStat->info.countryStr[2]);
1288
1289 hddLog(VOS_TRACE_LEVEL_INFO,
1290 " beaconRx %u "
1291 " mgmtRx %u "
1292 " mgmtActionRx %u "
1293 " mgmtActionTx %u "
Dino Mycle3b9536d2014-07-09 22:05:24 +05301294 " rssiMgmt %d "
1295 " rssiData %d "
1296 " rssiAck %d",
Sunil Duttc69bccb2014-05-26 21:30:20 +05301297 pWifiIfaceStat->beaconRx,
1298 pWifiIfaceStat->mgmtRx,
1299 pWifiIfaceStat->mgmtActionRx,
1300 pWifiIfaceStat->mgmtActionTx,
1301 pWifiIfaceStat->rssiMgmt,
1302 pWifiIfaceStat->rssiData,
1303 pWifiIfaceStat->rssiAck );
1304
1305
1306 {
1307 int i;
1308 for (i = 0 ; i < WIFI_AC_MAX; i ++)
1309 {
1310 hddLog(VOS_TRACE_LEVEL_INFO,
1311
1312 " %d) LL_STATS IFACE: "
1313 " ac: %u txMpdu: %u "
1314 " rxMpdu: %u txMcast: %u "
1315 " rxMcast: %u rxAmpdu: %u "
1316 " txAmpdu: %u mpduLost: %u "
1317 " retries: %u retriesShort: %u "
1318 " retriesLong: %u contentionTimeMin: %u "
1319 " contentionTimeMax: %u contentionTimeAvg: %u "
1320 " contentionNumSamples: %u",
1321 i,
1322 pWifiIfaceStat->AccessclassStats[i].ac,
1323 pWifiIfaceStat->AccessclassStats[i].txMpdu,
1324 pWifiIfaceStat->AccessclassStats[i].rxMpdu,
1325 pWifiIfaceStat->AccessclassStats[i].txMcast,
1326 pWifiIfaceStat->AccessclassStats[i].rxMcast,
1327 pWifiIfaceStat->AccessclassStats[i].rxAmpdu,
1328 pWifiIfaceStat->AccessclassStats[i].txAmpdu,
1329 pWifiIfaceStat->AccessclassStats[i].mpduLost,
1330 pWifiIfaceStat->AccessclassStats[i].retries,
1331 pWifiIfaceStat->
1332 AccessclassStats[i].retriesShort,
1333 pWifiIfaceStat->AccessclassStats[i].retriesLong,
1334 pWifiIfaceStat->
1335 AccessclassStats[i].contentionTimeMin,
1336 pWifiIfaceStat->
1337 AccessclassStats[i].contentionTimeMax,
1338 pWifiIfaceStat->
1339 AccessclassStats[i].contentionTimeAvg,
1340 pWifiIfaceStat->
1341 AccessclassStats[i].contentionNumSamples);
1342
1343 }
1344 }
1345
Sunil Duttc69bccb2014-05-26 21:30:20 +05301346 cfg80211_vendor_event(vendor_event, GFP_KERNEL);
1347}
1348
1349/*
1350 * hdd_link_layer_process_radio_stats () - This function is called after
1351 * receiving Link Layer Radio statistics from FW.This function converts
1352 * the firmware data to the NL data and sends the same to the kernel/upper
1353 * layers.
1354 */
1355static v_VOID_t hdd_link_layer_process_radio_stats(hdd_adapter_t *pAdapter,
1356 v_VOID_t *pData)
1357{
1358 int status, i;
1359 tpSirWifiRadioStat pWifiRadioStat;
1360 tpSirWifiChannelStats pWifiChannelStats;
1361 struct sk_buff *vendor_event;
1362 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
1363 struct nlattr *chList;
1364
1365 status = wlan_hdd_validate_context(pHddCtx);
1366 if (0 != status)
1367 {
1368 hddLog(VOS_TRACE_LEVEL_ERROR,
1369 FL("HDD context is not valid") );
1370 return;
1371 }
1372 pWifiRadioStat = (tpSirWifiRadioStat) pData;
1373
1374 hddLog(VOS_TRACE_LEVEL_INFO,
1375 "LL_STATS_RADIO"
1376 " radio is %d onTime is %u "
1377 " txTime is %u rxTime is %u "
1378 " onTimeScan is %u onTimeNbd is %u "
Dino Mycle6fb96c12014-06-10 11:52:40 +05301379 " onTimeEXTScan is %u onTimeRoamScan is %u "
Sunil Duttc69bccb2014-05-26 21:30:20 +05301380 " onTimePnoScan is %u onTimeHs20 is %u "
1381 " numChannels is %u",
1382 pWifiRadioStat->radio, pWifiRadioStat->onTime,
1383 pWifiRadioStat->txTime, pWifiRadioStat->rxTime,
1384 pWifiRadioStat->onTimeScan, pWifiRadioStat->onTimeNbd,
Dino Mycle6fb96c12014-06-10 11:52:40 +05301385 pWifiRadioStat->onTimeEXTScan,
Sunil Duttc69bccb2014-05-26 21:30:20 +05301386 pWifiRadioStat->onTimeRoamScan,
1387 pWifiRadioStat->onTimePnoScan,
1388 pWifiRadioStat->onTimeHs20,
1389 pWifiRadioStat->numChannels);
1390 /*
1391 * Allocate a size of 4096 for the Radio stats comprising
1392 * sizeof (tSirWifiRadioStat) + numChannels * sizeof
1393 * (tSirWifiChannelStats).Each channel data is put with an
1394 * NL attribute.The size of 4096 is considered assuming that
1395 * number of channels shall not exceed beyond 60 with the
1396 * sizeof (tSirWifiChannelStats) being 24 bytes.
1397 */
1398
1399 vendor_event = cfg80211_vendor_event_alloc(pHddCtx->wiphy,
1400 LL_STATS_EVENT_BUF_SIZE + NLMSG_HDRLEN ,
1401 QCA_NL80211_VENDOR_SUBCMD_LL_RADIO_STATS_INDEX,
1402 GFP_KERNEL);
1403
1404 if (!vendor_event)
1405 {
1406 hddLog(VOS_TRACE_LEVEL_ERROR,
1407 FL("cfg80211_vendor_event_alloc failed") );
1408 return;
1409 }
1410
1411 if (nla_put_u32(vendor_event,
1412 QCA_WLAN_VENDOR_ATTR_LL_STATS_RADIO_ID,
1413 pWifiRadioStat->radio) ||
1414 nla_put_u32(vendor_event,
1415 QCA_WLAN_VENDOR_ATTR_LL_STATS_RADIO_ON_TIME,
1416 pWifiRadioStat->onTime) ||
1417 nla_put_u32(vendor_event,
1418 QCA_WLAN_VENDOR_ATTR_LL_STATS_RADIO_TX_TIME,
1419 pWifiRadioStat->txTime) ||
1420 nla_put_u32(vendor_event,
1421 QCA_WLAN_VENDOR_ATTR_LL_STATS_RADIO_RX_TIME,
1422 pWifiRadioStat->rxTime) ||
1423 nla_put_u32(vendor_event,
1424 QCA_WLAN_VENDOR_ATTR_LL_STATS_RADIO_ON_TIME_SCAN,
1425 pWifiRadioStat->onTimeScan) ||
1426 nla_put_u32(vendor_event,
1427 QCA_WLAN_VENDOR_ATTR_LL_STATS_RADIO_ON_TIME_NBD,
1428 pWifiRadioStat->onTimeNbd) ||
1429 nla_put_u32(vendor_event,
Dino Mycle6fb96c12014-06-10 11:52:40 +05301430 QCA_WLAN_VENDOR_ATTR_LL_STATS_RADIO_ON_TIME_EXTSCAN,
1431 pWifiRadioStat->onTimeEXTScan)||
Sunil Duttc69bccb2014-05-26 21:30:20 +05301432 nla_put_u32(vendor_event,
1433 QCA_WLAN_VENDOR_ATTR_LL_STATS_RADIO_ON_TIME_ROAM_SCAN,
1434 pWifiRadioStat->onTimeRoamScan) ||
1435 nla_put_u32(vendor_event,
1436 QCA_WLAN_VENDOR_ATTR_LL_STATS_RADIO_ON_TIME_PNO_SCAN,
1437 pWifiRadioStat->onTimePnoScan) ||
1438 nla_put_u32(vendor_event,
1439 QCA_WLAN_VENDOR_ATTR_LL_STATS_RADIO_ON_TIME_HS20,
1440 pWifiRadioStat->onTimeHs20) ||
1441 nla_put_u32(vendor_event,
1442 QCA_WLAN_VENDOR_ATTR_LL_STATS_RADIO_NUM_CHANNELS,
1443 pWifiRadioStat->numChannels))
1444 {
1445 hddLog(VOS_TRACE_LEVEL_ERROR,
1446 FL("QCA_WLAN_VENDOR_ATTR put fail"));
1447 kfree_skb(vendor_event);
1448 return ;
1449 }
1450
1451 chList = nla_nest_start(vendor_event,
1452 QCA_WLAN_VENDOR_ATTR_LL_STATS_CH_INFO);
1453 for (i = 0; i < pWifiRadioStat->numChannels; i++)
1454 {
1455 struct nlattr *chInfo;
1456
1457 pWifiChannelStats = (tpSirWifiChannelStats) ((uint8*)
1458 pWifiRadioStat->channels +
1459 (i * sizeof(tSirWifiChannelStats)));
1460
1461 hddLog(VOS_TRACE_LEVEL_INFO,
1462 " %d) Channel Info"
1463 " width is %u "
1464 " CenterFreq %u "
1465 " CenterFreq0 %u "
1466 " CenterFreq1 %u "
1467 " onTime %u "
1468 " ccaBusyTime %u",
1469 i,
1470 pWifiChannelStats->channel.width,
1471 pWifiChannelStats->channel.centerFreq,
1472 pWifiChannelStats->channel.centerFreq0,
1473 pWifiChannelStats->channel.centerFreq1,
1474 pWifiChannelStats->onTime,
1475 pWifiChannelStats->ccaBusyTime);
1476
1477
1478 chInfo = nla_nest_start(vendor_event, i);
1479
1480 if (nla_put_u32(vendor_event,
1481 QCA_WLAN_VENDOR_ATTR_LL_STATS_CHANNEL_INFO_WIDTH,
1482 pWifiChannelStats->channel.width) ||
1483 nla_put_u32(vendor_event,
1484 QCA_WLAN_VENDOR_ATTR_LL_STATS_CHANNEL_INFO_CENTER_FREQ,
1485 pWifiChannelStats->channel.centerFreq) ||
1486 nla_put_u32(vendor_event,
1487 QCA_WLAN_VENDOR_ATTR_LL_STATS_CHANNEL_INFO_CENTER_FREQ0,
1488 pWifiChannelStats->channel.centerFreq0) ||
1489 nla_put_u32(vendor_event,
1490 QCA_WLAN_VENDOR_ATTR_LL_STATS_CHANNEL_INFO_CENTER_FREQ1,
1491 pWifiChannelStats->channel.centerFreq1) ||
1492 nla_put_u32(vendor_event,
1493 QCA_WLAN_VENDOR_ATTR_LL_STATS_CHANNEL_ON_TIME,
1494 pWifiChannelStats->onTime) ||
1495 nla_put_u32(vendor_event,
1496 QCA_WLAN_VENDOR_ATTR_LL_STATS_CHANNEL_CCA_BUSY_TIME,
1497 pWifiChannelStats->ccaBusyTime))
1498 {
1499 hddLog(VOS_TRACE_LEVEL_ERROR,
1500 FL("cfg80211_vendor_event_alloc failed") );
1501 kfree_skb(vendor_event);
1502 return ;
1503 }
1504 nla_nest_end(vendor_event, chInfo);
1505 }
1506 nla_nest_end(vendor_event, chList);
1507
1508 cfg80211_vendor_event(vendor_event, GFP_KERNEL);
1509 return;
1510}
1511
1512/*
1513 * hdd_link_layer_stats_ind_callback () - This function is called after
1514 * receiving Link Layer indications from FW.This callback converts the firmware
1515 * data to the NL data and send the same to the kernel/upper layers.
1516 */
1517static void hdd_link_layer_stats_ind_callback ( void *pCtx,
1518 int indType,
Dino Mycled3d50022014-07-07 12:58:25 +05301519 void *pRsp, u8 *macAddr)
Sunil Duttc69bccb2014-05-26 21:30:20 +05301520{
Dino Mycled3d50022014-07-07 12:58:25 +05301521 hdd_context_t *pHddCtx = (hdd_context_t *)pCtx;
1522 hdd_adapter_t *pAdapter = NULL;
1523 tpSirLLStatsResults linkLayerStatsResults = (tpSirLLStatsResults)pRsp;
Sunil Duttc69bccb2014-05-26 21:30:20 +05301524 int status;
1525
1526 status = wlan_hdd_validate_context(pHddCtx);
1527
1528 if (0 != status)
1529 {
1530 hddLog(VOS_TRACE_LEVEL_ERROR,
1531 FL("HDD context is not valid"));
1532 return;
1533 }
1534
Dino Mycled3d50022014-07-07 12:58:25 +05301535
1536
1537 pAdapter = hdd_get_adapter_by_macaddr(pHddCtx, macAddr);
1538 if (NULL == pAdapter)
1539 {
1540 hddLog(VOS_TRACE_LEVEL_ERROR,
1541 FL(" MAC address %pM does not exist with host"),
1542 macAddr);
1543 return;
1544 }
1545
Sunil Duttc69bccb2014-05-26 21:30:20 +05301546 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Dino Mycled3d50022014-07-07 12:58:25 +05301547 "%s: Interface: %s LLStats indType: %d", __func__,
1548 pAdapter->dev->name, indType);
1549
Sunil Duttc69bccb2014-05-26 21:30:20 +05301550 switch (indType)
1551 {
1552 case SIR_HAL_LL_STATS_RESULTS_RSP:
1553 {
Sunil Duttc69bccb2014-05-26 21:30:20 +05301554 hddLog(VOS_TRACE_LEVEL_INFO,
1555 FL("RESPONSE SIR_HAL_LL_STATS_RESULTS_RSP") );
1556 hddLog(VOS_TRACE_LEVEL_INFO,
1557 "LL_STATS RESULTS RESPONSE paramID = 0x%x",
1558 linkLayerStatsResults->paramId);
1559 hddLog(VOS_TRACE_LEVEL_INFO,
Dino Mycled3d50022014-07-07 12:58:25 +05301560 "LL_STATS RESULTS RESPONSE ifaceId = %u MAC: %pM",
1561 linkLayerStatsResults->ifaceId, macAddr);
Sunil Duttc69bccb2014-05-26 21:30:20 +05301562 hddLog(VOS_TRACE_LEVEL_INFO,
1563 "LL_STATS RESULTS RESPONSE respId = %u",
1564 linkLayerStatsResults->respId);
1565 hddLog(VOS_TRACE_LEVEL_INFO,
1566 "LL_STATS RESULTS RESPONSE moreResultToFollow = %u",
1567 linkLayerStatsResults->moreResultToFollow);
1568 hddLog(VOS_TRACE_LEVEL_INFO,
1569 "LL_STATS RESULTS RESPONSE result = %p",
1570 linkLayerStatsResults->result);
1571 if ( linkLayerStatsResults->paramId & WMI_LINK_STATS_RADIO )
1572 {
1573 hdd_link_layer_process_radio_stats(pAdapter,
1574 (v_VOID_t *)linkLayerStatsResults->result);
1575 }
1576 else if ( linkLayerStatsResults->paramId & WMI_LINK_STATS_IFACE )
1577 {
1578 hdd_link_layer_process_iface_stats(pAdapter,
1579 (v_VOID_t *)linkLayerStatsResults->result);
1580 }
1581 else if ( linkLayerStatsResults->paramId &
1582 WMI_LINK_STATS_ALL_PEER )
1583 {
1584 hdd_link_layer_process_peer_stats(pAdapter,
1585 (v_VOID_t *)linkLayerStatsResults->result);
1586 } /* WMI_LINK_STATS_ALL_PEER */
1587 else
1588 {
1589 hddLog(VOS_TRACE_LEVEL_ERROR,
1590 FL("INVALID LL_STATS_NOTIFY RESPONSE ***********"));
1591 }
1592
1593 break;
1594 }
1595 default:
1596 hddLog(VOS_TRACE_LEVEL_ERROR, "invalid event type %d", indType);
1597 break;
1598 }
1599 return;
1600}
1601
1602const struct
1603nla_policy
1604qca_wlan_vendor_ll_set_policy[QCA_WLAN_VENDOR_ATTR_LL_STATS_SET_MAX +1] =
1605{
1606 [QCA_WLAN_VENDOR_ATTR_LL_STATS_SET_CONFIG_MPDU_SIZE_THRESHOLD] =
1607 { .type = NLA_U32 },
1608 [QCA_WLAN_VENDOR_ATTR_LL_STATS_SET_CONFIG_AGGRESSIVE_STATS_GATHERING] =
1609 { .type = NLA_U32 },
1610};
1611
1612static int wlan_hdd_cfg80211_ll_stats_set(struct wiphy *wiphy,
1613 struct wireless_dev *wdev,
1614 void *data,
1615 int data_len)
1616{
1617 int status;
1618 struct nlattr *tb_vendor[QCA_WLAN_VENDOR_ATTR_LL_STATS_SET_MAX + 1];
Dino Mycledf0a5d92014-07-04 09:41:55 +05301619 tSirLLStatsSetReq linkLayerStatsSetReq;
Sunil Duttc69bccb2014-05-26 21:30:20 +05301620 struct net_device *dev = wdev->netdev;
1621 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
1622 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
1623
1624 status = wlan_hdd_validate_context(pHddCtx);
1625 if (0 != status)
1626 {
1627 hddLog(VOS_TRACE_LEVEL_ERROR,
1628 FL("HDD context is not valid"));
1629 return -EINVAL;
1630 }
1631
1632 if (NULL == pAdapter)
1633 {
1634 hddLog(VOS_TRACE_LEVEL_ERROR,
1635 FL("HDD adapter is Null"));
1636 return -ENODEV;
1637 }
Dino Mycledf0a5d92014-07-04 09:41:55 +05301638 /* check the LLStats Capability */
1639 if ( (TRUE != pHddCtx->cfg_ini->fEnableLLStats) ||
1640 (TRUE != sme_IsFeatureSupportedByFW(LINK_LAYER_STATS_MEAS)))
1641 {
1642 hddLog(VOS_TRACE_LEVEL_ERROR,
1643 FL("Link Layer Statistics not supported by Firmware"));
1644 return -EINVAL;
1645 }
Sunil Duttc69bccb2014-05-26 21:30:20 +05301646
1647 if (nla_parse(tb_vendor, QCA_WLAN_VENDOR_ATTR_LL_STATS_SET_MAX,
1648 (struct nlattr *)data,
1649 data_len, qca_wlan_vendor_ll_set_policy))
1650 {
1651 hddLog(VOS_TRACE_LEVEL_ERROR, FL() );
1652 return -EINVAL;
1653 }
1654 if (!tb_vendor
1655 [QCA_WLAN_VENDOR_ATTR_LL_STATS_SET_CONFIG_MPDU_SIZE_THRESHOLD])
1656 {
1657 hddLog(VOS_TRACE_LEVEL_ERROR, FL("MPDU size Not present"));
1658 return -EINVAL;
1659 }
1660 if (!tb_vendor[
1661 QCA_WLAN_VENDOR_ATTR_LL_STATS_SET_CONFIG_AGGRESSIVE_STATS_GATHERING])
1662 {
1663 hddLog(VOS_TRACE_LEVEL_ERROR, FL(" Stats Gathering Not Present"));
1664 return -EINVAL;
1665 }
Sunil Duttc69bccb2014-05-26 21:30:20 +05301666 // Shall take the request Id if the Upper layers pass. 1 For now.
Dino Mycledf0a5d92014-07-04 09:41:55 +05301667 linkLayerStatsSetReq.reqId = 1;
Sunil Duttc69bccb2014-05-26 21:30:20 +05301668
Dino Mycledf0a5d92014-07-04 09:41:55 +05301669 linkLayerStatsSetReq.mpduSizeThreshold =
Sunil Duttc69bccb2014-05-26 21:30:20 +05301670 nla_get_u32(
1671 tb_vendor[QCA_WLAN_VENDOR_ATTR_LL_STATS_SET_CONFIG_MPDU_SIZE_THRESHOLD]);
1672
Dino Mycledf0a5d92014-07-04 09:41:55 +05301673 linkLayerStatsSetReq.aggressiveStatisticsGathering =
Sunil Duttc69bccb2014-05-26 21:30:20 +05301674 nla_get_u32(
1675 tb_vendor[QCA_WLAN_VENDOR_ATTR_LL_STATS_SET_CONFIG_AGGRESSIVE_STATS_GATHERING]);
1676
Dino Mycled3d50022014-07-07 12:58:25 +05301677 vos_mem_copy(linkLayerStatsSetReq.macAddr,
1678 pAdapter->macAddressCurrent.bytes, sizeof(v_MACADDR_t));
Sunil Duttc69bccb2014-05-26 21:30:20 +05301679
1680
1681 hddLog(VOS_TRACE_LEVEL_INFO,
Dino Mycled3d50022014-07-07 12:58:25 +05301682 "LL_STATS_SET reqId = %d", linkLayerStatsSetReq.reqId);
Sunil Duttc69bccb2014-05-26 21:30:20 +05301683 hddLog(VOS_TRACE_LEVEL_INFO,
Dino Mycled3d50022014-07-07 12:58:25 +05301684 "LL_STATS_SET MAC = %pM", linkLayerStatsSetReq.macAddr);
Sunil Duttc69bccb2014-05-26 21:30:20 +05301685 hddLog(VOS_TRACE_LEVEL_INFO,
1686 "LL_STATS_SET mpduSizeThreshold = %d",
Dino Mycledf0a5d92014-07-04 09:41:55 +05301687 linkLayerStatsSetReq.mpduSizeThreshold);
Sunil Duttc69bccb2014-05-26 21:30:20 +05301688 hddLog(VOS_TRACE_LEVEL_INFO,
1689 "LL_STATS_SET aggressive Statistics Gathering = %d",
Dino Mycledf0a5d92014-07-04 09:41:55 +05301690 linkLayerStatsSetReq.aggressiveStatisticsGathering);
Sunil Duttc69bccb2014-05-26 21:30:20 +05301691
1692 if (eHAL_STATUS_SUCCESS != sme_SetLinkLayerStatsIndCB(
1693 pHddCtx->hHal,
Dino Mycled3d50022014-07-07 12:58:25 +05301694 hdd_link_layer_stats_ind_callback))
Sunil Duttc69bccb2014-05-26 21:30:20 +05301695 {
1696 hddLog(VOS_TRACE_LEVEL_ERROR, "%s:"
1697 "sme_SetLinkLayerStatsIndCB Failed", __func__);
Sunil Duttc69bccb2014-05-26 21:30:20 +05301698 return -EINVAL;
1699
1700 }
1701 if (eHAL_STATUS_SUCCESS != sme_LLStatsSetReq( pHddCtx->hHal,
Dino Mycledf0a5d92014-07-04 09:41:55 +05301702 &linkLayerStatsSetReq))
Sunil Duttc69bccb2014-05-26 21:30:20 +05301703 {
1704 hddLog(VOS_TRACE_LEVEL_ERROR, "%s:"
1705 "sme_LLStatsSetReq Failed", __func__);
Sunil Duttc69bccb2014-05-26 21:30:20 +05301706 return -EINVAL;
1707 }
1708
1709 pAdapter->isLinkLayerStatsSet = 1;
1710
1711 return 0;
1712}
1713
1714const struct
1715nla_policy
1716qca_wlan_vendor_ll_get_policy[QCA_WLAN_VENDOR_ATTR_LL_STATS_GET_MAX +1] =
1717{
1718 /* Unsigned 32bit value provided by the caller issuing the GET stats
1719 * command. When reporting
1720 * the stats results, the driver uses the same value to indicate
1721 * which GET request the results
1722 * correspond to.
1723 */
1724 [QCA_WLAN_VENDOR_ATTR_LL_STATS_GET_CONFIG_REQ_ID] = { .type = NLA_U32 },
1725
1726 /* Unsigned 32bit value . bit mask to identify what statistics are
1727 requested for retrieval */
1728 [QCA_WLAN_VENDOR_ATTR_LL_STATS_GET_CONFIG_REQ_MASK] = { .type = NLA_U32 },
1729};
1730
1731static int wlan_hdd_cfg80211_ll_stats_get(struct wiphy *wiphy,
1732 struct wireless_dev *wdev,
1733 void *data,
1734 int data_len)
1735{
1736 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
1737 struct nlattr *tb_vendor[QCA_WLAN_VENDOR_ATTR_LL_STATS_GET_MAX + 1];
Dino Mycledf0a5d92014-07-04 09:41:55 +05301738 tSirLLStatsGetReq linkLayerStatsGetReq;
Sunil Duttc69bccb2014-05-26 21:30:20 +05301739 struct net_device *dev = wdev->netdev;
1740 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
1741 int status;
1742
1743 status = wlan_hdd_validate_context(pHddCtx);
1744 if (0 != status)
1745 {
1746 hddLog(VOS_TRACE_LEVEL_ERROR,
1747 FL("HDD context is not valid"));
1748 return -EINVAL ;
1749 }
1750
1751 if (NULL == pAdapter)
1752 {
1753 hddLog(VOS_TRACE_LEVEL_FATAL,
1754 "%s: HDD adapter is Null", __func__);
1755 return -ENODEV;
1756 }
Dino Mycledf0a5d92014-07-04 09:41:55 +05301757 /* check the LLStats Capability */
1758 if ( (TRUE != pHddCtx->cfg_ini->fEnableLLStats) ||
1759 (TRUE != sme_IsFeatureSupportedByFW(LINK_LAYER_STATS_MEAS)))
1760 {
1761 hddLog(VOS_TRACE_LEVEL_ERROR,
1762 FL("Link Layer Statistics not supported by Firmware"));
1763 return -EINVAL;
1764 }
1765
Sunil Duttc69bccb2014-05-26 21:30:20 +05301766
1767 if (!pAdapter->isLinkLayerStatsSet)
1768 {
1769 hddLog(VOS_TRACE_LEVEL_FATAL,
1770 "%s: isLinkLayerStatsSet : %d",
1771 __func__, pAdapter->isLinkLayerStatsSet);
1772 return -EINVAL;
1773 }
1774
1775 if (nla_parse(tb_vendor, QCA_WLAN_VENDOR_ATTR_LL_STATS_GET_MAX,
1776 (struct nlattr *)data,
1777 data_len, qca_wlan_vendor_ll_get_policy))
1778 {
1779 hddLog(VOS_TRACE_LEVEL_ERROR, FL() );
1780 return -EINVAL;
1781 }
1782
1783 if (!tb_vendor
1784 [QCA_WLAN_VENDOR_ATTR_LL_STATS_GET_CONFIG_REQ_ID])
1785 {
1786 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Request Id Not present"));
1787 return -EINVAL;
1788 }
1789
1790 if (!tb_vendor
1791 [QCA_WLAN_VENDOR_ATTR_LL_STATS_GET_CONFIG_REQ_MASK])
1792 {
1793 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Req Mask Not present"));
1794 return -EINVAL;
1795 }
1796
Sunil Duttc69bccb2014-05-26 21:30:20 +05301797
Dino Mycledf0a5d92014-07-04 09:41:55 +05301798 linkLayerStatsGetReq.reqId =
Sunil Duttc69bccb2014-05-26 21:30:20 +05301799 nla_get_u32( tb_vendor[
1800 QCA_WLAN_VENDOR_ATTR_LL_STATS_GET_CONFIG_REQ_ID]);
Dino Mycledf0a5d92014-07-04 09:41:55 +05301801 linkLayerStatsGetReq.paramIdMask =
Sunil Duttc69bccb2014-05-26 21:30:20 +05301802 nla_get_u32( tb_vendor[
1803 QCA_WLAN_VENDOR_ATTR_LL_STATS_GET_CONFIG_REQ_MASK]);
1804
Dino Mycled3d50022014-07-07 12:58:25 +05301805 vos_mem_copy(linkLayerStatsGetReq.macAddr,
1806 pAdapter->macAddressCurrent.bytes, sizeof(v_MACADDR_t));
Sunil Duttc69bccb2014-05-26 21:30:20 +05301807
1808 hddLog(VOS_TRACE_LEVEL_INFO,
Dino Mycledf0a5d92014-07-04 09:41:55 +05301809 "LL_STATS_GET reqId = %d", linkLayerStatsGetReq.reqId);
Sunil Duttc69bccb2014-05-26 21:30:20 +05301810 hddLog(VOS_TRACE_LEVEL_INFO,
Dino Mycled3d50022014-07-07 12:58:25 +05301811 "LL_STATS_GET MAC = %pM", linkLayerStatsGetReq.macAddr);
Sunil Duttc69bccb2014-05-26 21:30:20 +05301812 hddLog(VOS_TRACE_LEVEL_INFO,
1813 "LL_STATS_GET paramIdMask = %d",
Dino Mycledf0a5d92014-07-04 09:41:55 +05301814 linkLayerStatsGetReq.paramIdMask);
Sunil Duttc69bccb2014-05-26 21:30:20 +05301815
1816 if (eHAL_STATUS_SUCCESS != sme_LLStatsGetReq( pHddCtx->hHal,
Dino Mycledf0a5d92014-07-04 09:41:55 +05301817 &linkLayerStatsGetReq))
Sunil Duttc69bccb2014-05-26 21:30:20 +05301818 {
1819 hddLog(VOS_TRACE_LEVEL_ERROR, "%s:"
1820 "sme_LLStatsGetReq Failed", __func__);
Sunil Duttc69bccb2014-05-26 21:30:20 +05301821 return -EINVAL;
1822 }
1823 return 0;
1824}
1825
1826const struct
1827nla_policy
1828qca_wlan_vendor_ll_clr_policy[QCA_WLAN_VENDOR_ATTR_LL_STATS_CLR_MAX +1] =
1829{
1830 [QCA_WLAN_VENDOR_ATTR_LL_STATS_CLR_CONFIG_REQ_MASK] = {.type = NLA_U32 },
1831 [QCA_WLAN_VENDOR_ATTR_LL_STATS_CLR_CONFIG_STOP_REQ] = {.type = NLA_U8 },
1832 [QCA_WLAN_VENDOR_ATTR_LL_STATS_CLR_CONFIG_RSP_MASK] = {.type = NLA_U32 },
1833 [QCA_WLAN_VENDOR_ATTR_LL_STATS_CLR_CONFIG_STOP_RSP] = {.type = NLA_U8 },
1834};
1835
1836static int wlan_hdd_cfg80211_ll_stats_clear(struct wiphy *wiphy,
1837 struct wireless_dev *wdev,
1838 void *data,
1839 int data_len)
1840{
1841 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
1842 struct nlattr *tb_vendor[QCA_WLAN_VENDOR_ATTR_LL_STATS_CLR_MAX + 1];
Dino Mycledf0a5d92014-07-04 09:41:55 +05301843 tSirLLStatsClearReq linkLayerStatsClearReq;
Sunil Duttc69bccb2014-05-26 21:30:20 +05301844 struct net_device *dev = wdev->netdev;
1845 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
1846 u32 statsClearReqMask;
1847 u8 stopReq;
1848 int status;
1849
1850 status = wlan_hdd_validate_context(pHddCtx);
1851 if (0 != status)
1852 {
1853 hddLog(VOS_TRACE_LEVEL_ERROR,
1854 FL("HDD context is not valid"));
1855 return -EINVAL;
1856 }
1857
1858 if (NULL == pAdapter)
1859 {
1860 hddLog(VOS_TRACE_LEVEL_FATAL,
1861 "%s: HDD adapter is Null", __func__);
1862 return -ENODEV;
1863 }
Dino Mycledf0a5d92014-07-04 09:41:55 +05301864 /* check the LLStats Capability */
1865 if ( (TRUE != pHddCtx->cfg_ini->fEnableLLStats) ||
1866 (TRUE != sme_IsFeatureSupportedByFW(LINK_LAYER_STATS_MEAS)))
1867 {
1868 hddLog(VOS_TRACE_LEVEL_ERROR,
1869 FL("Enable LLStats Capability"));
1870 return -EINVAL;
1871 }
Sunil Duttc69bccb2014-05-26 21:30:20 +05301872
1873 if (!pAdapter->isLinkLayerStatsSet)
1874 {
1875 hddLog(VOS_TRACE_LEVEL_FATAL,
1876 "%s: isLinkLayerStatsSet : %d",
1877 __func__, pAdapter->isLinkLayerStatsSet);
1878 return -EINVAL;
1879 }
1880
1881 if (nla_parse(tb_vendor, QCA_WLAN_VENDOR_ATTR_LL_STATS_CLR_MAX,
1882 (struct nlattr *)data,
1883 data_len, qca_wlan_vendor_ll_clr_policy))
1884 {
1885 hddLog(VOS_TRACE_LEVEL_ERROR, FL() );
1886 return -EINVAL;
1887 }
1888
1889 if (!tb_vendor[QCA_WLAN_VENDOR_ATTR_LL_STATS_CLR_CONFIG_REQ_MASK] ||
1890
1891 !tb_vendor[QCA_WLAN_VENDOR_ATTR_LL_STATS_CLR_CONFIG_STOP_REQ])
1892 {
1893 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Error in LL_STATS CLR CONFIG PARA") );
1894 return -EINVAL;
1895
1896 }
1897
Sunil Duttc69bccb2014-05-26 21:30:20 +05301898
Dino Mycledf0a5d92014-07-04 09:41:55 +05301899 statsClearReqMask = linkLayerStatsClearReq.statsClearReqMask =
Sunil Duttc69bccb2014-05-26 21:30:20 +05301900 nla_get_u32(
1901 tb_vendor[QCA_WLAN_VENDOR_ATTR_LL_STATS_CLR_CONFIG_REQ_MASK]);
1902
Dino Mycledf0a5d92014-07-04 09:41:55 +05301903 stopReq = linkLayerStatsClearReq.stopReq =
Sunil Duttc69bccb2014-05-26 21:30:20 +05301904 nla_get_u8(
1905 tb_vendor[QCA_WLAN_VENDOR_ATTR_LL_STATS_CLR_CONFIG_STOP_REQ]);
1906
1907 // Shall take the request Id if the Upper layers pass. 1 For now.
Dino Mycledf0a5d92014-07-04 09:41:55 +05301908 linkLayerStatsClearReq.reqId = 1;
Sunil Duttc69bccb2014-05-26 21:30:20 +05301909
Dino Mycled3d50022014-07-07 12:58:25 +05301910 vos_mem_copy(linkLayerStatsClearReq.macAddr,
1911 pAdapter->macAddressCurrent.bytes, sizeof(v_MACADDR_t));
Sunil Duttc69bccb2014-05-26 21:30:20 +05301912
1913 hddLog(VOS_TRACE_LEVEL_INFO,
Dino Mycledf0a5d92014-07-04 09:41:55 +05301914 "LL_STATS_CLEAR reqId = %d", linkLayerStatsClearReq.reqId);
Sunil Duttc69bccb2014-05-26 21:30:20 +05301915 hddLog(VOS_TRACE_LEVEL_INFO,
Dino Mycled3d50022014-07-07 12:58:25 +05301916 "LL_STATS_CLEAR MAC = %pM", linkLayerStatsClearReq.macAddr);
Sunil Duttc69bccb2014-05-26 21:30:20 +05301917 hddLog(VOS_TRACE_LEVEL_INFO,
1918 "LL_STATS_CLEAR statsClearReqMask = 0x%X",
Dino Mycledf0a5d92014-07-04 09:41:55 +05301919 linkLayerStatsClearReq.statsClearReqMask);
Sunil Duttc69bccb2014-05-26 21:30:20 +05301920 hddLog(VOS_TRACE_LEVEL_INFO,
1921 "LL_STATS_CLEAR stopReq = %d",
Dino Mycledf0a5d92014-07-04 09:41:55 +05301922 linkLayerStatsClearReq.stopReq);
Sunil Duttc69bccb2014-05-26 21:30:20 +05301923
1924 if (eHAL_STATUS_SUCCESS == sme_LLStatsClearReq(pHddCtx->hHal,
Dino Mycledf0a5d92014-07-04 09:41:55 +05301925 &linkLayerStatsClearReq))
Sunil Duttc69bccb2014-05-26 21:30:20 +05301926 {
1927 struct sk_buff *temp_skbuff;
1928 temp_skbuff = cfg80211_vendor_cmd_alloc_reply_skb(wiphy,
1929 2 * sizeof(u32) +
1930 NLMSG_HDRLEN);
1931
1932 if (temp_skbuff != NULL)
1933 {
1934
1935 if (nla_put_u32(temp_skbuff,
1936 QCA_WLAN_VENDOR_ATTR_LL_STATS_CLR_CONFIG_RSP_MASK,
1937 statsClearReqMask) ||
1938 nla_put_u32(temp_skbuff,
1939 QCA_WLAN_VENDOR_ATTR_LL_STATS_CLR_CONFIG_STOP_RSP,
1940 stopReq))
1941 {
1942 hddLog(VOS_TRACE_LEVEL_ERROR, FL("LL_STATS_CLR put fail"));
1943 kfree_skb(temp_skbuff);
1944 return -EINVAL;
1945 }
1946 /* If the ask is to stop the stats collection as part of clear
1947 * (stopReq = 1) , ensure that no further requests of get
1948 * go to the firmware by having isLinkLayerStatsSet set to 0.
1949 * However it the stopReq as part of the clear request is 0 ,
Dino Mycledf0a5d92014-07-04 09:41:55 +05301950 * the request to get the statistics are honoured as in this
Sunil Duttc69bccb2014-05-26 21:30:20 +05301951 * case the firmware is just asked to clear the statistics.
1952 */
Dino Mycledf0a5d92014-07-04 09:41:55 +05301953 if (linkLayerStatsClearReq.stopReq == 1)
Sunil Duttc69bccb2014-05-26 21:30:20 +05301954 pAdapter->isLinkLayerStatsSet = 0;
1955 return cfg80211_vendor_cmd_reply(temp_skbuff);
1956 }
1957 return -ENOMEM;
1958 }
Sunil Duttc69bccb2014-05-26 21:30:20 +05301959 return -EINVAL;
1960}
1961#endif /* WLAN_FEATURE_LINK_LAYER_STATS */
1962
Dino Mycle6fb96c12014-06-10 11:52:40 +05301963#ifdef WLAN_FEATURE_EXTSCAN
1964static const struct nla_policy
1965wlan_hdd_extscan_config_policy
1966 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX + 1] =
1967{
1968 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_REQUEST_ID] =
1969 { .type = NLA_U32 },
1970 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_GET_VALID_CHANNELS_CONFIG_PARAM_WIFI_BAND] =
1971 { .type = NLA_U32 },
1972 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_CHANNEL_SPEC_CHANNEL] = { .type = NLA_U32 },
1973 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_CHANNEL_SPEC_DWELL_TIME] =
1974 { .type = NLA_U32 },
1975 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_CHANNEL_SPEC_PASSIVE] = { .type = NLA_U8 },
1976 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_CHANNEL_SPEC_CLASS] = { .type = NLA_U8 },
1977
1978 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_INDEX] = { .type = NLA_U8 },
1979 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_BAND] = { .type = NLA_U8 },
1980 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_PERIOD] = { .type = NLA_U32 },
1981 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_REPORT_EVENTS] =
1982 { .type = NLA_U8 },
1983 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_NUM_CHANNEL_SPECS] =
1984 { .type = NLA_U32 },
1985 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_SCAN_CMD_PARAMS_BASE_PERIOD] =
1986 { .type = NLA_U32 },
1987 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_SCAN_CMD_PARAMS_MAX_AP_PER_SCAN] =
1988 { .type = NLA_U32 },
1989 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_SCAN_CMD_PARAMS_REPORT_THRESHOLD] =
1990 { .type = NLA_U8 },
1991 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_SCAN_CMD_PARAMS_NUM_BUCKETS] =
1992 { .type = NLA_U8 },
1993 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_GET_CACHED_SCAN_RESULTS_CONFIG_PARAM_FLUSH] =
1994 { .type = NLA_U8 },
1995
1996 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_GET_CACHED_SCAN_RESULTS_CONFIG_PARAM_MAX] =
1997 { .type = NLA_U32 },
1998 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_AP_THRESHOLD_PARAM_BSSID] =
1999 { .type = NLA_UNSPEC },
2000 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_AP_THRESHOLD_PARAM_RSSI_LOW] =
2001 { .type = NLA_S32 },
2002 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_AP_THRESHOLD_PARAM_RSSI_HIGH] =
2003 { .type = NLA_S32 },
2004 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_AP_THRESHOLD_PARAM_CHANNEL] =
2005 { .type = NLA_U32 },
2006 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_BSSID_HOTLIST_PARAMS_NUM_AP] =
2007 { .type = NLA_U32 },
2008 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_SIGNIFICANT_CHANGE_PARAMS_RSSI_SAMPLE_SIZE] =
2009 { .type = NLA_U32 },
2010 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_SIGNIFICANT_CHANGE_PARAMS_LOST_AP_SAMPLE_SIZE]
2011 = { .type = NLA_U32 },
2012 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_SIGNIFICANT_CHANGE_PARAMS_MIN_BREACHING] =
2013 { .type = NLA_U32 },
2014 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_SIGNIFICANT_CHANGE_PARAMS_NUM_AP] = { .type =
2015 NLA_U32 },
2016};
2017
2018static void wlan_hdd_cfg80211_extscan_get_capabilities_ind(void *ctx, void *pMsg)
2019{
2020 hdd_context_t *pHddCtx = (hdd_context_t *)ctx;
2021 struct sk_buff *skb = NULL;
2022 tpSirEXTScanCapabilitiesEvent pData =
2023 (tpSirEXTScanCapabilitiesEvent) pMsg;
2024
2025 if (wlan_hdd_validate_context(pHddCtx) || !pData) {
2026 hddLog(VOS_TRACE_LEVEL_ERROR, FL("HDD context is not valid "
2027 "or pData(%p) is null"), pData);
2028 return;
2029 }
2030
2031 skb = cfg80211_vendor_event_alloc(pHddCtx->wiphy,
2032 EXTSCAN_EVENT_BUF_SIZE + NLMSG_HDRLEN,
2033 QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_GET_CAPABILITIES_INDEX,
2034 GFP_KERNEL);
2035
2036 if (!skb) {
2037 hddLog(VOS_TRACE_LEVEL_ERROR,
2038 FL("cfg80211_vendor_event_alloc failed"));
2039 return;
2040 }
2041
2042 hddLog(VOS_TRACE_LEVEL_INFO, "Req Id (%u)", pData->requestId);
2043 hddLog(VOS_TRACE_LEVEL_INFO, "Scan cache size (%u)", pData->scanCacheSize);
2044 hddLog(VOS_TRACE_LEVEL_INFO, "Scan buckets (%u)", pData->scanBuckets);
2045 hddLog(VOS_TRACE_LEVEL_INFO, "Max AP per scan (%u)", pData->maxApPerScan);
2046 hddLog(VOS_TRACE_LEVEL_INFO, "maxRssiSampleSize (%u)",
2047 pData->maxRssiSampleSize);
2048 hddLog(VOS_TRACE_LEVEL_INFO, "maxScanReportingThreshold (%u)",
2049 pData->maxScanReportingThreshold);
2050 hddLog(VOS_TRACE_LEVEL_INFO, "maxHotlistAPs (%u)", pData->maxHotlistAPs);
2051 hddLog(VOS_TRACE_LEVEL_INFO, "maxSignificantWifiChangeAPs (%u)",
2052 pData->maxSignificantWifiChangeAPs);
2053 hddLog(VOS_TRACE_LEVEL_INFO, "maxBsidHistoryEntries (%u)",
2054 pData->maxBsidHistoryEntries);
2055
2056 if (nla_put_u32(skb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_REQUEST_ID,
2057 pData->requestId) ||
2058 nla_put_u32(skb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_STATUS, pData->status) ||
2059 nla_put_u32(skb,
2060 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_CAPABILITIES_MAX_SCAN_CACHE_SIZE,
2061 pData->scanCacheSize) ||
2062 nla_put_u32(skb,
2063 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_CAPABILITIES_MAX_SCAN_BUCKETS,
2064 pData->scanBuckets) ||
2065 nla_put_u32(skb,
2066 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_CAPABILITIES_MAX_AP_CACHE_PER_SCAN,
2067 pData->maxApPerScan) ||
2068 nla_put_u32(skb,
2069 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_CAPABILITIES_MAX_RSSI_SAMPLE_SIZE,
2070 pData->maxRssiSampleSize) ||
2071 nla_put_u32(skb,
2072 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_CAPABILITIES_MAX_SCAN_REPORTING_THRESHOLD,
2073 pData->maxScanReportingThreshold) ||
2074 nla_put_u32(skb,
2075 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_CAPABILITIES_MAX_HOTLIST_APS,
2076 pData->maxHotlistAPs) ||
2077 nla_put_u32(skb,
2078 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_CAPABILITIES_MAX_SIGNIFICANT_WIFI_CHANGE_APS,
2079 pData->maxSignificantWifiChangeAPs) ||
2080 nla_put_u32(skb,
2081 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_CAPABILITIES_MAX_BSSID_HISTORY_ENTRIES,
2082 pData->maxBsidHistoryEntries)) {
2083 hddLog(VOS_TRACE_LEVEL_ERROR, FL("nla put fail"));
2084 goto nla_put_failure;
2085 }
2086
2087 cfg80211_vendor_event(skb, GFP_KERNEL);
2088 return;
2089
2090nla_put_failure:
2091 kfree_skb(skb);
2092 return;
2093}
2094
2095
2096static void wlan_hdd_cfg80211_extscan_start_rsp(void *ctx, void *pMsg)
2097{
2098 tpSirEXTScanStartRspParams pData = (tpSirEXTScanStartRspParams) pMsg;
2099 hdd_context_t *pHddCtx = (hdd_context_t *)ctx;
2100 struct sk_buff *skb = NULL;
2101 tpAniSirGlobal pMac = PMAC_STRUCT( pHddCtx->hHal );
2102
2103
2104 if (wlan_hdd_validate_context(pHddCtx) || !pData) {
2105 hddLog(VOS_TRACE_LEVEL_ERROR, FL("HDD context is not valid "
2106 "or pData(%p) is null"), pData);
2107 return;
2108 }
2109
2110 skb = cfg80211_vendor_event_alloc(pHddCtx->wiphy,
2111 EXTSCAN_EVENT_BUF_SIZE + NLMSG_HDRLEN,
2112 QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_START_INDEX,
2113 GFP_KERNEL);
2114
2115 if (!skb) {
2116 hddLog(VOS_TRACE_LEVEL_ERROR,
2117 FL("cfg80211_vendor_event_alloc failed"));
2118 return;
2119 }
2120 hddLog(VOS_TRACE_LEVEL_INFO, FL("Entering "));
2121 hddLog(VOS_TRACE_LEVEL_INFO, "Req Id (%u)", pData->requestId);
2122 hddLog(VOS_TRACE_LEVEL_INFO, "Status (%u)", pData->status);
2123
2124 if (nla_put_u32(skb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_REQUEST_ID,
2125 pData->requestId) ||
2126 nla_put_u32(skb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_STATUS, pData->status)) {
2127 hddLog(VOS_TRACE_LEVEL_ERROR, FL("nla put fail"));
2128 goto nla_put_failure;
2129 }
2130
2131 /*
2132 * Store the Request ID for comparing with the requestID obtained
2133 * in other requests.HDD shall return a failure is the extscan_stop
2134 * request is issued with a different requestId as that of the
2135 * extscan_start request. Also, This requestId shall be used while
2136 * indicating the full scan results to the upper layers.
2137 * The requestId is stored with the assumption that the firmware
2138 * shall return the ext scan start request's requestId in ext scan
2139 * start response.
2140 */
2141 if (pData->status == 0)
2142 pMac->sme.extScanStartReqId = pData->requestId;
2143
2144
2145 cfg80211_vendor_event(skb, GFP_KERNEL);
2146 return;
2147
2148nla_put_failure:
2149 kfree_skb(skb);
2150 return;
2151}
2152
2153
2154static void wlan_hdd_cfg80211_extscan_stop_rsp(void *ctx, void *pMsg)
2155{
2156 tpSirEXTScanStopRspParams pData = (tpSirEXTScanStopRspParams) pMsg;
2157 hdd_context_t *pHddCtx = (hdd_context_t *)ctx;
2158 struct sk_buff *skb = NULL;
2159
2160 if (wlan_hdd_validate_context(pHddCtx) || !pData) {
2161 hddLog(VOS_TRACE_LEVEL_ERROR, FL("HDD context is not valid "
2162 "or pData(%p) is null"), pData);
2163 return;
2164 }
2165
2166 skb = cfg80211_vendor_event_alloc(pHddCtx->wiphy,
2167 EXTSCAN_EVENT_BUF_SIZE + NLMSG_HDRLEN,
2168 QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_STOP_INDEX,
2169 GFP_KERNEL);
2170
2171 if (!skb) {
2172 hddLog(VOS_TRACE_LEVEL_ERROR,
2173 FL("cfg80211_vendor_event_alloc failed"));
2174 return;
2175 }
2176 hddLog(VOS_TRACE_LEVEL_INFO, FL("Entering "));
2177 hddLog(VOS_TRACE_LEVEL_INFO, "Req Id (%u)", pData->requestId);
2178
2179 if (nla_put_u32(skb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_REQUEST_ID,
2180 pData->requestId) ||
2181 nla_put_u32(skb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_STATUS, pData->status)) {
2182 hddLog(VOS_TRACE_LEVEL_ERROR, FL("nla put fail"));
2183 goto nla_put_failure;
2184 }
2185
2186 cfg80211_vendor_event(skb, GFP_KERNEL);
2187 return;
2188
2189nla_put_failure:
2190 kfree_skb(skb);
2191 return;
2192}
2193
2194
2195static void wlan_hdd_cfg80211_extscan_set_bss_hotlist_rsp(void *ctx,
2196 void *pMsg)
2197{
2198 hdd_context_t *pHddCtx = (hdd_context_t *)ctx;
2199 struct sk_buff *skb = NULL;
2200 tpSirEXTScanSetBssidHotListRspParams pData =
2201 (tpSirEXTScanSetBssidHotListRspParams) pMsg;
2202
2203 if (wlan_hdd_validate_context(pHddCtx) || !pData) {
2204 hddLog(VOS_TRACE_LEVEL_ERROR, FL("HDD context is not valid "
2205 "or pData(%p) is null"), pData);
2206 return;
2207 }
2208 skb = cfg80211_vendor_event_alloc(pHddCtx->wiphy,
2209 EXTSCAN_EVENT_BUF_SIZE + NLMSG_HDRLEN,
2210 QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_SET_BSSID_HOTLIST_INDEX,
2211 GFP_KERNEL);
2212
2213 if (!skb) {
2214 hddLog(VOS_TRACE_LEVEL_ERROR,
2215 FL("cfg80211_vendor_event_alloc failed"));
2216 return;
2217 }
2218 hddLog(VOS_TRACE_LEVEL_INFO, FL("Entering "));
2219 hddLog(VOS_TRACE_LEVEL_INFO, "Req Id (%u)", pData->requestId);
2220 hddLog(VOS_TRACE_LEVEL_INFO, "Status (%u)", pData->status);
2221
2222 if (nla_put_u32(skb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_REQUEST_ID,
2223 pData->requestId) ||
2224 nla_put_u32(skb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_STATUS, pData->status)) {
2225 hddLog(VOS_TRACE_LEVEL_ERROR, FL("nla put fail"));
2226 goto nla_put_failure;
2227 }
2228
2229 cfg80211_vendor_event(skb, GFP_KERNEL);
2230 return;
2231
2232nla_put_failure:
2233 kfree_skb(skb);
2234 return;
2235}
2236
2237static void wlan_hdd_cfg80211_extscan_reset_bss_hotlist_rsp(void *ctx,
2238 void *pMsg)
2239{
2240 hdd_context_t *pHddCtx = (hdd_context_t *)ctx;
2241 struct sk_buff *skb = NULL;
2242 tpSirEXTScanResetBssidHotlistRspParams pData =
2243 (tpSirEXTScanResetBssidHotlistRspParams) pMsg;
2244
2245 if (wlan_hdd_validate_context(pHddCtx) || !pData) {
2246 hddLog(VOS_TRACE_LEVEL_ERROR, FL("HDD context is not valid "
2247 "or pData(%p) is null"), pData);
2248 return;
2249 }
2250
2251 skb = cfg80211_vendor_event_alloc(pHddCtx->wiphy,
2252 EXTSCAN_EVENT_BUF_SIZE + NLMSG_HDRLEN,
2253 QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_RESET_BSSID_HOTLIST_INDEX,
2254 GFP_KERNEL);
2255
2256 if (!skb) {
2257 hddLog(VOS_TRACE_LEVEL_ERROR,
2258 FL("cfg80211_vendor_event_alloc failed"));
2259 return;
2260 }
2261 hddLog(VOS_TRACE_LEVEL_INFO, FL("Entering "));
2262 hddLog(VOS_TRACE_LEVEL_INFO, "Req Id (%u)", pData->requestId);
2263
2264 if (nla_put_u32(skb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_REQUEST_ID,
2265 pData->requestId) ||
2266 nla_put_u32(skb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_STATUS, pData->status)) {
2267 hddLog(VOS_TRACE_LEVEL_ERROR, FL("nla put fail"));
2268 goto nla_put_failure;
2269 }
2270
2271 cfg80211_vendor_event(skb, GFP_KERNEL);
2272 return;
2273
2274nla_put_failure:
2275 kfree_skb(skb);
2276 return;
2277}
2278
2279
2280static void wlan_hdd_cfg80211_extscan_set_signf_wifi_change_rsp(void *ctx,
2281 void *pMsg)
2282{
2283 hdd_context_t *pHddCtx = (hdd_context_t *)ctx;
2284 struct sk_buff *skb = NULL;
2285 tpSirEXTScanSetSignificantChangeRspParams pData =
2286 (tpSirEXTScanSetSignificantChangeRspParams) pMsg;
2287
2288 if (wlan_hdd_validate_context(pHddCtx) || !pData) {
2289 hddLog(VOS_TRACE_LEVEL_ERROR, FL("HDD context is not valid "
2290 "or pData(%p) is null"), pData);
2291 return;
2292 }
2293
2294 skb = cfg80211_vendor_event_alloc(pHddCtx->wiphy,
2295 EXTSCAN_EVENT_BUF_SIZE + NLMSG_HDRLEN,
2296 QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_SET_SIGNIFICANT_CHANGE_INDEX,
2297 GFP_KERNEL);
2298
2299 if (!skb) {
2300 hddLog(VOS_TRACE_LEVEL_ERROR,
2301 FL("cfg80211_vendor_event_alloc failed"));
2302 return;
2303 }
2304 hddLog(VOS_TRACE_LEVEL_INFO, FL("Entering "));
2305 hddLog(VOS_TRACE_LEVEL_INFO, "Req Id (%u)", pData->requestId);
2306 hddLog(VOS_TRACE_LEVEL_INFO, "Status (%u)", pData->status);
2307
2308 if (nla_put_u32(skb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_REQUEST_ID,
2309 pData->requestId) ||
2310 nla_put_u32(skb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_STATUS, pData->status)) {
2311 hddLog(VOS_TRACE_LEVEL_ERROR, FL("nla put fail"));
2312 goto nla_put_failure;
2313 }
2314
2315 cfg80211_vendor_event(skb, GFP_KERNEL);
2316 return;
2317
2318nla_put_failure:
2319 kfree_skb(skb);
2320 return;
2321}
2322
2323
2324static void wlan_hdd_cfg80211_extscan_reset_signf_wifi_change_rsp(void *ctx,
2325 void *pMsg)
2326{
2327 hdd_context_t *pHddCtx = (hdd_context_t *)ctx;
2328 struct sk_buff *skb = NULL;
2329 tpSirEXTScanResetSignificantChangeRspParams pData =
2330 (tpSirEXTScanResetSignificantChangeRspParams) pMsg;
2331
2332 if (wlan_hdd_validate_context(pHddCtx) || !pData) {
2333 hddLog(VOS_TRACE_LEVEL_ERROR, FL("HDD context is not valid "
2334 "or pData(%p) is null"), pData);
2335 return;
2336 }
2337
2338 skb = cfg80211_vendor_event_alloc(pHddCtx->wiphy,
2339 EXTSCAN_EVENT_BUF_SIZE + NLMSG_HDRLEN,
2340 QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_RESET_SIGNIFICANT_CHANGE_INDEX,
2341 GFP_KERNEL);
2342
2343 if (!skb) {
2344 hddLog(VOS_TRACE_LEVEL_ERROR,
2345 FL("cfg80211_vendor_event_alloc failed"));
2346 return;
2347 }
2348 hddLog(VOS_TRACE_LEVEL_INFO, FL("Entering "));
2349 hddLog(VOS_TRACE_LEVEL_INFO, "Req Id (%u)", pData->requestId);
2350 hddLog(VOS_TRACE_LEVEL_INFO, "Status (%u)", pData->status);
2351
2352 if (nla_put_u32(skb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_REQUEST_ID,
2353 pData->requestId) ||
2354 nla_put_u32(skb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_STATUS, pData->status)) {
2355 hddLog(VOS_TRACE_LEVEL_ERROR, FL("nla put fail"));
2356 goto nla_put_failure;
2357 }
2358
2359 cfg80211_vendor_event(skb, GFP_KERNEL);
2360 return;
2361
2362nla_put_failure:
2363 kfree_skb(skb);
2364 return;
2365}
2366
2367static void wlan_hdd_cfg80211_extscan_cached_results_ind(void *ctx,
2368 void *pMsg)
2369{
2370 hdd_context_t *pHddCtx = (hdd_context_t *)ctx;
2371 struct sk_buff *skb = NULL;
2372 tANI_U32 i = 0, j, resultsPerEvent;
2373 tANI_S32 totalResults;
2374 tpSirWifiScanResultEvent pData = (tpSirWifiScanResultEvent) pMsg;
2375 tpSirWifiScanResult pSirWifiScanResult;
2376
2377 if (wlan_hdd_validate_context(pHddCtx) || !pData) {
2378 hddLog(VOS_TRACE_LEVEL_ERROR, FL("HDD context is not valid "
2379 "or pData(%p) is null"), pData);
2380 return;
2381 }
2382 totalResults = pData->numOfAps;
2383 hddLog(VOS_TRACE_LEVEL_INFO, "Req Id (%u)", pData->requestId);
2384 hddLog(VOS_TRACE_LEVEL_INFO, "Num results (%u)", pData->numOfAps);
2385 hddLog(VOS_TRACE_LEVEL_INFO, "More Data (%u)", pData->moreData);
2386
2387 do{
2388 resultsPerEvent = ((totalResults >= EXTSCAN_MAX_CACHED_RESULTS_PER_IND) ?
2389 EXTSCAN_MAX_CACHED_RESULTS_PER_IND : totalResults);
2390 totalResults -= EXTSCAN_MAX_CACHED_RESULTS_PER_IND;
2391
2392 skb = cfg80211_vendor_event_alloc(pHddCtx->wiphy,
2393 EXTSCAN_EVENT_BUF_SIZE + NLMSG_HDRLEN,
2394 QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_GET_CACHED_RESULTS_INDEX,
2395 GFP_KERNEL);
2396
2397 if (!skb) {
2398 hddLog(VOS_TRACE_LEVEL_ERROR,
2399 FL("cfg80211_vendor_event_alloc failed"));
2400 return;
2401 }
2402
2403 hddLog(VOS_TRACE_LEVEL_INFO, "resultsPerEvent (%u)", resultsPerEvent);
2404
2405 if (nla_put_u32(skb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_REQUEST_ID,
2406 pData->requestId) ||
2407 nla_put_u32(skb,
2408 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_NUM_RESULTS_AVAILABLE,
2409 resultsPerEvent)) {
2410 hddLog(VOS_TRACE_LEVEL_ERROR, FL("put fail"));
2411 goto fail;
2412 }
2413 if (nla_put_u8(skb,
2414 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_MORE_DATA,
2415 pData->moreData ? 1 : (totalResults > 0 ? 1 : 0 )))
2416 {
2417 hddLog(VOS_TRACE_LEVEL_ERROR, FL("put fail"));
2418 goto fail;
2419 }
2420
2421 if (resultsPerEvent) {
2422 struct nlattr *aps;
2423
2424 aps = nla_nest_start(skb,
2425 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_LIST);
2426 if (!aps)
2427 {
2428 hddLog(VOS_TRACE_LEVEL_ERROR, FL("put fail"));
2429 goto fail;
2430 }
2431
2432 for (j = 0; j < resultsPerEvent; j++, i++) {
2433 struct nlattr *ap;
2434 pSirWifiScanResult = (tpSirWifiScanResult) ((tANI_U8 *)
2435 pData->ap + ( i* sizeof(tSirWifiScanResult)));
2436
2437 hddLog(VOS_TRACE_LEVEL_INFO, "[index=%u] Timestamp(%llu) "
2438 "Ssid (%s)"
2439 "Bssid: %pM "
2440 "Channel (%u)"
2441 "Rssi (%d)"
2442 "RTT (%u)"
2443 "RTT_SD (%u)",
2444 i,
2445 pSirWifiScanResult->ts,
2446 pSirWifiScanResult->ssid,
2447 pSirWifiScanResult->bssid,
2448 pSirWifiScanResult->channel,
2449 pSirWifiScanResult->rssi,
2450 pSirWifiScanResult->rtt,
2451 pSirWifiScanResult->rtt_sd);
2452
2453 ap = nla_nest_start(skb, j + 1);
2454 if (!ap)
2455 {
2456 hddLog(VOS_TRACE_LEVEL_ERROR, FL("put fail"));
2457 goto fail;
2458 }
2459
2460 if (nla_put_u64(skb,
2461 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_TIME_STAMP,
2462 pSirWifiScanResult->ts) )
2463 {
2464 hddLog(VOS_TRACE_LEVEL_ERROR, FL("put fail"));
2465 goto fail;
2466 }
2467 if (nla_put(skb,
2468 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_SSID,
2469 sizeof(pSirWifiScanResult->ssid),
2470 pSirWifiScanResult->ssid) )
2471 {
2472 hddLog(VOS_TRACE_LEVEL_ERROR, FL("put fail"));
2473 goto fail;
2474 }
2475 if (nla_put(skb,
2476 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_BSSID,
2477 sizeof(pSirWifiScanResult->bssid),
2478 pSirWifiScanResult->bssid) )
2479 {
2480 hddLog(VOS_TRACE_LEVEL_ERROR, FL("put fail"));
2481 goto fail;
2482 }
2483 if (nla_put_u32(skb,
2484 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_CHANNEL,
2485 pSirWifiScanResult->channel) )
2486 {
2487 hddLog(VOS_TRACE_LEVEL_ERROR, FL("put fail"));
2488 goto fail;
2489 }
2490 if (nla_put_u32(skb,
2491 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_RSSI,
2492 pSirWifiScanResult->rssi) )
2493 {
2494 hddLog(VOS_TRACE_LEVEL_ERROR, FL("put fail"));
2495 goto fail;
2496 }
2497 if (nla_put_u32(skb,
2498 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_RTT,
2499 pSirWifiScanResult->rtt) )
2500 {
2501 hddLog(VOS_TRACE_LEVEL_ERROR, FL("put fail"));
2502 goto fail;
2503 }
2504 if (nla_put_u32(skb,
2505 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_RTT_SD,
2506 pSirWifiScanResult->rtt_sd))
2507 {
2508 hddLog(VOS_TRACE_LEVEL_ERROR, FL("put fail"));
2509 goto fail;
2510 }
2511
2512 nla_nest_end(skb, ap);
2513 }
2514 nla_nest_end(skb, aps);
2515
2516 }
2517 cfg80211_vendor_event(skb, GFP_KERNEL);
2518 } while (totalResults > 0);
2519
2520 return;
2521fail:
2522 kfree_skb(skb);
2523 return;
2524}
2525
2526static void wlan_hdd_cfg80211_extscan_hotlist_match_ind(void *ctx,
2527 void *pMsg)
2528{
2529 tpSirWifiScanResultEvent pData = (tpSirWifiScanResultEvent) pMsg;
2530 hdd_context_t *pHddCtx = (hdd_context_t *)ctx;
2531 struct sk_buff *skb = NULL;
2532 tANI_U32 i;
2533
2534 if (wlan_hdd_validate_context(pHddCtx) || !pData) {
2535 hddLog(VOS_TRACE_LEVEL_ERROR, FL("HDD context is not valid "
2536 "or pData(%p) is null"), pData);
2537 return;
2538 }
2539
2540 skb = cfg80211_vendor_event_alloc(pHddCtx->wiphy,
2541 EXTSCAN_EVENT_BUF_SIZE + NLMSG_HDRLEN,
2542 QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_HOTLIST_AP_FOUND_INDEX,
2543 GFP_KERNEL);
2544
2545 if (!skb) {
2546 hddLog(VOS_TRACE_LEVEL_ERROR,
2547 FL("cfg80211_vendor_event_alloc failed"));
2548 return;
2549 }
2550 hddLog(VOS_TRACE_LEVEL_INFO, FL("Entering "));
2551 hddLog(VOS_TRACE_LEVEL_INFO, "Req Id (%u)", pData->requestId);
2552 hddLog(VOS_TRACE_LEVEL_INFO, "Num results (%u)", pData->numOfAps);
2553 hddLog(VOS_TRACE_LEVEL_INFO, "More Data (%u)", pData->moreData);
2554
2555 for (i = 0; i < pData->numOfAps; i++) {
2556 hddLog(VOS_TRACE_LEVEL_INFO, "[index=%u] Timestamp(0x%lld) "
2557 "Ssid (%s) "
2558 "Bssid (" MAC_ADDRESS_STR ") "
2559 "Channel (%u) "
2560 "Rssi (%d) "
2561 "RTT (%u) "
2562 "RTT_SD (%u) ",
2563 i,
2564 pData->ap[i].ts,
2565 pData->ap[i].ssid,
2566 MAC_ADDR_ARRAY(pData->ap[i].bssid),
2567 pData->ap[i].channel,
2568 pData->ap[i].rssi,
2569 pData->ap[i].rtt,
2570 pData->ap[i].rtt_sd);
2571 }
2572
2573 if (nla_put_u32(skb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_REQUEST_ID,
2574 pData->requestId) ||
2575 nla_put_u32(skb,
2576 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_NUM_RESULTS_AVAILABLE,
2577 pData->numOfAps)) {
2578 hddLog(VOS_TRACE_LEVEL_ERROR, FL("put fail"));
2579 goto fail;
2580 }
2581 if (pData->numOfAps) {
2582 struct nlattr *aps;
2583
2584 aps = nla_nest_start(skb,
2585 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_LIST);
2586 if (!aps)
2587 goto fail;
2588
2589 for (i = 0; i < pData->numOfAps; i++) {
2590 struct nlattr *ap;
2591
2592 ap = nla_nest_start(skb, i + 1);
2593 if (!ap)
2594 goto fail;
2595
2596 if (nla_put_u64(skb,
2597 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_TIME_STAMP,
2598 pData->ap[i].ts) ||
2599 nla_put(skb,
2600 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_SSID,
2601 sizeof(pData->ap[i].ssid),
2602 pData->ap[i].ssid) ||
2603 nla_put(skb,
2604 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_BSSID,
2605 sizeof(pData->ap[i].bssid),
2606 pData->ap[i].bssid) ||
2607 nla_put_u32(skb,
2608 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_CHANNEL,
2609 pData->ap[i].channel) ||
2610 nla_put_s32(skb,
2611 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_RSSI,
2612 pData->ap[i].rssi) ||
2613 nla_put_u32(skb,
2614 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_RTT,
2615 pData->ap[i].rtt) ||
2616 nla_put_u32(skb,
2617 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_RTT_SD,
2618 pData->ap[i].rtt_sd))
2619 goto fail;
2620
2621 nla_nest_end(skb, ap);
2622 }
2623 nla_nest_end(skb, aps);
2624
2625 if (nla_put_u8(skb,
2626 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_MORE_DATA,
2627 pData->moreData))
2628 goto fail;
2629 }
2630
2631 cfg80211_vendor_event(skb, GFP_KERNEL);
2632 return;
2633
2634fail:
2635 kfree_skb(skb);
2636 return;
2637
2638}
2639static void wlan_hdd_cfg80211_extscan_signif_wifi_change_results_ind(void *ctx,
2640 void *pMsg)
2641{
2642 hdd_context_t *pHddCtx = (hdd_context_t *)ctx;
2643 struct sk_buff *skb = NULL;
2644 tANI_U32 i, j;
2645 tpSirWifiSignificantChangeEvent pData =
2646 (tpSirWifiSignificantChangeEvent) pMsg;
2647
2648 if (wlan_hdd_validate_context(pHddCtx) || !pData) {
2649 hddLog(VOS_TRACE_LEVEL_ERROR, FL("HDD context is not valid "
2650 "or pData(%p) is null"), pData);
2651 return;
2652 }
2653 skb = cfg80211_vendor_event_alloc(pHddCtx->wiphy,
2654 EXTSCAN_EVENT_BUF_SIZE,
2655 QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_SIGNIFICANT_CHANGE_INDEX,
2656 GFP_KERNEL);
2657
2658 if (!skb) {
2659 hddLog(VOS_TRACE_LEVEL_ERROR,
2660 FL("cfg80211_vendor_event_alloc failed"));
2661 return;
2662 }
2663 hddLog(VOS_TRACE_LEVEL_INFO, FL("Entering "));
2664 hddLog(VOS_TRACE_LEVEL_INFO, "Req Id (%u)", pData->requestId);
2665 hddLog(VOS_TRACE_LEVEL_INFO, "total List Size %u ", pData->numSigRssiBss);
2666 hddLog(VOS_TRACE_LEVEL_INFO, " CUrrent List size (%u)",
2667 pData->numSigRssiBss);
2668 hddLog(VOS_TRACE_LEVEL_INFO, "moreData (%u)", pData->moreData);
2669
2670 for (i = 0; i < pData->numSigRssiBss; i++) {
2671 hddLog(VOS_TRACE_LEVEL_INFO , "Rssi List [%d] BSSID: (%pM) Channel %u "
2672 " num RSSI %u ",
2673 i, pData->sigRssiResult[i].bssid,
2674 pData->sigRssiResult[i].channel,
2675 pData->sigRssiResult[i].numRssi);
2676
2677 for (j = 0; j < pData->sigRssiResult[i].numRssi; j++){
2678
2679 hddLog(VOS_TRACE_LEVEL_INFO,
2680 " [%d]",
Dino Myclec8f3f332014-07-21 16:48:27 +05302681 pData->sigRssiResult[i].rssi[j]);
Dino Mycle6fb96c12014-06-10 11:52:40 +05302682
2683 }
2684 }
2685
2686
2687 if (nla_put_u32(skb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_REQUEST_ID,
2688 pData->requestId) ||
2689 nla_put_u32(skb,
2690 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_NUM_RESULTS_AVAILABLE,
2691 pData->numSigRssiBss)) {
2692 hddLog(VOS_TRACE_LEVEL_ERROR, FL("put fail"));
2693 goto fail;
2694 }
2695
2696 if (pData->numSigRssiBss) {
2697 struct nlattr *aps;
2698 aps = nla_nest_start(skb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_LIST);
2699 if (!aps)
2700 goto fail;
2701 for (i = 0; i < pData->numSigRssiBss; i++) {
2702 struct nlattr *ap;
2703
2704 ap = nla_nest_start(skb, i);
2705 if (!ap)
2706 goto fail;
2707 if (nla_put(skb,
2708 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SIGNIFICANT_CHANGE_RESULT_BSSID,
2709 sizeof(tSirMacAddr), pData->sigRssiResult[i].bssid) ||
2710 nla_put_u32(skb,
2711 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SIGNIFICANT_CHANGE_RESULT_CHANNEL,
2712 pData->sigRssiResult[i].channel) ||
2713 nla_put_u32(skb,
2714 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SIGNIFICANT_CHANGE_RESULT_NUM_RSSI,
2715 pData->sigRssiResult[i].numRssi) ||
2716 nla_put(skb,
2717 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SIGNIFICANT_CHANGE_RESULT_RSSI_LIST,
2718 sizeof(s32) * pData->sigRssiResult[i].numRssi,
2719 pData->sigRssiResult[i].rssi))
2720 goto fail;
2721 nla_nest_end(skb, ap);
2722 }
2723 nla_nest_end(skb, aps);
2724 if (nla_put_u8(skb,
2725 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_MORE_DATA,
2726 pData->moreData))
2727 goto fail;
2728 }
2729 cfg80211_vendor_event(skb, GFP_KERNEL);
2730 return;
2731fail:
2732 kfree_skb(skb);
2733 return;
2734}
2735
2736static void wlan_hdd_cfg80211_extscan_full_scan_result_event(void *ctx,
2737 void *pMsg)
2738{
2739 struct sk_buff *skb;
2740 hdd_context_t *pHddCtx = (hdd_context_t *)ctx;
2741 tpSirWifiFullScanResultEvent pData =
2742 (tpSirWifiFullScanResultEvent) (pMsg);
2743
2744 if (wlan_hdd_validate_context(pHddCtx) || !pData) {
2745 hddLog(VOS_TRACE_LEVEL_ERROR, FL("HDD context is not valid "
2746 "or pData(%p) is null"), pData);
2747 return;
2748 }
2749
2750 skb = cfg80211_vendor_event_alloc(pHddCtx->wiphy,
2751 EXTSCAN_EVENT_BUF_SIZE + NLMSG_HDRLEN,
2752 QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_FULL_SCAN_RESULT_INDEX,
2753 GFP_KERNEL);
2754
2755 if (!skb) {
2756 hddLog(VOS_TRACE_LEVEL_ERROR,
2757 FL("cfg80211_vendor_event_alloc failed"));
2758 return;
2759 }
2760
2761 hddLog(VOS_TRACE_LEVEL_INFO, FL("Entering "));
2762 hddLog(VOS_TRACE_LEVEL_INFO, FL("Req Id (%u)"), pData->requestId);
2763 hddLog(VOS_TRACE_LEVEL_INFO, FL("More Data (%u)"), pData->moreData);
2764 hddLog(VOS_TRACE_LEVEL_INFO, FL("AP Info: Timestamp(0x%llX) "
2765 "Ssid (%s)"
2766 "Bssid (" MAC_ADDRESS_STR ")"
2767 "Channel (%u)"
2768 "Rssi (%d)"
2769 "RTT (%u)"
2770 "RTT_SD (%u)"),
2771 pData->ap.ts,
2772 pData->ap.ssid,
2773 MAC_ADDR_ARRAY(pData->ap.bssid),
2774 pData->ap.channel,
2775 pData->ap.rssi,
2776 pData->ap.rtt,
2777 pData->ap.rtt_sd);
2778 hddLog(VOS_TRACE_LEVEL_INFO, "IE Length (%u)", pData->ieLength);
2779 if (nla_put_u32(skb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_REQUEST_ID,
2780 pData->requestId) ||
2781 nla_put_u64(skb,
2782 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_TIME_STAMP,
2783 pData->ap.ts) ||
2784 nla_put(skb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_SSID,
2785 sizeof(pData->ap.ssid),
2786 pData->ap.ssid) ||
2787 nla_put(skb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_BSSID,
2788 WNI_CFG_BSSID_LEN,
2789 pData->ap.bssid) ||
2790 nla_put_u32(skb,
2791 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_CHANNEL,
2792 pData->ap.channel) ||
2793 nla_put_u32(skb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_RSSI,
2794 pData->ap.rssi) ||
2795 nla_put_u32(skb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_RTT,
2796 pData->ap.rtt) ||
2797 nla_put_u32(skb,
2798 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_RTT_SD,
2799 pData->ap.rtt_sd) ||
2800 nla_put_u16(skb,
2801 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_BEACON_PERIOD,
2802 pData->ap.beaconPeriod) ||
2803 nla_put_u16(skb,
2804 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_CAPABILITY,
2805 pData->ap.capability) ||
2806 nla_put_u32(skb,
2807 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_IE_LENGTH,
2808 pData->ieLength))
2809 {
2810 hddLog(VOS_TRACE_LEVEL_ERROR, FL("nla put fail"));
2811 goto nla_put_failure;
2812 }
2813 if (nla_put(skb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_IE_DATA,
2814 pData->ieLength,
2815 pData->ie))
2816 {
2817 hddLog(VOS_TRACE_LEVEL_ERROR, FL("nla put fail"));
2818 goto nla_put_failure;
2819 }
2820
2821 cfg80211_vendor_event(skb, GFP_KERNEL);
2822 return;
2823
2824nla_put_failure:
2825 kfree_skb(skb);
2826 return;
2827}
2828
2829static void wlan_hdd_cfg80211_extscan_scan_res_available_event(void *ctx,
2830 void *pMsg)
2831{
2832 hdd_context_t *pHddCtx = (hdd_context_t *)ctx;
2833 struct sk_buff *skb = NULL;
2834 tpSirEXTScanResultsAvailableIndParams pData =
2835 (tpSirEXTScanResultsAvailableIndParams) pMsg;
2836
2837 if (wlan_hdd_validate_context(pHddCtx) || !pData) {
2838 hddLog(VOS_TRACE_LEVEL_ERROR, FL("HDD context is not valid "
2839 "or pData(%p) is null"), pData);
2840 return;
2841 }
2842
2843 skb = cfg80211_vendor_event_alloc(pHddCtx->wiphy,
2844 EXTSCAN_EVENT_BUF_SIZE + NLMSG_HDRLEN,
2845 QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_SCAN_RESULTS_AVAILABLE_INDEX,
2846 GFP_KERNEL);
2847
2848 if (!skb) {
2849 hddLog(VOS_TRACE_LEVEL_ERROR,
2850 FL("cfg80211_vendor_event_alloc failed"));
2851 return;
2852 }
2853
2854 hddLog(VOS_TRACE_LEVEL_INFO, FL("Entering "));
2855 hddLog(VOS_TRACE_LEVEL_INFO, "Req Id (%u)", pData->requestId);
2856 hddLog(VOS_TRACE_LEVEL_INFO, "Num results (%u)",
2857 pData->numResultsAvailable);
2858 if (nla_put_u32(skb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_REQUEST_ID,
2859 pData->requestId) ||
2860 nla_put_u32(skb,
2861 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_NUM_RESULTS_AVAILABLE,
2862 pData->numResultsAvailable)) {
2863 hddLog(VOS_TRACE_LEVEL_ERROR, FL("nla put fail"));
2864 goto nla_put_failure;
2865 }
2866
2867 cfg80211_vendor_event(skb, GFP_KERNEL);
2868 return;
2869
2870nla_put_failure:
2871 kfree_skb(skb);
2872 return;
2873}
2874
2875static void wlan_hdd_cfg80211_extscan_scan_progress_event(void *ctx, void *pMsg)
2876{
2877 hdd_context_t *pHddCtx = (hdd_context_t *)ctx;
2878 struct sk_buff *skb = NULL;
2879 tpSirEXTScanProgressIndParams pData =
2880 (tpSirEXTScanProgressIndParams) pMsg;
2881
2882 if (wlan_hdd_validate_context(pHddCtx) || !pData) {
2883 hddLog(VOS_TRACE_LEVEL_ERROR, FL("HDD context is not valid "
2884 "or pData(%p) is null"), pData);
2885 return;
2886 }
2887
2888 skb = cfg80211_vendor_event_alloc(pHddCtx->wiphy,
2889 EXTSCAN_EVENT_BUF_SIZE + NLMSG_HDRLEN,
2890 QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_SCAN_EVENT_INDEX,
2891 GFP_KERNEL);
2892
2893 if (!skb) {
2894 hddLog(VOS_TRACE_LEVEL_ERROR,
2895 FL("cfg80211_vendor_event_alloc failed"));
2896 return;
2897 }
2898 hddLog(VOS_TRACE_LEVEL_INFO, FL("Entering "));
2899 hddLog(VOS_TRACE_LEVEL_INFO, "Scan event type (%u)",
2900 pData->extScanEventType);
2901 hddLog(VOS_TRACE_LEVEL_INFO, "Scan event status (%u)",
2902 pData->status);
2903
2904 if (nla_put_u8(skb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_EVENT_TYPE,
2905 pData->extScanEventType) ||
2906 nla_put_u32(skb,
Dasari Srinivas5a288652014-06-30 17:13:22 +05302907 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_REQUEST_ID,
2908 pData->requestId) ||
2909 nla_put_u32(skb,
Dino Mycle6fb96c12014-06-10 11:52:40 +05302910 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_EVENT_STATUS,
2911 pData->status)) {
2912 hddLog(VOS_TRACE_LEVEL_ERROR, FL("nla put fail"));
2913 goto nla_put_failure;
2914 }
2915
2916 cfg80211_vendor_event(skb, GFP_KERNEL);
2917 return;
2918
2919nla_put_failure:
2920 kfree_skb(skb);
2921 return;
2922}
2923
2924void wlan_hdd_cfg80211_extscan_callback(void *ctx, const tANI_U16 evType,
2925 void *pMsg)
2926{
2927 hdd_context_t *pHddCtx = (hdd_context_t *)ctx;
2928
2929 if (wlan_hdd_validate_context(pHddCtx)) {
2930 hddLog(VOS_TRACE_LEVEL_ERROR, FL("HDD context is not valid"));
2931 return;
2932 }
2933
2934 hddLog(VOS_TRACE_LEVEL_INFO, FL("Rcvd Event (%d)"), evType);
2935
2936
2937 switch(evType) {
2938 case SIR_HAL_EXTSCAN_START_RSP:
2939 wlan_hdd_cfg80211_extscan_start_rsp(ctx, pMsg);
2940 break;
2941
2942 case SIR_HAL_EXTSCAN_STOP_RSP:
2943 wlan_hdd_cfg80211_extscan_stop_rsp(ctx, pMsg);
2944 break;
2945 case SIR_HAL_EXTSCAN_GET_CACHED_RESULTS_RSP:
2946 /* There is no need to send this response to upper layer
2947 Just log the message */
2948 hddLog(VOS_TRACE_LEVEL_INFO,
2949 FL("Rcvd SIR_HAL_EXTSCAN_CACHED_RESULTS_RSP"));
2950 break;
2951 case SIR_HAL_EXTSCAN_SET_BSS_HOTLIST_RSP:
2952 wlan_hdd_cfg80211_extscan_set_bss_hotlist_rsp(ctx, pMsg);
2953 break;
2954
2955 case SIR_HAL_EXTSCAN_RESET_BSS_HOTLIST_RSP:
2956 wlan_hdd_cfg80211_extscan_reset_bss_hotlist_rsp(ctx, pMsg);
2957 break;
2958
2959 case SIR_HAL_EXTSCAN_SET_SIGNF_RSSI_CHANGE_RSP:
2960 wlan_hdd_cfg80211_extscan_set_signf_wifi_change_rsp(ctx, pMsg);
2961 break;
2962
2963 case SIR_HAL_EXTSCAN_RESET_SIGNF_RSSI_CHANGE_RSP:
2964 wlan_hdd_cfg80211_extscan_reset_signf_wifi_change_rsp(ctx, pMsg);
2965 break;
2966 case SIR_HAL_EXTSCAN_GET_CAPABILITIES_RSP:
2967 wlan_hdd_cfg80211_extscan_get_capabilities_ind(ctx, pMsg);
2968 break;
2969 case SIR_HAL_EXTSCAN_PROGRESS_IND:
2970 wlan_hdd_cfg80211_extscan_scan_progress_event(ctx, pMsg);
2971 break;
2972 case SIR_HAL_EXTSCAN_SCAN_AVAILABLE_IND:
2973 wlan_hdd_cfg80211_extscan_scan_res_available_event(ctx, pMsg);
2974 break;
2975 case SIR_HAL_EXTSCAN_SCAN_RESULT_IND:
2976 wlan_hdd_cfg80211_extscan_cached_results_ind(ctx, pMsg);
2977 break;
2978 case SIR_HAL_EXTSCAN_HOTLIST_MATCH_IND:
2979 wlan_hdd_cfg80211_extscan_hotlist_match_ind(ctx, pMsg);
2980 break;
2981 case SIR_HAL_EXTSCAN_SIGNF_WIFI_CHANGE_IND:
2982 wlan_hdd_cfg80211_extscan_signif_wifi_change_results_ind(ctx, pMsg);
2983 break;
2984 case SIR_HAL_EXTSCAN_FULL_SCAN_RESULT_IND:
2985 wlan_hdd_cfg80211_extscan_full_scan_result_event(ctx, pMsg);
2986 break;
2987 default:
2988 hddLog(VOS_TRACE_LEVEL_ERROR, FL("invalid event type %d "), evType);
2989 break;
2990 }
2991}
2992
2993static int wlan_hdd_cfg80211_extscan_get_capabilities(struct wiphy *wiphy,
2994 struct wireless_dev *wdev,
2995 void *data, int dataLen)
2996{
Dino Myclee8843b32014-07-04 14:21:45 +05302997 tSirGetEXTScanCapabilitiesReqParams reqMsg;
Dino Mycle6fb96c12014-06-10 11:52:40 +05302998 struct net_device *dev = wdev->netdev;
2999 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
3000 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
3001 struct nlattr
3002 *tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX + 1];
3003 eHalStatus status;
3004
3005 hddLog(VOS_TRACE_LEVEL_INFO, FL("Entering"));
3006 status = wlan_hdd_validate_context(pHddCtx);
3007 if (0 != status)
3008 {
3009 hddLog(VOS_TRACE_LEVEL_ERROR,
3010 FL("HDD context is not valid"));
3011 return -EINVAL;
3012 }
Dino Myclee8843b32014-07-04 14:21:45 +05303013 /* check the EXTScan Capability */
3014 if ( (TRUE != pHddCtx->cfg_ini->fEnableEXTScan) ||
3015 (TRUE != sme_IsFeatureSupportedByFW(EXTENDED_SCAN)))
3016 {
3017 hddLog(VOS_TRACE_LEVEL_ERROR,
3018 FL("EXTScan not enabled/supported by Firmware"));
3019 return -EINVAL;
3020 }
3021
Dino Mycle6fb96c12014-06-10 11:52:40 +05303022 if (nla_parse(tb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX,
3023 data, dataLen,
3024 wlan_hdd_extscan_config_policy)) {
3025 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Invalid ATTR"));
3026 return -EINVAL;
3027 }
3028
3029 /* Parse and fetch request Id */
3030 if (!tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_REQUEST_ID]) {
3031 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr request id failed"));
3032 return -EINVAL;
3033 }
3034
Dino Mycle6fb96c12014-06-10 11:52:40 +05303035
Dino Myclee8843b32014-07-04 14:21:45 +05303036 reqMsg.requestId = nla_get_u32(
Dino Mycle6fb96c12014-06-10 11:52:40 +05303037 tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_REQUEST_ID]);
Dino Myclee8843b32014-07-04 14:21:45 +05303038 hddLog(VOS_TRACE_LEVEL_INFO, FL("Req Id (%d)"), reqMsg.requestId);
Dino Mycle6fb96c12014-06-10 11:52:40 +05303039
Dino Myclee8843b32014-07-04 14:21:45 +05303040 reqMsg.sessionId = pAdapter->sessionId;
3041 hddLog(VOS_TRACE_LEVEL_INFO, FL("Session Id (%d)"), reqMsg.sessionId);
Dino Mycle6fb96c12014-06-10 11:52:40 +05303042
Dino Myclee8843b32014-07-04 14:21:45 +05303043 status = sme_EXTScanGetCapabilities(pHddCtx->hHal, &reqMsg);
Dino Mycle6fb96c12014-06-10 11:52:40 +05303044 if (!HAL_STATUS_SUCCESS(status)) {
3045 hddLog(VOS_TRACE_LEVEL_ERROR,
3046 FL("sme_EXTScanGetCapabilities failed(err=%d)"), status);
Dino Mycle6fb96c12014-06-10 11:52:40 +05303047 return -EINVAL;
3048 }
3049
3050 return 0;
3051}
3052
3053
3054static int wlan_hdd_cfg80211_extscan_get_cached_results(struct wiphy *wiphy,
3055 struct wireless_dev *wdev,
3056 void *data, int dataLen)
3057{
Dino Myclee8843b32014-07-04 14:21:45 +05303058 tSirEXTScanGetCachedResultsReqParams reqMsg;
Dino Mycle6fb96c12014-06-10 11:52:40 +05303059 struct net_device *dev = wdev->netdev;
3060 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
3061 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
3062 struct nlattr
3063 *tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX + 1];
3064 eHalStatus status;
3065
3066 status = wlan_hdd_validate_context(pHddCtx);
3067 if (0 != status)
3068 {
3069 hddLog(VOS_TRACE_LEVEL_ERROR,
3070 FL("HDD context is not valid"));
3071 return -EINVAL;
3072 }
Dino Myclee8843b32014-07-04 14:21:45 +05303073 /* check the EXTScan Capability */
3074 if ( (TRUE != pHddCtx->cfg_ini->fEnableEXTScan) ||
3075 (TRUE != sme_IsFeatureSupportedByFW(EXTENDED_SCAN)))
3076 {
3077 hddLog(VOS_TRACE_LEVEL_ERROR,
3078 FL("EXTScan not enabled/supported by Firmware"));
3079 return -EINVAL;
3080 }
3081
Dino Mycle6fb96c12014-06-10 11:52:40 +05303082 if (nla_parse(tb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX,
3083 data, dataLen,
3084 wlan_hdd_extscan_config_policy)) {
3085 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Invalid ATTR"));
3086 return -EINVAL;
3087 }
3088 /* Parse and fetch request Id */
3089 if (!tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_REQUEST_ID]) {
3090 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr request id failed"));
3091 return -EINVAL;
3092 }
Dino Mycle6fb96c12014-06-10 11:52:40 +05303093
Dino Myclee8843b32014-07-04 14:21:45 +05303094 reqMsg.requestId = nla_get_u32(
Dino Mycle6fb96c12014-06-10 11:52:40 +05303095 tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_REQUEST_ID]);
3096
Dino Myclee8843b32014-07-04 14:21:45 +05303097 hddLog(VOS_TRACE_LEVEL_INFO, FL("Req Id (%d)"), reqMsg.requestId);
Dino Mycle6fb96c12014-06-10 11:52:40 +05303098
Dino Myclee8843b32014-07-04 14:21:45 +05303099 reqMsg.sessionId = pAdapter->sessionId;
3100 hddLog(VOS_TRACE_LEVEL_INFO, FL("Session Id (%d)"), reqMsg.sessionId);
Dino Mycle6fb96c12014-06-10 11:52:40 +05303101
3102 /* Parse and fetch flush parameter */
3103 if (!tb
3104 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_GET_CACHED_SCAN_RESULTS_CONFIG_PARAM_FLUSH])
3105 {
3106 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr flush failed"));
3107 goto failed;
3108 }
Dino Myclee8843b32014-07-04 14:21:45 +05303109 reqMsg.flush = nla_get_u8(
Dino Mycle6fb96c12014-06-10 11:52:40 +05303110 tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_GET_CACHED_SCAN_RESULTS_CONFIG_PARAM_FLUSH]);
3111
Dino Myclee8843b32014-07-04 14:21:45 +05303112 hddLog(VOS_TRACE_LEVEL_INFO, FL("Flush (%d)"), reqMsg.flush);
Dino Mycle6fb96c12014-06-10 11:52:40 +05303113
Dino Myclee8843b32014-07-04 14:21:45 +05303114 status = sme_getCachedResults(pHddCtx->hHal, &reqMsg);
Dino Mycle6fb96c12014-06-10 11:52:40 +05303115 if (!HAL_STATUS_SUCCESS(status)) {
3116 hddLog(VOS_TRACE_LEVEL_ERROR,
3117 FL("sme_getCachedResults failed(err=%d)"), status);
Dino Mycle6fb96c12014-06-10 11:52:40 +05303118 return -EINVAL;
3119 }
3120 return 0;
3121
3122failed:
Dino Mycle6fb96c12014-06-10 11:52:40 +05303123 return -EINVAL;
3124}
3125
3126static int wlan_hdd_cfg80211_extscan_set_bssid_hotlist(struct wiphy *wiphy,
3127 struct wireless_dev *wdev,
3128 void *data, int dataLen)
3129{
3130 tpSirEXTScanSetBssidHotListReqParams pReqMsg = NULL;
3131 struct net_device *dev = wdev->netdev;
3132 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
3133 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
3134 struct nlattr
3135 *tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX + 1];
3136 struct nlattr
3137 *tb2[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX + 1];
3138 struct nlattr *apTh;
3139 eHalStatus status;
3140 tANI_U8 i = 0;
3141 int rem;
3142
3143 status = wlan_hdd_validate_context(pHddCtx);
3144 if (0 != status)
3145 {
3146 hddLog(VOS_TRACE_LEVEL_ERROR,
3147 FL("HDD context is not valid"));
3148 return -EINVAL;
3149 }
Dino Myclee8843b32014-07-04 14:21:45 +05303150 /* check the EXTScan Capability */
3151 if ( (TRUE != pHddCtx->cfg_ini->fEnableEXTScan) ||
3152 (TRUE != sme_IsFeatureSupportedByFW(EXTENDED_SCAN)))
3153 {
3154 hddLog(VOS_TRACE_LEVEL_ERROR,
3155 FL("EXTScan not enabled/supported by Firmware"));
3156 return -EINVAL;
3157 }
3158
Dino Mycle6fb96c12014-06-10 11:52:40 +05303159 if (nla_parse(tb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX,
3160 data, dataLen,
3161 wlan_hdd_extscan_config_policy)) {
3162 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Invalid ATTR"));
3163 return -EINVAL;
3164 }
3165
3166 /* Parse and fetch request Id */
3167 if (!tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_REQUEST_ID]) {
3168 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr request id failed"));
3169 return -EINVAL;
3170 }
Dino Mycle6fb96c12014-06-10 11:52:40 +05303171 pReqMsg = (tpSirEXTScanSetBssidHotListReqParams)
3172 vos_mem_malloc(sizeof(*pReqMsg));
3173 if (!pReqMsg) {
3174 hddLog(VOS_TRACE_LEVEL_ERROR, FL("vos_mem_malloc failed"));
3175 return -ENOMEM;
3176 }
3177
Dino Myclee8843b32014-07-04 14:21:45 +05303178
Dino Mycle6fb96c12014-06-10 11:52:40 +05303179 pReqMsg->requestId = nla_get_u32(
3180 tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_REQUEST_ID]);
3181 hddLog(VOS_TRACE_LEVEL_INFO, FL("Req Id (%d)"), pReqMsg->requestId);
3182
3183 /* Parse and fetch number of APs */
3184 if (!tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_BSSID_HOTLIST_PARAMS_NUM_AP]) {
3185 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr number of AP failed"));
3186 goto fail;
3187 }
3188
3189 pReqMsg->sessionId = pAdapter->sessionId;
3190 hddLog(VOS_TRACE_LEVEL_INFO, FL("Session Id (%d)"), pReqMsg->sessionId);
3191
3192 pReqMsg->numAp = nla_get_u32(
3193 tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_BSSID_HOTLIST_PARAMS_NUM_AP]);
3194 hddLog(VOS_TRACE_LEVEL_INFO, FL("Number of AP (%d)"), pReqMsg->numAp);
3195
3196 nla_for_each_nested(apTh,
3197 tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_AP_THRESHOLD_PARAM], rem) {
3198 if(nla_parse(tb2, QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX,
3199 nla_data(apTh), nla_len(apTh),
3200 NULL)) {
3201 hddLog(VOS_TRACE_LEVEL_ERROR, FL("nla_parse failed"));
3202 goto fail;
3203 }
3204
3205 /* Parse and fetch MAC address */
3206 if (!tb2[QCA_WLAN_VENDOR_ATTR_EXTSCAN_AP_THRESHOLD_PARAM_BSSID]) {
3207 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr mac address failed"));
3208 goto fail;
3209 }
3210 memcpy(pReqMsg->ap[i].bssid, nla_data(
3211 tb2[QCA_WLAN_VENDOR_ATTR_EXTSCAN_AP_THRESHOLD_PARAM_BSSID]),
3212 sizeof(tSirMacAddr));
3213 hddLog(VOS_TRACE_LEVEL_INFO, FL("BSSID: %pM "), pReqMsg->ap[i].bssid);
3214
3215 /* Parse and fetch low RSSI */
3216 if (!tb2[QCA_WLAN_VENDOR_ATTR_EXTSCAN_AP_THRESHOLD_PARAM_RSSI_LOW]) {
3217 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr low RSSI failed"));
3218 goto fail;
3219 }
3220 pReqMsg->ap[i].low = nla_get_s32(
3221 tb2[QCA_WLAN_VENDOR_ATTR_EXTSCAN_AP_THRESHOLD_PARAM_RSSI_LOW]);
3222 hddLog(VOS_TRACE_LEVEL_INFO, FL("RSSI low (%d)"), pReqMsg->ap[i].low);
3223
3224 /* Parse and fetch high RSSI */
3225 if (!tb2[QCA_WLAN_VENDOR_ATTR_EXTSCAN_AP_THRESHOLD_PARAM_RSSI_HIGH]) {
3226 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr high RSSI failed"));
3227 goto fail;
3228 }
3229 pReqMsg->ap[i].high = nla_get_s32(
3230 tb2[QCA_WLAN_VENDOR_ATTR_EXTSCAN_AP_THRESHOLD_PARAM_RSSI_HIGH]);
3231 hddLog(VOS_TRACE_LEVEL_INFO, FL("RSSI High (%d)"),
3232 pReqMsg->ap[i].high);
3233
3234 /* Parse and fetch channel */
3235 if (!tb2[QCA_WLAN_VENDOR_ATTR_EXTSCAN_AP_THRESHOLD_PARAM_CHANNEL]) {
3236 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr channel failed"));
3237 goto fail;
3238 }
3239 pReqMsg->ap[i].channel = nla_get_u32(
3240 tb2[QCA_WLAN_VENDOR_ATTR_EXTSCAN_AP_THRESHOLD_PARAM_CHANNEL]);
3241 hddLog(VOS_TRACE_LEVEL_INFO,
3242 FL("Channel (%u)"), pReqMsg->ap[i].channel);
3243 i++;
3244 }
3245 status = sme_SetBssHotlist(pHddCtx->hHal, pReqMsg);
3246 if (!HAL_STATUS_SUCCESS(status)) {
3247 hddLog(VOS_TRACE_LEVEL_ERROR,
3248 FL("sme_SetBssHotlist failed(err=%d)"), status);
3249 vos_mem_free(pReqMsg);
3250 return -EINVAL;
3251 }
3252
Dino Myclee8843b32014-07-04 14:21:45 +05303253 vos_mem_free(pReqMsg);
3254
Dino Mycle6fb96c12014-06-10 11:52:40 +05303255 return 0;
3256
3257fail:
3258 vos_mem_free(pReqMsg);
3259 return -EINVAL;
3260}
3261
3262static int wlan_hdd_cfg80211_extscan_set_significant_change(struct wiphy *wiphy,
3263 struct wireless_dev *wdev,
3264 void *data, int dataLen)
3265{
3266 tpSirEXTScanSetSignificantChangeReqParams pReqMsg = NULL;
3267 struct net_device *dev = wdev->netdev;
3268 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
3269 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
3270 struct nlattr
3271 *tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX + 1];
3272 struct nlattr
3273 *tb2[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX + 1];
3274 struct nlattr *apTh;
3275 eHalStatus status;
3276 int i = 0;
3277 int rem;
3278
3279 status = wlan_hdd_validate_context(pHddCtx);
3280 if (0 != status)
3281 {
3282 hddLog(VOS_TRACE_LEVEL_ERROR,
3283 FL("HDD context is not valid"));
3284 return -EINVAL;
3285 }
Dino Myclee8843b32014-07-04 14:21:45 +05303286 /* check the EXTScan Capability */
3287 if ( (TRUE != pHddCtx->cfg_ini->fEnableEXTScan) ||
3288 (TRUE != sme_IsFeatureSupportedByFW(EXTENDED_SCAN)))
3289 {
3290 hddLog(VOS_TRACE_LEVEL_ERROR,
3291 FL("EXTScan not enabled/supported by Firmware"));
3292 return -EINVAL;
3293 }
3294
Dino Mycle6fb96c12014-06-10 11:52:40 +05303295 if (nla_parse(tb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX,
3296 data, dataLen,
3297 wlan_hdd_extscan_config_policy)) {
3298 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Invalid ATTR"));
3299 return -EINVAL;
3300 }
3301
3302 /* Parse and fetch request Id */
3303 if (!tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_REQUEST_ID]) {
3304 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr request id failed"));
3305 return -EINVAL;
3306 }
Dino Mycle6fb96c12014-06-10 11:52:40 +05303307 pReqMsg = (tpSirEXTScanSetSignificantChangeReqParams)
Dino Myclee8843b32014-07-04 14:21:45 +05303308 vos_mem_malloc(sizeof(*pReqMsg));
Dino Mycle6fb96c12014-06-10 11:52:40 +05303309 if (!pReqMsg) {
Dino Myclee8843b32014-07-04 14:21:45 +05303310 hddLog(VOS_TRACE_LEVEL_ERROR, FL("vos_mem_malloc failed"));
3311 return -ENOMEM;
Dino Mycle6fb96c12014-06-10 11:52:40 +05303312 }
3313
Dino Myclee8843b32014-07-04 14:21:45 +05303314
3315
Dino Mycle6fb96c12014-06-10 11:52:40 +05303316 pReqMsg->requestId = nla_get_u32(
3317 tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_REQUEST_ID]);
3318 hddLog(VOS_TRACE_LEVEL_INFO, FL("Req Id (%d)"), pReqMsg->requestId);
3319
3320 /* Parse and fetch RSSI sample size */
3321 if (!tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SIGNIFICANT_CHANGE_PARAMS_RSSI_SAMPLE_SIZE])
3322 {
3323 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr RSSI sample size failed"));
3324 goto fail;
3325 }
3326 pReqMsg->rssiSampleSize = nla_get_u32(
3327 tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SIGNIFICANT_CHANGE_PARAMS_RSSI_SAMPLE_SIZE]);
3328 hddLog(VOS_TRACE_LEVEL_INFO,
3329 FL("RSSI sample size (%u)"), pReqMsg->rssiSampleSize);
3330
3331 /* Parse and fetch lost AP sample size */
3332 if (!tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SIGNIFICANT_CHANGE_PARAMS_LOST_AP_SAMPLE_SIZE])
3333 {
3334 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr lost AP sample size failed"));
3335 goto fail;
3336 }
3337 pReqMsg->lostApSampleSize = nla_get_u32(
3338 tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SIGNIFICANT_CHANGE_PARAMS_LOST_AP_SAMPLE_SIZE]);
3339 hddLog(VOS_TRACE_LEVEL_INFO,
3340 FL("Lost AP sample size (%u)"), pReqMsg->lostApSampleSize);
3341 /* Parse and fetch minimum Breaching */
3342 if (!tb
3343 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_SIGNIFICANT_CHANGE_PARAMS_MIN_BREACHING]) {
3344 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr minBreaching failed"));
3345 goto fail;
3346 }
3347 pReqMsg->minBreaching = nla_get_u32(
3348 tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SIGNIFICANT_CHANGE_PARAMS_MIN_BREACHING]);
3349 hddLog(VOS_TRACE_LEVEL_INFO, FL(" Breaching (%d)"), pReqMsg->minBreaching);
3350
3351 /* Parse and fetch number of APs */
3352 if (!tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SIGNIFICANT_CHANGE_PARAMS_NUM_AP]) {
3353 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr number of AP failed"));
3354 goto fail;
3355 }
3356 pReqMsg->numAp = nla_get_u32(
3357 tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SIGNIFICANT_CHANGE_PARAMS_NUM_AP]);
3358 hddLog(VOS_TRACE_LEVEL_INFO, FL("Number of AP (%d)"), pReqMsg->numAp);
3359
3360 pReqMsg->sessionId = pAdapter->sessionId;
3361 hddLog(VOS_TRACE_LEVEL_INFO, FL("Session Id (%d)"), pReqMsg->sessionId);
3362
3363 nla_for_each_nested(apTh,
3364 tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_AP_THRESHOLD_PARAM], rem) {
3365 if(nla_parse(tb2,
3366 QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX,
3367 nla_data(apTh), nla_len(apTh),
3368 NULL)) {
3369 hddLog(VOS_TRACE_LEVEL_ERROR, FL("nla_parse failed"));
3370 goto fail;
3371 }
3372
3373 /* Parse and fetch MAC address */
3374 if (!tb2[QCA_WLAN_VENDOR_ATTR_EXTSCAN_AP_THRESHOLD_PARAM_BSSID]) {
3375 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr mac address failed"));
3376 goto fail;
3377 }
3378 memcpy(pReqMsg->ap[i].bssid, nla_data(
3379 tb2[QCA_WLAN_VENDOR_ATTR_EXTSCAN_AP_THRESHOLD_PARAM_BSSID]),
3380 sizeof(tSirMacAddr));
3381
3382 /* Parse and fetch low RSSI */
3383 if (!tb2[QCA_WLAN_VENDOR_ATTR_EXTSCAN_AP_THRESHOLD_PARAM_RSSI_LOW]) {
3384 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr low RSSI failed"));
3385 goto fail;
3386 }
3387 pReqMsg->ap[i].low = nla_get_s32(
3388 tb2[QCA_WLAN_VENDOR_ATTR_EXTSCAN_AP_THRESHOLD_PARAM_RSSI_LOW]);
3389 hddLog(VOS_TRACE_LEVEL_INFO, FL("RSSI low (%d)"), pReqMsg->ap[i].low);
3390
3391 /* Parse and fetch high RSSI */
3392 if (!tb2[QCA_WLAN_VENDOR_ATTR_EXTSCAN_AP_THRESHOLD_PARAM_RSSI_HIGH]) {
3393 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr high RSSI failed"));
3394 goto fail;
3395 }
3396 pReqMsg->ap[i].high = nla_get_s32(
3397 tb2[QCA_WLAN_VENDOR_ATTR_EXTSCAN_AP_THRESHOLD_PARAM_RSSI_HIGH]);
3398 hddLog(VOS_TRACE_LEVEL_INFO,
3399 FL("RSSI High (%d)"), pReqMsg->ap[i].high);
3400
3401 /* Parse and fetch channel */
3402 if (!tb2[QCA_WLAN_VENDOR_ATTR_EXTSCAN_AP_THRESHOLD_PARAM_CHANNEL]) {
3403 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr channel failed"));
3404 goto fail;
3405 }
3406 pReqMsg->ap[i].channel = nla_get_u32(
3407 tb2[QCA_WLAN_VENDOR_ATTR_EXTSCAN_AP_THRESHOLD_PARAM_CHANNEL]);
3408 hddLog(VOS_TRACE_LEVEL_INFO,
3409 FL("Channel (%u)"), pReqMsg->ap[i].channel);
3410 i++;
3411 }
3412
3413 status = sme_SetSignificantChange(pHddCtx->hHal, pReqMsg);
3414 if (!HAL_STATUS_SUCCESS(status)) {
3415 hddLog(VOS_TRACE_LEVEL_ERROR,
3416 FL("sme_SetSignificantChange failed(err=%d)"), status);
3417 vos_mem_free(pReqMsg);
3418 return -EINVAL;
3419 }
Dino Myclee8843b32014-07-04 14:21:45 +05303420 vos_mem_free(pReqMsg);
Dino Mycle6fb96c12014-06-10 11:52:40 +05303421 hddLog(VOS_TRACE_LEVEL_ERROR, FL(" Exiting"));
3422 return 0;
3423
3424fail:
3425 vos_mem_free(pReqMsg);
3426 return -EINVAL;
3427}
3428
3429static int wlan_hdd_cfg80211_extscan_get_valid_channels(struct wiphy *wiphy,
3430 struct wireless_dev *wdev,
3431 void *data, int dataLen)
3432{
3433 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
3434 tANI_U32 ChannelList[WNI_CFG_VALID_CHANNEL_LIST_LEN] = {0};
3435 tANI_U8 numChannels = 0;
3436 struct nlattr *tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX + 1];
3437 tANI_U32 requestId;
3438 tWifiBand wifiBand;
3439 eHalStatus status;
3440 struct sk_buff *replySkb;
3441 tANI_U8 i;
3442
3443 hddLog(VOS_TRACE_LEVEL_INFO, FL("Entering"));
3444 status = wlan_hdd_validate_context(pHddCtx);
3445 if (0 != status)
3446 {
3447 hddLog(VOS_TRACE_LEVEL_ERROR,
3448 FL("HDD context is not valid"));
3449 return -EINVAL;
3450 }
Dino Myclee8843b32014-07-04 14:21:45 +05303451 /* check the EXTScan Capability */
3452 if ( (TRUE != pHddCtx->cfg_ini->fEnableEXTScan) ||
3453 (TRUE != sme_IsFeatureSupportedByFW(EXTENDED_SCAN)))
3454 {
3455 hddLog(VOS_TRACE_LEVEL_ERROR,
3456 FL("EXTScan not enabled/supported by Firmware"));
3457 return -EINVAL;
3458 }
3459
Dino Mycle6fb96c12014-06-10 11:52:40 +05303460 if (nla_parse(tb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX,
3461 data, dataLen,
3462 wlan_hdd_extscan_config_policy)) {
3463 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Invalid ATTR"));
3464 return -EINVAL;
3465 }
3466
3467 /* Parse and fetch request Id */
3468 if (!tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_REQUEST_ID]) {
3469 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr request id failed"));
3470 return -EINVAL;
3471 }
3472 requestId = nla_get_u32(
3473 tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_REQUEST_ID]);
3474 hddLog(VOS_TRACE_LEVEL_INFO, FL("Req Id (%d)"), requestId);
3475
3476 /* Parse and fetch wifi band */
3477 if (!tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_GET_VALID_CHANNELS_CONFIG_PARAM_WIFI_BAND])
3478 {
3479 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr wifi band failed"));
3480 return -EINVAL;
3481 }
3482 wifiBand = nla_get_u32(
3483 tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_GET_VALID_CHANNELS_CONFIG_PARAM_WIFI_BAND]);
3484 hddLog(VOS_TRACE_LEVEL_INFO, FL("Wifi band (%d)"), wifiBand);
3485
3486 status = sme_GetValidChannelsByBand((tHalHandle)(pHddCtx->hHal),
3487 wifiBand, ChannelList,
3488 &numChannels);
3489 if (eHAL_STATUS_SUCCESS != status) {
3490 hddLog(VOS_TRACE_LEVEL_ERROR,
3491 FL("sme_GetValidChannelsByBand failed (err=%d)"), status);
3492 return -EINVAL;
3493 }
3494 hddLog(VOS_TRACE_LEVEL_INFO, FL("Number of channels (%d)"), numChannels);
3495 for (i = 0; i < numChannels; i++)
3496 hddLog(VOS_TRACE_LEVEL_INFO, "Channel: %u ", ChannelList[i]);
3497
3498 replySkb = cfg80211_vendor_cmd_alloc_reply_skb(wiphy, sizeof(u32) +
3499 sizeof(u32) * numChannels +
3500 NLMSG_HDRLEN);
3501
3502 if (!replySkb) {
3503 hddLog(VOS_TRACE_LEVEL_ERROR,
3504 FL("valid channels: buffer alloc fail"));
3505 return -EINVAL;
3506 }
3507 if (nla_put_u32(replySkb,
3508 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_NUM_CHANNELS,
3509 numChannels) ||
3510 nla_put(replySkb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_CHANNELS,
3511 sizeof(u32) * numChannels, ChannelList)) {
3512
3513 hddLog(VOS_TRACE_LEVEL_ERROR, FL("nla put fail"));
3514 kfree_skb(replySkb);
3515 return -EINVAL;
3516 }
3517
3518 return cfg80211_vendor_cmd_reply(replySkb);
3519}
3520
3521static int wlan_hdd_cfg80211_extscan_start(struct wiphy *wiphy,
3522 struct wireless_dev *wdev,
3523 void *data, int dataLen)
3524{
Dino Myclee8843b32014-07-04 14:21:45 +05303525 tpSirEXTScanStartReqParams pReqMsg = NULL;
Dino Mycle6fb96c12014-06-10 11:52:40 +05303526 struct net_device *dev = wdev->netdev;
3527 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
3528 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
3529 struct nlattr *tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX + 1];
3530 struct nlattr *bucket[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX + 1];
3531 struct nlattr *channel[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX + 1];
3532 struct nlattr *buckets;
3533 struct nlattr *channels;
3534 int rem1;
3535 int rem2;
3536 eHalStatus status;
Dasari Srinivas8b2ce272014-09-16 16:57:30 +05303537 tANI_U32 j = 0, index = 0;
Dino Mycle6fb96c12014-06-10 11:52:40 +05303538
3539 status = wlan_hdd_validate_context(pHddCtx);
3540 if (0 != status)
3541 {
3542 hddLog(VOS_TRACE_LEVEL_ERROR,
3543 FL("HDD context is not valid"));
3544 return -EINVAL;
3545 }
Dino Myclee8843b32014-07-04 14:21:45 +05303546 /* check the EXTScan Capability */
3547 if ( (TRUE != pHddCtx->cfg_ini->fEnableEXTScan) ||
3548 (TRUE != sme_IsFeatureSupportedByFW(EXTENDED_SCAN)))
3549 {
3550 hddLog(VOS_TRACE_LEVEL_ERROR,
3551 FL("EXTScan not enabled/supported by Firmware"));
3552 return -EINVAL;
3553 }
3554
Dino Mycle6fb96c12014-06-10 11:52:40 +05303555 if (nla_parse(tb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX,
3556 data, dataLen,
3557 wlan_hdd_extscan_config_policy)) {
3558 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Invalid ATTR"));
3559 return -EINVAL;
3560 }
3561
3562 /* Parse and fetch request Id */
3563 if (!tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_REQUEST_ID]) {
3564 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr request id failed"));
3565 return -EINVAL;
3566 }
3567
Dino Myclee8843b32014-07-04 14:21:45 +05303568 pReqMsg = (tpSirEXTScanStartReqParams)
3569 vos_mem_malloc(sizeof(*pReqMsg));
Dino Mycle6fb96c12014-06-10 11:52:40 +05303570 if (!pReqMsg) {
Dino Myclee8843b32014-07-04 14:21:45 +05303571 hddLog(VOS_TRACE_LEVEL_ERROR, FL("vos_mem_malloc failed"));
3572 return -ENOMEM;
Dino Mycle6fb96c12014-06-10 11:52:40 +05303573 }
3574
3575 pReqMsg->requestId = nla_get_u32(
3576 tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_REQUEST_ID]);
3577 hddLog(VOS_TRACE_LEVEL_INFO, FL("Req Id (%d)"), pReqMsg->requestId);
3578
3579 pReqMsg->sessionId = pAdapter->sessionId;
3580 hddLog(VOS_TRACE_LEVEL_INFO, FL("Session Id (%d)"), pReqMsg->sessionId);
3581
3582 /* Parse and fetch base period */
3583 if (!tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SCAN_CMD_PARAMS_BASE_PERIOD]) {
3584 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr base period failed"));
3585 goto fail;
3586 }
3587 pReqMsg->basePeriod = nla_get_u32(
3588 tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SCAN_CMD_PARAMS_BASE_PERIOD]);
3589 hddLog(VOS_TRACE_LEVEL_INFO, FL("Base Period (%d)"),
3590 pReqMsg->basePeriod);
3591
3592 /* Parse and fetch max AP per scan */
3593 if (!tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SCAN_CMD_PARAMS_MAX_AP_PER_SCAN]) {
3594 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr max_ap_per_scan failed"));
3595 goto fail;
3596 }
3597 pReqMsg->maxAPperScan = nla_get_u32(
3598 tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SCAN_CMD_PARAMS_MAX_AP_PER_SCAN]);
3599 hddLog(VOS_TRACE_LEVEL_INFO, FL("Max AP per Scan (%d)"),
3600 pReqMsg->maxAPperScan);
3601
3602 /* Parse and fetch report threshold */
3603 if (!tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SCAN_CMD_PARAMS_REPORT_THRESHOLD]) {
3604 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr report_threshold failed"));
3605 goto fail;
3606 }
3607 pReqMsg->reportThreshold = nla_get_u8(
3608 tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SCAN_CMD_PARAMS_REPORT_THRESHOLD]);
3609 hddLog(VOS_TRACE_LEVEL_INFO, FL("Report Threshold (%d)"),
3610 pReqMsg->reportThreshold);
3611
3612 /* Parse and fetch number of buckets */
3613 if (!tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SCAN_CMD_PARAMS_NUM_BUCKETS]) {
3614 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr number of buckets failed"));
3615 goto fail;
3616 }
3617 pReqMsg->numBuckets = nla_get_u8(
3618 tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SCAN_CMD_PARAMS_NUM_BUCKETS]);
3619 if (pReqMsg->numBuckets > WLAN_EXTSCAN_MAX_BUCKETS) {
3620 hddLog(VOS_TRACE_LEVEL_WARN, FL("Exceeded MAX number of buckets "
3621 "Setting numBuckets to %u"), WLAN_EXTSCAN_MAX_BUCKETS);
3622 pReqMsg->numBuckets = WLAN_EXTSCAN_MAX_BUCKETS;
3623 }
3624 hddLog(VOS_TRACE_LEVEL_INFO, FL("Number of Buckets (%d)"),
3625 pReqMsg->numBuckets);
3626 if (!tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC]) {
3627 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr bucket spec failed"));
3628 goto fail;
3629 }
3630
3631 nla_for_each_nested(buckets,
3632 tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC], rem1) {
3633 if(nla_parse(bucket,
3634 QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX,
3635 nla_data(buckets), nla_len(buckets), NULL)) { //policy
3636 hddLog(VOS_TRACE_LEVEL_ERROR, FL("nla_parse failed"));
3637 goto fail;
3638 }
3639
3640 /* Parse and fetch bucket spec */
3641 if (!bucket[QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_INDEX]) {
3642 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr bucket index failed"));
3643 goto fail;
3644 }
Dasari Srinivas8b2ce272014-09-16 16:57:30 +05303645
3646 pReqMsg->buckets[index].bucket = nla_get_u8(
3647 bucket[QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_INDEX]);
3648
3649 hddLog(VOS_TRACE_LEVEL_INFO, FL("Bucket spec Index (%d)"),
3650 pReqMsg->buckets[index].bucket);
Dino Mycle6fb96c12014-06-10 11:52:40 +05303651
3652 /* Parse and fetch wifi band */
3653 if (!bucket[QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_BAND]) {
3654 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr wifi band failed"));
3655 goto fail;
3656 }
Dasari Srinivas8b2ce272014-09-16 16:57:30 +05303657 pReqMsg->buckets[index].band = nla_get_u8(
Dino Mycle6fb96c12014-06-10 11:52:40 +05303658 bucket[QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_BAND]);
3659 hddLog(VOS_TRACE_LEVEL_INFO, FL("Wifi band (%d)"),
Dasari Srinivas8b2ce272014-09-16 16:57:30 +05303660 pReqMsg->buckets[index].band);
Dino Mycle6fb96c12014-06-10 11:52:40 +05303661
3662 /* Parse and fetch period */
3663 if (!bucket[QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_PERIOD]) {
3664 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr period failed"));
3665 goto fail;
3666 }
Dasari Srinivas8b2ce272014-09-16 16:57:30 +05303667 pReqMsg->buckets[index].period = nla_get_u32(
Dino Mycle6fb96c12014-06-10 11:52:40 +05303668 bucket[QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_PERIOD]);
3669 hddLog(VOS_TRACE_LEVEL_INFO, FL("period (%d)"),
Dasari Srinivas8b2ce272014-09-16 16:57:30 +05303670 pReqMsg->buckets[index].period);
Dino Mycle6fb96c12014-06-10 11:52:40 +05303671
3672 /* Parse and fetch report events */
3673 if (!bucket[QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_REPORT_EVENTS]) {
3674 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr report events failed"));
3675 goto fail;
3676 }
Dasari Srinivas8b2ce272014-09-16 16:57:30 +05303677 pReqMsg->buckets[index].reportEvents = nla_get_u8(
Dino Mycle6fb96c12014-06-10 11:52:40 +05303678 bucket[QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_REPORT_EVENTS]);
3679 hddLog(VOS_TRACE_LEVEL_INFO, FL("report events (%d)"),
Dasari Srinivas8b2ce272014-09-16 16:57:30 +05303680 pReqMsg->buckets[index].reportEvents);
Dino Mycle6fb96c12014-06-10 11:52:40 +05303681
3682 /* Parse and fetch number of channels */
Dasari Srinivas8b2ce272014-09-16 16:57:30 +05303683 if (!bucket[QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_NUM_CHANNEL_SPECS])
3684 {
Dino Mycle6fb96c12014-06-10 11:52:40 +05303685 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr num channels failed"));
3686 goto fail;
3687 }
Dasari Srinivas8b2ce272014-09-16 16:57:30 +05303688 pReqMsg->buckets[index].numChannels = nla_get_u32(
Dino Mycle6fb96c12014-06-10 11:52:40 +05303689 bucket[QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_NUM_CHANNEL_SPECS]);
3690 hddLog(VOS_TRACE_LEVEL_INFO, FL("num channels (%d)"),
Dasari Srinivas8b2ce272014-09-16 16:57:30 +05303691 pReqMsg->buckets[index].numChannels);
Dino Mycle6fb96c12014-06-10 11:52:40 +05303692
3693 if (!bucket[QCA_WLAN_VENDOR_ATTR_EXTSCAN_CHANNEL_SPEC]) {
3694 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr channel spec failed"));
3695 goto fail;
3696 }
3697
3698 j = 0;
3699 nla_for_each_nested(channels,
3700 bucket[QCA_WLAN_VENDOR_ATTR_EXTSCAN_CHANNEL_SPEC], rem2) {
3701 if(nla_parse(channel,
3702 QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX,
3703 nla_data(channels), nla_len(channels),
3704 NULL)) { //wlan_hdd_extscan_config_policy here
3705 hddLog(VOS_TRACE_LEVEL_ERROR, FL("nla_parse failed"));
3706 goto fail;
3707 }
3708
3709 /* Parse and fetch channel */
3710 if (!channel[QCA_WLAN_VENDOR_ATTR_EXTSCAN_CHANNEL_SPEC_CHANNEL]) {
3711 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr channel failed"));
3712 goto fail;
3713 }
Dasari Srinivas8b2ce272014-09-16 16:57:30 +05303714 pReqMsg->buckets[index].channels[j].channel = nla_get_u32(
Dino Mycle6fb96c12014-06-10 11:52:40 +05303715 channel[QCA_WLAN_VENDOR_ATTR_EXTSCAN_CHANNEL_SPEC_CHANNEL]);
3716 hddLog(VOS_TRACE_LEVEL_INFO, FL("channel (%u)"),
Dasari Srinivas8b2ce272014-09-16 16:57:30 +05303717 pReqMsg->buckets[index].channels[j].channel);
Dino Mycle6fb96c12014-06-10 11:52:40 +05303718
3719 /* Parse and fetch dwell time */
3720 if (!channel[QCA_WLAN_VENDOR_ATTR_EXTSCAN_CHANNEL_SPEC_DWELL_TIME]) {
3721 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr dwelltime failed"));
3722 goto fail;
3723 }
Dasari Srinivas8b2ce272014-09-16 16:57:30 +05303724 pReqMsg->buckets[index].channels[j].dwellTimeMs = nla_get_u32(
Dino Mycle6fb96c12014-06-10 11:52:40 +05303725 channel[QCA_WLAN_VENDOR_ATTR_EXTSCAN_CHANNEL_SPEC_DWELL_TIME]);
3726 hddLog(VOS_TRACE_LEVEL_INFO, FL("Dwell time (%u ms)"),
Dasari Srinivas8b2ce272014-09-16 16:57:30 +05303727 pReqMsg->buckets[index].channels[j].dwellTimeMs);
Dino Mycle6fb96c12014-06-10 11:52:40 +05303728
3729 /* Parse and fetch channel spec passive */
3730 if (!channel[QCA_WLAN_VENDOR_ATTR_EXTSCAN_CHANNEL_SPEC_PASSIVE]) {
3731 hddLog(VOS_TRACE_LEVEL_ERROR,
3732 FL("attr channel spec passive failed"));
3733 goto fail;
3734 }
Dasari Srinivas8b2ce272014-09-16 16:57:30 +05303735 pReqMsg->buckets[index].channels[j].passive = nla_get_u8(
Dino Mycle6fb96c12014-06-10 11:52:40 +05303736 channel[QCA_WLAN_VENDOR_ATTR_EXTSCAN_CHANNEL_SPEC_PASSIVE]);
3737 hddLog(VOS_TRACE_LEVEL_INFO, FL("Chnl spec passive (%u)"),
Dasari Srinivas8b2ce272014-09-16 16:57:30 +05303738 pReqMsg->buckets[index].channels[j].passive);
Dino Mycle6fb96c12014-06-10 11:52:40 +05303739 j++;
3740 }
Dasari Srinivas8b2ce272014-09-16 16:57:30 +05303741 index++;
Dino Mycle6fb96c12014-06-10 11:52:40 +05303742 }
3743 status = sme_EXTScanStart(pHddCtx->hHal, pReqMsg);
3744 if (!HAL_STATUS_SUCCESS(status)) {
3745 hddLog(VOS_TRACE_LEVEL_ERROR,
3746 FL("sme_EXTScanStart failed(err=%d)"), status);
3747 vos_mem_free(pReqMsg);
3748 return -EINVAL;
3749 }
3750
Dino Myclee8843b32014-07-04 14:21:45 +05303751 vos_mem_free(pReqMsg);
Dino Mycle6fb96c12014-06-10 11:52:40 +05303752 return 0;
3753
3754fail:
3755 vos_mem_free(pReqMsg);
3756 return -EINVAL;
3757}
3758
3759static int wlan_hdd_cfg80211_extscan_stop(struct wiphy *wiphy,
3760 struct wireless_dev *wdev,
3761 void *data, int dataLen)
3762{
Dino Myclee8843b32014-07-04 14:21:45 +05303763 tSirEXTScanStopReqParams reqMsg;
Dino Mycle6fb96c12014-06-10 11:52:40 +05303764 struct net_device *dev = wdev->netdev;
3765 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
3766 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
3767 struct nlattr *tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX + 1];
3768 eHalStatus status;
3769
3770 status = wlan_hdd_validate_context(pHddCtx);
3771 if (0 != status)
3772 {
3773 hddLog(VOS_TRACE_LEVEL_ERROR,
3774 FL("HDD context is not valid"));
3775 return -EINVAL;
3776 }
Dino Myclee8843b32014-07-04 14:21:45 +05303777 /* check the EXTScan Capability */
3778 if ( (TRUE != pHddCtx->cfg_ini->fEnableEXTScan) ||
3779 (TRUE != sme_IsFeatureSupportedByFW(EXTENDED_SCAN)))
3780 {
3781 hddLog(VOS_TRACE_LEVEL_ERROR,
3782 FL("EXTScan not enabled/supported by Firmware"));
3783 return -EINVAL;
3784 }
3785
Dino Mycle6fb96c12014-06-10 11:52:40 +05303786 if (nla_parse(tb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX,
3787 data, dataLen,
3788 wlan_hdd_extscan_config_policy)) {
3789 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Invalid ATTR"));
3790 return -EINVAL;
3791 }
3792
3793 /* Parse and fetch request Id */
3794 if (!tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_REQUEST_ID]) {
3795 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr request id failed"));
3796 return -EINVAL;
3797 }
3798
Dino Myclee8843b32014-07-04 14:21:45 +05303799 reqMsg.requestId = nla_get_u32(
Dino Mycle6fb96c12014-06-10 11:52:40 +05303800 tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_REQUEST_ID]);
Dino Myclee8843b32014-07-04 14:21:45 +05303801 hddLog(VOS_TRACE_LEVEL_INFO, FL("Req Id (%d)"), reqMsg.requestId);
Dino Mycle6fb96c12014-06-10 11:52:40 +05303802
Dino Myclee8843b32014-07-04 14:21:45 +05303803 reqMsg.sessionId = pAdapter->sessionId;
3804 hddLog(VOS_TRACE_LEVEL_INFO, FL("Session Id (%d)"), reqMsg.sessionId);
Dino Mycle6fb96c12014-06-10 11:52:40 +05303805
Dino Myclee8843b32014-07-04 14:21:45 +05303806 status = sme_EXTScanStop(pHddCtx->hHal, &reqMsg);
Dino Mycle6fb96c12014-06-10 11:52:40 +05303807 if (!HAL_STATUS_SUCCESS(status)) {
3808 hddLog(VOS_TRACE_LEVEL_ERROR,
3809 FL("sme_EXTScanStop failed(err=%d)"), status);
Dino Mycle6fb96c12014-06-10 11:52:40 +05303810 return -EINVAL;
3811 }
3812
3813 return 0;
3814}
3815
3816static int wlan_hdd_cfg80211_extscan_reset_bssid_hotlist(struct wiphy *wiphy,
3817 struct wireless_dev *wdev,
3818 void *data, int dataLen)
3819{
Dino Myclee8843b32014-07-04 14:21:45 +05303820 tSirEXTScanResetBssidHotlistReqParams reqMsg;
Dino Mycle6fb96c12014-06-10 11:52:40 +05303821 struct net_device *dev = wdev->netdev;
3822 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
3823 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
3824 struct nlattr *tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX + 1];
3825 eHalStatus status;
3826
3827 status = wlan_hdd_validate_context(pHddCtx);
3828 if (0 != status)
3829 {
3830 hddLog(VOS_TRACE_LEVEL_ERROR,
3831 FL("HDD context is not valid"));
3832 return -EINVAL;
3833 }
Dino Myclee8843b32014-07-04 14:21:45 +05303834 /* check the EXTScan Capability */
3835 if ( (TRUE != pHddCtx->cfg_ini->fEnableEXTScan) ||
3836 (TRUE != sme_IsFeatureSupportedByFW(EXTENDED_SCAN)))
3837 {
3838 hddLog(VOS_TRACE_LEVEL_ERROR,
3839 FL("EXTScan not enabled/supported by Firmware"));
3840 return -EINVAL;
3841 }
3842
Dino Mycle6fb96c12014-06-10 11:52:40 +05303843 if (nla_parse(tb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX,
3844 data, dataLen,
3845 wlan_hdd_extscan_config_policy)) {
3846 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Invalid ATTR"));
3847 return -EINVAL;
3848 }
3849
3850 /* Parse and fetch request Id */
3851 if (!tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_REQUEST_ID]) {
3852 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr request id failed"));
3853 return -EINVAL;
3854 }
3855
Dino Myclee8843b32014-07-04 14:21:45 +05303856 reqMsg.requestId = nla_get_u32(
Dino Mycle6fb96c12014-06-10 11:52:40 +05303857 tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_REQUEST_ID]);
Dino Myclee8843b32014-07-04 14:21:45 +05303858 hddLog(VOS_TRACE_LEVEL_INFO, FL("Req Id (%d)"), reqMsg.requestId);
Dino Mycle6fb96c12014-06-10 11:52:40 +05303859
Dino Myclee8843b32014-07-04 14:21:45 +05303860 reqMsg.sessionId = pAdapter->sessionId;
3861 hddLog(VOS_TRACE_LEVEL_INFO, FL("Session Id (%d)"), reqMsg.sessionId);
Dino Mycle6fb96c12014-06-10 11:52:40 +05303862
Dino Myclee8843b32014-07-04 14:21:45 +05303863 status = sme_ResetBssHotlist(pHddCtx->hHal, &reqMsg);
Dino Mycle6fb96c12014-06-10 11:52:40 +05303864 if (!HAL_STATUS_SUCCESS(status)) {
3865 hddLog(VOS_TRACE_LEVEL_ERROR,
3866 FL("sme_ResetBssHotlist failed(err=%d)"), status);
Dino Mycle6fb96c12014-06-10 11:52:40 +05303867 return -EINVAL;
3868 }
3869
3870 return 0;
3871}
3872
3873static int wlan_hdd_cfg80211_extscan_reset_significant_change(
3874 struct wiphy *wiphy,
3875 struct wireless_dev *wdev,
3876 void *data, int dataLen)
3877{
Dino Myclee8843b32014-07-04 14:21:45 +05303878 tSirEXTScanResetSignificantChangeReqParams reqMsg;
Dino Mycle6fb96c12014-06-10 11:52:40 +05303879 struct net_device *dev = wdev->netdev;
3880 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
3881 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
3882 struct nlattr *tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX + 1];
3883 eHalStatus status;
3884
3885 hddLog(VOS_TRACE_LEVEL_INFO, FL(" Entering"));
3886 status = wlan_hdd_validate_context(pHddCtx);
3887 if (0 != status)
3888 {
3889 hddLog(VOS_TRACE_LEVEL_ERROR,
3890 FL("HDD context is not valid"));
3891 return -EINVAL;
3892 }
Dino Myclee8843b32014-07-04 14:21:45 +05303893 /* check the EXTScan Capability */
3894 if ( (TRUE != pHddCtx->cfg_ini->fEnableEXTScan) ||
3895 (TRUE != sme_IsFeatureSupportedByFW(EXTENDED_SCAN)))
3896 {
3897 hddLog(VOS_TRACE_LEVEL_ERROR,
3898 FL("EXTScan not enabled/supported by Firmware"));
3899 return -EINVAL;
3900 }
3901
Dino Mycle6fb96c12014-06-10 11:52:40 +05303902 if (nla_parse(tb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX,
3903 data, dataLen,
3904 wlan_hdd_extscan_config_policy)) {
3905 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Invalid ATTR"));
3906 return -EINVAL;
3907 }
3908
3909 /* Parse and fetch request Id */
3910 if (!tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_REQUEST_ID]) {
3911 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr request id failed"));
3912 return -EINVAL;
3913 }
3914
Dino Mycle6fb96c12014-06-10 11:52:40 +05303915
Dino Myclee8843b32014-07-04 14:21:45 +05303916 reqMsg.requestId = nla_get_u32(
Dino Mycle6fb96c12014-06-10 11:52:40 +05303917 tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_REQUEST_ID]);
Dino Myclee8843b32014-07-04 14:21:45 +05303918 hddLog(VOS_TRACE_LEVEL_INFO, FL("Req Id (%d)"), reqMsg.requestId);
Dino Mycle6fb96c12014-06-10 11:52:40 +05303919
Dino Myclee8843b32014-07-04 14:21:45 +05303920 reqMsg.sessionId = pAdapter->sessionId;
3921 hddLog(VOS_TRACE_LEVEL_INFO, FL("Session Id (%d)"), reqMsg.sessionId);
Dino Mycle6fb96c12014-06-10 11:52:40 +05303922
Dino Myclee8843b32014-07-04 14:21:45 +05303923 status = sme_ResetSignificantChange(pHddCtx->hHal, &reqMsg);
Dino Mycle6fb96c12014-06-10 11:52:40 +05303924 if (!HAL_STATUS_SUCCESS(status)) {
3925 hddLog(VOS_TRACE_LEVEL_ERROR,
3926 FL("sme_ResetSignificantChange failed(err=%d)"), status);
Dino Mycle6fb96c12014-06-10 11:52:40 +05303927 return -EINVAL;
3928 }
3929
3930 hddLog(VOS_TRACE_LEVEL_ERROR, FL(" Exiting"));
3931 return 0;
3932}
3933
3934#endif /* WLAN_FEATURE_EXTSCAN */
3935
Atul Mittal115287b2014-07-08 13:26:33 +05303936/*EXT TDLS*/
3937static const struct nla_policy
3938wlan_hdd_tdls_config_enable_policy[QCA_WLAN_VENDOR_ATTR_TDLS_ENABLE_MAX +1] =
3939{
3940 [QCA_WLAN_VENDOR_ATTR_TDLS_ENABLE_MAC_ADDR] = {.type = NLA_UNSPEC },
3941 [QCA_WLAN_VENDOR_ATTR_TDLS_ENABLE_CHANNEL] = {.type = NLA_S32 },
3942 [QCA_WLAN_VENDOR_ATTR_TDLS_ENABLE_GLOBAL_OPERATING_CLASS] =
3943 {.type = NLA_S32 },
3944 [QCA_WLAN_VENDOR_ATTR_TDLS_ENABLE_MAX_LATENCY_MS] = {.type = NLA_S32 },
3945 [QCA_WLAN_VENDOR_ATTR_TDLS_ENABLE_MIN_BANDWIDTH_KBPS] = {.type = NLA_S32 },
3946
3947};
3948
3949static const struct nla_policy
3950wlan_hdd_tdls_config_disable_policy[QCA_WLAN_VENDOR_ATTR_TDLS_DISABLE_MAX +1] =
3951{
3952 [QCA_WLAN_VENDOR_ATTR_TDLS_DISABLE_MAC_ADDR] = {.type = NLA_UNSPEC },
3953
3954};
3955
3956static const struct nla_policy
3957wlan_hdd_tdls_config_state_change_policy[
3958 QCA_WLAN_VENDOR_ATTR_TDLS_STATE_MAX +1] =
3959{
3960 [QCA_WLAN_VENDOR_ATTR_TDLS_STATE_MAC_ADDR] = {.type = NLA_UNSPEC },
3961 [QCA_WLAN_VENDOR_ATTR_TDLS_NEW_STATE] = {.type = NLA_S32 },
3962 [QCA_WLAN_VENDOR_ATTR_TDLS_STATE_REASON] = {.type = NLA_S32 },
3963
3964};
3965
3966static const struct nla_policy
3967wlan_hdd_tdls_config_get_status_policy[
3968 QCA_WLAN_VENDOR_ATTR_TDLS_GET_STATUS_MAX +1] =
3969{
3970 [QCA_WLAN_VENDOR_ATTR_TDLS_GET_STATUS_MAC_ADDR] = {.type = NLA_UNSPEC },
3971 [QCA_WLAN_VENDOR_ATTR_TDLS_GET_STATUS_STATE] = {.type = NLA_S32 },
3972 [QCA_WLAN_VENDOR_ATTR_TDLS_GET_STATUS_REASON] = {.type = NLA_S32 },
3973
3974};
3975static int wlan_hdd_cfg80211_exttdls_get_status(struct wiphy *wiphy,
3976 struct wireless_dev *wdev,
3977 void *data,
3978 int data_len)
3979{
3980 u8 peer[6] = {0};
3981 struct net_device *dev = wdev->netdev;
3982 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
3983 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
3984 struct nlattr *tb[QCA_WLAN_VENDOR_ATTR_TDLS_GET_STATUS_MAX + 1];
3985 eHalStatus ret;
3986 tANI_S32 state;
3987 tANI_S32 reason;
3988 struct sk_buff *skb = NULL;
3989
3990 ret = wlan_hdd_validate_context(pHddCtx);
3991 if (0 != ret) {
3992
3993 return -EINVAL;
3994 }
3995 if (pHddCtx->cfg_ini->fTDLSExternalControl == FALSE) {
3996
3997 return -ENOTSUPP;
3998 }
3999 if (nla_parse(tb, QCA_WLAN_VENDOR_ATTR_TDLS_GET_STATUS_MAX,
4000 data, data_len,
4001 wlan_hdd_tdls_config_get_status_policy)) {
4002 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Invalid ATTR"));
4003 return -EINVAL;
4004 }
4005
4006 /* Parse and fetch mac address */
4007 if (!tb[QCA_WLAN_VENDOR_ATTR_TDLS_GET_STATUS_MAC_ADDR]) {
4008 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr mac addr failed"));
4009 return -EINVAL;
4010 }
4011
4012 memcpy(peer, nla_data(
4013 tb[QCA_WLAN_VENDOR_ATTR_TDLS_GET_STATUS_MAC_ADDR]),
4014 sizeof(peer));
4015 hddLog(VOS_TRACE_LEVEL_INFO, FL(MAC_ADDRESS_STR),MAC_ADDR_ARRAY(peer));
4016
4017 ret = wlan_hdd_tdls_get_status(pAdapter, peer, &state, &reason);
4018
4019 if (0 != ret) {
4020 hddLog(VOS_TRACE_LEVEL_ERROR,
4021 FL("get status Failed"));
4022 return -EINVAL;
4023 }
4024 skb = cfg80211_vendor_cmd_alloc_reply_skb(wiphy,
4025 2 * sizeof(s32) +
4026 NLMSG_HDRLEN);
4027
4028 if (!skb) {
4029 hddLog(VOS_TRACE_LEVEL_ERROR,
4030 FL("cfg80211_vendor_cmd_alloc_reply_skb failed"));
4031 return -EINVAL;
4032 }
4033 hddLog(VOS_TRACE_LEVEL_INFO, FL("Reason (%d) Status (%d) tdls peer" MAC_ADDRESS_STR),
4034 reason,
4035 state,
4036 MAC_ADDR_ARRAY(peer));
4037
4038 if (nla_put_s32(skb, QCA_WLAN_VENDOR_ATTR_TDLS_GET_STATUS_STATE, state) ||
4039 nla_put_s32(skb, QCA_WLAN_VENDOR_ATTR_TDLS_GET_STATUS_REASON, reason)) {
4040
4041 hddLog(VOS_TRACE_LEVEL_ERROR, FL("nla put fail"));
4042 goto nla_put_failure;
4043 }
4044
4045 return cfg80211_vendor_cmd_reply(skb);
4046
4047nla_put_failure:
4048 kfree_skb(skb);
4049 return -EINVAL;
4050}
4051
4052static int wlan_hdd_cfg80211_exttdls_callback(tANI_U8* mac,
4053 tANI_S32 state,
4054 tANI_S32 reason,
4055 void *ctx)
4056{
4057 hdd_adapter_t* pAdapter = (hdd_adapter_t*)ctx;
4058 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
4059 struct sk_buff *skb = NULL;
4060
4061 if (wlan_hdd_validate_context(pHddCtx)) {
4062 hddLog(VOS_TRACE_LEVEL_ERROR, FL("HDD context is not valid "));
4063 return -EINVAL;
4064 }
4065
4066 if (pHddCtx->cfg_ini->fTDLSExternalControl == FALSE) {
4067
4068 return -ENOTSUPP;
4069 }
4070 skb = cfg80211_vendor_event_alloc(
4071 pHddCtx->wiphy,
4072 EXTTDLS_EVENT_BUF_SIZE + NLMSG_HDRLEN,
4073 QCA_NL80211_VENDOR_SUBCMD_TDLS_STATE_CHANGE_INDEX,
4074 GFP_KERNEL);
4075
4076 if (!skb) {
4077 hddLog(VOS_TRACE_LEVEL_ERROR,
4078 FL("cfg80211_vendor_event_alloc failed"));
4079 return -EINVAL;
4080 }
4081 hddLog(VOS_TRACE_LEVEL_INFO, FL("Entering "));
4082 hddLog(VOS_TRACE_LEVEL_INFO, "Reason (%d) Status (%d)", reason, state);
4083 hddLog(VOS_TRACE_LEVEL_WARN, "tdls peer " MAC_ADDRESS_STR,
4084 MAC_ADDR_ARRAY(mac));
4085
4086 if (nla_put(skb, QCA_WLAN_VENDOR_ATTR_TDLS_STATE_MAC_ADDR,
4087 VOS_MAC_ADDR_SIZE, mac) ||
4088 nla_put_s32(skb, QCA_WLAN_VENDOR_ATTR_TDLS_NEW_STATE, state) ||
4089 nla_put_s32(skb, QCA_WLAN_VENDOR_ATTR_TDLS_STATE_REASON, reason)
4090 ) {
4091
4092 hddLog(VOS_TRACE_LEVEL_ERROR, FL("nla put fail"));
4093 goto nla_put_failure;
4094 }
4095
4096 cfg80211_vendor_event(skb, GFP_KERNEL);
4097 return (0);
4098
4099nla_put_failure:
4100 kfree_skb(skb);
4101 return -EINVAL;
4102}
4103
4104static int wlan_hdd_cfg80211_exttdls_enable(struct wiphy *wiphy,
4105 struct wireless_dev *wdev,
4106 void *data,
4107 int data_len)
4108{
4109 u8 peer[6] = {0};
4110 struct net_device *dev = wdev->netdev;
4111 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
4112 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
4113 struct nlattr *tb[QCA_WLAN_VENDOR_ATTR_TDLS_ENABLE_MAX + 1];
4114 eHalStatus status;
4115 tdls_req_params_t pReqMsg = {0};
4116
4117 status = wlan_hdd_validate_context(pHddCtx);
4118 if (0 != status) {
4119 hddLog(VOS_TRACE_LEVEL_ERROR,
4120 FL("HDD context is not valid"));
4121 return -EINVAL;
4122 }
4123 if (pHddCtx->cfg_ini->fTDLSExternalControl == FALSE) {
4124
4125 return -ENOTSUPP;
4126 }
4127 if (nla_parse(tb, QCA_WLAN_VENDOR_ATTR_TDLS_ENABLE_MAX,
4128 data, data_len,
4129 wlan_hdd_tdls_config_enable_policy)) {
4130 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Invalid ATTR"));
4131 return -EINVAL;
4132 }
4133
4134 /* Parse and fetch mac address */
4135 if (!tb[QCA_WLAN_VENDOR_ATTR_TDLS_ENABLE_MAC_ADDR]) {
4136 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr mac addr failed"));
4137 return -EINVAL;
4138 }
4139
4140 memcpy(peer, nla_data(
4141 tb[QCA_WLAN_VENDOR_ATTR_TDLS_ENABLE_MAC_ADDR]),
4142 sizeof(peer));
4143 hddLog(VOS_TRACE_LEVEL_INFO, FL(MAC_ADDRESS_STR),MAC_ADDR_ARRAY(peer));
4144
4145 /* Parse and fetch channel */
4146 if (!tb[QCA_WLAN_VENDOR_ATTR_TDLS_ENABLE_CHANNEL]) {
4147 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr channel failed"));
4148 return -EINVAL;
4149 }
4150 pReqMsg.channel = nla_get_s32(
4151 tb[QCA_WLAN_VENDOR_ATTR_TDLS_ENABLE_CHANNEL]);
4152 hddLog(VOS_TRACE_LEVEL_INFO, FL("Channel Num (%d)"), pReqMsg.channel);
4153
4154 /* Parse and fetch global operating class */
4155 if (!tb[QCA_WLAN_VENDOR_ATTR_TDLS_ENABLE_GLOBAL_OPERATING_CLASS]) {
4156 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr operating class failed"));
4157 return -EINVAL;
4158 }
4159 pReqMsg.global_operating_class = nla_get_s32(
4160 tb[QCA_WLAN_VENDOR_ATTR_TDLS_ENABLE_GLOBAL_OPERATING_CLASS]);
4161 hddLog(VOS_TRACE_LEVEL_INFO, FL("Operating class (%d)"),
4162 pReqMsg.global_operating_class);
4163
4164 /* Parse and fetch latency ms */
4165 if (!tb[QCA_WLAN_VENDOR_ATTR_TDLS_ENABLE_MAX_LATENCY_MS]) {
4166 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr latency failed"));
4167 return -EINVAL;
4168 }
4169 pReqMsg.max_latency_ms = nla_get_s32(
4170 tb[QCA_WLAN_VENDOR_ATTR_TDLS_ENABLE_MAX_LATENCY_MS]);
4171 hddLog(VOS_TRACE_LEVEL_INFO, FL("Latency (%d)"),
4172 pReqMsg.max_latency_ms);
4173
4174 /* Parse and fetch required bandwidth kbps */
4175 if (!tb[QCA_WLAN_VENDOR_ATTR_TDLS_ENABLE_MIN_BANDWIDTH_KBPS]) {
4176 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr bandwidth failed"));
4177 return -EINVAL;
4178 }
4179
4180 pReqMsg.min_bandwidth_kbps = nla_get_s32(
4181 tb[QCA_WLAN_VENDOR_ATTR_TDLS_ENABLE_MIN_BANDWIDTH_KBPS]);
4182 hddLog(VOS_TRACE_LEVEL_INFO, FL("Bandwidth (%d)"),
4183 pReqMsg.min_bandwidth_kbps);
4184
4185 return (wlan_hdd_tdls_extctrl_config_peer(pAdapter,
4186 peer,
4187 wlan_hdd_cfg80211_exttdls_callback));
4188}
4189
4190static int wlan_hdd_cfg80211_exttdls_disable(struct wiphy *wiphy,
4191 struct wireless_dev *wdev,
4192 void *data,
4193 int data_len)
4194{
4195 u8 peer[6] = {0};
4196 struct net_device *dev = wdev->netdev;
4197 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
4198 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
4199 struct nlattr *tb[QCA_WLAN_VENDOR_ATTR_TDLS_DISABLE_MAX + 1];
4200 eHalStatus status;
4201
4202 status = wlan_hdd_validate_context(pHddCtx);
4203 if (0 != status) {
4204 hddLog(VOS_TRACE_LEVEL_ERROR,
4205 FL("HDD context is not valid"));
4206 return -EINVAL;
4207 }
4208 if (pHddCtx->cfg_ini->fTDLSExternalControl == FALSE) {
4209
4210 return -ENOTSUPP;
4211 }
4212 if (nla_parse(tb, QCA_WLAN_VENDOR_ATTR_TDLS_DISABLE_MAX,
4213 data, data_len,
4214 wlan_hdd_tdls_config_disable_policy)) {
4215 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Invalid ATTR"));
4216 return -EINVAL;
4217 }
4218 /* Parse and fetch mac address */
4219 if (!tb[QCA_WLAN_VENDOR_ATTR_TDLS_DISABLE_MAC_ADDR]) {
4220 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr mac addr failed"));
4221 return -EINVAL;
4222 }
4223
4224 memcpy(peer, nla_data(
4225 tb[QCA_WLAN_VENDOR_ATTR_TDLS_DISABLE_MAC_ADDR]),
4226 sizeof(peer));
4227 hddLog(VOS_TRACE_LEVEL_INFO, FL(MAC_ADDRESS_STR),MAC_ADDR_ARRAY(peer));
4228
4229 return (wlan_hdd_tdls_extctrl_deconfig_peer(pAdapter, peer));
4230}
4231
4232
Sunil Duttc69bccb2014-05-26 21:30:20 +05304233const struct wiphy_vendor_command hdd_wiphy_vendor_commands[] =
4234{
4235#ifdef WLAN_FEATURE_LINK_LAYER_STATS
4236 {
4237 .info.vendor_id = QCA_NL80211_VENDOR_ID,
4238 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_LL_STATS_CLR,
4239 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
4240 WIPHY_VENDOR_CMD_NEED_NETDEV |
4241 WIPHY_VENDOR_CMD_NEED_RUNNING,
4242 .doit = wlan_hdd_cfg80211_ll_stats_clear
4243 },
4244
4245 {
4246 .info.vendor_id = QCA_NL80211_VENDOR_ID,
4247 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_LL_STATS_SET,
4248 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
4249 WIPHY_VENDOR_CMD_NEED_NETDEV |
4250 WIPHY_VENDOR_CMD_NEED_RUNNING,
4251 .doit = wlan_hdd_cfg80211_ll_stats_set
4252 },
4253
4254 {
4255 .info.vendor_id = QCA_NL80211_VENDOR_ID,
4256 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_LL_STATS_GET,
4257 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
4258 WIPHY_VENDOR_CMD_NEED_NETDEV |
4259 WIPHY_VENDOR_CMD_NEED_RUNNING,
4260 .doit = wlan_hdd_cfg80211_ll_stats_get
Dino Mycle6fb96c12014-06-10 11:52:40 +05304261 },
Sunil Duttc69bccb2014-05-26 21:30:20 +05304262#endif /* WLAN_FEATURE_LINK_LAYER_STATS */
Dino Mycle6fb96c12014-06-10 11:52:40 +05304263#ifdef WLAN_FEATURE_EXTSCAN
4264 {
4265 .info.vendor_id = QCA_NL80211_VENDOR_ID,
4266 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_START,
4267 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
4268 WIPHY_VENDOR_CMD_NEED_NETDEV |
4269 WIPHY_VENDOR_CMD_NEED_RUNNING,
4270 .doit = wlan_hdd_cfg80211_extscan_start
4271 },
4272 {
4273 .info.vendor_id = QCA_NL80211_VENDOR_ID,
4274 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_STOP,
4275 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
4276 WIPHY_VENDOR_CMD_NEED_NETDEV |
4277 WIPHY_VENDOR_CMD_NEED_RUNNING,
4278 .doit = wlan_hdd_cfg80211_extscan_stop
4279 },
4280 {
4281 .info.vendor_id = QCA_NL80211_VENDOR_ID,
4282 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_GET_VALID_CHANNELS,
4283 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
4284 WIPHY_VENDOR_CMD_NEED_NETDEV,
4285 .doit = wlan_hdd_cfg80211_extscan_get_valid_channels
4286 },
4287 {
4288 .info.vendor_id = QCA_NL80211_VENDOR_ID,
4289 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_GET_CAPABILITIES,
4290 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
4291 WIPHY_VENDOR_CMD_NEED_NETDEV |
4292 WIPHY_VENDOR_CMD_NEED_RUNNING,
4293 .doit = wlan_hdd_cfg80211_extscan_get_capabilities
4294 },
4295 {
4296 .info.vendor_id = QCA_NL80211_VENDOR_ID,
4297 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_GET_CACHED_RESULTS,
4298 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
4299 WIPHY_VENDOR_CMD_NEED_NETDEV |
4300 WIPHY_VENDOR_CMD_NEED_RUNNING,
4301 .doit = wlan_hdd_cfg80211_extscan_get_cached_results
4302 },
4303 {
4304 .info.vendor_id = QCA_NL80211_VENDOR_ID,
4305 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_SET_BSSID_HOTLIST,
4306 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
4307 WIPHY_VENDOR_CMD_NEED_NETDEV |
4308 WIPHY_VENDOR_CMD_NEED_RUNNING,
4309 .doit = wlan_hdd_cfg80211_extscan_set_bssid_hotlist
4310 },
4311 {
4312 .info.vendor_id = QCA_NL80211_VENDOR_ID,
4313 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_RESET_BSSID_HOTLIST,
4314 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
4315 WIPHY_VENDOR_CMD_NEED_NETDEV |
4316 WIPHY_VENDOR_CMD_NEED_RUNNING,
4317 .doit = wlan_hdd_cfg80211_extscan_reset_bssid_hotlist
4318 },
4319 {
4320 .info.vendor_id = QCA_NL80211_VENDOR_ID,
4321 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_SET_SIGNIFICANT_CHANGE,
4322 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
4323 WIPHY_VENDOR_CMD_NEED_NETDEV |
4324 WIPHY_VENDOR_CMD_NEED_RUNNING,
4325 .doit = wlan_hdd_cfg80211_extscan_set_significant_change
4326 },
4327 {
4328 .info.vendor_id = QCA_NL80211_VENDOR_ID,
4329 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_RESET_SIGNIFICANT_CHANGE,
4330 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
4331 WIPHY_VENDOR_CMD_NEED_NETDEV |
4332 WIPHY_VENDOR_CMD_NEED_RUNNING,
4333 .doit = wlan_hdd_cfg80211_extscan_reset_significant_change
4334 },
4335#endif /* WLAN_FEATURE_EXTSCAN */
Atul Mittal115287b2014-07-08 13:26:33 +05304336/*EXT TDLS*/
4337 {
4338 .info.vendor_id = QCA_NL80211_VENDOR_ID,
4339 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_TDLS_ENABLE,
4340 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
4341 WIPHY_VENDOR_CMD_NEED_NETDEV |
4342 WIPHY_VENDOR_CMD_NEED_RUNNING,
4343 .doit = wlan_hdd_cfg80211_exttdls_enable
4344 },
4345 {
4346 .info.vendor_id = QCA_NL80211_VENDOR_ID,
4347 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_TDLS_DISABLE,
4348 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
4349 WIPHY_VENDOR_CMD_NEED_NETDEV |
4350 WIPHY_VENDOR_CMD_NEED_RUNNING,
4351 .doit = wlan_hdd_cfg80211_exttdls_disable
4352 },
4353 {
4354 .info.vendor_id = QCA_NL80211_VENDOR_ID,
4355 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_TDLS_GET_STATUS,
4356 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
4357 WIPHY_VENDOR_CMD_NEED_NETDEV,
4358 .doit = wlan_hdd_cfg80211_exttdls_get_status
4359 },
4360
Sunil Duttc69bccb2014-05-26 21:30:20 +05304361};
4362
Rajesh Chauhan98a31f82014-01-06 20:15:25 -08004363/* vendor specific events */
Sunil Duttc69bccb2014-05-26 21:30:20 +05304364static const
4365struct nl80211_vendor_cmd_info wlan_hdd_cfg80211_vendor_events[] =
Rajesh Chauhan98a31f82014-01-06 20:15:25 -08004366{
4367#ifdef FEATURE_WLAN_CH_AVOID
4368 {
Sunil Duttc69bccb2014-05-26 21:30:20 +05304369 .vendor_id = QCA_NL80211_VENDOR_ID,
4370 .subcmd = QCA_NL80211_VENDOR_SUBCMD_AVOID_FREQUENCY
Rajesh Chauhan98a31f82014-01-06 20:15:25 -08004371 },
Sunil Duttc69bccb2014-05-26 21:30:20 +05304372#endif /* FEATURE_WLAN_CH_AVOID Index = 0*/
4373#ifdef WLAN_FEATURE_LINK_LAYER_STATS
4374 {
4375 /* Index = 1*/
4376 .vendor_id = QCA_NL80211_VENDOR_ID,
4377 .subcmd = QCA_NL80211_VENDOR_SUBCMD_LL_STATS_SET
4378 },
4379 {
4380 /* Index = 2*/
4381 .vendor_id = QCA_NL80211_VENDOR_ID,
4382 .subcmd = QCA_NL80211_VENDOR_SUBCMD_LL_STATS_GET
4383 },
4384 {
4385 /* Index = 3*/
4386 .vendor_id = QCA_NL80211_VENDOR_ID,
4387 .subcmd = QCA_NL80211_VENDOR_SUBCMD_LL_STATS_CLR
4388 },
4389 {
4390 /* Index = 4*/
4391 .vendor_id = QCA_NL80211_VENDOR_ID,
4392 .subcmd = QCA_NL80211_VENDOR_SUBCMD_LL_STATS_RADIO_RESULTS
4393 },
4394 {
4395 /* Index = 5*/
4396 .vendor_id = QCA_NL80211_VENDOR_ID,
4397 .subcmd = QCA_NL80211_VENDOR_SUBCMD_LL_STATS_IFACE_RESULTS
4398 },
4399 {
4400 /* Index = 6*/
4401 .vendor_id = QCA_NL80211_VENDOR_ID,
4402 .subcmd = QCA_NL80211_VENDOR_SUBCMD_LL_STATS_PEERS_RESULTS
4403 },
4404#endif /* WLAN_FEATURE_LINK_LAYER_STATS */
Dino Mycle6fb96c12014-06-10 11:52:40 +05304405#ifdef WLAN_FEATURE_EXTSCAN
4406 {
4407 .vendor_id = QCA_NL80211_VENDOR_ID,
4408 .subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_START
4409 },
4410 {
4411 .vendor_id = QCA_NL80211_VENDOR_ID,
4412 .subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_STOP
4413 },
4414 {
4415 .vendor_id = QCA_NL80211_VENDOR_ID,
4416 .subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_GET_CAPABILITIES
4417 },
4418 {
4419 .vendor_id = QCA_NL80211_VENDOR_ID,
4420 .subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_GET_CACHED_RESULTS
4421 },
4422 {
4423 .vendor_id = QCA_NL80211_VENDOR_ID,
4424 .subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_SCAN_RESULTS_AVAILABLE
4425 },
4426 {
4427 .vendor_id = QCA_NL80211_VENDOR_ID,
4428 .subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_FULL_SCAN_RESULT
4429 },
4430 {
4431 .vendor_id = QCA_NL80211_VENDOR_ID,
4432 .subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_SCAN_EVENT
4433 },
4434 {
4435 .vendor_id = QCA_NL80211_VENDOR_ID,
4436 .subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_HOTLIST_AP_FOUND
4437 },
4438 {
4439 .vendor_id = QCA_NL80211_VENDOR_ID,
4440 .subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_SET_BSSID_HOTLIST
4441 },
4442 {
4443 .vendor_id = QCA_NL80211_VENDOR_ID,
4444 .subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_RESET_BSSID_HOTLIST
4445 },
4446 {
4447 .vendor_id = QCA_NL80211_VENDOR_ID,
4448 .subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_SIGNIFICANT_CHANGE
4449 },
4450 {
4451 .vendor_id = QCA_NL80211_VENDOR_ID,
4452 .subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_SET_SIGNIFICANT_CHANGE
4453 },
4454 {
4455 .vendor_id = QCA_NL80211_VENDOR_ID,
4456 .subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_RESET_SIGNIFICANT_CHANGE
4457 },
4458#endif /* WLAN_FEATURE_EXTSCAN */
Atul Mittal115287b2014-07-08 13:26:33 +05304459/*EXT TDLS*/
4460 {
4461 .vendor_id = QCA_NL80211_VENDOR_ID,
4462 .subcmd = QCA_NL80211_VENDOR_SUBCMD_TDLS_STATE
4463 },
Rajesh Chauhan98a31f82014-01-06 20:15:25 -08004464};
4465
Jeff Johnson295189b2012-06-20 16:38:30 -07004466/*
Madan Mohan Koyyalamudi71278262013-04-12 22:00:48 +05304467 * FUNCTION: wlan_hdd_cfg80211_wiphy_alloc
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304468 * This function is called by hdd_wlan_startup()
4469 * during initialization.
Madan Mohan Koyyalamudi71278262013-04-12 22:00:48 +05304470 * This function is used to allocate wiphy structure.
Jeff Johnson295189b2012-06-20 16:38:30 -07004471 */
Madan Mohan Koyyalamudi71278262013-04-12 22:00:48 +05304472struct wiphy *wlan_hdd_cfg80211_wiphy_alloc(int priv_size)
Jeff Johnson295189b2012-06-20 16:38:30 -07004473{
4474 struct wiphy *wiphy;
4475 ENTER();
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304476 /*
4477 * Create wiphy device
Jeff Johnson295189b2012-06-20 16:38:30 -07004478 */
4479 wiphy = wiphy_new(&wlan_hdd_cfg80211_ops, priv_size);
4480
4481 if (!wiphy)
4482 {
4483 /* Print error and jump into err label and free the memory */
4484 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: wiphy init failed", __func__);
4485 return NULL;
4486 }
4487
Sunil Duttc69bccb2014-05-26 21:30:20 +05304488
Jeff Johnson295189b2012-06-20 16:38:30 -07004489 return wiphy;
4490}
4491
4492/*
4493 * FUNCTION: wlan_hdd_cfg80211_update_band
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304494 * This function is called from the supplicant through a
Jeff Johnson295189b2012-06-20 16:38:30 -07004495 * private ioctl to change the band value
4496 */
4497int wlan_hdd_cfg80211_update_band(struct wiphy *wiphy, eCsrBand eBand)
4498{
Gopichand Nakkala1f7a64f2013-04-01 18:37:17 +05304499 int i, j;
4500 eNVChannelEnabledType channelEnabledState;
4501
Jeff Johnsone7245742012-09-05 17:12:55 -07004502 ENTER();
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05304503
Gopichand Nakkala1f7a64f2013-04-01 18:37:17 +05304504 for (i = 0; i < IEEE80211_NUM_BANDS; i++)
Jeff Johnson295189b2012-06-20 16:38:30 -07004505 {
Gopichand Nakkala1f7a64f2013-04-01 18:37:17 +05304506
4507 if (NULL == wiphy->bands[i])
4508 {
4509 hddLog(VOS_TRACE_LEVEL_ERROR,"%s: wiphy->bands[i] is NULL, i = %d",
4510 __func__, i);
4511 continue;
4512 }
4513
4514 for (j = 0; j < wiphy->bands[i]->n_channels; j++)
4515 {
4516 struct ieee80211_supported_band *band = wiphy->bands[i];
4517
4518 channelEnabledState = vos_nv_getChannelEnabledState(
4519 band->channels[j].hw_value);
4520
4521 if (IEEE80211_BAND_2GHZ == i && eCSR_BAND_5G == eBand) // 5G only
4522 {
4523 // Enable Social channels for P2P
4524 if (WLAN_HDD_IS_SOCIAL_CHANNEL(band->channels[j].center_freq) &&
4525 NV_CHANNEL_ENABLE == channelEnabledState)
4526 band->channels[j].flags &= ~IEEE80211_CHAN_DISABLED;
4527 else
4528 band->channels[j].flags |= IEEE80211_CHAN_DISABLED;
4529 continue;
4530 }
4531 else if (IEEE80211_BAND_5GHZ == i && eCSR_BAND_24 == eBand) // 2G only
4532 {
4533 band->channels[j].flags |= IEEE80211_CHAN_DISABLED;
4534 continue;
4535 }
4536
4537 if (NV_CHANNEL_DISABLE == channelEnabledState ||
4538 NV_CHANNEL_INVALID == channelEnabledState)
4539 {
4540 band->channels[j].flags |= IEEE80211_CHAN_DISABLED;
4541 }
4542 else if (NV_CHANNEL_DFS == channelEnabledState)
4543 {
4544 band->channels[j].flags &= ~IEEE80211_CHAN_DISABLED;
4545 band->channels[j].flags |= IEEE80211_CHAN_RADAR;
4546 }
4547 else
4548 {
4549 band->channels[j].flags &= ~(IEEE80211_CHAN_DISABLED
4550 |IEEE80211_CHAN_RADAR);
4551 }
4552 }
Jeff Johnson295189b2012-06-20 16:38:30 -07004553 }
4554 return 0;
4555}
4556/*
4557 * FUNCTION: wlan_hdd_cfg80211_init
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304558 * This function is called by hdd_wlan_startup()
4559 * during initialization.
Jeff Johnson295189b2012-06-20 16:38:30 -07004560 * This function is used to initialize and register wiphy structure.
4561 */
Madan Mohan Koyyalamudi71278262013-04-12 22:00:48 +05304562int wlan_hdd_cfg80211_init(struct device *dev,
Jeff Johnson295189b2012-06-20 16:38:30 -07004563 struct wiphy *wiphy,
4564 hdd_config_t *pCfg
4565 )
4566{
Gopichand Nakkala1f7a64f2013-04-01 18:37:17 +05304567 int i, j;
Vinay Krishna Erannafacf5e22014-02-24 13:16:25 +05304568 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
4569
Jeff Johnsone7245742012-09-05 17:12:55 -07004570 ENTER();
4571
Jeff Johnson295189b2012-06-20 16:38:30 -07004572 /* Now bind the underlying wlan device with wiphy */
4573 set_wiphy_dev(wiphy, dev);
4574
4575 wiphy->mgmt_stypes = wlan_hdd_txrx_stypes;
Amar Singhalfddc28c2013-09-05 13:03:40 -07004576
Kiet Lam6c583332013-10-14 05:37:09 +05304577#ifndef CONFIG_ENABLE_LINUX_REG
Amar Singhal0a402232013-10-11 20:57:16 -07004578 /* the flag for the other case would be initialzed in
4579 vos_init_wiphy_from_nv_bin */
Amar Singhal0a402232013-10-11 20:57:16 -07004580 wiphy->flags |= WIPHY_FLAG_STRICT_REGULATORY;
Kiet Lam6c583332013-10-14 05:37:09 +05304581#endif
Amar Singhala49cbc52013-10-08 18:37:44 -07004582
Amar Singhalfddc28c2013-09-05 13:03:40 -07004583 /* This will disable updating of NL channels from passive to
4584 * active if a beacon is received on passive channel. */
4585 wiphy->flags |= WIPHY_FLAG_DISABLE_BEACON_HINTS;
Amar Singhalf0073192013-09-20 12:34:56 -07004586
Amar Singhalfddc28c2013-09-05 13:03:40 -07004587
Amar Singhala49cbc52013-10-08 18:37:44 -07004588
Jeff Johnson04dd8a82012-06-29 20:41:40 -07004589#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,4,0))
Madan Mohan Koyyalamudi1b4afb02012-10-22 15:25:16 -07004590 wiphy->flags |= WIPHY_FLAG_HAVE_AP_SME
4591 | WIPHY_FLAG_AP_PROBE_RESP_OFFLOAD
4592 | WIPHY_FLAG_HAS_REMAIN_ON_CHANNEL
Jeff Johnsone7245742012-09-05 17:12:55 -07004593 | WIPHY_FLAG_OFFCHAN_TX;
Kiet Lam6c583332013-10-14 05:37:09 +05304594 wiphy->country_ie_pref = NL80211_COUNTRY_IE_IGNORE_CORE;
Jeff Johnson04dd8a82012-06-29 20:41:40 -07004595#endif
Amar Singhala49cbc52013-10-08 18:37:44 -07004596
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08004597#if defined (WLAN_FEATURE_VOWIFI_11R) || defined (FEATURE_WLAN_ESE) || defined(FEATURE_WLAN_LFR)
Srinivas Girigowda640728a2013-03-28 12:21:54 -07004598 if (pCfg->isFastTransitionEnabled
James Zmuda77fb5ae2013-01-29 08:00:17 -08004599#ifdef FEATURE_WLAN_LFR
Srinivas Girigowda640728a2013-03-28 12:21:54 -07004600 || pCfg->isFastRoamIniFeatureEnabled
4601#endif
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08004602#ifdef FEATURE_WLAN_ESE
4603 || pCfg->isEseIniFeatureEnabled
Srinivas Girigowda640728a2013-03-28 12:21:54 -07004604#endif
4605 )
4606 {
4607 wiphy->flags |= WIPHY_FLAG_SUPPORTS_FW_ROAM;
4608 }
James Zmuda77fb5ae2013-01-29 08:00:17 -08004609#endif
Mohit Khanna698ba2a2012-12-04 15:08:18 -08004610#ifdef FEATURE_WLAN_TDLS
4611 wiphy->flags |= WIPHY_FLAG_SUPPORTS_TDLS
4612 | WIPHY_FLAG_TDLS_EXTERNAL_SETUP;
4613#endif
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +05304614#ifdef FEATURE_WLAN_SCAN_PNO
Hardik Kantilal Patel3dfd8792013-11-13 20:34:57 +05304615 if (pCfg->configPNOScanSupport)
4616 {
4617 wiphy->flags |= WIPHY_FLAG_SUPPORTS_SCHED_SCAN;
4618 wiphy->max_sched_scan_ssids = SIR_PNO_MAX_SUPP_NETWORKS;
4619 wiphy->max_match_sets = SIR_PNO_MAX_SUPP_NETWORKS;
4620 wiphy->max_sched_scan_ie_len = SIR_MAC_MAX_IE_LENGTH;
4621 }
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +05304622#endif/*FEATURE_WLAN_SCAN_PNO*/
Mohit Khanna698ba2a2012-12-04 15:08:18 -08004623
Amar Singhalfddc28c2013-09-05 13:03:40 -07004624#ifdef CONFIG_ENABLE_LINUX_REG
Madan Mohan Koyyalamudic3a240c2012-09-28 15:34:08 -07004625 /* even with WIPHY_FLAG_CUSTOM_REGULATORY,
4626 driver can still register regulatory callback and
Amar Singhalfddc28c2013-09-05 13:03:40 -07004627 it will get regulatory settings in wiphy->band[], but
Madan Mohan Koyyalamudic3a240c2012-09-28 15:34:08 -07004628 driver need to determine what to do with both
4629 regulatory settings */
Amar Singhalfddc28c2013-09-05 13:03:40 -07004630
4631 wiphy->reg_notifier = wlan_hdd_linux_reg_notifier;
Amar Singhala49cbc52013-10-08 18:37:44 -07004632#else
4633 wiphy->reg_notifier = wlan_hdd_crda_reg_notifier;
Amar Singhalfddc28c2013-09-05 13:03:40 -07004634#endif
Jeff Johnson04dd8a82012-06-29 20:41:40 -07004635
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304636 wiphy->max_scan_ssids = MAX_SCAN_SSID;
4637
Madan Mohan Koyyalamudi6815b162013-07-19 17:17:46 +05304638 wiphy->max_scan_ie_len = SIR_MAC_MAX_IE_LENGTH;
Jeff Johnson295189b2012-06-20 16:38:30 -07004639
Gopichand Nakkalac005b7c2013-05-14 16:04:14 +05304640 wiphy->max_acl_mac_addrs = MAX_ACL_MAC_ADDRESS;
4641
Jeff Johnson295189b2012-06-20 16:38:30 -07004642 /* Supports STATION & AD-HOC modes right now */
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304643 wiphy->interface_modes = BIT(NL80211_IFTYPE_STATION)
Jeff Johnson295189b2012-06-20 16:38:30 -07004644 | BIT(NL80211_IFTYPE_ADHOC)
Jeff Johnson295189b2012-06-20 16:38:30 -07004645 | BIT(NL80211_IFTYPE_P2P_CLIENT)
4646 | BIT(NL80211_IFTYPE_P2P_GO)
Jeff Johnson295189b2012-06-20 16:38:30 -07004647 | BIT(NL80211_IFTYPE_AP);
4648
Rashmi Ramannabd3feb72014-02-25 16:14:48 +05304649 if( pCfg->advertiseConcurrentOperation )
Sudhir Sattayappa Kohalli278eee52013-01-16 17:35:13 -08004650 {
Rashmi Ramannabd3feb72014-02-25 16:14:48 +05304651#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,4,0))
4652 if( pCfg->enableMCC )
4653 {
4654 /* Currently, supports up to two channels */
4655 wlan_hdd_iface_combination.num_different_channels = 2;
Sudhir Sattayappa Kohalli278eee52013-01-16 17:35:13 -08004656
Rashmi Ramannabd3feb72014-02-25 16:14:48 +05304657 if( !pCfg->allowMCCGODiffBI )
4658 wlan_hdd_iface_combination.beacon_int_infra_match = true;
Sudhir Sattayappa Kohalli278eee52013-01-16 17:35:13 -08004659
Rashmi Ramannabd3feb72014-02-25 16:14:48 +05304660 }
4661 wiphy->iface_combinations = &wlan_hdd_iface_combination;
4662 wiphy->n_iface_combinations = 1;
Sudhir Sattayappa Kohalli278eee52013-01-16 17:35:13 -08004663#endif
Rashmi Ramannabd3feb72014-02-25 16:14:48 +05304664 }
Sudhir Sattayappa Kohalli278eee52013-01-16 17:35:13 -08004665
Jeff Johnson295189b2012-06-20 16:38:30 -07004666 /* Before registering we need to update the ht capabilitied based
4667 * on ini values*/
4668 if( !pCfg->ShortGI20MhzEnable )
4669 {
4670 wlan_hdd_band_2_4_GHZ.ht_cap.cap &= ~IEEE80211_HT_CAP_SGI_20;
4671 wlan_hdd_band_5_GHZ.ht_cap.cap &= ~IEEE80211_HT_CAP_SGI_20;
4672 wlan_hdd_band_p2p_2_4_GHZ.ht_cap.cap &= ~IEEE80211_HT_CAP_SGI_20;
4673 }
4674
4675 if( !pCfg->ShortGI40MhzEnable )
4676 {
4677 wlan_hdd_band_5_GHZ.ht_cap.cap &= ~IEEE80211_HT_CAP_SGI_40;
4678 }
4679
4680 if( !pCfg->nChannelBondingMode5GHz )
4681 {
4682 wlan_hdd_band_5_GHZ.ht_cap.cap &= ~IEEE80211_HT_CAP_SUP_WIDTH_20_40;
4683 }
4684
Gopichand Nakkala1f7a64f2013-04-01 18:37:17 +05304685 wiphy->bands[IEEE80211_BAND_2GHZ] = &wlan_hdd_band_2_4_GHZ;
Vinay Krishna Erannafacf5e22014-02-24 13:16:25 +05304686 if (true == hdd_is_5g_supported(pHddCtx))
4687 {
4688 wiphy->bands[IEEE80211_BAND_5GHZ] = &wlan_hdd_band_5_GHZ;
4689 }
Gopichand Nakkala1f7a64f2013-04-01 18:37:17 +05304690
4691 for (i = 0; i < IEEE80211_NUM_BANDS; i++)
4692 {
4693
4694 if (NULL == wiphy->bands[i])
4695 {
4696 hddLog(VOS_TRACE_LEVEL_ERROR,"%s: wiphy->bands[i] is NULL, i = %d",
4697 __func__, i);
4698 continue;
4699 }
4700
4701 for (j = 0; j < wiphy->bands[i]->n_channels; j++)
4702 {
4703 struct ieee80211_supported_band *band = wiphy->bands[i];
4704
4705 if (IEEE80211_BAND_2GHZ == i && eCSR_BAND_5G == pCfg->nBandCapability) // 5G only
4706 {
4707 // Enable social channels for P2P
4708 if (WLAN_HDD_IS_SOCIAL_CHANNEL(band->channels[j].center_freq))
4709 band->channels[j].flags &= ~IEEE80211_CHAN_DISABLED;
4710 else
4711 band->channels[j].flags |= IEEE80211_CHAN_DISABLED;
4712 continue;
4713 }
4714 else if (IEEE80211_BAND_5GHZ == i && eCSR_BAND_24 == pCfg->nBandCapability) // 2G only
4715 {
4716 band->channels[j].flags |= IEEE80211_CHAN_DISABLED;
4717 continue;
4718 }
4719 }
Jeff Johnson295189b2012-06-20 16:38:30 -07004720 }
4721 /*Initialise the supported cipher suite details*/
4722 wiphy->cipher_suites = hdd_cipher_suites;
4723 wiphy->n_cipher_suites = ARRAY_SIZE(hdd_cipher_suites);
4724
4725 /*signal strength in mBm (100*dBm) */
4726 wiphy->signal_type = CFG80211_SIGNAL_TYPE_MBM;
4727
4728#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
Sushant Kaushik4f640e42014-07-08 12:27:09 +05304729 wiphy->max_remain_on_channel_duration = 5000;
Jeff Johnson295189b2012-06-20 16:38:30 -07004730#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07004731
Sunil Duttc69bccb2014-05-26 21:30:20 +05304732 wiphy->n_vendor_commands = ARRAY_SIZE(hdd_wiphy_vendor_commands);
4733 wiphy->vendor_commands = hdd_wiphy_vendor_commands;
Rajesh Chauhan98a31f82014-01-06 20:15:25 -08004734 wiphy->vendor_events = wlan_hdd_cfg80211_vendor_events;
4735 wiphy->n_vendor_events = ARRAY_SIZE(wlan_hdd_cfg80211_vendor_events);
4736
Madan Mohan Koyyalamudi71278262013-04-12 22:00:48 +05304737 EXIT();
4738 return 0;
4739}
4740
4741/* In this function we are registering wiphy. */
4742int wlan_hdd_cfg80211_register(struct wiphy *wiphy)
4743{
4744 ENTER();
4745 /* Register our wiphy dev with cfg80211 */
Jeff Johnson295189b2012-06-20 16:38:30 -07004746 if (0 > wiphy_register(wiphy))
4747 {
Madan Mohan Koyyalamudi71278262013-04-12 22:00:48 +05304748 /* print error */
Jeff Johnson295189b2012-06-20 16:38:30 -07004749 hddLog(VOS_TRACE_LEVEL_ERROR,"%s: wiphy register failed", __func__);
4750 return -EIO;
4751 }
4752
4753 EXIT();
4754 return 0;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304755}
Jeff Johnson295189b2012-06-20 16:38:30 -07004756
Madan Mohan Koyyalamudi71278262013-04-12 22:00:48 +05304757/* In this function we are updating channel list when,
4758 regulatory domain is FCC and country code is US.
4759 Here In FCC standard 5GHz UNII-1 Bands are indoor only.
4760 As per FCC smart phone is not a indoor device.
4761 GO should not opeate on indoor channels */
4762void wlan_hdd_cfg80211_update_reg_info(struct wiphy *wiphy)
4763{
4764 int j;
4765 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
4766 tANI_U8 defaultCountryCode[3] = SME_INVALID_COUNTRY_CODE;
4767 //Default counrtycode from NV at the time of wiphy initialization.
4768 if (eHAL_STATUS_SUCCESS != sme_GetDefaultCountryCodeFrmNv(pHddCtx->hHal,
4769 &defaultCountryCode[0]))
4770 {
Jeff Johnson0299d0a2013-10-30 12:37:43 -07004771 hddLog(LOGE, FL("Failed to get default country code from NV"));
Madan Mohan Koyyalamudi71278262013-04-12 22:00:48 +05304772 }
4773 if ((defaultCountryCode[0]== 'U') && (defaultCountryCode[1]=='S'))
4774 {
Madan Mohan Koyyalamudi71278262013-04-12 22:00:48 +05304775 if (NULL == wiphy->bands[IEEE80211_BAND_5GHZ])
4776 {
4777 hddLog(VOS_TRACE_LEVEL_ERROR,"%s: wiphy->bands[IEEE80211_BAND_5GHZ] is NULL",__func__ );
4778 return;
4779 }
4780 for (j = 0; j < wiphy->bands[IEEE80211_BAND_5GHZ]->n_channels; j++)
4781 {
4782 struct ieee80211_supported_band *band = wiphy->bands[IEEE80211_BAND_5GHZ];
4783 // Mark UNII -1 band channel as passive
4784 if (WLAN_HDD_CHANNEL_IN_UNII_1_BAND(band->channels[j].center_freq))
4785 band->channels[j].flags |= IEEE80211_CHAN_PASSIVE_SCAN;
4786 }
4787 }
4788}
4789
Agarwal Ashish8fa0e9a2014-05-23 00:40:12 +05304790/* This function registers for all frame which supplicant is interested in */
4791void wlan_hdd_cfg80211_register_frames(hdd_adapter_t* pAdapter)
Jeff Johnson295189b2012-06-20 16:38:30 -07004792{
Jeff Johnson295189b2012-06-20 16:38:30 -07004793 tHalHandle hHal = WLAN_HDD_GET_HAL_CTX(pAdapter);
4794 /* Register for all P2P action, public action etc frames */
4795 v_U16_t type = (SIR_MAC_MGMT_FRAME << 2) | ( SIR_MAC_MGMT_ACTION << 4);
4796
Jeff Johnsone7245742012-09-05 17:12:55 -07004797 ENTER();
4798
Jeff Johnson295189b2012-06-20 16:38:30 -07004799 /* Right now we are registering these frame when driver is getting
4800 initialized. Once we will move to 2.6.37 kernel, in which we have
4801 frame register ops, we will move this code as a part of that */
4802 /* GAS Initial Request */
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304803 sme_RegisterMgmtFrame(hHal, pAdapter->sessionId, type,
Jeff Johnson295189b2012-06-20 16:38:30 -07004804 (v_U8_t*)GAS_INITIAL_REQ, GAS_INITIAL_REQ_SIZE );
4805
4806 /* GAS Initial Response */
4807 sme_RegisterMgmtFrame(hHal, pAdapter->sessionId, type,
4808 (v_U8_t*)GAS_INITIAL_RSP, GAS_INITIAL_RSP_SIZE );
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304809
Jeff Johnson295189b2012-06-20 16:38:30 -07004810 /* GAS Comeback Request */
4811 sme_RegisterMgmtFrame(hHal, pAdapter->sessionId, type,
4812 (v_U8_t*)GAS_COMEBACK_REQ, GAS_COMEBACK_REQ_SIZE );
4813
4814 /* GAS Comeback Response */
4815 sme_RegisterMgmtFrame(hHal, pAdapter->sessionId, type,
4816 (v_U8_t*)GAS_COMEBACK_RSP, GAS_COMEBACK_RSP_SIZE );
4817
4818 /* P2P Public Action */
4819 sme_RegisterMgmtFrame(hHal, pAdapter->sessionId, type,
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304820 (v_U8_t*)P2P_PUBLIC_ACTION_FRAME,
Jeff Johnson295189b2012-06-20 16:38:30 -07004821 P2P_PUBLIC_ACTION_FRAME_SIZE );
4822
4823 /* P2P Action */
4824 sme_RegisterMgmtFrame(hHal, pAdapter->sessionId, type,
4825 (v_U8_t*)P2P_ACTION_FRAME,
4826 P2P_ACTION_FRAME_SIZE );
Chet Lanctot186b5732013-03-18 10:26:30 -07004827
Gopichand Nakkalae3d56e72013-04-21 23:33:32 +05304828 /* WNM BSS Transition Request frame */
4829 sme_RegisterMgmtFrame(hHal, pAdapter->sessionId, type,
4830 (v_U8_t*)WNM_BSS_ACTION_FRAME,
4831 WNM_BSS_ACTION_FRAME_SIZE );
Leela Venkata Kiran Kumar Reddy Chiralae8e62c82013-10-29 18:23:26 -07004832
4833 /* WNM-Notification */
4834 sme_RegisterMgmtFrame(hHal, pAdapter->sessionId, type,
4835 (v_U8_t*)WNM_NOTIFICATION_FRAME,
4836 WNM_NOTIFICATION_FRAME_SIZE );
Jeff Johnson295189b2012-06-20 16:38:30 -07004837}
4838
Agarwal Ashish8fa0e9a2014-05-23 00:40:12 +05304839void wlan_hdd_cfg80211_deregister_frames(hdd_adapter_t* pAdapter)
Jeff Johnson295189b2012-06-20 16:38:30 -07004840{
Jeff Johnson295189b2012-06-20 16:38:30 -07004841 tHalHandle hHal = WLAN_HDD_GET_HAL_CTX(pAdapter);
4842 /* Register for all P2P action, public action etc frames */
4843 v_U16_t type = (SIR_MAC_MGMT_FRAME << 2) | ( SIR_MAC_MGMT_ACTION << 4);
4844
Jeff Johnsone7245742012-09-05 17:12:55 -07004845 ENTER();
4846
Jeff Johnson295189b2012-06-20 16:38:30 -07004847 /* Right now we are registering these frame when driver is getting
4848 initialized. Once we will move to 2.6.37 kernel, in which we have
4849 frame register ops, we will move this code as a part of that */
4850 /* GAS Initial Request */
4851
4852 sme_DeregisterMgmtFrame(hHal, pAdapter->sessionId, type,
4853 (v_U8_t*)GAS_INITIAL_REQ, GAS_INITIAL_REQ_SIZE );
4854
4855 /* GAS Initial Response */
4856 sme_DeregisterMgmtFrame(hHal, pAdapter->sessionId, type,
4857 (v_U8_t*)GAS_INITIAL_RSP, GAS_INITIAL_RSP_SIZE );
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304858
Jeff Johnson295189b2012-06-20 16:38:30 -07004859 /* GAS Comeback Request */
4860 sme_DeregisterMgmtFrame(hHal, pAdapter->sessionId, type,
4861 (v_U8_t*)GAS_COMEBACK_REQ, GAS_COMEBACK_REQ_SIZE );
4862
4863 /* GAS Comeback Response */
4864 sme_DeregisterMgmtFrame(hHal, pAdapter->sessionId, type,
4865 (v_U8_t*)GAS_COMEBACK_RSP, GAS_COMEBACK_RSP_SIZE );
4866
4867 /* P2P Public Action */
4868 sme_DeregisterMgmtFrame(hHal, pAdapter->sessionId, type,
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304869 (v_U8_t*)P2P_PUBLIC_ACTION_FRAME,
Jeff Johnson295189b2012-06-20 16:38:30 -07004870 P2P_PUBLIC_ACTION_FRAME_SIZE );
4871
4872 /* P2P Action */
4873 sme_DeregisterMgmtFrame(hHal, pAdapter->sessionId, type,
4874 (v_U8_t*)P2P_ACTION_FRAME,
4875 P2P_ACTION_FRAME_SIZE );
Leela Venkata Kiran Kumar Reddy Chiralae8e62c82013-10-29 18:23:26 -07004876 /* WNM-Notification */
4877 sme_DeregisterMgmtFrame(hHal, pAdapter->sessionId, type,
4878 (v_U8_t*)WNM_NOTIFICATION_FRAME,
4879 WNM_NOTIFICATION_FRAME_SIZE );
Jeff Johnson295189b2012-06-20 16:38:30 -07004880}
4881
4882#ifdef FEATURE_WLAN_WAPI
4883void wlan_hdd_cfg80211_set_key_wapi(hdd_adapter_t* pAdapter, u8 key_index,
4884 const u8 *mac_addr, u8 *key , int key_Len)
4885{
4886 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
4887 tCsrRoamSetKey setKey;
4888 v_BOOL_t isConnected = TRUE;
4889 int status = 0;
4890 v_U32_t roamId= 0xFF;
4891 tANI_U8 *pKeyPtr = NULL;
4892 int n = 0;
4893
Sushant Kaushik8bc7df22014-04-09 17:55:29 +05304894 hddLog(VOS_TRACE_LEVEL_INFO, "%s: device_mode = %s(%d)",
4895 __func__, hdd_device_modetoString(pAdapter->device_mode),
4896 pAdapter->device_mode);
Jeff Johnson295189b2012-06-20 16:38:30 -07004897
Gopichand Nakkalae7480202013-02-11 15:24:22 +05304898 vos_mem_zero(&setKey, sizeof(tCsrRoamSetKey));
Jeff Johnson295189b2012-06-20 16:38:30 -07004899 setKey.keyId = key_index; // Store Key ID
4900 setKey.encType = eCSR_ENCRYPT_TYPE_WPI; // SET WAPI Encryption
4901 setKey.keyDirection = eSIR_TX_RX; // Key Directionn both TX and RX
4902 setKey.paeRole = 0 ; // the PAE role
4903 if (!mac_addr || is_broadcast_ether_addr(mac_addr))
4904 {
4905 vos_set_macaddr_broadcast( (v_MACADDR_t *)setKey.peerMac );
4906 }
4907 else
4908 {
4909 isConnected = hdd_connIsConnected(pHddStaCtx);
4910 vos_mem_copy(setKey.peerMac,&pHddStaCtx->conn_info.bssId,WNI_CFG_BSSID_LEN);
4911 }
4912 setKey.keyLength = key_Len;
4913 pKeyPtr = setKey.Key;
4914 memcpy( pKeyPtr, key, key_Len);
4915
Arif Hussain6d2a3322013-11-17 19:50:10 -08004916 hddLog(VOS_TRACE_LEVEL_INFO,"%s: WAPI KEY LENGTH:0x%04x",
Jeff Johnson295189b2012-06-20 16:38:30 -07004917 __func__, key_Len);
4918 for (n = 0 ; n < key_Len; n++)
4919 hddLog(VOS_TRACE_LEVEL_INFO, "%s WAPI KEY Data[%d]:%02x ",
4920 __func__,n,setKey.Key[n]);
4921
4922 pHddStaCtx->roam_info.roamingState = HDD_ROAM_STATE_SETTING_KEY;
4923 if ( isConnected )
4924 {
4925 status= sme_RoamSetKey( WLAN_HDD_GET_HAL_CTX(pAdapter),
4926 pAdapter->sessionId, &setKey, &roamId );
4927 }
4928 if ( status != 0 )
4929 {
4930 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
4931 "[%4d] sme_RoamSetKey returned ERROR status= %d",
4932 __LINE__, status );
4933 pHddStaCtx->roam_info.roamingState = HDD_ROAM_STATE_NONE;
4934 }
4935}
4936#endif /* FEATURE_WLAN_WAPI*/
4937
4938#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,4,0))
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304939int wlan_hdd_cfg80211_alloc_new_beacon(hdd_adapter_t *pAdapter,
Jeff Johnson295189b2012-06-20 16:38:30 -07004940 beacon_data_t **ppBeacon,
4941 struct beacon_parameters *params)
Jeff Johnson04dd8a82012-06-29 20:41:40 -07004942#else
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304943int wlan_hdd_cfg80211_alloc_new_beacon(hdd_adapter_t *pAdapter,
Jeff Johnson04dd8a82012-06-29 20:41:40 -07004944 beacon_data_t **ppBeacon,
4945 struct cfg80211_beacon_data *params,
4946 int dtim_period)
4947#endif
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304948{
Jeff Johnson295189b2012-06-20 16:38:30 -07004949 int size;
4950 beacon_data_t *beacon = NULL;
4951 beacon_data_t *old = NULL;
4952 int head_len,tail_len;
4953
Jeff Johnsone7245742012-09-05 17:12:55 -07004954 ENTER();
Jeff Johnson295189b2012-06-20 16:38:30 -07004955 if (params->head && !params->head_len)
c_hpothu6ff1c3c2013-10-01 19:01:57 +05304956 {
4957 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
4958 FL("head_len is NULL"));
Jeff Johnson295189b2012-06-20 16:38:30 -07004959 return -EINVAL;
c_hpothu6ff1c3c2013-10-01 19:01:57 +05304960 }
Jeff Johnson295189b2012-06-20 16:38:30 -07004961
4962 old = pAdapter->sessionCtx.ap.beacon;
4963
4964 if (!params->head && !old)
c_hpothu6ff1c3c2013-10-01 19:01:57 +05304965 {
4966 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
4967 FL("session(%d) old and new heads points to NULL"),
4968 pAdapter->sessionId);
Jeff Johnson295189b2012-06-20 16:38:30 -07004969 return -EINVAL;
c_hpothu6ff1c3c2013-10-01 19:01:57 +05304970 }
4971
4972 if (params->tail && !params->tail_len)
4973 {
4974 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
4975 FL("tail_len is zero but tail is not NULL"));
4976 return -EINVAL;
4977 }
Jeff Johnson295189b2012-06-20 16:38:30 -07004978
Jeff Johnson295189b2012-06-20 16:38:30 -07004979#if (LINUX_VERSION_CODE <= KERNEL_VERSION(2,6,38))
4980 /* Kernel 3.0 is not updating dtim_period for set beacon */
4981 if (!params->dtim_period)
c_hpothu6ff1c3c2013-10-01 19:01:57 +05304982 {
4983 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
4984 FL("dtim period is 0"));
Jeff Johnson295189b2012-06-20 16:38:30 -07004985 return -EINVAL;
c_hpothu6ff1c3c2013-10-01 19:01:57 +05304986 }
Jeff Johnson295189b2012-06-20 16:38:30 -07004987#endif
4988
4989 if(params->head)
4990 head_len = params->head_len;
4991 else
4992 head_len = old->head_len;
4993
4994 if(params->tail || !old)
4995 tail_len = params->tail_len;
4996 else
4997 tail_len = old->tail_len;
4998
4999 size = sizeof(beacon_data_t) + head_len + tail_len;
5000
5001 beacon = kzalloc(size, GFP_KERNEL);
5002
5003 if( beacon == NULL )
c_hpothu6ff1c3c2013-10-01 19:01:57 +05305004 {
5005 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
5006 FL("Mem allocation for beacon failed"));
Jeff Johnson295189b2012-06-20 16:38:30 -07005007 return -ENOMEM;
c_hpothu6ff1c3c2013-10-01 19:01:57 +05305008 }
Jeff Johnson295189b2012-06-20 16:38:30 -07005009
Jeff Johnson04dd8a82012-06-29 20:41:40 -07005010#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,4,0))
Jeff Johnson295189b2012-06-20 16:38:30 -07005011 if(params->dtim_period || !old )
5012 beacon->dtim_period = params->dtim_period;
5013 else
5014 beacon->dtim_period = old->dtim_period;
Jeff Johnson04dd8a82012-06-29 20:41:40 -07005015#else
5016 if(dtim_period || !old )
5017 beacon->dtim_period = dtim_period;
5018 else
5019 beacon->dtim_period = old->dtim_period;
5020#endif
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305021
Jeff Johnson295189b2012-06-20 16:38:30 -07005022 beacon->head = ((u8 *) beacon) + sizeof(beacon_data_t);
5023 beacon->tail = beacon->head + head_len;
5024 beacon->head_len = head_len;
5025 beacon->tail_len = tail_len;
5026
5027 if(params->head) {
5028 memcpy (beacon->head,params->head,beacon->head_len);
5029 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305030 else {
Jeff Johnson295189b2012-06-20 16:38:30 -07005031 if(old)
5032 memcpy (beacon->head,old->head,beacon->head_len);
5033 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305034
Jeff Johnson295189b2012-06-20 16:38:30 -07005035 if(params->tail) {
5036 memcpy (beacon->tail,params->tail,beacon->tail_len);
5037 }
5038 else {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305039 if(old)
Jeff Johnson295189b2012-06-20 16:38:30 -07005040 memcpy (beacon->tail,old->tail,beacon->tail_len);
5041 }
5042
5043 *ppBeacon = beacon;
5044
5045 kfree(old);
5046
5047 return 0;
5048
5049}
Jeff Johnson295189b2012-06-20 16:38:30 -07005050
5051v_U8_t* wlan_hdd_cfg80211_get_ie_ptr(v_U8_t *pIes, int length, v_U8_t eid)
5052{
5053 int left = length;
5054 v_U8_t *ptr = pIes;
5055 v_U8_t elem_id,elem_len;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305056
Jeff Johnson295189b2012-06-20 16:38:30 -07005057 while(left >= 2)
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305058 {
Jeff Johnson295189b2012-06-20 16:38:30 -07005059 elem_id = ptr[0];
5060 elem_len = ptr[1];
5061 left -= 2;
5062 if(elem_len > left)
5063 {
5064 hddLog(VOS_TRACE_LEVEL_FATAL,
Madan Mohan Koyyalamudi8bdd3112012-09-24 13:55:14 -07005065 FL("****Invalid IEs eid = %d elem_len=%d left=%d*****"),
Jeff Johnson295189b2012-06-20 16:38:30 -07005066 eid,elem_len,left);
5067 return NULL;
5068 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305069 if (elem_id == eid)
Jeff Johnson295189b2012-06-20 16:38:30 -07005070 {
5071 return ptr;
5072 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305073
Jeff Johnson295189b2012-06-20 16:38:30 -07005074 left -= elem_len;
5075 ptr += (elem_len + 2);
5076 }
5077 return NULL;
5078}
5079
Jeff Johnson295189b2012-06-20 16:38:30 -07005080/* Check if rate is 11g rate or not */
5081static int wlan_hdd_rate_is_11g(u8 rate)
5082{
Sanjay Devnani28322e22013-06-21 16:13:40 -07005083 static const u8 gRateArray[8] = {12, 18, 24, 36, 48, 72, 96, 108}; /* actual rate * 2 */
Jeff Johnson295189b2012-06-20 16:38:30 -07005084 u8 i;
5085 for (i = 0; i < 8; i++)
5086 {
5087 if(rate == gRateArray[i])
5088 return TRUE;
5089 }
5090 return FALSE;
5091}
5092
5093/* Check for 11g rate and set proper 11g only mode */
5094static void wlan_hdd_check_11gmode(u8 *pIe, u8* require_ht,
5095 u8* pCheckRatesfor11g, eSapPhyMode* pSapHw_mode)
5096{
5097 u8 i, num_rates = pIe[0];
5098
5099 pIe += 1;
5100 for ( i = 0; i < num_rates; i++)
5101 {
5102 if( *pCheckRatesfor11g && (TRUE == wlan_hdd_rate_is_11g(pIe[i] & RATE_MASK)))
5103 {
5104 /* If rate set have 11g rate than change the mode to 11G */
5105 *pSapHw_mode = eSAP_DOT11_MODE_11g;
5106 if (pIe[i] & BASIC_RATE_MASK)
5107 {
5108 /* If we have 11g rate as basic rate, it means mode
5109 is 11g only mode.
5110 */
5111 *pSapHw_mode = eSAP_DOT11_MODE_11g_ONLY;
5112 *pCheckRatesfor11g = FALSE;
5113 }
5114 }
5115 else if((BASIC_RATE_MASK | WLAN_BSS_MEMBERSHIP_SELECTOR_HT_PHY) == pIe[i])
5116 {
5117 *require_ht = TRUE;
5118 }
5119 }
5120 return;
5121}
5122
5123static void wlan_hdd_set_sapHwmode(hdd_adapter_t *pHostapdAdapter)
5124{
5125 tsap_Config_t *pConfig = &pHostapdAdapter->sessionCtx.ap.sapConfig;
5126 beacon_data_t *pBeacon = pHostapdAdapter->sessionCtx.ap.beacon;
5127 struct ieee80211_mgmt *pMgmt_frame = (struct ieee80211_mgmt*)pBeacon->head;
5128 u8 checkRatesfor11g = TRUE;
5129 u8 require_ht = FALSE;
5130 u8 *pIe=NULL;
5131
5132 pConfig->SapHw_mode= eSAP_DOT11_MODE_11b;
5133
5134 pIe = wlan_hdd_cfg80211_get_ie_ptr(&pMgmt_frame->u.beacon.variable[0],
5135 pBeacon->head_len, WLAN_EID_SUPP_RATES);
5136 if (pIe != NULL)
5137 {
5138 pIe += 1;
5139 wlan_hdd_check_11gmode(pIe, &require_ht, &checkRatesfor11g,
5140 &pConfig->SapHw_mode);
5141 }
5142
5143 pIe = wlan_hdd_cfg80211_get_ie_ptr(pBeacon->tail, pBeacon->tail_len,
5144 WLAN_EID_EXT_SUPP_RATES);
5145 if (pIe != NULL)
5146 {
5147
5148 pIe += 1;
5149 wlan_hdd_check_11gmode(pIe, &require_ht, &checkRatesfor11g,
5150 &pConfig->SapHw_mode);
5151 }
5152
5153 if( pConfig->channel > 14 )
5154 {
5155 pConfig->SapHw_mode= eSAP_DOT11_MODE_11a;
5156 }
5157
5158 pIe = wlan_hdd_cfg80211_get_ie_ptr(pBeacon->tail, pBeacon->tail_len,
5159 WLAN_EID_HT_CAPABILITY);
5160
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305161 if(pIe)
Jeff Johnson295189b2012-06-20 16:38:30 -07005162 {
5163 pConfig->SapHw_mode= eSAP_DOT11_MODE_11n;
5164 if(require_ht)
5165 pConfig->SapHw_mode= eSAP_DOT11_MODE_11n_ONLY;
5166 }
5167}
5168
Gopichand Nakkala2b25f4e2013-03-21 19:14:07 +05305169static int wlan_hdd_add_ie(hdd_adapter_t* pHostapdAdapter, v_U8_t *genie,
5170 v_U8_t *total_ielen, v_U8_t *oui, v_U8_t oui_size)
5171{
Arif Hussaine7f3ea52013-09-12 21:56:36 -07005172 v_U16_t ielen = 0;
Gopichand Nakkala2b25f4e2013-03-21 19:14:07 +05305173 v_U8_t *pIe = NULL;
5174 beacon_data_t *pBeacon = pHostapdAdapter->sessionCtx.ap.beacon;
5175
5176 pIe = wlan_hdd_get_vendor_oui_ie_ptr(oui, oui_size,
5177 pBeacon->tail, pBeacon->tail_len);
5178
5179 if (pIe)
5180 {
5181 ielen = pIe[1] + 2;
5182 if ((*total_ielen + ielen) <= MAX_GENIE_LEN)
5183 {
5184 vos_mem_copy(&genie[*total_ielen], pIe, ielen);
5185 }
5186 else
5187 {
5188 hddLog( VOS_TRACE_LEVEL_ERROR, "**Ie Length is too big***");
5189 return -EINVAL;
5190 }
5191 *total_ielen += ielen;
5192 }
5193 return 0;
5194}
5195
Arif Hussaine7f3ea52013-09-12 21:56:36 -07005196static void wlan_hdd_add_hostapd_conf_vsie(hdd_adapter_t* pHostapdAdapter,
5197 v_U8_t *genie, v_U8_t *total_ielen)
5198{
5199 beacon_data_t *pBeacon = pHostapdAdapter->sessionCtx.ap.beacon;
5200 int left = pBeacon->tail_len;
5201 v_U8_t *ptr = pBeacon->tail;
5202 v_U8_t elem_id, elem_len;
5203 v_U16_t ielen = 0;
5204
5205 if ( NULL == ptr || 0 == left )
5206 return;
5207
5208 while (left >= 2)
5209 {
5210 elem_id = ptr[0];
5211 elem_len = ptr[1];
5212 left -= 2;
5213 if (elem_len > left)
5214 {
5215 hddLog( VOS_TRACE_LEVEL_ERROR,
5216 "****Invalid IEs eid = %d elem_len=%d left=%d*****",
5217 elem_id, elem_len, left);
5218 return;
5219 }
5220 if (IE_EID_VENDOR == elem_id)
5221 {
5222 /* skipping the VSIE's which we don't want to include or
5223 * it will be included by existing code
5224 */
5225 if ((memcmp( &ptr[2], WPS_OUI_TYPE, WPS_OUI_TYPE_SIZE) != 0 ) &&
5226#ifdef WLAN_FEATURE_WFD
5227 (memcmp( &ptr[2], WFD_OUI_TYPE, WFD_OUI_TYPE_SIZE) != 0) &&
5228#endif
5229 (memcmp( &ptr[2], WHITELIST_OUI_TYPE, WPA_OUI_TYPE_SIZE) != 0) &&
5230 (memcmp( &ptr[2], BLACKLIST_OUI_TYPE, WPA_OUI_TYPE_SIZE) != 0) &&
5231 (memcmp( &ptr[2], "\x00\x50\xf2\x02", WPA_OUI_TYPE_SIZE) != 0) &&
5232 (memcmp( &ptr[2], WPA_OUI_TYPE, WPA_OUI_TYPE_SIZE) != 0) &&
5233 (memcmp( &ptr[2], P2P_OUI_TYPE, P2P_OUI_TYPE_SIZE) != 0))
5234 {
5235 ielen = ptr[1] + 2;
5236 if ((*total_ielen + ielen) <= MAX_GENIE_LEN)
5237 {
5238 vos_mem_copy(&genie[*total_ielen], ptr, ielen);
5239 *total_ielen += ielen;
5240 }
5241 else
5242 {
5243 hddLog( VOS_TRACE_LEVEL_ERROR,
5244 "IE Length is too big "
5245 "IEs eid=%d elem_len=%d total_ie_lent=%d",
5246 elem_id, elem_len, *total_ielen);
5247 }
5248 }
5249 }
5250
5251 left -= elem_len;
5252 ptr += (elem_len + 2);
5253 }
5254 return;
5255}
5256
Jeff Johnson04dd8a82012-06-29 20:41:40 -07005257#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,4,0))
Jeff Johnson295189b2012-06-20 16:38:30 -07005258static int wlan_hdd_cfg80211_update_apies(hdd_adapter_t* pHostapdAdapter,
5259 struct beacon_parameters *params)
Jeff Johnson04dd8a82012-06-29 20:41:40 -07005260#else
5261static int wlan_hdd_cfg80211_update_apies(hdd_adapter_t* pHostapdAdapter,
5262 struct cfg80211_beacon_data *params)
5263#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07005264{
5265 v_U8_t *genie;
Gopichand Nakkala2b25f4e2013-03-21 19:14:07 +05305266 v_U8_t total_ielen = 0;
Jeff Johnson295189b2012-06-20 16:38:30 -07005267 v_U8_t addIE[1] = {0};
Jeff Johnsone7245742012-09-05 17:12:55 -07005268 int ret = 0;
Jeff Johnson295189b2012-06-20 16:38:30 -07005269
5270 genie = vos_mem_malloc(MAX_GENIE_LEN);
5271
5272 if(genie == NULL) {
5273
5274 return -ENOMEM;
5275 }
5276
Gopichand Nakkala2b25f4e2013-03-21 19:14:07 +05305277 if (0 != wlan_hdd_add_ie(pHostapdAdapter, genie,
5278 &total_ielen, WPS_OUI_TYPE, WPS_OUI_TYPE_SIZE))
Jeff Johnson295189b2012-06-20 16:38:30 -07005279 {
c_hpothu6ff1c3c2013-10-01 19:01:57 +05305280 hddLog(LOGE,
5281 FL("Adding WPS IE failed"));
Gopichand Nakkala2b25f4e2013-03-21 19:14:07 +05305282 ret = -EINVAL;
5283 goto done;
Jeff Johnson295189b2012-06-20 16:38:30 -07005284 }
5285
5286#ifdef WLAN_FEATURE_WFD
Gopichand Nakkala2b25f4e2013-03-21 19:14:07 +05305287 if (0 != wlan_hdd_add_ie(pHostapdAdapter, genie,
5288 &total_ielen, WFD_OUI_TYPE, WFD_OUI_TYPE_SIZE))
5289 {
c_hpothu6ff1c3c2013-10-01 19:01:57 +05305290 hddLog(LOGE,
5291 FL("Adding WFD IE failed"));
Gopichand Nakkala2b25f4e2013-03-21 19:14:07 +05305292 ret = -EINVAL;
5293 goto done;
Jeff Johnson295189b2012-06-20 16:38:30 -07005294 }
5295#endif
5296
Gopichand Nakkala2b25f4e2013-03-21 19:14:07 +05305297 if (0 != wlan_hdd_add_ie(pHostapdAdapter, genie,
5298 &total_ielen, P2P_OUI_TYPE, P2P_OUI_TYPE_SIZE))
Jeff Johnson295189b2012-06-20 16:38:30 -07005299 {
c_hpothu6ff1c3c2013-10-01 19:01:57 +05305300 hddLog(LOGE,
5301 FL("Adding P2P IE failed"));
Gopichand Nakkala2b25f4e2013-03-21 19:14:07 +05305302 ret = -EINVAL;
5303 goto done;
5304 }
5305
5306 if (WLAN_HDD_SOFTAP == pHostapdAdapter->device_mode)
5307 {
Arif Hussaine7f3ea52013-09-12 21:56:36 -07005308 wlan_hdd_add_hostapd_conf_vsie(pHostapdAdapter, genie, &total_ielen);
Jeff Johnson295189b2012-06-20 16:38:30 -07005309 }
Jeff Johnson295189b2012-06-20 16:38:30 -07005310
5311 if (ccmCfgSetStr((WLAN_HDD_GET_CTX(pHostapdAdapter))->hHal,
5312 WNI_CFG_PROBE_RSP_BCN_ADDNIE_DATA, genie, total_ielen, NULL,
5313 eANI_BOOLEAN_FALSE)==eHAL_STATUS_FAILURE)
5314 {
5315 hddLog(LOGE,
5316 "Could not pass on WNI_CFG_PROBE_RSP_BCN_ADDNIE_DATA to CCM");
Jeff Johnsone7245742012-09-05 17:12:55 -07005317 ret = -EINVAL;
5318 goto done;
Jeff Johnson295189b2012-06-20 16:38:30 -07005319 }
5320
5321 if (ccmCfgSetInt((WLAN_HDD_GET_CTX(pHostapdAdapter))->hHal,
5322 WNI_CFG_PROBE_RSP_BCN_ADDNIE_FLAG, 1,NULL,
5323 test_bit(SOFTAP_BSS_STARTED, &pHostapdAdapter->event_flags) ?
5324 eANI_BOOLEAN_TRUE : eANI_BOOLEAN_FALSE)
5325 ==eHAL_STATUS_FAILURE)
5326 {
5327 hddLog(LOGE,
5328 "Could not pass on WNI_CFG_PROBE_RSP_BCN_ADDNIE_FLAG to CCM");
Jeff Johnsone7245742012-09-05 17:12:55 -07005329 ret = -EINVAL;
5330 goto done;
Jeff Johnson295189b2012-06-20 16:38:30 -07005331 }
5332
5333 // Added for ProResp IE
5334 if ( (params->proberesp_ies != NULL) && (params->proberesp_ies_len != 0) )
5335 {
5336 u16 rem_probe_resp_ie_len = params->proberesp_ies_len;
5337 u8 probe_rsp_ie_len[3] = {0};
5338 u8 counter = 0;
5339 /* Check Probe Resp Length if it is greater then 255 then Store
5340 Probe Resp IEs into WNI_CFG_PROBE_RSP_ADDNIE_DATA1 &
5341 WNI_CFG_PROBE_RSP_ADDNIE_DATA2 CFG Variable As We are not able
5342 Store More then 255 bytes into One Variable.
5343 */
5344 while ((rem_probe_resp_ie_len > 0) && (counter < 3))
5345 {
5346 if (rem_probe_resp_ie_len > MAX_CFG_STRING_LEN)
5347 {
5348 probe_rsp_ie_len[counter++] = MAX_CFG_STRING_LEN;
5349 rem_probe_resp_ie_len -= MAX_CFG_STRING_LEN;
5350 }
5351 else
5352 {
5353 probe_rsp_ie_len[counter++] = rem_probe_resp_ie_len;
5354 rem_probe_resp_ie_len = 0;
5355 }
5356 }
5357
5358 rem_probe_resp_ie_len = 0;
5359
5360 if (probe_rsp_ie_len[0] > 0)
5361 {
5362 if (ccmCfgSetStr((WLAN_HDD_GET_CTX(pHostapdAdapter))->hHal,
5363 WNI_CFG_PROBE_RSP_ADDNIE_DATA1,
5364 (tANI_U8*)&params->proberesp_ies[rem_probe_resp_ie_len],
5365 probe_rsp_ie_len[0], NULL,
5366 eANI_BOOLEAN_FALSE) == eHAL_STATUS_FAILURE)
5367 {
5368 hddLog(LOGE,
5369 "Could not pass on WNI_CFG_PROBE_RSP_ADDNIE_DATA1 to CCM");
Jeff Johnsone7245742012-09-05 17:12:55 -07005370 ret = -EINVAL;
5371 goto done;
Jeff Johnson295189b2012-06-20 16:38:30 -07005372 }
5373 rem_probe_resp_ie_len += probe_rsp_ie_len[0];
5374 }
5375
5376 if (probe_rsp_ie_len[1] > 0)
5377 {
5378 if (ccmCfgSetStr((WLAN_HDD_GET_CTX(pHostapdAdapter))->hHal,
5379 WNI_CFG_PROBE_RSP_ADDNIE_DATA2,
5380 (tANI_U8*)&params->proberesp_ies[rem_probe_resp_ie_len],
5381 probe_rsp_ie_len[1], NULL,
5382 eANI_BOOLEAN_FALSE) == eHAL_STATUS_FAILURE)
5383 {
5384 hddLog(LOGE,
5385 "Could not pass on WNI_CFG_PROBE_RSP_ADDNIE_DATA2 to CCM");
Jeff Johnsone7245742012-09-05 17:12:55 -07005386 ret = -EINVAL;
5387 goto done;
Jeff Johnson295189b2012-06-20 16:38:30 -07005388 }
5389 rem_probe_resp_ie_len += probe_rsp_ie_len[1];
5390 }
5391
5392 if (probe_rsp_ie_len[2] > 0)
5393 {
5394 if (ccmCfgSetStr((WLAN_HDD_GET_CTX(pHostapdAdapter))->hHal,
5395 WNI_CFG_PROBE_RSP_ADDNIE_DATA3,
5396 (tANI_U8*)&params->proberesp_ies[rem_probe_resp_ie_len],
5397 probe_rsp_ie_len[2], NULL,
5398 eANI_BOOLEAN_FALSE) == eHAL_STATUS_FAILURE)
5399 {
5400 hddLog(LOGE,
5401 "Could not pass on WNI_CFG_PROBE_RSP_ADDNIE_DATA3 to CCM");
Jeff Johnsone7245742012-09-05 17:12:55 -07005402 ret = -EINVAL;
5403 goto done;
Jeff Johnson295189b2012-06-20 16:38:30 -07005404 }
5405 rem_probe_resp_ie_len += probe_rsp_ie_len[2];
5406 }
5407
5408 if (probe_rsp_ie_len[1] == 0 )
5409 {
5410 if ( eHAL_STATUS_FAILURE == ccmCfgSetStr((WLAN_HDD_GET_CTX(pHostapdAdapter))->hHal,
5411 WNI_CFG_PROBE_RSP_ADDNIE_DATA2, (tANI_U8*)addIE, 0, NULL,
5412 eANI_BOOLEAN_FALSE) )
5413 {
5414 hddLog(LOGE,
Arif Hussain6d2a3322013-11-17 19:50:10 -08005415 "Could not pass on WNI_CFG_PROBE_RSP_ADDNIE_DATA2 to CCM");
Jeff Johnson295189b2012-06-20 16:38:30 -07005416 }
5417 }
5418
5419 if (probe_rsp_ie_len[2] == 0 )
5420 {
5421 if ( eHAL_STATUS_FAILURE == ccmCfgSetStr((WLAN_HDD_GET_CTX(pHostapdAdapter))->hHal,
5422 WNI_CFG_PROBE_RSP_ADDNIE_DATA3, (tANI_U8*)addIE, 0, NULL,
5423 eANI_BOOLEAN_FALSE) )
5424 {
5425 hddLog(LOGE,
Arif Hussain6d2a3322013-11-17 19:50:10 -08005426 "Could not pass on WNI_CFG_PROBE_RSP_ADDNIE_DATA3 to CCM");
Jeff Johnson295189b2012-06-20 16:38:30 -07005427 }
5428 }
5429
5430 if (ccmCfgSetInt((WLAN_HDD_GET_CTX(pHostapdAdapter))->hHal,
5431 WNI_CFG_PROBE_RSP_ADDNIE_FLAG, 1,NULL,
5432 test_bit(SOFTAP_BSS_STARTED, &pHostapdAdapter->event_flags) ?
5433 eANI_BOOLEAN_TRUE : eANI_BOOLEAN_FALSE)
5434 == eHAL_STATUS_FAILURE)
5435 {
5436 hddLog(LOGE,
5437 "Could not pass on WNI_CFG_PROBE_RSP_ADDNIE_FLAG to CCM");
Jeff Johnsone7245742012-09-05 17:12:55 -07005438 ret = -EINVAL;
5439 goto done;
Jeff Johnson295189b2012-06-20 16:38:30 -07005440 }
5441 }
5442 else
5443 {
5444 // Reset WNI_CFG_PROBE_RSP Flags
5445 wlan_hdd_reset_prob_rspies(pHostapdAdapter);
5446
5447 hddLog(VOS_TRACE_LEVEL_INFO,
5448 "%s: No Probe Response IE received in set beacon",
5449 __func__);
5450 }
5451
5452 // Added for AssocResp IE
5453 if ( (params->assocresp_ies != NULL) && (params->assocresp_ies_len != 0) )
5454 {
5455 if (ccmCfgSetStr((WLAN_HDD_GET_CTX(pHostapdAdapter))->hHal,
5456 WNI_CFG_ASSOC_RSP_ADDNIE_DATA, (tANI_U8*)params->assocresp_ies,
5457 params->assocresp_ies_len, NULL,
5458 eANI_BOOLEAN_FALSE) == eHAL_STATUS_FAILURE)
5459 {
5460 hddLog(LOGE,
5461 "Could not pass on WNI_CFG_ASSOC_RSP_ADDNIE_DATA to CCM");
Jeff Johnsone7245742012-09-05 17:12:55 -07005462 ret = -EINVAL;
5463 goto done;
Jeff Johnson295189b2012-06-20 16:38:30 -07005464 }
5465
5466 if (ccmCfgSetInt((WLAN_HDD_GET_CTX(pHostapdAdapter))->hHal,
5467 WNI_CFG_ASSOC_RSP_ADDNIE_FLAG, 1, NULL,
5468 test_bit(SOFTAP_BSS_STARTED, &pHostapdAdapter->event_flags) ?
5469 eANI_BOOLEAN_TRUE : eANI_BOOLEAN_FALSE)
5470 == eHAL_STATUS_FAILURE)
5471 {
5472 hddLog(LOGE,
5473 "Could not pass on WNI_CFG_ASSOC_RSP_ADDNIE_FLAG to CCM");
Jeff Johnsone7245742012-09-05 17:12:55 -07005474 ret = -EINVAL;
5475 goto done;
Jeff Johnson295189b2012-06-20 16:38:30 -07005476 }
5477 }
5478 else
5479 {
5480 hddLog(VOS_TRACE_LEVEL_INFO,
5481 "%s: No Assoc Response IE received in set beacon",
5482 __func__);
5483
5484 if ( eHAL_STATUS_FAILURE == ccmCfgSetInt((WLAN_HDD_GET_CTX(pHostapdAdapter))->hHal,
5485 WNI_CFG_ASSOC_RSP_ADDNIE_FLAG, 0, NULL,
5486 eANI_BOOLEAN_FALSE) )
5487 {
5488 hddLog(LOGE,
Arif Hussain6d2a3322013-11-17 19:50:10 -08005489 "Could not pass on WNI_CFG_ASSOC_RSP_ADDNIE_FLAG to CCM");
Jeff Johnson295189b2012-06-20 16:38:30 -07005490 }
5491 }
5492
Jeff Johnsone7245742012-09-05 17:12:55 -07005493done:
Jeff Johnson295189b2012-06-20 16:38:30 -07005494 vos_mem_free(genie);
Gopichand Nakkala2b25f4e2013-03-21 19:14:07 +05305495 return ret;
Jeff Johnson295189b2012-06-20 16:38:30 -07005496}
Jeff Johnson295189b2012-06-20 16:38:30 -07005497
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305498/*
Jeff Johnson295189b2012-06-20 16:38:30 -07005499 * FUNCTION: wlan_hdd_validate_operation_channel
5500 * called by wlan_hdd_cfg80211_start_bss() and
5501 * wlan_hdd_cfg80211_set_channel()
5502 * This function validates whether given channel is part of valid
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305503 * channel list.
5504 */
Varun Reddy Yeturu920df212013-05-22 08:07:23 -07005505VOS_STATUS wlan_hdd_validate_operation_channel(hdd_adapter_t *pAdapter,int channel)
Jeff Johnson295189b2012-06-20 16:38:30 -07005506{
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305507
Jeff Johnson295189b2012-06-20 16:38:30 -07005508 v_U32_t num_ch = 0;
5509 u8 valid_ch[WNI_CFG_VALID_CHANNEL_LIST_LEN];
5510 u32 indx = 0;
5511 tHalHandle hHal = WLAN_HDD_GET_HAL_CTX(pAdapter);
Madan Mohan Koyylamudi64267f72013-02-05 14:07:08 +05305512 v_U8_t fValidChannel = FALSE, count = 0;
5513 hdd_config_t *hdd_pConfig_ini= (WLAN_HDD_GET_CTX(pAdapter))->cfg_ini;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305514
Jeff Johnson295189b2012-06-20 16:38:30 -07005515 num_ch = WNI_CFG_VALID_CHANNEL_LIST_LEN;
5516
Madan Mohan Koyylamudi64267f72013-02-05 14:07:08 +05305517 if ( hdd_pConfig_ini->sapAllowAllChannel)
Jeff Johnson295189b2012-06-20 16:38:30 -07005518 {
Madan Mohan Koyylamudi64267f72013-02-05 14:07:08 +05305519 /* Validate the channel */
5520 for (count = RF_CHAN_1 ; count <= RF_CHAN_165 ; count++)
Jeff Johnson295189b2012-06-20 16:38:30 -07005521 {
Madan Mohan Koyylamudi64267f72013-02-05 14:07:08 +05305522 if ( channel == rfChannels[count].channelNum )
5523 {
5524 fValidChannel = TRUE;
5525 break;
5526 }
5527 }
5528 if (fValidChannel != TRUE)
5529 {
5530 hddLog(VOS_TRACE_LEVEL_ERROR,
5531 "%s: Invalid Channel [%d]", __func__, channel);
5532 return VOS_STATUS_E_FAILURE;
Jeff Johnson295189b2012-06-20 16:38:30 -07005533 }
5534 }
Madan Mohan Koyylamudi64267f72013-02-05 14:07:08 +05305535 else
Jeff Johnson295189b2012-06-20 16:38:30 -07005536 {
Madan Mohan Koyylamudi64267f72013-02-05 14:07:08 +05305537 if (0 != ccmCfgGetStr(hHal, WNI_CFG_VALID_CHANNEL_LIST,
5538 valid_ch, &num_ch))
5539 {
5540 hddLog(VOS_TRACE_LEVEL_ERROR,
5541 "%s: failed to get valid channel list", __func__);
5542 return VOS_STATUS_E_FAILURE;
5543 }
5544 for (indx = 0; indx < num_ch; indx++)
5545 {
5546 if (channel == valid_ch[indx])
5547 {
5548 break;
5549 }
5550 }
5551
Rashmi Ramanna3b59e122014-04-10 14:45:13 +05305552 if (indx >= num_ch)
5553 {
5554 if (WLAN_HDD_P2P_GO == pAdapter->device_mode)
5555 {
5556 eCsrBand band;
5557 unsigned int freq;
5558
5559 sme_GetFreqBand(hHal, &band);
5560
5561 if (eCSR_BAND_5G == band)
5562 {
5563#if (LINUX_VERSION_CODE > KERNEL_VERSION(2,6,38))
5564 if (channel <= ARRAY_SIZE(hdd_channels_2_4_GHZ))
5565 {
5566 freq = ieee80211_channel_to_frequency(channel,
5567 IEEE80211_BAND_2GHZ);
5568 }
5569 else
5570 {
5571 freq = ieee80211_channel_to_frequency(channel,
5572 IEEE80211_BAND_5GHZ);
5573 }
5574#else
5575 freq = ieee80211_channel_to_frequency(channel);
5576#endif
5577 if(WLAN_HDD_IS_SOCIAL_CHANNEL(freq))
5578 return VOS_STATUS_SUCCESS;
5579 }
5580 }
5581
5582 hddLog(VOS_TRACE_LEVEL_ERROR,
5583 "%s: Invalid Channel [%d]", __func__, channel);
5584 return VOS_STATUS_E_FAILURE;
5585 }
Jeff Johnson295189b2012-06-20 16:38:30 -07005586 }
Rashmi Ramanna3b59e122014-04-10 14:45:13 +05305587
Jeff Johnson295189b2012-06-20 16:38:30 -07005588 return VOS_STATUS_SUCCESS;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305589
Jeff Johnson295189b2012-06-20 16:38:30 -07005590}
5591
Viral Modi3a32cc52013-02-08 11:14:52 -08005592/**
5593 * FUNCTION: wlan_hdd_cfg80211_set_channel
5594 * This function is used to set the channel number
5595 */
5596static int wlan_hdd_cfg80211_set_channel( struct wiphy *wiphy, struct net_device *dev,
5597 struct ieee80211_channel *chan,
5598 enum nl80211_channel_type channel_type
5599 )
5600{
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05305601 hdd_adapter_t *pAdapter = NULL;
Viral Modi3a32cc52013-02-08 11:14:52 -08005602 v_U32_t num_ch = 0;
Jeff Johnson4416a782013-03-25 14:17:50 -07005603 int channel = 0;
Viral Modi3a32cc52013-02-08 11:14:52 -08005604 int freq = chan->center_freq; /* freq is in MHZ */
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05305605 hdd_context_t *pHddCtx;
5606 int status;
Viral Modi3a32cc52013-02-08 11:14:52 -08005607
5608 ENTER();
5609
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05305610
Viral Modi3a32cc52013-02-08 11:14:52 -08005611 if( NULL == dev )
5612 {
5613 hddLog(VOS_TRACE_LEVEL_ERROR,
Arif Hussain6d2a3322013-11-17 19:50:10 -08005614 "%s: Called with dev = NULL.", __func__);
Viral Modi3a32cc52013-02-08 11:14:52 -08005615 return -ENODEV;
5616 }
5617 pAdapter = WLAN_HDD_GET_PRIV_PTR( dev );
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +05305618
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05305619 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
5620 TRACE_CODE_HDD_CFG80211_SET_CHANNEL, pAdapter->sessionId,
5621 channel_type ));
Viral Modi3a32cc52013-02-08 11:14:52 -08005622 hddLog(VOS_TRACE_LEVEL_INFO,
Sushant Kaushik8bc7df22014-04-09 17:55:29 +05305623 "%s: device_mode = %s (%d) freq = %d", __func__,
5624 hdd_device_modetoString(pAdapter->device_mode),
5625 pAdapter->device_mode, chan->center_freq);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05305626
5627 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
5628 status = wlan_hdd_validate_context(pHddCtx);
5629
5630 if (0 != status)
Viral Modi3a32cc52013-02-08 11:14:52 -08005631 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05305632 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
5633 "%s: HDD context is not valid", __func__);
5634 return status;
Viral Modi3a32cc52013-02-08 11:14:52 -08005635 }
5636
5637 /*
5638 * Do freq to chan conversion
5639 * TODO: for 11a
5640 */
5641
5642 channel = ieee80211_frequency_to_channel(freq);
5643
5644 /* Check freq range */
5645 if ((WNI_CFG_CURRENT_CHANNEL_STAMIN > channel) ||
5646 (WNI_CFG_CURRENT_CHANNEL_STAMAX < channel))
5647 {
5648 hddLog(VOS_TRACE_LEVEL_ERROR,
Arif Hussain6d2a3322013-11-17 19:50:10 -08005649 "%s: Channel [%d] is outside valid range from %d to %d",
Viral Modi3a32cc52013-02-08 11:14:52 -08005650 __func__, channel, WNI_CFG_CURRENT_CHANNEL_STAMIN,
5651 WNI_CFG_CURRENT_CHANNEL_STAMAX);
5652 return -EINVAL;
5653 }
5654
5655 num_ch = WNI_CFG_VALID_CHANNEL_LIST_LEN;
5656
Gopichand Nakkala6ab19562013-03-07 13:59:42 +05305657 if ((WLAN_HDD_SOFTAP != pAdapter->device_mode) &&
5658 (WLAN_HDD_P2P_GO != pAdapter->device_mode))
Viral Modi3a32cc52013-02-08 11:14:52 -08005659 {
5660 if(VOS_STATUS_SUCCESS != wlan_hdd_validate_operation_channel(pAdapter,channel))
5661 {
5662 hddLog(VOS_TRACE_LEVEL_ERROR,
Arif Hussain6d2a3322013-11-17 19:50:10 -08005663 "%s: Invalid Channel [%d]", __func__, channel);
Viral Modi3a32cc52013-02-08 11:14:52 -08005664 return -EINVAL;
5665 }
5666 hddLog(VOS_TRACE_LEVEL_INFO_HIGH,
5667 "%s: set channel to [%d] for device mode =%d",
5668 __func__, channel,pAdapter->device_mode);
5669 }
5670 if( (pAdapter->device_mode == WLAN_HDD_INFRA_STATION)
Viral Modi3a32cc52013-02-08 11:14:52 -08005671 || (pAdapter->device_mode == WLAN_HDD_P2P_CLIENT)
Viral Modi3a32cc52013-02-08 11:14:52 -08005672 )
5673 {
5674 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
5675 tCsrRoamProfile * pRoamProfile = &pWextState->roamProfile;
5676 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
5677
5678 if (eConnectionState_IbssConnected == pHddStaCtx->conn_info.connState)
5679 {
5680 /* Link is up then return cant set channel*/
5681 hddLog( VOS_TRACE_LEVEL_ERROR,
Arif Hussain6d2a3322013-11-17 19:50:10 -08005682 "%s: IBSS Associated, can't set the channel", __func__);
Viral Modi3a32cc52013-02-08 11:14:52 -08005683 return -EINVAL;
5684 }
5685
5686 num_ch = pRoamProfile->ChannelInfo.numOfChannels = 1;
5687 pHddStaCtx->conn_info.operationChannel = channel;
5688 pRoamProfile->ChannelInfo.ChannelList =
5689 &pHddStaCtx->conn_info.operationChannel;
5690 }
5691 else if ((pAdapter->device_mode == WLAN_HDD_SOFTAP)
Viral Modi3a32cc52013-02-08 11:14:52 -08005692 || (pAdapter->device_mode == WLAN_HDD_P2P_GO)
Viral Modi3a32cc52013-02-08 11:14:52 -08005693 )
5694 {
Gopichand Nakkalac8fa7b62013-03-11 13:56:41 +05305695 if (WLAN_HDD_P2P_GO == pAdapter->device_mode)
5696 {
5697 if(VOS_STATUS_SUCCESS !=
5698 wlan_hdd_validate_operation_channel(pAdapter,channel))
5699 {
5700 hddLog(VOS_TRACE_LEVEL_ERROR,
Arif Hussain6d2a3322013-11-17 19:50:10 -08005701 "%s: Invalid Channel [%d]", __func__, channel);
Gopichand Nakkalac8fa7b62013-03-11 13:56:41 +05305702 return -EINVAL;
5703 }
5704 (WLAN_HDD_GET_AP_CTX_PTR(pAdapter))->sapConfig.channel = channel;
5705 }
5706 else if ( WLAN_HDD_SOFTAP == pAdapter->device_mode )
Viral Modi3a32cc52013-02-08 11:14:52 -08005707 {
5708 hdd_config_t *cfg_param = (WLAN_HDD_GET_CTX(pAdapter))->cfg_ini;
5709
5710 /* If auto channel selection is configured as enable/ 1 then ignore
5711 channel set by supplicant
5712 */
5713 if ( cfg_param->apAutoChannelSelection )
5714 {
Gopichand Nakkalac8fa7b62013-03-11 13:56:41 +05305715 (WLAN_HDD_GET_AP_CTX_PTR(pAdapter))->sapConfig.channel =
5716 AUTO_CHANNEL_SELECT;
Viral Modi3a32cc52013-02-08 11:14:52 -08005717 hddLog(VOS_TRACE_LEVEL_INFO_HIGH,
Sushant Kaushik8bc7df22014-04-09 17:55:29 +05305718 "%s: set channel to auto channel (0) for device mode =%s (%d)",
5719 __func__, hdd_device_modetoString(pAdapter->device_mode),
5720 pAdapter->device_mode);
Viral Modi3a32cc52013-02-08 11:14:52 -08005721 }
Gopichand Nakkalac8fa7b62013-03-11 13:56:41 +05305722 else
5723 {
5724 if(VOS_STATUS_SUCCESS !=
5725 wlan_hdd_validate_operation_channel(pAdapter,channel))
5726 {
5727 hddLog(VOS_TRACE_LEVEL_ERROR,
Arif Hussain6d2a3322013-11-17 19:50:10 -08005728 "%s: Invalid Channel [%d]", __func__, channel);
Gopichand Nakkalac8fa7b62013-03-11 13:56:41 +05305729 return -EINVAL;
5730 }
5731 (WLAN_HDD_GET_AP_CTX_PTR(pAdapter))->sapConfig.channel = channel;
5732 }
Viral Modi3a32cc52013-02-08 11:14:52 -08005733 }
5734 }
5735 else
5736 {
5737 hddLog(VOS_TRACE_LEVEL_FATAL,
5738 "%s: Invalid device mode failed to set valid channel", __func__);
5739 return -EINVAL;
5740 }
5741 EXIT();
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05305742 return status;
Viral Modi3a32cc52013-02-08 11:14:52 -08005743}
5744
Jeff Johnson295189b2012-06-20 16:38:30 -07005745#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,4,0))
5746static int wlan_hdd_cfg80211_start_bss(hdd_adapter_t *pHostapdAdapter,
5747 struct beacon_parameters *params)
Jeff Johnson04dd8a82012-06-29 20:41:40 -07005748#else
5749static int wlan_hdd_cfg80211_start_bss(hdd_adapter_t *pHostapdAdapter,
5750 struct cfg80211_beacon_data *params,
5751 const u8 *ssid, size_t ssid_len,
5752 enum nl80211_hidden_ssid hidden_ssid)
5753#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07005754{
5755 tsap_Config_t *pConfig;
5756 beacon_data_t *pBeacon = NULL;
5757 struct ieee80211_mgmt *pMgmt_frame;
5758 v_U8_t *pIe=NULL;
5759 v_U16_t capab_info;
5760 eCsrAuthType RSNAuthType;
5761 eCsrEncryptionType RSNEncryptType;
5762 eCsrEncryptionType mcRSNEncryptType;
5763 int status = VOS_STATUS_SUCCESS;
5764 tpWLAN_SAPEventCB pSapEventCallback;
5765 hdd_hostapd_state_t *pHostapdState;
5766 v_U8_t wpaRsnIEdata[(SIR_MAC_MAX_IE_LENGTH * 2)+4]; //Max ie length 255 * 2(WPA+RSN) + 2 bytes (vendor specific ID) * 2
5767 v_CONTEXT_t pVosContext = (WLAN_HDD_GET_CTX(pHostapdAdapter))->pvosContext;
Madan Mohan Koyylamudia16d0202013-02-01 11:05:57 +05305768 tHalHandle hHal = WLAN_HDD_GET_HAL_CTX(pHostapdAdapter);
Jeff Johnson295189b2012-06-20 16:38:30 -07005769 struct qc_mac_acl_entry *acl_entry = NULL;
Siddharth Bhal5cba24e2014-05-08 18:59:39 +05305770 hdd_config_t *iniConfig;
Jeff Johnson295189b2012-06-20 16:38:30 -07005771 v_SINT_t i;
Madan Mohan Koyyalamudi543172b2012-12-05 16:40:18 -08005772 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pHostapdAdapter);
Peng Xu2446a892014-09-05 17:21:18 +05305773 tSmeConfigParams *psmeConfig;
Chet Lanctot40142442014-05-20 13:39:25 -07005774 v_BOOL_t MFPCapable = VOS_FALSE;
5775 v_BOOL_t MFPRequired = VOS_FALSE;
Abhishek Singhf0ac1752014-03-05 17:47:09 +05305776 eHddDot11Mode sapDot11Mode =
5777 (WLAN_HDD_GET_CTX(pHostapdAdapter))->cfg_ini->sapDot11Mode;
Jeff Johnson295189b2012-06-20 16:38:30 -07005778
5779 ENTER();
5780
Siddharth Bhal5cba24e2014-05-08 18:59:39 +05305781 iniConfig = pHddCtx->cfg_ini;
5782
Jeff Johnson295189b2012-06-20 16:38:30 -07005783 pHostapdState = WLAN_HDD_GET_HOSTAP_STATE_PTR(pHostapdAdapter);
5784
5785 pConfig = &pHostapdAdapter->sessionCtx.ap.sapConfig;
5786
5787 pBeacon = pHostapdAdapter->sessionCtx.ap.beacon;
5788
5789 pMgmt_frame = (struct ieee80211_mgmt*)pBeacon->head;
5790
5791 pConfig->beacon_int = pMgmt_frame->u.beacon.beacon_int;
5792
5793 //channel is already set in the set_channel Call back
5794 //pConfig->channel = pCommitConfig->channel;
5795
5796 /*Protection parameter to enable or disable*/
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305797 pConfig->protEnabled =
Jeff Johnson295189b2012-06-20 16:38:30 -07005798 (WLAN_HDD_GET_CTX(pHostapdAdapter))->cfg_ini->apProtEnabled;
5799
5800 pConfig->dtim_period = pBeacon->dtim_period;
5801
Arif Hussain6d2a3322013-11-17 19:50:10 -08005802 hddLog(VOS_TRACE_LEVEL_INFO_HIGH,"****pConfig->dtim_period=%d***",
Jeff Johnson295189b2012-06-20 16:38:30 -07005803 pConfig->dtim_period);
5804
Madan Mohan Koyyalamudie0ca11f2012-11-27 15:57:52 -08005805 if (pHostapdAdapter->device_mode == WLAN_HDD_SOFTAP)
Jeff Johnson32d95a32012-09-10 13:15:23 -07005806 {
5807 pIe = wlan_hdd_cfg80211_get_ie_ptr(pBeacon->tail, pBeacon->tail_len,
Jeff Johnson295189b2012-06-20 16:38:30 -07005808 WLAN_EID_COUNTRY);
Kiet Lam083504c2013-11-25 14:17:45 +05305809 if(memcmp(pHddCtx->cfg_ini->apCntryCode, CFG_AP_COUNTRY_CODE_DEFAULT, 3) != 0)
5810 {
5811 tANI_BOOLEAN restartNeeded;
5812 pConfig->ieee80211d = 1;
5813 vos_mem_copy(pConfig->countryCode, pHddCtx->cfg_ini->apCntryCode, 3);
5814 sme_setRegInfo(hHal, pConfig->countryCode);
5815 sme_ResetCountryCodeInformation(hHal, &restartNeeded);
5816 }
5817 else if(pIe)
Jeff Johnson295189b2012-06-20 16:38:30 -07005818 {
Jeff Johnson32d95a32012-09-10 13:15:23 -07005819 tANI_BOOLEAN restartNeeded;
Jeff Johnson32d95a32012-09-10 13:15:23 -07005820 pConfig->ieee80211d = 1;
5821 vos_mem_copy(pConfig->countryCode, &pIe[2], 3);
5822 sme_setRegInfo(hHal, pConfig->countryCode);
5823 sme_ResetCountryCodeInformation(hHal, &restartNeeded);
Jeff Johnson295189b2012-06-20 16:38:30 -07005824 }
Jeff Johnson32d95a32012-09-10 13:15:23 -07005825 else
5826 {
5827 pConfig->ieee80211d = 0;
5828 }
Madan Mohan Koyylamudia16d0202013-02-01 11:05:57 +05305829 /*
5830 * If auto channel is configured i.e. channel is 0,
5831 * so skip channel validation.
5832 */
5833 if( AUTO_CHANNEL_SELECT != pConfig->channel )
5834 {
5835 if(VOS_STATUS_SUCCESS != wlan_hdd_validate_operation_channel(pHostapdAdapter,pConfig->channel))
5836 {
5837 hddLog(VOS_TRACE_LEVEL_ERROR,
Arif Hussain6d2a3322013-11-17 19:50:10 -08005838 "%s: Invalid Channel [%d]", __func__, pConfig->channel);
Madan Mohan Koyylamudia16d0202013-02-01 11:05:57 +05305839 return -EINVAL;
5840 }
5841 }
5842 else
5843 {
5844 if(1 != pHddCtx->is_dynamic_channel_range_set)
5845 {
5846 hdd_config_t *hdd_pConfig= (WLAN_HDD_GET_CTX(pHostapdAdapter))->cfg_ini;
5847 WLANSAP_SetChannelRange(hHal, hdd_pConfig->apStartChannelNum,
5848 hdd_pConfig->apEndChannelNum,hdd_pConfig->apOperatingBand);
5849 }
5850 pHddCtx->is_dynamic_channel_range_set = 0;
5851 }
Jeff Johnson295189b2012-06-20 16:38:30 -07005852 }
Jeff Johnson32d95a32012-09-10 13:15:23 -07005853 else
Jeff Johnson295189b2012-06-20 16:38:30 -07005854 {
5855 pConfig->ieee80211d = 0;
5856 }
5857 pConfig->authType = eSAP_AUTO_SWITCH;
5858
5859 capab_info = pMgmt_frame->u.beacon.capab_info;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305860
5861 pConfig->privacy = (pMgmt_frame->u.beacon.capab_info &
Jeff Johnson295189b2012-06-20 16:38:30 -07005862 WLAN_CAPABILITY_PRIVACY) ? VOS_TRUE : VOS_FALSE;
5863
5864 (WLAN_HDD_GET_AP_CTX_PTR(pHostapdAdapter))->uPrivacy = pConfig->privacy;
5865
5866 /*Set wps station to configured*/
5867 pIe = wlan_hdd_get_wps_ie_ptr(pBeacon->tail, pBeacon->tail_len);
5868
5869 if(pIe)
5870 {
5871 if(pIe[1] < (2 + WPS_OUI_TYPE_SIZE))
5872 {
Arif Hussain6d2a3322013-11-17 19:50:10 -08005873 hddLog( VOS_TRACE_LEVEL_ERROR, "**Wps Ie Length is too small***");
Jeff Johnson295189b2012-06-20 16:38:30 -07005874 return -EINVAL;
5875 }
5876 else if(memcmp(&pIe[2], WPS_OUI_TYPE, WPS_OUI_TYPE_SIZE) == 0)
5877 {
Madan Mohan Koyyalamudi8bdd3112012-09-24 13:55:14 -07005878 hddLog( VOS_TRACE_LEVEL_INFO, "** WPS IE(len %d) ***", (pIe[1]+2));
Jeff Johnson295189b2012-06-20 16:38:30 -07005879 /* Check 15 bit of WPS IE as it contain information for wps state
5880 * WPS state
5881 */
5882 if(SAP_WPS_ENABLED_UNCONFIGURED == pIe[15])
5883 {
5884 pConfig->wps_state = SAP_WPS_ENABLED_UNCONFIGURED;
5885 } else if(SAP_WPS_ENABLED_CONFIGURED == pIe[15])
5886 {
5887 pConfig->wps_state = SAP_WPS_ENABLED_CONFIGURED;
5888 }
5889 }
5890 }
5891 else
5892 {
5893 pConfig->wps_state = SAP_WPS_DISABLED;
5894 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305895 pConfig->fwdWPSPBCProbeReq = 1; // Forward WPS PBC probe request frame up
Jeff Johnson295189b2012-06-20 16:38:30 -07005896
c_hpothufe599e92014-06-16 11:38:55 +05305897 pConfig->RSNEncryptType = eCSR_ENCRYPT_TYPE_NONE;
5898 pConfig->mcRSNEncryptType = eCSR_ENCRYPT_TYPE_NONE;
5899 (WLAN_HDD_GET_AP_CTX_PTR(pHostapdAdapter))->ucEncryptType =
5900 eCSR_ENCRYPT_TYPE_NONE;
5901
Jeff Johnson295189b2012-06-20 16:38:30 -07005902 pConfig->RSNWPAReqIELength = 0;
5903 pConfig->pRSNWPAReqIE = NULL;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305904 pIe = wlan_hdd_cfg80211_get_ie_ptr(pBeacon->tail, pBeacon->tail_len,
Jeff Johnson295189b2012-06-20 16:38:30 -07005905 WLAN_EID_RSN);
5906 if(pIe && pIe[1])
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305907 {
Jeff Johnson295189b2012-06-20 16:38:30 -07005908 pConfig->RSNWPAReqIELength = pIe[1] + 2;
5909 memcpy(&wpaRsnIEdata[0], pIe, pConfig->RSNWPAReqIELength);
5910 pConfig->pRSNWPAReqIE = &wpaRsnIEdata[0];
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305911 /* The actual processing may eventually be more extensive than
5912 * this. Right now, just consume any PMKIDs that are sent in
Jeff Johnson295189b2012-06-20 16:38:30 -07005913 * by the app.
5914 * */
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305915 status = hdd_softap_unpackIE(
Jeff Johnson295189b2012-06-20 16:38:30 -07005916 vos_get_context( VOS_MODULE_ID_SME, pVosContext),
5917 &RSNEncryptType,
5918 &mcRSNEncryptType,
5919 &RSNAuthType,
Chet Lanctot8cecea22014-02-11 19:09:36 -08005920 &MFPCapable,
5921 &MFPRequired,
Jeff Johnson295189b2012-06-20 16:38:30 -07005922 pConfig->pRSNWPAReqIE[1]+2,
5923 pConfig->pRSNWPAReqIE );
5924
5925 if( VOS_STATUS_SUCCESS == status )
5926 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305927 /* Now copy over all the security attributes you have
5928 * parsed out
Jeff Johnson295189b2012-06-20 16:38:30 -07005929 * */
5930 pConfig->RSNEncryptType = RSNEncryptType; // Use the cipher type in the RSN IE
5931 pConfig->mcRSNEncryptType = mcRSNEncryptType;
5932 (WLAN_HDD_GET_AP_CTX_PTR(pHostapdAdapter))->ucEncryptType
5933 = RSNEncryptType;
Gopichand Nakkala66c0bd02013-04-10 11:36:29 +05305934 hddLog( LOG1, FL("CSR AuthType = %d, "
Arif Hussain6d2a3322013-11-17 19:50:10 -08005935 "EncryptionType = %d mcEncryptionType = %d"),
Jeff Johnson295189b2012-06-20 16:38:30 -07005936 RSNAuthType, RSNEncryptType, mcRSNEncryptType);
5937 }
5938 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305939
Jeff Johnson295189b2012-06-20 16:38:30 -07005940 pIe = wlan_hdd_get_vendor_oui_ie_ptr(WPA_OUI_TYPE, WPA_OUI_TYPE_SIZE,
5941 pBeacon->tail, pBeacon->tail_len);
5942
5943 if(pIe && pIe[1] && (pIe[0] == DOT11F_EID_WPA))
5944 {
5945 if (pConfig->pRSNWPAReqIE)
5946 {
5947 /*Mixed mode WPA/WPA2*/
5948 memcpy((&wpaRsnIEdata[0] + pConfig->RSNWPAReqIELength), pIe, pIe[1] + 2);
5949 pConfig->RSNWPAReqIELength += pIe[1] + 2;
5950 }
5951 else
5952 {
5953 pConfig->RSNWPAReqIELength = pIe[1] + 2;
5954 memcpy(&wpaRsnIEdata[0], pIe, pConfig->RSNWPAReqIELength);
5955 pConfig->pRSNWPAReqIE = &wpaRsnIEdata[0];
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305956 status = hdd_softap_unpackIE(
Jeff Johnson295189b2012-06-20 16:38:30 -07005957 vos_get_context( VOS_MODULE_ID_SME, pVosContext),
5958 &RSNEncryptType,
5959 &mcRSNEncryptType,
5960 &RSNAuthType,
Chet Lanctot8cecea22014-02-11 19:09:36 -08005961 &MFPCapable,
5962 &MFPRequired,
Jeff Johnson295189b2012-06-20 16:38:30 -07005963 pConfig->pRSNWPAReqIE[1]+2,
5964 pConfig->pRSNWPAReqIE );
5965
5966 if( VOS_STATUS_SUCCESS == status )
5967 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305968 /* Now copy over all the security attributes you have
5969 * parsed out
Jeff Johnson295189b2012-06-20 16:38:30 -07005970 * */
5971 pConfig->RSNEncryptType = RSNEncryptType; // Use the cipher type in the RSN IE
5972 pConfig->mcRSNEncryptType = mcRSNEncryptType;
5973 (WLAN_HDD_GET_AP_CTX_PTR(pHostapdAdapter))->ucEncryptType
5974 = RSNEncryptType;
Gopichand Nakkala66c0bd02013-04-10 11:36:29 +05305975 hddLog( LOG1, FL("CSR AuthType = %d, "
Arif Hussain6d2a3322013-11-17 19:50:10 -08005976 "EncryptionType = %d mcEncryptionType = %d"),
Jeff Johnson295189b2012-06-20 16:38:30 -07005977 RSNAuthType, RSNEncryptType, mcRSNEncryptType);
5978 }
5979 }
5980 }
5981
Jeff Johnson4416a782013-03-25 14:17:50 -07005982 if (pConfig->RSNWPAReqIELength > sizeof wpaRsnIEdata) {
5983 hddLog( VOS_TRACE_LEVEL_ERROR, "**RSNWPAReqIELength is too large***");
5984 return -EINVAL;
5985 }
5986
Jeff Johnson295189b2012-06-20 16:38:30 -07005987 pConfig->SSIDinfo.ssidHidden = VOS_FALSE;
5988
Jeff Johnson04dd8a82012-06-29 20:41:40 -07005989#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,4,0))
Jeff Johnson295189b2012-06-20 16:38:30 -07005990 if (params->ssid != NULL)
5991 {
5992 memcpy(pConfig->SSIDinfo.ssid.ssId, params->ssid, params->ssid_len);
5993 pConfig->SSIDinfo.ssid.length = params->ssid_len;
5994 if (params->hidden_ssid != NL80211_HIDDEN_SSID_NOT_IN_USE)
5995 pConfig->SSIDinfo.ssidHidden = VOS_TRUE;
5996 }
Jeff Johnson04dd8a82012-06-29 20:41:40 -07005997#else
5998 if (ssid != NULL)
5999 {
6000 memcpy(pConfig->SSIDinfo.ssid.ssId, ssid, ssid_len);
6001 pConfig->SSIDinfo.ssid.length = ssid_len;
6002 if (hidden_ssid != NL80211_HIDDEN_SSID_NOT_IN_USE)
6003 pConfig->SSIDinfo.ssidHidden = VOS_TRUE;
6004 }
6005#endif
6006
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306007 vos_mem_copy(pConfig->self_macaddr.bytes,
Jeff Johnson295189b2012-06-20 16:38:30 -07006008 pHostapdAdapter->macAddressCurrent.bytes, sizeof(v_MACADDR_t));
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306009
Jeff Johnson295189b2012-06-20 16:38:30 -07006010 /* default value */
6011 pConfig->SapMacaddr_acl = eSAP_ACCEPT_UNLESS_DENIED;
6012 pConfig->num_accept_mac = 0;
6013 pConfig->num_deny_mac = 0;
6014
6015 pIe = wlan_hdd_get_vendor_oui_ie_ptr(BLACKLIST_OUI_TYPE, WPA_OUI_TYPE_SIZE,
6016 pBeacon->tail, pBeacon->tail_len);
6017
6018 /* pIe for black list is following form:
6019 type : 1 byte
6020 length : 1 byte
6021 OUI : 4 bytes
6022 acl type : 1 byte
6023 no of mac addr in black list: 1 byte
6024 list of mac_acl_entries: variable, 6 bytes per mac address + sizeof(int) for vlan id
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306025 */
6026 if ((pIe != NULL) && (pIe[1] != 0))
Jeff Johnson295189b2012-06-20 16:38:30 -07006027 {
6028 pConfig->SapMacaddr_acl = pIe[6];
6029 pConfig->num_deny_mac = pIe[7];
Arif Hussain6d2a3322013-11-17 19:50:10 -08006030 hddLog(VOS_TRACE_LEVEL_INFO,"acl type = %d no deny mac = %d",
Jeff Johnson295189b2012-06-20 16:38:30 -07006031 pIe[6], pIe[7]);
Gopichand Nakkalac005b7c2013-05-14 16:04:14 +05306032 if (pConfig->num_deny_mac > MAX_ACL_MAC_ADDRESS)
6033 pConfig->num_deny_mac = MAX_ACL_MAC_ADDRESS;
Jeff Johnson295189b2012-06-20 16:38:30 -07006034 acl_entry = (struct qc_mac_acl_entry *)(pIe + 8);
6035 for (i = 0; i < pConfig->num_deny_mac; i++)
6036 {
6037 vos_mem_copy(&pConfig->deny_mac[i], acl_entry->addr, sizeof(qcmacaddr));
6038 acl_entry++;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306039 }
Jeff Johnson295189b2012-06-20 16:38:30 -07006040 }
6041 pIe = wlan_hdd_get_vendor_oui_ie_ptr(WHITELIST_OUI_TYPE, WPA_OUI_TYPE_SIZE,
6042 pBeacon->tail, pBeacon->tail_len);
6043
6044 /* pIe for white list is following form:
6045 type : 1 byte
6046 length : 1 byte
6047 OUI : 4 bytes
6048 acl type : 1 byte
6049 no of mac addr in white list: 1 byte
6050 list of mac_acl_entries: variable, 6 bytes per mac address + sizeof(int) for vlan id
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306051 */
6052 if ((pIe != NULL) && (pIe[1] != 0))
Jeff Johnson295189b2012-06-20 16:38:30 -07006053 {
6054 pConfig->SapMacaddr_acl = pIe[6];
6055 pConfig->num_accept_mac = pIe[7];
Arif Hussain6d2a3322013-11-17 19:50:10 -08006056 hddLog(VOS_TRACE_LEVEL_INFO,"acl type = %d no accept mac = %d",
Jeff Johnson295189b2012-06-20 16:38:30 -07006057 pIe[6], pIe[7]);
Gopichand Nakkalac005b7c2013-05-14 16:04:14 +05306058 if (pConfig->num_accept_mac > MAX_ACL_MAC_ADDRESS)
6059 pConfig->num_accept_mac = MAX_ACL_MAC_ADDRESS;
Jeff Johnson295189b2012-06-20 16:38:30 -07006060 acl_entry = (struct qc_mac_acl_entry *)(pIe + 8);
6061 for (i = 0; i < pConfig->num_accept_mac; i++)
6062 {
6063 vos_mem_copy(&pConfig->accept_mac[i], acl_entry->addr, sizeof(qcmacaddr));
6064 acl_entry++;
6065 }
6066 }
Gopichand Nakkalac005b7c2013-05-14 16:04:14 +05306067
Jeff Johnson295189b2012-06-20 16:38:30 -07006068 wlan_hdd_set_sapHwmode(pHostapdAdapter);
6069
Jeff Johnsone7245742012-09-05 17:12:55 -07006070#ifdef WLAN_FEATURE_11AC
Ravi Kumar Vaishnavbbaebbe2013-01-15 17:09:48 -08006071 /* Overwrite the hostapd setting for HW mode only for 11ac.
Kiet Lam0f320422013-11-21 19:29:17 +05306072 * This is valid only if mode is set to 11n in hostapd, either AUTO or
6073 * 11ac in .ini and 11ac is supported by both host and firmware.
6074 * Otherwise, leave whatever is set in hostapd (a OR b OR g OR n mode)
6075 */
Ravi Kumar Vaishnavbbaebbe2013-01-15 17:09:48 -08006076 if( ((pConfig->SapHw_mode == eSAP_DOT11_MODE_11n) ||
6077 (pConfig->SapHw_mode == eSAP_DOT11_MODE_11n_ONLY)) &&
Abhishek Singhf0ac1752014-03-05 17:47:09 +05306078 (( sapDot11Mode == eHDD_DOT11_MODE_AUTO ) ||
6079 ( sapDot11Mode == eHDD_DOT11_MODE_11ac ) ||
6080 ( sapDot11Mode == eHDD_DOT11_MODE_11ac_ONLY ) ) &&
6081 (sme_IsFeatureSupportedByDriver(DOT11AC)) &&
6082 (sme_IsFeatureSupportedByFW(DOT11AC)) )
Jeff Johnsone7245742012-09-05 17:12:55 -07006083 {
Siddharth Bhalf42f8592014-05-15 13:39:07 +05306084 v_U32_t operatingBand = 0;
Jeff Johnsone7245742012-09-05 17:12:55 -07006085 pConfig->SapHw_mode = eSAP_DOT11_MODE_11ac;
Siddharth Bhalf42f8592014-05-15 13:39:07 +05306086 ccmCfgGetInt(hHal, WNI_CFG_SAP_CHANNEL_SELECT_OPERATING_BAND, &operatingBand);
Ravi Joshi83bfaa12013-05-28 22:12:08 -07006087
Siddharth Bhal5cba24e2014-05-08 18:59:39 +05306088 /* If ACS disable and selected channel <= 14
6089 * OR
6090 * ACS enabled and ACS operating band is choosen as 2.4
6091 * AND
6092 * VHT in 2.4G Disabled
6093 * THEN
6094 * Fallback to 11N mode
6095 */
6096 if (((AUTO_CHANNEL_SELECT != pConfig->channel && pConfig->channel <= SIR_11B_CHANNEL_END)
6097 || (AUTO_CHANNEL_SELECT == pConfig->channel &&
Siddharth Bhalf42f8592014-05-15 13:39:07 +05306098 operatingBand == RF_SUBBAND_2_4_GHZ)) &&
Siddharth Bhal5cba24e2014-05-08 18:59:39 +05306099 iniConfig->enableVhtFor24GHzBand == FALSE)
Ravi Joshi83bfaa12013-05-28 22:12:08 -07006100 {
Siddharth Bhalf42f8592014-05-15 13:39:07 +05306101 hddLog(LOGW, FL("Setting hwmode to 11n, operatingBand = %d, Channel = %d"),
6102 operatingBand, pConfig->channel);
Ravi Joshi83bfaa12013-05-28 22:12:08 -07006103 pConfig->SapHw_mode = eSAP_DOT11_MODE_11n;
6104 }
Jeff Johnsone7245742012-09-05 17:12:55 -07006105 }
6106#endif
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306107
Ravi Joshiaeb7d9e2013-05-02 12:28:14 -07006108 if ( AUTO_CHANNEL_SELECT != pConfig->channel )
6109 {
6110 sme_SelectCBMode(hHal,
6111 sapConvertSapPhyModeToCsrPhyMode(pConfig->SapHw_mode),
6112 pConfig->channel);
6113 }
Jeff Johnson295189b2012-06-20 16:38:30 -07006114 // ht_capab is not what the name conveys,this is used for protection bitmap
6115 pConfig->ht_capab =
6116 (WLAN_HDD_GET_CTX(pHostapdAdapter))->cfg_ini->apProtection;
6117
6118 if ( 0 != wlan_hdd_cfg80211_update_apies(pHostapdAdapter, params) )
6119 {
6120 hddLog(LOGE, FL("SAP Not able to set AP IEs"));
6121 return -EINVAL;
6122 }
6123
6124 //Uapsd Enabled Bit
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306125 pConfig->UapsdEnable =
Jeff Johnson295189b2012-06-20 16:38:30 -07006126 (WLAN_HDD_GET_CTX(pHostapdAdapter))->cfg_ini->apUapsdEnabled;
6127 //Enable OBSS protection
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306128 pConfig->obssProtEnabled =
6129 (WLAN_HDD_GET_CTX(pHostapdAdapter))->cfg_ini->apOBSSProtEnabled;
Jeff Johnson295189b2012-06-20 16:38:30 -07006130
Chet Lanctot8cecea22014-02-11 19:09:36 -08006131#ifdef WLAN_FEATURE_11W
6132 pConfig->mfpCapable = MFPCapable;
6133 pConfig->mfpRequired = MFPRequired;
6134 hddLog(LOGW, FL("Soft AP MFP capable %d, MFP required %d\n"),
6135 pConfig->mfpCapable, pConfig->mfpRequired);
6136#endif
6137
Arif Hussain6d2a3322013-11-17 19:50:10 -08006138 hddLog(LOGW, FL("SOftAP macaddress : "MAC_ADDRESS_STR),
Jeff Johnson295189b2012-06-20 16:38:30 -07006139 MAC_ADDR_ARRAY(pHostapdAdapter->macAddressCurrent.bytes));
Arif Hussain6d2a3322013-11-17 19:50:10 -08006140 hddLog(LOGW,FL("ssid =%s, beaconint=%d, channel=%d"),
6141 pConfig->SSIDinfo.ssid.ssId, (int)pConfig->beacon_int,
6142 (int)pConfig->channel);
6143 hddLog(LOGW,FL("hw_mode=%x, privacy=%d, authType=%d"),
6144 pConfig->SapHw_mode, pConfig->privacy,
6145 pConfig->authType);
6146 hddLog(LOGW,FL("RSN/WPALen=%d, Uapsd = %d"),
6147 (int)pConfig->RSNWPAReqIELength, pConfig->UapsdEnable);
6148 hddLog(LOGW,FL("ProtEnabled = %d, OBSSProtEnabled = %d"),
6149 pConfig->protEnabled, pConfig->obssProtEnabled);
Jeff Johnson295189b2012-06-20 16:38:30 -07006150
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306151 if(test_bit(SOFTAP_BSS_STARTED, &pHostapdAdapter->event_flags))
Jeff Johnson295189b2012-06-20 16:38:30 -07006152 {
6153 //Bss already started. just return.
6154 //TODO Probably it should update some beacon params.
6155 hddLog( LOGE, "Bss Already started...Ignore the request");
6156 EXIT();
6157 return 0;
6158 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306159
Agarwal Ashish51325b52014-06-16 16:50:49 +05306160 if (vos_max_concurrent_connections_reached()) {
6161 hddLog(VOS_TRACE_LEVEL_INFO, FL("Reached max concurrent connections"));
6162 return -EINVAL;
6163 }
6164
Jeff Johnson295189b2012-06-20 16:38:30 -07006165 pConfig->persona = pHostapdAdapter->device_mode;
6166
Peng Xu2446a892014-09-05 17:21:18 +05306167 psmeConfig = (tSmeConfigParams*) vos_mem_malloc(sizeof(tSmeConfigParams));
6168 if ( NULL != psmeConfig)
6169 {
6170 sme_GetConfigParam(hHal, psmeConfig);
6171 pConfig->scanBandPreference = psmeConfig->csrConfig.scanBandPreference;
6172 vos_mem_free(psmeConfig);
6173 }
Peng Xuafc34e32014-09-25 13:23:55 +05306174 pConfig->acsBandSwitchThreshold = iniConfig->acsBandSwitchThreshold;
Peng Xu2446a892014-09-05 17:21:18 +05306175
Jeff Johnson295189b2012-06-20 16:38:30 -07006176 pSapEventCallback = hdd_hostapd_SAPEventCB;
6177 if(WLANSAP_StartBss(pVosContext, pSapEventCallback, pConfig,
6178 (v_PVOID_t)pHostapdAdapter->dev) != VOS_STATUS_SUCCESS)
6179 {
Arif Hussain6d2a3322013-11-17 19:50:10 -08006180 hddLog(LOGE,FL("SAP Start Bss fail"));
Jeff Johnson295189b2012-06-20 16:38:30 -07006181 return -EINVAL;
6182 }
6183
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306184 hddLog(LOG1,
Jeff Johnson295189b2012-06-20 16:38:30 -07006185 FL("Waiting for Scan to complete(auto mode) and BSS to start"));
6186
6187 status = vos_wait_single_event(&pHostapdState->vosEvent, 10000);
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306188
Jeff Johnson295189b2012-06-20 16:38:30 -07006189 if (!VOS_IS_STATUS_SUCCESS(status))
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306190 {
6191 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Arif Hussain6d2a3322013-11-17 19:50:10 -08006192 ("ERROR: HDD vos wait for single_event failed!!"));
Tushnim Bhattacharyyaad37df12013-10-02 12:01:33 -07006193 smeGetCommandQStatus(hHal);
Jeff Johnson295189b2012-06-20 16:38:30 -07006194 VOS_ASSERT(0);
6195 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306196
Jeff Johnson295189b2012-06-20 16:38:30 -07006197 set_bit(SOFTAP_BSS_STARTED, &pHostapdAdapter->event_flags);
Agarwal Ashish51325b52014-06-16 16:50:49 +05306198 wlan_hdd_incr_active_session(pHddCtx, pHostapdAdapter->device_mode);
Jeff Johnson295189b2012-06-20 16:38:30 -07006199
Madan Mohan Koyyalamudi26bd7142012-10-30 18:14:19 -07006200#ifdef WLAN_FEATURE_P2P_DEBUG
6201 if (pHostapdAdapter->device_mode == WLAN_HDD_P2P_GO)
6202 {
6203 if(globalP2PConnectionStatus == P2P_GO_NEG_COMPLETED)
6204 {
6205 globalP2PConnectionStatus = P2P_GO_COMPLETED_STATE;
6206 hddLog(LOGE,"[P2P State] From Go nego completed to "
Jeff Johnson1250df42012-12-10 14:31:52 -08006207 "Non-autonomous Group started");
Madan Mohan Koyyalamudi26bd7142012-10-30 18:14:19 -07006208 }
6209 else if(globalP2PConnectionStatus == P2P_NOT_ACTIVE)
6210 {
6211 globalP2PConnectionStatus = P2P_GO_COMPLETED_STATE;
6212 hddLog(LOGE,"[P2P State] From Inactive to "
Jeff Johnson1250df42012-12-10 14:31:52 -08006213 "Autonomous Group started");
Madan Mohan Koyyalamudi26bd7142012-10-30 18:14:19 -07006214 }
6215 }
6216#endif
6217
Jeff Johnson295189b2012-06-20 16:38:30 -07006218 pHostapdState->bCommit = TRUE;
6219 EXIT();
6220
6221 return 0;
6222}
6223
Jeff Johnson04dd8a82012-06-29 20:41:40 -07006224#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,4,0))
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306225static int wlan_hdd_cfg80211_add_beacon(struct wiphy *wiphy,
6226 struct net_device *dev,
Jeff Johnson295189b2012-06-20 16:38:30 -07006227 struct beacon_parameters *params)
6228{
6229 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +05306230 hdd_context_t *pHddCtx;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05306231 int status;
Jeff Johnson295189b2012-06-20 16:38:30 -07006232
6233 ENTER();
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +05306234
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05306235 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
6236 TRACE_CODE_HDD_CFG80211_ADD_BEACON,
6237 pAdapter->sessionId, params->interval));
Sushant Kaushik8bc7df22014-04-09 17:55:29 +05306238 hddLog(VOS_TRACE_LEVEL_INFO_HIGH, "device mode=%s (%d)",
6239 hdd_device_modetoString(pAdapter->device_mode),
6240 pAdapter->device_mode);
Jeff Johnson295189b2012-06-20 16:38:30 -07006241
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05306242 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
6243 status = wlan_hdd_validate_context(pHddCtx);
6244
6245 if (0 != status)
Jeff Johnson04dd8a82012-06-29 20:41:40 -07006246 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05306247 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
6248 "%s: HDD context is not valid", __func__);
6249 return status;
Jeff Johnson04dd8a82012-06-29 20:41:40 -07006250 }
6251
Agarwal Ashish51325b52014-06-16 16:50:49 +05306252 if (vos_max_concurrent_connections_reached()) {
6253 hddLog(VOS_TRACE_LEVEL_INFO, FL("Reached max concurrent connections"));
6254 return -EINVAL;
6255 }
6256
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306257 if ( (pAdapter->device_mode == WLAN_HDD_SOFTAP)
Jeff Johnson295189b2012-06-20 16:38:30 -07006258 || (pAdapter->device_mode == WLAN_HDD_P2P_GO)
Jeff Johnson295189b2012-06-20 16:38:30 -07006259 )
6260 {
6261 beacon_data_t *old,*new;
6262
6263 old = pAdapter->sessionCtx.ap.beacon;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306264
Jeff Johnson295189b2012-06-20 16:38:30 -07006265 if (old)
c_hpothu6ff1c3c2013-10-01 19:01:57 +05306266 {
6267 hddLog(VOS_TRACE_LEVEL_WARN,
6268 FL("already beacon info added to session(%d)"),
6269 pAdapter->sessionId);
Jeff Johnson295189b2012-06-20 16:38:30 -07006270 return -EALREADY;
c_hpothu6ff1c3c2013-10-01 19:01:57 +05306271 }
Jeff Johnson295189b2012-06-20 16:38:30 -07006272
6273 status = wlan_hdd_cfg80211_alloc_new_beacon(pAdapter,&new,params);
6274
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306275 if(status != VOS_STATUS_SUCCESS)
Jeff Johnson295189b2012-06-20 16:38:30 -07006276 {
6277 hddLog(VOS_TRACE_LEVEL_FATAL,
Arif Hussain6d2a3322013-11-17 19:50:10 -08006278 "%s:Error!!! Allocating the new beacon",__func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07006279 return -EINVAL;
6280 }
6281
6282 pAdapter->sessionCtx.ap.beacon = new;
6283
6284 status = wlan_hdd_cfg80211_start_bss(pAdapter, params);
6285 }
6286
6287 EXIT();
6288 return status;
6289}
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306290
6291static int wlan_hdd_cfg80211_set_beacon(struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -07006292 struct net_device *dev,
6293 struct beacon_parameters *params)
6294{
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306295 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +05306296 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
6297 hdd_context_t *pHddCtx;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05306298 int status;
Jeff Johnson295189b2012-06-20 16:38:30 -07006299
6300 ENTER();
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +05306301 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
6302 TRACE_CODE_HDD_CFG80211_SET_BEACON,
6303 pAdapter->sessionId, pHddStaCtx->conn_info.authType));
6304 hddLog(VOS_TRACE_LEVEL_INFO, "%s: device_mode = %s (%d)",
6305 __func__, hdd_device_modetoString(pAdapter->device_mode),
6306 pAdapter->device_mode);
6307
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05306308 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
6309 status = wlan_hdd_validate_context(pHddCtx);
6310
6311 if (0 != status)
Jeff Johnson04dd8a82012-06-29 20:41:40 -07006312 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05306313 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
6314 "%s: HDD context is not valid", __func__);
6315 return status;
Jeff Johnson04dd8a82012-06-29 20:41:40 -07006316 }
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +05306317
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306318 if ((pAdapter->device_mode == WLAN_HDD_SOFTAP)
Jeff Johnson295189b2012-06-20 16:38:30 -07006319 || (pAdapter->device_mode == WLAN_HDD_P2P_GO)
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306320 )
Jeff Johnson295189b2012-06-20 16:38:30 -07006321 {
6322 beacon_data_t *old,*new;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306323
Jeff Johnson295189b2012-06-20 16:38:30 -07006324 old = pAdapter->sessionCtx.ap.beacon;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306325
Jeff Johnson295189b2012-06-20 16:38:30 -07006326 if (!old)
c_hpothu6ff1c3c2013-10-01 19:01:57 +05306327 {
6328 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
6329 FL("session(%d) old and new heads points to NULL"),
6330 pAdapter->sessionId);
Jeff Johnson295189b2012-06-20 16:38:30 -07006331 return -ENOENT;
c_hpothu6ff1c3c2013-10-01 19:01:57 +05306332 }
Jeff Johnson295189b2012-06-20 16:38:30 -07006333
6334 status = wlan_hdd_cfg80211_alloc_new_beacon(pAdapter,&new,params);
6335
6336 if(status != VOS_STATUS_SUCCESS) {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306337 hddLog(VOS_TRACE_LEVEL_FATAL,
Arif Hussain6d2a3322013-11-17 19:50:10 -08006338 "%s: Error!!! Allocating the new beacon",__func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07006339 return -EINVAL;
6340 }
6341
6342 pAdapter->sessionCtx.ap.beacon = new;
6343
6344 status = wlan_hdd_cfg80211_start_bss(pAdapter, params);
6345 }
6346
6347 EXIT();
6348 return status;
6349}
6350
Jeff Johnson04dd8a82012-06-29 20:41:40 -07006351#endif //(LINUX_VERSION_CODE < KERNEL_VERSION(3,4,0))
6352
6353#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,4,0))
Jeff Johnson295189b2012-06-20 16:38:30 -07006354static int wlan_hdd_cfg80211_del_beacon(struct wiphy *wiphy,
6355 struct net_device *dev)
Jeff Johnson04dd8a82012-06-29 20:41:40 -07006356#else
6357static int wlan_hdd_cfg80211_stop_ap (struct wiphy *wiphy,
6358 struct net_device *dev)
6359#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07006360{
6361 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
Jeff Johnsone7245742012-09-05 17:12:55 -07006362 hdd_context_t *pHddCtx = NULL;
6363 hdd_scaninfo_t *pScanInfo = NULL;
6364 hdd_adapter_t *staAdapter = NULL;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05306365 VOS_STATUS status;
Mahesh A Saptasagar2395ee62014-05-21 19:12:21 +05306366 long ret;
Jeff Johnson295189b2012-06-20 16:38:30 -07006367
6368 ENTER();
6369
6370 if (NULL == pAdapter)
6371 {
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +05306372 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07006373 "%s: HDD adapter context is Null", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07006374 return -ENODEV;
6375 }
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -07006376
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05306377 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
6378 TRACE_CODE_HDD_CFG80211_STOP_AP,
6379 pAdapter->sessionId, pAdapter->device_mode));
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05306380 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
6381 status = wlan_hdd_validate_context(pHddCtx);
6382
6383 if (0 != status)
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -07006384 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05306385 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
6386 "%s: HDD context is not valid", __func__);
6387 return status;
Jeff Johnson4416a782013-03-25 14:17:50 -07006388 }
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -07006389
6390 staAdapter = hdd_get_adapter(pAdapter->pHddCtx, WLAN_HDD_INFRA_STATION);
6391 if (NULL == staAdapter)
6392 {
6393 staAdapter = hdd_get_adapter(pAdapter->pHddCtx, WLAN_HDD_P2P_CLIENT);
6394 if (NULL == staAdapter)
6395 {
Rajesh Chauhan52d885b2013-11-01 10:54:25 -07006396 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO_HIGH,
6397 "%s: HDD adapter context for STA/P2P-CLI is Null",
6398 __func__);
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -07006399 }
6400 }
6401
6402 pScanInfo = &pHddCtx->scan_info;
6403
Sushant Kaushik8bc7df22014-04-09 17:55:29 +05306404 hddLog(VOS_TRACE_LEVEL_INFO, "%s: device_mode = %s (%d)",
6405 __func__, hdd_device_modetoString(pAdapter->device_mode),
6406 pAdapter->device_mode);
Jeff Johnson295189b2012-06-20 16:38:30 -07006407
Mahesh A Saptasagar2395ee62014-05-21 19:12:21 +05306408 ret = wlan_hdd_scan_abort(pAdapter);
6409
Girish Gowli4bf7a632014-06-12 13:42:11 +05306410 if (ret < 0)
Jeff Johnsone7245742012-09-05 17:12:55 -07006411 {
Mahesh A Saptasagar2395ee62014-05-21 19:12:21 +05306412 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
6413 FL("Timeout occurred while waiting for abortscan %ld"), ret);
c_hpothu6ff1c3c2013-10-01 19:01:57 +05306414
Mahesh A Saptasagar2395ee62014-05-21 19:12:21 +05306415 if (pHddCtx->isLogpInProgress)
Jeff Johnsone7245742012-09-05 17:12:55 -07006416 {
Mahesh A Saptasagar2395ee62014-05-21 19:12:21 +05306417 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
6418 "%s: LOGP in Progress. Ignore!!!", __func__);
Yue Ma4f55ef32014-01-23 16:45:33 -08006419
Jeff Johnsone7245742012-09-05 17:12:55 -07006420 VOS_ASSERT(pScanInfo->mScanPending);
Mahesh A Saptasagar2395ee62014-05-21 19:12:21 +05306421 return -EAGAIN;
Jeff Johnsone7245742012-09-05 17:12:55 -07006422 }
Mahesh A Saptasagar2395ee62014-05-21 19:12:21 +05306423 VOS_ASSERT(pScanInfo->mScanPending);
Jeff Johnsone7245742012-09-05 17:12:55 -07006424 }
6425
Rashmi Ramanna1f0948d2014-08-28 15:33:48 +05306426 /* Delete all associated STAs before stopping AP/P2P GO */
6427 hdd_del_all_sta(pAdapter);
Arun Kumar Khandavallia3bd8002014-01-17 16:21:19 +05306428 hdd_hostapd_stop(dev);
6429
Jeff Johnson295189b2012-06-20 16:38:30 -07006430 if ((pAdapter->device_mode == WLAN_HDD_SOFTAP)
Jeff Johnson295189b2012-06-20 16:38:30 -07006431 || (pAdapter->device_mode == WLAN_HDD_P2P_GO)
Jeff Johnson295189b2012-06-20 16:38:30 -07006432 )
6433 {
6434 beacon_data_t *old;
6435
6436 old = pAdapter->sessionCtx.ap.beacon;
6437
6438 if (!old)
c_hpothu6ff1c3c2013-10-01 19:01:57 +05306439 {
6440 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
6441 FL("session(%d) beacon data points to NULL"),
6442 pAdapter->sessionId);
Jeff Johnson295189b2012-06-20 16:38:30 -07006443 return -ENOENT;
c_hpothu6ff1c3c2013-10-01 19:01:57 +05306444 }
Jeff Johnson295189b2012-06-20 16:38:30 -07006445
Jeff Johnson295189b2012-06-20 16:38:30 -07006446 hdd_cleanup_actionframe(pHddCtx, pAdapter);
Jeff Johnson295189b2012-06-20 16:38:30 -07006447
6448 mutex_lock(&pHddCtx->sap_lock);
6449 if(test_bit(SOFTAP_BSS_STARTED, &pAdapter->event_flags))
6450 {
Jeff Johnson4416a782013-03-25 14:17:50 -07006451 if ( VOS_STATUS_SUCCESS == (status = WLANSAP_StopBss(pHddCtx->pvosContext) ) )
Jeff Johnson295189b2012-06-20 16:38:30 -07006452 {
6453 hdd_hostapd_state_t *pHostapdState = WLAN_HDD_GET_HOSTAP_STATE_PTR(pAdapter);
6454
6455 status = vos_wait_single_event(&pHostapdState->vosEvent, 10000);
6456
6457 if (!VOS_IS_STATUS_SUCCESS(status))
6458 {
6459 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Arif Hussain6d2a3322013-11-17 19:50:10 -08006460 ("ERROR: HDD vos wait for single_event failed!!"));
Jeff Johnson295189b2012-06-20 16:38:30 -07006461 VOS_ASSERT(0);
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05306462 }
6463 }
Jeff Johnson295189b2012-06-20 16:38:30 -07006464 clear_bit(SOFTAP_BSS_STARTED, &pAdapter->event_flags);
Agarwal Ashish51325b52014-06-16 16:50:49 +05306465 /* BSS stopped, clear the active sessions for this device mode */
6466 wlan_hdd_decr_active_session(pHddCtx, pAdapter->device_mode);
Jeff Johnson295189b2012-06-20 16:38:30 -07006467 }
6468 mutex_unlock(&pHddCtx->sap_lock);
6469
6470 if(status != VOS_STATUS_SUCCESS)
6471 {
6472 hddLog(VOS_TRACE_LEVEL_FATAL,
Arif Hussain6d2a3322013-11-17 19:50:10 -08006473 "%s:Error!!! Stopping the BSS",__func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07006474 return -EINVAL;
6475 }
6476
Jeff Johnson4416a782013-03-25 14:17:50 -07006477 if (ccmCfgSetInt(pHddCtx->hHal,
Jeff Johnson295189b2012-06-20 16:38:30 -07006478 WNI_CFG_PROBE_RSP_BCN_ADDNIE_FLAG, 0,NULL, eANI_BOOLEAN_FALSE)
6479 ==eHAL_STATUS_FAILURE)
6480 {
6481 hddLog(LOGE,
Arif Hussain6d2a3322013-11-17 19:50:10 -08006482 "Could not pass on WNI_CFG_PROBE_RSP_BCN_ADDNIE_FLAG to CCM");
Jeff Johnson295189b2012-06-20 16:38:30 -07006483 }
6484
Jeff Johnson4416a782013-03-25 14:17:50 -07006485 if ( eHAL_STATUS_FAILURE == ccmCfgSetInt(pHddCtx->hHal,
Jeff Johnson295189b2012-06-20 16:38:30 -07006486 WNI_CFG_ASSOC_RSP_ADDNIE_FLAG, 0, NULL,
6487 eANI_BOOLEAN_FALSE) )
6488 {
6489 hddLog(LOGE,
Arif Hussain6d2a3322013-11-17 19:50:10 -08006490 "Could not pass on WNI_CFG_ASSOC_RSP_ADDNIE_FLAG to CCM");
Jeff Johnson295189b2012-06-20 16:38:30 -07006491 }
6492
6493 // Reset WNI_CFG_PROBE_RSP Flags
6494 wlan_hdd_reset_prob_rspies(pAdapter);
6495
6496 pAdapter->sessionCtx.ap.beacon = NULL;
6497 kfree(old);
Madan Mohan Koyyalamudi26bd7142012-10-30 18:14:19 -07006498#ifdef WLAN_FEATURE_P2P_DEBUG
6499 if((pAdapter->device_mode == WLAN_HDD_P2P_GO) &&
6500 (globalP2PConnectionStatus == P2P_GO_COMPLETED_STATE))
6501 {
6502 hddLog(LOGE,"[P2P State] From GO completed to Inactive state "
6503 "GO got removed");
6504 globalP2PConnectionStatus = P2P_NOT_ACTIVE;
6505 }
6506#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07006507 }
6508 EXIT();
6509 return status;
6510}
Jeff Johnson04dd8a82012-06-29 20:41:40 -07006511
6512#if (LINUX_VERSION_CODE > KERNEL_VERSION(3,3,0))
6513
Pratik Bhalgata0c7f262012-11-22 17:40:24 +05306514static int wlan_hdd_cfg80211_start_ap(struct wiphy *wiphy,
6515 struct net_device *dev,
Jeff Johnson04dd8a82012-06-29 20:41:40 -07006516 struct cfg80211_ap_settings *params)
6517{
Pratik Bhalgata0c7f262012-11-22 17:40:24 +05306518 hdd_adapter_t *pAdapter;
6519 hdd_context_t *pHddCtx;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05306520 int status;
Jeff Johnson04dd8a82012-06-29 20:41:40 -07006521
6522 ENTER();
6523
Pratik Bhalgata0c7f262012-11-22 17:40:24 +05306524 if (NULL == dev)
Madan Mohan Koyyalamudib2c36892012-10-18 20:52:38 -07006525 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05306526 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Pratik Bhalgata0c7f262012-11-22 17:40:24 +05306527 "%s: Device is Null", __func__);
6528 return -ENODEV;
6529 }
6530
6531 pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
6532 if (NULL == pAdapter)
6533 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05306534 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Pratik Bhalgata0c7f262012-11-22 17:40:24 +05306535 "%s: HDD adapter is Null", __func__);
6536 return -ENODEV;
6537 }
6538
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05306539 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
6540 TRACE_CODE_HDD_CFG80211_START_AP, pAdapter->sessionId,
6541 params-> beacon_interval));
Pratik Bhalgata0c7f262012-11-22 17:40:24 +05306542 if (WLAN_HDD_ADAPTER_MAGIC != pAdapter->magic)
6543 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05306544 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Pratik Bhalgata0c7f262012-11-22 17:40:24 +05306545 "%s: HDD adapter magic is invalid", __func__);
6546 return -ENODEV;
6547 }
6548
6549 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05306550 status = wlan_hdd_validate_context(pHddCtx);
Pratik Bhalgata0c7f262012-11-22 17:40:24 +05306551
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05306552 if (0 != status)
Pratik Bhalgata0c7f262012-11-22 17:40:24 +05306553 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05306554 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
6555 "%s: HDD context is not valid", __func__);
6556 return status;
Pratik Bhalgata0c7f262012-11-22 17:40:24 +05306557 }
6558
Sushant Kaushik8bc7df22014-04-09 17:55:29 +05306559 hddLog(VOS_TRACE_LEVEL_INFO_HIGH, "%s: device mode = %s (%d)",
6560 __func__, hdd_device_modetoString(pAdapter->device_mode),
6561 pAdapter->device_mode);
Pratik Bhalgata0c7f262012-11-22 17:40:24 +05306562
6563 if ((pAdapter->device_mode == WLAN_HDD_SOFTAP)
Jeff Johnson04dd8a82012-06-29 20:41:40 -07006564 || (pAdapter->device_mode == WLAN_HDD_P2P_GO)
Jeff Johnson04dd8a82012-06-29 20:41:40 -07006565 )
6566 {
Pratik Bhalgata0c7f262012-11-22 17:40:24 +05306567 beacon_data_t *old, *new;
Jeff Johnson04dd8a82012-06-29 20:41:40 -07006568
6569 old = pAdapter->sessionCtx.ap.beacon;
Pratik Bhalgata0c7f262012-11-22 17:40:24 +05306570
Jeff Johnson04dd8a82012-06-29 20:41:40 -07006571 if (old)
c_hpothu6ff1c3c2013-10-01 19:01:57 +05306572 {
6573 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_WARN,
6574 FL("already beacon info added to session(%d)"),
6575 pAdapter->sessionId);
Jeff Johnson04dd8a82012-06-29 20:41:40 -07006576 return -EALREADY;
c_hpothu6ff1c3c2013-10-01 19:01:57 +05306577 }
Jeff Johnson04dd8a82012-06-29 20:41:40 -07006578
6579 status = wlan_hdd_cfg80211_alloc_new_beacon(pAdapter, &new, &params->beacon, params->dtim_period);
6580
Pratik Bhalgata0c7f262012-11-22 17:40:24 +05306581 if (status != 0)
Jeff Johnson04dd8a82012-06-29 20:41:40 -07006582 {
6583 hddLog(VOS_TRACE_LEVEL_FATAL,
Pratik Bhalgata0c7f262012-11-22 17:40:24 +05306584 "%s:Error!!! Allocating the new beacon", __func__);
Jeff Johnson04dd8a82012-06-29 20:41:40 -07006585 return -EINVAL;
6586 }
6587 pAdapter->sessionCtx.ap.beacon = new;
Viral Modi3a32cc52013-02-08 11:14:52 -08006588#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,6,0))
Yue Maf49ba872013-08-19 12:04:25 -07006589 wlan_hdd_cfg80211_set_channel(wiphy, dev,
6590#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,8,0))
6591 params->channel, params->channel_type);
6592#else
6593 params->chandef.chan, cfg80211_get_chandef_type(&(params->chandef)));
6594#endif
Viral Modi3a32cc52013-02-08 11:14:52 -08006595#endif
Jeff Johnson04dd8a82012-06-29 20:41:40 -07006596 status = wlan_hdd_cfg80211_start_bss(pAdapter, &params->beacon, params->ssid,
6597 params->ssid_len, params->hidden_ssid);
6598 }
6599
6600 EXIT();
6601 return status;
6602}
6603
6604
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306605static int wlan_hdd_cfg80211_change_beacon(struct wiphy *wiphy,
Jeff Johnson04dd8a82012-06-29 20:41:40 -07006606 struct net_device *dev,
6607 struct cfg80211_beacon_data *params)
6608{
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306609 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +05306610 hdd_context_t *pHddCtx;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05306611 int status;
Jeff Johnson04dd8a82012-06-29 20:41:40 -07006612
6613 ENTER();
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +05306614
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05306615 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
6616 TRACE_CODE_HDD_CFG80211_CHANGE_BEACON,
6617 pAdapter->sessionId, pAdapter->device_mode));
Arif Hussain6d2a3322013-11-17 19:50:10 -08006618 hddLog(VOS_TRACE_LEVEL_INFO, "%s: device_mode = %d",
Jeff Johnson04dd8a82012-06-29 20:41:40 -07006619 __func__, pAdapter->device_mode);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05306620
6621 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
6622 status = wlan_hdd_validate_context(pHddCtx);
6623
6624 if (0 != status)
Madan Mohan Koyyalamudib2c36892012-10-18 20:52:38 -07006625 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05306626 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
6627 "%s: HDD context is not valid", __func__);
6628 return status;
Madan Mohan Koyyalamudib2c36892012-10-18 20:52:38 -07006629 }
Jeff Johnson04dd8a82012-06-29 20:41:40 -07006630
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306631 if ((pAdapter->device_mode == WLAN_HDD_SOFTAP)
Jeff Johnson04dd8a82012-06-29 20:41:40 -07006632 || (pAdapter->device_mode == WLAN_HDD_P2P_GO)
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306633 )
Jeff Johnson04dd8a82012-06-29 20:41:40 -07006634 {
6635 beacon_data_t *old,*new;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306636
Jeff Johnson04dd8a82012-06-29 20:41:40 -07006637 old = pAdapter->sessionCtx.ap.beacon;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306638
Jeff Johnson04dd8a82012-06-29 20:41:40 -07006639 if (!old)
c_hpothu6ff1c3c2013-10-01 19:01:57 +05306640 {
6641 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
6642 FL("session(%d) beacon data points to NULL"),
6643 pAdapter->sessionId);
Jeff Johnson04dd8a82012-06-29 20:41:40 -07006644 return -ENOENT;
c_hpothu6ff1c3c2013-10-01 19:01:57 +05306645 }
Jeff Johnson04dd8a82012-06-29 20:41:40 -07006646
6647 status = wlan_hdd_cfg80211_alloc_new_beacon(pAdapter, &new, params, 0);
6648
6649 if(status != VOS_STATUS_SUCCESS) {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306650 hddLog(VOS_TRACE_LEVEL_FATAL,
Arif Hussain6d2a3322013-11-17 19:50:10 -08006651 "%s: Error!!! Allocating the new beacon",__func__);
Jeff Johnson04dd8a82012-06-29 20:41:40 -07006652 return -EINVAL;
6653 }
6654
6655 pAdapter->sessionCtx.ap.beacon = new;
6656
6657 status = wlan_hdd_cfg80211_start_bss(pAdapter, params, NULL, 0, 0);
6658 }
6659
6660 EXIT();
6661 return status;
6662}
6663
6664#endif //(LINUX_VERSION_CODE > KERNEL_VERSION(3,3,0))
6665
Jeff Johnson295189b2012-06-20 16:38:30 -07006666
Mahesh A Saptasagar179d2252014-06-02 21:32:21 +05306667static int __wlan_hdd_cfg80211_change_bss (struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -07006668 struct net_device *dev,
6669 struct bss_parameters *params)
6670{
6671 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
6672
6673 ENTER();
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +05306674
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05306675 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
6676 TRACE_CODE_HDD_CFG80211_CHANGE_BSS,
6677 pAdapter->sessionId, params->ap_isolate));
Sushant Kaushik8bc7df22014-04-09 17:55:29 +05306678 hddLog(VOS_TRACE_LEVEL_INFO, "%s: device_mode = %s (%d)",
6679 __func__, hdd_device_modetoString(pAdapter->device_mode),
6680 pAdapter->device_mode);
Jeff Johnson295189b2012-06-20 16:38:30 -07006681
6682 if((pAdapter->device_mode == WLAN_HDD_SOFTAP)
Jeff Johnson295189b2012-06-20 16:38:30 -07006683 || (pAdapter->device_mode == WLAN_HDD_P2P_GO)
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306684 )
Jeff Johnson295189b2012-06-20 16:38:30 -07006685 {
6686 /* ap_isolate == -1 means that in change bss, upper layer doesn't
6687 * want to update this parameter */
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306688 if (-1 != params->ap_isolate)
Jeff Johnson295189b2012-06-20 16:38:30 -07006689 {
6690 pAdapter->sessionCtx.ap.apDisableIntraBssFwd = !!params->ap_isolate;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306691 }
Jeff Johnson295189b2012-06-20 16:38:30 -07006692 }
6693
6694 EXIT();
6695 return 0;
6696}
6697
Mahesh A Saptasagar179d2252014-06-02 21:32:21 +05306698static int wlan_hdd_cfg80211_change_bss (struct wiphy *wiphy,
6699 struct net_device *dev,
6700 struct bss_parameters *params)
6701{
6702 int ret;
6703
6704 vos_ssr_protect(__func__);
6705 ret = __wlan_hdd_cfg80211_change_bss(wiphy, dev, params);
6706 vos_ssr_unprotect(__func__);
6707
6708 return ret;
6709}
Kiet Lam10841362013-11-01 11:36:50 +05306710/* FUNCTION: wlan_hdd_change_country_code_cd
6711* to wait for contry code completion
6712*/
6713void* wlan_hdd_change_country_code_cb(void *pAdapter)
6714{
6715 hdd_adapter_t *call_back_pAdapter = pAdapter;
6716 complete(&call_back_pAdapter->change_country_code);
6717 return NULL;
6718}
6719
Jeff Johnson295189b2012-06-20 16:38:30 -07006720/*
Mahesh A Saptasagar0e59c472014-04-14 19:17:41 +05306721 * FUNCTION: __wlan_hdd_cfg80211_change_iface
Jeff Johnson295189b2012-06-20 16:38:30 -07006722 * This function is used to set the interface type (INFRASTRUCTURE/ADHOC)
6723 */
Mahesh A Saptasagar0e59c472014-04-14 19:17:41 +05306724int __wlan_hdd_cfg80211_change_iface( struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -07006725 struct net_device *ndev,
6726 enum nl80211_iftype type,
6727 u32 *flags,
6728 struct vif_params *params
6729 )
6730{
6731 struct wireless_dev *wdev;
6732 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( ndev );
Rajesh Chauhana0516c62014-01-30 16:11:18 -08006733 hdd_context_t *pHddCtx;
Mohit Khanna0f232092012-09-11 14:46:08 -07006734 hdd_adapter_t *pP2pAdapter = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -07006735 tCsrRoamProfile *pRoamProfile = NULL;
6736 eCsrRoamBssType LastBSSType;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05306737 hdd_config_t *pConfig = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -07006738 eMib_dot11DesiredBssType connectedBssType;
6739 VOS_STATUS status;
c_hpothu6ff1c3c2013-10-01 19:01:57 +05306740 long ret;
Jeff Johnson295189b2012-06-20 16:38:30 -07006741
6742 ENTER();
6743
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05306744 if (!pAdapter)
Rajesh Chauhana0516c62014-01-30 16:11:18 -08006745 {
6746 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
6747 "%s: Adapter context is null", __func__);
6748 return VOS_STATUS_E_FAILURE;
6749 }
6750
6751 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
6752 if (!pHddCtx)
6753 {
6754 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
6755 "%s: HDD context is null", __func__);
6756 return VOS_STATUS_E_FAILURE;
6757 }
6758
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05306759 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
6760 TRACE_CODE_HDD_CFG80211_CHANGE_IFACE,
6761 pAdapter->sessionId, type));
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05306762 status = wlan_hdd_validate_context(pHddCtx);
6763
6764 if (0 != status)
Jeff Johnson295189b2012-06-20 16:38:30 -07006765 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05306766 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
6767 "%s: HDD context is not valid", __func__);
6768 return status;
Jeff Johnson295189b2012-06-20 16:38:30 -07006769 }
6770
Sushant Kaushik8bc7df22014-04-09 17:55:29 +05306771 hddLog(VOS_TRACE_LEVEL_INFO, "%s: device_mode = %s (%d)",
6772 __func__, hdd_device_modetoString(pAdapter->device_mode),
6773 pAdapter->device_mode);
Jeff Johnson295189b2012-06-20 16:38:30 -07006774
Agarwal Ashish51325b52014-06-16 16:50:49 +05306775 if (vos_max_concurrent_connections_reached()) {
6776 hddLog(VOS_TRACE_LEVEL_INFO, FL("Reached max concurrent connections"));
6777 return -EINVAL;
6778 }
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05306779 pConfig = pHddCtx->cfg_ini;
Jeff Johnson295189b2012-06-20 16:38:30 -07006780 wdev = ndev->ieee80211_ptr;
6781
6782#ifdef WLAN_BTAMP_FEATURE
6783 if((NL80211_IFTYPE_P2P_CLIENT == type)||
6784 (NL80211_IFTYPE_ADHOC == type)||
6785 (NL80211_IFTYPE_AP == type)||
6786 (NL80211_IFTYPE_P2P_GO == type))
6787 {
6788 pHddCtx->isAmpAllowed = VOS_FALSE;
6789 // stop AMP traffic
6790 status = WLANBAP_StopAmp();
6791 if(VOS_STATUS_SUCCESS != status )
6792 {
6793 pHddCtx->isAmpAllowed = VOS_TRUE;
6794 hddLog(VOS_TRACE_LEVEL_FATAL,
6795 "%s: Failed to stop AMP", __func__);
6796 return -EINVAL;
6797 }
6798 }
6799#endif //WLAN_BTAMP_FEATURE
6800 /* Reset the current device mode bit mask*/
6801 wlan_hdd_clear_concurrency_mode(pHddCtx, pAdapter->device_mode);
6802
6803 if( (pAdapter->device_mode == WLAN_HDD_INFRA_STATION)
Jeff Johnson295189b2012-06-20 16:38:30 -07006804 || (pAdapter->device_mode == WLAN_HDD_P2P_CLIENT)
Jeff Johnsone7245742012-09-05 17:12:55 -07006805 || (pAdapter->device_mode == WLAN_HDD_P2P_DEVICE)
Jeff Johnson295189b2012-06-20 16:38:30 -07006806 )
6807 {
6808 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
Rajesh Chauhana0516c62014-01-30 16:11:18 -08006809 if (!pWextState)
6810 {
6811 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
6812 "%s: pWextState is null", __func__);
6813 return VOS_STATUS_E_FAILURE;
6814 }
Jeff Johnson295189b2012-06-20 16:38:30 -07006815 pRoamProfile = &pWextState->roamProfile;
6816 LastBSSType = pRoamProfile->BSSType;
6817
6818 switch (type)
6819 {
6820 case NL80211_IFTYPE_STATION:
Jeff Johnson295189b2012-06-20 16:38:30 -07006821 case NL80211_IFTYPE_P2P_CLIENT:
Jeff Johnson295189b2012-06-20 16:38:30 -07006822 hddLog(VOS_TRACE_LEVEL_INFO,
6823 "%s: setting interface Type to INFRASTRUCTURE", __func__);
6824 pRoamProfile->BSSType = eCSR_BSS_TYPE_INFRASTRUCTURE;
Jeff Johnsone7245742012-09-05 17:12:55 -07006825#ifdef WLAN_FEATURE_11AC
6826 if(pConfig->dot11Mode == eHDD_DOT11_MODE_AUTO)
6827 {
6828 pConfig->dot11Mode = eHDD_DOT11_MODE_11ac;
6829 }
6830#endif
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306831 pRoamProfile->phyMode =
Jeff Johnsone7245742012-09-05 17:12:55 -07006832 hdd_cfg_xlate_to_csr_phy_mode(pConfig->dot11Mode);
Jeff Johnson295189b2012-06-20 16:38:30 -07006833 wdev->iftype = type;
Gopichand Nakkalaf527dc62012-12-31 16:35:10 -08006834 //Check for sub-string p2p to confirm its a p2p interface
6835 if (NULL != strstr(ndev->name,"p2p"))
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306836 {
Gopichand Nakkala864d3552012-12-31 16:08:51 -08006837 pAdapter->device_mode = (type == NL80211_IFTYPE_STATION) ?
6838 WLAN_HDD_P2P_DEVICE : WLAN_HDD_P2P_CLIENT;
6839 }
6840 else
6841 {
6842 pAdapter->device_mode = (type == NL80211_IFTYPE_STATION) ?
Jeff Johnson295189b2012-06-20 16:38:30 -07006843 WLAN_HDD_INFRA_STATION: WLAN_HDD_P2P_CLIENT;
Gopichand Nakkala864d3552012-12-31 16:08:51 -08006844 }
Madan Mohan Koyyalamudi81746922013-07-17 14:38:51 +05306845#ifdef FEATURE_WLAN_TDLS
6846 /* The open adapter for the p2p shall skip initializations in
6847 * tdls_init if the device mode is WLAN_HDD_P2P_DEVICE, for
6848 * TDLS is supported only on WLAN_HDD_P2P_CLIENT. Hence invoke
6849 * tdls_init when the change_iface sets the device mode to
6850 * WLAN_HDD_P2P_CLIENT.
6851 */
6852
6853 if ( pAdapter->device_mode == WLAN_HDD_P2P_CLIENT)
6854 {
Agarwal Ashish4b87f922014-06-18 03:03:21 +05306855 if (0 != wlan_hdd_sta_tdls_init (pAdapter))
Madan Mohan Koyyalamudi81746922013-07-17 14:38:51 +05306856 {
c_hpothu6ff1c3c2013-10-01 19:01:57 +05306857 hddLog(VOS_TRACE_LEVEL_ERROR,
6858 "%s: tdls initialization failed", __func__);
Madan Mohan Koyyalamudi81746922013-07-17 14:38:51 +05306859 return -EINVAL;
6860 }
6861 }
6862#endif
6863
Jeff Johnson295189b2012-06-20 16:38:30 -07006864 break;
6865 case NL80211_IFTYPE_ADHOC:
6866 hddLog(VOS_TRACE_LEVEL_INFO,
6867 "%s: setting interface Type to ADHOC", __func__);
6868 pRoamProfile->BSSType = eCSR_BSS_TYPE_START_IBSS;
6869 pRoamProfile->phyMode =
6870 hdd_cfg_xlate_to_csr_phy_mode(pConfig->dot11Mode);
Shailender Karmuchia734f332013-04-19 14:02:48 -07006871 pAdapter->device_mode = WLAN_HDD_IBSS;
Jeff Johnson295189b2012-06-20 16:38:30 -07006872 wdev->iftype = type;
6873 break;
6874
6875 case NL80211_IFTYPE_AP:
Jeff Johnson295189b2012-06-20 16:38:30 -07006876 case NL80211_IFTYPE_P2P_GO:
Jeff Johnson295189b2012-06-20 16:38:30 -07006877 {
6878 hddLog(VOS_TRACE_LEVEL_INFO_HIGH,
6879 "%s: setting interface Type to %s", __func__,
6880 (type == NL80211_IFTYPE_AP) ? "SoftAP" : "P2pGo");
6881
Gopichand Nakkalaf527dc62012-12-31 16:35:10 -08006882 //Cancel any remain on channel for GO mode
6883 if (NL80211_IFTYPE_P2P_GO == type)
6884 {
6885 wlan_hdd_cancel_existing_remain_on_channel(pAdapter);
6886 }
Mohit Khanna0f232092012-09-11 14:46:08 -07006887 if (NL80211_IFTYPE_AP == type)
6888 {
6889 /* As Loading WLAN Driver one interface being created for p2p device
6890 * address. This will take one HW STA and the max number of clients
6891 * that can connect to softAP will be reduced by one. so while changing
6892 * the interface type to NL80211_IFTYPE_AP (SoftAP) remove p2p0
6893 * interface as it is not required in SoftAP mode.
6894 */
6895
6896 // Get P2P Adapter
6897 pP2pAdapter = hdd_get_adapter(pHddCtx, WLAN_HDD_P2P_DEVICE);
6898
6899 if (pP2pAdapter)
6900 {
Agarwal Ashish3a38bd12014-06-12 15:16:52 +05306901 hdd_stop_adapter(pHddCtx, pP2pAdapter, VOS_TRUE);
Mohit Khanna0f232092012-09-11 14:46:08 -07006902 hdd_deinit_adapter(pHddCtx, pP2pAdapter);
6903 hdd_close_adapter(pHddCtx, pP2pAdapter, VOS_TRUE);
6904 }
6905 }
Swaroop Goltia2e32212014-04-09 23:37:33 +05306906 //Disable IMPS & BMPS for SAP/GO
6907 if(VOS_STATUS_E_FAILURE ==
6908 hdd_disable_bmps_imps(pHddCtx, WLAN_HDD_P2P_GO))
6909 {
6910 //Fail to Exit BMPS
6911 VOS_ASSERT(0);
6912 }
Deepthi Gowri500fc472014-08-11 19:53:10 +05306913
6914 hdd_stop_adapter( pHddCtx, pAdapter, VOS_TRUE );
6915
Madan Mohan Koyyalamudi96797442013-10-08 16:04:42 +05306916#ifdef FEATURE_WLAN_TDLS
Mohit Khanna0f232092012-09-11 14:46:08 -07006917
Madan Mohan Koyyalamudi96797442013-10-08 16:04:42 +05306918 /* A Mutex Lock is introduced while changing the mode to
6919 * protect the concurrent access for the Adapters by TDLS
6920 * module.
6921 */
Rajesh Chauhana34c6e62014-03-25 16:37:58 +05306922 mutex_lock(&pHddCtx->tdls_lock);
Madan Mohan Koyyalamudi96797442013-10-08 16:04:42 +05306923#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07006924 //De-init the adapter.
Jeff Johnson295189b2012-06-20 16:38:30 -07006925 hdd_deinit_adapter( pHddCtx, pAdapter );
6926 memset(&pAdapter->sessionCtx, 0, sizeof(pAdapter->sessionCtx));
Jeff Johnson295189b2012-06-20 16:38:30 -07006927 pAdapter->device_mode = (type == NL80211_IFTYPE_AP) ?
6928 WLAN_HDD_SOFTAP : WLAN_HDD_P2P_GO;
Madan Mohan Koyyalamudi96797442013-10-08 16:04:42 +05306929#ifdef FEATURE_WLAN_TDLS
6930 mutex_unlock(&pHddCtx->tdls_lock);
6931#endif
Madan Mohan Koyyalamudi3ff2a0b2012-10-15 14:33:46 -07006932 if ((WLAN_HDD_SOFTAP == pAdapter->device_mode) &&
6933 (pConfig->apRandomBssidEnabled))
6934 {
6935 /* To meet Android requirements create a randomized
6936 MAC address of the form 02:1A:11:Fx:xx:xx */
6937 get_random_bytes(&ndev->dev_addr[3], 3);
6938 ndev->dev_addr[0] = 0x02;
6939 ndev->dev_addr[1] = 0x1A;
6940 ndev->dev_addr[2] = 0x11;
6941 ndev->dev_addr[3] |= 0xF0;
6942 memcpy(pAdapter->macAddressCurrent.bytes, ndev->dev_addr,
6943 VOS_MAC_ADDR_SIZE);
Arif Hussain24bafea2013-11-15 15:10:03 -08006944 pr_info("wlan: Generated HotSpot BSSID " MAC_ADDRESS_STR"\n",
6945 MAC_ADDR_ARRAY(ndev->dev_addr));
Madan Mohan Koyyalamudi3ff2a0b2012-10-15 14:33:46 -07006946 }
6947
Jeff Johnson295189b2012-06-20 16:38:30 -07006948 hdd_set_ap_ops( pAdapter->dev );
6949
Kiet Lam10841362013-11-01 11:36:50 +05306950 /* This is for only SAP mode where users can
6951 * control country through ini.
6952 * P2P GO follows station country code
6953 * acquired during the STA scanning. */
6954 if((NL80211_IFTYPE_AP == type) &&
6955 (memcmp(pConfig->apCntryCode, CFG_AP_COUNTRY_CODE_DEFAULT, 3) != 0))
6956 {
6957 int status = 0;
6958 VOS_TRACE(VOS_MODULE_ID_HDD,VOS_TRACE_LEVEL_INFO,
6959 "%s: setting country code from INI ", __func__);
6960 init_completion(&pAdapter->change_country_code);
6961 status = (int)sme_ChangeCountryCode(pHddCtx->hHal,
6962 (void *)(tSmeChangeCountryCallback)
6963 wlan_hdd_change_country_code_cb,
6964 pConfig->apCntryCode, pAdapter,
6965 pHddCtx->pvosContext,
Abhishek Singha306a442013-11-07 18:39:01 +05306966 eSIR_FALSE,
6967 eSIR_TRUE);
Kiet Lam10841362013-11-01 11:36:50 +05306968 if (eHAL_STATUS_SUCCESS == status)
6969 {
6970 /* Wait for completion */
c_hpothu6ff1c3c2013-10-01 19:01:57 +05306971 ret = wait_for_completion_interruptible_timeout(
Kiet Lam10841362013-11-01 11:36:50 +05306972 &pAdapter->change_country_code,
6973 msecs_to_jiffies(WLAN_WAIT_TIME_COUNTRY));
c_hpothu6ff1c3c2013-10-01 19:01:57 +05306974 if (ret <= 0)
Kiet Lam10841362013-11-01 11:36:50 +05306975 {
6976 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
c_hpothu6ff1c3c2013-10-01 19:01:57 +05306977 FL("SME Timed out while setting country code %ld"),
6978 ret);
Yue Ma4f55ef32014-01-23 16:45:33 -08006979
6980 if (pHddCtx->isLogpInProgress)
6981 {
6982 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
6983 "%s: LOGP in Progress. Ignore!!!", __func__);
6984 return -EAGAIN;
6985 }
Kiet Lam10841362013-11-01 11:36:50 +05306986 }
6987 }
6988 else
6989 {
6990 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Arif Hussain6d2a3322013-11-17 19:50:10 -08006991 "%s: SME Change Country code failed",__func__);
Kiet Lam10841362013-11-01 11:36:50 +05306992 return -EINVAL;
6993 }
6994 }
Jeff Johnson295189b2012-06-20 16:38:30 -07006995 status = hdd_init_ap_mode(pAdapter);
6996 if(status != VOS_STATUS_SUCCESS)
6997 {
6998 hddLog(VOS_TRACE_LEVEL_FATAL,
6999 "%s: Error initializing the ap mode", __func__);
7000 return -EINVAL;
7001 }
7002 hdd_set_conparam(1);
7003
Jeff Johnson295189b2012-06-20 16:38:30 -07007004 /*interface type changed update in wiphy structure*/
7005 if(wdev)
7006 {
7007 wdev->iftype = type;
7008 pHddCtx->change_iface = type;
7009 }
7010 else
7011 {
7012 hddLog(VOS_TRACE_LEVEL_ERROR,
7013 "%s: ERROR !!!! Wireless dev is NULL", __func__);
7014 return -EINVAL;
7015 }
7016 goto done;
7017 }
7018
7019 default:
7020 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Unsupported interface Type",
7021 __func__);
7022 return -EOPNOTSUPP;
7023 }
7024 }
7025 else if ( (pAdapter->device_mode == WLAN_HDD_SOFTAP)
Jeff Johnson295189b2012-06-20 16:38:30 -07007026 || (pAdapter->device_mode == WLAN_HDD_P2P_GO)
Jeff Johnson295189b2012-06-20 16:38:30 -07007027 )
7028 {
7029 switch(type)
7030 {
7031 case NL80211_IFTYPE_STATION:
Jeff Johnson295189b2012-06-20 16:38:30 -07007032 case NL80211_IFTYPE_P2P_CLIENT:
Jeff Johnson295189b2012-06-20 16:38:30 -07007033 case NL80211_IFTYPE_ADHOC:
Deepthi Gowri500fc472014-08-11 19:53:10 +05307034
7035 hdd_stop_adapter( pHddCtx, pAdapter, VOS_TRUE );
Madan Mohan Koyyalamudi96797442013-10-08 16:04:42 +05307036#ifdef FEATURE_WLAN_TDLS
7037
7038 /* A Mutex Lock is introduced while changing the mode to
7039 * protect the concurrent access for the Adapters by TDLS
7040 * module.
7041 */
Rajesh Chauhana34c6e62014-03-25 16:37:58 +05307042 mutex_lock(&pHddCtx->tdls_lock);
Madan Mohan Koyyalamudi96797442013-10-08 16:04:42 +05307043#endif
Jeff Johnson32d95a32012-09-10 13:15:23 -07007044 hdd_deinit_adapter( pHddCtx, pAdapter );
Jeff Johnson295189b2012-06-20 16:38:30 -07007045 wdev->iftype = type;
Gopichand Nakkalaf527dc62012-12-31 16:35:10 -08007046 //Check for sub-string p2p to confirm its a p2p interface
7047 if (NULL != strstr(ndev->name,"p2p"))
Gopichand Nakkala864d3552012-12-31 16:08:51 -08007048 {
7049 pAdapter->device_mode = (type == NL80211_IFTYPE_STATION) ?
7050 WLAN_HDD_P2P_DEVICE : WLAN_HDD_P2P_CLIENT;
7051 }
7052 else
7053 {
7054 pAdapter->device_mode = (type == NL80211_IFTYPE_STATION) ?
Jeff Johnson295189b2012-06-20 16:38:30 -07007055 WLAN_HDD_INFRA_STATION: WLAN_HDD_P2P_CLIENT;
Gopichand Nakkala864d3552012-12-31 16:08:51 -08007056 }
Jeff Johnson295189b2012-06-20 16:38:30 -07007057 hdd_set_conparam(0);
7058 pHddCtx->change_iface = type;
Jeff Johnson295189b2012-06-20 16:38:30 -07007059 memset(&pAdapter->sessionCtx, 0, sizeof(pAdapter->sessionCtx));
7060 hdd_set_station_ops( pAdapter->dev );
Madan Mohan Koyyalamudi96797442013-10-08 16:04:42 +05307061#ifdef FEATURE_WLAN_TDLS
7062 mutex_unlock(&pHddCtx->tdls_lock);
7063#endif
Sunil Dutt66485cb2013-12-19 19:05:03 +05307064 status = hdd_init_station_mode( pAdapter );
Jeff Johnson295189b2012-06-20 16:38:30 -07007065 if( VOS_STATUS_SUCCESS != status )
7066 return -EOPNOTSUPP;
Jeff Johnsone7245742012-09-05 17:12:55 -07007067 /* In case of JB, for P2P-GO, only change interface will be called,
7068 * This is the right place to enable back bmps_imps()
7069 */
Gopichand Nakkalaa2fe5b02013-06-06 16:32:28 +05307070 if (pHddCtx->hdd_wlan_suspended)
7071 {
7072 hdd_set_pwrparams(pHddCtx);
7073 }
Jeff Johnsone7245742012-09-05 17:12:55 -07007074 hdd_enable_bmps_imps(pHddCtx);
Jeff Johnson295189b2012-06-20 16:38:30 -07007075 goto done;
7076 case NL80211_IFTYPE_AP:
Jeff Johnson295189b2012-06-20 16:38:30 -07007077 case NL80211_IFTYPE_P2P_GO:
Jeff Johnson295189b2012-06-20 16:38:30 -07007078 wdev->iftype = type;
Jeff Johnson295189b2012-06-20 16:38:30 -07007079 pAdapter->device_mode = (type == NL80211_IFTYPE_AP) ?
7080 WLAN_HDD_SOFTAP : WLAN_HDD_P2P_GO;
Jeff Johnson295189b2012-06-20 16:38:30 -07007081 goto done;
7082 default:
7083 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Unsupported interface Type",
7084 __func__);
7085 return -EOPNOTSUPP;
7086
7087 }
7088
7089 }
7090 else
7091 {
Sushant Kaushik8bc7df22014-04-09 17:55:29 +05307092 hddLog(VOS_TRACE_LEVEL_ERROR,"%s: unsupported device mode(%s (%d))",
7093 __func__, hdd_device_modetoString(pAdapter->device_mode),
7094 pAdapter->device_mode);
Jeff Johnson295189b2012-06-20 16:38:30 -07007095 return -EOPNOTSUPP;
7096 }
7097
7098
7099 if(pRoamProfile)
7100 {
7101 if ( LastBSSType != pRoamProfile->BSSType )
7102 {
7103 /*interface type changed update in wiphy structure*/
7104 wdev->iftype = type;
7105
7106 /*the BSS mode changed, We need to issue disconnect
7107 if connected or in IBSS disconnect state*/
7108 if ( hdd_connGetConnectedBssType(
7109 WLAN_HDD_GET_STATION_CTX_PTR(pAdapter), &connectedBssType ) ||
7110 ( eCSR_BSS_TYPE_START_IBSS == LastBSSType ) )
7111 {
7112 /*need to issue a disconnect to CSR.*/
7113 INIT_COMPLETION(pAdapter->disconnect_comp_var);
7114 if( eHAL_STATUS_SUCCESS ==
7115 sme_RoamDisconnect( WLAN_HDD_GET_HAL_CTX(pAdapter),
7116 pAdapter->sessionId,
7117 eCSR_DISCONNECT_REASON_UNSPECIFIED ) )
7118 {
c_hpothu6ff1c3c2013-10-01 19:01:57 +05307119 ret = wait_for_completion_interruptible_timeout(
7120 &pAdapter->disconnect_comp_var,
7121 msecs_to_jiffies(WLAN_WAIT_TIME_DISCONNECT));
7122 if (ret <= 0)
7123 {
7124 hddLog(VOS_TRACE_LEVEL_ERROR,
7125 FL("wait on disconnect_comp_var failed %ld"), ret);
7126 }
Jeff Johnson295189b2012-06-20 16:38:30 -07007127 }
7128 }
7129 }
7130 }
7131
7132done:
7133 /*set bitmask based on updated value*/
7134 wlan_hdd_set_concurrency_mode(pHddCtx, pAdapter->device_mode);
Leo Chang6fe1f922013-06-07 19:21:24 -07007135
7136 /* Only STA mode support TM now
7137 * all other mode, TM feature should be disabled */
7138 if ( (pHddCtx->cfg_ini->thermalMitigationEnable) &&
7139 (~VOS_STA & pHddCtx->concurrency_mode) )
7140 {
7141 hddDevTmLevelChangedHandler(pHddCtx->parent_dev, 0);
7142 }
7143
Jeff Johnson295189b2012-06-20 16:38:30 -07007144#ifdef WLAN_BTAMP_FEATURE
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307145 if((NL80211_IFTYPE_STATION == type) && (pHddCtx->concurrency_mode <= 1) &&
Agarwal Ashish51325b52014-06-16 16:50:49 +05307146 (pHddCtx->no_of_open_sessions[WLAN_HDD_INFRA_STATION] <=1))
Jeff Johnson295189b2012-06-20 16:38:30 -07007147 {
7148 //we are ok to do AMP
7149 pHddCtx->isAmpAllowed = VOS_TRUE;
7150 }
7151#endif //WLAN_BTAMP_FEATURE
7152 EXIT();
7153 return 0;
7154}
7155
Mahesh A Saptasagar0e59c472014-04-14 19:17:41 +05307156/*
7157 * FUNCTION: wlan_hdd_cfg80211_change_iface
7158 * wrapper function to protect the actual implementation from SSR.
7159 */
7160int wlan_hdd_cfg80211_change_iface( struct wiphy *wiphy,
7161 struct net_device *ndev,
7162 enum nl80211_iftype type,
7163 u32 *flags,
7164 struct vif_params *params
7165 )
7166{
7167 int ret;
7168
7169 vos_ssr_protect(__func__);
7170 ret = __wlan_hdd_cfg80211_change_iface(wiphy, ndev, type, flags, params);
7171 vos_ssr_unprotect(__func__);
7172
7173 return ret;
7174}
7175
Gopichand Nakkala681989c2013-03-06 22:27:48 -08007176#ifdef FEATURE_WLAN_TDLS
7177static int wlan_hdd_tdls_add_station(struct wiphy *wiphy,
7178 struct net_device *dev, u8 *mac, bool update, tCsrStaParams *StaParams)
7179{
7180 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
7181 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
7182 VOS_STATUS status;
Hoonki Lee5305c3a2013-04-29 23:28:59 -07007183 hddTdlsPeer_t *pTdlsPeer;
c_hpothu6ff1c3c2013-10-01 19:01:57 +05307184 long ret;
Rajesh Chauhana34c6e62014-03-25 16:37:58 +05307185 tANI_U16 numCurrTdlsPeers;
Gopichand Nakkala681989c2013-03-06 22:27:48 -08007186
7187 ENTER();
7188
Gopichand Nakkala838be5d2013-04-10 22:41:51 +05307189 if (NULL == pHddCtx || NULL == pHddCtx->cfg_ini)
Gopichand Nakkala681989c2013-03-06 22:27:48 -08007190 {
7191 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
7192 "Invalid arguments");
7193 return -EINVAL;
7194 }
Hoonki Lee27511902013-03-14 18:19:06 -07007195
7196 if ((eTDLS_SUPPORT_NOT_ENABLED == pHddCtx->tdls_mode) ||
7197 (eTDLS_SUPPORT_DISABLED == pHddCtx->tdls_mode))
7198 {
7199 VOS_TRACE( VOS_MODULE_ID_HDD, TDLS_LOG_LEVEL,
7200 "%s: TDLS mode is disabled OR not enabled in FW."
7201 MAC_ADDRESS_STR " Request declined.",
7202 __func__, MAC_ADDR_ARRAY(mac));
7203 return -ENOTSUPP;
7204 }
7205
Gopichand Nakkala681989c2013-03-06 22:27:48 -08007206 if (pHddCtx->isLogpInProgress)
7207 {
7208 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
7209 "%s:LOGP in Progress. Ignore!!!", __func__);
Atul Mittal115287b2014-07-08 13:26:33 +05307210 wlan_hdd_tdls_set_link_status(pAdapter,
7211 mac,
7212 eTDLS_LINK_IDLE,
7213 eTDLS_LINK_UNSPECIFIED);
Gopichand Nakkala681989c2013-03-06 22:27:48 -08007214 return -EBUSY;
7215 }
7216
Naresh Jayaram9c6f4462014-02-13 12:20:31 +05307217 pTdlsPeer = wlan_hdd_tdls_get_peer(pAdapter, mac);
Hoonki Lee5305c3a2013-04-29 23:28:59 -07007218
7219 if ( NULL == pTdlsPeer ) {
7220 VOS_TRACE( VOS_MODULE_ID_HDD, TDLS_LOG_LEVEL,
7221 "%s: " MAC_ADDRESS_STR " (update %d) not exist. return invalid",
7222 __func__, MAC_ADDR_ARRAY(mac), update);
7223 return -EINVAL;
Gopichand Nakkala34d1b062013-03-19 15:28:33 -07007224 }
Hoonki Lee5305c3a2013-04-29 23:28:59 -07007225
7226 /* in add station, we accept existing valid staId if there is */
7227 if ((0 == update) &&
7228 ((pTdlsPeer->link_status >= eTDLS_LINK_CONNECTING) ||
7229 (TDLS_STA_INDEX_VALID(pTdlsPeer->staId))))
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -07007230 {
Hoonki Lee5305c3a2013-04-29 23:28:59 -07007231 VOS_TRACE( VOS_MODULE_ID_HDD, TDLS_LOG_LEVEL,
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -07007232 "%s: " MAC_ADDRESS_STR
Hoonki Lee5305c3a2013-04-29 23:28:59 -07007233 " link_status %d. staId %d. add station ignored.",
7234 __func__, MAC_ADDR_ARRAY(mac), pTdlsPeer->link_status, pTdlsPeer->staId);
7235 return 0;
7236 }
7237 /* in change station, we accept only when staId is valid */
7238 if ((1 == update) &&
7239 ((pTdlsPeer->link_status > eTDLS_LINK_CONNECTING) ||
7240 (!TDLS_STA_INDEX_VALID(pTdlsPeer->staId))))
7241 {
7242 VOS_TRACE( VOS_MODULE_ID_HDD, TDLS_LOG_LEVEL,
7243 "%s: " MAC_ADDRESS_STR
7244 " link status %d. staId %d. change station %s.",
7245 __func__, MAC_ADDR_ARRAY(mac), pTdlsPeer->link_status, pTdlsPeer->staId,
7246 (TDLS_STA_INDEX_VALID(pTdlsPeer->staId)) ? "ignored" : "declined");
7247 return (TDLS_STA_INDEX_VALID(pTdlsPeer->staId)) ? 0 : -EPERM;
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -07007248 }
Gopichand Nakkala34d1b062013-03-19 15:28:33 -07007249
7250 /* when others are on-going, we want to change link_status to idle */
Madan Mohan Koyyalamudi96797442013-10-08 16:04:42 +05307251 if (NULL != wlan_hdd_tdls_is_progress(pHddCtx, mac, TRUE))
Gopichand Nakkala681989c2013-03-06 22:27:48 -08007252 {
Gopichand Nakkalac87400e2013-03-13 18:51:00 -07007253 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
7254 "%s: " MAC_ADDRESS_STR
7255 " TDLS setup is ongoing. Request declined.",
7256 __func__, MAC_ADDR_ARRAY(mac));
Gopichand Nakkala05922802013-03-14 12:23:19 -07007257 goto error;
Gopichand Nakkala681989c2013-03-06 22:27:48 -08007258 }
7259
7260 /* first to check if we reached to maximum supported TDLS peer.
7261 TODO: for now, return -EPERM looks working fine,
7262 but need to check if any other errno fit into this category.*/
Rajesh Chauhana34c6e62014-03-25 16:37:58 +05307263 numCurrTdlsPeers = wlan_hdd_tdlsConnectedPeers(pAdapter);
7264 if (HDD_MAX_NUM_TDLS_STA <= numCurrTdlsPeers)
Gopichand Nakkala681989c2013-03-06 22:27:48 -08007265 {
Gopichand Nakkalac87400e2013-03-13 18:51:00 -07007266 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
7267 "%s: " MAC_ADDRESS_STR
Rajesh Chauhana34c6e62014-03-25 16:37:58 +05307268 " TDLS Max peer already connected. Request declined."
7269 " Num of peers (%d), Max allowed (%d).",
7270 __func__, MAC_ADDR_ARRAY(mac), numCurrTdlsPeers,
7271 HDD_MAX_NUM_TDLS_STA);
Gopichand Nakkala05922802013-03-14 12:23:19 -07007272 goto error;
Gopichand Nakkala681989c2013-03-06 22:27:48 -08007273 }
7274 else
7275 {
7276 hddTdlsPeer_t *pTdlsPeer;
Madan Mohan Koyyalamudi96797442013-10-08 16:04:42 +05307277 pTdlsPeer = wlan_hdd_tdls_find_peer(pAdapter, mac, TRUE);
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -07007278 if (pTdlsPeer && TDLS_IS_CONNECTED(pTdlsPeer))
Gopichand Nakkala681989c2013-03-06 22:27:48 -08007279 {
Gopichand Nakkalac87400e2013-03-13 18:51:00 -07007280 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
7281 "%s: " MAC_ADDRESS_STR " already connected. Request declined.",
7282 __func__, MAC_ADDR_ARRAY(mac));
Gopichand Nakkala681989c2013-03-06 22:27:48 -08007283 return -EPERM;
7284 }
7285 }
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -07007286 if (0 == update)
Atul Mittal115287b2014-07-08 13:26:33 +05307287 wlan_hdd_tdls_set_link_status(pAdapter,
7288 mac,
7289 eTDLS_LINK_CONNECTING,
7290 eTDLS_LINK_SUCCESS);
Gopichand Nakkala681989c2013-03-06 22:27:48 -08007291
Jeff Johnsond75fe012013-04-06 10:53:06 -07007292 /* debug code */
Gopichand Nakkala838be5d2013-04-10 22:41:51 +05307293 if (NULL != StaParams)
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -07007294 {
7295 VOS_TRACE(VOS_MODULE_ID_HDD, TDLS_LOG_LEVEL,
7296 "%s: TDLS Peer Parameters.", __func__);
Hoonki Lee66b75f32013-04-16 18:30:07 -07007297 if(StaParams->htcap_present)
7298 {
7299 VOS_TRACE(VOS_MODULE_ID_HDD, TDLS_LOG_LEVEL,
7300 "ht_capa->cap_info: %0x", StaParams->HTCap.capInfo);
7301 VOS_TRACE(VOS_MODULE_ID_HDD, TDLS_LOG_LEVEL,
7302 "ht_capa->extended_capabilities: %0x",
7303 StaParams->HTCap.extendedHtCapInfo);
7304 }
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -07007305 VOS_TRACE(VOS_MODULE_ID_HDD, TDLS_LOG_LEVEL,
7306 "params->capability: %0x",StaParams->capability);
7307 VOS_TRACE(VOS_MODULE_ID_HDD, TDLS_LOG_LEVEL,
Jeff Johnson0299d0a2013-10-30 12:37:43 -07007308 "params->ext_capab_len: %0x",StaParams->extn_capability[0]);
Hoonki Lee66b75f32013-04-16 18:30:07 -07007309 if(StaParams->vhtcap_present)
7310 {
7311 VOS_TRACE(VOS_MODULE_ID_HDD, TDLS_LOG_LEVEL,
7312 "rxMcsMap %x rxHighest %x txMcsMap %x txHighest %x",
7313 StaParams->VHTCap.suppMcs.rxMcsMap, StaParams->VHTCap.suppMcs.rxHighest,
7314 StaParams->VHTCap.suppMcs.txMcsMap, StaParams->VHTCap.suppMcs.txHighest);
7315 }
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -07007316 {
7317 int i = 0;
Hoonki Lee5305c3a2013-04-29 23:28:59 -07007318 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO, "Supported rates:");
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -07007319 for (i = 0; i < sizeof(StaParams->supported_rates); i++)
7320 VOS_TRACE(VOS_MODULE_ID_HDD, TDLS_LOG_LEVEL,
7321 "[%d]: %x ", i, StaParams->supported_rates[i]);
7322 }
Jeff Johnsond75fe012013-04-06 10:53:06 -07007323 } /* end debug code */
Gopichand Nakkala838be5d2013-04-10 22:41:51 +05307324 else if ((1 == update) && (NULL == StaParams))
7325 {
7326 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
7327 "%s : update is true, but staParams is NULL. Error!", __func__);
7328 return -EPERM;
7329 }
Gopichand Nakkala681989c2013-03-06 22:27:48 -08007330
7331 INIT_COMPLETION(pAdapter->tdls_add_station_comp);
7332
7333 if (!update)
7334 {
7335 status = sme_AddTdlsPeerSta(WLAN_HDD_GET_HAL_CTX(pAdapter),
7336 pAdapter->sessionId, mac);
7337 }
7338 else
7339 {
7340 status = sme_ChangeTdlsPeerSta(WLAN_HDD_GET_HAL_CTX(pAdapter),
7341 pAdapter->sessionId, mac, StaParams);
7342 }
7343
c_hpothu6ff1c3c2013-10-01 19:01:57 +05307344 ret = wait_for_completion_interruptible_timeout(&pAdapter->tdls_add_station_comp,
Gopichand Nakkala681989c2013-03-06 22:27:48 -08007345 msecs_to_jiffies(WAIT_TIME_TDLS_ADD_STA));
7346
c_hpothu6ff1c3c2013-10-01 19:01:57 +05307347 if (ret <= 0)
Gopichand Nakkala681989c2013-03-06 22:27:48 -08007348 {
Gopichand Nakkalac87400e2013-03-13 18:51:00 -07007349 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
c_hpothu6ff1c3c2013-10-01 19:01:57 +05307350 "%s: timeout waiting for tdls add station indication %ld",
7351 __func__, ret);
Gopichand Nakkala34d1b062013-03-19 15:28:33 -07007352 return -EPERM;
Gopichand Nakkala681989c2013-03-06 22:27:48 -08007353 }
c_hpothu6ff1c3c2013-10-01 19:01:57 +05307354
Gopichand Nakkala681989c2013-03-06 22:27:48 -08007355 if ( eHAL_STATUS_SUCCESS != pAdapter->tdlsAddStaStatus)
7356 {
Gopichand Nakkalac87400e2013-03-13 18:51:00 -07007357 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Gopichand Nakkala681989c2013-03-06 22:27:48 -08007358 "%s: Add Station is unsucessful", __func__);
Gopichand Nakkala34d1b062013-03-19 15:28:33 -07007359 return -EPERM;
Gopichand Nakkala681989c2013-03-06 22:27:48 -08007360 }
7361
7362 return 0;
Gopichand Nakkala05922802013-03-14 12:23:19 -07007363
7364error:
Atul Mittal115287b2014-07-08 13:26:33 +05307365 wlan_hdd_tdls_set_link_status(pAdapter,
7366 mac,
7367 eTDLS_LINK_IDLE,
7368 eTDLS_LINK_UNSPECIFIED);
Gopichand Nakkala05922802013-03-14 12:23:19 -07007369 return -EPERM;
7370
Gopichand Nakkala681989c2013-03-06 22:27:48 -08007371}
7372#endif
7373
Jeff Johnson295189b2012-06-20 16:38:30 -07007374static int wlan_hdd_change_station(struct wiphy *wiphy,
7375 struct net_device *dev,
7376 u8 *mac,
7377 struct station_parameters *params)
7378{
7379 VOS_STATUS status = VOS_STATUS_SUCCESS;
7380 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( dev );
Gopichand Nakkala29149562013-05-10 21:43:41 +05307381 hdd_context_t *pHddCtx;
7382 hdd_station_ctx_t *pHddStaCtx;
Jeff Johnson295189b2012-06-20 16:38:30 -07007383 v_MACADDR_t STAMacAddress;
Gopichand Nakkalab0856222013-03-12 22:39:05 -07007384#ifdef FEATURE_WLAN_TDLS
Gopichand Nakkala681989c2013-03-06 22:27:48 -08007385 tCsrStaParams StaParams = {0};
Gopichand Nakkala681989c2013-03-06 22:27:48 -08007386 tANI_U8 isBufSta = 0;
Naresh Jayaram3180aa42014-02-12 21:47:26 +05307387 tANI_U8 isOffChannelSupported = 0;
Gopichand Nakkalab0856222013-03-12 22:39:05 -07007388#endif
Jeff Johnsone7245742012-09-05 17:12:55 -07007389 ENTER();
7390
Gopichand Nakkala29149562013-05-10 21:43:41 +05307391 if ((NULL == pAdapter))
7392 {
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +05307393 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
Gopichand Nakkala29149562013-05-10 21:43:41 +05307394 "invalid adapter ");
7395 return -EINVAL;
7396 }
7397
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05307398 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
7399 TRACE_CODE_HDD_CHANGE_STATION,
7400 pAdapter->sessionId, params->listen_interval));
Gopichand Nakkala29149562013-05-10 21:43:41 +05307401 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
7402 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
7403
7404 if ((NULL == pHddCtx) || (NULL == pHddStaCtx))
7405 {
7406 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
7407 "invalid HDD state or HDD station context");
7408 return -EINVAL;
7409 }
7410
7411 if (pHddCtx->isLogpInProgress)
Jeff Johnson04dd8a82012-06-29 20:41:40 -07007412 {
7413 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
7414 "%s:LOGP in Progress. Ignore!!!", __func__);
7415 return -EAGAIN;
7416 }
7417
Jeff Johnson295189b2012-06-20 16:38:30 -07007418 vos_mem_copy(STAMacAddress.bytes, mac, sizeof(v_MACADDR_t));
7419
Gopichand Nakkala681989c2013-03-06 22:27:48 -08007420 if ((pAdapter->device_mode == WLAN_HDD_SOFTAP)
7421 || (pAdapter->device_mode == WLAN_HDD_P2P_GO))
Jeff Johnson295189b2012-06-20 16:38:30 -07007422 {
Gopichand Nakkala681989c2013-03-06 22:27:48 -08007423 if (params->sta_flags_set & BIT(NL80211_STA_FLAG_AUTHORIZED))
Jeff Johnson295189b2012-06-20 16:38:30 -07007424 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307425 status = hdd_softap_change_STA_state( pAdapter, &STAMacAddress,
Jeff Johnson295189b2012-06-20 16:38:30 -07007426 WLANTL_STA_AUTHENTICATED);
7427
Gopichand Nakkala29149562013-05-10 21:43:41 +05307428 if (status != VOS_STATUS_SUCCESS)
7429 {
7430 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
7431 "%s: Not able to change TL state to AUTHENTICATED", __func__);
7432 return -EINVAL;
7433 }
Jeff Johnson295189b2012-06-20 16:38:30 -07007434 }
7435 }
Hoonki Leea6d49be2013-04-05 09:43:25 -07007436 else if ((pAdapter->device_mode == WLAN_HDD_INFRA_STATION)
7437 || (pAdapter->device_mode == WLAN_HDD_P2P_CLIENT)) {
Gopichand Nakkala29149562013-05-10 21:43:41 +05307438#ifdef FEATURE_WLAN_TDLS
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -07007439 if (params->sta_flags_set & BIT(NL80211_STA_FLAG_TDLS_PEER)) {
7440 StaParams.capability = params->capability;
7441 StaParams.uapsd_queues = params->uapsd_queues;
7442 StaParams.max_sp = params->max_sp;
7443
Naresh Jayaram3180aa42014-02-12 21:47:26 +05307444 /* Convert (first channel , number of channels) tuple to
7445 * the total list of channels. This goes with the assumption
7446 * that if the first channel is < 14, then the next channels
7447 * are an incremental of 1 else an incremental of 4 till the number
7448 * of channels.
7449 */
7450 if (0 != params->supported_channels_len) {
7451 int i = 0,j = 0,k = 0, no_of_channels = 0 ;
7452 for ( i = 0 ; i < params->supported_channels_len ; i+=2)
7453 {
7454 int wifi_chan_index;
7455 StaParams.supported_channels[j] = params->supported_channels[i];
7456 wifi_chan_index =
7457 ((StaParams.supported_channels[j] <= HDD_CHANNEL_14 ) ? 1 : 4 );
7458 no_of_channels = params->supported_channels[i+1];
7459 for(k=1; k <= no_of_channels; k++)
7460 {
7461 StaParams.supported_channels[j+1] =
7462 StaParams.supported_channels[j] + wifi_chan_index;
7463 j+=1;
7464 }
7465 }
7466 StaParams.supported_channels_len = j;
7467 }
7468 vos_mem_copy(StaParams.supported_oper_classes,
7469 params->supported_oper_classes,
7470 params->supported_oper_classes_len);
7471 StaParams.supported_oper_classes_len =
7472 params->supported_oper_classes_len;
7473
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -07007474 if (0 != params->ext_capab_len)
7475 vos_mem_copy(StaParams.extn_capability, params->ext_capab,
7476 sizeof(StaParams.extn_capability));
7477
7478 if (NULL != params->ht_capa)
Hoonki Lee66b75f32013-04-16 18:30:07 -07007479 {
7480 StaParams.htcap_present = 1;
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -07007481 vos_mem_copy(&StaParams.HTCap, params->ht_capa, sizeof(tSirHTCap));
Hoonki Lee66b75f32013-04-16 18:30:07 -07007482 }
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -07007483
7484 StaParams.supported_rates_len = params->supported_rates_len;
7485
7486 /* Note : The Maximum sizeof supported_rates sent by the Supplicant is 32.
7487 * The supported_rates array , for all the structures propogating till Add Sta
7488 * to the firmware has to be modified , if the supplicant (ieee80211) is
7489 * modified to send more rates.
7490 */
7491
7492 /* To avoid Data Currption , set to max length to SIR_MAC_MAX_SUPP_RATES
7493 */
7494 if (StaParams.supported_rates_len > SIR_MAC_MAX_SUPP_RATES)
7495 StaParams.supported_rates_len = SIR_MAC_MAX_SUPP_RATES;
7496
7497 if (0 != StaParams.supported_rates_len) {
7498 int i = 0;
7499 vos_mem_copy(StaParams.supported_rates, params->supported_rates,
7500 StaParams.supported_rates_len);
Hoonki Lee5305c3a2013-04-29 23:28:59 -07007501 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -07007502 "Supported Rates with Length %d", StaParams.supported_rates_len);
7503 for (i=0; i < StaParams.supported_rates_len; i++)
Hoonki Lee5305c3a2013-04-29 23:28:59 -07007504 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -07007505 "[%d]: %0x", i, StaParams.supported_rates[i]);
7506 }
7507
7508 if (NULL != params->vht_capa)
Hoonki Lee66b75f32013-04-16 18:30:07 -07007509 {
7510 StaParams.vhtcap_present = 1;
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -07007511 vos_mem_copy(&StaParams.VHTCap, params->vht_capa, sizeof(tSirVHTCap));
Hoonki Lee66b75f32013-04-16 18:30:07 -07007512 }
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -07007513
Gopichand Nakkala681989c2013-03-06 22:27:48 -08007514 if (0 != params->ext_capab_len ) {
7515 /*Define A Macro : TODO Sunil*/
7516 if ((1<<4) & StaParams.extn_capability[3]) {
7517 isBufSta = 1;
7518 }
Naresh Jayaram3180aa42014-02-12 21:47:26 +05307519 /* TDLS Channel Switching Support */
7520 if ((1<<6) & StaParams.extn_capability[3]) {
7521 isOffChannelSupported = 1;
7522 }
Gopichand Nakkala681989c2013-03-06 22:27:48 -08007523 }
Naresh Jayaram3180aa42014-02-12 21:47:26 +05307524 status = wlan_hdd_tdls_set_peer_caps( pAdapter, mac,
7525 &StaParams, isBufSta,
7526 isOffChannelSupported);
7527
Gopichand Nakkala79ff85d2013-05-27 17:05:29 +05307528 if (VOS_STATUS_SUCCESS != status) {
7529 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
7530 "%s: wlan_hdd_tdls_set_peer_caps failed!", __func__);
7531 return -EINVAL;
7532 }
Gopichand Nakkala681989c2013-03-06 22:27:48 -08007533 status = wlan_hdd_tdls_add_station(wiphy, dev, mac, 1, &StaParams);
7534
7535 if (VOS_STATUS_SUCCESS != status) {
7536 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
7537 "%s: sme_ChangeTdlsPeerSta failed!", __func__);
7538 return -EINVAL;
7539 }
7540 }
Gopichand Nakkalab0856222013-03-12 22:39:05 -07007541#endif
Gopichand Nakkala6239acd2013-06-14 14:48:00 +05307542 }
Jeff Johnsone7245742012-09-05 17:12:55 -07007543 EXIT();
Jeff Johnson295189b2012-06-20 16:38:30 -07007544 return status;
7545}
7546
7547/*
Mahesh A Saptasagar1a51bc02014-06-02 18:28:08 +05307548 * FUNCTION: __wlan_hdd_cfg80211_add_key
Jeff Johnson295189b2012-06-20 16:38:30 -07007549 * This function is used to initialize the key information
7550 */
7551#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
Mahesh A Saptasagar1a51bc02014-06-02 18:28:08 +05307552static int __wlan_hdd_cfg80211_add_key( struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -07007553 struct net_device *ndev,
7554 u8 key_index, bool pairwise,
7555 const u8 *mac_addr,
7556 struct key_params *params
7557 )
7558#else
Mahesh A Saptasagar1a51bc02014-06-02 18:28:08 +05307559static int __wlan_hdd_cfg80211_add_key( struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -07007560 struct net_device *ndev,
7561 u8 key_index, const u8 *mac_addr,
7562 struct key_params *params
7563 )
7564#endif
7565{
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -07007566 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( ndev );
Jeff Johnson295189b2012-06-20 16:38:30 -07007567 tCsrRoamSetKey setKey;
7568 u8 groupmacaddr[WNI_CFG_BSSID_LEN] = {0xFF,0xFF,0xFF,0xFF,0xFF,0xFF};
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05307569 int status;
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -07007570 v_U32_t roamId= 0xFF;
7571 v_CONTEXT_t pVosContext = (WLAN_HDD_GET_CTX(pAdapter))->pvosContext;
Jeff Johnson295189b2012-06-20 16:38:30 -07007572 hdd_hostapd_state_t *pHostapdState;
7573 VOS_STATUS vos_status;
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -07007574 eHalStatus halStatus;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05307575 hdd_context_t *pHddCtx;
Jeff Johnson295189b2012-06-20 16:38:30 -07007576
7577 ENTER();
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +05307578
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05307579 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
7580 TRACE_CODE_HDD_CFG80211_ADD_KEY,
7581 pAdapter->sessionId, params->key_len));
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05307582 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
7583 status = wlan_hdd_validate_context(pHddCtx);
7584
7585 if (0 != status)
Jeff Johnson04dd8a82012-06-29 20:41:40 -07007586 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05307587 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
7588 "%s: HDD context is not valid", __func__);
7589 return status;
Jeff Johnson04dd8a82012-06-29 20:41:40 -07007590 }
7591
Sushant Kaushik8bc7df22014-04-09 17:55:29 +05307592 hddLog(VOS_TRACE_LEVEL_INFO, "%s: device_mode = %s (%d)",
7593 __func__, hdd_device_modetoString(pAdapter->device_mode),
7594 pAdapter->device_mode);
Jeff Johnson295189b2012-06-20 16:38:30 -07007595
7596 if (CSR_MAX_NUM_KEY <= key_index)
7597 {
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -07007598 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Invalid key index %d", __func__,
Jeff Johnson295189b2012-06-20 16:38:30 -07007599 key_index);
7600
7601 return -EINVAL;
7602 }
7603
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -07007604 if (CSR_MAX_KEY_LEN < params->key_len)
7605 {
7606 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Invalid key length %d", __func__,
7607 params->key_len);
7608
7609 return -EINVAL;
7610 }
7611
7612 hddLog(VOS_TRACE_LEVEL_INFO,
7613 "%s: called with key index = %d & key length %d",
7614 __func__, key_index, params->key_len);
Jeff Johnson295189b2012-06-20 16:38:30 -07007615
7616 /*extract key idx, key len and key*/
7617 vos_mem_zero(&setKey,sizeof(tCsrRoamSetKey));
7618 setKey.keyId = key_index;
7619 setKey.keyLength = params->key_len;
7620 vos_mem_copy(&setKey.Key[0],params->key, params->key_len);
7621
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -07007622 switch (params->cipher)
Jeff Johnson295189b2012-06-20 16:38:30 -07007623 {
7624 case WLAN_CIPHER_SUITE_WEP40:
7625 setKey.encType = eCSR_ENCRYPT_TYPE_WEP40_STATICKEY;
7626 break;
7627
7628 case WLAN_CIPHER_SUITE_WEP104:
7629 setKey.encType = eCSR_ENCRYPT_TYPE_WEP104_STATICKEY;
7630 break;
7631
7632 case WLAN_CIPHER_SUITE_TKIP:
7633 {
7634 u8 *pKey = &setKey.Key[0];
7635 setKey.encType = eCSR_ENCRYPT_TYPE_TKIP;
7636
7637 vos_mem_zero(pKey, CSR_MAX_KEY_LEN);
7638
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -07007639 /*Supplicant sends the 32bytes key in this order
Jeff Johnson295189b2012-06-20 16:38:30 -07007640
7641 |--------------|----------|----------|
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -07007642 | Tk1 |TX-MIC | RX Mic |
Jeff Johnson295189b2012-06-20 16:38:30 -07007643 |--------------|----------|----------|
7644 <---16bytes---><--8bytes--><--8bytes-->
7645
7646 */
7647 /*Sme expects the 32 bytes key to be in the below order
7648
7649 |--------------|----------|----------|
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -07007650 | Tk1 |RX-MIC | TX Mic |
Jeff Johnson295189b2012-06-20 16:38:30 -07007651 |--------------|----------|----------|
7652 <---16bytes---><--8bytes--><--8bytes-->
7653 */
7654 /* Copy the Temporal Key 1 (TK1) */
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -07007655 vos_mem_copy(pKey, params->key, 16);
Jeff Johnson295189b2012-06-20 16:38:30 -07007656
7657 /*Copy the rx mic first*/
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -07007658 vos_mem_copy(&pKey[16], &params->key[24], 8);
Jeff Johnson295189b2012-06-20 16:38:30 -07007659
7660 /*Copy the tx mic */
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -07007661 vos_mem_copy(&pKey[24], &params->key[16], 8);
Jeff Johnson295189b2012-06-20 16:38:30 -07007662
7663
7664 break;
7665 }
7666
7667 case WLAN_CIPHER_SUITE_CCMP:
7668 setKey.encType = eCSR_ENCRYPT_TYPE_AES;
7669 break;
7670
7671#ifdef FEATURE_WLAN_WAPI
7672 case WLAN_CIPHER_SUITE_SMS4:
7673 {
7674 vos_mem_zero(&setKey,sizeof(tCsrRoamSetKey));
7675 wlan_hdd_cfg80211_set_key_wapi(pAdapter, key_index, mac_addr,
7676 params->key, params->key_len);
7677 return 0;
7678 }
7679#endif
Chet Lanctot186b5732013-03-18 10:26:30 -07007680
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08007681#ifdef FEATURE_WLAN_ESE
Jeff Johnson295189b2012-06-20 16:38:30 -07007682 case WLAN_CIPHER_SUITE_KRK:
7683 setKey.encType = eCSR_ENCRYPT_TYPE_KRK;
7684 break;
7685#endif
Chet Lanctot186b5732013-03-18 10:26:30 -07007686
7687#ifdef WLAN_FEATURE_11W
7688 case WLAN_CIPHER_SUITE_AES_CMAC:
7689 setKey.encType = eCSR_ENCRYPT_TYPE_AES_CMAC;
Chet Lanctot3b5158a2013-03-31 16:45:21 -07007690 break;
Chet Lanctot186b5732013-03-18 10:26:30 -07007691#endif
7692
Jeff Johnson295189b2012-06-20 16:38:30 -07007693 default:
Jeff Johnson0299d0a2013-10-30 12:37:43 -07007694 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: unsupported cipher type %u",
Jeff Johnson295189b2012-06-20 16:38:30 -07007695 __func__, params->cipher);
7696 return -EOPNOTSUPP;
7697 }
7698
7699 hddLog(VOS_TRACE_LEVEL_INFO_MED, "%s: encryption type %d",
7700 __func__, setKey.encType);
7701
Shailender Karmuchi642e9812013-05-30 14:34:49 -07007702 if (
Jeff Johnson295189b2012-06-20 16:38:30 -07007703#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
7704 (!pairwise)
7705#else
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -07007706 (!mac_addr || is_broadcast_ether_addr(mac_addr))
Jeff Johnson295189b2012-06-20 16:38:30 -07007707#endif
Shailender Karmuchi642e9812013-05-30 14:34:49 -07007708 )
7709 {
7710 /* set group key*/
7711 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
7712 "%s- %d: setting Broadcast key",
7713 __func__, __LINE__);
7714 setKey.keyDirection = eSIR_RX_ONLY;
7715 vos_mem_copy(setKey.peerMac,groupmacaddr,WNI_CFG_BSSID_LEN);
7716 }
7717 else
7718 {
7719 /* set pairwise key*/
7720 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
7721 "%s- %d: setting pairwise key",
7722 __func__, __LINE__);
7723 setKey.keyDirection = eSIR_TX_RX;
7724 vos_mem_copy(setKey.peerMac, mac_addr,WNI_CFG_BSSID_LEN);
7725 }
7726 if ((WLAN_HDD_IBSS == pAdapter->device_mode) && !pairwise)
7727 {
7728 setKey.keyDirection = eSIR_TX_RX;
7729 /*Set the group key*/
7730 status = sme_RoamSetKey( WLAN_HDD_GET_HAL_CTX(pAdapter),
7731 pAdapter->sessionId, &setKey, &roamId );
Jeff Johnson295189b2012-06-20 16:38:30 -07007732
Shailender Karmuchi642e9812013-05-30 14:34:49 -07007733 if ( 0 != status )
7734 {
7735 hddLog(VOS_TRACE_LEVEL_ERROR,
7736 "%s: sme_RoamSetKey failed, returned %d", __func__, status);
7737 return -EINVAL;
7738 }
7739 /*Save the keys here and call sme_RoamSetKey for setting
7740 the PTK after peer joins the IBSS network*/
7741 vos_mem_copy(&pAdapter->sessionCtx.station.ibss_enc_key,
7742 &setKey, sizeof(tCsrRoamSetKey));
7743 return status;
7744 }
Gopichand Nakkala29149562013-05-10 21:43:41 +05307745 if ((pAdapter->device_mode == WLAN_HDD_SOFTAP) ||
7746 (pAdapter->device_mode == WLAN_HDD_P2P_GO))
7747 {
Jeff Johnson295189b2012-06-20 16:38:30 -07007748 pHostapdState = WLAN_HDD_GET_HOSTAP_STATE_PTR(pAdapter);
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -07007749 if( pHostapdState->bssState == BSS_START )
7750 {
c_hpothu7c55da62014-01-23 18:34:02 +05307751 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
7752 vos_status = wlan_hdd_check_ula_done(pAdapter);
7753
7754 if ( vos_status != VOS_STATUS_SUCCESS )
7755 {
7756 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
7757 "[%4d] wlan_hdd_check_ula_done returned ERROR status= %d",
7758 __LINE__, vos_status );
7759
7760 pHddStaCtx->roam_info.roamingState = HDD_ROAM_STATE_NONE;
7761
7762 return -EINVAL;
7763 }
7764
Jeff Johnson295189b2012-06-20 16:38:30 -07007765 status = WLANSAP_SetKeySta( pVosContext, &setKey);
7766
7767 if ( status != eHAL_STATUS_SUCCESS )
7768 {
7769 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
7770 "[%4d] WLANSAP_SetKeySta returned ERROR status= %d",
7771 __LINE__, status );
7772 }
7773 }
7774
7775 /* Saving WEP keys */
7776 else if( eCSR_ENCRYPT_TYPE_WEP40_STATICKEY == setKey.encType ||
7777 eCSR_ENCRYPT_TYPE_WEP104_STATICKEY == setKey.encType )
7778 {
7779 //Save the wep key in ap context. Issue setkey after the BSS is started.
7780 hdd_ap_ctx_t *pAPCtx = WLAN_HDD_GET_AP_CTX_PTR(pAdapter);
7781 vos_mem_copy(&pAPCtx->wepKey[key_index], &setKey, sizeof(tCsrRoamSetKey));
7782 }
7783 else
7784 {
7785 //Save the key in ap context. Issue setkey after the BSS is started.
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -07007786 hdd_ap_ctx_t *pAPCtx = WLAN_HDD_GET_AP_CTX_PTR(pAdapter);
Jeff Johnson295189b2012-06-20 16:38:30 -07007787 vos_mem_copy(&pAPCtx->groupKey, &setKey, sizeof(tCsrRoamSetKey));
7788 }
7789 }
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -07007790 else if ( (pAdapter->device_mode == WLAN_HDD_INFRA_STATION) ||
7791 (pAdapter->device_mode == WLAN_HDD_P2P_CLIENT) )
Jeff Johnson295189b2012-06-20 16:38:30 -07007792 {
7793 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
7794 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
7795
Gopichand Nakkala3d295922013-05-07 16:19:14 +05307796#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
7797 if (!pairwise)
7798#else
7799 if (!mac_addr || is_broadcast_ether_addr(mac_addr))
7800#endif
7801 {
7802 /* set group key*/
7803 if (pHddStaCtx->roam_info.deferKeyComplete)
7804 {
7805 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
7806 "%s- %d: Perform Set key Complete",
7807 __func__, __LINE__);
7808 hdd_PerformRoamSetKeyComplete(pAdapter);
7809 }
7810 }
7811
Jeff Johnson295189b2012-06-20 16:38:30 -07007812 pWextState->roamProfile.Keys.KeyLength[key_index] = (u8)params->key_len;
7813
Venkata Prathyusha Kuntupalliee2ce712013-01-17 14:09:24 -08007814 pWextState->roamProfile.Keys.defaultIndex = key_index;
7815
7816
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -07007817 vos_mem_copy(&pWextState->roamProfile.Keys.KeyMaterial[key_index][0],
Jeff Johnson295189b2012-06-20 16:38:30 -07007818 params->key, params->key_len);
7819
Gopichand Nakkala3d295922013-05-07 16:19:14 +05307820
Jeff Johnson295189b2012-06-20 16:38:30 -07007821 pHddStaCtx->roam_info.roamingState = HDD_ROAM_STATE_SETTING_KEY;
7822
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307823 hddLog(VOS_TRACE_LEVEL_INFO_MED,
Jeff Johnson295189b2012-06-20 16:38:30 -07007824 "%s: set key for peerMac %2x:%2x:%2x:%2x:%2x:%2x, direction %d",
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307825 __func__, setKey.peerMac[0], setKey.peerMac[1],
7826 setKey.peerMac[2], setKey.peerMac[3],
7827 setKey.peerMac[4], setKey.peerMac[5],
Jeff Johnson295189b2012-06-20 16:38:30 -07007828 setKey.keyDirection);
7829
7830 vos_status = wlan_hdd_check_ula_done(pAdapter);
7831
7832 if ( vos_status != VOS_STATUS_SUCCESS )
7833 {
7834 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
7835 "[%4d] wlan_hdd_check_ula_done returned ERROR status= %d",
7836 __LINE__, vos_status );
7837
7838 pHddStaCtx->roam_info.roamingState = HDD_ROAM_STATE_NONE;
7839
7840 return -EINVAL;
7841
7842 }
7843
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -07007844#ifdef WLAN_FEATURE_VOWIFI_11R
Gopichand Nakkala3d295922013-05-07 16:19:14 +05307845 /* The supplicant may attempt to set the PTK once pre-authentication
7846 is done. Save the key in the UMAC and include it in the ADD BSS
7847 request */
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -07007848 halStatus = sme_FTUpdateKey( WLAN_HDD_GET_HAL_CTX(pAdapter), &setKey);
Gopichand Nakkala3d295922013-05-07 16:19:14 +05307849 if ( halStatus == eHAL_STATUS_FT_PREAUTH_KEY_SUCCESS )
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -07007850 {
Gopichand Nakkala3d295922013-05-07 16:19:14 +05307851 hddLog(VOS_TRACE_LEVEL_INFO_MED,
7852 "%s: Update PreAuth Key success", __func__);
7853 return 0;
7854 }
7855 else if ( halStatus == eHAL_STATUS_FT_PREAUTH_KEY_FAILED )
7856 {
7857 hddLog(VOS_TRACE_LEVEL_ERROR,
7858 "%s: Update PreAuth Key failed", __func__);
Gopichand Nakkalad7d13652013-02-15 01:48:00 +05307859 return -EINVAL;
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -07007860 }
7861#endif /* WLAN_FEATURE_VOWIFI_11R */
Jeff Johnson295189b2012-06-20 16:38:30 -07007862
7863 /* issue set key request to SME*/
7864 status = sme_RoamSetKey( WLAN_HDD_GET_HAL_CTX(pAdapter),
7865 pAdapter->sessionId, &setKey, &roamId );
7866
7867 if ( 0 != status )
7868 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307869 hddLog(VOS_TRACE_LEVEL_ERROR,
Jeff Johnson295189b2012-06-20 16:38:30 -07007870 "%s: sme_RoamSetKey failed, returned %d", __func__, status);
7871 pHddStaCtx->roam_info.roamingState = HDD_ROAM_STATE_NONE;
7872 return -EINVAL;
7873 }
7874
7875
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307876 /* in case of IBSS as there was no information available about WEP keys during
7877 * IBSS join, group key intialized with NULL key, so re-initialize group key
Jeff Johnson295189b2012-06-20 16:38:30 -07007878 * with correct value*/
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307879 if ( (eCSR_BSS_TYPE_START_IBSS == pWextState->roamProfile.BSSType) &&
7880 !( ( IW_AUTH_KEY_MGMT_802_1X
7881 == (pWextState->authKeyMgmt & IW_AUTH_KEY_MGMT_802_1X))
Jeff Johnson295189b2012-06-20 16:38:30 -07007882 && (eCSR_AUTH_TYPE_OPEN_SYSTEM == pHddStaCtx->conn_info.authType)
7883 )
7884 &&
7885 ( (WLAN_CIPHER_SUITE_WEP40 == params->cipher)
7886 || (WLAN_CIPHER_SUITE_WEP104 == params->cipher)
7887 )
7888 )
7889 {
7890 setKey.keyDirection = eSIR_RX_ONLY;
7891 vos_mem_copy(setKey.peerMac,groupmacaddr,WNI_CFG_BSSID_LEN);
7892
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307893 hddLog(VOS_TRACE_LEVEL_INFO_MED,
Jeff Johnson295189b2012-06-20 16:38:30 -07007894 "%s: set key peerMac %2x:%2x:%2x:%2x:%2x:%2x, direction %d",
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307895 __func__, setKey.peerMac[0], setKey.peerMac[1],
7896 setKey.peerMac[2], setKey.peerMac[3],
7897 setKey.peerMac[4], setKey.peerMac[5],
Jeff Johnson295189b2012-06-20 16:38:30 -07007898 setKey.keyDirection);
7899
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307900 status = sme_RoamSetKey( WLAN_HDD_GET_HAL_CTX(pAdapter),
Jeff Johnson295189b2012-06-20 16:38:30 -07007901 pAdapter->sessionId, &setKey, &roamId );
7902
7903 if ( 0 != status )
7904 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307905 hddLog(VOS_TRACE_LEVEL_ERROR,
7906 "%s: sme_RoamSetKey failed for group key (IBSS), returned %d",
Jeff Johnson295189b2012-06-20 16:38:30 -07007907 __func__, status);
7908 pHddStaCtx->roam_info.roamingState = HDD_ROAM_STATE_NONE;
7909 return -EINVAL;
7910 }
7911 }
7912 }
7913
7914 return 0;
7915}
7916
Mahesh A Saptasagar1a51bc02014-06-02 18:28:08 +05307917#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
7918static int wlan_hdd_cfg80211_add_key( struct wiphy *wiphy,
7919 struct net_device *ndev,
7920 u8 key_index, bool pairwise,
7921 const u8 *mac_addr,
7922 struct key_params *params
7923 )
7924#else
7925static int wlan_hdd_cfg80211_add_key( struct wiphy *wiphy,
7926 struct net_device *ndev,
7927 u8 key_index, const u8 *mac_addr,
7928 struct key_params *params
7929 )
7930#endif
7931{
7932 int ret;
7933 vos_ssr_protect(__func__);
7934#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
7935 ret = __wlan_hdd_cfg80211_add_key(wiphy, ndev, key_index, pairwise,
7936 mac_addr, params);
7937#else
7938 ret = __wlan_hdd_cfg80211_add_key(wiphy, ndev, key_index, mac_addr,
7939 params);
7940#endif
7941 vos_ssr_unprotect(__func__);
7942
7943 return ret;
7944}
7945
Jeff Johnson295189b2012-06-20 16:38:30 -07007946/*
Mahesh A Saptasagar1a51bc02014-06-02 18:28:08 +05307947 * FUNCTION: __wlan_hdd_cfg80211_get_key
Jeff Johnson295189b2012-06-20 16:38:30 -07007948 * This function is used to get the key information
7949 */
7950#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
Mahesh A Saptasagar1a51bc02014-06-02 18:28:08 +05307951static int __wlan_hdd_cfg80211_get_key(
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307952 struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -07007953 struct net_device *ndev,
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307954 u8 key_index, bool pairwise,
Jeff Johnson295189b2012-06-20 16:38:30 -07007955 const u8 *mac_addr, void *cookie,
7956 void (*callback)(void *cookie, struct key_params*)
7957 )
7958#else
Mahesh A Saptasagar1a51bc02014-06-02 18:28:08 +05307959static int __wlan_hdd_cfg80211_get_key(
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307960 struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -07007961 struct net_device *ndev,
7962 u8 key_index, const u8 *mac_addr, void *cookie,
7963 void (*callback)(void *cookie, struct key_params*)
7964 )
7965#endif
7966{
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307967 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( ndev );
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +05307968 hdd_wext_state_t *pWextState= WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
7969 tCsrRoamProfile *pRoamProfile = &(pWextState->roamProfile);
Jeff Johnson295189b2012-06-20 16:38:30 -07007970 struct key_params params;
7971
7972 ENTER();
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307973
Sushant Kaushik8bc7df22014-04-09 17:55:29 +05307974 hddLog(VOS_TRACE_LEVEL_INFO, "%s: device_mode = %s (%d)",
7975 __func__, hdd_device_modetoString(pAdapter->device_mode),
7976 pAdapter->device_mode);
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +05307977
Jeff Johnson295189b2012-06-20 16:38:30 -07007978 memset(&params, 0, sizeof(params));
7979
7980 if (CSR_MAX_NUM_KEY <= key_index)
7981 {
c_hpothu6ff1c3c2013-10-01 19:01:57 +05307982 hddLog(VOS_TRACE_LEVEL_ERROR, FL("invalid key index %d"), key_index);
Jeff Johnson295189b2012-06-20 16:38:30 -07007983 return -EINVAL;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307984 }
Jeff Johnson295189b2012-06-20 16:38:30 -07007985
7986 switch(pRoamProfile->EncryptionType.encryptionType[0])
7987 {
7988 case eCSR_ENCRYPT_TYPE_NONE:
7989 params.cipher = IW_AUTH_CIPHER_NONE;
7990 break;
7991
7992 case eCSR_ENCRYPT_TYPE_WEP40_STATICKEY:
7993 case eCSR_ENCRYPT_TYPE_WEP40:
7994 params.cipher = WLAN_CIPHER_SUITE_WEP40;
7995 break;
7996
7997 case eCSR_ENCRYPT_TYPE_WEP104_STATICKEY:
7998 case eCSR_ENCRYPT_TYPE_WEP104:
7999 params.cipher = WLAN_CIPHER_SUITE_WEP104;
8000 break;
8001
8002 case eCSR_ENCRYPT_TYPE_TKIP:
8003 params.cipher = WLAN_CIPHER_SUITE_TKIP;
8004 break;
8005
8006 case eCSR_ENCRYPT_TYPE_AES:
8007 params.cipher = WLAN_CIPHER_SUITE_AES_CMAC;
8008 break;
8009
8010 default:
8011 params.cipher = IW_AUTH_CIPHER_NONE;
8012 break;
8013 }
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +05308014
c_hpothuaaf19692014-05-17 17:01:48 +05308015 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
8016 TRACE_CODE_HDD_CFG80211_GET_KEY,
8017 pAdapter->sessionId, params.cipher));
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +05308018
Jeff Johnson295189b2012-06-20 16:38:30 -07008019 params.key_len = pRoamProfile->Keys.KeyLength[key_index];
8020 params.seq_len = 0;
8021 params.seq = NULL;
8022 params.key = &pRoamProfile->Keys.KeyMaterial[key_index][0];
8023 callback(cookie, &params);
8024 return 0;
8025}
8026
Mahesh A Saptasagar1a51bc02014-06-02 18:28:08 +05308027#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
8028static int wlan_hdd_cfg80211_get_key(
8029 struct wiphy *wiphy,
8030 struct net_device *ndev,
8031 u8 key_index, bool pairwise,
8032 const u8 *mac_addr, void *cookie,
8033 void (*callback)(void *cookie, struct key_params*)
8034 )
8035#else
8036static int wlan_hdd_cfg80211_get_key(
8037 struct wiphy *wiphy,
8038 struct net_device *ndev,
8039 u8 key_index, const u8 *mac_addr, void *cookie,
8040 void (*callback)(void *cookie, struct key_params*)
8041 )
8042#endif
8043{
8044 int ret;
8045
8046 vos_ssr_protect(__func__);
8047#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
8048 ret = __wlan_hdd_cfg80211_get_key(wiphy, ndev, key_index, pairwise,
8049 mac_addr, cookie, callback);
8050#else
8051 ret = __wlan_hdd_cfg80211_get_key(wiphy, ndev, key_index, mac_addr,
8052 callback);
8053#endif
8054 vos_ssr_unprotect(__func__);
8055
8056 return ret;
8057}
8058
Jeff Johnson295189b2012-06-20 16:38:30 -07008059/*
8060 * FUNCTION: wlan_hdd_cfg80211_del_key
8061 * This function is used to delete the key information
8062 */
8063#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308064static int wlan_hdd_cfg80211_del_key( struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -07008065 struct net_device *ndev,
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308066 u8 key_index,
8067 bool pairwise,
Jeff Johnson295189b2012-06-20 16:38:30 -07008068 const u8 *mac_addr
8069 )
8070#else
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308071static int wlan_hdd_cfg80211_del_key( struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -07008072 struct net_device *ndev,
8073 u8 key_index,
8074 const u8 *mac_addr
8075 )
8076#endif
8077{
8078 int status = 0;
8079
8080 //This code needs to be revisited. There is sme_removeKey API, we should
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308081 //plan to use that. After the change to use correct index in setkey,
Jeff Johnson295189b2012-06-20 16:38:30 -07008082 //it is observed that this is invalidating peer
8083 //key index whenever re-key is done. This is affecting data link.
8084 //It should be ok to ignore del_key.
8085#if 0
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308086 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( ndev );
8087 v_CONTEXT_t pVosContext = (WLAN_HDD_GET_CTX(pAdapter))->pvosContext;
Jeff Johnson295189b2012-06-20 16:38:30 -07008088 u8 groupmacaddr[WNI_CFG_BSSID_LEN] = {0xFF,0xFF,0xFF,0xFF,0xFF,0xFF};
8089 tCsrRoamSetKey setKey;
8090 v_U32_t roamId= 0xFF;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308091
Jeff Johnson295189b2012-06-20 16:38:30 -07008092 ENTER();
8093
8094 hddLog(VOS_TRACE_LEVEL_INFO_HIGH, "%s: device_mode = %d\n",
8095 __func__,pAdapter->device_mode);
8096
8097 if (CSR_MAX_NUM_KEY <= key_index)
8098 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308099 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Invalid key index %d", __func__,
Jeff Johnson295189b2012-06-20 16:38:30 -07008100 key_index);
8101
8102 return -EINVAL;
8103 }
8104
8105 vos_mem_zero(&setKey,sizeof(tCsrRoamSetKey));
8106 setKey.keyId = key_index;
8107
8108 if (mac_addr)
8109 vos_mem_copy(setKey.peerMac, mac_addr,WNI_CFG_BSSID_LEN);
8110 else
8111 vos_mem_copy(setKey.peerMac, groupmacaddr, WNI_CFG_BSSID_LEN);
8112
8113 setKey.encType = eCSR_ENCRYPT_TYPE_NONE;
8114
8115 if ((pAdapter->device_mode == WLAN_HDD_SOFTAP)
Jeff Johnson295189b2012-06-20 16:38:30 -07008116 || (pAdapter->device_mode == WLAN_HDD_P2P_GO)
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308117 )
8118 {
8119
8120 hdd_hostapd_state_t *pHostapdState =
Jeff Johnson295189b2012-06-20 16:38:30 -07008121 WLAN_HDD_GET_HOSTAP_STATE_PTR(pAdapter);
8122 if( pHostapdState->bssState == BSS_START)
8123 {
8124 status = WLANSAP_SetKeySta( pVosContext, &setKey);
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308125
Jeff Johnson295189b2012-06-20 16:38:30 -07008126 if ( status != eHAL_STATUS_SUCCESS )
8127 {
8128 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
8129 "[%4d] WLANSAP_SetKeySta returned ERROR status= %d",
8130 __LINE__, status );
8131 }
8132 }
8133 }
8134 else if ( (pAdapter->device_mode == WLAN_HDD_INFRA_STATION)
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308135 || (pAdapter->device_mode == WLAN_HDD_P2P_CLIENT)
Jeff Johnson295189b2012-06-20 16:38:30 -07008136 )
8137 {
8138 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
8139
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308140 pHddStaCtx->roam_info.roamingState = HDD_ROAM_STATE_SETTING_KEY;
8141
8142 hddLog(VOS_TRACE_LEVEL_INFO_MED,
Jeff Johnson295189b2012-06-20 16:38:30 -07008143 "%s: delete key for peerMac %2x:%2x:%2x:%2x:%2x:%2x",
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308144 __func__, setKey.peerMac[0], setKey.peerMac[1],
8145 setKey.peerMac[2], setKey.peerMac[3],
Jeff Johnson295189b2012-06-20 16:38:30 -07008146 setKey.peerMac[4], setKey.peerMac[5]);
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308147 if(pAdapter->sessionCtx.station.conn_info.connState ==
8148 eConnectionState_Associated)
Jeff Johnson295189b2012-06-20 16:38:30 -07008149 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308150 status = sme_RoamSetKey( WLAN_HDD_GET_HAL_CTX(pAdapter),
Jeff Johnson295189b2012-06-20 16:38:30 -07008151 pAdapter->sessionId, &setKey, &roamId );
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308152
Jeff Johnson295189b2012-06-20 16:38:30 -07008153 if ( 0 != status )
8154 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308155 hddLog(VOS_TRACE_LEVEL_ERROR,
Jeff Johnson295189b2012-06-20 16:38:30 -07008156 "%s: sme_RoamSetKey failure, returned %d",
8157 __func__, status);
8158 pHddStaCtx->roam_info.roamingState = HDD_ROAM_STATE_NONE;
8159 return -EINVAL;
8160 }
8161 }
8162 }
8163#endif
Jeff Johnsone7245742012-09-05 17:12:55 -07008164 EXIT();
Jeff Johnson295189b2012-06-20 16:38:30 -07008165 return status;
8166}
8167
8168/*
Mahesh A Saptasagar1a51bc02014-06-02 18:28:08 +05308169 * FUNCTION: __wlan_hdd_cfg80211_set_default_key
Jeff Johnson295189b2012-06-20 16:38:30 -07008170 * This function is used to set the default tx key index
8171 */
8172#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
Mahesh A Saptasagar1a51bc02014-06-02 18:28:08 +05308173static int __wlan_hdd_cfg80211_set_default_key( struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -07008174 struct net_device *ndev,
8175 u8 key_index,
8176 bool unicast, bool multicast)
8177#else
Mahesh A Saptasagar1a51bc02014-06-02 18:28:08 +05308178static int __wlan_hdd_cfg80211_set_default_key( struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -07008179 struct net_device *ndev,
8180 u8 key_index)
8181#endif
8182{
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308183 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( ndev );
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05308184 int status;
Gopichand Nakkala29149562013-05-10 21:43:41 +05308185 hdd_wext_state_t *pWextState;
8186 hdd_station_ctx_t *pHddStaCtx;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05308187 hdd_context_t *pHddCtx;
Jeff Johnson295189b2012-06-20 16:38:30 -07008188
8189 ENTER();
8190
Gopichand Nakkala29149562013-05-10 21:43:41 +05308191 if ((NULL == pAdapter))
8192 {
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +05308193 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
Gopichand Nakkala29149562013-05-10 21:43:41 +05308194 "invalid adapter");
8195 return -EINVAL;
8196 }
8197
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05308198 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
8199 TRACE_CODE_HDD_CFG80211_SET_DEFAULT_KEY,
8200 pAdapter->sessionId, key_index));
8201
Gopichand Nakkala29149562013-05-10 21:43:41 +05308202 pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
8203 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
8204
8205 if ((NULL == pWextState) || (NULL == pHddStaCtx))
8206 {
8207 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
8208 "invalid Wext state or HDD context");
8209 return -EINVAL;
8210 }
8211
Arif Hussain6d2a3322013-11-17 19:50:10 -08008212 hddLog(VOS_TRACE_LEVEL_INFO, "%s: device_mode = %d key_index = %d",
Jeff Johnson295189b2012-06-20 16:38:30 -07008213 __func__,pAdapter->device_mode, key_index);
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308214
Jeff Johnson295189b2012-06-20 16:38:30 -07008215 if (CSR_MAX_NUM_KEY <= key_index)
8216 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308217 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Invalid key index %d", __func__,
Jeff Johnson295189b2012-06-20 16:38:30 -07008218 key_index);
8219
8220 return -EINVAL;
8221 }
8222
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05308223 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
8224 status = wlan_hdd_validate_context(pHddCtx);
8225
8226 if (0 != status)
Jeff Johnson04dd8a82012-06-29 20:41:40 -07008227 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05308228 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
8229 "%s: HDD context is not valid", __func__);
8230 return status;
Jeff Johnson04dd8a82012-06-29 20:41:40 -07008231 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308232
Jeff Johnson295189b2012-06-20 16:38:30 -07008233 if ((pAdapter->device_mode == WLAN_HDD_INFRA_STATION)
Jeff Johnson295189b2012-06-20 16:38:30 -07008234 || (pAdapter->device_mode == WLAN_HDD_P2P_CLIENT)
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308235 )
Jeff Johnson295189b2012-06-20 16:38:30 -07008236 {
Gopichand Nakkala29149562013-05-10 21:43:41 +05308237 if ( (eCSR_ENCRYPT_TYPE_TKIP !=
Arif Hussain6943f522013-11-04 20:10:10 -08008238 pHddStaCtx->conn_info.ucEncryptionType) &&
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308239 (eCSR_ENCRYPT_TYPE_AES !=
Arif Hussain6943f522013-11-04 20:10:10 -08008240 pHddStaCtx->conn_info.ucEncryptionType)
Jeff Johnson295189b2012-06-20 16:38:30 -07008241 )
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308242 {
8243 /* if default key index is not same as previous one,
Jeff Johnson295189b2012-06-20 16:38:30 -07008244 * then update the default key index */
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308245
Jeff Johnson295189b2012-06-20 16:38:30 -07008246 tCsrRoamSetKey setKey;
8247 v_U32_t roamId= 0xFF;
8248 tCsrKeys *Keys = &pWextState->roamProfile.Keys;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308249
8250 hddLog(VOS_TRACE_LEVEL_INFO_HIGH, "%s: default tx key index %d",
Jeff Johnson295189b2012-06-20 16:38:30 -07008251 __func__, key_index);
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308252
Jeff Johnson295189b2012-06-20 16:38:30 -07008253 Keys->defaultIndex = (u8)key_index;
8254 vos_mem_zero(&setKey,sizeof(tCsrRoamSetKey));
8255 setKey.keyId = key_index;
8256 setKey.keyLength = Keys->KeyLength[key_index];
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308257
8258 vos_mem_copy(&setKey.Key[0],
8259 &Keys->KeyMaterial[key_index][0],
Jeff Johnson295189b2012-06-20 16:38:30 -07008260 Keys->KeyLength[key_index]);
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308261
Gopichand Nakkala29149562013-05-10 21:43:41 +05308262 setKey.keyDirection = eSIR_TX_RX;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308263
8264 vos_mem_copy(setKey.peerMac,
Jeff Johnson295189b2012-06-20 16:38:30 -07008265 &pHddStaCtx->conn_info.bssId[0],
8266 WNI_CFG_BSSID_LEN);
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308267
Gopichand Nakkala29149562013-05-10 21:43:41 +05308268 if (Keys->KeyLength[key_index] == CSR_WEP40_KEY_LEN &&
8269 pWextState->roamProfile.EncryptionType.encryptionType[0] ==
8270 eCSR_ENCRYPT_TYPE_WEP104)
8271 {
8272 /*In the case of dynamic wep supplicant hardcodes DWEP type to eCSR_ENCRYPT_TYPE_WEP104
8273 even though ap is configured for WEP-40 encryption. In this canse the key length
8274 is 5 but the encryption type is 104 hence checking the key langht(5) and encryption
8275 type(104) and switching encryption type to 40*/
8276 pWextState->roamProfile.EncryptionType.encryptionType[0] =
8277 eCSR_ENCRYPT_TYPE_WEP40;
8278 pWextState->roamProfile.mcEncryptionType.encryptionType[0] =
8279 eCSR_ENCRYPT_TYPE_WEP40;
8280 }
8281
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308282 setKey.encType =
Jeff Johnson295189b2012-06-20 16:38:30 -07008283 pWextState->roamProfile.EncryptionType.encryptionType[0];
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308284
Jeff Johnson295189b2012-06-20 16:38:30 -07008285 /* issue set key request */
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308286 status = sme_RoamSetKey( WLAN_HDD_GET_HAL_CTX(pAdapter),
Jeff Johnson295189b2012-06-20 16:38:30 -07008287 pAdapter->sessionId, &setKey, &roamId );
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308288
Jeff Johnson295189b2012-06-20 16:38:30 -07008289 if ( 0 != status )
8290 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308291 hddLog(VOS_TRACE_LEVEL_ERROR,
8292 "%s: sme_RoamSetKey failed, returned %d", __func__,
Jeff Johnson295189b2012-06-20 16:38:30 -07008293 status);
8294 return -EINVAL;
8295 }
8296 }
8297 }
8298
8299 /* In SoftAp mode setting key direction for default mode */
8300 else if ( WLAN_HDD_SOFTAP == pAdapter->device_mode )
8301 {
8302 if ( (eCSR_ENCRYPT_TYPE_TKIP !=
8303 pWextState->roamProfile.EncryptionType.encryptionType[0]) &&
8304 (eCSR_ENCRYPT_TYPE_AES !=
8305 pWextState->roamProfile.EncryptionType.encryptionType[0])
8306 )
8307 {
8308 /* Saving key direction for default key index to TX default */
8309 hdd_ap_ctx_t *pAPCtx = WLAN_HDD_GET_AP_CTX_PTR(pAdapter);
8310 pAPCtx->wepKey[key_index].keyDirection = eSIR_TX_DEFAULT;
8311 }
8312 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308313
Jeff Johnson295189b2012-06-20 16:38:30 -07008314 return status;
8315}
8316
Mahesh A Saptasagar1a51bc02014-06-02 18:28:08 +05308317#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
8318static int wlan_hdd_cfg80211_set_default_key( struct wiphy *wiphy,
8319 struct net_device *ndev,
8320 u8 key_index,
8321 bool unicast, bool multicast)
8322#else
8323static int wlan_hdd_cfg80211_set_default_key( struct wiphy *wiphy,
8324 struct net_device *ndev,
8325 u8 key_index)
8326#endif
8327{
8328 int ret;
8329 vos_ssr_protect(__func__);
8330#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
8331 ret = __wlan_hdd_cfg80211_set_default_key(wiphy, ndev, key_index, unicast,
8332 multicast);
8333#else
8334 ret = __wlan_hdd_cfg80211_set_default_key(wiphy, ndev, key_index);
8335#endif
8336 vos_ssr_unprotect(__func__);
8337
8338 return ret;
8339}
8340
Jeff Johnson295189b2012-06-20 16:38:30 -07008341/*
8342 * FUNCTION: wlan_hdd_cfg80211_inform_bss
8343 * This function is used to inform the BSS details to nl80211 interface.
8344 */
8345static struct cfg80211_bss* wlan_hdd_cfg80211_inform_bss(
8346 hdd_adapter_t *pAdapter, tCsrRoamConnectedProfile *roamProfile)
8347{
8348 struct net_device *dev = pAdapter->dev;
8349 struct wireless_dev *wdev = dev->ieee80211_ptr;
8350 struct wiphy *wiphy = wdev->wiphy;
8351 tSirBssDescription *pBssDesc = roamProfile->pBssDesc;
8352 int chan_no;
8353 int ie_length;
8354 const char *ie;
8355 unsigned int freq;
8356 struct ieee80211_channel *chan;
8357 int rssi = 0;
8358 struct cfg80211_bss *bss = NULL;
8359
8360 ENTER();
8361
8362 if( NULL == pBssDesc )
8363 {
Arif Hussain6d2a3322013-11-17 19:50:10 -08008364 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: pBssDesc is NULL", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07008365 return bss;
8366 }
8367
8368 chan_no = pBssDesc->channelId;
8369 ie_length = GET_IE_LEN_IN_BSS_DESC( pBssDesc->length );
8370 ie = ((ie_length != 0) ? (const char *)&pBssDesc->ieFields: NULL);
8371
8372 if( NULL == ie )
8373 {
Arif Hussain6d2a3322013-11-17 19:50:10 -08008374 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: IE of BSS descriptor is NULL", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07008375 return bss;
8376 }
8377
8378#if (LINUX_VERSION_CODE > KERNEL_VERSION(2,6,38))
8379 if (chan_no <= ARRAY_SIZE(hdd_channels_2_4_GHZ))
8380 {
8381 freq = ieee80211_channel_to_frequency(chan_no, IEEE80211_BAND_2GHZ);
8382 }
8383 else
8384 {
8385 freq = ieee80211_channel_to_frequency(chan_no, IEEE80211_BAND_5GHZ);
8386 }
8387#else
8388 freq = ieee80211_channel_to_frequency(chan_no);
8389#endif
8390
8391 chan = __ieee80211_get_channel(wiphy, freq);
8392
Santhosh Kumar Padmaa45fdb12014-04-15 15:54:38 +05308393 if (!chan) {
8394 hddLog(VOS_TRACE_LEVEL_ERROR, "%s chan pointer is NULL", __func__);
8395 return NULL;
8396 }
8397
Abhishek Singhaee43942014-06-16 18:55:47 +05308398 rssi = (VOS_MIN ((pBssDesc->rssi + pBssDesc->sinr), 0))*100;
Jeff Johnson295189b2012-06-20 16:38:30 -07008399
Abhishek Singhaee43942014-06-16 18:55:47 +05308400 return cfg80211_inform_bss(wiphy, chan, pBssDesc->bssId,
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308401 le64_to_cpu(*(__le64 *)pBssDesc->timeStamp),
Jeff Johnson295189b2012-06-20 16:38:30 -07008402 pBssDesc->capabilityInfo,
8403 pBssDesc->beaconInterval, ie, ie_length,
Abhishek Singhaee43942014-06-16 18:55:47 +05308404 rssi, GFP_KERNEL );
Jeff Johnson295189b2012-06-20 16:38:30 -07008405}
8406
8407
8408
8409/*
8410 * FUNCTION: wlan_hdd_cfg80211_inform_bss_frame
8411 * This function is used to inform the BSS details to nl80211 interface.
8412 */
8413struct cfg80211_bss*
8414wlan_hdd_cfg80211_inform_bss_frame( hdd_adapter_t *pAdapter,
8415 tSirBssDescription *bss_desc
8416 )
8417{
8418 /*
8419 cfg80211_inform_bss() is not updating ie field of bss entry, if entry
8420 already exists in bss data base of cfg80211 for that particular BSS ID.
8421 Using cfg80211_inform_bss_frame to update the bss entry instead of
8422 cfg80211_inform_bss, But this call expects mgmt packet as input. As of
8423 now there is no possibility to get the mgmt(probe response) frame from PE,
8424 converting bss_desc to ieee80211_mgmt(probe response) and passing to
8425 cfg80211_inform_bss_frame.
8426 */
8427 struct net_device *dev = pAdapter->dev;
8428 struct wireless_dev *wdev = dev->ieee80211_ptr;
8429 struct wiphy *wiphy = wdev->wiphy;
8430 int chan_no = bss_desc->channelId;
Madan Mohan Koyyalamudi86f629e2012-11-09 16:27:29 -08008431#ifdef WLAN_ENABLE_AGEIE_ON_SCAN_RESULTS
8432 qcom_ie_age *qie_age = NULL;
8433 int ie_length = GET_IE_LEN_IN_BSS_DESC( bss_desc->length ) + sizeof(qcom_ie_age);
8434#else
Jeff Johnson295189b2012-06-20 16:38:30 -07008435 int ie_length = GET_IE_LEN_IN_BSS_DESC( bss_desc->length );
Madan Mohan Koyyalamudi86f629e2012-11-09 16:27:29 -08008436#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07008437 const char *ie =
8438 ((ie_length != 0) ? (const char *)&bss_desc->ieFields: NULL);
8439 unsigned int freq;
8440 struct ieee80211_channel *chan;
Abhishek Singh1e2bfa32014-01-02 15:44:15 +05308441 struct ieee80211_mgmt *mgmt = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -07008442 struct cfg80211_bss *bss_status = NULL;
8443 size_t frame_len = sizeof (struct ieee80211_mgmt) + ie_length;
8444 int rssi = 0;
Wilson Yangf80a0542013-10-07 13:02:37 -07008445 hdd_context_t *pHddCtx;
8446 int status;
Jeff Johnsone7245742012-09-05 17:12:55 -07008447#ifdef WLAN_OPEN_SOURCE
8448 struct timespec ts;
8449#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07008450
Wilson Yangf80a0542013-10-07 13:02:37 -07008451 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
8452 status = wlan_hdd_validate_context(pHddCtx);
8453
8454 /*bss_update is not allowed during wlan driver loading or unloading*/
Mihir Shete18156292014-03-11 15:38:30 +05308455 if (WLAN_HDD_IS_LOAD_UNLOAD_IN_PROGRESS(pHddCtx))
Wilson Yangf80a0542013-10-07 13:02:37 -07008456 {
8457 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
8458 "%s:Loading_unloading in Progress. Ignore!!!",__func__);
8459 return NULL;
8460 }
8461
8462
8463 if (0 != status)
8464 {
8465 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
8466 "%s: HDD context is not valid", __func__);
Madan Mohan Koyyalamudi2e5c9142012-11-02 13:17:48 -07008467 return NULL;
Wilson Yangf80a0542013-10-07 13:02:37 -07008468 }
8469
Abhishek Singh1e2bfa32014-01-02 15:44:15 +05308470 mgmt = kzalloc((sizeof (struct ieee80211_mgmt) + ie_length), GFP_KERNEL);
Wilson Yangf80a0542013-10-07 13:02:37 -07008471 if (!mgmt)
8472 {
8473 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
8474 "%s: memory allocation failed ", __func__);
8475 return NULL;
8476 }
Madan Mohan Koyyalamudi2e5c9142012-11-02 13:17:48 -07008477
Jeff Johnson295189b2012-06-20 16:38:30 -07008478 memcpy(mgmt->bssid, bss_desc->bssId, ETH_ALEN);
Jeff Johnsone7245742012-09-05 17:12:55 -07008479
8480#ifdef WLAN_OPEN_SOURCE
8481 /* Android does not want the timestamp from the frame.
8482 Instead it wants a monotonic increasing value */
8483 get_monotonic_boottime(&ts);
8484 mgmt->u.probe_resp.timestamp =
8485 ((u64)ts.tv_sec * 1000000) + (ts.tv_nsec / 1000);
8486#else
8487 /* keep old behavior for non-open source (for now) */
Jeff Johnson295189b2012-06-20 16:38:30 -07008488 memcpy(&mgmt->u.probe_resp.timestamp, bss_desc->timeStamp,
8489 sizeof (bss_desc->timeStamp));
Jeff Johnsone7245742012-09-05 17:12:55 -07008490
8491#endif
8492
Jeff Johnson295189b2012-06-20 16:38:30 -07008493 mgmt->u.probe_resp.beacon_int = bss_desc->beaconInterval;
8494 mgmt->u.probe_resp.capab_info = bss_desc->capabilityInfo;
Madan Mohan Koyyalamudi86f629e2012-11-09 16:27:29 -08008495
8496#ifdef WLAN_ENABLE_AGEIE_ON_SCAN_RESULTS
8497 /* GPS Requirement: need age ie per entry. Using vendor specific. */
8498 /* Assuming this is the last IE, copy at the end */
8499 ie_length -=sizeof(qcom_ie_age);
8500 qie_age = (qcom_ie_age *)(mgmt->u.probe_resp.variable + ie_length);
8501 qie_age->element_id = QCOM_VENDOR_IE_ID;
8502 qie_age->len = QCOM_VENDOR_IE_AGE_LEN;
8503 qie_age->oui_1 = QCOM_OUI1;
8504 qie_age->oui_2 = QCOM_OUI2;
8505 qie_age->oui_3 = QCOM_OUI3;
8506 qie_age->type = QCOM_VENDOR_IE_AGE_TYPE;
8507 qie_age->age = vos_timer_get_system_ticks() - bss_desc->nReceivedTime;
8508#endif
8509
Jeff Johnson295189b2012-06-20 16:38:30 -07008510 memcpy(mgmt->u.probe_resp.variable, ie, ie_length);
Gopichand Nakkalad908ec82013-05-16 19:32:19 +05308511 if (bss_desc->fProbeRsp)
8512 {
8513 mgmt->frame_control |=
8514 (u16)(IEEE80211_FTYPE_MGMT | IEEE80211_STYPE_PROBE_RESP);
8515 }
8516 else
8517 {
8518 mgmt->frame_control |=
8519 (u16)(IEEE80211_FTYPE_MGMT | IEEE80211_STYPE_BEACON);
8520 }
Jeff Johnson295189b2012-06-20 16:38:30 -07008521
8522#if (LINUX_VERSION_CODE > KERNEL_VERSION(2,6,38))
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308523 if (chan_no <= ARRAY_SIZE(hdd_channels_2_4_GHZ) &&
Jeff Johnson295189b2012-06-20 16:38:30 -07008524 (wiphy->bands[IEEE80211_BAND_2GHZ] != NULL))
8525 {
8526 freq = ieee80211_channel_to_frequency(chan_no, IEEE80211_BAND_2GHZ);
8527 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308528 else if ((chan_no > ARRAY_SIZE(hdd_channels_2_4_GHZ)) &&
Jeff Johnson295189b2012-06-20 16:38:30 -07008529 (wiphy->bands[IEEE80211_BAND_5GHZ] != NULL))
8530
8531 {
8532 freq = ieee80211_channel_to_frequency(chan_no, IEEE80211_BAND_5GHZ);
8533 }
8534 else
8535 {
Nirav Shah20ac06f2013-12-12 18:14:06 +05308536 hddLog(VOS_TRACE_LEVEL_ERROR, "%s Invalid chan_no:%d",
8537 __func__, chan_no);
Jeff Johnson295189b2012-06-20 16:38:30 -07008538 kfree(mgmt);
8539 return NULL;
8540 }
8541#else
8542 freq = ieee80211_channel_to_frequency(chan_no);
8543#endif
8544 chan = __ieee80211_get_channel(wiphy, freq);
Leela V Kiran Kumar Reddy90032de2013-01-24 18:33:30 -08008545 /*when the band is changed on the fly using the GUI, three things are done
8546 * 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)
8547 * as part of the scan abort, message willbe queued to PE and we proceed with flushing and changinh the band.
8548 * pe will stop the scanning further and report back the results what ever it had till now by calling the call back function.
8549 * if the time between update band and scandone call back is sufficent enough the band change reflects in SME, SME validates the channels
8550 * and discards the channels correponding to previous band and calls back with zero bss results.
8551 * 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
8552 * all the channels correponding to previous band.this is due to race condition.but those channels are invalid to the new band and so
8553 * this function __ieee80211_get_channel will return NULL.Each time we report scan result with this pointer null warning kernel trace is printed.
8554 * if the scan results contain large number of APs continuosly kernel warning trace is printed and it will lead to apps watch dog bark.
8555 * So drop the bss and continue to next bss.
8556 */
8557 if(chan == NULL)
8558 {
Nirav Shah20ac06f2013-12-12 18:14:06 +05308559 hddLog(VOS_TRACE_LEVEL_ERROR, "%s chan pointer is NULL", __func__);
Chilam Ngc4244af2013-04-01 15:37:32 -07008560 kfree(mgmt);
Leela V Kiran Kumar Reddy90032de2013-01-24 18:33:30 -08008561 return NULL;
8562 }
Jeff Johnson295189b2012-06-20 16:38:30 -07008563 /*To keep the rssi icon of the connected AP in the scan window
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308564 *and the rssi icon of the wireless networks in sync
Jeff Johnson295189b2012-06-20 16:38:30 -07008565 * */
8566 if (( eConnectionState_Associated ==
8567 pAdapter->sessionCtx.station.conn_info.connState ) &&
8568 ( VOS_TRUE == vos_mem_compare(bss_desc->bssId,
8569 pAdapter->sessionCtx.station.conn_info.bssId,
8570 WNI_CFG_BSSID_LEN)))
8571 {
8572 /* supplicant takes the signal strength in terms of mBm(100*dBm) */
8573 rssi = (pAdapter->rssi * 100);
8574 }
8575 else
8576 {
8577 rssi = (VOS_MIN ((bss_desc->rssi + bss_desc->sinr), 0))*100;
8578 }
8579
Nirav Shah20ac06f2013-12-12 18:14:06 +05308580 hddLog(VOS_TRACE_LEVEL_INFO, "%s: BSSID:" MAC_ADDRESS_STR " Channel:%d"
8581 "RSSI:%d", __func__, MAC_ADDR_ARRAY(mgmt->bssid),
8582 chan->center_freq, (int)(rssi/100));
8583
Jeff Johnson295189b2012-06-20 16:38:30 -07008584 bss_status = cfg80211_inform_bss_frame(wiphy, chan, mgmt,
8585 frame_len, rssi, GFP_KERNEL);
8586 kfree(mgmt);
8587 return bss_status;
8588}
8589
8590/*
8591 * FUNCTION: wlan_hdd_cfg80211_update_bss_db
8592 * This function is used to update the BSS data base of CFG8011
8593 */
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308594struct cfg80211_bss* wlan_hdd_cfg80211_update_bss_db( hdd_adapter_t *pAdapter,
Jeff Johnson295189b2012-06-20 16:38:30 -07008595 tCsrRoamInfo *pRoamInfo
8596 )
8597{
8598 tCsrRoamConnectedProfile roamProfile;
8599 tHalHandle hHal = WLAN_HDD_GET_HAL_CTX(pAdapter);
8600 struct cfg80211_bss *bss = NULL;
8601
8602 ENTER();
8603
8604 memset(&roamProfile, 0, sizeof(tCsrRoamConnectedProfile));
8605 sme_RoamGetConnectProfile(hHal, pAdapter->sessionId, &roamProfile);
8606
8607 if (NULL != roamProfile.pBssDesc)
8608 {
Girish Gowlif4b68022014-08-28 23:18:57 +05308609 bss = wlan_hdd_cfg80211_inform_bss_frame(pAdapter,
8610 roamProfile.pBssDesc);
Jeff Johnson295189b2012-06-20 16:38:30 -07008611
8612 if (NULL == bss)
8613 {
8614 hddLog(VOS_TRACE_LEVEL_INFO, "%s: cfg80211_inform_bss return NULL",
8615 __func__);
8616 }
8617
8618 sme_RoamFreeConnectProfile(hHal, &roamProfile);
8619 }
8620 else
8621 {
8622 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: roamProfile.pBssDesc is NULL",
8623 __func__);
8624 }
8625 return bss;
8626}
8627
8628/*
8629 * FUNCTION: wlan_hdd_cfg80211_update_bss
8630 */
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308631static int wlan_hdd_cfg80211_update_bss( struct wiphy *wiphy,
8632 hdd_adapter_t *pAdapter
Jeff Johnson295189b2012-06-20 16:38:30 -07008633 )
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308634{
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +05308635 tHalHandle hHal = WLAN_HDD_GET_HAL_CTX(pAdapter);
Jeff Johnson295189b2012-06-20 16:38:30 -07008636 tCsrScanResultInfo *pScanResult;
8637 eHalStatus status = 0;
8638 tScanResultHandle pResult;
8639 struct cfg80211_bss *bss_status = NULL;
Wilson Yangf80a0542013-10-07 13:02:37 -07008640 hdd_context_t *pHddCtx;
Jeff Johnson295189b2012-06-20 16:38:30 -07008641
8642 ENTER();
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +05308643
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05308644 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
8645 TRACE_CODE_HDD_CFG80211_UPDATE_BSS,
8646 NO_SESSION, pAdapter->sessionId));
8647
Wilson Yangf80a0542013-10-07 13:02:37 -07008648 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
8649
8650 if (pHddCtx->isLogpInProgress)
Jeff Johnson295189b2012-06-20 16:38:30 -07008651 {
Wilson Yangf80a0542013-10-07 13:02:37 -07008652 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
8653 "%s:LOGP in Progress. Ignore!!!",__func__);
8654 return -EAGAIN;
Jeff Johnson295189b2012-06-20 16:38:30 -07008655 }
8656
Wilson Yangf80a0542013-10-07 13:02:37 -07008657
8658 /*bss_update is not allowed during wlan driver loading or unloading*/
Mihir Shete18156292014-03-11 15:38:30 +05308659 if (WLAN_HDD_IS_LOAD_UNLOAD_IN_PROGRESS(pHddCtx))
Wilson Yangf80a0542013-10-07 13:02:37 -07008660 {
8661 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
8662 "%s:Loading_unloading in Progress. Ignore!!!",__func__);
8663 return VOS_STATUS_E_PERM;
8664 }
8665
8666
Jeff Johnson295189b2012-06-20 16:38:30 -07008667 /*
8668 * start getting scan results and populate cgf80211 BSS database
8669 */
8670 status = sme_ScanGetResult(hHal, pAdapter->sessionId, NULL, &pResult);
8671
8672 /* no scan results */
8673 if (NULL == pResult)
8674 {
Nirav Shah20ac06f2013-12-12 18:14:06 +05308675 hddLog(VOS_TRACE_LEVEL_INFO, "%s: No scan result Status %d",
8676 __func__, status);
Jeff Johnson295189b2012-06-20 16:38:30 -07008677 return status;
8678 }
8679
8680 pScanResult = sme_ScanResultGetFirst(hHal, pResult);
8681
8682 while (pScanResult)
8683 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308684 /*
8685 * cfg80211_inform_bss() is not updating ie field of bss entry, if
8686 * entry already exists in bss data base of cfg80211 for that
8687 * particular BSS ID. Using cfg80211_inform_bss_frame to update the
8688 * bss entry instead of cfg80211_inform_bss, But this call expects
8689 * mgmt packet as input. As of now there is no possibility to get
8690 * the mgmt(probe response) frame from PE, converting bss_desc to
Jeff Johnson295189b2012-06-20 16:38:30 -07008691 * ieee80211_mgmt(probe response) and passing to c
8692 * fg80211_inform_bss_frame.
8693 * */
8694
8695 bss_status = wlan_hdd_cfg80211_inform_bss_frame(pAdapter,
8696 &pScanResult->BssDescriptor);
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308697
Jeff Johnson295189b2012-06-20 16:38:30 -07008698
8699 if (NULL == bss_status)
8700 {
8701 hddLog(VOS_TRACE_LEVEL_INFO,
Arif Hussain6d2a3322013-11-17 19:50:10 -08008702 "%s: NULL returned by cfg80211_inform_bss", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07008703 }
8704 else
8705 {
Yue Maf49ba872013-08-19 12:04:25 -07008706 cfg80211_put_bss(
8707#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,9,0))
8708 wiphy,
8709#endif
8710 bss_status);
Jeff Johnson295189b2012-06-20 16:38:30 -07008711 }
8712
8713 pScanResult = sme_ScanResultGetNext(hHal, pResult);
8714 }
8715
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308716 sme_ScanResultPurge(hHal, pResult);
Jeff Johnson295189b2012-06-20 16:38:30 -07008717
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308718 return 0;
Jeff Johnson295189b2012-06-20 16:38:30 -07008719}
8720
Jeff Johnson04dd8a82012-06-29 20:41:40 -07008721void
8722hddPrintMacAddr(tCsrBssid macAddr, tANI_U8 logLevel)
8723{
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308724 VOS_TRACE(VOS_MODULE_ID_HDD, logLevel,
Arif Hussaina7c8e412013-11-20 11:06:42 -08008725 MAC_ADDRESS_STR, MAC_ADDR_ARRAY(macAddr));
Jeff Johnson04dd8a82012-06-29 20:41:40 -07008726} /****** end hddPrintMacAddr() ******/
8727
8728void
Madan Mohan Koyyalamudic75be962012-10-18 19:19:03 -07008729hddPrintPmkId(tANI_U8 *pmkId, tANI_U8 logLevel)
Jeff Johnson04dd8a82012-06-29 20:41:40 -07008730{
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308731 VOS_TRACE(VOS_MODULE_ID_HDD, logLevel,
Arif Hussain6d2a3322013-11-17 19:50:10 -08008732 "%02X:%02X:%02X:%02X:%02X:%02X:%02X:%02X:%02X:%02X:%02X:%02X:%02X:%02X:%02X:%02X",
Madan Mohan Koyyalamudic75be962012-10-18 19:19:03 -07008733 pmkId[0], pmkId[1], pmkId[2], pmkId[3], pmkId[4],
8734 pmkId[5], pmkId[6], pmkId[7], pmkId[8], pmkId[9], pmkId[10],
8735 pmkId[11], pmkId[12], pmkId[13], pmkId[14], pmkId[15]);
Jeff Johnson04dd8a82012-06-29 20:41:40 -07008736} /****** end hddPrintPmkId() ******/
8737
8738//hddPrintMacAddr(tCsrBssid macAddr, tANI_U8 logLevel);
8739//hddPrintMacAddr(macAddr, VOS_TRACE_LEVEL_FATAL);
8740
8741//void sirDumpBuf(tpAniSirGlobal pMac, tANI_U8 modId, tANI_U32 level, tANI_U8 *buf, tANI_U32 size);
8742//sirDumpBuf(pMac, VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL, pmkid, 16);
8743
8744#define dump_bssid(bssid) \
8745 { \
Jeff Johnsone7245742012-09-05 17:12:55 -07008746 hddLog(VOS_TRACE_LEVEL_INFO, "BSSID (MAC) address:\t"); \
8747 hddPrintMacAddr(bssid, VOS_TRACE_LEVEL_INFO);\
Jeff Johnson04dd8a82012-06-29 20:41:40 -07008748 }
8749
8750#define dump_pmkid(pMac, pmkid) \
8751 { \
Jeff Johnsone7245742012-09-05 17:12:55 -07008752 hddLog(VOS_TRACE_LEVEL_INFO, "PMKSA-ID:\t"); \
8753 hddPrintPmkId(pmkid, VOS_TRACE_LEVEL_INFO);\
Jeff Johnson04dd8a82012-06-29 20:41:40 -07008754 }
8755
Madan Mohan Koyyalamudi1b4afb02012-10-22 15:25:16 -07008756#if defined(FEATURE_WLAN_LFR) && (LINUX_VERSION_CODE >= KERNEL_VERSION(3,4,0))
Jeff Johnson04dd8a82012-06-29 20:41:40 -07008757/*
8758 * FUNCTION: wlan_hdd_cfg80211_pmksa_candidate_notify
8759 * This function is used to notify the supplicant of a new PMKSA candidate.
8760 */
8761int wlan_hdd_cfg80211_pmksa_candidate_notify(
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308762 hdd_adapter_t *pAdapter, tCsrRoamInfo *pRoamInfo,
Jeff Johnson04dd8a82012-06-29 20:41:40 -07008763 int index, bool preauth )
8764{
Jeff Johnsone7245742012-09-05 17:12:55 -07008765#ifdef FEATURE_WLAN_OKC
Jeff Johnson04dd8a82012-06-29 20:41:40 -07008766 struct net_device *dev = pAdapter->dev;
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07008767 hdd_context_t *pHddCtx = (hdd_context_t*)pAdapter->pHddCtx;
Jeff Johnson04dd8a82012-06-29 20:41:40 -07008768
8769 ENTER();
Jeff Johnsone7245742012-09-05 17:12:55 -07008770 hddLog(VOS_TRACE_LEVEL_INFO, "%s is going to notify supplicant of:", __func__);
Jeff Johnson04dd8a82012-06-29 20:41:40 -07008771
8772 if( NULL == pRoamInfo )
8773 {
Arif Hussain6d2a3322013-11-17 19:50:10 -08008774 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: pRoamInfo is NULL", __func__);
Jeff Johnson04dd8a82012-06-29 20:41:40 -07008775 return -EINVAL;
8776 }
8777
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07008778 if (eANI_BOOLEAN_TRUE == hdd_is_okc_mode_enabled(pHddCtx))
8779 {
8780 dump_bssid(pRoamInfo->bssid);
8781 cfg80211_pmksa_candidate_notify(dev, index,
Jeff Johnson04dd8a82012-06-29 20:41:40 -07008782 pRoamInfo->bssid, preauth, GFP_KERNEL);
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07008783 }
Jeff Johnsone7245742012-09-05 17:12:55 -07008784#endif /* FEATURE_WLAN_OKC */
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308785 return 0;
Jeff Johnson04dd8a82012-06-29 20:41:40 -07008786}
8787#endif //FEATURE_WLAN_LFR
8788
Yue Maef608272013-04-08 23:09:17 -07008789#ifdef FEATURE_WLAN_LFR_METRICS
8790/*
8791 * FUNCTION: wlan_hdd_cfg80211_roam_metrics_preauth
8792 * 802.11r/LFR metrics reporting function to report preauth initiation
8793 *
8794 */
8795#define MAX_LFR_METRICS_EVENT_LENGTH 100
8796VOS_STATUS wlan_hdd_cfg80211_roam_metrics_preauth(hdd_adapter_t *pAdapter,
8797 tCsrRoamInfo *pRoamInfo)
8798{
8799 unsigned char metrics_notification[MAX_LFR_METRICS_EVENT_LENGTH + 1];
8800 union iwreq_data wrqu;
8801
8802 ENTER();
8803
8804 if (NULL == pAdapter)
8805 {
8806 hddLog(LOGE, "%s: pAdapter is NULL!", __func__);
8807 return VOS_STATUS_E_FAILURE;
8808 }
8809
8810 /* create the event */
8811 memset(&wrqu, 0, sizeof(wrqu));
8812 memset(metrics_notification, 0, sizeof(metrics_notification));
8813
8814 wrqu.data.pointer = metrics_notification;
8815 wrqu.data.length = scnprintf(metrics_notification,
8816 sizeof(metrics_notification), "QCOM: LFR_PREAUTH_INIT "
8817 MAC_ADDRESS_STR, MAC_ADDR_ARRAY(pRoamInfo->bssid));
8818
8819 wireless_send_event(pAdapter->dev, IWEVCUSTOM, &wrqu, metrics_notification);
8820
8821 EXIT();
8822
8823 return VOS_STATUS_SUCCESS;
8824}
8825
8826/*
8827 * FUNCTION: wlan_hdd_cfg80211_roam_metrics_preauth_status
8828 * 802.11r/LFR metrics reporting function to report preauth completion
8829 * or failure
8830 */
8831VOS_STATUS wlan_hdd_cfg80211_roam_metrics_preauth_status(
8832 hdd_adapter_t *pAdapter, tCsrRoamInfo *pRoamInfo, bool preauth_status)
8833{
8834 unsigned char metrics_notification[MAX_LFR_METRICS_EVENT_LENGTH + 1];
8835 union iwreq_data wrqu;
8836
8837 ENTER();
8838
8839 if (NULL == pAdapter)
8840 {
8841 hddLog(LOGE, "%s: pAdapter is NULL!", __func__);
8842 return VOS_STATUS_E_FAILURE;
8843 }
8844
8845 /* create the event */
8846 memset(&wrqu, 0, sizeof(wrqu));
8847 memset(metrics_notification, 0, sizeof(metrics_notification));
8848
8849 scnprintf(metrics_notification, sizeof(metrics_notification),
8850 "QCOM: LFR_PREAUTH_STATUS "MAC_ADDRESS_STR,
8851 MAC_ADDR_ARRAY(pRoamInfo->bssid));
8852
8853 if (1 == preauth_status)
8854 strncat(metrics_notification, " TRUE", 5);
8855 else
8856 strncat(metrics_notification, " FALSE", 6);
8857
8858 wrqu.data.pointer = metrics_notification;
8859 wrqu.data.length = strlen(metrics_notification);
8860
8861 wireless_send_event(pAdapter->dev, IWEVCUSTOM, &wrqu, metrics_notification);
8862
8863 EXIT();
8864
8865 return VOS_STATUS_SUCCESS;
8866}
8867
8868/*
8869 * FUNCTION: wlan_hdd_cfg80211_roam_metrics_handover
8870 * 802.11r/LFR metrics reporting function to report handover initiation
8871 *
8872 */
8873VOS_STATUS wlan_hdd_cfg80211_roam_metrics_handover(hdd_adapter_t * pAdapter,
8874 tCsrRoamInfo *pRoamInfo)
8875{
8876 unsigned char metrics_notification[MAX_LFR_METRICS_EVENT_LENGTH + 1];
8877 union iwreq_data wrqu;
8878
8879 ENTER();
8880
8881 if (NULL == pAdapter)
8882 {
8883 hddLog(LOGE, "%s: pAdapter is NULL!", __func__);
8884 return VOS_STATUS_E_FAILURE;
8885 }
8886
8887 /* create the event */
8888 memset(&wrqu, 0, sizeof(wrqu));
8889 memset(metrics_notification, 0, sizeof(metrics_notification));
8890
8891 wrqu.data.pointer = metrics_notification;
8892 wrqu.data.length = scnprintf(metrics_notification,
8893 sizeof(metrics_notification), "QCOM: LFR_PREAUTH_HANDOVER "
8894 MAC_ADDRESS_STR, MAC_ADDR_ARRAY(pRoamInfo->bssid));
8895
8896 wireless_send_event(pAdapter->dev, IWEVCUSTOM, &wrqu, metrics_notification);
8897
8898 EXIT();
8899
8900 return VOS_STATUS_SUCCESS;
8901}
8902#endif
8903
Jeff Johnson295189b2012-06-20 16:38:30 -07008904/*
8905 * FUNCTION: hdd_cfg80211_scan_done_callback
8906 * scanning callback function, called after finishing scan
8907 *
8908 */
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308909static eHalStatus hdd_cfg80211_scan_done_callback(tHalHandle halHandle,
Jeff Johnson295189b2012-06-20 16:38:30 -07008910 void *pContext, tANI_U32 scanId, eCsrScanStatus status)
8911{
8912 struct net_device *dev = (struct net_device *) pContext;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308913 //struct wireless_dev *wdev = dev->ieee80211_ptr;
Jeff Johnson295189b2012-06-20 16:38:30 -07008914 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( dev );
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -07008915 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
8916 hdd_scaninfo_t *pScanInfo = &pHddCtx->scan_info;
Jeff Johnson295189b2012-06-20 16:38:30 -07008917 struct cfg80211_scan_request *req = NULL;
8918 int ret = 0;
Mahesh A Saptasagar05a357e2014-02-26 16:28:06 +05308919 bool aborted = false;
c_hpothu6ff1c3c2013-10-01 19:01:57 +05308920 long waitRet = 0;
Jeff Johnson295189b2012-06-20 16:38:30 -07008921
8922 ENTER();
8923
8924 hddLog(VOS_TRACE_LEVEL_INFO,
8925 "%s called with halHandle = %p, pContext = %p,"
Arif Hussain6d2a3322013-11-17 19:50:10 -08008926 "scanID = %d, returned status = %d",
Jeff Johnson295189b2012-06-20 16:38:30 -07008927 __func__, halHandle, pContext, (int) scanId, (int) status);
8928
Kiet Lamac06e2c2013-10-23 16:25:07 +05308929 pScanInfo->mScanPendingCounter = 0;
8930
Jeff Johnson295189b2012-06-20 16:38:30 -07008931 //Block on scan req completion variable. Can't wait forever though.
c_hpothu6ff1c3c2013-10-01 19:01:57 +05308932 waitRet = wait_for_completion_interruptible_timeout(
Jeff Johnson295189b2012-06-20 16:38:30 -07008933 &pScanInfo->scan_req_completion_event,
8934 msecs_to_jiffies(WLAN_WAIT_TIME_SCAN_REQ));
c_hpothu6ff1c3c2013-10-01 19:01:57 +05308935 if (waitRet <= 0)
Jeff Johnson295189b2012-06-20 16:38:30 -07008936 {
c_hpothu6ff1c3c2013-10-01 19:01:57 +05308937 hddLog(VOS_TRACE_LEVEL_ERROR,
8938 "%s wait on scan_req_completion_event failed %ld",__func__, waitRet);
Jeff Johnson295189b2012-06-20 16:38:30 -07008939 VOS_ASSERT(pScanInfo->mScanPending);
Jeff Johnsone7245742012-09-05 17:12:55 -07008940 goto allow_suspend;
Jeff Johnson295189b2012-06-20 16:38:30 -07008941 }
8942
Yue Maef608272013-04-08 23:09:17 -07008943 if (pScanInfo->mScanPending != VOS_TRUE)
Jeff Johnson295189b2012-06-20 16:38:30 -07008944 {
8945 VOS_ASSERT(pScanInfo->mScanPending);
Jeff Johnsone7245742012-09-05 17:12:55 -07008946 goto allow_suspend;
Jeff Johnson295189b2012-06-20 16:38:30 -07008947 }
8948
8949 /* Check the scanId */
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308950 if (pScanInfo->scanId != scanId)
Jeff Johnson295189b2012-06-20 16:38:30 -07008951 {
8952 hddLog(VOS_TRACE_LEVEL_INFO,
8953 "%s called with mismatched scanId pScanInfo->scanId = %d "
Arif Hussain6d2a3322013-11-17 19:50:10 -08008954 "scanId = %d", __func__, (int) pScanInfo->scanId,
Jeff Johnson295189b2012-06-20 16:38:30 -07008955 (int) scanId);
8956 }
8957
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308958 ret = wlan_hdd_cfg80211_update_bss((WLAN_HDD_GET_CTX(pAdapter))->wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -07008959 pAdapter);
8960
8961 if (0 > ret)
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308962 hddLog(VOS_TRACE_LEVEL_INFO, "%s: NO SCAN result", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07008963
8964
8965 /* If any client wait scan result through WEXT
8966 * send scan done event to client */
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -07008967 if (pHddCtx->scan_info.waitScanResult)
Jeff Johnson295189b2012-06-20 16:38:30 -07008968 {
8969 /* The other scan request waiting for current scan finish
8970 * Send event to notify current scan finished */
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -07008971 if(WEXT_SCAN_PENDING_DELAY == pHddCtx->scan_info.scan_pending_option)
Jeff Johnson295189b2012-06-20 16:38:30 -07008972 {
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -07008973 vos_event_set(&pHddCtx->scan_info.scan_finished_event);
Jeff Johnson295189b2012-06-20 16:38:30 -07008974 }
8975 /* Send notify to WEXT client */
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -07008976 else if(WEXT_SCAN_PENDING_PIGGYBACK == pHddCtx->scan_info.scan_pending_option)
Jeff Johnson295189b2012-06-20 16:38:30 -07008977 {
8978 struct net_device *dev = pAdapter->dev;
8979 union iwreq_data wrqu;
8980 int we_event;
8981 char *msg;
8982
8983 memset(&wrqu, '\0', sizeof(wrqu));
8984 we_event = SIOCGIWSCAN;
8985 msg = NULL;
8986 wireless_send_event(dev, we_event, &wrqu, msg);
8987 }
8988 }
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -07008989 pHddCtx->scan_info.waitScanResult = FALSE;
Jeff Johnson295189b2012-06-20 16:38:30 -07008990
8991 /* Get the Scan Req */
8992 req = pAdapter->request;
8993
8994 if (!req)
8995 {
Arif Hussain6d2a3322013-11-17 19:50:10 -08008996 hddLog(VOS_TRACE_LEVEL_ERROR, "request is became NULL");
Madan Mohan Koyyalamudi9f5a10c2012-09-28 14:46:16 -07008997 pScanInfo->mScanPending = VOS_FALSE;
Jeff Johnsone7245742012-09-05 17:12:55 -07008998 goto allow_suspend;
Jeff Johnson295189b2012-06-20 16:38:30 -07008999 }
9000
9001 /*
9002 * setting up 0, just in case.
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309003 */
Jeff Johnson295189b2012-06-20 16:38:30 -07009004 req->n_ssids = 0;
9005 req->n_channels = 0;
9006 req->ie = 0;
9007
Jeff Johnson295189b2012-06-20 16:38:30 -07009008 pAdapter->request = NULL;
Jeff Johnsone7245742012-09-05 17:12:55 -07009009 /* Scan is no longer pending */
9010 pScanInfo->mScanPending = VOS_FALSE;
Jeff Johnson295189b2012-06-20 16:38:30 -07009011
Madan Mohan Koyyalamudib764bf82012-10-11 16:38:51 -07009012 /*
9013 * cfg80211_scan_done informing NL80211 about completion
9014 * of scanning
9015 */
Mahesh A Saptasagar05a357e2014-02-26 16:28:06 +05309016 if (status == eCSR_SCAN_ABORT || status == eCSR_SCAN_FAILURE)
9017 {
9018 aborted = true;
9019 }
9020 cfg80211_scan_done(req, aborted);
Madan Mohan Koyyalamudif4e81002012-11-13 10:46:38 -08009021 complete(&pScanInfo->abortscan_event_var);
Jeff Johnson295189b2012-06-20 16:38:30 -07009022
Jeff Johnsone7245742012-09-05 17:12:55 -07009023allow_suspend:
Madan Mohan Koyyalamudi9f5a10c2012-09-28 14:46:16 -07009024 /* release the wake lock at the end of the scan*/
9025 hdd_allow_suspend();
Jeff Johnsone7245742012-09-05 17:12:55 -07009026
Madan Mohan Koyyalamudi10d83a92012-09-28 15:47:05 -07009027 /* Acquire wakelock to handle the case where APP's tries to suspend
9028 * immediatly after the driver gets connect request(i.e after scan)
9029 * from supplicant, this result in app's is suspending and not able
9030 * to process the connect request to AP */
Mahesh A Saptasagarb9c50402014-01-16 15:49:22 +05309031 hdd_prevent_suspend_timeout(1000);
Madan Mohan Koyyalamudi10d83a92012-09-28 15:47:05 -07009032
Gopichand Nakkala638ebc72013-03-21 18:04:02 -07009033#ifdef FEATURE_WLAN_TDLS
c_hpothu3c8f8e82014-06-02 18:01:50 +05309034 if (!(eTDLS_SUPPORT_NOT_ENABLED == pHddCtx->tdls_mode))
9035 {
9036 wlan_hdd_tdls_scan_done_callback(pAdapter);
9037 }
Gopichand Nakkala638ebc72013-03-21 18:04:02 -07009038#endif
9039
Jeff Johnson295189b2012-06-20 16:38:30 -07009040 EXIT();
9041 return 0;
9042}
9043
9044/*
Rashmi Ramannab1429032014-04-26 14:59:09 +05309045 * FUNCTION: hdd_isConnectionInProgress
9046 * Go through each adapter and check if Connection is in progress
Madan Mohan Koyyalamudicfd53742013-01-11 15:29:03 -08009047 *
9048 */
Ganesh Kondabattiniaeb7b772014-08-11 20:00:36 +05309049v_BOOL_t hdd_isConnectionInProgress( hdd_context_t *pHddCtx, v_BOOL_t isRoC )
Madan Mohan Koyyalamudicfd53742013-01-11 15:29:03 -08009050{
9051 hdd_adapter_list_node_t *pAdapterNode = NULL, *pNext = NULL;
9052 hdd_station_ctx_t *pHddStaCtx = NULL;
9053 hdd_adapter_t *pAdapter = NULL;
9054 VOS_STATUS status = 0;
9055 v_U8_t staId = 0;
9056 v_U8_t *staMac = NULL;
9057
c_hpothu9b781ba2013-12-30 20:57:45 +05309058 if (TRUE == pHddCtx->btCoexModeSet)
9059 {
9060 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Rashmi Ramannab1429032014-04-26 14:59:09 +05309061 FL("BTCoex Mode operation in progress"));
9062 return VOS_TRUE;
c_hpothu9b781ba2013-12-30 20:57:45 +05309063 }
9064
Madan Mohan Koyyalamudicfd53742013-01-11 15:29:03 -08009065 status = hdd_get_front_adapter ( pHddCtx, &pAdapterNode );
9066
9067 while ( NULL != pAdapterNode && VOS_STATUS_SUCCESS == status )
9068 {
9069 pAdapter = pAdapterNode->pAdapter;
9070
9071 if( pAdapter )
9072 {
9073 hddLog(VOS_TRACE_LEVEL_INFO,
Sushant Kaushik8bc7df22014-04-09 17:55:29 +05309074 "%s: Adapter with device mode %s (%d) exists",
9075 __func__, hdd_device_modetoString(pAdapter->device_mode),
9076 pAdapter->device_mode);
Ganesh Kondabattiniaeb7b772014-08-11 20:00:36 +05309077 if ((((!isRoC) && (WLAN_HDD_INFRA_STATION == pAdapter->device_mode)) ||
Rashmi Ramannab1429032014-04-26 14:59:09 +05309078 (WLAN_HDD_P2P_CLIENT == pAdapter->device_mode) ||
9079 (WLAN_HDD_P2P_DEVICE == pAdapter->device_mode)) &&
9080 (eConnectionState_Connecting ==
9081 (WLAN_HDD_GET_STATION_CTX_PTR(pAdapter))->conn_info.connState))
9082 {
9083 hddLog(VOS_TRACE_LEVEL_ERROR,
9084 "%s: %p(%d) Connection is in progress", __func__,
9085 WLAN_HDD_GET_STATION_CTX_PTR(pAdapter), pAdapter->sessionId);
9086 return VOS_TRUE;
9087 }
Ganesh Kondabattiniaeb7b772014-08-11 20:00:36 +05309088 if (((!isRoC) && (WLAN_HDD_INFRA_STATION == pAdapter->device_mode)) ||
Sushant Kaushik8bc7df22014-04-09 17:55:29 +05309089 (WLAN_HDD_P2P_CLIENT == pAdapter->device_mode) ||
9090 (WLAN_HDD_P2P_DEVICE == pAdapter->device_mode))
Madan Mohan Koyyalamudicfd53742013-01-11 15:29:03 -08009091 {
9092 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
9093 if ((eConnectionState_Associated == pHddStaCtx->conn_info.connState) &&
Sushant Kaushik8bc7df22014-04-09 17:55:29 +05309094 (VOS_FALSE == pHddStaCtx->conn_info.uIsAuthenticated))
Madan Mohan Koyyalamudicfd53742013-01-11 15:29:03 -08009095 {
9096 staMac = (v_U8_t *) &(pAdapter->macAddressCurrent.bytes[0]);
9097 hddLog(VOS_TRACE_LEVEL_ERROR,
Arif Hussain24bafea2013-11-15 15:10:03 -08009098 "%s: client " MAC_ADDRESS_STR
9099 " is in the middle of WPS/EAPOL exchange.", __func__,
9100 MAC_ADDR_ARRAY(staMac));
Rashmi Ramannab1429032014-04-26 14:59:09 +05309101 return VOS_TRUE;
Madan Mohan Koyyalamudicfd53742013-01-11 15:29:03 -08009102 }
9103 }
9104 else if ((WLAN_HDD_SOFTAP == pAdapter->device_mode) ||
9105 (WLAN_HDD_P2P_GO == pAdapter->device_mode))
9106 {
9107 for (staId = 0; staId < WLAN_MAX_STA_COUNT; staId++)
9108 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309109 if ((pAdapter->aStaInfo[staId].isUsed) &&
Madan Mohan Koyyalamudicfd53742013-01-11 15:29:03 -08009110 (WLANTL_STA_CONNECTED == pAdapter->aStaInfo[staId].tlSTAState))
9111 {
9112 staMac = (v_U8_t *) &(pAdapter->aStaInfo[staId].macAddrSTA.bytes[0]);
9113
9114 hddLog(VOS_TRACE_LEVEL_ERROR,
Arif Hussain24bafea2013-11-15 15:10:03 -08009115 "%s: client " MAC_ADDRESS_STR " of SoftAP/P2P-GO is in the "
9116 "middle of WPS/EAPOL exchange.", __func__,
9117 MAC_ADDR_ARRAY(staMac));
Rashmi Ramannab1429032014-04-26 14:59:09 +05309118 return VOS_TRUE;
Madan Mohan Koyyalamudicfd53742013-01-11 15:29:03 -08009119 }
9120 }
9121 }
9122 }
9123 status = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
9124 pAdapterNode = pNext;
9125 }
Rashmi Ramannab1429032014-04-26 14:59:09 +05309126 return VOS_FALSE;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309127}
Madan Mohan Koyyalamudicfd53742013-01-11 15:29:03 -08009128
9129/*
Mahesh A Saptasagarfafb7fe2014-05-16 13:19:37 +05309130 * FUNCTION: __wlan_hdd_cfg80211_scan
Jeff Johnson295189b2012-06-20 16:38:30 -07009131 * this scan respond to scan trigger and update cfg80211 scan database
9132 * later, scan dump command can be used to recieve scan results
9133 */
Mahesh A Saptasagarfafb7fe2014-05-16 13:19:37 +05309134int __wlan_hdd_cfg80211_scan( struct wiphy *wiphy,
Jeff Johnson3bbe4bf2013-01-18 17:05:29 -08009135#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,6,0))
9136 struct net_device *dev,
9137#endif
9138 struct cfg80211_scan_request *request)
9139{
Siddharth Bhal0c162d02014-05-06 19:50:42 +05309140 hdd_adapter_t *pAdapter = NULL;
9141 hdd_context_t *pHddCtx = NULL;
9142 hdd_wext_state_t *pwextBuf = NULL;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05309143 hdd_config_t *cfg_param = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -07009144 tCsrScanRequest scanRequest;
9145 tANI_U8 *channelList = NULL, i;
9146 v_U32_t scanId = 0;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05309147 int status;
9148 hdd_scaninfo_t *pScanInfo = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -07009149 v_U8_t* pP2pIe = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -07009150
Siddharth Bhal0c162d02014-05-06 19:50:42 +05309151#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,6,0))
9152 struct net_device *dev = NULL;
9153 if (NULL == request)
9154 {
9155 hddLog(VOS_TRACE_LEVEL_ERROR,
9156 "%s: scan req param null", __func__);
9157 return -EINVAL;
9158 }
9159 dev = request->wdev->netdev;
9160#endif
9161
9162 pAdapter = WLAN_HDD_GET_PRIV_PTR( dev );
9163 pHddCtx = WLAN_HDD_GET_CTX( pAdapter );
9164 pwextBuf = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
9165
Jeff Johnson295189b2012-06-20 16:38:30 -07009166 ENTER();
9167
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +05309168
Sushant Kaushik8bc7df22014-04-09 17:55:29 +05309169 hddLog(VOS_TRACE_LEVEL_INFO, "%s: device_mode = %s (%d)",
9170 __func__, hdd_device_modetoString(pAdapter->device_mode),
9171 pAdapter->device_mode);
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +05309172
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05309173 status = wlan_hdd_validate_context(pHddCtx);
9174
9175 if (0 != status)
9176 {
9177 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
9178 "%s: HDD context is not valid", __func__);
9179 return status;
9180 }
9181
Siddharth Bhal0c162d02014-05-06 19:50:42 +05309182 if (NULL == pwextBuf)
9183 {
9184 hddLog (VOS_TRACE_LEVEL_ERROR, "%s ERROR: invalid WEXT state\n",
9185 __func__);
9186 return -EIO;
9187 }
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05309188 cfg_param = pHddCtx->cfg_ini;
9189 pScanInfo = &pHddCtx->scan_info;
9190
Jeff Johnson295189b2012-06-20 16:38:30 -07009191#ifdef WLAN_BTAMP_FEATURE
9192 //Scan not supported when AMP traffic is on.
Gopichand Nakkala681989c2013-03-06 22:27:48 -08009193 if (VOS_TRUE == WLANBAP_AmpSessionOn())
Jeff Johnson295189b2012-06-20 16:38:30 -07009194 {
Madan Mohan Koyyalamudifd4e1da2012-11-09 17:50:19 -08009195 hddLog(VOS_TRACE_LEVEL_ERROR,
Jeff Johnson295189b2012-06-20 16:38:30 -07009196 "%s: No scanning when AMP is on", __func__);
9197 return -EOPNOTSUPP;
9198 }
9199#endif
9200 //Scan on any other interface is not supported.
Gopichand Nakkala681989c2013-03-06 22:27:48 -08009201 if (pAdapter->device_mode == WLAN_HDD_SOFTAP)
Jeff Johnson295189b2012-06-20 16:38:30 -07009202 {
Gopichand Nakkala681989c2013-03-06 22:27:48 -08009203 hddLog(VOS_TRACE_LEVEL_ERROR,
Sushant Kaushik8bc7df22014-04-09 17:55:29 +05309204 "%s: Not scanning on device_mode = %s (%d)",
9205 __func__, hdd_device_modetoString(pAdapter->device_mode),
9206 pAdapter->device_mode);
Jeff Johnson295189b2012-06-20 16:38:30 -07009207 return -EOPNOTSUPP;
9208 }
9209
9210 if (TRUE == pScanInfo->mScanPending)
9211 {
Kiet Lamac06e2c2013-10-23 16:25:07 +05309212 if ( MAX_PENDING_LOG > pScanInfo->mScanPendingCounter++ )
9213 {
9214 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: mScanPending is TRUE", __func__);
9215 }
Gopichand Nakkala681989c2013-03-06 22:27:48 -08009216 return -EBUSY;
Jeff Johnson295189b2012-06-20 16:38:30 -07009217 }
9218
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309219 //Don't Allow Scan and return busy if Remain On
Jeff Johnson32d95a32012-09-10 13:15:23 -07009220 //Channel and action frame is pending
9221 //Otherwise Cancel Remain On Channel and allow Scan
9222 //If no action frame pending
Gopichand Nakkala681989c2013-03-06 22:27:48 -08009223 if (0 != wlan_hdd_check_remain_on_channel(pAdapter))
Jeff Johnson32d95a32012-09-10 13:15:23 -07009224 {
Kiet Lamac06e2c2013-10-23 16:25:07 +05309225 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Remain On Channel Pending", __func__);
Jeff Johnson32d95a32012-09-10 13:15:23 -07009226 return -EBUSY;
9227 }
Gopichand Nakkala681989c2013-03-06 22:27:48 -08009228#ifdef FEATURE_WLAN_TDLS
Gopichand Nakkala638ebc72013-03-21 18:04:02 -07009229 /* if tdls disagree scan right now, return immediately.
9230 tdls will schedule the scan when scan is allowed. (return SUCCESS)
9231 or will reject the scan if any TDLS is in progress. (return -EBUSY)
9232 */
9233 status = wlan_hdd_tdls_scan_callback (pAdapter,
9234 wiphy,
9235#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,6,0))
9236 dev,
Gopichand Nakkalac3c42b92013-03-20 19:42:34 -07009237#endif
Gopichand Nakkala638ebc72013-03-21 18:04:02 -07009238 request);
9239 if(status <= 0)
9240 {
Nirav Shah20ac06f2013-12-12 18:14:06 +05309241 if(!status)
9242 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: TDLS in progress."
9243 "scan rejected %d", __func__, status);
9244 else
9245 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: TDLS teardown is ongoing %d",
9246 __func__, status);
9247
Gopichand Nakkala638ebc72013-03-21 18:04:02 -07009248 return status;
Gopichand Nakkala681989c2013-03-06 22:27:48 -08009249 }
9250#endif
Jeff Johnson32d95a32012-09-10 13:15:23 -07009251
Jeff Johnson295189b2012-06-20 16:38:30 -07009252 if (mutex_lock_interruptible(&pHddCtx->tmInfo.tmOperationLock))
9253 {
9254 VOS_TRACE(VOS_MODULE_ID_HDD,VOS_TRACE_LEVEL_ERROR,
Jeff Johnson1250df42012-12-10 14:31:52 -08009255 "%s: Acquire lock fail", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07009256 return -EAGAIN;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309257 }
Jeff Johnson295189b2012-06-20 16:38:30 -07009258 if (TRUE == pHddCtx->tmInfo.tmAction.enterImps)
9259 {
Nirav Shah20ac06f2013-12-12 18:14:06 +05309260 hddLog(VOS_TRACE_LEVEL_ERROR,
Jeff Johnson295189b2012-06-20 16:38:30 -07009261 "%s: MAX TM Level Scan not allowed", __func__);
9262 mutex_unlock(&pHddCtx->tmInfo.tmOperationLock);
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309263 return -EBUSY;
Jeff Johnson295189b2012-06-20 16:38:30 -07009264 }
9265 mutex_unlock(&pHddCtx->tmInfo.tmOperationLock);
9266
Madan Mohan Koyyalamudicfd53742013-01-11 15:29:03 -08009267 /* Check if scan is allowed at this point of time.
9268 */
Ganesh Kondabattiniaeb7b772014-08-11 20:00:36 +05309269 if (hdd_isConnectionInProgress(pHddCtx, VOS_FALSE))
Madan Mohan Koyyalamudicfd53742013-01-11 15:29:03 -08009270 {
9271 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Scan not allowed", __func__);
9272 return -EBUSY;
9273 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309274
Jeff Johnson295189b2012-06-20 16:38:30 -07009275 vos_mem_zero( &scanRequest, sizeof(scanRequest));
9276
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +05309277 hddLog(VOS_TRACE_LEVEL_INFO, "scan request for ssid = %d",
9278 (int)request->n_ssids);
9279
9280 /* Even though supplicant doesn't provide any SSIDs, n_ssids is set to 1.
9281 * Becasue of this, driver is assuming that this is not wildcard scan and so
9282 * is not aging out the scan results.
9283 */
9284 if (request->ssids && '\0' == request->ssids->ssid[0])
Jeff Johnson295189b2012-06-20 16:38:30 -07009285 {
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +05309286 request->n_ssids = 0;
Jeff Johnson295189b2012-06-20 16:38:30 -07009287 }
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +05309288
9289 if ((request->ssids) && (0 < request->n_ssids))
9290 {
9291 tCsrSSIDInfo *SsidInfo;
9292 int j;
9293 scanRequest.SSIDs.numOfSSIDs = request->n_ssids;
9294 /* Allocate num_ssid tCsrSSIDInfo structure */
9295 SsidInfo = scanRequest.SSIDs.SSIDList =
9296 ( tCsrSSIDInfo *)vos_mem_malloc(
9297 request->n_ssids*sizeof(tCsrSSIDInfo));
9298
9299 if(NULL == scanRequest.SSIDs.SSIDList)
9300 {
9301 hddLog(VOS_TRACE_LEVEL_ERROR,
9302 "%s: memory alloc failed SSIDInfo buffer", __func__);
9303 return -ENOMEM;
9304 }
9305
9306 /* copy all the ssid's and their length */
9307 for(j = 0; j < request->n_ssids; j++, SsidInfo++)
9308 {
9309 /* get the ssid length */
9310 SsidInfo->SSID.length = request->ssids[j].ssid_len;
9311 vos_mem_copy(SsidInfo->SSID.ssId, &request->ssids[j].ssid[0],
9312 SsidInfo->SSID.length);
9313 SsidInfo->SSID.ssId[SsidInfo->SSID.length] = '\0';
9314 hddLog(VOS_TRACE_LEVEL_INFO, "SSID number %d: %s",
9315 j, SsidInfo->SSID.ssId);
9316 }
9317 /* set the scan type to active */
9318 scanRequest.scanType = eSIR_ACTIVE_SCAN;
9319 }
9320 else if(WLAN_HDD_P2P_GO == pAdapter->device_mode)
Jeff Johnson295189b2012-06-20 16:38:30 -07009321 {
Siddharth Bhal0c162d02014-05-06 19:50:42 +05309322 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
9323 TRACE_CODE_HDD_CFG80211_SCAN,
9324 pAdapter->sessionId, 0));
Jeff Johnson295189b2012-06-20 16:38:30 -07009325 /* set the scan type to active */
9326 scanRequest.scanType = eSIR_ACTIVE_SCAN;
Jeff Johnson295189b2012-06-20 16:38:30 -07009327 }
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +05309328 else
9329 {
9330 /*Set the scan type to default type, in this case it is ACTIVE*/
9331 scanRequest.scanType = pScanInfo->scan_mode;
9332 }
9333 scanRequest.minChnTime = cfg_param->nActiveMinChnTime;
9334 scanRequest.maxChnTime = cfg_param->nActiveMaxChnTime;
Jeff Johnson295189b2012-06-20 16:38:30 -07009335
9336 /* set BSSType to default type */
9337 scanRequest.BSSType = eCSR_BSS_TYPE_ANY;
9338
9339 /*TODO: scan the requested channels only*/
9340
9341 /*Right now scanning all the channels */
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +05309342 if (MAX_CHANNEL < request->n_channels)
Jeff Johnson295189b2012-06-20 16:38:30 -07009343 {
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +05309344 hddLog(VOS_TRACE_LEVEL_WARN,
9345 "No of Scan Channels exceeded limit: %d", request->n_channels);
9346 request->n_channels = MAX_CHANNEL;
9347 }
9348
9349 hddLog(VOS_TRACE_LEVEL_INFO,
9350 "No of Scan Channels: %d", request->n_channels);
9351
9352
9353 if( request->n_channels )
9354 {
9355 char chList [(request->n_channels*5)+1];
9356 int len;
9357 channelList = vos_mem_malloc( request->n_channels );
9358 if( NULL == channelList )
c_hpothu53512302014-04-15 18:49:53 +05309359 {
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +05309360 hddLog(VOS_TRACE_LEVEL_ERROR,
9361 "%s: memory alloc failed channelList", __func__);
9362 status = -ENOMEM;
9363 goto free_mem;
c_hpothu53512302014-04-15 18:49:53 +05309364 }
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +05309365
9366 for( i = 0, len = 0; i < request->n_channels ; i++ )
9367 {
9368 channelList[i] = request->channels[i]->hw_value;
9369 len += snprintf(chList+len, 5, "%d ", channelList[i]);
9370 }
9371
Nirav Shah20ac06f2013-12-12 18:14:06 +05309372 hddLog(VOS_TRACE_LEVEL_INFO,
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +05309373 "Channel-List: %s ", chList);
9374 }
c_hpothu53512302014-04-15 18:49:53 +05309375
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +05309376 scanRequest.ChannelInfo.numOfChannels = request->n_channels;
9377 scanRequest.ChannelInfo.ChannelList = channelList;
9378
9379 /* set requestType to full scan */
9380 scanRequest.requestType = eCSR_SCAN_REQUEST_FULL_SCAN;
9381
9382 /* Flush the scan results(only p2p beacons) for STA scan and P2P
9383 * search (Flush on both full scan and social scan but not on single
9384 * channel scan).P2P search happens on 3 social channels (1, 6, 11)
9385 */
9386
9387 /* Supplicant does single channel scan after 8-way handshake
9388 * and in that case driver shoudnt flush scan results. If
9389 * driver flushes the scan results here and unfortunately if
9390 * the AP doesnt respond to our probe req then association
9391 * fails which is not desired
9392 */
9393
9394 if( request->n_channels != WLAN_HDD_P2P_SINGLE_CHANNEL_SCAN )
9395 {
9396 hddLog(VOS_TRACE_LEVEL_DEBUG, "Flushing P2P Results");
9397 sme_ScanFlushP2PResult( WLAN_HDD_GET_HAL_CTX(pAdapter),
9398 pAdapter->sessionId );
9399 }
9400
9401 if( request->ie_len )
9402 {
9403 /* save this for future association (join requires this) */
9404 /*TODO: Array needs to be converted to dynamic allocation,
9405 * as multiple ie.s can be sent in cfg80211_scan_request structure
9406 * CR 597966
9407 */
9408 memset( &pScanInfo->scanAddIE, 0, sizeof(pScanInfo->scanAddIE) );
9409 memcpy( pScanInfo->scanAddIE.addIEdata, request->ie, request->ie_len);
9410 pScanInfo->scanAddIE.length = request->ie_len;
9411
9412 if ((WLAN_HDD_INFRA_STATION == pAdapter->device_mode) ||
9413 (WLAN_HDD_P2P_CLIENT == pAdapter->device_mode) ||
9414 (WLAN_HDD_P2P_DEVICE == pAdapter->device_mode))
Jeff Johnson295189b2012-06-20 16:38:30 -07009415 {
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +05309416 if ( request->ie_len <= SIR_MAC_MAX_IE_LENGTH)
Jeff Johnson295189b2012-06-20 16:38:30 -07009417 {
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +05309418 pwextBuf->roamProfile.nAddIEScanLength = request->ie_len;
9419 memcpy( pwextBuf->roamProfile.addIEScan,
9420 request->ie, request->ie_len);
9421 }
9422 else
9423 {
9424 hddLog(VOS_TRACE_LEVEL_ERROR, "Scan Ie length is invalid:"
9425 "%zu", request->ie_len);
Jeff Johnson295189b2012-06-20 16:38:30 -07009426 }
9427
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +05309428 }
9429 scanRequest.uIEFieldLen = pScanInfo->scanAddIE.length;
9430 scanRequest.pIEField = pScanInfo->scanAddIE.addIEdata;
9431
9432 pP2pIe = wlan_hdd_get_p2p_ie_ptr((v_U8_t*)request->ie,
9433 request->ie_len);
9434 if (pP2pIe != NULL)
9435 {
9436#ifdef WLAN_FEATURE_P2P_DEBUG
9437 if (((globalP2PConnectionStatus == P2P_GO_NEG_COMPLETED) ||
9438 (globalP2PConnectionStatus == P2P_GO_NEG_PROCESS)) &&
9439 (WLAN_HDD_P2P_CLIENT == pAdapter->device_mode))
Nirav Shah20ac06f2013-12-12 18:14:06 +05309440 {
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +05309441 globalP2PConnectionStatus = P2P_CLIENT_CONNECTING_STATE_1;
9442 hddLog(VOS_TRACE_LEVEL_ERROR,"[P2P State] Changing state from "
9443 "Go nego completed to Connection is started");
9444 hddLog(VOS_TRACE_LEVEL_ERROR,"[P2P]P2P Scanning is started "
9445 "for 8way Handshake");
Nirav Shah20ac06f2013-12-12 18:14:06 +05309446 }
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +05309447 else if((globalP2PConnectionStatus == P2P_CLIENT_DISCONNECTED_STATE) &&
9448 (WLAN_HDD_P2P_CLIENT == pAdapter->device_mode))
Jeff Johnson295189b2012-06-20 16:38:30 -07009449 {
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +05309450 globalP2PConnectionStatus = P2P_CLIENT_CONNECTING_STATE_2;
9451 hddLog(VOS_TRACE_LEVEL_ERROR,"[P2P State] Changing state from "
9452 "Disconnected state to Connection is started");
9453 hddLog(VOS_TRACE_LEVEL_ERROR,"[P2P]P2P Scanning is started "
9454 "for 4way Handshake");
9455 }
9456#endif
9457
9458 /* no_cck will be set during p2p find to disable 11b rates */
9459 if(TRUE == request->no_cck)
9460 {
9461 hddLog(VOS_TRACE_LEVEL_INFO,
9462 "%s: This is a P2P Search", __func__);
9463 scanRequest.p2pSearch = 1;
9464
9465 if( request->n_channels == WLAN_HDD_P2P_SOCIAL_CHANNELS )
Agarwal Ashish4f616132013-12-30 23:32:50 +05309466 {
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +05309467 /* set requestType to P2P Discovery */
9468 scanRequest.requestType = eCSR_SCAN_P2P_DISCOVERY;
9469 }
9470
9471 /*
9472 Skip Dfs Channel in case of P2P Search
9473 if it is set in ini file
9474 */
9475 if(cfg_param->skipDfsChnlInP2pSearch)
9476 {
9477 scanRequest.skipDfsChnlInP2pSearch = 1;
Agarwal Ashish4f616132013-12-30 23:32:50 +05309478 }
9479 else
9480 {
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +05309481 scanRequest.skipDfsChnlInP2pSearch = 0;
Agarwal Ashish4f616132013-12-30 23:32:50 +05309482 }
Jeff Johnson295189b2012-06-20 16:38:30 -07009483
Agarwal Ashish4f616132013-12-30 23:32:50 +05309484 }
Jeff Johnson295189b2012-06-20 16:38:30 -07009485 }
9486 }
9487
9488 INIT_COMPLETION(pScanInfo->scan_req_completion_event);
9489
Madan Mohan Koyyalamudi9f5a10c2012-09-28 14:46:16 -07009490 /* acquire the wakelock to avoid the apps suspend during the scan. To
9491 * address the following issues.
9492 * 1) Disconnected scenario: we are not allowing the suspend as WLAN is not in
9493 * BMPS/IMPS this result in android trying to suspend aggressively and backing off
9494 * for long time, this result in apps running at full power for long time.
9495 * 2) Connected scenario: If we allow the suspend during the scan, RIVA will
9496 * be stuck in full power because of resume BMPS
9497 */
9498 hdd_prevent_suspend();
Jeff Johnsone7245742012-09-05 17:12:55 -07009499
Nirav Shah20ac06f2013-12-12 18:14:06 +05309500 hddLog(VOS_TRACE_LEVEL_INFO_HIGH,
9501 "requestType %d, scanType %d, minChnTime %d, maxChnTime %d,"
Sushant Kaushik8bc7df22014-04-09 17:55:29 +05309502 "p2pSearch %d, skipDfsChnlInP2pSearch %d",
9503 scanRequest.requestType, scanRequest.scanType,
9504 scanRequest.minChnTime, scanRequest.maxChnTime,
Nirav Shah20ac06f2013-12-12 18:14:06 +05309505 scanRequest.p2pSearch, scanRequest.skipDfsChnlInP2pSearch);
9506
Jeff Johnsone7245742012-09-05 17:12:55 -07009507 status = sme_ScanRequest( WLAN_HDD_GET_HAL_CTX(pAdapter),
Jeff Johnson295189b2012-06-20 16:38:30 -07009508 pAdapter->sessionId, &scanRequest, &scanId,
9509 &hdd_cfg80211_scan_done_callback, dev );
Jeff Johnsone7245742012-09-05 17:12:55 -07009510
Jeff Johnson295189b2012-06-20 16:38:30 -07009511 if (eHAL_STATUS_SUCCESS != status)
9512 {
9513 hddLog(VOS_TRACE_LEVEL_ERROR,
9514 "%s: sme_ScanRequest returned error %d", __func__, status);
9515 complete(&pScanInfo->scan_req_completion_event);
Madan Mohan Koyyalamudi3b230fe2012-10-18 14:46:32 -07009516 if(eHAL_STATUS_RESOURCES == status)
9517 {
Nirav Shah20ac06f2013-12-12 18:14:06 +05309518 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: HO is in progress."
9519 "So defer the scan by informing busy",__func__);
Madan Mohan Koyyalamudi3b230fe2012-10-18 14:46:32 -07009520 status = -EBUSY;
9521 } else {
9522 status = -EIO;
9523 }
Madan Mohan Koyyalamudi9f5a10c2012-09-28 14:46:16 -07009524 hdd_allow_suspend();
Jeff Johnson295189b2012-06-20 16:38:30 -07009525 goto free_mem;
9526 }
9527
9528 pScanInfo->mScanPending = TRUE;
9529 pAdapter->request = request;
9530 pScanInfo->scanId = scanId;
9531
9532 complete(&pScanInfo->scan_req_completion_event);
9533
9534free_mem:
9535 if( scanRequest.SSIDs.SSIDList )
9536 {
9537 vos_mem_free(scanRequest.SSIDs.SSIDList);
9538 }
9539
9540 if( channelList )
9541 vos_mem_free( channelList );
9542
9543 EXIT();
9544
9545 return status;
9546}
9547
Mahesh A Saptasagarfafb7fe2014-05-16 13:19:37 +05309548int wlan_hdd_cfg80211_scan( struct wiphy *wiphy,
9549#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,6,0))
9550 struct net_device *dev,
9551#endif
9552 struct cfg80211_scan_request *request)
9553{
9554 int ret;
9555
9556 vos_ssr_protect(__func__);
9557 ret = __wlan_hdd_cfg80211_scan(wiphy,
9558#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,6,0))
9559 dev,
9560#endif
9561 request);
9562 vos_ssr_unprotect(__func__);
9563
9564 return ret;
9565}
Shailender Karmuchi15cd0672013-05-15 19:50:04 -07009566
9567void hdd_select_cbmode( hdd_adapter_t *pAdapter,v_U8_t operationChannel)
9568{
9569 v_U8_t iniDot11Mode =
9570 (WLAN_HDD_GET_CTX(pAdapter))->cfg_ini->dot11Mode;
9571 eHddDot11Mode hddDot11Mode = iniDot11Mode;
9572
Arun Kumar Khandavalli94a2bb02013-12-28 19:17:25 +05309573 hddLog(LOG1, FL("Channel Bonding Mode Selected is %u"),
9574 iniDot11Mode);
Shailender Karmuchi15cd0672013-05-15 19:50:04 -07009575 switch ( iniDot11Mode )
9576 {
9577 case eHDD_DOT11_MODE_AUTO:
9578 case eHDD_DOT11_MODE_11ac:
9579 case eHDD_DOT11_MODE_11ac_ONLY:
9580#ifdef WLAN_FEATURE_11AC
Abhishek Singh4b1d2352014-08-01 21:59:28 +05309581 if ( sme_IsFeatureSupportedByDriver(DOT11AC) &&
9582 sme_IsFeatureSupportedByFW(DOT11AC) )
9583 hddDot11Mode = eHDD_DOT11_MODE_11ac;
9584 else
9585 hddDot11Mode = eHDD_DOT11_MODE_11n;
Shailender Karmuchi15cd0672013-05-15 19:50:04 -07009586#else
9587 hddDot11Mode = eHDD_DOT11_MODE_11n;
9588#endif
9589 break;
9590 case eHDD_DOT11_MODE_11n:
9591 case eHDD_DOT11_MODE_11n_ONLY:
9592 hddDot11Mode = eHDD_DOT11_MODE_11n;
9593 break;
9594 default:
9595 hddDot11Mode = iniDot11Mode;
9596 break;
9597 }
9598 /* This call decides required channel bonding mode */
9599 sme_SelectCBMode((WLAN_HDD_GET_CTX(pAdapter)->hHal),
9600 hdd_cfg_xlate_to_csr_phy_mode(hddDot11Mode),
9601 operationChannel);
9602}
9603
Jeff Johnson295189b2012-06-20 16:38:30 -07009604/*
9605 * FUNCTION: wlan_hdd_cfg80211_connect_start
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309606 * This function is used to start the association process
Jeff Johnson295189b2012-06-20 16:38:30 -07009607 */
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309608int wlan_hdd_cfg80211_connect_start( hdd_adapter_t *pAdapter,
Jeff Johnson32d95a32012-09-10 13:15:23 -07009609 const u8 *ssid, size_t ssid_len, const u8 *bssid, u8 operatingChannel)
Jeff Johnson295189b2012-06-20 16:38:30 -07009610{
9611 int status = 0;
9612 hdd_wext_state_t *pWextState;
Yue Mae36e3552014-03-05 17:06:20 -08009613 hdd_context_t *pHddCtx;
Jeff Johnson295189b2012-06-20 16:38:30 -07009614 v_U32_t roamId;
9615 tCsrRoamProfile *pRoamProfile;
Jeff Johnson295189b2012-06-20 16:38:30 -07009616 eCsrAuthType RSNAuthType;
9617
9618 ENTER();
9619
9620 pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
Yue Mae36e3552014-03-05 17:06:20 -08009621 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
9622
9623 status = wlan_hdd_validate_context(pHddCtx);
9624 if (status)
9625 {
9626 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
9627 "%s: HDD context is not valid!", __func__);
9628 return status;
9629 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309630
Jeff Johnson295189b2012-06-20 16:38:30 -07009631 if (SIR_MAC_MAX_SSID_LENGTH < ssid_len)
9632 {
9633 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: wrong SSID len", __func__);
9634 return -EINVAL;
9635 }
9636
9637 pRoamProfile = &pWextState->roamProfile;
9638
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309639 if (pRoamProfile)
Jeff Johnson295189b2012-06-20 16:38:30 -07009640 {
Jeff Johnsone7245742012-09-05 17:12:55 -07009641 hdd_station_ctx_t *pHddStaCtx;
9642 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
Jeff Johnson295189b2012-06-20 16:38:30 -07009643
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309644 if (HDD_WMM_USER_MODE_NO_QOS ==
Jeff Johnson295189b2012-06-20 16:38:30 -07009645 (WLAN_HDD_GET_CTX(pAdapter))->cfg_ini->WmmMode)
9646 {
9647 /*QoS not enabled in cfg file*/
9648 pRoamProfile->uapsd_mask = 0;
9649 }
9650 else
9651 {
9652 /*QoS enabled, update uapsd mask from cfg file*/
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309653 pRoamProfile->uapsd_mask =
Jeff Johnson295189b2012-06-20 16:38:30 -07009654 (WLAN_HDD_GET_CTX(pAdapter))->cfg_ini->UapsdMask;
9655 }
9656
9657 pRoamProfile->SSIDs.numOfSSIDs = 1;
9658 pRoamProfile->SSIDs.SSIDList->SSID.length = ssid_len;
9659 vos_mem_zero(pRoamProfile->SSIDs.SSIDList->SSID.ssId,
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309660 sizeof(pRoamProfile->SSIDs.SSIDList->SSID.ssId));
Jeff Johnson295189b2012-06-20 16:38:30 -07009661 vos_mem_copy((void *)(pRoamProfile->SSIDs.SSIDList->SSID.ssId),
9662 ssid, ssid_len);
9663
9664 if (bssid)
9665 {
9666 pRoamProfile->BSSIDs.numOfBSSIDs = 1;
9667 vos_mem_copy((void *)(pRoamProfile->BSSIDs.bssid), bssid,
9668 WNI_CFG_BSSID_LEN);
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309669 /* Save BSSID in seperate variable as well, as RoamProfile
9670 BSSID is getting zeroed out in the association process. And in
Jeff Johnson295189b2012-06-20 16:38:30 -07009671 case of join failure we should send valid BSSID to supplicant
9672 */
9673 vos_mem_copy((void *)(pWextState->req_bssId), bssid,
9674 WNI_CFG_BSSID_LEN);
9675 }
Dhanashri Atre51981c62013-06-13 11:47:57 -07009676 else
9677 {
9678 vos_mem_zero((void *)(pRoamProfile->BSSIDs.bssid),WNI_CFG_BSSID_LEN);
9679 }
Jeff Johnson295189b2012-06-20 16:38:30 -07009680
Arun Kumar Khandavalli94a2bb02013-12-28 19:17:25 +05309681 hddLog(LOG1, FL("Connect to SSID: %s opertating Channel: %u"),
9682 pRoamProfile->SSIDs.SSIDList->SSID.ssId, operatingChannel);
Jeff Johnson295189b2012-06-20 16:38:30 -07009683 if ((IW_AUTH_WPA_VERSION_WPA == pWextState->wpaVersion) ||
9684 (IW_AUTH_WPA_VERSION_WPA2 == pWextState->wpaVersion))
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309685 {
Jeff Johnson295189b2012-06-20 16:38:30 -07009686 /*set gen ie*/
9687 hdd_SetGENIEToCsr(pAdapter, &RSNAuthType);
9688 /*set auth*/
9689 hdd_set_csr_auth_type(pAdapter, RSNAuthType);
9690 }
Jeff Johnson295189b2012-06-20 16:38:30 -07009691#ifdef FEATURE_WLAN_WAPI
9692 if (pAdapter->wapi_info.nWapiMode)
9693 {
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07009694 hddLog(LOG1, "%s: Setting WAPI AUTH Type and Encryption Mode values", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07009695 switch (pAdapter->wapi_info.wapiAuthMode)
9696 {
9697 case WAPI_AUTH_MODE_PSK:
9698 {
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07009699 hddLog(LOG1, "%s: WAPI AUTH TYPE: PSK: %d", __func__,
Jeff Johnson295189b2012-06-20 16:38:30 -07009700 pAdapter->wapi_info.wapiAuthMode);
9701 pRoamProfile->AuthType.authType[0] = eCSR_AUTH_TYPE_WAPI_WAI_PSK;
9702 break;
9703 }
9704 case WAPI_AUTH_MODE_CERT:
9705 {
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07009706 hddLog(LOG1, "%s: WAPI AUTH TYPE: CERT: %d", __func__,
Jeff Johnson295189b2012-06-20 16:38:30 -07009707 pAdapter->wapi_info.wapiAuthMode);
9708 pRoamProfile->AuthType.authType[0] = eCSR_AUTH_TYPE_WAPI_WAI_CERTIFICATE;
9709 break;
9710 }
9711 } // End of switch
9712 if ( pAdapter->wapi_info.wapiAuthMode == WAPI_AUTH_MODE_PSK ||
9713 pAdapter->wapi_info.wapiAuthMode == WAPI_AUTH_MODE_CERT)
9714 {
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07009715 hddLog(LOG1, "%s: WAPI PAIRWISE/GROUP ENCRYPTION: WPI", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07009716 pRoamProfile->AuthType.numEntries = 1;
9717 pRoamProfile->EncryptionType.numEntries = 1;
9718 pRoamProfile->EncryptionType.encryptionType[0] = eCSR_ENCRYPT_TYPE_WPI;
9719 pRoamProfile->mcEncryptionType.numEntries = 1;
9720 pRoamProfile->mcEncryptionType.encryptionType[0] = eCSR_ENCRYPT_TYPE_WPI;
9721 }
9722 }
9723#endif /* FEATURE_WLAN_WAPI */
Gopichand Nakkala870cbae2013-03-15 21:16:09 +05309724#ifdef WLAN_FEATURE_GTK_OFFLOAD
Gopichand Nakkalad36ee622013-05-07 14:13:27 +05309725 /* Initializing gtkOffloadReqParams */
Gopichand Nakkala870cbae2013-03-15 21:16:09 +05309726 if ((WLAN_HDD_INFRA_STATION == pAdapter->device_mode) ||
9727 (WLAN_HDD_P2P_CLIENT == pAdapter->device_mode))
9728 {
Gopichand Nakkalad36ee622013-05-07 14:13:27 +05309729 memset(&pHddStaCtx->gtkOffloadReqParams, 0,
9730 sizeof (tSirGtkOffloadParams));
9731 pHddStaCtx->gtkOffloadReqParams.ulFlags = GTK_OFFLOAD_DISABLE;
Gopichand Nakkala870cbae2013-03-15 21:16:09 +05309732 }
9733#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07009734 pRoamProfile->csrPersona = pAdapter->device_mode;
9735
Jeff Johnson32d95a32012-09-10 13:15:23 -07009736 if( operatingChannel )
9737 {
9738 pRoamProfile->ChannelInfo.ChannelList = &operatingChannel;
9739 pRoamProfile->ChannelInfo.numOfChannels = 1;
9740 }
Chet Lanctot186b5732013-03-18 10:26:30 -07009741 else
9742 {
9743 pRoamProfile->ChannelInfo.ChannelList = NULL;
9744 pRoamProfile->ChannelInfo.numOfChannels = 0;
9745 }
Shailender Karmuchi15cd0672013-05-15 19:50:04 -07009746 if ( (WLAN_HDD_IBSS == pAdapter->device_mode) && operatingChannel)
9747 {
9748 hdd_select_cbmode(pAdapter,operatingChannel);
9749 }
Arun Kumar Khandavalli94a2bb02013-12-28 19:17:25 +05309750
Madan Mohan Koyyalamudi42dcd162012-12-03 16:34:04 -08009751 /* change conn_state to connecting before sme_RoamConnect(), because sme_RoamConnect()
9752 * has a direct path to call hdd_smeRoamCallback(), which will change the conn_state
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309753 * If direct path, conn_state will be accordingly changed to NotConnected or Associated
Madan Mohan Koyyalamudi42dcd162012-12-03 16:34:04 -08009754 * by either hdd_AssociationCompletionHandler() or hdd_DisConnectHandler() in sme_RoamCallback()
Madan Mohan Koyyalamudidf86c422012-12-04 17:03:44 -08009755 * if sme_RomConnect is to be queued, Connecting state will remain until it is completed.
9756 */
Gopichand Nakkalaa3c8fb62013-06-21 15:36:42 +05309757 if (WLAN_HDD_INFRA_STATION == pAdapter->device_mode ||
9758 WLAN_HDD_P2P_CLIENT == pAdapter->device_mode)
Abhishek Singhf4669da2014-05-26 15:07:49 +05309759 {
9760 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
9761 "%s: Set HDD connState to eConnectionState_Connecting",
9762 __func__);
Madan Mohan Koyyalamudidf86c422012-12-04 17:03:44 -08009763 hdd_connSetConnectionState(WLAN_HDD_GET_STATION_CTX_PTR(pAdapter),
9764 eConnectionState_Connecting);
Abhishek Singhf4669da2014-05-26 15:07:49 +05309765 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309766 status = sme_RoamConnect( WLAN_HDD_GET_HAL_CTX(pAdapter),
Jeff Johnson295189b2012-06-20 16:38:30 -07009767 pAdapter->sessionId, pRoamProfile, &roamId);
9768
Gopichand Nakkalaa3c8fb62013-06-21 15:36:42 +05309769 if ((eHAL_STATUS_SUCCESS != status) &&
9770 (WLAN_HDD_INFRA_STATION == pAdapter->device_mode ||
9771 WLAN_HDD_P2P_CLIENT == pAdapter->device_mode))
Madan Mohan Koyyalamudid5acbf52012-11-28 01:45:08 +05309772
9773 {
Madan Mohan Koyyalamudi42dcd162012-12-03 16:34:04 -08009774 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: sme_RoamConnect (session %d) failed with "
9775 "status %d. -> NotConnected", __func__, pAdapter->sessionId, status);
9776 /* change back to NotAssociated */
Madan Mohan Koyyalamudid5acbf52012-11-28 01:45:08 +05309777 hdd_connSetConnectionState(WLAN_HDD_GET_STATION_CTX_PTR(pAdapter),
Madan Mohan Koyyalamudi42dcd162012-12-03 16:34:04 -08009778 eConnectionState_NotConnected);
Madan Mohan Koyyalamudid5acbf52012-11-28 01:45:08 +05309779 }
Madan Mohan Koyyalamudidf86c422012-12-04 17:03:44 -08009780
9781 pRoamProfile->ChannelInfo.ChannelList = NULL;
9782 pRoamProfile->ChannelInfo.numOfChannels = 0;
9783
Jeff Johnson295189b2012-06-20 16:38:30 -07009784 }
9785 else
9786 {
9787 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: No valid Roam profile", __func__);
9788 return -EINVAL;
9789 }
Madan Mohan Koyyalamudifd4e1da2012-11-09 17:50:19 -08009790 EXIT();
Jeff Johnson295189b2012-06-20 16:38:30 -07009791 return status;
9792}
9793
9794/*
9795 * FUNCTION: wlan_hdd_set_cfg80211_auth_type
9796 * This function is used to set the authentication type (OPEN/SHARED).
9797 *
9798 */
9799static int wlan_hdd_cfg80211_set_auth_type(hdd_adapter_t *pAdapter,
9800 enum nl80211_auth_type auth_type)
9801{
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309802 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
Jeff Johnson295189b2012-06-20 16:38:30 -07009803 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
9804
9805 ENTER();
9806
9807 /*set authentication type*/
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309808 switch (auth_type)
Jeff Johnson295189b2012-06-20 16:38:30 -07009809 {
Jeff Johnson295189b2012-06-20 16:38:30 -07009810 case NL80211_AUTHTYPE_AUTOMATIC:
Gopichand Nakkala29149562013-05-10 21:43:41 +05309811 hddLog(VOS_TRACE_LEVEL_INFO,
9812 "%s: set authentication type to AUTOSWITCH", __func__);
9813 pHddStaCtx->conn_info.authType = eCSR_AUTH_TYPE_AUTOSWITCH;
9814 break;
9815
9816 case NL80211_AUTHTYPE_OPEN_SYSTEM:
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -07009817#ifdef WLAN_FEATURE_VOWIFI_11R
9818 case NL80211_AUTHTYPE_FT:
9819#endif /* WLAN_FEATURE_VOWIFI_11R */
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309820 hddLog(VOS_TRACE_LEVEL_INFO,
Jeff Johnson295189b2012-06-20 16:38:30 -07009821 "%s: set authentication type to OPEN", __func__);
9822 pHddStaCtx->conn_info.authType = eCSR_AUTH_TYPE_OPEN_SYSTEM;
9823 break;
9824
9825 case NL80211_AUTHTYPE_SHARED_KEY:
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309826 hddLog(VOS_TRACE_LEVEL_INFO,
Jeff Johnson295189b2012-06-20 16:38:30 -07009827 "%s: set authentication type to SHARED", __func__);
9828 pHddStaCtx->conn_info.authType = eCSR_AUTH_TYPE_SHARED_KEY;
9829 break;
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08009830#ifdef FEATURE_WLAN_ESE
Jeff Johnson295189b2012-06-20 16:38:30 -07009831 case NL80211_AUTHTYPE_NETWORK_EAP:
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309832 hddLog(VOS_TRACE_LEVEL_INFO,
Jeff Johnson295189b2012-06-20 16:38:30 -07009833 "%s: set authentication type to CCKM WPA", __func__);
9834 pHddStaCtx->conn_info.authType = eCSR_AUTH_TYPE_CCKM_WPA;//eCSR_AUTH_TYPE_CCKM_RSN needs to be handled as well if required.
9835 break;
9836#endif
9837
9838
9839 default:
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309840 hddLog(VOS_TRACE_LEVEL_ERROR,
9841 "%s: Unsupported authentication type %d", __func__,
Jeff Johnson295189b2012-06-20 16:38:30 -07009842 auth_type);
9843 pHddStaCtx->conn_info.authType = eCSR_AUTH_TYPE_UNKNOWN;
9844 return -EINVAL;
9845 }
9846
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309847 pWextState->roamProfile.AuthType.authType[0] =
Jeff Johnson295189b2012-06-20 16:38:30 -07009848 pHddStaCtx->conn_info.authType;
9849 return 0;
9850}
9851
9852/*
9853 * FUNCTION: wlan_hdd_set_akm_suite
9854 * This function is used to set the key mgmt type(PSK/8021x).
9855 *
9856 */
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309857static int wlan_hdd_set_akm_suite( hdd_adapter_t *pAdapter,
Jeff Johnson295189b2012-06-20 16:38:30 -07009858 u32 key_mgmt
9859 )
9860{
9861 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
9862 ENTER();
Abhishek Singhae408032014-09-25 17:22:04 +05309863 /* Should be in ieee802_11_defs.h */
9864#define WLAN_AKM_SUITE_8021X_SHA256 0x000FAC05
9865#define WLAN_AKM_SUITE_PSK_SHA256 0x000FAC06
Jeff Johnson295189b2012-06-20 16:38:30 -07009866 /*set key mgmt type*/
9867 switch(key_mgmt)
9868 {
9869 case WLAN_AKM_SUITE_PSK:
Abhishek Singhae408032014-09-25 17:22:04 +05309870 case WLAN_AKM_SUITE_PSK_SHA256:
Gopichand Nakkala356fb102013-03-06 12:34:04 +05309871#ifdef WLAN_FEATURE_VOWIFI_11R
9872 case WLAN_AKM_SUITE_FT_PSK:
9873#endif
9874 hddLog(VOS_TRACE_LEVEL_INFO, "%s: setting key mgmt type to PSK",
Jeff Johnson295189b2012-06-20 16:38:30 -07009875 __func__);
9876 pWextState->authKeyMgmt |= IW_AUTH_KEY_MGMT_PSK;
9877 break;
9878
9879 case WLAN_AKM_SUITE_8021X:
Abhishek Singhae408032014-09-25 17:22:04 +05309880 case WLAN_AKM_SUITE_8021X_SHA256:
Gopichand Nakkala356fb102013-03-06 12:34:04 +05309881#ifdef WLAN_FEATURE_VOWIFI_11R
9882 case WLAN_AKM_SUITE_FT_8021X:
9883#endif
9884 hddLog(VOS_TRACE_LEVEL_INFO, "%s: setting key mgmt type to 8021x",
Jeff Johnson295189b2012-06-20 16:38:30 -07009885 __func__);
9886 pWextState->authKeyMgmt |= IW_AUTH_KEY_MGMT_802_1X;
9887 break;
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08009888#ifdef FEATURE_WLAN_ESE
Jeff Johnson295189b2012-06-20 16:38:30 -07009889#define WLAN_AKM_SUITE_CCKM 0x00409600 /* Should be in ieee802_11_defs.h */
9890#define IW_AUTH_KEY_MGMT_CCKM 8 /* Should be in linux/wireless.h */
9891 case WLAN_AKM_SUITE_CCKM:
9892 hddLog(VOS_TRACE_LEVEL_INFO, "%s: setting key mgmt type to CCKM",
9893 __func__);
9894 pWextState->authKeyMgmt |= IW_AUTH_KEY_MGMT_CCKM;
9895 break;
9896#endif
Leela Venkata Kiran Kumar Reddy Chiralae208a832014-04-27 22:34:25 -07009897#ifndef WLAN_AKM_SUITE_OSEN
9898#define WLAN_AKM_SUITE_OSEN 0x506f9a01 /* Should be in ieee802_11_defs.h */
9899 case WLAN_AKM_SUITE_OSEN:
9900 hddLog(VOS_TRACE_LEVEL_INFO, "%s: setting key mgmt type to OSEN",
9901 __func__);
9902 pWextState->authKeyMgmt |= IW_AUTH_KEY_MGMT_802_1X;
9903 break;
9904#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07009905
9906 default:
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309907 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Unsupported key mgmt type %d",
Jeff Johnson295189b2012-06-20 16:38:30 -07009908 __func__, key_mgmt);
9909 return -EINVAL;
9910
9911 }
9912 return 0;
9913}
9914
9915/*
9916 * FUNCTION: wlan_hdd_cfg80211_set_cipher
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309917 * This function is used to set the encryption type
Jeff Johnson295189b2012-06-20 16:38:30 -07009918 * (NONE/WEP40/WEP104/TKIP/CCMP).
9919 */
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309920static int wlan_hdd_cfg80211_set_cipher( hdd_adapter_t *pAdapter,
9921 u32 cipher,
Jeff Johnson295189b2012-06-20 16:38:30 -07009922 bool ucast
9923 )
9924{
9925 eCsrEncryptionType encryptionType = eCSR_ENCRYPT_TYPE_NONE;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309926 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
Jeff Johnson295189b2012-06-20 16:38:30 -07009927 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
9928
9929 ENTER();
9930
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309931 if (!cipher)
Jeff Johnson295189b2012-06-20 16:38:30 -07009932 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309933 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: received cipher %d - considering none",
Jeff Johnson295189b2012-06-20 16:38:30 -07009934 __func__, cipher);
9935 encryptionType = eCSR_ENCRYPT_TYPE_NONE;
9936 }
9937 else
9938 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309939
Jeff Johnson295189b2012-06-20 16:38:30 -07009940 /*set encryption method*/
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309941 switch (cipher)
Jeff Johnson295189b2012-06-20 16:38:30 -07009942 {
9943 case IW_AUTH_CIPHER_NONE:
9944 encryptionType = eCSR_ENCRYPT_TYPE_NONE;
9945 break;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309946
Jeff Johnson295189b2012-06-20 16:38:30 -07009947 case WLAN_CIPHER_SUITE_WEP40:
Gopichand Nakkala29149562013-05-10 21:43:41 +05309948 encryptionType = eCSR_ENCRYPT_TYPE_WEP40;
Jeff Johnson295189b2012-06-20 16:38:30 -07009949 break;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309950
Jeff Johnson295189b2012-06-20 16:38:30 -07009951 case WLAN_CIPHER_SUITE_WEP104:
Gopichand Nakkala29149562013-05-10 21:43:41 +05309952 encryptionType = eCSR_ENCRYPT_TYPE_WEP104;
Jeff Johnson295189b2012-06-20 16:38:30 -07009953 break;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309954
Jeff Johnson295189b2012-06-20 16:38:30 -07009955 case WLAN_CIPHER_SUITE_TKIP:
9956 encryptionType = eCSR_ENCRYPT_TYPE_TKIP;
9957 break;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309958
Jeff Johnson295189b2012-06-20 16:38:30 -07009959 case WLAN_CIPHER_SUITE_CCMP:
9960 encryptionType = eCSR_ENCRYPT_TYPE_AES;
9961 break;
9962#ifdef FEATURE_WLAN_WAPI
9963 case WLAN_CIPHER_SUITE_SMS4:
9964 encryptionType = eCSR_ENCRYPT_TYPE_WPI;
9965 break;
9966#endif
9967
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08009968#ifdef FEATURE_WLAN_ESE
Jeff Johnson295189b2012-06-20 16:38:30 -07009969 case WLAN_CIPHER_SUITE_KRK:
9970 encryptionType = eCSR_ENCRYPT_TYPE_KRK;
9971 break;
9972#endif
9973 default:
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309974 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Unsupported cipher type %d",
Jeff Johnson295189b2012-06-20 16:38:30 -07009975 __func__, cipher);
9976 return -EOPNOTSUPP;
9977 }
9978 }
9979
9980 if (ucast)
9981 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309982 hddLog(VOS_TRACE_LEVEL_INFO, "%s: setting unicast cipher type to %d",
Jeff Johnson295189b2012-06-20 16:38:30 -07009983 __func__, encryptionType);
9984 pHddStaCtx->conn_info.ucEncryptionType = encryptionType;
9985 pWextState->roamProfile.EncryptionType.numEntries = 1;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309986 pWextState->roamProfile.EncryptionType.encryptionType[0] =
Jeff Johnson295189b2012-06-20 16:38:30 -07009987 encryptionType;
9988 }
9989 else
9990 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309991 hddLog(VOS_TRACE_LEVEL_INFO, "%s: setting mcast cipher type to %d",
Jeff Johnson295189b2012-06-20 16:38:30 -07009992 __func__, encryptionType);
9993 pHddStaCtx->conn_info.mcEncryptionType = encryptionType;
9994 pWextState->roamProfile.mcEncryptionType.numEntries = 1;
9995 pWextState->roamProfile.mcEncryptionType.encryptionType[0] = encryptionType;
9996 }
9997
9998 return 0;
9999}
10000
10001
10002/*
10003 * FUNCTION: wlan_hdd_cfg80211_set_ie
10004 * This function is used to parse WPA/RSN IE's.
10005 */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010006int wlan_hdd_cfg80211_set_ie( hdd_adapter_t *pAdapter,
10007 u8 *ie,
Jeff Johnson295189b2012-06-20 16:38:30 -070010008 size_t ie_len
10009 )
10010{
10011 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
10012 u8 *genie = ie;
10013 v_U16_t remLen = ie_len;
10014#ifdef FEATURE_WLAN_WAPI
10015 v_U32_t akmsuite[MAX_NUM_AKM_SUITES];
10016 u16 *tmp;
10017 v_U16_t akmsuiteCount;
10018 int *akmlist;
10019#endif
10020 ENTER();
10021
10022 /* clear previous assocAddIE */
10023 pWextState->assocAddIE.length = 0;
10024 pWextState->roamProfile.bWPSAssociation = VOS_FALSE;
Leela Venkata Kiran Kumar Reddy Chiralaf257bef2014-04-11 18:48:12 -070010025 pWextState->roamProfile.bOSENAssociation = VOS_FALSE;
Jeff Johnson295189b2012-06-20 16:38:30 -070010026
10027 while (remLen >= 2)
10028 {
10029 v_U16_t eLen = 0;
10030 v_U8_t elementId;
10031 elementId = *genie++;
10032 eLen = *genie++;
10033 remLen -= 2;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010034
Arif Hussain6d2a3322013-11-17 19:50:10 -080010035 hddLog(VOS_TRACE_LEVEL_INFO, "%s: IE[0x%X], LEN[%d]",
Jeff Johnson295189b2012-06-20 16:38:30 -070010036 __func__, elementId, eLen);
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010037
10038 switch ( elementId )
Jeff Johnson295189b2012-06-20 16:38:30 -070010039 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010040 case DOT11F_EID_WPA:
Madan Mohan Koyyalamudief3b66e2012-10-11 14:29:42 -070010041 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 -070010042 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010043 hddLog(VOS_TRACE_LEVEL_ERROR,
Jeff Johnson295189b2012-06-20 16:38:30 -070010044 "%s: Invalid WPA IE", __func__);
10045 return -EINVAL;
10046 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010047 else if (0 == memcmp(&genie[0], "\x00\x50\xf2\x04", 4))
Jeff Johnson295189b2012-06-20 16:38:30 -070010048 {
10049 v_U16_t curAddIELen = pWextState->assocAddIE.length;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010050 hddLog (VOS_TRACE_LEVEL_INFO, "%s Set WPS IE(len %d)",
Jeff Johnson295189b2012-06-20 16:38:30 -070010051 __func__, eLen + 2);
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010052
Jeff Johnson295189b2012-06-20 16:38:30 -070010053 if( SIR_MAC_MAX_IE_LENGTH < (pWextState->assocAddIE.length + eLen) )
10054 {
Jeff Johnson902c9832012-12-10 14:28:09 -080010055 hddLog(VOS_TRACE_LEVEL_FATAL, "Cannot accommodate assocAddIE. "
10056 "Need bigger buffer space");
Jeff Johnson295189b2012-06-20 16:38:30 -070010057 VOS_ASSERT(0);
10058 return -ENOMEM;
10059 }
10060 // WSC IE is saved to Additional IE ; it should be accumulated to handle WPS IE + P2P IE
10061 memcpy( pWextState->assocAddIE.addIEdata + curAddIELen, genie - 2, eLen + 2);
10062 pWextState->assocAddIE.length += eLen + 2;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010063
Jeff Johnson295189b2012-06-20 16:38:30 -070010064 pWextState->roamProfile.bWPSAssociation = VOS_TRUE;
10065 pWextState->roamProfile.pAddIEAssoc = pWextState->assocAddIE.addIEdata;
10066 pWextState->roamProfile.nAddIEAssocLength = pWextState->assocAddIE.length;
10067 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010068 else if (0 == memcmp(&genie[0], "\x00\x50\xf2", 3))
10069 {
Jeff Johnson295189b2012-06-20 16:38:30 -070010070 hddLog (VOS_TRACE_LEVEL_INFO, "%s Set WPA IE (len %d)",__func__, eLen + 2);
10071 memset( pWextState->WPARSNIE, 0, MAX_WPA_RSN_IE_LEN );
10072 memcpy( pWextState->WPARSNIE, genie - 2, (eLen + 2) /*ie_len*/);
10073 pWextState->roamProfile.pWPAReqIE = pWextState->WPARSNIE;
10074 pWextState->roamProfile.nWPAReqIELength = eLen + 2;//ie_len;
10075 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010076 else if ( (0 == memcmp(&genie[0], P2P_OUI_TYPE,
Kiet Lam8da98992013-11-21 15:59:07 +053010077 P2P_OUI_TYPE_SIZE)))
Jeff Johnson295189b2012-06-20 16:38:30 -070010078 {
10079 v_U16_t curAddIELen = pWextState->assocAddIE.length;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010080 hddLog (VOS_TRACE_LEVEL_INFO, "%s Set P2P IE(len %d)",
Jeff Johnson295189b2012-06-20 16:38:30 -070010081 __func__, eLen + 2);
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010082
Jeff Johnson295189b2012-06-20 16:38:30 -070010083 if( SIR_MAC_MAX_IE_LENGTH < (pWextState->assocAddIE.length + eLen) )
10084 {
Jeff Johnson902c9832012-12-10 14:28:09 -080010085 hddLog(VOS_TRACE_LEVEL_FATAL, "Cannot accommodate assocAddIE "
10086 "Need bigger buffer space");
Jeff Johnson295189b2012-06-20 16:38:30 -070010087 VOS_ASSERT(0);
10088 return -ENOMEM;
10089 }
10090 // P2P IE is saved to Additional IE ; it should be accumulated to handle WPS IE + P2P IE
10091 memcpy( pWextState->assocAddIE.addIEdata + curAddIELen, genie - 2, eLen + 2);
10092 pWextState->assocAddIE.length += eLen + 2;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010093
Jeff Johnson295189b2012-06-20 16:38:30 -070010094 pWextState->roamProfile.pAddIEAssoc = pWextState->assocAddIE.addIEdata;
10095 pWextState->roamProfile.nAddIEAssocLength = pWextState->assocAddIE.length;
10096 }
Jeff Johnson295189b2012-06-20 16:38:30 -070010097#ifdef WLAN_FEATURE_WFD
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010098 else if ( (0 == memcmp(&genie[0], WFD_OUI_TYPE,
10099 WFD_OUI_TYPE_SIZE))
Jeff Johnson295189b2012-06-20 16:38:30 -070010100 /*Consider WFD IE, only for P2P Client */
10101 && (WLAN_HDD_P2P_CLIENT == pAdapter->device_mode) )
10102 {
10103 v_U16_t curAddIELen = pWextState->assocAddIE.length;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010104 hddLog (VOS_TRACE_LEVEL_INFO, "%s Set WFD IE(len %d)",
Jeff Johnson295189b2012-06-20 16:38:30 -070010105 __func__, eLen + 2);
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010106
Jeff Johnson295189b2012-06-20 16:38:30 -070010107 if( SIR_MAC_MAX_IE_LENGTH < (pWextState->assocAddIE.length + eLen) )
10108 {
Jeff Johnson902c9832012-12-10 14:28:09 -080010109 hddLog(VOS_TRACE_LEVEL_FATAL, "Cannot accommodate assocAddIE "
10110 "Need bigger buffer space");
Jeff Johnson295189b2012-06-20 16:38:30 -070010111 VOS_ASSERT(0);
10112 return -ENOMEM;
10113 }
10114 // WFD IE is saved to Additional IE ; it should be accumulated to handle
10115 // WPS IE + P2P IE + WFD IE
10116 memcpy( pWextState->assocAddIE.addIEdata + curAddIELen, genie - 2, eLen + 2);
10117 pWextState->assocAddIE.length += eLen + 2;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010118
Jeff Johnson295189b2012-06-20 16:38:30 -070010119 pWextState->roamProfile.pAddIEAssoc = pWextState->assocAddIE.addIEdata;
10120 pWextState->roamProfile.nAddIEAssocLength = pWextState->assocAddIE.length;
10121 }
10122#endif
Madan Mohan Koyyalamudief3b66e2012-10-11 14:29:42 -070010123 /* Appending HS 2.0 Indication Element in Assiciation Request */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010124 else if ( (0 == memcmp(&genie[0], HS20_OUI_TYPE,
Madan Mohan Koyyalamudi1bed5982012-10-22 14:38:06 -070010125 HS20_OUI_TYPE_SIZE)) )
10126 {
10127 v_U16_t curAddIELen = pWextState->assocAddIE.length;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010128 hddLog (VOS_TRACE_LEVEL_INFO, "%s Set HS20 IE(len %d)",
Madan Mohan Koyyalamudi1bed5982012-10-22 14:38:06 -070010129 __func__, eLen + 2);
Madan Mohan Koyyalamudief3b66e2012-10-11 14:29:42 -070010130
Madan Mohan Koyyalamudi1bed5982012-10-22 14:38:06 -070010131 if( SIR_MAC_MAX_IE_LENGTH < (pWextState->assocAddIE.length + eLen) )
10132 {
Jeff Johnson902c9832012-12-10 14:28:09 -080010133 hddLog(VOS_TRACE_LEVEL_FATAL, "Cannot accommodate assocAddIE "
10134 "Need bigger buffer space");
Madan Mohan Koyyalamudi1bed5982012-10-22 14:38:06 -070010135 VOS_ASSERT(0);
10136 return -ENOMEM;
10137 }
10138 memcpy( pWextState->assocAddIE.addIEdata + curAddIELen, genie - 2, eLen + 2);
10139 pWextState->assocAddIE.length += eLen + 2;
Madan Mohan Koyyalamudief3b66e2012-10-11 14:29:42 -070010140
Madan Mohan Koyyalamudi1bed5982012-10-22 14:38:06 -070010141 pWextState->roamProfile.pAddIEAssoc = pWextState->assocAddIE.addIEdata;
10142 pWextState->roamProfile.nAddIEAssocLength = pWextState->assocAddIE.length;
10143 }
Leela Venkata Kiran Kumar Reddy Chiralaf257bef2014-04-11 18:48:12 -070010144 /* Appending OSEN Information Element in Assiciation Request */
10145 else if ( (0 == memcmp(&genie[0], OSEN_OUI_TYPE,
10146 OSEN_OUI_TYPE_SIZE)) )
10147 {
10148 v_U16_t curAddIELen = pWextState->assocAddIE.length;
10149 hddLog (VOS_TRACE_LEVEL_INFO, "%s Set OSEN IE(len %d)",
10150 __func__, eLen + 2);
Madan Mohan Koyyalamudief3b66e2012-10-11 14:29:42 -070010151
Leela Venkata Kiran Kumar Reddy Chiralaf257bef2014-04-11 18:48:12 -070010152 if( SIR_MAC_MAX_IE_LENGTH < (pWextState->assocAddIE.length + eLen) )
10153 {
10154 hddLog(VOS_TRACE_LEVEL_FATAL, "Cannot accommodate assocAddIE "
10155 "Need bigger buffer space");
10156 VOS_ASSERT(0);
10157 return -ENOMEM;
10158 }
10159 memcpy( pWextState->assocAddIE.addIEdata + curAddIELen, genie - 2, eLen + 2);
10160 pWextState->assocAddIE.length += eLen + 2;
10161
10162 pWextState->roamProfile.bOSENAssociation = VOS_TRUE;
10163 pWextState->roamProfile.pAddIEAssoc = pWextState->assocAddIE.addIEdata;
10164 pWextState->roamProfile.nAddIEAssocLength = pWextState->assocAddIE.length;
10165 }
10166
10167 break;
Praveen Kumar Sirisilla7d68b7b2013-09-22 14:01:42 -070010168 if (WLAN_HDD_IBSS == pAdapter->device_mode) {
10169
10170 /* populating as ADDIE in beacon frames */
10171 if (ccmCfgSetStr(WLAN_HDD_GET_HAL_CTX(pAdapter),
10172 WNI_CFG_PROBE_RSP_BCN_ADDNIE_DATA, genie - 2, eLen + 2,
10173 NULL, eANI_BOOLEAN_FALSE)== eHAL_STATUS_SUCCESS)
10174 {
10175 if (ccmCfgSetInt(WLAN_HDD_GET_HAL_CTX(pAdapter),
10176 WNI_CFG_PROBE_RSP_BCN_ADDNIE_FLAG, 1,NULL,
10177 eANI_BOOLEAN_FALSE) == eHAL_STATUS_FAILURE)
10178 {
10179 hddLog(LOGE,
10180 "Coldn't pass "
10181 "WNI_CFG_PROBE_RSP_BCN_ADDNIE_FLAG to CCM");
10182 }
10183 }/* ccmCfgSetStr(,WNI_CFG_PROBE_RSP_BCN_ADDNIE_DATA, , )*/
10184 else
10185 hddLog(LOGE,
10186 "Could not pass on "
10187 "WNI_CFG_PROBE_RSP_BCN_ADDNIE_DATA to CCM");
10188
10189 /* IBSS mode doesn't contain params->proberesp_ies still
10190 beaconIE's need to be populated in probe response frames */
10191 if ( (NULL != (genie - 2)) && (0 != eLen + 2) )
10192 {
10193 u16 rem_probe_resp_ie_len = eLen + 2;
10194 u8 probe_rsp_ie_len[3] = {0};
10195 u8 counter = 0;
10196
10197 /* Check Probe Resp Length if it is greater then 255 then
10198 Store Probe Rsp IEs into WNI_CFG_PROBE_RSP_ADDNIE_DATA1
10199 & WNI_CFG_PROBE_RSP_ADDNIE_DATA2 CFG Variable As We are
10200 not able Store More then 255 bytes into One Variable */
10201
10202 while ((rem_probe_resp_ie_len > 0) && (counter < 3))
10203 {
10204 if (rem_probe_resp_ie_len > MAX_CFG_STRING_LEN)
10205 {
10206 probe_rsp_ie_len[counter++] = MAX_CFG_STRING_LEN;
10207 rem_probe_resp_ie_len -= MAX_CFG_STRING_LEN;
10208 }
10209 else
10210 {
10211 probe_rsp_ie_len[counter++] = rem_probe_resp_ie_len;
10212 rem_probe_resp_ie_len = 0;
10213 }
10214 }
10215
10216 rem_probe_resp_ie_len = 0;
10217
10218 if (probe_rsp_ie_len[0] > 0)
10219 {
10220 if (ccmCfgSetStr(WLAN_HDD_GET_HAL_CTX(pAdapter),
10221 WNI_CFG_PROBE_RSP_ADDNIE_DATA1,
10222 (tANI_U8*)(genie - 2),
10223 probe_rsp_ie_len[0], NULL,
10224 eANI_BOOLEAN_FALSE)
10225 == eHAL_STATUS_FAILURE)
10226 {
10227 hddLog(LOGE,
10228 "Could not pass"
10229 "on WNI_CFG_PROBE_RSP_ADDNIE_DATA1 to CCM");
10230 }
10231 rem_probe_resp_ie_len += probe_rsp_ie_len[0];
10232 }
10233
10234 if (probe_rsp_ie_len[1] > 0)
10235 {
10236 if (ccmCfgSetStr(WLAN_HDD_GET_HAL_CTX(pAdapter),
10237 WNI_CFG_PROBE_RSP_ADDNIE_DATA2,
10238 (tANI_U8*)(genie - (2 + rem_probe_resp_ie_len)),
10239 probe_rsp_ie_len[1], NULL,
10240 eANI_BOOLEAN_FALSE)
10241 == eHAL_STATUS_FAILURE)
10242 {
10243 hddLog(LOGE,
10244 "Could not pass"
10245 "on WNI_CFG_PROBE_RSP_ADDNIE_DATA2 to CCM");
10246 }
10247 rem_probe_resp_ie_len += probe_rsp_ie_len[1];
10248 }
10249
10250 if (probe_rsp_ie_len[2] > 0)
10251 {
10252 if (ccmCfgSetStr(WLAN_HDD_GET_HAL_CTX(pAdapter),
10253 WNI_CFG_PROBE_RSP_ADDNIE_DATA3,
10254 (tANI_U8*)(genie - (2 + rem_probe_resp_ie_len)),
10255 probe_rsp_ie_len[2], NULL,
10256 eANI_BOOLEAN_FALSE)
10257 == eHAL_STATUS_FAILURE)
10258 {
10259 hddLog(LOGE,
10260 "Could not pass"
10261 "on WNI_CFG_PROBE_RSP_ADDNIE_DATA3 to CCM");
10262 }
10263 rem_probe_resp_ie_len += probe_rsp_ie_len[2];
10264 }
10265
10266 if (ccmCfgSetInt(WLAN_HDD_GET_HAL_CTX(pAdapter),
10267 WNI_CFG_PROBE_RSP_ADDNIE_FLAG, 1,NULL,
10268 eANI_BOOLEAN_FALSE) == eHAL_STATUS_FAILURE)
10269 {
10270 hddLog(LOGE,
10271 "Could not pass"
10272 "on WNI_CFG_PROBE_RSP_ADDNIE_FLAG to CCM");
10273 }
10274 }
10275 else
10276 {
10277 // Reset WNI_CFG_PROBE_RSP Flags
10278 wlan_hdd_reset_prob_rspies(pAdapter);
10279
10280 hddLog(VOS_TRACE_LEVEL_INFO,
10281 "%s: No Probe Response IE received in set beacon",
10282 __func__);
10283 }
10284 } /* end of if (WLAN_HDD_IBSS == pAdapter->device_mode) */
Jeff Johnson295189b2012-06-20 16:38:30 -070010285 break;
10286 case DOT11F_EID_RSN:
10287 hddLog (VOS_TRACE_LEVEL_INFO, "%s Set RSN IE(len %d)",__func__, eLen + 2);
10288 memset( pWextState->WPARSNIE, 0, MAX_WPA_RSN_IE_LEN );
10289 memcpy( pWextState->WPARSNIE, genie - 2, (eLen + 2)/*ie_len*/);
10290 pWextState->roamProfile.pRSNReqIE = pWextState->WPARSNIE;
10291 pWextState->roamProfile.nRSNReqIELength = eLen + 2; //ie_len;
10292 break;
Madan Mohan Koyyalamudief3b66e2012-10-11 14:29:42 -070010293 /* Appending Extended Capabilities with Interworking bit set in Assoc Req */
10294 case DOT11F_EID_EXTCAP:
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010295 {
Madan Mohan Koyyalamudief3b66e2012-10-11 14:29:42 -070010296 v_U16_t curAddIELen = pWextState->assocAddIE.length;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010297 hddLog (VOS_TRACE_LEVEL_INFO, "%s Set Extended CAPS IE(len %d)",
Madan Mohan Koyyalamudief3b66e2012-10-11 14:29:42 -070010298 __func__, eLen + 2);
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010299
Madan Mohan Koyyalamudief3b66e2012-10-11 14:29:42 -070010300 if( SIR_MAC_MAX_IE_LENGTH < (pWextState->assocAddIE.length + eLen) )
10301 {
Jeff Johnson902c9832012-12-10 14:28:09 -080010302 hddLog(VOS_TRACE_LEVEL_FATAL, "Cannot accommodate assocAddIE "
10303 "Need bigger buffer space");
Madan Mohan Koyyalamudief3b66e2012-10-11 14:29:42 -070010304 VOS_ASSERT(0);
10305 return -ENOMEM;
10306 }
10307 memcpy( pWextState->assocAddIE.addIEdata + curAddIELen, genie - 2, eLen + 2);
10308 pWextState->assocAddIE.length += eLen + 2;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010309
Madan Mohan Koyyalamudief3b66e2012-10-11 14:29:42 -070010310 pWextState->roamProfile.pAddIEAssoc = pWextState->assocAddIE.addIEdata;
10311 pWextState->roamProfile.nAddIEAssocLength = pWextState->assocAddIE.length;
10312 break;
10313 }
Jeff Johnson295189b2012-06-20 16:38:30 -070010314#ifdef FEATURE_WLAN_WAPI
10315 case WLAN_EID_WAPI:
10316 pAdapter->wapi_info.nWapiMode = 1; //Setting WAPI Mode to ON=1
Jeff Johnson0299d0a2013-10-30 12:37:43 -070010317 hddLog(VOS_TRACE_LEVEL_INFO, "WAPI MODE IS %u",
Jeff Johnson295189b2012-06-20 16:38:30 -070010318 pAdapter->wapi_info.nWapiMode);
10319 tmp = (u16 *)ie;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010320 tmp = tmp + 2; // Skip element Id and Len, Version
Jeff Johnson295189b2012-06-20 16:38:30 -070010321 akmsuiteCount = WPA_GET_LE16(tmp);
10322 tmp = tmp + 1;
10323 akmlist = (int *)(tmp);
10324 if(akmsuiteCount <= MAX_NUM_AKM_SUITES)
10325 {
10326 memcpy(akmsuite, akmlist, (4*akmsuiteCount));
10327 }
10328 else
10329 {
Arif Hussain6d2a3322013-11-17 19:50:10 -080010330 hddLog(VOS_TRACE_LEVEL_FATAL, "Invalid akmSuite count");
Jeff Johnson295189b2012-06-20 16:38:30 -070010331 VOS_ASSERT(0);
10332 return -EINVAL;
10333 }
10334
10335 if (WAPI_PSK_AKM_SUITE == akmsuite[0])
10336 {
10337 hddLog(VOS_TRACE_LEVEL_INFO, "%s: WAPI AUTH MODE SET TO PSK",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -070010338 __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -070010339 pAdapter->wapi_info.wapiAuthMode = WAPI_AUTH_MODE_PSK;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010340 }
Jeff Johnson295189b2012-06-20 16:38:30 -070010341 if (WAPI_CERT_AKM_SUITE == akmsuite[0])
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010342 {
Jeff Johnson295189b2012-06-20 16:38:30 -070010343 hddLog(VOS_TRACE_LEVEL_INFO, "%s: WAPI AUTH MODE SET TO CERTIFICATE",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -070010344 __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -070010345 pAdapter->wapi_info.wapiAuthMode = WAPI_AUTH_MODE_CERT;
10346 }
10347 break;
10348#endif
10349 default:
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010350 hddLog (VOS_TRACE_LEVEL_ERROR,
Jeff Johnson295189b2012-06-20 16:38:30 -070010351 "%s Set UNKNOWN IE %X", __func__, elementId);
Madan Mohan Koyyalamudief3b66e2012-10-11 14:29:42 -070010352 /* when Unknown IE is received we should break and continue
10353 * to the next IE in the buffer instead we were returning
10354 * so changing this to break */
10355 break;
Jeff Johnson295189b2012-06-20 16:38:30 -070010356 }
10357 genie += eLen;
10358 remLen -= eLen;
10359 }
10360 EXIT();
10361 return 0;
10362}
10363
10364/*
Gopichand Nakkala18f0c262013-05-07 23:25:08 +053010365 * FUNCTION: hdd_isWPAIEPresent
10366 * Parse the received IE to find the WPA IE
10367 *
10368 */
10369static bool hdd_isWPAIEPresent(u8 *ie, u8 ie_len)
10370{
10371 v_U8_t eLen = 0;
10372 v_U16_t remLen = ie_len;
10373 v_U8_t elementId = 0;
10374
10375 while (remLen >= 2)
10376 {
10377 elementId = *ie++;
10378 eLen = *ie++;
10379 remLen -= 2;
10380 if (eLen > remLen)
10381 {
10382 hddLog(VOS_TRACE_LEVEL_ERROR,
10383 "%s: IE length is wrong %d", __func__, eLen);
10384 return FALSE;
10385 }
10386 if ((elementId == DOT11F_EID_WPA) && (remLen > 5))
10387 {
10388 /* OUI - 0x00 0X50 0XF2
10389 WPA Information Element - 0x01
10390 WPA version - 0x01*/
10391 if (0 == memcmp(&ie[0], "\x00\x50\xf2\x01\x01", 5))
10392 return TRUE;
10393 }
10394 ie += eLen;
10395 remLen -= eLen;
10396 }
10397 return FALSE;
10398}
10399
10400/*
Jeff Johnson295189b2012-06-20 16:38:30 -070010401 * FUNCTION: wlan_hdd_cfg80211_set_privacy
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010402 * This function is used to initialize the security
Jeff Johnson295189b2012-06-20 16:38:30 -070010403 * parameters during connect operation.
10404 */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010405int wlan_hdd_cfg80211_set_privacy( hdd_adapter_t *pAdapter,
Jeff Johnson295189b2012-06-20 16:38:30 -070010406 struct cfg80211_connect_params *req
10407 )
10408{
10409 int status = 0;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010410 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
Jeff Johnson295189b2012-06-20 16:38:30 -070010411 ENTER();
10412
10413 /*set wpa version*/
10414 pWextState->wpaVersion = IW_AUTH_WPA_VERSION_DISABLED;
10415
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010416 if (req->crypto.wpa_versions)
Jeff Johnson295189b2012-06-20 16:38:30 -070010417 {
Gopichand Nakkala781ded42013-06-28 12:10:45 +053010418 if (NL80211_WPA_VERSION_1 == req->crypto.wpa_versions)
Jeff Johnson295189b2012-06-20 16:38:30 -070010419 {
10420 pWextState->wpaVersion = IW_AUTH_WPA_VERSION_WPA;
10421 }
10422 else if (NL80211_WPA_VERSION_2 == req->crypto.wpa_versions)
10423 {
10424 pWextState->wpaVersion = IW_AUTH_WPA_VERSION_WPA2;
10425 }
10426 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010427
10428 hddLog(VOS_TRACE_LEVEL_INFO, "%s: set wpa version to %d", __func__,
Jeff Johnson295189b2012-06-20 16:38:30 -070010429 pWextState->wpaVersion);
10430
10431 /*set authentication type*/
10432 status = wlan_hdd_cfg80211_set_auth_type(pAdapter, req->auth_type);
10433
10434 if (0 > status)
10435 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010436 hddLog(VOS_TRACE_LEVEL_ERROR,
Jeff Johnson295189b2012-06-20 16:38:30 -070010437 "%s: failed to set authentication type ", __func__);
10438 return status;
10439 }
10440
10441 /*set key mgmt type*/
10442 if (req->crypto.n_akm_suites)
10443 {
10444 status = wlan_hdd_set_akm_suite(pAdapter, req->crypto.akm_suites[0]);
10445 if (0 > status)
10446 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010447 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: failed to set akm suite",
Jeff Johnson295189b2012-06-20 16:38:30 -070010448 __func__);
10449 return status;
10450 }
10451 }
10452
10453 /*set pairwise cipher type*/
10454 if (req->crypto.n_ciphers_pairwise)
10455 {
10456 status = wlan_hdd_cfg80211_set_cipher(pAdapter,
10457 req->crypto.ciphers_pairwise[0], true);
10458 if (0 > status)
10459 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010460 hddLog(VOS_TRACE_LEVEL_ERROR,
Jeff Johnson295189b2012-06-20 16:38:30 -070010461 "%s: failed to set unicast cipher type", __func__);
10462 return status;
10463 }
10464 }
10465 else
10466 {
10467 /*Reset previous cipher suite to none*/
10468 status = wlan_hdd_cfg80211_set_cipher(pAdapter, 0, true);
10469 if (0 > status)
10470 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010471 hddLog(VOS_TRACE_LEVEL_ERROR,
Jeff Johnson295189b2012-06-20 16:38:30 -070010472 "%s: failed to set unicast cipher type", __func__);
10473 return status;
10474 }
10475 }
10476
10477 /*set group cipher type*/
10478 status = wlan_hdd_cfg80211_set_cipher(pAdapter, req->crypto.cipher_group,
10479 false);
10480
10481 if (0 > status)
10482 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010483 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: failed to set mcast cipher type",
Jeff Johnson295189b2012-06-20 16:38:30 -070010484 __func__);
10485 return status;
10486 }
10487
Chet Lanctot186b5732013-03-18 10:26:30 -070010488#ifdef WLAN_FEATURE_11W
10489 pWextState->roamProfile.MFPEnabled = (req->mfp == NL80211_MFP_REQUIRED);
10490#endif
10491
Jeff Johnson295189b2012-06-20 16:38:30 -070010492 /*parse WPA/RSN IE, and set the correspoing fileds in Roam profile*/
10493 if (req->ie_len)
10494 {
10495 status = wlan_hdd_cfg80211_set_ie(pAdapter, req->ie, req->ie_len);
10496 if ( 0 > status)
10497 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010498 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: failed to parse the WPA/RSN IE",
Jeff Johnson295189b2012-06-20 16:38:30 -070010499 __func__);
10500 return status;
10501 }
10502 }
10503
10504 /*incase of WEP set default key information*/
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010505 if (req->key && req->key_len)
Jeff Johnson295189b2012-06-20 16:38:30 -070010506 {
10507 if ( (WLAN_CIPHER_SUITE_WEP40 == req->crypto.ciphers_pairwise[0])
10508 || (WLAN_CIPHER_SUITE_WEP104 == req->crypto.ciphers_pairwise[0])
10509 )
10510 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010511 if ( IW_AUTH_KEY_MGMT_802_1X
Jeff Johnson295189b2012-06-20 16:38:30 -070010512 == (pWextState->authKeyMgmt & IW_AUTH_KEY_MGMT_802_1X ))
10513 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010514 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Dynamic WEP not supported",
Jeff Johnson295189b2012-06-20 16:38:30 -070010515 __func__);
10516 return -EOPNOTSUPP;
10517 }
10518 else
10519 {
10520 u8 key_len = req->key_len;
10521 u8 key_idx = req->key_idx;
10522
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010523 if ((eCSR_SECURITY_WEP_KEYSIZE_MAX_BYTES >= key_len)
Jeff Johnson295189b2012-06-20 16:38:30 -070010524 && (CSR_MAX_NUM_KEY > key_idx)
10525 )
10526 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010527 hddLog(VOS_TRACE_LEVEL_INFO,
10528 "%s: setting default wep key, key_idx = %hu key_len %hu",
Jeff Johnson295189b2012-06-20 16:38:30 -070010529 __func__, key_idx, key_len);
10530 vos_mem_copy(
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010531 &pWextState->roamProfile.Keys.KeyMaterial[key_idx][0],
Jeff Johnson295189b2012-06-20 16:38:30 -070010532 req->key, key_len);
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010533 pWextState->roamProfile.Keys.KeyLength[key_idx] =
Jeff Johnson295189b2012-06-20 16:38:30 -070010534 (u8)key_len;
10535 pWextState->roamProfile.Keys.defaultIndex = (u8)key_idx;
10536 }
10537 }
10538 }
10539 }
10540
10541 return status;
10542}
10543
10544/*
Vinay Krishna Eranna21042322014-01-08 19:21:39 +053010545 * FUNCTION: wlan_hdd_try_disconnect
10546 * This function is used to disconnect from previous
10547 * connection
10548 */
10549static int wlan_hdd_try_disconnect( hdd_adapter_t *pAdapter )
10550{
10551 long ret = 0;
10552 hdd_station_ctx_t *pHddStaCtx;
10553 eMib_dot11DesiredBssType connectedBssType;
10554
10555 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
10556
10557 hdd_connGetConnectedBssType(pHddStaCtx,&connectedBssType );
10558
10559 if((eMib_dot11DesiredBssType_independent == connectedBssType) ||
10560 (eConnectionState_Associated == pHddStaCtx->conn_info.connState) ||
10561 (eConnectionState_IbssConnected == pHddStaCtx->conn_info.connState))
10562 {
10563 /* Issue disconnect to CSR */
10564 INIT_COMPLETION(pAdapter->disconnect_comp_var);
10565 if( eHAL_STATUS_SUCCESS ==
10566 sme_RoamDisconnect( WLAN_HDD_GET_HAL_CTX(pAdapter),
10567 pAdapter->sessionId,
10568 eCSR_DISCONNECT_REASON_UNSPECIFIED ) )
10569 {
10570 ret = wait_for_completion_interruptible_timeout(
10571 &pAdapter->disconnect_comp_var,
10572 msecs_to_jiffies(WLAN_WAIT_TIME_DISCONNECT));
10573 if (0 >= ret)
10574 {
10575 hddLog(LOGE, FL("Failed to receive disconnect event"));
10576 return -EALREADY;
10577 }
10578 }
10579 }
10580 else if(eConnectionState_Disconnecting == pHddStaCtx->conn_info.connState)
10581 {
10582 ret = wait_for_completion_interruptible_timeout(
10583 &pAdapter->disconnect_comp_var,
10584 msecs_to_jiffies(WLAN_WAIT_TIME_DISCONNECT));
10585 if (0 >= ret)
10586 {
10587 hddLog(LOGE, FL("Failed to receive disconnect event"));
10588 return -EALREADY;
10589 }
10590 }
10591
10592 return 0;
10593}
10594
10595/*
Agarwal Ashish51325b52014-06-16 16:50:49 +053010596 * FUNCTION: __wlan_hdd_cfg80211_connect
10597 * This function is used to start the association process
Jeff Johnson295189b2012-06-20 16:38:30 -070010598 */
Mahesh A Saptasagarfafb7fe2014-05-16 13:19:37 +053010599static int __wlan_hdd_cfg80211_connect( struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -070010600 struct net_device *ndev,
10601 struct cfg80211_connect_params *req
10602 )
10603{
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053010604 int status;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010605 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( ndev );
Jeff Johnson295189b2012-06-20 16:38:30 -070010606 VOS_STATUS exitbmpsStatus = VOS_STATUS_E_INVAL;
Sushant Kaushikba6764e2014-06-30 19:52:09 +053010607 hdd_context_t *pHddCtx = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -070010608
10609 ENTER();
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053010610
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053010611 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
10612 TRACE_CODE_HDD_CFG80211_CONNECT,
10613 pAdapter->sessionId, pAdapter->device_mode));
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010614 hddLog(VOS_TRACE_LEVEL_INFO,
Sushant Kaushik8bc7df22014-04-09 17:55:29 +053010615 "%s: device_mode = %s (%d)", __func__,
10616 hdd_device_modetoString(pAdapter->device_mode),
10617 pAdapter->device_mode);
Jeff Johnson295189b2012-06-20 16:38:30 -070010618
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053010619 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Rajesh Chauhana0516c62014-01-30 16:11:18 -080010620 if (!pHddCtx)
10621 {
10622 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
10623 "%s: HDD context is null", __func__);
Agarwal Ashish51325b52014-06-16 16:50:49 +053010624 return -EINVAL;
Rajesh Chauhana0516c62014-01-30 16:11:18 -080010625 }
10626
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053010627 status = wlan_hdd_validate_context(pHddCtx);
10628
10629 if (0 != status)
Jeff Johnson295189b2012-06-20 16:38:30 -070010630 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053010631 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
10632 "%s: HDD context is not valid", __func__);
10633 return status;
Jeff Johnson295189b2012-06-20 16:38:30 -070010634 }
10635
Agarwal Ashish51325b52014-06-16 16:50:49 +053010636 if (vos_max_concurrent_connections_reached()) {
10637 hddLog(VOS_TRACE_LEVEL_INFO, FL("Reached max concurrent connections"));
10638 return -ECONNREFUSED;
10639 }
10640
Jeff Johnson295189b2012-06-20 16:38:30 -070010641#ifdef WLAN_BTAMP_FEATURE
10642 //Infra connect not supported when AMP traffic is on.
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010643 if( VOS_TRUE == WLANBAP_AmpSessionOn() )
Jeff Johnson295189b2012-06-20 16:38:30 -070010644 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010645 hddLog(VOS_TRACE_LEVEL_ERROR,
Jeff Johnson295189b2012-06-20 16:38:30 -070010646 "%s: No connection when AMP is on", __func__);
Madan Mohan Koyyalamudicae253a2012-11-06 19:10:35 -080010647 return -ECONNREFUSED;
Jeff Johnson295189b2012-06-20 16:38:30 -070010648 }
10649#endif
Vinay Krishna Eranna21042322014-01-08 19:21:39 +053010650
10651 //If Device Mode is Station Concurrent Sessions Exit BMps
10652 //P2P Mode will be taken care in Open/close adapter
10653 if((WLAN_HDD_INFRA_STATION == pAdapter->device_mode) &&
Agarwal Ashish51325b52014-06-16 16:50:49 +053010654 (vos_concurrent_open_sessions_running())) {
10655 exitbmpsStatus = hdd_disable_bmps_imps(pHddCtx,
10656 WLAN_HDD_INFRA_STATION);
Vinay Krishna Eranna21042322014-01-08 19:21:39 +053010657 }
10658
10659 /*Try disconnecting if already in connected state*/
10660 status = wlan_hdd_try_disconnect(pAdapter);
10661 if ( 0 > status)
10662 {
10663 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Failed to disconnect the existing"
10664 " connection"));
10665 return -EALREADY;
10666 }
10667
Jeff Johnson295189b2012-06-20 16:38:30 -070010668 /*initialise security parameters*/
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010669 status = wlan_hdd_cfg80211_set_privacy(pAdapter, req);
Jeff Johnson295189b2012-06-20 16:38:30 -070010670
10671 if ( 0 > status)
10672 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010673 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: failed to set security params",
Jeff Johnson295189b2012-06-20 16:38:30 -070010674 __func__);
10675 return status;
10676 }
Mohit Khanna765234a2012-09-11 15:08:35 -070010677 if ( req->channel )
10678 {
10679 status = wlan_hdd_cfg80211_connect_start(pAdapter, req->ssid,
10680 req->ssid_len, req->bssid,
10681 req->channel->hw_value);
10682 }
10683 else
10684 {
10685 status = wlan_hdd_cfg80211_connect_start(pAdapter, req->ssid,
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053010686 req->ssid_len, req->bssid, 0);
Mohit Khanna765234a2012-09-11 15:08:35 -070010687 }
Jeff Johnson295189b2012-06-20 16:38:30 -070010688
10689 if (0 > status)
10690 {
10691 //ReEnable BMPS if disabled
10692 if((VOS_STATUS_SUCCESS == exitbmpsStatus) &&
10693 (NULL != pHddCtx))
10694 {
Gopichand Nakkalaa2fe5b02013-06-06 16:32:28 +053010695 if (pHddCtx->hdd_wlan_suspended)
10696 {
10697 hdd_set_pwrparams(pHddCtx);
10698 }
Jeff Johnson295189b2012-06-20 16:38:30 -070010699 //ReEnable Bmps and Imps back
10700 hdd_enable_bmps_imps(pHddCtx);
10701 }
Agarwal Ashish51325b52014-06-16 16:50:49 +053010702 hddLog(VOS_TRACE_LEVEL_ERROR, FL("connect failed"));
Jeff Johnson295189b2012-06-20 16:38:30 -070010703 return status;
10704 }
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053010705 pHddCtx->isAmpAllowed = VOS_FALSE;
Jeff Johnson295189b2012-06-20 16:38:30 -070010706 EXIT();
10707 return status;
10708}
10709
Mahesh A Saptasagarfafb7fe2014-05-16 13:19:37 +053010710static int wlan_hdd_cfg80211_connect( struct wiphy *wiphy,
10711 struct net_device *ndev,
10712 struct cfg80211_connect_params *req)
10713{
10714 int ret;
10715 vos_ssr_protect(__func__);
10716 ret = __wlan_hdd_cfg80211_connect(wiphy, ndev, req);
10717 vos_ssr_unprotect(__func__);
10718
10719 return ret;
10720}
Jeff Johnson295189b2012-06-20 16:38:30 -070010721
10722/*
Gopichand Nakkala78a6c812013-05-13 16:39:49 +053010723 * FUNCTION: wlan_hdd_disconnect
10724 * This function is used to issue a disconnect request to SME
10725 */
10726int wlan_hdd_disconnect( hdd_adapter_t *pAdapter, u16 reason )
10727{
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053010728 int status;
Gopichand Nakkala78a6c812013-05-13 16:39:49 +053010729 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053010730 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Abhishek Singhdc2bfd42014-06-19 17:59:05 +053010731 long ret;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053010732
10733 status = wlan_hdd_validate_context(pHddCtx);
10734
10735 if (0 != status)
10736 {
10737 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
10738 "%s: HDD context is not valid", __func__);
10739 return status;
10740 }
10741
10742 pHddCtx->isAmpAllowed = VOS_TRUE;
Agarwal Ashishc65b5ca2014-07-28 21:02:57 +053010743
Agarwal Ashish47d18112014-08-04 19:55:07 +053010744 /* Need to apply spin lock before decreasing active sessions
10745 * as there can be chance for double decrement if context switch
10746 * Calls hdd_DisConnectHandler.
10747 */
10748
10749 spin_lock_bh(&pAdapter->lock_for_active_session);
Agarwal Ashishc65b5ca2014-07-28 21:02:57 +053010750 if (eConnectionState_Associated == pHddStaCtx->conn_info.connState)
10751 {
Agarwal Ashishc65b5ca2014-07-28 21:02:57 +053010752 wlan_hdd_decr_active_session(pHddCtx, pAdapter->device_mode);
10753 }
Agarwal Ashish47d18112014-08-04 19:55:07 +053010754 hdd_connSetConnectionState( pHddStaCtx, eConnectionState_Disconnecting );
10755 spin_unlock_bh(&pAdapter->lock_for_active_session);
Agarwal Ashishc65b5ca2014-07-28 21:02:57 +053010756
Abhishek Singhf4669da2014-05-26 15:07:49 +053010757 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Agarwal Ashish47d18112014-08-04 19:55:07 +053010758 FL( "Set HDD connState to eConnectionState_Disconnecting" ));
10759
Gopichand Nakkala78a6c812013-05-13 16:39:49 +053010760 INIT_COMPLETION(pAdapter->disconnect_comp_var);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053010761
Mihir Shete182a0b22014-08-18 16:08:48 +053010762 /*
10763 * stop tx queues before deleting STA/BSS context from the firmware.
10764 * tx has to be disabled because the firmware can get busy dropping
10765 * the tx frames after BSS/STA has been deleted and will not send
10766 * back a response resulting in WDI timeout
10767 */
10768 netif_tx_disable(pAdapter->dev);
10769 netif_carrier_off(pAdapter->dev);
Arun Kumar Khandavalli94a2bb02013-12-28 19:17:25 +053010770
Mihir Shete182a0b22014-08-18 16:08:48 +053010771 /*issue disconnect*/
Gopichand Nakkala78a6c812013-05-13 16:39:49 +053010772 status = sme_RoamDisconnect( WLAN_HDD_GET_HAL_CTX(pAdapter),
10773 pAdapter->sessionId, reason);
Abhishek Singhdc2bfd42014-06-19 17:59:05 +053010774 if(eHAL_STATUS_CMD_NOT_QUEUED == status)
10775 {
10776 hddLog(VOS_TRACE_LEVEL_INFO,
10777 FL("status = %d, already disconnected"),
10778 (int)status );
Gopichand Nakkala78a6c812013-05-13 16:39:49 +053010779
Abhishek Singhdc2bfd42014-06-19 17:59:05 +053010780 }
10781 else if ( 0 != status )
Gopichand Nakkala78a6c812013-05-13 16:39:49 +053010782 {
10783 hddLog(VOS_TRACE_LEVEL_ERROR,
Arif Hussain6d2a3322013-11-17 19:50:10 -080010784 "%s csrRoamDisconnect failure, returned %d",
Gopichand Nakkala78a6c812013-05-13 16:39:49 +053010785 __func__, (int)status );
10786 return -EINVAL;
10787 }
Abhishek Singhdc2bfd42014-06-19 17:59:05 +053010788 ret = wait_for_completion_interruptible_timeout(
Gopichand Nakkala78a6c812013-05-13 16:39:49 +053010789 &pAdapter->disconnect_comp_var,
10790 msecs_to_jiffies(WLAN_WAIT_TIME_DISCONNECT));
Abhishek Singhdc2bfd42014-06-19 17:59:05 +053010791 if (!ret && ( eHAL_STATUS_CMD_NOT_QUEUED != status ))
c_hpothu6ff1c3c2013-10-01 19:01:57 +053010792 {
10793 hddLog(VOS_TRACE_LEVEL_ERROR,
Mahesh A Saptasagar05a357e2014-02-26 16:28:06 +053010794 "%s: Failed to disconnect, timed out", __func__);
10795 return -ETIMEDOUT;
10796 }
Abhishek Singhdc2bfd42014-06-19 17:59:05 +053010797 else if (ret == -ERESTARTSYS)
Mahesh A Saptasagar05a357e2014-02-26 16:28:06 +053010798 {
10799 hddLog(VOS_TRACE_LEVEL_ERROR,
10800 "%s: Failed to disconnect, wait interrupted", __func__);
Abhishek Singhdc2bfd42014-06-19 17:59:05 +053010801 return ret;
c_hpothu6ff1c3c2013-10-01 19:01:57 +053010802 }
Abhishek Singhdc2bfd42014-06-19 17:59:05 +053010803 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
10804 FL("Set HDD connState to eConnectionState_NotConnected"));
10805 pHddStaCtx->conn_info.connState = eConnectionState_NotConnected;
10806
Mahesh A Saptasagar05a357e2014-02-26 16:28:06 +053010807 return 0;
Gopichand Nakkala78a6c812013-05-13 16:39:49 +053010808}
10809
10810
10811/*
Mahesh A Saptasagarfafb7fe2014-05-16 13:19:37 +053010812 * FUNCTION: __wlan_hdd_cfg80211_disconnect
Jeff Johnson295189b2012-06-20 16:38:30 -070010813 * This function is used to issue a disconnect request to SME
10814 */
Mahesh A Saptasagarfafb7fe2014-05-16 13:19:37 +053010815static int __wlan_hdd_cfg80211_disconnect( struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -070010816 struct net_device *dev,
10817 u16 reason
10818 )
10819{
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010820 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( dev );
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053010821 tCsrRoamProfile *pRoamProfile =
10822 &(WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter))->roamProfile;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053010823 int status;
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053010824 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
10825 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Gopichand Nakkalaaa353782013-05-17 20:36:22 +053010826#ifdef FEATURE_WLAN_TDLS
Gopichand Nakkala2a0a1572013-02-10 21:39:16 -080010827 tANI_U8 staIdx;
10828#endif
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010829
Jeff Johnson295189b2012-06-20 16:38:30 -070010830 ENTER();
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053010831
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053010832 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
10833 TRACE_CODE_HDD_CFG80211_DISCONNECT,
10834 pAdapter->sessionId, reason));
Sushant Kaushik8bc7df22014-04-09 17:55:29 +053010835 hddLog(VOS_TRACE_LEVEL_INFO, "%s: device_mode = %s(%d)",
10836 __func__, hdd_device_modetoString(pAdapter->device_mode),
10837 pAdapter->device_mode);
Jeff Johnson295189b2012-06-20 16:38:30 -070010838
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010839 hddLog(VOS_TRACE_LEVEL_INFO, "%s: Disconnect called with reason code %d",
10840 __func__, reason);
Jeff Johnson295189b2012-06-20 16:38:30 -070010841
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053010842 status = wlan_hdd_validate_context(pHddCtx);
10843
10844 if (0 != status)
Jeff Johnson295189b2012-06-20 16:38:30 -070010845 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053010846 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
10847 "%s: HDD context is not valid", __func__);
10848 return status;
Jeff Johnson295189b2012-06-20 16:38:30 -070010849 }
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053010850
Jeff Johnson295189b2012-06-20 16:38:30 -070010851 if (NULL != pRoamProfile)
10852 {
10853 /*issue disconnect request to SME, if station is in connected state*/
Mahesh A Saptasagar280fd5a2013-12-05 15:38:31 +053010854 if ((pHddStaCtx->conn_info.connState == eConnectionState_Associated) ||
10855 (pHddStaCtx->conn_info.connState == eConnectionState_Connecting))
Jeff Johnson295189b2012-06-20 16:38:30 -070010856 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010857 eCsrRoamDisconnectReason reasonCode =
Jeff Johnson295189b2012-06-20 16:38:30 -070010858 eCSR_DISCONNECT_REASON_UNSPECIFIED;
Gopichand Nakkalaaa353782013-05-17 20:36:22 +053010859 hdd_scaninfo_t *pScanInfo;
Jeff Johnson295189b2012-06-20 16:38:30 -070010860 switch(reason)
10861 {
10862 case WLAN_REASON_MIC_FAILURE:
10863 reasonCode = eCSR_DISCONNECT_REASON_MIC_ERROR;
10864 break;
10865
10866 case WLAN_REASON_DISASSOC_DUE_TO_INACTIVITY:
10867 case WLAN_REASON_DISASSOC_AP_BUSY:
10868 case WLAN_REASON_CLASS3_FRAME_FROM_NONASSOC_STA:
10869 reasonCode = eCSR_DISCONNECT_REASON_DISASSOC;
10870 break;
10871
10872 case WLAN_REASON_PREV_AUTH_NOT_VALID:
10873 case WLAN_REASON_CLASS2_FRAME_FROM_NONAUTH_STA:
Abhishek Singhc3269a52014-05-21 17:22:24 +053010874 case WLAN_REASON_DEAUTH_LEAVING:
Jeff Johnson295189b2012-06-20 16:38:30 -070010875 reasonCode = eCSR_DISCONNECT_REASON_DEAUTH;
10876 break;
10877
Jeff Johnson295189b2012-06-20 16:38:30 -070010878 default:
10879 reasonCode = eCSR_DISCONNECT_REASON_UNSPECIFIED;
10880 break;
10881 }
Gopichand Nakkalaaa353782013-05-17 20:36:22 +053010882 pScanInfo = &pHddCtx->scan_info;
10883 if (pScanInfo->mScanPending)
10884 {
Srinivas, Dasari138af4f2014-02-07 11:13:45 +053010885 hddLog(VOS_TRACE_LEVEL_INFO, "Disconnect is in progress, "
Gopichand Nakkalaaa353782013-05-17 20:36:22 +053010886 "Aborting Scan");
Srinivas, Dasari138af4f2014-02-07 11:13:45 +053010887 hdd_abort_mac_scan(pHddCtx, pAdapter->sessionId,
10888 eCSR_SCAN_ABORT_DEFAULT);
Gopichand Nakkalaaa353782013-05-17 20:36:22 +053010889 }
Jeff Johnson295189b2012-06-20 16:38:30 -070010890
Gopichand Nakkala2a0a1572013-02-10 21:39:16 -080010891#ifdef FEATURE_WLAN_TDLS
10892 /* First clean up the tdls peers if any */
Gopichand Nakkala4327a152013-03-04 23:22:42 -080010893 for (staIdx = 0 ; staIdx < HDD_MAX_NUM_TDLS_STA; staIdx++)
Gopichand Nakkala2a0a1572013-02-10 21:39:16 -080010894 {
Gopichand Nakkala4327a152013-03-04 23:22:42 -080010895 if ((pHddCtx->tdlsConnInfo[staIdx].sessionId == pAdapter->sessionId) &&
10896 (pHddCtx->tdlsConnInfo[staIdx].staId))
Gopichand Nakkala2a0a1572013-02-10 21:39:16 -080010897 {
Hoonki Lee11f7dda2013-02-14 16:55:44 -080010898 uint8 *mac;
Gopichand Nakkala4327a152013-03-04 23:22:42 -080010899 mac = pHddCtx->tdlsConnInfo[staIdx].peerMac.bytes;
Hoonki Lee11f7dda2013-02-14 16:55:44 -080010900 VOS_TRACE(VOS_MODULE_ID_HDD, TDLS_LOG_LEVEL,
Gopichand Nakkalac87400e2013-03-13 18:51:00 -070010901 "%s: call sme_DeleteTdlsPeerSta staId %d sessionId %d " MAC_ADDRESS_STR,
Gopichand Nakkala4327a152013-03-04 23:22:42 -080010902 __func__, pHddCtx->tdlsConnInfo[staIdx].staId, pAdapter->sessionId,
Gopichand Nakkalac87400e2013-03-13 18:51:00 -070010903 MAC_ADDR_ARRAY(mac));
Gopichand Nakkala2a0a1572013-02-10 21:39:16 -080010904 sme_DeleteTdlsPeerSta(WLAN_HDD_GET_HAL_CTX(pAdapter),
Gopichand Nakkala4327a152013-03-04 23:22:42 -080010905 pAdapter->sessionId,
10906 mac);
Gopichand Nakkala2a0a1572013-02-10 21:39:16 -080010907 }
10908 }
10909#endif
Arun Kumar Khandavalli94a2bb02013-12-28 19:17:25 +053010910 hddLog(LOG1, FL("Disconnecting with reasoncode:%u"), reasonCode);
Gopichand Nakkala78a6c812013-05-13 16:39:49 +053010911 status = wlan_hdd_disconnect(pAdapter, reasonCode);
10912 if ( 0 != status )
Jeff Johnson295189b2012-06-20 16:38:30 -070010913 {
10914 hddLog(VOS_TRACE_LEVEL_ERROR,
Arif Hussain6d2a3322013-11-17 19:50:10 -080010915 "%s wlan_hdd_disconnect failure, returned %d",
Jeff Johnson295189b2012-06-20 16:38:30 -070010916 __func__, (int)status );
10917 return -EINVAL;
10918 }
Jeff Johnson295189b2012-06-20 16:38:30 -070010919 }
Mahesh A Saptasagar280fd5a2013-12-05 15:38:31 +053010920 else
10921 {
10922 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: unexpected cfg disconnect API"
10923 "called while in %d state", __func__,
10924 pHddStaCtx->conn_info.connState);
10925 }
Jeff Johnson295189b2012-06-20 16:38:30 -070010926 }
10927 else
10928 {
10929 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: No valid roam profile", __func__);
10930 }
10931
10932 return status;
10933}
10934
Mahesh A Saptasagarfafb7fe2014-05-16 13:19:37 +053010935static int wlan_hdd_cfg80211_disconnect( struct wiphy *wiphy,
10936 struct net_device *dev,
10937 u16 reason
10938 )
10939{
10940 int ret;
10941 vos_ssr_protect(__func__);
10942 ret = __wlan_hdd_cfg80211_disconnect(wiphy, dev, reason);
10943 vos_ssr_unprotect(__func__);
10944
10945 return ret;
10946}
Gopichand Nakkala78a6c812013-05-13 16:39:49 +053010947
Jeff Johnson295189b2012-06-20 16:38:30 -070010948/*
10949 * FUNCTION: wlan_hdd_cfg80211_set_privacy_ibss
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010950 * This function is used to initialize the security
Jeff Johnson295189b2012-06-20 16:38:30 -070010951 * settings in IBSS mode.
10952 */
10953static int wlan_hdd_cfg80211_set_privacy_ibss(
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010954 hdd_adapter_t *pAdapter,
Jeff Johnson295189b2012-06-20 16:38:30 -070010955 struct cfg80211_ibss_params *params
10956 )
10957{
10958 int status = 0;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010959 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
Jeff Johnson295189b2012-06-20 16:38:30 -070010960 eCsrEncryptionType encryptionType = eCSR_ENCRYPT_TYPE_NONE;
10961 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010962
Jeff Johnson295189b2012-06-20 16:38:30 -070010963 ENTER();
10964
10965 pWextState->wpaVersion = IW_AUTH_WPA_VERSION_DISABLED;
Ravi Joshib58ca0d2013-10-29 09:50:23 -070010966 vos_mem_zero(&pHddStaCtx->ibss_enc_key, sizeof(tCsrRoamSetKey));
Jeff Johnson295189b2012-06-20 16:38:30 -070010967
10968 if (params->ie_len && ( NULL != params->ie) )
10969 {
Shailender Karmuchi67edd312013-06-18 16:30:48 -070010970 if (wlan_hdd_cfg80211_get_ie_ptr (params->ie,
10971 params->ie_len, WLAN_EID_RSN ))
Jeff Johnson295189b2012-06-20 16:38:30 -070010972 {
10973 pWextState->wpaVersion = IW_AUTH_WPA_VERSION_WPA2;
10974 encryptionType = eCSR_ENCRYPT_TYPE_AES;
10975 }
Shailender Karmuchi67edd312013-06-18 16:30:48 -070010976 else if ( hdd_isWPAIEPresent (params->ie, params->ie_len ))
Jeff Johnson295189b2012-06-20 16:38:30 -070010977 {
Shailender Karmuchi642e9812013-05-30 14:34:49 -070010978 tDot11fIEWPA dot11WPAIE;
10979 tHalHandle halHandle = WLAN_HDD_GET_HAL_CTX(pAdapter);
Shailender Karmuchi67edd312013-06-18 16:30:48 -070010980 u8 *ie;
Shailender Karmuchi642e9812013-05-30 14:34:49 -070010981
Wilson Yang00256342013-10-10 23:13:38 -070010982 memset(&dot11WPAIE, 0, sizeof(dot11WPAIE));
Shailender Karmuchi67edd312013-06-18 16:30:48 -070010983 ie = wlan_hdd_cfg80211_get_ie_ptr (params->ie,
10984 params->ie_len, DOT11F_EID_WPA);
10985 if ( NULL != ie )
10986 {
10987 pWextState->wpaVersion = IW_AUTH_WPA_VERSION_WPA;
10988 // Unpack the WPA IE
10989 //Skip past the EID byte and length byte - and four byte WiFi OUI
10990 dot11fUnpackIeWPA((tpAniSirGlobal) halHandle,
10991 &ie[2+4],
10992 ie[1] - 4,
10993 &dot11WPAIE);
10994 /*Extract the multicast cipher, the encType for unicast
10995 cipher for wpa-none is none*/
10996 encryptionType =
10997 hdd_TranslateWPAToCsrEncryptionType(dot11WPAIE.multicast_cipher);
10998 }
Jeff Johnson295189b2012-06-20 16:38:30 -070010999 }
Shailender Karmuchi67edd312013-06-18 16:30:48 -070011000
Jeff Johnson295189b2012-06-20 16:38:30 -070011001 status = wlan_hdd_cfg80211_set_ie(pAdapter, params->ie, params->ie_len);
11002
11003 if (0 > status)
11004 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011005 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: failed to parse WPA/RSN IE",
Jeff Johnson295189b2012-06-20 16:38:30 -070011006 __func__);
11007 return status;
11008 }
11009 }
11010
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011011 pWextState->roamProfile.AuthType.authType[0] =
11012 pHddStaCtx->conn_info.authType =
Jeff Johnson295189b2012-06-20 16:38:30 -070011013 eCSR_AUTH_TYPE_OPEN_SYSTEM;
11014
11015 if (params->privacy)
11016 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011017 /* Security enabled IBSS, At this time there is no information available
11018 * about the security paramters, so initialise the encryption type to
Jeff Johnson295189b2012-06-20 16:38:30 -070011019 * eCSR_ENCRYPT_TYPE_WEP40_STATICKEY.
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011020 * The correct security parameters will be updated later in
Jeff Johnson295189b2012-06-20 16:38:30 -070011021 * wlan_hdd_cfg80211_add_key */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011022 /* Hal expects encryption type to be set inorder
Jeff Johnson295189b2012-06-20 16:38:30 -070011023 *enable privacy bit in beacons */
11024
11025 encryptionType = eCSR_ENCRYPT_TYPE_WEP40_STATICKEY;
11026 }
Shailender Karmuchi642e9812013-05-30 14:34:49 -070011027 VOS_TRACE (VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO_HIGH,
11028 "encryptionType=%d", encryptionType);
Jeff Johnson295189b2012-06-20 16:38:30 -070011029 pHddStaCtx->conn_info.ucEncryptionType = encryptionType;
11030 pWextState->roamProfile.EncryptionType.numEntries = 1;
11031 pWextState->roamProfile.EncryptionType.encryptionType[0] = encryptionType;
Jeff Johnson295189b2012-06-20 16:38:30 -070011032 return status;
11033}
11034
11035/*
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053011036 * FUNCTION: __wlan_hdd_cfg80211_join_ibss
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011037 * This function is used to create/join an IBSS
Jeff Johnson295189b2012-06-20 16:38:30 -070011038 */
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053011039static int __wlan_hdd_cfg80211_join_ibss( struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -070011040 struct net_device *dev,
11041 struct cfg80211_ibss_params *params
11042 )
11043{
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011044 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( dev );
Jeff Johnson295189b2012-06-20 16:38:30 -070011045 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
11046 tCsrRoamProfile *pRoamProfile;
11047 int status;
krunal sonie9002db2013-11-25 14:24:17 -080011048 bool alloc_bssid = VOS_FALSE;
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053011049 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
11050 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Jeff Johnson295189b2012-06-20 16:38:30 -070011051
11052 ENTER();
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053011053
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053011054 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
11055 TRACE_CODE_HDD_CFG80211_JOIN_IBSS,
11056 pAdapter->sessionId, pAdapter->device_mode));
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011057 hddLog(VOS_TRACE_LEVEL_INFO,
Sushant Kaushik8bc7df22014-04-09 17:55:29 +053011058 "%s: device_mode = %s (%d)", __func__,
11059 hdd_device_modetoString(pAdapter->device_mode),
11060 pAdapter->device_mode);
Jeff Johnson295189b2012-06-20 16:38:30 -070011061
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053011062 status = wlan_hdd_validate_context(pHddCtx);
11063
11064 if (0 != status)
Jeff Johnson295189b2012-06-20 16:38:30 -070011065 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053011066 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
11067 "%s: HDD context is not valid", __func__);
11068 return status;
Jeff Johnson295189b2012-06-20 16:38:30 -070011069 }
11070
11071 if (NULL == pWextState)
11072 {
Arif Hussain6d2a3322013-11-17 19:50:10 -080011073 hddLog (VOS_TRACE_LEVEL_ERROR, "%s ERROR: Data Storage Corruption",
Jeff Johnson295189b2012-06-20 16:38:30 -070011074 __func__);
11075 return -EIO;
11076 }
11077
Agarwal Ashish51325b52014-06-16 16:50:49 +053011078 if (vos_max_concurrent_connections_reached()) {
11079 hddLog(VOS_TRACE_LEVEL_INFO, FL("Reached max concurrent connections"));
11080 return -ECONNREFUSED;
11081 }
11082
Vinay Krishna Eranna21042322014-01-08 19:21:39 +053011083 /*Try disconnecting if already in connected state*/
11084 status = wlan_hdd_try_disconnect(pAdapter);
11085 if ( 0 > status)
11086 {
11087 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Failed to disconnect the existing"
11088 " IBSS connection"));
11089 return -EALREADY;
11090 }
11091
Jeff Johnson295189b2012-06-20 16:38:30 -070011092 pRoamProfile = &pWextState->roamProfile;
11093
11094 if ( eCSR_BSS_TYPE_START_IBSS != pRoamProfile->BSSType )
11095 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011096 hddLog (VOS_TRACE_LEVEL_ERROR,
Arif Hussain6d2a3322013-11-17 19:50:10 -080011097 "%s Interface type is not set to IBSS", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -070011098 return -EINVAL;
11099 }
11100
Praveen Kumar Sirisillad123d142013-09-24 16:50:13 -070011101 /* BSSID is provided by upper layers hence no need to AUTO generate */
11102 if (NULL != params->bssid) {
11103 if (ccmCfgSetInt(pHddCtx->hHal, WNI_CFG_IBSS_AUTO_BSSID, 0,
11104 NULL, eANI_BOOLEAN_FALSE)==eHAL_STATUS_FAILURE) {
11105 hddLog (VOS_TRACE_LEVEL_ERROR,
11106 "%s:ccmCfgStInt faild for WNI_CFG_IBSS_AUTO_BSSID", __func__);
11107 return -EIO;
11108 }
11109 }
krunal sonie9002db2013-11-25 14:24:17 -080011110 else if(pHddCtx->cfg_ini->isCoalesingInIBSSAllowed == 0)
11111 {
11112 if (ccmCfgSetInt(pHddCtx->hHal, WNI_CFG_IBSS_AUTO_BSSID, 0,
11113 NULL, eANI_BOOLEAN_FALSE)==eHAL_STATUS_FAILURE)
11114 {
11115 hddLog (VOS_TRACE_LEVEL_ERROR,
11116 "%s:ccmCfgStInt faild for WNI_CFG_IBSS_AUTO_BSSID", __func__);
11117 return -EIO;
11118 }
11119 params->bssid = vos_mem_malloc(sizeof(VOS_MAC_ADDR_SIZE));
11120 if (!params->bssid)
11121 {
11122 hddLog (VOS_TRACE_LEVEL_ERROR,
11123 "%s:Failed memory allocation", __func__);
11124 return -EIO;
11125 }
11126 vos_mem_copy((v_U8_t *)params->bssid,
11127 (v_U8_t *)&pHddCtx->cfg_ini->IbssBssid.bytes[0],
11128 VOS_MAC_ADDR_SIZE);
11129 alloc_bssid = VOS_TRUE;
11130 }
Praveen Kumar Sirisillad123d142013-09-24 16:50:13 -070011131
Jeff Johnson295189b2012-06-20 16:38:30 -070011132 /* Set Channel */
Yue Maf49ba872013-08-19 12:04:25 -070011133 if (NULL !=
11134#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,8,0))
11135 params->chandef.chan)
11136#else
11137 params->channel)
11138#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070011139 {
11140 u8 channelNum;
Shailender Karmuchi15cd0672013-05-15 19:50:04 -070011141 v_U32_t numChans = WNI_CFG_VALID_CHANNEL_LIST_LEN;
11142 v_U8_t validChan[WNI_CFG_VALID_CHANNEL_LIST_LEN];
11143 tHalHandle hHal = WLAN_HDD_GET_HAL_CTX(pAdapter);
11144 int indx;
Jeff Johnson295189b2012-06-20 16:38:30 -070011145
11146 /* Get channel number */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011147 channelNum =
Yue Maf49ba872013-08-19 12:04:25 -070011148 ieee80211_frequency_to_channel(
11149#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,8,0))
11150 params->chandef.chan->center_freq);
11151#else
11152 params->channel->center_freq);
11153#endif
Shailender Karmuchi15cd0672013-05-15 19:50:04 -070011154
11155 if (0 != ccmCfgGetStr(hHal, WNI_CFG_VALID_CHANNEL_LIST,
11156 validChan, &numChans))
Jeff Johnson295189b2012-06-20 16:38:30 -070011157 {
Shailender Karmuchi15cd0672013-05-15 19:50:04 -070011158 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: No valid channel list",
11159 __func__);
11160 return -EOPNOTSUPP;
Jeff Johnson295189b2012-06-20 16:38:30 -070011161 }
Shailender Karmuchi15cd0672013-05-15 19:50:04 -070011162
11163 for (indx = 0; indx < numChans; indx++)
Jeff Johnson295189b2012-06-20 16:38:30 -070011164 {
Shailender Karmuchi15cd0672013-05-15 19:50:04 -070011165 if (channelNum == validChan[indx])
11166 {
11167 break;
11168 }
11169 }
11170 if (indx >= numChans)
11171 {
11172 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Not valid Channel %d",
Jeff Johnson295189b2012-06-20 16:38:30 -070011173 __func__, channelNum);
11174 return -EINVAL;
11175 }
Shailender Karmuchi15cd0672013-05-15 19:50:04 -070011176 /* Set the Operational Channel */
11177 hddLog(VOS_TRACE_LEVEL_INFO_HIGH, "%s: set channel %d", __func__,
11178 channelNum);
11179 pRoamProfile->ChannelInfo.numOfChannels = 1;
11180 pHddStaCtx->conn_info.operationChannel = channelNum;
11181 pRoamProfile->ChannelInfo.ChannelList =
11182 &pHddStaCtx->conn_info.operationChannel;
Jeff Johnson295189b2012-06-20 16:38:30 -070011183 }
11184
11185 /* Initialize security parameters */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011186 status = wlan_hdd_cfg80211_set_privacy_ibss(pAdapter, params);
Jeff Johnson295189b2012-06-20 16:38:30 -070011187 if (status < 0)
11188 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011189 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: failed to set security parameters",
Jeff Johnson295189b2012-06-20 16:38:30 -070011190 __func__);
11191 return status;
11192 }
11193
11194 /* Issue connect start */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011195 status = wlan_hdd_cfg80211_connect_start(pAdapter, params->ssid,
Shailender Karmuchi15cd0672013-05-15 19:50:04 -070011196 params->ssid_len, params->bssid,
11197 pHddStaCtx->conn_info.operationChannel);
Jeff Johnson295189b2012-06-20 16:38:30 -070011198
11199 if (0 > status)
11200 {
11201 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: connect failed", __func__);
11202 return status;
11203 }
11204
krunal sonie9002db2013-11-25 14:24:17 -080011205 if (NULL != params->bssid &&
11206 pHddCtx->cfg_ini->isCoalesingInIBSSAllowed == 0 &&
11207 alloc_bssid == VOS_TRUE)
11208 {
11209 vos_mem_free(params->bssid);
11210 }
Jeff Johnson295189b2012-06-20 16:38:30 -070011211 return 0;
11212}
11213
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053011214static int wlan_hdd_cfg80211_join_ibss( struct wiphy *wiphy,
11215 struct net_device *dev,
11216 struct cfg80211_ibss_params *params
11217 )
11218{
11219 int ret = 0;
11220
11221 vos_ssr_protect(__func__);
11222 ret = __wlan_hdd_cfg80211_join_ibss(wiphy, dev, params);
11223 vos_ssr_unprotect(__func__);
11224
11225 return ret;
11226}
11227
Jeff Johnson295189b2012-06-20 16:38:30 -070011228/*
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053011229 * FUNCTION: __wlan_hdd_cfg80211_leave_ibss
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011230 * This function is used to leave an IBSS
Jeff Johnson295189b2012-06-20 16:38:30 -070011231 */
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053011232static int __wlan_hdd_cfg80211_leave_ibss( struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -070011233 struct net_device *dev
11234 )
11235{
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011236 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( dev );
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053011237 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
11238 tCsrRoamProfile *pRoamProfile;
11239 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053011240 int status;
Jeff Johnson295189b2012-06-20 16:38:30 -070011241
11242 ENTER();
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053011243
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053011244 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
11245 TRACE_CODE_HDD_CFG80211_LEAVE_IBSS,
11246 pAdapter->sessionId, eCSR_DISCONNECT_REASON_IBSS_LEAVE));
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053011247 status = wlan_hdd_validate_context(pHddCtx);
11248
11249 if (0 != status)
Jeff Johnson04dd8a82012-06-29 20:41:40 -070011250 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053011251 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
11252 "%s: HDD context is not valid", __func__);
11253 return status;
Jeff Johnson04dd8a82012-06-29 20:41:40 -070011254 }
11255
Sushant Kaushik8bc7df22014-04-09 17:55:29 +053011256 hddLog(VOS_TRACE_LEVEL_INFO, "%s: device_mode = %s (%d)", __func__,
11257 hdd_device_modetoString(pAdapter->device_mode),
11258 pAdapter->device_mode);
Jeff Johnson295189b2012-06-20 16:38:30 -070011259 if (NULL == pWextState)
11260 {
Arif Hussain6d2a3322013-11-17 19:50:10 -080011261 hddLog (VOS_TRACE_LEVEL_ERROR, "%s ERROR: Data Storage Corruption",
Jeff Johnson295189b2012-06-20 16:38:30 -070011262 __func__);
11263 return -EIO;
11264 }
11265
11266 pRoamProfile = &pWextState->roamProfile;
11267
11268 /* Issue disconnect only if interface type is set to IBSS */
11269 if (eCSR_BSS_TYPE_START_IBSS != pRoamProfile->BSSType)
11270 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011271 hddLog (VOS_TRACE_LEVEL_ERROR, "%s: BSS Type is not set to IBSS",
Jeff Johnson295189b2012-06-20 16:38:30 -070011272 __func__);
11273 return -EINVAL;
11274 }
11275
11276 /* Issue Disconnect request */
11277 INIT_COMPLETION(pAdapter->disconnect_comp_var);
11278 sme_RoamDisconnect( WLAN_HDD_GET_HAL_CTX(pAdapter), pAdapter->sessionId,
11279 eCSR_DISCONNECT_REASON_IBSS_LEAVE);
11280
11281 return 0;
11282}
11283
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053011284static int wlan_hdd_cfg80211_leave_ibss( struct wiphy *wiphy,
11285 struct net_device *dev
11286 )
11287{
11288 int ret = 0;
11289
11290 vos_ssr_protect(__func__);
11291 ret = __wlan_hdd_cfg80211_leave_ibss(wiphy, dev);
11292 vos_ssr_unprotect(__func__);
11293
11294 return ret;
11295}
11296
Jeff Johnson295189b2012-06-20 16:38:30 -070011297/*
Mahesh A Saptasagar179d2252014-06-02 21:32:21 +053011298 * FUNCTION: __wlan_hdd_cfg80211_set_wiphy_params
Jeff Johnson295189b2012-06-20 16:38:30 -070011299 * This function is used to set the phy parameters
11300 * (RTS Threshold/FRAG Threshold/Retry Count etc ...)
11301 */
Mahesh A Saptasagar179d2252014-06-02 21:32:21 +053011302static int __wlan_hdd_cfg80211_set_wiphy_params(struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -070011303 u32 changed)
11304{
11305 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
11306 tHalHandle hHal = pHddCtx->hHal;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053011307 int status;
Jeff Johnson295189b2012-06-20 16:38:30 -070011308
11309 ENTER();
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053011310 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
11311 TRACE_CODE_HDD_CFG80211_SET_WIPHY_PARAMS,
11312 NO_SESSION, wiphy->rts_threshold));
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053011313 status = wlan_hdd_validate_context(pHddCtx);
11314
11315 if (0 != status)
Jeff Johnson04dd8a82012-06-29 20:41:40 -070011316 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053011317 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
11318 "%s: HDD context is not valid", __func__);
11319 return status;
Jeff Johnson04dd8a82012-06-29 20:41:40 -070011320 }
11321
Jeff Johnson295189b2012-06-20 16:38:30 -070011322 if (changed & WIPHY_PARAM_RTS_THRESHOLD)
11323 {
11324 u16 rts_threshold = (wiphy->rts_threshold == -1) ?
11325 WNI_CFG_RTS_THRESHOLD_STAMAX :
11326 wiphy->rts_threshold;
11327
11328 if ((WNI_CFG_RTS_THRESHOLD_STAMIN > rts_threshold) ||
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011329 (WNI_CFG_RTS_THRESHOLD_STAMAX < rts_threshold))
Jeff Johnson295189b2012-06-20 16:38:30 -070011330 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011331 hddLog(VOS_TRACE_LEVEL_ERROR,
11332 "%s: Invalid RTS Threshold value %hu",
Jeff Johnson295189b2012-06-20 16:38:30 -070011333 __func__, rts_threshold);
11334 return -EINVAL;
11335 }
11336
11337 if (0 != ccmCfgSetInt(hHal, WNI_CFG_RTS_THRESHOLD,
11338 rts_threshold, ccmCfgSetCallback,
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011339 eANI_BOOLEAN_TRUE))
Jeff Johnson295189b2012-06-20 16:38:30 -070011340 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011341 hddLog(VOS_TRACE_LEVEL_ERROR,
11342 "%s: ccmCfgSetInt failed for rts_threshold value %hu",
Jeff Johnson295189b2012-06-20 16:38:30 -070011343 __func__, rts_threshold);
11344 return -EIO;
11345 }
11346
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011347 hddLog(VOS_TRACE_LEVEL_INFO_MED, "%s: set rts threshold %hu", __func__,
Jeff Johnson295189b2012-06-20 16:38:30 -070011348 rts_threshold);
11349 }
11350
11351 if (changed & WIPHY_PARAM_FRAG_THRESHOLD)
11352 {
11353 u16 frag_threshold = (wiphy->frag_threshold == -1) ?
11354 WNI_CFG_FRAGMENTATION_THRESHOLD_STAMAX :
11355 wiphy->frag_threshold;
11356
11357 if ((WNI_CFG_FRAGMENTATION_THRESHOLD_STAMIN > frag_threshold)||
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011358 (WNI_CFG_FRAGMENTATION_THRESHOLD_STAMAX < frag_threshold) )
Jeff Johnson295189b2012-06-20 16:38:30 -070011359 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011360 hddLog(VOS_TRACE_LEVEL_ERROR,
11361 "%s: Invalid frag_threshold value %hu", __func__,
Jeff Johnson295189b2012-06-20 16:38:30 -070011362 frag_threshold);
11363 return -EINVAL;
11364 }
11365
11366 if (0 != ccmCfgSetInt(hHal, WNI_CFG_FRAGMENTATION_THRESHOLD,
11367 frag_threshold, ccmCfgSetCallback,
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011368 eANI_BOOLEAN_TRUE))
Jeff Johnson295189b2012-06-20 16:38:30 -070011369 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011370 hddLog(VOS_TRACE_LEVEL_ERROR,
11371 "%s: ccmCfgSetInt failed for frag_threshold value %hu",
Jeff Johnson295189b2012-06-20 16:38:30 -070011372 __func__, frag_threshold);
11373 return -EIO;
11374 }
11375
11376 hddLog(VOS_TRACE_LEVEL_INFO_MED, "%s: set frag threshold %hu", __func__,
11377 frag_threshold);
11378 }
11379
11380 if ((changed & WIPHY_PARAM_RETRY_SHORT)
11381 || (changed & WIPHY_PARAM_RETRY_LONG))
11382 {
11383 u8 retry_value = (changed & WIPHY_PARAM_RETRY_SHORT) ?
11384 wiphy->retry_short :
11385 wiphy->retry_long;
11386
11387 if ((WNI_CFG_LONG_RETRY_LIMIT_STAMIN > retry_value) ||
11388 (WNI_CFG_LONG_RETRY_LIMIT_STAMAX < retry_value))
11389 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011390 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Invalid Retry count %hu",
Jeff Johnson295189b2012-06-20 16:38:30 -070011391 __func__, retry_value);
11392 return -EINVAL;
11393 }
11394
11395 if (changed & WIPHY_PARAM_RETRY_SHORT)
11396 {
11397 if (0 != ccmCfgSetInt(hHal, WNI_CFG_LONG_RETRY_LIMIT,
11398 retry_value, ccmCfgSetCallback,
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011399 eANI_BOOLEAN_TRUE))
Jeff Johnson295189b2012-06-20 16:38:30 -070011400 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011401 hddLog(VOS_TRACE_LEVEL_ERROR,
11402 "%s: ccmCfgSetInt failed for long retry count %hu",
Jeff Johnson295189b2012-06-20 16:38:30 -070011403 __func__, retry_value);
11404 return -EIO;
11405 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011406 hddLog(VOS_TRACE_LEVEL_INFO_MED, "%s: set long retry count %hu",
Jeff Johnson295189b2012-06-20 16:38:30 -070011407 __func__, retry_value);
11408 }
11409 else if (changed & WIPHY_PARAM_RETRY_SHORT)
11410 {
11411 if (0 != ccmCfgSetInt(hHal, WNI_CFG_SHORT_RETRY_LIMIT,
11412 retry_value, ccmCfgSetCallback,
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011413 eANI_BOOLEAN_TRUE))
Jeff Johnson295189b2012-06-20 16:38:30 -070011414 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011415 hddLog(VOS_TRACE_LEVEL_ERROR,
11416 "%s: ccmCfgSetInt failed for short retry count %hu",
Jeff Johnson295189b2012-06-20 16:38:30 -070011417 __func__, retry_value);
11418 return -EIO;
11419 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011420 hddLog(VOS_TRACE_LEVEL_INFO_MED, "%s: set short retry count %hu",
Jeff Johnson295189b2012-06-20 16:38:30 -070011421 __func__, retry_value);
11422 }
11423 }
11424
11425 return 0;
11426}
11427
Mahesh A Saptasagar179d2252014-06-02 21:32:21 +053011428static int wlan_hdd_cfg80211_set_wiphy_params(struct wiphy *wiphy,
11429 u32 changed)
11430{
11431 int ret;
11432
11433 vos_ssr_protect(__func__);
11434 ret = __wlan_hdd_cfg80211_set_wiphy_params(wiphy, changed);
11435 vos_ssr_unprotect(__func__);
11436
11437 return ret;
11438}
11439
Jeff Johnson295189b2012-06-20 16:38:30 -070011440/*
Mahesh A Saptasagar179d2252014-06-02 21:32:21 +053011441 * FUNCTION: __wlan_hdd_cfg80211_set_txpower
Jeff Johnson295189b2012-06-20 16:38:30 -070011442 * This function is used to set the txpower
11443 */
Mahesh A Saptasagar179d2252014-06-02 21:32:21 +053011444static int __wlan_hdd_cfg80211_set_txpower(struct wiphy *wiphy,
Yue Maf49ba872013-08-19 12:04:25 -070011445#if LINUX_VERSION_CODE >= KERNEL_VERSION(3,8,0)
11446 struct wireless_dev *wdev,
11447#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070011448#if LINUX_VERSION_CODE <= KERNEL_VERSION(2,6,35)
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011449 enum tx_power_setting type,
Jeff Johnson295189b2012-06-20 16:38:30 -070011450#else
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011451 enum nl80211_tx_power_setting type,
Jeff Johnson295189b2012-06-20 16:38:30 -070011452#endif
11453 int dbm)
11454{
11455 hdd_context_t *pHddCtx = (hdd_context_t*) wiphy_priv(wiphy);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053011456 tHalHandle hHal = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -070011457 tSirMacAddr bssid = {0xFF,0xFF,0xFF,0xFF,0xFF,0xFF};
11458 tSirMacAddr selfMac = {0xFF,0xFF,0xFF,0xFF,0xFF,0xFF};
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053011459 int status;
Jeff Johnson295189b2012-06-20 16:38:30 -070011460
11461 ENTER();
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053011462 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
11463 TRACE_CODE_HDD_CFG80211_SET_TXPOWER,
11464 NO_SESSION, type ));
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053011465 status = wlan_hdd_validate_context(pHddCtx);
11466
11467 if (0 != status)
11468 {
11469 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
11470 "%s: HDD context is not valid", __func__);
11471 return status;
11472 }
11473
11474 hHal = pHddCtx->hHal;
11475
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011476 if (0 != ccmCfgSetInt(hHal, WNI_CFG_CURRENT_TX_POWER_LEVEL,
11477 dbm, ccmCfgSetCallback,
11478 eANI_BOOLEAN_TRUE))
Jeff Johnson295189b2012-06-20 16:38:30 -070011479 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011480 hddLog(VOS_TRACE_LEVEL_ERROR,
Jeff Johnson295189b2012-06-20 16:38:30 -070011481 "%s: ccmCfgSetInt failed for tx power %hu", __func__, dbm);
11482 return -EIO;
11483 }
11484
11485 hddLog(VOS_TRACE_LEVEL_INFO_MED, "%s: set tx power level %d dbm", __func__,
11486 dbm);
11487
11488 switch(type)
11489 {
11490 case NL80211_TX_POWER_AUTOMATIC: /*automatically determine transmit power*/
11491 /* Fall through */
11492 case NL80211_TX_POWER_LIMITED: /*limit TX power by the mBm parameter*/
11493 if( sme_SetMaxTxPower(hHal, bssid, selfMac, dbm) != eHAL_STATUS_SUCCESS )
11494 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011495 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Setting maximum tx power failed",
11496 __func__);
11497 return -EIO;
Jeff Johnson295189b2012-06-20 16:38:30 -070011498 }
11499 break;
11500 case NL80211_TX_POWER_FIXED: /*fix TX power to the mBm parameter*/
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011501 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: NL80211_TX_POWER_FIXED not supported",
Jeff Johnson295189b2012-06-20 16:38:30 -070011502 __func__);
11503 return -EOPNOTSUPP;
11504 break;
11505 default:
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011506 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Invalid power setting type %d",
11507 __func__, type);
Jeff Johnson295189b2012-06-20 16:38:30 -070011508 return -EIO;
11509 }
11510
11511 return 0;
11512}
11513
Mahesh A Saptasagar179d2252014-06-02 21:32:21 +053011514static int wlan_hdd_cfg80211_set_txpower(struct wiphy *wiphy,
11515#if LINUX_VERSION_CODE >= KERNEL_VERSION(3,8,0)
11516 struct wireless_dev *wdev,
11517#endif
11518#if LINUX_VERSION_CODE <= KERNEL_VERSION(2,6,35)
11519 enum tx_power_setting type,
11520#else
11521 enum nl80211_tx_power_setting type,
11522#endif
11523 int dbm)
11524{
11525 int ret;
11526 vos_ssr_protect(__func__);
11527 ret = __wlan_hdd_cfg80211_set_txpower(wiphy,
11528#if LINUX_VERSION_CODE >= KERNEL_VERSION(3,8,0)
11529 wdev,
11530#endif
11531#if LINUX_VERSION_CODE <= KERNEL_VERSION(2,6,35)
11532 type,
11533#else
11534 type,
11535#endif
11536 dbm);
11537 vos_ssr_unprotect(__func__);
11538
11539 return ret;
11540}
11541
Jeff Johnson295189b2012-06-20 16:38:30 -070011542/*
11543 * FUNCTION: wlan_hdd_cfg80211_get_txpower
11544 * This function is used to read the txpower
11545 */
Yue Maf49ba872013-08-19 12:04:25 -070011546static int wlan_hdd_cfg80211_get_txpower(struct wiphy *wiphy,
11547#if LINUX_VERSION_CODE >= KERNEL_VERSION(3,8,0)
11548 struct wireless_dev *wdev,
11549#endif
11550 int *dbm)
Jeff Johnson295189b2012-06-20 16:38:30 -070011551{
11552
11553 hdd_adapter_t *pAdapter;
11554 hdd_context_t *pHddCtx = (hdd_context_t*) wiphy_priv(wiphy);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053011555 int status;
Jeff Johnson295189b2012-06-20 16:38:30 -070011556
Jeff Johnsone7245742012-09-05 17:12:55 -070011557 ENTER();
11558
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053011559 status = wlan_hdd_validate_context(pHddCtx);
Jeff Johnson295189b2012-06-20 16:38:30 -070011560
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053011561 if (0 != status)
Jeff Johnson04dd8a82012-06-29 20:41:40 -070011562 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053011563 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
11564 "%s: HDD context is not valid", __func__);
11565 *dbm = 0;
11566 return status;
Jeff Johnson04dd8a82012-06-29 20:41:40 -070011567 }
11568
Jeff Johnson295189b2012-06-20 16:38:30 -070011569 pAdapter = hdd_get_adapter(pHddCtx, WLAN_HDD_INFRA_STATION);
11570 if (NULL == pAdapter)
11571 {
11572 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: Not in station context " ,__func__);
11573 return -ENOENT;
11574 }
11575
11576 wlan_hdd_get_classAstats(pAdapter);
11577 *dbm = pAdapter->hdd_stats.ClassA_stat.max_pwr;
11578
Jeff Johnsone7245742012-09-05 17:12:55 -070011579 EXIT();
Jeff Johnson295189b2012-06-20 16:38:30 -070011580 return 0;
11581}
11582
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053011583static int __wlan_hdd_cfg80211_get_station(struct wiphy *wiphy, struct net_device *dev,
Jeff Johnson295189b2012-06-20 16:38:30 -070011584 u8* mac, struct station_info *sinfo)
11585{
11586 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( dev );
11587 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
11588 int ssidlen = pHddStaCtx->conn_info.SSID.SSID.length;
c_hpothu44ff4e02014-05-08 00:13:57 +053011589 tANI_U32 rate_flags;
Jeff Johnson295189b2012-06-20 16:38:30 -070011590
11591 hdd_context_t *pHddCtx = (hdd_context_t*) wiphy_priv(wiphy);
11592 hdd_config_t *pCfg = pHddCtx->cfg_ini;
Jeff Johnson295189b2012-06-20 16:38:30 -070011593
11594 tANI_U8 OperationalRates[CSR_DOT11_SUPPORTED_RATES_MAX];
11595 tANI_U32 ORLeng = CSR_DOT11_SUPPORTED_RATES_MAX;
11596 tANI_U8 ExtendedRates[CSR_DOT11_EXTENDED_SUPPORTED_RATES_MAX];
11597 tANI_U32 ERLeng = CSR_DOT11_EXTENDED_SUPPORTED_RATES_MAX;
11598 tANI_U8 MCSRates[SIZE_OF_BASIC_MCS_SET];
11599 tANI_U32 MCSLeng = SIZE_OF_BASIC_MCS_SET;
11600 tANI_U16 maxRate = 0;
11601 tANI_U16 myRate;
11602 tANI_U16 currentRate = 0;
11603 tANI_U8 maxSpeedMCS = 0;
11604 tANI_U8 maxMCSIdx = 0;
11605 tANI_U8 rateFlag = 1;
c_hpothu79aab322014-07-14 21:11:01 +053011606 tANI_U8 i, j, rssidx, mode=0;
Madan Mohan Koyyalamudic75be962012-10-18 19:19:03 -070011607 tANI_U16 temp;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053011608 int status;
Jeff Johnson295189b2012-06-20 16:38:30 -070011609
Leo Chang6f8870f2013-03-26 18:11:36 -070011610#ifdef WLAN_FEATURE_11AC
11611 tANI_U32 vht_mcs_map;
11612 eDataRate11ACMaxMcs vhtMaxMcs;
11613#endif /* WLAN_FEATURE_11AC */
11614
Jeff Johnsone7245742012-09-05 17:12:55 -070011615 ENTER();
11616
Jeff Johnson295189b2012-06-20 16:38:30 -070011617 if ((eConnectionState_Associated != pHddStaCtx->conn_info.connState) ||
11618 (0 == ssidlen))
11619 {
11620 hddLog(VOS_TRACE_LEVEL_INFO, "%s: Not associated or"
11621 " Invalid ssidlen, %d", __func__, ssidlen);
11622 /*To keep GUI happy*/
11623 return 0;
11624 }
11625
Mukul Sharma811205f2014-07-09 21:07:30 +053011626 if (VOS_TRUE == pHddStaCtx->hdd_ReassocScenario)
11627 {
11628 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
11629 "%s: Roaming in progress, so unable to proceed this request", __func__);
11630 return 0;
11631 }
11632
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053011633 status = wlan_hdd_validate_context(pHddCtx);
11634
11635 if (0 != status)
Jeff Johnson04dd8a82012-06-29 20:41:40 -070011636 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053011637 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
11638 "%s: HDD context is not valid", __func__);
11639 return status;
Jeff Johnson04dd8a82012-06-29 20:41:40 -070011640 }
11641
Jeff Johnson295189b2012-06-20 16:38:30 -070011642
Kiet Lam3b17fc82013-09-27 05:24:08 +053011643 wlan_hdd_get_rssi(pAdapter, &sinfo->signal);
11644 sinfo->filled |= STATION_INFO_SIGNAL;
11645
c_hpothu09f19542014-05-30 21:53:31 +053011646 wlan_hdd_get_station_stats(pAdapter);
11647 rate_flags = pAdapter->hdd_stats.ClassA_stat.tx_rate_flags;
11648
11649 /*overwrite rate_flags if MAX link-speed need to be reported*/
c_hpothu44ff4e02014-05-08 00:13:57 +053011650 if ((eHDD_LINK_SPEED_REPORT_MAX == pCfg->reportMaxLinkSpeed) ||
11651 (eHDD_LINK_SPEED_REPORT_MAX_SCALED == pCfg->reportMaxLinkSpeed &&
c_hpothu79aab322014-07-14 21:11:01 +053011652 sinfo->signal >= pCfg->linkSpeedRssiLow))
c_hpothu44ff4e02014-05-08 00:13:57 +053011653 {
11654 rate_flags = pAdapter->maxRateFlags;
11655 }
c_hpothu44ff4e02014-05-08 00:13:57 +053011656
Jeff Johnson295189b2012-06-20 16:38:30 -070011657 //convert to the UI units of 100kbps
11658 myRate = pAdapter->hdd_stats.ClassA_stat.tx_rate * 5;
11659
11660#ifdef LINKSPEED_DEBUG_ENABLED
Leo Chang6f8870f2013-03-26 18:11:36 -070011661 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 -070011662 sinfo->signal,
11663 pCfg->reportMaxLinkSpeed,
11664 myRate,
11665 (int) pCfg->linkSpeedRssiHigh,
Madan Mohan Koyyalamudi8df78d52012-11-02 12:30:06 -070011666 (int) pCfg->linkSpeedRssiMid,
11667 (int) pCfg->linkSpeedRssiLow,
Leo Chang6f8870f2013-03-26 18:11:36 -070011668 (int) rate_flags,
11669 (int) pAdapter->hdd_stats.ClassA_stat.mcs_index);
Jeff Johnson295189b2012-06-20 16:38:30 -070011670#endif //LINKSPEED_DEBUG_ENABLED
11671
11672 if (eHDD_LINK_SPEED_REPORT_ACTUAL != pCfg->reportMaxLinkSpeed)
11673 {
11674 // we do not want to necessarily report the current speed
11675 if (eHDD_LINK_SPEED_REPORT_MAX == pCfg->reportMaxLinkSpeed)
11676 {
11677 // report the max possible speed
11678 rssidx = 0;
11679 }
11680 else if (eHDD_LINK_SPEED_REPORT_MAX_SCALED == pCfg->reportMaxLinkSpeed)
11681 {
11682 // report the max possible speed with RSSI scaling
11683 if (sinfo->signal >= pCfg->linkSpeedRssiHigh)
11684 {
11685 // report the max possible speed
11686 rssidx = 0;
11687 }
Madan Mohan Koyyalamudi8df78d52012-11-02 12:30:06 -070011688 else if (sinfo->signal >= pCfg->linkSpeedRssiMid)
Jeff Johnson295189b2012-06-20 16:38:30 -070011689 {
11690 // report middle speed
11691 rssidx = 1;
11692 }
Madan Mohan Koyyalamudi8df78d52012-11-02 12:30:06 -070011693 else if (sinfo->signal >= pCfg->linkSpeedRssiLow)
11694 {
11695 // report middle speed
11696 rssidx = 2;
11697 }
Jeff Johnson295189b2012-06-20 16:38:30 -070011698 else
11699 {
11700 // report actual speed
Madan Mohan Koyyalamudi8df78d52012-11-02 12:30:06 -070011701 rssidx = 3;
Jeff Johnson295189b2012-06-20 16:38:30 -070011702 }
11703 }
11704 else
11705 {
11706 // unknown, treat as eHDD_LINK_SPEED_REPORT_MAX
11707 hddLog(VOS_TRACE_LEVEL_ERROR,
11708 "%s: Invalid value for reportMaxLinkSpeed: %u",
11709 __func__, pCfg->reportMaxLinkSpeed);
11710 rssidx = 0;
11711 }
11712
11713 maxRate = 0;
11714
11715 /* Get Basic Rate Set */
Gopichand Nakkala05ab1322013-02-15 11:28:38 +053011716 if (0 != ccmCfgGetStr(WLAN_HDD_GET_HAL_CTX(pAdapter), WNI_CFG_OPERATIONAL_RATE_SET,
11717 OperationalRates, &ORLeng))
11718 {
11719 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: ccm api returned failure", __func__);
11720 /*To keep GUI happy*/
11721 return 0;
11722 }
11723
Jeff Johnson295189b2012-06-20 16:38:30 -070011724 for (i = 0; i < ORLeng; i++)
11725 {
Jeff Johnsone7245742012-09-05 17:12:55 -070011726 for (j = 0; j < (sizeof(supported_data_rate) / sizeof(supported_data_rate[0])); j ++)
Jeff Johnson295189b2012-06-20 16:38:30 -070011727 {
11728 /* Validate Rate Set */
11729 if (supported_data_rate[j].beacon_rate_index == (OperationalRates[i] & 0x7F))
11730 {
11731 currentRate = supported_data_rate[j].supported_rate[rssidx];
11732 break;
11733 }
11734 }
11735 /* Update MAX rate */
11736 maxRate = (currentRate > maxRate)?currentRate:maxRate;
11737 }
11738
11739 /* Get Extended Rate Set */
Gopichand Nakkala05ab1322013-02-15 11:28:38 +053011740 if (0 != ccmCfgGetStr(WLAN_HDD_GET_HAL_CTX(pAdapter), WNI_CFG_EXTENDED_OPERATIONAL_RATE_SET,
11741 ExtendedRates, &ERLeng))
11742 {
11743 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: ccm api returned failure", __func__);
11744 /*To keep GUI happy*/
11745 return 0;
11746 }
11747
Jeff Johnson295189b2012-06-20 16:38:30 -070011748 for (i = 0; i < ERLeng; i++)
11749 {
Jeff Johnsone7245742012-09-05 17:12:55 -070011750 for (j = 0; j < (sizeof(supported_data_rate) / sizeof(supported_data_rate[0])); j ++)
Jeff Johnson295189b2012-06-20 16:38:30 -070011751 {
11752 if (supported_data_rate[j].beacon_rate_index == (ExtendedRates[i] & 0x7F))
11753 {
11754 currentRate = supported_data_rate[j].supported_rate[rssidx];
11755 break;
11756 }
11757 }
11758 /* Update MAX rate */
11759 maxRate = (currentRate > maxRate)?currentRate:maxRate;
11760 }
c_hpothu79aab322014-07-14 21:11:01 +053011761
Kiet Lamb69f8dc2013-11-15 15:34:27 +053011762 /* Get MCS Rate Set --
Kaushik, Sushantdc304d82014-01-22 10:58:37 +053011763 Only if we are always reporting max speed (or)
Kiet Lamb69f8dc2013-11-15 15:34:27 +053011764 if we have good rssi */
c_hpothu79aab322014-07-14 21:11:01 +053011765 if ((3 != rssidx) && !(rate_flags & eHAL_TX_RATE_LEGACY))
Jeff Johnson295189b2012-06-20 16:38:30 -070011766 {
c_hpothu79aab322014-07-14 21:11:01 +053011767 if (rate_flags & eHAL_TX_RATE_VHT80)
11768 mode = 2;
11769 else if (rate_flags & (eHAL_TX_RATE_VHT40 | eHAL_TX_RATE_HT40))
11770 mode = 1;
11771 else
11772 mode = 0;
11773
Gopichand Nakkala05ab1322013-02-15 11:28:38 +053011774 if (0 != ccmCfgGetStr(WLAN_HDD_GET_HAL_CTX(pAdapter), WNI_CFG_CURRENT_MCS_SET,
11775 MCSRates, &MCSLeng))
11776 {
11777 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: ccm api returned failure", __func__);
11778 /*To keep GUI happy*/
11779 return 0;
11780 }
Jeff Johnson295189b2012-06-20 16:38:30 -070011781 rateFlag = 0;
Leo Chang6f8870f2013-03-26 18:11:36 -070011782#ifdef WLAN_FEATURE_11AC
11783 /* VHT80 rate has seperate rate table */
Gopichand Nakkala4c705372013-04-24 13:20:33 +053011784 if (rate_flags & (eHAL_TX_RATE_VHT20|eHAL_TX_RATE_VHT40|eHAL_TX_RATE_VHT80))
Jeff Johnson295189b2012-06-20 16:38:30 -070011785 {
Leo Chang6f8870f2013-03-26 18:11:36 -070011786 ccmCfgGetInt(WLAN_HDD_GET_HAL_CTX(pAdapter), WNI_CFG_VHT_TX_MCS_MAP, &vht_mcs_map);
Gopichand Nakkala4c705372013-04-24 13:20:33 +053011787 vhtMaxMcs = (eDataRate11ACMaxMcs)(vht_mcs_map & DATA_RATE_11AC_MCS_MASK );
Leo Chang6f8870f2013-03-26 18:11:36 -070011788 if (rate_flags & eHAL_TX_RATE_SGI)
Jeff Johnson295189b2012-06-20 16:38:30 -070011789 {
Leo Chang6f8870f2013-03-26 18:11:36 -070011790 rateFlag |= 1;
Jeff Johnson295189b2012-06-20 16:38:30 -070011791 }
Leo Chang6f8870f2013-03-26 18:11:36 -070011792 if (DATA_RATE_11AC_MAX_MCS_7 == vhtMaxMcs)
Jeff Johnson295189b2012-06-20 16:38:30 -070011793 {
Leo Chang6f8870f2013-03-26 18:11:36 -070011794 maxMCSIdx = 7;
11795 }
11796 else if (DATA_RATE_11AC_MAX_MCS_8 == vhtMaxMcs)
11797 {
11798 maxMCSIdx = 8;
11799 }
11800 else if (DATA_RATE_11AC_MAX_MCS_9 == vhtMaxMcs)
11801 {
Gopichand Nakkala4c705372013-04-24 13:20:33 +053011802 //VHT20 is supporting 0~8
11803 if (rate_flags & eHAL_TX_RATE_VHT20)
11804 maxMCSIdx = 8;
11805 else
11806 maxMCSIdx = 9;
Leo Chang6f8870f2013-03-26 18:11:36 -070011807 }
Gopichand Nakkala4c705372013-04-24 13:20:33 +053011808
c_hpothu79aab322014-07-14 21:11:01 +053011809 if (0 != rssidx)/*check for scaled */
11810 {
11811 //get middle rate MCS index if rssi=1/2
11812 for (i=0; i <= maxMCSIdx; i++)
11813 {
11814 if (sinfo->signal <= rssiMcsTbl[mode][i])
11815 {
11816 maxMCSIdx = i;
11817 break;
11818 }
11819 }
11820 }
11821
Gopichand Nakkala4c705372013-04-24 13:20:33 +053011822 if (rate_flags & eHAL_TX_RATE_VHT80)
11823 {
11824 currentRate = supported_vht_mcs_rate[pAdapter->hdd_stats.ClassA_stat.mcs_index].supported_VHT80_rate[rateFlag];
11825 maxRate = supported_vht_mcs_rate[maxMCSIdx].supported_VHT80_rate[rateFlag];
11826 }
11827 else if (rate_flags & eHAL_TX_RATE_VHT40)
11828 {
11829 currentRate = supported_vht_mcs_rate[pAdapter->hdd_stats.ClassA_stat.mcs_index].supported_VHT40_rate[rateFlag];
11830 maxRate = supported_vht_mcs_rate[maxMCSIdx].supported_VHT40_rate[rateFlag];
11831 }
11832 else if (rate_flags & eHAL_TX_RATE_VHT20)
11833 {
11834 currentRate = supported_vht_mcs_rate[pAdapter->hdd_stats.ClassA_stat.mcs_index].supported_VHT20_rate[rateFlag];
11835 maxRate = supported_vht_mcs_rate[maxMCSIdx].supported_VHT20_rate[rateFlag];
11836 }
11837
Leo Chang6f8870f2013-03-26 18:11:36 -070011838 maxSpeedMCS = 1;
11839 if (currentRate > maxRate)
11840 {
11841 maxRate = currentRate;
11842 }
Gopichand Nakkala4c705372013-04-24 13:20:33 +053011843
Leo Chang6f8870f2013-03-26 18:11:36 -070011844 }
11845 else
11846#endif /* WLAN_FEATURE_11AC */
11847 {
11848 if (rate_flags & eHAL_TX_RATE_HT40)
11849 {
11850 rateFlag |= 1;
11851 }
11852 if (rate_flags & eHAL_TX_RATE_SGI)
11853 {
11854 rateFlag |= 2;
11855 }
11856
Girish Gowli01abcee2014-07-31 20:18:55 +053011857 temp = sizeof(supported_mcs_rate) / sizeof(supported_mcs_rate[0]);
c_hpothu79aab322014-07-14 21:11:01 +053011858 if (rssidx == 1 || rssidx == 2)
11859 {
11860 //get middle rate MCS index if rssi=1/2
11861 for (i=0; i <= 7; i++)
11862 {
11863 if (sinfo->signal <= rssiMcsTbl[mode][i])
11864 {
11865 temp = i+1;
11866 break;
11867 }
11868 }
11869 }
c_hpothu79aab322014-07-14 21:11:01 +053011870
11871 for (i = 0; i < MCSLeng; i++)
11872 {
Leo Chang6f8870f2013-03-26 18:11:36 -070011873 for (j = 0; j < temp; j++)
11874 {
11875 if (supported_mcs_rate[j].beacon_rate_index == MCSRates[i])
11876 {
11877 currentRate = supported_mcs_rate[j].supported_rate[rateFlag];
11878 break;
11879 }
11880 }
11881 if ((j < temp) && (currentRate > maxRate))
11882 {
11883 maxRate = currentRate;
11884 maxSpeedMCS = 1;
11885 maxMCSIdx = supported_mcs_rate[j].beacon_rate_index;
11886 }
Jeff Johnson295189b2012-06-20 16:38:30 -070011887 }
11888 }
11889 }
11890
Gopichand Nakkala4c705372013-04-24 13:20:33 +053011891 else if (!(rate_flags & eHAL_TX_RATE_LEGACY))
11892 {
11893 maxRate = myRate;
11894 maxSpeedMCS = 1;
11895 maxMCSIdx = pAdapter->hdd_stats.ClassA_stat.mcs_index;
11896 }
Jeff Johnson295189b2012-06-20 16:38:30 -070011897 // make sure we report a value at least as big as our current rate
c_hpothu79aab322014-07-14 21:11:01 +053011898 if ((maxRate < myRate) || (0 == maxRate))
Jeff Johnson295189b2012-06-20 16:38:30 -070011899 {
11900 maxRate = myRate;
11901 if (rate_flags & eHAL_TX_RATE_LEGACY)
11902 {
11903 maxSpeedMCS = 0;
11904 }
11905 else
11906 {
11907 maxSpeedMCS = 1;
11908 maxMCSIdx = pAdapter->hdd_stats.ClassA_stat.mcs_index;
11909 }
11910 }
11911
Gopichand Nakkala4c705372013-04-24 13:20:33 +053011912 if (rate_flags & eHAL_TX_RATE_LEGACY)
Jeff Johnson295189b2012-06-20 16:38:30 -070011913 {
11914 sinfo->txrate.legacy = maxRate;
11915#ifdef LINKSPEED_DEBUG_ENABLED
11916 pr_info("Reporting legacy rate %d\n", sinfo->txrate.legacy);
11917#endif //LINKSPEED_DEBUG_ENABLED
11918 }
11919 else
11920 {
11921 sinfo->txrate.mcs = maxMCSIdx;
Leo Chang6f8870f2013-03-26 18:11:36 -070011922#ifdef WLAN_FEATURE_11AC
11923 sinfo->txrate.nss = 1;
11924 if (rate_flags & eHAL_TX_RATE_VHT80)
11925 {
11926 sinfo->txrate.flags |= RATE_INFO_FLAGS_VHT_MCS;
Gopichand Nakkala4c705372013-04-24 13:20:33 +053011927 sinfo->txrate.flags |= RATE_INFO_FLAGS_80_MHZ_WIDTH;
Leo Chang6f8870f2013-03-26 18:11:36 -070011928 }
Gopichand Nakkala4c705372013-04-24 13:20:33 +053011929 else if (rate_flags & eHAL_TX_RATE_VHT40)
Leo Chang6f8870f2013-03-26 18:11:36 -070011930 {
Gopichand Nakkala4c705372013-04-24 13:20:33 +053011931 sinfo->txrate.flags |= RATE_INFO_FLAGS_VHT_MCS;
11932 sinfo->txrate.flags |= RATE_INFO_FLAGS_40_MHZ_WIDTH;
11933 }
11934 else if (rate_flags & eHAL_TX_RATE_VHT20)
11935 {
11936 sinfo->txrate.flags |= RATE_INFO_FLAGS_VHT_MCS;
11937 }
11938#endif /* WLAN_FEATURE_11AC */
11939 if (rate_flags & (eHAL_TX_RATE_HT20 | eHAL_TX_RATE_HT40))
11940 {
11941 sinfo->txrate.flags |= RATE_INFO_FLAGS_MCS;
11942 if (rate_flags & eHAL_TX_RATE_HT40)
11943 {
11944 sinfo->txrate.flags |= RATE_INFO_FLAGS_40_MHZ_WIDTH;
11945 }
Leo Chang6f8870f2013-03-26 18:11:36 -070011946 }
Jeff Johnson295189b2012-06-20 16:38:30 -070011947 if (rate_flags & eHAL_TX_RATE_SGI)
11948 {
11949 sinfo->txrate.flags |= RATE_INFO_FLAGS_SHORT_GI;
11950 }
Gopichand Nakkala4c705372013-04-24 13:20:33 +053011951
Jeff Johnson295189b2012-06-20 16:38:30 -070011952#ifdef LINKSPEED_DEBUG_ENABLED
11953 pr_info("Reporting MCS rate %d flags %x\n",
11954 sinfo->txrate.mcs,
11955 sinfo->txrate.flags );
11956#endif //LINKSPEED_DEBUG_ENABLED
11957 }
11958 }
11959 else
11960 {
11961 // report current rate instead of max rate
11962
11963 if (rate_flags & eHAL_TX_RATE_LEGACY)
11964 {
11965 //provide to the UI in units of 100kbps
11966 sinfo->txrate.legacy = myRate;
11967#ifdef LINKSPEED_DEBUG_ENABLED
11968 pr_info("Reporting actual legacy rate %d\n", sinfo->txrate.legacy);
11969#endif //LINKSPEED_DEBUG_ENABLED
11970 }
11971 else
11972 {
11973 //must be MCS
11974 sinfo->txrate.mcs = pAdapter->hdd_stats.ClassA_stat.mcs_index;
Leo Chang6f8870f2013-03-26 18:11:36 -070011975#ifdef WLAN_FEATURE_11AC
11976 sinfo->txrate.nss = 1;
11977 if (rate_flags & eHAL_TX_RATE_VHT80)
11978 {
11979 sinfo->txrate.flags |= RATE_INFO_FLAGS_VHT_MCS;
11980 }
11981 else
11982#endif /* WLAN_FEATURE_11AC */
11983 {
11984 sinfo->txrate.flags |= RATE_INFO_FLAGS_MCS;
11985 }
Jeff Johnson295189b2012-06-20 16:38:30 -070011986 if (rate_flags & eHAL_TX_RATE_SGI)
11987 {
11988 sinfo->txrate.flags |= RATE_INFO_FLAGS_SHORT_GI;
11989 }
11990 if (rate_flags & eHAL_TX_RATE_HT40)
11991 {
11992 sinfo->txrate.flags |= RATE_INFO_FLAGS_40_MHZ_WIDTH;
11993 }
Leo Chang6f8870f2013-03-26 18:11:36 -070011994#ifdef WLAN_FEATURE_11AC
11995 else if (rate_flags & eHAL_TX_RATE_VHT80)
11996 {
11997 sinfo->txrate.flags |= RATE_INFO_FLAGS_80_MHZ_WIDTH;
11998 }
11999#endif /* WLAN_FEATURE_11AC */
Jeff Johnson295189b2012-06-20 16:38:30 -070012000#ifdef LINKSPEED_DEBUG_ENABLED
12001 pr_info("Reporting actual MCS rate %d flags %x\n",
12002 sinfo->txrate.mcs,
12003 sinfo->txrate.flags );
12004#endif //LINKSPEED_DEBUG_ENABLED
12005 }
12006 }
12007 sinfo->filled |= STATION_INFO_TX_BITRATE;
12008
Madan Mohan Koyyalamudi4d4d2812012-09-24 14:08:29 -070012009 sinfo->tx_packets =
12010 pAdapter->hdd_stats.summary_stat.tx_frm_cnt[0] +
12011 pAdapter->hdd_stats.summary_stat.tx_frm_cnt[1] +
12012 pAdapter->hdd_stats.summary_stat.tx_frm_cnt[2] +
12013 pAdapter->hdd_stats.summary_stat.tx_frm_cnt[3];
12014
12015 sinfo->tx_retries =
12016 pAdapter->hdd_stats.summary_stat.retry_cnt[0] +
12017 pAdapter->hdd_stats.summary_stat.retry_cnt[1] +
12018 pAdapter->hdd_stats.summary_stat.retry_cnt[2] +
12019 pAdapter->hdd_stats.summary_stat.retry_cnt[3];
12020
12021 sinfo->tx_failed =
12022 pAdapter->hdd_stats.summary_stat.fail_cnt[0] +
12023 pAdapter->hdd_stats.summary_stat.fail_cnt[1] +
12024 pAdapter->hdd_stats.summary_stat.fail_cnt[2] +
12025 pAdapter->hdd_stats.summary_stat.fail_cnt[3];
12026
12027 sinfo->filled |=
12028 STATION_INFO_TX_PACKETS |
12029 STATION_INFO_TX_RETRIES |
12030 STATION_INFO_TX_FAILED;
12031
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053012032 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
12033 TRACE_CODE_HDD_CFG80211_GET_STA,
12034 pAdapter->sessionId, maxRate));
Madan Mohan Koyyalamudi4d4d2812012-09-24 14:08:29 -070012035 EXIT();
12036 return 0;
Jeff Johnson295189b2012-06-20 16:38:30 -070012037}
12038
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053012039static int wlan_hdd_cfg80211_get_station(struct wiphy *wiphy, struct net_device *dev,
12040 u8* mac, struct station_info *sinfo)
12041{
12042 int ret;
12043
12044 vos_ssr_protect(__func__);
12045 ret = __wlan_hdd_cfg80211_get_station(wiphy, dev, mac, sinfo);
12046 vos_ssr_unprotect(__func__);
12047
12048 return ret;
12049}
12050
12051static int __wlan_hdd_cfg80211_set_power_mgmt(struct wiphy *wiphy,
Sameer Thalappilc9f26e92013-06-07 10:11:06 -070012052 struct net_device *dev, bool mode, int timeout)
Jeff Johnson295189b2012-06-20 16:38:30 -070012053{
12054 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
Gopichand Nakkala20c4c042013-04-19 22:08:55 +053012055 hdd_context_t *pHddCtx;
Jeff Johnson295189b2012-06-20 16:38:30 -070012056 VOS_STATUS vos_status;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053012057 int status;
Jeff Johnson295189b2012-06-20 16:38:30 -070012058
Jeff Johnsone7245742012-09-05 17:12:55 -070012059 ENTER();
12060
Jeff Johnson295189b2012-06-20 16:38:30 -070012061 if (NULL == pAdapter)
12062 {
Arif Hussain6d2a3322013-11-17 19:50:10 -080012063 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Adapter is NULL", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -070012064 return -ENODEV;
12065 }
12066
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053012067 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
12068 TRACE_CODE_HDD_CFG80211_SET_POWER_MGMT,
12069 pAdapter->sessionId, timeout));
12070
Gopichand Nakkala20c4c042013-04-19 22:08:55 +053012071 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053012072 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkala20c4c042013-04-19 22:08:55 +053012073
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053012074 if (0 != status)
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012075 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053012076 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
12077 "%s: HDD context is not valid", __func__);
12078 return status;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012079 }
12080
Gopichand Nakkala20c4c042013-04-19 22:08:55 +053012081 if ((DRIVER_POWER_MODE_AUTO == !mode) &&
12082 (TRUE == pHddCtx->hdd_wlan_suspended) &&
12083 (pHddCtx->cfg_ini->fhostArpOffload) &&
12084 (eConnectionState_Associated ==
12085 (WLAN_HDD_GET_STATION_CTX_PTR(pAdapter))->conn_info.connState))
12086 {
Amar Singhald53568e2013-09-26 11:03:45 -070012087
12088 hddLog(VOS_TRACE_LEVEL_INFO,
12089 "offload: in cfg80211_set_power_mgmt, calling arp offload");
Gopichand Nakkalab03e8082013-05-30 18:09:25 +053012090 vos_status = hdd_conf_arp_offload(pAdapter, TRUE);
Gopichand Nakkala20c4c042013-04-19 22:08:55 +053012091 if (!VOS_IS_STATUS_SUCCESS(vos_status))
12092 {
12093 hddLog(VOS_TRACE_LEVEL_INFO,
Arif Hussain6d2a3322013-11-17 19:50:10 -080012094 "%s:Failed to enable ARPOFFLOAD Feature %d",
Gopichand Nakkala20c4c042013-04-19 22:08:55 +053012095 __func__, vos_status);
12096 }
12097 }
12098
Jeff Johnson295189b2012-06-20 16:38:30 -070012099 /**The get power cmd from the supplicant gets updated by the nl only
12100 *on successful execution of the function call
12101 *we are oppositely mapped w.r.t mode in the driver
12102 **/
12103 vos_status = wlan_hdd_enter_bmps(pAdapter, !mode);
12104
Jeff Johnsone7245742012-09-05 17:12:55 -070012105 EXIT();
Jeff Johnson295189b2012-06-20 16:38:30 -070012106 if (VOS_STATUS_E_FAILURE == vos_status)
12107 {
c_hpothu6ff1c3c2013-10-01 19:01:57 +053012108 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
12109 "%s: failed to enter bmps mode", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -070012110 return -EINVAL;
12111 }
12112 return 0;
12113}
12114
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053012115static int wlan_hdd_cfg80211_set_power_mgmt(struct wiphy *wiphy,
12116 struct net_device *dev, bool mode, int timeout)
12117{
12118 int ret;
Jeff Johnson295189b2012-06-20 16:38:30 -070012119
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053012120 vos_ssr_protect(__func__);
12121 ret = __wlan_hdd_cfg80211_set_power_mgmt(wiphy, dev, mode, timeout);
12122 vos_ssr_unprotect(__func__);
12123
12124 return ret;
12125}
Jeff Johnson295189b2012-06-20 16:38:30 -070012126#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
12127static int wlan_hdd_set_default_mgmt_key(struct wiphy *wiphy,
12128 struct net_device *netdev,
12129 u8 key_index)
12130{
Jeff Johnsone7245742012-09-05 17:12:55 -070012131 ENTER();
Jeff Johnson295189b2012-06-20 16:38:30 -070012132 return 0;
12133}
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012134#endif //LINUX_VERSION_CODE
Jeff Johnson295189b2012-06-20 16:38:30 -070012135
12136#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,4,0))
12137static int wlan_hdd_set_txq_params(struct wiphy *wiphy,
12138 struct net_device *dev,
12139 struct ieee80211_txq_params *params)
12140{
Jeff Johnsone7245742012-09-05 17:12:55 -070012141 ENTER();
Jeff Johnson295189b2012-06-20 16:38:30 -070012142 return 0;
12143}
12144#elif (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
12145static int wlan_hdd_set_txq_params(struct wiphy *wiphy,
12146 struct ieee80211_txq_params *params)
12147{
Jeff Johnsone7245742012-09-05 17:12:55 -070012148 ENTER();
Jeff Johnson295189b2012-06-20 16:38:30 -070012149 return 0;
12150}
12151#endif //LINUX_VERSION_CODE
12152
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053012153static int __wlan_hdd_cfg80211_del_station(struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -070012154 struct net_device *dev, u8 *mac)
12155{
12156 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053012157 hdd_context_t *pHddCtx;
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -080012158 VOS_STATUS vos_status;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053012159 int status;
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -080012160 v_U8_t staId;
Jeff Johnson295189b2012-06-20 16:38:30 -070012161
Jeff Johnsone7245742012-09-05 17:12:55 -070012162 ENTER();
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053012163
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053012164 if ( NULL == pAdapter )
Jeff Johnson295189b2012-06-20 16:38:30 -070012165 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053012166 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Invalid Adapter" ,__func__);
Jeff Johnson295189b2012-06-20 16:38:30 -070012167 return -EINVAL;
12168 }
12169
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053012170 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
12171 TRACE_CODE_HDD_CFG80211_DEL_STA,
12172 pAdapter->sessionId, pAdapter->device_mode));
12173
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053012174 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
12175 status = wlan_hdd_validate_context(pHddCtx);
Jeff Johnson295189b2012-06-20 16:38:30 -070012176
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053012177 if (0 != status)
Jeff Johnson04dd8a82012-06-29 20:41:40 -070012178 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053012179 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
12180 "%s: HDD context is not valid", __func__);
12181 return status;
Jeff Johnson04dd8a82012-06-29 20:41:40 -070012182 }
12183
Jeff Johnson295189b2012-06-20 16:38:30 -070012184 if ( (WLAN_HDD_SOFTAP == pAdapter->device_mode)
Jeff Johnson295189b2012-06-20 16:38:30 -070012185 || (WLAN_HDD_P2P_GO == pAdapter->device_mode)
Jeff Johnson295189b2012-06-20 16:38:30 -070012186 )
12187 {
12188 if( NULL == mac )
12189 {
12190 v_U16_t i;
12191 for(i = 0; i < WLAN_MAX_STA_COUNT; i++)
12192 {
Rajesh Chauhan18488fc2013-08-22 10:15:03 -070012193 if ((pAdapter->aStaInfo[i].isUsed) &&
12194 (!pAdapter->aStaInfo[i].isDeauthInProgress))
Jeff Johnson295189b2012-06-20 16:38:30 -070012195 {
12196 u8 *macAddr = pAdapter->aStaInfo[i].macAddrSTA.bytes;
12197 hddLog(VOS_TRACE_LEVEL_INFO,
Arif Hussain24bafea2013-11-15 15:10:03 -080012198 "%s: Delete STA with MAC::"
12199 MAC_ADDRESS_STR,
12200 __func__, MAC_ADDR_ARRAY(macAddr));
Rajesh Chauhan18488fc2013-08-22 10:15:03 -070012201 vos_status = hdd_softap_sta_deauth(pAdapter, macAddr);
12202 if (VOS_IS_STATUS_SUCCESS(vos_status))
12203 pAdapter->aStaInfo[i].isDeauthInProgress = TRUE;
Jeff Johnson295189b2012-06-20 16:38:30 -070012204 }
12205 }
12206 }
12207 else
12208 {
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -080012209
12210 vos_status = hdd_softap_GetStaId(pAdapter,(v_MACADDR_t *)mac, &staId);
12211 if (!VOS_IS_STATUS_SUCCESS(vos_status))
12212 {
12213 hddLog(VOS_TRACE_LEVEL_INFO,
Arif Hussain24bafea2013-11-15 15:10:03 -080012214 "%s: Skip this DEL STA as this is not used::"
12215 MAC_ADDRESS_STR,
12216 __func__, MAC_ADDR_ARRAY(mac));
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -080012217 return -ENOENT;
12218 }
12219
12220 if( pAdapter->aStaInfo[staId].isDeauthInProgress == TRUE)
12221 {
12222 hddLog(VOS_TRACE_LEVEL_INFO,
Arif Hussain24bafea2013-11-15 15:10:03 -080012223 "%s: Skip this DEL STA as deauth is in progress::"
12224 MAC_ADDRESS_STR,
12225 __func__, MAC_ADDR_ARRAY(mac));
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -080012226 return -ENOENT;
12227 }
12228
12229 pAdapter->aStaInfo[staId].isDeauthInProgress = TRUE;
12230
Jeff Johnson295189b2012-06-20 16:38:30 -070012231 hddLog(VOS_TRACE_LEVEL_INFO,
12232 "%s: Delete STA with MAC::"
Arif Hussain24bafea2013-11-15 15:10:03 -080012233 MAC_ADDRESS_STR,
Jeff Johnson295189b2012-06-20 16:38:30 -070012234 __func__,
Arif Hussain24bafea2013-11-15 15:10:03 -080012235 MAC_ADDR_ARRAY(mac));
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -080012236
12237 vos_status = hdd_softap_sta_deauth(pAdapter, mac);
12238 if (!VOS_IS_STATUS_SUCCESS(vos_status))
12239 {
12240 pAdapter->aStaInfo[staId].isDeauthInProgress = FALSE;
12241 hddLog(VOS_TRACE_LEVEL_INFO,
12242 "%s: STA removal failed for ::"
Arif Hussain24bafea2013-11-15 15:10:03 -080012243 MAC_ADDRESS_STR,
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -080012244 __func__,
Arif Hussain24bafea2013-11-15 15:10:03 -080012245 MAC_ADDR_ARRAY(mac));
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -080012246 return -ENOENT;
12247 }
12248
Jeff Johnson295189b2012-06-20 16:38:30 -070012249 }
12250 }
12251
12252 EXIT();
12253
12254 return 0;
12255}
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053012256static int wlan_hdd_cfg80211_del_station(struct wiphy *wiphy,
12257 struct net_device *dev, u8 *mac)
12258{
12259 int ret;
Jeff Johnson295189b2012-06-20 16:38:30 -070012260
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053012261 vos_ssr_protect(__func__);
12262 ret = __wlan_hdd_cfg80211_del_station(wiphy, dev, mac);
12263 vos_ssr_unprotect(__func__);
12264
12265 return ret;
12266}
12267
12268static int __wlan_hdd_cfg80211_add_station(struct wiphy *wiphy,
Hoonki Lee11f7dda2013-02-14 16:55:44 -080012269 struct net_device *dev, u8 *mac, struct station_parameters *params)
12270{
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053012271 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
Gopichand Nakkalab977a972013-02-18 19:15:09 -080012272 int status = -EPERM;
Hoonki Lee11f7dda2013-02-14 16:55:44 -080012273#ifdef FEATURE_WLAN_TDLS
12274 u32 mask, set;
Hoonki Lee11f7dda2013-02-14 16:55:44 -080012275 ENTER();
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053012276
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053012277 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
12278 TRACE_CODE_HDD_CFG80211_ADD_STA,
12279 pAdapter->sessionId, params->listen_interval));
Mohit Khanna698ba2a2012-12-04 15:08:18 -080012280 mask = params->sta_flags_mask;
12281
12282 set = params->sta_flags_set;
12283
Gopichand Nakkalac87400e2013-03-13 18:51:00 -070012284#ifdef WLAN_FEATURE_TDLS_DEBUG
12285 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
12286 "%s: mask 0x%x set 0x%x " MAC_ADDRESS_STR,
12287 __func__, mask, set, MAC_ADDR_ARRAY(mac));
12288#endif
Mohit Khanna698ba2a2012-12-04 15:08:18 -080012289
12290 if (mask & BIT(NL80211_STA_FLAG_TDLS_PEER)) {
12291 if (set & BIT(NL80211_STA_FLAG_TDLS_PEER)) {
Gopichand Nakkala681989c2013-03-06 22:27:48 -080012292 status = wlan_hdd_tdls_add_station(wiphy, dev, mac, 0, NULL);
Mohit Khanna698ba2a2012-12-04 15:08:18 -080012293 }
12294 }
12295#endif
Gopichand Nakkalab977a972013-02-18 19:15:09 -080012296 return status;
Jeff Johnson295189b2012-06-20 16:38:30 -070012297}
12298
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053012299static int wlan_hdd_cfg80211_add_station(struct wiphy *wiphy,
12300 struct net_device *dev, u8 *mac, struct station_parameters *params)
12301{
12302 int ret;
Jeff Johnson04dd8a82012-06-29 20:41:40 -070012303
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053012304 vos_ssr_protect(__func__);
12305 ret = __wlan_hdd_cfg80211_add_station(wiphy, dev, mac, params);
12306 vos_ssr_unprotect(__func__);
12307
12308 return ret;
12309}
Jeff Johnson04dd8a82012-06-29 20:41:40 -070012310#ifdef FEATURE_WLAN_LFR
Wilson Yang6507c4e2013-10-01 20:11:19 -070012311
Mahesh A Saptasagarf7418d72014-06-02 14:48:54 +053012312static int __wlan_hdd_cfg80211_set_pmksa(struct wiphy *wiphy, struct net_device *dev,
Jeff Johnsond13512a2012-07-17 11:42:19 -070012313 struct cfg80211_pmksa *pmksa)
Jeff Johnson04dd8a82012-06-29 20:41:40 -070012314{
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012315 tANI_U32 j=0;
Jeff Johnson04dd8a82012-06-29 20:41:40 -070012316 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
Agarwal Ashish3da95242014-05-21 14:57:17 +053012317 hdd_station_ctx_t *pHddStaCtx;
Jeff Johnson04dd8a82012-06-29 20:41:40 -070012318 tHalHandle halHandle;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012319 eHalStatus result;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053012320 int status;
Jeff Johnson04dd8a82012-06-29 20:41:40 -070012321 tANI_U8 BSSIDMatched = 0;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053012322 hdd_context_t *pHddCtx;
Jeff Johnson0299d0a2013-10-30 12:37:43 -070012323 hddLog(VOS_TRACE_LEVEL_DEBUG, "%s: set PMKSA for " MAC_ADDRESS_STR,
12324 __func__, MAC_ADDR_ARRAY(pmksa->bssid));
Jeff Johnsone7245742012-09-05 17:12:55 -070012325
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012326 // Validate pAdapter
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053012327 if ( NULL == pAdapter )
Jeff Johnson04dd8a82012-06-29 20:41:40 -070012328 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053012329 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Invalid Adapter" ,__func__);
Jeff Johnson04dd8a82012-06-29 20:41:40 -070012330 return -EINVAL;
12331 }
12332
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053012333 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
12334 status = wlan_hdd_validate_context(pHddCtx);
Jeff Johnson04dd8a82012-06-29 20:41:40 -070012335
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053012336 if (0 != status)
Jeff Johnson04dd8a82012-06-29 20:41:40 -070012337 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053012338 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
12339 "%s: HDD context is not valid", __func__);
12340 return status;
Jeff Johnson04dd8a82012-06-29 20:41:40 -070012341 }
12342
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012343 // Retrieve halHandle
Jeff Johnson04dd8a82012-06-29 20:41:40 -070012344 halHandle = WLAN_HDD_GET_HAL_CTX(pAdapter);
Agarwal Ashish3da95242014-05-21 14:57:17 +053012345 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
Jeff Johnson04dd8a82012-06-29 20:41:40 -070012346
Agarwal Ashish3da95242014-05-21 14:57:17 +053012347 for (j = 0; j < pHddStaCtx->PMKIDCacheIndex; j++)
Jeff Johnson04dd8a82012-06-29 20:41:40 -070012348 {
Agarwal Ashish3da95242014-05-21 14:57:17 +053012349 if (vos_mem_compare(pHddStaCtx->PMKIDCache[j].BSSID,
Jeff Johnson04dd8a82012-06-29 20:41:40 -070012350 pmksa->bssid, WNI_CFG_BSSID_LEN))
12351 {
12352 /* BSSID matched previous entry. Overwrite it. */
12353 BSSIDMatched = 1;
Agarwal Ashish3da95242014-05-21 14:57:17 +053012354 vos_mem_copy(pHddStaCtx->PMKIDCache[j].BSSID,
Jeff Johnson04dd8a82012-06-29 20:41:40 -070012355 pmksa->bssid, WNI_CFG_BSSID_LEN);
Agarwal Ashish3da95242014-05-21 14:57:17 +053012356 vos_mem_copy(pHddStaCtx->PMKIDCache[j].PMKID,
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012357 pmksa->pmkid,
Jeff Johnson04dd8a82012-06-29 20:41:40 -070012358 CSR_RSN_PMKID_SIZE);
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012359 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: Reusing cache entry %d.",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -070012360 __func__, j );
Jeff Johnson04dd8a82012-06-29 20:41:40 -070012361 dump_bssid(pmksa->bssid);
12362 dump_pmkid(halHandle, pmksa->pmkid);
12363 break;
12364 }
12365 }
12366
Madan Mohan Koyyalamudic4b317d2012-10-18 19:43:08 -070012367 /* Check we compared all entries,if then take the first slot now */
Agarwal Ashish3da95242014-05-21 14:57:17 +053012368 if (j == MAX_PMKSAIDS_IN_CACHE) pHddStaCtx->PMKIDCacheIndex=0;
Madan Mohan Koyyalamudic4b317d2012-10-18 19:43:08 -070012369
Jeff Johnson04dd8a82012-06-29 20:41:40 -070012370 if (!BSSIDMatched)
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012371 {
12372 // Now, we DON'T have a BSSID match, so take a new entry in the cache.
Agarwal Ashish3da95242014-05-21 14:57:17 +053012373 vos_mem_copy(pHddStaCtx->PMKIDCache[pHddStaCtx->PMKIDCacheIndex].BSSID,
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012374 pmksa->bssid, ETHER_ADDR_LEN);
Agarwal Ashish3da95242014-05-21 14:57:17 +053012375 vos_mem_copy(pHddStaCtx->PMKIDCache[pHddStaCtx->PMKIDCacheIndex].PMKID,
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012376 pmksa->pmkid,
Jeff Johnson04dd8a82012-06-29 20:41:40 -070012377 CSR_RSN_PMKID_SIZE);
Agarwal Ashish3da95242014-05-21 14:57:17 +053012378 hddLog(VOS_TRACE_LEVEL_DEBUG, "%s: Adding a new cache entry %d.",
12379 __func__, pHddStaCtx->PMKIDCacheIndex );
Jeff Johnson04dd8a82012-06-29 20:41:40 -070012380 dump_bssid(pmksa->bssid);
12381 dump_pmkid(halHandle, pmksa->pmkid);
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012382 // Increment the HDD Local Cache index
Jeff Johnson04dd8a82012-06-29 20:41:40 -070012383 // The "i=0" doesn't work for the call to sme_RoamSetPMKIDCache() - LFR FIXME
Agarwal Ashish3da95242014-05-21 14:57:17 +053012384 if (pHddStaCtx->PMKIDCacheIndex <= (MAX_PMKSAIDS_IN_CACHE-1))
12385 pHddStaCtx->PMKIDCacheIndex++;
12386 else
12387 pHddStaCtx->PMKIDCacheIndex = 0;
Jeff Johnson04dd8a82012-06-29 20:41:40 -070012388 }
12389
12390
12391 // Calling csrRoamSetPMKIDCache to configure the PMKIDs into the cache
Agarwal Ashish3da95242014-05-21 14:57:17 +053012392 hddLog(VOS_TRACE_LEVEL_DEBUG, "%s: Calling csrRoamSetPMKIDCache with %d cache entries.",
12393 __func__, pHddStaCtx->PMKIDCacheIndex );
12394
Jeff Johnson04dd8a82012-06-29 20:41:40 -070012395 // Finally set the PMKSA ID Cache in CSR
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012396 result = sme_RoamSetPMKIDCache(halHandle,pAdapter->sessionId,
Agarwal Ashish3da95242014-05-21 14:57:17 +053012397 pHddStaCtx->PMKIDCache,
12398 pHddStaCtx->PMKIDCacheIndex);
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053012399 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
12400 TRACE_CODE_HDD_CFG80211_SET_PMKSA,
12401 pAdapter->sessionId, result));
Jeff Johnson04dd8a82012-06-29 20:41:40 -070012402 return 0;
12403}
12404
Mahesh A Saptasagarf7418d72014-06-02 14:48:54 +053012405static int wlan_hdd_cfg80211_set_pmksa(struct wiphy *wiphy, struct net_device *dev,
12406 struct cfg80211_pmksa *pmksa)
12407{
12408 int ret;
12409
12410 vos_ssr_protect(__func__);
12411 ret = __wlan_hdd_cfg80211_set_pmksa(wiphy, dev, pmksa);
12412 vos_ssr_unprotect(__func__);
12413
12414 return ret;
12415}
Jeff Johnson04dd8a82012-06-29 20:41:40 -070012416
Wilson Yang6507c4e2013-10-01 20:11:19 -070012417
Mahesh A Saptasagarf7418d72014-06-02 14:48:54 +053012418static int __wlan_hdd_cfg80211_del_pmksa(struct wiphy *wiphy, struct net_device *dev,
Wilson Yang6507c4e2013-10-01 20:11:19 -070012419 struct cfg80211_pmksa *pmksa)
Jeff Johnson04dd8a82012-06-29 20:41:40 -070012420{
Wilson Yang6507c4e2013-10-01 20:11:19 -070012421 tANI_U32 j=0;
12422 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
Agarwal Ashish3da95242014-05-21 14:57:17 +053012423 hdd_station_ctx_t *pHddStaCtx;
Wilson Yang6507c4e2013-10-01 20:11:19 -070012424 tHalHandle halHandle;
Wilson Yang6507c4e2013-10-01 20:11:19 -070012425 tANI_U8 BSSIDMatched = 0;
Wilson Yang6507c4e2013-10-01 20:11:19 -070012426 hdd_context_t *pHddCtx;
Wilson Yangef657d32014-01-15 19:19:23 -080012427 int status = 0;
Wilson Yang6507c4e2013-10-01 20:11:19 -070012428
Jeff Johnson0299d0a2013-10-30 12:37:43 -070012429 hddLog(VOS_TRACE_LEVEL_DEBUG, "%s: deleting PMKSA for " MAC_ADDRESS_STR,
12430 __func__, MAC_ADDR_ARRAY(pmksa->bssid));
Wilson Yang6507c4e2013-10-01 20:11:19 -070012431
12432 /* Validate pAdapter */
12433 if (NULL == pAdapter)
12434 {
12435 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Invalid Adapter" ,__func__);
12436 return -EINVAL;
12437 }
12438
12439 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
12440 status = wlan_hdd_validate_context(pHddCtx);
12441
12442 if (0 != status)
12443 {
12444 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
12445 "%s: HDD context is not valid", __func__);
12446 return status;
12447 }
12448
12449 /*Retrieve halHandle*/
12450 halHandle = WLAN_HDD_GET_HAL_CTX(pAdapter);
Agarwal Ashish3da95242014-05-21 14:57:17 +053012451 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
Wilson Yang6507c4e2013-10-01 20:11:19 -070012452
12453 /*in case index is 0,no entry to delete*/
Agarwal Ashish3da95242014-05-21 14:57:17 +053012454 if (0 == pHddStaCtx->PMKIDCacheIndex)
Wilson Yang6507c4e2013-10-01 20:11:19 -070012455 {
Agarwal Ashish3da95242014-05-21 14:57:17 +053012456 hddLog(VOS_TRACE_LEVEL_INFO, FL("No entries to flush"));
12457 return 0;
Wilson Yang6507c4e2013-10-01 20:11:19 -070012458 }
12459
12460 /*find the matching PMKSA entry from j=0 to (index-1),
12461 * and delete the matched one
12462 */
Agarwal Ashish3da95242014-05-21 14:57:17 +053012463 for (j = 0; j < pHddStaCtx->PMKIDCacheIndex; j++)
Wilson Yang6507c4e2013-10-01 20:11:19 -070012464 {
Agarwal Ashish3da95242014-05-21 14:57:17 +053012465 if (vos_mem_compare(pHddStaCtx->PMKIDCache[j].BSSID,
Wilson Yang6507c4e2013-10-01 20:11:19 -070012466 pmksa->bssid,
12467 WNI_CFG_BSSID_LEN))
12468 {
12469 /* BSSID matched entry */
12470 BSSIDMatched = 1;
Agarwal Ashish3da95242014-05-21 14:57:17 +053012471 if (j < pHddStaCtx->PMKIDCacheIndex-1)
Wilson Yang6507c4e2013-10-01 20:11:19 -070012472 {
12473 /*replace the matching entry with the last entry in HDD local cache*/
Agarwal Ashish3da95242014-05-21 14:57:17 +053012474 vos_mem_copy(pHddStaCtx->PMKIDCache[j].BSSID,
12475 pHddStaCtx->PMKIDCache[pHddStaCtx->PMKIDCacheIndex-1].BSSID,
12476 VOS_MAC_ADDR_SIZE);
12477 vos_mem_copy(pHddStaCtx->PMKIDCache[j].PMKID,
12478 pHddStaCtx->PMKIDCache[pHddStaCtx->PMKIDCacheIndex-1].PMKID,
12479 CSR_RSN_PMKID_SIZE);
12480 }
Wilson Yang6507c4e2013-10-01 20:11:19 -070012481
12482 /*clear the last entry in HDD cache ---[index-1]*/
Agarwal Ashish3da95242014-05-21 14:57:17 +053012483 vos_mem_zero(pHddStaCtx->PMKIDCache[pHddStaCtx->PMKIDCacheIndex-1].BSSID,
12484 VOS_MAC_ADDR_SIZE);
12485 vos_mem_zero(pHddStaCtx->PMKIDCache[pHddStaCtx->PMKIDCacheIndex-1].PMKID,
12486 CSR_RSN_PMKID_SIZE);
Wilson Yang6507c4e2013-10-01 20:11:19 -070012487 /*reduce the PMKID array index*/
Agarwal Ashish3da95242014-05-21 14:57:17 +053012488 pHddStaCtx->PMKIDCacheIndex--;
Wilson Yang6507c4e2013-10-01 20:11:19 -070012489 /*delete the last PMKID cache in CSR*/
Wilson Yangef657d32014-01-15 19:19:23 -080012490 if (eHAL_STATUS_SUCCESS !=
12491 sme_RoamDelPMKIDfromCache(halHandle, pAdapter->sessionId, pmksa->bssid))
Wilson Yang6507c4e2013-10-01 20:11:19 -070012492 {
12493 hddLog(VOS_TRACE_LEVEL_ERROR,"%s: cannot delete PMKSA %d CONTENT.",
Agarwal Ashish3da95242014-05-21 14:57:17 +053012494 __func__, pHddStaCtx->PMKIDCacheIndex);
Wilson Yangef657d32014-01-15 19:19:23 -080012495 status = -EINVAL;
Wilson Yang6507c4e2013-10-01 20:11:19 -070012496 }
12497
12498 dump_bssid(pmksa->bssid);
12499 dump_pmkid(halHandle,pmksa->pmkid);
12500
12501 break;
12502 }
12503 }
12504
12505 /* we compare all entries,but cannot find matching entry */
12506 if (j == MAX_PMKSAIDS_IN_CACHE && !BSSIDMatched)
12507 {
Jeff Johnson0299d0a2013-10-30 12:37:43 -070012508 hddLog(VOS_TRACE_LEVEL_FATAL,
12509 "%s: No such PMKSA entry existed " MAC_ADDRESS_STR,
12510 __func__, MAC_ADDR_ARRAY(pmksa->bssid));
Wilson Yang6507c4e2013-10-01 20:11:19 -070012511 dump_bssid(pmksa->bssid);
12512 dump_pmkid(halHandle, pmksa->pmkid);
12513 return -EINVAL;
12514 }
Wilson Yangef657d32014-01-15 19:19:23 -080012515 return status;
Jeff Johnson04dd8a82012-06-29 20:41:40 -070012516}
12517
Wilson Yang6507c4e2013-10-01 20:11:19 -070012518
Mahesh A Saptasagarf7418d72014-06-02 14:48:54 +053012519static int wlan_hdd_cfg80211_del_pmksa(struct wiphy *wiphy, struct net_device *dev,
12520 struct cfg80211_pmksa *pmksa)
12521{
12522 int ret;
Wilson Yang6507c4e2013-10-01 20:11:19 -070012523
Mahesh A Saptasagarf7418d72014-06-02 14:48:54 +053012524 vos_ssr_protect(__func__);
12525 ret = __wlan_hdd_cfg80211_del_pmksa(wiphy, dev, pmksa);
12526 vos_ssr_unprotect(__func__);
12527
12528 return ret;
12529
12530}
12531
12532static int __wlan_hdd_cfg80211_flush_pmksa(struct wiphy *wiphy, struct net_device *dev)
Jeff Johnson04dd8a82012-06-29 20:41:40 -070012533{
Wilson Yang6507c4e2013-10-01 20:11:19 -070012534 tANI_U32 j=0;
12535 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
Agarwal Ashish3da95242014-05-21 14:57:17 +053012536 hdd_station_ctx_t *pHddStaCtx;
Wilson Yang6507c4e2013-10-01 20:11:19 -070012537 tHalHandle halHandle;
12538 hdd_context_t *pHddCtx;
12539 tANI_U8 *pBSSId;
Wilson Yangef657d32014-01-15 19:19:23 -080012540 int status = 0;
Wilson Yang6507c4e2013-10-01 20:11:19 -070012541
12542 hddLog(VOS_TRACE_LEVEL_DEBUG, "%s: flushing PMKSA ",__func__);
12543
12544 /* Validate pAdapter */
12545 if (NULL == pAdapter)
12546 {
12547 hddLog(VOS_TRACE_LEVEL_ERROR,
12548 "%s: Invalid Adapter" ,__func__);
12549 return -EINVAL;
12550 }
12551
12552 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
12553 status = wlan_hdd_validate_context(pHddCtx);
12554
12555 if (0 != status)
12556 {
12557 hddLog(VOS_TRACE_LEVEL_ERROR,
12558 "%s: HDD context is not valid", __func__);
12559 return status;
12560 }
12561
12562 /*Retrieve halHandle*/
12563 halHandle = WLAN_HDD_GET_HAL_CTX(pAdapter);
Agarwal Ashish3da95242014-05-21 14:57:17 +053012564 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
Wilson Yang6507c4e2013-10-01 20:11:19 -070012565
12566 /*in case index is 0,no entry to delete*/
Agarwal Ashish3da95242014-05-21 14:57:17 +053012567 if (0 == pHddStaCtx->PMKIDCacheIndex)
Wilson Yang6507c4e2013-10-01 20:11:19 -070012568 {
Vinay Krishna Erannacbf75f42014-02-26 17:35:20 +053012569 hddLog(VOS_TRACE_LEVEL_ERROR, FL("No entries to flush"));
Agarwal Ashish3da95242014-05-21 14:57:17 +053012570 return 0;
Wilson Yang6507c4e2013-10-01 20:11:19 -070012571 }
12572
12573 /*delete all the PMKSA one by one */
Agarwal Ashish3da95242014-05-21 14:57:17 +053012574 for (j = 0; j < pHddStaCtx->PMKIDCacheIndex; j++)
Wilson Yang6507c4e2013-10-01 20:11:19 -070012575 {
Agarwal Ashish3da95242014-05-21 14:57:17 +053012576 pBSSId =(tANI_U8 *)(pHddStaCtx->PMKIDCache[j].BSSID);
Wilson Yang6507c4e2013-10-01 20:11:19 -070012577 /*delete the PMKID in CSR*/
Wilson Yangef657d32014-01-15 19:19:23 -080012578 if (eHAL_STATUS_SUCCESS !=
12579 sme_RoamDelPMKIDfromCache(halHandle, pAdapter->sessionId, pBSSId))
Wilson Yang6507c4e2013-10-01 20:11:19 -070012580 {
12581 hddLog(VOS_TRACE_LEVEL_ERROR ,"%s cannot flush PMKIDCache %d.",
12582 __func__,j);
Wilson Yangef657d32014-01-15 19:19:23 -080012583 status = -EINVAL;
Wilson Yang6507c4e2013-10-01 20:11:19 -070012584 }
Kiet Lam8d21d5b2013-10-31 17:18:29 +053012585 /*clear the entry in HDD cache 0--index-1 */
Agarwal Ashish3da95242014-05-21 14:57:17 +053012586 vos_mem_zero(pHddStaCtx->PMKIDCache[j].BSSID, VOS_MAC_ADDR_SIZE);
12587 vos_mem_zero(pHddStaCtx->PMKIDCache[j].PMKID, CSR_RSN_PMKID_SIZE);
12588 }
Wilson Yang6507c4e2013-10-01 20:11:19 -070012589
Agarwal Ashish3da95242014-05-21 14:57:17 +053012590 pHddStaCtx->PMKIDCacheIndex = 0;
Wilson Yangef657d32014-01-15 19:19:23 -080012591 return status;
Jeff Johnson04dd8a82012-06-29 20:41:40 -070012592}
Mahesh A Saptasagarf7418d72014-06-02 14:48:54 +053012593
12594static int wlan_hdd_cfg80211_flush_pmksa(struct wiphy *wiphy, struct net_device *dev)
12595{
12596 int ret;
12597
12598 vos_ssr_protect(__func__);
12599 ret = __wlan_hdd_cfg80211_flush_pmksa(wiphy, dev);
12600 vos_ssr_unprotect(__func__);
12601
12602 return ret;
12603}
Jeff Johnson04dd8a82012-06-29 20:41:40 -070012604#endif
12605
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070012606#if defined(WLAN_FEATURE_VOWIFI_11R) && defined(KERNEL_SUPPORT_11R_CFG80211)
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053012607static int __wlan_hdd_cfg80211_update_ft_ies(struct wiphy *wiphy,
12608 struct net_device *dev,
12609 struct cfg80211_update_ft_ies_params *ftie)
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070012610{
12611 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
12612 hdd_station_ctx_t *pHddStaCtx;
12613
12614 if (NULL == pAdapter)
12615 {
Arif Hussain6d2a3322013-11-17 19:50:10 -080012616 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Adapter is NULL", __func__);
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070012617 return -ENODEV;
12618 }
12619
12620 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
12621
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053012622 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
12623 TRACE_CODE_HDD_CFG80211_UPDATE_FT_IES,
12624 pAdapter->sessionId, pHddStaCtx->conn_info.connState));
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070012625 // Added for debug on reception of Re-assoc Req.
12626 if (eConnectionState_Associated != pHddStaCtx->conn_info.connState)
12627 {
Arif Hussain6d2a3322013-11-17 19:50:10 -080012628 hddLog(LOGE, FL("Called with Ie of length = %zu when not associated"),
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070012629 ftie->ie_len);
Arif Hussain6d2a3322013-11-17 19:50:10 -080012630 hddLog(LOGE, FL("Should be Re-assoc Req IEs"));
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070012631 }
12632
12633#ifdef WLAN_FEATURE_VOWIFI_11R_DEBUG
Arif Hussain6d2a3322013-11-17 19:50:10 -080012634 hddLog(LOGE, FL("%s called with Ie of length = %zu"), __func__,
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070012635 ftie->ie_len);
12636#endif
12637
12638 // Pass the received FT IEs to SME
Gopichand Nakkala356fb102013-03-06 12:34:04 +053012639 sme_SetFTIEs( WLAN_HDD_GET_HAL_CTX(pAdapter), pAdapter->sessionId,
12640 (const u8 *)ftie->ie,
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070012641 ftie->ie_len);
12642 return 0;
12643}
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053012644
12645static int wlan_hdd_cfg80211_update_ft_ies(struct wiphy *wiphy,
12646 struct net_device *dev,
12647 struct cfg80211_update_ft_ies_params *ftie)
12648{
12649 int ret;
12650
12651 vos_ssr_protect(__func__);
12652 ret = __wlan_hdd_cfg80211_update_ft_ies(wiphy, dev, ftie);
12653 vos_ssr_unprotect(__func__);
12654
12655 return ret;
12656}
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070012657#endif
Jeff Johnson04dd8a82012-06-29 20:41:40 -070012658
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053012659#ifdef FEATURE_WLAN_SCAN_PNO
12660
12661void hdd_cfg80211_sched_scan_done_callback(void *callbackContext,
12662 tSirPrefNetworkFoundInd *pPrefNetworkFoundInd)
12663{
12664 int ret;
12665 hdd_adapter_t* pAdapter = (hdd_adapter_t*)callbackContext;
12666 hdd_context_t *pHddCtx;
12667
Nirav Shah80830bf2013-12-31 16:35:12 +053012668 ENTER();
12669
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053012670 if (NULL == pAdapter)
12671 {
Agarwal Ashish971c2882013-10-30 20:11:12 +053012672 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053012673 "%s: HDD adapter is Null", __func__);
12674 return ;
12675 }
12676
12677 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
12678 if (NULL == pHddCtx)
12679 {
12680 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
12681 "%s: HDD context is Null!!!", __func__);
12682 return ;
12683 }
12684
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053012685 spin_lock(&pHddCtx->schedScan_lock);
12686 if (TRUE == pHddCtx->isWiphySuspended)
12687 {
12688 pHddCtx->isSchedScanUpdatePending = TRUE;
12689 spin_unlock(&pHddCtx->schedScan_lock);
12690 hddLog(VOS_TRACE_LEVEL_INFO,
12691 "%s: Update cfg80211 scan database after it resume", __func__);
12692 return ;
12693 }
12694 spin_unlock(&pHddCtx->schedScan_lock);
12695
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053012696 ret = wlan_hdd_cfg80211_update_bss(pHddCtx->wiphy, pAdapter);
12697
12698 if (0 > ret)
12699 hddLog(VOS_TRACE_LEVEL_INFO, "%s: NO SCAN result", __func__);
12700
12701 cfg80211_sched_scan_results(pHddCtx->wiphy);
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053012702 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
12703 "%s: cfg80211 scan result database updated", __func__);
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053012704}
12705
12706/*
Mahesh A Saptasagar0f7b0372013-11-28 23:23:07 +053012707 * FUNCTION: wlan_hdd_is_pno_allowed
Vinay Krishna Erannacbf75f42014-02-26 17:35:20 +053012708 * Disallow pno if any session is active
Mahesh A Saptasagar0f7b0372013-11-28 23:23:07 +053012709 */
12710static eHalStatus wlan_hdd_is_pno_allowed(hdd_adapter_t *pAdapter)
12711{
12712 hdd_adapter_list_node_t *pAdapterNode = NULL, *pNext = NULL;
12713 hdd_adapter_t *pTempAdapter = NULL;
Vinay Krishna Eranna23ffd182013-12-26 19:16:55 +053012714 hdd_station_ctx_t *pStaCtx;
Mahesh A Saptasagar0f7b0372013-11-28 23:23:07 +053012715 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
12716 int status = 0;
12717 status = hdd_get_front_adapter(pHddCtx, &pAdapterNode);
12718
Vinay Krishna Erannacbf75f42014-02-26 17:35:20 +053012719 /* The current firmware design does not allow PNO during any
12720 * active sessions. Hence, determine the active sessions
12721 * and return a failure.
12722 */
Mahesh A Saptasagar0f7b0372013-11-28 23:23:07 +053012723 while ((NULL != pAdapterNode) && (VOS_STATUS_SUCCESS == status))
12724 {
12725 pTempAdapter = pAdapterNode->pAdapter;
Vinay Krishna Eranna23ffd182013-12-26 19:16:55 +053012726 pStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pTempAdapter);
Mahesh A Saptasagar0f7b0372013-11-28 23:23:07 +053012727
Vinay Krishna Eranna23ffd182013-12-26 19:16:55 +053012728 if (((WLAN_HDD_INFRA_STATION == pTempAdapter->device_mode)
12729 && (eConnectionState_NotConnected != pStaCtx->conn_info.connState))
12730 || (WLAN_HDD_P2P_CLIENT == pTempAdapter->device_mode)
12731 || (WLAN_HDD_P2P_GO == pTempAdapter->device_mode)
12732 || (WLAN_HDD_SOFTAP == pTempAdapter->device_mode)
12733 )
Mahesh A Saptasagar0f7b0372013-11-28 23:23:07 +053012734 {
Vinay Krishna Eranna23ffd182013-12-26 19:16:55 +053012735 return eHAL_STATUS_FAILURE;
Mahesh A Saptasagar0f7b0372013-11-28 23:23:07 +053012736 }
12737 status = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
12738 pAdapterNode = pNext;
12739 }
Vinay Krishna Eranna23ffd182013-12-26 19:16:55 +053012740 return eHAL_STATUS_SUCCESS;
Mahesh A Saptasagar0f7b0372013-11-28 23:23:07 +053012741}
12742
Vinay Krishna Erannaf0e523b2014-03-01 21:00:16 +053012743void hdd_cfg80211_sched_scan_start_status_cb(void *callbackContext, VOS_STATUS status)
12744{
12745 hdd_adapter_t *pAdapter = callbackContext;
12746 hdd_context_t *pHddCtx;
12747
12748 if ((NULL == pAdapter) || (WLAN_HDD_ADAPTER_MAGIC != pAdapter->magic))
12749 {
12750 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
12751 FL("Invalid adapter or adapter has invalid magic"));
12752 return;
12753 }
12754
12755 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
12756 if (0 != wlan_hdd_validate_context(pHddCtx))
12757 {
12758 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
12759 FL("HDD context is not valid"));
12760 return;
12761 }
12762
c_hpothub53c45d2014-08-18 16:53:14 +053012763 if (VOS_STATUS_SUCCESS != status)
12764 {
12765 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Vinay Krishna Erannaf0e523b2014-03-01 21:00:16 +053012766 FL("PNO enable response status = %d"), status);
c_hpothub53c45d2014-08-18 16:53:14 +053012767 pHddCtx->isPnoEnable = FALSE;
12768 }
Vinay Krishna Erannaf0e523b2014-03-01 21:00:16 +053012769
12770 pAdapter->pno_req_status = (status == VOS_STATUS_SUCCESS) ? 0 : -EBUSY;
12771 complete(&pAdapter->pno_comp_var);
12772}
12773
Mahesh A Saptasagar0f7b0372013-11-28 23:23:07 +053012774/*
Mahesh A Saptasagar6cc38562014-05-23 21:22:17 +053012775 * FUNCTION: __wlan_hdd_cfg80211_sched_scan_start
12776 * Function to enable PNO
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053012777 */
Mahesh A Saptasagar6cc38562014-05-23 21:22:17 +053012778static int __wlan_hdd_cfg80211_sched_scan_start(struct wiphy *wiphy,
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053012779 struct net_device *dev, struct cfg80211_sched_scan_request *request)
12780{
12781 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
12782 tpSirPNOScanReq pPnoRequest = NULL;
12783 hdd_context_t *pHddCtx;
12784 tHalHandle hHal;
Mahesh A Saptasagar7bd6ad42014-07-21 18:56:33 +053012785 v_U32_t i, indx, num_ch, tempInterval, j;
Sushant Kaushikd62d9782014-02-19 15:39:40 +053012786 u8 valid_ch[WNI_CFG_VALID_CHANNEL_LIST_LEN] = {0};
12787 u8 channels_allowed[WNI_CFG_VALID_CHANNEL_LIST_LEN] = {0};
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053012788 v_U32_t num_channels_allowed = WNI_CFG_VALID_CHANNEL_LIST_LEN;
12789 eHalStatus status = eHAL_STATUS_FAILURE;
Kamath Vinayakba5313f2013-08-22 15:52:39 +053012790 int ret = 0;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053012791
12792 if (NULL == pAdapter)
12793 {
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053012794 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053012795 "%s: HDD adapter is Null", __func__);
12796 return -ENODEV;
12797 }
12798
12799 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053012800 ret = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053012801
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053012802 if (0 != ret)
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053012803 {
Gopichand Nakkalac005b7c2013-05-14 16:04:14 +053012804 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
12805 "%s: HDD context is not valid", __func__);
Kamath Vinayakba5313f2013-08-22 15:52:39 +053012806 return -EINVAL;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053012807 }
12808
12809 hHal = WLAN_HDD_GET_HAL_CTX(pAdapter);
12810 if (NULL == hHal)
12811 {
12812 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
12813 "%s: HAL context is Null!!!", __func__);
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053012814 return -EINVAL;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053012815 }
Sushant Kaushik2fe89932014-09-03 10:58:09 +053012816 sme_ScanFlushResult(hHal, pAdapter->sessionId);
Mahesh A Saptasagar2395ee62014-05-21 19:12:21 +053012817 ret = wlan_hdd_scan_abort(pAdapter);
Girish Gowli4bf7a632014-06-12 13:42:11 +053012818 if (ret < 0)
Mahesh A Saptasagar2395ee62014-05-21 19:12:21 +053012819 {
12820 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
12821 "%s: aborting the existing scan is unsuccessfull", __func__);
12822 return -EBUSY;
12823 }
12824
Vinay Krishna Eranna23ffd182013-12-26 19:16:55 +053012825 if (eHAL_STATUS_SUCCESS != wlan_hdd_is_pno_allowed(pAdapter))
Mahesh A Saptasagar0f7b0372013-11-28 23:23:07 +053012826 {
Vinay Krishna Erannacbf75f42014-02-26 17:35:20 +053012827 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_WARN,
Vinay Krishna Eranna23ffd182013-12-26 19:16:55 +053012828 FL("Cannot handle sched_scan"));
Mahesh A Saptasagar0f7b0372013-11-28 23:23:07 +053012829 return -EBUSY;
12830 }
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053012831
c_hpothu37f21312014-04-09 21:49:54 +053012832 if (TRUE == pHddCtx->isPnoEnable)
12833 {
12834 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_WARN,
12835 FL("already PNO is enabled"));
12836 return -EBUSY;
12837 }
12838 pHddCtx->isPnoEnable = TRUE;
12839
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053012840 pPnoRequest = (tpSirPNOScanReq) vos_mem_malloc(sizeof (tSirPNOScanReq));
12841 if (NULL == pPnoRequest)
12842 {
12843 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
12844 "%s: vos_mem_malloc failed", __func__);
c_hpothu37f21312014-04-09 21:49:54 +053012845 pHddCtx->isPnoEnable = FALSE;
Kamath Vinayakba5313f2013-08-22 15:52:39 +053012846 return -ENOMEM;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053012847 }
12848
Madan Mohan Koyyalamudic3f04352013-09-26 19:21:48 +053012849 memset(pPnoRequest, 0, sizeof (tSirPNOScanReq));
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053012850 pPnoRequest->enable = 1; /*Enable PNO */
12851 pPnoRequest->ucNetworksCount = request->n_match_sets;
12852
12853 if (( !pPnoRequest->ucNetworksCount ) ||
12854 ( pPnoRequest->ucNetworksCount > SIR_PNO_MAX_SUPP_NETWORKS ))
12855 {
12856 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Sushant Kaushik1e406c32014-05-09 15:57:52 +053012857 "%s: Network input is not correct %d Max Network supported is %d",
12858 __func__, pPnoRequest->ucNetworksCount,
12859 SIR_PNO_MAX_SUPP_NETWORKS);
Kamath Vinayakba5313f2013-08-22 15:52:39 +053012860 ret = -EINVAL;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053012861 goto error;
12862 }
12863
12864 if ( SIR_PNO_MAX_NETW_CHANNELS_EX < request->n_channels )
12865 {
12866 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Nirav Shah80830bf2013-12-31 16:35:12 +053012867 "%s: Incorrect number of channels %d",
12868 __func__, request->n_channels);
Kamath Vinayakba5313f2013-08-22 15:52:39 +053012869 ret = -EINVAL;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053012870 goto error;
12871 }
12872
12873 /* Framework provides one set of channels(all)
12874 * common for all saved profile */
12875 if (0 != ccmCfgGetStr(hHal, WNI_CFG_VALID_CHANNEL_LIST,
12876 channels_allowed, &num_channels_allowed))
12877 {
12878 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
12879 "%s: failed to get valid channel list", __func__);
Kamath Vinayakba5313f2013-08-22 15:52:39 +053012880 ret = -EINVAL;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053012881 goto error;
12882 }
12883 /* Checking each channel against allowed channel list */
12884 num_ch = 0;
Nirav Shah80830bf2013-12-31 16:35:12 +053012885 if (request->n_channels)
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053012886 {
Nirav Shah80830bf2013-12-31 16:35:12 +053012887 char chList [(request->n_channels*5)+1];
12888 int len;
12889 for (i = 0, len = 0; i < request->n_channels; i++)
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053012890 {
Nirav Shah80830bf2013-12-31 16:35:12 +053012891 for (indx = 0; indx < num_channels_allowed; indx++)
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053012892 {
Nirav Shah80830bf2013-12-31 16:35:12 +053012893 if (request->channels[i]->hw_value == channels_allowed[indx])
12894 {
12895 valid_ch[num_ch++] = request->channels[i]->hw_value;
12896 len += snprintf(chList+len, 5, "%d ",
12897 request->channels[i]->hw_value);
12898 break ;
12899 }
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053012900 }
12901 }
Nirav Shah80830bf2013-12-31 16:35:12 +053012902 hddLog(VOS_TRACE_LEVEL_INFO,"Channel-List: %s ", chList);
12903 }
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053012904
12905 /* Filling per profile params */
12906 for (i = 0; i < pPnoRequest->ucNetworksCount; i++)
12907 {
12908 pPnoRequest->aNetworks[i].ssId.length =
12909 request->match_sets[i].ssid.ssid_len;
12910
12911 if (( 0 == pPnoRequest->aNetworks[i].ssId.length ) ||
12912 ( pPnoRequest->aNetworks[i].ssId.length > 32 ) )
12913 {
12914 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Nirav Shah80830bf2013-12-31 16:35:12 +053012915 "%s: SSID Len %d is not correct for network %d",
12916 __func__, pPnoRequest->aNetworks[i].ssId.length, i);
Kamath Vinayakba5313f2013-08-22 15:52:39 +053012917 ret = -EINVAL;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053012918 goto error;
12919 }
12920
12921 memcpy(pPnoRequest->aNetworks[i].ssId.ssId,
12922 request->match_sets[i].ssid.ssid,
12923 request->match_sets[i].ssid.ssid_len);
Sushant Kaushik1e406c32014-05-09 15:57:52 +053012924 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
12925 "%s: SSID of network %d is %s ", __func__,
12926 i, pPnoRequest->aNetworks[i].ssId.ssId);
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053012927 pPnoRequest->aNetworks[i].authentication = 0; /*eAUTH_TYPE_ANY*/
12928 pPnoRequest->aNetworks[i].encryption = 0; /*eED_ANY*/
12929 pPnoRequest->aNetworks[i].bcastNetwType = 0; /*eBCAST_UNKNOWN*/
12930
12931 /*Copying list of valid channel into request */
12932 memcpy(pPnoRequest->aNetworks[i].aChannels, valid_ch, num_ch);
12933 pPnoRequest->aNetworks[i].ucChannelCount = num_ch;
12934
12935 pPnoRequest->aNetworks[i].rssiThreshold = 0; //Default value
12936 }
12937
Mahesh A Saptasagar7bd6ad42014-07-21 18:56:33 +053012938 for (i = 0; i < request->n_ssids; i++)
12939 {
12940 j = 0;
12941 while (j < pPnoRequest->ucNetworksCount)
12942 {
12943 if ((pPnoRequest->aNetworks[j].ssId.length ==
12944 request->ssids[i].ssid_len) &&
12945 (0 == memcmp(pPnoRequest->aNetworks[j].ssId.ssId,
12946 request->ssids[i].ssid,
12947 pPnoRequest->aNetworks[j].ssId.length)))
12948 {
12949 pPnoRequest->aNetworks[j].bcastNetwType = eBCAST_HIDDEN;
12950 break;
12951 }
12952 j++;
12953 }
12954 }
12955 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
12956 "Number of hidden networks being Configured = %d",
12957 request->n_ssids);
Madan Mohan Koyyalamudia7765d52013-09-18 16:49:56 +053012958 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Jeff Johnson59a121e2013-11-30 09:46:08 -080012959 "request->ie_len = %zu", request->ie_len);
Madan Mohan Koyyalamudia7765d52013-09-18 16:49:56 +053012960 if ((0 < request->ie_len) && (NULL != request->ie))
12961 {
12962 pPnoRequest->us24GProbeTemplateLen = request->ie_len;
12963 memcpy(&pPnoRequest->p24GProbeTemplate, request->ie,
12964 pPnoRequest->us24GProbeTemplateLen);
12965
12966 pPnoRequest->us5GProbeTemplateLen = request->ie_len;
12967 memcpy(&pPnoRequest->p5GProbeTemplate, request->ie,
12968 pPnoRequest->us5GProbeTemplateLen);
12969 }
12970
Madan Mohan Koyyalamudi1d16f462013-08-27 16:25:34 +053012971 /* Driver gets only one time interval which is hardcoded in
12972 * supplicant for 10000ms. Taking power consumption into account 6 timers
12973 * will be used, Timervalue is increased exponentially i.e 10,20,40,
12974 * 80,160,320 secs. And number of scan cycle for each timer
12975 * is configurable through INI param gPNOScanTimerRepeatValue.
12976 * If it is set to 0 only one timer will be used and PNO scan cycle
12977 * will be repeated after each interval specified by supplicant
12978 * till PNO is disabled.
12979 */
12980 if (0 == pHddCtx->cfg_ini->configPNOScanTimerRepeatValue)
12981 pPnoRequest->scanTimers.ucScanTimersCount = HDD_PNO_SCAN_TIMERS_SET_ONE;
12982 else
12983 pPnoRequest->scanTimers.ucScanTimersCount =
12984 HDD_PNO_SCAN_TIMERS_SET_MULTIPLE;
12985
12986 tempInterval = (request->interval)/1000;
12987 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
12988 "Base scan interval = %d PNOScanTimerRepeatValue = %d",
12989 tempInterval, pHddCtx->cfg_ini->configPNOScanTimerRepeatValue);
12990 for ( i = 0; i < pPnoRequest->scanTimers.ucScanTimersCount; i++)
12991 {
12992 pPnoRequest->scanTimers.aTimerValues[i].uTimerRepeat =
12993 pHddCtx->cfg_ini->configPNOScanTimerRepeatValue;
12994 pPnoRequest->scanTimers.aTimerValues[i].uTimerValue = tempInterval;
12995 tempInterval *= 2;
12996 }
12997 //Repeat last timer until pno disabled.
12998 pPnoRequest->scanTimers.aTimerValues[i-1].uTimerRepeat = 0;
12999
Madan Mohan Koyyalamudid206c7b2013-09-26 22:54:51 +053013000 pPnoRequest->modePNO = SIR_PNO_MODE_IMMEDIATE;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053013001
Vinay Krishna Erannaf0e523b2014-03-01 21:00:16 +053013002 INIT_COMPLETION(pAdapter->pno_comp_var);
13003 pPnoRequest->statusCallback = hdd_cfg80211_sched_scan_start_status_cb;
13004 pPnoRequest->callbackContext = pAdapter;
13005 pAdapter->pno_req_status = 0;
13006
Nirav Shah80830bf2013-12-31 16:35:12 +053013007 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
13008 "SessionId %d, enable %d, modePNO %d, ucScanTimersCount %d",
13009 pAdapter->sessionId, pPnoRequest->enable, pPnoRequest->modePNO,
13010 pPnoRequest->scanTimers.ucScanTimersCount);
13011
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053013012 status = sme_SetPreferredNetworkList(WLAN_HDD_GET_HAL_CTX(pAdapter),
13013 pPnoRequest, pAdapter->sessionId,
13014 hdd_cfg80211_sched_scan_done_callback, pAdapter);
13015 if (eHAL_STATUS_SUCCESS != status)
13016 {
13017 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Nirav Shah80830bf2013-12-31 16:35:12 +053013018 "%s: Failed to enable PNO", __func__);
Kamath Vinayakba5313f2013-08-22 15:52:39 +053013019 ret = -EINVAL;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053013020 goto error;
13021 }
13022
Vinay Krishna Erannaf0e523b2014-03-01 21:00:16 +053013023 ret = wait_for_completion_timeout(
13024 &pAdapter->pno_comp_var,
13025 msecs_to_jiffies(WLAN_WAIT_TIME_PNO));
13026 if (0 >= ret)
13027 {
13028 // Did not receive the response for PNO enable in time.
13029 // Assuming the PNO enable was success.
13030 // Returning error from here, because we timeout, results
13031 // in side effect of Wifi (Wifi Setting) not to work.
13032 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
13033 FL("Timed out waiting for PNO to be Enabled"));
13034 ret = 0;
13035 goto error;
13036 }
13037
c_hpothu3c986b22014-07-09 14:45:09 +053013038 vos_mem_free(pPnoRequest);
Vinay Krishna Erannaf0e523b2014-03-01 21:00:16 +053013039 ret = pAdapter->pno_req_status;
c_hpothu37f21312014-04-09 21:49:54 +053013040 return ret;
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053013041
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053013042error:
Vinay Krishna Erannaf0e523b2014-03-01 21:00:16 +053013043 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
13044 FL("PNO scanRequest offloaded ret = %d"), ret);
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053013045 vos_mem_free(pPnoRequest);
c_hpothu37f21312014-04-09 21:49:54 +053013046 pHddCtx->isPnoEnable = FALSE;
Kamath Vinayakba5313f2013-08-22 15:52:39 +053013047 return ret;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053013048}
13049
13050/*
Mahesh A Saptasagar6cc38562014-05-23 21:22:17 +053013051 * FUNCTION: wlan_hdd_cfg80211_sched_scan_start
13052 * NL interface to enable PNO
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053013053 */
Mahesh A Saptasagar6cc38562014-05-23 21:22:17 +053013054static int wlan_hdd_cfg80211_sched_scan_start(struct wiphy *wiphy,
13055 struct net_device *dev, struct cfg80211_sched_scan_request *request)
13056{
13057 int ret;
13058
13059 vos_ssr_protect(__func__);
13060 ret = __wlan_hdd_cfg80211_sched_scan_start(wiphy, dev, request);
13061 vos_ssr_unprotect(__func__);
13062
13063 return ret;
13064}
13065
13066/*
13067 * FUNCTION: __wlan_hdd_cfg80211_sched_scan_stop
13068 * Function to disable PNO
13069 */
13070static int __wlan_hdd_cfg80211_sched_scan_stop(struct wiphy *wiphy,
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053013071 struct net_device *dev)
13072{
13073 eHalStatus status = eHAL_STATUS_FAILURE;
13074 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
13075 hdd_context_t *pHddCtx;
13076 tHalHandle hHal;
13077 tpSirPNOScanReq pPnoRequest = NULL;
Kamath Vinayakba5313f2013-08-22 15:52:39 +053013078 int ret = 0;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053013079
13080 ENTER();
13081
13082 if (NULL == pAdapter)
13083 {
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053013084 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053013085 "%s: HDD adapter is Null", __func__);
13086 return -ENODEV;
13087 }
13088
13089 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053013090
Kamath Vinayakba5313f2013-08-22 15:52:39 +053013091 if (NULL == pHddCtx)
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053013092 {
Gopichand Nakkalac005b7c2013-05-14 16:04:14 +053013093 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Kamath Vinayakba5313f2013-08-22 15:52:39 +053013094 "%s: HDD context is Null", __func__);
13095 return -ENODEV;
13096 }
13097
13098 /* The return 0 is intentional when isLogpInProgress and
13099 * isLoadUnloadInProgress. We did observe a crash due to a return of
13100 * failure in sched_scan_stop , especially for a case where the unload
13101 * of the happens at the same time. The function __cfg80211_stop_sched_scan
13102 * was clearing rdev->sched_scan_req only when the sched_scan_stop returns
13103 * success. If it returns a failure , then its next invocation due to the
13104 * clean up of the second interface will have the dev pointer corresponding
13105 * to the first one leading to a crash.
13106 */
13107 if (pHddCtx->isLogpInProgress)
13108 {
13109 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
13110 "%s: LOGP in Progress. Ignore!!!", __func__);
13111 return ret;
13112 }
13113
Mihir Shete18156292014-03-11 15:38:30 +053013114 if (WLAN_HDD_IS_LOAD_UNLOAD_IN_PROGRESS(pHddCtx))
Kamath Vinayakba5313f2013-08-22 15:52:39 +053013115 {
13116 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
13117 "%s: Unloading/Loading in Progress. Ignore!!!", __func__);
13118 return ret;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053013119 }
13120
13121 hHal = WLAN_HDD_GET_HAL_CTX(pAdapter);
13122 if (NULL == hHal)
13123 {
13124 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
13125 "%s: HAL context is Null!!!", __func__);
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053013126 return -EINVAL;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053013127 }
13128
13129 pPnoRequest = (tpSirPNOScanReq) vos_mem_malloc(sizeof (tSirPNOScanReq));
13130 if (NULL == pPnoRequest)
13131 {
13132 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
13133 "%s: vos_mem_malloc failed", __func__);
Kamath Vinayakba5313f2013-08-22 15:52:39 +053013134 return -ENOMEM;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053013135 }
13136
13137 memset(pPnoRequest, 0, sizeof (tSirPNOScanReq));
13138 pPnoRequest->enable = 0; /* Disable PNO */
13139 pPnoRequest->ucNetworksCount = 0;
13140
13141 status = sme_SetPreferredNetworkList(hHal, pPnoRequest,
13142 pAdapter->sessionId,
13143 NULL, pAdapter);
13144 if (eHAL_STATUS_SUCCESS != status)
13145 {
13146 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
13147 "Failed to disabled PNO");
Kamath Vinayakba5313f2013-08-22 15:52:39 +053013148 ret = -EINVAL;
Vinay Krishna Erannaf0e523b2014-03-01 21:00:16 +053013149 goto error;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053013150 }
c_hpothu37f21312014-04-09 21:49:54 +053013151 pHddCtx->isPnoEnable = FALSE;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053013152
Vinay Krishna Erannaf0e523b2014-03-01 21:00:16 +053013153error:
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053013154 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Vinay Krishna Erannaf0e523b2014-03-01 21:00:16 +053013155 FL("PNO scan disabled ret = %d"), ret);
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053013156 vos_mem_free(pPnoRequest);
13157
13158 EXIT();
Kamath Vinayakba5313f2013-08-22 15:52:39 +053013159 return ret;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053013160}
13161
Mahesh A Saptasagar6cc38562014-05-23 21:22:17 +053013162/*
13163 * FUNCTION: wlan_hdd_cfg80211_sched_scan_stop
13164 * NL interface to disable PNO
13165 */
13166static int wlan_hdd_cfg80211_sched_scan_stop(struct wiphy *wiphy,
13167 struct net_device *dev)
13168{
13169 int ret;
13170
13171 vos_ssr_protect(__func__);
13172 ret = __wlan_hdd_cfg80211_sched_scan_stop(wiphy, dev);
13173 vos_ssr_unprotect(__func__);
13174
13175 return ret;
13176}
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053013177#endif /*FEATURE_WLAN_SCAN_PNO*/
13178
13179
Mohit Khanna698ba2a2012-12-04 15:08:18 -080013180#ifdef FEATURE_WLAN_TDLS
Sunil Dutt Undekarieacac6f2014-03-21 14:08:53 +053013181#if TDLS_MGMT_VERSION2
Mohit Khanna698ba2a2012-12-04 15:08:18 -080013182static int wlan_hdd_cfg80211_tdls_mgmt(struct wiphy *wiphy, struct net_device *dev,
13183 u8 *peer, u8 action_code, u8 dialog_token,
Sunil Dutt Undekarieacac6f2014-03-21 14:08:53 +053013184 u16 status_code, u32 peer_capability, const u8 *buf, size_t len)
13185#else
13186static int wlan_hdd_cfg80211_tdls_mgmt(struct wiphy *wiphy, struct net_device *dev,
13187 u8 *peer, u8 action_code, u8 dialog_token,
13188 u16 status_code, const u8 *buf, size_t len)
13189#endif
Mohit Khanna698ba2a2012-12-04 15:08:18 -080013190{
13191
13192 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
13193 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
Mohit Khanna698ba2a2012-12-04 15:08:18 -080013194 u8 peerMac[6];
13195 VOS_STATUS status;
Gopichand Nakkala05922802013-03-14 12:23:19 -070013196 int max_sta_failed = 0;
Hoonki Leea34dd892013-02-05 22:56:02 -080013197 int responder;
Hoonki Leed37cbb32013-04-20 00:31:14 -070013198 long rc;
Sunil Dutt Undekarieacac6f2014-03-21 14:08:53 +053013199#if !(TDLS_MGMT_VERSION2)
13200 u32 peer_capability = 0;
13201#endif
Rajesh Chauhana34c6e62014-03-25 16:37:58 +053013202 tANI_U16 numCurrTdlsPeers;
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053013203
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053013204 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
13205 TRACE_CODE_HDD_CFG80211_TDLS_MGMT,
13206 pAdapter->sessionId, action_code));
Hoonki Lee11f7dda2013-02-14 16:55:44 -080013207 if (NULL == pHddCtx || NULL == pHddCtx->cfg_ini)
Mohit Khanna698ba2a2012-12-04 15:08:18 -080013208 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013209 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Mohit Khanna698ba2a2012-12-04 15:08:18 -080013210 "Invalid arguments");
13211 return -EINVAL;
13212 }
13213
Sameer Thalappil75ea31a2013-02-21 19:38:16 -080013214 if (pHddCtx->isLogpInProgress)
13215 {
13216 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
13217 "%s:LOGP in Progress. Ignore!!!", __func__);
Atul Mittal115287b2014-07-08 13:26:33 +053013218 wlan_hdd_tdls_set_link_status(pAdapter,
13219 peer,
13220 eTDLS_LINK_IDLE,
13221 eTDLS_LINK_UNSPECIFIED);
Sameer Thalappil75ea31a2013-02-21 19:38:16 -080013222 return -EBUSY;
13223 }
13224
Hoonki Lee27511902013-03-14 18:19:06 -070013225 if (eTDLS_SUPPORT_NOT_ENABLED == pHddCtx->tdls_mode)
Mohit Khanna698ba2a2012-12-04 15:08:18 -080013226 {
Hoonki Lee27511902013-03-14 18:19:06 -070013227 VOS_TRACE( VOS_MODULE_ID_HDD, TDLS_LOG_LEVEL,
13228 "%s: TDLS mode is disabled OR not enabled in FW."
13229 MAC_ADDRESS_STR " action %d declined.",
13230 __func__, MAC_ADDR_ARRAY(peer), action_code);
Mohit Khanna698ba2a2012-12-04 15:08:18 -080013231 return -ENOTSUPP;
13232 }
Lee Hoonkic1262f22013-01-24 21:59:00 -080013233
Hoonki Lee27511902013-03-14 18:19:06 -070013234 /* other than teardown frame, other mgmt frames are not sent if disabled */
13235 if (SIR_MAC_TDLS_TEARDOWN != action_code)
13236 {
13237 /* if tdls_mode is disabled to respond to peer's request */
13238 if (eTDLS_SUPPORT_DISABLED == pHddCtx->tdls_mode)
13239 {
13240 VOS_TRACE( VOS_MODULE_ID_HDD, TDLS_LOG_LEVEL,
13241 "%s: " MAC_ADDRESS_STR
Gopichand Nakkala34d1b062013-03-19 15:28:33 -070013242 " TDLS mode is disabled. action %d declined.",
13243 __func__, MAC_ADDR_ARRAY(peer), action_code);
Hoonki Lee27511902013-03-14 18:19:06 -070013244
13245 return -ENOTSUPP;
13246 }
Agarwal Ashish4b87f922014-06-18 03:03:21 +053013247
13248 if (vos_max_concurrent_connections_reached())
13249 {
13250 hddLog(VOS_TRACE_LEVEL_INFO, FL("Reached max concurrent connections"));
13251 return -EINVAL;
13252 }
Hoonki Lee27511902013-03-14 18:19:06 -070013253 }
13254
Gopichand Nakkalab977a972013-02-18 19:15:09 -080013255 if (WLAN_IS_TDLS_SETUP_ACTION(action_code))
13256 {
Madan Mohan Koyyalamudi96797442013-10-08 16:04:42 +053013257 if (NULL != wlan_hdd_tdls_is_progress(pHddCtx, peer, TRUE))
Gopichand Nakkalab977a972013-02-18 19:15:09 -080013258 {
13259 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Gopichand Nakkalac87400e2013-03-13 18:51:00 -070013260 "%s: " MAC_ADDRESS_STR
Gopichand Nakkala34d1b062013-03-19 15:28:33 -070013261 " TDLS setup is ongoing. action %d declined.",
13262 __func__, MAC_ADDR_ARRAY(peer), action_code);
13263 return -EPERM;
Gopichand Nakkalab977a972013-02-18 19:15:09 -080013264 }
13265 }
13266
Hoonki Lee11f7dda2013-02-14 16:55:44 -080013267 if (SIR_MAC_TDLS_SETUP_REQ == action_code ||
13268 SIR_MAC_TDLS_SETUP_RSP == action_code )
Lee Hoonkic1262f22013-01-24 21:59:00 -080013269 {
Rajesh Chauhana34c6e62014-03-25 16:37:58 +053013270 numCurrTdlsPeers = wlan_hdd_tdlsConnectedPeers(pAdapter);
13271 if (HDD_MAX_NUM_TDLS_STA <= numCurrTdlsPeers)
Lee Hoonkic1262f22013-01-24 21:59:00 -080013272 {
13273 /* supplicant still sends tdls_mgmt(SETUP_REQ) even after
13274 we return error code at 'add_station()'. Hence we have this
13275 check again in addtion to add_station().
13276 Anyway, there is no hard to double-check. */
Hoonki Lee11f7dda2013-02-14 16:55:44 -080013277 if (SIR_MAC_TDLS_SETUP_REQ == action_code)
Lee Hoonkic1262f22013-01-24 21:59:00 -080013278 {
Gopichand Nakkalac87400e2013-03-13 18:51:00 -070013279 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
13280 "%s: " MAC_ADDRESS_STR
Rajesh Chauhana34c6e62014-03-25 16:37:58 +053013281 " TDLS Max peer already connected. action (%d) declined. Num of peers (%d), Max allowed (%d).",
13282 __func__, MAC_ADDR_ARRAY(peer), action_code,
13283 numCurrTdlsPeers, HDD_MAX_NUM_TDLS_STA);
Sunil Dutt388ac8f2013-11-28 18:06:52 +053013284 return -EINVAL;
Lee Hoonkic1262f22013-01-24 21:59:00 -080013285 }
13286 else
13287 {
Gopichand Nakkalab977a972013-02-18 19:15:09 -080013288 /* maximum reached. tweak to send error code to peer and return
13289 error code to supplicant */
Lee Hoonkic1262f22013-01-24 21:59:00 -080013290 status_code = eSIR_MAC_UNSPEC_FAILURE_STATUS;
Gopichand Nakkalac87400e2013-03-13 18:51:00 -070013291 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
13292 "%s: " MAC_ADDRESS_STR
Rajesh Chauhana34c6e62014-03-25 16:37:58 +053013293 " TDLS Max peer already connected, send response status (%d). Num of peers (%d), Max allowed (%d).",
13294 __func__, MAC_ADDR_ARRAY(peer), status_code,
13295 numCurrTdlsPeers, HDD_MAX_NUM_TDLS_STA);
Gopichand Nakkala05922802013-03-14 12:23:19 -070013296 max_sta_failed = -EPERM;
Gopichand Nakkalab977a972013-02-18 19:15:09 -080013297 /* fall through to send setup resp with failure status
13298 code */
Lee Hoonkic1262f22013-01-24 21:59:00 -080013299 }
13300 }
Hoonki Lee11f7dda2013-02-14 16:55:44 -080013301 else
13302 {
13303 hddTdlsPeer_t *pTdlsPeer;
Madan Mohan Koyyalamudi96797442013-10-08 16:04:42 +053013304 pTdlsPeer = wlan_hdd_tdls_find_peer(pAdapter, peer, TRUE);
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -070013305 if (pTdlsPeer && TDLS_IS_CONNECTED(pTdlsPeer))
Hoonki Lee11f7dda2013-02-14 16:55:44 -080013306 {
Gopichand Nakkalac87400e2013-03-13 18:51:00 -070013307 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Gopichand Nakkala34d1b062013-03-19 15:28:33 -070013308 "%s:" MAC_ADDRESS_STR " already connected. action %d declined.",
13309 __func__, MAC_ADDR_ARRAY(peer), action_code);
Hoonki Lee11f7dda2013-02-14 16:55:44 -080013310 return -EPERM;
13311 }
13312 }
Lee Hoonkic1262f22013-01-24 21:59:00 -080013313 }
Hoonki Lee11f7dda2013-02-14 16:55:44 -080013314 vos_mem_copy(peerMac, peer, 6);
Mohit Khanna698ba2a2012-12-04 15:08:18 -080013315
Hoonki Lee1090c6a2013-01-16 17:40:54 -080013316#ifdef WLAN_FEATURE_TDLS_DEBUG
13317 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Arun Kumar Khandavalli9fb625e2014-03-17 16:07:40 +053013318 "%s: " MAC_ADDRESS_STR " action %d, dialog_token %d status %d, len = %zu",
Gopichand Nakkalac87400e2013-03-13 18:51:00 -070013319 "tdls_mgmt", MAC_ADDR_ARRAY(peer),
13320 action_code, dialog_token, status_code, len);
Hoonki Lee1090c6a2013-01-16 17:40:54 -080013321#endif
Mohit Khanna698ba2a2012-12-04 15:08:18 -080013322
Hoonki Leea34dd892013-02-05 22:56:02 -080013323 /*Except teardown responder will not be used so just make 0*/
13324 responder = 0;
Hoonki Lee11f7dda2013-02-14 16:55:44 -080013325 if (SIR_MAC_TDLS_TEARDOWN == action_code)
Hoonki Leea34dd892013-02-05 22:56:02 -080013326 {
Gopichand Nakkala97a65fd2013-04-16 16:59:38 -070013327
13328 hddTdlsPeer_t *pTdlsPeer;
Madan Mohan Koyyalamudi96797442013-10-08 16:04:42 +053013329 pTdlsPeer = wlan_hdd_tdls_find_peer(pAdapter, peerMac, TRUE);
Gopichand Nakkala97a65fd2013-04-16 16:59:38 -070013330
13331 if(pTdlsPeer && TDLS_IS_CONNECTED(pTdlsPeer))
13332 responder = pTdlsPeer->is_responder;
13333 else
Hoonki Leea34dd892013-02-05 22:56:02 -080013334 {
Gopichand Nakkala97a65fd2013-04-16 16:59:38 -070013335 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Arun Kumar Khandavalli9fb625e2014-03-17 16:07:40 +053013336 "%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 -070013337 __func__, MAC_ADDR_ARRAY(peer), (NULL == pTdlsPeer) ? -1 : pTdlsPeer->link_status,
13338 dialog_token, status_code, len);
13339 return -EPERM;
Hoonki Leea34dd892013-02-05 22:56:02 -080013340 }
Mohit Khanna698ba2a2012-12-04 15:08:18 -080013341 }
Mohit Khanna698ba2a2012-12-04 15:08:18 -080013342
Gopichand Nakkala2f1ff152013-07-01 11:27:43 +053013343 /* For explicit trigger of DIS_REQ come out of BMPS for
13344 successfully receiving DIS_RSP from peer. */
Hoonki Lee14621352013-04-16 17:51:19 -070013345 if ((SIR_MAC_TDLS_SETUP_RSP == action_code) ||
Gopichand Nakkala2f1ff152013-07-01 11:27:43 +053013346 (SIR_MAC_TDLS_DIS_RSP == action_code) ||
13347 (SIR_MAC_TDLS_DIS_REQ == action_code))
Hoonki Lee14621352013-04-16 17:51:19 -070013348 {
13349 if (TRUE == sme_IsPmcBmps(WLAN_HDD_GET_HAL_CTX(pAdapter)))
13350 {
13351 VOS_TRACE( VOS_MODULE_ID_HDD, TDLS_LOG_LEVEL,
Gopichand Nakkala2f1ff152013-07-01 11:27:43 +053013352 "%s: Sending frame action_code %u.Disable BMPS", __func__, action_code);
Hoonki Lee14621352013-04-16 17:51:19 -070013353 hdd_disable_bmps_imps(pHddCtx, WLAN_HDD_INFRA_STATION);
13354 }
Gopichand Nakkala2f1ff152013-07-01 11:27:43 +053013355 if (SIR_MAC_TDLS_DIS_REQ != action_code)
13356 wlan_hdd_tdls_set_cap(pAdapter, peerMac, eTDLS_CAP_SUPPORTED);
Hoonki Lee14621352013-04-16 17:51:19 -070013357 }
13358
Hoonki Lee5305c3a2013-04-29 23:28:59 -070013359 /* make sure doesn't call send_mgmt() while it is pending */
13360 if (TDLS_CTX_MAGIC == pAdapter->mgmtTxCompletionStatus)
13361 {
13362 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Arif Hussain6d2a3322013-11-17 19:50:10 -080013363 "%s: " MAC_ADDRESS_STR " action %d couldn't sent, as one is pending. return EBUSY",
Hoonki Lee5305c3a2013-04-29 23:28:59 -070013364 __func__, MAC_ADDR_ARRAY(peer), action_code);
13365 return -EBUSY;
13366 }
13367
13368 pAdapter->mgmtTxCompletionStatus = TDLS_CTX_MAGIC;
Gopichand Nakkalab977a972013-02-18 19:15:09 -080013369 INIT_COMPLETION(pAdapter->tdls_mgmt_comp);
13370
Mohit Khanna698ba2a2012-12-04 15:08:18 -080013371 status = sme_SendTdlsMgmtFrame(WLAN_HDD_GET_HAL_CTX(pAdapter), pAdapter->sessionId,
Pradeep Reddy POTTETIca171f82014-03-21 14:17:35 +053013372 peerMac, action_code, dialog_token, status_code, peer_capability, (tANI_U8 *)buf, len, responder);
Mohit Khanna698ba2a2012-12-04 15:08:18 -080013373
Gopichand Nakkalab977a972013-02-18 19:15:09 -080013374 if (VOS_STATUS_SUCCESS != status)
13375 {
Mohit Khanna698ba2a2012-12-04 15:08:18 -080013376 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
13377 "%s: sme_SendTdlsMgmtFrame failed!", __func__);
Hoonki Lee5305c3a2013-04-29 23:28:59 -070013378 pAdapter->mgmtTxCompletionStatus = FALSE;
Hoonki Lee14621352013-04-16 17:51:19 -070013379 wlan_hdd_tdls_check_bmps(pAdapter);
Sunil Dutt388ac8f2013-11-28 18:06:52 +053013380 return -EINVAL;
Mohit Khanna698ba2a2012-12-04 15:08:18 -080013381 }
13382
Hoonki Leed37cbb32013-04-20 00:31:14 -070013383 rc = wait_for_completion_interruptible_timeout(&pAdapter->tdls_mgmt_comp,
13384 msecs_to_jiffies(WAIT_TIME_TDLS_MGMT));
13385
13386 if ((rc <= 0) || (TRUE != pAdapter->mgmtTxCompletionStatus))
Gopichand Nakkalab977a972013-02-18 19:15:09 -080013387 {
Hoonki Leed37cbb32013-04-20 00:31:14 -070013388 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Jeff Johnson0299d0a2013-10-30 12:37:43 -070013389 "%s: Mgmt Tx Completion failed status %ld TxCompletion %u",
Hoonki Leed37cbb32013-04-20 00:31:14 -070013390 __func__, rc, pAdapter->mgmtTxCompletionStatus);
Hoonki Lee5305c3a2013-04-29 23:28:59 -070013391 pAdapter->mgmtTxCompletionStatus = FALSE;
Yue Ma4f55ef32014-01-23 16:45:33 -080013392
13393 if (pHddCtx->isLogpInProgress)
13394 {
13395 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
13396 "%s: LOGP in Progress. Ignore!!!", __func__);
13397 return -EAGAIN;
13398 }
13399
Hoonki Leed37cbb32013-04-20 00:31:14 -070013400 wlan_hdd_tdls_check_bmps(pAdapter);
Sunil Dutt388ac8f2013-11-28 18:06:52 +053013401 return -EINVAL;
Gopichand Nakkalab977a972013-02-18 19:15:09 -080013402 }
13403
Gopichand Nakkala05922802013-03-14 12:23:19 -070013404 if (max_sta_failed)
Hoonki Lee14621352013-04-16 17:51:19 -070013405 {
13406 wlan_hdd_tdls_check_bmps(pAdapter);
Gopichand Nakkala05922802013-03-14 12:23:19 -070013407 return max_sta_failed;
Hoonki Lee14621352013-04-16 17:51:19 -070013408 }
Gopichand Nakkalab977a972013-02-18 19:15:09 -080013409
Hoonki Leea34dd892013-02-05 22:56:02 -080013410 if (SIR_MAC_TDLS_SETUP_RSP == action_code)
13411 {
Gopichand Nakkala4327a152013-03-04 23:22:42 -080013412 wlan_hdd_tdls_set_responder(pAdapter, peerMac, TRUE);
Hoonki Leea34dd892013-02-05 22:56:02 -080013413 }
13414 else if (SIR_MAC_TDLS_SETUP_CNF == action_code)
13415 {
Gopichand Nakkala4327a152013-03-04 23:22:42 -080013416 wlan_hdd_tdls_set_responder(pAdapter, peerMac, FALSE);
Hoonki Leea34dd892013-02-05 22:56:02 -080013417 }
Mohit Khanna698ba2a2012-12-04 15:08:18 -080013418
13419 return 0;
13420}
13421
Atul Mittal115287b2014-07-08 13:26:33 +053013422
13423int wlan_hdd_tdls_extctrl_config_peer(hdd_adapter_t *pAdapter,
13424 u8 *peer,
13425 cfg80211_exttdls_callback callback)
13426{
13427
13428 hddTdlsPeer_t *pTdlsPeer;
13429 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
13430 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
13431 " %s : NL80211_TDLS_SETUP for " MAC_ADDRESS_STR,
13432 __func__, MAC_ADDR_ARRAY(peer));
13433
13434 if ( (FALSE == pHddCtx->cfg_ini->fTDLSExternalControl) ||
13435 (FALSE == pHddCtx->cfg_ini->fEnableTDLSImplicitTrigger) ) {
13436
13437 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
13438 " %s TDLS External control and Implicit Trigger not enabled ",
13439 __func__);
13440 return -ENOTSUPP;
13441 }
13442
13443 /* To cater the requirement of establishing the TDLS link
13444 * irrespective of the data traffic , get an entry of TDLS peer.
13445 */
13446 pTdlsPeer = wlan_hdd_tdls_get_peer(pAdapter, peer);
13447 if (pTdlsPeer == NULL) {
13448 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
13449 "%s: peer " MAC_ADDRESS_STR " not existing",
13450 __func__, MAC_ADDR_ARRAY(peer));
13451 return -EINVAL;
13452 }
13453
13454 if ( 0 != wlan_hdd_tdls_set_force_peer(pAdapter, peer, TRUE) ) {
13455
13456 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
13457 " %s TDLS Add Force Peer Failed",
13458 __func__);
13459 return -EINVAL;
13460 }
13461 /*EXT TDLS*/
13462
13463 if ( 0 != wlan_hdd_set_callback(pTdlsPeer, callback) ) {
13464 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
13465 " %s TDLS set callback Failed",
13466 __func__);
13467 return -EINVAL;
13468 }
13469
13470 return(0);
13471
13472}
13473
13474int wlan_hdd_tdls_extctrl_deconfig_peer(hdd_adapter_t *pAdapter, u8 *peer)
13475{
13476
13477 hddTdlsPeer_t *pTdlsPeer;
13478 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
13479 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
13480 " %s : NL80211_TDLS_TEARDOWN for " MAC_ADDRESS_STR,
13481 __func__, MAC_ADDR_ARRAY(peer));
13482
13483 if ( (FALSE == pHddCtx->cfg_ini->fTDLSExternalControl) ||
13484 (FALSE == pHddCtx->cfg_ini->fEnableTDLSImplicitTrigger) ) {
13485
13486 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
13487 " %s TDLS External control and Implicit Trigger not enabled ",
13488 __func__);
13489 return -ENOTSUPP;
13490 }
13491
13492
13493 pTdlsPeer = wlan_hdd_tdls_find_peer(pAdapter, peer, TRUE);
13494
13495 if ( NULL == pTdlsPeer ) {
13496 hddLog(VOS_TRACE_LEVEL_INFO, "%s: " MAC_ADDRESS_STR
13497 " peer not exsting",
13498 __func__, MAC_ADDR_ARRAY(peer));
13499 return -EINVAL;
13500 }
13501 else {
13502 wlan_hdd_tdls_indicate_teardown(pAdapter, pTdlsPeer,
13503 eSIR_MAC_TDLS_TEARDOWN_UNSPEC_REASON);
13504 }
13505
13506 if ( 0 != wlan_hdd_tdls_set_force_peer(pAdapter, peer, FALSE) )
13507 return -EINVAL;
13508
13509 /*EXT TDLS*/
13510
13511 if ( 0 != wlan_hdd_set_callback(pTdlsPeer, NULL )) {
13512
13513 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
13514 " %s TDLS set callback Failed",
13515 __func__);
13516 return -EINVAL;
13517 }
13518 return(0);
13519
13520}
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053013521static int __wlan_hdd_cfg80211_tdls_oper(struct wiphy *wiphy, struct net_device *dev,
Mohit Khanna698ba2a2012-12-04 15:08:18 -080013522 u8 *peer, enum nl80211_tdls_operation oper)
13523{
13524 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
13525 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053013526 int status;
Hoonki Lee5305c3a2013-04-29 23:28:59 -070013527 hddTdlsPeer_t *pTdlsPeer;
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053013528
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053013529 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
13530 TRACE_CODE_HDD_CFG80211_TDLS_OPER,
13531 pAdapter->sessionId, oper));
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053013532 if ( NULL == peer )
Mohit Khanna698ba2a2012-12-04 15:08:18 -080013533 {
Gopichand Nakkalab977a972013-02-18 19:15:09 -080013534 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Chilam Ngc4244af2013-04-01 15:37:32 -070013535 "%s: Invalid arguments", __func__);
Mohit Khanna698ba2a2012-12-04 15:08:18 -080013536 return -EINVAL;
13537 }
Hoonki Lee1090c6a2013-01-16 17:40:54 -080013538
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053013539 status = wlan_hdd_validate_context(pHddCtx);
13540
13541 if (0 != status)
Sameer Thalappil75ea31a2013-02-21 19:38:16 -080013542 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053013543 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
13544 "%s: HDD context is not valid", __func__);
13545 return status;
Sameer Thalappil75ea31a2013-02-21 19:38:16 -080013546 }
13547
Mohit Khanna698ba2a2012-12-04 15:08:18 -080013548
13549 if( FALSE == pHddCtx->cfg_ini->fEnableTDLSSupport ||
Hoonki Lee1090c6a2013-01-16 17:40:54 -080013550 FALSE == sme_IsFeatureSupportedByFW(TDLS))
Mohit Khanna698ba2a2012-12-04 15:08:18 -080013551 {
Hoonki Lee1090c6a2013-01-16 17:40:54 -080013552 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Chilam Ngc4244af2013-04-01 15:37:32 -070013553 "TDLS Disabled in INI OR not enabled in FW. "
13554 "Cannot process TDLS commands");
Mohit Khanna698ba2a2012-12-04 15:08:18 -080013555 return -ENOTSUPP;
13556 }
13557
13558 switch (oper) {
13559 case NL80211_TDLS_ENABLE_LINK:
13560 {
Mohit Khanna698ba2a2012-12-04 15:08:18 -080013561 VOS_STATUS status;
c_hpothu6ff1c3c2013-10-01 19:01:57 +053013562 long ret;
Gopichand Nakkala79ff85d2013-05-27 17:05:29 +053013563 tCsrTdlsLinkEstablishParams tdlsLinkEstablishParams;
Mohit Khanna698ba2a2012-12-04 15:08:18 -080013564
Sunil Dutt41de4e22013-11-14 18:09:02 +053013565 pTdlsPeer = wlan_hdd_tdls_find_peer(pAdapter, peer, TRUE);
13566
13567 if ( NULL == pTdlsPeer ) {
13568 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: " MAC_ADDRESS_STR
13569 " (oper %d) not exsting. ignored",
13570 __func__, MAC_ADDR_ARRAY(peer), (int)oper);
13571 return -EINVAL;
13572 }
13573
13574 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
13575 "%s: " MAC_ADDRESS_STR " link_status %d (%s) ", "tdls_oper",
13576 MAC_ADDR_ARRAY(peer), pTdlsPeer->link_status,
13577 "NL80211_TDLS_ENABLE_LINK");
13578
Gopichand Nakkala2f4a2822013-04-17 11:22:01 -070013579 if (!TDLS_STA_INDEX_VALID(pTdlsPeer->staId))
13580 {
13581 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Invalid Staion Index %u "
13582 MAC_ADDRESS_STR " failed",
13583 __func__, pTdlsPeer->staId, MAC_ADDR_ARRAY(peer));
13584 return -EINVAL;
13585 }
13586
Hoonki Lee5305c3a2013-04-29 23:28:59 -070013587 if (eTDLS_LINK_CONNECTED != pTdlsPeer->link_status)
Gopichand Nakkalac87400e2013-03-13 18:51:00 -070013588 {
Madan Mohan Koyyalamudice419872013-09-13 19:36:52 +053013589 if (IS_ADVANCE_TDLS_ENABLE) {
Gopichand Nakkala24be5312013-07-02 16:47:12 +053013590
Madan Mohan Koyyalamudice419872013-09-13 19:36:52 +053013591 if (0 != wlan_hdd_tdls_get_link_establish_params(
13592 pAdapter, peer,&tdlsLinkEstablishParams)) {
13593 return -EINVAL;
13594 }
13595 INIT_COMPLETION(pAdapter->tdls_link_establish_req_comp);
Gopichand Nakkala79ff85d2013-05-27 17:05:29 +053013596
Madan Mohan Koyyalamudice419872013-09-13 19:36:52 +053013597 sme_SendTdlsLinkEstablishParams(WLAN_HDD_GET_HAL_CTX(pAdapter),
13598 pAdapter->sessionId, peer, &tdlsLinkEstablishParams);
13599 /* Send TDLS peer UAPSD capabilities to the firmware and
13600 * register with the TL on after the response for this operation
13601 * is received .
13602 */
13603 ret = wait_for_completion_interruptible_timeout(
13604 &pAdapter->tdls_link_establish_req_comp,
13605 msecs_to_jiffies(WAIT_TIME_TDLS_LINK_ESTABLISH_REQ));
13606 if (ret <= 0)
13607 {
13608 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
13609 "%s: Link Establish Request Faled Status %ld",
13610 __func__, ret);
13611 return -EINVAL;
13612 }
Gopichand Nakkala79ff85d2013-05-27 17:05:29 +053013613 }
Atul Mittal115287b2014-07-08 13:26:33 +053013614 wlan_hdd_tdls_set_peer_link_status(pTdlsPeer,
13615 eTDLS_LINK_CONNECTED,
13616 eTDLS_LINK_SUCCESS);
Gopichand Nakkala471708b2013-06-04 20:03:01 +053013617 /* Mark TDLS client Authenticated .*/
13618 status = WLANTL_ChangeSTAState( pHddCtx->pvosContext,
13619 pTdlsPeer->staId,
13620 WLANTL_STA_AUTHENTICATED);
Gopichand Nakkalaccd3a382013-03-19 13:56:10 -070013621 if (VOS_STATUS_SUCCESS == status)
13622 {
Hoonki Lee14621352013-04-16 17:51:19 -070013623 if (pTdlsPeer->is_responder == 0)
13624 {
13625 v_U8_t staId = (v_U8_t)pTdlsPeer->staId;
13626
13627 wlan_hdd_tdls_timer_restart(pAdapter,
13628 &pTdlsPeer->initiatorWaitTimeoutTimer,
13629 WAIT_TIME_TDLS_INITIATOR);
13630 /* suspend initiator TX until it receives direct packet from the
13631 reponder or WAIT_TIME_TDLS_INITIATOR timer expires */
13632 WLANTL_SuspendDataTx( (WLAN_HDD_GET_CTX(pAdapter))->pvosContext,
13633 &staId, NULL);
13634 }
Gopichand Nakkalaccd3a382013-03-19 13:56:10 -070013635 wlan_hdd_tdls_increment_peer_count(pAdapter);
13636 }
Gopichand Nakkalac87400e2013-03-13 18:51:00 -070013637 wlan_hdd_tdls_check_bmps(pAdapter);
Gopichand Nakkala79ff85d2013-05-27 17:05:29 +053013638
13639 /* Update TL about the UAPSD masks , to route the packets to firmware */
Gopichand Nakkala574f6d12013-06-27 19:38:43 +053013640 if ((TRUE == pHddCtx->cfg_ini->fEnableTDLSBufferSta)
13641 || pHddCtx->cfg_ini->fTDLSUapsdMask )
Gopichand Nakkala79ff85d2013-05-27 17:05:29 +053013642 {
Gopichand Nakkala574f6d12013-06-27 19:38:43 +053013643 int ac;
13644 uint8 ucAc[4] = { WLANTL_AC_VO,
13645 WLANTL_AC_VI,
13646 WLANTL_AC_BK,
13647 WLANTL_AC_BE };
13648 uint8 tlTid[4] = { 7, 5, 2, 3 } ;
13649 for(ac=0; ac < 4; ac++)
13650 {
13651 status = WLANTL_EnableUAPSDForAC( (WLAN_HDD_GET_CTX(pAdapter))->pvosContext,
13652 pTdlsPeer->staId, ucAc[ac],
13653 tlTid[ac], tlTid[ac], 0, 0,
13654 WLANTL_BI_DIR );
13655 }
Gopichand Nakkala79ff85d2013-05-27 17:05:29 +053013656 }
Gopichand Nakkalac87400e2013-03-13 18:51:00 -070013657 }
13658
Mohit Khanna698ba2a2012-12-04 15:08:18 -080013659 }
13660 break;
13661 case NL80211_TDLS_DISABLE_LINK:
Lee Hoonkic1262f22013-01-24 21:59:00 -080013662 {
Sunil Dutt41de4e22013-11-14 18:09:02 +053013663 pTdlsPeer = wlan_hdd_tdls_find_peer(pAdapter, peer, TRUE);
13664
13665 if ( NULL == pTdlsPeer ) {
13666 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: " MAC_ADDRESS_STR
13667 " (oper %d) not exsting. ignored",
13668 __func__, MAC_ADDR_ARRAY(peer), (int)oper);
13669 return -EINVAL;
13670 }
13671
13672 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
13673 "%s: " MAC_ADDRESS_STR " link_status %d (%s) ", "tdls_oper",
13674 MAC_ADDR_ARRAY(peer), pTdlsPeer->link_status,
13675 "NL80211_TDLS_DISABLE_LINK");
13676
Hoonki Lee5305c3a2013-04-29 23:28:59 -070013677 if(TDLS_STA_INDEX_VALID(pTdlsPeer->staId))
Lee Hoonkic1262f22013-01-24 21:59:00 -080013678 {
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -070013679 long status;
13680
Atul Mittal271a7652014-09-12 13:18:22 +053013681
13682 wlan_hdd_tdls_set_peer_link_status(pTdlsPeer,
13683 eTDLS_LINK_TEARING,
13684 (pTdlsPeer->link_status == eTDLS_LINK_TEARING)?
13685 eTDLS_LINK_UNSPECIFIED:
13686 eTDLS_LINK_DROPPED_BY_REMOTE);
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -070013687 INIT_COMPLETION(pAdapter->tdls_del_station_comp);
13688
Lee Hoonkic1262f22013-01-24 21:59:00 -080013689 sme_DeleteTdlsPeerSta( WLAN_HDD_GET_HAL_CTX(pAdapter),
13690 pAdapter->sessionId, peer );
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -070013691
13692 status = wait_for_completion_interruptible_timeout(&pAdapter->tdls_del_station_comp,
13693 msecs_to_jiffies(WAIT_TIME_TDLS_DEL_STA));
Atul Mittal271a7652014-09-12 13:18:22 +053013694 wlan_hdd_tdls_set_peer_link_status(pTdlsPeer,
13695 eTDLS_LINK_IDLE,
13696 (pTdlsPeer->link_status == eTDLS_LINK_TEARING)?
13697 eTDLS_LINK_UNSPECIFIED:
13698 eTDLS_LINK_DROPPED_BY_REMOTE);
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -070013699 if (status <= 0)
13700 {
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -070013701 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
13702 "%s: Del station failed status %ld",
13703 __func__, status);
13704 return -EPERM;
13705 }
Lee Hoonkic1262f22013-01-24 21:59:00 -080013706 }
13707 else
13708 {
Gopichand Nakkalac87400e2013-03-13 18:51:00 -070013709 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
13710 "%s: TDLS Peer Station doesn't exist.", __func__);
Lee Hoonkic1262f22013-01-24 21:59:00 -080013711 }
Lee Hoonkic1262f22013-01-24 21:59:00 -080013712 }
Gopichand Nakkalac87400e2013-03-13 18:51:00 -070013713 break;
Mohit Khanna698ba2a2012-12-04 15:08:18 -080013714 case NL80211_TDLS_TEARDOWN:
Sunil Dutt41de4e22013-11-14 18:09:02 +053013715 {
Atul Mittal115287b2014-07-08 13:26:33 +053013716 status = wlan_hdd_tdls_extctrl_deconfig_peer(pAdapter, peer);
Sunil Dutt41de4e22013-11-14 18:09:02 +053013717
Atul Mittal115287b2014-07-08 13:26:33 +053013718 if (0 != status)
13719 {
13720 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
13721 "%s: Error in TDLS Teardown", __func__);
13722 return status;
Sunil Dutt41de4e22013-11-14 18:09:02 +053013723 }
Sunil Dutt41de4e22013-11-14 18:09:02 +053013724 break;
13725 }
Mohit Khanna698ba2a2012-12-04 15:08:18 -080013726 case NL80211_TDLS_SETUP:
Sunil Dutt41de4e22013-11-14 18:09:02 +053013727 {
Atul Mittal115287b2014-07-08 13:26:33 +053013728 status = wlan_hdd_tdls_extctrl_config_peer(pAdapter,
13729 peer,
13730 NULL);
Sunil Dutt41de4e22013-11-14 18:09:02 +053013731
Atul Mittal115287b2014-07-08 13:26:33 +053013732 if (0 != status)
13733 {
13734 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
13735 "%s: Error in TDLS Setup", __func__);
13736 return status;
Naresh Jayaram937abdf2013-11-26 19:50:25 +053013737 }
Naresh Jayaramdb4514b2013-11-25 18:08:10 +053013738 break;
Sunil Dutt41de4e22013-11-14 18:09:02 +053013739 }
Mohit Khanna698ba2a2012-12-04 15:08:18 -080013740 case NL80211_TDLS_DISCOVERY_REQ:
13741 /* We don't support in-driver setup/teardown/discovery */
c_hpothu6ff1c3c2013-10-01 19:01:57 +053013742 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_WARN,
13743 "%s: We don't support in-driver setup/teardown/discovery "
13744 ,__func__);
Mohit Khanna698ba2a2012-12-04 15:08:18 -080013745 return -ENOTSUPP;
13746 default:
c_hpothu6ff1c3c2013-10-01 19:01:57 +053013747 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
13748 "%s: unsupported event",__func__);
Mohit Khanna698ba2a2012-12-04 15:08:18 -080013749 return -ENOTSUPP;
13750 }
13751 return 0;
13752}
Chilam NG571c65a2013-01-19 12:27:36 +053013753
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053013754static int wlan_hdd_cfg80211_tdls_oper(struct wiphy *wiphy, struct net_device *dev,
13755 u8 *peer, enum nl80211_tdls_operation oper)
13756{
13757 int ret;
13758
13759 vos_ssr_protect(__func__);
13760 ret = __wlan_hdd_cfg80211_tdls_oper(wiphy, dev, peer, oper);
13761 vos_ssr_unprotect(__func__);
13762
13763 return ret;
13764}
13765
Chilam NG571c65a2013-01-19 12:27:36 +053013766int wlan_hdd_cfg80211_send_tdls_discover_req(struct wiphy *wiphy,
13767 struct net_device *dev, u8 *peer)
13768{
Arif Hussaina7c8e412013-11-20 11:06:42 -080013769 hddLog(VOS_TRACE_LEVEL_INFO,
13770 "tdls send discover req: "MAC_ADDRESS_STR,
13771 MAC_ADDR_ARRAY(peer));
Chilam NG571c65a2013-01-19 12:27:36 +053013772
Sunil Dutt Undekarieacac6f2014-03-21 14:08:53 +053013773#if TDLS_MGMT_VERSION2
13774 return wlan_hdd_cfg80211_tdls_mgmt(wiphy, dev, peer,
13775 WLAN_TDLS_DISCOVERY_REQUEST, 1, 0, 0, NULL, 0);
13776#else
Chilam NG571c65a2013-01-19 12:27:36 +053013777 return wlan_hdd_cfg80211_tdls_mgmt(wiphy, dev, peer,
13778 WLAN_TDLS_DISCOVERY_REQUEST, 1, 0, NULL, 0);
Sunil Dutt Undekarieacac6f2014-03-21 14:08:53 +053013779#endif
Chilam NG571c65a2013-01-19 12:27:36 +053013780}
Mohit Khanna698ba2a2012-12-04 15:08:18 -080013781#endif
13782
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053013783#ifdef WLAN_FEATURE_GTK_OFFLOAD
13784/*
13785 * FUNCTION: wlan_hdd_cfg80211_update_replayCounterCallback
13786 * Callback rountine called upon receiving response for
13787 * get offload info
13788 */
13789void wlan_hdd_cfg80211_update_replayCounterCallback(void *callbackContext,
13790 tpSirGtkOffloadGetInfoRspParams pGtkOffloadGetInfoRsp)
13791{
13792
13793 hdd_adapter_t *pAdapter = (hdd_adapter_t *)callbackContext;
Gopichand Nakkalad36ee622013-05-07 14:13:27 +053013794 tANI_U8 tempReplayCounter[8];
13795 hdd_station_ctx_t *pHddStaCtx;
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053013796
13797 ENTER();
13798
13799 if (NULL == pAdapter)
13800 {
Agarwal Ashish971c2882013-10-30 20:11:12 +053013801 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053013802 "%s: HDD adapter is Null", __func__);
13803 return ;
13804 }
13805
13806 if (NULL == pGtkOffloadGetInfoRsp)
13807 {
13808 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
13809 "%s: pGtkOffloadGetInfoRsp is Null", __func__);
13810 return ;
13811 }
13812
13813 if (VOS_STATUS_SUCCESS != pGtkOffloadGetInfoRsp->ulStatus)
13814 {
13815 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
13816 "%s: wlan Failed to get replay counter value",
13817 __func__);
13818 return ;
13819 }
13820
Gopichand Nakkalad36ee622013-05-07 14:13:27 +053013821 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
13822 /* Update replay counter */
13823 pHddStaCtx->gtkOffloadReqParams.ullKeyReplayCounter =
13824 pGtkOffloadGetInfoRsp->ullKeyReplayCounter;
13825
13826 {
13827 /* changing from little to big endian since supplicant
13828 * works on big endian format
13829 */
13830 int i;
13831 tANI_U8 *p = (tANI_U8 *)&pGtkOffloadGetInfoRsp->ullKeyReplayCounter;
13832
13833 for (i = 0; i < 8; i++)
13834 {
13835 tempReplayCounter[7-i] = (tANI_U8)p[i];
13836 }
13837 }
13838
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053013839 /* Update replay counter to NL */
13840 cfg80211_gtk_rekey_notify(pAdapter->dev, pGtkOffloadGetInfoRsp->bssId,
Gopichand Nakkalad36ee622013-05-07 14:13:27 +053013841 tempReplayCounter, GFP_KERNEL);
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053013842}
13843
13844/*
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053013845 * FUNCTION: __wlan_hdd_cfg80211_set_rekey_data
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053013846 * This function is used to offload GTK rekeying job to the firmware.
13847 */
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053013848int __wlan_hdd_cfg80211_set_rekey_data(struct wiphy *wiphy, struct net_device *dev,
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053013849 struct cfg80211_gtk_rekey_data *data)
13850{
13851 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
13852 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
13853 hdd_station_ctx_t *pHddStaCtx;
13854 tHalHandle hHal;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053013855 int result;
Gopichand Nakkalad36ee622013-05-07 14:13:27 +053013856 tSirGtkOffloadParams hddGtkOffloadReqParams;
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053013857 eHalStatus status = eHAL_STATUS_FAILURE;
13858
13859 ENTER();
13860
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053013861
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053013862 if (NULL == pAdapter)
13863 {
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053013864 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053013865 "%s: HDD adapter is Null", __func__);
13866 return -ENODEV;
13867 }
13868
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053013869 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
13870 TRACE_CODE_HDD_CFG80211_SET_REKEY_DATA,
13871 pAdapter->sessionId, pAdapter->device_mode));
13872
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053013873 result = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053013874
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053013875 if (0 != result)
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053013876 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053013877 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
13878 "%s: HDD context is not valid", __func__);
13879 return result;
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053013880 }
13881
13882 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
13883 hHal = WLAN_HDD_GET_HAL_CTX(pAdapter);
13884 if (NULL == hHal)
13885 {
13886 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
13887 "%s: HAL context is Null!!!", __func__);
13888 return -EAGAIN;
13889 }
13890
Gopichand Nakkalad36ee622013-05-07 14:13:27 +053013891 pHddStaCtx->gtkOffloadReqParams.ulFlags = GTK_OFFLOAD_ENABLE;
13892 memcpy(pHddStaCtx->gtkOffloadReqParams.aKCK, data->kck, NL80211_KCK_LEN);
13893 memcpy(pHddStaCtx->gtkOffloadReqParams.aKEK, data->kek, NL80211_KEK_LEN);
13894 memcpy(pHddStaCtx->gtkOffloadReqParams.bssId, &pHddStaCtx->conn_info.bssId,
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053013895 WNI_CFG_BSSID_LEN);
Gopichand Nakkalad36ee622013-05-07 14:13:27 +053013896 {
13897 /* changing from big to little endian since driver
13898 * works on little endian format
13899 */
13900 tANI_U8 *p =
13901 (tANI_U8 *)&pHddStaCtx->gtkOffloadReqParams.ullKeyReplayCounter;
13902 int i;
13903
13904 for (i = 0; i < 8; i++)
13905 {
13906 p[7-i] = data->replay_ctr[i];
13907 }
13908 }
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053013909
13910 if (TRUE == pHddCtx->hdd_wlan_suspended)
13911 {
13912 /* if wlan is suspended, enable GTK offload directly from here */
Gopichand Nakkalad36ee622013-05-07 14:13:27 +053013913 memcpy(&hddGtkOffloadReqParams, &pHddStaCtx->gtkOffloadReqParams,
13914 sizeof (tSirGtkOffloadParams));
13915 status = sme_SetGTKOffload(hHal, &hddGtkOffloadReqParams,
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053013916 pAdapter->sessionId);
13917
13918 if (eHAL_STATUS_SUCCESS != status)
13919 {
13920 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
13921 "%s: sme_SetGTKOffload failed, returned %d",
13922 __func__, status);
13923 return status;
13924 }
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053013925 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
13926 "%s: sme_SetGTKOffload successfull", __func__);
13927 }
13928 else
13929 {
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053013930 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
13931 "%s: wlan not suspended GTKOffload request is stored",
13932 __func__);
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053013933 }
Gopichand Nakkalad36ee622013-05-07 14:13:27 +053013934
13935 return eHAL_STATUS_SUCCESS;
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053013936}
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053013937
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053013938int wlan_hdd_cfg80211_set_rekey_data(struct wiphy *wiphy, struct net_device *dev,
13939 struct cfg80211_gtk_rekey_data *data)
13940{
13941 int ret;
13942
13943 vos_ssr_protect(__func__);
13944 ret = __wlan_hdd_cfg80211_set_rekey_data(wiphy, dev, data);
13945 vos_ssr_unprotect(__func__);
13946
13947 return ret;
13948}
13949#endif /*WLAN_FEATURE_GTK_OFFLOAD*/
Gopichand Nakkalac005b7c2013-05-14 16:04:14 +053013950/*
13951 * FUNCTION: wlan_hdd_cfg80211_set_mac_acl
13952 * This function is used to set access control policy
13953 */
13954static int wlan_hdd_cfg80211_set_mac_acl(struct wiphy *wiphy,
13955 struct net_device *dev, const struct cfg80211_acl_data *params)
13956{
13957 int i;
13958 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
13959 hdd_hostapd_state_t *pHostapdState;
13960 tsap_Config_t *pConfig;
13961 v_CONTEXT_t pVosContext = NULL;
13962 hdd_context_t *pHddCtx;
13963 int status;
13964
13965 ENTER();
13966
13967 if (NULL == pAdapter)
13968 {
13969 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
13970 "%s: HDD adapter is Null", __func__);
13971 return -ENODEV;
13972 }
13973
13974 if (NULL == params)
13975 {
13976 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
13977 "%s: params is Null", __func__);
13978 return -EINVAL;
13979 }
13980
13981 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
13982 status = wlan_hdd_validate_context(pHddCtx);
13983
13984 if (0 != status)
13985 {
13986 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
13987 "%s: HDD context is not valid", __func__);
13988 return status;
13989 }
13990
13991 pVosContext = pHddCtx->pvosContext;
13992 pHostapdState = WLAN_HDD_GET_HOSTAP_STATE_PTR(pAdapter);
13993
13994 if (NULL == pHostapdState)
13995 {
13996 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
13997 "%s: pHostapdState is Null", __func__);
13998 return -EINVAL;
13999 }
14000
14001 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,"acl policy: = %d"
14002 "no acl entries = %d", params->acl_policy, params->n_acl_entries);
14003
14004 if (WLAN_HDD_SOFTAP == pAdapter->device_mode)
14005 {
14006 pConfig = &pAdapter->sessionCtx.ap.sapConfig;
14007
14008 /* default value */
14009 pConfig->num_accept_mac = 0;
14010 pConfig->num_deny_mac = 0;
14011
14012 /**
14013 * access control policy
14014 * @NL80211_ACL_POLICY_ACCEPT_UNLESS_LISTED: Deny stations which are
14015 * listed in hostapd.deny file.
14016 * @NL80211_ACL_POLICY_DENY_UNLESS_LISTED: Allow stations which are
14017 * listed in hostapd.accept file.
14018 */
14019 if (NL80211_ACL_POLICY_DENY_UNLESS_LISTED == params->acl_policy)
14020 {
14021 pConfig->SapMacaddr_acl = eSAP_DENY_UNLESS_ACCEPTED;
14022 }
14023 else if (NL80211_ACL_POLICY_ACCEPT_UNLESS_LISTED == params->acl_policy)
14024 {
14025 pConfig->SapMacaddr_acl = eSAP_ACCEPT_UNLESS_DENIED;
14026 }
14027 else
14028 {
14029 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
14030 "%s:Acl Policy : %d is not supported",
14031 __func__, params->acl_policy);
14032 return -ENOTSUPP;
14033 }
14034
14035 if (eSAP_DENY_UNLESS_ACCEPTED == pConfig->SapMacaddr_acl)
14036 {
14037 pConfig->num_accept_mac = params->n_acl_entries;
14038 for (i = 0; i < params->n_acl_entries; i++)
14039 {
14040 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
14041 "** Add ACL MAC entry %i in WhiletList :"
14042 MAC_ADDRESS_STR, i,
14043 MAC_ADDR_ARRAY(params->mac_addrs[i].addr));
14044
14045 vos_mem_copy(&pConfig->accept_mac[i], params->mac_addrs[i].addr,
14046 sizeof(qcmacaddr));
14047 }
14048 }
14049 else if (eSAP_ACCEPT_UNLESS_DENIED == pConfig->SapMacaddr_acl)
14050 {
14051 pConfig->num_deny_mac = params->n_acl_entries;
14052 for (i = 0; i < params->n_acl_entries; i++)
14053 {
14054 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
14055 "** Add ACL MAC entry %i in BlackList :"
14056 MAC_ADDRESS_STR, i,
14057 MAC_ADDR_ARRAY(params->mac_addrs[i].addr));
14058
14059 vos_mem_copy(&pConfig->deny_mac[i], params->mac_addrs[i].addr,
14060 sizeof(qcmacaddr));
14061 }
14062 }
14063
14064 if (VOS_STATUS_SUCCESS != WLANSAP_SetMacACL(pVosContext, pConfig))
14065 {
14066 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
14067 "%s: SAP Set Mac Acl fail", __func__);
14068 return -EINVAL;
14069 }
14070 }
14071 else
14072 {
14073 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Sushant Kaushik8bc7df22014-04-09 17:55:29 +053014074 "%s: Invalid device_mode = %s (%d)",
14075 __func__, hdd_device_modetoString(pAdapter->device_mode),
14076 pAdapter->device_mode);
Gopichand Nakkalac005b7c2013-05-14 16:04:14 +053014077 return -EINVAL;
14078 }
14079
14080 return 0;
14081}
14082
Leo Chang9056f462013-08-01 19:21:11 -070014083#ifdef WLAN_NL80211_TESTMODE
14084#ifdef FEATURE_WLAN_LPHB
Leo Changd9df8aa2013-09-26 13:32:26 -070014085void wlan_hdd_cfg80211_lphb_ind_handler
Leo Chang9056f462013-08-01 19:21:11 -070014086(
14087 void *pAdapter,
14088 void *indCont
14089)
14090{
Leo Changd9df8aa2013-09-26 13:32:26 -070014091 tSirLPHBInd *lphbInd;
14092 struct sk_buff *skb;
c_hpothu73f35e62014-04-18 13:40:08 +053014093 hdd_context_t *pHddCtxt;
Leo Chang9056f462013-08-01 19:21:11 -070014094
14095 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Leo Changd9df8aa2013-09-26 13:32:26 -070014096 "LPHB indication arrived");
Leo Chang9056f462013-08-01 19:21:11 -070014097
c_hpothu73f35e62014-04-18 13:40:08 +053014098 if (pAdapter == NULL)
14099 {
14100 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
14101 "%s: pAdapter is NULL\n",__func__);
14102 return;
14103 }
14104
Leo Chang9056f462013-08-01 19:21:11 -070014105 if (NULL == indCont)
14106 {
14107 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Leo Changd9df8aa2013-09-26 13:32:26 -070014108 "LPHB IND, invalid argument");
Leo Chang9056f462013-08-01 19:21:11 -070014109 return;
14110 }
14111
c_hpothu73f35e62014-04-18 13:40:08 +053014112 pHddCtxt = (hdd_context_t *)pAdapter;
Leo Changd9df8aa2013-09-26 13:32:26 -070014113 lphbInd = (tSirLPHBInd *)indCont;
Leo Chang9056f462013-08-01 19:21:11 -070014114 skb = cfg80211_testmode_alloc_event_skb(
c_hpothu73f35e62014-04-18 13:40:08 +053014115 pHddCtxt->wiphy,
Leo Changd9df8aa2013-09-26 13:32:26 -070014116 sizeof(tSirLPHBInd),
Leo Chang9056f462013-08-01 19:21:11 -070014117 GFP_ATOMIC);
14118 if (!skb)
14119 {
14120 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
14121 "LPHB timeout, NL buffer alloc fail");
14122 return;
14123 }
14124
Leo Changac3ba772013-10-07 09:47:04 -070014125 if(nla_put_u32(skb, WLAN_HDD_TM_ATTR_CMD, WLAN_HDD_TM_CMD_WLAN_HB))
Leo Changd9df8aa2013-09-26 13:32:26 -070014126 {
14127 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
14128 "WLAN_HDD_TM_ATTR_CMD put fail");
14129 goto nla_put_failure;
14130 }
Leo Changac3ba772013-10-07 09:47:04 -070014131 if(nla_put_u32(skb, WLAN_HDD_TM_ATTR_TYPE, lphbInd->protocolType))
Leo Changd9df8aa2013-09-26 13:32:26 -070014132 {
14133 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
14134 "WLAN_HDD_TM_ATTR_TYPE put fail");
14135 goto nla_put_failure;
14136 }
Leo Changac3ba772013-10-07 09:47:04 -070014137 if(nla_put(skb, WLAN_HDD_TM_ATTR_DATA,
Leo Changd9df8aa2013-09-26 13:32:26 -070014138 sizeof(tSirLPHBInd), lphbInd))
14139 {
14140 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
14141 "WLAN_HDD_TM_ATTR_DATA put fail");
14142 goto nla_put_failure;
14143 }
Leo Chang9056f462013-08-01 19:21:11 -070014144 cfg80211_testmode_event(skb, GFP_ATOMIC);
14145 return;
14146
14147nla_put_failure:
14148 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
14149 "NLA Put fail");
14150 kfree_skb(skb);
14151
14152 return;
14153}
14154#endif /* FEATURE_WLAN_LPHB */
14155
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053014156static int __wlan_hdd_cfg80211_testmode(struct wiphy *wiphy, void *data, int len)
Leo Chang9056f462013-08-01 19:21:11 -070014157{
14158 struct nlattr *tb[WLAN_HDD_TM_ATTR_MAX + 1];
14159 int err = 0;
14160#ifdef FEATURE_WLAN_LPHB
14161 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
Leo Changd9df8aa2013-09-26 13:32:26 -070014162 eHalStatus smeStatus;
Leo Chang9056f462013-08-01 19:21:11 -070014163#endif /* FEATURE_WLAN_LPHB */
14164
14165 err = nla_parse(tb, WLAN_HDD_TM_ATTR_MAX, data, len, wlan_hdd_tm_policy);
14166 if (err)
14167 {
14168 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
14169 "%s Testmode INV ATTR", __func__);
14170 return err;
14171 }
14172
14173 if (!tb[WLAN_HDD_TM_ATTR_CMD])
14174 {
14175 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
14176 "%s Testmode INV CMD", __func__);
14177 return -EINVAL;
14178 }
14179
14180 switch (nla_get_u32(tb[WLAN_HDD_TM_ATTR_CMD]))
14181 {
14182#ifdef FEATURE_WLAN_LPHB
14183 /* Low Power Heartbeat configuration request */
14184 case WLAN_HDD_TM_CMD_WLAN_HB:
14185 {
14186 int buf_len;
14187 void *buf;
14188 tSirLPHBReq *hb_params = NULL;
Amar Singhal05852702014-02-04 14:40:00 -080014189 tSirLPHBReq *hb_params_temp = NULL;
Leo Chang9056f462013-08-01 19:21:11 -070014190
14191 if (!tb[WLAN_HDD_TM_ATTR_DATA])
14192 {
14193 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
14194 "%s Testmode INV DATA", __func__);
14195 return -EINVAL;
14196 }
14197
14198 buf = nla_data(tb[WLAN_HDD_TM_ATTR_DATA]);
14199 buf_len = nla_len(tb[WLAN_HDD_TM_ATTR_DATA]);
Amar Singhal05852702014-02-04 14:40:00 -080014200
14201 hb_params_temp =(tSirLPHBReq *)buf;
14202 if ((hb_params_temp->cmd == LPHB_SET_TCP_PARAMS_INDID) &&
14203 (hb_params_temp->params.lphbTcpParamReq.timePeriodSec == 0))
14204 return -EINVAL;
14205
Leo Chang9056f462013-08-01 19:21:11 -070014206 hb_params = (tSirLPHBReq *)vos_mem_malloc(sizeof(tSirLPHBReq));
14207 if (NULL == hb_params)
14208 {
14209 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
14210 "%s Request Buffer Alloc Fail", __func__);
14211 return -EINVAL;
14212 }
14213
14214 vos_mem_copy(hb_params, buf, buf_len);
Leo Changd9df8aa2013-09-26 13:32:26 -070014215 smeStatus = sme_LPHBConfigReq((tHalHandle)(pHddCtx->hHal),
14216 hb_params,
14217 wlan_hdd_cfg80211_lphb_ind_handler);
14218 if (eHAL_STATUS_SUCCESS != smeStatus)
Leo Chang9056f462013-08-01 19:21:11 -070014219 {
Leo Changd9df8aa2013-09-26 13:32:26 -070014220 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
14221 "LPHB Config Fail, disable");
Leo Chang9056f462013-08-01 19:21:11 -070014222 vos_mem_free(hb_params);
14223 }
Leo Chang9056f462013-08-01 19:21:11 -070014224 return 0;
14225 }
14226#endif /* FEATURE_WLAN_LPHB */
14227 default:
c_hpothu6ff1c3c2013-10-01 19:01:57 +053014228 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
14229 "%s: unsupported event",__func__);
Leo Chang9056f462013-08-01 19:21:11 -070014230 return -EOPNOTSUPP;
14231 }
14232
14233 return err;
14234}
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053014235
14236static int wlan_hdd_cfg80211_testmode(struct wiphy *wiphy, void *data, int len)
14237{
14238 int ret;
14239
14240 vos_ssr_protect(__func__);
14241 ret = __wlan_hdd_cfg80211_testmode(wiphy, data, len);
14242 vos_ssr_unprotect(__func__);
14243
14244 return ret;
14245}
Leo Chang9056f462013-08-01 19:21:11 -070014246#endif /* CONFIG_NL80211_TESTMODE */
14247
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053014248static int __wlan_hdd_cfg80211_dump_survey(struct wiphy *wiphy,
Madan Mohan Koyyalamudid9383fd2013-08-13 09:27:30 +053014249 struct net_device *dev,
14250 int idx, struct survey_info *survey)
14251{
14252 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
14253 hdd_context_t *pHddCtx;
Mihir Sheted9072e02013-08-21 17:02:29 +053014254 hdd_station_ctx_t *pHddStaCtx;
Madan Mohan Koyyalamudid9383fd2013-08-13 09:27:30 +053014255 tHalHandle halHandle;
Mihir Sheted9072e02013-08-21 17:02:29 +053014256 v_U32_t channel = 0, freq = 0; /* Initialization Required */
Madan Mohan Koyyalamudid9383fd2013-08-13 09:27:30 +053014257 v_S7_t snr,rssi;
14258 int status, i, j, filled = 0;
14259
14260 ENTER();
14261
Madan Mohan Koyyalamudid9383fd2013-08-13 09:27:30 +053014262 if (NULL == pAdapter)
14263 {
14264 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
14265 "%s: HDD adapter is Null", __func__);
14266 return -ENODEV;
14267 }
14268
14269 if (NULL == wiphy)
14270 {
14271 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
14272 "%s: wiphy is Null", __func__);
14273 return -ENODEV;
14274 }
14275
14276 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
14277 status = wlan_hdd_validate_context(pHddCtx);
14278
14279 if (0 != status)
14280 {
14281 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
14282 "%s: HDD context is not valid", __func__);
14283 return status;
14284 }
14285
Mihir Sheted9072e02013-08-21 17:02:29 +053014286 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
14287
Madan Mohan Koyyalamudid9383fd2013-08-13 09:27:30 +053014288 if (0 == pHddCtx->cfg_ini->fEnableSNRMonitoring ||
Mihir Sheted9072e02013-08-21 17:02:29 +053014289 0 != pAdapter->survey_idx ||
14290 eConnectionState_Associated != pHddStaCtx->conn_info.connState)
Madan Mohan Koyyalamudid9383fd2013-08-13 09:27:30 +053014291 {
14292 /* The survey dump ops when implemented completely is expected to
14293 * return a survey of all channels and the ops is called by the
14294 * kernel with incremental values of the argument 'idx' till it
14295 * returns -ENONET. But we can only support the survey for the
14296 * operating channel for now. survey_idx is used to track
14297 * that the ops is called only once and then return -ENONET for
14298 * the next iteration
14299 */
14300 pAdapter->survey_idx = 0;
14301 return -ENONET;
14302 }
14303
14304 halHandle = WLAN_HDD_GET_HAL_CTX(pAdapter);
14305
14306 wlan_hdd_get_snr(pAdapter, &snr);
14307 wlan_hdd_get_rssi(pAdapter, &rssi);
14308
14309 sme_GetOperationChannel(halHandle, &channel, pAdapter->sessionId);
14310 hdd_wlan_get_freq(channel, &freq);
14311
14312
14313 for (i = 0; i < IEEE80211_NUM_BANDS; i++)
14314 {
14315 if (NULL == wiphy->bands[i])
14316 {
14317 VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_INFO,
14318 "%s: wiphy->bands[i] is NULL, i = %d", __func__, i);
14319 continue;
14320 }
14321
14322 for (j = 0; j < wiphy->bands[i]->n_channels; j++)
14323 {
14324 struct ieee80211_supported_band *band = wiphy->bands[i];
14325
14326 if (band->channels[j].center_freq == (v_U16_t)freq)
14327 {
14328 survey->channel = &band->channels[j];
14329 /* The Rx BDs contain SNR values in dB for the received frames
14330 * while the supplicant expects noise. So we calculate and
14331 * return the value of noise (dBm)
14332 * SNR (dB) = RSSI (dBm) - NOISE (dBm)
14333 */
14334 survey->noise = rssi - snr;
14335 survey->filled = SURVEY_INFO_NOISE_DBM;
14336 filled = 1;
14337 }
14338 }
14339 }
14340
14341 if (filled)
14342 pAdapter->survey_idx = 1;
14343 else
14344 {
14345 pAdapter->survey_idx = 0;
14346 return -ENONET;
14347 }
14348
14349 return 0;
14350}
14351
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053014352static int wlan_hdd_cfg80211_dump_survey(struct wiphy *wiphy,
14353 struct net_device *dev,
14354 int idx, struct survey_info *survey)
14355{
14356 int ret;
14357
14358 vos_ssr_protect(__func__);
14359 ret = __wlan_hdd_cfg80211_dump_survey(wiphy, dev, idx, survey);
14360 vos_ssr_unprotect(__func__);
14361
14362 return ret;
14363}
14364
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053014365/*
Mahesh A Saptasagarbcc5b662014-06-02 21:46:23 +053014366 * FUNCTION: __wlan_hdd_cfg80211_resume_wlan
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053014367 * this is called when cfg80211 driver resume
14368 * driver updates latest sched_scan scan result(if any) to cfg80211 database
14369 */
Mahesh A Saptasagarbcc5b662014-06-02 21:46:23 +053014370int __wlan_hdd_cfg80211_resume_wlan(struct wiphy *wiphy)
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053014371{
14372 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
14373 hdd_adapter_t *pAdapter;
14374 hdd_adapter_list_node_t *pAdapterNode, *pNext;
14375 VOS_STATUS status = VOS_STATUS_SUCCESS;
14376
14377 ENTER();
14378
14379 if ( NULL == pHddCtx )
14380 {
14381 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
14382 "%s: HddCtx validation failed", __func__);
14383 return 0;
14384 }
14385
14386 if (pHddCtx->isLogpInProgress)
14387 {
14388 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
14389 "%s: LOGP in Progress. Ignore!!!", __func__);
14390 return 0;
14391 }
14392
Mihir Shete18156292014-03-11 15:38:30 +053014393 if (WLAN_HDD_IS_LOAD_UNLOAD_IN_PROGRESS(pHddCtx))
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053014394 {
14395 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
14396 "%s: Unloading/Loading in Progress. Ignore!!!", __func__);
14397 return 0;
14398 }
14399
14400 spin_lock(&pHddCtx->schedScan_lock);
14401 pHddCtx->isWiphySuspended = FALSE;
14402 if (TRUE != pHddCtx->isSchedScanUpdatePending)
14403 {
14404 spin_unlock(&pHddCtx->schedScan_lock);
14405 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
14406 "%s: Return resume is not due to PNO indication", __func__);
14407 return 0;
14408 }
14409 // Reset flag to avoid updatating cfg80211 data old results again
14410 pHddCtx->isSchedScanUpdatePending = FALSE;
14411 spin_unlock(&pHddCtx->schedScan_lock);
14412
Mahesh A Saptasagarb9c50402014-01-16 15:49:22 +053014413
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053014414 status = hdd_get_front_adapter ( pHddCtx, &pAdapterNode );
14415
14416 while ( NULL != pAdapterNode && VOS_STATUS_SUCCESS == status )
14417 {
14418 pAdapter = pAdapterNode->pAdapter;
14419 if ( (NULL != pAdapter) &&
14420 (WLAN_HDD_INFRA_STATION == pAdapter->device_mode) )
14421 {
14422 if (0 != wlan_hdd_cfg80211_update_bss(pHddCtx->wiphy, pAdapter))
Mahesh A Saptasagarb9c50402014-01-16 15:49:22 +053014423 {
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053014424 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_WARN,
14425 "%s: NO SCAN result", __func__);
Mahesh A Saptasagarb9c50402014-01-16 15:49:22 +053014426 }
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053014427 else
Mahesh A Saptasagarb9c50402014-01-16 15:49:22 +053014428 {
14429 /* Acquire wakelock to handle the case where APP's tries to
14430 * suspend immediately after updating the scan results. Whis
14431 * results in app's is in suspended state and not able to
14432 * process the connect request to AP
14433 */
14434 hdd_prevent_suspend_timeout(2000);
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053014435 cfg80211_sched_scan_results(pHddCtx->wiphy);
Mahesh A Saptasagarb9c50402014-01-16 15:49:22 +053014436 }
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053014437
14438 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
14439 "%s : cfg80211 scan result database updated", __func__);
14440
14441 return 0;
14442
14443 }
14444 status = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
14445 pAdapterNode = pNext;
14446 }
14447
14448 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
14449 "%s: Failed to find Adapter", __func__);
14450 return 0;
14451}
14452
Mahesh A Saptasagarbcc5b662014-06-02 21:46:23 +053014453int wlan_hdd_cfg80211_resume_wlan(struct wiphy *wiphy)
14454{
14455 int ret;
14456
14457 vos_ssr_protect(__func__);
14458 ret = __wlan_hdd_cfg80211_resume_wlan(wiphy);
14459 vos_ssr_unprotect(__func__);
14460
14461 return ret;
14462}
14463
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053014464/*
Mahesh A Saptasagarbcc5b662014-06-02 21:46:23 +053014465 * FUNCTION: __wlan_hdd_cfg80211_suspend_wlan
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053014466 * this is called when cfg80211 driver suspends
14467 */
Mahesh A Saptasagarbcc5b662014-06-02 21:46:23 +053014468int __wlan_hdd_cfg80211_suspend_wlan(struct wiphy *wiphy,
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053014469 struct cfg80211_wowlan *wow)
14470{
14471 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
14472
14473 ENTER();
14474 if (NULL == pHddCtx)
14475 {
14476 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
14477 "%s: HddCtx validation failed", __func__);
14478 return 0;
14479 }
14480
14481 pHddCtx->isWiphySuspended = TRUE;
14482
14483 EXIT();
14484
14485 return 0;
14486}
14487
Mahesh A Saptasagarbcc5b662014-06-02 21:46:23 +053014488int wlan_hdd_cfg80211_suspend_wlan(struct wiphy *wiphy,
14489 struct cfg80211_wowlan *wow)
14490{
14491 int ret;
14492
14493 vos_ssr_protect(__func__);
14494 ret = __wlan_hdd_cfg80211_suspend_wlan(wiphy, wow);
14495 vos_ssr_unprotect(__func__);
14496
14497 return ret;
14498}
Jeff Johnson295189b2012-06-20 16:38:30 -070014499/* cfg80211_ops */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014500static struct cfg80211_ops wlan_hdd_cfg80211_ops =
Jeff Johnson295189b2012-06-20 16:38:30 -070014501{
14502 .add_virtual_intf = wlan_hdd_add_virtual_intf,
14503 .del_virtual_intf = wlan_hdd_del_virtual_intf,
14504 .change_virtual_intf = wlan_hdd_cfg80211_change_iface,
14505 .change_station = wlan_hdd_change_station,
14506#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,4,0))
14507 .add_beacon = wlan_hdd_cfg80211_add_beacon,
14508 .del_beacon = wlan_hdd_cfg80211_del_beacon,
14509 .set_beacon = wlan_hdd_cfg80211_set_beacon,
Jeff Johnson04dd8a82012-06-29 20:41:40 -070014510#else
14511 .start_ap = wlan_hdd_cfg80211_start_ap,
14512 .change_beacon = wlan_hdd_cfg80211_change_beacon,
14513 .stop_ap = wlan_hdd_cfg80211_stop_ap,
Jeff Johnson295189b2012-06-20 16:38:30 -070014514#endif
14515 .change_bss = wlan_hdd_cfg80211_change_bss,
14516 .add_key = wlan_hdd_cfg80211_add_key,
14517 .get_key = wlan_hdd_cfg80211_get_key,
14518 .del_key = wlan_hdd_cfg80211_del_key,
14519 .set_default_key = wlan_hdd_cfg80211_set_default_key,
Jeff Johnson3bbe4bf2013-01-18 17:05:29 -080014520#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,6,0))
Jeff Johnson295189b2012-06-20 16:38:30 -070014521 .set_channel = wlan_hdd_cfg80211_set_channel,
Jeff Johnson3bbe4bf2013-01-18 17:05:29 -080014522#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070014523 .scan = wlan_hdd_cfg80211_scan,
14524 .connect = wlan_hdd_cfg80211_connect,
14525 .disconnect = wlan_hdd_cfg80211_disconnect,
14526 .join_ibss = wlan_hdd_cfg80211_join_ibss,
14527 .leave_ibss = wlan_hdd_cfg80211_leave_ibss,
14528 .set_wiphy_params = wlan_hdd_cfg80211_set_wiphy_params,
14529 .set_tx_power = wlan_hdd_cfg80211_set_txpower,
14530 .get_tx_power = wlan_hdd_cfg80211_get_txpower,
Jeff Johnson295189b2012-06-20 16:38:30 -070014531 .remain_on_channel = wlan_hdd_cfg80211_remain_on_channel,
14532 .cancel_remain_on_channel = wlan_hdd_cfg80211_cancel_remain_on_channel,
DARAM SUDHA39eede62014-02-12 11:16:40 +053014533 .mgmt_tx = wlan_hdd_mgmt_tx,
Jeff Johnson295189b2012-06-20 16:38:30 -070014534#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
14535 .mgmt_tx_cancel_wait = wlan_hdd_cfg80211_mgmt_tx_cancel_wait,
14536 .set_default_mgmt_key = wlan_hdd_set_default_mgmt_key,
14537 .set_txq_params = wlan_hdd_set_txq_params,
14538#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070014539 .get_station = wlan_hdd_cfg80211_get_station,
14540 .set_power_mgmt = wlan_hdd_cfg80211_set_power_mgmt,
14541 .del_station = wlan_hdd_cfg80211_del_station,
Jeff Johnson04dd8a82012-06-29 20:41:40 -070014542 .add_station = wlan_hdd_cfg80211_add_station,
14543#ifdef FEATURE_WLAN_LFR
14544 .set_pmksa = wlan_hdd_cfg80211_set_pmksa,
14545 .del_pmksa = wlan_hdd_cfg80211_del_pmksa,
14546 .flush_pmksa = wlan_hdd_cfg80211_flush_pmksa,
14547#endif
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070014548#if defined(WLAN_FEATURE_VOWIFI_11R) && defined(KERNEL_SUPPORT_11R_CFG80211)
14549 .update_ft_ies = wlan_hdd_cfg80211_update_ft_ies,
14550#endif
Mohit Khanna698ba2a2012-12-04 15:08:18 -080014551#ifdef FEATURE_WLAN_TDLS
14552 .tdls_mgmt = wlan_hdd_cfg80211_tdls_mgmt,
14553 .tdls_oper = wlan_hdd_cfg80211_tdls_oper,
14554#endif
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053014555#ifdef WLAN_FEATURE_GTK_OFFLOAD
14556 .set_rekey_data = wlan_hdd_cfg80211_set_rekey_data,
14557#endif /* WLAN_FEATURE_GTK_OFFLOAD */
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053014558#ifdef FEATURE_WLAN_SCAN_PNO
14559 .sched_scan_start = wlan_hdd_cfg80211_sched_scan_start,
14560 .sched_scan_stop = wlan_hdd_cfg80211_sched_scan_stop,
14561#endif /*FEATURE_WLAN_SCAN_PNO */
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053014562 .resume = wlan_hdd_cfg80211_resume_wlan,
14563 .suspend = wlan_hdd_cfg80211_suspend_wlan,
Gopichand Nakkalac005b7c2013-05-14 16:04:14 +053014564 .set_mac_acl = wlan_hdd_cfg80211_set_mac_acl,
Leo Chang9056f462013-08-01 19:21:11 -070014565#ifdef WLAN_NL80211_TESTMODE
14566 .testmode_cmd = wlan_hdd_cfg80211_testmode,
14567#endif
Madan Mohan Koyyalamudid9383fd2013-08-13 09:27:30 +053014568 .dump_survey = wlan_hdd_cfg80211_dump_survey,
Jeff Johnson295189b2012-06-20 16:38:30 -070014569};
14570