blob: 8d2835005515c099a03ddafe4f150c0236235c6e [file] [log] [blame]
Jeff Johnson295189b2012-06-20 16:38:30 -07001/*
Kiet Lam842dad02014-02-18 18:44:02 -08002 * Copyright (c) 2012-2014 The Linux Foundation. All rights reserved.
3 *
4 * Previously licensed under the ISC license by Qualcomm Atheros, Inc.
5 *
6 *
7 * Permission to use, copy, modify, and/or distribute this software for
8 * any purpose with or without fee is hereby granted, provided that the
9 * above copyright notice and this permission notice appear in all
10 * copies.
11 *
12 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL
13 * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED
14 * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE
15 * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL
16 * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
17 * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
18 * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
19 * PERFORMANCE OF THIS SOFTWARE.
20 */
21
22/*
Kiet Lama7f454d2014-07-24 12:04:06 -070023 * This file was originally distributed by Qualcomm Atheros, Inc.
24 * under proprietary terms before Copyright ownership was assigned
25 * to the Linux Foundation.
Kiet Lamaa8e15a2014-02-11 23:30:06 -080026 */
Kiet Lam842dad02014-02-18 18:44:02 -080027
28
Kiet Lama7f454d2014-07-24 12:04:06 -070029
30
Jeff Johnson295189b2012-06-20 16:38:30 -070031/**========================================================================
32
33 \file wlan_hdd_cfg80211.c
34
35 \brief WLAN Host Device Driver implementation
36
Jeff Johnson295189b2012-06-20 16:38:30 -070037 ========================================================================*/
38
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -070039/**=========================================================================
Jeff Johnson295189b2012-06-20 16:38:30 -070040
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -070041 EDIT HISTORY FOR FILE
Jeff Johnson295189b2012-06-20 16:38:30 -070042
43
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -070044 This section contains comments describing changes made to the module.
45 Notice that changes are listed in reverse chronological order.
Jeff Johnson295189b2012-06-20 16:38:30 -070046
47
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -070048 $Header:$ $DateTime: $ $Author: $
Jeff Johnson295189b2012-06-20 16:38:30 -070049
50
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -070051 when who what, where, why
Jeff Johnson295189b2012-06-20 16:38:30 -070052 -------- --- --------------------------------------------------------
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -070053 21/12/09 Ashwani Created module.
Jeff Johnson295189b2012-06-20 16:38:30 -070054
55 07/06/10 Kumar Deepak Implemented cfg80211 callbacks for ANDROID
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -070056 Ganesh K
Jeff Johnson295189b2012-06-20 16:38:30 -070057 ==========================================================================*/
58
Jeff Johnson295189b2012-06-20 16:38:30 -070059
60#include <linux/version.h>
61#include <linux/module.h>
62#include <linux/kernel.h>
63#include <linux/init.h>
64#include <linux/wireless.h>
65#include <wlan_hdd_includes.h>
66#include <net/arp.h>
67#include <net/cfg80211.h>
68#include <linux/wireless.h>
69#include <wlan_hdd_wowl.h>
70#include <aniGlobal.h>
71#include "ccmApi.h"
72#include "sirParams.h"
73#include "dot11f.h"
74#include "wlan_hdd_assoc.h"
75#include "wlan_hdd_wext.h"
76#include "sme_Api.h"
77#include "wlan_hdd_p2p.h"
78#include "wlan_hdd_cfg80211.h"
79#include "wlan_hdd_hostapd.h"
80#include "sapInternal.h"
81#include "wlan_hdd_softap_tx_rx.h"
82#include "wlan_hdd_main.h"
Madan Mohan Koyyalamudid5acbf52012-11-28 01:45:08 +053083#include "wlan_hdd_assoc.h"
Gopichand Nakkala20c4c042013-04-19 22:08:55 +053084#include "wlan_hdd_power.h"
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053085#include "wlan_hdd_trace.h"
86#include "vos_types.h"
87#include "vos_trace.h"
Jeff Johnson295189b2012-06-20 16:38:30 -070088#ifdef WLAN_BTAMP_FEATURE
89#include "bap_hdd_misc.h"
90#endif
91#include <qc_sap_ioctl.h>
Mohit Khanna698ba2a2012-12-04 15:08:18 -080092#ifdef FEATURE_WLAN_TDLS
93#include "wlan_hdd_tdls.h"
Gopichand Nakkala79ff85d2013-05-27 17:05:29 +053094#include "wlan_hdd_wmm.h"
Madan Mohan Koyyalamudice419872013-09-13 19:36:52 +053095#include "wlan_qct_wda.h"
Mohit Khanna698ba2a2012-12-04 15:08:18 -080096#endif
Madan Mohan Koyylamudi64267f72013-02-05 14:07:08 +053097#include "wlan_nv.h"
Leo Chang6fe1f922013-06-07 19:21:24 -070098#include "wlan_hdd_dev_pwr.h"
Jeff Johnson295189b2012-06-20 16:38:30 -070099
100#define g_mode_rates_size (12)
101#define a_mode_rates_size (8)
102#define FREQ_BASE_80211G (2407)
103#define FREQ_BAND_DIFF_80211G (5)
Jeff Johnson04dd8a82012-06-29 20:41:40 -0700104#define MAX_SCAN_SSID 9
Kiet Lamac06e2c2013-10-23 16:25:07 +0530105#define MAX_PENDING_LOG 5
Jeff Johnson295189b2012-06-20 16:38:30 -0700106#define GET_IE_LEN_IN_BSS_DESC(lenInBss) ( lenInBss + sizeof(lenInBss) - \
krunal soni2a6a9062014-02-11 14:14:23 -0800107 ((uintptr_t)OFFSET_OF( tSirBssDescription, ieFields)))
Jeff Johnson295189b2012-06-20 16:38:30 -0700108
109#define HDD2GHZCHAN(freq, chan, flag) { \
110 .band = IEEE80211_BAND_2GHZ, \
111 .center_freq = (freq), \
112 .hw_value = (chan),\
113 .flags = (flag), \
114 .max_antenna_gain = 0 ,\
115 .max_power = 30, \
116}
117
118#define HDD5GHZCHAN(freq, chan, flag) { \
119 .band = IEEE80211_BAND_5GHZ, \
120 .center_freq = (freq), \
121 .hw_value = (chan),\
122 .flags = (flag), \
123 .max_antenna_gain = 0 ,\
124 .max_power = 30, \
125}
126
127#define HDD_G_MODE_RATETAB(rate, rate_id, flag)\
128{\
129 .bitrate = rate, \
130 .hw_value = rate_id, \
131 .flags = flag, \
132}
133
Lee Hoonkic1262f22013-01-24 21:59:00 -0800134#ifndef WLAN_FEATURE_TDLS_DEBUG
135#define TDLS_LOG_LEVEL VOS_TRACE_LEVEL_INFO
136#else
137#define TDLS_LOG_LEVEL VOS_TRACE_LEVEL_ERROR
138#endif
139
Gopichand Nakkala356fb102013-03-06 12:34:04 +0530140#ifdef WLAN_FEATURE_VOWIFI_11R
141#define WLAN_AKM_SUITE_FT_8021X 0x000FAC03
142#define WLAN_AKM_SUITE_FT_PSK 0x000FAC04
143#endif
144
Naresh Jayaram3180aa42014-02-12 21:47:26 +0530145#define HDD_CHANNEL_14 14
146
Sunil Duttc69bccb2014-05-26 21:30:20 +0530147#ifdef WLAN_FEATURE_LINK_LAYER_STATS
148/*
149 * Used to allocate the size of 4096 for the link layer stats.
150 * The size of 4096 is considered assuming that all data per
151 * respective event fit with in the limit.Please take a call
152 * on the limit based on the data requirements on link layer
153 * statistics.
154 */
155#define LL_STATS_EVENT_BUF_SIZE 4096
156#endif
Dino Mycle6fb96c12014-06-10 11:52:40 +0530157#ifdef WLAN_FEATURE_EXTSCAN
158/*
159 * Used to allocate the size of 4096 for the EXTScan NL data.
160 * The size of 4096 is considered assuming that all data per
161 * respective event fit with in the limit.Please take a call
162 * on the limit based on the data requirements.
163 */
164
165#define EXTSCAN_EVENT_BUF_SIZE 4096
166#define EXTSCAN_MAX_CACHED_RESULTS_PER_IND 32
167#endif
Sunil Duttc69bccb2014-05-26 21:30:20 +0530168
Atul Mittal115287b2014-07-08 13:26:33 +0530169/*EXT TDLS*/
170/*
171 * Used to allocate the size of 4096 for the TDLS.
172 * The size of 4096 is considered assuming that all data per
173 * respective event fit with in the limit.Please take a call
174 * on the limit based on the data requirements on link layer
175 * statistics.
176 */
177#define EXTTDLS_EVENT_BUF_SIZE 4096
178
Gopichand Nakkala747461f2013-04-24 19:24:45 +0530179static const u32 hdd_cipher_suites[] =
Jeff Johnson295189b2012-06-20 16:38:30 -0700180{
181 WLAN_CIPHER_SUITE_WEP40,
182 WLAN_CIPHER_SUITE_WEP104,
183 WLAN_CIPHER_SUITE_TKIP,
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -0800184#ifdef FEATURE_WLAN_ESE
Jeff Johnson295189b2012-06-20 16:38:30 -0700185#define WLAN_CIPHER_SUITE_KRK 0x004096ff /* use for KRK */
186 WLAN_CIPHER_SUITE_KRK,
187 WLAN_CIPHER_SUITE_CCMP,
188#else
189 WLAN_CIPHER_SUITE_CCMP,
190#endif
191#ifdef FEATURE_WLAN_WAPI
192 WLAN_CIPHER_SUITE_SMS4,
193#endif
Chet Lanctot186b5732013-03-18 10:26:30 -0700194#ifdef WLAN_FEATURE_11W
195 WLAN_CIPHER_SUITE_AES_CMAC,
196#endif
Jeff Johnson295189b2012-06-20 16:38:30 -0700197};
198
199static inline int is_broadcast_ether_addr(const u8 *addr)
200{
201 return ((addr[0] == 0xff) && (addr[1] == 0xff) && (addr[2] == 0xff) &&
202 (addr[3] == 0xff) && (addr[4] == 0xff) && (addr[5] == 0xff));
203}
204
205static struct ieee80211_channel hdd_channels_2_4_GHZ[] =
Gopichand Nakkala747461f2013-04-24 19:24:45 +0530206{
Jeff Johnson295189b2012-06-20 16:38:30 -0700207 HDD2GHZCHAN(2412, 1, 0) ,
208 HDD2GHZCHAN(2417, 2, 0) ,
209 HDD2GHZCHAN(2422, 3, 0) ,
210 HDD2GHZCHAN(2427, 4, 0) ,
211 HDD2GHZCHAN(2432, 5, 0) ,
212 HDD2GHZCHAN(2437, 6, 0) ,
213 HDD2GHZCHAN(2442, 7, 0) ,
214 HDD2GHZCHAN(2447, 8, 0) ,
215 HDD2GHZCHAN(2452, 9, 0) ,
216 HDD2GHZCHAN(2457, 10, 0) ,
217 HDD2GHZCHAN(2462, 11, 0) ,
218 HDD2GHZCHAN(2467, 12, 0) ,
219 HDD2GHZCHAN(2472, 13, 0) ,
220 HDD2GHZCHAN(2484, 14, 0) ,
221};
222
Jeff Johnson295189b2012-06-20 16:38:30 -0700223static struct ieee80211_channel hdd_social_channels_2_4_GHZ[] =
224{
225 HDD2GHZCHAN(2412, 1, 0) ,
226 HDD2GHZCHAN(2437, 6, 0) ,
227 HDD2GHZCHAN(2462, 11, 0) ,
228};
Jeff Johnson295189b2012-06-20 16:38:30 -0700229
230static struct ieee80211_channel hdd_channels_5_GHZ[] =
231{
Madan Mohan Koyyalamudic3a240c2012-09-28 15:34:08 -0700232 HDD5GHZCHAN(4920, 240, 0) ,
233 HDD5GHZCHAN(4940, 244, 0) ,
234 HDD5GHZCHAN(4960, 248, 0) ,
235 HDD5GHZCHAN(4980, 252, 0) ,
236 HDD5GHZCHAN(5040, 208, 0) ,
237 HDD5GHZCHAN(5060, 212, 0) ,
238 HDD5GHZCHAN(5080, 216, 0) ,
Jeff Johnson295189b2012-06-20 16:38:30 -0700239 HDD5GHZCHAN(5180, 36, 0) ,
240 HDD5GHZCHAN(5200, 40, 0) ,
241 HDD5GHZCHAN(5220, 44, 0) ,
242 HDD5GHZCHAN(5240, 48, 0) ,
243 HDD5GHZCHAN(5260, 52, 0) ,
244 HDD5GHZCHAN(5280, 56, 0) ,
245 HDD5GHZCHAN(5300, 60, 0) ,
246 HDD5GHZCHAN(5320, 64, 0) ,
247 HDD5GHZCHAN(5500,100, 0) ,
248 HDD5GHZCHAN(5520,104, 0) ,
249 HDD5GHZCHAN(5540,108, 0) ,
250 HDD5GHZCHAN(5560,112, 0) ,
251 HDD5GHZCHAN(5580,116, 0) ,
252 HDD5GHZCHAN(5600,120, 0) ,
253 HDD5GHZCHAN(5620,124, 0) ,
254 HDD5GHZCHAN(5640,128, 0) ,
255 HDD5GHZCHAN(5660,132, 0) ,
256 HDD5GHZCHAN(5680,136, 0) ,
257 HDD5GHZCHAN(5700,140, 0) ,
Leo Chang80de3c22013-11-26 10:52:12 -0800258#ifdef FEATURE_WLAN_CH144
259 HDD5GHZCHAN(5720,144, 0) ,
260#endif /* FEATURE_WLAN_CH144 */
Jeff Johnson295189b2012-06-20 16:38:30 -0700261 HDD5GHZCHAN(5745,149, 0) ,
262 HDD5GHZCHAN(5765,153, 0) ,
263 HDD5GHZCHAN(5785,157, 0) ,
264 HDD5GHZCHAN(5805,161, 0) ,
265 HDD5GHZCHAN(5825,165, 0) ,
266};
267
268static struct ieee80211_rate g_mode_rates[] =
269{
Gopichand Nakkala747461f2013-04-24 19:24:45 +0530270 HDD_G_MODE_RATETAB(10, 0x1, 0),
271 HDD_G_MODE_RATETAB(20, 0x2, 0),
272 HDD_G_MODE_RATETAB(55, 0x4, 0),
273 HDD_G_MODE_RATETAB(110, 0x8, 0),
274 HDD_G_MODE_RATETAB(60, 0x10, 0),
275 HDD_G_MODE_RATETAB(90, 0x20, 0),
276 HDD_G_MODE_RATETAB(120, 0x40, 0),
277 HDD_G_MODE_RATETAB(180, 0x80, 0),
278 HDD_G_MODE_RATETAB(240, 0x100, 0),
279 HDD_G_MODE_RATETAB(360, 0x200, 0),
280 HDD_G_MODE_RATETAB(480, 0x400, 0),
Jeff Johnson295189b2012-06-20 16:38:30 -0700281 HDD_G_MODE_RATETAB(540, 0x800, 0),
Gopichand Nakkala747461f2013-04-24 19:24:45 +0530282};
Jeff Johnson295189b2012-06-20 16:38:30 -0700283
284static struct ieee80211_rate a_mode_rates[] =
285{
Gopichand Nakkala747461f2013-04-24 19:24:45 +0530286 HDD_G_MODE_RATETAB(60, 0x10, 0),
287 HDD_G_MODE_RATETAB(90, 0x20, 0),
288 HDD_G_MODE_RATETAB(120, 0x40, 0),
289 HDD_G_MODE_RATETAB(180, 0x80, 0),
290 HDD_G_MODE_RATETAB(240, 0x100, 0),
291 HDD_G_MODE_RATETAB(360, 0x200, 0),
292 HDD_G_MODE_RATETAB(480, 0x400, 0),
Jeff Johnson295189b2012-06-20 16:38:30 -0700293 HDD_G_MODE_RATETAB(540, 0x800, 0),
294};
295
296static struct ieee80211_supported_band wlan_hdd_band_2_4_GHZ =
297{
298 .channels = hdd_channels_2_4_GHZ,
299 .n_channels = ARRAY_SIZE(hdd_channels_2_4_GHZ),
300 .band = IEEE80211_BAND_2GHZ,
301 .bitrates = g_mode_rates,
302 .n_bitrates = g_mode_rates_size,
303 .ht_cap.ht_supported = 1,
304 .ht_cap.cap = IEEE80211_HT_CAP_SGI_20
305 | IEEE80211_HT_CAP_GRN_FLD
306 | IEEE80211_HT_CAP_DSSSCCK40
307 | IEEE80211_HT_CAP_LSIG_TXOP_PROT,
308 .ht_cap.ampdu_factor = IEEE80211_HT_MAX_AMPDU_64K,
309 .ht_cap.ampdu_density = IEEE80211_HT_MPDU_DENSITY_16,
310 .ht_cap.mcs.rx_mask = { 0xff, 0, 0, 0, 0, 0, 0, 0, 0, 0, },
311 .ht_cap.mcs.rx_highest = cpu_to_le16( 72 ),
312 .ht_cap.mcs.tx_params = IEEE80211_HT_MCS_TX_DEFINED,
313};
314
Jeff Johnson295189b2012-06-20 16:38:30 -0700315static struct ieee80211_supported_band wlan_hdd_band_p2p_2_4_GHZ =
316{
317 .channels = hdd_social_channels_2_4_GHZ,
318 .n_channels = ARRAY_SIZE(hdd_social_channels_2_4_GHZ),
319 .band = IEEE80211_BAND_2GHZ,
320 .bitrates = g_mode_rates,
321 .n_bitrates = g_mode_rates_size,
322 .ht_cap.ht_supported = 1,
323 .ht_cap.cap = IEEE80211_HT_CAP_SGI_20
324 | IEEE80211_HT_CAP_GRN_FLD
325 | IEEE80211_HT_CAP_DSSSCCK40
326 | IEEE80211_HT_CAP_LSIG_TXOP_PROT,
327 .ht_cap.ampdu_factor = IEEE80211_HT_MAX_AMPDU_64K,
328 .ht_cap.ampdu_density = IEEE80211_HT_MPDU_DENSITY_16,
329 .ht_cap.mcs.rx_mask = { 0xff, 0, 0, 0, 0, 0, 0, 0, 0, 0, },
330 .ht_cap.mcs.rx_highest = cpu_to_le16( 72 ),
331 .ht_cap.mcs.tx_params = IEEE80211_HT_MCS_TX_DEFINED,
332};
Jeff Johnson295189b2012-06-20 16:38:30 -0700333
334static struct ieee80211_supported_band wlan_hdd_band_5_GHZ =
335{
336 .channels = hdd_channels_5_GHZ,
337 .n_channels = ARRAY_SIZE(hdd_channels_5_GHZ),
338 .band = IEEE80211_BAND_5GHZ,
339 .bitrates = a_mode_rates,
340 .n_bitrates = a_mode_rates_size,
341 .ht_cap.ht_supported = 1,
342 .ht_cap.cap = IEEE80211_HT_CAP_SGI_20
343 | IEEE80211_HT_CAP_GRN_FLD
344 | IEEE80211_HT_CAP_DSSSCCK40
345 | IEEE80211_HT_CAP_LSIG_TXOP_PROT
346 | IEEE80211_HT_CAP_SGI_40
347 | IEEE80211_HT_CAP_SUP_WIDTH_20_40,
348 .ht_cap.ampdu_factor = IEEE80211_HT_MAX_AMPDU_64K,
349 .ht_cap.ampdu_density = IEEE80211_HT_MPDU_DENSITY_16,
350 .ht_cap.mcs.rx_mask = { 0xff, 0, 0, 0, 0, 0, 0, 0, 0, 0, },
351 .ht_cap.mcs.rx_highest = cpu_to_le16( 72 ),
352 .ht_cap.mcs.tx_params = IEEE80211_HT_MCS_TX_DEFINED,
353};
354
Gopichand Nakkala747461f2013-04-24 19:24:45 +0530355/* This structure contain information what kind of frame are expected in
Jeff Johnson295189b2012-06-20 16:38:30 -0700356 TX/RX direction for each kind of interface */
357static const struct ieee80211_txrx_stypes
358wlan_hdd_txrx_stypes[NUM_NL80211_IFTYPES] = {
359 [NL80211_IFTYPE_STATION] = {
360 .tx = 0xffff,
361 .rx = BIT(SIR_MAC_MGMT_ACTION) |
362 BIT(SIR_MAC_MGMT_PROBE_REQ),
363 },
364 [NL80211_IFTYPE_AP] = {
365 .tx = 0xffff,
366 .rx = BIT(SIR_MAC_MGMT_ASSOC_REQ) |
367 BIT(SIR_MAC_MGMT_REASSOC_REQ) |
368 BIT(SIR_MAC_MGMT_PROBE_REQ) |
369 BIT(SIR_MAC_MGMT_DISASSOC) |
370 BIT(SIR_MAC_MGMT_AUTH) |
371 BIT(SIR_MAC_MGMT_DEAUTH) |
372 BIT(SIR_MAC_MGMT_ACTION),
373 },
Jeff Johnsonbc006202013-04-29 14:05:30 -0700374 [NL80211_IFTYPE_ADHOC] = {
375 .tx = 0xffff,
376 .rx = BIT(SIR_MAC_MGMT_ASSOC_REQ) |
377 BIT(SIR_MAC_MGMT_REASSOC_REQ) |
378 BIT(SIR_MAC_MGMT_PROBE_REQ) |
379 BIT(SIR_MAC_MGMT_DISASSOC) |
380 BIT(SIR_MAC_MGMT_AUTH) |
381 BIT(SIR_MAC_MGMT_DEAUTH) |
382 BIT(SIR_MAC_MGMT_ACTION),
383 },
Jeff Johnson295189b2012-06-20 16:38:30 -0700384 [NL80211_IFTYPE_P2P_CLIENT] = {
385 .tx = 0xffff,
386 .rx = BIT(SIR_MAC_MGMT_ACTION) |
387 BIT(SIR_MAC_MGMT_PROBE_REQ),
388 },
389 [NL80211_IFTYPE_P2P_GO] = {
390 /* This is also same as for SoftAP */
391 .tx = 0xffff,
392 .rx = BIT(SIR_MAC_MGMT_ASSOC_REQ) |
393 BIT(SIR_MAC_MGMT_REASSOC_REQ) |
394 BIT(SIR_MAC_MGMT_PROBE_REQ) |
395 BIT(SIR_MAC_MGMT_DISASSOC) |
396 BIT(SIR_MAC_MGMT_AUTH) |
397 BIT(SIR_MAC_MGMT_DEAUTH) |
398 BIT(SIR_MAC_MGMT_ACTION),
399 },
Jeff Johnson295189b2012-06-20 16:38:30 -0700400};
401
Sudhir Sattayappa Kohalli278eee52013-01-16 17:35:13 -0800402#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,4,0))
Sudhir Sattayappa Kohalli278eee52013-01-16 17:35:13 -0800403static const struct ieee80211_iface_limit
404wlan_hdd_iface_limit[] = {
405 {
Sunil Ravia72c3992013-01-31 06:12:22 -0800406 /* max = 3 ; Our driver create two interfaces during driver init
407 * wlan0 and p2p0 interfaces. p2p0 is considered as station
408 * interface until a group is formed. In JB architecture, once the
409 * group is formed, interface type of p2p0 is changed to P2P GO or
410 * Client.
411 * When supplicant remove the group, it first issue a set interface
412 * cmd to change the mode back to Station. In JB this works fine as
413 * we advertize two station type interface during driver init.
414 * Some vendors create separate interface for P2P GO/Client,
415 * after group formation(Third one). But while group remove
416 * supplicant first tries to change the mode(3rd interface) to STATION
417 * But as we advertized only two sta type interfaces nl80211 was
418 * returning error for the third one which was leading to failure in
419 * delete interface. Ideally while removing the group, supplicant
420 * should not try to change the 3rd interface mode to Station type.
421 * Till we get a fix in wpa_supplicant, we advertize max STA
422 * interface type to 3
423 */
424 .max = 3,
Sudhir Sattayappa Kohalli278eee52013-01-16 17:35:13 -0800425 .types = BIT(NL80211_IFTYPE_STATION),
426 },
427 {
428 .max = 1,
Jeff Johnsonbc006202013-04-29 14:05:30 -0700429 .types = BIT(NL80211_IFTYPE_ADHOC) | BIT(NL80211_IFTYPE_AP),
Sudhir Sattayappa Kohalli278eee52013-01-16 17:35:13 -0800430 },
431 {
432 .max = 1,
433 .types = BIT(NL80211_IFTYPE_P2P_GO) |
434 BIT(NL80211_IFTYPE_P2P_CLIENT),
435 },
436};
437
438/* By default, only single channel concurrency is allowed */
439static struct ieee80211_iface_combination
440wlan_hdd_iface_combination = {
441 .limits = wlan_hdd_iface_limit,
442 .num_different_channels = 1,
Sunil Ravia72c3992013-01-31 06:12:22 -0800443 /*
444 * max = WLAN_MAX_INTERFACES ; JellyBean architecture creates wlan0
445 * and p2p0 interfaces during driver init
446 * Some vendors create separate interface for P2P operations.
447 * wlan0: STA interface
448 * p2p0: P2P Device interface, action frames goes
449 * through this interface.
450 * p2p-xx: P2P interface, After GO negotiation this interface is
451 * created for p2p operations(GO/CLIENT interface).
452 */
453 .max_interfaces = WLAN_MAX_INTERFACES,
Sudhir Sattayappa Kohalli278eee52013-01-16 17:35:13 -0800454 .n_limits = ARRAY_SIZE(wlan_hdd_iface_limit),
455 .beacon_int_infra_match = false,
456};
457#endif
Sudhir Sattayappa Kohalli278eee52013-01-16 17:35:13 -0800458
Jeff Johnson295189b2012-06-20 16:38:30 -0700459static struct cfg80211_ops wlan_hdd_cfg80211_ops;
460
461/* Data rate 100KBPS based on IE Index */
462struct index_data_rate_type
463{
464 v_U8_t beacon_rate_index;
465 v_U16_t supported_rate[4];
466};
467
468/* 11B, 11G Rate table include Basic rate and Extended rate
469 The IDX field is the rate index
470 The HI field is the rate when RSSI is strong or being ignored
471 (in this case we report actual rate)
472 The MID field is the rate when RSSI is moderate
473 (in this case we cap 11b rates at 5.5 and 11g rates at 24)
474 The LO field is the rate when RSSI is low
475 (in this case we don't report rates, actual current rate used)
476 */
477static const struct
478{
479 v_U8_t beacon_rate_index;
Madan Mohan Koyyalamudi8df78d52012-11-02 12:30:06 -0700480 v_U16_t supported_rate[4];
Jeff Johnson295189b2012-06-20 16:38:30 -0700481} supported_data_rate[] =
482{
Madan Mohan Koyyalamudi8df78d52012-11-02 12:30:06 -0700483/* IDX HI HM LM LO (RSSI-based index */
484 {2, { 10, 10, 10, 0}},
485 {4, { 20, 20, 10, 0}},
486 {11, { 55, 20, 10, 0}},
487 {12, { 60, 55, 20, 0}},
488 {18, { 90, 55, 20, 0}},
489 {22, {110, 55, 20, 0}},
490 {24, {120, 90, 60, 0}},
491 {36, {180, 120, 60, 0}},
492 {44, {220, 180, 60, 0}},
493 {48, {240, 180, 90, 0}},
494 {66, {330, 180, 90, 0}},
495 {72, {360, 240, 90, 0}},
496 {96, {480, 240, 120, 0}},
497 {108, {540, 240, 120, 0}}
Jeff Johnson295189b2012-06-20 16:38:30 -0700498};
499
500/* MCS Based rate table */
501static struct index_data_rate_type supported_mcs_rate[] =
502{
503/* MCS L20 L40 S20 S40 */
504 {0, {65, 135, 72, 150}},
505 {1, {130, 270, 144, 300}},
506 {2, {195, 405, 217, 450}},
507 {3, {260, 540, 289, 600}},
508 {4, {390, 810, 433, 900}},
509 {5, {520, 1080, 578, 1200}},
510 {6, {585, 1215, 650, 1350}},
511 {7, {650, 1350, 722, 1500}}
512};
513
Leo Chang6f8870f2013-03-26 18:11:36 -0700514#ifdef WLAN_FEATURE_11AC
515
Gopichand Nakkala4c705372013-04-24 13:20:33 +0530516#define DATA_RATE_11AC_MCS_MASK 0x03
Leo Chang6f8870f2013-03-26 18:11:36 -0700517
518struct index_vht_data_rate_type
519{
520 v_U8_t beacon_rate_index;
Gopichand Nakkala4c705372013-04-24 13:20:33 +0530521 v_U16_t supported_VHT80_rate[2];
522 v_U16_t supported_VHT40_rate[2];
523 v_U16_t supported_VHT20_rate[2];
Leo Chang6f8870f2013-03-26 18:11:36 -0700524};
525
526typedef enum
527{
528 DATA_RATE_11AC_MAX_MCS_7,
529 DATA_RATE_11AC_MAX_MCS_8,
530 DATA_RATE_11AC_MAX_MCS_9,
531 DATA_RATE_11AC_MAX_MCS_NA
532} eDataRate11ACMaxMcs;
533
Mahesh A Saptasagar7bd6ad42014-07-21 18:56:33 +0530534/* SSID broadcast type */
535typedef enum eSSIDBcastType
536{
537 eBCAST_UNKNOWN = 0,
538 eBCAST_NORMAL = 1,
539 eBCAST_HIDDEN = 2,
540} tSSIDBcastType;
541
Leo Chang6f8870f2013-03-26 18:11:36 -0700542/* MCS Based VHT rate table */
543static struct index_vht_data_rate_type supported_vht_mcs_rate[] =
544{
Gopichand Nakkala4c705372013-04-24 13:20:33 +0530545/* MCS L80 S80 L40 S40 L20 S40*/
546 {0, {293, 325}, {135, 150}, {65, 72}},
547 {1, {585, 650}, {270, 300}, {130, 144}},
548 {2, {878, 975}, {405, 450}, {195, 217}},
549 {3, {1170, 1300}, {540, 600}, {260, 289}},
550 {4, {1755, 1950}, {810, 900}, {390, 433}},
551 {5, {2340, 2600}, {1080, 1200}, {520, 578}},
552 {6, {2633, 2925}, {1215, 1350}, {585, 650}},
553 {7, {2925, 3250}, {1350, 1500}, {650, 722}},
554 {8, {3510, 3900}, {1620, 1800}, {780, 867}},
555 {9, {3900, 4333}, {1800, 2000}, {780, 867}}
Leo Chang6f8870f2013-03-26 18:11:36 -0700556};
557#endif /* WLAN_FEATURE_11AC */
558
c_hpothu79aab322014-07-14 21:11:01 +0530559/*array index points to MCS and array value points respective rssi*/
560static int rssiMcsTbl[][10] =
561{
562/*MCS 0 1 2 3 4 5 6 7 8 9*/
563 {-82, -79, -77, -74, -70, -66, -65, -64, -59, -57}, //20
564 {-79, -76, -74, -71, -67, -63, -62, -61, -56, -54}, //40
565 {-76, -73, -71, -68, -64, -60, -59, -58, -53, -51} //80
566};
567
Jeff Johnson295189b2012-06-20 16:38:30 -0700568extern struct net_device_ops net_ops_struct;
Dasari Srinivas7875a302014-09-26 17:50:57 +0530569#ifdef FEATURE_WLAN_SCAN_PNO
570static eHalStatus wlan_hdd_is_pno_allowed(hdd_adapter_t *pAdapter);
571#endif
Jeff Johnson295189b2012-06-20 16:38:30 -0700572
Leo Chang9056f462013-08-01 19:21:11 -0700573#ifdef WLAN_NL80211_TESTMODE
574enum wlan_hdd_tm_attr
575{
576 WLAN_HDD_TM_ATTR_INVALID = 0,
577 WLAN_HDD_TM_ATTR_CMD = 1,
578 WLAN_HDD_TM_ATTR_DATA = 2,
579 WLAN_HDD_TM_ATTR_TYPE = 3,
580 /* keep last */
581 WLAN_HDD_TM_ATTR_AFTER_LAST,
582 WLAN_HDD_TM_ATTR_MAX = WLAN_HDD_TM_ATTR_AFTER_LAST - 1,
583};
584
585enum wlan_hdd_tm_cmd
586{
587 WLAN_HDD_TM_CMD_WLAN_HB = 1,
588};
589
590#define WLAN_HDD_TM_DATA_MAX_LEN 5000
591
592static const struct nla_policy wlan_hdd_tm_policy[WLAN_HDD_TM_ATTR_MAX + 1] =
593{
594 [WLAN_HDD_TM_ATTR_CMD] = { .type = NLA_U32 },
595 [WLAN_HDD_TM_ATTR_DATA] = { .type = NLA_BINARY,
596 .len = WLAN_HDD_TM_DATA_MAX_LEN },
597};
598#endif /* WLAN_NL80211_TESTMODE */
599
Rajesh Chauhan98a31f82014-01-06 20:15:25 -0800600#ifdef FEATURE_WLAN_CH_AVOID
601/*
602 * FUNCTION: wlan_hdd_send_avoid_freq_event
603 * This is called when wlan driver needs to send vendor specific
604 * avoid frequency range event to userspace
605 */
606int wlan_hdd_send_avoid_freq_event(hdd_context_t *pHddCtx,
607 tHddAvoidFreqList *pAvoidFreqList)
608{
609 struct sk_buff *vendor_event;
610
611 ENTER();
612
613 if (!pHddCtx)
614 {
615 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
616 "%s: HDD context is null", __func__);
617 return -1;
618 }
619
620 if (!pAvoidFreqList)
621 {
622 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
623 "%s: pAvoidFreqList is null", __func__);
624 return -1;
625 }
626
627 vendor_event = cfg80211_vendor_event_alloc(pHddCtx->wiphy,
628 sizeof(tHddAvoidFreqList),
Sunil Duttc69bccb2014-05-26 21:30:20 +0530629 QCA_NL80211_VENDOR_SUBCMD_AVOID_FREQUENCY_INDEX,
Rajesh Chauhan98a31f82014-01-06 20:15:25 -0800630 GFP_KERNEL);
631 if (!vendor_event)
632 {
633 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
634 "%s: cfg80211_vendor_event_alloc failed", __func__);
635 return -1;
636 }
637
638 memcpy(skb_put(vendor_event, sizeof(tHddAvoidFreqList)),
639 (void *)pAvoidFreqList, sizeof(tHddAvoidFreqList));
640
641 cfg80211_vendor_event(vendor_event, GFP_KERNEL);
642
643 EXIT();
644 return 0;
645}
646#endif /* FEATURE_WLAN_CH_AVOID */
647
Sunil Duttc69bccb2014-05-26 21:30:20 +0530648#ifdef WLAN_FEATURE_LINK_LAYER_STATS
649
650static v_BOOL_t put_wifi_rate_stat( tpSirWifiRateStat stats,
651 struct sk_buff *vendor_event)
652{
653 if (nla_put_u8(vendor_event,
654 QCA_WLAN_VENDOR_ATTR_LL_STATS_RATE_PREAMBLE,
655 stats->rate.preamble) ||
656 nla_put_u8(vendor_event,
657 QCA_WLAN_VENDOR_ATTR_LL_STATS_RATE_NSS,
658 stats->rate.nss) ||
659 nla_put_u8(vendor_event,
660 QCA_WLAN_VENDOR_ATTR_LL_STATS_RATE_BW,
661 stats->rate.bw) ||
662 nla_put_u8(vendor_event,
663 QCA_WLAN_VENDOR_ATTR_LL_STATS_RATE_MCS_INDEX,
664 stats->rate.rateMcsIdx) ||
665 nla_put_u32(vendor_event, QCA_WLAN_VENDOR_ATTR_LL_STATS_RATE_BIT_RATE,
666 stats->rate.bitrate ) ||
667 nla_put_u32(vendor_event, QCA_WLAN_VENDOR_ATTR_LL_STATS_RATE_TX_MPDU,
668 stats->txMpdu ) ||
669 nla_put_u32(vendor_event, QCA_WLAN_VENDOR_ATTR_LL_STATS_RATE_RX_MPDU,
670 stats->rxMpdu ) ||
671 nla_put_u32(vendor_event, QCA_WLAN_VENDOR_ATTR_LL_STATS_RATE_MPDU_LOST,
672 stats->mpduLost ) ||
673 nla_put_u32(vendor_event, QCA_WLAN_VENDOR_ATTR_LL_STATS_RATE_RETRIES,
674 stats->retries) ||
675 nla_put_u32(vendor_event,
676 QCA_WLAN_VENDOR_ATTR_LL_STATS_RATE_RETRIES_SHORT,
677 stats->retriesShort ) ||
678 nla_put_u32(vendor_event,
679 QCA_WLAN_VENDOR_ATTR_LL_STATS_RATE_RETRIES_LONG,
680 stats->retriesLong))
681 {
682 hddLog(VOS_TRACE_LEVEL_ERROR,
683 FL("QCA_WLAN_VENDOR_ATTR put fail"));
684 return FALSE;
685 }
686 return TRUE;
687}
688
689static v_BOOL_t put_wifi_peer_info( tpSirWifiPeerInfo stats,
690 struct sk_buff *vendor_event)
691{
692 u32 i = 0;
693 struct nlattr *rateInfo;
694 if (nla_put_u32(vendor_event, QCA_WLAN_VENDOR_ATTR_LL_STATS_PEER_INFO_TYPE,
695 stats->type) ||
696 nla_put(vendor_event,
697 QCA_WLAN_VENDOR_ATTR_LL_STATS_PEER_INFO_MAC_ADDRESS,
698 VOS_MAC_ADDR_SIZE, &stats->peerMacAddress[0]) ||
699 nla_put_u32(vendor_event,
700 QCA_WLAN_VENDOR_ATTR_LL_STATS_PEER_INFO_CAPABILITIES,
701 stats->capabilities) ||
702 nla_put_u32(vendor_event,
703 QCA_WLAN_VENDOR_ATTR_LL_STATS_PEER_INFO_NUM_RATES,
704 stats->numRate))
705 {
706 hddLog(VOS_TRACE_LEVEL_ERROR,
707 FL("QCA_WLAN_VENDOR_ATTR put fail"));
708 goto error;
709 }
710
711 rateInfo = nla_nest_start(vendor_event,
712 QCA_WLAN_VENDOR_ATTR_LL_STATS_PEER_INFO_RATE_INFO);
713 for (i = 0; i < stats->numRate; i++)
714 {
715 struct nlattr *rates;
716 tpSirWifiRateStat pRateStats = (tpSirWifiRateStat )((uint8 *)
717 stats->rateStats +
718 (i * sizeof(tSirWifiRateStat)));
719 rates = nla_nest_start(vendor_event, i);
720
721 if (FALSE == put_wifi_rate_stat(pRateStats, vendor_event))
722 {
723 hddLog(VOS_TRACE_LEVEL_ERROR,
724 FL("QCA_WLAN_VENDOR_ATTR put fail"));
725 return FALSE;
726 }
727 nla_nest_end(vendor_event, rates);
728 }
729 nla_nest_end(vendor_event, rateInfo);
730
731 return TRUE;
732error:
733 return FALSE;
734}
735
736static v_BOOL_t put_wifi_wmm_ac_stat( tpSirWifiWmmAcStat stats,
737 struct sk_buff *vendor_event)
738{
739 if (nla_put_u32(vendor_event, QCA_WLAN_VENDOR_ATTR_LL_STATS_WMM_AC_AC,
740 stats->ac ) ||
741 nla_put_u32(vendor_event,
742 QCA_WLAN_VENDOR_ATTR_LL_STATS_WMM_AC_TX_MPDU,
743 stats->txMpdu ) ||
744 nla_put_u32(vendor_event,
745 QCA_WLAN_VENDOR_ATTR_LL_STATS_WMM_AC_RX_MPDU,
746 stats->rxMpdu ) ||
747 nla_put_u32(vendor_event,
748 QCA_WLAN_VENDOR_ATTR_LL_STATS_WMM_AC_TX_MCAST,
749 stats->txMcast ) ||
750 nla_put_u32(vendor_event,
751 QCA_WLAN_VENDOR_ATTR_LL_STATS_WMM_AC_RX_MCAST,
752 stats->rxMcast ) ||
753 nla_put_u32(vendor_event,
754 QCA_WLAN_VENDOR_ATTR_LL_STATS_WMM_AC_RX_AMPDU,
755 stats->rxAmpdu ) ||
756 nla_put_u32(vendor_event,
757 QCA_WLAN_VENDOR_ATTR_LL_STATS_WMM_AC_TX_AMPDU,
758 stats->txAmpdu ) ||
759 nla_put_u32(vendor_event,
760 QCA_WLAN_VENDOR_ATTR_LL_STATS_WMM_AC_MPDU_LOST,
761 stats->mpduLost )||
762 nla_put_u32(vendor_event,
763 QCA_WLAN_VENDOR_ATTR_LL_STATS_WMM_AC_RETRIES,
764 stats->retries ) ||
765 nla_put_u32(vendor_event,
766 QCA_WLAN_VENDOR_ATTR_LL_STATS_WMM_AC_RETRIES_SHORT,
767 stats->retriesShort ) ||
768 nla_put_u32(vendor_event,
769 QCA_WLAN_VENDOR_ATTR_LL_STATS_WMM_AC_RETRIES_LONG,
770 stats->retriesLong ) ||
771 nla_put_u32(vendor_event,
772 QCA_WLAN_VENDOR_ATTR_LL_STATS_WMM_AC_CONTENTION_TIME_MIN,
773 stats->contentionTimeMin ) ||
774 nla_put_u32(vendor_event,
775 QCA_WLAN_VENDOR_ATTR_LL_STATS_WMM_AC_CONTENTION_TIME_MAX,
776 stats->contentionTimeMax ) ||
777 nla_put_u32(vendor_event,
778 QCA_WLAN_VENDOR_ATTR_LL_STATS_WMM_AC_CONTENTION_TIME_AVG,
779 stats->contentionTimeAvg ) ||
780 nla_put_u32(vendor_event,
781 QCA_WLAN_VENDOR_ATTR_LL_STATS_WMM_AC_CONTENTION_NUM_SAMPLES,
782 stats->contentionNumSamples ))
783 {
784 hddLog(VOS_TRACE_LEVEL_ERROR,
785 FL("QCA_WLAN_VENDOR_ATTR put fail") );
786 return FALSE;
787 }
788 return TRUE;
789}
790
791static v_BOOL_t put_wifi_interface_info(tpSirWifiInterfaceInfo stats,
792 struct sk_buff *vendor_event)
793{
Dino Myclec8f3f332014-07-21 16:48:27 +0530794 if (nla_put_s32(vendor_event,
Sunil Duttc69bccb2014-05-26 21:30:20 +0530795 QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_INFO_MODE, stats->mode ) ||
796 nla_put(vendor_event,
797 QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_INFO_MAC_ADDR,
798 VOS_MAC_ADDR_SIZE, stats->macAddr) ||
799 nla_put_u32(vendor_event,
800 QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_INFO_STATE,
801 stats->state ) ||
802 nla_put_u32(vendor_event,
803 QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_INFO_ROAMING,
804 stats->roaming ) ||
805 nla_put_u32(vendor_event,
806 QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_INFO_CAPABILITIES,
807 stats->capabilities ) ||
808 nla_put(vendor_event,
809 QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_INFO_SSID,
810 strlen(stats->ssid), stats->ssid) ||
811 nla_put(vendor_event,
812 QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_INFO_BSSID,
813 WNI_CFG_BSSID_LEN, stats->bssid) ||
814 nla_put(vendor_event,
815 QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_INFO_AP_COUNTRY_STR,
816 WNI_CFG_COUNTRY_CODE_LEN, stats->apCountryStr) ||
817 nla_put(vendor_event,
818 QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_INFO_COUNTRY_STR,
819 WNI_CFG_COUNTRY_CODE_LEN, stats->countryStr)
820 )
821 {
822 hddLog(VOS_TRACE_LEVEL_ERROR,
823 FL("QCA_WLAN_VENDOR_ATTR put fail") );
824 return FALSE;
825 }
826 return TRUE;
827}
828
Dino Mycle3b9536d2014-07-09 22:05:24 +0530829static v_BOOL_t put_wifi_iface_stats(hdd_adapter_t *pAdapter,
830 tpSirWifiIfaceStat pWifiIfaceStat,
Sunil Duttc69bccb2014-05-26 21:30:20 +0530831 struct sk_buff *vendor_event)
832{
833 int i = 0;
834 struct nlattr *wmmInfo;
Dino Mycle3b9536d2014-07-09 22:05:24 +0530835 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
836 WLANTL_InterfaceStatsType *pWifiIfaceStatTL = NULL;
837
Sunil Duttc69bccb2014-05-26 21:30:20 +0530838 if (FALSE == put_wifi_interface_info(
839 &pWifiIfaceStat->info,
840 vendor_event))
841 {
842 hddLog(VOS_TRACE_LEVEL_ERROR,
843 FL("QCA_WLAN_VENDOR_ATTR put fail") );
844 return FALSE;
845
846 }
Dino Mycle3b9536d2014-07-09 22:05:24 +0530847 pWifiIfaceStatTL = (WLANTL_InterfaceStatsType *)
848 vos_mem_malloc(sizeof(WLANTL_InterfaceStatsType));
849 if (NULL == pWifiIfaceStatTL)
850 {
851 hddLog(VOS_TRACE_LEVEL_ERROR, FL("vos_mem_malloc failed"));
852 return FALSE;
853 }
854
855
856 if ( pWifiIfaceStat->info.state == WIFI_ASSOCIATED)
857 {
858 if (VOS_STATUS_SUCCESS ==
859 WLANTL_CollectInterfaceStats((WLAN_HDD_GET_CTX(pAdapter))->pvosContext,
860 pHddStaCtx->conn_info.staId[0], pWifiIfaceStatTL))
861 {
862 /* mgmtRx, MgmtActionRx, rxMcast, rxMpdu, rxAmpdu, rssiData are
863 * obtained from TL structure
864 */
865
866 pWifiIfaceStat->mgmtRx = pWifiIfaceStat->beaconRx +
867 pWifiIfaceStatTL->mgmtRx;
868 pWifiIfaceStat->mgmtActionRx = pWifiIfaceStatTL->mgmtActionRx;
869 pWifiIfaceStat->mgmtActionTx = pWifiIfaceStatTL->mgmtActionTx;
870 pWifiIfaceStat->rssiData = pWifiIfaceStatTL->rssiData;
871
872 vos_mem_copy(
873 (void *) &pWifiIfaceStat->AccessclassStats[WIFI_AC_VO],
874 (void *) &pWifiIfaceStatTL->accessCategoryStats[WLANTL_AC_VO],
875 sizeof(WLANTL_AccessCategoryStatsType));
876
877 vos_mem_copy(
878 (void *) &pWifiIfaceStat->AccessclassStats[WIFI_AC_VI],
879 (void *) &pWifiIfaceStatTL->accessCategoryStats[WLANTL_AC_VI],
880 sizeof(WLANTL_AccessCategoryStatsType));
881
882 vos_mem_copy(
883 (void *) &pWifiIfaceStat->AccessclassStats[WIFI_AC_BE],
884 (void *) &pWifiIfaceStatTL->accessCategoryStats[WLANTL_AC_BE],
885 sizeof(WLANTL_AccessCategoryStatsType));
886
887 vos_mem_copy(
888 (void *) &pWifiIfaceStat->AccessclassStats[WIFI_AC_BK],
889 (void *) &pWifiIfaceStatTL->accessCategoryStats[WLANTL_AC_BK],
890 sizeof(WLANTL_AccessCategoryStatsType));
891 }
892 else
893 {
894 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Error in getting stats from TL"));
895 }
896
897 pWifiIfaceStat->AccessclassStats[WIFI_AC_VO].txMpdu =
898 pAdapter->hdd_stats.hddTxRxStats.txFetchedAC[WLANTL_AC_VO];
899 pWifiIfaceStat->AccessclassStats[WIFI_AC_VI].txMpdu =
900 pAdapter->hdd_stats.hddTxRxStats.txFetchedAC[WLANTL_AC_VI];
901 pWifiIfaceStat->AccessclassStats[WIFI_AC_BE].txMpdu =
902 pAdapter->hdd_stats.hddTxRxStats.txFetchedAC[WLANTL_AC_BE];
903 pWifiIfaceStat->AccessclassStats[WIFI_AC_BK].txMpdu =
904 pAdapter->hdd_stats.hddTxRxStats.txFetchedAC[WLANTL_AC_BK];
905
906 pWifiIfaceStat->AccessclassStats[WIFI_AC_VO].txMcast =
907 pAdapter->hdd_stats.hddTxRxStats.txMcast[WLANTL_AC_VO];
908 pWifiIfaceStat->AccessclassStats[WIFI_AC_VI].txMcast =
909 pAdapter->hdd_stats.hddTxRxStats.txMcast[WLANTL_AC_VI];
910 pWifiIfaceStat->AccessclassStats[WIFI_AC_BE].txMcast =
911 pAdapter->hdd_stats.hddTxRxStats.txMcast[WLANTL_AC_BE];
912 pWifiIfaceStat->AccessclassStats[WIFI_AC_BK].txMcast =
913 pAdapter->hdd_stats.hddTxRxStats.txMcast[WLANTL_AC_BK];
914 }
915 else
916 {
917 hddLog(VOS_TRACE_LEVEL_INFO, FL("Interface not Associated"));
918 }
919
920
Sunil Duttc69bccb2014-05-26 21:30:20 +0530921
922 if (nla_put_u32(vendor_event,
923 QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_BEACON_RX,
924 pWifiIfaceStat->beaconRx) ||
925 nla_put_u32(vendor_event,
926 QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_MGMT_RX,
927 pWifiIfaceStat->mgmtRx) ||
928 nla_put_u32(vendor_event,
929 QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_MGMT_ACTION_RX,
930 pWifiIfaceStat->mgmtActionRx) ||
931 nla_put_u32(vendor_event,
932 QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_MGMT_ACTION_TX,
933 pWifiIfaceStat->mgmtActionTx) ||
Dino Mycle3b9536d2014-07-09 22:05:24 +0530934 nla_put_s32(vendor_event,
Sunil Duttc69bccb2014-05-26 21:30:20 +0530935 QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_RSSI_MGMT,
936 pWifiIfaceStat->rssiMgmt) ||
Dino Mycle3b9536d2014-07-09 22:05:24 +0530937 nla_put_s32(vendor_event,
Sunil Duttc69bccb2014-05-26 21:30:20 +0530938 QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_RSSI_DATA,
939 pWifiIfaceStat->rssiData) ||
Dino Mycle3b9536d2014-07-09 22:05:24 +0530940 nla_put_s32(vendor_event,
Sunil Duttc69bccb2014-05-26 21:30:20 +0530941 QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_RSSI_ACK,
942 pWifiIfaceStat->rssiAck))
943 {
944 hddLog(VOS_TRACE_LEVEL_ERROR,
945 FL("QCA_WLAN_VENDOR_ATTR put fail"));
Dino Mycle3b9536d2014-07-09 22:05:24 +0530946 vos_mem_free(pWifiIfaceStatTL);
Sunil Duttc69bccb2014-05-26 21:30:20 +0530947 return FALSE;
948 }
949
950 wmmInfo = nla_nest_start(vendor_event,
951 QCA_WLAN_VENDOR_ATTR_LL_STATS_WMM_INFO);
952 for (i = 0; i < WIFI_AC_MAX; i++)
953 {
954 struct nlattr *wmmStats;
955 wmmStats = nla_nest_start(vendor_event, i);
956 if (FALSE == put_wifi_wmm_ac_stat(
957 &pWifiIfaceStat->AccessclassStats[i],
958 vendor_event))
959 {
960 hddLog(VOS_TRACE_LEVEL_ERROR,
961 FL("QCA_WLAN_VENDOR_ATTR put Fail"));
Dino Mycle3b9536d2014-07-09 22:05:24 +0530962 vos_mem_free(pWifiIfaceStatTL);
Sunil Duttc69bccb2014-05-26 21:30:20 +0530963 return FALSE;
964 }
965
966 nla_nest_end(vendor_event, wmmStats);
967 }
968 nla_nest_end(vendor_event, wmmInfo);
Dino Mycle3b9536d2014-07-09 22:05:24 +0530969 vos_mem_free(pWifiIfaceStatTL);
Sunil Duttc69bccb2014-05-26 21:30:20 +0530970 return TRUE;
971}
972
973static tSirWifiInterfaceMode
974 hdd_map_device_to_ll_iface_mode ( int deviceMode )
975{
976 switch (deviceMode)
977 {
978 case WLAN_HDD_INFRA_STATION:
979 return WIFI_INTERFACE_STA;
980 case WLAN_HDD_SOFTAP:
981 return WIFI_INTERFACE_SOFTAP;
982 case WLAN_HDD_P2P_CLIENT:
983 return WIFI_INTERFACE_P2P_CLIENT;
984 case WLAN_HDD_P2P_GO:
985 return WIFI_INTERFACE_P2P_GO;
986 case WLAN_HDD_IBSS:
987 return WIFI_INTERFACE_IBSS;
988 default:
Dino Myclec8f3f332014-07-21 16:48:27 +0530989 return WIFI_INTERFACE_UNKNOWN;
Sunil Duttc69bccb2014-05-26 21:30:20 +0530990 }
991}
992
993static v_BOOL_t hdd_get_interface_info(hdd_adapter_t *pAdapter,
994 tpSirWifiInterfaceInfo pInfo)
995{
996 v_U8_t *staMac = NULL;
997 hdd_station_ctx_t *pHddStaCtx;
998 tHalHandle hHal = WLAN_HDD_GET_HAL_CTX(pAdapter);
999 tpAniSirGlobal pMac = PMAC_STRUCT( hHal );
1000
1001 pInfo->mode = hdd_map_device_to_ll_iface_mode(pAdapter->device_mode);
1002
1003 vos_mem_copy(pInfo->macAddr,
1004 pAdapter->macAddressCurrent.bytes, sizeof(v_MACADDR_t));
1005
1006 if (((WLAN_HDD_INFRA_STATION == pAdapter->device_mode) ||
1007 (WLAN_HDD_P2P_CLIENT == pAdapter->device_mode) ||
1008 (WLAN_HDD_P2P_DEVICE == pAdapter->device_mode)))
1009 {
1010 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
1011 if (eConnectionState_NotConnected == pHddStaCtx->conn_info.connState)
1012 {
1013 pInfo->state = WIFI_DISCONNECTED;
1014 }
1015 if (eConnectionState_Connecting == pHddStaCtx->conn_info.connState)
1016 {
1017 hddLog(VOS_TRACE_LEVEL_ERROR,
1018 "%s: Session ID %d, Connection is in progress", __func__,
1019 pAdapter->sessionId);
1020 pInfo->state = WIFI_ASSOCIATING;
1021 }
1022 if ((eConnectionState_Associated == pHddStaCtx->conn_info.connState) &&
1023 (VOS_FALSE == pHddStaCtx->conn_info.uIsAuthenticated))
1024 {
1025 staMac = (v_U8_t *) &(pAdapter->macAddressCurrent.bytes[0]);
1026 hddLog(VOS_TRACE_LEVEL_ERROR,
1027 "%s: client " MAC_ADDRESS_STR
1028 " is in the middle of WPS/EAPOL exchange.", __func__,
1029 MAC_ADDR_ARRAY(staMac));
1030 pInfo->state = WIFI_AUTHENTICATING;
1031 }
1032 if (eConnectionState_Associated == pHddStaCtx->conn_info.connState)
1033 {
1034 pInfo->state = WIFI_ASSOCIATED;
1035 vos_mem_copy(pInfo->bssid,
1036 &pHddStaCtx->conn_info.bssId, WNI_CFG_BSSID_LEN);
1037 vos_mem_copy(pInfo->ssid,
1038 pHddStaCtx->conn_info.SSID.SSID.ssId,
1039 pHddStaCtx->conn_info.SSID.SSID.length);
1040 //NULL Terminate the string.
1041 pInfo->ssid[pHddStaCtx->conn_info.SSID.SSID.length] = 0;
1042 }
1043 }
1044 vos_mem_copy(pInfo->countryStr,
1045 pMac->scan.countryCodeCurrent, WNI_CFG_COUNTRY_CODE_LEN);
1046
1047 vos_mem_copy(pInfo->apCountryStr,
1048 pMac->scan.countryCodeCurrent, WNI_CFG_COUNTRY_CODE_LEN);
1049
1050 return TRUE;
1051}
1052
1053/*
1054 * hdd_link_layer_process_peer_stats () - This function is called after
1055 * receiving Link Layer Peer statistics from FW.This function converts
1056 * the firmware data to the NL data and sends the same to the kernel/upper
1057 * layers.
1058 */
1059static v_VOID_t hdd_link_layer_process_peer_stats(hdd_adapter_t *pAdapter,
1060 v_VOID_t *pData)
1061{
1062 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
1063 tpSirWifiRateStat pWifiRateStat;
1064 tpSirWifiPeerStat pWifiPeerStat;
1065 tpSirWifiPeerInfo pWifiPeerInfo;
1066 struct nlattr *peerInfo;
1067 struct sk_buff *vendor_event;
1068 int status, i;
1069
1070 status = wlan_hdd_validate_context(pHddCtx);
1071 if (0 != status)
1072 {
1073 hddLog(VOS_TRACE_LEVEL_ERROR,
1074 FL("HDD context is not valid") );
1075 return;
1076 }
1077
1078 pWifiPeerStat = (tpSirWifiPeerStat) pData;
1079
1080 hddLog(VOS_TRACE_LEVEL_INFO,
1081 "LL_STATS_PEER_ALL : numPeers %u",
1082 pWifiPeerStat->numPeers);
1083 {
1084 for (i = 0; i < pWifiPeerStat->numPeers; i++)
1085 {
1086 pWifiPeerInfo = (tpSirWifiPeerInfo)
1087 ((uint8 *)pWifiPeerStat->peerInfo +
1088 ( i * sizeof(tSirWifiPeerInfo)));
1089
Dasari Srinivas1be0c4e2014-10-19 13:03:41 +05301090 if (WLAN_HDD_INFRA_STATION == pAdapter->device_mode) {
1091 pWifiPeerInfo->type = WIFI_PEER_AP;
1092 }
1093 if (WLAN_HDD_P2P_CLIENT == pAdapter->device_mode) {
1094 pWifiPeerInfo->type = WIFI_PEER_P2P_GO;
1095 }
1096
Sunil Duttc69bccb2014-05-26 21:30:20 +05301097 hddLog(VOS_TRACE_LEVEL_INFO,
1098 " %d) LL_STATS Channel Stats "
1099 " Peer Type %u "
1100 " peerMacAddress %pM "
1101 " capabilities 0x%x "
1102 " numRate %u ",
1103 i,
1104 pWifiPeerInfo->type,
1105 pWifiPeerInfo->peerMacAddress,
1106 pWifiPeerInfo->capabilities,
1107 pWifiPeerInfo->numRate);
1108 {
1109 int j;
1110 for (j = 0; j < pWifiPeerInfo->numRate; j++)
1111 {
1112 pWifiRateStat = (tpSirWifiRateStat)
1113 ((tANI_U8 *) pWifiPeerInfo->rateStats +
1114 ( j * sizeof(tSirWifiRateStat)));
1115
1116 hddLog(VOS_TRACE_LEVEL_INFO,
1117 " peer Rate Stats "
1118 " preamble %u "
1119 " nss %u "
1120 " bw %u "
1121 " rateMcsIdx %u "
1122 " reserved %u "
1123 " bitrate %u "
1124 " txMpdu %u "
1125 " rxMpdu %u "
1126 " mpduLost %u "
1127 " retries %u "
1128 " retriesShort %u "
1129 " retriesLong %u",
1130 pWifiRateStat->rate.preamble,
1131 pWifiRateStat->rate.nss,
1132 pWifiRateStat->rate.bw,
1133 pWifiRateStat->rate.rateMcsIdx,
1134 pWifiRateStat->rate.reserved,
1135 pWifiRateStat->rate.bitrate,
1136 pWifiRateStat->txMpdu,
1137 pWifiRateStat->rxMpdu,
1138 pWifiRateStat->mpduLost,
1139 pWifiRateStat->retries,
1140 pWifiRateStat->retriesShort,
1141 pWifiRateStat->retriesLong);
1142 }
1143 }
1144 }
1145 }
1146
1147 /*
1148 * Allocate a size of 4096 for the peer stats comprising
1149 * each of size = sizeof (tSirWifiPeerInfo) + numRate *
1150 * sizeof (tSirWifiRateStat).Each field is put with an
1151 * NL attribute.The size of 4096 is considered assuming
1152 * that number of rates shall not exceed beyond 50 with
1153 * the sizeof (tSirWifiRateStat) being 32.
1154 */
1155 vendor_event = cfg80211_vendor_event_alloc(pHddCtx->wiphy,
1156 LL_STATS_EVENT_BUF_SIZE + NLMSG_HDRLEN,
1157 QCA_NL80211_VENDOR_SUBCMD_LL_PEER_INFO_STATS_INDEX,
1158 GFP_KERNEL);
1159 if (!vendor_event)
1160 {
1161 hddLog(VOS_TRACE_LEVEL_ERROR,
1162 "%s: cfg80211_vendor_event_alloc failed",
1163 __func__);
1164 return;
1165 }
1166 if (nla_put_u32(vendor_event,
1167 QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_NUM_PEERS,
1168 pWifiPeerStat->numPeers))
1169 {
1170 hddLog(VOS_TRACE_LEVEL_ERROR,
1171 "%s: QCA_WLAN_VENDOR_ATTR put fail", __func__);
1172 kfree_skb(vendor_event);
1173 return;
1174 }
1175
1176 peerInfo = nla_nest_start(vendor_event,
1177 QCA_WLAN_VENDOR_ATTR_LL_STATS_PEER_INFO);
1178
1179 pWifiPeerInfo = (tpSirWifiPeerInfo) ((uint8 *)
1180 pWifiPeerStat->peerInfo);
1181
1182 for (i = 1; i <= pWifiPeerStat->numPeers; i++)
1183 {
1184 struct nlattr *peers = nla_nest_start(vendor_event, i);
1185 int numRate = pWifiPeerInfo->numRate;
1186
1187 if (FALSE == put_wifi_peer_info(
1188 pWifiPeerInfo, vendor_event))
1189 {
1190 hddLog(VOS_TRACE_LEVEL_ERROR,
1191 "%s: put_wifi_peer_info put fail", __func__);
1192 kfree_skb(vendor_event);
1193 return;
1194 }
1195
1196 pWifiPeerInfo = (tpSirWifiPeerInfo) ((uint8 *)
1197 pWifiPeerStat->peerInfo +
1198 (i * sizeof(tSirWifiPeerInfo)) +
1199 (numRate * sizeof (tSirWifiRateStat)));
1200 nla_nest_end(vendor_event, peers);
1201 }
1202 nla_nest_end(vendor_event, peerInfo);
1203 cfg80211_vendor_event(vendor_event, GFP_KERNEL);
1204}
1205
1206/*
1207 * hdd_link_layer_process_iface_stats () - This function is called after
1208 * receiving Link Layer Interface statistics from FW.This function converts
1209 * the firmware data to the NL data and sends the same to the kernel/upper
1210 * layers.
1211 */
1212static v_VOID_t hdd_link_layer_process_iface_stats(hdd_adapter_t *pAdapter,
1213 v_VOID_t *pData)
1214{
1215 tpSirWifiIfaceStat pWifiIfaceStat;
1216 struct sk_buff *vendor_event;
1217 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
1218 int status;
1219
1220 status = wlan_hdd_validate_context(pHddCtx);
1221 if (0 != status)
1222 {
1223 hddLog(VOS_TRACE_LEVEL_ERROR,
1224 FL("HDD context is not valid") );
1225 return;
1226 }
1227 /*
1228 * Allocate a size of 4096 for the interface stats comprising
1229 * sizeof (tpSirWifiIfaceStat).The size of 4096 is considered
1230 * assuming that all these fit with in the limit.Please take
1231 * a call on the limit based on the data requirements on
1232 * interface statistics.
1233 */
1234 vendor_event = cfg80211_vendor_event_alloc(pHddCtx->wiphy,
1235 LL_STATS_EVENT_BUF_SIZE + NLMSG_HDRLEN,
1236 QCA_NL80211_VENDOR_SUBCMD_LL_IFACE_STATS_INDEX,
1237 GFP_KERNEL);
1238 if (!vendor_event)
1239 {
1240 hddLog(VOS_TRACE_LEVEL_ERROR,
1241 FL("cfg80211_vendor_event_alloc failed") );
1242 return;
1243 }
1244
1245 pWifiIfaceStat = (tpSirWifiIfaceStat) pData;
1246
Dino Mycle3b9536d2014-07-09 22:05:24 +05301247
1248 if (FALSE == hdd_get_interface_info( pAdapter,
1249 &pWifiIfaceStat->info))
1250 {
1251 hddLog(VOS_TRACE_LEVEL_ERROR,
1252 FL("hdd_get_interface_info get fail") );
1253 kfree_skb(vendor_event);
1254 return;
1255 }
1256
1257 if (FALSE == put_wifi_iface_stats( pAdapter, pWifiIfaceStat,
1258 vendor_event))
1259 {
1260 hddLog(VOS_TRACE_LEVEL_ERROR,
1261 FL("put_wifi_iface_stats fail") );
1262 kfree_skb(vendor_event);
1263 return;
1264 }
1265
Sunil Duttc69bccb2014-05-26 21:30:20 +05301266 hddLog(VOS_TRACE_LEVEL_INFO,
1267 "WMI_LINK_STATS_IFACE Data");
1268
1269 hddLog(VOS_TRACE_LEVEL_INFO,
1270 "LL_STATS_IFACE: "
1271 " Mode %u "
1272 " MAC %pM "
1273 " State %u "
1274 " Roaming %u "
1275 " capabilities 0x%x "
1276 " SSID %s "
1277 " BSSID %pM",
1278 pWifiIfaceStat->info.mode,
1279 pWifiIfaceStat->info.macAddr,
1280 pWifiIfaceStat->info.state,
1281 pWifiIfaceStat->info.roaming,
1282 pWifiIfaceStat->info.capabilities,
1283 pWifiIfaceStat->info.ssid,
1284 pWifiIfaceStat->info.bssid);
1285
1286 hddLog(VOS_TRACE_LEVEL_INFO,
1287 " AP country str: %c%c%c",
1288 pWifiIfaceStat->info.apCountryStr[0],
1289 pWifiIfaceStat->info.apCountryStr[1],
1290 pWifiIfaceStat->info.apCountryStr[2]);
1291
1292
1293 hddLog(VOS_TRACE_LEVEL_INFO,
1294 " Country Str Association: %c%c%c",
1295 pWifiIfaceStat->info.countryStr[0],
1296 pWifiIfaceStat->info.countryStr[1],
1297 pWifiIfaceStat->info.countryStr[2]);
1298
1299 hddLog(VOS_TRACE_LEVEL_INFO,
1300 " beaconRx %u "
1301 " mgmtRx %u "
1302 " mgmtActionRx %u "
1303 " mgmtActionTx %u "
Dino Mycle3b9536d2014-07-09 22:05:24 +05301304 " rssiMgmt %d "
1305 " rssiData %d "
1306 " rssiAck %d",
Sunil Duttc69bccb2014-05-26 21:30:20 +05301307 pWifiIfaceStat->beaconRx,
1308 pWifiIfaceStat->mgmtRx,
1309 pWifiIfaceStat->mgmtActionRx,
1310 pWifiIfaceStat->mgmtActionTx,
1311 pWifiIfaceStat->rssiMgmt,
1312 pWifiIfaceStat->rssiData,
1313 pWifiIfaceStat->rssiAck );
1314
1315
1316 {
1317 int i;
1318 for (i = 0 ; i < WIFI_AC_MAX; i ++)
1319 {
1320 hddLog(VOS_TRACE_LEVEL_INFO,
1321
1322 " %d) LL_STATS IFACE: "
1323 " ac: %u txMpdu: %u "
1324 " rxMpdu: %u txMcast: %u "
1325 " rxMcast: %u rxAmpdu: %u "
1326 " txAmpdu: %u mpduLost: %u "
1327 " retries: %u retriesShort: %u "
1328 " retriesLong: %u contentionTimeMin: %u "
1329 " contentionTimeMax: %u contentionTimeAvg: %u "
1330 " contentionNumSamples: %u",
1331 i,
1332 pWifiIfaceStat->AccessclassStats[i].ac,
1333 pWifiIfaceStat->AccessclassStats[i].txMpdu,
1334 pWifiIfaceStat->AccessclassStats[i].rxMpdu,
1335 pWifiIfaceStat->AccessclassStats[i].txMcast,
1336 pWifiIfaceStat->AccessclassStats[i].rxMcast,
1337 pWifiIfaceStat->AccessclassStats[i].rxAmpdu,
1338 pWifiIfaceStat->AccessclassStats[i].txAmpdu,
1339 pWifiIfaceStat->AccessclassStats[i].mpduLost,
1340 pWifiIfaceStat->AccessclassStats[i].retries,
1341 pWifiIfaceStat->
1342 AccessclassStats[i].retriesShort,
1343 pWifiIfaceStat->AccessclassStats[i].retriesLong,
1344 pWifiIfaceStat->
1345 AccessclassStats[i].contentionTimeMin,
1346 pWifiIfaceStat->
1347 AccessclassStats[i].contentionTimeMax,
1348 pWifiIfaceStat->
1349 AccessclassStats[i].contentionTimeAvg,
1350 pWifiIfaceStat->
1351 AccessclassStats[i].contentionNumSamples);
1352
1353 }
1354 }
1355
Sunil Duttc69bccb2014-05-26 21:30:20 +05301356 cfg80211_vendor_event(vendor_event, GFP_KERNEL);
1357}
1358
1359/*
1360 * hdd_link_layer_process_radio_stats () - This function is called after
1361 * receiving Link Layer Radio statistics from FW.This function converts
1362 * the firmware data to the NL data and sends the same to the kernel/upper
1363 * layers.
1364 */
1365static v_VOID_t hdd_link_layer_process_radio_stats(hdd_adapter_t *pAdapter,
1366 v_VOID_t *pData)
1367{
1368 int status, i;
1369 tpSirWifiRadioStat pWifiRadioStat;
1370 tpSirWifiChannelStats pWifiChannelStats;
1371 struct sk_buff *vendor_event;
1372 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
1373 struct nlattr *chList;
1374
1375 status = wlan_hdd_validate_context(pHddCtx);
1376 if (0 != status)
1377 {
1378 hddLog(VOS_TRACE_LEVEL_ERROR,
1379 FL("HDD context is not valid") );
1380 return;
1381 }
1382 pWifiRadioStat = (tpSirWifiRadioStat) pData;
1383
1384 hddLog(VOS_TRACE_LEVEL_INFO,
1385 "LL_STATS_RADIO"
1386 " radio is %d onTime is %u "
1387 " txTime is %u rxTime is %u "
1388 " onTimeScan is %u onTimeNbd is %u "
Dino Mycle6fb96c12014-06-10 11:52:40 +05301389 " onTimeEXTScan is %u onTimeRoamScan is %u "
Sunil Duttc69bccb2014-05-26 21:30:20 +05301390 " onTimePnoScan is %u onTimeHs20 is %u "
1391 " numChannels is %u",
1392 pWifiRadioStat->radio, pWifiRadioStat->onTime,
1393 pWifiRadioStat->txTime, pWifiRadioStat->rxTime,
1394 pWifiRadioStat->onTimeScan, pWifiRadioStat->onTimeNbd,
Dino Mycle6fb96c12014-06-10 11:52:40 +05301395 pWifiRadioStat->onTimeEXTScan,
Sunil Duttc69bccb2014-05-26 21:30:20 +05301396 pWifiRadioStat->onTimeRoamScan,
1397 pWifiRadioStat->onTimePnoScan,
1398 pWifiRadioStat->onTimeHs20,
1399 pWifiRadioStat->numChannels);
1400 /*
1401 * Allocate a size of 4096 for the Radio stats comprising
1402 * sizeof (tSirWifiRadioStat) + numChannels * sizeof
1403 * (tSirWifiChannelStats).Each channel data is put with an
1404 * NL attribute.The size of 4096 is considered assuming that
1405 * number of channels shall not exceed beyond 60 with the
1406 * sizeof (tSirWifiChannelStats) being 24 bytes.
1407 */
1408
1409 vendor_event = cfg80211_vendor_event_alloc(pHddCtx->wiphy,
1410 LL_STATS_EVENT_BUF_SIZE + NLMSG_HDRLEN ,
1411 QCA_NL80211_VENDOR_SUBCMD_LL_RADIO_STATS_INDEX,
1412 GFP_KERNEL);
1413
1414 if (!vendor_event)
1415 {
1416 hddLog(VOS_TRACE_LEVEL_ERROR,
1417 FL("cfg80211_vendor_event_alloc failed") );
1418 return;
1419 }
1420
1421 if (nla_put_u32(vendor_event,
1422 QCA_WLAN_VENDOR_ATTR_LL_STATS_RADIO_ID,
1423 pWifiRadioStat->radio) ||
1424 nla_put_u32(vendor_event,
1425 QCA_WLAN_VENDOR_ATTR_LL_STATS_RADIO_ON_TIME,
1426 pWifiRadioStat->onTime) ||
1427 nla_put_u32(vendor_event,
1428 QCA_WLAN_VENDOR_ATTR_LL_STATS_RADIO_TX_TIME,
1429 pWifiRadioStat->txTime) ||
1430 nla_put_u32(vendor_event,
1431 QCA_WLAN_VENDOR_ATTR_LL_STATS_RADIO_RX_TIME,
1432 pWifiRadioStat->rxTime) ||
1433 nla_put_u32(vendor_event,
1434 QCA_WLAN_VENDOR_ATTR_LL_STATS_RADIO_ON_TIME_SCAN,
1435 pWifiRadioStat->onTimeScan) ||
1436 nla_put_u32(vendor_event,
1437 QCA_WLAN_VENDOR_ATTR_LL_STATS_RADIO_ON_TIME_NBD,
1438 pWifiRadioStat->onTimeNbd) ||
1439 nla_put_u32(vendor_event,
Dino Mycle6fb96c12014-06-10 11:52:40 +05301440 QCA_WLAN_VENDOR_ATTR_LL_STATS_RADIO_ON_TIME_EXTSCAN,
1441 pWifiRadioStat->onTimeEXTScan)||
Sunil Duttc69bccb2014-05-26 21:30:20 +05301442 nla_put_u32(vendor_event,
1443 QCA_WLAN_VENDOR_ATTR_LL_STATS_RADIO_ON_TIME_ROAM_SCAN,
1444 pWifiRadioStat->onTimeRoamScan) ||
1445 nla_put_u32(vendor_event,
1446 QCA_WLAN_VENDOR_ATTR_LL_STATS_RADIO_ON_TIME_PNO_SCAN,
1447 pWifiRadioStat->onTimePnoScan) ||
1448 nla_put_u32(vendor_event,
1449 QCA_WLAN_VENDOR_ATTR_LL_STATS_RADIO_ON_TIME_HS20,
1450 pWifiRadioStat->onTimeHs20) ||
1451 nla_put_u32(vendor_event,
1452 QCA_WLAN_VENDOR_ATTR_LL_STATS_RADIO_NUM_CHANNELS,
1453 pWifiRadioStat->numChannels))
1454 {
1455 hddLog(VOS_TRACE_LEVEL_ERROR,
1456 FL("QCA_WLAN_VENDOR_ATTR put fail"));
1457 kfree_skb(vendor_event);
1458 return ;
1459 }
1460
1461 chList = nla_nest_start(vendor_event,
1462 QCA_WLAN_VENDOR_ATTR_LL_STATS_CH_INFO);
1463 for (i = 0; i < pWifiRadioStat->numChannels; i++)
1464 {
1465 struct nlattr *chInfo;
1466
1467 pWifiChannelStats = (tpSirWifiChannelStats) ((uint8*)
1468 pWifiRadioStat->channels +
1469 (i * sizeof(tSirWifiChannelStats)));
1470
1471 hddLog(VOS_TRACE_LEVEL_INFO,
1472 " %d) Channel Info"
1473 " width is %u "
1474 " CenterFreq %u "
1475 " CenterFreq0 %u "
1476 " CenterFreq1 %u "
1477 " onTime %u "
1478 " ccaBusyTime %u",
1479 i,
1480 pWifiChannelStats->channel.width,
1481 pWifiChannelStats->channel.centerFreq,
1482 pWifiChannelStats->channel.centerFreq0,
1483 pWifiChannelStats->channel.centerFreq1,
1484 pWifiChannelStats->onTime,
1485 pWifiChannelStats->ccaBusyTime);
1486
1487
1488 chInfo = nla_nest_start(vendor_event, i);
1489
1490 if (nla_put_u32(vendor_event,
1491 QCA_WLAN_VENDOR_ATTR_LL_STATS_CHANNEL_INFO_WIDTH,
1492 pWifiChannelStats->channel.width) ||
1493 nla_put_u32(vendor_event,
1494 QCA_WLAN_VENDOR_ATTR_LL_STATS_CHANNEL_INFO_CENTER_FREQ,
1495 pWifiChannelStats->channel.centerFreq) ||
1496 nla_put_u32(vendor_event,
1497 QCA_WLAN_VENDOR_ATTR_LL_STATS_CHANNEL_INFO_CENTER_FREQ0,
1498 pWifiChannelStats->channel.centerFreq0) ||
1499 nla_put_u32(vendor_event,
1500 QCA_WLAN_VENDOR_ATTR_LL_STATS_CHANNEL_INFO_CENTER_FREQ1,
1501 pWifiChannelStats->channel.centerFreq1) ||
1502 nla_put_u32(vendor_event,
1503 QCA_WLAN_VENDOR_ATTR_LL_STATS_CHANNEL_ON_TIME,
1504 pWifiChannelStats->onTime) ||
1505 nla_put_u32(vendor_event,
1506 QCA_WLAN_VENDOR_ATTR_LL_STATS_CHANNEL_CCA_BUSY_TIME,
1507 pWifiChannelStats->ccaBusyTime))
1508 {
1509 hddLog(VOS_TRACE_LEVEL_ERROR,
1510 FL("cfg80211_vendor_event_alloc failed") );
1511 kfree_skb(vendor_event);
1512 return ;
1513 }
1514 nla_nest_end(vendor_event, chInfo);
1515 }
1516 nla_nest_end(vendor_event, chList);
1517
1518 cfg80211_vendor_event(vendor_event, GFP_KERNEL);
1519 return;
1520}
1521
1522/*
1523 * hdd_link_layer_stats_ind_callback () - This function is called after
1524 * receiving Link Layer indications from FW.This callback converts the firmware
1525 * data to the NL data and send the same to the kernel/upper layers.
1526 */
1527static void hdd_link_layer_stats_ind_callback ( void *pCtx,
1528 int indType,
Dino Mycled3d50022014-07-07 12:58:25 +05301529 void *pRsp, u8 *macAddr)
Sunil Duttc69bccb2014-05-26 21:30:20 +05301530{
Dino Mycled3d50022014-07-07 12:58:25 +05301531 hdd_context_t *pHddCtx = (hdd_context_t *)pCtx;
1532 hdd_adapter_t *pAdapter = NULL;
1533 tpSirLLStatsResults linkLayerStatsResults = (tpSirLLStatsResults)pRsp;
Sunil Duttc69bccb2014-05-26 21:30:20 +05301534 int status;
1535
1536 status = wlan_hdd_validate_context(pHddCtx);
1537
1538 if (0 != status)
1539 {
1540 hddLog(VOS_TRACE_LEVEL_ERROR,
1541 FL("HDD context is not valid"));
1542 return;
1543 }
1544
Dino Mycled3d50022014-07-07 12:58:25 +05301545
1546
1547 pAdapter = hdd_get_adapter_by_macaddr(pHddCtx, macAddr);
1548 if (NULL == pAdapter)
1549 {
1550 hddLog(VOS_TRACE_LEVEL_ERROR,
1551 FL(" MAC address %pM does not exist with host"),
1552 macAddr);
1553 return;
1554 }
1555
Sunil Duttc69bccb2014-05-26 21:30:20 +05301556 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Dino Mycled3d50022014-07-07 12:58:25 +05301557 "%s: Interface: %s LLStats indType: %d", __func__,
1558 pAdapter->dev->name, indType);
1559
Sunil Duttc69bccb2014-05-26 21:30:20 +05301560 switch (indType)
1561 {
1562 case SIR_HAL_LL_STATS_RESULTS_RSP:
1563 {
Sunil Duttc69bccb2014-05-26 21:30:20 +05301564 hddLog(VOS_TRACE_LEVEL_INFO,
1565 FL("RESPONSE SIR_HAL_LL_STATS_RESULTS_RSP") );
1566 hddLog(VOS_TRACE_LEVEL_INFO,
1567 "LL_STATS RESULTS RESPONSE paramID = 0x%x",
1568 linkLayerStatsResults->paramId);
1569 hddLog(VOS_TRACE_LEVEL_INFO,
Dino Mycled3d50022014-07-07 12:58:25 +05301570 "LL_STATS RESULTS RESPONSE ifaceId = %u MAC: %pM",
1571 linkLayerStatsResults->ifaceId, macAddr);
Sunil Duttc69bccb2014-05-26 21:30:20 +05301572 hddLog(VOS_TRACE_LEVEL_INFO,
1573 "LL_STATS RESULTS RESPONSE respId = %u",
1574 linkLayerStatsResults->respId);
1575 hddLog(VOS_TRACE_LEVEL_INFO,
1576 "LL_STATS RESULTS RESPONSE moreResultToFollow = %u",
1577 linkLayerStatsResults->moreResultToFollow);
1578 hddLog(VOS_TRACE_LEVEL_INFO,
1579 "LL_STATS RESULTS RESPONSE result = %p",
1580 linkLayerStatsResults->result);
1581 if ( linkLayerStatsResults->paramId & WMI_LINK_STATS_RADIO )
1582 {
1583 hdd_link_layer_process_radio_stats(pAdapter,
1584 (v_VOID_t *)linkLayerStatsResults->result);
1585 }
1586 else if ( linkLayerStatsResults->paramId & WMI_LINK_STATS_IFACE )
1587 {
1588 hdd_link_layer_process_iface_stats(pAdapter,
1589 (v_VOID_t *)linkLayerStatsResults->result);
1590 }
1591 else if ( linkLayerStatsResults->paramId &
1592 WMI_LINK_STATS_ALL_PEER )
1593 {
1594 hdd_link_layer_process_peer_stats(pAdapter,
1595 (v_VOID_t *)linkLayerStatsResults->result);
1596 } /* WMI_LINK_STATS_ALL_PEER */
1597 else
1598 {
1599 hddLog(VOS_TRACE_LEVEL_ERROR,
1600 FL("INVALID LL_STATS_NOTIFY RESPONSE ***********"));
1601 }
1602
1603 break;
1604 }
1605 default:
1606 hddLog(VOS_TRACE_LEVEL_ERROR, "invalid event type %d", indType);
1607 break;
1608 }
1609 return;
1610}
1611
1612const struct
1613nla_policy
1614qca_wlan_vendor_ll_set_policy[QCA_WLAN_VENDOR_ATTR_LL_STATS_SET_MAX +1] =
1615{
1616 [QCA_WLAN_VENDOR_ATTR_LL_STATS_SET_CONFIG_MPDU_SIZE_THRESHOLD] =
1617 { .type = NLA_U32 },
1618 [QCA_WLAN_VENDOR_ATTR_LL_STATS_SET_CONFIG_AGGRESSIVE_STATS_GATHERING] =
1619 { .type = NLA_U32 },
1620};
1621
1622static int wlan_hdd_cfg80211_ll_stats_set(struct wiphy *wiphy,
1623 struct wireless_dev *wdev,
1624 void *data,
1625 int data_len)
1626{
1627 int status;
1628 struct nlattr *tb_vendor[QCA_WLAN_VENDOR_ATTR_LL_STATS_SET_MAX + 1];
Dino Mycledf0a5d92014-07-04 09:41:55 +05301629 tSirLLStatsSetReq linkLayerStatsSetReq;
Sunil Duttc69bccb2014-05-26 21:30:20 +05301630 struct net_device *dev = wdev->netdev;
1631 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
1632 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
1633
1634 status = wlan_hdd_validate_context(pHddCtx);
1635 if (0 != status)
1636 {
1637 hddLog(VOS_TRACE_LEVEL_ERROR,
1638 FL("HDD context is not valid"));
1639 return -EINVAL;
1640 }
1641
1642 if (NULL == pAdapter)
1643 {
1644 hddLog(VOS_TRACE_LEVEL_ERROR,
1645 FL("HDD adapter is Null"));
1646 return -ENODEV;
1647 }
Dino Mycledf0a5d92014-07-04 09:41:55 +05301648 /* check the LLStats Capability */
1649 if ( (TRUE != pHddCtx->cfg_ini->fEnableLLStats) ||
1650 (TRUE != sme_IsFeatureSupportedByFW(LINK_LAYER_STATS_MEAS)))
1651 {
1652 hddLog(VOS_TRACE_LEVEL_ERROR,
1653 FL("Link Layer Statistics not supported by Firmware"));
1654 return -EINVAL;
1655 }
Sunil Duttc69bccb2014-05-26 21:30:20 +05301656
1657 if (nla_parse(tb_vendor, QCA_WLAN_VENDOR_ATTR_LL_STATS_SET_MAX,
1658 (struct nlattr *)data,
1659 data_len, qca_wlan_vendor_ll_set_policy))
1660 {
1661 hddLog(VOS_TRACE_LEVEL_ERROR, FL() );
1662 return -EINVAL;
1663 }
1664 if (!tb_vendor
1665 [QCA_WLAN_VENDOR_ATTR_LL_STATS_SET_CONFIG_MPDU_SIZE_THRESHOLD])
1666 {
1667 hddLog(VOS_TRACE_LEVEL_ERROR, FL("MPDU size Not present"));
1668 return -EINVAL;
1669 }
1670 if (!tb_vendor[
1671 QCA_WLAN_VENDOR_ATTR_LL_STATS_SET_CONFIG_AGGRESSIVE_STATS_GATHERING])
1672 {
1673 hddLog(VOS_TRACE_LEVEL_ERROR, FL(" Stats Gathering Not Present"));
1674 return -EINVAL;
1675 }
Sunil Duttc69bccb2014-05-26 21:30:20 +05301676 // Shall take the request Id if the Upper layers pass. 1 For now.
Dino Mycledf0a5d92014-07-04 09:41:55 +05301677 linkLayerStatsSetReq.reqId = 1;
Sunil Duttc69bccb2014-05-26 21:30:20 +05301678
Dino Mycledf0a5d92014-07-04 09:41:55 +05301679 linkLayerStatsSetReq.mpduSizeThreshold =
Sunil Duttc69bccb2014-05-26 21:30:20 +05301680 nla_get_u32(
1681 tb_vendor[QCA_WLAN_VENDOR_ATTR_LL_STATS_SET_CONFIG_MPDU_SIZE_THRESHOLD]);
1682
Dino Mycledf0a5d92014-07-04 09:41:55 +05301683 linkLayerStatsSetReq.aggressiveStatisticsGathering =
Sunil Duttc69bccb2014-05-26 21:30:20 +05301684 nla_get_u32(
1685 tb_vendor[QCA_WLAN_VENDOR_ATTR_LL_STATS_SET_CONFIG_AGGRESSIVE_STATS_GATHERING]);
1686
Dino Mycled3d50022014-07-07 12:58:25 +05301687 vos_mem_copy(linkLayerStatsSetReq.macAddr,
1688 pAdapter->macAddressCurrent.bytes, sizeof(v_MACADDR_t));
Sunil Duttc69bccb2014-05-26 21:30:20 +05301689
1690
1691 hddLog(VOS_TRACE_LEVEL_INFO,
Dino Mycled3d50022014-07-07 12:58:25 +05301692 "LL_STATS_SET reqId = %d", linkLayerStatsSetReq.reqId);
Sunil Duttc69bccb2014-05-26 21:30:20 +05301693 hddLog(VOS_TRACE_LEVEL_INFO,
Dino Mycled3d50022014-07-07 12:58:25 +05301694 "LL_STATS_SET MAC = %pM", linkLayerStatsSetReq.macAddr);
Sunil Duttc69bccb2014-05-26 21:30:20 +05301695 hddLog(VOS_TRACE_LEVEL_INFO,
1696 "LL_STATS_SET mpduSizeThreshold = %d",
Dino Mycledf0a5d92014-07-04 09:41:55 +05301697 linkLayerStatsSetReq.mpduSizeThreshold);
Sunil Duttc69bccb2014-05-26 21:30:20 +05301698 hddLog(VOS_TRACE_LEVEL_INFO,
1699 "LL_STATS_SET aggressive Statistics Gathering = %d",
Dino Mycledf0a5d92014-07-04 09:41:55 +05301700 linkLayerStatsSetReq.aggressiveStatisticsGathering);
Sunil Duttc69bccb2014-05-26 21:30:20 +05301701
1702 if (eHAL_STATUS_SUCCESS != sme_SetLinkLayerStatsIndCB(
1703 pHddCtx->hHal,
Dino Mycled3d50022014-07-07 12:58:25 +05301704 hdd_link_layer_stats_ind_callback))
Sunil Duttc69bccb2014-05-26 21:30:20 +05301705 {
1706 hddLog(VOS_TRACE_LEVEL_ERROR, "%s:"
1707 "sme_SetLinkLayerStatsIndCB Failed", __func__);
Sunil Duttc69bccb2014-05-26 21:30:20 +05301708 return -EINVAL;
1709
1710 }
1711 if (eHAL_STATUS_SUCCESS != sme_LLStatsSetReq( pHddCtx->hHal,
Dino Mycledf0a5d92014-07-04 09:41:55 +05301712 &linkLayerStatsSetReq))
Sunil Duttc69bccb2014-05-26 21:30:20 +05301713 {
1714 hddLog(VOS_TRACE_LEVEL_ERROR, "%s:"
1715 "sme_LLStatsSetReq Failed", __func__);
Sunil Duttc69bccb2014-05-26 21:30:20 +05301716 return -EINVAL;
1717 }
1718
1719 pAdapter->isLinkLayerStatsSet = 1;
1720
1721 return 0;
1722}
1723
1724const struct
1725nla_policy
1726qca_wlan_vendor_ll_get_policy[QCA_WLAN_VENDOR_ATTR_LL_STATS_GET_MAX +1] =
1727{
1728 /* Unsigned 32bit value provided by the caller issuing the GET stats
1729 * command. When reporting
1730 * the stats results, the driver uses the same value to indicate
1731 * which GET request the results
1732 * correspond to.
1733 */
1734 [QCA_WLAN_VENDOR_ATTR_LL_STATS_GET_CONFIG_REQ_ID] = { .type = NLA_U32 },
1735
1736 /* Unsigned 32bit value . bit mask to identify what statistics are
1737 requested for retrieval */
1738 [QCA_WLAN_VENDOR_ATTR_LL_STATS_GET_CONFIG_REQ_MASK] = { .type = NLA_U32 },
1739};
1740
1741static int wlan_hdd_cfg80211_ll_stats_get(struct wiphy *wiphy,
1742 struct wireless_dev *wdev,
1743 void *data,
1744 int data_len)
1745{
1746 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
1747 struct nlattr *tb_vendor[QCA_WLAN_VENDOR_ATTR_LL_STATS_GET_MAX + 1];
Dino Mycledf0a5d92014-07-04 09:41:55 +05301748 tSirLLStatsGetReq linkLayerStatsGetReq;
Sunil Duttc69bccb2014-05-26 21:30:20 +05301749 struct net_device *dev = wdev->netdev;
1750 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
1751 int status;
1752
1753 status = wlan_hdd_validate_context(pHddCtx);
1754 if (0 != status)
1755 {
1756 hddLog(VOS_TRACE_LEVEL_ERROR,
1757 FL("HDD context is not valid"));
1758 return -EINVAL ;
1759 }
1760
1761 if (NULL == pAdapter)
1762 {
1763 hddLog(VOS_TRACE_LEVEL_FATAL,
1764 "%s: HDD adapter is Null", __func__);
1765 return -ENODEV;
1766 }
Dino Mycledf0a5d92014-07-04 09:41:55 +05301767 /* check the LLStats Capability */
1768 if ( (TRUE != pHddCtx->cfg_ini->fEnableLLStats) ||
1769 (TRUE != sme_IsFeatureSupportedByFW(LINK_LAYER_STATS_MEAS)))
1770 {
1771 hddLog(VOS_TRACE_LEVEL_ERROR,
1772 FL("Link Layer Statistics not supported by Firmware"));
1773 return -EINVAL;
1774 }
1775
Sunil Duttc69bccb2014-05-26 21:30:20 +05301776
1777 if (!pAdapter->isLinkLayerStatsSet)
1778 {
1779 hddLog(VOS_TRACE_LEVEL_FATAL,
1780 "%s: isLinkLayerStatsSet : %d",
1781 __func__, pAdapter->isLinkLayerStatsSet);
1782 return -EINVAL;
1783 }
1784
1785 if (nla_parse(tb_vendor, QCA_WLAN_VENDOR_ATTR_LL_STATS_GET_MAX,
1786 (struct nlattr *)data,
1787 data_len, qca_wlan_vendor_ll_get_policy))
1788 {
1789 hddLog(VOS_TRACE_LEVEL_ERROR, FL() );
1790 return -EINVAL;
1791 }
1792
1793 if (!tb_vendor
1794 [QCA_WLAN_VENDOR_ATTR_LL_STATS_GET_CONFIG_REQ_ID])
1795 {
1796 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Request Id Not present"));
1797 return -EINVAL;
1798 }
1799
1800 if (!tb_vendor
1801 [QCA_WLAN_VENDOR_ATTR_LL_STATS_GET_CONFIG_REQ_MASK])
1802 {
1803 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Req Mask Not present"));
1804 return -EINVAL;
1805 }
1806
Sunil Duttc69bccb2014-05-26 21:30:20 +05301807
Dino Mycledf0a5d92014-07-04 09:41:55 +05301808 linkLayerStatsGetReq.reqId =
Sunil Duttc69bccb2014-05-26 21:30:20 +05301809 nla_get_u32( tb_vendor[
1810 QCA_WLAN_VENDOR_ATTR_LL_STATS_GET_CONFIG_REQ_ID]);
Dino Mycledf0a5d92014-07-04 09:41:55 +05301811 linkLayerStatsGetReq.paramIdMask =
Sunil Duttc69bccb2014-05-26 21:30:20 +05301812 nla_get_u32( tb_vendor[
1813 QCA_WLAN_VENDOR_ATTR_LL_STATS_GET_CONFIG_REQ_MASK]);
1814
Dino Mycled3d50022014-07-07 12:58:25 +05301815 vos_mem_copy(linkLayerStatsGetReq.macAddr,
1816 pAdapter->macAddressCurrent.bytes, sizeof(v_MACADDR_t));
Sunil Duttc69bccb2014-05-26 21:30:20 +05301817
1818 hddLog(VOS_TRACE_LEVEL_INFO,
Dino Mycledf0a5d92014-07-04 09:41:55 +05301819 "LL_STATS_GET reqId = %d", linkLayerStatsGetReq.reqId);
Sunil Duttc69bccb2014-05-26 21:30:20 +05301820 hddLog(VOS_TRACE_LEVEL_INFO,
Dino Mycled3d50022014-07-07 12:58:25 +05301821 "LL_STATS_GET MAC = %pM", linkLayerStatsGetReq.macAddr);
Sunil Duttc69bccb2014-05-26 21:30:20 +05301822 hddLog(VOS_TRACE_LEVEL_INFO,
1823 "LL_STATS_GET paramIdMask = %d",
Dino Mycledf0a5d92014-07-04 09:41:55 +05301824 linkLayerStatsGetReq.paramIdMask);
Sunil Duttc69bccb2014-05-26 21:30:20 +05301825
1826 if (eHAL_STATUS_SUCCESS != sme_LLStatsGetReq( pHddCtx->hHal,
Dino Mycledf0a5d92014-07-04 09:41:55 +05301827 &linkLayerStatsGetReq))
Sunil Duttc69bccb2014-05-26 21:30:20 +05301828 {
1829 hddLog(VOS_TRACE_LEVEL_ERROR, "%s:"
1830 "sme_LLStatsGetReq Failed", __func__);
Sunil Duttc69bccb2014-05-26 21:30:20 +05301831 return -EINVAL;
1832 }
1833 return 0;
1834}
1835
1836const struct
1837nla_policy
1838qca_wlan_vendor_ll_clr_policy[QCA_WLAN_VENDOR_ATTR_LL_STATS_CLR_MAX +1] =
1839{
1840 [QCA_WLAN_VENDOR_ATTR_LL_STATS_CLR_CONFIG_REQ_MASK] = {.type = NLA_U32 },
1841 [QCA_WLAN_VENDOR_ATTR_LL_STATS_CLR_CONFIG_STOP_REQ] = {.type = NLA_U8 },
1842 [QCA_WLAN_VENDOR_ATTR_LL_STATS_CLR_CONFIG_RSP_MASK] = {.type = NLA_U32 },
1843 [QCA_WLAN_VENDOR_ATTR_LL_STATS_CLR_CONFIG_STOP_RSP] = {.type = NLA_U8 },
1844};
1845
1846static int wlan_hdd_cfg80211_ll_stats_clear(struct wiphy *wiphy,
1847 struct wireless_dev *wdev,
1848 void *data,
1849 int data_len)
1850{
1851 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
1852 struct nlattr *tb_vendor[QCA_WLAN_VENDOR_ATTR_LL_STATS_CLR_MAX + 1];
Dino Mycledf0a5d92014-07-04 09:41:55 +05301853 tSirLLStatsClearReq linkLayerStatsClearReq;
Sunil Duttc69bccb2014-05-26 21:30:20 +05301854 struct net_device *dev = wdev->netdev;
1855 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
1856 u32 statsClearReqMask;
1857 u8 stopReq;
1858 int status;
1859
1860 status = wlan_hdd_validate_context(pHddCtx);
1861 if (0 != status)
1862 {
1863 hddLog(VOS_TRACE_LEVEL_ERROR,
1864 FL("HDD context is not valid"));
1865 return -EINVAL;
1866 }
1867
1868 if (NULL == pAdapter)
1869 {
1870 hddLog(VOS_TRACE_LEVEL_FATAL,
1871 "%s: HDD adapter is Null", __func__);
1872 return -ENODEV;
1873 }
Dino Mycledf0a5d92014-07-04 09:41:55 +05301874 /* check the LLStats Capability */
1875 if ( (TRUE != pHddCtx->cfg_ini->fEnableLLStats) ||
1876 (TRUE != sme_IsFeatureSupportedByFW(LINK_LAYER_STATS_MEAS)))
1877 {
1878 hddLog(VOS_TRACE_LEVEL_ERROR,
1879 FL("Enable LLStats Capability"));
1880 return -EINVAL;
1881 }
Sunil Duttc69bccb2014-05-26 21:30:20 +05301882
1883 if (!pAdapter->isLinkLayerStatsSet)
1884 {
1885 hddLog(VOS_TRACE_LEVEL_FATAL,
1886 "%s: isLinkLayerStatsSet : %d",
1887 __func__, pAdapter->isLinkLayerStatsSet);
1888 return -EINVAL;
1889 }
1890
1891 if (nla_parse(tb_vendor, QCA_WLAN_VENDOR_ATTR_LL_STATS_CLR_MAX,
1892 (struct nlattr *)data,
1893 data_len, qca_wlan_vendor_ll_clr_policy))
1894 {
1895 hddLog(VOS_TRACE_LEVEL_ERROR, FL() );
1896 return -EINVAL;
1897 }
1898
1899 if (!tb_vendor[QCA_WLAN_VENDOR_ATTR_LL_STATS_CLR_CONFIG_REQ_MASK] ||
1900
1901 !tb_vendor[QCA_WLAN_VENDOR_ATTR_LL_STATS_CLR_CONFIG_STOP_REQ])
1902 {
1903 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Error in LL_STATS CLR CONFIG PARA") );
1904 return -EINVAL;
1905
1906 }
1907
Sunil Duttc69bccb2014-05-26 21:30:20 +05301908
Dino Mycledf0a5d92014-07-04 09:41:55 +05301909 statsClearReqMask = linkLayerStatsClearReq.statsClearReqMask =
Sunil Duttc69bccb2014-05-26 21:30:20 +05301910 nla_get_u32(
1911 tb_vendor[QCA_WLAN_VENDOR_ATTR_LL_STATS_CLR_CONFIG_REQ_MASK]);
1912
Dino Mycledf0a5d92014-07-04 09:41:55 +05301913 stopReq = linkLayerStatsClearReq.stopReq =
Sunil Duttc69bccb2014-05-26 21:30:20 +05301914 nla_get_u8(
1915 tb_vendor[QCA_WLAN_VENDOR_ATTR_LL_STATS_CLR_CONFIG_STOP_REQ]);
1916
1917 // Shall take the request Id if the Upper layers pass. 1 For now.
Dino Mycledf0a5d92014-07-04 09:41:55 +05301918 linkLayerStatsClearReq.reqId = 1;
Sunil Duttc69bccb2014-05-26 21:30:20 +05301919
Dino Mycled3d50022014-07-07 12:58:25 +05301920 vos_mem_copy(linkLayerStatsClearReq.macAddr,
1921 pAdapter->macAddressCurrent.bytes, sizeof(v_MACADDR_t));
Sunil Duttc69bccb2014-05-26 21:30:20 +05301922
1923 hddLog(VOS_TRACE_LEVEL_INFO,
Dino Mycledf0a5d92014-07-04 09:41:55 +05301924 "LL_STATS_CLEAR reqId = %d", linkLayerStatsClearReq.reqId);
Sunil Duttc69bccb2014-05-26 21:30:20 +05301925 hddLog(VOS_TRACE_LEVEL_INFO,
Dino Mycled3d50022014-07-07 12:58:25 +05301926 "LL_STATS_CLEAR MAC = %pM", linkLayerStatsClearReq.macAddr);
Sunil Duttc69bccb2014-05-26 21:30:20 +05301927 hddLog(VOS_TRACE_LEVEL_INFO,
1928 "LL_STATS_CLEAR statsClearReqMask = 0x%X",
Dino Mycledf0a5d92014-07-04 09:41:55 +05301929 linkLayerStatsClearReq.statsClearReqMask);
Sunil Duttc69bccb2014-05-26 21:30:20 +05301930 hddLog(VOS_TRACE_LEVEL_INFO,
1931 "LL_STATS_CLEAR stopReq = %d",
Dino Mycledf0a5d92014-07-04 09:41:55 +05301932 linkLayerStatsClearReq.stopReq);
Sunil Duttc69bccb2014-05-26 21:30:20 +05301933
1934 if (eHAL_STATUS_SUCCESS == sme_LLStatsClearReq(pHddCtx->hHal,
Dino Mycledf0a5d92014-07-04 09:41:55 +05301935 &linkLayerStatsClearReq))
Sunil Duttc69bccb2014-05-26 21:30:20 +05301936 {
1937 struct sk_buff *temp_skbuff;
1938 temp_skbuff = cfg80211_vendor_cmd_alloc_reply_skb(wiphy,
1939 2 * sizeof(u32) +
1940 NLMSG_HDRLEN);
1941
1942 if (temp_skbuff != NULL)
1943 {
1944
1945 if (nla_put_u32(temp_skbuff,
1946 QCA_WLAN_VENDOR_ATTR_LL_STATS_CLR_CONFIG_RSP_MASK,
1947 statsClearReqMask) ||
1948 nla_put_u32(temp_skbuff,
1949 QCA_WLAN_VENDOR_ATTR_LL_STATS_CLR_CONFIG_STOP_RSP,
1950 stopReq))
1951 {
1952 hddLog(VOS_TRACE_LEVEL_ERROR, FL("LL_STATS_CLR put fail"));
1953 kfree_skb(temp_skbuff);
1954 return -EINVAL;
1955 }
1956 /* If the ask is to stop the stats collection as part of clear
1957 * (stopReq = 1) , ensure that no further requests of get
1958 * go to the firmware by having isLinkLayerStatsSet set to 0.
1959 * However it the stopReq as part of the clear request is 0 ,
Dino Mycledf0a5d92014-07-04 09:41:55 +05301960 * the request to get the statistics are honoured as in this
Sunil Duttc69bccb2014-05-26 21:30:20 +05301961 * case the firmware is just asked to clear the statistics.
1962 */
Dino Mycledf0a5d92014-07-04 09:41:55 +05301963 if (linkLayerStatsClearReq.stopReq == 1)
Sunil Duttc69bccb2014-05-26 21:30:20 +05301964 pAdapter->isLinkLayerStatsSet = 0;
1965 return cfg80211_vendor_cmd_reply(temp_skbuff);
1966 }
1967 return -ENOMEM;
1968 }
Sunil Duttc69bccb2014-05-26 21:30:20 +05301969 return -EINVAL;
1970}
1971#endif /* WLAN_FEATURE_LINK_LAYER_STATS */
1972
Dino Mycle6fb96c12014-06-10 11:52:40 +05301973#ifdef WLAN_FEATURE_EXTSCAN
1974static const struct nla_policy
1975wlan_hdd_extscan_config_policy
1976 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX + 1] =
1977{
1978 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_REQUEST_ID] =
1979 { .type = NLA_U32 },
1980 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_GET_VALID_CHANNELS_CONFIG_PARAM_WIFI_BAND] =
1981 { .type = NLA_U32 },
1982 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_CHANNEL_SPEC_CHANNEL] = { .type = NLA_U32 },
1983 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_CHANNEL_SPEC_DWELL_TIME] =
1984 { .type = NLA_U32 },
1985 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_CHANNEL_SPEC_PASSIVE] = { .type = NLA_U8 },
1986 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_CHANNEL_SPEC_CLASS] = { .type = NLA_U8 },
1987
1988 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_INDEX] = { .type = NLA_U8 },
1989 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_BAND] = { .type = NLA_U8 },
1990 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_PERIOD] = { .type = NLA_U32 },
1991 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_REPORT_EVENTS] =
1992 { .type = NLA_U8 },
1993 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_NUM_CHANNEL_SPECS] =
1994 { .type = NLA_U32 },
1995 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_SCAN_CMD_PARAMS_BASE_PERIOD] =
1996 { .type = NLA_U32 },
1997 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_SCAN_CMD_PARAMS_MAX_AP_PER_SCAN] =
1998 { .type = NLA_U32 },
1999 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_SCAN_CMD_PARAMS_REPORT_THRESHOLD] =
2000 { .type = NLA_U8 },
2001 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_SCAN_CMD_PARAMS_NUM_BUCKETS] =
2002 { .type = NLA_U8 },
2003 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_GET_CACHED_SCAN_RESULTS_CONFIG_PARAM_FLUSH] =
2004 { .type = NLA_U8 },
2005
2006 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_GET_CACHED_SCAN_RESULTS_CONFIG_PARAM_MAX] =
2007 { .type = NLA_U32 },
2008 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_AP_THRESHOLD_PARAM_BSSID] =
2009 { .type = NLA_UNSPEC },
2010 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_AP_THRESHOLD_PARAM_RSSI_LOW] =
2011 { .type = NLA_S32 },
2012 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_AP_THRESHOLD_PARAM_RSSI_HIGH] =
2013 { .type = NLA_S32 },
2014 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_AP_THRESHOLD_PARAM_CHANNEL] =
2015 { .type = NLA_U32 },
2016 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_BSSID_HOTLIST_PARAMS_NUM_AP] =
2017 { .type = NLA_U32 },
2018 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_SIGNIFICANT_CHANGE_PARAMS_RSSI_SAMPLE_SIZE] =
2019 { .type = NLA_U32 },
2020 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_SIGNIFICANT_CHANGE_PARAMS_LOST_AP_SAMPLE_SIZE]
2021 = { .type = NLA_U32 },
2022 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_SIGNIFICANT_CHANGE_PARAMS_MIN_BREACHING] =
2023 { .type = NLA_U32 },
2024 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_SIGNIFICANT_CHANGE_PARAMS_NUM_AP] = { .type =
2025 NLA_U32 },
2026};
2027
2028static void wlan_hdd_cfg80211_extscan_get_capabilities_ind(void *ctx, void *pMsg)
2029{
2030 hdd_context_t *pHddCtx = (hdd_context_t *)ctx;
2031 struct sk_buff *skb = NULL;
2032 tpSirEXTScanCapabilitiesEvent pData =
2033 (tpSirEXTScanCapabilitiesEvent) pMsg;
2034
2035 if (wlan_hdd_validate_context(pHddCtx) || !pData) {
2036 hddLog(VOS_TRACE_LEVEL_ERROR, FL("HDD context is not valid "
2037 "or pData(%p) is null"), pData);
2038 return;
2039 }
2040
2041 skb = cfg80211_vendor_event_alloc(pHddCtx->wiphy,
2042 EXTSCAN_EVENT_BUF_SIZE + NLMSG_HDRLEN,
2043 QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_GET_CAPABILITIES_INDEX,
2044 GFP_KERNEL);
2045
2046 if (!skb) {
2047 hddLog(VOS_TRACE_LEVEL_ERROR,
2048 FL("cfg80211_vendor_event_alloc failed"));
2049 return;
2050 }
2051
2052 hddLog(VOS_TRACE_LEVEL_INFO, "Req Id (%u)", pData->requestId);
2053 hddLog(VOS_TRACE_LEVEL_INFO, "Scan cache size (%u)", pData->scanCacheSize);
2054 hddLog(VOS_TRACE_LEVEL_INFO, "Scan buckets (%u)", pData->scanBuckets);
2055 hddLog(VOS_TRACE_LEVEL_INFO, "Max AP per scan (%u)", pData->maxApPerScan);
2056 hddLog(VOS_TRACE_LEVEL_INFO, "maxRssiSampleSize (%u)",
2057 pData->maxRssiSampleSize);
2058 hddLog(VOS_TRACE_LEVEL_INFO, "maxScanReportingThreshold (%u)",
2059 pData->maxScanReportingThreshold);
2060 hddLog(VOS_TRACE_LEVEL_INFO, "maxHotlistAPs (%u)", pData->maxHotlistAPs);
2061 hddLog(VOS_TRACE_LEVEL_INFO, "maxSignificantWifiChangeAPs (%u)",
2062 pData->maxSignificantWifiChangeAPs);
2063 hddLog(VOS_TRACE_LEVEL_INFO, "maxBsidHistoryEntries (%u)",
2064 pData->maxBsidHistoryEntries);
2065
2066 if (nla_put_u32(skb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_REQUEST_ID,
2067 pData->requestId) ||
2068 nla_put_u32(skb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_STATUS, pData->status) ||
2069 nla_put_u32(skb,
2070 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_CAPABILITIES_MAX_SCAN_CACHE_SIZE,
2071 pData->scanCacheSize) ||
2072 nla_put_u32(skb,
2073 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_CAPABILITIES_MAX_SCAN_BUCKETS,
2074 pData->scanBuckets) ||
2075 nla_put_u32(skb,
2076 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_CAPABILITIES_MAX_AP_CACHE_PER_SCAN,
2077 pData->maxApPerScan) ||
2078 nla_put_u32(skb,
2079 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_CAPABILITIES_MAX_RSSI_SAMPLE_SIZE,
2080 pData->maxRssiSampleSize) ||
2081 nla_put_u32(skb,
2082 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_CAPABILITIES_MAX_SCAN_REPORTING_THRESHOLD,
2083 pData->maxScanReportingThreshold) ||
2084 nla_put_u32(skb,
2085 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_CAPABILITIES_MAX_HOTLIST_APS,
2086 pData->maxHotlistAPs) ||
2087 nla_put_u32(skb,
2088 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_CAPABILITIES_MAX_SIGNIFICANT_WIFI_CHANGE_APS,
2089 pData->maxSignificantWifiChangeAPs) ||
2090 nla_put_u32(skb,
2091 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_CAPABILITIES_MAX_BSSID_HISTORY_ENTRIES,
2092 pData->maxBsidHistoryEntries)) {
2093 hddLog(VOS_TRACE_LEVEL_ERROR, FL("nla put fail"));
2094 goto nla_put_failure;
2095 }
2096
2097 cfg80211_vendor_event(skb, GFP_KERNEL);
2098 return;
2099
2100nla_put_failure:
2101 kfree_skb(skb);
2102 return;
2103}
2104
2105
2106static void wlan_hdd_cfg80211_extscan_start_rsp(void *ctx, void *pMsg)
2107{
2108 tpSirEXTScanStartRspParams pData = (tpSirEXTScanStartRspParams) pMsg;
2109 hdd_context_t *pHddCtx = (hdd_context_t *)ctx;
2110 struct sk_buff *skb = NULL;
2111 tpAniSirGlobal pMac = PMAC_STRUCT( pHddCtx->hHal );
2112
2113
2114 if (wlan_hdd_validate_context(pHddCtx) || !pData) {
2115 hddLog(VOS_TRACE_LEVEL_ERROR, FL("HDD context is not valid "
2116 "or pData(%p) is null"), pData);
2117 return;
2118 }
2119
2120 skb = cfg80211_vendor_event_alloc(pHddCtx->wiphy,
2121 EXTSCAN_EVENT_BUF_SIZE + NLMSG_HDRLEN,
2122 QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_START_INDEX,
2123 GFP_KERNEL);
2124
2125 if (!skb) {
2126 hddLog(VOS_TRACE_LEVEL_ERROR,
2127 FL("cfg80211_vendor_event_alloc failed"));
2128 return;
2129 }
2130 hddLog(VOS_TRACE_LEVEL_INFO, FL("Entering "));
2131 hddLog(VOS_TRACE_LEVEL_INFO, "Req Id (%u)", pData->requestId);
2132 hddLog(VOS_TRACE_LEVEL_INFO, "Status (%u)", pData->status);
2133
2134 if (nla_put_u32(skb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_REQUEST_ID,
2135 pData->requestId) ||
2136 nla_put_u32(skb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_STATUS, pData->status)) {
2137 hddLog(VOS_TRACE_LEVEL_ERROR, FL("nla put fail"));
2138 goto nla_put_failure;
2139 }
2140
2141 /*
2142 * Store the Request ID for comparing with the requestID obtained
2143 * in other requests.HDD shall return a failure is the extscan_stop
2144 * request is issued with a different requestId as that of the
2145 * extscan_start request. Also, This requestId shall be used while
2146 * indicating the full scan results to the upper layers.
2147 * The requestId is stored with the assumption that the firmware
2148 * shall return the ext scan start request's requestId in ext scan
2149 * start response.
2150 */
2151 if (pData->status == 0)
2152 pMac->sme.extScanStartReqId = pData->requestId;
2153
2154
2155 cfg80211_vendor_event(skb, GFP_KERNEL);
2156 return;
2157
2158nla_put_failure:
2159 kfree_skb(skb);
2160 return;
2161}
2162
2163
2164static void wlan_hdd_cfg80211_extscan_stop_rsp(void *ctx, void *pMsg)
2165{
2166 tpSirEXTScanStopRspParams pData = (tpSirEXTScanStopRspParams) pMsg;
2167 hdd_context_t *pHddCtx = (hdd_context_t *)ctx;
2168 struct sk_buff *skb = NULL;
2169
2170 if (wlan_hdd_validate_context(pHddCtx) || !pData) {
2171 hddLog(VOS_TRACE_LEVEL_ERROR, FL("HDD context is not valid "
2172 "or pData(%p) is null"), pData);
2173 return;
2174 }
2175
2176 skb = cfg80211_vendor_event_alloc(pHddCtx->wiphy,
2177 EXTSCAN_EVENT_BUF_SIZE + NLMSG_HDRLEN,
2178 QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_STOP_INDEX,
2179 GFP_KERNEL);
2180
2181 if (!skb) {
2182 hddLog(VOS_TRACE_LEVEL_ERROR,
2183 FL("cfg80211_vendor_event_alloc failed"));
2184 return;
2185 }
2186 hddLog(VOS_TRACE_LEVEL_INFO, FL("Entering "));
2187 hddLog(VOS_TRACE_LEVEL_INFO, "Req Id (%u)", pData->requestId);
2188
2189 if (nla_put_u32(skb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_REQUEST_ID,
2190 pData->requestId) ||
2191 nla_put_u32(skb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_STATUS, pData->status)) {
2192 hddLog(VOS_TRACE_LEVEL_ERROR, FL("nla put fail"));
2193 goto nla_put_failure;
2194 }
2195
2196 cfg80211_vendor_event(skb, GFP_KERNEL);
2197 return;
2198
2199nla_put_failure:
2200 kfree_skb(skb);
2201 return;
2202}
2203
2204
2205static void wlan_hdd_cfg80211_extscan_set_bss_hotlist_rsp(void *ctx,
2206 void *pMsg)
2207{
2208 hdd_context_t *pHddCtx = (hdd_context_t *)ctx;
2209 struct sk_buff *skb = NULL;
2210 tpSirEXTScanSetBssidHotListRspParams pData =
2211 (tpSirEXTScanSetBssidHotListRspParams) pMsg;
2212
2213 if (wlan_hdd_validate_context(pHddCtx) || !pData) {
2214 hddLog(VOS_TRACE_LEVEL_ERROR, FL("HDD context is not valid "
2215 "or pData(%p) is null"), pData);
2216 return;
2217 }
2218 skb = cfg80211_vendor_event_alloc(pHddCtx->wiphy,
2219 EXTSCAN_EVENT_BUF_SIZE + NLMSG_HDRLEN,
2220 QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_SET_BSSID_HOTLIST_INDEX,
2221 GFP_KERNEL);
2222
2223 if (!skb) {
2224 hddLog(VOS_TRACE_LEVEL_ERROR,
2225 FL("cfg80211_vendor_event_alloc failed"));
2226 return;
2227 }
2228 hddLog(VOS_TRACE_LEVEL_INFO, FL("Entering "));
2229 hddLog(VOS_TRACE_LEVEL_INFO, "Req Id (%u)", pData->requestId);
2230 hddLog(VOS_TRACE_LEVEL_INFO, "Status (%u)", pData->status);
2231
2232 if (nla_put_u32(skb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_REQUEST_ID,
2233 pData->requestId) ||
2234 nla_put_u32(skb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_STATUS, pData->status)) {
2235 hddLog(VOS_TRACE_LEVEL_ERROR, FL("nla put fail"));
2236 goto nla_put_failure;
2237 }
2238
2239 cfg80211_vendor_event(skb, GFP_KERNEL);
2240 return;
2241
2242nla_put_failure:
2243 kfree_skb(skb);
2244 return;
2245}
2246
2247static void wlan_hdd_cfg80211_extscan_reset_bss_hotlist_rsp(void *ctx,
2248 void *pMsg)
2249{
2250 hdd_context_t *pHddCtx = (hdd_context_t *)ctx;
2251 struct sk_buff *skb = NULL;
2252 tpSirEXTScanResetBssidHotlistRspParams pData =
2253 (tpSirEXTScanResetBssidHotlistRspParams) pMsg;
2254
2255 if (wlan_hdd_validate_context(pHddCtx) || !pData) {
2256 hddLog(VOS_TRACE_LEVEL_ERROR, FL("HDD context is not valid "
2257 "or pData(%p) is null"), pData);
2258 return;
2259 }
2260
2261 skb = cfg80211_vendor_event_alloc(pHddCtx->wiphy,
2262 EXTSCAN_EVENT_BUF_SIZE + NLMSG_HDRLEN,
2263 QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_RESET_BSSID_HOTLIST_INDEX,
2264 GFP_KERNEL);
2265
2266 if (!skb) {
2267 hddLog(VOS_TRACE_LEVEL_ERROR,
2268 FL("cfg80211_vendor_event_alloc failed"));
2269 return;
2270 }
2271 hddLog(VOS_TRACE_LEVEL_INFO, FL("Entering "));
2272 hddLog(VOS_TRACE_LEVEL_INFO, "Req Id (%u)", pData->requestId);
2273
2274 if (nla_put_u32(skb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_REQUEST_ID,
2275 pData->requestId) ||
2276 nla_put_u32(skb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_STATUS, pData->status)) {
2277 hddLog(VOS_TRACE_LEVEL_ERROR, FL("nla put fail"));
2278 goto nla_put_failure;
2279 }
2280
2281 cfg80211_vendor_event(skb, GFP_KERNEL);
2282 return;
2283
2284nla_put_failure:
2285 kfree_skb(skb);
2286 return;
2287}
2288
2289
2290static void wlan_hdd_cfg80211_extscan_set_signf_wifi_change_rsp(void *ctx,
2291 void *pMsg)
2292{
2293 hdd_context_t *pHddCtx = (hdd_context_t *)ctx;
2294 struct sk_buff *skb = NULL;
2295 tpSirEXTScanSetSignificantChangeRspParams pData =
2296 (tpSirEXTScanSetSignificantChangeRspParams) pMsg;
2297
2298 if (wlan_hdd_validate_context(pHddCtx) || !pData) {
2299 hddLog(VOS_TRACE_LEVEL_ERROR, FL("HDD context is not valid "
2300 "or pData(%p) is null"), pData);
2301 return;
2302 }
2303
2304 skb = cfg80211_vendor_event_alloc(pHddCtx->wiphy,
2305 EXTSCAN_EVENT_BUF_SIZE + NLMSG_HDRLEN,
2306 QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_SET_SIGNIFICANT_CHANGE_INDEX,
2307 GFP_KERNEL);
2308
2309 if (!skb) {
2310 hddLog(VOS_TRACE_LEVEL_ERROR,
2311 FL("cfg80211_vendor_event_alloc failed"));
2312 return;
2313 }
2314 hddLog(VOS_TRACE_LEVEL_INFO, FL("Entering "));
2315 hddLog(VOS_TRACE_LEVEL_INFO, "Req Id (%u)", pData->requestId);
2316 hddLog(VOS_TRACE_LEVEL_INFO, "Status (%u)", pData->status);
2317
2318 if (nla_put_u32(skb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_REQUEST_ID,
2319 pData->requestId) ||
2320 nla_put_u32(skb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_STATUS, pData->status)) {
2321 hddLog(VOS_TRACE_LEVEL_ERROR, FL("nla put fail"));
2322 goto nla_put_failure;
2323 }
2324
2325 cfg80211_vendor_event(skb, GFP_KERNEL);
2326 return;
2327
2328nla_put_failure:
2329 kfree_skb(skb);
2330 return;
2331}
2332
2333
2334static void wlan_hdd_cfg80211_extscan_reset_signf_wifi_change_rsp(void *ctx,
2335 void *pMsg)
2336{
2337 hdd_context_t *pHddCtx = (hdd_context_t *)ctx;
2338 struct sk_buff *skb = NULL;
2339 tpSirEXTScanResetSignificantChangeRspParams pData =
2340 (tpSirEXTScanResetSignificantChangeRspParams) pMsg;
2341
2342 if (wlan_hdd_validate_context(pHddCtx) || !pData) {
2343 hddLog(VOS_TRACE_LEVEL_ERROR, FL("HDD context is not valid "
2344 "or pData(%p) is null"), pData);
2345 return;
2346 }
2347
2348 skb = cfg80211_vendor_event_alloc(pHddCtx->wiphy,
2349 EXTSCAN_EVENT_BUF_SIZE + NLMSG_HDRLEN,
2350 QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_RESET_SIGNIFICANT_CHANGE_INDEX,
2351 GFP_KERNEL);
2352
2353 if (!skb) {
2354 hddLog(VOS_TRACE_LEVEL_ERROR,
2355 FL("cfg80211_vendor_event_alloc failed"));
2356 return;
2357 }
2358 hddLog(VOS_TRACE_LEVEL_INFO, FL("Entering "));
2359 hddLog(VOS_TRACE_LEVEL_INFO, "Req Id (%u)", pData->requestId);
2360 hddLog(VOS_TRACE_LEVEL_INFO, "Status (%u)", pData->status);
2361
2362 if (nla_put_u32(skb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_REQUEST_ID,
2363 pData->requestId) ||
2364 nla_put_u32(skb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_STATUS, pData->status)) {
2365 hddLog(VOS_TRACE_LEVEL_ERROR, FL("nla put fail"));
2366 goto nla_put_failure;
2367 }
2368
2369 cfg80211_vendor_event(skb, GFP_KERNEL);
2370 return;
2371
2372nla_put_failure:
2373 kfree_skb(skb);
2374 return;
2375}
2376
2377static void wlan_hdd_cfg80211_extscan_cached_results_ind(void *ctx,
2378 void *pMsg)
2379{
2380 hdd_context_t *pHddCtx = (hdd_context_t *)ctx;
2381 struct sk_buff *skb = NULL;
2382 tANI_U32 i = 0, j, resultsPerEvent;
2383 tANI_S32 totalResults;
2384 tpSirWifiScanResultEvent pData = (tpSirWifiScanResultEvent) pMsg;
2385 tpSirWifiScanResult pSirWifiScanResult;
2386
2387 if (wlan_hdd_validate_context(pHddCtx) || !pData) {
2388 hddLog(VOS_TRACE_LEVEL_ERROR, FL("HDD context is not valid "
2389 "or pData(%p) is null"), pData);
2390 return;
2391 }
2392 totalResults = pData->numOfAps;
2393 hddLog(VOS_TRACE_LEVEL_INFO, "Req Id (%u)", pData->requestId);
2394 hddLog(VOS_TRACE_LEVEL_INFO, "Num results (%u)", pData->numOfAps);
2395 hddLog(VOS_TRACE_LEVEL_INFO, "More Data (%u)", pData->moreData);
2396
2397 do{
2398 resultsPerEvent = ((totalResults >= EXTSCAN_MAX_CACHED_RESULTS_PER_IND) ?
2399 EXTSCAN_MAX_CACHED_RESULTS_PER_IND : totalResults);
2400 totalResults -= EXTSCAN_MAX_CACHED_RESULTS_PER_IND;
2401
2402 skb = cfg80211_vendor_event_alloc(pHddCtx->wiphy,
2403 EXTSCAN_EVENT_BUF_SIZE + NLMSG_HDRLEN,
2404 QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_GET_CACHED_RESULTS_INDEX,
2405 GFP_KERNEL);
2406
2407 if (!skb) {
2408 hddLog(VOS_TRACE_LEVEL_ERROR,
2409 FL("cfg80211_vendor_event_alloc failed"));
2410 return;
2411 }
2412
2413 hddLog(VOS_TRACE_LEVEL_INFO, "resultsPerEvent (%u)", resultsPerEvent);
2414
2415 if (nla_put_u32(skb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_REQUEST_ID,
2416 pData->requestId) ||
2417 nla_put_u32(skb,
2418 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_NUM_RESULTS_AVAILABLE,
2419 resultsPerEvent)) {
2420 hddLog(VOS_TRACE_LEVEL_ERROR, FL("put fail"));
2421 goto fail;
2422 }
2423 if (nla_put_u8(skb,
2424 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_MORE_DATA,
2425 pData->moreData ? 1 : (totalResults > 0 ? 1 : 0 )))
2426 {
2427 hddLog(VOS_TRACE_LEVEL_ERROR, FL("put fail"));
2428 goto fail;
2429 }
2430
2431 if (resultsPerEvent) {
2432 struct nlattr *aps;
2433
2434 aps = nla_nest_start(skb,
2435 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_LIST);
2436 if (!aps)
2437 {
2438 hddLog(VOS_TRACE_LEVEL_ERROR, FL("put fail"));
2439 goto fail;
2440 }
2441
2442 for (j = 0; j < resultsPerEvent; j++, i++) {
2443 struct nlattr *ap;
2444 pSirWifiScanResult = (tpSirWifiScanResult) ((tANI_U8 *)
2445 pData->ap + ( i* sizeof(tSirWifiScanResult)));
2446
2447 hddLog(VOS_TRACE_LEVEL_INFO, "[index=%u] Timestamp(%llu) "
2448 "Ssid (%s)"
2449 "Bssid: %pM "
2450 "Channel (%u)"
2451 "Rssi (%d)"
2452 "RTT (%u)"
2453 "RTT_SD (%u)",
2454 i,
2455 pSirWifiScanResult->ts,
2456 pSirWifiScanResult->ssid,
2457 pSirWifiScanResult->bssid,
2458 pSirWifiScanResult->channel,
2459 pSirWifiScanResult->rssi,
2460 pSirWifiScanResult->rtt,
2461 pSirWifiScanResult->rtt_sd);
2462
2463 ap = nla_nest_start(skb, j + 1);
2464 if (!ap)
2465 {
2466 hddLog(VOS_TRACE_LEVEL_ERROR, FL("put fail"));
2467 goto fail;
2468 }
2469
2470 if (nla_put_u64(skb,
2471 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_TIME_STAMP,
2472 pSirWifiScanResult->ts) )
2473 {
2474 hddLog(VOS_TRACE_LEVEL_ERROR, FL("put fail"));
2475 goto fail;
2476 }
2477 if (nla_put(skb,
2478 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_SSID,
2479 sizeof(pSirWifiScanResult->ssid),
2480 pSirWifiScanResult->ssid) )
2481 {
2482 hddLog(VOS_TRACE_LEVEL_ERROR, FL("put fail"));
2483 goto fail;
2484 }
2485 if (nla_put(skb,
2486 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_BSSID,
2487 sizeof(pSirWifiScanResult->bssid),
2488 pSirWifiScanResult->bssid) )
2489 {
2490 hddLog(VOS_TRACE_LEVEL_ERROR, FL("put fail"));
2491 goto fail;
2492 }
2493 if (nla_put_u32(skb,
2494 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_CHANNEL,
2495 pSirWifiScanResult->channel) )
2496 {
2497 hddLog(VOS_TRACE_LEVEL_ERROR, FL("put fail"));
2498 goto fail;
2499 }
Dasari Srinivas90747d72014-10-08 12:16:15 +05302500 if (nla_put_s32(skb,
Dino Mycle6fb96c12014-06-10 11:52:40 +05302501 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_RSSI,
2502 pSirWifiScanResult->rssi) )
2503 {
2504 hddLog(VOS_TRACE_LEVEL_ERROR, FL("put fail"));
2505 goto fail;
2506 }
2507 if (nla_put_u32(skb,
2508 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_RTT,
2509 pSirWifiScanResult->rtt) )
2510 {
2511 hddLog(VOS_TRACE_LEVEL_ERROR, FL("put fail"));
2512 goto fail;
2513 }
2514 if (nla_put_u32(skb,
2515 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_RTT_SD,
2516 pSirWifiScanResult->rtt_sd))
2517 {
2518 hddLog(VOS_TRACE_LEVEL_ERROR, FL("put fail"));
2519 goto fail;
2520 }
2521
2522 nla_nest_end(skb, ap);
2523 }
2524 nla_nest_end(skb, aps);
2525
2526 }
2527 cfg80211_vendor_event(skb, GFP_KERNEL);
2528 } while (totalResults > 0);
2529
2530 return;
2531fail:
2532 kfree_skb(skb);
2533 return;
2534}
2535
2536static void wlan_hdd_cfg80211_extscan_hotlist_match_ind(void *ctx,
2537 void *pMsg)
2538{
2539 tpSirWifiScanResultEvent pData = (tpSirWifiScanResultEvent) pMsg;
2540 hdd_context_t *pHddCtx = (hdd_context_t *)ctx;
2541 struct sk_buff *skb = NULL;
2542 tANI_U32 i;
2543
2544 if (wlan_hdd_validate_context(pHddCtx) || !pData) {
2545 hddLog(VOS_TRACE_LEVEL_ERROR, FL("HDD context is not valid "
2546 "or pData(%p) is null"), pData);
2547 return;
2548 }
2549
2550 skb = cfg80211_vendor_event_alloc(pHddCtx->wiphy,
2551 EXTSCAN_EVENT_BUF_SIZE + NLMSG_HDRLEN,
2552 QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_HOTLIST_AP_FOUND_INDEX,
2553 GFP_KERNEL);
2554
2555 if (!skb) {
2556 hddLog(VOS_TRACE_LEVEL_ERROR,
2557 FL("cfg80211_vendor_event_alloc failed"));
2558 return;
2559 }
2560 hddLog(VOS_TRACE_LEVEL_INFO, FL("Entering "));
2561 hddLog(VOS_TRACE_LEVEL_INFO, "Req Id (%u)", pData->requestId);
2562 hddLog(VOS_TRACE_LEVEL_INFO, "Num results (%u)", pData->numOfAps);
2563 hddLog(VOS_TRACE_LEVEL_INFO, "More Data (%u)", pData->moreData);
2564
2565 for (i = 0; i < pData->numOfAps; i++) {
2566 hddLog(VOS_TRACE_LEVEL_INFO, "[index=%u] Timestamp(0x%lld) "
2567 "Ssid (%s) "
2568 "Bssid (" MAC_ADDRESS_STR ") "
2569 "Channel (%u) "
2570 "Rssi (%d) "
2571 "RTT (%u) "
2572 "RTT_SD (%u) ",
2573 i,
2574 pData->ap[i].ts,
2575 pData->ap[i].ssid,
2576 MAC_ADDR_ARRAY(pData->ap[i].bssid),
2577 pData->ap[i].channel,
2578 pData->ap[i].rssi,
2579 pData->ap[i].rtt,
2580 pData->ap[i].rtt_sd);
2581 }
2582
2583 if (nla_put_u32(skb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_REQUEST_ID,
2584 pData->requestId) ||
2585 nla_put_u32(skb,
2586 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_NUM_RESULTS_AVAILABLE,
2587 pData->numOfAps)) {
2588 hddLog(VOS_TRACE_LEVEL_ERROR, FL("put fail"));
2589 goto fail;
2590 }
2591 if (pData->numOfAps) {
2592 struct nlattr *aps;
2593
2594 aps = nla_nest_start(skb,
2595 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_LIST);
2596 if (!aps)
2597 goto fail;
2598
2599 for (i = 0; i < pData->numOfAps; i++) {
2600 struct nlattr *ap;
2601
2602 ap = nla_nest_start(skb, i + 1);
2603 if (!ap)
2604 goto fail;
2605
2606 if (nla_put_u64(skb,
2607 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_TIME_STAMP,
2608 pData->ap[i].ts) ||
2609 nla_put(skb,
2610 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_SSID,
2611 sizeof(pData->ap[i].ssid),
2612 pData->ap[i].ssid) ||
2613 nla_put(skb,
2614 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_BSSID,
2615 sizeof(pData->ap[i].bssid),
2616 pData->ap[i].bssid) ||
2617 nla_put_u32(skb,
2618 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_CHANNEL,
2619 pData->ap[i].channel) ||
2620 nla_put_s32(skb,
2621 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_RSSI,
2622 pData->ap[i].rssi) ||
2623 nla_put_u32(skb,
2624 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_RTT,
2625 pData->ap[i].rtt) ||
2626 nla_put_u32(skb,
2627 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_RTT_SD,
2628 pData->ap[i].rtt_sd))
2629 goto fail;
2630
2631 nla_nest_end(skb, ap);
2632 }
2633 nla_nest_end(skb, aps);
2634
2635 if (nla_put_u8(skb,
2636 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_MORE_DATA,
2637 pData->moreData))
2638 goto fail;
2639 }
2640
2641 cfg80211_vendor_event(skb, GFP_KERNEL);
2642 return;
2643
2644fail:
2645 kfree_skb(skb);
2646 return;
2647
2648}
2649static void wlan_hdd_cfg80211_extscan_signif_wifi_change_results_ind(void *ctx,
2650 void *pMsg)
2651{
2652 hdd_context_t *pHddCtx = (hdd_context_t *)ctx;
2653 struct sk_buff *skb = NULL;
2654 tANI_U32 i, j;
2655 tpSirWifiSignificantChangeEvent pData =
2656 (tpSirWifiSignificantChangeEvent) pMsg;
2657
2658 if (wlan_hdd_validate_context(pHddCtx) || !pData) {
2659 hddLog(VOS_TRACE_LEVEL_ERROR, FL("HDD context is not valid "
2660 "or pData(%p) is null"), pData);
2661 return;
2662 }
2663 skb = cfg80211_vendor_event_alloc(pHddCtx->wiphy,
2664 EXTSCAN_EVENT_BUF_SIZE,
2665 QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_SIGNIFICANT_CHANGE_INDEX,
2666 GFP_KERNEL);
2667
2668 if (!skb) {
2669 hddLog(VOS_TRACE_LEVEL_ERROR,
2670 FL("cfg80211_vendor_event_alloc failed"));
2671 return;
2672 }
2673 hddLog(VOS_TRACE_LEVEL_INFO, FL("Entering "));
2674 hddLog(VOS_TRACE_LEVEL_INFO, "Req Id (%u)", pData->requestId);
2675 hddLog(VOS_TRACE_LEVEL_INFO, "total List Size %u ", pData->numSigRssiBss);
2676 hddLog(VOS_TRACE_LEVEL_INFO, " CUrrent List size (%u)",
2677 pData->numSigRssiBss);
2678 hddLog(VOS_TRACE_LEVEL_INFO, "moreData (%u)", pData->moreData);
2679
2680 for (i = 0; i < pData->numSigRssiBss; i++) {
2681 hddLog(VOS_TRACE_LEVEL_INFO , "Rssi List [%d] BSSID: (%pM) Channel %u "
2682 " num RSSI %u ",
2683 i, pData->sigRssiResult[i].bssid,
2684 pData->sigRssiResult[i].channel,
2685 pData->sigRssiResult[i].numRssi);
2686
2687 for (j = 0; j < pData->sigRssiResult[i].numRssi; j++){
2688
2689 hddLog(VOS_TRACE_LEVEL_INFO,
2690 " [%d]",
Dino Myclec8f3f332014-07-21 16:48:27 +05302691 pData->sigRssiResult[i].rssi[j]);
Dino Mycle6fb96c12014-06-10 11:52:40 +05302692
2693 }
2694 }
2695
2696
2697 if (nla_put_u32(skb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_REQUEST_ID,
2698 pData->requestId) ||
2699 nla_put_u32(skb,
2700 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_NUM_RESULTS_AVAILABLE,
2701 pData->numSigRssiBss)) {
2702 hddLog(VOS_TRACE_LEVEL_ERROR, FL("put fail"));
2703 goto fail;
2704 }
2705
2706 if (pData->numSigRssiBss) {
2707 struct nlattr *aps;
2708 aps = nla_nest_start(skb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_LIST);
2709 if (!aps)
2710 goto fail;
2711 for (i = 0; i < pData->numSigRssiBss; i++) {
2712 struct nlattr *ap;
2713
2714 ap = nla_nest_start(skb, i);
2715 if (!ap)
2716 goto fail;
2717 if (nla_put(skb,
2718 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SIGNIFICANT_CHANGE_RESULT_BSSID,
2719 sizeof(tSirMacAddr), pData->sigRssiResult[i].bssid) ||
2720 nla_put_u32(skb,
2721 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SIGNIFICANT_CHANGE_RESULT_CHANNEL,
2722 pData->sigRssiResult[i].channel) ||
2723 nla_put_u32(skb,
2724 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SIGNIFICANT_CHANGE_RESULT_NUM_RSSI,
2725 pData->sigRssiResult[i].numRssi) ||
2726 nla_put(skb,
2727 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SIGNIFICANT_CHANGE_RESULT_RSSI_LIST,
2728 sizeof(s32) * pData->sigRssiResult[i].numRssi,
2729 pData->sigRssiResult[i].rssi))
2730 goto fail;
2731 nla_nest_end(skb, ap);
2732 }
2733 nla_nest_end(skb, aps);
2734 if (nla_put_u8(skb,
2735 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_MORE_DATA,
2736 pData->moreData))
2737 goto fail;
2738 }
2739 cfg80211_vendor_event(skb, GFP_KERNEL);
2740 return;
2741fail:
2742 kfree_skb(skb);
2743 return;
2744}
2745
2746static void wlan_hdd_cfg80211_extscan_full_scan_result_event(void *ctx,
2747 void *pMsg)
2748{
2749 struct sk_buff *skb;
2750 hdd_context_t *pHddCtx = (hdd_context_t *)ctx;
2751 tpSirWifiFullScanResultEvent pData =
2752 (tpSirWifiFullScanResultEvent) (pMsg);
2753
2754 if (wlan_hdd_validate_context(pHddCtx) || !pData) {
2755 hddLog(VOS_TRACE_LEVEL_ERROR, FL("HDD context is not valid "
2756 "or pData(%p) is null"), pData);
2757 return;
2758 }
2759
2760 skb = cfg80211_vendor_event_alloc(pHddCtx->wiphy,
2761 EXTSCAN_EVENT_BUF_SIZE + NLMSG_HDRLEN,
2762 QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_FULL_SCAN_RESULT_INDEX,
2763 GFP_KERNEL);
2764
2765 if (!skb) {
2766 hddLog(VOS_TRACE_LEVEL_ERROR,
2767 FL("cfg80211_vendor_event_alloc failed"));
2768 return;
2769 }
2770
2771 hddLog(VOS_TRACE_LEVEL_INFO, FL("Entering "));
2772 hddLog(VOS_TRACE_LEVEL_INFO, FL("Req Id (%u)"), pData->requestId);
2773 hddLog(VOS_TRACE_LEVEL_INFO, FL("More Data (%u)"), pData->moreData);
2774 hddLog(VOS_TRACE_LEVEL_INFO, FL("AP Info: Timestamp(0x%llX) "
2775 "Ssid (%s)"
2776 "Bssid (" MAC_ADDRESS_STR ")"
2777 "Channel (%u)"
2778 "Rssi (%d)"
2779 "RTT (%u)"
2780 "RTT_SD (%u)"),
2781 pData->ap.ts,
2782 pData->ap.ssid,
2783 MAC_ADDR_ARRAY(pData->ap.bssid),
2784 pData->ap.channel,
2785 pData->ap.rssi,
2786 pData->ap.rtt,
2787 pData->ap.rtt_sd);
2788 hddLog(VOS_TRACE_LEVEL_INFO, "IE Length (%u)", pData->ieLength);
2789 if (nla_put_u32(skb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_REQUEST_ID,
2790 pData->requestId) ||
2791 nla_put_u64(skb,
2792 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_TIME_STAMP,
2793 pData->ap.ts) ||
2794 nla_put(skb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_SSID,
2795 sizeof(pData->ap.ssid),
2796 pData->ap.ssid) ||
2797 nla_put(skb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_BSSID,
2798 WNI_CFG_BSSID_LEN,
2799 pData->ap.bssid) ||
2800 nla_put_u32(skb,
2801 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_CHANNEL,
2802 pData->ap.channel) ||
Dasari Srinivas90747d72014-10-08 12:16:15 +05302803 nla_put_s32(skb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_RSSI,
Dino Mycle6fb96c12014-06-10 11:52:40 +05302804 pData->ap.rssi) ||
2805 nla_put_u32(skb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_RTT,
2806 pData->ap.rtt) ||
2807 nla_put_u32(skb,
2808 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_RTT_SD,
2809 pData->ap.rtt_sd) ||
2810 nla_put_u16(skb,
2811 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_BEACON_PERIOD,
2812 pData->ap.beaconPeriod) ||
2813 nla_put_u16(skb,
2814 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_CAPABILITY,
2815 pData->ap.capability) ||
2816 nla_put_u32(skb,
2817 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_IE_LENGTH,
2818 pData->ieLength))
2819 {
2820 hddLog(VOS_TRACE_LEVEL_ERROR, FL("nla put fail"));
2821 goto nla_put_failure;
2822 }
2823 if (nla_put(skb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_IE_DATA,
2824 pData->ieLength,
2825 pData->ie))
2826 {
2827 hddLog(VOS_TRACE_LEVEL_ERROR, FL("nla put fail"));
2828 goto nla_put_failure;
2829 }
2830
2831 cfg80211_vendor_event(skb, GFP_KERNEL);
2832 return;
2833
2834nla_put_failure:
2835 kfree_skb(skb);
2836 return;
2837}
2838
2839static void wlan_hdd_cfg80211_extscan_scan_res_available_event(void *ctx,
2840 void *pMsg)
2841{
2842 hdd_context_t *pHddCtx = (hdd_context_t *)ctx;
2843 struct sk_buff *skb = NULL;
2844 tpSirEXTScanResultsAvailableIndParams pData =
2845 (tpSirEXTScanResultsAvailableIndParams) pMsg;
2846
2847 if (wlan_hdd_validate_context(pHddCtx) || !pData) {
2848 hddLog(VOS_TRACE_LEVEL_ERROR, FL("HDD context is not valid "
2849 "or pData(%p) is null"), pData);
2850 return;
2851 }
2852
2853 skb = cfg80211_vendor_event_alloc(pHddCtx->wiphy,
2854 EXTSCAN_EVENT_BUF_SIZE + NLMSG_HDRLEN,
2855 QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_SCAN_RESULTS_AVAILABLE_INDEX,
2856 GFP_KERNEL);
2857
2858 if (!skb) {
2859 hddLog(VOS_TRACE_LEVEL_ERROR,
2860 FL("cfg80211_vendor_event_alloc failed"));
2861 return;
2862 }
2863
2864 hddLog(VOS_TRACE_LEVEL_INFO, FL("Entering "));
2865 hddLog(VOS_TRACE_LEVEL_INFO, "Req Id (%u)", pData->requestId);
2866 hddLog(VOS_TRACE_LEVEL_INFO, "Num results (%u)",
2867 pData->numResultsAvailable);
2868 if (nla_put_u32(skb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_REQUEST_ID,
2869 pData->requestId) ||
2870 nla_put_u32(skb,
2871 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_NUM_RESULTS_AVAILABLE,
2872 pData->numResultsAvailable)) {
2873 hddLog(VOS_TRACE_LEVEL_ERROR, FL("nla put fail"));
2874 goto nla_put_failure;
2875 }
2876
2877 cfg80211_vendor_event(skb, GFP_KERNEL);
2878 return;
2879
2880nla_put_failure:
2881 kfree_skb(skb);
2882 return;
2883}
2884
2885static void wlan_hdd_cfg80211_extscan_scan_progress_event(void *ctx, void *pMsg)
2886{
2887 hdd_context_t *pHddCtx = (hdd_context_t *)ctx;
2888 struct sk_buff *skb = NULL;
2889 tpSirEXTScanProgressIndParams pData =
2890 (tpSirEXTScanProgressIndParams) pMsg;
2891
2892 if (wlan_hdd_validate_context(pHddCtx) || !pData) {
2893 hddLog(VOS_TRACE_LEVEL_ERROR, FL("HDD context is not valid "
2894 "or pData(%p) is null"), pData);
2895 return;
2896 }
2897
2898 skb = cfg80211_vendor_event_alloc(pHddCtx->wiphy,
2899 EXTSCAN_EVENT_BUF_SIZE + NLMSG_HDRLEN,
2900 QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_SCAN_EVENT_INDEX,
2901 GFP_KERNEL);
2902
2903 if (!skb) {
2904 hddLog(VOS_TRACE_LEVEL_ERROR,
2905 FL("cfg80211_vendor_event_alloc failed"));
2906 return;
2907 }
2908 hddLog(VOS_TRACE_LEVEL_INFO, FL("Entering "));
2909 hddLog(VOS_TRACE_LEVEL_INFO, "Scan event type (%u)",
2910 pData->extScanEventType);
2911 hddLog(VOS_TRACE_LEVEL_INFO, "Scan event status (%u)",
2912 pData->status);
2913
2914 if (nla_put_u8(skb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_EVENT_TYPE,
2915 pData->extScanEventType) ||
2916 nla_put_u32(skb,
Dasari Srinivas5a288652014-06-30 17:13:22 +05302917 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_REQUEST_ID,
2918 pData->requestId) ||
2919 nla_put_u32(skb,
Dino Mycle6fb96c12014-06-10 11:52:40 +05302920 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_EVENT_STATUS,
2921 pData->status)) {
2922 hddLog(VOS_TRACE_LEVEL_ERROR, FL("nla put fail"));
2923 goto nla_put_failure;
2924 }
2925
2926 cfg80211_vendor_event(skb, GFP_KERNEL);
2927 return;
2928
2929nla_put_failure:
2930 kfree_skb(skb);
2931 return;
2932}
2933
2934void wlan_hdd_cfg80211_extscan_callback(void *ctx, const tANI_U16 evType,
2935 void *pMsg)
2936{
2937 hdd_context_t *pHddCtx = (hdd_context_t *)ctx;
2938
2939 if (wlan_hdd_validate_context(pHddCtx)) {
Dasari Srinivasb46ed1d2014-10-08 13:03:08 +05302940 hddLog(VOS_TRACE_LEVEL_INFO, FL("HDD context is not valid"));
Dino Mycle6fb96c12014-06-10 11:52:40 +05302941 return;
2942 }
2943
2944 hddLog(VOS_TRACE_LEVEL_INFO, FL("Rcvd Event (%d)"), evType);
2945
2946
2947 switch(evType) {
2948 case SIR_HAL_EXTSCAN_START_RSP:
2949 wlan_hdd_cfg80211_extscan_start_rsp(ctx, pMsg);
2950 break;
2951
2952 case SIR_HAL_EXTSCAN_STOP_RSP:
2953 wlan_hdd_cfg80211_extscan_stop_rsp(ctx, pMsg);
2954 break;
2955 case SIR_HAL_EXTSCAN_GET_CACHED_RESULTS_RSP:
2956 /* There is no need to send this response to upper layer
2957 Just log the message */
2958 hddLog(VOS_TRACE_LEVEL_INFO,
2959 FL("Rcvd SIR_HAL_EXTSCAN_CACHED_RESULTS_RSP"));
2960 break;
2961 case SIR_HAL_EXTSCAN_SET_BSS_HOTLIST_RSP:
2962 wlan_hdd_cfg80211_extscan_set_bss_hotlist_rsp(ctx, pMsg);
2963 break;
2964
2965 case SIR_HAL_EXTSCAN_RESET_BSS_HOTLIST_RSP:
2966 wlan_hdd_cfg80211_extscan_reset_bss_hotlist_rsp(ctx, pMsg);
2967 break;
2968
2969 case SIR_HAL_EXTSCAN_SET_SIGNF_RSSI_CHANGE_RSP:
2970 wlan_hdd_cfg80211_extscan_set_signf_wifi_change_rsp(ctx, pMsg);
2971 break;
2972
2973 case SIR_HAL_EXTSCAN_RESET_SIGNF_RSSI_CHANGE_RSP:
2974 wlan_hdd_cfg80211_extscan_reset_signf_wifi_change_rsp(ctx, pMsg);
2975 break;
2976 case SIR_HAL_EXTSCAN_GET_CAPABILITIES_RSP:
2977 wlan_hdd_cfg80211_extscan_get_capabilities_ind(ctx, pMsg);
2978 break;
2979 case SIR_HAL_EXTSCAN_PROGRESS_IND:
2980 wlan_hdd_cfg80211_extscan_scan_progress_event(ctx, pMsg);
2981 break;
2982 case SIR_HAL_EXTSCAN_SCAN_AVAILABLE_IND:
2983 wlan_hdd_cfg80211_extscan_scan_res_available_event(ctx, pMsg);
2984 break;
2985 case SIR_HAL_EXTSCAN_SCAN_RESULT_IND:
2986 wlan_hdd_cfg80211_extscan_cached_results_ind(ctx, pMsg);
2987 break;
2988 case SIR_HAL_EXTSCAN_HOTLIST_MATCH_IND:
2989 wlan_hdd_cfg80211_extscan_hotlist_match_ind(ctx, pMsg);
2990 break;
2991 case SIR_HAL_EXTSCAN_SIGNF_WIFI_CHANGE_IND:
2992 wlan_hdd_cfg80211_extscan_signif_wifi_change_results_ind(ctx, pMsg);
2993 break;
2994 case SIR_HAL_EXTSCAN_FULL_SCAN_RESULT_IND:
2995 wlan_hdd_cfg80211_extscan_full_scan_result_event(ctx, pMsg);
2996 break;
2997 default:
2998 hddLog(VOS_TRACE_LEVEL_ERROR, FL("invalid event type %d "), evType);
2999 break;
3000 }
3001}
3002
3003static int wlan_hdd_cfg80211_extscan_get_capabilities(struct wiphy *wiphy,
3004 struct wireless_dev *wdev,
3005 void *data, int dataLen)
3006{
Dino Myclee8843b32014-07-04 14:21:45 +05303007 tSirGetEXTScanCapabilitiesReqParams reqMsg;
Dino Mycle6fb96c12014-06-10 11:52:40 +05303008 struct net_device *dev = wdev->netdev;
3009 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
3010 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
3011 struct nlattr
3012 *tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX + 1];
3013 eHalStatus status;
3014
3015 hddLog(VOS_TRACE_LEVEL_INFO, FL("Entering"));
3016 status = wlan_hdd_validate_context(pHddCtx);
3017 if (0 != status)
3018 {
3019 hddLog(VOS_TRACE_LEVEL_ERROR,
3020 FL("HDD context is not valid"));
3021 return -EINVAL;
3022 }
Dino Myclee8843b32014-07-04 14:21:45 +05303023 /* check the EXTScan Capability */
3024 if ( (TRUE != pHddCtx->cfg_ini->fEnableEXTScan) ||
3025 (TRUE != sme_IsFeatureSupportedByFW(EXTENDED_SCAN)))
3026 {
3027 hddLog(VOS_TRACE_LEVEL_ERROR,
3028 FL("EXTScan not enabled/supported by Firmware"));
3029 return -EINVAL;
3030 }
3031
Dino Mycle6fb96c12014-06-10 11:52:40 +05303032 if (nla_parse(tb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX,
3033 data, dataLen,
3034 wlan_hdd_extscan_config_policy)) {
3035 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Invalid ATTR"));
3036 return -EINVAL;
3037 }
3038
3039 /* Parse and fetch request Id */
3040 if (!tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_REQUEST_ID]) {
3041 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr request id failed"));
3042 return -EINVAL;
3043 }
3044
Dino Mycle6fb96c12014-06-10 11:52:40 +05303045
Dino Myclee8843b32014-07-04 14:21:45 +05303046 reqMsg.requestId = nla_get_u32(
Dino Mycle6fb96c12014-06-10 11:52:40 +05303047 tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_REQUEST_ID]);
Dino Myclee8843b32014-07-04 14:21:45 +05303048 hddLog(VOS_TRACE_LEVEL_INFO, FL("Req Id (%d)"), reqMsg.requestId);
Dino Mycle6fb96c12014-06-10 11:52:40 +05303049
Dino Myclee8843b32014-07-04 14:21:45 +05303050 reqMsg.sessionId = pAdapter->sessionId;
3051 hddLog(VOS_TRACE_LEVEL_INFO, FL("Session Id (%d)"), reqMsg.sessionId);
Dino Mycle6fb96c12014-06-10 11:52:40 +05303052
Dino Myclee8843b32014-07-04 14:21:45 +05303053 status = sme_EXTScanGetCapabilities(pHddCtx->hHal, &reqMsg);
Dino Mycle6fb96c12014-06-10 11:52:40 +05303054 if (!HAL_STATUS_SUCCESS(status)) {
3055 hddLog(VOS_TRACE_LEVEL_ERROR,
3056 FL("sme_EXTScanGetCapabilities failed(err=%d)"), status);
Dino Mycle6fb96c12014-06-10 11:52:40 +05303057 return -EINVAL;
3058 }
3059
3060 return 0;
3061}
3062
3063
3064static int wlan_hdd_cfg80211_extscan_get_cached_results(struct wiphy *wiphy,
3065 struct wireless_dev *wdev,
3066 void *data, int dataLen)
3067{
Dino Myclee8843b32014-07-04 14:21:45 +05303068 tSirEXTScanGetCachedResultsReqParams reqMsg;
Dino Mycle6fb96c12014-06-10 11:52:40 +05303069 struct net_device *dev = wdev->netdev;
3070 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
3071 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
3072 struct nlattr
3073 *tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX + 1];
3074 eHalStatus status;
3075
3076 status = wlan_hdd_validate_context(pHddCtx);
3077 if (0 != status)
3078 {
3079 hddLog(VOS_TRACE_LEVEL_ERROR,
3080 FL("HDD context is not valid"));
3081 return -EINVAL;
3082 }
Dino Myclee8843b32014-07-04 14:21:45 +05303083 /* check the EXTScan Capability */
3084 if ( (TRUE != pHddCtx->cfg_ini->fEnableEXTScan) ||
3085 (TRUE != sme_IsFeatureSupportedByFW(EXTENDED_SCAN)))
3086 {
3087 hddLog(VOS_TRACE_LEVEL_ERROR,
3088 FL("EXTScan not enabled/supported by Firmware"));
3089 return -EINVAL;
3090 }
3091
Dino Mycle6fb96c12014-06-10 11:52:40 +05303092 if (nla_parse(tb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX,
3093 data, dataLen,
3094 wlan_hdd_extscan_config_policy)) {
3095 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Invalid ATTR"));
3096 return -EINVAL;
3097 }
3098 /* Parse and fetch request Id */
3099 if (!tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_REQUEST_ID]) {
3100 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr request id failed"));
3101 return -EINVAL;
3102 }
Dino Mycle6fb96c12014-06-10 11:52:40 +05303103
Dino Myclee8843b32014-07-04 14:21:45 +05303104 reqMsg.requestId = nla_get_u32(
Dino Mycle6fb96c12014-06-10 11:52:40 +05303105 tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_REQUEST_ID]);
3106
Dino Myclee8843b32014-07-04 14:21:45 +05303107 hddLog(VOS_TRACE_LEVEL_INFO, FL("Req Id (%d)"), reqMsg.requestId);
Dino Mycle6fb96c12014-06-10 11:52:40 +05303108
Dino Myclee8843b32014-07-04 14:21:45 +05303109 reqMsg.sessionId = pAdapter->sessionId;
3110 hddLog(VOS_TRACE_LEVEL_INFO, FL("Session Id (%d)"), reqMsg.sessionId);
Dino Mycle6fb96c12014-06-10 11:52:40 +05303111
3112 /* Parse and fetch flush parameter */
3113 if (!tb
3114 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_GET_CACHED_SCAN_RESULTS_CONFIG_PARAM_FLUSH])
3115 {
3116 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr flush failed"));
3117 goto failed;
3118 }
Dino Myclee8843b32014-07-04 14:21:45 +05303119 reqMsg.flush = nla_get_u8(
Dino Mycle6fb96c12014-06-10 11:52:40 +05303120 tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_GET_CACHED_SCAN_RESULTS_CONFIG_PARAM_FLUSH]);
3121
Dino Myclee8843b32014-07-04 14:21:45 +05303122 hddLog(VOS_TRACE_LEVEL_INFO, FL("Flush (%d)"), reqMsg.flush);
Dino Mycle6fb96c12014-06-10 11:52:40 +05303123
Dino Myclee8843b32014-07-04 14:21:45 +05303124 status = sme_getCachedResults(pHddCtx->hHal, &reqMsg);
Dino Mycle6fb96c12014-06-10 11:52:40 +05303125 if (!HAL_STATUS_SUCCESS(status)) {
3126 hddLog(VOS_TRACE_LEVEL_ERROR,
3127 FL("sme_getCachedResults failed(err=%d)"), status);
Dino Mycle6fb96c12014-06-10 11:52:40 +05303128 return -EINVAL;
3129 }
3130 return 0;
3131
3132failed:
Dino Mycle6fb96c12014-06-10 11:52:40 +05303133 return -EINVAL;
3134}
3135
3136static int wlan_hdd_cfg80211_extscan_set_bssid_hotlist(struct wiphy *wiphy,
3137 struct wireless_dev *wdev,
3138 void *data, int dataLen)
3139{
3140 tpSirEXTScanSetBssidHotListReqParams pReqMsg = NULL;
3141 struct net_device *dev = wdev->netdev;
3142 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
3143 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
3144 struct nlattr
3145 *tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX + 1];
3146 struct nlattr
3147 *tb2[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX + 1];
3148 struct nlattr *apTh;
3149 eHalStatus status;
3150 tANI_U8 i = 0;
3151 int rem;
3152
3153 status = wlan_hdd_validate_context(pHddCtx);
3154 if (0 != status)
3155 {
3156 hddLog(VOS_TRACE_LEVEL_ERROR,
3157 FL("HDD context is not valid"));
3158 return -EINVAL;
3159 }
Dino Myclee8843b32014-07-04 14:21:45 +05303160 /* check the EXTScan Capability */
3161 if ( (TRUE != pHddCtx->cfg_ini->fEnableEXTScan) ||
3162 (TRUE != sme_IsFeatureSupportedByFW(EXTENDED_SCAN)))
3163 {
3164 hddLog(VOS_TRACE_LEVEL_ERROR,
3165 FL("EXTScan not enabled/supported by Firmware"));
3166 return -EINVAL;
3167 }
3168
Dino Mycle6fb96c12014-06-10 11:52:40 +05303169 if (nla_parse(tb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX,
3170 data, dataLen,
3171 wlan_hdd_extscan_config_policy)) {
3172 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Invalid ATTR"));
3173 return -EINVAL;
3174 }
3175
3176 /* Parse and fetch request Id */
3177 if (!tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_REQUEST_ID]) {
3178 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr request id failed"));
3179 return -EINVAL;
3180 }
Dino Mycle6fb96c12014-06-10 11:52:40 +05303181 pReqMsg = (tpSirEXTScanSetBssidHotListReqParams)
3182 vos_mem_malloc(sizeof(*pReqMsg));
3183 if (!pReqMsg) {
3184 hddLog(VOS_TRACE_LEVEL_ERROR, FL("vos_mem_malloc failed"));
3185 return -ENOMEM;
3186 }
3187
Dino Myclee8843b32014-07-04 14:21:45 +05303188
Dino Mycle6fb96c12014-06-10 11:52:40 +05303189 pReqMsg->requestId = nla_get_u32(
3190 tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_REQUEST_ID]);
3191 hddLog(VOS_TRACE_LEVEL_INFO, FL("Req Id (%d)"), pReqMsg->requestId);
3192
3193 /* Parse and fetch number of APs */
3194 if (!tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_BSSID_HOTLIST_PARAMS_NUM_AP]) {
3195 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr number of AP failed"));
3196 goto fail;
3197 }
3198
3199 pReqMsg->sessionId = pAdapter->sessionId;
3200 hddLog(VOS_TRACE_LEVEL_INFO, FL("Session Id (%d)"), pReqMsg->sessionId);
3201
3202 pReqMsg->numAp = nla_get_u32(
3203 tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_BSSID_HOTLIST_PARAMS_NUM_AP]);
3204 hddLog(VOS_TRACE_LEVEL_INFO, FL("Number of AP (%d)"), pReqMsg->numAp);
3205
3206 nla_for_each_nested(apTh,
3207 tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_AP_THRESHOLD_PARAM], rem) {
3208 if(nla_parse(tb2, QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX,
3209 nla_data(apTh), nla_len(apTh),
3210 NULL)) {
3211 hddLog(VOS_TRACE_LEVEL_ERROR, FL("nla_parse failed"));
3212 goto fail;
3213 }
3214
3215 /* Parse and fetch MAC address */
3216 if (!tb2[QCA_WLAN_VENDOR_ATTR_EXTSCAN_AP_THRESHOLD_PARAM_BSSID]) {
3217 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr mac address failed"));
3218 goto fail;
3219 }
3220 memcpy(pReqMsg->ap[i].bssid, nla_data(
3221 tb2[QCA_WLAN_VENDOR_ATTR_EXTSCAN_AP_THRESHOLD_PARAM_BSSID]),
3222 sizeof(tSirMacAddr));
3223 hddLog(VOS_TRACE_LEVEL_INFO, FL("BSSID: %pM "), pReqMsg->ap[i].bssid);
3224
3225 /* Parse and fetch low RSSI */
3226 if (!tb2[QCA_WLAN_VENDOR_ATTR_EXTSCAN_AP_THRESHOLD_PARAM_RSSI_LOW]) {
3227 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr low RSSI failed"));
3228 goto fail;
3229 }
3230 pReqMsg->ap[i].low = nla_get_s32(
3231 tb2[QCA_WLAN_VENDOR_ATTR_EXTSCAN_AP_THRESHOLD_PARAM_RSSI_LOW]);
3232 hddLog(VOS_TRACE_LEVEL_INFO, FL("RSSI low (%d)"), pReqMsg->ap[i].low);
3233
3234 /* Parse and fetch high RSSI */
3235 if (!tb2[QCA_WLAN_VENDOR_ATTR_EXTSCAN_AP_THRESHOLD_PARAM_RSSI_HIGH]) {
3236 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr high RSSI failed"));
3237 goto fail;
3238 }
3239 pReqMsg->ap[i].high = nla_get_s32(
3240 tb2[QCA_WLAN_VENDOR_ATTR_EXTSCAN_AP_THRESHOLD_PARAM_RSSI_HIGH]);
3241 hddLog(VOS_TRACE_LEVEL_INFO, FL("RSSI High (%d)"),
3242 pReqMsg->ap[i].high);
3243
3244 /* Parse and fetch channel */
3245 if (!tb2[QCA_WLAN_VENDOR_ATTR_EXTSCAN_AP_THRESHOLD_PARAM_CHANNEL]) {
3246 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr channel failed"));
3247 goto fail;
3248 }
3249 pReqMsg->ap[i].channel = nla_get_u32(
3250 tb2[QCA_WLAN_VENDOR_ATTR_EXTSCAN_AP_THRESHOLD_PARAM_CHANNEL]);
3251 hddLog(VOS_TRACE_LEVEL_INFO,
3252 FL("Channel (%u)"), pReqMsg->ap[i].channel);
3253 i++;
3254 }
3255 status = sme_SetBssHotlist(pHddCtx->hHal, pReqMsg);
3256 if (!HAL_STATUS_SUCCESS(status)) {
3257 hddLog(VOS_TRACE_LEVEL_ERROR,
3258 FL("sme_SetBssHotlist failed(err=%d)"), status);
3259 vos_mem_free(pReqMsg);
3260 return -EINVAL;
3261 }
3262
Dino Myclee8843b32014-07-04 14:21:45 +05303263 vos_mem_free(pReqMsg);
3264
Dino Mycle6fb96c12014-06-10 11:52:40 +05303265 return 0;
3266
3267fail:
3268 vos_mem_free(pReqMsg);
3269 return -EINVAL;
3270}
3271
3272static int wlan_hdd_cfg80211_extscan_set_significant_change(struct wiphy *wiphy,
3273 struct wireless_dev *wdev,
3274 void *data, int dataLen)
3275{
3276 tpSirEXTScanSetSignificantChangeReqParams pReqMsg = NULL;
3277 struct net_device *dev = wdev->netdev;
3278 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
3279 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
3280 struct nlattr
3281 *tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX + 1];
3282 struct nlattr
3283 *tb2[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX + 1];
3284 struct nlattr *apTh;
3285 eHalStatus status;
3286 int i = 0;
3287 int rem;
3288
3289 status = wlan_hdd_validate_context(pHddCtx);
3290 if (0 != status)
3291 {
3292 hddLog(VOS_TRACE_LEVEL_ERROR,
3293 FL("HDD context is not valid"));
3294 return -EINVAL;
3295 }
Dino Myclee8843b32014-07-04 14:21:45 +05303296 /* check the EXTScan Capability */
3297 if ( (TRUE != pHddCtx->cfg_ini->fEnableEXTScan) ||
3298 (TRUE != sme_IsFeatureSupportedByFW(EXTENDED_SCAN)))
3299 {
3300 hddLog(VOS_TRACE_LEVEL_ERROR,
3301 FL("EXTScan not enabled/supported by Firmware"));
3302 return -EINVAL;
3303 }
3304
Dino Mycle6fb96c12014-06-10 11:52:40 +05303305 if (nla_parse(tb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX,
3306 data, dataLen,
3307 wlan_hdd_extscan_config_policy)) {
3308 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Invalid ATTR"));
3309 return -EINVAL;
3310 }
3311
3312 /* Parse and fetch request Id */
3313 if (!tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_REQUEST_ID]) {
3314 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr request id failed"));
3315 return -EINVAL;
3316 }
Dino Mycle6fb96c12014-06-10 11:52:40 +05303317 pReqMsg = (tpSirEXTScanSetSignificantChangeReqParams)
Dino Myclee8843b32014-07-04 14:21:45 +05303318 vos_mem_malloc(sizeof(*pReqMsg));
Dino Mycle6fb96c12014-06-10 11:52:40 +05303319 if (!pReqMsg) {
Dino Myclee8843b32014-07-04 14:21:45 +05303320 hddLog(VOS_TRACE_LEVEL_ERROR, FL("vos_mem_malloc failed"));
3321 return -ENOMEM;
Dino Mycle6fb96c12014-06-10 11:52:40 +05303322 }
3323
Dino Myclee8843b32014-07-04 14:21:45 +05303324
3325
Dino Mycle6fb96c12014-06-10 11:52:40 +05303326 pReqMsg->requestId = nla_get_u32(
3327 tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_REQUEST_ID]);
3328 hddLog(VOS_TRACE_LEVEL_INFO, FL("Req Id (%d)"), pReqMsg->requestId);
3329
3330 /* Parse and fetch RSSI sample size */
3331 if (!tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SIGNIFICANT_CHANGE_PARAMS_RSSI_SAMPLE_SIZE])
3332 {
3333 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr RSSI sample size failed"));
3334 goto fail;
3335 }
3336 pReqMsg->rssiSampleSize = nla_get_u32(
3337 tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SIGNIFICANT_CHANGE_PARAMS_RSSI_SAMPLE_SIZE]);
3338 hddLog(VOS_TRACE_LEVEL_INFO,
3339 FL("RSSI sample size (%u)"), pReqMsg->rssiSampleSize);
3340
3341 /* Parse and fetch lost AP sample size */
3342 if (!tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SIGNIFICANT_CHANGE_PARAMS_LOST_AP_SAMPLE_SIZE])
3343 {
3344 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr lost AP sample size failed"));
3345 goto fail;
3346 }
3347 pReqMsg->lostApSampleSize = nla_get_u32(
3348 tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SIGNIFICANT_CHANGE_PARAMS_LOST_AP_SAMPLE_SIZE]);
3349 hddLog(VOS_TRACE_LEVEL_INFO,
3350 FL("Lost AP sample size (%u)"), pReqMsg->lostApSampleSize);
3351 /* Parse and fetch minimum Breaching */
3352 if (!tb
3353 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_SIGNIFICANT_CHANGE_PARAMS_MIN_BREACHING]) {
3354 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr minBreaching failed"));
3355 goto fail;
3356 }
3357 pReqMsg->minBreaching = nla_get_u32(
3358 tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SIGNIFICANT_CHANGE_PARAMS_MIN_BREACHING]);
3359 hddLog(VOS_TRACE_LEVEL_INFO, FL(" Breaching (%d)"), pReqMsg->minBreaching);
3360
3361 /* Parse and fetch number of APs */
3362 if (!tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SIGNIFICANT_CHANGE_PARAMS_NUM_AP]) {
3363 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr number of AP failed"));
3364 goto fail;
3365 }
3366 pReqMsg->numAp = nla_get_u32(
3367 tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SIGNIFICANT_CHANGE_PARAMS_NUM_AP]);
3368 hddLog(VOS_TRACE_LEVEL_INFO, FL("Number of AP (%d)"), pReqMsg->numAp);
3369
3370 pReqMsg->sessionId = pAdapter->sessionId;
3371 hddLog(VOS_TRACE_LEVEL_INFO, FL("Session Id (%d)"), pReqMsg->sessionId);
3372
3373 nla_for_each_nested(apTh,
3374 tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_AP_THRESHOLD_PARAM], rem) {
3375 if(nla_parse(tb2,
3376 QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX,
3377 nla_data(apTh), nla_len(apTh),
3378 NULL)) {
3379 hddLog(VOS_TRACE_LEVEL_ERROR, FL("nla_parse failed"));
3380 goto fail;
3381 }
3382
3383 /* Parse and fetch MAC address */
3384 if (!tb2[QCA_WLAN_VENDOR_ATTR_EXTSCAN_AP_THRESHOLD_PARAM_BSSID]) {
3385 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr mac address failed"));
3386 goto fail;
3387 }
3388 memcpy(pReqMsg->ap[i].bssid, nla_data(
3389 tb2[QCA_WLAN_VENDOR_ATTR_EXTSCAN_AP_THRESHOLD_PARAM_BSSID]),
3390 sizeof(tSirMacAddr));
3391
3392 /* Parse and fetch low RSSI */
3393 if (!tb2[QCA_WLAN_VENDOR_ATTR_EXTSCAN_AP_THRESHOLD_PARAM_RSSI_LOW]) {
3394 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr low RSSI failed"));
3395 goto fail;
3396 }
3397 pReqMsg->ap[i].low = nla_get_s32(
3398 tb2[QCA_WLAN_VENDOR_ATTR_EXTSCAN_AP_THRESHOLD_PARAM_RSSI_LOW]);
3399 hddLog(VOS_TRACE_LEVEL_INFO, FL("RSSI low (%d)"), pReqMsg->ap[i].low);
3400
3401 /* Parse and fetch high RSSI */
3402 if (!tb2[QCA_WLAN_VENDOR_ATTR_EXTSCAN_AP_THRESHOLD_PARAM_RSSI_HIGH]) {
3403 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr high RSSI failed"));
3404 goto fail;
3405 }
3406 pReqMsg->ap[i].high = nla_get_s32(
3407 tb2[QCA_WLAN_VENDOR_ATTR_EXTSCAN_AP_THRESHOLD_PARAM_RSSI_HIGH]);
3408 hddLog(VOS_TRACE_LEVEL_INFO,
3409 FL("RSSI High (%d)"), pReqMsg->ap[i].high);
3410
3411 /* Parse and fetch channel */
3412 if (!tb2[QCA_WLAN_VENDOR_ATTR_EXTSCAN_AP_THRESHOLD_PARAM_CHANNEL]) {
3413 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr channel failed"));
3414 goto fail;
3415 }
3416 pReqMsg->ap[i].channel = nla_get_u32(
3417 tb2[QCA_WLAN_VENDOR_ATTR_EXTSCAN_AP_THRESHOLD_PARAM_CHANNEL]);
3418 hddLog(VOS_TRACE_LEVEL_INFO,
3419 FL("Channel (%u)"), pReqMsg->ap[i].channel);
3420 i++;
3421 }
3422
3423 status = sme_SetSignificantChange(pHddCtx->hHal, pReqMsg);
3424 if (!HAL_STATUS_SUCCESS(status)) {
3425 hddLog(VOS_TRACE_LEVEL_ERROR,
3426 FL("sme_SetSignificantChange failed(err=%d)"), status);
3427 vos_mem_free(pReqMsg);
3428 return -EINVAL;
3429 }
Dino Myclee8843b32014-07-04 14:21:45 +05303430 vos_mem_free(pReqMsg);
Dino Mycle6fb96c12014-06-10 11:52:40 +05303431 hddLog(VOS_TRACE_LEVEL_ERROR, FL(" Exiting"));
3432 return 0;
3433
3434fail:
3435 vos_mem_free(pReqMsg);
3436 return -EINVAL;
3437}
3438
3439static int wlan_hdd_cfg80211_extscan_get_valid_channels(struct wiphy *wiphy,
3440 struct wireless_dev *wdev,
3441 void *data, int dataLen)
3442{
3443 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
3444 tANI_U32 ChannelList[WNI_CFG_VALID_CHANNEL_LIST_LEN] = {0};
3445 tANI_U8 numChannels = 0;
3446 struct nlattr *tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX + 1];
3447 tANI_U32 requestId;
3448 tWifiBand wifiBand;
3449 eHalStatus status;
3450 struct sk_buff *replySkb;
3451 tANI_U8 i;
3452
3453 hddLog(VOS_TRACE_LEVEL_INFO, FL("Entering"));
3454 status = wlan_hdd_validate_context(pHddCtx);
3455 if (0 != status)
3456 {
3457 hddLog(VOS_TRACE_LEVEL_ERROR,
3458 FL("HDD context is not valid"));
3459 return -EINVAL;
3460 }
Dino Myclee8843b32014-07-04 14:21:45 +05303461 /* check the EXTScan Capability */
3462 if ( (TRUE != pHddCtx->cfg_ini->fEnableEXTScan) ||
3463 (TRUE != sme_IsFeatureSupportedByFW(EXTENDED_SCAN)))
3464 {
3465 hddLog(VOS_TRACE_LEVEL_ERROR,
3466 FL("EXTScan not enabled/supported by Firmware"));
3467 return -EINVAL;
3468 }
3469
Dino Mycle6fb96c12014-06-10 11:52:40 +05303470 if (nla_parse(tb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX,
3471 data, dataLen,
3472 wlan_hdd_extscan_config_policy)) {
3473 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Invalid ATTR"));
3474 return -EINVAL;
3475 }
3476
3477 /* Parse and fetch request Id */
3478 if (!tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_REQUEST_ID]) {
3479 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr request id failed"));
3480 return -EINVAL;
3481 }
3482 requestId = nla_get_u32(
3483 tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_REQUEST_ID]);
3484 hddLog(VOS_TRACE_LEVEL_INFO, FL("Req Id (%d)"), requestId);
3485
3486 /* Parse and fetch wifi band */
3487 if (!tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_GET_VALID_CHANNELS_CONFIG_PARAM_WIFI_BAND])
3488 {
3489 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr wifi band failed"));
3490 return -EINVAL;
3491 }
3492 wifiBand = nla_get_u32(
3493 tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_GET_VALID_CHANNELS_CONFIG_PARAM_WIFI_BAND]);
3494 hddLog(VOS_TRACE_LEVEL_INFO, FL("Wifi band (%d)"), wifiBand);
3495
3496 status = sme_GetValidChannelsByBand((tHalHandle)(pHddCtx->hHal),
3497 wifiBand, ChannelList,
3498 &numChannels);
3499 if (eHAL_STATUS_SUCCESS != status) {
3500 hddLog(VOS_TRACE_LEVEL_ERROR,
3501 FL("sme_GetValidChannelsByBand failed (err=%d)"), status);
3502 return -EINVAL;
3503 }
3504 hddLog(VOS_TRACE_LEVEL_INFO, FL("Number of channels (%d)"), numChannels);
3505 for (i = 0; i < numChannels; i++)
3506 hddLog(VOS_TRACE_LEVEL_INFO, "Channel: %u ", ChannelList[i]);
3507
3508 replySkb = cfg80211_vendor_cmd_alloc_reply_skb(wiphy, sizeof(u32) +
3509 sizeof(u32) * numChannels +
3510 NLMSG_HDRLEN);
3511
3512 if (!replySkb) {
3513 hddLog(VOS_TRACE_LEVEL_ERROR,
3514 FL("valid channels: buffer alloc fail"));
3515 return -EINVAL;
3516 }
3517 if (nla_put_u32(replySkb,
3518 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_NUM_CHANNELS,
3519 numChannels) ||
3520 nla_put(replySkb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_CHANNELS,
3521 sizeof(u32) * numChannels, ChannelList)) {
3522
3523 hddLog(VOS_TRACE_LEVEL_ERROR, FL("nla put fail"));
3524 kfree_skb(replySkb);
3525 return -EINVAL;
3526 }
3527
3528 return cfg80211_vendor_cmd_reply(replySkb);
3529}
3530
3531static int wlan_hdd_cfg80211_extscan_start(struct wiphy *wiphy,
3532 struct wireless_dev *wdev,
3533 void *data, int dataLen)
3534{
Dino Myclee8843b32014-07-04 14:21:45 +05303535 tpSirEXTScanStartReqParams pReqMsg = NULL;
Dino Mycle6fb96c12014-06-10 11:52:40 +05303536 struct net_device *dev = wdev->netdev;
3537 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
3538 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
3539 struct nlattr *tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX + 1];
3540 struct nlattr *bucket[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX + 1];
3541 struct nlattr *channel[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX + 1];
3542 struct nlattr *buckets;
3543 struct nlattr *channels;
3544 int rem1;
3545 int rem2;
3546 eHalStatus status;
Dasari Srinivas8b2ce272014-09-16 16:57:30 +05303547 tANI_U32 j = 0, index = 0;
Dino Mycle6fb96c12014-06-10 11:52:40 +05303548
3549 status = wlan_hdd_validate_context(pHddCtx);
3550 if (0 != status)
3551 {
3552 hddLog(VOS_TRACE_LEVEL_ERROR,
3553 FL("HDD context is not valid"));
3554 return -EINVAL;
3555 }
Dino Myclee8843b32014-07-04 14:21:45 +05303556 /* check the EXTScan Capability */
3557 if ( (TRUE != pHddCtx->cfg_ini->fEnableEXTScan) ||
3558 (TRUE != sme_IsFeatureSupportedByFW(EXTENDED_SCAN)))
3559 {
3560 hddLog(VOS_TRACE_LEVEL_ERROR,
3561 FL("EXTScan not enabled/supported by Firmware"));
3562 return -EINVAL;
3563 }
3564
Dino Mycle6fb96c12014-06-10 11:52:40 +05303565 if (nla_parse(tb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX,
3566 data, dataLen,
3567 wlan_hdd_extscan_config_policy)) {
3568 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Invalid ATTR"));
3569 return -EINVAL;
3570 }
3571
3572 /* Parse and fetch request Id */
3573 if (!tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_REQUEST_ID]) {
3574 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr request id failed"));
3575 return -EINVAL;
3576 }
3577
Dino Myclee8843b32014-07-04 14:21:45 +05303578 pReqMsg = (tpSirEXTScanStartReqParams)
3579 vos_mem_malloc(sizeof(*pReqMsg));
Dino Mycle6fb96c12014-06-10 11:52:40 +05303580 if (!pReqMsg) {
Dino Myclee8843b32014-07-04 14:21:45 +05303581 hddLog(VOS_TRACE_LEVEL_ERROR, FL("vos_mem_malloc failed"));
3582 return -ENOMEM;
Dino Mycle6fb96c12014-06-10 11:52:40 +05303583 }
3584
3585 pReqMsg->requestId = nla_get_u32(
3586 tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_REQUEST_ID]);
3587 hddLog(VOS_TRACE_LEVEL_INFO, FL("Req Id (%d)"), pReqMsg->requestId);
3588
3589 pReqMsg->sessionId = pAdapter->sessionId;
3590 hddLog(VOS_TRACE_LEVEL_INFO, FL("Session Id (%d)"), pReqMsg->sessionId);
3591
3592 /* Parse and fetch base period */
3593 if (!tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SCAN_CMD_PARAMS_BASE_PERIOD]) {
3594 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr base period failed"));
3595 goto fail;
3596 }
3597 pReqMsg->basePeriod = nla_get_u32(
3598 tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SCAN_CMD_PARAMS_BASE_PERIOD]);
3599 hddLog(VOS_TRACE_LEVEL_INFO, FL("Base Period (%d)"),
3600 pReqMsg->basePeriod);
3601
3602 /* Parse and fetch max AP per scan */
3603 if (!tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SCAN_CMD_PARAMS_MAX_AP_PER_SCAN]) {
3604 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr max_ap_per_scan failed"));
3605 goto fail;
3606 }
3607 pReqMsg->maxAPperScan = nla_get_u32(
3608 tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SCAN_CMD_PARAMS_MAX_AP_PER_SCAN]);
3609 hddLog(VOS_TRACE_LEVEL_INFO, FL("Max AP per Scan (%d)"),
3610 pReqMsg->maxAPperScan);
3611
3612 /* Parse and fetch report threshold */
3613 if (!tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SCAN_CMD_PARAMS_REPORT_THRESHOLD]) {
3614 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr report_threshold failed"));
3615 goto fail;
3616 }
3617 pReqMsg->reportThreshold = nla_get_u8(
3618 tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SCAN_CMD_PARAMS_REPORT_THRESHOLD]);
3619 hddLog(VOS_TRACE_LEVEL_INFO, FL("Report Threshold (%d)"),
3620 pReqMsg->reportThreshold);
3621
3622 /* Parse and fetch number of buckets */
3623 if (!tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SCAN_CMD_PARAMS_NUM_BUCKETS]) {
3624 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr number of buckets failed"));
3625 goto fail;
3626 }
3627 pReqMsg->numBuckets = nla_get_u8(
3628 tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SCAN_CMD_PARAMS_NUM_BUCKETS]);
3629 if (pReqMsg->numBuckets > WLAN_EXTSCAN_MAX_BUCKETS) {
3630 hddLog(VOS_TRACE_LEVEL_WARN, FL("Exceeded MAX number of buckets "
3631 "Setting numBuckets to %u"), WLAN_EXTSCAN_MAX_BUCKETS);
3632 pReqMsg->numBuckets = WLAN_EXTSCAN_MAX_BUCKETS;
3633 }
3634 hddLog(VOS_TRACE_LEVEL_INFO, FL("Number of Buckets (%d)"),
3635 pReqMsg->numBuckets);
3636 if (!tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC]) {
3637 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr bucket spec failed"));
3638 goto fail;
3639 }
3640
3641 nla_for_each_nested(buckets,
3642 tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC], rem1) {
3643 if(nla_parse(bucket,
3644 QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX,
3645 nla_data(buckets), nla_len(buckets), NULL)) { //policy
3646 hddLog(VOS_TRACE_LEVEL_ERROR, FL("nla_parse failed"));
3647 goto fail;
3648 }
3649
3650 /* Parse and fetch bucket spec */
3651 if (!bucket[QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_INDEX]) {
3652 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr bucket index failed"));
3653 goto fail;
3654 }
Dasari Srinivas8b2ce272014-09-16 16:57:30 +05303655
3656 pReqMsg->buckets[index].bucket = nla_get_u8(
3657 bucket[QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_INDEX]);
3658
3659 hddLog(VOS_TRACE_LEVEL_INFO, FL("Bucket spec Index (%d)"),
3660 pReqMsg->buckets[index].bucket);
Dino Mycle6fb96c12014-06-10 11:52:40 +05303661
3662 /* Parse and fetch wifi band */
3663 if (!bucket[QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_BAND]) {
3664 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr wifi band failed"));
3665 goto fail;
3666 }
Dasari Srinivas8b2ce272014-09-16 16:57:30 +05303667 pReqMsg->buckets[index].band = nla_get_u8(
Dino Mycle6fb96c12014-06-10 11:52:40 +05303668 bucket[QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_BAND]);
3669 hddLog(VOS_TRACE_LEVEL_INFO, FL("Wifi band (%d)"),
Dasari Srinivas8b2ce272014-09-16 16:57:30 +05303670 pReqMsg->buckets[index].band);
Dino Mycle6fb96c12014-06-10 11:52:40 +05303671
3672 /* Parse and fetch period */
3673 if (!bucket[QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_PERIOD]) {
3674 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr period failed"));
3675 goto fail;
3676 }
Dasari Srinivas8b2ce272014-09-16 16:57:30 +05303677 pReqMsg->buckets[index].period = nla_get_u32(
Dino Mycle6fb96c12014-06-10 11:52:40 +05303678 bucket[QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_PERIOD]);
3679 hddLog(VOS_TRACE_LEVEL_INFO, FL("period (%d)"),
Dasari Srinivas8b2ce272014-09-16 16:57:30 +05303680 pReqMsg->buckets[index].period);
Dino Mycle6fb96c12014-06-10 11:52:40 +05303681
3682 /* Parse and fetch report events */
3683 if (!bucket[QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_REPORT_EVENTS]) {
3684 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr report events failed"));
3685 goto fail;
3686 }
Dasari Srinivas8b2ce272014-09-16 16:57:30 +05303687 pReqMsg->buckets[index].reportEvents = nla_get_u8(
Dino Mycle6fb96c12014-06-10 11:52:40 +05303688 bucket[QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_REPORT_EVENTS]);
3689 hddLog(VOS_TRACE_LEVEL_INFO, FL("report events (%d)"),
Dasari Srinivas8b2ce272014-09-16 16:57:30 +05303690 pReqMsg->buckets[index].reportEvents);
Dino Mycle6fb96c12014-06-10 11:52:40 +05303691
3692 /* Parse and fetch number of channels */
Dasari Srinivas8b2ce272014-09-16 16:57:30 +05303693 if (!bucket[QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_NUM_CHANNEL_SPECS])
3694 {
Dino Mycle6fb96c12014-06-10 11:52:40 +05303695 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr num channels failed"));
3696 goto fail;
3697 }
Dasari Srinivas8b2ce272014-09-16 16:57:30 +05303698 pReqMsg->buckets[index].numChannels = nla_get_u32(
Dino Mycle6fb96c12014-06-10 11:52:40 +05303699 bucket[QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_NUM_CHANNEL_SPECS]);
3700 hddLog(VOS_TRACE_LEVEL_INFO, FL("num channels (%d)"),
Dasari Srinivas8b2ce272014-09-16 16:57:30 +05303701 pReqMsg->buckets[index].numChannels);
Dino Mycle6fb96c12014-06-10 11:52:40 +05303702
3703 if (!bucket[QCA_WLAN_VENDOR_ATTR_EXTSCAN_CHANNEL_SPEC]) {
3704 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr channel spec failed"));
3705 goto fail;
3706 }
3707
3708 j = 0;
3709 nla_for_each_nested(channels,
3710 bucket[QCA_WLAN_VENDOR_ATTR_EXTSCAN_CHANNEL_SPEC], rem2) {
3711 if(nla_parse(channel,
3712 QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX,
3713 nla_data(channels), nla_len(channels),
3714 NULL)) { //wlan_hdd_extscan_config_policy here
3715 hddLog(VOS_TRACE_LEVEL_ERROR, FL("nla_parse failed"));
3716 goto fail;
3717 }
3718
3719 /* Parse and fetch channel */
3720 if (!channel[QCA_WLAN_VENDOR_ATTR_EXTSCAN_CHANNEL_SPEC_CHANNEL]) {
3721 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr channel failed"));
3722 goto fail;
3723 }
Dasari Srinivas8b2ce272014-09-16 16:57:30 +05303724 pReqMsg->buckets[index].channels[j].channel = nla_get_u32(
Dino Mycle6fb96c12014-06-10 11:52:40 +05303725 channel[QCA_WLAN_VENDOR_ATTR_EXTSCAN_CHANNEL_SPEC_CHANNEL]);
3726 hddLog(VOS_TRACE_LEVEL_INFO, FL("channel (%u)"),
Dasari Srinivas8b2ce272014-09-16 16:57:30 +05303727 pReqMsg->buckets[index].channels[j].channel);
Dino Mycle6fb96c12014-06-10 11:52:40 +05303728
3729 /* Parse and fetch dwell time */
3730 if (!channel[QCA_WLAN_VENDOR_ATTR_EXTSCAN_CHANNEL_SPEC_DWELL_TIME]) {
3731 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr dwelltime failed"));
3732 goto fail;
3733 }
Dasari Srinivas8b2ce272014-09-16 16:57:30 +05303734 pReqMsg->buckets[index].channels[j].dwellTimeMs = nla_get_u32(
Dino Mycle6fb96c12014-06-10 11:52:40 +05303735 channel[QCA_WLAN_VENDOR_ATTR_EXTSCAN_CHANNEL_SPEC_DWELL_TIME]);
3736 hddLog(VOS_TRACE_LEVEL_INFO, FL("Dwell time (%u ms)"),
Dasari Srinivas8b2ce272014-09-16 16:57:30 +05303737 pReqMsg->buckets[index].channels[j].dwellTimeMs);
Dino Mycle6fb96c12014-06-10 11:52:40 +05303738
3739 /* Parse and fetch channel spec passive */
3740 if (!channel[QCA_WLAN_VENDOR_ATTR_EXTSCAN_CHANNEL_SPEC_PASSIVE]) {
3741 hddLog(VOS_TRACE_LEVEL_ERROR,
3742 FL("attr channel spec passive failed"));
3743 goto fail;
3744 }
Dasari Srinivas8b2ce272014-09-16 16:57:30 +05303745 pReqMsg->buckets[index].channels[j].passive = nla_get_u8(
Dino Mycle6fb96c12014-06-10 11:52:40 +05303746 channel[QCA_WLAN_VENDOR_ATTR_EXTSCAN_CHANNEL_SPEC_PASSIVE]);
3747 hddLog(VOS_TRACE_LEVEL_INFO, FL("Chnl spec passive (%u)"),
Dasari Srinivas8b2ce272014-09-16 16:57:30 +05303748 pReqMsg->buckets[index].channels[j].passive);
Dino Mycle6fb96c12014-06-10 11:52:40 +05303749 j++;
3750 }
Dasari Srinivas8b2ce272014-09-16 16:57:30 +05303751 index++;
Dino Mycle6fb96c12014-06-10 11:52:40 +05303752 }
3753 status = sme_EXTScanStart(pHddCtx->hHal, pReqMsg);
3754 if (!HAL_STATUS_SUCCESS(status)) {
3755 hddLog(VOS_TRACE_LEVEL_ERROR,
3756 FL("sme_EXTScanStart failed(err=%d)"), status);
3757 vos_mem_free(pReqMsg);
3758 return -EINVAL;
3759 }
3760
Dino Myclee8843b32014-07-04 14:21:45 +05303761 vos_mem_free(pReqMsg);
Dino Mycle6fb96c12014-06-10 11:52:40 +05303762 return 0;
3763
3764fail:
3765 vos_mem_free(pReqMsg);
3766 return -EINVAL;
3767}
3768
3769static int wlan_hdd_cfg80211_extscan_stop(struct wiphy *wiphy,
3770 struct wireless_dev *wdev,
3771 void *data, int dataLen)
3772{
Dino Myclee8843b32014-07-04 14:21:45 +05303773 tSirEXTScanStopReqParams reqMsg;
Dino Mycle6fb96c12014-06-10 11:52:40 +05303774 struct net_device *dev = wdev->netdev;
3775 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
3776 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
3777 struct nlattr *tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX + 1];
3778 eHalStatus status;
3779
3780 status = wlan_hdd_validate_context(pHddCtx);
3781 if (0 != status)
3782 {
3783 hddLog(VOS_TRACE_LEVEL_ERROR,
3784 FL("HDD context is not valid"));
3785 return -EINVAL;
3786 }
Dino Myclee8843b32014-07-04 14:21:45 +05303787 /* check the EXTScan Capability */
3788 if ( (TRUE != pHddCtx->cfg_ini->fEnableEXTScan) ||
3789 (TRUE != sme_IsFeatureSupportedByFW(EXTENDED_SCAN)))
3790 {
3791 hddLog(VOS_TRACE_LEVEL_ERROR,
3792 FL("EXTScan not enabled/supported by Firmware"));
3793 return -EINVAL;
3794 }
3795
Dino Mycle6fb96c12014-06-10 11:52:40 +05303796 if (nla_parse(tb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX,
3797 data, dataLen,
3798 wlan_hdd_extscan_config_policy)) {
3799 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Invalid ATTR"));
3800 return -EINVAL;
3801 }
3802
3803 /* Parse and fetch request Id */
3804 if (!tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_REQUEST_ID]) {
3805 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr request id failed"));
3806 return -EINVAL;
3807 }
3808
Dino Myclee8843b32014-07-04 14:21:45 +05303809 reqMsg.requestId = nla_get_u32(
Dino Mycle6fb96c12014-06-10 11:52:40 +05303810 tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_REQUEST_ID]);
Dino Myclee8843b32014-07-04 14:21:45 +05303811 hddLog(VOS_TRACE_LEVEL_INFO, FL("Req Id (%d)"), reqMsg.requestId);
Dino Mycle6fb96c12014-06-10 11:52:40 +05303812
Dino Myclee8843b32014-07-04 14:21:45 +05303813 reqMsg.sessionId = pAdapter->sessionId;
3814 hddLog(VOS_TRACE_LEVEL_INFO, FL("Session Id (%d)"), reqMsg.sessionId);
Dino Mycle6fb96c12014-06-10 11:52:40 +05303815
Dino Myclee8843b32014-07-04 14:21:45 +05303816 status = sme_EXTScanStop(pHddCtx->hHal, &reqMsg);
Dino Mycle6fb96c12014-06-10 11:52:40 +05303817 if (!HAL_STATUS_SUCCESS(status)) {
3818 hddLog(VOS_TRACE_LEVEL_ERROR,
3819 FL("sme_EXTScanStop failed(err=%d)"), status);
Dino Mycle6fb96c12014-06-10 11:52:40 +05303820 return -EINVAL;
3821 }
3822
3823 return 0;
3824}
3825
3826static int wlan_hdd_cfg80211_extscan_reset_bssid_hotlist(struct wiphy *wiphy,
3827 struct wireless_dev *wdev,
3828 void *data, int dataLen)
3829{
Dino Myclee8843b32014-07-04 14:21:45 +05303830 tSirEXTScanResetBssidHotlistReqParams reqMsg;
Dino Mycle6fb96c12014-06-10 11:52:40 +05303831 struct net_device *dev = wdev->netdev;
3832 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
3833 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
3834 struct nlattr *tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX + 1];
3835 eHalStatus status;
3836
3837 status = wlan_hdd_validate_context(pHddCtx);
3838 if (0 != status)
3839 {
3840 hddLog(VOS_TRACE_LEVEL_ERROR,
3841 FL("HDD context is not valid"));
3842 return -EINVAL;
3843 }
Dino Myclee8843b32014-07-04 14:21:45 +05303844 /* check the EXTScan Capability */
3845 if ( (TRUE != pHddCtx->cfg_ini->fEnableEXTScan) ||
3846 (TRUE != sme_IsFeatureSupportedByFW(EXTENDED_SCAN)))
3847 {
3848 hddLog(VOS_TRACE_LEVEL_ERROR,
3849 FL("EXTScan not enabled/supported by Firmware"));
3850 return -EINVAL;
3851 }
3852
Dino Mycle6fb96c12014-06-10 11:52:40 +05303853 if (nla_parse(tb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX,
3854 data, dataLen,
3855 wlan_hdd_extscan_config_policy)) {
3856 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Invalid ATTR"));
3857 return -EINVAL;
3858 }
3859
3860 /* Parse and fetch request Id */
3861 if (!tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_REQUEST_ID]) {
3862 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr request id failed"));
3863 return -EINVAL;
3864 }
3865
Dino Myclee8843b32014-07-04 14:21:45 +05303866 reqMsg.requestId = nla_get_u32(
Dino Mycle6fb96c12014-06-10 11:52:40 +05303867 tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_REQUEST_ID]);
Dino Myclee8843b32014-07-04 14:21:45 +05303868 hddLog(VOS_TRACE_LEVEL_INFO, FL("Req Id (%d)"), reqMsg.requestId);
Dino Mycle6fb96c12014-06-10 11:52:40 +05303869
Dino Myclee8843b32014-07-04 14:21:45 +05303870 reqMsg.sessionId = pAdapter->sessionId;
3871 hddLog(VOS_TRACE_LEVEL_INFO, FL("Session Id (%d)"), reqMsg.sessionId);
Dino Mycle6fb96c12014-06-10 11:52:40 +05303872
Dino Myclee8843b32014-07-04 14:21:45 +05303873 status = sme_ResetBssHotlist(pHddCtx->hHal, &reqMsg);
Dino Mycle6fb96c12014-06-10 11:52:40 +05303874 if (!HAL_STATUS_SUCCESS(status)) {
3875 hddLog(VOS_TRACE_LEVEL_ERROR,
3876 FL("sme_ResetBssHotlist failed(err=%d)"), status);
Dino Mycle6fb96c12014-06-10 11:52:40 +05303877 return -EINVAL;
3878 }
3879
3880 return 0;
3881}
3882
3883static int wlan_hdd_cfg80211_extscan_reset_significant_change(
3884 struct wiphy *wiphy,
3885 struct wireless_dev *wdev,
3886 void *data, int dataLen)
3887{
Dino Myclee8843b32014-07-04 14:21:45 +05303888 tSirEXTScanResetSignificantChangeReqParams reqMsg;
Dino Mycle6fb96c12014-06-10 11:52:40 +05303889 struct net_device *dev = wdev->netdev;
3890 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
3891 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
3892 struct nlattr *tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX + 1];
3893 eHalStatus status;
3894
3895 hddLog(VOS_TRACE_LEVEL_INFO, FL(" Entering"));
3896 status = wlan_hdd_validate_context(pHddCtx);
3897 if (0 != status)
3898 {
3899 hddLog(VOS_TRACE_LEVEL_ERROR,
3900 FL("HDD context is not valid"));
3901 return -EINVAL;
3902 }
Dino Myclee8843b32014-07-04 14:21:45 +05303903 /* check the EXTScan Capability */
3904 if ( (TRUE != pHddCtx->cfg_ini->fEnableEXTScan) ||
3905 (TRUE != sme_IsFeatureSupportedByFW(EXTENDED_SCAN)))
3906 {
3907 hddLog(VOS_TRACE_LEVEL_ERROR,
3908 FL("EXTScan not enabled/supported by Firmware"));
3909 return -EINVAL;
3910 }
3911
Dino Mycle6fb96c12014-06-10 11:52:40 +05303912 if (nla_parse(tb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX,
3913 data, dataLen,
3914 wlan_hdd_extscan_config_policy)) {
3915 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Invalid ATTR"));
3916 return -EINVAL;
3917 }
3918
3919 /* Parse and fetch request Id */
3920 if (!tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_REQUEST_ID]) {
3921 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr request id failed"));
3922 return -EINVAL;
3923 }
3924
Dino Mycle6fb96c12014-06-10 11:52:40 +05303925
Dino Myclee8843b32014-07-04 14:21:45 +05303926 reqMsg.requestId = nla_get_u32(
Dino Mycle6fb96c12014-06-10 11:52:40 +05303927 tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_REQUEST_ID]);
Dino Myclee8843b32014-07-04 14:21:45 +05303928 hddLog(VOS_TRACE_LEVEL_INFO, FL("Req Id (%d)"), reqMsg.requestId);
Dino Mycle6fb96c12014-06-10 11:52:40 +05303929
Dino Myclee8843b32014-07-04 14:21:45 +05303930 reqMsg.sessionId = pAdapter->sessionId;
3931 hddLog(VOS_TRACE_LEVEL_INFO, FL("Session Id (%d)"), reqMsg.sessionId);
Dino Mycle6fb96c12014-06-10 11:52:40 +05303932
Dino Myclee8843b32014-07-04 14:21:45 +05303933 status = sme_ResetSignificantChange(pHddCtx->hHal, &reqMsg);
Dino Mycle6fb96c12014-06-10 11:52:40 +05303934 if (!HAL_STATUS_SUCCESS(status)) {
3935 hddLog(VOS_TRACE_LEVEL_ERROR,
3936 FL("sme_ResetSignificantChange failed(err=%d)"), status);
Dino Mycle6fb96c12014-06-10 11:52:40 +05303937 return -EINVAL;
3938 }
3939
3940 hddLog(VOS_TRACE_LEVEL_ERROR, FL(" Exiting"));
3941 return 0;
3942}
3943
3944#endif /* WLAN_FEATURE_EXTSCAN */
3945
Atul Mittal115287b2014-07-08 13:26:33 +05303946/*EXT TDLS*/
3947static const struct nla_policy
3948wlan_hdd_tdls_config_enable_policy[QCA_WLAN_VENDOR_ATTR_TDLS_ENABLE_MAX +1] =
3949{
3950 [QCA_WLAN_VENDOR_ATTR_TDLS_ENABLE_MAC_ADDR] = {.type = NLA_UNSPEC },
3951 [QCA_WLAN_VENDOR_ATTR_TDLS_ENABLE_CHANNEL] = {.type = NLA_S32 },
3952 [QCA_WLAN_VENDOR_ATTR_TDLS_ENABLE_GLOBAL_OPERATING_CLASS] =
3953 {.type = NLA_S32 },
3954 [QCA_WLAN_VENDOR_ATTR_TDLS_ENABLE_MAX_LATENCY_MS] = {.type = NLA_S32 },
3955 [QCA_WLAN_VENDOR_ATTR_TDLS_ENABLE_MIN_BANDWIDTH_KBPS] = {.type = NLA_S32 },
3956
3957};
3958
3959static const struct nla_policy
3960wlan_hdd_tdls_config_disable_policy[QCA_WLAN_VENDOR_ATTR_TDLS_DISABLE_MAX +1] =
3961{
3962 [QCA_WLAN_VENDOR_ATTR_TDLS_DISABLE_MAC_ADDR] = {.type = NLA_UNSPEC },
3963
3964};
3965
3966static const struct nla_policy
3967wlan_hdd_tdls_config_state_change_policy[
3968 QCA_WLAN_VENDOR_ATTR_TDLS_STATE_MAX +1] =
3969{
3970 [QCA_WLAN_VENDOR_ATTR_TDLS_STATE_MAC_ADDR] = {.type = NLA_UNSPEC },
3971 [QCA_WLAN_VENDOR_ATTR_TDLS_NEW_STATE] = {.type = NLA_S32 },
3972 [QCA_WLAN_VENDOR_ATTR_TDLS_STATE_REASON] = {.type = NLA_S32 },
Atul Mittal0a9f68d2014-10-16 15:26:38 +05303973 [QCA_WLAN_VENDOR_ATTR_TDLS_STATE_CHANNEL] = {.type = NLA_S32 },
3974 [QCA_WLAN_VENDOR_ATTR_TDLS_STATE_GLOBAL_OPERATING_CLASS] =
3975 {.type = NLA_S32 },
Atul Mittal115287b2014-07-08 13:26:33 +05303976
3977};
3978
3979static const struct nla_policy
3980wlan_hdd_tdls_config_get_status_policy[
3981 QCA_WLAN_VENDOR_ATTR_TDLS_GET_STATUS_MAX +1] =
3982{
3983 [QCA_WLAN_VENDOR_ATTR_TDLS_GET_STATUS_MAC_ADDR] = {.type = NLA_UNSPEC },
3984 [QCA_WLAN_VENDOR_ATTR_TDLS_GET_STATUS_STATE] = {.type = NLA_S32 },
3985 [QCA_WLAN_VENDOR_ATTR_TDLS_GET_STATUS_REASON] = {.type = NLA_S32 },
Atul Mittal0a9f68d2014-10-16 15:26:38 +05303986 [QCA_WLAN_VENDOR_ATTR_TDLS_GET_STATUS_CHANNEL] = {.type = NLA_S32 },
3987 [QCA_WLAN_VENDOR_ATTR_TDLS_GET_STATUS_GLOBAL_OPERATING_CLASS]
3988 = {.type = NLA_S32 },
Atul Mittal115287b2014-07-08 13:26:33 +05303989
3990};
Siddharth Bhala3a5cb42014-09-29 21:13:13 +05303991
3992static const struct nla_policy
3993wlan_hdd_mac_config[QCA_WLAN_VENDOR_ATTR_SET_SCANNING_MAC_OUI_MAX+1] =
3994{
3995 [QCA_WLAN_VENDOR_ATTR_SET_SCANNING_MAC_OUI] = {.type = NLA_UNSPEC },
3996};
3997
3998static int wlan_hdd_cfg80211_set_spoofed_mac_oui(struct wiphy *wiphy,
3999 struct wireless_dev *wdev,
4000 void *data,
4001 int data_len)
4002{
4003
4004 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
4005 struct nlattr *tb[QCA_WLAN_VENDOR_ATTR_SET_SCANNING_MAC_OUI_MAX + 1];
4006
4007 if (0 != wlan_hdd_validate_context(pHddCtx)){
4008 hddLog(VOS_TRACE_LEVEL_ERROR, FL("hdd Ctx invalid while spoof macAddr"));
4009 return -EINVAL;
4010 }
4011 if (FALSE == pHddCtx->cfg_ini->enableMacSpoofing) {
4012 hddLog(VOS_TRACE_LEVEL_ERROR, FL("MAC_SPOOFED_SCAN disabled in ini"));
4013 return -ENOTSUPP;
Siddharth Bhal76972212014-10-15 16:22:51 +05304014 }
Siddharth Bhala3a5cb42014-09-29 21:13:13 +05304015 if (TRUE != sme_IsFeatureSupportedByFW(MAC_SPOOFED_SCAN)){
4016 hddLog(VOS_TRACE_LEVEL_ERROR, FL("MAC_SPOOFED_SCAN not supported by FW"));
4017 return -ENOTSUPP;
4018 }
4019
4020 if (nla_parse(tb, QCA_WLAN_VENDOR_ATTR_SET_SCANNING_MAC_OUI_MAX,
4021 data, data_len, wlan_hdd_mac_config)) {
4022 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Invalid ATTR"));
4023 return -EINVAL;
4024 }
4025
4026 /* Parse and fetch mac address */
4027 if (!tb[QCA_WLAN_VENDOR_ATTR_SET_SCANNING_MAC_OUI]) {
4028 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr mac addr failed"));
4029 return -EINVAL;
4030 }
4031
4032 memcpy(pHddCtx->spoofMacAddr.randomMacAddr.bytes, nla_data(
4033 tb[QCA_WLAN_VENDOR_ATTR_SET_SCANNING_MAC_OUI]),
4034 VOS_MAC_ADDR_LAST_3_BYTES);
4035
Siddharth Bhal76972212014-10-15 16:22:51 +05304036 pHddCtx->spoofMacAddr.isEnabled = TRUE;
4037
4038 vos_trace_hex_dump( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO, nla_data(
Siddharth Bhala3a5cb42014-09-29 21:13:13 +05304039 tb[QCA_WLAN_VENDOR_ATTR_SET_SCANNING_MAC_OUI]),
4040 VOS_MAC_ADDR_FIRST_3_BYTES);
Siddharth Bhal76972212014-10-15 16:22:51 +05304041 if ((pHddCtx->spoofMacAddr.randomMacAddr.bytes[0] == 0) &&
4042 (pHddCtx->spoofMacAddr.randomMacAddr.bytes[1] == 0) &&
4043 (pHddCtx->spoofMacAddr.randomMacAddr.bytes[2] == 0))
4044 {
4045 hddLog(LOG1, FL("ZERO MAC OUI Recieved. Disabling Spoofing"));
4046 vos_mem_zero(pHddCtx->spoofMacAddr.randomMacAddr.bytes,
4047 VOS_MAC_ADDRESS_LEN);
4048 pHddCtx->spoofMacAddr.isEnabled = FALSE;
Siddharth Bhala3a5cb42014-09-29 21:13:13 +05304049 }
Siddharth Bhala3a5cb42014-09-29 21:13:13 +05304050
Siddharth Bhal76972212014-10-15 16:22:51 +05304051 if (VOS_STATUS_SUCCESS != hdd_processSpoofMacAddrRequest(pHddCtx))
4052 {
Siddharth Bhala3a5cb42014-09-29 21:13:13 +05304053 hddLog(LOGE, FL("Failed to send Spoof Mac Addr to FW"));
4054 }
4055
4056 return 0;
4057}
4058
Atul Mittal115287b2014-07-08 13:26:33 +05304059static int wlan_hdd_cfg80211_exttdls_get_status(struct wiphy *wiphy,
4060 struct wireless_dev *wdev,
4061 void *data,
4062 int data_len)
4063{
4064 u8 peer[6] = {0};
4065 struct net_device *dev = wdev->netdev;
4066 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
4067 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
4068 struct nlattr *tb[QCA_WLAN_VENDOR_ATTR_TDLS_GET_STATUS_MAX + 1];
4069 eHalStatus ret;
4070 tANI_S32 state;
4071 tANI_S32 reason;
Atul Mittal0a9f68d2014-10-16 15:26:38 +05304072 tANI_S32 global_operating_class = 0;
4073 tANI_S32 channel = 0;
Atul Mittal115287b2014-07-08 13:26:33 +05304074 struct sk_buff *skb = NULL;
4075
4076 ret = wlan_hdd_validate_context(pHddCtx);
4077 if (0 != ret) {
4078
4079 return -EINVAL;
4080 }
4081 if (pHddCtx->cfg_ini->fTDLSExternalControl == FALSE) {
4082
4083 return -ENOTSUPP;
4084 }
4085 if (nla_parse(tb, QCA_WLAN_VENDOR_ATTR_TDLS_GET_STATUS_MAX,
4086 data, data_len,
4087 wlan_hdd_tdls_config_get_status_policy)) {
4088 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Invalid ATTR"));
4089 return -EINVAL;
4090 }
4091
4092 /* Parse and fetch mac address */
4093 if (!tb[QCA_WLAN_VENDOR_ATTR_TDLS_GET_STATUS_MAC_ADDR]) {
4094 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr mac addr failed"));
4095 return -EINVAL;
4096 }
4097
4098 memcpy(peer, nla_data(
4099 tb[QCA_WLAN_VENDOR_ATTR_TDLS_GET_STATUS_MAC_ADDR]),
4100 sizeof(peer));
4101 hddLog(VOS_TRACE_LEVEL_INFO, FL(MAC_ADDRESS_STR),MAC_ADDR_ARRAY(peer));
4102
4103 ret = wlan_hdd_tdls_get_status(pAdapter, peer, &state, &reason);
4104
4105 if (0 != ret) {
4106 hddLog(VOS_TRACE_LEVEL_ERROR,
4107 FL("get status Failed"));
4108 return -EINVAL;
4109 }
4110 skb = cfg80211_vendor_cmd_alloc_reply_skb(wiphy,
Atul Mittal0a9f68d2014-10-16 15:26:38 +05304111 4 * sizeof(s32) +
Atul Mittal115287b2014-07-08 13:26:33 +05304112 NLMSG_HDRLEN);
4113
4114 if (!skb) {
4115 hddLog(VOS_TRACE_LEVEL_ERROR,
4116 FL("cfg80211_vendor_cmd_alloc_reply_skb failed"));
4117 return -EINVAL;
4118 }
Atul Mittal0a9f68d2014-10-16 15:26:38 +05304119 hddLog(VOS_TRACE_LEVEL_INFO, FL("Reason (%d) Status (%d) class (%d) channel (%d) peer" MAC_ADDRESS_STR),
Atul Mittal115287b2014-07-08 13:26:33 +05304120 reason,
4121 state,
Atul Mittal0a9f68d2014-10-16 15:26:38 +05304122 global_operating_class,
4123 channel,
Atul Mittal115287b2014-07-08 13:26:33 +05304124 MAC_ADDR_ARRAY(peer));
Atul Mittal0a9f68d2014-10-16 15:26:38 +05304125 if (nla_put_s32(skb,
4126 QCA_WLAN_VENDOR_ATTR_TDLS_GET_STATUS_STATE,
4127 state) ||
4128 nla_put_s32(skb,
4129 QCA_WLAN_VENDOR_ATTR_TDLS_GET_STATUS_REASON,
4130 reason) ||
4131 nla_put_s32(skb,
4132 QCA_WLAN_VENDOR_ATTR_TDLS_GET_STATUS_GLOBAL_OPERATING_CLASS,
4133 global_operating_class) ||
4134 nla_put_s32(skb,
4135 QCA_WLAN_VENDOR_ATTR_TDLS_GET_STATUS_CHANNEL,
4136 channel)) {
Atul Mittal115287b2014-07-08 13:26:33 +05304137
4138 hddLog(VOS_TRACE_LEVEL_ERROR, FL("nla put fail"));
4139 goto nla_put_failure;
4140 }
4141
4142 return cfg80211_vendor_cmd_reply(skb);
4143
4144nla_put_failure:
4145 kfree_skb(skb);
4146 return -EINVAL;
4147}
4148
4149static int wlan_hdd_cfg80211_exttdls_callback(tANI_U8* mac,
4150 tANI_S32 state,
4151 tANI_S32 reason,
4152 void *ctx)
4153{
4154 hdd_adapter_t* pAdapter = (hdd_adapter_t*)ctx;
4155 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
4156 struct sk_buff *skb = NULL;
Atul Mittal0a9f68d2014-10-16 15:26:38 +05304157 tANI_S32 global_operating_class = 0;
4158 tANI_S32 channel = 0;
Atul Mittal115287b2014-07-08 13:26:33 +05304159
4160 if (wlan_hdd_validate_context(pHddCtx)) {
4161 hddLog(VOS_TRACE_LEVEL_ERROR, FL("HDD context is not valid "));
4162 return -EINVAL;
4163 }
4164
4165 if (pHddCtx->cfg_ini->fTDLSExternalControl == FALSE) {
4166
4167 return -ENOTSUPP;
4168 }
4169 skb = cfg80211_vendor_event_alloc(
4170 pHddCtx->wiphy,
4171 EXTTDLS_EVENT_BUF_SIZE + NLMSG_HDRLEN,
4172 QCA_NL80211_VENDOR_SUBCMD_TDLS_STATE_CHANGE_INDEX,
4173 GFP_KERNEL);
4174
4175 if (!skb) {
4176 hddLog(VOS_TRACE_LEVEL_ERROR,
4177 FL("cfg80211_vendor_event_alloc failed"));
4178 return -EINVAL;
4179 }
4180 hddLog(VOS_TRACE_LEVEL_INFO, FL("Entering "));
Atul Mittal0a9f68d2014-10-16 15:26:38 +05304181 hddLog(VOS_TRACE_LEVEL_INFO, "Reason: (%d) Status: (%d) Class: (%d) Channel: (%d)",
4182 reason,
4183 state,
4184 global_operating_class,
4185 channel);
Atul Mittal115287b2014-07-08 13:26:33 +05304186 hddLog(VOS_TRACE_LEVEL_WARN, "tdls peer " MAC_ADDRESS_STR,
4187 MAC_ADDR_ARRAY(mac));
4188
Atul Mittal0a9f68d2014-10-16 15:26:38 +05304189 if (nla_put(skb,
4190 QCA_WLAN_VENDOR_ATTR_TDLS_STATE_MAC_ADDR,
4191 VOS_MAC_ADDR_SIZE, mac) ||
4192 nla_put_s32(skb,
4193 QCA_WLAN_VENDOR_ATTR_TDLS_NEW_STATE,
4194 state) ||
4195 nla_put_s32(skb,
4196 QCA_WLAN_VENDOR_ATTR_TDLS_STATE_REASON,
4197 reason) ||
4198 nla_put_s32(skb,
4199 QCA_WLAN_VENDOR_ATTR_TDLS_STATE_CHANNEL,
4200 channel) ||
4201 nla_put_s32(skb,
4202 QCA_WLAN_VENDOR_ATTR_TDLS_STATE_GLOBAL_OPERATING_CLASS,
4203 global_operating_class)
4204 ) {
Atul Mittal115287b2014-07-08 13:26:33 +05304205 hddLog(VOS_TRACE_LEVEL_ERROR, FL("nla put fail"));
4206 goto nla_put_failure;
4207 }
4208
4209 cfg80211_vendor_event(skb, GFP_KERNEL);
4210 return (0);
4211
4212nla_put_failure:
4213 kfree_skb(skb);
4214 return -EINVAL;
4215}
4216
4217static int wlan_hdd_cfg80211_exttdls_enable(struct wiphy *wiphy,
4218 struct wireless_dev *wdev,
4219 void *data,
4220 int data_len)
4221{
4222 u8 peer[6] = {0};
4223 struct net_device *dev = wdev->netdev;
4224 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
4225 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
4226 struct nlattr *tb[QCA_WLAN_VENDOR_ATTR_TDLS_ENABLE_MAX + 1];
4227 eHalStatus status;
4228 tdls_req_params_t pReqMsg = {0};
4229
4230 status = wlan_hdd_validate_context(pHddCtx);
4231 if (0 != status) {
4232 hddLog(VOS_TRACE_LEVEL_ERROR,
4233 FL("HDD context is not valid"));
4234 return -EINVAL;
4235 }
4236 if (pHddCtx->cfg_ini->fTDLSExternalControl == FALSE) {
4237
4238 return -ENOTSUPP;
4239 }
4240 if (nla_parse(tb, QCA_WLAN_VENDOR_ATTR_TDLS_ENABLE_MAX,
4241 data, data_len,
4242 wlan_hdd_tdls_config_enable_policy)) {
4243 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Invalid ATTR"));
4244 return -EINVAL;
4245 }
4246
4247 /* Parse and fetch mac address */
4248 if (!tb[QCA_WLAN_VENDOR_ATTR_TDLS_ENABLE_MAC_ADDR]) {
4249 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr mac addr failed"));
4250 return -EINVAL;
4251 }
4252
4253 memcpy(peer, nla_data(
4254 tb[QCA_WLAN_VENDOR_ATTR_TDLS_ENABLE_MAC_ADDR]),
4255 sizeof(peer));
4256 hddLog(VOS_TRACE_LEVEL_INFO, FL(MAC_ADDRESS_STR),MAC_ADDR_ARRAY(peer));
4257
4258 /* Parse and fetch channel */
4259 if (!tb[QCA_WLAN_VENDOR_ATTR_TDLS_ENABLE_CHANNEL]) {
4260 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr channel failed"));
4261 return -EINVAL;
4262 }
4263 pReqMsg.channel = nla_get_s32(
4264 tb[QCA_WLAN_VENDOR_ATTR_TDLS_ENABLE_CHANNEL]);
4265 hddLog(VOS_TRACE_LEVEL_INFO, FL("Channel Num (%d)"), pReqMsg.channel);
4266
4267 /* Parse and fetch global operating class */
4268 if (!tb[QCA_WLAN_VENDOR_ATTR_TDLS_ENABLE_GLOBAL_OPERATING_CLASS]) {
4269 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr operating class failed"));
4270 return -EINVAL;
4271 }
4272 pReqMsg.global_operating_class = nla_get_s32(
4273 tb[QCA_WLAN_VENDOR_ATTR_TDLS_ENABLE_GLOBAL_OPERATING_CLASS]);
4274 hddLog(VOS_TRACE_LEVEL_INFO, FL("Operating class (%d)"),
4275 pReqMsg.global_operating_class);
4276
4277 /* Parse and fetch latency ms */
4278 if (!tb[QCA_WLAN_VENDOR_ATTR_TDLS_ENABLE_MAX_LATENCY_MS]) {
4279 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr latency failed"));
4280 return -EINVAL;
4281 }
4282 pReqMsg.max_latency_ms = nla_get_s32(
4283 tb[QCA_WLAN_VENDOR_ATTR_TDLS_ENABLE_MAX_LATENCY_MS]);
4284 hddLog(VOS_TRACE_LEVEL_INFO, FL("Latency (%d)"),
4285 pReqMsg.max_latency_ms);
4286
4287 /* Parse and fetch required bandwidth kbps */
4288 if (!tb[QCA_WLAN_VENDOR_ATTR_TDLS_ENABLE_MIN_BANDWIDTH_KBPS]) {
4289 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr bandwidth failed"));
4290 return -EINVAL;
4291 }
4292
4293 pReqMsg.min_bandwidth_kbps = nla_get_s32(
4294 tb[QCA_WLAN_VENDOR_ATTR_TDLS_ENABLE_MIN_BANDWIDTH_KBPS]);
4295 hddLog(VOS_TRACE_LEVEL_INFO, FL("Bandwidth (%d)"),
4296 pReqMsg.min_bandwidth_kbps);
4297
4298 return (wlan_hdd_tdls_extctrl_config_peer(pAdapter,
4299 peer,
4300 wlan_hdd_cfg80211_exttdls_callback));
4301}
4302
4303static int wlan_hdd_cfg80211_exttdls_disable(struct wiphy *wiphy,
4304 struct wireless_dev *wdev,
4305 void *data,
4306 int data_len)
4307{
4308 u8 peer[6] = {0};
4309 struct net_device *dev = wdev->netdev;
4310 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
4311 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
4312 struct nlattr *tb[QCA_WLAN_VENDOR_ATTR_TDLS_DISABLE_MAX + 1];
4313 eHalStatus status;
4314
4315 status = wlan_hdd_validate_context(pHddCtx);
4316 if (0 != status) {
4317 hddLog(VOS_TRACE_LEVEL_ERROR,
4318 FL("HDD context is not valid"));
4319 return -EINVAL;
4320 }
4321 if (pHddCtx->cfg_ini->fTDLSExternalControl == FALSE) {
4322
4323 return -ENOTSUPP;
4324 }
4325 if (nla_parse(tb, QCA_WLAN_VENDOR_ATTR_TDLS_DISABLE_MAX,
4326 data, data_len,
4327 wlan_hdd_tdls_config_disable_policy)) {
4328 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Invalid ATTR"));
4329 return -EINVAL;
4330 }
4331 /* Parse and fetch mac address */
4332 if (!tb[QCA_WLAN_VENDOR_ATTR_TDLS_DISABLE_MAC_ADDR]) {
4333 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr mac addr failed"));
4334 return -EINVAL;
4335 }
4336
4337 memcpy(peer, nla_data(
4338 tb[QCA_WLAN_VENDOR_ATTR_TDLS_DISABLE_MAC_ADDR]),
4339 sizeof(peer));
4340 hddLog(VOS_TRACE_LEVEL_INFO, FL(MAC_ADDRESS_STR),MAC_ADDR_ARRAY(peer));
4341
4342 return (wlan_hdd_tdls_extctrl_deconfig_peer(pAdapter, peer));
4343}
4344
Dasari Srinivas7875a302014-09-26 17:50:57 +05304345static int
4346wlan_hdd_cfg80211_get_supported_features(struct wiphy *wiphy,
4347 struct wireless_dev *wdev,
4348 void *data, int data_len)
4349{
4350 struct net_device *dev = wdev->netdev;
4351 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
4352 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
4353 struct sk_buff *skb = NULL;
4354 tANI_U32 fset = 0;
4355
4356 if (wiphy->interface_modes & BIT(NL80211_IFTYPE_STATION)) {
4357 hddLog(LOG1, FL("Infra Station mode is supported by driver"));
4358 fset |= WIFI_FEATURE_INFRA;
4359 }
4360
4361 if (TRUE == hdd_is_5g_supported(pHddCtx)) {
4362 hddLog(LOG1, FL("INFRA_5G is supported by firmware"));
4363 fset |= WIFI_FEATURE_INFRA_5G;
4364 }
4365
4366#ifdef WLAN_FEATURE_P2P
4367 if ((wiphy->interface_modes & BIT(NL80211_IFTYPE_P2P_CLIENT)) &&
4368 (wiphy->interface_modes & BIT(NL80211_IFTYPE_P2P_GO))) {
4369 hddLog(LOG1, FL("WiFi-Direct is supported by driver"));
4370 fset |= WIFI_FEATURE_P2P;
4371 }
4372#endif
4373
4374 /* Soft-AP is supported currently by default */
4375 fset |= WIFI_FEATURE_SOFT_AP;
4376
4377#ifdef WLAN_FEATURE_EXTSCAN
4378 if ((TRUE == pHddCtx->cfg_ini->fEnableEXTScan) &&
4379 sme_IsFeatureSupportedByFW(EXTENDED_SCAN)) {
4380 hddLog(LOG1, FL("EXTScan is supported by firmware"));
4381 fset |= WIFI_FEATURE_EXTSCAN;
4382 }
4383#endif
4384
4385#ifdef WLAN_FEATURE_NAN
4386 if (sme_IsFeatureSupportedByFW(NAN)) {
4387 hddLog(LOG1, FL("NAN is supported by firmware"));
4388 fset |= WIFI_FEATURE_NAN;
4389 }
4390#endif
4391
4392 /* D2D RTT is not supported currently by default */
4393 if (sme_IsFeatureSupportedByFW(RTT)) {
4394 hddLog(LOG1, FL("RTT is supported by firmware"));
4395 fset |= WIFI_FEATURE_D2AP_RTT;
4396 }
4397
4398#ifdef FEATURE_WLAN_BATCH_SCAN
4399 if (fset & WIFI_FEATURE_EXTSCAN) {
4400 hddLog(LOG1, FL("Batch scan is supported as extscan is supported"));
4401 fset &= ~WIFI_FEATURE_BATCH_SCAN;
4402 } else if (sme_IsFeatureSupportedByFW(BATCH_SCAN)) {
4403 hddLog(LOG1, FL("Batch scan is supported by firmware"));
4404 fset |= WIFI_FEATURE_BATCH_SCAN;
4405 }
4406#endif
4407
4408#ifdef FEATURE_WLAN_SCAN_PNO
4409 if (pHddCtx->cfg_ini->configPNOScanSupport &&
4410 (eHAL_STATUS_SUCCESS == wlan_hdd_is_pno_allowed(pAdapter))) {
4411 hddLog(LOG1, FL("PNO is supported by firmware"));
4412 fset |= WIFI_FEATURE_PNO;
4413 }
4414#endif
4415
4416 /* STA+STA is supported currently by default */
4417 fset |= WIFI_FEATURE_ADDITIONAL_STA;
4418
4419#ifdef FEATURE_WLAN_TDLS
4420 if ((TRUE == pHddCtx->cfg_ini->fEnableTDLSSupport) &&
4421 sme_IsFeatureSupportedByFW(TDLS)) {
4422 hddLog(LOG1, FL("TDLS is supported by firmware"));
4423 fset |= WIFI_FEATURE_TDLS;
4424 }
4425
4426 /* TDLS_OFFCHANNEL is not supported currently by default */
4427#endif
4428
4429#ifdef WLAN_AP_STA_CONCURRENCY
4430 /* AP+STA concurrency is supported currently by default */
4431 fset |= WIFI_FEATURE_AP_STA;
4432#endif
4433
4434 skb = cfg80211_vendor_cmd_alloc_reply_skb(wiphy, sizeof(fset) +
4435 NLMSG_HDRLEN);
4436
4437 if (!skb) {
4438 hddLog(LOGE, FL("cfg80211_vendor_cmd_alloc_reply_skb failed"));
4439 return -EINVAL;
4440 }
4441 hddLog(LOG1, FL("Supported Features : 0x%x"), fset);
4442
4443 if (nla_put_u32(skb, QCA_WLAN_VENDOR_ATTR_FEATURE_SET, fset)) {
4444 hddLog(LOGE, FL("nla put fail"));
4445 goto nla_put_failure;
4446 }
4447
4448 return cfg80211_vendor_cmd_reply(skb);
4449
4450nla_put_failure:
4451 kfree_skb(skb);
4452 return -EINVAL;
4453}
4454
Agarwal Ashish738843c2014-09-25 12:27:56 +05304455static const struct nla_policy
4456wlan_hdd_set_no_dfs_flag_config_policy[QCA_WLAN_VENDOR_ATTR_SET_NO_DFS_FLAG_MAX
4457 +1] =
4458{
4459 [QCA_WLAN_VENDOR_ATTR_SET_NO_DFS_FLAG] = {.type = NLA_U32 },
4460};
4461
4462static int wlan_hdd_cfg80211_disable_dfs_channels(struct wiphy *wiphy,
4463 struct wireless_dev *wdev,
4464 void *data,
4465 int data_len)
4466{
4467 struct net_device *dev = wdev->netdev;
4468 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
4469 tHalHandle hHal = WLAN_HDD_GET_HAL_CTX(pAdapter);
4470 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
4471 struct nlattr *tb[QCA_WLAN_VENDOR_ATTR_SET_NO_DFS_FLAG_MAX + 1];
4472 eHalStatus status;
4473 u32 dfsFlag = 0;
4474
4475 status = wlan_hdd_validate_context(pHddCtx);
4476 if (0 != status) {
4477 hddLog(VOS_TRACE_LEVEL_ERROR,
4478 FL("HDD context is not valid"));
4479 return -EINVAL;
4480 }
4481 if (nla_parse(tb, QCA_WLAN_VENDOR_ATTR_SET_NO_DFS_FLAG_MAX,
4482 data, data_len,
4483 wlan_hdd_set_no_dfs_flag_config_policy)) {
4484 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Invalid ATTR"));
4485 return -EINVAL;
4486 }
4487
4488 /* Parse and fetch required bandwidth kbps */
4489 if (!tb[QCA_WLAN_VENDOR_ATTR_SET_NO_DFS_FLAG]) {
4490 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr dfs flag failed"));
4491 return -EINVAL;
4492 }
4493
4494 dfsFlag = nla_get_u32(
4495 tb[QCA_WLAN_VENDOR_ATTR_SET_NO_DFS_FLAG]);
4496 hddLog(VOS_TRACE_LEVEL_INFO, FL(" DFS flag (%d)"),
4497 dfsFlag);
4498
4499 pHddCtx->disable_dfs_flag = dfsFlag;
4500
4501 sme_disable_dfs_channel(hHal, dfsFlag);
4502 sme_FilterScanResults(hHal, pAdapter->sessionId);
4503 return 0;
4504}
Atul Mittal115287b2014-07-08 13:26:33 +05304505
Mukul Sharma2a271632014-10-13 14:59:01 +05304506const struct
4507nla_policy qca_wlan_vendor_attr[QCA_WLAN_VENDOR_ATTR_MAX+1] =
4508{
4509 [QCA_WLAN_VENDOR_ATTR_ROAMING_POLICY] = { .type = NLA_U32 },
4510 [QCA_WLAN_VENDOR_ATTR_MAC_ADDR] = { .type = NLA_UNSPEC },
4511};
4512
4513static int wlan_hdd_cfg80211_firmware_roaming(struct wiphy *wiphy,
4514 struct wireless_dev *wdev, void *data, int data_len)
4515{
4516
4517 u8 bssid[6] = {0};
4518 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
4519 struct nlattr *tb[QCA_WLAN_VENDOR_ATTR_MAX + 1];
4520 eHalStatus status = eHAL_STATUS_SUCCESS;
4521 v_U32_t isFwrRoamEnabled = FALSE;
4522 int ret;
4523
4524 if (NULL == pHddCtx) {
4525 hddLog(VOS_TRACE_LEVEL_ERROR,
4526 FL("HDD context is not valid"));
4527 return -EINVAL;
4528 }
4529
4530 ret = nla_parse(tb, QCA_WLAN_VENDOR_ATTR_MAX,
4531 data, data_len,
4532 qca_wlan_vendor_attr);
4533 if (ret){
4534 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Invalid ATTR"));
4535 return -EINVAL;
4536 }
4537
4538 /* Parse and fetch Enable flag */
4539 if (!tb[QCA_WLAN_VENDOR_ATTR_ROAMING_POLICY]) {
4540 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr enable failed"));
4541 return -EINVAL;
4542 }
4543
4544 isFwrRoamEnabled = nla_get_u32(
4545 tb[QCA_WLAN_VENDOR_ATTR_ROAMING_POLICY]);
4546
4547 hddLog(VOS_TRACE_LEVEL_INFO, FL("isFwrRoamEnabled (%d)"), isFwrRoamEnabled);
4548
4549 /* Parse and fetch bssid */
4550 if (!tb[QCA_WLAN_VENDOR_ATTR_MAC_ADDR]) {
4551 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr bss id failed"));
4552 return -EINVAL;
4553 }
4554
4555 memcpy(bssid, nla_data(
4556 tb[QCA_WLAN_VENDOR_ATTR_MAC_ADDR]),
4557 sizeof(bssid));
4558 hddLog(VOS_TRACE_LEVEL_INFO, FL(MAC_ADDRESS_STR),MAC_ADDR_ARRAY(bssid));
4559
4560 //Update roaming
4561 status = sme_ConfigFwrRoaming((tHalHandle)(pHddCtx->hHal), isFwrRoamEnabled);
4562 return status;
4563}
4564
Sunil Duttc69bccb2014-05-26 21:30:20 +05304565const struct wiphy_vendor_command hdd_wiphy_vendor_commands[] =
4566{
Mukul Sharma2a271632014-10-13 14:59:01 +05304567 {
4568 .info.vendor_id = QCA_NL80211_VENDOR_ID,
4569 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_ROAMING,
4570 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
4571 WIPHY_VENDOR_CMD_NEED_NETDEV |
4572 WIPHY_VENDOR_CMD_NEED_RUNNING,
4573 .doit = wlan_hdd_cfg80211_firmware_roaming
4574 },
Sunil Duttc69bccb2014-05-26 21:30:20 +05304575#ifdef WLAN_FEATURE_LINK_LAYER_STATS
4576 {
4577 .info.vendor_id = QCA_NL80211_VENDOR_ID,
4578 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_LL_STATS_CLR,
4579 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
4580 WIPHY_VENDOR_CMD_NEED_NETDEV |
4581 WIPHY_VENDOR_CMD_NEED_RUNNING,
4582 .doit = wlan_hdd_cfg80211_ll_stats_clear
4583 },
4584
4585 {
4586 .info.vendor_id = QCA_NL80211_VENDOR_ID,
4587 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_LL_STATS_SET,
4588 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
4589 WIPHY_VENDOR_CMD_NEED_NETDEV |
4590 WIPHY_VENDOR_CMD_NEED_RUNNING,
4591 .doit = wlan_hdd_cfg80211_ll_stats_set
4592 },
4593
4594 {
4595 .info.vendor_id = QCA_NL80211_VENDOR_ID,
4596 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_LL_STATS_GET,
4597 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
4598 WIPHY_VENDOR_CMD_NEED_NETDEV |
4599 WIPHY_VENDOR_CMD_NEED_RUNNING,
4600 .doit = wlan_hdd_cfg80211_ll_stats_get
Dino Mycle6fb96c12014-06-10 11:52:40 +05304601 },
Sunil Duttc69bccb2014-05-26 21:30:20 +05304602#endif /* WLAN_FEATURE_LINK_LAYER_STATS */
Dino Mycle6fb96c12014-06-10 11:52:40 +05304603#ifdef WLAN_FEATURE_EXTSCAN
4604 {
4605 .info.vendor_id = QCA_NL80211_VENDOR_ID,
4606 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_START,
4607 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
4608 WIPHY_VENDOR_CMD_NEED_NETDEV |
4609 WIPHY_VENDOR_CMD_NEED_RUNNING,
4610 .doit = wlan_hdd_cfg80211_extscan_start
4611 },
4612 {
4613 .info.vendor_id = QCA_NL80211_VENDOR_ID,
4614 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_STOP,
4615 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
4616 WIPHY_VENDOR_CMD_NEED_NETDEV |
4617 WIPHY_VENDOR_CMD_NEED_RUNNING,
4618 .doit = wlan_hdd_cfg80211_extscan_stop
4619 },
4620 {
4621 .info.vendor_id = QCA_NL80211_VENDOR_ID,
4622 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_GET_VALID_CHANNELS,
4623 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
4624 WIPHY_VENDOR_CMD_NEED_NETDEV,
4625 .doit = wlan_hdd_cfg80211_extscan_get_valid_channels
4626 },
4627 {
4628 .info.vendor_id = QCA_NL80211_VENDOR_ID,
4629 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_GET_CAPABILITIES,
4630 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
4631 WIPHY_VENDOR_CMD_NEED_NETDEV |
4632 WIPHY_VENDOR_CMD_NEED_RUNNING,
4633 .doit = wlan_hdd_cfg80211_extscan_get_capabilities
4634 },
4635 {
4636 .info.vendor_id = QCA_NL80211_VENDOR_ID,
4637 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_GET_CACHED_RESULTS,
4638 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
4639 WIPHY_VENDOR_CMD_NEED_NETDEV |
4640 WIPHY_VENDOR_CMD_NEED_RUNNING,
4641 .doit = wlan_hdd_cfg80211_extscan_get_cached_results
4642 },
4643 {
4644 .info.vendor_id = QCA_NL80211_VENDOR_ID,
4645 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_SET_BSSID_HOTLIST,
4646 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
4647 WIPHY_VENDOR_CMD_NEED_NETDEV |
4648 WIPHY_VENDOR_CMD_NEED_RUNNING,
4649 .doit = wlan_hdd_cfg80211_extscan_set_bssid_hotlist
4650 },
4651 {
4652 .info.vendor_id = QCA_NL80211_VENDOR_ID,
4653 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_RESET_BSSID_HOTLIST,
4654 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
4655 WIPHY_VENDOR_CMD_NEED_NETDEV |
4656 WIPHY_VENDOR_CMD_NEED_RUNNING,
4657 .doit = wlan_hdd_cfg80211_extscan_reset_bssid_hotlist
4658 },
4659 {
4660 .info.vendor_id = QCA_NL80211_VENDOR_ID,
4661 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_SET_SIGNIFICANT_CHANGE,
4662 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
4663 WIPHY_VENDOR_CMD_NEED_NETDEV |
4664 WIPHY_VENDOR_CMD_NEED_RUNNING,
4665 .doit = wlan_hdd_cfg80211_extscan_set_significant_change
4666 },
4667 {
4668 .info.vendor_id = QCA_NL80211_VENDOR_ID,
4669 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_RESET_SIGNIFICANT_CHANGE,
4670 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
4671 WIPHY_VENDOR_CMD_NEED_NETDEV |
4672 WIPHY_VENDOR_CMD_NEED_RUNNING,
4673 .doit = wlan_hdd_cfg80211_extscan_reset_significant_change
4674 },
4675#endif /* WLAN_FEATURE_EXTSCAN */
Atul Mittal115287b2014-07-08 13:26:33 +05304676/*EXT TDLS*/
4677 {
4678 .info.vendor_id = QCA_NL80211_VENDOR_ID,
4679 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_TDLS_ENABLE,
4680 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
4681 WIPHY_VENDOR_CMD_NEED_NETDEV |
4682 WIPHY_VENDOR_CMD_NEED_RUNNING,
4683 .doit = wlan_hdd_cfg80211_exttdls_enable
4684 },
4685 {
4686 .info.vendor_id = QCA_NL80211_VENDOR_ID,
4687 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_TDLS_DISABLE,
4688 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
4689 WIPHY_VENDOR_CMD_NEED_NETDEV |
4690 WIPHY_VENDOR_CMD_NEED_RUNNING,
4691 .doit = wlan_hdd_cfg80211_exttdls_disable
4692 },
4693 {
4694 .info.vendor_id = QCA_NL80211_VENDOR_ID,
4695 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_TDLS_GET_STATUS,
4696 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
4697 WIPHY_VENDOR_CMD_NEED_NETDEV,
4698 .doit = wlan_hdd_cfg80211_exttdls_get_status
4699 },
Dasari Srinivas7875a302014-09-26 17:50:57 +05304700 {
4701 .info.vendor_id = QCA_NL80211_VENDOR_ID,
4702 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_GET_SUPPORTED_FEATURES,
4703 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
4704 WIPHY_VENDOR_CMD_NEED_NETDEV,
4705 .doit = wlan_hdd_cfg80211_get_supported_features
4706 },
Agarwal Ashish738843c2014-09-25 12:27:56 +05304707 {
4708 .info.vendor_id = QCA_NL80211_VENDOR_ID,
4709 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_NO_DFS_FLAG,
4710 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
4711 WIPHY_VENDOR_CMD_NEED_NETDEV,
4712 .doit = wlan_hdd_cfg80211_disable_dfs_channels
4713 },
Siddharth Bhala3a5cb42014-09-29 21:13:13 +05304714 {
4715 .info.vendor_id = QCA_NL80211_VENDOR_ID,
4716 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_MAC_OUI,
4717 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
4718 WIPHY_VENDOR_CMD_NEED_NETDEV,
4719 .doit = wlan_hdd_cfg80211_set_spoofed_mac_oui
4720 },
Sunil Duttc69bccb2014-05-26 21:30:20 +05304721};
4722
Rajesh Chauhan98a31f82014-01-06 20:15:25 -08004723/* vendor specific events */
Sunil Duttc69bccb2014-05-26 21:30:20 +05304724static const
4725struct nl80211_vendor_cmd_info wlan_hdd_cfg80211_vendor_events[] =
Rajesh Chauhan98a31f82014-01-06 20:15:25 -08004726{
4727#ifdef FEATURE_WLAN_CH_AVOID
4728 {
Sunil Duttc69bccb2014-05-26 21:30:20 +05304729 .vendor_id = QCA_NL80211_VENDOR_ID,
4730 .subcmd = QCA_NL80211_VENDOR_SUBCMD_AVOID_FREQUENCY
Rajesh Chauhan98a31f82014-01-06 20:15:25 -08004731 },
Sunil Duttc69bccb2014-05-26 21:30:20 +05304732#endif /* FEATURE_WLAN_CH_AVOID Index = 0*/
4733#ifdef WLAN_FEATURE_LINK_LAYER_STATS
4734 {
4735 /* Index = 1*/
4736 .vendor_id = QCA_NL80211_VENDOR_ID,
4737 .subcmd = QCA_NL80211_VENDOR_SUBCMD_LL_STATS_SET
4738 },
4739 {
4740 /* Index = 2*/
4741 .vendor_id = QCA_NL80211_VENDOR_ID,
4742 .subcmd = QCA_NL80211_VENDOR_SUBCMD_LL_STATS_GET
4743 },
4744 {
4745 /* Index = 3*/
4746 .vendor_id = QCA_NL80211_VENDOR_ID,
4747 .subcmd = QCA_NL80211_VENDOR_SUBCMD_LL_STATS_CLR
4748 },
4749 {
4750 /* Index = 4*/
4751 .vendor_id = QCA_NL80211_VENDOR_ID,
4752 .subcmd = QCA_NL80211_VENDOR_SUBCMD_LL_STATS_RADIO_RESULTS
4753 },
4754 {
4755 /* Index = 5*/
4756 .vendor_id = QCA_NL80211_VENDOR_ID,
4757 .subcmd = QCA_NL80211_VENDOR_SUBCMD_LL_STATS_IFACE_RESULTS
4758 },
4759 {
4760 /* Index = 6*/
4761 .vendor_id = QCA_NL80211_VENDOR_ID,
4762 .subcmd = QCA_NL80211_VENDOR_SUBCMD_LL_STATS_PEERS_RESULTS
4763 },
4764#endif /* WLAN_FEATURE_LINK_LAYER_STATS */
Dino Mycle6fb96c12014-06-10 11:52:40 +05304765#ifdef WLAN_FEATURE_EXTSCAN
4766 {
4767 .vendor_id = QCA_NL80211_VENDOR_ID,
4768 .subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_START
4769 },
4770 {
4771 .vendor_id = QCA_NL80211_VENDOR_ID,
4772 .subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_STOP
4773 },
4774 {
4775 .vendor_id = QCA_NL80211_VENDOR_ID,
4776 .subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_GET_CAPABILITIES
4777 },
4778 {
4779 .vendor_id = QCA_NL80211_VENDOR_ID,
4780 .subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_GET_CACHED_RESULTS
4781 },
4782 {
4783 .vendor_id = QCA_NL80211_VENDOR_ID,
4784 .subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_SCAN_RESULTS_AVAILABLE
4785 },
4786 {
4787 .vendor_id = QCA_NL80211_VENDOR_ID,
4788 .subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_FULL_SCAN_RESULT
4789 },
4790 {
4791 .vendor_id = QCA_NL80211_VENDOR_ID,
4792 .subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_SCAN_EVENT
4793 },
4794 {
4795 .vendor_id = QCA_NL80211_VENDOR_ID,
4796 .subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_HOTLIST_AP_FOUND
4797 },
4798 {
4799 .vendor_id = QCA_NL80211_VENDOR_ID,
4800 .subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_SET_BSSID_HOTLIST
4801 },
4802 {
4803 .vendor_id = QCA_NL80211_VENDOR_ID,
4804 .subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_RESET_BSSID_HOTLIST
4805 },
4806 {
4807 .vendor_id = QCA_NL80211_VENDOR_ID,
4808 .subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_SIGNIFICANT_CHANGE
4809 },
4810 {
4811 .vendor_id = QCA_NL80211_VENDOR_ID,
4812 .subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_SET_SIGNIFICANT_CHANGE
4813 },
4814 {
4815 .vendor_id = QCA_NL80211_VENDOR_ID,
4816 .subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_RESET_SIGNIFICANT_CHANGE
4817 },
4818#endif /* WLAN_FEATURE_EXTSCAN */
Atul Mittal115287b2014-07-08 13:26:33 +05304819/*EXT TDLS*/
4820 {
4821 .vendor_id = QCA_NL80211_VENDOR_ID,
4822 .subcmd = QCA_NL80211_VENDOR_SUBCMD_TDLS_STATE
4823 },
Rajesh Chauhan98a31f82014-01-06 20:15:25 -08004824};
4825
Jeff Johnson295189b2012-06-20 16:38:30 -07004826/*
Madan Mohan Koyyalamudi71278262013-04-12 22:00:48 +05304827 * FUNCTION: wlan_hdd_cfg80211_wiphy_alloc
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304828 * This function is called by hdd_wlan_startup()
4829 * during initialization.
Madan Mohan Koyyalamudi71278262013-04-12 22:00:48 +05304830 * This function is used to allocate wiphy structure.
Jeff Johnson295189b2012-06-20 16:38:30 -07004831 */
Madan Mohan Koyyalamudi71278262013-04-12 22:00:48 +05304832struct wiphy *wlan_hdd_cfg80211_wiphy_alloc(int priv_size)
Jeff Johnson295189b2012-06-20 16:38:30 -07004833{
4834 struct wiphy *wiphy;
4835 ENTER();
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304836 /*
4837 * Create wiphy device
Jeff Johnson295189b2012-06-20 16:38:30 -07004838 */
4839 wiphy = wiphy_new(&wlan_hdd_cfg80211_ops, priv_size);
4840
4841 if (!wiphy)
4842 {
4843 /* Print error and jump into err label and free the memory */
4844 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: wiphy init failed", __func__);
4845 return NULL;
4846 }
4847
Sunil Duttc69bccb2014-05-26 21:30:20 +05304848
Jeff Johnson295189b2012-06-20 16:38:30 -07004849 return wiphy;
4850}
4851
4852/*
4853 * FUNCTION: wlan_hdd_cfg80211_update_band
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304854 * This function is called from the supplicant through a
Jeff Johnson295189b2012-06-20 16:38:30 -07004855 * private ioctl to change the band value
4856 */
4857int wlan_hdd_cfg80211_update_band(struct wiphy *wiphy, eCsrBand eBand)
4858{
Gopichand Nakkala1f7a64f2013-04-01 18:37:17 +05304859 int i, j;
4860 eNVChannelEnabledType channelEnabledState;
4861
Jeff Johnsone7245742012-09-05 17:12:55 -07004862 ENTER();
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05304863
Gopichand Nakkala1f7a64f2013-04-01 18:37:17 +05304864 for (i = 0; i < IEEE80211_NUM_BANDS; i++)
Jeff Johnson295189b2012-06-20 16:38:30 -07004865 {
Gopichand Nakkala1f7a64f2013-04-01 18:37:17 +05304866
4867 if (NULL == wiphy->bands[i])
4868 {
4869 hddLog(VOS_TRACE_LEVEL_ERROR,"%s: wiphy->bands[i] is NULL, i = %d",
4870 __func__, i);
4871 continue;
4872 }
4873
4874 for (j = 0; j < wiphy->bands[i]->n_channels; j++)
4875 {
4876 struct ieee80211_supported_band *band = wiphy->bands[i];
4877
4878 channelEnabledState = vos_nv_getChannelEnabledState(
4879 band->channels[j].hw_value);
4880
4881 if (IEEE80211_BAND_2GHZ == i && eCSR_BAND_5G == eBand) // 5G only
4882 {
4883 // Enable Social channels for P2P
4884 if (WLAN_HDD_IS_SOCIAL_CHANNEL(band->channels[j].center_freq) &&
4885 NV_CHANNEL_ENABLE == channelEnabledState)
4886 band->channels[j].flags &= ~IEEE80211_CHAN_DISABLED;
4887 else
4888 band->channels[j].flags |= IEEE80211_CHAN_DISABLED;
4889 continue;
4890 }
4891 else if (IEEE80211_BAND_5GHZ == i && eCSR_BAND_24 == eBand) // 2G only
4892 {
4893 band->channels[j].flags |= IEEE80211_CHAN_DISABLED;
4894 continue;
4895 }
4896
4897 if (NV_CHANNEL_DISABLE == channelEnabledState ||
4898 NV_CHANNEL_INVALID == channelEnabledState)
4899 {
4900 band->channels[j].flags |= IEEE80211_CHAN_DISABLED;
4901 }
4902 else if (NV_CHANNEL_DFS == channelEnabledState)
4903 {
4904 band->channels[j].flags &= ~IEEE80211_CHAN_DISABLED;
4905 band->channels[j].flags |= IEEE80211_CHAN_RADAR;
4906 }
4907 else
4908 {
4909 band->channels[j].flags &= ~(IEEE80211_CHAN_DISABLED
4910 |IEEE80211_CHAN_RADAR);
4911 }
4912 }
Jeff Johnson295189b2012-06-20 16:38:30 -07004913 }
4914 return 0;
4915}
4916/*
4917 * FUNCTION: wlan_hdd_cfg80211_init
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304918 * This function is called by hdd_wlan_startup()
4919 * during initialization.
Jeff Johnson295189b2012-06-20 16:38:30 -07004920 * This function is used to initialize and register wiphy structure.
4921 */
Madan Mohan Koyyalamudi71278262013-04-12 22:00:48 +05304922int wlan_hdd_cfg80211_init(struct device *dev,
Jeff Johnson295189b2012-06-20 16:38:30 -07004923 struct wiphy *wiphy,
4924 hdd_config_t *pCfg
4925 )
4926{
Gopichand Nakkala1f7a64f2013-04-01 18:37:17 +05304927 int i, j;
Vinay Krishna Erannafacf5e22014-02-24 13:16:25 +05304928 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
4929
Jeff Johnsone7245742012-09-05 17:12:55 -07004930 ENTER();
4931
Jeff Johnson295189b2012-06-20 16:38:30 -07004932 /* Now bind the underlying wlan device with wiphy */
4933 set_wiphy_dev(wiphy, dev);
4934
4935 wiphy->mgmt_stypes = wlan_hdd_txrx_stypes;
Amar Singhalfddc28c2013-09-05 13:03:40 -07004936
Kiet Lam6c583332013-10-14 05:37:09 +05304937#ifndef CONFIG_ENABLE_LINUX_REG
Amar Singhal0a402232013-10-11 20:57:16 -07004938 /* the flag for the other case would be initialzed in
4939 vos_init_wiphy_from_nv_bin */
Amar Singhal0a402232013-10-11 20:57:16 -07004940 wiphy->flags |= WIPHY_FLAG_STRICT_REGULATORY;
Kiet Lam6c583332013-10-14 05:37:09 +05304941#endif
Amar Singhala49cbc52013-10-08 18:37:44 -07004942
Amar Singhalfddc28c2013-09-05 13:03:40 -07004943 /* This will disable updating of NL channels from passive to
4944 * active if a beacon is received on passive channel. */
4945 wiphy->flags |= WIPHY_FLAG_DISABLE_BEACON_HINTS;
Amar Singhalf0073192013-09-20 12:34:56 -07004946
Amar Singhalfddc28c2013-09-05 13:03:40 -07004947
Amar Singhala49cbc52013-10-08 18:37:44 -07004948
Jeff Johnson04dd8a82012-06-29 20:41:40 -07004949#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,4,0))
Madan Mohan Koyyalamudi1b4afb02012-10-22 15:25:16 -07004950 wiphy->flags |= WIPHY_FLAG_HAVE_AP_SME
4951 | WIPHY_FLAG_AP_PROBE_RESP_OFFLOAD
4952 | WIPHY_FLAG_HAS_REMAIN_ON_CHANNEL
Jeff Johnsone7245742012-09-05 17:12:55 -07004953 | WIPHY_FLAG_OFFCHAN_TX;
Kiet Lam6c583332013-10-14 05:37:09 +05304954 wiphy->country_ie_pref = NL80211_COUNTRY_IE_IGNORE_CORE;
Jeff Johnson04dd8a82012-06-29 20:41:40 -07004955#endif
Amar Singhala49cbc52013-10-08 18:37:44 -07004956
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08004957#if defined (WLAN_FEATURE_VOWIFI_11R) || defined (FEATURE_WLAN_ESE) || defined(FEATURE_WLAN_LFR)
Srinivas Girigowda640728a2013-03-28 12:21:54 -07004958 if (pCfg->isFastTransitionEnabled
James Zmuda77fb5ae2013-01-29 08:00:17 -08004959#ifdef FEATURE_WLAN_LFR
Srinivas Girigowda640728a2013-03-28 12:21:54 -07004960 || pCfg->isFastRoamIniFeatureEnabled
4961#endif
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08004962#ifdef FEATURE_WLAN_ESE
4963 || pCfg->isEseIniFeatureEnabled
Srinivas Girigowda640728a2013-03-28 12:21:54 -07004964#endif
4965 )
4966 {
4967 wiphy->flags |= WIPHY_FLAG_SUPPORTS_FW_ROAM;
4968 }
James Zmuda77fb5ae2013-01-29 08:00:17 -08004969#endif
Mohit Khanna698ba2a2012-12-04 15:08:18 -08004970#ifdef FEATURE_WLAN_TDLS
4971 wiphy->flags |= WIPHY_FLAG_SUPPORTS_TDLS
4972 | WIPHY_FLAG_TDLS_EXTERNAL_SETUP;
4973#endif
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +05304974#ifdef FEATURE_WLAN_SCAN_PNO
Hardik Kantilal Patel3dfd8792013-11-13 20:34:57 +05304975 if (pCfg->configPNOScanSupport)
4976 {
4977 wiphy->flags |= WIPHY_FLAG_SUPPORTS_SCHED_SCAN;
4978 wiphy->max_sched_scan_ssids = SIR_PNO_MAX_SUPP_NETWORKS;
4979 wiphy->max_match_sets = SIR_PNO_MAX_SUPP_NETWORKS;
4980 wiphy->max_sched_scan_ie_len = SIR_MAC_MAX_IE_LENGTH;
4981 }
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +05304982#endif/*FEATURE_WLAN_SCAN_PNO*/
Mohit Khanna698ba2a2012-12-04 15:08:18 -08004983
Amar Singhalfddc28c2013-09-05 13:03:40 -07004984#ifdef CONFIG_ENABLE_LINUX_REG
Madan Mohan Koyyalamudic3a240c2012-09-28 15:34:08 -07004985 /* even with WIPHY_FLAG_CUSTOM_REGULATORY,
4986 driver can still register regulatory callback and
Amar Singhalfddc28c2013-09-05 13:03:40 -07004987 it will get regulatory settings in wiphy->band[], but
Madan Mohan Koyyalamudic3a240c2012-09-28 15:34:08 -07004988 driver need to determine what to do with both
4989 regulatory settings */
Amar Singhalfddc28c2013-09-05 13:03:40 -07004990
4991 wiphy->reg_notifier = wlan_hdd_linux_reg_notifier;
Amar Singhala49cbc52013-10-08 18:37:44 -07004992#else
4993 wiphy->reg_notifier = wlan_hdd_crda_reg_notifier;
Amar Singhalfddc28c2013-09-05 13:03:40 -07004994#endif
Jeff Johnson04dd8a82012-06-29 20:41:40 -07004995
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304996 wiphy->max_scan_ssids = MAX_SCAN_SSID;
4997
Madan Mohan Koyyalamudi6815b162013-07-19 17:17:46 +05304998 wiphy->max_scan_ie_len = SIR_MAC_MAX_IE_LENGTH;
Jeff Johnson295189b2012-06-20 16:38:30 -07004999
Gopichand Nakkalac005b7c2013-05-14 16:04:14 +05305000 wiphy->max_acl_mac_addrs = MAX_ACL_MAC_ADDRESS;
5001
Jeff Johnson295189b2012-06-20 16:38:30 -07005002 /* Supports STATION & AD-HOC modes right now */
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305003 wiphy->interface_modes = BIT(NL80211_IFTYPE_STATION)
Jeff Johnson295189b2012-06-20 16:38:30 -07005004 | BIT(NL80211_IFTYPE_ADHOC)
Jeff Johnson295189b2012-06-20 16:38:30 -07005005 | BIT(NL80211_IFTYPE_P2P_CLIENT)
5006 | BIT(NL80211_IFTYPE_P2P_GO)
Jeff Johnson295189b2012-06-20 16:38:30 -07005007 | BIT(NL80211_IFTYPE_AP);
5008
Rashmi Ramannabd3feb72014-02-25 16:14:48 +05305009 if( pCfg->advertiseConcurrentOperation )
Sudhir Sattayappa Kohalli278eee52013-01-16 17:35:13 -08005010 {
Rashmi Ramannabd3feb72014-02-25 16:14:48 +05305011#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,4,0))
5012 if( pCfg->enableMCC )
5013 {
5014 /* Currently, supports up to two channels */
5015 wlan_hdd_iface_combination.num_different_channels = 2;
Sudhir Sattayappa Kohalli278eee52013-01-16 17:35:13 -08005016
Rashmi Ramannabd3feb72014-02-25 16:14:48 +05305017 if( !pCfg->allowMCCGODiffBI )
5018 wlan_hdd_iface_combination.beacon_int_infra_match = true;
Sudhir Sattayappa Kohalli278eee52013-01-16 17:35:13 -08005019
Rashmi Ramannabd3feb72014-02-25 16:14:48 +05305020 }
5021 wiphy->iface_combinations = &wlan_hdd_iface_combination;
5022 wiphy->n_iface_combinations = 1;
Sudhir Sattayappa Kohalli278eee52013-01-16 17:35:13 -08005023#endif
Rashmi Ramannabd3feb72014-02-25 16:14:48 +05305024 }
Sudhir Sattayappa Kohalli278eee52013-01-16 17:35:13 -08005025
Jeff Johnson295189b2012-06-20 16:38:30 -07005026 /* Before registering we need to update the ht capabilitied based
5027 * on ini values*/
5028 if( !pCfg->ShortGI20MhzEnable )
5029 {
5030 wlan_hdd_band_2_4_GHZ.ht_cap.cap &= ~IEEE80211_HT_CAP_SGI_20;
5031 wlan_hdd_band_5_GHZ.ht_cap.cap &= ~IEEE80211_HT_CAP_SGI_20;
5032 wlan_hdd_band_p2p_2_4_GHZ.ht_cap.cap &= ~IEEE80211_HT_CAP_SGI_20;
5033 }
5034
5035 if( !pCfg->ShortGI40MhzEnable )
5036 {
5037 wlan_hdd_band_5_GHZ.ht_cap.cap &= ~IEEE80211_HT_CAP_SGI_40;
5038 }
5039
5040 if( !pCfg->nChannelBondingMode5GHz )
5041 {
5042 wlan_hdd_band_5_GHZ.ht_cap.cap &= ~IEEE80211_HT_CAP_SUP_WIDTH_20_40;
5043 }
5044
Gopichand Nakkala1f7a64f2013-04-01 18:37:17 +05305045 wiphy->bands[IEEE80211_BAND_2GHZ] = &wlan_hdd_band_2_4_GHZ;
Vinay Krishna Erannafacf5e22014-02-24 13:16:25 +05305046 if (true == hdd_is_5g_supported(pHddCtx))
5047 {
5048 wiphy->bands[IEEE80211_BAND_5GHZ] = &wlan_hdd_band_5_GHZ;
5049 }
Gopichand Nakkala1f7a64f2013-04-01 18:37:17 +05305050
5051 for (i = 0; i < IEEE80211_NUM_BANDS; i++)
5052 {
5053
5054 if (NULL == wiphy->bands[i])
5055 {
5056 hddLog(VOS_TRACE_LEVEL_ERROR,"%s: wiphy->bands[i] is NULL, i = %d",
5057 __func__, i);
5058 continue;
5059 }
5060
5061 for (j = 0; j < wiphy->bands[i]->n_channels; j++)
5062 {
5063 struct ieee80211_supported_band *band = wiphy->bands[i];
5064
5065 if (IEEE80211_BAND_2GHZ == i && eCSR_BAND_5G == pCfg->nBandCapability) // 5G only
5066 {
5067 // Enable social channels for P2P
5068 if (WLAN_HDD_IS_SOCIAL_CHANNEL(band->channels[j].center_freq))
5069 band->channels[j].flags &= ~IEEE80211_CHAN_DISABLED;
5070 else
5071 band->channels[j].flags |= IEEE80211_CHAN_DISABLED;
5072 continue;
5073 }
5074 else if (IEEE80211_BAND_5GHZ == i && eCSR_BAND_24 == pCfg->nBandCapability) // 2G only
5075 {
5076 band->channels[j].flags |= IEEE80211_CHAN_DISABLED;
5077 continue;
5078 }
5079 }
Jeff Johnson295189b2012-06-20 16:38:30 -07005080 }
5081 /*Initialise the supported cipher suite details*/
5082 wiphy->cipher_suites = hdd_cipher_suites;
5083 wiphy->n_cipher_suites = ARRAY_SIZE(hdd_cipher_suites);
5084
5085 /*signal strength in mBm (100*dBm) */
5086 wiphy->signal_type = CFG80211_SIGNAL_TYPE_MBM;
5087
5088#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
Sushant Kaushik4f640e42014-07-08 12:27:09 +05305089 wiphy->max_remain_on_channel_duration = 5000;
Jeff Johnson295189b2012-06-20 16:38:30 -07005090#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07005091
Sunil Duttc69bccb2014-05-26 21:30:20 +05305092 wiphy->n_vendor_commands = ARRAY_SIZE(hdd_wiphy_vendor_commands);
5093 wiphy->vendor_commands = hdd_wiphy_vendor_commands;
Rajesh Chauhan98a31f82014-01-06 20:15:25 -08005094 wiphy->vendor_events = wlan_hdd_cfg80211_vendor_events;
5095 wiphy->n_vendor_events = ARRAY_SIZE(wlan_hdd_cfg80211_vendor_events);
5096
Madan Mohan Koyyalamudi71278262013-04-12 22:00:48 +05305097 EXIT();
5098 return 0;
5099}
5100
5101/* In this function we are registering wiphy. */
5102int wlan_hdd_cfg80211_register(struct wiphy *wiphy)
5103{
5104 ENTER();
5105 /* Register our wiphy dev with cfg80211 */
Jeff Johnson295189b2012-06-20 16:38:30 -07005106 if (0 > wiphy_register(wiphy))
5107 {
Madan Mohan Koyyalamudi71278262013-04-12 22:00:48 +05305108 /* print error */
Jeff Johnson295189b2012-06-20 16:38:30 -07005109 hddLog(VOS_TRACE_LEVEL_ERROR,"%s: wiphy register failed", __func__);
5110 return -EIO;
5111 }
5112
5113 EXIT();
5114 return 0;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305115}
Jeff Johnson295189b2012-06-20 16:38:30 -07005116
Madan Mohan Koyyalamudi71278262013-04-12 22:00:48 +05305117/* In this function we are updating channel list when,
5118 regulatory domain is FCC and country code is US.
5119 Here In FCC standard 5GHz UNII-1 Bands are indoor only.
5120 As per FCC smart phone is not a indoor device.
5121 GO should not opeate on indoor channels */
5122void wlan_hdd_cfg80211_update_reg_info(struct wiphy *wiphy)
5123{
5124 int j;
5125 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
5126 tANI_U8 defaultCountryCode[3] = SME_INVALID_COUNTRY_CODE;
5127 //Default counrtycode from NV at the time of wiphy initialization.
5128 if (eHAL_STATUS_SUCCESS != sme_GetDefaultCountryCodeFrmNv(pHddCtx->hHal,
5129 &defaultCountryCode[0]))
5130 {
Jeff Johnson0299d0a2013-10-30 12:37:43 -07005131 hddLog(LOGE, FL("Failed to get default country code from NV"));
Madan Mohan Koyyalamudi71278262013-04-12 22:00:48 +05305132 }
5133 if ((defaultCountryCode[0]== 'U') && (defaultCountryCode[1]=='S'))
5134 {
Madan Mohan Koyyalamudi71278262013-04-12 22:00:48 +05305135 if (NULL == wiphy->bands[IEEE80211_BAND_5GHZ])
5136 {
5137 hddLog(VOS_TRACE_LEVEL_ERROR,"%s: wiphy->bands[IEEE80211_BAND_5GHZ] is NULL",__func__ );
5138 return;
5139 }
5140 for (j = 0; j < wiphy->bands[IEEE80211_BAND_5GHZ]->n_channels; j++)
5141 {
5142 struct ieee80211_supported_band *band = wiphy->bands[IEEE80211_BAND_5GHZ];
5143 // Mark UNII -1 band channel as passive
5144 if (WLAN_HDD_CHANNEL_IN_UNII_1_BAND(band->channels[j].center_freq))
5145 band->channels[j].flags |= IEEE80211_CHAN_PASSIVE_SCAN;
5146 }
5147 }
5148}
5149
Agarwal Ashish8fa0e9a2014-05-23 00:40:12 +05305150/* This function registers for all frame which supplicant is interested in */
5151void wlan_hdd_cfg80211_register_frames(hdd_adapter_t* pAdapter)
Jeff Johnson295189b2012-06-20 16:38:30 -07005152{
Jeff Johnson295189b2012-06-20 16:38:30 -07005153 tHalHandle hHal = WLAN_HDD_GET_HAL_CTX(pAdapter);
5154 /* Register for all P2P action, public action etc frames */
5155 v_U16_t type = (SIR_MAC_MGMT_FRAME << 2) | ( SIR_MAC_MGMT_ACTION << 4);
5156
Jeff Johnsone7245742012-09-05 17:12:55 -07005157 ENTER();
5158
Jeff Johnson295189b2012-06-20 16:38:30 -07005159 /* Right now we are registering these frame when driver is getting
5160 initialized. Once we will move to 2.6.37 kernel, in which we have
5161 frame register ops, we will move this code as a part of that */
5162 /* GAS Initial Request */
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305163 sme_RegisterMgmtFrame(hHal, pAdapter->sessionId, type,
Jeff Johnson295189b2012-06-20 16:38:30 -07005164 (v_U8_t*)GAS_INITIAL_REQ, GAS_INITIAL_REQ_SIZE );
5165
5166 /* GAS Initial Response */
5167 sme_RegisterMgmtFrame(hHal, pAdapter->sessionId, type,
5168 (v_U8_t*)GAS_INITIAL_RSP, GAS_INITIAL_RSP_SIZE );
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305169
Jeff Johnson295189b2012-06-20 16:38:30 -07005170 /* GAS Comeback Request */
5171 sme_RegisterMgmtFrame(hHal, pAdapter->sessionId, type,
5172 (v_U8_t*)GAS_COMEBACK_REQ, GAS_COMEBACK_REQ_SIZE );
5173
5174 /* GAS Comeback Response */
5175 sme_RegisterMgmtFrame(hHal, pAdapter->sessionId, type,
5176 (v_U8_t*)GAS_COMEBACK_RSP, GAS_COMEBACK_RSP_SIZE );
5177
5178 /* P2P Public Action */
5179 sme_RegisterMgmtFrame(hHal, pAdapter->sessionId, type,
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305180 (v_U8_t*)P2P_PUBLIC_ACTION_FRAME,
Jeff Johnson295189b2012-06-20 16:38:30 -07005181 P2P_PUBLIC_ACTION_FRAME_SIZE );
5182
5183 /* P2P Action */
5184 sme_RegisterMgmtFrame(hHal, pAdapter->sessionId, type,
5185 (v_U8_t*)P2P_ACTION_FRAME,
5186 P2P_ACTION_FRAME_SIZE );
Chet Lanctot186b5732013-03-18 10:26:30 -07005187
Gopichand Nakkalae3d56e72013-04-21 23:33:32 +05305188 /* WNM BSS Transition Request frame */
5189 sme_RegisterMgmtFrame(hHal, pAdapter->sessionId, type,
5190 (v_U8_t*)WNM_BSS_ACTION_FRAME,
5191 WNM_BSS_ACTION_FRAME_SIZE );
Leela Venkata Kiran Kumar Reddy Chiralae8e62c82013-10-29 18:23:26 -07005192
5193 /* WNM-Notification */
5194 sme_RegisterMgmtFrame(hHal, pAdapter->sessionId, type,
5195 (v_U8_t*)WNM_NOTIFICATION_FRAME,
5196 WNM_NOTIFICATION_FRAME_SIZE );
Jeff Johnson295189b2012-06-20 16:38:30 -07005197}
5198
Agarwal Ashish8fa0e9a2014-05-23 00:40:12 +05305199void wlan_hdd_cfg80211_deregister_frames(hdd_adapter_t* pAdapter)
Jeff Johnson295189b2012-06-20 16:38:30 -07005200{
Jeff Johnson295189b2012-06-20 16:38:30 -07005201 tHalHandle hHal = WLAN_HDD_GET_HAL_CTX(pAdapter);
5202 /* Register for all P2P action, public action etc frames */
5203 v_U16_t type = (SIR_MAC_MGMT_FRAME << 2) | ( SIR_MAC_MGMT_ACTION << 4);
5204
Jeff Johnsone7245742012-09-05 17:12:55 -07005205 ENTER();
5206
Jeff Johnson295189b2012-06-20 16:38:30 -07005207 /* Right now we are registering these frame when driver is getting
5208 initialized. Once we will move to 2.6.37 kernel, in which we have
5209 frame register ops, we will move this code as a part of that */
5210 /* GAS Initial Request */
5211
5212 sme_DeregisterMgmtFrame(hHal, pAdapter->sessionId, type,
5213 (v_U8_t*)GAS_INITIAL_REQ, GAS_INITIAL_REQ_SIZE );
5214
5215 /* GAS Initial Response */
5216 sme_DeregisterMgmtFrame(hHal, pAdapter->sessionId, type,
5217 (v_U8_t*)GAS_INITIAL_RSP, GAS_INITIAL_RSP_SIZE );
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305218
Jeff Johnson295189b2012-06-20 16:38:30 -07005219 /* GAS Comeback Request */
5220 sme_DeregisterMgmtFrame(hHal, pAdapter->sessionId, type,
5221 (v_U8_t*)GAS_COMEBACK_REQ, GAS_COMEBACK_REQ_SIZE );
5222
5223 /* GAS Comeback Response */
5224 sme_DeregisterMgmtFrame(hHal, pAdapter->sessionId, type,
5225 (v_U8_t*)GAS_COMEBACK_RSP, GAS_COMEBACK_RSP_SIZE );
5226
5227 /* P2P Public Action */
5228 sme_DeregisterMgmtFrame(hHal, pAdapter->sessionId, type,
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305229 (v_U8_t*)P2P_PUBLIC_ACTION_FRAME,
Jeff Johnson295189b2012-06-20 16:38:30 -07005230 P2P_PUBLIC_ACTION_FRAME_SIZE );
5231
5232 /* P2P Action */
5233 sme_DeregisterMgmtFrame(hHal, pAdapter->sessionId, type,
5234 (v_U8_t*)P2P_ACTION_FRAME,
5235 P2P_ACTION_FRAME_SIZE );
Leela Venkata Kiran Kumar Reddy Chiralae8e62c82013-10-29 18:23:26 -07005236 /* WNM-Notification */
5237 sme_DeregisterMgmtFrame(hHal, pAdapter->sessionId, type,
5238 (v_U8_t*)WNM_NOTIFICATION_FRAME,
5239 WNM_NOTIFICATION_FRAME_SIZE );
Jeff Johnson295189b2012-06-20 16:38:30 -07005240}
5241
5242#ifdef FEATURE_WLAN_WAPI
5243void wlan_hdd_cfg80211_set_key_wapi(hdd_adapter_t* pAdapter, u8 key_index,
5244 const u8 *mac_addr, u8 *key , int key_Len)
5245{
5246 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
5247 tCsrRoamSetKey setKey;
5248 v_BOOL_t isConnected = TRUE;
5249 int status = 0;
5250 v_U32_t roamId= 0xFF;
5251 tANI_U8 *pKeyPtr = NULL;
5252 int n = 0;
5253
Sushant Kaushik8bc7df22014-04-09 17:55:29 +05305254 hddLog(VOS_TRACE_LEVEL_INFO, "%s: device_mode = %s(%d)",
5255 __func__, hdd_device_modetoString(pAdapter->device_mode),
5256 pAdapter->device_mode);
Jeff Johnson295189b2012-06-20 16:38:30 -07005257
Gopichand Nakkalae7480202013-02-11 15:24:22 +05305258 vos_mem_zero(&setKey, sizeof(tCsrRoamSetKey));
Jeff Johnson295189b2012-06-20 16:38:30 -07005259 setKey.keyId = key_index; // Store Key ID
5260 setKey.encType = eCSR_ENCRYPT_TYPE_WPI; // SET WAPI Encryption
5261 setKey.keyDirection = eSIR_TX_RX; // Key Directionn both TX and RX
5262 setKey.paeRole = 0 ; // the PAE role
5263 if (!mac_addr || is_broadcast_ether_addr(mac_addr))
5264 {
5265 vos_set_macaddr_broadcast( (v_MACADDR_t *)setKey.peerMac );
5266 }
5267 else
5268 {
5269 isConnected = hdd_connIsConnected(pHddStaCtx);
5270 vos_mem_copy(setKey.peerMac,&pHddStaCtx->conn_info.bssId,WNI_CFG_BSSID_LEN);
5271 }
5272 setKey.keyLength = key_Len;
5273 pKeyPtr = setKey.Key;
5274 memcpy( pKeyPtr, key, key_Len);
5275
Arif Hussain6d2a3322013-11-17 19:50:10 -08005276 hddLog(VOS_TRACE_LEVEL_INFO,"%s: WAPI KEY LENGTH:0x%04x",
Jeff Johnson295189b2012-06-20 16:38:30 -07005277 __func__, key_Len);
5278 for (n = 0 ; n < key_Len; n++)
5279 hddLog(VOS_TRACE_LEVEL_INFO, "%s WAPI KEY Data[%d]:%02x ",
5280 __func__,n,setKey.Key[n]);
5281
5282 pHddStaCtx->roam_info.roamingState = HDD_ROAM_STATE_SETTING_KEY;
5283 if ( isConnected )
5284 {
5285 status= sme_RoamSetKey( WLAN_HDD_GET_HAL_CTX(pAdapter),
5286 pAdapter->sessionId, &setKey, &roamId );
5287 }
5288 if ( status != 0 )
5289 {
5290 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
5291 "[%4d] sme_RoamSetKey returned ERROR status= %d",
5292 __LINE__, status );
5293 pHddStaCtx->roam_info.roamingState = HDD_ROAM_STATE_NONE;
5294 }
Vinay Krishna Eranna6f22c1f2014-10-13 16:03:06 +05305295 /* Need to clear any trace of key value in the memory.
5296 * Thus zero out the memory even though it is local
5297 * variable.
5298 */
5299 vos_mem_zero(&setKey, sizeof(setKey));
Jeff Johnson295189b2012-06-20 16:38:30 -07005300}
5301#endif /* FEATURE_WLAN_WAPI*/
5302
5303#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,4,0))
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305304int wlan_hdd_cfg80211_alloc_new_beacon(hdd_adapter_t *pAdapter,
Jeff Johnson295189b2012-06-20 16:38:30 -07005305 beacon_data_t **ppBeacon,
5306 struct beacon_parameters *params)
Jeff Johnson04dd8a82012-06-29 20:41:40 -07005307#else
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305308int wlan_hdd_cfg80211_alloc_new_beacon(hdd_adapter_t *pAdapter,
Jeff Johnson04dd8a82012-06-29 20:41:40 -07005309 beacon_data_t **ppBeacon,
5310 struct cfg80211_beacon_data *params,
5311 int dtim_period)
5312#endif
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305313{
Jeff Johnson295189b2012-06-20 16:38:30 -07005314 int size;
5315 beacon_data_t *beacon = NULL;
5316 beacon_data_t *old = NULL;
5317 int head_len,tail_len;
5318
Jeff Johnsone7245742012-09-05 17:12:55 -07005319 ENTER();
Jeff Johnson295189b2012-06-20 16:38:30 -07005320 if (params->head && !params->head_len)
c_hpothu6ff1c3c2013-10-01 19:01:57 +05305321 {
5322 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
5323 FL("head_len is NULL"));
Jeff Johnson295189b2012-06-20 16:38:30 -07005324 return -EINVAL;
c_hpothu6ff1c3c2013-10-01 19:01:57 +05305325 }
Jeff Johnson295189b2012-06-20 16:38:30 -07005326
5327 old = pAdapter->sessionCtx.ap.beacon;
5328
5329 if (!params->head && !old)
c_hpothu6ff1c3c2013-10-01 19:01:57 +05305330 {
5331 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
5332 FL("session(%d) old and new heads points to NULL"),
5333 pAdapter->sessionId);
Jeff Johnson295189b2012-06-20 16:38:30 -07005334 return -EINVAL;
c_hpothu6ff1c3c2013-10-01 19:01:57 +05305335 }
5336
5337 if (params->tail && !params->tail_len)
5338 {
5339 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
5340 FL("tail_len is zero but tail is not NULL"));
5341 return -EINVAL;
5342 }
Jeff Johnson295189b2012-06-20 16:38:30 -07005343
Jeff Johnson295189b2012-06-20 16:38:30 -07005344#if (LINUX_VERSION_CODE <= KERNEL_VERSION(2,6,38))
5345 /* Kernel 3.0 is not updating dtim_period for set beacon */
5346 if (!params->dtim_period)
c_hpothu6ff1c3c2013-10-01 19:01:57 +05305347 {
5348 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
5349 FL("dtim period is 0"));
Jeff Johnson295189b2012-06-20 16:38:30 -07005350 return -EINVAL;
c_hpothu6ff1c3c2013-10-01 19:01:57 +05305351 }
Jeff Johnson295189b2012-06-20 16:38:30 -07005352#endif
5353
5354 if(params->head)
5355 head_len = params->head_len;
5356 else
5357 head_len = old->head_len;
5358
5359 if(params->tail || !old)
5360 tail_len = params->tail_len;
5361 else
5362 tail_len = old->tail_len;
5363
5364 size = sizeof(beacon_data_t) + head_len + tail_len;
5365
5366 beacon = kzalloc(size, GFP_KERNEL);
5367
5368 if( beacon == NULL )
c_hpothu6ff1c3c2013-10-01 19:01:57 +05305369 {
5370 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
5371 FL("Mem allocation for beacon failed"));
Jeff Johnson295189b2012-06-20 16:38:30 -07005372 return -ENOMEM;
c_hpothu6ff1c3c2013-10-01 19:01:57 +05305373 }
Jeff Johnson295189b2012-06-20 16:38:30 -07005374
Jeff Johnson04dd8a82012-06-29 20:41:40 -07005375#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,4,0))
Jeff Johnson295189b2012-06-20 16:38:30 -07005376 if(params->dtim_period || !old )
5377 beacon->dtim_period = params->dtim_period;
5378 else
5379 beacon->dtim_period = old->dtim_period;
Jeff Johnson04dd8a82012-06-29 20:41:40 -07005380#else
5381 if(dtim_period || !old )
5382 beacon->dtim_period = dtim_period;
5383 else
5384 beacon->dtim_period = old->dtim_period;
5385#endif
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305386
Jeff Johnson295189b2012-06-20 16:38:30 -07005387 beacon->head = ((u8 *) beacon) + sizeof(beacon_data_t);
5388 beacon->tail = beacon->head + head_len;
5389 beacon->head_len = head_len;
5390 beacon->tail_len = tail_len;
5391
5392 if(params->head) {
5393 memcpy (beacon->head,params->head,beacon->head_len);
5394 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305395 else {
Jeff Johnson295189b2012-06-20 16:38:30 -07005396 if(old)
5397 memcpy (beacon->head,old->head,beacon->head_len);
5398 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305399
Jeff Johnson295189b2012-06-20 16:38:30 -07005400 if(params->tail) {
5401 memcpy (beacon->tail,params->tail,beacon->tail_len);
5402 }
5403 else {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305404 if(old)
Jeff Johnson295189b2012-06-20 16:38:30 -07005405 memcpy (beacon->tail,old->tail,beacon->tail_len);
5406 }
5407
5408 *ppBeacon = beacon;
5409
5410 kfree(old);
5411
5412 return 0;
5413
5414}
Jeff Johnson295189b2012-06-20 16:38:30 -07005415
5416v_U8_t* wlan_hdd_cfg80211_get_ie_ptr(v_U8_t *pIes, int length, v_U8_t eid)
5417{
5418 int left = length;
5419 v_U8_t *ptr = pIes;
5420 v_U8_t elem_id,elem_len;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305421
Jeff Johnson295189b2012-06-20 16:38:30 -07005422 while(left >= 2)
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305423 {
Jeff Johnson295189b2012-06-20 16:38:30 -07005424 elem_id = ptr[0];
5425 elem_len = ptr[1];
5426 left -= 2;
5427 if(elem_len > left)
5428 {
5429 hddLog(VOS_TRACE_LEVEL_FATAL,
Madan Mohan Koyyalamudi8bdd3112012-09-24 13:55:14 -07005430 FL("****Invalid IEs eid = %d elem_len=%d left=%d*****"),
Jeff Johnson295189b2012-06-20 16:38:30 -07005431 eid,elem_len,left);
5432 return NULL;
5433 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305434 if (elem_id == eid)
Jeff Johnson295189b2012-06-20 16:38:30 -07005435 {
5436 return ptr;
5437 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305438
Jeff Johnson295189b2012-06-20 16:38:30 -07005439 left -= elem_len;
5440 ptr += (elem_len + 2);
5441 }
5442 return NULL;
5443}
5444
Jeff Johnson295189b2012-06-20 16:38:30 -07005445/* Check if rate is 11g rate or not */
5446static int wlan_hdd_rate_is_11g(u8 rate)
5447{
Sanjay Devnani28322e22013-06-21 16:13:40 -07005448 static const u8 gRateArray[8] = {12, 18, 24, 36, 48, 72, 96, 108}; /* actual rate * 2 */
Jeff Johnson295189b2012-06-20 16:38:30 -07005449 u8 i;
5450 for (i = 0; i < 8; i++)
5451 {
5452 if(rate == gRateArray[i])
5453 return TRUE;
5454 }
5455 return FALSE;
5456}
5457
5458/* Check for 11g rate and set proper 11g only mode */
5459static void wlan_hdd_check_11gmode(u8 *pIe, u8* require_ht,
5460 u8* pCheckRatesfor11g, eSapPhyMode* pSapHw_mode)
5461{
5462 u8 i, num_rates = pIe[0];
5463
5464 pIe += 1;
5465 for ( i = 0; i < num_rates; i++)
5466 {
5467 if( *pCheckRatesfor11g && (TRUE == wlan_hdd_rate_is_11g(pIe[i] & RATE_MASK)))
5468 {
5469 /* If rate set have 11g rate than change the mode to 11G */
5470 *pSapHw_mode = eSAP_DOT11_MODE_11g;
5471 if (pIe[i] & BASIC_RATE_MASK)
5472 {
5473 /* If we have 11g rate as basic rate, it means mode
5474 is 11g only mode.
5475 */
5476 *pSapHw_mode = eSAP_DOT11_MODE_11g_ONLY;
5477 *pCheckRatesfor11g = FALSE;
5478 }
5479 }
5480 else if((BASIC_RATE_MASK | WLAN_BSS_MEMBERSHIP_SELECTOR_HT_PHY) == pIe[i])
5481 {
5482 *require_ht = TRUE;
5483 }
5484 }
5485 return;
5486}
5487
5488static void wlan_hdd_set_sapHwmode(hdd_adapter_t *pHostapdAdapter)
5489{
5490 tsap_Config_t *pConfig = &pHostapdAdapter->sessionCtx.ap.sapConfig;
5491 beacon_data_t *pBeacon = pHostapdAdapter->sessionCtx.ap.beacon;
5492 struct ieee80211_mgmt *pMgmt_frame = (struct ieee80211_mgmt*)pBeacon->head;
5493 u8 checkRatesfor11g = TRUE;
5494 u8 require_ht = FALSE;
5495 u8 *pIe=NULL;
5496
5497 pConfig->SapHw_mode= eSAP_DOT11_MODE_11b;
5498
5499 pIe = wlan_hdd_cfg80211_get_ie_ptr(&pMgmt_frame->u.beacon.variable[0],
5500 pBeacon->head_len, WLAN_EID_SUPP_RATES);
5501 if (pIe != NULL)
5502 {
5503 pIe += 1;
5504 wlan_hdd_check_11gmode(pIe, &require_ht, &checkRatesfor11g,
5505 &pConfig->SapHw_mode);
5506 }
5507
5508 pIe = wlan_hdd_cfg80211_get_ie_ptr(pBeacon->tail, pBeacon->tail_len,
5509 WLAN_EID_EXT_SUPP_RATES);
5510 if (pIe != NULL)
5511 {
5512
5513 pIe += 1;
5514 wlan_hdd_check_11gmode(pIe, &require_ht, &checkRatesfor11g,
5515 &pConfig->SapHw_mode);
5516 }
5517
5518 if( pConfig->channel > 14 )
5519 {
5520 pConfig->SapHw_mode= eSAP_DOT11_MODE_11a;
5521 }
5522
5523 pIe = wlan_hdd_cfg80211_get_ie_ptr(pBeacon->tail, pBeacon->tail_len,
5524 WLAN_EID_HT_CAPABILITY);
5525
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305526 if(pIe)
Jeff Johnson295189b2012-06-20 16:38:30 -07005527 {
5528 pConfig->SapHw_mode= eSAP_DOT11_MODE_11n;
5529 if(require_ht)
5530 pConfig->SapHw_mode= eSAP_DOT11_MODE_11n_ONLY;
5531 }
5532}
5533
Gopichand Nakkala2b25f4e2013-03-21 19:14:07 +05305534static int wlan_hdd_add_ie(hdd_adapter_t* pHostapdAdapter, v_U8_t *genie,
5535 v_U8_t *total_ielen, v_U8_t *oui, v_U8_t oui_size)
5536{
Arif Hussaine7f3ea52013-09-12 21:56:36 -07005537 v_U16_t ielen = 0;
Gopichand Nakkala2b25f4e2013-03-21 19:14:07 +05305538 v_U8_t *pIe = NULL;
5539 beacon_data_t *pBeacon = pHostapdAdapter->sessionCtx.ap.beacon;
5540
5541 pIe = wlan_hdd_get_vendor_oui_ie_ptr(oui, oui_size,
5542 pBeacon->tail, pBeacon->tail_len);
5543
5544 if (pIe)
5545 {
5546 ielen = pIe[1] + 2;
5547 if ((*total_ielen + ielen) <= MAX_GENIE_LEN)
5548 {
5549 vos_mem_copy(&genie[*total_ielen], pIe, ielen);
5550 }
5551 else
5552 {
5553 hddLog( VOS_TRACE_LEVEL_ERROR, "**Ie Length is too big***");
5554 return -EINVAL;
5555 }
5556 *total_ielen += ielen;
5557 }
5558 return 0;
5559}
5560
Arif Hussaine7f3ea52013-09-12 21:56:36 -07005561static void wlan_hdd_add_hostapd_conf_vsie(hdd_adapter_t* pHostapdAdapter,
5562 v_U8_t *genie, v_U8_t *total_ielen)
5563{
5564 beacon_data_t *pBeacon = pHostapdAdapter->sessionCtx.ap.beacon;
5565 int left = pBeacon->tail_len;
5566 v_U8_t *ptr = pBeacon->tail;
5567 v_U8_t elem_id, elem_len;
5568 v_U16_t ielen = 0;
5569
5570 if ( NULL == ptr || 0 == left )
5571 return;
5572
5573 while (left >= 2)
5574 {
5575 elem_id = ptr[0];
5576 elem_len = ptr[1];
5577 left -= 2;
5578 if (elem_len > left)
5579 {
5580 hddLog( VOS_TRACE_LEVEL_ERROR,
5581 "****Invalid IEs eid = %d elem_len=%d left=%d*****",
5582 elem_id, elem_len, left);
5583 return;
5584 }
5585 if (IE_EID_VENDOR == elem_id)
5586 {
5587 /* skipping the VSIE's which we don't want to include or
5588 * it will be included by existing code
5589 */
5590 if ((memcmp( &ptr[2], WPS_OUI_TYPE, WPS_OUI_TYPE_SIZE) != 0 ) &&
5591#ifdef WLAN_FEATURE_WFD
5592 (memcmp( &ptr[2], WFD_OUI_TYPE, WFD_OUI_TYPE_SIZE) != 0) &&
5593#endif
5594 (memcmp( &ptr[2], WHITELIST_OUI_TYPE, WPA_OUI_TYPE_SIZE) != 0) &&
5595 (memcmp( &ptr[2], BLACKLIST_OUI_TYPE, WPA_OUI_TYPE_SIZE) != 0) &&
5596 (memcmp( &ptr[2], "\x00\x50\xf2\x02", WPA_OUI_TYPE_SIZE) != 0) &&
5597 (memcmp( &ptr[2], WPA_OUI_TYPE, WPA_OUI_TYPE_SIZE) != 0) &&
5598 (memcmp( &ptr[2], P2P_OUI_TYPE, P2P_OUI_TYPE_SIZE) != 0))
5599 {
5600 ielen = ptr[1] + 2;
5601 if ((*total_ielen + ielen) <= MAX_GENIE_LEN)
5602 {
5603 vos_mem_copy(&genie[*total_ielen], ptr, ielen);
5604 *total_ielen += ielen;
5605 }
5606 else
5607 {
5608 hddLog( VOS_TRACE_LEVEL_ERROR,
5609 "IE Length is too big "
5610 "IEs eid=%d elem_len=%d total_ie_lent=%d",
5611 elem_id, elem_len, *total_ielen);
5612 }
5613 }
5614 }
5615
5616 left -= elem_len;
5617 ptr += (elem_len + 2);
5618 }
5619 return;
5620}
5621
Jeff Johnson04dd8a82012-06-29 20:41:40 -07005622#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,4,0))
Jeff Johnson295189b2012-06-20 16:38:30 -07005623static int wlan_hdd_cfg80211_update_apies(hdd_adapter_t* pHostapdAdapter,
5624 struct beacon_parameters *params)
Jeff Johnson04dd8a82012-06-29 20:41:40 -07005625#else
5626static int wlan_hdd_cfg80211_update_apies(hdd_adapter_t* pHostapdAdapter,
5627 struct cfg80211_beacon_data *params)
5628#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07005629{
5630 v_U8_t *genie;
Gopichand Nakkala2b25f4e2013-03-21 19:14:07 +05305631 v_U8_t total_ielen = 0;
Jeff Johnson295189b2012-06-20 16:38:30 -07005632 v_U8_t addIE[1] = {0};
Jeff Johnsone7245742012-09-05 17:12:55 -07005633 int ret = 0;
Jeff Johnson295189b2012-06-20 16:38:30 -07005634
5635 genie = vos_mem_malloc(MAX_GENIE_LEN);
5636
5637 if(genie == NULL) {
5638
5639 return -ENOMEM;
5640 }
5641
Gopichand Nakkala2b25f4e2013-03-21 19:14:07 +05305642 if (0 != wlan_hdd_add_ie(pHostapdAdapter, genie,
5643 &total_ielen, WPS_OUI_TYPE, WPS_OUI_TYPE_SIZE))
Jeff Johnson295189b2012-06-20 16:38:30 -07005644 {
c_hpothu6ff1c3c2013-10-01 19:01:57 +05305645 hddLog(LOGE,
5646 FL("Adding WPS IE failed"));
Gopichand Nakkala2b25f4e2013-03-21 19:14:07 +05305647 ret = -EINVAL;
5648 goto done;
Jeff Johnson295189b2012-06-20 16:38:30 -07005649 }
5650
5651#ifdef WLAN_FEATURE_WFD
Gopichand Nakkala2b25f4e2013-03-21 19:14:07 +05305652 if (0 != wlan_hdd_add_ie(pHostapdAdapter, genie,
5653 &total_ielen, WFD_OUI_TYPE, WFD_OUI_TYPE_SIZE))
5654 {
c_hpothu6ff1c3c2013-10-01 19:01:57 +05305655 hddLog(LOGE,
5656 FL("Adding WFD IE failed"));
Gopichand Nakkala2b25f4e2013-03-21 19:14:07 +05305657 ret = -EINVAL;
5658 goto done;
Jeff Johnson295189b2012-06-20 16:38:30 -07005659 }
5660#endif
5661
Gopichand Nakkala2b25f4e2013-03-21 19:14:07 +05305662 if (0 != wlan_hdd_add_ie(pHostapdAdapter, genie,
5663 &total_ielen, P2P_OUI_TYPE, P2P_OUI_TYPE_SIZE))
Jeff Johnson295189b2012-06-20 16:38:30 -07005664 {
c_hpothu6ff1c3c2013-10-01 19:01:57 +05305665 hddLog(LOGE,
5666 FL("Adding P2P IE failed"));
Gopichand Nakkala2b25f4e2013-03-21 19:14:07 +05305667 ret = -EINVAL;
5668 goto done;
5669 }
5670
5671 if (WLAN_HDD_SOFTAP == pHostapdAdapter->device_mode)
5672 {
Arif Hussaine7f3ea52013-09-12 21:56:36 -07005673 wlan_hdd_add_hostapd_conf_vsie(pHostapdAdapter, genie, &total_ielen);
Jeff Johnson295189b2012-06-20 16:38:30 -07005674 }
Jeff Johnson295189b2012-06-20 16:38:30 -07005675
5676 if (ccmCfgSetStr((WLAN_HDD_GET_CTX(pHostapdAdapter))->hHal,
5677 WNI_CFG_PROBE_RSP_BCN_ADDNIE_DATA, genie, total_ielen, NULL,
5678 eANI_BOOLEAN_FALSE)==eHAL_STATUS_FAILURE)
5679 {
5680 hddLog(LOGE,
5681 "Could not pass on WNI_CFG_PROBE_RSP_BCN_ADDNIE_DATA to CCM");
Jeff Johnsone7245742012-09-05 17:12:55 -07005682 ret = -EINVAL;
5683 goto done;
Jeff Johnson295189b2012-06-20 16:38:30 -07005684 }
5685
5686 if (ccmCfgSetInt((WLAN_HDD_GET_CTX(pHostapdAdapter))->hHal,
5687 WNI_CFG_PROBE_RSP_BCN_ADDNIE_FLAG, 1,NULL,
5688 test_bit(SOFTAP_BSS_STARTED, &pHostapdAdapter->event_flags) ?
5689 eANI_BOOLEAN_TRUE : eANI_BOOLEAN_FALSE)
5690 ==eHAL_STATUS_FAILURE)
5691 {
5692 hddLog(LOGE,
5693 "Could not pass on WNI_CFG_PROBE_RSP_BCN_ADDNIE_FLAG to CCM");
Jeff Johnsone7245742012-09-05 17:12:55 -07005694 ret = -EINVAL;
5695 goto done;
Jeff Johnson295189b2012-06-20 16:38:30 -07005696 }
5697
5698 // Added for ProResp IE
5699 if ( (params->proberesp_ies != NULL) && (params->proberesp_ies_len != 0) )
5700 {
5701 u16 rem_probe_resp_ie_len = params->proberesp_ies_len;
5702 u8 probe_rsp_ie_len[3] = {0};
5703 u8 counter = 0;
5704 /* Check Probe Resp Length if it is greater then 255 then Store
5705 Probe Resp IEs into WNI_CFG_PROBE_RSP_ADDNIE_DATA1 &
5706 WNI_CFG_PROBE_RSP_ADDNIE_DATA2 CFG Variable As We are not able
5707 Store More then 255 bytes into One Variable.
5708 */
5709 while ((rem_probe_resp_ie_len > 0) && (counter < 3))
5710 {
5711 if (rem_probe_resp_ie_len > MAX_CFG_STRING_LEN)
5712 {
5713 probe_rsp_ie_len[counter++] = MAX_CFG_STRING_LEN;
5714 rem_probe_resp_ie_len -= MAX_CFG_STRING_LEN;
5715 }
5716 else
5717 {
5718 probe_rsp_ie_len[counter++] = rem_probe_resp_ie_len;
5719 rem_probe_resp_ie_len = 0;
5720 }
5721 }
5722
5723 rem_probe_resp_ie_len = 0;
5724
5725 if (probe_rsp_ie_len[0] > 0)
5726 {
5727 if (ccmCfgSetStr((WLAN_HDD_GET_CTX(pHostapdAdapter))->hHal,
5728 WNI_CFG_PROBE_RSP_ADDNIE_DATA1,
5729 (tANI_U8*)&params->proberesp_ies[rem_probe_resp_ie_len],
5730 probe_rsp_ie_len[0], NULL,
5731 eANI_BOOLEAN_FALSE) == eHAL_STATUS_FAILURE)
5732 {
5733 hddLog(LOGE,
5734 "Could not pass on WNI_CFG_PROBE_RSP_ADDNIE_DATA1 to CCM");
Jeff Johnsone7245742012-09-05 17:12:55 -07005735 ret = -EINVAL;
5736 goto done;
Jeff Johnson295189b2012-06-20 16:38:30 -07005737 }
5738 rem_probe_resp_ie_len += probe_rsp_ie_len[0];
5739 }
5740
5741 if (probe_rsp_ie_len[1] > 0)
5742 {
5743 if (ccmCfgSetStr((WLAN_HDD_GET_CTX(pHostapdAdapter))->hHal,
5744 WNI_CFG_PROBE_RSP_ADDNIE_DATA2,
5745 (tANI_U8*)&params->proberesp_ies[rem_probe_resp_ie_len],
5746 probe_rsp_ie_len[1], NULL,
5747 eANI_BOOLEAN_FALSE) == eHAL_STATUS_FAILURE)
5748 {
5749 hddLog(LOGE,
5750 "Could not pass on WNI_CFG_PROBE_RSP_ADDNIE_DATA2 to CCM");
Jeff Johnsone7245742012-09-05 17:12:55 -07005751 ret = -EINVAL;
5752 goto done;
Jeff Johnson295189b2012-06-20 16:38:30 -07005753 }
5754 rem_probe_resp_ie_len += probe_rsp_ie_len[1];
5755 }
5756
5757 if (probe_rsp_ie_len[2] > 0)
5758 {
5759 if (ccmCfgSetStr((WLAN_HDD_GET_CTX(pHostapdAdapter))->hHal,
5760 WNI_CFG_PROBE_RSP_ADDNIE_DATA3,
5761 (tANI_U8*)&params->proberesp_ies[rem_probe_resp_ie_len],
5762 probe_rsp_ie_len[2], NULL,
5763 eANI_BOOLEAN_FALSE) == eHAL_STATUS_FAILURE)
5764 {
5765 hddLog(LOGE,
5766 "Could not pass on WNI_CFG_PROBE_RSP_ADDNIE_DATA3 to CCM");
Jeff Johnsone7245742012-09-05 17:12:55 -07005767 ret = -EINVAL;
5768 goto done;
Jeff Johnson295189b2012-06-20 16:38:30 -07005769 }
5770 rem_probe_resp_ie_len += probe_rsp_ie_len[2];
5771 }
5772
5773 if (probe_rsp_ie_len[1] == 0 )
5774 {
5775 if ( eHAL_STATUS_FAILURE == ccmCfgSetStr((WLAN_HDD_GET_CTX(pHostapdAdapter))->hHal,
5776 WNI_CFG_PROBE_RSP_ADDNIE_DATA2, (tANI_U8*)addIE, 0, NULL,
5777 eANI_BOOLEAN_FALSE) )
5778 {
5779 hddLog(LOGE,
Arif Hussain6d2a3322013-11-17 19:50:10 -08005780 "Could not pass on WNI_CFG_PROBE_RSP_ADDNIE_DATA2 to CCM");
Jeff Johnson295189b2012-06-20 16:38:30 -07005781 }
5782 }
5783
5784 if (probe_rsp_ie_len[2] == 0 )
5785 {
5786 if ( eHAL_STATUS_FAILURE == ccmCfgSetStr((WLAN_HDD_GET_CTX(pHostapdAdapter))->hHal,
5787 WNI_CFG_PROBE_RSP_ADDNIE_DATA3, (tANI_U8*)addIE, 0, NULL,
5788 eANI_BOOLEAN_FALSE) )
5789 {
5790 hddLog(LOGE,
Arif Hussain6d2a3322013-11-17 19:50:10 -08005791 "Could not pass on WNI_CFG_PROBE_RSP_ADDNIE_DATA3 to CCM");
Jeff Johnson295189b2012-06-20 16:38:30 -07005792 }
5793 }
5794
5795 if (ccmCfgSetInt((WLAN_HDD_GET_CTX(pHostapdAdapter))->hHal,
5796 WNI_CFG_PROBE_RSP_ADDNIE_FLAG, 1,NULL,
5797 test_bit(SOFTAP_BSS_STARTED, &pHostapdAdapter->event_flags) ?
5798 eANI_BOOLEAN_TRUE : eANI_BOOLEAN_FALSE)
5799 == eHAL_STATUS_FAILURE)
5800 {
5801 hddLog(LOGE,
5802 "Could not pass on WNI_CFG_PROBE_RSP_ADDNIE_FLAG to CCM");
Jeff Johnsone7245742012-09-05 17:12:55 -07005803 ret = -EINVAL;
5804 goto done;
Jeff Johnson295189b2012-06-20 16:38:30 -07005805 }
5806 }
5807 else
5808 {
5809 // Reset WNI_CFG_PROBE_RSP Flags
5810 wlan_hdd_reset_prob_rspies(pHostapdAdapter);
5811
5812 hddLog(VOS_TRACE_LEVEL_INFO,
5813 "%s: No Probe Response IE received in set beacon",
5814 __func__);
5815 }
5816
5817 // Added for AssocResp IE
5818 if ( (params->assocresp_ies != NULL) && (params->assocresp_ies_len != 0) )
5819 {
5820 if (ccmCfgSetStr((WLAN_HDD_GET_CTX(pHostapdAdapter))->hHal,
5821 WNI_CFG_ASSOC_RSP_ADDNIE_DATA, (tANI_U8*)params->assocresp_ies,
5822 params->assocresp_ies_len, NULL,
5823 eANI_BOOLEAN_FALSE) == eHAL_STATUS_FAILURE)
5824 {
5825 hddLog(LOGE,
5826 "Could not pass on WNI_CFG_ASSOC_RSP_ADDNIE_DATA to CCM");
Jeff Johnsone7245742012-09-05 17:12:55 -07005827 ret = -EINVAL;
5828 goto done;
Jeff Johnson295189b2012-06-20 16:38:30 -07005829 }
5830
5831 if (ccmCfgSetInt((WLAN_HDD_GET_CTX(pHostapdAdapter))->hHal,
5832 WNI_CFG_ASSOC_RSP_ADDNIE_FLAG, 1, NULL,
5833 test_bit(SOFTAP_BSS_STARTED, &pHostapdAdapter->event_flags) ?
5834 eANI_BOOLEAN_TRUE : eANI_BOOLEAN_FALSE)
5835 == eHAL_STATUS_FAILURE)
5836 {
5837 hddLog(LOGE,
5838 "Could not pass on WNI_CFG_ASSOC_RSP_ADDNIE_FLAG to CCM");
Jeff Johnsone7245742012-09-05 17:12:55 -07005839 ret = -EINVAL;
5840 goto done;
Jeff Johnson295189b2012-06-20 16:38:30 -07005841 }
5842 }
5843 else
5844 {
5845 hddLog(VOS_TRACE_LEVEL_INFO,
5846 "%s: No Assoc Response IE received in set beacon",
5847 __func__);
5848
5849 if ( eHAL_STATUS_FAILURE == ccmCfgSetInt((WLAN_HDD_GET_CTX(pHostapdAdapter))->hHal,
5850 WNI_CFG_ASSOC_RSP_ADDNIE_FLAG, 0, NULL,
5851 eANI_BOOLEAN_FALSE) )
5852 {
5853 hddLog(LOGE,
Arif Hussain6d2a3322013-11-17 19:50:10 -08005854 "Could not pass on WNI_CFG_ASSOC_RSP_ADDNIE_FLAG to CCM");
Jeff Johnson295189b2012-06-20 16:38:30 -07005855 }
5856 }
5857
Jeff Johnsone7245742012-09-05 17:12:55 -07005858done:
Jeff Johnson295189b2012-06-20 16:38:30 -07005859 vos_mem_free(genie);
Gopichand Nakkala2b25f4e2013-03-21 19:14:07 +05305860 return ret;
Jeff Johnson295189b2012-06-20 16:38:30 -07005861}
Jeff Johnson295189b2012-06-20 16:38:30 -07005862
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305863/*
Jeff Johnson295189b2012-06-20 16:38:30 -07005864 * FUNCTION: wlan_hdd_validate_operation_channel
5865 * called by wlan_hdd_cfg80211_start_bss() and
5866 * wlan_hdd_cfg80211_set_channel()
5867 * This function validates whether given channel is part of valid
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305868 * channel list.
5869 */
Varun Reddy Yeturu920df212013-05-22 08:07:23 -07005870VOS_STATUS wlan_hdd_validate_operation_channel(hdd_adapter_t *pAdapter,int channel)
Jeff Johnson295189b2012-06-20 16:38:30 -07005871{
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305872
Jeff Johnson295189b2012-06-20 16:38:30 -07005873 v_U32_t num_ch = 0;
5874 u8 valid_ch[WNI_CFG_VALID_CHANNEL_LIST_LEN];
5875 u32 indx = 0;
5876 tHalHandle hHal = WLAN_HDD_GET_HAL_CTX(pAdapter);
Madan Mohan Koyylamudi64267f72013-02-05 14:07:08 +05305877 v_U8_t fValidChannel = FALSE, count = 0;
5878 hdd_config_t *hdd_pConfig_ini= (WLAN_HDD_GET_CTX(pAdapter))->cfg_ini;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305879
Jeff Johnson295189b2012-06-20 16:38:30 -07005880 num_ch = WNI_CFG_VALID_CHANNEL_LIST_LEN;
5881
Madan Mohan Koyylamudi64267f72013-02-05 14:07:08 +05305882 if ( hdd_pConfig_ini->sapAllowAllChannel)
Jeff Johnson295189b2012-06-20 16:38:30 -07005883 {
Madan Mohan Koyylamudi64267f72013-02-05 14:07:08 +05305884 /* Validate the channel */
5885 for (count = RF_CHAN_1 ; count <= RF_CHAN_165 ; count++)
Jeff Johnson295189b2012-06-20 16:38:30 -07005886 {
Madan Mohan Koyylamudi64267f72013-02-05 14:07:08 +05305887 if ( channel == rfChannels[count].channelNum )
5888 {
5889 fValidChannel = TRUE;
5890 break;
5891 }
5892 }
5893 if (fValidChannel != TRUE)
5894 {
5895 hddLog(VOS_TRACE_LEVEL_ERROR,
5896 "%s: Invalid Channel [%d]", __func__, channel);
5897 return VOS_STATUS_E_FAILURE;
Jeff Johnson295189b2012-06-20 16:38:30 -07005898 }
5899 }
Madan Mohan Koyylamudi64267f72013-02-05 14:07:08 +05305900 else
Jeff Johnson295189b2012-06-20 16:38:30 -07005901 {
Madan Mohan Koyylamudi64267f72013-02-05 14:07:08 +05305902 if (0 != ccmCfgGetStr(hHal, WNI_CFG_VALID_CHANNEL_LIST,
5903 valid_ch, &num_ch))
5904 {
5905 hddLog(VOS_TRACE_LEVEL_ERROR,
5906 "%s: failed to get valid channel list", __func__);
5907 return VOS_STATUS_E_FAILURE;
5908 }
5909 for (indx = 0; indx < num_ch; indx++)
5910 {
5911 if (channel == valid_ch[indx])
5912 {
5913 break;
5914 }
5915 }
5916
Rashmi Ramanna3b59e122014-04-10 14:45:13 +05305917 if (indx >= num_ch)
5918 {
5919 if (WLAN_HDD_P2P_GO == pAdapter->device_mode)
5920 {
5921 eCsrBand band;
5922 unsigned int freq;
5923
5924 sme_GetFreqBand(hHal, &band);
5925
5926 if (eCSR_BAND_5G == band)
5927 {
5928#if (LINUX_VERSION_CODE > KERNEL_VERSION(2,6,38))
5929 if (channel <= ARRAY_SIZE(hdd_channels_2_4_GHZ))
5930 {
5931 freq = ieee80211_channel_to_frequency(channel,
5932 IEEE80211_BAND_2GHZ);
5933 }
5934 else
5935 {
5936 freq = ieee80211_channel_to_frequency(channel,
5937 IEEE80211_BAND_5GHZ);
5938 }
5939#else
5940 freq = ieee80211_channel_to_frequency(channel);
5941#endif
5942 if(WLAN_HDD_IS_SOCIAL_CHANNEL(freq))
5943 return VOS_STATUS_SUCCESS;
5944 }
5945 }
5946
5947 hddLog(VOS_TRACE_LEVEL_ERROR,
5948 "%s: Invalid Channel [%d]", __func__, channel);
5949 return VOS_STATUS_E_FAILURE;
5950 }
Jeff Johnson295189b2012-06-20 16:38:30 -07005951 }
Rashmi Ramanna3b59e122014-04-10 14:45:13 +05305952
Jeff Johnson295189b2012-06-20 16:38:30 -07005953 return VOS_STATUS_SUCCESS;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305954
Jeff Johnson295189b2012-06-20 16:38:30 -07005955}
5956
Viral Modi3a32cc52013-02-08 11:14:52 -08005957/**
5958 * FUNCTION: wlan_hdd_cfg80211_set_channel
5959 * This function is used to set the channel number
5960 */
5961static int wlan_hdd_cfg80211_set_channel( struct wiphy *wiphy, struct net_device *dev,
5962 struct ieee80211_channel *chan,
5963 enum nl80211_channel_type channel_type
5964 )
5965{
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05305966 hdd_adapter_t *pAdapter = NULL;
Viral Modi3a32cc52013-02-08 11:14:52 -08005967 v_U32_t num_ch = 0;
Jeff Johnson4416a782013-03-25 14:17:50 -07005968 int channel = 0;
Viral Modi3a32cc52013-02-08 11:14:52 -08005969 int freq = chan->center_freq; /* freq is in MHZ */
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05305970 hdd_context_t *pHddCtx;
5971 int status;
Viral Modi3a32cc52013-02-08 11:14:52 -08005972
5973 ENTER();
5974
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05305975
Viral Modi3a32cc52013-02-08 11:14:52 -08005976 if( NULL == dev )
5977 {
5978 hddLog(VOS_TRACE_LEVEL_ERROR,
Arif Hussain6d2a3322013-11-17 19:50:10 -08005979 "%s: Called with dev = NULL.", __func__);
Viral Modi3a32cc52013-02-08 11:14:52 -08005980 return -ENODEV;
5981 }
5982 pAdapter = WLAN_HDD_GET_PRIV_PTR( dev );
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +05305983
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05305984 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
5985 TRACE_CODE_HDD_CFG80211_SET_CHANNEL, pAdapter->sessionId,
5986 channel_type ));
Viral Modi3a32cc52013-02-08 11:14:52 -08005987 hddLog(VOS_TRACE_LEVEL_INFO,
Sushant Kaushik8bc7df22014-04-09 17:55:29 +05305988 "%s: device_mode = %s (%d) freq = %d", __func__,
5989 hdd_device_modetoString(pAdapter->device_mode),
5990 pAdapter->device_mode, chan->center_freq);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05305991
5992 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
5993 status = wlan_hdd_validate_context(pHddCtx);
5994
5995 if (0 != status)
Viral Modi3a32cc52013-02-08 11:14:52 -08005996 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05305997 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
5998 "%s: HDD context is not valid", __func__);
5999 return status;
Viral Modi3a32cc52013-02-08 11:14:52 -08006000 }
6001
6002 /*
6003 * Do freq to chan conversion
6004 * TODO: for 11a
6005 */
6006
6007 channel = ieee80211_frequency_to_channel(freq);
6008
6009 /* Check freq range */
6010 if ((WNI_CFG_CURRENT_CHANNEL_STAMIN > channel) ||
6011 (WNI_CFG_CURRENT_CHANNEL_STAMAX < channel))
6012 {
6013 hddLog(VOS_TRACE_LEVEL_ERROR,
Arif Hussain6d2a3322013-11-17 19:50:10 -08006014 "%s: Channel [%d] is outside valid range from %d to %d",
Viral Modi3a32cc52013-02-08 11:14:52 -08006015 __func__, channel, WNI_CFG_CURRENT_CHANNEL_STAMIN,
6016 WNI_CFG_CURRENT_CHANNEL_STAMAX);
6017 return -EINVAL;
6018 }
6019
6020 num_ch = WNI_CFG_VALID_CHANNEL_LIST_LEN;
6021
Gopichand Nakkala6ab19562013-03-07 13:59:42 +05306022 if ((WLAN_HDD_SOFTAP != pAdapter->device_mode) &&
6023 (WLAN_HDD_P2P_GO != pAdapter->device_mode))
Viral Modi3a32cc52013-02-08 11:14:52 -08006024 {
6025 if(VOS_STATUS_SUCCESS != wlan_hdd_validate_operation_channel(pAdapter,channel))
6026 {
6027 hddLog(VOS_TRACE_LEVEL_ERROR,
Arif Hussain6d2a3322013-11-17 19:50:10 -08006028 "%s: Invalid Channel [%d]", __func__, channel);
Viral Modi3a32cc52013-02-08 11:14:52 -08006029 return -EINVAL;
6030 }
6031 hddLog(VOS_TRACE_LEVEL_INFO_HIGH,
6032 "%s: set channel to [%d] for device mode =%d",
6033 __func__, channel,pAdapter->device_mode);
6034 }
6035 if( (pAdapter->device_mode == WLAN_HDD_INFRA_STATION)
Viral Modi3a32cc52013-02-08 11:14:52 -08006036 || (pAdapter->device_mode == WLAN_HDD_P2P_CLIENT)
Viral Modi3a32cc52013-02-08 11:14:52 -08006037 )
6038 {
6039 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
6040 tCsrRoamProfile * pRoamProfile = &pWextState->roamProfile;
6041 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
6042
6043 if (eConnectionState_IbssConnected == pHddStaCtx->conn_info.connState)
6044 {
6045 /* Link is up then return cant set channel*/
6046 hddLog( VOS_TRACE_LEVEL_ERROR,
Arif Hussain6d2a3322013-11-17 19:50:10 -08006047 "%s: IBSS Associated, can't set the channel", __func__);
Viral Modi3a32cc52013-02-08 11:14:52 -08006048 return -EINVAL;
6049 }
6050
6051 num_ch = pRoamProfile->ChannelInfo.numOfChannels = 1;
6052 pHddStaCtx->conn_info.operationChannel = channel;
6053 pRoamProfile->ChannelInfo.ChannelList =
6054 &pHddStaCtx->conn_info.operationChannel;
6055 }
6056 else if ((pAdapter->device_mode == WLAN_HDD_SOFTAP)
Viral Modi3a32cc52013-02-08 11:14:52 -08006057 || (pAdapter->device_mode == WLAN_HDD_P2P_GO)
Viral Modi3a32cc52013-02-08 11:14:52 -08006058 )
6059 {
Gopichand Nakkalac8fa7b62013-03-11 13:56:41 +05306060 if (WLAN_HDD_P2P_GO == pAdapter->device_mode)
6061 {
6062 if(VOS_STATUS_SUCCESS !=
6063 wlan_hdd_validate_operation_channel(pAdapter,channel))
6064 {
6065 hddLog(VOS_TRACE_LEVEL_ERROR,
Arif Hussain6d2a3322013-11-17 19:50:10 -08006066 "%s: Invalid Channel [%d]", __func__, channel);
Gopichand Nakkalac8fa7b62013-03-11 13:56:41 +05306067 return -EINVAL;
6068 }
6069 (WLAN_HDD_GET_AP_CTX_PTR(pAdapter))->sapConfig.channel = channel;
6070 }
6071 else if ( WLAN_HDD_SOFTAP == pAdapter->device_mode )
Viral Modi3a32cc52013-02-08 11:14:52 -08006072 {
6073 hdd_config_t *cfg_param = (WLAN_HDD_GET_CTX(pAdapter))->cfg_ini;
6074
6075 /* If auto channel selection is configured as enable/ 1 then ignore
6076 channel set by supplicant
6077 */
6078 if ( cfg_param->apAutoChannelSelection )
6079 {
Gopichand Nakkalac8fa7b62013-03-11 13:56:41 +05306080 (WLAN_HDD_GET_AP_CTX_PTR(pAdapter))->sapConfig.channel =
6081 AUTO_CHANNEL_SELECT;
Viral Modi3a32cc52013-02-08 11:14:52 -08006082 hddLog(VOS_TRACE_LEVEL_INFO_HIGH,
Sushant Kaushik8bc7df22014-04-09 17:55:29 +05306083 "%s: set channel to auto channel (0) for device mode =%s (%d)",
6084 __func__, hdd_device_modetoString(pAdapter->device_mode),
6085 pAdapter->device_mode);
Viral Modi3a32cc52013-02-08 11:14:52 -08006086 }
Gopichand Nakkalac8fa7b62013-03-11 13:56:41 +05306087 else
6088 {
6089 if(VOS_STATUS_SUCCESS !=
6090 wlan_hdd_validate_operation_channel(pAdapter,channel))
6091 {
6092 hddLog(VOS_TRACE_LEVEL_ERROR,
Arif Hussain6d2a3322013-11-17 19:50:10 -08006093 "%s: Invalid Channel [%d]", __func__, channel);
Gopichand Nakkalac8fa7b62013-03-11 13:56:41 +05306094 return -EINVAL;
6095 }
6096 (WLAN_HDD_GET_AP_CTX_PTR(pAdapter))->sapConfig.channel = channel;
6097 }
Viral Modi3a32cc52013-02-08 11:14:52 -08006098 }
6099 }
6100 else
6101 {
6102 hddLog(VOS_TRACE_LEVEL_FATAL,
6103 "%s: Invalid device mode failed to set valid channel", __func__);
6104 return -EINVAL;
6105 }
6106 EXIT();
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05306107 return status;
Viral Modi3a32cc52013-02-08 11:14:52 -08006108}
6109
Jeff Johnson295189b2012-06-20 16:38:30 -07006110#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,4,0))
6111static int wlan_hdd_cfg80211_start_bss(hdd_adapter_t *pHostapdAdapter,
6112 struct beacon_parameters *params)
Jeff Johnson04dd8a82012-06-29 20:41:40 -07006113#else
6114static int wlan_hdd_cfg80211_start_bss(hdd_adapter_t *pHostapdAdapter,
6115 struct cfg80211_beacon_data *params,
6116 const u8 *ssid, size_t ssid_len,
6117 enum nl80211_hidden_ssid hidden_ssid)
6118#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07006119{
6120 tsap_Config_t *pConfig;
6121 beacon_data_t *pBeacon = NULL;
6122 struct ieee80211_mgmt *pMgmt_frame;
6123 v_U8_t *pIe=NULL;
6124 v_U16_t capab_info;
6125 eCsrAuthType RSNAuthType;
6126 eCsrEncryptionType RSNEncryptType;
6127 eCsrEncryptionType mcRSNEncryptType;
6128 int status = VOS_STATUS_SUCCESS;
6129 tpWLAN_SAPEventCB pSapEventCallback;
6130 hdd_hostapd_state_t *pHostapdState;
6131 v_U8_t wpaRsnIEdata[(SIR_MAC_MAX_IE_LENGTH * 2)+4]; //Max ie length 255 * 2(WPA+RSN) + 2 bytes (vendor specific ID) * 2
6132 v_CONTEXT_t pVosContext = (WLAN_HDD_GET_CTX(pHostapdAdapter))->pvosContext;
Madan Mohan Koyylamudia16d0202013-02-01 11:05:57 +05306133 tHalHandle hHal = WLAN_HDD_GET_HAL_CTX(pHostapdAdapter);
Jeff Johnson295189b2012-06-20 16:38:30 -07006134 struct qc_mac_acl_entry *acl_entry = NULL;
Siddharth Bhal5cba24e2014-05-08 18:59:39 +05306135 hdd_config_t *iniConfig;
Jeff Johnson295189b2012-06-20 16:38:30 -07006136 v_SINT_t i;
Madan Mohan Koyyalamudi543172b2012-12-05 16:40:18 -08006137 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pHostapdAdapter);
Peng Xu2446a892014-09-05 17:21:18 +05306138 tSmeConfigParams *psmeConfig;
Chet Lanctot40142442014-05-20 13:39:25 -07006139 v_BOOL_t MFPCapable = VOS_FALSE;
6140 v_BOOL_t MFPRequired = VOS_FALSE;
Abhishek Singhf0ac1752014-03-05 17:47:09 +05306141 eHddDot11Mode sapDot11Mode =
6142 (WLAN_HDD_GET_CTX(pHostapdAdapter))->cfg_ini->sapDot11Mode;
Jeff Johnson295189b2012-06-20 16:38:30 -07006143
6144 ENTER();
6145
Siddharth Bhal5cba24e2014-05-08 18:59:39 +05306146 iniConfig = pHddCtx->cfg_ini;
6147
Jeff Johnson295189b2012-06-20 16:38:30 -07006148 pHostapdState = WLAN_HDD_GET_HOSTAP_STATE_PTR(pHostapdAdapter);
6149
6150 pConfig = &pHostapdAdapter->sessionCtx.ap.sapConfig;
6151
6152 pBeacon = pHostapdAdapter->sessionCtx.ap.beacon;
6153
6154 pMgmt_frame = (struct ieee80211_mgmt*)pBeacon->head;
6155
6156 pConfig->beacon_int = pMgmt_frame->u.beacon.beacon_int;
6157
6158 //channel is already set in the set_channel Call back
6159 //pConfig->channel = pCommitConfig->channel;
6160
6161 /*Protection parameter to enable or disable*/
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306162 pConfig->protEnabled =
Jeff Johnson295189b2012-06-20 16:38:30 -07006163 (WLAN_HDD_GET_CTX(pHostapdAdapter))->cfg_ini->apProtEnabled;
6164
6165 pConfig->dtim_period = pBeacon->dtim_period;
6166
Arif Hussain6d2a3322013-11-17 19:50:10 -08006167 hddLog(VOS_TRACE_LEVEL_INFO_HIGH,"****pConfig->dtim_period=%d***",
Jeff Johnson295189b2012-06-20 16:38:30 -07006168 pConfig->dtim_period);
6169
Madan Mohan Koyyalamudie0ca11f2012-11-27 15:57:52 -08006170 if (pHostapdAdapter->device_mode == WLAN_HDD_SOFTAP)
Jeff Johnson32d95a32012-09-10 13:15:23 -07006171 {
6172 pIe = wlan_hdd_cfg80211_get_ie_ptr(pBeacon->tail, pBeacon->tail_len,
Jeff Johnson295189b2012-06-20 16:38:30 -07006173 WLAN_EID_COUNTRY);
Kiet Lam083504c2013-11-25 14:17:45 +05306174 if(memcmp(pHddCtx->cfg_ini->apCntryCode, CFG_AP_COUNTRY_CODE_DEFAULT, 3) != 0)
6175 {
6176 tANI_BOOLEAN restartNeeded;
6177 pConfig->ieee80211d = 1;
6178 vos_mem_copy(pConfig->countryCode, pHddCtx->cfg_ini->apCntryCode, 3);
6179 sme_setRegInfo(hHal, pConfig->countryCode);
6180 sme_ResetCountryCodeInformation(hHal, &restartNeeded);
6181 }
6182 else if(pIe)
Jeff Johnson295189b2012-06-20 16:38:30 -07006183 {
Jeff Johnson32d95a32012-09-10 13:15:23 -07006184 tANI_BOOLEAN restartNeeded;
Jeff Johnson32d95a32012-09-10 13:15:23 -07006185 pConfig->ieee80211d = 1;
6186 vos_mem_copy(pConfig->countryCode, &pIe[2], 3);
6187 sme_setRegInfo(hHal, pConfig->countryCode);
6188 sme_ResetCountryCodeInformation(hHal, &restartNeeded);
Jeff Johnson295189b2012-06-20 16:38:30 -07006189 }
Jeff Johnson32d95a32012-09-10 13:15:23 -07006190 else
6191 {
6192 pConfig->ieee80211d = 0;
6193 }
Madan Mohan Koyylamudia16d0202013-02-01 11:05:57 +05306194 /*
6195 * If auto channel is configured i.e. channel is 0,
6196 * so skip channel validation.
6197 */
6198 if( AUTO_CHANNEL_SELECT != pConfig->channel )
6199 {
6200 if(VOS_STATUS_SUCCESS != wlan_hdd_validate_operation_channel(pHostapdAdapter,pConfig->channel))
6201 {
6202 hddLog(VOS_TRACE_LEVEL_ERROR,
Arif Hussain6d2a3322013-11-17 19:50:10 -08006203 "%s: Invalid Channel [%d]", __func__, pConfig->channel);
Madan Mohan Koyylamudia16d0202013-02-01 11:05:57 +05306204 return -EINVAL;
6205 }
6206 }
6207 else
6208 {
6209 if(1 != pHddCtx->is_dynamic_channel_range_set)
6210 {
6211 hdd_config_t *hdd_pConfig= (WLAN_HDD_GET_CTX(pHostapdAdapter))->cfg_ini;
6212 WLANSAP_SetChannelRange(hHal, hdd_pConfig->apStartChannelNum,
6213 hdd_pConfig->apEndChannelNum,hdd_pConfig->apOperatingBand);
6214 }
6215 pHddCtx->is_dynamic_channel_range_set = 0;
6216 }
Jeff Johnson295189b2012-06-20 16:38:30 -07006217 }
Jeff Johnson32d95a32012-09-10 13:15:23 -07006218 else
Jeff Johnson295189b2012-06-20 16:38:30 -07006219 {
6220 pConfig->ieee80211d = 0;
6221 }
6222 pConfig->authType = eSAP_AUTO_SWITCH;
6223
6224 capab_info = pMgmt_frame->u.beacon.capab_info;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306225
6226 pConfig->privacy = (pMgmt_frame->u.beacon.capab_info &
Jeff Johnson295189b2012-06-20 16:38:30 -07006227 WLAN_CAPABILITY_PRIVACY) ? VOS_TRUE : VOS_FALSE;
6228
6229 (WLAN_HDD_GET_AP_CTX_PTR(pHostapdAdapter))->uPrivacy = pConfig->privacy;
6230
6231 /*Set wps station to configured*/
6232 pIe = wlan_hdd_get_wps_ie_ptr(pBeacon->tail, pBeacon->tail_len);
6233
6234 if(pIe)
6235 {
6236 if(pIe[1] < (2 + WPS_OUI_TYPE_SIZE))
6237 {
Arif Hussain6d2a3322013-11-17 19:50:10 -08006238 hddLog( VOS_TRACE_LEVEL_ERROR, "**Wps Ie Length is too small***");
Jeff Johnson295189b2012-06-20 16:38:30 -07006239 return -EINVAL;
6240 }
6241 else if(memcmp(&pIe[2], WPS_OUI_TYPE, WPS_OUI_TYPE_SIZE) == 0)
6242 {
Madan Mohan Koyyalamudi8bdd3112012-09-24 13:55:14 -07006243 hddLog( VOS_TRACE_LEVEL_INFO, "** WPS IE(len %d) ***", (pIe[1]+2));
Jeff Johnson295189b2012-06-20 16:38:30 -07006244 /* Check 15 bit of WPS IE as it contain information for wps state
6245 * WPS state
6246 */
6247 if(SAP_WPS_ENABLED_UNCONFIGURED == pIe[15])
6248 {
6249 pConfig->wps_state = SAP_WPS_ENABLED_UNCONFIGURED;
6250 } else if(SAP_WPS_ENABLED_CONFIGURED == pIe[15])
6251 {
6252 pConfig->wps_state = SAP_WPS_ENABLED_CONFIGURED;
6253 }
6254 }
6255 }
6256 else
6257 {
6258 pConfig->wps_state = SAP_WPS_DISABLED;
6259 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306260 pConfig->fwdWPSPBCProbeReq = 1; // Forward WPS PBC probe request frame up
Jeff Johnson295189b2012-06-20 16:38:30 -07006261
c_hpothufe599e92014-06-16 11:38:55 +05306262 pConfig->RSNEncryptType = eCSR_ENCRYPT_TYPE_NONE;
6263 pConfig->mcRSNEncryptType = eCSR_ENCRYPT_TYPE_NONE;
6264 (WLAN_HDD_GET_AP_CTX_PTR(pHostapdAdapter))->ucEncryptType =
6265 eCSR_ENCRYPT_TYPE_NONE;
6266
Jeff Johnson295189b2012-06-20 16:38:30 -07006267 pConfig->RSNWPAReqIELength = 0;
6268 pConfig->pRSNWPAReqIE = NULL;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306269 pIe = wlan_hdd_cfg80211_get_ie_ptr(pBeacon->tail, pBeacon->tail_len,
Jeff Johnson295189b2012-06-20 16:38:30 -07006270 WLAN_EID_RSN);
6271 if(pIe && pIe[1])
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306272 {
Jeff Johnson295189b2012-06-20 16:38:30 -07006273 pConfig->RSNWPAReqIELength = pIe[1] + 2;
6274 memcpy(&wpaRsnIEdata[0], pIe, pConfig->RSNWPAReqIELength);
6275 pConfig->pRSNWPAReqIE = &wpaRsnIEdata[0];
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306276 /* The actual processing may eventually be more extensive than
6277 * this. Right now, just consume any PMKIDs that are sent in
Jeff Johnson295189b2012-06-20 16:38:30 -07006278 * by the app.
6279 * */
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306280 status = hdd_softap_unpackIE(
Jeff Johnson295189b2012-06-20 16:38:30 -07006281 vos_get_context( VOS_MODULE_ID_SME, pVosContext),
6282 &RSNEncryptType,
6283 &mcRSNEncryptType,
6284 &RSNAuthType,
Chet Lanctot8cecea22014-02-11 19:09:36 -08006285 &MFPCapable,
6286 &MFPRequired,
Jeff Johnson295189b2012-06-20 16:38:30 -07006287 pConfig->pRSNWPAReqIE[1]+2,
6288 pConfig->pRSNWPAReqIE );
6289
6290 if( VOS_STATUS_SUCCESS == status )
6291 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306292 /* Now copy over all the security attributes you have
6293 * parsed out
Jeff Johnson295189b2012-06-20 16:38:30 -07006294 * */
6295 pConfig->RSNEncryptType = RSNEncryptType; // Use the cipher type in the RSN IE
6296 pConfig->mcRSNEncryptType = mcRSNEncryptType;
6297 (WLAN_HDD_GET_AP_CTX_PTR(pHostapdAdapter))->ucEncryptType
6298 = RSNEncryptType;
Gopichand Nakkala66c0bd02013-04-10 11:36:29 +05306299 hddLog( LOG1, FL("CSR AuthType = %d, "
Arif Hussain6d2a3322013-11-17 19:50:10 -08006300 "EncryptionType = %d mcEncryptionType = %d"),
Jeff Johnson295189b2012-06-20 16:38:30 -07006301 RSNAuthType, RSNEncryptType, mcRSNEncryptType);
6302 }
6303 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306304
Jeff Johnson295189b2012-06-20 16:38:30 -07006305 pIe = wlan_hdd_get_vendor_oui_ie_ptr(WPA_OUI_TYPE, WPA_OUI_TYPE_SIZE,
6306 pBeacon->tail, pBeacon->tail_len);
6307
6308 if(pIe && pIe[1] && (pIe[0] == DOT11F_EID_WPA))
6309 {
6310 if (pConfig->pRSNWPAReqIE)
6311 {
6312 /*Mixed mode WPA/WPA2*/
6313 memcpy((&wpaRsnIEdata[0] + pConfig->RSNWPAReqIELength), pIe, pIe[1] + 2);
6314 pConfig->RSNWPAReqIELength += pIe[1] + 2;
6315 }
6316 else
6317 {
6318 pConfig->RSNWPAReqIELength = pIe[1] + 2;
6319 memcpy(&wpaRsnIEdata[0], pIe, pConfig->RSNWPAReqIELength);
6320 pConfig->pRSNWPAReqIE = &wpaRsnIEdata[0];
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306321 status = hdd_softap_unpackIE(
Jeff Johnson295189b2012-06-20 16:38:30 -07006322 vos_get_context( VOS_MODULE_ID_SME, pVosContext),
6323 &RSNEncryptType,
6324 &mcRSNEncryptType,
6325 &RSNAuthType,
Chet Lanctot8cecea22014-02-11 19:09:36 -08006326 &MFPCapable,
6327 &MFPRequired,
Jeff Johnson295189b2012-06-20 16:38:30 -07006328 pConfig->pRSNWPAReqIE[1]+2,
6329 pConfig->pRSNWPAReqIE );
6330
6331 if( VOS_STATUS_SUCCESS == status )
6332 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306333 /* Now copy over all the security attributes you have
6334 * parsed out
Jeff Johnson295189b2012-06-20 16:38:30 -07006335 * */
6336 pConfig->RSNEncryptType = RSNEncryptType; // Use the cipher type in the RSN IE
6337 pConfig->mcRSNEncryptType = mcRSNEncryptType;
6338 (WLAN_HDD_GET_AP_CTX_PTR(pHostapdAdapter))->ucEncryptType
6339 = RSNEncryptType;
Gopichand Nakkala66c0bd02013-04-10 11:36:29 +05306340 hddLog( LOG1, FL("CSR AuthType = %d, "
Arif Hussain6d2a3322013-11-17 19:50:10 -08006341 "EncryptionType = %d mcEncryptionType = %d"),
Jeff Johnson295189b2012-06-20 16:38:30 -07006342 RSNAuthType, RSNEncryptType, mcRSNEncryptType);
6343 }
6344 }
6345 }
6346
Jeff Johnson4416a782013-03-25 14:17:50 -07006347 if (pConfig->RSNWPAReqIELength > sizeof wpaRsnIEdata) {
6348 hddLog( VOS_TRACE_LEVEL_ERROR, "**RSNWPAReqIELength is too large***");
6349 return -EINVAL;
6350 }
6351
Jeff Johnson295189b2012-06-20 16:38:30 -07006352 pConfig->SSIDinfo.ssidHidden = VOS_FALSE;
6353
Jeff Johnson04dd8a82012-06-29 20:41:40 -07006354#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,4,0))
Jeff Johnson295189b2012-06-20 16:38:30 -07006355 if (params->ssid != NULL)
6356 {
6357 memcpy(pConfig->SSIDinfo.ssid.ssId, params->ssid, params->ssid_len);
6358 pConfig->SSIDinfo.ssid.length = params->ssid_len;
6359 if (params->hidden_ssid != NL80211_HIDDEN_SSID_NOT_IN_USE)
6360 pConfig->SSIDinfo.ssidHidden = VOS_TRUE;
6361 }
Jeff Johnson04dd8a82012-06-29 20:41:40 -07006362#else
6363 if (ssid != NULL)
6364 {
6365 memcpy(pConfig->SSIDinfo.ssid.ssId, ssid, ssid_len);
6366 pConfig->SSIDinfo.ssid.length = ssid_len;
6367 if (hidden_ssid != NL80211_HIDDEN_SSID_NOT_IN_USE)
6368 pConfig->SSIDinfo.ssidHidden = VOS_TRUE;
6369 }
6370#endif
6371
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306372 vos_mem_copy(pConfig->self_macaddr.bytes,
Jeff Johnson295189b2012-06-20 16:38:30 -07006373 pHostapdAdapter->macAddressCurrent.bytes, sizeof(v_MACADDR_t));
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306374
Jeff Johnson295189b2012-06-20 16:38:30 -07006375 /* default value */
6376 pConfig->SapMacaddr_acl = eSAP_ACCEPT_UNLESS_DENIED;
6377 pConfig->num_accept_mac = 0;
6378 pConfig->num_deny_mac = 0;
6379
6380 pIe = wlan_hdd_get_vendor_oui_ie_ptr(BLACKLIST_OUI_TYPE, WPA_OUI_TYPE_SIZE,
6381 pBeacon->tail, pBeacon->tail_len);
6382
6383 /* pIe for black list is following form:
6384 type : 1 byte
6385 length : 1 byte
6386 OUI : 4 bytes
6387 acl type : 1 byte
6388 no of mac addr in black list: 1 byte
6389 list of mac_acl_entries: variable, 6 bytes per mac address + sizeof(int) for vlan id
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306390 */
6391 if ((pIe != NULL) && (pIe[1] != 0))
Jeff Johnson295189b2012-06-20 16:38:30 -07006392 {
6393 pConfig->SapMacaddr_acl = pIe[6];
6394 pConfig->num_deny_mac = pIe[7];
Arif Hussain6d2a3322013-11-17 19:50:10 -08006395 hddLog(VOS_TRACE_LEVEL_INFO,"acl type = %d no deny mac = %d",
Jeff Johnson295189b2012-06-20 16:38:30 -07006396 pIe[6], pIe[7]);
Gopichand Nakkalac005b7c2013-05-14 16:04:14 +05306397 if (pConfig->num_deny_mac > MAX_ACL_MAC_ADDRESS)
6398 pConfig->num_deny_mac = MAX_ACL_MAC_ADDRESS;
Jeff Johnson295189b2012-06-20 16:38:30 -07006399 acl_entry = (struct qc_mac_acl_entry *)(pIe + 8);
6400 for (i = 0; i < pConfig->num_deny_mac; i++)
6401 {
6402 vos_mem_copy(&pConfig->deny_mac[i], acl_entry->addr, sizeof(qcmacaddr));
6403 acl_entry++;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306404 }
Jeff Johnson295189b2012-06-20 16:38:30 -07006405 }
6406 pIe = wlan_hdd_get_vendor_oui_ie_ptr(WHITELIST_OUI_TYPE, WPA_OUI_TYPE_SIZE,
6407 pBeacon->tail, pBeacon->tail_len);
6408
6409 /* pIe for white list is following form:
6410 type : 1 byte
6411 length : 1 byte
6412 OUI : 4 bytes
6413 acl type : 1 byte
6414 no of mac addr in white list: 1 byte
6415 list of mac_acl_entries: variable, 6 bytes per mac address + sizeof(int) for vlan id
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306416 */
6417 if ((pIe != NULL) && (pIe[1] != 0))
Jeff Johnson295189b2012-06-20 16:38:30 -07006418 {
6419 pConfig->SapMacaddr_acl = pIe[6];
6420 pConfig->num_accept_mac = pIe[7];
Arif Hussain6d2a3322013-11-17 19:50:10 -08006421 hddLog(VOS_TRACE_LEVEL_INFO,"acl type = %d no accept mac = %d",
Jeff Johnson295189b2012-06-20 16:38:30 -07006422 pIe[6], pIe[7]);
Gopichand Nakkalac005b7c2013-05-14 16:04:14 +05306423 if (pConfig->num_accept_mac > MAX_ACL_MAC_ADDRESS)
6424 pConfig->num_accept_mac = MAX_ACL_MAC_ADDRESS;
Jeff Johnson295189b2012-06-20 16:38:30 -07006425 acl_entry = (struct qc_mac_acl_entry *)(pIe + 8);
6426 for (i = 0; i < pConfig->num_accept_mac; i++)
6427 {
6428 vos_mem_copy(&pConfig->accept_mac[i], acl_entry->addr, sizeof(qcmacaddr));
6429 acl_entry++;
6430 }
6431 }
Gopichand Nakkalac005b7c2013-05-14 16:04:14 +05306432
Jeff Johnson295189b2012-06-20 16:38:30 -07006433 wlan_hdd_set_sapHwmode(pHostapdAdapter);
6434
Jeff Johnsone7245742012-09-05 17:12:55 -07006435#ifdef WLAN_FEATURE_11AC
Ravi Kumar Vaishnavbbaebbe2013-01-15 17:09:48 -08006436 /* Overwrite the hostapd setting for HW mode only for 11ac.
Kiet Lam0f320422013-11-21 19:29:17 +05306437 * This is valid only if mode is set to 11n in hostapd, either AUTO or
6438 * 11ac in .ini and 11ac is supported by both host and firmware.
6439 * Otherwise, leave whatever is set in hostapd (a OR b OR g OR n mode)
6440 */
Ravi Kumar Vaishnavbbaebbe2013-01-15 17:09:48 -08006441 if( ((pConfig->SapHw_mode == eSAP_DOT11_MODE_11n) ||
6442 (pConfig->SapHw_mode == eSAP_DOT11_MODE_11n_ONLY)) &&
Abhishek Singhf0ac1752014-03-05 17:47:09 +05306443 (( sapDot11Mode == eHDD_DOT11_MODE_AUTO ) ||
6444 ( sapDot11Mode == eHDD_DOT11_MODE_11ac ) ||
6445 ( sapDot11Mode == eHDD_DOT11_MODE_11ac_ONLY ) ) &&
6446 (sme_IsFeatureSupportedByDriver(DOT11AC)) &&
6447 (sme_IsFeatureSupportedByFW(DOT11AC)) )
Jeff Johnsone7245742012-09-05 17:12:55 -07006448 {
Siddharth Bhalf42f8592014-05-15 13:39:07 +05306449 v_U32_t operatingBand = 0;
Jeff Johnsone7245742012-09-05 17:12:55 -07006450 pConfig->SapHw_mode = eSAP_DOT11_MODE_11ac;
Siddharth Bhalf42f8592014-05-15 13:39:07 +05306451 ccmCfgGetInt(hHal, WNI_CFG_SAP_CHANNEL_SELECT_OPERATING_BAND, &operatingBand);
Ravi Joshi83bfaa12013-05-28 22:12:08 -07006452
Siddharth Bhal5cba24e2014-05-08 18:59:39 +05306453 /* If ACS disable and selected channel <= 14
6454 * OR
6455 * ACS enabled and ACS operating band is choosen as 2.4
6456 * AND
6457 * VHT in 2.4G Disabled
6458 * THEN
6459 * Fallback to 11N mode
6460 */
6461 if (((AUTO_CHANNEL_SELECT != pConfig->channel && pConfig->channel <= SIR_11B_CHANNEL_END)
6462 || (AUTO_CHANNEL_SELECT == pConfig->channel &&
Deepthi Gowri7db41f32014-10-13 17:02:29 +05306463 operatingBand == eSAP_RF_SUBBAND_2_4_GHZ)) &&
Siddharth Bhal5cba24e2014-05-08 18:59:39 +05306464 iniConfig->enableVhtFor24GHzBand == FALSE)
Ravi Joshi83bfaa12013-05-28 22:12:08 -07006465 {
Siddharth Bhalf42f8592014-05-15 13:39:07 +05306466 hddLog(LOGW, FL("Setting hwmode to 11n, operatingBand = %d, Channel = %d"),
6467 operatingBand, pConfig->channel);
Ravi Joshi83bfaa12013-05-28 22:12:08 -07006468 pConfig->SapHw_mode = eSAP_DOT11_MODE_11n;
6469 }
Jeff Johnsone7245742012-09-05 17:12:55 -07006470 }
6471#endif
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306472
Ravi Joshiaeb7d9e2013-05-02 12:28:14 -07006473 if ( AUTO_CHANNEL_SELECT != pConfig->channel )
6474 {
6475 sme_SelectCBMode(hHal,
6476 sapConvertSapPhyModeToCsrPhyMode(pConfig->SapHw_mode),
6477 pConfig->channel);
6478 }
Jeff Johnson295189b2012-06-20 16:38:30 -07006479 // ht_capab is not what the name conveys,this is used for protection bitmap
6480 pConfig->ht_capab =
6481 (WLAN_HDD_GET_CTX(pHostapdAdapter))->cfg_ini->apProtection;
6482
6483 if ( 0 != wlan_hdd_cfg80211_update_apies(pHostapdAdapter, params) )
6484 {
6485 hddLog(LOGE, FL("SAP Not able to set AP IEs"));
6486 return -EINVAL;
6487 }
6488
6489 //Uapsd Enabled Bit
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306490 pConfig->UapsdEnable =
Jeff Johnson295189b2012-06-20 16:38:30 -07006491 (WLAN_HDD_GET_CTX(pHostapdAdapter))->cfg_ini->apUapsdEnabled;
6492 //Enable OBSS protection
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306493 pConfig->obssProtEnabled =
6494 (WLAN_HDD_GET_CTX(pHostapdAdapter))->cfg_ini->apOBSSProtEnabled;
Jeff Johnson295189b2012-06-20 16:38:30 -07006495
Chet Lanctot8cecea22014-02-11 19:09:36 -08006496#ifdef WLAN_FEATURE_11W
6497 pConfig->mfpCapable = MFPCapable;
6498 pConfig->mfpRequired = MFPRequired;
6499 hddLog(LOGW, FL("Soft AP MFP capable %d, MFP required %d\n"),
6500 pConfig->mfpCapable, pConfig->mfpRequired);
6501#endif
6502
Arif Hussain6d2a3322013-11-17 19:50:10 -08006503 hddLog(LOGW, FL("SOftAP macaddress : "MAC_ADDRESS_STR),
Jeff Johnson295189b2012-06-20 16:38:30 -07006504 MAC_ADDR_ARRAY(pHostapdAdapter->macAddressCurrent.bytes));
Arif Hussain6d2a3322013-11-17 19:50:10 -08006505 hddLog(LOGW,FL("ssid =%s, beaconint=%d, channel=%d"),
6506 pConfig->SSIDinfo.ssid.ssId, (int)pConfig->beacon_int,
6507 (int)pConfig->channel);
6508 hddLog(LOGW,FL("hw_mode=%x, privacy=%d, authType=%d"),
6509 pConfig->SapHw_mode, pConfig->privacy,
6510 pConfig->authType);
6511 hddLog(LOGW,FL("RSN/WPALen=%d, Uapsd = %d"),
6512 (int)pConfig->RSNWPAReqIELength, pConfig->UapsdEnable);
6513 hddLog(LOGW,FL("ProtEnabled = %d, OBSSProtEnabled = %d"),
6514 pConfig->protEnabled, pConfig->obssProtEnabled);
Jeff Johnson295189b2012-06-20 16:38:30 -07006515
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306516 if(test_bit(SOFTAP_BSS_STARTED, &pHostapdAdapter->event_flags))
Jeff Johnson295189b2012-06-20 16:38:30 -07006517 {
6518 //Bss already started. just return.
6519 //TODO Probably it should update some beacon params.
6520 hddLog( LOGE, "Bss Already started...Ignore the request");
6521 EXIT();
6522 return 0;
6523 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306524
Agarwal Ashish51325b52014-06-16 16:50:49 +05306525 if (vos_max_concurrent_connections_reached()) {
6526 hddLog(VOS_TRACE_LEVEL_INFO, FL("Reached max concurrent connections"));
6527 return -EINVAL;
6528 }
6529
Jeff Johnson295189b2012-06-20 16:38:30 -07006530 pConfig->persona = pHostapdAdapter->device_mode;
6531
Peng Xu2446a892014-09-05 17:21:18 +05306532 psmeConfig = (tSmeConfigParams*) vos_mem_malloc(sizeof(tSmeConfigParams));
6533 if ( NULL != psmeConfig)
6534 {
6535 sme_GetConfigParam(hHal, psmeConfig);
6536 pConfig->scanBandPreference = psmeConfig->csrConfig.scanBandPreference;
6537 vos_mem_free(psmeConfig);
6538 }
Peng Xuafc34e32014-09-25 13:23:55 +05306539 pConfig->acsBandSwitchThreshold = iniConfig->acsBandSwitchThreshold;
Peng Xu2446a892014-09-05 17:21:18 +05306540
Jeff Johnson295189b2012-06-20 16:38:30 -07006541 pSapEventCallback = hdd_hostapd_SAPEventCB;
6542 if(WLANSAP_StartBss(pVosContext, pSapEventCallback, pConfig,
6543 (v_PVOID_t)pHostapdAdapter->dev) != VOS_STATUS_SUCCESS)
6544 {
Arif Hussain6d2a3322013-11-17 19:50:10 -08006545 hddLog(LOGE,FL("SAP Start Bss fail"));
Jeff Johnson295189b2012-06-20 16:38:30 -07006546 return -EINVAL;
6547 }
6548
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306549 hddLog(LOG1,
Jeff Johnson295189b2012-06-20 16:38:30 -07006550 FL("Waiting for Scan to complete(auto mode) and BSS to start"));
6551
6552 status = vos_wait_single_event(&pHostapdState->vosEvent, 10000);
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306553
Jeff Johnson295189b2012-06-20 16:38:30 -07006554 if (!VOS_IS_STATUS_SUCCESS(status))
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306555 {
6556 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Arif Hussain6d2a3322013-11-17 19:50:10 -08006557 ("ERROR: HDD vos wait for single_event failed!!"));
Tushnim Bhattacharyyaad37df12013-10-02 12:01:33 -07006558 smeGetCommandQStatus(hHal);
Jeff Johnson295189b2012-06-20 16:38:30 -07006559 VOS_ASSERT(0);
6560 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306561
Jeff Johnson295189b2012-06-20 16:38:30 -07006562 set_bit(SOFTAP_BSS_STARTED, &pHostapdAdapter->event_flags);
Kaushik, Sushantf6070802014-10-15 15:09:23 +05306563 /* Initialize WMM configuation */
6564 hdd_wmm_init(pHostapdAdapter);
Agarwal Ashish51325b52014-06-16 16:50:49 +05306565 wlan_hdd_incr_active_session(pHddCtx, pHostapdAdapter->device_mode);
Jeff Johnson295189b2012-06-20 16:38:30 -07006566
Madan Mohan Koyyalamudi26bd7142012-10-30 18:14:19 -07006567#ifdef WLAN_FEATURE_P2P_DEBUG
6568 if (pHostapdAdapter->device_mode == WLAN_HDD_P2P_GO)
6569 {
6570 if(globalP2PConnectionStatus == P2P_GO_NEG_COMPLETED)
6571 {
6572 globalP2PConnectionStatus = P2P_GO_COMPLETED_STATE;
6573 hddLog(LOGE,"[P2P State] From Go nego completed to "
Jeff Johnson1250df42012-12-10 14:31:52 -08006574 "Non-autonomous Group started");
Madan Mohan Koyyalamudi26bd7142012-10-30 18:14:19 -07006575 }
6576 else if(globalP2PConnectionStatus == P2P_NOT_ACTIVE)
6577 {
6578 globalP2PConnectionStatus = P2P_GO_COMPLETED_STATE;
6579 hddLog(LOGE,"[P2P State] From Inactive to "
Jeff Johnson1250df42012-12-10 14:31:52 -08006580 "Autonomous Group started");
Madan Mohan Koyyalamudi26bd7142012-10-30 18:14:19 -07006581 }
6582 }
6583#endif
6584
Jeff Johnson295189b2012-06-20 16:38:30 -07006585 pHostapdState->bCommit = TRUE;
6586 EXIT();
6587
6588 return 0;
6589}
6590
Jeff Johnson04dd8a82012-06-29 20:41:40 -07006591#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,4,0))
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306592static int wlan_hdd_cfg80211_add_beacon(struct wiphy *wiphy,
6593 struct net_device *dev,
Jeff Johnson295189b2012-06-20 16:38:30 -07006594 struct beacon_parameters *params)
6595{
6596 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +05306597 hdd_context_t *pHddCtx;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05306598 int status;
Jeff Johnson295189b2012-06-20 16:38:30 -07006599
6600 ENTER();
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +05306601
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05306602 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
6603 TRACE_CODE_HDD_CFG80211_ADD_BEACON,
6604 pAdapter->sessionId, params->interval));
Sushant Kaushik8bc7df22014-04-09 17:55:29 +05306605 hddLog(VOS_TRACE_LEVEL_INFO_HIGH, "device mode=%s (%d)",
6606 hdd_device_modetoString(pAdapter->device_mode),
6607 pAdapter->device_mode);
Jeff Johnson295189b2012-06-20 16:38:30 -07006608
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05306609 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
6610 status = wlan_hdd_validate_context(pHddCtx);
6611
6612 if (0 != status)
Jeff Johnson04dd8a82012-06-29 20:41:40 -07006613 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05306614 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
6615 "%s: HDD context is not valid", __func__);
6616 return status;
Jeff Johnson04dd8a82012-06-29 20:41:40 -07006617 }
6618
Agarwal Ashish51325b52014-06-16 16:50:49 +05306619 if (vos_max_concurrent_connections_reached()) {
6620 hddLog(VOS_TRACE_LEVEL_INFO, FL("Reached max concurrent connections"));
6621 return -EINVAL;
6622 }
6623
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306624 if ( (pAdapter->device_mode == WLAN_HDD_SOFTAP)
Jeff Johnson295189b2012-06-20 16:38:30 -07006625 || (pAdapter->device_mode == WLAN_HDD_P2P_GO)
Jeff Johnson295189b2012-06-20 16:38:30 -07006626 )
6627 {
6628 beacon_data_t *old,*new;
6629
6630 old = pAdapter->sessionCtx.ap.beacon;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306631
Jeff Johnson295189b2012-06-20 16:38:30 -07006632 if (old)
c_hpothu6ff1c3c2013-10-01 19:01:57 +05306633 {
6634 hddLog(VOS_TRACE_LEVEL_WARN,
6635 FL("already beacon info added to session(%d)"),
6636 pAdapter->sessionId);
Jeff Johnson295189b2012-06-20 16:38:30 -07006637 return -EALREADY;
c_hpothu6ff1c3c2013-10-01 19:01:57 +05306638 }
Jeff Johnson295189b2012-06-20 16:38:30 -07006639
6640 status = wlan_hdd_cfg80211_alloc_new_beacon(pAdapter,&new,params);
6641
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306642 if(status != VOS_STATUS_SUCCESS)
Jeff Johnson295189b2012-06-20 16:38:30 -07006643 {
6644 hddLog(VOS_TRACE_LEVEL_FATAL,
Arif Hussain6d2a3322013-11-17 19:50:10 -08006645 "%s:Error!!! Allocating the new beacon",__func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07006646 return -EINVAL;
6647 }
6648
6649 pAdapter->sessionCtx.ap.beacon = new;
6650
6651 status = wlan_hdd_cfg80211_start_bss(pAdapter, params);
6652 }
6653
6654 EXIT();
6655 return status;
6656}
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306657
6658static int wlan_hdd_cfg80211_set_beacon(struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -07006659 struct net_device *dev,
6660 struct beacon_parameters *params)
6661{
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306662 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +05306663 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
6664 hdd_context_t *pHddCtx;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05306665 int status;
Jeff Johnson295189b2012-06-20 16:38:30 -07006666
6667 ENTER();
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +05306668 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
6669 TRACE_CODE_HDD_CFG80211_SET_BEACON,
6670 pAdapter->sessionId, pHddStaCtx->conn_info.authType));
6671 hddLog(VOS_TRACE_LEVEL_INFO, "%s: device_mode = %s (%d)",
6672 __func__, hdd_device_modetoString(pAdapter->device_mode),
6673 pAdapter->device_mode);
6674
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05306675 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
6676 status = wlan_hdd_validate_context(pHddCtx);
6677
6678 if (0 != status)
Jeff Johnson04dd8a82012-06-29 20:41:40 -07006679 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05306680 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
6681 "%s: HDD context is not valid", __func__);
6682 return status;
Jeff Johnson04dd8a82012-06-29 20:41:40 -07006683 }
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +05306684
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306685 if ((pAdapter->device_mode == WLAN_HDD_SOFTAP)
Jeff Johnson295189b2012-06-20 16:38:30 -07006686 || (pAdapter->device_mode == WLAN_HDD_P2P_GO)
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306687 )
Jeff Johnson295189b2012-06-20 16:38:30 -07006688 {
6689 beacon_data_t *old,*new;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306690
Jeff Johnson295189b2012-06-20 16:38:30 -07006691 old = pAdapter->sessionCtx.ap.beacon;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306692
Jeff Johnson295189b2012-06-20 16:38:30 -07006693 if (!old)
c_hpothu6ff1c3c2013-10-01 19:01:57 +05306694 {
6695 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
6696 FL("session(%d) old and new heads points to NULL"),
6697 pAdapter->sessionId);
Jeff Johnson295189b2012-06-20 16:38:30 -07006698 return -ENOENT;
c_hpothu6ff1c3c2013-10-01 19:01:57 +05306699 }
Jeff Johnson295189b2012-06-20 16:38:30 -07006700
6701 status = wlan_hdd_cfg80211_alloc_new_beacon(pAdapter,&new,params);
6702
6703 if(status != VOS_STATUS_SUCCESS) {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306704 hddLog(VOS_TRACE_LEVEL_FATAL,
Arif Hussain6d2a3322013-11-17 19:50:10 -08006705 "%s: Error!!! Allocating the new beacon",__func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07006706 return -EINVAL;
6707 }
6708
6709 pAdapter->sessionCtx.ap.beacon = new;
6710
6711 status = wlan_hdd_cfg80211_start_bss(pAdapter, params);
6712 }
6713
6714 EXIT();
6715 return status;
6716}
6717
Jeff Johnson04dd8a82012-06-29 20:41:40 -07006718#endif //(LINUX_VERSION_CODE < KERNEL_VERSION(3,4,0))
6719
6720#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,4,0))
Jeff Johnson295189b2012-06-20 16:38:30 -07006721static int wlan_hdd_cfg80211_del_beacon(struct wiphy *wiphy,
6722 struct net_device *dev)
Jeff Johnson04dd8a82012-06-29 20:41:40 -07006723#else
6724static int wlan_hdd_cfg80211_stop_ap (struct wiphy *wiphy,
6725 struct net_device *dev)
6726#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07006727{
6728 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
Jeff Johnsone7245742012-09-05 17:12:55 -07006729 hdd_context_t *pHddCtx = NULL;
6730 hdd_scaninfo_t *pScanInfo = NULL;
6731 hdd_adapter_t *staAdapter = NULL;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05306732 VOS_STATUS status;
Mahesh A Saptasagar2395ee62014-05-21 19:12:21 +05306733 long ret;
Jeff Johnson295189b2012-06-20 16:38:30 -07006734
6735 ENTER();
6736
6737 if (NULL == pAdapter)
6738 {
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +05306739 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07006740 "%s: HDD adapter context is Null", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07006741 return -ENODEV;
6742 }
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -07006743
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05306744 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
6745 TRACE_CODE_HDD_CFG80211_STOP_AP,
6746 pAdapter->sessionId, pAdapter->device_mode));
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05306747 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
6748 status = wlan_hdd_validate_context(pHddCtx);
6749
6750 if (0 != status)
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -07006751 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05306752 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
6753 "%s: HDD context is not valid", __func__);
6754 return status;
Jeff Johnson4416a782013-03-25 14:17:50 -07006755 }
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -07006756
6757 staAdapter = hdd_get_adapter(pAdapter->pHddCtx, WLAN_HDD_INFRA_STATION);
6758 if (NULL == staAdapter)
6759 {
6760 staAdapter = hdd_get_adapter(pAdapter->pHddCtx, WLAN_HDD_P2P_CLIENT);
6761 if (NULL == staAdapter)
6762 {
Rajesh Chauhan52d885b2013-11-01 10:54:25 -07006763 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO_HIGH,
6764 "%s: HDD adapter context for STA/P2P-CLI is Null",
6765 __func__);
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -07006766 }
6767 }
6768
6769 pScanInfo = &pHddCtx->scan_info;
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
Mahesh A Saptasagar2395ee62014-05-21 19:12:21 +05306775 ret = wlan_hdd_scan_abort(pAdapter);
6776
Girish Gowli4bf7a632014-06-12 13:42:11 +05306777 if (ret < 0)
Jeff Johnsone7245742012-09-05 17:12:55 -07006778 {
Mahesh A Saptasagar2395ee62014-05-21 19:12:21 +05306779 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
6780 FL("Timeout occurred while waiting for abortscan %ld"), ret);
c_hpothu6ff1c3c2013-10-01 19:01:57 +05306781
Mahesh A Saptasagar2395ee62014-05-21 19:12:21 +05306782 if (pHddCtx->isLogpInProgress)
Jeff Johnsone7245742012-09-05 17:12:55 -07006783 {
Mahesh A Saptasagar2395ee62014-05-21 19:12:21 +05306784 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
6785 "%s: LOGP in Progress. Ignore!!!", __func__);
Yue Ma4f55ef32014-01-23 16:45:33 -08006786
Jeff Johnsone7245742012-09-05 17:12:55 -07006787 VOS_ASSERT(pScanInfo->mScanPending);
Mahesh A Saptasagar2395ee62014-05-21 19:12:21 +05306788 return -EAGAIN;
Jeff Johnsone7245742012-09-05 17:12:55 -07006789 }
Mahesh A Saptasagar2395ee62014-05-21 19:12:21 +05306790 VOS_ASSERT(pScanInfo->mScanPending);
Jeff Johnsone7245742012-09-05 17:12:55 -07006791 }
6792
Rashmi Ramanna1f0948d2014-08-28 15:33:48 +05306793 /* Delete all associated STAs before stopping AP/P2P GO */
6794 hdd_del_all_sta(pAdapter);
Arun Kumar Khandavallia3bd8002014-01-17 16:21:19 +05306795 hdd_hostapd_stop(dev);
6796
Jeff Johnson295189b2012-06-20 16:38:30 -07006797 if ((pAdapter->device_mode == WLAN_HDD_SOFTAP)
Jeff Johnson295189b2012-06-20 16:38:30 -07006798 || (pAdapter->device_mode == WLAN_HDD_P2P_GO)
Jeff Johnson295189b2012-06-20 16:38:30 -07006799 )
6800 {
6801 beacon_data_t *old;
6802
6803 old = pAdapter->sessionCtx.ap.beacon;
6804
6805 if (!old)
c_hpothu6ff1c3c2013-10-01 19:01:57 +05306806 {
6807 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
6808 FL("session(%d) beacon data points to NULL"),
6809 pAdapter->sessionId);
Jeff Johnson295189b2012-06-20 16:38:30 -07006810 return -ENOENT;
c_hpothu6ff1c3c2013-10-01 19:01:57 +05306811 }
Jeff Johnson295189b2012-06-20 16:38:30 -07006812
Jeff Johnson295189b2012-06-20 16:38:30 -07006813 hdd_cleanup_actionframe(pHddCtx, pAdapter);
Jeff Johnson295189b2012-06-20 16:38:30 -07006814
6815 mutex_lock(&pHddCtx->sap_lock);
6816 if(test_bit(SOFTAP_BSS_STARTED, &pAdapter->event_flags))
6817 {
Jeff Johnson4416a782013-03-25 14:17:50 -07006818 if ( VOS_STATUS_SUCCESS == (status = WLANSAP_StopBss(pHddCtx->pvosContext) ) )
Jeff Johnson295189b2012-06-20 16:38:30 -07006819 {
6820 hdd_hostapd_state_t *pHostapdState = WLAN_HDD_GET_HOSTAP_STATE_PTR(pAdapter);
6821
6822 status = vos_wait_single_event(&pHostapdState->vosEvent, 10000);
6823
6824 if (!VOS_IS_STATUS_SUCCESS(status))
6825 {
6826 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Arif Hussain6d2a3322013-11-17 19:50:10 -08006827 ("ERROR: HDD vos wait for single_event failed!!"));
Jeff Johnson295189b2012-06-20 16:38:30 -07006828 VOS_ASSERT(0);
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05306829 }
6830 }
Jeff Johnson295189b2012-06-20 16:38:30 -07006831 clear_bit(SOFTAP_BSS_STARTED, &pAdapter->event_flags);
Agarwal Ashish51325b52014-06-16 16:50:49 +05306832 /* BSS stopped, clear the active sessions for this device mode */
6833 wlan_hdd_decr_active_session(pHddCtx, pAdapter->device_mode);
Jeff Johnson295189b2012-06-20 16:38:30 -07006834 }
6835 mutex_unlock(&pHddCtx->sap_lock);
6836
6837 if(status != VOS_STATUS_SUCCESS)
6838 {
6839 hddLog(VOS_TRACE_LEVEL_FATAL,
Arif Hussain6d2a3322013-11-17 19:50:10 -08006840 "%s:Error!!! Stopping the BSS",__func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07006841 return -EINVAL;
6842 }
6843
Jeff Johnson4416a782013-03-25 14:17:50 -07006844 if (ccmCfgSetInt(pHddCtx->hHal,
Jeff Johnson295189b2012-06-20 16:38:30 -07006845 WNI_CFG_PROBE_RSP_BCN_ADDNIE_FLAG, 0,NULL, eANI_BOOLEAN_FALSE)
6846 ==eHAL_STATUS_FAILURE)
6847 {
6848 hddLog(LOGE,
Arif Hussain6d2a3322013-11-17 19:50:10 -08006849 "Could not pass on WNI_CFG_PROBE_RSP_BCN_ADDNIE_FLAG to CCM");
Jeff Johnson295189b2012-06-20 16:38:30 -07006850 }
6851
Jeff Johnson4416a782013-03-25 14:17:50 -07006852 if ( eHAL_STATUS_FAILURE == ccmCfgSetInt(pHddCtx->hHal,
Jeff Johnson295189b2012-06-20 16:38:30 -07006853 WNI_CFG_ASSOC_RSP_ADDNIE_FLAG, 0, NULL,
6854 eANI_BOOLEAN_FALSE) )
6855 {
6856 hddLog(LOGE,
Arif Hussain6d2a3322013-11-17 19:50:10 -08006857 "Could not pass on WNI_CFG_ASSOC_RSP_ADDNIE_FLAG to CCM");
Jeff Johnson295189b2012-06-20 16:38:30 -07006858 }
6859
6860 // Reset WNI_CFG_PROBE_RSP Flags
6861 wlan_hdd_reset_prob_rspies(pAdapter);
6862
6863 pAdapter->sessionCtx.ap.beacon = NULL;
6864 kfree(old);
Madan Mohan Koyyalamudi26bd7142012-10-30 18:14:19 -07006865#ifdef WLAN_FEATURE_P2P_DEBUG
6866 if((pAdapter->device_mode == WLAN_HDD_P2P_GO) &&
6867 (globalP2PConnectionStatus == P2P_GO_COMPLETED_STATE))
6868 {
6869 hddLog(LOGE,"[P2P State] From GO completed to Inactive state "
6870 "GO got removed");
6871 globalP2PConnectionStatus = P2P_NOT_ACTIVE;
6872 }
6873#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07006874 }
6875 EXIT();
6876 return status;
6877}
Jeff Johnson04dd8a82012-06-29 20:41:40 -07006878
6879#if (LINUX_VERSION_CODE > KERNEL_VERSION(3,3,0))
6880
Pratik Bhalgata0c7f262012-11-22 17:40:24 +05306881static int wlan_hdd_cfg80211_start_ap(struct wiphy *wiphy,
6882 struct net_device *dev,
Jeff Johnson04dd8a82012-06-29 20:41:40 -07006883 struct cfg80211_ap_settings *params)
6884{
Pratik Bhalgata0c7f262012-11-22 17:40:24 +05306885 hdd_adapter_t *pAdapter;
6886 hdd_context_t *pHddCtx;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05306887 int status;
Jeff Johnson04dd8a82012-06-29 20:41:40 -07006888
6889 ENTER();
6890
Pratik Bhalgata0c7f262012-11-22 17:40:24 +05306891 if (NULL == dev)
Madan Mohan Koyyalamudib2c36892012-10-18 20:52:38 -07006892 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05306893 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Pratik Bhalgata0c7f262012-11-22 17:40:24 +05306894 "%s: Device is Null", __func__);
6895 return -ENODEV;
6896 }
6897
6898 pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
6899 if (NULL == pAdapter)
6900 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05306901 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Pratik Bhalgata0c7f262012-11-22 17:40:24 +05306902 "%s: HDD adapter is Null", __func__);
6903 return -ENODEV;
6904 }
6905
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05306906 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
6907 TRACE_CODE_HDD_CFG80211_START_AP, pAdapter->sessionId,
6908 params-> beacon_interval));
Pratik Bhalgata0c7f262012-11-22 17:40:24 +05306909 if (WLAN_HDD_ADAPTER_MAGIC != pAdapter->magic)
6910 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05306911 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Pratik Bhalgata0c7f262012-11-22 17:40:24 +05306912 "%s: HDD adapter magic is invalid", __func__);
6913 return -ENODEV;
6914 }
6915
6916 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05306917 status = wlan_hdd_validate_context(pHddCtx);
Pratik Bhalgata0c7f262012-11-22 17:40:24 +05306918
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05306919 if (0 != status)
Pratik Bhalgata0c7f262012-11-22 17:40:24 +05306920 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05306921 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
6922 "%s: HDD context is not valid", __func__);
6923 return status;
Pratik Bhalgata0c7f262012-11-22 17:40:24 +05306924 }
6925
Sushant Kaushik8bc7df22014-04-09 17:55:29 +05306926 hddLog(VOS_TRACE_LEVEL_INFO_HIGH, "%s: device mode = %s (%d)",
6927 __func__, hdd_device_modetoString(pAdapter->device_mode),
6928 pAdapter->device_mode);
Pratik Bhalgata0c7f262012-11-22 17:40:24 +05306929
6930 if ((pAdapter->device_mode == WLAN_HDD_SOFTAP)
Jeff Johnson04dd8a82012-06-29 20:41:40 -07006931 || (pAdapter->device_mode == WLAN_HDD_P2P_GO)
Jeff Johnson04dd8a82012-06-29 20:41:40 -07006932 )
6933 {
Pratik Bhalgata0c7f262012-11-22 17:40:24 +05306934 beacon_data_t *old, *new;
Jeff Johnson04dd8a82012-06-29 20:41:40 -07006935
6936 old = pAdapter->sessionCtx.ap.beacon;
Pratik Bhalgata0c7f262012-11-22 17:40:24 +05306937
Jeff Johnson04dd8a82012-06-29 20:41:40 -07006938 if (old)
c_hpothu6ff1c3c2013-10-01 19:01:57 +05306939 {
6940 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_WARN,
6941 FL("already beacon info added to session(%d)"),
6942 pAdapter->sessionId);
Jeff Johnson04dd8a82012-06-29 20:41:40 -07006943 return -EALREADY;
c_hpothu6ff1c3c2013-10-01 19:01:57 +05306944 }
Jeff Johnson04dd8a82012-06-29 20:41:40 -07006945
6946 status = wlan_hdd_cfg80211_alloc_new_beacon(pAdapter, &new, &params->beacon, params->dtim_period);
6947
Pratik Bhalgata0c7f262012-11-22 17:40:24 +05306948 if (status != 0)
Jeff Johnson04dd8a82012-06-29 20:41:40 -07006949 {
6950 hddLog(VOS_TRACE_LEVEL_FATAL,
Pratik Bhalgata0c7f262012-11-22 17:40:24 +05306951 "%s:Error!!! Allocating the new beacon", __func__);
Jeff Johnson04dd8a82012-06-29 20:41:40 -07006952 return -EINVAL;
6953 }
6954 pAdapter->sessionCtx.ap.beacon = new;
Viral Modi3a32cc52013-02-08 11:14:52 -08006955#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,6,0))
Yue Maf49ba872013-08-19 12:04:25 -07006956 wlan_hdd_cfg80211_set_channel(wiphy, dev,
6957#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,8,0))
6958 params->channel, params->channel_type);
6959#else
6960 params->chandef.chan, cfg80211_get_chandef_type(&(params->chandef)));
6961#endif
Viral Modi3a32cc52013-02-08 11:14:52 -08006962#endif
Jeff Johnson04dd8a82012-06-29 20:41:40 -07006963 status = wlan_hdd_cfg80211_start_bss(pAdapter, &params->beacon, params->ssid,
6964 params->ssid_len, params->hidden_ssid);
6965 }
6966
6967 EXIT();
6968 return status;
6969}
6970
6971
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306972static int wlan_hdd_cfg80211_change_beacon(struct wiphy *wiphy,
Jeff Johnson04dd8a82012-06-29 20:41:40 -07006973 struct net_device *dev,
6974 struct cfg80211_beacon_data *params)
6975{
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306976 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +05306977 hdd_context_t *pHddCtx;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05306978 int status;
Jeff Johnson04dd8a82012-06-29 20:41:40 -07006979
6980 ENTER();
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +05306981
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05306982 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
6983 TRACE_CODE_HDD_CFG80211_CHANGE_BEACON,
6984 pAdapter->sessionId, pAdapter->device_mode));
Arif Hussain6d2a3322013-11-17 19:50:10 -08006985 hddLog(VOS_TRACE_LEVEL_INFO, "%s: device_mode = %d",
Jeff Johnson04dd8a82012-06-29 20:41:40 -07006986 __func__, pAdapter->device_mode);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05306987
6988 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
6989 status = wlan_hdd_validate_context(pHddCtx);
6990
6991 if (0 != status)
Madan Mohan Koyyalamudib2c36892012-10-18 20:52:38 -07006992 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05306993 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
6994 "%s: HDD context is not valid", __func__);
6995 return status;
Madan Mohan Koyyalamudib2c36892012-10-18 20:52:38 -07006996 }
Jeff Johnson04dd8a82012-06-29 20:41:40 -07006997
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306998 if ((pAdapter->device_mode == WLAN_HDD_SOFTAP)
Jeff Johnson04dd8a82012-06-29 20:41:40 -07006999 || (pAdapter->device_mode == WLAN_HDD_P2P_GO)
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307000 )
Jeff Johnson04dd8a82012-06-29 20:41:40 -07007001 {
7002 beacon_data_t *old,*new;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307003
Jeff Johnson04dd8a82012-06-29 20:41:40 -07007004 old = pAdapter->sessionCtx.ap.beacon;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307005
Jeff Johnson04dd8a82012-06-29 20:41:40 -07007006 if (!old)
c_hpothu6ff1c3c2013-10-01 19:01:57 +05307007 {
7008 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
7009 FL("session(%d) beacon data points to NULL"),
7010 pAdapter->sessionId);
Jeff Johnson04dd8a82012-06-29 20:41:40 -07007011 return -ENOENT;
c_hpothu6ff1c3c2013-10-01 19:01:57 +05307012 }
Jeff Johnson04dd8a82012-06-29 20:41:40 -07007013
7014 status = wlan_hdd_cfg80211_alloc_new_beacon(pAdapter, &new, params, 0);
7015
7016 if(status != VOS_STATUS_SUCCESS) {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307017 hddLog(VOS_TRACE_LEVEL_FATAL,
Arif Hussain6d2a3322013-11-17 19:50:10 -08007018 "%s: Error!!! Allocating the new beacon",__func__);
Jeff Johnson04dd8a82012-06-29 20:41:40 -07007019 return -EINVAL;
7020 }
7021
7022 pAdapter->sessionCtx.ap.beacon = new;
7023
7024 status = wlan_hdd_cfg80211_start_bss(pAdapter, params, NULL, 0, 0);
7025 }
7026
7027 EXIT();
7028 return status;
7029}
7030
7031#endif //(LINUX_VERSION_CODE > KERNEL_VERSION(3,3,0))
7032
Jeff Johnson295189b2012-06-20 16:38:30 -07007033
Mahesh A Saptasagar179d2252014-06-02 21:32:21 +05307034static int __wlan_hdd_cfg80211_change_bss (struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -07007035 struct net_device *dev,
7036 struct bss_parameters *params)
7037{
7038 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
7039
7040 ENTER();
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +05307041
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05307042 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
7043 TRACE_CODE_HDD_CFG80211_CHANGE_BSS,
7044 pAdapter->sessionId, params->ap_isolate));
Sushant Kaushik8bc7df22014-04-09 17:55:29 +05307045 hddLog(VOS_TRACE_LEVEL_INFO, "%s: device_mode = %s (%d)",
7046 __func__, hdd_device_modetoString(pAdapter->device_mode),
7047 pAdapter->device_mode);
Jeff Johnson295189b2012-06-20 16:38:30 -07007048
7049 if((pAdapter->device_mode == WLAN_HDD_SOFTAP)
Jeff Johnson295189b2012-06-20 16:38:30 -07007050 || (pAdapter->device_mode == WLAN_HDD_P2P_GO)
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307051 )
Jeff Johnson295189b2012-06-20 16:38:30 -07007052 {
7053 /* ap_isolate == -1 means that in change bss, upper layer doesn't
7054 * want to update this parameter */
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307055 if (-1 != params->ap_isolate)
Jeff Johnson295189b2012-06-20 16:38:30 -07007056 {
7057 pAdapter->sessionCtx.ap.apDisableIntraBssFwd = !!params->ap_isolate;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307058 }
Jeff Johnson295189b2012-06-20 16:38:30 -07007059 }
7060
7061 EXIT();
7062 return 0;
7063}
7064
Mahesh A Saptasagar179d2252014-06-02 21:32:21 +05307065static int wlan_hdd_cfg80211_change_bss (struct wiphy *wiphy,
7066 struct net_device *dev,
7067 struct bss_parameters *params)
7068{
7069 int ret;
7070
7071 vos_ssr_protect(__func__);
7072 ret = __wlan_hdd_cfg80211_change_bss(wiphy, dev, params);
7073 vos_ssr_unprotect(__func__);
7074
7075 return ret;
7076}
Kiet Lam10841362013-11-01 11:36:50 +05307077/* FUNCTION: wlan_hdd_change_country_code_cd
7078* to wait for contry code completion
7079*/
7080void* wlan_hdd_change_country_code_cb(void *pAdapter)
7081{
7082 hdd_adapter_t *call_back_pAdapter = pAdapter;
7083 complete(&call_back_pAdapter->change_country_code);
7084 return NULL;
7085}
7086
Jeff Johnson295189b2012-06-20 16:38:30 -07007087/*
Mahesh A Saptasagar0e59c472014-04-14 19:17:41 +05307088 * FUNCTION: __wlan_hdd_cfg80211_change_iface
Jeff Johnson295189b2012-06-20 16:38:30 -07007089 * This function is used to set the interface type (INFRASTRUCTURE/ADHOC)
7090 */
Mahesh A Saptasagar0e59c472014-04-14 19:17:41 +05307091int __wlan_hdd_cfg80211_change_iface( struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -07007092 struct net_device *ndev,
7093 enum nl80211_iftype type,
7094 u32 *flags,
7095 struct vif_params *params
7096 )
7097{
7098 struct wireless_dev *wdev;
7099 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( ndev );
Rajesh Chauhana0516c62014-01-30 16:11:18 -08007100 hdd_context_t *pHddCtx;
Mohit Khanna0f232092012-09-11 14:46:08 -07007101 hdd_adapter_t *pP2pAdapter = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -07007102 tCsrRoamProfile *pRoamProfile = NULL;
7103 eCsrRoamBssType LastBSSType;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05307104 hdd_config_t *pConfig = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -07007105 eMib_dot11DesiredBssType connectedBssType;
7106 VOS_STATUS status;
c_hpothu6ff1c3c2013-10-01 19:01:57 +05307107 long ret;
Jeff Johnson295189b2012-06-20 16:38:30 -07007108
7109 ENTER();
7110
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05307111 if (!pAdapter)
Rajesh Chauhana0516c62014-01-30 16:11:18 -08007112 {
7113 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
7114 "%s: Adapter context is null", __func__);
7115 return VOS_STATUS_E_FAILURE;
7116 }
7117
7118 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
7119 if (!pHddCtx)
7120 {
7121 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
7122 "%s: HDD context is null", __func__);
7123 return VOS_STATUS_E_FAILURE;
7124 }
7125
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05307126 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
7127 TRACE_CODE_HDD_CFG80211_CHANGE_IFACE,
7128 pAdapter->sessionId, type));
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05307129 status = wlan_hdd_validate_context(pHddCtx);
7130
7131 if (0 != status)
Jeff Johnson295189b2012-06-20 16:38:30 -07007132 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05307133 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
7134 "%s: HDD context is not valid", __func__);
7135 return status;
Jeff Johnson295189b2012-06-20 16:38:30 -07007136 }
7137
Sushant Kaushik8bc7df22014-04-09 17:55:29 +05307138 hddLog(VOS_TRACE_LEVEL_INFO, "%s: device_mode = %s (%d)",
7139 __func__, hdd_device_modetoString(pAdapter->device_mode),
7140 pAdapter->device_mode);
Jeff Johnson295189b2012-06-20 16:38:30 -07007141
Agarwal Ashish51325b52014-06-16 16:50:49 +05307142 if (vos_max_concurrent_connections_reached()) {
7143 hddLog(VOS_TRACE_LEVEL_INFO, FL("Reached max concurrent connections"));
7144 return -EINVAL;
7145 }
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05307146 pConfig = pHddCtx->cfg_ini;
Jeff Johnson295189b2012-06-20 16:38:30 -07007147 wdev = ndev->ieee80211_ptr;
7148
7149#ifdef WLAN_BTAMP_FEATURE
7150 if((NL80211_IFTYPE_P2P_CLIENT == type)||
7151 (NL80211_IFTYPE_ADHOC == type)||
7152 (NL80211_IFTYPE_AP == type)||
7153 (NL80211_IFTYPE_P2P_GO == type))
7154 {
7155 pHddCtx->isAmpAllowed = VOS_FALSE;
7156 // stop AMP traffic
7157 status = WLANBAP_StopAmp();
7158 if(VOS_STATUS_SUCCESS != status )
7159 {
7160 pHddCtx->isAmpAllowed = VOS_TRUE;
7161 hddLog(VOS_TRACE_LEVEL_FATAL,
7162 "%s: Failed to stop AMP", __func__);
7163 return -EINVAL;
7164 }
7165 }
7166#endif //WLAN_BTAMP_FEATURE
7167 /* Reset the current device mode bit mask*/
7168 wlan_hdd_clear_concurrency_mode(pHddCtx, pAdapter->device_mode);
7169
7170 if( (pAdapter->device_mode == WLAN_HDD_INFRA_STATION)
Jeff Johnson295189b2012-06-20 16:38:30 -07007171 || (pAdapter->device_mode == WLAN_HDD_P2P_CLIENT)
Jeff Johnsone7245742012-09-05 17:12:55 -07007172 || (pAdapter->device_mode == WLAN_HDD_P2P_DEVICE)
Jeff Johnson295189b2012-06-20 16:38:30 -07007173 )
7174 {
7175 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
Rajesh Chauhana0516c62014-01-30 16:11:18 -08007176 if (!pWextState)
7177 {
7178 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
7179 "%s: pWextState is null", __func__);
7180 return VOS_STATUS_E_FAILURE;
7181 }
Jeff Johnson295189b2012-06-20 16:38:30 -07007182 pRoamProfile = &pWextState->roamProfile;
7183 LastBSSType = pRoamProfile->BSSType;
7184
7185 switch (type)
7186 {
7187 case NL80211_IFTYPE_STATION:
Jeff Johnson295189b2012-06-20 16:38:30 -07007188 case NL80211_IFTYPE_P2P_CLIENT:
Jeff Johnson295189b2012-06-20 16:38:30 -07007189 hddLog(VOS_TRACE_LEVEL_INFO,
7190 "%s: setting interface Type to INFRASTRUCTURE", __func__);
7191 pRoamProfile->BSSType = eCSR_BSS_TYPE_INFRASTRUCTURE;
Jeff Johnsone7245742012-09-05 17:12:55 -07007192#ifdef WLAN_FEATURE_11AC
7193 if(pConfig->dot11Mode == eHDD_DOT11_MODE_AUTO)
7194 {
7195 pConfig->dot11Mode = eHDD_DOT11_MODE_11ac;
7196 }
7197#endif
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307198 pRoamProfile->phyMode =
Jeff Johnsone7245742012-09-05 17:12:55 -07007199 hdd_cfg_xlate_to_csr_phy_mode(pConfig->dot11Mode);
Jeff Johnson295189b2012-06-20 16:38:30 -07007200 wdev->iftype = type;
Gopichand Nakkalaf527dc62012-12-31 16:35:10 -08007201 //Check for sub-string p2p to confirm its a p2p interface
7202 if (NULL != strstr(ndev->name,"p2p"))
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307203 {
Gopichand Nakkala864d3552012-12-31 16:08:51 -08007204 pAdapter->device_mode = (type == NL80211_IFTYPE_STATION) ?
7205 WLAN_HDD_P2P_DEVICE : WLAN_HDD_P2P_CLIENT;
7206 }
7207 else
7208 {
7209 pAdapter->device_mode = (type == NL80211_IFTYPE_STATION) ?
Jeff Johnson295189b2012-06-20 16:38:30 -07007210 WLAN_HDD_INFRA_STATION: WLAN_HDD_P2P_CLIENT;
Gopichand Nakkala864d3552012-12-31 16:08:51 -08007211 }
Madan Mohan Koyyalamudi81746922013-07-17 14:38:51 +05307212#ifdef FEATURE_WLAN_TDLS
7213 /* The open adapter for the p2p shall skip initializations in
7214 * tdls_init if the device mode is WLAN_HDD_P2P_DEVICE, for
7215 * TDLS is supported only on WLAN_HDD_P2P_CLIENT. Hence invoke
7216 * tdls_init when the change_iface sets the device mode to
7217 * WLAN_HDD_P2P_CLIENT.
7218 */
7219
7220 if ( pAdapter->device_mode == WLAN_HDD_P2P_CLIENT)
7221 {
Agarwal Ashish4b87f922014-06-18 03:03:21 +05307222 if (0 != wlan_hdd_sta_tdls_init (pAdapter))
Madan Mohan Koyyalamudi81746922013-07-17 14:38:51 +05307223 {
c_hpothu6ff1c3c2013-10-01 19:01:57 +05307224 hddLog(VOS_TRACE_LEVEL_ERROR,
7225 "%s: tdls initialization failed", __func__);
Madan Mohan Koyyalamudi81746922013-07-17 14:38:51 +05307226 return -EINVAL;
7227 }
7228 }
7229#endif
7230
Jeff Johnson295189b2012-06-20 16:38:30 -07007231 break;
7232 case NL80211_IFTYPE_ADHOC:
7233 hddLog(VOS_TRACE_LEVEL_INFO,
7234 "%s: setting interface Type to ADHOC", __func__);
7235 pRoamProfile->BSSType = eCSR_BSS_TYPE_START_IBSS;
7236 pRoamProfile->phyMode =
7237 hdd_cfg_xlate_to_csr_phy_mode(pConfig->dot11Mode);
Shailender Karmuchia734f332013-04-19 14:02:48 -07007238 pAdapter->device_mode = WLAN_HDD_IBSS;
Jeff Johnson295189b2012-06-20 16:38:30 -07007239 wdev->iftype = type;
7240 break;
7241
7242 case NL80211_IFTYPE_AP:
Jeff Johnson295189b2012-06-20 16:38:30 -07007243 case NL80211_IFTYPE_P2P_GO:
Jeff Johnson295189b2012-06-20 16:38:30 -07007244 {
7245 hddLog(VOS_TRACE_LEVEL_INFO_HIGH,
7246 "%s: setting interface Type to %s", __func__,
7247 (type == NL80211_IFTYPE_AP) ? "SoftAP" : "P2pGo");
7248
Gopichand Nakkalaf527dc62012-12-31 16:35:10 -08007249 //Cancel any remain on channel for GO mode
7250 if (NL80211_IFTYPE_P2P_GO == type)
7251 {
7252 wlan_hdd_cancel_existing_remain_on_channel(pAdapter);
7253 }
Mohit Khanna0f232092012-09-11 14:46:08 -07007254 if (NL80211_IFTYPE_AP == type)
7255 {
7256 /* As Loading WLAN Driver one interface being created for p2p device
7257 * address. This will take one HW STA and the max number of clients
7258 * that can connect to softAP will be reduced by one. so while changing
7259 * the interface type to NL80211_IFTYPE_AP (SoftAP) remove p2p0
7260 * interface as it is not required in SoftAP mode.
7261 */
7262
7263 // Get P2P Adapter
7264 pP2pAdapter = hdd_get_adapter(pHddCtx, WLAN_HDD_P2P_DEVICE);
7265
7266 if (pP2pAdapter)
7267 {
Agarwal Ashish3a38bd12014-06-12 15:16:52 +05307268 hdd_stop_adapter(pHddCtx, pP2pAdapter, VOS_TRUE);
Mohit Khanna0f232092012-09-11 14:46:08 -07007269 hdd_deinit_adapter(pHddCtx, pP2pAdapter);
7270 hdd_close_adapter(pHddCtx, pP2pAdapter, VOS_TRUE);
7271 }
7272 }
Swaroop Goltia2e32212014-04-09 23:37:33 +05307273 //Disable IMPS & BMPS for SAP/GO
7274 if(VOS_STATUS_E_FAILURE ==
7275 hdd_disable_bmps_imps(pHddCtx, WLAN_HDD_P2P_GO))
7276 {
7277 //Fail to Exit BMPS
7278 VOS_ASSERT(0);
7279 }
Deepthi Gowri500fc472014-08-11 19:53:10 +05307280
7281 hdd_stop_adapter( pHddCtx, pAdapter, VOS_TRUE );
7282
Madan Mohan Koyyalamudi96797442013-10-08 16:04:42 +05307283#ifdef FEATURE_WLAN_TDLS
Mohit Khanna0f232092012-09-11 14:46:08 -07007284
Madan Mohan Koyyalamudi96797442013-10-08 16:04:42 +05307285 /* A Mutex Lock is introduced while changing the mode to
7286 * protect the concurrent access for the Adapters by TDLS
7287 * module.
7288 */
Rajesh Chauhana34c6e62014-03-25 16:37:58 +05307289 mutex_lock(&pHddCtx->tdls_lock);
Madan Mohan Koyyalamudi96797442013-10-08 16:04:42 +05307290#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07007291 //De-init the adapter.
Jeff Johnson295189b2012-06-20 16:38:30 -07007292 hdd_deinit_adapter( pHddCtx, pAdapter );
7293 memset(&pAdapter->sessionCtx, 0, sizeof(pAdapter->sessionCtx));
Jeff Johnson295189b2012-06-20 16:38:30 -07007294 pAdapter->device_mode = (type == NL80211_IFTYPE_AP) ?
7295 WLAN_HDD_SOFTAP : WLAN_HDD_P2P_GO;
Madan Mohan Koyyalamudi96797442013-10-08 16:04:42 +05307296#ifdef FEATURE_WLAN_TDLS
7297 mutex_unlock(&pHddCtx->tdls_lock);
7298#endif
Madan Mohan Koyyalamudi3ff2a0b2012-10-15 14:33:46 -07007299 if ((WLAN_HDD_SOFTAP == pAdapter->device_mode) &&
7300 (pConfig->apRandomBssidEnabled))
7301 {
7302 /* To meet Android requirements create a randomized
7303 MAC address of the form 02:1A:11:Fx:xx:xx */
7304 get_random_bytes(&ndev->dev_addr[3], 3);
7305 ndev->dev_addr[0] = 0x02;
7306 ndev->dev_addr[1] = 0x1A;
7307 ndev->dev_addr[2] = 0x11;
7308 ndev->dev_addr[3] |= 0xF0;
7309 memcpy(pAdapter->macAddressCurrent.bytes, ndev->dev_addr,
7310 VOS_MAC_ADDR_SIZE);
Arif Hussain24bafea2013-11-15 15:10:03 -08007311 pr_info("wlan: Generated HotSpot BSSID " MAC_ADDRESS_STR"\n",
7312 MAC_ADDR_ARRAY(ndev->dev_addr));
Madan Mohan Koyyalamudi3ff2a0b2012-10-15 14:33:46 -07007313 }
7314
Jeff Johnson295189b2012-06-20 16:38:30 -07007315 hdd_set_ap_ops( pAdapter->dev );
7316
Kiet Lam10841362013-11-01 11:36:50 +05307317 /* This is for only SAP mode where users can
7318 * control country through ini.
7319 * P2P GO follows station country code
7320 * acquired during the STA scanning. */
7321 if((NL80211_IFTYPE_AP == type) &&
7322 (memcmp(pConfig->apCntryCode, CFG_AP_COUNTRY_CODE_DEFAULT, 3) != 0))
7323 {
7324 int status = 0;
7325 VOS_TRACE(VOS_MODULE_ID_HDD,VOS_TRACE_LEVEL_INFO,
7326 "%s: setting country code from INI ", __func__);
7327 init_completion(&pAdapter->change_country_code);
7328 status = (int)sme_ChangeCountryCode(pHddCtx->hHal,
7329 (void *)(tSmeChangeCountryCallback)
7330 wlan_hdd_change_country_code_cb,
7331 pConfig->apCntryCode, pAdapter,
7332 pHddCtx->pvosContext,
Abhishek Singha306a442013-11-07 18:39:01 +05307333 eSIR_FALSE,
7334 eSIR_TRUE);
Kiet Lam10841362013-11-01 11:36:50 +05307335 if (eHAL_STATUS_SUCCESS == status)
7336 {
7337 /* Wait for completion */
c_hpothu6ff1c3c2013-10-01 19:01:57 +05307338 ret = wait_for_completion_interruptible_timeout(
Kiet Lam10841362013-11-01 11:36:50 +05307339 &pAdapter->change_country_code,
7340 msecs_to_jiffies(WLAN_WAIT_TIME_COUNTRY));
c_hpothu6ff1c3c2013-10-01 19:01:57 +05307341 if (ret <= 0)
Kiet Lam10841362013-11-01 11:36:50 +05307342 {
7343 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
c_hpothu6ff1c3c2013-10-01 19:01:57 +05307344 FL("SME Timed out while setting country code %ld"),
7345 ret);
Yue Ma4f55ef32014-01-23 16:45:33 -08007346
7347 if (pHddCtx->isLogpInProgress)
7348 {
7349 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
7350 "%s: LOGP in Progress. Ignore!!!", __func__);
7351 return -EAGAIN;
7352 }
Kiet Lam10841362013-11-01 11:36:50 +05307353 }
7354 }
7355 else
7356 {
7357 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Arif Hussain6d2a3322013-11-17 19:50:10 -08007358 "%s: SME Change Country code failed",__func__);
Kiet Lam10841362013-11-01 11:36:50 +05307359 return -EINVAL;
7360 }
7361 }
Jeff Johnson295189b2012-06-20 16:38:30 -07007362 status = hdd_init_ap_mode(pAdapter);
7363 if(status != VOS_STATUS_SUCCESS)
7364 {
7365 hddLog(VOS_TRACE_LEVEL_FATAL,
7366 "%s: Error initializing the ap mode", __func__);
7367 return -EINVAL;
7368 }
7369 hdd_set_conparam(1);
7370
Jeff Johnson295189b2012-06-20 16:38:30 -07007371 /*interface type changed update in wiphy structure*/
7372 if(wdev)
7373 {
7374 wdev->iftype = type;
7375 pHddCtx->change_iface = type;
7376 }
7377 else
7378 {
7379 hddLog(VOS_TRACE_LEVEL_ERROR,
7380 "%s: ERROR !!!! Wireless dev is NULL", __func__);
7381 return -EINVAL;
7382 }
7383 goto done;
7384 }
7385
7386 default:
7387 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Unsupported interface Type",
7388 __func__);
7389 return -EOPNOTSUPP;
7390 }
7391 }
7392 else if ( (pAdapter->device_mode == WLAN_HDD_SOFTAP)
Jeff Johnson295189b2012-06-20 16:38:30 -07007393 || (pAdapter->device_mode == WLAN_HDD_P2P_GO)
Jeff Johnson295189b2012-06-20 16:38:30 -07007394 )
7395 {
7396 switch(type)
7397 {
7398 case NL80211_IFTYPE_STATION:
Jeff Johnson295189b2012-06-20 16:38:30 -07007399 case NL80211_IFTYPE_P2P_CLIENT:
Jeff Johnson295189b2012-06-20 16:38:30 -07007400 case NL80211_IFTYPE_ADHOC:
Deepthi Gowri500fc472014-08-11 19:53:10 +05307401
7402 hdd_stop_adapter( pHddCtx, pAdapter, VOS_TRUE );
Madan Mohan Koyyalamudi96797442013-10-08 16:04:42 +05307403#ifdef FEATURE_WLAN_TDLS
7404
7405 /* A Mutex Lock is introduced while changing the mode to
7406 * protect the concurrent access for the Adapters by TDLS
7407 * module.
7408 */
Rajesh Chauhana34c6e62014-03-25 16:37:58 +05307409 mutex_lock(&pHddCtx->tdls_lock);
Madan Mohan Koyyalamudi96797442013-10-08 16:04:42 +05307410#endif
Jeff Johnson32d95a32012-09-10 13:15:23 -07007411 hdd_deinit_adapter( pHddCtx, pAdapter );
Jeff Johnson295189b2012-06-20 16:38:30 -07007412 wdev->iftype = type;
Gopichand Nakkalaf527dc62012-12-31 16:35:10 -08007413 //Check for sub-string p2p to confirm its a p2p interface
7414 if (NULL != strstr(ndev->name,"p2p"))
Gopichand Nakkala864d3552012-12-31 16:08:51 -08007415 {
7416 pAdapter->device_mode = (type == NL80211_IFTYPE_STATION) ?
7417 WLAN_HDD_P2P_DEVICE : WLAN_HDD_P2P_CLIENT;
7418 }
7419 else
7420 {
7421 pAdapter->device_mode = (type == NL80211_IFTYPE_STATION) ?
Jeff Johnson295189b2012-06-20 16:38:30 -07007422 WLAN_HDD_INFRA_STATION: WLAN_HDD_P2P_CLIENT;
Gopichand Nakkala864d3552012-12-31 16:08:51 -08007423 }
Jeff Johnson295189b2012-06-20 16:38:30 -07007424 hdd_set_conparam(0);
7425 pHddCtx->change_iface = type;
Jeff Johnson295189b2012-06-20 16:38:30 -07007426 memset(&pAdapter->sessionCtx, 0, sizeof(pAdapter->sessionCtx));
7427 hdd_set_station_ops( pAdapter->dev );
Madan Mohan Koyyalamudi96797442013-10-08 16:04:42 +05307428#ifdef FEATURE_WLAN_TDLS
7429 mutex_unlock(&pHddCtx->tdls_lock);
7430#endif
Sunil Dutt66485cb2013-12-19 19:05:03 +05307431 status = hdd_init_station_mode( pAdapter );
Jeff Johnson295189b2012-06-20 16:38:30 -07007432 if( VOS_STATUS_SUCCESS != status )
7433 return -EOPNOTSUPP;
Jeff Johnsone7245742012-09-05 17:12:55 -07007434 /* In case of JB, for P2P-GO, only change interface will be called,
7435 * This is the right place to enable back bmps_imps()
7436 */
Gopichand Nakkalaa2fe5b02013-06-06 16:32:28 +05307437 if (pHddCtx->hdd_wlan_suspended)
7438 {
7439 hdd_set_pwrparams(pHddCtx);
7440 }
Jeff Johnsone7245742012-09-05 17:12:55 -07007441 hdd_enable_bmps_imps(pHddCtx);
Jeff Johnson295189b2012-06-20 16:38:30 -07007442 goto done;
7443 case NL80211_IFTYPE_AP:
Jeff Johnson295189b2012-06-20 16:38:30 -07007444 case NL80211_IFTYPE_P2P_GO:
Jeff Johnson295189b2012-06-20 16:38:30 -07007445 wdev->iftype = type;
Jeff Johnson295189b2012-06-20 16:38:30 -07007446 pAdapter->device_mode = (type == NL80211_IFTYPE_AP) ?
7447 WLAN_HDD_SOFTAP : WLAN_HDD_P2P_GO;
Jeff Johnson295189b2012-06-20 16:38:30 -07007448 goto done;
7449 default:
7450 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Unsupported interface Type",
7451 __func__);
7452 return -EOPNOTSUPP;
7453
7454 }
7455
7456 }
7457 else
7458 {
Sushant Kaushik8bc7df22014-04-09 17:55:29 +05307459 hddLog(VOS_TRACE_LEVEL_ERROR,"%s: unsupported device mode(%s (%d))",
7460 __func__, hdd_device_modetoString(pAdapter->device_mode),
7461 pAdapter->device_mode);
Jeff Johnson295189b2012-06-20 16:38:30 -07007462 return -EOPNOTSUPP;
7463 }
7464
7465
7466 if(pRoamProfile)
7467 {
7468 if ( LastBSSType != pRoamProfile->BSSType )
7469 {
7470 /*interface type changed update in wiphy structure*/
7471 wdev->iftype = type;
7472
7473 /*the BSS mode changed, We need to issue disconnect
7474 if connected or in IBSS disconnect state*/
7475 if ( hdd_connGetConnectedBssType(
7476 WLAN_HDD_GET_STATION_CTX_PTR(pAdapter), &connectedBssType ) ||
7477 ( eCSR_BSS_TYPE_START_IBSS == LastBSSType ) )
7478 {
7479 /*need to issue a disconnect to CSR.*/
7480 INIT_COMPLETION(pAdapter->disconnect_comp_var);
7481 if( eHAL_STATUS_SUCCESS ==
7482 sme_RoamDisconnect( WLAN_HDD_GET_HAL_CTX(pAdapter),
7483 pAdapter->sessionId,
7484 eCSR_DISCONNECT_REASON_UNSPECIFIED ) )
7485 {
c_hpothu6ff1c3c2013-10-01 19:01:57 +05307486 ret = wait_for_completion_interruptible_timeout(
7487 &pAdapter->disconnect_comp_var,
7488 msecs_to_jiffies(WLAN_WAIT_TIME_DISCONNECT));
7489 if (ret <= 0)
7490 {
7491 hddLog(VOS_TRACE_LEVEL_ERROR,
7492 FL("wait on disconnect_comp_var failed %ld"), ret);
7493 }
Jeff Johnson295189b2012-06-20 16:38:30 -07007494 }
7495 }
7496 }
7497 }
7498
7499done:
7500 /*set bitmask based on updated value*/
7501 wlan_hdd_set_concurrency_mode(pHddCtx, pAdapter->device_mode);
Leo Chang6fe1f922013-06-07 19:21:24 -07007502
7503 /* Only STA mode support TM now
7504 * all other mode, TM feature should be disabled */
7505 if ( (pHddCtx->cfg_ini->thermalMitigationEnable) &&
7506 (~VOS_STA & pHddCtx->concurrency_mode) )
7507 {
7508 hddDevTmLevelChangedHandler(pHddCtx->parent_dev, 0);
7509 }
7510
Jeff Johnson295189b2012-06-20 16:38:30 -07007511#ifdef WLAN_BTAMP_FEATURE
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307512 if((NL80211_IFTYPE_STATION == type) && (pHddCtx->concurrency_mode <= 1) &&
Agarwal Ashish51325b52014-06-16 16:50:49 +05307513 (pHddCtx->no_of_open_sessions[WLAN_HDD_INFRA_STATION] <=1))
Jeff Johnson295189b2012-06-20 16:38:30 -07007514 {
7515 //we are ok to do AMP
7516 pHddCtx->isAmpAllowed = VOS_TRUE;
7517 }
7518#endif //WLAN_BTAMP_FEATURE
7519 EXIT();
7520 return 0;
7521}
7522
Mahesh A Saptasagar0e59c472014-04-14 19:17:41 +05307523/*
7524 * FUNCTION: wlan_hdd_cfg80211_change_iface
7525 * wrapper function to protect the actual implementation from SSR.
7526 */
7527int wlan_hdd_cfg80211_change_iface( struct wiphy *wiphy,
7528 struct net_device *ndev,
7529 enum nl80211_iftype type,
7530 u32 *flags,
7531 struct vif_params *params
7532 )
7533{
7534 int ret;
7535
7536 vos_ssr_protect(__func__);
7537 ret = __wlan_hdd_cfg80211_change_iface(wiphy, ndev, type, flags, params);
7538 vos_ssr_unprotect(__func__);
7539
7540 return ret;
7541}
7542
Gopichand Nakkala681989c2013-03-06 22:27:48 -08007543#ifdef FEATURE_WLAN_TDLS
7544static int wlan_hdd_tdls_add_station(struct wiphy *wiphy,
7545 struct net_device *dev, u8 *mac, bool update, tCsrStaParams *StaParams)
7546{
7547 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
7548 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
7549 VOS_STATUS status;
Hoonki Lee5305c3a2013-04-29 23:28:59 -07007550 hddTdlsPeer_t *pTdlsPeer;
c_hpothu6ff1c3c2013-10-01 19:01:57 +05307551 long ret;
Rajesh Chauhana34c6e62014-03-25 16:37:58 +05307552 tANI_U16 numCurrTdlsPeers;
Gopichand Nakkala681989c2013-03-06 22:27:48 -08007553
7554 ENTER();
7555
Gopichand Nakkala838be5d2013-04-10 22:41:51 +05307556 if (NULL == pHddCtx || NULL == pHddCtx->cfg_ini)
Gopichand Nakkala681989c2013-03-06 22:27:48 -08007557 {
7558 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
7559 "Invalid arguments");
7560 return -EINVAL;
7561 }
Hoonki Lee27511902013-03-14 18:19:06 -07007562
7563 if ((eTDLS_SUPPORT_NOT_ENABLED == pHddCtx->tdls_mode) ||
7564 (eTDLS_SUPPORT_DISABLED == pHddCtx->tdls_mode))
7565 {
7566 VOS_TRACE( VOS_MODULE_ID_HDD, TDLS_LOG_LEVEL,
7567 "%s: TDLS mode is disabled OR not enabled in FW."
7568 MAC_ADDRESS_STR " Request declined.",
7569 __func__, MAC_ADDR_ARRAY(mac));
7570 return -ENOTSUPP;
7571 }
7572
Gopichand Nakkala681989c2013-03-06 22:27:48 -08007573 if (pHddCtx->isLogpInProgress)
7574 {
7575 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
7576 "%s:LOGP in Progress. Ignore!!!", __func__);
Atul Mittal115287b2014-07-08 13:26:33 +05307577 wlan_hdd_tdls_set_link_status(pAdapter,
7578 mac,
7579 eTDLS_LINK_IDLE,
7580 eTDLS_LINK_UNSPECIFIED);
Gopichand Nakkala681989c2013-03-06 22:27:48 -08007581 return -EBUSY;
7582 }
7583
Naresh Jayaram9c6f4462014-02-13 12:20:31 +05307584 pTdlsPeer = wlan_hdd_tdls_get_peer(pAdapter, mac);
Hoonki Lee5305c3a2013-04-29 23:28:59 -07007585
7586 if ( NULL == pTdlsPeer ) {
7587 VOS_TRACE( VOS_MODULE_ID_HDD, TDLS_LOG_LEVEL,
7588 "%s: " MAC_ADDRESS_STR " (update %d) not exist. return invalid",
7589 __func__, MAC_ADDR_ARRAY(mac), update);
7590 return -EINVAL;
Gopichand Nakkala34d1b062013-03-19 15:28:33 -07007591 }
Hoonki Lee5305c3a2013-04-29 23:28:59 -07007592
7593 /* in add station, we accept existing valid staId if there is */
7594 if ((0 == update) &&
7595 ((pTdlsPeer->link_status >= eTDLS_LINK_CONNECTING) ||
7596 (TDLS_STA_INDEX_VALID(pTdlsPeer->staId))))
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -07007597 {
Hoonki Lee5305c3a2013-04-29 23:28:59 -07007598 VOS_TRACE( VOS_MODULE_ID_HDD, TDLS_LOG_LEVEL,
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -07007599 "%s: " MAC_ADDRESS_STR
Hoonki Lee5305c3a2013-04-29 23:28:59 -07007600 " link_status %d. staId %d. add station ignored.",
7601 __func__, MAC_ADDR_ARRAY(mac), pTdlsPeer->link_status, pTdlsPeer->staId);
7602 return 0;
7603 }
7604 /* in change station, we accept only when staId is valid */
7605 if ((1 == update) &&
7606 ((pTdlsPeer->link_status > eTDLS_LINK_CONNECTING) ||
7607 (!TDLS_STA_INDEX_VALID(pTdlsPeer->staId))))
7608 {
7609 VOS_TRACE( VOS_MODULE_ID_HDD, TDLS_LOG_LEVEL,
7610 "%s: " MAC_ADDRESS_STR
7611 " link status %d. staId %d. change station %s.",
7612 __func__, MAC_ADDR_ARRAY(mac), pTdlsPeer->link_status, pTdlsPeer->staId,
7613 (TDLS_STA_INDEX_VALID(pTdlsPeer->staId)) ? "ignored" : "declined");
7614 return (TDLS_STA_INDEX_VALID(pTdlsPeer->staId)) ? 0 : -EPERM;
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -07007615 }
Gopichand Nakkala34d1b062013-03-19 15:28:33 -07007616
7617 /* when others are on-going, we want to change link_status to idle */
Madan Mohan Koyyalamudi96797442013-10-08 16:04:42 +05307618 if (NULL != wlan_hdd_tdls_is_progress(pHddCtx, mac, TRUE))
Gopichand Nakkala681989c2013-03-06 22:27:48 -08007619 {
Gopichand Nakkalac87400e2013-03-13 18:51:00 -07007620 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
7621 "%s: " MAC_ADDRESS_STR
7622 " TDLS setup is ongoing. Request declined.",
7623 __func__, MAC_ADDR_ARRAY(mac));
Gopichand Nakkala05922802013-03-14 12:23:19 -07007624 goto error;
Gopichand Nakkala681989c2013-03-06 22:27:48 -08007625 }
7626
7627 /* first to check if we reached to maximum supported TDLS peer.
7628 TODO: for now, return -EPERM looks working fine,
7629 but need to check if any other errno fit into this category.*/
Rajesh Chauhana34c6e62014-03-25 16:37:58 +05307630 numCurrTdlsPeers = wlan_hdd_tdlsConnectedPeers(pAdapter);
7631 if (HDD_MAX_NUM_TDLS_STA <= numCurrTdlsPeers)
Gopichand Nakkala681989c2013-03-06 22:27:48 -08007632 {
Gopichand Nakkalac87400e2013-03-13 18:51:00 -07007633 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
7634 "%s: " MAC_ADDRESS_STR
Rajesh Chauhana34c6e62014-03-25 16:37:58 +05307635 " TDLS Max peer already connected. Request declined."
7636 " Num of peers (%d), Max allowed (%d).",
7637 __func__, MAC_ADDR_ARRAY(mac), numCurrTdlsPeers,
7638 HDD_MAX_NUM_TDLS_STA);
Gopichand Nakkala05922802013-03-14 12:23:19 -07007639 goto error;
Gopichand Nakkala681989c2013-03-06 22:27:48 -08007640 }
7641 else
7642 {
7643 hddTdlsPeer_t *pTdlsPeer;
Madan Mohan Koyyalamudi96797442013-10-08 16:04:42 +05307644 pTdlsPeer = wlan_hdd_tdls_find_peer(pAdapter, mac, TRUE);
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -07007645 if (pTdlsPeer && TDLS_IS_CONNECTED(pTdlsPeer))
Gopichand Nakkala681989c2013-03-06 22:27:48 -08007646 {
Gopichand Nakkalac87400e2013-03-13 18:51:00 -07007647 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
7648 "%s: " MAC_ADDRESS_STR " already connected. Request declined.",
7649 __func__, MAC_ADDR_ARRAY(mac));
Gopichand Nakkala681989c2013-03-06 22:27:48 -08007650 return -EPERM;
7651 }
7652 }
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -07007653 if (0 == update)
Atul Mittal115287b2014-07-08 13:26:33 +05307654 wlan_hdd_tdls_set_link_status(pAdapter,
7655 mac,
7656 eTDLS_LINK_CONNECTING,
7657 eTDLS_LINK_SUCCESS);
Gopichand Nakkala681989c2013-03-06 22:27:48 -08007658
Jeff Johnsond75fe012013-04-06 10:53:06 -07007659 /* debug code */
Gopichand Nakkala838be5d2013-04-10 22:41:51 +05307660 if (NULL != StaParams)
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -07007661 {
7662 VOS_TRACE(VOS_MODULE_ID_HDD, TDLS_LOG_LEVEL,
7663 "%s: TDLS Peer Parameters.", __func__);
Hoonki Lee66b75f32013-04-16 18:30:07 -07007664 if(StaParams->htcap_present)
7665 {
7666 VOS_TRACE(VOS_MODULE_ID_HDD, TDLS_LOG_LEVEL,
7667 "ht_capa->cap_info: %0x", StaParams->HTCap.capInfo);
7668 VOS_TRACE(VOS_MODULE_ID_HDD, TDLS_LOG_LEVEL,
7669 "ht_capa->extended_capabilities: %0x",
7670 StaParams->HTCap.extendedHtCapInfo);
7671 }
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -07007672 VOS_TRACE(VOS_MODULE_ID_HDD, TDLS_LOG_LEVEL,
7673 "params->capability: %0x",StaParams->capability);
7674 VOS_TRACE(VOS_MODULE_ID_HDD, TDLS_LOG_LEVEL,
Jeff Johnson0299d0a2013-10-30 12:37:43 -07007675 "params->ext_capab_len: %0x",StaParams->extn_capability[0]);
Hoonki Lee66b75f32013-04-16 18:30:07 -07007676 if(StaParams->vhtcap_present)
7677 {
7678 VOS_TRACE(VOS_MODULE_ID_HDD, TDLS_LOG_LEVEL,
7679 "rxMcsMap %x rxHighest %x txMcsMap %x txHighest %x",
7680 StaParams->VHTCap.suppMcs.rxMcsMap, StaParams->VHTCap.suppMcs.rxHighest,
7681 StaParams->VHTCap.suppMcs.txMcsMap, StaParams->VHTCap.suppMcs.txHighest);
7682 }
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -07007683 {
7684 int i = 0;
Hoonki Lee5305c3a2013-04-29 23:28:59 -07007685 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO, "Supported rates:");
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -07007686 for (i = 0; i < sizeof(StaParams->supported_rates); i++)
7687 VOS_TRACE(VOS_MODULE_ID_HDD, TDLS_LOG_LEVEL,
7688 "[%d]: %x ", i, StaParams->supported_rates[i]);
7689 }
Jeff Johnsond75fe012013-04-06 10:53:06 -07007690 } /* end debug code */
Gopichand Nakkala838be5d2013-04-10 22:41:51 +05307691 else if ((1 == update) && (NULL == StaParams))
7692 {
7693 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
7694 "%s : update is true, but staParams is NULL. Error!", __func__);
7695 return -EPERM;
7696 }
Gopichand Nakkala681989c2013-03-06 22:27:48 -08007697
7698 INIT_COMPLETION(pAdapter->tdls_add_station_comp);
7699
7700 if (!update)
7701 {
7702 status = sme_AddTdlsPeerSta(WLAN_HDD_GET_HAL_CTX(pAdapter),
7703 pAdapter->sessionId, mac);
7704 }
7705 else
7706 {
7707 status = sme_ChangeTdlsPeerSta(WLAN_HDD_GET_HAL_CTX(pAdapter),
7708 pAdapter->sessionId, mac, StaParams);
7709 }
7710
c_hpothu6ff1c3c2013-10-01 19:01:57 +05307711 ret = wait_for_completion_interruptible_timeout(&pAdapter->tdls_add_station_comp,
Gopichand Nakkala681989c2013-03-06 22:27:48 -08007712 msecs_to_jiffies(WAIT_TIME_TDLS_ADD_STA));
7713
c_hpothu6ff1c3c2013-10-01 19:01:57 +05307714 if (ret <= 0)
Gopichand Nakkala681989c2013-03-06 22:27:48 -08007715 {
Gopichand Nakkalac87400e2013-03-13 18:51:00 -07007716 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
c_hpothu6ff1c3c2013-10-01 19:01:57 +05307717 "%s: timeout waiting for tdls add station indication %ld",
7718 __func__, ret);
Gopichand Nakkala34d1b062013-03-19 15:28:33 -07007719 return -EPERM;
Gopichand Nakkala681989c2013-03-06 22:27:48 -08007720 }
c_hpothu6ff1c3c2013-10-01 19:01:57 +05307721
Gopichand Nakkala681989c2013-03-06 22:27:48 -08007722 if ( eHAL_STATUS_SUCCESS != pAdapter->tdlsAddStaStatus)
7723 {
Gopichand Nakkalac87400e2013-03-13 18:51:00 -07007724 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Gopichand Nakkala681989c2013-03-06 22:27:48 -08007725 "%s: Add Station is unsucessful", __func__);
Gopichand Nakkala34d1b062013-03-19 15:28:33 -07007726 return -EPERM;
Gopichand Nakkala681989c2013-03-06 22:27:48 -08007727 }
7728
7729 return 0;
Gopichand Nakkala05922802013-03-14 12:23:19 -07007730
7731error:
Atul Mittal115287b2014-07-08 13:26:33 +05307732 wlan_hdd_tdls_set_link_status(pAdapter,
7733 mac,
7734 eTDLS_LINK_IDLE,
7735 eTDLS_LINK_UNSPECIFIED);
Gopichand Nakkala05922802013-03-14 12:23:19 -07007736 return -EPERM;
7737
Gopichand Nakkala681989c2013-03-06 22:27:48 -08007738}
7739#endif
7740
Jeff Johnson295189b2012-06-20 16:38:30 -07007741static int wlan_hdd_change_station(struct wiphy *wiphy,
7742 struct net_device *dev,
7743 u8 *mac,
7744 struct station_parameters *params)
7745{
7746 VOS_STATUS status = VOS_STATUS_SUCCESS;
7747 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( dev );
Gopichand Nakkala29149562013-05-10 21:43:41 +05307748 hdd_context_t *pHddCtx;
7749 hdd_station_ctx_t *pHddStaCtx;
Jeff Johnson295189b2012-06-20 16:38:30 -07007750 v_MACADDR_t STAMacAddress;
Gopichand Nakkalab0856222013-03-12 22:39:05 -07007751#ifdef FEATURE_WLAN_TDLS
Gopichand Nakkala681989c2013-03-06 22:27:48 -08007752 tCsrStaParams StaParams = {0};
Gopichand Nakkala681989c2013-03-06 22:27:48 -08007753 tANI_U8 isBufSta = 0;
Naresh Jayaram3180aa42014-02-12 21:47:26 +05307754 tANI_U8 isOffChannelSupported = 0;
Gopichand Nakkalab0856222013-03-12 22:39:05 -07007755#endif
Jeff Johnsone7245742012-09-05 17:12:55 -07007756 ENTER();
7757
Gopichand Nakkala29149562013-05-10 21:43:41 +05307758 if ((NULL == pAdapter))
7759 {
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +05307760 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
Gopichand Nakkala29149562013-05-10 21:43:41 +05307761 "invalid adapter ");
7762 return -EINVAL;
7763 }
7764
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05307765 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
7766 TRACE_CODE_HDD_CHANGE_STATION,
7767 pAdapter->sessionId, params->listen_interval));
Gopichand Nakkala29149562013-05-10 21:43:41 +05307768 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
7769 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
7770
7771 if ((NULL == pHddCtx) || (NULL == pHddStaCtx))
7772 {
7773 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
7774 "invalid HDD state or HDD station context");
7775 return -EINVAL;
7776 }
7777
7778 if (pHddCtx->isLogpInProgress)
Jeff Johnson04dd8a82012-06-29 20:41:40 -07007779 {
7780 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
7781 "%s:LOGP in Progress. Ignore!!!", __func__);
7782 return -EAGAIN;
7783 }
7784
Jeff Johnson295189b2012-06-20 16:38:30 -07007785 vos_mem_copy(STAMacAddress.bytes, mac, sizeof(v_MACADDR_t));
7786
Gopichand Nakkala681989c2013-03-06 22:27:48 -08007787 if ((pAdapter->device_mode == WLAN_HDD_SOFTAP)
7788 || (pAdapter->device_mode == WLAN_HDD_P2P_GO))
Jeff Johnson295189b2012-06-20 16:38:30 -07007789 {
Gopichand Nakkala681989c2013-03-06 22:27:48 -08007790 if (params->sta_flags_set & BIT(NL80211_STA_FLAG_AUTHORIZED))
Jeff Johnson295189b2012-06-20 16:38:30 -07007791 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307792 status = hdd_softap_change_STA_state( pAdapter, &STAMacAddress,
Jeff Johnson295189b2012-06-20 16:38:30 -07007793 WLANTL_STA_AUTHENTICATED);
7794
Gopichand Nakkala29149562013-05-10 21:43:41 +05307795 if (status != VOS_STATUS_SUCCESS)
7796 {
7797 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
7798 "%s: Not able to change TL state to AUTHENTICATED", __func__);
7799 return -EINVAL;
7800 }
Jeff Johnson295189b2012-06-20 16:38:30 -07007801 }
7802 }
Hoonki Leea6d49be2013-04-05 09:43:25 -07007803 else if ((pAdapter->device_mode == WLAN_HDD_INFRA_STATION)
7804 || (pAdapter->device_mode == WLAN_HDD_P2P_CLIENT)) {
Gopichand Nakkala29149562013-05-10 21:43:41 +05307805#ifdef FEATURE_WLAN_TDLS
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -07007806 if (params->sta_flags_set & BIT(NL80211_STA_FLAG_TDLS_PEER)) {
7807 StaParams.capability = params->capability;
7808 StaParams.uapsd_queues = params->uapsd_queues;
7809 StaParams.max_sp = params->max_sp;
7810
Naresh Jayaram3180aa42014-02-12 21:47:26 +05307811 /* Convert (first channel , number of channels) tuple to
7812 * the total list of channels. This goes with the assumption
7813 * that if the first channel is < 14, then the next channels
7814 * are an incremental of 1 else an incremental of 4 till the number
7815 * of channels.
7816 */
7817 if (0 != params->supported_channels_len) {
7818 int i = 0,j = 0,k = 0, no_of_channels = 0 ;
7819 for ( i = 0 ; i < params->supported_channels_len ; i+=2)
7820 {
7821 int wifi_chan_index;
7822 StaParams.supported_channels[j] = params->supported_channels[i];
7823 wifi_chan_index =
7824 ((StaParams.supported_channels[j] <= HDD_CHANNEL_14 ) ? 1 : 4 );
7825 no_of_channels = params->supported_channels[i+1];
7826 for(k=1; k <= no_of_channels; k++)
7827 {
7828 StaParams.supported_channels[j+1] =
7829 StaParams.supported_channels[j] + wifi_chan_index;
7830 j+=1;
7831 }
7832 }
7833 StaParams.supported_channels_len = j;
7834 }
7835 vos_mem_copy(StaParams.supported_oper_classes,
7836 params->supported_oper_classes,
7837 params->supported_oper_classes_len);
7838 StaParams.supported_oper_classes_len =
7839 params->supported_oper_classes_len;
7840
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -07007841 if (0 != params->ext_capab_len)
7842 vos_mem_copy(StaParams.extn_capability, params->ext_capab,
7843 sizeof(StaParams.extn_capability));
7844
7845 if (NULL != params->ht_capa)
Hoonki Lee66b75f32013-04-16 18:30:07 -07007846 {
7847 StaParams.htcap_present = 1;
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -07007848 vos_mem_copy(&StaParams.HTCap, params->ht_capa, sizeof(tSirHTCap));
Hoonki Lee66b75f32013-04-16 18:30:07 -07007849 }
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -07007850
7851 StaParams.supported_rates_len = params->supported_rates_len;
7852
7853 /* Note : The Maximum sizeof supported_rates sent by the Supplicant is 32.
7854 * The supported_rates array , for all the structures propogating till Add Sta
7855 * to the firmware has to be modified , if the supplicant (ieee80211) is
7856 * modified to send more rates.
7857 */
7858
7859 /* To avoid Data Currption , set to max length to SIR_MAC_MAX_SUPP_RATES
7860 */
7861 if (StaParams.supported_rates_len > SIR_MAC_MAX_SUPP_RATES)
7862 StaParams.supported_rates_len = SIR_MAC_MAX_SUPP_RATES;
7863
7864 if (0 != StaParams.supported_rates_len) {
7865 int i = 0;
7866 vos_mem_copy(StaParams.supported_rates, params->supported_rates,
7867 StaParams.supported_rates_len);
Hoonki Lee5305c3a2013-04-29 23:28:59 -07007868 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -07007869 "Supported Rates with Length %d", StaParams.supported_rates_len);
7870 for (i=0; i < StaParams.supported_rates_len; i++)
Hoonki Lee5305c3a2013-04-29 23:28:59 -07007871 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -07007872 "[%d]: %0x", i, StaParams.supported_rates[i]);
7873 }
7874
7875 if (NULL != params->vht_capa)
Hoonki Lee66b75f32013-04-16 18:30:07 -07007876 {
7877 StaParams.vhtcap_present = 1;
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -07007878 vos_mem_copy(&StaParams.VHTCap, params->vht_capa, sizeof(tSirVHTCap));
Hoonki Lee66b75f32013-04-16 18:30:07 -07007879 }
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -07007880
Gopichand Nakkala681989c2013-03-06 22:27:48 -08007881 if (0 != params->ext_capab_len ) {
7882 /*Define A Macro : TODO Sunil*/
7883 if ((1<<4) & StaParams.extn_capability[3]) {
7884 isBufSta = 1;
7885 }
Naresh Jayaram3180aa42014-02-12 21:47:26 +05307886 /* TDLS Channel Switching Support */
7887 if ((1<<6) & StaParams.extn_capability[3]) {
7888 isOffChannelSupported = 1;
7889 }
Gopichand Nakkala681989c2013-03-06 22:27:48 -08007890 }
Naresh Jayaram3180aa42014-02-12 21:47:26 +05307891 status = wlan_hdd_tdls_set_peer_caps( pAdapter, mac,
7892 &StaParams, isBufSta,
7893 isOffChannelSupported);
7894
Gopichand Nakkala79ff85d2013-05-27 17:05:29 +05307895 if (VOS_STATUS_SUCCESS != status) {
7896 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
7897 "%s: wlan_hdd_tdls_set_peer_caps failed!", __func__);
7898 return -EINVAL;
7899 }
Gopichand Nakkala681989c2013-03-06 22:27:48 -08007900 status = wlan_hdd_tdls_add_station(wiphy, dev, mac, 1, &StaParams);
7901
7902 if (VOS_STATUS_SUCCESS != status) {
7903 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
7904 "%s: sme_ChangeTdlsPeerSta failed!", __func__);
7905 return -EINVAL;
7906 }
7907 }
Gopichand Nakkalab0856222013-03-12 22:39:05 -07007908#endif
Gopichand Nakkala6239acd2013-06-14 14:48:00 +05307909 }
Jeff Johnsone7245742012-09-05 17:12:55 -07007910 EXIT();
Jeff Johnson295189b2012-06-20 16:38:30 -07007911 return status;
7912}
7913
7914/*
Mahesh A Saptasagar1a51bc02014-06-02 18:28:08 +05307915 * FUNCTION: __wlan_hdd_cfg80211_add_key
Jeff Johnson295189b2012-06-20 16:38:30 -07007916 * This function is used to initialize the key information
7917 */
7918#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
Mahesh A Saptasagar1a51bc02014-06-02 18:28:08 +05307919static int __wlan_hdd_cfg80211_add_key( struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -07007920 struct net_device *ndev,
7921 u8 key_index, bool pairwise,
7922 const u8 *mac_addr,
7923 struct key_params *params
7924 )
7925#else
Mahesh A Saptasagar1a51bc02014-06-02 18:28:08 +05307926static int __wlan_hdd_cfg80211_add_key( struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -07007927 struct net_device *ndev,
7928 u8 key_index, const u8 *mac_addr,
7929 struct key_params *params
7930 )
7931#endif
7932{
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -07007933 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( ndev );
Jeff Johnson295189b2012-06-20 16:38:30 -07007934 tCsrRoamSetKey setKey;
7935 u8 groupmacaddr[WNI_CFG_BSSID_LEN] = {0xFF,0xFF,0xFF,0xFF,0xFF,0xFF};
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05307936 int status;
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -07007937 v_U32_t roamId= 0xFF;
7938 v_CONTEXT_t pVosContext = (WLAN_HDD_GET_CTX(pAdapter))->pvosContext;
Jeff Johnson295189b2012-06-20 16:38:30 -07007939 hdd_hostapd_state_t *pHostapdState;
7940 VOS_STATUS vos_status;
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -07007941 eHalStatus halStatus;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05307942 hdd_context_t *pHddCtx;
Jeff Johnson295189b2012-06-20 16:38:30 -07007943
7944 ENTER();
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +05307945
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05307946 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
7947 TRACE_CODE_HDD_CFG80211_ADD_KEY,
7948 pAdapter->sessionId, params->key_len));
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05307949 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
7950 status = wlan_hdd_validate_context(pHddCtx);
7951
7952 if (0 != status)
Jeff Johnson04dd8a82012-06-29 20:41:40 -07007953 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05307954 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
7955 "%s: HDD context is not valid", __func__);
7956 return status;
Jeff Johnson04dd8a82012-06-29 20:41:40 -07007957 }
7958
Sushant Kaushik8bc7df22014-04-09 17:55:29 +05307959 hddLog(VOS_TRACE_LEVEL_INFO, "%s: device_mode = %s (%d)",
7960 __func__, hdd_device_modetoString(pAdapter->device_mode),
7961 pAdapter->device_mode);
Jeff Johnson295189b2012-06-20 16:38:30 -07007962
7963 if (CSR_MAX_NUM_KEY <= key_index)
7964 {
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -07007965 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Invalid key index %d", __func__,
Jeff Johnson295189b2012-06-20 16:38:30 -07007966 key_index);
7967
7968 return -EINVAL;
7969 }
7970
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -07007971 if (CSR_MAX_KEY_LEN < params->key_len)
7972 {
7973 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Invalid key length %d", __func__,
7974 params->key_len);
7975
7976 return -EINVAL;
7977 }
7978
7979 hddLog(VOS_TRACE_LEVEL_INFO,
7980 "%s: called with key index = %d & key length %d",
7981 __func__, key_index, params->key_len);
Jeff Johnson295189b2012-06-20 16:38:30 -07007982
7983 /*extract key idx, key len and key*/
7984 vos_mem_zero(&setKey,sizeof(tCsrRoamSetKey));
7985 setKey.keyId = key_index;
7986 setKey.keyLength = params->key_len;
7987 vos_mem_copy(&setKey.Key[0],params->key, params->key_len);
7988
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -07007989 switch (params->cipher)
Jeff Johnson295189b2012-06-20 16:38:30 -07007990 {
7991 case WLAN_CIPHER_SUITE_WEP40:
7992 setKey.encType = eCSR_ENCRYPT_TYPE_WEP40_STATICKEY;
7993 break;
7994
7995 case WLAN_CIPHER_SUITE_WEP104:
7996 setKey.encType = eCSR_ENCRYPT_TYPE_WEP104_STATICKEY;
7997 break;
7998
7999 case WLAN_CIPHER_SUITE_TKIP:
8000 {
8001 u8 *pKey = &setKey.Key[0];
8002 setKey.encType = eCSR_ENCRYPT_TYPE_TKIP;
8003
8004 vos_mem_zero(pKey, CSR_MAX_KEY_LEN);
8005
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -07008006 /*Supplicant sends the 32bytes key in this order
Jeff Johnson295189b2012-06-20 16:38:30 -07008007
8008 |--------------|----------|----------|
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -07008009 | Tk1 |TX-MIC | RX Mic |
Jeff Johnson295189b2012-06-20 16:38:30 -07008010 |--------------|----------|----------|
8011 <---16bytes---><--8bytes--><--8bytes-->
8012
8013 */
8014 /*Sme expects the 32 bytes key to be in the below order
8015
8016 |--------------|----------|----------|
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -07008017 | Tk1 |RX-MIC | TX Mic |
Jeff Johnson295189b2012-06-20 16:38:30 -07008018 |--------------|----------|----------|
8019 <---16bytes---><--8bytes--><--8bytes-->
8020 */
8021 /* Copy the Temporal Key 1 (TK1) */
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -07008022 vos_mem_copy(pKey, params->key, 16);
Jeff Johnson295189b2012-06-20 16:38:30 -07008023
8024 /*Copy the rx mic first*/
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -07008025 vos_mem_copy(&pKey[16], &params->key[24], 8);
Jeff Johnson295189b2012-06-20 16:38:30 -07008026
8027 /*Copy the tx mic */
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -07008028 vos_mem_copy(&pKey[24], &params->key[16], 8);
Jeff Johnson295189b2012-06-20 16:38:30 -07008029
8030
8031 break;
8032 }
8033
8034 case WLAN_CIPHER_SUITE_CCMP:
8035 setKey.encType = eCSR_ENCRYPT_TYPE_AES;
8036 break;
8037
8038#ifdef FEATURE_WLAN_WAPI
8039 case WLAN_CIPHER_SUITE_SMS4:
8040 {
8041 vos_mem_zero(&setKey,sizeof(tCsrRoamSetKey));
8042 wlan_hdd_cfg80211_set_key_wapi(pAdapter, key_index, mac_addr,
8043 params->key, params->key_len);
8044 return 0;
8045 }
8046#endif
Chet Lanctot186b5732013-03-18 10:26:30 -07008047
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08008048#ifdef FEATURE_WLAN_ESE
Jeff Johnson295189b2012-06-20 16:38:30 -07008049 case WLAN_CIPHER_SUITE_KRK:
8050 setKey.encType = eCSR_ENCRYPT_TYPE_KRK;
8051 break;
8052#endif
Chet Lanctot186b5732013-03-18 10:26:30 -07008053
8054#ifdef WLAN_FEATURE_11W
8055 case WLAN_CIPHER_SUITE_AES_CMAC:
8056 setKey.encType = eCSR_ENCRYPT_TYPE_AES_CMAC;
Chet Lanctot3b5158a2013-03-31 16:45:21 -07008057 break;
Chet Lanctot186b5732013-03-18 10:26:30 -07008058#endif
8059
Jeff Johnson295189b2012-06-20 16:38:30 -07008060 default:
Jeff Johnson0299d0a2013-10-30 12:37:43 -07008061 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: unsupported cipher type %u",
Jeff Johnson295189b2012-06-20 16:38:30 -07008062 __func__, params->cipher);
Vinay Krishna Eranna6f22c1f2014-10-13 16:03:06 +05308063 status = -EOPNOTSUPP;
8064 goto end;
Jeff Johnson295189b2012-06-20 16:38:30 -07008065 }
8066
8067 hddLog(VOS_TRACE_LEVEL_INFO_MED, "%s: encryption type %d",
8068 __func__, setKey.encType);
8069
Shailender Karmuchi642e9812013-05-30 14:34:49 -07008070 if (
Jeff Johnson295189b2012-06-20 16:38:30 -07008071#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
8072 (!pairwise)
8073#else
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -07008074 (!mac_addr || is_broadcast_ether_addr(mac_addr))
Jeff Johnson295189b2012-06-20 16:38:30 -07008075#endif
Shailender Karmuchi642e9812013-05-30 14:34:49 -07008076 )
8077 {
8078 /* set group key*/
8079 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
8080 "%s- %d: setting Broadcast key",
8081 __func__, __LINE__);
8082 setKey.keyDirection = eSIR_RX_ONLY;
8083 vos_mem_copy(setKey.peerMac,groupmacaddr,WNI_CFG_BSSID_LEN);
8084 }
8085 else
8086 {
8087 /* set pairwise key*/
8088 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
8089 "%s- %d: setting pairwise key",
8090 __func__, __LINE__);
8091 setKey.keyDirection = eSIR_TX_RX;
8092 vos_mem_copy(setKey.peerMac, mac_addr,WNI_CFG_BSSID_LEN);
8093 }
8094 if ((WLAN_HDD_IBSS == pAdapter->device_mode) && !pairwise)
8095 {
8096 setKey.keyDirection = eSIR_TX_RX;
8097 /*Set the group key*/
8098 status = sme_RoamSetKey( WLAN_HDD_GET_HAL_CTX(pAdapter),
8099 pAdapter->sessionId, &setKey, &roamId );
Jeff Johnson295189b2012-06-20 16:38:30 -07008100
Shailender Karmuchi642e9812013-05-30 14:34:49 -07008101 if ( 0 != status )
8102 {
8103 hddLog(VOS_TRACE_LEVEL_ERROR,
8104 "%s: sme_RoamSetKey failed, returned %d", __func__, status);
Vinay Krishna Eranna6f22c1f2014-10-13 16:03:06 +05308105 status = -EINVAL;
8106 goto end;
Shailender Karmuchi642e9812013-05-30 14:34:49 -07008107 }
8108 /*Save the keys here and call sme_RoamSetKey for setting
8109 the PTK after peer joins the IBSS network*/
8110 vos_mem_copy(&pAdapter->sessionCtx.station.ibss_enc_key,
8111 &setKey, sizeof(tCsrRoamSetKey));
Vinay Krishna Eranna6f22c1f2014-10-13 16:03:06 +05308112 goto end;
Shailender Karmuchi642e9812013-05-30 14:34:49 -07008113 }
Gopichand Nakkala29149562013-05-10 21:43:41 +05308114 if ((pAdapter->device_mode == WLAN_HDD_SOFTAP) ||
8115 (pAdapter->device_mode == WLAN_HDD_P2P_GO))
8116 {
Jeff Johnson295189b2012-06-20 16:38:30 -07008117 pHostapdState = WLAN_HDD_GET_HOSTAP_STATE_PTR(pAdapter);
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -07008118 if( pHostapdState->bssState == BSS_START )
8119 {
c_hpothu7c55da62014-01-23 18:34:02 +05308120 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
8121 vos_status = wlan_hdd_check_ula_done(pAdapter);
8122
8123 if ( vos_status != VOS_STATUS_SUCCESS )
8124 {
8125 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
8126 "[%4d] wlan_hdd_check_ula_done returned ERROR status= %d",
8127 __LINE__, vos_status );
8128
8129 pHddStaCtx->roam_info.roamingState = HDD_ROAM_STATE_NONE;
8130
Vinay Krishna Eranna6f22c1f2014-10-13 16:03:06 +05308131 status = -EINVAL;
8132 goto end;
c_hpothu7c55da62014-01-23 18:34:02 +05308133 }
8134
Jeff Johnson295189b2012-06-20 16:38:30 -07008135 status = WLANSAP_SetKeySta( pVosContext, &setKey);
8136
8137 if ( status != eHAL_STATUS_SUCCESS )
8138 {
8139 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
8140 "[%4d] WLANSAP_SetKeySta returned ERROR status= %d",
8141 __LINE__, status );
Vinay Krishna Eranna6f22c1f2014-10-13 16:03:06 +05308142 status = -EINVAL;
8143 goto end;
Jeff Johnson295189b2012-06-20 16:38:30 -07008144 }
8145 }
8146
8147 /* Saving WEP keys */
8148 else if( eCSR_ENCRYPT_TYPE_WEP40_STATICKEY == setKey.encType ||
8149 eCSR_ENCRYPT_TYPE_WEP104_STATICKEY == setKey.encType )
8150 {
8151 //Save the wep key in ap context. Issue setkey after the BSS is started.
8152 hdd_ap_ctx_t *pAPCtx = WLAN_HDD_GET_AP_CTX_PTR(pAdapter);
8153 vos_mem_copy(&pAPCtx->wepKey[key_index], &setKey, sizeof(tCsrRoamSetKey));
8154 }
8155 else
8156 {
8157 //Save the key in ap context. Issue setkey after the BSS is started.
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -07008158 hdd_ap_ctx_t *pAPCtx = WLAN_HDD_GET_AP_CTX_PTR(pAdapter);
Jeff Johnson295189b2012-06-20 16:38:30 -07008159 vos_mem_copy(&pAPCtx->groupKey, &setKey, sizeof(tCsrRoamSetKey));
8160 }
8161 }
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -07008162 else if ( (pAdapter->device_mode == WLAN_HDD_INFRA_STATION) ||
8163 (pAdapter->device_mode == WLAN_HDD_P2P_CLIENT) )
Jeff Johnson295189b2012-06-20 16:38:30 -07008164 {
8165 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
8166 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
8167
Gopichand Nakkala3d295922013-05-07 16:19:14 +05308168#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
8169 if (!pairwise)
8170#else
8171 if (!mac_addr || is_broadcast_ether_addr(mac_addr))
8172#endif
8173 {
8174 /* set group key*/
8175 if (pHddStaCtx->roam_info.deferKeyComplete)
8176 {
8177 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
8178 "%s- %d: Perform Set key Complete",
8179 __func__, __LINE__);
8180 hdd_PerformRoamSetKeyComplete(pAdapter);
8181 }
8182 }
8183
Jeff Johnson295189b2012-06-20 16:38:30 -07008184 pWextState->roamProfile.Keys.KeyLength[key_index] = (u8)params->key_len;
8185
Venkata Prathyusha Kuntupalliee2ce712013-01-17 14:09:24 -08008186 pWextState->roamProfile.Keys.defaultIndex = key_index;
8187
8188
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -07008189 vos_mem_copy(&pWextState->roamProfile.Keys.KeyMaterial[key_index][0],
Jeff Johnson295189b2012-06-20 16:38:30 -07008190 params->key, params->key_len);
8191
Gopichand Nakkala3d295922013-05-07 16:19:14 +05308192
Jeff Johnson295189b2012-06-20 16:38:30 -07008193 pHddStaCtx->roam_info.roamingState = HDD_ROAM_STATE_SETTING_KEY;
8194
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308195 hddLog(VOS_TRACE_LEVEL_INFO_MED,
Jeff Johnson295189b2012-06-20 16:38:30 -07008196 "%s: set key for peerMac %2x:%2x:%2x:%2x:%2x:%2x, direction %d",
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308197 __func__, setKey.peerMac[0], setKey.peerMac[1],
8198 setKey.peerMac[2], setKey.peerMac[3],
8199 setKey.peerMac[4], setKey.peerMac[5],
Jeff Johnson295189b2012-06-20 16:38:30 -07008200 setKey.keyDirection);
8201
8202 vos_status = wlan_hdd_check_ula_done(pAdapter);
8203
8204 if ( vos_status != VOS_STATUS_SUCCESS )
8205 {
8206 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
8207 "[%4d] wlan_hdd_check_ula_done returned ERROR status= %d",
8208 __LINE__, vos_status );
8209
8210 pHddStaCtx->roam_info.roamingState = HDD_ROAM_STATE_NONE;
8211
Vinay Krishna Eranna6f22c1f2014-10-13 16:03:06 +05308212 status = -EINVAL;
8213 goto end;
Jeff Johnson295189b2012-06-20 16:38:30 -07008214
8215 }
8216
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -07008217#ifdef WLAN_FEATURE_VOWIFI_11R
Gopichand Nakkala3d295922013-05-07 16:19:14 +05308218 /* The supplicant may attempt to set the PTK once pre-authentication
8219 is done. Save the key in the UMAC and include it in the ADD BSS
8220 request */
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -07008221 halStatus = sme_FTUpdateKey( WLAN_HDD_GET_HAL_CTX(pAdapter), &setKey);
Gopichand Nakkala3d295922013-05-07 16:19:14 +05308222 if ( halStatus == eHAL_STATUS_FT_PREAUTH_KEY_SUCCESS )
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -07008223 {
Gopichand Nakkala3d295922013-05-07 16:19:14 +05308224 hddLog(VOS_TRACE_LEVEL_INFO_MED,
8225 "%s: Update PreAuth Key success", __func__);
Vinay Krishna Eranna6f22c1f2014-10-13 16:03:06 +05308226 status = 0;
8227 goto end;
Gopichand Nakkala3d295922013-05-07 16:19:14 +05308228 }
8229 else if ( halStatus == eHAL_STATUS_FT_PREAUTH_KEY_FAILED )
8230 {
8231 hddLog(VOS_TRACE_LEVEL_ERROR,
8232 "%s: Update PreAuth Key failed", __func__);
Vinay Krishna Eranna6f22c1f2014-10-13 16:03:06 +05308233 status = -EINVAL;
8234 goto end;
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -07008235 }
8236#endif /* WLAN_FEATURE_VOWIFI_11R */
Jeff Johnson295189b2012-06-20 16:38:30 -07008237
8238 /* issue set key request to SME*/
8239 status = sme_RoamSetKey( WLAN_HDD_GET_HAL_CTX(pAdapter),
8240 pAdapter->sessionId, &setKey, &roamId );
8241
8242 if ( 0 != status )
8243 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308244 hddLog(VOS_TRACE_LEVEL_ERROR,
Jeff Johnson295189b2012-06-20 16:38:30 -07008245 "%s: sme_RoamSetKey failed, returned %d", __func__, status);
8246 pHddStaCtx->roam_info.roamingState = HDD_ROAM_STATE_NONE;
Vinay Krishna Eranna6f22c1f2014-10-13 16:03:06 +05308247 status = -EINVAL;
8248 goto end;
Jeff Johnson295189b2012-06-20 16:38:30 -07008249 }
8250
8251
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308252 /* in case of IBSS as there was no information available about WEP keys during
8253 * IBSS join, group key intialized with NULL key, so re-initialize group key
Jeff Johnson295189b2012-06-20 16:38:30 -07008254 * with correct value*/
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308255 if ( (eCSR_BSS_TYPE_START_IBSS == pWextState->roamProfile.BSSType) &&
8256 !( ( IW_AUTH_KEY_MGMT_802_1X
8257 == (pWextState->authKeyMgmt & IW_AUTH_KEY_MGMT_802_1X))
Jeff Johnson295189b2012-06-20 16:38:30 -07008258 && (eCSR_AUTH_TYPE_OPEN_SYSTEM == pHddStaCtx->conn_info.authType)
8259 )
8260 &&
8261 ( (WLAN_CIPHER_SUITE_WEP40 == params->cipher)
8262 || (WLAN_CIPHER_SUITE_WEP104 == params->cipher)
8263 )
8264 )
8265 {
8266 setKey.keyDirection = eSIR_RX_ONLY;
8267 vos_mem_copy(setKey.peerMac,groupmacaddr,WNI_CFG_BSSID_LEN);
8268
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308269 hddLog(VOS_TRACE_LEVEL_INFO_MED,
Jeff Johnson295189b2012-06-20 16:38:30 -07008270 "%s: set key peerMac %2x:%2x:%2x:%2x:%2x:%2x, direction %d",
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308271 __func__, setKey.peerMac[0], setKey.peerMac[1],
8272 setKey.peerMac[2], setKey.peerMac[3],
8273 setKey.peerMac[4], setKey.peerMac[5],
Jeff Johnson295189b2012-06-20 16:38:30 -07008274 setKey.keyDirection);
8275
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308276 status = sme_RoamSetKey( WLAN_HDD_GET_HAL_CTX(pAdapter),
Jeff Johnson295189b2012-06-20 16:38:30 -07008277 pAdapter->sessionId, &setKey, &roamId );
8278
8279 if ( 0 != status )
8280 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308281 hddLog(VOS_TRACE_LEVEL_ERROR,
8282 "%s: sme_RoamSetKey failed for group key (IBSS), returned %d",
Jeff Johnson295189b2012-06-20 16:38:30 -07008283 __func__, status);
8284 pHddStaCtx->roam_info.roamingState = HDD_ROAM_STATE_NONE;
Vinay Krishna Eranna6f22c1f2014-10-13 16:03:06 +05308285 status = -EINVAL;
8286 goto end;
Jeff Johnson295189b2012-06-20 16:38:30 -07008287 }
8288 }
8289 }
8290
Vinay Krishna Eranna6f22c1f2014-10-13 16:03:06 +05308291end:
8292 /* Need to clear any trace of key value in the memory.
8293 * Thus zero out the memory even though it is local
8294 * variable.
8295 */
8296 vos_mem_zero(&setKey, sizeof(setKey));
8297
8298 return status;
Jeff Johnson295189b2012-06-20 16:38:30 -07008299}
8300
Mahesh A Saptasagar1a51bc02014-06-02 18:28:08 +05308301#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
8302static int wlan_hdd_cfg80211_add_key( struct wiphy *wiphy,
8303 struct net_device *ndev,
8304 u8 key_index, bool pairwise,
8305 const u8 *mac_addr,
8306 struct key_params *params
8307 )
8308#else
8309static int wlan_hdd_cfg80211_add_key( struct wiphy *wiphy,
8310 struct net_device *ndev,
8311 u8 key_index, const u8 *mac_addr,
8312 struct key_params *params
8313 )
8314#endif
8315{
8316 int ret;
8317 vos_ssr_protect(__func__);
8318#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
8319 ret = __wlan_hdd_cfg80211_add_key(wiphy, ndev, key_index, pairwise,
8320 mac_addr, params);
8321#else
8322 ret = __wlan_hdd_cfg80211_add_key(wiphy, ndev, key_index, mac_addr,
8323 params);
8324#endif
8325 vos_ssr_unprotect(__func__);
8326
8327 return ret;
8328}
8329
Jeff Johnson295189b2012-06-20 16:38:30 -07008330/*
Mahesh A Saptasagar1a51bc02014-06-02 18:28:08 +05308331 * FUNCTION: __wlan_hdd_cfg80211_get_key
Jeff Johnson295189b2012-06-20 16:38:30 -07008332 * This function is used to get the key information
8333 */
8334#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
Mahesh A Saptasagar1a51bc02014-06-02 18:28:08 +05308335static int __wlan_hdd_cfg80211_get_key(
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308336 struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -07008337 struct net_device *ndev,
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308338 u8 key_index, bool pairwise,
Jeff Johnson295189b2012-06-20 16:38:30 -07008339 const u8 *mac_addr, void *cookie,
8340 void (*callback)(void *cookie, struct key_params*)
8341 )
8342#else
Mahesh A Saptasagar1a51bc02014-06-02 18:28:08 +05308343static int __wlan_hdd_cfg80211_get_key(
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308344 struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -07008345 struct net_device *ndev,
8346 u8 key_index, const u8 *mac_addr, void *cookie,
8347 void (*callback)(void *cookie, struct key_params*)
8348 )
8349#endif
8350{
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308351 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( ndev );
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +05308352 hdd_wext_state_t *pWextState= WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
8353 tCsrRoamProfile *pRoamProfile = &(pWextState->roamProfile);
Jeff Johnson295189b2012-06-20 16:38:30 -07008354 struct key_params params;
8355
8356 ENTER();
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308357
Sushant Kaushik8bc7df22014-04-09 17:55:29 +05308358 hddLog(VOS_TRACE_LEVEL_INFO, "%s: device_mode = %s (%d)",
8359 __func__, hdd_device_modetoString(pAdapter->device_mode),
8360 pAdapter->device_mode);
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +05308361
Jeff Johnson295189b2012-06-20 16:38:30 -07008362 memset(&params, 0, sizeof(params));
8363
8364 if (CSR_MAX_NUM_KEY <= key_index)
8365 {
c_hpothu6ff1c3c2013-10-01 19:01:57 +05308366 hddLog(VOS_TRACE_LEVEL_ERROR, FL("invalid key index %d"), key_index);
Jeff Johnson295189b2012-06-20 16:38:30 -07008367 return -EINVAL;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308368 }
Jeff Johnson295189b2012-06-20 16:38:30 -07008369
8370 switch(pRoamProfile->EncryptionType.encryptionType[0])
8371 {
8372 case eCSR_ENCRYPT_TYPE_NONE:
8373 params.cipher = IW_AUTH_CIPHER_NONE;
8374 break;
8375
8376 case eCSR_ENCRYPT_TYPE_WEP40_STATICKEY:
8377 case eCSR_ENCRYPT_TYPE_WEP40:
8378 params.cipher = WLAN_CIPHER_SUITE_WEP40;
8379 break;
8380
8381 case eCSR_ENCRYPT_TYPE_WEP104_STATICKEY:
8382 case eCSR_ENCRYPT_TYPE_WEP104:
8383 params.cipher = WLAN_CIPHER_SUITE_WEP104;
8384 break;
8385
8386 case eCSR_ENCRYPT_TYPE_TKIP:
8387 params.cipher = WLAN_CIPHER_SUITE_TKIP;
8388 break;
8389
8390 case eCSR_ENCRYPT_TYPE_AES:
8391 params.cipher = WLAN_CIPHER_SUITE_AES_CMAC;
8392 break;
8393
8394 default:
8395 params.cipher = IW_AUTH_CIPHER_NONE;
8396 break;
8397 }
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +05308398
c_hpothuaaf19692014-05-17 17:01:48 +05308399 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
8400 TRACE_CODE_HDD_CFG80211_GET_KEY,
8401 pAdapter->sessionId, params.cipher));
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +05308402
Jeff Johnson295189b2012-06-20 16:38:30 -07008403 params.key_len = pRoamProfile->Keys.KeyLength[key_index];
8404 params.seq_len = 0;
8405 params.seq = NULL;
8406 params.key = &pRoamProfile->Keys.KeyMaterial[key_index][0];
8407 callback(cookie, &params);
8408 return 0;
8409}
8410
Mahesh A Saptasagar1a51bc02014-06-02 18:28:08 +05308411#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
8412static int wlan_hdd_cfg80211_get_key(
8413 struct wiphy *wiphy,
8414 struct net_device *ndev,
8415 u8 key_index, bool pairwise,
8416 const u8 *mac_addr, void *cookie,
8417 void (*callback)(void *cookie, struct key_params*)
8418 )
8419#else
8420static int wlan_hdd_cfg80211_get_key(
8421 struct wiphy *wiphy,
8422 struct net_device *ndev,
8423 u8 key_index, const u8 *mac_addr, void *cookie,
8424 void (*callback)(void *cookie, struct key_params*)
8425 )
8426#endif
8427{
8428 int ret;
8429
8430 vos_ssr_protect(__func__);
8431#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
8432 ret = __wlan_hdd_cfg80211_get_key(wiphy, ndev, key_index, pairwise,
8433 mac_addr, cookie, callback);
8434#else
8435 ret = __wlan_hdd_cfg80211_get_key(wiphy, ndev, key_index, mac_addr,
8436 callback);
8437#endif
8438 vos_ssr_unprotect(__func__);
8439
8440 return ret;
8441}
8442
Jeff Johnson295189b2012-06-20 16:38:30 -07008443/*
8444 * FUNCTION: wlan_hdd_cfg80211_del_key
8445 * This function is used to delete the key information
8446 */
8447#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308448static int wlan_hdd_cfg80211_del_key( struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -07008449 struct net_device *ndev,
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308450 u8 key_index,
8451 bool pairwise,
Jeff Johnson295189b2012-06-20 16:38:30 -07008452 const u8 *mac_addr
8453 )
8454#else
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308455static int wlan_hdd_cfg80211_del_key( struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -07008456 struct net_device *ndev,
8457 u8 key_index,
8458 const u8 *mac_addr
8459 )
8460#endif
8461{
8462 int status = 0;
8463
8464 //This code needs to be revisited. There is sme_removeKey API, we should
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308465 //plan to use that. After the change to use correct index in setkey,
Jeff Johnson295189b2012-06-20 16:38:30 -07008466 //it is observed that this is invalidating peer
8467 //key index whenever re-key is done. This is affecting data link.
8468 //It should be ok to ignore del_key.
8469#if 0
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308470 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( ndev );
8471 v_CONTEXT_t pVosContext = (WLAN_HDD_GET_CTX(pAdapter))->pvosContext;
Jeff Johnson295189b2012-06-20 16:38:30 -07008472 u8 groupmacaddr[WNI_CFG_BSSID_LEN] = {0xFF,0xFF,0xFF,0xFF,0xFF,0xFF};
8473 tCsrRoamSetKey setKey;
8474 v_U32_t roamId= 0xFF;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308475
Jeff Johnson295189b2012-06-20 16:38:30 -07008476 ENTER();
8477
8478 hddLog(VOS_TRACE_LEVEL_INFO_HIGH, "%s: device_mode = %d\n",
8479 __func__,pAdapter->device_mode);
8480
8481 if (CSR_MAX_NUM_KEY <= key_index)
8482 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308483 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Invalid key index %d", __func__,
Jeff Johnson295189b2012-06-20 16:38:30 -07008484 key_index);
8485
8486 return -EINVAL;
8487 }
8488
8489 vos_mem_zero(&setKey,sizeof(tCsrRoamSetKey));
8490 setKey.keyId = key_index;
8491
8492 if (mac_addr)
8493 vos_mem_copy(setKey.peerMac, mac_addr,WNI_CFG_BSSID_LEN);
8494 else
8495 vos_mem_copy(setKey.peerMac, groupmacaddr, WNI_CFG_BSSID_LEN);
8496
8497 setKey.encType = eCSR_ENCRYPT_TYPE_NONE;
8498
8499 if ((pAdapter->device_mode == WLAN_HDD_SOFTAP)
Jeff Johnson295189b2012-06-20 16:38:30 -07008500 || (pAdapter->device_mode == WLAN_HDD_P2P_GO)
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308501 )
8502 {
8503
8504 hdd_hostapd_state_t *pHostapdState =
Jeff Johnson295189b2012-06-20 16:38:30 -07008505 WLAN_HDD_GET_HOSTAP_STATE_PTR(pAdapter);
8506 if( pHostapdState->bssState == BSS_START)
8507 {
8508 status = WLANSAP_SetKeySta( pVosContext, &setKey);
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308509
Jeff Johnson295189b2012-06-20 16:38:30 -07008510 if ( status != eHAL_STATUS_SUCCESS )
8511 {
8512 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
8513 "[%4d] WLANSAP_SetKeySta returned ERROR status= %d",
8514 __LINE__, status );
8515 }
8516 }
8517 }
8518 else if ( (pAdapter->device_mode == WLAN_HDD_INFRA_STATION)
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308519 || (pAdapter->device_mode == WLAN_HDD_P2P_CLIENT)
Jeff Johnson295189b2012-06-20 16:38:30 -07008520 )
8521 {
8522 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
8523
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308524 pHddStaCtx->roam_info.roamingState = HDD_ROAM_STATE_SETTING_KEY;
8525
8526 hddLog(VOS_TRACE_LEVEL_INFO_MED,
Jeff Johnson295189b2012-06-20 16:38:30 -07008527 "%s: delete key for peerMac %2x:%2x:%2x:%2x:%2x:%2x",
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308528 __func__, setKey.peerMac[0], setKey.peerMac[1],
8529 setKey.peerMac[2], setKey.peerMac[3],
Jeff Johnson295189b2012-06-20 16:38:30 -07008530 setKey.peerMac[4], setKey.peerMac[5]);
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308531 if(pAdapter->sessionCtx.station.conn_info.connState ==
8532 eConnectionState_Associated)
Jeff Johnson295189b2012-06-20 16:38:30 -07008533 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308534 status = sme_RoamSetKey( WLAN_HDD_GET_HAL_CTX(pAdapter),
Jeff Johnson295189b2012-06-20 16:38:30 -07008535 pAdapter->sessionId, &setKey, &roamId );
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308536
Jeff Johnson295189b2012-06-20 16:38:30 -07008537 if ( 0 != status )
8538 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308539 hddLog(VOS_TRACE_LEVEL_ERROR,
Jeff Johnson295189b2012-06-20 16:38:30 -07008540 "%s: sme_RoamSetKey failure, returned %d",
8541 __func__, status);
8542 pHddStaCtx->roam_info.roamingState = HDD_ROAM_STATE_NONE;
8543 return -EINVAL;
8544 }
8545 }
8546 }
8547#endif
Jeff Johnsone7245742012-09-05 17:12:55 -07008548 EXIT();
Jeff Johnson295189b2012-06-20 16:38:30 -07008549 return status;
8550}
8551
8552/*
Mahesh A Saptasagar1a51bc02014-06-02 18:28:08 +05308553 * FUNCTION: __wlan_hdd_cfg80211_set_default_key
Jeff Johnson295189b2012-06-20 16:38:30 -07008554 * This function is used to set the default tx key index
8555 */
8556#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
Mahesh A Saptasagar1a51bc02014-06-02 18:28:08 +05308557static int __wlan_hdd_cfg80211_set_default_key( struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -07008558 struct net_device *ndev,
8559 u8 key_index,
8560 bool unicast, bool multicast)
8561#else
Mahesh A Saptasagar1a51bc02014-06-02 18:28:08 +05308562static int __wlan_hdd_cfg80211_set_default_key( struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -07008563 struct net_device *ndev,
8564 u8 key_index)
8565#endif
8566{
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308567 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( ndev );
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05308568 int status;
Gopichand Nakkala29149562013-05-10 21:43:41 +05308569 hdd_wext_state_t *pWextState;
8570 hdd_station_ctx_t *pHddStaCtx;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05308571 hdd_context_t *pHddCtx;
Jeff Johnson295189b2012-06-20 16:38:30 -07008572
8573 ENTER();
8574
Gopichand Nakkala29149562013-05-10 21:43:41 +05308575 if ((NULL == pAdapter))
8576 {
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +05308577 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
Gopichand Nakkala29149562013-05-10 21:43:41 +05308578 "invalid adapter");
8579 return -EINVAL;
8580 }
8581
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05308582 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
8583 TRACE_CODE_HDD_CFG80211_SET_DEFAULT_KEY,
8584 pAdapter->sessionId, key_index));
8585
Gopichand Nakkala29149562013-05-10 21:43:41 +05308586 pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
8587 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
8588
8589 if ((NULL == pWextState) || (NULL == pHddStaCtx))
8590 {
8591 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
8592 "invalid Wext state or HDD context");
8593 return -EINVAL;
8594 }
8595
Arif Hussain6d2a3322013-11-17 19:50:10 -08008596 hddLog(VOS_TRACE_LEVEL_INFO, "%s: device_mode = %d key_index = %d",
Jeff Johnson295189b2012-06-20 16:38:30 -07008597 __func__,pAdapter->device_mode, key_index);
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308598
Jeff Johnson295189b2012-06-20 16:38:30 -07008599 if (CSR_MAX_NUM_KEY <= key_index)
8600 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308601 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Invalid key index %d", __func__,
Jeff Johnson295189b2012-06-20 16:38:30 -07008602 key_index);
8603
8604 return -EINVAL;
8605 }
8606
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05308607 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
8608 status = wlan_hdd_validate_context(pHddCtx);
8609
8610 if (0 != status)
Jeff Johnson04dd8a82012-06-29 20:41:40 -07008611 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05308612 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
8613 "%s: HDD context is not valid", __func__);
8614 return status;
Jeff Johnson04dd8a82012-06-29 20:41:40 -07008615 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308616
Jeff Johnson295189b2012-06-20 16:38:30 -07008617 if ((pAdapter->device_mode == WLAN_HDD_INFRA_STATION)
Jeff Johnson295189b2012-06-20 16:38:30 -07008618 || (pAdapter->device_mode == WLAN_HDD_P2P_CLIENT)
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308619 )
Jeff Johnson295189b2012-06-20 16:38:30 -07008620 {
Gopichand Nakkala29149562013-05-10 21:43:41 +05308621 if ( (eCSR_ENCRYPT_TYPE_TKIP !=
Arif Hussain6943f522013-11-04 20:10:10 -08008622 pHddStaCtx->conn_info.ucEncryptionType) &&
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308623 (eCSR_ENCRYPT_TYPE_AES !=
Arif Hussain6943f522013-11-04 20:10:10 -08008624 pHddStaCtx->conn_info.ucEncryptionType)
Jeff Johnson295189b2012-06-20 16:38:30 -07008625 )
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308626 {
8627 /* if default key index is not same as previous one,
Jeff Johnson295189b2012-06-20 16:38:30 -07008628 * then update the default key index */
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308629
Jeff Johnson295189b2012-06-20 16:38:30 -07008630 tCsrRoamSetKey setKey;
8631 v_U32_t roamId= 0xFF;
8632 tCsrKeys *Keys = &pWextState->roamProfile.Keys;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308633
8634 hddLog(VOS_TRACE_LEVEL_INFO_HIGH, "%s: default tx key index %d",
Jeff Johnson295189b2012-06-20 16:38:30 -07008635 __func__, key_index);
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308636
Jeff Johnson295189b2012-06-20 16:38:30 -07008637 Keys->defaultIndex = (u8)key_index;
8638 vos_mem_zero(&setKey,sizeof(tCsrRoamSetKey));
8639 setKey.keyId = key_index;
8640 setKey.keyLength = Keys->KeyLength[key_index];
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308641
8642 vos_mem_copy(&setKey.Key[0],
8643 &Keys->KeyMaterial[key_index][0],
Jeff Johnson295189b2012-06-20 16:38:30 -07008644 Keys->KeyLength[key_index]);
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308645
Gopichand Nakkala29149562013-05-10 21:43:41 +05308646 setKey.keyDirection = eSIR_TX_RX;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308647
8648 vos_mem_copy(setKey.peerMac,
Jeff Johnson295189b2012-06-20 16:38:30 -07008649 &pHddStaCtx->conn_info.bssId[0],
8650 WNI_CFG_BSSID_LEN);
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308651
Gopichand Nakkala29149562013-05-10 21:43:41 +05308652 if (Keys->KeyLength[key_index] == CSR_WEP40_KEY_LEN &&
8653 pWextState->roamProfile.EncryptionType.encryptionType[0] ==
8654 eCSR_ENCRYPT_TYPE_WEP104)
8655 {
8656 /*In the case of dynamic wep supplicant hardcodes DWEP type to eCSR_ENCRYPT_TYPE_WEP104
8657 even though ap is configured for WEP-40 encryption. In this canse the key length
8658 is 5 but the encryption type is 104 hence checking the key langht(5) and encryption
8659 type(104) and switching encryption type to 40*/
8660 pWextState->roamProfile.EncryptionType.encryptionType[0] =
8661 eCSR_ENCRYPT_TYPE_WEP40;
8662 pWextState->roamProfile.mcEncryptionType.encryptionType[0] =
8663 eCSR_ENCRYPT_TYPE_WEP40;
8664 }
8665
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308666 setKey.encType =
Jeff Johnson295189b2012-06-20 16:38:30 -07008667 pWextState->roamProfile.EncryptionType.encryptionType[0];
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308668
Jeff Johnson295189b2012-06-20 16:38:30 -07008669 /* issue set key request */
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308670 status = sme_RoamSetKey( WLAN_HDD_GET_HAL_CTX(pAdapter),
Jeff Johnson295189b2012-06-20 16:38:30 -07008671 pAdapter->sessionId, &setKey, &roamId );
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308672
Jeff Johnson295189b2012-06-20 16:38:30 -07008673 if ( 0 != status )
8674 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308675 hddLog(VOS_TRACE_LEVEL_ERROR,
8676 "%s: sme_RoamSetKey failed, returned %d", __func__,
Jeff Johnson295189b2012-06-20 16:38:30 -07008677 status);
8678 return -EINVAL;
8679 }
8680 }
8681 }
8682
8683 /* In SoftAp mode setting key direction for default mode */
8684 else if ( WLAN_HDD_SOFTAP == pAdapter->device_mode )
8685 {
8686 if ( (eCSR_ENCRYPT_TYPE_TKIP !=
8687 pWextState->roamProfile.EncryptionType.encryptionType[0]) &&
8688 (eCSR_ENCRYPT_TYPE_AES !=
8689 pWextState->roamProfile.EncryptionType.encryptionType[0])
8690 )
8691 {
8692 /* Saving key direction for default key index to TX default */
8693 hdd_ap_ctx_t *pAPCtx = WLAN_HDD_GET_AP_CTX_PTR(pAdapter);
8694 pAPCtx->wepKey[key_index].keyDirection = eSIR_TX_DEFAULT;
8695 }
8696 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308697
Jeff Johnson295189b2012-06-20 16:38:30 -07008698 return status;
8699}
8700
Mahesh A Saptasagar1a51bc02014-06-02 18:28:08 +05308701#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
8702static int wlan_hdd_cfg80211_set_default_key( struct wiphy *wiphy,
8703 struct net_device *ndev,
8704 u8 key_index,
8705 bool unicast, bool multicast)
8706#else
8707static int wlan_hdd_cfg80211_set_default_key( struct wiphy *wiphy,
8708 struct net_device *ndev,
8709 u8 key_index)
8710#endif
8711{
8712 int ret;
8713 vos_ssr_protect(__func__);
8714#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
8715 ret = __wlan_hdd_cfg80211_set_default_key(wiphy, ndev, key_index, unicast,
8716 multicast);
8717#else
8718 ret = __wlan_hdd_cfg80211_set_default_key(wiphy, ndev, key_index);
8719#endif
8720 vos_ssr_unprotect(__func__);
8721
8722 return ret;
8723}
8724
Jeff Johnson295189b2012-06-20 16:38:30 -07008725/*
8726 * FUNCTION: wlan_hdd_cfg80211_inform_bss
8727 * This function is used to inform the BSS details to nl80211 interface.
8728 */
8729static struct cfg80211_bss* wlan_hdd_cfg80211_inform_bss(
8730 hdd_adapter_t *pAdapter, tCsrRoamConnectedProfile *roamProfile)
8731{
8732 struct net_device *dev = pAdapter->dev;
8733 struct wireless_dev *wdev = dev->ieee80211_ptr;
8734 struct wiphy *wiphy = wdev->wiphy;
8735 tSirBssDescription *pBssDesc = roamProfile->pBssDesc;
8736 int chan_no;
8737 int ie_length;
8738 const char *ie;
8739 unsigned int freq;
8740 struct ieee80211_channel *chan;
8741 int rssi = 0;
8742 struct cfg80211_bss *bss = NULL;
8743
8744 ENTER();
8745
8746 if( NULL == pBssDesc )
8747 {
Arif Hussain6d2a3322013-11-17 19:50:10 -08008748 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: pBssDesc is NULL", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07008749 return bss;
8750 }
8751
8752 chan_no = pBssDesc->channelId;
8753 ie_length = GET_IE_LEN_IN_BSS_DESC( pBssDesc->length );
8754 ie = ((ie_length != 0) ? (const char *)&pBssDesc->ieFields: NULL);
8755
8756 if( NULL == ie )
8757 {
Arif Hussain6d2a3322013-11-17 19:50:10 -08008758 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: IE of BSS descriptor is NULL", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07008759 return bss;
8760 }
8761
8762#if (LINUX_VERSION_CODE > KERNEL_VERSION(2,6,38))
8763 if (chan_no <= ARRAY_SIZE(hdd_channels_2_4_GHZ))
8764 {
8765 freq = ieee80211_channel_to_frequency(chan_no, IEEE80211_BAND_2GHZ);
8766 }
8767 else
8768 {
8769 freq = ieee80211_channel_to_frequency(chan_no, IEEE80211_BAND_5GHZ);
8770 }
8771#else
8772 freq = ieee80211_channel_to_frequency(chan_no);
8773#endif
8774
8775 chan = __ieee80211_get_channel(wiphy, freq);
8776
Santhosh Kumar Padmaa45fdb12014-04-15 15:54:38 +05308777 if (!chan) {
8778 hddLog(VOS_TRACE_LEVEL_ERROR, "%s chan pointer is NULL", __func__);
8779 return NULL;
8780 }
8781
Abhishek Singhaee43942014-06-16 18:55:47 +05308782 rssi = (VOS_MIN ((pBssDesc->rssi + pBssDesc->sinr), 0))*100;
Jeff Johnson295189b2012-06-20 16:38:30 -07008783
Abhishek Singhaee43942014-06-16 18:55:47 +05308784 return cfg80211_inform_bss(wiphy, chan, pBssDesc->bssId,
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308785 le64_to_cpu(*(__le64 *)pBssDesc->timeStamp),
Jeff Johnson295189b2012-06-20 16:38:30 -07008786 pBssDesc->capabilityInfo,
8787 pBssDesc->beaconInterval, ie, ie_length,
Abhishek Singhaee43942014-06-16 18:55:47 +05308788 rssi, GFP_KERNEL );
Jeff Johnson295189b2012-06-20 16:38:30 -07008789}
8790
8791
8792
8793/*
8794 * FUNCTION: wlan_hdd_cfg80211_inform_bss_frame
8795 * This function is used to inform the BSS details to nl80211 interface.
8796 */
8797struct cfg80211_bss*
8798wlan_hdd_cfg80211_inform_bss_frame( hdd_adapter_t *pAdapter,
8799 tSirBssDescription *bss_desc
8800 )
8801{
8802 /*
8803 cfg80211_inform_bss() is not updating ie field of bss entry, if entry
8804 already exists in bss data base of cfg80211 for that particular BSS ID.
8805 Using cfg80211_inform_bss_frame to update the bss entry instead of
8806 cfg80211_inform_bss, But this call expects mgmt packet as input. As of
8807 now there is no possibility to get the mgmt(probe response) frame from PE,
8808 converting bss_desc to ieee80211_mgmt(probe response) and passing to
8809 cfg80211_inform_bss_frame.
8810 */
8811 struct net_device *dev = pAdapter->dev;
8812 struct wireless_dev *wdev = dev->ieee80211_ptr;
8813 struct wiphy *wiphy = wdev->wiphy;
8814 int chan_no = bss_desc->channelId;
Madan Mohan Koyyalamudi86f629e2012-11-09 16:27:29 -08008815#ifdef WLAN_ENABLE_AGEIE_ON_SCAN_RESULTS
8816 qcom_ie_age *qie_age = NULL;
8817 int ie_length = GET_IE_LEN_IN_BSS_DESC( bss_desc->length ) + sizeof(qcom_ie_age);
8818#else
Jeff Johnson295189b2012-06-20 16:38:30 -07008819 int ie_length = GET_IE_LEN_IN_BSS_DESC( bss_desc->length );
Madan Mohan Koyyalamudi86f629e2012-11-09 16:27:29 -08008820#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07008821 const char *ie =
8822 ((ie_length != 0) ? (const char *)&bss_desc->ieFields: NULL);
8823 unsigned int freq;
8824 struct ieee80211_channel *chan;
Abhishek Singh1e2bfa32014-01-02 15:44:15 +05308825 struct ieee80211_mgmt *mgmt = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -07008826 struct cfg80211_bss *bss_status = NULL;
8827 size_t frame_len = sizeof (struct ieee80211_mgmt) + ie_length;
8828 int rssi = 0;
Wilson Yangf80a0542013-10-07 13:02:37 -07008829 hdd_context_t *pHddCtx;
8830 int status;
Jeff Johnsone7245742012-09-05 17:12:55 -07008831#ifdef WLAN_OPEN_SOURCE
8832 struct timespec ts;
8833#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07008834
Wilson Yangf80a0542013-10-07 13:02:37 -07008835 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
8836 status = wlan_hdd_validate_context(pHddCtx);
8837
8838 /*bss_update is not allowed during wlan driver loading or unloading*/
Mihir Shete18156292014-03-11 15:38:30 +05308839 if (WLAN_HDD_IS_LOAD_UNLOAD_IN_PROGRESS(pHddCtx))
Wilson Yangf80a0542013-10-07 13:02:37 -07008840 {
8841 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
8842 "%s:Loading_unloading in Progress. Ignore!!!",__func__);
8843 return NULL;
8844 }
8845
8846
8847 if (0 != status)
8848 {
8849 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
8850 "%s: HDD context is not valid", __func__);
Madan Mohan Koyyalamudi2e5c9142012-11-02 13:17:48 -07008851 return NULL;
Wilson Yangf80a0542013-10-07 13:02:37 -07008852 }
8853
Abhishek Singh1e2bfa32014-01-02 15:44:15 +05308854 mgmt = kzalloc((sizeof (struct ieee80211_mgmt) + ie_length), GFP_KERNEL);
Wilson Yangf80a0542013-10-07 13:02:37 -07008855 if (!mgmt)
8856 {
8857 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
8858 "%s: memory allocation failed ", __func__);
8859 return NULL;
8860 }
Madan Mohan Koyyalamudi2e5c9142012-11-02 13:17:48 -07008861
Jeff Johnson295189b2012-06-20 16:38:30 -07008862 memcpy(mgmt->bssid, bss_desc->bssId, ETH_ALEN);
Jeff Johnsone7245742012-09-05 17:12:55 -07008863
8864#ifdef WLAN_OPEN_SOURCE
8865 /* Android does not want the timestamp from the frame.
8866 Instead it wants a monotonic increasing value */
8867 get_monotonic_boottime(&ts);
8868 mgmt->u.probe_resp.timestamp =
8869 ((u64)ts.tv_sec * 1000000) + (ts.tv_nsec / 1000);
8870#else
8871 /* keep old behavior for non-open source (for now) */
Jeff Johnson295189b2012-06-20 16:38:30 -07008872 memcpy(&mgmt->u.probe_resp.timestamp, bss_desc->timeStamp,
8873 sizeof (bss_desc->timeStamp));
Jeff Johnsone7245742012-09-05 17:12:55 -07008874
8875#endif
8876
Jeff Johnson295189b2012-06-20 16:38:30 -07008877 mgmt->u.probe_resp.beacon_int = bss_desc->beaconInterval;
8878 mgmt->u.probe_resp.capab_info = bss_desc->capabilityInfo;
Madan Mohan Koyyalamudi86f629e2012-11-09 16:27:29 -08008879
8880#ifdef WLAN_ENABLE_AGEIE_ON_SCAN_RESULTS
8881 /* GPS Requirement: need age ie per entry. Using vendor specific. */
8882 /* Assuming this is the last IE, copy at the end */
8883 ie_length -=sizeof(qcom_ie_age);
8884 qie_age = (qcom_ie_age *)(mgmt->u.probe_resp.variable + ie_length);
8885 qie_age->element_id = QCOM_VENDOR_IE_ID;
8886 qie_age->len = QCOM_VENDOR_IE_AGE_LEN;
8887 qie_age->oui_1 = QCOM_OUI1;
8888 qie_age->oui_2 = QCOM_OUI2;
8889 qie_age->oui_3 = QCOM_OUI3;
8890 qie_age->type = QCOM_VENDOR_IE_AGE_TYPE;
8891 qie_age->age = vos_timer_get_system_ticks() - bss_desc->nReceivedTime;
8892#endif
8893
Jeff Johnson295189b2012-06-20 16:38:30 -07008894 memcpy(mgmt->u.probe_resp.variable, ie, ie_length);
Gopichand Nakkalad908ec82013-05-16 19:32:19 +05308895 if (bss_desc->fProbeRsp)
8896 {
8897 mgmt->frame_control |=
8898 (u16)(IEEE80211_FTYPE_MGMT | IEEE80211_STYPE_PROBE_RESP);
8899 }
8900 else
8901 {
8902 mgmt->frame_control |=
8903 (u16)(IEEE80211_FTYPE_MGMT | IEEE80211_STYPE_BEACON);
8904 }
Jeff Johnson295189b2012-06-20 16:38:30 -07008905
8906#if (LINUX_VERSION_CODE > KERNEL_VERSION(2,6,38))
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308907 if (chan_no <= ARRAY_SIZE(hdd_channels_2_4_GHZ) &&
Jeff Johnson295189b2012-06-20 16:38:30 -07008908 (wiphy->bands[IEEE80211_BAND_2GHZ] != NULL))
8909 {
8910 freq = ieee80211_channel_to_frequency(chan_no, IEEE80211_BAND_2GHZ);
8911 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308912 else if ((chan_no > ARRAY_SIZE(hdd_channels_2_4_GHZ)) &&
Jeff Johnson295189b2012-06-20 16:38:30 -07008913 (wiphy->bands[IEEE80211_BAND_5GHZ] != NULL))
8914
8915 {
8916 freq = ieee80211_channel_to_frequency(chan_no, IEEE80211_BAND_5GHZ);
8917 }
8918 else
8919 {
Nirav Shah20ac06f2013-12-12 18:14:06 +05308920 hddLog(VOS_TRACE_LEVEL_ERROR, "%s Invalid chan_no:%d",
8921 __func__, chan_no);
Jeff Johnson295189b2012-06-20 16:38:30 -07008922 kfree(mgmt);
8923 return NULL;
8924 }
8925#else
8926 freq = ieee80211_channel_to_frequency(chan_no);
8927#endif
8928 chan = __ieee80211_get_channel(wiphy, freq);
Leela V Kiran Kumar Reddy90032de2013-01-24 18:33:30 -08008929 /*when the band is changed on the fly using the GUI, three things are done
8930 * 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)
8931 * as part of the scan abort, message willbe queued to PE and we proceed with flushing and changinh the band.
8932 * pe will stop the scanning further and report back the results what ever it had till now by calling the call back function.
8933 * if the time between update band and scandone call back is sufficent enough the band change reflects in SME, SME validates the channels
8934 * and discards the channels correponding to previous band and calls back with zero bss results.
8935 * 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
8936 * all the channels correponding to previous band.this is due to race condition.but those channels are invalid to the new band and so
8937 * this function __ieee80211_get_channel will return NULL.Each time we report scan result with this pointer null warning kernel trace is printed.
8938 * if the scan results contain large number of APs continuosly kernel warning trace is printed and it will lead to apps watch dog bark.
8939 * So drop the bss and continue to next bss.
8940 */
8941 if(chan == NULL)
8942 {
Nirav Shah20ac06f2013-12-12 18:14:06 +05308943 hddLog(VOS_TRACE_LEVEL_ERROR, "%s chan pointer is NULL", __func__);
Chilam Ngc4244af2013-04-01 15:37:32 -07008944 kfree(mgmt);
Leela V Kiran Kumar Reddy90032de2013-01-24 18:33:30 -08008945 return NULL;
8946 }
Jeff Johnson295189b2012-06-20 16:38:30 -07008947 /*To keep the rssi icon of the connected AP in the scan window
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308948 *and the rssi icon of the wireless networks in sync
Jeff Johnson295189b2012-06-20 16:38:30 -07008949 * */
8950 if (( eConnectionState_Associated ==
8951 pAdapter->sessionCtx.station.conn_info.connState ) &&
8952 ( VOS_TRUE == vos_mem_compare(bss_desc->bssId,
8953 pAdapter->sessionCtx.station.conn_info.bssId,
8954 WNI_CFG_BSSID_LEN)))
8955 {
8956 /* supplicant takes the signal strength in terms of mBm(100*dBm) */
8957 rssi = (pAdapter->rssi * 100);
8958 }
8959 else
8960 {
8961 rssi = (VOS_MIN ((bss_desc->rssi + bss_desc->sinr), 0))*100;
8962 }
8963
Nirav Shah20ac06f2013-12-12 18:14:06 +05308964 hddLog(VOS_TRACE_LEVEL_INFO, "%s: BSSID:" MAC_ADDRESS_STR " Channel:%d"
8965 "RSSI:%d", __func__, MAC_ADDR_ARRAY(mgmt->bssid),
8966 chan->center_freq, (int)(rssi/100));
8967
Jeff Johnson295189b2012-06-20 16:38:30 -07008968 bss_status = cfg80211_inform_bss_frame(wiphy, chan, mgmt,
8969 frame_len, rssi, GFP_KERNEL);
8970 kfree(mgmt);
8971 return bss_status;
8972}
8973
8974/*
8975 * FUNCTION: wlan_hdd_cfg80211_update_bss_db
8976 * This function is used to update the BSS data base of CFG8011
8977 */
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308978struct cfg80211_bss* wlan_hdd_cfg80211_update_bss_db( hdd_adapter_t *pAdapter,
Jeff Johnson295189b2012-06-20 16:38:30 -07008979 tCsrRoamInfo *pRoamInfo
8980 )
8981{
8982 tCsrRoamConnectedProfile roamProfile;
8983 tHalHandle hHal = WLAN_HDD_GET_HAL_CTX(pAdapter);
8984 struct cfg80211_bss *bss = NULL;
8985
8986 ENTER();
8987
8988 memset(&roamProfile, 0, sizeof(tCsrRoamConnectedProfile));
8989 sme_RoamGetConnectProfile(hHal, pAdapter->sessionId, &roamProfile);
8990
8991 if (NULL != roamProfile.pBssDesc)
8992 {
Girish Gowlif4b68022014-08-28 23:18:57 +05308993 bss = wlan_hdd_cfg80211_inform_bss_frame(pAdapter,
8994 roamProfile.pBssDesc);
Jeff Johnson295189b2012-06-20 16:38:30 -07008995
8996 if (NULL == bss)
8997 {
8998 hddLog(VOS_TRACE_LEVEL_INFO, "%s: cfg80211_inform_bss return NULL",
8999 __func__);
9000 }
9001
9002 sme_RoamFreeConnectProfile(hHal, &roamProfile);
9003 }
9004 else
9005 {
9006 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: roamProfile.pBssDesc is NULL",
9007 __func__);
9008 }
9009 return bss;
9010}
9011
9012/*
9013 * FUNCTION: wlan_hdd_cfg80211_update_bss
9014 */
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309015static int wlan_hdd_cfg80211_update_bss( struct wiphy *wiphy,
9016 hdd_adapter_t *pAdapter
Jeff Johnson295189b2012-06-20 16:38:30 -07009017 )
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309018{
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +05309019 tHalHandle hHal = WLAN_HDD_GET_HAL_CTX(pAdapter);
Jeff Johnson295189b2012-06-20 16:38:30 -07009020 tCsrScanResultInfo *pScanResult;
9021 eHalStatus status = 0;
9022 tScanResultHandle pResult;
9023 struct cfg80211_bss *bss_status = NULL;
Wilson Yangf80a0542013-10-07 13:02:37 -07009024 hdd_context_t *pHddCtx;
Jeff Johnson295189b2012-06-20 16:38:30 -07009025
9026 ENTER();
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +05309027
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05309028 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
9029 TRACE_CODE_HDD_CFG80211_UPDATE_BSS,
9030 NO_SESSION, pAdapter->sessionId));
9031
Wilson Yangf80a0542013-10-07 13:02:37 -07009032 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
9033
9034 if (pHddCtx->isLogpInProgress)
Jeff Johnson295189b2012-06-20 16:38:30 -07009035 {
Wilson Yangf80a0542013-10-07 13:02:37 -07009036 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
9037 "%s:LOGP in Progress. Ignore!!!",__func__);
9038 return -EAGAIN;
Jeff Johnson295189b2012-06-20 16:38:30 -07009039 }
9040
Wilson Yangf80a0542013-10-07 13:02:37 -07009041
9042 /*bss_update is not allowed during wlan driver loading or unloading*/
Mihir Shete18156292014-03-11 15:38:30 +05309043 if (WLAN_HDD_IS_LOAD_UNLOAD_IN_PROGRESS(pHddCtx))
Wilson Yangf80a0542013-10-07 13:02:37 -07009044 {
9045 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
9046 "%s:Loading_unloading in Progress. Ignore!!!",__func__);
9047 return VOS_STATUS_E_PERM;
9048 }
9049
9050
Jeff Johnson295189b2012-06-20 16:38:30 -07009051 /*
9052 * start getting scan results and populate cgf80211 BSS database
9053 */
9054 status = sme_ScanGetResult(hHal, pAdapter->sessionId, NULL, &pResult);
9055
9056 /* no scan results */
9057 if (NULL == pResult)
9058 {
Nirav Shah20ac06f2013-12-12 18:14:06 +05309059 hddLog(VOS_TRACE_LEVEL_INFO, "%s: No scan result Status %d",
9060 __func__, status);
Jeff Johnson295189b2012-06-20 16:38:30 -07009061 return status;
9062 }
9063
9064 pScanResult = sme_ScanResultGetFirst(hHal, pResult);
9065
9066 while (pScanResult)
9067 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309068 /*
9069 * cfg80211_inform_bss() is not updating ie field of bss entry, if
9070 * entry already exists in bss data base of cfg80211 for that
9071 * particular BSS ID. Using cfg80211_inform_bss_frame to update the
9072 * bss entry instead of cfg80211_inform_bss, But this call expects
9073 * mgmt packet as input. As of now there is no possibility to get
9074 * the mgmt(probe response) frame from PE, converting bss_desc to
Jeff Johnson295189b2012-06-20 16:38:30 -07009075 * ieee80211_mgmt(probe response) and passing to c
9076 * fg80211_inform_bss_frame.
9077 * */
9078
9079 bss_status = wlan_hdd_cfg80211_inform_bss_frame(pAdapter,
9080 &pScanResult->BssDescriptor);
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309081
Jeff Johnson295189b2012-06-20 16:38:30 -07009082
9083 if (NULL == bss_status)
9084 {
9085 hddLog(VOS_TRACE_LEVEL_INFO,
Arif Hussain6d2a3322013-11-17 19:50:10 -08009086 "%s: NULL returned by cfg80211_inform_bss", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07009087 }
9088 else
9089 {
Yue Maf49ba872013-08-19 12:04:25 -07009090 cfg80211_put_bss(
9091#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,9,0))
9092 wiphy,
9093#endif
9094 bss_status);
Jeff Johnson295189b2012-06-20 16:38:30 -07009095 }
9096
9097 pScanResult = sme_ScanResultGetNext(hHal, pResult);
9098 }
9099
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309100 sme_ScanResultPurge(hHal, pResult);
Jeff Johnson295189b2012-06-20 16:38:30 -07009101
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309102 return 0;
Jeff Johnson295189b2012-06-20 16:38:30 -07009103}
9104
Jeff Johnson04dd8a82012-06-29 20:41:40 -07009105void
9106hddPrintMacAddr(tCsrBssid macAddr, tANI_U8 logLevel)
9107{
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309108 VOS_TRACE(VOS_MODULE_ID_HDD, logLevel,
Arif Hussaina7c8e412013-11-20 11:06:42 -08009109 MAC_ADDRESS_STR, MAC_ADDR_ARRAY(macAddr));
Jeff Johnson04dd8a82012-06-29 20:41:40 -07009110} /****** end hddPrintMacAddr() ******/
9111
9112void
Madan Mohan Koyyalamudic75be962012-10-18 19:19:03 -07009113hddPrintPmkId(tANI_U8 *pmkId, tANI_U8 logLevel)
Jeff Johnson04dd8a82012-06-29 20:41:40 -07009114{
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309115 VOS_TRACE(VOS_MODULE_ID_HDD, logLevel,
Arif Hussain6d2a3322013-11-17 19:50:10 -08009116 "%02X:%02X:%02X:%02X:%02X:%02X:%02X:%02X:%02X:%02X:%02X:%02X:%02X:%02X:%02X:%02X",
Madan Mohan Koyyalamudic75be962012-10-18 19:19:03 -07009117 pmkId[0], pmkId[1], pmkId[2], pmkId[3], pmkId[4],
9118 pmkId[5], pmkId[6], pmkId[7], pmkId[8], pmkId[9], pmkId[10],
9119 pmkId[11], pmkId[12], pmkId[13], pmkId[14], pmkId[15]);
Jeff Johnson04dd8a82012-06-29 20:41:40 -07009120} /****** end hddPrintPmkId() ******/
9121
9122//hddPrintMacAddr(tCsrBssid macAddr, tANI_U8 logLevel);
9123//hddPrintMacAddr(macAddr, VOS_TRACE_LEVEL_FATAL);
9124
9125//void sirDumpBuf(tpAniSirGlobal pMac, tANI_U8 modId, tANI_U32 level, tANI_U8 *buf, tANI_U32 size);
9126//sirDumpBuf(pMac, VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL, pmkid, 16);
9127
9128#define dump_bssid(bssid) \
9129 { \
Jeff Johnsone7245742012-09-05 17:12:55 -07009130 hddLog(VOS_TRACE_LEVEL_INFO, "BSSID (MAC) address:\t"); \
9131 hddPrintMacAddr(bssid, VOS_TRACE_LEVEL_INFO);\
Jeff Johnson04dd8a82012-06-29 20:41:40 -07009132 }
9133
9134#define dump_pmkid(pMac, pmkid) \
9135 { \
Jeff Johnsone7245742012-09-05 17:12:55 -07009136 hddLog(VOS_TRACE_LEVEL_INFO, "PMKSA-ID:\t"); \
9137 hddPrintPmkId(pmkid, VOS_TRACE_LEVEL_INFO);\
Jeff Johnson04dd8a82012-06-29 20:41:40 -07009138 }
9139
Madan Mohan Koyyalamudi1b4afb02012-10-22 15:25:16 -07009140#if defined(FEATURE_WLAN_LFR) && (LINUX_VERSION_CODE >= KERNEL_VERSION(3,4,0))
Jeff Johnson04dd8a82012-06-29 20:41:40 -07009141/*
9142 * FUNCTION: wlan_hdd_cfg80211_pmksa_candidate_notify
9143 * This function is used to notify the supplicant of a new PMKSA candidate.
9144 */
9145int wlan_hdd_cfg80211_pmksa_candidate_notify(
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309146 hdd_adapter_t *pAdapter, tCsrRoamInfo *pRoamInfo,
Jeff Johnson04dd8a82012-06-29 20:41:40 -07009147 int index, bool preauth )
9148{
Jeff Johnsone7245742012-09-05 17:12:55 -07009149#ifdef FEATURE_WLAN_OKC
Jeff Johnson04dd8a82012-06-29 20:41:40 -07009150 struct net_device *dev = pAdapter->dev;
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07009151 hdd_context_t *pHddCtx = (hdd_context_t*)pAdapter->pHddCtx;
Jeff Johnson04dd8a82012-06-29 20:41:40 -07009152
9153 ENTER();
Jeff Johnsone7245742012-09-05 17:12:55 -07009154 hddLog(VOS_TRACE_LEVEL_INFO, "%s is going to notify supplicant of:", __func__);
Jeff Johnson04dd8a82012-06-29 20:41:40 -07009155
9156 if( NULL == pRoamInfo )
9157 {
Arif Hussain6d2a3322013-11-17 19:50:10 -08009158 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: pRoamInfo is NULL", __func__);
Jeff Johnson04dd8a82012-06-29 20:41:40 -07009159 return -EINVAL;
9160 }
9161
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07009162 if (eANI_BOOLEAN_TRUE == hdd_is_okc_mode_enabled(pHddCtx))
9163 {
9164 dump_bssid(pRoamInfo->bssid);
9165 cfg80211_pmksa_candidate_notify(dev, index,
Jeff Johnson04dd8a82012-06-29 20:41:40 -07009166 pRoamInfo->bssid, preauth, GFP_KERNEL);
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07009167 }
Jeff Johnsone7245742012-09-05 17:12:55 -07009168#endif /* FEATURE_WLAN_OKC */
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309169 return 0;
Jeff Johnson04dd8a82012-06-29 20:41:40 -07009170}
9171#endif //FEATURE_WLAN_LFR
9172
Yue Maef608272013-04-08 23:09:17 -07009173#ifdef FEATURE_WLAN_LFR_METRICS
9174/*
9175 * FUNCTION: wlan_hdd_cfg80211_roam_metrics_preauth
9176 * 802.11r/LFR metrics reporting function to report preauth initiation
9177 *
9178 */
9179#define MAX_LFR_METRICS_EVENT_LENGTH 100
9180VOS_STATUS wlan_hdd_cfg80211_roam_metrics_preauth(hdd_adapter_t *pAdapter,
9181 tCsrRoamInfo *pRoamInfo)
9182{
9183 unsigned char metrics_notification[MAX_LFR_METRICS_EVENT_LENGTH + 1];
9184 union iwreq_data wrqu;
9185
9186 ENTER();
9187
9188 if (NULL == pAdapter)
9189 {
9190 hddLog(LOGE, "%s: pAdapter is NULL!", __func__);
9191 return VOS_STATUS_E_FAILURE;
9192 }
9193
9194 /* create the event */
9195 memset(&wrqu, 0, sizeof(wrqu));
9196 memset(metrics_notification, 0, sizeof(metrics_notification));
9197
9198 wrqu.data.pointer = metrics_notification;
9199 wrqu.data.length = scnprintf(metrics_notification,
9200 sizeof(metrics_notification), "QCOM: LFR_PREAUTH_INIT "
9201 MAC_ADDRESS_STR, MAC_ADDR_ARRAY(pRoamInfo->bssid));
9202
9203 wireless_send_event(pAdapter->dev, IWEVCUSTOM, &wrqu, metrics_notification);
9204
9205 EXIT();
9206
9207 return VOS_STATUS_SUCCESS;
9208}
9209
9210/*
9211 * FUNCTION: wlan_hdd_cfg80211_roam_metrics_preauth_status
9212 * 802.11r/LFR metrics reporting function to report preauth completion
9213 * or failure
9214 */
9215VOS_STATUS wlan_hdd_cfg80211_roam_metrics_preauth_status(
9216 hdd_adapter_t *pAdapter, tCsrRoamInfo *pRoamInfo, bool preauth_status)
9217{
9218 unsigned char metrics_notification[MAX_LFR_METRICS_EVENT_LENGTH + 1];
9219 union iwreq_data wrqu;
9220
9221 ENTER();
9222
9223 if (NULL == pAdapter)
9224 {
9225 hddLog(LOGE, "%s: pAdapter is NULL!", __func__);
9226 return VOS_STATUS_E_FAILURE;
9227 }
9228
9229 /* create the event */
9230 memset(&wrqu, 0, sizeof(wrqu));
9231 memset(metrics_notification, 0, sizeof(metrics_notification));
9232
9233 scnprintf(metrics_notification, sizeof(metrics_notification),
9234 "QCOM: LFR_PREAUTH_STATUS "MAC_ADDRESS_STR,
9235 MAC_ADDR_ARRAY(pRoamInfo->bssid));
9236
9237 if (1 == preauth_status)
9238 strncat(metrics_notification, " TRUE", 5);
9239 else
9240 strncat(metrics_notification, " FALSE", 6);
9241
9242 wrqu.data.pointer = metrics_notification;
9243 wrqu.data.length = strlen(metrics_notification);
9244
9245 wireless_send_event(pAdapter->dev, IWEVCUSTOM, &wrqu, metrics_notification);
9246
9247 EXIT();
9248
9249 return VOS_STATUS_SUCCESS;
9250}
9251
9252/*
9253 * FUNCTION: wlan_hdd_cfg80211_roam_metrics_handover
9254 * 802.11r/LFR metrics reporting function to report handover initiation
9255 *
9256 */
9257VOS_STATUS wlan_hdd_cfg80211_roam_metrics_handover(hdd_adapter_t * pAdapter,
9258 tCsrRoamInfo *pRoamInfo)
9259{
9260 unsigned char metrics_notification[MAX_LFR_METRICS_EVENT_LENGTH + 1];
9261 union iwreq_data wrqu;
9262
9263 ENTER();
9264
9265 if (NULL == pAdapter)
9266 {
9267 hddLog(LOGE, "%s: pAdapter is NULL!", __func__);
9268 return VOS_STATUS_E_FAILURE;
9269 }
9270
9271 /* create the event */
9272 memset(&wrqu, 0, sizeof(wrqu));
9273 memset(metrics_notification, 0, sizeof(metrics_notification));
9274
9275 wrqu.data.pointer = metrics_notification;
9276 wrqu.data.length = scnprintf(metrics_notification,
9277 sizeof(metrics_notification), "QCOM: LFR_PREAUTH_HANDOVER "
9278 MAC_ADDRESS_STR, MAC_ADDR_ARRAY(pRoamInfo->bssid));
9279
9280 wireless_send_event(pAdapter->dev, IWEVCUSTOM, &wrqu, metrics_notification);
9281
9282 EXIT();
9283
9284 return VOS_STATUS_SUCCESS;
9285}
9286#endif
9287
Jeff Johnson295189b2012-06-20 16:38:30 -07009288/*
9289 * FUNCTION: hdd_cfg80211_scan_done_callback
9290 * scanning callback function, called after finishing scan
9291 *
9292 */
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309293static eHalStatus hdd_cfg80211_scan_done_callback(tHalHandle halHandle,
Jeff Johnson295189b2012-06-20 16:38:30 -07009294 void *pContext, tANI_U32 scanId, eCsrScanStatus status)
9295{
9296 struct net_device *dev = (struct net_device *) pContext;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309297 //struct wireless_dev *wdev = dev->ieee80211_ptr;
Jeff Johnson295189b2012-06-20 16:38:30 -07009298 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( dev );
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -07009299 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
9300 hdd_scaninfo_t *pScanInfo = &pHddCtx->scan_info;
Jeff Johnson295189b2012-06-20 16:38:30 -07009301 struct cfg80211_scan_request *req = NULL;
9302 int ret = 0;
Mahesh A Saptasagar05a357e2014-02-26 16:28:06 +05309303 bool aborted = false;
c_hpothu6ff1c3c2013-10-01 19:01:57 +05309304 long waitRet = 0;
Jeff Johnson295189b2012-06-20 16:38:30 -07009305
9306 ENTER();
9307
9308 hddLog(VOS_TRACE_LEVEL_INFO,
9309 "%s called with halHandle = %p, pContext = %p,"
Arif Hussain6d2a3322013-11-17 19:50:10 -08009310 "scanID = %d, returned status = %d",
Jeff Johnson295189b2012-06-20 16:38:30 -07009311 __func__, halHandle, pContext, (int) scanId, (int) status);
9312
Kiet Lamac06e2c2013-10-23 16:25:07 +05309313 pScanInfo->mScanPendingCounter = 0;
9314
Jeff Johnson295189b2012-06-20 16:38:30 -07009315 //Block on scan req completion variable. Can't wait forever though.
c_hpothu6ff1c3c2013-10-01 19:01:57 +05309316 waitRet = wait_for_completion_interruptible_timeout(
Jeff Johnson295189b2012-06-20 16:38:30 -07009317 &pScanInfo->scan_req_completion_event,
9318 msecs_to_jiffies(WLAN_WAIT_TIME_SCAN_REQ));
c_hpothu6ff1c3c2013-10-01 19:01:57 +05309319 if (waitRet <= 0)
Jeff Johnson295189b2012-06-20 16:38:30 -07009320 {
c_hpothu6ff1c3c2013-10-01 19:01:57 +05309321 hddLog(VOS_TRACE_LEVEL_ERROR,
9322 "%s wait on scan_req_completion_event failed %ld",__func__, waitRet);
Jeff Johnson295189b2012-06-20 16:38:30 -07009323 VOS_ASSERT(pScanInfo->mScanPending);
Jeff Johnsone7245742012-09-05 17:12:55 -07009324 goto allow_suspend;
Jeff Johnson295189b2012-06-20 16:38:30 -07009325 }
9326
Yue Maef608272013-04-08 23:09:17 -07009327 if (pScanInfo->mScanPending != VOS_TRUE)
Jeff Johnson295189b2012-06-20 16:38:30 -07009328 {
9329 VOS_ASSERT(pScanInfo->mScanPending);
Jeff Johnsone7245742012-09-05 17:12:55 -07009330 goto allow_suspend;
Jeff Johnson295189b2012-06-20 16:38:30 -07009331 }
9332
9333 /* Check the scanId */
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309334 if (pScanInfo->scanId != scanId)
Jeff Johnson295189b2012-06-20 16:38:30 -07009335 {
9336 hddLog(VOS_TRACE_LEVEL_INFO,
9337 "%s called with mismatched scanId pScanInfo->scanId = %d "
Arif Hussain6d2a3322013-11-17 19:50:10 -08009338 "scanId = %d", __func__, (int) pScanInfo->scanId,
Jeff Johnson295189b2012-06-20 16:38:30 -07009339 (int) scanId);
9340 }
9341
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309342 ret = wlan_hdd_cfg80211_update_bss((WLAN_HDD_GET_CTX(pAdapter))->wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -07009343 pAdapter);
9344
9345 if (0 > ret)
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309346 hddLog(VOS_TRACE_LEVEL_INFO, "%s: NO SCAN result", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07009347
9348
9349 /* If any client wait scan result through WEXT
9350 * send scan done event to client */
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -07009351 if (pHddCtx->scan_info.waitScanResult)
Jeff Johnson295189b2012-06-20 16:38:30 -07009352 {
9353 /* The other scan request waiting for current scan finish
9354 * Send event to notify current scan finished */
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -07009355 if(WEXT_SCAN_PENDING_DELAY == pHddCtx->scan_info.scan_pending_option)
Jeff Johnson295189b2012-06-20 16:38:30 -07009356 {
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -07009357 vos_event_set(&pHddCtx->scan_info.scan_finished_event);
Jeff Johnson295189b2012-06-20 16:38:30 -07009358 }
9359 /* Send notify to WEXT client */
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -07009360 else if(WEXT_SCAN_PENDING_PIGGYBACK == pHddCtx->scan_info.scan_pending_option)
Jeff Johnson295189b2012-06-20 16:38:30 -07009361 {
9362 struct net_device *dev = pAdapter->dev;
9363 union iwreq_data wrqu;
9364 int we_event;
9365 char *msg;
9366
9367 memset(&wrqu, '\0', sizeof(wrqu));
9368 we_event = SIOCGIWSCAN;
9369 msg = NULL;
9370 wireless_send_event(dev, we_event, &wrqu, msg);
9371 }
9372 }
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -07009373 pHddCtx->scan_info.waitScanResult = FALSE;
Jeff Johnson295189b2012-06-20 16:38:30 -07009374
9375 /* Get the Scan Req */
9376 req = pAdapter->request;
9377
9378 if (!req)
9379 {
Arif Hussain6d2a3322013-11-17 19:50:10 -08009380 hddLog(VOS_TRACE_LEVEL_ERROR, "request is became NULL");
Madan Mohan Koyyalamudi9f5a10c2012-09-28 14:46:16 -07009381 pScanInfo->mScanPending = VOS_FALSE;
Jeff Johnsone7245742012-09-05 17:12:55 -07009382 goto allow_suspend;
Jeff Johnson295189b2012-06-20 16:38:30 -07009383 }
9384
9385 /*
9386 * setting up 0, just in case.
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309387 */
Jeff Johnson295189b2012-06-20 16:38:30 -07009388 req->n_ssids = 0;
9389 req->n_channels = 0;
9390 req->ie = 0;
9391
Jeff Johnson295189b2012-06-20 16:38:30 -07009392 pAdapter->request = NULL;
Jeff Johnsone7245742012-09-05 17:12:55 -07009393 /* Scan is no longer pending */
9394 pScanInfo->mScanPending = VOS_FALSE;
Jeff Johnson295189b2012-06-20 16:38:30 -07009395
Madan Mohan Koyyalamudib764bf82012-10-11 16:38:51 -07009396 /*
9397 * cfg80211_scan_done informing NL80211 about completion
9398 * of scanning
9399 */
Mahesh A Saptasagar05a357e2014-02-26 16:28:06 +05309400 if (status == eCSR_SCAN_ABORT || status == eCSR_SCAN_FAILURE)
9401 {
9402 aborted = true;
9403 }
9404 cfg80211_scan_done(req, aborted);
Madan Mohan Koyyalamudif4e81002012-11-13 10:46:38 -08009405 complete(&pScanInfo->abortscan_event_var);
Jeff Johnson295189b2012-06-20 16:38:30 -07009406
Siddharth Bhal76972212014-10-15 16:22:51 +05309407 if (pHddCtx->spoofMacAddr.isEnabled || pHddCtx->spoofMacAddr.isReqDeferred) {
9408 /* Generate new random mac addr for next scan */
9409 hddLog(VOS_TRACE_LEVEL_INFO, "scan completed - generate new spoof mac addr");
9410 hdd_processSpoofMacAddrRequest(pHddCtx);
9411 }
9412
Jeff Johnsone7245742012-09-05 17:12:55 -07009413allow_suspend:
Madan Mohan Koyyalamudi9f5a10c2012-09-28 14:46:16 -07009414 /* release the wake lock at the end of the scan*/
9415 hdd_allow_suspend();
Jeff Johnsone7245742012-09-05 17:12:55 -07009416
Madan Mohan Koyyalamudi10d83a92012-09-28 15:47:05 -07009417 /* Acquire wakelock to handle the case where APP's tries to suspend
9418 * immediatly after the driver gets connect request(i.e after scan)
9419 * from supplicant, this result in app's is suspending and not able
9420 * to process the connect request to AP */
Mahesh A Saptasagarb9c50402014-01-16 15:49:22 +05309421 hdd_prevent_suspend_timeout(1000);
Madan Mohan Koyyalamudi10d83a92012-09-28 15:47:05 -07009422
Gopichand Nakkala638ebc72013-03-21 18:04:02 -07009423#ifdef FEATURE_WLAN_TDLS
c_hpothu3c8f8e82014-06-02 18:01:50 +05309424 if (!(eTDLS_SUPPORT_NOT_ENABLED == pHddCtx->tdls_mode))
9425 {
9426 wlan_hdd_tdls_scan_done_callback(pAdapter);
9427 }
Gopichand Nakkala638ebc72013-03-21 18:04:02 -07009428#endif
9429
Jeff Johnson295189b2012-06-20 16:38:30 -07009430 EXIT();
9431 return 0;
9432}
9433
9434/*
Rashmi Ramannab1429032014-04-26 14:59:09 +05309435 * FUNCTION: hdd_isConnectionInProgress
9436 * Go through each adapter and check if Connection is in progress
Madan Mohan Koyyalamudicfd53742013-01-11 15:29:03 -08009437 *
9438 */
Ganesh Kondabattiniaeb7b772014-08-11 20:00:36 +05309439v_BOOL_t hdd_isConnectionInProgress( hdd_context_t *pHddCtx, v_BOOL_t isRoC )
Madan Mohan Koyyalamudicfd53742013-01-11 15:29:03 -08009440{
9441 hdd_adapter_list_node_t *pAdapterNode = NULL, *pNext = NULL;
9442 hdd_station_ctx_t *pHddStaCtx = NULL;
9443 hdd_adapter_t *pAdapter = NULL;
9444 VOS_STATUS status = 0;
9445 v_U8_t staId = 0;
9446 v_U8_t *staMac = NULL;
9447
c_hpothu9b781ba2013-12-30 20:57:45 +05309448 if (TRUE == pHddCtx->btCoexModeSet)
9449 {
9450 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Rashmi Ramannab1429032014-04-26 14:59:09 +05309451 FL("BTCoex Mode operation in progress"));
9452 return VOS_TRUE;
c_hpothu9b781ba2013-12-30 20:57:45 +05309453 }
9454
Madan Mohan Koyyalamudicfd53742013-01-11 15:29:03 -08009455 status = hdd_get_front_adapter ( pHddCtx, &pAdapterNode );
9456
9457 while ( NULL != pAdapterNode && VOS_STATUS_SUCCESS == status )
9458 {
9459 pAdapter = pAdapterNode->pAdapter;
9460
9461 if( pAdapter )
9462 {
9463 hddLog(VOS_TRACE_LEVEL_INFO,
Sushant Kaushik8bc7df22014-04-09 17:55:29 +05309464 "%s: Adapter with device mode %s (%d) exists",
9465 __func__, hdd_device_modetoString(pAdapter->device_mode),
9466 pAdapter->device_mode);
Ganesh Kondabattiniaeb7b772014-08-11 20:00:36 +05309467 if ((((!isRoC) && (WLAN_HDD_INFRA_STATION == pAdapter->device_mode)) ||
Rashmi Ramannab1429032014-04-26 14:59:09 +05309468 (WLAN_HDD_P2P_CLIENT == pAdapter->device_mode) ||
9469 (WLAN_HDD_P2P_DEVICE == pAdapter->device_mode)) &&
9470 (eConnectionState_Connecting ==
9471 (WLAN_HDD_GET_STATION_CTX_PTR(pAdapter))->conn_info.connState))
9472 {
9473 hddLog(VOS_TRACE_LEVEL_ERROR,
9474 "%s: %p(%d) Connection is in progress", __func__,
9475 WLAN_HDD_GET_STATION_CTX_PTR(pAdapter), pAdapter->sessionId);
9476 return VOS_TRUE;
9477 }
Ganesh Kondabattiniaeb7b772014-08-11 20:00:36 +05309478 if (((!isRoC) && (WLAN_HDD_INFRA_STATION == pAdapter->device_mode)) ||
Sushant Kaushik8bc7df22014-04-09 17:55:29 +05309479 (WLAN_HDD_P2P_CLIENT == pAdapter->device_mode) ||
9480 (WLAN_HDD_P2P_DEVICE == pAdapter->device_mode))
Madan Mohan Koyyalamudicfd53742013-01-11 15:29:03 -08009481 {
9482 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
9483 if ((eConnectionState_Associated == pHddStaCtx->conn_info.connState) &&
Sushant Kaushik8bc7df22014-04-09 17:55:29 +05309484 (VOS_FALSE == pHddStaCtx->conn_info.uIsAuthenticated))
Madan Mohan Koyyalamudicfd53742013-01-11 15:29:03 -08009485 {
9486 staMac = (v_U8_t *) &(pAdapter->macAddressCurrent.bytes[0]);
9487 hddLog(VOS_TRACE_LEVEL_ERROR,
Arif Hussain24bafea2013-11-15 15:10:03 -08009488 "%s: client " MAC_ADDRESS_STR
9489 " is in the middle of WPS/EAPOL exchange.", __func__,
9490 MAC_ADDR_ARRAY(staMac));
Rashmi Ramannab1429032014-04-26 14:59:09 +05309491 return VOS_TRUE;
Madan Mohan Koyyalamudicfd53742013-01-11 15:29:03 -08009492 }
9493 }
9494 else if ((WLAN_HDD_SOFTAP == pAdapter->device_mode) ||
9495 (WLAN_HDD_P2P_GO == pAdapter->device_mode))
9496 {
9497 for (staId = 0; staId < WLAN_MAX_STA_COUNT; staId++)
9498 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309499 if ((pAdapter->aStaInfo[staId].isUsed) &&
Madan Mohan Koyyalamudicfd53742013-01-11 15:29:03 -08009500 (WLANTL_STA_CONNECTED == pAdapter->aStaInfo[staId].tlSTAState))
9501 {
9502 staMac = (v_U8_t *) &(pAdapter->aStaInfo[staId].macAddrSTA.bytes[0]);
9503
9504 hddLog(VOS_TRACE_LEVEL_ERROR,
Arif Hussain24bafea2013-11-15 15:10:03 -08009505 "%s: client " MAC_ADDRESS_STR " of SoftAP/P2P-GO is in the "
9506 "middle of WPS/EAPOL exchange.", __func__,
9507 MAC_ADDR_ARRAY(staMac));
Rashmi Ramannab1429032014-04-26 14:59:09 +05309508 return VOS_TRUE;
Madan Mohan Koyyalamudicfd53742013-01-11 15:29:03 -08009509 }
9510 }
9511 }
9512 }
9513 status = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
9514 pAdapterNode = pNext;
9515 }
Rashmi Ramannab1429032014-04-26 14:59:09 +05309516 return VOS_FALSE;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309517}
Madan Mohan Koyyalamudicfd53742013-01-11 15:29:03 -08009518
9519/*
Mahesh A Saptasagarfafb7fe2014-05-16 13:19:37 +05309520 * FUNCTION: __wlan_hdd_cfg80211_scan
Jeff Johnson295189b2012-06-20 16:38:30 -07009521 * this scan respond to scan trigger and update cfg80211 scan database
9522 * later, scan dump command can be used to recieve scan results
9523 */
Mahesh A Saptasagarfafb7fe2014-05-16 13:19:37 +05309524int __wlan_hdd_cfg80211_scan( struct wiphy *wiphy,
Jeff Johnson3bbe4bf2013-01-18 17:05:29 -08009525#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,6,0))
9526 struct net_device *dev,
9527#endif
9528 struct cfg80211_scan_request *request)
9529{
Siddharth Bhal0c162d02014-05-06 19:50:42 +05309530 hdd_adapter_t *pAdapter = NULL;
9531 hdd_context_t *pHddCtx = NULL;
9532 hdd_wext_state_t *pwextBuf = NULL;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05309533 hdd_config_t *cfg_param = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -07009534 tCsrScanRequest scanRequest;
9535 tANI_U8 *channelList = NULL, i;
9536 v_U32_t scanId = 0;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05309537 int status;
9538 hdd_scaninfo_t *pScanInfo = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -07009539 v_U8_t* pP2pIe = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -07009540
Siddharth Bhal0c162d02014-05-06 19:50:42 +05309541#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,6,0))
9542 struct net_device *dev = NULL;
9543 if (NULL == request)
9544 {
9545 hddLog(VOS_TRACE_LEVEL_ERROR,
9546 "%s: scan req param null", __func__);
9547 return -EINVAL;
9548 }
9549 dev = request->wdev->netdev;
9550#endif
9551
9552 pAdapter = WLAN_HDD_GET_PRIV_PTR( dev );
9553 pHddCtx = WLAN_HDD_GET_CTX( pAdapter );
9554 pwextBuf = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
9555
Jeff Johnson295189b2012-06-20 16:38:30 -07009556 ENTER();
9557
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +05309558
Sushant Kaushik8bc7df22014-04-09 17:55:29 +05309559 hddLog(VOS_TRACE_LEVEL_INFO, "%s: device_mode = %s (%d)",
9560 __func__, hdd_device_modetoString(pAdapter->device_mode),
9561 pAdapter->device_mode);
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +05309562
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05309563 status = wlan_hdd_validate_context(pHddCtx);
9564
9565 if (0 != status)
9566 {
9567 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
9568 "%s: HDD context is not valid", __func__);
9569 return status;
9570 }
9571
Siddharth Bhal0c162d02014-05-06 19:50:42 +05309572 if (NULL == pwextBuf)
9573 {
9574 hddLog (VOS_TRACE_LEVEL_ERROR, "%s ERROR: invalid WEXT state\n",
9575 __func__);
9576 return -EIO;
9577 }
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05309578 cfg_param = pHddCtx->cfg_ini;
9579 pScanInfo = &pHddCtx->scan_info;
9580
Jeff Johnson295189b2012-06-20 16:38:30 -07009581#ifdef WLAN_BTAMP_FEATURE
9582 //Scan not supported when AMP traffic is on.
Gopichand Nakkala681989c2013-03-06 22:27:48 -08009583 if (VOS_TRUE == WLANBAP_AmpSessionOn())
Jeff Johnson295189b2012-06-20 16:38:30 -07009584 {
Madan Mohan Koyyalamudifd4e1da2012-11-09 17:50:19 -08009585 hddLog(VOS_TRACE_LEVEL_ERROR,
Jeff Johnson295189b2012-06-20 16:38:30 -07009586 "%s: No scanning when AMP is on", __func__);
9587 return -EOPNOTSUPP;
9588 }
9589#endif
9590 //Scan on any other interface is not supported.
Gopichand Nakkala681989c2013-03-06 22:27:48 -08009591 if (pAdapter->device_mode == WLAN_HDD_SOFTAP)
Jeff Johnson295189b2012-06-20 16:38:30 -07009592 {
Gopichand Nakkala681989c2013-03-06 22:27:48 -08009593 hddLog(VOS_TRACE_LEVEL_ERROR,
Sushant Kaushik8bc7df22014-04-09 17:55:29 +05309594 "%s: Not scanning on device_mode = %s (%d)",
9595 __func__, hdd_device_modetoString(pAdapter->device_mode),
9596 pAdapter->device_mode);
Jeff Johnson295189b2012-06-20 16:38:30 -07009597 return -EOPNOTSUPP;
9598 }
9599
9600 if (TRUE == pScanInfo->mScanPending)
9601 {
Kiet Lamac06e2c2013-10-23 16:25:07 +05309602 if ( MAX_PENDING_LOG > pScanInfo->mScanPendingCounter++ )
9603 {
9604 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: mScanPending is TRUE", __func__);
9605 }
Gopichand Nakkala681989c2013-03-06 22:27:48 -08009606 return -EBUSY;
Jeff Johnson295189b2012-06-20 16:38:30 -07009607 }
9608
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309609 //Don't Allow Scan and return busy if Remain On
Jeff Johnson32d95a32012-09-10 13:15:23 -07009610 //Channel and action frame is pending
9611 //Otherwise Cancel Remain On Channel and allow Scan
9612 //If no action frame pending
Gopichand Nakkala681989c2013-03-06 22:27:48 -08009613 if (0 != wlan_hdd_check_remain_on_channel(pAdapter))
Jeff Johnson32d95a32012-09-10 13:15:23 -07009614 {
Kiet Lamac06e2c2013-10-23 16:25:07 +05309615 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Remain On Channel Pending", __func__);
Jeff Johnson32d95a32012-09-10 13:15:23 -07009616 return -EBUSY;
9617 }
Gopichand Nakkala681989c2013-03-06 22:27:48 -08009618#ifdef FEATURE_WLAN_TDLS
Gopichand Nakkala638ebc72013-03-21 18:04:02 -07009619 /* if tdls disagree scan right now, return immediately.
9620 tdls will schedule the scan when scan is allowed. (return SUCCESS)
9621 or will reject the scan if any TDLS is in progress. (return -EBUSY)
9622 */
9623 status = wlan_hdd_tdls_scan_callback (pAdapter,
9624 wiphy,
9625#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,6,0))
9626 dev,
Gopichand Nakkalac3c42b92013-03-20 19:42:34 -07009627#endif
Gopichand Nakkala638ebc72013-03-21 18:04:02 -07009628 request);
9629 if(status <= 0)
9630 {
Nirav Shah20ac06f2013-12-12 18:14:06 +05309631 if(!status)
9632 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: TDLS in progress."
9633 "scan rejected %d", __func__, status);
9634 else
9635 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: TDLS teardown is ongoing %d",
9636 __func__, status);
9637
Gopichand Nakkala638ebc72013-03-21 18:04:02 -07009638 return status;
Gopichand Nakkala681989c2013-03-06 22:27:48 -08009639 }
9640#endif
Jeff Johnson32d95a32012-09-10 13:15:23 -07009641
Jeff Johnson295189b2012-06-20 16:38:30 -07009642 if (mutex_lock_interruptible(&pHddCtx->tmInfo.tmOperationLock))
9643 {
9644 VOS_TRACE(VOS_MODULE_ID_HDD,VOS_TRACE_LEVEL_ERROR,
Jeff Johnson1250df42012-12-10 14:31:52 -08009645 "%s: Acquire lock fail", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07009646 return -EAGAIN;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309647 }
Jeff Johnson295189b2012-06-20 16:38:30 -07009648 if (TRUE == pHddCtx->tmInfo.tmAction.enterImps)
9649 {
Nirav Shah20ac06f2013-12-12 18:14:06 +05309650 hddLog(VOS_TRACE_LEVEL_ERROR,
Jeff Johnson295189b2012-06-20 16:38:30 -07009651 "%s: MAX TM Level Scan not allowed", __func__);
9652 mutex_unlock(&pHddCtx->tmInfo.tmOperationLock);
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309653 return -EBUSY;
Jeff Johnson295189b2012-06-20 16:38:30 -07009654 }
9655 mutex_unlock(&pHddCtx->tmInfo.tmOperationLock);
9656
Madan Mohan Koyyalamudicfd53742013-01-11 15:29:03 -08009657 /* Check if scan is allowed at this point of time.
9658 */
Ganesh Kondabattiniaeb7b772014-08-11 20:00:36 +05309659 if (hdd_isConnectionInProgress(pHddCtx, VOS_FALSE))
Madan Mohan Koyyalamudicfd53742013-01-11 15:29:03 -08009660 {
9661 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Scan not allowed", __func__);
9662 return -EBUSY;
9663 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309664
Jeff Johnson295189b2012-06-20 16:38:30 -07009665 vos_mem_zero( &scanRequest, sizeof(scanRequest));
9666
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +05309667 hddLog(VOS_TRACE_LEVEL_INFO, "scan request for ssid = %d",
9668 (int)request->n_ssids);
9669
9670 /* Even though supplicant doesn't provide any SSIDs, n_ssids is set to 1.
9671 * Becasue of this, driver is assuming that this is not wildcard scan and so
9672 * is not aging out the scan results.
9673 */
9674 if (request->ssids && '\0' == request->ssids->ssid[0])
Jeff Johnson295189b2012-06-20 16:38:30 -07009675 {
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +05309676 request->n_ssids = 0;
Jeff Johnson295189b2012-06-20 16:38:30 -07009677 }
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +05309678
9679 if ((request->ssids) && (0 < request->n_ssids))
9680 {
9681 tCsrSSIDInfo *SsidInfo;
9682 int j;
9683 scanRequest.SSIDs.numOfSSIDs = request->n_ssids;
9684 /* Allocate num_ssid tCsrSSIDInfo structure */
9685 SsidInfo = scanRequest.SSIDs.SSIDList =
9686 ( tCsrSSIDInfo *)vos_mem_malloc(
9687 request->n_ssids*sizeof(tCsrSSIDInfo));
9688
9689 if(NULL == scanRequest.SSIDs.SSIDList)
9690 {
9691 hddLog(VOS_TRACE_LEVEL_ERROR,
9692 "%s: memory alloc failed SSIDInfo buffer", __func__);
9693 return -ENOMEM;
9694 }
9695
9696 /* copy all the ssid's and their length */
9697 for(j = 0; j < request->n_ssids; j++, SsidInfo++)
9698 {
9699 /* get the ssid length */
9700 SsidInfo->SSID.length = request->ssids[j].ssid_len;
9701 vos_mem_copy(SsidInfo->SSID.ssId, &request->ssids[j].ssid[0],
9702 SsidInfo->SSID.length);
9703 SsidInfo->SSID.ssId[SsidInfo->SSID.length] = '\0';
9704 hddLog(VOS_TRACE_LEVEL_INFO, "SSID number %d: %s",
9705 j, SsidInfo->SSID.ssId);
9706 }
9707 /* set the scan type to active */
9708 scanRequest.scanType = eSIR_ACTIVE_SCAN;
9709 }
9710 else if(WLAN_HDD_P2P_GO == pAdapter->device_mode)
Jeff Johnson295189b2012-06-20 16:38:30 -07009711 {
Siddharth Bhal0c162d02014-05-06 19:50:42 +05309712 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
9713 TRACE_CODE_HDD_CFG80211_SCAN,
9714 pAdapter->sessionId, 0));
Jeff Johnson295189b2012-06-20 16:38:30 -07009715 /* set the scan type to active */
9716 scanRequest.scanType = eSIR_ACTIVE_SCAN;
Jeff Johnson295189b2012-06-20 16:38:30 -07009717 }
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +05309718 else
9719 {
9720 /*Set the scan type to default type, in this case it is ACTIVE*/
9721 scanRequest.scanType = pScanInfo->scan_mode;
9722 }
9723 scanRequest.minChnTime = cfg_param->nActiveMinChnTime;
9724 scanRequest.maxChnTime = cfg_param->nActiveMaxChnTime;
Jeff Johnson295189b2012-06-20 16:38:30 -07009725
9726 /* set BSSType to default type */
9727 scanRequest.BSSType = eCSR_BSS_TYPE_ANY;
9728
9729 /*TODO: scan the requested channels only*/
9730
9731 /*Right now scanning all the channels */
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +05309732 if (MAX_CHANNEL < request->n_channels)
Jeff Johnson295189b2012-06-20 16:38:30 -07009733 {
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +05309734 hddLog(VOS_TRACE_LEVEL_WARN,
9735 "No of Scan Channels exceeded limit: %d", request->n_channels);
9736 request->n_channels = MAX_CHANNEL;
9737 }
9738
9739 hddLog(VOS_TRACE_LEVEL_INFO,
9740 "No of Scan Channels: %d", request->n_channels);
9741
9742
9743 if( request->n_channels )
9744 {
9745 char chList [(request->n_channels*5)+1];
9746 int len;
9747 channelList = vos_mem_malloc( request->n_channels );
9748 if( NULL == channelList )
c_hpothu53512302014-04-15 18:49:53 +05309749 {
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +05309750 hddLog(VOS_TRACE_LEVEL_ERROR,
9751 "%s: memory alloc failed channelList", __func__);
9752 status = -ENOMEM;
9753 goto free_mem;
c_hpothu53512302014-04-15 18:49:53 +05309754 }
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +05309755
9756 for( i = 0, len = 0; i < request->n_channels ; i++ )
9757 {
9758 channelList[i] = request->channels[i]->hw_value;
9759 len += snprintf(chList+len, 5, "%d ", channelList[i]);
9760 }
9761
Nirav Shah20ac06f2013-12-12 18:14:06 +05309762 hddLog(VOS_TRACE_LEVEL_INFO,
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +05309763 "Channel-List: %s ", chList);
9764 }
c_hpothu53512302014-04-15 18:49:53 +05309765
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +05309766 scanRequest.ChannelInfo.numOfChannels = request->n_channels;
9767 scanRequest.ChannelInfo.ChannelList = channelList;
9768
9769 /* set requestType to full scan */
9770 scanRequest.requestType = eCSR_SCAN_REQUEST_FULL_SCAN;
9771
9772 /* Flush the scan results(only p2p beacons) for STA scan and P2P
9773 * search (Flush on both full scan and social scan but not on single
9774 * channel scan).P2P search happens on 3 social channels (1, 6, 11)
9775 */
9776
9777 /* Supplicant does single channel scan after 8-way handshake
9778 * and in that case driver shoudnt flush scan results. If
9779 * driver flushes the scan results here and unfortunately if
9780 * the AP doesnt respond to our probe req then association
9781 * fails which is not desired
9782 */
9783
9784 if( request->n_channels != WLAN_HDD_P2P_SINGLE_CHANNEL_SCAN )
9785 {
9786 hddLog(VOS_TRACE_LEVEL_DEBUG, "Flushing P2P Results");
9787 sme_ScanFlushP2PResult( WLAN_HDD_GET_HAL_CTX(pAdapter),
9788 pAdapter->sessionId );
9789 }
9790
9791 if( request->ie_len )
9792 {
9793 /* save this for future association (join requires this) */
9794 /*TODO: Array needs to be converted to dynamic allocation,
9795 * as multiple ie.s can be sent in cfg80211_scan_request structure
9796 * CR 597966
9797 */
9798 memset( &pScanInfo->scanAddIE, 0, sizeof(pScanInfo->scanAddIE) );
9799 memcpy( pScanInfo->scanAddIE.addIEdata, request->ie, request->ie_len);
9800 pScanInfo->scanAddIE.length = request->ie_len;
9801
9802 if ((WLAN_HDD_INFRA_STATION == pAdapter->device_mode) ||
9803 (WLAN_HDD_P2P_CLIENT == pAdapter->device_mode) ||
9804 (WLAN_HDD_P2P_DEVICE == pAdapter->device_mode))
Jeff Johnson295189b2012-06-20 16:38:30 -07009805 {
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +05309806 if ( request->ie_len <= SIR_MAC_MAX_IE_LENGTH)
Jeff Johnson295189b2012-06-20 16:38:30 -07009807 {
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +05309808 pwextBuf->roamProfile.nAddIEScanLength = request->ie_len;
9809 memcpy( pwextBuf->roamProfile.addIEScan,
9810 request->ie, request->ie_len);
9811 }
9812 else
9813 {
9814 hddLog(VOS_TRACE_LEVEL_ERROR, "Scan Ie length is invalid:"
9815 "%zu", request->ie_len);
Jeff Johnson295189b2012-06-20 16:38:30 -07009816 }
9817
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +05309818 }
9819 scanRequest.uIEFieldLen = pScanInfo->scanAddIE.length;
9820 scanRequest.pIEField = pScanInfo->scanAddIE.addIEdata;
9821
9822 pP2pIe = wlan_hdd_get_p2p_ie_ptr((v_U8_t*)request->ie,
9823 request->ie_len);
9824 if (pP2pIe != NULL)
9825 {
9826#ifdef WLAN_FEATURE_P2P_DEBUG
9827 if (((globalP2PConnectionStatus == P2P_GO_NEG_COMPLETED) ||
9828 (globalP2PConnectionStatus == P2P_GO_NEG_PROCESS)) &&
9829 (WLAN_HDD_P2P_CLIENT == pAdapter->device_mode))
Nirav Shah20ac06f2013-12-12 18:14:06 +05309830 {
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +05309831 globalP2PConnectionStatus = P2P_CLIENT_CONNECTING_STATE_1;
9832 hddLog(VOS_TRACE_LEVEL_ERROR,"[P2P State] Changing state from "
9833 "Go nego completed to Connection is started");
9834 hddLog(VOS_TRACE_LEVEL_ERROR,"[P2P]P2P Scanning is started "
9835 "for 8way Handshake");
Nirav Shah20ac06f2013-12-12 18:14:06 +05309836 }
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +05309837 else if((globalP2PConnectionStatus == P2P_CLIENT_DISCONNECTED_STATE) &&
9838 (WLAN_HDD_P2P_CLIENT == pAdapter->device_mode))
Jeff Johnson295189b2012-06-20 16:38:30 -07009839 {
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +05309840 globalP2PConnectionStatus = P2P_CLIENT_CONNECTING_STATE_2;
9841 hddLog(VOS_TRACE_LEVEL_ERROR,"[P2P State] Changing state from "
9842 "Disconnected state to Connection is started");
9843 hddLog(VOS_TRACE_LEVEL_ERROR,"[P2P]P2P Scanning is started "
9844 "for 4way Handshake");
9845 }
9846#endif
9847
9848 /* no_cck will be set during p2p find to disable 11b rates */
9849 if(TRUE == request->no_cck)
9850 {
9851 hddLog(VOS_TRACE_LEVEL_INFO,
9852 "%s: This is a P2P Search", __func__);
9853 scanRequest.p2pSearch = 1;
9854
9855 if( request->n_channels == WLAN_HDD_P2P_SOCIAL_CHANNELS )
Agarwal Ashish4f616132013-12-30 23:32:50 +05309856 {
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +05309857 /* set requestType to P2P Discovery */
9858 scanRequest.requestType = eCSR_SCAN_P2P_DISCOVERY;
9859 }
9860
9861 /*
9862 Skip Dfs Channel in case of P2P Search
9863 if it is set in ini file
9864 */
9865 if(cfg_param->skipDfsChnlInP2pSearch)
9866 {
9867 scanRequest.skipDfsChnlInP2pSearch = 1;
Agarwal Ashish4f616132013-12-30 23:32:50 +05309868 }
9869 else
9870 {
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +05309871 scanRequest.skipDfsChnlInP2pSearch = 0;
Agarwal Ashish4f616132013-12-30 23:32:50 +05309872 }
Jeff Johnson295189b2012-06-20 16:38:30 -07009873
Agarwal Ashish4f616132013-12-30 23:32:50 +05309874 }
Jeff Johnson295189b2012-06-20 16:38:30 -07009875 }
9876 }
9877
9878 INIT_COMPLETION(pScanInfo->scan_req_completion_event);
9879
Madan Mohan Koyyalamudi9f5a10c2012-09-28 14:46:16 -07009880 /* acquire the wakelock to avoid the apps suspend during the scan. To
9881 * address the following issues.
9882 * 1) Disconnected scenario: we are not allowing the suspend as WLAN is not in
9883 * BMPS/IMPS this result in android trying to suspend aggressively and backing off
9884 * for long time, this result in apps running at full power for long time.
9885 * 2) Connected scenario: If we allow the suspend during the scan, RIVA will
9886 * be stuck in full power because of resume BMPS
9887 */
9888 hdd_prevent_suspend();
Jeff Johnsone7245742012-09-05 17:12:55 -07009889
Nirav Shah20ac06f2013-12-12 18:14:06 +05309890 hddLog(VOS_TRACE_LEVEL_INFO_HIGH,
9891 "requestType %d, scanType %d, minChnTime %d, maxChnTime %d,"
Sushant Kaushik8bc7df22014-04-09 17:55:29 +05309892 "p2pSearch %d, skipDfsChnlInP2pSearch %d",
9893 scanRequest.requestType, scanRequest.scanType,
9894 scanRequest.minChnTime, scanRequest.maxChnTime,
Nirav Shah20ac06f2013-12-12 18:14:06 +05309895 scanRequest.p2pSearch, scanRequest.skipDfsChnlInP2pSearch);
9896
Siddharth Bhal76972212014-10-15 16:22:51 +05309897 if (pHddCtx->spoofMacAddr.isEnabled)
9898 {
9899 hddLog(VOS_TRACE_LEVEL_INFO,
9900 "%s: MAC Spoofing enabled for current scan", __func__);
9901 /* Updating SelfSta Mac Addr in TL which will be used to get staidx
9902 * to fill TxBds for probe request during current scan
9903 */
9904 WLANTL_updateSpoofMacAddr(pHddCtx->pvosContext,
9905 &pHddCtx->spoofMacAddr.randomMacAddr, &pAdapter->macAddressCurrent);
9906 }
9907
Jeff Johnsone7245742012-09-05 17:12:55 -07009908 status = sme_ScanRequest( WLAN_HDD_GET_HAL_CTX(pAdapter),
Jeff Johnson295189b2012-06-20 16:38:30 -07009909 pAdapter->sessionId, &scanRequest, &scanId,
9910 &hdd_cfg80211_scan_done_callback, dev );
Jeff Johnsone7245742012-09-05 17:12:55 -07009911
Jeff Johnson295189b2012-06-20 16:38:30 -07009912 if (eHAL_STATUS_SUCCESS != status)
9913 {
9914 hddLog(VOS_TRACE_LEVEL_ERROR,
9915 "%s: sme_ScanRequest returned error %d", __func__, status);
9916 complete(&pScanInfo->scan_req_completion_event);
Madan Mohan Koyyalamudi3b230fe2012-10-18 14:46:32 -07009917 if(eHAL_STATUS_RESOURCES == status)
9918 {
Nirav Shah20ac06f2013-12-12 18:14:06 +05309919 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: HO is in progress."
9920 "So defer the scan by informing busy",__func__);
Madan Mohan Koyyalamudi3b230fe2012-10-18 14:46:32 -07009921 status = -EBUSY;
9922 } else {
9923 status = -EIO;
9924 }
Madan Mohan Koyyalamudi9f5a10c2012-09-28 14:46:16 -07009925 hdd_allow_suspend();
Jeff Johnson295189b2012-06-20 16:38:30 -07009926 goto free_mem;
9927 }
9928
9929 pScanInfo->mScanPending = TRUE;
Kaushik, Sushant4975a572014-10-21 16:07:48 +05309930 pScanInfo->sessionId = pAdapter->sessionId;
Jeff Johnson295189b2012-06-20 16:38:30 -07009931 pAdapter->request = request;
9932 pScanInfo->scanId = scanId;
9933
9934 complete(&pScanInfo->scan_req_completion_event);
9935
9936free_mem:
9937 if( scanRequest.SSIDs.SSIDList )
9938 {
9939 vos_mem_free(scanRequest.SSIDs.SSIDList);
9940 }
9941
9942 if( channelList )
9943 vos_mem_free( channelList );
9944
9945 EXIT();
9946
9947 return status;
9948}
9949
Mahesh A Saptasagarfafb7fe2014-05-16 13:19:37 +05309950int wlan_hdd_cfg80211_scan( struct wiphy *wiphy,
9951#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,6,0))
9952 struct net_device *dev,
9953#endif
9954 struct cfg80211_scan_request *request)
9955{
9956 int ret;
9957
9958 vos_ssr_protect(__func__);
9959 ret = __wlan_hdd_cfg80211_scan(wiphy,
9960#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,6,0))
9961 dev,
9962#endif
9963 request);
9964 vos_ssr_unprotect(__func__);
9965
9966 return ret;
9967}
Shailender Karmuchi15cd0672013-05-15 19:50:04 -07009968
9969void hdd_select_cbmode( hdd_adapter_t *pAdapter,v_U8_t operationChannel)
9970{
9971 v_U8_t iniDot11Mode =
9972 (WLAN_HDD_GET_CTX(pAdapter))->cfg_ini->dot11Mode;
9973 eHddDot11Mode hddDot11Mode = iniDot11Mode;
9974
Arun Kumar Khandavalli94a2bb02013-12-28 19:17:25 +05309975 hddLog(LOG1, FL("Channel Bonding Mode Selected is %u"),
9976 iniDot11Mode);
Shailender Karmuchi15cd0672013-05-15 19:50:04 -07009977 switch ( iniDot11Mode )
9978 {
9979 case eHDD_DOT11_MODE_AUTO:
9980 case eHDD_DOT11_MODE_11ac:
9981 case eHDD_DOT11_MODE_11ac_ONLY:
9982#ifdef WLAN_FEATURE_11AC
Abhishek Singh4b1d2352014-08-01 21:59:28 +05309983 if ( sme_IsFeatureSupportedByDriver(DOT11AC) &&
9984 sme_IsFeatureSupportedByFW(DOT11AC) )
9985 hddDot11Mode = eHDD_DOT11_MODE_11ac;
9986 else
9987 hddDot11Mode = eHDD_DOT11_MODE_11n;
Shailender Karmuchi15cd0672013-05-15 19:50:04 -07009988#else
9989 hddDot11Mode = eHDD_DOT11_MODE_11n;
9990#endif
9991 break;
9992 case eHDD_DOT11_MODE_11n:
9993 case eHDD_DOT11_MODE_11n_ONLY:
9994 hddDot11Mode = eHDD_DOT11_MODE_11n;
9995 break;
9996 default:
9997 hddDot11Mode = iniDot11Mode;
9998 break;
9999 }
10000 /* This call decides required channel bonding mode */
10001 sme_SelectCBMode((WLAN_HDD_GET_CTX(pAdapter)->hHal),
10002 hdd_cfg_xlate_to_csr_phy_mode(hddDot11Mode),
10003 operationChannel);
10004}
10005
Jeff Johnson295189b2012-06-20 16:38:30 -070010006/*
10007 * FUNCTION: wlan_hdd_cfg80211_connect_start
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010008 * This function is used to start the association process
Jeff Johnson295189b2012-06-20 16:38:30 -070010009 */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010010int wlan_hdd_cfg80211_connect_start( hdd_adapter_t *pAdapter,
Jeff Johnson32d95a32012-09-10 13:15:23 -070010011 const u8 *ssid, size_t ssid_len, const u8 *bssid, u8 operatingChannel)
Jeff Johnson295189b2012-06-20 16:38:30 -070010012{
10013 int status = 0;
10014 hdd_wext_state_t *pWextState;
Yue Mae36e3552014-03-05 17:06:20 -080010015 hdd_context_t *pHddCtx;
Jeff Johnson295189b2012-06-20 16:38:30 -070010016 v_U32_t roamId;
10017 tCsrRoamProfile *pRoamProfile;
Jeff Johnson295189b2012-06-20 16:38:30 -070010018 eCsrAuthType RSNAuthType;
10019
10020 ENTER();
10021
10022 pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
Yue Mae36e3552014-03-05 17:06:20 -080010023 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
10024
10025 status = wlan_hdd_validate_context(pHddCtx);
10026 if (status)
10027 {
10028 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
10029 "%s: HDD context is not valid!", __func__);
10030 return status;
10031 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010032
Jeff Johnson295189b2012-06-20 16:38:30 -070010033 if (SIR_MAC_MAX_SSID_LENGTH < ssid_len)
10034 {
10035 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: wrong SSID len", __func__);
10036 return -EINVAL;
10037 }
10038
10039 pRoamProfile = &pWextState->roamProfile;
10040
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010041 if (pRoamProfile)
Jeff Johnson295189b2012-06-20 16:38:30 -070010042 {
Jeff Johnsone7245742012-09-05 17:12:55 -070010043 hdd_station_ctx_t *pHddStaCtx;
10044 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
Jeff Johnson295189b2012-06-20 16:38:30 -070010045
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010046 if (HDD_WMM_USER_MODE_NO_QOS ==
Jeff Johnson295189b2012-06-20 16:38:30 -070010047 (WLAN_HDD_GET_CTX(pAdapter))->cfg_ini->WmmMode)
10048 {
10049 /*QoS not enabled in cfg file*/
10050 pRoamProfile->uapsd_mask = 0;
10051 }
10052 else
10053 {
10054 /*QoS enabled, update uapsd mask from cfg file*/
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010055 pRoamProfile->uapsd_mask =
Jeff Johnson295189b2012-06-20 16:38:30 -070010056 (WLAN_HDD_GET_CTX(pAdapter))->cfg_ini->UapsdMask;
10057 }
10058
10059 pRoamProfile->SSIDs.numOfSSIDs = 1;
10060 pRoamProfile->SSIDs.SSIDList->SSID.length = ssid_len;
10061 vos_mem_zero(pRoamProfile->SSIDs.SSIDList->SSID.ssId,
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010062 sizeof(pRoamProfile->SSIDs.SSIDList->SSID.ssId));
Jeff Johnson295189b2012-06-20 16:38:30 -070010063 vos_mem_copy((void *)(pRoamProfile->SSIDs.SSIDList->SSID.ssId),
10064 ssid, ssid_len);
10065
10066 if (bssid)
10067 {
10068 pRoamProfile->BSSIDs.numOfBSSIDs = 1;
10069 vos_mem_copy((void *)(pRoamProfile->BSSIDs.bssid), bssid,
10070 WNI_CFG_BSSID_LEN);
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010071 /* Save BSSID in seperate variable as well, as RoamProfile
10072 BSSID is getting zeroed out in the association process. And in
Jeff Johnson295189b2012-06-20 16:38:30 -070010073 case of join failure we should send valid BSSID to supplicant
10074 */
10075 vos_mem_copy((void *)(pWextState->req_bssId), bssid,
10076 WNI_CFG_BSSID_LEN);
10077 }
Dhanashri Atre51981c62013-06-13 11:47:57 -070010078 else
10079 {
10080 vos_mem_zero((void *)(pRoamProfile->BSSIDs.bssid),WNI_CFG_BSSID_LEN);
10081 }
Jeff Johnson295189b2012-06-20 16:38:30 -070010082
Arun Kumar Khandavalli94a2bb02013-12-28 19:17:25 +053010083 hddLog(LOG1, FL("Connect to SSID: %s opertating Channel: %u"),
10084 pRoamProfile->SSIDs.SSIDList->SSID.ssId, operatingChannel);
Jeff Johnson295189b2012-06-20 16:38:30 -070010085 if ((IW_AUTH_WPA_VERSION_WPA == pWextState->wpaVersion) ||
10086 (IW_AUTH_WPA_VERSION_WPA2 == pWextState->wpaVersion))
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010087 {
Jeff Johnson295189b2012-06-20 16:38:30 -070010088 /*set gen ie*/
10089 hdd_SetGENIEToCsr(pAdapter, &RSNAuthType);
10090 /*set auth*/
10091 hdd_set_csr_auth_type(pAdapter, RSNAuthType);
10092 }
Jeff Johnson295189b2012-06-20 16:38:30 -070010093#ifdef FEATURE_WLAN_WAPI
10094 if (pAdapter->wapi_info.nWapiMode)
10095 {
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -070010096 hddLog(LOG1, "%s: Setting WAPI AUTH Type and Encryption Mode values", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -070010097 switch (pAdapter->wapi_info.wapiAuthMode)
10098 {
10099 case WAPI_AUTH_MODE_PSK:
10100 {
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -070010101 hddLog(LOG1, "%s: WAPI AUTH TYPE: PSK: %d", __func__,
Jeff Johnson295189b2012-06-20 16:38:30 -070010102 pAdapter->wapi_info.wapiAuthMode);
10103 pRoamProfile->AuthType.authType[0] = eCSR_AUTH_TYPE_WAPI_WAI_PSK;
10104 break;
10105 }
10106 case WAPI_AUTH_MODE_CERT:
10107 {
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -070010108 hddLog(LOG1, "%s: WAPI AUTH TYPE: CERT: %d", __func__,
Jeff Johnson295189b2012-06-20 16:38:30 -070010109 pAdapter->wapi_info.wapiAuthMode);
10110 pRoamProfile->AuthType.authType[0] = eCSR_AUTH_TYPE_WAPI_WAI_CERTIFICATE;
10111 break;
10112 }
10113 } // End of switch
10114 if ( pAdapter->wapi_info.wapiAuthMode == WAPI_AUTH_MODE_PSK ||
10115 pAdapter->wapi_info.wapiAuthMode == WAPI_AUTH_MODE_CERT)
10116 {
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -070010117 hddLog(LOG1, "%s: WAPI PAIRWISE/GROUP ENCRYPTION: WPI", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -070010118 pRoamProfile->AuthType.numEntries = 1;
10119 pRoamProfile->EncryptionType.numEntries = 1;
10120 pRoamProfile->EncryptionType.encryptionType[0] = eCSR_ENCRYPT_TYPE_WPI;
10121 pRoamProfile->mcEncryptionType.numEntries = 1;
10122 pRoamProfile->mcEncryptionType.encryptionType[0] = eCSR_ENCRYPT_TYPE_WPI;
10123 }
10124 }
10125#endif /* FEATURE_WLAN_WAPI */
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053010126#ifdef WLAN_FEATURE_GTK_OFFLOAD
Gopichand Nakkalad36ee622013-05-07 14:13:27 +053010127 /* Initializing gtkOffloadReqParams */
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053010128 if ((WLAN_HDD_INFRA_STATION == pAdapter->device_mode) ||
10129 (WLAN_HDD_P2P_CLIENT == pAdapter->device_mode))
10130 {
Gopichand Nakkalad36ee622013-05-07 14:13:27 +053010131 memset(&pHddStaCtx->gtkOffloadReqParams, 0,
10132 sizeof (tSirGtkOffloadParams));
10133 pHddStaCtx->gtkOffloadReqParams.ulFlags = GTK_OFFLOAD_DISABLE;
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053010134 }
10135#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070010136 pRoamProfile->csrPersona = pAdapter->device_mode;
10137
Jeff Johnson32d95a32012-09-10 13:15:23 -070010138 if( operatingChannel )
10139 {
10140 pRoamProfile->ChannelInfo.ChannelList = &operatingChannel;
10141 pRoamProfile->ChannelInfo.numOfChannels = 1;
10142 }
Chet Lanctot186b5732013-03-18 10:26:30 -070010143 else
10144 {
10145 pRoamProfile->ChannelInfo.ChannelList = NULL;
10146 pRoamProfile->ChannelInfo.numOfChannels = 0;
10147 }
Shailender Karmuchi15cd0672013-05-15 19:50:04 -070010148 if ( (WLAN_HDD_IBSS == pAdapter->device_mode) && operatingChannel)
10149 {
10150 hdd_select_cbmode(pAdapter,operatingChannel);
10151 }
Arun Kumar Khandavalli94a2bb02013-12-28 19:17:25 +053010152
Madan Mohan Koyyalamudi42dcd162012-12-03 16:34:04 -080010153 /* change conn_state to connecting before sme_RoamConnect(), because sme_RoamConnect()
10154 * has a direct path to call hdd_smeRoamCallback(), which will change the conn_state
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010155 * If direct path, conn_state will be accordingly changed to NotConnected or Associated
Madan Mohan Koyyalamudi42dcd162012-12-03 16:34:04 -080010156 * by either hdd_AssociationCompletionHandler() or hdd_DisConnectHandler() in sme_RoamCallback()
Madan Mohan Koyyalamudidf86c422012-12-04 17:03:44 -080010157 * if sme_RomConnect is to be queued, Connecting state will remain until it is completed.
10158 */
Gopichand Nakkalaa3c8fb62013-06-21 15:36:42 +053010159 if (WLAN_HDD_INFRA_STATION == pAdapter->device_mode ||
10160 WLAN_HDD_P2P_CLIENT == pAdapter->device_mode)
Abhishek Singhf4669da2014-05-26 15:07:49 +053010161 {
10162 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
10163 "%s: Set HDD connState to eConnectionState_Connecting",
10164 __func__);
Madan Mohan Koyyalamudidf86c422012-12-04 17:03:44 -080010165 hdd_connSetConnectionState(WLAN_HDD_GET_STATION_CTX_PTR(pAdapter),
10166 eConnectionState_Connecting);
Abhishek Singhf4669da2014-05-26 15:07:49 +053010167 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010168 status = sme_RoamConnect( WLAN_HDD_GET_HAL_CTX(pAdapter),
Jeff Johnson295189b2012-06-20 16:38:30 -070010169 pAdapter->sessionId, pRoamProfile, &roamId);
10170
Gopichand Nakkalaa3c8fb62013-06-21 15:36:42 +053010171 if ((eHAL_STATUS_SUCCESS != status) &&
10172 (WLAN_HDD_INFRA_STATION == pAdapter->device_mode ||
10173 WLAN_HDD_P2P_CLIENT == pAdapter->device_mode))
Madan Mohan Koyyalamudid5acbf52012-11-28 01:45:08 +053010174
10175 {
Madan Mohan Koyyalamudi42dcd162012-12-03 16:34:04 -080010176 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: sme_RoamConnect (session %d) failed with "
10177 "status %d. -> NotConnected", __func__, pAdapter->sessionId, status);
10178 /* change back to NotAssociated */
Madan Mohan Koyyalamudid5acbf52012-11-28 01:45:08 +053010179 hdd_connSetConnectionState(WLAN_HDD_GET_STATION_CTX_PTR(pAdapter),
Madan Mohan Koyyalamudi42dcd162012-12-03 16:34:04 -080010180 eConnectionState_NotConnected);
Madan Mohan Koyyalamudid5acbf52012-11-28 01:45:08 +053010181 }
Madan Mohan Koyyalamudidf86c422012-12-04 17:03:44 -080010182
10183 pRoamProfile->ChannelInfo.ChannelList = NULL;
10184 pRoamProfile->ChannelInfo.numOfChannels = 0;
10185
Jeff Johnson295189b2012-06-20 16:38:30 -070010186 }
10187 else
10188 {
10189 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: No valid Roam profile", __func__);
10190 return -EINVAL;
10191 }
Madan Mohan Koyyalamudifd4e1da2012-11-09 17:50:19 -080010192 EXIT();
Jeff Johnson295189b2012-06-20 16:38:30 -070010193 return status;
10194}
10195
10196/*
10197 * FUNCTION: wlan_hdd_set_cfg80211_auth_type
10198 * This function is used to set the authentication type (OPEN/SHARED).
10199 *
10200 */
10201static int wlan_hdd_cfg80211_set_auth_type(hdd_adapter_t *pAdapter,
10202 enum nl80211_auth_type auth_type)
10203{
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010204 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
Jeff Johnson295189b2012-06-20 16:38:30 -070010205 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
10206
10207 ENTER();
10208
10209 /*set authentication type*/
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010210 switch (auth_type)
Jeff Johnson295189b2012-06-20 16:38:30 -070010211 {
Jeff Johnson295189b2012-06-20 16:38:30 -070010212 case NL80211_AUTHTYPE_AUTOMATIC:
Gopichand Nakkala29149562013-05-10 21:43:41 +053010213 hddLog(VOS_TRACE_LEVEL_INFO,
10214 "%s: set authentication type to AUTOSWITCH", __func__);
10215 pHddStaCtx->conn_info.authType = eCSR_AUTH_TYPE_AUTOSWITCH;
10216 break;
10217
10218 case NL80211_AUTHTYPE_OPEN_SYSTEM:
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070010219#ifdef WLAN_FEATURE_VOWIFI_11R
10220 case NL80211_AUTHTYPE_FT:
10221#endif /* WLAN_FEATURE_VOWIFI_11R */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010222 hddLog(VOS_TRACE_LEVEL_INFO,
Jeff Johnson295189b2012-06-20 16:38:30 -070010223 "%s: set authentication type to OPEN", __func__);
10224 pHddStaCtx->conn_info.authType = eCSR_AUTH_TYPE_OPEN_SYSTEM;
10225 break;
10226
10227 case NL80211_AUTHTYPE_SHARED_KEY:
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010228 hddLog(VOS_TRACE_LEVEL_INFO,
Jeff Johnson295189b2012-06-20 16:38:30 -070010229 "%s: set authentication type to SHARED", __func__);
10230 pHddStaCtx->conn_info.authType = eCSR_AUTH_TYPE_SHARED_KEY;
10231 break;
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -080010232#ifdef FEATURE_WLAN_ESE
Jeff Johnson295189b2012-06-20 16:38:30 -070010233 case NL80211_AUTHTYPE_NETWORK_EAP:
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010234 hddLog(VOS_TRACE_LEVEL_INFO,
Jeff Johnson295189b2012-06-20 16:38:30 -070010235 "%s: set authentication type to CCKM WPA", __func__);
10236 pHddStaCtx->conn_info.authType = eCSR_AUTH_TYPE_CCKM_WPA;//eCSR_AUTH_TYPE_CCKM_RSN needs to be handled as well if required.
10237 break;
10238#endif
10239
10240
10241 default:
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010242 hddLog(VOS_TRACE_LEVEL_ERROR,
10243 "%s: Unsupported authentication type %d", __func__,
Jeff Johnson295189b2012-06-20 16:38:30 -070010244 auth_type);
10245 pHddStaCtx->conn_info.authType = eCSR_AUTH_TYPE_UNKNOWN;
10246 return -EINVAL;
10247 }
10248
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010249 pWextState->roamProfile.AuthType.authType[0] =
Jeff Johnson295189b2012-06-20 16:38:30 -070010250 pHddStaCtx->conn_info.authType;
10251 return 0;
10252}
10253
10254/*
10255 * FUNCTION: wlan_hdd_set_akm_suite
10256 * This function is used to set the key mgmt type(PSK/8021x).
10257 *
10258 */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010259static int wlan_hdd_set_akm_suite( hdd_adapter_t *pAdapter,
Jeff Johnson295189b2012-06-20 16:38:30 -070010260 u32 key_mgmt
10261 )
10262{
10263 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
10264 ENTER();
Abhishek Singhae408032014-09-25 17:22:04 +053010265 /* Should be in ieee802_11_defs.h */
10266#define WLAN_AKM_SUITE_8021X_SHA256 0x000FAC05
10267#define WLAN_AKM_SUITE_PSK_SHA256 0x000FAC06
Jeff Johnson295189b2012-06-20 16:38:30 -070010268 /*set key mgmt type*/
10269 switch(key_mgmt)
10270 {
10271 case WLAN_AKM_SUITE_PSK:
Abhishek Singhae408032014-09-25 17:22:04 +053010272 case WLAN_AKM_SUITE_PSK_SHA256:
Gopichand Nakkala356fb102013-03-06 12:34:04 +053010273#ifdef WLAN_FEATURE_VOWIFI_11R
10274 case WLAN_AKM_SUITE_FT_PSK:
10275#endif
10276 hddLog(VOS_TRACE_LEVEL_INFO, "%s: setting key mgmt type to PSK",
Jeff Johnson295189b2012-06-20 16:38:30 -070010277 __func__);
10278 pWextState->authKeyMgmt |= IW_AUTH_KEY_MGMT_PSK;
10279 break;
10280
10281 case WLAN_AKM_SUITE_8021X:
Abhishek Singhae408032014-09-25 17:22:04 +053010282 case WLAN_AKM_SUITE_8021X_SHA256:
Gopichand Nakkala356fb102013-03-06 12:34:04 +053010283#ifdef WLAN_FEATURE_VOWIFI_11R
10284 case WLAN_AKM_SUITE_FT_8021X:
10285#endif
10286 hddLog(VOS_TRACE_LEVEL_INFO, "%s: setting key mgmt type to 8021x",
Jeff Johnson295189b2012-06-20 16:38:30 -070010287 __func__);
10288 pWextState->authKeyMgmt |= IW_AUTH_KEY_MGMT_802_1X;
10289 break;
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -080010290#ifdef FEATURE_WLAN_ESE
Jeff Johnson295189b2012-06-20 16:38:30 -070010291#define WLAN_AKM_SUITE_CCKM 0x00409600 /* Should be in ieee802_11_defs.h */
10292#define IW_AUTH_KEY_MGMT_CCKM 8 /* Should be in linux/wireless.h */
10293 case WLAN_AKM_SUITE_CCKM:
10294 hddLog(VOS_TRACE_LEVEL_INFO, "%s: setting key mgmt type to CCKM",
10295 __func__);
10296 pWextState->authKeyMgmt |= IW_AUTH_KEY_MGMT_CCKM;
10297 break;
10298#endif
Leela Venkata Kiran Kumar Reddy Chiralae208a832014-04-27 22:34:25 -070010299#ifndef WLAN_AKM_SUITE_OSEN
10300#define WLAN_AKM_SUITE_OSEN 0x506f9a01 /* Should be in ieee802_11_defs.h */
10301 case WLAN_AKM_SUITE_OSEN:
10302 hddLog(VOS_TRACE_LEVEL_INFO, "%s: setting key mgmt type to OSEN",
10303 __func__);
10304 pWextState->authKeyMgmt |= IW_AUTH_KEY_MGMT_802_1X;
10305 break;
10306#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070010307
10308 default:
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010309 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Unsupported key mgmt type %d",
Jeff Johnson295189b2012-06-20 16:38:30 -070010310 __func__, key_mgmt);
10311 return -EINVAL;
10312
10313 }
10314 return 0;
10315}
10316
10317/*
10318 * FUNCTION: wlan_hdd_cfg80211_set_cipher
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010319 * This function is used to set the encryption type
Jeff Johnson295189b2012-06-20 16:38:30 -070010320 * (NONE/WEP40/WEP104/TKIP/CCMP).
10321 */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010322static int wlan_hdd_cfg80211_set_cipher( hdd_adapter_t *pAdapter,
10323 u32 cipher,
Jeff Johnson295189b2012-06-20 16:38:30 -070010324 bool ucast
10325 )
10326{
10327 eCsrEncryptionType encryptionType = eCSR_ENCRYPT_TYPE_NONE;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010328 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
Jeff Johnson295189b2012-06-20 16:38:30 -070010329 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
10330
10331 ENTER();
10332
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010333 if (!cipher)
Jeff Johnson295189b2012-06-20 16:38:30 -070010334 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010335 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: received cipher %d - considering none",
Jeff Johnson295189b2012-06-20 16:38:30 -070010336 __func__, cipher);
10337 encryptionType = eCSR_ENCRYPT_TYPE_NONE;
10338 }
10339 else
10340 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010341
Jeff Johnson295189b2012-06-20 16:38:30 -070010342 /*set encryption method*/
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010343 switch (cipher)
Jeff Johnson295189b2012-06-20 16:38:30 -070010344 {
10345 case IW_AUTH_CIPHER_NONE:
10346 encryptionType = eCSR_ENCRYPT_TYPE_NONE;
10347 break;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010348
Jeff Johnson295189b2012-06-20 16:38:30 -070010349 case WLAN_CIPHER_SUITE_WEP40:
Gopichand Nakkala29149562013-05-10 21:43:41 +053010350 encryptionType = eCSR_ENCRYPT_TYPE_WEP40;
Jeff Johnson295189b2012-06-20 16:38:30 -070010351 break;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010352
Jeff Johnson295189b2012-06-20 16:38:30 -070010353 case WLAN_CIPHER_SUITE_WEP104:
Gopichand Nakkala29149562013-05-10 21:43:41 +053010354 encryptionType = eCSR_ENCRYPT_TYPE_WEP104;
Jeff Johnson295189b2012-06-20 16:38:30 -070010355 break;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010356
Jeff Johnson295189b2012-06-20 16:38:30 -070010357 case WLAN_CIPHER_SUITE_TKIP:
10358 encryptionType = eCSR_ENCRYPT_TYPE_TKIP;
10359 break;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010360
Jeff Johnson295189b2012-06-20 16:38:30 -070010361 case WLAN_CIPHER_SUITE_CCMP:
10362 encryptionType = eCSR_ENCRYPT_TYPE_AES;
10363 break;
10364#ifdef FEATURE_WLAN_WAPI
10365 case WLAN_CIPHER_SUITE_SMS4:
10366 encryptionType = eCSR_ENCRYPT_TYPE_WPI;
10367 break;
10368#endif
10369
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -080010370#ifdef FEATURE_WLAN_ESE
Jeff Johnson295189b2012-06-20 16:38:30 -070010371 case WLAN_CIPHER_SUITE_KRK:
10372 encryptionType = eCSR_ENCRYPT_TYPE_KRK;
10373 break;
10374#endif
10375 default:
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010376 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Unsupported cipher type %d",
Jeff Johnson295189b2012-06-20 16:38:30 -070010377 __func__, cipher);
10378 return -EOPNOTSUPP;
10379 }
10380 }
10381
10382 if (ucast)
10383 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010384 hddLog(VOS_TRACE_LEVEL_INFO, "%s: setting unicast cipher type to %d",
Jeff Johnson295189b2012-06-20 16:38:30 -070010385 __func__, encryptionType);
10386 pHddStaCtx->conn_info.ucEncryptionType = encryptionType;
10387 pWextState->roamProfile.EncryptionType.numEntries = 1;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010388 pWextState->roamProfile.EncryptionType.encryptionType[0] =
Jeff Johnson295189b2012-06-20 16:38:30 -070010389 encryptionType;
10390 }
10391 else
10392 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010393 hddLog(VOS_TRACE_LEVEL_INFO, "%s: setting mcast cipher type to %d",
Jeff Johnson295189b2012-06-20 16:38:30 -070010394 __func__, encryptionType);
10395 pHddStaCtx->conn_info.mcEncryptionType = encryptionType;
10396 pWextState->roamProfile.mcEncryptionType.numEntries = 1;
10397 pWextState->roamProfile.mcEncryptionType.encryptionType[0] = encryptionType;
10398 }
10399
10400 return 0;
10401}
10402
10403
10404/*
10405 * FUNCTION: wlan_hdd_cfg80211_set_ie
10406 * This function is used to parse WPA/RSN IE's.
10407 */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010408int wlan_hdd_cfg80211_set_ie( hdd_adapter_t *pAdapter,
10409 u8 *ie,
Jeff Johnson295189b2012-06-20 16:38:30 -070010410 size_t ie_len
10411 )
10412{
10413 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
10414 u8 *genie = ie;
10415 v_U16_t remLen = ie_len;
10416#ifdef FEATURE_WLAN_WAPI
10417 v_U32_t akmsuite[MAX_NUM_AKM_SUITES];
10418 u16 *tmp;
10419 v_U16_t akmsuiteCount;
10420 int *akmlist;
10421#endif
10422 ENTER();
10423
10424 /* clear previous assocAddIE */
10425 pWextState->assocAddIE.length = 0;
10426 pWextState->roamProfile.bWPSAssociation = VOS_FALSE;
Leela Venkata Kiran Kumar Reddy Chiralaf257bef2014-04-11 18:48:12 -070010427 pWextState->roamProfile.bOSENAssociation = VOS_FALSE;
Jeff Johnson295189b2012-06-20 16:38:30 -070010428
10429 while (remLen >= 2)
10430 {
10431 v_U16_t eLen = 0;
10432 v_U8_t elementId;
10433 elementId = *genie++;
10434 eLen = *genie++;
10435 remLen -= 2;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010436
Arif Hussain6d2a3322013-11-17 19:50:10 -080010437 hddLog(VOS_TRACE_LEVEL_INFO, "%s: IE[0x%X], LEN[%d]",
Jeff Johnson295189b2012-06-20 16:38:30 -070010438 __func__, elementId, eLen);
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010439
10440 switch ( elementId )
Jeff Johnson295189b2012-06-20 16:38:30 -070010441 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010442 case DOT11F_EID_WPA:
Madan Mohan Koyyalamudief3b66e2012-10-11 14:29:42 -070010443 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 -070010444 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010445 hddLog(VOS_TRACE_LEVEL_ERROR,
Jeff Johnson295189b2012-06-20 16:38:30 -070010446 "%s: Invalid WPA IE", __func__);
10447 return -EINVAL;
10448 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010449 else if (0 == memcmp(&genie[0], "\x00\x50\xf2\x04", 4))
Jeff Johnson295189b2012-06-20 16:38:30 -070010450 {
10451 v_U16_t curAddIELen = pWextState->assocAddIE.length;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010452 hddLog (VOS_TRACE_LEVEL_INFO, "%s Set WPS IE(len %d)",
Jeff Johnson295189b2012-06-20 16:38:30 -070010453 __func__, eLen + 2);
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010454
Jeff Johnson295189b2012-06-20 16:38:30 -070010455 if( SIR_MAC_MAX_IE_LENGTH < (pWextState->assocAddIE.length + eLen) )
10456 {
Jeff Johnson902c9832012-12-10 14:28:09 -080010457 hddLog(VOS_TRACE_LEVEL_FATAL, "Cannot accommodate assocAddIE. "
10458 "Need bigger buffer space");
Jeff Johnson295189b2012-06-20 16:38:30 -070010459 VOS_ASSERT(0);
10460 return -ENOMEM;
10461 }
10462 // WSC IE is saved to Additional IE ; it should be accumulated to handle WPS IE + P2P IE
10463 memcpy( pWextState->assocAddIE.addIEdata + curAddIELen, genie - 2, eLen + 2);
10464 pWextState->assocAddIE.length += eLen + 2;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010465
Jeff Johnson295189b2012-06-20 16:38:30 -070010466 pWextState->roamProfile.bWPSAssociation = VOS_TRUE;
10467 pWextState->roamProfile.pAddIEAssoc = pWextState->assocAddIE.addIEdata;
10468 pWextState->roamProfile.nAddIEAssocLength = pWextState->assocAddIE.length;
10469 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010470 else if (0 == memcmp(&genie[0], "\x00\x50\xf2", 3))
10471 {
Jeff Johnson295189b2012-06-20 16:38:30 -070010472 hddLog (VOS_TRACE_LEVEL_INFO, "%s Set WPA IE (len %d)",__func__, eLen + 2);
10473 memset( pWextState->WPARSNIE, 0, MAX_WPA_RSN_IE_LEN );
10474 memcpy( pWextState->WPARSNIE, genie - 2, (eLen + 2) /*ie_len*/);
10475 pWextState->roamProfile.pWPAReqIE = pWextState->WPARSNIE;
10476 pWextState->roamProfile.nWPAReqIELength = eLen + 2;//ie_len;
10477 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010478 else if ( (0 == memcmp(&genie[0], P2P_OUI_TYPE,
Kiet Lam8da98992013-11-21 15:59:07 +053010479 P2P_OUI_TYPE_SIZE)))
Jeff Johnson295189b2012-06-20 16:38:30 -070010480 {
10481 v_U16_t curAddIELen = pWextState->assocAddIE.length;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010482 hddLog (VOS_TRACE_LEVEL_INFO, "%s Set P2P IE(len %d)",
Jeff Johnson295189b2012-06-20 16:38:30 -070010483 __func__, eLen + 2);
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010484
Jeff Johnson295189b2012-06-20 16:38:30 -070010485 if( SIR_MAC_MAX_IE_LENGTH < (pWextState->assocAddIE.length + eLen) )
10486 {
Jeff Johnson902c9832012-12-10 14:28:09 -080010487 hddLog(VOS_TRACE_LEVEL_FATAL, "Cannot accommodate assocAddIE "
10488 "Need bigger buffer space");
Jeff Johnson295189b2012-06-20 16:38:30 -070010489 VOS_ASSERT(0);
10490 return -ENOMEM;
10491 }
10492 // P2P IE is saved to Additional IE ; it should be accumulated to handle WPS IE + P2P IE
10493 memcpy( pWextState->assocAddIE.addIEdata + curAddIELen, genie - 2, eLen + 2);
10494 pWextState->assocAddIE.length += eLen + 2;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010495
Jeff Johnson295189b2012-06-20 16:38:30 -070010496 pWextState->roamProfile.pAddIEAssoc = pWextState->assocAddIE.addIEdata;
10497 pWextState->roamProfile.nAddIEAssocLength = pWextState->assocAddIE.length;
10498 }
Jeff Johnson295189b2012-06-20 16:38:30 -070010499#ifdef WLAN_FEATURE_WFD
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010500 else if ( (0 == memcmp(&genie[0], WFD_OUI_TYPE,
10501 WFD_OUI_TYPE_SIZE))
Jeff Johnson295189b2012-06-20 16:38:30 -070010502 /*Consider WFD IE, only for P2P Client */
10503 && (WLAN_HDD_P2P_CLIENT == pAdapter->device_mode) )
10504 {
10505 v_U16_t curAddIELen = pWextState->assocAddIE.length;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010506 hddLog (VOS_TRACE_LEVEL_INFO, "%s Set WFD IE(len %d)",
Jeff Johnson295189b2012-06-20 16:38:30 -070010507 __func__, eLen + 2);
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010508
Jeff Johnson295189b2012-06-20 16:38:30 -070010509 if( SIR_MAC_MAX_IE_LENGTH < (pWextState->assocAddIE.length + eLen) )
10510 {
Jeff Johnson902c9832012-12-10 14:28:09 -080010511 hddLog(VOS_TRACE_LEVEL_FATAL, "Cannot accommodate assocAddIE "
10512 "Need bigger buffer space");
Jeff Johnson295189b2012-06-20 16:38:30 -070010513 VOS_ASSERT(0);
10514 return -ENOMEM;
10515 }
10516 // WFD IE is saved to Additional IE ; it should be accumulated to handle
10517 // WPS IE + P2P IE + WFD IE
10518 memcpy( pWextState->assocAddIE.addIEdata + curAddIELen, genie - 2, eLen + 2);
10519 pWextState->assocAddIE.length += eLen + 2;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010520
Jeff Johnson295189b2012-06-20 16:38:30 -070010521 pWextState->roamProfile.pAddIEAssoc = pWextState->assocAddIE.addIEdata;
10522 pWextState->roamProfile.nAddIEAssocLength = pWextState->assocAddIE.length;
10523 }
10524#endif
Madan Mohan Koyyalamudief3b66e2012-10-11 14:29:42 -070010525 /* Appending HS 2.0 Indication Element in Assiciation Request */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010526 else if ( (0 == memcmp(&genie[0], HS20_OUI_TYPE,
Madan Mohan Koyyalamudi1bed5982012-10-22 14:38:06 -070010527 HS20_OUI_TYPE_SIZE)) )
10528 {
10529 v_U16_t curAddIELen = pWextState->assocAddIE.length;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010530 hddLog (VOS_TRACE_LEVEL_INFO, "%s Set HS20 IE(len %d)",
Madan Mohan Koyyalamudi1bed5982012-10-22 14:38:06 -070010531 __func__, eLen + 2);
Madan Mohan Koyyalamudief3b66e2012-10-11 14:29:42 -070010532
Madan Mohan Koyyalamudi1bed5982012-10-22 14:38:06 -070010533 if( SIR_MAC_MAX_IE_LENGTH < (pWextState->assocAddIE.length + eLen) )
10534 {
Jeff Johnson902c9832012-12-10 14:28:09 -080010535 hddLog(VOS_TRACE_LEVEL_FATAL, "Cannot accommodate assocAddIE "
10536 "Need bigger buffer space");
Madan Mohan Koyyalamudi1bed5982012-10-22 14:38:06 -070010537 VOS_ASSERT(0);
10538 return -ENOMEM;
10539 }
10540 memcpy( pWextState->assocAddIE.addIEdata + curAddIELen, genie - 2, eLen + 2);
10541 pWextState->assocAddIE.length += eLen + 2;
Madan Mohan Koyyalamudief3b66e2012-10-11 14:29:42 -070010542
Madan Mohan Koyyalamudi1bed5982012-10-22 14:38:06 -070010543 pWextState->roamProfile.pAddIEAssoc = pWextState->assocAddIE.addIEdata;
10544 pWextState->roamProfile.nAddIEAssocLength = pWextState->assocAddIE.length;
10545 }
Leela Venkata Kiran Kumar Reddy Chiralaf257bef2014-04-11 18:48:12 -070010546 /* Appending OSEN Information Element in Assiciation Request */
10547 else if ( (0 == memcmp(&genie[0], OSEN_OUI_TYPE,
10548 OSEN_OUI_TYPE_SIZE)) )
10549 {
10550 v_U16_t curAddIELen = pWextState->assocAddIE.length;
10551 hddLog (VOS_TRACE_LEVEL_INFO, "%s Set OSEN IE(len %d)",
10552 __func__, eLen + 2);
Madan Mohan Koyyalamudief3b66e2012-10-11 14:29:42 -070010553
Leela Venkata Kiran Kumar Reddy Chiralaf257bef2014-04-11 18:48:12 -070010554 if( SIR_MAC_MAX_IE_LENGTH < (pWextState->assocAddIE.length + eLen) )
10555 {
10556 hddLog(VOS_TRACE_LEVEL_FATAL, "Cannot accommodate assocAddIE "
10557 "Need bigger buffer space");
10558 VOS_ASSERT(0);
10559 return -ENOMEM;
10560 }
10561 memcpy( pWextState->assocAddIE.addIEdata + curAddIELen, genie - 2, eLen + 2);
10562 pWextState->assocAddIE.length += eLen + 2;
10563
10564 pWextState->roamProfile.bOSENAssociation = VOS_TRUE;
10565 pWextState->roamProfile.pAddIEAssoc = pWextState->assocAddIE.addIEdata;
10566 pWextState->roamProfile.nAddIEAssocLength = pWextState->assocAddIE.length;
10567 }
10568
10569 break;
Praveen Kumar Sirisilla7d68b7b2013-09-22 14:01:42 -070010570 if (WLAN_HDD_IBSS == pAdapter->device_mode) {
10571
10572 /* populating as ADDIE in beacon frames */
10573 if (ccmCfgSetStr(WLAN_HDD_GET_HAL_CTX(pAdapter),
10574 WNI_CFG_PROBE_RSP_BCN_ADDNIE_DATA, genie - 2, eLen + 2,
10575 NULL, eANI_BOOLEAN_FALSE)== eHAL_STATUS_SUCCESS)
10576 {
10577 if (ccmCfgSetInt(WLAN_HDD_GET_HAL_CTX(pAdapter),
10578 WNI_CFG_PROBE_RSP_BCN_ADDNIE_FLAG, 1,NULL,
10579 eANI_BOOLEAN_FALSE) == eHAL_STATUS_FAILURE)
10580 {
10581 hddLog(LOGE,
10582 "Coldn't pass "
10583 "WNI_CFG_PROBE_RSP_BCN_ADDNIE_FLAG to CCM");
10584 }
10585 }/* ccmCfgSetStr(,WNI_CFG_PROBE_RSP_BCN_ADDNIE_DATA, , )*/
10586 else
10587 hddLog(LOGE,
10588 "Could not pass on "
10589 "WNI_CFG_PROBE_RSP_BCN_ADDNIE_DATA to CCM");
10590
10591 /* IBSS mode doesn't contain params->proberesp_ies still
10592 beaconIE's need to be populated in probe response frames */
10593 if ( (NULL != (genie - 2)) && (0 != eLen + 2) )
10594 {
10595 u16 rem_probe_resp_ie_len = eLen + 2;
10596 u8 probe_rsp_ie_len[3] = {0};
10597 u8 counter = 0;
10598
10599 /* Check Probe Resp Length if it is greater then 255 then
10600 Store Probe Rsp IEs into WNI_CFG_PROBE_RSP_ADDNIE_DATA1
10601 & WNI_CFG_PROBE_RSP_ADDNIE_DATA2 CFG Variable As We are
10602 not able Store More then 255 bytes into One Variable */
10603
10604 while ((rem_probe_resp_ie_len > 0) && (counter < 3))
10605 {
10606 if (rem_probe_resp_ie_len > MAX_CFG_STRING_LEN)
10607 {
10608 probe_rsp_ie_len[counter++] = MAX_CFG_STRING_LEN;
10609 rem_probe_resp_ie_len -= MAX_CFG_STRING_LEN;
10610 }
10611 else
10612 {
10613 probe_rsp_ie_len[counter++] = rem_probe_resp_ie_len;
10614 rem_probe_resp_ie_len = 0;
10615 }
10616 }
10617
10618 rem_probe_resp_ie_len = 0;
10619
10620 if (probe_rsp_ie_len[0] > 0)
10621 {
10622 if (ccmCfgSetStr(WLAN_HDD_GET_HAL_CTX(pAdapter),
10623 WNI_CFG_PROBE_RSP_ADDNIE_DATA1,
10624 (tANI_U8*)(genie - 2),
10625 probe_rsp_ie_len[0], NULL,
10626 eANI_BOOLEAN_FALSE)
10627 == eHAL_STATUS_FAILURE)
10628 {
10629 hddLog(LOGE,
10630 "Could not pass"
10631 "on WNI_CFG_PROBE_RSP_ADDNIE_DATA1 to CCM");
10632 }
10633 rem_probe_resp_ie_len += probe_rsp_ie_len[0];
10634 }
10635
10636 if (probe_rsp_ie_len[1] > 0)
10637 {
10638 if (ccmCfgSetStr(WLAN_HDD_GET_HAL_CTX(pAdapter),
10639 WNI_CFG_PROBE_RSP_ADDNIE_DATA2,
10640 (tANI_U8*)(genie - (2 + rem_probe_resp_ie_len)),
10641 probe_rsp_ie_len[1], NULL,
10642 eANI_BOOLEAN_FALSE)
10643 == eHAL_STATUS_FAILURE)
10644 {
10645 hddLog(LOGE,
10646 "Could not pass"
10647 "on WNI_CFG_PROBE_RSP_ADDNIE_DATA2 to CCM");
10648 }
10649 rem_probe_resp_ie_len += probe_rsp_ie_len[1];
10650 }
10651
10652 if (probe_rsp_ie_len[2] > 0)
10653 {
10654 if (ccmCfgSetStr(WLAN_HDD_GET_HAL_CTX(pAdapter),
10655 WNI_CFG_PROBE_RSP_ADDNIE_DATA3,
10656 (tANI_U8*)(genie - (2 + rem_probe_resp_ie_len)),
10657 probe_rsp_ie_len[2], NULL,
10658 eANI_BOOLEAN_FALSE)
10659 == eHAL_STATUS_FAILURE)
10660 {
10661 hddLog(LOGE,
10662 "Could not pass"
10663 "on WNI_CFG_PROBE_RSP_ADDNIE_DATA3 to CCM");
10664 }
10665 rem_probe_resp_ie_len += probe_rsp_ie_len[2];
10666 }
10667
10668 if (ccmCfgSetInt(WLAN_HDD_GET_HAL_CTX(pAdapter),
10669 WNI_CFG_PROBE_RSP_ADDNIE_FLAG, 1,NULL,
10670 eANI_BOOLEAN_FALSE) == eHAL_STATUS_FAILURE)
10671 {
10672 hddLog(LOGE,
10673 "Could not pass"
10674 "on WNI_CFG_PROBE_RSP_ADDNIE_FLAG to CCM");
10675 }
10676 }
10677 else
10678 {
10679 // Reset WNI_CFG_PROBE_RSP Flags
10680 wlan_hdd_reset_prob_rspies(pAdapter);
10681
10682 hddLog(VOS_TRACE_LEVEL_INFO,
10683 "%s: No Probe Response IE received in set beacon",
10684 __func__);
10685 }
10686 } /* end of if (WLAN_HDD_IBSS == pAdapter->device_mode) */
Jeff Johnson295189b2012-06-20 16:38:30 -070010687 break;
10688 case DOT11F_EID_RSN:
10689 hddLog (VOS_TRACE_LEVEL_INFO, "%s Set RSN IE(len %d)",__func__, eLen + 2);
10690 memset( pWextState->WPARSNIE, 0, MAX_WPA_RSN_IE_LEN );
10691 memcpy( pWextState->WPARSNIE, genie - 2, (eLen + 2)/*ie_len*/);
10692 pWextState->roamProfile.pRSNReqIE = pWextState->WPARSNIE;
10693 pWextState->roamProfile.nRSNReqIELength = eLen + 2; //ie_len;
10694 break;
Madan Mohan Koyyalamudief3b66e2012-10-11 14:29:42 -070010695 /* Appending Extended Capabilities with Interworking bit set in Assoc Req */
10696 case DOT11F_EID_EXTCAP:
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010697 {
Madan Mohan Koyyalamudief3b66e2012-10-11 14:29:42 -070010698 v_U16_t curAddIELen = pWextState->assocAddIE.length;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010699 hddLog (VOS_TRACE_LEVEL_INFO, "%s Set Extended CAPS IE(len %d)",
Madan Mohan Koyyalamudief3b66e2012-10-11 14:29:42 -070010700 __func__, eLen + 2);
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010701
Madan Mohan Koyyalamudief3b66e2012-10-11 14:29:42 -070010702 if( SIR_MAC_MAX_IE_LENGTH < (pWextState->assocAddIE.length + eLen) )
10703 {
Jeff Johnson902c9832012-12-10 14:28:09 -080010704 hddLog(VOS_TRACE_LEVEL_FATAL, "Cannot accommodate assocAddIE "
10705 "Need bigger buffer space");
Madan Mohan Koyyalamudief3b66e2012-10-11 14:29:42 -070010706 VOS_ASSERT(0);
10707 return -ENOMEM;
10708 }
10709 memcpy( pWextState->assocAddIE.addIEdata + curAddIELen, genie - 2, eLen + 2);
10710 pWextState->assocAddIE.length += eLen + 2;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010711
Madan Mohan Koyyalamudief3b66e2012-10-11 14:29:42 -070010712 pWextState->roamProfile.pAddIEAssoc = pWextState->assocAddIE.addIEdata;
10713 pWextState->roamProfile.nAddIEAssocLength = pWextState->assocAddIE.length;
10714 break;
10715 }
Jeff Johnson295189b2012-06-20 16:38:30 -070010716#ifdef FEATURE_WLAN_WAPI
10717 case WLAN_EID_WAPI:
10718 pAdapter->wapi_info.nWapiMode = 1; //Setting WAPI Mode to ON=1
Jeff Johnson0299d0a2013-10-30 12:37:43 -070010719 hddLog(VOS_TRACE_LEVEL_INFO, "WAPI MODE IS %u",
Jeff Johnson295189b2012-06-20 16:38:30 -070010720 pAdapter->wapi_info.nWapiMode);
10721 tmp = (u16 *)ie;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010722 tmp = tmp + 2; // Skip element Id and Len, Version
Jeff Johnson295189b2012-06-20 16:38:30 -070010723 akmsuiteCount = WPA_GET_LE16(tmp);
10724 tmp = tmp + 1;
10725 akmlist = (int *)(tmp);
10726 if(akmsuiteCount <= MAX_NUM_AKM_SUITES)
10727 {
10728 memcpy(akmsuite, akmlist, (4*akmsuiteCount));
10729 }
10730 else
10731 {
Arif Hussain6d2a3322013-11-17 19:50:10 -080010732 hddLog(VOS_TRACE_LEVEL_FATAL, "Invalid akmSuite count");
Jeff Johnson295189b2012-06-20 16:38:30 -070010733 VOS_ASSERT(0);
10734 return -EINVAL;
10735 }
10736
10737 if (WAPI_PSK_AKM_SUITE == akmsuite[0])
10738 {
10739 hddLog(VOS_TRACE_LEVEL_INFO, "%s: WAPI AUTH MODE SET TO PSK",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -070010740 __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -070010741 pAdapter->wapi_info.wapiAuthMode = WAPI_AUTH_MODE_PSK;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010742 }
Jeff Johnson295189b2012-06-20 16:38:30 -070010743 if (WAPI_CERT_AKM_SUITE == akmsuite[0])
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010744 {
Jeff Johnson295189b2012-06-20 16:38:30 -070010745 hddLog(VOS_TRACE_LEVEL_INFO, "%s: WAPI AUTH MODE SET TO CERTIFICATE",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -070010746 __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -070010747 pAdapter->wapi_info.wapiAuthMode = WAPI_AUTH_MODE_CERT;
10748 }
10749 break;
10750#endif
10751 default:
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010752 hddLog (VOS_TRACE_LEVEL_ERROR,
Jeff Johnson295189b2012-06-20 16:38:30 -070010753 "%s Set UNKNOWN IE %X", __func__, elementId);
Madan Mohan Koyyalamudief3b66e2012-10-11 14:29:42 -070010754 /* when Unknown IE is received we should break and continue
10755 * to the next IE in the buffer instead we were returning
10756 * so changing this to break */
10757 break;
Jeff Johnson295189b2012-06-20 16:38:30 -070010758 }
10759 genie += eLen;
10760 remLen -= eLen;
10761 }
10762 EXIT();
10763 return 0;
10764}
10765
10766/*
Gopichand Nakkala18f0c262013-05-07 23:25:08 +053010767 * FUNCTION: hdd_isWPAIEPresent
10768 * Parse the received IE to find the WPA IE
10769 *
10770 */
10771static bool hdd_isWPAIEPresent(u8 *ie, u8 ie_len)
10772{
10773 v_U8_t eLen = 0;
10774 v_U16_t remLen = ie_len;
10775 v_U8_t elementId = 0;
10776
10777 while (remLen >= 2)
10778 {
10779 elementId = *ie++;
10780 eLen = *ie++;
10781 remLen -= 2;
10782 if (eLen > remLen)
10783 {
10784 hddLog(VOS_TRACE_LEVEL_ERROR,
10785 "%s: IE length is wrong %d", __func__, eLen);
10786 return FALSE;
10787 }
10788 if ((elementId == DOT11F_EID_WPA) && (remLen > 5))
10789 {
10790 /* OUI - 0x00 0X50 0XF2
10791 WPA Information Element - 0x01
10792 WPA version - 0x01*/
10793 if (0 == memcmp(&ie[0], "\x00\x50\xf2\x01\x01", 5))
10794 return TRUE;
10795 }
10796 ie += eLen;
10797 remLen -= eLen;
10798 }
10799 return FALSE;
10800}
10801
10802/*
Jeff Johnson295189b2012-06-20 16:38:30 -070010803 * FUNCTION: wlan_hdd_cfg80211_set_privacy
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010804 * This function is used to initialize the security
Jeff Johnson295189b2012-06-20 16:38:30 -070010805 * parameters during connect operation.
10806 */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010807int wlan_hdd_cfg80211_set_privacy( hdd_adapter_t *pAdapter,
Jeff Johnson295189b2012-06-20 16:38:30 -070010808 struct cfg80211_connect_params *req
10809 )
10810{
10811 int status = 0;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010812 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
Jeff Johnson295189b2012-06-20 16:38:30 -070010813 ENTER();
10814
10815 /*set wpa version*/
10816 pWextState->wpaVersion = IW_AUTH_WPA_VERSION_DISABLED;
10817
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010818 if (req->crypto.wpa_versions)
Jeff Johnson295189b2012-06-20 16:38:30 -070010819 {
Gopichand Nakkala781ded42013-06-28 12:10:45 +053010820 if (NL80211_WPA_VERSION_1 == req->crypto.wpa_versions)
Jeff Johnson295189b2012-06-20 16:38:30 -070010821 {
10822 pWextState->wpaVersion = IW_AUTH_WPA_VERSION_WPA;
10823 }
10824 else if (NL80211_WPA_VERSION_2 == req->crypto.wpa_versions)
10825 {
10826 pWextState->wpaVersion = IW_AUTH_WPA_VERSION_WPA2;
10827 }
10828 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010829
10830 hddLog(VOS_TRACE_LEVEL_INFO, "%s: set wpa version to %d", __func__,
Jeff Johnson295189b2012-06-20 16:38:30 -070010831 pWextState->wpaVersion);
10832
10833 /*set authentication type*/
10834 status = wlan_hdd_cfg80211_set_auth_type(pAdapter, req->auth_type);
10835
10836 if (0 > status)
10837 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010838 hddLog(VOS_TRACE_LEVEL_ERROR,
Jeff Johnson295189b2012-06-20 16:38:30 -070010839 "%s: failed to set authentication type ", __func__);
10840 return status;
10841 }
10842
10843 /*set key mgmt type*/
10844 if (req->crypto.n_akm_suites)
10845 {
10846 status = wlan_hdd_set_akm_suite(pAdapter, req->crypto.akm_suites[0]);
10847 if (0 > status)
10848 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010849 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: failed to set akm suite",
Jeff Johnson295189b2012-06-20 16:38:30 -070010850 __func__);
10851 return status;
10852 }
10853 }
10854
10855 /*set pairwise cipher type*/
10856 if (req->crypto.n_ciphers_pairwise)
10857 {
10858 status = wlan_hdd_cfg80211_set_cipher(pAdapter,
10859 req->crypto.ciphers_pairwise[0], true);
10860 if (0 > status)
10861 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010862 hddLog(VOS_TRACE_LEVEL_ERROR,
Jeff Johnson295189b2012-06-20 16:38:30 -070010863 "%s: failed to set unicast cipher type", __func__);
10864 return status;
10865 }
10866 }
10867 else
10868 {
10869 /*Reset previous cipher suite to none*/
10870 status = wlan_hdd_cfg80211_set_cipher(pAdapter, 0, true);
10871 if (0 > status)
10872 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010873 hddLog(VOS_TRACE_LEVEL_ERROR,
Jeff Johnson295189b2012-06-20 16:38:30 -070010874 "%s: failed to set unicast cipher type", __func__);
10875 return status;
10876 }
10877 }
10878
10879 /*set group cipher type*/
10880 status = wlan_hdd_cfg80211_set_cipher(pAdapter, req->crypto.cipher_group,
10881 false);
10882
10883 if (0 > status)
10884 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010885 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: failed to set mcast cipher type",
Jeff Johnson295189b2012-06-20 16:38:30 -070010886 __func__);
10887 return status;
10888 }
10889
Chet Lanctot186b5732013-03-18 10:26:30 -070010890#ifdef WLAN_FEATURE_11W
10891 pWextState->roamProfile.MFPEnabled = (req->mfp == NL80211_MFP_REQUIRED);
10892#endif
10893
Jeff Johnson295189b2012-06-20 16:38:30 -070010894 /*parse WPA/RSN IE, and set the correspoing fileds in Roam profile*/
10895 if (req->ie_len)
10896 {
10897 status = wlan_hdd_cfg80211_set_ie(pAdapter, req->ie, req->ie_len);
10898 if ( 0 > status)
10899 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010900 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: failed to parse the WPA/RSN IE",
Jeff Johnson295189b2012-06-20 16:38:30 -070010901 __func__);
10902 return status;
10903 }
10904 }
10905
10906 /*incase of WEP set default key information*/
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010907 if (req->key && req->key_len)
Jeff Johnson295189b2012-06-20 16:38:30 -070010908 {
10909 if ( (WLAN_CIPHER_SUITE_WEP40 == req->crypto.ciphers_pairwise[0])
10910 || (WLAN_CIPHER_SUITE_WEP104 == req->crypto.ciphers_pairwise[0])
10911 )
10912 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010913 if ( IW_AUTH_KEY_MGMT_802_1X
Jeff Johnson295189b2012-06-20 16:38:30 -070010914 == (pWextState->authKeyMgmt & IW_AUTH_KEY_MGMT_802_1X ))
10915 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010916 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Dynamic WEP not supported",
Jeff Johnson295189b2012-06-20 16:38:30 -070010917 __func__);
10918 return -EOPNOTSUPP;
10919 }
10920 else
10921 {
10922 u8 key_len = req->key_len;
10923 u8 key_idx = req->key_idx;
10924
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010925 if ((eCSR_SECURITY_WEP_KEYSIZE_MAX_BYTES >= key_len)
Jeff Johnson295189b2012-06-20 16:38:30 -070010926 && (CSR_MAX_NUM_KEY > key_idx)
10927 )
10928 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010929 hddLog(VOS_TRACE_LEVEL_INFO,
10930 "%s: setting default wep key, key_idx = %hu key_len %hu",
Jeff Johnson295189b2012-06-20 16:38:30 -070010931 __func__, key_idx, key_len);
10932 vos_mem_copy(
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010933 &pWextState->roamProfile.Keys.KeyMaterial[key_idx][0],
Jeff Johnson295189b2012-06-20 16:38:30 -070010934 req->key, key_len);
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010935 pWextState->roamProfile.Keys.KeyLength[key_idx] =
Jeff Johnson295189b2012-06-20 16:38:30 -070010936 (u8)key_len;
10937 pWextState->roamProfile.Keys.defaultIndex = (u8)key_idx;
10938 }
10939 }
10940 }
10941 }
10942
10943 return status;
10944}
10945
10946/*
Vinay Krishna Eranna21042322014-01-08 19:21:39 +053010947 * FUNCTION: wlan_hdd_try_disconnect
10948 * This function is used to disconnect from previous
10949 * connection
10950 */
10951static int wlan_hdd_try_disconnect( hdd_adapter_t *pAdapter )
10952{
10953 long ret = 0;
10954 hdd_station_ctx_t *pHddStaCtx;
10955 eMib_dot11DesiredBssType connectedBssType;
10956
10957 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
10958
10959 hdd_connGetConnectedBssType(pHddStaCtx,&connectedBssType );
10960
10961 if((eMib_dot11DesiredBssType_independent == connectedBssType) ||
10962 (eConnectionState_Associated == pHddStaCtx->conn_info.connState) ||
10963 (eConnectionState_IbssConnected == pHddStaCtx->conn_info.connState))
10964 {
10965 /* Issue disconnect to CSR */
10966 INIT_COMPLETION(pAdapter->disconnect_comp_var);
10967 if( eHAL_STATUS_SUCCESS ==
10968 sme_RoamDisconnect( WLAN_HDD_GET_HAL_CTX(pAdapter),
10969 pAdapter->sessionId,
10970 eCSR_DISCONNECT_REASON_UNSPECIFIED ) )
10971 {
10972 ret = wait_for_completion_interruptible_timeout(
10973 &pAdapter->disconnect_comp_var,
10974 msecs_to_jiffies(WLAN_WAIT_TIME_DISCONNECT));
10975 if (0 >= ret)
10976 {
10977 hddLog(LOGE, FL("Failed to receive disconnect event"));
10978 return -EALREADY;
10979 }
10980 }
10981 }
10982 else if(eConnectionState_Disconnecting == pHddStaCtx->conn_info.connState)
10983 {
10984 ret = wait_for_completion_interruptible_timeout(
10985 &pAdapter->disconnect_comp_var,
10986 msecs_to_jiffies(WLAN_WAIT_TIME_DISCONNECT));
10987 if (0 >= ret)
10988 {
10989 hddLog(LOGE, FL("Failed to receive disconnect event"));
10990 return -EALREADY;
10991 }
10992 }
10993
10994 return 0;
10995}
10996
10997/*
Agarwal Ashish51325b52014-06-16 16:50:49 +053010998 * FUNCTION: __wlan_hdd_cfg80211_connect
10999 * This function is used to start the association process
Jeff Johnson295189b2012-06-20 16:38:30 -070011000 */
Mahesh A Saptasagarfafb7fe2014-05-16 13:19:37 +053011001static int __wlan_hdd_cfg80211_connect( struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -070011002 struct net_device *ndev,
11003 struct cfg80211_connect_params *req
11004 )
11005{
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053011006 int status;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011007 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( ndev );
Jeff Johnson295189b2012-06-20 16:38:30 -070011008 VOS_STATUS exitbmpsStatus = VOS_STATUS_E_INVAL;
Sushant Kaushikba6764e2014-06-30 19:52:09 +053011009 hdd_context_t *pHddCtx = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -070011010
11011 ENTER();
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053011012
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053011013 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
11014 TRACE_CODE_HDD_CFG80211_CONNECT,
11015 pAdapter->sessionId, pAdapter->device_mode));
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011016 hddLog(VOS_TRACE_LEVEL_INFO,
Sushant Kaushik8bc7df22014-04-09 17:55:29 +053011017 "%s: device_mode = %s (%d)", __func__,
11018 hdd_device_modetoString(pAdapter->device_mode),
11019 pAdapter->device_mode);
Jeff Johnson295189b2012-06-20 16:38:30 -070011020
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053011021 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Rajesh Chauhana0516c62014-01-30 16:11:18 -080011022 if (!pHddCtx)
11023 {
11024 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
11025 "%s: HDD context is null", __func__);
Agarwal Ashish51325b52014-06-16 16:50:49 +053011026 return -EINVAL;
Rajesh Chauhana0516c62014-01-30 16:11:18 -080011027 }
11028
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053011029 status = wlan_hdd_validate_context(pHddCtx);
11030
11031 if (0 != status)
Jeff Johnson295189b2012-06-20 16:38:30 -070011032 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053011033 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
11034 "%s: HDD context is not valid", __func__);
11035 return status;
Jeff Johnson295189b2012-06-20 16:38:30 -070011036 }
11037
Agarwal Ashish51325b52014-06-16 16:50:49 +053011038 if (vos_max_concurrent_connections_reached()) {
11039 hddLog(VOS_TRACE_LEVEL_INFO, FL("Reached max concurrent connections"));
11040 return -ECONNREFUSED;
11041 }
11042
Jeff Johnson295189b2012-06-20 16:38:30 -070011043#ifdef WLAN_BTAMP_FEATURE
11044 //Infra connect not supported when AMP traffic is on.
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011045 if( VOS_TRUE == WLANBAP_AmpSessionOn() )
Jeff Johnson295189b2012-06-20 16:38:30 -070011046 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011047 hddLog(VOS_TRACE_LEVEL_ERROR,
Jeff Johnson295189b2012-06-20 16:38:30 -070011048 "%s: No connection when AMP is on", __func__);
Madan Mohan Koyyalamudicae253a2012-11-06 19:10:35 -080011049 return -ECONNREFUSED;
Jeff Johnson295189b2012-06-20 16:38:30 -070011050 }
11051#endif
Vinay Krishna Eranna21042322014-01-08 19:21:39 +053011052
11053 //If Device Mode is Station Concurrent Sessions Exit BMps
11054 //P2P Mode will be taken care in Open/close adapter
11055 if((WLAN_HDD_INFRA_STATION == pAdapter->device_mode) &&
Agarwal Ashish51325b52014-06-16 16:50:49 +053011056 (vos_concurrent_open_sessions_running())) {
11057 exitbmpsStatus = hdd_disable_bmps_imps(pHddCtx,
11058 WLAN_HDD_INFRA_STATION);
Vinay Krishna Eranna21042322014-01-08 19:21:39 +053011059 }
11060
11061 /*Try disconnecting if already in connected state*/
11062 status = wlan_hdd_try_disconnect(pAdapter);
11063 if ( 0 > status)
11064 {
11065 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Failed to disconnect the existing"
11066 " connection"));
11067 return -EALREADY;
11068 }
11069
Jeff Johnson295189b2012-06-20 16:38:30 -070011070 /*initialise security parameters*/
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011071 status = wlan_hdd_cfg80211_set_privacy(pAdapter, req);
Jeff Johnson295189b2012-06-20 16:38:30 -070011072
11073 if ( 0 > status)
11074 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011075 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: failed to set security params",
Jeff Johnson295189b2012-06-20 16:38:30 -070011076 __func__);
11077 return status;
11078 }
Mohit Khanna765234a2012-09-11 15:08:35 -070011079 if ( req->channel )
11080 {
11081 status = wlan_hdd_cfg80211_connect_start(pAdapter, req->ssid,
11082 req->ssid_len, req->bssid,
11083 req->channel->hw_value);
11084 }
11085 else
11086 {
11087 status = wlan_hdd_cfg80211_connect_start(pAdapter, req->ssid,
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053011088 req->ssid_len, req->bssid, 0);
Mohit Khanna765234a2012-09-11 15:08:35 -070011089 }
Jeff Johnson295189b2012-06-20 16:38:30 -070011090
11091 if (0 > status)
11092 {
11093 //ReEnable BMPS if disabled
11094 if((VOS_STATUS_SUCCESS == exitbmpsStatus) &&
11095 (NULL != pHddCtx))
11096 {
Gopichand Nakkalaa2fe5b02013-06-06 16:32:28 +053011097 if (pHddCtx->hdd_wlan_suspended)
11098 {
11099 hdd_set_pwrparams(pHddCtx);
11100 }
Jeff Johnson295189b2012-06-20 16:38:30 -070011101 //ReEnable Bmps and Imps back
11102 hdd_enable_bmps_imps(pHddCtx);
11103 }
Agarwal Ashish51325b52014-06-16 16:50:49 +053011104 hddLog(VOS_TRACE_LEVEL_ERROR, FL("connect failed"));
Jeff Johnson295189b2012-06-20 16:38:30 -070011105 return status;
11106 }
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053011107 pHddCtx->isAmpAllowed = VOS_FALSE;
Jeff Johnson295189b2012-06-20 16:38:30 -070011108 EXIT();
11109 return status;
11110}
11111
Mahesh A Saptasagarfafb7fe2014-05-16 13:19:37 +053011112static int wlan_hdd_cfg80211_connect( struct wiphy *wiphy,
11113 struct net_device *ndev,
11114 struct cfg80211_connect_params *req)
11115{
11116 int ret;
11117 vos_ssr_protect(__func__);
11118 ret = __wlan_hdd_cfg80211_connect(wiphy, ndev, req);
11119 vos_ssr_unprotect(__func__);
11120
11121 return ret;
11122}
Jeff Johnson295189b2012-06-20 16:38:30 -070011123
11124/*
Gopichand Nakkala78a6c812013-05-13 16:39:49 +053011125 * FUNCTION: wlan_hdd_disconnect
11126 * This function is used to issue a disconnect request to SME
11127 */
11128int wlan_hdd_disconnect( hdd_adapter_t *pAdapter, u16 reason )
11129{
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053011130 int status;
Gopichand Nakkala78a6c812013-05-13 16:39:49 +053011131 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053011132 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Abhishek Singhdc2bfd42014-06-19 17:59:05 +053011133 long ret;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053011134
11135 status = wlan_hdd_validate_context(pHddCtx);
11136
11137 if (0 != status)
11138 {
11139 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
11140 "%s: HDD context is not valid", __func__);
11141 return status;
11142 }
11143
11144 pHddCtx->isAmpAllowed = VOS_TRUE;
Agarwal Ashishc65b5ca2014-07-28 21:02:57 +053011145
Agarwal Ashish47d18112014-08-04 19:55:07 +053011146 /* Need to apply spin lock before decreasing active sessions
11147 * as there can be chance for double decrement if context switch
11148 * Calls hdd_DisConnectHandler.
11149 */
11150
11151 spin_lock_bh(&pAdapter->lock_for_active_session);
Agarwal Ashishc65b5ca2014-07-28 21:02:57 +053011152 if (eConnectionState_Associated == pHddStaCtx->conn_info.connState)
11153 {
Agarwal Ashishc65b5ca2014-07-28 21:02:57 +053011154 wlan_hdd_decr_active_session(pHddCtx, pAdapter->device_mode);
11155 }
Agarwal Ashish47d18112014-08-04 19:55:07 +053011156 hdd_connSetConnectionState( pHddStaCtx, eConnectionState_Disconnecting );
11157 spin_unlock_bh(&pAdapter->lock_for_active_session);
Agarwal Ashishc65b5ca2014-07-28 21:02:57 +053011158
Abhishek Singhf4669da2014-05-26 15:07:49 +053011159 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Agarwal Ashish47d18112014-08-04 19:55:07 +053011160 FL( "Set HDD connState to eConnectionState_Disconnecting" ));
11161
Gopichand Nakkala78a6c812013-05-13 16:39:49 +053011162 INIT_COMPLETION(pAdapter->disconnect_comp_var);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053011163
Mihir Shete182a0b22014-08-18 16:08:48 +053011164 /*
11165 * stop tx queues before deleting STA/BSS context from the firmware.
11166 * tx has to be disabled because the firmware can get busy dropping
11167 * the tx frames after BSS/STA has been deleted and will not send
11168 * back a response resulting in WDI timeout
11169 */
11170 netif_tx_disable(pAdapter->dev);
11171 netif_carrier_off(pAdapter->dev);
Arun Kumar Khandavalli94a2bb02013-12-28 19:17:25 +053011172
Mihir Shete182a0b22014-08-18 16:08:48 +053011173 /*issue disconnect*/
Gopichand Nakkala78a6c812013-05-13 16:39:49 +053011174 status = sme_RoamDisconnect( WLAN_HDD_GET_HAL_CTX(pAdapter),
11175 pAdapter->sessionId, reason);
Abhishek Singhdc2bfd42014-06-19 17:59:05 +053011176 if(eHAL_STATUS_CMD_NOT_QUEUED == status)
11177 {
11178 hddLog(VOS_TRACE_LEVEL_INFO,
11179 FL("status = %d, already disconnected"),
11180 (int)status );
Gopichand Nakkala78a6c812013-05-13 16:39:49 +053011181
Abhishek Singhdc2bfd42014-06-19 17:59:05 +053011182 }
11183 else if ( 0 != status )
Gopichand Nakkala78a6c812013-05-13 16:39:49 +053011184 {
11185 hddLog(VOS_TRACE_LEVEL_ERROR,
Arif Hussain6d2a3322013-11-17 19:50:10 -080011186 "%s csrRoamDisconnect failure, returned %d",
Gopichand Nakkala78a6c812013-05-13 16:39:49 +053011187 __func__, (int)status );
11188 return -EINVAL;
11189 }
Abhishek Singhdc2bfd42014-06-19 17:59:05 +053011190 ret = wait_for_completion_interruptible_timeout(
Gopichand Nakkala78a6c812013-05-13 16:39:49 +053011191 &pAdapter->disconnect_comp_var,
11192 msecs_to_jiffies(WLAN_WAIT_TIME_DISCONNECT));
Abhishek Singhdc2bfd42014-06-19 17:59:05 +053011193 if (!ret && ( eHAL_STATUS_CMD_NOT_QUEUED != status ))
c_hpothu6ff1c3c2013-10-01 19:01:57 +053011194 {
11195 hddLog(VOS_TRACE_LEVEL_ERROR,
Mahesh A Saptasagar05a357e2014-02-26 16:28:06 +053011196 "%s: Failed to disconnect, timed out", __func__);
11197 return -ETIMEDOUT;
11198 }
Abhishek Singhdc2bfd42014-06-19 17:59:05 +053011199 else if (ret == -ERESTARTSYS)
Mahesh A Saptasagar05a357e2014-02-26 16:28:06 +053011200 {
11201 hddLog(VOS_TRACE_LEVEL_ERROR,
11202 "%s: Failed to disconnect, wait interrupted", __func__);
Abhishek Singhdc2bfd42014-06-19 17:59:05 +053011203 return ret;
c_hpothu6ff1c3c2013-10-01 19:01:57 +053011204 }
Abhishek Singhdc2bfd42014-06-19 17:59:05 +053011205 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
11206 FL("Set HDD connState to eConnectionState_NotConnected"));
11207 pHddStaCtx->conn_info.connState = eConnectionState_NotConnected;
11208
Mahesh A Saptasagar05a357e2014-02-26 16:28:06 +053011209 return 0;
Gopichand Nakkala78a6c812013-05-13 16:39:49 +053011210}
11211
11212
11213/*
Mahesh A Saptasagarfafb7fe2014-05-16 13:19:37 +053011214 * FUNCTION: __wlan_hdd_cfg80211_disconnect
Jeff Johnson295189b2012-06-20 16:38:30 -070011215 * This function is used to issue a disconnect request to SME
11216 */
Mahesh A Saptasagarfafb7fe2014-05-16 13:19:37 +053011217static int __wlan_hdd_cfg80211_disconnect( struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -070011218 struct net_device *dev,
11219 u16 reason
11220 )
11221{
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011222 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( dev );
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053011223 tCsrRoamProfile *pRoamProfile =
11224 &(WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter))->roamProfile;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053011225 int status;
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053011226 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
11227 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Gopichand Nakkalaaa353782013-05-17 20:36:22 +053011228#ifdef FEATURE_WLAN_TDLS
Gopichand Nakkala2a0a1572013-02-10 21:39:16 -080011229 tANI_U8 staIdx;
11230#endif
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011231
Jeff Johnson295189b2012-06-20 16:38:30 -070011232 ENTER();
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053011233
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053011234 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
11235 TRACE_CODE_HDD_CFG80211_DISCONNECT,
11236 pAdapter->sessionId, reason));
Sushant Kaushik8bc7df22014-04-09 17:55:29 +053011237 hddLog(VOS_TRACE_LEVEL_INFO, "%s: device_mode = %s(%d)",
11238 __func__, hdd_device_modetoString(pAdapter->device_mode),
11239 pAdapter->device_mode);
Jeff Johnson295189b2012-06-20 16:38:30 -070011240
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011241 hddLog(VOS_TRACE_LEVEL_INFO, "%s: Disconnect called with reason code %d",
11242 __func__, reason);
Jeff Johnson295189b2012-06-20 16:38:30 -070011243
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053011244 status = wlan_hdd_validate_context(pHddCtx);
11245
11246 if (0 != status)
Jeff Johnson295189b2012-06-20 16:38:30 -070011247 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053011248 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
11249 "%s: HDD context is not valid", __func__);
11250 return status;
Jeff Johnson295189b2012-06-20 16:38:30 -070011251 }
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053011252
Jeff Johnson295189b2012-06-20 16:38:30 -070011253 if (NULL != pRoamProfile)
11254 {
11255 /*issue disconnect request to SME, if station is in connected state*/
Mahesh A Saptasagar280fd5a2013-12-05 15:38:31 +053011256 if ((pHddStaCtx->conn_info.connState == eConnectionState_Associated) ||
11257 (pHddStaCtx->conn_info.connState == eConnectionState_Connecting))
Jeff Johnson295189b2012-06-20 16:38:30 -070011258 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011259 eCsrRoamDisconnectReason reasonCode =
Jeff Johnson295189b2012-06-20 16:38:30 -070011260 eCSR_DISCONNECT_REASON_UNSPECIFIED;
Gopichand Nakkalaaa353782013-05-17 20:36:22 +053011261 hdd_scaninfo_t *pScanInfo;
Jeff Johnson295189b2012-06-20 16:38:30 -070011262 switch(reason)
11263 {
11264 case WLAN_REASON_MIC_FAILURE:
11265 reasonCode = eCSR_DISCONNECT_REASON_MIC_ERROR;
11266 break;
11267
11268 case WLAN_REASON_DISASSOC_DUE_TO_INACTIVITY:
11269 case WLAN_REASON_DISASSOC_AP_BUSY:
11270 case WLAN_REASON_CLASS3_FRAME_FROM_NONASSOC_STA:
11271 reasonCode = eCSR_DISCONNECT_REASON_DISASSOC;
11272 break;
11273
11274 case WLAN_REASON_PREV_AUTH_NOT_VALID:
11275 case WLAN_REASON_CLASS2_FRAME_FROM_NONAUTH_STA:
Abhishek Singhc3269a52014-05-21 17:22:24 +053011276 case WLAN_REASON_DEAUTH_LEAVING:
Jeff Johnson295189b2012-06-20 16:38:30 -070011277 reasonCode = eCSR_DISCONNECT_REASON_DEAUTH;
11278 break;
11279
Jeff Johnson295189b2012-06-20 16:38:30 -070011280 default:
11281 reasonCode = eCSR_DISCONNECT_REASON_UNSPECIFIED;
11282 break;
11283 }
Gopichand Nakkalaaa353782013-05-17 20:36:22 +053011284 pScanInfo = &pHddCtx->scan_info;
11285 if (pScanInfo->mScanPending)
11286 {
Srinivas, Dasari138af4f2014-02-07 11:13:45 +053011287 hddLog(VOS_TRACE_LEVEL_INFO, "Disconnect is in progress, "
Gopichand Nakkalaaa353782013-05-17 20:36:22 +053011288 "Aborting Scan");
Kaushik, Sushant4975a572014-10-21 16:07:48 +053011289 hdd_abort_mac_scan(pHddCtx, pScanInfo->sessionId,
Srinivas, Dasari138af4f2014-02-07 11:13:45 +053011290 eCSR_SCAN_ABORT_DEFAULT);
Gopichand Nakkalaaa353782013-05-17 20:36:22 +053011291 }
Jeff Johnson295189b2012-06-20 16:38:30 -070011292
Gopichand Nakkala2a0a1572013-02-10 21:39:16 -080011293#ifdef FEATURE_WLAN_TDLS
11294 /* First clean up the tdls peers if any */
Gopichand Nakkala4327a152013-03-04 23:22:42 -080011295 for (staIdx = 0 ; staIdx < HDD_MAX_NUM_TDLS_STA; staIdx++)
Gopichand Nakkala2a0a1572013-02-10 21:39:16 -080011296 {
Gopichand Nakkala4327a152013-03-04 23:22:42 -080011297 if ((pHddCtx->tdlsConnInfo[staIdx].sessionId == pAdapter->sessionId) &&
11298 (pHddCtx->tdlsConnInfo[staIdx].staId))
Gopichand Nakkala2a0a1572013-02-10 21:39:16 -080011299 {
Hoonki Lee11f7dda2013-02-14 16:55:44 -080011300 uint8 *mac;
Gopichand Nakkala4327a152013-03-04 23:22:42 -080011301 mac = pHddCtx->tdlsConnInfo[staIdx].peerMac.bytes;
Hoonki Lee11f7dda2013-02-14 16:55:44 -080011302 VOS_TRACE(VOS_MODULE_ID_HDD, TDLS_LOG_LEVEL,
Gopichand Nakkalac87400e2013-03-13 18:51:00 -070011303 "%s: call sme_DeleteTdlsPeerSta staId %d sessionId %d " MAC_ADDRESS_STR,
Gopichand Nakkala4327a152013-03-04 23:22:42 -080011304 __func__, pHddCtx->tdlsConnInfo[staIdx].staId, pAdapter->sessionId,
Gopichand Nakkalac87400e2013-03-13 18:51:00 -070011305 MAC_ADDR_ARRAY(mac));
Gopichand Nakkala2a0a1572013-02-10 21:39:16 -080011306 sme_DeleteTdlsPeerSta(WLAN_HDD_GET_HAL_CTX(pAdapter),
Gopichand Nakkala4327a152013-03-04 23:22:42 -080011307 pAdapter->sessionId,
11308 mac);
Gopichand Nakkala2a0a1572013-02-10 21:39:16 -080011309 }
11310 }
11311#endif
Arun Kumar Khandavalli94a2bb02013-12-28 19:17:25 +053011312 hddLog(LOG1, FL("Disconnecting with reasoncode:%u"), reasonCode);
Gopichand Nakkala78a6c812013-05-13 16:39:49 +053011313 status = wlan_hdd_disconnect(pAdapter, reasonCode);
11314 if ( 0 != status )
Jeff Johnson295189b2012-06-20 16:38:30 -070011315 {
11316 hddLog(VOS_TRACE_LEVEL_ERROR,
Arif Hussain6d2a3322013-11-17 19:50:10 -080011317 "%s wlan_hdd_disconnect failure, returned %d",
Jeff Johnson295189b2012-06-20 16:38:30 -070011318 __func__, (int)status );
11319 return -EINVAL;
11320 }
Jeff Johnson295189b2012-06-20 16:38:30 -070011321 }
Mahesh A Saptasagar280fd5a2013-12-05 15:38:31 +053011322 else
11323 {
11324 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: unexpected cfg disconnect API"
11325 "called while in %d state", __func__,
11326 pHddStaCtx->conn_info.connState);
11327 }
Jeff Johnson295189b2012-06-20 16:38:30 -070011328 }
11329 else
11330 {
11331 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: No valid roam profile", __func__);
11332 }
11333
11334 return status;
11335}
11336
Mahesh A Saptasagarfafb7fe2014-05-16 13:19:37 +053011337static int wlan_hdd_cfg80211_disconnect( struct wiphy *wiphy,
11338 struct net_device *dev,
11339 u16 reason
11340 )
11341{
11342 int ret;
11343 vos_ssr_protect(__func__);
11344 ret = __wlan_hdd_cfg80211_disconnect(wiphy, dev, reason);
11345 vos_ssr_unprotect(__func__);
11346
11347 return ret;
11348}
Gopichand Nakkala78a6c812013-05-13 16:39:49 +053011349
Jeff Johnson295189b2012-06-20 16:38:30 -070011350/*
11351 * FUNCTION: wlan_hdd_cfg80211_set_privacy_ibss
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011352 * This function is used to initialize the security
Jeff Johnson295189b2012-06-20 16:38:30 -070011353 * settings in IBSS mode.
11354 */
11355static int wlan_hdd_cfg80211_set_privacy_ibss(
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011356 hdd_adapter_t *pAdapter,
Jeff Johnson295189b2012-06-20 16:38:30 -070011357 struct cfg80211_ibss_params *params
11358 )
11359{
11360 int status = 0;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011361 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
Jeff Johnson295189b2012-06-20 16:38:30 -070011362 eCsrEncryptionType encryptionType = eCSR_ENCRYPT_TYPE_NONE;
11363 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011364
Jeff Johnson295189b2012-06-20 16:38:30 -070011365 ENTER();
11366
11367 pWextState->wpaVersion = IW_AUTH_WPA_VERSION_DISABLED;
Ravi Joshib58ca0d2013-10-29 09:50:23 -070011368 vos_mem_zero(&pHddStaCtx->ibss_enc_key, sizeof(tCsrRoamSetKey));
Jeff Johnson295189b2012-06-20 16:38:30 -070011369
11370 if (params->ie_len && ( NULL != params->ie) )
11371 {
Shailender Karmuchi67edd312013-06-18 16:30:48 -070011372 if (wlan_hdd_cfg80211_get_ie_ptr (params->ie,
11373 params->ie_len, WLAN_EID_RSN ))
Jeff Johnson295189b2012-06-20 16:38:30 -070011374 {
11375 pWextState->wpaVersion = IW_AUTH_WPA_VERSION_WPA2;
11376 encryptionType = eCSR_ENCRYPT_TYPE_AES;
11377 }
Shailender Karmuchi67edd312013-06-18 16:30:48 -070011378 else if ( hdd_isWPAIEPresent (params->ie, params->ie_len ))
Jeff Johnson295189b2012-06-20 16:38:30 -070011379 {
Shailender Karmuchi642e9812013-05-30 14:34:49 -070011380 tDot11fIEWPA dot11WPAIE;
11381 tHalHandle halHandle = WLAN_HDD_GET_HAL_CTX(pAdapter);
Shailender Karmuchi67edd312013-06-18 16:30:48 -070011382 u8 *ie;
Shailender Karmuchi642e9812013-05-30 14:34:49 -070011383
Wilson Yang00256342013-10-10 23:13:38 -070011384 memset(&dot11WPAIE, 0, sizeof(dot11WPAIE));
Shailender Karmuchi67edd312013-06-18 16:30:48 -070011385 ie = wlan_hdd_cfg80211_get_ie_ptr (params->ie,
11386 params->ie_len, DOT11F_EID_WPA);
11387 if ( NULL != ie )
11388 {
11389 pWextState->wpaVersion = IW_AUTH_WPA_VERSION_WPA;
11390 // Unpack the WPA IE
11391 //Skip past the EID byte and length byte - and four byte WiFi OUI
11392 dot11fUnpackIeWPA((tpAniSirGlobal) halHandle,
11393 &ie[2+4],
11394 ie[1] - 4,
11395 &dot11WPAIE);
11396 /*Extract the multicast cipher, the encType for unicast
11397 cipher for wpa-none is none*/
11398 encryptionType =
11399 hdd_TranslateWPAToCsrEncryptionType(dot11WPAIE.multicast_cipher);
11400 }
Jeff Johnson295189b2012-06-20 16:38:30 -070011401 }
Shailender Karmuchi67edd312013-06-18 16:30:48 -070011402
Jeff Johnson295189b2012-06-20 16:38:30 -070011403 status = wlan_hdd_cfg80211_set_ie(pAdapter, params->ie, params->ie_len);
11404
11405 if (0 > status)
11406 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011407 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: failed to parse WPA/RSN IE",
Jeff Johnson295189b2012-06-20 16:38:30 -070011408 __func__);
11409 return status;
11410 }
11411 }
11412
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011413 pWextState->roamProfile.AuthType.authType[0] =
11414 pHddStaCtx->conn_info.authType =
Jeff Johnson295189b2012-06-20 16:38:30 -070011415 eCSR_AUTH_TYPE_OPEN_SYSTEM;
11416
11417 if (params->privacy)
11418 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011419 /* Security enabled IBSS, At this time there is no information available
11420 * about the security paramters, so initialise the encryption type to
Jeff Johnson295189b2012-06-20 16:38:30 -070011421 * eCSR_ENCRYPT_TYPE_WEP40_STATICKEY.
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011422 * The correct security parameters will be updated later in
Jeff Johnson295189b2012-06-20 16:38:30 -070011423 * wlan_hdd_cfg80211_add_key */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011424 /* Hal expects encryption type to be set inorder
Jeff Johnson295189b2012-06-20 16:38:30 -070011425 *enable privacy bit in beacons */
11426
11427 encryptionType = eCSR_ENCRYPT_TYPE_WEP40_STATICKEY;
11428 }
Shailender Karmuchi642e9812013-05-30 14:34:49 -070011429 VOS_TRACE (VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO_HIGH,
11430 "encryptionType=%d", encryptionType);
Jeff Johnson295189b2012-06-20 16:38:30 -070011431 pHddStaCtx->conn_info.ucEncryptionType = encryptionType;
11432 pWextState->roamProfile.EncryptionType.numEntries = 1;
11433 pWextState->roamProfile.EncryptionType.encryptionType[0] = encryptionType;
Jeff Johnson295189b2012-06-20 16:38:30 -070011434 return status;
11435}
11436
11437/*
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053011438 * FUNCTION: __wlan_hdd_cfg80211_join_ibss
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011439 * This function is used to create/join an IBSS
Jeff Johnson295189b2012-06-20 16:38:30 -070011440 */
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053011441static int __wlan_hdd_cfg80211_join_ibss( struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -070011442 struct net_device *dev,
11443 struct cfg80211_ibss_params *params
11444 )
11445{
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011446 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( dev );
Jeff Johnson295189b2012-06-20 16:38:30 -070011447 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
11448 tCsrRoamProfile *pRoamProfile;
11449 int status;
krunal sonie9002db2013-11-25 14:24:17 -080011450 bool alloc_bssid = VOS_FALSE;
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053011451 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
11452 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Jeff Johnson295189b2012-06-20 16:38:30 -070011453
11454 ENTER();
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053011455
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053011456 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
11457 TRACE_CODE_HDD_CFG80211_JOIN_IBSS,
11458 pAdapter->sessionId, pAdapter->device_mode));
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011459 hddLog(VOS_TRACE_LEVEL_INFO,
Sushant Kaushik8bc7df22014-04-09 17:55:29 +053011460 "%s: device_mode = %s (%d)", __func__,
11461 hdd_device_modetoString(pAdapter->device_mode),
11462 pAdapter->device_mode);
Jeff Johnson295189b2012-06-20 16:38:30 -070011463
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053011464 status = wlan_hdd_validate_context(pHddCtx);
11465
11466 if (0 != status)
Jeff Johnson295189b2012-06-20 16:38:30 -070011467 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053011468 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
11469 "%s: HDD context is not valid", __func__);
11470 return status;
Jeff Johnson295189b2012-06-20 16:38:30 -070011471 }
11472
11473 if (NULL == pWextState)
11474 {
Arif Hussain6d2a3322013-11-17 19:50:10 -080011475 hddLog (VOS_TRACE_LEVEL_ERROR, "%s ERROR: Data Storage Corruption",
Jeff Johnson295189b2012-06-20 16:38:30 -070011476 __func__);
11477 return -EIO;
11478 }
11479
Agarwal Ashish51325b52014-06-16 16:50:49 +053011480 if (vos_max_concurrent_connections_reached()) {
11481 hddLog(VOS_TRACE_LEVEL_INFO, FL("Reached max concurrent connections"));
11482 return -ECONNREFUSED;
11483 }
11484
Vinay Krishna Eranna21042322014-01-08 19:21:39 +053011485 /*Try disconnecting if already in connected state*/
11486 status = wlan_hdd_try_disconnect(pAdapter);
11487 if ( 0 > status)
11488 {
11489 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Failed to disconnect the existing"
11490 " IBSS connection"));
11491 return -EALREADY;
11492 }
11493
Jeff Johnson295189b2012-06-20 16:38:30 -070011494 pRoamProfile = &pWextState->roamProfile;
11495
11496 if ( eCSR_BSS_TYPE_START_IBSS != pRoamProfile->BSSType )
11497 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011498 hddLog (VOS_TRACE_LEVEL_ERROR,
Arif Hussain6d2a3322013-11-17 19:50:10 -080011499 "%s Interface type is not set to IBSS", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -070011500 return -EINVAL;
11501 }
11502
Praveen Kumar Sirisillad123d142013-09-24 16:50:13 -070011503 /* BSSID is provided by upper layers hence no need to AUTO generate */
11504 if (NULL != params->bssid) {
11505 if (ccmCfgSetInt(pHddCtx->hHal, WNI_CFG_IBSS_AUTO_BSSID, 0,
11506 NULL, eANI_BOOLEAN_FALSE)==eHAL_STATUS_FAILURE) {
11507 hddLog (VOS_TRACE_LEVEL_ERROR,
11508 "%s:ccmCfgStInt faild for WNI_CFG_IBSS_AUTO_BSSID", __func__);
11509 return -EIO;
11510 }
11511 }
krunal sonie9002db2013-11-25 14:24:17 -080011512 else if(pHddCtx->cfg_ini->isCoalesingInIBSSAllowed == 0)
11513 {
11514 if (ccmCfgSetInt(pHddCtx->hHal, WNI_CFG_IBSS_AUTO_BSSID, 0,
11515 NULL, eANI_BOOLEAN_FALSE)==eHAL_STATUS_FAILURE)
11516 {
11517 hddLog (VOS_TRACE_LEVEL_ERROR,
11518 "%s:ccmCfgStInt faild for WNI_CFG_IBSS_AUTO_BSSID", __func__);
11519 return -EIO;
11520 }
11521 params->bssid = vos_mem_malloc(sizeof(VOS_MAC_ADDR_SIZE));
11522 if (!params->bssid)
11523 {
11524 hddLog (VOS_TRACE_LEVEL_ERROR,
11525 "%s:Failed memory allocation", __func__);
11526 return -EIO;
11527 }
11528 vos_mem_copy((v_U8_t *)params->bssid,
11529 (v_U8_t *)&pHddCtx->cfg_ini->IbssBssid.bytes[0],
11530 VOS_MAC_ADDR_SIZE);
11531 alloc_bssid = VOS_TRUE;
11532 }
Praveen Kumar Sirisillad123d142013-09-24 16:50:13 -070011533
Jeff Johnson295189b2012-06-20 16:38:30 -070011534 /* Set Channel */
Yue Maf49ba872013-08-19 12:04:25 -070011535 if (NULL !=
11536#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,8,0))
11537 params->chandef.chan)
11538#else
11539 params->channel)
11540#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070011541 {
11542 u8 channelNum;
Shailender Karmuchi15cd0672013-05-15 19:50:04 -070011543 v_U32_t numChans = WNI_CFG_VALID_CHANNEL_LIST_LEN;
11544 v_U8_t validChan[WNI_CFG_VALID_CHANNEL_LIST_LEN];
11545 tHalHandle hHal = WLAN_HDD_GET_HAL_CTX(pAdapter);
11546 int indx;
Jeff Johnson295189b2012-06-20 16:38:30 -070011547
11548 /* Get channel number */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011549 channelNum =
Yue Maf49ba872013-08-19 12:04:25 -070011550 ieee80211_frequency_to_channel(
11551#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,8,0))
11552 params->chandef.chan->center_freq);
11553#else
11554 params->channel->center_freq);
11555#endif
Shailender Karmuchi15cd0672013-05-15 19:50:04 -070011556
11557 if (0 != ccmCfgGetStr(hHal, WNI_CFG_VALID_CHANNEL_LIST,
11558 validChan, &numChans))
Jeff Johnson295189b2012-06-20 16:38:30 -070011559 {
Shailender Karmuchi15cd0672013-05-15 19:50:04 -070011560 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: No valid channel list",
11561 __func__);
11562 return -EOPNOTSUPP;
Jeff Johnson295189b2012-06-20 16:38:30 -070011563 }
Shailender Karmuchi15cd0672013-05-15 19:50:04 -070011564
11565 for (indx = 0; indx < numChans; indx++)
Jeff Johnson295189b2012-06-20 16:38:30 -070011566 {
Shailender Karmuchi15cd0672013-05-15 19:50:04 -070011567 if (channelNum == validChan[indx])
11568 {
11569 break;
11570 }
11571 }
11572 if (indx >= numChans)
11573 {
11574 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Not valid Channel %d",
Jeff Johnson295189b2012-06-20 16:38:30 -070011575 __func__, channelNum);
11576 return -EINVAL;
11577 }
Shailender Karmuchi15cd0672013-05-15 19:50:04 -070011578 /* Set the Operational Channel */
11579 hddLog(VOS_TRACE_LEVEL_INFO_HIGH, "%s: set channel %d", __func__,
11580 channelNum);
11581 pRoamProfile->ChannelInfo.numOfChannels = 1;
11582 pHddStaCtx->conn_info.operationChannel = channelNum;
11583 pRoamProfile->ChannelInfo.ChannelList =
11584 &pHddStaCtx->conn_info.operationChannel;
Jeff Johnson295189b2012-06-20 16:38:30 -070011585 }
11586
11587 /* Initialize security parameters */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011588 status = wlan_hdd_cfg80211_set_privacy_ibss(pAdapter, params);
Jeff Johnson295189b2012-06-20 16:38:30 -070011589 if (status < 0)
11590 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011591 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: failed to set security parameters",
Jeff Johnson295189b2012-06-20 16:38:30 -070011592 __func__);
11593 return status;
11594 }
11595
11596 /* Issue connect start */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011597 status = wlan_hdd_cfg80211_connect_start(pAdapter, params->ssid,
Shailender Karmuchi15cd0672013-05-15 19:50:04 -070011598 params->ssid_len, params->bssid,
11599 pHddStaCtx->conn_info.operationChannel);
Jeff Johnson295189b2012-06-20 16:38:30 -070011600
11601 if (0 > status)
11602 {
11603 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: connect failed", __func__);
11604 return status;
11605 }
11606
krunal sonie9002db2013-11-25 14:24:17 -080011607 if (NULL != params->bssid &&
11608 pHddCtx->cfg_ini->isCoalesingInIBSSAllowed == 0 &&
11609 alloc_bssid == VOS_TRUE)
11610 {
11611 vos_mem_free(params->bssid);
11612 }
Jeff Johnson295189b2012-06-20 16:38:30 -070011613 return 0;
11614}
11615
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053011616static int wlan_hdd_cfg80211_join_ibss( struct wiphy *wiphy,
11617 struct net_device *dev,
11618 struct cfg80211_ibss_params *params
11619 )
11620{
11621 int ret = 0;
11622
11623 vos_ssr_protect(__func__);
11624 ret = __wlan_hdd_cfg80211_join_ibss(wiphy, dev, params);
11625 vos_ssr_unprotect(__func__);
11626
11627 return ret;
11628}
11629
Jeff Johnson295189b2012-06-20 16:38:30 -070011630/*
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053011631 * FUNCTION: __wlan_hdd_cfg80211_leave_ibss
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011632 * This function is used to leave an IBSS
Jeff Johnson295189b2012-06-20 16:38:30 -070011633 */
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053011634static int __wlan_hdd_cfg80211_leave_ibss( struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -070011635 struct net_device *dev
11636 )
11637{
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011638 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( dev );
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053011639 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
11640 tCsrRoamProfile *pRoamProfile;
11641 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053011642 int status;
Jeff Johnson295189b2012-06-20 16:38:30 -070011643
11644 ENTER();
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053011645
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053011646 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
11647 TRACE_CODE_HDD_CFG80211_LEAVE_IBSS,
11648 pAdapter->sessionId, eCSR_DISCONNECT_REASON_IBSS_LEAVE));
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053011649 status = wlan_hdd_validate_context(pHddCtx);
11650
11651 if (0 != status)
Jeff Johnson04dd8a82012-06-29 20:41:40 -070011652 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053011653 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
11654 "%s: HDD context is not valid", __func__);
11655 return status;
Jeff Johnson04dd8a82012-06-29 20:41:40 -070011656 }
11657
Sushant Kaushik8bc7df22014-04-09 17:55:29 +053011658 hddLog(VOS_TRACE_LEVEL_INFO, "%s: device_mode = %s (%d)", __func__,
11659 hdd_device_modetoString(pAdapter->device_mode),
11660 pAdapter->device_mode);
Jeff Johnson295189b2012-06-20 16:38:30 -070011661 if (NULL == pWextState)
11662 {
Arif Hussain6d2a3322013-11-17 19:50:10 -080011663 hddLog (VOS_TRACE_LEVEL_ERROR, "%s ERROR: Data Storage Corruption",
Jeff Johnson295189b2012-06-20 16:38:30 -070011664 __func__);
11665 return -EIO;
11666 }
11667
11668 pRoamProfile = &pWextState->roamProfile;
11669
11670 /* Issue disconnect only if interface type is set to IBSS */
11671 if (eCSR_BSS_TYPE_START_IBSS != pRoamProfile->BSSType)
11672 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011673 hddLog (VOS_TRACE_LEVEL_ERROR, "%s: BSS Type is not set to IBSS",
Jeff Johnson295189b2012-06-20 16:38:30 -070011674 __func__);
11675 return -EINVAL;
11676 }
11677
11678 /* Issue Disconnect request */
11679 INIT_COMPLETION(pAdapter->disconnect_comp_var);
11680 sme_RoamDisconnect( WLAN_HDD_GET_HAL_CTX(pAdapter), pAdapter->sessionId,
11681 eCSR_DISCONNECT_REASON_IBSS_LEAVE);
11682
11683 return 0;
11684}
11685
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053011686static int wlan_hdd_cfg80211_leave_ibss( struct wiphy *wiphy,
11687 struct net_device *dev
11688 )
11689{
11690 int ret = 0;
11691
11692 vos_ssr_protect(__func__);
11693 ret = __wlan_hdd_cfg80211_leave_ibss(wiphy, dev);
11694 vos_ssr_unprotect(__func__);
11695
11696 return ret;
11697}
11698
Jeff Johnson295189b2012-06-20 16:38:30 -070011699/*
Mahesh A Saptasagar179d2252014-06-02 21:32:21 +053011700 * FUNCTION: __wlan_hdd_cfg80211_set_wiphy_params
Jeff Johnson295189b2012-06-20 16:38:30 -070011701 * This function is used to set the phy parameters
11702 * (RTS Threshold/FRAG Threshold/Retry Count etc ...)
11703 */
Mahesh A Saptasagar179d2252014-06-02 21:32:21 +053011704static int __wlan_hdd_cfg80211_set_wiphy_params(struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -070011705 u32 changed)
11706{
11707 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
11708 tHalHandle hHal = pHddCtx->hHal;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053011709 int status;
Jeff Johnson295189b2012-06-20 16:38:30 -070011710
11711 ENTER();
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053011712 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
11713 TRACE_CODE_HDD_CFG80211_SET_WIPHY_PARAMS,
11714 NO_SESSION, wiphy->rts_threshold));
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053011715 status = wlan_hdd_validate_context(pHddCtx);
11716
11717 if (0 != status)
Jeff Johnson04dd8a82012-06-29 20:41:40 -070011718 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053011719 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
11720 "%s: HDD context is not valid", __func__);
11721 return status;
Jeff Johnson04dd8a82012-06-29 20:41:40 -070011722 }
11723
Jeff Johnson295189b2012-06-20 16:38:30 -070011724 if (changed & WIPHY_PARAM_RTS_THRESHOLD)
11725 {
11726 u16 rts_threshold = (wiphy->rts_threshold == -1) ?
11727 WNI_CFG_RTS_THRESHOLD_STAMAX :
11728 wiphy->rts_threshold;
11729
11730 if ((WNI_CFG_RTS_THRESHOLD_STAMIN > rts_threshold) ||
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011731 (WNI_CFG_RTS_THRESHOLD_STAMAX < rts_threshold))
Jeff Johnson295189b2012-06-20 16:38:30 -070011732 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011733 hddLog(VOS_TRACE_LEVEL_ERROR,
11734 "%s: Invalid RTS Threshold value %hu",
Jeff Johnson295189b2012-06-20 16:38:30 -070011735 __func__, rts_threshold);
11736 return -EINVAL;
11737 }
11738
11739 if (0 != ccmCfgSetInt(hHal, WNI_CFG_RTS_THRESHOLD,
11740 rts_threshold, ccmCfgSetCallback,
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011741 eANI_BOOLEAN_TRUE))
Jeff Johnson295189b2012-06-20 16:38:30 -070011742 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011743 hddLog(VOS_TRACE_LEVEL_ERROR,
11744 "%s: ccmCfgSetInt failed for rts_threshold value %hu",
Jeff Johnson295189b2012-06-20 16:38:30 -070011745 __func__, rts_threshold);
11746 return -EIO;
11747 }
11748
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011749 hddLog(VOS_TRACE_LEVEL_INFO_MED, "%s: set rts threshold %hu", __func__,
Jeff Johnson295189b2012-06-20 16:38:30 -070011750 rts_threshold);
11751 }
11752
11753 if (changed & WIPHY_PARAM_FRAG_THRESHOLD)
11754 {
11755 u16 frag_threshold = (wiphy->frag_threshold == -1) ?
11756 WNI_CFG_FRAGMENTATION_THRESHOLD_STAMAX :
11757 wiphy->frag_threshold;
11758
11759 if ((WNI_CFG_FRAGMENTATION_THRESHOLD_STAMIN > frag_threshold)||
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011760 (WNI_CFG_FRAGMENTATION_THRESHOLD_STAMAX < frag_threshold) )
Jeff Johnson295189b2012-06-20 16:38:30 -070011761 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011762 hddLog(VOS_TRACE_LEVEL_ERROR,
11763 "%s: Invalid frag_threshold value %hu", __func__,
Jeff Johnson295189b2012-06-20 16:38:30 -070011764 frag_threshold);
11765 return -EINVAL;
11766 }
11767
11768 if (0 != ccmCfgSetInt(hHal, WNI_CFG_FRAGMENTATION_THRESHOLD,
11769 frag_threshold, ccmCfgSetCallback,
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011770 eANI_BOOLEAN_TRUE))
Jeff Johnson295189b2012-06-20 16:38:30 -070011771 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011772 hddLog(VOS_TRACE_LEVEL_ERROR,
11773 "%s: ccmCfgSetInt failed for frag_threshold value %hu",
Jeff Johnson295189b2012-06-20 16:38:30 -070011774 __func__, frag_threshold);
11775 return -EIO;
11776 }
11777
11778 hddLog(VOS_TRACE_LEVEL_INFO_MED, "%s: set frag threshold %hu", __func__,
11779 frag_threshold);
11780 }
11781
11782 if ((changed & WIPHY_PARAM_RETRY_SHORT)
11783 || (changed & WIPHY_PARAM_RETRY_LONG))
11784 {
11785 u8 retry_value = (changed & WIPHY_PARAM_RETRY_SHORT) ?
11786 wiphy->retry_short :
11787 wiphy->retry_long;
11788
11789 if ((WNI_CFG_LONG_RETRY_LIMIT_STAMIN > retry_value) ||
11790 (WNI_CFG_LONG_RETRY_LIMIT_STAMAX < retry_value))
11791 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011792 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Invalid Retry count %hu",
Jeff Johnson295189b2012-06-20 16:38:30 -070011793 __func__, retry_value);
11794 return -EINVAL;
11795 }
11796
11797 if (changed & WIPHY_PARAM_RETRY_SHORT)
11798 {
11799 if (0 != ccmCfgSetInt(hHal, WNI_CFG_LONG_RETRY_LIMIT,
11800 retry_value, ccmCfgSetCallback,
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011801 eANI_BOOLEAN_TRUE))
Jeff Johnson295189b2012-06-20 16:38:30 -070011802 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011803 hddLog(VOS_TRACE_LEVEL_ERROR,
11804 "%s: ccmCfgSetInt failed for long retry count %hu",
Jeff Johnson295189b2012-06-20 16:38:30 -070011805 __func__, retry_value);
11806 return -EIO;
11807 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011808 hddLog(VOS_TRACE_LEVEL_INFO_MED, "%s: set long retry count %hu",
Jeff Johnson295189b2012-06-20 16:38:30 -070011809 __func__, retry_value);
11810 }
11811 else if (changed & WIPHY_PARAM_RETRY_SHORT)
11812 {
11813 if (0 != ccmCfgSetInt(hHal, WNI_CFG_SHORT_RETRY_LIMIT,
11814 retry_value, ccmCfgSetCallback,
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011815 eANI_BOOLEAN_TRUE))
Jeff Johnson295189b2012-06-20 16:38:30 -070011816 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011817 hddLog(VOS_TRACE_LEVEL_ERROR,
11818 "%s: ccmCfgSetInt failed for short retry count %hu",
Jeff Johnson295189b2012-06-20 16:38:30 -070011819 __func__, retry_value);
11820 return -EIO;
11821 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011822 hddLog(VOS_TRACE_LEVEL_INFO_MED, "%s: set short retry count %hu",
Jeff Johnson295189b2012-06-20 16:38:30 -070011823 __func__, retry_value);
11824 }
11825 }
11826
11827 return 0;
11828}
11829
Mahesh A Saptasagar179d2252014-06-02 21:32:21 +053011830static int wlan_hdd_cfg80211_set_wiphy_params(struct wiphy *wiphy,
11831 u32 changed)
11832{
11833 int ret;
11834
11835 vos_ssr_protect(__func__);
11836 ret = __wlan_hdd_cfg80211_set_wiphy_params(wiphy, changed);
11837 vos_ssr_unprotect(__func__);
11838
11839 return ret;
11840}
11841
Jeff Johnson295189b2012-06-20 16:38:30 -070011842/*
Mahesh A Saptasagar179d2252014-06-02 21:32:21 +053011843 * FUNCTION: __wlan_hdd_cfg80211_set_txpower
Jeff Johnson295189b2012-06-20 16:38:30 -070011844 * This function is used to set the txpower
11845 */
Mahesh A Saptasagar179d2252014-06-02 21:32:21 +053011846static int __wlan_hdd_cfg80211_set_txpower(struct wiphy *wiphy,
Yue Maf49ba872013-08-19 12:04:25 -070011847#if LINUX_VERSION_CODE >= KERNEL_VERSION(3,8,0)
11848 struct wireless_dev *wdev,
11849#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070011850#if LINUX_VERSION_CODE <= KERNEL_VERSION(2,6,35)
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011851 enum tx_power_setting type,
Jeff Johnson295189b2012-06-20 16:38:30 -070011852#else
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011853 enum nl80211_tx_power_setting type,
Jeff Johnson295189b2012-06-20 16:38:30 -070011854#endif
11855 int dbm)
11856{
11857 hdd_context_t *pHddCtx = (hdd_context_t*) wiphy_priv(wiphy);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053011858 tHalHandle hHal = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -070011859 tSirMacAddr bssid = {0xFF,0xFF,0xFF,0xFF,0xFF,0xFF};
11860 tSirMacAddr selfMac = {0xFF,0xFF,0xFF,0xFF,0xFF,0xFF};
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053011861 int status;
Jeff Johnson295189b2012-06-20 16:38:30 -070011862
11863 ENTER();
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053011864 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
11865 TRACE_CODE_HDD_CFG80211_SET_TXPOWER,
11866 NO_SESSION, type ));
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053011867 status = wlan_hdd_validate_context(pHddCtx);
11868
11869 if (0 != status)
11870 {
11871 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
11872 "%s: HDD context is not valid", __func__);
11873 return status;
11874 }
11875
11876 hHal = pHddCtx->hHal;
11877
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011878 if (0 != ccmCfgSetInt(hHal, WNI_CFG_CURRENT_TX_POWER_LEVEL,
11879 dbm, ccmCfgSetCallback,
11880 eANI_BOOLEAN_TRUE))
Jeff Johnson295189b2012-06-20 16:38:30 -070011881 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011882 hddLog(VOS_TRACE_LEVEL_ERROR,
Jeff Johnson295189b2012-06-20 16:38:30 -070011883 "%s: ccmCfgSetInt failed for tx power %hu", __func__, dbm);
11884 return -EIO;
11885 }
11886
11887 hddLog(VOS_TRACE_LEVEL_INFO_MED, "%s: set tx power level %d dbm", __func__,
11888 dbm);
11889
11890 switch(type)
11891 {
11892 case NL80211_TX_POWER_AUTOMATIC: /*automatically determine transmit power*/
11893 /* Fall through */
11894 case NL80211_TX_POWER_LIMITED: /*limit TX power by the mBm parameter*/
11895 if( sme_SetMaxTxPower(hHal, bssid, selfMac, dbm) != eHAL_STATUS_SUCCESS )
11896 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011897 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Setting maximum tx power failed",
11898 __func__);
11899 return -EIO;
Jeff Johnson295189b2012-06-20 16:38:30 -070011900 }
11901 break;
11902 case NL80211_TX_POWER_FIXED: /*fix TX power to the mBm parameter*/
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011903 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: NL80211_TX_POWER_FIXED not supported",
Jeff Johnson295189b2012-06-20 16:38:30 -070011904 __func__);
11905 return -EOPNOTSUPP;
11906 break;
11907 default:
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011908 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Invalid power setting type %d",
11909 __func__, type);
Jeff Johnson295189b2012-06-20 16:38:30 -070011910 return -EIO;
11911 }
11912
11913 return 0;
11914}
11915
Mahesh A Saptasagar179d2252014-06-02 21:32:21 +053011916static int wlan_hdd_cfg80211_set_txpower(struct wiphy *wiphy,
11917#if LINUX_VERSION_CODE >= KERNEL_VERSION(3,8,0)
11918 struct wireless_dev *wdev,
11919#endif
11920#if LINUX_VERSION_CODE <= KERNEL_VERSION(2,6,35)
11921 enum tx_power_setting type,
11922#else
11923 enum nl80211_tx_power_setting type,
11924#endif
11925 int dbm)
11926{
11927 int ret;
11928 vos_ssr_protect(__func__);
11929 ret = __wlan_hdd_cfg80211_set_txpower(wiphy,
11930#if LINUX_VERSION_CODE >= KERNEL_VERSION(3,8,0)
11931 wdev,
11932#endif
11933#if LINUX_VERSION_CODE <= KERNEL_VERSION(2,6,35)
11934 type,
11935#else
11936 type,
11937#endif
11938 dbm);
11939 vos_ssr_unprotect(__func__);
11940
11941 return ret;
11942}
11943
Jeff Johnson295189b2012-06-20 16:38:30 -070011944/*
11945 * FUNCTION: wlan_hdd_cfg80211_get_txpower
11946 * This function is used to read the txpower
11947 */
Yue Maf49ba872013-08-19 12:04:25 -070011948static int wlan_hdd_cfg80211_get_txpower(struct wiphy *wiphy,
11949#if LINUX_VERSION_CODE >= KERNEL_VERSION(3,8,0)
11950 struct wireless_dev *wdev,
11951#endif
11952 int *dbm)
Jeff Johnson295189b2012-06-20 16:38:30 -070011953{
11954
11955 hdd_adapter_t *pAdapter;
11956 hdd_context_t *pHddCtx = (hdd_context_t*) wiphy_priv(wiphy);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053011957 int status;
Jeff Johnson295189b2012-06-20 16:38:30 -070011958
Jeff Johnsone7245742012-09-05 17:12:55 -070011959 ENTER();
11960
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053011961 status = wlan_hdd_validate_context(pHddCtx);
Jeff Johnson295189b2012-06-20 16:38:30 -070011962
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053011963 if (0 != status)
Jeff Johnson04dd8a82012-06-29 20:41:40 -070011964 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053011965 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
11966 "%s: HDD context is not valid", __func__);
11967 *dbm = 0;
11968 return status;
Jeff Johnson04dd8a82012-06-29 20:41:40 -070011969 }
11970
Jeff Johnson295189b2012-06-20 16:38:30 -070011971 pAdapter = hdd_get_adapter(pHddCtx, WLAN_HDD_INFRA_STATION);
11972 if (NULL == pAdapter)
11973 {
11974 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: Not in station context " ,__func__);
11975 return -ENOENT;
11976 }
11977
11978 wlan_hdd_get_classAstats(pAdapter);
11979 *dbm = pAdapter->hdd_stats.ClassA_stat.max_pwr;
11980
Jeff Johnsone7245742012-09-05 17:12:55 -070011981 EXIT();
Jeff Johnson295189b2012-06-20 16:38:30 -070011982 return 0;
11983}
11984
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053011985static int __wlan_hdd_cfg80211_get_station(struct wiphy *wiphy, struct net_device *dev,
Jeff Johnson295189b2012-06-20 16:38:30 -070011986 u8* mac, struct station_info *sinfo)
11987{
11988 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( dev );
11989 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
11990 int ssidlen = pHddStaCtx->conn_info.SSID.SSID.length;
c_hpothu44ff4e02014-05-08 00:13:57 +053011991 tANI_U32 rate_flags;
Jeff Johnson295189b2012-06-20 16:38:30 -070011992
11993 hdd_context_t *pHddCtx = (hdd_context_t*) wiphy_priv(wiphy);
11994 hdd_config_t *pCfg = pHddCtx->cfg_ini;
Jeff Johnson295189b2012-06-20 16:38:30 -070011995
11996 tANI_U8 OperationalRates[CSR_DOT11_SUPPORTED_RATES_MAX];
11997 tANI_U32 ORLeng = CSR_DOT11_SUPPORTED_RATES_MAX;
11998 tANI_U8 ExtendedRates[CSR_DOT11_EXTENDED_SUPPORTED_RATES_MAX];
11999 tANI_U32 ERLeng = CSR_DOT11_EXTENDED_SUPPORTED_RATES_MAX;
12000 tANI_U8 MCSRates[SIZE_OF_BASIC_MCS_SET];
12001 tANI_U32 MCSLeng = SIZE_OF_BASIC_MCS_SET;
12002 tANI_U16 maxRate = 0;
12003 tANI_U16 myRate;
12004 tANI_U16 currentRate = 0;
12005 tANI_U8 maxSpeedMCS = 0;
12006 tANI_U8 maxMCSIdx = 0;
12007 tANI_U8 rateFlag = 1;
c_hpothu79aab322014-07-14 21:11:01 +053012008 tANI_U8 i, j, rssidx, mode=0;
Madan Mohan Koyyalamudic75be962012-10-18 19:19:03 -070012009 tANI_U16 temp;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053012010 int status;
Jeff Johnson295189b2012-06-20 16:38:30 -070012011
Leo Chang6f8870f2013-03-26 18:11:36 -070012012#ifdef WLAN_FEATURE_11AC
12013 tANI_U32 vht_mcs_map;
12014 eDataRate11ACMaxMcs vhtMaxMcs;
12015#endif /* WLAN_FEATURE_11AC */
12016
Jeff Johnsone7245742012-09-05 17:12:55 -070012017 ENTER();
12018
Jeff Johnson295189b2012-06-20 16:38:30 -070012019 if ((eConnectionState_Associated != pHddStaCtx->conn_info.connState) ||
12020 (0 == ssidlen))
12021 {
12022 hddLog(VOS_TRACE_LEVEL_INFO, "%s: Not associated or"
12023 " Invalid ssidlen, %d", __func__, ssidlen);
12024 /*To keep GUI happy*/
12025 return 0;
12026 }
12027
Mukul Sharma811205f2014-07-09 21:07:30 +053012028 if (VOS_TRUE == pHddStaCtx->hdd_ReassocScenario)
12029 {
12030 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
12031 "%s: Roaming in progress, so unable to proceed this request", __func__);
12032 return 0;
12033 }
12034
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053012035 status = wlan_hdd_validate_context(pHddCtx);
12036
12037 if (0 != status)
Jeff Johnson04dd8a82012-06-29 20:41:40 -070012038 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053012039 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
12040 "%s: HDD context is not valid", __func__);
12041 return status;
Jeff Johnson04dd8a82012-06-29 20:41:40 -070012042 }
12043
Jeff Johnson295189b2012-06-20 16:38:30 -070012044
Kiet Lam3b17fc82013-09-27 05:24:08 +053012045 wlan_hdd_get_rssi(pAdapter, &sinfo->signal);
12046 sinfo->filled |= STATION_INFO_SIGNAL;
12047
c_hpothu09f19542014-05-30 21:53:31 +053012048 wlan_hdd_get_station_stats(pAdapter);
12049 rate_flags = pAdapter->hdd_stats.ClassA_stat.tx_rate_flags;
12050
12051 /*overwrite rate_flags if MAX link-speed need to be reported*/
c_hpothu44ff4e02014-05-08 00:13:57 +053012052 if ((eHDD_LINK_SPEED_REPORT_MAX == pCfg->reportMaxLinkSpeed) ||
12053 (eHDD_LINK_SPEED_REPORT_MAX_SCALED == pCfg->reportMaxLinkSpeed &&
c_hpothu79aab322014-07-14 21:11:01 +053012054 sinfo->signal >= pCfg->linkSpeedRssiLow))
c_hpothu44ff4e02014-05-08 00:13:57 +053012055 {
12056 rate_flags = pAdapter->maxRateFlags;
12057 }
c_hpothu44ff4e02014-05-08 00:13:57 +053012058
Jeff Johnson295189b2012-06-20 16:38:30 -070012059 //convert to the UI units of 100kbps
12060 myRate = pAdapter->hdd_stats.ClassA_stat.tx_rate * 5;
12061
12062#ifdef LINKSPEED_DEBUG_ENABLED
Leo Chang6f8870f2013-03-26 18:11:36 -070012063 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 -070012064 sinfo->signal,
12065 pCfg->reportMaxLinkSpeed,
12066 myRate,
12067 (int) pCfg->linkSpeedRssiHigh,
Madan Mohan Koyyalamudi8df78d52012-11-02 12:30:06 -070012068 (int) pCfg->linkSpeedRssiMid,
12069 (int) pCfg->linkSpeedRssiLow,
Leo Chang6f8870f2013-03-26 18:11:36 -070012070 (int) rate_flags,
12071 (int) pAdapter->hdd_stats.ClassA_stat.mcs_index);
Jeff Johnson295189b2012-06-20 16:38:30 -070012072#endif //LINKSPEED_DEBUG_ENABLED
12073
12074 if (eHDD_LINK_SPEED_REPORT_ACTUAL != pCfg->reportMaxLinkSpeed)
12075 {
12076 // we do not want to necessarily report the current speed
12077 if (eHDD_LINK_SPEED_REPORT_MAX == pCfg->reportMaxLinkSpeed)
12078 {
12079 // report the max possible speed
12080 rssidx = 0;
12081 }
12082 else if (eHDD_LINK_SPEED_REPORT_MAX_SCALED == pCfg->reportMaxLinkSpeed)
12083 {
12084 // report the max possible speed with RSSI scaling
12085 if (sinfo->signal >= pCfg->linkSpeedRssiHigh)
12086 {
12087 // report the max possible speed
12088 rssidx = 0;
12089 }
Madan Mohan Koyyalamudi8df78d52012-11-02 12:30:06 -070012090 else if (sinfo->signal >= pCfg->linkSpeedRssiMid)
Jeff Johnson295189b2012-06-20 16:38:30 -070012091 {
12092 // report middle speed
12093 rssidx = 1;
12094 }
Madan Mohan Koyyalamudi8df78d52012-11-02 12:30:06 -070012095 else if (sinfo->signal >= pCfg->linkSpeedRssiLow)
12096 {
12097 // report middle speed
12098 rssidx = 2;
12099 }
Jeff Johnson295189b2012-06-20 16:38:30 -070012100 else
12101 {
12102 // report actual speed
Madan Mohan Koyyalamudi8df78d52012-11-02 12:30:06 -070012103 rssidx = 3;
Jeff Johnson295189b2012-06-20 16:38:30 -070012104 }
12105 }
12106 else
12107 {
12108 // unknown, treat as eHDD_LINK_SPEED_REPORT_MAX
12109 hddLog(VOS_TRACE_LEVEL_ERROR,
12110 "%s: Invalid value for reportMaxLinkSpeed: %u",
12111 __func__, pCfg->reportMaxLinkSpeed);
12112 rssidx = 0;
12113 }
12114
12115 maxRate = 0;
12116
12117 /* Get Basic Rate Set */
Gopichand Nakkala05ab1322013-02-15 11:28:38 +053012118 if (0 != ccmCfgGetStr(WLAN_HDD_GET_HAL_CTX(pAdapter), WNI_CFG_OPERATIONAL_RATE_SET,
12119 OperationalRates, &ORLeng))
12120 {
12121 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: ccm api returned failure", __func__);
12122 /*To keep GUI happy*/
12123 return 0;
12124 }
12125
Jeff Johnson295189b2012-06-20 16:38:30 -070012126 for (i = 0; i < ORLeng; i++)
12127 {
Jeff Johnsone7245742012-09-05 17:12:55 -070012128 for (j = 0; j < (sizeof(supported_data_rate) / sizeof(supported_data_rate[0])); j ++)
Jeff Johnson295189b2012-06-20 16:38:30 -070012129 {
12130 /* Validate Rate Set */
12131 if (supported_data_rate[j].beacon_rate_index == (OperationalRates[i] & 0x7F))
12132 {
12133 currentRate = supported_data_rate[j].supported_rate[rssidx];
12134 break;
12135 }
12136 }
12137 /* Update MAX rate */
12138 maxRate = (currentRate > maxRate)?currentRate:maxRate;
12139 }
12140
12141 /* Get Extended Rate Set */
Gopichand Nakkala05ab1322013-02-15 11:28:38 +053012142 if (0 != ccmCfgGetStr(WLAN_HDD_GET_HAL_CTX(pAdapter), WNI_CFG_EXTENDED_OPERATIONAL_RATE_SET,
12143 ExtendedRates, &ERLeng))
12144 {
12145 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: ccm api returned failure", __func__);
12146 /*To keep GUI happy*/
12147 return 0;
12148 }
12149
Jeff Johnson295189b2012-06-20 16:38:30 -070012150 for (i = 0; i < ERLeng; i++)
12151 {
Jeff Johnsone7245742012-09-05 17:12:55 -070012152 for (j = 0; j < (sizeof(supported_data_rate) / sizeof(supported_data_rate[0])); j ++)
Jeff Johnson295189b2012-06-20 16:38:30 -070012153 {
12154 if (supported_data_rate[j].beacon_rate_index == (ExtendedRates[i] & 0x7F))
12155 {
12156 currentRate = supported_data_rate[j].supported_rate[rssidx];
12157 break;
12158 }
12159 }
12160 /* Update MAX rate */
12161 maxRate = (currentRate > maxRate)?currentRate:maxRate;
12162 }
c_hpothu79aab322014-07-14 21:11:01 +053012163
Kiet Lamb69f8dc2013-11-15 15:34:27 +053012164 /* Get MCS Rate Set --
Kaushik, Sushantdc304d82014-01-22 10:58:37 +053012165 Only if we are always reporting max speed (or)
Kiet Lamb69f8dc2013-11-15 15:34:27 +053012166 if we have good rssi */
c_hpothu79aab322014-07-14 21:11:01 +053012167 if ((3 != rssidx) && !(rate_flags & eHAL_TX_RATE_LEGACY))
Jeff Johnson295189b2012-06-20 16:38:30 -070012168 {
c_hpothu79aab322014-07-14 21:11:01 +053012169 if (rate_flags & eHAL_TX_RATE_VHT80)
12170 mode = 2;
12171 else if (rate_flags & (eHAL_TX_RATE_VHT40 | eHAL_TX_RATE_HT40))
12172 mode = 1;
12173 else
12174 mode = 0;
12175
Gopichand Nakkala05ab1322013-02-15 11:28:38 +053012176 if (0 != ccmCfgGetStr(WLAN_HDD_GET_HAL_CTX(pAdapter), WNI_CFG_CURRENT_MCS_SET,
12177 MCSRates, &MCSLeng))
12178 {
12179 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: ccm api returned failure", __func__);
12180 /*To keep GUI happy*/
12181 return 0;
12182 }
Jeff Johnson295189b2012-06-20 16:38:30 -070012183 rateFlag = 0;
Leo Chang6f8870f2013-03-26 18:11:36 -070012184#ifdef WLAN_FEATURE_11AC
12185 /* VHT80 rate has seperate rate table */
Gopichand Nakkala4c705372013-04-24 13:20:33 +053012186 if (rate_flags & (eHAL_TX_RATE_VHT20|eHAL_TX_RATE_VHT40|eHAL_TX_RATE_VHT80))
Jeff Johnson295189b2012-06-20 16:38:30 -070012187 {
Leo Chang6f8870f2013-03-26 18:11:36 -070012188 ccmCfgGetInt(WLAN_HDD_GET_HAL_CTX(pAdapter), WNI_CFG_VHT_TX_MCS_MAP, &vht_mcs_map);
Gopichand Nakkala4c705372013-04-24 13:20:33 +053012189 vhtMaxMcs = (eDataRate11ACMaxMcs)(vht_mcs_map & DATA_RATE_11AC_MCS_MASK );
Leo Chang6f8870f2013-03-26 18:11:36 -070012190 if (rate_flags & eHAL_TX_RATE_SGI)
Jeff Johnson295189b2012-06-20 16:38:30 -070012191 {
Leo Chang6f8870f2013-03-26 18:11:36 -070012192 rateFlag |= 1;
Jeff Johnson295189b2012-06-20 16:38:30 -070012193 }
Leo Chang6f8870f2013-03-26 18:11:36 -070012194 if (DATA_RATE_11AC_MAX_MCS_7 == vhtMaxMcs)
Jeff Johnson295189b2012-06-20 16:38:30 -070012195 {
Leo Chang6f8870f2013-03-26 18:11:36 -070012196 maxMCSIdx = 7;
12197 }
12198 else if (DATA_RATE_11AC_MAX_MCS_8 == vhtMaxMcs)
12199 {
12200 maxMCSIdx = 8;
12201 }
12202 else if (DATA_RATE_11AC_MAX_MCS_9 == vhtMaxMcs)
12203 {
Gopichand Nakkala4c705372013-04-24 13:20:33 +053012204 //VHT20 is supporting 0~8
12205 if (rate_flags & eHAL_TX_RATE_VHT20)
12206 maxMCSIdx = 8;
12207 else
12208 maxMCSIdx = 9;
Leo Chang6f8870f2013-03-26 18:11:36 -070012209 }
Gopichand Nakkala4c705372013-04-24 13:20:33 +053012210
c_hpothu79aab322014-07-14 21:11:01 +053012211 if (0 != rssidx)/*check for scaled */
12212 {
12213 //get middle rate MCS index if rssi=1/2
12214 for (i=0; i <= maxMCSIdx; i++)
12215 {
12216 if (sinfo->signal <= rssiMcsTbl[mode][i])
12217 {
12218 maxMCSIdx = i;
12219 break;
12220 }
12221 }
12222 }
12223
Gopichand Nakkala4c705372013-04-24 13:20:33 +053012224 if (rate_flags & eHAL_TX_RATE_VHT80)
12225 {
12226 currentRate = supported_vht_mcs_rate[pAdapter->hdd_stats.ClassA_stat.mcs_index].supported_VHT80_rate[rateFlag];
12227 maxRate = supported_vht_mcs_rate[maxMCSIdx].supported_VHT80_rate[rateFlag];
12228 }
12229 else if (rate_flags & eHAL_TX_RATE_VHT40)
12230 {
12231 currentRate = supported_vht_mcs_rate[pAdapter->hdd_stats.ClassA_stat.mcs_index].supported_VHT40_rate[rateFlag];
12232 maxRate = supported_vht_mcs_rate[maxMCSIdx].supported_VHT40_rate[rateFlag];
12233 }
12234 else if (rate_flags & eHAL_TX_RATE_VHT20)
12235 {
12236 currentRate = supported_vht_mcs_rate[pAdapter->hdd_stats.ClassA_stat.mcs_index].supported_VHT20_rate[rateFlag];
12237 maxRate = supported_vht_mcs_rate[maxMCSIdx].supported_VHT20_rate[rateFlag];
12238 }
12239
Leo Chang6f8870f2013-03-26 18:11:36 -070012240 maxSpeedMCS = 1;
12241 if (currentRate > maxRate)
12242 {
12243 maxRate = currentRate;
12244 }
Gopichand Nakkala4c705372013-04-24 13:20:33 +053012245
Leo Chang6f8870f2013-03-26 18:11:36 -070012246 }
12247 else
12248#endif /* WLAN_FEATURE_11AC */
12249 {
12250 if (rate_flags & eHAL_TX_RATE_HT40)
12251 {
12252 rateFlag |= 1;
12253 }
12254 if (rate_flags & eHAL_TX_RATE_SGI)
12255 {
12256 rateFlag |= 2;
12257 }
12258
Girish Gowli01abcee2014-07-31 20:18:55 +053012259 temp = sizeof(supported_mcs_rate) / sizeof(supported_mcs_rate[0]);
c_hpothu79aab322014-07-14 21:11:01 +053012260 if (rssidx == 1 || rssidx == 2)
12261 {
12262 //get middle rate MCS index if rssi=1/2
12263 for (i=0; i <= 7; i++)
12264 {
12265 if (sinfo->signal <= rssiMcsTbl[mode][i])
12266 {
12267 temp = i+1;
12268 break;
12269 }
12270 }
12271 }
c_hpothu79aab322014-07-14 21:11:01 +053012272
12273 for (i = 0; i < MCSLeng; i++)
12274 {
Leo Chang6f8870f2013-03-26 18:11:36 -070012275 for (j = 0; j < temp; j++)
12276 {
12277 if (supported_mcs_rate[j].beacon_rate_index == MCSRates[i])
12278 {
12279 currentRate = supported_mcs_rate[j].supported_rate[rateFlag];
12280 break;
12281 }
12282 }
12283 if ((j < temp) && (currentRate > maxRate))
12284 {
12285 maxRate = currentRate;
12286 maxSpeedMCS = 1;
12287 maxMCSIdx = supported_mcs_rate[j].beacon_rate_index;
12288 }
Jeff Johnson295189b2012-06-20 16:38:30 -070012289 }
12290 }
12291 }
12292
Gopichand Nakkala4c705372013-04-24 13:20:33 +053012293 else if (!(rate_flags & eHAL_TX_RATE_LEGACY))
12294 {
12295 maxRate = myRate;
12296 maxSpeedMCS = 1;
12297 maxMCSIdx = pAdapter->hdd_stats.ClassA_stat.mcs_index;
12298 }
Jeff Johnson295189b2012-06-20 16:38:30 -070012299 // make sure we report a value at least as big as our current rate
c_hpothu79aab322014-07-14 21:11:01 +053012300 if ((maxRate < myRate) || (0 == maxRate))
Jeff Johnson295189b2012-06-20 16:38:30 -070012301 {
12302 maxRate = myRate;
12303 if (rate_flags & eHAL_TX_RATE_LEGACY)
12304 {
12305 maxSpeedMCS = 0;
12306 }
12307 else
12308 {
12309 maxSpeedMCS = 1;
12310 maxMCSIdx = pAdapter->hdd_stats.ClassA_stat.mcs_index;
12311 }
12312 }
12313
Gopichand Nakkala4c705372013-04-24 13:20:33 +053012314 if (rate_flags & eHAL_TX_RATE_LEGACY)
Jeff Johnson295189b2012-06-20 16:38:30 -070012315 {
12316 sinfo->txrate.legacy = maxRate;
12317#ifdef LINKSPEED_DEBUG_ENABLED
12318 pr_info("Reporting legacy rate %d\n", sinfo->txrate.legacy);
12319#endif //LINKSPEED_DEBUG_ENABLED
12320 }
12321 else
12322 {
12323 sinfo->txrate.mcs = maxMCSIdx;
Leo Chang6f8870f2013-03-26 18:11:36 -070012324#ifdef WLAN_FEATURE_11AC
12325 sinfo->txrate.nss = 1;
12326 if (rate_flags & eHAL_TX_RATE_VHT80)
12327 {
12328 sinfo->txrate.flags |= RATE_INFO_FLAGS_VHT_MCS;
Gopichand Nakkala4c705372013-04-24 13:20:33 +053012329 sinfo->txrate.flags |= RATE_INFO_FLAGS_80_MHZ_WIDTH;
Leo Chang6f8870f2013-03-26 18:11:36 -070012330 }
Gopichand Nakkala4c705372013-04-24 13:20:33 +053012331 else if (rate_flags & eHAL_TX_RATE_VHT40)
Leo Chang6f8870f2013-03-26 18:11:36 -070012332 {
Gopichand Nakkala4c705372013-04-24 13:20:33 +053012333 sinfo->txrate.flags |= RATE_INFO_FLAGS_VHT_MCS;
12334 sinfo->txrate.flags |= RATE_INFO_FLAGS_40_MHZ_WIDTH;
12335 }
12336 else if (rate_flags & eHAL_TX_RATE_VHT20)
12337 {
12338 sinfo->txrate.flags |= RATE_INFO_FLAGS_VHT_MCS;
12339 }
12340#endif /* WLAN_FEATURE_11AC */
12341 if (rate_flags & (eHAL_TX_RATE_HT20 | eHAL_TX_RATE_HT40))
12342 {
12343 sinfo->txrate.flags |= RATE_INFO_FLAGS_MCS;
12344 if (rate_flags & eHAL_TX_RATE_HT40)
12345 {
12346 sinfo->txrate.flags |= RATE_INFO_FLAGS_40_MHZ_WIDTH;
12347 }
Leo Chang6f8870f2013-03-26 18:11:36 -070012348 }
Jeff Johnson295189b2012-06-20 16:38:30 -070012349 if (rate_flags & eHAL_TX_RATE_SGI)
12350 {
12351 sinfo->txrate.flags |= RATE_INFO_FLAGS_SHORT_GI;
12352 }
Gopichand Nakkala4c705372013-04-24 13:20:33 +053012353
Jeff Johnson295189b2012-06-20 16:38:30 -070012354#ifdef LINKSPEED_DEBUG_ENABLED
12355 pr_info("Reporting MCS rate %d flags %x\n",
12356 sinfo->txrate.mcs,
12357 sinfo->txrate.flags );
12358#endif //LINKSPEED_DEBUG_ENABLED
12359 }
12360 }
12361 else
12362 {
12363 // report current rate instead of max rate
12364
12365 if (rate_flags & eHAL_TX_RATE_LEGACY)
12366 {
12367 //provide to the UI in units of 100kbps
12368 sinfo->txrate.legacy = myRate;
12369#ifdef LINKSPEED_DEBUG_ENABLED
12370 pr_info("Reporting actual legacy rate %d\n", sinfo->txrate.legacy);
12371#endif //LINKSPEED_DEBUG_ENABLED
12372 }
12373 else
12374 {
12375 //must be MCS
12376 sinfo->txrate.mcs = pAdapter->hdd_stats.ClassA_stat.mcs_index;
Leo Chang6f8870f2013-03-26 18:11:36 -070012377#ifdef WLAN_FEATURE_11AC
12378 sinfo->txrate.nss = 1;
12379 if (rate_flags & eHAL_TX_RATE_VHT80)
12380 {
12381 sinfo->txrate.flags |= RATE_INFO_FLAGS_VHT_MCS;
12382 }
12383 else
12384#endif /* WLAN_FEATURE_11AC */
12385 {
12386 sinfo->txrate.flags |= RATE_INFO_FLAGS_MCS;
12387 }
Jeff Johnson295189b2012-06-20 16:38:30 -070012388 if (rate_flags & eHAL_TX_RATE_SGI)
12389 {
12390 sinfo->txrate.flags |= RATE_INFO_FLAGS_SHORT_GI;
12391 }
12392 if (rate_flags & eHAL_TX_RATE_HT40)
12393 {
12394 sinfo->txrate.flags |= RATE_INFO_FLAGS_40_MHZ_WIDTH;
12395 }
Leo Chang6f8870f2013-03-26 18:11:36 -070012396#ifdef WLAN_FEATURE_11AC
12397 else if (rate_flags & eHAL_TX_RATE_VHT80)
12398 {
12399 sinfo->txrate.flags |= RATE_INFO_FLAGS_80_MHZ_WIDTH;
12400 }
12401#endif /* WLAN_FEATURE_11AC */
Jeff Johnson295189b2012-06-20 16:38:30 -070012402#ifdef LINKSPEED_DEBUG_ENABLED
12403 pr_info("Reporting actual MCS rate %d flags %x\n",
12404 sinfo->txrate.mcs,
12405 sinfo->txrate.flags );
12406#endif //LINKSPEED_DEBUG_ENABLED
12407 }
12408 }
12409 sinfo->filled |= STATION_INFO_TX_BITRATE;
12410
Madan Mohan Koyyalamudi4d4d2812012-09-24 14:08:29 -070012411 sinfo->tx_packets =
12412 pAdapter->hdd_stats.summary_stat.tx_frm_cnt[0] +
12413 pAdapter->hdd_stats.summary_stat.tx_frm_cnt[1] +
12414 pAdapter->hdd_stats.summary_stat.tx_frm_cnt[2] +
12415 pAdapter->hdd_stats.summary_stat.tx_frm_cnt[3];
12416
12417 sinfo->tx_retries =
12418 pAdapter->hdd_stats.summary_stat.retry_cnt[0] +
12419 pAdapter->hdd_stats.summary_stat.retry_cnt[1] +
12420 pAdapter->hdd_stats.summary_stat.retry_cnt[2] +
12421 pAdapter->hdd_stats.summary_stat.retry_cnt[3];
12422
12423 sinfo->tx_failed =
12424 pAdapter->hdd_stats.summary_stat.fail_cnt[0] +
12425 pAdapter->hdd_stats.summary_stat.fail_cnt[1] +
12426 pAdapter->hdd_stats.summary_stat.fail_cnt[2] +
12427 pAdapter->hdd_stats.summary_stat.fail_cnt[3];
12428
12429 sinfo->filled |=
12430 STATION_INFO_TX_PACKETS |
12431 STATION_INFO_TX_RETRIES |
12432 STATION_INFO_TX_FAILED;
12433
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053012434 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
12435 TRACE_CODE_HDD_CFG80211_GET_STA,
12436 pAdapter->sessionId, maxRate));
Madan Mohan Koyyalamudi4d4d2812012-09-24 14:08:29 -070012437 EXIT();
12438 return 0;
Jeff Johnson295189b2012-06-20 16:38:30 -070012439}
12440
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053012441static int wlan_hdd_cfg80211_get_station(struct wiphy *wiphy, struct net_device *dev,
12442 u8* mac, struct station_info *sinfo)
12443{
12444 int ret;
12445
12446 vos_ssr_protect(__func__);
12447 ret = __wlan_hdd_cfg80211_get_station(wiphy, dev, mac, sinfo);
12448 vos_ssr_unprotect(__func__);
12449
12450 return ret;
12451}
12452
12453static int __wlan_hdd_cfg80211_set_power_mgmt(struct wiphy *wiphy,
Sameer Thalappilc9f26e92013-06-07 10:11:06 -070012454 struct net_device *dev, bool mode, int timeout)
Jeff Johnson295189b2012-06-20 16:38:30 -070012455{
12456 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
Gopichand Nakkala20c4c042013-04-19 22:08:55 +053012457 hdd_context_t *pHddCtx;
Jeff Johnson295189b2012-06-20 16:38:30 -070012458 VOS_STATUS vos_status;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053012459 int status;
Jeff Johnson295189b2012-06-20 16:38:30 -070012460
Jeff Johnsone7245742012-09-05 17:12:55 -070012461 ENTER();
12462
Jeff Johnson295189b2012-06-20 16:38:30 -070012463 if (NULL == pAdapter)
12464 {
Arif Hussain6d2a3322013-11-17 19:50:10 -080012465 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Adapter is NULL", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -070012466 return -ENODEV;
12467 }
12468
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053012469 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
12470 TRACE_CODE_HDD_CFG80211_SET_POWER_MGMT,
12471 pAdapter->sessionId, timeout));
12472
Gopichand Nakkala20c4c042013-04-19 22:08:55 +053012473 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053012474 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkala20c4c042013-04-19 22:08:55 +053012475
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053012476 if (0 != status)
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012477 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053012478 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
12479 "%s: HDD context is not valid", __func__);
12480 return status;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012481 }
12482
Gopichand Nakkala20c4c042013-04-19 22:08:55 +053012483 if ((DRIVER_POWER_MODE_AUTO == !mode) &&
12484 (TRUE == pHddCtx->hdd_wlan_suspended) &&
12485 (pHddCtx->cfg_ini->fhostArpOffload) &&
12486 (eConnectionState_Associated ==
12487 (WLAN_HDD_GET_STATION_CTX_PTR(pAdapter))->conn_info.connState))
12488 {
Amar Singhald53568e2013-09-26 11:03:45 -070012489
12490 hddLog(VOS_TRACE_LEVEL_INFO,
12491 "offload: in cfg80211_set_power_mgmt, calling arp offload");
Gopichand Nakkalab03e8082013-05-30 18:09:25 +053012492 vos_status = hdd_conf_arp_offload(pAdapter, TRUE);
Gopichand Nakkala20c4c042013-04-19 22:08:55 +053012493 if (!VOS_IS_STATUS_SUCCESS(vos_status))
12494 {
12495 hddLog(VOS_TRACE_LEVEL_INFO,
Arif Hussain6d2a3322013-11-17 19:50:10 -080012496 "%s:Failed to enable ARPOFFLOAD Feature %d",
Gopichand Nakkala20c4c042013-04-19 22:08:55 +053012497 __func__, vos_status);
12498 }
12499 }
12500
Jeff Johnson295189b2012-06-20 16:38:30 -070012501 /**The get power cmd from the supplicant gets updated by the nl only
12502 *on successful execution of the function call
12503 *we are oppositely mapped w.r.t mode in the driver
12504 **/
12505 vos_status = wlan_hdd_enter_bmps(pAdapter, !mode);
12506
Jeff Johnsone7245742012-09-05 17:12:55 -070012507 EXIT();
Jeff Johnson295189b2012-06-20 16:38:30 -070012508 if (VOS_STATUS_E_FAILURE == vos_status)
12509 {
c_hpothu6ff1c3c2013-10-01 19:01:57 +053012510 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
12511 "%s: failed to enter bmps mode", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -070012512 return -EINVAL;
12513 }
12514 return 0;
12515}
12516
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053012517static int wlan_hdd_cfg80211_set_power_mgmt(struct wiphy *wiphy,
12518 struct net_device *dev, bool mode, int timeout)
12519{
12520 int ret;
Jeff Johnson295189b2012-06-20 16:38:30 -070012521
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053012522 vos_ssr_protect(__func__);
12523 ret = __wlan_hdd_cfg80211_set_power_mgmt(wiphy, dev, mode, timeout);
12524 vos_ssr_unprotect(__func__);
12525
12526 return ret;
12527}
Jeff Johnson295189b2012-06-20 16:38:30 -070012528#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
12529static int wlan_hdd_set_default_mgmt_key(struct wiphy *wiphy,
12530 struct net_device *netdev,
12531 u8 key_index)
12532{
Jeff Johnsone7245742012-09-05 17:12:55 -070012533 ENTER();
Jeff Johnson295189b2012-06-20 16:38:30 -070012534 return 0;
12535}
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012536#endif //LINUX_VERSION_CODE
Jeff Johnson295189b2012-06-20 16:38:30 -070012537
12538#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,4,0))
12539static int wlan_hdd_set_txq_params(struct wiphy *wiphy,
12540 struct net_device *dev,
12541 struct ieee80211_txq_params *params)
12542{
Jeff Johnsone7245742012-09-05 17:12:55 -070012543 ENTER();
Jeff Johnson295189b2012-06-20 16:38:30 -070012544 return 0;
12545}
12546#elif (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
12547static int wlan_hdd_set_txq_params(struct wiphy *wiphy,
12548 struct ieee80211_txq_params *params)
12549{
Jeff Johnsone7245742012-09-05 17:12:55 -070012550 ENTER();
Jeff Johnson295189b2012-06-20 16:38:30 -070012551 return 0;
12552}
12553#endif //LINUX_VERSION_CODE
12554
Naresh Jayaram69e3f282014-10-14 12:29:12 +053012555#ifdef CFG80211_DEL_STA_V2
12556static int __wlan_hdd_cfg80211_del_station(struct wiphy *wiphy,
12557 struct net_device *dev,
12558 struct station_del_parameters *param)
12559#else
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053012560static int __wlan_hdd_cfg80211_del_station(struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -070012561 struct net_device *dev, u8 *mac)
Naresh Jayaram69e3f282014-10-14 12:29:12 +053012562#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070012563{
12564 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053012565 hdd_context_t *pHddCtx;
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -080012566 VOS_STATUS vos_status;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053012567 int status;
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -080012568 v_U8_t staId;
Jeff Johnson295189b2012-06-20 16:38:30 -070012569
Jeff Johnsone7245742012-09-05 17:12:55 -070012570 ENTER();
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053012571
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053012572 if ( NULL == pAdapter )
Jeff Johnson295189b2012-06-20 16:38:30 -070012573 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053012574 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Invalid Adapter" ,__func__);
Jeff Johnson295189b2012-06-20 16:38:30 -070012575 return -EINVAL;
12576 }
12577
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053012578 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
12579 TRACE_CODE_HDD_CFG80211_DEL_STA,
12580 pAdapter->sessionId, pAdapter->device_mode));
12581
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053012582 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
12583 status = wlan_hdd_validate_context(pHddCtx);
Jeff Johnson295189b2012-06-20 16:38:30 -070012584
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053012585 if (0 != status)
Jeff Johnson04dd8a82012-06-29 20:41:40 -070012586 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053012587 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
12588 "%s: HDD context is not valid", __func__);
12589 return status;
Jeff Johnson04dd8a82012-06-29 20:41:40 -070012590 }
12591
Jeff Johnson295189b2012-06-20 16:38:30 -070012592 if ( (WLAN_HDD_SOFTAP == pAdapter->device_mode)
Jeff Johnson295189b2012-06-20 16:38:30 -070012593 || (WLAN_HDD_P2P_GO == pAdapter->device_mode)
Jeff Johnson295189b2012-06-20 16:38:30 -070012594 )
12595 {
12596 if( NULL == mac )
12597 {
12598 v_U16_t i;
12599 for(i = 0; i < WLAN_MAX_STA_COUNT; i++)
12600 {
Rajesh Chauhan18488fc2013-08-22 10:15:03 -070012601 if ((pAdapter->aStaInfo[i].isUsed) &&
12602 (!pAdapter->aStaInfo[i].isDeauthInProgress))
Jeff Johnson295189b2012-06-20 16:38:30 -070012603 {
12604 u8 *macAddr = pAdapter->aStaInfo[i].macAddrSTA.bytes;
12605 hddLog(VOS_TRACE_LEVEL_INFO,
Arif Hussain24bafea2013-11-15 15:10:03 -080012606 "%s: Delete STA with MAC::"
12607 MAC_ADDRESS_STR,
12608 __func__, MAC_ADDR_ARRAY(macAddr));
Rajesh Chauhan18488fc2013-08-22 10:15:03 -070012609 vos_status = hdd_softap_sta_deauth(pAdapter, macAddr);
12610 if (VOS_IS_STATUS_SUCCESS(vos_status))
12611 pAdapter->aStaInfo[i].isDeauthInProgress = TRUE;
Jeff Johnson295189b2012-06-20 16:38:30 -070012612 }
12613 }
12614 }
12615 else
12616 {
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -080012617
12618 vos_status = hdd_softap_GetStaId(pAdapter,(v_MACADDR_t *)mac, &staId);
12619 if (!VOS_IS_STATUS_SUCCESS(vos_status))
12620 {
12621 hddLog(VOS_TRACE_LEVEL_INFO,
Arif Hussain24bafea2013-11-15 15:10:03 -080012622 "%s: Skip this DEL STA as this is not used::"
12623 MAC_ADDRESS_STR,
12624 __func__, MAC_ADDR_ARRAY(mac));
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -080012625 return -ENOENT;
12626 }
12627
12628 if( pAdapter->aStaInfo[staId].isDeauthInProgress == TRUE)
12629 {
12630 hddLog(VOS_TRACE_LEVEL_INFO,
Arif Hussain24bafea2013-11-15 15:10:03 -080012631 "%s: Skip this DEL STA as deauth is in progress::"
12632 MAC_ADDRESS_STR,
12633 __func__, MAC_ADDR_ARRAY(mac));
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -080012634 return -ENOENT;
12635 }
12636
12637 pAdapter->aStaInfo[staId].isDeauthInProgress = TRUE;
12638
Jeff Johnson295189b2012-06-20 16:38:30 -070012639 hddLog(VOS_TRACE_LEVEL_INFO,
12640 "%s: Delete STA with MAC::"
Arif Hussain24bafea2013-11-15 15:10:03 -080012641 MAC_ADDRESS_STR,
Jeff Johnson295189b2012-06-20 16:38:30 -070012642 __func__,
Arif Hussain24bafea2013-11-15 15:10:03 -080012643 MAC_ADDR_ARRAY(mac));
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -080012644
12645 vos_status = hdd_softap_sta_deauth(pAdapter, mac);
12646 if (!VOS_IS_STATUS_SUCCESS(vos_status))
12647 {
12648 pAdapter->aStaInfo[staId].isDeauthInProgress = FALSE;
12649 hddLog(VOS_TRACE_LEVEL_INFO,
12650 "%s: STA removal failed for ::"
Arif Hussain24bafea2013-11-15 15:10:03 -080012651 MAC_ADDRESS_STR,
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -080012652 __func__,
Arif Hussain24bafea2013-11-15 15:10:03 -080012653 MAC_ADDR_ARRAY(mac));
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -080012654 return -ENOENT;
12655 }
12656
Jeff Johnson295189b2012-06-20 16:38:30 -070012657 }
12658 }
12659
12660 EXIT();
12661
12662 return 0;
12663}
Naresh Jayaram69e3f282014-10-14 12:29:12 +053012664
12665#ifdef CFG80211_DEL_STA_V2
12666static int wlan_hdd_cfg80211_del_station(struct wiphy *wiphy,
12667 struct net_device *dev,
12668 struct station_del_parameters *param)
12669#else
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053012670static int wlan_hdd_cfg80211_del_station(struct wiphy *wiphy,
12671 struct net_device *dev, u8 *mac)
Naresh Jayaram69e3f282014-10-14 12:29:12 +053012672#endif
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053012673{
12674 int ret;
Jeff Johnson295189b2012-06-20 16:38:30 -070012675
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053012676 vos_ssr_protect(__func__);
Naresh Jayaram69e3f282014-10-14 12:29:12 +053012677#ifdef CFG80211_DEL_STA_V2
12678 ret = __wlan_hdd_cfg80211_del_station(wiphy, dev, param);
12679#else
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053012680 ret = __wlan_hdd_cfg80211_del_station(wiphy, dev, mac);
Naresh Jayaram69e3f282014-10-14 12:29:12 +053012681#endif
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053012682 vos_ssr_unprotect(__func__);
12683
12684 return ret;
12685}
12686
12687static int __wlan_hdd_cfg80211_add_station(struct wiphy *wiphy,
Hoonki Lee11f7dda2013-02-14 16:55:44 -080012688 struct net_device *dev, u8 *mac, struct station_parameters *params)
12689{
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053012690 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
Gopichand Nakkalab977a972013-02-18 19:15:09 -080012691 int status = -EPERM;
Hoonki Lee11f7dda2013-02-14 16:55:44 -080012692#ifdef FEATURE_WLAN_TDLS
12693 u32 mask, set;
Hoonki Lee11f7dda2013-02-14 16:55:44 -080012694 ENTER();
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053012695
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053012696 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
12697 TRACE_CODE_HDD_CFG80211_ADD_STA,
12698 pAdapter->sessionId, params->listen_interval));
Mohit Khanna698ba2a2012-12-04 15:08:18 -080012699 mask = params->sta_flags_mask;
12700
12701 set = params->sta_flags_set;
12702
Gopichand Nakkalac87400e2013-03-13 18:51:00 -070012703#ifdef WLAN_FEATURE_TDLS_DEBUG
12704 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
12705 "%s: mask 0x%x set 0x%x " MAC_ADDRESS_STR,
12706 __func__, mask, set, MAC_ADDR_ARRAY(mac));
12707#endif
Mohit Khanna698ba2a2012-12-04 15:08:18 -080012708
12709 if (mask & BIT(NL80211_STA_FLAG_TDLS_PEER)) {
12710 if (set & BIT(NL80211_STA_FLAG_TDLS_PEER)) {
Gopichand Nakkala681989c2013-03-06 22:27:48 -080012711 status = wlan_hdd_tdls_add_station(wiphy, dev, mac, 0, NULL);
Mohit Khanna698ba2a2012-12-04 15:08:18 -080012712 }
12713 }
12714#endif
Gopichand Nakkalab977a972013-02-18 19:15:09 -080012715 return status;
Jeff Johnson295189b2012-06-20 16:38:30 -070012716}
12717
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053012718static int wlan_hdd_cfg80211_add_station(struct wiphy *wiphy,
12719 struct net_device *dev, u8 *mac, struct station_parameters *params)
12720{
12721 int ret;
Jeff Johnson04dd8a82012-06-29 20:41:40 -070012722
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053012723 vos_ssr_protect(__func__);
12724 ret = __wlan_hdd_cfg80211_add_station(wiphy, dev, mac, params);
12725 vos_ssr_unprotect(__func__);
12726
12727 return ret;
12728}
Jeff Johnson04dd8a82012-06-29 20:41:40 -070012729#ifdef FEATURE_WLAN_LFR
Wilson Yang6507c4e2013-10-01 20:11:19 -070012730
Mahesh A Saptasagarf7418d72014-06-02 14:48:54 +053012731static int __wlan_hdd_cfg80211_set_pmksa(struct wiphy *wiphy, struct net_device *dev,
Jeff Johnsond13512a2012-07-17 11:42:19 -070012732 struct cfg80211_pmksa *pmksa)
Jeff Johnson04dd8a82012-06-29 20:41:40 -070012733{
Jeff Johnson04dd8a82012-06-29 20:41:40 -070012734 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
12735 tHalHandle halHandle;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012736 eHalStatus result;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053012737 int status;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053012738 hdd_context_t *pHddCtx;
Kanchanapally, Vidyullatha2633ace2014-09-25 15:16:50 +053012739 tPmkidCacheInfo pmk_id;
Jeff Johnsone7245742012-09-05 17:12:55 -070012740
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012741 // Validate pAdapter
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053012742 if ( NULL == pAdapter )
Jeff Johnson04dd8a82012-06-29 20:41:40 -070012743 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053012744 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Invalid Adapter" ,__func__);
Jeff Johnson04dd8a82012-06-29 20:41:40 -070012745 return -EINVAL;
12746 }
12747
Kanchanapally, Vidyullatha2633ace2014-09-25 15:16:50 +053012748 if (!pmksa) {
12749 hddLog(LOGE, FL("pmksa is NULL"));
12750 return -EINVAL;
12751 }
12752
12753 if (!pmksa->bssid || !pmksa->pmkid) {
12754 hddLog(LOGE, FL("pmksa->bssid(%p) or pmksa->pmkid(%p) is NULL"),
12755 pmksa->bssid, pmksa->pmkid);
12756 return -EINVAL;
12757 }
12758
12759 hddLog(VOS_TRACE_LEVEL_DEBUG, "%s: set PMKSA for " MAC_ADDRESS_STR,
12760 __func__, MAC_ADDR_ARRAY(pmksa->bssid));
12761
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053012762 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
12763 status = wlan_hdd_validate_context(pHddCtx);
Jeff Johnson04dd8a82012-06-29 20:41:40 -070012764
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053012765 if (0 != status)
Jeff Johnson04dd8a82012-06-29 20:41:40 -070012766 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053012767 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
12768 "%s: HDD context is not valid", __func__);
12769 return status;
Jeff Johnson04dd8a82012-06-29 20:41:40 -070012770 }
12771
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012772 // Retrieve halHandle
Jeff Johnson04dd8a82012-06-29 20:41:40 -070012773 halHandle = WLAN_HDD_GET_HAL_CTX(pAdapter);
12774
Kanchanapally, Vidyullatha2633ace2014-09-25 15:16:50 +053012775 vos_mem_copy(pmk_id.BSSID, pmksa->bssid, ETHER_ADDR_LEN);
12776 vos_mem_copy(pmk_id.PMKID, pmksa->pmkid, CSR_RSN_PMKID_SIZE);
Jeff Johnson04dd8a82012-06-29 20:41:40 -070012777
Kanchanapally, Vidyullatha2633ace2014-09-25 15:16:50 +053012778 /* Add to the PMKSA ID Cache in CSR */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012779 result = sme_RoamSetPMKIDCache(halHandle,pAdapter->sessionId,
Kanchanapally, Vidyullatha2633ace2014-09-25 15:16:50 +053012780 &pmk_id, 1, FALSE);
12781
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053012782 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
12783 TRACE_CODE_HDD_CFG80211_SET_PMKSA,
12784 pAdapter->sessionId, result));
Kanchanapally, Vidyullatha2633ace2014-09-25 15:16:50 +053012785
12786 return HAL_STATUS_SUCCESS(result) ? 0 : -EINVAL;
Jeff Johnson04dd8a82012-06-29 20:41:40 -070012787}
12788
Mahesh A Saptasagarf7418d72014-06-02 14:48:54 +053012789static int wlan_hdd_cfg80211_set_pmksa(struct wiphy *wiphy, struct net_device *dev,
12790 struct cfg80211_pmksa *pmksa)
12791{
12792 int ret;
12793
12794 vos_ssr_protect(__func__);
12795 ret = __wlan_hdd_cfg80211_set_pmksa(wiphy, dev, pmksa);
12796 vos_ssr_unprotect(__func__);
12797
12798 return ret;
12799}
Jeff Johnson04dd8a82012-06-29 20:41:40 -070012800
Wilson Yang6507c4e2013-10-01 20:11:19 -070012801
Mahesh A Saptasagarf7418d72014-06-02 14:48:54 +053012802static int __wlan_hdd_cfg80211_del_pmksa(struct wiphy *wiphy, struct net_device *dev,
Wilson Yang6507c4e2013-10-01 20:11:19 -070012803 struct cfg80211_pmksa *pmksa)
Jeff Johnson04dd8a82012-06-29 20:41:40 -070012804{
Wilson Yang6507c4e2013-10-01 20:11:19 -070012805 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
12806 tHalHandle halHandle;
Wilson Yang6507c4e2013-10-01 20:11:19 -070012807 hdd_context_t *pHddCtx;
Wilson Yangef657d32014-01-15 19:19:23 -080012808 int status = 0;
Wilson Yang6507c4e2013-10-01 20:11:19 -070012809
Wilson Yang6507c4e2013-10-01 20:11:19 -070012810 /* Validate pAdapter */
12811 if (NULL == pAdapter)
12812 {
12813 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Invalid Adapter" ,__func__);
12814 return -EINVAL;
12815 }
12816
Kanchanapally, Vidyullatha2633ace2014-09-25 15:16:50 +053012817 if (!pmksa) {
12818 hddLog(LOGE, FL("pmksa is NULL"));
12819 return -EINVAL;
12820 }
12821
12822 if (!pmksa->bssid) {
12823 hddLog(LOGE, FL("pmksa->bssid is NULL"));
12824 return -EINVAL;
12825 }
12826
Kiet Lam98c46a12014-10-31 15:34:57 -070012827 hddLog(VOS_TRACE_LEVEL_DEBUG, "%s: deleting PMKSA for " MAC_ADDRESS_STR,
12828 __func__, MAC_ADDR_ARRAY(pmksa->bssid));
12829
Wilson Yang6507c4e2013-10-01 20:11:19 -070012830 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
12831 status = wlan_hdd_validate_context(pHddCtx);
12832
12833 if (0 != status)
12834 {
12835 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
12836 "%s: HDD context is not valid", __func__);
12837 return status;
12838 }
12839
12840 /*Retrieve halHandle*/
12841 halHandle = WLAN_HDD_GET_HAL_CTX(pAdapter);
12842
Kanchanapally, Vidyullatha2633ace2014-09-25 15:16:50 +053012843 /* Delete the PMKID CSR cache */
12844 if (eHAL_STATUS_SUCCESS !=
12845 sme_RoamDelPMKIDfromCache(halHandle,
12846 pAdapter->sessionId, pmksa->bssid, FALSE)) {
12847 hddLog(LOGE, FL("Failed to delete PMKSA for "MAC_ADDRESS_STR),
12848 MAC_ADDR_ARRAY(pmksa->bssid));
12849 status = -EINVAL;
Wilson Yang6507c4e2013-10-01 20:11:19 -070012850 }
12851
Wilson Yangef657d32014-01-15 19:19:23 -080012852 return status;
Jeff Johnson04dd8a82012-06-29 20:41:40 -070012853}
12854
Wilson Yang6507c4e2013-10-01 20:11:19 -070012855
Mahesh A Saptasagarf7418d72014-06-02 14:48:54 +053012856static int wlan_hdd_cfg80211_del_pmksa(struct wiphy *wiphy, struct net_device *dev,
12857 struct cfg80211_pmksa *pmksa)
12858{
12859 int ret;
Wilson Yang6507c4e2013-10-01 20:11:19 -070012860
Mahesh A Saptasagarf7418d72014-06-02 14:48:54 +053012861 vos_ssr_protect(__func__);
12862 ret = __wlan_hdd_cfg80211_del_pmksa(wiphy, dev, pmksa);
12863 vos_ssr_unprotect(__func__);
12864
12865 return ret;
12866
12867}
12868
12869static int __wlan_hdd_cfg80211_flush_pmksa(struct wiphy *wiphy, struct net_device *dev)
Jeff Johnson04dd8a82012-06-29 20:41:40 -070012870{
Wilson Yang6507c4e2013-10-01 20:11:19 -070012871 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
12872 tHalHandle halHandle;
12873 hdd_context_t *pHddCtx;
Wilson Yangef657d32014-01-15 19:19:23 -080012874 int status = 0;
Wilson Yang6507c4e2013-10-01 20:11:19 -070012875
12876 hddLog(VOS_TRACE_LEVEL_DEBUG, "%s: flushing PMKSA ",__func__);
12877
12878 /* Validate pAdapter */
12879 if (NULL == pAdapter)
12880 {
12881 hddLog(VOS_TRACE_LEVEL_ERROR,
12882 "%s: Invalid Adapter" ,__func__);
12883 return -EINVAL;
12884 }
12885
12886 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
12887 status = wlan_hdd_validate_context(pHddCtx);
12888
12889 if (0 != status)
12890 {
12891 hddLog(VOS_TRACE_LEVEL_ERROR,
12892 "%s: HDD context is not valid", __func__);
12893 return status;
12894 }
12895
12896 /*Retrieve halHandle*/
12897 halHandle = WLAN_HDD_GET_HAL_CTX(pAdapter);
12898
Kanchanapally, Vidyullatha2633ace2014-09-25 15:16:50 +053012899 /* Flush the PMKID cache in CSR */
12900 if (eHAL_STATUS_SUCCESS !=
12901 sme_RoamDelPMKIDfromCache(halHandle, pAdapter->sessionId, NULL, TRUE)) {
12902 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Cannot flush PMKIDCache"));
12903 status = -EINVAL;
Wilson Yang6507c4e2013-10-01 20:11:19 -070012904 }
12905
Wilson Yangef657d32014-01-15 19:19:23 -080012906 return status;
Jeff Johnson04dd8a82012-06-29 20:41:40 -070012907}
Mahesh A Saptasagarf7418d72014-06-02 14:48:54 +053012908
12909static int wlan_hdd_cfg80211_flush_pmksa(struct wiphy *wiphy, struct net_device *dev)
12910{
12911 int ret;
12912
12913 vos_ssr_protect(__func__);
12914 ret = __wlan_hdd_cfg80211_flush_pmksa(wiphy, dev);
12915 vos_ssr_unprotect(__func__);
12916
12917 return ret;
12918}
Jeff Johnson04dd8a82012-06-29 20:41:40 -070012919#endif
12920
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070012921#if defined(WLAN_FEATURE_VOWIFI_11R) && defined(KERNEL_SUPPORT_11R_CFG80211)
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053012922static int __wlan_hdd_cfg80211_update_ft_ies(struct wiphy *wiphy,
12923 struct net_device *dev,
12924 struct cfg80211_update_ft_ies_params *ftie)
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070012925{
12926 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
12927 hdd_station_ctx_t *pHddStaCtx;
12928
12929 if (NULL == pAdapter)
12930 {
Arif Hussain6d2a3322013-11-17 19:50:10 -080012931 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Adapter is NULL", __func__);
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070012932 return -ENODEV;
12933 }
12934
12935 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
12936
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053012937 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
12938 TRACE_CODE_HDD_CFG80211_UPDATE_FT_IES,
12939 pAdapter->sessionId, pHddStaCtx->conn_info.connState));
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070012940 // Added for debug on reception of Re-assoc Req.
12941 if (eConnectionState_Associated != pHddStaCtx->conn_info.connState)
12942 {
Arif Hussain6d2a3322013-11-17 19:50:10 -080012943 hddLog(LOGE, FL("Called with Ie of length = %zu when not associated"),
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070012944 ftie->ie_len);
Arif Hussain6d2a3322013-11-17 19:50:10 -080012945 hddLog(LOGE, FL("Should be Re-assoc Req IEs"));
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070012946 }
12947
12948#ifdef WLAN_FEATURE_VOWIFI_11R_DEBUG
Arif Hussain6d2a3322013-11-17 19:50:10 -080012949 hddLog(LOGE, FL("%s called with Ie of length = %zu"), __func__,
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070012950 ftie->ie_len);
12951#endif
12952
12953 // Pass the received FT IEs to SME
Gopichand Nakkala356fb102013-03-06 12:34:04 +053012954 sme_SetFTIEs( WLAN_HDD_GET_HAL_CTX(pAdapter), pAdapter->sessionId,
12955 (const u8 *)ftie->ie,
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070012956 ftie->ie_len);
12957 return 0;
12958}
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053012959
12960static int wlan_hdd_cfg80211_update_ft_ies(struct wiphy *wiphy,
12961 struct net_device *dev,
12962 struct cfg80211_update_ft_ies_params *ftie)
12963{
12964 int ret;
12965
12966 vos_ssr_protect(__func__);
12967 ret = __wlan_hdd_cfg80211_update_ft_ies(wiphy, dev, ftie);
12968 vos_ssr_unprotect(__func__);
12969
12970 return ret;
12971}
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070012972#endif
Jeff Johnson04dd8a82012-06-29 20:41:40 -070012973
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053012974#ifdef FEATURE_WLAN_SCAN_PNO
12975
12976void hdd_cfg80211_sched_scan_done_callback(void *callbackContext,
12977 tSirPrefNetworkFoundInd *pPrefNetworkFoundInd)
12978{
12979 int ret;
12980 hdd_adapter_t* pAdapter = (hdd_adapter_t*)callbackContext;
12981 hdd_context_t *pHddCtx;
12982
Nirav Shah80830bf2013-12-31 16:35:12 +053012983 ENTER();
12984
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053012985 if (NULL == pAdapter)
12986 {
Agarwal Ashish971c2882013-10-30 20:11:12 +053012987 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053012988 "%s: HDD adapter is Null", __func__);
12989 return ;
12990 }
12991
12992 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
12993 if (NULL == pHddCtx)
12994 {
12995 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
12996 "%s: HDD context is Null!!!", __func__);
12997 return ;
12998 }
12999
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053013000 spin_lock(&pHddCtx->schedScan_lock);
13001 if (TRUE == pHddCtx->isWiphySuspended)
13002 {
13003 pHddCtx->isSchedScanUpdatePending = TRUE;
13004 spin_unlock(&pHddCtx->schedScan_lock);
13005 hddLog(VOS_TRACE_LEVEL_INFO,
13006 "%s: Update cfg80211 scan database after it resume", __func__);
13007 return ;
13008 }
13009 spin_unlock(&pHddCtx->schedScan_lock);
13010
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053013011 ret = wlan_hdd_cfg80211_update_bss(pHddCtx->wiphy, pAdapter);
13012
13013 if (0 > ret)
13014 hddLog(VOS_TRACE_LEVEL_INFO, "%s: NO SCAN result", __func__);
13015
13016 cfg80211_sched_scan_results(pHddCtx->wiphy);
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053013017 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
13018 "%s: cfg80211 scan result database updated", __func__);
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053013019}
13020
13021/*
Mahesh A Saptasagar0f7b0372013-11-28 23:23:07 +053013022 * FUNCTION: wlan_hdd_is_pno_allowed
Vinay Krishna Erannacbf75f42014-02-26 17:35:20 +053013023 * Disallow pno if any session is active
Mahesh A Saptasagar0f7b0372013-11-28 23:23:07 +053013024 */
13025static eHalStatus wlan_hdd_is_pno_allowed(hdd_adapter_t *pAdapter)
13026{
13027 hdd_adapter_list_node_t *pAdapterNode = NULL, *pNext = NULL;
13028 hdd_adapter_t *pTempAdapter = NULL;
Vinay Krishna Eranna23ffd182013-12-26 19:16:55 +053013029 hdd_station_ctx_t *pStaCtx;
Mahesh A Saptasagar0f7b0372013-11-28 23:23:07 +053013030 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
13031 int status = 0;
13032 status = hdd_get_front_adapter(pHddCtx, &pAdapterNode);
13033
Vinay Krishna Erannacbf75f42014-02-26 17:35:20 +053013034 /* The current firmware design does not allow PNO during any
13035 * active sessions. Hence, determine the active sessions
13036 * and return a failure.
13037 */
Mahesh A Saptasagar0f7b0372013-11-28 23:23:07 +053013038 while ((NULL != pAdapterNode) && (VOS_STATUS_SUCCESS == status))
13039 {
13040 pTempAdapter = pAdapterNode->pAdapter;
Vinay Krishna Eranna23ffd182013-12-26 19:16:55 +053013041 pStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pTempAdapter);
Mahesh A Saptasagar0f7b0372013-11-28 23:23:07 +053013042
Vinay Krishna Eranna23ffd182013-12-26 19:16:55 +053013043 if (((WLAN_HDD_INFRA_STATION == pTempAdapter->device_mode)
13044 && (eConnectionState_NotConnected != pStaCtx->conn_info.connState))
13045 || (WLAN_HDD_P2P_CLIENT == pTempAdapter->device_mode)
13046 || (WLAN_HDD_P2P_GO == pTempAdapter->device_mode)
13047 || (WLAN_HDD_SOFTAP == pTempAdapter->device_mode)
13048 )
Mahesh A Saptasagar0f7b0372013-11-28 23:23:07 +053013049 {
Vinay Krishna Eranna23ffd182013-12-26 19:16:55 +053013050 return eHAL_STATUS_FAILURE;
Mahesh A Saptasagar0f7b0372013-11-28 23:23:07 +053013051 }
13052 status = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
13053 pAdapterNode = pNext;
13054 }
Vinay Krishna Eranna23ffd182013-12-26 19:16:55 +053013055 return eHAL_STATUS_SUCCESS;
Mahesh A Saptasagar0f7b0372013-11-28 23:23:07 +053013056}
13057
Vinay Krishna Erannaf0e523b2014-03-01 21:00:16 +053013058void hdd_cfg80211_sched_scan_start_status_cb(void *callbackContext, VOS_STATUS status)
13059{
13060 hdd_adapter_t *pAdapter = callbackContext;
13061 hdd_context_t *pHddCtx;
13062
13063 if ((NULL == pAdapter) || (WLAN_HDD_ADAPTER_MAGIC != pAdapter->magic))
13064 {
13065 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
13066 FL("Invalid adapter or adapter has invalid magic"));
13067 return;
13068 }
13069
13070 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
13071 if (0 != wlan_hdd_validate_context(pHddCtx))
13072 {
13073 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
13074 FL("HDD context is not valid"));
13075 return;
13076 }
13077
c_hpothub53c45d2014-08-18 16:53:14 +053013078 if (VOS_STATUS_SUCCESS != status)
13079 {
13080 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Vinay Krishna Erannaf0e523b2014-03-01 21:00:16 +053013081 FL("PNO enable response status = %d"), status);
c_hpothub53c45d2014-08-18 16:53:14 +053013082 pHddCtx->isPnoEnable = FALSE;
13083 }
Vinay Krishna Erannaf0e523b2014-03-01 21:00:16 +053013084
13085 pAdapter->pno_req_status = (status == VOS_STATUS_SUCCESS) ? 0 : -EBUSY;
13086 complete(&pAdapter->pno_comp_var);
13087}
13088
Mahesh A Saptasagar0f7b0372013-11-28 23:23:07 +053013089/*
Mahesh A Saptasagar6cc38562014-05-23 21:22:17 +053013090 * FUNCTION: __wlan_hdd_cfg80211_sched_scan_start
13091 * Function to enable PNO
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053013092 */
Mahesh A Saptasagar6cc38562014-05-23 21:22:17 +053013093static int __wlan_hdd_cfg80211_sched_scan_start(struct wiphy *wiphy,
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053013094 struct net_device *dev, struct cfg80211_sched_scan_request *request)
13095{
13096 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
13097 tpSirPNOScanReq pPnoRequest = NULL;
13098 hdd_context_t *pHddCtx;
13099 tHalHandle hHal;
Mahesh A Saptasagar7bd6ad42014-07-21 18:56:33 +053013100 v_U32_t i, indx, num_ch, tempInterval, j;
Sushant Kaushikd62d9782014-02-19 15:39:40 +053013101 u8 valid_ch[WNI_CFG_VALID_CHANNEL_LIST_LEN] = {0};
13102 u8 channels_allowed[WNI_CFG_VALID_CHANNEL_LIST_LEN] = {0};
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053013103 v_U32_t num_channels_allowed = WNI_CFG_VALID_CHANNEL_LIST_LEN;
13104 eHalStatus status = eHAL_STATUS_FAILURE;
Kamath Vinayakba5313f2013-08-22 15:52:39 +053013105 int ret = 0;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053013106
13107 if (NULL == pAdapter)
13108 {
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053013109 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053013110 "%s: HDD adapter is Null", __func__);
13111 return -ENODEV;
13112 }
13113
13114 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053013115 ret = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053013116
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053013117 if (0 != ret)
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053013118 {
Gopichand Nakkalac005b7c2013-05-14 16:04:14 +053013119 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
13120 "%s: HDD context is not valid", __func__);
Kamath Vinayakba5313f2013-08-22 15:52:39 +053013121 return -EINVAL;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053013122 }
13123
13124 hHal = WLAN_HDD_GET_HAL_CTX(pAdapter);
13125 if (NULL == hHal)
13126 {
13127 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
13128 "%s: HAL context is Null!!!", __func__);
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053013129 return -EINVAL;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053013130 }
Sushant Kaushik2fe89932014-09-03 10:58:09 +053013131 sme_ScanFlushResult(hHal, pAdapter->sessionId);
Mahesh A Saptasagar2395ee62014-05-21 19:12:21 +053013132 ret = wlan_hdd_scan_abort(pAdapter);
Girish Gowli4bf7a632014-06-12 13:42:11 +053013133 if (ret < 0)
Mahesh A Saptasagar2395ee62014-05-21 19:12:21 +053013134 {
13135 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
13136 "%s: aborting the existing scan is unsuccessfull", __func__);
13137 return -EBUSY;
13138 }
13139
Vinay Krishna Eranna23ffd182013-12-26 19:16:55 +053013140 if (eHAL_STATUS_SUCCESS != wlan_hdd_is_pno_allowed(pAdapter))
Mahesh A Saptasagar0f7b0372013-11-28 23:23:07 +053013141 {
Vinay Krishna Erannacbf75f42014-02-26 17:35:20 +053013142 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_WARN,
Vinay Krishna Eranna23ffd182013-12-26 19:16:55 +053013143 FL("Cannot handle sched_scan"));
Mahesh A Saptasagar0f7b0372013-11-28 23:23:07 +053013144 return -EBUSY;
13145 }
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053013146
c_hpothu37f21312014-04-09 21:49:54 +053013147 if (TRUE == pHddCtx->isPnoEnable)
13148 {
13149 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_WARN,
13150 FL("already PNO is enabled"));
13151 return -EBUSY;
13152 }
c_hpothu225aa7c2014-10-22 17:45:13 +053013153
13154 if (VOS_STATUS_SUCCESS != wlan_hdd_cancel_remain_on_channel(pHddCtx))
13155 {
13156 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
13157 "%s: abort ROC failed ", __func__);
13158 return -EBUSY;
13159 }
13160
c_hpothu37f21312014-04-09 21:49:54 +053013161 pHddCtx->isPnoEnable = TRUE;
13162
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053013163 pPnoRequest = (tpSirPNOScanReq) vos_mem_malloc(sizeof (tSirPNOScanReq));
13164 if (NULL == pPnoRequest)
13165 {
13166 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
13167 "%s: vos_mem_malloc failed", __func__);
c_hpothu37f21312014-04-09 21:49:54 +053013168 pHddCtx->isPnoEnable = FALSE;
Kamath Vinayakba5313f2013-08-22 15:52:39 +053013169 return -ENOMEM;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053013170 }
13171
Madan Mohan Koyyalamudic3f04352013-09-26 19:21:48 +053013172 memset(pPnoRequest, 0, sizeof (tSirPNOScanReq));
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053013173 pPnoRequest->enable = 1; /*Enable PNO */
13174 pPnoRequest->ucNetworksCount = request->n_match_sets;
13175
13176 if (( !pPnoRequest->ucNetworksCount ) ||
13177 ( pPnoRequest->ucNetworksCount > SIR_PNO_MAX_SUPP_NETWORKS ))
13178 {
13179 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Sushant Kaushik1e406c32014-05-09 15:57:52 +053013180 "%s: Network input is not correct %d Max Network supported is %d",
13181 __func__, pPnoRequest->ucNetworksCount,
13182 SIR_PNO_MAX_SUPP_NETWORKS);
Kamath Vinayakba5313f2013-08-22 15:52:39 +053013183 ret = -EINVAL;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053013184 goto error;
13185 }
13186
13187 if ( SIR_PNO_MAX_NETW_CHANNELS_EX < request->n_channels )
13188 {
13189 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Nirav Shah80830bf2013-12-31 16:35:12 +053013190 "%s: Incorrect number of channels %d",
13191 __func__, request->n_channels);
Kamath Vinayakba5313f2013-08-22 15:52:39 +053013192 ret = -EINVAL;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053013193 goto error;
13194 }
13195
13196 /* Framework provides one set of channels(all)
13197 * common for all saved profile */
13198 if (0 != ccmCfgGetStr(hHal, WNI_CFG_VALID_CHANNEL_LIST,
13199 channels_allowed, &num_channels_allowed))
13200 {
13201 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
13202 "%s: failed to get valid channel list", __func__);
Kamath Vinayakba5313f2013-08-22 15:52:39 +053013203 ret = -EINVAL;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053013204 goto error;
13205 }
13206 /* Checking each channel against allowed channel list */
13207 num_ch = 0;
Nirav Shah80830bf2013-12-31 16:35:12 +053013208 if (request->n_channels)
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053013209 {
Nirav Shah80830bf2013-12-31 16:35:12 +053013210 char chList [(request->n_channels*5)+1];
13211 int len;
13212 for (i = 0, len = 0; i < request->n_channels; i++)
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053013213 {
Nirav Shah80830bf2013-12-31 16:35:12 +053013214 for (indx = 0; indx < num_channels_allowed; indx++)
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053013215 {
Nirav Shah80830bf2013-12-31 16:35:12 +053013216 if (request->channels[i]->hw_value == channels_allowed[indx])
13217 {
13218 valid_ch[num_ch++] = request->channels[i]->hw_value;
13219 len += snprintf(chList+len, 5, "%d ",
13220 request->channels[i]->hw_value);
13221 break ;
13222 }
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053013223 }
13224 }
Nirav Shah80830bf2013-12-31 16:35:12 +053013225 hddLog(VOS_TRACE_LEVEL_INFO,"Channel-List: %s ", chList);
13226 }
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053013227
13228 /* Filling per profile params */
13229 for (i = 0; i < pPnoRequest->ucNetworksCount; i++)
13230 {
13231 pPnoRequest->aNetworks[i].ssId.length =
13232 request->match_sets[i].ssid.ssid_len;
13233
13234 if (( 0 == pPnoRequest->aNetworks[i].ssId.length ) ||
13235 ( pPnoRequest->aNetworks[i].ssId.length > 32 ) )
13236 {
13237 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Nirav Shah80830bf2013-12-31 16:35:12 +053013238 "%s: SSID Len %d is not correct for network %d",
13239 __func__, pPnoRequest->aNetworks[i].ssId.length, i);
Kamath Vinayakba5313f2013-08-22 15:52:39 +053013240 ret = -EINVAL;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053013241 goto error;
13242 }
13243
13244 memcpy(pPnoRequest->aNetworks[i].ssId.ssId,
13245 request->match_sets[i].ssid.ssid,
13246 request->match_sets[i].ssid.ssid_len);
Sushant Kaushik1e406c32014-05-09 15:57:52 +053013247 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
13248 "%s: SSID of network %d is %s ", __func__,
13249 i, pPnoRequest->aNetworks[i].ssId.ssId);
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053013250 pPnoRequest->aNetworks[i].authentication = 0; /*eAUTH_TYPE_ANY*/
13251 pPnoRequest->aNetworks[i].encryption = 0; /*eED_ANY*/
13252 pPnoRequest->aNetworks[i].bcastNetwType = 0; /*eBCAST_UNKNOWN*/
13253
13254 /*Copying list of valid channel into request */
13255 memcpy(pPnoRequest->aNetworks[i].aChannels, valid_ch, num_ch);
13256 pPnoRequest->aNetworks[i].ucChannelCount = num_ch;
13257
13258 pPnoRequest->aNetworks[i].rssiThreshold = 0; //Default value
13259 }
13260
Mahesh A Saptasagar7bd6ad42014-07-21 18:56:33 +053013261 for (i = 0; i < request->n_ssids; i++)
13262 {
13263 j = 0;
13264 while (j < pPnoRequest->ucNetworksCount)
13265 {
13266 if ((pPnoRequest->aNetworks[j].ssId.length ==
13267 request->ssids[i].ssid_len) &&
13268 (0 == memcmp(pPnoRequest->aNetworks[j].ssId.ssId,
13269 request->ssids[i].ssid,
13270 pPnoRequest->aNetworks[j].ssId.length)))
13271 {
13272 pPnoRequest->aNetworks[j].bcastNetwType = eBCAST_HIDDEN;
13273 break;
13274 }
13275 j++;
13276 }
13277 }
13278 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
13279 "Number of hidden networks being Configured = %d",
13280 request->n_ssids);
Madan Mohan Koyyalamudia7765d52013-09-18 16:49:56 +053013281 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Jeff Johnson59a121e2013-11-30 09:46:08 -080013282 "request->ie_len = %zu", request->ie_len);
Madan Mohan Koyyalamudia7765d52013-09-18 16:49:56 +053013283 if ((0 < request->ie_len) && (NULL != request->ie))
13284 {
13285 pPnoRequest->us24GProbeTemplateLen = request->ie_len;
13286 memcpy(&pPnoRequest->p24GProbeTemplate, request->ie,
13287 pPnoRequest->us24GProbeTemplateLen);
13288
13289 pPnoRequest->us5GProbeTemplateLen = request->ie_len;
13290 memcpy(&pPnoRequest->p5GProbeTemplate, request->ie,
13291 pPnoRequest->us5GProbeTemplateLen);
13292 }
13293
Madan Mohan Koyyalamudi1d16f462013-08-27 16:25:34 +053013294 /* Driver gets only one time interval which is hardcoded in
13295 * supplicant for 10000ms. Taking power consumption into account 6 timers
13296 * will be used, Timervalue is increased exponentially i.e 10,20,40,
13297 * 80,160,320 secs. And number of scan cycle for each timer
13298 * is configurable through INI param gPNOScanTimerRepeatValue.
13299 * If it is set to 0 only one timer will be used and PNO scan cycle
13300 * will be repeated after each interval specified by supplicant
13301 * till PNO is disabled.
13302 */
13303 if (0 == pHddCtx->cfg_ini->configPNOScanTimerRepeatValue)
13304 pPnoRequest->scanTimers.ucScanTimersCount = HDD_PNO_SCAN_TIMERS_SET_ONE;
13305 else
13306 pPnoRequest->scanTimers.ucScanTimersCount =
13307 HDD_PNO_SCAN_TIMERS_SET_MULTIPLE;
13308
13309 tempInterval = (request->interval)/1000;
13310 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
13311 "Base scan interval = %d PNOScanTimerRepeatValue = %d",
13312 tempInterval, pHddCtx->cfg_ini->configPNOScanTimerRepeatValue);
13313 for ( i = 0; i < pPnoRequest->scanTimers.ucScanTimersCount; i++)
13314 {
13315 pPnoRequest->scanTimers.aTimerValues[i].uTimerRepeat =
13316 pHddCtx->cfg_ini->configPNOScanTimerRepeatValue;
13317 pPnoRequest->scanTimers.aTimerValues[i].uTimerValue = tempInterval;
13318 tempInterval *= 2;
13319 }
13320 //Repeat last timer until pno disabled.
13321 pPnoRequest->scanTimers.aTimerValues[i-1].uTimerRepeat = 0;
13322
Madan Mohan Koyyalamudid206c7b2013-09-26 22:54:51 +053013323 pPnoRequest->modePNO = SIR_PNO_MODE_IMMEDIATE;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053013324
Vinay Krishna Erannaf0e523b2014-03-01 21:00:16 +053013325 INIT_COMPLETION(pAdapter->pno_comp_var);
13326 pPnoRequest->statusCallback = hdd_cfg80211_sched_scan_start_status_cb;
13327 pPnoRequest->callbackContext = pAdapter;
13328 pAdapter->pno_req_status = 0;
13329
Nirav Shah80830bf2013-12-31 16:35:12 +053013330 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
13331 "SessionId %d, enable %d, modePNO %d, ucScanTimersCount %d",
13332 pAdapter->sessionId, pPnoRequest->enable, pPnoRequest->modePNO,
13333 pPnoRequest->scanTimers.ucScanTimersCount);
13334
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053013335 status = sme_SetPreferredNetworkList(WLAN_HDD_GET_HAL_CTX(pAdapter),
13336 pPnoRequest, pAdapter->sessionId,
13337 hdd_cfg80211_sched_scan_done_callback, pAdapter);
13338 if (eHAL_STATUS_SUCCESS != status)
13339 {
13340 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Nirav Shah80830bf2013-12-31 16:35:12 +053013341 "%s: Failed to enable PNO", __func__);
Kamath Vinayakba5313f2013-08-22 15:52:39 +053013342 ret = -EINVAL;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053013343 goto error;
13344 }
13345
Vinay Krishna Erannaf0e523b2014-03-01 21:00:16 +053013346 ret = wait_for_completion_timeout(
13347 &pAdapter->pno_comp_var,
13348 msecs_to_jiffies(WLAN_WAIT_TIME_PNO));
13349 if (0 >= ret)
13350 {
13351 // Did not receive the response for PNO enable in time.
13352 // Assuming the PNO enable was success.
13353 // Returning error from here, because we timeout, results
13354 // in side effect of Wifi (Wifi Setting) not to work.
13355 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
13356 FL("Timed out waiting for PNO to be Enabled"));
13357 ret = 0;
13358 goto error;
13359 }
13360
c_hpothu3c986b22014-07-09 14:45:09 +053013361 vos_mem_free(pPnoRequest);
Vinay Krishna Erannaf0e523b2014-03-01 21:00:16 +053013362 ret = pAdapter->pno_req_status;
c_hpothu37f21312014-04-09 21:49:54 +053013363 return ret;
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053013364
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053013365error:
Vinay Krishna Erannaf0e523b2014-03-01 21:00:16 +053013366 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
13367 FL("PNO scanRequest offloaded ret = %d"), ret);
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053013368 vos_mem_free(pPnoRequest);
c_hpothu37f21312014-04-09 21:49:54 +053013369 pHddCtx->isPnoEnable = FALSE;
Kamath Vinayakba5313f2013-08-22 15:52:39 +053013370 return ret;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053013371}
13372
13373/*
Mahesh A Saptasagar6cc38562014-05-23 21:22:17 +053013374 * FUNCTION: wlan_hdd_cfg80211_sched_scan_start
13375 * NL interface to enable PNO
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053013376 */
Mahesh A Saptasagar6cc38562014-05-23 21:22:17 +053013377static int wlan_hdd_cfg80211_sched_scan_start(struct wiphy *wiphy,
13378 struct net_device *dev, struct cfg80211_sched_scan_request *request)
13379{
13380 int ret;
13381
13382 vos_ssr_protect(__func__);
13383 ret = __wlan_hdd_cfg80211_sched_scan_start(wiphy, dev, request);
13384 vos_ssr_unprotect(__func__);
13385
13386 return ret;
13387}
13388
13389/*
13390 * FUNCTION: __wlan_hdd_cfg80211_sched_scan_stop
13391 * Function to disable PNO
13392 */
13393static int __wlan_hdd_cfg80211_sched_scan_stop(struct wiphy *wiphy,
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053013394 struct net_device *dev)
13395{
13396 eHalStatus status = eHAL_STATUS_FAILURE;
13397 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
13398 hdd_context_t *pHddCtx;
13399 tHalHandle hHal;
13400 tpSirPNOScanReq pPnoRequest = NULL;
Kamath Vinayakba5313f2013-08-22 15:52:39 +053013401 int ret = 0;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053013402
13403 ENTER();
13404
13405 if (NULL == pAdapter)
13406 {
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053013407 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053013408 "%s: HDD adapter is Null", __func__);
13409 return -ENODEV;
13410 }
13411
13412 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053013413
Kamath Vinayakba5313f2013-08-22 15:52:39 +053013414 if (NULL == pHddCtx)
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053013415 {
Gopichand Nakkalac005b7c2013-05-14 16:04:14 +053013416 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Kamath Vinayakba5313f2013-08-22 15:52:39 +053013417 "%s: HDD context is Null", __func__);
13418 return -ENODEV;
13419 }
13420
13421 /* The return 0 is intentional when isLogpInProgress and
13422 * isLoadUnloadInProgress. We did observe a crash due to a return of
13423 * failure in sched_scan_stop , especially for a case where the unload
13424 * of the happens at the same time. The function __cfg80211_stop_sched_scan
13425 * was clearing rdev->sched_scan_req only when the sched_scan_stop returns
13426 * success. If it returns a failure , then its next invocation due to the
13427 * clean up of the second interface will have the dev pointer corresponding
13428 * to the first one leading to a crash.
13429 */
13430 if (pHddCtx->isLogpInProgress)
13431 {
13432 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
13433 "%s: LOGP in Progress. Ignore!!!", __func__);
13434 return ret;
13435 }
13436
Mihir Shete18156292014-03-11 15:38:30 +053013437 if (WLAN_HDD_IS_LOAD_UNLOAD_IN_PROGRESS(pHddCtx))
Kamath Vinayakba5313f2013-08-22 15:52:39 +053013438 {
13439 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
13440 "%s: Unloading/Loading in Progress. Ignore!!!", __func__);
13441 return ret;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053013442 }
13443
13444 hHal = WLAN_HDD_GET_HAL_CTX(pAdapter);
13445 if (NULL == hHal)
13446 {
13447 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
13448 "%s: HAL context is Null!!!", __func__);
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053013449 return -EINVAL;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053013450 }
13451
13452 pPnoRequest = (tpSirPNOScanReq) vos_mem_malloc(sizeof (tSirPNOScanReq));
13453 if (NULL == pPnoRequest)
13454 {
13455 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
13456 "%s: vos_mem_malloc failed", __func__);
Kamath Vinayakba5313f2013-08-22 15:52:39 +053013457 return -ENOMEM;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053013458 }
13459
13460 memset(pPnoRequest, 0, sizeof (tSirPNOScanReq));
13461 pPnoRequest->enable = 0; /* Disable PNO */
13462 pPnoRequest->ucNetworksCount = 0;
13463
13464 status = sme_SetPreferredNetworkList(hHal, pPnoRequest,
13465 pAdapter->sessionId,
13466 NULL, pAdapter);
13467 if (eHAL_STATUS_SUCCESS != status)
13468 {
13469 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
13470 "Failed to disabled PNO");
Kamath Vinayakba5313f2013-08-22 15:52:39 +053013471 ret = -EINVAL;
Vinay Krishna Erannaf0e523b2014-03-01 21:00:16 +053013472 goto error;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053013473 }
c_hpothu37f21312014-04-09 21:49:54 +053013474 pHddCtx->isPnoEnable = FALSE;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053013475
Vinay Krishna Erannaf0e523b2014-03-01 21:00:16 +053013476error:
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053013477 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Vinay Krishna Erannaf0e523b2014-03-01 21:00:16 +053013478 FL("PNO scan disabled ret = %d"), ret);
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053013479 vos_mem_free(pPnoRequest);
13480
13481 EXIT();
Kamath Vinayakba5313f2013-08-22 15:52:39 +053013482 return ret;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053013483}
13484
Mahesh A Saptasagar6cc38562014-05-23 21:22:17 +053013485/*
13486 * FUNCTION: wlan_hdd_cfg80211_sched_scan_stop
13487 * NL interface to disable PNO
13488 */
13489static int wlan_hdd_cfg80211_sched_scan_stop(struct wiphy *wiphy,
13490 struct net_device *dev)
13491{
13492 int ret;
13493
13494 vos_ssr_protect(__func__);
13495 ret = __wlan_hdd_cfg80211_sched_scan_stop(wiphy, dev);
13496 vos_ssr_unprotect(__func__);
13497
13498 return ret;
13499}
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053013500#endif /*FEATURE_WLAN_SCAN_PNO*/
13501
13502
Mohit Khanna698ba2a2012-12-04 15:08:18 -080013503#ifdef FEATURE_WLAN_TDLS
Sunil Dutt Undekarieacac6f2014-03-21 14:08:53 +053013504#if TDLS_MGMT_VERSION2
Mohit Khanna698ba2a2012-12-04 15:08:18 -080013505static int wlan_hdd_cfg80211_tdls_mgmt(struct wiphy *wiphy, struct net_device *dev,
13506 u8 *peer, u8 action_code, u8 dialog_token,
Sunil Dutt Undekarieacac6f2014-03-21 14:08:53 +053013507 u16 status_code, u32 peer_capability, const u8 *buf, size_t len)
13508#else
13509static int wlan_hdd_cfg80211_tdls_mgmt(struct wiphy *wiphy, struct net_device *dev,
13510 u8 *peer, u8 action_code, u8 dialog_token,
13511 u16 status_code, const u8 *buf, size_t len)
13512#endif
Mohit Khanna698ba2a2012-12-04 15:08:18 -080013513{
13514
13515 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
13516 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
Mohit Khanna698ba2a2012-12-04 15:08:18 -080013517 u8 peerMac[6];
13518 VOS_STATUS status;
Gopichand Nakkala05922802013-03-14 12:23:19 -070013519 int max_sta_failed = 0;
Hoonki Leea34dd892013-02-05 22:56:02 -080013520 int responder;
Hoonki Leed37cbb32013-04-20 00:31:14 -070013521 long rc;
Sunil Dutt Undekarieacac6f2014-03-21 14:08:53 +053013522#if !(TDLS_MGMT_VERSION2)
13523 u32 peer_capability = 0;
13524#endif
Rajesh Chauhana34c6e62014-03-25 16:37:58 +053013525 tANI_U16 numCurrTdlsPeers;
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053013526
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053013527 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
13528 TRACE_CODE_HDD_CFG80211_TDLS_MGMT,
13529 pAdapter->sessionId, action_code));
Hoonki Lee11f7dda2013-02-14 16:55:44 -080013530 if (NULL == pHddCtx || NULL == pHddCtx->cfg_ini)
Mohit Khanna698ba2a2012-12-04 15:08:18 -080013531 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013532 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Mohit Khanna698ba2a2012-12-04 15:08:18 -080013533 "Invalid arguments");
13534 return -EINVAL;
13535 }
13536
Sameer Thalappil75ea31a2013-02-21 19:38:16 -080013537 if (pHddCtx->isLogpInProgress)
13538 {
13539 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
13540 "%s:LOGP in Progress. Ignore!!!", __func__);
Atul Mittal115287b2014-07-08 13:26:33 +053013541 wlan_hdd_tdls_set_link_status(pAdapter,
13542 peer,
13543 eTDLS_LINK_IDLE,
13544 eTDLS_LINK_UNSPECIFIED);
Sameer Thalappil75ea31a2013-02-21 19:38:16 -080013545 return -EBUSY;
13546 }
13547
Hoonki Lee27511902013-03-14 18:19:06 -070013548 if (eTDLS_SUPPORT_NOT_ENABLED == pHddCtx->tdls_mode)
Mohit Khanna698ba2a2012-12-04 15:08:18 -080013549 {
Hoonki Lee27511902013-03-14 18:19:06 -070013550 VOS_TRACE( VOS_MODULE_ID_HDD, TDLS_LOG_LEVEL,
13551 "%s: TDLS mode is disabled OR not enabled in FW."
13552 MAC_ADDRESS_STR " action %d declined.",
13553 __func__, MAC_ADDR_ARRAY(peer), action_code);
Mohit Khanna698ba2a2012-12-04 15:08:18 -080013554 return -ENOTSUPP;
13555 }
Lee Hoonkic1262f22013-01-24 21:59:00 -080013556
Hoonki Lee27511902013-03-14 18:19:06 -070013557 /* other than teardown frame, other mgmt frames are not sent if disabled */
13558 if (SIR_MAC_TDLS_TEARDOWN != action_code)
13559 {
13560 /* if tdls_mode is disabled to respond to peer's request */
13561 if (eTDLS_SUPPORT_DISABLED == pHddCtx->tdls_mode)
13562 {
13563 VOS_TRACE( VOS_MODULE_ID_HDD, TDLS_LOG_LEVEL,
13564 "%s: " MAC_ADDRESS_STR
Gopichand Nakkala34d1b062013-03-19 15:28:33 -070013565 " TDLS mode is disabled. action %d declined.",
13566 __func__, MAC_ADDR_ARRAY(peer), action_code);
Hoonki Lee27511902013-03-14 18:19:06 -070013567
13568 return -ENOTSUPP;
13569 }
Agarwal Ashish4b87f922014-06-18 03:03:21 +053013570
13571 if (vos_max_concurrent_connections_reached())
13572 {
13573 hddLog(VOS_TRACE_LEVEL_INFO, FL("Reached max concurrent connections"));
13574 return -EINVAL;
13575 }
Hoonki Lee27511902013-03-14 18:19:06 -070013576 }
13577
Gopichand Nakkalab977a972013-02-18 19:15:09 -080013578 if (WLAN_IS_TDLS_SETUP_ACTION(action_code))
13579 {
Madan Mohan Koyyalamudi96797442013-10-08 16:04:42 +053013580 if (NULL != wlan_hdd_tdls_is_progress(pHddCtx, peer, TRUE))
Gopichand Nakkalab977a972013-02-18 19:15:09 -080013581 {
13582 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Gopichand Nakkalac87400e2013-03-13 18:51:00 -070013583 "%s: " MAC_ADDRESS_STR
Gopichand Nakkala34d1b062013-03-19 15:28:33 -070013584 " TDLS setup is ongoing. action %d declined.",
13585 __func__, MAC_ADDR_ARRAY(peer), action_code);
13586 return -EPERM;
Gopichand Nakkalab977a972013-02-18 19:15:09 -080013587 }
13588 }
13589
Hoonki Lee11f7dda2013-02-14 16:55:44 -080013590 if (SIR_MAC_TDLS_SETUP_REQ == action_code ||
13591 SIR_MAC_TDLS_SETUP_RSP == action_code )
Lee Hoonkic1262f22013-01-24 21:59:00 -080013592 {
Rajesh Chauhana34c6e62014-03-25 16:37:58 +053013593 numCurrTdlsPeers = wlan_hdd_tdlsConnectedPeers(pAdapter);
13594 if (HDD_MAX_NUM_TDLS_STA <= numCurrTdlsPeers)
Lee Hoonkic1262f22013-01-24 21:59:00 -080013595 {
13596 /* supplicant still sends tdls_mgmt(SETUP_REQ) even after
13597 we return error code at 'add_station()'. Hence we have this
13598 check again in addtion to add_station().
13599 Anyway, there is no hard to double-check. */
Hoonki Lee11f7dda2013-02-14 16:55:44 -080013600 if (SIR_MAC_TDLS_SETUP_REQ == action_code)
Lee Hoonkic1262f22013-01-24 21:59:00 -080013601 {
Gopichand Nakkalac87400e2013-03-13 18:51:00 -070013602 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
13603 "%s: " MAC_ADDRESS_STR
Rajesh Chauhana34c6e62014-03-25 16:37:58 +053013604 " TDLS Max peer already connected. action (%d) declined. Num of peers (%d), Max allowed (%d).",
13605 __func__, MAC_ADDR_ARRAY(peer), action_code,
13606 numCurrTdlsPeers, HDD_MAX_NUM_TDLS_STA);
Sunil Dutt388ac8f2013-11-28 18:06:52 +053013607 return -EINVAL;
Lee Hoonkic1262f22013-01-24 21:59:00 -080013608 }
13609 else
13610 {
Gopichand Nakkalab977a972013-02-18 19:15:09 -080013611 /* maximum reached. tweak to send error code to peer and return
13612 error code to supplicant */
Lee Hoonkic1262f22013-01-24 21:59:00 -080013613 status_code = eSIR_MAC_UNSPEC_FAILURE_STATUS;
Gopichand Nakkalac87400e2013-03-13 18:51:00 -070013614 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
13615 "%s: " MAC_ADDRESS_STR
Rajesh Chauhana34c6e62014-03-25 16:37:58 +053013616 " TDLS Max peer already connected, send response status (%d). Num of peers (%d), Max allowed (%d).",
13617 __func__, MAC_ADDR_ARRAY(peer), status_code,
13618 numCurrTdlsPeers, HDD_MAX_NUM_TDLS_STA);
Gopichand Nakkala05922802013-03-14 12:23:19 -070013619 max_sta_failed = -EPERM;
Gopichand Nakkalab977a972013-02-18 19:15:09 -080013620 /* fall through to send setup resp with failure status
13621 code */
Lee Hoonkic1262f22013-01-24 21:59:00 -080013622 }
13623 }
Hoonki Lee11f7dda2013-02-14 16:55:44 -080013624 else
13625 {
13626 hddTdlsPeer_t *pTdlsPeer;
Madan Mohan Koyyalamudi96797442013-10-08 16:04:42 +053013627 pTdlsPeer = wlan_hdd_tdls_find_peer(pAdapter, peer, TRUE);
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -070013628 if (pTdlsPeer && TDLS_IS_CONNECTED(pTdlsPeer))
Hoonki Lee11f7dda2013-02-14 16:55:44 -080013629 {
Gopichand Nakkalac87400e2013-03-13 18:51:00 -070013630 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Gopichand Nakkala34d1b062013-03-19 15:28:33 -070013631 "%s:" MAC_ADDRESS_STR " already connected. action %d declined.",
13632 __func__, MAC_ADDR_ARRAY(peer), action_code);
Hoonki Lee11f7dda2013-02-14 16:55:44 -080013633 return -EPERM;
13634 }
13635 }
Lee Hoonkic1262f22013-01-24 21:59:00 -080013636 }
Hoonki Lee11f7dda2013-02-14 16:55:44 -080013637 vos_mem_copy(peerMac, peer, 6);
Mohit Khanna698ba2a2012-12-04 15:08:18 -080013638
Hoonki Lee1090c6a2013-01-16 17:40:54 -080013639#ifdef WLAN_FEATURE_TDLS_DEBUG
13640 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Arun Kumar Khandavalli9fb625e2014-03-17 16:07:40 +053013641 "%s: " MAC_ADDRESS_STR " action %d, dialog_token %d status %d, len = %zu",
Gopichand Nakkalac87400e2013-03-13 18:51:00 -070013642 "tdls_mgmt", MAC_ADDR_ARRAY(peer),
13643 action_code, dialog_token, status_code, len);
Hoonki Lee1090c6a2013-01-16 17:40:54 -080013644#endif
Mohit Khanna698ba2a2012-12-04 15:08:18 -080013645
Hoonki Leea34dd892013-02-05 22:56:02 -080013646 /*Except teardown responder will not be used so just make 0*/
13647 responder = 0;
Hoonki Lee11f7dda2013-02-14 16:55:44 -080013648 if (SIR_MAC_TDLS_TEARDOWN == action_code)
Hoonki Leea34dd892013-02-05 22:56:02 -080013649 {
Gopichand Nakkala97a65fd2013-04-16 16:59:38 -070013650
13651 hddTdlsPeer_t *pTdlsPeer;
Madan Mohan Koyyalamudi96797442013-10-08 16:04:42 +053013652 pTdlsPeer = wlan_hdd_tdls_find_peer(pAdapter, peerMac, TRUE);
Gopichand Nakkala97a65fd2013-04-16 16:59:38 -070013653
13654 if(pTdlsPeer && TDLS_IS_CONNECTED(pTdlsPeer))
13655 responder = pTdlsPeer->is_responder;
13656 else
Hoonki Leea34dd892013-02-05 22:56:02 -080013657 {
Gopichand Nakkala97a65fd2013-04-16 16:59:38 -070013658 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Arun Kumar Khandavalli9fb625e2014-03-17 16:07:40 +053013659 "%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 -070013660 __func__, MAC_ADDR_ARRAY(peer), (NULL == pTdlsPeer) ? -1 : pTdlsPeer->link_status,
13661 dialog_token, status_code, len);
13662 return -EPERM;
Hoonki Leea34dd892013-02-05 22:56:02 -080013663 }
Mohit Khanna698ba2a2012-12-04 15:08:18 -080013664 }
Mohit Khanna698ba2a2012-12-04 15:08:18 -080013665
Gopichand Nakkala2f1ff152013-07-01 11:27:43 +053013666 /* For explicit trigger of DIS_REQ come out of BMPS for
13667 successfully receiving DIS_RSP from peer. */
Hoonki Lee14621352013-04-16 17:51:19 -070013668 if ((SIR_MAC_TDLS_SETUP_RSP == action_code) ||
Gopichand Nakkala2f1ff152013-07-01 11:27:43 +053013669 (SIR_MAC_TDLS_DIS_RSP == action_code) ||
13670 (SIR_MAC_TDLS_DIS_REQ == action_code))
Hoonki Lee14621352013-04-16 17:51:19 -070013671 {
13672 if (TRUE == sme_IsPmcBmps(WLAN_HDD_GET_HAL_CTX(pAdapter)))
13673 {
13674 VOS_TRACE( VOS_MODULE_ID_HDD, TDLS_LOG_LEVEL,
Gopichand Nakkala2f1ff152013-07-01 11:27:43 +053013675 "%s: Sending frame action_code %u.Disable BMPS", __func__, action_code);
Hoonki Lee14621352013-04-16 17:51:19 -070013676 hdd_disable_bmps_imps(pHddCtx, WLAN_HDD_INFRA_STATION);
13677 }
Gopichand Nakkala2f1ff152013-07-01 11:27:43 +053013678 if (SIR_MAC_TDLS_DIS_REQ != action_code)
13679 wlan_hdd_tdls_set_cap(pAdapter, peerMac, eTDLS_CAP_SUPPORTED);
Hoonki Lee14621352013-04-16 17:51:19 -070013680 }
13681
Hoonki Lee5305c3a2013-04-29 23:28:59 -070013682 /* make sure doesn't call send_mgmt() while it is pending */
13683 if (TDLS_CTX_MAGIC == pAdapter->mgmtTxCompletionStatus)
13684 {
13685 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Arif Hussain6d2a3322013-11-17 19:50:10 -080013686 "%s: " MAC_ADDRESS_STR " action %d couldn't sent, as one is pending. return EBUSY",
Hoonki Lee5305c3a2013-04-29 23:28:59 -070013687 __func__, MAC_ADDR_ARRAY(peer), action_code);
13688 return -EBUSY;
13689 }
13690
13691 pAdapter->mgmtTxCompletionStatus = TDLS_CTX_MAGIC;
Gopichand Nakkalab977a972013-02-18 19:15:09 -080013692 INIT_COMPLETION(pAdapter->tdls_mgmt_comp);
13693
Mohit Khanna698ba2a2012-12-04 15:08:18 -080013694 status = sme_SendTdlsMgmtFrame(WLAN_HDD_GET_HAL_CTX(pAdapter), pAdapter->sessionId,
Pradeep Reddy POTTETIca171f82014-03-21 14:17:35 +053013695 peerMac, action_code, dialog_token, status_code, peer_capability, (tANI_U8 *)buf, len, responder);
Mohit Khanna698ba2a2012-12-04 15:08:18 -080013696
Gopichand Nakkalab977a972013-02-18 19:15:09 -080013697 if (VOS_STATUS_SUCCESS != status)
13698 {
Mohit Khanna698ba2a2012-12-04 15:08:18 -080013699 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
13700 "%s: sme_SendTdlsMgmtFrame failed!", __func__);
Hoonki Lee5305c3a2013-04-29 23:28:59 -070013701 pAdapter->mgmtTxCompletionStatus = FALSE;
Hoonki Lee14621352013-04-16 17:51:19 -070013702 wlan_hdd_tdls_check_bmps(pAdapter);
Sunil Dutt388ac8f2013-11-28 18:06:52 +053013703 return -EINVAL;
Mohit Khanna698ba2a2012-12-04 15:08:18 -080013704 }
13705
Hoonki Leed37cbb32013-04-20 00:31:14 -070013706 rc = wait_for_completion_interruptible_timeout(&pAdapter->tdls_mgmt_comp,
13707 msecs_to_jiffies(WAIT_TIME_TDLS_MGMT));
13708
13709 if ((rc <= 0) || (TRUE != pAdapter->mgmtTxCompletionStatus))
Gopichand Nakkalab977a972013-02-18 19:15:09 -080013710 {
Hoonki Leed37cbb32013-04-20 00:31:14 -070013711 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Jeff Johnson0299d0a2013-10-30 12:37:43 -070013712 "%s: Mgmt Tx Completion failed status %ld TxCompletion %u",
Hoonki Leed37cbb32013-04-20 00:31:14 -070013713 __func__, rc, pAdapter->mgmtTxCompletionStatus);
Hoonki Lee5305c3a2013-04-29 23:28:59 -070013714 pAdapter->mgmtTxCompletionStatus = FALSE;
Yue Ma4f55ef32014-01-23 16:45:33 -080013715
13716 if (pHddCtx->isLogpInProgress)
13717 {
13718 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
13719 "%s: LOGP in Progress. Ignore!!!", __func__);
13720 return -EAGAIN;
13721 }
13722
Hoonki Leed37cbb32013-04-20 00:31:14 -070013723 wlan_hdd_tdls_check_bmps(pAdapter);
Sunil Dutt388ac8f2013-11-28 18:06:52 +053013724 return -EINVAL;
Gopichand Nakkalab977a972013-02-18 19:15:09 -080013725 }
13726
Gopichand Nakkala05922802013-03-14 12:23:19 -070013727 if (max_sta_failed)
Hoonki Lee14621352013-04-16 17:51:19 -070013728 {
13729 wlan_hdd_tdls_check_bmps(pAdapter);
Gopichand Nakkala05922802013-03-14 12:23:19 -070013730 return max_sta_failed;
Hoonki Lee14621352013-04-16 17:51:19 -070013731 }
Gopichand Nakkalab977a972013-02-18 19:15:09 -080013732
Hoonki Leea34dd892013-02-05 22:56:02 -080013733 if (SIR_MAC_TDLS_SETUP_RSP == action_code)
13734 {
Gopichand Nakkala4327a152013-03-04 23:22:42 -080013735 wlan_hdd_tdls_set_responder(pAdapter, peerMac, TRUE);
Hoonki Leea34dd892013-02-05 22:56:02 -080013736 }
13737 else if (SIR_MAC_TDLS_SETUP_CNF == action_code)
13738 {
Gopichand Nakkala4327a152013-03-04 23:22:42 -080013739 wlan_hdd_tdls_set_responder(pAdapter, peerMac, FALSE);
Hoonki Leea34dd892013-02-05 22:56:02 -080013740 }
Mohit Khanna698ba2a2012-12-04 15:08:18 -080013741
13742 return 0;
13743}
13744
Atul Mittal115287b2014-07-08 13:26:33 +053013745
13746int wlan_hdd_tdls_extctrl_config_peer(hdd_adapter_t *pAdapter,
13747 u8 *peer,
13748 cfg80211_exttdls_callback callback)
13749{
13750
13751 hddTdlsPeer_t *pTdlsPeer;
13752 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
13753 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
13754 " %s : NL80211_TDLS_SETUP for " MAC_ADDRESS_STR,
13755 __func__, MAC_ADDR_ARRAY(peer));
13756
13757 if ( (FALSE == pHddCtx->cfg_ini->fTDLSExternalControl) ||
13758 (FALSE == pHddCtx->cfg_ini->fEnableTDLSImplicitTrigger) ) {
13759
13760 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
13761 " %s TDLS External control and Implicit Trigger not enabled ",
13762 __func__);
13763 return -ENOTSUPP;
13764 }
13765
13766 /* To cater the requirement of establishing the TDLS link
13767 * irrespective of the data traffic , get an entry of TDLS peer.
13768 */
13769 pTdlsPeer = wlan_hdd_tdls_get_peer(pAdapter, peer);
13770 if (pTdlsPeer == NULL) {
13771 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
13772 "%s: peer " MAC_ADDRESS_STR " not existing",
13773 __func__, MAC_ADDR_ARRAY(peer));
13774 return -EINVAL;
13775 }
13776
13777 if ( 0 != wlan_hdd_tdls_set_force_peer(pAdapter, peer, TRUE) ) {
13778
13779 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
13780 " %s TDLS Add Force Peer Failed",
13781 __func__);
13782 return -EINVAL;
13783 }
13784 /*EXT TDLS*/
13785
13786 if ( 0 != wlan_hdd_set_callback(pTdlsPeer, callback) ) {
13787 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
13788 " %s TDLS set callback Failed",
13789 __func__);
13790 return -EINVAL;
13791 }
13792
13793 return(0);
13794
13795}
13796
13797int wlan_hdd_tdls_extctrl_deconfig_peer(hdd_adapter_t *pAdapter, u8 *peer)
13798{
13799
13800 hddTdlsPeer_t *pTdlsPeer;
13801 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
13802 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
13803 " %s : NL80211_TDLS_TEARDOWN for " MAC_ADDRESS_STR,
13804 __func__, MAC_ADDR_ARRAY(peer));
13805
13806 if ( (FALSE == pHddCtx->cfg_ini->fTDLSExternalControl) ||
13807 (FALSE == pHddCtx->cfg_ini->fEnableTDLSImplicitTrigger) ) {
13808
13809 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
13810 " %s TDLS External control and Implicit Trigger not enabled ",
13811 __func__);
13812 return -ENOTSUPP;
13813 }
13814
13815
13816 pTdlsPeer = wlan_hdd_tdls_find_peer(pAdapter, peer, TRUE);
13817
13818 if ( NULL == pTdlsPeer ) {
13819 hddLog(VOS_TRACE_LEVEL_INFO, "%s: " MAC_ADDRESS_STR
13820 " peer not exsting",
13821 __func__, MAC_ADDR_ARRAY(peer));
13822 return -EINVAL;
13823 }
13824 else {
13825 wlan_hdd_tdls_indicate_teardown(pAdapter, pTdlsPeer,
13826 eSIR_MAC_TDLS_TEARDOWN_UNSPEC_REASON);
13827 }
13828
13829 if ( 0 != wlan_hdd_tdls_set_force_peer(pAdapter, peer, FALSE) )
13830 return -EINVAL;
13831
13832 /*EXT TDLS*/
13833
13834 if ( 0 != wlan_hdd_set_callback(pTdlsPeer, NULL )) {
13835
13836 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
13837 " %s TDLS set callback Failed",
13838 __func__);
13839 return -EINVAL;
13840 }
13841 return(0);
13842
13843}
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053013844static int __wlan_hdd_cfg80211_tdls_oper(struct wiphy *wiphy, struct net_device *dev,
Mohit Khanna698ba2a2012-12-04 15:08:18 -080013845 u8 *peer, enum nl80211_tdls_operation oper)
13846{
13847 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
13848 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053013849 int status;
Hoonki Lee5305c3a2013-04-29 23:28:59 -070013850 hddTdlsPeer_t *pTdlsPeer;
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053013851
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053013852 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
13853 TRACE_CODE_HDD_CFG80211_TDLS_OPER,
13854 pAdapter->sessionId, oper));
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053013855 if ( NULL == peer )
Mohit Khanna698ba2a2012-12-04 15:08:18 -080013856 {
Gopichand Nakkalab977a972013-02-18 19:15:09 -080013857 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Chilam Ngc4244af2013-04-01 15:37:32 -070013858 "%s: Invalid arguments", __func__);
Mohit Khanna698ba2a2012-12-04 15:08:18 -080013859 return -EINVAL;
13860 }
Hoonki Lee1090c6a2013-01-16 17:40:54 -080013861
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053013862 status = wlan_hdd_validate_context(pHddCtx);
13863
13864 if (0 != status)
Sameer Thalappil75ea31a2013-02-21 19:38:16 -080013865 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053013866 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
13867 "%s: HDD context is not valid", __func__);
13868 return status;
Sameer Thalappil75ea31a2013-02-21 19:38:16 -080013869 }
13870
Mohit Khanna698ba2a2012-12-04 15:08:18 -080013871
13872 if( FALSE == pHddCtx->cfg_ini->fEnableTDLSSupport ||
Hoonki Lee1090c6a2013-01-16 17:40:54 -080013873 FALSE == sme_IsFeatureSupportedByFW(TDLS))
Mohit Khanna698ba2a2012-12-04 15:08:18 -080013874 {
Hoonki Lee1090c6a2013-01-16 17:40:54 -080013875 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Chilam Ngc4244af2013-04-01 15:37:32 -070013876 "TDLS Disabled in INI OR not enabled in FW. "
13877 "Cannot process TDLS commands");
Mohit Khanna698ba2a2012-12-04 15:08:18 -080013878 return -ENOTSUPP;
13879 }
13880
13881 switch (oper) {
13882 case NL80211_TDLS_ENABLE_LINK:
13883 {
Mohit Khanna698ba2a2012-12-04 15:08:18 -080013884 VOS_STATUS status;
c_hpothu6ff1c3c2013-10-01 19:01:57 +053013885 long ret;
Gopichand Nakkala79ff85d2013-05-27 17:05:29 +053013886 tCsrTdlsLinkEstablishParams tdlsLinkEstablishParams;
Mohit Khanna698ba2a2012-12-04 15:08:18 -080013887
Sunil Dutt41de4e22013-11-14 18:09:02 +053013888 pTdlsPeer = wlan_hdd_tdls_find_peer(pAdapter, peer, TRUE);
13889
13890 if ( NULL == pTdlsPeer ) {
13891 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: " MAC_ADDRESS_STR
13892 " (oper %d) not exsting. ignored",
13893 __func__, MAC_ADDR_ARRAY(peer), (int)oper);
13894 return -EINVAL;
13895 }
13896
13897 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
13898 "%s: " MAC_ADDRESS_STR " link_status %d (%s) ", "tdls_oper",
13899 MAC_ADDR_ARRAY(peer), pTdlsPeer->link_status,
13900 "NL80211_TDLS_ENABLE_LINK");
13901
Gopichand Nakkala2f4a2822013-04-17 11:22:01 -070013902 if (!TDLS_STA_INDEX_VALID(pTdlsPeer->staId))
13903 {
13904 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Invalid Staion Index %u "
13905 MAC_ADDRESS_STR " failed",
13906 __func__, pTdlsPeer->staId, MAC_ADDR_ARRAY(peer));
13907 return -EINVAL;
13908 }
13909
Hoonki Lee5305c3a2013-04-29 23:28:59 -070013910 if (eTDLS_LINK_CONNECTED != pTdlsPeer->link_status)
Gopichand Nakkalac87400e2013-03-13 18:51:00 -070013911 {
Madan Mohan Koyyalamudice419872013-09-13 19:36:52 +053013912 if (IS_ADVANCE_TDLS_ENABLE) {
Gopichand Nakkala24be5312013-07-02 16:47:12 +053013913
Madan Mohan Koyyalamudice419872013-09-13 19:36:52 +053013914 if (0 != wlan_hdd_tdls_get_link_establish_params(
13915 pAdapter, peer,&tdlsLinkEstablishParams)) {
13916 return -EINVAL;
13917 }
13918 INIT_COMPLETION(pAdapter->tdls_link_establish_req_comp);
Gopichand Nakkala79ff85d2013-05-27 17:05:29 +053013919
Madan Mohan Koyyalamudice419872013-09-13 19:36:52 +053013920 sme_SendTdlsLinkEstablishParams(WLAN_HDD_GET_HAL_CTX(pAdapter),
13921 pAdapter->sessionId, peer, &tdlsLinkEstablishParams);
13922 /* Send TDLS peer UAPSD capabilities to the firmware and
13923 * register with the TL on after the response for this operation
13924 * is received .
13925 */
13926 ret = wait_for_completion_interruptible_timeout(
13927 &pAdapter->tdls_link_establish_req_comp,
13928 msecs_to_jiffies(WAIT_TIME_TDLS_LINK_ESTABLISH_REQ));
13929 if (ret <= 0)
13930 {
13931 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
13932 "%s: Link Establish Request Faled Status %ld",
13933 __func__, ret);
13934 return -EINVAL;
13935 }
Gopichand Nakkala79ff85d2013-05-27 17:05:29 +053013936 }
Atul Mittal115287b2014-07-08 13:26:33 +053013937 wlan_hdd_tdls_set_peer_link_status(pTdlsPeer,
13938 eTDLS_LINK_CONNECTED,
13939 eTDLS_LINK_SUCCESS);
Gopichand Nakkala471708b2013-06-04 20:03:01 +053013940 /* Mark TDLS client Authenticated .*/
13941 status = WLANTL_ChangeSTAState( pHddCtx->pvosContext,
13942 pTdlsPeer->staId,
13943 WLANTL_STA_AUTHENTICATED);
Gopichand Nakkalaccd3a382013-03-19 13:56:10 -070013944 if (VOS_STATUS_SUCCESS == status)
13945 {
Hoonki Lee14621352013-04-16 17:51:19 -070013946 if (pTdlsPeer->is_responder == 0)
13947 {
13948 v_U8_t staId = (v_U8_t)pTdlsPeer->staId;
13949
13950 wlan_hdd_tdls_timer_restart(pAdapter,
13951 &pTdlsPeer->initiatorWaitTimeoutTimer,
13952 WAIT_TIME_TDLS_INITIATOR);
13953 /* suspend initiator TX until it receives direct packet from the
13954 reponder or WAIT_TIME_TDLS_INITIATOR timer expires */
13955 WLANTL_SuspendDataTx( (WLAN_HDD_GET_CTX(pAdapter))->pvosContext,
13956 &staId, NULL);
13957 }
Gopichand Nakkalaccd3a382013-03-19 13:56:10 -070013958 wlan_hdd_tdls_increment_peer_count(pAdapter);
13959 }
Gopichand Nakkalac87400e2013-03-13 18:51:00 -070013960 wlan_hdd_tdls_check_bmps(pAdapter);
Gopichand Nakkala79ff85d2013-05-27 17:05:29 +053013961
13962 /* Update TL about the UAPSD masks , to route the packets to firmware */
Gopichand Nakkala574f6d12013-06-27 19:38:43 +053013963 if ((TRUE == pHddCtx->cfg_ini->fEnableTDLSBufferSta)
13964 || pHddCtx->cfg_ini->fTDLSUapsdMask )
Gopichand Nakkala79ff85d2013-05-27 17:05:29 +053013965 {
Gopichand Nakkala574f6d12013-06-27 19:38:43 +053013966 int ac;
13967 uint8 ucAc[4] = { WLANTL_AC_VO,
13968 WLANTL_AC_VI,
13969 WLANTL_AC_BK,
13970 WLANTL_AC_BE };
13971 uint8 tlTid[4] = { 7, 5, 2, 3 } ;
13972 for(ac=0; ac < 4; ac++)
13973 {
13974 status = WLANTL_EnableUAPSDForAC( (WLAN_HDD_GET_CTX(pAdapter))->pvosContext,
13975 pTdlsPeer->staId, ucAc[ac],
13976 tlTid[ac], tlTid[ac], 0, 0,
13977 WLANTL_BI_DIR );
13978 }
Gopichand Nakkala79ff85d2013-05-27 17:05:29 +053013979 }
Gopichand Nakkalac87400e2013-03-13 18:51:00 -070013980 }
13981
Mohit Khanna698ba2a2012-12-04 15:08:18 -080013982 }
13983 break;
13984 case NL80211_TDLS_DISABLE_LINK:
Lee Hoonkic1262f22013-01-24 21:59:00 -080013985 {
Sunil Dutt41de4e22013-11-14 18:09:02 +053013986 pTdlsPeer = wlan_hdd_tdls_find_peer(pAdapter, peer, TRUE);
13987
13988 if ( NULL == pTdlsPeer ) {
13989 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: " MAC_ADDRESS_STR
13990 " (oper %d) not exsting. ignored",
13991 __func__, MAC_ADDR_ARRAY(peer), (int)oper);
13992 return -EINVAL;
13993 }
13994
13995 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
13996 "%s: " MAC_ADDRESS_STR " link_status %d (%s) ", "tdls_oper",
13997 MAC_ADDR_ARRAY(peer), pTdlsPeer->link_status,
13998 "NL80211_TDLS_DISABLE_LINK");
13999
Hoonki Lee5305c3a2013-04-29 23:28:59 -070014000 if(TDLS_STA_INDEX_VALID(pTdlsPeer->staId))
Lee Hoonkic1262f22013-01-24 21:59:00 -080014001 {
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -070014002 long status;
14003
Atul Mittal271a7652014-09-12 13:18:22 +053014004
14005 wlan_hdd_tdls_set_peer_link_status(pTdlsPeer,
14006 eTDLS_LINK_TEARING,
14007 (pTdlsPeer->link_status == eTDLS_LINK_TEARING)?
14008 eTDLS_LINK_UNSPECIFIED:
14009 eTDLS_LINK_DROPPED_BY_REMOTE);
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -070014010 INIT_COMPLETION(pAdapter->tdls_del_station_comp);
14011
Lee Hoonkic1262f22013-01-24 21:59:00 -080014012 sme_DeleteTdlsPeerSta( WLAN_HDD_GET_HAL_CTX(pAdapter),
14013 pAdapter->sessionId, peer );
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -070014014
14015 status = wait_for_completion_interruptible_timeout(&pAdapter->tdls_del_station_comp,
14016 msecs_to_jiffies(WAIT_TIME_TDLS_DEL_STA));
Atul Mittal271a7652014-09-12 13:18:22 +053014017 wlan_hdd_tdls_set_peer_link_status(pTdlsPeer,
Atul Mittal454664b2014-10-10 11:03:46 +053014018 eTDLS_LINK_IDLE,
14019 eTDLS_LINK_UNSPECIFIED);
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -070014020 if (status <= 0)
14021 {
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -070014022 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
14023 "%s: Del station failed status %ld",
14024 __func__, status);
14025 return -EPERM;
14026 }
Lee Hoonkic1262f22013-01-24 21:59:00 -080014027 }
14028 else
14029 {
Gopichand Nakkalac87400e2013-03-13 18:51:00 -070014030 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
14031 "%s: TDLS Peer Station doesn't exist.", __func__);
Lee Hoonkic1262f22013-01-24 21:59:00 -080014032 }
Lee Hoonkic1262f22013-01-24 21:59:00 -080014033 }
Gopichand Nakkalac87400e2013-03-13 18:51:00 -070014034 break;
Mohit Khanna698ba2a2012-12-04 15:08:18 -080014035 case NL80211_TDLS_TEARDOWN:
Sunil Dutt41de4e22013-11-14 18:09:02 +053014036 {
Atul Mittal115287b2014-07-08 13:26:33 +053014037 status = wlan_hdd_tdls_extctrl_deconfig_peer(pAdapter, peer);
Sunil Dutt41de4e22013-11-14 18:09:02 +053014038
Atul Mittal115287b2014-07-08 13:26:33 +053014039 if (0 != status)
14040 {
14041 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
14042 "%s: Error in TDLS Teardown", __func__);
14043 return status;
Sunil Dutt41de4e22013-11-14 18:09:02 +053014044 }
Sunil Dutt41de4e22013-11-14 18:09:02 +053014045 break;
14046 }
Mohit Khanna698ba2a2012-12-04 15:08:18 -080014047 case NL80211_TDLS_SETUP:
Sunil Dutt41de4e22013-11-14 18:09:02 +053014048 {
Atul Mittal115287b2014-07-08 13:26:33 +053014049 status = wlan_hdd_tdls_extctrl_config_peer(pAdapter,
14050 peer,
14051 NULL);
Sunil Dutt41de4e22013-11-14 18:09:02 +053014052
Atul Mittal115287b2014-07-08 13:26:33 +053014053 if (0 != status)
14054 {
14055 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
14056 "%s: Error in TDLS Setup", __func__);
14057 return status;
Naresh Jayaram937abdf2013-11-26 19:50:25 +053014058 }
Naresh Jayaramdb4514b2013-11-25 18:08:10 +053014059 break;
Sunil Dutt41de4e22013-11-14 18:09:02 +053014060 }
Mohit Khanna698ba2a2012-12-04 15:08:18 -080014061 case NL80211_TDLS_DISCOVERY_REQ:
14062 /* We don't support in-driver setup/teardown/discovery */
c_hpothu6ff1c3c2013-10-01 19:01:57 +053014063 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_WARN,
14064 "%s: We don't support in-driver setup/teardown/discovery "
14065 ,__func__);
Mohit Khanna698ba2a2012-12-04 15:08:18 -080014066 return -ENOTSUPP;
14067 default:
c_hpothu6ff1c3c2013-10-01 19:01:57 +053014068 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
14069 "%s: unsupported event",__func__);
Mohit Khanna698ba2a2012-12-04 15:08:18 -080014070 return -ENOTSUPP;
14071 }
14072 return 0;
14073}
Chilam NG571c65a2013-01-19 12:27:36 +053014074
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053014075static int wlan_hdd_cfg80211_tdls_oper(struct wiphy *wiphy, struct net_device *dev,
14076 u8 *peer, enum nl80211_tdls_operation oper)
14077{
14078 int ret;
14079
14080 vos_ssr_protect(__func__);
14081 ret = __wlan_hdd_cfg80211_tdls_oper(wiphy, dev, peer, oper);
14082 vos_ssr_unprotect(__func__);
14083
14084 return ret;
14085}
14086
Chilam NG571c65a2013-01-19 12:27:36 +053014087int wlan_hdd_cfg80211_send_tdls_discover_req(struct wiphy *wiphy,
14088 struct net_device *dev, u8 *peer)
14089{
Arif Hussaina7c8e412013-11-20 11:06:42 -080014090 hddLog(VOS_TRACE_LEVEL_INFO,
14091 "tdls send discover req: "MAC_ADDRESS_STR,
14092 MAC_ADDR_ARRAY(peer));
Chilam NG571c65a2013-01-19 12:27:36 +053014093
Sunil Dutt Undekarieacac6f2014-03-21 14:08:53 +053014094#if TDLS_MGMT_VERSION2
14095 return wlan_hdd_cfg80211_tdls_mgmt(wiphy, dev, peer,
14096 WLAN_TDLS_DISCOVERY_REQUEST, 1, 0, 0, NULL, 0);
14097#else
Chilam NG571c65a2013-01-19 12:27:36 +053014098 return wlan_hdd_cfg80211_tdls_mgmt(wiphy, dev, peer,
14099 WLAN_TDLS_DISCOVERY_REQUEST, 1, 0, NULL, 0);
Sunil Dutt Undekarieacac6f2014-03-21 14:08:53 +053014100#endif
Chilam NG571c65a2013-01-19 12:27:36 +053014101}
Mohit Khanna698ba2a2012-12-04 15:08:18 -080014102#endif
14103
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053014104#ifdef WLAN_FEATURE_GTK_OFFLOAD
14105/*
14106 * FUNCTION: wlan_hdd_cfg80211_update_replayCounterCallback
14107 * Callback rountine called upon receiving response for
14108 * get offload info
14109 */
14110void wlan_hdd_cfg80211_update_replayCounterCallback(void *callbackContext,
14111 tpSirGtkOffloadGetInfoRspParams pGtkOffloadGetInfoRsp)
14112{
14113
14114 hdd_adapter_t *pAdapter = (hdd_adapter_t *)callbackContext;
Gopichand Nakkalad36ee622013-05-07 14:13:27 +053014115 tANI_U8 tempReplayCounter[8];
14116 hdd_station_ctx_t *pHddStaCtx;
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053014117
14118 ENTER();
14119
14120 if (NULL == pAdapter)
14121 {
Agarwal Ashish971c2882013-10-30 20:11:12 +053014122 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053014123 "%s: HDD adapter is Null", __func__);
14124 return ;
14125 }
14126
14127 if (NULL == pGtkOffloadGetInfoRsp)
14128 {
14129 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
14130 "%s: pGtkOffloadGetInfoRsp is Null", __func__);
14131 return ;
14132 }
14133
14134 if (VOS_STATUS_SUCCESS != pGtkOffloadGetInfoRsp->ulStatus)
14135 {
14136 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
14137 "%s: wlan Failed to get replay counter value",
14138 __func__);
14139 return ;
14140 }
14141
Gopichand Nakkalad36ee622013-05-07 14:13:27 +053014142 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
14143 /* Update replay counter */
14144 pHddStaCtx->gtkOffloadReqParams.ullKeyReplayCounter =
14145 pGtkOffloadGetInfoRsp->ullKeyReplayCounter;
14146
14147 {
14148 /* changing from little to big endian since supplicant
14149 * works on big endian format
14150 */
14151 int i;
14152 tANI_U8 *p = (tANI_U8 *)&pGtkOffloadGetInfoRsp->ullKeyReplayCounter;
14153
14154 for (i = 0; i < 8; i++)
14155 {
14156 tempReplayCounter[7-i] = (tANI_U8)p[i];
14157 }
14158 }
14159
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053014160 /* Update replay counter to NL */
14161 cfg80211_gtk_rekey_notify(pAdapter->dev, pGtkOffloadGetInfoRsp->bssId,
Gopichand Nakkalad36ee622013-05-07 14:13:27 +053014162 tempReplayCounter, GFP_KERNEL);
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053014163}
14164
14165/*
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053014166 * FUNCTION: __wlan_hdd_cfg80211_set_rekey_data
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053014167 * This function is used to offload GTK rekeying job to the firmware.
14168 */
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053014169int __wlan_hdd_cfg80211_set_rekey_data(struct wiphy *wiphy, struct net_device *dev,
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053014170 struct cfg80211_gtk_rekey_data *data)
14171{
14172 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
14173 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
14174 hdd_station_ctx_t *pHddStaCtx;
14175 tHalHandle hHal;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053014176 int result;
Gopichand Nakkalad36ee622013-05-07 14:13:27 +053014177 tSirGtkOffloadParams hddGtkOffloadReqParams;
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053014178 eHalStatus status = eHAL_STATUS_FAILURE;
14179
14180 ENTER();
14181
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053014182
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053014183 if (NULL == pAdapter)
14184 {
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053014185 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053014186 "%s: HDD adapter is Null", __func__);
14187 return -ENODEV;
14188 }
14189
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053014190 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
14191 TRACE_CODE_HDD_CFG80211_SET_REKEY_DATA,
14192 pAdapter->sessionId, pAdapter->device_mode));
14193
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053014194 result = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053014195
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053014196 if (0 != result)
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053014197 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053014198 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
14199 "%s: HDD context is not valid", __func__);
14200 return result;
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053014201 }
14202
14203 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
14204 hHal = WLAN_HDD_GET_HAL_CTX(pAdapter);
14205 if (NULL == hHal)
14206 {
14207 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
14208 "%s: HAL context is Null!!!", __func__);
14209 return -EAGAIN;
14210 }
14211
Gopichand Nakkalad36ee622013-05-07 14:13:27 +053014212 pHddStaCtx->gtkOffloadReqParams.ulFlags = GTK_OFFLOAD_ENABLE;
14213 memcpy(pHddStaCtx->gtkOffloadReqParams.aKCK, data->kck, NL80211_KCK_LEN);
14214 memcpy(pHddStaCtx->gtkOffloadReqParams.aKEK, data->kek, NL80211_KEK_LEN);
14215 memcpy(pHddStaCtx->gtkOffloadReqParams.bssId, &pHddStaCtx->conn_info.bssId,
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053014216 WNI_CFG_BSSID_LEN);
Gopichand Nakkalad36ee622013-05-07 14:13:27 +053014217 {
14218 /* changing from big to little endian since driver
14219 * works on little endian format
14220 */
14221 tANI_U8 *p =
14222 (tANI_U8 *)&pHddStaCtx->gtkOffloadReqParams.ullKeyReplayCounter;
14223 int i;
14224
14225 for (i = 0; i < 8; i++)
14226 {
14227 p[7-i] = data->replay_ctr[i];
14228 }
14229 }
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053014230
14231 if (TRUE == pHddCtx->hdd_wlan_suspended)
14232 {
14233 /* if wlan is suspended, enable GTK offload directly from here */
Gopichand Nakkalad36ee622013-05-07 14:13:27 +053014234 memcpy(&hddGtkOffloadReqParams, &pHddStaCtx->gtkOffloadReqParams,
14235 sizeof (tSirGtkOffloadParams));
14236 status = sme_SetGTKOffload(hHal, &hddGtkOffloadReqParams,
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053014237 pAdapter->sessionId);
14238
14239 if (eHAL_STATUS_SUCCESS != status)
14240 {
14241 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
14242 "%s: sme_SetGTKOffload failed, returned %d",
14243 __func__, status);
Vinay Krishna Eranna6f22c1f2014-10-13 16:03:06 +053014244
14245 /* Need to clear any trace of key value in the memory.
14246 * Thus zero out the memory even though it is local
14247 * variable.
14248 */
14249 vos_mem_zero(&hddGtkOffloadReqParams,
14250 sizeof(hddGtkOffloadReqParams));
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053014251 return status;
14252 }
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053014253 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
14254 "%s: sme_SetGTKOffload successfull", __func__);
14255 }
14256 else
14257 {
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053014258 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
14259 "%s: wlan not suspended GTKOffload request is stored",
14260 __func__);
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053014261 }
Gopichand Nakkalad36ee622013-05-07 14:13:27 +053014262
Vinay Krishna Eranna6f22c1f2014-10-13 16:03:06 +053014263 /* Need to clear any trace of key value in the memory.
14264 * Thus zero out the memory even though it is local
14265 * variable.
14266 */
14267 vos_mem_zero(&hddGtkOffloadReqParams,
14268 sizeof(hddGtkOffloadReqParams));
14269
Gopichand Nakkalad36ee622013-05-07 14:13:27 +053014270 return eHAL_STATUS_SUCCESS;
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053014271}
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053014272
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053014273int wlan_hdd_cfg80211_set_rekey_data(struct wiphy *wiphy, struct net_device *dev,
14274 struct cfg80211_gtk_rekey_data *data)
14275{
14276 int ret;
14277
14278 vos_ssr_protect(__func__);
14279 ret = __wlan_hdd_cfg80211_set_rekey_data(wiphy, dev, data);
14280 vos_ssr_unprotect(__func__);
14281
14282 return ret;
14283}
14284#endif /*WLAN_FEATURE_GTK_OFFLOAD*/
Gopichand Nakkalac005b7c2013-05-14 16:04:14 +053014285/*
14286 * FUNCTION: wlan_hdd_cfg80211_set_mac_acl
14287 * This function is used to set access control policy
14288 */
14289static int wlan_hdd_cfg80211_set_mac_acl(struct wiphy *wiphy,
14290 struct net_device *dev, const struct cfg80211_acl_data *params)
14291{
14292 int i;
14293 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
14294 hdd_hostapd_state_t *pHostapdState;
14295 tsap_Config_t *pConfig;
14296 v_CONTEXT_t pVosContext = NULL;
14297 hdd_context_t *pHddCtx;
14298 int status;
14299
14300 ENTER();
14301
14302 if (NULL == pAdapter)
14303 {
14304 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
14305 "%s: HDD adapter is Null", __func__);
14306 return -ENODEV;
14307 }
14308
14309 if (NULL == params)
14310 {
14311 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
14312 "%s: params is Null", __func__);
14313 return -EINVAL;
14314 }
14315
14316 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
14317 status = wlan_hdd_validate_context(pHddCtx);
14318
14319 if (0 != status)
14320 {
14321 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
14322 "%s: HDD context is not valid", __func__);
14323 return status;
14324 }
14325
14326 pVosContext = pHddCtx->pvosContext;
14327 pHostapdState = WLAN_HDD_GET_HOSTAP_STATE_PTR(pAdapter);
14328
14329 if (NULL == pHostapdState)
14330 {
14331 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
14332 "%s: pHostapdState is Null", __func__);
14333 return -EINVAL;
14334 }
14335
14336 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,"acl policy: = %d"
14337 "no acl entries = %d", params->acl_policy, params->n_acl_entries);
14338
14339 if (WLAN_HDD_SOFTAP == pAdapter->device_mode)
14340 {
14341 pConfig = &pAdapter->sessionCtx.ap.sapConfig;
14342
14343 /* default value */
14344 pConfig->num_accept_mac = 0;
14345 pConfig->num_deny_mac = 0;
14346
14347 /**
14348 * access control policy
14349 * @NL80211_ACL_POLICY_ACCEPT_UNLESS_LISTED: Deny stations which are
14350 * listed in hostapd.deny file.
14351 * @NL80211_ACL_POLICY_DENY_UNLESS_LISTED: Allow stations which are
14352 * listed in hostapd.accept file.
14353 */
14354 if (NL80211_ACL_POLICY_DENY_UNLESS_LISTED == params->acl_policy)
14355 {
14356 pConfig->SapMacaddr_acl = eSAP_DENY_UNLESS_ACCEPTED;
14357 }
14358 else if (NL80211_ACL_POLICY_ACCEPT_UNLESS_LISTED == params->acl_policy)
14359 {
14360 pConfig->SapMacaddr_acl = eSAP_ACCEPT_UNLESS_DENIED;
14361 }
14362 else
14363 {
14364 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
14365 "%s:Acl Policy : %d is not supported",
14366 __func__, params->acl_policy);
14367 return -ENOTSUPP;
14368 }
14369
14370 if (eSAP_DENY_UNLESS_ACCEPTED == pConfig->SapMacaddr_acl)
14371 {
14372 pConfig->num_accept_mac = params->n_acl_entries;
14373 for (i = 0; i < params->n_acl_entries; i++)
14374 {
14375 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
14376 "** Add ACL MAC entry %i in WhiletList :"
14377 MAC_ADDRESS_STR, i,
14378 MAC_ADDR_ARRAY(params->mac_addrs[i].addr));
14379
14380 vos_mem_copy(&pConfig->accept_mac[i], params->mac_addrs[i].addr,
14381 sizeof(qcmacaddr));
14382 }
14383 }
14384 else if (eSAP_ACCEPT_UNLESS_DENIED == pConfig->SapMacaddr_acl)
14385 {
14386 pConfig->num_deny_mac = params->n_acl_entries;
14387 for (i = 0; i < params->n_acl_entries; i++)
14388 {
14389 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
14390 "** Add ACL MAC entry %i in BlackList :"
14391 MAC_ADDRESS_STR, i,
14392 MAC_ADDR_ARRAY(params->mac_addrs[i].addr));
14393
14394 vos_mem_copy(&pConfig->deny_mac[i], params->mac_addrs[i].addr,
14395 sizeof(qcmacaddr));
14396 }
14397 }
14398
14399 if (VOS_STATUS_SUCCESS != WLANSAP_SetMacACL(pVosContext, pConfig))
14400 {
14401 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
14402 "%s: SAP Set Mac Acl fail", __func__);
14403 return -EINVAL;
14404 }
14405 }
14406 else
14407 {
14408 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Sushant Kaushik8bc7df22014-04-09 17:55:29 +053014409 "%s: Invalid device_mode = %s (%d)",
14410 __func__, hdd_device_modetoString(pAdapter->device_mode),
14411 pAdapter->device_mode);
Gopichand Nakkalac005b7c2013-05-14 16:04:14 +053014412 return -EINVAL;
14413 }
14414
14415 return 0;
14416}
14417
Leo Chang9056f462013-08-01 19:21:11 -070014418#ifdef WLAN_NL80211_TESTMODE
14419#ifdef FEATURE_WLAN_LPHB
Leo Changd9df8aa2013-09-26 13:32:26 -070014420void wlan_hdd_cfg80211_lphb_ind_handler
Leo Chang9056f462013-08-01 19:21:11 -070014421(
14422 void *pAdapter,
14423 void *indCont
14424)
14425{
Leo Changd9df8aa2013-09-26 13:32:26 -070014426 tSirLPHBInd *lphbInd;
14427 struct sk_buff *skb;
c_hpothu73f35e62014-04-18 13:40:08 +053014428 hdd_context_t *pHddCtxt;
Leo Chang9056f462013-08-01 19:21:11 -070014429
14430 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Leo Changd9df8aa2013-09-26 13:32:26 -070014431 "LPHB indication arrived");
Leo Chang9056f462013-08-01 19:21:11 -070014432
c_hpothu73f35e62014-04-18 13:40:08 +053014433 if (pAdapter == NULL)
14434 {
14435 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
14436 "%s: pAdapter is NULL\n",__func__);
14437 return;
14438 }
14439
Leo Chang9056f462013-08-01 19:21:11 -070014440 if (NULL == indCont)
14441 {
14442 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Leo Changd9df8aa2013-09-26 13:32:26 -070014443 "LPHB IND, invalid argument");
Leo Chang9056f462013-08-01 19:21:11 -070014444 return;
14445 }
14446
c_hpothu73f35e62014-04-18 13:40:08 +053014447 pHddCtxt = (hdd_context_t *)pAdapter;
Leo Changd9df8aa2013-09-26 13:32:26 -070014448 lphbInd = (tSirLPHBInd *)indCont;
Leo Chang9056f462013-08-01 19:21:11 -070014449 skb = cfg80211_testmode_alloc_event_skb(
c_hpothu73f35e62014-04-18 13:40:08 +053014450 pHddCtxt->wiphy,
Leo Changd9df8aa2013-09-26 13:32:26 -070014451 sizeof(tSirLPHBInd),
Leo Chang9056f462013-08-01 19:21:11 -070014452 GFP_ATOMIC);
14453 if (!skb)
14454 {
14455 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
14456 "LPHB timeout, NL buffer alloc fail");
14457 return;
14458 }
14459
Leo Changac3ba772013-10-07 09:47:04 -070014460 if(nla_put_u32(skb, WLAN_HDD_TM_ATTR_CMD, WLAN_HDD_TM_CMD_WLAN_HB))
Leo Changd9df8aa2013-09-26 13:32:26 -070014461 {
14462 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
14463 "WLAN_HDD_TM_ATTR_CMD put fail");
14464 goto nla_put_failure;
14465 }
Leo Changac3ba772013-10-07 09:47:04 -070014466 if(nla_put_u32(skb, WLAN_HDD_TM_ATTR_TYPE, lphbInd->protocolType))
Leo Changd9df8aa2013-09-26 13:32:26 -070014467 {
14468 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
14469 "WLAN_HDD_TM_ATTR_TYPE put fail");
14470 goto nla_put_failure;
14471 }
Leo Changac3ba772013-10-07 09:47:04 -070014472 if(nla_put(skb, WLAN_HDD_TM_ATTR_DATA,
Leo Changd9df8aa2013-09-26 13:32:26 -070014473 sizeof(tSirLPHBInd), lphbInd))
14474 {
14475 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
14476 "WLAN_HDD_TM_ATTR_DATA put fail");
14477 goto nla_put_failure;
14478 }
Leo Chang9056f462013-08-01 19:21:11 -070014479 cfg80211_testmode_event(skb, GFP_ATOMIC);
14480 return;
14481
14482nla_put_failure:
14483 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
14484 "NLA Put fail");
14485 kfree_skb(skb);
14486
14487 return;
14488}
14489#endif /* FEATURE_WLAN_LPHB */
14490
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053014491static int __wlan_hdd_cfg80211_testmode(struct wiphy *wiphy, void *data, int len)
Leo Chang9056f462013-08-01 19:21:11 -070014492{
14493 struct nlattr *tb[WLAN_HDD_TM_ATTR_MAX + 1];
14494 int err = 0;
14495#ifdef FEATURE_WLAN_LPHB
14496 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
Leo Changd9df8aa2013-09-26 13:32:26 -070014497 eHalStatus smeStatus;
Leo Chang9056f462013-08-01 19:21:11 -070014498#endif /* FEATURE_WLAN_LPHB */
14499
14500 err = nla_parse(tb, WLAN_HDD_TM_ATTR_MAX, data, len, wlan_hdd_tm_policy);
14501 if (err)
14502 {
14503 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
14504 "%s Testmode INV ATTR", __func__);
14505 return err;
14506 }
14507
14508 if (!tb[WLAN_HDD_TM_ATTR_CMD])
14509 {
14510 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
14511 "%s Testmode INV CMD", __func__);
14512 return -EINVAL;
14513 }
14514
14515 switch (nla_get_u32(tb[WLAN_HDD_TM_ATTR_CMD]))
14516 {
14517#ifdef FEATURE_WLAN_LPHB
14518 /* Low Power Heartbeat configuration request */
14519 case WLAN_HDD_TM_CMD_WLAN_HB:
14520 {
14521 int buf_len;
14522 void *buf;
14523 tSirLPHBReq *hb_params = NULL;
Amar Singhal05852702014-02-04 14:40:00 -080014524 tSirLPHBReq *hb_params_temp = NULL;
Leo Chang9056f462013-08-01 19:21:11 -070014525
14526 if (!tb[WLAN_HDD_TM_ATTR_DATA])
14527 {
14528 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
14529 "%s Testmode INV DATA", __func__);
14530 return -EINVAL;
14531 }
14532
14533 buf = nla_data(tb[WLAN_HDD_TM_ATTR_DATA]);
14534 buf_len = nla_len(tb[WLAN_HDD_TM_ATTR_DATA]);
Amar Singhal05852702014-02-04 14:40:00 -080014535
14536 hb_params_temp =(tSirLPHBReq *)buf;
14537 if ((hb_params_temp->cmd == LPHB_SET_TCP_PARAMS_INDID) &&
14538 (hb_params_temp->params.lphbTcpParamReq.timePeriodSec == 0))
14539 return -EINVAL;
14540
Leo Chang9056f462013-08-01 19:21:11 -070014541 hb_params = (tSirLPHBReq *)vos_mem_malloc(sizeof(tSirLPHBReq));
14542 if (NULL == hb_params)
14543 {
14544 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
14545 "%s Request Buffer Alloc Fail", __func__);
14546 return -EINVAL;
14547 }
14548
14549 vos_mem_copy(hb_params, buf, buf_len);
Leo Changd9df8aa2013-09-26 13:32:26 -070014550 smeStatus = sme_LPHBConfigReq((tHalHandle)(pHddCtx->hHal),
14551 hb_params,
14552 wlan_hdd_cfg80211_lphb_ind_handler);
14553 if (eHAL_STATUS_SUCCESS != smeStatus)
Leo Chang9056f462013-08-01 19:21:11 -070014554 {
Leo Changd9df8aa2013-09-26 13:32:26 -070014555 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
14556 "LPHB Config Fail, disable");
Leo Chang9056f462013-08-01 19:21:11 -070014557 vos_mem_free(hb_params);
14558 }
Leo Chang9056f462013-08-01 19:21:11 -070014559 return 0;
14560 }
14561#endif /* FEATURE_WLAN_LPHB */
14562 default:
c_hpothu6ff1c3c2013-10-01 19:01:57 +053014563 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
14564 "%s: unsupported event",__func__);
Leo Chang9056f462013-08-01 19:21:11 -070014565 return -EOPNOTSUPP;
14566 }
14567
14568 return err;
14569}
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053014570
14571static int wlan_hdd_cfg80211_testmode(struct wiphy *wiphy, void *data, int len)
14572{
14573 int ret;
14574
14575 vos_ssr_protect(__func__);
14576 ret = __wlan_hdd_cfg80211_testmode(wiphy, data, len);
14577 vos_ssr_unprotect(__func__);
14578
14579 return ret;
14580}
Leo Chang9056f462013-08-01 19:21:11 -070014581#endif /* CONFIG_NL80211_TESTMODE */
14582
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053014583static int __wlan_hdd_cfg80211_dump_survey(struct wiphy *wiphy,
Madan Mohan Koyyalamudid9383fd2013-08-13 09:27:30 +053014584 struct net_device *dev,
14585 int idx, struct survey_info *survey)
14586{
14587 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
14588 hdd_context_t *pHddCtx;
Mihir Sheted9072e02013-08-21 17:02:29 +053014589 hdd_station_ctx_t *pHddStaCtx;
Madan Mohan Koyyalamudid9383fd2013-08-13 09:27:30 +053014590 tHalHandle halHandle;
Mihir Sheted9072e02013-08-21 17:02:29 +053014591 v_U32_t channel = 0, freq = 0; /* Initialization Required */
Madan Mohan Koyyalamudid9383fd2013-08-13 09:27:30 +053014592 v_S7_t snr,rssi;
14593 int status, i, j, filled = 0;
14594
14595 ENTER();
14596
Madan Mohan Koyyalamudid9383fd2013-08-13 09:27:30 +053014597 if (NULL == pAdapter)
14598 {
14599 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
14600 "%s: HDD adapter is Null", __func__);
14601 return -ENODEV;
14602 }
14603
14604 if (NULL == wiphy)
14605 {
14606 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
14607 "%s: wiphy is Null", __func__);
14608 return -ENODEV;
14609 }
14610
14611 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
14612 status = wlan_hdd_validate_context(pHddCtx);
14613
14614 if (0 != status)
14615 {
14616 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
14617 "%s: HDD context is not valid", __func__);
14618 return status;
14619 }
14620
Mihir Sheted9072e02013-08-21 17:02:29 +053014621 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
14622
Madan Mohan Koyyalamudid9383fd2013-08-13 09:27:30 +053014623 if (0 == pHddCtx->cfg_ini->fEnableSNRMonitoring ||
Mihir Sheted9072e02013-08-21 17:02:29 +053014624 0 != pAdapter->survey_idx ||
14625 eConnectionState_Associated != pHddStaCtx->conn_info.connState)
Madan Mohan Koyyalamudid9383fd2013-08-13 09:27:30 +053014626 {
14627 /* The survey dump ops when implemented completely is expected to
14628 * return a survey of all channels and the ops is called by the
14629 * kernel with incremental values of the argument 'idx' till it
14630 * returns -ENONET. But we can only support the survey for the
14631 * operating channel for now. survey_idx is used to track
14632 * that the ops is called only once and then return -ENONET for
14633 * the next iteration
14634 */
14635 pAdapter->survey_idx = 0;
14636 return -ENONET;
14637 }
14638
14639 halHandle = WLAN_HDD_GET_HAL_CTX(pAdapter);
14640
14641 wlan_hdd_get_snr(pAdapter, &snr);
14642 wlan_hdd_get_rssi(pAdapter, &rssi);
14643
14644 sme_GetOperationChannel(halHandle, &channel, pAdapter->sessionId);
14645 hdd_wlan_get_freq(channel, &freq);
14646
14647
14648 for (i = 0; i < IEEE80211_NUM_BANDS; i++)
14649 {
14650 if (NULL == wiphy->bands[i])
14651 {
14652 VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_INFO,
14653 "%s: wiphy->bands[i] is NULL, i = %d", __func__, i);
14654 continue;
14655 }
14656
14657 for (j = 0; j < wiphy->bands[i]->n_channels; j++)
14658 {
14659 struct ieee80211_supported_band *band = wiphy->bands[i];
14660
14661 if (band->channels[j].center_freq == (v_U16_t)freq)
14662 {
14663 survey->channel = &band->channels[j];
14664 /* The Rx BDs contain SNR values in dB for the received frames
14665 * while the supplicant expects noise. So we calculate and
14666 * return the value of noise (dBm)
14667 * SNR (dB) = RSSI (dBm) - NOISE (dBm)
14668 */
14669 survey->noise = rssi - snr;
14670 survey->filled = SURVEY_INFO_NOISE_DBM;
14671 filled = 1;
14672 }
14673 }
14674 }
14675
14676 if (filled)
14677 pAdapter->survey_idx = 1;
14678 else
14679 {
14680 pAdapter->survey_idx = 0;
14681 return -ENONET;
14682 }
14683
14684 return 0;
14685}
14686
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053014687static int wlan_hdd_cfg80211_dump_survey(struct wiphy *wiphy,
14688 struct net_device *dev,
14689 int idx, struct survey_info *survey)
14690{
14691 int ret;
14692
14693 vos_ssr_protect(__func__);
14694 ret = __wlan_hdd_cfg80211_dump_survey(wiphy, dev, idx, survey);
14695 vos_ssr_unprotect(__func__);
14696
14697 return ret;
14698}
14699
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053014700/*
Mahesh A Saptasagarbcc5b662014-06-02 21:46:23 +053014701 * FUNCTION: __wlan_hdd_cfg80211_resume_wlan
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053014702 * this is called when cfg80211 driver resume
14703 * driver updates latest sched_scan scan result(if any) to cfg80211 database
14704 */
Mahesh A Saptasagarbcc5b662014-06-02 21:46:23 +053014705int __wlan_hdd_cfg80211_resume_wlan(struct wiphy *wiphy)
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053014706{
14707 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
14708 hdd_adapter_t *pAdapter;
14709 hdd_adapter_list_node_t *pAdapterNode, *pNext;
14710 VOS_STATUS status = VOS_STATUS_SUCCESS;
14711
14712 ENTER();
14713
14714 if ( NULL == pHddCtx )
14715 {
14716 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
14717 "%s: HddCtx validation failed", __func__);
14718 return 0;
14719 }
14720
14721 if (pHddCtx->isLogpInProgress)
14722 {
14723 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
14724 "%s: LOGP in Progress. Ignore!!!", __func__);
14725 return 0;
14726 }
14727
Mihir Shete18156292014-03-11 15:38:30 +053014728 if (WLAN_HDD_IS_LOAD_UNLOAD_IN_PROGRESS(pHddCtx))
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053014729 {
14730 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
14731 "%s: Unloading/Loading in Progress. Ignore!!!", __func__);
14732 return 0;
14733 }
14734
14735 spin_lock(&pHddCtx->schedScan_lock);
14736 pHddCtx->isWiphySuspended = FALSE;
14737 if (TRUE != pHddCtx->isSchedScanUpdatePending)
14738 {
14739 spin_unlock(&pHddCtx->schedScan_lock);
14740 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
14741 "%s: Return resume is not due to PNO indication", __func__);
14742 return 0;
14743 }
14744 // Reset flag to avoid updatating cfg80211 data old results again
14745 pHddCtx->isSchedScanUpdatePending = FALSE;
14746 spin_unlock(&pHddCtx->schedScan_lock);
14747
Mahesh A Saptasagarb9c50402014-01-16 15:49:22 +053014748
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053014749 status = hdd_get_front_adapter ( pHddCtx, &pAdapterNode );
14750
14751 while ( NULL != pAdapterNode && VOS_STATUS_SUCCESS == status )
14752 {
14753 pAdapter = pAdapterNode->pAdapter;
14754 if ( (NULL != pAdapter) &&
14755 (WLAN_HDD_INFRA_STATION == pAdapter->device_mode) )
14756 {
14757 if (0 != wlan_hdd_cfg80211_update_bss(pHddCtx->wiphy, pAdapter))
Mahesh A Saptasagarb9c50402014-01-16 15:49:22 +053014758 {
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053014759 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_WARN,
14760 "%s: NO SCAN result", __func__);
Mahesh A Saptasagarb9c50402014-01-16 15:49:22 +053014761 }
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053014762 else
Mahesh A Saptasagarb9c50402014-01-16 15:49:22 +053014763 {
14764 /* Acquire wakelock to handle the case where APP's tries to
14765 * suspend immediately after updating the scan results. Whis
14766 * results in app's is in suspended state and not able to
14767 * process the connect request to AP
14768 */
14769 hdd_prevent_suspend_timeout(2000);
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053014770 cfg80211_sched_scan_results(pHddCtx->wiphy);
Mahesh A Saptasagarb9c50402014-01-16 15:49:22 +053014771 }
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053014772
14773 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
14774 "%s : cfg80211 scan result database updated", __func__);
14775
14776 return 0;
14777
14778 }
14779 status = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
14780 pAdapterNode = pNext;
14781 }
14782
14783 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
14784 "%s: Failed to find Adapter", __func__);
14785 return 0;
14786}
14787
Mahesh A Saptasagarbcc5b662014-06-02 21:46:23 +053014788int wlan_hdd_cfg80211_resume_wlan(struct wiphy *wiphy)
14789{
14790 int ret;
14791
14792 vos_ssr_protect(__func__);
14793 ret = __wlan_hdd_cfg80211_resume_wlan(wiphy);
14794 vos_ssr_unprotect(__func__);
14795
14796 return ret;
14797}
14798
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053014799/*
Mahesh A Saptasagarbcc5b662014-06-02 21:46:23 +053014800 * FUNCTION: __wlan_hdd_cfg80211_suspend_wlan
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053014801 * this is called when cfg80211 driver suspends
14802 */
Mahesh A Saptasagarbcc5b662014-06-02 21:46:23 +053014803int __wlan_hdd_cfg80211_suspend_wlan(struct wiphy *wiphy,
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053014804 struct cfg80211_wowlan *wow)
14805{
14806 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
14807
14808 ENTER();
14809 if (NULL == pHddCtx)
14810 {
14811 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
14812 "%s: HddCtx validation failed", __func__);
14813 return 0;
14814 }
14815
14816 pHddCtx->isWiphySuspended = TRUE;
14817
14818 EXIT();
14819
14820 return 0;
14821}
14822
Mahesh A Saptasagarbcc5b662014-06-02 21:46:23 +053014823int wlan_hdd_cfg80211_suspend_wlan(struct wiphy *wiphy,
14824 struct cfg80211_wowlan *wow)
14825{
14826 int ret;
14827
14828 vos_ssr_protect(__func__);
14829 ret = __wlan_hdd_cfg80211_suspend_wlan(wiphy, wow);
14830 vos_ssr_unprotect(__func__);
14831
14832 return ret;
14833}
Jeff Johnson295189b2012-06-20 16:38:30 -070014834/* cfg80211_ops */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014835static struct cfg80211_ops wlan_hdd_cfg80211_ops =
Jeff Johnson295189b2012-06-20 16:38:30 -070014836{
14837 .add_virtual_intf = wlan_hdd_add_virtual_intf,
14838 .del_virtual_intf = wlan_hdd_del_virtual_intf,
14839 .change_virtual_intf = wlan_hdd_cfg80211_change_iface,
14840 .change_station = wlan_hdd_change_station,
14841#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,4,0))
14842 .add_beacon = wlan_hdd_cfg80211_add_beacon,
14843 .del_beacon = wlan_hdd_cfg80211_del_beacon,
14844 .set_beacon = wlan_hdd_cfg80211_set_beacon,
Jeff Johnson04dd8a82012-06-29 20:41:40 -070014845#else
14846 .start_ap = wlan_hdd_cfg80211_start_ap,
14847 .change_beacon = wlan_hdd_cfg80211_change_beacon,
14848 .stop_ap = wlan_hdd_cfg80211_stop_ap,
Jeff Johnson295189b2012-06-20 16:38:30 -070014849#endif
14850 .change_bss = wlan_hdd_cfg80211_change_bss,
14851 .add_key = wlan_hdd_cfg80211_add_key,
14852 .get_key = wlan_hdd_cfg80211_get_key,
14853 .del_key = wlan_hdd_cfg80211_del_key,
14854 .set_default_key = wlan_hdd_cfg80211_set_default_key,
Jeff Johnson3bbe4bf2013-01-18 17:05:29 -080014855#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,6,0))
Jeff Johnson295189b2012-06-20 16:38:30 -070014856 .set_channel = wlan_hdd_cfg80211_set_channel,
Jeff Johnson3bbe4bf2013-01-18 17:05:29 -080014857#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070014858 .scan = wlan_hdd_cfg80211_scan,
14859 .connect = wlan_hdd_cfg80211_connect,
14860 .disconnect = wlan_hdd_cfg80211_disconnect,
14861 .join_ibss = wlan_hdd_cfg80211_join_ibss,
14862 .leave_ibss = wlan_hdd_cfg80211_leave_ibss,
14863 .set_wiphy_params = wlan_hdd_cfg80211_set_wiphy_params,
14864 .set_tx_power = wlan_hdd_cfg80211_set_txpower,
14865 .get_tx_power = wlan_hdd_cfg80211_get_txpower,
Jeff Johnson295189b2012-06-20 16:38:30 -070014866 .remain_on_channel = wlan_hdd_cfg80211_remain_on_channel,
14867 .cancel_remain_on_channel = wlan_hdd_cfg80211_cancel_remain_on_channel,
DARAM SUDHA39eede62014-02-12 11:16:40 +053014868 .mgmt_tx = wlan_hdd_mgmt_tx,
Jeff Johnson295189b2012-06-20 16:38:30 -070014869#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
14870 .mgmt_tx_cancel_wait = wlan_hdd_cfg80211_mgmt_tx_cancel_wait,
14871 .set_default_mgmt_key = wlan_hdd_set_default_mgmt_key,
14872 .set_txq_params = wlan_hdd_set_txq_params,
14873#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070014874 .get_station = wlan_hdd_cfg80211_get_station,
14875 .set_power_mgmt = wlan_hdd_cfg80211_set_power_mgmt,
14876 .del_station = wlan_hdd_cfg80211_del_station,
Jeff Johnson04dd8a82012-06-29 20:41:40 -070014877 .add_station = wlan_hdd_cfg80211_add_station,
14878#ifdef FEATURE_WLAN_LFR
14879 .set_pmksa = wlan_hdd_cfg80211_set_pmksa,
14880 .del_pmksa = wlan_hdd_cfg80211_del_pmksa,
14881 .flush_pmksa = wlan_hdd_cfg80211_flush_pmksa,
14882#endif
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070014883#if defined(WLAN_FEATURE_VOWIFI_11R) && defined(KERNEL_SUPPORT_11R_CFG80211)
14884 .update_ft_ies = wlan_hdd_cfg80211_update_ft_ies,
14885#endif
Mohit Khanna698ba2a2012-12-04 15:08:18 -080014886#ifdef FEATURE_WLAN_TDLS
14887 .tdls_mgmt = wlan_hdd_cfg80211_tdls_mgmt,
14888 .tdls_oper = wlan_hdd_cfg80211_tdls_oper,
14889#endif
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053014890#ifdef WLAN_FEATURE_GTK_OFFLOAD
14891 .set_rekey_data = wlan_hdd_cfg80211_set_rekey_data,
14892#endif /* WLAN_FEATURE_GTK_OFFLOAD */
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053014893#ifdef FEATURE_WLAN_SCAN_PNO
14894 .sched_scan_start = wlan_hdd_cfg80211_sched_scan_start,
14895 .sched_scan_stop = wlan_hdd_cfg80211_sched_scan_stop,
14896#endif /*FEATURE_WLAN_SCAN_PNO */
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053014897 .resume = wlan_hdd_cfg80211_resume_wlan,
14898 .suspend = wlan_hdd_cfg80211_suspend_wlan,
Gopichand Nakkalac005b7c2013-05-14 16:04:14 +053014899 .set_mac_acl = wlan_hdd_cfg80211_set_mac_acl,
Leo Chang9056f462013-08-01 19:21:11 -070014900#ifdef WLAN_NL80211_TESTMODE
14901 .testmode_cmd = wlan_hdd_cfg80211_testmode,
14902#endif
Madan Mohan Koyyalamudid9383fd2013-08-13 09:27:30 +053014903 .dump_survey = wlan_hdd_cfg80211_dump_survey,
Jeff Johnson295189b2012-06-20 16:38:30 -070014904};
14905