blob: 1c3d2280fbdd81342cf8c1b40247844805e8f341 [file] [log] [blame]
Jeff Johnson295189b2012-06-20 16:38:30 -07001/*
Kiet Lam842dad02014-02-18 18:44:02 -08002 * Copyright (c) 2012-2014 The Linux Foundation. All rights reserved.
3 *
4 * Previously licensed under the ISC license by Qualcomm Atheros, Inc.
5 *
6 *
7 * Permission to use, copy, modify, and/or distribute this software for
8 * any purpose with or without fee is hereby granted, provided that the
9 * above copyright notice and this permission notice appear in all
10 * copies.
11 *
12 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL
13 * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED
14 * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE
15 * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL
16 * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
17 * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
18 * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
19 * PERFORMANCE OF THIS SOFTWARE.
20 */
21
22/*
Kiet Lama7f454d2014-07-24 12:04:06 -070023 * This file was originally distributed by Qualcomm Atheros, Inc.
24 * under proprietary terms before Copyright ownership was assigned
25 * to the Linux Foundation.
Kiet Lamaa8e15a2014-02-11 23:30:06 -080026 */
Kiet Lam842dad02014-02-18 18:44:02 -080027
28
Kiet Lama7f454d2014-07-24 12:04:06 -070029
30
Jeff Johnson295189b2012-06-20 16:38:30 -070031/**========================================================================
32
33 \file wlan_hdd_cfg80211.c
34
35 \brief WLAN Host Device Driver implementation
36
Jeff Johnson295189b2012-06-20 16:38:30 -070037 ========================================================================*/
38
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -070039/**=========================================================================
Jeff Johnson295189b2012-06-20 16:38:30 -070040
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -070041 EDIT HISTORY FOR FILE
Jeff Johnson295189b2012-06-20 16:38:30 -070042
43
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -070044 This section contains comments describing changes made to the module.
45 Notice that changes are listed in reverse chronological order.
Jeff Johnson295189b2012-06-20 16:38:30 -070046
47
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -070048 $Header:$ $DateTime: $ $Author: $
Jeff Johnson295189b2012-06-20 16:38:30 -070049
50
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -070051 when who what, where, why
Jeff Johnson295189b2012-06-20 16:38:30 -070052 -------- --- --------------------------------------------------------
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -070053 21/12/09 Ashwani Created module.
Jeff Johnson295189b2012-06-20 16:38:30 -070054
55 07/06/10 Kumar Deepak Implemented cfg80211 callbacks for ANDROID
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -070056 Ganesh K
Jeff Johnson295189b2012-06-20 16:38:30 -070057 ==========================================================================*/
58
Jeff Johnson295189b2012-06-20 16:38:30 -070059
60#include <linux/version.h>
61#include <linux/module.h>
62#include <linux/kernel.h>
63#include <linux/init.h>
64#include <linux/wireless.h>
65#include <wlan_hdd_includes.h>
66#include <net/arp.h>
67#include <net/cfg80211.h>
68#include <linux/wireless.h>
69#include <wlan_hdd_wowl.h>
70#include <aniGlobal.h>
71#include "ccmApi.h"
72#include "sirParams.h"
73#include "dot11f.h"
74#include "wlan_hdd_assoc.h"
75#include "wlan_hdd_wext.h"
76#include "sme_Api.h"
77#include "wlan_hdd_p2p.h"
78#include "wlan_hdd_cfg80211.h"
79#include "wlan_hdd_hostapd.h"
80#include "sapInternal.h"
81#include "wlan_hdd_softap_tx_rx.h"
82#include "wlan_hdd_main.h"
Madan Mohan Koyyalamudid5acbf52012-11-28 01:45:08 +053083#include "wlan_hdd_assoc.h"
Gopichand Nakkala20c4c042013-04-19 22:08:55 +053084#include "wlan_hdd_power.h"
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053085#include "wlan_hdd_trace.h"
86#include "vos_types.h"
87#include "vos_trace.h"
Jeff Johnson295189b2012-06-20 16:38:30 -070088#ifdef WLAN_BTAMP_FEATURE
89#include "bap_hdd_misc.h"
90#endif
91#include <qc_sap_ioctl.h>
Mohit Khanna698ba2a2012-12-04 15:08:18 -080092#ifdef FEATURE_WLAN_TDLS
93#include "wlan_hdd_tdls.h"
Gopichand Nakkala79ff85d2013-05-27 17:05:29 +053094#include "wlan_hdd_wmm.h"
Madan Mohan Koyyalamudice419872013-09-13 19:36:52 +053095#include "wlan_qct_wda.h"
Mohit Khanna698ba2a2012-12-04 15:08:18 -080096#endif
Madan Mohan Koyylamudi64267f72013-02-05 14:07:08 +053097#include "wlan_nv.h"
Leo Chang6fe1f922013-06-07 19:21:24 -070098#include "wlan_hdd_dev_pwr.h"
Jeff Johnson295189b2012-06-20 16:38:30 -070099
100#define g_mode_rates_size (12)
101#define a_mode_rates_size (8)
102#define FREQ_BASE_80211G (2407)
103#define FREQ_BAND_DIFF_80211G (5)
Jeff Johnson04dd8a82012-06-29 20:41:40 -0700104#define MAX_SCAN_SSID 9
Kiet Lamac06e2c2013-10-23 16:25:07 +0530105#define MAX_PENDING_LOG 5
Jeff Johnson295189b2012-06-20 16:38:30 -0700106#define GET_IE_LEN_IN_BSS_DESC(lenInBss) ( lenInBss + sizeof(lenInBss) - \
krunal soni2a6a9062014-02-11 14:14:23 -0800107 ((uintptr_t)OFFSET_OF( tSirBssDescription, ieFields)))
Jeff Johnson295189b2012-06-20 16:38:30 -0700108
109#define HDD2GHZCHAN(freq, chan, flag) { \
110 .band = IEEE80211_BAND_2GHZ, \
111 .center_freq = (freq), \
112 .hw_value = (chan),\
113 .flags = (flag), \
114 .max_antenna_gain = 0 ,\
115 .max_power = 30, \
116}
117
118#define HDD5GHZCHAN(freq, chan, flag) { \
119 .band = IEEE80211_BAND_5GHZ, \
120 .center_freq = (freq), \
121 .hw_value = (chan),\
122 .flags = (flag), \
123 .max_antenna_gain = 0 ,\
124 .max_power = 30, \
125}
126
127#define HDD_G_MODE_RATETAB(rate, rate_id, flag)\
128{\
129 .bitrate = rate, \
130 .hw_value = rate_id, \
131 .flags = flag, \
132}
133
Lee Hoonkic1262f22013-01-24 21:59:00 -0800134#ifndef WLAN_FEATURE_TDLS_DEBUG
135#define TDLS_LOG_LEVEL VOS_TRACE_LEVEL_INFO
136#else
137#define TDLS_LOG_LEVEL VOS_TRACE_LEVEL_ERROR
138#endif
139
Gopichand Nakkala356fb102013-03-06 12:34:04 +0530140#ifdef WLAN_FEATURE_VOWIFI_11R
141#define WLAN_AKM_SUITE_FT_8021X 0x000FAC03
142#define WLAN_AKM_SUITE_FT_PSK 0x000FAC04
143#endif
144
Naresh Jayaram3180aa42014-02-12 21:47:26 +0530145#define HDD_CHANNEL_14 14
146
Sunil Duttc69bccb2014-05-26 21:30:20 +0530147#ifdef WLAN_FEATURE_LINK_LAYER_STATS
148/*
149 * Used to allocate the size of 4096 for the link layer stats.
150 * The size of 4096 is considered assuming that all data per
151 * respective event fit with in the limit.Please take a call
152 * on the limit based on the data requirements on link layer
153 * statistics.
154 */
155#define LL_STATS_EVENT_BUF_SIZE 4096
156#endif
Dino Mycle6fb96c12014-06-10 11:52:40 +0530157#ifdef WLAN_FEATURE_EXTSCAN
158/*
159 * Used to allocate the size of 4096 for the EXTScan NL data.
160 * The size of 4096 is considered assuming that all data per
161 * respective event fit with in the limit.Please take a call
162 * on the limit based on the data requirements.
163 */
164
165#define EXTSCAN_EVENT_BUF_SIZE 4096
166#define EXTSCAN_MAX_CACHED_RESULTS_PER_IND 32
167#endif
Sunil Duttc69bccb2014-05-26 21:30:20 +0530168
Atul Mittal115287b2014-07-08 13:26:33 +0530169/*EXT TDLS*/
170/*
171 * Used to allocate the size of 4096 for the TDLS.
172 * The size of 4096 is considered assuming that all data per
173 * respective event fit with in the limit.Please take a call
174 * on the limit based on the data requirements on link layer
175 * statistics.
176 */
177#define EXTTDLS_EVENT_BUF_SIZE 4096
178
Gopichand Nakkala747461f2013-04-24 19:24:45 +0530179static const u32 hdd_cipher_suites[] =
Jeff Johnson295189b2012-06-20 16:38:30 -0700180{
181 WLAN_CIPHER_SUITE_WEP40,
182 WLAN_CIPHER_SUITE_WEP104,
183 WLAN_CIPHER_SUITE_TKIP,
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -0800184#ifdef FEATURE_WLAN_ESE
Jeff Johnson295189b2012-06-20 16:38:30 -0700185#define WLAN_CIPHER_SUITE_KRK 0x004096ff /* use for KRK */
186 WLAN_CIPHER_SUITE_KRK,
187 WLAN_CIPHER_SUITE_CCMP,
188#else
189 WLAN_CIPHER_SUITE_CCMP,
190#endif
191#ifdef FEATURE_WLAN_WAPI
192 WLAN_CIPHER_SUITE_SMS4,
193#endif
Chet Lanctot186b5732013-03-18 10:26:30 -0700194#ifdef WLAN_FEATURE_11W
195 WLAN_CIPHER_SUITE_AES_CMAC,
196#endif
Jeff Johnson295189b2012-06-20 16:38:30 -0700197};
198
199static inline int is_broadcast_ether_addr(const u8 *addr)
200{
201 return ((addr[0] == 0xff) && (addr[1] == 0xff) && (addr[2] == 0xff) &&
202 (addr[3] == 0xff) && (addr[4] == 0xff) && (addr[5] == 0xff));
203}
204
205static struct ieee80211_channel hdd_channels_2_4_GHZ[] =
Gopichand Nakkala747461f2013-04-24 19:24:45 +0530206{
Jeff Johnson295189b2012-06-20 16:38:30 -0700207 HDD2GHZCHAN(2412, 1, 0) ,
208 HDD2GHZCHAN(2417, 2, 0) ,
209 HDD2GHZCHAN(2422, 3, 0) ,
210 HDD2GHZCHAN(2427, 4, 0) ,
211 HDD2GHZCHAN(2432, 5, 0) ,
212 HDD2GHZCHAN(2437, 6, 0) ,
213 HDD2GHZCHAN(2442, 7, 0) ,
214 HDD2GHZCHAN(2447, 8, 0) ,
215 HDD2GHZCHAN(2452, 9, 0) ,
216 HDD2GHZCHAN(2457, 10, 0) ,
217 HDD2GHZCHAN(2462, 11, 0) ,
218 HDD2GHZCHAN(2467, 12, 0) ,
219 HDD2GHZCHAN(2472, 13, 0) ,
220 HDD2GHZCHAN(2484, 14, 0) ,
221};
222
Jeff Johnson295189b2012-06-20 16:38:30 -0700223static struct ieee80211_channel hdd_social_channels_2_4_GHZ[] =
224{
225 HDD2GHZCHAN(2412, 1, 0) ,
226 HDD2GHZCHAN(2437, 6, 0) ,
227 HDD2GHZCHAN(2462, 11, 0) ,
228};
Jeff Johnson295189b2012-06-20 16:38:30 -0700229
230static struct ieee80211_channel hdd_channels_5_GHZ[] =
231{
Madan Mohan Koyyalamudic3a240c2012-09-28 15:34:08 -0700232 HDD5GHZCHAN(4920, 240, 0) ,
233 HDD5GHZCHAN(4940, 244, 0) ,
234 HDD5GHZCHAN(4960, 248, 0) ,
235 HDD5GHZCHAN(4980, 252, 0) ,
236 HDD5GHZCHAN(5040, 208, 0) ,
237 HDD5GHZCHAN(5060, 212, 0) ,
238 HDD5GHZCHAN(5080, 216, 0) ,
Jeff Johnson295189b2012-06-20 16:38:30 -0700239 HDD5GHZCHAN(5180, 36, 0) ,
240 HDD5GHZCHAN(5200, 40, 0) ,
241 HDD5GHZCHAN(5220, 44, 0) ,
242 HDD5GHZCHAN(5240, 48, 0) ,
243 HDD5GHZCHAN(5260, 52, 0) ,
244 HDD5GHZCHAN(5280, 56, 0) ,
245 HDD5GHZCHAN(5300, 60, 0) ,
246 HDD5GHZCHAN(5320, 64, 0) ,
247 HDD5GHZCHAN(5500,100, 0) ,
248 HDD5GHZCHAN(5520,104, 0) ,
249 HDD5GHZCHAN(5540,108, 0) ,
250 HDD5GHZCHAN(5560,112, 0) ,
251 HDD5GHZCHAN(5580,116, 0) ,
252 HDD5GHZCHAN(5600,120, 0) ,
253 HDD5GHZCHAN(5620,124, 0) ,
254 HDD5GHZCHAN(5640,128, 0) ,
255 HDD5GHZCHAN(5660,132, 0) ,
256 HDD5GHZCHAN(5680,136, 0) ,
257 HDD5GHZCHAN(5700,140, 0) ,
Leo Chang80de3c22013-11-26 10:52:12 -0800258#ifdef FEATURE_WLAN_CH144
259 HDD5GHZCHAN(5720,144, 0) ,
260#endif /* FEATURE_WLAN_CH144 */
Jeff Johnson295189b2012-06-20 16:38:30 -0700261 HDD5GHZCHAN(5745,149, 0) ,
262 HDD5GHZCHAN(5765,153, 0) ,
263 HDD5GHZCHAN(5785,157, 0) ,
264 HDD5GHZCHAN(5805,161, 0) ,
265 HDD5GHZCHAN(5825,165, 0) ,
266};
267
268static struct ieee80211_rate g_mode_rates[] =
269{
Gopichand Nakkala747461f2013-04-24 19:24:45 +0530270 HDD_G_MODE_RATETAB(10, 0x1, 0),
271 HDD_G_MODE_RATETAB(20, 0x2, 0),
272 HDD_G_MODE_RATETAB(55, 0x4, 0),
273 HDD_G_MODE_RATETAB(110, 0x8, 0),
274 HDD_G_MODE_RATETAB(60, 0x10, 0),
275 HDD_G_MODE_RATETAB(90, 0x20, 0),
276 HDD_G_MODE_RATETAB(120, 0x40, 0),
277 HDD_G_MODE_RATETAB(180, 0x80, 0),
278 HDD_G_MODE_RATETAB(240, 0x100, 0),
279 HDD_G_MODE_RATETAB(360, 0x200, 0),
280 HDD_G_MODE_RATETAB(480, 0x400, 0),
Jeff Johnson295189b2012-06-20 16:38:30 -0700281 HDD_G_MODE_RATETAB(540, 0x800, 0),
Gopichand Nakkala747461f2013-04-24 19:24:45 +0530282};
Jeff Johnson295189b2012-06-20 16:38:30 -0700283
284static struct ieee80211_rate a_mode_rates[] =
285{
Gopichand Nakkala747461f2013-04-24 19:24:45 +0530286 HDD_G_MODE_RATETAB(60, 0x10, 0),
287 HDD_G_MODE_RATETAB(90, 0x20, 0),
288 HDD_G_MODE_RATETAB(120, 0x40, 0),
289 HDD_G_MODE_RATETAB(180, 0x80, 0),
290 HDD_G_MODE_RATETAB(240, 0x100, 0),
291 HDD_G_MODE_RATETAB(360, 0x200, 0),
292 HDD_G_MODE_RATETAB(480, 0x400, 0),
Jeff Johnson295189b2012-06-20 16:38:30 -0700293 HDD_G_MODE_RATETAB(540, 0x800, 0),
294};
295
296static struct ieee80211_supported_band wlan_hdd_band_2_4_GHZ =
297{
298 .channels = hdd_channels_2_4_GHZ,
299 .n_channels = ARRAY_SIZE(hdd_channels_2_4_GHZ),
300 .band = IEEE80211_BAND_2GHZ,
301 .bitrates = g_mode_rates,
302 .n_bitrates = g_mode_rates_size,
303 .ht_cap.ht_supported = 1,
304 .ht_cap.cap = IEEE80211_HT_CAP_SGI_20
305 | IEEE80211_HT_CAP_GRN_FLD
306 | IEEE80211_HT_CAP_DSSSCCK40
307 | IEEE80211_HT_CAP_LSIG_TXOP_PROT,
308 .ht_cap.ampdu_factor = IEEE80211_HT_MAX_AMPDU_64K,
309 .ht_cap.ampdu_density = IEEE80211_HT_MPDU_DENSITY_16,
310 .ht_cap.mcs.rx_mask = { 0xff, 0, 0, 0, 0, 0, 0, 0, 0, 0, },
311 .ht_cap.mcs.rx_highest = cpu_to_le16( 72 ),
312 .ht_cap.mcs.tx_params = IEEE80211_HT_MCS_TX_DEFINED,
313};
314
Jeff Johnson295189b2012-06-20 16:38:30 -0700315static struct ieee80211_supported_band wlan_hdd_band_p2p_2_4_GHZ =
316{
317 .channels = hdd_social_channels_2_4_GHZ,
318 .n_channels = ARRAY_SIZE(hdd_social_channels_2_4_GHZ),
319 .band = IEEE80211_BAND_2GHZ,
320 .bitrates = g_mode_rates,
321 .n_bitrates = g_mode_rates_size,
322 .ht_cap.ht_supported = 1,
323 .ht_cap.cap = IEEE80211_HT_CAP_SGI_20
324 | IEEE80211_HT_CAP_GRN_FLD
325 | IEEE80211_HT_CAP_DSSSCCK40
326 | IEEE80211_HT_CAP_LSIG_TXOP_PROT,
327 .ht_cap.ampdu_factor = IEEE80211_HT_MAX_AMPDU_64K,
328 .ht_cap.ampdu_density = IEEE80211_HT_MPDU_DENSITY_16,
329 .ht_cap.mcs.rx_mask = { 0xff, 0, 0, 0, 0, 0, 0, 0, 0, 0, },
330 .ht_cap.mcs.rx_highest = cpu_to_le16( 72 ),
331 .ht_cap.mcs.tx_params = IEEE80211_HT_MCS_TX_DEFINED,
332};
Jeff Johnson295189b2012-06-20 16:38:30 -0700333
334static struct ieee80211_supported_band wlan_hdd_band_5_GHZ =
335{
336 .channels = hdd_channels_5_GHZ,
337 .n_channels = ARRAY_SIZE(hdd_channels_5_GHZ),
338 .band = IEEE80211_BAND_5GHZ,
339 .bitrates = a_mode_rates,
340 .n_bitrates = a_mode_rates_size,
341 .ht_cap.ht_supported = 1,
342 .ht_cap.cap = IEEE80211_HT_CAP_SGI_20
343 | IEEE80211_HT_CAP_GRN_FLD
344 | IEEE80211_HT_CAP_DSSSCCK40
345 | IEEE80211_HT_CAP_LSIG_TXOP_PROT
346 | IEEE80211_HT_CAP_SGI_40
347 | IEEE80211_HT_CAP_SUP_WIDTH_20_40,
348 .ht_cap.ampdu_factor = IEEE80211_HT_MAX_AMPDU_64K,
349 .ht_cap.ampdu_density = IEEE80211_HT_MPDU_DENSITY_16,
350 .ht_cap.mcs.rx_mask = { 0xff, 0, 0, 0, 0, 0, 0, 0, 0, 0, },
351 .ht_cap.mcs.rx_highest = cpu_to_le16( 72 ),
352 .ht_cap.mcs.tx_params = IEEE80211_HT_MCS_TX_DEFINED,
353};
354
Gopichand Nakkala747461f2013-04-24 19:24:45 +0530355/* This structure contain information what kind of frame are expected in
Jeff Johnson295189b2012-06-20 16:38:30 -0700356 TX/RX direction for each kind of interface */
357static const struct ieee80211_txrx_stypes
358wlan_hdd_txrx_stypes[NUM_NL80211_IFTYPES] = {
359 [NL80211_IFTYPE_STATION] = {
360 .tx = 0xffff,
361 .rx = BIT(SIR_MAC_MGMT_ACTION) |
362 BIT(SIR_MAC_MGMT_PROBE_REQ),
363 },
364 [NL80211_IFTYPE_AP] = {
365 .tx = 0xffff,
366 .rx = BIT(SIR_MAC_MGMT_ASSOC_REQ) |
367 BIT(SIR_MAC_MGMT_REASSOC_REQ) |
368 BIT(SIR_MAC_MGMT_PROBE_REQ) |
369 BIT(SIR_MAC_MGMT_DISASSOC) |
370 BIT(SIR_MAC_MGMT_AUTH) |
371 BIT(SIR_MAC_MGMT_DEAUTH) |
372 BIT(SIR_MAC_MGMT_ACTION),
373 },
Jeff Johnsonbc006202013-04-29 14:05:30 -0700374 [NL80211_IFTYPE_ADHOC] = {
375 .tx = 0xffff,
376 .rx = BIT(SIR_MAC_MGMT_ASSOC_REQ) |
377 BIT(SIR_MAC_MGMT_REASSOC_REQ) |
378 BIT(SIR_MAC_MGMT_PROBE_REQ) |
379 BIT(SIR_MAC_MGMT_DISASSOC) |
380 BIT(SIR_MAC_MGMT_AUTH) |
381 BIT(SIR_MAC_MGMT_DEAUTH) |
382 BIT(SIR_MAC_MGMT_ACTION),
383 },
Jeff Johnson295189b2012-06-20 16:38:30 -0700384 [NL80211_IFTYPE_P2P_CLIENT] = {
385 .tx = 0xffff,
386 .rx = BIT(SIR_MAC_MGMT_ACTION) |
387 BIT(SIR_MAC_MGMT_PROBE_REQ),
388 },
389 [NL80211_IFTYPE_P2P_GO] = {
390 /* This is also same as for SoftAP */
391 .tx = 0xffff,
392 .rx = BIT(SIR_MAC_MGMT_ASSOC_REQ) |
393 BIT(SIR_MAC_MGMT_REASSOC_REQ) |
394 BIT(SIR_MAC_MGMT_PROBE_REQ) |
395 BIT(SIR_MAC_MGMT_DISASSOC) |
396 BIT(SIR_MAC_MGMT_AUTH) |
397 BIT(SIR_MAC_MGMT_DEAUTH) |
398 BIT(SIR_MAC_MGMT_ACTION),
399 },
Jeff Johnson295189b2012-06-20 16:38:30 -0700400};
401
Sudhir Sattayappa Kohalli278eee52013-01-16 17:35:13 -0800402#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,4,0))
Sudhir Sattayappa Kohalli278eee52013-01-16 17:35:13 -0800403static const struct ieee80211_iface_limit
404wlan_hdd_iface_limit[] = {
405 {
Sunil Ravia72c3992013-01-31 06:12:22 -0800406 /* max = 3 ; Our driver create two interfaces during driver init
407 * wlan0 and p2p0 interfaces. p2p0 is considered as station
408 * interface until a group is formed. In JB architecture, once the
409 * group is formed, interface type of p2p0 is changed to P2P GO or
410 * Client.
411 * When supplicant remove the group, it first issue a set interface
412 * cmd to change the mode back to Station. In JB this works fine as
413 * we advertize two station type interface during driver init.
414 * Some vendors create separate interface for P2P GO/Client,
415 * after group formation(Third one). But while group remove
416 * supplicant first tries to change the mode(3rd interface) to STATION
417 * But as we advertized only two sta type interfaces nl80211 was
418 * returning error for the third one which was leading to failure in
419 * delete interface. Ideally while removing the group, supplicant
420 * should not try to change the 3rd interface mode to Station type.
421 * Till we get a fix in wpa_supplicant, we advertize max STA
422 * interface type to 3
423 */
424 .max = 3,
Sudhir Sattayappa Kohalli278eee52013-01-16 17:35:13 -0800425 .types = BIT(NL80211_IFTYPE_STATION),
426 },
427 {
428 .max = 1,
Jeff Johnsonbc006202013-04-29 14:05:30 -0700429 .types = BIT(NL80211_IFTYPE_ADHOC) | BIT(NL80211_IFTYPE_AP),
Sudhir Sattayappa Kohalli278eee52013-01-16 17:35:13 -0800430 },
431 {
432 .max = 1,
433 .types = BIT(NL80211_IFTYPE_P2P_GO) |
434 BIT(NL80211_IFTYPE_P2P_CLIENT),
435 },
436};
437
438/* By default, only single channel concurrency is allowed */
439static struct ieee80211_iface_combination
440wlan_hdd_iface_combination = {
441 .limits = wlan_hdd_iface_limit,
442 .num_different_channels = 1,
Sunil Ravia72c3992013-01-31 06:12:22 -0800443 /*
444 * max = WLAN_MAX_INTERFACES ; JellyBean architecture creates wlan0
445 * and p2p0 interfaces during driver init
446 * Some vendors create separate interface for P2P operations.
447 * wlan0: STA interface
448 * p2p0: P2P Device interface, action frames goes
449 * through this interface.
450 * p2p-xx: P2P interface, After GO negotiation this interface is
451 * created for p2p operations(GO/CLIENT interface).
452 */
453 .max_interfaces = WLAN_MAX_INTERFACES,
Sudhir Sattayappa Kohalli278eee52013-01-16 17:35:13 -0800454 .n_limits = ARRAY_SIZE(wlan_hdd_iface_limit),
455 .beacon_int_infra_match = false,
456};
457#endif
Sudhir Sattayappa Kohalli278eee52013-01-16 17:35:13 -0800458
Jeff Johnson295189b2012-06-20 16:38:30 -0700459static struct cfg80211_ops wlan_hdd_cfg80211_ops;
460
461/* Data rate 100KBPS based on IE Index */
462struct index_data_rate_type
463{
464 v_U8_t beacon_rate_index;
465 v_U16_t supported_rate[4];
466};
467
468/* 11B, 11G Rate table include Basic rate and Extended rate
469 The IDX field is the rate index
470 The HI field is the rate when RSSI is strong or being ignored
471 (in this case we report actual rate)
472 The MID field is the rate when RSSI is moderate
473 (in this case we cap 11b rates at 5.5 and 11g rates at 24)
474 The LO field is the rate when RSSI is low
475 (in this case we don't report rates, actual current rate used)
476 */
477static const struct
478{
479 v_U8_t beacon_rate_index;
Madan Mohan Koyyalamudi8df78d52012-11-02 12:30:06 -0700480 v_U16_t supported_rate[4];
Jeff Johnson295189b2012-06-20 16:38:30 -0700481} supported_data_rate[] =
482{
Madan Mohan Koyyalamudi8df78d52012-11-02 12:30:06 -0700483/* IDX HI HM LM LO (RSSI-based index */
484 {2, { 10, 10, 10, 0}},
485 {4, { 20, 20, 10, 0}},
486 {11, { 55, 20, 10, 0}},
487 {12, { 60, 55, 20, 0}},
488 {18, { 90, 55, 20, 0}},
489 {22, {110, 55, 20, 0}},
490 {24, {120, 90, 60, 0}},
491 {36, {180, 120, 60, 0}},
492 {44, {220, 180, 60, 0}},
493 {48, {240, 180, 90, 0}},
494 {66, {330, 180, 90, 0}},
495 {72, {360, 240, 90, 0}},
496 {96, {480, 240, 120, 0}},
497 {108, {540, 240, 120, 0}}
Jeff Johnson295189b2012-06-20 16:38:30 -0700498};
499
500/* MCS Based rate table */
501static struct index_data_rate_type supported_mcs_rate[] =
502{
503/* MCS L20 L40 S20 S40 */
504 {0, {65, 135, 72, 150}},
505 {1, {130, 270, 144, 300}},
506 {2, {195, 405, 217, 450}},
507 {3, {260, 540, 289, 600}},
508 {4, {390, 810, 433, 900}},
509 {5, {520, 1080, 578, 1200}},
510 {6, {585, 1215, 650, 1350}},
511 {7, {650, 1350, 722, 1500}}
512};
513
Leo Chang6f8870f2013-03-26 18:11:36 -0700514#ifdef WLAN_FEATURE_11AC
515
Gopichand Nakkala4c705372013-04-24 13:20:33 +0530516#define DATA_RATE_11AC_MCS_MASK 0x03
Leo Chang6f8870f2013-03-26 18:11:36 -0700517
518struct index_vht_data_rate_type
519{
520 v_U8_t beacon_rate_index;
Gopichand Nakkala4c705372013-04-24 13:20:33 +0530521 v_U16_t supported_VHT80_rate[2];
522 v_U16_t supported_VHT40_rate[2];
523 v_U16_t supported_VHT20_rate[2];
Leo Chang6f8870f2013-03-26 18:11:36 -0700524};
525
526typedef enum
527{
528 DATA_RATE_11AC_MAX_MCS_7,
529 DATA_RATE_11AC_MAX_MCS_8,
530 DATA_RATE_11AC_MAX_MCS_9,
531 DATA_RATE_11AC_MAX_MCS_NA
532} eDataRate11ACMaxMcs;
533
Mahesh A Saptasagar7bd6ad42014-07-21 18:56:33 +0530534/* SSID broadcast type */
535typedef enum eSSIDBcastType
536{
537 eBCAST_UNKNOWN = 0,
538 eBCAST_NORMAL = 1,
539 eBCAST_HIDDEN = 2,
540} tSSIDBcastType;
541
Leo Chang6f8870f2013-03-26 18:11:36 -0700542/* MCS Based VHT rate table */
543static struct index_vht_data_rate_type supported_vht_mcs_rate[] =
544{
Gopichand Nakkala4c705372013-04-24 13:20:33 +0530545/* MCS L80 S80 L40 S40 L20 S40*/
546 {0, {293, 325}, {135, 150}, {65, 72}},
547 {1, {585, 650}, {270, 300}, {130, 144}},
548 {2, {878, 975}, {405, 450}, {195, 217}},
549 {3, {1170, 1300}, {540, 600}, {260, 289}},
550 {4, {1755, 1950}, {810, 900}, {390, 433}},
551 {5, {2340, 2600}, {1080, 1200}, {520, 578}},
552 {6, {2633, 2925}, {1215, 1350}, {585, 650}},
553 {7, {2925, 3250}, {1350, 1500}, {650, 722}},
554 {8, {3510, 3900}, {1620, 1800}, {780, 867}},
555 {9, {3900, 4333}, {1800, 2000}, {780, 867}}
Leo Chang6f8870f2013-03-26 18:11:36 -0700556};
557#endif /* WLAN_FEATURE_11AC */
558
c_hpothu79aab322014-07-14 21:11:01 +0530559/*array index points to MCS and array value points respective rssi*/
560static int rssiMcsTbl[][10] =
561{
562/*MCS 0 1 2 3 4 5 6 7 8 9*/
563 {-82, -79, -77, -74, -70, -66, -65, -64, -59, -57}, //20
564 {-79, -76, -74, -71, -67, -63, -62, -61, -56, -54}, //40
565 {-76, -73, -71, -68, -64, -60, -59, -58, -53, -51} //80
566};
567
Jeff Johnson295189b2012-06-20 16:38:30 -0700568extern struct net_device_ops net_ops_struct;
569
Leo Chang9056f462013-08-01 19:21:11 -0700570#ifdef WLAN_NL80211_TESTMODE
571enum wlan_hdd_tm_attr
572{
573 WLAN_HDD_TM_ATTR_INVALID = 0,
574 WLAN_HDD_TM_ATTR_CMD = 1,
575 WLAN_HDD_TM_ATTR_DATA = 2,
576 WLAN_HDD_TM_ATTR_TYPE = 3,
577 /* keep last */
578 WLAN_HDD_TM_ATTR_AFTER_LAST,
579 WLAN_HDD_TM_ATTR_MAX = WLAN_HDD_TM_ATTR_AFTER_LAST - 1,
580};
581
582enum wlan_hdd_tm_cmd
583{
584 WLAN_HDD_TM_CMD_WLAN_HB = 1,
585};
586
587#define WLAN_HDD_TM_DATA_MAX_LEN 5000
588
589static const struct nla_policy wlan_hdd_tm_policy[WLAN_HDD_TM_ATTR_MAX + 1] =
590{
591 [WLAN_HDD_TM_ATTR_CMD] = { .type = NLA_U32 },
592 [WLAN_HDD_TM_ATTR_DATA] = { .type = NLA_BINARY,
593 .len = WLAN_HDD_TM_DATA_MAX_LEN },
594};
595#endif /* WLAN_NL80211_TESTMODE */
596
Rajesh Chauhan98a31f82014-01-06 20:15:25 -0800597#ifdef FEATURE_WLAN_CH_AVOID
598/*
599 * FUNCTION: wlan_hdd_send_avoid_freq_event
600 * This is called when wlan driver needs to send vendor specific
601 * avoid frequency range event to userspace
602 */
603int wlan_hdd_send_avoid_freq_event(hdd_context_t *pHddCtx,
604 tHddAvoidFreqList *pAvoidFreqList)
605{
606 struct sk_buff *vendor_event;
607
608 ENTER();
609
610 if (!pHddCtx)
611 {
612 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
613 "%s: HDD context is null", __func__);
614 return -1;
615 }
616
617 if (!pAvoidFreqList)
618 {
619 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
620 "%s: pAvoidFreqList is null", __func__);
621 return -1;
622 }
623
624 vendor_event = cfg80211_vendor_event_alloc(pHddCtx->wiphy,
625 sizeof(tHddAvoidFreqList),
Sunil Duttc69bccb2014-05-26 21:30:20 +0530626 QCA_NL80211_VENDOR_SUBCMD_AVOID_FREQUENCY_INDEX,
Rajesh Chauhan98a31f82014-01-06 20:15:25 -0800627 GFP_KERNEL);
628 if (!vendor_event)
629 {
630 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
631 "%s: cfg80211_vendor_event_alloc failed", __func__);
632 return -1;
633 }
634
635 memcpy(skb_put(vendor_event, sizeof(tHddAvoidFreqList)),
636 (void *)pAvoidFreqList, sizeof(tHddAvoidFreqList));
637
638 cfg80211_vendor_event(vendor_event, GFP_KERNEL);
639
640 EXIT();
641 return 0;
642}
643#endif /* FEATURE_WLAN_CH_AVOID */
644
Sunil Duttc69bccb2014-05-26 21:30:20 +0530645#ifdef WLAN_FEATURE_LINK_LAYER_STATS
646
647static v_BOOL_t put_wifi_rate_stat( tpSirWifiRateStat stats,
648 struct sk_buff *vendor_event)
649{
650 if (nla_put_u8(vendor_event,
651 QCA_WLAN_VENDOR_ATTR_LL_STATS_RATE_PREAMBLE,
652 stats->rate.preamble) ||
653 nla_put_u8(vendor_event,
654 QCA_WLAN_VENDOR_ATTR_LL_STATS_RATE_NSS,
655 stats->rate.nss) ||
656 nla_put_u8(vendor_event,
657 QCA_WLAN_VENDOR_ATTR_LL_STATS_RATE_BW,
658 stats->rate.bw) ||
659 nla_put_u8(vendor_event,
660 QCA_WLAN_VENDOR_ATTR_LL_STATS_RATE_MCS_INDEX,
661 stats->rate.rateMcsIdx) ||
662 nla_put_u32(vendor_event, QCA_WLAN_VENDOR_ATTR_LL_STATS_RATE_BIT_RATE,
663 stats->rate.bitrate ) ||
664 nla_put_u32(vendor_event, QCA_WLAN_VENDOR_ATTR_LL_STATS_RATE_TX_MPDU,
665 stats->txMpdu ) ||
666 nla_put_u32(vendor_event, QCA_WLAN_VENDOR_ATTR_LL_STATS_RATE_RX_MPDU,
667 stats->rxMpdu ) ||
668 nla_put_u32(vendor_event, QCA_WLAN_VENDOR_ATTR_LL_STATS_RATE_MPDU_LOST,
669 stats->mpduLost ) ||
670 nla_put_u32(vendor_event, QCA_WLAN_VENDOR_ATTR_LL_STATS_RATE_RETRIES,
671 stats->retries) ||
672 nla_put_u32(vendor_event,
673 QCA_WLAN_VENDOR_ATTR_LL_STATS_RATE_RETRIES_SHORT,
674 stats->retriesShort ) ||
675 nla_put_u32(vendor_event,
676 QCA_WLAN_VENDOR_ATTR_LL_STATS_RATE_RETRIES_LONG,
677 stats->retriesLong))
678 {
679 hddLog(VOS_TRACE_LEVEL_ERROR,
680 FL("QCA_WLAN_VENDOR_ATTR put fail"));
681 return FALSE;
682 }
683 return TRUE;
684}
685
686static v_BOOL_t put_wifi_peer_info( tpSirWifiPeerInfo stats,
687 struct sk_buff *vendor_event)
688{
689 u32 i = 0;
690 struct nlattr *rateInfo;
691 if (nla_put_u32(vendor_event, QCA_WLAN_VENDOR_ATTR_LL_STATS_PEER_INFO_TYPE,
692 stats->type) ||
693 nla_put(vendor_event,
694 QCA_WLAN_VENDOR_ATTR_LL_STATS_PEER_INFO_MAC_ADDRESS,
695 VOS_MAC_ADDR_SIZE, &stats->peerMacAddress[0]) ||
696 nla_put_u32(vendor_event,
697 QCA_WLAN_VENDOR_ATTR_LL_STATS_PEER_INFO_CAPABILITIES,
698 stats->capabilities) ||
699 nla_put_u32(vendor_event,
700 QCA_WLAN_VENDOR_ATTR_LL_STATS_PEER_INFO_NUM_RATES,
701 stats->numRate))
702 {
703 hddLog(VOS_TRACE_LEVEL_ERROR,
704 FL("QCA_WLAN_VENDOR_ATTR put fail"));
705 goto error;
706 }
707
708 rateInfo = nla_nest_start(vendor_event,
709 QCA_WLAN_VENDOR_ATTR_LL_STATS_PEER_INFO_RATE_INFO);
710 for (i = 0; i < stats->numRate; i++)
711 {
712 struct nlattr *rates;
713 tpSirWifiRateStat pRateStats = (tpSirWifiRateStat )((uint8 *)
714 stats->rateStats +
715 (i * sizeof(tSirWifiRateStat)));
716 rates = nla_nest_start(vendor_event, i);
717
718 if (FALSE == put_wifi_rate_stat(pRateStats, vendor_event))
719 {
720 hddLog(VOS_TRACE_LEVEL_ERROR,
721 FL("QCA_WLAN_VENDOR_ATTR put fail"));
722 return FALSE;
723 }
724 nla_nest_end(vendor_event, rates);
725 }
726 nla_nest_end(vendor_event, rateInfo);
727
728 return TRUE;
729error:
730 return FALSE;
731}
732
733static v_BOOL_t put_wifi_wmm_ac_stat( tpSirWifiWmmAcStat stats,
734 struct sk_buff *vendor_event)
735{
736 if (nla_put_u32(vendor_event, QCA_WLAN_VENDOR_ATTR_LL_STATS_WMM_AC_AC,
737 stats->ac ) ||
738 nla_put_u32(vendor_event,
739 QCA_WLAN_VENDOR_ATTR_LL_STATS_WMM_AC_TX_MPDU,
740 stats->txMpdu ) ||
741 nla_put_u32(vendor_event,
742 QCA_WLAN_VENDOR_ATTR_LL_STATS_WMM_AC_RX_MPDU,
743 stats->rxMpdu ) ||
744 nla_put_u32(vendor_event,
745 QCA_WLAN_VENDOR_ATTR_LL_STATS_WMM_AC_TX_MCAST,
746 stats->txMcast ) ||
747 nla_put_u32(vendor_event,
748 QCA_WLAN_VENDOR_ATTR_LL_STATS_WMM_AC_RX_MCAST,
749 stats->rxMcast ) ||
750 nla_put_u32(vendor_event,
751 QCA_WLAN_VENDOR_ATTR_LL_STATS_WMM_AC_RX_AMPDU,
752 stats->rxAmpdu ) ||
753 nla_put_u32(vendor_event,
754 QCA_WLAN_VENDOR_ATTR_LL_STATS_WMM_AC_TX_AMPDU,
755 stats->txAmpdu ) ||
756 nla_put_u32(vendor_event,
757 QCA_WLAN_VENDOR_ATTR_LL_STATS_WMM_AC_MPDU_LOST,
758 stats->mpduLost )||
759 nla_put_u32(vendor_event,
760 QCA_WLAN_VENDOR_ATTR_LL_STATS_WMM_AC_RETRIES,
761 stats->retries ) ||
762 nla_put_u32(vendor_event,
763 QCA_WLAN_VENDOR_ATTR_LL_STATS_WMM_AC_RETRIES_SHORT,
764 stats->retriesShort ) ||
765 nla_put_u32(vendor_event,
766 QCA_WLAN_VENDOR_ATTR_LL_STATS_WMM_AC_RETRIES_LONG,
767 stats->retriesLong ) ||
768 nla_put_u32(vendor_event,
769 QCA_WLAN_VENDOR_ATTR_LL_STATS_WMM_AC_CONTENTION_TIME_MIN,
770 stats->contentionTimeMin ) ||
771 nla_put_u32(vendor_event,
772 QCA_WLAN_VENDOR_ATTR_LL_STATS_WMM_AC_CONTENTION_TIME_MAX,
773 stats->contentionTimeMax ) ||
774 nla_put_u32(vendor_event,
775 QCA_WLAN_VENDOR_ATTR_LL_STATS_WMM_AC_CONTENTION_TIME_AVG,
776 stats->contentionTimeAvg ) ||
777 nla_put_u32(vendor_event,
778 QCA_WLAN_VENDOR_ATTR_LL_STATS_WMM_AC_CONTENTION_NUM_SAMPLES,
779 stats->contentionNumSamples ))
780 {
781 hddLog(VOS_TRACE_LEVEL_ERROR,
782 FL("QCA_WLAN_VENDOR_ATTR put fail") );
783 return FALSE;
784 }
785 return TRUE;
786}
787
788static v_BOOL_t put_wifi_interface_info(tpSirWifiInterfaceInfo stats,
789 struct sk_buff *vendor_event)
790{
Dino Myclec8f3f332014-07-21 16:48:27 +0530791 if (nla_put_s32(vendor_event,
Sunil Duttc69bccb2014-05-26 21:30:20 +0530792 QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_INFO_MODE, stats->mode ) ||
793 nla_put(vendor_event,
794 QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_INFO_MAC_ADDR,
795 VOS_MAC_ADDR_SIZE, stats->macAddr) ||
796 nla_put_u32(vendor_event,
797 QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_INFO_STATE,
798 stats->state ) ||
799 nla_put_u32(vendor_event,
800 QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_INFO_ROAMING,
801 stats->roaming ) ||
802 nla_put_u32(vendor_event,
803 QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_INFO_CAPABILITIES,
804 stats->capabilities ) ||
805 nla_put(vendor_event,
806 QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_INFO_SSID,
807 strlen(stats->ssid), stats->ssid) ||
808 nla_put(vendor_event,
809 QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_INFO_BSSID,
810 WNI_CFG_BSSID_LEN, stats->bssid) ||
811 nla_put(vendor_event,
812 QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_INFO_AP_COUNTRY_STR,
813 WNI_CFG_COUNTRY_CODE_LEN, stats->apCountryStr) ||
814 nla_put(vendor_event,
815 QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_INFO_COUNTRY_STR,
816 WNI_CFG_COUNTRY_CODE_LEN, stats->countryStr)
817 )
818 {
819 hddLog(VOS_TRACE_LEVEL_ERROR,
820 FL("QCA_WLAN_VENDOR_ATTR put fail") );
821 return FALSE;
822 }
823 return TRUE;
824}
825
Dino Mycle3b9536d2014-07-09 22:05:24 +0530826static v_BOOL_t put_wifi_iface_stats(hdd_adapter_t *pAdapter,
827 tpSirWifiIfaceStat pWifiIfaceStat,
Sunil Duttc69bccb2014-05-26 21:30:20 +0530828 struct sk_buff *vendor_event)
829{
830 int i = 0;
831 struct nlattr *wmmInfo;
Dino Mycle3b9536d2014-07-09 22:05:24 +0530832 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
833 WLANTL_InterfaceStatsType *pWifiIfaceStatTL = NULL;
834
Sunil Duttc69bccb2014-05-26 21:30:20 +0530835 if (FALSE == put_wifi_interface_info(
836 &pWifiIfaceStat->info,
837 vendor_event))
838 {
839 hddLog(VOS_TRACE_LEVEL_ERROR,
840 FL("QCA_WLAN_VENDOR_ATTR put fail") );
841 return FALSE;
842
843 }
Dino Mycle3b9536d2014-07-09 22:05:24 +0530844 pWifiIfaceStatTL = (WLANTL_InterfaceStatsType *)
845 vos_mem_malloc(sizeof(WLANTL_InterfaceStatsType));
846 if (NULL == pWifiIfaceStatTL)
847 {
848 hddLog(VOS_TRACE_LEVEL_ERROR, FL("vos_mem_malloc failed"));
849 return FALSE;
850 }
851
852
853 if ( pWifiIfaceStat->info.state == WIFI_ASSOCIATED)
854 {
855 if (VOS_STATUS_SUCCESS ==
856 WLANTL_CollectInterfaceStats((WLAN_HDD_GET_CTX(pAdapter))->pvosContext,
857 pHddStaCtx->conn_info.staId[0], pWifiIfaceStatTL))
858 {
859 /* mgmtRx, MgmtActionRx, rxMcast, rxMpdu, rxAmpdu, rssiData are
860 * obtained from TL structure
861 */
862
863 pWifiIfaceStat->mgmtRx = pWifiIfaceStat->beaconRx +
864 pWifiIfaceStatTL->mgmtRx;
865 pWifiIfaceStat->mgmtActionRx = pWifiIfaceStatTL->mgmtActionRx;
866 pWifiIfaceStat->mgmtActionTx = pWifiIfaceStatTL->mgmtActionTx;
867 pWifiIfaceStat->rssiData = pWifiIfaceStatTL->rssiData;
868
869 vos_mem_copy(
870 (void *) &pWifiIfaceStat->AccessclassStats[WIFI_AC_VO],
871 (void *) &pWifiIfaceStatTL->accessCategoryStats[WLANTL_AC_VO],
872 sizeof(WLANTL_AccessCategoryStatsType));
873
874 vos_mem_copy(
875 (void *) &pWifiIfaceStat->AccessclassStats[WIFI_AC_VI],
876 (void *) &pWifiIfaceStatTL->accessCategoryStats[WLANTL_AC_VI],
877 sizeof(WLANTL_AccessCategoryStatsType));
878
879 vos_mem_copy(
880 (void *) &pWifiIfaceStat->AccessclassStats[WIFI_AC_BE],
881 (void *) &pWifiIfaceStatTL->accessCategoryStats[WLANTL_AC_BE],
882 sizeof(WLANTL_AccessCategoryStatsType));
883
884 vos_mem_copy(
885 (void *) &pWifiIfaceStat->AccessclassStats[WIFI_AC_BK],
886 (void *) &pWifiIfaceStatTL->accessCategoryStats[WLANTL_AC_BK],
887 sizeof(WLANTL_AccessCategoryStatsType));
888 }
889 else
890 {
891 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Error in getting stats from TL"));
892 }
893
894 pWifiIfaceStat->AccessclassStats[WIFI_AC_VO].txMpdu =
895 pAdapter->hdd_stats.hddTxRxStats.txFetchedAC[WLANTL_AC_VO];
896 pWifiIfaceStat->AccessclassStats[WIFI_AC_VI].txMpdu =
897 pAdapter->hdd_stats.hddTxRxStats.txFetchedAC[WLANTL_AC_VI];
898 pWifiIfaceStat->AccessclassStats[WIFI_AC_BE].txMpdu =
899 pAdapter->hdd_stats.hddTxRxStats.txFetchedAC[WLANTL_AC_BE];
900 pWifiIfaceStat->AccessclassStats[WIFI_AC_BK].txMpdu =
901 pAdapter->hdd_stats.hddTxRxStats.txFetchedAC[WLANTL_AC_BK];
902
903 pWifiIfaceStat->AccessclassStats[WIFI_AC_VO].txMcast =
904 pAdapter->hdd_stats.hddTxRxStats.txMcast[WLANTL_AC_VO];
905 pWifiIfaceStat->AccessclassStats[WIFI_AC_VI].txMcast =
906 pAdapter->hdd_stats.hddTxRxStats.txMcast[WLANTL_AC_VI];
907 pWifiIfaceStat->AccessclassStats[WIFI_AC_BE].txMcast =
908 pAdapter->hdd_stats.hddTxRxStats.txMcast[WLANTL_AC_BE];
909 pWifiIfaceStat->AccessclassStats[WIFI_AC_BK].txMcast =
910 pAdapter->hdd_stats.hddTxRxStats.txMcast[WLANTL_AC_BK];
911 }
912 else
913 {
914 hddLog(VOS_TRACE_LEVEL_INFO, FL("Interface not Associated"));
915 }
916
917
Sunil Duttc69bccb2014-05-26 21:30:20 +0530918
919 if (nla_put_u32(vendor_event,
920 QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_BEACON_RX,
921 pWifiIfaceStat->beaconRx) ||
922 nla_put_u32(vendor_event,
923 QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_MGMT_RX,
924 pWifiIfaceStat->mgmtRx) ||
925 nla_put_u32(vendor_event,
926 QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_MGMT_ACTION_RX,
927 pWifiIfaceStat->mgmtActionRx) ||
928 nla_put_u32(vendor_event,
929 QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_MGMT_ACTION_TX,
930 pWifiIfaceStat->mgmtActionTx) ||
Dino Mycle3b9536d2014-07-09 22:05:24 +0530931 nla_put_s32(vendor_event,
Sunil Duttc69bccb2014-05-26 21:30:20 +0530932 QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_RSSI_MGMT,
933 pWifiIfaceStat->rssiMgmt) ||
Dino Mycle3b9536d2014-07-09 22:05:24 +0530934 nla_put_s32(vendor_event,
Sunil Duttc69bccb2014-05-26 21:30:20 +0530935 QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_RSSI_DATA,
936 pWifiIfaceStat->rssiData) ||
Dino Mycle3b9536d2014-07-09 22:05:24 +0530937 nla_put_s32(vendor_event,
Sunil Duttc69bccb2014-05-26 21:30:20 +0530938 QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_RSSI_ACK,
939 pWifiIfaceStat->rssiAck))
940 {
941 hddLog(VOS_TRACE_LEVEL_ERROR,
942 FL("QCA_WLAN_VENDOR_ATTR put fail"));
Dino Mycle3b9536d2014-07-09 22:05:24 +0530943 vos_mem_free(pWifiIfaceStatTL);
Sunil Duttc69bccb2014-05-26 21:30:20 +0530944 return FALSE;
945 }
946
947 wmmInfo = nla_nest_start(vendor_event,
948 QCA_WLAN_VENDOR_ATTR_LL_STATS_WMM_INFO);
949 for (i = 0; i < WIFI_AC_MAX; i++)
950 {
951 struct nlattr *wmmStats;
952 wmmStats = nla_nest_start(vendor_event, i);
953 if (FALSE == put_wifi_wmm_ac_stat(
954 &pWifiIfaceStat->AccessclassStats[i],
955 vendor_event))
956 {
957 hddLog(VOS_TRACE_LEVEL_ERROR,
958 FL("QCA_WLAN_VENDOR_ATTR put Fail"));
Dino Mycle3b9536d2014-07-09 22:05:24 +0530959 vos_mem_free(pWifiIfaceStatTL);
Sunil Duttc69bccb2014-05-26 21:30:20 +0530960 return FALSE;
961 }
962
963 nla_nest_end(vendor_event, wmmStats);
964 }
965 nla_nest_end(vendor_event, wmmInfo);
Dino Mycle3b9536d2014-07-09 22:05:24 +0530966 vos_mem_free(pWifiIfaceStatTL);
Sunil Duttc69bccb2014-05-26 21:30:20 +0530967 return TRUE;
968}
969
970static tSirWifiInterfaceMode
971 hdd_map_device_to_ll_iface_mode ( int deviceMode )
972{
973 switch (deviceMode)
974 {
975 case WLAN_HDD_INFRA_STATION:
976 return WIFI_INTERFACE_STA;
977 case WLAN_HDD_SOFTAP:
978 return WIFI_INTERFACE_SOFTAP;
979 case WLAN_HDD_P2P_CLIENT:
980 return WIFI_INTERFACE_P2P_CLIENT;
981 case WLAN_HDD_P2P_GO:
982 return WIFI_INTERFACE_P2P_GO;
983 case WLAN_HDD_IBSS:
984 return WIFI_INTERFACE_IBSS;
985 default:
Dino Myclec8f3f332014-07-21 16:48:27 +0530986 return WIFI_INTERFACE_UNKNOWN;
Sunil Duttc69bccb2014-05-26 21:30:20 +0530987 }
988}
989
990static v_BOOL_t hdd_get_interface_info(hdd_adapter_t *pAdapter,
991 tpSirWifiInterfaceInfo pInfo)
992{
993 v_U8_t *staMac = NULL;
994 hdd_station_ctx_t *pHddStaCtx;
995 tHalHandle hHal = WLAN_HDD_GET_HAL_CTX(pAdapter);
996 tpAniSirGlobal pMac = PMAC_STRUCT( hHal );
997
998 pInfo->mode = hdd_map_device_to_ll_iface_mode(pAdapter->device_mode);
999
1000 vos_mem_copy(pInfo->macAddr,
1001 pAdapter->macAddressCurrent.bytes, sizeof(v_MACADDR_t));
1002
1003 if (((WLAN_HDD_INFRA_STATION == pAdapter->device_mode) ||
1004 (WLAN_HDD_P2P_CLIENT == pAdapter->device_mode) ||
1005 (WLAN_HDD_P2P_DEVICE == pAdapter->device_mode)))
1006 {
1007 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
1008 if (eConnectionState_NotConnected == pHddStaCtx->conn_info.connState)
1009 {
1010 pInfo->state = WIFI_DISCONNECTED;
1011 }
1012 if (eConnectionState_Connecting == pHddStaCtx->conn_info.connState)
1013 {
1014 hddLog(VOS_TRACE_LEVEL_ERROR,
1015 "%s: Session ID %d, Connection is in progress", __func__,
1016 pAdapter->sessionId);
1017 pInfo->state = WIFI_ASSOCIATING;
1018 }
1019 if ((eConnectionState_Associated == pHddStaCtx->conn_info.connState) &&
1020 (VOS_FALSE == pHddStaCtx->conn_info.uIsAuthenticated))
1021 {
1022 staMac = (v_U8_t *) &(pAdapter->macAddressCurrent.bytes[0]);
1023 hddLog(VOS_TRACE_LEVEL_ERROR,
1024 "%s: client " MAC_ADDRESS_STR
1025 " is in the middle of WPS/EAPOL exchange.", __func__,
1026 MAC_ADDR_ARRAY(staMac));
1027 pInfo->state = WIFI_AUTHENTICATING;
1028 }
1029 if (eConnectionState_Associated == pHddStaCtx->conn_info.connState)
1030 {
1031 pInfo->state = WIFI_ASSOCIATED;
1032 vos_mem_copy(pInfo->bssid,
1033 &pHddStaCtx->conn_info.bssId, WNI_CFG_BSSID_LEN);
1034 vos_mem_copy(pInfo->ssid,
1035 pHddStaCtx->conn_info.SSID.SSID.ssId,
1036 pHddStaCtx->conn_info.SSID.SSID.length);
1037 //NULL Terminate the string.
1038 pInfo->ssid[pHddStaCtx->conn_info.SSID.SSID.length] = 0;
1039 }
1040 }
1041 vos_mem_copy(pInfo->countryStr,
1042 pMac->scan.countryCodeCurrent, WNI_CFG_COUNTRY_CODE_LEN);
1043
1044 vos_mem_copy(pInfo->apCountryStr,
1045 pMac->scan.countryCodeCurrent, WNI_CFG_COUNTRY_CODE_LEN);
1046
1047 return TRUE;
1048}
1049
1050/*
1051 * hdd_link_layer_process_peer_stats () - This function is called after
1052 * receiving Link Layer Peer statistics from FW.This function converts
1053 * the firmware data to the NL data and sends the same to the kernel/upper
1054 * layers.
1055 */
1056static v_VOID_t hdd_link_layer_process_peer_stats(hdd_adapter_t *pAdapter,
1057 v_VOID_t *pData)
1058{
1059 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
1060 tpSirWifiRateStat pWifiRateStat;
1061 tpSirWifiPeerStat pWifiPeerStat;
1062 tpSirWifiPeerInfo pWifiPeerInfo;
1063 struct nlattr *peerInfo;
1064 struct sk_buff *vendor_event;
1065 int status, i;
1066
1067 status = wlan_hdd_validate_context(pHddCtx);
1068 if (0 != status)
1069 {
1070 hddLog(VOS_TRACE_LEVEL_ERROR,
1071 FL("HDD context is not valid") );
1072 return;
1073 }
1074
1075 pWifiPeerStat = (tpSirWifiPeerStat) pData;
1076
1077 hddLog(VOS_TRACE_LEVEL_INFO,
1078 "LL_STATS_PEER_ALL : numPeers %u",
1079 pWifiPeerStat->numPeers);
1080 {
1081 for (i = 0; i < pWifiPeerStat->numPeers; i++)
1082 {
1083 pWifiPeerInfo = (tpSirWifiPeerInfo)
1084 ((uint8 *)pWifiPeerStat->peerInfo +
1085 ( i * sizeof(tSirWifiPeerInfo)));
1086
1087 hddLog(VOS_TRACE_LEVEL_INFO,
1088 " %d) LL_STATS Channel Stats "
1089 " Peer Type %u "
1090 " peerMacAddress %pM "
1091 " capabilities 0x%x "
1092 " numRate %u ",
1093 i,
1094 pWifiPeerInfo->type,
1095 pWifiPeerInfo->peerMacAddress,
1096 pWifiPeerInfo->capabilities,
1097 pWifiPeerInfo->numRate);
1098 {
1099 int j;
1100 for (j = 0; j < pWifiPeerInfo->numRate; j++)
1101 {
1102 pWifiRateStat = (tpSirWifiRateStat)
1103 ((tANI_U8 *) pWifiPeerInfo->rateStats +
1104 ( j * sizeof(tSirWifiRateStat)));
1105
1106 hddLog(VOS_TRACE_LEVEL_INFO,
1107 " peer Rate Stats "
1108 " preamble %u "
1109 " nss %u "
1110 " bw %u "
1111 " rateMcsIdx %u "
1112 " reserved %u "
1113 " bitrate %u "
1114 " txMpdu %u "
1115 " rxMpdu %u "
1116 " mpduLost %u "
1117 " retries %u "
1118 " retriesShort %u "
1119 " retriesLong %u",
1120 pWifiRateStat->rate.preamble,
1121 pWifiRateStat->rate.nss,
1122 pWifiRateStat->rate.bw,
1123 pWifiRateStat->rate.rateMcsIdx,
1124 pWifiRateStat->rate.reserved,
1125 pWifiRateStat->rate.bitrate,
1126 pWifiRateStat->txMpdu,
1127 pWifiRateStat->rxMpdu,
1128 pWifiRateStat->mpduLost,
1129 pWifiRateStat->retries,
1130 pWifiRateStat->retriesShort,
1131 pWifiRateStat->retriesLong);
1132 }
1133 }
1134 }
1135 }
1136
1137 /*
1138 * Allocate a size of 4096 for the peer stats comprising
1139 * each of size = sizeof (tSirWifiPeerInfo) + numRate *
1140 * sizeof (tSirWifiRateStat).Each field is put with an
1141 * NL attribute.The size of 4096 is considered assuming
1142 * that number of rates shall not exceed beyond 50 with
1143 * the sizeof (tSirWifiRateStat) being 32.
1144 */
1145 vendor_event = cfg80211_vendor_event_alloc(pHddCtx->wiphy,
1146 LL_STATS_EVENT_BUF_SIZE + NLMSG_HDRLEN,
1147 QCA_NL80211_VENDOR_SUBCMD_LL_PEER_INFO_STATS_INDEX,
1148 GFP_KERNEL);
1149 if (!vendor_event)
1150 {
1151 hddLog(VOS_TRACE_LEVEL_ERROR,
1152 "%s: cfg80211_vendor_event_alloc failed",
1153 __func__);
1154 return;
1155 }
1156 if (nla_put_u32(vendor_event,
1157 QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_NUM_PEERS,
1158 pWifiPeerStat->numPeers))
1159 {
1160 hddLog(VOS_TRACE_LEVEL_ERROR,
1161 "%s: QCA_WLAN_VENDOR_ATTR put fail", __func__);
1162 kfree_skb(vendor_event);
1163 return;
1164 }
1165
1166 peerInfo = nla_nest_start(vendor_event,
1167 QCA_WLAN_VENDOR_ATTR_LL_STATS_PEER_INFO);
1168
1169 pWifiPeerInfo = (tpSirWifiPeerInfo) ((uint8 *)
1170 pWifiPeerStat->peerInfo);
1171
1172 for (i = 1; i <= pWifiPeerStat->numPeers; i++)
1173 {
1174 struct nlattr *peers = nla_nest_start(vendor_event, i);
1175 int numRate = pWifiPeerInfo->numRate;
1176
1177 if (FALSE == put_wifi_peer_info(
1178 pWifiPeerInfo, vendor_event))
1179 {
1180 hddLog(VOS_TRACE_LEVEL_ERROR,
1181 "%s: put_wifi_peer_info put fail", __func__);
1182 kfree_skb(vendor_event);
1183 return;
1184 }
1185
1186 pWifiPeerInfo = (tpSirWifiPeerInfo) ((uint8 *)
1187 pWifiPeerStat->peerInfo +
1188 (i * sizeof(tSirWifiPeerInfo)) +
1189 (numRate * sizeof (tSirWifiRateStat)));
1190 nla_nest_end(vendor_event, peers);
1191 }
1192 nla_nest_end(vendor_event, peerInfo);
1193 cfg80211_vendor_event(vendor_event, GFP_KERNEL);
1194}
1195
1196/*
1197 * hdd_link_layer_process_iface_stats () - This function is called after
1198 * receiving Link Layer Interface statistics from FW.This function converts
1199 * the firmware data to the NL data and sends the same to the kernel/upper
1200 * layers.
1201 */
1202static v_VOID_t hdd_link_layer_process_iface_stats(hdd_adapter_t *pAdapter,
1203 v_VOID_t *pData)
1204{
1205 tpSirWifiIfaceStat pWifiIfaceStat;
1206 struct sk_buff *vendor_event;
1207 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
1208 int status;
1209
1210 status = wlan_hdd_validate_context(pHddCtx);
1211 if (0 != status)
1212 {
1213 hddLog(VOS_TRACE_LEVEL_ERROR,
1214 FL("HDD context is not valid") );
1215 return;
1216 }
1217 /*
1218 * Allocate a size of 4096 for the interface stats comprising
1219 * sizeof (tpSirWifiIfaceStat).The size of 4096 is considered
1220 * assuming that all these fit with in the limit.Please take
1221 * a call on the limit based on the data requirements on
1222 * interface statistics.
1223 */
1224 vendor_event = cfg80211_vendor_event_alloc(pHddCtx->wiphy,
1225 LL_STATS_EVENT_BUF_SIZE + NLMSG_HDRLEN,
1226 QCA_NL80211_VENDOR_SUBCMD_LL_IFACE_STATS_INDEX,
1227 GFP_KERNEL);
1228 if (!vendor_event)
1229 {
1230 hddLog(VOS_TRACE_LEVEL_ERROR,
1231 FL("cfg80211_vendor_event_alloc failed") );
1232 return;
1233 }
1234
1235 pWifiIfaceStat = (tpSirWifiIfaceStat) pData;
1236
Dino Mycle3b9536d2014-07-09 22:05:24 +05301237
1238 if (FALSE == hdd_get_interface_info( pAdapter,
1239 &pWifiIfaceStat->info))
1240 {
1241 hddLog(VOS_TRACE_LEVEL_ERROR,
1242 FL("hdd_get_interface_info get fail") );
1243 kfree_skb(vendor_event);
1244 return;
1245 }
1246
1247 if (FALSE == put_wifi_iface_stats( pAdapter, pWifiIfaceStat,
1248 vendor_event))
1249 {
1250 hddLog(VOS_TRACE_LEVEL_ERROR,
1251 FL("put_wifi_iface_stats fail") );
1252 kfree_skb(vendor_event);
1253 return;
1254 }
1255
Sunil Duttc69bccb2014-05-26 21:30:20 +05301256 hddLog(VOS_TRACE_LEVEL_INFO,
1257 "WMI_LINK_STATS_IFACE Data");
1258
1259 hddLog(VOS_TRACE_LEVEL_INFO,
1260 "LL_STATS_IFACE: "
1261 " Mode %u "
1262 " MAC %pM "
1263 " State %u "
1264 " Roaming %u "
1265 " capabilities 0x%x "
1266 " SSID %s "
1267 " BSSID %pM",
1268 pWifiIfaceStat->info.mode,
1269 pWifiIfaceStat->info.macAddr,
1270 pWifiIfaceStat->info.state,
1271 pWifiIfaceStat->info.roaming,
1272 pWifiIfaceStat->info.capabilities,
1273 pWifiIfaceStat->info.ssid,
1274 pWifiIfaceStat->info.bssid);
1275
1276 hddLog(VOS_TRACE_LEVEL_INFO,
1277 " AP country str: %c%c%c",
1278 pWifiIfaceStat->info.apCountryStr[0],
1279 pWifiIfaceStat->info.apCountryStr[1],
1280 pWifiIfaceStat->info.apCountryStr[2]);
1281
1282
1283 hddLog(VOS_TRACE_LEVEL_INFO,
1284 " Country Str Association: %c%c%c",
1285 pWifiIfaceStat->info.countryStr[0],
1286 pWifiIfaceStat->info.countryStr[1],
1287 pWifiIfaceStat->info.countryStr[2]);
1288
1289 hddLog(VOS_TRACE_LEVEL_INFO,
1290 " beaconRx %u "
1291 " mgmtRx %u "
1292 " mgmtActionRx %u "
1293 " mgmtActionTx %u "
Dino Mycle3b9536d2014-07-09 22:05:24 +05301294 " rssiMgmt %d "
1295 " rssiData %d "
1296 " rssiAck %d",
Sunil Duttc69bccb2014-05-26 21:30:20 +05301297 pWifiIfaceStat->beaconRx,
1298 pWifiIfaceStat->mgmtRx,
1299 pWifiIfaceStat->mgmtActionRx,
1300 pWifiIfaceStat->mgmtActionTx,
1301 pWifiIfaceStat->rssiMgmt,
1302 pWifiIfaceStat->rssiData,
1303 pWifiIfaceStat->rssiAck );
1304
1305
1306 {
1307 int i;
1308 for (i = 0 ; i < WIFI_AC_MAX; i ++)
1309 {
1310 hddLog(VOS_TRACE_LEVEL_INFO,
1311
1312 " %d) LL_STATS IFACE: "
1313 " ac: %u txMpdu: %u "
1314 " rxMpdu: %u txMcast: %u "
1315 " rxMcast: %u rxAmpdu: %u "
1316 " txAmpdu: %u mpduLost: %u "
1317 " retries: %u retriesShort: %u "
1318 " retriesLong: %u contentionTimeMin: %u "
1319 " contentionTimeMax: %u contentionTimeAvg: %u "
1320 " contentionNumSamples: %u",
1321 i,
1322 pWifiIfaceStat->AccessclassStats[i].ac,
1323 pWifiIfaceStat->AccessclassStats[i].txMpdu,
1324 pWifiIfaceStat->AccessclassStats[i].rxMpdu,
1325 pWifiIfaceStat->AccessclassStats[i].txMcast,
1326 pWifiIfaceStat->AccessclassStats[i].rxMcast,
1327 pWifiIfaceStat->AccessclassStats[i].rxAmpdu,
1328 pWifiIfaceStat->AccessclassStats[i].txAmpdu,
1329 pWifiIfaceStat->AccessclassStats[i].mpduLost,
1330 pWifiIfaceStat->AccessclassStats[i].retries,
1331 pWifiIfaceStat->
1332 AccessclassStats[i].retriesShort,
1333 pWifiIfaceStat->AccessclassStats[i].retriesLong,
1334 pWifiIfaceStat->
1335 AccessclassStats[i].contentionTimeMin,
1336 pWifiIfaceStat->
1337 AccessclassStats[i].contentionTimeMax,
1338 pWifiIfaceStat->
1339 AccessclassStats[i].contentionTimeAvg,
1340 pWifiIfaceStat->
1341 AccessclassStats[i].contentionNumSamples);
1342
1343 }
1344 }
1345
Sunil Duttc69bccb2014-05-26 21:30:20 +05301346 cfg80211_vendor_event(vendor_event, GFP_KERNEL);
1347}
1348
1349/*
1350 * hdd_link_layer_process_radio_stats () - This function is called after
1351 * receiving Link Layer Radio statistics from FW.This function converts
1352 * the firmware data to the NL data and sends the same to the kernel/upper
1353 * layers.
1354 */
1355static v_VOID_t hdd_link_layer_process_radio_stats(hdd_adapter_t *pAdapter,
1356 v_VOID_t *pData)
1357{
1358 int status, i;
1359 tpSirWifiRadioStat pWifiRadioStat;
1360 tpSirWifiChannelStats pWifiChannelStats;
1361 struct sk_buff *vendor_event;
1362 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
1363 struct nlattr *chList;
1364
1365 status = wlan_hdd_validate_context(pHddCtx);
1366 if (0 != status)
1367 {
1368 hddLog(VOS_TRACE_LEVEL_ERROR,
1369 FL("HDD context is not valid") );
1370 return;
1371 }
1372 pWifiRadioStat = (tpSirWifiRadioStat) pData;
1373
1374 hddLog(VOS_TRACE_LEVEL_INFO,
1375 "LL_STATS_RADIO"
1376 " radio is %d onTime is %u "
1377 " txTime is %u rxTime is %u "
1378 " onTimeScan is %u onTimeNbd is %u "
Dino Mycle6fb96c12014-06-10 11:52:40 +05301379 " onTimeEXTScan is %u onTimeRoamScan is %u "
Sunil Duttc69bccb2014-05-26 21:30:20 +05301380 " onTimePnoScan is %u onTimeHs20 is %u "
1381 " numChannels is %u",
1382 pWifiRadioStat->radio, pWifiRadioStat->onTime,
1383 pWifiRadioStat->txTime, pWifiRadioStat->rxTime,
1384 pWifiRadioStat->onTimeScan, pWifiRadioStat->onTimeNbd,
Dino Mycle6fb96c12014-06-10 11:52:40 +05301385 pWifiRadioStat->onTimeEXTScan,
Sunil Duttc69bccb2014-05-26 21:30:20 +05301386 pWifiRadioStat->onTimeRoamScan,
1387 pWifiRadioStat->onTimePnoScan,
1388 pWifiRadioStat->onTimeHs20,
1389 pWifiRadioStat->numChannels);
1390 /*
1391 * Allocate a size of 4096 for the Radio stats comprising
1392 * sizeof (tSirWifiRadioStat) + numChannels * sizeof
1393 * (tSirWifiChannelStats).Each channel data is put with an
1394 * NL attribute.The size of 4096 is considered assuming that
1395 * number of channels shall not exceed beyond 60 with the
1396 * sizeof (tSirWifiChannelStats) being 24 bytes.
1397 */
1398
1399 vendor_event = cfg80211_vendor_event_alloc(pHddCtx->wiphy,
1400 LL_STATS_EVENT_BUF_SIZE + NLMSG_HDRLEN ,
1401 QCA_NL80211_VENDOR_SUBCMD_LL_RADIO_STATS_INDEX,
1402 GFP_KERNEL);
1403
1404 if (!vendor_event)
1405 {
1406 hddLog(VOS_TRACE_LEVEL_ERROR,
1407 FL("cfg80211_vendor_event_alloc failed") );
1408 return;
1409 }
1410
1411 if (nla_put_u32(vendor_event,
1412 QCA_WLAN_VENDOR_ATTR_LL_STATS_RADIO_ID,
1413 pWifiRadioStat->radio) ||
1414 nla_put_u32(vendor_event,
1415 QCA_WLAN_VENDOR_ATTR_LL_STATS_RADIO_ON_TIME,
1416 pWifiRadioStat->onTime) ||
1417 nla_put_u32(vendor_event,
1418 QCA_WLAN_VENDOR_ATTR_LL_STATS_RADIO_TX_TIME,
1419 pWifiRadioStat->txTime) ||
1420 nla_put_u32(vendor_event,
1421 QCA_WLAN_VENDOR_ATTR_LL_STATS_RADIO_RX_TIME,
1422 pWifiRadioStat->rxTime) ||
1423 nla_put_u32(vendor_event,
1424 QCA_WLAN_VENDOR_ATTR_LL_STATS_RADIO_ON_TIME_SCAN,
1425 pWifiRadioStat->onTimeScan) ||
1426 nla_put_u32(vendor_event,
1427 QCA_WLAN_VENDOR_ATTR_LL_STATS_RADIO_ON_TIME_NBD,
1428 pWifiRadioStat->onTimeNbd) ||
1429 nla_put_u32(vendor_event,
Dino Mycle6fb96c12014-06-10 11:52:40 +05301430 QCA_WLAN_VENDOR_ATTR_LL_STATS_RADIO_ON_TIME_EXTSCAN,
1431 pWifiRadioStat->onTimeEXTScan)||
Sunil Duttc69bccb2014-05-26 21:30:20 +05301432 nla_put_u32(vendor_event,
1433 QCA_WLAN_VENDOR_ATTR_LL_STATS_RADIO_ON_TIME_ROAM_SCAN,
1434 pWifiRadioStat->onTimeRoamScan) ||
1435 nla_put_u32(vendor_event,
1436 QCA_WLAN_VENDOR_ATTR_LL_STATS_RADIO_ON_TIME_PNO_SCAN,
1437 pWifiRadioStat->onTimePnoScan) ||
1438 nla_put_u32(vendor_event,
1439 QCA_WLAN_VENDOR_ATTR_LL_STATS_RADIO_ON_TIME_HS20,
1440 pWifiRadioStat->onTimeHs20) ||
1441 nla_put_u32(vendor_event,
1442 QCA_WLAN_VENDOR_ATTR_LL_STATS_RADIO_NUM_CHANNELS,
1443 pWifiRadioStat->numChannels))
1444 {
1445 hddLog(VOS_TRACE_LEVEL_ERROR,
1446 FL("QCA_WLAN_VENDOR_ATTR put fail"));
1447 kfree_skb(vendor_event);
1448 return ;
1449 }
1450
1451 chList = nla_nest_start(vendor_event,
1452 QCA_WLAN_VENDOR_ATTR_LL_STATS_CH_INFO);
1453 for (i = 0; i < pWifiRadioStat->numChannels; i++)
1454 {
1455 struct nlattr *chInfo;
1456
1457 pWifiChannelStats = (tpSirWifiChannelStats) ((uint8*)
1458 pWifiRadioStat->channels +
1459 (i * sizeof(tSirWifiChannelStats)));
1460
1461 hddLog(VOS_TRACE_LEVEL_INFO,
1462 " %d) Channel Info"
1463 " width is %u "
1464 " CenterFreq %u "
1465 " CenterFreq0 %u "
1466 " CenterFreq1 %u "
1467 " onTime %u "
1468 " ccaBusyTime %u",
1469 i,
1470 pWifiChannelStats->channel.width,
1471 pWifiChannelStats->channel.centerFreq,
1472 pWifiChannelStats->channel.centerFreq0,
1473 pWifiChannelStats->channel.centerFreq1,
1474 pWifiChannelStats->onTime,
1475 pWifiChannelStats->ccaBusyTime);
1476
1477
1478 chInfo = nla_nest_start(vendor_event, i);
1479
1480 if (nla_put_u32(vendor_event,
1481 QCA_WLAN_VENDOR_ATTR_LL_STATS_CHANNEL_INFO_WIDTH,
1482 pWifiChannelStats->channel.width) ||
1483 nla_put_u32(vendor_event,
1484 QCA_WLAN_VENDOR_ATTR_LL_STATS_CHANNEL_INFO_CENTER_FREQ,
1485 pWifiChannelStats->channel.centerFreq) ||
1486 nla_put_u32(vendor_event,
1487 QCA_WLAN_VENDOR_ATTR_LL_STATS_CHANNEL_INFO_CENTER_FREQ0,
1488 pWifiChannelStats->channel.centerFreq0) ||
1489 nla_put_u32(vendor_event,
1490 QCA_WLAN_VENDOR_ATTR_LL_STATS_CHANNEL_INFO_CENTER_FREQ1,
1491 pWifiChannelStats->channel.centerFreq1) ||
1492 nla_put_u32(vendor_event,
1493 QCA_WLAN_VENDOR_ATTR_LL_STATS_CHANNEL_ON_TIME,
1494 pWifiChannelStats->onTime) ||
1495 nla_put_u32(vendor_event,
1496 QCA_WLAN_VENDOR_ATTR_LL_STATS_CHANNEL_CCA_BUSY_TIME,
1497 pWifiChannelStats->ccaBusyTime))
1498 {
1499 hddLog(VOS_TRACE_LEVEL_ERROR,
1500 FL("cfg80211_vendor_event_alloc failed") );
1501 kfree_skb(vendor_event);
1502 return ;
1503 }
1504 nla_nest_end(vendor_event, chInfo);
1505 }
1506 nla_nest_end(vendor_event, chList);
1507
1508 cfg80211_vendor_event(vendor_event, GFP_KERNEL);
1509 return;
1510}
1511
1512/*
1513 * hdd_link_layer_stats_ind_callback () - This function is called after
1514 * receiving Link Layer indications from FW.This callback converts the firmware
1515 * data to the NL data and send the same to the kernel/upper layers.
1516 */
1517static void hdd_link_layer_stats_ind_callback ( void *pCtx,
1518 int indType,
Dino Mycled3d50022014-07-07 12:58:25 +05301519 void *pRsp, u8 *macAddr)
Sunil Duttc69bccb2014-05-26 21:30:20 +05301520{
Dino Mycled3d50022014-07-07 12:58:25 +05301521 hdd_context_t *pHddCtx = (hdd_context_t *)pCtx;
1522 hdd_adapter_t *pAdapter = NULL;
1523 tpSirLLStatsResults linkLayerStatsResults = (tpSirLLStatsResults)pRsp;
Sunil Duttc69bccb2014-05-26 21:30:20 +05301524 int status;
1525
1526 status = wlan_hdd_validate_context(pHddCtx);
1527
1528 if (0 != status)
1529 {
1530 hddLog(VOS_TRACE_LEVEL_ERROR,
1531 FL("HDD context is not valid"));
1532 return;
1533 }
1534
Dino Mycled3d50022014-07-07 12:58:25 +05301535
1536
1537 pAdapter = hdd_get_adapter_by_macaddr(pHddCtx, macAddr);
1538 if (NULL == pAdapter)
1539 {
1540 hddLog(VOS_TRACE_LEVEL_ERROR,
1541 FL(" MAC address %pM does not exist with host"),
1542 macAddr);
1543 return;
1544 }
1545
Sunil Duttc69bccb2014-05-26 21:30:20 +05301546 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Dino Mycled3d50022014-07-07 12:58:25 +05301547 "%s: Interface: %s LLStats indType: %d", __func__,
1548 pAdapter->dev->name, indType);
1549
Sunil Duttc69bccb2014-05-26 21:30:20 +05301550 switch (indType)
1551 {
1552 case SIR_HAL_LL_STATS_RESULTS_RSP:
1553 {
Sunil Duttc69bccb2014-05-26 21:30:20 +05301554 hddLog(VOS_TRACE_LEVEL_INFO,
1555 FL("RESPONSE SIR_HAL_LL_STATS_RESULTS_RSP") );
1556 hddLog(VOS_TRACE_LEVEL_INFO,
1557 "LL_STATS RESULTS RESPONSE paramID = 0x%x",
1558 linkLayerStatsResults->paramId);
1559 hddLog(VOS_TRACE_LEVEL_INFO,
Dino Mycled3d50022014-07-07 12:58:25 +05301560 "LL_STATS RESULTS RESPONSE ifaceId = %u MAC: %pM",
1561 linkLayerStatsResults->ifaceId, macAddr);
Sunil Duttc69bccb2014-05-26 21:30:20 +05301562 hddLog(VOS_TRACE_LEVEL_INFO,
1563 "LL_STATS RESULTS RESPONSE respId = %u",
1564 linkLayerStatsResults->respId);
1565 hddLog(VOS_TRACE_LEVEL_INFO,
1566 "LL_STATS RESULTS RESPONSE moreResultToFollow = %u",
1567 linkLayerStatsResults->moreResultToFollow);
1568 hddLog(VOS_TRACE_LEVEL_INFO,
1569 "LL_STATS RESULTS RESPONSE result = %p",
1570 linkLayerStatsResults->result);
1571 if ( linkLayerStatsResults->paramId & WMI_LINK_STATS_RADIO )
1572 {
1573 hdd_link_layer_process_radio_stats(pAdapter,
1574 (v_VOID_t *)linkLayerStatsResults->result);
1575 }
1576 else if ( linkLayerStatsResults->paramId & WMI_LINK_STATS_IFACE )
1577 {
1578 hdd_link_layer_process_iface_stats(pAdapter,
1579 (v_VOID_t *)linkLayerStatsResults->result);
1580 }
1581 else if ( linkLayerStatsResults->paramId &
1582 WMI_LINK_STATS_ALL_PEER )
1583 {
1584 hdd_link_layer_process_peer_stats(pAdapter,
1585 (v_VOID_t *)linkLayerStatsResults->result);
1586 } /* WMI_LINK_STATS_ALL_PEER */
1587 else
1588 {
1589 hddLog(VOS_TRACE_LEVEL_ERROR,
1590 FL("INVALID LL_STATS_NOTIFY RESPONSE ***********"));
1591 }
1592
1593 break;
1594 }
1595 default:
1596 hddLog(VOS_TRACE_LEVEL_ERROR, "invalid event type %d", indType);
1597 break;
1598 }
1599 return;
1600}
1601
1602const struct
1603nla_policy
1604qca_wlan_vendor_ll_set_policy[QCA_WLAN_VENDOR_ATTR_LL_STATS_SET_MAX +1] =
1605{
1606 [QCA_WLAN_VENDOR_ATTR_LL_STATS_SET_CONFIG_MPDU_SIZE_THRESHOLD] =
1607 { .type = NLA_U32 },
1608 [QCA_WLAN_VENDOR_ATTR_LL_STATS_SET_CONFIG_AGGRESSIVE_STATS_GATHERING] =
1609 { .type = NLA_U32 },
1610};
1611
1612static int wlan_hdd_cfg80211_ll_stats_set(struct wiphy *wiphy,
1613 struct wireless_dev *wdev,
1614 void *data,
1615 int data_len)
1616{
1617 int status;
1618 struct nlattr *tb_vendor[QCA_WLAN_VENDOR_ATTR_LL_STATS_SET_MAX + 1];
Dino Mycledf0a5d92014-07-04 09:41:55 +05301619 tSirLLStatsSetReq linkLayerStatsSetReq;
Sunil Duttc69bccb2014-05-26 21:30:20 +05301620 struct net_device *dev = wdev->netdev;
1621 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
1622 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
1623
1624 status = wlan_hdd_validate_context(pHddCtx);
1625 if (0 != status)
1626 {
1627 hddLog(VOS_TRACE_LEVEL_ERROR,
1628 FL("HDD context is not valid"));
1629 return -EINVAL;
1630 }
1631
1632 if (NULL == pAdapter)
1633 {
1634 hddLog(VOS_TRACE_LEVEL_ERROR,
1635 FL("HDD adapter is Null"));
1636 return -ENODEV;
1637 }
Dino Mycledf0a5d92014-07-04 09:41:55 +05301638 /* check the LLStats Capability */
1639 if ( (TRUE != pHddCtx->cfg_ini->fEnableLLStats) ||
1640 (TRUE != sme_IsFeatureSupportedByFW(LINK_LAYER_STATS_MEAS)))
1641 {
1642 hddLog(VOS_TRACE_LEVEL_ERROR,
1643 FL("Link Layer Statistics not supported by Firmware"));
1644 return -EINVAL;
1645 }
Sunil Duttc69bccb2014-05-26 21:30:20 +05301646
1647 if (nla_parse(tb_vendor, QCA_WLAN_VENDOR_ATTR_LL_STATS_SET_MAX,
1648 (struct nlattr *)data,
1649 data_len, qca_wlan_vendor_ll_set_policy))
1650 {
1651 hddLog(VOS_TRACE_LEVEL_ERROR, FL() );
1652 return -EINVAL;
1653 }
1654 if (!tb_vendor
1655 [QCA_WLAN_VENDOR_ATTR_LL_STATS_SET_CONFIG_MPDU_SIZE_THRESHOLD])
1656 {
1657 hddLog(VOS_TRACE_LEVEL_ERROR, FL("MPDU size Not present"));
1658 return -EINVAL;
1659 }
1660 if (!tb_vendor[
1661 QCA_WLAN_VENDOR_ATTR_LL_STATS_SET_CONFIG_AGGRESSIVE_STATS_GATHERING])
1662 {
1663 hddLog(VOS_TRACE_LEVEL_ERROR, FL(" Stats Gathering Not Present"));
1664 return -EINVAL;
1665 }
Sunil Duttc69bccb2014-05-26 21:30:20 +05301666 // Shall take the request Id if the Upper layers pass. 1 For now.
Dino Mycledf0a5d92014-07-04 09:41:55 +05301667 linkLayerStatsSetReq.reqId = 1;
Sunil Duttc69bccb2014-05-26 21:30:20 +05301668
Dino Mycledf0a5d92014-07-04 09:41:55 +05301669 linkLayerStatsSetReq.mpduSizeThreshold =
Sunil Duttc69bccb2014-05-26 21:30:20 +05301670 nla_get_u32(
1671 tb_vendor[QCA_WLAN_VENDOR_ATTR_LL_STATS_SET_CONFIG_MPDU_SIZE_THRESHOLD]);
1672
Dino Mycledf0a5d92014-07-04 09:41:55 +05301673 linkLayerStatsSetReq.aggressiveStatisticsGathering =
Sunil Duttc69bccb2014-05-26 21:30:20 +05301674 nla_get_u32(
1675 tb_vendor[QCA_WLAN_VENDOR_ATTR_LL_STATS_SET_CONFIG_AGGRESSIVE_STATS_GATHERING]);
1676
Dino Mycled3d50022014-07-07 12:58:25 +05301677 vos_mem_copy(linkLayerStatsSetReq.macAddr,
1678 pAdapter->macAddressCurrent.bytes, sizeof(v_MACADDR_t));
Sunil Duttc69bccb2014-05-26 21:30:20 +05301679
1680
1681 hddLog(VOS_TRACE_LEVEL_INFO,
Dino Mycled3d50022014-07-07 12:58:25 +05301682 "LL_STATS_SET reqId = %d", linkLayerStatsSetReq.reqId);
Sunil Duttc69bccb2014-05-26 21:30:20 +05301683 hddLog(VOS_TRACE_LEVEL_INFO,
Dino Mycled3d50022014-07-07 12:58:25 +05301684 "LL_STATS_SET MAC = %pM", linkLayerStatsSetReq.macAddr);
Sunil Duttc69bccb2014-05-26 21:30:20 +05301685 hddLog(VOS_TRACE_LEVEL_INFO,
1686 "LL_STATS_SET mpduSizeThreshold = %d",
Dino Mycledf0a5d92014-07-04 09:41:55 +05301687 linkLayerStatsSetReq.mpduSizeThreshold);
Sunil Duttc69bccb2014-05-26 21:30:20 +05301688 hddLog(VOS_TRACE_LEVEL_INFO,
1689 "LL_STATS_SET aggressive Statistics Gathering = %d",
Dino Mycledf0a5d92014-07-04 09:41:55 +05301690 linkLayerStatsSetReq.aggressiveStatisticsGathering);
Sunil Duttc69bccb2014-05-26 21:30:20 +05301691
1692 if (eHAL_STATUS_SUCCESS != sme_SetLinkLayerStatsIndCB(
1693 pHddCtx->hHal,
Dino Mycled3d50022014-07-07 12:58:25 +05301694 hdd_link_layer_stats_ind_callback))
Sunil Duttc69bccb2014-05-26 21:30:20 +05301695 {
1696 hddLog(VOS_TRACE_LEVEL_ERROR, "%s:"
1697 "sme_SetLinkLayerStatsIndCB Failed", __func__);
Sunil Duttc69bccb2014-05-26 21:30:20 +05301698 return -EINVAL;
1699
1700 }
1701 if (eHAL_STATUS_SUCCESS != sme_LLStatsSetReq( pHddCtx->hHal,
Dino Mycledf0a5d92014-07-04 09:41:55 +05301702 &linkLayerStatsSetReq))
Sunil Duttc69bccb2014-05-26 21:30:20 +05301703 {
1704 hddLog(VOS_TRACE_LEVEL_ERROR, "%s:"
1705 "sme_LLStatsSetReq Failed", __func__);
Sunil Duttc69bccb2014-05-26 21:30:20 +05301706 return -EINVAL;
1707 }
1708
1709 pAdapter->isLinkLayerStatsSet = 1;
1710
1711 return 0;
1712}
1713
1714const struct
1715nla_policy
1716qca_wlan_vendor_ll_get_policy[QCA_WLAN_VENDOR_ATTR_LL_STATS_GET_MAX +1] =
1717{
1718 /* Unsigned 32bit value provided by the caller issuing the GET stats
1719 * command. When reporting
1720 * the stats results, the driver uses the same value to indicate
1721 * which GET request the results
1722 * correspond to.
1723 */
1724 [QCA_WLAN_VENDOR_ATTR_LL_STATS_GET_CONFIG_REQ_ID] = { .type = NLA_U32 },
1725
1726 /* Unsigned 32bit value . bit mask to identify what statistics are
1727 requested for retrieval */
1728 [QCA_WLAN_VENDOR_ATTR_LL_STATS_GET_CONFIG_REQ_MASK] = { .type = NLA_U32 },
1729};
1730
1731static int wlan_hdd_cfg80211_ll_stats_get(struct wiphy *wiphy,
1732 struct wireless_dev *wdev,
1733 void *data,
1734 int data_len)
1735{
1736 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
1737 struct nlattr *tb_vendor[QCA_WLAN_VENDOR_ATTR_LL_STATS_GET_MAX + 1];
Dino Mycledf0a5d92014-07-04 09:41:55 +05301738 tSirLLStatsGetReq linkLayerStatsGetReq;
Sunil Duttc69bccb2014-05-26 21:30:20 +05301739 struct net_device *dev = wdev->netdev;
1740 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
1741 int status;
1742
1743 status = wlan_hdd_validate_context(pHddCtx);
1744 if (0 != status)
1745 {
1746 hddLog(VOS_TRACE_LEVEL_ERROR,
1747 FL("HDD context is not valid"));
1748 return -EINVAL ;
1749 }
1750
1751 if (NULL == pAdapter)
1752 {
1753 hddLog(VOS_TRACE_LEVEL_FATAL,
1754 "%s: HDD adapter is Null", __func__);
1755 return -ENODEV;
1756 }
Dino Mycledf0a5d92014-07-04 09:41:55 +05301757 /* check the LLStats Capability */
1758 if ( (TRUE != pHddCtx->cfg_ini->fEnableLLStats) ||
1759 (TRUE != sme_IsFeatureSupportedByFW(LINK_LAYER_STATS_MEAS)))
1760 {
1761 hddLog(VOS_TRACE_LEVEL_ERROR,
1762 FL("Link Layer Statistics not supported by Firmware"));
1763 return -EINVAL;
1764 }
1765
Sunil Duttc69bccb2014-05-26 21:30:20 +05301766
1767 if (!pAdapter->isLinkLayerStatsSet)
1768 {
1769 hddLog(VOS_TRACE_LEVEL_FATAL,
1770 "%s: isLinkLayerStatsSet : %d",
1771 __func__, pAdapter->isLinkLayerStatsSet);
1772 return -EINVAL;
1773 }
1774
1775 if (nla_parse(tb_vendor, QCA_WLAN_VENDOR_ATTR_LL_STATS_GET_MAX,
1776 (struct nlattr *)data,
1777 data_len, qca_wlan_vendor_ll_get_policy))
1778 {
1779 hddLog(VOS_TRACE_LEVEL_ERROR, FL() );
1780 return -EINVAL;
1781 }
1782
1783 if (!tb_vendor
1784 [QCA_WLAN_VENDOR_ATTR_LL_STATS_GET_CONFIG_REQ_ID])
1785 {
1786 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Request Id Not present"));
1787 return -EINVAL;
1788 }
1789
1790 if (!tb_vendor
1791 [QCA_WLAN_VENDOR_ATTR_LL_STATS_GET_CONFIG_REQ_MASK])
1792 {
1793 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Req Mask Not present"));
1794 return -EINVAL;
1795 }
1796
Sunil Duttc69bccb2014-05-26 21:30:20 +05301797
Dino Mycledf0a5d92014-07-04 09:41:55 +05301798 linkLayerStatsGetReq.reqId =
Sunil Duttc69bccb2014-05-26 21:30:20 +05301799 nla_get_u32( tb_vendor[
1800 QCA_WLAN_VENDOR_ATTR_LL_STATS_GET_CONFIG_REQ_ID]);
Dino Mycledf0a5d92014-07-04 09:41:55 +05301801 linkLayerStatsGetReq.paramIdMask =
Sunil Duttc69bccb2014-05-26 21:30:20 +05301802 nla_get_u32( tb_vendor[
1803 QCA_WLAN_VENDOR_ATTR_LL_STATS_GET_CONFIG_REQ_MASK]);
1804
Dino Mycled3d50022014-07-07 12:58:25 +05301805 vos_mem_copy(linkLayerStatsGetReq.macAddr,
1806 pAdapter->macAddressCurrent.bytes, sizeof(v_MACADDR_t));
Sunil Duttc69bccb2014-05-26 21:30:20 +05301807
1808 hddLog(VOS_TRACE_LEVEL_INFO,
Dino Mycledf0a5d92014-07-04 09:41:55 +05301809 "LL_STATS_GET reqId = %d", linkLayerStatsGetReq.reqId);
Sunil Duttc69bccb2014-05-26 21:30:20 +05301810 hddLog(VOS_TRACE_LEVEL_INFO,
Dino Mycled3d50022014-07-07 12:58:25 +05301811 "LL_STATS_GET MAC = %pM", linkLayerStatsGetReq.macAddr);
Sunil Duttc69bccb2014-05-26 21:30:20 +05301812 hddLog(VOS_TRACE_LEVEL_INFO,
1813 "LL_STATS_GET paramIdMask = %d",
Dino Mycledf0a5d92014-07-04 09:41:55 +05301814 linkLayerStatsGetReq.paramIdMask);
Sunil Duttc69bccb2014-05-26 21:30:20 +05301815
1816 if (eHAL_STATUS_SUCCESS != sme_LLStatsGetReq( pHddCtx->hHal,
Dino Mycledf0a5d92014-07-04 09:41:55 +05301817 &linkLayerStatsGetReq))
Sunil Duttc69bccb2014-05-26 21:30:20 +05301818 {
1819 hddLog(VOS_TRACE_LEVEL_ERROR, "%s:"
1820 "sme_LLStatsGetReq Failed", __func__);
Sunil Duttc69bccb2014-05-26 21:30:20 +05301821 return -EINVAL;
1822 }
1823 return 0;
1824}
1825
1826const struct
1827nla_policy
1828qca_wlan_vendor_ll_clr_policy[QCA_WLAN_VENDOR_ATTR_LL_STATS_CLR_MAX +1] =
1829{
1830 [QCA_WLAN_VENDOR_ATTR_LL_STATS_CLR_CONFIG_REQ_MASK] = {.type = NLA_U32 },
1831 [QCA_WLAN_VENDOR_ATTR_LL_STATS_CLR_CONFIG_STOP_REQ] = {.type = NLA_U8 },
1832 [QCA_WLAN_VENDOR_ATTR_LL_STATS_CLR_CONFIG_RSP_MASK] = {.type = NLA_U32 },
1833 [QCA_WLAN_VENDOR_ATTR_LL_STATS_CLR_CONFIG_STOP_RSP] = {.type = NLA_U8 },
1834};
1835
1836static int wlan_hdd_cfg80211_ll_stats_clear(struct wiphy *wiphy,
1837 struct wireless_dev *wdev,
1838 void *data,
1839 int data_len)
1840{
1841 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
1842 struct nlattr *tb_vendor[QCA_WLAN_VENDOR_ATTR_LL_STATS_CLR_MAX + 1];
Dino Mycledf0a5d92014-07-04 09:41:55 +05301843 tSirLLStatsClearReq linkLayerStatsClearReq;
Sunil Duttc69bccb2014-05-26 21:30:20 +05301844 struct net_device *dev = wdev->netdev;
1845 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
1846 u32 statsClearReqMask;
1847 u8 stopReq;
1848 int status;
1849
1850 status = wlan_hdd_validate_context(pHddCtx);
1851 if (0 != status)
1852 {
1853 hddLog(VOS_TRACE_LEVEL_ERROR,
1854 FL("HDD context is not valid"));
1855 return -EINVAL;
1856 }
1857
1858 if (NULL == pAdapter)
1859 {
1860 hddLog(VOS_TRACE_LEVEL_FATAL,
1861 "%s: HDD adapter is Null", __func__);
1862 return -ENODEV;
1863 }
Dino Mycledf0a5d92014-07-04 09:41:55 +05301864 /* check the LLStats Capability */
1865 if ( (TRUE != pHddCtx->cfg_ini->fEnableLLStats) ||
1866 (TRUE != sme_IsFeatureSupportedByFW(LINK_LAYER_STATS_MEAS)))
1867 {
1868 hddLog(VOS_TRACE_LEVEL_ERROR,
1869 FL("Enable LLStats Capability"));
1870 return -EINVAL;
1871 }
Sunil Duttc69bccb2014-05-26 21:30:20 +05301872
1873 if (!pAdapter->isLinkLayerStatsSet)
1874 {
1875 hddLog(VOS_TRACE_LEVEL_FATAL,
1876 "%s: isLinkLayerStatsSet : %d",
1877 __func__, pAdapter->isLinkLayerStatsSet);
1878 return -EINVAL;
1879 }
1880
1881 if (nla_parse(tb_vendor, QCA_WLAN_VENDOR_ATTR_LL_STATS_CLR_MAX,
1882 (struct nlattr *)data,
1883 data_len, qca_wlan_vendor_ll_clr_policy))
1884 {
1885 hddLog(VOS_TRACE_LEVEL_ERROR, FL() );
1886 return -EINVAL;
1887 }
1888
1889 if (!tb_vendor[QCA_WLAN_VENDOR_ATTR_LL_STATS_CLR_CONFIG_REQ_MASK] ||
1890
1891 !tb_vendor[QCA_WLAN_VENDOR_ATTR_LL_STATS_CLR_CONFIG_STOP_REQ])
1892 {
1893 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Error in LL_STATS CLR CONFIG PARA") );
1894 return -EINVAL;
1895
1896 }
1897
Sunil Duttc69bccb2014-05-26 21:30:20 +05301898
Dino Mycledf0a5d92014-07-04 09:41:55 +05301899 statsClearReqMask = linkLayerStatsClearReq.statsClearReqMask =
Sunil Duttc69bccb2014-05-26 21:30:20 +05301900 nla_get_u32(
1901 tb_vendor[QCA_WLAN_VENDOR_ATTR_LL_STATS_CLR_CONFIG_REQ_MASK]);
1902
Dino Mycledf0a5d92014-07-04 09:41:55 +05301903 stopReq = linkLayerStatsClearReq.stopReq =
Sunil Duttc69bccb2014-05-26 21:30:20 +05301904 nla_get_u8(
1905 tb_vendor[QCA_WLAN_VENDOR_ATTR_LL_STATS_CLR_CONFIG_STOP_REQ]);
1906
1907 // Shall take the request Id if the Upper layers pass. 1 For now.
Dino Mycledf0a5d92014-07-04 09:41:55 +05301908 linkLayerStatsClearReq.reqId = 1;
Sunil Duttc69bccb2014-05-26 21:30:20 +05301909
Dino Mycled3d50022014-07-07 12:58:25 +05301910 vos_mem_copy(linkLayerStatsClearReq.macAddr,
1911 pAdapter->macAddressCurrent.bytes, sizeof(v_MACADDR_t));
Sunil Duttc69bccb2014-05-26 21:30:20 +05301912
1913 hddLog(VOS_TRACE_LEVEL_INFO,
Dino Mycledf0a5d92014-07-04 09:41:55 +05301914 "LL_STATS_CLEAR reqId = %d", linkLayerStatsClearReq.reqId);
Sunil Duttc69bccb2014-05-26 21:30:20 +05301915 hddLog(VOS_TRACE_LEVEL_INFO,
Dino Mycled3d50022014-07-07 12:58:25 +05301916 "LL_STATS_CLEAR MAC = %pM", linkLayerStatsClearReq.macAddr);
Sunil Duttc69bccb2014-05-26 21:30:20 +05301917 hddLog(VOS_TRACE_LEVEL_INFO,
1918 "LL_STATS_CLEAR statsClearReqMask = 0x%X",
Dino Mycledf0a5d92014-07-04 09:41:55 +05301919 linkLayerStatsClearReq.statsClearReqMask);
Sunil Duttc69bccb2014-05-26 21:30:20 +05301920 hddLog(VOS_TRACE_LEVEL_INFO,
1921 "LL_STATS_CLEAR stopReq = %d",
Dino Mycledf0a5d92014-07-04 09:41:55 +05301922 linkLayerStatsClearReq.stopReq);
Sunil Duttc69bccb2014-05-26 21:30:20 +05301923
1924 if (eHAL_STATUS_SUCCESS == sme_LLStatsClearReq(pHddCtx->hHal,
Dino Mycledf0a5d92014-07-04 09:41:55 +05301925 &linkLayerStatsClearReq))
Sunil Duttc69bccb2014-05-26 21:30:20 +05301926 {
1927 struct sk_buff *temp_skbuff;
1928 temp_skbuff = cfg80211_vendor_cmd_alloc_reply_skb(wiphy,
1929 2 * sizeof(u32) +
1930 NLMSG_HDRLEN);
1931
1932 if (temp_skbuff != NULL)
1933 {
1934
1935 if (nla_put_u32(temp_skbuff,
1936 QCA_WLAN_VENDOR_ATTR_LL_STATS_CLR_CONFIG_RSP_MASK,
1937 statsClearReqMask) ||
1938 nla_put_u32(temp_skbuff,
1939 QCA_WLAN_VENDOR_ATTR_LL_STATS_CLR_CONFIG_STOP_RSP,
1940 stopReq))
1941 {
1942 hddLog(VOS_TRACE_LEVEL_ERROR, FL("LL_STATS_CLR put fail"));
1943 kfree_skb(temp_skbuff);
1944 return -EINVAL;
1945 }
1946 /* If the ask is to stop the stats collection as part of clear
1947 * (stopReq = 1) , ensure that no further requests of get
1948 * go to the firmware by having isLinkLayerStatsSet set to 0.
1949 * However it the stopReq as part of the clear request is 0 ,
Dino Mycledf0a5d92014-07-04 09:41:55 +05301950 * the request to get the statistics are honoured as in this
Sunil Duttc69bccb2014-05-26 21:30:20 +05301951 * case the firmware is just asked to clear the statistics.
1952 */
Dino Mycledf0a5d92014-07-04 09:41:55 +05301953 if (linkLayerStatsClearReq.stopReq == 1)
Sunil Duttc69bccb2014-05-26 21:30:20 +05301954 pAdapter->isLinkLayerStatsSet = 0;
1955 return cfg80211_vendor_cmd_reply(temp_skbuff);
1956 }
1957 return -ENOMEM;
1958 }
Sunil Duttc69bccb2014-05-26 21:30:20 +05301959 return -EINVAL;
1960}
1961#endif /* WLAN_FEATURE_LINK_LAYER_STATS */
1962
Dino Mycle6fb96c12014-06-10 11:52:40 +05301963#ifdef WLAN_FEATURE_EXTSCAN
1964static const struct nla_policy
1965wlan_hdd_extscan_config_policy
1966 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX + 1] =
1967{
1968 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_REQUEST_ID] =
1969 { .type = NLA_U32 },
1970 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_GET_VALID_CHANNELS_CONFIG_PARAM_WIFI_BAND] =
1971 { .type = NLA_U32 },
1972 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_CHANNEL_SPEC_CHANNEL] = { .type = NLA_U32 },
1973 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_CHANNEL_SPEC_DWELL_TIME] =
1974 { .type = NLA_U32 },
1975 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_CHANNEL_SPEC_PASSIVE] = { .type = NLA_U8 },
1976 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_CHANNEL_SPEC_CLASS] = { .type = NLA_U8 },
1977
1978 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_INDEX] = { .type = NLA_U8 },
1979 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_BAND] = { .type = NLA_U8 },
1980 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_PERIOD] = { .type = NLA_U32 },
1981 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_REPORT_EVENTS] =
1982 { .type = NLA_U8 },
1983 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_NUM_CHANNEL_SPECS] =
1984 { .type = NLA_U32 },
1985 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_SCAN_CMD_PARAMS_BASE_PERIOD] =
1986 { .type = NLA_U32 },
1987 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_SCAN_CMD_PARAMS_MAX_AP_PER_SCAN] =
1988 { .type = NLA_U32 },
1989 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_SCAN_CMD_PARAMS_REPORT_THRESHOLD] =
1990 { .type = NLA_U8 },
1991 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_SCAN_CMD_PARAMS_NUM_BUCKETS] =
1992 { .type = NLA_U8 },
1993 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_GET_CACHED_SCAN_RESULTS_CONFIG_PARAM_FLUSH] =
1994 { .type = NLA_U8 },
1995
1996 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_GET_CACHED_SCAN_RESULTS_CONFIG_PARAM_MAX] =
1997 { .type = NLA_U32 },
1998 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_AP_THRESHOLD_PARAM_BSSID] =
1999 { .type = NLA_UNSPEC },
2000 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_AP_THRESHOLD_PARAM_RSSI_LOW] =
2001 { .type = NLA_S32 },
2002 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_AP_THRESHOLD_PARAM_RSSI_HIGH] =
2003 { .type = NLA_S32 },
2004 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_AP_THRESHOLD_PARAM_CHANNEL] =
2005 { .type = NLA_U32 },
2006 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_BSSID_HOTLIST_PARAMS_NUM_AP] =
2007 { .type = NLA_U32 },
2008 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_SIGNIFICANT_CHANGE_PARAMS_RSSI_SAMPLE_SIZE] =
2009 { .type = NLA_U32 },
2010 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_SIGNIFICANT_CHANGE_PARAMS_LOST_AP_SAMPLE_SIZE]
2011 = { .type = NLA_U32 },
2012 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_SIGNIFICANT_CHANGE_PARAMS_MIN_BREACHING] =
2013 { .type = NLA_U32 },
2014 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_SIGNIFICANT_CHANGE_PARAMS_NUM_AP] = { .type =
2015 NLA_U32 },
2016};
2017
2018static void wlan_hdd_cfg80211_extscan_get_capabilities_ind(void *ctx, void *pMsg)
2019{
2020 hdd_context_t *pHddCtx = (hdd_context_t *)ctx;
2021 struct sk_buff *skb = NULL;
2022 tpSirEXTScanCapabilitiesEvent pData =
2023 (tpSirEXTScanCapabilitiesEvent) pMsg;
2024
2025 if (wlan_hdd_validate_context(pHddCtx) || !pData) {
2026 hddLog(VOS_TRACE_LEVEL_ERROR, FL("HDD context is not valid "
2027 "or pData(%p) is null"), pData);
2028 return;
2029 }
2030
2031 skb = cfg80211_vendor_event_alloc(pHddCtx->wiphy,
2032 EXTSCAN_EVENT_BUF_SIZE + NLMSG_HDRLEN,
2033 QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_GET_CAPABILITIES_INDEX,
2034 GFP_KERNEL);
2035
2036 if (!skb) {
2037 hddLog(VOS_TRACE_LEVEL_ERROR,
2038 FL("cfg80211_vendor_event_alloc failed"));
2039 return;
2040 }
2041
2042 hddLog(VOS_TRACE_LEVEL_INFO, "Req Id (%u)", pData->requestId);
2043 hddLog(VOS_TRACE_LEVEL_INFO, "Scan cache size (%u)", pData->scanCacheSize);
2044 hddLog(VOS_TRACE_LEVEL_INFO, "Scan buckets (%u)", pData->scanBuckets);
2045 hddLog(VOS_TRACE_LEVEL_INFO, "Max AP per scan (%u)", pData->maxApPerScan);
2046 hddLog(VOS_TRACE_LEVEL_INFO, "maxRssiSampleSize (%u)",
2047 pData->maxRssiSampleSize);
2048 hddLog(VOS_TRACE_LEVEL_INFO, "maxScanReportingThreshold (%u)",
2049 pData->maxScanReportingThreshold);
2050 hddLog(VOS_TRACE_LEVEL_INFO, "maxHotlistAPs (%u)", pData->maxHotlistAPs);
2051 hddLog(VOS_TRACE_LEVEL_INFO, "maxSignificantWifiChangeAPs (%u)",
2052 pData->maxSignificantWifiChangeAPs);
2053 hddLog(VOS_TRACE_LEVEL_INFO, "maxBsidHistoryEntries (%u)",
2054 pData->maxBsidHistoryEntries);
2055
2056 if (nla_put_u32(skb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_REQUEST_ID,
2057 pData->requestId) ||
2058 nla_put_u32(skb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_STATUS, pData->status) ||
2059 nla_put_u32(skb,
2060 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_CAPABILITIES_MAX_SCAN_CACHE_SIZE,
2061 pData->scanCacheSize) ||
2062 nla_put_u32(skb,
2063 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_CAPABILITIES_MAX_SCAN_BUCKETS,
2064 pData->scanBuckets) ||
2065 nla_put_u32(skb,
2066 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_CAPABILITIES_MAX_AP_CACHE_PER_SCAN,
2067 pData->maxApPerScan) ||
2068 nla_put_u32(skb,
2069 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_CAPABILITIES_MAX_RSSI_SAMPLE_SIZE,
2070 pData->maxRssiSampleSize) ||
2071 nla_put_u32(skb,
2072 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_CAPABILITIES_MAX_SCAN_REPORTING_THRESHOLD,
2073 pData->maxScanReportingThreshold) ||
2074 nla_put_u32(skb,
2075 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_CAPABILITIES_MAX_HOTLIST_APS,
2076 pData->maxHotlistAPs) ||
2077 nla_put_u32(skb,
2078 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_CAPABILITIES_MAX_SIGNIFICANT_WIFI_CHANGE_APS,
2079 pData->maxSignificantWifiChangeAPs) ||
2080 nla_put_u32(skb,
2081 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_CAPABILITIES_MAX_BSSID_HISTORY_ENTRIES,
2082 pData->maxBsidHistoryEntries)) {
2083 hddLog(VOS_TRACE_LEVEL_ERROR, FL("nla put fail"));
2084 goto nla_put_failure;
2085 }
2086
2087 cfg80211_vendor_event(skb, GFP_KERNEL);
2088 return;
2089
2090nla_put_failure:
2091 kfree_skb(skb);
2092 return;
2093}
2094
2095
2096static void wlan_hdd_cfg80211_extscan_start_rsp(void *ctx, void *pMsg)
2097{
2098 tpSirEXTScanStartRspParams pData = (tpSirEXTScanStartRspParams) pMsg;
2099 hdd_context_t *pHddCtx = (hdd_context_t *)ctx;
2100 struct sk_buff *skb = NULL;
2101 tpAniSirGlobal pMac = PMAC_STRUCT( pHddCtx->hHal );
2102
2103
2104 if (wlan_hdd_validate_context(pHddCtx) || !pData) {
2105 hddLog(VOS_TRACE_LEVEL_ERROR, FL("HDD context is not valid "
2106 "or pData(%p) is null"), pData);
2107 return;
2108 }
2109
2110 skb = cfg80211_vendor_event_alloc(pHddCtx->wiphy,
2111 EXTSCAN_EVENT_BUF_SIZE + NLMSG_HDRLEN,
2112 QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_START_INDEX,
2113 GFP_KERNEL);
2114
2115 if (!skb) {
2116 hddLog(VOS_TRACE_LEVEL_ERROR,
2117 FL("cfg80211_vendor_event_alloc failed"));
2118 return;
2119 }
2120 hddLog(VOS_TRACE_LEVEL_INFO, FL("Entering "));
2121 hddLog(VOS_TRACE_LEVEL_INFO, "Req Id (%u)", pData->requestId);
2122 hddLog(VOS_TRACE_LEVEL_INFO, "Status (%u)", pData->status);
2123
2124 if (nla_put_u32(skb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_REQUEST_ID,
2125 pData->requestId) ||
2126 nla_put_u32(skb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_STATUS, pData->status)) {
2127 hddLog(VOS_TRACE_LEVEL_ERROR, FL("nla put fail"));
2128 goto nla_put_failure;
2129 }
2130
2131 /*
2132 * Store the Request ID for comparing with the requestID obtained
2133 * in other requests.HDD shall return a failure is the extscan_stop
2134 * request is issued with a different requestId as that of the
2135 * extscan_start request. Also, This requestId shall be used while
2136 * indicating the full scan results to the upper layers.
2137 * The requestId is stored with the assumption that the firmware
2138 * shall return the ext scan start request's requestId in ext scan
2139 * start response.
2140 */
2141 if (pData->status == 0)
2142 pMac->sme.extScanStartReqId = pData->requestId;
2143
2144
2145 cfg80211_vendor_event(skb, GFP_KERNEL);
2146 return;
2147
2148nla_put_failure:
2149 kfree_skb(skb);
2150 return;
2151}
2152
2153
2154static void wlan_hdd_cfg80211_extscan_stop_rsp(void *ctx, void *pMsg)
2155{
2156 tpSirEXTScanStopRspParams pData = (tpSirEXTScanStopRspParams) pMsg;
2157 hdd_context_t *pHddCtx = (hdd_context_t *)ctx;
2158 struct sk_buff *skb = NULL;
2159
2160 if (wlan_hdd_validate_context(pHddCtx) || !pData) {
2161 hddLog(VOS_TRACE_LEVEL_ERROR, FL("HDD context is not valid "
2162 "or pData(%p) is null"), pData);
2163 return;
2164 }
2165
2166 skb = cfg80211_vendor_event_alloc(pHddCtx->wiphy,
2167 EXTSCAN_EVENT_BUF_SIZE + NLMSG_HDRLEN,
2168 QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_STOP_INDEX,
2169 GFP_KERNEL);
2170
2171 if (!skb) {
2172 hddLog(VOS_TRACE_LEVEL_ERROR,
2173 FL("cfg80211_vendor_event_alloc failed"));
2174 return;
2175 }
2176 hddLog(VOS_TRACE_LEVEL_INFO, FL("Entering "));
2177 hddLog(VOS_TRACE_LEVEL_INFO, "Req Id (%u)", pData->requestId);
2178
2179 if (nla_put_u32(skb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_REQUEST_ID,
2180 pData->requestId) ||
2181 nla_put_u32(skb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_STATUS, pData->status)) {
2182 hddLog(VOS_TRACE_LEVEL_ERROR, FL("nla put fail"));
2183 goto nla_put_failure;
2184 }
2185
2186 cfg80211_vendor_event(skb, GFP_KERNEL);
2187 return;
2188
2189nla_put_failure:
2190 kfree_skb(skb);
2191 return;
2192}
2193
2194
2195static void wlan_hdd_cfg80211_extscan_set_bss_hotlist_rsp(void *ctx,
2196 void *pMsg)
2197{
2198 hdd_context_t *pHddCtx = (hdd_context_t *)ctx;
2199 struct sk_buff *skb = NULL;
2200 tpSirEXTScanSetBssidHotListRspParams pData =
2201 (tpSirEXTScanSetBssidHotListRspParams) pMsg;
2202
2203 if (wlan_hdd_validate_context(pHddCtx) || !pData) {
2204 hddLog(VOS_TRACE_LEVEL_ERROR, FL("HDD context is not valid "
2205 "or pData(%p) is null"), pData);
2206 return;
2207 }
2208 skb = cfg80211_vendor_event_alloc(pHddCtx->wiphy,
2209 EXTSCAN_EVENT_BUF_SIZE + NLMSG_HDRLEN,
2210 QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_SET_BSSID_HOTLIST_INDEX,
2211 GFP_KERNEL);
2212
2213 if (!skb) {
2214 hddLog(VOS_TRACE_LEVEL_ERROR,
2215 FL("cfg80211_vendor_event_alloc failed"));
2216 return;
2217 }
2218 hddLog(VOS_TRACE_LEVEL_INFO, FL("Entering "));
2219 hddLog(VOS_TRACE_LEVEL_INFO, "Req Id (%u)", pData->requestId);
2220 hddLog(VOS_TRACE_LEVEL_INFO, "Status (%u)", pData->status);
2221
2222 if (nla_put_u32(skb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_REQUEST_ID,
2223 pData->requestId) ||
2224 nla_put_u32(skb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_STATUS, pData->status)) {
2225 hddLog(VOS_TRACE_LEVEL_ERROR, FL("nla put fail"));
2226 goto nla_put_failure;
2227 }
2228
2229 cfg80211_vendor_event(skb, GFP_KERNEL);
2230 return;
2231
2232nla_put_failure:
2233 kfree_skb(skb);
2234 return;
2235}
2236
2237static void wlan_hdd_cfg80211_extscan_reset_bss_hotlist_rsp(void *ctx,
2238 void *pMsg)
2239{
2240 hdd_context_t *pHddCtx = (hdd_context_t *)ctx;
2241 struct sk_buff *skb = NULL;
2242 tpSirEXTScanResetBssidHotlistRspParams pData =
2243 (tpSirEXTScanResetBssidHotlistRspParams) pMsg;
2244
2245 if (wlan_hdd_validate_context(pHddCtx) || !pData) {
2246 hddLog(VOS_TRACE_LEVEL_ERROR, FL("HDD context is not valid "
2247 "or pData(%p) is null"), pData);
2248 return;
2249 }
2250
2251 skb = cfg80211_vendor_event_alloc(pHddCtx->wiphy,
2252 EXTSCAN_EVENT_BUF_SIZE + NLMSG_HDRLEN,
2253 QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_RESET_BSSID_HOTLIST_INDEX,
2254 GFP_KERNEL);
2255
2256 if (!skb) {
2257 hddLog(VOS_TRACE_LEVEL_ERROR,
2258 FL("cfg80211_vendor_event_alloc failed"));
2259 return;
2260 }
2261 hddLog(VOS_TRACE_LEVEL_INFO, FL("Entering "));
2262 hddLog(VOS_TRACE_LEVEL_INFO, "Req Id (%u)", pData->requestId);
2263
2264 if (nla_put_u32(skb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_REQUEST_ID,
2265 pData->requestId) ||
2266 nla_put_u32(skb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_STATUS, pData->status)) {
2267 hddLog(VOS_TRACE_LEVEL_ERROR, FL("nla put fail"));
2268 goto nla_put_failure;
2269 }
2270
2271 cfg80211_vendor_event(skb, GFP_KERNEL);
2272 return;
2273
2274nla_put_failure:
2275 kfree_skb(skb);
2276 return;
2277}
2278
2279
2280static void wlan_hdd_cfg80211_extscan_set_signf_wifi_change_rsp(void *ctx,
2281 void *pMsg)
2282{
2283 hdd_context_t *pHddCtx = (hdd_context_t *)ctx;
2284 struct sk_buff *skb = NULL;
2285 tpSirEXTScanSetSignificantChangeRspParams pData =
2286 (tpSirEXTScanSetSignificantChangeRspParams) pMsg;
2287
2288 if (wlan_hdd_validate_context(pHddCtx) || !pData) {
2289 hddLog(VOS_TRACE_LEVEL_ERROR, FL("HDD context is not valid "
2290 "or pData(%p) is null"), pData);
2291 return;
2292 }
2293
2294 skb = cfg80211_vendor_event_alloc(pHddCtx->wiphy,
2295 EXTSCAN_EVENT_BUF_SIZE + NLMSG_HDRLEN,
2296 QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_SET_SIGNIFICANT_CHANGE_INDEX,
2297 GFP_KERNEL);
2298
2299 if (!skb) {
2300 hddLog(VOS_TRACE_LEVEL_ERROR,
2301 FL("cfg80211_vendor_event_alloc failed"));
2302 return;
2303 }
2304 hddLog(VOS_TRACE_LEVEL_INFO, FL("Entering "));
2305 hddLog(VOS_TRACE_LEVEL_INFO, "Req Id (%u)", pData->requestId);
2306 hddLog(VOS_TRACE_LEVEL_INFO, "Status (%u)", pData->status);
2307
2308 if (nla_put_u32(skb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_REQUEST_ID,
2309 pData->requestId) ||
2310 nla_put_u32(skb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_STATUS, pData->status)) {
2311 hddLog(VOS_TRACE_LEVEL_ERROR, FL("nla put fail"));
2312 goto nla_put_failure;
2313 }
2314
2315 cfg80211_vendor_event(skb, GFP_KERNEL);
2316 return;
2317
2318nla_put_failure:
2319 kfree_skb(skb);
2320 return;
2321}
2322
2323
2324static void wlan_hdd_cfg80211_extscan_reset_signf_wifi_change_rsp(void *ctx,
2325 void *pMsg)
2326{
2327 hdd_context_t *pHddCtx = (hdd_context_t *)ctx;
2328 struct sk_buff *skb = NULL;
2329 tpSirEXTScanResetSignificantChangeRspParams pData =
2330 (tpSirEXTScanResetSignificantChangeRspParams) pMsg;
2331
2332 if (wlan_hdd_validate_context(pHddCtx) || !pData) {
2333 hddLog(VOS_TRACE_LEVEL_ERROR, FL("HDD context is not valid "
2334 "or pData(%p) is null"), pData);
2335 return;
2336 }
2337
2338 skb = cfg80211_vendor_event_alloc(pHddCtx->wiphy,
2339 EXTSCAN_EVENT_BUF_SIZE + NLMSG_HDRLEN,
2340 QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_RESET_SIGNIFICANT_CHANGE_INDEX,
2341 GFP_KERNEL);
2342
2343 if (!skb) {
2344 hddLog(VOS_TRACE_LEVEL_ERROR,
2345 FL("cfg80211_vendor_event_alloc failed"));
2346 return;
2347 }
2348 hddLog(VOS_TRACE_LEVEL_INFO, FL("Entering "));
2349 hddLog(VOS_TRACE_LEVEL_INFO, "Req Id (%u)", pData->requestId);
2350 hddLog(VOS_TRACE_LEVEL_INFO, "Status (%u)", pData->status);
2351
2352 if (nla_put_u32(skb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_REQUEST_ID,
2353 pData->requestId) ||
2354 nla_put_u32(skb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_STATUS, pData->status)) {
2355 hddLog(VOS_TRACE_LEVEL_ERROR, FL("nla put fail"));
2356 goto nla_put_failure;
2357 }
2358
2359 cfg80211_vendor_event(skb, GFP_KERNEL);
2360 return;
2361
2362nla_put_failure:
2363 kfree_skb(skb);
2364 return;
2365}
2366
2367static void wlan_hdd_cfg80211_extscan_cached_results_ind(void *ctx,
2368 void *pMsg)
2369{
2370 hdd_context_t *pHddCtx = (hdd_context_t *)ctx;
2371 struct sk_buff *skb = NULL;
2372 tANI_U32 i = 0, j, resultsPerEvent;
2373 tANI_S32 totalResults;
2374 tpSirWifiScanResultEvent pData = (tpSirWifiScanResultEvent) pMsg;
2375 tpSirWifiScanResult pSirWifiScanResult;
2376
2377 if (wlan_hdd_validate_context(pHddCtx) || !pData) {
2378 hddLog(VOS_TRACE_LEVEL_ERROR, FL("HDD context is not valid "
2379 "or pData(%p) is null"), pData);
2380 return;
2381 }
2382 totalResults = pData->numOfAps;
2383 hddLog(VOS_TRACE_LEVEL_INFO, "Req Id (%u)", pData->requestId);
2384 hddLog(VOS_TRACE_LEVEL_INFO, "Num results (%u)", pData->numOfAps);
2385 hddLog(VOS_TRACE_LEVEL_INFO, "More Data (%u)", pData->moreData);
2386
2387 do{
2388 resultsPerEvent = ((totalResults >= EXTSCAN_MAX_CACHED_RESULTS_PER_IND) ?
2389 EXTSCAN_MAX_CACHED_RESULTS_PER_IND : totalResults);
2390 totalResults -= EXTSCAN_MAX_CACHED_RESULTS_PER_IND;
2391
2392 skb = cfg80211_vendor_event_alloc(pHddCtx->wiphy,
2393 EXTSCAN_EVENT_BUF_SIZE + NLMSG_HDRLEN,
2394 QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_GET_CACHED_RESULTS_INDEX,
2395 GFP_KERNEL);
2396
2397 if (!skb) {
2398 hddLog(VOS_TRACE_LEVEL_ERROR,
2399 FL("cfg80211_vendor_event_alloc failed"));
2400 return;
2401 }
2402
2403 hddLog(VOS_TRACE_LEVEL_INFO, "resultsPerEvent (%u)", resultsPerEvent);
2404
2405 if (nla_put_u32(skb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_REQUEST_ID,
2406 pData->requestId) ||
2407 nla_put_u32(skb,
2408 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_NUM_RESULTS_AVAILABLE,
2409 resultsPerEvent)) {
2410 hddLog(VOS_TRACE_LEVEL_ERROR, FL("put fail"));
2411 goto fail;
2412 }
2413 if (nla_put_u8(skb,
2414 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_MORE_DATA,
2415 pData->moreData ? 1 : (totalResults > 0 ? 1 : 0 )))
2416 {
2417 hddLog(VOS_TRACE_LEVEL_ERROR, FL("put fail"));
2418 goto fail;
2419 }
2420
2421 if (resultsPerEvent) {
2422 struct nlattr *aps;
2423
2424 aps = nla_nest_start(skb,
2425 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_LIST);
2426 if (!aps)
2427 {
2428 hddLog(VOS_TRACE_LEVEL_ERROR, FL("put fail"));
2429 goto fail;
2430 }
2431
2432 for (j = 0; j < resultsPerEvent; j++, i++) {
2433 struct nlattr *ap;
2434 pSirWifiScanResult = (tpSirWifiScanResult) ((tANI_U8 *)
2435 pData->ap + ( i* sizeof(tSirWifiScanResult)));
2436
2437 hddLog(VOS_TRACE_LEVEL_INFO, "[index=%u] Timestamp(%llu) "
2438 "Ssid (%s)"
2439 "Bssid: %pM "
2440 "Channel (%u)"
2441 "Rssi (%d)"
2442 "RTT (%u)"
2443 "RTT_SD (%u)",
2444 i,
2445 pSirWifiScanResult->ts,
2446 pSirWifiScanResult->ssid,
2447 pSirWifiScanResult->bssid,
2448 pSirWifiScanResult->channel,
2449 pSirWifiScanResult->rssi,
2450 pSirWifiScanResult->rtt,
2451 pSirWifiScanResult->rtt_sd);
2452
2453 ap = nla_nest_start(skb, j + 1);
2454 if (!ap)
2455 {
2456 hddLog(VOS_TRACE_LEVEL_ERROR, FL("put fail"));
2457 goto fail;
2458 }
2459
2460 if (nla_put_u64(skb,
2461 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_TIME_STAMP,
2462 pSirWifiScanResult->ts) )
2463 {
2464 hddLog(VOS_TRACE_LEVEL_ERROR, FL("put fail"));
2465 goto fail;
2466 }
2467 if (nla_put(skb,
2468 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_SSID,
2469 sizeof(pSirWifiScanResult->ssid),
2470 pSirWifiScanResult->ssid) )
2471 {
2472 hddLog(VOS_TRACE_LEVEL_ERROR, FL("put fail"));
2473 goto fail;
2474 }
2475 if (nla_put(skb,
2476 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_BSSID,
2477 sizeof(pSirWifiScanResult->bssid),
2478 pSirWifiScanResult->bssid) )
2479 {
2480 hddLog(VOS_TRACE_LEVEL_ERROR, FL("put fail"));
2481 goto fail;
2482 }
2483 if (nla_put_u32(skb,
2484 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_CHANNEL,
2485 pSirWifiScanResult->channel) )
2486 {
2487 hddLog(VOS_TRACE_LEVEL_ERROR, FL("put fail"));
2488 goto fail;
2489 }
2490 if (nla_put_u32(skb,
2491 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_RSSI,
2492 pSirWifiScanResult->rssi) )
2493 {
2494 hddLog(VOS_TRACE_LEVEL_ERROR, FL("put fail"));
2495 goto fail;
2496 }
2497 if (nla_put_u32(skb,
2498 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_RTT,
2499 pSirWifiScanResult->rtt) )
2500 {
2501 hddLog(VOS_TRACE_LEVEL_ERROR, FL("put fail"));
2502 goto fail;
2503 }
2504 if (nla_put_u32(skb,
2505 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_RTT_SD,
2506 pSirWifiScanResult->rtt_sd))
2507 {
2508 hddLog(VOS_TRACE_LEVEL_ERROR, FL("put fail"));
2509 goto fail;
2510 }
2511
2512 nla_nest_end(skb, ap);
2513 }
2514 nla_nest_end(skb, aps);
2515
2516 }
2517 cfg80211_vendor_event(skb, GFP_KERNEL);
2518 } while (totalResults > 0);
2519
2520 return;
2521fail:
2522 kfree_skb(skb);
2523 return;
2524}
2525
2526static void wlan_hdd_cfg80211_extscan_hotlist_match_ind(void *ctx,
2527 void *pMsg)
2528{
2529 tpSirWifiScanResultEvent pData = (tpSirWifiScanResultEvent) pMsg;
2530 hdd_context_t *pHddCtx = (hdd_context_t *)ctx;
2531 struct sk_buff *skb = NULL;
2532 tANI_U32 i;
2533
2534 if (wlan_hdd_validate_context(pHddCtx) || !pData) {
2535 hddLog(VOS_TRACE_LEVEL_ERROR, FL("HDD context is not valid "
2536 "or pData(%p) is null"), pData);
2537 return;
2538 }
2539
2540 skb = cfg80211_vendor_event_alloc(pHddCtx->wiphy,
2541 EXTSCAN_EVENT_BUF_SIZE + NLMSG_HDRLEN,
2542 QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_HOTLIST_AP_FOUND_INDEX,
2543 GFP_KERNEL);
2544
2545 if (!skb) {
2546 hddLog(VOS_TRACE_LEVEL_ERROR,
2547 FL("cfg80211_vendor_event_alloc failed"));
2548 return;
2549 }
2550 hddLog(VOS_TRACE_LEVEL_INFO, FL("Entering "));
2551 hddLog(VOS_TRACE_LEVEL_INFO, "Req Id (%u)", pData->requestId);
2552 hddLog(VOS_TRACE_LEVEL_INFO, "Num results (%u)", pData->numOfAps);
2553 hddLog(VOS_TRACE_LEVEL_INFO, "More Data (%u)", pData->moreData);
2554
2555 for (i = 0; i < pData->numOfAps; i++) {
2556 hddLog(VOS_TRACE_LEVEL_INFO, "[index=%u] Timestamp(0x%lld) "
2557 "Ssid (%s) "
2558 "Bssid (" MAC_ADDRESS_STR ") "
2559 "Channel (%u) "
2560 "Rssi (%d) "
2561 "RTT (%u) "
2562 "RTT_SD (%u) ",
2563 i,
2564 pData->ap[i].ts,
2565 pData->ap[i].ssid,
2566 MAC_ADDR_ARRAY(pData->ap[i].bssid),
2567 pData->ap[i].channel,
2568 pData->ap[i].rssi,
2569 pData->ap[i].rtt,
2570 pData->ap[i].rtt_sd);
2571 }
2572
2573 if (nla_put_u32(skb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_REQUEST_ID,
2574 pData->requestId) ||
2575 nla_put_u32(skb,
2576 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_NUM_RESULTS_AVAILABLE,
2577 pData->numOfAps)) {
2578 hddLog(VOS_TRACE_LEVEL_ERROR, FL("put fail"));
2579 goto fail;
2580 }
2581 if (pData->numOfAps) {
2582 struct nlattr *aps;
2583
2584 aps = nla_nest_start(skb,
2585 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_LIST);
2586 if (!aps)
2587 goto fail;
2588
2589 for (i = 0; i < pData->numOfAps; i++) {
2590 struct nlattr *ap;
2591
2592 ap = nla_nest_start(skb, i + 1);
2593 if (!ap)
2594 goto fail;
2595
2596 if (nla_put_u64(skb,
2597 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_TIME_STAMP,
2598 pData->ap[i].ts) ||
2599 nla_put(skb,
2600 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_SSID,
2601 sizeof(pData->ap[i].ssid),
2602 pData->ap[i].ssid) ||
2603 nla_put(skb,
2604 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_BSSID,
2605 sizeof(pData->ap[i].bssid),
2606 pData->ap[i].bssid) ||
2607 nla_put_u32(skb,
2608 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_CHANNEL,
2609 pData->ap[i].channel) ||
2610 nla_put_s32(skb,
2611 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_RSSI,
2612 pData->ap[i].rssi) ||
2613 nla_put_u32(skb,
2614 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_RTT,
2615 pData->ap[i].rtt) ||
2616 nla_put_u32(skb,
2617 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_RTT_SD,
2618 pData->ap[i].rtt_sd))
2619 goto fail;
2620
2621 nla_nest_end(skb, ap);
2622 }
2623 nla_nest_end(skb, aps);
2624
2625 if (nla_put_u8(skb,
2626 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_MORE_DATA,
2627 pData->moreData))
2628 goto fail;
2629 }
2630
2631 cfg80211_vendor_event(skb, GFP_KERNEL);
2632 return;
2633
2634fail:
2635 kfree_skb(skb);
2636 return;
2637
2638}
2639static void wlan_hdd_cfg80211_extscan_signif_wifi_change_results_ind(void *ctx,
2640 void *pMsg)
2641{
2642 hdd_context_t *pHddCtx = (hdd_context_t *)ctx;
2643 struct sk_buff *skb = NULL;
2644 tANI_U32 i, j;
2645 tpSirWifiSignificantChangeEvent pData =
2646 (tpSirWifiSignificantChangeEvent) pMsg;
2647
2648 if (wlan_hdd_validate_context(pHddCtx) || !pData) {
2649 hddLog(VOS_TRACE_LEVEL_ERROR, FL("HDD context is not valid "
2650 "or pData(%p) is null"), pData);
2651 return;
2652 }
2653 skb = cfg80211_vendor_event_alloc(pHddCtx->wiphy,
2654 EXTSCAN_EVENT_BUF_SIZE,
2655 QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_SIGNIFICANT_CHANGE_INDEX,
2656 GFP_KERNEL);
2657
2658 if (!skb) {
2659 hddLog(VOS_TRACE_LEVEL_ERROR,
2660 FL("cfg80211_vendor_event_alloc failed"));
2661 return;
2662 }
2663 hddLog(VOS_TRACE_LEVEL_INFO, FL("Entering "));
2664 hddLog(VOS_TRACE_LEVEL_INFO, "Req Id (%u)", pData->requestId);
2665 hddLog(VOS_TRACE_LEVEL_INFO, "total List Size %u ", pData->numSigRssiBss);
2666 hddLog(VOS_TRACE_LEVEL_INFO, " CUrrent List size (%u)",
2667 pData->numSigRssiBss);
2668 hddLog(VOS_TRACE_LEVEL_INFO, "moreData (%u)", pData->moreData);
2669
2670 for (i = 0; i < pData->numSigRssiBss; i++) {
2671 hddLog(VOS_TRACE_LEVEL_INFO , "Rssi List [%d] BSSID: (%pM) Channel %u "
2672 " num RSSI %u ",
2673 i, pData->sigRssiResult[i].bssid,
2674 pData->sigRssiResult[i].channel,
2675 pData->sigRssiResult[i].numRssi);
2676
2677 for (j = 0; j < pData->sigRssiResult[i].numRssi; j++){
2678
2679 hddLog(VOS_TRACE_LEVEL_INFO,
2680 " [%d]",
Dino Myclec8f3f332014-07-21 16:48:27 +05302681 pData->sigRssiResult[i].rssi[j]);
Dino Mycle6fb96c12014-06-10 11:52:40 +05302682
2683 }
2684 }
2685
2686
2687 if (nla_put_u32(skb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_REQUEST_ID,
2688 pData->requestId) ||
2689 nla_put_u32(skb,
2690 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_NUM_RESULTS_AVAILABLE,
2691 pData->numSigRssiBss)) {
2692 hddLog(VOS_TRACE_LEVEL_ERROR, FL("put fail"));
2693 goto fail;
2694 }
2695
2696 if (pData->numSigRssiBss) {
2697 struct nlattr *aps;
2698 aps = nla_nest_start(skb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_LIST);
2699 if (!aps)
2700 goto fail;
2701 for (i = 0; i < pData->numSigRssiBss; i++) {
2702 struct nlattr *ap;
2703
2704 ap = nla_nest_start(skb, i);
2705 if (!ap)
2706 goto fail;
2707 if (nla_put(skb,
2708 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SIGNIFICANT_CHANGE_RESULT_BSSID,
2709 sizeof(tSirMacAddr), pData->sigRssiResult[i].bssid) ||
2710 nla_put_u32(skb,
2711 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SIGNIFICANT_CHANGE_RESULT_CHANNEL,
2712 pData->sigRssiResult[i].channel) ||
2713 nla_put_u32(skb,
2714 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SIGNIFICANT_CHANGE_RESULT_NUM_RSSI,
2715 pData->sigRssiResult[i].numRssi) ||
2716 nla_put(skb,
2717 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SIGNIFICANT_CHANGE_RESULT_RSSI_LIST,
2718 sizeof(s32) * pData->sigRssiResult[i].numRssi,
2719 pData->sigRssiResult[i].rssi))
2720 goto fail;
2721 nla_nest_end(skb, ap);
2722 }
2723 nla_nest_end(skb, aps);
2724 if (nla_put_u8(skb,
2725 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_MORE_DATA,
2726 pData->moreData))
2727 goto fail;
2728 }
2729 cfg80211_vendor_event(skb, GFP_KERNEL);
2730 return;
2731fail:
2732 kfree_skb(skb);
2733 return;
2734}
2735
2736static void wlan_hdd_cfg80211_extscan_full_scan_result_event(void *ctx,
2737 void *pMsg)
2738{
2739 struct sk_buff *skb;
2740 hdd_context_t *pHddCtx = (hdd_context_t *)ctx;
2741 tpSirWifiFullScanResultEvent pData =
2742 (tpSirWifiFullScanResultEvent) (pMsg);
2743
2744 if (wlan_hdd_validate_context(pHddCtx) || !pData) {
2745 hddLog(VOS_TRACE_LEVEL_ERROR, FL("HDD context is not valid "
2746 "or pData(%p) is null"), pData);
2747 return;
2748 }
2749
2750 skb = cfg80211_vendor_event_alloc(pHddCtx->wiphy,
2751 EXTSCAN_EVENT_BUF_SIZE + NLMSG_HDRLEN,
2752 QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_FULL_SCAN_RESULT_INDEX,
2753 GFP_KERNEL);
2754
2755 if (!skb) {
2756 hddLog(VOS_TRACE_LEVEL_ERROR,
2757 FL("cfg80211_vendor_event_alloc failed"));
2758 return;
2759 }
2760
2761 hddLog(VOS_TRACE_LEVEL_INFO, FL("Entering "));
2762 hddLog(VOS_TRACE_LEVEL_INFO, FL("Req Id (%u)"), pData->requestId);
2763 hddLog(VOS_TRACE_LEVEL_INFO, FL("More Data (%u)"), pData->moreData);
2764 hddLog(VOS_TRACE_LEVEL_INFO, FL("AP Info: Timestamp(0x%llX) "
2765 "Ssid (%s)"
2766 "Bssid (" MAC_ADDRESS_STR ")"
2767 "Channel (%u)"
2768 "Rssi (%d)"
2769 "RTT (%u)"
2770 "RTT_SD (%u)"),
2771 pData->ap.ts,
2772 pData->ap.ssid,
2773 MAC_ADDR_ARRAY(pData->ap.bssid),
2774 pData->ap.channel,
2775 pData->ap.rssi,
2776 pData->ap.rtt,
2777 pData->ap.rtt_sd);
2778 hddLog(VOS_TRACE_LEVEL_INFO, "IE Length (%u)", pData->ieLength);
2779 if (nla_put_u32(skb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_REQUEST_ID,
2780 pData->requestId) ||
2781 nla_put_u64(skb,
2782 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_TIME_STAMP,
2783 pData->ap.ts) ||
2784 nla_put(skb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_SSID,
2785 sizeof(pData->ap.ssid),
2786 pData->ap.ssid) ||
2787 nla_put(skb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_BSSID,
2788 WNI_CFG_BSSID_LEN,
2789 pData->ap.bssid) ||
2790 nla_put_u32(skb,
2791 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_CHANNEL,
2792 pData->ap.channel) ||
2793 nla_put_u32(skb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_RSSI,
2794 pData->ap.rssi) ||
2795 nla_put_u32(skb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_RTT,
2796 pData->ap.rtt) ||
2797 nla_put_u32(skb,
2798 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_RTT_SD,
2799 pData->ap.rtt_sd) ||
2800 nla_put_u16(skb,
2801 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_BEACON_PERIOD,
2802 pData->ap.beaconPeriod) ||
2803 nla_put_u16(skb,
2804 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_CAPABILITY,
2805 pData->ap.capability) ||
2806 nla_put_u32(skb,
2807 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_IE_LENGTH,
2808 pData->ieLength))
2809 {
2810 hddLog(VOS_TRACE_LEVEL_ERROR, FL("nla put fail"));
2811 goto nla_put_failure;
2812 }
2813 if (nla_put(skb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_IE_DATA,
2814 pData->ieLength,
2815 pData->ie))
2816 {
2817 hddLog(VOS_TRACE_LEVEL_ERROR, FL("nla put fail"));
2818 goto nla_put_failure;
2819 }
2820
2821 cfg80211_vendor_event(skb, GFP_KERNEL);
2822 return;
2823
2824nla_put_failure:
2825 kfree_skb(skb);
2826 return;
2827}
2828
2829static void wlan_hdd_cfg80211_extscan_scan_res_available_event(void *ctx,
2830 void *pMsg)
2831{
2832 hdd_context_t *pHddCtx = (hdd_context_t *)ctx;
2833 struct sk_buff *skb = NULL;
2834 tpSirEXTScanResultsAvailableIndParams pData =
2835 (tpSirEXTScanResultsAvailableIndParams) pMsg;
2836
2837 if (wlan_hdd_validate_context(pHddCtx) || !pData) {
2838 hddLog(VOS_TRACE_LEVEL_ERROR, FL("HDD context is not valid "
2839 "or pData(%p) is null"), pData);
2840 return;
2841 }
2842
2843 skb = cfg80211_vendor_event_alloc(pHddCtx->wiphy,
2844 EXTSCAN_EVENT_BUF_SIZE + NLMSG_HDRLEN,
2845 QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_SCAN_RESULTS_AVAILABLE_INDEX,
2846 GFP_KERNEL);
2847
2848 if (!skb) {
2849 hddLog(VOS_TRACE_LEVEL_ERROR,
2850 FL("cfg80211_vendor_event_alloc failed"));
2851 return;
2852 }
2853
2854 hddLog(VOS_TRACE_LEVEL_INFO, FL("Entering "));
2855 hddLog(VOS_TRACE_LEVEL_INFO, "Req Id (%u)", pData->requestId);
2856 hddLog(VOS_TRACE_LEVEL_INFO, "Num results (%u)",
2857 pData->numResultsAvailable);
2858 if (nla_put_u32(skb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_REQUEST_ID,
2859 pData->requestId) ||
2860 nla_put_u32(skb,
2861 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_NUM_RESULTS_AVAILABLE,
2862 pData->numResultsAvailable)) {
2863 hddLog(VOS_TRACE_LEVEL_ERROR, FL("nla put fail"));
2864 goto nla_put_failure;
2865 }
2866
2867 cfg80211_vendor_event(skb, GFP_KERNEL);
2868 return;
2869
2870nla_put_failure:
2871 kfree_skb(skb);
2872 return;
2873}
2874
2875static void wlan_hdd_cfg80211_extscan_scan_progress_event(void *ctx, void *pMsg)
2876{
2877 hdd_context_t *pHddCtx = (hdd_context_t *)ctx;
2878 struct sk_buff *skb = NULL;
2879 tpSirEXTScanProgressIndParams pData =
2880 (tpSirEXTScanProgressIndParams) pMsg;
2881
2882 if (wlan_hdd_validate_context(pHddCtx) || !pData) {
2883 hddLog(VOS_TRACE_LEVEL_ERROR, FL("HDD context is not valid "
2884 "or pData(%p) is null"), pData);
2885 return;
2886 }
2887
2888 skb = cfg80211_vendor_event_alloc(pHddCtx->wiphy,
2889 EXTSCAN_EVENT_BUF_SIZE + NLMSG_HDRLEN,
2890 QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_SCAN_EVENT_INDEX,
2891 GFP_KERNEL);
2892
2893 if (!skb) {
2894 hddLog(VOS_TRACE_LEVEL_ERROR,
2895 FL("cfg80211_vendor_event_alloc failed"));
2896 return;
2897 }
2898 hddLog(VOS_TRACE_LEVEL_INFO, FL("Entering "));
2899 hddLog(VOS_TRACE_LEVEL_INFO, "Scan event type (%u)",
2900 pData->extScanEventType);
2901 hddLog(VOS_TRACE_LEVEL_INFO, "Scan event status (%u)",
2902 pData->status);
2903
2904 if (nla_put_u8(skb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_EVENT_TYPE,
2905 pData->extScanEventType) ||
2906 nla_put_u32(skb,
Dasari Srinivas5a288652014-06-30 17:13:22 +05302907 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_REQUEST_ID,
2908 pData->requestId) ||
2909 nla_put_u32(skb,
Dino Mycle6fb96c12014-06-10 11:52:40 +05302910 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_EVENT_STATUS,
2911 pData->status)) {
2912 hddLog(VOS_TRACE_LEVEL_ERROR, FL("nla put fail"));
2913 goto nla_put_failure;
2914 }
2915
2916 cfg80211_vendor_event(skb, GFP_KERNEL);
2917 return;
2918
2919nla_put_failure:
2920 kfree_skb(skb);
2921 return;
2922}
2923
2924void wlan_hdd_cfg80211_extscan_callback(void *ctx, const tANI_U16 evType,
2925 void *pMsg)
2926{
2927 hdd_context_t *pHddCtx = (hdd_context_t *)ctx;
2928
2929 if (wlan_hdd_validate_context(pHddCtx)) {
2930 hddLog(VOS_TRACE_LEVEL_ERROR, FL("HDD context is not valid"));
2931 return;
2932 }
2933
2934 hddLog(VOS_TRACE_LEVEL_INFO, FL("Rcvd Event (%d)"), evType);
2935
2936
2937 switch(evType) {
2938 case SIR_HAL_EXTSCAN_START_RSP:
2939 wlan_hdd_cfg80211_extscan_start_rsp(ctx, pMsg);
2940 break;
2941
2942 case SIR_HAL_EXTSCAN_STOP_RSP:
2943 wlan_hdd_cfg80211_extscan_stop_rsp(ctx, pMsg);
2944 break;
2945 case SIR_HAL_EXTSCAN_GET_CACHED_RESULTS_RSP:
2946 /* There is no need to send this response to upper layer
2947 Just log the message */
2948 hddLog(VOS_TRACE_LEVEL_INFO,
2949 FL("Rcvd SIR_HAL_EXTSCAN_CACHED_RESULTS_RSP"));
2950 break;
2951 case SIR_HAL_EXTSCAN_SET_BSS_HOTLIST_RSP:
2952 wlan_hdd_cfg80211_extscan_set_bss_hotlist_rsp(ctx, pMsg);
2953 break;
2954
2955 case SIR_HAL_EXTSCAN_RESET_BSS_HOTLIST_RSP:
2956 wlan_hdd_cfg80211_extscan_reset_bss_hotlist_rsp(ctx, pMsg);
2957 break;
2958
2959 case SIR_HAL_EXTSCAN_SET_SIGNF_RSSI_CHANGE_RSP:
2960 wlan_hdd_cfg80211_extscan_set_signf_wifi_change_rsp(ctx, pMsg);
2961 break;
2962
2963 case SIR_HAL_EXTSCAN_RESET_SIGNF_RSSI_CHANGE_RSP:
2964 wlan_hdd_cfg80211_extscan_reset_signf_wifi_change_rsp(ctx, pMsg);
2965 break;
2966 case SIR_HAL_EXTSCAN_GET_CAPABILITIES_RSP:
2967 wlan_hdd_cfg80211_extscan_get_capabilities_ind(ctx, pMsg);
2968 break;
2969 case SIR_HAL_EXTSCAN_PROGRESS_IND:
2970 wlan_hdd_cfg80211_extscan_scan_progress_event(ctx, pMsg);
2971 break;
2972 case SIR_HAL_EXTSCAN_SCAN_AVAILABLE_IND:
2973 wlan_hdd_cfg80211_extscan_scan_res_available_event(ctx, pMsg);
2974 break;
2975 case SIR_HAL_EXTSCAN_SCAN_RESULT_IND:
2976 wlan_hdd_cfg80211_extscan_cached_results_ind(ctx, pMsg);
2977 break;
2978 case SIR_HAL_EXTSCAN_HOTLIST_MATCH_IND:
2979 wlan_hdd_cfg80211_extscan_hotlist_match_ind(ctx, pMsg);
2980 break;
2981 case SIR_HAL_EXTSCAN_SIGNF_WIFI_CHANGE_IND:
2982 wlan_hdd_cfg80211_extscan_signif_wifi_change_results_ind(ctx, pMsg);
2983 break;
2984 case SIR_HAL_EXTSCAN_FULL_SCAN_RESULT_IND:
2985 wlan_hdd_cfg80211_extscan_full_scan_result_event(ctx, pMsg);
2986 break;
2987 default:
2988 hddLog(VOS_TRACE_LEVEL_ERROR, FL("invalid event type %d "), evType);
2989 break;
2990 }
2991}
2992
2993static int wlan_hdd_cfg80211_extscan_get_capabilities(struct wiphy *wiphy,
2994 struct wireless_dev *wdev,
2995 void *data, int dataLen)
2996{
Dino Myclee8843b32014-07-04 14:21:45 +05302997 tSirGetEXTScanCapabilitiesReqParams reqMsg;
Dino Mycle6fb96c12014-06-10 11:52:40 +05302998 struct net_device *dev = wdev->netdev;
2999 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
3000 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
3001 struct nlattr
3002 *tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX + 1];
3003 eHalStatus status;
3004
3005 hddLog(VOS_TRACE_LEVEL_INFO, FL("Entering"));
3006 status = wlan_hdd_validate_context(pHddCtx);
3007 if (0 != status)
3008 {
3009 hddLog(VOS_TRACE_LEVEL_ERROR,
3010 FL("HDD context is not valid"));
3011 return -EINVAL;
3012 }
Dino Myclee8843b32014-07-04 14:21:45 +05303013 /* check the EXTScan Capability */
3014 if ( (TRUE != pHddCtx->cfg_ini->fEnableEXTScan) ||
3015 (TRUE != sme_IsFeatureSupportedByFW(EXTENDED_SCAN)))
3016 {
3017 hddLog(VOS_TRACE_LEVEL_ERROR,
3018 FL("EXTScan not enabled/supported by Firmware"));
3019 return -EINVAL;
3020 }
3021
Dino Mycle6fb96c12014-06-10 11:52:40 +05303022 if (nla_parse(tb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX,
3023 data, dataLen,
3024 wlan_hdd_extscan_config_policy)) {
3025 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Invalid ATTR"));
3026 return -EINVAL;
3027 }
3028
3029 /* Parse and fetch request Id */
3030 if (!tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_REQUEST_ID]) {
3031 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr request id failed"));
3032 return -EINVAL;
3033 }
3034
Dino Mycle6fb96c12014-06-10 11:52:40 +05303035
Dino Myclee8843b32014-07-04 14:21:45 +05303036 reqMsg.requestId = nla_get_u32(
Dino Mycle6fb96c12014-06-10 11:52:40 +05303037 tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_REQUEST_ID]);
Dino Myclee8843b32014-07-04 14:21:45 +05303038 hddLog(VOS_TRACE_LEVEL_INFO, FL("Req Id (%d)"), reqMsg.requestId);
Dino Mycle6fb96c12014-06-10 11:52:40 +05303039
Dino Myclee8843b32014-07-04 14:21:45 +05303040 reqMsg.sessionId = pAdapter->sessionId;
3041 hddLog(VOS_TRACE_LEVEL_INFO, FL("Session Id (%d)"), reqMsg.sessionId);
Dino Mycle6fb96c12014-06-10 11:52:40 +05303042
Dino Myclee8843b32014-07-04 14:21:45 +05303043 status = sme_EXTScanGetCapabilities(pHddCtx->hHal, &reqMsg);
Dino Mycle6fb96c12014-06-10 11:52:40 +05303044 if (!HAL_STATUS_SUCCESS(status)) {
3045 hddLog(VOS_TRACE_LEVEL_ERROR,
3046 FL("sme_EXTScanGetCapabilities failed(err=%d)"), status);
Dino Mycle6fb96c12014-06-10 11:52:40 +05303047 return -EINVAL;
3048 }
3049
3050 return 0;
3051}
3052
3053
3054static int wlan_hdd_cfg80211_extscan_get_cached_results(struct wiphy *wiphy,
3055 struct wireless_dev *wdev,
3056 void *data, int dataLen)
3057{
Dino Myclee8843b32014-07-04 14:21:45 +05303058 tSirEXTScanGetCachedResultsReqParams reqMsg;
Dino Mycle6fb96c12014-06-10 11:52:40 +05303059 struct net_device *dev = wdev->netdev;
3060 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
3061 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
3062 struct nlattr
3063 *tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX + 1];
3064 eHalStatus status;
3065
3066 status = wlan_hdd_validate_context(pHddCtx);
3067 if (0 != status)
3068 {
3069 hddLog(VOS_TRACE_LEVEL_ERROR,
3070 FL("HDD context is not valid"));
3071 return -EINVAL;
3072 }
Dino Myclee8843b32014-07-04 14:21:45 +05303073 /* check the EXTScan Capability */
3074 if ( (TRUE != pHddCtx->cfg_ini->fEnableEXTScan) ||
3075 (TRUE != sme_IsFeatureSupportedByFW(EXTENDED_SCAN)))
3076 {
3077 hddLog(VOS_TRACE_LEVEL_ERROR,
3078 FL("EXTScan not enabled/supported by Firmware"));
3079 return -EINVAL;
3080 }
3081
Dino Mycle6fb96c12014-06-10 11:52:40 +05303082 if (nla_parse(tb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX,
3083 data, dataLen,
3084 wlan_hdd_extscan_config_policy)) {
3085 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Invalid ATTR"));
3086 return -EINVAL;
3087 }
3088 /* Parse and fetch request Id */
3089 if (!tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_REQUEST_ID]) {
3090 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr request id failed"));
3091 return -EINVAL;
3092 }
Dino Mycle6fb96c12014-06-10 11:52:40 +05303093
Dino Myclee8843b32014-07-04 14:21:45 +05303094 reqMsg.requestId = nla_get_u32(
Dino Mycle6fb96c12014-06-10 11:52:40 +05303095 tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_REQUEST_ID]);
3096
Dino Myclee8843b32014-07-04 14:21:45 +05303097 hddLog(VOS_TRACE_LEVEL_INFO, FL("Req Id (%d)"), reqMsg.requestId);
Dino Mycle6fb96c12014-06-10 11:52:40 +05303098
Dino Myclee8843b32014-07-04 14:21:45 +05303099 reqMsg.sessionId = pAdapter->sessionId;
3100 hddLog(VOS_TRACE_LEVEL_INFO, FL("Session Id (%d)"), reqMsg.sessionId);
Dino Mycle6fb96c12014-06-10 11:52:40 +05303101
3102 /* Parse and fetch flush parameter */
3103 if (!tb
3104 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_GET_CACHED_SCAN_RESULTS_CONFIG_PARAM_FLUSH])
3105 {
3106 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr flush failed"));
3107 goto failed;
3108 }
Dino Myclee8843b32014-07-04 14:21:45 +05303109 reqMsg.flush = nla_get_u8(
Dino Mycle6fb96c12014-06-10 11:52:40 +05303110 tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_GET_CACHED_SCAN_RESULTS_CONFIG_PARAM_FLUSH]);
3111
Dino Myclee8843b32014-07-04 14:21:45 +05303112 hddLog(VOS_TRACE_LEVEL_INFO, FL("Flush (%d)"), reqMsg.flush);
Dino Mycle6fb96c12014-06-10 11:52:40 +05303113
Dino Myclee8843b32014-07-04 14:21:45 +05303114 status = sme_getCachedResults(pHddCtx->hHal, &reqMsg);
Dino Mycle6fb96c12014-06-10 11:52:40 +05303115 if (!HAL_STATUS_SUCCESS(status)) {
3116 hddLog(VOS_TRACE_LEVEL_ERROR,
3117 FL("sme_getCachedResults failed(err=%d)"), status);
Dino Mycle6fb96c12014-06-10 11:52:40 +05303118 return -EINVAL;
3119 }
3120 return 0;
3121
3122failed:
Dino Mycle6fb96c12014-06-10 11:52:40 +05303123 return -EINVAL;
3124}
3125
3126static int wlan_hdd_cfg80211_extscan_set_bssid_hotlist(struct wiphy *wiphy,
3127 struct wireless_dev *wdev,
3128 void *data, int dataLen)
3129{
3130 tpSirEXTScanSetBssidHotListReqParams pReqMsg = NULL;
3131 struct net_device *dev = wdev->netdev;
3132 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
3133 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
3134 struct nlattr
3135 *tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX + 1];
3136 struct nlattr
3137 *tb2[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX + 1];
3138 struct nlattr *apTh;
3139 eHalStatus status;
3140 tANI_U8 i = 0;
3141 int rem;
3142
3143 status = wlan_hdd_validate_context(pHddCtx);
3144 if (0 != status)
3145 {
3146 hddLog(VOS_TRACE_LEVEL_ERROR,
3147 FL("HDD context is not valid"));
3148 return -EINVAL;
3149 }
Dino Myclee8843b32014-07-04 14:21:45 +05303150 /* check the EXTScan Capability */
3151 if ( (TRUE != pHddCtx->cfg_ini->fEnableEXTScan) ||
3152 (TRUE != sme_IsFeatureSupportedByFW(EXTENDED_SCAN)))
3153 {
3154 hddLog(VOS_TRACE_LEVEL_ERROR,
3155 FL("EXTScan not enabled/supported by Firmware"));
3156 return -EINVAL;
3157 }
3158
Dino Mycle6fb96c12014-06-10 11:52:40 +05303159 if (nla_parse(tb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX,
3160 data, dataLen,
3161 wlan_hdd_extscan_config_policy)) {
3162 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Invalid ATTR"));
3163 return -EINVAL;
3164 }
3165
3166 /* Parse and fetch request Id */
3167 if (!tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_REQUEST_ID]) {
3168 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr request id failed"));
3169 return -EINVAL;
3170 }
Dino Mycle6fb96c12014-06-10 11:52:40 +05303171 pReqMsg = (tpSirEXTScanSetBssidHotListReqParams)
3172 vos_mem_malloc(sizeof(*pReqMsg));
3173 if (!pReqMsg) {
3174 hddLog(VOS_TRACE_LEVEL_ERROR, FL("vos_mem_malloc failed"));
3175 return -ENOMEM;
3176 }
3177
Dino Myclee8843b32014-07-04 14:21:45 +05303178
Dino Mycle6fb96c12014-06-10 11:52:40 +05303179 pReqMsg->requestId = nla_get_u32(
3180 tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_REQUEST_ID]);
3181 hddLog(VOS_TRACE_LEVEL_INFO, FL("Req Id (%d)"), pReqMsg->requestId);
3182
3183 /* Parse and fetch number of APs */
3184 if (!tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_BSSID_HOTLIST_PARAMS_NUM_AP]) {
3185 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr number of AP failed"));
3186 goto fail;
3187 }
3188
3189 pReqMsg->sessionId = pAdapter->sessionId;
3190 hddLog(VOS_TRACE_LEVEL_INFO, FL("Session Id (%d)"), pReqMsg->sessionId);
3191
3192 pReqMsg->numAp = nla_get_u32(
3193 tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_BSSID_HOTLIST_PARAMS_NUM_AP]);
3194 hddLog(VOS_TRACE_LEVEL_INFO, FL("Number of AP (%d)"), pReqMsg->numAp);
3195
3196 nla_for_each_nested(apTh,
3197 tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_AP_THRESHOLD_PARAM], rem) {
3198 if(nla_parse(tb2, QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX,
3199 nla_data(apTh), nla_len(apTh),
3200 NULL)) {
3201 hddLog(VOS_TRACE_LEVEL_ERROR, FL("nla_parse failed"));
3202 goto fail;
3203 }
3204
3205 /* Parse and fetch MAC address */
3206 if (!tb2[QCA_WLAN_VENDOR_ATTR_EXTSCAN_AP_THRESHOLD_PARAM_BSSID]) {
3207 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr mac address failed"));
3208 goto fail;
3209 }
3210 memcpy(pReqMsg->ap[i].bssid, nla_data(
3211 tb2[QCA_WLAN_VENDOR_ATTR_EXTSCAN_AP_THRESHOLD_PARAM_BSSID]),
3212 sizeof(tSirMacAddr));
3213 hddLog(VOS_TRACE_LEVEL_INFO, FL("BSSID: %pM "), pReqMsg->ap[i].bssid);
3214
3215 /* Parse and fetch low RSSI */
3216 if (!tb2[QCA_WLAN_VENDOR_ATTR_EXTSCAN_AP_THRESHOLD_PARAM_RSSI_LOW]) {
3217 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr low RSSI failed"));
3218 goto fail;
3219 }
3220 pReqMsg->ap[i].low = nla_get_s32(
3221 tb2[QCA_WLAN_VENDOR_ATTR_EXTSCAN_AP_THRESHOLD_PARAM_RSSI_LOW]);
3222 hddLog(VOS_TRACE_LEVEL_INFO, FL("RSSI low (%d)"), pReqMsg->ap[i].low);
3223
3224 /* Parse and fetch high RSSI */
3225 if (!tb2[QCA_WLAN_VENDOR_ATTR_EXTSCAN_AP_THRESHOLD_PARAM_RSSI_HIGH]) {
3226 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr high RSSI failed"));
3227 goto fail;
3228 }
3229 pReqMsg->ap[i].high = nla_get_s32(
3230 tb2[QCA_WLAN_VENDOR_ATTR_EXTSCAN_AP_THRESHOLD_PARAM_RSSI_HIGH]);
3231 hddLog(VOS_TRACE_LEVEL_INFO, FL("RSSI High (%d)"),
3232 pReqMsg->ap[i].high);
3233
3234 /* Parse and fetch channel */
3235 if (!tb2[QCA_WLAN_VENDOR_ATTR_EXTSCAN_AP_THRESHOLD_PARAM_CHANNEL]) {
3236 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr channel failed"));
3237 goto fail;
3238 }
3239 pReqMsg->ap[i].channel = nla_get_u32(
3240 tb2[QCA_WLAN_VENDOR_ATTR_EXTSCAN_AP_THRESHOLD_PARAM_CHANNEL]);
3241 hddLog(VOS_TRACE_LEVEL_INFO,
3242 FL("Channel (%u)"), pReqMsg->ap[i].channel);
3243 i++;
3244 }
3245 status = sme_SetBssHotlist(pHddCtx->hHal, pReqMsg);
3246 if (!HAL_STATUS_SUCCESS(status)) {
3247 hddLog(VOS_TRACE_LEVEL_ERROR,
3248 FL("sme_SetBssHotlist failed(err=%d)"), status);
3249 vos_mem_free(pReqMsg);
3250 return -EINVAL;
3251 }
3252
Dino Myclee8843b32014-07-04 14:21:45 +05303253 vos_mem_free(pReqMsg);
3254
Dino Mycle6fb96c12014-06-10 11:52:40 +05303255 return 0;
3256
3257fail:
3258 vos_mem_free(pReqMsg);
3259 return -EINVAL;
3260}
3261
3262static int wlan_hdd_cfg80211_extscan_set_significant_change(struct wiphy *wiphy,
3263 struct wireless_dev *wdev,
3264 void *data, int dataLen)
3265{
3266 tpSirEXTScanSetSignificantChangeReqParams pReqMsg = NULL;
3267 struct net_device *dev = wdev->netdev;
3268 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
3269 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
3270 struct nlattr
3271 *tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX + 1];
3272 struct nlattr
3273 *tb2[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX + 1];
3274 struct nlattr *apTh;
3275 eHalStatus status;
3276 int i = 0;
3277 int rem;
3278
3279 status = wlan_hdd_validate_context(pHddCtx);
3280 if (0 != status)
3281 {
3282 hddLog(VOS_TRACE_LEVEL_ERROR,
3283 FL("HDD context is not valid"));
3284 return -EINVAL;
3285 }
Dino Myclee8843b32014-07-04 14:21:45 +05303286 /* check the EXTScan Capability */
3287 if ( (TRUE != pHddCtx->cfg_ini->fEnableEXTScan) ||
3288 (TRUE != sme_IsFeatureSupportedByFW(EXTENDED_SCAN)))
3289 {
3290 hddLog(VOS_TRACE_LEVEL_ERROR,
3291 FL("EXTScan not enabled/supported by Firmware"));
3292 return -EINVAL;
3293 }
3294
Dino Mycle6fb96c12014-06-10 11:52:40 +05303295 if (nla_parse(tb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX,
3296 data, dataLen,
3297 wlan_hdd_extscan_config_policy)) {
3298 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Invalid ATTR"));
3299 return -EINVAL;
3300 }
3301
3302 /* Parse and fetch request Id */
3303 if (!tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_REQUEST_ID]) {
3304 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr request id failed"));
3305 return -EINVAL;
3306 }
Dino Mycle6fb96c12014-06-10 11:52:40 +05303307 pReqMsg = (tpSirEXTScanSetSignificantChangeReqParams)
Dino Myclee8843b32014-07-04 14:21:45 +05303308 vos_mem_malloc(sizeof(*pReqMsg));
Dino Mycle6fb96c12014-06-10 11:52:40 +05303309 if (!pReqMsg) {
Dino Myclee8843b32014-07-04 14:21:45 +05303310 hddLog(VOS_TRACE_LEVEL_ERROR, FL("vos_mem_malloc failed"));
3311 return -ENOMEM;
Dino Mycle6fb96c12014-06-10 11:52:40 +05303312 }
3313
Dino Myclee8843b32014-07-04 14:21:45 +05303314
3315
Dino Mycle6fb96c12014-06-10 11:52:40 +05303316 pReqMsg->requestId = nla_get_u32(
3317 tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_REQUEST_ID]);
3318 hddLog(VOS_TRACE_LEVEL_INFO, FL("Req Id (%d)"), pReqMsg->requestId);
3319
3320 /* Parse and fetch RSSI sample size */
3321 if (!tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SIGNIFICANT_CHANGE_PARAMS_RSSI_SAMPLE_SIZE])
3322 {
3323 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr RSSI sample size failed"));
3324 goto fail;
3325 }
3326 pReqMsg->rssiSampleSize = nla_get_u32(
3327 tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SIGNIFICANT_CHANGE_PARAMS_RSSI_SAMPLE_SIZE]);
3328 hddLog(VOS_TRACE_LEVEL_INFO,
3329 FL("RSSI sample size (%u)"), pReqMsg->rssiSampleSize);
3330
3331 /* Parse and fetch lost AP sample size */
3332 if (!tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SIGNIFICANT_CHANGE_PARAMS_LOST_AP_SAMPLE_SIZE])
3333 {
3334 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr lost AP sample size failed"));
3335 goto fail;
3336 }
3337 pReqMsg->lostApSampleSize = nla_get_u32(
3338 tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SIGNIFICANT_CHANGE_PARAMS_LOST_AP_SAMPLE_SIZE]);
3339 hddLog(VOS_TRACE_LEVEL_INFO,
3340 FL("Lost AP sample size (%u)"), pReqMsg->lostApSampleSize);
3341 /* Parse and fetch minimum Breaching */
3342 if (!tb
3343 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_SIGNIFICANT_CHANGE_PARAMS_MIN_BREACHING]) {
3344 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr minBreaching failed"));
3345 goto fail;
3346 }
3347 pReqMsg->minBreaching = nla_get_u32(
3348 tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SIGNIFICANT_CHANGE_PARAMS_MIN_BREACHING]);
3349 hddLog(VOS_TRACE_LEVEL_INFO, FL(" Breaching (%d)"), pReqMsg->minBreaching);
3350
3351 /* Parse and fetch number of APs */
3352 if (!tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SIGNIFICANT_CHANGE_PARAMS_NUM_AP]) {
3353 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr number of AP failed"));
3354 goto fail;
3355 }
3356 pReqMsg->numAp = nla_get_u32(
3357 tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SIGNIFICANT_CHANGE_PARAMS_NUM_AP]);
3358 hddLog(VOS_TRACE_LEVEL_INFO, FL("Number of AP (%d)"), pReqMsg->numAp);
3359
3360 pReqMsg->sessionId = pAdapter->sessionId;
3361 hddLog(VOS_TRACE_LEVEL_INFO, FL("Session Id (%d)"), pReqMsg->sessionId);
3362
3363 nla_for_each_nested(apTh,
3364 tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_AP_THRESHOLD_PARAM], rem) {
3365 if(nla_parse(tb2,
3366 QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX,
3367 nla_data(apTh), nla_len(apTh),
3368 NULL)) {
3369 hddLog(VOS_TRACE_LEVEL_ERROR, FL("nla_parse failed"));
3370 goto fail;
3371 }
3372
3373 /* Parse and fetch MAC address */
3374 if (!tb2[QCA_WLAN_VENDOR_ATTR_EXTSCAN_AP_THRESHOLD_PARAM_BSSID]) {
3375 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr mac address failed"));
3376 goto fail;
3377 }
3378 memcpy(pReqMsg->ap[i].bssid, nla_data(
3379 tb2[QCA_WLAN_VENDOR_ATTR_EXTSCAN_AP_THRESHOLD_PARAM_BSSID]),
3380 sizeof(tSirMacAddr));
3381
3382 /* Parse and fetch low RSSI */
3383 if (!tb2[QCA_WLAN_VENDOR_ATTR_EXTSCAN_AP_THRESHOLD_PARAM_RSSI_LOW]) {
3384 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr low RSSI failed"));
3385 goto fail;
3386 }
3387 pReqMsg->ap[i].low = nla_get_s32(
3388 tb2[QCA_WLAN_VENDOR_ATTR_EXTSCAN_AP_THRESHOLD_PARAM_RSSI_LOW]);
3389 hddLog(VOS_TRACE_LEVEL_INFO, FL("RSSI low (%d)"), pReqMsg->ap[i].low);
3390
3391 /* Parse and fetch high RSSI */
3392 if (!tb2[QCA_WLAN_VENDOR_ATTR_EXTSCAN_AP_THRESHOLD_PARAM_RSSI_HIGH]) {
3393 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr high RSSI failed"));
3394 goto fail;
3395 }
3396 pReqMsg->ap[i].high = nla_get_s32(
3397 tb2[QCA_WLAN_VENDOR_ATTR_EXTSCAN_AP_THRESHOLD_PARAM_RSSI_HIGH]);
3398 hddLog(VOS_TRACE_LEVEL_INFO,
3399 FL("RSSI High (%d)"), pReqMsg->ap[i].high);
3400
3401 /* Parse and fetch channel */
3402 if (!tb2[QCA_WLAN_VENDOR_ATTR_EXTSCAN_AP_THRESHOLD_PARAM_CHANNEL]) {
3403 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr channel failed"));
3404 goto fail;
3405 }
3406 pReqMsg->ap[i].channel = nla_get_u32(
3407 tb2[QCA_WLAN_VENDOR_ATTR_EXTSCAN_AP_THRESHOLD_PARAM_CHANNEL]);
3408 hddLog(VOS_TRACE_LEVEL_INFO,
3409 FL("Channel (%u)"), pReqMsg->ap[i].channel);
3410 i++;
3411 }
3412
3413 status = sme_SetSignificantChange(pHddCtx->hHal, pReqMsg);
3414 if (!HAL_STATUS_SUCCESS(status)) {
3415 hddLog(VOS_TRACE_LEVEL_ERROR,
3416 FL("sme_SetSignificantChange failed(err=%d)"), status);
3417 vos_mem_free(pReqMsg);
3418 return -EINVAL;
3419 }
Dino Myclee8843b32014-07-04 14:21:45 +05303420 vos_mem_free(pReqMsg);
Dino Mycle6fb96c12014-06-10 11:52:40 +05303421 hddLog(VOS_TRACE_LEVEL_ERROR, FL(" Exiting"));
3422 return 0;
3423
3424fail:
3425 vos_mem_free(pReqMsg);
3426 return -EINVAL;
3427}
3428
3429static int wlan_hdd_cfg80211_extscan_get_valid_channels(struct wiphy *wiphy,
3430 struct wireless_dev *wdev,
3431 void *data, int dataLen)
3432{
3433 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
3434 tANI_U32 ChannelList[WNI_CFG_VALID_CHANNEL_LIST_LEN] = {0};
3435 tANI_U8 numChannels = 0;
3436 struct nlattr *tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX + 1];
3437 tANI_U32 requestId;
3438 tWifiBand wifiBand;
3439 eHalStatus status;
3440 struct sk_buff *replySkb;
3441 tANI_U8 i;
3442
3443 hddLog(VOS_TRACE_LEVEL_INFO, FL("Entering"));
3444 status = wlan_hdd_validate_context(pHddCtx);
3445 if (0 != status)
3446 {
3447 hddLog(VOS_TRACE_LEVEL_ERROR,
3448 FL("HDD context is not valid"));
3449 return -EINVAL;
3450 }
Dino Myclee8843b32014-07-04 14:21:45 +05303451 /* check the EXTScan Capability */
3452 if ( (TRUE != pHddCtx->cfg_ini->fEnableEXTScan) ||
3453 (TRUE != sme_IsFeatureSupportedByFW(EXTENDED_SCAN)))
3454 {
3455 hddLog(VOS_TRACE_LEVEL_ERROR,
3456 FL("EXTScan not enabled/supported by Firmware"));
3457 return -EINVAL;
3458 }
3459
Dino Mycle6fb96c12014-06-10 11:52:40 +05303460 if (nla_parse(tb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX,
3461 data, dataLen,
3462 wlan_hdd_extscan_config_policy)) {
3463 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Invalid ATTR"));
3464 return -EINVAL;
3465 }
3466
3467 /* Parse and fetch request Id */
3468 if (!tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_REQUEST_ID]) {
3469 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr request id failed"));
3470 return -EINVAL;
3471 }
3472 requestId = nla_get_u32(
3473 tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_REQUEST_ID]);
3474 hddLog(VOS_TRACE_LEVEL_INFO, FL("Req Id (%d)"), requestId);
3475
3476 /* Parse and fetch wifi band */
3477 if (!tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_GET_VALID_CHANNELS_CONFIG_PARAM_WIFI_BAND])
3478 {
3479 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr wifi band failed"));
3480 return -EINVAL;
3481 }
3482 wifiBand = nla_get_u32(
3483 tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_GET_VALID_CHANNELS_CONFIG_PARAM_WIFI_BAND]);
3484 hddLog(VOS_TRACE_LEVEL_INFO, FL("Wifi band (%d)"), wifiBand);
3485
3486 status = sme_GetValidChannelsByBand((tHalHandle)(pHddCtx->hHal),
3487 wifiBand, ChannelList,
3488 &numChannels);
3489 if (eHAL_STATUS_SUCCESS != status) {
3490 hddLog(VOS_TRACE_LEVEL_ERROR,
3491 FL("sme_GetValidChannelsByBand failed (err=%d)"), status);
3492 return -EINVAL;
3493 }
3494 hddLog(VOS_TRACE_LEVEL_INFO, FL("Number of channels (%d)"), numChannels);
3495 for (i = 0; i < numChannels; i++)
3496 hddLog(VOS_TRACE_LEVEL_INFO, "Channel: %u ", ChannelList[i]);
3497
3498 replySkb = cfg80211_vendor_cmd_alloc_reply_skb(wiphy, sizeof(u32) +
3499 sizeof(u32) * numChannels +
3500 NLMSG_HDRLEN);
3501
3502 if (!replySkb) {
3503 hddLog(VOS_TRACE_LEVEL_ERROR,
3504 FL("valid channels: buffer alloc fail"));
3505 return -EINVAL;
3506 }
3507 if (nla_put_u32(replySkb,
3508 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_NUM_CHANNELS,
3509 numChannels) ||
3510 nla_put(replySkb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_CHANNELS,
3511 sizeof(u32) * numChannels, ChannelList)) {
3512
3513 hddLog(VOS_TRACE_LEVEL_ERROR, FL("nla put fail"));
3514 kfree_skb(replySkb);
3515 return -EINVAL;
3516 }
3517
3518 return cfg80211_vendor_cmd_reply(replySkb);
3519}
3520
3521static int wlan_hdd_cfg80211_extscan_start(struct wiphy *wiphy,
3522 struct wireless_dev *wdev,
3523 void *data, int dataLen)
3524{
Dino Myclee8843b32014-07-04 14:21:45 +05303525 tpSirEXTScanStartReqParams pReqMsg = NULL;
Dino Mycle6fb96c12014-06-10 11:52:40 +05303526 struct net_device *dev = wdev->netdev;
3527 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
3528 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
3529 struct nlattr *tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX + 1];
3530 struct nlattr *bucket[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX + 1];
3531 struct nlattr *channel[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX + 1];
3532 struct nlattr *buckets;
3533 struct nlattr *channels;
3534 int rem1;
3535 int rem2;
3536 eHalStatus status;
Dasari Srinivas8b2ce272014-09-16 16:57:30 +05303537 tANI_U32 j = 0, index = 0;
Dino Mycle6fb96c12014-06-10 11:52:40 +05303538
3539 status = wlan_hdd_validate_context(pHddCtx);
3540 if (0 != status)
3541 {
3542 hddLog(VOS_TRACE_LEVEL_ERROR,
3543 FL("HDD context is not valid"));
3544 return -EINVAL;
3545 }
Dino Myclee8843b32014-07-04 14:21:45 +05303546 /* check the EXTScan Capability */
3547 if ( (TRUE != pHddCtx->cfg_ini->fEnableEXTScan) ||
3548 (TRUE != sme_IsFeatureSupportedByFW(EXTENDED_SCAN)))
3549 {
3550 hddLog(VOS_TRACE_LEVEL_ERROR,
3551 FL("EXTScan not enabled/supported by Firmware"));
3552 return -EINVAL;
3553 }
3554
Dino Mycle6fb96c12014-06-10 11:52:40 +05303555 if (nla_parse(tb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX,
3556 data, dataLen,
3557 wlan_hdd_extscan_config_policy)) {
3558 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Invalid ATTR"));
3559 return -EINVAL;
3560 }
3561
3562 /* Parse and fetch request Id */
3563 if (!tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_REQUEST_ID]) {
3564 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr request id failed"));
3565 return -EINVAL;
3566 }
3567
Dino Myclee8843b32014-07-04 14:21:45 +05303568 pReqMsg = (tpSirEXTScanStartReqParams)
3569 vos_mem_malloc(sizeof(*pReqMsg));
Dino Mycle6fb96c12014-06-10 11:52:40 +05303570 if (!pReqMsg) {
Dino Myclee8843b32014-07-04 14:21:45 +05303571 hddLog(VOS_TRACE_LEVEL_ERROR, FL("vos_mem_malloc failed"));
3572 return -ENOMEM;
Dino Mycle6fb96c12014-06-10 11:52:40 +05303573 }
3574
3575 pReqMsg->requestId = nla_get_u32(
3576 tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_REQUEST_ID]);
3577 hddLog(VOS_TRACE_LEVEL_INFO, FL("Req Id (%d)"), pReqMsg->requestId);
3578
3579 pReqMsg->sessionId = pAdapter->sessionId;
3580 hddLog(VOS_TRACE_LEVEL_INFO, FL("Session Id (%d)"), pReqMsg->sessionId);
3581
3582 /* Parse and fetch base period */
3583 if (!tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SCAN_CMD_PARAMS_BASE_PERIOD]) {
3584 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr base period failed"));
3585 goto fail;
3586 }
3587 pReqMsg->basePeriod = nla_get_u32(
3588 tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SCAN_CMD_PARAMS_BASE_PERIOD]);
3589 hddLog(VOS_TRACE_LEVEL_INFO, FL("Base Period (%d)"),
3590 pReqMsg->basePeriod);
3591
3592 /* Parse and fetch max AP per scan */
3593 if (!tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SCAN_CMD_PARAMS_MAX_AP_PER_SCAN]) {
3594 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr max_ap_per_scan failed"));
3595 goto fail;
3596 }
3597 pReqMsg->maxAPperScan = nla_get_u32(
3598 tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SCAN_CMD_PARAMS_MAX_AP_PER_SCAN]);
3599 hddLog(VOS_TRACE_LEVEL_INFO, FL("Max AP per Scan (%d)"),
3600 pReqMsg->maxAPperScan);
3601
3602 /* Parse and fetch report threshold */
3603 if (!tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SCAN_CMD_PARAMS_REPORT_THRESHOLD]) {
3604 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr report_threshold failed"));
3605 goto fail;
3606 }
3607 pReqMsg->reportThreshold = nla_get_u8(
3608 tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SCAN_CMD_PARAMS_REPORT_THRESHOLD]);
3609 hddLog(VOS_TRACE_LEVEL_INFO, FL("Report Threshold (%d)"),
3610 pReqMsg->reportThreshold);
3611
3612 /* Parse and fetch number of buckets */
3613 if (!tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SCAN_CMD_PARAMS_NUM_BUCKETS]) {
3614 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr number of buckets failed"));
3615 goto fail;
3616 }
3617 pReqMsg->numBuckets = nla_get_u8(
3618 tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SCAN_CMD_PARAMS_NUM_BUCKETS]);
3619 if (pReqMsg->numBuckets > WLAN_EXTSCAN_MAX_BUCKETS) {
3620 hddLog(VOS_TRACE_LEVEL_WARN, FL("Exceeded MAX number of buckets "
3621 "Setting numBuckets to %u"), WLAN_EXTSCAN_MAX_BUCKETS);
3622 pReqMsg->numBuckets = WLAN_EXTSCAN_MAX_BUCKETS;
3623 }
3624 hddLog(VOS_TRACE_LEVEL_INFO, FL("Number of Buckets (%d)"),
3625 pReqMsg->numBuckets);
3626 if (!tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC]) {
3627 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr bucket spec failed"));
3628 goto fail;
3629 }
3630
3631 nla_for_each_nested(buckets,
3632 tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC], rem1) {
3633 if(nla_parse(bucket,
3634 QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX,
3635 nla_data(buckets), nla_len(buckets), NULL)) { //policy
3636 hddLog(VOS_TRACE_LEVEL_ERROR, FL("nla_parse failed"));
3637 goto fail;
3638 }
3639
3640 /* Parse and fetch bucket spec */
3641 if (!bucket[QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_INDEX]) {
3642 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr bucket index failed"));
3643 goto fail;
3644 }
Dasari Srinivas8b2ce272014-09-16 16:57:30 +05303645
3646 pReqMsg->buckets[index].bucket = nla_get_u8(
3647 bucket[QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_INDEX]);
3648
3649 hddLog(VOS_TRACE_LEVEL_INFO, FL("Bucket spec Index (%d)"),
3650 pReqMsg->buckets[index].bucket);
Dino Mycle6fb96c12014-06-10 11:52:40 +05303651
3652 /* Parse and fetch wifi band */
3653 if (!bucket[QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_BAND]) {
3654 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr wifi band failed"));
3655 goto fail;
3656 }
Dasari Srinivas8b2ce272014-09-16 16:57:30 +05303657 pReqMsg->buckets[index].band = nla_get_u8(
Dino Mycle6fb96c12014-06-10 11:52:40 +05303658 bucket[QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_BAND]);
3659 hddLog(VOS_TRACE_LEVEL_INFO, FL("Wifi band (%d)"),
Dasari Srinivas8b2ce272014-09-16 16:57:30 +05303660 pReqMsg->buckets[index].band);
Dino Mycle6fb96c12014-06-10 11:52:40 +05303661
3662 /* Parse and fetch period */
3663 if (!bucket[QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_PERIOD]) {
3664 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr period failed"));
3665 goto fail;
3666 }
Dasari Srinivas8b2ce272014-09-16 16:57:30 +05303667 pReqMsg->buckets[index].period = nla_get_u32(
Dino Mycle6fb96c12014-06-10 11:52:40 +05303668 bucket[QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_PERIOD]);
3669 hddLog(VOS_TRACE_LEVEL_INFO, FL("period (%d)"),
Dasari Srinivas8b2ce272014-09-16 16:57:30 +05303670 pReqMsg->buckets[index].period);
Dino Mycle6fb96c12014-06-10 11:52:40 +05303671
3672 /* Parse and fetch report events */
3673 if (!bucket[QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_REPORT_EVENTS]) {
3674 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr report events failed"));
3675 goto fail;
3676 }
Dasari Srinivas8b2ce272014-09-16 16:57:30 +05303677 pReqMsg->buckets[index].reportEvents = nla_get_u8(
Dino Mycle6fb96c12014-06-10 11:52:40 +05303678 bucket[QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_REPORT_EVENTS]);
3679 hddLog(VOS_TRACE_LEVEL_INFO, FL("report events (%d)"),
Dasari Srinivas8b2ce272014-09-16 16:57:30 +05303680 pReqMsg->buckets[index].reportEvents);
Dino Mycle6fb96c12014-06-10 11:52:40 +05303681
3682 /* Parse and fetch number of channels */
Dasari Srinivas8b2ce272014-09-16 16:57:30 +05303683 if (!bucket[QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_NUM_CHANNEL_SPECS])
3684 {
Dino Mycle6fb96c12014-06-10 11:52:40 +05303685 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr num channels failed"));
3686 goto fail;
3687 }
Dasari Srinivas8b2ce272014-09-16 16:57:30 +05303688 pReqMsg->buckets[index].numChannels = nla_get_u32(
Dino Mycle6fb96c12014-06-10 11:52:40 +05303689 bucket[QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_NUM_CHANNEL_SPECS]);
3690 hddLog(VOS_TRACE_LEVEL_INFO, FL("num channels (%d)"),
Dasari Srinivas8b2ce272014-09-16 16:57:30 +05303691 pReqMsg->buckets[index].numChannels);
Dino Mycle6fb96c12014-06-10 11:52:40 +05303692
3693 if (!bucket[QCA_WLAN_VENDOR_ATTR_EXTSCAN_CHANNEL_SPEC]) {
3694 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr channel spec failed"));
3695 goto fail;
3696 }
3697
3698 j = 0;
3699 nla_for_each_nested(channels,
3700 bucket[QCA_WLAN_VENDOR_ATTR_EXTSCAN_CHANNEL_SPEC], rem2) {
3701 if(nla_parse(channel,
3702 QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX,
3703 nla_data(channels), nla_len(channels),
3704 NULL)) { //wlan_hdd_extscan_config_policy here
3705 hddLog(VOS_TRACE_LEVEL_ERROR, FL("nla_parse failed"));
3706 goto fail;
3707 }
3708
3709 /* Parse and fetch channel */
3710 if (!channel[QCA_WLAN_VENDOR_ATTR_EXTSCAN_CHANNEL_SPEC_CHANNEL]) {
3711 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr channel failed"));
3712 goto fail;
3713 }
Dasari Srinivas8b2ce272014-09-16 16:57:30 +05303714 pReqMsg->buckets[index].channels[j].channel = nla_get_u32(
Dino Mycle6fb96c12014-06-10 11:52:40 +05303715 channel[QCA_WLAN_VENDOR_ATTR_EXTSCAN_CHANNEL_SPEC_CHANNEL]);
3716 hddLog(VOS_TRACE_LEVEL_INFO, FL("channel (%u)"),
Dasari Srinivas8b2ce272014-09-16 16:57:30 +05303717 pReqMsg->buckets[index].channels[j].channel);
Dino Mycle6fb96c12014-06-10 11:52:40 +05303718
3719 /* Parse and fetch dwell time */
3720 if (!channel[QCA_WLAN_VENDOR_ATTR_EXTSCAN_CHANNEL_SPEC_DWELL_TIME]) {
3721 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr dwelltime failed"));
3722 goto fail;
3723 }
Dasari Srinivas8b2ce272014-09-16 16:57:30 +05303724 pReqMsg->buckets[index].channels[j].dwellTimeMs = nla_get_u32(
Dino Mycle6fb96c12014-06-10 11:52:40 +05303725 channel[QCA_WLAN_VENDOR_ATTR_EXTSCAN_CHANNEL_SPEC_DWELL_TIME]);
3726 hddLog(VOS_TRACE_LEVEL_INFO, FL("Dwell time (%u ms)"),
Dasari Srinivas8b2ce272014-09-16 16:57:30 +05303727 pReqMsg->buckets[index].channels[j].dwellTimeMs);
Dino Mycle6fb96c12014-06-10 11:52:40 +05303728
3729 /* Parse and fetch channel spec passive */
3730 if (!channel[QCA_WLAN_VENDOR_ATTR_EXTSCAN_CHANNEL_SPEC_PASSIVE]) {
3731 hddLog(VOS_TRACE_LEVEL_ERROR,
3732 FL("attr channel spec passive failed"));
3733 goto fail;
3734 }
Dasari Srinivas8b2ce272014-09-16 16:57:30 +05303735 pReqMsg->buckets[index].channels[j].passive = nla_get_u8(
Dino Mycle6fb96c12014-06-10 11:52:40 +05303736 channel[QCA_WLAN_VENDOR_ATTR_EXTSCAN_CHANNEL_SPEC_PASSIVE]);
3737 hddLog(VOS_TRACE_LEVEL_INFO, FL("Chnl spec passive (%u)"),
Dasari Srinivas8b2ce272014-09-16 16:57:30 +05303738 pReqMsg->buckets[index].channels[j].passive);
Dino Mycle6fb96c12014-06-10 11:52:40 +05303739 j++;
3740 }
Dasari Srinivas8b2ce272014-09-16 16:57:30 +05303741 index++;
Dino Mycle6fb96c12014-06-10 11:52:40 +05303742 }
3743 status = sme_EXTScanStart(pHddCtx->hHal, pReqMsg);
3744 if (!HAL_STATUS_SUCCESS(status)) {
3745 hddLog(VOS_TRACE_LEVEL_ERROR,
3746 FL("sme_EXTScanStart failed(err=%d)"), status);
3747 vos_mem_free(pReqMsg);
3748 return -EINVAL;
3749 }
3750
Dino Myclee8843b32014-07-04 14:21:45 +05303751 vos_mem_free(pReqMsg);
Dino Mycle6fb96c12014-06-10 11:52:40 +05303752 return 0;
3753
3754fail:
3755 vos_mem_free(pReqMsg);
3756 return -EINVAL;
3757}
3758
3759static int wlan_hdd_cfg80211_extscan_stop(struct wiphy *wiphy,
3760 struct wireless_dev *wdev,
3761 void *data, int dataLen)
3762{
Dino Myclee8843b32014-07-04 14:21:45 +05303763 tSirEXTScanStopReqParams reqMsg;
Dino Mycle6fb96c12014-06-10 11:52:40 +05303764 struct net_device *dev = wdev->netdev;
3765 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
3766 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
3767 struct nlattr *tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX + 1];
3768 eHalStatus status;
3769
3770 status = wlan_hdd_validate_context(pHddCtx);
3771 if (0 != status)
3772 {
3773 hddLog(VOS_TRACE_LEVEL_ERROR,
3774 FL("HDD context is not valid"));
3775 return -EINVAL;
3776 }
Dino Myclee8843b32014-07-04 14:21:45 +05303777 /* check the EXTScan Capability */
3778 if ( (TRUE != pHddCtx->cfg_ini->fEnableEXTScan) ||
3779 (TRUE != sme_IsFeatureSupportedByFW(EXTENDED_SCAN)))
3780 {
3781 hddLog(VOS_TRACE_LEVEL_ERROR,
3782 FL("EXTScan not enabled/supported by Firmware"));
3783 return -EINVAL;
3784 }
3785
Dino Mycle6fb96c12014-06-10 11:52:40 +05303786 if (nla_parse(tb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX,
3787 data, dataLen,
3788 wlan_hdd_extscan_config_policy)) {
3789 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Invalid ATTR"));
3790 return -EINVAL;
3791 }
3792
3793 /* Parse and fetch request Id */
3794 if (!tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_REQUEST_ID]) {
3795 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr request id failed"));
3796 return -EINVAL;
3797 }
3798
Dino Myclee8843b32014-07-04 14:21:45 +05303799 reqMsg.requestId = nla_get_u32(
Dino Mycle6fb96c12014-06-10 11:52:40 +05303800 tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_REQUEST_ID]);
Dino Myclee8843b32014-07-04 14:21:45 +05303801 hddLog(VOS_TRACE_LEVEL_INFO, FL("Req Id (%d)"), reqMsg.requestId);
Dino Mycle6fb96c12014-06-10 11:52:40 +05303802
Dino Myclee8843b32014-07-04 14:21:45 +05303803 reqMsg.sessionId = pAdapter->sessionId;
3804 hddLog(VOS_TRACE_LEVEL_INFO, FL("Session Id (%d)"), reqMsg.sessionId);
Dino Mycle6fb96c12014-06-10 11:52:40 +05303805
Dino Myclee8843b32014-07-04 14:21:45 +05303806 status = sme_EXTScanStop(pHddCtx->hHal, &reqMsg);
Dino Mycle6fb96c12014-06-10 11:52:40 +05303807 if (!HAL_STATUS_SUCCESS(status)) {
3808 hddLog(VOS_TRACE_LEVEL_ERROR,
3809 FL("sme_EXTScanStop failed(err=%d)"), status);
Dino Mycle6fb96c12014-06-10 11:52:40 +05303810 return -EINVAL;
3811 }
3812
3813 return 0;
3814}
3815
3816static int wlan_hdd_cfg80211_extscan_reset_bssid_hotlist(struct wiphy *wiphy,
3817 struct wireless_dev *wdev,
3818 void *data, int dataLen)
3819{
Dino Myclee8843b32014-07-04 14:21:45 +05303820 tSirEXTScanResetBssidHotlistReqParams reqMsg;
Dino Mycle6fb96c12014-06-10 11:52:40 +05303821 struct net_device *dev = wdev->netdev;
3822 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
3823 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
3824 struct nlattr *tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX + 1];
3825 eHalStatus status;
3826
3827 status = wlan_hdd_validate_context(pHddCtx);
3828 if (0 != status)
3829 {
3830 hddLog(VOS_TRACE_LEVEL_ERROR,
3831 FL("HDD context is not valid"));
3832 return -EINVAL;
3833 }
Dino Myclee8843b32014-07-04 14:21:45 +05303834 /* check the EXTScan Capability */
3835 if ( (TRUE != pHddCtx->cfg_ini->fEnableEXTScan) ||
3836 (TRUE != sme_IsFeatureSupportedByFW(EXTENDED_SCAN)))
3837 {
3838 hddLog(VOS_TRACE_LEVEL_ERROR,
3839 FL("EXTScan not enabled/supported by Firmware"));
3840 return -EINVAL;
3841 }
3842
Dino Mycle6fb96c12014-06-10 11:52:40 +05303843 if (nla_parse(tb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX,
3844 data, dataLen,
3845 wlan_hdd_extscan_config_policy)) {
3846 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Invalid ATTR"));
3847 return -EINVAL;
3848 }
3849
3850 /* Parse and fetch request Id */
3851 if (!tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_REQUEST_ID]) {
3852 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr request id failed"));
3853 return -EINVAL;
3854 }
3855
Dino Myclee8843b32014-07-04 14:21:45 +05303856 reqMsg.requestId = nla_get_u32(
Dino Mycle6fb96c12014-06-10 11:52:40 +05303857 tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_REQUEST_ID]);
Dino Myclee8843b32014-07-04 14:21:45 +05303858 hddLog(VOS_TRACE_LEVEL_INFO, FL("Req Id (%d)"), reqMsg.requestId);
Dino Mycle6fb96c12014-06-10 11:52:40 +05303859
Dino Myclee8843b32014-07-04 14:21:45 +05303860 reqMsg.sessionId = pAdapter->sessionId;
3861 hddLog(VOS_TRACE_LEVEL_INFO, FL("Session Id (%d)"), reqMsg.sessionId);
Dino Mycle6fb96c12014-06-10 11:52:40 +05303862
Dino Myclee8843b32014-07-04 14:21:45 +05303863 status = sme_ResetBssHotlist(pHddCtx->hHal, &reqMsg);
Dino Mycle6fb96c12014-06-10 11:52:40 +05303864 if (!HAL_STATUS_SUCCESS(status)) {
3865 hddLog(VOS_TRACE_LEVEL_ERROR,
3866 FL("sme_ResetBssHotlist failed(err=%d)"), status);
Dino Mycle6fb96c12014-06-10 11:52:40 +05303867 return -EINVAL;
3868 }
3869
3870 return 0;
3871}
3872
3873static int wlan_hdd_cfg80211_extscan_reset_significant_change(
3874 struct wiphy *wiphy,
3875 struct wireless_dev *wdev,
3876 void *data, int dataLen)
3877{
Dino Myclee8843b32014-07-04 14:21:45 +05303878 tSirEXTScanResetSignificantChangeReqParams reqMsg;
Dino Mycle6fb96c12014-06-10 11:52:40 +05303879 struct net_device *dev = wdev->netdev;
3880 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
3881 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
3882 struct nlattr *tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX + 1];
3883 eHalStatus status;
3884
3885 hddLog(VOS_TRACE_LEVEL_INFO, FL(" Entering"));
3886 status = wlan_hdd_validate_context(pHddCtx);
3887 if (0 != status)
3888 {
3889 hddLog(VOS_TRACE_LEVEL_ERROR,
3890 FL("HDD context is not valid"));
3891 return -EINVAL;
3892 }
Dino Myclee8843b32014-07-04 14:21:45 +05303893 /* check the EXTScan Capability */
3894 if ( (TRUE != pHddCtx->cfg_ini->fEnableEXTScan) ||
3895 (TRUE != sme_IsFeatureSupportedByFW(EXTENDED_SCAN)))
3896 {
3897 hddLog(VOS_TRACE_LEVEL_ERROR,
3898 FL("EXTScan not enabled/supported by Firmware"));
3899 return -EINVAL;
3900 }
3901
Dino Mycle6fb96c12014-06-10 11:52:40 +05303902 if (nla_parse(tb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX,
3903 data, dataLen,
3904 wlan_hdd_extscan_config_policy)) {
3905 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Invalid ATTR"));
3906 return -EINVAL;
3907 }
3908
3909 /* Parse and fetch request Id */
3910 if (!tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_REQUEST_ID]) {
3911 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr request id failed"));
3912 return -EINVAL;
3913 }
3914
Dino Mycle6fb96c12014-06-10 11:52:40 +05303915
Dino Myclee8843b32014-07-04 14:21:45 +05303916 reqMsg.requestId = nla_get_u32(
Dino Mycle6fb96c12014-06-10 11:52:40 +05303917 tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_REQUEST_ID]);
Dino Myclee8843b32014-07-04 14:21:45 +05303918 hddLog(VOS_TRACE_LEVEL_INFO, FL("Req Id (%d)"), reqMsg.requestId);
Dino Mycle6fb96c12014-06-10 11:52:40 +05303919
Dino Myclee8843b32014-07-04 14:21:45 +05303920 reqMsg.sessionId = pAdapter->sessionId;
3921 hddLog(VOS_TRACE_LEVEL_INFO, FL("Session Id (%d)"), reqMsg.sessionId);
Dino Mycle6fb96c12014-06-10 11:52:40 +05303922
Dino Myclee8843b32014-07-04 14:21:45 +05303923 status = sme_ResetSignificantChange(pHddCtx->hHal, &reqMsg);
Dino Mycle6fb96c12014-06-10 11:52:40 +05303924 if (!HAL_STATUS_SUCCESS(status)) {
3925 hddLog(VOS_TRACE_LEVEL_ERROR,
3926 FL("sme_ResetSignificantChange failed(err=%d)"), status);
Dino Mycle6fb96c12014-06-10 11:52:40 +05303927 return -EINVAL;
3928 }
3929
3930 hddLog(VOS_TRACE_LEVEL_ERROR, FL(" Exiting"));
3931 return 0;
3932}
3933
3934#endif /* WLAN_FEATURE_EXTSCAN */
3935
Atul Mittal115287b2014-07-08 13:26:33 +05303936/*EXT TDLS*/
3937static const struct nla_policy
3938wlan_hdd_tdls_config_enable_policy[QCA_WLAN_VENDOR_ATTR_TDLS_ENABLE_MAX +1] =
3939{
3940 [QCA_WLAN_VENDOR_ATTR_TDLS_ENABLE_MAC_ADDR] = {.type = NLA_UNSPEC },
3941 [QCA_WLAN_VENDOR_ATTR_TDLS_ENABLE_CHANNEL] = {.type = NLA_S32 },
3942 [QCA_WLAN_VENDOR_ATTR_TDLS_ENABLE_GLOBAL_OPERATING_CLASS] =
3943 {.type = NLA_S32 },
3944 [QCA_WLAN_VENDOR_ATTR_TDLS_ENABLE_MAX_LATENCY_MS] = {.type = NLA_S32 },
3945 [QCA_WLAN_VENDOR_ATTR_TDLS_ENABLE_MIN_BANDWIDTH_KBPS] = {.type = NLA_S32 },
3946
3947};
3948
3949static const struct nla_policy
3950wlan_hdd_tdls_config_disable_policy[QCA_WLAN_VENDOR_ATTR_TDLS_DISABLE_MAX +1] =
3951{
3952 [QCA_WLAN_VENDOR_ATTR_TDLS_DISABLE_MAC_ADDR] = {.type = NLA_UNSPEC },
3953
3954};
3955
3956static const struct nla_policy
3957wlan_hdd_tdls_config_state_change_policy[
3958 QCA_WLAN_VENDOR_ATTR_TDLS_STATE_MAX +1] =
3959{
3960 [QCA_WLAN_VENDOR_ATTR_TDLS_STATE_MAC_ADDR] = {.type = NLA_UNSPEC },
3961 [QCA_WLAN_VENDOR_ATTR_TDLS_NEW_STATE] = {.type = NLA_S32 },
3962 [QCA_WLAN_VENDOR_ATTR_TDLS_STATE_REASON] = {.type = NLA_S32 },
3963
3964};
3965
3966static const struct nla_policy
3967wlan_hdd_tdls_config_get_status_policy[
3968 QCA_WLAN_VENDOR_ATTR_TDLS_GET_STATUS_MAX +1] =
3969{
3970 [QCA_WLAN_VENDOR_ATTR_TDLS_GET_STATUS_MAC_ADDR] = {.type = NLA_UNSPEC },
3971 [QCA_WLAN_VENDOR_ATTR_TDLS_GET_STATUS_STATE] = {.type = NLA_S32 },
3972 [QCA_WLAN_VENDOR_ATTR_TDLS_GET_STATUS_REASON] = {.type = NLA_S32 },
3973
3974};
Siddharth Bhala3a5cb42014-09-29 21:13:13 +05303975
3976static const struct nla_policy
3977wlan_hdd_mac_config[QCA_WLAN_VENDOR_ATTR_SET_SCANNING_MAC_OUI_MAX+1] =
3978{
3979 [QCA_WLAN_VENDOR_ATTR_SET_SCANNING_MAC_OUI] = {.type = NLA_UNSPEC },
3980};
3981
3982static int wlan_hdd_cfg80211_set_spoofed_mac_oui(struct wiphy *wiphy,
3983 struct wireless_dev *wdev,
3984 void *data,
3985 int data_len)
3986{
3987
3988 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
3989 struct nlattr *tb[QCA_WLAN_VENDOR_ATTR_SET_SCANNING_MAC_OUI_MAX + 1];
3990
3991 if (0 != wlan_hdd_validate_context(pHddCtx)){
3992 hddLog(VOS_TRACE_LEVEL_ERROR, FL("hdd Ctx invalid while spoof macAddr"));
3993 return -EINVAL;
3994 }
3995 if (FALSE == pHddCtx->cfg_ini->enableMacSpoofing) {
3996 hddLog(VOS_TRACE_LEVEL_ERROR, FL("MAC_SPOOFED_SCAN disabled in ini"));
3997 return -ENOTSUPP;
3998 }
3999 if (TRUE != sme_IsFeatureSupportedByFW(MAC_SPOOFED_SCAN)){
4000 hddLog(VOS_TRACE_LEVEL_ERROR, FL("MAC_SPOOFED_SCAN not supported by FW"));
4001 return -ENOTSUPP;
4002 }
4003
4004 if (nla_parse(tb, QCA_WLAN_VENDOR_ATTR_SET_SCANNING_MAC_OUI_MAX,
4005 data, data_len, wlan_hdd_mac_config)) {
4006 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Invalid ATTR"));
4007 return -EINVAL;
4008 }
4009
4010 /* Parse and fetch mac address */
4011 if (!tb[QCA_WLAN_VENDOR_ATTR_SET_SCANNING_MAC_OUI]) {
4012 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr mac addr failed"));
4013 return -EINVAL;
4014 }
4015
4016 memcpy(pHddCtx->spoofMacAddr.randomMacAddr.bytes, nla_data(
4017 tb[QCA_WLAN_VENDOR_ATTR_SET_SCANNING_MAC_OUI]),
4018 VOS_MAC_ADDR_LAST_3_BYTES);
4019
4020 vos_trace_hex_dump( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,nla_data(
4021 tb[QCA_WLAN_VENDOR_ATTR_SET_SCANNING_MAC_OUI]),
4022 VOS_MAC_ADDR_FIRST_3_BYTES);
4023
4024 if (VOS_STATUS_SUCCESS != vos_randomize_n_bytes(
4025 (void *)(&pHddCtx->spoofMacAddr.randomMacAddr.bytes[3]),
4026 VOS_MAC_ADDR_LAST_3_BYTES)) {
4027 hddLog(LOGE, FL("Failed to generate random Mac Addr"));
4028 }
4029 vos_trace_hex_dump( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
4030 pHddCtx->spoofMacAddr.randomMacAddr.bytes,
4031 VOS_MAC_ADDR_SIZE);
4032
4033 if (eHAL_STATUS_SUCCESS != sme_SpoofMacAddrReq(pHddCtx->hHal,
4034 &pHddCtx->spoofMacAddr.randomMacAddr)) {
4035 hddLog(LOGE, FL("Failed to send Spoof Mac Addr to FW"));
4036 }
4037
4038 return 0;
4039}
4040
Atul Mittal115287b2014-07-08 13:26:33 +05304041static int wlan_hdd_cfg80211_exttdls_get_status(struct wiphy *wiphy,
4042 struct wireless_dev *wdev,
4043 void *data,
4044 int data_len)
4045{
4046 u8 peer[6] = {0};
4047 struct net_device *dev = wdev->netdev;
4048 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
4049 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
4050 struct nlattr *tb[QCA_WLAN_VENDOR_ATTR_TDLS_GET_STATUS_MAX + 1];
4051 eHalStatus ret;
4052 tANI_S32 state;
4053 tANI_S32 reason;
4054 struct sk_buff *skb = NULL;
4055
4056 ret = wlan_hdd_validate_context(pHddCtx);
4057 if (0 != ret) {
4058
4059 return -EINVAL;
4060 }
4061 if (pHddCtx->cfg_ini->fTDLSExternalControl == FALSE) {
4062
4063 return -ENOTSUPP;
4064 }
4065 if (nla_parse(tb, QCA_WLAN_VENDOR_ATTR_TDLS_GET_STATUS_MAX,
4066 data, data_len,
4067 wlan_hdd_tdls_config_get_status_policy)) {
4068 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Invalid ATTR"));
4069 return -EINVAL;
4070 }
4071
4072 /* Parse and fetch mac address */
4073 if (!tb[QCA_WLAN_VENDOR_ATTR_TDLS_GET_STATUS_MAC_ADDR]) {
4074 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr mac addr failed"));
4075 return -EINVAL;
4076 }
4077
4078 memcpy(peer, nla_data(
4079 tb[QCA_WLAN_VENDOR_ATTR_TDLS_GET_STATUS_MAC_ADDR]),
4080 sizeof(peer));
4081 hddLog(VOS_TRACE_LEVEL_INFO, FL(MAC_ADDRESS_STR),MAC_ADDR_ARRAY(peer));
4082
4083 ret = wlan_hdd_tdls_get_status(pAdapter, peer, &state, &reason);
4084
4085 if (0 != ret) {
4086 hddLog(VOS_TRACE_LEVEL_ERROR,
4087 FL("get status Failed"));
4088 return -EINVAL;
4089 }
4090 skb = cfg80211_vendor_cmd_alloc_reply_skb(wiphy,
4091 2 * sizeof(s32) +
4092 NLMSG_HDRLEN);
4093
4094 if (!skb) {
4095 hddLog(VOS_TRACE_LEVEL_ERROR,
4096 FL("cfg80211_vendor_cmd_alloc_reply_skb failed"));
4097 return -EINVAL;
4098 }
4099 hddLog(VOS_TRACE_LEVEL_INFO, FL("Reason (%d) Status (%d) tdls peer" MAC_ADDRESS_STR),
4100 reason,
4101 state,
4102 MAC_ADDR_ARRAY(peer));
4103
4104 if (nla_put_s32(skb, QCA_WLAN_VENDOR_ATTR_TDLS_GET_STATUS_STATE, state) ||
4105 nla_put_s32(skb, QCA_WLAN_VENDOR_ATTR_TDLS_GET_STATUS_REASON, reason)) {
4106
4107 hddLog(VOS_TRACE_LEVEL_ERROR, FL("nla put fail"));
4108 goto nla_put_failure;
4109 }
4110
4111 return cfg80211_vendor_cmd_reply(skb);
4112
4113nla_put_failure:
4114 kfree_skb(skb);
4115 return -EINVAL;
4116}
4117
4118static int wlan_hdd_cfg80211_exttdls_callback(tANI_U8* mac,
4119 tANI_S32 state,
4120 tANI_S32 reason,
4121 void *ctx)
4122{
4123 hdd_adapter_t* pAdapter = (hdd_adapter_t*)ctx;
4124 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
4125 struct sk_buff *skb = NULL;
4126
4127 if (wlan_hdd_validate_context(pHddCtx)) {
4128 hddLog(VOS_TRACE_LEVEL_ERROR, FL("HDD context is not valid "));
4129 return -EINVAL;
4130 }
4131
4132 if (pHddCtx->cfg_ini->fTDLSExternalControl == FALSE) {
4133
4134 return -ENOTSUPP;
4135 }
4136 skb = cfg80211_vendor_event_alloc(
4137 pHddCtx->wiphy,
4138 EXTTDLS_EVENT_BUF_SIZE + NLMSG_HDRLEN,
4139 QCA_NL80211_VENDOR_SUBCMD_TDLS_STATE_CHANGE_INDEX,
4140 GFP_KERNEL);
4141
4142 if (!skb) {
4143 hddLog(VOS_TRACE_LEVEL_ERROR,
4144 FL("cfg80211_vendor_event_alloc failed"));
4145 return -EINVAL;
4146 }
4147 hddLog(VOS_TRACE_LEVEL_INFO, FL("Entering "));
4148 hddLog(VOS_TRACE_LEVEL_INFO, "Reason (%d) Status (%d)", reason, state);
4149 hddLog(VOS_TRACE_LEVEL_WARN, "tdls peer " MAC_ADDRESS_STR,
4150 MAC_ADDR_ARRAY(mac));
4151
4152 if (nla_put(skb, QCA_WLAN_VENDOR_ATTR_TDLS_STATE_MAC_ADDR,
4153 VOS_MAC_ADDR_SIZE, mac) ||
4154 nla_put_s32(skb, QCA_WLAN_VENDOR_ATTR_TDLS_NEW_STATE, state) ||
4155 nla_put_s32(skb, QCA_WLAN_VENDOR_ATTR_TDLS_STATE_REASON, reason)
4156 ) {
4157
4158 hddLog(VOS_TRACE_LEVEL_ERROR, FL("nla put fail"));
4159 goto nla_put_failure;
4160 }
4161
4162 cfg80211_vendor_event(skb, GFP_KERNEL);
4163 return (0);
4164
4165nla_put_failure:
4166 kfree_skb(skb);
4167 return -EINVAL;
4168}
4169
4170static int wlan_hdd_cfg80211_exttdls_enable(struct wiphy *wiphy,
4171 struct wireless_dev *wdev,
4172 void *data,
4173 int data_len)
4174{
4175 u8 peer[6] = {0};
4176 struct net_device *dev = wdev->netdev;
4177 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
4178 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
4179 struct nlattr *tb[QCA_WLAN_VENDOR_ATTR_TDLS_ENABLE_MAX + 1];
4180 eHalStatus status;
4181 tdls_req_params_t pReqMsg = {0};
4182
4183 status = wlan_hdd_validate_context(pHddCtx);
4184 if (0 != status) {
4185 hddLog(VOS_TRACE_LEVEL_ERROR,
4186 FL("HDD context is not valid"));
4187 return -EINVAL;
4188 }
4189 if (pHddCtx->cfg_ini->fTDLSExternalControl == FALSE) {
4190
4191 return -ENOTSUPP;
4192 }
4193 if (nla_parse(tb, QCA_WLAN_VENDOR_ATTR_TDLS_ENABLE_MAX,
4194 data, data_len,
4195 wlan_hdd_tdls_config_enable_policy)) {
4196 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Invalid ATTR"));
4197 return -EINVAL;
4198 }
4199
4200 /* Parse and fetch mac address */
4201 if (!tb[QCA_WLAN_VENDOR_ATTR_TDLS_ENABLE_MAC_ADDR]) {
4202 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr mac addr failed"));
4203 return -EINVAL;
4204 }
4205
4206 memcpy(peer, nla_data(
4207 tb[QCA_WLAN_VENDOR_ATTR_TDLS_ENABLE_MAC_ADDR]),
4208 sizeof(peer));
4209 hddLog(VOS_TRACE_LEVEL_INFO, FL(MAC_ADDRESS_STR),MAC_ADDR_ARRAY(peer));
4210
4211 /* Parse and fetch channel */
4212 if (!tb[QCA_WLAN_VENDOR_ATTR_TDLS_ENABLE_CHANNEL]) {
4213 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr channel failed"));
4214 return -EINVAL;
4215 }
4216 pReqMsg.channel = nla_get_s32(
4217 tb[QCA_WLAN_VENDOR_ATTR_TDLS_ENABLE_CHANNEL]);
4218 hddLog(VOS_TRACE_LEVEL_INFO, FL("Channel Num (%d)"), pReqMsg.channel);
4219
4220 /* Parse and fetch global operating class */
4221 if (!tb[QCA_WLAN_VENDOR_ATTR_TDLS_ENABLE_GLOBAL_OPERATING_CLASS]) {
4222 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr operating class failed"));
4223 return -EINVAL;
4224 }
4225 pReqMsg.global_operating_class = nla_get_s32(
4226 tb[QCA_WLAN_VENDOR_ATTR_TDLS_ENABLE_GLOBAL_OPERATING_CLASS]);
4227 hddLog(VOS_TRACE_LEVEL_INFO, FL("Operating class (%d)"),
4228 pReqMsg.global_operating_class);
4229
4230 /* Parse and fetch latency ms */
4231 if (!tb[QCA_WLAN_VENDOR_ATTR_TDLS_ENABLE_MAX_LATENCY_MS]) {
4232 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr latency failed"));
4233 return -EINVAL;
4234 }
4235 pReqMsg.max_latency_ms = nla_get_s32(
4236 tb[QCA_WLAN_VENDOR_ATTR_TDLS_ENABLE_MAX_LATENCY_MS]);
4237 hddLog(VOS_TRACE_LEVEL_INFO, FL("Latency (%d)"),
4238 pReqMsg.max_latency_ms);
4239
4240 /* Parse and fetch required bandwidth kbps */
4241 if (!tb[QCA_WLAN_VENDOR_ATTR_TDLS_ENABLE_MIN_BANDWIDTH_KBPS]) {
4242 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr bandwidth failed"));
4243 return -EINVAL;
4244 }
4245
4246 pReqMsg.min_bandwidth_kbps = nla_get_s32(
4247 tb[QCA_WLAN_VENDOR_ATTR_TDLS_ENABLE_MIN_BANDWIDTH_KBPS]);
4248 hddLog(VOS_TRACE_LEVEL_INFO, FL("Bandwidth (%d)"),
4249 pReqMsg.min_bandwidth_kbps);
4250
4251 return (wlan_hdd_tdls_extctrl_config_peer(pAdapter,
4252 peer,
4253 wlan_hdd_cfg80211_exttdls_callback));
4254}
4255
4256static int wlan_hdd_cfg80211_exttdls_disable(struct wiphy *wiphy,
4257 struct wireless_dev *wdev,
4258 void *data,
4259 int data_len)
4260{
4261 u8 peer[6] = {0};
4262 struct net_device *dev = wdev->netdev;
4263 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
4264 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
4265 struct nlattr *tb[QCA_WLAN_VENDOR_ATTR_TDLS_DISABLE_MAX + 1];
4266 eHalStatus status;
4267
4268 status = wlan_hdd_validate_context(pHddCtx);
4269 if (0 != status) {
4270 hddLog(VOS_TRACE_LEVEL_ERROR,
4271 FL("HDD context is not valid"));
4272 return -EINVAL;
4273 }
4274 if (pHddCtx->cfg_ini->fTDLSExternalControl == FALSE) {
4275
4276 return -ENOTSUPP;
4277 }
4278 if (nla_parse(tb, QCA_WLAN_VENDOR_ATTR_TDLS_DISABLE_MAX,
4279 data, data_len,
4280 wlan_hdd_tdls_config_disable_policy)) {
4281 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Invalid ATTR"));
4282 return -EINVAL;
4283 }
4284 /* Parse and fetch mac address */
4285 if (!tb[QCA_WLAN_VENDOR_ATTR_TDLS_DISABLE_MAC_ADDR]) {
4286 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr mac addr failed"));
4287 return -EINVAL;
4288 }
4289
4290 memcpy(peer, nla_data(
4291 tb[QCA_WLAN_VENDOR_ATTR_TDLS_DISABLE_MAC_ADDR]),
4292 sizeof(peer));
4293 hddLog(VOS_TRACE_LEVEL_INFO, FL(MAC_ADDRESS_STR),MAC_ADDR_ARRAY(peer));
4294
4295 return (wlan_hdd_tdls_extctrl_deconfig_peer(pAdapter, peer));
4296}
4297
4298
Sunil Duttc69bccb2014-05-26 21:30:20 +05304299const struct wiphy_vendor_command hdd_wiphy_vendor_commands[] =
4300{
4301#ifdef WLAN_FEATURE_LINK_LAYER_STATS
4302 {
4303 .info.vendor_id = QCA_NL80211_VENDOR_ID,
4304 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_LL_STATS_CLR,
4305 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
4306 WIPHY_VENDOR_CMD_NEED_NETDEV |
4307 WIPHY_VENDOR_CMD_NEED_RUNNING,
4308 .doit = wlan_hdd_cfg80211_ll_stats_clear
4309 },
4310
4311 {
4312 .info.vendor_id = QCA_NL80211_VENDOR_ID,
4313 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_LL_STATS_SET,
4314 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
4315 WIPHY_VENDOR_CMD_NEED_NETDEV |
4316 WIPHY_VENDOR_CMD_NEED_RUNNING,
4317 .doit = wlan_hdd_cfg80211_ll_stats_set
4318 },
4319
4320 {
4321 .info.vendor_id = QCA_NL80211_VENDOR_ID,
4322 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_LL_STATS_GET,
4323 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
4324 WIPHY_VENDOR_CMD_NEED_NETDEV |
4325 WIPHY_VENDOR_CMD_NEED_RUNNING,
4326 .doit = wlan_hdd_cfg80211_ll_stats_get
Dino Mycle6fb96c12014-06-10 11:52:40 +05304327 },
Sunil Duttc69bccb2014-05-26 21:30:20 +05304328#endif /* WLAN_FEATURE_LINK_LAYER_STATS */
Dino Mycle6fb96c12014-06-10 11:52:40 +05304329#ifdef WLAN_FEATURE_EXTSCAN
4330 {
4331 .info.vendor_id = QCA_NL80211_VENDOR_ID,
4332 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_START,
4333 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
4334 WIPHY_VENDOR_CMD_NEED_NETDEV |
4335 WIPHY_VENDOR_CMD_NEED_RUNNING,
4336 .doit = wlan_hdd_cfg80211_extscan_start
4337 },
4338 {
4339 .info.vendor_id = QCA_NL80211_VENDOR_ID,
4340 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_STOP,
4341 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
4342 WIPHY_VENDOR_CMD_NEED_NETDEV |
4343 WIPHY_VENDOR_CMD_NEED_RUNNING,
4344 .doit = wlan_hdd_cfg80211_extscan_stop
4345 },
4346 {
4347 .info.vendor_id = QCA_NL80211_VENDOR_ID,
4348 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_GET_VALID_CHANNELS,
4349 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
4350 WIPHY_VENDOR_CMD_NEED_NETDEV,
4351 .doit = wlan_hdd_cfg80211_extscan_get_valid_channels
4352 },
4353 {
4354 .info.vendor_id = QCA_NL80211_VENDOR_ID,
4355 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_GET_CAPABILITIES,
4356 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
4357 WIPHY_VENDOR_CMD_NEED_NETDEV |
4358 WIPHY_VENDOR_CMD_NEED_RUNNING,
4359 .doit = wlan_hdd_cfg80211_extscan_get_capabilities
4360 },
4361 {
4362 .info.vendor_id = QCA_NL80211_VENDOR_ID,
4363 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_GET_CACHED_RESULTS,
4364 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
4365 WIPHY_VENDOR_CMD_NEED_NETDEV |
4366 WIPHY_VENDOR_CMD_NEED_RUNNING,
4367 .doit = wlan_hdd_cfg80211_extscan_get_cached_results
4368 },
4369 {
4370 .info.vendor_id = QCA_NL80211_VENDOR_ID,
4371 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_SET_BSSID_HOTLIST,
4372 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
4373 WIPHY_VENDOR_CMD_NEED_NETDEV |
4374 WIPHY_VENDOR_CMD_NEED_RUNNING,
4375 .doit = wlan_hdd_cfg80211_extscan_set_bssid_hotlist
4376 },
4377 {
4378 .info.vendor_id = QCA_NL80211_VENDOR_ID,
4379 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_RESET_BSSID_HOTLIST,
4380 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
4381 WIPHY_VENDOR_CMD_NEED_NETDEV |
4382 WIPHY_VENDOR_CMD_NEED_RUNNING,
4383 .doit = wlan_hdd_cfg80211_extscan_reset_bssid_hotlist
4384 },
4385 {
4386 .info.vendor_id = QCA_NL80211_VENDOR_ID,
4387 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_SET_SIGNIFICANT_CHANGE,
4388 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
4389 WIPHY_VENDOR_CMD_NEED_NETDEV |
4390 WIPHY_VENDOR_CMD_NEED_RUNNING,
4391 .doit = wlan_hdd_cfg80211_extscan_set_significant_change
4392 },
4393 {
4394 .info.vendor_id = QCA_NL80211_VENDOR_ID,
4395 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_RESET_SIGNIFICANT_CHANGE,
4396 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
4397 WIPHY_VENDOR_CMD_NEED_NETDEV |
4398 WIPHY_VENDOR_CMD_NEED_RUNNING,
4399 .doit = wlan_hdd_cfg80211_extscan_reset_significant_change
4400 },
4401#endif /* WLAN_FEATURE_EXTSCAN */
Atul Mittal115287b2014-07-08 13:26:33 +05304402/*EXT TDLS*/
4403 {
4404 .info.vendor_id = QCA_NL80211_VENDOR_ID,
4405 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_TDLS_ENABLE,
4406 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
4407 WIPHY_VENDOR_CMD_NEED_NETDEV |
4408 WIPHY_VENDOR_CMD_NEED_RUNNING,
4409 .doit = wlan_hdd_cfg80211_exttdls_enable
4410 },
4411 {
4412 .info.vendor_id = QCA_NL80211_VENDOR_ID,
4413 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_TDLS_DISABLE,
4414 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
4415 WIPHY_VENDOR_CMD_NEED_NETDEV |
4416 WIPHY_VENDOR_CMD_NEED_RUNNING,
4417 .doit = wlan_hdd_cfg80211_exttdls_disable
4418 },
4419 {
4420 .info.vendor_id = QCA_NL80211_VENDOR_ID,
4421 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_TDLS_GET_STATUS,
4422 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
4423 WIPHY_VENDOR_CMD_NEED_NETDEV,
4424 .doit = wlan_hdd_cfg80211_exttdls_get_status
4425 },
4426
Siddharth Bhala3a5cb42014-09-29 21:13:13 +05304427 {
4428 .info.vendor_id = QCA_NL80211_VENDOR_ID,
4429 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_MAC_OUI,
4430 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
4431 WIPHY_VENDOR_CMD_NEED_NETDEV,
4432 .doit = wlan_hdd_cfg80211_set_spoofed_mac_oui
4433 },
Sunil Duttc69bccb2014-05-26 21:30:20 +05304434};
4435
Rajesh Chauhan98a31f82014-01-06 20:15:25 -08004436/* vendor specific events */
Sunil Duttc69bccb2014-05-26 21:30:20 +05304437static const
4438struct nl80211_vendor_cmd_info wlan_hdd_cfg80211_vendor_events[] =
Rajesh Chauhan98a31f82014-01-06 20:15:25 -08004439{
4440#ifdef FEATURE_WLAN_CH_AVOID
4441 {
Sunil Duttc69bccb2014-05-26 21:30:20 +05304442 .vendor_id = QCA_NL80211_VENDOR_ID,
4443 .subcmd = QCA_NL80211_VENDOR_SUBCMD_AVOID_FREQUENCY
Rajesh Chauhan98a31f82014-01-06 20:15:25 -08004444 },
Sunil Duttc69bccb2014-05-26 21:30:20 +05304445#endif /* FEATURE_WLAN_CH_AVOID Index = 0*/
4446#ifdef WLAN_FEATURE_LINK_LAYER_STATS
4447 {
4448 /* Index = 1*/
4449 .vendor_id = QCA_NL80211_VENDOR_ID,
4450 .subcmd = QCA_NL80211_VENDOR_SUBCMD_LL_STATS_SET
4451 },
4452 {
4453 /* Index = 2*/
4454 .vendor_id = QCA_NL80211_VENDOR_ID,
4455 .subcmd = QCA_NL80211_VENDOR_SUBCMD_LL_STATS_GET
4456 },
4457 {
4458 /* Index = 3*/
4459 .vendor_id = QCA_NL80211_VENDOR_ID,
4460 .subcmd = QCA_NL80211_VENDOR_SUBCMD_LL_STATS_CLR
4461 },
4462 {
4463 /* Index = 4*/
4464 .vendor_id = QCA_NL80211_VENDOR_ID,
4465 .subcmd = QCA_NL80211_VENDOR_SUBCMD_LL_STATS_RADIO_RESULTS
4466 },
4467 {
4468 /* Index = 5*/
4469 .vendor_id = QCA_NL80211_VENDOR_ID,
4470 .subcmd = QCA_NL80211_VENDOR_SUBCMD_LL_STATS_IFACE_RESULTS
4471 },
4472 {
4473 /* Index = 6*/
4474 .vendor_id = QCA_NL80211_VENDOR_ID,
4475 .subcmd = QCA_NL80211_VENDOR_SUBCMD_LL_STATS_PEERS_RESULTS
4476 },
4477#endif /* WLAN_FEATURE_LINK_LAYER_STATS */
Dino Mycle6fb96c12014-06-10 11:52:40 +05304478#ifdef WLAN_FEATURE_EXTSCAN
4479 {
4480 .vendor_id = QCA_NL80211_VENDOR_ID,
4481 .subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_START
4482 },
4483 {
4484 .vendor_id = QCA_NL80211_VENDOR_ID,
4485 .subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_STOP
4486 },
4487 {
4488 .vendor_id = QCA_NL80211_VENDOR_ID,
4489 .subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_GET_CAPABILITIES
4490 },
4491 {
4492 .vendor_id = QCA_NL80211_VENDOR_ID,
4493 .subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_GET_CACHED_RESULTS
4494 },
4495 {
4496 .vendor_id = QCA_NL80211_VENDOR_ID,
4497 .subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_SCAN_RESULTS_AVAILABLE
4498 },
4499 {
4500 .vendor_id = QCA_NL80211_VENDOR_ID,
4501 .subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_FULL_SCAN_RESULT
4502 },
4503 {
4504 .vendor_id = QCA_NL80211_VENDOR_ID,
4505 .subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_SCAN_EVENT
4506 },
4507 {
4508 .vendor_id = QCA_NL80211_VENDOR_ID,
4509 .subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_HOTLIST_AP_FOUND
4510 },
4511 {
4512 .vendor_id = QCA_NL80211_VENDOR_ID,
4513 .subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_SET_BSSID_HOTLIST
4514 },
4515 {
4516 .vendor_id = QCA_NL80211_VENDOR_ID,
4517 .subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_RESET_BSSID_HOTLIST
4518 },
4519 {
4520 .vendor_id = QCA_NL80211_VENDOR_ID,
4521 .subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_SIGNIFICANT_CHANGE
4522 },
4523 {
4524 .vendor_id = QCA_NL80211_VENDOR_ID,
4525 .subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_SET_SIGNIFICANT_CHANGE
4526 },
4527 {
4528 .vendor_id = QCA_NL80211_VENDOR_ID,
4529 .subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_RESET_SIGNIFICANT_CHANGE
4530 },
4531#endif /* WLAN_FEATURE_EXTSCAN */
Atul Mittal115287b2014-07-08 13:26:33 +05304532/*EXT TDLS*/
4533 {
4534 .vendor_id = QCA_NL80211_VENDOR_ID,
4535 .subcmd = QCA_NL80211_VENDOR_SUBCMD_TDLS_STATE
4536 },
Rajesh Chauhan98a31f82014-01-06 20:15:25 -08004537};
4538
Jeff Johnson295189b2012-06-20 16:38:30 -07004539/*
Madan Mohan Koyyalamudi71278262013-04-12 22:00:48 +05304540 * FUNCTION: wlan_hdd_cfg80211_wiphy_alloc
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304541 * This function is called by hdd_wlan_startup()
4542 * during initialization.
Madan Mohan Koyyalamudi71278262013-04-12 22:00:48 +05304543 * This function is used to allocate wiphy structure.
Jeff Johnson295189b2012-06-20 16:38:30 -07004544 */
Madan Mohan Koyyalamudi71278262013-04-12 22:00:48 +05304545struct wiphy *wlan_hdd_cfg80211_wiphy_alloc(int priv_size)
Jeff Johnson295189b2012-06-20 16:38:30 -07004546{
4547 struct wiphy *wiphy;
4548 ENTER();
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304549 /*
4550 * Create wiphy device
Jeff Johnson295189b2012-06-20 16:38:30 -07004551 */
4552 wiphy = wiphy_new(&wlan_hdd_cfg80211_ops, priv_size);
4553
4554 if (!wiphy)
4555 {
4556 /* Print error and jump into err label and free the memory */
4557 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: wiphy init failed", __func__);
4558 return NULL;
4559 }
4560
Sunil Duttc69bccb2014-05-26 21:30:20 +05304561
Jeff Johnson295189b2012-06-20 16:38:30 -07004562 return wiphy;
4563}
4564
4565/*
4566 * FUNCTION: wlan_hdd_cfg80211_update_band
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304567 * This function is called from the supplicant through a
Jeff Johnson295189b2012-06-20 16:38:30 -07004568 * private ioctl to change the band value
4569 */
4570int wlan_hdd_cfg80211_update_band(struct wiphy *wiphy, eCsrBand eBand)
4571{
Gopichand Nakkala1f7a64f2013-04-01 18:37:17 +05304572 int i, j;
4573 eNVChannelEnabledType channelEnabledState;
4574
Jeff Johnsone7245742012-09-05 17:12:55 -07004575 ENTER();
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05304576
Gopichand Nakkala1f7a64f2013-04-01 18:37:17 +05304577 for (i = 0; i < IEEE80211_NUM_BANDS; i++)
Jeff Johnson295189b2012-06-20 16:38:30 -07004578 {
Gopichand Nakkala1f7a64f2013-04-01 18:37:17 +05304579
4580 if (NULL == wiphy->bands[i])
4581 {
4582 hddLog(VOS_TRACE_LEVEL_ERROR,"%s: wiphy->bands[i] is NULL, i = %d",
4583 __func__, i);
4584 continue;
4585 }
4586
4587 for (j = 0; j < wiphy->bands[i]->n_channels; j++)
4588 {
4589 struct ieee80211_supported_band *band = wiphy->bands[i];
4590
4591 channelEnabledState = vos_nv_getChannelEnabledState(
4592 band->channels[j].hw_value);
4593
4594 if (IEEE80211_BAND_2GHZ == i && eCSR_BAND_5G == eBand) // 5G only
4595 {
4596 // Enable Social channels for P2P
4597 if (WLAN_HDD_IS_SOCIAL_CHANNEL(band->channels[j].center_freq) &&
4598 NV_CHANNEL_ENABLE == channelEnabledState)
4599 band->channels[j].flags &= ~IEEE80211_CHAN_DISABLED;
4600 else
4601 band->channels[j].flags |= IEEE80211_CHAN_DISABLED;
4602 continue;
4603 }
4604 else if (IEEE80211_BAND_5GHZ == i && eCSR_BAND_24 == eBand) // 2G only
4605 {
4606 band->channels[j].flags |= IEEE80211_CHAN_DISABLED;
4607 continue;
4608 }
4609
4610 if (NV_CHANNEL_DISABLE == channelEnabledState ||
4611 NV_CHANNEL_INVALID == channelEnabledState)
4612 {
4613 band->channels[j].flags |= IEEE80211_CHAN_DISABLED;
4614 }
4615 else if (NV_CHANNEL_DFS == channelEnabledState)
4616 {
4617 band->channels[j].flags &= ~IEEE80211_CHAN_DISABLED;
4618 band->channels[j].flags |= IEEE80211_CHAN_RADAR;
4619 }
4620 else
4621 {
4622 band->channels[j].flags &= ~(IEEE80211_CHAN_DISABLED
4623 |IEEE80211_CHAN_RADAR);
4624 }
4625 }
Jeff Johnson295189b2012-06-20 16:38:30 -07004626 }
4627 return 0;
4628}
4629/*
4630 * FUNCTION: wlan_hdd_cfg80211_init
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304631 * This function is called by hdd_wlan_startup()
4632 * during initialization.
Jeff Johnson295189b2012-06-20 16:38:30 -07004633 * This function is used to initialize and register wiphy structure.
4634 */
Madan Mohan Koyyalamudi71278262013-04-12 22:00:48 +05304635int wlan_hdd_cfg80211_init(struct device *dev,
Jeff Johnson295189b2012-06-20 16:38:30 -07004636 struct wiphy *wiphy,
4637 hdd_config_t *pCfg
4638 )
4639{
Gopichand Nakkala1f7a64f2013-04-01 18:37:17 +05304640 int i, j;
Vinay Krishna Erannafacf5e22014-02-24 13:16:25 +05304641 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
4642
Jeff Johnsone7245742012-09-05 17:12:55 -07004643 ENTER();
4644
Jeff Johnson295189b2012-06-20 16:38:30 -07004645 /* Now bind the underlying wlan device with wiphy */
4646 set_wiphy_dev(wiphy, dev);
4647
4648 wiphy->mgmt_stypes = wlan_hdd_txrx_stypes;
Amar Singhalfddc28c2013-09-05 13:03:40 -07004649
Kiet Lam6c583332013-10-14 05:37:09 +05304650#ifndef CONFIG_ENABLE_LINUX_REG
Amar Singhal0a402232013-10-11 20:57:16 -07004651 /* the flag for the other case would be initialzed in
4652 vos_init_wiphy_from_nv_bin */
Amar Singhal0a402232013-10-11 20:57:16 -07004653 wiphy->flags |= WIPHY_FLAG_STRICT_REGULATORY;
Kiet Lam6c583332013-10-14 05:37:09 +05304654#endif
Amar Singhala49cbc52013-10-08 18:37:44 -07004655
Amar Singhalfddc28c2013-09-05 13:03:40 -07004656 /* This will disable updating of NL channels from passive to
4657 * active if a beacon is received on passive channel. */
4658 wiphy->flags |= WIPHY_FLAG_DISABLE_BEACON_HINTS;
Amar Singhalf0073192013-09-20 12:34:56 -07004659
Amar Singhalfddc28c2013-09-05 13:03:40 -07004660
Amar Singhala49cbc52013-10-08 18:37:44 -07004661
Jeff Johnson04dd8a82012-06-29 20:41:40 -07004662#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,4,0))
Madan Mohan Koyyalamudi1b4afb02012-10-22 15:25:16 -07004663 wiphy->flags |= WIPHY_FLAG_HAVE_AP_SME
4664 | WIPHY_FLAG_AP_PROBE_RESP_OFFLOAD
4665 | WIPHY_FLAG_HAS_REMAIN_ON_CHANNEL
Jeff Johnsone7245742012-09-05 17:12:55 -07004666 | WIPHY_FLAG_OFFCHAN_TX;
Kiet Lam6c583332013-10-14 05:37:09 +05304667 wiphy->country_ie_pref = NL80211_COUNTRY_IE_IGNORE_CORE;
Jeff Johnson04dd8a82012-06-29 20:41:40 -07004668#endif
Amar Singhala49cbc52013-10-08 18:37:44 -07004669
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08004670#if defined (WLAN_FEATURE_VOWIFI_11R) || defined (FEATURE_WLAN_ESE) || defined(FEATURE_WLAN_LFR)
Srinivas Girigowda640728a2013-03-28 12:21:54 -07004671 if (pCfg->isFastTransitionEnabled
James Zmuda77fb5ae2013-01-29 08:00:17 -08004672#ifdef FEATURE_WLAN_LFR
Srinivas Girigowda640728a2013-03-28 12:21:54 -07004673 || pCfg->isFastRoamIniFeatureEnabled
4674#endif
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08004675#ifdef FEATURE_WLAN_ESE
4676 || pCfg->isEseIniFeatureEnabled
Srinivas Girigowda640728a2013-03-28 12:21:54 -07004677#endif
4678 )
4679 {
4680 wiphy->flags |= WIPHY_FLAG_SUPPORTS_FW_ROAM;
4681 }
James Zmuda77fb5ae2013-01-29 08:00:17 -08004682#endif
Mohit Khanna698ba2a2012-12-04 15:08:18 -08004683#ifdef FEATURE_WLAN_TDLS
4684 wiphy->flags |= WIPHY_FLAG_SUPPORTS_TDLS
4685 | WIPHY_FLAG_TDLS_EXTERNAL_SETUP;
4686#endif
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +05304687#ifdef FEATURE_WLAN_SCAN_PNO
Hardik Kantilal Patel3dfd8792013-11-13 20:34:57 +05304688 if (pCfg->configPNOScanSupport)
4689 {
4690 wiphy->flags |= WIPHY_FLAG_SUPPORTS_SCHED_SCAN;
4691 wiphy->max_sched_scan_ssids = SIR_PNO_MAX_SUPP_NETWORKS;
4692 wiphy->max_match_sets = SIR_PNO_MAX_SUPP_NETWORKS;
4693 wiphy->max_sched_scan_ie_len = SIR_MAC_MAX_IE_LENGTH;
4694 }
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +05304695#endif/*FEATURE_WLAN_SCAN_PNO*/
Mohit Khanna698ba2a2012-12-04 15:08:18 -08004696
Amar Singhalfddc28c2013-09-05 13:03:40 -07004697#ifdef CONFIG_ENABLE_LINUX_REG
Madan Mohan Koyyalamudic3a240c2012-09-28 15:34:08 -07004698 /* even with WIPHY_FLAG_CUSTOM_REGULATORY,
4699 driver can still register regulatory callback and
Amar Singhalfddc28c2013-09-05 13:03:40 -07004700 it will get regulatory settings in wiphy->band[], but
Madan Mohan Koyyalamudic3a240c2012-09-28 15:34:08 -07004701 driver need to determine what to do with both
4702 regulatory settings */
Amar Singhalfddc28c2013-09-05 13:03:40 -07004703
4704 wiphy->reg_notifier = wlan_hdd_linux_reg_notifier;
Amar Singhala49cbc52013-10-08 18:37:44 -07004705#else
4706 wiphy->reg_notifier = wlan_hdd_crda_reg_notifier;
Amar Singhalfddc28c2013-09-05 13:03:40 -07004707#endif
Jeff Johnson04dd8a82012-06-29 20:41:40 -07004708
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304709 wiphy->max_scan_ssids = MAX_SCAN_SSID;
4710
Madan Mohan Koyyalamudi6815b162013-07-19 17:17:46 +05304711 wiphy->max_scan_ie_len = SIR_MAC_MAX_IE_LENGTH;
Jeff Johnson295189b2012-06-20 16:38:30 -07004712
Gopichand Nakkalac005b7c2013-05-14 16:04:14 +05304713 wiphy->max_acl_mac_addrs = MAX_ACL_MAC_ADDRESS;
4714
Jeff Johnson295189b2012-06-20 16:38:30 -07004715 /* Supports STATION & AD-HOC modes right now */
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304716 wiphy->interface_modes = BIT(NL80211_IFTYPE_STATION)
Jeff Johnson295189b2012-06-20 16:38:30 -07004717 | BIT(NL80211_IFTYPE_ADHOC)
Jeff Johnson295189b2012-06-20 16:38:30 -07004718 | BIT(NL80211_IFTYPE_P2P_CLIENT)
4719 | BIT(NL80211_IFTYPE_P2P_GO)
Jeff Johnson295189b2012-06-20 16:38:30 -07004720 | BIT(NL80211_IFTYPE_AP);
4721
Rashmi Ramannabd3feb72014-02-25 16:14:48 +05304722 if( pCfg->advertiseConcurrentOperation )
Sudhir Sattayappa Kohalli278eee52013-01-16 17:35:13 -08004723 {
Rashmi Ramannabd3feb72014-02-25 16:14:48 +05304724#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,4,0))
4725 if( pCfg->enableMCC )
4726 {
4727 /* Currently, supports up to two channels */
4728 wlan_hdd_iface_combination.num_different_channels = 2;
Sudhir Sattayappa Kohalli278eee52013-01-16 17:35:13 -08004729
Rashmi Ramannabd3feb72014-02-25 16:14:48 +05304730 if( !pCfg->allowMCCGODiffBI )
4731 wlan_hdd_iface_combination.beacon_int_infra_match = true;
Sudhir Sattayappa Kohalli278eee52013-01-16 17:35:13 -08004732
Rashmi Ramannabd3feb72014-02-25 16:14:48 +05304733 }
4734 wiphy->iface_combinations = &wlan_hdd_iface_combination;
4735 wiphy->n_iface_combinations = 1;
Sudhir Sattayappa Kohalli278eee52013-01-16 17:35:13 -08004736#endif
Rashmi Ramannabd3feb72014-02-25 16:14:48 +05304737 }
Sudhir Sattayappa Kohalli278eee52013-01-16 17:35:13 -08004738
Jeff Johnson295189b2012-06-20 16:38:30 -07004739 /* Before registering we need to update the ht capabilitied based
4740 * on ini values*/
4741 if( !pCfg->ShortGI20MhzEnable )
4742 {
4743 wlan_hdd_band_2_4_GHZ.ht_cap.cap &= ~IEEE80211_HT_CAP_SGI_20;
4744 wlan_hdd_band_5_GHZ.ht_cap.cap &= ~IEEE80211_HT_CAP_SGI_20;
4745 wlan_hdd_band_p2p_2_4_GHZ.ht_cap.cap &= ~IEEE80211_HT_CAP_SGI_20;
4746 }
4747
4748 if( !pCfg->ShortGI40MhzEnable )
4749 {
4750 wlan_hdd_band_5_GHZ.ht_cap.cap &= ~IEEE80211_HT_CAP_SGI_40;
4751 }
4752
4753 if( !pCfg->nChannelBondingMode5GHz )
4754 {
4755 wlan_hdd_band_5_GHZ.ht_cap.cap &= ~IEEE80211_HT_CAP_SUP_WIDTH_20_40;
4756 }
4757
Gopichand Nakkala1f7a64f2013-04-01 18:37:17 +05304758 wiphy->bands[IEEE80211_BAND_2GHZ] = &wlan_hdd_band_2_4_GHZ;
Vinay Krishna Erannafacf5e22014-02-24 13:16:25 +05304759 if (true == hdd_is_5g_supported(pHddCtx))
4760 {
4761 wiphy->bands[IEEE80211_BAND_5GHZ] = &wlan_hdd_band_5_GHZ;
4762 }
Gopichand Nakkala1f7a64f2013-04-01 18:37:17 +05304763
4764 for (i = 0; i < IEEE80211_NUM_BANDS; i++)
4765 {
4766
4767 if (NULL == wiphy->bands[i])
4768 {
4769 hddLog(VOS_TRACE_LEVEL_ERROR,"%s: wiphy->bands[i] is NULL, i = %d",
4770 __func__, i);
4771 continue;
4772 }
4773
4774 for (j = 0; j < wiphy->bands[i]->n_channels; j++)
4775 {
4776 struct ieee80211_supported_band *band = wiphy->bands[i];
4777
4778 if (IEEE80211_BAND_2GHZ == i && eCSR_BAND_5G == pCfg->nBandCapability) // 5G only
4779 {
4780 // Enable social channels for P2P
4781 if (WLAN_HDD_IS_SOCIAL_CHANNEL(band->channels[j].center_freq))
4782 band->channels[j].flags &= ~IEEE80211_CHAN_DISABLED;
4783 else
4784 band->channels[j].flags |= IEEE80211_CHAN_DISABLED;
4785 continue;
4786 }
4787 else if (IEEE80211_BAND_5GHZ == i && eCSR_BAND_24 == pCfg->nBandCapability) // 2G only
4788 {
4789 band->channels[j].flags |= IEEE80211_CHAN_DISABLED;
4790 continue;
4791 }
4792 }
Jeff Johnson295189b2012-06-20 16:38:30 -07004793 }
4794 /*Initialise the supported cipher suite details*/
4795 wiphy->cipher_suites = hdd_cipher_suites;
4796 wiphy->n_cipher_suites = ARRAY_SIZE(hdd_cipher_suites);
4797
4798 /*signal strength in mBm (100*dBm) */
4799 wiphy->signal_type = CFG80211_SIGNAL_TYPE_MBM;
4800
4801#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
Sushant Kaushik4f640e42014-07-08 12:27:09 +05304802 wiphy->max_remain_on_channel_duration = 5000;
Jeff Johnson295189b2012-06-20 16:38:30 -07004803#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07004804
Sunil Duttc69bccb2014-05-26 21:30:20 +05304805 wiphy->n_vendor_commands = ARRAY_SIZE(hdd_wiphy_vendor_commands);
4806 wiphy->vendor_commands = hdd_wiphy_vendor_commands;
Rajesh Chauhan98a31f82014-01-06 20:15:25 -08004807 wiphy->vendor_events = wlan_hdd_cfg80211_vendor_events;
4808 wiphy->n_vendor_events = ARRAY_SIZE(wlan_hdd_cfg80211_vendor_events);
4809
Madan Mohan Koyyalamudi71278262013-04-12 22:00:48 +05304810 EXIT();
4811 return 0;
4812}
4813
4814/* In this function we are registering wiphy. */
4815int wlan_hdd_cfg80211_register(struct wiphy *wiphy)
4816{
4817 ENTER();
4818 /* Register our wiphy dev with cfg80211 */
Jeff Johnson295189b2012-06-20 16:38:30 -07004819 if (0 > wiphy_register(wiphy))
4820 {
Madan Mohan Koyyalamudi71278262013-04-12 22:00:48 +05304821 /* print error */
Jeff Johnson295189b2012-06-20 16:38:30 -07004822 hddLog(VOS_TRACE_LEVEL_ERROR,"%s: wiphy register failed", __func__);
4823 return -EIO;
4824 }
4825
4826 EXIT();
4827 return 0;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304828}
Jeff Johnson295189b2012-06-20 16:38:30 -07004829
Madan Mohan Koyyalamudi71278262013-04-12 22:00:48 +05304830/* In this function we are updating channel list when,
4831 regulatory domain is FCC and country code is US.
4832 Here In FCC standard 5GHz UNII-1 Bands are indoor only.
4833 As per FCC smart phone is not a indoor device.
4834 GO should not opeate on indoor channels */
4835void wlan_hdd_cfg80211_update_reg_info(struct wiphy *wiphy)
4836{
4837 int j;
4838 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
4839 tANI_U8 defaultCountryCode[3] = SME_INVALID_COUNTRY_CODE;
4840 //Default counrtycode from NV at the time of wiphy initialization.
4841 if (eHAL_STATUS_SUCCESS != sme_GetDefaultCountryCodeFrmNv(pHddCtx->hHal,
4842 &defaultCountryCode[0]))
4843 {
Jeff Johnson0299d0a2013-10-30 12:37:43 -07004844 hddLog(LOGE, FL("Failed to get default country code from NV"));
Madan Mohan Koyyalamudi71278262013-04-12 22:00:48 +05304845 }
4846 if ((defaultCountryCode[0]== 'U') && (defaultCountryCode[1]=='S'))
4847 {
Madan Mohan Koyyalamudi71278262013-04-12 22:00:48 +05304848 if (NULL == wiphy->bands[IEEE80211_BAND_5GHZ])
4849 {
4850 hddLog(VOS_TRACE_LEVEL_ERROR,"%s: wiphy->bands[IEEE80211_BAND_5GHZ] is NULL",__func__ );
4851 return;
4852 }
4853 for (j = 0; j < wiphy->bands[IEEE80211_BAND_5GHZ]->n_channels; j++)
4854 {
4855 struct ieee80211_supported_band *band = wiphy->bands[IEEE80211_BAND_5GHZ];
4856 // Mark UNII -1 band channel as passive
4857 if (WLAN_HDD_CHANNEL_IN_UNII_1_BAND(band->channels[j].center_freq))
4858 band->channels[j].flags |= IEEE80211_CHAN_PASSIVE_SCAN;
4859 }
4860 }
4861}
4862
Agarwal Ashish8fa0e9a2014-05-23 00:40:12 +05304863/* This function registers for all frame which supplicant is interested in */
4864void wlan_hdd_cfg80211_register_frames(hdd_adapter_t* pAdapter)
Jeff Johnson295189b2012-06-20 16:38:30 -07004865{
Jeff Johnson295189b2012-06-20 16:38:30 -07004866 tHalHandle hHal = WLAN_HDD_GET_HAL_CTX(pAdapter);
4867 /* Register for all P2P action, public action etc frames */
4868 v_U16_t type = (SIR_MAC_MGMT_FRAME << 2) | ( SIR_MAC_MGMT_ACTION << 4);
4869
Jeff Johnsone7245742012-09-05 17:12:55 -07004870 ENTER();
4871
Jeff Johnson295189b2012-06-20 16:38:30 -07004872 /* Right now we are registering these frame when driver is getting
4873 initialized. Once we will move to 2.6.37 kernel, in which we have
4874 frame register ops, we will move this code as a part of that */
4875 /* GAS Initial Request */
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304876 sme_RegisterMgmtFrame(hHal, pAdapter->sessionId, type,
Jeff Johnson295189b2012-06-20 16:38:30 -07004877 (v_U8_t*)GAS_INITIAL_REQ, GAS_INITIAL_REQ_SIZE );
4878
4879 /* GAS Initial Response */
4880 sme_RegisterMgmtFrame(hHal, pAdapter->sessionId, type,
4881 (v_U8_t*)GAS_INITIAL_RSP, GAS_INITIAL_RSP_SIZE );
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304882
Jeff Johnson295189b2012-06-20 16:38:30 -07004883 /* GAS Comeback Request */
4884 sme_RegisterMgmtFrame(hHal, pAdapter->sessionId, type,
4885 (v_U8_t*)GAS_COMEBACK_REQ, GAS_COMEBACK_REQ_SIZE );
4886
4887 /* GAS Comeback Response */
4888 sme_RegisterMgmtFrame(hHal, pAdapter->sessionId, type,
4889 (v_U8_t*)GAS_COMEBACK_RSP, GAS_COMEBACK_RSP_SIZE );
4890
4891 /* P2P Public Action */
4892 sme_RegisterMgmtFrame(hHal, pAdapter->sessionId, type,
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304893 (v_U8_t*)P2P_PUBLIC_ACTION_FRAME,
Jeff Johnson295189b2012-06-20 16:38:30 -07004894 P2P_PUBLIC_ACTION_FRAME_SIZE );
4895
4896 /* P2P Action */
4897 sme_RegisterMgmtFrame(hHal, pAdapter->sessionId, type,
4898 (v_U8_t*)P2P_ACTION_FRAME,
4899 P2P_ACTION_FRAME_SIZE );
Chet Lanctot186b5732013-03-18 10:26:30 -07004900
Gopichand Nakkalae3d56e72013-04-21 23:33:32 +05304901 /* WNM BSS Transition Request frame */
4902 sme_RegisterMgmtFrame(hHal, pAdapter->sessionId, type,
4903 (v_U8_t*)WNM_BSS_ACTION_FRAME,
4904 WNM_BSS_ACTION_FRAME_SIZE );
Leela Venkata Kiran Kumar Reddy Chiralae8e62c82013-10-29 18:23:26 -07004905
4906 /* WNM-Notification */
4907 sme_RegisterMgmtFrame(hHal, pAdapter->sessionId, type,
4908 (v_U8_t*)WNM_NOTIFICATION_FRAME,
4909 WNM_NOTIFICATION_FRAME_SIZE );
Jeff Johnson295189b2012-06-20 16:38:30 -07004910}
4911
Agarwal Ashish8fa0e9a2014-05-23 00:40:12 +05304912void wlan_hdd_cfg80211_deregister_frames(hdd_adapter_t* pAdapter)
Jeff Johnson295189b2012-06-20 16:38:30 -07004913{
Jeff Johnson295189b2012-06-20 16:38:30 -07004914 tHalHandle hHal = WLAN_HDD_GET_HAL_CTX(pAdapter);
4915 /* Register for all P2P action, public action etc frames */
4916 v_U16_t type = (SIR_MAC_MGMT_FRAME << 2) | ( SIR_MAC_MGMT_ACTION << 4);
4917
Jeff Johnsone7245742012-09-05 17:12:55 -07004918 ENTER();
4919
Jeff Johnson295189b2012-06-20 16:38:30 -07004920 /* Right now we are registering these frame when driver is getting
4921 initialized. Once we will move to 2.6.37 kernel, in which we have
4922 frame register ops, we will move this code as a part of that */
4923 /* GAS Initial Request */
4924
4925 sme_DeregisterMgmtFrame(hHal, pAdapter->sessionId, type,
4926 (v_U8_t*)GAS_INITIAL_REQ, GAS_INITIAL_REQ_SIZE );
4927
4928 /* GAS Initial Response */
4929 sme_DeregisterMgmtFrame(hHal, pAdapter->sessionId, type,
4930 (v_U8_t*)GAS_INITIAL_RSP, GAS_INITIAL_RSP_SIZE );
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304931
Jeff Johnson295189b2012-06-20 16:38:30 -07004932 /* GAS Comeback Request */
4933 sme_DeregisterMgmtFrame(hHal, pAdapter->sessionId, type,
4934 (v_U8_t*)GAS_COMEBACK_REQ, GAS_COMEBACK_REQ_SIZE );
4935
4936 /* GAS Comeback Response */
4937 sme_DeregisterMgmtFrame(hHal, pAdapter->sessionId, type,
4938 (v_U8_t*)GAS_COMEBACK_RSP, GAS_COMEBACK_RSP_SIZE );
4939
4940 /* P2P Public Action */
4941 sme_DeregisterMgmtFrame(hHal, pAdapter->sessionId, type,
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304942 (v_U8_t*)P2P_PUBLIC_ACTION_FRAME,
Jeff Johnson295189b2012-06-20 16:38:30 -07004943 P2P_PUBLIC_ACTION_FRAME_SIZE );
4944
4945 /* P2P Action */
4946 sme_DeregisterMgmtFrame(hHal, pAdapter->sessionId, type,
4947 (v_U8_t*)P2P_ACTION_FRAME,
4948 P2P_ACTION_FRAME_SIZE );
Leela Venkata Kiran Kumar Reddy Chiralae8e62c82013-10-29 18:23:26 -07004949 /* WNM-Notification */
4950 sme_DeregisterMgmtFrame(hHal, pAdapter->sessionId, type,
4951 (v_U8_t*)WNM_NOTIFICATION_FRAME,
4952 WNM_NOTIFICATION_FRAME_SIZE );
Jeff Johnson295189b2012-06-20 16:38:30 -07004953}
4954
4955#ifdef FEATURE_WLAN_WAPI
4956void wlan_hdd_cfg80211_set_key_wapi(hdd_adapter_t* pAdapter, u8 key_index,
4957 const u8 *mac_addr, u8 *key , int key_Len)
4958{
4959 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
4960 tCsrRoamSetKey setKey;
4961 v_BOOL_t isConnected = TRUE;
4962 int status = 0;
4963 v_U32_t roamId= 0xFF;
4964 tANI_U8 *pKeyPtr = NULL;
4965 int n = 0;
4966
Sushant Kaushik8bc7df22014-04-09 17:55:29 +05304967 hddLog(VOS_TRACE_LEVEL_INFO, "%s: device_mode = %s(%d)",
4968 __func__, hdd_device_modetoString(pAdapter->device_mode),
4969 pAdapter->device_mode);
Jeff Johnson295189b2012-06-20 16:38:30 -07004970
Gopichand Nakkalae7480202013-02-11 15:24:22 +05304971 vos_mem_zero(&setKey, sizeof(tCsrRoamSetKey));
Jeff Johnson295189b2012-06-20 16:38:30 -07004972 setKey.keyId = key_index; // Store Key ID
4973 setKey.encType = eCSR_ENCRYPT_TYPE_WPI; // SET WAPI Encryption
4974 setKey.keyDirection = eSIR_TX_RX; // Key Directionn both TX and RX
4975 setKey.paeRole = 0 ; // the PAE role
4976 if (!mac_addr || is_broadcast_ether_addr(mac_addr))
4977 {
4978 vos_set_macaddr_broadcast( (v_MACADDR_t *)setKey.peerMac );
4979 }
4980 else
4981 {
4982 isConnected = hdd_connIsConnected(pHddStaCtx);
4983 vos_mem_copy(setKey.peerMac,&pHddStaCtx->conn_info.bssId,WNI_CFG_BSSID_LEN);
4984 }
4985 setKey.keyLength = key_Len;
4986 pKeyPtr = setKey.Key;
4987 memcpy( pKeyPtr, key, key_Len);
4988
Arif Hussain6d2a3322013-11-17 19:50:10 -08004989 hddLog(VOS_TRACE_LEVEL_INFO,"%s: WAPI KEY LENGTH:0x%04x",
Jeff Johnson295189b2012-06-20 16:38:30 -07004990 __func__, key_Len);
4991 for (n = 0 ; n < key_Len; n++)
4992 hddLog(VOS_TRACE_LEVEL_INFO, "%s WAPI KEY Data[%d]:%02x ",
4993 __func__,n,setKey.Key[n]);
4994
4995 pHddStaCtx->roam_info.roamingState = HDD_ROAM_STATE_SETTING_KEY;
4996 if ( isConnected )
4997 {
4998 status= sme_RoamSetKey( WLAN_HDD_GET_HAL_CTX(pAdapter),
4999 pAdapter->sessionId, &setKey, &roamId );
5000 }
5001 if ( status != 0 )
5002 {
5003 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
5004 "[%4d] sme_RoamSetKey returned ERROR status= %d",
5005 __LINE__, status );
5006 pHddStaCtx->roam_info.roamingState = HDD_ROAM_STATE_NONE;
5007 }
5008}
5009#endif /* FEATURE_WLAN_WAPI*/
5010
5011#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,4,0))
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305012int wlan_hdd_cfg80211_alloc_new_beacon(hdd_adapter_t *pAdapter,
Jeff Johnson295189b2012-06-20 16:38:30 -07005013 beacon_data_t **ppBeacon,
5014 struct beacon_parameters *params)
Jeff Johnson04dd8a82012-06-29 20:41:40 -07005015#else
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305016int wlan_hdd_cfg80211_alloc_new_beacon(hdd_adapter_t *pAdapter,
Jeff Johnson04dd8a82012-06-29 20:41:40 -07005017 beacon_data_t **ppBeacon,
5018 struct cfg80211_beacon_data *params,
5019 int dtim_period)
5020#endif
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305021{
Jeff Johnson295189b2012-06-20 16:38:30 -07005022 int size;
5023 beacon_data_t *beacon = NULL;
5024 beacon_data_t *old = NULL;
5025 int head_len,tail_len;
5026
Jeff Johnsone7245742012-09-05 17:12:55 -07005027 ENTER();
Jeff Johnson295189b2012-06-20 16:38:30 -07005028 if (params->head && !params->head_len)
c_hpothu6ff1c3c2013-10-01 19:01:57 +05305029 {
5030 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
5031 FL("head_len is NULL"));
Jeff Johnson295189b2012-06-20 16:38:30 -07005032 return -EINVAL;
c_hpothu6ff1c3c2013-10-01 19:01:57 +05305033 }
Jeff Johnson295189b2012-06-20 16:38:30 -07005034
5035 old = pAdapter->sessionCtx.ap.beacon;
5036
5037 if (!params->head && !old)
c_hpothu6ff1c3c2013-10-01 19:01:57 +05305038 {
5039 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
5040 FL("session(%d) old and new heads points to NULL"),
5041 pAdapter->sessionId);
Jeff Johnson295189b2012-06-20 16:38:30 -07005042 return -EINVAL;
c_hpothu6ff1c3c2013-10-01 19:01:57 +05305043 }
5044
5045 if (params->tail && !params->tail_len)
5046 {
5047 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
5048 FL("tail_len is zero but tail is not NULL"));
5049 return -EINVAL;
5050 }
Jeff Johnson295189b2012-06-20 16:38:30 -07005051
Jeff Johnson295189b2012-06-20 16:38:30 -07005052#if (LINUX_VERSION_CODE <= KERNEL_VERSION(2,6,38))
5053 /* Kernel 3.0 is not updating dtim_period for set beacon */
5054 if (!params->dtim_period)
c_hpothu6ff1c3c2013-10-01 19:01:57 +05305055 {
5056 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
5057 FL("dtim period is 0"));
Jeff Johnson295189b2012-06-20 16:38:30 -07005058 return -EINVAL;
c_hpothu6ff1c3c2013-10-01 19:01:57 +05305059 }
Jeff Johnson295189b2012-06-20 16:38:30 -07005060#endif
5061
5062 if(params->head)
5063 head_len = params->head_len;
5064 else
5065 head_len = old->head_len;
5066
5067 if(params->tail || !old)
5068 tail_len = params->tail_len;
5069 else
5070 tail_len = old->tail_len;
5071
5072 size = sizeof(beacon_data_t) + head_len + tail_len;
5073
5074 beacon = kzalloc(size, GFP_KERNEL);
5075
5076 if( beacon == NULL )
c_hpothu6ff1c3c2013-10-01 19:01:57 +05305077 {
5078 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
5079 FL("Mem allocation for beacon failed"));
Jeff Johnson295189b2012-06-20 16:38:30 -07005080 return -ENOMEM;
c_hpothu6ff1c3c2013-10-01 19:01:57 +05305081 }
Jeff Johnson295189b2012-06-20 16:38:30 -07005082
Jeff Johnson04dd8a82012-06-29 20:41:40 -07005083#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,4,0))
Jeff Johnson295189b2012-06-20 16:38:30 -07005084 if(params->dtim_period || !old )
5085 beacon->dtim_period = params->dtim_period;
5086 else
5087 beacon->dtim_period = old->dtim_period;
Jeff Johnson04dd8a82012-06-29 20:41:40 -07005088#else
5089 if(dtim_period || !old )
5090 beacon->dtim_period = dtim_period;
5091 else
5092 beacon->dtim_period = old->dtim_period;
5093#endif
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305094
Jeff Johnson295189b2012-06-20 16:38:30 -07005095 beacon->head = ((u8 *) beacon) + sizeof(beacon_data_t);
5096 beacon->tail = beacon->head + head_len;
5097 beacon->head_len = head_len;
5098 beacon->tail_len = tail_len;
5099
5100 if(params->head) {
5101 memcpy (beacon->head,params->head,beacon->head_len);
5102 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305103 else {
Jeff Johnson295189b2012-06-20 16:38:30 -07005104 if(old)
5105 memcpy (beacon->head,old->head,beacon->head_len);
5106 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305107
Jeff Johnson295189b2012-06-20 16:38:30 -07005108 if(params->tail) {
5109 memcpy (beacon->tail,params->tail,beacon->tail_len);
5110 }
5111 else {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305112 if(old)
Jeff Johnson295189b2012-06-20 16:38:30 -07005113 memcpy (beacon->tail,old->tail,beacon->tail_len);
5114 }
5115
5116 *ppBeacon = beacon;
5117
5118 kfree(old);
5119
5120 return 0;
5121
5122}
Jeff Johnson295189b2012-06-20 16:38:30 -07005123
5124v_U8_t* wlan_hdd_cfg80211_get_ie_ptr(v_U8_t *pIes, int length, v_U8_t eid)
5125{
5126 int left = length;
5127 v_U8_t *ptr = pIes;
5128 v_U8_t elem_id,elem_len;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305129
Jeff Johnson295189b2012-06-20 16:38:30 -07005130 while(left >= 2)
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305131 {
Jeff Johnson295189b2012-06-20 16:38:30 -07005132 elem_id = ptr[0];
5133 elem_len = ptr[1];
5134 left -= 2;
5135 if(elem_len > left)
5136 {
5137 hddLog(VOS_TRACE_LEVEL_FATAL,
Madan Mohan Koyyalamudi8bdd3112012-09-24 13:55:14 -07005138 FL("****Invalid IEs eid = %d elem_len=%d left=%d*****"),
Jeff Johnson295189b2012-06-20 16:38:30 -07005139 eid,elem_len,left);
5140 return NULL;
5141 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305142 if (elem_id == eid)
Jeff Johnson295189b2012-06-20 16:38:30 -07005143 {
5144 return ptr;
5145 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305146
Jeff Johnson295189b2012-06-20 16:38:30 -07005147 left -= elem_len;
5148 ptr += (elem_len + 2);
5149 }
5150 return NULL;
5151}
5152
Jeff Johnson295189b2012-06-20 16:38:30 -07005153/* Check if rate is 11g rate or not */
5154static int wlan_hdd_rate_is_11g(u8 rate)
5155{
Sanjay Devnani28322e22013-06-21 16:13:40 -07005156 static const u8 gRateArray[8] = {12, 18, 24, 36, 48, 72, 96, 108}; /* actual rate * 2 */
Jeff Johnson295189b2012-06-20 16:38:30 -07005157 u8 i;
5158 for (i = 0; i < 8; i++)
5159 {
5160 if(rate == gRateArray[i])
5161 return TRUE;
5162 }
5163 return FALSE;
5164}
5165
5166/* Check for 11g rate and set proper 11g only mode */
5167static void wlan_hdd_check_11gmode(u8 *pIe, u8* require_ht,
5168 u8* pCheckRatesfor11g, eSapPhyMode* pSapHw_mode)
5169{
5170 u8 i, num_rates = pIe[0];
5171
5172 pIe += 1;
5173 for ( i = 0; i < num_rates; i++)
5174 {
5175 if( *pCheckRatesfor11g && (TRUE == wlan_hdd_rate_is_11g(pIe[i] & RATE_MASK)))
5176 {
5177 /* If rate set have 11g rate than change the mode to 11G */
5178 *pSapHw_mode = eSAP_DOT11_MODE_11g;
5179 if (pIe[i] & BASIC_RATE_MASK)
5180 {
5181 /* If we have 11g rate as basic rate, it means mode
5182 is 11g only mode.
5183 */
5184 *pSapHw_mode = eSAP_DOT11_MODE_11g_ONLY;
5185 *pCheckRatesfor11g = FALSE;
5186 }
5187 }
5188 else if((BASIC_RATE_MASK | WLAN_BSS_MEMBERSHIP_SELECTOR_HT_PHY) == pIe[i])
5189 {
5190 *require_ht = TRUE;
5191 }
5192 }
5193 return;
5194}
5195
5196static void wlan_hdd_set_sapHwmode(hdd_adapter_t *pHostapdAdapter)
5197{
5198 tsap_Config_t *pConfig = &pHostapdAdapter->sessionCtx.ap.sapConfig;
5199 beacon_data_t *pBeacon = pHostapdAdapter->sessionCtx.ap.beacon;
5200 struct ieee80211_mgmt *pMgmt_frame = (struct ieee80211_mgmt*)pBeacon->head;
5201 u8 checkRatesfor11g = TRUE;
5202 u8 require_ht = FALSE;
5203 u8 *pIe=NULL;
5204
5205 pConfig->SapHw_mode= eSAP_DOT11_MODE_11b;
5206
5207 pIe = wlan_hdd_cfg80211_get_ie_ptr(&pMgmt_frame->u.beacon.variable[0],
5208 pBeacon->head_len, WLAN_EID_SUPP_RATES);
5209 if (pIe != NULL)
5210 {
5211 pIe += 1;
5212 wlan_hdd_check_11gmode(pIe, &require_ht, &checkRatesfor11g,
5213 &pConfig->SapHw_mode);
5214 }
5215
5216 pIe = wlan_hdd_cfg80211_get_ie_ptr(pBeacon->tail, pBeacon->tail_len,
5217 WLAN_EID_EXT_SUPP_RATES);
5218 if (pIe != NULL)
5219 {
5220
5221 pIe += 1;
5222 wlan_hdd_check_11gmode(pIe, &require_ht, &checkRatesfor11g,
5223 &pConfig->SapHw_mode);
5224 }
5225
5226 if( pConfig->channel > 14 )
5227 {
5228 pConfig->SapHw_mode= eSAP_DOT11_MODE_11a;
5229 }
5230
5231 pIe = wlan_hdd_cfg80211_get_ie_ptr(pBeacon->tail, pBeacon->tail_len,
5232 WLAN_EID_HT_CAPABILITY);
5233
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305234 if(pIe)
Jeff Johnson295189b2012-06-20 16:38:30 -07005235 {
5236 pConfig->SapHw_mode= eSAP_DOT11_MODE_11n;
5237 if(require_ht)
5238 pConfig->SapHw_mode= eSAP_DOT11_MODE_11n_ONLY;
5239 }
5240}
5241
Gopichand Nakkala2b25f4e2013-03-21 19:14:07 +05305242static int wlan_hdd_add_ie(hdd_adapter_t* pHostapdAdapter, v_U8_t *genie,
5243 v_U8_t *total_ielen, v_U8_t *oui, v_U8_t oui_size)
5244{
Arif Hussaine7f3ea52013-09-12 21:56:36 -07005245 v_U16_t ielen = 0;
Gopichand Nakkala2b25f4e2013-03-21 19:14:07 +05305246 v_U8_t *pIe = NULL;
5247 beacon_data_t *pBeacon = pHostapdAdapter->sessionCtx.ap.beacon;
5248
5249 pIe = wlan_hdd_get_vendor_oui_ie_ptr(oui, oui_size,
5250 pBeacon->tail, pBeacon->tail_len);
5251
5252 if (pIe)
5253 {
5254 ielen = pIe[1] + 2;
5255 if ((*total_ielen + ielen) <= MAX_GENIE_LEN)
5256 {
5257 vos_mem_copy(&genie[*total_ielen], pIe, ielen);
5258 }
5259 else
5260 {
5261 hddLog( VOS_TRACE_LEVEL_ERROR, "**Ie Length is too big***");
5262 return -EINVAL;
5263 }
5264 *total_ielen += ielen;
5265 }
5266 return 0;
5267}
5268
Arif Hussaine7f3ea52013-09-12 21:56:36 -07005269static void wlan_hdd_add_hostapd_conf_vsie(hdd_adapter_t* pHostapdAdapter,
5270 v_U8_t *genie, v_U8_t *total_ielen)
5271{
5272 beacon_data_t *pBeacon = pHostapdAdapter->sessionCtx.ap.beacon;
5273 int left = pBeacon->tail_len;
5274 v_U8_t *ptr = pBeacon->tail;
5275 v_U8_t elem_id, elem_len;
5276 v_U16_t ielen = 0;
5277
5278 if ( NULL == ptr || 0 == left )
5279 return;
5280
5281 while (left >= 2)
5282 {
5283 elem_id = ptr[0];
5284 elem_len = ptr[1];
5285 left -= 2;
5286 if (elem_len > left)
5287 {
5288 hddLog( VOS_TRACE_LEVEL_ERROR,
5289 "****Invalid IEs eid = %d elem_len=%d left=%d*****",
5290 elem_id, elem_len, left);
5291 return;
5292 }
5293 if (IE_EID_VENDOR == elem_id)
5294 {
5295 /* skipping the VSIE's which we don't want to include or
5296 * it will be included by existing code
5297 */
5298 if ((memcmp( &ptr[2], WPS_OUI_TYPE, WPS_OUI_TYPE_SIZE) != 0 ) &&
5299#ifdef WLAN_FEATURE_WFD
5300 (memcmp( &ptr[2], WFD_OUI_TYPE, WFD_OUI_TYPE_SIZE) != 0) &&
5301#endif
5302 (memcmp( &ptr[2], WHITELIST_OUI_TYPE, WPA_OUI_TYPE_SIZE) != 0) &&
5303 (memcmp( &ptr[2], BLACKLIST_OUI_TYPE, WPA_OUI_TYPE_SIZE) != 0) &&
5304 (memcmp( &ptr[2], "\x00\x50\xf2\x02", WPA_OUI_TYPE_SIZE) != 0) &&
5305 (memcmp( &ptr[2], WPA_OUI_TYPE, WPA_OUI_TYPE_SIZE) != 0) &&
5306 (memcmp( &ptr[2], P2P_OUI_TYPE, P2P_OUI_TYPE_SIZE) != 0))
5307 {
5308 ielen = ptr[1] + 2;
5309 if ((*total_ielen + ielen) <= MAX_GENIE_LEN)
5310 {
5311 vos_mem_copy(&genie[*total_ielen], ptr, ielen);
5312 *total_ielen += ielen;
5313 }
5314 else
5315 {
5316 hddLog( VOS_TRACE_LEVEL_ERROR,
5317 "IE Length is too big "
5318 "IEs eid=%d elem_len=%d total_ie_lent=%d",
5319 elem_id, elem_len, *total_ielen);
5320 }
5321 }
5322 }
5323
5324 left -= elem_len;
5325 ptr += (elem_len + 2);
5326 }
5327 return;
5328}
5329
Jeff Johnson04dd8a82012-06-29 20:41:40 -07005330#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,4,0))
Jeff Johnson295189b2012-06-20 16:38:30 -07005331static int wlan_hdd_cfg80211_update_apies(hdd_adapter_t* pHostapdAdapter,
5332 struct beacon_parameters *params)
Jeff Johnson04dd8a82012-06-29 20:41:40 -07005333#else
5334static int wlan_hdd_cfg80211_update_apies(hdd_adapter_t* pHostapdAdapter,
5335 struct cfg80211_beacon_data *params)
5336#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07005337{
5338 v_U8_t *genie;
Gopichand Nakkala2b25f4e2013-03-21 19:14:07 +05305339 v_U8_t total_ielen = 0;
Jeff Johnson295189b2012-06-20 16:38:30 -07005340 v_U8_t addIE[1] = {0};
Jeff Johnsone7245742012-09-05 17:12:55 -07005341 int ret = 0;
Jeff Johnson295189b2012-06-20 16:38:30 -07005342
5343 genie = vos_mem_malloc(MAX_GENIE_LEN);
5344
5345 if(genie == NULL) {
5346
5347 return -ENOMEM;
5348 }
5349
Gopichand Nakkala2b25f4e2013-03-21 19:14:07 +05305350 if (0 != wlan_hdd_add_ie(pHostapdAdapter, genie,
5351 &total_ielen, WPS_OUI_TYPE, WPS_OUI_TYPE_SIZE))
Jeff Johnson295189b2012-06-20 16:38:30 -07005352 {
c_hpothu6ff1c3c2013-10-01 19:01:57 +05305353 hddLog(LOGE,
5354 FL("Adding WPS IE failed"));
Gopichand Nakkala2b25f4e2013-03-21 19:14:07 +05305355 ret = -EINVAL;
5356 goto done;
Jeff Johnson295189b2012-06-20 16:38:30 -07005357 }
5358
5359#ifdef WLAN_FEATURE_WFD
Gopichand Nakkala2b25f4e2013-03-21 19:14:07 +05305360 if (0 != wlan_hdd_add_ie(pHostapdAdapter, genie,
5361 &total_ielen, WFD_OUI_TYPE, WFD_OUI_TYPE_SIZE))
5362 {
c_hpothu6ff1c3c2013-10-01 19:01:57 +05305363 hddLog(LOGE,
5364 FL("Adding WFD IE failed"));
Gopichand Nakkala2b25f4e2013-03-21 19:14:07 +05305365 ret = -EINVAL;
5366 goto done;
Jeff Johnson295189b2012-06-20 16:38:30 -07005367 }
5368#endif
5369
Gopichand Nakkala2b25f4e2013-03-21 19:14:07 +05305370 if (0 != wlan_hdd_add_ie(pHostapdAdapter, genie,
5371 &total_ielen, P2P_OUI_TYPE, P2P_OUI_TYPE_SIZE))
Jeff Johnson295189b2012-06-20 16:38:30 -07005372 {
c_hpothu6ff1c3c2013-10-01 19:01:57 +05305373 hddLog(LOGE,
5374 FL("Adding P2P IE failed"));
Gopichand Nakkala2b25f4e2013-03-21 19:14:07 +05305375 ret = -EINVAL;
5376 goto done;
5377 }
5378
5379 if (WLAN_HDD_SOFTAP == pHostapdAdapter->device_mode)
5380 {
Arif Hussaine7f3ea52013-09-12 21:56:36 -07005381 wlan_hdd_add_hostapd_conf_vsie(pHostapdAdapter, genie, &total_ielen);
Jeff Johnson295189b2012-06-20 16:38:30 -07005382 }
Jeff Johnson295189b2012-06-20 16:38:30 -07005383
5384 if (ccmCfgSetStr((WLAN_HDD_GET_CTX(pHostapdAdapter))->hHal,
5385 WNI_CFG_PROBE_RSP_BCN_ADDNIE_DATA, genie, total_ielen, NULL,
5386 eANI_BOOLEAN_FALSE)==eHAL_STATUS_FAILURE)
5387 {
5388 hddLog(LOGE,
5389 "Could not pass on WNI_CFG_PROBE_RSP_BCN_ADDNIE_DATA to CCM");
Jeff Johnsone7245742012-09-05 17:12:55 -07005390 ret = -EINVAL;
5391 goto done;
Jeff Johnson295189b2012-06-20 16:38:30 -07005392 }
5393
5394 if (ccmCfgSetInt((WLAN_HDD_GET_CTX(pHostapdAdapter))->hHal,
5395 WNI_CFG_PROBE_RSP_BCN_ADDNIE_FLAG, 1,NULL,
5396 test_bit(SOFTAP_BSS_STARTED, &pHostapdAdapter->event_flags) ?
5397 eANI_BOOLEAN_TRUE : eANI_BOOLEAN_FALSE)
5398 ==eHAL_STATUS_FAILURE)
5399 {
5400 hddLog(LOGE,
5401 "Could not pass on WNI_CFG_PROBE_RSP_BCN_ADDNIE_FLAG to CCM");
Jeff Johnsone7245742012-09-05 17:12:55 -07005402 ret = -EINVAL;
5403 goto done;
Jeff Johnson295189b2012-06-20 16:38:30 -07005404 }
5405
5406 // Added for ProResp IE
5407 if ( (params->proberesp_ies != NULL) && (params->proberesp_ies_len != 0) )
5408 {
5409 u16 rem_probe_resp_ie_len = params->proberesp_ies_len;
5410 u8 probe_rsp_ie_len[3] = {0};
5411 u8 counter = 0;
5412 /* Check Probe Resp Length if it is greater then 255 then Store
5413 Probe Resp IEs into WNI_CFG_PROBE_RSP_ADDNIE_DATA1 &
5414 WNI_CFG_PROBE_RSP_ADDNIE_DATA2 CFG Variable As We are not able
5415 Store More then 255 bytes into One Variable.
5416 */
5417 while ((rem_probe_resp_ie_len > 0) && (counter < 3))
5418 {
5419 if (rem_probe_resp_ie_len > MAX_CFG_STRING_LEN)
5420 {
5421 probe_rsp_ie_len[counter++] = MAX_CFG_STRING_LEN;
5422 rem_probe_resp_ie_len -= MAX_CFG_STRING_LEN;
5423 }
5424 else
5425 {
5426 probe_rsp_ie_len[counter++] = rem_probe_resp_ie_len;
5427 rem_probe_resp_ie_len = 0;
5428 }
5429 }
5430
5431 rem_probe_resp_ie_len = 0;
5432
5433 if (probe_rsp_ie_len[0] > 0)
5434 {
5435 if (ccmCfgSetStr((WLAN_HDD_GET_CTX(pHostapdAdapter))->hHal,
5436 WNI_CFG_PROBE_RSP_ADDNIE_DATA1,
5437 (tANI_U8*)&params->proberesp_ies[rem_probe_resp_ie_len],
5438 probe_rsp_ie_len[0], NULL,
5439 eANI_BOOLEAN_FALSE) == eHAL_STATUS_FAILURE)
5440 {
5441 hddLog(LOGE,
5442 "Could not pass on WNI_CFG_PROBE_RSP_ADDNIE_DATA1 to CCM");
Jeff Johnsone7245742012-09-05 17:12:55 -07005443 ret = -EINVAL;
5444 goto done;
Jeff Johnson295189b2012-06-20 16:38:30 -07005445 }
5446 rem_probe_resp_ie_len += probe_rsp_ie_len[0];
5447 }
5448
5449 if (probe_rsp_ie_len[1] > 0)
5450 {
5451 if (ccmCfgSetStr((WLAN_HDD_GET_CTX(pHostapdAdapter))->hHal,
5452 WNI_CFG_PROBE_RSP_ADDNIE_DATA2,
5453 (tANI_U8*)&params->proberesp_ies[rem_probe_resp_ie_len],
5454 probe_rsp_ie_len[1], NULL,
5455 eANI_BOOLEAN_FALSE) == eHAL_STATUS_FAILURE)
5456 {
5457 hddLog(LOGE,
5458 "Could not pass on WNI_CFG_PROBE_RSP_ADDNIE_DATA2 to CCM");
Jeff Johnsone7245742012-09-05 17:12:55 -07005459 ret = -EINVAL;
5460 goto done;
Jeff Johnson295189b2012-06-20 16:38:30 -07005461 }
5462 rem_probe_resp_ie_len += probe_rsp_ie_len[1];
5463 }
5464
5465 if (probe_rsp_ie_len[2] > 0)
5466 {
5467 if (ccmCfgSetStr((WLAN_HDD_GET_CTX(pHostapdAdapter))->hHal,
5468 WNI_CFG_PROBE_RSP_ADDNIE_DATA3,
5469 (tANI_U8*)&params->proberesp_ies[rem_probe_resp_ie_len],
5470 probe_rsp_ie_len[2], NULL,
5471 eANI_BOOLEAN_FALSE) == eHAL_STATUS_FAILURE)
5472 {
5473 hddLog(LOGE,
5474 "Could not pass on WNI_CFG_PROBE_RSP_ADDNIE_DATA3 to CCM");
Jeff Johnsone7245742012-09-05 17:12:55 -07005475 ret = -EINVAL;
5476 goto done;
Jeff Johnson295189b2012-06-20 16:38:30 -07005477 }
5478 rem_probe_resp_ie_len += probe_rsp_ie_len[2];
5479 }
5480
5481 if (probe_rsp_ie_len[1] == 0 )
5482 {
5483 if ( eHAL_STATUS_FAILURE == ccmCfgSetStr((WLAN_HDD_GET_CTX(pHostapdAdapter))->hHal,
5484 WNI_CFG_PROBE_RSP_ADDNIE_DATA2, (tANI_U8*)addIE, 0, NULL,
5485 eANI_BOOLEAN_FALSE) )
5486 {
5487 hddLog(LOGE,
Arif Hussain6d2a3322013-11-17 19:50:10 -08005488 "Could not pass on WNI_CFG_PROBE_RSP_ADDNIE_DATA2 to CCM");
Jeff Johnson295189b2012-06-20 16:38:30 -07005489 }
5490 }
5491
5492 if (probe_rsp_ie_len[2] == 0 )
5493 {
5494 if ( eHAL_STATUS_FAILURE == ccmCfgSetStr((WLAN_HDD_GET_CTX(pHostapdAdapter))->hHal,
5495 WNI_CFG_PROBE_RSP_ADDNIE_DATA3, (tANI_U8*)addIE, 0, NULL,
5496 eANI_BOOLEAN_FALSE) )
5497 {
5498 hddLog(LOGE,
Arif Hussain6d2a3322013-11-17 19:50:10 -08005499 "Could not pass on WNI_CFG_PROBE_RSP_ADDNIE_DATA3 to CCM");
Jeff Johnson295189b2012-06-20 16:38:30 -07005500 }
5501 }
5502
5503 if (ccmCfgSetInt((WLAN_HDD_GET_CTX(pHostapdAdapter))->hHal,
5504 WNI_CFG_PROBE_RSP_ADDNIE_FLAG, 1,NULL,
5505 test_bit(SOFTAP_BSS_STARTED, &pHostapdAdapter->event_flags) ?
5506 eANI_BOOLEAN_TRUE : eANI_BOOLEAN_FALSE)
5507 == eHAL_STATUS_FAILURE)
5508 {
5509 hddLog(LOGE,
5510 "Could not pass on WNI_CFG_PROBE_RSP_ADDNIE_FLAG to CCM");
Jeff Johnsone7245742012-09-05 17:12:55 -07005511 ret = -EINVAL;
5512 goto done;
Jeff Johnson295189b2012-06-20 16:38:30 -07005513 }
5514 }
5515 else
5516 {
5517 // Reset WNI_CFG_PROBE_RSP Flags
5518 wlan_hdd_reset_prob_rspies(pHostapdAdapter);
5519
5520 hddLog(VOS_TRACE_LEVEL_INFO,
5521 "%s: No Probe Response IE received in set beacon",
5522 __func__);
5523 }
5524
5525 // Added for AssocResp IE
5526 if ( (params->assocresp_ies != NULL) && (params->assocresp_ies_len != 0) )
5527 {
5528 if (ccmCfgSetStr((WLAN_HDD_GET_CTX(pHostapdAdapter))->hHal,
5529 WNI_CFG_ASSOC_RSP_ADDNIE_DATA, (tANI_U8*)params->assocresp_ies,
5530 params->assocresp_ies_len, NULL,
5531 eANI_BOOLEAN_FALSE) == eHAL_STATUS_FAILURE)
5532 {
5533 hddLog(LOGE,
5534 "Could not pass on WNI_CFG_ASSOC_RSP_ADDNIE_DATA to CCM");
Jeff Johnsone7245742012-09-05 17:12:55 -07005535 ret = -EINVAL;
5536 goto done;
Jeff Johnson295189b2012-06-20 16:38:30 -07005537 }
5538
5539 if (ccmCfgSetInt((WLAN_HDD_GET_CTX(pHostapdAdapter))->hHal,
5540 WNI_CFG_ASSOC_RSP_ADDNIE_FLAG, 1, NULL,
5541 test_bit(SOFTAP_BSS_STARTED, &pHostapdAdapter->event_flags) ?
5542 eANI_BOOLEAN_TRUE : eANI_BOOLEAN_FALSE)
5543 == eHAL_STATUS_FAILURE)
5544 {
5545 hddLog(LOGE,
5546 "Could not pass on WNI_CFG_ASSOC_RSP_ADDNIE_FLAG to CCM");
Jeff Johnsone7245742012-09-05 17:12:55 -07005547 ret = -EINVAL;
5548 goto done;
Jeff Johnson295189b2012-06-20 16:38:30 -07005549 }
5550 }
5551 else
5552 {
5553 hddLog(VOS_TRACE_LEVEL_INFO,
5554 "%s: No Assoc Response IE received in set beacon",
5555 __func__);
5556
5557 if ( eHAL_STATUS_FAILURE == ccmCfgSetInt((WLAN_HDD_GET_CTX(pHostapdAdapter))->hHal,
5558 WNI_CFG_ASSOC_RSP_ADDNIE_FLAG, 0, NULL,
5559 eANI_BOOLEAN_FALSE) )
5560 {
5561 hddLog(LOGE,
Arif Hussain6d2a3322013-11-17 19:50:10 -08005562 "Could not pass on WNI_CFG_ASSOC_RSP_ADDNIE_FLAG to CCM");
Jeff Johnson295189b2012-06-20 16:38:30 -07005563 }
5564 }
5565
Jeff Johnsone7245742012-09-05 17:12:55 -07005566done:
Jeff Johnson295189b2012-06-20 16:38:30 -07005567 vos_mem_free(genie);
Gopichand Nakkala2b25f4e2013-03-21 19:14:07 +05305568 return ret;
Jeff Johnson295189b2012-06-20 16:38:30 -07005569}
Jeff Johnson295189b2012-06-20 16:38:30 -07005570
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305571/*
Jeff Johnson295189b2012-06-20 16:38:30 -07005572 * FUNCTION: wlan_hdd_validate_operation_channel
5573 * called by wlan_hdd_cfg80211_start_bss() and
5574 * wlan_hdd_cfg80211_set_channel()
5575 * This function validates whether given channel is part of valid
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305576 * channel list.
5577 */
Varun Reddy Yeturu920df212013-05-22 08:07:23 -07005578VOS_STATUS wlan_hdd_validate_operation_channel(hdd_adapter_t *pAdapter,int channel)
Jeff Johnson295189b2012-06-20 16:38:30 -07005579{
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305580
Jeff Johnson295189b2012-06-20 16:38:30 -07005581 v_U32_t num_ch = 0;
5582 u8 valid_ch[WNI_CFG_VALID_CHANNEL_LIST_LEN];
5583 u32 indx = 0;
5584 tHalHandle hHal = WLAN_HDD_GET_HAL_CTX(pAdapter);
Madan Mohan Koyylamudi64267f72013-02-05 14:07:08 +05305585 v_U8_t fValidChannel = FALSE, count = 0;
5586 hdd_config_t *hdd_pConfig_ini= (WLAN_HDD_GET_CTX(pAdapter))->cfg_ini;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305587
Jeff Johnson295189b2012-06-20 16:38:30 -07005588 num_ch = WNI_CFG_VALID_CHANNEL_LIST_LEN;
5589
Madan Mohan Koyylamudi64267f72013-02-05 14:07:08 +05305590 if ( hdd_pConfig_ini->sapAllowAllChannel)
Jeff Johnson295189b2012-06-20 16:38:30 -07005591 {
Madan Mohan Koyylamudi64267f72013-02-05 14:07:08 +05305592 /* Validate the channel */
5593 for (count = RF_CHAN_1 ; count <= RF_CHAN_165 ; count++)
Jeff Johnson295189b2012-06-20 16:38:30 -07005594 {
Madan Mohan Koyylamudi64267f72013-02-05 14:07:08 +05305595 if ( channel == rfChannels[count].channelNum )
5596 {
5597 fValidChannel = TRUE;
5598 break;
5599 }
5600 }
5601 if (fValidChannel != TRUE)
5602 {
5603 hddLog(VOS_TRACE_LEVEL_ERROR,
5604 "%s: Invalid Channel [%d]", __func__, channel);
5605 return VOS_STATUS_E_FAILURE;
Jeff Johnson295189b2012-06-20 16:38:30 -07005606 }
5607 }
Madan Mohan Koyylamudi64267f72013-02-05 14:07:08 +05305608 else
Jeff Johnson295189b2012-06-20 16:38:30 -07005609 {
Madan Mohan Koyylamudi64267f72013-02-05 14:07:08 +05305610 if (0 != ccmCfgGetStr(hHal, WNI_CFG_VALID_CHANNEL_LIST,
5611 valid_ch, &num_ch))
5612 {
5613 hddLog(VOS_TRACE_LEVEL_ERROR,
5614 "%s: failed to get valid channel list", __func__);
5615 return VOS_STATUS_E_FAILURE;
5616 }
5617 for (indx = 0; indx < num_ch; indx++)
5618 {
5619 if (channel == valid_ch[indx])
5620 {
5621 break;
5622 }
5623 }
5624
Rashmi Ramanna3b59e122014-04-10 14:45:13 +05305625 if (indx >= num_ch)
5626 {
5627 if (WLAN_HDD_P2P_GO == pAdapter->device_mode)
5628 {
5629 eCsrBand band;
5630 unsigned int freq;
5631
5632 sme_GetFreqBand(hHal, &band);
5633
5634 if (eCSR_BAND_5G == band)
5635 {
5636#if (LINUX_VERSION_CODE > KERNEL_VERSION(2,6,38))
5637 if (channel <= ARRAY_SIZE(hdd_channels_2_4_GHZ))
5638 {
5639 freq = ieee80211_channel_to_frequency(channel,
5640 IEEE80211_BAND_2GHZ);
5641 }
5642 else
5643 {
5644 freq = ieee80211_channel_to_frequency(channel,
5645 IEEE80211_BAND_5GHZ);
5646 }
5647#else
5648 freq = ieee80211_channel_to_frequency(channel);
5649#endif
5650 if(WLAN_HDD_IS_SOCIAL_CHANNEL(freq))
5651 return VOS_STATUS_SUCCESS;
5652 }
5653 }
5654
5655 hddLog(VOS_TRACE_LEVEL_ERROR,
5656 "%s: Invalid Channel [%d]", __func__, channel);
5657 return VOS_STATUS_E_FAILURE;
5658 }
Jeff Johnson295189b2012-06-20 16:38:30 -07005659 }
Rashmi Ramanna3b59e122014-04-10 14:45:13 +05305660
Jeff Johnson295189b2012-06-20 16:38:30 -07005661 return VOS_STATUS_SUCCESS;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305662
Jeff Johnson295189b2012-06-20 16:38:30 -07005663}
5664
Viral Modi3a32cc52013-02-08 11:14:52 -08005665/**
5666 * FUNCTION: wlan_hdd_cfg80211_set_channel
5667 * This function is used to set the channel number
5668 */
5669static int wlan_hdd_cfg80211_set_channel( struct wiphy *wiphy, struct net_device *dev,
5670 struct ieee80211_channel *chan,
5671 enum nl80211_channel_type channel_type
5672 )
5673{
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05305674 hdd_adapter_t *pAdapter = NULL;
Viral Modi3a32cc52013-02-08 11:14:52 -08005675 v_U32_t num_ch = 0;
Jeff Johnson4416a782013-03-25 14:17:50 -07005676 int channel = 0;
Viral Modi3a32cc52013-02-08 11:14:52 -08005677 int freq = chan->center_freq; /* freq is in MHZ */
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05305678 hdd_context_t *pHddCtx;
5679 int status;
Viral Modi3a32cc52013-02-08 11:14:52 -08005680
5681 ENTER();
5682
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05305683
Viral Modi3a32cc52013-02-08 11:14:52 -08005684 if( NULL == dev )
5685 {
5686 hddLog(VOS_TRACE_LEVEL_ERROR,
Arif Hussain6d2a3322013-11-17 19:50:10 -08005687 "%s: Called with dev = NULL.", __func__);
Viral Modi3a32cc52013-02-08 11:14:52 -08005688 return -ENODEV;
5689 }
5690 pAdapter = WLAN_HDD_GET_PRIV_PTR( dev );
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +05305691
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05305692 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
5693 TRACE_CODE_HDD_CFG80211_SET_CHANNEL, pAdapter->sessionId,
5694 channel_type ));
Viral Modi3a32cc52013-02-08 11:14:52 -08005695 hddLog(VOS_TRACE_LEVEL_INFO,
Sushant Kaushik8bc7df22014-04-09 17:55:29 +05305696 "%s: device_mode = %s (%d) freq = %d", __func__,
5697 hdd_device_modetoString(pAdapter->device_mode),
5698 pAdapter->device_mode, chan->center_freq);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05305699
5700 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
5701 status = wlan_hdd_validate_context(pHddCtx);
5702
5703 if (0 != status)
Viral Modi3a32cc52013-02-08 11:14:52 -08005704 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05305705 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
5706 "%s: HDD context is not valid", __func__);
5707 return status;
Viral Modi3a32cc52013-02-08 11:14:52 -08005708 }
5709
5710 /*
5711 * Do freq to chan conversion
5712 * TODO: for 11a
5713 */
5714
5715 channel = ieee80211_frequency_to_channel(freq);
5716
5717 /* Check freq range */
5718 if ((WNI_CFG_CURRENT_CHANNEL_STAMIN > channel) ||
5719 (WNI_CFG_CURRENT_CHANNEL_STAMAX < channel))
5720 {
5721 hddLog(VOS_TRACE_LEVEL_ERROR,
Arif Hussain6d2a3322013-11-17 19:50:10 -08005722 "%s: Channel [%d] is outside valid range from %d to %d",
Viral Modi3a32cc52013-02-08 11:14:52 -08005723 __func__, channel, WNI_CFG_CURRENT_CHANNEL_STAMIN,
5724 WNI_CFG_CURRENT_CHANNEL_STAMAX);
5725 return -EINVAL;
5726 }
5727
5728 num_ch = WNI_CFG_VALID_CHANNEL_LIST_LEN;
5729
Gopichand Nakkala6ab19562013-03-07 13:59:42 +05305730 if ((WLAN_HDD_SOFTAP != pAdapter->device_mode) &&
5731 (WLAN_HDD_P2P_GO != pAdapter->device_mode))
Viral Modi3a32cc52013-02-08 11:14:52 -08005732 {
5733 if(VOS_STATUS_SUCCESS != wlan_hdd_validate_operation_channel(pAdapter,channel))
5734 {
5735 hddLog(VOS_TRACE_LEVEL_ERROR,
Arif Hussain6d2a3322013-11-17 19:50:10 -08005736 "%s: Invalid Channel [%d]", __func__, channel);
Viral Modi3a32cc52013-02-08 11:14:52 -08005737 return -EINVAL;
5738 }
5739 hddLog(VOS_TRACE_LEVEL_INFO_HIGH,
5740 "%s: set channel to [%d] for device mode =%d",
5741 __func__, channel,pAdapter->device_mode);
5742 }
5743 if( (pAdapter->device_mode == WLAN_HDD_INFRA_STATION)
Viral Modi3a32cc52013-02-08 11:14:52 -08005744 || (pAdapter->device_mode == WLAN_HDD_P2P_CLIENT)
Viral Modi3a32cc52013-02-08 11:14:52 -08005745 )
5746 {
5747 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
5748 tCsrRoamProfile * pRoamProfile = &pWextState->roamProfile;
5749 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
5750
5751 if (eConnectionState_IbssConnected == pHddStaCtx->conn_info.connState)
5752 {
5753 /* Link is up then return cant set channel*/
5754 hddLog( VOS_TRACE_LEVEL_ERROR,
Arif Hussain6d2a3322013-11-17 19:50:10 -08005755 "%s: IBSS Associated, can't set the channel", __func__);
Viral Modi3a32cc52013-02-08 11:14:52 -08005756 return -EINVAL;
5757 }
5758
5759 num_ch = pRoamProfile->ChannelInfo.numOfChannels = 1;
5760 pHddStaCtx->conn_info.operationChannel = channel;
5761 pRoamProfile->ChannelInfo.ChannelList =
5762 &pHddStaCtx->conn_info.operationChannel;
5763 }
5764 else if ((pAdapter->device_mode == WLAN_HDD_SOFTAP)
Viral Modi3a32cc52013-02-08 11:14:52 -08005765 || (pAdapter->device_mode == WLAN_HDD_P2P_GO)
Viral Modi3a32cc52013-02-08 11:14:52 -08005766 )
5767 {
Gopichand Nakkalac8fa7b62013-03-11 13:56:41 +05305768 if (WLAN_HDD_P2P_GO == pAdapter->device_mode)
5769 {
5770 if(VOS_STATUS_SUCCESS !=
5771 wlan_hdd_validate_operation_channel(pAdapter,channel))
5772 {
5773 hddLog(VOS_TRACE_LEVEL_ERROR,
Arif Hussain6d2a3322013-11-17 19:50:10 -08005774 "%s: Invalid Channel [%d]", __func__, channel);
Gopichand Nakkalac8fa7b62013-03-11 13:56:41 +05305775 return -EINVAL;
5776 }
5777 (WLAN_HDD_GET_AP_CTX_PTR(pAdapter))->sapConfig.channel = channel;
5778 }
5779 else if ( WLAN_HDD_SOFTAP == pAdapter->device_mode )
Viral Modi3a32cc52013-02-08 11:14:52 -08005780 {
5781 hdd_config_t *cfg_param = (WLAN_HDD_GET_CTX(pAdapter))->cfg_ini;
5782
5783 /* If auto channel selection is configured as enable/ 1 then ignore
5784 channel set by supplicant
5785 */
5786 if ( cfg_param->apAutoChannelSelection )
5787 {
Gopichand Nakkalac8fa7b62013-03-11 13:56:41 +05305788 (WLAN_HDD_GET_AP_CTX_PTR(pAdapter))->sapConfig.channel =
5789 AUTO_CHANNEL_SELECT;
Viral Modi3a32cc52013-02-08 11:14:52 -08005790 hddLog(VOS_TRACE_LEVEL_INFO_HIGH,
Sushant Kaushik8bc7df22014-04-09 17:55:29 +05305791 "%s: set channel to auto channel (0) for device mode =%s (%d)",
5792 __func__, hdd_device_modetoString(pAdapter->device_mode),
5793 pAdapter->device_mode);
Viral Modi3a32cc52013-02-08 11:14:52 -08005794 }
Gopichand Nakkalac8fa7b62013-03-11 13:56:41 +05305795 else
5796 {
5797 if(VOS_STATUS_SUCCESS !=
5798 wlan_hdd_validate_operation_channel(pAdapter,channel))
5799 {
5800 hddLog(VOS_TRACE_LEVEL_ERROR,
Arif Hussain6d2a3322013-11-17 19:50:10 -08005801 "%s: Invalid Channel [%d]", __func__, channel);
Gopichand Nakkalac8fa7b62013-03-11 13:56:41 +05305802 return -EINVAL;
5803 }
5804 (WLAN_HDD_GET_AP_CTX_PTR(pAdapter))->sapConfig.channel = channel;
5805 }
Viral Modi3a32cc52013-02-08 11:14:52 -08005806 }
5807 }
5808 else
5809 {
5810 hddLog(VOS_TRACE_LEVEL_FATAL,
5811 "%s: Invalid device mode failed to set valid channel", __func__);
5812 return -EINVAL;
5813 }
5814 EXIT();
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05305815 return status;
Viral Modi3a32cc52013-02-08 11:14:52 -08005816}
5817
Jeff Johnson295189b2012-06-20 16:38:30 -07005818#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,4,0))
5819static int wlan_hdd_cfg80211_start_bss(hdd_adapter_t *pHostapdAdapter,
5820 struct beacon_parameters *params)
Jeff Johnson04dd8a82012-06-29 20:41:40 -07005821#else
5822static int wlan_hdd_cfg80211_start_bss(hdd_adapter_t *pHostapdAdapter,
5823 struct cfg80211_beacon_data *params,
5824 const u8 *ssid, size_t ssid_len,
5825 enum nl80211_hidden_ssid hidden_ssid)
5826#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07005827{
5828 tsap_Config_t *pConfig;
5829 beacon_data_t *pBeacon = NULL;
5830 struct ieee80211_mgmt *pMgmt_frame;
5831 v_U8_t *pIe=NULL;
5832 v_U16_t capab_info;
5833 eCsrAuthType RSNAuthType;
5834 eCsrEncryptionType RSNEncryptType;
5835 eCsrEncryptionType mcRSNEncryptType;
5836 int status = VOS_STATUS_SUCCESS;
5837 tpWLAN_SAPEventCB pSapEventCallback;
5838 hdd_hostapd_state_t *pHostapdState;
5839 v_U8_t wpaRsnIEdata[(SIR_MAC_MAX_IE_LENGTH * 2)+4]; //Max ie length 255 * 2(WPA+RSN) + 2 bytes (vendor specific ID) * 2
5840 v_CONTEXT_t pVosContext = (WLAN_HDD_GET_CTX(pHostapdAdapter))->pvosContext;
Madan Mohan Koyylamudia16d0202013-02-01 11:05:57 +05305841 tHalHandle hHal = WLAN_HDD_GET_HAL_CTX(pHostapdAdapter);
Jeff Johnson295189b2012-06-20 16:38:30 -07005842 struct qc_mac_acl_entry *acl_entry = NULL;
Siddharth Bhal5cba24e2014-05-08 18:59:39 +05305843 hdd_config_t *iniConfig;
Jeff Johnson295189b2012-06-20 16:38:30 -07005844 v_SINT_t i;
Madan Mohan Koyyalamudi543172b2012-12-05 16:40:18 -08005845 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pHostapdAdapter);
Peng Xu2446a892014-09-05 17:21:18 +05305846 tSmeConfigParams *psmeConfig;
Chet Lanctot40142442014-05-20 13:39:25 -07005847 v_BOOL_t MFPCapable = VOS_FALSE;
5848 v_BOOL_t MFPRequired = VOS_FALSE;
Abhishek Singhf0ac1752014-03-05 17:47:09 +05305849 eHddDot11Mode sapDot11Mode =
5850 (WLAN_HDD_GET_CTX(pHostapdAdapter))->cfg_ini->sapDot11Mode;
Jeff Johnson295189b2012-06-20 16:38:30 -07005851
5852 ENTER();
5853
Siddharth Bhal5cba24e2014-05-08 18:59:39 +05305854 iniConfig = pHddCtx->cfg_ini;
5855
Jeff Johnson295189b2012-06-20 16:38:30 -07005856 pHostapdState = WLAN_HDD_GET_HOSTAP_STATE_PTR(pHostapdAdapter);
5857
5858 pConfig = &pHostapdAdapter->sessionCtx.ap.sapConfig;
5859
5860 pBeacon = pHostapdAdapter->sessionCtx.ap.beacon;
5861
5862 pMgmt_frame = (struct ieee80211_mgmt*)pBeacon->head;
5863
5864 pConfig->beacon_int = pMgmt_frame->u.beacon.beacon_int;
5865
5866 //channel is already set in the set_channel Call back
5867 //pConfig->channel = pCommitConfig->channel;
5868
5869 /*Protection parameter to enable or disable*/
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305870 pConfig->protEnabled =
Jeff Johnson295189b2012-06-20 16:38:30 -07005871 (WLAN_HDD_GET_CTX(pHostapdAdapter))->cfg_ini->apProtEnabled;
5872
5873 pConfig->dtim_period = pBeacon->dtim_period;
5874
Arif Hussain6d2a3322013-11-17 19:50:10 -08005875 hddLog(VOS_TRACE_LEVEL_INFO_HIGH,"****pConfig->dtim_period=%d***",
Jeff Johnson295189b2012-06-20 16:38:30 -07005876 pConfig->dtim_period);
5877
Madan Mohan Koyyalamudie0ca11f2012-11-27 15:57:52 -08005878 if (pHostapdAdapter->device_mode == WLAN_HDD_SOFTAP)
Jeff Johnson32d95a32012-09-10 13:15:23 -07005879 {
5880 pIe = wlan_hdd_cfg80211_get_ie_ptr(pBeacon->tail, pBeacon->tail_len,
Jeff Johnson295189b2012-06-20 16:38:30 -07005881 WLAN_EID_COUNTRY);
Kiet Lam083504c2013-11-25 14:17:45 +05305882 if(memcmp(pHddCtx->cfg_ini->apCntryCode, CFG_AP_COUNTRY_CODE_DEFAULT, 3) != 0)
5883 {
5884 tANI_BOOLEAN restartNeeded;
5885 pConfig->ieee80211d = 1;
5886 vos_mem_copy(pConfig->countryCode, pHddCtx->cfg_ini->apCntryCode, 3);
5887 sme_setRegInfo(hHal, pConfig->countryCode);
5888 sme_ResetCountryCodeInformation(hHal, &restartNeeded);
5889 }
5890 else if(pIe)
Jeff Johnson295189b2012-06-20 16:38:30 -07005891 {
Jeff Johnson32d95a32012-09-10 13:15:23 -07005892 tANI_BOOLEAN restartNeeded;
Jeff Johnson32d95a32012-09-10 13:15:23 -07005893 pConfig->ieee80211d = 1;
5894 vos_mem_copy(pConfig->countryCode, &pIe[2], 3);
5895 sme_setRegInfo(hHal, pConfig->countryCode);
5896 sme_ResetCountryCodeInformation(hHal, &restartNeeded);
Jeff Johnson295189b2012-06-20 16:38:30 -07005897 }
Jeff Johnson32d95a32012-09-10 13:15:23 -07005898 else
5899 {
5900 pConfig->ieee80211d = 0;
5901 }
Madan Mohan Koyylamudia16d0202013-02-01 11:05:57 +05305902 /*
5903 * If auto channel is configured i.e. channel is 0,
5904 * so skip channel validation.
5905 */
5906 if( AUTO_CHANNEL_SELECT != pConfig->channel )
5907 {
5908 if(VOS_STATUS_SUCCESS != wlan_hdd_validate_operation_channel(pHostapdAdapter,pConfig->channel))
5909 {
5910 hddLog(VOS_TRACE_LEVEL_ERROR,
Arif Hussain6d2a3322013-11-17 19:50:10 -08005911 "%s: Invalid Channel [%d]", __func__, pConfig->channel);
Madan Mohan Koyylamudia16d0202013-02-01 11:05:57 +05305912 return -EINVAL;
5913 }
5914 }
5915 else
5916 {
5917 if(1 != pHddCtx->is_dynamic_channel_range_set)
5918 {
5919 hdd_config_t *hdd_pConfig= (WLAN_HDD_GET_CTX(pHostapdAdapter))->cfg_ini;
5920 WLANSAP_SetChannelRange(hHal, hdd_pConfig->apStartChannelNum,
5921 hdd_pConfig->apEndChannelNum,hdd_pConfig->apOperatingBand);
5922 }
5923 pHddCtx->is_dynamic_channel_range_set = 0;
5924 }
Jeff Johnson295189b2012-06-20 16:38:30 -07005925 }
Jeff Johnson32d95a32012-09-10 13:15:23 -07005926 else
Jeff Johnson295189b2012-06-20 16:38:30 -07005927 {
5928 pConfig->ieee80211d = 0;
5929 }
5930 pConfig->authType = eSAP_AUTO_SWITCH;
5931
5932 capab_info = pMgmt_frame->u.beacon.capab_info;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305933
5934 pConfig->privacy = (pMgmt_frame->u.beacon.capab_info &
Jeff Johnson295189b2012-06-20 16:38:30 -07005935 WLAN_CAPABILITY_PRIVACY) ? VOS_TRUE : VOS_FALSE;
5936
5937 (WLAN_HDD_GET_AP_CTX_PTR(pHostapdAdapter))->uPrivacy = pConfig->privacy;
5938
5939 /*Set wps station to configured*/
5940 pIe = wlan_hdd_get_wps_ie_ptr(pBeacon->tail, pBeacon->tail_len);
5941
5942 if(pIe)
5943 {
5944 if(pIe[1] < (2 + WPS_OUI_TYPE_SIZE))
5945 {
Arif Hussain6d2a3322013-11-17 19:50:10 -08005946 hddLog( VOS_TRACE_LEVEL_ERROR, "**Wps Ie Length is too small***");
Jeff Johnson295189b2012-06-20 16:38:30 -07005947 return -EINVAL;
5948 }
5949 else if(memcmp(&pIe[2], WPS_OUI_TYPE, WPS_OUI_TYPE_SIZE) == 0)
5950 {
Madan Mohan Koyyalamudi8bdd3112012-09-24 13:55:14 -07005951 hddLog( VOS_TRACE_LEVEL_INFO, "** WPS IE(len %d) ***", (pIe[1]+2));
Jeff Johnson295189b2012-06-20 16:38:30 -07005952 /* Check 15 bit of WPS IE as it contain information for wps state
5953 * WPS state
5954 */
5955 if(SAP_WPS_ENABLED_UNCONFIGURED == pIe[15])
5956 {
5957 pConfig->wps_state = SAP_WPS_ENABLED_UNCONFIGURED;
5958 } else if(SAP_WPS_ENABLED_CONFIGURED == pIe[15])
5959 {
5960 pConfig->wps_state = SAP_WPS_ENABLED_CONFIGURED;
5961 }
5962 }
5963 }
5964 else
5965 {
5966 pConfig->wps_state = SAP_WPS_DISABLED;
5967 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305968 pConfig->fwdWPSPBCProbeReq = 1; // Forward WPS PBC probe request frame up
Jeff Johnson295189b2012-06-20 16:38:30 -07005969
c_hpothufe599e92014-06-16 11:38:55 +05305970 pConfig->RSNEncryptType = eCSR_ENCRYPT_TYPE_NONE;
5971 pConfig->mcRSNEncryptType = eCSR_ENCRYPT_TYPE_NONE;
5972 (WLAN_HDD_GET_AP_CTX_PTR(pHostapdAdapter))->ucEncryptType =
5973 eCSR_ENCRYPT_TYPE_NONE;
5974
Jeff Johnson295189b2012-06-20 16:38:30 -07005975 pConfig->RSNWPAReqIELength = 0;
5976 pConfig->pRSNWPAReqIE = NULL;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305977 pIe = wlan_hdd_cfg80211_get_ie_ptr(pBeacon->tail, pBeacon->tail_len,
Jeff Johnson295189b2012-06-20 16:38:30 -07005978 WLAN_EID_RSN);
5979 if(pIe && pIe[1])
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305980 {
Jeff Johnson295189b2012-06-20 16:38:30 -07005981 pConfig->RSNWPAReqIELength = pIe[1] + 2;
5982 memcpy(&wpaRsnIEdata[0], pIe, pConfig->RSNWPAReqIELength);
5983 pConfig->pRSNWPAReqIE = &wpaRsnIEdata[0];
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305984 /* The actual processing may eventually be more extensive than
5985 * this. Right now, just consume any PMKIDs that are sent in
Jeff Johnson295189b2012-06-20 16:38:30 -07005986 * by the app.
5987 * */
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305988 status = hdd_softap_unpackIE(
Jeff Johnson295189b2012-06-20 16:38:30 -07005989 vos_get_context( VOS_MODULE_ID_SME, pVosContext),
5990 &RSNEncryptType,
5991 &mcRSNEncryptType,
5992 &RSNAuthType,
Chet Lanctot8cecea22014-02-11 19:09:36 -08005993 &MFPCapable,
5994 &MFPRequired,
Jeff Johnson295189b2012-06-20 16:38:30 -07005995 pConfig->pRSNWPAReqIE[1]+2,
5996 pConfig->pRSNWPAReqIE );
5997
5998 if( VOS_STATUS_SUCCESS == status )
5999 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306000 /* Now copy over all the security attributes you have
6001 * parsed out
Jeff Johnson295189b2012-06-20 16:38:30 -07006002 * */
6003 pConfig->RSNEncryptType = RSNEncryptType; // Use the cipher type in the RSN IE
6004 pConfig->mcRSNEncryptType = mcRSNEncryptType;
6005 (WLAN_HDD_GET_AP_CTX_PTR(pHostapdAdapter))->ucEncryptType
6006 = RSNEncryptType;
Gopichand Nakkala66c0bd02013-04-10 11:36:29 +05306007 hddLog( LOG1, FL("CSR AuthType = %d, "
Arif Hussain6d2a3322013-11-17 19:50:10 -08006008 "EncryptionType = %d mcEncryptionType = %d"),
Jeff Johnson295189b2012-06-20 16:38:30 -07006009 RSNAuthType, RSNEncryptType, mcRSNEncryptType);
6010 }
6011 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306012
Jeff Johnson295189b2012-06-20 16:38:30 -07006013 pIe = wlan_hdd_get_vendor_oui_ie_ptr(WPA_OUI_TYPE, WPA_OUI_TYPE_SIZE,
6014 pBeacon->tail, pBeacon->tail_len);
6015
6016 if(pIe && pIe[1] && (pIe[0] == DOT11F_EID_WPA))
6017 {
6018 if (pConfig->pRSNWPAReqIE)
6019 {
6020 /*Mixed mode WPA/WPA2*/
6021 memcpy((&wpaRsnIEdata[0] + pConfig->RSNWPAReqIELength), pIe, pIe[1] + 2);
6022 pConfig->RSNWPAReqIELength += pIe[1] + 2;
6023 }
6024 else
6025 {
6026 pConfig->RSNWPAReqIELength = pIe[1] + 2;
6027 memcpy(&wpaRsnIEdata[0], pIe, pConfig->RSNWPAReqIELength);
6028 pConfig->pRSNWPAReqIE = &wpaRsnIEdata[0];
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306029 status = hdd_softap_unpackIE(
Jeff Johnson295189b2012-06-20 16:38:30 -07006030 vos_get_context( VOS_MODULE_ID_SME, pVosContext),
6031 &RSNEncryptType,
6032 &mcRSNEncryptType,
6033 &RSNAuthType,
Chet Lanctot8cecea22014-02-11 19:09:36 -08006034 &MFPCapable,
6035 &MFPRequired,
Jeff Johnson295189b2012-06-20 16:38:30 -07006036 pConfig->pRSNWPAReqIE[1]+2,
6037 pConfig->pRSNWPAReqIE );
6038
6039 if( VOS_STATUS_SUCCESS == status )
6040 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306041 /* Now copy over all the security attributes you have
6042 * parsed out
Jeff Johnson295189b2012-06-20 16:38:30 -07006043 * */
6044 pConfig->RSNEncryptType = RSNEncryptType; // Use the cipher type in the RSN IE
6045 pConfig->mcRSNEncryptType = mcRSNEncryptType;
6046 (WLAN_HDD_GET_AP_CTX_PTR(pHostapdAdapter))->ucEncryptType
6047 = RSNEncryptType;
Gopichand Nakkala66c0bd02013-04-10 11:36:29 +05306048 hddLog( LOG1, FL("CSR AuthType = %d, "
Arif Hussain6d2a3322013-11-17 19:50:10 -08006049 "EncryptionType = %d mcEncryptionType = %d"),
Jeff Johnson295189b2012-06-20 16:38:30 -07006050 RSNAuthType, RSNEncryptType, mcRSNEncryptType);
6051 }
6052 }
6053 }
6054
Jeff Johnson4416a782013-03-25 14:17:50 -07006055 if (pConfig->RSNWPAReqIELength > sizeof wpaRsnIEdata) {
6056 hddLog( VOS_TRACE_LEVEL_ERROR, "**RSNWPAReqIELength is too large***");
6057 return -EINVAL;
6058 }
6059
Jeff Johnson295189b2012-06-20 16:38:30 -07006060 pConfig->SSIDinfo.ssidHidden = VOS_FALSE;
6061
Jeff Johnson04dd8a82012-06-29 20:41:40 -07006062#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,4,0))
Jeff Johnson295189b2012-06-20 16:38:30 -07006063 if (params->ssid != NULL)
6064 {
6065 memcpy(pConfig->SSIDinfo.ssid.ssId, params->ssid, params->ssid_len);
6066 pConfig->SSIDinfo.ssid.length = params->ssid_len;
6067 if (params->hidden_ssid != NL80211_HIDDEN_SSID_NOT_IN_USE)
6068 pConfig->SSIDinfo.ssidHidden = VOS_TRUE;
6069 }
Jeff Johnson04dd8a82012-06-29 20:41:40 -07006070#else
6071 if (ssid != NULL)
6072 {
6073 memcpy(pConfig->SSIDinfo.ssid.ssId, ssid, ssid_len);
6074 pConfig->SSIDinfo.ssid.length = ssid_len;
6075 if (hidden_ssid != NL80211_HIDDEN_SSID_NOT_IN_USE)
6076 pConfig->SSIDinfo.ssidHidden = VOS_TRUE;
6077 }
6078#endif
6079
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306080 vos_mem_copy(pConfig->self_macaddr.bytes,
Jeff Johnson295189b2012-06-20 16:38:30 -07006081 pHostapdAdapter->macAddressCurrent.bytes, sizeof(v_MACADDR_t));
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306082
Jeff Johnson295189b2012-06-20 16:38:30 -07006083 /* default value */
6084 pConfig->SapMacaddr_acl = eSAP_ACCEPT_UNLESS_DENIED;
6085 pConfig->num_accept_mac = 0;
6086 pConfig->num_deny_mac = 0;
6087
6088 pIe = wlan_hdd_get_vendor_oui_ie_ptr(BLACKLIST_OUI_TYPE, WPA_OUI_TYPE_SIZE,
6089 pBeacon->tail, pBeacon->tail_len);
6090
6091 /* pIe for black list is following form:
6092 type : 1 byte
6093 length : 1 byte
6094 OUI : 4 bytes
6095 acl type : 1 byte
6096 no of mac addr in black list: 1 byte
6097 list of mac_acl_entries: variable, 6 bytes per mac address + sizeof(int) for vlan id
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306098 */
6099 if ((pIe != NULL) && (pIe[1] != 0))
Jeff Johnson295189b2012-06-20 16:38:30 -07006100 {
6101 pConfig->SapMacaddr_acl = pIe[6];
6102 pConfig->num_deny_mac = pIe[7];
Arif Hussain6d2a3322013-11-17 19:50:10 -08006103 hddLog(VOS_TRACE_LEVEL_INFO,"acl type = %d no deny mac = %d",
Jeff Johnson295189b2012-06-20 16:38:30 -07006104 pIe[6], pIe[7]);
Gopichand Nakkalac005b7c2013-05-14 16:04:14 +05306105 if (pConfig->num_deny_mac > MAX_ACL_MAC_ADDRESS)
6106 pConfig->num_deny_mac = MAX_ACL_MAC_ADDRESS;
Jeff Johnson295189b2012-06-20 16:38:30 -07006107 acl_entry = (struct qc_mac_acl_entry *)(pIe + 8);
6108 for (i = 0; i < pConfig->num_deny_mac; i++)
6109 {
6110 vos_mem_copy(&pConfig->deny_mac[i], acl_entry->addr, sizeof(qcmacaddr));
6111 acl_entry++;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306112 }
Jeff Johnson295189b2012-06-20 16:38:30 -07006113 }
6114 pIe = wlan_hdd_get_vendor_oui_ie_ptr(WHITELIST_OUI_TYPE, WPA_OUI_TYPE_SIZE,
6115 pBeacon->tail, pBeacon->tail_len);
6116
6117 /* pIe for white list is following form:
6118 type : 1 byte
6119 length : 1 byte
6120 OUI : 4 bytes
6121 acl type : 1 byte
6122 no of mac addr in white list: 1 byte
6123 list of mac_acl_entries: variable, 6 bytes per mac address + sizeof(int) for vlan id
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306124 */
6125 if ((pIe != NULL) && (pIe[1] != 0))
Jeff Johnson295189b2012-06-20 16:38:30 -07006126 {
6127 pConfig->SapMacaddr_acl = pIe[6];
6128 pConfig->num_accept_mac = pIe[7];
Arif Hussain6d2a3322013-11-17 19:50:10 -08006129 hddLog(VOS_TRACE_LEVEL_INFO,"acl type = %d no accept mac = %d",
Jeff Johnson295189b2012-06-20 16:38:30 -07006130 pIe[6], pIe[7]);
Gopichand Nakkalac005b7c2013-05-14 16:04:14 +05306131 if (pConfig->num_accept_mac > MAX_ACL_MAC_ADDRESS)
6132 pConfig->num_accept_mac = MAX_ACL_MAC_ADDRESS;
Jeff Johnson295189b2012-06-20 16:38:30 -07006133 acl_entry = (struct qc_mac_acl_entry *)(pIe + 8);
6134 for (i = 0; i < pConfig->num_accept_mac; i++)
6135 {
6136 vos_mem_copy(&pConfig->accept_mac[i], acl_entry->addr, sizeof(qcmacaddr));
6137 acl_entry++;
6138 }
6139 }
Gopichand Nakkalac005b7c2013-05-14 16:04:14 +05306140
Jeff Johnson295189b2012-06-20 16:38:30 -07006141 wlan_hdd_set_sapHwmode(pHostapdAdapter);
6142
Jeff Johnsone7245742012-09-05 17:12:55 -07006143#ifdef WLAN_FEATURE_11AC
Ravi Kumar Vaishnavbbaebbe2013-01-15 17:09:48 -08006144 /* Overwrite the hostapd setting for HW mode only for 11ac.
Kiet Lam0f320422013-11-21 19:29:17 +05306145 * This is valid only if mode is set to 11n in hostapd, either AUTO or
6146 * 11ac in .ini and 11ac is supported by both host and firmware.
6147 * Otherwise, leave whatever is set in hostapd (a OR b OR g OR n mode)
6148 */
Ravi Kumar Vaishnavbbaebbe2013-01-15 17:09:48 -08006149 if( ((pConfig->SapHw_mode == eSAP_DOT11_MODE_11n) ||
6150 (pConfig->SapHw_mode == eSAP_DOT11_MODE_11n_ONLY)) &&
Abhishek Singhf0ac1752014-03-05 17:47:09 +05306151 (( sapDot11Mode == eHDD_DOT11_MODE_AUTO ) ||
6152 ( sapDot11Mode == eHDD_DOT11_MODE_11ac ) ||
6153 ( sapDot11Mode == eHDD_DOT11_MODE_11ac_ONLY ) ) &&
6154 (sme_IsFeatureSupportedByDriver(DOT11AC)) &&
6155 (sme_IsFeatureSupportedByFW(DOT11AC)) )
Jeff Johnsone7245742012-09-05 17:12:55 -07006156 {
Siddharth Bhalf42f8592014-05-15 13:39:07 +05306157 v_U32_t operatingBand = 0;
Jeff Johnsone7245742012-09-05 17:12:55 -07006158 pConfig->SapHw_mode = eSAP_DOT11_MODE_11ac;
Siddharth Bhalf42f8592014-05-15 13:39:07 +05306159 ccmCfgGetInt(hHal, WNI_CFG_SAP_CHANNEL_SELECT_OPERATING_BAND, &operatingBand);
Ravi Joshi83bfaa12013-05-28 22:12:08 -07006160
Siddharth Bhal5cba24e2014-05-08 18:59:39 +05306161 /* If ACS disable and selected channel <= 14
6162 * OR
6163 * ACS enabled and ACS operating band is choosen as 2.4
6164 * AND
6165 * VHT in 2.4G Disabled
6166 * THEN
6167 * Fallback to 11N mode
6168 */
6169 if (((AUTO_CHANNEL_SELECT != pConfig->channel && pConfig->channel <= SIR_11B_CHANNEL_END)
6170 || (AUTO_CHANNEL_SELECT == pConfig->channel &&
Siddharth Bhalf42f8592014-05-15 13:39:07 +05306171 operatingBand == RF_SUBBAND_2_4_GHZ)) &&
Siddharth Bhal5cba24e2014-05-08 18:59:39 +05306172 iniConfig->enableVhtFor24GHzBand == FALSE)
Ravi Joshi83bfaa12013-05-28 22:12:08 -07006173 {
Siddharth Bhalf42f8592014-05-15 13:39:07 +05306174 hddLog(LOGW, FL("Setting hwmode to 11n, operatingBand = %d, Channel = %d"),
6175 operatingBand, pConfig->channel);
Ravi Joshi83bfaa12013-05-28 22:12:08 -07006176 pConfig->SapHw_mode = eSAP_DOT11_MODE_11n;
6177 }
Jeff Johnsone7245742012-09-05 17:12:55 -07006178 }
6179#endif
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306180
Ravi Joshiaeb7d9e2013-05-02 12:28:14 -07006181 if ( AUTO_CHANNEL_SELECT != pConfig->channel )
6182 {
6183 sme_SelectCBMode(hHal,
6184 sapConvertSapPhyModeToCsrPhyMode(pConfig->SapHw_mode),
6185 pConfig->channel);
6186 }
Jeff Johnson295189b2012-06-20 16:38:30 -07006187 // ht_capab is not what the name conveys,this is used for protection bitmap
6188 pConfig->ht_capab =
6189 (WLAN_HDD_GET_CTX(pHostapdAdapter))->cfg_ini->apProtection;
6190
6191 if ( 0 != wlan_hdd_cfg80211_update_apies(pHostapdAdapter, params) )
6192 {
6193 hddLog(LOGE, FL("SAP Not able to set AP IEs"));
6194 return -EINVAL;
6195 }
6196
6197 //Uapsd Enabled Bit
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306198 pConfig->UapsdEnable =
Jeff Johnson295189b2012-06-20 16:38:30 -07006199 (WLAN_HDD_GET_CTX(pHostapdAdapter))->cfg_ini->apUapsdEnabled;
6200 //Enable OBSS protection
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306201 pConfig->obssProtEnabled =
6202 (WLAN_HDD_GET_CTX(pHostapdAdapter))->cfg_ini->apOBSSProtEnabled;
Jeff Johnson295189b2012-06-20 16:38:30 -07006203
Chet Lanctot8cecea22014-02-11 19:09:36 -08006204#ifdef WLAN_FEATURE_11W
6205 pConfig->mfpCapable = MFPCapable;
6206 pConfig->mfpRequired = MFPRequired;
6207 hddLog(LOGW, FL("Soft AP MFP capable %d, MFP required %d\n"),
6208 pConfig->mfpCapable, pConfig->mfpRequired);
6209#endif
6210
Arif Hussain6d2a3322013-11-17 19:50:10 -08006211 hddLog(LOGW, FL("SOftAP macaddress : "MAC_ADDRESS_STR),
Jeff Johnson295189b2012-06-20 16:38:30 -07006212 MAC_ADDR_ARRAY(pHostapdAdapter->macAddressCurrent.bytes));
Arif Hussain6d2a3322013-11-17 19:50:10 -08006213 hddLog(LOGW,FL("ssid =%s, beaconint=%d, channel=%d"),
6214 pConfig->SSIDinfo.ssid.ssId, (int)pConfig->beacon_int,
6215 (int)pConfig->channel);
6216 hddLog(LOGW,FL("hw_mode=%x, privacy=%d, authType=%d"),
6217 pConfig->SapHw_mode, pConfig->privacy,
6218 pConfig->authType);
6219 hddLog(LOGW,FL("RSN/WPALen=%d, Uapsd = %d"),
6220 (int)pConfig->RSNWPAReqIELength, pConfig->UapsdEnable);
6221 hddLog(LOGW,FL("ProtEnabled = %d, OBSSProtEnabled = %d"),
6222 pConfig->protEnabled, pConfig->obssProtEnabled);
Jeff Johnson295189b2012-06-20 16:38:30 -07006223
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306224 if(test_bit(SOFTAP_BSS_STARTED, &pHostapdAdapter->event_flags))
Jeff Johnson295189b2012-06-20 16:38:30 -07006225 {
6226 //Bss already started. just return.
6227 //TODO Probably it should update some beacon params.
6228 hddLog( LOGE, "Bss Already started...Ignore the request");
6229 EXIT();
6230 return 0;
6231 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306232
Agarwal Ashish51325b52014-06-16 16:50:49 +05306233 if (vos_max_concurrent_connections_reached()) {
6234 hddLog(VOS_TRACE_LEVEL_INFO, FL("Reached max concurrent connections"));
6235 return -EINVAL;
6236 }
6237
Jeff Johnson295189b2012-06-20 16:38:30 -07006238 pConfig->persona = pHostapdAdapter->device_mode;
6239
Peng Xu2446a892014-09-05 17:21:18 +05306240 psmeConfig = (tSmeConfigParams*) vos_mem_malloc(sizeof(tSmeConfigParams));
6241 if ( NULL != psmeConfig)
6242 {
6243 sme_GetConfigParam(hHal, psmeConfig);
6244 pConfig->scanBandPreference = psmeConfig->csrConfig.scanBandPreference;
6245 vos_mem_free(psmeConfig);
6246 }
Peng Xuafc34e32014-09-25 13:23:55 +05306247 pConfig->acsBandSwitchThreshold = iniConfig->acsBandSwitchThreshold;
Peng Xu2446a892014-09-05 17:21:18 +05306248
Jeff Johnson295189b2012-06-20 16:38:30 -07006249 pSapEventCallback = hdd_hostapd_SAPEventCB;
6250 if(WLANSAP_StartBss(pVosContext, pSapEventCallback, pConfig,
6251 (v_PVOID_t)pHostapdAdapter->dev) != VOS_STATUS_SUCCESS)
6252 {
Arif Hussain6d2a3322013-11-17 19:50:10 -08006253 hddLog(LOGE,FL("SAP Start Bss fail"));
Jeff Johnson295189b2012-06-20 16:38:30 -07006254 return -EINVAL;
6255 }
6256
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306257 hddLog(LOG1,
Jeff Johnson295189b2012-06-20 16:38:30 -07006258 FL("Waiting for Scan to complete(auto mode) and BSS to start"));
6259
6260 status = vos_wait_single_event(&pHostapdState->vosEvent, 10000);
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306261
Jeff Johnson295189b2012-06-20 16:38:30 -07006262 if (!VOS_IS_STATUS_SUCCESS(status))
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306263 {
6264 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Arif Hussain6d2a3322013-11-17 19:50:10 -08006265 ("ERROR: HDD vos wait for single_event failed!!"));
Tushnim Bhattacharyyaad37df12013-10-02 12:01:33 -07006266 smeGetCommandQStatus(hHal);
Jeff Johnson295189b2012-06-20 16:38:30 -07006267 VOS_ASSERT(0);
6268 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306269
Jeff Johnson295189b2012-06-20 16:38:30 -07006270 set_bit(SOFTAP_BSS_STARTED, &pHostapdAdapter->event_flags);
Agarwal Ashish51325b52014-06-16 16:50:49 +05306271 wlan_hdd_incr_active_session(pHddCtx, pHostapdAdapter->device_mode);
Jeff Johnson295189b2012-06-20 16:38:30 -07006272
Madan Mohan Koyyalamudi26bd7142012-10-30 18:14:19 -07006273#ifdef WLAN_FEATURE_P2P_DEBUG
6274 if (pHostapdAdapter->device_mode == WLAN_HDD_P2P_GO)
6275 {
6276 if(globalP2PConnectionStatus == P2P_GO_NEG_COMPLETED)
6277 {
6278 globalP2PConnectionStatus = P2P_GO_COMPLETED_STATE;
6279 hddLog(LOGE,"[P2P State] From Go nego completed to "
Jeff Johnson1250df42012-12-10 14:31:52 -08006280 "Non-autonomous Group started");
Madan Mohan Koyyalamudi26bd7142012-10-30 18:14:19 -07006281 }
6282 else if(globalP2PConnectionStatus == P2P_NOT_ACTIVE)
6283 {
6284 globalP2PConnectionStatus = P2P_GO_COMPLETED_STATE;
6285 hddLog(LOGE,"[P2P State] From Inactive to "
Jeff Johnson1250df42012-12-10 14:31:52 -08006286 "Autonomous Group started");
Madan Mohan Koyyalamudi26bd7142012-10-30 18:14:19 -07006287 }
6288 }
6289#endif
6290
Jeff Johnson295189b2012-06-20 16:38:30 -07006291 pHostapdState->bCommit = TRUE;
6292 EXIT();
6293
6294 return 0;
6295}
6296
Jeff Johnson04dd8a82012-06-29 20:41:40 -07006297#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,4,0))
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306298static int wlan_hdd_cfg80211_add_beacon(struct wiphy *wiphy,
6299 struct net_device *dev,
Jeff Johnson295189b2012-06-20 16:38:30 -07006300 struct beacon_parameters *params)
6301{
6302 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +05306303 hdd_context_t *pHddCtx;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05306304 int status;
Jeff Johnson295189b2012-06-20 16:38:30 -07006305
6306 ENTER();
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +05306307
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05306308 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
6309 TRACE_CODE_HDD_CFG80211_ADD_BEACON,
6310 pAdapter->sessionId, params->interval));
Sushant Kaushik8bc7df22014-04-09 17:55:29 +05306311 hddLog(VOS_TRACE_LEVEL_INFO_HIGH, "device mode=%s (%d)",
6312 hdd_device_modetoString(pAdapter->device_mode),
6313 pAdapter->device_mode);
Jeff Johnson295189b2012-06-20 16:38:30 -07006314
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05306315 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
6316 status = wlan_hdd_validate_context(pHddCtx);
6317
6318 if (0 != status)
Jeff Johnson04dd8a82012-06-29 20:41:40 -07006319 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05306320 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
6321 "%s: HDD context is not valid", __func__);
6322 return status;
Jeff Johnson04dd8a82012-06-29 20:41:40 -07006323 }
6324
Agarwal Ashish51325b52014-06-16 16:50:49 +05306325 if (vos_max_concurrent_connections_reached()) {
6326 hddLog(VOS_TRACE_LEVEL_INFO, FL("Reached max concurrent connections"));
6327 return -EINVAL;
6328 }
6329
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306330 if ( (pAdapter->device_mode == WLAN_HDD_SOFTAP)
Jeff Johnson295189b2012-06-20 16:38:30 -07006331 || (pAdapter->device_mode == WLAN_HDD_P2P_GO)
Jeff Johnson295189b2012-06-20 16:38:30 -07006332 )
6333 {
6334 beacon_data_t *old,*new;
6335
6336 old = pAdapter->sessionCtx.ap.beacon;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306337
Jeff Johnson295189b2012-06-20 16:38:30 -07006338 if (old)
c_hpothu6ff1c3c2013-10-01 19:01:57 +05306339 {
6340 hddLog(VOS_TRACE_LEVEL_WARN,
6341 FL("already beacon info added to session(%d)"),
6342 pAdapter->sessionId);
Jeff Johnson295189b2012-06-20 16:38:30 -07006343 return -EALREADY;
c_hpothu6ff1c3c2013-10-01 19:01:57 +05306344 }
Jeff Johnson295189b2012-06-20 16:38:30 -07006345
6346 status = wlan_hdd_cfg80211_alloc_new_beacon(pAdapter,&new,params);
6347
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306348 if(status != VOS_STATUS_SUCCESS)
Jeff Johnson295189b2012-06-20 16:38:30 -07006349 {
6350 hddLog(VOS_TRACE_LEVEL_FATAL,
Arif Hussain6d2a3322013-11-17 19:50:10 -08006351 "%s:Error!!! Allocating the new beacon",__func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07006352 return -EINVAL;
6353 }
6354
6355 pAdapter->sessionCtx.ap.beacon = new;
6356
6357 status = wlan_hdd_cfg80211_start_bss(pAdapter, params);
6358 }
6359
6360 EXIT();
6361 return status;
6362}
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306363
6364static int wlan_hdd_cfg80211_set_beacon(struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -07006365 struct net_device *dev,
6366 struct beacon_parameters *params)
6367{
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306368 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +05306369 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
6370 hdd_context_t *pHddCtx;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05306371 int status;
Jeff Johnson295189b2012-06-20 16:38:30 -07006372
6373 ENTER();
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +05306374 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
6375 TRACE_CODE_HDD_CFG80211_SET_BEACON,
6376 pAdapter->sessionId, pHddStaCtx->conn_info.authType));
6377 hddLog(VOS_TRACE_LEVEL_INFO, "%s: device_mode = %s (%d)",
6378 __func__, hdd_device_modetoString(pAdapter->device_mode),
6379 pAdapter->device_mode);
6380
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05306381 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
6382 status = wlan_hdd_validate_context(pHddCtx);
6383
6384 if (0 != status)
Jeff Johnson04dd8a82012-06-29 20:41:40 -07006385 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05306386 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
6387 "%s: HDD context is not valid", __func__);
6388 return status;
Jeff Johnson04dd8a82012-06-29 20:41:40 -07006389 }
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +05306390
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306391 if ((pAdapter->device_mode == WLAN_HDD_SOFTAP)
Jeff Johnson295189b2012-06-20 16:38:30 -07006392 || (pAdapter->device_mode == WLAN_HDD_P2P_GO)
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306393 )
Jeff Johnson295189b2012-06-20 16:38:30 -07006394 {
6395 beacon_data_t *old,*new;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306396
Jeff Johnson295189b2012-06-20 16:38:30 -07006397 old = pAdapter->sessionCtx.ap.beacon;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306398
Jeff Johnson295189b2012-06-20 16:38:30 -07006399 if (!old)
c_hpothu6ff1c3c2013-10-01 19:01:57 +05306400 {
6401 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
6402 FL("session(%d) old and new heads points to NULL"),
6403 pAdapter->sessionId);
Jeff Johnson295189b2012-06-20 16:38:30 -07006404 return -ENOENT;
c_hpothu6ff1c3c2013-10-01 19:01:57 +05306405 }
Jeff Johnson295189b2012-06-20 16:38:30 -07006406
6407 status = wlan_hdd_cfg80211_alloc_new_beacon(pAdapter,&new,params);
6408
6409 if(status != VOS_STATUS_SUCCESS) {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306410 hddLog(VOS_TRACE_LEVEL_FATAL,
Arif Hussain6d2a3322013-11-17 19:50:10 -08006411 "%s: Error!!! Allocating the new beacon",__func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07006412 return -EINVAL;
6413 }
6414
6415 pAdapter->sessionCtx.ap.beacon = new;
6416
6417 status = wlan_hdd_cfg80211_start_bss(pAdapter, params);
6418 }
6419
6420 EXIT();
6421 return status;
6422}
6423
Jeff Johnson04dd8a82012-06-29 20:41:40 -07006424#endif //(LINUX_VERSION_CODE < KERNEL_VERSION(3,4,0))
6425
6426#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,4,0))
Jeff Johnson295189b2012-06-20 16:38:30 -07006427static int wlan_hdd_cfg80211_del_beacon(struct wiphy *wiphy,
6428 struct net_device *dev)
Jeff Johnson04dd8a82012-06-29 20:41:40 -07006429#else
6430static int wlan_hdd_cfg80211_stop_ap (struct wiphy *wiphy,
6431 struct net_device *dev)
6432#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07006433{
6434 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
Jeff Johnsone7245742012-09-05 17:12:55 -07006435 hdd_context_t *pHddCtx = NULL;
6436 hdd_scaninfo_t *pScanInfo = NULL;
6437 hdd_adapter_t *staAdapter = NULL;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05306438 VOS_STATUS status;
Mahesh A Saptasagar2395ee62014-05-21 19:12:21 +05306439 long ret;
Jeff Johnson295189b2012-06-20 16:38:30 -07006440
6441 ENTER();
6442
6443 if (NULL == pAdapter)
6444 {
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +05306445 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07006446 "%s: HDD adapter context is Null", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07006447 return -ENODEV;
6448 }
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -07006449
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05306450 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
6451 TRACE_CODE_HDD_CFG80211_STOP_AP,
6452 pAdapter->sessionId, pAdapter->device_mode));
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05306453 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
6454 status = wlan_hdd_validate_context(pHddCtx);
6455
6456 if (0 != status)
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -07006457 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05306458 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
6459 "%s: HDD context is not valid", __func__);
6460 return status;
Jeff Johnson4416a782013-03-25 14:17:50 -07006461 }
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -07006462
6463 staAdapter = hdd_get_adapter(pAdapter->pHddCtx, WLAN_HDD_INFRA_STATION);
6464 if (NULL == staAdapter)
6465 {
6466 staAdapter = hdd_get_adapter(pAdapter->pHddCtx, WLAN_HDD_P2P_CLIENT);
6467 if (NULL == staAdapter)
6468 {
Rajesh Chauhan52d885b2013-11-01 10:54:25 -07006469 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO_HIGH,
6470 "%s: HDD adapter context for STA/P2P-CLI is Null",
6471 __func__);
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -07006472 }
6473 }
6474
6475 pScanInfo = &pHddCtx->scan_info;
6476
Sushant Kaushik8bc7df22014-04-09 17:55:29 +05306477 hddLog(VOS_TRACE_LEVEL_INFO, "%s: device_mode = %s (%d)",
6478 __func__, hdd_device_modetoString(pAdapter->device_mode),
6479 pAdapter->device_mode);
Jeff Johnson295189b2012-06-20 16:38:30 -07006480
Mahesh A Saptasagar2395ee62014-05-21 19:12:21 +05306481 ret = wlan_hdd_scan_abort(pAdapter);
6482
Girish Gowli4bf7a632014-06-12 13:42:11 +05306483 if (ret < 0)
Jeff Johnsone7245742012-09-05 17:12:55 -07006484 {
Mahesh A Saptasagar2395ee62014-05-21 19:12:21 +05306485 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
6486 FL("Timeout occurred while waiting for abortscan %ld"), ret);
c_hpothu6ff1c3c2013-10-01 19:01:57 +05306487
Mahesh A Saptasagar2395ee62014-05-21 19:12:21 +05306488 if (pHddCtx->isLogpInProgress)
Jeff Johnsone7245742012-09-05 17:12:55 -07006489 {
Mahesh A Saptasagar2395ee62014-05-21 19:12:21 +05306490 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
6491 "%s: LOGP in Progress. Ignore!!!", __func__);
Yue Ma4f55ef32014-01-23 16:45:33 -08006492
Jeff Johnsone7245742012-09-05 17:12:55 -07006493 VOS_ASSERT(pScanInfo->mScanPending);
Mahesh A Saptasagar2395ee62014-05-21 19:12:21 +05306494 return -EAGAIN;
Jeff Johnsone7245742012-09-05 17:12:55 -07006495 }
Mahesh A Saptasagar2395ee62014-05-21 19:12:21 +05306496 VOS_ASSERT(pScanInfo->mScanPending);
Jeff Johnsone7245742012-09-05 17:12:55 -07006497 }
6498
Rashmi Ramanna1f0948d2014-08-28 15:33:48 +05306499 /* Delete all associated STAs before stopping AP/P2P GO */
6500 hdd_del_all_sta(pAdapter);
Arun Kumar Khandavallia3bd8002014-01-17 16:21:19 +05306501 hdd_hostapd_stop(dev);
6502
Jeff Johnson295189b2012-06-20 16:38:30 -07006503 if ((pAdapter->device_mode == WLAN_HDD_SOFTAP)
Jeff Johnson295189b2012-06-20 16:38:30 -07006504 || (pAdapter->device_mode == WLAN_HDD_P2P_GO)
Jeff Johnson295189b2012-06-20 16:38:30 -07006505 )
6506 {
6507 beacon_data_t *old;
6508
6509 old = pAdapter->sessionCtx.ap.beacon;
6510
6511 if (!old)
c_hpothu6ff1c3c2013-10-01 19:01:57 +05306512 {
6513 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
6514 FL("session(%d) beacon data points to NULL"),
6515 pAdapter->sessionId);
Jeff Johnson295189b2012-06-20 16:38:30 -07006516 return -ENOENT;
c_hpothu6ff1c3c2013-10-01 19:01:57 +05306517 }
Jeff Johnson295189b2012-06-20 16:38:30 -07006518
Jeff Johnson295189b2012-06-20 16:38:30 -07006519 hdd_cleanup_actionframe(pHddCtx, pAdapter);
Jeff Johnson295189b2012-06-20 16:38:30 -07006520
6521 mutex_lock(&pHddCtx->sap_lock);
6522 if(test_bit(SOFTAP_BSS_STARTED, &pAdapter->event_flags))
6523 {
Jeff Johnson4416a782013-03-25 14:17:50 -07006524 if ( VOS_STATUS_SUCCESS == (status = WLANSAP_StopBss(pHddCtx->pvosContext) ) )
Jeff Johnson295189b2012-06-20 16:38:30 -07006525 {
6526 hdd_hostapd_state_t *pHostapdState = WLAN_HDD_GET_HOSTAP_STATE_PTR(pAdapter);
6527
6528 status = vos_wait_single_event(&pHostapdState->vosEvent, 10000);
6529
6530 if (!VOS_IS_STATUS_SUCCESS(status))
6531 {
6532 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Arif Hussain6d2a3322013-11-17 19:50:10 -08006533 ("ERROR: HDD vos wait for single_event failed!!"));
Jeff Johnson295189b2012-06-20 16:38:30 -07006534 VOS_ASSERT(0);
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05306535 }
6536 }
Jeff Johnson295189b2012-06-20 16:38:30 -07006537 clear_bit(SOFTAP_BSS_STARTED, &pAdapter->event_flags);
Agarwal Ashish51325b52014-06-16 16:50:49 +05306538 /* BSS stopped, clear the active sessions for this device mode */
6539 wlan_hdd_decr_active_session(pHddCtx, pAdapter->device_mode);
Jeff Johnson295189b2012-06-20 16:38:30 -07006540 }
6541 mutex_unlock(&pHddCtx->sap_lock);
6542
6543 if(status != VOS_STATUS_SUCCESS)
6544 {
6545 hddLog(VOS_TRACE_LEVEL_FATAL,
Arif Hussain6d2a3322013-11-17 19:50:10 -08006546 "%s:Error!!! Stopping the BSS",__func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07006547 return -EINVAL;
6548 }
6549
Jeff Johnson4416a782013-03-25 14:17:50 -07006550 if (ccmCfgSetInt(pHddCtx->hHal,
Jeff Johnson295189b2012-06-20 16:38:30 -07006551 WNI_CFG_PROBE_RSP_BCN_ADDNIE_FLAG, 0,NULL, eANI_BOOLEAN_FALSE)
6552 ==eHAL_STATUS_FAILURE)
6553 {
6554 hddLog(LOGE,
Arif Hussain6d2a3322013-11-17 19:50:10 -08006555 "Could not pass on WNI_CFG_PROBE_RSP_BCN_ADDNIE_FLAG to CCM");
Jeff Johnson295189b2012-06-20 16:38:30 -07006556 }
6557
Jeff Johnson4416a782013-03-25 14:17:50 -07006558 if ( eHAL_STATUS_FAILURE == ccmCfgSetInt(pHddCtx->hHal,
Jeff Johnson295189b2012-06-20 16:38:30 -07006559 WNI_CFG_ASSOC_RSP_ADDNIE_FLAG, 0, NULL,
6560 eANI_BOOLEAN_FALSE) )
6561 {
6562 hddLog(LOGE,
Arif Hussain6d2a3322013-11-17 19:50:10 -08006563 "Could not pass on WNI_CFG_ASSOC_RSP_ADDNIE_FLAG to CCM");
Jeff Johnson295189b2012-06-20 16:38:30 -07006564 }
6565
6566 // Reset WNI_CFG_PROBE_RSP Flags
6567 wlan_hdd_reset_prob_rspies(pAdapter);
6568
6569 pAdapter->sessionCtx.ap.beacon = NULL;
6570 kfree(old);
Madan Mohan Koyyalamudi26bd7142012-10-30 18:14:19 -07006571#ifdef WLAN_FEATURE_P2P_DEBUG
6572 if((pAdapter->device_mode == WLAN_HDD_P2P_GO) &&
6573 (globalP2PConnectionStatus == P2P_GO_COMPLETED_STATE))
6574 {
6575 hddLog(LOGE,"[P2P State] From GO completed to Inactive state "
6576 "GO got removed");
6577 globalP2PConnectionStatus = P2P_NOT_ACTIVE;
6578 }
6579#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07006580 }
6581 EXIT();
6582 return status;
6583}
Jeff Johnson04dd8a82012-06-29 20:41:40 -07006584
6585#if (LINUX_VERSION_CODE > KERNEL_VERSION(3,3,0))
6586
Pratik Bhalgata0c7f262012-11-22 17:40:24 +05306587static int wlan_hdd_cfg80211_start_ap(struct wiphy *wiphy,
6588 struct net_device *dev,
Jeff Johnson04dd8a82012-06-29 20:41:40 -07006589 struct cfg80211_ap_settings *params)
6590{
Pratik Bhalgata0c7f262012-11-22 17:40:24 +05306591 hdd_adapter_t *pAdapter;
6592 hdd_context_t *pHddCtx;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05306593 int status;
Jeff Johnson04dd8a82012-06-29 20:41:40 -07006594
6595 ENTER();
6596
Pratik Bhalgata0c7f262012-11-22 17:40:24 +05306597 if (NULL == dev)
Madan Mohan Koyyalamudib2c36892012-10-18 20:52:38 -07006598 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05306599 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Pratik Bhalgata0c7f262012-11-22 17:40:24 +05306600 "%s: Device is Null", __func__);
6601 return -ENODEV;
6602 }
6603
6604 pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
6605 if (NULL == pAdapter)
6606 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05306607 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Pratik Bhalgata0c7f262012-11-22 17:40:24 +05306608 "%s: HDD adapter is Null", __func__);
6609 return -ENODEV;
6610 }
6611
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05306612 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
6613 TRACE_CODE_HDD_CFG80211_START_AP, pAdapter->sessionId,
6614 params-> beacon_interval));
Pratik Bhalgata0c7f262012-11-22 17:40:24 +05306615 if (WLAN_HDD_ADAPTER_MAGIC != pAdapter->magic)
6616 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05306617 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Pratik Bhalgata0c7f262012-11-22 17:40:24 +05306618 "%s: HDD adapter magic is invalid", __func__);
6619 return -ENODEV;
6620 }
6621
6622 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05306623 status = wlan_hdd_validate_context(pHddCtx);
Pratik Bhalgata0c7f262012-11-22 17:40:24 +05306624
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05306625 if (0 != status)
Pratik Bhalgata0c7f262012-11-22 17:40:24 +05306626 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05306627 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
6628 "%s: HDD context is not valid", __func__);
6629 return status;
Pratik Bhalgata0c7f262012-11-22 17:40:24 +05306630 }
6631
Sushant Kaushik8bc7df22014-04-09 17:55:29 +05306632 hddLog(VOS_TRACE_LEVEL_INFO_HIGH, "%s: device mode = %s (%d)",
6633 __func__, hdd_device_modetoString(pAdapter->device_mode),
6634 pAdapter->device_mode);
Pratik Bhalgata0c7f262012-11-22 17:40:24 +05306635
6636 if ((pAdapter->device_mode == WLAN_HDD_SOFTAP)
Jeff Johnson04dd8a82012-06-29 20:41:40 -07006637 || (pAdapter->device_mode == WLAN_HDD_P2P_GO)
Jeff Johnson04dd8a82012-06-29 20:41:40 -07006638 )
6639 {
Pratik Bhalgata0c7f262012-11-22 17:40:24 +05306640 beacon_data_t *old, *new;
Jeff Johnson04dd8a82012-06-29 20:41:40 -07006641
6642 old = pAdapter->sessionCtx.ap.beacon;
Pratik Bhalgata0c7f262012-11-22 17:40:24 +05306643
Jeff Johnson04dd8a82012-06-29 20:41:40 -07006644 if (old)
c_hpothu6ff1c3c2013-10-01 19:01:57 +05306645 {
6646 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_WARN,
6647 FL("already beacon info added to session(%d)"),
6648 pAdapter->sessionId);
Jeff Johnson04dd8a82012-06-29 20:41:40 -07006649 return -EALREADY;
c_hpothu6ff1c3c2013-10-01 19:01:57 +05306650 }
Jeff Johnson04dd8a82012-06-29 20:41:40 -07006651
6652 status = wlan_hdd_cfg80211_alloc_new_beacon(pAdapter, &new, &params->beacon, params->dtim_period);
6653
Pratik Bhalgata0c7f262012-11-22 17:40:24 +05306654 if (status != 0)
Jeff Johnson04dd8a82012-06-29 20:41:40 -07006655 {
6656 hddLog(VOS_TRACE_LEVEL_FATAL,
Pratik Bhalgata0c7f262012-11-22 17:40:24 +05306657 "%s:Error!!! Allocating the new beacon", __func__);
Jeff Johnson04dd8a82012-06-29 20:41:40 -07006658 return -EINVAL;
6659 }
6660 pAdapter->sessionCtx.ap.beacon = new;
Viral Modi3a32cc52013-02-08 11:14:52 -08006661#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,6,0))
Yue Maf49ba872013-08-19 12:04:25 -07006662 wlan_hdd_cfg80211_set_channel(wiphy, dev,
6663#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,8,0))
6664 params->channel, params->channel_type);
6665#else
6666 params->chandef.chan, cfg80211_get_chandef_type(&(params->chandef)));
6667#endif
Viral Modi3a32cc52013-02-08 11:14:52 -08006668#endif
Jeff Johnson04dd8a82012-06-29 20:41:40 -07006669 status = wlan_hdd_cfg80211_start_bss(pAdapter, &params->beacon, params->ssid,
6670 params->ssid_len, params->hidden_ssid);
6671 }
6672
6673 EXIT();
6674 return status;
6675}
6676
6677
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306678static int wlan_hdd_cfg80211_change_beacon(struct wiphy *wiphy,
Jeff Johnson04dd8a82012-06-29 20:41:40 -07006679 struct net_device *dev,
6680 struct cfg80211_beacon_data *params)
6681{
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306682 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +05306683 hdd_context_t *pHddCtx;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05306684 int status;
Jeff Johnson04dd8a82012-06-29 20:41:40 -07006685
6686 ENTER();
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +05306687
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05306688 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
6689 TRACE_CODE_HDD_CFG80211_CHANGE_BEACON,
6690 pAdapter->sessionId, pAdapter->device_mode));
Arif Hussain6d2a3322013-11-17 19:50:10 -08006691 hddLog(VOS_TRACE_LEVEL_INFO, "%s: device_mode = %d",
Jeff Johnson04dd8a82012-06-29 20:41:40 -07006692 __func__, pAdapter->device_mode);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05306693
6694 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
6695 status = wlan_hdd_validate_context(pHddCtx);
6696
6697 if (0 != status)
Madan Mohan Koyyalamudib2c36892012-10-18 20:52:38 -07006698 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05306699 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
6700 "%s: HDD context is not valid", __func__);
6701 return status;
Madan Mohan Koyyalamudib2c36892012-10-18 20:52:38 -07006702 }
Jeff Johnson04dd8a82012-06-29 20:41:40 -07006703
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306704 if ((pAdapter->device_mode == WLAN_HDD_SOFTAP)
Jeff Johnson04dd8a82012-06-29 20:41:40 -07006705 || (pAdapter->device_mode == WLAN_HDD_P2P_GO)
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306706 )
Jeff Johnson04dd8a82012-06-29 20:41:40 -07006707 {
6708 beacon_data_t *old,*new;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306709
Jeff Johnson04dd8a82012-06-29 20:41:40 -07006710 old = pAdapter->sessionCtx.ap.beacon;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306711
Jeff Johnson04dd8a82012-06-29 20:41:40 -07006712 if (!old)
c_hpothu6ff1c3c2013-10-01 19:01:57 +05306713 {
6714 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
6715 FL("session(%d) beacon data points to NULL"),
6716 pAdapter->sessionId);
Jeff Johnson04dd8a82012-06-29 20:41:40 -07006717 return -ENOENT;
c_hpothu6ff1c3c2013-10-01 19:01:57 +05306718 }
Jeff Johnson04dd8a82012-06-29 20:41:40 -07006719
6720 status = wlan_hdd_cfg80211_alloc_new_beacon(pAdapter, &new, params, 0);
6721
6722 if(status != VOS_STATUS_SUCCESS) {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306723 hddLog(VOS_TRACE_LEVEL_FATAL,
Arif Hussain6d2a3322013-11-17 19:50:10 -08006724 "%s: Error!!! Allocating the new beacon",__func__);
Jeff Johnson04dd8a82012-06-29 20:41:40 -07006725 return -EINVAL;
6726 }
6727
6728 pAdapter->sessionCtx.ap.beacon = new;
6729
6730 status = wlan_hdd_cfg80211_start_bss(pAdapter, params, NULL, 0, 0);
6731 }
6732
6733 EXIT();
6734 return status;
6735}
6736
6737#endif //(LINUX_VERSION_CODE > KERNEL_VERSION(3,3,0))
6738
Jeff Johnson295189b2012-06-20 16:38:30 -07006739
Mahesh A Saptasagar179d2252014-06-02 21:32:21 +05306740static int __wlan_hdd_cfg80211_change_bss (struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -07006741 struct net_device *dev,
6742 struct bss_parameters *params)
6743{
6744 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
6745
6746 ENTER();
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +05306747
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05306748 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
6749 TRACE_CODE_HDD_CFG80211_CHANGE_BSS,
6750 pAdapter->sessionId, params->ap_isolate));
Sushant Kaushik8bc7df22014-04-09 17:55:29 +05306751 hddLog(VOS_TRACE_LEVEL_INFO, "%s: device_mode = %s (%d)",
6752 __func__, hdd_device_modetoString(pAdapter->device_mode),
6753 pAdapter->device_mode);
Jeff Johnson295189b2012-06-20 16:38:30 -07006754
6755 if((pAdapter->device_mode == WLAN_HDD_SOFTAP)
Jeff Johnson295189b2012-06-20 16:38:30 -07006756 || (pAdapter->device_mode == WLAN_HDD_P2P_GO)
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306757 )
Jeff Johnson295189b2012-06-20 16:38:30 -07006758 {
6759 /* ap_isolate == -1 means that in change bss, upper layer doesn't
6760 * want to update this parameter */
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306761 if (-1 != params->ap_isolate)
Jeff Johnson295189b2012-06-20 16:38:30 -07006762 {
6763 pAdapter->sessionCtx.ap.apDisableIntraBssFwd = !!params->ap_isolate;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306764 }
Jeff Johnson295189b2012-06-20 16:38:30 -07006765 }
6766
6767 EXIT();
6768 return 0;
6769}
6770
Mahesh A Saptasagar179d2252014-06-02 21:32:21 +05306771static int wlan_hdd_cfg80211_change_bss (struct wiphy *wiphy,
6772 struct net_device *dev,
6773 struct bss_parameters *params)
6774{
6775 int ret;
6776
6777 vos_ssr_protect(__func__);
6778 ret = __wlan_hdd_cfg80211_change_bss(wiphy, dev, params);
6779 vos_ssr_unprotect(__func__);
6780
6781 return ret;
6782}
Kiet Lam10841362013-11-01 11:36:50 +05306783/* FUNCTION: wlan_hdd_change_country_code_cd
6784* to wait for contry code completion
6785*/
6786void* wlan_hdd_change_country_code_cb(void *pAdapter)
6787{
6788 hdd_adapter_t *call_back_pAdapter = pAdapter;
6789 complete(&call_back_pAdapter->change_country_code);
6790 return NULL;
6791}
6792
Jeff Johnson295189b2012-06-20 16:38:30 -07006793/*
Mahesh A Saptasagar0e59c472014-04-14 19:17:41 +05306794 * FUNCTION: __wlan_hdd_cfg80211_change_iface
Jeff Johnson295189b2012-06-20 16:38:30 -07006795 * This function is used to set the interface type (INFRASTRUCTURE/ADHOC)
6796 */
Mahesh A Saptasagar0e59c472014-04-14 19:17:41 +05306797int __wlan_hdd_cfg80211_change_iface( struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -07006798 struct net_device *ndev,
6799 enum nl80211_iftype type,
6800 u32 *flags,
6801 struct vif_params *params
6802 )
6803{
6804 struct wireless_dev *wdev;
6805 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( ndev );
Rajesh Chauhana0516c62014-01-30 16:11:18 -08006806 hdd_context_t *pHddCtx;
Mohit Khanna0f232092012-09-11 14:46:08 -07006807 hdd_adapter_t *pP2pAdapter = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -07006808 tCsrRoamProfile *pRoamProfile = NULL;
6809 eCsrRoamBssType LastBSSType;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05306810 hdd_config_t *pConfig = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -07006811 eMib_dot11DesiredBssType connectedBssType;
6812 VOS_STATUS status;
c_hpothu6ff1c3c2013-10-01 19:01:57 +05306813 long ret;
Jeff Johnson295189b2012-06-20 16:38:30 -07006814
6815 ENTER();
6816
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05306817 if (!pAdapter)
Rajesh Chauhana0516c62014-01-30 16:11:18 -08006818 {
6819 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
6820 "%s: Adapter context is null", __func__);
6821 return VOS_STATUS_E_FAILURE;
6822 }
6823
6824 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
6825 if (!pHddCtx)
6826 {
6827 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
6828 "%s: HDD context is null", __func__);
6829 return VOS_STATUS_E_FAILURE;
6830 }
6831
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05306832 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
6833 TRACE_CODE_HDD_CFG80211_CHANGE_IFACE,
6834 pAdapter->sessionId, type));
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05306835 status = wlan_hdd_validate_context(pHddCtx);
6836
6837 if (0 != status)
Jeff Johnson295189b2012-06-20 16:38:30 -07006838 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05306839 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
6840 "%s: HDD context is not valid", __func__);
6841 return status;
Jeff Johnson295189b2012-06-20 16:38:30 -07006842 }
6843
Sushant Kaushik8bc7df22014-04-09 17:55:29 +05306844 hddLog(VOS_TRACE_LEVEL_INFO, "%s: device_mode = %s (%d)",
6845 __func__, hdd_device_modetoString(pAdapter->device_mode),
6846 pAdapter->device_mode);
Jeff Johnson295189b2012-06-20 16:38:30 -07006847
Agarwal Ashish51325b52014-06-16 16:50:49 +05306848 if (vos_max_concurrent_connections_reached()) {
6849 hddLog(VOS_TRACE_LEVEL_INFO, FL("Reached max concurrent connections"));
6850 return -EINVAL;
6851 }
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05306852 pConfig = pHddCtx->cfg_ini;
Jeff Johnson295189b2012-06-20 16:38:30 -07006853 wdev = ndev->ieee80211_ptr;
6854
6855#ifdef WLAN_BTAMP_FEATURE
6856 if((NL80211_IFTYPE_P2P_CLIENT == type)||
6857 (NL80211_IFTYPE_ADHOC == type)||
6858 (NL80211_IFTYPE_AP == type)||
6859 (NL80211_IFTYPE_P2P_GO == type))
6860 {
6861 pHddCtx->isAmpAllowed = VOS_FALSE;
6862 // stop AMP traffic
6863 status = WLANBAP_StopAmp();
6864 if(VOS_STATUS_SUCCESS != status )
6865 {
6866 pHddCtx->isAmpAllowed = VOS_TRUE;
6867 hddLog(VOS_TRACE_LEVEL_FATAL,
6868 "%s: Failed to stop AMP", __func__);
6869 return -EINVAL;
6870 }
6871 }
6872#endif //WLAN_BTAMP_FEATURE
6873 /* Reset the current device mode bit mask*/
6874 wlan_hdd_clear_concurrency_mode(pHddCtx, pAdapter->device_mode);
6875
6876 if( (pAdapter->device_mode == WLAN_HDD_INFRA_STATION)
Jeff Johnson295189b2012-06-20 16:38:30 -07006877 || (pAdapter->device_mode == WLAN_HDD_P2P_CLIENT)
Jeff Johnsone7245742012-09-05 17:12:55 -07006878 || (pAdapter->device_mode == WLAN_HDD_P2P_DEVICE)
Jeff Johnson295189b2012-06-20 16:38:30 -07006879 )
6880 {
6881 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
Rajesh Chauhana0516c62014-01-30 16:11:18 -08006882 if (!pWextState)
6883 {
6884 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
6885 "%s: pWextState is null", __func__);
6886 return VOS_STATUS_E_FAILURE;
6887 }
Jeff Johnson295189b2012-06-20 16:38:30 -07006888 pRoamProfile = &pWextState->roamProfile;
6889 LastBSSType = pRoamProfile->BSSType;
6890
6891 switch (type)
6892 {
6893 case NL80211_IFTYPE_STATION:
Jeff Johnson295189b2012-06-20 16:38:30 -07006894 case NL80211_IFTYPE_P2P_CLIENT:
Jeff Johnson295189b2012-06-20 16:38:30 -07006895 hddLog(VOS_TRACE_LEVEL_INFO,
6896 "%s: setting interface Type to INFRASTRUCTURE", __func__);
6897 pRoamProfile->BSSType = eCSR_BSS_TYPE_INFRASTRUCTURE;
Jeff Johnsone7245742012-09-05 17:12:55 -07006898#ifdef WLAN_FEATURE_11AC
6899 if(pConfig->dot11Mode == eHDD_DOT11_MODE_AUTO)
6900 {
6901 pConfig->dot11Mode = eHDD_DOT11_MODE_11ac;
6902 }
6903#endif
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306904 pRoamProfile->phyMode =
Jeff Johnsone7245742012-09-05 17:12:55 -07006905 hdd_cfg_xlate_to_csr_phy_mode(pConfig->dot11Mode);
Jeff Johnson295189b2012-06-20 16:38:30 -07006906 wdev->iftype = type;
Gopichand Nakkalaf527dc62012-12-31 16:35:10 -08006907 //Check for sub-string p2p to confirm its a p2p interface
6908 if (NULL != strstr(ndev->name,"p2p"))
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306909 {
Gopichand Nakkala864d3552012-12-31 16:08:51 -08006910 pAdapter->device_mode = (type == NL80211_IFTYPE_STATION) ?
6911 WLAN_HDD_P2P_DEVICE : WLAN_HDD_P2P_CLIENT;
6912 }
6913 else
6914 {
6915 pAdapter->device_mode = (type == NL80211_IFTYPE_STATION) ?
Jeff Johnson295189b2012-06-20 16:38:30 -07006916 WLAN_HDD_INFRA_STATION: WLAN_HDD_P2P_CLIENT;
Gopichand Nakkala864d3552012-12-31 16:08:51 -08006917 }
Madan Mohan Koyyalamudi81746922013-07-17 14:38:51 +05306918#ifdef FEATURE_WLAN_TDLS
6919 /* The open adapter for the p2p shall skip initializations in
6920 * tdls_init if the device mode is WLAN_HDD_P2P_DEVICE, for
6921 * TDLS is supported only on WLAN_HDD_P2P_CLIENT. Hence invoke
6922 * tdls_init when the change_iface sets the device mode to
6923 * WLAN_HDD_P2P_CLIENT.
6924 */
6925
6926 if ( pAdapter->device_mode == WLAN_HDD_P2P_CLIENT)
6927 {
Agarwal Ashish4b87f922014-06-18 03:03:21 +05306928 if (0 != wlan_hdd_sta_tdls_init (pAdapter))
Madan Mohan Koyyalamudi81746922013-07-17 14:38:51 +05306929 {
c_hpothu6ff1c3c2013-10-01 19:01:57 +05306930 hddLog(VOS_TRACE_LEVEL_ERROR,
6931 "%s: tdls initialization failed", __func__);
Madan Mohan Koyyalamudi81746922013-07-17 14:38:51 +05306932 return -EINVAL;
6933 }
6934 }
6935#endif
6936
Jeff Johnson295189b2012-06-20 16:38:30 -07006937 break;
6938 case NL80211_IFTYPE_ADHOC:
6939 hddLog(VOS_TRACE_LEVEL_INFO,
6940 "%s: setting interface Type to ADHOC", __func__);
6941 pRoamProfile->BSSType = eCSR_BSS_TYPE_START_IBSS;
6942 pRoamProfile->phyMode =
6943 hdd_cfg_xlate_to_csr_phy_mode(pConfig->dot11Mode);
Shailender Karmuchia734f332013-04-19 14:02:48 -07006944 pAdapter->device_mode = WLAN_HDD_IBSS;
Jeff Johnson295189b2012-06-20 16:38:30 -07006945 wdev->iftype = type;
6946 break;
6947
6948 case NL80211_IFTYPE_AP:
Jeff Johnson295189b2012-06-20 16:38:30 -07006949 case NL80211_IFTYPE_P2P_GO:
Jeff Johnson295189b2012-06-20 16:38:30 -07006950 {
6951 hddLog(VOS_TRACE_LEVEL_INFO_HIGH,
6952 "%s: setting interface Type to %s", __func__,
6953 (type == NL80211_IFTYPE_AP) ? "SoftAP" : "P2pGo");
6954
Gopichand Nakkalaf527dc62012-12-31 16:35:10 -08006955 //Cancel any remain on channel for GO mode
6956 if (NL80211_IFTYPE_P2P_GO == type)
6957 {
6958 wlan_hdd_cancel_existing_remain_on_channel(pAdapter);
6959 }
Mohit Khanna0f232092012-09-11 14:46:08 -07006960 if (NL80211_IFTYPE_AP == type)
6961 {
6962 /* As Loading WLAN Driver one interface being created for p2p device
6963 * address. This will take one HW STA and the max number of clients
6964 * that can connect to softAP will be reduced by one. so while changing
6965 * the interface type to NL80211_IFTYPE_AP (SoftAP) remove p2p0
6966 * interface as it is not required in SoftAP mode.
6967 */
6968
6969 // Get P2P Adapter
6970 pP2pAdapter = hdd_get_adapter(pHddCtx, WLAN_HDD_P2P_DEVICE);
6971
6972 if (pP2pAdapter)
6973 {
Agarwal Ashish3a38bd12014-06-12 15:16:52 +05306974 hdd_stop_adapter(pHddCtx, pP2pAdapter, VOS_TRUE);
Mohit Khanna0f232092012-09-11 14:46:08 -07006975 hdd_deinit_adapter(pHddCtx, pP2pAdapter);
6976 hdd_close_adapter(pHddCtx, pP2pAdapter, VOS_TRUE);
6977 }
6978 }
Swaroop Goltia2e32212014-04-09 23:37:33 +05306979 //Disable IMPS & BMPS for SAP/GO
6980 if(VOS_STATUS_E_FAILURE ==
6981 hdd_disable_bmps_imps(pHddCtx, WLAN_HDD_P2P_GO))
6982 {
6983 //Fail to Exit BMPS
6984 VOS_ASSERT(0);
6985 }
Deepthi Gowri500fc472014-08-11 19:53:10 +05306986
6987 hdd_stop_adapter( pHddCtx, pAdapter, VOS_TRUE );
6988
Madan Mohan Koyyalamudi96797442013-10-08 16:04:42 +05306989#ifdef FEATURE_WLAN_TDLS
Mohit Khanna0f232092012-09-11 14:46:08 -07006990
Madan Mohan Koyyalamudi96797442013-10-08 16:04:42 +05306991 /* A Mutex Lock is introduced while changing the mode to
6992 * protect the concurrent access for the Adapters by TDLS
6993 * module.
6994 */
Rajesh Chauhana34c6e62014-03-25 16:37:58 +05306995 mutex_lock(&pHddCtx->tdls_lock);
Madan Mohan Koyyalamudi96797442013-10-08 16:04:42 +05306996#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07006997 //De-init the adapter.
Jeff Johnson295189b2012-06-20 16:38:30 -07006998 hdd_deinit_adapter( pHddCtx, pAdapter );
6999 memset(&pAdapter->sessionCtx, 0, sizeof(pAdapter->sessionCtx));
Jeff Johnson295189b2012-06-20 16:38:30 -07007000 pAdapter->device_mode = (type == NL80211_IFTYPE_AP) ?
7001 WLAN_HDD_SOFTAP : WLAN_HDD_P2P_GO;
Madan Mohan Koyyalamudi96797442013-10-08 16:04:42 +05307002#ifdef FEATURE_WLAN_TDLS
7003 mutex_unlock(&pHddCtx->tdls_lock);
7004#endif
Madan Mohan Koyyalamudi3ff2a0b2012-10-15 14:33:46 -07007005 if ((WLAN_HDD_SOFTAP == pAdapter->device_mode) &&
7006 (pConfig->apRandomBssidEnabled))
7007 {
7008 /* To meet Android requirements create a randomized
7009 MAC address of the form 02:1A:11:Fx:xx:xx */
7010 get_random_bytes(&ndev->dev_addr[3], 3);
7011 ndev->dev_addr[0] = 0x02;
7012 ndev->dev_addr[1] = 0x1A;
7013 ndev->dev_addr[2] = 0x11;
7014 ndev->dev_addr[3] |= 0xF0;
7015 memcpy(pAdapter->macAddressCurrent.bytes, ndev->dev_addr,
7016 VOS_MAC_ADDR_SIZE);
Arif Hussain24bafea2013-11-15 15:10:03 -08007017 pr_info("wlan: Generated HotSpot BSSID " MAC_ADDRESS_STR"\n",
7018 MAC_ADDR_ARRAY(ndev->dev_addr));
Madan Mohan Koyyalamudi3ff2a0b2012-10-15 14:33:46 -07007019 }
7020
Jeff Johnson295189b2012-06-20 16:38:30 -07007021 hdd_set_ap_ops( pAdapter->dev );
7022
Kiet Lam10841362013-11-01 11:36:50 +05307023 /* This is for only SAP mode where users can
7024 * control country through ini.
7025 * P2P GO follows station country code
7026 * acquired during the STA scanning. */
7027 if((NL80211_IFTYPE_AP == type) &&
7028 (memcmp(pConfig->apCntryCode, CFG_AP_COUNTRY_CODE_DEFAULT, 3) != 0))
7029 {
7030 int status = 0;
7031 VOS_TRACE(VOS_MODULE_ID_HDD,VOS_TRACE_LEVEL_INFO,
7032 "%s: setting country code from INI ", __func__);
7033 init_completion(&pAdapter->change_country_code);
7034 status = (int)sme_ChangeCountryCode(pHddCtx->hHal,
7035 (void *)(tSmeChangeCountryCallback)
7036 wlan_hdd_change_country_code_cb,
7037 pConfig->apCntryCode, pAdapter,
7038 pHddCtx->pvosContext,
Abhishek Singha306a442013-11-07 18:39:01 +05307039 eSIR_FALSE,
7040 eSIR_TRUE);
Kiet Lam10841362013-11-01 11:36:50 +05307041 if (eHAL_STATUS_SUCCESS == status)
7042 {
7043 /* Wait for completion */
c_hpothu6ff1c3c2013-10-01 19:01:57 +05307044 ret = wait_for_completion_interruptible_timeout(
Kiet Lam10841362013-11-01 11:36:50 +05307045 &pAdapter->change_country_code,
7046 msecs_to_jiffies(WLAN_WAIT_TIME_COUNTRY));
c_hpothu6ff1c3c2013-10-01 19:01:57 +05307047 if (ret <= 0)
Kiet Lam10841362013-11-01 11:36:50 +05307048 {
7049 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
c_hpothu6ff1c3c2013-10-01 19:01:57 +05307050 FL("SME Timed out while setting country code %ld"),
7051 ret);
Yue Ma4f55ef32014-01-23 16:45:33 -08007052
7053 if (pHddCtx->isLogpInProgress)
7054 {
7055 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
7056 "%s: LOGP in Progress. Ignore!!!", __func__);
7057 return -EAGAIN;
7058 }
Kiet Lam10841362013-11-01 11:36:50 +05307059 }
7060 }
7061 else
7062 {
7063 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Arif Hussain6d2a3322013-11-17 19:50:10 -08007064 "%s: SME Change Country code failed",__func__);
Kiet Lam10841362013-11-01 11:36:50 +05307065 return -EINVAL;
7066 }
7067 }
Jeff Johnson295189b2012-06-20 16:38:30 -07007068 status = hdd_init_ap_mode(pAdapter);
7069 if(status != VOS_STATUS_SUCCESS)
7070 {
7071 hddLog(VOS_TRACE_LEVEL_FATAL,
7072 "%s: Error initializing the ap mode", __func__);
7073 return -EINVAL;
7074 }
7075 hdd_set_conparam(1);
7076
Jeff Johnson295189b2012-06-20 16:38:30 -07007077 /*interface type changed update in wiphy structure*/
7078 if(wdev)
7079 {
7080 wdev->iftype = type;
7081 pHddCtx->change_iface = type;
7082 }
7083 else
7084 {
7085 hddLog(VOS_TRACE_LEVEL_ERROR,
7086 "%s: ERROR !!!! Wireless dev is NULL", __func__);
7087 return -EINVAL;
7088 }
7089 goto done;
7090 }
7091
7092 default:
7093 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Unsupported interface Type",
7094 __func__);
7095 return -EOPNOTSUPP;
7096 }
7097 }
7098 else if ( (pAdapter->device_mode == WLAN_HDD_SOFTAP)
Jeff Johnson295189b2012-06-20 16:38:30 -07007099 || (pAdapter->device_mode == WLAN_HDD_P2P_GO)
Jeff Johnson295189b2012-06-20 16:38:30 -07007100 )
7101 {
7102 switch(type)
7103 {
7104 case NL80211_IFTYPE_STATION:
Jeff Johnson295189b2012-06-20 16:38:30 -07007105 case NL80211_IFTYPE_P2P_CLIENT:
Jeff Johnson295189b2012-06-20 16:38:30 -07007106 case NL80211_IFTYPE_ADHOC:
Deepthi Gowri500fc472014-08-11 19:53:10 +05307107
7108 hdd_stop_adapter( pHddCtx, pAdapter, VOS_TRUE );
Madan Mohan Koyyalamudi96797442013-10-08 16:04:42 +05307109#ifdef FEATURE_WLAN_TDLS
7110
7111 /* A Mutex Lock is introduced while changing the mode to
7112 * protect the concurrent access for the Adapters by TDLS
7113 * module.
7114 */
Rajesh Chauhana34c6e62014-03-25 16:37:58 +05307115 mutex_lock(&pHddCtx->tdls_lock);
Madan Mohan Koyyalamudi96797442013-10-08 16:04:42 +05307116#endif
Jeff Johnson32d95a32012-09-10 13:15:23 -07007117 hdd_deinit_adapter( pHddCtx, pAdapter );
Jeff Johnson295189b2012-06-20 16:38:30 -07007118 wdev->iftype = type;
Gopichand Nakkalaf527dc62012-12-31 16:35:10 -08007119 //Check for sub-string p2p to confirm its a p2p interface
7120 if (NULL != strstr(ndev->name,"p2p"))
Gopichand Nakkala864d3552012-12-31 16:08:51 -08007121 {
7122 pAdapter->device_mode = (type == NL80211_IFTYPE_STATION) ?
7123 WLAN_HDD_P2P_DEVICE : WLAN_HDD_P2P_CLIENT;
7124 }
7125 else
7126 {
7127 pAdapter->device_mode = (type == NL80211_IFTYPE_STATION) ?
Jeff Johnson295189b2012-06-20 16:38:30 -07007128 WLAN_HDD_INFRA_STATION: WLAN_HDD_P2P_CLIENT;
Gopichand Nakkala864d3552012-12-31 16:08:51 -08007129 }
Jeff Johnson295189b2012-06-20 16:38:30 -07007130 hdd_set_conparam(0);
7131 pHddCtx->change_iface = type;
Jeff Johnson295189b2012-06-20 16:38:30 -07007132 memset(&pAdapter->sessionCtx, 0, sizeof(pAdapter->sessionCtx));
7133 hdd_set_station_ops( pAdapter->dev );
Madan Mohan Koyyalamudi96797442013-10-08 16:04:42 +05307134#ifdef FEATURE_WLAN_TDLS
7135 mutex_unlock(&pHddCtx->tdls_lock);
7136#endif
Sunil Dutt66485cb2013-12-19 19:05:03 +05307137 status = hdd_init_station_mode( pAdapter );
Jeff Johnson295189b2012-06-20 16:38:30 -07007138 if( VOS_STATUS_SUCCESS != status )
7139 return -EOPNOTSUPP;
Jeff Johnsone7245742012-09-05 17:12:55 -07007140 /* In case of JB, for P2P-GO, only change interface will be called,
7141 * This is the right place to enable back bmps_imps()
7142 */
Gopichand Nakkalaa2fe5b02013-06-06 16:32:28 +05307143 if (pHddCtx->hdd_wlan_suspended)
7144 {
7145 hdd_set_pwrparams(pHddCtx);
7146 }
Jeff Johnsone7245742012-09-05 17:12:55 -07007147 hdd_enable_bmps_imps(pHddCtx);
Jeff Johnson295189b2012-06-20 16:38:30 -07007148 goto done;
7149 case NL80211_IFTYPE_AP:
Jeff Johnson295189b2012-06-20 16:38:30 -07007150 case NL80211_IFTYPE_P2P_GO:
Jeff Johnson295189b2012-06-20 16:38:30 -07007151 wdev->iftype = type;
Jeff Johnson295189b2012-06-20 16:38:30 -07007152 pAdapter->device_mode = (type == NL80211_IFTYPE_AP) ?
7153 WLAN_HDD_SOFTAP : WLAN_HDD_P2P_GO;
Jeff Johnson295189b2012-06-20 16:38:30 -07007154 goto done;
7155 default:
7156 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Unsupported interface Type",
7157 __func__);
7158 return -EOPNOTSUPP;
7159
7160 }
7161
7162 }
7163 else
7164 {
Sushant Kaushik8bc7df22014-04-09 17:55:29 +05307165 hddLog(VOS_TRACE_LEVEL_ERROR,"%s: unsupported device mode(%s (%d))",
7166 __func__, hdd_device_modetoString(pAdapter->device_mode),
7167 pAdapter->device_mode);
Jeff Johnson295189b2012-06-20 16:38:30 -07007168 return -EOPNOTSUPP;
7169 }
7170
7171
7172 if(pRoamProfile)
7173 {
7174 if ( LastBSSType != pRoamProfile->BSSType )
7175 {
7176 /*interface type changed update in wiphy structure*/
7177 wdev->iftype = type;
7178
7179 /*the BSS mode changed, We need to issue disconnect
7180 if connected or in IBSS disconnect state*/
7181 if ( hdd_connGetConnectedBssType(
7182 WLAN_HDD_GET_STATION_CTX_PTR(pAdapter), &connectedBssType ) ||
7183 ( eCSR_BSS_TYPE_START_IBSS == LastBSSType ) )
7184 {
7185 /*need to issue a disconnect to CSR.*/
7186 INIT_COMPLETION(pAdapter->disconnect_comp_var);
7187 if( eHAL_STATUS_SUCCESS ==
7188 sme_RoamDisconnect( WLAN_HDD_GET_HAL_CTX(pAdapter),
7189 pAdapter->sessionId,
7190 eCSR_DISCONNECT_REASON_UNSPECIFIED ) )
7191 {
c_hpothu6ff1c3c2013-10-01 19:01:57 +05307192 ret = wait_for_completion_interruptible_timeout(
7193 &pAdapter->disconnect_comp_var,
7194 msecs_to_jiffies(WLAN_WAIT_TIME_DISCONNECT));
7195 if (ret <= 0)
7196 {
7197 hddLog(VOS_TRACE_LEVEL_ERROR,
7198 FL("wait on disconnect_comp_var failed %ld"), ret);
7199 }
Jeff Johnson295189b2012-06-20 16:38:30 -07007200 }
7201 }
7202 }
7203 }
7204
7205done:
7206 /*set bitmask based on updated value*/
7207 wlan_hdd_set_concurrency_mode(pHddCtx, pAdapter->device_mode);
Leo Chang6fe1f922013-06-07 19:21:24 -07007208
7209 /* Only STA mode support TM now
7210 * all other mode, TM feature should be disabled */
7211 if ( (pHddCtx->cfg_ini->thermalMitigationEnable) &&
7212 (~VOS_STA & pHddCtx->concurrency_mode) )
7213 {
7214 hddDevTmLevelChangedHandler(pHddCtx->parent_dev, 0);
7215 }
7216
Jeff Johnson295189b2012-06-20 16:38:30 -07007217#ifdef WLAN_BTAMP_FEATURE
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307218 if((NL80211_IFTYPE_STATION == type) && (pHddCtx->concurrency_mode <= 1) &&
Agarwal Ashish51325b52014-06-16 16:50:49 +05307219 (pHddCtx->no_of_open_sessions[WLAN_HDD_INFRA_STATION] <=1))
Jeff Johnson295189b2012-06-20 16:38:30 -07007220 {
7221 //we are ok to do AMP
7222 pHddCtx->isAmpAllowed = VOS_TRUE;
7223 }
7224#endif //WLAN_BTAMP_FEATURE
7225 EXIT();
7226 return 0;
7227}
7228
Mahesh A Saptasagar0e59c472014-04-14 19:17:41 +05307229/*
7230 * FUNCTION: wlan_hdd_cfg80211_change_iface
7231 * wrapper function to protect the actual implementation from SSR.
7232 */
7233int wlan_hdd_cfg80211_change_iface( struct wiphy *wiphy,
7234 struct net_device *ndev,
7235 enum nl80211_iftype type,
7236 u32 *flags,
7237 struct vif_params *params
7238 )
7239{
7240 int ret;
7241
7242 vos_ssr_protect(__func__);
7243 ret = __wlan_hdd_cfg80211_change_iface(wiphy, ndev, type, flags, params);
7244 vos_ssr_unprotect(__func__);
7245
7246 return ret;
7247}
7248
Gopichand Nakkala681989c2013-03-06 22:27:48 -08007249#ifdef FEATURE_WLAN_TDLS
7250static int wlan_hdd_tdls_add_station(struct wiphy *wiphy,
7251 struct net_device *dev, u8 *mac, bool update, tCsrStaParams *StaParams)
7252{
7253 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
7254 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
7255 VOS_STATUS status;
Hoonki Lee5305c3a2013-04-29 23:28:59 -07007256 hddTdlsPeer_t *pTdlsPeer;
c_hpothu6ff1c3c2013-10-01 19:01:57 +05307257 long ret;
Rajesh Chauhana34c6e62014-03-25 16:37:58 +05307258 tANI_U16 numCurrTdlsPeers;
Gopichand Nakkala681989c2013-03-06 22:27:48 -08007259
7260 ENTER();
7261
Gopichand Nakkala838be5d2013-04-10 22:41:51 +05307262 if (NULL == pHddCtx || NULL == pHddCtx->cfg_ini)
Gopichand Nakkala681989c2013-03-06 22:27:48 -08007263 {
7264 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
7265 "Invalid arguments");
7266 return -EINVAL;
7267 }
Hoonki Lee27511902013-03-14 18:19:06 -07007268
7269 if ((eTDLS_SUPPORT_NOT_ENABLED == pHddCtx->tdls_mode) ||
7270 (eTDLS_SUPPORT_DISABLED == pHddCtx->tdls_mode))
7271 {
7272 VOS_TRACE( VOS_MODULE_ID_HDD, TDLS_LOG_LEVEL,
7273 "%s: TDLS mode is disabled OR not enabled in FW."
7274 MAC_ADDRESS_STR " Request declined.",
7275 __func__, MAC_ADDR_ARRAY(mac));
7276 return -ENOTSUPP;
7277 }
7278
Gopichand Nakkala681989c2013-03-06 22:27:48 -08007279 if (pHddCtx->isLogpInProgress)
7280 {
7281 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
7282 "%s:LOGP in Progress. Ignore!!!", __func__);
Atul Mittal115287b2014-07-08 13:26:33 +05307283 wlan_hdd_tdls_set_link_status(pAdapter,
7284 mac,
7285 eTDLS_LINK_IDLE,
7286 eTDLS_LINK_UNSPECIFIED);
Gopichand Nakkala681989c2013-03-06 22:27:48 -08007287 return -EBUSY;
7288 }
7289
Naresh Jayaram9c6f4462014-02-13 12:20:31 +05307290 pTdlsPeer = wlan_hdd_tdls_get_peer(pAdapter, mac);
Hoonki Lee5305c3a2013-04-29 23:28:59 -07007291
7292 if ( NULL == pTdlsPeer ) {
7293 VOS_TRACE( VOS_MODULE_ID_HDD, TDLS_LOG_LEVEL,
7294 "%s: " MAC_ADDRESS_STR " (update %d) not exist. return invalid",
7295 __func__, MAC_ADDR_ARRAY(mac), update);
7296 return -EINVAL;
Gopichand Nakkala34d1b062013-03-19 15:28:33 -07007297 }
Hoonki Lee5305c3a2013-04-29 23:28:59 -07007298
7299 /* in add station, we accept existing valid staId if there is */
7300 if ((0 == update) &&
7301 ((pTdlsPeer->link_status >= eTDLS_LINK_CONNECTING) ||
7302 (TDLS_STA_INDEX_VALID(pTdlsPeer->staId))))
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -07007303 {
Hoonki Lee5305c3a2013-04-29 23:28:59 -07007304 VOS_TRACE( VOS_MODULE_ID_HDD, TDLS_LOG_LEVEL,
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -07007305 "%s: " MAC_ADDRESS_STR
Hoonki Lee5305c3a2013-04-29 23:28:59 -07007306 " link_status %d. staId %d. add station ignored.",
7307 __func__, MAC_ADDR_ARRAY(mac), pTdlsPeer->link_status, pTdlsPeer->staId);
7308 return 0;
7309 }
7310 /* in change station, we accept only when staId is valid */
7311 if ((1 == update) &&
7312 ((pTdlsPeer->link_status > eTDLS_LINK_CONNECTING) ||
7313 (!TDLS_STA_INDEX_VALID(pTdlsPeer->staId))))
7314 {
7315 VOS_TRACE( VOS_MODULE_ID_HDD, TDLS_LOG_LEVEL,
7316 "%s: " MAC_ADDRESS_STR
7317 " link status %d. staId %d. change station %s.",
7318 __func__, MAC_ADDR_ARRAY(mac), pTdlsPeer->link_status, pTdlsPeer->staId,
7319 (TDLS_STA_INDEX_VALID(pTdlsPeer->staId)) ? "ignored" : "declined");
7320 return (TDLS_STA_INDEX_VALID(pTdlsPeer->staId)) ? 0 : -EPERM;
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -07007321 }
Gopichand Nakkala34d1b062013-03-19 15:28:33 -07007322
7323 /* when others are on-going, we want to change link_status to idle */
Madan Mohan Koyyalamudi96797442013-10-08 16:04:42 +05307324 if (NULL != wlan_hdd_tdls_is_progress(pHddCtx, mac, TRUE))
Gopichand Nakkala681989c2013-03-06 22:27:48 -08007325 {
Gopichand Nakkalac87400e2013-03-13 18:51:00 -07007326 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
7327 "%s: " MAC_ADDRESS_STR
7328 " TDLS setup is ongoing. Request declined.",
7329 __func__, MAC_ADDR_ARRAY(mac));
Gopichand Nakkala05922802013-03-14 12:23:19 -07007330 goto error;
Gopichand Nakkala681989c2013-03-06 22:27:48 -08007331 }
7332
7333 /* first to check if we reached to maximum supported TDLS peer.
7334 TODO: for now, return -EPERM looks working fine,
7335 but need to check if any other errno fit into this category.*/
Rajesh Chauhana34c6e62014-03-25 16:37:58 +05307336 numCurrTdlsPeers = wlan_hdd_tdlsConnectedPeers(pAdapter);
7337 if (HDD_MAX_NUM_TDLS_STA <= numCurrTdlsPeers)
Gopichand Nakkala681989c2013-03-06 22:27:48 -08007338 {
Gopichand Nakkalac87400e2013-03-13 18:51:00 -07007339 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
7340 "%s: " MAC_ADDRESS_STR
Rajesh Chauhana34c6e62014-03-25 16:37:58 +05307341 " TDLS Max peer already connected. Request declined."
7342 " Num of peers (%d), Max allowed (%d).",
7343 __func__, MAC_ADDR_ARRAY(mac), numCurrTdlsPeers,
7344 HDD_MAX_NUM_TDLS_STA);
Gopichand Nakkala05922802013-03-14 12:23:19 -07007345 goto error;
Gopichand Nakkala681989c2013-03-06 22:27:48 -08007346 }
7347 else
7348 {
7349 hddTdlsPeer_t *pTdlsPeer;
Madan Mohan Koyyalamudi96797442013-10-08 16:04:42 +05307350 pTdlsPeer = wlan_hdd_tdls_find_peer(pAdapter, mac, TRUE);
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -07007351 if (pTdlsPeer && TDLS_IS_CONNECTED(pTdlsPeer))
Gopichand Nakkala681989c2013-03-06 22:27:48 -08007352 {
Gopichand Nakkalac87400e2013-03-13 18:51:00 -07007353 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
7354 "%s: " MAC_ADDRESS_STR " already connected. Request declined.",
7355 __func__, MAC_ADDR_ARRAY(mac));
Gopichand Nakkala681989c2013-03-06 22:27:48 -08007356 return -EPERM;
7357 }
7358 }
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -07007359 if (0 == update)
Atul Mittal115287b2014-07-08 13:26:33 +05307360 wlan_hdd_tdls_set_link_status(pAdapter,
7361 mac,
7362 eTDLS_LINK_CONNECTING,
7363 eTDLS_LINK_SUCCESS);
Gopichand Nakkala681989c2013-03-06 22:27:48 -08007364
Jeff Johnsond75fe012013-04-06 10:53:06 -07007365 /* debug code */
Gopichand Nakkala838be5d2013-04-10 22:41:51 +05307366 if (NULL != StaParams)
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -07007367 {
7368 VOS_TRACE(VOS_MODULE_ID_HDD, TDLS_LOG_LEVEL,
7369 "%s: TDLS Peer Parameters.", __func__);
Hoonki Lee66b75f32013-04-16 18:30:07 -07007370 if(StaParams->htcap_present)
7371 {
7372 VOS_TRACE(VOS_MODULE_ID_HDD, TDLS_LOG_LEVEL,
7373 "ht_capa->cap_info: %0x", StaParams->HTCap.capInfo);
7374 VOS_TRACE(VOS_MODULE_ID_HDD, TDLS_LOG_LEVEL,
7375 "ht_capa->extended_capabilities: %0x",
7376 StaParams->HTCap.extendedHtCapInfo);
7377 }
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -07007378 VOS_TRACE(VOS_MODULE_ID_HDD, TDLS_LOG_LEVEL,
7379 "params->capability: %0x",StaParams->capability);
7380 VOS_TRACE(VOS_MODULE_ID_HDD, TDLS_LOG_LEVEL,
Jeff Johnson0299d0a2013-10-30 12:37:43 -07007381 "params->ext_capab_len: %0x",StaParams->extn_capability[0]);
Hoonki Lee66b75f32013-04-16 18:30:07 -07007382 if(StaParams->vhtcap_present)
7383 {
7384 VOS_TRACE(VOS_MODULE_ID_HDD, TDLS_LOG_LEVEL,
7385 "rxMcsMap %x rxHighest %x txMcsMap %x txHighest %x",
7386 StaParams->VHTCap.suppMcs.rxMcsMap, StaParams->VHTCap.suppMcs.rxHighest,
7387 StaParams->VHTCap.suppMcs.txMcsMap, StaParams->VHTCap.suppMcs.txHighest);
7388 }
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -07007389 {
7390 int i = 0;
Hoonki Lee5305c3a2013-04-29 23:28:59 -07007391 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO, "Supported rates:");
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -07007392 for (i = 0; i < sizeof(StaParams->supported_rates); i++)
7393 VOS_TRACE(VOS_MODULE_ID_HDD, TDLS_LOG_LEVEL,
7394 "[%d]: %x ", i, StaParams->supported_rates[i]);
7395 }
Jeff Johnsond75fe012013-04-06 10:53:06 -07007396 } /* end debug code */
Gopichand Nakkala838be5d2013-04-10 22:41:51 +05307397 else if ((1 == update) && (NULL == StaParams))
7398 {
7399 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
7400 "%s : update is true, but staParams is NULL. Error!", __func__);
7401 return -EPERM;
7402 }
Gopichand Nakkala681989c2013-03-06 22:27:48 -08007403
7404 INIT_COMPLETION(pAdapter->tdls_add_station_comp);
7405
7406 if (!update)
7407 {
7408 status = sme_AddTdlsPeerSta(WLAN_HDD_GET_HAL_CTX(pAdapter),
7409 pAdapter->sessionId, mac);
7410 }
7411 else
7412 {
7413 status = sme_ChangeTdlsPeerSta(WLAN_HDD_GET_HAL_CTX(pAdapter),
7414 pAdapter->sessionId, mac, StaParams);
7415 }
7416
c_hpothu6ff1c3c2013-10-01 19:01:57 +05307417 ret = wait_for_completion_interruptible_timeout(&pAdapter->tdls_add_station_comp,
Gopichand Nakkala681989c2013-03-06 22:27:48 -08007418 msecs_to_jiffies(WAIT_TIME_TDLS_ADD_STA));
7419
c_hpothu6ff1c3c2013-10-01 19:01:57 +05307420 if (ret <= 0)
Gopichand Nakkala681989c2013-03-06 22:27:48 -08007421 {
Gopichand Nakkalac87400e2013-03-13 18:51:00 -07007422 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
c_hpothu6ff1c3c2013-10-01 19:01:57 +05307423 "%s: timeout waiting for tdls add station indication %ld",
7424 __func__, ret);
Gopichand Nakkala34d1b062013-03-19 15:28:33 -07007425 return -EPERM;
Gopichand Nakkala681989c2013-03-06 22:27:48 -08007426 }
c_hpothu6ff1c3c2013-10-01 19:01:57 +05307427
Gopichand Nakkala681989c2013-03-06 22:27:48 -08007428 if ( eHAL_STATUS_SUCCESS != pAdapter->tdlsAddStaStatus)
7429 {
Gopichand Nakkalac87400e2013-03-13 18:51:00 -07007430 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Gopichand Nakkala681989c2013-03-06 22:27:48 -08007431 "%s: Add Station is unsucessful", __func__);
Gopichand Nakkala34d1b062013-03-19 15:28:33 -07007432 return -EPERM;
Gopichand Nakkala681989c2013-03-06 22:27:48 -08007433 }
7434
7435 return 0;
Gopichand Nakkala05922802013-03-14 12:23:19 -07007436
7437error:
Atul Mittal115287b2014-07-08 13:26:33 +05307438 wlan_hdd_tdls_set_link_status(pAdapter,
7439 mac,
7440 eTDLS_LINK_IDLE,
7441 eTDLS_LINK_UNSPECIFIED);
Gopichand Nakkala05922802013-03-14 12:23:19 -07007442 return -EPERM;
7443
Gopichand Nakkala681989c2013-03-06 22:27:48 -08007444}
7445#endif
7446
Jeff Johnson295189b2012-06-20 16:38:30 -07007447static int wlan_hdd_change_station(struct wiphy *wiphy,
7448 struct net_device *dev,
7449 u8 *mac,
7450 struct station_parameters *params)
7451{
7452 VOS_STATUS status = VOS_STATUS_SUCCESS;
7453 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( dev );
Gopichand Nakkala29149562013-05-10 21:43:41 +05307454 hdd_context_t *pHddCtx;
7455 hdd_station_ctx_t *pHddStaCtx;
Jeff Johnson295189b2012-06-20 16:38:30 -07007456 v_MACADDR_t STAMacAddress;
Gopichand Nakkalab0856222013-03-12 22:39:05 -07007457#ifdef FEATURE_WLAN_TDLS
Gopichand Nakkala681989c2013-03-06 22:27:48 -08007458 tCsrStaParams StaParams = {0};
Gopichand Nakkala681989c2013-03-06 22:27:48 -08007459 tANI_U8 isBufSta = 0;
Naresh Jayaram3180aa42014-02-12 21:47:26 +05307460 tANI_U8 isOffChannelSupported = 0;
Gopichand Nakkalab0856222013-03-12 22:39:05 -07007461#endif
Jeff Johnsone7245742012-09-05 17:12:55 -07007462 ENTER();
7463
Gopichand Nakkala29149562013-05-10 21:43:41 +05307464 if ((NULL == pAdapter))
7465 {
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +05307466 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
Gopichand Nakkala29149562013-05-10 21:43:41 +05307467 "invalid adapter ");
7468 return -EINVAL;
7469 }
7470
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05307471 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
7472 TRACE_CODE_HDD_CHANGE_STATION,
7473 pAdapter->sessionId, params->listen_interval));
Gopichand Nakkala29149562013-05-10 21:43:41 +05307474 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
7475 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
7476
7477 if ((NULL == pHddCtx) || (NULL == pHddStaCtx))
7478 {
7479 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
7480 "invalid HDD state or HDD station context");
7481 return -EINVAL;
7482 }
7483
7484 if (pHddCtx->isLogpInProgress)
Jeff Johnson04dd8a82012-06-29 20:41:40 -07007485 {
7486 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
7487 "%s:LOGP in Progress. Ignore!!!", __func__);
7488 return -EAGAIN;
7489 }
7490
Jeff Johnson295189b2012-06-20 16:38:30 -07007491 vos_mem_copy(STAMacAddress.bytes, mac, sizeof(v_MACADDR_t));
7492
Gopichand Nakkala681989c2013-03-06 22:27:48 -08007493 if ((pAdapter->device_mode == WLAN_HDD_SOFTAP)
7494 || (pAdapter->device_mode == WLAN_HDD_P2P_GO))
Jeff Johnson295189b2012-06-20 16:38:30 -07007495 {
Gopichand Nakkala681989c2013-03-06 22:27:48 -08007496 if (params->sta_flags_set & BIT(NL80211_STA_FLAG_AUTHORIZED))
Jeff Johnson295189b2012-06-20 16:38:30 -07007497 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307498 status = hdd_softap_change_STA_state( pAdapter, &STAMacAddress,
Jeff Johnson295189b2012-06-20 16:38:30 -07007499 WLANTL_STA_AUTHENTICATED);
7500
Gopichand Nakkala29149562013-05-10 21:43:41 +05307501 if (status != VOS_STATUS_SUCCESS)
7502 {
7503 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
7504 "%s: Not able to change TL state to AUTHENTICATED", __func__);
7505 return -EINVAL;
7506 }
Jeff Johnson295189b2012-06-20 16:38:30 -07007507 }
7508 }
Hoonki Leea6d49be2013-04-05 09:43:25 -07007509 else if ((pAdapter->device_mode == WLAN_HDD_INFRA_STATION)
7510 || (pAdapter->device_mode == WLAN_HDD_P2P_CLIENT)) {
Gopichand Nakkala29149562013-05-10 21:43:41 +05307511#ifdef FEATURE_WLAN_TDLS
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -07007512 if (params->sta_flags_set & BIT(NL80211_STA_FLAG_TDLS_PEER)) {
7513 StaParams.capability = params->capability;
7514 StaParams.uapsd_queues = params->uapsd_queues;
7515 StaParams.max_sp = params->max_sp;
7516
Naresh Jayaram3180aa42014-02-12 21:47:26 +05307517 /* Convert (first channel , number of channels) tuple to
7518 * the total list of channels. This goes with the assumption
7519 * that if the first channel is < 14, then the next channels
7520 * are an incremental of 1 else an incremental of 4 till the number
7521 * of channels.
7522 */
7523 if (0 != params->supported_channels_len) {
7524 int i = 0,j = 0,k = 0, no_of_channels = 0 ;
7525 for ( i = 0 ; i < params->supported_channels_len ; i+=2)
7526 {
7527 int wifi_chan_index;
7528 StaParams.supported_channels[j] = params->supported_channels[i];
7529 wifi_chan_index =
7530 ((StaParams.supported_channels[j] <= HDD_CHANNEL_14 ) ? 1 : 4 );
7531 no_of_channels = params->supported_channels[i+1];
7532 for(k=1; k <= no_of_channels; k++)
7533 {
7534 StaParams.supported_channels[j+1] =
7535 StaParams.supported_channels[j] + wifi_chan_index;
7536 j+=1;
7537 }
7538 }
7539 StaParams.supported_channels_len = j;
7540 }
7541 vos_mem_copy(StaParams.supported_oper_classes,
7542 params->supported_oper_classes,
7543 params->supported_oper_classes_len);
7544 StaParams.supported_oper_classes_len =
7545 params->supported_oper_classes_len;
7546
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -07007547 if (0 != params->ext_capab_len)
7548 vos_mem_copy(StaParams.extn_capability, params->ext_capab,
7549 sizeof(StaParams.extn_capability));
7550
7551 if (NULL != params->ht_capa)
Hoonki Lee66b75f32013-04-16 18:30:07 -07007552 {
7553 StaParams.htcap_present = 1;
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -07007554 vos_mem_copy(&StaParams.HTCap, params->ht_capa, sizeof(tSirHTCap));
Hoonki Lee66b75f32013-04-16 18:30:07 -07007555 }
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -07007556
7557 StaParams.supported_rates_len = params->supported_rates_len;
7558
7559 /* Note : The Maximum sizeof supported_rates sent by the Supplicant is 32.
7560 * The supported_rates array , for all the structures propogating till Add Sta
7561 * to the firmware has to be modified , if the supplicant (ieee80211) is
7562 * modified to send more rates.
7563 */
7564
7565 /* To avoid Data Currption , set to max length to SIR_MAC_MAX_SUPP_RATES
7566 */
7567 if (StaParams.supported_rates_len > SIR_MAC_MAX_SUPP_RATES)
7568 StaParams.supported_rates_len = SIR_MAC_MAX_SUPP_RATES;
7569
7570 if (0 != StaParams.supported_rates_len) {
7571 int i = 0;
7572 vos_mem_copy(StaParams.supported_rates, params->supported_rates,
7573 StaParams.supported_rates_len);
Hoonki Lee5305c3a2013-04-29 23:28:59 -07007574 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -07007575 "Supported Rates with Length %d", StaParams.supported_rates_len);
7576 for (i=0; i < StaParams.supported_rates_len; i++)
Hoonki Lee5305c3a2013-04-29 23:28:59 -07007577 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -07007578 "[%d]: %0x", i, StaParams.supported_rates[i]);
7579 }
7580
7581 if (NULL != params->vht_capa)
Hoonki Lee66b75f32013-04-16 18:30:07 -07007582 {
7583 StaParams.vhtcap_present = 1;
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -07007584 vos_mem_copy(&StaParams.VHTCap, params->vht_capa, sizeof(tSirVHTCap));
Hoonki Lee66b75f32013-04-16 18:30:07 -07007585 }
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -07007586
Gopichand Nakkala681989c2013-03-06 22:27:48 -08007587 if (0 != params->ext_capab_len ) {
7588 /*Define A Macro : TODO Sunil*/
7589 if ((1<<4) & StaParams.extn_capability[3]) {
7590 isBufSta = 1;
7591 }
Naresh Jayaram3180aa42014-02-12 21:47:26 +05307592 /* TDLS Channel Switching Support */
7593 if ((1<<6) & StaParams.extn_capability[3]) {
7594 isOffChannelSupported = 1;
7595 }
Gopichand Nakkala681989c2013-03-06 22:27:48 -08007596 }
Naresh Jayaram3180aa42014-02-12 21:47:26 +05307597 status = wlan_hdd_tdls_set_peer_caps( pAdapter, mac,
7598 &StaParams, isBufSta,
7599 isOffChannelSupported);
7600
Gopichand Nakkala79ff85d2013-05-27 17:05:29 +05307601 if (VOS_STATUS_SUCCESS != status) {
7602 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
7603 "%s: wlan_hdd_tdls_set_peer_caps failed!", __func__);
7604 return -EINVAL;
7605 }
Gopichand Nakkala681989c2013-03-06 22:27:48 -08007606 status = wlan_hdd_tdls_add_station(wiphy, dev, mac, 1, &StaParams);
7607
7608 if (VOS_STATUS_SUCCESS != status) {
7609 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
7610 "%s: sme_ChangeTdlsPeerSta failed!", __func__);
7611 return -EINVAL;
7612 }
7613 }
Gopichand Nakkalab0856222013-03-12 22:39:05 -07007614#endif
Gopichand Nakkala6239acd2013-06-14 14:48:00 +05307615 }
Jeff Johnsone7245742012-09-05 17:12:55 -07007616 EXIT();
Jeff Johnson295189b2012-06-20 16:38:30 -07007617 return status;
7618}
7619
7620/*
Mahesh A Saptasagar1a51bc02014-06-02 18:28:08 +05307621 * FUNCTION: __wlan_hdd_cfg80211_add_key
Jeff Johnson295189b2012-06-20 16:38:30 -07007622 * This function is used to initialize the key information
7623 */
7624#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
Mahesh A Saptasagar1a51bc02014-06-02 18:28:08 +05307625static int __wlan_hdd_cfg80211_add_key( struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -07007626 struct net_device *ndev,
7627 u8 key_index, bool pairwise,
7628 const u8 *mac_addr,
7629 struct key_params *params
7630 )
7631#else
Mahesh A Saptasagar1a51bc02014-06-02 18:28:08 +05307632static int __wlan_hdd_cfg80211_add_key( struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -07007633 struct net_device *ndev,
7634 u8 key_index, const u8 *mac_addr,
7635 struct key_params *params
7636 )
7637#endif
7638{
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -07007639 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( ndev );
Jeff Johnson295189b2012-06-20 16:38:30 -07007640 tCsrRoamSetKey setKey;
7641 u8 groupmacaddr[WNI_CFG_BSSID_LEN] = {0xFF,0xFF,0xFF,0xFF,0xFF,0xFF};
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05307642 int status;
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -07007643 v_U32_t roamId= 0xFF;
7644 v_CONTEXT_t pVosContext = (WLAN_HDD_GET_CTX(pAdapter))->pvosContext;
Jeff Johnson295189b2012-06-20 16:38:30 -07007645 hdd_hostapd_state_t *pHostapdState;
7646 VOS_STATUS vos_status;
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -07007647 eHalStatus halStatus;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05307648 hdd_context_t *pHddCtx;
Jeff Johnson295189b2012-06-20 16:38:30 -07007649
7650 ENTER();
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +05307651
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05307652 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
7653 TRACE_CODE_HDD_CFG80211_ADD_KEY,
7654 pAdapter->sessionId, params->key_len));
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05307655 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
7656 status = wlan_hdd_validate_context(pHddCtx);
7657
7658 if (0 != status)
Jeff Johnson04dd8a82012-06-29 20:41:40 -07007659 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05307660 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
7661 "%s: HDD context is not valid", __func__);
7662 return status;
Jeff Johnson04dd8a82012-06-29 20:41:40 -07007663 }
7664
Sushant Kaushik8bc7df22014-04-09 17:55:29 +05307665 hddLog(VOS_TRACE_LEVEL_INFO, "%s: device_mode = %s (%d)",
7666 __func__, hdd_device_modetoString(pAdapter->device_mode),
7667 pAdapter->device_mode);
Jeff Johnson295189b2012-06-20 16:38:30 -07007668
7669 if (CSR_MAX_NUM_KEY <= key_index)
7670 {
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -07007671 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Invalid key index %d", __func__,
Jeff Johnson295189b2012-06-20 16:38:30 -07007672 key_index);
7673
7674 return -EINVAL;
7675 }
7676
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -07007677 if (CSR_MAX_KEY_LEN < params->key_len)
7678 {
7679 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Invalid key length %d", __func__,
7680 params->key_len);
7681
7682 return -EINVAL;
7683 }
7684
7685 hddLog(VOS_TRACE_LEVEL_INFO,
7686 "%s: called with key index = %d & key length %d",
7687 __func__, key_index, params->key_len);
Jeff Johnson295189b2012-06-20 16:38:30 -07007688
7689 /*extract key idx, key len and key*/
7690 vos_mem_zero(&setKey,sizeof(tCsrRoamSetKey));
7691 setKey.keyId = key_index;
7692 setKey.keyLength = params->key_len;
7693 vos_mem_copy(&setKey.Key[0],params->key, params->key_len);
7694
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -07007695 switch (params->cipher)
Jeff Johnson295189b2012-06-20 16:38:30 -07007696 {
7697 case WLAN_CIPHER_SUITE_WEP40:
7698 setKey.encType = eCSR_ENCRYPT_TYPE_WEP40_STATICKEY;
7699 break;
7700
7701 case WLAN_CIPHER_SUITE_WEP104:
7702 setKey.encType = eCSR_ENCRYPT_TYPE_WEP104_STATICKEY;
7703 break;
7704
7705 case WLAN_CIPHER_SUITE_TKIP:
7706 {
7707 u8 *pKey = &setKey.Key[0];
7708 setKey.encType = eCSR_ENCRYPT_TYPE_TKIP;
7709
7710 vos_mem_zero(pKey, CSR_MAX_KEY_LEN);
7711
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -07007712 /*Supplicant sends the 32bytes key in this order
Jeff Johnson295189b2012-06-20 16:38:30 -07007713
7714 |--------------|----------|----------|
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -07007715 | Tk1 |TX-MIC | RX Mic |
Jeff Johnson295189b2012-06-20 16:38:30 -07007716 |--------------|----------|----------|
7717 <---16bytes---><--8bytes--><--8bytes-->
7718
7719 */
7720 /*Sme expects the 32 bytes key to be in the below order
7721
7722 |--------------|----------|----------|
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -07007723 | Tk1 |RX-MIC | TX Mic |
Jeff Johnson295189b2012-06-20 16:38:30 -07007724 |--------------|----------|----------|
7725 <---16bytes---><--8bytes--><--8bytes-->
7726 */
7727 /* Copy the Temporal Key 1 (TK1) */
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -07007728 vos_mem_copy(pKey, params->key, 16);
Jeff Johnson295189b2012-06-20 16:38:30 -07007729
7730 /*Copy the rx mic first*/
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -07007731 vos_mem_copy(&pKey[16], &params->key[24], 8);
Jeff Johnson295189b2012-06-20 16:38:30 -07007732
7733 /*Copy the tx mic */
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -07007734 vos_mem_copy(&pKey[24], &params->key[16], 8);
Jeff Johnson295189b2012-06-20 16:38:30 -07007735
7736
7737 break;
7738 }
7739
7740 case WLAN_CIPHER_SUITE_CCMP:
7741 setKey.encType = eCSR_ENCRYPT_TYPE_AES;
7742 break;
7743
7744#ifdef FEATURE_WLAN_WAPI
7745 case WLAN_CIPHER_SUITE_SMS4:
7746 {
7747 vos_mem_zero(&setKey,sizeof(tCsrRoamSetKey));
7748 wlan_hdd_cfg80211_set_key_wapi(pAdapter, key_index, mac_addr,
7749 params->key, params->key_len);
7750 return 0;
7751 }
7752#endif
Chet Lanctot186b5732013-03-18 10:26:30 -07007753
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08007754#ifdef FEATURE_WLAN_ESE
Jeff Johnson295189b2012-06-20 16:38:30 -07007755 case WLAN_CIPHER_SUITE_KRK:
7756 setKey.encType = eCSR_ENCRYPT_TYPE_KRK;
7757 break;
7758#endif
Chet Lanctot186b5732013-03-18 10:26:30 -07007759
7760#ifdef WLAN_FEATURE_11W
7761 case WLAN_CIPHER_SUITE_AES_CMAC:
7762 setKey.encType = eCSR_ENCRYPT_TYPE_AES_CMAC;
Chet Lanctot3b5158a2013-03-31 16:45:21 -07007763 break;
Chet Lanctot186b5732013-03-18 10:26:30 -07007764#endif
7765
Jeff Johnson295189b2012-06-20 16:38:30 -07007766 default:
Jeff Johnson0299d0a2013-10-30 12:37:43 -07007767 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: unsupported cipher type %u",
Jeff Johnson295189b2012-06-20 16:38:30 -07007768 __func__, params->cipher);
7769 return -EOPNOTSUPP;
7770 }
7771
7772 hddLog(VOS_TRACE_LEVEL_INFO_MED, "%s: encryption type %d",
7773 __func__, setKey.encType);
7774
Shailender Karmuchi642e9812013-05-30 14:34:49 -07007775 if (
Jeff Johnson295189b2012-06-20 16:38:30 -07007776#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
7777 (!pairwise)
7778#else
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -07007779 (!mac_addr || is_broadcast_ether_addr(mac_addr))
Jeff Johnson295189b2012-06-20 16:38:30 -07007780#endif
Shailender Karmuchi642e9812013-05-30 14:34:49 -07007781 )
7782 {
7783 /* set group key*/
7784 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
7785 "%s- %d: setting Broadcast key",
7786 __func__, __LINE__);
7787 setKey.keyDirection = eSIR_RX_ONLY;
7788 vos_mem_copy(setKey.peerMac,groupmacaddr,WNI_CFG_BSSID_LEN);
7789 }
7790 else
7791 {
7792 /* set pairwise key*/
7793 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
7794 "%s- %d: setting pairwise key",
7795 __func__, __LINE__);
7796 setKey.keyDirection = eSIR_TX_RX;
7797 vos_mem_copy(setKey.peerMac, mac_addr,WNI_CFG_BSSID_LEN);
7798 }
7799 if ((WLAN_HDD_IBSS == pAdapter->device_mode) && !pairwise)
7800 {
7801 setKey.keyDirection = eSIR_TX_RX;
7802 /*Set the group key*/
7803 status = sme_RoamSetKey( WLAN_HDD_GET_HAL_CTX(pAdapter),
7804 pAdapter->sessionId, &setKey, &roamId );
Jeff Johnson295189b2012-06-20 16:38:30 -07007805
Shailender Karmuchi642e9812013-05-30 14:34:49 -07007806 if ( 0 != status )
7807 {
7808 hddLog(VOS_TRACE_LEVEL_ERROR,
7809 "%s: sme_RoamSetKey failed, returned %d", __func__, status);
7810 return -EINVAL;
7811 }
7812 /*Save the keys here and call sme_RoamSetKey for setting
7813 the PTK after peer joins the IBSS network*/
7814 vos_mem_copy(&pAdapter->sessionCtx.station.ibss_enc_key,
7815 &setKey, sizeof(tCsrRoamSetKey));
7816 return status;
7817 }
Gopichand Nakkala29149562013-05-10 21:43:41 +05307818 if ((pAdapter->device_mode == WLAN_HDD_SOFTAP) ||
7819 (pAdapter->device_mode == WLAN_HDD_P2P_GO))
7820 {
Jeff Johnson295189b2012-06-20 16:38:30 -07007821 pHostapdState = WLAN_HDD_GET_HOSTAP_STATE_PTR(pAdapter);
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -07007822 if( pHostapdState->bssState == BSS_START )
7823 {
c_hpothu7c55da62014-01-23 18:34:02 +05307824 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
7825 vos_status = wlan_hdd_check_ula_done(pAdapter);
7826
7827 if ( vos_status != VOS_STATUS_SUCCESS )
7828 {
7829 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
7830 "[%4d] wlan_hdd_check_ula_done returned ERROR status= %d",
7831 __LINE__, vos_status );
7832
7833 pHddStaCtx->roam_info.roamingState = HDD_ROAM_STATE_NONE;
7834
7835 return -EINVAL;
7836 }
7837
Jeff Johnson295189b2012-06-20 16:38:30 -07007838 status = WLANSAP_SetKeySta( pVosContext, &setKey);
7839
7840 if ( status != eHAL_STATUS_SUCCESS )
7841 {
7842 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
7843 "[%4d] WLANSAP_SetKeySta returned ERROR status= %d",
7844 __LINE__, status );
7845 }
7846 }
7847
7848 /* Saving WEP keys */
7849 else if( eCSR_ENCRYPT_TYPE_WEP40_STATICKEY == setKey.encType ||
7850 eCSR_ENCRYPT_TYPE_WEP104_STATICKEY == setKey.encType )
7851 {
7852 //Save the wep key in ap context. Issue setkey after the BSS is started.
7853 hdd_ap_ctx_t *pAPCtx = WLAN_HDD_GET_AP_CTX_PTR(pAdapter);
7854 vos_mem_copy(&pAPCtx->wepKey[key_index], &setKey, sizeof(tCsrRoamSetKey));
7855 }
7856 else
7857 {
7858 //Save the key in ap context. Issue setkey after the BSS is started.
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -07007859 hdd_ap_ctx_t *pAPCtx = WLAN_HDD_GET_AP_CTX_PTR(pAdapter);
Jeff Johnson295189b2012-06-20 16:38:30 -07007860 vos_mem_copy(&pAPCtx->groupKey, &setKey, sizeof(tCsrRoamSetKey));
7861 }
7862 }
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -07007863 else if ( (pAdapter->device_mode == WLAN_HDD_INFRA_STATION) ||
7864 (pAdapter->device_mode == WLAN_HDD_P2P_CLIENT) )
Jeff Johnson295189b2012-06-20 16:38:30 -07007865 {
7866 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
7867 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
7868
Gopichand Nakkala3d295922013-05-07 16:19:14 +05307869#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
7870 if (!pairwise)
7871#else
7872 if (!mac_addr || is_broadcast_ether_addr(mac_addr))
7873#endif
7874 {
7875 /* set group key*/
7876 if (pHddStaCtx->roam_info.deferKeyComplete)
7877 {
7878 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
7879 "%s- %d: Perform Set key Complete",
7880 __func__, __LINE__);
7881 hdd_PerformRoamSetKeyComplete(pAdapter);
7882 }
7883 }
7884
Jeff Johnson295189b2012-06-20 16:38:30 -07007885 pWextState->roamProfile.Keys.KeyLength[key_index] = (u8)params->key_len;
7886
Venkata Prathyusha Kuntupalliee2ce712013-01-17 14:09:24 -08007887 pWextState->roamProfile.Keys.defaultIndex = key_index;
7888
7889
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -07007890 vos_mem_copy(&pWextState->roamProfile.Keys.KeyMaterial[key_index][0],
Jeff Johnson295189b2012-06-20 16:38:30 -07007891 params->key, params->key_len);
7892
Gopichand Nakkala3d295922013-05-07 16:19:14 +05307893
Jeff Johnson295189b2012-06-20 16:38:30 -07007894 pHddStaCtx->roam_info.roamingState = HDD_ROAM_STATE_SETTING_KEY;
7895
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307896 hddLog(VOS_TRACE_LEVEL_INFO_MED,
Jeff Johnson295189b2012-06-20 16:38:30 -07007897 "%s: set key for peerMac %2x:%2x:%2x:%2x:%2x:%2x, direction %d",
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307898 __func__, setKey.peerMac[0], setKey.peerMac[1],
7899 setKey.peerMac[2], setKey.peerMac[3],
7900 setKey.peerMac[4], setKey.peerMac[5],
Jeff Johnson295189b2012-06-20 16:38:30 -07007901 setKey.keyDirection);
7902
7903 vos_status = wlan_hdd_check_ula_done(pAdapter);
7904
7905 if ( vos_status != VOS_STATUS_SUCCESS )
7906 {
7907 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
7908 "[%4d] wlan_hdd_check_ula_done returned ERROR status= %d",
7909 __LINE__, vos_status );
7910
7911 pHddStaCtx->roam_info.roamingState = HDD_ROAM_STATE_NONE;
7912
7913 return -EINVAL;
7914
7915 }
7916
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -07007917#ifdef WLAN_FEATURE_VOWIFI_11R
Gopichand Nakkala3d295922013-05-07 16:19:14 +05307918 /* The supplicant may attempt to set the PTK once pre-authentication
7919 is done. Save the key in the UMAC and include it in the ADD BSS
7920 request */
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -07007921 halStatus = sme_FTUpdateKey( WLAN_HDD_GET_HAL_CTX(pAdapter), &setKey);
Gopichand Nakkala3d295922013-05-07 16:19:14 +05307922 if ( halStatus == eHAL_STATUS_FT_PREAUTH_KEY_SUCCESS )
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -07007923 {
Gopichand Nakkala3d295922013-05-07 16:19:14 +05307924 hddLog(VOS_TRACE_LEVEL_INFO_MED,
7925 "%s: Update PreAuth Key success", __func__);
7926 return 0;
7927 }
7928 else if ( halStatus == eHAL_STATUS_FT_PREAUTH_KEY_FAILED )
7929 {
7930 hddLog(VOS_TRACE_LEVEL_ERROR,
7931 "%s: Update PreAuth Key failed", __func__);
Gopichand Nakkalad7d13652013-02-15 01:48:00 +05307932 return -EINVAL;
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -07007933 }
7934#endif /* WLAN_FEATURE_VOWIFI_11R */
Jeff Johnson295189b2012-06-20 16:38:30 -07007935
7936 /* issue set key request to SME*/
7937 status = sme_RoamSetKey( WLAN_HDD_GET_HAL_CTX(pAdapter),
7938 pAdapter->sessionId, &setKey, &roamId );
7939
7940 if ( 0 != status )
7941 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307942 hddLog(VOS_TRACE_LEVEL_ERROR,
Jeff Johnson295189b2012-06-20 16:38:30 -07007943 "%s: sme_RoamSetKey failed, returned %d", __func__, status);
7944 pHddStaCtx->roam_info.roamingState = HDD_ROAM_STATE_NONE;
7945 return -EINVAL;
7946 }
7947
7948
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307949 /* in case of IBSS as there was no information available about WEP keys during
7950 * IBSS join, group key intialized with NULL key, so re-initialize group key
Jeff Johnson295189b2012-06-20 16:38:30 -07007951 * with correct value*/
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307952 if ( (eCSR_BSS_TYPE_START_IBSS == pWextState->roamProfile.BSSType) &&
7953 !( ( IW_AUTH_KEY_MGMT_802_1X
7954 == (pWextState->authKeyMgmt & IW_AUTH_KEY_MGMT_802_1X))
Jeff Johnson295189b2012-06-20 16:38:30 -07007955 && (eCSR_AUTH_TYPE_OPEN_SYSTEM == pHddStaCtx->conn_info.authType)
7956 )
7957 &&
7958 ( (WLAN_CIPHER_SUITE_WEP40 == params->cipher)
7959 || (WLAN_CIPHER_SUITE_WEP104 == params->cipher)
7960 )
7961 )
7962 {
7963 setKey.keyDirection = eSIR_RX_ONLY;
7964 vos_mem_copy(setKey.peerMac,groupmacaddr,WNI_CFG_BSSID_LEN);
7965
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307966 hddLog(VOS_TRACE_LEVEL_INFO_MED,
Jeff Johnson295189b2012-06-20 16:38:30 -07007967 "%s: set key peerMac %2x:%2x:%2x:%2x:%2x:%2x, direction %d",
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307968 __func__, setKey.peerMac[0], setKey.peerMac[1],
7969 setKey.peerMac[2], setKey.peerMac[3],
7970 setKey.peerMac[4], setKey.peerMac[5],
Jeff Johnson295189b2012-06-20 16:38:30 -07007971 setKey.keyDirection);
7972
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307973 status = sme_RoamSetKey( WLAN_HDD_GET_HAL_CTX(pAdapter),
Jeff Johnson295189b2012-06-20 16:38:30 -07007974 pAdapter->sessionId, &setKey, &roamId );
7975
7976 if ( 0 != status )
7977 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307978 hddLog(VOS_TRACE_LEVEL_ERROR,
7979 "%s: sme_RoamSetKey failed for group key (IBSS), returned %d",
Jeff Johnson295189b2012-06-20 16:38:30 -07007980 __func__, status);
7981 pHddStaCtx->roam_info.roamingState = HDD_ROAM_STATE_NONE;
7982 return -EINVAL;
7983 }
7984 }
7985 }
7986
7987 return 0;
7988}
7989
Mahesh A Saptasagar1a51bc02014-06-02 18:28:08 +05307990#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
7991static int wlan_hdd_cfg80211_add_key( struct wiphy *wiphy,
7992 struct net_device *ndev,
7993 u8 key_index, bool pairwise,
7994 const u8 *mac_addr,
7995 struct key_params *params
7996 )
7997#else
7998static int wlan_hdd_cfg80211_add_key( struct wiphy *wiphy,
7999 struct net_device *ndev,
8000 u8 key_index, const u8 *mac_addr,
8001 struct key_params *params
8002 )
8003#endif
8004{
8005 int ret;
8006 vos_ssr_protect(__func__);
8007#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
8008 ret = __wlan_hdd_cfg80211_add_key(wiphy, ndev, key_index, pairwise,
8009 mac_addr, params);
8010#else
8011 ret = __wlan_hdd_cfg80211_add_key(wiphy, ndev, key_index, mac_addr,
8012 params);
8013#endif
8014 vos_ssr_unprotect(__func__);
8015
8016 return ret;
8017}
8018
Jeff Johnson295189b2012-06-20 16:38:30 -07008019/*
Mahesh A Saptasagar1a51bc02014-06-02 18:28:08 +05308020 * FUNCTION: __wlan_hdd_cfg80211_get_key
Jeff Johnson295189b2012-06-20 16:38:30 -07008021 * This function is used to get the key information
8022 */
8023#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
Mahesh A Saptasagar1a51bc02014-06-02 18:28:08 +05308024static int __wlan_hdd_cfg80211_get_key(
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308025 struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -07008026 struct net_device *ndev,
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308027 u8 key_index, bool pairwise,
Jeff Johnson295189b2012-06-20 16:38:30 -07008028 const u8 *mac_addr, void *cookie,
8029 void (*callback)(void *cookie, struct key_params*)
8030 )
8031#else
Mahesh A Saptasagar1a51bc02014-06-02 18:28:08 +05308032static int __wlan_hdd_cfg80211_get_key(
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308033 struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -07008034 struct net_device *ndev,
8035 u8 key_index, const u8 *mac_addr, void *cookie,
8036 void (*callback)(void *cookie, struct key_params*)
8037 )
8038#endif
8039{
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308040 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( ndev );
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +05308041 hdd_wext_state_t *pWextState= WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
8042 tCsrRoamProfile *pRoamProfile = &(pWextState->roamProfile);
Jeff Johnson295189b2012-06-20 16:38:30 -07008043 struct key_params params;
8044
8045 ENTER();
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308046
Sushant Kaushik8bc7df22014-04-09 17:55:29 +05308047 hddLog(VOS_TRACE_LEVEL_INFO, "%s: device_mode = %s (%d)",
8048 __func__, hdd_device_modetoString(pAdapter->device_mode),
8049 pAdapter->device_mode);
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +05308050
Jeff Johnson295189b2012-06-20 16:38:30 -07008051 memset(&params, 0, sizeof(params));
8052
8053 if (CSR_MAX_NUM_KEY <= key_index)
8054 {
c_hpothu6ff1c3c2013-10-01 19:01:57 +05308055 hddLog(VOS_TRACE_LEVEL_ERROR, FL("invalid key index %d"), key_index);
Jeff Johnson295189b2012-06-20 16:38:30 -07008056 return -EINVAL;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308057 }
Jeff Johnson295189b2012-06-20 16:38:30 -07008058
8059 switch(pRoamProfile->EncryptionType.encryptionType[0])
8060 {
8061 case eCSR_ENCRYPT_TYPE_NONE:
8062 params.cipher = IW_AUTH_CIPHER_NONE;
8063 break;
8064
8065 case eCSR_ENCRYPT_TYPE_WEP40_STATICKEY:
8066 case eCSR_ENCRYPT_TYPE_WEP40:
8067 params.cipher = WLAN_CIPHER_SUITE_WEP40;
8068 break;
8069
8070 case eCSR_ENCRYPT_TYPE_WEP104_STATICKEY:
8071 case eCSR_ENCRYPT_TYPE_WEP104:
8072 params.cipher = WLAN_CIPHER_SUITE_WEP104;
8073 break;
8074
8075 case eCSR_ENCRYPT_TYPE_TKIP:
8076 params.cipher = WLAN_CIPHER_SUITE_TKIP;
8077 break;
8078
8079 case eCSR_ENCRYPT_TYPE_AES:
8080 params.cipher = WLAN_CIPHER_SUITE_AES_CMAC;
8081 break;
8082
8083 default:
8084 params.cipher = IW_AUTH_CIPHER_NONE;
8085 break;
8086 }
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +05308087
c_hpothuaaf19692014-05-17 17:01:48 +05308088 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
8089 TRACE_CODE_HDD_CFG80211_GET_KEY,
8090 pAdapter->sessionId, params.cipher));
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +05308091
Jeff Johnson295189b2012-06-20 16:38:30 -07008092 params.key_len = pRoamProfile->Keys.KeyLength[key_index];
8093 params.seq_len = 0;
8094 params.seq = NULL;
8095 params.key = &pRoamProfile->Keys.KeyMaterial[key_index][0];
8096 callback(cookie, &params);
8097 return 0;
8098}
8099
Mahesh A Saptasagar1a51bc02014-06-02 18:28:08 +05308100#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
8101static int wlan_hdd_cfg80211_get_key(
8102 struct wiphy *wiphy,
8103 struct net_device *ndev,
8104 u8 key_index, bool pairwise,
8105 const u8 *mac_addr, void *cookie,
8106 void (*callback)(void *cookie, struct key_params*)
8107 )
8108#else
8109static int wlan_hdd_cfg80211_get_key(
8110 struct wiphy *wiphy,
8111 struct net_device *ndev,
8112 u8 key_index, const u8 *mac_addr, void *cookie,
8113 void (*callback)(void *cookie, struct key_params*)
8114 )
8115#endif
8116{
8117 int ret;
8118
8119 vos_ssr_protect(__func__);
8120#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
8121 ret = __wlan_hdd_cfg80211_get_key(wiphy, ndev, key_index, pairwise,
8122 mac_addr, cookie, callback);
8123#else
8124 ret = __wlan_hdd_cfg80211_get_key(wiphy, ndev, key_index, mac_addr,
8125 callback);
8126#endif
8127 vos_ssr_unprotect(__func__);
8128
8129 return ret;
8130}
8131
Jeff Johnson295189b2012-06-20 16:38:30 -07008132/*
8133 * FUNCTION: wlan_hdd_cfg80211_del_key
8134 * This function is used to delete the key information
8135 */
8136#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308137static int wlan_hdd_cfg80211_del_key( struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -07008138 struct net_device *ndev,
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308139 u8 key_index,
8140 bool pairwise,
Jeff Johnson295189b2012-06-20 16:38:30 -07008141 const u8 *mac_addr
8142 )
8143#else
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308144static int wlan_hdd_cfg80211_del_key( struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -07008145 struct net_device *ndev,
8146 u8 key_index,
8147 const u8 *mac_addr
8148 )
8149#endif
8150{
8151 int status = 0;
8152
8153 //This code needs to be revisited. There is sme_removeKey API, we should
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308154 //plan to use that. After the change to use correct index in setkey,
Jeff Johnson295189b2012-06-20 16:38:30 -07008155 //it is observed that this is invalidating peer
8156 //key index whenever re-key is done. This is affecting data link.
8157 //It should be ok to ignore del_key.
8158#if 0
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308159 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( ndev );
8160 v_CONTEXT_t pVosContext = (WLAN_HDD_GET_CTX(pAdapter))->pvosContext;
Jeff Johnson295189b2012-06-20 16:38:30 -07008161 u8 groupmacaddr[WNI_CFG_BSSID_LEN] = {0xFF,0xFF,0xFF,0xFF,0xFF,0xFF};
8162 tCsrRoamSetKey setKey;
8163 v_U32_t roamId= 0xFF;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308164
Jeff Johnson295189b2012-06-20 16:38:30 -07008165 ENTER();
8166
8167 hddLog(VOS_TRACE_LEVEL_INFO_HIGH, "%s: device_mode = %d\n",
8168 __func__,pAdapter->device_mode);
8169
8170 if (CSR_MAX_NUM_KEY <= key_index)
8171 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308172 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Invalid key index %d", __func__,
Jeff Johnson295189b2012-06-20 16:38:30 -07008173 key_index);
8174
8175 return -EINVAL;
8176 }
8177
8178 vos_mem_zero(&setKey,sizeof(tCsrRoamSetKey));
8179 setKey.keyId = key_index;
8180
8181 if (mac_addr)
8182 vos_mem_copy(setKey.peerMac, mac_addr,WNI_CFG_BSSID_LEN);
8183 else
8184 vos_mem_copy(setKey.peerMac, groupmacaddr, WNI_CFG_BSSID_LEN);
8185
8186 setKey.encType = eCSR_ENCRYPT_TYPE_NONE;
8187
8188 if ((pAdapter->device_mode == WLAN_HDD_SOFTAP)
Jeff Johnson295189b2012-06-20 16:38:30 -07008189 || (pAdapter->device_mode == WLAN_HDD_P2P_GO)
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308190 )
8191 {
8192
8193 hdd_hostapd_state_t *pHostapdState =
Jeff Johnson295189b2012-06-20 16:38:30 -07008194 WLAN_HDD_GET_HOSTAP_STATE_PTR(pAdapter);
8195 if( pHostapdState->bssState == BSS_START)
8196 {
8197 status = WLANSAP_SetKeySta( pVosContext, &setKey);
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308198
Jeff Johnson295189b2012-06-20 16:38:30 -07008199 if ( status != eHAL_STATUS_SUCCESS )
8200 {
8201 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
8202 "[%4d] WLANSAP_SetKeySta returned ERROR status= %d",
8203 __LINE__, status );
8204 }
8205 }
8206 }
8207 else if ( (pAdapter->device_mode == WLAN_HDD_INFRA_STATION)
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308208 || (pAdapter->device_mode == WLAN_HDD_P2P_CLIENT)
Jeff Johnson295189b2012-06-20 16:38:30 -07008209 )
8210 {
8211 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
8212
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308213 pHddStaCtx->roam_info.roamingState = HDD_ROAM_STATE_SETTING_KEY;
8214
8215 hddLog(VOS_TRACE_LEVEL_INFO_MED,
Jeff Johnson295189b2012-06-20 16:38:30 -07008216 "%s: delete key for peerMac %2x:%2x:%2x:%2x:%2x:%2x",
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308217 __func__, setKey.peerMac[0], setKey.peerMac[1],
8218 setKey.peerMac[2], setKey.peerMac[3],
Jeff Johnson295189b2012-06-20 16:38:30 -07008219 setKey.peerMac[4], setKey.peerMac[5]);
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308220 if(pAdapter->sessionCtx.station.conn_info.connState ==
8221 eConnectionState_Associated)
Jeff Johnson295189b2012-06-20 16:38:30 -07008222 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308223 status = sme_RoamSetKey( WLAN_HDD_GET_HAL_CTX(pAdapter),
Jeff Johnson295189b2012-06-20 16:38:30 -07008224 pAdapter->sessionId, &setKey, &roamId );
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308225
Jeff Johnson295189b2012-06-20 16:38:30 -07008226 if ( 0 != status )
8227 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308228 hddLog(VOS_TRACE_LEVEL_ERROR,
Jeff Johnson295189b2012-06-20 16:38:30 -07008229 "%s: sme_RoamSetKey failure, returned %d",
8230 __func__, status);
8231 pHddStaCtx->roam_info.roamingState = HDD_ROAM_STATE_NONE;
8232 return -EINVAL;
8233 }
8234 }
8235 }
8236#endif
Jeff Johnsone7245742012-09-05 17:12:55 -07008237 EXIT();
Jeff Johnson295189b2012-06-20 16:38:30 -07008238 return status;
8239}
8240
8241/*
Mahesh A Saptasagar1a51bc02014-06-02 18:28:08 +05308242 * FUNCTION: __wlan_hdd_cfg80211_set_default_key
Jeff Johnson295189b2012-06-20 16:38:30 -07008243 * This function is used to set the default tx key index
8244 */
8245#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
Mahesh A Saptasagar1a51bc02014-06-02 18:28:08 +05308246static int __wlan_hdd_cfg80211_set_default_key( struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -07008247 struct net_device *ndev,
8248 u8 key_index,
8249 bool unicast, bool multicast)
8250#else
Mahesh A Saptasagar1a51bc02014-06-02 18:28:08 +05308251static int __wlan_hdd_cfg80211_set_default_key( struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -07008252 struct net_device *ndev,
8253 u8 key_index)
8254#endif
8255{
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308256 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( ndev );
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05308257 int status;
Gopichand Nakkala29149562013-05-10 21:43:41 +05308258 hdd_wext_state_t *pWextState;
8259 hdd_station_ctx_t *pHddStaCtx;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05308260 hdd_context_t *pHddCtx;
Jeff Johnson295189b2012-06-20 16:38:30 -07008261
8262 ENTER();
8263
Gopichand Nakkala29149562013-05-10 21:43:41 +05308264 if ((NULL == pAdapter))
8265 {
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +05308266 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
Gopichand Nakkala29149562013-05-10 21:43:41 +05308267 "invalid adapter");
8268 return -EINVAL;
8269 }
8270
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05308271 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
8272 TRACE_CODE_HDD_CFG80211_SET_DEFAULT_KEY,
8273 pAdapter->sessionId, key_index));
8274
Gopichand Nakkala29149562013-05-10 21:43:41 +05308275 pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
8276 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
8277
8278 if ((NULL == pWextState) || (NULL == pHddStaCtx))
8279 {
8280 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
8281 "invalid Wext state or HDD context");
8282 return -EINVAL;
8283 }
8284
Arif Hussain6d2a3322013-11-17 19:50:10 -08008285 hddLog(VOS_TRACE_LEVEL_INFO, "%s: device_mode = %d key_index = %d",
Jeff Johnson295189b2012-06-20 16:38:30 -07008286 __func__,pAdapter->device_mode, key_index);
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308287
Jeff Johnson295189b2012-06-20 16:38:30 -07008288 if (CSR_MAX_NUM_KEY <= key_index)
8289 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308290 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Invalid key index %d", __func__,
Jeff Johnson295189b2012-06-20 16:38:30 -07008291 key_index);
8292
8293 return -EINVAL;
8294 }
8295
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05308296 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
8297 status = wlan_hdd_validate_context(pHddCtx);
8298
8299 if (0 != status)
Jeff Johnson04dd8a82012-06-29 20:41:40 -07008300 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05308301 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
8302 "%s: HDD context is not valid", __func__);
8303 return status;
Jeff Johnson04dd8a82012-06-29 20:41:40 -07008304 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308305
Jeff Johnson295189b2012-06-20 16:38:30 -07008306 if ((pAdapter->device_mode == WLAN_HDD_INFRA_STATION)
Jeff Johnson295189b2012-06-20 16:38:30 -07008307 || (pAdapter->device_mode == WLAN_HDD_P2P_CLIENT)
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308308 )
Jeff Johnson295189b2012-06-20 16:38:30 -07008309 {
Gopichand Nakkala29149562013-05-10 21:43:41 +05308310 if ( (eCSR_ENCRYPT_TYPE_TKIP !=
Arif Hussain6943f522013-11-04 20:10:10 -08008311 pHddStaCtx->conn_info.ucEncryptionType) &&
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308312 (eCSR_ENCRYPT_TYPE_AES !=
Arif Hussain6943f522013-11-04 20:10:10 -08008313 pHddStaCtx->conn_info.ucEncryptionType)
Jeff Johnson295189b2012-06-20 16:38:30 -07008314 )
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308315 {
8316 /* if default key index is not same as previous one,
Jeff Johnson295189b2012-06-20 16:38:30 -07008317 * then update the default key index */
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308318
Jeff Johnson295189b2012-06-20 16:38:30 -07008319 tCsrRoamSetKey setKey;
8320 v_U32_t roamId= 0xFF;
8321 tCsrKeys *Keys = &pWextState->roamProfile.Keys;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308322
8323 hddLog(VOS_TRACE_LEVEL_INFO_HIGH, "%s: default tx key index %d",
Jeff Johnson295189b2012-06-20 16:38:30 -07008324 __func__, key_index);
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308325
Jeff Johnson295189b2012-06-20 16:38:30 -07008326 Keys->defaultIndex = (u8)key_index;
8327 vos_mem_zero(&setKey,sizeof(tCsrRoamSetKey));
8328 setKey.keyId = key_index;
8329 setKey.keyLength = Keys->KeyLength[key_index];
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308330
8331 vos_mem_copy(&setKey.Key[0],
8332 &Keys->KeyMaterial[key_index][0],
Jeff Johnson295189b2012-06-20 16:38:30 -07008333 Keys->KeyLength[key_index]);
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308334
Gopichand Nakkala29149562013-05-10 21:43:41 +05308335 setKey.keyDirection = eSIR_TX_RX;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308336
8337 vos_mem_copy(setKey.peerMac,
Jeff Johnson295189b2012-06-20 16:38:30 -07008338 &pHddStaCtx->conn_info.bssId[0],
8339 WNI_CFG_BSSID_LEN);
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308340
Gopichand Nakkala29149562013-05-10 21:43:41 +05308341 if (Keys->KeyLength[key_index] == CSR_WEP40_KEY_LEN &&
8342 pWextState->roamProfile.EncryptionType.encryptionType[0] ==
8343 eCSR_ENCRYPT_TYPE_WEP104)
8344 {
8345 /*In the case of dynamic wep supplicant hardcodes DWEP type to eCSR_ENCRYPT_TYPE_WEP104
8346 even though ap is configured for WEP-40 encryption. In this canse the key length
8347 is 5 but the encryption type is 104 hence checking the key langht(5) and encryption
8348 type(104) and switching encryption type to 40*/
8349 pWextState->roamProfile.EncryptionType.encryptionType[0] =
8350 eCSR_ENCRYPT_TYPE_WEP40;
8351 pWextState->roamProfile.mcEncryptionType.encryptionType[0] =
8352 eCSR_ENCRYPT_TYPE_WEP40;
8353 }
8354
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308355 setKey.encType =
Jeff Johnson295189b2012-06-20 16:38:30 -07008356 pWextState->roamProfile.EncryptionType.encryptionType[0];
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308357
Jeff Johnson295189b2012-06-20 16:38:30 -07008358 /* issue set key request */
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308359 status = sme_RoamSetKey( WLAN_HDD_GET_HAL_CTX(pAdapter),
Jeff Johnson295189b2012-06-20 16:38:30 -07008360 pAdapter->sessionId, &setKey, &roamId );
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308361
Jeff Johnson295189b2012-06-20 16:38:30 -07008362 if ( 0 != status )
8363 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308364 hddLog(VOS_TRACE_LEVEL_ERROR,
8365 "%s: sme_RoamSetKey failed, returned %d", __func__,
Jeff Johnson295189b2012-06-20 16:38:30 -07008366 status);
8367 return -EINVAL;
8368 }
8369 }
8370 }
8371
8372 /* In SoftAp mode setting key direction for default mode */
8373 else if ( WLAN_HDD_SOFTAP == pAdapter->device_mode )
8374 {
8375 if ( (eCSR_ENCRYPT_TYPE_TKIP !=
8376 pWextState->roamProfile.EncryptionType.encryptionType[0]) &&
8377 (eCSR_ENCRYPT_TYPE_AES !=
8378 pWextState->roamProfile.EncryptionType.encryptionType[0])
8379 )
8380 {
8381 /* Saving key direction for default key index to TX default */
8382 hdd_ap_ctx_t *pAPCtx = WLAN_HDD_GET_AP_CTX_PTR(pAdapter);
8383 pAPCtx->wepKey[key_index].keyDirection = eSIR_TX_DEFAULT;
8384 }
8385 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308386
Jeff Johnson295189b2012-06-20 16:38:30 -07008387 return status;
8388}
8389
Mahesh A Saptasagar1a51bc02014-06-02 18:28:08 +05308390#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
8391static int wlan_hdd_cfg80211_set_default_key( struct wiphy *wiphy,
8392 struct net_device *ndev,
8393 u8 key_index,
8394 bool unicast, bool multicast)
8395#else
8396static int wlan_hdd_cfg80211_set_default_key( struct wiphy *wiphy,
8397 struct net_device *ndev,
8398 u8 key_index)
8399#endif
8400{
8401 int ret;
8402 vos_ssr_protect(__func__);
8403#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
8404 ret = __wlan_hdd_cfg80211_set_default_key(wiphy, ndev, key_index, unicast,
8405 multicast);
8406#else
8407 ret = __wlan_hdd_cfg80211_set_default_key(wiphy, ndev, key_index);
8408#endif
8409 vos_ssr_unprotect(__func__);
8410
8411 return ret;
8412}
8413
Jeff Johnson295189b2012-06-20 16:38:30 -07008414/*
8415 * FUNCTION: wlan_hdd_cfg80211_inform_bss
8416 * This function is used to inform the BSS details to nl80211 interface.
8417 */
8418static struct cfg80211_bss* wlan_hdd_cfg80211_inform_bss(
8419 hdd_adapter_t *pAdapter, tCsrRoamConnectedProfile *roamProfile)
8420{
8421 struct net_device *dev = pAdapter->dev;
8422 struct wireless_dev *wdev = dev->ieee80211_ptr;
8423 struct wiphy *wiphy = wdev->wiphy;
8424 tSirBssDescription *pBssDesc = roamProfile->pBssDesc;
8425 int chan_no;
8426 int ie_length;
8427 const char *ie;
8428 unsigned int freq;
8429 struct ieee80211_channel *chan;
8430 int rssi = 0;
8431 struct cfg80211_bss *bss = NULL;
8432
8433 ENTER();
8434
8435 if( NULL == pBssDesc )
8436 {
Arif Hussain6d2a3322013-11-17 19:50:10 -08008437 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: pBssDesc is NULL", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07008438 return bss;
8439 }
8440
8441 chan_no = pBssDesc->channelId;
8442 ie_length = GET_IE_LEN_IN_BSS_DESC( pBssDesc->length );
8443 ie = ((ie_length != 0) ? (const char *)&pBssDesc->ieFields: NULL);
8444
8445 if( NULL == ie )
8446 {
Arif Hussain6d2a3322013-11-17 19:50:10 -08008447 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: IE of BSS descriptor is NULL", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07008448 return bss;
8449 }
8450
8451#if (LINUX_VERSION_CODE > KERNEL_VERSION(2,6,38))
8452 if (chan_no <= ARRAY_SIZE(hdd_channels_2_4_GHZ))
8453 {
8454 freq = ieee80211_channel_to_frequency(chan_no, IEEE80211_BAND_2GHZ);
8455 }
8456 else
8457 {
8458 freq = ieee80211_channel_to_frequency(chan_no, IEEE80211_BAND_5GHZ);
8459 }
8460#else
8461 freq = ieee80211_channel_to_frequency(chan_no);
8462#endif
8463
8464 chan = __ieee80211_get_channel(wiphy, freq);
8465
Santhosh Kumar Padmaa45fdb12014-04-15 15:54:38 +05308466 if (!chan) {
8467 hddLog(VOS_TRACE_LEVEL_ERROR, "%s chan pointer is NULL", __func__);
8468 return NULL;
8469 }
8470
Abhishek Singhaee43942014-06-16 18:55:47 +05308471 rssi = (VOS_MIN ((pBssDesc->rssi + pBssDesc->sinr), 0))*100;
Jeff Johnson295189b2012-06-20 16:38:30 -07008472
Abhishek Singhaee43942014-06-16 18:55:47 +05308473 return cfg80211_inform_bss(wiphy, chan, pBssDesc->bssId,
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308474 le64_to_cpu(*(__le64 *)pBssDesc->timeStamp),
Jeff Johnson295189b2012-06-20 16:38:30 -07008475 pBssDesc->capabilityInfo,
8476 pBssDesc->beaconInterval, ie, ie_length,
Abhishek Singhaee43942014-06-16 18:55:47 +05308477 rssi, GFP_KERNEL );
Jeff Johnson295189b2012-06-20 16:38:30 -07008478}
8479
8480
8481
8482/*
8483 * FUNCTION: wlan_hdd_cfg80211_inform_bss_frame
8484 * This function is used to inform the BSS details to nl80211 interface.
8485 */
8486struct cfg80211_bss*
8487wlan_hdd_cfg80211_inform_bss_frame( hdd_adapter_t *pAdapter,
8488 tSirBssDescription *bss_desc
8489 )
8490{
8491 /*
8492 cfg80211_inform_bss() is not updating ie field of bss entry, if entry
8493 already exists in bss data base of cfg80211 for that particular BSS ID.
8494 Using cfg80211_inform_bss_frame to update the bss entry instead of
8495 cfg80211_inform_bss, But this call expects mgmt packet as input. As of
8496 now there is no possibility to get the mgmt(probe response) frame from PE,
8497 converting bss_desc to ieee80211_mgmt(probe response) and passing to
8498 cfg80211_inform_bss_frame.
8499 */
8500 struct net_device *dev = pAdapter->dev;
8501 struct wireless_dev *wdev = dev->ieee80211_ptr;
8502 struct wiphy *wiphy = wdev->wiphy;
8503 int chan_no = bss_desc->channelId;
Madan Mohan Koyyalamudi86f629e2012-11-09 16:27:29 -08008504#ifdef WLAN_ENABLE_AGEIE_ON_SCAN_RESULTS
8505 qcom_ie_age *qie_age = NULL;
8506 int ie_length = GET_IE_LEN_IN_BSS_DESC( bss_desc->length ) + sizeof(qcom_ie_age);
8507#else
Jeff Johnson295189b2012-06-20 16:38:30 -07008508 int ie_length = GET_IE_LEN_IN_BSS_DESC( bss_desc->length );
Madan Mohan Koyyalamudi86f629e2012-11-09 16:27:29 -08008509#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07008510 const char *ie =
8511 ((ie_length != 0) ? (const char *)&bss_desc->ieFields: NULL);
8512 unsigned int freq;
8513 struct ieee80211_channel *chan;
Abhishek Singh1e2bfa32014-01-02 15:44:15 +05308514 struct ieee80211_mgmt *mgmt = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -07008515 struct cfg80211_bss *bss_status = NULL;
8516 size_t frame_len = sizeof (struct ieee80211_mgmt) + ie_length;
8517 int rssi = 0;
Wilson Yangf80a0542013-10-07 13:02:37 -07008518 hdd_context_t *pHddCtx;
8519 int status;
Jeff Johnsone7245742012-09-05 17:12:55 -07008520#ifdef WLAN_OPEN_SOURCE
8521 struct timespec ts;
8522#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07008523
Wilson Yangf80a0542013-10-07 13:02:37 -07008524 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
8525 status = wlan_hdd_validate_context(pHddCtx);
8526
8527 /*bss_update is not allowed during wlan driver loading or unloading*/
Mihir Shete18156292014-03-11 15:38:30 +05308528 if (WLAN_HDD_IS_LOAD_UNLOAD_IN_PROGRESS(pHddCtx))
Wilson Yangf80a0542013-10-07 13:02:37 -07008529 {
8530 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
8531 "%s:Loading_unloading in Progress. Ignore!!!",__func__);
8532 return NULL;
8533 }
8534
8535
8536 if (0 != status)
8537 {
8538 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
8539 "%s: HDD context is not valid", __func__);
Madan Mohan Koyyalamudi2e5c9142012-11-02 13:17:48 -07008540 return NULL;
Wilson Yangf80a0542013-10-07 13:02:37 -07008541 }
8542
Abhishek Singh1e2bfa32014-01-02 15:44:15 +05308543 mgmt = kzalloc((sizeof (struct ieee80211_mgmt) + ie_length), GFP_KERNEL);
Wilson Yangf80a0542013-10-07 13:02:37 -07008544 if (!mgmt)
8545 {
8546 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
8547 "%s: memory allocation failed ", __func__);
8548 return NULL;
8549 }
Madan Mohan Koyyalamudi2e5c9142012-11-02 13:17:48 -07008550
Jeff Johnson295189b2012-06-20 16:38:30 -07008551 memcpy(mgmt->bssid, bss_desc->bssId, ETH_ALEN);
Jeff Johnsone7245742012-09-05 17:12:55 -07008552
8553#ifdef WLAN_OPEN_SOURCE
8554 /* Android does not want the timestamp from the frame.
8555 Instead it wants a monotonic increasing value */
8556 get_monotonic_boottime(&ts);
8557 mgmt->u.probe_resp.timestamp =
8558 ((u64)ts.tv_sec * 1000000) + (ts.tv_nsec / 1000);
8559#else
8560 /* keep old behavior for non-open source (for now) */
Jeff Johnson295189b2012-06-20 16:38:30 -07008561 memcpy(&mgmt->u.probe_resp.timestamp, bss_desc->timeStamp,
8562 sizeof (bss_desc->timeStamp));
Jeff Johnsone7245742012-09-05 17:12:55 -07008563
8564#endif
8565
Jeff Johnson295189b2012-06-20 16:38:30 -07008566 mgmt->u.probe_resp.beacon_int = bss_desc->beaconInterval;
8567 mgmt->u.probe_resp.capab_info = bss_desc->capabilityInfo;
Madan Mohan Koyyalamudi86f629e2012-11-09 16:27:29 -08008568
8569#ifdef WLAN_ENABLE_AGEIE_ON_SCAN_RESULTS
8570 /* GPS Requirement: need age ie per entry. Using vendor specific. */
8571 /* Assuming this is the last IE, copy at the end */
8572 ie_length -=sizeof(qcom_ie_age);
8573 qie_age = (qcom_ie_age *)(mgmt->u.probe_resp.variable + ie_length);
8574 qie_age->element_id = QCOM_VENDOR_IE_ID;
8575 qie_age->len = QCOM_VENDOR_IE_AGE_LEN;
8576 qie_age->oui_1 = QCOM_OUI1;
8577 qie_age->oui_2 = QCOM_OUI2;
8578 qie_age->oui_3 = QCOM_OUI3;
8579 qie_age->type = QCOM_VENDOR_IE_AGE_TYPE;
8580 qie_age->age = vos_timer_get_system_ticks() - bss_desc->nReceivedTime;
8581#endif
8582
Jeff Johnson295189b2012-06-20 16:38:30 -07008583 memcpy(mgmt->u.probe_resp.variable, ie, ie_length);
Gopichand Nakkalad908ec82013-05-16 19:32:19 +05308584 if (bss_desc->fProbeRsp)
8585 {
8586 mgmt->frame_control |=
8587 (u16)(IEEE80211_FTYPE_MGMT | IEEE80211_STYPE_PROBE_RESP);
8588 }
8589 else
8590 {
8591 mgmt->frame_control |=
8592 (u16)(IEEE80211_FTYPE_MGMT | IEEE80211_STYPE_BEACON);
8593 }
Jeff Johnson295189b2012-06-20 16:38:30 -07008594
8595#if (LINUX_VERSION_CODE > KERNEL_VERSION(2,6,38))
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308596 if (chan_no <= ARRAY_SIZE(hdd_channels_2_4_GHZ) &&
Jeff Johnson295189b2012-06-20 16:38:30 -07008597 (wiphy->bands[IEEE80211_BAND_2GHZ] != NULL))
8598 {
8599 freq = ieee80211_channel_to_frequency(chan_no, IEEE80211_BAND_2GHZ);
8600 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308601 else if ((chan_no > ARRAY_SIZE(hdd_channels_2_4_GHZ)) &&
Jeff Johnson295189b2012-06-20 16:38:30 -07008602 (wiphy->bands[IEEE80211_BAND_5GHZ] != NULL))
8603
8604 {
8605 freq = ieee80211_channel_to_frequency(chan_no, IEEE80211_BAND_5GHZ);
8606 }
8607 else
8608 {
Nirav Shah20ac06f2013-12-12 18:14:06 +05308609 hddLog(VOS_TRACE_LEVEL_ERROR, "%s Invalid chan_no:%d",
8610 __func__, chan_no);
Jeff Johnson295189b2012-06-20 16:38:30 -07008611 kfree(mgmt);
8612 return NULL;
8613 }
8614#else
8615 freq = ieee80211_channel_to_frequency(chan_no);
8616#endif
8617 chan = __ieee80211_get_channel(wiphy, freq);
Leela V Kiran Kumar Reddy90032de2013-01-24 18:33:30 -08008618 /*when the band is changed on the fly using the GUI, three things are done
8619 * 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)
8620 * as part of the scan abort, message willbe queued to PE and we proceed with flushing and changinh the band.
8621 * pe will stop the scanning further and report back the results what ever it had till now by calling the call back function.
8622 * if the time between update band and scandone call back is sufficent enough the band change reflects in SME, SME validates the channels
8623 * and discards the channels correponding to previous band and calls back with zero bss results.
8624 * 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
8625 * all the channels correponding to previous band.this is due to race condition.but those channels are invalid to the new band and so
8626 * this function __ieee80211_get_channel will return NULL.Each time we report scan result with this pointer null warning kernel trace is printed.
8627 * if the scan results contain large number of APs continuosly kernel warning trace is printed and it will lead to apps watch dog bark.
8628 * So drop the bss and continue to next bss.
8629 */
8630 if(chan == NULL)
8631 {
Nirav Shah20ac06f2013-12-12 18:14:06 +05308632 hddLog(VOS_TRACE_LEVEL_ERROR, "%s chan pointer is NULL", __func__);
Chilam Ngc4244af2013-04-01 15:37:32 -07008633 kfree(mgmt);
Leela V Kiran Kumar Reddy90032de2013-01-24 18:33:30 -08008634 return NULL;
8635 }
Jeff Johnson295189b2012-06-20 16:38:30 -07008636 /*To keep the rssi icon of the connected AP in the scan window
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308637 *and the rssi icon of the wireless networks in sync
Jeff Johnson295189b2012-06-20 16:38:30 -07008638 * */
8639 if (( eConnectionState_Associated ==
8640 pAdapter->sessionCtx.station.conn_info.connState ) &&
8641 ( VOS_TRUE == vos_mem_compare(bss_desc->bssId,
8642 pAdapter->sessionCtx.station.conn_info.bssId,
8643 WNI_CFG_BSSID_LEN)))
8644 {
8645 /* supplicant takes the signal strength in terms of mBm(100*dBm) */
8646 rssi = (pAdapter->rssi * 100);
8647 }
8648 else
8649 {
8650 rssi = (VOS_MIN ((bss_desc->rssi + bss_desc->sinr), 0))*100;
8651 }
8652
Nirav Shah20ac06f2013-12-12 18:14:06 +05308653 hddLog(VOS_TRACE_LEVEL_INFO, "%s: BSSID:" MAC_ADDRESS_STR " Channel:%d"
8654 "RSSI:%d", __func__, MAC_ADDR_ARRAY(mgmt->bssid),
8655 chan->center_freq, (int)(rssi/100));
8656
Jeff Johnson295189b2012-06-20 16:38:30 -07008657 bss_status = cfg80211_inform_bss_frame(wiphy, chan, mgmt,
8658 frame_len, rssi, GFP_KERNEL);
8659 kfree(mgmt);
8660 return bss_status;
8661}
8662
8663/*
8664 * FUNCTION: wlan_hdd_cfg80211_update_bss_db
8665 * This function is used to update the BSS data base of CFG8011
8666 */
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308667struct cfg80211_bss* wlan_hdd_cfg80211_update_bss_db( hdd_adapter_t *pAdapter,
Jeff Johnson295189b2012-06-20 16:38:30 -07008668 tCsrRoamInfo *pRoamInfo
8669 )
8670{
8671 tCsrRoamConnectedProfile roamProfile;
8672 tHalHandle hHal = WLAN_HDD_GET_HAL_CTX(pAdapter);
8673 struct cfg80211_bss *bss = NULL;
8674
8675 ENTER();
8676
8677 memset(&roamProfile, 0, sizeof(tCsrRoamConnectedProfile));
8678 sme_RoamGetConnectProfile(hHal, pAdapter->sessionId, &roamProfile);
8679
8680 if (NULL != roamProfile.pBssDesc)
8681 {
Girish Gowlif4b68022014-08-28 23:18:57 +05308682 bss = wlan_hdd_cfg80211_inform_bss_frame(pAdapter,
8683 roamProfile.pBssDesc);
Jeff Johnson295189b2012-06-20 16:38:30 -07008684
8685 if (NULL == bss)
8686 {
8687 hddLog(VOS_TRACE_LEVEL_INFO, "%s: cfg80211_inform_bss return NULL",
8688 __func__);
8689 }
8690
8691 sme_RoamFreeConnectProfile(hHal, &roamProfile);
8692 }
8693 else
8694 {
8695 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: roamProfile.pBssDesc is NULL",
8696 __func__);
8697 }
8698 return bss;
8699}
8700
8701/*
8702 * FUNCTION: wlan_hdd_cfg80211_update_bss
8703 */
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308704static int wlan_hdd_cfg80211_update_bss( struct wiphy *wiphy,
8705 hdd_adapter_t *pAdapter
Jeff Johnson295189b2012-06-20 16:38:30 -07008706 )
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308707{
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +05308708 tHalHandle hHal = WLAN_HDD_GET_HAL_CTX(pAdapter);
Jeff Johnson295189b2012-06-20 16:38:30 -07008709 tCsrScanResultInfo *pScanResult;
8710 eHalStatus status = 0;
8711 tScanResultHandle pResult;
8712 struct cfg80211_bss *bss_status = NULL;
Wilson Yangf80a0542013-10-07 13:02:37 -07008713 hdd_context_t *pHddCtx;
Jeff Johnson295189b2012-06-20 16:38:30 -07008714
8715 ENTER();
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +05308716
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05308717 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
8718 TRACE_CODE_HDD_CFG80211_UPDATE_BSS,
8719 NO_SESSION, pAdapter->sessionId));
8720
Wilson Yangf80a0542013-10-07 13:02:37 -07008721 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
8722
8723 if (pHddCtx->isLogpInProgress)
Jeff Johnson295189b2012-06-20 16:38:30 -07008724 {
Wilson Yangf80a0542013-10-07 13:02:37 -07008725 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
8726 "%s:LOGP in Progress. Ignore!!!",__func__);
8727 return -EAGAIN;
Jeff Johnson295189b2012-06-20 16:38:30 -07008728 }
8729
Wilson Yangf80a0542013-10-07 13:02:37 -07008730
8731 /*bss_update is not allowed during wlan driver loading or unloading*/
Mihir Shete18156292014-03-11 15:38:30 +05308732 if (WLAN_HDD_IS_LOAD_UNLOAD_IN_PROGRESS(pHddCtx))
Wilson Yangf80a0542013-10-07 13:02:37 -07008733 {
8734 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
8735 "%s:Loading_unloading in Progress. Ignore!!!",__func__);
8736 return VOS_STATUS_E_PERM;
8737 }
8738
8739
Jeff Johnson295189b2012-06-20 16:38:30 -07008740 /*
8741 * start getting scan results and populate cgf80211 BSS database
8742 */
8743 status = sme_ScanGetResult(hHal, pAdapter->sessionId, NULL, &pResult);
8744
8745 /* no scan results */
8746 if (NULL == pResult)
8747 {
Nirav Shah20ac06f2013-12-12 18:14:06 +05308748 hddLog(VOS_TRACE_LEVEL_INFO, "%s: No scan result Status %d",
8749 __func__, status);
Jeff Johnson295189b2012-06-20 16:38:30 -07008750 return status;
8751 }
8752
8753 pScanResult = sme_ScanResultGetFirst(hHal, pResult);
8754
8755 while (pScanResult)
8756 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308757 /*
8758 * cfg80211_inform_bss() is not updating ie field of bss entry, if
8759 * entry already exists in bss data base of cfg80211 for that
8760 * particular BSS ID. Using cfg80211_inform_bss_frame to update the
8761 * bss entry instead of cfg80211_inform_bss, But this call expects
8762 * mgmt packet as input. As of now there is no possibility to get
8763 * the mgmt(probe response) frame from PE, converting bss_desc to
Jeff Johnson295189b2012-06-20 16:38:30 -07008764 * ieee80211_mgmt(probe response) and passing to c
8765 * fg80211_inform_bss_frame.
8766 * */
8767
8768 bss_status = wlan_hdd_cfg80211_inform_bss_frame(pAdapter,
8769 &pScanResult->BssDescriptor);
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308770
Jeff Johnson295189b2012-06-20 16:38:30 -07008771
8772 if (NULL == bss_status)
8773 {
8774 hddLog(VOS_TRACE_LEVEL_INFO,
Arif Hussain6d2a3322013-11-17 19:50:10 -08008775 "%s: NULL returned by cfg80211_inform_bss", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07008776 }
8777 else
8778 {
Yue Maf49ba872013-08-19 12:04:25 -07008779 cfg80211_put_bss(
8780#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,9,0))
8781 wiphy,
8782#endif
8783 bss_status);
Jeff Johnson295189b2012-06-20 16:38:30 -07008784 }
8785
8786 pScanResult = sme_ScanResultGetNext(hHal, pResult);
8787 }
8788
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308789 sme_ScanResultPurge(hHal, pResult);
Jeff Johnson295189b2012-06-20 16:38:30 -07008790
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308791 return 0;
Jeff Johnson295189b2012-06-20 16:38:30 -07008792}
8793
Jeff Johnson04dd8a82012-06-29 20:41:40 -07008794void
8795hddPrintMacAddr(tCsrBssid macAddr, tANI_U8 logLevel)
8796{
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308797 VOS_TRACE(VOS_MODULE_ID_HDD, logLevel,
Arif Hussaina7c8e412013-11-20 11:06:42 -08008798 MAC_ADDRESS_STR, MAC_ADDR_ARRAY(macAddr));
Jeff Johnson04dd8a82012-06-29 20:41:40 -07008799} /****** end hddPrintMacAddr() ******/
8800
8801void
Madan Mohan Koyyalamudic75be962012-10-18 19:19:03 -07008802hddPrintPmkId(tANI_U8 *pmkId, tANI_U8 logLevel)
Jeff Johnson04dd8a82012-06-29 20:41:40 -07008803{
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308804 VOS_TRACE(VOS_MODULE_ID_HDD, logLevel,
Arif Hussain6d2a3322013-11-17 19:50:10 -08008805 "%02X:%02X:%02X:%02X:%02X:%02X:%02X:%02X:%02X:%02X:%02X:%02X:%02X:%02X:%02X:%02X",
Madan Mohan Koyyalamudic75be962012-10-18 19:19:03 -07008806 pmkId[0], pmkId[1], pmkId[2], pmkId[3], pmkId[4],
8807 pmkId[5], pmkId[6], pmkId[7], pmkId[8], pmkId[9], pmkId[10],
8808 pmkId[11], pmkId[12], pmkId[13], pmkId[14], pmkId[15]);
Jeff Johnson04dd8a82012-06-29 20:41:40 -07008809} /****** end hddPrintPmkId() ******/
8810
8811//hddPrintMacAddr(tCsrBssid macAddr, tANI_U8 logLevel);
8812//hddPrintMacAddr(macAddr, VOS_TRACE_LEVEL_FATAL);
8813
8814//void sirDumpBuf(tpAniSirGlobal pMac, tANI_U8 modId, tANI_U32 level, tANI_U8 *buf, tANI_U32 size);
8815//sirDumpBuf(pMac, VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL, pmkid, 16);
8816
8817#define dump_bssid(bssid) \
8818 { \
Jeff Johnsone7245742012-09-05 17:12:55 -07008819 hddLog(VOS_TRACE_LEVEL_INFO, "BSSID (MAC) address:\t"); \
8820 hddPrintMacAddr(bssid, VOS_TRACE_LEVEL_INFO);\
Jeff Johnson04dd8a82012-06-29 20:41:40 -07008821 }
8822
8823#define dump_pmkid(pMac, pmkid) \
8824 { \
Jeff Johnsone7245742012-09-05 17:12:55 -07008825 hddLog(VOS_TRACE_LEVEL_INFO, "PMKSA-ID:\t"); \
8826 hddPrintPmkId(pmkid, VOS_TRACE_LEVEL_INFO);\
Jeff Johnson04dd8a82012-06-29 20:41:40 -07008827 }
8828
Madan Mohan Koyyalamudi1b4afb02012-10-22 15:25:16 -07008829#if defined(FEATURE_WLAN_LFR) && (LINUX_VERSION_CODE >= KERNEL_VERSION(3,4,0))
Jeff Johnson04dd8a82012-06-29 20:41:40 -07008830/*
8831 * FUNCTION: wlan_hdd_cfg80211_pmksa_candidate_notify
8832 * This function is used to notify the supplicant of a new PMKSA candidate.
8833 */
8834int wlan_hdd_cfg80211_pmksa_candidate_notify(
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308835 hdd_adapter_t *pAdapter, tCsrRoamInfo *pRoamInfo,
Jeff Johnson04dd8a82012-06-29 20:41:40 -07008836 int index, bool preauth )
8837{
Jeff Johnsone7245742012-09-05 17:12:55 -07008838#ifdef FEATURE_WLAN_OKC
Jeff Johnson04dd8a82012-06-29 20:41:40 -07008839 struct net_device *dev = pAdapter->dev;
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07008840 hdd_context_t *pHddCtx = (hdd_context_t*)pAdapter->pHddCtx;
Jeff Johnson04dd8a82012-06-29 20:41:40 -07008841
8842 ENTER();
Jeff Johnsone7245742012-09-05 17:12:55 -07008843 hddLog(VOS_TRACE_LEVEL_INFO, "%s is going to notify supplicant of:", __func__);
Jeff Johnson04dd8a82012-06-29 20:41:40 -07008844
8845 if( NULL == pRoamInfo )
8846 {
Arif Hussain6d2a3322013-11-17 19:50:10 -08008847 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: pRoamInfo is NULL", __func__);
Jeff Johnson04dd8a82012-06-29 20:41:40 -07008848 return -EINVAL;
8849 }
8850
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07008851 if (eANI_BOOLEAN_TRUE == hdd_is_okc_mode_enabled(pHddCtx))
8852 {
8853 dump_bssid(pRoamInfo->bssid);
8854 cfg80211_pmksa_candidate_notify(dev, index,
Jeff Johnson04dd8a82012-06-29 20:41:40 -07008855 pRoamInfo->bssid, preauth, GFP_KERNEL);
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07008856 }
Jeff Johnsone7245742012-09-05 17:12:55 -07008857#endif /* FEATURE_WLAN_OKC */
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308858 return 0;
Jeff Johnson04dd8a82012-06-29 20:41:40 -07008859}
8860#endif //FEATURE_WLAN_LFR
8861
Yue Maef608272013-04-08 23:09:17 -07008862#ifdef FEATURE_WLAN_LFR_METRICS
8863/*
8864 * FUNCTION: wlan_hdd_cfg80211_roam_metrics_preauth
8865 * 802.11r/LFR metrics reporting function to report preauth initiation
8866 *
8867 */
8868#define MAX_LFR_METRICS_EVENT_LENGTH 100
8869VOS_STATUS wlan_hdd_cfg80211_roam_metrics_preauth(hdd_adapter_t *pAdapter,
8870 tCsrRoamInfo *pRoamInfo)
8871{
8872 unsigned char metrics_notification[MAX_LFR_METRICS_EVENT_LENGTH + 1];
8873 union iwreq_data wrqu;
8874
8875 ENTER();
8876
8877 if (NULL == pAdapter)
8878 {
8879 hddLog(LOGE, "%s: pAdapter is NULL!", __func__);
8880 return VOS_STATUS_E_FAILURE;
8881 }
8882
8883 /* create the event */
8884 memset(&wrqu, 0, sizeof(wrqu));
8885 memset(metrics_notification, 0, sizeof(metrics_notification));
8886
8887 wrqu.data.pointer = metrics_notification;
8888 wrqu.data.length = scnprintf(metrics_notification,
8889 sizeof(metrics_notification), "QCOM: LFR_PREAUTH_INIT "
8890 MAC_ADDRESS_STR, MAC_ADDR_ARRAY(pRoamInfo->bssid));
8891
8892 wireless_send_event(pAdapter->dev, IWEVCUSTOM, &wrqu, metrics_notification);
8893
8894 EXIT();
8895
8896 return VOS_STATUS_SUCCESS;
8897}
8898
8899/*
8900 * FUNCTION: wlan_hdd_cfg80211_roam_metrics_preauth_status
8901 * 802.11r/LFR metrics reporting function to report preauth completion
8902 * or failure
8903 */
8904VOS_STATUS wlan_hdd_cfg80211_roam_metrics_preauth_status(
8905 hdd_adapter_t *pAdapter, tCsrRoamInfo *pRoamInfo, bool preauth_status)
8906{
8907 unsigned char metrics_notification[MAX_LFR_METRICS_EVENT_LENGTH + 1];
8908 union iwreq_data wrqu;
8909
8910 ENTER();
8911
8912 if (NULL == pAdapter)
8913 {
8914 hddLog(LOGE, "%s: pAdapter is NULL!", __func__);
8915 return VOS_STATUS_E_FAILURE;
8916 }
8917
8918 /* create the event */
8919 memset(&wrqu, 0, sizeof(wrqu));
8920 memset(metrics_notification, 0, sizeof(metrics_notification));
8921
8922 scnprintf(metrics_notification, sizeof(metrics_notification),
8923 "QCOM: LFR_PREAUTH_STATUS "MAC_ADDRESS_STR,
8924 MAC_ADDR_ARRAY(pRoamInfo->bssid));
8925
8926 if (1 == preauth_status)
8927 strncat(metrics_notification, " TRUE", 5);
8928 else
8929 strncat(metrics_notification, " FALSE", 6);
8930
8931 wrqu.data.pointer = metrics_notification;
8932 wrqu.data.length = strlen(metrics_notification);
8933
8934 wireless_send_event(pAdapter->dev, IWEVCUSTOM, &wrqu, metrics_notification);
8935
8936 EXIT();
8937
8938 return VOS_STATUS_SUCCESS;
8939}
8940
8941/*
8942 * FUNCTION: wlan_hdd_cfg80211_roam_metrics_handover
8943 * 802.11r/LFR metrics reporting function to report handover initiation
8944 *
8945 */
8946VOS_STATUS wlan_hdd_cfg80211_roam_metrics_handover(hdd_adapter_t * pAdapter,
8947 tCsrRoamInfo *pRoamInfo)
8948{
8949 unsigned char metrics_notification[MAX_LFR_METRICS_EVENT_LENGTH + 1];
8950 union iwreq_data wrqu;
8951
8952 ENTER();
8953
8954 if (NULL == pAdapter)
8955 {
8956 hddLog(LOGE, "%s: pAdapter is NULL!", __func__);
8957 return VOS_STATUS_E_FAILURE;
8958 }
8959
8960 /* create the event */
8961 memset(&wrqu, 0, sizeof(wrqu));
8962 memset(metrics_notification, 0, sizeof(metrics_notification));
8963
8964 wrqu.data.pointer = metrics_notification;
8965 wrqu.data.length = scnprintf(metrics_notification,
8966 sizeof(metrics_notification), "QCOM: LFR_PREAUTH_HANDOVER "
8967 MAC_ADDRESS_STR, MAC_ADDR_ARRAY(pRoamInfo->bssid));
8968
8969 wireless_send_event(pAdapter->dev, IWEVCUSTOM, &wrqu, metrics_notification);
8970
8971 EXIT();
8972
8973 return VOS_STATUS_SUCCESS;
8974}
8975#endif
8976
Jeff Johnson295189b2012-06-20 16:38:30 -07008977/*
8978 * FUNCTION: hdd_cfg80211_scan_done_callback
8979 * scanning callback function, called after finishing scan
8980 *
8981 */
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308982static eHalStatus hdd_cfg80211_scan_done_callback(tHalHandle halHandle,
Jeff Johnson295189b2012-06-20 16:38:30 -07008983 void *pContext, tANI_U32 scanId, eCsrScanStatus status)
8984{
8985 struct net_device *dev = (struct net_device *) pContext;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308986 //struct wireless_dev *wdev = dev->ieee80211_ptr;
Jeff Johnson295189b2012-06-20 16:38:30 -07008987 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( dev );
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -07008988 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
8989 hdd_scaninfo_t *pScanInfo = &pHddCtx->scan_info;
Jeff Johnson295189b2012-06-20 16:38:30 -07008990 struct cfg80211_scan_request *req = NULL;
8991 int ret = 0;
Mahesh A Saptasagar05a357e2014-02-26 16:28:06 +05308992 bool aborted = false;
c_hpothu6ff1c3c2013-10-01 19:01:57 +05308993 long waitRet = 0;
Jeff Johnson295189b2012-06-20 16:38:30 -07008994
8995 ENTER();
8996
8997 hddLog(VOS_TRACE_LEVEL_INFO,
8998 "%s called with halHandle = %p, pContext = %p,"
Arif Hussain6d2a3322013-11-17 19:50:10 -08008999 "scanID = %d, returned status = %d",
Jeff Johnson295189b2012-06-20 16:38:30 -07009000 __func__, halHandle, pContext, (int) scanId, (int) status);
9001
Kiet Lamac06e2c2013-10-23 16:25:07 +05309002 pScanInfo->mScanPendingCounter = 0;
9003
Jeff Johnson295189b2012-06-20 16:38:30 -07009004 //Block on scan req completion variable. Can't wait forever though.
c_hpothu6ff1c3c2013-10-01 19:01:57 +05309005 waitRet = wait_for_completion_interruptible_timeout(
Jeff Johnson295189b2012-06-20 16:38:30 -07009006 &pScanInfo->scan_req_completion_event,
9007 msecs_to_jiffies(WLAN_WAIT_TIME_SCAN_REQ));
c_hpothu6ff1c3c2013-10-01 19:01:57 +05309008 if (waitRet <= 0)
Jeff Johnson295189b2012-06-20 16:38:30 -07009009 {
c_hpothu6ff1c3c2013-10-01 19:01:57 +05309010 hddLog(VOS_TRACE_LEVEL_ERROR,
9011 "%s wait on scan_req_completion_event failed %ld",__func__, waitRet);
Jeff Johnson295189b2012-06-20 16:38:30 -07009012 VOS_ASSERT(pScanInfo->mScanPending);
Jeff Johnsone7245742012-09-05 17:12:55 -07009013 goto allow_suspend;
Jeff Johnson295189b2012-06-20 16:38:30 -07009014 }
9015
Yue Maef608272013-04-08 23:09:17 -07009016 if (pScanInfo->mScanPending != VOS_TRUE)
Jeff Johnson295189b2012-06-20 16:38:30 -07009017 {
9018 VOS_ASSERT(pScanInfo->mScanPending);
Jeff Johnsone7245742012-09-05 17:12:55 -07009019 goto allow_suspend;
Jeff Johnson295189b2012-06-20 16:38:30 -07009020 }
9021
9022 /* Check the scanId */
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309023 if (pScanInfo->scanId != scanId)
Jeff Johnson295189b2012-06-20 16:38:30 -07009024 {
9025 hddLog(VOS_TRACE_LEVEL_INFO,
9026 "%s called with mismatched scanId pScanInfo->scanId = %d "
Arif Hussain6d2a3322013-11-17 19:50:10 -08009027 "scanId = %d", __func__, (int) pScanInfo->scanId,
Jeff Johnson295189b2012-06-20 16:38:30 -07009028 (int) scanId);
9029 }
9030
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309031 ret = wlan_hdd_cfg80211_update_bss((WLAN_HDD_GET_CTX(pAdapter))->wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -07009032 pAdapter);
9033
9034 if (0 > ret)
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309035 hddLog(VOS_TRACE_LEVEL_INFO, "%s: NO SCAN result", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07009036
9037
9038 /* If any client wait scan result through WEXT
9039 * send scan done event to client */
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -07009040 if (pHddCtx->scan_info.waitScanResult)
Jeff Johnson295189b2012-06-20 16:38:30 -07009041 {
9042 /* The other scan request waiting for current scan finish
9043 * Send event to notify current scan finished */
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -07009044 if(WEXT_SCAN_PENDING_DELAY == pHddCtx->scan_info.scan_pending_option)
Jeff Johnson295189b2012-06-20 16:38:30 -07009045 {
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -07009046 vos_event_set(&pHddCtx->scan_info.scan_finished_event);
Jeff Johnson295189b2012-06-20 16:38:30 -07009047 }
9048 /* Send notify to WEXT client */
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -07009049 else if(WEXT_SCAN_PENDING_PIGGYBACK == pHddCtx->scan_info.scan_pending_option)
Jeff Johnson295189b2012-06-20 16:38:30 -07009050 {
9051 struct net_device *dev = pAdapter->dev;
9052 union iwreq_data wrqu;
9053 int we_event;
9054 char *msg;
9055
9056 memset(&wrqu, '\0', sizeof(wrqu));
9057 we_event = SIOCGIWSCAN;
9058 msg = NULL;
9059 wireless_send_event(dev, we_event, &wrqu, msg);
9060 }
9061 }
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -07009062 pHddCtx->scan_info.waitScanResult = FALSE;
Jeff Johnson295189b2012-06-20 16:38:30 -07009063
9064 /* Get the Scan Req */
9065 req = pAdapter->request;
9066
9067 if (!req)
9068 {
Arif Hussain6d2a3322013-11-17 19:50:10 -08009069 hddLog(VOS_TRACE_LEVEL_ERROR, "request is became NULL");
Madan Mohan Koyyalamudi9f5a10c2012-09-28 14:46:16 -07009070 pScanInfo->mScanPending = VOS_FALSE;
Jeff Johnsone7245742012-09-05 17:12:55 -07009071 goto allow_suspend;
Jeff Johnson295189b2012-06-20 16:38:30 -07009072 }
9073
9074 /*
9075 * setting up 0, just in case.
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309076 */
Jeff Johnson295189b2012-06-20 16:38:30 -07009077 req->n_ssids = 0;
9078 req->n_channels = 0;
9079 req->ie = 0;
9080
Jeff Johnson295189b2012-06-20 16:38:30 -07009081 pAdapter->request = NULL;
Jeff Johnsone7245742012-09-05 17:12:55 -07009082 /* Scan is no longer pending */
9083 pScanInfo->mScanPending = VOS_FALSE;
Jeff Johnson295189b2012-06-20 16:38:30 -07009084
Madan Mohan Koyyalamudib764bf82012-10-11 16:38:51 -07009085 /*
9086 * cfg80211_scan_done informing NL80211 about completion
9087 * of scanning
9088 */
Mahesh A Saptasagar05a357e2014-02-26 16:28:06 +05309089 if (status == eCSR_SCAN_ABORT || status == eCSR_SCAN_FAILURE)
9090 {
9091 aborted = true;
9092 }
9093 cfg80211_scan_done(req, aborted);
Madan Mohan Koyyalamudif4e81002012-11-13 10:46:38 -08009094 complete(&pScanInfo->abortscan_event_var);
Jeff Johnson295189b2012-06-20 16:38:30 -07009095
Jeff Johnsone7245742012-09-05 17:12:55 -07009096allow_suspend:
Madan Mohan Koyyalamudi9f5a10c2012-09-28 14:46:16 -07009097 /* release the wake lock at the end of the scan*/
9098 hdd_allow_suspend();
Jeff Johnsone7245742012-09-05 17:12:55 -07009099
Madan Mohan Koyyalamudi10d83a92012-09-28 15:47:05 -07009100 /* Acquire wakelock to handle the case where APP's tries to suspend
9101 * immediatly after the driver gets connect request(i.e after scan)
9102 * from supplicant, this result in app's is suspending and not able
9103 * to process the connect request to AP */
Mahesh A Saptasagarb9c50402014-01-16 15:49:22 +05309104 hdd_prevent_suspend_timeout(1000);
Madan Mohan Koyyalamudi10d83a92012-09-28 15:47:05 -07009105
Gopichand Nakkala638ebc72013-03-21 18:04:02 -07009106#ifdef FEATURE_WLAN_TDLS
c_hpothu3c8f8e82014-06-02 18:01:50 +05309107 if (!(eTDLS_SUPPORT_NOT_ENABLED == pHddCtx->tdls_mode))
9108 {
9109 wlan_hdd_tdls_scan_done_callback(pAdapter);
9110 }
Gopichand Nakkala638ebc72013-03-21 18:04:02 -07009111#endif
9112
Jeff Johnson295189b2012-06-20 16:38:30 -07009113 EXIT();
9114 return 0;
9115}
9116
9117/*
Rashmi Ramannab1429032014-04-26 14:59:09 +05309118 * FUNCTION: hdd_isConnectionInProgress
9119 * Go through each adapter and check if Connection is in progress
Madan Mohan Koyyalamudicfd53742013-01-11 15:29:03 -08009120 *
9121 */
Ganesh Kondabattiniaeb7b772014-08-11 20:00:36 +05309122v_BOOL_t hdd_isConnectionInProgress( hdd_context_t *pHddCtx, v_BOOL_t isRoC )
Madan Mohan Koyyalamudicfd53742013-01-11 15:29:03 -08009123{
9124 hdd_adapter_list_node_t *pAdapterNode = NULL, *pNext = NULL;
9125 hdd_station_ctx_t *pHddStaCtx = NULL;
9126 hdd_adapter_t *pAdapter = NULL;
9127 VOS_STATUS status = 0;
9128 v_U8_t staId = 0;
9129 v_U8_t *staMac = NULL;
9130
c_hpothu9b781ba2013-12-30 20:57:45 +05309131 if (TRUE == pHddCtx->btCoexModeSet)
9132 {
9133 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Rashmi Ramannab1429032014-04-26 14:59:09 +05309134 FL("BTCoex Mode operation in progress"));
9135 return VOS_TRUE;
c_hpothu9b781ba2013-12-30 20:57:45 +05309136 }
9137
Madan Mohan Koyyalamudicfd53742013-01-11 15:29:03 -08009138 status = hdd_get_front_adapter ( pHddCtx, &pAdapterNode );
9139
9140 while ( NULL != pAdapterNode && VOS_STATUS_SUCCESS == status )
9141 {
9142 pAdapter = pAdapterNode->pAdapter;
9143
9144 if( pAdapter )
9145 {
9146 hddLog(VOS_TRACE_LEVEL_INFO,
Sushant Kaushik8bc7df22014-04-09 17:55:29 +05309147 "%s: Adapter with device mode %s (%d) exists",
9148 __func__, hdd_device_modetoString(pAdapter->device_mode),
9149 pAdapter->device_mode);
Ganesh Kondabattiniaeb7b772014-08-11 20:00:36 +05309150 if ((((!isRoC) && (WLAN_HDD_INFRA_STATION == pAdapter->device_mode)) ||
Rashmi Ramannab1429032014-04-26 14:59:09 +05309151 (WLAN_HDD_P2P_CLIENT == pAdapter->device_mode) ||
9152 (WLAN_HDD_P2P_DEVICE == pAdapter->device_mode)) &&
9153 (eConnectionState_Connecting ==
9154 (WLAN_HDD_GET_STATION_CTX_PTR(pAdapter))->conn_info.connState))
9155 {
9156 hddLog(VOS_TRACE_LEVEL_ERROR,
9157 "%s: %p(%d) Connection is in progress", __func__,
9158 WLAN_HDD_GET_STATION_CTX_PTR(pAdapter), pAdapter->sessionId);
9159 return VOS_TRUE;
9160 }
Ganesh Kondabattiniaeb7b772014-08-11 20:00:36 +05309161 if (((!isRoC) && (WLAN_HDD_INFRA_STATION == pAdapter->device_mode)) ||
Sushant Kaushik8bc7df22014-04-09 17:55:29 +05309162 (WLAN_HDD_P2P_CLIENT == pAdapter->device_mode) ||
9163 (WLAN_HDD_P2P_DEVICE == pAdapter->device_mode))
Madan Mohan Koyyalamudicfd53742013-01-11 15:29:03 -08009164 {
9165 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
9166 if ((eConnectionState_Associated == pHddStaCtx->conn_info.connState) &&
Sushant Kaushik8bc7df22014-04-09 17:55:29 +05309167 (VOS_FALSE == pHddStaCtx->conn_info.uIsAuthenticated))
Madan Mohan Koyyalamudicfd53742013-01-11 15:29:03 -08009168 {
9169 staMac = (v_U8_t *) &(pAdapter->macAddressCurrent.bytes[0]);
9170 hddLog(VOS_TRACE_LEVEL_ERROR,
Arif Hussain24bafea2013-11-15 15:10:03 -08009171 "%s: client " MAC_ADDRESS_STR
9172 " is in the middle of WPS/EAPOL exchange.", __func__,
9173 MAC_ADDR_ARRAY(staMac));
Rashmi Ramannab1429032014-04-26 14:59:09 +05309174 return VOS_TRUE;
Madan Mohan Koyyalamudicfd53742013-01-11 15:29:03 -08009175 }
9176 }
9177 else if ((WLAN_HDD_SOFTAP == pAdapter->device_mode) ||
9178 (WLAN_HDD_P2P_GO == pAdapter->device_mode))
9179 {
9180 for (staId = 0; staId < WLAN_MAX_STA_COUNT; staId++)
9181 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309182 if ((pAdapter->aStaInfo[staId].isUsed) &&
Madan Mohan Koyyalamudicfd53742013-01-11 15:29:03 -08009183 (WLANTL_STA_CONNECTED == pAdapter->aStaInfo[staId].tlSTAState))
9184 {
9185 staMac = (v_U8_t *) &(pAdapter->aStaInfo[staId].macAddrSTA.bytes[0]);
9186
9187 hddLog(VOS_TRACE_LEVEL_ERROR,
Arif Hussain24bafea2013-11-15 15:10:03 -08009188 "%s: client " MAC_ADDRESS_STR " of SoftAP/P2P-GO is in the "
9189 "middle of WPS/EAPOL exchange.", __func__,
9190 MAC_ADDR_ARRAY(staMac));
Rashmi Ramannab1429032014-04-26 14:59:09 +05309191 return VOS_TRUE;
Madan Mohan Koyyalamudicfd53742013-01-11 15:29:03 -08009192 }
9193 }
9194 }
9195 }
9196 status = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
9197 pAdapterNode = pNext;
9198 }
Rashmi Ramannab1429032014-04-26 14:59:09 +05309199 return VOS_FALSE;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309200}
Madan Mohan Koyyalamudicfd53742013-01-11 15:29:03 -08009201
9202/*
Mahesh A Saptasagarfafb7fe2014-05-16 13:19:37 +05309203 * FUNCTION: __wlan_hdd_cfg80211_scan
Jeff Johnson295189b2012-06-20 16:38:30 -07009204 * this scan respond to scan trigger and update cfg80211 scan database
9205 * later, scan dump command can be used to recieve scan results
9206 */
Mahesh A Saptasagarfafb7fe2014-05-16 13:19:37 +05309207int __wlan_hdd_cfg80211_scan( struct wiphy *wiphy,
Jeff Johnson3bbe4bf2013-01-18 17:05:29 -08009208#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,6,0))
9209 struct net_device *dev,
9210#endif
9211 struct cfg80211_scan_request *request)
9212{
Siddharth Bhal0c162d02014-05-06 19:50:42 +05309213 hdd_adapter_t *pAdapter = NULL;
9214 hdd_context_t *pHddCtx = NULL;
9215 hdd_wext_state_t *pwextBuf = NULL;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05309216 hdd_config_t *cfg_param = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -07009217 tCsrScanRequest scanRequest;
9218 tANI_U8 *channelList = NULL, i;
9219 v_U32_t scanId = 0;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05309220 int status;
9221 hdd_scaninfo_t *pScanInfo = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -07009222 v_U8_t* pP2pIe = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -07009223
Siddharth Bhal0c162d02014-05-06 19:50:42 +05309224#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,6,0))
9225 struct net_device *dev = NULL;
9226 if (NULL == request)
9227 {
9228 hddLog(VOS_TRACE_LEVEL_ERROR,
9229 "%s: scan req param null", __func__);
9230 return -EINVAL;
9231 }
9232 dev = request->wdev->netdev;
9233#endif
9234
9235 pAdapter = WLAN_HDD_GET_PRIV_PTR( dev );
9236 pHddCtx = WLAN_HDD_GET_CTX( pAdapter );
9237 pwextBuf = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
9238
Jeff Johnson295189b2012-06-20 16:38:30 -07009239 ENTER();
9240
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +05309241
Sushant Kaushik8bc7df22014-04-09 17:55:29 +05309242 hddLog(VOS_TRACE_LEVEL_INFO, "%s: device_mode = %s (%d)",
9243 __func__, hdd_device_modetoString(pAdapter->device_mode),
9244 pAdapter->device_mode);
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +05309245
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05309246 status = wlan_hdd_validate_context(pHddCtx);
9247
9248 if (0 != status)
9249 {
9250 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
9251 "%s: HDD context is not valid", __func__);
9252 return status;
9253 }
9254
Siddharth Bhal0c162d02014-05-06 19:50:42 +05309255 if (NULL == pwextBuf)
9256 {
9257 hddLog (VOS_TRACE_LEVEL_ERROR, "%s ERROR: invalid WEXT state\n",
9258 __func__);
9259 return -EIO;
9260 }
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05309261 cfg_param = pHddCtx->cfg_ini;
9262 pScanInfo = &pHddCtx->scan_info;
9263
Jeff Johnson295189b2012-06-20 16:38:30 -07009264#ifdef WLAN_BTAMP_FEATURE
9265 //Scan not supported when AMP traffic is on.
Gopichand Nakkala681989c2013-03-06 22:27:48 -08009266 if (VOS_TRUE == WLANBAP_AmpSessionOn())
Jeff Johnson295189b2012-06-20 16:38:30 -07009267 {
Madan Mohan Koyyalamudifd4e1da2012-11-09 17:50:19 -08009268 hddLog(VOS_TRACE_LEVEL_ERROR,
Jeff Johnson295189b2012-06-20 16:38:30 -07009269 "%s: No scanning when AMP is on", __func__);
9270 return -EOPNOTSUPP;
9271 }
9272#endif
9273 //Scan on any other interface is not supported.
Gopichand Nakkala681989c2013-03-06 22:27:48 -08009274 if (pAdapter->device_mode == WLAN_HDD_SOFTAP)
Jeff Johnson295189b2012-06-20 16:38:30 -07009275 {
Gopichand Nakkala681989c2013-03-06 22:27:48 -08009276 hddLog(VOS_TRACE_LEVEL_ERROR,
Sushant Kaushik8bc7df22014-04-09 17:55:29 +05309277 "%s: Not scanning on device_mode = %s (%d)",
9278 __func__, hdd_device_modetoString(pAdapter->device_mode),
9279 pAdapter->device_mode);
Jeff Johnson295189b2012-06-20 16:38:30 -07009280 return -EOPNOTSUPP;
9281 }
9282
9283 if (TRUE == pScanInfo->mScanPending)
9284 {
Kiet Lamac06e2c2013-10-23 16:25:07 +05309285 if ( MAX_PENDING_LOG > pScanInfo->mScanPendingCounter++ )
9286 {
9287 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: mScanPending is TRUE", __func__);
9288 }
Gopichand Nakkala681989c2013-03-06 22:27:48 -08009289 return -EBUSY;
Jeff Johnson295189b2012-06-20 16:38:30 -07009290 }
9291
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309292 //Don't Allow Scan and return busy if Remain On
Jeff Johnson32d95a32012-09-10 13:15:23 -07009293 //Channel and action frame is pending
9294 //Otherwise Cancel Remain On Channel and allow Scan
9295 //If no action frame pending
Gopichand Nakkala681989c2013-03-06 22:27:48 -08009296 if (0 != wlan_hdd_check_remain_on_channel(pAdapter))
Jeff Johnson32d95a32012-09-10 13:15:23 -07009297 {
Kiet Lamac06e2c2013-10-23 16:25:07 +05309298 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Remain On Channel Pending", __func__);
Jeff Johnson32d95a32012-09-10 13:15:23 -07009299 return -EBUSY;
9300 }
Gopichand Nakkala681989c2013-03-06 22:27:48 -08009301#ifdef FEATURE_WLAN_TDLS
Gopichand Nakkala638ebc72013-03-21 18:04:02 -07009302 /* if tdls disagree scan right now, return immediately.
9303 tdls will schedule the scan when scan is allowed. (return SUCCESS)
9304 or will reject the scan if any TDLS is in progress. (return -EBUSY)
9305 */
9306 status = wlan_hdd_tdls_scan_callback (pAdapter,
9307 wiphy,
9308#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,6,0))
9309 dev,
Gopichand Nakkalac3c42b92013-03-20 19:42:34 -07009310#endif
Gopichand Nakkala638ebc72013-03-21 18:04:02 -07009311 request);
9312 if(status <= 0)
9313 {
Nirav Shah20ac06f2013-12-12 18:14:06 +05309314 if(!status)
9315 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: TDLS in progress."
9316 "scan rejected %d", __func__, status);
9317 else
9318 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: TDLS teardown is ongoing %d",
9319 __func__, status);
9320
Gopichand Nakkala638ebc72013-03-21 18:04:02 -07009321 return status;
Gopichand Nakkala681989c2013-03-06 22:27:48 -08009322 }
9323#endif
Jeff Johnson32d95a32012-09-10 13:15:23 -07009324
Jeff Johnson295189b2012-06-20 16:38:30 -07009325 if (mutex_lock_interruptible(&pHddCtx->tmInfo.tmOperationLock))
9326 {
9327 VOS_TRACE(VOS_MODULE_ID_HDD,VOS_TRACE_LEVEL_ERROR,
Jeff Johnson1250df42012-12-10 14:31:52 -08009328 "%s: Acquire lock fail", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07009329 return -EAGAIN;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309330 }
Jeff Johnson295189b2012-06-20 16:38:30 -07009331 if (TRUE == pHddCtx->tmInfo.tmAction.enterImps)
9332 {
Nirav Shah20ac06f2013-12-12 18:14:06 +05309333 hddLog(VOS_TRACE_LEVEL_ERROR,
Jeff Johnson295189b2012-06-20 16:38:30 -07009334 "%s: MAX TM Level Scan not allowed", __func__);
9335 mutex_unlock(&pHddCtx->tmInfo.tmOperationLock);
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309336 return -EBUSY;
Jeff Johnson295189b2012-06-20 16:38:30 -07009337 }
9338 mutex_unlock(&pHddCtx->tmInfo.tmOperationLock);
9339
Madan Mohan Koyyalamudicfd53742013-01-11 15:29:03 -08009340 /* Check if scan is allowed at this point of time.
9341 */
Ganesh Kondabattiniaeb7b772014-08-11 20:00:36 +05309342 if (hdd_isConnectionInProgress(pHddCtx, VOS_FALSE))
Madan Mohan Koyyalamudicfd53742013-01-11 15:29:03 -08009343 {
9344 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Scan not allowed", __func__);
9345 return -EBUSY;
9346 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309347
Jeff Johnson295189b2012-06-20 16:38:30 -07009348 vos_mem_zero( &scanRequest, sizeof(scanRequest));
9349
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +05309350 hddLog(VOS_TRACE_LEVEL_INFO, "scan request for ssid = %d",
9351 (int)request->n_ssids);
9352
9353 /* Even though supplicant doesn't provide any SSIDs, n_ssids is set to 1.
9354 * Becasue of this, driver is assuming that this is not wildcard scan and so
9355 * is not aging out the scan results.
9356 */
9357 if (request->ssids && '\0' == request->ssids->ssid[0])
Jeff Johnson295189b2012-06-20 16:38:30 -07009358 {
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +05309359 request->n_ssids = 0;
Jeff Johnson295189b2012-06-20 16:38:30 -07009360 }
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +05309361
9362 if ((request->ssids) && (0 < request->n_ssids))
9363 {
9364 tCsrSSIDInfo *SsidInfo;
9365 int j;
9366 scanRequest.SSIDs.numOfSSIDs = request->n_ssids;
9367 /* Allocate num_ssid tCsrSSIDInfo structure */
9368 SsidInfo = scanRequest.SSIDs.SSIDList =
9369 ( tCsrSSIDInfo *)vos_mem_malloc(
9370 request->n_ssids*sizeof(tCsrSSIDInfo));
9371
9372 if(NULL == scanRequest.SSIDs.SSIDList)
9373 {
9374 hddLog(VOS_TRACE_LEVEL_ERROR,
9375 "%s: memory alloc failed SSIDInfo buffer", __func__);
9376 return -ENOMEM;
9377 }
9378
9379 /* copy all the ssid's and their length */
9380 for(j = 0; j < request->n_ssids; j++, SsidInfo++)
9381 {
9382 /* get the ssid length */
9383 SsidInfo->SSID.length = request->ssids[j].ssid_len;
9384 vos_mem_copy(SsidInfo->SSID.ssId, &request->ssids[j].ssid[0],
9385 SsidInfo->SSID.length);
9386 SsidInfo->SSID.ssId[SsidInfo->SSID.length] = '\0';
9387 hddLog(VOS_TRACE_LEVEL_INFO, "SSID number %d: %s",
9388 j, SsidInfo->SSID.ssId);
9389 }
9390 /* set the scan type to active */
9391 scanRequest.scanType = eSIR_ACTIVE_SCAN;
9392 }
9393 else if(WLAN_HDD_P2P_GO == pAdapter->device_mode)
Jeff Johnson295189b2012-06-20 16:38:30 -07009394 {
Siddharth Bhal0c162d02014-05-06 19:50:42 +05309395 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
9396 TRACE_CODE_HDD_CFG80211_SCAN,
9397 pAdapter->sessionId, 0));
Jeff Johnson295189b2012-06-20 16:38:30 -07009398 /* set the scan type to active */
9399 scanRequest.scanType = eSIR_ACTIVE_SCAN;
Jeff Johnson295189b2012-06-20 16:38:30 -07009400 }
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +05309401 else
9402 {
9403 /*Set the scan type to default type, in this case it is ACTIVE*/
9404 scanRequest.scanType = pScanInfo->scan_mode;
9405 }
9406 scanRequest.minChnTime = cfg_param->nActiveMinChnTime;
9407 scanRequest.maxChnTime = cfg_param->nActiveMaxChnTime;
Jeff Johnson295189b2012-06-20 16:38:30 -07009408
9409 /* set BSSType to default type */
9410 scanRequest.BSSType = eCSR_BSS_TYPE_ANY;
9411
9412 /*TODO: scan the requested channels only*/
9413
9414 /*Right now scanning all the channels */
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +05309415 if (MAX_CHANNEL < request->n_channels)
Jeff Johnson295189b2012-06-20 16:38:30 -07009416 {
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +05309417 hddLog(VOS_TRACE_LEVEL_WARN,
9418 "No of Scan Channels exceeded limit: %d", request->n_channels);
9419 request->n_channels = MAX_CHANNEL;
9420 }
9421
9422 hddLog(VOS_TRACE_LEVEL_INFO,
9423 "No of Scan Channels: %d", request->n_channels);
9424
9425
9426 if( request->n_channels )
9427 {
9428 char chList [(request->n_channels*5)+1];
9429 int len;
9430 channelList = vos_mem_malloc( request->n_channels );
9431 if( NULL == channelList )
c_hpothu53512302014-04-15 18:49:53 +05309432 {
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +05309433 hddLog(VOS_TRACE_LEVEL_ERROR,
9434 "%s: memory alloc failed channelList", __func__);
9435 status = -ENOMEM;
9436 goto free_mem;
c_hpothu53512302014-04-15 18:49:53 +05309437 }
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +05309438
9439 for( i = 0, len = 0; i < request->n_channels ; i++ )
9440 {
9441 channelList[i] = request->channels[i]->hw_value;
9442 len += snprintf(chList+len, 5, "%d ", channelList[i]);
9443 }
9444
Nirav Shah20ac06f2013-12-12 18:14:06 +05309445 hddLog(VOS_TRACE_LEVEL_INFO,
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +05309446 "Channel-List: %s ", chList);
9447 }
c_hpothu53512302014-04-15 18:49:53 +05309448
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +05309449 scanRequest.ChannelInfo.numOfChannels = request->n_channels;
9450 scanRequest.ChannelInfo.ChannelList = channelList;
9451
9452 /* set requestType to full scan */
9453 scanRequest.requestType = eCSR_SCAN_REQUEST_FULL_SCAN;
9454
9455 /* Flush the scan results(only p2p beacons) for STA scan and P2P
9456 * search (Flush on both full scan and social scan but not on single
9457 * channel scan).P2P search happens on 3 social channels (1, 6, 11)
9458 */
9459
9460 /* Supplicant does single channel scan after 8-way handshake
9461 * and in that case driver shoudnt flush scan results. If
9462 * driver flushes the scan results here and unfortunately if
9463 * the AP doesnt respond to our probe req then association
9464 * fails which is not desired
9465 */
9466
9467 if( request->n_channels != WLAN_HDD_P2P_SINGLE_CHANNEL_SCAN )
9468 {
9469 hddLog(VOS_TRACE_LEVEL_DEBUG, "Flushing P2P Results");
9470 sme_ScanFlushP2PResult( WLAN_HDD_GET_HAL_CTX(pAdapter),
9471 pAdapter->sessionId );
9472 }
9473
9474 if( request->ie_len )
9475 {
9476 /* save this for future association (join requires this) */
9477 /*TODO: Array needs to be converted to dynamic allocation,
9478 * as multiple ie.s can be sent in cfg80211_scan_request structure
9479 * CR 597966
9480 */
9481 memset( &pScanInfo->scanAddIE, 0, sizeof(pScanInfo->scanAddIE) );
9482 memcpy( pScanInfo->scanAddIE.addIEdata, request->ie, request->ie_len);
9483 pScanInfo->scanAddIE.length = request->ie_len;
9484
9485 if ((WLAN_HDD_INFRA_STATION == pAdapter->device_mode) ||
9486 (WLAN_HDD_P2P_CLIENT == pAdapter->device_mode) ||
9487 (WLAN_HDD_P2P_DEVICE == pAdapter->device_mode))
Jeff Johnson295189b2012-06-20 16:38:30 -07009488 {
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +05309489 if ( request->ie_len <= SIR_MAC_MAX_IE_LENGTH)
Jeff Johnson295189b2012-06-20 16:38:30 -07009490 {
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +05309491 pwextBuf->roamProfile.nAddIEScanLength = request->ie_len;
9492 memcpy( pwextBuf->roamProfile.addIEScan,
9493 request->ie, request->ie_len);
9494 }
9495 else
9496 {
9497 hddLog(VOS_TRACE_LEVEL_ERROR, "Scan Ie length is invalid:"
9498 "%zu", request->ie_len);
Jeff Johnson295189b2012-06-20 16:38:30 -07009499 }
9500
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +05309501 }
9502 scanRequest.uIEFieldLen = pScanInfo->scanAddIE.length;
9503 scanRequest.pIEField = pScanInfo->scanAddIE.addIEdata;
9504
9505 pP2pIe = wlan_hdd_get_p2p_ie_ptr((v_U8_t*)request->ie,
9506 request->ie_len);
9507 if (pP2pIe != NULL)
9508 {
9509#ifdef WLAN_FEATURE_P2P_DEBUG
9510 if (((globalP2PConnectionStatus == P2P_GO_NEG_COMPLETED) ||
9511 (globalP2PConnectionStatus == P2P_GO_NEG_PROCESS)) &&
9512 (WLAN_HDD_P2P_CLIENT == pAdapter->device_mode))
Nirav Shah20ac06f2013-12-12 18:14:06 +05309513 {
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +05309514 globalP2PConnectionStatus = P2P_CLIENT_CONNECTING_STATE_1;
9515 hddLog(VOS_TRACE_LEVEL_ERROR,"[P2P State] Changing state from "
9516 "Go nego completed to Connection is started");
9517 hddLog(VOS_TRACE_LEVEL_ERROR,"[P2P]P2P Scanning is started "
9518 "for 8way Handshake");
Nirav Shah20ac06f2013-12-12 18:14:06 +05309519 }
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +05309520 else if((globalP2PConnectionStatus == P2P_CLIENT_DISCONNECTED_STATE) &&
9521 (WLAN_HDD_P2P_CLIENT == pAdapter->device_mode))
Jeff Johnson295189b2012-06-20 16:38:30 -07009522 {
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +05309523 globalP2PConnectionStatus = P2P_CLIENT_CONNECTING_STATE_2;
9524 hddLog(VOS_TRACE_LEVEL_ERROR,"[P2P State] Changing state from "
9525 "Disconnected state to Connection is started");
9526 hddLog(VOS_TRACE_LEVEL_ERROR,"[P2P]P2P Scanning is started "
9527 "for 4way Handshake");
9528 }
9529#endif
9530
9531 /* no_cck will be set during p2p find to disable 11b rates */
9532 if(TRUE == request->no_cck)
9533 {
9534 hddLog(VOS_TRACE_LEVEL_INFO,
9535 "%s: This is a P2P Search", __func__);
9536 scanRequest.p2pSearch = 1;
9537
9538 if( request->n_channels == WLAN_HDD_P2P_SOCIAL_CHANNELS )
Agarwal Ashish4f616132013-12-30 23:32:50 +05309539 {
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +05309540 /* set requestType to P2P Discovery */
9541 scanRequest.requestType = eCSR_SCAN_P2P_DISCOVERY;
9542 }
9543
9544 /*
9545 Skip Dfs Channel in case of P2P Search
9546 if it is set in ini file
9547 */
9548 if(cfg_param->skipDfsChnlInP2pSearch)
9549 {
9550 scanRequest.skipDfsChnlInP2pSearch = 1;
Agarwal Ashish4f616132013-12-30 23:32:50 +05309551 }
9552 else
9553 {
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +05309554 scanRequest.skipDfsChnlInP2pSearch = 0;
Agarwal Ashish4f616132013-12-30 23:32:50 +05309555 }
Jeff Johnson295189b2012-06-20 16:38:30 -07009556
Agarwal Ashish4f616132013-12-30 23:32:50 +05309557 }
Jeff Johnson295189b2012-06-20 16:38:30 -07009558 }
9559 }
9560
9561 INIT_COMPLETION(pScanInfo->scan_req_completion_event);
9562
Madan Mohan Koyyalamudi9f5a10c2012-09-28 14:46:16 -07009563 /* acquire the wakelock to avoid the apps suspend during the scan. To
9564 * address the following issues.
9565 * 1) Disconnected scenario: we are not allowing the suspend as WLAN is not in
9566 * BMPS/IMPS this result in android trying to suspend aggressively and backing off
9567 * for long time, this result in apps running at full power for long time.
9568 * 2) Connected scenario: If we allow the suspend during the scan, RIVA will
9569 * be stuck in full power because of resume BMPS
9570 */
9571 hdd_prevent_suspend();
Jeff Johnsone7245742012-09-05 17:12:55 -07009572
Nirav Shah20ac06f2013-12-12 18:14:06 +05309573 hddLog(VOS_TRACE_LEVEL_INFO_HIGH,
9574 "requestType %d, scanType %d, minChnTime %d, maxChnTime %d,"
Sushant Kaushik8bc7df22014-04-09 17:55:29 +05309575 "p2pSearch %d, skipDfsChnlInP2pSearch %d",
9576 scanRequest.requestType, scanRequest.scanType,
9577 scanRequest.minChnTime, scanRequest.maxChnTime,
Nirav Shah20ac06f2013-12-12 18:14:06 +05309578 scanRequest.p2pSearch, scanRequest.skipDfsChnlInP2pSearch);
9579
Jeff Johnsone7245742012-09-05 17:12:55 -07009580 status = sme_ScanRequest( WLAN_HDD_GET_HAL_CTX(pAdapter),
Jeff Johnson295189b2012-06-20 16:38:30 -07009581 pAdapter->sessionId, &scanRequest, &scanId,
9582 &hdd_cfg80211_scan_done_callback, dev );
Jeff Johnsone7245742012-09-05 17:12:55 -07009583
Jeff Johnson295189b2012-06-20 16:38:30 -07009584 if (eHAL_STATUS_SUCCESS != status)
9585 {
9586 hddLog(VOS_TRACE_LEVEL_ERROR,
9587 "%s: sme_ScanRequest returned error %d", __func__, status);
9588 complete(&pScanInfo->scan_req_completion_event);
Madan Mohan Koyyalamudi3b230fe2012-10-18 14:46:32 -07009589 if(eHAL_STATUS_RESOURCES == status)
9590 {
Nirav Shah20ac06f2013-12-12 18:14:06 +05309591 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: HO is in progress."
9592 "So defer the scan by informing busy",__func__);
Madan Mohan Koyyalamudi3b230fe2012-10-18 14:46:32 -07009593 status = -EBUSY;
9594 } else {
9595 status = -EIO;
9596 }
Madan Mohan Koyyalamudi9f5a10c2012-09-28 14:46:16 -07009597 hdd_allow_suspend();
Jeff Johnson295189b2012-06-20 16:38:30 -07009598 goto free_mem;
9599 }
9600
9601 pScanInfo->mScanPending = TRUE;
9602 pAdapter->request = request;
9603 pScanInfo->scanId = scanId;
9604
9605 complete(&pScanInfo->scan_req_completion_event);
9606
9607free_mem:
9608 if( scanRequest.SSIDs.SSIDList )
9609 {
9610 vos_mem_free(scanRequest.SSIDs.SSIDList);
9611 }
9612
9613 if( channelList )
9614 vos_mem_free( channelList );
9615
9616 EXIT();
9617
9618 return status;
9619}
9620
Mahesh A Saptasagarfafb7fe2014-05-16 13:19:37 +05309621int wlan_hdd_cfg80211_scan( struct wiphy *wiphy,
9622#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,6,0))
9623 struct net_device *dev,
9624#endif
9625 struct cfg80211_scan_request *request)
9626{
9627 int ret;
9628
9629 vos_ssr_protect(__func__);
9630 ret = __wlan_hdd_cfg80211_scan(wiphy,
9631#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,6,0))
9632 dev,
9633#endif
9634 request);
9635 vos_ssr_unprotect(__func__);
9636
9637 return ret;
9638}
Shailender Karmuchi15cd0672013-05-15 19:50:04 -07009639
9640void hdd_select_cbmode( hdd_adapter_t *pAdapter,v_U8_t operationChannel)
9641{
9642 v_U8_t iniDot11Mode =
9643 (WLAN_HDD_GET_CTX(pAdapter))->cfg_ini->dot11Mode;
9644 eHddDot11Mode hddDot11Mode = iniDot11Mode;
9645
Arun Kumar Khandavalli94a2bb02013-12-28 19:17:25 +05309646 hddLog(LOG1, FL("Channel Bonding Mode Selected is %u"),
9647 iniDot11Mode);
Shailender Karmuchi15cd0672013-05-15 19:50:04 -07009648 switch ( iniDot11Mode )
9649 {
9650 case eHDD_DOT11_MODE_AUTO:
9651 case eHDD_DOT11_MODE_11ac:
9652 case eHDD_DOT11_MODE_11ac_ONLY:
9653#ifdef WLAN_FEATURE_11AC
Abhishek Singh4b1d2352014-08-01 21:59:28 +05309654 if ( sme_IsFeatureSupportedByDriver(DOT11AC) &&
9655 sme_IsFeatureSupportedByFW(DOT11AC) )
9656 hddDot11Mode = eHDD_DOT11_MODE_11ac;
9657 else
9658 hddDot11Mode = eHDD_DOT11_MODE_11n;
Shailender Karmuchi15cd0672013-05-15 19:50:04 -07009659#else
9660 hddDot11Mode = eHDD_DOT11_MODE_11n;
9661#endif
9662 break;
9663 case eHDD_DOT11_MODE_11n:
9664 case eHDD_DOT11_MODE_11n_ONLY:
9665 hddDot11Mode = eHDD_DOT11_MODE_11n;
9666 break;
9667 default:
9668 hddDot11Mode = iniDot11Mode;
9669 break;
9670 }
9671 /* This call decides required channel bonding mode */
9672 sme_SelectCBMode((WLAN_HDD_GET_CTX(pAdapter)->hHal),
9673 hdd_cfg_xlate_to_csr_phy_mode(hddDot11Mode),
9674 operationChannel);
9675}
9676
Jeff Johnson295189b2012-06-20 16:38:30 -07009677/*
9678 * FUNCTION: wlan_hdd_cfg80211_connect_start
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309679 * This function is used to start the association process
Jeff Johnson295189b2012-06-20 16:38:30 -07009680 */
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309681int wlan_hdd_cfg80211_connect_start( hdd_adapter_t *pAdapter,
Jeff Johnson32d95a32012-09-10 13:15:23 -07009682 const u8 *ssid, size_t ssid_len, const u8 *bssid, u8 operatingChannel)
Jeff Johnson295189b2012-06-20 16:38:30 -07009683{
9684 int status = 0;
9685 hdd_wext_state_t *pWextState;
Yue Mae36e3552014-03-05 17:06:20 -08009686 hdd_context_t *pHddCtx;
Jeff Johnson295189b2012-06-20 16:38:30 -07009687 v_U32_t roamId;
9688 tCsrRoamProfile *pRoamProfile;
Jeff Johnson295189b2012-06-20 16:38:30 -07009689 eCsrAuthType RSNAuthType;
9690
9691 ENTER();
9692
9693 pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
Yue Mae36e3552014-03-05 17:06:20 -08009694 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
9695
9696 status = wlan_hdd_validate_context(pHddCtx);
9697 if (status)
9698 {
9699 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
9700 "%s: HDD context is not valid!", __func__);
9701 return status;
9702 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309703
Jeff Johnson295189b2012-06-20 16:38:30 -07009704 if (SIR_MAC_MAX_SSID_LENGTH < ssid_len)
9705 {
9706 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: wrong SSID len", __func__);
9707 return -EINVAL;
9708 }
9709
9710 pRoamProfile = &pWextState->roamProfile;
9711
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309712 if (pRoamProfile)
Jeff Johnson295189b2012-06-20 16:38:30 -07009713 {
Jeff Johnsone7245742012-09-05 17:12:55 -07009714 hdd_station_ctx_t *pHddStaCtx;
9715 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
Jeff Johnson295189b2012-06-20 16:38:30 -07009716
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309717 if (HDD_WMM_USER_MODE_NO_QOS ==
Jeff Johnson295189b2012-06-20 16:38:30 -07009718 (WLAN_HDD_GET_CTX(pAdapter))->cfg_ini->WmmMode)
9719 {
9720 /*QoS not enabled in cfg file*/
9721 pRoamProfile->uapsd_mask = 0;
9722 }
9723 else
9724 {
9725 /*QoS enabled, update uapsd mask from cfg file*/
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309726 pRoamProfile->uapsd_mask =
Jeff Johnson295189b2012-06-20 16:38:30 -07009727 (WLAN_HDD_GET_CTX(pAdapter))->cfg_ini->UapsdMask;
9728 }
9729
9730 pRoamProfile->SSIDs.numOfSSIDs = 1;
9731 pRoamProfile->SSIDs.SSIDList->SSID.length = ssid_len;
9732 vos_mem_zero(pRoamProfile->SSIDs.SSIDList->SSID.ssId,
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309733 sizeof(pRoamProfile->SSIDs.SSIDList->SSID.ssId));
Jeff Johnson295189b2012-06-20 16:38:30 -07009734 vos_mem_copy((void *)(pRoamProfile->SSIDs.SSIDList->SSID.ssId),
9735 ssid, ssid_len);
9736
9737 if (bssid)
9738 {
9739 pRoamProfile->BSSIDs.numOfBSSIDs = 1;
9740 vos_mem_copy((void *)(pRoamProfile->BSSIDs.bssid), bssid,
9741 WNI_CFG_BSSID_LEN);
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309742 /* Save BSSID in seperate variable as well, as RoamProfile
9743 BSSID is getting zeroed out in the association process. And in
Jeff Johnson295189b2012-06-20 16:38:30 -07009744 case of join failure we should send valid BSSID to supplicant
9745 */
9746 vos_mem_copy((void *)(pWextState->req_bssId), bssid,
9747 WNI_CFG_BSSID_LEN);
9748 }
Dhanashri Atre51981c62013-06-13 11:47:57 -07009749 else
9750 {
9751 vos_mem_zero((void *)(pRoamProfile->BSSIDs.bssid),WNI_CFG_BSSID_LEN);
9752 }
Jeff Johnson295189b2012-06-20 16:38:30 -07009753
Arun Kumar Khandavalli94a2bb02013-12-28 19:17:25 +05309754 hddLog(LOG1, FL("Connect to SSID: %s opertating Channel: %u"),
9755 pRoamProfile->SSIDs.SSIDList->SSID.ssId, operatingChannel);
Jeff Johnson295189b2012-06-20 16:38:30 -07009756 if ((IW_AUTH_WPA_VERSION_WPA == pWextState->wpaVersion) ||
9757 (IW_AUTH_WPA_VERSION_WPA2 == pWextState->wpaVersion))
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309758 {
Jeff Johnson295189b2012-06-20 16:38:30 -07009759 /*set gen ie*/
9760 hdd_SetGENIEToCsr(pAdapter, &RSNAuthType);
9761 /*set auth*/
9762 hdd_set_csr_auth_type(pAdapter, RSNAuthType);
9763 }
Jeff Johnson295189b2012-06-20 16:38:30 -07009764#ifdef FEATURE_WLAN_WAPI
9765 if (pAdapter->wapi_info.nWapiMode)
9766 {
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07009767 hddLog(LOG1, "%s: Setting WAPI AUTH Type and Encryption Mode values", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07009768 switch (pAdapter->wapi_info.wapiAuthMode)
9769 {
9770 case WAPI_AUTH_MODE_PSK:
9771 {
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07009772 hddLog(LOG1, "%s: WAPI AUTH TYPE: PSK: %d", __func__,
Jeff Johnson295189b2012-06-20 16:38:30 -07009773 pAdapter->wapi_info.wapiAuthMode);
9774 pRoamProfile->AuthType.authType[0] = eCSR_AUTH_TYPE_WAPI_WAI_PSK;
9775 break;
9776 }
9777 case WAPI_AUTH_MODE_CERT:
9778 {
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07009779 hddLog(LOG1, "%s: WAPI AUTH TYPE: CERT: %d", __func__,
Jeff Johnson295189b2012-06-20 16:38:30 -07009780 pAdapter->wapi_info.wapiAuthMode);
9781 pRoamProfile->AuthType.authType[0] = eCSR_AUTH_TYPE_WAPI_WAI_CERTIFICATE;
9782 break;
9783 }
9784 } // End of switch
9785 if ( pAdapter->wapi_info.wapiAuthMode == WAPI_AUTH_MODE_PSK ||
9786 pAdapter->wapi_info.wapiAuthMode == WAPI_AUTH_MODE_CERT)
9787 {
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07009788 hddLog(LOG1, "%s: WAPI PAIRWISE/GROUP ENCRYPTION: WPI", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07009789 pRoamProfile->AuthType.numEntries = 1;
9790 pRoamProfile->EncryptionType.numEntries = 1;
9791 pRoamProfile->EncryptionType.encryptionType[0] = eCSR_ENCRYPT_TYPE_WPI;
9792 pRoamProfile->mcEncryptionType.numEntries = 1;
9793 pRoamProfile->mcEncryptionType.encryptionType[0] = eCSR_ENCRYPT_TYPE_WPI;
9794 }
9795 }
9796#endif /* FEATURE_WLAN_WAPI */
Gopichand Nakkala870cbae2013-03-15 21:16:09 +05309797#ifdef WLAN_FEATURE_GTK_OFFLOAD
Gopichand Nakkalad36ee622013-05-07 14:13:27 +05309798 /* Initializing gtkOffloadReqParams */
Gopichand Nakkala870cbae2013-03-15 21:16:09 +05309799 if ((WLAN_HDD_INFRA_STATION == pAdapter->device_mode) ||
9800 (WLAN_HDD_P2P_CLIENT == pAdapter->device_mode))
9801 {
Gopichand Nakkalad36ee622013-05-07 14:13:27 +05309802 memset(&pHddStaCtx->gtkOffloadReqParams, 0,
9803 sizeof (tSirGtkOffloadParams));
9804 pHddStaCtx->gtkOffloadReqParams.ulFlags = GTK_OFFLOAD_DISABLE;
Gopichand Nakkala870cbae2013-03-15 21:16:09 +05309805 }
9806#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07009807 pRoamProfile->csrPersona = pAdapter->device_mode;
9808
Jeff Johnson32d95a32012-09-10 13:15:23 -07009809 if( operatingChannel )
9810 {
9811 pRoamProfile->ChannelInfo.ChannelList = &operatingChannel;
9812 pRoamProfile->ChannelInfo.numOfChannels = 1;
9813 }
Chet Lanctot186b5732013-03-18 10:26:30 -07009814 else
9815 {
9816 pRoamProfile->ChannelInfo.ChannelList = NULL;
9817 pRoamProfile->ChannelInfo.numOfChannels = 0;
9818 }
Shailender Karmuchi15cd0672013-05-15 19:50:04 -07009819 if ( (WLAN_HDD_IBSS == pAdapter->device_mode) && operatingChannel)
9820 {
9821 hdd_select_cbmode(pAdapter,operatingChannel);
9822 }
Arun Kumar Khandavalli94a2bb02013-12-28 19:17:25 +05309823
Madan Mohan Koyyalamudi42dcd162012-12-03 16:34:04 -08009824 /* change conn_state to connecting before sme_RoamConnect(), because sme_RoamConnect()
9825 * has a direct path to call hdd_smeRoamCallback(), which will change the conn_state
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309826 * If direct path, conn_state will be accordingly changed to NotConnected or Associated
Madan Mohan Koyyalamudi42dcd162012-12-03 16:34:04 -08009827 * by either hdd_AssociationCompletionHandler() or hdd_DisConnectHandler() in sme_RoamCallback()
Madan Mohan Koyyalamudidf86c422012-12-04 17:03:44 -08009828 * if sme_RomConnect is to be queued, Connecting state will remain until it is completed.
9829 */
Gopichand Nakkalaa3c8fb62013-06-21 15:36:42 +05309830 if (WLAN_HDD_INFRA_STATION == pAdapter->device_mode ||
9831 WLAN_HDD_P2P_CLIENT == pAdapter->device_mode)
Abhishek Singhf4669da2014-05-26 15:07:49 +05309832 {
9833 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
9834 "%s: Set HDD connState to eConnectionState_Connecting",
9835 __func__);
Madan Mohan Koyyalamudidf86c422012-12-04 17:03:44 -08009836 hdd_connSetConnectionState(WLAN_HDD_GET_STATION_CTX_PTR(pAdapter),
9837 eConnectionState_Connecting);
Abhishek Singhf4669da2014-05-26 15:07:49 +05309838 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309839 status = sme_RoamConnect( WLAN_HDD_GET_HAL_CTX(pAdapter),
Jeff Johnson295189b2012-06-20 16:38:30 -07009840 pAdapter->sessionId, pRoamProfile, &roamId);
9841
Gopichand Nakkalaa3c8fb62013-06-21 15:36:42 +05309842 if ((eHAL_STATUS_SUCCESS != status) &&
9843 (WLAN_HDD_INFRA_STATION == pAdapter->device_mode ||
9844 WLAN_HDD_P2P_CLIENT == pAdapter->device_mode))
Madan Mohan Koyyalamudid5acbf52012-11-28 01:45:08 +05309845
9846 {
Madan Mohan Koyyalamudi42dcd162012-12-03 16:34:04 -08009847 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: sme_RoamConnect (session %d) failed with "
9848 "status %d. -> NotConnected", __func__, pAdapter->sessionId, status);
9849 /* change back to NotAssociated */
Madan Mohan Koyyalamudid5acbf52012-11-28 01:45:08 +05309850 hdd_connSetConnectionState(WLAN_HDD_GET_STATION_CTX_PTR(pAdapter),
Madan Mohan Koyyalamudi42dcd162012-12-03 16:34:04 -08009851 eConnectionState_NotConnected);
Madan Mohan Koyyalamudid5acbf52012-11-28 01:45:08 +05309852 }
Madan Mohan Koyyalamudidf86c422012-12-04 17:03:44 -08009853
9854 pRoamProfile->ChannelInfo.ChannelList = NULL;
9855 pRoamProfile->ChannelInfo.numOfChannels = 0;
9856
Jeff Johnson295189b2012-06-20 16:38:30 -07009857 }
9858 else
9859 {
9860 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: No valid Roam profile", __func__);
9861 return -EINVAL;
9862 }
Madan Mohan Koyyalamudifd4e1da2012-11-09 17:50:19 -08009863 EXIT();
Jeff Johnson295189b2012-06-20 16:38:30 -07009864 return status;
9865}
9866
9867/*
9868 * FUNCTION: wlan_hdd_set_cfg80211_auth_type
9869 * This function is used to set the authentication type (OPEN/SHARED).
9870 *
9871 */
9872static int wlan_hdd_cfg80211_set_auth_type(hdd_adapter_t *pAdapter,
9873 enum nl80211_auth_type auth_type)
9874{
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309875 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
Jeff Johnson295189b2012-06-20 16:38:30 -07009876 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
9877
9878 ENTER();
9879
9880 /*set authentication type*/
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309881 switch (auth_type)
Jeff Johnson295189b2012-06-20 16:38:30 -07009882 {
Jeff Johnson295189b2012-06-20 16:38:30 -07009883 case NL80211_AUTHTYPE_AUTOMATIC:
Gopichand Nakkala29149562013-05-10 21:43:41 +05309884 hddLog(VOS_TRACE_LEVEL_INFO,
9885 "%s: set authentication type to AUTOSWITCH", __func__);
9886 pHddStaCtx->conn_info.authType = eCSR_AUTH_TYPE_AUTOSWITCH;
9887 break;
9888
9889 case NL80211_AUTHTYPE_OPEN_SYSTEM:
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -07009890#ifdef WLAN_FEATURE_VOWIFI_11R
9891 case NL80211_AUTHTYPE_FT:
9892#endif /* WLAN_FEATURE_VOWIFI_11R */
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309893 hddLog(VOS_TRACE_LEVEL_INFO,
Jeff Johnson295189b2012-06-20 16:38:30 -07009894 "%s: set authentication type to OPEN", __func__);
9895 pHddStaCtx->conn_info.authType = eCSR_AUTH_TYPE_OPEN_SYSTEM;
9896 break;
9897
9898 case NL80211_AUTHTYPE_SHARED_KEY:
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309899 hddLog(VOS_TRACE_LEVEL_INFO,
Jeff Johnson295189b2012-06-20 16:38:30 -07009900 "%s: set authentication type to SHARED", __func__);
9901 pHddStaCtx->conn_info.authType = eCSR_AUTH_TYPE_SHARED_KEY;
9902 break;
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08009903#ifdef FEATURE_WLAN_ESE
Jeff Johnson295189b2012-06-20 16:38:30 -07009904 case NL80211_AUTHTYPE_NETWORK_EAP:
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309905 hddLog(VOS_TRACE_LEVEL_INFO,
Jeff Johnson295189b2012-06-20 16:38:30 -07009906 "%s: set authentication type to CCKM WPA", __func__);
9907 pHddStaCtx->conn_info.authType = eCSR_AUTH_TYPE_CCKM_WPA;//eCSR_AUTH_TYPE_CCKM_RSN needs to be handled as well if required.
9908 break;
9909#endif
9910
9911
9912 default:
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309913 hddLog(VOS_TRACE_LEVEL_ERROR,
9914 "%s: Unsupported authentication type %d", __func__,
Jeff Johnson295189b2012-06-20 16:38:30 -07009915 auth_type);
9916 pHddStaCtx->conn_info.authType = eCSR_AUTH_TYPE_UNKNOWN;
9917 return -EINVAL;
9918 }
9919
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309920 pWextState->roamProfile.AuthType.authType[0] =
Jeff Johnson295189b2012-06-20 16:38:30 -07009921 pHddStaCtx->conn_info.authType;
9922 return 0;
9923}
9924
9925/*
9926 * FUNCTION: wlan_hdd_set_akm_suite
9927 * This function is used to set the key mgmt type(PSK/8021x).
9928 *
9929 */
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309930static int wlan_hdd_set_akm_suite( hdd_adapter_t *pAdapter,
Jeff Johnson295189b2012-06-20 16:38:30 -07009931 u32 key_mgmt
9932 )
9933{
9934 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
9935 ENTER();
Abhishek Singhae408032014-09-25 17:22:04 +05309936 /* Should be in ieee802_11_defs.h */
9937#define WLAN_AKM_SUITE_8021X_SHA256 0x000FAC05
9938#define WLAN_AKM_SUITE_PSK_SHA256 0x000FAC06
Jeff Johnson295189b2012-06-20 16:38:30 -07009939 /*set key mgmt type*/
9940 switch(key_mgmt)
9941 {
9942 case WLAN_AKM_SUITE_PSK:
Abhishek Singhae408032014-09-25 17:22:04 +05309943 case WLAN_AKM_SUITE_PSK_SHA256:
Gopichand Nakkala356fb102013-03-06 12:34:04 +05309944#ifdef WLAN_FEATURE_VOWIFI_11R
9945 case WLAN_AKM_SUITE_FT_PSK:
9946#endif
9947 hddLog(VOS_TRACE_LEVEL_INFO, "%s: setting key mgmt type to PSK",
Jeff Johnson295189b2012-06-20 16:38:30 -07009948 __func__);
9949 pWextState->authKeyMgmt |= IW_AUTH_KEY_MGMT_PSK;
9950 break;
9951
9952 case WLAN_AKM_SUITE_8021X:
Abhishek Singhae408032014-09-25 17:22:04 +05309953 case WLAN_AKM_SUITE_8021X_SHA256:
Gopichand Nakkala356fb102013-03-06 12:34:04 +05309954#ifdef WLAN_FEATURE_VOWIFI_11R
9955 case WLAN_AKM_SUITE_FT_8021X:
9956#endif
9957 hddLog(VOS_TRACE_LEVEL_INFO, "%s: setting key mgmt type to 8021x",
Jeff Johnson295189b2012-06-20 16:38:30 -07009958 __func__);
9959 pWextState->authKeyMgmt |= IW_AUTH_KEY_MGMT_802_1X;
9960 break;
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08009961#ifdef FEATURE_WLAN_ESE
Jeff Johnson295189b2012-06-20 16:38:30 -07009962#define WLAN_AKM_SUITE_CCKM 0x00409600 /* Should be in ieee802_11_defs.h */
9963#define IW_AUTH_KEY_MGMT_CCKM 8 /* Should be in linux/wireless.h */
9964 case WLAN_AKM_SUITE_CCKM:
9965 hddLog(VOS_TRACE_LEVEL_INFO, "%s: setting key mgmt type to CCKM",
9966 __func__);
9967 pWextState->authKeyMgmt |= IW_AUTH_KEY_MGMT_CCKM;
9968 break;
9969#endif
Leela Venkata Kiran Kumar Reddy Chiralae208a832014-04-27 22:34:25 -07009970#ifndef WLAN_AKM_SUITE_OSEN
9971#define WLAN_AKM_SUITE_OSEN 0x506f9a01 /* Should be in ieee802_11_defs.h */
9972 case WLAN_AKM_SUITE_OSEN:
9973 hddLog(VOS_TRACE_LEVEL_INFO, "%s: setting key mgmt type to OSEN",
9974 __func__);
9975 pWextState->authKeyMgmt |= IW_AUTH_KEY_MGMT_802_1X;
9976 break;
9977#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07009978
9979 default:
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309980 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Unsupported key mgmt type %d",
Jeff Johnson295189b2012-06-20 16:38:30 -07009981 __func__, key_mgmt);
9982 return -EINVAL;
9983
9984 }
9985 return 0;
9986}
9987
9988/*
9989 * FUNCTION: wlan_hdd_cfg80211_set_cipher
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309990 * This function is used to set the encryption type
Jeff Johnson295189b2012-06-20 16:38:30 -07009991 * (NONE/WEP40/WEP104/TKIP/CCMP).
9992 */
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309993static int wlan_hdd_cfg80211_set_cipher( hdd_adapter_t *pAdapter,
9994 u32 cipher,
Jeff Johnson295189b2012-06-20 16:38:30 -07009995 bool ucast
9996 )
9997{
9998 eCsrEncryptionType encryptionType = eCSR_ENCRYPT_TYPE_NONE;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309999 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
Jeff Johnson295189b2012-06-20 16:38:30 -070010000 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
10001
10002 ENTER();
10003
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010004 if (!cipher)
Jeff Johnson295189b2012-06-20 16:38:30 -070010005 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010006 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: received cipher %d - considering none",
Jeff Johnson295189b2012-06-20 16:38:30 -070010007 __func__, cipher);
10008 encryptionType = eCSR_ENCRYPT_TYPE_NONE;
10009 }
10010 else
10011 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010012
Jeff Johnson295189b2012-06-20 16:38:30 -070010013 /*set encryption method*/
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010014 switch (cipher)
Jeff Johnson295189b2012-06-20 16:38:30 -070010015 {
10016 case IW_AUTH_CIPHER_NONE:
10017 encryptionType = eCSR_ENCRYPT_TYPE_NONE;
10018 break;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010019
Jeff Johnson295189b2012-06-20 16:38:30 -070010020 case WLAN_CIPHER_SUITE_WEP40:
Gopichand Nakkala29149562013-05-10 21:43:41 +053010021 encryptionType = eCSR_ENCRYPT_TYPE_WEP40;
Jeff Johnson295189b2012-06-20 16:38:30 -070010022 break;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010023
Jeff Johnson295189b2012-06-20 16:38:30 -070010024 case WLAN_CIPHER_SUITE_WEP104:
Gopichand Nakkala29149562013-05-10 21:43:41 +053010025 encryptionType = eCSR_ENCRYPT_TYPE_WEP104;
Jeff Johnson295189b2012-06-20 16:38:30 -070010026 break;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010027
Jeff Johnson295189b2012-06-20 16:38:30 -070010028 case WLAN_CIPHER_SUITE_TKIP:
10029 encryptionType = eCSR_ENCRYPT_TYPE_TKIP;
10030 break;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010031
Jeff Johnson295189b2012-06-20 16:38:30 -070010032 case WLAN_CIPHER_SUITE_CCMP:
10033 encryptionType = eCSR_ENCRYPT_TYPE_AES;
10034 break;
10035#ifdef FEATURE_WLAN_WAPI
10036 case WLAN_CIPHER_SUITE_SMS4:
10037 encryptionType = eCSR_ENCRYPT_TYPE_WPI;
10038 break;
10039#endif
10040
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -080010041#ifdef FEATURE_WLAN_ESE
Jeff Johnson295189b2012-06-20 16:38:30 -070010042 case WLAN_CIPHER_SUITE_KRK:
10043 encryptionType = eCSR_ENCRYPT_TYPE_KRK;
10044 break;
10045#endif
10046 default:
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010047 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Unsupported cipher type %d",
Jeff Johnson295189b2012-06-20 16:38:30 -070010048 __func__, cipher);
10049 return -EOPNOTSUPP;
10050 }
10051 }
10052
10053 if (ucast)
10054 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010055 hddLog(VOS_TRACE_LEVEL_INFO, "%s: setting unicast cipher type to %d",
Jeff Johnson295189b2012-06-20 16:38:30 -070010056 __func__, encryptionType);
10057 pHddStaCtx->conn_info.ucEncryptionType = encryptionType;
10058 pWextState->roamProfile.EncryptionType.numEntries = 1;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010059 pWextState->roamProfile.EncryptionType.encryptionType[0] =
Jeff Johnson295189b2012-06-20 16:38:30 -070010060 encryptionType;
10061 }
10062 else
10063 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010064 hddLog(VOS_TRACE_LEVEL_INFO, "%s: setting mcast cipher type to %d",
Jeff Johnson295189b2012-06-20 16:38:30 -070010065 __func__, encryptionType);
10066 pHddStaCtx->conn_info.mcEncryptionType = encryptionType;
10067 pWextState->roamProfile.mcEncryptionType.numEntries = 1;
10068 pWextState->roamProfile.mcEncryptionType.encryptionType[0] = encryptionType;
10069 }
10070
10071 return 0;
10072}
10073
10074
10075/*
10076 * FUNCTION: wlan_hdd_cfg80211_set_ie
10077 * This function is used to parse WPA/RSN IE's.
10078 */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010079int wlan_hdd_cfg80211_set_ie( hdd_adapter_t *pAdapter,
10080 u8 *ie,
Jeff Johnson295189b2012-06-20 16:38:30 -070010081 size_t ie_len
10082 )
10083{
10084 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
10085 u8 *genie = ie;
10086 v_U16_t remLen = ie_len;
10087#ifdef FEATURE_WLAN_WAPI
10088 v_U32_t akmsuite[MAX_NUM_AKM_SUITES];
10089 u16 *tmp;
10090 v_U16_t akmsuiteCount;
10091 int *akmlist;
10092#endif
10093 ENTER();
10094
10095 /* clear previous assocAddIE */
10096 pWextState->assocAddIE.length = 0;
10097 pWextState->roamProfile.bWPSAssociation = VOS_FALSE;
Leela Venkata Kiran Kumar Reddy Chiralaf257bef2014-04-11 18:48:12 -070010098 pWextState->roamProfile.bOSENAssociation = VOS_FALSE;
Jeff Johnson295189b2012-06-20 16:38:30 -070010099
10100 while (remLen >= 2)
10101 {
10102 v_U16_t eLen = 0;
10103 v_U8_t elementId;
10104 elementId = *genie++;
10105 eLen = *genie++;
10106 remLen -= 2;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010107
Arif Hussain6d2a3322013-11-17 19:50:10 -080010108 hddLog(VOS_TRACE_LEVEL_INFO, "%s: IE[0x%X], LEN[%d]",
Jeff Johnson295189b2012-06-20 16:38:30 -070010109 __func__, elementId, eLen);
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010110
10111 switch ( elementId )
Jeff Johnson295189b2012-06-20 16:38:30 -070010112 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010113 case DOT11F_EID_WPA:
Madan Mohan Koyyalamudief3b66e2012-10-11 14:29:42 -070010114 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 -070010115 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010116 hddLog(VOS_TRACE_LEVEL_ERROR,
Jeff Johnson295189b2012-06-20 16:38:30 -070010117 "%s: Invalid WPA IE", __func__);
10118 return -EINVAL;
10119 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010120 else if (0 == memcmp(&genie[0], "\x00\x50\xf2\x04", 4))
Jeff Johnson295189b2012-06-20 16:38:30 -070010121 {
10122 v_U16_t curAddIELen = pWextState->assocAddIE.length;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010123 hddLog (VOS_TRACE_LEVEL_INFO, "%s Set WPS IE(len %d)",
Jeff Johnson295189b2012-06-20 16:38:30 -070010124 __func__, eLen + 2);
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010125
Jeff Johnson295189b2012-06-20 16:38:30 -070010126 if( SIR_MAC_MAX_IE_LENGTH < (pWextState->assocAddIE.length + eLen) )
10127 {
Jeff Johnson902c9832012-12-10 14:28:09 -080010128 hddLog(VOS_TRACE_LEVEL_FATAL, "Cannot accommodate assocAddIE. "
10129 "Need bigger buffer space");
Jeff Johnson295189b2012-06-20 16:38:30 -070010130 VOS_ASSERT(0);
10131 return -ENOMEM;
10132 }
10133 // WSC IE is saved to Additional IE ; it should be accumulated to handle WPS IE + P2P IE
10134 memcpy( pWextState->assocAddIE.addIEdata + curAddIELen, genie - 2, eLen + 2);
10135 pWextState->assocAddIE.length += eLen + 2;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010136
Jeff Johnson295189b2012-06-20 16:38:30 -070010137 pWextState->roamProfile.bWPSAssociation = VOS_TRUE;
10138 pWextState->roamProfile.pAddIEAssoc = pWextState->assocAddIE.addIEdata;
10139 pWextState->roamProfile.nAddIEAssocLength = pWextState->assocAddIE.length;
10140 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010141 else if (0 == memcmp(&genie[0], "\x00\x50\xf2", 3))
10142 {
Jeff Johnson295189b2012-06-20 16:38:30 -070010143 hddLog (VOS_TRACE_LEVEL_INFO, "%s Set WPA IE (len %d)",__func__, eLen + 2);
10144 memset( pWextState->WPARSNIE, 0, MAX_WPA_RSN_IE_LEN );
10145 memcpy( pWextState->WPARSNIE, genie - 2, (eLen + 2) /*ie_len*/);
10146 pWextState->roamProfile.pWPAReqIE = pWextState->WPARSNIE;
10147 pWextState->roamProfile.nWPAReqIELength = eLen + 2;//ie_len;
10148 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010149 else if ( (0 == memcmp(&genie[0], P2P_OUI_TYPE,
Kiet Lam8da98992013-11-21 15:59:07 +053010150 P2P_OUI_TYPE_SIZE)))
Jeff Johnson295189b2012-06-20 16:38:30 -070010151 {
10152 v_U16_t curAddIELen = pWextState->assocAddIE.length;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010153 hddLog (VOS_TRACE_LEVEL_INFO, "%s Set P2P IE(len %d)",
Jeff Johnson295189b2012-06-20 16:38:30 -070010154 __func__, eLen + 2);
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010155
Jeff Johnson295189b2012-06-20 16:38:30 -070010156 if( SIR_MAC_MAX_IE_LENGTH < (pWextState->assocAddIE.length + eLen) )
10157 {
Jeff Johnson902c9832012-12-10 14:28:09 -080010158 hddLog(VOS_TRACE_LEVEL_FATAL, "Cannot accommodate assocAddIE "
10159 "Need bigger buffer space");
Jeff Johnson295189b2012-06-20 16:38:30 -070010160 VOS_ASSERT(0);
10161 return -ENOMEM;
10162 }
10163 // P2P IE is saved to Additional IE ; it should be accumulated to handle WPS IE + P2P IE
10164 memcpy( pWextState->assocAddIE.addIEdata + curAddIELen, genie - 2, eLen + 2);
10165 pWextState->assocAddIE.length += eLen + 2;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010166
Jeff Johnson295189b2012-06-20 16:38:30 -070010167 pWextState->roamProfile.pAddIEAssoc = pWextState->assocAddIE.addIEdata;
10168 pWextState->roamProfile.nAddIEAssocLength = pWextState->assocAddIE.length;
10169 }
Jeff Johnson295189b2012-06-20 16:38:30 -070010170#ifdef WLAN_FEATURE_WFD
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010171 else if ( (0 == memcmp(&genie[0], WFD_OUI_TYPE,
10172 WFD_OUI_TYPE_SIZE))
Jeff Johnson295189b2012-06-20 16:38:30 -070010173 /*Consider WFD IE, only for P2P Client */
10174 && (WLAN_HDD_P2P_CLIENT == pAdapter->device_mode) )
10175 {
10176 v_U16_t curAddIELen = pWextState->assocAddIE.length;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010177 hddLog (VOS_TRACE_LEVEL_INFO, "%s Set WFD IE(len %d)",
Jeff Johnson295189b2012-06-20 16:38:30 -070010178 __func__, eLen + 2);
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010179
Jeff Johnson295189b2012-06-20 16:38:30 -070010180 if( SIR_MAC_MAX_IE_LENGTH < (pWextState->assocAddIE.length + eLen) )
10181 {
Jeff Johnson902c9832012-12-10 14:28:09 -080010182 hddLog(VOS_TRACE_LEVEL_FATAL, "Cannot accommodate assocAddIE "
10183 "Need bigger buffer space");
Jeff Johnson295189b2012-06-20 16:38:30 -070010184 VOS_ASSERT(0);
10185 return -ENOMEM;
10186 }
10187 // WFD IE is saved to Additional IE ; it should be accumulated to handle
10188 // WPS IE + P2P IE + WFD IE
10189 memcpy( pWextState->assocAddIE.addIEdata + curAddIELen, genie - 2, eLen + 2);
10190 pWextState->assocAddIE.length += eLen + 2;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010191
Jeff Johnson295189b2012-06-20 16:38:30 -070010192 pWextState->roamProfile.pAddIEAssoc = pWextState->assocAddIE.addIEdata;
10193 pWextState->roamProfile.nAddIEAssocLength = pWextState->assocAddIE.length;
10194 }
10195#endif
Madan Mohan Koyyalamudief3b66e2012-10-11 14:29:42 -070010196 /* Appending HS 2.0 Indication Element in Assiciation Request */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010197 else if ( (0 == memcmp(&genie[0], HS20_OUI_TYPE,
Madan Mohan Koyyalamudi1bed5982012-10-22 14:38:06 -070010198 HS20_OUI_TYPE_SIZE)) )
10199 {
10200 v_U16_t curAddIELen = pWextState->assocAddIE.length;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010201 hddLog (VOS_TRACE_LEVEL_INFO, "%s Set HS20 IE(len %d)",
Madan Mohan Koyyalamudi1bed5982012-10-22 14:38:06 -070010202 __func__, eLen + 2);
Madan Mohan Koyyalamudief3b66e2012-10-11 14:29:42 -070010203
Madan Mohan Koyyalamudi1bed5982012-10-22 14:38:06 -070010204 if( SIR_MAC_MAX_IE_LENGTH < (pWextState->assocAddIE.length + eLen) )
10205 {
Jeff Johnson902c9832012-12-10 14:28:09 -080010206 hddLog(VOS_TRACE_LEVEL_FATAL, "Cannot accommodate assocAddIE "
10207 "Need bigger buffer space");
Madan Mohan Koyyalamudi1bed5982012-10-22 14:38:06 -070010208 VOS_ASSERT(0);
10209 return -ENOMEM;
10210 }
10211 memcpy( pWextState->assocAddIE.addIEdata + curAddIELen, genie - 2, eLen + 2);
10212 pWextState->assocAddIE.length += eLen + 2;
Madan Mohan Koyyalamudief3b66e2012-10-11 14:29:42 -070010213
Madan Mohan Koyyalamudi1bed5982012-10-22 14:38:06 -070010214 pWextState->roamProfile.pAddIEAssoc = pWextState->assocAddIE.addIEdata;
10215 pWextState->roamProfile.nAddIEAssocLength = pWextState->assocAddIE.length;
10216 }
Leela Venkata Kiran Kumar Reddy Chiralaf257bef2014-04-11 18:48:12 -070010217 /* Appending OSEN Information Element in Assiciation Request */
10218 else if ( (0 == memcmp(&genie[0], OSEN_OUI_TYPE,
10219 OSEN_OUI_TYPE_SIZE)) )
10220 {
10221 v_U16_t curAddIELen = pWextState->assocAddIE.length;
10222 hddLog (VOS_TRACE_LEVEL_INFO, "%s Set OSEN IE(len %d)",
10223 __func__, eLen + 2);
Madan Mohan Koyyalamudief3b66e2012-10-11 14:29:42 -070010224
Leela Venkata Kiran Kumar Reddy Chiralaf257bef2014-04-11 18:48:12 -070010225 if( SIR_MAC_MAX_IE_LENGTH < (pWextState->assocAddIE.length + eLen) )
10226 {
10227 hddLog(VOS_TRACE_LEVEL_FATAL, "Cannot accommodate assocAddIE "
10228 "Need bigger buffer space");
10229 VOS_ASSERT(0);
10230 return -ENOMEM;
10231 }
10232 memcpy( pWextState->assocAddIE.addIEdata + curAddIELen, genie - 2, eLen + 2);
10233 pWextState->assocAddIE.length += eLen + 2;
10234
10235 pWextState->roamProfile.bOSENAssociation = VOS_TRUE;
10236 pWextState->roamProfile.pAddIEAssoc = pWextState->assocAddIE.addIEdata;
10237 pWextState->roamProfile.nAddIEAssocLength = pWextState->assocAddIE.length;
10238 }
10239
10240 break;
Praveen Kumar Sirisilla7d68b7b2013-09-22 14:01:42 -070010241 if (WLAN_HDD_IBSS == pAdapter->device_mode) {
10242
10243 /* populating as ADDIE in beacon frames */
10244 if (ccmCfgSetStr(WLAN_HDD_GET_HAL_CTX(pAdapter),
10245 WNI_CFG_PROBE_RSP_BCN_ADDNIE_DATA, genie - 2, eLen + 2,
10246 NULL, eANI_BOOLEAN_FALSE)== eHAL_STATUS_SUCCESS)
10247 {
10248 if (ccmCfgSetInt(WLAN_HDD_GET_HAL_CTX(pAdapter),
10249 WNI_CFG_PROBE_RSP_BCN_ADDNIE_FLAG, 1,NULL,
10250 eANI_BOOLEAN_FALSE) == eHAL_STATUS_FAILURE)
10251 {
10252 hddLog(LOGE,
10253 "Coldn't pass "
10254 "WNI_CFG_PROBE_RSP_BCN_ADDNIE_FLAG to CCM");
10255 }
10256 }/* ccmCfgSetStr(,WNI_CFG_PROBE_RSP_BCN_ADDNIE_DATA, , )*/
10257 else
10258 hddLog(LOGE,
10259 "Could not pass on "
10260 "WNI_CFG_PROBE_RSP_BCN_ADDNIE_DATA to CCM");
10261
10262 /* IBSS mode doesn't contain params->proberesp_ies still
10263 beaconIE's need to be populated in probe response frames */
10264 if ( (NULL != (genie - 2)) && (0 != eLen + 2) )
10265 {
10266 u16 rem_probe_resp_ie_len = eLen + 2;
10267 u8 probe_rsp_ie_len[3] = {0};
10268 u8 counter = 0;
10269
10270 /* Check Probe Resp Length if it is greater then 255 then
10271 Store Probe Rsp IEs into WNI_CFG_PROBE_RSP_ADDNIE_DATA1
10272 & WNI_CFG_PROBE_RSP_ADDNIE_DATA2 CFG Variable As We are
10273 not able Store More then 255 bytes into One Variable */
10274
10275 while ((rem_probe_resp_ie_len > 0) && (counter < 3))
10276 {
10277 if (rem_probe_resp_ie_len > MAX_CFG_STRING_LEN)
10278 {
10279 probe_rsp_ie_len[counter++] = MAX_CFG_STRING_LEN;
10280 rem_probe_resp_ie_len -= MAX_CFG_STRING_LEN;
10281 }
10282 else
10283 {
10284 probe_rsp_ie_len[counter++] = rem_probe_resp_ie_len;
10285 rem_probe_resp_ie_len = 0;
10286 }
10287 }
10288
10289 rem_probe_resp_ie_len = 0;
10290
10291 if (probe_rsp_ie_len[0] > 0)
10292 {
10293 if (ccmCfgSetStr(WLAN_HDD_GET_HAL_CTX(pAdapter),
10294 WNI_CFG_PROBE_RSP_ADDNIE_DATA1,
10295 (tANI_U8*)(genie - 2),
10296 probe_rsp_ie_len[0], NULL,
10297 eANI_BOOLEAN_FALSE)
10298 == eHAL_STATUS_FAILURE)
10299 {
10300 hddLog(LOGE,
10301 "Could not pass"
10302 "on WNI_CFG_PROBE_RSP_ADDNIE_DATA1 to CCM");
10303 }
10304 rem_probe_resp_ie_len += probe_rsp_ie_len[0];
10305 }
10306
10307 if (probe_rsp_ie_len[1] > 0)
10308 {
10309 if (ccmCfgSetStr(WLAN_HDD_GET_HAL_CTX(pAdapter),
10310 WNI_CFG_PROBE_RSP_ADDNIE_DATA2,
10311 (tANI_U8*)(genie - (2 + rem_probe_resp_ie_len)),
10312 probe_rsp_ie_len[1], NULL,
10313 eANI_BOOLEAN_FALSE)
10314 == eHAL_STATUS_FAILURE)
10315 {
10316 hddLog(LOGE,
10317 "Could not pass"
10318 "on WNI_CFG_PROBE_RSP_ADDNIE_DATA2 to CCM");
10319 }
10320 rem_probe_resp_ie_len += probe_rsp_ie_len[1];
10321 }
10322
10323 if (probe_rsp_ie_len[2] > 0)
10324 {
10325 if (ccmCfgSetStr(WLAN_HDD_GET_HAL_CTX(pAdapter),
10326 WNI_CFG_PROBE_RSP_ADDNIE_DATA3,
10327 (tANI_U8*)(genie - (2 + rem_probe_resp_ie_len)),
10328 probe_rsp_ie_len[2], NULL,
10329 eANI_BOOLEAN_FALSE)
10330 == eHAL_STATUS_FAILURE)
10331 {
10332 hddLog(LOGE,
10333 "Could not pass"
10334 "on WNI_CFG_PROBE_RSP_ADDNIE_DATA3 to CCM");
10335 }
10336 rem_probe_resp_ie_len += probe_rsp_ie_len[2];
10337 }
10338
10339 if (ccmCfgSetInt(WLAN_HDD_GET_HAL_CTX(pAdapter),
10340 WNI_CFG_PROBE_RSP_ADDNIE_FLAG, 1,NULL,
10341 eANI_BOOLEAN_FALSE) == eHAL_STATUS_FAILURE)
10342 {
10343 hddLog(LOGE,
10344 "Could not pass"
10345 "on WNI_CFG_PROBE_RSP_ADDNIE_FLAG to CCM");
10346 }
10347 }
10348 else
10349 {
10350 // Reset WNI_CFG_PROBE_RSP Flags
10351 wlan_hdd_reset_prob_rspies(pAdapter);
10352
10353 hddLog(VOS_TRACE_LEVEL_INFO,
10354 "%s: No Probe Response IE received in set beacon",
10355 __func__);
10356 }
10357 } /* end of if (WLAN_HDD_IBSS == pAdapter->device_mode) */
Jeff Johnson295189b2012-06-20 16:38:30 -070010358 break;
10359 case DOT11F_EID_RSN:
10360 hddLog (VOS_TRACE_LEVEL_INFO, "%s Set RSN IE(len %d)",__func__, eLen + 2);
10361 memset( pWextState->WPARSNIE, 0, MAX_WPA_RSN_IE_LEN );
10362 memcpy( pWextState->WPARSNIE, genie - 2, (eLen + 2)/*ie_len*/);
10363 pWextState->roamProfile.pRSNReqIE = pWextState->WPARSNIE;
10364 pWextState->roamProfile.nRSNReqIELength = eLen + 2; //ie_len;
10365 break;
Madan Mohan Koyyalamudief3b66e2012-10-11 14:29:42 -070010366 /* Appending Extended Capabilities with Interworking bit set in Assoc Req */
10367 case DOT11F_EID_EXTCAP:
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010368 {
Madan Mohan Koyyalamudief3b66e2012-10-11 14:29:42 -070010369 v_U16_t curAddIELen = pWextState->assocAddIE.length;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010370 hddLog (VOS_TRACE_LEVEL_INFO, "%s Set Extended CAPS IE(len %d)",
Madan Mohan Koyyalamudief3b66e2012-10-11 14:29:42 -070010371 __func__, eLen + 2);
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010372
Madan Mohan Koyyalamudief3b66e2012-10-11 14:29:42 -070010373 if( SIR_MAC_MAX_IE_LENGTH < (pWextState->assocAddIE.length + eLen) )
10374 {
Jeff Johnson902c9832012-12-10 14:28:09 -080010375 hddLog(VOS_TRACE_LEVEL_FATAL, "Cannot accommodate assocAddIE "
10376 "Need bigger buffer space");
Madan Mohan Koyyalamudief3b66e2012-10-11 14:29:42 -070010377 VOS_ASSERT(0);
10378 return -ENOMEM;
10379 }
10380 memcpy( pWextState->assocAddIE.addIEdata + curAddIELen, genie - 2, eLen + 2);
10381 pWextState->assocAddIE.length += eLen + 2;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010382
Madan Mohan Koyyalamudief3b66e2012-10-11 14:29:42 -070010383 pWextState->roamProfile.pAddIEAssoc = pWextState->assocAddIE.addIEdata;
10384 pWextState->roamProfile.nAddIEAssocLength = pWextState->assocAddIE.length;
10385 break;
10386 }
Jeff Johnson295189b2012-06-20 16:38:30 -070010387#ifdef FEATURE_WLAN_WAPI
10388 case WLAN_EID_WAPI:
10389 pAdapter->wapi_info.nWapiMode = 1; //Setting WAPI Mode to ON=1
Jeff Johnson0299d0a2013-10-30 12:37:43 -070010390 hddLog(VOS_TRACE_LEVEL_INFO, "WAPI MODE IS %u",
Jeff Johnson295189b2012-06-20 16:38:30 -070010391 pAdapter->wapi_info.nWapiMode);
10392 tmp = (u16 *)ie;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010393 tmp = tmp + 2; // Skip element Id and Len, Version
Jeff Johnson295189b2012-06-20 16:38:30 -070010394 akmsuiteCount = WPA_GET_LE16(tmp);
10395 tmp = tmp + 1;
10396 akmlist = (int *)(tmp);
10397 if(akmsuiteCount <= MAX_NUM_AKM_SUITES)
10398 {
10399 memcpy(akmsuite, akmlist, (4*akmsuiteCount));
10400 }
10401 else
10402 {
Arif Hussain6d2a3322013-11-17 19:50:10 -080010403 hddLog(VOS_TRACE_LEVEL_FATAL, "Invalid akmSuite count");
Jeff Johnson295189b2012-06-20 16:38:30 -070010404 VOS_ASSERT(0);
10405 return -EINVAL;
10406 }
10407
10408 if (WAPI_PSK_AKM_SUITE == akmsuite[0])
10409 {
10410 hddLog(VOS_TRACE_LEVEL_INFO, "%s: WAPI AUTH MODE SET TO PSK",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -070010411 __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -070010412 pAdapter->wapi_info.wapiAuthMode = WAPI_AUTH_MODE_PSK;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010413 }
Jeff Johnson295189b2012-06-20 16:38:30 -070010414 if (WAPI_CERT_AKM_SUITE == akmsuite[0])
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010415 {
Jeff Johnson295189b2012-06-20 16:38:30 -070010416 hddLog(VOS_TRACE_LEVEL_INFO, "%s: WAPI AUTH MODE SET TO CERTIFICATE",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -070010417 __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -070010418 pAdapter->wapi_info.wapiAuthMode = WAPI_AUTH_MODE_CERT;
10419 }
10420 break;
10421#endif
10422 default:
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010423 hddLog (VOS_TRACE_LEVEL_ERROR,
Jeff Johnson295189b2012-06-20 16:38:30 -070010424 "%s Set UNKNOWN IE %X", __func__, elementId);
Madan Mohan Koyyalamudief3b66e2012-10-11 14:29:42 -070010425 /* when Unknown IE is received we should break and continue
10426 * to the next IE in the buffer instead we were returning
10427 * so changing this to break */
10428 break;
Jeff Johnson295189b2012-06-20 16:38:30 -070010429 }
10430 genie += eLen;
10431 remLen -= eLen;
10432 }
10433 EXIT();
10434 return 0;
10435}
10436
10437/*
Gopichand Nakkala18f0c262013-05-07 23:25:08 +053010438 * FUNCTION: hdd_isWPAIEPresent
10439 * Parse the received IE to find the WPA IE
10440 *
10441 */
10442static bool hdd_isWPAIEPresent(u8 *ie, u8 ie_len)
10443{
10444 v_U8_t eLen = 0;
10445 v_U16_t remLen = ie_len;
10446 v_U8_t elementId = 0;
10447
10448 while (remLen >= 2)
10449 {
10450 elementId = *ie++;
10451 eLen = *ie++;
10452 remLen -= 2;
10453 if (eLen > remLen)
10454 {
10455 hddLog(VOS_TRACE_LEVEL_ERROR,
10456 "%s: IE length is wrong %d", __func__, eLen);
10457 return FALSE;
10458 }
10459 if ((elementId == DOT11F_EID_WPA) && (remLen > 5))
10460 {
10461 /* OUI - 0x00 0X50 0XF2
10462 WPA Information Element - 0x01
10463 WPA version - 0x01*/
10464 if (0 == memcmp(&ie[0], "\x00\x50\xf2\x01\x01", 5))
10465 return TRUE;
10466 }
10467 ie += eLen;
10468 remLen -= eLen;
10469 }
10470 return FALSE;
10471}
10472
10473/*
Jeff Johnson295189b2012-06-20 16:38:30 -070010474 * FUNCTION: wlan_hdd_cfg80211_set_privacy
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010475 * This function is used to initialize the security
Jeff Johnson295189b2012-06-20 16:38:30 -070010476 * parameters during connect operation.
10477 */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010478int wlan_hdd_cfg80211_set_privacy( hdd_adapter_t *pAdapter,
Jeff Johnson295189b2012-06-20 16:38:30 -070010479 struct cfg80211_connect_params *req
10480 )
10481{
10482 int status = 0;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010483 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
Jeff Johnson295189b2012-06-20 16:38:30 -070010484 ENTER();
10485
10486 /*set wpa version*/
10487 pWextState->wpaVersion = IW_AUTH_WPA_VERSION_DISABLED;
10488
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010489 if (req->crypto.wpa_versions)
Jeff Johnson295189b2012-06-20 16:38:30 -070010490 {
Gopichand Nakkala781ded42013-06-28 12:10:45 +053010491 if (NL80211_WPA_VERSION_1 == req->crypto.wpa_versions)
Jeff Johnson295189b2012-06-20 16:38:30 -070010492 {
10493 pWextState->wpaVersion = IW_AUTH_WPA_VERSION_WPA;
10494 }
10495 else if (NL80211_WPA_VERSION_2 == req->crypto.wpa_versions)
10496 {
10497 pWextState->wpaVersion = IW_AUTH_WPA_VERSION_WPA2;
10498 }
10499 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010500
10501 hddLog(VOS_TRACE_LEVEL_INFO, "%s: set wpa version to %d", __func__,
Jeff Johnson295189b2012-06-20 16:38:30 -070010502 pWextState->wpaVersion);
10503
10504 /*set authentication type*/
10505 status = wlan_hdd_cfg80211_set_auth_type(pAdapter, req->auth_type);
10506
10507 if (0 > status)
10508 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010509 hddLog(VOS_TRACE_LEVEL_ERROR,
Jeff Johnson295189b2012-06-20 16:38:30 -070010510 "%s: failed to set authentication type ", __func__);
10511 return status;
10512 }
10513
10514 /*set key mgmt type*/
10515 if (req->crypto.n_akm_suites)
10516 {
10517 status = wlan_hdd_set_akm_suite(pAdapter, req->crypto.akm_suites[0]);
10518 if (0 > status)
10519 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010520 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: failed to set akm suite",
Jeff Johnson295189b2012-06-20 16:38:30 -070010521 __func__);
10522 return status;
10523 }
10524 }
10525
10526 /*set pairwise cipher type*/
10527 if (req->crypto.n_ciphers_pairwise)
10528 {
10529 status = wlan_hdd_cfg80211_set_cipher(pAdapter,
10530 req->crypto.ciphers_pairwise[0], true);
10531 if (0 > status)
10532 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010533 hddLog(VOS_TRACE_LEVEL_ERROR,
Jeff Johnson295189b2012-06-20 16:38:30 -070010534 "%s: failed to set unicast cipher type", __func__);
10535 return status;
10536 }
10537 }
10538 else
10539 {
10540 /*Reset previous cipher suite to none*/
10541 status = wlan_hdd_cfg80211_set_cipher(pAdapter, 0, true);
10542 if (0 > status)
10543 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010544 hddLog(VOS_TRACE_LEVEL_ERROR,
Jeff Johnson295189b2012-06-20 16:38:30 -070010545 "%s: failed to set unicast cipher type", __func__);
10546 return status;
10547 }
10548 }
10549
10550 /*set group cipher type*/
10551 status = wlan_hdd_cfg80211_set_cipher(pAdapter, req->crypto.cipher_group,
10552 false);
10553
10554 if (0 > status)
10555 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010556 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: failed to set mcast cipher type",
Jeff Johnson295189b2012-06-20 16:38:30 -070010557 __func__);
10558 return status;
10559 }
10560
Chet Lanctot186b5732013-03-18 10:26:30 -070010561#ifdef WLAN_FEATURE_11W
10562 pWextState->roamProfile.MFPEnabled = (req->mfp == NL80211_MFP_REQUIRED);
10563#endif
10564
Jeff Johnson295189b2012-06-20 16:38:30 -070010565 /*parse WPA/RSN IE, and set the correspoing fileds in Roam profile*/
10566 if (req->ie_len)
10567 {
10568 status = wlan_hdd_cfg80211_set_ie(pAdapter, req->ie, req->ie_len);
10569 if ( 0 > status)
10570 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010571 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: failed to parse the WPA/RSN IE",
Jeff Johnson295189b2012-06-20 16:38:30 -070010572 __func__);
10573 return status;
10574 }
10575 }
10576
10577 /*incase of WEP set default key information*/
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010578 if (req->key && req->key_len)
Jeff Johnson295189b2012-06-20 16:38:30 -070010579 {
10580 if ( (WLAN_CIPHER_SUITE_WEP40 == req->crypto.ciphers_pairwise[0])
10581 || (WLAN_CIPHER_SUITE_WEP104 == req->crypto.ciphers_pairwise[0])
10582 )
10583 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010584 if ( IW_AUTH_KEY_MGMT_802_1X
Jeff Johnson295189b2012-06-20 16:38:30 -070010585 == (pWextState->authKeyMgmt & IW_AUTH_KEY_MGMT_802_1X ))
10586 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010587 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Dynamic WEP not supported",
Jeff Johnson295189b2012-06-20 16:38:30 -070010588 __func__);
10589 return -EOPNOTSUPP;
10590 }
10591 else
10592 {
10593 u8 key_len = req->key_len;
10594 u8 key_idx = req->key_idx;
10595
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010596 if ((eCSR_SECURITY_WEP_KEYSIZE_MAX_BYTES >= key_len)
Jeff Johnson295189b2012-06-20 16:38:30 -070010597 && (CSR_MAX_NUM_KEY > key_idx)
10598 )
10599 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010600 hddLog(VOS_TRACE_LEVEL_INFO,
10601 "%s: setting default wep key, key_idx = %hu key_len %hu",
Jeff Johnson295189b2012-06-20 16:38:30 -070010602 __func__, key_idx, key_len);
10603 vos_mem_copy(
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010604 &pWextState->roamProfile.Keys.KeyMaterial[key_idx][0],
Jeff Johnson295189b2012-06-20 16:38:30 -070010605 req->key, key_len);
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010606 pWextState->roamProfile.Keys.KeyLength[key_idx] =
Jeff Johnson295189b2012-06-20 16:38:30 -070010607 (u8)key_len;
10608 pWextState->roamProfile.Keys.defaultIndex = (u8)key_idx;
10609 }
10610 }
10611 }
10612 }
10613
10614 return status;
10615}
10616
10617/*
Vinay Krishna Eranna21042322014-01-08 19:21:39 +053010618 * FUNCTION: wlan_hdd_try_disconnect
10619 * This function is used to disconnect from previous
10620 * connection
10621 */
10622static int wlan_hdd_try_disconnect( hdd_adapter_t *pAdapter )
10623{
10624 long ret = 0;
10625 hdd_station_ctx_t *pHddStaCtx;
10626 eMib_dot11DesiredBssType connectedBssType;
10627
10628 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
10629
10630 hdd_connGetConnectedBssType(pHddStaCtx,&connectedBssType );
10631
10632 if((eMib_dot11DesiredBssType_independent == connectedBssType) ||
10633 (eConnectionState_Associated == pHddStaCtx->conn_info.connState) ||
10634 (eConnectionState_IbssConnected == pHddStaCtx->conn_info.connState))
10635 {
10636 /* Issue disconnect to CSR */
10637 INIT_COMPLETION(pAdapter->disconnect_comp_var);
10638 if( eHAL_STATUS_SUCCESS ==
10639 sme_RoamDisconnect( WLAN_HDD_GET_HAL_CTX(pAdapter),
10640 pAdapter->sessionId,
10641 eCSR_DISCONNECT_REASON_UNSPECIFIED ) )
10642 {
10643 ret = wait_for_completion_interruptible_timeout(
10644 &pAdapter->disconnect_comp_var,
10645 msecs_to_jiffies(WLAN_WAIT_TIME_DISCONNECT));
10646 if (0 >= ret)
10647 {
10648 hddLog(LOGE, FL("Failed to receive disconnect event"));
10649 return -EALREADY;
10650 }
10651 }
10652 }
10653 else if(eConnectionState_Disconnecting == pHddStaCtx->conn_info.connState)
10654 {
10655 ret = wait_for_completion_interruptible_timeout(
10656 &pAdapter->disconnect_comp_var,
10657 msecs_to_jiffies(WLAN_WAIT_TIME_DISCONNECT));
10658 if (0 >= ret)
10659 {
10660 hddLog(LOGE, FL("Failed to receive disconnect event"));
10661 return -EALREADY;
10662 }
10663 }
10664
10665 return 0;
10666}
10667
10668/*
Agarwal Ashish51325b52014-06-16 16:50:49 +053010669 * FUNCTION: __wlan_hdd_cfg80211_connect
10670 * This function is used to start the association process
Jeff Johnson295189b2012-06-20 16:38:30 -070010671 */
Mahesh A Saptasagarfafb7fe2014-05-16 13:19:37 +053010672static int __wlan_hdd_cfg80211_connect( struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -070010673 struct net_device *ndev,
10674 struct cfg80211_connect_params *req
10675 )
10676{
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053010677 int status;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010678 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( ndev );
Jeff Johnson295189b2012-06-20 16:38:30 -070010679 VOS_STATUS exitbmpsStatus = VOS_STATUS_E_INVAL;
Sushant Kaushikba6764e2014-06-30 19:52:09 +053010680 hdd_context_t *pHddCtx = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -070010681
10682 ENTER();
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053010683
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053010684 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
10685 TRACE_CODE_HDD_CFG80211_CONNECT,
10686 pAdapter->sessionId, pAdapter->device_mode));
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010687 hddLog(VOS_TRACE_LEVEL_INFO,
Sushant Kaushik8bc7df22014-04-09 17:55:29 +053010688 "%s: device_mode = %s (%d)", __func__,
10689 hdd_device_modetoString(pAdapter->device_mode),
10690 pAdapter->device_mode);
Jeff Johnson295189b2012-06-20 16:38:30 -070010691
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053010692 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Rajesh Chauhana0516c62014-01-30 16:11:18 -080010693 if (!pHddCtx)
10694 {
10695 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
10696 "%s: HDD context is null", __func__);
Agarwal Ashish51325b52014-06-16 16:50:49 +053010697 return -EINVAL;
Rajesh Chauhana0516c62014-01-30 16:11:18 -080010698 }
10699
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053010700 status = wlan_hdd_validate_context(pHddCtx);
10701
10702 if (0 != status)
Jeff Johnson295189b2012-06-20 16:38:30 -070010703 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053010704 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
10705 "%s: HDD context is not valid", __func__);
10706 return status;
Jeff Johnson295189b2012-06-20 16:38:30 -070010707 }
10708
Agarwal Ashish51325b52014-06-16 16:50:49 +053010709 if (vos_max_concurrent_connections_reached()) {
10710 hddLog(VOS_TRACE_LEVEL_INFO, FL("Reached max concurrent connections"));
10711 return -ECONNREFUSED;
10712 }
10713
Jeff Johnson295189b2012-06-20 16:38:30 -070010714#ifdef WLAN_BTAMP_FEATURE
10715 //Infra connect not supported when AMP traffic is on.
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010716 if( VOS_TRUE == WLANBAP_AmpSessionOn() )
Jeff Johnson295189b2012-06-20 16:38:30 -070010717 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010718 hddLog(VOS_TRACE_LEVEL_ERROR,
Jeff Johnson295189b2012-06-20 16:38:30 -070010719 "%s: No connection when AMP is on", __func__);
Madan Mohan Koyyalamudicae253a2012-11-06 19:10:35 -080010720 return -ECONNREFUSED;
Jeff Johnson295189b2012-06-20 16:38:30 -070010721 }
10722#endif
Vinay Krishna Eranna21042322014-01-08 19:21:39 +053010723
10724 //If Device Mode is Station Concurrent Sessions Exit BMps
10725 //P2P Mode will be taken care in Open/close adapter
10726 if((WLAN_HDD_INFRA_STATION == pAdapter->device_mode) &&
Agarwal Ashish51325b52014-06-16 16:50:49 +053010727 (vos_concurrent_open_sessions_running())) {
10728 exitbmpsStatus = hdd_disable_bmps_imps(pHddCtx,
10729 WLAN_HDD_INFRA_STATION);
Vinay Krishna Eranna21042322014-01-08 19:21:39 +053010730 }
10731
10732 /*Try disconnecting if already in connected state*/
10733 status = wlan_hdd_try_disconnect(pAdapter);
10734 if ( 0 > status)
10735 {
10736 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Failed to disconnect the existing"
10737 " connection"));
10738 return -EALREADY;
10739 }
10740
Jeff Johnson295189b2012-06-20 16:38:30 -070010741 /*initialise security parameters*/
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010742 status = wlan_hdd_cfg80211_set_privacy(pAdapter, req);
Jeff Johnson295189b2012-06-20 16:38:30 -070010743
10744 if ( 0 > status)
10745 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010746 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: failed to set security params",
Jeff Johnson295189b2012-06-20 16:38:30 -070010747 __func__);
10748 return status;
10749 }
Mohit Khanna765234a2012-09-11 15:08:35 -070010750 if ( req->channel )
10751 {
10752 status = wlan_hdd_cfg80211_connect_start(pAdapter, req->ssid,
10753 req->ssid_len, req->bssid,
10754 req->channel->hw_value);
10755 }
10756 else
10757 {
10758 status = wlan_hdd_cfg80211_connect_start(pAdapter, req->ssid,
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053010759 req->ssid_len, req->bssid, 0);
Mohit Khanna765234a2012-09-11 15:08:35 -070010760 }
Jeff Johnson295189b2012-06-20 16:38:30 -070010761
10762 if (0 > status)
10763 {
10764 //ReEnable BMPS if disabled
10765 if((VOS_STATUS_SUCCESS == exitbmpsStatus) &&
10766 (NULL != pHddCtx))
10767 {
Gopichand Nakkalaa2fe5b02013-06-06 16:32:28 +053010768 if (pHddCtx->hdd_wlan_suspended)
10769 {
10770 hdd_set_pwrparams(pHddCtx);
10771 }
Jeff Johnson295189b2012-06-20 16:38:30 -070010772 //ReEnable Bmps and Imps back
10773 hdd_enable_bmps_imps(pHddCtx);
10774 }
Agarwal Ashish51325b52014-06-16 16:50:49 +053010775 hddLog(VOS_TRACE_LEVEL_ERROR, FL("connect failed"));
Jeff Johnson295189b2012-06-20 16:38:30 -070010776 return status;
10777 }
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053010778 pHddCtx->isAmpAllowed = VOS_FALSE;
Jeff Johnson295189b2012-06-20 16:38:30 -070010779 EXIT();
10780 return status;
10781}
10782
Mahesh A Saptasagarfafb7fe2014-05-16 13:19:37 +053010783static int wlan_hdd_cfg80211_connect( struct wiphy *wiphy,
10784 struct net_device *ndev,
10785 struct cfg80211_connect_params *req)
10786{
10787 int ret;
10788 vos_ssr_protect(__func__);
10789 ret = __wlan_hdd_cfg80211_connect(wiphy, ndev, req);
10790 vos_ssr_unprotect(__func__);
10791
10792 return ret;
10793}
Jeff Johnson295189b2012-06-20 16:38:30 -070010794
10795/*
Gopichand Nakkala78a6c812013-05-13 16:39:49 +053010796 * FUNCTION: wlan_hdd_disconnect
10797 * This function is used to issue a disconnect request to SME
10798 */
10799int wlan_hdd_disconnect( hdd_adapter_t *pAdapter, u16 reason )
10800{
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053010801 int status;
Gopichand Nakkala78a6c812013-05-13 16:39:49 +053010802 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053010803 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Abhishek Singhdc2bfd42014-06-19 17:59:05 +053010804 long ret;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053010805
10806 status = wlan_hdd_validate_context(pHddCtx);
10807
10808 if (0 != status)
10809 {
10810 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
10811 "%s: HDD context is not valid", __func__);
10812 return status;
10813 }
10814
10815 pHddCtx->isAmpAllowed = VOS_TRUE;
Agarwal Ashishc65b5ca2014-07-28 21:02:57 +053010816
Agarwal Ashish47d18112014-08-04 19:55:07 +053010817 /* Need to apply spin lock before decreasing active sessions
10818 * as there can be chance for double decrement if context switch
10819 * Calls hdd_DisConnectHandler.
10820 */
10821
10822 spin_lock_bh(&pAdapter->lock_for_active_session);
Agarwal Ashishc65b5ca2014-07-28 21:02:57 +053010823 if (eConnectionState_Associated == pHddStaCtx->conn_info.connState)
10824 {
Agarwal Ashishc65b5ca2014-07-28 21:02:57 +053010825 wlan_hdd_decr_active_session(pHddCtx, pAdapter->device_mode);
10826 }
Agarwal Ashish47d18112014-08-04 19:55:07 +053010827 hdd_connSetConnectionState( pHddStaCtx, eConnectionState_Disconnecting );
10828 spin_unlock_bh(&pAdapter->lock_for_active_session);
Agarwal Ashishc65b5ca2014-07-28 21:02:57 +053010829
Abhishek Singhf4669da2014-05-26 15:07:49 +053010830 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Agarwal Ashish47d18112014-08-04 19:55:07 +053010831 FL( "Set HDD connState to eConnectionState_Disconnecting" ));
10832
Gopichand Nakkala78a6c812013-05-13 16:39:49 +053010833 INIT_COMPLETION(pAdapter->disconnect_comp_var);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053010834
Mihir Shete182a0b22014-08-18 16:08:48 +053010835 /*
10836 * stop tx queues before deleting STA/BSS context from the firmware.
10837 * tx has to be disabled because the firmware can get busy dropping
10838 * the tx frames after BSS/STA has been deleted and will not send
10839 * back a response resulting in WDI timeout
10840 */
10841 netif_tx_disable(pAdapter->dev);
10842 netif_carrier_off(pAdapter->dev);
Arun Kumar Khandavalli94a2bb02013-12-28 19:17:25 +053010843
Mihir Shete182a0b22014-08-18 16:08:48 +053010844 /*issue disconnect*/
Gopichand Nakkala78a6c812013-05-13 16:39:49 +053010845 status = sme_RoamDisconnect( WLAN_HDD_GET_HAL_CTX(pAdapter),
10846 pAdapter->sessionId, reason);
Abhishek Singhdc2bfd42014-06-19 17:59:05 +053010847 if(eHAL_STATUS_CMD_NOT_QUEUED == status)
10848 {
10849 hddLog(VOS_TRACE_LEVEL_INFO,
10850 FL("status = %d, already disconnected"),
10851 (int)status );
Gopichand Nakkala78a6c812013-05-13 16:39:49 +053010852
Abhishek Singhdc2bfd42014-06-19 17:59:05 +053010853 }
10854 else if ( 0 != status )
Gopichand Nakkala78a6c812013-05-13 16:39:49 +053010855 {
10856 hddLog(VOS_TRACE_LEVEL_ERROR,
Arif Hussain6d2a3322013-11-17 19:50:10 -080010857 "%s csrRoamDisconnect failure, returned %d",
Gopichand Nakkala78a6c812013-05-13 16:39:49 +053010858 __func__, (int)status );
10859 return -EINVAL;
10860 }
Abhishek Singhdc2bfd42014-06-19 17:59:05 +053010861 ret = wait_for_completion_interruptible_timeout(
Gopichand Nakkala78a6c812013-05-13 16:39:49 +053010862 &pAdapter->disconnect_comp_var,
10863 msecs_to_jiffies(WLAN_WAIT_TIME_DISCONNECT));
Abhishek Singhdc2bfd42014-06-19 17:59:05 +053010864 if (!ret && ( eHAL_STATUS_CMD_NOT_QUEUED != status ))
c_hpothu6ff1c3c2013-10-01 19:01:57 +053010865 {
10866 hddLog(VOS_TRACE_LEVEL_ERROR,
Mahesh A Saptasagar05a357e2014-02-26 16:28:06 +053010867 "%s: Failed to disconnect, timed out", __func__);
10868 return -ETIMEDOUT;
10869 }
Abhishek Singhdc2bfd42014-06-19 17:59:05 +053010870 else if (ret == -ERESTARTSYS)
Mahesh A Saptasagar05a357e2014-02-26 16:28:06 +053010871 {
10872 hddLog(VOS_TRACE_LEVEL_ERROR,
10873 "%s: Failed to disconnect, wait interrupted", __func__);
Abhishek Singhdc2bfd42014-06-19 17:59:05 +053010874 return ret;
c_hpothu6ff1c3c2013-10-01 19:01:57 +053010875 }
Abhishek Singhdc2bfd42014-06-19 17:59:05 +053010876 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
10877 FL("Set HDD connState to eConnectionState_NotConnected"));
10878 pHddStaCtx->conn_info.connState = eConnectionState_NotConnected;
10879
Mahesh A Saptasagar05a357e2014-02-26 16:28:06 +053010880 return 0;
Gopichand Nakkala78a6c812013-05-13 16:39:49 +053010881}
10882
10883
10884/*
Mahesh A Saptasagarfafb7fe2014-05-16 13:19:37 +053010885 * FUNCTION: __wlan_hdd_cfg80211_disconnect
Jeff Johnson295189b2012-06-20 16:38:30 -070010886 * This function is used to issue a disconnect request to SME
10887 */
Mahesh A Saptasagarfafb7fe2014-05-16 13:19:37 +053010888static int __wlan_hdd_cfg80211_disconnect( struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -070010889 struct net_device *dev,
10890 u16 reason
10891 )
10892{
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010893 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( dev );
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053010894 tCsrRoamProfile *pRoamProfile =
10895 &(WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter))->roamProfile;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053010896 int status;
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053010897 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
10898 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Gopichand Nakkalaaa353782013-05-17 20:36:22 +053010899#ifdef FEATURE_WLAN_TDLS
Gopichand Nakkala2a0a1572013-02-10 21:39:16 -080010900 tANI_U8 staIdx;
10901#endif
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010902
Jeff Johnson295189b2012-06-20 16:38:30 -070010903 ENTER();
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053010904
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053010905 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
10906 TRACE_CODE_HDD_CFG80211_DISCONNECT,
10907 pAdapter->sessionId, reason));
Sushant Kaushik8bc7df22014-04-09 17:55:29 +053010908 hddLog(VOS_TRACE_LEVEL_INFO, "%s: device_mode = %s(%d)",
10909 __func__, hdd_device_modetoString(pAdapter->device_mode),
10910 pAdapter->device_mode);
Jeff Johnson295189b2012-06-20 16:38:30 -070010911
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010912 hddLog(VOS_TRACE_LEVEL_INFO, "%s: Disconnect called with reason code %d",
10913 __func__, reason);
Jeff Johnson295189b2012-06-20 16:38:30 -070010914
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053010915 status = wlan_hdd_validate_context(pHddCtx);
10916
10917 if (0 != status)
Jeff Johnson295189b2012-06-20 16:38:30 -070010918 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053010919 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
10920 "%s: HDD context is not valid", __func__);
10921 return status;
Jeff Johnson295189b2012-06-20 16:38:30 -070010922 }
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053010923
Jeff Johnson295189b2012-06-20 16:38:30 -070010924 if (NULL != pRoamProfile)
10925 {
10926 /*issue disconnect request to SME, if station is in connected state*/
Mahesh A Saptasagar280fd5a2013-12-05 15:38:31 +053010927 if ((pHddStaCtx->conn_info.connState == eConnectionState_Associated) ||
10928 (pHddStaCtx->conn_info.connState == eConnectionState_Connecting))
Jeff Johnson295189b2012-06-20 16:38:30 -070010929 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010930 eCsrRoamDisconnectReason reasonCode =
Jeff Johnson295189b2012-06-20 16:38:30 -070010931 eCSR_DISCONNECT_REASON_UNSPECIFIED;
Gopichand Nakkalaaa353782013-05-17 20:36:22 +053010932 hdd_scaninfo_t *pScanInfo;
Jeff Johnson295189b2012-06-20 16:38:30 -070010933 switch(reason)
10934 {
10935 case WLAN_REASON_MIC_FAILURE:
10936 reasonCode = eCSR_DISCONNECT_REASON_MIC_ERROR;
10937 break;
10938
10939 case WLAN_REASON_DISASSOC_DUE_TO_INACTIVITY:
10940 case WLAN_REASON_DISASSOC_AP_BUSY:
10941 case WLAN_REASON_CLASS3_FRAME_FROM_NONASSOC_STA:
10942 reasonCode = eCSR_DISCONNECT_REASON_DISASSOC;
10943 break;
10944
10945 case WLAN_REASON_PREV_AUTH_NOT_VALID:
10946 case WLAN_REASON_CLASS2_FRAME_FROM_NONAUTH_STA:
Abhishek Singhc3269a52014-05-21 17:22:24 +053010947 case WLAN_REASON_DEAUTH_LEAVING:
Jeff Johnson295189b2012-06-20 16:38:30 -070010948 reasonCode = eCSR_DISCONNECT_REASON_DEAUTH;
10949 break;
10950
Jeff Johnson295189b2012-06-20 16:38:30 -070010951 default:
10952 reasonCode = eCSR_DISCONNECT_REASON_UNSPECIFIED;
10953 break;
10954 }
Gopichand Nakkalaaa353782013-05-17 20:36:22 +053010955 pScanInfo = &pHddCtx->scan_info;
10956 if (pScanInfo->mScanPending)
10957 {
Srinivas, Dasari138af4f2014-02-07 11:13:45 +053010958 hddLog(VOS_TRACE_LEVEL_INFO, "Disconnect is in progress, "
Gopichand Nakkalaaa353782013-05-17 20:36:22 +053010959 "Aborting Scan");
Srinivas, Dasari138af4f2014-02-07 11:13:45 +053010960 hdd_abort_mac_scan(pHddCtx, pAdapter->sessionId,
10961 eCSR_SCAN_ABORT_DEFAULT);
Gopichand Nakkalaaa353782013-05-17 20:36:22 +053010962 }
Jeff Johnson295189b2012-06-20 16:38:30 -070010963
Gopichand Nakkala2a0a1572013-02-10 21:39:16 -080010964#ifdef FEATURE_WLAN_TDLS
10965 /* First clean up the tdls peers if any */
Gopichand Nakkala4327a152013-03-04 23:22:42 -080010966 for (staIdx = 0 ; staIdx < HDD_MAX_NUM_TDLS_STA; staIdx++)
Gopichand Nakkala2a0a1572013-02-10 21:39:16 -080010967 {
Gopichand Nakkala4327a152013-03-04 23:22:42 -080010968 if ((pHddCtx->tdlsConnInfo[staIdx].sessionId == pAdapter->sessionId) &&
10969 (pHddCtx->tdlsConnInfo[staIdx].staId))
Gopichand Nakkala2a0a1572013-02-10 21:39:16 -080010970 {
Hoonki Lee11f7dda2013-02-14 16:55:44 -080010971 uint8 *mac;
Gopichand Nakkala4327a152013-03-04 23:22:42 -080010972 mac = pHddCtx->tdlsConnInfo[staIdx].peerMac.bytes;
Hoonki Lee11f7dda2013-02-14 16:55:44 -080010973 VOS_TRACE(VOS_MODULE_ID_HDD, TDLS_LOG_LEVEL,
Gopichand Nakkalac87400e2013-03-13 18:51:00 -070010974 "%s: call sme_DeleteTdlsPeerSta staId %d sessionId %d " MAC_ADDRESS_STR,
Gopichand Nakkala4327a152013-03-04 23:22:42 -080010975 __func__, pHddCtx->tdlsConnInfo[staIdx].staId, pAdapter->sessionId,
Gopichand Nakkalac87400e2013-03-13 18:51:00 -070010976 MAC_ADDR_ARRAY(mac));
Gopichand Nakkala2a0a1572013-02-10 21:39:16 -080010977 sme_DeleteTdlsPeerSta(WLAN_HDD_GET_HAL_CTX(pAdapter),
Gopichand Nakkala4327a152013-03-04 23:22:42 -080010978 pAdapter->sessionId,
10979 mac);
Gopichand Nakkala2a0a1572013-02-10 21:39:16 -080010980 }
10981 }
10982#endif
Arun Kumar Khandavalli94a2bb02013-12-28 19:17:25 +053010983 hddLog(LOG1, FL("Disconnecting with reasoncode:%u"), reasonCode);
Gopichand Nakkala78a6c812013-05-13 16:39:49 +053010984 status = wlan_hdd_disconnect(pAdapter, reasonCode);
10985 if ( 0 != status )
Jeff Johnson295189b2012-06-20 16:38:30 -070010986 {
10987 hddLog(VOS_TRACE_LEVEL_ERROR,
Arif Hussain6d2a3322013-11-17 19:50:10 -080010988 "%s wlan_hdd_disconnect failure, returned %d",
Jeff Johnson295189b2012-06-20 16:38:30 -070010989 __func__, (int)status );
10990 return -EINVAL;
10991 }
Jeff Johnson295189b2012-06-20 16:38:30 -070010992 }
Mahesh A Saptasagar280fd5a2013-12-05 15:38:31 +053010993 else
10994 {
10995 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: unexpected cfg disconnect API"
10996 "called while in %d state", __func__,
10997 pHddStaCtx->conn_info.connState);
10998 }
Jeff Johnson295189b2012-06-20 16:38:30 -070010999 }
11000 else
11001 {
11002 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: No valid roam profile", __func__);
11003 }
11004
11005 return status;
11006}
11007
Mahesh A Saptasagarfafb7fe2014-05-16 13:19:37 +053011008static int wlan_hdd_cfg80211_disconnect( struct wiphy *wiphy,
11009 struct net_device *dev,
11010 u16 reason
11011 )
11012{
11013 int ret;
11014 vos_ssr_protect(__func__);
11015 ret = __wlan_hdd_cfg80211_disconnect(wiphy, dev, reason);
11016 vos_ssr_unprotect(__func__);
11017
11018 return ret;
11019}
Gopichand Nakkala78a6c812013-05-13 16:39:49 +053011020
Jeff Johnson295189b2012-06-20 16:38:30 -070011021/*
11022 * FUNCTION: wlan_hdd_cfg80211_set_privacy_ibss
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011023 * This function is used to initialize the security
Jeff Johnson295189b2012-06-20 16:38:30 -070011024 * settings in IBSS mode.
11025 */
11026static int wlan_hdd_cfg80211_set_privacy_ibss(
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011027 hdd_adapter_t *pAdapter,
Jeff Johnson295189b2012-06-20 16:38:30 -070011028 struct cfg80211_ibss_params *params
11029 )
11030{
11031 int status = 0;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011032 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
Jeff Johnson295189b2012-06-20 16:38:30 -070011033 eCsrEncryptionType encryptionType = eCSR_ENCRYPT_TYPE_NONE;
11034 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011035
Jeff Johnson295189b2012-06-20 16:38:30 -070011036 ENTER();
11037
11038 pWextState->wpaVersion = IW_AUTH_WPA_VERSION_DISABLED;
Ravi Joshib58ca0d2013-10-29 09:50:23 -070011039 vos_mem_zero(&pHddStaCtx->ibss_enc_key, sizeof(tCsrRoamSetKey));
Jeff Johnson295189b2012-06-20 16:38:30 -070011040
11041 if (params->ie_len && ( NULL != params->ie) )
11042 {
Shailender Karmuchi67edd312013-06-18 16:30:48 -070011043 if (wlan_hdd_cfg80211_get_ie_ptr (params->ie,
11044 params->ie_len, WLAN_EID_RSN ))
Jeff Johnson295189b2012-06-20 16:38:30 -070011045 {
11046 pWextState->wpaVersion = IW_AUTH_WPA_VERSION_WPA2;
11047 encryptionType = eCSR_ENCRYPT_TYPE_AES;
11048 }
Shailender Karmuchi67edd312013-06-18 16:30:48 -070011049 else if ( hdd_isWPAIEPresent (params->ie, params->ie_len ))
Jeff Johnson295189b2012-06-20 16:38:30 -070011050 {
Shailender Karmuchi642e9812013-05-30 14:34:49 -070011051 tDot11fIEWPA dot11WPAIE;
11052 tHalHandle halHandle = WLAN_HDD_GET_HAL_CTX(pAdapter);
Shailender Karmuchi67edd312013-06-18 16:30:48 -070011053 u8 *ie;
Shailender Karmuchi642e9812013-05-30 14:34:49 -070011054
Wilson Yang00256342013-10-10 23:13:38 -070011055 memset(&dot11WPAIE, 0, sizeof(dot11WPAIE));
Shailender Karmuchi67edd312013-06-18 16:30:48 -070011056 ie = wlan_hdd_cfg80211_get_ie_ptr (params->ie,
11057 params->ie_len, DOT11F_EID_WPA);
11058 if ( NULL != ie )
11059 {
11060 pWextState->wpaVersion = IW_AUTH_WPA_VERSION_WPA;
11061 // Unpack the WPA IE
11062 //Skip past the EID byte and length byte - and four byte WiFi OUI
11063 dot11fUnpackIeWPA((tpAniSirGlobal) halHandle,
11064 &ie[2+4],
11065 ie[1] - 4,
11066 &dot11WPAIE);
11067 /*Extract the multicast cipher, the encType for unicast
11068 cipher for wpa-none is none*/
11069 encryptionType =
11070 hdd_TranslateWPAToCsrEncryptionType(dot11WPAIE.multicast_cipher);
11071 }
Jeff Johnson295189b2012-06-20 16:38:30 -070011072 }
Shailender Karmuchi67edd312013-06-18 16:30:48 -070011073
Jeff Johnson295189b2012-06-20 16:38:30 -070011074 status = wlan_hdd_cfg80211_set_ie(pAdapter, params->ie, params->ie_len);
11075
11076 if (0 > status)
11077 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011078 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: failed to parse WPA/RSN IE",
Jeff Johnson295189b2012-06-20 16:38:30 -070011079 __func__);
11080 return status;
11081 }
11082 }
11083
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011084 pWextState->roamProfile.AuthType.authType[0] =
11085 pHddStaCtx->conn_info.authType =
Jeff Johnson295189b2012-06-20 16:38:30 -070011086 eCSR_AUTH_TYPE_OPEN_SYSTEM;
11087
11088 if (params->privacy)
11089 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011090 /* Security enabled IBSS, At this time there is no information available
11091 * about the security paramters, so initialise the encryption type to
Jeff Johnson295189b2012-06-20 16:38:30 -070011092 * eCSR_ENCRYPT_TYPE_WEP40_STATICKEY.
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011093 * The correct security parameters will be updated later in
Jeff Johnson295189b2012-06-20 16:38:30 -070011094 * wlan_hdd_cfg80211_add_key */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011095 /* Hal expects encryption type to be set inorder
Jeff Johnson295189b2012-06-20 16:38:30 -070011096 *enable privacy bit in beacons */
11097
11098 encryptionType = eCSR_ENCRYPT_TYPE_WEP40_STATICKEY;
11099 }
Shailender Karmuchi642e9812013-05-30 14:34:49 -070011100 VOS_TRACE (VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO_HIGH,
11101 "encryptionType=%d", encryptionType);
Jeff Johnson295189b2012-06-20 16:38:30 -070011102 pHddStaCtx->conn_info.ucEncryptionType = encryptionType;
11103 pWextState->roamProfile.EncryptionType.numEntries = 1;
11104 pWextState->roamProfile.EncryptionType.encryptionType[0] = encryptionType;
Jeff Johnson295189b2012-06-20 16:38:30 -070011105 return status;
11106}
11107
11108/*
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053011109 * FUNCTION: __wlan_hdd_cfg80211_join_ibss
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011110 * This function is used to create/join an IBSS
Jeff Johnson295189b2012-06-20 16:38:30 -070011111 */
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053011112static int __wlan_hdd_cfg80211_join_ibss( struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -070011113 struct net_device *dev,
11114 struct cfg80211_ibss_params *params
11115 )
11116{
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011117 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( dev );
Jeff Johnson295189b2012-06-20 16:38:30 -070011118 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
11119 tCsrRoamProfile *pRoamProfile;
11120 int status;
krunal sonie9002db2013-11-25 14:24:17 -080011121 bool alloc_bssid = VOS_FALSE;
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053011122 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
11123 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Jeff Johnson295189b2012-06-20 16:38:30 -070011124
11125 ENTER();
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053011126
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053011127 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
11128 TRACE_CODE_HDD_CFG80211_JOIN_IBSS,
11129 pAdapter->sessionId, pAdapter->device_mode));
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011130 hddLog(VOS_TRACE_LEVEL_INFO,
Sushant Kaushik8bc7df22014-04-09 17:55:29 +053011131 "%s: device_mode = %s (%d)", __func__,
11132 hdd_device_modetoString(pAdapter->device_mode),
11133 pAdapter->device_mode);
Jeff Johnson295189b2012-06-20 16:38:30 -070011134
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053011135 status = wlan_hdd_validate_context(pHddCtx);
11136
11137 if (0 != status)
Jeff Johnson295189b2012-06-20 16:38:30 -070011138 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053011139 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
11140 "%s: HDD context is not valid", __func__);
11141 return status;
Jeff Johnson295189b2012-06-20 16:38:30 -070011142 }
11143
11144 if (NULL == pWextState)
11145 {
Arif Hussain6d2a3322013-11-17 19:50:10 -080011146 hddLog (VOS_TRACE_LEVEL_ERROR, "%s ERROR: Data Storage Corruption",
Jeff Johnson295189b2012-06-20 16:38:30 -070011147 __func__);
11148 return -EIO;
11149 }
11150
Agarwal Ashish51325b52014-06-16 16:50:49 +053011151 if (vos_max_concurrent_connections_reached()) {
11152 hddLog(VOS_TRACE_LEVEL_INFO, FL("Reached max concurrent connections"));
11153 return -ECONNREFUSED;
11154 }
11155
Vinay Krishna Eranna21042322014-01-08 19:21:39 +053011156 /*Try disconnecting if already in connected state*/
11157 status = wlan_hdd_try_disconnect(pAdapter);
11158 if ( 0 > status)
11159 {
11160 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Failed to disconnect the existing"
11161 " IBSS connection"));
11162 return -EALREADY;
11163 }
11164
Jeff Johnson295189b2012-06-20 16:38:30 -070011165 pRoamProfile = &pWextState->roamProfile;
11166
11167 if ( eCSR_BSS_TYPE_START_IBSS != pRoamProfile->BSSType )
11168 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011169 hddLog (VOS_TRACE_LEVEL_ERROR,
Arif Hussain6d2a3322013-11-17 19:50:10 -080011170 "%s Interface type is not set to IBSS", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -070011171 return -EINVAL;
11172 }
11173
Praveen Kumar Sirisillad123d142013-09-24 16:50:13 -070011174 /* BSSID is provided by upper layers hence no need to AUTO generate */
11175 if (NULL != params->bssid) {
11176 if (ccmCfgSetInt(pHddCtx->hHal, WNI_CFG_IBSS_AUTO_BSSID, 0,
11177 NULL, eANI_BOOLEAN_FALSE)==eHAL_STATUS_FAILURE) {
11178 hddLog (VOS_TRACE_LEVEL_ERROR,
11179 "%s:ccmCfgStInt faild for WNI_CFG_IBSS_AUTO_BSSID", __func__);
11180 return -EIO;
11181 }
11182 }
krunal sonie9002db2013-11-25 14:24:17 -080011183 else if(pHddCtx->cfg_ini->isCoalesingInIBSSAllowed == 0)
11184 {
11185 if (ccmCfgSetInt(pHddCtx->hHal, WNI_CFG_IBSS_AUTO_BSSID, 0,
11186 NULL, eANI_BOOLEAN_FALSE)==eHAL_STATUS_FAILURE)
11187 {
11188 hddLog (VOS_TRACE_LEVEL_ERROR,
11189 "%s:ccmCfgStInt faild for WNI_CFG_IBSS_AUTO_BSSID", __func__);
11190 return -EIO;
11191 }
11192 params->bssid = vos_mem_malloc(sizeof(VOS_MAC_ADDR_SIZE));
11193 if (!params->bssid)
11194 {
11195 hddLog (VOS_TRACE_LEVEL_ERROR,
11196 "%s:Failed memory allocation", __func__);
11197 return -EIO;
11198 }
11199 vos_mem_copy((v_U8_t *)params->bssid,
11200 (v_U8_t *)&pHddCtx->cfg_ini->IbssBssid.bytes[0],
11201 VOS_MAC_ADDR_SIZE);
11202 alloc_bssid = VOS_TRUE;
11203 }
Praveen Kumar Sirisillad123d142013-09-24 16:50:13 -070011204
Jeff Johnson295189b2012-06-20 16:38:30 -070011205 /* Set Channel */
Yue Maf49ba872013-08-19 12:04:25 -070011206 if (NULL !=
11207#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,8,0))
11208 params->chandef.chan)
11209#else
11210 params->channel)
11211#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070011212 {
11213 u8 channelNum;
Shailender Karmuchi15cd0672013-05-15 19:50:04 -070011214 v_U32_t numChans = WNI_CFG_VALID_CHANNEL_LIST_LEN;
11215 v_U8_t validChan[WNI_CFG_VALID_CHANNEL_LIST_LEN];
11216 tHalHandle hHal = WLAN_HDD_GET_HAL_CTX(pAdapter);
11217 int indx;
Jeff Johnson295189b2012-06-20 16:38:30 -070011218
11219 /* Get channel number */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011220 channelNum =
Yue Maf49ba872013-08-19 12:04:25 -070011221 ieee80211_frequency_to_channel(
11222#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,8,0))
11223 params->chandef.chan->center_freq);
11224#else
11225 params->channel->center_freq);
11226#endif
Shailender Karmuchi15cd0672013-05-15 19:50:04 -070011227
11228 if (0 != ccmCfgGetStr(hHal, WNI_CFG_VALID_CHANNEL_LIST,
11229 validChan, &numChans))
Jeff Johnson295189b2012-06-20 16:38:30 -070011230 {
Shailender Karmuchi15cd0672013-05-15 19:50:04 -070011231 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: No valid channel list",
11232 __func__);
11233 return -EOPNOTSUPP;
Jeff Johnson295189b2012-06-20 16:38:30 -070011234 }
Shailender Karmuchi15cd0672013-05-15 19:50:04 -070011235
11236 for (indx = 0; indx < numChans; indx++)
Jeff Johnson295189b2012-06-20 16:38:30 -070011237 {
Shailender Karmuchi15cd0672013-05-15 19:50:04 -070011238 if (channelNum == validChan[indx])
11239 {
11240 break;
11241 }
11242 }
11243 if (indx >= numChans)
11244 {
11245 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Not valid Channel %d",
Jeff Johnson295189b2012-06-20 16:38:30 -070011246 __func__, channelNum);
11247 return -EINVAL;
11248 }
Shailender Karmuchi15cd0672013-05-15 19:50:04 -070011249 /* Set the Operational Channel */
11250 hddLog(VOS_TRACE_LEVEL_INFO_HIGH, "%s: set channel %d", __func__,
11251 channelNum);
11252 pRoamProfile->ChannelInfo.numOfChannels = 1;
11253 pHddStaCtx->conn_info.operationChannel = channelNum;
11254 pRoamProfile->ChannelInfo.ChannelList =
11255 &pHddStaCtx->conn_info.operationChannel;
Jeff Johnson295189b2012-06-20 16:38:30 -070011256 }
11257
11258 /* Initialize security parameters */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011259 status = wlan_hdd_cfg80211_set_privacy_ibss(pAdapter, params);
Jeff Johnson295189b2012-06-20 16:38:30 -070011260 if (status < 0)
11261 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011262 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: failed to set security parameters",
Jeff Johnson295189b2012-06-20 16:38:30 -070011263 __func__);
11264 return status;
11265 }
11266
11267 /* Issue connect start */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011268 status = wlan_hdd_cfg80211_connect_start(pAdapter, params->ssid,
Shailender Karmuchi15cd0672013-05-15 19:50:04 -070011269 params->ssid_len, params->bssid,
11270 pHddStaCtx->conn_info.operationChannel);
Jeff Johnson295189b2012-06-20 16:38:30 -070011271
11272 if (0 > status)
11273 {
11274 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: connect failed", __func__);
11275 return status;
11276 }
11277
krunal sonie9002db2013-11-25 14:24:17 -080011278 if (NULL != params->bssid &&
11279 pHddCtx->cfg_ini->isCoalesingInIBSSAllowed == 0 &&
11280 alloc_bssid == VOS_TRUE)
11281 {
11282 vos_mem_free(params->bssid);
11283 }
Jeff Johnson295189b2012-06-20 16:38:30 -070011284 return 0;
11285}
11286
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053011287static int wlan_hdd_cfg80211_join_ibss( struct wiphy *wiphy,
11288 struct net_device *dev,
11289 struct cfg80211_ibss_params *params
11290 )
11291{
11292 int ret = 0;
11293
11294 vos_ssr_protect(__func__);
11295 ret = __wlan_hdd_cfg80211_join_ibss(wiphy, dev, params);
11296 vos_ssr_unprotect(__func__);
11297
11298 return ret;
11299}
11300
Jeff Johnson295189b2012-06-20 16:38:30 -070011301/*
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053011302 * FUNCTION: __wlan_hdd_cfg80211_leave_ibss
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011303 * This function is used to leave an IBSS
Jeff Johnson295189b2012-06-20 16:38:30 -070011304 */
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053011305static int __wlan_hdd_cfg80211_leave_ibss( struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -070011306 struct net_device *dev
11307 )
11308{
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011309 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( dev );
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053011310 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
11311 tCsrRoamProfile *pRoamProfile;
11312 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053011313 int status;
Jeff Johnson295189b2012-06-20 16:38:30 -070011314
11315 ENTER();
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053011316
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053011317 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
11318 TRACE_CODE_HDD_CFG80211_LEAVE_IBSS,
11319 pAdapter->sessionId, eCSR_DISCONNECT_REASON_IBSS_LEAVE));
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053011320 status = wlan_hdd_validate_context(pHddCtx);
11321
11322 if (0 != status)
Jeff Johnson04dd8a82012-06-29 20:41:40 -070011323 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053011324 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
11325 "%s: HDD context is not valid", __func__);
11326 return status;
Jeff Johnson04dd8a82012-06-29 20:41:40 -070011327 }
11328
Sushant Kaushik8bc7df22014-04-09 17:55:29 +053011329 hddLog(VOS_TRACE_LEVEL_INFO, "%s: device_mode = %s (%d)", __func__,
11330 hdd_device_modetoString(pAdapter->device_mode),
11331 pAdapter->device_mode);
Jeff Johnson295189b2012-06-20 16:38:30 -070011332 if (NULL == pWextState)
11333 {
Arif Hussain6d2a3322013-11-17 19:50:10 -080011334 hddLog (VOS_TRACE_LEVEL_ERROR, "%s ERROR: Data Storage Corruption",
Jeff Johnson295189b2012-06-20 16:38:30 -070011335 __func__);
11336 return -EIO;
11337 }
11338
11339 pRoamProfile = &pWextState->roamProfile;
11340
11341 /* Issue disconnect only if interface type is set to IBSS */
11342 if (eCSR_BSS_TYPE_START_IBSS != pRoamProfile->BSSType)
11343 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011344 hddLog (VOS_TRACE_LEVEL_ERROR, "%s: BSS Type is not set to IBSS",
Jeff Johnson295189b2012-06-20 16:38:30 -070011345 __func__);
11346 return -EINVAL;
11347 }
11348
11349 /* Issue Disconnect request */
11350 INIT_COMPLETION(pAdapter->disconnect_comp_var);
11351 sme_RoamDisconnect( WLAN_HDD_GET_HAL_CTX(pAdapter), pAdapter->sessionId,
11352 eCSR_DISCONNECT_REASON_IBSS_LEAVE);
11353
11354 return 0;
11355}
11356
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053011357static int wlan_hdd_cfg80211_leave_ibss( struct wiphy *wiphy,
11358 struct net_device *dev
11359 )
11360{
11361 int ret = 0;
11362
11363 vos_ssr_protect(__func__);
11364 ret = __wlan_hdd_cfg80211_leave_ibss(wiphy, dev);
11365 vos_ssr_unprotect(__func__);
11366
11367 return ret;
11368}
11369
Jeff Johnson295189b2012-06-20 16:38:30 -070011370/*
Mahesh A Saptasagar179d2252014-06-02 21:32:21 +053011371 * FUNCTION: __wlan_hdd_cfg80211_set_wiphy_params
Jeff Johnson295189b2012-06-20 16:38:30 -070011372 * This function is used to set the phy parameters
11373 * (RTS Threshold/FRAG Threshold/Retry Count etc ...)
11374 */
Mahesh A Saptasagar179d2252014-06-02 21:32:21 +053011375static int __wlan_hdd_cfg80211_set_wiphy_params(struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -070011376 u32 changed)
11377{
11378 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
11379 tHalHandle hHal = pHddCtx->hHal;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053011380 int status;
Jeff Johnson295189b2012-06-20 16:38:30 -070011381
11382 ENTER();
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053011383 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
11384 TRACE_CODE_HDD_CFG80211_SET_WIPHY_PARAMS,
11385 NO_SESSION, wiphy->rts_threshold));
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053011386 status = wlan_hdd_validate_context(pHddCtx);
11387
11388 if (0 != status)
Jeff Johnson04dd8a82012-06-29 20:41:40 -070011389 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053011390 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
11391 "%s: HDD context is not valid", __func__);
11392 return status;
Jeff Johnson04dd8a82012-06-29 20:41:40 -070011393 }
11394
Jeff Johnson295189b2012-06-20 16:38:30 -070011395 if (changed & WIPHY_PARAM_RTS_THRESHOLD)
11396 {
11397 u16 rts_threshold = (wiphy->rts_threshold == -1) ?
11398 WNI_CFG_RTS_THRESHOLD_STAMAX :
11399 wiphy->rts_threshold;
11400
11401 if ((WNI_CFG_RTS_THRESHOLD_STAMIN > rts_threshold) ||
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011402 (WNI_CFG_RTS_THRESHOLD_STAMAX < rts_threshold))
Jeff Johnson295189b2012-06-20 16:38:30 -070011403 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011404 hddLog(VOS_TRACE_LEVEL_ERROR,
11405 "%s: Invalid RTS Threshold value %hu",
Jeff Johnson295189b2012-06-20 16:38:30 -070011406 __func__, rts_threshold);
11407 return -EINVAL;
11408 }
11409
11410 if (0 != ccmCfgSetInt(hHal, WNI_CFG_RTS_THRESHOLD,
11411 rts_threshold, ccmCfgSetCallback,
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011412 eANI_BOOLEAN_TRUE))
Jeff Johnson295189b2012-06-20 16:38:30 -070011413 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011414 hddLog(VOS_TRACE_LEVEL_ERROR,
11415 "%s: ccmCfgSetInt failed for rts_threshold value %hu",
Jeff Johnson295189b2012-06-20 16:38:30 -070011416 __func__, rts_threshold);
11417 return -EIO;
11418 }
11419
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011420 hddLog(VOS_TRACE_LEVEL_INFO_MED, "%s: set rts threshold %hu", __func__,
Jeff Johnson295189b2012-06-20 16:38:30 -070011421 rts_threshold);
11422 }
11423
11424 if (changed & WIPHY_PARAM_FRAG_THRESHOLD)
11425 {
11426 u16 frag_threshold = (wiphy->frag_threshold == -1) ?
11427 WNI_CFG_FRAGMENTATION_THRESHOLD_STAMAX :
11428 wiphy->frag_threshold;
11429
11430 if ((WNI_CFG_FRAGMENTATION_THRESHOLD_STAMIN > frag_threshold)||
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011431 (WNI_CFG_FRAGMENTATION_THRESHOLD_STAMAX < frag_threshold) )
Jeff Johnson295189b2012-06-20 16:38:30 -070011432 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011433 hddLog(VOS_TRACE_LEVEL_ERROR,
11434 "%s: Invalid frag_threshold value %hu", __func__,
Jeff Johnson295189b2012-06-20 16:38:30 -070011435 frag_threshold);
11436 return -EINVAL;
11437 }
11438
11439 if (0 != ccmCfgSetInt(hHal, WNI_CFG_FRAGMENTATION_THRESHOLD,
11440 frag_threshold, ccmCfgSetCallback,
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011441 eANI_BOOLEAN_TRUE))
Jeff Johnson295189b2012-06-20 16:38:30 -070011442 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011443 hddLog(VOS_TRACE_LEVEL_ERROR,
11444 "%s: ccmCfgSetInt failed for frag_threshold value %hu",
Jeff Johnson295189b2012-06-20 16:38:30 -070011445 __func__, frag_threshold);
11446 return -EIO;
11447 }
11448
11449 hddLog(VOS_TRACE_LEVEL_INFO_MED, "%s: set frag threshold %hu", __func__,
11450 frag_threshold);
11451 }
11452
11453 if ((changed & WIPHY_PARAM_RETRY_SHORT)
11454 || (changed & WIPHY_PARAM_RETRY_LONG))
11455 {
11456 u8 retry_value = (changed & WIPHY_PARAM_RETRY_SHORT) ?
11457 wiphy->retry_short :
11458 wiphy->retry_long;
11459
11460 if ((WNI_CFG_LONG_RETRY_LIMIT_STAMIN > retry_value) ||
11461 (WNI_CFG_LONG_RETRY_LIMIT_STAMAX < retry_value))
11462 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011463 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Invalid Retry count %hu",
Jeff Johnson295189b2012-06-20 16:38:30 -070011464 __func__, retry_value);
11465 return -EINVAL;
11466 }
11467
11468 if (changed & WIPHY_PARAM_RETRY_SHORT)
11469 {
11470 if (0 != ccmCfgSetInt(hHal, WNI_CFG_LONG_RETRY_LIMIT,
11471 retry_value, ccmCfgSetCallback,
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011472 eANI_BOOLEAN_TRUE))
Jeff Johnson295189b2012-06-20 16:38:30 -070011473 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011474 hddLog(VOS_TRACE_LEVEL_ERROR,
11475 "%s: ccmCfgSetInt failed for long retry count %hu",
Jeff Johnson295189b2012-06-20 16:38:30 -070011476 __func__, retry_value);
11477 return -EIO;
11478 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011479 hddLog(VOS_TRACE_LEVEL_INFO_MED, "%s: set long retry count %hu",
Jeff Johnson295189b2012-06-20 16:38:30 -070011480 __func__, retry_value);
11481 }
11482 else if (changed & WIPHY_PARAM_RETRY_SHORT)
11483 {
11484 if (0 != ccmCfgSetInt(hHal, WNI_CFG_SHORT_RETRY_LIMIT,
11485 retry_value, ccmCfgSetCallback,
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011486 eANI_BOOLEAN_TRUE))
Jeff Johnson295189b2012-06-20 16:38:30 -070011487 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011488 hddLog(VOS_TRACE_LEVEL_ERROR,
11489 "%s: ccmCfgSetInt failed for short retry count %hu",
Jeff Johnson295189b2012-06-20 16:38:30 -070011490 __func__, retry_value);
11491 return -EIO;
11492 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011493 hddLog(VOS_TRACE_LEVEL_INFO_MED, "%s: set short retry count %hu",
Jeff Johnson295189b2012-06-20 16:38:30 -070011494 __func__, retry_value);
11495 }
11496 }
11497
11498 return 0;
11499}
11500
Mahesh A Saptasagar179d2252014-06-02 21:32:21 +053011501static int wlan_hdd_cfg80211_set_wiphy_params(struct wiphy *wiphy,
11502 u32 changed)
11503{
11504 int ret;
11505
11506 vos_ssr_protect(__func__);
11507 ret = __wlan_hdd_cfg80211_set_wiphy_params(wiphy, changed);
11508 vos_ssr_unprotect(__func__);
11509
11510 return ret;
11511}
11512
Jeff Johnson295189b2012-06-20 16:38:30 -070011513/*
Mahesh A Saptasagar179d2252014-06-02 21:32:21 +053011514 * FUNCTION: __wlan_hdd_cfg80211_set_txpower
Jeff Johnson295189b2012-06-20 16:38:30 -070011515 * This function is used to set the txpower
11516 */
Mahesh A Saptasagar179d2252014-06-02 21:32:21 +053011517static int __wlan_hdd_cfg80211_set_txpower(struct wiphy *wiphy,
Yue Maf49ba872013-08-19 12:04:25 -070011518#if LINUX_VERSION_CODE >= KERNEL_VERSION(3,8,0)
11519 struct wireless_dev *wdev,
11520#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070011521#if LINUX_VERSION_CODE <= KERNEL_VERSION(2,6,35)
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011522 enum tx_power_setting type,
Jeff Johnson295189b2012-06-20 16:38:30 -070011523#else
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011524 enum nl80211_tx_power_setting type,
Jeff Johnson295189b2012-06-20 16:38:30 -070011525#endif
11526 int dbm)
11527{
11528 hdd_context_t *pHddCtx = (hdd_context_t*) wiphy_priv(wiphy);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053011529 tHalHandle hHal = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -070011530 tSirMacAddr bssid = {0xFF,0xFF,0xFF,0xFF,0xFF,0xFF};
11531 tSirMacAddr selfMac = {0xFF,0xFF,0xFF,0xFF,0xFF,0xFF};
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053011532 int status;
Jeff Johnson295189b2012-06-20 16:38:30 -070011533
11534 ENTER();
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053011535 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
11536 TRACE_CODE_HDD_CFG80211_SET_TXPOWER,
11537 NO_SESSION, type ));
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053011538 status = wlan_hdd_validate_context(pHddCtx);
11539
11540 if (0 != status)
11541 {
11542 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
11543 "%s: HDD context is not valid", __func__);
11544 return status;
11545 }
11546
11547 hHal = pHddCtx->hHal;
11548
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011549 if (0 != ccmCfgSetInt(hHal, WNI_CFG_CURRENT_TX_POWER_LEVEL,
11550 dbm, ccmCfgSetCallback,
11551 eANI_BOOLEAN_TRUE))
Jeff Johnson295189b2012-06-20 16:38:30 -070011552 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011553 hddLog(VOS_TRACE_LEVEL_ERROR,
Jeff Johnson295189b2012-06-20 16:38:30 -070011554 "%s: ccmCfgSetInt failed for tx power %hu", __func__, dbm);
11555 return -EIO;
11556 }
11557
11558 hddLog(VOS_TRACE_LEVEL_INFO_MED, "%s: set tx power level %d dbm", __func__,
11559 dbm);
11560
11561 switch(type)
11562 {
11563 case NL80211_TX_POWER_AUTOMATIC: /*automatically determine transmit power*/
11564 /* Fall through */
11565 case NL80211_TX_POWER_LIMITED: /*limit TX power by the mBm parameter*/
11566 if( sme_SetMaxTxPower(hHal, bssid, selfMac, dbm) != eHAL_STATUS_SUCCESS )
11567 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011568 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Setting maximum tx power failed",
11569 __func__);
11570 return -EIO;
Jeff Johnson295189b2012-06-20 16:38:30 -070011571 }
11572 break;
11573 case NL80211_TX_POWER_FIXED: /*fix TX power to the mBm parameter*/
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011574 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: NL80211_TX_POWER_FIXED not supported",
Jeff Johnson295189b2012-06-20 16:38:30 -070011575 __func__);
11576 return -EOPNOTSUPP;
11577 break;
11578 default:
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011579 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Invalid power setting type %d",
11580 __func__, type);
Jeff Johnson295189b2012-06-20 16:38:30 -070011581 return -EIO;
11582 }
11583
11584 return 0;
11585}
11586
Mahesh A Saptasagar179d2252014-06-02 21:32:21 +053011587static int wlan_hdd_cfg80211_set_txpower(struct wiphy *wiphy,
11588#if LINUX_VERSION_CODE >= KERNEL_VERSION(3,8,0)
11589 struct wireless_dev *wdev,
11590#endif
11591#if LINUX_VERSION_CODE <= KERNEL_VERSION(2,6,35)
11592 enum tx_power_setting type,
11593#else
11594 enum nl80211_tx_power_setting type,
11595#endif
11596 int dbm)
11597{
11598 int ret;
11599 vos_ssr_protect(__func__);
11600 ret = __wlan_hdd_cfg80211_set_txpower(wiphy,
11601#if LINUX_VERSION_CODE >= KERNEL_VERSION(3,8,0)
11602 wdev,
11603#endif
11604#if LINUX_VERSION_CODE <= KERNEL_VERSION(2,6,35)
11605 type,
11606#else
11607 type,
11608#endif
11609 dbm);
11610 vos_ssr_unprotect(__func__);
11611
11612 return ret;
11613}
11614
Jeff Johnson295189b2012-06-20 16:38:30 -070011615/*
11616 * FUNCTION: wlan_hdd_cfg80211_get_txpower
11617 * This function is used to read the txpower
11618 */
Yue Maf49ba872013-08-19 12:04:25 -070011619static int wlan_hdd_cfg80211_get_txpower(struct wiphy *wiphy,
11620#if LINUX_VERSION_CODE >= KERNEL_VERSION(3,8,0)
11621 struct wireless_dev *wdev,
11622#endif
11623 int *dbm)
Jeff Johnson295189b2012-06-20 16:38:30 -070011624{
11625
11626 hdd_adapter_t *pAdapter;
11627 hdd_context_t *pHddCtx = (hdd_context_t*) wiphy_priv(wiphy);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053011628 int status;
Jeff Johnson295189b2012-06-20 16:38:30 -070011629
Jeff Johnsone7245742012-09-05 17:12:55 -070011630 ENTER();
11631
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053011632 status = wlan_hdd_validate_context(pHddCtx);
Jeff Johnson295189b2012-06-20 16:38:30 -070011633
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053011634 if (0 != status)
Jeff Johnson04dd8a82012-06-29 20:41:40 -070011635 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053011636 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
11637 "%s: HDD context is not valid", __func__);
11638 *dbm = 0;
11639 return status;
Jeff Johnson04dd8a82012-06-29 20:41:40 -070011640 }
11641
Jeff Johnson295189b2012-06-20 16:38:30 -070011642 pAdapter = hdd_get_adapter(pHddCtx, WLAN_HDD_INFRA_STATION);
11643 if (NULL == pAdapter)
11644 {
11645 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: Not in station context " ,__func__);
11646 return -ENOENT;
11647 }
11648
11649 wlan_hdd_get_classAstats(pAdapter);
11650 *dbm = pAdapter->hdd_stats.ClassA_stat.max_pwr;
11651
Jeff Johnsone7245742012-09-05 17:12:55 -070011652 EXIT();
Jeff Johnson295189b2012-06-20 16:38:30 -070011653 return 0;
11654}
11655
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053011656static int __wlan_hdd_cfg80211_get_station(struct wiphy *wiphy, struct net_device *dev,
Jeff Johnson295189b2012-06-20 16:38:30 -070011657 u8* mac, struct station_info *sinfo)
11658{
11659 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( dev );
11660 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
11661 int ssidlen = pHddStaCtx->conn_info.SSID.SSID.length;
c_hpothu44ff4e02014-05-08 00:13:57 +053011662 tANI_U32 rate_flags;
Jeff Johnson295189b2012-06-20 16:38:30 -070011663
11664 hdd_context_t *pHddCtx = (hdd_context_t*) wiphy_priv(wiphy);
11665 hdd_config_t *pCfg = pHddCtx->cfg_ini;
Jeff Johnson295189b2012-06-20 16:38:30 -070011666
11667 tANI_U8 OperationalRates[CSR_DOT11_SUPPORTED_RATES_MAX];
11668 tANI_U32 ORLeng = CSR_DOT11_SUPPORTED_RATES_MAX;
11669 tANI_U8 ExtendedRates[CSR_DOT11_EXTENDED_SUPPORTED_RATES_MAX];
11670 tANI_U32 ERLeng = CSR_DOT11_EXTENDED_SUPPORTED_RATES_MAX;
11671 tANI_U8 MCSRates[SIZE_OF_BASIC_MCS_SET];
11672 tANI_U32 MCSLeng = SIZE_OF_BASIC_MCS_SET;
11673 tANI_U16 maxRate = 0;
11674 tANI_U16 myRate;
11675 tANI_U16 currentRate = 0;
11676 tANI_U8 maxSpeedMCS = 0;
11677 tANI_U8 maxMCSIdx = 0;
11678 tANI_U8 rateFlag = 1;
c_hpothu79aab322014-07-14 21:11:01 +053011679 tANI_U8 i, j, rssidx, mode=0;
Madan Mohan Koyyalamudic75be962012-10-18 19:19:03 -070011680 tANI_U16 temp;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053011681 int status;
Jeff Johnson295189b2012-06-20 16:38:30 -070011682
Leo Chang6f8870f2013-03-26 18:11:36 -070011683#ifdef WLAN_FEATURE_11AC
11684 tANI_U32 vht_mcs_map;
11685 eDataRate11ACMaxMcs vhtMaxMcs;
11686#endif /* WLAN_FEATURE_11AC */
11687
Jeff Johnsone7245742012-09-05 17:12:55 -070011688 ENTER();
11689
Jeff Johnson295189b2012-06-20 16:38:30 -070011690 if ((eConnectionState_Associated != pHddStaCtx->conn_info.connState) ||
11691 (0 == ssidlen))
11692 {
11693 hddLog(VOS_TRACE_LEVEL_INFO, "%s: Not associated or"
11694 " Invalid ssidlen, %d", __func__, ssidlen);
11695 /*To keep GUI happy*/
11696 return 0;
11697 }
11698
Mukul Sharma811205f2014-07-09 21:07:30 +053011699 if (VOS_TRUE == pHddStaCtx->hdd_ReassocScenario)
11700 {
11701 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
11702 "%s: Roaming in progress, so unable to proceed this request", __func__);
11703 return 0;
11704 }
11705
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053011706 status = wlan_hdd_validate_context(pHddCtx);
11707
11708 if (0 != status)
Jeff Johnson04dd8a82012-06-29 20:41:40 -070011709 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053011710 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
11711 "%s: HDD context is not valid", __func__);
11712 return status;
Jeff Johnson04dd8a82012-06-29 20:41:40 -070011713 }
11714
Jeff Johnson295189b2012-06-20 16:38:30 -070011715
Kiet Lam3b17fc82013-09-27 05:24:08 +053011716 wlan_hdd_get_rssi(pAdapter, &sinfo->signal);
11717 sinfo->filled |= STATION_INFO_SIGNAL;
11718
c_hpothu09f19542014-05-30 21:53:31 +053011719 wlan_hdd_get_station_stats(pAdapter);
11720 rate_flags = pAdapter->hdd_stats.ClassA_stat.tx_rate_flags;
11721
11722 /*overwrite rate_flags if MAX link-speed need to be reported*/
c_hpothu44ff4e02014-05-08 00:13:57 +053011723 if ((eHDD_LINK_SPEED_REPORT_MAX == pCfg->reportMaxLinkSpeed) ||
11724 (eHDD_LINK_SPEED_REPORT_MAX_SCALED == pCfg->reportMaxLinkSpeed &&
c_hpothu79aab322014-07-14 21:11:01 +053011725 sinfo->signal >= pCfg->linkSpeedRssiLow))
c_hpothu44ff4e02014-05-08 00:13:57 +053011726 {
11727 rate_flags = pAdapter->maxRateFlags;
11728 }
c_hpothu44ff4e02014-05-08 00:13:57 +053011729
Jeff Johnson295189b2012-06-20 16:38:30 -070011730 //convert to the UI units of 100kbps
11731 myRate = pAdapter->hdd_stats.ClassA_stat.tx_rate * 5;
11732
11733#ifdef LINKSPEED_DEBUG_ENABLED
Leo Chang6f8870f2013-03-26 18:11:36 -070011734 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 -070011735 sinfo->signal,
11736 pCfg->reportMaxLinkSpeed,
11737 myRate,
11738 (int) pCfg->linkSpeedRssiHigh,
Madan Mohan Koyyalamudi8df78d52012-11-02 12:30:06 -070011739 (int) pCfg->linkSpeedRssiMid,
11740 (int) pCfg->linkSpeedRssiLow,
Leo Chang6f8870f2013-03-26 18:11:36 -070011741 (int) rate_flags,
11742 (int) pAdapter->hdd_stats.ClassA_stat.mcs_index);
Jeff Johnson295189b2012-06-20 16:38:30 -070011743#endif //LINKSPEED_DEBUG_ENABLED
11744
11745 if (eHDD_LINK_SPEED_REPORT_ACTUAL != pCfg->reportMaxLinkSpeed)
11746 {
11747 // we do not want to necessarily report the current speed
11748 if (eHDD_LINK_SPEED_REPORT_MAX == pCfg->reportMaxLinkSpeed)
11749 {
11750 // report the max possible speed
11751 rssidx = 0;
11752 }
11753 else if (eHDD_LINK_SPEED_REPORT_MAX_SCALED == pCfg->reportMaxLinkSpeed)
11754 {
11755 // report the max possible speed with RSSI scaling
11756 if (sinfo->signal >= pCfg->linkSpeedRssiHigh)
11757 {
11758 // report the max possible speed
11759 rssidx = 0;
11760 }
Madan Mohan Koyyalamudi8df78d52012-11-02 12:30:06 -070011761 else if (sinfo->signal >= pCfg->linkSpeedRssiMid)
Jeff Johnson295189b2012-06-20 16:38:30 -070011762 {
11763 // report middle speed
11764 rssidx = 1;
11765 }
Madan Mohan Koyyalamudi8df78d52012-11-02 12:30:06 -070011766 else if (sinfo->signal >= pCfg->linkSpeedRssiLow)
11767 {
11768 // report middle speed
11769 rssidx = 2;
11770 }
Jeff Johnson295189b2012-06-20 16:38:30 -070011771 else
11772 {
11773 // report actual speed
Madan Mohan Koyyalamudi8df78d52012-11-02 12:30:06 -070011774 rssidx = 3;
Jeff Johnson295189b2012-06-20 16:38:30 -070011775 }
11776 }
11777 else
11778 {
11779 // unknown, treat as eHDD_LINK_SPEED_REPORT_MAX
11780 hddLog(VOS_TRACE_LEVEL_ERROR,
11781 "%s: Invalid value for reportMaxLinkSpeed: %u",
11782 __func__, pCfg->reportMaxLinkSpeed);
11783 rssidx = 0;
11784 }
11785
11786 maxRate = 0;
11787
11788 /* Get Basic Rate Set */
Gopichand Nakkala05ab1322013-02-15 11:28:38 +053011789 if (0 != ccmCfgGetStr(WLAN_HDD_GET_HAL_CTX(pAdapter), WNI_CFG_OPERATIONAL_RATE_SET,
11790 OperationalRates, &ORLeng))
11791 {
11792 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: ccm api returned failure", __func__);
11793 /*To keep GUI happy*/
11794 return 0;
11795 }
11796
Jeff Johnson295189b2012-06-20 16:38:30 -070011797 for (i = 0; i < ORLeng; i++)
11798 {
Jeff Johnsone7245742012-09-05 17:12:55 -070011799 for (j = 0; j < (sizeof(supported_data_rate) / sizeof(supported_data_rate[0])); j ++)
Jeff Johnson295189b2012-06-20 16:38:30 -070011800 {
11801 /* Validate Rate Set */
11802 if (supported_data_rate[j].beacon_rate_index == (OperationalRates[i] & 0x7F))
11803 {
11804 currentRate = supported_data_rate[j].supported_rate[rssidx];
11805 break;
11806 }
11807 }
11808 /* Update MAX rate */
11809 maxRate = (currentRate > maxRate)?currentRate:maxRate;
11810 }
11811
11812 /* Get Extended Rate Set */
Gopichand Nakkala05ab1322013-02-15 11:28:38 +053011813 if (0 != ccmCfgGetStr(WLAN_HDD_GET_HAL_CTX(pAdapter), WNI_CFG_EXTENDED_OPERATIONAL_RATE_SET,
11814 ExtendedRates, &ERLeng))
11815 {
11816 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: ccm api returned failure", __func__);
11817 /*To keep GUI happy*/
11818 return 0;
11819 }
11820
Jeff Johnson295189b2012-06-20 16:38:30 -070011821 for (i = 0; i < ERLeng; i++)
11822 {
Jeff Johnsone7245742012-09-05 17:12:55 -070011823 for (j = 0; j < (sizeof(supported_data_rate) / sizeof(supported_data_rate[0])); j ++)
Jeff Johnson295189b2012-06-20 16:38:30 -070011824 {
11825 if (supported_data_rate[j].beacon_rate_index == (ExtendedRates[i] & 0x7F))
11826 {
11827 currentRate = supported_data_rate[j].supported_rate[rssidx];
11828 break;
11829 }
11830 }
11831 /* Update MAX rate */
11832 maxRate = (currentRate > maxRate)?currentRate:maxRate;
11833 }
c_hpothu79aab322014-07-14 21:11:01 +053011834
Kiet Lamb69f8dc2013-11-15 15:34:27 +053011835 /* Get MCS Rate Set --
Kaushik, Sushantdc304d82014-01-22 10:58:37 +053011836 Only if we are always reporting max speed (or)
Kiet Lamb69f8dc2013-11-15 15:34:27 +053011837 if we have good rssi */
c_hpothu79aab322014-07-14 21:11:01 +053011838 if ((3 != rssidx) && !(rate_flags & eHAL_TX_RATE_LEGACY))
Jeff Johnson295189b2012-06-20 16:38:30 -070011839 {
c_hpothu79aab322014-07-14 21:11:01 +053011840 if (rate_flags & eHAL_TX_RATE_VHT80)
11841 mode = 2;
11842 else if (rate_flags & (eHAL_TX_RATE_VHT40 | eHAL_TX_RATE_HT40))
11843 mode = 1;
11844 else
11845 mode = 0;
11846
Gopichand Nakkala05ab1322013-02-15 11:28:38 +053011847 if (0 != ccmCfgGetStr(WLAN_HDD_GET_HAL_CTX(pAdapter), WNI_CFG_CURRENT_MCS_SET,
11848 MCSRates, &MCSLeng))
11849 {
11850 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: ccm api returned failure", __func__);
11851 /*To keep GUI happy*/
11852 return 0;
11853 }
Jeff Johnson295189b2012-06-20 16:38:30 -070011854 rateFlag = 0;
Leo Chang6f8870f2013-03-26 18:11:36 -070011855#ifdef WLAN_FEATURE_11AC
11856 /* VHT80 rate has seperate rate table */
Gopichand Nakkala4c705372013-04-24 13:20:33 +053011857 if (rate_flags & (eHAL_TX_RATE_VHT20|eHAL_TX_RATE_VHT40|eHAL_TX_RATE_VHT80))
Jeff Johnson295189b2012-06-20 16:38:30 -070011858 {
Leo Chang6f8870f2013-03-26 18:11:36 -070011859 ccmCfgGetInt(WLAN_HDD_GET_HAL_CTX(pAdapter), WNI_CFG_VHT_TX_MCS_MAP, &vht_mcs_map);
Gopichand Nakkala4c705372013-04-24 13:20:33 +053011860 vhtMaxMcs = (eDataRate11ACMaxMcs)(vht_mcs_map & DATA_RATE_11AC_MCS_MASK );
Leo Chang6f8870f2013-03-26 18:11:36 -070011861 if (rate_flags & eHAL_TX_RATE_SGI)
Jeff Johnson295189b2012-06-20 16:38:30 -070011862 {
Leo Chang6f8870f2013-03-26 18:11:36 -070011863 rateFlag |= 1;
Jeff Johnson295189b2012-06-20 16:38:30 -070011864 }
Leo Chang6f8870f2013-03-26 18:11:36 -070011865 if (DATA_RATE_11AC_MAX_MCS_7 == vhtMaxMcs)
Jeff Johnson295189b2012-06-20 16:38:30 -070011866 {
Leo Chang6f8870f2013-03-26 18:11:36 -070011867 maxMCSIdx = 7;
11868 }
11869 else if (DATA_RATE_11AC_MAX_MCS_8 == vhtMaxMcs)
11870 {
11871 maxMCSIdx = 8;
11872 }
11873 else if (DATA_RATE_11AC_MAX_MCS_9 == vhtMaxMcs)
11874 {
Gopichand Nakkala4c705372013-04-24 13:20:33 +053011875 //VHT20 is supporting 0~8
11876 if (rate_flags & eHAL_TX_RATE_VHT20)
11877 maxMCSIdx = 8;
11878 else
11879 maxMCSIdx = 9;
Leo Chang6f8870f2013-03-26 18:11:36 -070011880 }
Gopichand Nakkala4c705372013-04-24 13:20:33 +053011881
c_hpothu79aab322014-07-14 21:11:01 +053011882 if (0 != rssidx)/*check for scaled */
11883 {
11884 //get middle rate MCS index if rssi=1/2
11885 for (i=0; i <= maxMCSIdx; i++)
11886 {
11887 if (sinfo->signal <= rssiMcsTbl[mode][i])
11888 {
11889 maxMCSIdx = i;
11890 break;
11891 }
11892 }
11893 }
11894
Gopichand Nakkala4c705372013-04-24 13:20:33 +053011895 if (rate_flags & eHAL_TX_RATE_VHT80)
11896 {
11897 currentRate = supported_vht_mcs_rate[pAdapter->hdd_stats.ClassA_stat.mcs_index].supported_VHT80_rate[rateFlag];
11898 maxRate = supported_vht_mcs_rate[maxMCSIdx].supported_VHT80_rate[rateFlag];
11899 }
11900 else if (rate_flags & eHAL_TX_RATE_VHT40)
11901 {
11902 currentRate = supported_vht_mcs_rate[pAdapter->hdd_stats.ClassA_stat.mcs_index].supported_VHT40_rate[rateFlag];
11903 maxRate = supported_vht_mcs_rate[maxMCSIdx].supported_VHT40_rate[rateFlag];
11904 }
11905 else if (rate_flags & eHAL_TX_RATE_VHT20)
11906 {
11907 currentRate = supported_vht_mcs_rate[pAdapter->hdd_stats.ClassA_stat.mcs_index].supported_VHT20_rate[rateFlag];
11908 maxRate = supported_vht_mcs_rate[maxMCSIdx].supported_VHT20_rate[rateFlag];
11909 }
11910
Leo Chang6f8870f2013-03-26 18:11:36 -070011911 maxSpeedMCS = 1;
11912 if (currentRate > maxRate)
11913 {
11914 maxRate = currentRate;
11915 }
Gopichand Nakkala4c705372013-04-24 13:20:33 +053011916
Leo Chang6f8870f2013-03-26 18:11:36 -070011917 }
11918 else
11919#endif /* WLAN_FEATURE_11AC */
11920 {
11921 if (rate_flags & eHAL_TX_RATE_HT40)
11922 {
11923 rateFlag |= 1;
11924 }
11925 if (rate_flags & eHAL_TX_RATE_SGI)
11926 {
11927 rateFlag |= 2;
11928 }
11929
Girish Gowli01abcee2014-07-31 20:18:55 +053011930 temp = sizeof(supported_mcs_rate) / sizeof(supported_mcs_rate[0]);
c_hpothu79aab322014-07-14 21:11:01 +053011931 if (rssidx == 1 || rssidx == 2)
11932 {
11933 //get middle rate MCS index if rssi=1/2
11934 for (i=0; i <= 7; i++)
11935 {
11936 if (sinfo->signal <= rssiMcsTbl[mode][i])
11937 {
11938 temp = i+1;
11939 break;
11940 }
11941 }
11942 }
c_hpothu79aab322014-07-14 21:11:01 +053011943
11944 for (i = 0; i < MCSLeng; i++)
11945 {
Leo Chang6f8870f2013-03-26 18:11:36 -070011946 for (j = 0; j < temp; j++)
11947 {
11948 if (supported_mcs_rate[j].beacon_rate_index == MCSRates[i])
11949 {
11950 currentRate = supported_mcs_rate[j].supported_rate[rateFlag];
11951 break;
11952 }
11953 }
11954 if ((j < temp) && (currentRate > maxRate))
11955 {
11956 maxRate = currentRate;
11957 maxSpeedMCS = 1;
11958 maxMCSIdx = supported_mcs_rate[j].beacon_rate_index;
11959 }
Jeff Johnson295189b2012-06-20 16:38:30 -070011960 }
11961 }
11962 }
11963
Gopichand Nakkala4c705372013-04-24 13:20:33 +053011964 else if (!(rate_flags & eHAL_TX_RATE_LEGACY))
11965 {
11966 maxRate = myRate;
11967 maxSpeedMCS = 1;
11968 maxMCSIdx = pAdapter->hdd_stats.ClassA_stat.mcs_index;
11969 }
Jeff Johnson295189b2012-06-20 16:38:30 -070011970 // make sure we report a value at least as big as our current rate
c_hpothu79aab322014-07-14 21:11:01 +053011971 if ((maxRate < myRate) || (0 == maxRate))
Jeff Johnson295189b2012-06-20 16:38:30 -070011972 {
11973 maxRate = myRate;
11974 if (rate_flags & eHAL_TX_RATE_LEGACY)
11975 {
11976 maxSpeedMCS = 0;
11977 }
11978 else
11979 {
11980 maxSpeedMCS = 1;
11981 maxMCSIdx = pAdapter->hdd_stats.ClassA_stat.mcs_index;
11982 }
11983 }
11984
Gopichand Nakkala4c705372013-04-24 13:20:33 +053011985 if (rate_flags & eHAL_TX_RATE_LEGACY)
Jeff Johnson295189b2012-06-20 16:38:30 -070011986 {
11987 sinfo->txrate.legacy = maxRate;
11988#ifdef LINKSPEED_DEBUG_ENABLED
11989 pr_info("Reporting legacy rate %d\n", sinfo->txrate.legacy);
11990#endif //LINKSPEED_DEBUG_ENABLED
11991 }
11992 else
11993 {
11994 sinfo->txrate.mcs = maxMCSIdx;
Leo Chang6f8870f2013-03-26 18:11:36 -070011995#ifdef WLAN_FEATURE_11AC
11996 sinfo->txrate.nss = 1;
11997 if (rate_flags & eHAL_TX_RATE_VHT80)
11998 {
11999 sinfo->txrate.flags |= RATE_INFO_FLAGS_VHT_MCS;
Gopichand Nakkala4c705372013-04-24 13:20:33 +053012000 sinfo->txrate.flags |= RATE_INFO_FLAGS_80_MHZ_WIDTH;
Leo Chang6f8870f2013-03-26 18:11:36 -070012001 }
Gopichand Nakkala4c705372013-04-24 13:20:33 +053012002 else if (rate_flags & eHAL_TX_RATE_VHT40)
Leo Chang6f8870f2013-03-26 18:11:36 -070012003 {
Gopichand Nakkala4c705372013-04-24 13:20:33 +053012004 sinfo->txrate.flags |= RATE_INFO_FLAGS_VHT_MCS;
12005 sinfo->txrate.flags |= RATE_INFO_FLAGS_40_MHZ_WIDTH;
12006 }
12007 else if (rate_flags & eHAL_TX_RATE_VHT20)
12008 {
12009 sinfo->txrate.flags |= RATE_INFO_FLAGS_VHT_MCS;
12010 }
12011#endif /* WLAN_FEATURE_11AC */
12012 if (rate_flags & (eHAL_TX_RATE_HT20 | eHAL_TX_RATE_HT40))
12013 {
12014 sinfo->txrate.flags |= RATE_INFO_FLAGS_MCS;
12015 if (rate_flags & eHAL_TX_RATE_HT40)
12016 {
12017 sinfo->txrate.flags |= RATE_INFO_FLAGS_40_MHZ_WIDTH;
12018 }
Leo Chang6f8870f2013-03-26 18:11:36 -070012019 }
Jeff Johnson295189b2012-06-20 16:38:30 -070012020 if (rate_flags & eHAL_TX_RATE_SGI)
12021 {
12022 sinfo->txrate.flags |= RATE_INFO_FLAGS_SHORT_GI;
12023 }
Gopichand Nakkala4c705372013-04-24 13:20:33 +053012024
Jeff Johnson295189b2012-06-20 16:38:30 -070012025#ifdef LINKSPEED_DEBUG_ENABLED
12026 pr_info("Reporting MCS rate %d flags %x\n",
12027 sinfo->txrate.mcs,
12028 sinfo->txrate.flags );
12029#endif //LINKSPEED_DEBUG_ENABLED
12030 }
12031 }
12032 else
12033 {
12034 // report current rate instead of max rate
12035
12036 if (rate_flags & eHAL_TX_RATE_LEGACY)
12037 {
12038 //provide to the UI in units of 100kbps
12039 sinfo->txrate.legacy = myRate;
12040#ifdef LINKSPEED_DEBUG_ENABLED
12041 pr_info("Reporting actual legacy rate %d\n", sinfo->txrate.legacy);
12042#endif //LINKSPEED_DEBUG_ENABLED
12043 }
12044 else
12045 {
12046 //must be MCS
12047 sinfo->txrate.mcs = pAdapter->hdd_stats.ClassA_stat.mcs_index;
Leo Chang6f8870f2013-03-26 18:11:36 -070012048#ifdef WLAN_FEATURE_11AC
12049 sinfo->txrate.nss = 1;
12050 if (rate_flags & eHAL_TX_RATE_VHT80)
12051 {
12052 sinfo->txrate.flags |= RATE_INFO_FLAGS_VHT_MCS;
12053 }
12054 else
12055#endif /* WLAN_FEATURE_11AC */
12056 {
12057 sinfo->txrate.flags |= RATE_INFO_FLAGS_MCS;
12058 }
Jeff Johnson295189b2012-06-20 16:38:30 -070012059 if (rate_flags & eHAL_TX_RATE_SGI)
12060 {
12061 sinfo->txrate.flags |= RATE_INFO_FLAGS_SHORT_GI;
12062 }
12063 if (rate_flags & eHAL_TX_RATE_HT40)
12064 {
12065 sinfo->txrate.flags |= RATE_INFO_FLAGS_40_MHZ_WIDTH;
12066 }
Leo Chang6f8870f2013-03-26 18:11:36 -070012067#ifdef WLAN_FEATURE_11AC
12068 else if (rate_flags & eHAL_TX_RATE_VHT80)
12069 {
12070 sinfo->txrate.flags |= RATE_INFO_FLAGS_80_MHZ_WIDTH;
12071 }
12072#endif /* WLAN_FEATURE_11AC */
Jeff Johnson295189b2012-06-20 16:38:30 -070012073#ifdef LINKSPEED_DEBUG_ENABLED
12074 pr_info("Reporting actual MCS rate %d flags %x\n",
12075 sinfo->txrate.mcs,
12076 sinfo->txrate.flags );
12077#endif //LINKSPEED_DEBUG_ENABLED
12078 }
12079 }
12080 sinfo->filled |= STATION_INFO_TX_BITRATE;
12081
Madan Mohan Koyyalamudi4d4d2812012-09-24 14:08:29 -070012082 sinfo->tx_packets =
12083 pAdapter->hdd_stats.summary_stat.tx_frm_cnt[0] +
12084 pAdapter->hdd_stats.summary_stat.tx_frm_cnt[1] +
12085 pAdapter->hdd_stats.summary_stat.tx_frm_cnt[2] +
12086 pAdapter->hdd_stats.summary_stat.tx_frm_cnt[3];
12087
12088 sinfo->tx_retries =
12089 pAdapter->hdd_stats.summary_stat.retry_cnt[0] +
12090 pAdapter->hdd_stats.summary_stat.retry_cnt[1] +
12091 pAdapter->hdd_stats.summary_stat.retry_cnt[2] +
12092 pAdapter->hdd_stats.summary_stat.retry_cnt[3];
12093
12094 sinfo->tx_failed =
12095 pAdapter->hdd_stats.summary_stat.fail_cnt[0] +
12096 pAdapter->hdd_stats.summary_stat.fail_cnt[1] +
12097 pAdapter->hdd_stats.summary_stat.fail_cnt[2] +
12098 pAdapter->hdd_stats.summary_stat.fail_cnt[3];
12099
12100 sinfo->filled |=
12101 STATION_INFO_TX_PACKETS |
12102 STATION_INFO_TX_RETRIES |
12103 STATION_INFO_TX_FAILED;
12104
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053012105 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
12106 TRACE_CODE_HDD_CFG80211_GET_STA,
12107 pAdapter->sessionId, maxRate));
Madan Mohan Koyyalamudi4d4d2812012-09-24 14:08:29 -070012108 EXIT();
12109 return 0;
Jeff Johnson295189b2012-06-20 16:38:30 -070012110}
12111
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053012112static int wlan_hdd_cfg80211_get_station(struct wiphy *wiphy, struct net_device *dev,
12113 u8* mac, struct station_info *sinfo)
12114{
12115 int ret;
12116
12117 vos_ssr_protect(__func__);
12118 ret = __wlan_hdd_cfg80211_get_station(wiphy, dev, mac, sinfo);
12119 vos_ssr_unprotect(__func__);
12120
12121 return ret;
12122}
12123
12124static int __wlan_hdd_cfg80211_set_power_mgmt(struct wiphy *wiphy,
Sameer Thalappilc9f26e92013-06-07 10:11:06 -070012125 struct net_device *dev, bool mode, int timeout)
Jeff Johnson295189b2012-06-20 16:38:30 -070012126{
12127 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
Gopichand Nakkala20c4c042013-04-19 22:08:55 +053012128 hdd_context_t *pHddCtx;
Jeff Johnson295189b2012-06-20 16:38:30 -070012129 VOS_STATUS vos_status;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053012130 int status;
Jeff Johnson295189b2012-06-20 16:38:30 -070012131
Jeff Johnsone7245742012-09-05 17:12:55 -070012132 ENTER();
12133
Jeff Johnson295189b2012-06-20 16:38:30 -070012134 if (NULL == pAdapter)
12135 {
Arif Hussain6d2a3322013-11-17 19:50:10 -080012136 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Adapter is NULL", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -070012137 return -ENODEV;
12138 }
12139
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053012140 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
12141 TRACE_CODE_HDD_CFG80211_SET_POWER_MGMT,
12142 pAdapter->sessionId, timeout));
12143
Gopichand Nakkala20c4c042013-04-19 22:08:55 +053012144 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053012145 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkala20c4c042013-04-19 22:08:55 +053012146
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053012147 if (0 != status)
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012148 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053012149 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
12150 "%s: HDD context is not valid", __func__);
12151 return status;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012152 }
12153
Gopichand Nakkala20c4c042013-04-19 22:08:55 +053012154 if ((DRIVER_POWER_MODE_AUTO == !mode) &&
12155 (TRUE == pHddCtx->hdd_wlan_suspended) &&
12156 (pHddCtx->cfg_ini->fhostArpOffload) &&
12157 (eConnectionState_Associated ==
12158 (WLAN_HDD_GET_STATION_CTX_PTR(pAdapter))->conn_info.connState))
12159 {
Amar Singhald53568e2013-09-26 11:03:45 -070012160
12161 hddLog(VOS_TRACE_LEVEL_INFO,
12162 "offload: in cfg80211_set_power_mgmt, calling arp offload");
Gopichand Nakkalab03e8082013-05-30 18:09:25 +053012163 vos_status = hdd_conf_arp_offload(pAdapter, TRUE);
Gopichand Nakkala20c4c042013-04-19 22:08:55 +053012164 if (!VOS_IS_STATUS_SUCCESS(vos_status))
12165 {
12166 hddLog(VOS_TRACE_LEVEL_INFO,
Arif Hussain6d2a3322013-11-17 19:50:10 -080012167 "%s:Failed to enable ARPOFFLOAD Feature %d",
Gopichand Nakkala20c4c042013-04-19 22:08:55 +053012168 __func__, vos_status);
12169 }
12170 }
12171
Jeff Johnson295189b2012-06-20 16:38:30 -070012172 /**The get power cmd from the supplicant gets updated by the nl only
12173 *on successful execution of the function call
12174 *we are oppositely mapped w.r.t mode in the driver
12175 **/
12176 vos_status = wlan_hdd_enter_bmps(pAdapter, !mode);
12177
Jeff Johnsone7245742012-09-05 17:12:55 -070012178 EXIT();
Jeff Johnson295189b2012-06-20 16:38:30 -070012179 if (VOS_STATUS_E_FAILURE == vos_status)
12180 {
c_hpothu6ff1c3c2013-10-01 19:01:57 +053012181 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
12182 "%s: failed to enter bmps mode", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -070012183 return -EINVAL;
12184 }
12185 return 0;
12186}
12187
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053012188static int wlan_hdd_cfg80211_set_power_mgmt(struct wiphy *wiphy,
12189 struct net_device *dev, bool mode, int timeout)
12190{
12191 int ret;
Jeff Johnson295189b2012-06-20 16:38:30 -070012192
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053012193 vos_ssr_protect(__func__);
12194 ret = __wlan_hdd_cfg80211_set_power_mgmt(wiphy, dev, mode, timeout);
12195 vos_ssr_unprotect(__func__);
12196
12197 return ret;
12198}
Jeff Johnson295189b2012-06-20 16:38:30 -070012199#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
12200static int wlan_hdd_set_default_mgmt_key(struct wiphy *wiphy,
12201 struct net_device *netdev,
12202 u8 key_index)
12203{
Jeff Johnsone7245742012-09-05 17:12:55 -070012204 ENTER();
Jeff Johnson295189b2012-06-20 16:38:30 -070012205 return 0;
12206}
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012207#endif //LINUX_VERSION_CODE
Jeff Johnson295189b2012-06-20 16:38:30 -070012208
12209#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,4,0))
12210static int wlan_hdd_set_txq_params(struct wiphy *wiphy,
12211 struct net_device *dev,
12212 struct ieee80211_txq_params *params)
12213{
Jeff Johnsone7245742012-09-05 17:12:55 -070012214 ENTER();
Jeff Johnson295189b2012-06-20 16:38:30 -070012215 return 0;
12216}
12217#elif (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
12218static int wlan_hdd_set_txq_params(struct wiphy *wiphy,
12219 struct ieee80211_txq_params *params)
12220{
Jeff Johnsone7245742012-09-05 17:12:55 -070012221 ENTER();
Jeff Johnson295189b2012-06-20 16:38:30 -070012222 return 0;
12223}
12224#endif //LINUX_VERSION_CODE
12225
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053012226static int __wlan_hdd_cfg80211_del_station(struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -070012227 struct net_device *dev, u8 *mac)
12228{
12229 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053012230 hdd_context_t *pHddCtx;
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -080012231 VOS_STATUS vos_status;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053012232 int status;
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -080012233 v_U8_t staId;
Jeff Johnson295189b2012-06-20 16:38:30 -070012234
Jeff Johnsone7245742012-09-05 17:12:55 -070012235 ENTER();
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053012236
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053012237 if ( NULL == pAdapter )
Jeff Johnson295189b2012-06-20 16:38:30 -070012238 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053012239 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Invalid Adapter" ,__func__);
Jeff Johnson295189b2012-06-20 16:38:30 -070012240 return -EINVAL;
12241 }
12242
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053012243 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
12244 TRACE_CODE_HDD_CFG80211_DEL_STA,
12245 pAdapter->sessionId, pAdapter->device_mode));
12246
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053012247 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
12248 status = wlan_hdd_validate_context(pHddCtx);
Jeff Johnson295189b2012-06-20 16:38:30 -070012249
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053012250 if (0 != status)
Jeff Johnson04dd8a82012-06-29 20:41:40 -070012251 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053012252 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
12253 "%s: HDD context is not valid", __func__);
12254 return status;
Jeff Johnson04dd8a82012-06-29 20:41:40 -070012255 }
12256
Jeff Johnson295189b2012-06-20 16:38:30 -070012257 if ( (WLAN_HDD_SOFTAP == pAdapter->device_mode)
Jeff Johnson295189b2012-06-20 16:38:30 -070012258 || (WLAN_HDD_P2P_GO == pAdapter->device_mode)
Jeff Johnson295189b2012-06-20 16:38:30 -070012259 )
12260 {
12261 if( NULL == mac )
12262 {
12263 v_U16_t i;
12264 for(i = 0; i < WLAN_MAX_STA_COUNT; i++)
12265 {
Rajesh Chauhan18488fc2013-08-22 10:15:03 -070012266 if ((pAdapter->aStaInfo[i].isUsed) &&
12267 (!pAdapter->aStaInfo[i].isDeauthInProgress))
Jeff Johnson295189b2012-06-20 16:38:30 -070012268 {
12269 u8 *macAddr = pAdapter->aStaInfo[i].macAddrSTA.bytes;
12270 hddLog(VOS_TRACE_LEVEL_INFO,
Arif Hussain24bafea2013-11-15 15:10:03 -080012271 "%s: Delete STA with MAC::"
12272 MAC_ADDRESS_STR,
12273 __func__, MAC_ADDR_ARRAY(macAddr));
Rajesh Chauhan18488fc2013-08-22 10:15:03 -070012274 vos_status = hdd_softap_sta_deauth(pAdapter, macAddr);
12275 if (VOS_IS_STATUS_SUCCESS(vos_status))
12276 pAdapter->aStaInfo[i].isDeauthInProgress = TRUE;
Jeff Johnson295189b2012-06-20 16:38:30 -070012277 }
12278 }
12279 }
12280 else
12281 {
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -080012282
12283 vos_status = hdd_softap_GetStaId(pAdapter,(v_MACADDR_t *)mac, &staId);
12284 if (!VOS_IS_STATUS_SUCCESS(vos_status))
12285 {
12286 hddLog(VOS_TRACE_LEVEL_INFO,
Arif Hussain24bafea2013-11-15 15:10:03 -080012287 "%s: Skip this DEL STA as this is not used::"
12288 MAC_ADDRESS_STR,
12289 __func__, MAC_ADDR_ARRAY(mac));
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -080012290 return -ENOENT;
12291 }
12292
12293 if( pAdapter->aStaInfo[staId].isDeauthInProgress == TRUE)
12294 {
12295 hddLog(VOS_TRACE_LEVEL_INFO,
Arif Hussain24bafea2013-11-15 15:10:03 -080012296 "%s: Skip this DEL STA as deauth is in progress::"
12297 MAC_ADDRESS_STR,
12298 __func__, MAC_ADDR_ARRAY(mac));
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -080012299 return -ENOENT;
12300 }
12301
12302 pAdapter->aStaInfo[staId].isDeauthInProgress = TRUE;
12303
Jeff Johnson295189b2012-06-20 16:38:30 -070012304 hddLog(VOS_TRACE_LEVEL_INFO,
12305 "%s: Delete STA with MAC::"
Arif Hussain24bafea2013-11-15 15:10:03 -080012306 MAC_ADDRESS_STR,
Jeff Johnson295189b2012-06-20 16:38:30 -070012307 __func__,
Arif Hussain24bafea2013-11-15 15:10:03 -080012308 MAC_ADDR_ARRAY(mac));
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -080012309
12310 vos_status = hdd_softap_sta_deauth(pAdapter, mac);
12311 if (!VOS_IS_STATUS_SUCCESS(vos_status))
12312 {
12313 pAdapter->aStaInfo[staId].isDeauthInProgress = FALSE;
12314 hddLog(VOS_TRACE_LEVEL_INFO,
12315 "%s: STA removal failed for ::"
Arif Hussain24bafea2013-11-15 15:10:03 -080012316 MAC_ADDRESS_STR,
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -080012317 __func__,
Arif Hussain24bafea2013-11-15 15:10:03 -080012318 MAC_ADDR_ARRAY(mac));
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -080012319 return -ENOENT;
12320 }
12321
Jeff Johnson295189b2012-06-20 16:38:30 -070012322 }
12323 }
12324
12325 EXIT();
12326
12327 return 0;
12328}
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053012329static int wlan_hdd_cfg80211_del_station(struct wiphy *wiphy,
12330 struct net_device *dev, u8 *mac)
12331{
12332 int ret;
Jeff Johnson295189b2012-06-20 16:38:30 -070012333
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053012334 vos_ssr_protect(__func__);
12335 ret = __wlan_hdd_cfg80211_del_station(wiphy, dev, mac);
12336 vos_ssr_unprotect(__func__);
12337
12338 return ret;
12339}
12340
12341static int __wlan_hdd_cfg80211_add_station(struct wiphy *wiphy,
Hoonki Lee11f7dda2013-02-14 16:55:44 -080012342 struct net_device *dev, u8 *mac, struct station_parameters *params)
12343{
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053012344 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
Gopichand Nakkalab977a972013-02-18 19:15:09 -080012345 int status = -EPERM;
Hoonki Lee11f7dda2013-02-14 16:55:44 -080012346#ifdef FEATURE_WLAN_TDLS
12347 u32 mask, set;
Hoonki Lee11f7dda2013-02-14 16:55:44 -080012348 ENTER();
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053012349
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053012350 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
12351 TRACE_CODE_HDD_CFG80211_ADD_STA,
12352 pAdapter->sessionId, params->listen_interval));
Mohit Khanna698ba2a2012-12-04 15:08:18 -080012353 mask = params->sta_flags_mask;
12354
12355 set = params->sta_flags_set;
12356
Gopichand Nakkalac87400e2013-03-13 18:51:00 -070012357#ifdef WLAN_FEATURE_TDLS_DEBUG
12358 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
12359 "%s: mask 0x%x set 0x%x " MAC_ADDRESS_STR,
12360 __func__, mask, set, MAC_ADDR_ARRAY(mac));
12361#endif
Mohit Khanna698ba2a2012-12-04 15:08:18 -080012362
12363 if (mask & BIT(NL80211_STA_FLAG_TDLS_PEER)) {
12364 if (set & BIT(NL80211_STA_FLAG_TDLS_PEER)) {
Gopichand Nakkala681989c2013-03-06 22:27:48 -080012365 status = wlan_hdd_tdls_add_station(wiphy, dev, mac, 0, NULL);
Mohit Khanna698ba2a2012-12-04 15:08:18 -080012366 }
12367 }
12368#endif
Gopichand Nakkalab977a972013-02-18 19:15:09 -080012369 return status;
Jeff Johnson295189b2012-06-20 16:38:30 -070012370}
12371
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053012372static int wlan_hdd_cfg80211_add_station(struct wiphy *wiphy,
12373 struct net_device *dev, u8 *mac, struct station_parameters *params)
12374{
12375 int ret;
Jeff Johnson04dd8a82012-06-29 20:41:40 -070012376
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053012377 vos_ssr_protect(__func__);
12378 ret = __wlan_hdd_cfg80211_add_station(wiphy, dev, mac, params);
12379 vos_ssr_unprotect(__func__);
12380
12381 return ret;
12382}
Jeff Johnson04dd8a82012-06-29 20:41:40 -070012383#ifdef FEATURE_WLAN_LFR
Wilson Yang6507c4e2013-10-01 20:11:19 -070012384
Mahesh A Saptasagarf7418d72014-06-02 14:48:54 +053012385static int __wlan_hdd_cfg80211_set_pmksa(struct wiphy *wiphy, struct net_device *dev,
Jeff Johnsond13512a2012-07-17 11:42:19 -070012386 struct cfg80211_pmksa *pmksa)
Jeff Johnson04dd8a82012-06-29 20:41:40 -070012387{
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012388 tANI_U32 j=0;
Jeff Johnson04dd8a82012-06-29 20:41:40 -070012389 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
Agarwal Ashish3da95242014-05-21 14:57:17 +053012390 hdd_station_ctx_t *pHddStaCtx;
Jeff Johnson04dd8a82012-06-29 20:41:40 -070012391 tHalHandle halHandle;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012392 eHalStatus result;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053012393 int status;
Jeff Johnson04dd8a82012-06-29 20:41:40 -070012394 tANI_U8 BSSIDMatched = 0;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053012395 hdd_context_t *pHddCtx;
Jeff Johnson0299d0a2013-10-30 12:37:43 -070012396 hddLog(VOS_TRACE_LEVEL_DEBUG, "%s: set PMKSA for " MAC_ADDRESS_STR,
12397 __func__, MAC_ADDR_ARRAY(pmksa->bssid));
Jeff Johnsone7245742012-09-05 17:12:55 -070012398
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012399 // Validate pAdapter
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053012400 if ( NULL == pAdapter )
Jeff Johnson04dd8a82012-06-29 20:41:40 -070012401 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053012402 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Invalid Adapter" ,__func__);
Jeff Johnson04dd8a82012-06-29 20:41:40 -070012403 return -EINVAL;
12404 }
12405
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053012406 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
12407 status = wlan_hdd_validate_context(pHddCtx);
Jeff Johnson04dd8a82012-06-29 20:41:40 -070012408
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053012409 if (0 != status)
Jeff Johnson04dd8a82012-06-29 20:41:40 -070012410 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053012411 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
12412 "%s: HDD context is not valid", __func__);
12413 return status;
Jeff Johnson04dd8a82012-06-29 20:41:40 -070012414 }
12415
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012416 // Retrieve halHandle
Jeff Johnson04dd8a82012-06-29 20:41:40 -070012417 halHandle = WLAN_HDD_GET_HAL_CTX(pAdapter);
Agarwal Ashish3da95242014-05-21 14:57:17 +053012418 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
Jeff Johnson04dd8a82012-06-29 20:41:40 -070012419
Agarwal Ashish3da95242014-05-21 14:57:17 +053012420 for (j = 0; j < pHddStaCtx->PMKIDCacheIndex; j++)
Jeff Johnson04dd8a82012-06-29 20:41:40 -070012421 {
Agarwal Ashish3da95242014-05-21 14:57:17 +053012422 if (vos_mem_compare(pHddStaCtx->PMKIDCache[j].BSSID,
Jeff Johnson04dd8a82012-06-29 20:41:40 -070012423 pmksa->bssid, WNI_CFG_BSSID_LEN))
12424 {
12425 /* BSSID matched previous entry. Overwrite it. */
12426 BSSIDMatched = 1;
Agarwal Ashish3da95242014-05-21 14:57:17 +053012427 vos_mem_copy(pHddStaCtx->PMKIDCache[j].BSSID,
Jeff Johnson04dd8a82012-06-29 20:41:40 -070012428 pmksa->bssid, WNI_CFG_BSSID_LEN);
Agarwal Ashish3da95242014-05-21 14:57:17 +053012429 vos_mem_copy(pHddStaCtx->PMKIDCache[j].PMKID,
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012430 pmksa->pmkid,
Jeff Johnson04dd8a82012-06-29 20:41:40 -070012431 CSR_RSN_PMKID_SIZE);
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012432 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: Reusing cache entry %d.",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -070012433 __func__, j );
Jeff Johnson04dd8a82012-06-29 20:41:40 -070012434 dump_bssid(pmksa->bssid);
12435 dump_pmkid(halHandle, pmksa->pmkid);
12436 break;
12437 }
12438 }
12439
Madan Mohan Koyyalamudic4b317d2012-10-18 19:43:08 -070012440 /* Check we compared all entries,if then take the first slot now */
Agarwal Ashish3da95242014-05-21 14:57:17 +053012441 if (j == MAX_PMKSAIDS_IN_CACHE) pHddStaCtx->PMKIDCacheIndex=0;
Madan Mohan Koyyalamudic4b317d2012-10-18 19:43:08 -070012442
Jeff Johnson04dd8a82012-06-29 20:41:40 -070012443 if (!BSSIDMatched)
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012444 {
12445 // Now, we DON'T have a BSSID match, so take a new entry in the cache.
Agarwal Ashish3da95242014-05-21 14:57:17 +053012446 vos_mem_copy(pHddStaCtx->PMKIDCache[pHddStaCtx->PMKIDCacheIndex].BSSID,
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012447 pmksa->bssid, ETHER_ADDR_LEN);
Agarwal Ashish3da95242014-05-21 14:57:17 +053012448 vos_mem_copy(pHddStaCtx->PMKIDCache[pHddStaCtx->PMKIDCacheIndex].PMKID,
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012449 pmksa->pmkid,
Jeff Johnson04dd8a82012-06-29 20:41:40 -070012450 CSR_RSN_PMKID_SIZE);
Agarwal Ashish3da95242014-05-21 14:57:17 +053012451 hddLog(VOS_TRACE_LEVEL_DEBUG, "%s: Adding a new cache entry %d.",
12452 __func__, pHddStaCtx->PMKIDCacheIndex );
Jeff Johnson04dd8a82012-06-29 20:41:40 -070012453 dump_bssid(pmksa->bssid);
12454 dump_pmkid(halHandle, pmksa->pmkid);
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012455 // Increment the HDD Local Cache index
Jeff Johnson04dd8a82012-06-29 20:41:40 -070012456 // The "i=0" doesn't work for the call to sme_RoamSetPMKIDCache() - LFR FIXME
Agarwal Ashish3da95242014-05-21 14:57:17 +053012457 if (pHddStaCtx->PMKIDCacheIndex <= (MAX_PMKSAIDS_IN_CACHE-1))
12458 pHddStaCtx->PMKIDCacheIndex++;
12459 else
12460 pHddStaCtx->PMKIDCacheIndex = 0;
Jeff Johnson04dd8a82012-06-29 20:41:40 -070012461 }
12462
12463
12464 // Calling csrRoamSetPMKIDCache to configure the PMKIDs into the cache
Agarwal Ashish3da95242014-05-21 14:57:17 +053012465 hddLog(VOS_TRACE_LEVEL_DEBUG, "%s: Calling csrRoamSetPMKIDCache with %d cache entries.",
12466 __func__, pHddStaCtx->PMKIDCacheIndex );
12467
Jeff Johnson04dd8a82012-06-29 20:41:40 -070012468 // Finally set the PMKSA ID Cache in CSR
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012469 result = sme_RoamSetPMKIDCache(halHandle,pAdapter->sessionId,
Agarwal Ashish3da95242014-05-21 14:57:17 +053012470 pHddStaCtx->PMKIDCache,
12471 pHddStaCtx->PMKIDCacheIndex);
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053012472 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
12473 TRACE_CODE_HDD_CFG80211_SET_PMKSA,
12474 pAdapter->sessionId, result));
Jeff Johnson04dd8a82012-06-29 20:41:40 -070012475 return 0;
12476}
12477
Mahesh A Saptasagarf7418d72014-06-02 14:48:54 +053012478static int wlan_hdd_cfg80211_set_pmksa(struct wiphy *wiphy, struct net_device *dev,
12479 struct cfg80211_pmksa *pmksa)
12480{
12481 int ret;
12482
12483 vos_ssr_protect(__func__);
12484 ret = __wlan_hdd_cfg80211_set_pmksa(wiphy, dev, pmksa);
12485 vos_ssr_unprotect(__func__);
12486
12487 return ret;
12488}
Jeff Johnson04dd8a82012-06-29 20:41:40 -070012489
Wilson Yang6507c4e2013-10-01 20:11:19 -070012490
Mahesh A Saptasagarf7418d72014-06-02 14:48:54 +053012491static int __wlan_hdd_cfg80211_del_pmksa(struct wiphy *wiphy, struct net_device *dev,
Wilson Yang6507c4e2013-10-01 20:11:19 -070012492 struct cfg80211_pmksa *pmksa)
Jeff Johnson04dd8a82012-06-29 20:41:40 -070012493{
Wilson Yang6507c4e2013-10-01 20:11:19 -070012494 tANI_U32 j=0;
12495 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
Agarwal Ashish3da95242014-05-21 14:57:17 +053012496 hdd_station_ctx_t *pHddStaCtx;
Wilson Yang6507c4e2013-10-01 20:11:19 -070012497 tHalHandle halHandle;
Wilson Yang6507c4e2013-10-01 20:11:19 -070012498 tANI_U8 BSSIDMatched = 0;
Wilson Yang6507c4e2013-10-01 20:11:19 -070012499 hdd_context_t *pHddCtx;
Wilson Yangef657d32014-01-15 19:19:23 -080012500 int status = 0;
Wilson Yang6507c4e2013-10-01 20:11:19 -070012501
Jeff Johnson0299d0a2013-10-30 12:37:43 -070012502 hddLog(VOS_TRACE_LEVEL_DEBUG, "%s: deleting PMKSA for " MAC_ADDRESS_STR,
12503 __func__, MAC_ADDR_ARRAY(pmksa->bssid));
Wilson Yang6507c4e2013-10-01 20:11:19 -070012504
12505 /* Validate pAdapter */
12506 if (NULL == pAdapter)
12507 {
12508 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Invalid Adapter" ,__func__);
12509 return -EINVAL;
12510 }
12511
12512 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
12513 status = wlan_hdd_validate_context(pHddCtx);
12514
12515 if (0 != status)
12516 {
12517 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
12518 "%s: HDD context is not valid", __func__);
12519 return status;
12520 }
12521
12522 /*Retrieve halHandle*/
12523 halHandle = WLAN_HDD_GET_HAL_CTX(pAdapter);
Agarwal Ashish3da95242014-05-21 14:57:17 +053012524 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
Wilson Yang6507c4e2013-10-01 20:11:19 -070012525
12526 /*in case index is 0,no entry to delete*/
Agarwal Ashish3da95242014-05-21 14:57:17 +053012527 if (0 == pHddStaCtx->PMKIDCacheIndex)
Wilson Yang6507c4e2013-10-01 20:11:19 -070012528 {
Agarwal Ashish3da95242014-05-21 14:57:17 +053012529 hddLog(VOS_TRACE_LEVEL_INFO, FL("No entries to flush"));
12530 return 0;
Wilson Yang6507c4e2013-10-01 20:11:19 -070012531 }
12532
12533 /*find the matching PMKSA entry from j=0 to (index-1),
12534 * and delete the matched one
12535 */
Agarwal Ashish3da95242014-05-21 14:57:17 +053012536 for (j = 0; j < pHddStaCtx->PMKIDCacheIndex; j++)
Wilson Yang6507c4e2013-10-01 20:11:19 -070012537 {
Agarwal Ashish3da95242014-05-21 14:57:17 +053012538 if (vos_mem_compare(pHddStaCtx->PMKIDCache[j].BSSID,
Wilson Yang6507c4e2013-10-01 20:11:19 -070012539 pmksa->bssid,
12540 WNI_CFG_BSSID_LEN))
12541 {
12542 /* BSSID matched entry */
12543 BSSIDMatched = 1;
Agarwal Ashish3da95242014-05-21 14:57:17 +053012544 if (j < pHddStaCtx->PMKIDCacheIndex-1)
Wilson Yang6507c4e2013-10-01 20:11:19 -070012545 {
12546 /*replace the matching entry with the last entry in HDD local cache*/
Agarwal Ashish3da95242014-05-21 14:57:17 +053012547 vos_mem_copy(pHddStaCtx->PMKIDCache[j].BSSID,
12548 pHddStaCtx->PMKIDCache[pHddStaCtx->PMKIDCacheIndex-1].BSSID,
12549 VOS_MAC_ADDR_SIZE);
12550 vos_mem_copy(pHddStaCtx->PMKIDCache[j].PMKID,
12551 pHddStaCtx->PMKIDCache[pHddStaCtx->PMKIDCacheIndex-1].PMKID,
12552 CSR_RSN_PMKID_SIZE);
12553 }
Wilson Yang6507c4e2013-10-01 20:11:19 -070012554
12555 /*clear the last entry in HDD cache ---[index-1]*/
Agarwal Ashish3da95242014-05-21 14:57:17 +053012556 vos_mem_zero(pHddStaCtx->PMKIDCache[pHddStaCtx->PMKIDCacheIndex-1].BSSID,
12557 VOS_MAC_ADDR_SIZE);
12558 vos_mem_zero(pHddStaCtx->PMKIDCache[pHddStaCtx->PMKIDCacheIndex-1].PMKID,
12559 CSR_RSN_PMKID_SIZE);
Wilson Yang6507c4e2013-10-01 20:11:19 -070012560 /*reduce the PMKID array index*/
Agarwal Ashish3da95242014-05-21 14:57:17 +053012561 pHddStaCtx->PMKIDCacheIndex--;
Wilson Yang6507c4e2013-10-01 20:11:19 -070012562 /*delete the last PMKID cache in CSR*/
Wilson Yangef657d32014-01-15 19:19:23 -080012563 if (eHAL_STATUS_SUCCESS !=
12564 sme_RoamDelPMKIDfromCache(halHandle, pAdapter->sessionId, pmksa->bssid))
Wilson Yang6507c4e2013-10-01 20:11:19 -070012565 {
12566 hddLog(VOS_TRACE_LEVEL_ERROR,"%s: cannot delete PMKSA %d CONTENT.",
Agarwal Ashish3da95242014-05-21 14:57:17 +053012567 __func__, pHddStaCtx->PMKIDCacheIndex);
Wilson Yangef657d32014-01-15 19:19:23 -080012568 status = -EINVAL;
Wilson Yang6507c4e2013-10-01 20:11:19 -070012569 }
12570
12571 dump_bssid(pmksa->bssid);
12572 dump_pmkid(halHandle,pmksa->pmkid);
12573
12574 break;
12575 }
12576 }
12577
12578 /* we compare all entries,but cannot find matching entry */
12579 if (j == MAX_PMKSAIDS_IN_CACHE && !BSSIDMatched)
12580 {
Jeff Johnson0299d0a2013-10-30 12:37:43 -070012581 hddLog(VOS_TRACE_LEVEL_FATAL,
12582 "%s: No such PMKSA entry existed " MAC_ADDRESS_STR,
12583 __func__, MAC_ADDR_ARRAY(pmksa->bssid));
Wilson Yang6507c4e2013-10-01 20:11:19 -070012584 dump_bssid(pmksa->bssid);
12585 dump_pmkid(halHandle, pmksa->pmkid);
12586 return -EINVAL;
12587 }
Wilson Yangef657d32014-01-15 19:19:23 -080012588 return status;
Jeff Johnson04dd8a82012-06-29 20:41:40 -070012589}
12590
Wilson Yang6507c4e2013-10-01 20:11:19 -070012591
Mahesh A Saptasagarf7418d72014-06-02 14:48:54 +053012592static int wlan_hdd_cfg80211_del_pmksa(struct wiphy *wiphy, struct net_device *dev,
12593 struct cfg80211_pmksa *pmksa)
12594{
12595 int ret;
Wilson Yang6507c4e2013-10-01 20:11:19 -070012596
Mahesh A Saptasagarf7418d72014-06-02 14:48:54 +053012597 vos_ssr_protect(__func__);
12598 ret = __wlan_hdd_cfg80211_del_pmksa(wiphy, dev, pmksa);
12599 vos_ssr_unprotect(__func__);
12600
12601 return ret;
12602
12603}
12604
12605static int __wlan_hdd_cfg80211_flush_pmksa(struct wiphy *wiphy, struct net_device *dev)
Jeff Johnson04dd8a82012-06-29 20:41:40 -070012606{
Wilson Yang6507c4e2013-10-01 20:11:19 -070012607 tANI_U32 j=0;
12608 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
Agarwal Ashish3da95242014-05-21 14:57:17 +053012609 hdd_station_ctx_t *pHddStaCtx;
Wilson Yang6507c4e2013-10-01 20:11:19 -070012610 tHalHandle halHandle;
12611 hdd_context_t *pHddCtx;
12612 tANI_U8 *pBSSId;
Wilson Yangef657d32014-01-15 19:19:23 -080012613 int status = 0;
Wilson Yang6507c4e2013-10-01 20:11:19 -070012614
12615 hddLog(VOS_TRACE_LEVEL_DEBUG, "%s: flushing PMKSA ",__func__);
12616
12617 /* Validate pAdapter */
12618 if (NULL == pAdapter)
12619 {
12620 hddLog(VOS_TRACE_LEVEL_ERROR,
12621 "%s: Invalid Adapter" ,__func__);
12622 return -EINVAL;
12623 }
12624
12625 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
12626 status = wlan_hdd_validate_context(pHddCtx);
12627
12628 if (0 != status)
12629 {
12630 hddLog(VOS_TRACE_LEVEL_ERROR,
12631 "%s: HDD context is not valid", __func__);
12632 return status;
12633 }
12634
12635 /*Retrieve halHandle*/
12636 halHandle = WLAN_HDD_GET_HAL_CTX(pAdapter);
Agarwal Ashish3da95242014-05-21 14:57:17 +053012637 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
Wilson Yang6507c4e2013-10-01 20:11:19 -070012638
12639 /*in case index is 0,no entry to delete*/
Agarwal Ashish3da95242014-05-21 14:57:17 +053012640 if (0 == pHddStaCtx->PMKIDCacheIndex)
Wilson Yang6507c4e2013-10-01 20:11:19 -070012641 {
Vinay Krishna Erannacbf75f42014-02-26 17:35:20 +053012642 hddLog(VOS_TRACE_LEVEL_ERROR, FL("No entries to flush"));
Agarwal Ashish3da95242014-05-21 14:57:17 +053012643 return 0;
Wilson Yang6507c4e2013-10-01 20:11:19 -070012644 }
12645
12646 /*delete all the PMKSA one by one */
Agarwal Ashish3da95242014-05-21 14:57:17 +053012647 for (j = 0; j < pHddStaCtx->PMKIDCacheIndex; j++)
Wilson Yang6507c4e2013-10-01 20:11:19 -070012648 {
Agarwal Ashish3da95242014-05-21 14:57:17 +053012649 pBSSId =(tANI_U8 *)(pHddStaCtx->PMKIDCache[j].BSSID);
Wilson Yang6507c4e2013-10-01 20:11:19 -070012650 /*delete the PMKID in CSR*/
Wilson Yangef657d32014-01-15 19:19:23 -080012651 if (eHAL_STATUS_SUCCESS !=
12652 sme_RoamDelPMKIDfromCache(halHandle, pAdapter->sessionId, pBSSId))
Wilson Yang6507c4e2013-10-01 20:11:19 -070012653 {
12654 hddLog(VOS_TRACE_LEVEL_ERROR ,"%s cannot flush PMKIDCache %d.",
12655 __func__,j);
Wilson Yangef657d32014-01-15 19:19:23 -080012656 status = -EINVAL;
Wilson Yang6507c4e2013-10-01 20:11:19 -070012657 }
Kiet Lam8d21d5b2013-10-31 17:18:29 +053012658 /*clear the entry in HDD cache 0--index-1 */
Agarwal Ashish3da95242014-05-21 14:57:17 +053012659 vos_mem_zero(pHddStaCtx->PMKIDCache[j].BSSID, VOS_MAC_ADDR_SIZE);
12660 vos_mem_zero(pHddStaCtx->PMKIDCache[j].PMKID, CSR_RSN_PMKID_SIZE);
12661 }
Wilson Yang6507c4e2013-10-01 20:11:19 -070012662
Agarwal Ashish3da95242014-05-21 14:57:17 +053012663 pHddStaCtx->PMKIDCacheIndex = 0;
Wilson Yangef657d32014-01-15 19:19:23 -080012664 return status;
Jeff Johnson04dd8a82012-06-29 20:41:40 -070012665}
Mahesh A Saptasagarf7418d72014-06-02 14:48:54 +053012666
12667static int wlan_hdd_cfg80211_flush_pmksa(struct wiphy *wiphy, struct net_device *dev)
12668{
12669 int ret;
12670
12671 vos_ssr_protect(__func__);
12672 ret = __wlan_hdd_cfg80211_flush_pmksa(wiphy, dev);
12673 vos_ssr_unprotect(__func__);
12674
12675 return ret;
12676}
Jeff Johnson04dd8a82012-06-29 20:41:40 -070012677#endif
12678
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070012679#if defined(WLAN_FEATURE_VOWIFI_11R) && defined(KERNEL_SUPPORT_11R_CFG80211)
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053012680static int __wlan_hdd_cfg80211_update_ft_ies(struct wiphy *wiphy,
12681 struct net_device *dev,
12682 struct cfg80211_update_ft_ies_params *ftie)
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070012683{
12684 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
12685 hdd_station_ctx_t *pHddStaCtx;
12686
12687 if (NULL == pAdapter)
12688 {
Arif Hussain6d2a3322013-11-17 19:50:10 -080012689 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Adapter is NULL", __func__);
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070012690 return -ENODEV;
12691 }
12692
12693 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
12694
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053012695 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
12696 TRACE_CODE_HDD_CFG80211_UPDATE_FT_IES,
12697 pAdapter->sessionId, pHddStaCtx->conn_info.connState));
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070012698 // Added for debug on reception of Re-assoc Req.
12699 if (eConnectionState_Associated != pHddStaCtx->conn_info.connState)
12700 {
Arif Hussain6d2a3322013-11-17 19:50:10 -080012701 hddLog(LOGE, FL("Called with Ie of length = %zu when not associated"),
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070012702 ftie->ie_len);
Arif Hussain6d2a3322013-11-17 19:50:10 -080012703 hddLog(LOGE, FL("Should be Re-assoc Req IEs"));
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070012704 }
12705
12706#ifdef WLAN_FEATURE_VOWIFI_11R_DEBUG
Arif Hussain6d2a3322013-11-17 19:50:10 -080012707 hddLog(LOGE, FL("%s called with Ie of length = %zu"), __func__,
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070012708 ftie->ie_len);
12709#endif
12710
12711 // Pass the received FT IEs to SME
Gopichand Nakkala356fb102013-03-06 12:34:04 +053012712 sme_SetFTIEs( WLAN_HDD_GET_HAL_CTX(pAdapter), pAdapter->sessionId,
12713 (const u8 *)ftie->ie,
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070012714 ftie->ie_len);
12715 return 0;
12716}
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053012717
12718static int wlan_hdd_cfg80211_update_ft_ies(struct wiphy *wiphy,
12719 struct net_device *dev,
12720 struct cfg80211_update_ft_ies_params *ftie)
12721{
12722 int ret;
12723
12724 vos_ssr_protect(__func__);
12725 ret = __wlan_hdd_cfg80211_update_ft_ies(wiphy, dev, ftie);
12726 vos_ssr_unprotect(__func__);
12727
12728 return ret;
12729}
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070012730#endif
Jeff Johnson04dd8a82012-06-29 20:41:40 -070012731
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053012732#ifdef FEATURE_WLAN_SCAN_PNO
12733
12734void hdd_cfg80211_sched_scan_done_callback(void *callbackContext,
12735 tSirPrefNetworkFoundInd *pPrefNetworkFoundInd)
12736{
12737 int ret;
12738 hdd_adapter_t* pAdapter = (hdd_adapter_t*)callbackContext;
12739 hdd_context_t *pHddCtx;
12740
Nirav Shah80830bf2013-12-31 16:35:12 +053012741 ENTER();
12742
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053012743 if (NULL == pAdapter)
12744 {
Agarwal Ashish971c2882013-10-30 20:11:12 +053012745 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053012746 "%s: HDD adapter is Null", __func__);
12747 return ;
12748 }
12749
12750 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
12751 if (NULL == pHddCtx)
12752 {
12753 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
12754 "%s: HDD context is Null!!!", __func__);
12755 return ;
12756 }
12757
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053012758 spin_lock(&pHddCtx->schedScan_lock);
12759 if (TRUE == pHddCtx->isWiphySuspended)
12760 {
12761 pHddCtx->isSchedScanUpdatePending = TRUE;
12762 spin_unlock(&pHddCtx->schedScan_lock);
12763 hddLog(VOS_TRACE_LEVEL_INFO,
12764 "%s: Update cfg80211 scan database after it resume", __func__);
12765 return ;
12766 }
12767 spin_unlock(&pHddCtx->schedScan_lock);
12768
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053012769 ret = wlan_hdd_cfg80211_update_bss(pHddCtx->wiphy, pAdapter);
12770
12771 if (0 > ret)
12772 hddLog(VOS_TRACE_LEVEL_INFO, "%s: NO SCAN result", __func__);
12773
12774 cfg80211_sched_scan_results(pHddCtx->wiphy);
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053012775 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
12776 "%s: cfg80211 scan result database updated", __func__);
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053012777}
12778
12779/*
Mahesh A Saptasagar0f7b0372013-11-28 23:23:07 +053012780 * FUNCTION: wlan_hdd_is_pno_allowed
Vinay Krishna Erannacbf75f42014-02-26 17:35:20 +053012781 * Disallow pno if any session is active
Mahesh A Saptasagar0f7b0372013-11-28 23:23:07 +053012782 */
12783static eHalStatus wlan_hdd_is_pno_allowed(hdd_adapter_t *pAdapter)
12784{
12785 hdd_adapter_list_node_t *pAdapterNode = NULL, *pNext = NULL;
12786 hdd_adapter_t *pTempAdapter = NULL;
Vinay Krishna Eranna23ffd182013-12-26 19:16:55 +053012787 hdd_station_ctx_t *pStaCtx;
Mahesh A Saptasagar0f7b0372013-11-28 23:23:07 +053012788 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
12789 int status = 0;
12790 status = hdd_get_front_adapter(pHddCtx, &pAdapterNode);
12791
Vinay Krishna Erannacbf75f42014-02-26 17:35:20 +053012792 /* The current firmware design does not allow PNO during any
12793 * active sessions. Hence, determine the active sessions
12794 * and return a failure.
12795 */
Mahesh A Saptasagar0f7b0372013-11-28 23:23:07 +053012796 while ((NULL != pAdapterNode) && (VOS_STATUS_SUCCESS == status))
12797 {
12798 pTempAdapter = pAdapterNode->pAdapter;
Vinay Krishna Eranna23ffd182013-12-26 19:16:55 +053012799 pStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pTempAdapter);
Mahesh A Saptasagar0f7b0372013-11-28 23:23:07 +053012800
Vinay Krishna Eranna23ffd182013-12-26 19:16:55 +053012801 if (((WLAN_HDD_INFRA_STATION == pTempAdapter->device_mode)
12802 && (eConnectionState_NotConnected != pStaCtx->conn_info.connState))
12803 || (WLAN_HDD_P2P_CLIENT == pTempAdapter->device_mode)
12804 || (WLAN_HDD_P2P_GO == pTempAdapter->device_mode)
12805 || (WLAN_HDD_SOFTAP == pTempAdapter->device_mode)
12806 )
Mahesh A Saptasagar0f7b0372013-11-28 23:23:07 +053012807 {
Vinay Krishna Eranna23ffd182013-12-26 19:16:55 +053012808 return eHAL_STATUS_FAILURE;
Mahesh A Saptasagar0f7b0372013-11-28 23:23:07 +053012809 }
12810 status = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
12811 pAdapterNode = pNext;
12812 }
Vinay Krishna Eranna23ffd182013-12-26 19:16:55 +053012813 return eHAL_STATUS_SUCCESS;
Mahesh A Saptasagar0f7b0372013-11-28 23:23:07 +053012814}
12815
Vinay Krishna Erannaf0e523b2014-03-01 21:00:16 +053012816void hdd_cfg80211_sched_scan_start_status_cb(void *callbackContext, VOS_STATUS status)
12817{
12818 hdd_adapter_t *pAdapter = callbackContext;
12819 hdd_context_t *pHddCtx;
12820
12821 if ((NULL == pAdapter) || (WLAN_HDD_ADAPTER_MAGIC != pAdapter->magic))
12822 {
12823 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
12824 FL("Invalid adapter or adapter has invalid magic"));
12825 return;
12826 }
12827
12828 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
12829 if (0 != wlan_hdd_validate_context(pHddCtx))
12830 {
12831 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
12832 FL("HDD context is not valid"));
12833 return;
12834 }
12835
c_hpothub53c45d2014-08-18 16:53:14 +053012836 if (VOS_STATUS_SUCCESS != status)
12837 {
12838 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Vinay Krishna Erannaf0e523b2014-03-01 21:00:16 +053012839 FL("PNO enable response status = %d"), status);
c_hpothub53c45d2014-08-18 16:53:14 +053012840 pHddCtx->isPnoEnable = FALSE;
12841 }
Vinay Krishna Erannaf0e523b2014-03-01 21:00:16 +053012842
12843 pAdapter->pno_req_status = (status == VOS_STATUS_SUCCESS) ? 0 : -EBUSY;
12844 complete(&pAdapter->pno_comp_var);
12845}
12846
Mahesh A Saptasagar0f7b0372013-11-28 23:23:07 +053012847/*
Mahesh A Saptasagar6cc38562014-05-23 21:22:17 +053012848 * FUNCTION: __wlan_hdd_cfg80211_sched_scan_start
12849 * Function to enable PNO
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053012850 */
Mahesh A Saptasagar6cc38562014-05-23 21:22:17 +053012851static int __wlan_hdd_cfg80211_sched_scan_start(struct wiphy *wiphy,
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053012852 struct net_device *dev, struct cfg80211_sched_scan_request *request)
12853{
12854 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
12855 tpSirPNOScanReq pPnoRequest = NULL;
12856 hdd_context_t *pHddCtx;
12857 tHalHandle hHal;
Mahesh A Saptasagar7bd6ad42014-07-21 18:56:33 +053012858 v_U32_t i, indx, num_ch, tempInterval, j;
Sushant Kaushikd62d9782014-02-19 15:39:40 +053012859 u8 valid_ch[WNI_CFG_VALID_CHANNEL_LIST_LEN] = {0};
12860 u8 channels_allowed[WNI_CFG_VALID_CHANNEL_LIST_LEN] = {0};
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053012861 v_U32_t num_channels_allowed = WNI_CFG_VALID_CHANNEL_LIST_LEN;
12862 eHalStatus status = eHAL_STATUS_FAILURE;
Kamath Vinayakba5313f2013-08-22 15:52:39 +053012863 int ret = 0;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053012864
12865 if (NULL == pAdapter)
12866 {
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053012867 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053012868 "%s: HDD adapter is Null", __func__);
12869 return -ENODEV;
12870 }
12871
12872 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053012873 ret = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053012874
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053012875 if (0 != ret)
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053012876 {
Gopichand Nakkalac005b7c2013-05-14 16:04:14 +053012877 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
12878 "%s: HDD context is not valid", __func__);
Kamath Vinayakba5313f2013-08-22 15:52:39 +053012879 return -EINVAL;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053012880 }
12881
12882 hHal = WLAN_HDD_GET_HAL_CTX(pAdapter);
12883 if (NULL == hHal)
12884 {
12885 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
12886 "%s: HAL context is Null!!!", __func__);
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053012887 return -EINVAL;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053012888 }
Sushant Kaushik2fe89932014-09-03 10:58:09 +053012889 sme_ScanFlushResult(hHal, pAdapter->sessionId);
Mahesh A Saptasagar2395ee62014-05-21 19:12:21 +053012890 ret = wlan_hdd_scan_abort(pAdapter);
Girish Gowli4bf7a632014-06-12 13:42:11 +053012891 if (ret < 0)
Mahesh A Saptasagar2395ee62014-05-21 19:12:21 +053012892 {
12893 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
12894 "%s: aborting the existing scan is unsuccessfull", __func__);
12895 return -EBUSY;
12896 }
12897
Vinay Krishna Eranna23ffd182013-12-26 19:16:55 +053012898 if (eHAL_STATUS_SUCCESS != wlan_hdd_is_pno_allowed(pAdapter))
Mahesh A Saptasagar0f7b0372013-11-28 23:23:07 +053012899 {
Vinay Krishna Erannacbf75f42014-02-26 17:35:20 +053012900 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_WARN,
Vinay Krishna Eranna23ffd182013-12-26 19:16:55 +053012901 FL("Cannot handle sched_scan"));
Mahesh A Saptasagar0f7b0372013-11-28 23:23:07 +053012902 return -EBUSY;
12903 }
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053012904
c_hpothu37f21312014-04-09 21:49:54 +053012905 if (TRUE == pHddCtx->isPnoEnable)
12906 {
12907 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_WARN,
12908 FL("already PNO is enabled"));
12909 return -EBUSY;
12910 }
12911 pHddCtx->isPnoEnable = TRUE;
12912
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053012913 pPnoRequest = (tpSirPNOScanReq) vos_mem_malloc(sizeof (tSirPNOScanReq));
12914 if (NULL == pPnoRequest)
12915 {
12916 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
12917 "%s: vos_mem_malloc failed", __func__);
c_hpothu37f21312014-04-09 21:49:54 +053012918 pHddCtx->isPnoEnable = FALSE;
Kamath Vinayakba5313f2013-08-22 15:52:39 +053012919 return -ENOMEM;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053012920 }
12921
Madan Mohan Koyyalamudic3f04352013-09-26 19:21:48 +053012922 memset(pPnoRequest, 0, sizeof (tSirPNOScanReq));
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053012923 pPnoRequest->enable = 1; /*Enable PNO */
12924 pPnoRequest->ucNetworksCount = request->n_match_sets;
12925
12926 if (( !pPnoRequest->ucNetworksCount ) ||
12927 ( pPnoRequest->ucNetworksCount > SIR_PNO_MAX_SUPP_NETWORKS ))
12928 {
12929 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Sushant Kaushik1e406c32014-05-09 15:57:52 +053012930 "%s: Network input is not correct %d Max Network supported is %d",
12931 __func__, pPnoRequest->ucNetworksCount,
12932 SIR_PNO_MAX_SUPP_NETWORKS);
Kamath Vinayakba5313f2013-08-22 15:52:39 +053012933 ret = -EINVAL;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053012934 goto error;
12935 }
12936
12937 if ( SIR_PNO_MAX_NETW_CHANNELS_EX < request->n_channels )
12938 {
12939 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Nirav Shah80830bf2013-12-31 16:35:12 +053012940 "%s: Incorrect number of channels %d",
12941 __func__, request->n_channels);
Kamath Vinayakba5313f2013-08-22 15:52:39 +053012942 ret = -EINVAL;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053012943 goto error;
12944 }
12945
12946 /* Framework provides one set of channels(all)
12947 * common for all saved profile */
12948 if (0 != ccmCfgGetStr(hHal, WNI_CFG_VALID_CHANNEL_LIST,
12949 channels_allowed, &num_channels_allowed))
12950 {
12951 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
12952 "%s: failed to get valid channel list", __func__);
Kamath Vinayakba5313f2013-08-22 15:52:39 +053012953 ret = -EINVAL;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053012954 goto error;
12955 }
12956 /* Checking each channel against allowed channel list */
12957 num_ch = 0;
Nirav Shah80830bf2013-12-31 16:35:12 +053012958 if (request->n_channels)
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053012959 {
Nirav Shah80830bf2013-12-31 16:35:12 +053012960 char chList [(request->n_channels*5)+1];
12961 int len;
12962 for (i = 0, len = 0; i < request->n_channels; i++)
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053012963 {
Nirav Shah80830bf2013-12-31 16:35:12 +053012964 for (indx = 0; indx < num_channels_allowed; indx++)
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053012965 {
Nirav Shah80830bf2013-12-31 16:35:12 +053012966 if (request->channels[i]->hw_value == channels_allowed[indx])
12967 {
12968 valid_ch[num_ch++] = request->channels[i]->hw_value;
12969 len += snprintf(chList+len, 5, "%d ",
12970 request->channels[i]->hw_value);
12971 break ;
12972 }
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053012973 }
12974 }
Nirav Shah80830bf2013-12-31 16:35:12 +053012975 hddLog(VOS_TRACE_LEVEL_INFO,"Channel-List: %s ", chList);
12976 }
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053012977
12978 /* Filling per profile params */
12979 for (i = 0; i < pPnoRequest->ucNetworksCount; i++)
12980 {
12981 pPnoRequest->aNetworks[i].ssId.length =
12982 request->match_sets[i].ssid.ssid_len;
12983
12984 if (( 0 == pPnoRequest->aNetworks[i].ssId.length ) ||
12985 ( pPnoRequest->aNetworks[i].ssId.length > 32 ) )
12986 {
12987 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Nirav Shah80830bf2013-12-31 16:35:12 +053012988 "%s: SSID Len %d is not correct for network %d",
12989 __func__, pPnoRequest->aNetworks[i].ssId.length, i);
Kamath Vinayakba5313f2013-08-22 15:52:39 +053012990 ret = -EINVAL;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053012991 goto error;
12992 }
12993
12994 memcpy(pPnoRequest->aNetworks[i].ssId.ssId,
12995 request->match_sets[i].ssid.ssid,
12996 request->match_sets[i].ssid.ssid_len);
Sushant Kaushik1e406c32014-05-09 15:57:52 +053012997 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
12998 "%s: SSID of network %d is %s ", __func__,
12999 i, pPnoRequest->aNetworks[i].ssId.ssId);
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053013000 pPnoRequest->aNetworks[i].authentication = 0; /*eAUTH_TYPE_ANY*/
13001 pPnoRequest->aNetworks[i].encryption = 0; /*eED_ANY*/
13002 pPnoRequest->aNetworks[i].bcastNetwType = 0; /*eBCAST_UNKNOWN*/
13003
13004 /*Copying list of valid channel into request */
13005 memcpy(pPnoRequest->aNetworks[i].aChannels, valid_ch, num_ch);
13006 pPnoRequest->aNetworks[i].ucChannelCount = num_ch;
13007
13008 pPnoRequest->aNetworks[i].rssiThreshold = 0; //Default value
13009 }
13010
Mahesh A Saptasagar7bd6ad42014-07-21 18:56:33 +053013011 for (i = 0; i < request->n_ssids; i++)
13012 {
13013 j = 0;
13014 while (j < pPnoRequest->ucNetworksCount)
13015 {
13016 if ((pPnoRequest->aNetworks[j].ssId.length ==
13017 request->ssids[i].ssid_len) &&
13018 (0 == memcmp(pPnoRequest->aNetworks[j].ssId.ssId,
13019 request->ssids[i].ssid,
13020 pPnoRequest->aNetworks[j].ssId.length)))
13021 {
13022 pPnoRequest->aNetworks[j].bcastNetwType = eBCAST_HIDDEN;
13023 break;
13024 }
13025 j++;
13026 }
13027 }
13028 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
13029 "Number of hidden networks being Configured = %d",
13030 request->n_ssids);
Madan Mohan Koyyalamudia7765d52013-09-18 16:49:56 +053013031 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Jeff Johnson59a121e2013-11-30 09:46:08 -080013032 "request->ie_len = %zu", request->ie_len);
Madan Mohan Koyyalamudia7765d52013-09-18 16:49:56 +053013033 if ((0 < request->ie_len) && (NULL != request->ie))
13034 {
13035 pPnoRequest->us24GProbeTemplateLen = request->ie_len;
13036 memcpy(&pPnoRequest->p24GProbeTemplate, request->ie,
13037 pPnoRequest->us24GProbeTemplateLen);
13038
13039 pPnoRequest->us5GProbeTemplateLen = request->ie_len;
13040 memcpy(&pPnoRequest->p5GProbeTemplate, request->ie,
13041 pPnoRequest->us5GProbeTemplateLen);
13042 }
13043
Madan Mohan Koyyalamudi1d16f462013-08-27 16:25:34 +053013044 /* Driver gets only one time interval which is hardcoded in
13045 * supplicant for 10000ms. Taking power consumption into account 6 timers
13046 * will be used, Timervalue is increased exponentially i.e 10,20,40,
13047 * 80,160,320 secs. And number of scan cycle for each timer
13048 * is configurable through INI param gPNOScanTimerRepeatValue.
13049 * If it is set to 0 only one timer will be used and PNO scan cycle
13050 * will be repeated after each interval specified by supplicant
13051 * till PNO is disabled.
13052 */
13053 if (0 == pHddCtx->cfg_ini->configPNOScanTimerRepeatValue)
13054 pPnoRequest->scanTimers.ucScanTimersCount = HDD_PNO_SCAN_TIMERS_SET_ONE;
13055 else
13056 pPnoRequest->scanTimers.ucScanTimersCount =
13057 HDD_PNO_SCAN_TIMERS_SET_MULTIPLE;
13058
13059 tempInterval = (request->interval)/1000;
13060 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
13061 "Base scan interval = %d PNOScanTimerRepeatValue = %d",
13062 tempInterval, pHddCtx->cfg_ini->configPNOScanTimerRepeatValue);
13063 for ( i = 0; i < pPnoRequest->scanTimers.ucScanTimersCount; i++)
13064 {
13065 pPnoRequest->scanTimers.aTimerValues[i].uTimerRepeat =
13066 pHddCtx->cfg_ini->configPNOScanTimerRepeatValue;
13067 pPnoRequest->scanTimers.aTimerValues[i].uTimerValue = tempInterval;
13068 tempInterval *= 2;
13069 }
13070 //Repeat last timer until pno disabled.
13071 pPnoRequest->scanTimers.aTimerValues[i-1].uTimerRepeat = 0;
13072
Madan Mohan Koyyalamudid206c7b2013-09-26 22:54:51 +053013073 pPnoRequest->modePNO = SIR_PNO_MODE_IMMEDIATE;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053013074
Vinay Krishna Erannaf0e523b2014-03-01 21:00:16 +053013075 INIT_COMPLETION(pAdapter->pno_comp_var);
13076 pPnoRequest->statusCallback = hdd_cfg80211_sched_scan_start_status_cb;
13077 pPnoRequest->callbackContext = pAdapter;
13078 pAdapter->pno_req_status = 0;
13079
Nirav Shah80830bf2013-12-31 16:35:12 +053013080 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
13081 "SessionId %d, enable %d, modePNO %d, ucScanTimersCount %d",
13082 pAdapter->sessionId, pPnoRequest->enable, pPnoRequest->modePNO,
13083 pPnoRequest->scanTimers.ucScanTimersCount);
13084
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053013085 status = sme_SetPreferredNetworkList(WLAN_HDD_GET_HAL_CTX(pAdapter),
13086 pPnoRequest, pAdapter->sessionId,
13087 hdd_cfg80211_sched_scan_done_callback, pAdapter);
13088 if (eHAL_STATUS_SUCCESS != status)
13089 {
13090 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Nirav Shah80830bf2013-12-31 16:35:12 +053013091 "%s: Failed to enable PNO", __func__);
Kamath Vinayakba5313f2013-08-22 15:52:39 +053013092 ret = -EINVAL;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053013093 goto error;
13094 }
13095
Vinay Krishna Erannaf0e523b2014-03-01 21:00:16 +053013096 ret = wait_for_completion_timeout(
13097 &pAdapter->pno_comp_var,
13098 msecs_to_jiffies(WLAN_WAIT_TIME_PNO));
13099 if (0 >= ret)
13100 {
13101 // Did not receive the response for PNO enable in time.
13102 // Assuming the PNO enable was success.
13103 // Returning error from here, because we timeout, results
13104 // in side effect of Wifi (Wifi Setting) not to work.
13105 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
13106 FL("Timed out waiting for PNO to be Enabled"));
13107 ret = 0;
13108 goto error;
13109 }
13110
c_hpothu3c986b22014-07-09 14:45:09 +053013111 vos_mem_free(pPnoRequest);
Vinay Krishna Erannaf0e523b2014-03-01 21:00:16 +053013112 ret = pAdapter->pno_req_status;
c_hpothu37f21312014-04-09 21:49:54 +053013113 return ret;
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053013114
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053013115error:
Vinay Krishna Erannaf0e523b2014-03-01 21:00:16 +053013116 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
13117 FL("PNO scanRequest offloaded ret = %d"), ret);
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053013118 vos_mem_free(pPnoRequest);
c_hpothu37f21312014-04-09 21:49:54 +053013119 pHddCtx->isPnoEnable = FALSE;
Kamath Vinayakba5313f2013-08-22 15:52:39 +053013120 return ret;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053013121}
13122
13123/*
Mahesh A Saptasagar6cc38562014-05-23 21:22:17 +053013124 * FUNCTION: wlan_hdd_cfg80211_sched_scan_start
13125 * NL interface to enable PNO
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053013126 */
Mahesh A Saptasagar6cc38562014-05-23 21:22:17 +053013127static int wlan_hdd_cfg80211_sched_scan_start(struct wiphy *wiphy,
13128 struct net_device *dev, struct cfg80211_sched_scan_request *request)
13129{
13130 int ret;
13131
13132 vos_ssr_protect(__func__);
13133 ret = __wlan_hdd_cfg80211_sched_scan_start(wiphy, dev, request);
13134 vos_ssr_unprotect(__func__);
13135
13136 return ret;
13137}
13138
13139/*
13140 * FUNCTION: __wlan_hdd_cfg80211_sched_scan_stop
13141 * Function to disable PNO
13142 */
13143static int __wlan_hdd_cfg80211_sched_scan_stop(struct wiphy *wiphy,
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053013144 struct net_device *dev)
13145{
13146 eHalStatus status = eHAL_STATUS_FAILURE;
13147 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
13148 hdd_context_t *pHddCtx;
13149 tHalHandle hHal;
13150 tpSirPNOScanReq pPnoRequest = NULL;
Kamath Vinayakba5313f2013-08-22 15:52:39 +053013151 int ret = 0;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053013152
13153 ENTER();
13154
13155 if (NULL == pAdapter)
13156 {
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053013157 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053013158 "%s: HDD adapter is Null", __func__);
13159 return -ENODEV;
13160 }
13161
13162 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053013163
Kamath Vinayakba5313f2013-08-22 15:52:39 +053013164 if (NULL == pHddCtx)
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053013165 {
Gopichand Nakkalac005b7c2013-05-14 16:04:14 +053013166 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Kamath Vinayakba5313f2013-08-22 15:52:39 +053013167 "%s: HDD context is Null", __func__);
13168 return -ENODEV;
13169 }
13170
13171 /* The return 0 is intentional when isLogpInProgress and
13172 * isLoadUnloadInProgress. We did observe a crash due to a return of
13173 * failure in sched_scan_stop , especially for a case where the unload
13174 * of the happens at the same time. The function __cfg80211_stop_sched_scan
13175 * was clearing rdev->sched_scan_req only when the sched_scan_stop returns
13176 * success. If it returns a failure , then its next invocation due to the
13177 * clean up of the second interface will have the dev pointer corresponding
13178 * to the first one leading to a crash.
13179 */
13180 if (pHddCtx->isLogpInProgress)
13181 {
13182 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
13183 "%s: LOGP in Progress. Ignore!!!", __func__);
13184 return ret;
13185 }
13186
Mihir Shete18156292014-03-11 15:38:30 +053013187 if (WLAN_HDD_IS_LOAD_UNLOAD_IN_PROGRESS(pHddCtx))
Kamath Vinayakba5313f2013-08-22 15:52:39 +053013188 {
13189 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
13190 "%s: Unloading/Loading in Progress. Ignore!!!", __func__);
13191 return ret;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053013192 }
13193
13194 hHal = WLAN_HDD_GET_HAL_CTX(pAdapter);
13195 if (NULL == hHal)
13196 {
13197 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
13198 "%s: HAL context is Null!!!", __func__);
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053013199 return -EINVAL;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053013200 }
13201
13202 pPnoRequest = (tpSirPNOScanReq) vos_mem_malloc(sizeof (tSirPNOScanReq));
13203 if (NULL == pPnoRequest)
13204 {
13205 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
13206 "%s: vos_mem_malloc failed", __func__);
Kamath Vinayakba5313f2013-08-22 15:52:39 +053013207 return -ENOMEM;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053013208 }
13209
13210 memset(pPnoRequest, 0, sizeof (tSirPNOScanReq));
13211 pPnoRequest->enable = 0; /* Disable PNO */
13212 pPnoRequest->ucNetworksCount = 0;
13213
13214 status = sme_SetPreferredNetworkList(hHal, pPnoRequest,
13215 pAdapter->sessionId,
13216 NULL, pAdapter);
13217 if (eHAL_STATUS_SUCCESS != status)
13218 {
13219 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
13220 "Failed to disabled PNO");
Kamath Vinayakba5313f2013-08-22 15:52:39 +053013221 ret = -EINVAL;
Vinay Krishna Erannaf0e523b2014-03-01 21:00:16 +053013222 goto error;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053013223 }
c_hpothu37f21312014-04-09 21:49:54 +053013224 pHddCtx->isPnoEnable = FALSE;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053013225
Vinay Krishna Erannaf0e523b2014-03-01 21:00:16 +053013226error:
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053013227 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Vinay Krishna Erannaf0e523b2014-03-01 21:00:16 +053013228 FL("PNO scan disabled ret = %d"), ret);
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053013229 vos_mem_free(pPnoRequest);
13230
13231 EXIT();
Kamath Vinayakba5313f2013-08-22 15:52:39 +053013232 return ret;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053013233}
13234
Mahesh A Saptasagar6cc38562014-05-23 21:22:17 +053013235/*
13236 * FUNCTION: wlan_hdd_cfg80211_sched_scan_stop
13237 * NL interface to disable PNO
13238 */
13239static int wlan_hdd_cfg80211_sched_scan_stop(struct wiphy *wiphy,
13240 struct net_device *dev)
13241{
13242 int ret;
13243
13244 vos_ssr_protect(__func__);
13245 ret = __wlan_hdd_cfg80211_sched_scan_stop(wiphy, dev);
13246 vos_ssr_unprotect(__func__);
13247
13248 return ret;
13249}
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053013250#endif /*FEATURE_WLAN_SCAN_PNO*/
13251
13252
Mohit Khanna698ba2a2012-12-04 15:08:18 -080013253#ifdef FEATURE_WLAN_TDLS
Sunil Dutt Undekarieacac6f2014-03-21 14:08:53 +053013254#if TDLS_MGMT_VERSION2
Mohit Khanna698ba2a2012-12-04 15:08:18 -080013255static int wlan_hdd_cfg80211_tdls_mgmt(struct wiphy *wiphy, struct net_device *dev,
13256 u8 *peer, u8 action_code, u8 dialog_token,
Sunil Dutt Undekarieacac6f2014-03-21 14:08:53 +053013257 u16 status_code, u32 peer_capability, const u8 *buf, size_t len)
13258#else
13259static int wlan_hdd_cfg80211_tdls_mgmt(struct wiphy *wiphy, struct net_device *dev,
13260 u8 *peer, u8 action_code, u8 dialog_token,
13261 u16 status_code, const u8 *buf, size_t len)
13262#endif
Mohit Khanna698ba2a2012-12-04 15:08:18 -080013263{
13264
13265 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
13266 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
Mohit Khanna698ba2a2012-12-04 15:08:18 -080013267 u8 peerMac[6];
13268 VOS_STATUS status;
Gopichand Nakkala05922802013-03-14 12:23:19 -070013269 int max_sta_failed = 0;
Hoonki Leea34dd892013-02-05 22:56:02 -080013270 int responder;
Hoonki Leed37cbb32013-04-20 00:31:14 -070013271 long rc;
Sunil Dutt Undekarieacac6f2014-03-21 14:08:53 +053013272#if !(TDLS_MGMT_VERSION2)
13273 u32 peer_capability = 0;
13274#endif
Rajesh Chauhana34c6e62014-03-25 16:37:58 +053013275 tANI_U16 numCurrTdlsPeers;
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053013276
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053013277 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
13278 TRACE_CODE_HDD_CFG80211_TDLS_MGMT,
13279 pAdapter->sessionId, action_code));
Hoonki Lee11f7dda2013-02-14 16:55:44 -080013280 if (NULL == pHddCtx || NULL == pHddCtx->cfg_ini)
Mohit Khanna698ba2a2012-12-04 15:08:18 -080013281 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013282 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Mohit Khanna698ba2a2012-12-04 15:08:18 -080013283 "Invalid arguments");
13284 return -EINVAL;
13285 }
13286
Sameer Thalappil75ea31a2013-02-21 19:38:16 -080013287 if (pHddCtx->isLogpInProgress)
13288 {
13289 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
13290 "%s:LOGP in Progress. Ignore!!!", __func__);
Atul Mittal115287b2014-07-08 13:26:33 +053013291 wlan_hdd_tdls_set_link_status(pAdapter,
13292 peer,
13293 eTDLS_LINK_IDLE,
13294 eTDLS_LINK_UNSPECIFIED);
Sameer Thalappil75ea31a2013-02-21 19:38:16 -080013295 return -EBUSY;
13296 }
13297
Hoonki Lee27511902013-03-14 18:19:06 -070013298 if (eTDLS_SUPPORT_NOT_ENABLED == pHddCtx->tdls_mode)
Mohit Khanna698ba2a2012-12-04 15:08:18 -080013299 {
Hoonki Lee27511902013-03-14 18:19:06 -070013300 VOS_TRACE( VOS_MODULE_ID_HDD, TDLS_LOG_LEVEL,
13301 "%s: TDLS mode is disabled OR not enabled in FW."
13302 MAC_ADDRESS_STR " action %d declined.",
13303 __func__, MAC_ADDR_ARRAY(peer), action_code);
Mohit Khanna698ba2a2012-12-04 15:08:18 -080013304 return -ENOTSUPP;
13305 }
Lee Hoonkic1262f22013-01-24 21:59:00 -080013306
Hoonki Lee27511902013-03-14 18:19:06 -070013307 /* other than teardown frame, other mgmt frames are not sent if disabled */
13308 if (SIR_MAC_TDLS_TEARDOWN != action_code)
13309 {
13310 /* if tdls_mode is disabled to respond to peer's request */
13311 if (eTDLS_SUPPORT_DISABLED == pHddCtx->tdls_mode)
13312 {
13313 VOS_TRACE( VOS_MODULE_ID_HDD, TDLS_LOG_LEVEL,
13314 "%s: " MAC_ADDRESS_STR
Gopichand Nakkala34d1b062013-03-19 15:28:33 -070013315 " TDLS mode is disabled. action %d declined.",
13316 __func__, MAC_ADDR_ARRAY(peer), action_code);
Hoonki Lee27511902013-03-14 18:19:06 -070013317
13318 return -ENOTSUPP;
13319 }
Agarwal Ashish4b87f922014-06-18 03:03:21 +053013320
13321 if (vos_max_concurrent_connections_reached())
13322 {
13323 hddLog(VOS_TRACE_LEVEL_INFO, FL("Reached max concurrent connections"));
13324 return -EINVAL;
13325 }
Hoonki Lee27511902013-03-14 18:19:06 -070013326 }
13327
Gopichand Nakkalab977a972013-02-18 19:15:09 -080013328 if (WLAN_IS_TDLS_SETUP_ACTION(action_code))
13329 {
Madan Mohan Koyyalamudi96797442013-10-08 16:04:42 +053013330 if (NULL != wlan_hdd_tdls_is_progress(pHddCtx, peer, TRUE))
Gopichand Nakkalab977a972013-02-18 19:15:09 -080013331 {
13332 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Gopichand Nakkalac87400e2013-03-13 18:51:00 -070013333 "%s: " MAC_ADDRESS_STR
Gopichand Nakkala34d1b062013-03-19 15:28:33 -070013334 " TDLS setup is ongoing. action %d declined.",
13335 __func__, MAC_ADDR_ARRAY(peer), action_code);
13336 return -EPERM;
Gopichand Nakkalab977a972013-02-18 19:15:09 -080013337 }
13338 }
13339
Hoonki Lee11f7dda2013-02-14 16:55:44 -080013340 if (SIR_MAC_TDLS_SETUP_REQ == action_code ||
13341 SIR_MAC_TDLS_SETUP_RSP == action_code )
Lee Hoonkic1262f22013-01-24 21:59:00 -080013342 {
Rajesh Chauhana34c6e62014-03-25 16:37:58 +053013343 numCurrTdlsPeers = wlan_hdd_tdlsConnectedPeers(pAdapter);
13344 if (HDD_MAX_NUM_TDLS_STA <= numCurrTdlsPeers)
Lee Hoonkic1262f22013-01-24 21:59:00 -080013345 {
13346 /* supplicant still sends tdls_mgmt(SETUP_REQ) even after
13347 we return error code at 'add_station()'. Hence we have this
13348 check again in addtion to add_station().
13349 Anyway, there is no hard to double-check. */
Hoonki Lee11f7dda2013-02-14 16:55:44 -080013350 if (SIR_MAC_TDLS_SETUP_REQ == action_code)
Lee Hoonkic1262f22013-01-24 21:59:00 -080013351 {
Gopichand Nakkalac87400e2013-03-13 18:51:00 -070013352 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
13353 "%s: " MAC_ADDRESS_STR
Rajesh Chauhana34c6e62014-03-25 16:37:58 +053013354 " TDLS Max peer already connected. action (%d) declined. Num of peers (%d), Max allowed (%d).",
13355 __func__, MAC_ADDR_ARRAY(peer), action_code,
13356 numCurrTdlsPeers, HDD_MAX_NUM_TDLS_STA);
Sunil Dutt388ac8f2013-11-28 18:06:52 +053013357 return -EINVAL;
Lee Hoonkic1262f22013-01-24 21:59:00 -080013358 }
13359 else
13360 {
Gopichand Nakkalab977a972013-02-18 19:15:09 -080013361 /* maximum reached. tweak to send error code to peer and return
13362 error code to supplicant */
Lee Hoonkic1262f22013-01-24 21:59:00 -080013363 status_code = eSIR_MAC_UNSPEC_FAILURE_STATUS;
Gopichand Nakkalac87400e2013-03-13 18:51:00 -070013364 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
13365 "%s: " MAC_ADDRESS_STR
Rajesh Chauhana34c6e62014-03-25 16:37:58 +053013366 " TDLS Max peer already connected, send response status (%d). Num of peers (%d), Max allowed (%d).",
13367 __func__, MAC_ADDR_ARRAY(peer), status_code,
13368 numCurrTdlsPeers, HDD_MAX_NUM_TDLS_STA);
Gopichand Nakkala05922802013-03-14 12:23:19 -070013369 max_sta_failed = -EPERM;
Gopichand Nakkalab977a972013-02-18 19:15:09 -080013370 /* fall through to send setup resp with failure status
13371 code */
Lee Hoonkic1262f22013-01-24 21:59:00 -080013372 }
13373 }
Hoonki Lee11f7dda2013-02-14 16:55:44 -080013374 else
13375 {
13376 hddTdlsPeer_t *pTdlsPeer;
Madan Mohan Koyyalamudi96797442013-10-08 16:04:42 +053013377 pTdlsPeer = wlan_hdd_tdls_find_peer(pAdapter, peer, TRUE);
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -070013378 if (pTdlsPeer && TDLS_IS_CONNECTED(pTdlsPeer))
Hoonki Lee11f7dda2013-02-14 16:55:44 -080013379 {
Gopichand Nakkalac87400e2013-03-13 18:51:00 -070013380 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Gopichand Nakkala34d1b062013-03-19 15:28:33 -070013381 "%s:" MAC_ADDRESS_STR " already connected. action %d declined.",
13382 __func__, MAC_ADDR_ARRAY(peer), action_code);
Hoonki Lee11f7dda2013-02-14 16:55:44 -080013383 return -EPERM;
13384 }
13385 }
Lee Hoonkic1262f22013-01-24 21:59:00 -080013386 }
Hoonki Lee11f7dda2013-02-14 16:55:44 -080013387 vos_mem_copy(peerMac, peer, 6);
Mohit Khanna698ba2a2012-12-04 15:08:18 -080013388
Hoonki Lee1090c6a2013-01-16 17:40:54 -080013389#ifdef WLAN_FEATURE_TDLS_DEBUG
13390 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Arun Kumar Khandavalli9fb625e2014-03-17 16:07:40 +053013391 "%s: " MAC_ADDRESS_STR " action %d, dialog_token %d status %d, len = %zu",
Gopichand Nakkalac87400e2013-03-13 18:51:00 -070013392 "tdls_mgmt", MAC_ADDR_ARRAY(peer),
13393 action_code, dialog_token, status_code, len);
Hoonki Lee1090c6a2013-01-16 17:40:54 -080013394#endif
Mohit Khanna698ba2a2012-12-04 15:08:18 -080013395
Hoonki Leea34dd892013-02-05 22:56:02 -080013396 /*Except teardown responder will not be used so just make 0*/
13397 responder = 0;
Hoonki Lee11f7dda2013-02-14 16:55:44 -080013398 if (SIR_MAC_TDLS_TEARDOWN == action_code)
Hoonki Leea34dd892013-02-05 22:56:02 -080013399 {
Gopichand Nakkala97a65fd2013-04-16 16:59:38 -070013400
13401 hddTdlsPeer_t *pTdlsPeer;
Madan Mohan Koyyalamudi96797442013-10-08 16:04:42 +053013402 pTdlsPeer = wlan_hdd_tdls_find_peer(pAdapter, peerMac, TRUE);
Gopichand Nakkala97a65fd2013-04-16 16:59:38 -070013403
13404 if(pTdlsPeer && TDLS_IS_CONNECTED(pTdlsPeer))
13405 responder = pTdlsPeer->is_responder;
13406 else
Hoonki Leea34dd892013-02-05 22:56:02 -080013407 {
Gopichand Nakkala97a65fd2013-04-16 16:59:38 -070013408 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Arun Kumar Khandavalli9fb625e2014-03-17 16:07:40 +053013409 "%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 -070013410 __func__, MAC_ADDR_ARRAY(peer), (NULL == pTdlsPeer) ? -1 : pTdlsPeer->link_status,
13411 dialog_token, status_code, len);
13412 return -EPERM;
Hoonki Leea34dd892013-02-05 22:56:02 -080013413 }
Mohit Khanna698ba2a2012-12-04 15:08:18 -080013414 }
Mohit Khanna698ba2a2012-12-04 15:08:18 -080013415
Gopichand Nakkala2f1ff152013-07-01 11:27:43 +053013416 /* For explicit trigger of DIS_REQ come out of BMPS for
13417 successfully receiving DIS_RSP from peer. */
Hoonki Lee14621352013-04-16 17:51:19 -070013418 if ((SIR_MAC_TDLS_SETUP_RSP == action_code) ||
Gopichand Nakkala2f1ff152013-07-01 11:27:43 +053013419 (SIR_MAC_TDLS_DIS_RSP == action_code) ||
13420 (SIR_MAC_TDLS_DIS_REQ == action_code))
Hoonki Lee14621352013-04-16 17:51:19 -070013421 {
13422 if (TRUE == sme_IsPmcBmps(WLAN_HDD_GET_HAL_CTX(pAdapter)))
13423 {
13424 VOS_TRACE( VOS_MODULE_ID_HDD, TDLS_LOG_LEVEL,
Gopichand Nakkala2f1ff152013-07-01 11:27:43 +053013425 "%s: Sending frame action_code %u.Disable BMPS", __func__, action_code);
Hoonki Lee14621352013-04-16 17:51:19 -070013426 hdd_disable_bmps_imps(pHddCtx, WLAN_HDD_INFRA_STATION);
13427 }
Gopichand Nakkala2f1ff152013-07-01 11:27:43 +053013428 if (SIR_MAC_TDLS_DIS_REQ != action_code)
13429 wlan_hdd_tdls_set_cap(pAdapter, peerMac, eTDLS_CAP_SUPPORTED);
Hoonki Lee14621352013-04-16 17:51:19 -070013430 }
13431
Hoonki Lee5305c3a2013-04-29 23:28:59 -070013432 /* make sure doesn't call send_mgmt() while it is pending */
13433 if (TDLS_CTX_MAGIC == pAdapter->mgmtTxCompletionStatus)
13434 {
13435 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Arif Hussain6d2a3322013-11-17 19:50:10 -080013436 "%s: " MAC_ADDRESS_STR " action %d couldn't sent, as one is pending. return EBUSY",
Hoonki Lee5305c3a2013-04-29 23:28:59 -070013437 __func__, MAC_ADDR_ARRAY(peer), action_code);
13438 return -EBUSY;
13439 }
13440
13441 pAdapter->mgmtTxCompletionStatus = TDLS_CTX_MAGIC;
Gopichand Nakkalab977a972013-02-18 19:15:09 -080013442 INIT_COMPLETION(pAdapter->tdls_mgmt_comp);
13443
Mohit Khanna698ba2a2012-12-04 15:08:18 -080013444 status = sme_SendTdlsMgmtFrame(WLAN_HDD_GET_HAL_CTX(pAdapter), pAdapter->sessionId,
Pradeep Reddy POTTETIca171f82014-03-21 14:17:35 +053013445 peerMac, action_code, dialog_token, status_code, peer_capability, (tANI_U8 *)buf, len, responder);
Mohit Khanna698ba2a2012-12-04 15:08:18 -080013446
Gopichand Nakkalab977a972013-02-18 19:15:09 -080013447 if (VOS_STATUS_SUCCESS != status)
13448 {
Mohit Khanna698ba2a2012-12-04 15:08:18 -080013449 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
13450 "%s: sme_SendTdlsMgmtFrame failed!", __func__);
Hoonki Lee5305c3a2013-04-29 23:28:59 -070013451 pAdapter->mgmtTxCompletionStatus = FALSE;
Hoonki Lee14621352013-04-16 17:51:19 -070013452 wlan_hdd_tdls_check_bmps(pAdapter);
Sunil Dutt388ac8f2013-11-28 18:06:52 +053013453 return -EINVAL;
Mohit Khanna698ba2a2012-12-04 15:08:18 -080013454 }
13455
Hoonki Leed37cbb32013-04-20 00:31:14 -070013456 rc = wait_for_completion_interruptible_timeout(&pAdapter->tdls_mgmt_comp,
13457 msecs_to_jiffies(WAIT_TIME_TDLS_MGMT));
13458
13459 if ((rc <= 0) || (TRUE != pAdapter->mgmtTxCompletionStatus))
Gopichand Nakkalab977a972013-02-18 19:15:09 -080013460 {
Hoonki Leed37cbb32013-04-20 00:31:14 -070013461 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Jeff Johnson0299d0a2013-10-30 12:37:43 -070013462 "%s: Mgmt Tx Completion failed status %ld TxCompletion %u",
Hoonki Leed37cbb32013-04-20 00:31:14 -070013463 __func__, rc, pAdapter->mgmtTxCompletionStatus);
Hoonki Lee5305c3a2013-04-29 23:28:59 -070013464 pAdapter->mgmtTxCompletionStatus = FALSE;
Yue Ma4f55ef32014-01-23 16:45:33 -080013465
13466 if (pHddCtx->isLogpInProgress)
13467 {
13468 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
13469 "%s: LOGP in Progress. Ignore!!!", __func__);
13470 return -EAGAIN;
13471 }
13472
Hoonki Leed37cbb32013-04-20 00:31:14 -070013473 wlan_hdd_tdls_check_bmps(pAdapter);
Sunil Dutt388ac8f2013-11-28 18:06:52 +053013474 return -EINVAL;
Gopichand Nakkalab977a972013-02-18 19:15:09 -080013475 }
13476
Gopichand Nakkala05922802013-03-14 12:23:19 -070013477 if (max_sta_failed)
Hoonki Lee14621352013-04-16 17:51:19 -070013478 {
13479 wlan_hdd_tdls_check_bmps(pAdapter);
Gopichand Nakkala05922802013-03-14 12:23:19 -070013480 return max_sta_failed;
Hoonki Lee14621352013-04-16 17:51:19 -070013481 }
Gopichand Nakkalab977a972013-02-18 19:15:09 -080013482
Hoonki Leea34dd892013-02-05 22:56:02 -080013483 if (SIR_MAC_TDLS_SETUP_RSP == action_code)
13484 {
Gopichand Nakkala4327a152013-03-04 23:22:42 -080013485 wlan_hdd_tdls_set_responder(pAdapter, peerMac, TRUE);
Hoonki Leea34dd892013-02-05 22:56:02 -080013486 }
13487 else if (SIR_MAC_TDLS_SETUP_CNF == action_code)
13488 {
Gopichand Nakkala4327a152013-03-04 23:22:42 -080013489 wlan_hdd_tdls_set_responder(pAdapter, peerMac, FALSE);
Hoonki Leea34dd892013-02-05 22:56:02 -080013490 }
Mohit Khanna698ba2a2012-12-04 15:08:18 -080013491
13492 return 0;
13493}
13494
Atul Mittal115287b2014-07-08 13:26:33 +053013495
13496int wlan_hdd_tdls_extctrl_config_peer(hdd_adapter_t *pAdapter,
13497 u8 *peer,
13498 cfg80211_exttdls_callback callback)
13499{
13500
13501 hddTdlsPeer_t *pTdlsPeer;
13502 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
13503 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
13504 " %s : NL80211_TDLS_SETUP for " MAC_ADDRESS_STR,
13505 __func__, MAC_ADDR_ARRAY(peer));
13506
13507 if ( (FALSE == pHddCtx->cfg_ini->fTDLSExternalControl) ||
13508 (FALSE == pHddCtx->cfg_ini->fEnableTDLSImplicitTrigger) ) {
13509
13510 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
13511 " %s TDLS External control and Implicit Trigger not enabled ",
13512 __func__);
13513 return -ENOTSUPP;
13514 }
13515
13516 /* To cater the requirement of establishing the TDLS link
13517 * irrespective of the data traffic , get an entry of TDLS peer.
13518 */
13519 pTdlsPeer = wlan_hdd_tdls_get_peer(pAdapter, peer);
13520 if (pTdlsPeer == NULL) {
13521 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
13522 "%s: peer " MAC_ADDRESS_STR " not existing",
13523 __func__, MAC_ADDR_ARRAY(peer));
13524 return -EINVAL;
13525 }
13526
13527 if ( 0 != wlan_hdd_tdls_set_force_peer(pAdapter, peer, TRUE) ) {
13528
13529 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
13530 " %s TDLS Add Force Peer Failed",
13531 __func__);
13532 return -EINVAL;
13533 }
13534 /*EXT TDLS*/
13535
13536 if ( 0 != wlan_hdd_set_callback(pTdlsPeer, callback) ) {
13537 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
13538 " %s TDLS set callback Failed",
13539 __func__);
13540 return -EINVAL;
13541 }
13542
13543 return(0);
13544
13545}
13546
13547int wlan_hdd_tdls_extctrl_deconfig_peer(hdd_adapter_t *pAdapter, u8 *peer)
13548{
13549
13550 hddTdlsPeer_t *pTdlsPeer;
13551 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
13552 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
13553 " %s : NL80211_TDLS_TEARDOWN for " MAC_ADDRESS_STR,
13554 __func__, MAC_ADDR_ARRAY(peer));
13555
13556 if ( (FALSE == pHddCtx->cfg_ini->fTDLSExternalControl) ||
13557 (FALSE == pHddCtx->cfg_ini->fEnableTDLSImplicitTrigger) ) {
13558
13559 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
13560 " %s TDLS External control and Implicit Trigger not enabled ",
13561 __func__);
13562 return -ENOTSUPP;
13563 }
13564
13565
13566 pTdlsPeer = wlan_hdd_tdls_find_peer(pAdapter, peer, TRUE);
13567
13568 if ( NULL == pTdlsPeer ) {
13569 hddLog(VOS_TRACE_LEVEL_INFO, "%s: " MAC_ADDRESS_STR
13570 " peer not exsting",
13571 __func__, MAC_ADDR_ARRAY(peer));
13572 return -EINVAL;
13573 }
13574 else {
13575 wlan_hdd_tdls_indicate_teardown(pAdapter, pTdlsPeer,
13576 eSIR_MAC_TDLS_TEARDOWN_UNSPEC_REASON);
13577 }
13578
13579 if ( 0 != wlan_hdd_tdls_set_force_peer(pAdapter, peer, FALSE) )
13580 return -EINVAL;
13581
13582 /*EXT TDLS*/
13583
13584 if ( 0 != wlan_hdd_set_callback(pTdlsPeer, NULL )) {
13585
13586 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
13587 " %s TDLS set callback Failed",
13588 __func__);
13589 return -EINVAL;
13590 }
13591 return(0);
13592
13593}
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053013594static int __wlan_hdd_cfg80211_tdls_oper(struct wiphy *wiphy, struct net_device *dev,
Mohit Khanna698ba2a2012-12-04 15:08:18 -080013595 u8 *peer, enum nl80211_tdls_operation oper)
13596{
13597 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
13598 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053013599 int status;
Hoonki Lee5305c3a2013-04-29 23:28:59 -070013600 hddTdlsPeer_t *pTdlsPeer;
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053013601
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053013602 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
13603 TRACE_CODE_HDD_CFG80211_TDLS_OPER,
13604 pAdapter->sessionId, oper));
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053013605 if ( NULL == peer )
Mohit Khanna698ba2a2012-12-04 15:08:18 -080013606 {
Gopichand Nakkalab977a972013-02-18 19:15:09 -080013607 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Chilam Ngc4244af2013-04-01 15:37:32 -070013608 "%s: Invalid arguments", __func__);
Mohit Khanna698ba2a2012-12-04 15:08:18 -080013609 return -EINVAL;
13610 }
Hoonki Lee1090c6a2013-01-16 17:40:54 -080013611
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053013612 status = wlan_hdd_validate_context(pHddCtx);
13613
13614 if (0 != status)
Sameer Thalappil75ea31a2013-02-21 19:38:16 -080013615 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053013616 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
13617 "%s: HDD context is not valid", __func__);
13618 return status;
Sameer Thalappil75ea31a2013-02-21 19:38:16 -080013619 }
13620
Mohit Khanna698ba2a2012-12-04 15:08:18 -080013621
13622 if( FALSE == pHddCtx->cfg_ini->fEnableTDLSSupport ||
Hoonki Lee1090c6a2013-01-16 17:40:54 -080013623 FALSE == sme_IsFeatureSupportedByFW(TDLS))
Mohit Khanna698ba2a2012-12-04 15:08:18 -080013624 {
Hoonki Lee1090c6a2013-01-16 17:40:54 -080013625 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Chilam Ngc4244af2013-04-01 15:37:32 -070013626 "TDLS Disabled in INI OR not enabled in FW. "
13627 "Cannot process TDLS commands");
Mohit Khanna698ba2a2012-12-04 15:08:18 -080013628 return -ENOTSUPP;
13629 }
13630
13631 switch (oper) {
13632 case NL80211_TDLS_ENABLE_LINK:
13633 {
Mohit Khanna698ba2a2012-12-04 15:08:18 -080013634 VOS_STATUS status;
c_hpothu6ff1c3c2013-10-01 19:01:57 +053013635 long ret;
Gopichand Nakkala79ff85d2013-05-27 17:05:29 +053013636 tCsrTdlsLinkEstablishParams tdlsLinkEstablishParams;
Mohit Khanna698ba2a2012-12-04 15:08:18 -080013637
Sunil Dutt41de4e22013-11-14 18:09:02 +053013638 pTdlsPeer = wlan_hdd_tdls_find_peer(pAdapter, peer, TRUE);
13639
13640 if ( NULL == pTdlsPeer ) {
13641 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: " MAC_ADDRESS_STR
13642 " (oper %d) not exsting. ignored",
13643 __func__, MAC_ADDR_ARRAY(peer), (int)oper);
13644 return -EINVAL;
13645 }
13646
13647 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
13648 "%s: " MAC_ADDRESS_STR " link_status %d (%s) ", "tdls_oper",
13649 MAC_ADDR_ARRAY(peer), pTdlsPeer->link_status,
13650 "NL80211_TDLS_ENABLE_LINK");
13651
Gopichand Nakkala2f4a2822013-04-17 11:22:01 -070013652 if (!TDLS_STA_INDEX_VALID(pTdlsPeer->staId))
13653 {
13654 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Invalid Staion Index %u "
13655 MAC_ADDRESS_STR " failed",
13656 __func__, pTdlsPeer->staId, MAC_ADDR_ARRAY(peer));
13657 return -EINVAL;
13658 }
13659
Hoonki Lee5305c3a2013-04-29 23:28:59 -070013660 if (eTDLS_LINK_CONNECTED != pTdlsPeer->link_status)
Gopichand Nakkalac87400e2013-03-13 18:51:00 -070013661 {
Madan Mohan Koyyalamudice419872013-09-13 19:36:52 +053013662 if (IS_ADVANCE_TDLS_ENABLE) {
Gopichand Nakkala24be5312013-07-02 16:47:12 +053013663
Madan Mohan Koyyalamudice419872013-09-13 19:36:52 +053013664 if (0 != wlan_hdd_tdls_get_link_establish_params(
13665 pAdapter, peer,&tdlsLinkEstablishParams)) {
13666 return -EINVAL;
13667 }
13668 INIT_COMPLETION(pAdapter->tdls_link_establish_req_comp);
Gopichand Nakkala79ff85d2013-05-27 17:05:29 +053013669
Madan Mohan Koyyalamudice419872013-09-13 19:36:52 +053013670 sme_SendTdlsLinkEstablishParams(WLAN_HDD_GET_HAL_CTX(pAdapter),
13671 pAdapter->sessionId, peer, &tdlsLinkEstablishParams);
13672 /* Send TDLS peer UAPSD capabilities to the firmware and
13673 * register with the TL on after the response for this operation
13674 * is received .
13675 */
13676 ret = wait_for_completion_interruptible_timeout(
13677 &pAdapter->tdls_link_establish_req_comp,
13678 msecs_to_jiffies(WAIT_TIME_TDLS_LINK_ESTABLISH_REQ));
13679 if (ret <= 0)
13680 {
13681 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
13682 "%s: Link Establish Request Faled Status %ld",
13683 __func__, ret);
13684 return -EINVAL;
13685 }
Gopichand Nakkala79ff85d2013-05-27 17:05:29 +053013686 }
Atul Mittal115287b2014-07-08 13:26:33 +053013687 wlan_hdd_tdls_set_peer_link_status(pTdlsPeer,
13688 eTDLS_LINK_CONNECTED,
13689 eTDLS_LINK_SUCCESS);
Gopichand Nakkala471708b2013-06-04 20:03:01 +053013690 /* Mark TDLS client Authenticated .*/
13691 status = WLANTL_ChangeSTAState( pHddCtx->pvosContext,
13692 pTdlsPeer->staId,
13693 WLANTL_STA_AUTHENTICATED);
Gopichand Nakkalaccd3a382013-03-19 13:56:10 -070013694 if (VOS_STATUS_SUCCESS == status)
13695 {
Hoonki Lee14621352013-04-16 17:51:19 -070013696 if (pTdlsPeer->is_responder == 0)
13697 {
13698 v_U8_t staId = (v_U8_t)pTdlsPeer->staId;
13699
13700 wlan_hdd_tdls_timer_restart(pAdapter,
13701 &pTdlsPeer->initiatorWaitTimeoutTimer,
13702 WAIT_TIME_TDLS_INITIATOR);
13703 /* suspend initiator TX until it receives direct packet from the
13704 reponder or WAIT_TIME_TDLS_INITIATOR timer expires */
13705 WLANTL_SuspendDataTx( (WLAN_HDD_GET_CTX(pAdapter))->pvosContext,
13706 &staId, NULL);
13707 }
Gopichand Nakkalaccd3a382013-03-19 13:56:10 -070013708 wlan_hdd_tdls_increment_peer_count(pAdapter);
13709 }
Gopichand Nakkalac87400e2013-03-13 18:51:00 -070013710 wlan_hdd_tdls_check_bmps(pAdapter);
Gopichand Nakkala79ff85d2013-05-27 17:05:29 +053013711
13712 /* Update TL about the UAPSD masks , to route the packets to firmware */
Gopichand Nakkala574f6d12013-06-27 19:38:43 +053013713 if ((TRUE == pHddCtx->cfg_ini->fEnableTDLSBufferSta)
13714 || pHddCtx->cfg_ini->fTDLSUapsdMask )
Gopichand Nakkala79ff85d2013-05-27 17:05:29 +053013715 {
Gopichand Nakkala574f6d12013-06-27 19:38:43 +053013716 int ac;
13717 uint8 ucAc[4] = { WLANTL_AC_VO,
13718 WLANTL_AC_VI,
13719 WLANTL_AC_BK,
13720 WLANTL_AC_BE };
13721 uint8 tlTid[4] = { 7, 5, 2, 3 } ;
13722 for(ac=0; ac < 4; ac++)
13723 {
13724 status = WLANTL_EnableUAPSDForAC( (WLAN_HDD_GET_CTX(pAdapter))->pvosContext,
13725 pTdlsPeer->staId, ucAc[ac],
13726 tlTid[ac], tlTid[ac], 0, 0,
13727 WLANTL_BI_DIR );
13728 }
Gopichand Nakkala79ff85d2013-05-27 17:05:29 +053013729 }
Gopichand Nakkalac87400e2013-03-13 18:51:00 -070013730 }
13731
Mohit Khanna698ba2a2012-12-04 15:08:18 -080013732 }
13733 break;
13734 case NL80211_TDLS_DISABLE_LINK:
Lee Hoonkic1262f22013-01-24 21:59:00 -080013735 {
Sunil Dutt41de4e22013-11-14 18:09:02 +053013736 pTdlsPeer = wlan_hdd_tdls_find_peer(pAdapter, peer, TRUE);
13737
13738 if ( NULL == pTdlsPeer ) {
13739 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: " MAC_ADDRESS_STR
13740 " (oper %d) not exsting. ignored",
13741 __func__, MAC_ADDR_ARRAY(peer), (int)oper);
13742 return -EINVAL;
13743 }
13744
13745 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
13746 "%s: " MAC_ADDRESS_STR " link_status %d (%s) ", "tdls_oper",
13747 MAC_ADDR_ARRAY(peer), pTdlsPeer->link_status,
13748 "NL80211_TDLS_DISABLE_LINK");
13749
Hoonki Lee5305c3a2013-04-29 23:28:59 -070013750 if(TDLS_STA_INDEX_VALID(pTdlsPeer->staId))
Lee Hoonkic1262f22013-01-24 21:59:00 -080013751 {
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -070013752 long status;
13753
Atul Mittal271a7652014-09-12 13:18:22 +053013754
13755 wlan_hdd_tdls_set_peer_link_status(pTdlsPeer,
13756 eTDLS_LINK_TEARING,
13757 (pTdlsPeer->link_status == eTDLS_LINK_TEARING)?
13758 eTDLS_LINK_UNSPECIFIED:
13759 eTDLS_LINK_DROPPED_BY_REMOTE);
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -070013760 INIT_COMPLETION(pAdapter->tdls_del_station_comp);
13761
Lee Hoonkic1262f22013-01-24 21:59:00 -080013762 sme_DeleteTdlsPeerSta( WLAN_HDD_GET_HAL_CTX(pAdapter),
13763 pAdapter->sessionId, peer );
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -070013764
13765 status = wait_for_completion_interruptible_timeout(&pAdapter->tdls_del_station_comp,
13766 msecs_to_jiffies(WAIT_TIME_TDLS_DEL_STA));
Atul Mittal271a7652014-09-12 13:18:22 +053013767 wlan_hdd_tdls_set_peer_link_status(pTdlsPeer,
13768 eTDLS_LINK_IDLE,
13769 (pTdlsPeer->link_status == eTDLS_LINK_TEARING)?
13770 eTDLS_LINK_UNSPECIFIED:
13771 eTDLS_LINK_DROPPED_BY_REMOTE);
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -070013772 if (status <= 0)
13773 {
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -070013774 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
13775 "%s: Del station failed status %ld",
13776 __func__, status);
13777 return -EPERM;
13778 }
Lee Hoonkic1262f22013-01-24 21:59:00 -080013779 }
13780 else
13781 {
Gopichand Nakkalac87400e2013-03-13 18:51:00 -070013782 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
13783 "%s: TDLS Peer Station doesn't exist.", __func__);
Lee Hoonkic1262f22013-01-24 21:59:00 -080013784 }
Lee Hoonkic1262f22013-01-24 21:59:00 -080013785 }
Gopichand Nakkalac87400e2013-03-13 18:51:00 -070013786 break;
Mohit Khanna698ba2a2012-12-04 15:08:18 -080013787 case NL80211_TDLS_TEARDOWN:
Sunil Dutt41de4e22013-11-14 18:09:02 +053013788 {
Atul Mittal115287b2014-07-08 13:26:33 +053013789 status = wlan_hdd_tdls_extctrl_deconfig_peer(pAdapter, peer);
Sunil Dutt41de4e22013-11-14 18:09:02 +053013790
Atul Mittal115287b2014-07-08 13:26:33 +053013791 if (0 != status)
13792 {
13793 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
13794 "%s: Error in TDLS Teardown", __func__);
13795 return status;
Sunil Dutt41de4e22013-11-14 18:09:02 +053013796 }
Sunil Dutt41de4e22013-11-14 18:09:02 +053013797 break;
13798 }
Mohit Khanna698ba2a2012-12-04 15:08:18 -080013799 case NL80211_TDLS_SETUP:
Sunil Dutt41de4e22013-11-14 18:09:02 +053013800 {
Atul Mittal115287b2014-07-08 13:26:33 +053013801 status = wlan_hdd_tdls_extctrl_config_peer(pAdapter,
13802 peer,
13803 NULL);
Sunil Dutt41de4e22013-11-14 18:09:02 +053013804
Atul Mittal115287b2014-07-08 13:26:33 +053013805 if (0 != status)
13806 {
13807 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
13808 "%s: Error in TDLS Setup", __func__);
13809 return status;
Naresh Jayaram937abdf2013-11-26 19:50:25 +053013810 }
Naresh Jayaramdb4514b2013-11-25 18:08:10 +053013811 break;
Sunil Dutt41de4e22013-11-14 18:09:02 +053013812 }
Mohit Khanna698ba2a2012-12-04 15:08:18 -080013813 case NL80211_TDLS_DISCOVERY_REQ:
13814 /* We don't support in-driver setup/teardown/discovery */
c_hpothu6ff1c3c2013-10-01 19:01:57 +053013815 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_WARN,
13816 "%s: We don't support in-driver setup/teardown/discovery "
13817 ,__func__);
Mohit Khanna698ba2a2012-12-04 15:08:18 -080013818 return -ENOTSUPP;
13819 default:
c_hpothu6ff1c3c2013-10-01 19:01:57 +053013820 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
13821 "%s: unsupported event",__func__);
Mohit Khanna698ba2a2012-12-04 15:08:18 -080013822 return -ENOTSUPP;
13823 }
13824 return 0;
13825}
Chilam NG571c65a2013-01-19 12:27:36 +053013826
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053013827static int wlan_hdd_cfg80211_tdls_oper(struct wiphy *wiphy, struct net_device *dev,
13828 u8 *peer, enum nl80211_tdls_operation oper)
13829{
13830 int ret;
13831
13832 vos_ssr_protect(__func__);
13833 ret = __wlan_hdd_cfg80211_tdls_oper(wiphy, dev, peer, oper);
13834 vos_ssr_unprotect(__func__);
13835
13836 return ret;
13837}
13838
Chilam NG571c65a2013-01-19 12:27:36 +053013839int wlan_hdd_cfg80211_send_tdls_discover_req(struct wiphy *wiphy,
13840 struct net_device *dev, u8 *peer)
13841{
Arif Hussaina7c8e412013-11-20 11:06:42 -080013842 hddLog(VOS_TRACE_LEVEL_INFO,
13843 "tdls send discover req: "MAC_ADDRESS_STR,
13844 MAC_ADDR_ARRAY(peer));
Chilam NG571c65a2013-01-19 12:27:36 +053013845
Sunil Dutt Undekarieacac6f2014-03-21 14:08:53 +053013846#if TDLS_MGMT_VERSION2
13847 return wlan_hdd_cfg80211_tdls_mgmt(wiphy, dev, peer,
13848 WLAN_TDLS_DISCOVERY_REQUEST, 1, 0, 0, NULL, 0);
13849#else
Chilam NG571c65a2013-01-19 12:27:36 +053013850 return wlan_hdd_cfg80211_tdls_mgmt(wiphy, dev, peer,
13851 WLAN_TDLS_DISCOVERY_REQUEST, 1, 0, NULL, 0);
Sunil Dutt Undekarieacac6f2014-03-21 14:08:53 +053013852#endif
Chilam NG571c65a2013-01-19 12:27:36 +053013853}
Mohit Khanna698ba2a2012-12-04 15:08:18 -080013854#endif
13855
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053013856#ifdef WLAN_FEATURE_GTK_OFFLOAD
13857/*
13858 * FUNCTION: wlan_hdd_cfg80211_update_replayCounterCallback
13859 * Callback rountine called upon receiving response for
13860 * get offload info
13861 */
13862void wlan_hdd_cfg80211_update_replayCounterCallback(void *callbackContext,
13863 tpSirGtkOffloadGetInfoRspParams pGtkOffloadGetInfoRsp)
13864{
13865
13866 hdd_adapter_t *pAdapter = (hdd_adapter_t *)callbackContext;
Gopichand Nakkalad36ee622013-05-07 14:13:27 +053013867 tANI_U8 tempReplayCounter[8];
13868 hdd_station_ctx_t *pHddStaCtx;
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053013869
13870 ENTER();
13871
13872 if (NULL == pAdapter)
13873 {
Agarwal Ashish971c2882013-10-30 20:11:12 +053013874 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053013875 "%s: HDD adapter is Null", __func__);
13876 return ;
13877 }
13878
13879 if (NULL == pGtkOffloadGetInfoRsp)
13880 {
13881 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
13882 "%s: pGtkOffloadGetInfoRsp is Null", __func__);
13883 return ;
13884 }
13885
13886 if (VOS_STATUS_SUCCESS != pGtkOffloadGetInfoRsp->ulStatus)
13887 {
13888 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
13889 "%s: wlan Failed to get replay counter value",
13890 __func__);
13891 return ;
13892 }
13893
Gopichand Nakkalad36ee622013-05-07 14:13:27 +053013894 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
13895 /* Update replay counter */
13896 pHddStaCtx->gtkOffloadReqParams.ullKeyReplayCounter =
13897 pGtkOffloadGetInfoRsp->ullKeyReplayCounter;
13898
13899 {
13900 /* changing from little to big endian since supplicant
13901 * works on big endian format
13902 */
13903 int i;
13904 tANI_U8 *p = (tANI_U8 *)&pGtkOffloadGetInfoRsp->ullKeyReplayCounter;
13905
13906 for (i = 0; i < 8; i++)
13907 {
13908 tempReplayCounter[7-i] = (tANI_U8)p[i];
13909 }
13910 }
13911
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053013912 /* Update replay counter to NL */
13913 cfg80211_gtk_rekey_notify(pAdapter->dev, pGtkOffloadGetInfoRsp->bssId,
Gopichand Nakkalad36ee622013-05-07 14:13:27 +053013914 tempReplayCounter, GFP_KERNEL);
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053013915}
13916
13917/*
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053013918 * FUNCTION: __wlan_hdd_cfg80211_set_rekey_data
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053013919 * This function is used to offload GTK rekeying job to the firmware.
13920 */
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053013921int __wlan_hdd_cfg80211_set_rekey_data(struct wiphy *wiphy, struct net_device *dev,
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053013922 struct cfg80211_gtk_rekey_data *data)
13923{
13924 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
13925 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
13926 hdd_station_ctx_t *pHddStaCtx;
13927 tHalHandle hHal;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053013928 int result;
Gopichand Nakkalad36ee622013-05-07 14:13:27 +053013929 tSirGtkOffloadParams hddGtkOffloadReqParams;
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053013930 eHalStatus status = eHAL_STATUS_FAILURE;
13931
13932 ENTER();
13933
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053013934
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053013935 if (NULL == pAdapter)
13936 {
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053013937 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053013938 "%s: HDD adapter is Null", __func__);
13939 return -ENODEV;
13940 }
13941
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053013942 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
13943 TRACE_CODE_HDD_CFG80211_SET_REKEY_DATA,
13944 pAdapter->sessionId, pAdapter->device_mode));
13945
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053013946 result = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053013947
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053013948 if (0 != result)
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053013949 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053013950 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
13951 "%s: HDD context is not valid", __func__);
13952 return result;
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053013953 }
13954
13955 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
13956 hHal = WLAN_HDD_GET_HAL_CTX(pAdapter);
13957 if (NULL == hHal)
13958 {
13959 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
13960 "%s: HAL context is Null!!!", __func__);
13961 return -EAGAIN;
13962 }
13963
Gopichand Nakkalad36ee622013-05-07 14:13:27 +053013964 pHddStaCtx->gtkOffloadReqParams.ulFlags = GTK_OFFLOAD_ENABLE;
13965 memcpy(pHddStaCtx->gtkOffloadReqParams.aKCK, data->kck, NL80211_KCK_LEN);
13966 memcpy(pHddStaCtx->gtkOffloadReqParams.aKEK, data->kek, NL80211_KEK_LEN);
13967 memcpy(pHddStaCtx->gtkOffloadReqParams.bssId, &pHddStaCtx->conn_info.bssId,
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053013968 WNI_CFG_BSSID_LEN);
Gopichand Nakkalad36ee622013-05-07 14:13:27 +053013969 {
13970 /* changing from big to little endian since driver
13971 * works on little endian format
13972 */
13973 tANI_U8 *p =
13974 (tANI_U8 *)&pHddStaCtx->gtkOffloadReqParams.ullKeyReplayCounter;
13975 int i;
13976
13977 for (i = 0; i < 8; i++)
13978 {
13979 p[7-i] = data->replay_ctr[i];
13980 }
13981 }
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053013982
13983 if (TRUE == pHddCtx->hdd_wlan_suspended)
13984 {
13985 /* if wlan is suspended, enable GTK offload directly from here */
Gopichand Nakkalad36ee622013-05-07 14:13:27 +053013986 memcpy(&hddGtkOffloadReqParams, &pHddStaCtx->gtkOffloadReqParams,
13987 sizeof (tSirGtkOffloadParams));
13988 status = sme_SetGTKOffload(hHal, &hddGtkOffloadReqParams,
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053013989 pAdapter->sessionId);
13990
13991 if (eHAL_STATUS_SUCCESS != status)
13992 {
13993 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
13994 "%s: sme_SetGTKOffload failed, returned %d",
13995 __func__, status);
13996 return status;
13997 }
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053013998 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
13999 "%s: sme_SetGTKOffload successfull", __func__);
14000 }
14001 else
14002 {
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053014003 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
14004 "%s: wlan not suspended GTKOffload request is stored",
14005 __func__);
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053014006 }
Gopichand Nakkalad36ee622013-05-07 14:13:27 +053014007
14008 return eHAL_STATUS_SUCCESS;
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053014009}
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053014010
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053014011int wlan_hdd_cfg80211_set_rekey_data(struct wiphy *wiphy, struct net_device *dev,
14012 struct cfg80211_gtk_rekey_data *data)
14013{
14014 int ret;
14015
14016 vos_ssr_protect(__func__);
14017 ret = __wlan_hdd_cfg80211_set_rekey_data(wiphy, dev, data);
14018 vos_ssr_unprotect(__func__);
14019
14020 return ret;
14021}
14022#endif /*WLAN_FEATURE_GTK_OFFLOAD*/
Gopichand Nakkalac005b7c2013-05-14 16:04:14 +053014023/*
14024 * FUNCTION: wlan_hdd_cfg80211_set_mac_acl
14025 * This function is used to set access control policy
14026 */
14027static int wlan_hdd_cfg80211_set_mac_acl(struct wiphy *wiphy,
14028 struct net_device *dev, const struct cfg80211_acl_data *params)
14029{
14030 int i;
14031 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
14032 hdd_hostapd_state_t *pHostapdState;
14033 tsap_Config_t *pConfig;
14034 v_CONTEXT_t pVosContext = NULL;
14035 hdd_context_t *pHddCtx;
14036 int status;
14037
14038 ENTER();
14039
14040 if (NULL == pAdapter)
14041 {
14042 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
14043 "%s: HDD adapter is Null", __func__);
14044 return -ENODEV;
14045 }
14046
14047 if (NULL == params)
14048 {
14049 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
14050 "%s: params is Null", __func__);
14051 return -EINVAL;
14052 }
14053
14054 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
14055 status = wlan_hdd_validate_context(pHddCtx);
14056
14057 if (0 != status)
14058 {
14059 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
14060 "%s: HDD context is not valid", __func__);
14061 return status;
14062 }
14063
14064 pVosContext = pHddCtx->pvosContext;
14065 pHostapdState = WLAN_HDD_GET_HOSTAP_STATE_PTR(pAdapter);
14066
14067 if (NULL == pHostapdState)
14068 {
14069 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
14070 "%s: pHostapdState is Null", __func__);
14071 return -EINVAL;
14072 }
14073
14074 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,"acl policy: = %d"
14075 "no acl entries = %d", params->acl_policy, params->n_acl_entries);
14076
14077 if (WLAN_HDD_SOFTAP == pAdapter->device_mode)
14078 {
14079 pConfig = &pAdapter->sessionCtx.ap.sapConfig;
14080
14081 /* default value */
14082 pConfig->num_accept_mac = 0;
14083 pConfig->num_deny_mac = 0;
14084
14085 /**
14086 * access control policy
14087 * @NL80211_ACL_POLICY_ACCEPT_UNLESS_LISTED: Deny stations which are
14088 * listed in hostapd.deny file.
14089 * @NL80211_ACL_POLICY_DENY_UNLESS_LISTED: Allow stations which are
14090 * listed in hostapd.accept file.
14091 */
14092 if (NL80211_ACL_POLICY_DENY_UNLESS_LISTED == params->acl_policy)
14093 {
14094 pConfig->SapMacaddr_acl = eSAP_DENY_UNLESS_ACCEPTED;
14095 }
14096 else if (NL80211_ACL_POLICY_ACCEPT_UNLESS_LISTED == params->acl_policy)
14097 {
14098 pConfig->SapMacaddr_acl = eSAP_ACCEPT_UNLESS_DENIED;
14099 }
14100 else
14101 {
14102 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
14103 "%s:Acl Policy : %d is not supported",
14104 __func__, params->acl_policy);
14105 return -ENOTSUPP;
14106 }
14107
14108 if (eSAP_DENY_UNLESS_ACCEPTED == pConfig->SapMacaddr_acl)
14109 {
14110 pConfig->num_accept_mac = params->n_acl_entries;
14111 for (i = 0; i < params->n_acl_entries; i++)
14112 {
14113 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
14114 "** Add ACL MAC entry %i in WhiletList :"
14115 MAC_ADDRESS_STR, i,
14116 MAC_ADDR_ARRAY(params->mac_addrs[i].addr));
14117
14118 vos_mem_copy(&pConfig->accept_mac[i], params->mac_addrs[i].addr,
14119 sizeof(qcmacaddr));
14120 }
14121 }
14122 else if (eSAP_ACCEPT_UNLESS_DENIED == pConfig->SapMacaddr_acl)
14123 {
14124 pConfig->num_deny_mac = params->n_acl_entries;
14125 for (i = 0; i < params->n_acl_entries; i++)
14126 {
14127 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
14128 "** Add ACL MAC entry %i in BlackList :"
14129 MAC_ADDRESS_STR, i,
14130 MAC_ADDR_ARRAY(params->mac_addrs[i].addr));
14131
14132 vos_mem_copy(&pConfig->deny_mac[i], params->mac_addrs[i].addr,
14133 sizeof(qcmacaddr));
14134 }
14135 }
14136
14137 if (VOS_STATUS_SUCCESS != WLANSAP_SetMacACL(pVosContext, pConfig))
14138 {
14139 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
14140 "%s: SAP Set Mac Acl fail", __func__);
14141 return -EINVAL;
14142 }
14143 }
14144 else
14145 {
14146 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Sushant Kaushik8bc7df22014-04-09 17:55:29 +053014147 "%s: Invalid device_mode = %s (%d)",
14148 __func__, hdd_device_modetoString(pAdapter->device_mode),
14149 pAdapter->device_mode);
Gopichand Nakkalac005b7c2013-05-14 16:04:14 +053014150 return -EINVAL;
14151 }
14152
14153 return 0;
14154}
14155
Leo Chang9056f462013-08-01 19:21:11 -070014156#ifdef WLAN_NL80211_TESTMODE
14157#ifdef FEATURE_WLAN_LPHB
Leo Changd9df8aa2013-09-26 13:32:26 -070014158void wlan_hdd_cfg80211_lphb_ind_handler
Leo Chang9056f462013-08-01 19:21:11 -070014159(
14160 void *pAdapter,
14161 void *indCont
14162)
14163{
Leo Changd9df8aa2013-09-26 13:32:26 -070014164 tSirLPHBInd *lphbInd;
14165 struct sk_buff *skb;
c_hpothu73f35e62014-04-18 13:40:08 +053014166 hdd_context_t *pHddCtxt;
Leo Chang9056f462013-08-01 19:21:11 -070014167
14168 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Leo Changd9df8aa2013-09-26 13:32:26 -070014169 "LPHB indication arrived");
Leo Chang9056f462013-08-01 19:21:11 -070014170
c_hpothu73f35e62014-04-18 13:40:08 +053014171 if (pAdapter == NULL)
14172 {
14173 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
14174 "%s: pAdapter is NULL\n",__func__);
14175 return;
14176 }
14177
Leo Chang9056f462013-08-01 19:21:11 -070014178 if (NULL == indCont)
14179 {
14180 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Leo Changd9df8aa2013-09-26 13:32:26 -070014181 "LPHB IND, invalid argument");
Leo Chang9056f462013-08-01 19:21:11 -070014182 return;
14183 }
14184
c_hpothu73f35e62014-04-18 13:40:08 +053014185 pHddCtxt = (hdd_context_t *)pAdapter;
Leo Changd9df8aa2013-09-26 13:32:26 -070014186 lphbInd = (tSirLPHBInd *)indCont;
Leo Chang9056f462013-08-01 19:21:11 -070014187 skb = cfg80211_testmode_alloc_event_skb(
c_hpothu73f35e62014-04-18 13:40:08 +053014188 pHddCtxt->wiphy,
Leo Changd9df8aa2013-09-26 13:32:26 -070014189 sizeof(tSirLPHBInd),
Leo Chang9056f462013-08-01 19:21:11 -070014190 GFP_ATOMIC);
14191 if (!skb)
14192 {
14193 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
14194 "LPHB timeout, NL buffer alloc fail");
14195 return;
14196 }
14197
Leo Changac3ba772013-10-07 09:47:04 -070014198 if(nla_put_u32(skb, WLAN_HDD_TM_ATTR_CMD, WLAN_HDD_TM_CMD_WLAN_HB))
Leo Changd9df8aa2013-09-26 13:32:26 -070014199 {
14200 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
14201 "WLAN_HDD_TM_ATTR_CMD put fail");
14202 goto nla_put_failure;
14203 }
Leo Changac3ba772013-10-07 09:47:04 -070014204 if(nla_put_u32(skb, WLAN_HDD_TM_ATTR_TYPE, lphbInd->protocolType))
Leo Changd9df8aa2013-09-26 13:32:26 -070014205 {
14206 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
14207 "WLAN_HDD_TM_ATTR_TYPE put fail");
14208 goto nla_put_failure;
14209 }
Leo Changac3ba772013-10-07 09:47:04 -070014210 if(nla_put(skb, WLAN_HDD_TM_ATTR_DATA,
Leo Changd9df8aa2013-09-26 13:32:26 -070014211 sizeof(tSirLPHBInd), lphbInd))
14212 {
14213 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
14214 "WLAN_HDD_TM_ATTR_DATA put fail");
14215 goto nla_put_failure;
14216 }
Leo Chang9056f462013-08-01 19:21:11 -070014217 cfg80211_testmode_event(skb, GFP_ATOMIC);
14218 return;
14219
14220nla_put_failure:
14221 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
14222 "NLA Put fail");
14223 kfree_skb(skb);
14224
14225 return;
14226}
14227#endif /* FEATURE_WLAN_LPHB */
14228
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053014229static int __wlan_hdd_cfg80211_testmode(struct wiphy *wiphy, void *data, int len)
Leo Chang9056f462013-08-01 19:21:11 -070014230{
14231 struct nlattr *tb[WLAN_HDD_TM_ATTR_MAX + 1];
14232 int err = 0;
14233#ifdef FEATURE_WLAN_LPHB
14234 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
Leo Changd9df8aa2013-09-26 13:32:26 -070014235 eHalStatus smeStatus;
Leo Chang9056f462013-08-01 19:21:11 -070014236#endif /* FEATURE_WLAN_LPHB */
14237
14238 err = nla_parse(tb, WLAN_HDD_TM_ATTR_MAX, data, len, wlan_hdd_tm_policy);
14239 if (err)
14240 {
14241 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
14242 "%s Testmode INV ATTR", __func__);
14243 return err;
14244 }
14245
14246 if (!tb[WLAN_HDD_TM_ATTR_CMD])
14247 {
14248 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
14249 "%s Testmode INV CMD", __func__);
14250 return -EINVAL;
14251 }
14252
14253 switch (nla_get_u32(tb[WLAN_HDD_TM_ATTR_CMD]))
14254 {
14255#ifdef FEATURE_WLAN_LPHB
14256 /* Low Power Heartbeat configuration request */
14257 case WLAN_HDD_TM_CMD_WLAN_HB:
14258 {
14259 int buf_len;
14260 void *buf;
14261 tSirLPHBReq *hb_params = NULL;
Amar Singhal05852702014-02-04 14:40:00 -080014262 tSirLPHBReq *hb_params_temp = NULL;
Leo Chang9056f462013-08-01 19:21:11 -070014263
14264 if (!tb[WLAN_HDD_TM_ATTR_DATA])
14265 {
14266 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
14267 "%s Testmode INV DATA", __func__);
14268 return -EINVAL;
14269 }
14270
14271 buf = nla_data(tb[WLAN_HDD_TM_ATTR_DATA]);
14272 buf_len = nla_len(tb[WLAN_HDD_TM_ATTR_DATA]);
Amar Singhal05852702014-02-04 14:40:00 -080014273
14274 hb_params_temp =(tSirLPHBReq *)buf;
14275 if ((hb_params_temp->cmd == LPHB_SET_TCP_PARAMS_INDID) &&
14276 (hb_params_temp->params.lphbTcpParamReq.timePeriodSec == 0))
14277 return -EINVAL;
14278
Leo Chang9056f462013-08-01 19:21:11 -070014279 hb_params = (tSirLPHBReq *)vos_mem_malloc(sizeof(tSirLPHBReq));
14280 if (NULL == hb_params)
14281 {
14282 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
14283 "%s Request Buffer Alloc Fail", __func__);
14284 return -EINVAL;
14285 }
14286
14287 vos_mem_copy(hb_params, buf, buf_len);
Leo Changd9df8aa2013-09-26 13:32:26 -070014288 smeStatus = sme_LPHBConfigReq((tHalHandle)(pHddCtx->hHal),
14289 hb_params,
14290 wlan_hdd_cfg80211_lphb_ind_handler);
14291 if (eHAL_STATUS_SUCCESS != smeStatus)
Leo Chang9056f462013-08-01 19:21:11 -070014292 {
Leo Changd9df8aa2013-09-26 13:32:26 -070014293 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
14294 "LPHB Config Fail, disable");
Leo Chang9056f462013-08-01 19:21:11 -070014295 vos_mem_free(hb_params);
14296 }
Leo Chang9056f462013-08-01 19:21:11 -070014297 return 0;
14298 }
14299#endif /* FEATURE_WLAN_LPHB */
14300 default:
c_hpothu6ff1c3c2013-10-01 19:01:57 +053014301 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
14302 "%s: unsupported event",__func__);
Leo Chang9056f462013-08-01 19:21:11 -070014303 return -EOPNOTSUPP;
14304 }
14305
14306 return err;
14307}
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053014308
14309static int wlan_hdd_cfg80211_testmode(struct wiphy *wiphy, void *data, int len)
14310{
14311 int ret;
14312
14313 vos_ssr_protect(__func__);
14314 ret = __wlan_hdd_cfg80211_testmode(wiphy, data, len);
14315 vos_ssr_unprotect(__func__);
14316
14317 return ret;
14318}
Leo Chang9056f462013-08-01 19:21:11 -070014319#endif /* CONFIG_NL80211_TESTMODE */
14320
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053014321static int __wlan_hdd_cfg80211_dump_survey(struct wiphy *wiphy,
Madan Mohan Koyyalamudid9383fd2013-08-13 09:27:30 +053014322 struct net_device *dev,
14323 int idx, struct survey_info *survey)
14324{
14325 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
14326 hdd_context_t *pHddCtx;
Mihir Sheted9072e02013-08-21 17:02:29 +053014327 hdd_station_ctx_t *pHddStaCtx;
Madan Mohan Koyyalamudid9383fd2013-08-13 09:27:30 +053014328 tHalHandle halHandle;
Mihir Sheted9072e02013-08-21 17:02:29 +053014329 v_U32_t channel = 0, freq = 0; /* Initialization Required */
Madan Mohan Koyyalamudid9383fd2013-08-13 09:27:30 +053014330 v_S7_t snr,rssi;
14331 int status, i, j, filled = 0;
14332
14333 ENTER();
14334
Madan Mohan Koyyalamudid9383fd2013-08-13 09:27:30 +053014335 if (NULL == pAdapter)
14336 {
14337 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
14338 "%s: HDD adapter is Null", __func__);
14339 return -ENODEV;
14340 }
14341
14342 if (NULL == wiphy)
14343 {
14344 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
14345 "%s: wiphy is Null", __func__);
14346 return -ENODEV;
14347 }
14348
14349 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
14350 status = wlan_hdd_validate_context(pHddCtx);
14351
14352 if (0 != status)
14353 {
14354 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
14355 "%s: HDD context is not valid", __func__);
14356 return status;
14357 }
14358
Mihir Sheted9072e02013-08-21 17:02:29 +053014359 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
14360
Madan Mohan Koyyalamudid9383fd2013-08-13 09:27:30 +053014361 if (0 == pHddCtx->cfg_ini->fEnableSNRMonitoring ||
Mihir Sheted9072e02013-08-21 17:02:29 +053014362 0 != pAdapter->survey_idx ||
14363 eConnectionState_Associated != pHddStaCtx->conn_info.connState)
Madan Mohan Koyyalamudid9383fd2013-08-13 09:27:30 +053014364 {
14365 /* The survey dump ops when implemented completely is expected to
14366 * return a survey of all channels and the ops is called by the
14367 * kernel with incremental values of the argument 'idx' till it
14368 * returns -ENONET. But we can only support the survey for the
14369 * operating channel for now. survey_idx is used to track
14370 * that the ops is called only once and then return -ENONET for
14371 * the next iteration
14372 */
14373 pAdapter->survey_idx = 0;
14374 return -ENONET;
14375 }
14376
14377 halHandle = WLAN_HDD_GET_HAL_CTX(pAdapter);
14378
14379 wlan_hdd_get_snr(pAdapter, &snr);
14380 wlan_hdd_get_rssi(pAdapter, &rssi);
14381
14382 sme_GetOperationChannel(halHandle, &channel, pAdapter->sessionId);
14383 hdd_wlan_get_freq(channel, &freq);
14384
14385
14386 for (i = 0; i < IEEE80211_NUM_BANDS; i++)
14387 {
14388 if (NULL == wiphy->bands[i])
14389 {
14390 VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_INFO,
14391 "%s: wiphy->bands[i] is NULL, i = %d", __func__, i);
14392 continue;
14393 }
14394
14395 for (j = 0; j < wiphy->bands[i]->n_channels; j++)
14396 {
14397 struct ieee80211_supported_band *band = wiphy->bands[i];
14398
14399 if (band->channels[j].center_freq == (v_U16_t)freq)
14400 {
14401 survey->channel = &band->channels[j];
14402 /* The Rx BDs contain SNR values in dB for the received frames
14403 * while the supplicant expects noise. So we calculate and
14404 * return the value of noise (dBm)
14405 * SNR (dB) = RSSI (dBm) - NOISE (dBm)
14406 */
14407 survey->noise = rssi - snr;
14408 survey->filled = SURVEY_INFO_NOISE_DBM;
14409 filled = 1;
14410 }
14411 }
14412 }
14413
14414 if (filled)
14415 pAdapter->survey_idx = 1;
14416 else
14417 {
14418 pAdapter->survey_idx = 0;
14419 return -ENONET;
14420 }
14421
14422 return 0;
14423}
14424
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053014425static int wlan_hdd_cfg80211_dump_survey(struct wiphy *wiphy,
14426 struct net_device *dev,
14427 int idx, struct survey_info *survey)
14428{
14429 int ret;
14430
14431 vos_ssr_protect(__func__);
14432 ret = __wlan_hdd_cfg80211_dump_survey(wiphy, dev, idx, survey);
14433 vos_ssr_unprotect(__func__);
14434
14435 return ret;
14436}
14437
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053014438/*
Mahesh A Saptasagarbcc5b662014-06-02 21:46:23 +053014439 * FUNCTION: __wlan_hdd_cfg80211_resume_wlan
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053014440 * this is called when cfg80211 driver resume
14441 * driver updates latest sched_scan scan result(if any) to cfg80211 database
14442 */
Mahesh A Saptasagarbcc5b662014-06-02 21:46:23 +053014443int __wlan_hdd_cfg80211_resume_wlan(struct wiphy *wiphy)
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053014444{
14445 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
14446 hdd_adapter_t *pAdapter;
14447 hdd_adapter_list_node_t *pAdapterNode, *pNext;
14448 VOS_STATUS status = VOS_STATUS_SUCCESS;
14449
14450 ENTER();
14451
14452 if ( NULL == pHddCtx )
14453 {
14454 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
14455 "%s: HddCtx validation failed", __func__);
14456 return 0;
14457 }
14458
14459 if (pHddCtx->isLogpInProgress)
14460 {
14461 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
14462 "%s: LOGP in Progress. Ignore!!!", __func__);
14463 return 0;
14464 }
14465
Mihir Shete18156292014-03-11 15:38:30 +053014466 if (WLAN_HDD_IS_LOAD_UNLOAD_IN_PROGRESS(pHddCtx))
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053014467 {
14468 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
14469 "%s: Unloading/Loading in Progress. Ignore!!!", __func__);
14470 return 0;
14471 }
14472
14473 spin_lock(&pHddCtx->schedScan_lock);
14474 pHddCtx->isWiphySuspended = FALSE;
14475 if (TRUE != pHddCtx->isSchedScanUpdatePending)
14476 {
14477 spin_unlock(&pHddCtx->schedScan_lock);
14478 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
14479 "%s: Return resume is not due to PNO indication", __func__);
14480 return 0;
14481 }
14482 // Reset flag to avoid updatating cfg80211 data old results again
14483 pHddCtx->isSchedScanUpdatePending = FALSE;
14484 spin_unlock(&pHddCtx->schedScan_lock);
14485
Mahesh A Saptasagarb9c50402014-01-16 15:49:22 +053014486
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053014487 status = hdd_get_front_adapter ( pHddCtx, &pAdapterNode );
14488
14489 while ( NULL != pAdapterNode && VOS_STATUS_SUCCESS == status )
14490 {
14491 pAdapter = pAdapterNode->pAdapter;
14492 if ( (NULL != pAdapter) &&
14493 (WLAN_HDD_INFRA_STATION == pAdapter->device_mode) )
14494 {
14495 if (0 != wlan_hdd_cfg80211_update_bss(pHddCtx->wiphy, pAdapter))
Mahesh A Saptasagarb9c50402014-01-16 15:49:22 +053014496 {
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053014497 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_WARN,
14498 "%s: NO SCAN result", __func__);
Mahesh A Saptasagarb9c50402014-01-16 15:49:22 +053014499 }
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053014500 else
Mahesh A Saptasagarb9c50402014-01-16 15:49:22 +053014501 {
14502 /* Acquire wakelock to handle the case where APP's tries to
14503 * suspend immediately after updating the scan results. Whis
14504 * results in app's is in suspended state and not able to
14505 * process the connect request to AP
14506 */
14507 hdd_prevent_suspend_timeout(2000);
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053014508 cfg80211_sched_scan_results(pHddCtx->wiphy);
Mahesh A Saptasagarb9c50402014-01-16 15:49:22 +053014509 }
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053014510
14511 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
14512 "%s : cfg80211 scan result database updated", __func__);
14513
14514 return 0;
14515
14516 }
14517 status = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
14518 pAdapterNode = pNext;
14519 }
14520
14521 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
14522 "%s: Failed to find Adapter", __func__);
14523 return 0;
14524}
14525
Mahesh A Saptasagarbcc5b662014-06-02 21:46:23 +053014526int wlan_hdd_cfg80211_resume_wlan(struct wiphy *wiphy)
14527{
14528 int ret;
14529
14530 vos_ssr_protect(__func__);
14531 ret = __wlan_hdd_cfg80211_resume_wlan(wiphy);
14532 vos_ssr_unprotect(__func__);
14533
14534 return ret;
14535}
14536
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053014537/*
Mahesh A Saptasagarbcc5b662014-06-02 21:46:23 +053014538 * FUNCTION: __wlan_hdd_cfg80211_suspend_wlan
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053014539 * this is called when cfg80211 driver suspends
14540 */
Mahesh A Saptasagarbcc5b662014-06-02 21:46:23 +053014541int __wlan_hdd_cfg80211_suspend_wlan(struct wiphy *wiphy,
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053014542 struct cfg80211_wowlan *wow)
14543{
14544 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
14545
14546 ENTER();
14547 if (NULL == pHddCtx)
14548 {
14549 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
14550 "%s: HddCtx validation failed", __func__);
14551 return 0;
14552 }
14553
14554 pHddCtx->isWiphySuspended = TRUE;
14555
14556 EXIT();
14557
14558 return 0;
14559}
14560
Mahesh A Saptasagarbcc5b662014-06-02 21:46:23 +053014561int wlan_hdd_cfg80211_suspend_wlan(struct wiphy *wiphy,
14562 struct cfg80211_wowlan *wow)
14563{
14564 int ret;
14565
14566 vos_ssr_protect(__func__);
14567 ret = __wlan_hdd_cfg80211_suspend_wlan(wiphy, wow);
14568 vos_ssr_unprotect(__func__);
14569
14570 return ret;
14571}
Jeff Johnson295189b2012-06-20 16:38:30 -070014572/* cfg80211_ops */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014573static struct cfg80211_ops wlan_hdd_cfg80211_ops =
Jeff Johnson295189b2012-06-20 16:38:30 -070014574{
14575 .add_virtual_intf = wlan_hdd_add_virtual_intf,
14576 .del_virtual_intf = wlan_hdd_del_virtual_intf,
14577 .change_virtual_intf = wlan_hdd_cfg80211_change_iface,
14578 .change_station = wlan_hdd_change_station,
14579#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,4,0))
14580 .add_beacon = wlan_hdd_cfg80211_add_beacon,
14581 .del_beacon = wlan_hdd_cfg80211_del_beacon,
14582 .set_beacon = wlan_hdd_cfg80211_set_beacon,
Jeff Johnson04dd8a82012-06-29 20:41:40 -070014583#else
14584 .start_ap = wlan_hdd_cfg80211_start_ap,
14585 .change_beacon = wlan_hdd_cfg80211_change_beacon,
14586 .stop_ap = wlan_hdd_cfg80211_stop_ap,
Jeff Johnson295189b2012-06-20 16:38:30 -070014587#endif
14588 .change_bss = wlan_hdd_cfg80211_change_bss,
14589 .add_key = wlan_hdd_cfg80211_add_key,
14590 .get_key = wlan_hdd_cfg80211_get_key,
14591 .del_key = wlan_hdd_cfg80211_del_key,
14592 .set_default_key = wlan_hdd_cfg80211_set_default_key,
Jeff Johnson3bbe4bf2013-01-18 17:05:29 -080014593#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,6,0))
Jeff Johnson295189b2012-06-20 16:38:30 -070014594 .set_channel = wlan_hdd_cfg80211_set_channel,
Jeff Johnson3bbe4bf2013-01-18 17:05:29 -080014595#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070014596 .scan = wlan_hdd_cfg80211_scan,
14597 .connect = wlan_hdd_cfg80211_connect,
14598 .disconnect = wlan_hdd_cfg80211_disconnect,
14599 .join_ibss = wlan_hdd_cfg80211_join_ibss,
14600 .leave_ibss = wlan_hdd_cfg80211_leave_ibss,
14601 .set_wiphy_params = wlan_hdd_cfg80211_set_wiphy_params,
14602 .set_tx_power = wlan_hdd_cfg80211_set_txpower,
14603 .get_tx_power = wlan_hdd_cfg80211_get_txpower,
Jeff Johnson295189b2012-06-20 16:38:30 -070014604 .remain_on_channel = wlan_hdd_cfg80211_remain_on_channel,
14605 .cancel_remain_on_channel = wlan_hdd_cfg80211_cancel_remain_on_channel,
DARAM SUDHA39eede62014-02-12 11:16:40 +053014606 .mgmt_tx = wlan_hdd_mgmt_tx,
Jeff Johnson295189b2012-06-20 16:38:30 -070014607#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
14608 .mgmt_tx_cancel_wait = wlan_hdd_cfg80211_mgmt_tx_cancel_wait,
14609 .set_default_mgmt_key = wlan_hdd_set_default_mgmt_key,
14610 .set_txq_params = wlan_hdd_set_txq_params,
14611#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070014612 .get_station = wlan_hdd_cfg80211_get_station,
14613 .set_power_mgmt = wlan_hdd_cfg80211_set_power_mgmt,
14614 .del_station = wlan_hdd_cfg80211_del_station,
Jeff Johnson04dd8a82012-06-29 20:41:40 -070014615 .add_station = wlan_hdd_cfg80211_add_station,
14616#ifdef FEATURE_WLAN_LFR
14617 .set_pmksa = wlan_hdd_cfg80211_set_pmksa,
14618 .del_pmksa = wlan_hdd_cfg80211_del_pmksa,
14619 .flush_pmksa = wlan_hdd_cfg80211_flush_pmksa,
14620#endif
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070014621#if defined(WLAN_FEATURE_VOWIFI_11R) && defined(KERNEL_SUPPORT_11R_CFG80211)
14622 .update_ft_ies = wlan_hdd_cfg80211_update_ft_ies,
14623#endif
Mohit Khanna698ba2a2012-12-04 15:08:18 -080014624#ifdef FEATURE_WLAN_TDLS
14625 .tdls_mgmt = wlan_hdd_cfg80211_tdls_mgmt,
14626 .tdls_oper = wlan_hdd_cfg80211_tdls_oper,
14627#endif
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053014628#ifdef WLAN_FEATURE_GTK_OFFLOAD
14629 .set_rekey_data = wlan_hdd_cfg80211_set_rekey_data,
14630#endif /* WLAN_FEATURE_GTK_OFFLOAD */
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053014631#ifdef FEATURE_WLAN_SCAN_PNO
14632 .sched_scan_start = wlan_hdd_cfg80211_sched_scan_start,
14633 .sched_scan_stop = wlan_hdd_cfg80211_sched_scan_stop,
14634#endif /*FEATURE_WLAN_SCAN_PNO */
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053014635 .resume = wlan_hdd_cfg80211_resume_wlan,
14636 .suspend = wlan_hdd_cfg80211_suspend_wlan,
Gopichand Nakkalac005b7c2013-05-14 16:04:14 +053014637 .set_mac_acl = wlan_hdd_cfg80211_set_mac_acl,
Leo Chang9056f462013-08-01 19:21:11 -070014638#ifdef WLAN_NL80211_TESTMODE
14639 .testmode_cmd = wlan_hdd_cfg80211_testmode,
14640#endif
Madan Mohan Koyyalamudid9383fd2013-08-13 09:27:30 +053014641 .dump_survey = wlan_hdd_cfg80211_dump_survey,
Jeff Johnson295189b2012-06-20 16:38:30 -070014642};
14643