blob: 6dc3b26aa84c003ef86be2c44636cbeda6f8083a [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
Gopichand Nakkala747461f2013-04-24 19:24:45 +0530169static const u32 hdd_cipher_suites[] =
Jeff Johnson295189b2012-06-20 16:38:30 -0700170{
171 WLAN_CIPHER_SUITE_WEP40,
172 WLAN_CIPHER_SUITE_WEP104,
173 WLAN_CIPHER_SUITE_TKIP,
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -0800174#ifdef FEATURE_WLAN_ESE
Jeff Johnson295189b2012-06-20 16:38:30 -0700175#define WLAN_CIPHER_SUITE_KRK 0x004096ff /* use for KRK */
176 WLAN_CIPHER_SUITE_KRK,
177 WLAN_CIPHER_SUITE_CCMP,
178#else
179 WLAN_CIPHER_SUITE_CCMP,
180#endif
181#ifdef FEATURE_WLAN_WAPI
182 WLAN_CIPHER_SUITE_SMS4,
183#endif
Chet Lanctot186b5732013-03-18 10:26:30 -0700184#ifdef WLAN_FEATURE_11W
185 WLAN_CIPHER_SUITE_AES_CMAC,
186#endif
Jeff Johnson295189b2012-06-20 16:38:30 -0700187};
188
189static inline int is_broadcast_ether_addr(const u8 *addr)
190{
191 return ((addr[0] == 0xff) && (addr[1] == 0xff) && (addr[2] == 0xff) &&
192 (addr[3] == 0xff) && (addr[4] == 0xff) && (addr[5] == 0xff));
193}
194
195static struct ieee80211_channel hdd_channels_2_4_GHZ[] =
Gopichand Nakkala747461f2013-04-24 19:24:45 +0530196{
Jeff Johnson295189b2012-06-20 16:38:30 -0700197 HDD2GHZCHAN(2412, 1, 0) ,
198 HDD2GHZCHAN(2417, 2, 0) ,
199 HDD2GHZCHAN(2422, 3, 0) ,
200 HDD2GHZCHAN(2427, 4, 0) ,
201 HDD2GHZCHAN(2432, 5, 0) ,
202 HDD2GHZCHAN(2437, 6, 0) ,
203 HDD2GHZCHAN(2442, 7, 0) ,
204 HDD2GHZCHAN(2447, 8, 0) ,
205 HDD2GHZCHAN(2452, 9, 0) ,
206 HDD2GHZCHAN(2457, 10, 0) ,
207 HDD2GHZCHAN(2462, 11, 0) ,
208 HDD2GHZCHAN(2467, 12, 0) ,
209 HDD2GHZCHAN(2472, 13, 0) ,
210 HDD2GHZCHAN(2484, 14, 0) ,
211};
212
Jeff Johnson295189b2012-06-20 16:38:30 -0700213static struct ieee80211_channel hdd_social_channels_2_4_GHZ[] =
214{
215 HDD2GHZCHAN(2412, 1, 0) ,
216 HDD2GHZCHAN(2437, 6, 0) ,
217 HDD2GHZCHAN(2462, 11, 0) ,
218};
Jeff Johnson295189b2012-06-20 16:38:30 -0700219
220static struct ieee80211_channel hdd_channels_5_GHZ[] =
221{
Madan Mohan Koyyalamudic3a240c2012-09-28 15:34:08 -0700222 HDD5GHZCHAN(4920, 240, 0) ,
223 HDD5GHZCHAN(4940, 244, 0) ,
224 HDD5GHZCHAN(4960, 248, 0) ,
225 HDD5GHZCHAN(4980, 252, 0) ,
226 HDD5GHZCHAN(5040, 208, 0) ,
227 HDD5GHZCHAN(5060, 212, 0) ,
228 HDD5GHZCHAN(5080, 216, 0) ,
Jeff Johnson295189b2012-06-20 16:38:30 -0700229 HDD5GHZCHAN(5180, 36, 0) ,
230 HDD5GHZCHAN(5200, 40, 0) ,
231 HDD5GHZCHAN(5220, 44, 0) ,
232 HDD5GHZCHAN(5240, 48, 0) ,
233 HDD5GHZCHAN(5260, 52, 0) ,
234 HDD5GHZCHAN(5280, 56, 0) ,
235 HDD5GHZCHAN(5300, 60, 0) ,
236 HDD5GHZCHAN(5320, 64, 0) ,
237 HDD5GHZCHAN(5500,100, 0) ,
238 HDD5GHZCHAN(5520,104, 0) ,
239 HDD5GHZCHAN(5540,108, 0) ,
240 HDD5GHZCHAN(5560,112, 0) ,
241 HDD5GHZCHAN(5580,116, 0) ,
242 HDD5GHZCHAN(5600,120, 0) ,
243 HDD5GHZCHAN(5620,124, 0) ,
244 HDD5GHZCHAN(5640,128, 0) ,
245 HDD5GHZCHAN(5660,132, 0) ,
246 HDD5GHZCHAN(5680,136, 0) ,
247 HDD5GHZCHAN(5700,140, 0) ,
Leo Chang80de3c22013-11-26 10:52:12 -0800248#ifdef FEATURE_WLAN_CH144
249 HDD5GHZCHAN(5720,144, 0) ,
250#endif /* FEATURE_WLAN_CH144 */
Jeff Johnson295189b2012-06-20 16:38:30 -0700251 HDD5GHZCHAN(5745,149, 0) ,
252 HDD5GHZCHAN(5765,153, 0) ,
253 HDD5GHZCHAN(5785,157, 0) ,
254 HDD5GHZCHAN(5805,161, 0) ,
255 HDD5GHZCHAN(5825,165, 0) ,
256};
257
258static struct ieee80211_rate g_mode_rates[] =
259{
Gopichand Nakkala747461f2013-04-24 19:24:45 +0530260 HDD_G_MODE_RATETAB(10, 0x1, 0),
261 HDD_G_MODE_RATETAB(20, 0x2, 0),
262 HDD_G_MODE_RATETAB(55, 0x4, 0),
263 HDD_G_MODE_RATETAB(110, 0x8, 0),
264 HDD_G_MODE_RATETAB(60, 0x10, 0),
265 HDD_G_MODE_RATETAB(90, 0x20, 0),
266 HDD_G_MODE_RATETAB(120, 0x40, 0),
267 HDD_G_MODE_RATETAB(180, 0x80, 0),
268 HDD_G_MODE_RATETAB(240, 0x100, 0),
269 HDD_G_MODE_RATETAB(360, 0x200, 0),
270 HDD_G_MODE_RATETAB(480, 0x400, 0),
Jeff Johnson295189b2012-06-20 16:38:30 -0700271 HDD_G_MODE_RATETAB(540, 0x800, 0),
Gopichand Nakkala747461f2013-04-24 19:24:45 +0530272};
Jeff Johnson295189b2012-06-20 16:38:30 -0700273
274static struct ieee80211_rate a_mode_rates[] =
275{
Gopichand Nakkala747461f2013-04-24 19:24:45 +0530276 HDD_G_MODE_RATETAB(60, 0x10, 0),
277 HDD_G_MODE_RATETAB(90, 0x20, 0),
278 HDD_G_MODE_RATETAB(120, 0x40, 0),
279 HDD_G_MODE_RATETAB(180, 0x80, 0),
280 HDD_G_MODE_RATETAB(240, 0x100, 0),
281 HDD_G_MODE_RATETAB(360, 0x200, 0),
282 HDD_G_MODE_RATETAB(480, 0x400, 0),
Jeff Johnson295189b2012-06-20 16:38:30 -0700283 HDD_G_MODE_RATETAB(540, 0x800, 0),
284};
285
286static struct ieee80211_supported_band wlan_hdd_band_2_4_GHZ =
287{
288 .channels = hdd_channels_2_4_GHZ,
289 .n_channels = ARRAY_SIZE(hdd_channels_2_4_GHZ),
290 .band = IEEE80211_BAND_2GHZ,
291 .bitrates = g_mode_rates,
292 .n_bitrates = g_mode_rates_size,
293 .ht_cap.ht_supported = 1,
294 .ht_cap.cap = IEEE80211_HT_CAP_SGI_20
295 | IEEE80211_HT_CAP_GRN_FLD
296 | IEEE80211_HT_CAP_DSSSCCK40
297 | IEEE80211_HT_CAP_LSIG_TXOP_PROT,
298 .ht_cap.ampdu_factor = IEEE80211_HT_MAX_AMPDU_64K,
299 .ht_cap.ampdu_density = IEEE80211_HT_MPDU_DENSITY_16,
300 .ht_cap.mcs.rx_mask = { 0xff, 0, 0, 0, 0, 0, 0, 0, 0, 0, },
301 .ht_cap.mcs.rx_highest = cpu_to_le16( 72 ),
302 .ht_cap.mcs.tx_params = IEEE80211_HT_MCS_TX_DEFINED,
303};
304
Jeff Johnson295189b2012-06-20 16:38:30 -0700305static struct ieee80211_supported_band wlan_hdd_band_p2p_2_4_GHZ =
306{
307 .channels = hdd_social_channels_2_4_GHZ,
308 .n_channels = ARRAY_SIZE(hdd_social_channels_2_4_GHZ),
309 .band = IEEE80211_BAND_2GHZ,
310 .bitrates = g_mode_rates,
311 .n_bitrates = g_mode_rates_size,
312 .ht_cap.ht_supported = 1,
313 .ht_cap.cap = IEEE80211_HT_CAP_SGI_20
314 | IEEE80211_HT_CAP_GRN_FLD
315 | IEEE80211_HT_CAP_DSSSCCK40
316 | IEEE80211_HT_CAP_LSIG_TXOP_PROT,
317 .ht_cap.ampdu_factor = IEEE80211_HT_MAX_AMPDU_64K,
318 .ht_cap.ampdu_density = IEEE80211_HT_MPDU_DENSITY_16,
319 .ht_cap.mcs.rx_mask = { 0xff, 0, 0, 0, 0, 0, 0, 0, 0, 0, },
320 .ht_cap.mcs.rx_highest = cpu_to_le16( 72 ),
321 .ht_cap.mcs.tx_params = IEEE80211_HT_MCS_TX_DEFINED,
322};
Jeff Johnson295189b2012-06-20 16:38:30 -0700323
324static struct ieee80211_supported_band wlan_hdd_band_5_GHZ =
325{
326 .channels = hdd_channels_5_GHZ,
327 .n_channels = ARRAY_SIZE(hdd_channels_5_GHZ),
328 .band = IEEE80211_BAND_5GHZ,
329 .bitrates = a_mode_rates,
330 .n_bitrates = a_mode_rates_size,
331 .ht_cap.ht_supported = 1,
332 .ht_cap.cap = IEEE80211_HT_CAP_SGI_20
333 | IEEE80211_HT_CAP_GRN_FLD
334 | IEEE80211_HT_CAP_DSSSCCK40
335 | IEEE80211_HT_CAP_LSIG_TXOP_PROT
336 | IEEE80211_HT_CAP_SGI_40
337 | IEEE80211_HT_CAP_SUP_WIDTH_20_40,
338 .ht_cap.ampdu_factor = IEEE80211_HT_MAX_AMPDU_64K,
339 .ht_cap.ampdu_density = IEEE80211_HT_MPDU_DENSITY_16,
340 .ht_cap.mcs.rx_mask = { 0xff, 0, 0, 0, 0, 0, 0, 0, 0, 0, },
341 .ht_cap.mcs.rx_highest = cpu_to_le16( 72 ),
342 .ht_cap.mcs.tx_params = IEEE80211_HT_MCS_TX_DEFINED,
343};
344
Gopichand Nakkala747461f2013-04-24 19:24:45 +0530345/* This structure contain information what kind of frame are expected in
Jeff Johnson295189b2012-06-20 16:38:30 -0700346 TX/RX direction for each kind of interface */
347static const struct ieee80211_txrx_stypes
348wlan_hdd_txrx_stypes[NUM_NL80211_IFTYPES] = {
349 [NL80211_IFTYPE_STATION] = {
350 .tx = 0xffff,
351 .rx = BIT(SIR_MAC_MGMT_ACTION) |
352 BIT(SIR_MAC_MGMT_PROBE_REQ),
353 },
354 [NL80211_IFTYPE_AP] = {
355 .tx = 0xffff,
356 .rx = BIT(SIR_MAC_MGMT_ASSOC_REQ) |
357 BIT(SIR_MAC_MGMT_REASSOC_REQ) |
358 BIT(SIR_MAC_MGMT_PROBE_REQ) |
359 BIT(SIR_MAC_MGMT_DISASSOC) |
360 BIT(SIR_MAC_MGMT_AUTH) |
361 BIT(SIR_MAC_MGMT_DEAUTH) |
362 BIT(SIR_MAC_MGMT_ACTION),
363 },
Jeff Johnsonbc006202013-04-29 14:05:30 -0700364 [NL80211_IFTYPE_ADHOC] = {
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 Johnson295189b2012-06-20 16:38:30 -0700374 [NL80211_IFTYPE_P2P_CLIENT] = {
375 .tx = 0xffff,
376 .rx = BIT(SIR_MAC_MGMT_ACTION) |
377 BIT(SIR_MAC_MGMT_PROBE_REQ),
378 },
379 [NL80211_IFTYPE_P2P_GO] = {
380 /* This is also same as for SoftAP */
381 .tx = 0xffff,
382 .rx = BIT(SIR_MAC_MGMT_ASSOC_REQ) |
383 BIT(SIR_MAC_MGMT_REASSOC_REQ) |
384 BIT(SIR_MAC_MGMT_PROBE_REQ) |
385 BIT(SIR_MAC_MGMT_DISASSOC) |
386 BIT(SIR_MAC_MGMT_AUTH) |
387 BIT(SIR_MAC_MGMT_DEAUTH) |
388 BIT(SIR_MAC_MGMT_ACTION),
389 },
Jeff Johnson295189b2012-06-20 16:38:30 -0700390};
391
Sudhir Sattayappa Kohalli278eee52013-01-16 17:35:13 -0800392#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,4,0))
Sudhir Sattayappa Kohalli278eee52013-01-16 17:35:13 -0800393static const struct ieee80211_iface_limit
394wlan_hdd_iface_limit[] = {
395 {
Sunil Ravia72c3992013-01-31 06:12:22 -0800396 /* max = 3 ; Our driver create two interfaces during driver init
397 * wlan0 and p2p0 interfaces. p2p0 is considered as station
398 * interface until a group is formed. In JB architecture, once the
399 * group is formed, interface type of p2p0 is changed to P2P GO or
400 * Client.
401 * When supplicant remove the group, it first issue a set interface
402 * cmd to change the mode back to Station. In JB this works fine as
403 * we advertize two station type interface during driver init.
404 * Some vendors create separate interface for P2P GO/Client,
405 * after group formation(Third one). But while group remove
406 * supplicant first tries to change the mode(3rd interface) to STATION
407 * But as we advertized only two sta type interfaces nl80211 was
408 * returning error for the third one which was leading to failure in
409 * delete interface. Ideally while removing the group, supplicant
410 * should not try to change the 3rd interface mode to Station type.
411 * Till we get a fix in wpa_supplicant, we advertize max STA
412 * interface type to 3
413 */
414 .max = 3,
Sudhir Sattayappa Kohalli278eee52013-01-16 17:35:13 -0800415 .types = BIT(NL80211_IFTYPE_STATION),
416 },
417 {
418 .max = 1,
Jeff Johnsonbc006202013-04-29 14:05:30 -0700419 .types = BIT(NL80211_IFTYPE_ADHOC) | BIT(NL80211_IFTYPE_AP),
Sudhir Sattayappa Kohalli278eee52013-01-16 17:35:13 -0800420 },
421 {
422 .max = 1,
423 .types = BIT(NL80211_IFTYPE_P2P_GO) |
424 BIT(NL80211_IFTYPE_P2P_CLIENT),
425 },
426};
427
428/* By default, only single channel concurrency is allowed */
429static struct ieee80211_iface_combination
430wlan_hdd_iface_combination = {
431 .limits = wlan_hdd_iface_limit,
432 .num_different_channels = 1,
Sunil Ravia72c3992013-01-31 06:12:22 -0800433 /*
434 * max = WLAN_MAX_INTERFACES ; JellyBean architecture creates wlan0
435 * and p2p0 interfaces during driver init
436 * Some vendors create separate interface for P2P operations.
437 * wlan0: STA interface
438 * p2p0: P2P Device interface, action frames goes
439 * through this interface.
440 * p2p-xx: P2P interface, After GO negotiation this interface is
441 * created for p2p operations(GO/CLIENT interface).
442 */
443 .max_interfaces = WLAN_MAX_INTERFACES,
Sudhir Sattayappa Kohalli278eee52013-01-16 17:35:13 -0800444 .n_limits = ARRAY_SIZE(wlan_hdd_iface_limit),
445 .beacon_int_infra_match = false,
446};
447#endif
Sudhir Sattayappa Kohalli278eee52013-01-16 17:35:13 -0800448
Jeff Johnson295189b2012-06-20 16:38:30 -0700449static struct cfg80211_ops wlan_hdd_cfg80211_ops;
450
451/* Data rate 100KBPS based on IE Index */
452struct index_data_rate_type
453{
454 v_U8_t beacon_rate_index;
455 v_U16_t supported_rate[4];
456};
457
458/* 11B, 11G Rate table include Basic rate and Extended rate
459 The IDX field is the rate index
460 The HI field is the rate when RSSI is strong or being ignored
461 (in this case we report actual rate)
462 The MID field is the rate when RSSI is moderate
463 (in this case we cap 11b rates at 5.5 and 11g rates at 24)
464 The LO field is the rate when RSSI is low
465 (in this case we don't report rates, actual current rate used)
466 */
467static const struct
468{
469 v_U8_t beacon_rate_index;
Madan Mohan Koyyalamudi8df78d52012-11-02 12:30:06 -0700470 v_U16_t supported_rate[4];
Jeff Johnson295189b2012-06-20 16:38:30 -0700471} supported_data_rate[] =
472{
Madan Mohan Koyyalamudi8df78d52012-11-02 12:30:06 -0700473/* IDX HI HM LM LO (RSSI-based index */
474 {2, { 10, 10, 10, 0}},
475 {4, { 20, 20, 10, 0}},
476 {11, { 55, 20, 10, 0}},
477 {12, { 60, 55, 20, 0}},
478 {18, { 90, 55, 20, 0}},
479 {22, {110, 55, 20, 0}},
480 {24, {120, 90, 60, 0}},
481 {36, {180, 120, 60, 0}},
482 {44, {220, 180, 60, 0}},
483 {48, {240, 180, 90, 0}},
484 {66, {330, 180, 90, 0}},
485 {72, {360, 240, 90, 0}},
486 {96, {480, 240, 120, 0}},
487 {108, {540, 240, 120, 0}}
Jeff Johnson295189b2012-06-20 16:38:30 -0700488};
489
490/* MCS Based rate table */
491static struct index_data_rate_type supported_mcs_rate[] =
492{
493/* MCS L20 L40 S20 S40 */
494 {0, {65, 135, 72, 150}},
495 {1, {130, 270, 144, 300}},
496 {2, {195, 405, 217, 450}},
497 {3, {260, 540, 289, 600}},
498 {4, {390, 810, 433, 900}},
499 {5, {520, 1080, 578, 1200}},
500 {6, {585, 1215, 650, 1350}},
501 {7, {650, 1350, 722, 1500}}
502};
503
Leo Chang6f8870f2013-03-26 18:11:36 -0700504#ifdef WLAN_FEATURE_11AC
505
Gopichand Nakkala4c705372013-04-24 13:20:33 +0530506#define DATA_RATE_11AC_MCS_MASK 0x03
Leo Chang6f8870f2013-03-26 18:11:36 -0700507
508struct index_vht_data_rate_type
509{
510 v_U8_t beacon_rate_index;
Gopichand Nakkala4c705372013-04-24 13:20:33 +0530511 v_U16_t supported_VHT80_rate[2];
512 v_U16_t supported_VHT40_rate[2];
513 v_U16_t supported_VHT20_rate[2];
Leo Chang6f8870f2013-03-26 18:11:36 -0700514};
515
516typedef enum
517{
518 DATA_RATE_11AC_MAX_MCS_7,
519 DATA_RATE_11AC_MAX_MCS_8,
520 DATA_RATE_11AC_MAX_MCS_9,
521 DATA_RATE_11AC_MAX_MCS_NA
522} eDataRate11ACMaxMcs;
523
Mahesh A Saptasagar7bd6ad42014-07-21 18:56:33 +0530524/* SSID broadcast type */
525typedef enum eSSIDBcastType
526{
527 eBCAST_UNKNOWN = 0,
528 eBCAST_NORMAL = 1,
529 eBCAST_HIDDEN = 2,
530} tSSIDBcastType;
531
Leo Chang6f8870f2013-03-26 18:11:36 -0700532/* MCS Based VHT rate table */
533static struct index_vht_data_rate_type supported_vht_mcs_rate[] =
534{
Gopichand Nakkala4c705372013-04-24 13:20:33 +0530535/* MCS L80 S80 L40 S40 L20 S40*/
536 {0, {293, 325}, {135, 150}, {65, 72}},
537 {1, {585, 650}, {270, 300}, {130, 144}},
538 {2, {878, 975}, {405, 450}, {195, 217}},
539 {3, {1170, 1300}, {540, 600}, {260, 289}},
540 {4, {1755, 1950}, {810, 900}, {390, 433}},
541 {5, {2340, 2600}, {1080, 1200}, {520, 578}},
542 {6, {2633, 2925}, {1215, 1350}, {585, 650}},
543 {7, {2925, 3250}, {1350, 1500}, {650, 722}},
544 {8, {3510, 3900}, {1620, 1800}, {780, 867}},
545 {9, {3900, 4333}, {1800, 2000}, {780, 867}}
Leo Chang6f8870f2013-03-26 18:11:36 -0700546};
547#endif /* WLAN_FEATURE_11AC */
548
c_hpothu79aab322014-07-14 21:11:01 +0530549/*array index points to MCS and array value points respective rssi*/
550static int rssiMcsTbl[][10] =
551{
552/*MCS 0 1 2 3 4 5 6 7 8 9*/
553 {-82, -79, -77, -74, -70, -66, -65, -64, -59, -57}, //20
554 {-79, -76, -74, -71, -67, -63, -62, -61, -56, -54}, //40
555 {-76, -73, -71, -68, -64, -60, -59, -58, -53, -51} //80
556};
557
Jeff Johnson295189b2012-06-20 16:38:30 -0700558extern struct net_device_ops net_ops_struct;
559
Leo Chang9056f462013-08-01 19:21:11 -0700560#ifdef WLAN_NL80211_TESTMODE
561enum wlan_hdd_tm_attr
562{
563 WLAN_HDD_TM_ATTR_INVALID = 0,
564 WLAN_HDD_TM_ATTR_CMD = 1,
565 WLAN_HDD_TM_ATTR_DATA = 2,
566 WLAN_HDD_TM_ATTR_TYPE = 3,
567 /* keep last */
568 WLAN_HDD_TM_ATTR_AFTER_LAST,
569 WLAN_HDD_TM_ATTR_MAX = WLAN_HDD_TM_ATTR_AFTER_LAST - 1,
570};
571
572enum wlan_hdd_tm_cmd
573{
574 WLAN_HDD_TM_CMD_WLAN_HB = 1,
575};
576
577#define WLAN_HDD_TM_DATA_MAX_LEN 5000
578
579static const struct nla_policy wlan_hdd_tm_policy[WLAN_HDD_TM_ATTR_MAX + 1] =
580{
581 [WLAN_HDD_TM_ATTR_CMD] = { .type = NLA_U32 },
582 [WLAN_HDD_TM_ATTR_DATA] = { .type = NLA_BINARY,
583 .len = WLAN_HDD_TM_DATA_MAX_LEN },
584};
585#endif /* WLAN_NL80211_TESTMODE */
586
Rajesh Chauhan98a31f82014-01-06 20:15:25 -0800587#ifdef FEATURE_WLAN_CH_AVOID
588/*
589 * FUNCTION: wlan_hdd_send_avoid_freq_event
590 * This is called when wlan driver needs to send vendor specific
591 * avoid frequency range event to userspace
592 */
593int wlan_hdd_send_avoid_freq_event(hdd_context_t *pHddCtx,
594 tHddAvoidFreqList *pAvoidFreqList)
595{
596 struct sk_buff *vendor_event;
597
598 ENTER();
599
600 if (!pHddCtx)
601 {
602 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
603 "%s: HDD context is null", __func__);
604 return -1;
605 }
606
607 if (!pAvoidFreqList)
608 {
609 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
610 "%s: pAvoidFreqList is null", __func__);
611 return -1;
612 }
613
614 vendor_event = cfg80211_vendor_event_alloc(pHddCtx->wiphy,
615 sizeof(tHddAvoidFreqList),
Sunil Duttc69bccb2014-05-26 21:30:20 +0530616 QCA_NL80211_VENDOR_SUBCMD_AVOID_FREQUENCY_INDEX,
Rajesh Chauhan98a31f82014-01-06 20:15:25 -0800617 GFP_KERNEL);
618 if (!vendor_event)
619 {
620 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
621 "%s: cfg80211_vendor_event_alloc failed", __func__);
622 return -1;
623 }
624
625 memcpy(skb_put(vendor_event, sizeof(tHddAvoidFreqList)),
626 (void *)pAvoidFreqList, sizeof(tHddAvoidFreqList));
627
628 cfg80211_vendor_event(vendor_event, GFP_KERNEL);
629
630 EXIT();
631 return 0;
632}
633#endif /* FEATURE_WLAN_CH_AVOID */
634
Sunil Duttc69bccb2014-05-26 21:30:20 +0530635#ifdef WLAN_FEATURE_LINK_LAYER_STATS
636
637static v_BOOL_t put_wifi_rate_stat( tpSirWifiRateStat stats,
638 struct sk_buff *vendor_event)
639{
640 if (nla_put_u8(vendor_event,
641 QCA_WLAN_VENDOR_ATTR_LL_STATS_RATE_PREAMBLE,
642 stats->rate.preamble) ||
643 nla_put_u8(vendor_event,
644 QCA_WLAN_VENDOR_ATTR_LL_STATS_RATE_NSS,
645 stats->rate.nss) ||
646 nla_put_u8(vendor_event,
647 QCA_WLAN_VENDOR_ATTR_LL_STATS_RATE_BW,
648 stats->rate.bw) ||
649 nla_put_u8(vendor_event,
650 QCA_WLAN_VENDOR_ATTR_LL_STATS_RATE_MCS_INDEX,
651 stats->rate.rateMcsIdx) ||
652 nla_put_u32(vendor_event, QCA_WLAN_VENDOR_ATTR_LL_STATS_RATE_BIT_RATE,
653 stats->rate.bitrate ) ||
654 nla_put_u32(vendor_event, QCA_WLAN_VENDOR_ATTR_LL_STATS_RATE_TX_MPDU,
655 stats->txMpdu ) ||
656 nla_put_u32(vendor_event, QCA_WLAN_VENDOR_ATTR_LL_STATS_RATE_RX_MPDU,
657 stats->rxMpdu ) ||
658 nla_put_u32(vendor_event, QCA_WLAN_VENDOR_ATTR_LL_STATS_RATE_MPDU_LOST,
659 stats->mpduLost ) ||
660 nla_put_u32(vendor_event, QCA_WLAN_VENDOR_ATTR_LL_STATS_RATE_RETRIES,
661 stats->retries) ||
662 nla_put_u32(vendor_event,
663 QCA_WLAN_VENDOR_ATTR_LL_STATS_RATE_RETRIES_SHORT,
664 stats->retriesShort ) ||
665 nla_put_u32(vendor_event,
666 QCA_WLAN_VENDOR_ATTR_LL_STATS_RATE_RETRIES_LONG,
667 stats->retriesLong))
668 {
669 hddLog(VOS_TRACE_LEVEL_ERROR,
670 FL("QCA_WLAN_VENDOR_ATTR put fail"));
671 return FALSE;
672 }
673 return TRUE;
674}
675
676static v_BOOL_t put_wifi_peer_info( tpSirWifiPeerInfo stats,
677 struct sk_buff *vendor_event)
678{
679 u32 i = 0;
680 struct nlattr *rateInfo;
681 if (nla_put_u32(vendor_event, QCA_WLAN_VENDOR_ATTR_LL_STATS_PEER_INFO_TYPE,
682 stats->type) ||
683 nla_put(vendor_event,
684 QCA_WLAN_VENDOR_ATTR_LL_STATS_PEER_INFO_MAC_ADDRESS,
685 VOS_MAC_ADDR_SIZE, &stats->peerMacAddress[0]) ||
686 nla_put_u32(vendor_event,
687 QCA_WLAN_VENDOR_ATTR_LL_STATS_PEER_INFO_CAPABILITIES,
688 stats->capabilities) ||
689 nla_put_u32(vendor_event,
690 QCA_WLAN_VENDOR_ATTR_LL_STATS_PEER_INFO_NUM_RATES,
691 stats->numRate))
692 {
693 hddLog(VOS_TRACE_LEVEL_ERROR,
694 FL("QCA_WLAN_VENDOR_ATTR put fail"));
695 goto error;
696 }
697
698 rateInfo = nla_nest_start(vendor_event,
699 QCA_WLAN_VENDOR_ATTR_LL_STATS_PEER_INFO_RATE_INFO);
700 for (i = 0; i < stats->numRate; i++)
701 {
702 struct nlattr *rates;
703 tpSirWifiRateStat pRateStats = (tpSirWifiRateStat )((uint8 *)
704 stats->rateStats +
705 (i * sizeof(tSirWifiRateStat)));
706 rates = nla_nest_start(vendor_event, i);
707
708 if (FALSE == put_wifi_rate_stat(pRateStats, vendor_event))
709 {
710 hddLog(VOS_TRACE_LEVEL_ERROR,
711 FL("QCA_WLAN_VENDOR_ATTR put fail"));
712 return FALSE;
713 }
714 nla_nest_end(vendor_event, rates);
715 }
716 nla_nest_end(vendor_event, rateInfo);
717
718 return TRUE;
719error:
720 return FALSE;
721}
722
723static v_BOOL_t put_wifi_wmm_ac_stat( tpSirWifiWmmAcStat stats,
724 struct sk_buff *vendor_event)
725{
726 if (nla_put_u32(vendor_event, QCA_WLAN_VENDOR_ATTR_LL_STATS_WMM_AC_AC,
727 stats->ac ) ||
728 nla_put_u32(vendor_event,
729 QCA_WLAN_VENDOR_ATTR_LL_STATS_WMM_AC_TX_MPDU,
730 stats->txMpdu ) ||
731 nla_put_u32(vendor_event,
732 QCA_WLAN_VENDOR_ATTR_LL_STATS_WMM_AC_RX_MPDU,
733 stats->rxMpdu ) ||
734 nla_put_u32(vendor_event,
735 QCA_WLAN_VENDOR_ATTR_LL_STATS_WMM_AC_TX_MCAST,
736 stats->txMcast ) ||
737 nla_put_u32(vendor_event,
738 QCA_WLAN_VENDOR_ATTR_LL_STATS_WMM_AC_RX_MCAST,
739 stats->rxMcast ) ||
740 nla_put_u32(vendor_event,
741 QCA_WLAN_VENDOR_ATTR_LL_STATS_WMM_AC_RX_AMPDU,
742 stats->rxAmpdu ) ||
743 nla_put_u32(vendor_event,
744 QCA_WLAN_VENDOR_ATTR_LL_STATS_WMM_AC_TX_AMPDU,
745 stats->txAmpdu ) ||
746 nla_put_u32(vendor_event,
747 QCA_WLAN_VENDOR_ATTR_LL_STATS_WMM_AC_MPDU_LOST,
748 stats->mpduLost )||
749 nla_put_u32(vendor_event,
750 QCA_WLAN_VENDOR_ATTR_LL_STATS_WMM_AC_RETRIES,
751 stats->retries ) ||
752 nla_put_u32(vendor_event,
753 QCA_WLAN_VENDOR_ATTR_LL_STATS_WMM_AC_RETRIES_SHORT,
754 stats->retriesShort ) ||
755 nla_put_u32(vendor_event,
756 QCA_WLAN_VENDOR_ATTR_LL_STATS_WMM_AC_RETRIES_LONG,
757 stats->retriesLong ) ||
758 nla_put_u32(vendor_event,
759 QCA_WLAN_VENDOR_ATTR_LL_STATS_WMM_AC_CONTENTION_TIME_MIN,
760 stats->contentionTimeMin ) ||
761 nla_put_u32(vendor_event,
762 QCA_WLAN_VENDOR_ATTR_LL_STATS_WMM_AC_CONTENTION_TIME_MAX,
763 stats->contentionTimeMax ) ||
764 nla_put_u32(vendor_event,
765 QCA_WLAN_VENDOR_ATTR_LL_STATS_WMM_AC_CONTENTION_TIME_AVG,
766 stats->contentionTimeAvg ) ||
767 nla_put_u32(vendor_event,
768 QCA_WLAN_VENDOR_ATTR_LL_STATS_WMM_AC_CONTENTION_NUM_SAMPLES,
769 stats->contentionNumSamples ))
770 {
771 hddLog(VOS_TRACE_LEVEL_ERROR,
772 FL("QCA_WLAN_VENDOR_ATTR put fail") );
773 return FALSE;
774 }
775 return TRUE;
776}
777
778static v_BOOL_t put_wifi_interface_info(tpSirWifiInterfaceInfo stats,
779 struct sk_buff *vendor_event)
780{
781 if (nla_put_u32(vendor_event,
782 QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_INFO_MODE, stats->mode ) ||
783 nla_put(vendor_event,
784 QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_INFO_MAC_ADDR,
785 VOS_MAC_ADDR_SIZE, stats->macAddr) ||
786 nla_put_u32(vendor_event,
787 QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_INFO_STATE,
788 stats->state ) ||
789 nla_put_u32(vendor_event,
790 QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_INFO_ROAMING,
791 stats->roaming ) ||
792 nla_put_u32(vendor_event,
793 QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_INFO_CAPABILITIES,
794 stats->capabilities ) ||
795 nla_put(vendor_event,
796 QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_INFO_SSID,
797 strlen(stats->ssid), stats->ssid) ||
798 nla_put(vendor_event,
799 QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_INFO_BSSID,
800 WNI_CFG_BSSID_LEN, stats->bssid) ||
801 nla_put(vendor_event,
802 QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_INFO_AP_COUNTRY_STR,
803 WNI_CFG_COUNTRY_CODE_LEN, stats->apCountryStr) ||
804 nla_put(vendor_event,
805 QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_INFO_COUNTRY_STR,
806 WNI_CFG_COUNTRY_CODE_LEN, stats->countryStr)
807 )
808 {
809 hddLog(VOS_TRACE_LEVEL_ERROR,
810 FL("QCA_WLAN_VENDOR_ATTR put fail") );
811 return FALSE;
812 }
813 return TRUE;
814}
815
816static v_BOOL_t put_wifi_iface_stats(tpSirWifiIfaceStat pWifiIfaceStat,
817 struct sk_buff *vendor_event)
818{
819 int i = 0;
820 struct nlattr *wmmInfo;
821 if (FALSE == put_wifi_interface_info(
822 &pWifiIfaceStat->info,
823 vendor_event))
824 {
825 hddLog(VOS_TRACE_LEVEL_ERROR,
826 FL("QCA_WLAN_VENDOR_ATTR put fail") );
827 return FALSE;
828
829 }
830
831 if (nla_put_u32(vendor_event,
832 QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_BEACON_RX,
833 pWifiIfaceStat->beaconRx) ||
834 nla_put_u32(vendor_event,
835 QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_MGMT_RX,
836 pWifiIfaceStat->mgmtRx) ||
837 nla_put_u32(vendor_event,
838 QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_MGMT_ACTION_RX,
839 pWifiIfaceStat->mgmtActionRx) ||
840 nla_put_u32(vendor_event,
841 QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_MGMT_ACTION_TX,
842 pWifiIfaceStat->mgmtActionTx) ||
843 nla_put_u32(vendor_event,
844 QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_RSSI_MGMT,
845 pWifiIfaceStat->rssiMgmt) ||
846 nla_put_u32(vendor_event,
847 QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_RSSI_DATA,
848 pWifiIfaceStat->rssiData) ||
849 nla_put_u32(vendor_event,
850 QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_RSSI_ACK,
851 pWifiIfaceStat->rssiAck))
852 {
853 hddLog(VOS_TRACE_LEVEL_ERROR,
854 FL("QCA_WLAN_VENDOR_ATTR put fail"));
855 return FALSE;
856 }
857
858 wmmInfo = nla_nest_start(vendor_event,
859 QCA_WLAN_VENDOR_ATTR_LL_STATS_WMM_INFO);
860 for (i = 0; i < WIFI_AC_MAX; i++)
861 {
862 struct nlattr *wmmStats;
863 wmmStats = nla_nest_start(vendor_event, i);
864 if (FALSE == put_wifi_wmm_ac_stat(
865 &pWifiIfaceStat->AccessclassStats[i],
866 vendor_event))
867 {
868 hddLog(VOS_TRACE_LEVEL_ERROR,
869 FL("QCA_WLAN_VENDOR_ATTR put Fail"));
870 return FALSE;
871 }
872
873 nla_nest_end(vendor_event, wmmStats);
874 }
875 nla_nest_end(vendor_event, wmmInfo);
876 return TRUE;
877}
878
879static tSirWifiInterfaceMode
880 hdd_map_device_to_ll_iface_mode ( int deviceMode )
881{
882 switch (deviceMode)
883 {
884 case WLAN_HDD_INFRA_STATION:
885 return WIFI_INTERFACE_STA;
886 case WLAN_HDD_SOFTAP:
887 return WIFI_INTERFACE_SOFTAP;
888 case WLAN_HDD_P2P_CLIENT:
889 return WIFI_INTERFACE_P2P_CLIENT;
890 case WLAN_HDD_P2P_GO:
891 return WIFI_INTERFACE_P2P_GO;
892 case WLAN_HDD_IBSS:
893 return WIFI_INTERFACE_IBSS;
894 default:
895 /* Return Interface Mode as STA for all the unsupported modes */
896 return WIFI_INTERFACE_STA;
897 }
898}
899
900static v_BOOL_t hdd_get_interface_info(hdd_adapter_t *pAdapter,
901 tpSirWifiInterfaceInfo pInfo)
902{
903 v_U8_t *staMac = NULL;
904 hdd_station_ctx_t *pHddStaCtx;
905 tHalHandle hHal = WLAN_HDD_GET_HAL_CTX(pAdapter);
906 tpAniSirGlobal pMac = PMAC_STRUCT( hHal );
907
908 pInfo->mode = hdd_map_device_to_ll_iface_mode(pAdapter->device_mode);
909
910 vos_mem_copy(pInfo->macAddr,
911 pAdapter->macAddressCurrent.bytes, sizeof(v_MACADDR_t));
912
913 if (((WLAN_HDD_INFRA_STATION == pAdapter->device_mode) ||
914 (WLAN_HDD_P2P_CLIENT == pAdapter->device_mode) ||
915 (WLAN_HDD_P2P_DEVICE == pAdapter->device_mode)))
916 {
917 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
918 if (eConnectionState_NotConnected == pHddStaCtx->conn_info.connState)
919 {
920 pInfo->state = WIFI_DISCONNECTED;
921 }
922 if (eConnectionState_Connecting == pHddStaCtx->conn_info.connState)
923 {
924 hddLog(VOS_TRACE_LEVEL_ERROR,
925 "%s: Session ID %d, Connection is in progress", __func__,
926 pAdapter->sessionId);
927 pInfo->state = WIFI_ASSOCIATING;
928 }
929 if ((eConnectionState_Associated == pHddStaCtx->conn_info.connState) &&
930 (VOS_FALSE == pHddStaCtx->conn_info.uIsAuthenticated))
931 {
932 staMac = (v_U8_t *) &(pAdapter->macAddressCurrent.bytes[0]);
933 hddLog(VOS_TRACE_LEVEL_ERROR,
934 "%s: client " MAC_ADDRESS_STR
935 " is in the middle of WPS/EAPOL exchange.", __func__,
936 MAC_ADDR_ARRAY(staMac));
937 pInfo->state = WIFI_AUTHENTICATING;
938 }
939 if (eConnectionState_Associated == pHddStaCtx->conn_info.connState)
940 {
941 pInfo->state = WIFI_ASSOCIATED;
942 vos_mem_copy(pInfo->bssid,
943 &pHddStaCtx->conn_info.bssId, WNI_CFG_BSSID_LEN);
944 vos_mem_copy(pInfo->ssid,
945 pHddStaCtx->conn_info.SSID.SSID.ssId,
946 pHddStaCtx->conn_info.SSID.SSID.length);
947 //NULL Terminate the string.
948 pInfo->ssid[pHddStaCtx->conn_info.SSID.SSID.length] = 0;
949 }
950 }
951 vos_mem_copy(pInfo->countryStr,
952 pMac->scan.countryCodeCurrent, WNI_CFG_COUNTRY_CODE_LEN);
953
954 vos_mem_copy(pInfo->apCountryStr,
955 pMac->scan.countryCodeCurrent, WNI_CFG_COUNTRY_CODE_LEN);
956
957 return TRUE;
958}
959
960/*
961 * hdd_link_layer_process_peer_stats () - This function is called after
962 * receiving Link Layer Peer statistics from FW.This function converts
963 * the firmware data to the NL data and sends the same to the kernel/upper
964 * layers.
965 */
966static v_VOID_t hdd_link_layer_process_peer_stats(hdd_adapter_t *pAdapter,
967 v_VOID_t *pData)
968{
969 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
970 tpSirWifiRateStat pWifiRateStat;
971 tpSirWifiPeerStat pWifiPeerStat;
972 tpSirWifiPeerInfo pWifiPeerInfo;
973 struct nlattr *peerInfo;
974 struct sk_buff *vendor_event;
975 int status, i;
976
977 status = wlan_hdd_validate_context(pHddCtx);
978 if (0 != status)
979 {
980 hddLog(VOS_TRACE_LEVEL_ERROR,
981 FL("HDD context is not valid") );
982 return;
983 }
984
985 pWifiPeerStat = (tpSirWifiPeerStat) pData;
986
987 hddLog(VOS_TRACE_LEVEL_INFO,
988 "LL_STATS_PEER_ALL : numPeers %u",
989 pWifiPeerStat->numPeers);
990 {
991 for (i = 0; i < pWifiPeerStat->numPeers; i++)
992 {
993 pWifiPeerInfo = (tpSirWifiPeerInfo)
994 ((uint8 *)pWifiPeerStat->peerInfo +
995 ( i * sizeof(tSirWifiPeerInfo)));
996
997 hddLog(VOS_TRACE_LEVEL_INFO,
998 " %d) LL_STATS Channel Stats "
999 " Peer Type %u "
1000 " peerMacAddress %pM "
1001 " capabilities 0x%x "
1002 " numRate %u ",
1003 i,
1004 pWifiPeerInfo->type,
1005 pWifiPeerInfo->peerMacAddress,
1006 pWifiPeerInfo->capabilities,
1007 pWifiPeerInfo->numRate);
1008 {
1009 int j;
1010 for (j = 0; j < pWifiPeerInfo->numRate; j++)
1011 {
1012 pWifiRateStat = (tpSirWifiRateStat)
1013 ((tANI_U8 *) pWifiPeerInfo->rateStats +
1014 ( j * sizeof(tSirWifiRateStat)));
1015
1016 hddLog(VOS_TRACE_LEVEL_INFO,
1017 " peer Rate Stats "
1018 " preamble %u "
1019 " nss %u "
1020 " bw %u "
1021 " rateMcsIdx %u "
1022 " reserved %u "
1023 " bitrate %u "
1024 " txMpdu %u "
1025 " rxMpdu %u "
1026 " mpduLost %u "
1027 " retries %u "
1028 " retriesShort %u "
1029 " retriesLong %u",
1030 pWifiRateStat->rate.preamble,
1031 pWifiRateStat->rate.nss,
1032 pWifiRateStat->rate.bw,
1033 pWifiRateStat->rate.rateMcsIdx,
1034 pWifiRateStat->rate.reserved,
1035 pWifiRateStat->rate.bitrate,
1036 pWifiRateStat->txMpdu,
1037 pWifiRateStat->rxMpdu,
1038 pWifiRateStat->mpduLost,
1039 pWifiRateStat->retries,
1040 pWifiRateStat->retriesShort,
1041 pWifiRateStat->retriesLong);
1042 }
1043 }
1044 }
1045 }
1046
1047 /*
1048 * Allocate a size of 4096 for the peer stats comprising
1049 * each of size = sizeof (tSirWifiPeerInfo) + numRate *
1050 * sizeof (tSirWifiRateStat).Each field is put with an
1051 * NL attribute.The size of 4096 is considered assuming
1052 * that number of rates shall not exceed beyond 50 with
1053 * the sizeof (tSirWifiRateStat) being 32.
1054 */
1055 vendor_event = cfg80211_vendor_event_alloc(pHddCtx->wiphy,
1056 LL_STATS_EVENT_BUF_SIZE + NLMSG_HDRLEN,
1057 QCA_NL80211_VENDOR_SUBCMD_LL_PEER_INFO_STATS_INDEX,
1058 GFP_KERNEL);
1059 if (!vendor_event)
1060 {
1061 hddLog(VOS_TRACE_LEVEL_ERROR,
1062 "%s: cfg80211_vendor_event_alloc failed",
1063 __func__);
1064 return;
1065 }
1066 if (nla_put_u32(vendor_event,
1067 QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_NUM_PEERS,
1068 pWifiPeerStat->numPeers))
1069 {
1070 hddLog(VOS_TRACE_LEVEL_ERROR,
1071 "%s: QCA_WLAN_VENDOR_ATTR put fail", __func__);
1072 kfree_skb(vendor_event);
1073 return;
1074 }
1075
1076 peerInfo = nla_nest_start(vendor_event,
1077 QCA_WLAN_VENDOR_ATTR_LL_STATS_PEER_INFO);
1078
1079 pWifiPeerInfo = (tpSirWifiPeerInfo) ((uint8 *)
1080 pWifiPeerStat->peerInfo);
1081
1082 for (i = 1; i <= pWifiPeerStat->numPeers; i++)
1083 {
1084 struct nlattr *peers = nla_nest_start(vendor_event, i);
1085 int numRate = pWifiPeerInfo->numRate;
1086
1087 if (FALSE == put_wifi_peer_info(
1088 pWifiPeerInfo, vendor_event))
1089 {
1090 hddLog(VOS_TRACE_LEVEL_ERROR,
1091 "%s: put_wifi_peer_info put fail", __func__);
1092 kfree_skb(vendor_event);
1093 return;
1094 }
1095
1096 pWifiPeerInfo = (tpSirWifiPeerInfo) ((uint8 *)
1097 pWifiPeerStat->peerInfo +
1098 (i * sizeof(tSirWifiPeerInfo)) +
1099 (numRate * sizeof (tSirWifiRateStat)));
1100 nla_nest_end(vendor_event, peers);
1101 }
1102 nla_nest_end(vendor_event, peerInfo);
1103 cfg80211_vendor_event(vendor_event, GFP_KERNEL);
1104}
1105
1106/*
1107 * hdd_link_layer_process_iface_stats () - This function is called after
1108 * receiving Link Layer Interface statistics from FW.This function converts
1109 * the firmware data to the NL data and sends the same to the kernel/upper
1110 * layers.
1111 */
1112static v_VOID_t hdd_link_layer_process_iface_stats(hdd_adapter_t *pAdapter,
1113 v_VOID_t *pData)
1114{
1115 tpSirWifiIfaceStat pWifiIfaceStat;
1116 struct sk_buff *vendor_event;
1117 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
1118 int status;
1119
1120 status = wlan_hdd_validate_context(pHddCtx);
1121 if (0 != status)
1122 {
1123 hddLog(VOS_TRACE_LEVEL_ERROR,
1124 FL("HDD context is not valid") );
1125 return;
1126 }
1127 /*
1128 * Allocate a size of 4096 for the interface stats comprising
1129 * sizeof (tpSirWifiIfaceStat).The size of 4096 is considered
1130 * assuming that all these fit with in the limit.Please take
1131 * a call on the limit based on the data requirements on
1132 * interface statistics.
1133 */
1134 vendor_event = cfg80211_vendor_event_alloc(pHddCtx->wiphy,
1135 LL_STATS_EVENT_BUF_SIZE + NLMSG_HDRLEN,
1136 QCA_NL80211_VENDOR_SUBCMD_LL_IFACE_STATS_INDEX,
1137 GFP_KERNEL);
1138 if (!vendor_event)
1139 {
1140 hddLog(VOS_TRACE_LEVEL_ERROR,
1141 FL("cfg80211_vendor_event_alloc failed") );
1142 return;
1143 }
1144
1145 pWifiIfaceStat = (tpSirWifiIfaceStat) pData;
1146
1147 hddLog(VOS_TRACE_LEVEL_INFO,
1148 "WMI_LINK_STATS_IFACE Data");
1149
1150 hddLog(VOS_TRACE_LEVEL_INFO,
1151 "LL_STATS_IFACE: "
1152 " Mode %u "
1153 " MAC %pM "
1154 " State %u "
1155 " Roaming %u "
1156 " capabilities 0x%x "
1157 " SSID %s "
1158 " BSSID %pM",
1159 pWifiIfaceStat->info.mode,
1160 pWifiIfaceStat->info.macAddr,
1161 pWifiIfaceStat->info.state,
1162 pWifiIfaceStat->info.roaming,
1163 pWifiIfaceStat->info.capabilities,
1164 pWifiIfaceStat->info.ssid,
1165 pWifiIfaceStat->info.bssid);
1166
1167 hddLog(VOS_TRACE_LEVEL_INFO,
1168 " AP country str: %c%c%c",
1169 pWifiIfaceStat->info.apCountryStr[0],
1170 pWifiIfaceStat->info.apCountryStr[1],
1171 pWifiIfaceStat->info.apCountryStr[2]);
1172
1173
1174 hddLog(VOS_TRACE_LEVEL_INFO,
1175 " Country Str Association: %c%c%c",
1176 pWifiIfaceStat->info.countryStr[0],
1177 pWifiIfaceStat->info.countryStr[1],
1178 pWifiIfaceStat->info.countryStr[2]);
1179
1180 hddLog(VOS_TRACE_LEVEL_INFO,
1181 " beaconRx %u "
1182 " mgmtRx %u "
1183 " mgmtActionRx %u "
1184 " mgmtActionTx %u "
1185 " rssiMgmt %u "
1186 " rssiData %u "
1187 " rssiAck %u",
1188 pWifiIfaceStat->beaconRx,
1189 pWifiIfaceStat->mgmtRx,
1190 pWifiIfaceStat->mgmtActionRx,
1191 pWifiIfaceStat->mgmtActionTx,
1192 pWifiIfaceStat->rssiMgmt,
1193 pWifiIfaceStat->rssiData,
1194 pWifiIfaceStat->rssiAck );
1195
1196
1197 {
1198 int i;
1199 for (i = 0 ; i < WIFI_AC_MAX; i ++)
1200 {
1201 hddLog(VOS_TRACE_LEVEL_INFO,
1202
1203 " %d) LL_STATS IFACE: "
1204 " ac: %u txMpdu: %u "
1205 " rxMpdu: %u txMcast: %u "
1206 " rxMcast: %u rxAmpdu: %u "
1207 " txAmpdu: %u mpduLost: %u "
1208 " retries: %u retriesShort: %u "
1209 " retriesLong: %u contentionTimeMin: %u "
1210 " contentionTimeMax: %u contentionTimeAvg: %u "
1211 " contentionNumSamples: %u",
1212 i,
1213 pWifiIfaceStat->AccessclassStats[i].ac,
1214 pWifiIfaceStat->AccessclassStats[i].txMpdu,
1215 pWifiIfaceStat->AccessclassStats[i].rxMpdu,
1216 pWifiIfaceStat->AccessclassStats[i].txMcast,
1217 pWifiIfaceStat->AccessclassStats[i].rxMcast,
1218 pWifiIfaceStat->AccessclassStats[i].rxAmpdu,
1219 pWifiIfaceStat->AccessclassStats[i].txAmpdu,
1220 pWifiIfaceStat->AccessclassStats[i].mpduLost,
1221 pWifiIfaceStat->AccessclassStats[i].retries,
1222 pWifiIfaceStat->
1223 AccessclassStats[i].retriesShort,
1224 pWifiIfaceStat->AccessclassStats[i].retriesLong,
1225 pWifiIfaceStat->
1226 AccessclassStats[i].contentionTimeMin,
1227 pWifiIfaceStat->
1228 AccessclassStats[i].contentionTimeMax,
1229 pWifiIfaceStat->
1230 AccessclassStats[i].contentionTimeAvg,
1231 pWifiIfaceStat->
1232 AccessclassStats[i].contentionNumSamples);
1233
1234 }
1235 }
1236
1237 if (FALSE == hdd_get_interface_info( pAdapter,
1238 &pWifiIfaceStat->info))
1239 {
1240 hddLog(VOS_TRACE_LEVEL_ERROR,
1241 FL("hdd_get_interface_info get fail") );
1242 kfree_skb(vendor_event);
1243 return;
1244 }
1245
1246 if (FALSE == put_wifi_iface_stats( pWifiIfaceStat,
1247 vendor_event))
1248 {
1249 hddLog(VOS_TRACE_LEVEL_ERROR,
1250 FL("put_wifi_iface_stats fail") );
1251 kfree_skb(vendor_event);
1252 return;
1253 }
1254 cfg80211_vendor_event(vendor_event, GFP_KERNEL);
1255}
1256
1257/*
1258 * hdd_link_layer_process_radio_stats () - This function is called after
1259 * receiving Link Layer Radio statistics from FW.This function converts
1260 * the firmware data to the NL data and sends the same to the kernel/upper
1261 * layers.
1262 */
1263static v_VOID_t hdd_link_layer_process_radio_stats(hdd_adapter_t *pAdapter,
1264 v_VOID_t *pData)
1265{
1266 int status, i;
1267 tpSirWifiRadioStat pWifiRadioStat;
1268 tpSirWifiChannelStats pWifiChannelStats;
1269 struct sk_buff *vendor_event;
1270 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
1271 struct nlattr *chList;
1272
1273 status = wlan_hdd_validate_context(pHddCtx);
1274 if (0 != status)
1275 {
1276 hddLog(VOS_TRACE_LEVEL_ERROR,
1277 FL("HDD context is not valid") );
1278 return;
1279 }
1280 pWifiRadioStat = (tpSirWifiRadioStat) pData;
1281
1282 hddLog(VOS_TRACE_LEVEL_INFO,
1283 "LL_STATS_RADIO"
1284 " radio is %d onTime is %u "
1285 " txTime is %u rxTime is %u "
1286 " onTimeScan is %u onTimeNbd is %u "
Dino Mycle6fb96c12014-06-10 11:52:40 +05301287 " onTimeEXTScan is %u onTimeRoamScan is %u "
Sunil Duttc69bccb2014-05-26 21:30:20 +05301288 " onTimePnoScan is %u onTimeHs20 is %u "
1289 " numChannels is %u",
1290 pWifiRadioStat->radio, pWifiRadioStat->onTime,
1291 pWifiRadioStat->txTime, pWifiRadioStat->rxTime,
1292 pWifiRadioStat->onTimeScan, pWifiRadioStat->onTimeNbd,
Dino Mycle6fb96c12014-06-10 11:52:40 +05301293 pWifiRadioStat->onTimeEXTScan,
Sunil Duttc69bccb2014-05-26 21:30:20 +05301294 pWifiRadioStat->onTimeRoamScan,
1295 pWifiRadioStat->onTimePnoScan,
1296 pWifiRadioStat->onTimeHs20,
1297 pWifiRadioStat->numChannels);
1298 /*
1299 * Allocate a size of 4096 for the Radio stats comprising
1300 * sizeof (tSirWifiRadioStat) + numChannels * sizeof
1301 * (tSirWifiChannelStats).Each channel data is put with an
1302 * NL attribute.The size of 4096 is considered assuming that
1303 * number of channels shall not exceed beyond 60 with the
1304 * sizeof (tSirWifiChannelStats) being 24 bytes.
1305 */
1306
1307 vendor_event = cfg80211_vendor_event_alloc(pHddCtx->wiphy,
1308 LL_STATS_EVENT_BUF_SIZE + NLMSG_HDRLEN ,
1309 QCA_NL80211_VENDOR_SUBCMD_LL_RADIO_STATS_INDEX,
1310 GFP_KERNEL);
1311
1312 if (!vendor_event)
1313 {
1314 hddLog(VOS_TRACE_LEVEL_ERROR,
1315 FL("cfg80211_vendor_event_alloc failed") );
1316 return;
1317 }
1318
1319 if (nla_put_u32(vendor_event,
1320 QCA_WLAN_VENDOR_ATTR_LL_STATS_RADIO_ID,
1321 pWifiRadioStat->radio) ||
1322 nla_put_u32(vendor_event,
1323 QCA_WLAN_VENDOR_ATTR_LL_STATS_RADIO_ON_TIME,
1324 pWifiRadioStat->onTime) ||
1325 nla_put_u32(vendor_event,
1326 QCA_WLAN_VENDOR_ATTR_LL_STATS_RADIO_TX_TIME,
1327 pWifiRadioStat->txTime) ||
1328 nla_put_u32(vendor_event,
1329 QCA_WLAN_VENDOR_ATTR_LL_STATS_RADIO_RX_TIME,
1330 pWifiRadioStat->rxTime) ||
1331 nla_put_u32(vendor_event,
1332 QCA_WLAN_VENDOR_ATTR_LL_STATS_RADIO_ON_TIME_SCAN,
1333 pWifiRadioStat->onTimeScan) ||
1334 nla_put_u32(vendor_event,
1335 QCA_WLAN_VENDOR_ATTR_LL_STATS_RADIO_ON_TIME_NBD,
1336 pWifiRadioStat->onTimeNbd) ||
1337 nla_put_u32(vendor_event,
Dino Mycle6fb96c12014-06-10 11:52:40 +05301338 QCA_WLAN_VENDOR_ATTR_LL_STATS_RADIO_ON_TIME_EXTSCAN,
1339 pWifiRadioStat->onTimeEXTScan)||
Sunil Duttc69bccb2014-05-26 21:30:20 +05301340 nla_put_u32(vendor_event,
1341 QCA_WLAN_VENDOR_ATTR_LL_STATS_RADIO_ON_TIME_ROAM_SCAN,
1342 pWifiRadioStat->onTimeRoamScan) ||
1343 nla_put_u32(vendor_event,
1344 QCA_WLAN_VENDOR_ATTR_LL_STATS_RADIO_ON_TIME_PNO_SCAN,
1345 pWifiRadioStat->onTimePnoScan) ||
1346 nla_put_u32(vendor_event,
1347 QCA_WLAN_VENDOR_ATTR_LL_STATS_RADIO_ON_TIME_HS20,
1348 pWifiRadioStat->onTimeHs20) ||
1349 nla_put_u32(vendor_event,
1350 QCA_WLAN_VENDOR_ATTR_LL_STATS_RADIO_NUM_CHANNELS,
1351 pWifiRadioStat->numChannels))
1352 {
1353 hddLog(VOS_TRACE_LEVEL_ERROR,
1354 FL("QCA_WLAN_VENDOR_ATTR put fail"));
1355 kfree_skb(vendor_event);
1356 return ;
1357 }
1358
1359 chList = nla_nest_start(vendor_event,
1360 QCA_WLAN_VENDOR_ATTR_LL_STATS_CH_INFO);
1361 for (i = 0; i < pWifiRadioStat->numChannels; i++)
1362 {
1363 struct nlattr *chInfo;
1364
1365 pWifiChannelStats = (tpSirWifiChannelStats) ((uint8*)
1366 pWifiRadioStat->channels +
1367 (i * sizeof(tSirWifiChannelStats)));
1368
1369 hddLog(VOS_TRACE_LEVEL_INFO,
1370 " %d) Channel Info"
1371 " width is %u "
1372 " CenterFreq %u "
1373 " CenterFreq0 %u "
1374 " CenterFreq1 %u "
1375 " onTime %u "
1376 " ccaBusyTime %u",
1377 i,
1378 pWifiChannelStats->channel.width,
1379 pWifiChannelStats->channel.centerFreq,
1380 pWifiChannelStats->channel.centerFreq0,
1381 pWifiChannelStats->channel.centerFreq1,
1382 pWifiChannelStats->onTime,
1383 pWifiChannelStats->ccaBusyTime);
1384
1385
1386 chInfo = nla_nest_start(vendor_event, i);
1387
1388 if (nla_put_u32(vendor_event,
1389 QCA_WLAN_VENDOR_ATTR_LL_STATS_CHANNEL_INFO_WIDTH,
1390 pWifiChannelStats->channel.width) ||
1391 nla_put_u32(vendor_event,
1392 QCA_WLAN_VENDOR_ATTR_LL_STATS_CHANNEL_INFO_CENTER_FREQ,
1393 pWifiChannelStats->channel.centerFreq) ||
1394 nla_put_u32(vendor_event,
1395 QCA_WLAN_VENDOR_ATTR_LL_STATS_CHANNEL_INFO_CENTER_FREQ0,
1396 pWifiChannelStats->channel.centerFreq0) ||
1397 nla_put_u32(vendor_event,
1398 QCA_WLAN_VENDOR_ATTR_LL_STATS_CHANNEL_INFO_CENTER_FREQ1,
1399 pWifiChannelStats->channel.centerFreq1) ||
1400 nla_put_u32(vendor_event,
1401 QCA_WLAN_VENDOR_ATTR_LL_STATS_CHANNEL_ON_TIME,
1402 pWifiChannelStats->onTime) ||
1403 nla_put_u32(vendor_event,
1404 QCA_WLAN_VENDOR_ATTR_LL_STATS_CHANNEL_CCA_BUSY_TIME,
1405 pWifiChannelStats->ccaBusyTime))
1406 {
1407 hddLog(VOS_TRACE_LEVEL_ERROR,
1408 FL("cfg80211_vendor_event_alloc failed") );
1409 kfree_skb(vendor_event);
1410 return ;
1411 }
1412 nla_nest_end(vendor_event, chInfo);
1413 }
1414 nla_nest_end(vendor_event, chList);
1415
1416 cfg80211_vendor_event(vendor_event, GFP_KERNEL);
1417 return;
1418}
1419
1420/*
1421 * hdd_link_layer_stats_ind_callback () - This function is called after
1422 * receiving Link Layer indications from FW.This callback converts the firmware
1423 * data to the NL data and send the same to the kernel/upper layers.
1424 */
1425static void hdd_link_layer_stats_ind_callback ( void *pCtx,
1426 int indType,
Dino Mycled3d50022014-07-07 12:58:25 +05301427 void *pRsp, u8 *macAddr)
Sunil Duttc69bccb2014-05-26 21:30:20 +05301428{
Dino Mycled3d50022014-07-07 12:58:25 +05301429 hdd_context_t *pHddCtx = (hdd_context_t *)pCtx;
1430 hdd_adapter_t *pAdapter = NULL;
1431 tpSirLLStatsResults linkLayerStatsResults = (tpSirLLStatsResults)pRsp;
Sunil Duttc69bccb2014-05-26 21:30:20 +05301432 int status;
1433
1434 status = wlan_hdd_validate_context(pHddCtx);
1435
1436 if (0 != status)
1437 {
1438 hddLog(VOS_TRACE_LEVEL_ERROR,
1439 FL("HDD context is not valid"));
1440 return;
1441 }
1442
Dino Mycled3d50022014-07-07 12:58:25 +05301443
1444
1445 pAdapter = hdd_get_adapter_by_macaddr(pHddCtx, macAddr);
1446 if (NULL == pAdapter)
1447 {
1448 hddLog(VOS_TRACE_LEVEL_ERROR,
1449 FL(" MAC address %pM does not exist with host"),
1450 macAddr);
1451 return;
1452 }
1453
Sunil Duttc69bccb2014-05-26 21:30:20 +05301454 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Dino Mycled3d50022014-07-07 12:58:25 +05301455 "%s: Interface: %s LLStats indType: %d", __func__,
1456 pAdapter->dev->name, indType);
1457
Sunil Duttc69bccb2014-05-26 21:30:20 +05301458 switch (indType)
1459 {
1460 case SIR_HAL_LL_STATS_RESULTS_RSP:
1461 {
Sunil Duttc69bccb2014-05-26 21:30:20 +05301462 hddLog(VOS_TRACE_LEVEL_INFO,
1463 FL("RESPONSE SIR_HAL_LL_STATS_RESULTS_RSP") );
1464 hddLog(VOS_TRACE_LEVEL_INFO,
1465 "LL_STATS RESULTS RESPONSE paramID = 0x%x",
1466 linkLayerStatsResults->paramId);
1467 hddLog(VOS_TRACE_LEVEL_INFO,
Dino Mycled3d50022014-07-07 12:58:25 +05301468 "LL_STATS RESULTS RESPONSE ifaceId = %u MAC: %pM",
1469 linkLayerStatsResults->ifaceId, macAddr);
Sunil Duttc69bccb2014-05-26 21:30:20 +05301470 hddLog(VOS_TRACE_LEVEL_INFO,
1471 "LL_STATS RESULTS RESPONSE respId = %u",
1472 linkLayerStatsResults->respId);
1473 hddLog(VOS_TRACE_LEVEL_INFO,
1474 "LL_STATS RESULTS RESPONSE moreResultToFollow = %u",
1475 linkLayerStatsResults->moreResultToFollow);
1476 hddLog(VOS_TRACE_LEVEL_INFO,
1477 "LL_STATS RESULTS RESPONSE result = %p",
1478 linkLayerStatsResults->result);
1479 if ( linkLayerStatsResults->paramId & WMI_LINK_STATS_RADIO )
1480 {
1481 hdd_link_layer_process_radio_stats(pAdapter,
1482 (v_VOID_t *)linkLayerStatsResults->result);
1483 }
1484 else if ( linkLayerStatsResults->paramId & WMI_LINK_STATS_IFACE )
1485 {
1486 hdd_link_layer_process_iface_stats(pAdapter,
1487 (v_VOID_t *)linkLayerStatsResults->result);
1488 }
1489 else if ( linkLayerStatsResults->paramId &
1490 WMI_LINK_STATS_ALL_PEER )
1491 {
1492 hdd_link_layer_process_peer_stats(pAdapter,
1493 (v_VOID_t *)linkLayerStatsResults->result);
1494 } /* WMI_LINK_STATS_ALL_PEER */
1495 else
1496 {
1497 hddLog(VOS_TRACE_LEVEL_ERROR,
1498 FL("INVALID LL_STATS_NOTIFY RESPONSE ***********"));
1499 }
1500
1501 break;
1502 }
1503 default:
1504 hddLog(VOS_TRACE_LEVEL_ERROR, "invalid event type %d", indType);
1505 break;
1506 }
1507 return;
1508}
1509
1510const struct
1511nla_policy
1512qca_wlan_vendor_ll_set_policy[QCA_WLAN_VENDOR_ATTR_LL_STATS_SET_MAX +1] =
1513{
1514 [QCA_WLAN_VENDOR_ATTR_LL_STATS_SET_CONFIG_MPDU_SIZE_THRESHOLD] =
1515 { .type = NLA_U32 },
1516 [QCA_WLAN_VENDOR_ATTR_LL_STATS_SET_CONFIG_AGGRESSIVE_STATS_GATHERING] =
1517 { .type = NLA_U32 },
1518};
1519
1520static int wlan_hdd_cfg80211_ll_stats_set(struct wiphy *wiphy,
1521 struct wireless_dev *wdev,
1522 void *data,
1523 int data_len)
1524{
1525 int status;
1526 struct nlattr *tb_vendor[QCA_WLAN_VENDOR_ATTR_LL_STATS_SET_MAX + 1];
Dino Mycledf0a5d92014-07-04 09:41:55 +05301527 tSirLLStatsSetReq linkLayerStatsSetReq;
Sunil Duttc69bccb2014-05-26 21:30:20 +05301528 struct net_device *dev = wdev->netdev;
1529 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
1530 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
1531
1532 status = wlan_hdd_validate_context(pHddCtx);
1533 if (0 != status)
1534 {
1535 hddLog(VOS_TRACE_LEVEL_ERROR,
1536 FL("HDD context is not valid"));
1537 return -EINVAL;
1538 }
1539
1540 if (NULL == pAdapter)
1541 {
1542 hddLog(VOS_TRACE_LEVEL_ERROR,
1543 FL("HDD adapter is Null"));
1544 return -ENODEV;
1545 }
Dino Mycledf0a5d92014-07-04 09:41:55 +05301546 /* check the LLStats Capability */
1547 if ( (TRUE != pHddCtx->cfg_ini->fEnableLLStats) ||
1548 (TRUE != sme_IsFeatureSupportedByFW(LINK_LAYER_STATS_MEAS)))
1549 {
1550 hddLog(VOS_TRACE_LEVEL_ERROR,
1551 FL("Link Layer Statistics not supported by Firmware"));
1552 return -EINVAL;
1553 }
Sunil Duttc69bccb2014-05-26 21:30:20 +05301554
1555 if (nla_parse(tb_vendor, QCA_WLAN_VENDOR_ATTR_LL_STATS_SET_MAX,
1556 (struct nlattr *)data,
1557 data_len, qca_wlan_vendor_ll_set_policy))
1558 {
1559 hddLog(VOS_TRACE_LEVEL_ERROR, FL() );
1560 return -EINVAL;
1561 }
1562 if (!tb_vendor
1563 [QCA_WLAN_VENDOR_ATTR_LL_STATS_SET_CONFIG_MPDU_SIZE_THRESHOLD])
1564 {
1565 hddLog(VOS_TRACE_LEVEL_ERROR, FL("MPDU size Not present"));
1566 return -EINVAL;
1567 }
1568 if (!tb_vendor[
1569 QCA_WLAN_VENDOR_ATTR_LL_STATS_SET_CONFIG_AGGRESSIVE_STATS_GATHERING])
1570 {
1571 hddLog(VOS_TRACE_LEVEL_ERROR, FL(" Stats Gathering Not Present"));
1572 return -EINVAL;
1573 }
Sunil Duttc69bccb2014-05-26 21:30:20 +05301574 // Shall take the request Id if the Upper layers pass. 1 For now.
Dino Mycledf0a5d92014-07-04 09:41:55 +05301575 linkLayerStatsSetReq.reqId = 1;
Sunil Duttc69bccb2014-05-26 21:30:20 +05301576
Dino Mycledf0a5d92014-07-04 09:41:55 +05301577 linkLayerStatsSetReq.mpduSizeThreshold =
Sunil Duttc69bccb2014-05-26 21:30:20 +05301578 nla_get_u32(
1579 tb_vendor[QCA_WLAN_VENDOR_ATTR_LL_STATS_SET_CONFIG_MPDU_SIZE_THRESHOLD]);
1580
Dino Mycledf0a5d92014-07-04 09:41:55 +05301581 linkLayerStatsSetReq.aggressiveStatisticsGathering =
Sunil Duttc69bccb2014-05-26 21:30:20 +05301582 nla_get_u32(
1583 tb_vendor[QCA_WLAN_VENDOR_ATTR_LL_STATS_SET_CONFIG_AGGRESSIVE_STATS_GATHERING]);
1584
Dino Mycled3d50022014-07-07 12:58:25 +05301585 vos_mem_copy(linkLayerStatsSetReq.macAddr,
1586 pAdapter->macAddressCurrent.bytes, sizeof(v_MACADDR_t));
Sunil Duttc69bccb2014-05-26 21:30:20 +05301587
1588
1589 hddLog(VOS_TRACE_LEVEL_INFO,
Dino Mycled3d50022014-07-07 12:58:25 +05301590 "LL_STATS_SET reqId = %d", linkLayerStatsSetReq.reqId);
Sunil Duttc69bccb2014-05-26 21:30:20 +05301591 hddLog(VOS_TRACE_LEVEL_INFO,
Dino Mycled3d50022014-07-07 12:58:25 +05301592 "LL_STATS_SET MAC = %pM", linkLayerStatsSetReq.macAddr);
Sunil Duttc69bccb2014-05-26 21:30:20 +05301593 hddLog(VOS_TRACE_LEVEL_INFO,
1594 "LL_STATS_SET mpduSizeThreshold = %d",
Dino Mycledf0a5d92014-07-04 09:41:55 +05301595 linkLayerStatsSetReq.mpduSizeThreshold);
Sunil Duttc69bccb2014-05-26 21:30:20 +05301596 hddLog(VOS_TRACE_LEVEL_INFO,
1597 "LL_STATS_SET aggressive Statistics Gathering = %d",
Dino Mycledf0a5d92014-07-04 09:41:55 +05301598 linkLayerStatsSetReq.aggressiveStatisticsGathering);
Sunil Duttc69bccb2014-05-26 21:30:20 +05301599
1600 if (eHAL_STATUS_SUCCESS != sme_SetLinkLayerStatsIndCB(
1601 pHddCtx->hHal,
Dino Mycled3d50022014-07-07 12:58:25 +05301602 hdd_link_layer_stats_ind_callback))
Sunil Duttc69bccb2014-05-26 21:30:20 +05301603 {
1604 hddLog(VOS_TRACE_LEVEL_ERROR, "%s:"
1605 "sme_SetLinkLayerStatsIndCB Failed", __func__);
Sunil Duttc69bccb2014-05-26 21:30:20 +05301606 return -EINVAL;
1607
1608 }
1609 if (eHAL_STATUS_SUCCESS != sme_LLStatsSetReq( pHddCtx->hHal,
Dino Mycledf0a5d92014-07-04 09:41:55 +05301610 &linkLayerStatsSetReq))
Sunil Duttc69bccb2014-05-26 21:30:20 +05301611 {
1612 hddLog(VOS_TRACE_LEVEL_ERROR, "%s:"
1613 "sme_LLStatsSetReq Failed", __func__);
Sunil Duttc69bccb2014-05-26 21:30:20 +05301614 return -EINVAL;
1615 }
1616
1617 pAdapter->isLinkLayerStatsSet = 1;
1618
1619 return 0;
1620}
1621
1622const struct
1623nla_policy
1624qca_wlan_vendor_ll_get_policy[QCA_WLAN_VENDOR_ATTR_LL_STATS_GET_MAX +1] =
1625{
1626 /* Unsigned 32bit value provided by the caller issuing the GET stats
1627 * command. When reporting
1628 * the stats results, the driver uses the same value to indicate
1629 * which GET request the results
1630 * correspond to.
1631 */
1632 [QCA_WLAN_VENDOR_ATTR_LL_STATS_GET_CONFIG_REQ_ID] = { .type = NLA_U32 },
1633
1634 /* Unsigned 32bit value . bit mask to identify what statistics are
1635 requested for retrieval */
1636 [QCA_WLAN_VENDOR_ATTR_LL_STATS_GET_CONFIG_REQ_MASK] = { .type = NLA_U32 },
1637};
1638
1639static int wlan_hdd_cfg80211_ll_stats_get(struct wiphy *wiphy,
1640 struct wireless_dev *wdev,
1641 void *data,
1642 int data_len)
1643{
1644 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
1645 struct nlattr *tb_vendor[QCA_WLAN_VENDOR_ATTR_LL_STATS_GET_MAX + 1];
Dino Mycledf0a5d92014-07-04 09:41:55 +05301646 tSirLLStatsGetReq linkLayerStatsGetReq;
Sunil Duttc69bccb2014-05-26 21:30:20 +05301647 struct net_device *dev = wdev->netdev;
1648 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
1649 int status;
1650
1651 status = wlan_hdd_validate_context(pHddCtx);
1652 if (0 != status)
1653 {
1654 hddLog(VOS_TRACE_LEVEL_ERROR,
1655 FL("HDD context is not valid"));
1656 return -EINVAL ;
1657 }
1658
1659 if (NULL == pAdapter)
1660 {
1661 hddLog(VOS_TRACE_LEVEL_FATAL,
1662 "%s: HDD adapter is Null", __func__);
1663 return -ENODEV;
1664 }
Dino Mycledf0a5d92014-07-04 09:41:55 +05301665 /* check the LLStats Capability */
1666 if ( (TRUE != pHddCtx->cfg_ini->fEnableLLStats) ||
1667 (TRUE != sme_IsFeatureSupportedByFW(LINK_LAYER_STATS_MEAS)))
1668 {
1669 hddLog(VOS_TRACE_LEVEL_ERROR,
1670 FL("Link Layer Statistics not supported by Firmware"));
1671 return -EINVAL;
1672 }
1673
Sunil Duttc69bccb2014-05-26 21:30:20 +05301674
1675 if (!pAdapter->isLinkLayerStatsSet)
1676 {
1677 hddLog(VOS_TRACE_LEVEL_FATAL,
1678 "%s: isLinkLayerStatsSet : %d",
1679 __func__, pAdapter->isLinkLayerStatsSet);
1680 return -EINVAL;
1681 }
1682
1683 if (nla_parse(tb_vendor, QCA_WLAN_VENDOR_ATTR_LL_STATS_GET_MAX,
1684 (struct nlattr *)data,
1685 data_len, qca_wlan_vendor_ll_get_policy))
1686 {
1687 hddLog(VOS_TRACE_LEVEL_ERROR, FL() );
1688 return -EINVAL;
1689 }
1690
1691 if (!tb_vendor
1692 [QCA_WLAN_VENDOR_ATTR_LL_STATS_GET_CONFIG_REQ_ID])
1693 {
1694 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Request Id Not present"));
1695 return -EINVAL;
1696 }
1697
1698 if (!tb_vendor
1699 [QCA_WLAN_VENDOR_ATTR_LL_STATS_GET_CONFIG_REQ_MASK])
1700 {
1701 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Req Mask Not present"));
1702 return -EINVAL;
1703 }
1704
Sunil Duttc69bccb2014-05-26 21:30:20 +05301705
Dino Mycledf0a5d92014-07-04 09:41:55 +05301706 linkLayerStatsGetReq.reqId =
Sunil Duttc69bccb2014-05-26 21:30:20 +05301707 nla_get_u32( tb_vendor[
1708 QCA_WLAN_VENDOR_ATTR_LL_STATS_GET_CONFIG_REQ_ID]);
Dino Mycledf0a5d92014-07-04 09:41:55 +05301709 linkLayerStatsGetReq.paramIdMask =
Sunil Duttc69bccb2014-05-26 21:30:20 +05301710 nla_get_u32( tb_vendor[
1711 QCA_WLAN_VENDOR_ATTR_LL_STATS_GET_CONFIG_REQ_MASK]);
1712
Dino Mycled3d50022014-07-07 12:58:25 +05301713 vos_mem_copy(linkLayerStatsGetReq.macAddr,
1714 pAdapter->macAddressCurrent.bytes, sizeof(v_MACADDR_t));
Sunil Duttc69bccb2014-05-26 21:30:20 +05301715
1716 hddLog(VOS_TRACE_LEVEL_INFO,
Dino Mycledf0a5d92014-07-04 09:41:55 +05301717 "LL_STATS_GET reqId = %d", linkLayerStatsGetReq.reqId);
Sunil Duttc69bccb2014-05-26 21:30:20 +05301718 hddLog(VOS_TRACE_LEVEL_INFO,
Dino Mycled3d50022014-07-07 12:58:25 +05301719 "LL_STATS_GET MAC = %pM", linkLayerStatsGetReq.macAddr);
Sunil Duttc69bccb2014-05-26 21:30:20 +05301720 hddLog(VOS_TRACE_LEVEL_INFO,
1721 "LL_STATS_GET paramIdMask = %d",
Dino Mycledf0a5d92014-07-04 09:41:55 +05301722 linkLayerStatsGetReq.paramIdMask);
Sunil Duttc69bccb2014-05-26 21:30:20 +05301723
1724 if (eHAL_STATUS_SUCCESS != sme_LLStatsGetReq( pHddCtx->hHal,
Dino Mycledf0a5d92014-07-04 09:41:55 +05301725 &linkLayerStatsGetReq))
Sunil Duttc69bccb2014-05-26 21:30:20 +05301726 {
1727 hddLog(VOS_TRACE_LEVEL_ERROR, "%s:"
1728 "sme_LLStatsGetReq Failed", __func__);
Sunil Duttc69bccb2014-05-26 21:30:20 +05301729 return -EINVAL;
1730 }
1731 return 0;
1732}
1733
1734const struct
1735nla_policy
1736qca_wlan_vendor_ll_clr_policy[QCA_WLAN_VENDOR_ATTR_LL_STATS_CLR_MAX +1] =
1737{
1738 [QCA_WLAN_VENDOR_ATTR_LL_STATS_CLR_CONFIG_REQ_MASK] = {.type = NLA_U32 },
1739 [QCA_WLAN_VENDOR_ATTR_LL_STATS_CLR_CONFIG_STOP_REQ] = {.type = NLA_U8 },
1740 [QCA_WLAN_VENDOR_ATTR_LL_STATS_CLR_CONFIG_RSP_MASK] = {.type = NLA_U32 },
1741 [QCA_WLAN_VENDOR_ATTR_LL_STATS_CLR_CONFIG_STOP_RSP] = {.type = NLA_U8 },
1742};
1743
1744static int wlan_hdd_cfg80211_ll_stats_clear(struct wiphy *wiphy,
1745 struct wireless_dev *wdev,
1746 void *data,
1747 int data_len)
1748{
1749 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
1750 struct nlattr *tb_vendor[QCA_WLAN_VENDOR_ATTR_LL_STATS_CLR_MAX + 1];
Dino Mycledf0a5d92014-07-04 09:41:55 +05301751 tSirLLStatsClearReq linkLayerStatsClearReq;
Sunil Duttc69bccb2014-05-26 21:30:20 +05301752 struct net_device *dev = wdev->netdev;
1753 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
1754 u32 statsClearReqMask;
1755 u8 stopReq;
1756 int status;
1757
1758 status = wlan_hdd_validate_context(pHddCtx);
1759 if (0 != status)
1760 {
1761 hddLog(VOS_TRACE_LEVEL_ERROR,
1762 FL("HDD context is not valid"));
1763 return -EINVAL;
1764 }
1765
1766 if (NULL == pAdapter)
1767 {
1768 hddLog(VOS_TRACE_LEVEL_FATAL,
1769 "%s: HDD adapter is Null", __func__);
1770 return -ENODEV;
1771 }
Dino Mycledf0a5d92014-07-04 09:41:55 +05301772 /* check the LLStats Capability */
1773 if ( (TRUE != pHddCtx->cfg_ini->fEnableLLStats) ||
1774 (TRUE != sme_IsFeatureSupportedByFW(LINK_LAYER_STATS_MEAS)))
1775 {
1776 hddLog(VOS_TRACE_LEVEL_ERROR,
1777 FL("Enable LLStats Capability"));
1778 return -EINVAL;
1779 }
Sunil Duttc69bccb2014-05-26 21:30:20 +05301780
1781 if (!pAdapter->isLinkLayerStatsSet)
1782 {
1783 hddLog(VOS_TRACE_LEVEL_FATAL,
1784 "%s: isLinkLayerStatsSet : %d",
1785 __func__, pAdapter->isLinkLayerStatsSet);
1786 return -EINVAL;
1787 }
1788
1789 if (nla_parse(tb_vendor, QCA_WLAN_VENDOR_ATTR_LL_STATS_CLR_MAX,
1790 (struct nlattr *)data,
1791 data_len, qca_wlan_vendor_ll_clr_policy))
1792 {
1793 hddLog(VOS_TRACE_LEVEL_ERROR, FL() );
1794 return -EINVAL;
1795 }
1796
1797 if (!tb_vendor[QCA_WLAN_VENDOR_ATTR_LL_STATS_CLR_CONFIG_REQ_MASK] ||
1798
1799 !tb_vendor[QCA_WLAN_VENDOR_ATTR_LL_STATS_CLR_CONFIG_STOP_REQ])
1800 {
1801 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Error in LL_STATS CLR CONFIG PARA") );
1802 return -EINVAL;
1803
1804 }
1805
Sunil Duttc69bccb2014-05-26 21:30:20 +05301806
Dino Mycledf0a5d92014-07-04 09:41:55 +05301807 statsClearReqMask = linkLayerStatsClearReq.statsClearReqMask =
Sunil Duttc69bccb2014-05-26 21:30:20 +05301808 nla_get_u32(
1809 tb_vendor[QCA_WLAN_VENDOR_ATTR_LL_STATS_CLR_CONFIG_REQ_MASK]);
1810
Dino Mycledf0a5d92014-07-04 09:41:55 +05301811 stopReq = linkLayerStatsClearReq.stopReq =
Sunil Duttc69bccb2014-05-26 21:30:20 +05301812 nla_get_u8(
1813 tb_vendor[QCA_WLAN_VENDOR_ATTR_LL_STATS_CLR_CONFIG_STOP_REQ]);
1814
1815 // Shall take the request Id if the Upper layers pass. 1 For now.
Dino Mycledf0a5d92014-07-04 09:41:55 +05301816 linkLayerStatsClearReq.reqId = 1;
Sunil Duttc69bccb2014-05-26 21:30:20 +05301817
Dino Mycled3d50022014-07-07 12:58:25 +05301818 vos_mem_copy(linkLayerStatsClearReq.macAddr,
1819 pAdapter->macAddressCurrent.bytes, sizeof(v_MACADDR_t));
Sunil Duttc69bccb2014-05-26 21:30:20 +05301820
1821 hddLog(VOS_TRACE_LEVEL_INFO,
Dino Mycledf0a5d92014-07-04 09:41:55 +05301822 "LL_STATS_CLEAR reqId = %d", linkLayerStatsClearReq.reqId);
Sunil Duttc69bccb2014-05-26 21:30:20 +05301823 hddLog(VOS_TRACE_LEVEL_INFO,
Dino Mycled3d50022014-07-07 12:58:25 +05301824 "LL_STATS_CLEAR MAC = %pM", linkLayerStatsClearReq.macAddr);
Sunil Duttc69bccb2014-05-26 21:30:20 +05301825 hddLog(VOS_TRACE_LEVEL_INFO,
1826 "LL_STATS_CLEAR statsClearReqMask = 0x%X",
Dino Mycledf0a5d92014-07-04 09:41:55 +05301827 linkLayerStatsClearReq.statsClearReqMask);
Sunil Duttc69bccb2014-05-26 21:30:20 +05301828 hddLog(VOS_TRACE_LEVEL_INFO,
1829 "LL_STATS_CLEAR stopReq = %d",
Dino Mycledf0a5d92014-07-04 09:41:55 +05301830 linkLayerStatsClearReq.stopReq);
Sunil Duttc69bccb2014-05-26 21:30:20 +05301831
1832 if (eHAL_STATUS_SUCCESS == sme_LLStatsClearReq(pHddCtx->hHal,
Dino Mycledf0a5d92014-07-04 09:41:55 +05301833 &linkLayerStatsClearReq))
Sunil Duttc69bccb2014-05-26 21:30:20 +05301834 {
1835 struct sk_buff *temp_skbuff;
1836 temp_skbuff = cfg80211_vendor_cmd_alloc_reply_skb(wiphy,
1837 2 * sizeof(u32) +
1838 NLMSG_HDRLEN);
1839
1840 if (temp_skbuff != NULL)
1841 {
1842
1843 if (nla_put_u32(temp_skbuff,
1844 QCA_WLAN_VENDOR_ATTR_LL_STATS_CLR_CONFIG_RSP_MASK,
1845 statsClearReqMask) ||
1846 nla_put_u32(temp_skbuff,
1847 QCA_WLAN_VENDOR_ATTR_LL_STATS_CLR_CONFIG_STOP_RSP,
1848 stopReq))
1849 {
1850 hddLog(VOS_TRACE_LEVEL_ERROR, FL("LL_STATS_CLR put fail"));
1851 kfree_skb(temp_skbuff);
1852 return -EINVAL;
1853 }
1854 /* If the ask is to stop the stats collection as part of clear
1855 * (stopReq = 1) , ensure that no further requests of get
1856 * go to the firmware by having isLinkLayerStatsSet set to 0.
1857 * However it the stopReq as part of the clear request is 0 ,
Dino Mycledf0a5d92014-07-04 09:41:55 +05301858 * the request to get the statistics are honoured as in this
Sunil Duttc69bccb2014-05-26 21:30:20 +05301859 * case the firmware is just asked to clear the statistics.
1860 */
Dino Mycledf0a5d92014-07-04 09:41:55 +05301861 if (linkLayerStatsClearReq.stopReq == 1)
Sunil Duttc69bccb2014-05-26 21:30:20 +05301862 pAdapter->isLinkLayerStatsSet = 0;
1863 return cfg80211_vendor_cmd_reply(temp_skbuff);
1864 }
1865 return -ENOMEM;
1866 }
Sunil Duttc69bccb2014-05-26 21:30:20 +05301867 return -EINVAL;
1868}
1869#endif /* WLAN_FEATURE_LINK_LAYER_STATS */
1870
Dino Mycle6fb96c12014-06-10 11:52:40 +05301871#ifdef WLAN_FEATURE_EXTSCAN
1872static const struct nla_policy
1873wlan_hdd_extscan_config_policy
1874 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX + 1] =
1875{
1876 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_REQUEST_ID] =
1877 { .type = NLA_U32 },
1878 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_GET_VALID_CHANNELS_CONFIG_PARAM_WIFI_BAND] =
1879 { .type = NLA_U32 },
1880 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_CHANNEL_SPEC_CHANNEL] = { .type = NLA_U32 },
1881 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_CHANNEL_SPEC_DWELL_TIME] =
1882 { .type = NLA_U32 },
1883 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_CHANNEL_SPEC_PASSIVE] = { .type = NLA_U8 },
1884 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_CHANNEL_SPEC_CLASS] = { .type = NLA_U8 },
1885
1886 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_INDEX] = { .type = NLA_U8 },
1887 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_BAND] = { .type = NLA_U8 },
1888 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_PERIOD] = { .type = NLA_U32 },
1889 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_REPORT_EVENTS] =
1890 { .type = NLA_U8 },
1891 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_NUM_CHANNEL_SPECS] =
1892 { .type = NLA_U32 },
1893 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_SCAN_CMD_PARAMS_BASE_PERIOD] =
1894 { .type = NLA_U32 },
1895 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_SCAN_CMD_PARAMS_MAX_AP_PER_SCAN] =
1896 { .type = NLA_U32 },
1897 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_SCAN_CMD_PARAMS_REPORT_THRESHOLD] =
1898 { .type = NLA_U8 },
1899 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_SCAN_CMD_PARAMS_NUM_BUCKETS] =
1900 { .type = NLA_U8 },
1901 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_GET_CACHED_SCAN_RESULTS_CONFIG_PARAM_FLUSH] =
1902 { .type = NLA_U8 },
1903
1904 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_GET_CACHED_SCAN_RESULTS_CONFIG_PARAM_MAX] =
1905 { .type = NLA_U32 },
1906 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_AP_THRESHOLD_PARAM_BSSID] =
1907 { .type = NLA_UNSPEC },
1908 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_AP_THRESHOLD_PARAM_RSSI_LOW] =
1909 { .type = NLA_S32 },
1910 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_AP_THRESHOLD_PARAM_RSSI_HIGH] =
1911 { .type = NLA_S32 },
1912 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_AP_THRESHOLD_PARAM_CHANNEL] =
1913 { .type = NLA_U32 },
1914 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_BSSID_HOTLIST_PARAMS_NUM_AP] =
1915 { .type = NLA_U32 },
1916 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_SIGNIFICANT_CHANGE_PARAMS_RSSI_SAMPLE_SIZE] =
1917 { .type = NLA_U32 },
1918 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_SIGNIFICANT_CHANGE_PARAMS_LOST_AP_SAMPLE_SIZE]
1919 = { .type = NLA_U32 },
1920 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_SIGNIFICANT_CHANGE_PARAMS_MIN_BREACHING] =
1921 { .type = NLA_U32 },
1922 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_SIGNIFICANT_CHANGE_PARAMS_NUM_AP] = { .type =
1923 NLA_U32 },
1924};
1925
1926static void wlan_hdd_cfg80211_extscan_get_capabilities_ind(void *ctx, void *pMsg)
1927{
1928 hdd_context_t *pHddCtx = (hdd_context_t *)ctx;
1929 struct sk_buff *skb = NULL;
1930 tpSirEXTScanCapabilitiesEvent pData =
1931 (tpSirEXTScanCapabilitiesEvent) pMsg;
1932
1933 if (wlan_hdd_validate_context(pHddCtx) || !pData) {
1934 hddLog(VOS_TRACE_LEVEL_ERROR, FL("HDD context is not valid "
1935 "or pData(%p) is null"), pData);
1936 return;
1937 }
1938
1939 skb = cfg80211_vendor_event_alloc(pHddCtx->wiphy,
1940 EXTSCAN_EVENT_BUF_SIZE + NLMSG_HDRLEN,
1941 QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_GET_CAPABILITIES_INDEX,
1942 GFP_KERNEL);
1943
1944 if (!skb) {
1945 hddLog(VOS_TRACE_LEVEL_ERROR,
1946 FL("cfg80211_vendor_event_alloc failed"));
1947 return;
1948 }
1949
1950 hddLog(VOS_TRACE_LEVEL_INFO, "Req Id (%u)", pData->requestId);
1951 hddLog(VOS_TRACE_LEVEL_INFO, "Scan cache size (%u)", pData->scanCacheSize);
1952 hddLog(VOS_TRACE_LEVEL_INFO, "Scan buckets (%u)", pData->scanBuckets);
1953 hddLog(VOS_TRACE_LEVEL_INFO, "Max AP per scan (%u)", pData->maxApPerScan);
1954 hddLog(VOS_TRACE_LEVEL_INFO, "maxRssiSampleSize (%u)",
1955 pData->maxRssiSampleSize);
1956 hddLog(VOS_TRACE_LEVEL_INFO, "maxScanReportingThreshold (%u)",
1957 pData->maxScanReportingThreshold);
1958 hddLog(VOS_TRACE_LEVEL_INFO, "maxHotlistAPs (%u)", pData->maxHotlistAPs);
1959 hddLog(VOS_TRACE_LEVEL_INFO, "maxSignificantWifiChangeAPs (%u)",
1960 pData->maxSignificantWifiChangeAPs);
1961 hddLog(VOS_TRACE_LEVEL_INFO, "maxBsidHistoryEntries (%u)",
1962 pData->maxBsidHistoryEntries);
1963
1964 if (nla_put_u32(skb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_REQUEST_ID,
1965 pData->requestId) ||
1966 nla_put_u32(skb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_STATUS, pData->status) ||
1967 nla_put_u32(skb,
1968 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_CAPABILITIES_MAX_SCAN_CACHE_SIZE,
1969 pData->scanCacheSize) ||
1970 nla_put_u32(skb,
1971 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_CAPABILITIES_MAX_SCAN_BUCKETS,
1972 pData->scanBuckets) ||
1973 nla_put_u32(skb,
1974 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_CAPABILITIES_MAX_AP_CACHE_PER_SCAN,
1975 pData->maxApPerScan) ||
1976 nla_put_u32(skb,
1977 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_CAPABILITIES_MAX_RSSI_SAMPLE_SIZE,
1978 pData->maxRssiSampleSize) ||
1979 nla_put_u32(skb,
1980 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_CAPABILITIES_MAX_SCAN_REPORTING_THRESHOLD,
1981 pData->maxScanReportingThreshold) ||
1982 nla_put_u32(skb,
1983 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_CAPABILITIES_MAX_HOTLIST_APS,
1984 pData->maxHotlistAPs) ||
1985 nla_put_u32(skb,
1986 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_CAPABILITIES_MAX_SIGNIFICANT_WIFI_CHANGE_APS,
1987 pData->maxSignificantWifiChangeAPs) ||
1988 nla_put_u32(skb,
1989 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_CAPABILITIES_MAX_BSSID_HISTORY_ENTRIES,
1990 pData->maxBsidHistoryEntries)) {
1991 hddLog(VOS_TRACE_LEVEL_ERROR, FL("nla put fail"));
1992 goto nla_put_failure;
1993 }
1994
1995 cfg80211_vendor_event(skb, GFP_KERNEL);
1996 return;
1997
1998nla_put_failure:
1999 kfree_skb(skb);
2000 return;
2001}
2002
2003
2004static void wlan_hdd_cfg80211_extscan_start_rsp(void *ctx, void *pMsg)
2005{
2006 tpSirEXTScanStartRspParams pData = (tpSirEXTScanStartRspParams) pMsg;
2007 hdd_context_t *pHddCtx = (hdd_context_t *)ctx;
2008 struct sk_buff *skb = NULL;
2009 tpAniSirGlobal pMac = PMAC_STRUCT( pHddCtx->hHal );
2010
2011
2012 if (wlan_hdd_validate_context(pHddCtx) || !pData) {
2013 hddLog(VOS_TRACE_LEVEL_ERROR, FL("HDD context is not valid "
2014 "or pData(%p) is null"), pData);
2015 return;
2016 }
2017
2018 skb = cfg80211_vendor_event_alloc(pHddCtx->wiphy,
2019 EXTSCAN_EVENT_BUF_SIZE + NLMSG_HDRLEN,
2020 QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_START_INDEX,
2021 GFP_KERNEL);
2022
2023 if (!skb) {
2024 hddLog(VOS_TRACE_LEVEL_ERROR,
2025 FL("cfg80211_vendor_event_alloc failed"));
2026 return;
2027 }
2028 hddLog(VOS_TRACE_LEVEL_INFO, FL("Entering "));
2029 hddLog(VOS_TRACE_LEVEL_INFO, "Req Id (%u)", pData->requestId);
2030 hddLog(VOS_TRACE_LEVEL_INFO, "Status (%u)", pData->status);
2031
2032 if (nla_put_u32(skb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_REQUEST_ID,
2033 pData->requestId) ||
2034 nla_put_u32(skb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_STATUS, pData->status)) {
2035 hddLog(VOS_TRACE_LEVEL_ERROR, FL("nla put fail"));
2036 goto nla_put_failure;
2037 }
2038
2039 /*
2040 * Store the Request ID for comparing with the requestID obtained
2041 * in other requests.HDD shall return a failure is the extscan_stop
2042 * request is issued with a different requestId as that of the
2043 * extscan_start request. Also, This requestId shall be used while
2044 * indicating the full scan results to the upper layers.
2045 * The requestId is stored with the assumption that the firmware
2046 * shall return the ext scan start request's requestId in ext scan
2047 * start response.
2048 */
2049 if (pData->status == 0)
2050 pMac->sme.extScanStartReqId = pData->requestId;
2051
2052
2053 cfg80211_vendor_event(skb, GFP_KERNEL);
2054 return;
2055
2056nla_put_failure:
2057 kfree_skb(skb);
2058 return;
2059}
2060
2061
2062static void wlan_hdd_cfg80211_extscan_stop_rsp(void *ctx, void *pMsg)
2063{
2064 tpSirEXTScanStopRspParams pData = (tpSirEXTScanStopRspParams) pMsg;
2065 hdd_context_t *pHddCtx = (hdd_context_t *)ctx;
2066 struct sk_buff *skb = NULL;
2067
2068 if (wlan_hdd_validate_context(pHddCtx) || !pData) {
2069 hddLog(VOS_TRACE_LEVEL_ERROR, FL("HDD context is not valid "
2070 "or pData(%p) is null"), pData);
2071 return;
2072 }
2073
2074 skb = cfg80211_vendor_event_alloc(pHddCtx->wiphy,
2075 EXTSCAN_EVENT_BUF_SIZE + NLMSG_HDRLEN,
2076 QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_STOP_INDEX,
2077 GFP_KERNEL);
2078
2079 if (!skb) {
2080 hddLog(VOS_TRACE_LEVEL_ERROR,
2081 FL("cfg80211_vendor_event_alloc failed"));
2082 return;
2083 }
2084 hddLog(VOS_TRACE_LEVEL_INFO, FL("Entering "));
2085 hddLog(VOS_TRACE_LEVEL_INFO, "Req Id (%u)", pData->requestId);
2086
2087 if (nla_put_u32(skb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_REQUEST_ID,
2088 pData->requestId) ||
2089 nla_put_u32(skb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_STATUS, pData->status)) {
2090 hddLog(VOS_TRACE_LEVEL_ERROR, FL("nla put fail"));
2091 goto nla_put_failure;
2092 }
2093
2094 cfg80211_vendor_event(skb, GFP_KERNEL);
2095 return;
2096
2097nla_put_failure:
2098 kfree_skb(skb);
2099 return;
2100}
2101
2102
2103static void wlan_hdd_cfg80211_extscan_set_bss_hotlist_rsp(void *ctx,
2104 void *pMsg)
2105{
2106 hdd_context_t *pHddCtx = (hdd_context_t *)ctx;
2107 struct sk_buff *skb = NULL;
2108 tpSirEXTScanSetBssidHotListRspParams pData =
2109 (tpSirEXTScanSetBssidHotListRspParams) pMsg;
2110
2111 if (wlan_hdd_validate_context(pHddCtx) || !pData) {
2112 hddLog(VOS_TRACE_LEVEL_ERROR, FL("HDD context is not valid "
2113 "or pData(%p) is null"), pData);
2114 return;
2115 }
2116 skb = cfg80211_vendor_event_alloc(pHddCtx->wiphy,
2117 EXTSCAN_EVENT_BUF_SIZE + NLMSG_HDRLEN,
2118 QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_SET_BSSID_HOTLIST_INDEX,
2119 GFP_KERNEL);
2120
2121 if (!skb) {
2122 hddLog(VOS_TRACE_LEVEL_ERROR,
2123 FL("cfg80211_vendor_event_alloc failed"));
2124 return;
2125 }
2126 hddLog(VOS_TRACE_LEVEL_INFO, FL("Entering "));
2127 hddLog(VOS_TRACE_LEVEL_INFO, "Req Id (%u)", pData->requestId);
2128 hddLog(VOS_TRACE_LEVEL_INFO, "Status (%u)", pData->status);
2129
2130 if (nla_put_u32(skb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_REQUEST_ID,
2131 pData->requestId) ||
2132 nla_put_u32(skb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_STATUS, pData->status)) {
2133 hddLog(VOS_TRACE_LEVEL_ERROR, FL("nla put fail"));
2134 goto nla_put_failure;
2135 }
2136
2137 cfg80211_vendor_event(skb, GFP_KERNEL);
2138 return;
2139
2140nla_put_failure:
2141 kfree_skb(skb);
2142 return;
2143}
2144
2145static void wlan_hdd_cfg80211_extscan_reset_bss_hotlist_rsp(void *ctx,
2146 void *pMsg)
2147{
2148 hdd_context_t *pHddCtx = (hdd_context_t *)ctx;
2149 struct sk_buff *skb = NULL;
2150 tpSirEXTScanResetBssidHotlistRspParams pData =
2151 (tpSirEXTScanResetBssidHotlistRspParams) pMsg;
2152
2153 if (wlan_hdd_validate_context(pHddCtx) || !pData) {
2154 hddLog(VOS_TRACE_LEVEL_ERROR, FL("HDD context is not valid "
2155 "or pData(%p) is null"), pData);
2156 return;
2157 }
2158
2159 skb = cfg80211_vendor_event_alloc(pHddCtx->wiphy,
2160 EXTSCAN_EVENT_BUF_SIZE + NLMSG_HDRLEN,
2161 QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_RESET_BSSID_HOTLIST_INDEX,
2162 GFP_KERNEL);
2163
2164 if (!skb) {
2165 hddLog(VOS_TRACE_LEVEL_ERROR,
2166 FL("cfg80211_vendor_event_alloc failed"));
2167 return;
2168 }
2169 hddLog(VOS_TRACE_LEVEL_INFO, FL("Entering "));
2170 hddLog(VOS_TRACE_LEVEL_INFO, "Req Id (%u)", pData->requestId);
2171
2172 if (nla_put_u32(skb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_REQUEST_ID,
2173 pData->requestId) ||
2174 nla_put_u32(skb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_STATUS, pData->status)) {
2175 hddLog(VOS_TRACE_LEVEL_ERROR, FL("nla put fail"));
2176 goto nla_put_failure;
2177 }
2178
2179 cfg80211_vendor_event(skb, GFP_KERNEL);
2180 return;
2181
2182nla_put_failure:
2183 kfree_skb(skb);
2184 return;
2185}
2186
2187
2188static void wlan_hdd_cfg80211_extscan_set_signf_wifi_change_rsp(void *ctx,
2189 void *pMsg)
2190{
2191 hdd_context_t *pHddCtx = (hdd_context_t *)ctx;
2192 struct sk_buff *skb = NULL;
2193 tpSirEXTScanSetSignificantChangeRspParams pData =
2194 (tpSirEXTScanSetSignificantChangeRspParams) pMsg;
2195
2196 if (wlan_hdd_validate_context(pHddCtx) || !pData) {
2197 hddLog(VOS_TRACE_LEVEL_ERROR, FL("HDD context is not valid "
2198 "or pData(%p) is null"), pData);
2199 return;
2200 }
2201
2202 skb = cfg80211_vendor_event_alloc(pHddCtx->wiphy,
2203 EXTSCAN_EVENT_BUF_SIZE + NLMSG_HDRLEN,
2204 QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_SET_SIGNIFICANT_CHANGE_INDEX,
2205 GFP_KERNEL);
2206
2207 if (!skb) {
2208 hddLog(VOS_TRACE_LEVEL_ERROR,
2209 FL("cfg80211_vendor_event_alloc failed"));
2210 return;
2211 }
2212 hddLog(VOS_TRACE_LEVEL_INFO, FL("Entering "));
2213 hddLog(VOS_TRACE_LEVEL_INFO, "Req Id (%u)", pData->requestId);
2214 hddLog(VOS_TRACE_LEVEL_INFO, "Status (%u)", pData->status);
2215
2216 if (nla_put_u32(skb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_REQUEST_ID,
2217 pData->requestId) ||
2218 nla_put_u32(skb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_STATUS, pData->status)) {
2219 hddLog(VOS_TRACE_LEVEL_ERROR, FL("nla put fail"));
2220 goto nla_put_failure;
2221 }
2222
2223 cfg80211_vendor_event(skb, GFP_KERNEL);
2224 return;
2225
2226nla_put_failure:
2227 kfree_skb(skb);
2228 return;
2229}
2230
2231
2232static void wlan_hdd_cfg80211_extscan_reset_signf_wifi_change_rsp(void *ctx,
2233 void *pMsg)
2234{
2235 hdd_context_t *pHddCtx = (hdd_context_t *)ctx;
2236 struct sk_buff *skb = NULL;
2237 tpSirEXTScanResetSignificantChangeRspParams pData =
2238 (tpSirEXTScanResetSignificantChangeRspParams) pMsg;
2239
2240 if (wlan_hdd_validate_context(pHddCtx) || !pData) {
2241 hddLog(VOS_TRACE_LEVEL_ERROR, FL("HDD context is not valid "
2242 "or pData(%p) is null"), pData);
2243 return;
2244 }
2245
2246 skb = cfg80211_vendor_event_alloc(pHddCtx->wiphy,
2247 EXTSCAN_EVENT_BUF_SIZE + NLMSG_HDRLEN,
2248 QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_RESET_SIGNIFICANT_CHANGE_INDEX,
2249 GFP_KERNEL);
2250
2251 if (!skb) {
2252 hddLog(VOS_TRACE_LEVEL_ERROR,
2253 FL("cfg80211_vendor_event_alloc failed"));
2254 return;
2255 }
2256 hddLog(VOS_TRACE_LEVEL_INFO, FL("Entering "));
2257 hddLog(VOS_TRACE_LEVEL_INFO, "Req Id (%u)", pData->requestId);
2258 hddLog(VOS_TRACE_LEVEL_INFO, "Status (%u)", pData->status);
2259
2260 if (nla_put_u32(skb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_REQUEST_ID,
2261 pData->requestId) ||
2262 nla_put_u32(skb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_STATUS, pData->status)) {
2263 hddLog(VOS_TRACE_LEVEL_ERROR, FL("nla put fail"));
2264 goto nla_put_failure;
2265 }
2266
2267 cfg80211_vendor_event(skb, GFP_KERNEL);
2268 return;
2269
2270nla_put_failure:
2271 kfree_skb(skb);
2272 return;
2273}
2274
2275static void wlan_hdd_cfg80211_extscan_cached_results_ind(void *ctx,
2276 void *pMsg)
2277{
2278 hdd_context_t *pHddCtx = (hdd_context_t *)ctx;
2279 struct sk_buff *skb = NULL;
2280 tANI_U32 i = 0, j, resultsPerEvent;
2281 tANI_S32 totalResults;
2282 tpSirWifiScanResultEvent pData = (tpSirWifiScanResultEvent) pMsg;
2283 tpSirWifiScanResult pSirWifiScanResult;
2284
2285 if (wlan_hdd_validate_context(pHddCtx) || !pData) {
2286 hddLog(VOS_TRACE_LEVEL_ERROR, FL("HDD context is not valid "
2287 "or pData(%p) is null"), pData);
2288 return;
2289 }
2290 totalResults = pData->numOfAps;
2291 hddLog(VOS_TRACE_LEVEL_INFO, "Req Id (%u)", pData->requestId);
2292 hddLog(VOS_TRACE_LEVEL_INFO, "Num results (%u)", pData->numOfAps);
2293 hddLog(VOS_TRACE_LEVEL_INFO, "More Data (%u)", pData->moreData);
2294
2295 do{
2296 resultsPerEvent = ((totalResults >= EXTSCAN_MAX_CACHED_RESULTS_PER_IND) ?
2297 EXTSCAN_MAX_CACHED_RESULTS_PER_IND : totalResults);
2298 totalResults -= EXTSCAN_MAX_CACHED_RESULTS_PER_IND;
2299
2300 skb = cfg80211_vendor_event_alloc(pHddCtx->wiphy,
2301 EXTSCAN_EVENT_BUF_SIZE + NLMSG_HDRLEN,
2302 QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_GET_CACHED_RESULTS_INDEX,
2303 GFP_KERNEL);
2304
2305 if (!skb) {
2306 hddLog(VOS_TRACE_LEVEL_ERROR,
2307 FL("cfg80211_vendor_event_alloc failed"));
2308 return;
2309 }
2310
2311 hddLog(VOS_TRACE_LEVEL_INFO, "resultsPerEvent (%u)", resultsPerEvent);
2312
2313 if (nla_put_u32(skb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_REQUEST_ID,
2314 pData->requestId) ||
2315 nla_put_u32(skb,
2316 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_NUM_RESULTS_AVAILABLE,
2317 resultsPerEvent)) {
2318 hddLog(VOS_TRACE_LEVEL_ERROR, FL("put fail"));
2319 goto fail;
2320 }
2321 if (nla_put_u8(skb,
2322 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_MORE_DATA,
2323 pData->moreData ? 1 : (totalResults > 0 ? 1 : 0 )))
2324 {
2325 hddLog(VOS_TRACE_LEVEL_ERROR, FL("put fail"));
2326 goto fail;
2327 }
2328
2329 if (resultsPerEvent) {
2330 struct nlattr *aps;
2331
2332 aps = nla_nest_start(skb,
2333 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_LIST);
2334 if (!aps)
2335 {
2336 hddLog(VOS_TRACE_LEVEL_ERROR, FL("put fail"));
2337 goto fail;
2338 }
2339
2340 for (j = 0; j < resultsPerEvent; j++, i++) {
2341 struct nlattr *ap;
2342 pSirWifiScanResult = (tpSirWifiScanResult) ((tANI_U8 *)
2343 pData->ap + ( i* sizeof(tSirWifiScanResult)));
2344
2345 hddLog(VOS_TRACE_LEVEL_INFO, "[index=%u] Timestamp(%llu) "
2346 "Ssid (%s)"
2347 "Bssid: %pM "
2348 "Channel (%u)"
2349 "Rssi (%d)"
2350 "RTT (%u)"
2351 "RTT_SD (%u)",
2352 i,
2353 pSirWifiScanResult->ts,
2354 pSirWifiScanResult->ssid,
2355 pSirWifiScanResult->bssid,
2356 pSirWifiScanResult->channel,
2357 pSirWifiScanResult->rssi,
2358 pSirWifiScanResult->rtt,
2359 pSirWifiScanResult->rtt_sd);
2360
2361 ap = nla_nest_start(skb, j + 1);
2362 if (!ap)
2363 {
2364 hddLog(VOS_TRACE_LEVEL_ERROR, FL("put fail"));
2365 goto fail;
2366 }
2367
2368 if (nla_put_u64(skb,
2369 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_TIME_STAMP,
2370 pSirWifiScanResult->ts) )
2371 {
2372 hddLog(VOS_TRACE_LEVEL_ERROR, FL("put fail"));
2373 goto fail;
2374 }
2375 if (nla_put(skb,
2376 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_SSID,
2377 sizeof(pSirWifiScanResult->ssid),
2378 pSirWifiScanResult->ssid) )
2379 {
2380 hddLog(VOS_TRACE_LEVEL_ERROR, FL("put fail"));
2381 goto fail;
2382 }
2383 if (nla_put(skb,
2384 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_BSSID,
2385 sizeof(pSirWifiScanResult->bssid),
2386 pSirWifiScanResult->bssid) )
2387 {
2388 hddLog(VOS_TRACE_LEVEL_ERROR, FL("put fail"));
2389 goto fail;
2390 }
2391 if (nla_put_u32(skb,
2392 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_CHANNEL,
2393 pSirWifiScanResult->channel) )
2394 {
2395 hddLog(VOS_TRACE_LEVEL_ERROR, FL("put fail"));
2396 goto fail;
2397 }
2398 if (nla_put_u32(skb,
2399 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_RSSI,
2400 pSirWifiScanResult->rssi) )
2401 {
2402 hddLog(VOS_TRACE_LEVEL_ERROR, FL("put fail"));
2403 goto fail;
2404 }
2405 if (nla_put_u32(skb,
2406 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_RTT,
2407 pSirWifiScanResult->rtt) )
2408 {
2409 hddLog(VOS_TRACE_LEVEL_ERROR, FL("put fail"));
2410 goto fail;
2411 }
2412 if (nla_put_u32(skb,
2413 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_RTT_SD,
2414 pSirWifiScanResult->rtt_sd))
2415 {
2416 hddLog(VOS_TRACE_LEVEL_ERROR, FL("put fail"));
2417 goto fail;
2418 }
2419
2420 nla_nest_end(skb, ap);
2421 }
2422 nla_nest_end(skb, aps);
2423
2424 }
2425 cfg80211_vendor_event(skb, GFP_KERNEL);
2426 } while (totalResults > 0);
2427
2428 return;
2429fail:
2430 kfree_skb(skb);
2431 return;
2432}
2433
2434static void wlan_hdd_cfg80211_extscan_hotlist_match_ind(void *ctx,
2435 void *pMsg)
2436{
2437 tpSirWifiScanResultEvent pData = (tpSirWifiScanResultEvent) pMsg;
2438 hdd_context_t *pHddCtx = (hdd_context_t *)ctx;
2439 struct sk_buff *skb = NULL;
2440 tANI_U32 i;
2441
2442 if (wlan_hdd_validate_context(pHddCtx) || !pData) {
2443 hddLog(VOS_TRACE_LEVEL_ERROR, FL("HDD context is not valid "
2444 "or pData(%p) is null"), pData);
2445 return;
2446 }
2447
2448 skb = cfg80211_vendor_event_alloc(pHddCtx->wiphy,
2449 EXTSCAN_EVENT_BUF_SIZE + NLMSG_HDRLEN,
2450 QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_HOTLIST_AP_FOUND_INDEX,
2451 GFP_KERNEL);
2452
2453 if (!skb) {
2454 hddLog(VOS_TRACE_LEVEL_ERROR,
2455 FL("cfg80211_vendor_event_alloc failed"));
2456 return;
2457 }
2458 hddLog(VOS_TRACE_LEVEL_INFO, FL("Entering "));
2459 hddLog(VOS_TRACE_LEVEL_INFO, "Req Id (%u)", pData->requestId);
2460 hddLog(VOS_TRACE_LEVEL_INFO, "Num results (%u)", pData->numOfAps);
2461 hddLog(VOS_TRACE_LEVEL_INFO, "More Data (%u)", pData->moreData);
2462
2463 for (i = 0; i < pData->numOfAps; i++) {
2464 hddLog(VOS_TRACE_LEVEL_INFO, "[index=%u] Timestamp(0x%lld) "
2465 "Ssid (%s) "
2466 "Bssid (" MAC_ADDRESS_STR ") "
2467 "Channel (%u) "
2468 "Rssi (%d) "
2469 "RTT (%u) "
2470 "RTT_SD (%u) ",
2471 i,
2472 pData->ap[i].ts,
2473 pData->ap[i].ssid,
2474 MAC_ADDR_ARRAY(pData->ap[i].bssid),
2475 pData->ap[i].channel,
2476 pData->ap[i].rssi,
2477 pData->ap[i].rtt,
2478 pData->ap[i].rtt_sd);
2479 }
2480
2481 if (nla_put_u32(skb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_REQUEST_ID,
2482 pData->requestId) ||
2483 nla_put_u32(skb,
2484 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_NUM_RESULTS_AVAILABLE,
2485 pData->numOfAps)) {
2486 hddLog(VOS_TRACE_LEVEL_ERROR, FL("put fail"));
2487 goto fail;
2488 }
2489 if (pData->numOfAps) {
2490 struct nlattr *aps;
2491
2492 aps = nla_nest_start(skb,
2493 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_LIST);
2494 if (!aps)
2495 goto fail;
2496
2497 for (i = 0; i < pData->numOfAps; i++) {
2498 struct nlattr *ap;
2499
2500 ap = nla_nest_start(skb, i + 1);
2501 if (!ap)
2502 goto fail;
2503
2504 if (nla_put_u64(skb,
2505 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_TIME_STAMP,
2506 pData->ap[i].ts) ||
2507 nla_put(skb,
2508 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_SSID,
2509 sizeof(pData->ap[i].ssid),
2510 pData->ap[i].ssid) ||
2511 nla_put(skb,
2512 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_BSSID,
2513 sizeof(pData->ap[i].bssid),
2514 pData->ap[i].bssid) ||
2515 nla_put_u32(skb,
2516 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_CHANNEL,
2517 pData->ap[i].channel) ||
2518 nla_put_s32(skb,
2519 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_RSSI,
2520 pData->ap[i].rssi) ||
2521 nla_put_u32(skb,
2522 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_RTT,
2523 pData->ap[i].rtt) ||
2524 nla_put_u32(skb,
2525 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_RTT_SD,
2526 pData->ap[i].rtt_sd))
2527 goto fail;
2528
2529 nla_nest_end(skb, ap);
2530 }
2531 nla_nest_end(skb, aps);
2532
2533 if (nla_put_u8(skb,
2534 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_MORE_DATA,
2535 pData->moreData))
2536 goto fail;
2537 }
2538
2539 cfg80211_vendor_event(skb, GFP_KERNEL);
2540 return;
2541
2542fail:
2543 kfree_skb(skb);
2544 return;
2545
2546}
2547static void wlan_hdd_cfg80211_extscan_signif_wifi_change_results_ind(void *ctx,
2548 void *pMsg)
2549{
2550 hdd_context_t *pHddCtx = (hdd_context_t *)ctx;
2551 struct sk_buff *skb = NULL;
2552 tANI_U32 i, j;
2553 tpSirWifiSignificantChangeEvent pData =
2554 (tpSirWifiSignificantChangeEvent) pMsg;
2555
2556 if (wlan_hdd_validate_context(pHddCtx) || !pData) {
2557 hddLog(VOS_TRACE_LEVEL_ERROR, FL("HDD context is not valid "
2558 "or pData(%p) is null"), pData);
2559 return;
2560 }
2561 skb = cfg80211_vendor_event_alloc(pHddCtx->wiphy,
2562 EXTSCAN_EVENT_BUF_SIZE,
2563 QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_SIGNIFICANT_CHANGE_INDEX,
2564 GFP_KERNEL);
2565
2566 if (!skb) {
2567 hddLog(VOS_TRACE_LEVEL_ERROR,
2568 FL("cfg80211_vendor_event_alloc failed"));
2569 return;
2570 }
2571 hddLog(VOS_TRACE_LEVEL_INFO, FL("Entering "));
2572 hddLog(VOS_TRACE_LEVEL_INFO, "Req Id (%u)", pData->requestId);
2573 hddLog(VOS_TRACE_LEVEL_INFO, "total List Size %u ", pData->numSigRssiBss);
2574 hddLog(VOS_TRACE_LEVEL_INFO, " CUrrent List size (%u)",
2575 pData->numSigRssiBss);
2576 hddLog(VOS_TRACE_LEVEL_INFO, "moreData (%u)", pData->moreData);
2577
2578 for (i = 0; i < pData->numSigRssiBss; i++) {
2579 hddLog(VOS_TRACE_LEVEL_INFO , "Rssi List [%d] BSSID: (%pM) Channel %u "
2580 " num RSSI %u ",
2581 i, pData->sigRssiResult[i].bssid,
2582 pData->sigRssiResult[i].channel,
2583 pData->sigRssiResult[i].numRssi);
2584
2585 for (j = 0; j < pData->sigRssiResult[i].numRssi; j++){
2586
2587 hddLog(VOS_TRACE_LEVEL_INFO,
2588 " [%d]",
2589 pData->sigRssiResult[i].rssi[0]);
2590
2591 }
2592 }
2593
2594
2595 if (nla_put_u32(skb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_REQUEST_ID,
2596 pData->requestId) ||
2597 nla_put_u32(skb,
2598 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_NUM_RESULTS_AVAILABLE,
2599 pData->numSigRssiBss)) {
2600 hddLog(VOS_TRACE_LEVEL_ERROR, FL("put fail"));
2601 goto fail;
2602 }
2603
2604 if (pData->numSigRssiBss) {
2605 struct nlattr *aps;
2606 aps = nla_nest_start(skb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_LIST);
2607 if (!aps)
2608 goto fail;
2609 for (i = 0; i < pData->numSigRssiBss; i++) {
2610 struct nlattr *ap;
2611
2612 ap = nla_nest_start(skb, i);
2613 if (!ap)
2614 goto fail;
2615 if (nla_put(skb,
2616 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SIGNIFICANT_CHANGE_RESULT_BSSID,
2617 sizeof(tSirMacAddr), pData->sigRssiResult[i].bssid) ||
2618 nla_put_u32(skb,
2619 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SIGNIFICANT_CHANGE_RESULT_CHANNEL,
2620 pData->sigRssiResult[i].channel) ||
2621 nla_put_u32(skb,
2622 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SIGNIFICANT_CHANGE_RESULT_NUM_RSSI,
2623 pData->sigRssiResult[i].numRssi) ||
2624 nla_put(skb,
2625 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SIGNIFICANT_CHANGE_RESULT_RSSI_LIST,
2626 sizeof(s32) * pData->sigRssiResult[i].numRssi,
2627 pData->sigRssiResult[i].rssi))
2628 goto fail;
2629 nla_nest_end(skb, ap);
2630 }
2631 nla_nest_end(skb, aps);
2632 if (nla_put_u8(skb,
2633 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_MORE_DATA,
2634 pData->moreData))
2635 goto fail;
2636 }
2637 cfg80211_vendor_event(skb, GFP_KERNEL);
2638 return;
2639fail:
2640 kfree_skb(skb);
2641 return;
2642}
2643
2644static void wlan_hdd_cfg80211_extscan_full_scan_result_event(void *ctx,
2645 void *pMsg)
2646{
2647 struct sk_buff *skb;
2648 hdd_context_t *pHddCtx = (hdd_context_t *)ctx;
2649 tpSirWifiFullScanResultEvent pData =
2650 (tpSirWifiFullScanResultEvent) (pMsg);
2651
2652 if (wlan_hdd_validate_context(pHddCtx) || !pData) {
2653 hddLog(VOS_TRACE_LEVEL_ERROR, FL("HDD context is not valid "
2654 "or pData(%p) is null"), pData);
2655 return;
2656 }
2657
2658 skb = cfg80211_vendor_event_alloc(pHddCtx->wiphy,
2659 EXTSCAN_EVENT_BUF_SIZE + NLMSG_HDRLEN,
2660 QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_FULL_SCAN_RESULT_INDEX,
2661 GFP_KERNEL);
2662
2663 if (!skb) {
2664 hddLog(VOS_TRACE_LEVEL_ERROR,
2665 FL("cfg80211_vendor_event_alloc failed"));
2666 return;
2667 }
2668
2669 hddLog(VOS_TRACE_LEVEL_INFO, FL("Entering "));
2670 hddLog(VOS_TRACE_LEVEL_INFO, FL("Req Id (%u)"), pData->requestId);
2671 hddLog(VOS_TRACE_LEVEL_INFO, FL("More Data (%u)"), pData->moreData);
2672 hddLog(VOS_TRACE_LEVEL_INFO, FL("AP Info: Timestamp(0x%llX) "
2673 "Ssid (%s)"
2674 "Bssid (" MAC_ADDRESS_STR ")"
2675 "Channel (%u)"
2676 "Rssi (%d)"
2677 "RTT (%u)"
2678 "RTT_SD (%u)"),
2679 pData->ap.ts,
2680 pData->ap.ssid,
2681 MAC_ADDR_ARRAY(pData->ap.bssid),
2682 pData->ap.channel,
2683 pData->ap.rssi,
2684 pData->ap.rtt,
2685 pData->ap.rtt_sd);
2686 hddLog(VOS_TRACE_LEVEL_INFO, "IE Length (%u)", pData->ieLength);
2687 if (nla_put_u32(skb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_REQUEST_ID,
2688 pData->requestId) ||
2689 nla_put_u64(skb,
2690 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_TIME_STAMP,
2691 pData->ap.ts) ||
2692 nla_put(skb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_SSID,
2693 sizeof(pData->ap.ssid),
2694 pData->ap.ssid) ||
2695 nla_put(skb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_BSSID,
2696 WNI_CFG_BSSID_LEN,
2697 pData->ap.bssid) ||
2698 nla_put_u32(skb,
2699 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_CHANNEL,
2700 pData->ap.channel) ||
2701 nla_put_u32(skb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_RSSI,
2702 pData->ap.rssi) ||
2703 nla_put_u32(skb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_RTT,
2704 pData->ap.rtt) ||
2705 nla_put_u32(skb,
2706 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_RTT_SD,
2707 pData->ap.rtt_sd) ||
2708 nla_put_u16(skb,
2709 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_BEACON_PERIOD,
2710 pData->ap.beaconPeriod) ||
2711 nla_put_u16(skb,
2712 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_CAPABILITY,
2713 pData->ap.capability) ||
2714 nla_put_u32(skb,
2715 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_IE_LENGTH,
2716 pData->ieLength))
2717 {
2718 hddLog(VOS_TRACE_LEVEL_ERROR, FL("nla put fail"));
2719 goto nla_put_failure;
2720 }
2721 if (nla_put(skb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_IE_DATA,
2722 pData->ieLength,
2723 pData->ie))
2724 {
2725 hddLog(VOS_TRACE_LEVEL_ERROR, FL("nla put fail"));
2726 goto nla_put_failure;
2727 }
2728
2729 cfg80211_vendor_event(skb, GFP_KERNEL);
2730 return;
2731
2732nla_put_failure:
2733 kfree_skb(skb);
2734 return;
2735}
2736
2737static void wlan_hdd_cfg80211_extscan_scan_res_available_event(void *ctx,
2738 void *pMsg)
2739{
2740 hdd_context_t *pHddCtx = (hdd_context_t *)ctx;
2741 struct sk_buff *skb = NULL;
2742 tpSirEXTScanResultsAvailableIndParams pData =
2743 (tpSirEXTScanResultsAvailableIndParams) pMsg;
2744
2745 if (wlan_hdd_validate_context(pHddCtx) || !pData) {
2746 hddLog(VOS_TRACE_LEVEL_ERROR, FL("HDD context is not valid "
2747 "or pData(%p) is null"), pData);
2748 return;
2749 }
2750
2751 skb = cfg80211_vendor_event_alloc(pHddCtx->wiphy,
2752 EXTSCAN_EVENT_BUF_SIZE + NLMSG_HDRLEN,
2753 QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_SCAN_RESULTS_AVAILABLE_INDEX,
2754 GFP_KERNEL);
2755
2756 if (!skb) {
2757 hddLog(VOS_TRACE_LEVEL_ERROR,
2758 FL("cfg80211_vendor_event_alloc failed"));
2759 return;
2760 }
2761
2762 hddLog(VOS_TRACE_LEVEL_INFO, FL("Entering "));
2763 hddLog(VOS_TRACE_LEVEL_INFO, "Req Id (%u)", pData->requestId);
2764 hddLog(VOS_TRACE_LEVEL_INFO, "Num results (%u)",
2765 pData->numResultsAvailable);
2766 if (nla_put_u32(skb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_REQUEST_ID,
2767 pData->requestId) ||
2768 nla_put_u32(skb,
2769 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_NUM_RESULTS_AVAILABLE,
2770 pData->numResultsAvailable)) {
2771 hddLog(VOS_TRACE_LEVEL_ERROR, FL("nla put fail"));
2772 goto nla_put_failure;
2773 }
2774
2775 cfg80211_vendor_event(skb, GFP_KERNEL);
2776 return;
2777
2778nla_put_failure:
2779 kfree_skb(skb);
2780 return;
2781}
2782
2783static void wlan_hdd_cfg80211_extscan_scan_progress_event(void *ctx, void *pMsg)
2784{
2785 hdd_context_t *pHddCtx = (hdd_context_t *)ctx;
2786 struct sk_buff *skb = NULL;
2787 tpSirEXTScanProgressIndParams pData =
2788 (tpSirEXTScanProgressIndParams) pMsg;
2789
2790 if (wlan_hdd_validate_context(pHddCtx) || !pData) {
2791 hddLog(VOS_TRACE_LEVEL_ERROR, FL("HDD context is not valid "
2792 "or pData(%p) is null"), pData);
2793 return;
2794 }
2795
2796 skb = cfg80211_vendor_event_alloc(pHddCtx->wiphy,
2797 EXTSCAN_EVENT_BUF_SIZE + NLMSG_HDRLEN,
2798 QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_SCAN_EVENT_INDEX,
2799 GFP_KERNEL);
2800
2801 if (!skb) {
2802 hddLog(VOS_TRACE_LEVEL_ERROR,
2803 FL("cfg80211_vendor_event_alloc failed"));
2804 return;
2805 }
2806 hddLog(VOS_TRACE_LEVEL_INFO, FL("Entering "));
2807 hddLog(VOS_TRACE_LEVEL_INFO, "Scan event type (%u)",
2808 pData->extScanEventType);
2809 hddLog(VOS_TRACE_LEVEL_INFO, "Scan event status (%u)",
2810 pData->status);
2811
2812 if (nla_put_u8(skb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_EVENT_TYPE,
2813 pData->extScanEventType) ||
2814 nla_put_u32(skb,
Dasari Srinivas5a288652014-06-30 17:13:22 +05302815 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_REQUEST_ID,
2816 pData->requestId) ||
2817 nla_put_u32(skb,
Dino Mycle6fb96c12014-06-10 11:52:40 +05302818 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_EVENT_STATUS,
2819 pData->status)) {
2820 hddLog(VOS_TRACE_LEVEL_ERROR, FL("nla put fail"));
2821 goto nla_put_failure;
2822 }
2823
2824 cfg80211_vendor_event(skb, GFP_KERNEL);
2825 return;
2826
2827nla_put_failure:
2828 kfree_skb(skb);
2829 return;
2830}
2831
2832void wlan_hdd_cfg80211_extscan_callback(void *ctx, const tANI_U16 evType,
2833 void *pMsg)
2834{
2835 hdd_context_t *pHddCtx = (hdd_context_t *)ctx;
2836
2837 if (wlan_hdd_validate_context(pHddCtx)) {
2838 hddLog(VOS_TRACE_LEVEL_ERROR, FL("HDD context is not valid"));
2839 return;
2840 }
2841
2842 hddLog(VOS_TRACE_LEVEL_INFO, FL("Rcvd Event (%d)"), evType);
2843
2844
2845 switch(evType) {
2846 case SIR_HAL_EXTSCAN_START_RSP:
2847 wlan_hdd_cfg80211_extscan_start_rsp(ctx, pMsg);
2848 break;
2849
2850 case SIR_HAL_EXTSCAN_STOP_RSP:
2851 wlan_hdd_cfg80211_extscan_stop_rsp(ctx, pMsg);
2852 break;
2853 case SIR_HAL_EXTSCAN_GET_CACHED_RESULTS_RSP:
2854 /* There is no need to send this response to upper layer
2855 Just log the message */
2856 hddLog(VOS_TRACE_LEVEL_INFO,
2857 FL("Rcvd SIR_HAL_EXTSCAN_CACHED_RESULTS_RSP"));
2858 break;
2859 case SIR_HAL_EXTSCAN_SET_BSS_HOTLIST_RSP:
2860 wlan_hdd_cfg80211_extscan_set_bss_hotlist_rsp(ctx, pMsg);
2861 break;
2862
2863 case SIR_HAL_EXTSCAN_RESET_BSS_HOTLIST_RSP:
2864 wlan_hdd_cfg80211_extscan_reset_bss_hotlist_rsp(ctx, pMsg);
2865 break;
2866
2867 case SIR_HAL_EXTSCAN_SET_SIGNF_RSSI_CHANGE_RSP:
2868 wlan_hdd_cfg80211_extscan_set_signf_wifi_change_rsp(ctx, pMsg);
2869 break;
2870
2871 case SIR_HAL_EXTSCAN_RESET_SIGNF_RSSI_CHANGE_RSP:
2872 wlan_hdd_cfg80211_extscan_reset_signf_wifi_change_rsp(ctx, pMsg);
2873 break;
2874 case SIR_HAL_EXTSCAN_GET_CAPABILITIES_RSP:
2875 wlan_hdd_cfg80211_extscan_get_capabilities_ind(ctx, pMsg);
2876 break;
2877 case SIR_HAL_EXTSCAN_PROGRESS_IND:
2878 wlan_hdd_cfg80211_extscan_scan_progress_event(ctx, pMsg);
2879 break;
2880 case SIR_HAL_EXTSCAN_SCAN_AVAILABLE_IND:
2881 wlan_hdd_cfg80211_extscan_scan_res_available_event(ctx, pMsg);
2882 break;
2883 case SIR_HAL_EXTSCAN_SCAN_RESULT_IND:
2884 wlan_hdd_cfg80211_extscan_cached_results_ind(ctx, pMsg);
2885 break;
2886 case SIR_HAL_EXTSCAN_HOTLIST_MATCH_IND:
2887 wlan_hdd_cfg80211_extscan_hotlist_match_ind(ctx, pMsg);
2888 break;
2889 case SIR_HAL_EXTSCAN_SIGNF_WIFI_CHANGE_IND:
2890 wlan_hdd_cfg80211_extscan_signif_wifi_change_results_ind(ctx, pMsg);
2891 break;
2892 case SIR_HAL_EXTSCAN_FULL_SCAN_RESULT_IND:
2893 wlan_hdd_cfg80211_extscan_full_scan_result_event(ctx, pMsg);
2894 break;
2895 default:
2896 hddLog(VOS_TRACE_LEVEL_ERROR, FL("invalid event type %d "), evType);
2897 break;
2898 }
2899}
2900
2901static int wlan_hdd_cfg80211_extscan_get_capabilities(struct wiphy *wiphy,
2902 struct wireless_dev *wdev,
2903 void *data, int dataLen)
2904{
Dino Myclee8843b32014-07-04 14:21:45 +05302905 tSirGetEXTScanCapabilitiesReqParams reqMsg;
Dino Mycle6fb96c12014-06-10 11:52:40 +05302906 struct net_device *dev = wdev->netdev;
2907 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
2908 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
2909 struct nlattr
2910 *tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX + 1];
2911 eHalStatus status;
2912
2913 hddLog(VOS_TRACE_LEVEL_INFO, FL("Entering"));
2914 status = wlan_hdd_validate_context(pHddCtx);
2915 if (0 != status)
2916 {
2917 hddLog(VOS_TRACE_LEVEL_ERROR,
2918 FL("HDD context is not valid"));
2919 return -EINVAL;
2920 }
Dino Myclee8843b32014-07-04 14:21:45 +05302921 /* check the EXTScan Capability */
2922 if ( (TRUE != pHddCtx->cfg_ini->fEnableEXTScan) ||
2923 (TRUE != sme_IsFeatureSupportedByFW(EXTENDED_SCAN)))
2924 {
2925 hddLog(VOS_TRACE_LEVEL_ERROR,
2926 FL("EXTScan not enabled/supported by Firmware"));
2927 return -EINVAL;
2928 }
2929
Dino Mycle6fb96c12014-06-10 11:52:40 +05302930 if (nla_parse(tb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX,
2931 data, dataLen,
2932 wlan_hdd_extscan_config_policy)) {
2933 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Invalid ATTR"));
2934 return -EINVAL;
2935 }
2936
2937 /* Parse and fetch request Id */
2938 if (!tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_REQUEST_ID]) {
2939 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr request id failed"));
2940 return -EINVAL;
2941 }
2942
Dino Mycle6fb96c12014-06-10 11:52:40 +05302943
Dino Myclee8843b32014-07-04 14:21:45 +05302944 reqMsg.requestId = nla_get_u32(
Dino Mycle6fb96c12014-06-10 11:52:40 +05302945 tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_REQUEST_ID]);
Dino Myclee8843b32014-07-04 14:21:45 +05302946 hddLog(VOS_TRACE_LEVEL_INFO, FL("Req Id (%d)"), reqMsg.requestId);
Dino Mycle6fb96c12014-06-10 11:52:40 +05302947
Dino Myclee8843b32014-07-04 14:21:45 +05302948 reqMsg.sessionId = pAdapter->sessionId;
2949 hddLog(VOS_TRACE_LEVEL_INFO, FL("Session Id (%d)"), reqMsg.sessionId);
Dino Mycle6fb96c12014-06-10 11:52:40 +05302950
Dino Myclee8843b32014-07-04 14:21:45 +05302951 status = sme_EXTScanGetCapabilities(pHddCtx->hHal, &reqMsg);
Dino Mycle6fb96c12014-06-10 11:52:40 +05302952 if (!HAL_STATUS_SUCCESS(status)) {
2953 hddLog(VOS_TRACE_LEVEL_ERROR,
2954 FL("sme_EXTScanGetCapabilities failed(err=%d)"), status);
Dino Mycle6fb96c12014-06-10 11:52:40 +05302955 return -EINVAL;
2956 }
2957
2958 return 0;
2959}
2960
2961
2962static int wlan_hdd_cfg80211_extscan_get_cached_results(struct wiphy *wiphy,
2963 struct wireless_dev *wdev,
2964 void *data, int dataLen)
2965{
Dino Myclee8843b32014-07-04 14:21:45 +05302966 tSirEXTScanGetCachedResultsReqParams reqMsg;
Dino Mycle6fb96c12014-06-10 11:52:40 +05302967 struct net_device *dev = wdev->netdev;
2968 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
2969 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
2970 struct nlattr
2971 *tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX + 1];
2972 eHalStatus status;
2973
2974 status = wlan_hdd_validate_context(pHddCtx);
2975 if (0 != status)
2976 {
2977 hddLog(VOS_TRACE_LEVEL_ERROR,
2978 FL("HDD context is not valid"));
2979 return -EINVAL;
2980 }
Dino Myclee8843b32014-07-04 14:21:45 +05302981 /* check the EXTScan Capability */
2982 if ( (TRUE != pHddCtx->cfg_ini->fEnableEXTScan) ||
2983 (TRUE != sme_IsFeatureSupportedByFW(EXTENDED_SCAN)))
2984 {
2985 hddLog(VOS_TRACE_LEVEL_ERROR,
2986 FL("EXTScan not enabled/supported by Firmware"));
2987 return -EINVAL;
2988 }
2989
Dino Mycle6fb96c12014-06-10 11:52:40 +05302990 if (nla_parse(tb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX,
2991 data, dataLen,
2992 wlan_hdd_extscan_config_policy)) {
2993 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Invalid ATTR"));
2994 return -EINVAL;
2995 }
2996 /* Parse and fetch request Id */
2997 if (!tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_REQUEST_ID]) {
2998 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr request id failed"));
2999 return -EINVAL;
3000 }
Dino Mycle6fb96c12014-06-10 11:52:40 +05303001
Dino Myclee8843b32014-07-04 14:21:45 +05303002 reqMsg.requestId = nla_get_u32(
Dino Mycle6fb96c12014-06-10 11:52:40 +05303003 tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_REQUEST_ID]);
3004
Dino Myclee8843b32014-07-04 14:21:45 +05303005 hddLog(VOS_TRACE_LEVEL_INFO, FL("Req Id (%d)"), reqMsg.requestId);
Dino Mycle6fb96c12014-06-10 11:52:40 +05303006
Dino Myclee8843b32014-07-04 14:21:45 +05303007 reqMsg.sessionId = pAdapter->sessionId;
3008 hddLog(VOS_TRACE_LEVEL_INFO, FL("Session Id (%d)"), reqMsg.sessionId);
Dino Mycle6fb96c12014-06-10 11:52:40 +05303009
3010 /* Parse and fetch flush parameter */
3011 if (!tb
3012 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_GET_CACHED_SCAN_RESULTS_CONFIG_PARAM_FLUSH])
3013 {
3014 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr flush failed"));
3015 goto failed;
3016 }
Dino Myclee8843b32014-07-04 14:21:45 +05303017 reqMsg.flush = nla_get_u8(
Dino Mycle6fb96c12014-06-10 11:52:40 +05303018 tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_GET_CACHED_SCAN_RESULTS_CONFIG_PARAM_FLUSH]);
3019
Dino Myclee8843b32014-07-04 14:21:45 +05303020 hddLog(VOS_TRACE_LEVEL_INFO, FL("Flush (%d)"), reqMsg.flush);
Dino Mycle6fb96c12014-06-10 11:52:40 +05303021
Dino Myclee8843b32014-07-04 14:21:45 +05303022 status = sme_getCachedResults(pHddCtx->hHal, &reqMsg);
Dino Mycle6fb96c12014-06-10 11:52:40 +05303023 if (!HAL_STATUS_SUCCESS(status)) {
3024 hddLog(VOS_TRACE_LEVEL_ERROR,
3025 FL("sme_getCachedResults failed(err=%d)"), status);
Dino Mycle6fb96c12014-06-10 11:52:40 +05303026 return -EINVAL;
3027 }
3028 return 0;
3029
3030failed:
Dino Mycle6fb96c12014-06-10 11:52:40 +05303031 return -EINVAL;
3032}
3033
3034static int wlan_hdd_cfg80211_extscan_set_bssid_hotlist(struct wiphy *wiphy,
3035 struct wireless_dev *wdev,
3036 void *data, int dataLen)
3037{
3038 tpSirEXTScanSetBssidHotListReqParams pReqMsg = NULL;
3039 struct net_device *dev = wdev->netdev;
3040 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
3041 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
3042 struct nlattr
3043 *tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX + 1];
3044 struct nlattr
3045 *tb2[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX + 1];
3046 struct nlattr *apTh;
3047 eHalStatus status;
3048 tANI_U8 i = 0;
3049 int rem;
3050
3051 status = wlan_hdd_validate_context(pHddCtx);
3052 if (0 != status)
3053 {
3054 hddLog(VOS_TRACE_LEVEL_ERROR,
3055 FL("HDD context is not valid"));
3056 return -EINVAL;
3057 }
Dino Myclee8843b32014-07-04 14:21:45 +05303058 /* check the EXTScan Capability */
3059 if ( (TRUE != pHddCtx->cfg_ini->fEnableEXTScan) ||
3060 (TRUE != sme_IsFeatureSupportedByFW(EXTENDED_SCAN)))
3061 {
3062 hddLog(VOS_TRACE_LEVEL_ERROR,
3063 FL("EXTScan not enabled/supported by Firmware"));
3064 return -EINVAL;
3065 }
3066
Dino Mycle6fb96c12014-06-10 11:52:40 +05303067 if (nla_parse(tb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX,
3068 data, dataLen,
3069 wlan_hdd_extscan_config_policy)) {
3070 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Invalid ATTR"));
3071 return -EINVAL;
3072 }
3073
3074 /* Parse and fetch request Id */
3075 if (!tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_REQUEST_ID]) {
3076 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr request id failed"));
3077 return -EINVAL;
3078 }
Dino Mycle6fb96c12014-06-10 11:52:40 +05303079 pReqMsg = (tpSirEXTScanSetBssidHotListReqParams)
3080 vos_mem_malloc(sizeof(*pReqMsg));
3081 if (!pReqMsg) {
3082 hddLog(VOS_TRACE_LEVEL_ERROR, FL("vos_mem_malloc failed"));
3083 return -ENOMEM;
3084 }
3085
Dino Myclee8843b32014-07-04 14:21:45 +05303086
Dino Mycle6fb96c12014-06-10 11:52:40 +05303087 pReqMsg->requestId = nla_get_u32(
3088 tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_REQUEST_ID]);
3089 hddLog(VOS_TRACE_LEVEL_INFO, FL("Req Id (%d)"), pReqMsg->requestId);
3090
3091 /* Parse and fetch number of APs */
3092 if (!tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_BSSID_HOTLIST_PARAMS_NUM_AP]) {
3093 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr number of AP failed"));
3094 goto fail;
3095 }
3096
3097 pReqMsg->sessionId = pAdapter->sessionId;
3098 hddLog(VOS_TRACE_LEVEL_INFO, FL("Session Id (%d)"), pReqMsg->sessionId);
3099
3100 pReqMsg->numAp = nla_get_u32(
3101 tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_BSSID_HOTLIST_PARAMS_NUM_AP]);
3102 hddLog(VOS_TRACE_LEVEL_INFO, FL("Number of AP (%d)"), pReqMsg->numAp);
3103
3104 nla_for_each_nested(apTh,
3105 tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_AP_THRESHOLD_PARAM], rem) {
3106 if(nla_parse(tb2, QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX,
3107 nla_data(apTh), nla_len(apTh),
3108 NULL)) {
3109 hddLog(VOS_TRACE_LEVEL_ERROR, FL("nla_parse failed"));
3110 goto fail;
3111 }
3112
3113 /* Parse and fetch MAC address */
3114 if (!tb2[QCA_WLAN_VENDOR_ATTR_EXTSCAN_AP_THRESHOLD_PARAM_BSSID]) {
3115 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr mac address failed"));
3116 goto fail;
3117 }
3118 memcpy(pReqMsg->ap[i].bssid, nla_data(
3119 tb2[QCA_WLAN_VENDOR_ATTR_EXTSCAN_AP_THRESHOLD_PARAM_BSSID]),
3120 sizeof(tSirMacAddr));
3121 hddLog(VOS_TRACE_LEVEL_INFO, FL("BSSID: %pM "), pReqMsg->ap[i].bssid);
3122
3123 /* Parse and fetch low RSSI */
3124 if (!tb2[QCA_WLAN_VENDOR_ATTR_EXTSCAN_AP_THRESHOLD_PARAM_RSSI_LOW]) {
3125 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr low RSSI failed"));
3126 goto fail;
3127 }
3128 pReqMsg->ap[i].low = nla_get_s32(
3129 tb2[QCA_WLAN_VENDOR_ATTR_EXTSCAN_AP_THRESHOLD_PARAM_RSSI_LOW]);
3130 hddLog(VOS_TRACE_LEVEL_INFO, FL("RSSI low (%d)"), pReqMsg->ap[i].low);
3131
3132 /* Parse and fetch high RSSI */
3133 if (!tb2[QCA_WLAN_VENDOR_ATTR_EXTSCAN_AP_THRESHOLD_PARAM_RSSI_HIGH]) {
3134 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr high RSSI failed"));
3135 goto fail;
3136 }
3137 pReqMsg->ap[i].high = nla_get_s32(
3138 tb2[QCA_WLAN_VENDOR_ATTR_EXTSCAN_AP_THRESHOLD_PARAM_RSSI_HIGH]);
3139 hddLog(VOS_TRACE_LEVEL_INFO, FL("RSSI High (%d)"),
3140 pReqMsg->ap[i].high);
3141
3142 /* Parse and fetch channel */
3143 if (!tb2[QCA_WLAN_VENDOR_ATTR_EXTSCAN_AP_THRESHOLD_PARAM_CHANNEL]) {
3144 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr channel failed"));
3145 goto fail;
3146 }
3147 pReqMsg->ap[i].channel = nla_get_u32(
3148 tb2[QCA_WLAN_VENDOR_ATTR_EXTSCAN_AP_THRESHOLD_PARAM_CHANNEL]);
3149 hddLog(VOS_TRACE_LEVEL_INFO,
3150 FL("Channel (%u)"), pReqMsg->ap[i].channel);
3151 i++;
3152 }
3153 status = sme_SetBssHotlist(pHddCtx->hHal, pReqMsg);
3154 if (!HAL_STATUS_SUCCESS(status)) {
3155 hddLog(VOS_TRACE_LEVEL_ERROR,
3156 FL("sme_SetBssHotlist failed(err=%d)"), status);
3157 vos_mem_free(pReqMsg);
3158 return -EINVAL;
3159 }
3160
Dino Myclee8843b32014-07-04 14:21:45 +05303161 vos_mem_free(pReqMsg);
3162
Dino Mycle6fb96c12014-06-10 11:52:40 +05303163 return 0;
3164
3165fail:
3166 vos_mem_free(pReqMsg);
3167 return -EINVAL;
3168}
3169
3170static int wlan_hdd_cfg80211_extscan_set_significant_change(struct wiphy *wiphy,
3171 struct wireless_dev *wdev,
3172 void *data, int dataLen)
3173{
3174 tpSirEXTScanSetSignificantChangeReqParams pReqMsg = NULL;
3175 struct net_device *dev = wdev->netdev;
3176 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
3177 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
3178 struct nlattr
3179 *tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX + 1];
3180 struct nlattr
3181 *tb2[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX + 1];
3182 struct nlattr *apTh;
3183 eHalStatus status;
3184 int i = 0;
3185 int rem;
3186
3187 status = wlan_hdd_validate_context(pHddCtx);
3188 if (0 != status)
3189 {
3190 hddLog(VOS_TRACE_LEVEL_ERROR,
3191 FL("HDD context is not valid"));
3192 return -EINVAL;
3193 }
Dino Myclee8843b32014-07-04 14:21:45 +05303194 /* check the EXTScan Capability */
3195 if ( (TRUE != pHddCtx->cfg_ini->fEnableEXTScan) ||
3196 (TRUE != sme_IsFeatureSupportedByFW(EXTENDED_SCAN)))
3197 {
3198 hddLog(VOS_TRACE_LEVEL_ERROR,
3199 FL("EXTScan not enabled/supported by Firmware"));
3200 return -EINVAL;
3201 }
3202
Dino Mycle6fb96c12014-06-10 11:52:40 +05303203 if (nla_parse(tb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX,
3204 data, dataLen,
3205 wlan_hdd_extscan_config_policy)) {
3206 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Invalid ATTR"));
3207 return -EINVAL;
3208 }
3209
3210 /* Parse and fetch request Id */
3211 if (!tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_REQUEST_ID]) {
3212 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr request id failed"));
3213 return -EINVAL;
3214 }
Dino Mycle6fb96c12014-06-10 11:52:40 +05303215 pReqMsg = (tpSirEXTScanSetSignificantChangeReqParams)
Dino Myclee8843b32014-07-04 14:21:45 +05303216 vos_mem_malloc(sizeof(*pReqMsg));
Dino Mycle6fb96c12014-06-10 11:52:40 +05303217 if (!pReqMsg) {
Dino Myclee8843b32014-07-04 14:21:45 +05303218 hddLog(VOS_TRACE_LEVEL_ERROR, FL("vos_mem_malloc failed"));
3219 return -ENOMEM;
Dino Mycle6fb96c12014-06-10 11:52:40 +05303220 }
3221
Dino Myclee8843b32014-07-04 14:21:45 +05303222
3223
Dino Mycle6fb96c12014-06-10 11:52:40 +05303224 pReqMsg->requestId = nla_get_u32(
3225 tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_REQUEST_ID]);
3226 hddLog(VOS_TRACE_LEVEL_INFO, FL("Req Id (%d)"), pReqMsg->requestId);
3227
3228 /* Parse and fetch RSSI sample size */
3229 if (!tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SIGNIFICANT_CHANGE_PARAMS_RSSI_SAMPLE_SIZE])
3230 {
3231 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr RSSI sample size failed"));
3232 goto fail;
3233 }
3234 pReqMsg->rssiSampleSize = nla_get_u32(
3235 tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SIGNIFICANT_CHANGE_PARAMS_RSSI_SAMPLE_SIZE]);
3236 hddLog(VOS_TRACE_LEVEL_INFO,
3237 FL("RSSI sample size (%u)"), pReqMsg->rssiSampleSize);
3238
3239 /* Parse and fetch lost AP sample size */
3240 if (!tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SIGNIFICANT_CHANGE_PARAMS_LOST_AP_SAMPLE_SIZE])
3241 {
3242 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr lost AP sample size failed"));
3243 goto fail;
3244 }
3245 pReqMsg->lostApSampleSize = nla_get_u32(
3246 tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SIGNIFICANT_CHANGE_PARAMS_LOST_AP_SAMPLE_SIZE]);
3247 hddLog(VOS_TRACE_LEVEL_INFO,
3248 FL("Lost AP sample size (%u)"), pReqMsg->lostApSampleSize);
3249 /* Parse and fetch minimum Breaching */
3250 if (!tb
3251 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_SIGNIFICANT_CHANGE_PARAMS_MIN_BREACHING]) {
3252 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr minBreaching failed"));
3253 goto fail;
3254 }
3255 pReqMsg->minBreaching = nla_get_u32(
3256 tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SIGNIFICANT_CHANGE_PARAMS_MIN_BREACHING]);
3257 hddLog(VOS_TRACE_LEVEL_INFO, FL(" Breaching (%d)"), pReqMsg->minBreaching);
3258
3259 /* Parse and fetch number of APs */
3260 if (!tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SIGNIFICANT_CHANGE_PARAMS_NUM_AP]) {
3261 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr number of AP failed"));
3262 goto fail;
3263 }
3264 pReqMsg->numAp = nla_get_u32(
3265 tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SIGNIFICANT_CHANGE_PARAMS_NUM_AP]);
3266 hddLog(VOS_TRACE_LEVEL_INFO, FL("Number of AP (%d)"), pReqMsg->numAp);
3267
3268 pReqMsg->sessionId = pAdapter->sessionId;
3269 hddLog(VOS_TRACE_LEVEL_INFO, FL("Session Id (%d)"), pReqMsg->sessionId);
3270
3271 nla_for_each_nested(apTh,
3272 tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_AP_THRESHOLD_PARAM], rem) {
3273 if(nla_parse(tb2,
3274 QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX,
3275 nla_data(apTh), nla_len(apTh),
3276 NULL)) {
3277 hddLog(VOS_TRACE_LEVEL_ERROR, FL("nla_parse failed"));
3278 goto fail;
3279 }
3280
3281 /* Parse and fetch MAC address */
3282 if (!tb2[QCA_WLAN_VENDOR_ATTR_EXTSCAN_AP_THRESHOLD_PARAM_BSSID]) {
3283 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr mac address failed"));
3284 goto fail;
3285 }
3286 memcpy(pReqMsg->ap[i].bssid, nla_data(
3287 tb2[QCA_WLAN_VENDOR_ATTR_EXTSCAN_AP_THRESHOLD_PARAM_BSSID]),
3288 sizeof(tSirMacAddr));
3289
3290 /* Parse and fetch low RSSI */
3291 if (!tb2[QCA_WLAN_VENDOR_ATTR_EXTSCAN_AP_THRESHOLD_PARAM_RSSI_LOW]) {
3292 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr low RSSI failed"));
3293 goto fail;
3294 }
3295 pReqMsg->ap[i].low = nla_get_s32(
3296 tb2[QCA_WLAN_VENDOR_ATTR_EXTSCAN_AP_THRESHOLD_PARAM_RSSI_LOW]);
3297 hddLog(VOS_TRACE_LEVEL_INFO, FL("RSSI low (%d)"), pReqMsg->ap[i].low);
3298
3299 /* Parse and fetch high RSSI */
3300 if (!tb2[QCA_WLAN_VENDOR_ATTR_EXTSCAN_AP_THRESHOLD_PARAM_RSSI_HIGH]) {
3301 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr high RSSI failed"));
3302 goto fail;
3303 }
3304 pReqMsg->ap[i].high = nla_get_s32(
3305 tb2[QCA_WLAN_VENDOR_ATTR_EXTSCAN_AP_THRESHOLD_PARAM_RSSI_HIGH]);
3306 hddLog(VOS_TRACE_LEVEL_INFO,
3307 FL("RSSI High (%d)"), pReqMsg->ap[i].high);
3308
3309 /* Parse and fetch channel */
3310 if (!tb2[QCA_WLAN_VENDOR_ATTR_EXTSCAN_AP_THRESHOLD_PARAM_CHANNEL]) {
3311 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr channel failed"));
3312 goto fail;
3313 }
3314 pReqMsg->ap[i].channel = nla_get_u32(
3315 tb2[QCA_WLAN_VENDOR_ATTR_EXTSCAN_AP_THRESHOLD_PARAM_CHANNEL]);
3316 hddLog(VOS_TRACE_LEVEL_INFO,
3317 FL("Channel (%u)"), pReqMsg->ap[i].channel);
3318 i++;
3319 }
3320
3321 status = sme_SetSignificantChange(pHddCtx->hHal, pReqMsg);
3322 if (!HAL_STATUS_SUCCESS(status)) {
3323 hddLog(VOS_TRACE_LEVEL_ERROR,
3324 FL("sme_SetSignificantChange failed(err=%d)"), status);
3325 vos_mem_free(pReqMsg);
3326 return -EINVAL;
3327 }
Dino Myclee8843b32014-07-04 14:21:45 +05303328 vos_mem_free(pReqMsg);
Dino Mycle6fb96c12014-06-10 11:52:40 +05303329 hddLog(VOS_TRACE_LEVEL_ERROR, FL(" Exiting"));
3330 return 0;
3331
3332fail:
3333 vos_mem_free(pReqMsg);
3334 return -EINVAL;
3335}
3336
3337static int wlan_hdd_cfg80211_extscan_get_valid_channels(struct wiphy *wiphy,
3338 struct wireless_dev *wdev,
3339 void *data, int dataLen)
3340{
3341 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
3342 tANI_U32 ChannelList[WNI_CFG_VALID_CHANNEL_LIST_LEN] = {0};
3343 tANI_U8 numChannels = 0;
3344 struct nlattr *tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX + 1];
3345 tANI_U32 requestId;
3346 tWifiBand wifiBand;
3347 eHalStatus status;
3348 struct sk_buff *replySkb;
3349 tANI_U8 i;
3350
3351 hddLog(VOS_TRACE_LEVEL_INFO, FL("Entering"));
3352 status = wlan_hdd_validate_context(pHddCtx);
3353 if (0 != status)
3354 {
3355 hddLog(VOS_TRACE_LEVEL_ERROR,
3356 FL("HDD context is not valid"));
3357 return -EINVAL;
3358 }
Dino Myclee8843b32014-07-04 14:21:45 +05303359 /* check the EXTScan Capability */
3360 if ( (TRUE != pHddCtx->cfg_ini->fEnableEXTScan) ||
3361 (TRUE != sme_IsFeatureSupportedByFW(EXTENDED_SCAN)))
3362 {
3363 hddLog(VOS_TRACE_LEVEL_ERROR,
3364 FL("EXTScan not enabled/supported by Firmware"));
3365 return -EINVAL;
3366 }
3367
Dino Mycle6fb96c12014-06-10 11:52:40 +05303368 if (nla_parse(tb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX,
3369 data, dataLen,
3370 wlan_hdd_extscan_config_policy)) {
3371 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Invalid ATTR"));
3372 return -EINVAL;
3373 }
3374
3375 /* Parse and fetch request Id */
3376 if (!tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_REQUEST_ID]) {
3377 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr request id failed"));
3378 return -EINVAL;
3379 }
3380 requestId = nla_get_u32(
3381 tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_REQUEST_ID]);
3382 hddLog(VOS_TRACE_LEVEL_INFO, FL("Req Id (%d)"), requestId);
3383
3384 /* Parse and fetch wifi band */
3385 if (!tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_GET_VALID_CHANNELS_CONFIG_PARAM_WIFI_BAND])
3386 {
3387 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr wifi band failed"));
3388 return -EINVAL;
3389 }
3390 wifiBand = nla_get_u32(
3391 tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_GET_VALID_CHANNELS_CONFIG_PARAM_WIFI_BAND]);
3392 hddLog(VOS_TRACE_LEVEL_INFO, FL("Wifi band (%d)"), wifiBand);
3393
3394 status = sme_GetValidChannelsByBand((tHalHandle)(pHddCtx->hHal),
3395 wifiBand, ChannelList,
3396 &numChannels);
3397 if (eHAL_STATUS_SUCCESS != status) {
3398 hddLog(VOS_TRACE_LEVEL_ERROR,
3399 FL("sme_GetValidChannelsByBand failed (err=%d)"), status);
3400 return -EINVAL;
3401 }
3402 hddLog(VOS_TRACE_LEVEL_INFO, FL("Number of channels (%d)"), numChannels);
3403 for (i = 0; i < numChannels; i++)
3404 hddLog(VOS_TRACE_LEVEL_INFO, "Channel: %u ", ChannelList[i]);
3405
3406 replySkb = cfg80211_vendor_cmd_alloc_reply_skb(wiphy, sizeof(u32) +
3407 sizeof(u32) * numChannels +
3408 NLMSG_HDRLEN);
3409
3410 if (!replySkb) {
3411 hddLog(VOS_TRACE_LEVEL_ERROR,
3412 FL("valid channels: buffer alloc fail"));
3413 return -EINVAL;
3414 }
3415 if (nla_put_u32(replySkb,
3416 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_NUM_CHANNELS,
3417 numChannels) ||
3418 nla_put(replySkb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_CHANNELS,
3419 sizeof(u32) * numChannels, ChannelList)) {
3420
3421 hddLog(VOS_TRACE_LEVEL_ERROR, FL("nla put fail"));
3422 kfree_skb(replySkb);
3423 return -EINVAL;
3424 }
3425
3426 return cfg80211_vendor_cmd_reply(replySkb);
3427}
3428
3429static int wlan_hdd_cfg80211_extscan_start(struct wiphy *wiphy,
3430 struct wireless_dev *wdev,
3431 void *data, int dataLen)
3432{
Dino Myclee8843b32014-07-04 14:21:45 +05303433 tpSirEXTScanStartReqParams pReqMsg = NULL;
Dino Mycle6fb96c12014-06-10 11:52:40 +05303434 struct net_device *dev = wdev->netdev;
3435 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
3436 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
3437 struct nlattr *tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX + 1];
3438 struct nlattr *bucket[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX + 1];
3439 struct nlattr *channel[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX + 1];
3440 struct nlattr *buckets;
3441 struct nlattr *channels;
3442 int rem1;
3443 int rem2;
3444 eHalStatus status;
3445 tANI_U8 bktIndex;
3446 tANI_U32 i = 0, j = 0;
3447
3448 status = wlan_hdd_validate_context(pHddCtx);
3449 if (0 != status)
3450 {
3451 hddLog(VOS_TRACE_LEVEL_ERROR,
3452 FL("HDD context is not valid"));
3453 return -EINVAL;
3454 }
Dino Myclee8843b32014-07-04 14:21:45 +05303455 /* check the EXTScan Capability */
3456 if ( (TRUE != pHddCtx->cfg_ini->fEnableEXTScan) ||
3457 (TRUE != sme_IsFeatureSupportedByFW(EXTENDED_SCAN)))
3458 {
3459 hddLog(VOS_TRACE_LEVEL_ERROR,
3460 FL("EXTScan not enabled/supported by Firmware"));
3461 return -EINVAL;
3462 }
3463
Dino Mycle6fb96c12014-06-10 11:52:40 +05303464 if (nla_parse(tb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX,
3465 data, dataLen,
3466 wlan_hdd_extscan_config_policy)) {
3467 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Invalid ATTR"));
3468 return -EINVAL;
3469 }
3470
3471 /* Parse and fetch request Id */
3472 if (!tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_REQUEST_ID]) {
3473 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr request id failed"));
3474 return -EINVAL;
3475 }
3476
Dino Myclee8843b32014-07-04 14:21:45 +05303477 pReqMsg = (tpSirEXTScanStartReqParams)
3478 vos_mem_malloc(sizeof(*pReqMsg));
Dino Mycle6fb96c12014-06-10 11:52:40 +05303479 if (!pReqMsg) {
Dino Myclee8843b32014-07-04 14:21:45 +05303480 hddLog(VOS_TRACE_LEVEL_ERROR, FL("vos_mem_malloc failed"));
3481 return -ENOMEM;
Dino Mycle6fb96c12014-06-10 11:52:40 +05303482 }
3483
3484 pReqMsg->requestId = nla_get_u32(
3485 tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_REQUEST_ID]);
3486 hddLog(VOS_TRACE_LEVEL_INFO, FL("Req Id (%d)"), pReqMsg->requestId);
3487
3488 pReqMsg->sessionId = pAdapter->sessionId;
3489 hddLog(VOS_TRACE_LEVEL_INFO, FL("Session Id (%d)"), pReqMsg->sessionId);
3490
3491 /* Parse and fetch base period */
3492 if (!tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SCAN_CMD_PARAMS_BASE_PERIOD]) {
3493 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr base period failed"));
3494 goto fail;
3495 }
3496 pReqMsg->basePeriod = nla_get_u32(
3497 tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SCAN_CMD_PARAMS_BASE_PERIOD]);
3498 hddLog(VOS_TRACE_LEVEL_INFO, FL("Base Period (%d)"),
3499 pReqMsg->basePeriod);
3500
3501 /* Parse and fetch max AP per scan */
3502 if (!tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SCAN_CMD_PARAMS_MAX_AP_PER_SCAN]) {
3503 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr max_ap_per_scan failed"));
3504 goto fail;
3505 }
3506 pReqMsg->maxAPperScan = nla_get_u32(
3507 tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SCAN_CMD_PARAMS_MAX_AP_PER_SCAN]);
3508 hddLog(VOS_TRACE_LEVEL_INFO, FL("Max AP per Scan (%d)"),
3509 pReqMsg->maxAPperScan);
3510
3511 /* Parse and fetch report threshold */
3512 if (!tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SCAN_CMD_PARAMS_REPORT_THRESHOLD]) {
3513 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr report_threshold failed"));
3514 goto fail;
3515 }
3516 pReqMsg->reportThreshold = nla_get_u8(
3517 tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SCAN_CMD_PARAMS_REPORT_THRESHOLD]);
3518 hddLog(VOS_TRACE_LEVEL_INFO, FL("Report Threshold (%d)"),
3519 pReqMsg->reportThreshold);
3520
3521 /* Parse and fetch number of buckets */
3522 if (!tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SCAN_CMD_PARAMS_NUM_BUCKETS]) {
3523 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr number of buckets failed"));
3524 goto fail;
3525 }
3526 pReqMsg->numBuckets = nla_get_u8(
3527 tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SCAN_CMD_PARAMS_NUM_BUCKETS]);
3528 if (pReqMsg->numBuckets > WLAN_EXTSCAN_MAX_BUCKETS) {
3529 hddLog(VOS_TRACE_LEVEL_WARN, FL("Exceeded MAX number of buckets "
3530 "Setting numBuckets to %u"), WLAN_EXTSCAN_MAX_BUCKETS);
3531 pReqMsg->numBuckets = WLAN_EXTSCAN_MAX_BUCKETS;
3532 }
3533 hddLog(VOS_TRACE_LEVEL_INFO, FL("Number of Buckets (%d)"),
3534 pReqMsg->numBuckets);
3535 if (!tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC]) {
3536 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr bucket spec failed"));
3537 goto fail;
3538 }
3539
3540 nla_for_each_nested(buckets,
3541 tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC], rem1) {
3542 if(nla_parse(bucket,
3543 QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX,
3544 nla_data(buckets), nla_len(buckets), NULL)) { //policy
3545 hddLog(VOS_TRACE_LEVEL_ERROR, FL("nla_parse failed"));
3546 goto fail;
3547 }
3548
3549 /* Parse and fetch bucket spec */
3550 if (!bucket[QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_INDEX]) {
3551 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr bucket index failed"));
3552 goto fail;
3553 }
3554 bktIndex = nla_get_u8(
3555 bucket[QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_INDEX]);
3556 hddLog(VOS_TRACE_LEVEL_INFO, FL("Bucket spec Index (%d)"), bktIndex);
3557 pReqMsg->buckets[bktIndex].bucket = bktIndex;
3558
3559 /* Parse and fetch wifi band */
3560 if (!bucket[QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_BAND]) {
3561 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr wifi band failed"));
3562 goto fail;
3563 }
3564 pReqMsg->buckets[bktIndex].band = nla_get_u8(
3565 bucket[QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_BAND]);
3566 hddLog(VOS_TRACE_LEVEL_INFO, FL("Wifi band (%d)"),
3567 pReqMsg->buckets[bktIndex].band);
3568
3569 /* Parse and fetch period */
3570 if (!bucket[QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_PERIOD]) {
3571 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr period failed"));
3572 goto fail;
3573 }
3574 pReqMsg->buckets[bktIndex].period = nla_get_u32(
3575 bucket[QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_PERIOD]);
3576 hddLog(VOS_TRACE_LEVEL_INFO, FL("period (%d)"),
3577 pReqMsg->buckets[bktIndex].period);
3578
3579 /* Parse and fetch report events */
3580 if (!bucket[QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_REPORT_EVENTS]) {
3581 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr report events failed"));
3582 goto fail;
3583 }
3584 pReqMsg->buckets[bktIndex].reportEvents = nla_get_u8(
3585 bucket[QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_REPORT_EVENTS]);
3586 hddLog(VOS_TRACE_LEVEL_INFO, FL("report events (%d)"),
3587 pReqMsg->buckets[bktIndex].reportEvents);
3588
3589 /* Parse and fetch number of channels */
3590 if (!bucket[QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_NUM_CHANNEL_SPECS]) {
3591 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr num channels failed"));
3592 goto fail;
3593 }
3594 pReqMsg->buckets[bktIndex].numChannels = nla_get_u32(
3595 bucket[QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_NUM_CHANNEL_SPECS]);
3596 hddLog(VOS_TRACE_LEVEL_INFO, FL("num channels (%d)"),
3597 pReqMsg->buckets[bktIndex].numChannels);
3598
3599 if (!bucket[QCA_WLAN_VENDOR_ATTR_EXTSCAN_CHANNEL_SPEC]) {
3600 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr channel spec failed"));
3601 goto fail;
3602 }
3603
3604 j = 0;
3605 nla_for_each_nested(channels,
3606 bucket[QCA_WLAN_VENDOR_ATTR_EXTSCAN_CHANNEL_SPEC], rem2) {
3607 if(nla_parse(channel,
3608 QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX,
3609 nla_data(channels), nla_len(channels),
3610 NULL)) { //wlan_hdd_extscan_config_policy here
3611 hddLog(VOS_TRACE_LEVEL_ERROR, FL("nla_parse failed"));
3612 goto fail;
3613 }
3614
3615 /* Parse and fetch channel */
3616 if (!channel[QCA_WLAN_VENDOR_ATTR_EXTSCAN_CHANNEL_SPEC_CHANNEL]) {
3617 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr channel failed"));
3618 goto fail;
3619 }
3620 pReqMsg->buckets[bktIndex].channels[j].channel = nla_get_u32(
3621 channel[QCA_WLAN_VENDOR_ATTR_EXTSCAN_CHANNEL_SPEC_CHANNEL]);
3622 hddLog(VOS_TRACE_LEVEL_INFO, FL("channel (%u)"),
3623 pReqMsg->buckets[bktIndex].channels[j].channel);
3624
3625 /* Parse and fetch dwell time */
3626 if (!channel[QCA_WLAN_VENDOR_ATTR_EXTSCAN_CHANNEL_SPEC_DWELL_TIME]) {
3627 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr dwelltime failed"));
3628 goto fail;
3629 }
3630 pReqMsg->buckets[bktIndex].channels[j].dwellTimeMs = nla_get_u32(
3631 channel[QCA_WLAN_VENDOR_ATTR_EXTSCAN_CHANNEL_SPEC_DWELL_TIME]);
3632 hddLog(VOS_TRACE_LEVEL_INFO, FL("Dwell time (%u ms)"),
3633 pReqMsg->buckets[bktIndex].channels[j].dwellTimeMs);
3634
3635 /* Parse and fetch channel spec passive */
3636 if (!channel[QCA_WLAN_VENDOR_ATTR_EXTSCAN_CHANNEL_SPEC_PASSIVE]) {
3637 hddLog(VOS_TRACE_LEVEL_ERROR,
3638 FL("attr channel spec passive failed"));
3639 goto fail;
3640 }
3641 pReqMsg->buckets[bktIndex].channels[j].passive = nla_get_u8(
3642 channel[QCA_WLAN_VENDOR_ATTR_EXTSCAN_CHANNEL_SPEC_PASSIVE]);
3643 hddLog(VOS_TRACE_LEVEL_INFO, FL("Chnl spec passive (%u)"),
3644 pReqMsg->buckets[bktIndex].channels[j].passive);
3645 j++;
3646 }
3647 i++;
3648 }
3649 status = sme_EXTScanStart(pHddCtx->hHal, pReqMsg);
3650 if (!HAL_STATUS_SUCCESS(status)) {
3651 hddLog(VOS_TRACE_LEVEL_ERROR,
3652 FL("sme_EXTScanStart failed(err=%d)"), status);
3653 vos_mem_free(pReqMsg);
3654 return -EINVAL;
3655 }
3656
Dino Myclee8843b32014-07-04 14:21:45 +05303657 vos_mem_free(pReqMsg);
Dino Mycle6fb96c12014-06-10 11:52:40 +05303658 return 0;
3659
3660fail:
3661 vos_mem_free(pReqMsg);
3662 return -EINVAL;
3663}
3664
3665static int wlan_hdd_cfg80211_extscan_stop(struct wiphy *wiphy,
3666 struct wireless_dev *wdev,
3667 void *data, int dataLen)
3668{
Dino Myclee8843b32014-07-04 14:21:45 +05303669 tSirEXTScanStopReqParams reqMsg;
Dino Mycle6fb96c12014-06-10 11:52:40 +05303670 struct net_device *dev = wdev->netdev;
3671 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
3672 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
3673 struct nlattr *tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX + 1];
3674 eHalStatus status;
3675
3676 status = wlan_hdd_validate_context(pHddCtx);
3677 if (0 != status)
3678 {
3679 hddLog(VOS_TRACE_LEVEL_ERROR,
3680 FL("HDD context is not valid"));
3681 return -EINVAL;
3682 }
Dino Myclee8843b32014-07-04 14:21:45 +05303683 /* check the EXTScan Capability */
3684 if ( (TRUE != pHddCtx->cfg_ini->fEnableEXTScan) ||
3685 (TRUE != sme_IsFeatureSupportedByFW(EXTENDED_SCAN)))
3686 {
3687 hddLog(VOS_TRACE_LEVEL_ERROR,
3688 FL("EXTScan not enabled/supported by Firmware"));
3689 return -EINVAL;
3690 }
3691
Dino Mycle6fb96c12014-06-10 11:52:40 +05303692 if (nla_parse(tb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX,
3693 data, dataLen,
3694 wlan_hdd_extscan_config_policy)) {
3695 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Invalid ATTR"));
3696 return -EINVAL;
3697 }
3698
3699 /* Parse and fetch request Id */
3700 if (!tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_REQUEST_ID]) {
3701 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr request id failed"));
3702 return -EINVAL;
3703 }
3704
Dino Myclee8843b32014-07-04 14:21:45 +05303705 reqMsg.requestId = nla_get_u32(
Dino Mycle6fb96c12014-06-10 11:52:40 +05303706 tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_REQUEST_ID]);
Dino Myclee8843b32014-07-04 14:21:45 +05303707 hddLog(VOS_TRACE_LEVEL_INFO, FL("Req Id (%d)"), reqMsg.requestId);
Dino Mycle6fb96c12014-06-10 11:52:40 +05303708
Dino Myclee8843b32014-07-04 14:21:45 +05303709 reqMsg.sessionId = pAdapter->sessionId;
3710 hddLog(VOS_TRACE_LEVEL_INFO, FL("Session Id (%d)"), reqMsg.sessionId);
Dino Mycle6fb96c12014-06-10 11:52:40 +05303711
Dino Myclee8843b32014-07-04 14:21:45 +05303712 status = sme_EXTScanStop(pHddCtx->hHal, &reqMsg);
Dino Mycle6fb96c12014-06-10 11:52:40 +05303713 if (!HAL_STATUS_SUCCESS(status)) {
3714 hddLog(VOS_TRACE_LEVEL_ERROR,
3715 FL("sme_EXTScanStop failed(err=%d)"), status);
Dino Mycle6fb96c12014-06-10 11:52:40 +05303716 return -EINVAL;
3717 }
3718
3719 return 0;
3720}
3721
3722static int wlan_hdd_cfg80211_extscan_reset_bssid_hotlist(struct wiphy *wiphy,
3723 struct wireless_dev *wdev,
3724 void *data, int dataLen)
3725{
Dino Myclee8843b32014-07-04 14:21:45 +05303726 tSirEXTScanResetBssidHotlistReqParams reqMsg;
Dino Mycle6fb96c12014-06-10 11:52:40 +05303727 struct net_device *dev = wdev->netdev;
3728 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
3729 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
3730 struct nlattr *tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX + 1];
3731 eHalStatus status;
3732
3733 status = wlan_hdd_validate_context(pHddCtx);
3734 if (0 != status)
3735 {
3736 hddLog(VOS_TRACE_LEVEL_ERROR,
3737 FL("HDD context is not valid"));
3738 return -EINVAL;
3739 }
Dino Myclee8843b32014-07-04 14:21:45 +05303740 /* check the EXTScan Capability */
3741 if ( (TRUE != pHddCtx->cfg_ini->fEnableEXTScan) ||
3742 (TRUE != sme_IsFeatureSupportedByFW(EXTENDED_SCAN)))
3743 {
3744 hddLog(VOS_TRACE_LEVEL_ERROR,
3745 FL("EXTScan not enabled/supported by Firmware"));
3746 return -EINVAL;
3747 }
3748
Dino Mycle6fb96c12014-06-10 11:52:40 +05303749 if (nla_parse(tb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX,
3750 data, dataLen,
3751 wlan_hdd_extscan_config_policy)) {
3752 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Invalid ATTR"));
3753 return -EINVAL;
3754 }
3755
3756 /* Parse and fetch request Id */
3757 if (!tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_REQUEST_ID]) {
3758 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr request id failed"));
3759 return -EINVAL;
3760 }
3761
Dino Myclee8843b32014-07-04 14:21:45 +05303762 reqMsg.requestId = nla_get_u32(
Dino Mycle6fb96c12014-06-10 11:52:40 +05303763 tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_REQUEST_ID]);
Dino Myclee8843b32014-07-04 14:21:45 +05303764 hddLog(VOS_TRACE_LEVEL_INFO, FL("Req Id (%d)"), reqMsg.requestId);
Dino Mycle6fb96c12014-06-10 11:52:40 +05303765
Dino Myclee8843b32014-07-04 14:21:45 +05303766 reqMsg.sessionId = pAdapter->sessionId;
3767 hddLog(VOS_TRACE_LEVEL_INFO, FL("Session Id (%d)"), reqMsg.sessionId);
Dino Mycle6fb96c12014-06-10 11:52:40 +05303768
Dino Myclee8843b32014-07-04 14:21:45 +05303769 status = sme_ResetBssHotlist(pHddCtx->hHal, &reqMsg);
Dino Mycle6fb96c12014-06-10 11:52:40 +05303770 if (!HAL_STATUS_SUCCESS(status)) {
3771 hddLog(VOS_TRACE_LEVEL_ERROR,
3772 FL("sme_ResetBssHotlist failed(err=%d)"), status);
Dino Mycle6fb96c12014-06-10 11:52:40 +05303773 return -EINVAL;
3774 }
3775
3776 return 0;
3777}
3778
3779static int wlan_hdd_cfg80211_extscan_reset_significant_change(
3780 struct wiphy *wiphy,
3781 struct wireless_dev *wdev,
3782 void *data, int dataLen)
3783{
Dino Myclee8843b32014-07-04 14:21:45 +05303784 tSirEXTScanResetSignificantChangeReqParams reqMsg;
Dino Mycle6fb96c12014-06-10 11:52:40 +05303785 struct net_device *dev = wdev->netdev;
3786 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
3787 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
3788 struct nlattr *tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX + 1];
3789 eHalStatus status;
3790
3791 hddLog(VOS_TRACE_LEVEL_INFO, FL(" Entering"));
3792 status = wlan_hdd_validate_context(pHddCtx);
3793 if (0 != status)
3794 {
3795 hddLog(VOS_TRACE_LEVEL_ERROR,
3796 FL("HDD context is not valid"));
3797 return -EINVAL;
3798 }
Dino Myclee8843b32014-07-04 14:21:45 +05303799 /* check the EXTScan Capability */
3800 if ( (TRUE != pHddCtx->cfg_ini->fEnableEXTScan) ||
3801 (TRUE != sme_IsFeatureSupportedByFW(EXTENDED_SCAN)))
3802 {
3803 hddLog(VOS_TRACE_LEVEL_ERROR,
3804 FL("EXTScan not enabled/supported by Firmware"));
3805 return -EINVAL;
3806 }
3807
Dino Mycle6fb96c12014-06-10 11:52:40 +05303808 if (nla_parse(tb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX,
3809 data, dataLen,
3810 wlan_hdd_extscan_config_policy)) {
3811 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Invalid ATTR"));
3812 return -EINVAL;
3813 }
3814
3815 /* Parse and fetch request Id */
3816 if (!tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_REQUEST_ID]) {
3817 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr request id failed"));
3818 return -EINVAL;
3819 }
3820
Dino Mycle6fb96c12014-06-10 11:52:40 +05303821
Dino Myclee8843b32014-07-04 14:21:45 +05303822 reqMsg.requestId = nla_get_u32(
Dino Mycle6fb96c12014-06-10 11:52:40 +05303823 tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_REQUEST_ID]);
Dino Myclee8843b32014-07-04 14:21:45 +05303824 hddLog(VOS_TRACE_LEVEL_INFO, FL("Req Id (%d)"), reqMsg.requestId);
Dino Mycle6fb96c12014-06-10 11:52:40 +05303825
Dino Myclee8843b32014-07-04 14:21:45 +05303826 reqMsg.sessionId = pAdapter->sessionId;
3827 hddLog(VOS_TRACE_LEVEL_INFO, FL("Session Id (%d)"), reqMsg.sessionId);
Dino Mycle6fb96c12014-06-10 11:52:40 +05303828
Dino Myclee8843b32014-07-04 14:21:45 +05303829 status = sme_ResetSignificantChange(pHddCtx->hHal, &reqMsg);
Dino Mycle6fb96c12014-06-10 11:52:40 +05303830 if (!HAL_STATUS_SUCCESS(status)) {
3831 hddLog(VOS_TRACE_LEVEL_ERROR,
3832 FL("sme_ResetSignificantChange failed(err=%d)"), status);
Dino Mycle6fb96c12014-06-10 11:52:40 +05303833 return -EINVAL;
3834 }
3835
3836 hddLog(VOS_TRACE_LEVEL_ERROR, FL(" Exiting"));
3837 return 0;
3838}
3839
3840#endif /* WLAN_FEATURE_EXTSCAN */
3841
Sunil Duttc69bccb2014-05-26 21:30:20 +05303842const struct wiphy_vendor_command hdd_wiphy_vendor_commands[] =
3843{
3844#ifdef WLAN_FEATURE_LINK_LAYER_STATS
3845 {
3846 .info.vendor_id = QCA_NL80211_VENDOR_ID,
3847 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_LL_STATS_CLR,
3848 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
3849 WIPHY_VENDOR_CMD_NEED_NETDEV |
3850 WIPHY_VENDOR_CMD_NEED_RUNNING,
3851 .doit = wlan_hdd_cfg80211_ll_stats_clear
3852 },
3853
3854 {
3855 .info.vendor_id = QCA_NL80211_VENDOR_ID,
3856 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_LL_STATS_SET,
3857 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
3858 WIPHY_VENDOR_CMD_NEED_NETDEV |
3859 WIPHY_VENDOR_CMD_NEED_RUNNING,
3860 .doit = wlan_hdd_cfg80211_ll_stats_set
3861 },
3862
3863 {
3864 .info.vendor_id = QCA_NL80211_VENDOR_ID,
3865 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_LL_STATS_GET,
3866 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
3867 WIPHY_VENDOR_CMD_NEED_NETDEV |
3868 WIPHY_VENDOR_CMD_NEED_RUNNING,
3869 .doit = wlan_hdd_cfg80211_ll_stats_get
Dino Mycle6fb96c12014-06-10 11:52:40 +05303870 },
Sunil Duttc69bccb2014-05-26 21:30:20 +05303871#endif /* WLAN_FEATURE_LINK_LAYER_STATS */
Dino Mycle6fb96c12014-06-10 11:52:40 +05303872#ifdef WLAN_FEATURE_EXTSCAN
3873 {
3874 .info.vendor_id = QCA_NL80211_VENDOR_ID,
3875 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_START,
3876 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
3877 WIPHY_VENDOR_CMD_NEED_NETDEV |
3878 WIPHY_VENDOR_CMD_NEED_RUNNING,
3879 .doit = wlan_hdd_cfg80211_extscan_start
3880 },
3881 {
3882 .info.vendor_id = QCA_NL80211_VENDOR_ID,
3883 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_STOP,
3884 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
3885 WIPHY_VENDOR_CMD_NEED_NETDEV |
3886 WIPHY_VENDOR_CMD_NEED_RUNNING,
3887 .doit = wlan_hdd_cfg80211_extscan_stop
3888 },
3889 {
3890 .info.vendor_id = QCA_NL80211_VENDOR_ID,
3891 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_GET_VALID_CHANNELS,
3892 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
3893 WIPHY_VENDOR_CMD_NEED_NETDEV,
3894 .doit = wlan_hdd_cfg80211_extscan_get_valid_channels
3895 },
3896 {
3897 .info.vendor_id = QCA_NL80211_VENDOR_ID,
3898 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_GET_CAPABILITIES,
3899 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
3900 WIPHY_VENDOR_CMD_NEED_NETDEV |
3901 WIPHY_VENDOR_CMD_NEED_RUNNING,
3902 .doit = wlan_hdd_cfg80211_extscan_get_capabilities
3903 },
3904 {
3905 .info.vendor_id = QCA_NL80211_VENDOR_ID,
3906 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_GET_CACHED_RESULTS,
3907 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
3908 WIPHY_VENDOR_CMD_NEED_NETDEV |
3909 WIPHY_VENDOR_CMD_NEED_RUNNING,
3910 .doit = wlan_hdd_cfg80211_extscan_get_cached_results
3911 },
3912 {
3913 .info.vendor_id = QCA_NL80211_VENDOR_ID,
3914 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_SET_BSSID_HOTLIST,
3915 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
3916 WIPHY_VENDOR_CMD_NEED_NETDEV |
3917 WIPHY_VENDOR_CMD_NEED_RUNNING,
3918 .doit = wlan_hdd_cfg80211_extscan_set_bssid_hotlist
3919 },
3920 {
3921 .info.vendor_id = QCA_NL80211_VENDOR_ID,
3922 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_RESET_BSSID_HOTLIST,
3923 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
3924 WIPHY_VENDOR_CMD_NEED_NETDEV |
3925 WIPHY_VENDOR_CMD_NEED_RUNNING,
3926 .doit = wlan_hdd_cfg80211_extscan_reset_bssid_hotlist
3927 },
3928 {
3929 .info.vendor_id = QCA_NL80211_VENDOR_ID,
3930 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_SET_SIGNIFICANT_CHANGE,
3931 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
3932 WIPHY_VENDOR_CMD_NEED_NETDEV |
3933 WIPHY_VENDOR_CMD_NEED_RUNNING,
3934 .doit = wlan_hdd_cfg80211_extscan_set_significant_change
3935 },
3936 {
3937 .info.vendor_id = QCA_NL80211_VENDOR_ID,
3938 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_RESET_SIGNIFICANT_CHANGE,
3939 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
3940 WIPHY_VENDOR_CMD_NEED_NETDEV |
3941 WIPHY_VENDOR_CMD_NEED_RUNNING,
3942 .doit = wlan_hdd_cfg80211_extscan_reset_significant_change
3943 },
3944#endif /* WLAN_FEATURE_EXTSCAN */
Sunil Duttc69bccb2014-05-26 21:30:20 +05303945};
3946
Rajesh Chauhan98a31f82014-01-06 20:15:25 -08003947/* vendor specific events */
Sunil Duttc69bccb2014-05-26 21:30:20 +05303948static const
3949struct nl80211_vendor_cmd_info wlan_hdd_cfg80211_vendor_events[] =
Rajesh Chauhan98a31f82014-01-06 20:15:25 -08003950{
3951#ifdef FEATURE_WLAN_CH_AVOID
3952 {
Sunil Duttc69bccb2014-05-26 21:30:20 +05303953 .vendor_id = QCA_NL80211_VENDOR_ID,
3954 .subcmd = QCA_NL80211_VENDOR_SUBCMD_AVOID_FREQUENCY
Rajesh Chauhan98a31f82014-01-06 20:15:25 -08003955 },
Sunil Duttc69bccb2014-05-26 21:30:20 +05303956#endif /* FEATURE_WLAN_CH_AVOID Index = 0*/
3957#ifdef WLAN_FEATURE_LINK_LAYER_STATS
3958 {
3959 /* Index = 1*/
3960 .vendor_id = QCA_NL80211_VENDOR_ID,
3961 .subcmd = QCA_NL80211_VENDOR_SUBCMD_LL_STATS_SET
3962 },
3963 {
3964 /* Index = 2*/
3965 .vendor_id = QCA_NL80211_VENDOR_ID,
3966 .subcmd = QCA_NL80211_VENDOR_SUBCMD_LL_STATS_GET
3967 },
3968 {
3969 /* Index = 3*/
3970 .vendor_id = QCA_NL80211_VENDOR_ID,
3971 .subcmd = QCA_NL80211_VENDOR_SUBCMD_LL_STATS_CLR
3972 },
3973 {
3974 /* Index = 4*/
3975 .vendor_id = QCA_NL80211_VENDOR_ID,
3976 .subcmd = QCA_NL80211_VENDOR_SUBCMD_LL_STATS_RADIO_RESULTS
3977 },
3978 {
3979 /* Index = 5*/
3980 .vendor_id = QCA_NL80211_VENDOR_ID,
3981 .subcmd = QCA_NL80211_VENDOR_SUBCMD_LL_STATS_IFACE_RESULTS
3982 },
3983 {
3984 /* Index = 6*/
3985 .vendor_id = QCA_NL80211_VENDOR_ID,
3986 .subcmd = QCA_NL80211_VENDOR_SUBCMD_LL_STATS_PEERS_RESULTS
3987 },
3988#endif /* WLAN_FEATURE_LINK_LAYER_STATS */
Dino Mycle6fb96c12014-06-10 11:52:40 +05303989#ifdef WLAN_FEATURE_EXTSCAN
3990 {
3991 .vendor_id = QCA_NL80211_VENDOR_ID,
3992 .subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_START
3993 },
3994 {
3995 .vendor_id = QCA_NL80211_VENDOR_ID,
3996 .subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_STOP
3997 },
3998 {
3999 .vendor_id = QCA_NL80211_VENDOR_ID,
4000 .subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_GET_CAPABILITIES
4001 },
4002 {
4003 .vendor_id = QCA_NL80211_VENDOR_ID,
4004 .subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_GET_CACHED_RESULTS
4005 },
4006 {
4007 .vendor_id = QCA_NL80211_VENDOR_ID,
4008 .subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_SCAN_RESULTS_AVAILABLE
4009 },
4010 {
4011 .vendor_id = QCA_NL80211_VENDOR_ID,
4012 .subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_FULL_SCAN_RESULT
4013 },
4014 {
4015 .vendor_id = QCA_NL80211_VENDOR_ID,
4016 .subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_SCAN_EVENT
4017 },
4018 {
4019 .vendor_id = QCA_NL80211_VENDOR_ID,
4020 .subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_HOTLIST_AP_FOUND
4021 },
4022 {
4023 .vendor_id = QCA_NL80211_VENDOR_ID,
4024 .subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_SET_BSSID_HOTLIST
4025 },
4026 {
4027 .vendor_id = QCA_NL80211_VENDOR_ID,
4028 .subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_RESET_BSSID_HOTLIST
4029 },
4030 {
4031 .vendor_id = QCA_NL80211_VENDOR_ID,
4032 .subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_SIGNIFICANT_CHANGE
4033 },
4034 {
4035 .vendor_id = QCA_NL80211_VENDOR_ID,
4036 .subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_SET_SIGNIFICANT_CHANGE
4037 },
4038 {
4039 .vendor_id = QCA_NL80211_VENDOR_ID,
4040 .subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_RESET_SIGNIFICANT_CHANGE
4041 },
4042#endif /* WLAN_FEATURE_EXTSCAN */
Sunil Duttc69bccb2014-05-26 21:30:20 +05304043
Rajesh Chauhan98a31f82014-01-06 20:15:25 -08004044};
4045
Jeff Johnson295189b2012-06-20 16:38:30 -07004046/*
Madan Mohan Koyyalamudi71278262013-04-12 22:00:48 +05304047 * FUNCTION: wlan_hdd_cfg80211_wiphy_alloc
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304048 * This function is called by hdd_wlan_startup()
4049 * during initialization.
Madan Mohan Koyyalamudi71278262013-04-12 22:00:48 +05304050 * This function is used to allocate wiphy structure.
Jeff Johnson295189b2012-06-20 16:38:30 -07004051 */
Madan Mohan Koyyalamudi71278262013-04-12 22:00:48 +05304052struct wiphy *wlan_hdd_cfg80211_wiphy_alloc(int priv_size)
Jeff Johnson295189b2012-06-20 16:38:30 -07004053{
4054 struct wiphy *wiphy;
4055 ENTER();
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304056 /*
4057 * Create wiphy device
Jeff Johnson295189b2012-06-20 16:38:30 -07004058 */
4059 wiphy = wiphy_new(&wlan_hdd_cfg80211_ops, priv_size);
4060
4061 if (!wiphy)
4062 {
4063 /* Print error and jump into err label and free the memory */
4064 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: wiphy init failed", __func__);
4065 return NULL;
4066 }
4067
Sunil Duttc69bccb2014-05-26 21:30:20 +05304068
Jeff Johnson295189b2012-06-20 16:38:30 -07004069 return wiphy;
4070}
4071
4072/*
4073 * FUNCTION: wlan_hdd_cfg80211_update_band
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304074 * This function is called from the supplicant through a
Jeff Johnson295189b2012-06-20 16:38:30 -07004075 * private ioctl to change the band value
4076 */
4077int wlan_hdd_cfg80211_update_band(struct wiphy *wiphy, eCsrBand eBand)
4078{
Gopichand Nakkala1f7a64f2013-04-01 18:37:17 +05304079 int i, j;
4080 eNVChannelEnabledType channelEnabledState;
4081
Jeff Johnsone7245742012-09-05 17:12:55 -07004082 ENTER();
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05304083
Gopichand Nakkala1f7a64f2013-04-01 18:37:17 +05304084 for (i = 0; i < IEEE80211_NUM_BANDS; i++)
Jeff Johnson295189b2012-06-20 16:38:30 -07004085 {
Gopichand Nakkala1f7a64f2013-04-01 18:37:17 +05304086
4087 if (NULL == wiphy->bands[i])
4088 {
4089 hddLog(VOS_TRACE_LEVEL_ERROR,"%s: wiphy->bands[i] is NULL, i = %d",
4090 __func__, i);
4091 continue;
4092 }
4093
4094 for (j = 0; j < wiphy->bands[i]->n_channels; j++)
4095 {
4096 struct ieee80211_supported_band *band = wiphy->bands[i];
4097
4098 channelEnabledState = vos_nv_getChannelEnabledState(
4099 band->channels[j].hw_value);
4100
4101 if (IEEE80211_BAND_2GHZ == i && eCSR_BAND_5G == eBand) // 5G only
4102 {
4103 // Enable Social channels for P2P
4104 if (WLAN_HDD_IS_SOCIAL_CHANNEL(band->channels[j].center_freq) &&
4105 NV_CHANNEL_ENABLE == channelEnabledState)
4106 band->channels[j].flags &= ~IEEE80211_CHAN_DISABLED;
4107 else
4108 band->channels[j].flags |= IEEE80211_CHAN_DISABLED;
4109 continue;
4110 }
4111 else if (IEEE80211_BAND_5GHZ == i && eCSR_BAND_24 == eBand) // 2G only
4112 {
4113 band->channels[j].flags |= IEEE80211_CHAN_DISABLED;
4114 continue;
4115 }
4116
4117 if (NV_CHANNEL_DISABLE == channelEnabledState ||
4118 NV_CHANNEL_INVALID == channelEnabledState)
4119 {
4120 band->channels[j].flags |= IEEE80211_CHAN_DISABLED;
4121 }
4122 else if (NV_CHANNEL_DFS == channelEnabledState)
4123 {
4124 band->channels[j].flags &= ~IEEE80211_CHAN_DISABLED;
4125 band->channels[j].flags |= IEEE80211_CHAN_RADAR;
4126 }
4127 else
4128 {
4129 band->channels[j].flags &= ~(IEEE80211_CHAN_DISABLED
4130 |IEEE80211_CHAN_RADAR);
4131 }
4132 }
Jeff Johnson295189b2012-06-20 16:38:30 -07004133 }
4134 return 0;
4135}
4136/*
4137 * FUNCTION: wlan_hdd_cfg80211_init
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304138 * This function is called by hdd_wlan_startup()
4139 * during initialization.
Jeff Johnson295189b2012-06-20 16:38:30 -07004140 * This function is used to initialize and register wiphy structure.
4141 */
Madan Mohan Koyyalamudi71278262013-04-12 22:00:48 +05304142int wlan_hdd_cfg80211_init(struct device *dev,
Jeff Johnson295189b2012-06-20 16:38:30 -07004143 struct wiphy *wiphy,
4144 hdd_config_t *pCfg
4145 )
4146{
Gopichand Nakkala1f7a64f2013-04-01 18:37:17 +05304147 int i, j;
Vinay Krishna Erannafacf5e22014-02-24 13:16:25 +05304148 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
4149
Jeff Johnsone7245742012-09-05 17:12:55 -07004150 ENTER();
4151
Jeff Johnson295189b2012-06-20 16:38:30 -07004152 /* Now bind the underlying wlan device with wiphy */
4153 set_wiphy_dev(wiphy, dev);
4154
4155 wiphy->mgmt_stypes = wlan_hdd_txrx_stypes;
Amar Singhalfddc28c2013-09-05 13:03:40 -07004156
Kiet Lam6c583332013-10-14 05:37:09 +05304157#ifndef CONFIG_ENABLE_LINUX_REG
Amar Singhal0a402232013-10-11 20:57:16 -07004158 /* the flag for the other case would be initialzed in
4159 vos_init_wiphy_from_nv_bin */
Amar Singhal0a402232013-10-11 20:57:16 -07004160 wiphy->flags |= WIPHY_FLAG_STRICT_REGULATORY;
Kiet Lam6c583332013-10-14 05:37:09 +05304161#endif
Amar Singhala49cbc52013-10-08 18:37:44 -07004162
Amar Singhalfddc28c2013-09-05 13:03:40 -07004163 /* This will disable updating of NL channels from passive to
4164 * active if a beacon is received on passive channel. */
4165 wiphy->flags |= WIPHY_FLAG_DISABLE_BEACON_HINTS;
Amar Singhalf0073192013-09-20 12:34:56 -07004166
Amar Singhalfddc28c2013-09-05 13:03:40 -07004167
Amar Singhala49cbc52013-10-08 18:37:44 -07004168
Jeff Johnson04dd8a82012-06-29 20:41:40 -07004169#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,4,0))
Madan Mohan Koyyalamudi1b4afb02012-10-22 15:25:16 -07004170 wiphy->flags |= WIPHY_FLAG_HAVE_AP_SME
4171 | WIPHY_FLAG_AP_PROBE_RESP_OFFLOAD
4172 | WIPHY_FLAG_HAS_REMAIN_ON_CHANNEL
Jeff Johnsone7245742012-09-05 17:12:55 -07004173 | WIPHY_FLAG_OFFCHAN_TX;
Kiet Lam6c583332013-10-14 05:37:09 +05304174 wiphy->country_ie_pref = NL80211_COUNTRY_IE_IGNORE_CORE;
Jeff Johnson04dd8a82012-06-29 20:41:40 -07004175#endif
Amar Singhala49cbc52013-10-08 18:37:44 -07004176
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08004177#if defined (WLAN_FEATURE_VOWIFI_11R) || defined (FEATURE_WLAN_ESE) || defined(FEATURE_WLAN_LFR)
Srinivas Girigowda640728a2013-03-28 12:21:54 -07004178 if (pCfg->isFastTransitionEnabled
James Zmuda77fb5ae2013-01-29 08:00:17 -08004179#ifdef FEATURE_WLAN_LFR
Srinivas Girigowda640728a2013-03-28 12:21:54 -07004180 || pCfg->isFastRoamIniFeatureEnabled
4181#endif
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08004182#ifdef FEATURE_WLAN_ESE
4183 || pCfg->isEseIniFeatureEnabled
Srinivas Girigowda640728a2013-03-28 12:21:54 -07004184#endif
4185 )
4186 {
4187 wiphy->flags |= WIPHY_FLAG_SUPPORTS_FW_ROAM;
4188 }
James Zmuda77fb5ae2013-01-29 08:00:17 -08004189#endif
Mohit Khanna698ba2a2012-12-04 15:08:18 -08004190#ifdef FEATURE_WLAN_TDLS
4191 wiphy->flags |= WIPHY_FLAG_SUPPORTS_TDLS
4192 | WIPHY_FLAG_TDLS_EXTERNAL_SETUP;
4193#endif
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +05304194#ifdef FEATURE_WLAN_SCAN_PNO
Hardik Kantilal Patel3dfd8792013-11-13 20:34:57 +05304195 if (pCfg->configPNOScanSupport)
4196 {
4197 wiphy->flags |= WIPHY_FLAG_SUPPORTS_SCHED_SCAN;
4198 wiphy->max_sched_scan_ssids = SIR_PNO_MAX_SUPP_NETWORKS;
4199 wiphy->max_match_sets = SIR_PNO_MAX_SUPP_NETWORKS;
4200 wiphy->max_sched_scan_ie_len = SIR_MAC_MAX_IE_LENGTH;
4201 }
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +05304202#endif/*FEATURE_WLAN_SCAN_PNO*/
Mohit Khanna698ba2a2012-12-04 15:08:18 -08004203
Amar Singhalfddc28c2013-09-05 13:03:40 -07004204#ifdef CONFIG_ENABLE_LINUX_REG
Madan Mohan Koyyalamudic3a240c2012-09-28 15:34:08 -07004205 /* even with WIPHY_FLAG_CUSTOM_REGULATORY,
4206 driver can still register regulatory callback and
Amar Singhalfddc28c2013-09-05 13:03:40 -07004207 it will get regulatory settings in wiphy->band[], but
Madan Mohan Koyyalamudic3a240c2012-09-28 15:34:08 -07004208 driver need to determine what to do with both
4209 regulatory settings */
Amar Singhalfddc28c2013-09-05 13:03:40 -07004210
4211 wiphy->reg_notifier = wlan_hdd_linux_reg_notifier;
Amar Singhala49cbc52013-10-08 18:37:44 -07004212#else
4213 wiphy->reg_notifier = wlan_hdd_crda_reg_notifier;
Amar Singhalfddc28c2013-09-05 13:03:40 -07004214#endif
Jeff Johnson04dd8a82012-06-29 20:41:40 -07004215
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304216 wiphy->max_scan_ssids = MAX_SCAN_SSID;
4217
Madan Mohan Koyyalamudi6815b162013-07-19 17:17:46 +05304218 wiphy->max_scan_ie_len = SIR_MAC_MAX_IE_LENGTH;
Jeff Johnson295189b2012-06-20 16:38:30 -07004219
Gopichand Nakkalac005b7c2013-05-14 16:04:14 +05304220 wiphy->max_acl_mac_addrs = MAX_ACL_MAC_ADDRESS;
4221
Jeff Johnson295189b2012-06-20 16:38:30 -07004222 /* Supports STATION & AD-HOC modes right now */
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304223 wiphy->interface_modes = BIT(NL80211_IFTYPE_STATION)
Jeff Johnson295189b2012-06-20 16:38:30 -07004224 | BIT(NL80211_IFTYPE_ADHOC)
Jeff Johnson295189b2012-06-20 16:38:30 -07004225 | BIT(NL80211_IFTYPE_P2P_CLIENT)
4226 | BIT(NL80211_IFTYPE_P2P_GO)
Jeff Johnson295189b2012-06-20 16:38:30 -07004227 | BIT(NL80211_IFTYPE_AP);
4228
Rashmi Ramannabd3feb72014-02-25 16:14:48 +05304229 if( pCfg->advertiseConcurrentOperation )
Sudhir Sattayappa Kohalli278eee52013-01-16 17:35:13 -08004230 {
Rashmi Ramannabd3feb72014-02-25 16:14:48 +05304231#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,4,0))
4232 if( pCfg->enableMCC )
4233 {
4234 /* Currently, supports up to two channels */
4235 wlan_hdd_iface_combination.num_different_channels = 2;
Sudhir Sattayappa Kohalli278eee52013-01-16 17:35:13 -08004236
Rashmi Ramannabd3feb72014-02-25 16:14:48 +05304237 if( !pCfg->allowMCCGODiffBI )
4238 wlan_hdd_iface_combination.beacon_int_infra_match = true;
Sudhir Sattayappa Kohalli278eee52013-01-16 17:35:13 -08004239
Rashmi Ramannabd3feb72014-02-25 16:14:48 +05304240 }
4241 wiphy->iface_combinations = &wlan_hdd_iface_combination;
4242 wiphy->n_iface_combinations = 1;
Sudhir Sattayappa Kohalli278eee52013-01-16 17:35:13 -08004243#endif
Rashmi Ramannabd3feb72014-02-25 16:14:48 +05304244 }
Sudhir Sattayappa Kohalli278eee52013-01-16 17:35:13 -08004245
Jeff Johnson295189b2012-06-20 16:38:30 -07004246 /* Before registering we need to update the ht capabilitied based
4247 * on ini values*/
4248 if( !pCfg->ShortGI20MhzEnable )
4249 {
4250 wlan_hdd_band_2_4_GHZ.ht_cap.cap &= ~IEEE80211_HT_CAP_SGI_20;
4251 wlan_hdd_band_5_GHZ.ht_cap.cap &= ~IEEE80211_HT_CAP_SGI_20;
4252 wlan_hdd_band_p2p_2_4_GHZ.ht_cap.cap &= ~IEEE80211_HT_CAP_SGI_20;
4253 }
4254
4255 if( !pCfg->ShortGI40MhzEnable )
4256 {
4257 wlan_hdd_band_5_GHZ.ht_cap.cap &= ~IEEE80211_HT_CAP_SGI_40;
4258 }
4259
4260 if( !pCfg->nChannelBondingMode5GHz )
4261 {
4262 wlan_hdd_band_5_GHZ.ht_cap.cap &= ~IEEE80211_HT_CAP_SUP_WIDTH_20_40;
4263 }
4264
Gopichand Nakkala1f7a64f2013-04-01 18:37:17 +05304265 wiphy->bands[IEEE80211_BAND_2GHZ] = &wlan_hdd_band_2_4_GHZ;
Vinay Krishna Erannafacf5e22014-02-24 13:16:25 +05304266 if (true == hdd_is_5g_supported(pHddCtx))
4267 {
4268 wiphy->bands[IEEE80211_BAND_5GHZ] = &wlan_hdd_band_5_GHZ;
4269 }
Gopichand Nakkala1f7a64f2013-04-01 18:37:17 +05304270
4271 for (i = 0; i < IEEE80211_NUM_BANDS; i++)
4272 {
4273
4274 if (NULL == wiphy->bands[i])
4275 {
4276 hddLog(VOS_TRACE_LEVEL_ERROR,"%s: wiphy->bands[i] is NULL, i = %d",
4277 __func__, i);
4278 continue;
4279 }
4280
4281 for (j = 0; j < wiphy->bands[i]->n_channels; j++)
4282 {
4283 struct ieee80211_supported_band *band = wiphy->bands[i];
4284
4285 if (IEEE80211_BAND_2GHZ == i && eCSR_BAND_5G == pCfg->nBandCapability) // 5G only
4286 {
4287 // Enable social channels for P2P
4288 if (WLAN_HDD_IS_SOCIAL_CHANNEL(band->channels[j].center_freq))
4289 band->channels[j].flags &= ~IEEE80211_CHAN_DISABLED;
4290 else
4291 band->channels[j].flags |= IEEE80211_CHAN_DISABLED;
4292 continue;
4293 }
4294 else if (IEEE80211_BAND_5GHZ == i && eCSR_BAND_24 == pCfg->nBandCapability) // 2G only
4295 {
4296 band->channels[j].flags |= IEEE80211_CHAN_DISABLED;
4297 continue;
4298 }
4299 }
Jeff Johnson295189b2012-06-20 16:38:30 -07004300 }
4301 /*Initialise the supported cipher suite details*/
4302 wiphy->cipher_suites = hdd_cipher_suites;
4303 wiphy->n_cipher_suites = ARRAY_SIZE(hdd_cipher_suites);
4304
4305 /*signal strength in mBm (100*dBm) */
4306 wiphy->signal_type = CFG80211_SIGNAL_TYPE_MBM;
4307
4308#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
Sushant Kaushik4f640e42014-07-08 12:27:09 +05304309 wiphy->max_remain_on_channel_duration = 5000;
Jeff Johnson295189b2012-06-20 16:38:30 -07004310#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07004311
Sunil Duttc69bccb2014-05-26 21:30:20 +05304312 wiphy->n_vendor_commands = ARRAY_SIZE(hdd_wiphy_vendor_commands);
4313 wiphy->vendor_commands = hdd_wiphy_vendor_commands;
Rajesh Chauhan98a31f82014-01-06 20:15:25 -08004314 wiphy->vendor_events = wlan_hdd_cfg80211_vendor_events;
4315 wiphy->n_vendor_events = ARRAY_SIZE(wlan_hdd_cfg80211_vendor_events);
4316
Madan Mohan Koyyalamudi71278262013-04-12 22:00:48 +05304317 EXIT();
4318 return 0;
4319}
4320
4321/* In this function we are registering wiphy. */
4322int wlan_hdd_cfg80211_register(struct wiphy *wiphy)
4323{
4324 ENTER();
4325 /* Register our wiphy dev with cfg80211 */
Jeff Johnson295189b2012-06-20 16:38:30 -07004326 if (0 > wiphy_register(wiphy))
4327 {
Madan Mohan Koyyalamudi71278262013-04-12 22:00:48 +05304328 /* print error */
Jeff Johnson295189b2012-06-20 16:38:30 -07004329 hddLog(VOS_TRACE_LEVEL_ERROR,"%s: wiphy register failed", __func__);
4330 return -EIO;
4331 }
4332
4333 EXIT();
4334 return 0;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304335}
Jeff Johnson295189b2012-06-20 16:38:30 -07004336
Madan Mohan Koyyalamudi71278262013-04-12 22:00:48 +05304337/* In this function we are updating channel list when,
4338 regulatory domain is FCC and country code is US.
4339 Here In FCC standard 5GHz UNII-1 Bands are indoor only.
4340 As per FCC smart phone is not a indoor device.
4341 GO should not opeate on indoor channels */
4342void wlan_hdd_cfg80211_update_reg_info(struct wiphy *wiphy)
4343{
4344 int j;
4345 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
4346 tANI_U8 defaultCountryCode[3] = SME_INVALID_COUNTRY_CODE;
4347 //Default counrtycode from NV at the time of wiphy initialization.
4348 if (eHAL_STATUS_SUCCESS != sme_GetDefaultCountryCodeFrmNv(pHddCtx->hHal,
4349 &defaultCountryCode[0]))
4350 {
Jeff Johnson0299d0a2013-10-30 12:37:43 -07004351 hddLog(LOGE, FL("Failed to get default country code from NV"));
Madan Mohan Koyyalamudi71278262013-04-12 22:00:48 +05304352 }
4353 if ((defaultCountryCode[0]== 'U') && (defaultCountryCode[1]=='S'))
4354 {
Madan Mohan Koyyalamudi71278262013-04-12 22:00:48 +05304355 if (NULL == wiphy->bands[IEEE80211_BAND_5GHZ])
4356 {
4357 hddLog(VOS_TRACE_LEVEL_ERROR,"%s: wiphy->bands[IEEE80211_BAND_5GHZ] is NULL",__func__ );
4358 return;
4359 }
4360 for (j = 0; j < wiphy->bands[IEEE80211_BAND_5GHZ]->n_channels; j++)
4361 {
4362 struct ieee80211_supported_band *band = wiphy->bands[IEEE80211_BAND_5GHZ];
4363 // Mark UNII -1 band channel as passive
4364 if (WLAN_HDD_CHANNEL_IN_UNII_1_BAND(band->channels[j].center_freq))
4365 band->channels[j].flags |= IEEE80211_CHAN_PASSIVE_SCAN;
4366 }
4367 }
4368}
4369
Agarwal Ashish8fa0e9a2014-05-23 00:40:12 +05304370/* This function registers for all frame which supplicant is interested in */
4371void wlan_hdd_cfg80211_register_frames(hdd_adapter_t* pAdapter)
Jeff Johnson295189b2012-06-20 16:38:30 -07004372{
Jeff Johnson295189b2012-06-20 16:38:30 -07004373 tHalHandle hHal = WLAN_HDD_GET_HAL_CTX(pAdapter);
4374 /* Register for all P2P action, public action etc frames */
4375 v_U16_t type = (SIR_MAC_MGMT_FRAME << 2) | ( SIR_MAC_MGMT_ACTION << 4);
4376
Jeff Johnsone7245742012-09-05 17:12:55 -07004377 ENTER();
4378
Jeff Johnson295189b2012-06-20 16:38:30 -07004379 /* Right now we are registering these frame when driver is getting
4380 initialized. Once we will move to 2.6.37 kernel, in which we have
4381 frame register ops, we will move this code as a part of that */
4382 /* GAS Initial Request */
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304383 sme_RegisterMgmtFrame(hHal, pAdapter->sessionId, type,
Jeff Johnson295189b2012-06-20 16:38:30 -07004384 (v_U8_t*)GAS_INITIAL_REQ, GAS_INITIAL_REQ_SIZE );
4385
4386 /* GAS Initial Response */
4387 sme_RegisterMgmtFrame(hHal, pAdapter->sessionId, type,
4388 (v_U8_t*)GAS_INITIAL_RSP, GAS_INITIAL_RSP_SIZE );
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304389
Jeff Johnson295189b2012-06-20 16:38:30 -07004390 /* GAS Comeback Request */
4391 sme_RegisterMgmtFrame(hHal, pAdapter->sessionId, type,
4392 (v_U8_t*)GAS_COMEBACK_REQ, GAS_COMEBACK_REQ_SIZE );
4393
4394 /* GAS Comeback Response */
4395 sme_RegisterMgmtFrame(hHal, pAdapter->sessionId, type,
4396 (v_U8_t*)GAS_COMEBACK_RSP, GAS_COMEBACK_RSP_SIZE );
4397
4398 /* P2P Public Action */
4399 sme_RegisterMgmtFrame(hHal, pAdapter->sessionId, type,
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304400 (v_U8_t*)P2P_PUBLIC_ACTION_FRAME,
Jeff Johnson295189b2012-06-20 16:38:30 -07004401 P2P_PUBLIC_ACTION_FRAME_SIZE );
4402
4403 /* P2P Action */
4404 sme_RegisterMgmtFrame(hHal, pAdapter->sessionId, type,
4405 (v_U8_t*)P2P_ACTION_FRAME,
4406 P2P_ACTION_FRAME_SIZE );
Chet Lanctot186b5732013-03-18 10:26:30 -07004407
Gopichand Nakkalae3d56e72013-04-21 23:33:32 +05304408 /* WNM BSS Transition Request frame */
4409 sme_RegisterMgmtFrame(hHal, pAdapter->sessionId, type,
4410 (v_U8_t*)WNM_BSS_ACTION_FRAME,
4411 WNM_BSS_ACTION_FRAME_SIZE );
Leela Venkata Kiran Kumar Reddy Chiralae8e62c82013-10-29 18:23:26 -07004412
4413 /* WNM-Notification */
4414 sme_RegisterMgmtFrame(hHal, pAdapter->sessionId, type,
4415 (v_U8_t*)WNM_NOTIFICATION_FRAME,
4416 WNM_NOTIFICATION_FRAME_SIZE );
Jeff Johnson295189b2012-06-20 16:38:30 -07004417}
4418
Agarwal Ashish8fa0e9a2014-05-23 00:40:12 +05304419void wlan_hdd_cfg80211_deregister_frames(hdd_adapter_t* pAdapter)
Jeff Johnson295189b2012-06-20 16:38:30 -07004420{
Jeff Johnson295189b2012-06-20 16:38:30 -07004421 tHalHandle hHal = WLAN_HDD_GET_HAL_CTX(pAdapter);
4422 /* Register for all P2P action, public action etc frames */
4423 v_U16_t type = (SIR_MAC_MGMT_FRAME << 2) | ( SIR_MAC_MGMT_ACTION << 4);
4424
Jeff Johnsone7245742012-09-05 17:12:55 -07004425 ENTER();
4426
Jeff Johnson295189b2012-06-20 16:38:30 -07004427 /* Right now we are registering these frame when driver is getting
4428 initialized. Once we will move to 2.6.37 kernel, in which we have
4429 frame register ops, we will move this code as a part of that */
4430 /* GAS Initial Request */
4431
4432 sme_DeregisterMgmtFrame(hHal, pAdapter->sessionId, type,
4433 (v_U8_t*)GAS_INITIAL_REQ, GAS_INITIAL_REQ_SIZE );
4434
4435 /* GAS Initial Response */
4436 sme_DeregisterMgmtFrame(hHal, pAdapter->sessionId, type,
4437 (v_U8_t*)GAS_INITIAL_RSP, GAS_INITIAL_RSP_SIZE );
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304438
Jeff Johnson295189b2012-06-20 16:38:30 -07004439 /* GAS Comeback Request */
4440 sme_DeregisterMgmtFrame(hHal, pAdapter->sessionId, type,
4441 (v_U8_t*)GAS_COMEBACK_REQ, GAS_COMEBACK_REQ_SIZE );
4442
4443 /* GAS Comeback Response */
4444 sme_DeregisterMgmtFrame(hHal, pAdapter->sessionId, type,
4445 (v_U8_t*)GAS_COMEBACK_RSP, GAS_COMEBACK_RSP_SIZE );
4446
4447 /* P2P Public Action */
4448 sme_DeregisterMgmtFrame(hHal, pAdapter->sessionId, type,
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304449 (v_U8_t*)P2P_PUBLIC_ACTION_FRAME,
Jeff Johnson295189b2012-06-20 16:38:30 -07004450 P2P_PUBLIC_ACTION_FRAME_SIZE );
4451
4452 /* P2P Action */
4453 sme_DeregisterMgmtFrame(hHal, pAdapter->sessionId, type,
4454 (v_U8_t*)P2P_ACTION_FRAME,
4455 P2P_ACTION_FRAME_SIZE );
Leela Venkata Kiran Kumar Reddy Chiralae8e62c82013-10-29 18:23:26 -07004456 /* WNM-Notification */
4457 sme_DeregisterMgmtFrame(hHal, pAdapter->sessionId, type,
4458 (v_U8_t*)WNM_NOTIFICATION_FRAME,
4459 WNM_NOTIFICATION_FRAME_SIZE );
Jeff Johnson295189b2012-06-20 16:38:30 -07004460}
4461
4462#ifdef FEATURE_WLAN_WAPI
4463void wlan_hdd_cfg80211_set_key_wapi(hdd_adapter_t* pAdapter, u8 key_index,
4464 const u8 *mac_addr, u8 *key , int key_Len)
4465{
4466 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
4467 tCsrRoamSetKey setKey;
4468 v_BOOL_t isConnected = TRUE;
4469 int status = 0;
4470 v_U32_t roamId= 0xFF;
4471 tANI_U8 *pKeyPtr = NULL;
4472 int n = 0;
4473
Sushant Kaushik8bc7df22014-04-09 17:55:29 +05304474 hddLog(VOS_TRACE_LEVEL_INFO, "%s: device_mode = %s(%d)",
4475 __func__, hdd_device_modetoString(pAdapter->device_mode),
4476 pAdapter->device_mode);
Jeff Johnson295189b2012-06-20 16:38:30 -07004477
Gopichand Nakkalae7480202013-02-11 15:24:22 +05304478 vos_mem_zero(&setKey, sizeof(tCsrRoamSetKey));
Jeff Johnson295189b2012-06-20 16:38:30 -07004479 setKey.keyId = key_index; // Store Key ID
4480 setKey.encType = eCSR_ENCRYPT_TYPE_WPI; // SET WAPI Encryption
4481 setKey.keyDirection = eSIR_TX_RX; // Key Directionn both TX and RX
4482 setKey.paeRole = 0 ; // the PAE role
4483 if (!mac_addr || is_broadcast_ether_addr(mac_addr))
4484 {
4485 vos_set_macaddr_broadcast( (v_MACADDR_t *)setKey.peerMac );
4486 }
4487 else
4488 {
4489 isConnected = hdd_connIsConnected(pHddStaCtx);
4490 vos_mem_copy(setKey.peerMac,&pHddStaCtx->conn_info.bssId,WNI_CFG_BSSID_LEN);
4491 }
4492 setKey.keyLength = key_Len;
4493 pKeyPtr = setKey.Key;
4494 memcpy( pKeyPtr, key, key_Len);
4495
Arif Hussain6d2a3322013-11-17 19:50:10 -08004496 hddLog(VOS_TRACE_LEVEL_INFO,"%s: WAPI KEY LENGTH:0x%04x",
Jeff Johnson295189b2012-06-20 16:38:30 -07004497 __func__, key_Len);
4498 for (n = 0 ; n < key_Len; n++)
4499 hddLog(VOS_TRACE_LEVEL_INFO, "%s WAPI KEY Data[%d]:%02x ",
4500 __func__,n,setKey.Key[n]);
4501
4502 pHddStaCtx->roam_info.roamingState = HDD_ROAM_STATE_SETTING_KEY;
4503 if ( isConnected )
4504 {
4505 status= sme_RoamSetKey( WLAN_HDD_GET_HAL_CTX(pAdapter),
4506 pAdapter->sessionId, &setKey, &roamId );
4507 }
4508 if ( status != 0 )
4509 {
4510 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
4511 "[%4d] sme_RoamSetKey returned ERROR status= %d",
4512 __LINE__, status );
4513 pHddStaCtx->roam_info.roamingState = HDD_ROAM_STATE_NONE;
4514 }
4515}
4516#endif /* FEATURE_WLAN_WAPI*/
4517
4518#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,4,0))
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304519int wlan_hdd_cfg80211_alloc_new_beacon(hdd_adapter_t *pAdapter,
Jeff Johnson295189b2012-06-20 16:38:30 -07004520 beacon_data_t **ppBeacon,
4521 struct beacon_parameters *params)
Jeff Johnson04dd8a82012-06-29 20:41:40 -07004522#else
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304523int wlan_hdd_cfg80211_alloc_new_beacon(hdd_adapter_t *pAdapter,
Jeff Johnson04dd8a82012-06-29 20:41:40 -07004524 beacon_data_t **ppBeacon,
4525 struct cfg80211_beacon_data *params,
4526 int dtim_period)
4527#endif
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304528{
Jeff Johnson295189b2012-06-20 16:38:30 -07004529 int size;
4530 beacon_data_t *beacon = NULL;
4531 beacon_data_t *old = NULL;
4532 int head_len,tail_len;
4533
Jeff Johnsone7245742012-09-05 17:12:55 -07004534 ENTER();
Jeff Johnson295189b2012-06-20 16:38:30 -07004535 if (params->head && !params->head_len)
c_hpothu6ff1c3c2013-10-01 19:01:57 +05304536 {
4537 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
4538 FL("head_len is NULL"));
Jeff Johnson295189b2012-06-20 16:38:30 -07004539 return -EINVAL;
c_hpothu6ff1c3c2013-10-01 19:01:57 +05304540 }
Jeff Johnson295189b2012-06-20 16:38:30 -07004541
4542 old = pAdapter->sessionCtx.ap.beacon;
4543
4544 if (!params->head && !old)
c_hpothu6ff1c3c2013-10-01 19:01:57 +05304545 {
4546 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
4547 FL("session(%d) old and new heads points to NULL"),
4548 pAdapter->sessionId);
Jeff Johnson295189b2012-06-20 16:38:30 -07004549 return -EINVAL;
c_hpothu6ff1c3c2013-10-01 19:01:57 +05304550 }
4551
4552 if (params->tail && !params->tail_len)
4553 {
4554 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
4555 FL("tail_len is zero but tail is not NULL"));
4556 return -EINVAL;
4557 }
Jeff Johnson295189b2012-06-20 16:38:30 -07004558
Jeff Johnson295189b2012-06-20 16:38:30 -07004559#if (LINUX_VERSION_CODE <= KERNEL_VERSION(2,6,38))
4560 /* Kernel 3.0 is not updating dtim_period for set beacon */
4561 if (!params->dtim_period)
c_hpothu6ff1c3c2013-10-01 19:01:57 +05304562 {
4563 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
4564 FL("dtim period is 0"));
Jeff Johnson295189b2012-06-20 16:38:30 -07004565 return -EINVAL;
c_hpothu6ff1c3c2013-10-01 19:01:57 +05304566 }
Jeff Johnson295189b2012-06-20 16:38:30 -07004567#endif
4568
4569 if(params->head)
4570 head_len = params->head_len;
4571 else
4572 head_len = old->head_len;
4573
4574 if(params->tail || !old)
4575 tail_len = params->tail_len;
4576 else
4577 tail_len = old->tail_len;
4578
4579 size = sizeof(beacon_data_t) + head_len + tail_len;
4580
4581 beacon = kzalloc(size, GFP_KERNEL);
4582
4583 if( beacon == NULL )
c_hpothu6ff1c3c2013-10-01 19:01:57 +05304584 {
4585 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
4586 FL("Mem allocation for beacon failed"));
Jeff Johnson295189b2012-06-20 16:38:30 -07004587 return -ENOMEM;
c_hpothu6ff1c3c2013-10-01 19:01:57 +05304588 }
Jeff Johnson295189b2012-06-20 16:38:30 -07004589
Jeff Johnson04dd8a82012-06-29 20:41:40 -07004590#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,4,0))
Jeff Johnson295189b2012-06-20 16:38:30 -07004591 if(params->dtim_period || !old )
4592 beacon->dtim_period = params->dtim_period;
4593 else
4594 beacon->dtim_period = old->dtim_period;
Jeff Johnson04dd8a82012-06-29 20:41:40 -07004595#else
4596 if(dtim_period || !old )
4597 beacon->dtim_period = dtim_period;
4598 else
4599 beacon->dtim_period = old->dtim_period;
4600#endif
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304601
Jeff Johnson295189b2012-06-20 16:38:30 -07004602 beacon->head = ((u8 *) beacon) + sizeof(beacon_data_t);
4603 beacon->tail = beacon->head + head_len;
4604 beacon->head_len = head_len;
4605 beacon->tail_len = tail_len;
4606
4607 if(params->head) {
4608 memcpy (beacon->head,params->head,beacon->head_len);
4609 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304610 else {
Jeff Johnson295189b2012-06-20 16:38:30 -07004611 if(old)
4612 memcpy (beacon->head,old->head,beacon->head_len);
4613 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304614
Jeff Johnson295189b2012-06-20 16:38:30 -07004615 if(params->tail) {
4616 memcpy (beacon->tail,params->tail,beacon->tail_len);
4617 }
4618 else {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304619 if(old)
Jeff Johnson295189b2012-06-20 16:38:30 -07004620 memcpy (beacon->tail,old->tail,beacon->tail_len);
4621 }
4622
4623 *ppBeacon = beacon;
4624
4625 kfree(old);
4626
4627 return 0;
4628
4629}
Jeff Johnson295189b2012-06-20 16:38:30 -07004630
4631v_U8_t* wlan_hdd_cfg80211_get_ie_ptr(v_U8_t *pIes, int length, v_U8_t eid)
4632{
4633 int left = length;
4634 v_U8_t *ptr = pIes;
4635 v_U8_t elem_id,elem_len;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304636
Jeff Johnson295189b2012-06-20 16:38:30 -07004637 while(left >= 2)
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304638 {
Jeff Johnson295189b2012-06-20 16:38:30 -07004639 elem_id = ptr[0];
4640 elem_len = ptr[1];
4641 left -= 2;
4642 if(elem_len > left)
4643 {
4644 hddLog(VOS_TRACE_LEVEL_FATAL,
Madan Mohan Koyyalamudi8bdd3112012-09-24 13:55:14 -07004645 FL("****Invalid IEs eid = %d elem_len=%d left=%d*****"),
Jeff Johnson295189b2012-06-20 16:38:30 -07004646 eid,elem_len,left);
4647 return NULL;
4648 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304649 if (elem_id == eid)
Jeff Johnson295189b2012-06-20 16:38:30 -07004650 {
4651 return ptr;
4652 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304653
Jeff Johnson295189b2012-06-20 16:38:30 -07004654 left -= elem_len;
4655 ptr += (elem_len + 2);
4656 }
4657 return NULL;
4658}
4659
Jeff Johnson295189b2012-06-20 16:38:30 -07004660/* Check if rate is 11g rate or not */
4661static int wlan_hdd_rate_is_11g(u8 rate)
4662{
Sanjay Devnani28322e22013-06-21 16:13:40 -07004663 static const u8 gRateArray[8] = {12, 18, 24, 36, 48, 72, 96, 108}; /* actual rate * 2 */
Jeff Johnson295189b2012-06-20 16:38:30 -07004664 u8 i;
4665 for (i = 0; i < 8; i++)
4666 {
4667 if(rate == gRateArray[i])
4668 return TRUE;
4669 }
4670 return FALSE;
4671}
4672
4673/* Check for 11g rate and set proper 11g only mode */
4674static void wlan_hdd_check_11gmode(u8 *pIe, u8* require_ht,
4675 u8* pCheckRatesfor11g, eSapPhyMode* pSapHw_mode)
4676{
4677 u8 i, num_rates = pIe[0];
4678
4679 pIe += 1;
4680 for ( i = 0; i < num_rates; i++)
4681 {
4682 if( *pCheckRatesfor11g && (TRUE == wlan_hdd_rate_is_11g(pIe[i] & RATE_MASK)))
4683 {
4684 /* If rate set have 11g rate than change the mode to 11G */
4685 *pSapHw_mode = eSAP_DOT11_MODE_11g;
4686 if (pIe[i] & BASIC_RATE_MASK)
4687 {
4688 /* If we have 11g rate as basic rate, it means mode
4689 is 11g only mode.
4690 */
4691 *pSapHw_mode = eSAP_DOT11_MODE_11g_ONLY;
4692 *pCheckRatesfor11g = FALSE;
4693 }
4694 }
4695 else if((BASIC_RATE_MASK | WLAN_BSS_MEMBERSHIP_SELECTOR_HT_PHY) == pIe[i])
4696 {
4697 *require_ht = TRUE;
4698 }
4699 }
4700 return;
4701}
4702
4703static void wlan_hdd_set_sapHwmode(hdd_adapter_t *pHostapdAdapter)
4704{
4705 tsap_Config_t *pConfig = &pHostapdAdapter->sessionCtx.ap.sapConfig;
4706 beacon_data_t *pBeacon = pHostapdAdapter->sessionCtx.ap.beacon;
4707 struct ieee80211_mgmt *pMgmt_frame = (struct ieee80211_mgmt*)pBeacon->head;
4708 u8 checkRatesfor11g = TRUE;
4709 u8 require_ht = FALSE;
4710 u8 *pIe=NULL;
4711
4712 pConfig->SapHw_mode= eSAP_DOT11_MODE_11b;
4713
4714 pIe = wlan_hdd_cfg80211_get_ie_ptr(&pMgmt_frame->u.beacon.variable[0],
4715 pBeacon->head_len, WLAN_EID_SUPP_RATES);
4716 if (pIe != NULL)
4717 {
4718 pIe += 1;
4719 wlan_hdd_check_11gmode(pIe, &require_ht, &checkRatesfor11g,
4720 &pConfig->SapHw_mode);
4721 }
4722
4723 pIe = wlan_hdd_cfg80211_get_ie_ptr(pBeacon->tail, pBeacon->tail_len,
4724 WLAN_EID_EXT_SUPP_RATES);
4725 if (pIe != NULL)
4726 {
4727
4728 pIe += 1;
4729 wlan_hdd_check_11gmode(pIe, &require_ht, &checkRatesfor11g,
4730 &pConfig->SapHw_mode);
4731 }
4732
4733 if( pConfig->channel > 14 )
4734 {
4735 pConfig->SapHw_mode= eSAP_DOT11_MODE_11a;
4736 }
4737
4738 pIe = wlan_hdd_cfg80211_get_ie_ptr(pBeacon->tail, pBeacon->tail_len,
4739 WLAN_EID_HT_CAPABILITY);
4740
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304741 if(pIe)
Jeff Johnson295189b2012-06-20 16:38:30 -07004742 {
4743 pConfig->SapHw_mode= eSAP_DOT11_MODE_11n;
4744 if(require_ht)
4745 pConfig->SapHw_mode= eSAP_DOT11_MODE_11n_ONLY;
4746 }
4747}
4748
Gopichand Nakkala2b25f4e2013-03-21 19:14:07 +05304749static int wlan_hdd_add_ie(hdd_adapter_t* pHostapdAdapter, v_U8_t *genie,
4750 v_U8_t *total_ielen, v_U8_t *oui, v_U8_t oui_size)
4751{
Arif Hussaine7f3ea52013-09-12 21:56:36 -07004752 v_U16_t ielen = 0;
Gopichand Nakkala2b25f4e2013-03-21 19:14:07 +05304753 v_U8_t *pIe = NULL;
4754 beacon_data_t *pBeacon = pHostapdAdapter->sessionCtx.ap.beacon;
4755
4756 pIe = wlan_hdd_get_vendor_oui_ie_ptr(oui, oui_size,
4757 pBeacon->tail, pBeacon->tail_len);
4758
4759 if (pIe)
4760 {
4761 ielen = pIe[1] + 2;
4762 if ((*total_ielen + ielen) <= MAX_GENIE_LEN)
4763 {
4764 vos_mem_copy(&genie[*total_ielen], pIe, ielen);
4765 }
4766 else
4767 {
4768 hddLog( VOS_TRACE_LEVEL_ERROR, "**Ie Length is too big***");
4769 return -EINVAL;
4770 }
4771 *total_ielen += ielen;
4772 }
4773 return 0;
4774}
4775
Arif Hussaine7f3ea52013-09-12 21:56:36 -07004776static void wlan_hdd_add_hostapd_conf_vsie(hdd_adapter_t* pHostapdAdapter,
4777 v_U8_t *genie, v_U8_t *total_ielen)
4778{
4779 beacon_data_t *pBeacon = pHostapdAdapter->sessionCtx.ap.beacon;
4780 int left = pBeacon->tail_len;
4781 v_U8_t *ptr = pBeacon->tail;
4782 v_U8_t elem_id, elem_len;
4783 v_U16_t ielen = 0;
4784
4785 if ( NULL == ptr || 0 == left )
4786 return;
4787
4788 while (left >= 2)
4789 {
4790 elem_id = ptr[0];
4791 elem_len = ptr[1];
4792 left -= 2;
4793 if (elem_len > left)
4794 {
4795 hddLog( VOS_TRACE_LEVEL_ERROR,
4796 "****Invalid IEs eid = %d elem_len=%d left=%d*****",
4797 elem_id, elem_len, left);
4798 return;
4799 }
4800 if (IE_EID_VENDOR == elem_id)
4801 {
4802 /* skipping the VSIE's which we don't want to include or
4803 * it will be included by existing code
4804 */
4805 if ((memcmp( &ptr[2], WPS_OUI_TYPE, WPS_OUI_TYPE_SIZE) != 0 ) &&
4806#ifdef WLAN_FEATURE_WFD
4807 (memcmp( &ptr[2], WFD_OUI_TYPE, WFD_OUI_TYPE_SIZE) != 0) &&
4808#endif
4809 (memcmp( &ptr[2], WHITELIST_OUI_TYPE, WPA_OUI_TYPE_SIZE) != 0) &&
4810 (memcmp( &ptr[2], BLACKLIST_OUI_TYPE, WPA_OUI_TYPE_SIZE) != 0) &&
4811 (memcmp( &ptr[2], "\x00\x50\xf2\x02", WPA_OUI_TYPE_SIZE) != 0) &&
4812 (memcmp( &ptr[2], WPA_OUI_TYPE, WPA_OUI_TYPE_SIZE) != 0) &&
4813 (memcmp( &ptr[2], P2P_OUI_TYPE, P2P_OUI_TYPE_SIZE) != 0))
4814 {
4815 ielen = ptr[1] + 2;
4816 if ((*total_ielen + ielen) <= MAX_GENIE_LEN)
4817 {
4818 vos_mem_copy(&genie[*total_ielen], ptr, ielen);
4819 *total_ielen += ielen;
4820 }
4821 else
4822 {
4823 hddLog( VOS_TRACE_LEVEL_ERROR,
4824 "IE Length is too big "
4825 "IEs eid=%d elem_len=%d total_ie_lent=%d",
4826 elem_id, elem_len, *total_ielen);
4827 }
4828 }
4829 }
4830
4831 left -= elem_len;
4832 ptr += (elem_len + 2);
4833 }
4834 return;
4835}
4836
Jeff Johnson04dd8a82012-06-29 20:41:40 -07004837#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,4,0))
Jeff Johnson295189b2012-06-20 16:38:30 -07004838static int wlan_hdd_cfg80211_update_apies(hdd_adapter_t* pHostapdAdapter,
4839 struct beacon_parameters *params)
Jeff Johnson04dd8a82012-06-29 20:41:40 -07004840#else
4841static int wlan_hdd_cfg80211_update_apies(hdd_adapter_t* pHostapdAdapter,
4842 struct cfg80211_beacon_data *params)
4843#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07004844{
4845 v_U8_t *genie;
Gopichand Nakkala2b25f4e2013-03-21 19:14:07 +05304846 v_U8_t total_ielen = 0;
Jeff Johnson295189b2012-06-20 16:38:30 -07004847 v_U8_t addIE[1] = {0};
Jeff Johnsone7245742012-09-05 17:12:55 -07004848 int ret = 0;
Jeff Johnson295189b2012-06-20 16:38:30 -07004849
4850 genie = vos_mem_malloc(MAX_GENIE_LEN);
4851
4852 if(genie == NULL) {
4853
4854 return -ENOMEM;
4855 }
4856
Gopichand Nakkala2b25f4e2013-03-21 19:14:07 +05304857 if (0 != wlan_hdd_add_ie(pHostapdAdapter, genie,
4858 &total_ielen, WPS_OUI_TYPE, WPS_OUI_TYPE_SIZE))
Jeff Johnson295189b2012-06-20 16:38:30 -07004859 {
c_hpothu6ff1c3c2013-10-01 19:01:57 +05304860 hddLog(LOGE,
4861 FL("Adding WPS IE failed"));
Gopichand Nakkala2b25f4e2013-03-21 19:14:07 +05304862 ret = -EINVAL;
4863 goto done;
Jeff Johnson295189b2012-06-20 16:38:30 -07004864 }
4865
4866#ifdef WLAN_FEATURE_WFD
Gopichand Nakkala2b25f4e2013-03-21 19:14:07 +05304867 if (0 != wlan_hdd_add_ie(pHostapdAdapter, genie,
4868 &total_ielen, WFD_OUI_TYPE, WFD_OUI_TYPE_SIZE))
4869 {
c_hpothu6ff1c3c2013-10-01 19:01:57 +05304870 hddLog(LOGE,
4871 FL("Adding WFD IE failed"));
Gopichand Nakkala2b25f4e2013-03-21 19:14:07 +05304872 ret = -EINVAL;
4873 goto done;
Jeff Johnson295189b2012-06-20 16:38:30 -07004874 }
4875#endif
4876
Gopichand Nakkala2b25f4e2013-03-21 19:14:07 +05304877 if (0 != wlan_hdd_add_ie(pHostapdAdapter, genie,
4878 &total_ielen, P2P_OUI_TYPE, P2P_OUI_TYPE_SIZE))
Jeff Johnson295189b2012-06-20 16:38:30 -07004879 {
c_hpothu6ff1c3c2013-10-01 19:01:57 +05304880 hddLog(LOGE,
4881 FL("Adding P2P IE failed"));
Gopichand Nakkala2b25f4e2013-03-21 19:14:07 +05304882 ret = -EINVAL;
4883 goto done;
4884 }
4885
4886 if (WLAN_HDD_SOFTAP == pHostapdAdapter->device_mode)
4887 {
Arif Hussaine7f3ea52013-09-12 21:56:36 -07004888 wlan_hdd_add_hostapd_conf_vsie(pHostapdAdapter, genie, &total_ielen);
Jeff Johnson295189b2012-06-20 16:38:30 -07004889 }
Jeff Johnson295189b2012-06-20 16:38:30 -07004890
4891 if (ccmCfgSetStr((WLAN_HDD_GET_CTX(pHostapdAdapter))->hHal,
4892 WNI_CFG_PROBE_RSP_BCN_ADDNIE_DATA, genie, total_ielen, NULL,
4893 eANI_BOOLEAN_FALSE)==eHAL_STATUS_FAILURE)
4894 {
4895 hddLog(LOGE,
4896 "Could not pass on WNI_CFG_PROBE_RSP_BCN_ADDNIE_DATA to CCM");
Jeff Johnsone7245742012-09-05 17:12:55 -07004897 ret = -EINVAL;
4898 goto done;
Jeff Johnson295189b2012-06-20 16:38:30 -07004899 }
4900
4901 if (ccmCfgSetInt((WLAN_HDD_GET_CTX(pHostapdAdapter))->hHal,
4902 WNI_CFG_PROBE_RSP_BCN_ADDNIE_FLAG, 1,NULL,
4903 test_bit(SOFTAP_BSS_STARTED, &pHostapdAdapter->event_flags) ?
4904 eANI_BOOLEAN_TRUE : eANI_BOOLEAN_FALSE)
4905 ==eHAL_STATUS_FAILURE)
4906 {
4907 hddLog(LOGE,
4908 "Could not pass on WNI_CFG_PROBE_RSP_BCN_ADDNIE_FLAG to CCM");
Jeff Johnsone7245742012-09-05 17:12:55 -07004909 ret = -EINVAL;
4910 goto done;
Jeff Johnson295189b2012-06-20 16:38:30 -07004911 }
4912
4913 // Added for ProResp IE
4914 if ( (params->proberesp_ies != NULL) && (params->proberesp_ies_len != 0) )
4915 {
4916 u16 rem_probe_resp_ie_len = params->proberesp_ies_len;
4917 u8 probe_rsp_ie_len[3] = {0};
4918 u8 counter = 0;
4919 /* Check Probe Resp Length if it is greater then 255 then Store
4920 Probe Resp IEs into WNI_CFG_PROBE_RSP_ADDNIE_DATA1 &
4921 WNI_CFG_PROBE_RSP_ADDNIE_DATA2 CFG Variable As We are not able
4922 Store More then 255 bytes into One Variable.
4923 */
4924 while ((rem_probe_resp_ie_len > 0) && (counter < 3))
4925 {
4926 if (rem_probe_resp_ie_len > MAX_CFG_STRING_LEN)
4927 {
4928 probe_rsp_ie_len[counter++] = MAX_CFG_STRING_LEN;
4929 rem_probe_resp_ie_len -= MAX_CFG_STRING_LEN;
4930 }
4931 else
4932 {
4933 probe_rsp_ie_len[counter++] = rem_probe_resp_ie_len;
4934 rem_probe_resp_ie_len = 0;
4935 }
4936 }
4937
4938 rem_probe_resp_ie_len = 0;
4939
4940 if (probe_rsp_ie_len[0] > 0)
4941 {
4942 if (ccmCfgSetStr((WLAN_HDD_GET_CTX(pHostapdAdapter))->hHal,
4943 WNI_CFG_PROBE_RSP_ADDNIE_DATA1,
4944 (tANI_U8*)&params->proberesp_ies[rem_probe_resp_ie_len],
4945 probe_rsp_ie_len[0], NULL,
4946 eANI_BOOLEAN_FALSE) == eHAL_STATUS_FAILURE)
4947 {
4948 hddLog(LOGE,
4949 "Could not pass on WNI_CFG_PROBE_RSP_ADDNIE_DATA1 to CCM");
Jeff Johnsone7245742012-09-05 17:12:55 -07004950 ret = -EINVAL;
4951 goto done;
Jeff Johnson295189b2012-06-20 16:38:30 -07004952 }
4953 rem_probe_resp_ie_len += probe_rsp_ie_len[0];
4954 }
4955
4956 if (probe_rsp_ie_len[1] > 0)
4957 {
4958 if (ccmCfgSetStr((WLAN_HDD_GET_CTX(pHostapdAdapter))->hHal,
4959 WNI_CFG_PROBE_RSP_ADDNIE_DATA2,
4960 (tANI_U8*)&params->proberesp_ies[rem_probe_resp_ie_len],
4961 probe_rsp_ie_len[1], NULL,
4962 eANI_BOOLEAN_FALSE) == eHAL_STATUS_FAILURE)
4963 {
4964 hddLog(LOGE,
4965 "Could not pass on WNI_CFG_PROBE_RSP_ADDNIE_DATA2 to CCM");
Jeff Johnsone7245742012-09-05 17:12:55 -07004966 ret = -EINVAL;
4967 goto done;
Jeff Johnson295189b2012-06-20 16:38:30 -07004968 }
4969 rem_probe_resp_ie_len += probe_rsp_ie_len[1];
4970 }
4971
4972 if (probe_rsp_ie_len[2] > 0)
4973 {
4974 if (ccmCfgSetStr((WLAN_HDD_GET_CTX(pHostapdAdapter))->hHal,
4975 WNI_CFG_PROBE_RSP_ADDNIE_DATA3,
4976 (tANI_U8*)&params->proberesp_ies[rem_probe_resp_ie_len],
4977 probe_rsp_ie_len[2], NULL,
4978 eANI_BOOLEAN_FALSE) == eHAL_STATUS_FAILURE)
4979 {
4980 hddLog(LOGE,
4981 "Could not pass on WNI_CFG_PROBE_RSP_ADDNIE_DATA3 to CCM");
Jeff Johnsone7245742012-09-05 17:12:55 -07004982 ret = -EINVAL;
4983 goto done;
Jeff Johnson295189b2012-06-20 16:38:30 -07004984 }
4985 rem_probe_resp_ie_len += probe_rsp_ie_len[2];
4986 }
4987
4988 if (probe_rsp_ie_len[1] == 0 )
4989 {
4990 if ( eHAL_STATUS_FAILURE == ccmCfgSetStr((WLAN_HDD_GET_CTX(pHostapdAdapter))->hHal,
4991 WNI_CFG_PROBE_RSP_ADDNIE_DATA2, (tANI_U8*)addIE, 0, NULL,
4992 eANI_BOOLEAN_FALSE) )
4993 {
4994 hddLog(LOGE,
Arif Hussain6d2a3322013-11-17 19:50:10 -08004995 "Could not pass on WNI_CFG_PROBE_RSP_ADDNIE_DATA2 to CCM");
Jeff Johnson295189b2012-06-20 16:38:30 -07004996 }
4997 }
4998
4999 if (probe_rsp_ie_len[2] == 0 )
5000 {
5001 if ( eHAL_STATUS_FAILURE == ccmCfgSetStr((WLAN_HDD_GET_CTX(pHostapdAdapter))->hHal,
5002 WNI_CFG_PROBE_RSP_ADDNIE_DATA3, (tANI_U8*)addIE, 0, NULL,
5003 eANI_BOOLEAN_FALSE) )
5004 {
5005 hddLog(LOGE,
Arif Hussain6d2a3322013-11-17 19:50:10 -08005006 "Could not pass on WNI_CFG_PROBE_RSP_ADDNIE_DATA3 to CCM");
Jeff Johnson295189b2012-06-20 16:38:30 -07005007 }
5008 }
5009
5010 if (ccmCfgSetInt((WLAN_HDD_GET_CTX(pHostapdAdapter))->hHal,
5011 WNI_CFG_PROBE_RSP_ADDNIE_FLAG, 1,NULL,
5012 test_bit(SOFTAP_BSS_STARTED, &pHostapdAdapter->event_flags) ?
5013 eANI_BOOLEAN_TRUE : eANI_BOOLEAN_FALSE)
5014 == eHAL_STATUS_FAILURE)
5015 {
5016 hddLog(LOGE,
5017 "Could not pass on WNI_CFG_PROBE_RSP_ADDNIE_FLAG to CCM");
Jeff Johnsone7245742012-09-05 17:12:55 -07005018 ret = -EINVAL;
5019 goto done;
Jeff Johnson295189b2012-06-20 16:38:30 -07005020 }
5021 }
5022 else
5023 {
5024 // Reset WNI_CFG_PROBE_RSP Flags
5025 wlan_hdd_reset_prob_rspies(pHostapdAdapter);
5026
5027 hddLog(VOS_TRACE_LEVEL_INFO,
5028 "%s: No Probe Response IE received in set beacon",
5029 __func__);
5030 }
5031
5032 // Added for AssocResp IE
5033 if ( (params->assocresp_ies != NULL) && (params->assocresp_ies_len != 0) )
5034 {
5035 if (ccmCfgSetStr((WLAN_HDD_GET_CTX(pHostapdAdapter))->hHal,
5036 WNI_CFG_ASSOC_RSP_ADDNIE_DATA, (tANI_U8*)params->assocresp_ies,
5037 params->assocresp_ies_len, NULL,
5038 eANI_BOOLEAN_FALSE) == eHAL_STATUS_FAILURE)
5039 {
5040 hddLog(LOGE,
5041 "Could not pass on WNI_CFG_ASSOC_RSP_ADDNIE_DATA to CCM");
Jeff Johnsone7245742012-09-05 17:12:55 -07005042 ret = -EINVAL;
5043 goto done;
Jeff Johnson295189b2012-06-20 16:38:30 -07005044 }
5045
5046 if (ccmCfgSetInt((WLAN_HDD_GET_CTX(pHostapdAdapter))->hHal,
5047 WNI_CFG_ASSOC_RSP_ADDNIE_FLAG, 1, NULL,
5048 test_bit(SOFTAP_BSS_STARTED, &pHostapdAdapter->event_flags) ?
5049 eANI_BOOLEAN_TRUE : eANI_BOOLEAN_FALSE)
5050 == eHAL_STATUS_FAILURE)
5051 {
5052 hddLog(LOGE,
5053 "Could not pass on WNI_CFG_ASSOC_RSP_ADDNIE_FLAG to CCM");
Jeff Johnsone7245742012-09-05 17:12:55 -07005054 ret = -EINVAL;
5055 goto done;
Jeff Johnson295189b2012-06-20 16:38:30 -07005056 }
5057 }
5058 else
5059 {
5060 hddLog(VOS_TRACE_LEVEL_INFO,
5061 "%s: No Assoc Response IE received in set beacon",
5062 __func__);
5063
5064 if ( eHAL_STATUS_FAILURE == ccmCfgSetInt((WLAN_HDD_GET_CTX(pHostapdAdapter))->hHal,
5065 WNI_CFG_ASSOC_RSP_ADDNIE_FLAG, 0, NULL,
5066 eANI_BOOLEAN_FALSE) )
5067 {
5068 hddLog(LOGE,
Arif Hussain6d2a3322013-11-17 19:50:10 -08005069 "Could not pass on WNI_CFG_ASSOC_RSP_ADDNIE_FLAG to CCM");
Jeff Johnson295189b2012-06-20 16:38:30 -07005070 }
5071 }
5072
Jeff Johnsone7245742012-09-05 17:12:55 -07005073done:
Jeff Johnson295189b2012-06-20 16:38:30 -07005074 vos_mem_free(genie);
Gopichand Nakkala2b25f4e2013-03-21 19:14:07 +05305075 return ret;
Jeff Johnson295189b2012-06-20 16:38:30 -07005076}
Jeff Johnson295189b2012-06-20 16:38:30 -07005077
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305078/*
Jeff Johnson295189b2012-06-20 16:38:30 -07005079 * FUNCTION: wlan_hdd_validate_operation_channel
5080 * called by wlan_hdd_cfg80211_start_bss() and
5081 * wlan_hdd_cfg80211_set_channel()
5082 * This function validates whether given channel is part of valid
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305083 * channel list.
5084 */
Varun Reddy Yeturu920df212013-05-22 08:07:23 -07005085VOS_STATUS wlan_hdd_validate_operation_channel(hdd_adapter_t *pAdapter,int channel)
Jeff Johnson295189b2012-06-20 16:38:30 -07005086{
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305087
Jeff Johnson295189b2012-06-20 16:38:30 -07005088 v_U32_t num_ch = 0;
5089 u8 valid_ch[WNI_CFG_VALID_CHANNEL_LIST_LEN];
5090 u32 indx = 0;
5091 tHalHandle hHal = WLAN_HDD_GET_HAL_CTX(pAdapter);
Madan Mohan Koyylamudi64267f72013-02-05 14:07:08 +05305092 v_U8_t fValidChannel = FALSE, count = 0;
5093 hdd_config_t *hdd_pConfig_ini= (WLAN_HDD_GET_CTX(pAdapter))->cfg_ini;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305094
Jeff Johnson295189b2012-06-20 16:38:30 -07005095 num_ch = WNI_CFG_VALID_CHANNEL_LIST_LEN;
5096
Madan Mohan Koyylamudi64267f72013-02-05 14:07:08 +05305097 if ( hdd_pConfig_ini->sapAllowAllChannel)
Jeff Johnson295189b2012-06-20 16:38:30 -07005098 {
Madan Mohan Koyylamudi64267f72013-02-05 14:07:08 +05305099 /* Validate the channel */
5100 for (count = RF_CHAN_1 ; count <= RF_CHAN_165 ; count++)
Jeff Johnson295189b2012-06-20 16:38:30 -07005101 {
Madan Mohan Koyylamudi64267f72013-02-05 14:07:08 +05305102 if ( channel == rfChannels[count].channelNum )
5103 {
5104 fValidChannel = TRUE;
5105 break;
5106 }
5107 }
5108 if (fValidChannel != TRUE)
5109 {
5110 hddLog(VOS_TRACE_LEVEL_ERROR,
5111 "%s: Invalid Channel [%d]", __func__, channel);
5112 return VOS_STATUS_E_FAILURE;
Jeff Johnson295189b2012-06-20 16:38:30 -07005113 }
5114 }
Madan Mohan Koyylamudi64267f72013-02-05 14:07:08 +05305115 else
Jeff Johnson295189b2012-06-20 16:38:30 -07005116 {
Madan Mohan Koyylamudi64267f72013-02-05 14:07:08 +05305117 if (0 != ccmCfgGetStr(hHal, WNI_CFG_VALID_CHANNEL_LIST,
5118 valid_ch, &num_ch))
5119 {
5120 hddLog(VOS_TRACE_LEVEL_ERROR,
5121 "%s: failed to get valid channel list", __func__);
5122 return VOS_STATUS_E_FAILURE;
5123 }
5124 for (indx = 0; indx < num_ch; indx++)
5125 {
5126 if (channel == valid_ch[indx])
5127 {
5128 break;
5129 }
5130 }
5131
Rashmi Ramanna3b59e122014-04-10 14:45:13 +05305132 if (indx >= num_ch)
5133 {
5134 if (WLAN_HDD_P2P_GO == pAdapter->device_mode)
5135 {
5136 eCsrBand band;
5137 unsigned int freq;
5138
5139 sme_GetFreqBand(hHal, &band);
5140
5141 if (eCSR_BAND_5G == band)
5142 {
5143#if (LINUX_VERSION_CODE > KERNEL_VERSION(2,6,38))
5144 if (channel <= ARRAY_SIZE(hdd_channels_2_4_GHZ))
5145 {
5146 freq = ieee80211_channel_to_frequency(channel,
5147 IEEE80211_BAND_2GHZ);
5148 }
5149 else
5150 {
5151 freq = ieee80211_channel_to_frequency(channel,
5152 IEEE80211_BAND_5GHZ);
5153 }
5154#else
5155 freq = ieee80211_channel_to_frequency(channel);
5156#endif
5157 if(WLAN_HDD_IS_SOCIAL_CHANNEL(freq))
5158 return VOS_STATUS_SUCCESS;
5159 }
5160 }
5161
5162 hddLog(VOS_TRACE_LEVEL_ERROR,
5163 "%s: Invalid Channel [%d]", __func__, channel);
5164 return VOS_STATUS_E_FAILURE;
5165 }
Jeff Johnson295189b2012-06-20 16:38:30 -07005166 }
Rashmi Ramanna3b59e122014-04-10 14:45:13 +05305167
Jeff Johnson295189b2012-06-20 16:38:30 -07005168 return VOS_STATUS_SUCCESS;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305169
Jeff Johnson295189b2012-06-20 16:38:30 -07005170}
5171
Viral Modi3a32cc52013-02-08 11:14:52 -08005172/**
5173 * FUNCTION: wlan_hdd_cfg80211_set_channel
5174 * This function is used to set the channel number
5175 */
5176static int wlan_hdd_cfg80211_set_channel( struct wiphy *wiphy, struct net_device *dev,
5177 struct ieee80211_channel *chan,
5178 enum nl80211_channel_type channel_type
5179 )
5180{
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05305181 hdd_adapter_t *pAdapter = NULL;
Viral Modi3a32cc52013-02-08 11:14:52 -08005182 v_U32_t num_ch = 0;
Jeff Johnson4416a782013-03-25 14:17:50 -07005183 int channel = 0;
Viral Modi3a32cc52013-02-08 11:14:52 -08005184 int freq = chan->center_freq; /* freq is in MHZ */
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05305185 hdd_context_t *pHddCtx;
5186 int status;
Viral Modi3a32cc52013-02-08 11:14:52 -08005187
5188 ENTER();
5189
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05305190
Viral Modi3a32cc52013-02-08 11:14:52 -08005191 if( NULL == dev )
5192 {
5193 hddLog(VOS_TRACE_LEVEL_ERROR,
Arif Hussain6d2a3322013-11-17 19:50:10 -08005194 "%s: Called with dev = NULL.", __func__);
Viral Modi3a32cc52013-02-08 11:14:52 -08005195 return -ENODEV;
5196 }
5197 pAdapter = WLAN_HDD_GET_PRIV_PTR( dev );
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +05305198
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05305199 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
5200 TRACE_CODE_HDD_CFG80211_SET_CHANNEL, pAdapter->sessionId,
5201 channel_type ));
Viral Modi3a32cc52013-02-08 11:14:52 -08005202 hddLog(VOS_TRACE_LEVEL_INFO,
Sushant Kaushik8bc7df22014-04-09 17:55:29 +05305203 "%s: device_mode = %s (%d) freq = %d", __func__,
5204 hdd_device_modetoString(pAdapter->device_mode),
5205 pAdapter->device_mode, chan->center_freq);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05305206
5207 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
5208 status = wlan_hdd_validate_context(pHddCtx);
5209
5210 if (0 != status)
Viral Modi3a32cc52013-02-08 11:14:52 -08005211 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05305212 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
5213 "%s: HDD context is not valid", __func__);
5214 return status;
Viral Modi3a32cc52013-02-08 11:14:52 -08005215 }
5216
5217 /*
5218 * Do freq to chan conversion
5219 * TODO: for 11a
5220 */
5221
5222 channel = ieee80211_frequency_to_channel(freq);
5223
5224 /* Check freq range */
5225 if ((WNI_CFG_CURRENT_CHANNEL_STAMIN > channel) ||
5226 (WNI_CFG_CURRENT_CHANNEL_STAMAX < channel))
5227 {
5228 hddLog(VOS_TRACE_LEVEL_ERROR,
Arif Hussain6d2a3322013-11-17 19:50:10 -08005229 "%s: Channel [%d] is outside valid range from %d to %d",
Viral Modi3a32cc52013-02-08 11:14:52 -08005230 __func__, channel, WNI_CFG_CURRENT_CHANNEL_STAMIN,
5231 WNI_CFG_CURRENT_CHANNEL_STAMAX);
5232 return -EINVAL;
5233 }
5234
5235 num_ch = WNI_CFG_VALID_CHANNEL_LIST_LEN;
5236
Gopichand Nakkala6ab19562013-03-07 13:59:42 +05305237 if ((WLAN_HDD_SOFTAP != pAdapter->device_mode) &&
5238 (WLAN_HDD_P2P_GO != pAdapter->device_mode))
Viral Modi3a32cc52013-02-08 11:14:52 -08005239 {
5240 if(VOS_STATUS_SUCCESS != wlan_hdd_validate_operation_channel(pAdapter,channel))
5241 {
5242 hddLog(VOS_TRACE_LEVEL_ERROR,
Arif Hussain6d2a3322013-11-17 19:50:10 -08005243 "%s: Invalid Channel [%d]", __func__, channel);
Viral Modi3a32cc52013-02-08 11:14:52 -08005244 return -EINVAL;
5245 }
5246 hddLog(VOS_TRACE_LEVEL_INFO_HIGH,
5247 "%s: set channel to [%d] for device mode =%d",
5248 __func__, channel,pAdapter->device_mode);
5249 }
5250 if( (pAdapter->device_mode == WLAN_HDD_INFRA_STATION)
Viral Modi3a32cc52013-02-08 11:14:52 -08005251 || (pAdapter->device_mode == WLAN_HDD_P2P_CLIENT)
Viral Modi3a32cc52013-02-08 11:14:52 -08005252 )
5253 {
5254 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
5255 tCsrRoamProfile * pRoamProfile = &pWextState->roamProfile;
5256 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
5257
5258 if (eConnectionState_IbssConnected == pHddStaCtx->conn_info.connState)
5259 {
5260 /* Link is up then return cant set channel*/
5261 hddLog( VOS_TRACE_LEVEL_ERROR,
Arif Hussain6d2a3322013-11-17 19:50:10 -08005262 "%s: IBSS Associated, can't set the channel", __func__);
Viral Modi3a32cc52013-02-08 11:14:52 -08005263 return -EINVAL;
5264 }
5265
5266 num_ch = pRoamProfile->ChannelInfo.numOfChannels = 1;
5267 pHddStaCtx->conn_info.operationChannel = channel;
5268 pRoamProfile->ChannelInfo.ChannelList =
5269 &pHddStaCtx->conn_info.operationChannel;
5270 }
5271 else if ((pAdapter->device_mode == WLAN_HDD_SOFTAP)
Viral Modi3a32cc52013-02-08 11:14:52 -08005272 || (pAdapter->device_mode == WLAN_HDD_P2P_GO)
Viral Modi3a32cc52013-02-08 11:14:52 -08005273 )
5274 {
Gopichand Nakkalac8fa7b62013-03-11 13:56:41 +05305275 if (WLAN_HDD_P2P_GO == pAdapter->device_mode)
5276 {
5277 if(VOS_STATUS_SUCCESS !=
5278 wlan_hdd_validate_operation_channel(pAdapter,channel))
5279 {
5280 hddLog(VOS_TRACE_LEVEL_ERROR,
Arif Hussain6d2a3322013-11-17 19:50:10 -08005281 "%s: Invalid Channel [%d]", __func__, channel);
Gopichand Nakkalac8fa7b62013-03-11 13:56:41 +05305282 return -EINVAL;
5283 }
5284 (WLAN_HDD_GET_AP_CTX_PTR(pAdapter))->sapConfig.channel = channel;
5285 }
5286 else if ( WLAN_HDD_SOFTAP == pAdapter->device_mode )
Viral Modi3a32cc52013-02-08 11:14:52 -08005287 {
5288 hdd_config_t *cfg_param = (WLAN_HDD_GET_CTX(pAdapter))->cfg_ini;
5289
5290 /* If auto channel selection is configured as enable/ 1 then ignore
5291 channel set by supplicant
5292 */
5293 if ( cfg_param->apAutoChannelSelection )
5294 {
Gopichand Nakkalac8fa7b62013-03-11 13:56:41 +05305295 (WLAN_HDD_GET_AP_CTX_PTR(pAdapter))->sapConfig.channel =
5296 AUTO_CHANNEL_SELECT;
Viral Modi3a32cc52013-02-08 11:14:52 -08005297 hddLog(VOS_TRACE_LEVEL_INFO_HIGH,
Sushant Kaushik8bc7df22014-04-09 17:55:29 +05305298 "%s: set channel to auto channel (0) for device mode =%s (%d)",
5299 __func__, hdd_device_modetoString(pAdapter->device_mode),
5300 pAdapter->device_mode);
Viral Modi3a32cc52013-02-08 11:14:52 -08005301 }
Gopichand Nakkalac8fa7b62013-03-11 13:56:41 +05305302 else
5303 {
5304 if(VOS_STATUS_SUCCESS !=
5305 wlan_hdd_validate_operation_channel(pAdapter,channel))
5306 {
5307 hddLog(VOS_TRACE_LEVEL_ERROR,
Arif Hussain6d2a3322013-11-17 19:50:10 -08005308 "%s: Invalid Channel [%d]", __func__, channel);
Gopichand Nakkalac8fa7b62013-03-11 13:56:41 +05305309 return -EINVAL;
5310 }
5311 (WLAN_HDD_GET_AP_CTX_PTR(pAdapter))->sapConfig.channel = channel;
5312 }
Viral Modi3a32cc52013-02-08 11:14:52 -08005313 }
5314 }
5315 else
5316 {
5317 hddLog(VOS_TRACE_LEVEL_FATAL,
5318 "%s: Invalid device mode failed to set valid channel", __func__);
5319 return -EINVAL;
5320 }
5321 EXIT();
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05305322 return status;
Viral Modi3a32cc52013-02-08 11:14:52 -08005323}
5324
Jeff Johnson295189b2012-06-20 16:38:30 -07005325#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,4,0))
5326static int wlan_hdd_cfg80211_start_bss(hdd_adapter_t *pHostapdAdapter,
5327 struct beacon_parameters *params)
Jeff Johnson04dd8a82012-06-29 20:41:40 -07005328#else
5329static int wlan_hdd_cfg80211_start_bss(hdd_adapter_t *pHostapdAdapter,
5330 struct cfg80211_beacon_data *params,
5331 const u8 *ssid, size_t ssid_len,
5332 enum nl80211_hidden_ssid hidden_ssid)
5333#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07005334{
5335 tsap_Config_t *pConfig;
5336 beacon_data_t *pBeacon = NULL;
5337 struct ieee80211_mgmt *pMgmt_frame;
5338 v_U8_t *pIe=NULL;
5339 v_U16_t capab_info;
5340 eCsrAuthType RSNAuthType;
5341 eCsrEncryptionType RSNEncryptType;
5342 eCsrEncryptionType mcRSNEncryptType;
5343 int status = VOS_STATUS_SUCCESS;
5344 tpWLAN_SAPEventCB pSapEventCallback;
5345 hdd_hostapd_state_t *pHostapdState;
5346 v_U8_t wpaRsnIEdata[(SIR_MAC_MAX_IE_LENGTH * 2)+4]; //Max ie length 255 * 2(WPA+RSN) + 2 bytes (vendor specific ID) * 2
5347 v_CONTEXT_t pVosContext = (WLAN_HDD_GET_CTX(pHostapdAdapter))->pvosContext;
Madan Mohan Koyylamudia16d0202013-02-01 11:05:57 +05305348 tHalHandle hHal = WLAN_HDD_GET_HAL_CTX(pHostapdAdapter);
Jeff Johnson295189b2012-06-20 16:38:30 -07005349 struct qc_mac_acl_entry *acl_entry = NULL;
Siddharth Bhal5cba24e2014-05-08 18:59:39 +05305350 hdd_config_t *iniConfig;
Jeff Johnson295189b2012-06-20 16:38:30 -07005351 v_SINT_t i;
Madan Mohan Koyyalamudi543172b2012-12-05 16:40:18 -08005352 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pHostapdAdapter);
Chet Lanctot40142442014-05-20 13:39:25 -07005353 v_BOOL_t MFPCapable = VOS_FALSE;
5354 v_BOOL_t MFPRequired = VOS_FALSE;
Abhishek Singhf0ac1752014-03-05 17:47:09 +05305355 eHddDot11Mode sapDot11Mode =
5356 (WLAN_HDD_GET_CTX(pHostapdAdapter))->cfg_ini->sapDot11Mode;
Jeff Johnson295189b2012-06-20 16:38:30 -07005357
5358 ENTER();
5359
Siddharth Bhal5cba24e2014-05-08 18:59:39 +05305360 iniConfig = pHddCtx->cfg_ini;
5361
Jeff Johnson295189b2012-06-20 16:38:30 -07005362 pHostapdState = WLAN_HDD_GET_HOSTAP_STATE_PTR(pHostapdAdapter);
5363
5364 pConfig = &pHostapdAdapter->sessionCtx.ap.sapConfig;
5365
5366 pBeacon = pHostapdAdapter->sessionCtx.ap.beacon;
5367
5368 pMgmt_frame = (struct ieee80211_mgmt*)pBeacon->head;
5369
5370 pConfig->beacon_int = pMgmt_frame->u.beacon.beacon_int;
5371
5372 //channel is already set in the set_channel Call back
5373 //pConfig->channel = pCommitConfig->channel;
5374
5375 /*Protection parameter to enable or disable*/
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305376 pConfig->protEnabled =
Jeff Johnson295189b2012-06-20 16:38:30 -07005377 (WLAN_HDD_GET_CTX(pHostapdAdapter))->cfg_ini->apProtEnabled;
5378
5379 pConfig->dtim_period = pBeacon->dtim_period;
5380
Arif Hussain6d2a3322013-11-17 19:50:10 -08005381 hddLog(VOS_TRACE_LEVEL_INFO_HIGH,"****pConfig->dtim_period=%d***",
Jeff Johnson295189b2012-06-20 16:38:30 -07005382 pConfig->dtim_period);
5383
5384
Madan Mohan Koyyalamudie0ca11f2012-11-27 15:57:52 -08005385 if (pHostapdAdapter->device_mode == WLAN_HDD_SOFTAP)
Jeff Johnson32d95a32012-09-10 13:15:23 -07005386 {
5387 pIe = wlan_hdd_cfg80211_get_ie_ptr(pBeacon->tail, pBeacon->tail_len,
Jeff Johnson295189b2012-06-20 16:38:30 -07005388 WLAN_EID_COUNTRY);
Kiet Lam083504c2013-11-25 14:17:45 +05305389 if(memcmp(pHddCtx->cfg_ini->apCntryCode, CFG_AP_COUNTRY_CODE_DEFAULT, 3) != 0)
5390 {
5391 tANI_BOOLEAN restartNeeded;
5392 pConfig->ieee80211d = 1;
5393 vos_mem_copy(pConfig->countryCode, pHddCtx->cfg_ini->apCntryCode, 3);
5394 sme_setRegInfo(hHal, pConfig->countryCode);
5395 sme_ResetCountryCodeInformation(hHal, &restartNeeded);
5396 }
5397 else if(pIe)
Jeff Johnson295189b2012-06-20 16:38:30 -07005398 {
Jeff Johnson32d95a32012-09-10 13:15:23 -07005399 tANI_BOOLEAN restartNeeded;
Jeff Johnson32d95a32012-09-10 13:15:23 -07005400 pConfig->ieee80211d = 1;
5401 vos_mem_copy(pConfig->countryCode, &pIe[2], 3);
5402 sme_setRegInfo(hHal, pConfig->countryCode);
5403 sme_ResetCountryCodeInformation(hHal, &restartNeeded);
Jeff Johnson295189b2012-06-20 16:38:30 -07005404 }
Jeff Johnson32d95a32012-09-10 13:15:23 -07005405 else
5406 {
5407 pConfig->ieee80211d = 0;
5408 }
Madan Mohan Koyylamudia16d0202013-02-01 11:05:57 +05305409 /*
5410 * If auto channel is configured i.e. channel is 0,
5411 * so skip channel validation.
5412 */
5413 if( AUTO_CHANNEL_SELECT != pConfig->channel )
5414 {
5415 if(VOS_STATUS_SUCCESS != wlan_hdd_validate_operation_channel(pHostapdAdapter,pConfig->channel))
5416 {
5417 hddLog(VOS_TRACE_LEVEL_ERROR,
Arif Hussain6d2a3322013-11-17 19:50:10 -08005418 "%s: Invalid Channel [%d]", __func__, pConfig->channel);
Madan Mohan Koyylamudia16d0202013-02-01 11:05:57 +05305419 return -EINVAL;
5420 }
5421 }
5422 else
5423 {
5424 if(1 != pHddCtx->is_dynamic_channel_range_set)
5425 {
5426 hdd_config_t *hdd_pConfig= (WLAN_HDD_GET_CTX(pHostapdAdapter))->cfg_ini;
5427 WLANSAP_SetChannelRange(hHal, hdd_pConfig->apStartChannelNum,
5428 hdd_pConfig->apEndChannelNum,hdd_pConfig->apOperatingBand);
5429 }
5430 pHddCtx->is_dynamic_channel_range_set = 0;
5431 }
Jeff Johnson295189b2012-06-20 16:38:30 -07005432 }
Jeff Johnson32d95a32012-09-10 13:15:23 -07005433 else
Jeff Johnson295189b2012-06-20 16:38:30 -07005434 {
5435 pConfig->ieee80211d = 0;
5436 }
5437 pConfig->authType = eSAP_AUTO_SWITCH;
5438
5439 capab_info = pMgmt_frame->u.beacon.capab_info;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305440
5441 pConfig->privacy = (pMgmt_frame->u.beacon.capab_info &
Jeff Johnson295189b2012-06-20 16:38:30 -07005442 WLAN_CAPABILITY_PRIVACY) ? VOS_TRUE : VOS_FALSE;
5443
5444 (WLAN_HDD_GET_AP_CTX_PTR(pHostapdAdapter))->uPrivacy = pConfig->privacy;
5445
5446 /*Set wps station to configured*/
5447 pIe = wlan_hdd_get_wps_ie_ptr(pBeacon->tail, pBeacon->tail_len);
5448
5449 if(pIe)
5450 {
5451 if(pIe[1] < (2 + WPS_OUI_TYPE_SIZE))
5452 {
Arif Hussain6d2a3322013-11-17 19:50:10 -08005453 hddLog( VOS_TRACE_LEVEL_ERROR, "**Wps Ie Length is too small***");
Jeff Johnson295189b2012-06-20 16:38:30 -07005454 return -EINVAL;
5455 }
5456 else if(memcmp(&pIe[2], WPS_OUI_TYPE, WPS_OUI_TYPE_SIZE) == 0)
5457 {
Madan Mohan Koyyalamudi8bdd3112012-09-24 13:55:14 -07005458 hddLog( VOS_TRACE_LEVEL_INFO, "** WPS IE(len %d) ***", (pIe[1]+2));
Jeff Johnson295189b2012-06-20 16:38:30 -07005459 /* Check 15 bit of WPS IE as it contain information for wps state
5460 * WPS state
5461 */
5462 if(SAP_WPS_ENABLED_UNCONFIGURED == pIe[15])
5463 {
5464 pConfig->wps_state = SAP_WPS_ENABLED_UNCONFIGURED;
5465 } else if(SAP_WPS_ENABLED_CONFIGURED == pIe[15])
5466 {
5467 pConfig->wps_state = SAP_WPS_ENABLED_CONFIGURED;
5468 }
5469 }
5470 }
5471 else
5472 {
5473 pConfig->wps_state = SAP_WPS_DISABLED;
5474 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305475 pConfig->fwdWPSPBCProbeReq = 1; // Forward WPS PBC probe request frame up
Jeff Johnson295189b2012-06-20 16:38:30 -07005476
c_hpothufe599e92014-06-16 11:38:55 +05305477 pConfig->RSNEncryptType = eCSR_ENCRYPT_TYPE_NONE;
5478 pConfig->mcRSNEncryptType = eCSR_ENCRYPT_TYPE_NONE;
5479 (WLAN_HDD_GET_AP_CTX_PTR(pHostapdAdapter))->ucEncryptType =
5480 eCSR_ENCRYPT_TYPE_NONE;
5481
Jeff Johnson295189b2012-06-20 16:38:30 -07005482 pConfig->RSNWPAReqIELength = 0;
5483 pConfig->pRSNWPAReqIE = NULL;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305484 pIe = wlan_hdd_cfg80211_get_ie_ptr(pBeacon->tail, pBeacon->tail_len,
Jeff Johnson295189b2012-06-20 16:38:30 -07005485 WLAN_EID_RSN);
5486 if(pIe && pIe[1])
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305487 {
Jeff Johnson295189b2012-06-20 16:38:30 -07005488 pConfig->RSNWPAReqIELength = pIe[1] + 2;
5489 memcpy(&wpaRsnIEdata[0], pIe, pConfig->RSNWPAReqIELength);
5490 pConfig->pRSNWPAReqIE = &wpaRsnIEdata[0];
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305491 /* The actual processing may eventually be more extensive than
5492 * this. Right now, just consume any PMKIDs that are sent in
Jeff Johnson295189b2012-06-20 16:38:30 -07005493 * by the app.
5494 * */
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305495 status = hdd_softap_unpackIE(
Jeff Johnson295189b2012-06-20 16:38:30 -07005496 vos_get_context( VOS_MODULE_ID_SME, pVosContext),
5497 &RSNEncryptType,
5498 &mcRSNEncryptType,
5499 &RSNAuthType,
Chet Lanctot8cecea22014-02-11 19:09:36 -08005500 &MFPCapable,
5501 &MFPRequired,
Jeff Johnson295189b2012-06-20 16:38:30 -07005502 pConfig->pRSNWPAReqIE[1]+2,
5503 pConfig->pRSNWPAReqIE );
5504
5505 if( VOS_STATUS_SUCCESS == status )
5506 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305507 /* Now copy over all the security attributes you have
5508 * parsed out
Jeff Johnson295189b2012-06-20 16:38:30 -07005509 * */
5510 pConfig->RSNEncryptType = RSNEncryptType; // Use the cipher type in the RSN IE
5511 pConfig->mcRSNEncryptType = mcRSNEncryptType;
5512 (WLAN_HDD_GET_AP_CTX_PTR(pHostapdAdapter))->ucEncryptType
5513 = RSNEncryptType;
Gopichand Nakkala66c0bd02013-04-10 11:36:29 +05305514 hddLog( LOG1, FL("CSR AuthType = %d, "
Arif Hussain6d2a3322013-11-17 19:50:10 -08005515 "EncryptionType = %d mcEncryptionType = %d"),
Jeff Johnson295189b2012-06-20 16:38:30 -07005516 RSNAuthType, RSNEncryptType, mcRSNEncryptType);
5517 }
5518 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305519
Jeff Johnson295189b2012-06-20 16:38:30 -07005520 pIe = wlan_hdd_get_vendor_oui_ie_ptr(WPA_OUI_TYPE, WPA_OUI_TYPE_SIZE,
5521 pBeacon->tail, pBeacon->tail_len);
5522
5523 if(pIe && pIe[1] && (pIe[0] == DOT11F_EID_WPA))
5524 {
5525 if (pConfig->pRSNWPAReqIE)
5526 {
5527 /*Mixed mode WPA/WPA2*/
5528 memcpy((&wpaRsnIEdata[0] + pConfig->RSNWPAReqIELength), pIe, pIe[1] + 2);
5529 pConfig->RSNWPAReqIELength += pIe[1] + 2;
5530 }
5531 else
5532 {
5533 pConfig->RSNWPAReqIELength = pIe[1] + 2;
5534 memcpy(&wpaRsnIEdata[0], pIe, pConfig->RSNWPAReqIELength);
5535 pConfig->pRSNWPAReqIE = &wpaRsnIEdata[0];
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305536 status = hdd_softap_unpackIE(
Jeff Johnson295189b2012-06-20 16:38:30 -07005537 vos_get_context( VOS_MODULE_ID_SME, pVosContext),
5538 &RSNEncryptType,
5539 &mcRSNEncryptType,
5540 &RSNAuthType,
Chet Lanctot8cecea22014-02-11 19:09:36 -08005541 &MFPCapable,
5542 &MFPRequired,
Jeff Johnson295189b2012-06-20 16:38:30 -07005543 pConfig->pRSNWPAReqIE[1]+2,
5544 pConfig->pRSNWPAReqIE );
5545
5546 if( VOS_STATUS_SUCCESS == status )
5547 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305548 /* Now copy over all the security attributes you have
5549 * parsed out
Jeff Johnson295189b2012-06-20 16:38:30 -07005550 * */
5551 pConfig->RSNEncryptType = RSNEncryptType; // Use the cipher type in the RSN IE
5552 pConfig->mcRSNEncryptType = mcRSNEncryptType;
5553 (WLAN_HDD_GET_AP_CTX_PTR(pHostapdAdapter))->ucEncryptType
5554 = RSNEncryptType;
Gopichand Nakkala66c0bd02013-04-10 11:36:29 +05305555 hddLog( LOG1, FL("CSR AuthType = %d, "
Arif Hussain6d2a3322013-11-17 19:50:10 -08005556 "EncryptionType = %d mcEncryptionType = %d"),
Jeff Johnson295189b2012-06-20 16:38:30 -07005557 RSNAuthType, RSNEncryptType, mcRSNEncryptType);
5558 }
5559 }
5560 }
5561
Jeff Johnson4416a782013-03-25 14:17:50 -07005562 if (pConfig->RSNWPAReqIELength > sizeof wpaRsnIEdata) {
5563 hddLog( VOS_TRACE_LEVEL_ERROR, "**RSNWPAReqIELength is too large***");
5564 return -EINVAL;
5565 }
5566
Jeff Johnson295189b2012-06-20 16:38:30 -07005567 pConfig->SSIDinfo.ssidHidden = VOS_FALSE;
5568
Jeff Johnson04dd8a82012-06-29 20:41:40 -07005569#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,4,0))
Jeff Johnson295189b2012-06-20 16:38:30 -07005570 if (params->ssid != NULL)
5571 {
5572 memcpy(pConfig->SSIDinfo.ssid.ssId, params->ssid, params->ssid_len);
5573 pConfig->SSIDinfo.ssid.length = params->ssid_len;
5574 if (params->hidden_ssid != NL80211_HIDDEN_SSID_NOT_IN_USE)
5575 pConfig->SSIDinfo.ssidHidden = VOS_TRUE;
5576 }
Jeff Johnson04dd8a82012-06-29 20:41:40 -07005577#else
5578 if (ssid != NULL)
5579 {
5580 memcpy(pConfig->SSIDinfo.ssid.ssId, ssid, ssid_len);
5581 pConfig->SSIDinfo.ssid.length = ssid_len;
5582 if (hidden_ssid != NL80211_HIDDEN_SSID_NOT_IN_USE)
5583 pConfig->SSIDinfo.ssidHidden = VOS_TRUE;
5584 }
5585#endif
5586
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305587 vos_mem_copy(pConfig->self_macaddr.bytes,
Jeff Johnson295189b2012-06-20 16:38:30 -07005588 pHostapdAdapter->macAddressCurrent.bytes, sizeof(v_MACADDR_t));
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305589
Jeff Johnson295189b2012-06-20 16:38:30 -07005590 /* default value */
5591 pConfig->SapMacaddr_acl = eSAP_ACCEPT_UNLESS_DENIED;
5592 pConfig->num_accept_mac = 0;
5593 pConfig->num_deny_mac = 0;
5594
5595 pIe = wlan_hdd_get_vendor_oui_ie_ptr(BLACKLIST_OUI_TYPE, WPA_OUI_TYPE_SIZE,
5596 pBeacon->tail, pBeacon->tail_len);
5597
5598 /* pIe for black list is following form:
5599 type : 1 byte
5600 length : 1 byte
5601 OUI : 4 bytes
5602 acl type : 1 byte
5603 no of mac addr in black list: 1 byte
5604 list of mac_acl_entries: variable, 6 bytes per mac address + sizeof(int) for vlan id
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305605 */
5606 if ((pIe != NULL) && (pIe[1] != 0))
Jeff Johnson295189b2012-06-20 16:38:30 -07005607 {
5608 pConfig->SapMacaddr_acl = pIe[6];
5609 pConfig->num_deny_mac = pIe[7];
Arif Hussain6d2a3322013-11-17 19:50:10 -08005610 hddLog(VOS_TRACE_LEVEL_INFO,"acl type = %d no deny mac = %d",
Jeff Johnson295189b2012-06-20 16:38:30 -07005611 pIe[6], pIe[7]);
Gopichand Nakkalac005b7c2013-05-14 16:04:14 +05305612 if (pConfig->num_deny_mac > MAX_ACL_MAC_ADDRESS)
5613 pConfig->num_deny_mac = MAX_ACL_MAC_ADDRESS;
Jeff Johnson295189b2012-06-20 16:38:30 -07005614 acl_entry = (struct qc_mac_acl_entry *)(pIe + 8);
5615 for (i = 0; i < pConfig->num_deny_mac; i++)
5616 {
5617 vos_mem_copy(&pConfig->deny_mac[i], acl_entry->addr, sizeof(qcmacaddr));
5618 acl_entry++;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305619 }
Jeff Johnson295189b2012-06-20 16:38:30 -07005620 }
5621 pIe = wlan_hdd_get_vendor_oui_ie_ptr(WHITELIST_OUI_TYPE, WPA_OUI_TYPE_SIZE,
5622 pBeacon->tail, pBeacon->tail_len);
5623
5624 /* pIe for white list is following form:
5625 type : 1 byte
5626 length : 1 byte
5627 OUI : 4 bytes
5628 acl type : 1 byte
5629 no of mac addr in white list: 1 byte
5630 list of mac_acl_entries: variable, 6 bytes per mac address + sizeof(int) for vlan id
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305631 */
5632 if ((pIe != NULL) && (pIe[1] != 0))
Jeff Johnson295189b2012-06-20 16:38:30 -07005633 {
5634 pConfig->SapMacaddr_acl = pIe[6];
5635 pConfig->num_accept_mac = pIe[7];
Arif Hussain6d2a3322013-11-17 19:50:10 -08005636 hddLog(VOS_TRACE_LEVEL_INFO,"acl type = %d no accept mac = %d",
Jeff Johnson295189b2012-06-20 16:38:30 -07005637 pIe[6], pIe[7]);
Gopichand Nakkalac005b7c2013-05-14 16:04:14 +05305638 if (pConfig->num_accept_mac > MAX_ACL_MAC_ADDRESS)
5639 pConfig->num_accept_mac = MAX_ACL_MAC_ADDRESS;
Jeff Johnson295189b2012-06-20 16:38:30 -07005640 acl_entry = (struct qc_mac_acl_entry *)(pIe + 8);
5641 for (i = 0; i < pConfig->num_accept_mac; i++)
5642 {
5643 vos_mem_copy(&pConfig->accept_mac[i], acl_entry->addr, sizeof(qcmacaddr));
5644 acl_entry++;
5645 }
5646 }
Gopichand Nakkalac005b7c2013-05-14 16:04:14 +05305647
Jeff Johnson295189b2012-06-20 16:38:30 -07005648 wlan_hdd_set_sapHwmode(pHostapdAdapter);
5649
Jeff Johnsone7245742012-09-05 17:12:55 -07005650#ifdef WLAN_FEATURE_11AC
Ravi Kumar Vaishnavbbaebbe2013-01-15 17:09:48 -08005651 /* Overwrite the hostapd setting for HW mode only for 11ac.
Kiet Lam0f320422013-11-21 19:29:17 +05305652 * This is valid only if mode is set to 11n in hostapd, either AUTO or
5653 * 11ac in .ini and 11ac is supported by both host and firmware.
5654 * Otherwise, leave whatever is set in hostapd (a OR b OR g OR n mode)
5655 */
Ravi Kumar Vaishnavbbaebbe2013-01-15 17:09:48 -08005656 if( ((pConfig->SapHw_mode == eSAP_DOT11_MODE_11n) ||
5657 (pConfig->SapHw_mode == eSAP_DOT11_MODE_11n_ONLY)) &&
Abhishek Singhf0ac1752014-03-05 17:47:09 +05305658 (( sapDot11Mode == eHDD_DOT11_MODE_AUTO ) ||
5659 ( sapDot11Mode == eHDD_DOT11_MODE_11ac ) ||
5660 ( sapDot11Mode == eHDD_DOT11_MODE_11ac_ONLY ) ) &&
5661 (sme_IsFeatureSupportedByDriver(DOT11AC)) &&
5662 (sme_IsFeatureSupportedByFW(DOT11AC)) )
Jeff Johnsone7245742012-09-05 17:12:55 -07005663 {
Siddharth Bhalf42f8592014-05-15 13:39:07 +05305664 v_U32_t operatingBand = 0;
Jeff Johnsone7245742012-09-05 17:12:55 -07005665 pConfig->SapHw_mode = eSAP_DOT11_MODE_11ac;
Siddharth Bhalf42f8592014-05-15 13:39:07 +05305666 ccmCfgGetInt(hHal, WNI_CFG_SAP_CHANNEL_SELECT_OPERATING_BAND, &operatingBand);
Ravi Joshi83bfaa12013-05-28 22:12:08 -07005667
Siddharth Bhal5cba24e2014-05-08 18:59:39 +05305668 /* If ACS disable and selected channel <= 14
5669 * OR
5670 * ACS enabled and ACS operating band is choosen as 2.4
5671 * AND
5672 * VHT in 2.4G Disabled
5673 * THEN
5674 * Fallback to 11N mode
5675 */
5676 if (((AUTO_CHANNEL_SELECT != pConfig->channel && pConfig->channel <= SIR_11B_CHANNEL_END)
5677 || (AUTO_CHANNEL_SELECT == pConfig->channel &&
Siddharth Bhalf42f8592014-05-15 13:39:07 +05305678 operatingBand == RF_SUBBAND_2_4_GHZ)) &&
Siddharth Bhal5cba24e2014-05-08 18:59:39 +05305679 iniConfig->enableVhtFor24GHzBand == FALSE)
Ravi Joshi83bfaa12013-05-28 22:12:08 -07005680 {
Siddharth Bhalf42f8592014-05-15 13:39:07 +05305681 hddLog(LOGW, FL("Setting hwmode to 11n, operatingBand = %d, Channel = %d"),
5682 operatingBand, pConfig->channel);
Ravi Joshi83bfaa12013-05-28 22:12:08 -07005683 pConfig->SapHw_mode = eSAP_DOT11_MODE_11n;
5684 }
Jeff Johnsone7245742012-09-05 17:12:55 -07005685 }
5686#endif
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305687
Ravi Joshiaeb7d9e2013-05-02 12:28:14 -07005688 if ( AUTO_CHANNEL_SELECT != pConfig->channel )
5689 {
5690 sme_SelectCBMode(hHal,
5691 sapConvertSapPhyModeToCsrPhyMode(pConfig->SapHw_mode),
5692 pConfig->channel);
5693 }
Jeff Johnson295189b2012-06-20 16:38:30 -07005694 // ht_capab is not what the name conveys,this is used for protection bitmap
5695 pConfig->ht_capab =
5696 (WLAN_HDD_GET_CTX(pHostapdAdapter))->cfg_ini->apProtection;
5697
5698 if ( 0 != wlan_hdd_cfg80211_update_apies(pHostapdAdapter, params) )
5699 {
5700 hddLog(LOGE, FL("SAP Not able to set AP IEs"));
5701 return -EINVAL;
5702 }
5703
5704 //Uapsd Enabled Bit
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305705 pConfig->UapsdEnable =
Jeff Johnson295189b2012-06-20 16:38:30 -07005706 (WLAN_HDD_GET_CTX(pHostapdAdapter))->cfg_ini->apUapsdEnabled;
5707 //Enable OBSS protection
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305708 pConfig->obssProtEnabled =
5709 (WLAN_HDD_GET_CTX(pHostapdAdapter))->cfg_ini->apOBSSProtEnabled;
Jeff Johnson295189b2012-06-20 16:38:30 -07005710
Chet Lanctot8cecea22014-02-11 19:09:36 -08005711#ifdef WLAN_FEATURE_11W
5712 pConfig->mfpCapable = MFPCapable;
5713 pConfig->mfpRequired = MFPRequired;
5714 hddLog(LOGW, FL("Soft AP MFP capable %d, MFP required %d\n"),
5715 pConfig->mfpCapable, pConfig->mfpRequired);
5716#endif
5717
Arif Hussain6d2a3322013-11-17 19:50:10 -08005718 hddLog(LOGW, FL("SOftAP macaddress : "MAC_ADDRESS_STR),
Jeff Johnson295189b2012-06-20 16:38:30 -07005719 MAC_ADDR_ARRAY(pHostapdAdapter->macAddressCurrent.bytes));
Arif Hussain6d2a3322013-11-17 19:50:10 -08005720 hddLog(LOGW,FL("ssid =%s, beaconint=%d, channel=%d"),
5721 pConfig->SSIDinfo.ssid.ssId, (int)pConfig->beacon_int,
5722 (int)pConfig->channel);
5723 hddLog(LOGW,FL("hw_mode=%x, privacy=%d, authType=%d"),
5724 pConfig->SapHw_mode, pConfig->privacy,
5725 pConfig->authType);
5726 hddLog(LOGW,FL("RSN/WPALen=%d, Uapsd = %d"),
5727 (int)pConfig->RSNWPAReqIELength, pConfig->UapsdEnable);
5728 hddLog(LOGW,FL("ProtEnabled = %d, OBSSProtEnabled = %d"),
5729 pConfig->protEnabled, pConfig->obssProtEnabled);
Jeff Johnson295189b2012-06-20 16:38:30 -07005730
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305731 if(test_bit(SOFTAP_BSS_STARTED, &pHostapdAdapter->event_flags))
Jeff Johnson295189b2012-06-20 16:38:30 -07005732 {
5733 //Bss already started. just return.
5734 //TODO Probably it should update some beacon params.
5735 hddLog( LOGE, "Bss Already started...Ignore the request");
5736 EXIT();
5737 return 0;
5738 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305739
Agarwal Ashish51325b52014-06-16 16:50:49 +05305740 if (vos_max_concurrent_connections_reached()) {
5741 hddLog(VOS_TRACE_LEVEL_INFO, FL("Reached max concurrent connections"));
5742 return -EINVAL;
5743 }
5744
Jeff Johnson295189b2012-06-20 16:38:30 -07005745 pConfig->persona = pHostapdAdapter->device_mode;
5746
5747 pSapEventCallback = hdd_hostapd_SAPEventCB;
5748 if(WLANSAP_StartBss(pVosContext, pSapEventCallback, pConfig,
5749 (v_PVOID_t)pHostapdAdapter->dev) != VOS_STATUS_SUCCESS)
5750 {
Arif Hussain6d2a3322013-11-17 19:50:10 -08005751 hddLog(LOGE,FL("SAP Start Bss fail"));
Jeff Johnson295189b2012-06-20 16:38:30 -07005752 return -EINVAL;
5753 }
5754
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305755 hddLog(LOG1,
Jeff Johnson295189b2012-06-20 16:38:30 -07005756 FL("Waiting for Scan to complete(auto mode) and BSS to start"));
5757
5758 status = vos_wait_single_event(&pHostapdState->vosEvent, 10000);
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305759
Jeff Johnson295189b2012-06-20 16:38:30 -07005760 if (!VOS_IS_STATUS_SUCCESS(status))
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305761 {
5762 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Arif Hussain6d2a3322013-11-17 19:50:10 -08005763 ("ERROR: HDD vos wait for single_event failed!!"));
Tushnim Bhattacharyyaad37df12013-10-02 12:01:33 -07005764 smeGetCommandQStatus(hHal);
Jeff Johnson295189b2012-06-20 16:38:30 -07005765 VOS_ASSERT(0);
5766 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305767
Jeff Johnson295189b2012-06-20 16:38:30 -07005768 set_bit(SOFTAP_BSS_STARTED, &pHostapdAdapter->event_flags);
Agarwal Ashish51325b52014-06-16 16:50:49 +05305769 wlan_hdd_incr_active_session(pHddCtx, pHostapdAdapter->device_mode);
Jeff Johnson295189b2012-06-20 16:38:30 -07005770
Madan Mohan Koyyalamudi26bd7142012-10-30 18:14:19 -07005771#ifdef WLAN_FEATURE_P2P_DEBUG
5772 if (pHostapdAdapter->device_mode == WLAN_HDD_P2P_GO)
5773 {
5774 if(globalP2PConnectionStatus == P2P_GO_NEG_COMPLETED)
5775 {
5776 globalP2PConnectionStatus = P2P_GO_COMPLETED_STATE;
5777 hddLog(LOGE,"[P2P State] From Go nego completed to "
Jeff Johnson1250df42012-12-10 14:31:52 -08005778 "Non-autonomous Group started");
Madan Mohan Koyyalamudi26bd7142012-10-30 18:14:19 -07005779 }
5780 else if(globalP2PConnectionStatus == P2P_NOT_ACTIVE)
5781 {
5782 globalP2PConnectionStatus = P2P_GO_COMPLETED_STATE;
5783 hddLog(LOGE,"[P2P State] From Inactive to "
Jeff Johnson1250df42012-12-10 14:31:52 -08005784 "Autonomous Group started");
Madan Mohan Koyyalamudi26bd7142012-10-30 18:14:19 -07005785 }
5786 }
5787#endif
5788
Jeff Johnson295189b2012-06-20 16:38:30 -07005789 pHostapdState->bCommit = TRUE;
5790 EXIT();
5791
5792 return 0;
5793}
5794
Jeff Johnson04dd8a82012-06-29 20:41:40 -07005795#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,4,0))
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305796static int wlan_hdd_cfg80211_add_beacon(struct wiphy *wiphy,
5797 struct net_device *dev,
Jeff Johnson295189b2012-06-20 16:38:30 -07005798 struct beacon_parameters *params)
5799{
5800 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +05305801 hdd_context_t *pHddCtx;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05305802 int status;
Jeff Johnson295189b2012-06-20 16:38:30 -07005803
5804 ENTER();
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +05305805
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05305806 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
5807 TRACE_CODE_HDD_CFG80211_ADD_BEACON,
5808 pAdapter->sessionId, params->interval));
Sushant Kaushik8bc7df22014-04-09 17:55:29 +05305809 hddLog(VOS_TRACE_LEVEL_INFO_HIGH, "device mode=%s (%d)",
5810 hdd_device_modetoString(pAdapter->device_mode),
5811 pAdapter->device_mode);
Jeff Johnson295189b2012-06-20 16:38:30 -07005812
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05305813 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
5814 status = wlan_hdd_validate_context(pHddCtx);
5815
5816 if (0 != status)
Jeff Johnson04dd8a82012-06-29 20:41:40 -07005817 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05305818 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
5819 "%s: HDD context is not valid", __func__);
5820 return status;
Jeff Johnson04dd8a82012-06-29 20:41:40 -07005821 }
5822
Agarwal Ashish51325b52014-06-16 16:50:49 +05305823 if (vos_max_concurrent_connections_reached()) {
5824 hddLog(VOS_TRACE_LEVEL_INFO, FL("Reached max concurrent connections"));
5825 return -EINVAL;
5826 }
5827
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305828 if ( (pAdapter->device_mode == WLAN_HDD_SOFTAP)
Jeff Johnson295189b2012-06-20 16:38:30 -07005829 || (pAdapter->device_mode == WLAN_HDD_P2P_GO)
Jeff Johnson295189b2012-06-20 16:38:30 -07005830 )
5831 {
5832 beacon_data_t *old,*new;
5833
5834 old = pAdapter->sessionCtx.ap.beacon;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305835
Jeff Johnson295189b2012-06-20 16:38:30 -07005836 if (old)
c_hpothu6ff1c3c2013-10-01 19:01:57 +05305837 {
5838 hddLog(VOS_TRACE_LEVEL_WARN,
5839 FL("already beacon info added to session(%d)"),
5840 pAdapter->sessionId);
Jeff Johnson295189b2012-06-20 16:38:30 -07005841 return -EALREADY;
c_hpothu6ff1c3c2013-10-01 19:01:57 +05305842 }
Jeff Johnson295189b2012-06-20 16:38:30 -07005843
5844 status = wlan_hdd_cfg80211_alloc_new_beacon(pAdapter,&new,params);
5845
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305846 if(status != VOS_STATUS_SUCCESS)
Jeff Johnson295189b2012-06-20 16:38:30 -07005847 {
5848 hddLog(VOS_TRACE_LEVEL_FATAL,
Arif Hussain6d2a3322013-11-17 19:50:10 -08005849 "%s:Error!!! Allocating the new beacon",__func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07005850 return -EINVAL;
5851 }
5852
5853 pAdapter->sessionCtx.ap.beacon = new;
5854
5855 status = wlan_hdd_cfg80211_start_bss(pAdapter, params);
5856 }
5857
5858 EXIT();
5859 return status;
5860}
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305861
5862static int wlan_hdd_cfg80211_set_beacon(struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -07005863 struct net_device *dev,
5864 struct beacon_parameters *params)
5865{
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305866 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +05305867 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
5868 hdd_context_t *pHddCtx;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05305869 int status;
Jeff Johnson295189b2012-06-20 16:38:30 -07005870
5871 ENTER();
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +05305872 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
5873 TRACE_CODE_HDD_CFG80211_SET_BEACON,
5874 pAdapter->sessionId, pHddStaCtx->conn_info.authType));
5875 hddLog(VOS_TRACE_LEVEL_INFO, "%s: device_mode = %s (%d)",
5876 __func__, hdd_device_modetoString(pAdapter->device_mode),
5877 pAdapter->device_mode);
5878
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05305879 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
5880 status = wlan_hdd_validate_context(pHddCtx);
5881
5882 if (0 != status)
Jeff Johnson04dd8a82012-06-29 20:41:40 -07005883 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05305884 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
5885 "%s: HDD context is not valid", __func__);
5886 return status;
Jeff Johnson04dd8a82012-06-29 20:41:40 -07005887 }
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +05305888
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305889 if ((pAdapter->device_mode == WLAN_HDD_SOFTAP)
Jeff Johnson295189b2012-06-20 16:38:30 -07005890 || (pAdapter->device_mode == WLAN_HDD_P2P_GO)
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305891 )
Jeff Johnson295189b2012-06-20 16:38:30 -07005892 {
5893 beacon_data_t *old,*new;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305894
Jeff Johnson295189b2012-06-20 16:38:30 -07005895 old = pAdapter->sessionCtx.ap.beacon;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305896
Jeff Johnson295189b2012-06-20 16:38:30 -07005897 if (!old)
c_hpothu6ff1c3c2013-10-01 19:01:57 +05305898 {
5899 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
5900 FL("session(%d) old and new heads points to NULL"),
5901 pAdapter->sessionId);
Jeff Johnson295189b2012-06-20 16:38:30 -07005902 return -ENOENT;
c_hpothu6ff1c3c2013-10-01 19:01:57 +05305903 }
Jeff Johnson295189b2012-06-20 16:38:30 -07005904
5905 status = wlan_hdd_cfg80211_alloc_new_beacon(pAdapter,&new,params);
5906
5907 if(status != VOS_STATUS_SUCCESS) {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305908 hddLog(VOS_TRACE_LEVEL_FATAL,
Arif Hussain6d2a3322013-11-17 19:50:10 -08005909 "%s: Error!!! Allocating the new beacon",__func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07005910 return -EINVAL;
5911 }
5912
5913 pAdapter->sessionCtx.ap.beacon = new;
5914
5915 status = wlan_hdd_cfg80211_start_bss(pAdapter, params);
5916 }
5917
5918 EXIT();
5919 return status;
5920}
5921
Jeff Johnson04dd8a82012-06-29 20:41:40 -07005922#endif //(LINUX_VERSION_CODE < KERNEL_VERSION(3,4,0))
5923
5924#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,4,0))
Jeff Johnson295189b2012-06-20 16:38:30 -07005925static int wlan_hdd_cfg80211_del_beacon(struct wiphy *wiphy,
5926 struct net_device *dev)
Jeff Johnson04dd8a82012-06-29 20:41:40 -07005927#else
5928static int wlan_hdd_cfg80211_stop_ap (struct wiphy *wiphy,
5929 struct net_device *dev)
5930#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07005931{
5932 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
Jeff Johnsone7245742012-09-05 17:12:55 -07005933 hdd_context_t *pHddCtx = NULL;
5934 hdd_scaninfo_t *pScanInfo = NULL;
5935 hdd_adapter_t *staAdapter = NULL;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05305936 VOS_STATUS status;
Mahesh A Saptasagar2395ee62014-05-21 19:12:21 +05305937 long ret;
Jeff Johnson295189b2012-06-20 16:38:30 -07005938
5939 ENTER();
5940
5941 if (NULL == pAdapter)
5942 {
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +05305943 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07005944 "%s: HDD adapter context is Null", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07005945 return -ENODEV;
5946 }
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -07005947
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05305948 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
5949 TRACE_CODE_HDD_CFG80211_STOP_AP,
5950 pAdapter->sessionId, pAdapter->device_mode));
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05305951 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
5952 status = wlan_hdd_validate_context(pHddCtx);
5953
5954 if (0 != status)
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -07005955 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05305956 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
5957 "%s: HDD context is not valid", __func__);
5958 return status;
Jeff Johnson4416a782013-03-25 14:17:50 -07005959 }
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -07005960
5961 staAdapter = hdd_get_adapter(pAdapter->pHddCtx, WLAN_HDD_INFRA_STATION);
5962 if (NULL == staAdapter)
5963 {
5964 staAdapter = hdd_get_adapter(pAdapter->pHddCtx, WLAN_HDD_P2P_CLIENT);
5965 if (NULL == staAdapter)
5966 {
Rajesh Chauhan52d885b2013-11-01 10:54:25 -07005967 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO_HIGH,
5968 "%s: HDD adapter context for STA/P2P-CLI is Null",
5969 __func__);
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -07005970 }
5971 }
5972
5973 pScanInfo = &pHddCtx->scan_info;
5974
Sushant Kaushik8bc7df22014-04-09 17:55:29 +05305975 hddLog(VOS_TRACE_LEVEL_INFO, "%s: device_mode = %s (%d)",
5976 __func__, hdd_device_modetoString(pAdapter->device_mode),
5977 pAdapter->device_mode);
Jeff Johnson295189b2012-06-20 16:38:30 -07005978
Mahesh A Saptasagar2395ee62014-05-21 19:12:21 +05305979 ret = wlan_hdd_scan_abort(pAdapter);
5980
Girish Gowli4bf7a632014-06-12 13:42:11 +05305981 if (ret < 0)
Jeff Johnsone7245742012-09-05 17:12:55 -07005982 {
Mahesh A Saptasagar2395ee62014-05-21 19:12:21 +05305983 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
5984 FL("Timeout occurred while waiting for abortscan %ld"), ret);
c_hpothu6ff1c3c2013-10-01 19:01:57 +05305985
Mahesh A Saptasagar2395ee62014-05-21 19:12:21 +05305986 if (pHddCtx->isLogpInProgress)
Jeff Johnsone7245742012-09-05 17:12:55 -07005987 {
Mahesh A Saptasagar2395ee62014-05-21 19:12:21 +05305988 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
5989 "%s: LOGP in Progress. Ignore!!!", __func__);
Yue Ma4f55ef32014-01-23 16:45:33 -08005990
Jeff Johnsone7245742012-09-05 17:12:55 -07005991 VOS_ASSERT(pScanInfo->mScanPending);
Mahesh A Saptasagar2395ee62014-05-21 19:12:21 +05305992 return -EAGAIN;
Jeff Johnsone7245742012-09-05 17:12:55 -07005993 }
Mahesh A Saptasagar2395ee62014-05-21 19:12:21 +05305994 VOS_ASSERT(pScanInfo->mScanPending);
Jeff Johnsone7245742012-09-05 17:12:55 -07005995 }
5996
Arun Kumar Khandavallia3bd8002014-01-17 16:21:19 +05305997 hdd_hostapd_stop(dev);
5998
Jeff Johnson295189b2012-06-20 16:38:30 -07005999 if ((pAdapter->device_mode == WLAN_HDD_SOFTAP)
Jeff Johnson295189b2012-06-20 16:38:30 -07006000 || (pAdapter->device_mode == WLAN_HDD_P2P_GO)
Jeff Johnson295189b2012-06-20 16:38:30 -07006001 )
6002 {
6003 beacon_data_t *old;
6004
6005 old = pAdapter->sessionCtx.ap.beacon;
6006
6007 if (!old)
c_hpothu6ff1c3c2013-10-01 19:01:57 +05306008 {
6009 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
6010 FL("session(%d) beacon data points to NULL"),
6011 pAdapter->sessionId);
Jeff Johnson295189b2012-06-20 16:38:30 -07006012 return -ENOENT;
c_hpothu6ff1c3c2013-10-01 19:01:57 +05306013 }
Jeff Johnson295189b2012-06-20 16:38:30 -07006014
Jeff Johnson295189b2012-06-20 16:38:30 -07006015 hdd_cleanup_actionframe(pHddCtx, pAdapter);
Jeff Johnson295189b2012-06-20 16:38:30 -07006016
6017 mutex_lock(&pHddCtx->sap_lock);
6018 if(test_bit(SOFTAP_BSS_STARTED, &pAdapter->event_flags))
6019 {
Jeff Johnson4416a782013-03-25 14:17:50 -07006020 if ( VOS_STATUS_SUCCESS == (status = WLANSAP_StopBss(pHddCtx->pvosContext) ) )
Jeff Johnson295189b2012-06-20 16:38:30 -07006021 {
6022 hdd_hostapd_state_t *pHostapdState = WLAN_HDD_GET_HOSTAP_STATE_PTR(pAdapter);
6023
6024 status = vos_wait_single_event(&pHostapdState->vosEvent, 10000);
6025
6026 if (!VOS_IS_STATUS_SUCCESS(status))
6027 {
6028 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Arif Hussain6d2a3322013-11-17 19:50:10 -08006029 ("ERROR: HDD vos wait for single_event failed!!"));
Jeff Johnson295189b2012-06-20 16:38:30 -07006030 VOS_ASSERT(0);
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05306031 }
6032 }
Jeff Johnson295189b2012-06-20 16:38:30 -07006033 clear_bit(SOFTAP_BSS_STARTED, &pAdapter->event_flags);
Agarwal Ashish51325b52014-06-16 16:50:49 +05306034 /* BSS stopped, clear the active sessions for this device mode */
6035 wlan_hdd_decr_active_session(pHddCtx, pAdapter->device_mode);
Jeff Johnson295189b2012-06-20 16:38:30 -07006036 }
6037 mutex_unlock(&pHddCtx->sap_lock);
6038
6039 if(status != VOS_STATUS_SUCCESS)
6040 {
6041 hddLog(VOS_TRACE_LEVEL_FATAL,
Arif Hussain6d2a3322013-11-17 19:50:10 -08006042 "%s:Error!!! Stopping the BSS",__func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07006043 return -EINVAL;
6044 }
6045
Jeff Johnson4416a782013-03-25 14:17:50 -07006046 if (ccmCfgSetInt(pHddCtx->hHal,
Jeff Johnson295189b2012-06-20 16:38:30 -07006047 WNI_CFG_PROBE_RSP_BCN_ADDNIE_FLAG, 0,NULL, eANI_BOOLEAN_FALSE)
6048 ==eHAL_STATUS_FAILURE)
6049 {
6050 hddLog(LOGE,
Arif Hussain6d2a3322013-11-17 19:50:10 -08006051 "Could not pass on WNI_CFG_PROBE_RSP_BCN_ADDNIE_FLAG to CCM");
Jeff Johnson295189b2012-06-20 16:38:30 -07006052 }
6053
Jeff Johnson4416a782013-03-25 14:17:50 -07006054 if ( eHAL_STATUS_FAILURE == ccmCfgSetInt(pHddCtx->hHal,
Jeff Johnson295189b2012-06-20 16:38:30 -07006055 WNI_CFG_ASSOC_RSP_ADDNIE_FLAG, 0, NULL,
6056 eANI_BOOLEAN_FALSE) )
6057 {
6058 hddLog(LOGE,
Arif Hussain6d2a3322013-11-17 19:50:10 -08006059 "Could not pass on WNI_CFG_ASSOC_RSP_ADDNIE_FLAG to CCM");
Jeff Johnson295189b2012-06-20 16:38:30 -07006060 }
6061
6062 // Reset WNI_CFG_PROBE_RSP Flags
6063 wlan_hdd_reset_prob_rspies(pAdapter);
6064
6065 pAdapter->sessionCtx.ap.beacon = NULL;
6066 kfree(old);
Madan Mohan Koyyalamudi26bd7142012-10-30 18:14:19 -07006067#ifdef WLAN_FEATURE_P2P_DEBUG
6068 if((pAdapter->device_mode == WLAN_HDD_P2P_GO) &&
6069 (globalP2PConnectionStatus == P2P_GO_COMPLETED_STATE))
6070 {
6071 hddLog(LOGE,"[P2P State] From GO completed to Inactive state "
6072 "GO got removed");
6073 globalP2PConnectionStatus = P2P_NOT_ACTIVE;
6074 }
6075#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07006076 }
6077 EXIT();
6078 return status;
6079}
Jeff Johnson04dd8a82012-06-29 20:41:40 -07006080
6081#if (LINUX_VERSION_CODE > KERNEL_VERSION(3,3,0))
6082
Pratik Bhalgata0c7f262012-11-22 17:40:24 +05306083static int wlan_hdd_cfg80211_start_ap(struct wiphy *wiphy,
6084 struct net_device *dev,
Jeff Johnson04dd8a82012-06-29 20:41:40 -07006085 struct cfg80211_ap_settings *params)
6086{
Pratik Bhalgata0c7f262012-11-22 17:40:24 +05306087 hdd_adapter_t *pAdapter;
6088 hdd_context_t *pHddCtx;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05306089 int status;
Jeff Johnson04dd8a82012-06-29 20:41:40 -07006090
6091 ENTER();
6092
Pratik Bhalgata0c7f262012-11-22 17:40:24 +05306093 if (NULL == dev)
Madan Mohan Koyyalamudib2c36892012-10-18 20:52:38 -07006094 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05306095 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Pratik Bhalgata0c7f262012-11-22 17:40:24 +05306096 "%s: Device is Null", __func__);
6097 return -ENODEV;
6098 }
6099
6100 pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
6101 if (NULL == pAdapter)
6102 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05306103 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Pratik Bhalgata0c7f262012-11-22 17:40:24 +05306104 "%s: HDD adapter is Null", __func__);
6105 return -ENODEV;
6106 }
6107
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05306108 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
6109 TRACE_CODE_HDD_CFG80211_START_AP, pAdapter->sessionId,
6110 params-> beacon_interval));
Pratik Bhalgata0c7f262012-11-22 17:40:24 +05306111 if (WLAN_HDD_ADAPTER_MAGIC != pAdapter->magic)
6112 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05306113 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Pratik Bhalgata0c7f262012-11-22 17:40:24 +05306114 "%s: HDD adapter magic is invalid", __func__);
6115 return -ENODEV;
6116 }
6117
6118 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05306119 status = wlan_hdd_validate_context(pHddCtx);
Pratik Bhalgata0c7f262012-11-22 17:40:24 +05306120
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05306121 if (0 != status)
Pratik Bhalgata0c7f262012-11-22 17:40:24 +05306122 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05306123 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
6124 "%s: HDD context is not valid", __func__);
6125 return status;
Pratik Bhalgata0c7f262012-11-22 17:40:24 +05306126 }
6127
Sushant Kaushik8bc7df22014-04-09 17:55:29 +05306128 hddLog(VOS_TRACE_LEVEL_INFO_HIGH, "%s: device mode = %s (%d)",
6129 __func__, hdd_device_modetoString(pAdapter->device_mode),
6130 pAdapter->device_mode);
Pratik Bhalgata0c7f262012-11-22 17:40:24 +05306131
6132 if ((pAdapter->device_mode == WLAN_HDD_SOFTAP)
Jeff Johnson04dd8a82012-06-29 20:41:40 -07006133 || (pAdapter->device_mode == WLAN_HDD_P2P_GO)
Jeff Johnson04dd8a82012-06-29 20:41:40 -07006134 )
6135 {
Pratik Bhalgata0c7f262012-11-22 17:40:24 +05306136 beacon_data_t *old, *new;
Jeff Johnson04dd8a82012-06-29 20:41:40 -07006137
6138 old = pAdapter->sessionCtx.ap.beacon;
Pratik Bhalgata0c7f262012-11-22 17:40:24 +05306139
Jeff Johnson04dd8a82012-06-29 20:41:40 -07006140 if (old)
c_hpothu6ff1c3c2013-10-01 19:01:57 +05306141 {
6142 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_WARN,
6143 FL("already beacon info added to session(%d)"),
6144 pAdapter->sessionId);
Jeff Johnson04dd8a82012-06-29 20:41:40 -07006145 return -EALREADY;
c_hpothu6ff1c3c2013-10-01 19:01:57 +05306146 }
Jeff Johnson04dd8a82012-06-29 20:41:40 -07006147
6148 status = wlan_hdd_cfg80211_alloc_new_beacon(pAdapter, &new, &params->beacon, params->dtim_period);
6149
Pratik Bhalgata0c7f262012-11-22 17:40:24 +05306150 if (status != 0)
Jeff Johnson04dd8a82012-06-29 20:41:40 -07006151 {
6152 hddLog(VOS_TRACE_LEVEL_FATAL,
Pratik Bhalgata0c7f262012-11-22 17:40:24 +05306153 "%s:Error!!! Allocating the new beacon", __func__);
Jeff Johnson04dd8a82012-06-29 20:41:40 -07006154 return -EINVAL;
6155 }
6156 pAdapter->sessionCtx.ap.beacon = new;
Viral Modi3a32cc52013-02-08 11:14:52 -08006157#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,6,0))
Yue Maf49ba872013-08-19 12:04:25 -07006158 wlan_hdd_cfg80211_set_channel(wiphy, dev,
6159#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,8,0))
6160 params->channel, params->channel_type);
6161#else
6162 params->chandef.chan, cfg80211_get_chandef_type(&(params->chandef)));
6163#endif
Viral Modi3a32cc52013-02-08 11:14:52 -08006164#endif
Jeff Johnson04dd8a82012-06-29 20:41:40 -07006165 status = wlan_hdd_cfg80211_start_bss(pAdapter, &params->beacon, params->ssid,
6166 params->ssid_len, params->hidden_ssid);
6167 }
6168
6169 EXIT();
6170 return status;
6171}
6172
6173
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306174static int wlan_hdd_cfg80211_change_beacon(struct wiphy *wiphy,
Jeff Johnson04dd8a82012-06-29 20:41:40 -07006175 struct net_device *dev,
6176 struct cfg80211_beacon_data *params)
6177{
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306178 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +05306179 hdd_context_t *pHddCtx;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05306180 int status;
Jeff Johnson04dd8a82012-06-29 20:41:40 -07006181
6182 ENTER();
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +05306183
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05306184 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
6185 TRACE_CODE_HDD_CFG80211_CHANGE_BEACON,
6186 pAdapter->sessionId, pAdapter->device_mode));
Arif Hussain6d2a3322013-11-17 19:50:10 -08006187 hddLog(VOS_TRACE_LEVEL_INFO, "%s: device_mode = %d",
Jeff Johnson04dd8a82012-06-29 20:41:40 -07006188 __func__, pAdapter->device_mode);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05306189
6190 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
6191 status = wlan_hdd_validate_context(pHddCtx);
6192
6193 if (0 != status)
Madan Mohan Koyyalamudib2c36892012-10-18 20:52:38 -07006194 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05306195 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
6196 "%s: HDD context is not valid", __func__);
6197 return status;
Madan Mohan Koyyalamudib2c36892012-10-18 20:52:38 -07006198 }
Jeff Johnson04dd8a82012-06-29 20:41:40 -07006199
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306200 if ((pAdapter->device_mode == WLAN_HDD_SOFTAP)
Jeff Johnson04dd8a82012-06-29 20:41:40 -07006201 || (pAdapter->device_mode == WLAN_HDD_P2P_GO)
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306202 )
Jeff Johnson04dd8a82012-06-29 20:41:40 -07006203 {
6204 beacon_data_t *old,*new;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306205
Jeff Johnson04dd8a82012-06-29 20:41:40 -07006206 old = pAdapter->sessionCtx.ap.beacon;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306207
Jeff Johnson04dd8a82012-06-29 20:41:40 -07006208 if (!old)
c_hpothu6ff1c3c2013-10-01 19:01:57 +05306209 {
6210 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
6211 FL("session(%d) beacon data points to NULL"),
6212 pAdapter->sessionId);
Jeff Johnson04dd8a82012-06-29 20:41:40 -07006213 return -ENOENT;
c_hpothu6ff1c3c2013-10-01 19:01:57 +05306214 }
Jeff Johnson04dd8a82012-06-29 20:41:40 -07006215
6216 status = wlan_hdd_cfg80211_alloc_new_beacon(pAdapter, &new, params, 0);
6217
6218 if(status != VOS_STATUS_SUCCESS) {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306219 hddLog(VOS_TRACE_LEVEL_FATAL,
Arif Hussain6d2a3322013-11-17 19:50:10 -08006220 "%s: Error!!! Allocating the new beacon",__func__);
Jeff Johnson04dd8a82012-06-29 20:41:40 -07006221 return -EINVAL;
6222 }
6223
6224 pAdapter->sessionCtx.ap.beacon = new;
6225
6226 status = wlan_hdd_cfg80211_start_bss(pAdapter, params, NULL, 0, 0);
6227 }
6228
6229 EXIT();
6230 return status;
6231}
6232
6233#endif //(LINUX_VERSION_CODE > KERNEL_VERSION(3,3,0))
6234
Jeff Johnson295189b2012-06-20 16:38:30 -07006235
Mahesh A Saptasagar179d2252014-06-02 21:32:21 +05306236static int __wlan_hdd_cfg80211_change_bss (struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -07006237 struct net_device *dev,
6238 struct bss_parameters *params)
6239{
6240 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
6241
6242 ENTER();
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +05306243
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05306244 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
6245 TRACE_CODE_HDD_CFG80211_CHANGE_BSS,
6246 pAdapter->sessionId, params->ap_isolate));
Sushant Kaushik8bc7df22014-04-09 17:55:29 +05306247 hddLog(VOS_TRACE_LEVEL_INFO, "%s: device_mode = %s (%d)",
6248 __func__, hdd_device_modetoString(pAdapter->device_mode),
6249 pAdapter->device_mode);
Jeff Johnson295189b2012-06-20 16:38:30 -07006250
6251 if((pAdapter->device_mode == WLAN_HDD_SOFTAP)
Jeff Johnson295189b2012-06-20 16:38:30 -07006252 || (pAdapter->device_mode == WLAN_HDD_P2P_GO)
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306253 )
Jeff Johnson295189b2012-06-20 16:38:30 -07006254 {
6255 /* ap_isolate == -1 means that in change bss, upper layer doesn't
6256 * want to update this parameter */
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306257 if (-1 != params->ap_isolate)
Jeff Johnson295189b2012-06-20 16:38:30 -07006258 {
6259 pAdapter->sessionCtx.ap.apDisableIntraBssFwd = !!params->ap_isolate;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306260 }
Jeff Johnson295189b2012-06-20 16:38:30 -07006261 }
6262
6263 EXIT();
6264 return 0;
6265}
6266
Mahesh A Saptasagar179d2252014-06-02 21:32:21 +05306267static int wlan_hdd_cfg80211_change_bss (struct wiphy *wiphy,
6268 struct net_device *dev,
6269 struct bss_parameters *params)
6270{
6271 int ret;
6272
6273 vos_ssr_protect(__func__);
6274 ret = __wlan_hdd_cfg80211_change_bss(wiphy, dev, params);
6275 vos_ssr_unprotect(__func__);
6276
6277 return ret;
6278}
Kiet Lam10841362013-11-01 11:36:50 +05306279/* FUNCTION: wlan_hdd_change_country_code_cd
6280* to wait for contry code completion
6281*/
6282void* wlan_hdd_change_country_code_cb(void *pAdapter)
6283{
6284 hdd_adapter_t *call_back_pAdapter = pAdapter;
6285 complete(&call_back_pAdapter->change_country_code);
6286 return NULL;
6287}
6288
Jeff Johnson295189b2012-06-20 16:38:30 -07006289/*
Mahesh A Saptasagar0e59c472014-04-14 19:17:41 +05306290 * FUNCTION: __wlan_hdd_cfg80211_change_iface
Jeff Johnson295189b2012-06-20 16:38:30 -07006291 * This function is used to set the interface type (INFRASTRUCTURE/ADHOC)
6292 */
Mahesh A Saptasagar0e59c472014-04-14 19:17:41 +05306293int __wlan_hdd_cfg80211_change_iface( struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -07006294 struct net_device *ndev,
6295 enum nl80211_iftype type,
6296 u32 *flags,
6297 struct vif_params *params
6298 )
6299{
6300 struct wireless_dev *wdev;
6301 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( ndev );
Rajesh Chauhana0516c62014-01-30 16:11:18 -08006302 hdd_context_t *pHddCtx;
Mohit Khanna0f232092012-09-11 14:46:08 -07006303 hdd_adapter_t *pP2pAdapter = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -07006304 tCsrRoamProfile *pRoamProfile = NULL;
6305 eCsrRoamBssType LastBSSType;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05306306 hdd_config_t *pConfig = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -07006307 eMib_dot11DesiredBssType connectedBssType;
6308 VOS_STATUS status;
c_hpothu6ff1c3c2013-10-01 19:01:57 +05306309 long ret;
Jeff Johnson295189b2012-06-20 16:38:30 -07006310
6311 ENTER();
6312
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05306313 if (!pAdapter)
Rajesh Chauhana0516c62014-01-30 16:11:18 -08006314 {
6315 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
6316 "%s: Adapter context is null", __func__);
6317 return VOS_STATUS_E_FAILURE;
6318 }
6319
6320 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
6321 if (!pHddCtx)
6322 {
6323 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
6324 "%s: HDD context is null", __func__);
6325 return VOS_STATUS_E_FAILURE;
6326 }
6327
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05306328 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
6329 TRACE_CODE_HDD_CFG80211_CHANGE_IFACE,
6330 pAdapter->sessionId, type));
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05306331 status = wlan_hdd_validate_context(pHddCtx);
6332
6333 if (0 != status)
Jeff Johnson295189b2012-06-20 16:38:30 -07006334 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05306335 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
6336 "%s: HDD context is not valid", __func__);
6337 return status;
Jeff Johnson295189b2012-06-20 16:38:30 -07006338 }
6339
Sushant Kaushik8bc7df22014-04-09 17:55:29 +05306340 hddLog(VOS_TRACE_LEVEL_INFO, "%s: device_mode = %s (%d)",
6341 __func__, hdd_device_modetoString(pAdapter->device_mode),
6342 pAdapter->device_mode);
Jeff Johnson295189b2012-06-20 16:38:30 -07006343
Agarwal Ashish51325b52014-06-16 16:50:49 +05306344 if (vos_max_concurrent_connections_reached()) {
6345 hddLog(VOS_TRACE_LEVEL_INFO, FL("Reached max concurrent connections"));
6346 return -EINVAL;
6347 }
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05306348 pConfig = pHddCtx->cfg_ini;
Jeff Johnson295189b2012-06-20 16:38:30 -07006349 wdev = ndev->ieee80211_ptr;
6350
6351#ifdef WLAN_BTAMP_FEATURE
6352 if((NL80211_IFTYPE_P2P_CLIENT == type)||
6353 (NL80211_IFTYPE_ADHOC == type)||
6354 (NL80211_IFTYPE_AP == type)||
6355 (NL80211_IFTYPE_P2P_GO == type))
6356 {
6357 pHddCtx->isAmpAllowed = VOS_FALSE;
6358 // stop AMP traffic
6359 status = WLANBAP_StopAmp();
6360 if(VOS_STATUS_SUCCESS != status )
6361 {
6362 pHddCtx->isAmpAllowed = VOS_TRUE;
6363 hddLog(VOS_TRACE_LEVEL_FATAL,
6364 "%s: Failed to stop AMP", __func__);
6365 return -EINVAL;
6366 }
6367 }
6368#endif //WLAN_BTAMP_FEATURE
6369 /* Reset the current device mode bit mask*/
6370 wlan_hdd_clear_concurrency_mode(pHddCtx, pAdapter->device_mode);
6371
6372 if( (pAdapter->device_mode == WLAN_HDD_INFRA_STATION)
Jeff Johnson295189b2012-06-20 16:38:30 -07006373 || (pAdapter->device_mode == WLAN_HDD_P2P_CLIENT)
Jeff Johnsone7245742012-09-05 17:12:55 -07006374 || (pAdapter->device_mode == WLAN_HDD_P2P_DEVICE)
Jeff Johnson295189b2012-06-20 16:38:30 -07006375 )
6376 {
6377 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
Rajesh Chauhana0516c62014-01-30 16:11:18 -08006378 if (!pWextState)
6379 {
6380 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
6381 "%s: pWextState is null", __func__);
6382 return VOS_STATUS_E_FAILURE;
6383 }
Jeff Johnson295189b2012-06-20 16:38:30 -07006384 pRoamProfile = &pWextState->roamProfile;
6385 LastBSSType = pRoamProfile->BSSType;
6386
6387 switch (type)
6388 {
6389 case NL80211_IFTYPE_STATION:
Jeff Johnson295189b2012-06-20 16:38:30 -07006390 case NL80211_IFTYPE_P2P_CLIENT:
Jeff Johnson295189b2012-06-20 16:38:30 -07006391 hddLog(VOS_TRACE_LEVEL_INFO,
6392 "%s: setting interface Type to INFRASTRUCTURE", __func__);
6393 pRoamProfile->BSSType = eCSR_BSS_TYPE_INFRASTRUCTURE;
Jeff Johnsone7245742012-09-05 17:12:55 -07006394#ifdef WLAN_FEATURE_11AC
6395 if(pConfig->dot11Mode == eHDD_DOT11_MODE_AUTO)
6396 {
6397 pConfig->dot11Mode = eHDD_DOT11_MODE_11ac;
6398 }
6399#endif
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306400 pRoamProfile->phyMode =
Jeff Johnsone7245742012-09-05 17:12:55 -07006401 hdd_cfg_xlate_to_csr_phy_mode(pConfig->dot11Mode);
Jeff Johnson295189b2012-06-20 16:38:30 -07006402 wdev->iftype = type;
Gopichand Nakkalaf527dc62012-12-31 16:35:10 -08006403 //Check for sub-string p2p to confirm its a p2p interface
6404 if (NULL != strstr(ndev->name,"p2p"))
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306405 {
Gopichand Nakkala864d3552012-12-31 16:08:51 -08006406 pAdapter->device_mode = (type == NL80211_IFTYPE_STATION) ?
6407 WLAN_HDD_P2P_DEVICE : WLAN_HDD_P2P_CLIENT;
6408 }
6409 else
6410 {
6411 pAdapter->device_mode = (type == NL80211_IFTYPE_STATION) ?
Jeff Johnson295189b2012-06-20 16:38:30 -07006412 WLAN_HDD_INFRA_STATION: WLAN_HDD_P2P_CLIENT;
Gopichand Nakkala864d3552012-12-31 16:08:51 -08006413 }
Madan Mohan Koyyalamudi81746922013-07-17 14:38:51 +05306414#ifdef FEATURE_WLAN_TDLS
6415 /* The open adapter for the p2p shall skip initializations in
6416 * tdls_init if the device mode is WLAN_HDD_P2P_DEVICE, for
6417 * TDLS is supported only on WLAN_HDD_P2P_CLIENT. Hence invoke
6418 * tdls_init when the change_iface sets the device mode to
6419 * WLAN_HDD_P2P_CLIENT.
6420 */
6421
6422 if ( pAdapter->device_mode == WLAN_HDD_P2P_CLIENT)
6423 {
Agarwal Ashish4b87f922014-06-18 03:03:21 +05306424 if (0 != wlan_hdd_sta_tdls_init (pAdapter))
Madan Mohan Koyyalamudi81746922013-07-17 14:38:51 +05306425 {
c_hpothu6ff1c3c2013-10-01 19:01:57 +05306426 hddLog(VOS_TRACE_LEVEL_ERROR,
6427 "%s: tdls initialization failed", __func__);
Madan Mohan Koyyalamudi81746922013-07-17 14:38:51 +05306428 return -EINVAL;
6429 }
6430 }
6431#endif
6432
Jeff Johnson295189b2012-06-20 16:38:30 -07006433 break;
6434 case NL80211_IFTYPE_ADHOC:
6435 hddLog(VOS_TRACE_LEVEL_INFO,
6436 "%s: setting interface Type to ADHOC", __func__);
6437 pRoamProfile->BSSType = eCSR_BSS_TYPE_START_IBSS;
6438 pRoamProfile->phyMode =
6439 hdd_cfg_xlate_to_csr_phy_mode(pConfig->dot11Mode);
Shailender Karmuchia734f332013-04-19 14:02:48 -07006440 pAdapter->device_mode = WLAN_HDD_IBSS;
Jeff Johnson295189b2012-06-20 16:38:30 -07006441 wdev->iftype = type;
6442 break;
6443
6444 case NL80211_IFTYPE_AP:
Jeff Johnson295189b2012-06-20 16:38:30 -07006445 case NL80211_IFTYPE_P2P_GO:
Jeff Johnson295189b2012-06-20 16:38:30 -07006446 {
6447 hddLog(VOS_TRACE_LEVEL_INFO_HIGH,
6448 "%s: setting interface Type to %s", __func__,
6449 (type == NL80211_IFTYPE_AP) ? "SoftAP" : "P2pGo");
6450
Gopichand Nakkalaf527dc62012-12-31 16:35:10 -08006451 //Cancel any remain on channel for GO mode
6452 if (NL80211_IFTYPE_P2P_GO == type)
6453 {
6454 wlan_hdd_cancel_existing_remain_on_channel(pAdapter);
6455 }
Mohit Khanna0f232092012-09-11 14:46:08 -07006456 if (NL80211_IFTYPE_AP == type)
6457 {
6458 /* As Loading WLAN Driver one interface being created for p2p device
6459 * address. This will take one HW STA and the max number of clients
6460 * that can connect to softAP will be reduced by one. so while changing
6461 * the interface type to NL80211_IFTYPE_AP (SoftAP) remove p2p0
6462 * interface as it is not required in SoftAP mode.
6463 */
6464
6465 // Get P2P Adapter
6466 pP2pAdapter = hdd_get_adapter(pHddCtx, WLAN_HDD_P2P_DEVICE);
6467
6468 if (pP2pAdapter)
6469 {
Agarwal Ashish3a38bd12014-06-12 15:16:52 +05306470 hdd_stop_adapter(pHddCtx, pP2pAdapter, VOS_TRUE);
Mohit Khanna0f232092012-09-11 14:46:08 -07006471 hdd_deinit_adapter(pHddCtx, pP2pAdapter);
6472 hdd_close_adapter(pHddCtx, pP2pAdapter, VOS_TRUE);
6473 }
6474 }
Swaroop Goltia2e32212014-04-09 23:37:33 +05306475 //Disable IMPS & BMPS for SAP/GO
6476 if(VOS_STATUS_E_FAILURE ==
6477 hdd_disable_bmps_imps(pHddCtx, WLAN_HDD_P2P_GO))
6478 {
6479 //Fail to Exit BMPS
6480 VOS_ASSERT(0);
6481 }
Madan Mohan Koyyalamudi96797442013-10-08 16:04:42 +05306482#ifdef FEATURE_WLAN_TDLS
Mohit Khanna0f232092012-09-11 14:46:08 -07006483
Madan Mohan Koyyalamudi96797442013-10-08 16:04:42 +05306484 /* A Mutex Lock is introduced while changing the mode to
6485 * protect the concurrent access for the Adapters by TDLS
6486 * module.
6487 */
Rajesh Chauhana34c6e62014-03-25 16:37:58 +05306488 mutex_lock(&pHddCtx->tdls_lock);
Madan Mohan Koyyalamudi96797442013-10-08 16:04:42 +05306489#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07006490 //De-init the adapter.
Agarwal Ashish3a38bd12014-06-12 15:16:52 +05306491 hdd_stop_adapter( pHddCtx, pAdapter, VOS_TRUE );
Jeff Johnson295189b2012-06-20 16:38:30 -07006492 hdd_deinit_adapter( pHddCtx, pAdapter );
6493 memset(&pAdapter->sessionCtx, 0, sizeof(pAdapter->sessionCtx));
Jeff Johnson295189b2012-06-20 16:38:30 -07006494 pAdapter->device_mode = (type == NL80211_IFTYPE_AP) ?
6495 WLAN_HDD_SOFTAP : WLAN_HDD_P2P_GO;
Madan Mohan Koyyalamudi96797442013-10-08 16:04:42 +05306496#ifdef FEATURE_WLAN_TDLS
6497 mutex_unlock(&pHddCtx->tdls_lock);
6498#endif
Madan Mohan Koyyalamudi3ff2a0b2012-10-15 14:33:46 -07006499 if ((WLAN_HDD_SOFTAP == pAdapter->device_mode) &&
6500 (pConfig->apRandomBssidEnabled))
6501 {
6502 /* To meet Android requirements create a randomized
6503 MAC address of the form 02:1A:11:Fx:xx:xx */
6504 get_random_bytes(&ndev->dev_addr[3], 3);
6505 ndev->dev_addr[0] = 0x02;
6506 ndev->dev_addr[1] = 0x1A;
6507 ndev->dev_addr[2] = 0x11;
6508 ndev->dev_addr[3] |= 0xF0;
6509 memcpy(pAdapter->macAddressCurrent.bytes, ndev->dev_addr,
6510 VOS_MAC_ADDR_SIZE);
Arif Hussain24bafea2013-11-15 15:10:03 -08006511 pr_info("wlan: Generated HotSpot BSSID " MAC_ADDRESS_STR"\n",
6512 MAC_ADDR_ARRAY(ndev->dev_addr));
Madan Mohan Koyyalamudi3ff2a0b2012-10-15 14:33:46 -07006513 }
6514
Jeff Johnson295189b2012-06-20 16:38:30 -07006515 hdd_set_ap_ops( pAdapter->dev );
6516
Kiet Lam10841362013-11-01 11:36:50 +05306517 /* This is for only SAP mode where users can
6518 * control country through ini.
6519 * P2P GO follows station country code
6520 * acquired during the STA scanning. */
6521 if((NL80211_IFTYPE_AP == type) &&
6522 (memcmp(pConfig->apCntryCode, CFG_AP_COUNTRY_CODE_DEFAULT, 3) != 0))
6523 {
6524 int status = 0;
6525 VOS_TRACE(VOS_MODULE_ID_HDD,VOS_TRACE_LEVEL_INFO,
6526 "%s: setting country code from INI ", __func__);
6527 init_completion(&pAdapter->change_country_code);
6528 status = (int)sme_ChangeCountryCode(pHddCtx->hHal,
6529 (void *)(tSmeChangeCountryCallback)
6530 wlan_hdd_change_country_code_cb,
6531 pConfig->apCntryCode, pAdapter,
6532 pHddCtx->pvosContext,
Abhishek Singha306a442013-11-07 18:39:01 +05306533 eSIR_FALSE,
6534 eSIR_TRUE);
Kiet Lam10841362013-11-01 11:36:50 +05306535 if (eHAL_STATUS_SUCCESS == status)
6536 {
6537 /* Wait for completion */
c_hpothu6ff1c3c2013-10-01 19:01:57 +05306538 ret = wait_for_completion_interruptible_timeout(
Kiet Lam10841362013-11-01 11:36:50 +05306539 &pAdapter->change_country_code,
6540 msecs_to_jiffies(WLAN_WAIT_TIME_COUNTRY));
c_hpothu6ff1c3c2013-10-01 19:01:57 +05306541 if (ret <= 0)
Kiet Lam10841362013-11-01 11:36:50 +05306542 {
6543 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
c_hpothu6ff1c3c2013-10-01 19:01:57 +05306544 FL("SME Timed out while setting country code %ld"),
6545 ret);
Yue Ma4f55ef32014-01-23 16:45:33 -08006546
6547 if (pHddCtx->isLogpInProgress)
6548 {
6549 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
6550 "%s: LOGP in Progress. Ignore!!!", __func__);
6551 return -EAGAIN;
6552 }
Kiet Lam10841362013-11-01 11:36:50 +05306553 }
6554 }
6555 else
6556 {
6557 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Arif Hussain6d2a3322013-11-17 19:50:10 -08006558 "%s: SME Change Country code failed",__func__);
Kiet Lam10841362013-11-01 11:36:50 +05306559 return -EINVAL;
6560 }
6561 }
Jeff Johnson295189b2012-06-20 16:38:30 -07006562 status = hdd_init_ap_mode(pAdapter);
6563 if(status != VOS_STATUS_SUCCESS)
6564 {
6565 hddLog(VOS_TRACE_LEVEL_FATAL,
6566 "%s: Error initializing the ap mode", __func__);
6567 return -EINVAL;
6568 }
6569 hdd_set_conparam(1);
6570
Jeff Johnson295189b2012-06-20 16:38:30 -07006571 /*interface type changed update in wiphy structure*/
6572 if(wdev)
6573 {
6574 wdev->iftype = type;
6575 pHddCtx->change_iface = type;
6576 }
6577 else
6578 {
6579 hddLog(VOS_TRACE_LEVEL_ERROR,
6580 "%s: ERROR !!!! Wireless dev is NULL", __func__);
6581 return -EINVAL;
6582 }
6583 goto done;
6584 }
6585
6586 default:
6587 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Unsupported interface Type",
6588 __func__);
6589 return -EOPNOTSUPP;
6590 }
6591 }
6592 else if ( (pAdapter->device_mode == WLAN_HDD_SOFTAP)
Jeff Johnson295189b2012-06-20 16:38:30 -07006593 || (pAdapter->device_mode == WLAN_HDD_P2P_GO)
Jeff Johnson295189b2012-06-20 16:38:30 -07006594 )
6595 {
6596 switch(type)
6597 {
6598 case NL80211_IFTYPE_STATION:
Jeff Johnson295189b2012-06-20 16:38:30 -07006599 case NL80211_IFTYPE_P2P_CLIENT:
Jeff Johnson295189b2012-06-20 16:38:30 -07006600 case NL80211_IFTYPE_ADHOC:
Madan Mohan Koyyalamudi96797442013-10-08 16:04:42 +05306601#ifdef FEATURE_WLAN_TDLS
6602
6603 /* A Mutex Lock is introduced while changing the mode to
6604 * protect the concurrent access for the Adapters by TDLS
6605 * module.
6606 */
Rajesh Chauhana34c6e62014-03-25 16:37:58 +05306607 mutex_lock(&pHddCtx->tdls_lock);
Madan Mohan Koyyalamudi96797442013-10-08 16:04:42 +05306608#endif
Agarwal Ashish3a38bd12014-06-12 15:16:52 +05306609 hdd_stop_adapter( pHddCtx, pAdapter, VOS_TRUE );
Jeff Johnson32d95a32012-09-10 13:15:23 -07006610 hdd_deinit_adapter( pHddCtx, pAdapter );
Jeff Johnson295189b2012-06-20 16:38:30 -07006611 wdev->iftype = type;
Gopichand Nakkalaf527dc62012-12-31 16:35:10 -08006612 //Check for sub-string p2p to confirm its a p2p interface
6613 if (NULL != strstr(ndev->name,"p2p"))
Gopichand Nakkala864d3552012-12-31 16:08:51 -08006614 {
6615 pAdapter->device_mode = (type == NL80211_IFTYPE_STATION) ?
6616 WLAN_HDD_P2P_DEVICE : WLAN_HDD_P2P_CLIENT;
6617 }
6618 else
6619 {
6620 pAdapter->device_mode = (type == NL80211_IFTYPE_STATION) ?
Jeff Johnson295189b2012-06-20 16:38:30 -07006621 WLAN_HDD_INFRA_STATION: WLAN_HDD_P2P_CLIENT;
Gopichand Nakkala864d3552012-12-31 16:08:51 -08006622 }
Jeff Johnson295189b2012-06-20 16:38:30 -07006623 hdd_set_conparam(0);
6624 pHddCtx->change_iface = type;
Jeff Johnson295189b2012-06-20 16:38:30 -07006625 memset(&pAdapter->sessionCtx, 0, sizeof(pAdapter->sessionCtx));
6626 hdd_set_station_ops( pAdapter->dev );
Madan Mohan Koyyalamudi96797442013-10-08 16:04:42 +05306627#ifdef FEATURE_WLAN_TDLS
6628 mutex_unlock(&pHddCtx->tdls_lock);
6629#endif
Sunil Dutt66485cb2013-12-19 19:05:03 +05306630 status = hdd_init_station_mode( pAdapter );
Jeff Johnson295189b2012-06-20 16:38:30 -07006631 if( VOS_STATUS_SUCCESS != status )
6632 return -EOPNOTSUPP;
Jeff Johnsone7245742012-09-05 17:12:55 -07006633 /* In case of JB, for P2P-GO, only change interface will be called,
6634 * This is the right place to enable back bmps_imps()
6635 */
Gopichand Nakkalaa2fe5b02013-06-06 16:32:28 +05306636 if (pHddCtx->hdd_wlan_suspended)
6637 {
6638 hdd_set_pwrparams(pHddCtx);
6639 }
Jeff Johnsone7245742012-09-05 17:12:55 -07006640 hdd_enable_bmps_imps(pHddCtx);
Jeff Johnson295189b2012-06-20 16:38:30 -07006641 goto done;
6642 case NL80211_IFTYPE_AP:
Jeff Johnson295189b2012-06-20 16:38:30 -07006643 case NL80211_IFTYPE_P2P_GO:
Jeff Johnson295189b2012-06-20 16:38:30 -07006644 wdev->iftype = type;
Jeff Johnson295189b2012-06-20 16:38:30 -07006645 pAdapter->device_mode = (type == NL80211_IFTYPE_AP) ?
6646 WLAN_HDD_SOFTAP : WLAN_HDD_P2P_GO;
Jeff Johnson295189b2012-06-20 16:38:30 -07006647 goto done;
6648 default:
6649 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Unsupported interface Type",
6650 __func__);
6651 return -EOPNOTSUPP;
6652
6653 }
6654
6655 }
6656 else
6657 {
Sushant Kaushik8bc7df22014-04-09 17:55:29 +05306658 hddLog(VOS_TRACE_LEVEL_ERROR,"%s: unsupported device mode(%s (%d))",
6659 __func__, hdd_device_modetoString(pAdapter->device_mode),
6660 pAdapter->device_mode);
Jeff Johnson295189b2012-06-20 16:38:30 -07006661 return -EOPNOTSUPP;
6662 }
6663
6664
6665 if(pRoamProfile)
6666 {
6667 if ( LastBSSType != pRoamProfile->BSSType )
6668 {
6669 /*interface type changed update in wiphy structure*/
6670 wdev->iftype = type;
6671
6672 /*the BSS mode changed, We need to issue disconnect
6673 if connected or in IBSS disconnect state*/
6674 if ( hdd_connGetConnectedBssType(
6675 WLAN_HDD_GET_STATION_CTX_PTR(pAdapter), &connectedBssType ) ||
6676 ( eCSR_BSS_TYPE_START_IBSS == LastBSSType ) )
6677 {
6678 /*need to issue a disconnect to CSR.*/
6679 INIT_COMPLETION(pAdapter->disconnect_comp_var);
6680 if( eHAL_STATUS_SUCCESS ==
6681 sme_RoamDisconnect( WLAN_HDD_GET_HAL_CTX(pAdapter),
6682 pAdapter->sessionId,
6683 eCSR_DISCONNECT_REASON_UNSPECIFIED ) )
6684 {
c_hpothu6ff1c3c2013-10-01 19:01:57 +05306685 ret = wait_for_completion_interruptible_timeout(
6686 &pAdapter->disconnect_comp_var,
6687 msecs_to_jiffies(WLAN_WAIT_TIME_DISCONNECT));
6688 if (ret <= 0)
6689 {
6690 hddLog(VOS_TRACE_LEVEL_ERROR,
6691 FL("wait on disconnect_comp_var failed %ld"), ret);
6692 }
Jeff Johnson295189b2012-06-20 16:38:30 -07006693 }
6694 }
6695 }
6696 }
6697
6698done:
6699 /*set bitmask based on updated value*/
6700 wlan_hdd_set_concurrency_mode(pHddCtx, pAdapter->device_mode);
Leo Chang6fe1f922013-06-07 19:21:24 -07006701
6702 /* Only STA mode support TM now
6703 * all other mode, TM feature should be disabled */
6704 if ( (pHddCtx->cfg_ini->thermalMitigationEnable) &&
6705 (~VOS_STA & pHddCtx->concurrency_mode) )
6706 {
6707 hddDevTmLevelChangedHandler(pHddCtx->parent_dev, 0);
6708 }
6709
Jeff Johnson295189b2012-06-20 16:38:30 -07006710#ifdef WLAN_BTAMP_FEATURE
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306711 if((NL80211_IFTYPE_STATION == type) && (pHddCtx->concurrency_mode <= 1) &&
Agarwal Ashish51325b52014-06-16 16:50:49 +05306712 (pHddCtx->no_of_open_sessions[WLAN_HDD_INFRA_STATION] <=1))
Jeff Johnson295189b2012-06-20 16:38:30 -07006713 {
6714 //we are ok to do AMP
6715 pHddCtx->isAmpAllowed = VOS_TRUE;
6716 }
6717#endif //WLAN_BTAMP_FEATURE
6718 EXIT();
6719 return 0;
6720}
6721
Mahesh A Saptasagar0e59c472014-04-14 19:17:41 +05306722/*
6723 * FUNCTION: wlan_hdd_cfg80211_change_iface
6724 * wrapper function to protect the actual implementation from SSR.
6725 */
6726int wlan_hdd_cfg80211_change_iface( struct wiphy *wiphy,
6727 struct net_device *ndev,
6728 enum nl80211_iftype type,
6729 u32 *flags,
6730 struct vif_params *params
6731 )
6732{
6733 int ret;
6734
6735 vos_ssr_protect(__func__);
6736 ret = __wlan_hdd_cfg80211_change_iface(wiphy, ndev, type, flags, params);
6737 vos_ssr_unprotect(__func__);
6738
6739 return ret;
6740}
6741
Gopichand Nakkala681989c2013-03-06 22:27:48 -08006742#ifdef FEATURE_WLAN_TDLS
6743static int wlan_hdd_tdls_add_station(struct wiphy *wiphy,
6744 struct net_device *dev, u8 *mac, bool update, tCsrStaParams *StaParams)
6745{
6746 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
6747 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
6748 VOS_STATUS status;
Hoonki Lee5305c3a2013-04-29 23:28:59 -07006749 hddTdlsPeer_t *pTdlsPeer;
c_hpothu6ff1c3c2013-10-01 19:01:57 +05306750 long ret;
Rajesh Chauhana34c6e62014-03-25 16:37:58 +05306751 tANI_U16 numCurrTdlsPeers;
Gopichand Nakkala681989c2013-03-06 22:27:48 -08006752
6753 ENTER();
6754
Gopichand Nakkala838be5d2013-04-10 22:41:51 +05306755 if (NULL == pHddCtx || NULL == pHddCtx->cfg_ini)
Gopichand Nakkala681989c2013-03-06 22:27:48 -08006756 {
6757 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
6758 "Invalid arguments");
6759 return -EINVAL;
6760 }
Hoonki Lee27511902013-03-14 18:19:06 -07006761
6762 if ((eTDLS_SUPPORT_NOT_ENABLED == pHddCtx->tdls_mode) ||
6763 (eTDLS_SUPPORT_DISABLED == pHddCtx->tdls_mode))
6764 {
6765 VOS_TRACE( VOS_MODULE_ID_HDD, TDLS_LOG_LEVEL,
6766 "%s: TDLS mode is disabled OR not enabled in FW."
6767 MAC_ADDRESS_STR " Request declined.",
6768 __func__, MAC_ADDR_ARRAY(mac));
6769 return -ENOTSUPP;
6770 }
6771
Gopichand Nakkala681989c2013-03-06 22:27:48 -08006772 if (pHddCtx->isLogpInProgress)
6773 {
6774 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
6775 "%s:LOGP in Progress. Ignore!!!", __func__);
Gopichand Nakkala05922802013-03-14 12:23:19 -07006776 wlan_hdd_tdls_set_link_status(pAdapter, mac, eTDLS_LINK_IDLE);
Gopichand Nakkala681989c2013-03-06 22:27:48 -08006777 return -EBUSY;
6778 }
6779
Naresh Jayaram9c6f4462014-02-13 12:20:31 +05306780 pTdlsPeer = wlan_hdd_tdls_get_peer(pAdapter, mac);
Hoonki Lee5305c3a2013-04-29 23:28:59 -07006781
6782 if ( NULL == pTdlsPeer ) {
6783 VOS_TRACE( VOS_MODULE_ID_HDD, TDLS_LOG_LEVEL,
6784 "%s: " MAC_ADDRESS_STR " (update %d) not exist. return invalid",
6785 __func__, MAC_ADDR_ARRAY(mac), update);
6786 return -EINVAL;
Gopichand Nakkala34d1b062013-03-19 15:28:33 -07006787 }
Hoonki Lee5305c3a2013-04-29 23:28:59 -07006788
6789 /* in add station, we accept existing valid staId if there is */
6790 if ((0 == update) &&
6791 ((pTdlsPeer->link_status >= eTDLS_LINK_CONNECTING) ||
6792 (TDLS_STA_INDEX_VALID(pTdlsPeer->staId))))
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -07006793 {
Hoonki Lee5305c3a2013-04-29 23:28:59 -07006794 VOS_TRACE( VOS_MODULE_ID_HDD, TDLS_LOG_LEVEL,
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -07006795 "%s: " MAC_ADDRESS_STR
Hoonki Lee5305c3a2013-04-29 23:28:59 -07006796 " link_status %d. staId %d. add station ignored.",
6797 __func__, MAC_ADDR_ARRAY(mac), pTdlsPeer->link_status, pTdlsPeer->staId);
6798 return 0;
6799 }
6800 /* in change station, we accept only when staId is valid */
6801 if ((1 == update) &&
6802 ((pTdlsPeer->link_status > eTDLS_LINK_CONNECTING) ||
6803 (!TDLS_STA_INDEX_VALID(pTdlsPeer->staId))))
6804 {
6805 VOS_TRACE( VOS_MODULE_ID_HDD, TDLS_LOG_LEVEL,
6806 "%s: " MAC_ADDRESS_STR
6807 " link status %d. staId %d. change station %s.",
6808 __func__, MAC_ADDR_ARRAY(mac), pTdlsPeer->link_status, pTdlsPeer->staId,
6809 (TDLS_STA_INDEX_VALID(pTdlsPeer->staId)) ? "ignored" : "declined");
6810 return (TDLS_STA_INDEX_VALID(pTdlsPeer->staId)) ? 0 : -EPERM;
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -07006811 }
Gopichand Nakkala34d1b062013-03-19 15:28:33 -07006812
6813 /* when others are on-going, we want to change link_status to idle */
Madan Mohan Koyyalamudi96797442013-10-08 16:04:42 +05306814 if (NULL != wlan_hdd_tdls_is_progress(pHddCtx, mac, TRUE))
Gopichand Nakkala681989c2013-03-06 22:27:48 -08006815 {
Gopichand Nakkalac87400e2013-03-13 18:51:00 -07006816 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
6817 "%s: " MAC_ADDRESS_STR
6818 " TDLS setup is ongoing. Request declined.",
6819 __func__, MAC_ADDR_ARRAY(mac));
Gopichand Nakkala05922802013-03-14 12:23:19 -07006820 goto error;
Gopichand Nakkala681989c2013-03-06 22:27:48 -08006821 }
6822
6823 /* first to check if we reached to maximum supported TDLS peer.
6824 TODO: for now, return -EPERM looks working fine,
6825 but need to check if any other errno fit into this category.*/
Rajesh Chauhana34c6e62014-03-25 16:37:58 +05306826 numCurrTdlsPeers = wlan_hdd_tdlsConnectedPeers(pAdapter);
6827 if (HDD_MAX_NUM_TDLS_STA <= numCurrTdlsPeers)
Gopichand Nakkala681989c2013-03-06 22:27:48 -08006828 {
Gopichand Nakkalac87400e2013-03-13 18:51:00 -07006829 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
6830 "%s: " MAC_ADDRESS_STR
Rajesh Chauhana34c6e62014-03-25 16:37:58 +05306831 " TDLS Max peer already connected. Request declined."
6832 " Num of peers (%d), Max allowed (%d).",
6833 __func__, MAC_ADDR_ARRAY(mac), numCurrTdlsPeers,
6834 HDD_MAX_NUM_TDLS_STA);
Gopichand Nakkala05922802013-03-14 12:23:19 -07006835 goto error;
Gopichand Nakkala681989c2013-03-06 22:27:48 -08006836 }
6837 else
6838 {
6839 hddTdlsPeer_t *pTdlsPeer;
Madan Mohan Koyyalamudi96797442013-10-08 16:04:42 +05306840 pTdlsPeer = wlan_hdd_tdls_find_peer(pAdapter, mac, TRUE);
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -07006841 if (pTdlsPeer && TDLS_IS_CONNECTED(pTdlsPeer))
Gopichand Nakkala681989c2013-03-06 22:27:48 -08006842 {
Gopichand Nakkalac87400e2013-03-13 18:51:00 -07006843 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
6844 "%s: " MAC_ADDRESS_STR " already connected. Request declined.",
6845 __func__, MAC_ADDR_ARRAY(mac));
Gopichand Nakkala681989c2013-03-06 22:27:48 -08006846 return -EPERM;
6847 }
6848 }
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -07006849 if (0 == update)
6850 wlan_hdd_tdls_set_link_status(pAdapter, mac, eTDLS_LINK_CONNECTING);
Gopichand Nakkala681989c2013-03-06 22:27:48 -08006851
Jeff Johnsond75fe012013-04-06 10:53:06 -07006852 /* debug code */
Gopichand Nakkala838be5d2013-04-10 22:41:51 +05306853 if (NULL != StaParams)
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -07006854 {
6855 VOS_TRACE(VOS_MODULE_ID_HDD, TDLS_LOG_LEVEL,
6856 "%s: TDLS Peer Parameters.", __func__);
Hoonki Lee66b75f32013-04-16 18:30:07 -07006857 if(StaParams->htcap_present)
6858 {
6859 VOS_TRACE(VOS_MODULE_ID_HDD, TDLS_LOG_LEVEL,
6860 "ht_capa->cap_info: %0x", StaParams->HTCap.capInfo);
6861 VOS_TRACE(VOS_MODULE_ID_HDD, TDLS_LOG_LEVEL,
6862 "ht_capa->extended_capabilities: %0x",
6863 StaParams->HTCap.extendedHtCapInfo);
6864 }
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -07006865 VOS_TRACE(VOS_MODULE_ID_HDD, TDLS_LOG_LEVEL,
6866 "params->capability: %0x",StaParams->capability);
6867 VOS_TRACE(VOS_MODULE_ID_HDD, TDLS_LOG_LEVEL,
Jeff Johnson0299d0a2013-10-30 12:37:43 -07006868 "params->ext_capab_len: %0x",StaParams->extn_capability[0]);
Hoonki Lee66b75f32013-04-16 18:30:07 -07006869 if(StaParams->vhtcap_present)
6870 {
6871 VOS_TRACE(VOS_MODULE_ID_HDD, TDLS_LOG_LEVEL,
6872 "rxMcsMap %x rxHighest %x txMcsMap %x txHighest %x",
6873 StaParams->VHTCap.suppMcs.rxMcsMap, StaParams->VHTCap.suppMcs.rxHighest,
6874 StaParams->VHTCap.suppMcs.txMcsMap, StaParams->VHTCap.suppMcs.txHighest);
6875 }
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -07006876 {
6877 int i = 0;
Hoonki Lee5305c3a2013-04-29 23:28:59 -07006878 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO, "Supported rates:");
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -07006879 for (i = 0; i < sizeof(StaParams->supported_rates); i++)
6880 VOS_TRACE(VOS_MODULE_ID_HDD, TDLS_LOG_LEVEL,
6881 "[%d]: %x ", i, StaParams->supported_rates[i]);
6882 }
Jeff Johnsond75fe012013-04-06 10:53:06 -07006883 } /* end debug code */
Gopichand Nakkala838be5d2013-04-10 22:41:51 +05306884 else if ((1 == update) && (NULL == StaParams))
6885 {
6886 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
6887 "%s : update is true, but staParams is NULL. Error!", __func__);
6888 return -EPERM;
6889 }
Gopichand Nakkala681989c2013-03-06 22:27:48 -08006890
6891 INIT_COMPLETION(pAdapter->tdls_add_station_comp);
6892
6893 if (!update)
6894 {
6895 status = sme_AddTdlsPeerSta(WLAN_HDD_GET_HAL_CTX(pAdapter),
6896 pAdapter->sessionId, mac);
6897 }
6898 else
6899 {
6900 status = sme_ChangeTdlsPeerSta(WLAN_HDD_GET_HAL_CTX(pAdapter),
6901 pAdapter->sessionId, mac, StaParams);
6902 }
6903
c_hpothu6ff1c3c2013-10-01 19:01:57 +05306904 ret = wait_for_completion_interruptible_timeout(&pAdapter->tdls_add_station_comp,
Gopichand Nakkala681989c2013-03-06 22:27:48 -08006905 msecs_to_jiffies(WAIT_TIME_TDLS_ADD_STA));
6906
c_hpothu6ff1c3c2013-10-01 19:01:57 +05306907 if (ret <= 0)
Gopichand Nakkala681989c2013-03-06 22:27:48 -08006908 {
Gopichand Nakkalac87400e2013-03-13 18:51:00 -07006909 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
c_hpothu6ff1c3c2013-10-01 19:01:57 +05306910 "%s: timeout waiting for tdls add station indication %ld",
6911 __func__, ret);
Gopichand Nakkala34d1b062013-03-19 15:28:33 -07006912 return -EPERM;
Gopichand Nakkala681989c2013-03-06 22:27:48 -08006913 }
c_hpothu6ff1c3c2013-10-01 19:01:57 +05306914
Gopichand Nakkala681989c2013-03-06 22:27:48 -08006915 if ( eHAL_STATUS_SUCCESS != pAdapter->tdlsAddStaStatus)
6916 {
Gopichand Nakkalac87400e2013-03-13 18:51:00 -07006917 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Gopichand Nakkala681989c2013-03-06 22:27:48 -08006918 "%s: Add Station is unsucessful", __func__);
Gopichand Nakkala34d1b062013-03-19 15:28:33 -07006919 return -EPERM;
Gopichand Nakkala681989c2013-03-06 22:27:48 -08006920 }
6921
6922 return 0;
Gopichand Nakkala05922802013-03-14 12:23:19 -07006923
6924error:
6925 wlan_hdd_tdls_set_link_status(pAdapter, mac, eTDLS_LINK_IDLE);
6926 return -EPERM;
6927
Gopichand Nakkala681989c2013-03-06 22:27:48 -08006928}
6929#endif
6930
Jeff Johnson295189b2012-06-20 16:38:30 -07006931static int wlan_hdd_change_station(struct wiphy *wiphy,
6932 struct net_device *dev,
6933 u8 *mac,
6934 struct station_parameters *params)
6935{
6936 VOS_STATUS status = VOS_STATUS_SUCCESS;
6937 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( dev );
Gopichand Nakkala29149562013-05-10 21:43:41 +05306938 hdd_context_t *pHddCtx;
6939 hdd_station_ctx_t *pHddStaCtx;
Jeff Johnson295189b2012-06-20 16:38:30 -07006940 v_MACADDR_t STAMacAddress;
Gopichand Nakkalab0856222013-03-12 22:39:05 -07006941#ifdef FEATURE_WLAN_TDLS
Gopichand Nakkala681989c2013-03-06 22:27:48 -08006942 tCsrStaParams StaParams = {0};
Gopichand Nakkala681989c2013-03-06 22:27:48 -08006943 tANI_U8 isBufSta = 0;
Naresh Jayaram3180aa42014-02-12 21:47:26 +05306944 tANI_U8 isOffChannelSupported = 0;
Gopichand Nakkalab0856222013-03-12 22:39:05 -07006945#endif
Jeff Johnsone7245742012-09-05 17:12:55 -07006946 ENTER();
6947
Gopichand Nakkala29149562013-05-10 21:43:41 +05306948 if ((NULL == pAdapter))
6949 {
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +05306950 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
Gopichand Nakkala29149562013-05-10 21:43:41 +05306951 "invalid adapter ");
6952 return -EINVAL;
6953 }
6954
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05306955 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
6956 TRACE_CODE_HDD_CHANGE_STATION,
6957 pAdapter->sessionId, params->listen_interval));
Gopichand Nakkala29149562013-05-10 21:43:41 +05306958 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
6959 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
6960
6961 if ((NULL == pHddCtx) || (NULL == pHddStaCtx))
6962 {
6963 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
6964 "invalid HDD state or HDD station context");
6965 return -EINVAL;
6966 }
6967
6968 if (pHddCtx->isLogpInProgress)
Jeff Johnson04dd8a82012-06-29 20:41:40 -07006969 {
6970 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
6971 "%s:LOGP in Progress. Ignore!!!", __func__);
6972 return -EAGAIN;
6973 }
6974
Jeff Johnson295189b2012-06-20 16:38:30 -07006975 vos_mem_copy(STAMacAddress.bytes, mac, sizeof(v_MACADDR_t));
6976
Gopichand Nakkala681989c2013-03-06 22:27:48 -08006977 if ((pAdapter->device_mode == WLAN_HDD_SOFTAP)
6978 || (pAdapter->device_mode == WLAN_HDD_P2P_GO))
Jeff Johnson295189b2012-06-20 16:38:30 -07006979 {
Gopichand Nakkala681989c2013-03-06 22:27:48 -08006980 if (params->sta_flags_set & BIT(NL80211_STA_FLAG_AUTHORIZED))
Jeff Johnson295189b2012-06-20 16:38:30 -07006981 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306982 status = hdd_softap_change_STA_state( pAdapter, &STAMacAddress,
Jeff Johnson295189b2012-06-20 16:38:30 -07006983 WLANTL_STA_AUTHENTICATED);
6984
Gopichand Nakkala29149562013-05-10 21:43:41 +05306985 if (status != VOS_STATUS_SUCCESS)
6986 {
6987 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
6988 "%s: Not able to change TL state to AUTHENTICATED", __func__);
6989 return -EINVAL;
6990 }
Jeff Johnson295189b2012-06-20 16:38:30 -07006991 }
6992 }
Hoonki Leea6d49be2013-04-05 09:43:25 -07006993 else if ((pAdapter->device_mode == WLAN_HDD_INFRA_STATION)
6994 || (pAdapter->device_mode == WLAN_HDD_P2P_CLIENT)) {
Gopichand Nakkala29149562013-05-10 21:43:41 +05306995#ifdef FEATURE_WLAN_TDLS
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -07006996 if (params->sta_flags_set & BIT(NL80211_STA_FLAG_TDLS_PEER)) {
6997 StaParams.capability = params->capability;
6998 StaParams.uapsd_queues = params->uapsd_queues;
6999 StaParams.max_sp = params->max_sp;
7000
Naresh Jayaram3180aa42014-02-12 21:47:26 +05307001 /* Convert (first channel , number of channels) tuple to
7002 * the total list of channels. This goes with the assumption
7003 * that if the first channel is < 14, then the next channels
7004 * are an incremental of 1 else an incremental of 4 till the number
7005 * of channels.
7006 */
7007 if (0 != params->supported_channels_len) {
7008 int i = 0,j = 0,k = 0, no_of_channels = 0 ;
7009 for ( i = 0 ; i < params->supported_channels_len ; i+=2)
7010 {
7011 int wifi_chan_index;
7012 StaParams.supported_channels[j] = params->supported_channels[i];
7013 wifi_chan_index =
7014 ((StaParams.supported_channels[j] <= HDD_CHANNEL_14 ) ? 1 : 4 );
7015 no_of_channels = params->supported_channels[i+1];
7016 for(k=1; k <= no_of_channels; k++)
7017 {
7018 StaParams.supported_channels[j+1] =
7019 StaParams.supported_channels[j] + wifi_chan_index;
7020 j+=1;
7021 }
7022 }
7023 StaParams.supported_channels_len = j;
7024 }
7025 vos_mem_copy(StaParams.supported_oper_classes,
7026 params->supported_oper_classes,
7027 params->supported_oper_classes_len);
7028 StaParams.supported_oper_classes_len =
7029 params->supported_oper_classes_len;
7030
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -07007031 if (0 != params->ext_capab_len)
7032 vos_mem_copy(StaParams.extn_capability, params->ext_capab,
7033 sizeof(StaParams.extn_capability));
7034
7035 if (NULL != params->ht_capa)
Hoonki Lee66b75f32013-04-16 18:30:07 -07007036 {
7037 StaParams.htcap_present = 1;
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -07007038 vos_mem_copy(&StaParams.HTCap, params->ht_capa, sizeof(tSirHTCap));
Hoonki Lee66b75f32013-04-16 18:30:07 -07007039 }
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -07007040
7041 StaParams.supported_rates_len = params->supported_rates_len;
7042
7043 /* Note : The Maximum sizeof supported_rates sent by the Supplicant is 32.
7044 * The supported_rates array , for all the structures propogating till Add Sta
7045 * to the firmware has to be modified , if the supplicant (ieee80211) is
7046 * modified to send more rates.
7047 */
7048
7049 /* To avoid Data Currption , set to max length to SIR_MAC_MAX_SUPP_RATES
7050 */
7051 if (StaParams.supported_rates_len > SIR_MAC_MAX_SUPP_RATES)
7052 StaParams.supported_rates_len = SIR_MAC_MAX_SUPP_RATES;
7053
7054 if (0 != StaParams.supported_rates_len) {
7055 int i = 0;
7056 vos_mem_copy(StaParams.supported_rates, params->supported_rates,
7057 StaParams.supported_rates_len);
Hoonki Lee5305c3a2013-04-29 23:28:59 -07007058 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -07007059 "Supported Rates with Length %d", StaParams.supported_rates_len);
7060 for (i=0; i < StaParams.supported_rates_len; i++)
Hoonki Lee5305c3a2013-04-29 23:28:59 -07007061 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -07007062 "[%d]: %0x", i, StaParams.supported_rates[i]);
7063 }
7064
7065 if (NULL != params->vht_capa)
Hoonki Lee66b75f32013-04-16 18:30:07 -07007066 {
7067 StaParams.vhtcap_present = 1;
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -07007068 vos_mem_copy(&StaParams.VHTCap, params->vht_capa, sizeof(tSirVHTCap));
Hoonki Lee66b75f32013-04-16 18:30:07 -07007069 }
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -07007070
Gopichand Nakkala681989c2013-03-06 22:27:48 -08007071 if (0 != params->ext_capab_len ) {
7072 /*Define A Macro : TODO Sunil*/
7073 if ((1<<4) & StaParams.extn_capability[3]) {
7074 isBufSta = 1;
7075 }
Naresh Jayaram3180aa42014-02-12 21:47:26 +05307076 /* TDLS Channel Switching Support */
7077 if ((1<<6) & StaParams.extn_capability[3]) {
7078 isOffChannelSupported = 1;
7079 }
Gopichand Nakkala681989c2013-03-06 22:27:48 -08007080 }
Naresh Jayaram3180aa42014-02-12 21:47:26 +05307081 status = wlan_hdd_tdls_set_peer_caps( pAdapter, mac,
7082 &StaParams, isBufSta,
7083 isOffChannelSupported);
7084
Gopichand Nakkala79ff85d2013-05-27 17:05:29 +05307085 if (VOS_STATUS_SUCCESS != status) {
7086 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
7087 "%s: wlan_hdd_tdls_set_peer_caps failed!", __func__);
7088 return -EINVAL;
7089 }
Gopichand Nakkala681989c2013-03-06 22:27:48 -08007090 status = wlan_hdd_tdls_add_station(wiphy, dev, mac, 1, &StaParams);
7091
7092 if (VOS_STATUS_SUCCESS != status) {
7093 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
7094 "%s: sme_ChangeTdlsPeerSta failed!", __func__);
7095 return -EINVAL;
7096 }
7097 }
Gopichand Nakkalab0856222013-03-12 22:39:05 -07007098#endif
Gopichand Nakkala6239acd2013-06-14 14:48:00 +05307099 }
Jeff Johnsone7245742012-09-05 17:12:55 -07007100 EXIT();
Jeff Johnson295189b2012-06-20 16:38:30 -07007101 return status;
7102}
7103
7104/*
Mahesh A Saptasagar1a51bc02014-06-02 18:28:08 +05307105 * FUNCTION: __wlan_hdd_cfg80211_add_key
Jeff Johnson295189b2012-06-20 16:38:30 -07007106 * This function is used to initialize the key information
7107 */
7108#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
Mahesh A Saptasagar1a51bc02014-06-02 18:28:08 +05307109static int __wlan_hdd_cfg80211_add_key( struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -07007110 struct net_device *ndev,
7111 u8 key_index, bool pairwise,
7112 const u8 *mac_addr,
7113 struct key_params *params
7114 )
7115#else
Mahesh A Saptasagar1a51bc02014-06-02 18:28:08 +05307116static int __wlan_hdd_cfg80211_add_key( struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -07007117 struct net_device *ndev,
7118 u8 key_index, const u8 *mac_addr,
7119 struct key_params *params
7120 )
7121#endif
7122{
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -07007123 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( ndev );
Jeff Johnson295189b2012-06-20 16:38:30 -07007124 tCsrRoamSetKey setKey;
7125 u8 groupmacaddr[WNI_CFG_BSSID_LEN] = {0xFF,0xFF,0xFF,0xFF,0xFF,0xFF};
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05307126 int status;
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -07007127 v_U32_t roamId= 0xFF;
7128 v_CONTEXT_t pVosContext = (WLAN_HDD_GET_CTX(pAdapter))->pvosContext;
Jeff Johnson295189b2012-06-20 16:38:30 -07007129 hdd_hostapd_state_t *pHostapdState;
7130 VOS_STATUS vos_status;
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -07007131 eHalStatus halStatus;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05307132 hdd_context_t *pHddCtx;
Jeff Johnson295189b2012-06-20 16:38:30 -07007133
7134 ENTER();
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +05307135
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05307136 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
7137 TRACE_CODE_HDD_CFG80211_ADD_KEY,
7138 pAdapter->sessionId, params->key_len));
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05307139 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
7140 status = wlan_hdd_validate_context(pHddCtx);
7141
7142 if (0 != status)
Jeff Johnson04dd8a82012-06-29 20:41:40 -07007143 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05307144 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
7145 "%s: HDD context is not valid", __func__);
7146 return status;
Jeff Johnson04dd8a82012-06-29 20:41:40 -07007147 }
7148
Sushant Kaushik8bc7df22014-04-09 17:55:29 +05307149 hddLog(VOS_TRACE_LEVEL_INFO, "%s: device_mode = %s (%d)",
7150 __func__, hdd_device_modetoString(pAdapter->device_mode),
7151 pAdapter->device_mode);
Jeff Johnson295189b2012-06-20 16:38:30 -07007152
7153 if (CSR_MAX_NUM_KEY <= key_index)
7154 {
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -07007155 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Invalid key index %d", __func__,
Jeff Johnson295189b2012-06-20 16:38:30 -07007156 key_index);
7157
7158 return -EINVAL;
7159 }
7160
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -07007161 if (CSR_MAX_KEY_LEN < params->key_len)
7162 {
7163 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Invalid key length %d", __func__,
7164 params->key_len);
7165
7166 return -EINVAL;
7167 }
7168
7169 hddLog(VOS_TRACE_LEVEL_INFO,
7170 "%s: called with key index = %d & key length %d",
7171 __func__, key_index, params->key_len);
Jeff Johnson295189b2012-06-20 16:38:30 -07007172
7173 /*extract key idx, key len and key*/
7174 vos_mem_zero(&setKey,sizeof(tCsrRoamSetKey));
7175 setKey.keyId = key_index;
7176 setKey.keyLength = params->key_len;
7177 vos_mem_copy(&setKey.Key[0],params->key, params->key_len);
7178
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -07007179 switch (params->cipher)
Jeff Johnson295189b2012-06-20 16:38:30 -07007180 {
7181 case WLAN_CIPHER_SUITE_WEP40:
7182 setKey.encType = eCSR_ENCRYPT_TYPE_WEP40_STATICKEY;
7183 break;
7184
7185 case WLAN_CIPHER_SUITE_WEP104:
7186 setKey.encType = eCSR_ENCRYPT_TYPE_WEP104_STATICKEY;
7187 break;
7188
7189 case WLAN_CIPHER_SUITE_TKIP:
7190 {
7191 u8 *pKey = &setKey.Key[0];
7192 setKey.encType = eCSR_ENCRYPT_TYPE_TKIP;
7193
7194 vos_mem_zero(pKey, CSR_MAX_KEY_LEN);
7195
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -07007196 /*Supplicant sends the 32bytes key in this order
Jeff Johnson295189b2012-06-20 16:38:30 -07007197
7198 |--------------|----------|----------|
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -07007199 | Tk1 |TX-MIC | RX Mic |
Jeff Johnson295189b2012-06-20 16:38:30 -07007200 |--------------|----------|----------|
7201 <---16bytes---><--8bytes--><--8bytes-->
7202
7203 */
7204 /*Sme expects the 32 bytes key to be in the below order
7205
7206 |--------------|----------|----------|
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -07007207 | Tk1 |RX-MIC | TX Mic |
Jeff Johnson295189b2012-06-20 16:38:30 -07007208 |--------------|----------|----------|
7209 <---16bytes---><--8bytes--><--8bytes-->
7210 */
7211 /* Copy the Temporal Key 1 (TK1) */
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -07007212 vos_mem_copy(pKey, params->key, 16);
Jeff Johnson295189b2012-06-20 16:38:30 -07007213
7214 /*Copy the rx mic first*/
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -07007215 vos_mem_copy(&pKey[16], &params->key[24], 8);
Jeff Johnson295189b2012-06-20 16:38:30 -07007216
7217 /*Copy the tx mic */
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -07007218 vos_mem_copy(&pKey[24], &params->key[16], 8);
Jeff Johnson295189b2012-06-20 16:38:30 -07007219
7220
7221 break;
7222 }
7223
7224 case WLAN_CIPHER_SUITE_CCMP:
7225 setKey.encType = eCSR_ENCRYPT_TYPE_AES;
7226 break;
7227
7228#ifdef FEATURE_WLAN_WAPI
7229 case WLAN_CIPHER_SUITE_SMS4:
7230 {
7231 vos_mem_zero(&setKey,sizeof(tCsrRoamSetKey));
7232 wlan_hdd_cfg80211_set_key_wapi(pAdapter, key_index, mac_addr,
7233 params->key, params->key_len);
7234 return 0;
7235 }
7236#endif
Chet Lanctot186b5732013-03-18 10:26:30 -07007237
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08007238#ifdef FEATURE_WLAN_ESE
Jeff Johnson295189b2012-06-20 16:38:30 -07007239 case WLAN_CIPHER_SUITE_KRK:
7240 setKey.encType = eCSR_ENCRYPT_TYPE_KRK;
7241 break;
7242#endif
Chet Lanctot186b5732013-03-18 10:26:30 -07007243
7244#ifdef WLAN_FEATURE_11W
7245 case WLAN_CIPHER_SUITE_AES_CMAC:
7246 setKey.encType = eCSR_ENCRYPT_TYPE_AES_CMAC;
Chet Lanctot3b5158a2013-03-31 16:45:21 -07007247 break;
Chet Lanctot186b5732013-03-18 10:26:30 -07007248#endif
7249
Jeff Johnson295189b2012-06-20 16:38:30 -07007250 default:
Jeff Johnson0299d0a2013-10-30 12:37:43 -07007251 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: unsupported cipher type %u",
Jeff Johnson295189b2012-06-20 16:38:30 -07007252 __func__, params->cipher);
7253 return -EOPNOTSUPP;
7254 }
7255
7256 hddLog(VOS_TRACE_LEVEL_INFO_MED, "%s: encryption type %d",
7257 __func__, setKey.encType);
7258
Shailender Karmuchi642e9812013-05-30 14:34:49 -07007259 if (
Jeff Johnson295189b2012-06-20 16:38:30 -07007260#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
7261 (!pairwise)
7262#else
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -07007263 (!mac_addr || is_broadcast_ether_addr(mac_addr))
Jeff Johnson295189b2012-06-20 16:38:30 -07007264#endif
Shailender Karmuchi642e9812013-05-30 14:34:49 -07007265 )
7266 {
7267 /* set group key*/
7268 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
7269 "%s- %d: setting Broadcast key",
7270 __func__, __LINE__);
7271 setKey.keyDirection = eSIR_RX_ONLY;
7272 vos_mem_copy(setKey.peerMac,groupmacaddr,WNI_CFG_BSSID_LEN);
7273 }
7274 else
7275 {
7276 /* set pairwise key*/
7277 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
7278 "%s- %d: setting pairwise key",
7279 __func__, __LINE__);
7280 setKey.keyDirection = eSIR_TX_RX;
7281 vos_mem_copy(setKey.peerMac, mac_addr,WNI_CFG_BSSID_LEN);
7282 }
7283 if ((WLAN_HDD_IBSS == pAdapter->device_mode) && !pairwise)
7284 {
7285 setKey.keyDirection = eSIR_TX_RX;
7286 /*Set the group key*/
7287 status = sme_RoamSetKey( WLAN_HDD_GET_HAL_CTX(pAdapter),
7288 pAdapter->sessionId, &setKey, &roamId );
Jeff Johnson295189b2012-06-20 16:38:30 -07007289
Shailender Karmuchi642e9812013-05-30 14:34:49 -07007290 if ( 0 != status )
7291 {
7292 hddLog(VOS_TRACE_LEVEL_ERROR,
7293 "%s: sme_RoamSetKey failed, returned %d", __func__, status);
7294 return -EINVAL;
7295 }
7296 /*Save the keys here and call sme_RoamSetKey for setting
7297 the PTK after peer joins the IBSS network*/
7298 vos_mem_copy(&pAdapter->sessionCtx.station.ibss_enc_key,
7299 &setKey, sizeof(tCsrRoamSetKey));
7300 return status;
7301 }
Gopichand Nakkala29149562013-05-10 21:43:41 +05307302 if ((pAdapter->device_mode == WLAN_HDD_SOFTAP) ||
7303 (pAdapter->device_mode == WLAN_HDD_P2P_GO))
7304 {
Jeff Johnson295189b2012-06-20 16:38:30 -07007305 pHostapdState = WLAN_HDD_GET_HOSTAP_STATE_PTR(pAdapter);
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -07007306 if( pHostapdState->bssState == BSS_START )
7307 {
c_hpothu7c55da62014-01-23 18:34:02 +05307308 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
7309 vos_status = wlan_hdd_check_ula_done(pAdapter);
7310
7311 if ( vos_status != VOS_STATUS_SUCCESS )
7312 {
7313 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
7314 "[%4d] wlan_hdd_check_ula_done returned ERROR status= %d",
7315 __LINE__, vos_status );
7316
7317 pHddStaCtx->roam_info.roamingState = HDD_ROAM_STATE_NONE;
7318
7319 return -EINVAL;
7320 }
7321
Jeff Johnson295189b2012-06-20 16:38:30 -07007322 status = WLANSAP_SetKeySta( pVosContext, &setKey);
7323
7324 if ( status != eHAL_STATUS_SUCCESS )
7325 {
7326 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
7327 "[%4d] WLANSAP_SetKeySta returned ERROR status= %d",
7328 __LINE__, status );
7329 }
7330 }
7331
7332 /* Saving WEP keys */
7333 else if( eCSR_ENCRYPT_TYPE_WEP40_STATICKEY == setKey.encType ||
7334 eCSR_ENCRYPT_TYPE_WEP104_STATICKEY == setKey.encType )
7335 {
7336 //Save the wep key in ap context. Issue setkey after the BSS is started.
7337 hdd_ap_ctx_t *pAPCtx = WLAN_HDD_GET_AP_CTX_PTR(pAdapter);
7338 vos_mem_copy(&pAPCtx->wepKey[key_index], &setKey, sizeof(tCsrRoamSetKey));
7339 }
7340 else
7341 {
7342 //Save the key in ap context. Issue setkey after the BSS is started.
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -07007343 hdd_ap_ctx_t *pAPCtx = WLAN_HDD_GET_AP_CTX_PTR(pAdapter);
Jeff Johnson295189b2012-06-20 16:38:30 -07007344 vos_mem_copy(&pAPCtx->groupKey, &setKey, sizeof(tCsrRoamSetKey));
7345 }
7346 }
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -07007347 else if ( (pAdapter->device_mode == WLAN_HDD_INFRA_STATION) ||
7348 (pAdapter->device_mode == WLAN_HDD_P2P_CLIENT) )
Jeff Johnson295189b2012-06-20 16:38:30 -07007349 {
7350 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
7351 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
7352
Gopichand Nakkala3d295922013-05-07 16:19:14 +05307353#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
7354 if (!pairwise)
7355#else
7356 if (!mac_addr || is_broadcast_ether_addr(mac_addr))
7357#endif
7358 {
7359 /* set group key*/
7360 if (pHddStaCtx->roam_info.deferKeyComplete)
7361 {
7362 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
7363 "%s- %d: Perform Set key Complete",
7364 __func__, __LINE__);
7365 hdd_PerformRoamSetKeyComplete(pAdapter);
7366 }
7367 }
7368
Jeff Johnson295189b2012-06-20 16:38:30 -07007369 pWextState->roamProfile.Keys.KeyLength[key_index] = (u8)params->key_len;
7370
Venkata Prathyusha Kuntupalliee2ce712013-01-17 14:09:24 -08007371 pWextState->roamProfile.Keys.defaultIndex = key_index;
7372
7373
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -07007374 vos_mem_copy(&pWextState->roamProfile.Keys.KeyMaterial[key_index][0],
Jeff Johnson295189b2012-06-20 16:38:30 -07007375 params->key, params->key_len);
7376
Gopichand Nakkala3d295922013-05-07 16:19:14 +05307377
Jeff Johnson295189b2012-06-20 16:38:30 -07007378 pHddStaCtx->roam_info.roamingState = HDD_ROAM_STATE_SETTING_KEY;
7379
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307380 hddLog(VOS_TRACE_LEVEL_INFO_MED,
Jeff Johnson295189b2012-06-20 16:38:30 -07007381 "%s: set key for peerMac %2x:%2x:%2x:%2x:%2x:%2x, direction %d",
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307382 __func__, setKey.peerMac[0], setKey.peerMac[1],
7383 setKey.peerMac[2], setKey.peerMac[3],
7384 setKey.peerMac[4], setKey.peerMac[5],
Jeff Johnson295189b2012-06-20 16:38:30 -07007385 setKey.keyDirection);
7386
7387 vos_status = wlan_hdd_check_ula_done(pAdapter);
7388
7389 if ( vos_status != VOS_STATUS_SUCCESS )
7390 {
7391 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
7392 "[%4d] wlan_hdd_check_ula_done returned ERROR status= %d",
7393 __LINE__, vos_status );
7394
7395 pHddStaCtx->roam_info.roamingState = HDD_ROAM_STATE_NONE;
7396
7397 return -EINVAL;
7398
7399 }
7400
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -07007401#ifdef WLAN_FEATURE_VOWIFI_11R
Gopichand Nakkala3d295922013-05-07 16:19:14 +05307402 /* The supplicant may attempt to set the PTK once pre-authentication
7403 is done. Save the key in the UMAC and include it in the ADD BSS
7404 request */
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -07007405 halStatus = sme_FTUpdateKey( WLAN_HDD_GET_HAL_CTX(pAdapter), &setKey);
Gopichand Nakkala3d295922013-05-07 16:19:14 +05307406 if ( halStatus == eHAL_STATUS_FT_PREAUTH_KEY_SUCCESS )
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -07007407 {
Gopichand Nakkala3d295922013-05-07 16:19:14 +05307408 hddLog(VOS_TRACE_LEVEL_INFO_MED,
7409 "%s: Update PreAuth Key success", __func__);
7410 return 0;
7411 }
7412 else if ( halStatus == eHAL_STATUS_FT_PREAUTH_KEY_FAILED )
7413 {
7414 hddLog(VOS_TRACE_LEVEL_ERROR,
7415 "%s: Update PreAuth Key failed", __func__);
Gopichand Nakkalad7d13652013-02-15 01:48:00 +05307416 return -EINVAL;
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -07007417 }
7418#endif /* WLAN_FEATURE_VOWIFI_11R */
Jeff Johnson295189b2012-06-20 16:38:30 -07007419
7420 /* issue set key request to SME*/
7421 status = sme_RoamSetKey( WLAN_HDD_GET_HAL_CTX(pAdapter),
7422 pAdapter->sessionId, &setKey, &roamId );
7423
7424 if ( 0 != status )
7425 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307426 hddLog(VOS_TRACE_LEVEL_ERROR,
Jeff Johnson295189b2012-06-20 16:38:30 -07007427 "%s: sme_RoamSetKey failed, returned %d", __func__, status);
7428 pHddStaCtx->roam_info.roamingState = HDD_ROAM_STATE_NONE;
7429 return -EINVAL;
7430 }
7431
7432
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307433 /* in case of IBSS as there was no information available about WEP keys during
7434 * IBSS join, group key intialized with NULL key, so re-initialize group key
Jeff Johnson295189b2012-06-20 16:38:30 -07007435 * with correct value*/
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307436 if ( (eCSR_BSS_TYPE_START_IBSS == pWextState->roamProfile.BSSType) &&
7437 !( ( IW_AUTH_KEY_MGMT_802_1X
7438 == (pWextState->authKeyMgmt & IW_AUTH_KEY_MGMT_802_1X))
Jeff Johnson295189b2012-06-20 16:38:30 -07007439 && (eCSR_AUTH_TYPE_OPEN_SYSTEM == pHddStaCtx->conn_info.authType)
7440 )
7441 &&
7442 ( (WLAN_CIPHER_SUITE_WEP40 == params->cipher)
7443 || (WLAN_CIPHER_SUITE_WEP104 == params->cipher)
7444 )
7445 )
7446 {
7447 setKey.keyDirection = eSIR_RX_ONLY;
7448 vos_mem_copy(setKey.peerMac,groupmacaddr,WNI_CFG_BSSID_LEN);
7449
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307450 hddLog(VOS_TRACE_LEVEL_INFO_MED,
Jeff Johnson295189b2012-06-20 16:38:30 -07007451 "%s: set key peerMac %2x:%2x:%2x:%2x:%2x:%2x, direction %d",
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307452 __func__, setKey.peerMac[0], setKey.peerMac[1],
7453 setKey.peerMac[2], setKey.peerMac[3],
7454 setKey.peerMac[4], setKey.peerMac[5],
Jeff Johnson295189b2012-06-20 16:38:30 -07007455 setKey.keyDirection);
7456
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307457 status = sme_RoamSetKey( WLAN_HDD_GET_HAL_CTX(pAdapter),
Jeff Johnson295189b2012-06-20 16:38:30 -07007458 pAdapter->sessionId, &setKey, &roamId );
7459
7460 if ( 0 != status )
7461 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307462 hddLog(VOS_TRACE_LEVEL_ERROR,
7463 "%s: sme_RoamSetKey failed for group key (IBSS), returned %d",
Jeff Johnson295189b2012-06-20 16:38:30 -07007464 __func__, status);
7465 pHddStaCtx->roam_info.roamingState = HDD_ROAM_STATE_NONE;
7466 return -EINVAL;
7467 }
7468 }
7469 }
7470
7471 return 0;
7472}
7473
Mahesh A Saptasagar1a51bc02014-06-02 18:28:08 +05307474#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
7475static int wlan_hdd_cfg80211_add_key( struct wiphy *wiphy,
7476 struct net_device *ndev,
7477 u8 key_index, bool pairwise,
7478 const u8 *mac_addr,
7479 struct key_params *params
7480 )
7481#else
7482static int wlan_hdd_cfg80211_add_key( struct wiphy *wiphy,
7483 struct net_device *ndev,
7484 u8 key_index, const u8 *mac_addr,
7485 struct key_params *params
7486 )
7487#endif
7488{
7489 int ret;
7490 vos_ssr_protect(__func__);
7491#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
7492 ret = __wlan_hdd_cfg80211_add_key(wiphy, ndev, key_index, pairwise,
7493 mac_addr, params);
7494#else
7495 ret = __wlan_hdd_cfg80211_add_key(wiphy, ndev, key_index, mac_addr,
7496 params);
7497#endif
7498 vos_ssr_unprotect(__func__);
7499
7500 return ret;
7501}
7502
Jeff Johnson295189b2012-06-20 16:38:30 -07007503/*
Mahesh A Saptasagar1a51bc02014-06-02 18:28:08 +05307504 * FUNCTION: __wlan_hdd_cfg80211_get_key
Jeff Johnson295189b2012-06-20 16:38:30 -07007505 * This function is used to get the key information
7506 */
7507#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
Mahesh A Saptasagar1a51bc02014-06-02 18:28:08 +05307508static int __wlan_hdd_cfg80211_get_key(
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307509 struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -07007510 struct net_device *ndev,
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307511 u8 key_index, bool pairwise,
Jeff Johnson295189b2012-06-20 16:38:30 -07007512 const u8 *mac_addr, void *cookie,
7513 void (*callback)(void *cookie, struct key_params*)
7514 )
7515#else
Mahesh A Saptasagar1a51bc02014-06-02 18:28:08 +05307516static int __wlan_hdd_cfg80211_get_key(
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307517 struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -07007518 struct net_device *ndev,
7519 u8 key_index, const u8 *mac_addr, void *cookie,
7520 void (*callback)(void *cookie, struct key_params*)
7521 )
7522#endif
7523{
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307524 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( ndev );
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +05307525 hdd_wext_state_t *pWextState= WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
7526 tCsrRoamProfile *pRoamProfile = &(pWextState->roamProfile);
Jeff Johnson295189b2012-06-20 16:38:30 -07007527 struct key_params params;
7528
7529 ENTER();
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307530
Sushant Kaushik8bc7df22014-04-09 17:55:29 +05307531 hddLog(VOS_TRACE_LEVEL_INFO, "%s: device_mode = %s (%d)",
7532 __func__, hdd_device_modetoString(pAdapter->device_mode),
7533 pAdapter->device_mode);
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +05307534
Jeff Johnson295189b2012-06-20 16:38:30 -07007535 memset(&params, 0, sizeof(params));
7536
7537 if (CSR_MAX_NUM_KEY <= key_index)
7538 {
c_hpothu6ff1c3c2013-10-01 19:01:57 +05307539 hddLog(VOS_TRACE_LEVEL_ERROR, FL("invalid key index %d"), key_index);
Jeff Johnson295189b2012-06-20 16:38:30 -07007540 return -EINVAL;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307541 }
Jeff Johnson295189b2012-06-20 16:38:30 -07007542
7543 switch(pRoamProfile->EncryptionType.encryptionType[0])
7544 {
7545 case eCSR_ENCRYPT_TYPE_NONE:
7546 params.cipher = IW_AUTH_CIPHER_NONE;
7547 break;
7548
7549 case eCSR_ENCRYPT_TYPE_WEP40_STATICKEY:
7550 case eCSR_ENCRYPT_TYPE_WEP40:
7551 params.cipher = WLAN_CIPHER_SUITE_WEP40;
7552 break;
7553
7554 case eCSR_ENCRYPT_TYPE_WEP104_STATICKEY:
7555 case eCSR_ENCRYPT_TYPE_WEP104:
7556 params.cipher = WLAN_CIPHER_SUITE_WEP104;
7557 break;
7558
7559 case eCSR_ENCRYPT_TYPE_TKIP:
7560 params.cipher = WLAN_CIPHER_SUITE_TKIP;
7561 break;
7562
7563 case eCSR_ENCRYPT_TYPE_AES:
7564 params.cipher = WLAN_CIPHER_SUITE_AES_CMAC;
7565 break;
7566
7567 default:
7568 params.cipher = IW_AUTH_CIPHER_NONE;
7569 break;
7570 }
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +05307571
c_hpothuaaf19692014-05-17 17:01:48 +05307572 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
7573 TRACE_CODE_HDD_CFG80211_GET_KEY,
7574 pAdapter->sessionId, params.cipher));
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +05307575
Jeff Johnson295189b2012-06-20 16:38:30 -07007576 params.key_len = pRoamProfile->Keys.KeyLength[key_index];
7577 params.seq_len = 0;
7578 params.seq = NULL;
7579 params.key = &pRoamProfile->Keys.KeyMaterial[key_index][0];
7580 callback(cookie, &params);
7581 return 0;
7582}
7583
Mahesh A Saptasagar1a51bc02014-06-02 18:28:08 +05307584#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
7585static int wlan_hdd_cfg80211_get_key(
7586 struct wiphy *wiphy,
7587 struct net_device *ndev,
7588 u8 key_index, bool pairwise,
7589 const u8 *mac_addr, void *cookie,
7590 void (*callback)(void *cookie, struct key_params*)
7591 )
7592#else
7593static int wlan_hdd_cfg80211_get_key(
7594 struct wiphy *wiphy,
7595 struct net_device *ndev,
7596 u8 key_index, const u8 *mac_addr, void *cookie,
7597 void (*callback)(void *cookie, struct key_params*)
7598 )
7599#endif
7600{
7601 int ret;
7602
7603 vos_ssr_protect(__func__);
7604#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
7605 ret = __wlan_hdd_cfg80211_get_key(wiphy, ndev, key_index, pairwise,
7606 mac_addr, cookie, callback);
7607#else
7608 ret = __wlan_hdd_cfg80211_get_key(wiphy, ndev, key_index, mac_addr,
7609 callback);
7610#endif
7611 vos_ssr_unprotect(__func__);
7612
7613 return ret;
7614}
7615
Jeff Johnson295189b2012-06-20 16:38:30 -07007616/*
7617 * FUNCTION: wlan_hdd_cfg80211_del_key
7618 * This function is used to delete the key information
7619 */
7620#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307621static int wlan_hdd_cfg80211_del_key( struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -07007622 struct net_device *ndev,
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307623 u8 key_index,
7624 bool pairwise,
Jeff Johnson295189b2012-06-20 16:38:30 -07007625 const u8 *mac_addr
7626 )
7627#else
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307628static int wlan_hdd_cfg80211_del_key( struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -07007629 struct net_device *ndev,
7630 u8 key_index,
7631 const u8 *mac_addr
7632 )
7633#endif
7634{
7635 int status = 0;
7636
7637 //This code needs to be revisited. There is sme_removeKey API, we should
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307638 //plan to use that. After the change to use correct index in setkey,
Jeff Johnson295189b2012-06-20 16:38:30 -07007639 //it is observed that this is invalidating peer
7640 //key index whenever re-key is done. This is affecting data link.
7641 //It should be ok to ignore del_key.
7642#if 0
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307643 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( ndev );
7644 v_CONTEXT_t pVosContext = (WLAN_HDD_GET_CTX(pAdapter))->pvosContext;
Jeff Johnson295189b2012-06-20 16:38:30 -07007645 u8 groupmacaddr[WNI_CFG_BSSID_LEN] = {0xFF,0xFF,0xFF,0xFF,0xFF,0xFF};
7646 tCsrRoamSetKey setKey;
7647 v_U32_t roamId= 0xFF;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307648
Jeff Johnson295189b2012-06-20 16:38:30 -07007649 ENTER();
7650
7651 hddLog(VOS_TRACE_LEVEL_INFO_HIGH, "%s: device_mode = %d\n",
7652 __func__,pAdapter->device_mode);
7653
7654 if (CSR_MAX_NUM_KEY <= key_index)
7655 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307656 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Invalid key index %d", __func__,
Jeff Johnson295189b2012-06-20 16:38:30 -07007657 key_index);
7658
7659 return -EINVAL;
7660 }
7661
7662 vos_mem_zero(&setKey,sizeof(tCsrRoamSetKey));
7663 setKey.keyId = key_index;
7664
7665 if (mac_addr)
7666 vos_mem_copy(setKey.peerMac, mac_addr,WNI_CFG_BSSID_LEN);
7667 else
7668 vos_mem_copy(setKey.peerMac, groupmacaddr, WNI_CFG_BSSID_LEN);
7669
7670 setKey.encType = eCSR_ENCRYPT_TYPE_NONE;
7671
7672 if ((pAdapter->device_mode == WLAN_HDD_SOFTAP)
Jeff Johnson295189b2012-06-20 16:38:30 -07007673 || (pAdapter->device_mode == WLAN_HDD_P2P_GO)
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307674 )
7675 {
7676
7677 hdd_hostapd_state_t *pHostapdState =
Jeff Johnson295189b2012-06-20 16:38:30 -07007678 WLAN_HDD_GET_HOSTAP_STATE_PTR(pAdapter);
7679 if( pHostapdState->bssState == BSS_START)
7680 {
7681 status = WLANSAP_SetKeySta( pVosContext, &setKey);
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307682
Jeff Johnson295189b2012-06-20 16:38:30 -07007683 if ( status != eHAL_STATUS_SUCCESS )
7684 {
7685 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
7686 "[%4d] WLANSAP_SetKeySta returned ERROR status= %d",
7687 __LINE__, status );
7688 }
7689 }
7690 }
7691 else if ( (pAdapter->device_mode == WLAN_HDD_INFRA_STATION)
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307692 || (pAdapter->device_mode == WLAN_HDD_P2P_CLIENT)
Jeff Johnson295189b2012-06-20 16:38:30 -07007693 )
7694 {
7695 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
7696
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307697 pHddStaCtx->roam_info.roamingState = HDD_ROAM_STATE_SETTING_KEY;
7698
7699 hddLog(VOS_TRACE_LEVEL_INFO_MED,
Jeff Johnson295189b2012-06-20 16:38:30 -07007700 "%s: delete key for peerMac %2x:%2x:%2x:%2x:%2x:%2x",
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307701 __func__, setKey.peerMac[0], setKey.peerMac[1],
7702 setKey.peerMac[2], setKey.peerMac[3],
Jeff Johnson295189b2012-06-20 16:38:30 -07007703 setKey.peerMac[4], setKey.peerMac[5]);
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307704 if(pAdapter->sessionCtx.station.conn_info.connState ==
7705 eConnectionState_Associated)
Jeff Johnson295189b2012-06-20 16:38:30 -07007706 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307707 status = sme_RoamSetKey( WLAN_HDD_GET_HAL_CTX(pAdapter),
Jeff Johnson295189b2012-06-20 16:38:30 -07007708 pAdapter->sessionId, &setKey, &roamId );
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307709
Jeff Johnson295189b2012-06-20 16:38:30 -07007710 if ( 0 != status )
7711 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307712 hddLog(VOS_TRACE_LEVEL_ERROR,
Jeff Johnson295189b2012-06-20 16:38:30 -07007713 "%s: sme_RoamSetKey failure, returned %d",
7714 __func__, status);
7715 pHddStaCtx->roam_info.roamingState = HDD_ROAM_STATE_NONE;
7716 return -EINVAL;
7717 }
7718 }
7719 }
7720#endif
Jeff Johnsone7245742012-09-05 17:12:55 -07007721 EXIT();
Jeff Johnson295189b2012-06-20 16:38:30 -07007722 return status;
7723}
7724
7725/*
Mahesh A Saptasagar1a51bc02014-06-02 18:28:08 +05307726 * FUNCTION: __wlan_hdd_cfg80211_set_default_key
Jeff Johnson295189b2012-06-20 16:38:30 -07007727 * This function is used to set the default tx key index
7728 */
7729#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
Mahesh A Saptasagar1a51bc02014-06-02 18:28:08 +05307730static int __wlan_hdd_cfg80211_set_default_key( struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -07007731 struct net_device *ndev,
7732 u8 key_index,
7733 bool unicast, bool multicast)
7734#else
Mahesh A Saptasagar1a51bc02014-06-02 18:28:08 +05307735static int __wlan_hdd_cfg80211_set_default_key( struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -07007736 struct net_device *ndev,
7737 u8 key_index)
7738#endif
7739{
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307740 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( ndev );
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05307741 int status;
Gopichand Nakkala29149562013-05-10 21:43:41 +05307742 hdd_wext_state_t *pWextState;
7743 hdd_station_ctx_t *pHddStaCtx;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05307744 hdd_context_t *pHddCtx;
Jeff Johnson295189b2012-06-20 16:38:30 -07007745
7746 ENTER();
7747
Gopichand Nakkala29149562013-05-10 21:43:41 +05307748 if ((NULL == pAdapter))
7749 {
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +05307750 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
Gopichand Nakkala29149562013-05-10 21:43:41 +05307751 "invalid adapter");
7752 return -EINVAL;
7753 }
7754
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05307755 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
7756 TRACE_CODE_HDD_CFG80211_SET_DEFAULT_KEY,
7757 pAdapter->sessionId, key_index));
7758
Gopichand Nakkala29149562013-05-10 21:43:41 +05307759 pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
7760 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
7761
7762 if ((NULL == pWextState) || (NULL == pHddStaCtx))
7763 {
7764 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
7765 "invalid Wext state or HDD context");
7766 return -EINVAL;
7767 }
7768
Arif Hussain6d2a3322013-11-17 19:50:10 -08007769 hddLog(VOS_TRACE_LEVEL_INFO, "%s: device_mode = %d key_index = %d",
Jeff Johnson295189b2012-06-20 16:38:30 -07007770 __func__,pAdapter->device_mode, key_index);
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307771
Jeff Johnson295189b2012-06-20 16:38:30 -07007772 if (CSR_MAX_NUM_KEY <= key_index)
7773 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307774 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Invalid key index %d", __func__,
Jeff Johnson295189b2012-06-20 16:38:30 -07007775 key_index);
7776
7777 return -EINVAL;
7778 }
7779
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05307780 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
7781 status = wlan_hdd_validate_context(pHddCtx);
7782
7783 if (0 != status)
Jeff Johnson04dd8a82012-06-29 20:41:40 -07007784 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05307785 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
7786 "%s: HDD context is not valid", __func__);
7787 return status;
Jeff Johnson04dd8a82012-06-29 20:41:40 -07007788 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307789
Jeff Johnson295189b2012-06-20 16:38:30 -07007790 if ((pAdapter->device_mode == WLAN_HDD_INFRA_STATION)
Jeff Johnson295189b2012-06-20 16:38:30 -07007791 || (pAdapter->device_mode == WLAN_HDD_P2P_CLIENT)
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307792 )
Jeff Johnson295189b2012-06-20 16:38:30 -07007793 {
Gopichand Nakkala29149562013-05-10 21:43:41 +05307794 if ( (eCSR_ENCRYPT_TYPE_TKIP !=
Arif Hussain6943f522013-11-04 20:10:10 -08007795 pHddStaCtx->conn_info.ucEncryptionType) &&
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307796 (eCSR_ENCRYPT_TYPE_AES !=
Arif Hussain6943f522013-11-04 20:10:10 -08007797 pHddStaCtx->conn_info.ucEncryptionType)
Jeff Johnson295189b2012-06-20 16:38:30 -07007798 )
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307799 {
7800 /* if default key index is not same as previous one,
Jeff Johnson295189b2012-06-20 16:38:30 -07007801 * then update the default key index */
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307802
Jeff Johnson295189b2012-06-20 16:38:30 -07007803 tCsrRoamSetKey setKey;
7804 v_U32_t roamId= 0xFF;
7805 tCsrKeys *Keys = &pWextState->roamProfile.Keys;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307806
7807 hddLog(VOS_TRACE_LEVEL_INFO_HIGH, "%s: default tx key index %d",
Jeff Johnson295189b2012-06-20 16:38:30 -07007808 __func__, key_index);
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307809
Jeff Johnson295189b2012-06-20 16:38:30 -07007810 Keys->defaultIndex = (u8)key_index;
7811 vos_mem_zero(&setKey,sizeof(tCsrRoamSetKey));
7812 setKey.keyId = key_index;
7813 setKey.keyLength = Keys->KeyLength[key_index];
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307814
7815 vos_mem_copy(&setKey.Key[0],
7816 &Keys->KeyMaterial[key_index][0],
Jeff Johnson295189b2012-06-20 16:38:30 -07007817 Keys->KeyLength[key_index]);
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307818
Gopichand Nakkala29149562013-05-10 21:43:41 +05307819 setKey.keyDirection = eSIR_TX_RX;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307820
7821 vos_mem_copy(setKey.peerMac,
Jeff Johnson295189b2012-06-20 16:38:30 -07007822 &pHddStaCtx->conn_info.bssId[0],
7823 WNI_CFG_BSSID_LEN);
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307824
Gopichand Nakkala29149562013-05-10 21:43:41 +05307825 if (Keys->KeyLength[key_index] == CSR_WEP40_KEY_LEN &&
7826 pWextState->roamProfile.EncryptionType.encryptionType[0] ==
7827 eCSR_ENCRYPT_TYPE_WEP104)
7828 {
7829 /*In the case of dynamic wep supplicant hardcodes DWEP type to eCSR_ENCRYPT_TYPE_WEP104
7830 even though ap is configured for WEP-40 encryption. In this canse the key length
7831 is 5 but the encryption type is 104 hence checking the key langht(5) and encryption
7832 type(104) and switching encryption type to 40*/
7833 pWextState->roamProfile.EncryptionType.encryptionType[0] =
7834 eCSR_ENCRYPT_TYPE_WEP40;
7835 pWextState->roamProfile.mcEncryptionType.encryptionType[0] =
7836 eCSR_ENCRYPT_TYPE_WEP40;
7837 }
7838
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307839 setKey.encType =
Jeff Johnson295189b2012-06-20 16:38:30 -07007840 pWextState->roamProfile.EncryptionType.encryptionType[0];
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307841
Jeff Johnson295189b2012-06-20 16:38:30 -07007842 /* issue set key request */
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307843 status = sme_RoamSetKey( WLAN_HDD_GET_HAL_CTX(pAdapter),
Jeff Johnson295189b2012-06-20 16:38:30 -07007844 pAdapter->sessionId, &setKey, &roamId );
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307845
Jeff Johnson295189b2012-06-20 16:38:30 -07007846 if ( 0 != status )
7847 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307848 hddLog(VOS_TRACE_LEVEL_ERROR,
7849 "%s: sme_RoamSetKey failed, returned %d", __func__,
Jeff Johnson295189b2012-06-20 16:38:30 -07007850 status);
7851 return -EINVAL;
7852 }
7853 }
7854 }
7855
7856 /* In SoftAp mode setting key direction for default mode */
7857 else if ( WLAN_HDD_SOFTAP == pAdapter->device_mode )
7858 {
7859 if ( (eCSR_ENCRYPT_TYPE_TKIP !=
7860 pWextState->roamProfile.EncryptionType.encryptionType[0]) &&
7861 (eCSR_ENCRYPT_TYPE_AES !=
7862 pWextState->roamProfile.EncryptionType.encryptionType[0])
7863 )
7864 {
7865 /* Saving key direction for default key index to TX default */
7866 hdd_ap_ctx_t *pAPCtx = WLAN_HDD_GET_AP_CTX_PTR(pAdapter);
7867 pAPCtx->wepKey[key_index].keyDirection = eSIR_TX_DEFAULT;
7868 }
7869 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307870
Jeff Johnson295189b2012-06-20 16:38:30 -07007871 return status;
7872}
7873
Mahesh A Saptasagar1a51bc02014-06-02 18:28:08 +05307874#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
7875static int wlan_hdd_cfg80211_set_default_key( struct wiphy *wiphy,
7876 struct net_device *ndev,
7877 u8 key_index,
7878 bool unicast, bool multicast)
7879#else
7880static int wlan_hdd_cfg80211_set_default_key( struct wiphy *wiphy,
7881 struct net_device *ndev,
7882 u8 key_index)
7883#endif
7884{
7885 int ret;
7886 vos_ssr_protect(__func__);
7887#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
7888 ret = __wlan_hdd_cfg80211_set_default_key(wiphy, ndev, key_index, unicast,
7889 multicast);
7890#else
7891 ret = __wlan_hdd_cfg80211_set_default_key(wiphy, ndev, key_index);
7892#endif
7893 vos_ssr_unprotect(__func__);
7894
7895 return ret;
7896}
7897
Jeff Johnson295189b2012-06-20 16:38:30 -07007898/*
7899 * FUNCTION: wlan_hdd_cfg80211_inform_bss
7900 * This function is used to inform the BSS details to nl80211 interface.
7901 */
7902static struct cfg80211_bss* wlan_hdd_cfg80211_inform_bss(
7903 hdd_adapter_t *pAdapter, tCsrRoamConnectedProfile *roamProfile)
7904{
7905 struct net_device *dev = pAdapter->dev;
7906 struct wireless_dev *wdev = dev->ieee80211_ptr;
7907 struct wiphy *wiphy = wdev->wiphy;
7908 tSirBssDescription *pBssDesc = roamProfile->pBssDesc;
7909 int chan_no;
7910 int ie_length;
7911 const char *ie;
7912 unsigned int freq;
7913 struct ieee80211_channel *chan;
7914 int rssi = 0;
7915 struct cfg80211_bss *bss = NULL;
7916
7917 ENTER();
7918
7919 if( NULL == pBssDesc )
7920 {
Arif Hussain6d2a3322013-11-17 19:50:10 -08007921 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: pBssDesc is NULL", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07007922 return bss;
7923 }
7924
7925 chan_no = pBssDesc->channelId;
7926 ie_length = GET_IE_LEN_IN_BSS_DESC( pBssDesc->length );
7927 ie = ((ie_length != 0) ? (const char *)&pBssDesc->ieFields: NULL);
7928
7929 if( NULL == ie )
7930 {
Arif Hussain6d2a3322013-11-17 19:50:10 -08007931 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: IE of BSS descriptor is NULL", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07007932 return bss;
7933 }
7934
7935#if (LINUX_VERSION_CODE > KERNEL_VERSION(2,6,38))
7936 if (chan_no <= ARRAY_SIZE(hdd_channels_2_4_GHZ))
7937 {
7938 freq = ieee80211_channel_to_frequency(chan_no, IEEE80211_BAND_2GHZ);
7939 }
7940 else
7941 {
7942 freq = ieee80211_channel_to_frequency(chan_no, IEEE80211_BAND_5GHZ);
7943 }
7944#else
7945 freq = ieee80211_channel_to_frequency(chan_no);
7946#endif
7947
7948 chan = __ieee80211_get_channel(wiphy, freq);
7949
Santhosh Kumar Padmaa45fdb12014-04-15 15:54:38 +05307950 if (!chan) {
7951 hddLog(VOS_TRACE_LEVEL_ERROR, "%s chan pointer is NULL", __func__);
7952 return NULL;
7953 }
7954
Abhishek Singhaee43942014-06-16 18:55:47 +05307955 rssi = (VOS_MIN ((pBssDesc->rssi + pBssDesc->sinr), 0))*100;
Jeff Johnson295189b2012-06-20 16:38:30 -07007956
Abhishek Singhaee43942014-06-16 18:55:47 +05307957 return cfg80211_inform_bss(wiphy, chan, pBssDesc->bssId,
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307958 le64_to_cpu(*(__le64 *)pBssDesc->timeStamp),
Jeff Johnson295189b2012-06-20 16:38:30 -07007959 pBssDesc->capabilityInfo,
7960 pBssDesc->beaconInterval, ie, ie_length,
Abhishek Singhaee43942014-06-16 18:55:47 +05307961 rssi, GFP_KERNEL );
Jeff Johnson295189b2012-06-20 16:38:30 -07007962}
7963
7964
7965
7966/*
7967 * FUNCTION: wlan_hdd_cfg80211_inform_bss_frame
7968 * This function is used to inform the BSS details to nl80211 interface.
7969 */
7970struct cfg80211_bss*
7971wlan_hdd_cfg80211_inform_bss_frame( hdd_adapter_t *pAdapter,
7972 tSirBssDescription *bss_desc
7973 )
7974{
7975 /*
7976 cfg80211_inform_bss() is not updating ie field of bss entry, if entry
7977 already exists in bss data base of cfg80211 for that particular BSS ID.
7978 Using cfg80211_inform_bss_frame to update the bss entry instead of
7979 cfg80211_inform_bss, But this call expects mgmt packet as input. As of
7980 now there is no possibility to get the mgmt(probe response) frame from PE,
7981 converting bss_desc to ieee80211_mgmt(probe response) and passing to
7982 cfg80211_inform_bss_frame.
7983 */
7984 struct net_device *dev = pAdapter->dev;
7985 struct wireless_dev *wdev = dev->ieee80211_ptr;
7986 struct wiphy *wiphy = wdev->wiphy;
7987 int chan_no = bss_desc->channelId;
Madan Mohan Koyyalamudi86f629e2012-11-09 16:27:29 -08007988#ifdef WLAN_ENABLE_AGEIE_ON_SCAN_RESULTS
7989 qcom_ie_age *qie_age = NULL;
7990 int ie_length = GET_IE_LEN_IN_BSS_DESC( bss_desc->length ) + sizeof(qcom_ie_age);
7991#else
Jeff Johnson295189b2012-06-20 16:38:30 -07007992 int ie_length = GET_IE_LEN_IN_BSS_DESC( bss_desc->length );
Madan Mohan Koyyalamudi86f629e2012-11-09 16:27:29 -08007993#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07007994 const char *ie =
7995 ((ie_length != 0) ? (const char *)&bss_desc->ieFields: NULL);
7996 unsigned int freq;
7997 struct ieee80211_channel *chan;
Abhishek Singh1e2bfa32014-01-02 15:44:15 +05307998 struct ieee80211_mgmt *mgmt = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -07007999 struct cfg80211_bss *bss_status = NULL;
8000 size_t frame_len = sizeof (struct ieee80211_mgmt) + ie_length;
8001 int rssi = 0;
Wilson Yangf80a0542013-10-07 13:02:37 -07008002 hdd_context_t *pHddCtx;
8003 int status;
Jeff Johnsone7245742012-09-05 17:12:55 -07008004#ifdef WLAN_OPEN_SOURCE
8005 struct timespec ts;
8006#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07008007
Wilson Yangf80a0542013-10-07 13:02:37 -07008008 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
8009 status = wlan_hdd_validate_context(pHddCtx);
8010
8011 /*bss_update is not allowed during wlan driver loading or unloading*/
Mihir Shete18156292014-03-11 15:38:30 +05308012 if (WLAN_HDD_IS_LOAD_UNLOAD_IN_PROGRESS(pHddCtx))
Wilson Yangf80a0542013-10-07 13:02:37 -07008013 {
8014 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
8015 "%s:Loading_unloading in Progress. Ignore!!!",__func__);
8016 return NULL;
8017 }
8018
8019
8020 if (0 != status)
8021 {
8022 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
8023 "%s: HDD context is not valid", __func__);
Madan Mohan Koyyalamudi2e5c9142012-11-02 13:17:48 -07008024 return NULL;
Wilson Yangf80a0542013-10-07 13:02:37 -07008025 }
8026
Abhishek Singh1e2bfa32014-01-02 15:44:15 +05308027 mgmt = kzalloc((sizeof (struct ieee80211_mgmt) + ie_length), GFP_KERNEL);
Wilson Yangf80a0542013-10-07 13:02:37 -07008028 if (!mgmt)
8029 {
8030 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
8031 "%s: memory allocation failed ", __func__);
8032 return NULL;
8033 }
Madan Mohan Koyyalamudi2e5c9142012-11-02 13:17:48 -07008034
Jeff Johnson295189b2012-06-20 16:38:30 -07008035 memcpy(mgmt->bssid, bss_desc->bssId, ETH_ALEN);
Jeff Johnsone7245742012-09-05 17:12:55 -07008036
8037#ifdef WLAN_OPEN_SOURCE
8038 /* Android does not want the timestamp from the frame.
8039 Instead it wants a monotonic increasing value */
8040 get_monotonic_boottime(&ts);
8041 mgmt->u.probe_resp.timestamp =
8042 ((u64)ts.tv_sec * 1000000) + (ts.tv_nsec / 1000);
8043#else
8044 /* keep old behavior for non-open source (for now) */
Jeff Johnson295189b2012-06-20 16:38:30 -07008045 memcpy(&mgmt->u.probe_resp.timestamp, bss_desc->timeStamp,
8046 sizeof (bss_desc->timeStamp));
Jeff Johnsone7245742012-09-05 17:12:55 -07008047
8048#endif
8049
Jeff Johnson295189b2012-06-20 16:38:30 -07008050 mgmt->u.probe_resp.beacon_int = bss_desc->beaconInterval;
8051 mgmt->u.probe_resp.capab_info = bss_desc->capabilityInfo;
Madan Mohan Koyyalamudi86f629e2012-11-09 16:27:29 -08008052
8053#ifdef WLAN_ENABLE_AGEIE_ON_SCAN_RESULTS
8054 /* GPS Requirement: need age ie per entry. Using vendor specific. */
8055 /* Assuming this is the last IE, copy at the end */
8056 ie_length -=sizeof(qcom_ie_age);
8057 qie_age = (qcom_ie_age *)(mgmt->u.probe_resp.variable + ie_length);
8058 qie_age->element_id = QCOM_VENDOR_IE_ID;
8059 qie_age->len = QCOM_VENDOR_IE_AGE_LEN;
8060 qie_age->oui_1 = QCOM_OUI1;
8061 qie_age->oui_2 = QCOM_OUI2;
8062 qie_age->oui_3 = QCOM_OUI3;
8063 qie_age->type = QCOM_VENDOR_IE_AGE_TYPE;
8064 qie_age->age = vos_timer_get_system_ticks() - bss_desc->nReceivedTime;
8065#endif
8066
Jeff Johnson295189b2012-06-20 16:38:30 -07008067 memcpy(mgmt->u.probe_resp.variable, ie, ie_length);
Gopichand Nakkalad908ec82013-05-16 19:32:19 +05308068 if (bss_desc->fProbeRsp)
8069 {
8070 mgmt->frame_control |=
8071 (u16)(IEEE80211_FTYPE_MGMT | IEEE80211_STYPE_PROBE_RESP);
8072 }
8073 else
8074 {
8075 mgmt->frame_control |=
8076 (u16)(IEEE80211_FTYPE_MGMT | IEEE80211_STYPE_BEACON);
8077 }
Jeff Johnson295189b2012-06-20 16:38:30 -07008078
8079#if (LINUX_VERSION_CODE > KERNEL_VERSION(2,6,38))
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308080 if (chan_no <= ARRAY_SIZE(hdd_channels_2_4_GHZ) &&
Jeff Johnson295189b2012-06-20 16:38:30 -07008081 (wiphy->bands[IEEE80211_BAND_2GHZ] != NULL))
8082 {
8083 freq = ieee80211_channel_to_frequency(chan_no, IEEE80211_BAND_2GHZ);
8084 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308085 else if ((chan_no > ARRAY_SIZE(hdd_channels_2_4_GHZ)) &&
Jeff Johnson295189b2012-06-20 16:38:30 -07008086 (wiphy->bands[IEEE80211_BAND_5GHZ] != NULL))
8087
8088 {
8089 freq = ieee80211_channel_to_frequency(chan_no, IEEE80211_BAND_5GHZ);
8090 }
8091 else
8092 {
Nirav Shah20ac06f2013-12-12 18:14:06 +05308093 hddLog(VOS_TRACE_LEVEL_ERROR, "%s Invalid chan_no:%d",
8094 __func__, chan_no);
Jeff Johnson295189b2012-06-20 16:38:30 -07008095 kfree(mgmt);
8096 return NULL;
8097 }
8098#else
8099 freq = ieee80211_channel_to_frequency(chan_no);
8100#endif
8101 chan = __ieee80211_get_channel(wiphy, freq);
Leela V Kiran Kumar Reddy90032de2013-01-24 18:33:30 -08008102 /*when the band is changed on the fly using the GUI, three things are done
8103 * 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)
8104 * as part of the scan abort, message willbe queued to PE and we proceed with flushing and changinh the band.
8105 * pe will stop the scanning further and report back the results what ever it had till now by calling the call back function.
8106 * if the time between update band and scandone call back is sufficent enough the band change reflects in SME, SME validates the channels
8107 * and discards the channels correponding to previous band and calls back with zero bss results.
8108 * 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
8109 * all the channels correponding to previous band.this is due to race condition.but those channels are invalid to the new band and so
8110 * this function __ieee80211_get_channel will return NULL.Each time we report scan result with this pointer null warning kernel trace is printed.
8111 * if the scan results contain large number of APs continuosly kernel warning trace is printed and it will lead to apps watch dog bark.
8112 * So drop the bss and continue to next bss.
8113 */
8114 if(chan == NULL)
8115 {
Nirav Shah20ac06f2013-12-12 18:14:06 +05308116 hddLog(VOS_TRACE_LEVEL_ERROR, "%s chan pointer is NULL", __func__);
Chilam Ngc4244af2013-04-01 15:37:32 -07008117 kfree(mgmt);
Leela V Kiran Kumar Reddy90032de2013-01-24 18:33:30 -08008118 return NULL;
8119 }
Jeff Johnson295189b2012-06-20 16:38:30 -07008120 /*To keep the rssi icon of the connected AP in the scan window
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308121 *and the rssi icon of the wireless networks in sync
Jeff Johnson295189b2012-06-20 16:38:30 -07008122 * */
8123 if (( eConnectionState_Associated ==
8124 pAdapter->sessionCtx.station.conn_info.connState ) &&
8125 ( VOS_TRUE == vos_mem_compare(bss_desc->bssId,
8126 pAdapter->sessionCtx.station.conn_info.bssId,
8127 WNI_CFG_BSSID_LEN)))
8128 {
8129 /* supplicant takes the signal strength in terms of mBm(100*dBm) */
8130 rssi = (pAdapter->rssi * 100);
8131 }
8132 else
8133 {
8134 rssi = (VOS_MIN ((bss_desc->rssi + bss_desc->sinr), 0))*100;
8135 }
8136
Nirav Shah20ac06f2013-12-12 18:14:06 +05308137 hddLog(VOS_TRACE_LEVEL_INFO, "%s: BSSID:" MAC_ADDRESS_STR " Channel:%d"
8138 "RSSI:%d", __func__, MAC_ADDR_ARRAY(mgmt->bssid),
8139 chan->center_freq, (int)(rssi/100));
8140
Jeff Johnson295189b2012-06-20 16:38:30 -07008141 bss_status = cfg80211_inform_bss_frame(wiphy, chan, mgmt,
8142 frame_len, rssi, GFP_KERNEL);
8143 kfree(mgmt);
8144 return bss_status;
8145}
8146
8147/*
8148 * FUNCTION: wlan_hdd_cfg80211_update_bss_db
8149 * This function is used to update the BSS data base of CFG8011
8150 */
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308151struct cfg80211_bss* wlan_hdd_cfg80211_update_bss_db( hdd_adapter_t *pAdapter,
Jeff Johnson295189b2012-06-20 16:38:30 -07008152 tCsrRoamInfo *pRoamInfo
8153 )
8154{
8155 tCsrRoamConnectedProfile roamProfile;
8156 tHalHandle hHal = WLAN_HDD_GET_HAL_CTX(pAdapter);
8157 struct cfg80211_bss *bss = NULL;
8158
8159 ENTER();
8160
8161 memset(&roamProfile, 0, sizeof(tCsrRoamConnectedProfile));
8162 sme_RoamGetConnectProfile(hHal, pAdapter->sessionId, &roamProfile);
8163
8164 if (NULL != roamProfile.pBssDesc)
8165 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308166 bss = wlan_hdd_cfg80211_inform_bss(pAdapter,
Jeff Johnson295189b2012-06-20 16:38:30 -07008167 &roamProfile);
8168
8169 if (NULL == bss)
8170 {
8171 hddLog(VOS_TRACE_LEVEL_INFO, "%s: cfg80211_inform_bss return NULL",
8172 __func__);
8173 }
8174
8175 sme_RoamFreeConnectProfile(hHal, &roamProfile);
8176 }
8177 else
8178 {
8179 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: roamProfile.pBssDesc is NULL",
8180 __func__);
8181 }
8182 return bss;
8183}
8184
8185/*
8186 * FUNCTION: wlan_hdd_cfg80211_update_bss
8187 */
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308188static int wlan_hdd_cfg80211_update_bss( struct wiphy *wiphy,
8189 hdd_adapter_t *pAdapter
Jeff Johnson295189b2012-06-20 16:38:30 -07008190 )
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308191{
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +05308192 tHalHandle hHal = WLAN_HDD_GET_HAL_CTX(pAdapter);
Jeff Johnson295189b2012-06-20 16:38:30 -07008193 tCsrScanResultInfo *pScanResult;
8194 eHalStatus status = 0;
8195 tScanResultHandle pResult;
8196 struct cfg80211_bss *bss_status = NULL;
Wilson Yangf80a0542013-10-07 13:02:37 -07008197 hdd_context_t *pHddCtx;
Jeff Johnson295189b2012-06-20 16:38:30 -07008198
8199 ENTER();
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +05308200
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05308201 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
8202 TRACE_CODE_HDD_CFG80211_UPDATE_BSS,
8203 NO_SESSION, pAdapter->sessionId));
8204
Wilson Yangf80a0542013-10-07 13:02:37 -07008205 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
8206
8207 if (pHddCtx->isLogpInProgress)
Jeff Johnson295189b2012-06-20 16:38:30 -07008208 {
Wilson Yangf80a0542013-10-07 13:02:37 -07008209 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
8210 "%s:LOGP in Progress. Ignore!!!",__func__);
8211 return -EAGAIN;
Jeff Johnson295189b2012-06-20 16:38:30 -07008212 }
8213
Wilson Yangf80a0542013-10-07 13:02:37 -07008214
8215 /*bss_update is not allowed during wlan driver loading or unloading*/
Mihir Shete18156292014-03-11 15:38:30 +05308216 if (WLAN_HDD_IS_LOAD_UNLOAD_IN_PROGRESS(pHddCtx))
Wilson Yangf80a0542013-10-07 13:02:37 -07008217 {
8218 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
8219 "%s:Loading_unloading in Progress. Ignore!!!",__func__);
8220 return VOS_STATUS_E_PERM;
8221 }
8222
8223
Jeff Johnson295189b2012-06-20 16:38:30 -07008224 /*
8225 * start getting scan results and populate cgf80211 BSS database
8226 */
8227 status = sme_ScanGetResult(hHal, pAdapter->sessionId, NULL, &pResult);
8228
8229 /* no scan results */
8230 if (NULL == pResult)
8231 {
Nirav Shah20ac06f2013-12-12 18:14:06 +05308232 hddLog(VOS_TRACE_LEVEL_INFO, "%s: No scan result Status %d",
8233 __func__, status);
Jeff Johnson295189b2012-06-20 16:38:30 -07008234 return status;
8235 }
8236
8237 pScanResult = sme_ScanResultGetFirst(hHal, pResult);
8238
8239 while (pScanResult)
8240 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308241 /*
8242 * cfg80211_inform_bss() is not updating ie field of bss entry, if
8243 * entry already exists in bss data base of cfg80211 for that
8244 * particular BSS ID. Using cfg80211_inform_bss_frame to update the
8245 * bss entry instead of cfg80211_inform_bss, But this call expects
8246 * mgmt packet as input. As of now there is no possibility to get
8247 * the mgmt(probe response) frame from PE, converting bss_desc to
Jeff Johnson295189b2012-06-20 16:38:30 -07008248 * ieee80211_mgmt(probe response) and passing to c
8249 * fg80211_inform_bss_frame.
8250 * */
8251
8252 bss_status = wlan_hdd_cfg80211_inform_bss_frame(pAdapter,
8253 &pScanResult->BssDescriptor);
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308254
Jeff Johnson295189b2012-06-20 16:38:30 -07008255
8256 if (NULL == bss_status)
8257 {
8258 hddLog(VOS_TRACE_LEVEL_INFO,
Arif Hussain6d2a3322013-11-17 19:50:10 -08008259 "%s: NULL returned by cfg80211_inform_bss", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07008260 }
8261 else
8262 {
Yue Maf49ba872013-08-19 12:04:25 -07008263 cfg80211_put_bss(
8264#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,9,0))
8265 wiphy,
8266#endif
8267 bss_status);
Jeff Johnson295189b2012-06-20 16:38:30 -07008268 }
8269
8270 pScanResult = sme_ScanResultGetNext(hHal, pResult);
8271 }
8272
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308273 sme_ScanResultPurge(hHal, pResult);
Jeff Johnson295189b2012-06-20 16:38:30 -07008274
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308275 return 0;
Jeff Johnson295189b2012-06-20 16:38:30 -07008276}
8277
Jeff Johnson04dd8a82012-06-29 20:41:40 -07008278void
8279hddPrintMacAddr(tCsrBssid macAddr, tANI_U8 logLevel)
8280{
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308281 VOS_TRACE(VOS_MODULE_ID_HDD, logLevel,
Arif Hussaina7c8e412013-11-20 11:06:42 -08008282 MAC_ADDRESS_STR, MAC_ADDR_ARRAY(macAddr));
Jeff Johnson04dd8a82012-06-29 20:41:40 -07008283} /****** end hddPrintMacAddr() ******/
8284
8285void
Madan Mohan Koyyalamudic75be962012-10-18 19:19:03 -07008286hddPrintPmkId(tANI_U8 *pmkId, tANI_U8 logLevel)
Jeff Johnson04dd8a82012-06-29 20:41:40 -07008287{
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308288 VOS_TRACE(VOS_MODULE_ID_HDD, logLevel,
Arif Hussain6d2a3322013-11-17 19:50:10 -08008289 "%02X:%02X:%02X:%02X:%02X:%02X:%02X:%02X:%02X:%02X:%02X:%02X:%02X:%02X:%02X:%02X",
Madan Mohan Koyyalamudic75be962012-10-18 19:19:03 -07008290 pmkId[0], pmkId[1], pmkId[2], pmkId[3], pmkId[4],
8291 pmkId[5], pmkId[6], pmkId[7], pmkId[8], pmkId[9], pmkId[10],
8292 pmkId[11], pmkId[12], pmkId[13], pmkId[14], pmkId[15]);
Jeff Johnson04dd8a82012-06-29 20:41:40 -07008293} /****** end hddPrintPmkId() ******/
8294
8295//hddPrintMacAddr(tCsrBssid macAddr, tANI_U8 logLevel);
8296//hddPrintMacAddr(macAddr, VOS_TRACE_LEVEL_FATAL);
8297
8298//void sirDumpBuf(tpAniSirGlobal pMac, tANI_U8 modId, tANI_U32 level, tANI_U8 *buf, tANI_U32 size);
8299//sirDumpBuf(pMac, VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL, pmkid, 16);
8300
8301#define dump_bssid(bssid) \
8302 { \
Jeff Johnsone7245742012-09-05 17:12:55 -07008303 hddLog(VOS_TRACE_LEVEL_INFO, "BSSID (MAC) address:\t"); \
8304 hddPrintMacAddr(bssid, VOS_TRACE_LEVEL_INFO);\
Jeff Johnson04dd8a82012-06-29 20:41:40 -07008305 }
8306
8307#define dump_pmkid(pMac, pmkid) \
8308 { \
Jeff Johnsone7245742012-09-05 17:12:55 -07008309 hddLog(VOS_TRACE_LEVEL_INFO, "PMKSA-ID:\t"); \
8310 hddPrintPmkId(pmkid, VOS_TRACE_LEVEL_INFO);\
Jeff Johnson04dd8a82012-06-29 20:41:40 -07008311 }
8312
Madan Mohan Koyyalamudi1b4afb02012-10-22 15:25:16 -07008313#if defined(FEATURE_WLAN_LFR) && (LINUX_VERSION_CODE >= KERNEL_VERSION(3,4,0))
Jeff Johnson04dd8a82012-06-29 20:41:40 -07008314/*
8315 * FUNCTION: wlan_hdd_cfg80211_pmksa_candidate_notify
8316 * This function is used to notify the supplicant of a new PMKSA candidate.
8317 */
8318int wlan_hdd_cfg80211_pmksa_candidate_notify(
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308319 hdd_adapter_t *pAdapter, tCsrRoamInfo *pRoamInfo,
Jeff Johnson04dd8a82012-06-29 20:41:40 -07008320 int index, bool preauth )
8321{
Jeff Johnsone7245742012-09-05 17:12:55 -07008322#ifdef FEATURE_WLAN_OKC
Jeff Johnson04dd8a82012-06-29 20:41:40 -07008323 struct net_device *dev = pAdapter->dev;
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07008324 hdd_context_t *pHddCtx = (hdd_context_t*)pAdapter->pHddCtx;
Jeff Johnson04dd8a82012-06-29 20:41:40 -07008325
8326 ENTER();
Jeff Johnsone7245742012-09-05 17:12:55 -07008327 hddLog(VOS_TRACE_LEVEL_INFO, "%s is going to notify supplicant of:", __func__);
Jeff Johnson04dd8a82012-06-29 20:41:40 -07008328
8329 if( NULL == pRoamInfo )
8330 {
Arif Hussain6d2a3322013-11-17 19:50:10 -08008331 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: pRoamInfo is NULL", __func__);
Jeff Johnson04dd8a82012-06-29 20:41:40 -07008332 return -EINVAL;
8333 }
8334
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07008335 if (eANI_BOOLEAN_TRUE == hdd_is_okc_mode_enabled(pHddCtx))
8336 {
8337 dump_bssid(pRoamInfo->bssid);
8338 cfg80211_pmksa_candidate_notify(dev, index,
Jeff Johnson04dd8a82012-06-29 20:41:40 -07008339 pRoamInfo->bssid, preauth, GFP_KERNEL);
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07008340 }
Jeff Johnsone7245742012-09-05 17:12:55 -07008341#endif /* FEATURE_WLAN_OKC */
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308342 return 0;
Jeff Johnson04dd8a82012-06-29 20:41:40 -07008343}
8344#endif //FEATURE_WLAN_LFR
8345
Yue Maef608272013-04-08 23:09:17 -07008346#ifdef FEATURE_WLAN_LFR_METRICS
8347/*
8348 * FUNCTION: wlan_hdd_cfg80211_roam_metrics_preauth
8349 * 802.11r/LFR metrics reporting function to report preauth initiation
8350 *
8351 */
8352#define MAX_LFR_METRICS_EVENT_LENGTH 100
8353VOS_STATUS wlan_hdd_cfg80211_roam_metrics_preauth(hdd_adapter_t *pAdapter,
8354 tCsrRoamInfo *pRoamInfo)
8355{
8356 unsigned char metrics_notification[MAX_LFR_METRICS_EVENT_LENGTH + 1];
8357 union iwreq_data wrqu;
8358
8359 ENTER();
8360
8361 if (NULL == pAdapter)
8362 {
8363 hddLog(LOGE, "%s: pAdapter is NULL!", __func__);
8364 return VOS_STATUS_E_FAILURE;
8365 }
8366
8367 /* create the event */
8368 memset(&wrqu, 0, sizeof(wrqu));
8369 memset(metrics_notification, 0, sizeof(metrics_notification));
8370
8371 wrqu.data.pointer = metrics_notification;
8372 wrqu.data.length = scnprintf(metrics_notification,
8373 sizeof(metrics_notification), "QCOM: LFR_PREAUTH_INIT "
8374 MAC_ADDRESS_STR, MAC_ADDR_ARRAY(pRoamInfo->bssid));
8375
8376 wireless_send_event(pAdapter->dev, IWEVCUSTOM, &wrqu, metrics_notification);
8377
8378 EXIT();
8379
8380 return VOS_STATUS_SUCCESS;
8381}
8382
8383/*
8384 * FUNCTION: wlan_hdd_cfg80211_roam_metrics_preauth_status
8385 * 802.11r/LFR metrics reporting function to report preauth completion
8386 * or failure
8387 */
8388VOS_STATUS wlan_hdd_cfg80211_roam_metrics_preauth_status(
8389 hdd_adapter_t *pAdapter, tCsrRoamInfo *pRoamInfo, bool preauth_status)
8390{
8391 unsigned char metrics_notification[MAX_LFR_METRICS_EVENT_LENGTH + 1];
8392 union iwreq_data wrqu;
8393
8394 ENTER();
8395
8396 if (NULL == pAdapter)
8397 {
8398 hddLog(LOGE, "%s: pAdapter is NULL!", __func__);
8399 return VOS_STATUS_E_FAILURE;
8400 }
8401
8402 /* create the event */
8403 memset(&wrqu, 0, sizeof(wrqu));
8404 memset(metrics_notification, 0, sizeof(metrics_notification));
8405
8406 scnprintf(metrics_notification, sizeof(metrics_notification),
8407 "QCOM: LFR_PREAUTH_STATUS "MAC_ADDRESS_STR,
8408 MAC_ADDR_ARRAY(pRoamInfo->bssid));
8409
8410 if (1 == preauth_status)
8411 strncat(metrics_notification, " TRUE", 5);
8412 else
8413 strncat(metrics_notification, " FALSE", 6);
8414
8415 wrqu.data.pointer = metrics_notification;
8416 wrqu.data.length = strlen(metrics_notification);
8417
8418 wireless_send_event(pAdapter->dev, IWEVCUSTOM, &wrqu, metrics_notification);
8419
8420 EXIT();
8421
8422 return VOS_STATUS_SUCCESS;
8423}
8424
8425/*
8426 * FUNCTION: wlan_hdd_cfg80211_roam_metrics_handover
8427 * 802.11r/LFR metrics reporting function to report handover initiation
8428 *
8429 */
8430VOS_STATUS wlan_hdd_cfg80211_roam_metrics_handover(hdd_adapter_t * pAdapter,
8431 tCsrRoamInfo *pRoamInfo)
8432{
8433 unsigned char metrics_notification[MAX_LFR_METRICS_EVENT_LENGTH + 1];
8434 union iwreq_data wrqu;
8435
8436 ENTER();
8437
8438 if (NULL == pAdapter)
8439 {
8440 hddLog(LOGE, "%s: pAdapter is NULL!", __func__);
8441 return VOS_STATUS_E_FAILURE;
8442 }
8443
8444 /* create the event */
8445 memset(&wrqu, 0, sizeof(wrqu));
8446 memset(metrics_notification, 0, sizeof(metrics_notification));
8447
8448 wrqu.data.pointer = metrics_notification;
8449 wrqu.data.length = scnprintf(metrics_notification,
8450 sizeof(metrics_notification), "QCOM: LFR_PREAUTH_HANDOVER "
8451 MAC_ADDRESS_STR, MAC_ADDR_ARRAY(pRoamInfo->bssid));
8452
8453 wireless_send_event(pAdapter->dev, IWEVCUSTOM, &wrqu, metrics_notification);
8454
8455 EXIT();
8456
8457 return VOS_STATUS_SUCCESS;
8458}
8459#endif
8460
Jeff Johnson295189b2012-06-20 16:38:30 -07008461/*
8462 * FUNCTION: hdd_cfg80211_scan_done_callback
8463 * scanning callback function, called after finishing scan
8464 *
8465 */
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308466static eHalStatus hdd_cfg80211_scan_done_callback(tHalHandle halHandle,
Jeff Johnson295189b2012-06-20 16:38:30 -07008467 void *pContext, tANI_U32 scanId, eCsrScanStatus status)
8468{
8469 struct net_device *dev = (struct net_device *) pContext;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308470 //struct wireless_dev *wdev = dev->ieee80211_ptr;
Jeff Johnson295189b2012-06-20 16:38:30 -07008471 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( dev );
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -07008472 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
8473 hdd_scaninfo_t *pScanInfo = &pHddCtx->scan_info;
Jeff Johnson295189b2012-06-20 16:38:30 -07008474 struct cfg80211_scan_request *req = NULL;
8475 int ret = 0;
Mahesh A Saptasagar05a357e2014-02-26 16:28:06 +05308476 bool aborted = false;
c_hpothu6ff1c3c2013-10-01 19:01:57 +05308477 long waitRet = 0;
Jeff Johnson295189b2012-06-20 16:38:30 -07008478
8479 ENTER();
8480
8481 hddLog(VOS_TRACE_LEVEL_INFO,
8482 "%s called with halHandle = %p, pContext = %p,"
Arif Hussain6d2a3322013-11-17 19:50:10 -08008483 "scanID = %d, returned status = %d",
Jeff Johnson295189b2012-06-20 16:38:30 -07008484 __func__, halHandle, pContext, (int) scanId, (int) status);
8485
Kiet Lamac06e2c2013-10-23 16:25:07 +05308486 pScanInfo->mScanPendingCounter = 0;
8487
Jeff Johnson295189b2012-06-20 16:38:30 -07008488 //Block on scan req completion variable. Can't wait forever though.
c_hpothu6ff1c3c2013-10-01 19:01:57 +05308489 waitRet = wait_for_completion_interruptible_timeout(
Jeff Johnson295189b2012-06-20 16:38:30 -07008490 &pScanInfo->scan_req_completion_event,
8491 msecs_to_jiffies(WLAN_WAIT_TIME_SCAN_REQ));
c_hpothu6ff1c3c2013-10-01 19:01:57 +05308492 if (waitRet <= 0)
Jeff Johnson295189b2012-06-20 16:38:30 -07008493 {
c_hpothu6ff1c3c2013-10-01 19:01:57 +05308494 hddLog(VOS_TRACE_LEVEL_ERROR,
8495 "%s wait on scan_req_completion_event failed %ld",__func__, waitRet);
Jeff Johnson295189b2012-06-20 16:38:30 -07008496 VOS_ASSERT(pScanInfo->mScanPending);
Jeff Johnsone7245742012-09-05 17:12:55 -07008497 goto allow_suspend;
Jeff Johnson295189b2012-06-20 16:38:30 -07008498 }
8499
Yue Maef608272013-04-08 23:09:17 -07008500 if (pScanInfo->mScanPending != VOS_TRUE)
Jeff Johnson295189b2012-06-20 16:38:30 -07008501 {
8502 VOS_ASSERT(pScanInfo->mScanPending);
Jeff Johnsone7245742012-09-05 17:12:55 -07008503 goto allow_suspend;
Jeff Johnson295189b2012-06-20 16:38:30 -07008504 }
8505
8506 /* Check the scanId */
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308507 if (pScanInfo->scanId != scanId)
Jeff Johnson295189b2012-06-20 16:38:30 -07008508 {
8509 hddLog(VOS_TRACE_LEVEL_INFO,
8510 "%s called with mismatched scanId pScanInfo->scanId = %d "
Arif Hussain6d2a3322013-11-17 19:50:10 -08008511 "scanId = %d", __func__, (int) pScanInfo->scanId,
Jeff Johnson295189b2012-06-20 16:38:30 -07008512 (int) scanId);
8513 }
8514
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308515 ret = wlan_hdd_cfg80211_update_bss((WLAN_HDD_GET_CTX(pAdapter))->wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -07008516 pAdapter);
8517
8518 if (0 > ret)
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308519 hddLog(VOS_TRACE_LEVEL_INFO, "%s: NO SCAN result", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07008520
8521
8522 /* If any client wait scan result through WEXT
8523 * send scan done event to client */
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -07008524 if (pHddCtx->scan_info.waitScanResult)
Jeff Johnson295189b2012-06-20 16:38:30 -07008525 {
8526 /* The other scan request waiting for current scan finish
8527 * Send event to notify current scan finished */
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -07008528 if(WEXT_SCAN_PENDING_DELAY == pHddCtx->scan_info.scan_pending_option)
Jeff Johnson295189b2012-06-20 16:38:30 -07008529 {
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -07008530 vos_event_set(&pHddCtx->scan_info.scan_finished_event);
Jeff Johnson295189b2012-06-20 16:38:30 -07008531 }
8532 /* Send notify to WEXT client */
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -07008533 else if(WEXT_SCAN_PENDING_PIGGYBACK == pHddCtx->scan_info.scan_pending_option)
Jeff Johnson295189b2012-06-20 16:38:30 -07008534 {
8535 struct net_device *dev = pAdapter->dev;
8536 union iwreq_data wrqu;
8537 int we_event;
8538 char *msg;
8539
8540 memset(&wrqu, '\0', sizeof(wrqu));
8541 we_event = SIOCGIWSCAN;
8542 msg = NULL;
8543 wireless_send_event(dev, we_event, &wrqu, msg);
8544 }
8545 }
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -07008546 pHddCtx->scan_info.waitScanResult = FALSE;
Jeff Johnson295189b2012-06-20 16:38:30 -07008547
8548 /* Get the Scan Req */
8549 req = pAdapter->request;
8550
8551 if (!req)
8552 {
Arif Hussain6d2a3322013-11-17 19:50:10 -08008553 hddLog(VOS_TRACE_LEVEL_ERROR, "request is became NULL");
Madan Mohan Koyyalamudi9f5a10c2012-09-28 14:46:16 -07008554 pScanInfo->mScanPending = VOS_FALSE;
Jeff Johnsone7245742012-09-05 17:12:55 -07008555 goto allow_suspend;
Jeff Johnson295189b2012-06-20 16:38:30 -07008556 }
8557
8558 /*
8559 * setting up 0, just in case.
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308560 */
Jeff Johnson295189b2012-06-20 16:38:30 -07008561 req->n_ssids = 0;
8562 req->n_channels = 0;
8563 req->ie = 0;
8564
Jeff Johnson295189b2012-06-20 16:38:30 -07008565 pAdapter->request = NULL;
Jeff Johnsone7245742012-09-05 17:12:55 -07008566 /* Scan is no longer pending */
8567 pScanInfo->mScanPending = VOS_FALSE;
Jeff Johnson295189b2012-06-20 16:38:30 -07008568
Madan Mohan Koyyalamudib764bf82012-10-11 16:38:51 -07008569 /*
8570 * cfg80211_scan_done informing NL80211 about completion
8571 * of scanning
8572 */
Mahesh A Saptasagar05a357e2014-02-26 16:28:06 +05308573 if (status == eCSR_SCAN_ABORT || status == eCSR_SCAN_FAILURE)
8574 {
8575 aborted = true;
8576 }
8577 cfg80211_scan_done(req, aborted);
Madan Mohan Koyyalamudif4e81002012-11-13 10:46:38 -08008578 complete(&pScanInfo->abortscan_event_var);
Jeff Johnson295189b2012-06-20 16:38:30 -07008579
Jeff Johnsone7245742012-09-05 17:12:55 -07008580allow_suspend:
Madan Mohan Koyyalamudi9f5a10c2012-09-28 14:46:16 -07008581 /* release the wake lock at the end of the scan*/
8582 hdd_allow_suspend();
Jeff Johnsone7245742012-09-05 17:12:55 -07008583
Madan Mohan Koyyalamudi10d83a92012-09-28 15:47:05 -07008584 /* Acquire wakelock to handle the case where APP's tries to suspend
8585 * immediatly after the driver gets connect request(i.e after scan)
8586 * from supplicant, this result in app's is suspending and not able
8587 * to process the connect request to AP */
Mahesh A Saptasagarb9c50402014-01-16 15:49:22 +05308588 hdd_prevent_suspend_timeout(1000);
Madan Mohan Koyyalamudi10d83a92012-09-28 15:47:05 -07008589
Gopichand Nakkala638ebc72013-03-21 18:04:02 -07008590#ifdef FEATURE_WLAN_TDLS
c_hpothu3c8f8e82014-06-02 18:01:50 +05308591 if (!(eTDLS_SUPPORT_NOT_ENABLED == pHddCtx->tdls_mode))
8592 {
8593 wlan_hdd_tdls_scan_done_callback(pAdapter);
8594 }
Gopichand Nakkala638ebc72013-03-21 18:04:02 -07008595#endif
8596
Jeff Johnson295189b2012-06-20 16:38:30 -07008597 EXIT();
8598 return 0;
8599}
8600
8601/*
Rashmi Ramannab1429032014-04-26 14:59:09 +05308602 * FUNCTION: hdd_isConnectionInProgress
8603 * Go through each adapter and check if Connection is in progress
Madan Mohan Koyyalamudicfd53742013-01-11 15:29:03 -08008604 *
8605 */
Rashmi Ramannab1429032014-04-26 14:59:09 +05308606v_BOOL_t hdd_isConnectionInProgress( hdd_context_t *pHddCtx )
Madan Mohan Koyyalamudicfd53742013-01-11 15:29:03 -08008607{
8608 hdd_adapter_list_node_t *pAdapterNode = NULL, *pNext = NULL;
8609 hdd_station_ctx_t *pHddStaCtx = NULL;
8610 hdd_adapter_t *pAdapter = NULL;
8611 VOS_STATUS status = 0;
8612 v_U8_t staId = 0;
8613 v_U8_t *staMac = NULL;
8614
c_hpothu9b781ba2013-12-30 20:57:45 +05308615 if (TRUE == pHddCtx->btCoexModeSet)
8616 {
8617 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Rashmi Ramannab1429032014-04-26 14:59:09 +05308618 FL("BTCoex Mode operation in progress"));
8619 return VOS_TRUE;
c_hpothu9b781ba2013-12-30 20:57:45 +05308620 }
8621
Madan Mohan Koyyalamudicfd53742013-01-11 15:29:03 -08008622 status = hdd_get_front_adapter ( pHddCtx, &pAdapterNode );
8623
8624 while ( NULL != pAdapterNode && VOS_STATUS_SUCCESS == status )
8625 {
8626 pAdapter = pAdapterNode->pAdapter;
8627
8628 if( pAdapter )
8629 {
8630 hddLog(VOS_TRACE_LEVEL_INFO,
Sushant Kaushik8bc7df22014-04-09 17:55:29 +05308631 "%s: Adapter with device mode %s (%d) exists",
8632 __func__, hdd_device_modetoString(pAdapter->device_mode),
8633 pAdapter->device_mode);
Rashmi Ramannab1429032014-04-26 14:59:09 +05308634 if (((WLAN_HDD_INFRA_STATION == pAdapter->device_mode) ||
8635 (WLAN_HDD_P2P_CLIENT == pAdapter->device_mode) ||
8636 (WLAN_HDD_P2P_DEVICE == pAdapter->device_mode)) &&
8637 (eConnectionState_Connecting ==
8638 (WLAN_HDD_GET_STATION_CTX_PTR(pAdapter))->conn_info.connState))
8639 {
8640 hddLog(VOS_TRACE_LEVEL_ERROR,
8641 "%s: %p(%d) Connection is in progress", __func__,
8642 WLAN_HDD_GET_STATION_CTX_PTR(pAdapter), pAdapter->sessionId);
8643 return VOS_TRUE;
8644 }
Madan Mohan Koyyalamudicfd53742013-01-11 15:29:03 -08008645 if ((WLAN_HDD_INFRA_STATION == pAdapter->device_mode) ||
Sushant Kaushik8bc7df22014-04-09 17:55:29 +05308646 (WLAN_HDD_P2P_CLIENT == pAdapter->device_mode) ||
8647 (WLAN_HDD_P2P_DEVICE == pAdapter->device_mode))
Madan Mohan Koyyalamudicfd53742013-01-11 15:29:03 -08008648 {
8649 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
8650 if ((eConnectionState_Associated == pHddStaCtx->conn_info.connState) &&
Sushant Kaushik8bc7df22014-04-09 17:55:29 +05308651 (VOS_FALSE == pHddStaCtx->conn_info.uIsAuthenticated))
Madan Mohan Koyyalamudicfd53742013-01-11 15:29:03 -08008652 {
8653 staMac = (v_U8_t *) &(pAdapter->macAddressCurrent.bytes[0]);
8654 hddLog(VOS_TRACE_LEVEL_ERROR,
Arif Hussain24bafea2013-11-15 15:10:03 -08008655 "%s: client " MAC_ADDRESS_STR
8656 " is in the middle of WPS/EAPOL exchange.", __func__,
8657 MAC_ADDR_ARRAY(staMac));
Rashmi Ramannab1429032014-04-26 14:59:09 +05308658 return VOS_TRUE;
Madan Mohan Koyyalamudicfd53742013-01-11 15:29:03 -08008659 }
8660 }
8661 else if ((WLAN_HDD_SOFTAP == pAdapter->device_mode) ||
8662 (WLAN_HDD_P2P_GO == pAdapter->device_mode))
8663 {
8664 for (staId = 0; staId < WLAN_MAX_STA_COUNT; staId++)
8665 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308666 if ((pAdapter->aStaInfo[staId].isUsed) &&
Madan Mohan Koyyalamudicfd53742013-01-11 15:29:03 -08008667 (WLANTL_STA_CONNECTED == pAdapter->aStaInfo[staId].tlSTAState))
8668 {
8669 staMac = (v_U8_t *) &(pAdapter->aStaInfo[staId].macAddrSTA.bytes[0]);
8670
8671 hddLog(VOS_TRACE_LEVEL_ERROR,
Arif Hussain24bafea2013-11-15 15:10:03 -08008672 "%s: client " MAC_ADDRESS_STR " of SoftAP/P2P-GO is in the "
8673 "middle of WPS/EAPOL exchange.", __func__,
8674 MAC_ADDR_ARRAY(staMac));
Rashmi Ramannab1429032014-04-26 14:59:09 +05308675 return VOS_TRUE;
Madan Mohan Koyyalamudicfd53742013-01-11 15:29:03 -08008676 }
8677 }
8678 }
8679 }
8680 status = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
8681 pAdapterNode = pNext;
8682 }
Rashmi Ramannab1429032014-04-26 14:59:09 +05308683 return VOS_FALSE;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308684}
Madan Mohan Koyyalamudicfd53742013-01-11 15:29:03 -08008685
8686/*
Mahesh A Saptasagarfafb7fe2014-05-16 13:19:37 +05308687 * FUNCTION: __wlan_hdd_cfg80211_scan
Jeff Johnson295189b2012-06-20 16:38:30 -07008688 * this scan respond to scan trigger and update cfg80211 scan database
8689 * later, scan dump command can be used to recieve scan results
8690 */
Mahesh A Saptasagarfafb7fe2014-05-16 13:19:37 +05308691int __wlan_hdd_cfg80211_scan( struct wiphy *wiphy,
Jeff Johnson3bbe4bf2013-01-18 17:05:29 -08008692#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,6,0))
8693 struct net_device *dev,
8694#endif
8695 struct cfg80211_scan_request *request)
8696{
Siddharth Bhal0c162d02014-05-06 19:50:42 +05308697 hdd_adapter_t *pAdapter = NULL;
8698 hdd_context_t *pHddCtx = NULL;
8699 hdd_wext_state_t *pwextBuf = NULL;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05308700 hdd_config_t *cfg_param = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -07008701 tCsrScanRequest scanRequest;
8702 tANI_U8 *channelList = NULL, i;
8703 v_U32_t scanId = 0;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05308704 int status;
8705 hdd_scaninfo_t *pScanInfo = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -07008706 v_U8_t* pP2pIe = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -07008707
Siddharth Bhal0c162d02014-05-06 19:50:42 +05308708#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,6,0))
8709 struct net_device *dev = NULL;
8710 if (NULL == request)
8711 {
8712 hddLog(VOS_TRACE_LEVEL_ERROR,
8713 "%s: scan req param null", __func__);
8714 return -EINVAL;
8715 }
8716 dev = request->wdev->netdev;
8717#endif
8718
8719 pAdapter = WLAN_HDD_GET_PRIV_PTR( dev );
8720 pHddCtx = WLAN_HDD_GET_CTX( pAdapter );
8721 pwextBuf = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
8722
Jeff Johnson295189b2012-06-20 16:38:30 -07008723 ENTER();
8724
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +05308725
Sushant Kaushik8bc7df22014-04-09 17:55:29 +05308726 hddLog(VOS_TRACE_LEVEL_INFO, "%s: device_mode = %s (%d)",
8727 __func__, hdd_device_modetoString(pAdapter->device_mode),
8728 pAdapter->device_mode);
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +05308729
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05308730 status = wlan_hdd_validate_context(pHddCtx);
8731
8732 if (0 != status)
8733 {
8734 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
8735 "%s: HDD context is not valid", __func__);
8736 return status;
8737 }
8738
Siddharth Bhal0c162d02014-05-06 19:50:42 +05308739 if (NULL == pwextBuf)
8740 {
8741 hddLog (VOS_TRACE_LEVEL_ERROR, "%s ERROR: invalid WEXT state\n",
8742 __func__);
8743 return -EIO;
8744 }
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05308745 cfg_param = pHddCtx->cfg_ini;
8746 pScanInfo = &pHddCtx->scan_info;
8747
Jeff Johnson295189b2012-06-20 16:38:30 -07008748#ifdef WLAN_BTAMP_FEATURE
8749 //Scan not supported when AMP traffic is on.
Gopichand Nakkala681989c2013-03-06 22:27:48 -08008750 if (VOS_TRUE == WLANBAP_AmpSessionOn())
Jeff Johnson295189b2012-06-20 16:38:30 -07008751 {
Madan Mohan Koyyalamudifd4e1da2012-11-09 17:50:19 -08008752 hddLog(VOS_TRACE_LEVEL_ERROR,
Jeff Johnson295189b2012-06-20 16:38:30 -07008753 "%s: No scanning when AMP is on", __func__);
8754 return -EOPNOTSUPP;
8755 }
8756#endif
8757 //Scan on any other interface is not supported.
Gopichand Nakkala681989c2013-03-06 22:27:48 -08008758 if (pAdapter->device_mode == WLAN_HDD_SOFTAP)
Jeff Johnson295189b2012-06-20 16:38:30 -07008759 {
Gopichand Nakkala681989c2013-03-06 22:27:48 -08008760 hddLog(VOS_TRACE_LEVEL_ERROR,
Sushant Kaushik8bc7df22014-04-09 17:55:29 +05308761 "%s: Not scanning on device_mode = %s (%d)",
8762 __func__, hdd_device_modetoString(pAdapter->device_mode),
8763 pAdapter->device_mode);
Jeff Johnson295189b2012-06-20 16:38:30 -07008764 return -EOPNOTSUPP;
8765 }
8766
8767 if (TRUE == pScanInfo->mScanPending)
8768 {
Kiet Lamac06e2c2013-10-23 16:25:07 +05308769 if ( MAX_PENDING_LOG > pScanInfo->mScanPendingCounter++ )
8770 {
8771 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: mScanPending is TRUE", __func__);
8772 }
Gopichand Nakkala681989c2013-03-06 22:27:48 -08008773 return -EBUSY;
Jeff Johnson295189b2012-06-20 16:38:30 -07008774 }
8775
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308776 //Don't Allow Scan and return busy if Remain On
Jeff Johnson32d95a32012-09-10 13:15:23 -07008777 //Channel and action frame is pending
8778 //Otherwise Cancel Remain On Channel and allow Scan
8779 //If no action frame pending
Gopichand Nakkala681989c2013-03-06 22:27:48 -08008780 if (0 != wlan_hdd_check_remain_on_channel(pAdapter))
Jeff Johnson32d95a32012-09-10 13:15:23 -07008781 {
Kiet Lamac06e2c2013-10-23 16:25:07 +05308782 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Remain On Channel Pending", __func__);
Jeff Johnson32d95a32012-09-10 13:15:23 -07008783 return -EBUSY;
8784 }
Gopichand Nakkala681989c2013-03-06 22:27:48 -08008785#ifdef FEATURE_WLAN_TDLS
Gopichand Nakkala638ebc72013-03-21 18:04:02 -07008786 /* if tdls disagree scan right now, return immediately.
8787 tdls will schedule the scan when scan is allowed. (return SUCCESS)
8788 or will reject the scan if any TDLS is in progress. (return -EBUSY)
8789 */
8790 status = wlan_hdd_tdls_scan_callback (pAdapter,
8791 wiphy,
8792#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,6,0))
8793 dev,
Gopichand Nakkalac3c42b92013-03-20 19:42:34 -07008794#endif
Gopichand Nakkala638ebc72013-03-21 18:04:02 -07008795 request);
8796 if(status <= 0)
8797 {
Nirav Shah20ac06f2013-12-12 18:14:06 +05308798 if(!status)
8799 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: TDLS in progress."
8800 "scan rejected %d", __func__, status);
8801 else
8802 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: TDLS teardown is ongoing %d",
8803 __func__, status);
8804
Gopichand Nakkala638ebc72013-03-21 18:04:02 -07008805 return status;
Gopichand Nakkala681989c2013-03-06 22:27:48 -08008806 }
8807#endif
Jeff Johnson32d95a32012-09-10 13:15:23 -07008808
Jeff Johnson295189b2012-06-20 16:38:30 -07008809 if (mutex_lock_interruptible(&pHddCtx->tmInfo.tmOperationLock))
8810 {
8811 VOS_TRACE(VOS_MODULE_ID_HDD,VOS_TRACE_LEVEL_ERROR,
Jeff Johnson1250df42012-12-10 14:31:52 -08008812 "%s: Acquire lock fail", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07008813 return -EAGAIN;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308814 }
Jeff Johnson295189b2012-06-20 16:38:30 -07008815 if (TRUE == pHddCtx->tmInfo.tmAction.enterImps)
8816 {
Nirav Shah20ac06f2013-12-12 18:14:06 +05308817 hddLog(VOS_TRACE_LEVEL_ERROR,
Jeff Johnson295189b2012-06-20 16:38:30 -07008818 "%s: MAX TM Level Scan not allowed", __func__);
8819 mutex_unlock(&pHddCtx->tmInfo.tmOperationLock);
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308820 return -EBUSY;
Jeff Johnson295189b2012-06-20 16:38:30 -07008821 }
8822 mutex_unlock(&pHddCtx->tmInfo.tmOperationLock);
8823
Madan Mohan Koyyalamudicfd53742013-01-11 15:29:03 -08008824 /* Check if scan is allowed at this point of time.
8825 */
Rashmi Ramannab1429032014-04-26 14:59:09 +05308826 if (hdd_isConnectionInProgress(pHddCtx))
Madan Mohan Koyyalamudicfd53742013-01-11 15:29:03 -08008827 {
8828 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Scan not allowed", __func__);
8829 return -EBUSY;
8830 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308831
Jeff Johnson295189b2012-06-20 16:38:30 -07008832 vos_mem_zero( &scanRequest, sizeof(scanRequest));
8833
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +05308834 hddLog(VOS_TRACE_LEVEL_INFO, "scan request for ssid = %d",
8835 (int)request->n_ssids);
8836
8837 /* Even though supplicant doesn't provide any SSIDs, n_ssids is set to 1.
8838 * Becasue of this, driver is assuming that this is not wildcard scan and so
8839 * is not aging out the scan results.
8840 */
8841 if (request->ssids && '\0' == request->ssids->ssid[0])
Jeff Johnson295189b2012-06-20 16:38:30 -07008842 {
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +05308843 request->n_ssids = 0;
Jeff Johnson295189b2012-06-20 16:38:30 -07008844 }
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +05308845
8846 if ((request->ssids) && (0 < request->n_ssids))
8847 {
8848 tCsrSSIDInfo *SsidInfo;
8849 int j;
8850 scanRequest.SSIDs.numOfSSIDs = request->n_ssids;
8851 /* Allocate num_ssid tCsrSSIDInfo structure */
8852 SsidInfo = scanRequest.SSIDs.SSIDList =
8853 ( tCsrSSIDInfo *)vos_mem_malloc(
8854 request->n_ssids*sizeof(tCsrSSIDInfo));
8855
8856 if(NULL == scanRequest.SSIDs.SSIDList)
8857 {
8858 hddLog(VOS_TRACE_LEVEL_ERROR,
8859 "%s: memory alloc failed SSIDInfo buffer", __func__);
8860 return -ENOMEM;
8861 }
8862
8863 /* copy all the ssid's and their length */
8864 for(j = 0; j < request->n_ssids; j++, SsidInfo++)
8865 {
8866 /* get the ssid length */
8867 SsidInfo->SSID.length = request->ssids[j].ssid_len;
8868 vos_mem_copy(SsidInfo->SSID.ssId, &request->ssids[j].ssid[0],
8869 SsidInfo->SSID.length);
8870 SsidInfo->SSID.ssId[SsidInfo->SSID.length] = '\0';
8871 hddLog(VOS_TRACE_LEVEL_INFO, "SSID number %d: %s",
8872 j, SsidInfo->SSID.ssId);
8873 }
8874 /* set the scan type to active */
8875 scanRequest.scanType = eSIR_ACTIVE_SCAN;
8876 }
8877 else if(WLAN_HDD_P2P_GO == pAdapter->device_mode)
Jeff Johnson295189b2012-06-20 16:38:30 -07008878 {
Siddharth Bhal0c162d02014-05-06 19:50:42 +05308879 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
8880 TRACE_CODE_HDD_CFG80211_SCAN,
8881 pAdapter->sessionId, 0));
Jeff Johnson295189b2012-06-20 16:38:30 -07008882 /* set the scan type to active */
8883 scanRequest.scanType = eSIR_ACTIVE_SCAN;
Jeff Johnson295189b2012-06-20 16:38:30 -07008884 }
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +05308885 else
8886 {
8887 /*Set the scan type to default type, in this case it is ACTIVE*/
8888 scanRequest.scanType = pScanInfo->scan_mode;
8889 }
8890 scanRequest.minChnTime = cfg_param->nActiveMinChnTime;
8891 scanRequest.maxChnTime = cfg_param->nActiveMaxChnTime;
Jeff Johnson295189b2012-06-20 16:38:30 -07008892
8893 /* set BSSType to default type */
8894 scanRequest.BSSType = eCSR_BSS_TYPE_ANY;
8895
8896 /*TODO: scan the requested channels only*/
8897
8898 /*Right now scanning all the channels */
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +05308899 if (MAX_CHANNEL < request->n_channels)
Jeff Johnson295189b2012-06-20 16:38:30 -07008900 {
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +05308901 hddLog(VOS_TRACE_LEVEL_WARN,
8902 "No of Scan Channels exceeded limit: %d", request->n_channels);
8903 request->n_channels = MAX_CHANNEL;
8904 }
8905
8906 hddLog(VOS_TRACE_LEVEL_INFO,
8907 "No of Scan Channels: %d", request->n_channels);
8908
8909
8910 if( request->n_channels )
8911 {
8912 char chList [(request->n_channels*5)+1];
8913 int len;
8914 channelList = vos_mem_malloc( request->n_channels );
8915 if( NULL == channelList )
c_hpothu53512302014-04-15 18:49:53 +05308916 {
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +05308917 hddLog(VOS_TRACE_LEVEL_ERROR,
8918 "%s: memory alloc failed channelList", __func__);
8919 status = -ENOMEM;
8920 goto free_mem;
c_hpothu53512302014-04-15 18:49:53 +05308921 }
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +05308922
8923 for( i = 0, len = 0; i < request->n_channels ; i++ )
8924 {
8925 channelList[i] = request->channels[i]->hw_value;
8926 len += snprintf(chList+len, 5, "%d ", channelList[i]);
8927 }
8928
Nirav Shah20ac06f2013-12-12 18:14:06 +05308929 hddLog(VOS_TRACE_LEVEL_INFO,
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +05308930 "Channel-List: %s ", chList);
8931 }
c_hpothu53512302014-04-15 18:49:53 +05308932
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +05308933 scanRequest.ChannelInfo.numOfChannels = request->n_channels;
8934 scanRequest.ChannelInfo.ChannelList = channelList;
8935
8936 /* set requestType to full scan */
8937 scanRequest.requestType = eCSR_SCAN_REQUEST_FULL_SCAN;
8938
8939 /* Flush the scan results(only p2p beacons) for STA scan and P2P
8940 * search (Flush on both full scan and social scan but not on single
8941 * channel scan).P2P search happens on 3 social channels (1, 6, 11)
8942 */
8943
8944 /* Supplicant does single channel scan after 8-way handshake
8945 * and in that case driver shoudnt flush scan results. If
8946 * driver flushes the scan results here and unfortunately if
8947 * the AP doesnt respond to our probe req then association
8948 * fails which is not desired
8949 */
8950
8951 if( request->n_channels != WLAN_HDD_P2P_SINGLE_CHANNEL_SCAN )
8952 {
8953 hddLog(VOS_TRACE_LEVEL_DEBUG, "Flushing P2P Results");
8954 sme_ScanFlushP2PResult( WLAN_HDD_GET_HAL_CTX(pAdapter),
8955 pAdapter->sessionId );
8956 }
8957
8958 if( request->ie_len )
8959 {
8960 /* save this for future association (join requires this) */
8961 /*TODO: Array needs to be converted to dynamic allocation,
8962 * as multiple ie.s can be sent in cfg80211_scan_request structure
8963 * CR 597966
8964 */
8965 memset( &pScanInfo->scanAddIE, 0, sizeof(pScanInfo->scanAddIE) );
8966 memcpy( pScanInfo->scanAddIE.addIEdata, request->ie, request->ie_len);
8967 pScanInfo->scanAddIE.length = request->ie_len;
8968
8969 if ((WLAN_HDD_INFRA_STATION == pAdapter->device_mode) ||
8970 (WLAN_HDD_P2P_CLIENT == pAdapter->device_mode) ||
8971 (WLAN_HDD_P2P_DEVICE == pAdapter->device_mode))
Jeff Johnson295189b2012-06-20 16:38:30 -07008972 {
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +05308973 if ( request->ie_len <= SIR_MAC_MAX_IE_LENGTH)
Jeff Johnson295189b2012-06-20 16:38:30 -07008974 {
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +05308975 pwextBuf->roamProfile.nAddIEScanLength = request->ie_len;
8976 memcpy( pwextBuf->roamProfile.addIEScan,
8977 request->ie, request->ie_len);
8978 }
8979 else
8980 {
8981 hddLog(VOS_TRACE_LEVEL_ERROR, "Scan Ie length is invalid:"
8982 "%zu", request->ie_len);
Jeff Johnson295189b2012-06-20 16:38:30 -07008983 }
8984
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +05308985 }
8986 scanRequest.uIEFieldLen = pScanInfo->scanAddIE.length;
8987 scanRequest.pIEField = pScanInfo->scanAddIE.addIEdata;
8988
8989 pP2pIe = wlan_hdd_get_p2p_ie_ptr((v_U8_t*)request->ie,
8990 request->ie_len);
8991 if (pP2pIe != NULL)
8992 {
8993#ifdef WLAN_FEATURE_P2P_DEBUG
8994 if (((globalP2PConnectionStatus == P2P_GO_NEG_COMPLETED) ||
8995 (globalP2PConnectionStatus == P2P_GO_NEG_PROCESS)) &&
8996 (WLAN_HDD_P2P_CLIENT == pAdapter->device_mode))
Nirav Shah20ac06f2013-12-12 18:14:06 +05308997 {
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +05308998 globalP2PConnectionStatus = P2P_CLIENT_CONNECTING_STATE_1;
8999 hddLog(VOS_TRACE_LEVEL_ERROR,"[P2P State] Changing state from "
9000 "Go nego completed to Connection is started");
9001 hddLog(VOS_TRACE_LEVEL_ERROR,"[P2P]P2P Scanning is started "
9002 "for 8way Handshake");
Nirav Shah20ac06f2013-12-12 18:14:06 +05309003 }
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +05309004 else if((globalP2PConnectionStatus == P2P_CLIENT_DISCONNECTED_STATE) &&
9005 (WLAN_HDD_P2P_CLIENT == pAdapter->device_mode))
Jeff Johnson295189b2012-06-20 16:38:30 -07009006 {
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +05309007 globalP2PConnectionStatus = P2P_CLIENT_CONNECTING_STATE_2;
9008 hddLog(VOS_TRACE_LEVEL_ERROR,"[P2P State] Changing state from "
9009 "Disconnected state to Connection is started");
9010 hddLog(VOS_TRACE_LEVEL_ERROR,"[P2P]P2P Scanning is started "
9011 "for 4way Handshake");
9012 }
9013#endif
9014
9015 /* no_cck will be set during p2p find to disable 11b rates */
9016 if(TRUE == request->no_cck)
9017 {
9018 hddLog(VOS_TRACE_LEVEL_INFO,
9019 "%s: This is a P2P Search", __func__);
9020 scanRequest.p2pSearch = 1;
9021
9022 if( request->n_channels == WLAN_HDD_P2P_SOCIAL_CHANNELS )
Agarwal Ashish4f616132013-12-30 23:32:50 +05309023 {
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +05309024 /* set requestType to P2P Discovery */
9025 scanRequest.requestType = eCSR_SCAN_P2P_DISCOVERY;
9026 }
9027
9028 /*
9029 Skip Dfs Channel in case of P2P Search
9030 if it is set in ini file
9031 */
9032 if(cfg_param->skipDfsChnlInP2pSearch)
9033 {
9034 scanRequest.skipDfsChnlInP2pSearch = 1;
Agarwal Ashish4f616132013-12-30 23:32:50 +05309035 }
9036 else
9037 {
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +05309038 scanRequest.skipDfsChnlInP2pSearch = 0;
Agarwal Ashish4f616132013-12-30 23:32:50 +05309039 }
Jeff Johnson295189b2012-06-20 16:38:30 -07009040
Agarwal Ashish4f616132013-12-30 23:32:50 +05309041 }
Jeff Johnson295189b2012-06-20 16:38:30 -07009042 }
9043 }
9044
9045 INIT_COMPLETION(pScanInfo->scan_req_completion_event);
9046
Madan Mohan Koyyalamudi9f5a10c2012-09-28 14:46:16 -07009047 /* acquire the wakelock to avoid the apps suspend during the scan. To
9048 * address the following issues.
9049 * 1) Disconnected scenario: we are not allowing the suspend as WLAN is not in
9050 * BMPS/IMPS this result in android trying to suspend aggressively and backing off
9051 * for long time, this result in apps running at full power for long time.
9052 * 2) Connected scenario: If we allow the suspend during the scan, RIVA will
9053 * be stuck in full power because of resume BMPS
9054 */
9055 hdd_prevent_suspend();
Jeff Johnsone7245742012-09-05 17:12:55 -07009056
Nirav Shah20ac06f2013-12-12 18:14:06 +05309057 hddLog(VOS_TRACE_LEVEL_INFO_HIGH,
9058 "requestType %d, scanType %d, minChnTime %d, maxChnTime %d,"
Sushant Kaushik8bc7df22014-04-09 17:55:29 +05309059 "p2pSearch %d, skipDfsChnlInP2pSearch %d",
9060 scanRequest.requestType, scanRequest.scanType,
9061 scanRequest.minChnTime, scanRequest.maxChnTime,
Nirav Shah20ac06f2013-12-12 18:14:06 +05309062 scanRequest.p2pSearch, scanRequest.skipDfsChnlInP2pSearch);
9063
Jeff Johnsone7245742012-09-05 17:12:55 -07009064 status = sme_ScanRequest( WLAN_HDD_GET_HAL_CTX(pAdapter),
Jeff Johnson295189b2012-06-20 16:38:30 -07009065 pAdapter->sessionId, &scanRequest, &scanId,
9066 &hdd_cfg80211_scan_done_callback, dev );
Jeff Johnsone7245742012-09-05 17:12:55 -07009067
Jeff Johnson295189b2012-06-20 16:38:30 -07009068 if (eHAL_STATUS_SUCCESS != status)
9069 {
9070 hddLog(VOS_TRACE_LEVEL_ERROR,
9071 "%s: sme_ScanRequest returned error %d", __func__, status);
9072 complete(&pScanInfo->scan_req_completion_event);
Madan Mohan Koyyalamudi3b230fe2012-10-18 14:46:32 -07009073 if(eHAL_STATUS_RESOURCES == status)
9074 {
Nirav Shah20ac06f2013-12-12 18:14:06 +05309075 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: HO is in progress."
9076 "So defer the scan by informing busy",__func__);
Madan Mohan Koyyalamudi3b230fe2012-10-18 14:46:32 -07009077 status = -EBUSY;
9078 } else {
9079 status = -EIO;
9080 }
Madan Mohan Koyyalamudi9f5a10c2012-09-28 14:46:16 -07009081 hdd_allow_suspend();
Jeff Johnson295189b2012-06-20 16:38:30 -07009082 goto free_mem;
9083 }
9084
9085 pScanInfo->mScanPending = TRUE;
9086 pAdapter->request = request;
9087 pScanInfo->scanId = scanId;
9088
9089 complete(&pScanInfo->scan_req_completion_event);
9090
9091free_mem:
9092 if( scanRequest.SSIDs.SSIDList )
9093 {
9094 vos_mem_free(scanRequest.SSIDs.SSIDList);
9095 }
9096
9097 if( channelList )
9098 vos_mem_free( channelList );
9099
9100 EXIT();
9101
9102 return status;
9103}
9104
Mahesh A Saptasagarfafb7fe2014-05-16 13:19:37 +05309105int wlan_hdd_cfg80211_scan( struct wiphy *wiphy,
9106#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,6,0))
9107 struct net_device *dev,
9108#endif
9109 struct cfg80211_scan_request *request)
9110{
9111 int ret;
9112
9113 vos_ssr_protect(__func__);
9114 ret = __wlan_hdd_cfg80211_scan(wiphy,
9115#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,6,0))
9116 dev,
9117#endif
9118 request);
9119 vos_ssr_unprotect(__func__);
9120
9121 return ret;
9122}
Shailender Karmuchi15cd0672013-05-15 19:50:04 -07009123
9124void hdd_select_cbmode( hdd_adapter_t *pAdapter,v_U8_t operationChannel)
9125{
9126 v_U8_t iniDot11Mode =
9127 (WLAN_HDD_GET_CTX(pAdapter))->cfg_ini->dot11Mode;
9128 eHddDot11Mode hddDot11Mode = iniDot11Mode;
9129
Arun Kumar Khandavalli94a2bb02013-12-28 19:17:25 +05309130 hddLog(LOG1, FL("Channel Bonding Mode Selected is %u"),
9131 iniDot11Mode);
Shailender Karmuchi15cd0672013-05-15 19:50:04 -07009132 switch ( iniDot11Mode )
9133 {
9134 case eHDD_DOT11_MODE_AUTO:
9135 case eHDD_DOT11_MODE_11ac:
9136 case eHDD_DOT11_MODE_11ac_ONLY:
9137#ifdef WLAN_FEATURE_11AC
9138 hddDot11Mode = eHDD_DOT11_MODE_11ac;
9139#else
9140 hddDot11Mode = eHDD_DOT11_MODE_11n;
9141#endif
9142 break;
9143 case eHDD_DOT11_MODE_11n:
9144 case eHDD_DOT11_MODE_11n_ONLY:
9145 hddDot11Mode = eHDD_DOT11_MODE_11n;
9146 break;
9147 default:
9148 hddDot11Mode = iniDot11Mode;
9149 break;
9150 }
9151 /* This call decides required channel bonding mode */
9152 sme_SelectCBMode((WLAN_HDD_GET_CTX(pAdapter)->hHal),
9153 hdd_cfg_xlate_to_csr_phy_mode(hddDot11Mode),
9154 operationChannel);
9155}
9156
Jeff Johnson295189b2012-06-20 16:38:30 -07009157/*
9158 * FUNCTION: wlan_hdd_cfg80211_connect_start
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309159 * This function is used to start the association process
Jeff Johnson295189b2012-06-20 16:38:30 -07009160 */
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309161int wlan_hdd_cfg80211_connect_start( hdd_adapter_t *pAdapter,
Jeff Johnson32d95a32012-09-10 13:15:23 -07009162 const u8 *ssid, size_t ssid_len, const u8 *bssid, u8 operatingChannel)
Jeff Johnson295189b2012-06-20 16:38:30 -07009163{
9164 int status = 0;
9165 hdd_wext_state_t *pWextState;
Yue Mae36e3552014-03-05 17:06:20 -08009166 hdd_context_t *pHddCtx;
Jeff Johnson295189b2012-06-20 16:38:30 -07009167 v_U32_t roamId;
9168 tCsrRoamProfile *pRoamProfile;
Jeff Johnson295189b2012-06-20 16:38:30 -07009169 eCsrAuthType RSNAuthType;
9170
9171 ENTER();
9172
9173 pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
Yue Mae36e3552014-03-05 17:06:20 -08009174 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
9175
9176 status = wlan_hdd_validate_context(pHddCtx);
9177 if (status)
9178 {
9179 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
9180 "%s: HDD context is not valid!", __func__);
9181 return status;
9182 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309183
Jeff Johnson295189b2012-06-20 16:38:30 -07009184 if (SIR_MAC_MAX_SSID_LENGTH < ssid_len)
9185 {
9186 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: wrong SSID len", __func__);
9187 return -EINVAL;
9188 }
9189
9190 pRoamProfile = &pWextState->roamProfile;
9191
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309192 if (pRoamProfile)
Jeff Johnson295189b2012-06-20 16:38:30 -07009193 {
Jeff Johnsone7245742012-09-05 17:12:55 -07009194 hdd_station_ctx_t *pHddStaCtx;
9195 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
Jeff Johnson295189b2012-06-20 16:38:30 -07009196
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309197 if (HDD_WMM_USER_MODE_NO_QOS ==
Jeff Johnson295189b2012-06-20 16:38:30 -07009198 (WLAN_HDD_GET_CTX(pAdapter))->cfg_ini->WmmMode)
9199 {
9200 /*QoS not enabled in cfg file*/
9201 pRoamProfile->uapsd_mask = 0;
9202 }
9203 else
9204 {
9205 /*QoS enabled, update uapsd mask from cfg file*/
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309206 pRoamProfile->uapsd_mask =
Jeff Johnson295189b2012-06-20 16:38:30 -07009207 (WLAN_HDD_GET_CTX(pAdapter))->cfg_ini->UapsdMask;
9208 }
9209
9210 pRoamProfile->SSIDs.numOfSSIDs = 1;
9211 pRoamProfile->SSIDs.SSIDList->SSID.length = ssid_len;
9212 vos_mem_zero(pRoamProfile->SSIDs.SSIDList->SSID.ssId,
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309213 sizeof(pRoamProfile->SSIDs.SSIDList->SSID.ssId));
Jeff Johnson295189b2012-06-20 16:38:30 -07009214 vos_mem_copy((void *)(pRoamProfile->SSIDs.SSIDList->SSID.ssId),
9215 ssid, ssid_len);
9216
9217 if (bssid)
9218 {
9219 pRoamProfile->BSSIDs.numOfBSSIDs = 1;
9220 vos_mem_copy((void *)(pRoamProfile->BSSIDs.bssid), bssid,
9221 WNI_CFG_BSSID_LEN);
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309222 /* Save BSSID in seperate variable as well, as RoamProfile
9223 BSSID is getting zeroed out in the association process. And in
Jeff Johnson295189b2012-06-20 16:38:30 -07009224 case of join failure we should send valid BSSID to supplicant
9225 */
9226 vos_mem_copy((void *)(pWextState->req_bssId), bssid,
9227 WNI_CFG_BSSID_LEN);
9228 }
Dhanashri Atre51981c62013-06-13 11:47:57 -07009229 else
9230 {
9231 vos_mem_zero((void *)(pRoamProfile->BSSIDs.bssid),WNI_CFG_BSSID_LEN);
9232 }
Jeff Johnson295189b2012-06-20 16:38:30 -07009233
Arun Kumar Khandavalli94a2bb02013-12-28 19:17:25 +05309234 hddLog(LOG1, FL("Connect to SSID: %s opertating Channel: %u"),
9235 pRoamProfile->SSIDs.SSIDList->SSID.ssId, operatingChannel);
Jeff Johnson295189b2012-06-20 16:38:30 -07009236 if ((IW_AUTH_WPA_VERSION_WPA == pWextState->wpaVersion) ||
9237 (IW_AUTH_WPA_VERSION_WPA2 == pWextState->wpaVersion))
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309238 {
Jeff Johnson295189b2012-06-20 16:38:30 -07009239 /*set gen ie*/
9240 hdd_SetGENIEToCsr(pAdapter, &RSNAuthType);
9241 /*set auth*/
9242 hdd_set_csr_auth_type(pAdapter, RSNAuthType);
9243 }
Jeff Johnson295189b2012-06-20 16:38:30 -07009244#ifdef FEATURE_WLAN_WAPI
9245 if (pAdapter->wapi_info.nWapiMode)
9246 {
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07009247 hddLog(LOG1, "%s: Setting WAPI AUTH Type and Encryption Mode values", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07009248 switch (pAdapter->wapi_info.wapiAuthMode)
9249 {
9250 case WAPI_AUTH_MODE_PSK:
9251 {
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07009252 hddLog(LOG1, "%s: WAPI AUTH TYPE: PSK: %d", __func__,
Jeff Johnson295189b2012-06-20 16:38:30 -07009253 pAdapter->wapi_info.wapiAuthMode);
9254 pRoamProfile->AuthType.authType[0] = eCSR_AUTH_TYPE_WAPI_WAI_PSK;
9255 break;
9256 }
9257 case WAPI_AUTH_MODE_CERT:
9258 {
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07009259 hddLog(LOG1, "%s: WAPI AUTH TYPE: CERT: %d", __func__,
Jeff Johnson295189b2012-06-20 16:38:30 -07009260 pAdapter->wapi_info.wapiAuthMode);
9261 pRoamProfile->AuthType.authType[0] = eCSR_AUTH_TYPE_WAPI_WAI_CERTIFICATE;
9262 break;
9263 }
9264 } // End of switch
9265 if ( pAdapter->wapi_info.wapiAuthMode == WAPI_AUTH_MODE_PSK ||
9266 pAdapter->wapi_info.wapiAuthMode == WAPI_AUTH_MODE_CERT)
9267 {
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07009268 hddLog(LOG1, "%s: WAPI PAIRWISE/GROUP ENCRYPTION: WPI", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07009269 pRoamProfile->AuthType.numEntries = 1;
9270 pRoamProfile->EncryptionType.numEntries = 1;
9271 pRoamProfile->EncryptionType.encryptionType[0] = eCSR_ENCRYPT_TYPE_WPI;
9272 pRoamProfile->mcEncryptionType.numEntries = 1;
9273 pRoamProfile->mcEncryptionType.encryptionType[0] = eCSR_ENCRYPT_TYPE_WPI;
9274 }
9275 }
9276#endif /* FEATURE_WLAN_WAPI */
Gopichand Nakkala870cbae2013-03-15 21:16:09 +05309277#ifdef WLAN_FEATURE_GTK_OFFLOAD
Gopichand Nakkalad36ee622013-05-07 14:13:27 +05309278 /* Initializing gtkOffloadReqParams */
Gopichand Nakkala870cbae2013-03-15 21:16:09 +05309279 if ((WLAN_HDD_INFRA_STATION == pAdapter->device_mode) ||
9280 (WLAN_HDD_P2P_CLIENT == pAdapter->device_mode))
9281 {
Gopichand Nakkalad36ee622013-05-07 14:13:27 +05309282 memset(&pHddStaCtx->gtkOffloadReqParams, 0,
9283 sizeof (tSirGtkOffloadParams));
9284 pHddStaCtx->gtkOffloadReqParams.ulFlags = GTK_OFFLOAD_DISABLE;
Gopichand Nakkala870cbae2013-03-15 21:16:09 +05309285 }
9286#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07009287 pRoamProfile->csrPersona = pAdapter->device_mode;
9288
Jeff Johnson32d95a32012-09-10 13:15:23 -07009289 if( operatingChannel )
9290 {
9291 pRoamProfile->ChannelInfo.ChannelList = &operatingChannel;
9292 pRoamProfile->ChannelInfo.numOfChannels = 1;
9293 }
Chet Lanctot186b5732013-03-18 10:26:30 -07009294 else
9295 {
9296 pRoamProfile->ChannelInfo.ChannelList = NULL;
9297 pRoamProfile->ChannelInfo.numOfChannels = 0;
9298 }
Shailender Karmuchi15cd0672013-05-15 19:50:04 -07009299 if ( (WLAN_HDD_IBSS == pAdapter->device_mode) && operatingChannel)
9300 {
9301 hdd_select_cbmode(pAdapter,operatingChannel);
9302 }
Arun Kumar Khandavalli94a2bb02013-12-28 19:17:25 +05309303
Madan Mohan Koyyalamudi42dcd162012-12-03 16:34:04 -08009304 /* change conn_state to connecting before sme_RoamConnect(), because sme_RoamConnect()
9305 * has a direct path to call hdd_smeRoamCallback(), which will change the conn_state
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309306 * If direct path, conn_state will be accordingly changed to NotConnected or Associated
Madan Mohan Koyyalamudi42dcd162012-12-03 16:34:04 -08009307 * by either hdd_AssociationCompletionHandler() or hdd_DisConnectHandler() in sme_RoamCallback()
Madan Mohan Koyyalamudidf86c422012-12-04 17:03:44 -08009308 * if sme_RomConnect is to be queued, Connecting state will remain until it is completed.
9309 */
Gopichand Nakkalaa3c8fb62013-06-21 15:36:42 +05309310 if (WLAN_HDD_INFRA_STATION == pAdapter->device_mode ||
9311 WLAN_HDD_P2P_CLIENT == pAdapter->device_mode)
Abhishek Singhf4669da2014-05-26 15:07:49 +05309312 {
9313 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
9314 "%s: Set HDD connState to eConnectionState_Connecting",
9315 __func__);
Madan Mohan Koyyalamudidf86c422012-12-04 17:03:44 -08009316 hdd_connSetConnectionState(WLAN_HDD_GET_STATION_CTX_PTR(pAdapter),
9317 eConnectionState_Connecting);
Abhishek Singhf4669da2014-05-26 15:07:49 +05309318 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309319 status = sme_RoamConnect( WLAN_HDD_GET_HAL_CTX(pAdapter),
Jeff Johnson295189b2012-06-20 16:38:30 -07009320 pAdapter->sessionId, pRoamProfile, &roamId);
9321
Gopichand Nakkalaa3c8fb62013-06-21 15:36:42 +05309322 if ((eHAL_STATUS_SUCCESS != status) &&
9323 (WLAN_HDD_INFRA_STATION == pAdapter->device_mode ||
9324 WLAN_HDD_P2P_CLIENT == pAdapter->device_mode))
Madan Mohan Koyyalamudid5acbf52012-11-28 01:45:08 +05309325
9326 {
Madan Mohan Koyyalamudi42dcd162012-12-03 16:34:04 -08009327 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: sme_RoamConnect (session %d) failed with "
9328 "status %d. -> NotConnected", __func__, pAdapter->sessionId, status);
9329 /* change back to NotAssociated */
Madan Mohan Koyyalamudid5acbf52012-11-28 01:45:08 +05309330 hdd_connSetConnectionState(WLAN_HDD_GET_STATION_CTX_PTR(pAdapter),
Madan Mohan Koyyalamudi42dcd162012-12-03 16:34:04 -08009331 eConnectionState_NotConnected);
Madan Mohan Koyyalamudid5acbf52012-11-28 01:45:08 +05309332 }
Madan Mohan Koyyalamudidf86c422012-12-04 17:03:44 -08009333
9334 pRoamProfile->ChannelInfo.ChannelList = NULL;
9335 pRoamProfile->ChannelInfo.numOfChannels = 0;
9336
Jeff Johnson295189b2012-06-20 16:38:30 -07009337 }
9338 else
9339 {
9340 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: No valid Roam profile", __func__);
9341 return -EINVAL;
9342 }
Madan Mohan Koyyalamudifd4e1da2012-11-09 17:50:19 -08009343 EXIT();
Jeff Johnson295189b2012-06-20 16:38:30 -07009344 return status;
9345}
9346
9347/*
9348 * FUNCTION: wlan_hdd_set_cfg80211_auth_type
9349 * This function is used to set the authentication type (OPEN/SHARED).
9350 *
9351 */
9352static int wlan_hdd_cfg80211_set_auth_type(hdd_adapter_t *pAdapter,
9353 enum nl80211_auth_type auth_type)
9354{
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309355 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
Jeff Johnson295189b2012-06-20 16:38:30 -07009356 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
9357
9358 ENTER();
9359
9360 /*set authentication type*/
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309361 switch (auth_type)
Jeff Johnson295189b2012-06-20 16:38:30 -07009362 {
Jeff Johnson295189b2012-06-20 16:38:30 -07009363 case NL80211_AUTHTYPE_AUTOMATIC:
Gopichand Nakkala29149562013-05-10 21:43:41 +05309364 hddLog(VOS_TRACE_LEVEL_INFO,
9365 "%s: set authentication type to AUTOSWITCH", __func__);
9366 pHddStaCtx->conn_info.authType = eCSR_AUTH_TYPE_AUTOSWITCH;
9367 break;
9368
9369 case NL80211_AUTHTYPE_OPEN_SYSTEM:
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -07009370#ifdef WLAN_FEATURE_VOWIFI_11R
9371 case NL80211_AUTHTYPE_FT:
9372#endif /* WLAN_FEATURE_VOWIFI_11R */
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309373 hddLog(VOS_TRACE_LEVEL_INFO,
Jeff Johnson295189b2012-06-20 16:38:30 -07009374 "%s: set authentication type to OPEN", __func__);
9375 pHddStaCtx->conn_info.authType = eCSR_AUTH_TYPE_OPEN_SYSTEM;
9376 break;
9377
9378 case NL80211_AUTHTYPE_SHARED_KEY:
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309379 hddLog(VOS_TRACE_LEVEL_INFO,
Jeff Johnson295189b2012-06-20 16:38:30 -07009380 "%s: set authentication type to SHARED", __func__);
9381 pHddStaCtx->conn_info.authType = eCSR_AUTH_TYPE_SHARED_KEY;
9382 break;
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08009383#ifdef FEATURE_WLAN_ESE
Jeff Johnson295189b2012-06-20 16:38:30 -07009384 case NL80211_AUTHTYPE_NETWORK_EAP:
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309385 hddLog(VOS_TRACE_LEVEL_INFO,
Jeff Johnson295189b2012-06-20 16:38:30 -07009386 "%s: set authentication type to CCKM WPA", __func__);
9387 pHddStaCtx->conn_info.authType = eCSR_AUTH_TYPE_CCKM_WPA;//eCSR_AUTH_TYPE_CCKM_RSN needs to be handled as well if required.
9388 break;
9389#endif
9390
9391
9392 default:
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309393 hddLog(VOS_TRACE_LEVEL_ERROR,
9394 "%s: Unsupported authentication type %d", __func__,
Jeff Johnson295189b2012-06-20 16:38:30 -07009395 auth_type);
9396 pHddStaCtx->conn_info.authType = eCSR_AUTH_TYPE_UNKNOWN;
9397 return -EINVAL;
9398 }
9399
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309400 pWextState->roamProfile.AuthType.authType[0] =
Jeff Johnson295189b2012-06-20 16:38:30 -07009401 pHddStaCtx->conn_info.authType;
9402 return 0;
9403}
9404
9405/*
9406 * FUNCTION: wlan_hdd_set_akm_suite
9407 * This function is used to set the key mgmt type(PSK/8021x).
9408 *
9409 */
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309410static int wlan_hdd_set_akm_suite( hdd_adapter_t *pAdapter,
Jeff Johnson295189b2012-06-20 16:38:30 -07009411 u32 key_mgmt
9412 )
9413{
9414 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
9415 ENTER();
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309416
Jeff Johnson295189b2012-06-20 16:38:30 -07009417 /*set key mgmt type*/
9418 switch(key_mgmt)
9419 {
9420 case WLAN_AKM_SUITE_PSK:
Gopichand Nakkala356fb102013-03-06 12:34:04 +05309421#ifdef WLAN_FEATURE_VOWIFI_11R
9422 case WLAN_AKM_SUITE_FT_PSK:
9423#endif
9424 hddLog(VOS_TRACE_LEVEL_INFO, "%s: setting key mgmt type to PSK",
Jeff Johnson295189b2012-06-20 16:38:30 -07009425 __func__);
9426 pWextState->authKeyMgmt |= IW_AUTH_KEY_MGMT_PSK;
9427 break;
9428
9429 case WLAN_AKM_SUITE_8021X:
Gopichand Nakkala356fb102013-03-06 12:34:04 +05309430#ifdef WLAN_FEATURE_VOWIFI_11R
9431 case WLAN_AKM_SUITE_FT_8021X:
9432#endif
9433 hddLog(VOS_TRACE_LEVEL_INFO, "%s: setting key mgmt type to 8021x",
Jeff Johnson295189b2012-06-20 16:38:30 -07009434 __func__);
9435 pWextState->authKeyMgmt |= IW_AUTH_KEY_MGMT_802_1X;
9436 break;
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08009437#ifdef FEATURE_WLAN_ESE
Jeff Johnson295189b2012-06-20 16:38:30 -07009438#define WLAN_AKM_SUITE_CCKM 0x00409600 /* Should be in ieee802_11_defs.h */
9439#define IW_AUTH_KEY_MGMT_CCKM 8 /* Should be in linux/wireless.h */
9440 case WLAN_AKM_SUITE_CCKM:
9441 hddLog(VOS_TRACE_LEVEL_INFO, "%s: setting key mgmt type to CCKM",
9442 __func__);
9443 pWextState->authKeyMgmt |= IW_AUTH_KEY_MGMT_CCKM;
9444 break;
9445#endif
Leela Venkata Kiran Kumar Reddy Chiralae208a832014-04-27 22:34:25 -07009446#ifndef WLAN_AKM_SUITE_OSEN
9447#define WLAN_AKM_SUITE_OSEN 0x506f9a01 /* Should be in ieee802_11_defs.h */
9448 case WLAN_AKM_SUITE_OSEN:
9449 hddLog(VOS_TRACE_LEVEL_INFO, "%s: setting key mgmt type to OSEN",
9450 __func__);
9451 pWextState->authKeyMgmt |= IW_AUTH_KEY_MGMT_802_1X;
9452 break;
9453#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07009454
9455 default:
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309456 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Unsupported key mgmt type %d",
Jeff Johnson295189b2012-06-20 16:38:30 -07009457 __func__, key_mgmt);
9458 return -EINVAL;
9459
9460 }
9461 return 0;
9462}
9463
9464/*
9465 * FUNCTION: wlan_hdd_cfg80211_set_cipher
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309466 * This function is used to set the encryption type
Jeff Johnson295189b2012-06-20 16:38:30 -07009467 * (NONE/WEP40/WEP104/TKIP/CCMP).
9468 */
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309469static int wlan_hdd_cfg80211_set_cipher( hdd_adapter_t *pAdapter,
9470 u32 cipher,
Jeff Johnson295189b2012-06-20 16:38:30 -07009471 bool ucast
9472 )
9473{
9474 eCsrEncryptionType encryptionType = eCSR_ENCRYPT_TYPE_NONE;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309475 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
Jeff Johnson295189b2012-06-20 16:38:30 -07009476 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
9477
9478 ENTER();
9479
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309480 if (!cipher)
Jeff Johnson295189b2012-06-20 16:38:30 -07009481 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309482 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: received cipher %d - considering none",
Jeff Johnson295189b2012-06-20 16:38:30 -07009483 __func__, cipher);
9484 encryptionType = eCSR_ENCRYPT_TYPE_NONE;
9485 }
9486 else
9487 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309488
Jeff Johnson295189b2012-06-20 16:38:30 -07009489 /*set encryption method*/
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309490 switch (cipher)
Jeff Johnson295189b2012-06-20 16:38:30 -07009491 {
9492 case IW_AUTH_CIPHER_NONE:
9493 encryptionType = eCSR_ENCRYPT_TYPE_NONE;
9494 break;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309495
Jeff Johnson295189b2012-06-20 16:38:30 -07009496 case WLAN_CIPHER_SUITE_WEP40:
Gopichand Nakkala29149562013-05-10 21:43:41 +05309497 encryptionType = eCSR_ENCRYPT_TYPE_WEP40;
Jeff Johnson295189b2012-06-20 16:38:30 -07009498 break;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309499
Jeff Johnson295189b2012-06-20 16:38:30 -07009500 case WLAN_CIPHER_SUITE_WEP104:
Gopichand Nakkala29149562013-05-10 21:43:41 +05309501 encryptionType = eCSR_ENCRYPT_TYPE_WEP104;
Jeff Johnson295189b2012-06-20 16:38:30 -07009502 break;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309503
Jeff Johnson295189b2012-06-20 16:38:30 -07009504 case WLAN_CIPHER_SUITE_TKIP:
9505 encryptionType = eCSR_ENCRYPT_TYPE_TKIP;
9506 break;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309507
Jeff Johnson295189b2012-06-20 16:38:30 -07009508 case WLAN_CIPHER_SUITE_CCMP:
9509 encryptionType = eCSR_ENCRYPT_TYPE_AES;
9510 break;
9511#ifdef FEATURE_WLAN_WAPI
9512 case WLAN_CIPHER_SUITE_SMS4:
9513 encryptionType = eCSR_ENCRYPT_TYPE_WPI;
9514 break;
9515#endif
9516
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08009517#ifdef FEATURE_WLAN_ESE
Jeff Johnson295189b2012-06-20 16:38:30 -07009518 case WLAN_CIPHER_SUITE_KRK:
9519 encryptionType = eCSR_ENCRYPT_TYPE_KRK;
9520 break;
9521#endif
9522 default:
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309523 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Unsupported cipher type %d",
Jeff Johnson295189b2012-06-20 16:38:30 -07009524 __func__, cipher);
9525 return -EOPNOTSUPP;
9526 }
9527 }
9528
9529 if (ucast)
9530 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309531 hddLog(VOS_TRACE_LEVEL_INFO, "%s: setting unicast cipher type to %d",
Jeff Johnson295189b2012-06-20 16:38:30 -07009532 __func__, encryptionType);
9533 pHddStaCtx->conn_info.ucEncryptionType = encryptionType;
9534 pWextState->roamProfile.EncryptionType.numEntries = 1;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309535 pWextState->roamProfile.EncryptionType.encryptionType[0] =
Jeff Johnson295189b2012-06-20 16:38:30 -07009536 encryptionType;
9537 }
9538 else
9539 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309540 hddLog(VOS_TRACE_LEVEL_INFO, "%s: setting mcast cipher type to %d",
Jeff Johnson295189b2012-06-20 16:38:30 -07009541 __func__, encryptionType);
9542 pHddStaCtx->conn_info.mcEncryptionType = encryptionType;
9543 pWextState->roamProfile.mcEncryptionType.numEntries = 1;
9544 pWextState->roamProfile.mcEncryptionType.encryptionType[0] = encryptionType;
9545 }
9546
9547 return 0;
9548}
9549
9550
9551/*
9552 * FUNCTION: wlan_hdd_cfg80211_set_ie
9553 * This function is used to parse WPA/RSN IE's.
9554 */
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309555int wlan_hdd_cfg80211_set_ie( hdd_adapter_t *pAdapter,
9556 u8 *ie,
Jeff Johnson295189b2012-06-20 16:38:30 -07009557 size_t ie_len
9558 )
9559{
9560 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
9561 u8 *genie = ie;
9562 v_U16_t remLen = ie_len;
9563#ifdef FEATURE_WLAN_WAPI
9564 v_U32_t akmsuite[MAX_NUM_AKM_SUITES];
9565 u16 *tmp;
9566 v_U16_t akmsuiteCount;
9567 int *akmlist;
9568#endif
9569 ENTER();
9570
9571 /* clear previous assocAddIE */
9572 pWextState->assocAddIE.length = 0;
9573 pWextState->roamProfile.bWPSAssociation = VOS_FALSE;
Leela Venkata Kiran Kumar Reddy Chiralaf257bef2014-04-11 18:48:12 -07009574 pWextState->roamProfile.bOSENAssociation = VOS_FALSE;
Jeff Johnson295189b2012-06-20 16:38:30 -07009575
9576 while (remLen >= 2)
9577 {
9578 v_U16_t eLen = 0;
9579 v_U8_t elementId;
9580 elementId = *genie++;
9581 eLen = *genie++;
9582 remLen -= 2;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309583
Arif Hussain6d2a3322013-11-17 19:50:10 -08009584 hddLog(VOS_TRACE_LEVEL_INFO, "%s: IE[0x%X], LEN[%d]",
Jeff Johnson295189b2012-06-20 16:38:30 -07009585 __func__, elementId, eLen);
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309586
9587 switch ( elementId )
Jeff Johnson295189b2012-06-20 16:38:30 -07009588 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309589 case DOT11F_EID_WPA:
Madan Mohan Koyyalamudief3b66e2012-10-11 14:29:42 -07009590 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 -07009591 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309592 hddLog(VOS_TRACE_LEVEL_ERROR,
Jeff Johnson295189b2012-06-20 16:38:30 -07009593 "%s: Invalid WPA IE", __func__);
9594 return -EINVAL;
9595 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309596 else if (0 == memcmp(&genie[0], "\x00\x50\xf2\x04", 4))
Jeff Johnson295189b2012-06-20 16:38:30 -07009597 {
9598 v_U16_t curAddIELen = pWextState->assocAddIE.length;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309599 hddLog (VOS_TRACE_LEVEL_INFO, "%s Set WPS IE(len %d)",
Jeff Johnson295189b2012-06-20 16:38:30 -07009600 __func__, eLen + 2);
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309601
Jeff Johnson295189b2012-06-20 16:38:30 -07009602 if( SIR_MAC_MAX_IE_LENGTH < (pWextState->assocAddIE.length + eLen) )
9603 {
Jeff Johnson902c9832012-12-10 14:28:09 -08009604 hddLog(VOS_TRACE_LEVEL_FATAL, "Cannot accommodate assocAddIE. "
9605 "Need bigger buffer space");
Jeff Johnson295189b2012-06-20 16:38:30 -07009606 VOS_ASSERT(0);
9607 return -ENOMEM;
9608 }
9609 // WSC IE is saved to Additional IE ; it should be accumulated to handle WPS IE + P2P IE
9610 memcpy( pWextState->assocAddIE.addIEdata + curAddIELen, genie - 2, eLen + 2);
9611 pWextState->assocAddIE.length += eLen + 2;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309612
Jeff Johnson295189b2012-06-20 16:38:30 -07009613 pWextState->roamProfile.bWPSAssociation = VOS_TRUE;
9614 pWextState->roamProfile.pAddIEAssoc = pWextState->assocAddIE.addIEdata;
9615 pWextState->roamProfile.nAddIEAssocLength = pWextState->assocAddIE.length;
9616 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309617 else if (0 == memcmp(&genie[0], "\x00\x50\xf2", 3))
9618 {
Jeff Johnson295189b2012-06-20 16:38:30 -07009619 hddLog (VOS_TRACE_LEVEL_INFO, "%s Set WPA IE (len %d)",__func__, eLen + 2);
9620 memset( pWextState->WPARSNIE, 0, MAX_WPA_RSN_IE_LEN );
9621 memcpy( pWextState->WPARSNIE, genie - 2, (eLen + 2) /*ie_len*/);
9622 pWextState->roamProfile.pWPAReqIE = pWextState->WPARSNIE;
9623 pWextState->roamProfile.nWPAReqIELength = eLen + 2;//ie_len;
9624 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309625 else if ( (0 == memcmp(&genie[0], P2P_OUI_TYPE,
Kiet Lam8da98992013-11-21 15:59:07 +05309626 P2P_OUI_TYPE_SIZE)))
Jeff Johnson295189b2012-06-20 16:38:30 -07009627 {
9628 v_U16_t curAddIELen = pWextState->assocAddIE.length;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309629 hddLog (VOS_TRACE_LEVEL_INFO, "%s Set P2P IE(len %d)",
Jeff Johnson295189b2012-06-20 16:38:30 -07009630 __func__, eLen + 2);
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309631
Jeff Johnson295189b2012-06-20 16:38:30 -07009632 if( SIR_MAC_MAX_IE_LENGTH < (pWextState->assocAddIE.length + eLen) )
9633 {
Jeff Johnson902c9832012-12-10 14:28:09 -08009634 hddLog(VOS_TRACE_LEVEL_FATAL, "Cannot accommodate assocAddIE "
9635 "Need bigger buffer space");
Jeff Johnson295189b2012-06-20 16:38:30 -07009636 VOS_ASSERT(0);
9637 return -ENOMEM;
9638 }
9639 // P2P IE is saved to Additional IE ; it should be accumulated to handle WPS IE + P2P IE
9640 memcpy( pWextState->assocAddIE.addIEdata + curAddIELen, genie - 2, eLen + 2);
9641 pWextState->assocAddIE.length += eLen + 2;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309642
Jeff Johnson295189b2012-06-20 16:38:30 -07009643 pWextState->roamProfile.pAddIEAssoc = pWextState->assocAddIE.addIEdata;
9644 pWextState->roamProfile.nAddIEAssocLength = pWextState->assocAddIE.length;
9645 }
Jeff Johnson295189b2012-06-20 16:38:30 -07009646#ifdef WLAN_FEATURE_WFD
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309647 else if ( (0 == memcmp(&genie[0], WFD_OUI_TYPE,
9648 WFD_OUI_TYPE_SIZE))
Jeff Johnson295189b2012-06-20 16:38:30 -07009649 /*Consider WFD IE, only for P2P Client */
9650 && (WLAN_HDD_P2P_CLIENT == pAdapter->device_mode) )
9651 {
9652 v_U16_t curAddIELen = pWextState->assocAddIE.length;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309653 hddLog (VOS_TRACE_LEVEL_INFO, "%s Set WFD IE(len %d)",
Jeff Johnson295189b2012-06-20 16:38:30 -07009654 __func__, eLen + 2);
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309655
Jeff Johnson295189b2012-06-20 16:38:30 -07009656 if( SIR_MAC_MAX_IE_LENGTH < (pWextState->assocAddIE.length + eLen) )
9657 {
Jeff Johnson902c9832012-12-10 14:28:09 -08009658 hddLog(VOS_TRACE_LEVEL_FATAL, "Cannot accommodate assocAddIE "
9659 "Need bigger buffer space");
Jeff Johnson295189b2012-06-20 16:38:30 -07009660 VOS_ASSERT(0);
9661 return -ENOMEM;
9662 }
9663 // WFD IE is saved to Additional IE ; it should be accumulated to handle
9664 // WPS IE + P2P IE + WFD IE
9665 memcpy( pWextState->assocAddIE.addIEdata + curAddIELen, genie - 2, eLen + 2);
9666 pWextState->assocAddIE.length += eLen + 2;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309667
Jeff Johnson295189b2012-06-20 16:38:30 -07009668 pWextState->roamProfile.pAddIEAssoc = pWextState->assocAddIE.addIEdata;
9669 pWextState->roamProfile.nAddIEAssocLength = pWextState->assocAddIE.length;
9670 }
9671#endif
Madan Mohan Koyyalamudief3b66e2012-10-11 14:29:42 -07009672 /* Appending HS 2.0 Indication Element in Assiciation Request */
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309673 else if ( (0 == memcmp(&genie[0], HS20_OUI_TYPE,
Madan Mohan Koyyalamudi1bed5982012-10-22 14:38:06 -07009674 HS20_OUI_TYPE_SIZE)) )
9675 {
9676 v_U16_t curAddIELen = pWextState->assocAddIE.length;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309677 hddLog (VOS_TRACE_LEVEL_INFO, "%s Set HS20 IE(len %d)",
Madan Mohan Koyyalamudi1bed5982012-10-22 14:38:06 -07009678 __func__, eLen + 2);
Madan Mohan Koyyalamudief3b66e2012-10-11 14:29:42 -07009679
Madan Mohan Koyyalamudi1bed5982012-10-22 14:38:06 -07009680 if( SIR_MAC_MAX_IE_LENGTH < (pWextState->assocAddIE.length + eLen) )
9681 {
Jeff Johnson902c9832012-12-10 14:28:09 -08009682 hddLog(VOS_TRACE_LEVEL_FATAL, "Cannot accommodate assocAddIE "
9683 "Need bigger buffer space");
Madan Mohan Koyyalamudi1bed5982012-10-22 14:38:06 -07009684 VOS_ASSERT(0);
9685 return -ENOMEM;
9686 }
9687 memcpy( pWextState->assocAddIE.addIEdata + curAddIELen, genie - 2, eLen + 2);
9688 pWextState->assocAddIE.length += eLen + 2;
Madan Mohan Koyyalamudief3b66e2012-10-11 14:29:42 -07009689
Madan Mohan Koyyalamudi1bed5982012-10-22 14:38:06 -07009690 pWextState->roamProfile.pAddIEAssoc = pWextState->assocAddIE.addIEdata;
9691 pWextState->roamProfile.nAddIEAssocLength = pWextState->assocAddIE.length;
9692 }
Leela Venkata Kiran Kumar Reddy Chiralaf257bef2014-04-11 18:48:12 -07009693 /* Appending OSEN Information Element in Assiciation Request */
9694 else if ( (0 == memcmp(&genie[0], OSEN_OUI_TYPE,
9695 OSEN_OUI_TYPE_SIZE)) )
9696 {
9697 v_U16_t curAddIELen = pWextState->assocAddIE.length;
9698 hddLog (VOS_TRACE_LEVEL_INFO, "%s Set OSEN IE(len %d)",
9699 __func__, eLen + 2);
Madan Mohan Koyyalamudief3b66e2012-10-11 14:29:42 -07009700
Leela Venkata Kiran Kumar Reddy Chiralaf257bef2014-04-11 18:48:12 -07009701 if( SIR_MAC_MAX_IE_LENGTH < (pWextState->assocAddIE.length + eLen) )
9702 {
9703 hddLog(VOS_TRACE_LEVEL_FATAL, "Cannot accommodate assocAddIE "
9704 "Need bigger buffer space");
9705 VOS_ASSERT(0);
9706 return -ENOMEM;
9707 }
9708 memcpy( pWextState->assocAddIE.addIEdata + curAddIELen, genie - 2, eLen + 2);
9709 pWextState->assocAddIE.length += eLen + 2;
9710
9711 pWextState->roamProfile.bOSENAssociation = VOS_TRUE;
9712 pWextState->roamProfile.pAddIEAssoc = pWextState->assocAddIE.addIEdata;
9713 pWextState->roamProfile.nAddIEAssocLength = pWextState->assocAddIE.length;
9714 }
9715
9716 break;
Praveen Kumar Sirisilla7d68b7b2013-09-22 14:01:42 -07009717 if (WLAN_HDD_IBSS == pAdapter->device_mode) {
9718
9719 /* populating as ADDIE in beacon frames */
9720 if (ccmCfgSetStr(WLAN_HDD_GET_HAL_CTX(pAdapter),
9721 WNI_CFG_PROBE_RSP_BCN_ADDNIE_DATA, genie - 2, eLen + 2,
9722 NULL, eANI_BOOLEAN_FALSE)== eHAL_STATUS_SUCCESS)
9723 {
9724 if (ccmCfgSetInt(WLAN_HDD_GET_HAL_CTX(pAdapter),
9725 WNI_CFG_PROBE_RSP_BCN_ADDNIE_FLAG, 1,NULL,
9726 eANI_BOOLEAN_FALSE) == eHAL_STATUS_FAILURE)
9727 {
9728 hddLog(LOGE,
9729 "Coldn't pass "
9730 "WNI_CFG_PROBE_RSP_BCN_ADDNIE_FLAG to CCM");
9731 }
9732 }/* ccmCfgSetStr(,WNI_CFG_PROBE_RSP_BCN_ADDNIE_DATA, , )*/
9733 else
9734 hddLog(LOGE,
9735 "Could not pass on "
9736 "WNI_CFG_PROBE_RSP_BCN_ADDNIE_DATA to CCM");
9737
9738 /* IBSS mode doesn't contain params->proberesp_ies still
9739 beaconIE's need to be populated in probe response frames */
9740 if ( (NULL != (genie - 2)) && (0 != eLen + 2) )
9741 {
9742 u16 rem_probe_resp_ie_len = eLen + 2;
9743 u8 probe_rsp_ie_len[3] = {0};
9744 u8 counter = 0;
9745
9746 /* Check Probe Resp Length if it is greater then 255 then
9747 Store Probe Rsp IEs into WNI_CFG_PROBE_RSP_ADDNIE_DATA1
9748 & WNI_CFG_PROBE_RSP_ADDNIE_DATA2 CFG Variable As We are
9749 not able Store More then 255 bytes into One Variable */
9750
9751 while ((rem_probe_resp_ie_len > 0) && (counter < 3))
9752 {
9753 if (rem_probe_resp_ie_len > MAX_CFG_STRING_LEN)
9754 {
9755 probe_rsp_ie_len[counter++] = MAX_CFG_STRING_LEN;
9756 rem_probe_resp_ie_len -= MAX_CFG_STRING_LEN;
9757 }
9758 else
9759 {
9760 probe_rsp_ie_len[counter++] = rem_probe_resp_ie_len;
9761 rem_probe_resp_ie_len = 0;
9762 }
9763 }
9764
9765 rem_probe_resp_ie_len = 0;
9766
9767 if (probe_rsp_ie_len[0] > 0)
9768 {
9769 if (ccmCfgSetStr(WLAN_HDD_GET_HAL_CTX(pAdapter),
9770 WNI_CFG_PROBE_RSP_ADDNIE_DATA1,
9771 (tANI_U8*)(genie - 2),
9772 probe_rsp_ie_len[0], NULL,
9773 eANI_BOOLEAN_FALSE)
9774 == eHAL_STATUS_FAILURE)
9775 {
9776 hddLog(LOGE,
9777 "Could not pass"
9778 "on WNI_CFG_PROBE_RSP_ADDNIE_DATA1 to CCM");
9779 }
9780 rem_probe_resp_ie_len += probe_rsp_ie_len[0];
9781 }
9782
9783 if (probe_rsp_ie_len[1] > 0)
9784 {
9785 if (ccmCfgSetStr(WLAN_HDD_GET_HAL_CTX(pAdapter),
9786 WNI_CFG_PROBE_RSP_ADDNIE_DATA2,
9787 (tANI_U8*)(genie - (2 + rem_probe_resp_ie_len)),
9788 probe_rsp_ie_len[1], NULL,
9789 eANI_BOOLEAN_FALSE)
9790 == eHAL_STATUS_FAILURE)
9791 {
9792 hddLog(LOGE,
9793 "Could not pass"
9794 "on WNI_CFG_PROBE_RSP_ADDNIE_DATA2 to CCM");
9795 }
9796 rem_probe_resp_ie_len += probe_rsp_ie_len[1];
9797 }
9798
9799 if (probe_rsp_ie_len[2] > 0)
9800 {
9801 if (ccmCfgSetStr(WLAN_HDD_GET_HAL_CTX(pAdapter),
9802 WNI_CFG_PROBE_RSP_ADDNIE_DATA3,
9803 (tANI_U8*)(genie - (2 + rem_probe_resp_ie_len)),
9804 probe_rsp_ie_len[2], NULL,
9805 eANI_BOOLEAN_FALSE)
9806 == eHAL_STATUS_FAILURE)
9807 {
9808 hddLog(LOGE,
9809 "Could not pass"
9810 "on WNI_CFG_PROBE_RSP_ADDNIE_DATA3 to CCM");
9811 }
9812 rem_probe_resp_ie_len += probe_rsp_ie_len[2];
9813 }
9814
9815 if (ccmCfgSetInt(WLAN_HDD_GET_HAL_CTX(pAdapter),
9816 WNI_CFG_PROBE_RSP_ADDNIE_FLAG, 1,NULL,
9817 eANI_BOOLEAN_FALSE) == eHAL_STATUS_FAILURE)
9818 {
9819 hddLog(LOGE,
9820 "Could not pass"
9821 "on WNI_CFG_PROBE_RSP_ADDNIE_FLAG to CCM");
9822 }
9823 }
9824 else
9825 {
9826 // Reset WNI_CFG_PROBE_RSP Flags
9827 wlan_hdd_reset_prob_rspies(pAdapter);
9828
9829 hddLog(VOS_TRACE_LEVEL_INFO,
9830 "%s: No Probe Response IE received in set beacon",
9831 __func__);
9832 }
9833 } /* end of if (WLAN_HDD_IBSS == pAdapter->device_mode) */
Jeff Johnson295189b2012-06-20 16:38:30 -07009834 break;
9835 case DOT11F_EID_RSN:
9836 hddLog (VOS_TRACE_LEVEL_INFO, "%s Set RSN IE(len %d)",__func__, eLen + 2);
9837 memset( pWextState->WPARSNIE, 0, MAX_WPA_RSN_IE_LEN );
9838 memcpy( pWextState->WPARSNIE, genie - 2, (eLen + 2)/*ie_len*/);
9839 pWextState->roamProfile.pRSNReqIE = pWextState->WPARSNIE;
9840 pWextState->roamProfile.nRSNReqIELength = eLen + 2; //ie_len;
9841 break;
Madan Mohan Koyyalamudief3b66e2012-10-11 14:29:42 -07009842 /* Appending Extended Capabilities with Interworking bit set in Assoc Req */
9843 case DOT11F_EID_EXTCAP:
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309844 {
Madan Mohan Koyyalamudief3b66e2012-10-11 14:29:42 -07009845 v_U16_t curAddIELen = pWextState->assocAddIE.length;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309846 hddLog (VOS_TRACE_LEVEL_INFO, "%s Set Extended CAPS IE(len %d)",
Madan Mohan Koyyalamudief3b66e2012-10-11 14:29:42 -07009847 __func__, eLen + 2);
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309848
Madan Mohan Koyyalamudief3b66e2012-10-11 14:29:42 -07009849 if( SIR_MAC_MAX_IE_LENGTH < (pWextState->assocAddIE.length + eLen) )
9850 {
Jeff Johnson902c9832012-12-10 14:28:09 -08009851 hddLog(VOS_TRACE_LEVEL_FATAL, "Cannot accommodate assocAddIE "
9852 "Need bigger buffer space");
Madan Mohan Koyyalamudief3b66e2012-10-11 14:29:42 -07009853 VOS_ASSERT(0);
9854 return -ENOMEM;
9855 }
9856 memcpy( pWextState->assocAddIE.addIEdata + curAddIELen, genie - 2, eLen + 2);
9857 pWextState->assocAddIE.length += eLen + 2;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309858
Madan Mohan Koyyalamudief3b66e2012-10-11 14:29:42 -07009859 pWextState->roamProfile.pAddIEAssoc = pWextState->assocAddIE.addIEdata;
9860 pWextState->roamProfile.nAddIEAssocLength = pWextState->assocAddIE.length;
9861 break;
9862 }
Jeff Johnson295189b2012-06-20 16:38:30 -07009863#ifdef FEATURE_WLAN_WAPI
9864 case WLAN_EID_WAPI:
9865 pAdapter->wapi_info.nWapiMode = 1; //Setting WAPI Mode to ON=1
Jeff Johnson0299d0a2013-10-30 12:37:43 -07009866 hddLog(VOS_TRACE_LEVEL_INFO, "WAPI MODE IS %u",
Jeff Johnson295189b2012-06-20 16:38:30 -07009867 pAdapter->wapi_info.nWapiMode);
9868 tmp = (u16 *)ie;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309869 tmp = tmp + 2; // Skip element Id and Len, Version
Jeff Johnson295189b2012-06-20 16:38:30 -07009870 akmsuiteCount = WPA_GET_LE16(tmp);
9871 tmp = tmp + 1;
9872 akmlist = (int *)(tmp);
9873 if(akmsuiteCount <= MAX_NUM_AKM_SUITES)
9874 {
9875 memcpy(akmsuite, akmlist, (4*akmsuiteCount));
9876 }
9877 else
9878 {
Arif Hussain6d2a3322013-11-17 19:50:10 -08009879 hddLog(VOS_TRACE_LEVEL_FATAL, "Invalid akmSuite count");
Jeff Johnson295189b2012-06-20 16:38:30 -07009880 VOS_ASSERT(0);
9881 return -EINVAL;
9882 }
9883
9884 if (WAPI_PSK_AKM_SUITE == akmsuite[0])
9885 {
9886 hddLog(VOS_TRACE_LEVEL_INFO, "%s: WAPI AUTH MODE SET TO PSK",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07009887 __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07009888 pAdapter->wapi_info.wapiAuthMode = WAPI_AUTH_MODE_PSK;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309889 }
Jeff Johnson295189b2012-06-20 16:38:30 -07009890 if (WAPI_CERT_AKM_SUITE == akmsuite[0])
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309891 {
Jeff Johnson295189b2012-06-20 16:38:30 -07009892 hddLog(VOS_TRACE_LEVEL_INFO, "%s: WAPI AUTH MODE SET TO CERTIFICATE",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07009893 __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07009894 pAdapter->wapi_info.wapiAuthMode = WAPI_AUTH_MODE_CERT;
9895 }
9896 break;
9897#endif
9898 default:
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309899 hddLog (VOS_TRACE_LEVEL_ERROR,
Jeff Johnson295189b2012-06-20 16:38:30 -07009900 "%s Set UNKNOWN IE %X", __func__, elementId);
Madan Mohan Koyyalamudief3b66e2012-10-11 14:29:42 -07009901 /* when Unknown IE is received we should break and continue
9902 * to the next IE in the buffer instead we were returning
9903 * so changing this to break */
9904 break;
Jeff Johnson295189b2012-06-20 16:38:30 -07009905 }
9906 genie += eLen;
9907 remLen -= eLen;
9908 }
9909 EXIT();
9910 return 0;
9911}
9912
9913/*
Gopichand Nakkala18f0c262013-05-07 23:25:08 +05309914 * FUNCTION: hdd_isWPAIEPresent
9915 * Parse the received IE to find the WPA IE
9916 *
9917 */
9918static bool hdd_isWPAIEPresent(u8 *ie, u8 ie_len)
9919{
9920 v_U8_t eLen = 0;
9921 v_U16_t remLen = ie_len;
9922 v_U8_t elementId = 0;
9923
9924 while (remLen >= 2)
9925 {
9926 elementId = *ie++;
9927 eLen = *ie++;
9928 remLen -= 2;
9929 if (eLen > remLen)
9930 {
9931 hddLog(VOS_TRACE_LEVEL_ERROR,
9932 "%s: IE length is wrong %d", __func__, eLen);
9933 return FALSE;
9934 }
9935 if ((elementId == DOT11F_EID_WPA) && (remLen > 5))
9936 {
9937 /* OUI - 0x00 0X50 0XF2
9938 WPA Information Element - 0x01
9939 WPA version - 0x01*/
9940 if (0 == memcmp(&ie[0], "\x00\x50\xf2\x01\x01", 5))
9941 return TRUE;
9942 }
9943 ie += eLen;
9944 remLen -= eLen;
9945 }
9946 return FALSE;
9947}
9948
9949/*
Jeff Johnson295189b2012-06-20 16:38:30 -07009950 * FUNCTION: wlan_hdd_cfg80211_set_privacy
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309951 * This function is used to initialize the security
Jeff Johnson295189b2012-06-20 16:38:30 -07009952 * parameters during connect operation.
9953 */
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309954int wlan_hdd_cfg80211_set_privacy( hdd_adapter_t *pAdapter,
Jeff Johnson295189b2012-06-20 16:38:30 -07009955 struct cfg80211_connect_params *req
9956 )
9957{
9958 int status = 0;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309959 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
Jeff Johnson295189b2012-06-20 16:38:30 -07009960 ENTER();
9961
9962 /*set wpa version*/
9963 pWextState->wpaVersion = IW_AUTH_WPA_VERSION_DISABLED;
9964
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309965 if (req->crypto.wpa_versions)
Jeff Johnson295189b2012-06-20 16:38:30 -07009966 {
Gopichand Nakkala781ded42013-06-28 12:10:45 +05309967 if (NL80211_WPA_VERSION_1 == req->crypto.wpa_versions)
Jeff Johnson295189b2012-06-20 16:38:30 -07009968 {
9969 pWextState->wpaVersion = IW_AUTH_WPA_VERSION_WPA;
9970 }
9971 else if (NL80211_WPA_VERSION_2 == req->crypto.wpa_versions)
9972 {
9973 pWextState->wpaVersion = IW_AUTH_WPA_VERSION_WPA2;
9974 }
9975 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309976
9977 hddLog(VOS_TRACE_LEVEL_INFO, "%s: set wpa version to %d", __func__,
Jeff Johnson295189b2012-06-20 16:38:30 -07009978 pWextState->wpaVersion);
9979
9980 /*set authentication type*/
9981 status = wlan_hdd_cfg80211_set_auth_type(pAdapter, req->auth_type);
9982
9983 if (0 > status)
9984 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309985 hddLog(VOS_TRACE_LEVEL_ERROR,
Jeff Johnson295189b2012-06-20 16:38:30 -07009986 "%s: failed to set authentication type ", __func__);
9987 return status;
9988 }
9989
9990 /*set key mgmt type*/
9991 if (req->crypto.n_akm_suites)
9992 {
9993 status = wlan_hdd_set_akm_suite(pAdapter, req->crypto.akm_suites[0]);
9994 if (0 > status)
9995 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309996 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: failed to set akm suite",
Jeff Johnson295189b2012-06-20 16:38:30 -07009997 __func__);
9998 return status;
9999 }
10000 }
10001
10002 /*set pairwise cipher type*/
10003 if (req->crypto.n_ciphers_pairwise)
10004 {
10005 status = wlan_hdd_cfg80211_set_cipher(pAdapter,
10006 req->crypto.ciphers_pairwise[0], true);
10007 if (0 > status)
10008 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010009 hddLog(VOS_TRACE_LEVEL_ERROR,
Jeff Johnson295189b2012-06-20 16:38:30 -070010010 "%s: failed to set unicast cipher type", __func__);
10011 return status;
10012 }
10013 }
10014 else
10015 {
10016 /*Reset previous cipher suite to none*/
10017 status = wlan_hdd_cfg80211_set_cipher(pAdapter, 0, true);
10018 if (0 > status)
10019 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010020 hddLog(VOS_TRACE_LEVEL_ERROR,
Jeff Johnson295189b2012-06-20 16:38:30 -070010021 "%s: failed to set unicast cipher type", __func__);
10022 return status;
10023 }
10024 }
10025
10026 /*set group cipher type*/
10027 status = wlan_hdd_cfg80211_set_cipher(pAdapter, req->crypto.cipher_group,
10028 false);
10029
10030 if (0 > status)
10031 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010032 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: failed to set mcast cipher type",
Jeff Johnson295189b2012-06-20 16:38:30 -070010033 __func__);
10034 return status;
10035 }
10036
Chet Lanctot186b5732013-03-18 10:26:30 -070010037#ifdef WLAN_FEATURE_11W
10038 pWextState->roamProfile.MFPEnabled = (req->mfp == NL80211_MFP_REQUIRED);
10039#endif
10040
Jeff Johnson295189b2012-06-20 16:38:30 -070010041 /*parse WPA/RSN IE, and set the correspoing fileds in Roam profile*/
10042 if (req->ie_len)
10043 {
10044 status = wlan_hdd_cfg80211_set_ie(pAdapter, req->ie, req->ie_len);
10045 if ( 0 > status)
10046 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010047 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: failed to parse the WPA/RSN IE",
Jeff Johnson295189b2012-06-20 16:38:30 -070010048 __func__);
10049 return status;
10050 }
10051 }
10052
10053 /*incase of WEP set default key information*/
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010054 if (req->key && req->key_len)
Jeff Johnson295189b2012-06-20 16:38:30 -070010055 {
10056 if ( (WLAN_CIPHER_SUITE_WEP40 == req->crypto.ciphers_pairwise[0])
10057 || (WLAN_CIPHER_SUITE_WEP104 == req->crypto.ciphers_pairwise[0])
10058 )
10059 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010060 if ( IW_AUTH_KEY_MGMT_802_1X
Jeff Johnson295189b2012-06-20 16:38:30 -070010061 == (pWextState->authKeyMgmt & IW_AUTH_KEY_MGMT_802_1X ))
10062 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010063 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Dynamic WEP not supported",
Jeff Johnson295189b2012-06-20 16:38:30 -070010064 __func__);
10065 return -EOPNOTSUPP;
10066 }
10067 else
10068 {
10069 u8 key_len = req->key_len;
10070 u8 key_idx = req->key_idx;
10071
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010072 if ((eCSR_SECURITY_WEP_KEYSIZE_MAX_BYTES >= key_len)
Jeff Johnson295189b2012-06-20 16:38:30 -070010073 && (CSR_MAX_NUM_KEY > key_idx)
10074 )
10075 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010076 hddLog(VOS_TRACE_LEVEL_INFO,
10077 "%s: setting default wep key, key_idx = %hu key_len %hu",
Jeff Johnson295189b2012-06-20 16:38:30 -070010078 __func__, key_idx, key_len);
10079 vos_mem_copy(
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010080 &pWextState->roamProfile.Keys.KeyMaterial[key_idx][0],
Jeff Johnson295189b2012-06-20 16:38:30 -070010081 req->key, key_len);
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010082 pWextState->roamProfile.Keys.KeyLength[key_idx] =
Jeff Johnson295189b2012-06-20 16:38:30 -070010083 (u8)key_len;
10084 pWextState->roamProfile.Keys.defaultIndex = (u8)key_idx;
10085 }
10086 }
10087 }
10088 }
10089
10090 return status;
10091}
10092
10093/*
Vinay Krishna Eranna21042322014-01-08 19:21:39 +053010094 * FUNCTION: wlan_hdd_try_disconnect
10095 * This function is used to disconnect from previous
10096 * connection
10097 */
10098static int wlan_hdd_try_disconnect( hdd_adapter_t *pAdapter )
10099{
10100 long ret = 0;
10101 hdd_station_ctx_t *pHddStaCtx;
10102 eMib_dot11DesiredBssType connectedBssType;
10103
10104 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
10105
10106 hdd_connGetConnectedBssType(pHddStaCtx,&connectedBssType );
10107
10108 if((eMib_dot11DesiredBssType_independent == connectedBssType) ||
10109 (eConnectionState_Associated == pHddStaCtx->conn_info.connState) ||
10110 (eConnectionState_IbssConnected == pHddStaCtx->conn_info.connState))
10111 {
10112 /* Issue disconnect to CSR */
10113 INIT_COMPLETION(pAdapter->disconnect_comp_var);
10114 if( eHAL_STATUS_SUCCESS ==
10115 sme_RoamDisconnect( WLAN_HDD_GET_HAL_CTX(pAdapter),
10116 pAdapter->sessionId,
10117 eCSR_DISCONNECT_REASON_UNSPECIFIED ) )
10118 {
10119 ret = wait_for_completion_interruptible_timeout(
10120 &pAdapter->disconnect_comp_var,
10121 msecs_to_jiffies(WLAN_WAIT_TIME_DISCONNECT));
10122 if (0 >= ret)
10123 {
10124 hddLog(LOGE, FL("Failed to receive disconnect event"));
10125 return -EALREADY;
10126 }
10127 }
10128 }
10129 else if(eConnectionState_Disconnecting == pHddStaCtx->conn_info.connState)
10130 {
10131 ret = wait_for_completion_interruptible_timeout(
10132 &pAdapter->disconnect_comp_var,
10133 msecs_to_jiffies(WLAN_WAIT_TIME_DISCONNECT));
10134 if (0 >= ret)
10135 {
10136 hddLog(LOGE, FL("Failed to receive disconnect event"));
10137 return -EALREADY;
10138 }
10139 }
10140
10141 return 0;
10142}
10143
10144/*
Agarwal Ashish51325b52014-06-16 16:50:49 +053010145 * FUNCTION: __wlan_hdd_cfg80211_connect
10146 * This function is used to start the association process
Jeff Johnson295189b2012-06-20 16:38:30 -070010147 */
Mahesh A Saptasagarfafb7fe2014-05-16 13:19:37 +053010148static int __wlan_hdd_cfg80211_connect( struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -070010149 struct net_device *ndev,
10150 struct cfg80211_connect_params *req
10151 )
10152{
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053010153 int status;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010154 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( ndev );
Sushant Kaushikba6764e2014-06-30 19:52:09 +053010155 hdd_adapter_t *pHostapdAdapter = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -070010156 VOS_STATUS exitbmpsStatus = VOS_STATUS_E_INVAL;
Sushant Kaushikba6764e2014-06-30 19:52:09 +053010157 hdd_context_t *pHddCtx = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -070010158
10159 ENTER();
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053010160
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053010161 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
10162 TRACE_CODE_HDD_CFG80211_CONNECT,
10163 pAdapter->sessionId, pAdapter->device_mode));
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010164 hddLog(VOS_TRACE_LEVEL_INFO,
Sushant Kaushik8bc7df22014-04-09 17:55:29 +053010165 "%s: device_mode = %s (%d)", __func__,
10166 hdd_device_modetoString(pAdapter->device_mode),
10167 pAdapter->device_mode);
Jeff Johnson295189b2012-06-20 16:38:30 -070010168
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053010169 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Rajesh Chauhana0516c62014-01-30 16:11:18 -080010170 if (!pHddCtx)
10171 {
10172 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
10173 "%s: HDD context is null", __func__);
Agarwal Ashish51325b52014-06-16 16:50:49 +053010174 return -EINVAL;
Rajesh Chauhana0516c62014-01-30 16:11:18 -080010175 }
10176
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053010177 status = wlan_hdd_validate_context(pHddCtx);
10178
10179 if (0 != status)
Jeff Johnson295189b2012-06-20 16:38:30 -070010180 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053010181 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
10182 "%s: HDD context is not valid", __func__);
10183 return status;
Jeff Johnson295189b2012-06-20 16:38:30 -070010184 }
10185
Agarwal Ashish51325b52014-06-16 16:50:49 +053010186 if (vos_max_concurrent_connections_reached()) {
10187 hddLog(VOS_TRACE_LEVEL_INFO, FL("Reached max concurrent connections"));
10188 return -ECONNREFUSED;
10189 }
10190
Jeff Johnson295189b2012-06-20 16:38:30 -070010191#ifdef WLAN_BTAMP_FEATURE
10192 //Infra connect not supported when AMP traffic is on.
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010193 if( VOS_TRUE == WLANBAP_AmpSessionOn() )
Jeff Johnson295189b2012-06-20 16:38:30 -070010194 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010195 hddLog(VOS_TRACE_LEVEL_ERROR,
Jeff Johnson295189b2012-06-20 16:38:30 -070010196 "%s: No connection when AMP is on", __func__);
Madan Mohan Koyyalamudicae253a2012-11-06 19:10:35 -080010197 return -ECONNREFUSED;
Jeff Johnson295189b2012-06-20 16:38:30 -070010198 }
10199#endif
Vinay Krishna Eranna21042322014-01-08 19:21:39 +053010200
10201 //If Device Mode is Station Concurrent Sessions Exit BMps
10202 //P2P Mode will be taken care in Open/close adapter
10203 if((WLAN_HDD_INFRA_STATION == pAdapter->device_mode) &&
Agarwal Ashish51325b52014-06-16 16:50:49 +053010204 (vos_concurrent_open_sessions_running())) {
10205 exitbmpsStatus = hdd_disable_bmps_imps(pHddCtx,
10206 WLAN_HDD_INFRA_STATION);
Vinay Krishna Eranna21042322014-01-08 19:21:39 +053010207 }
10208
10209 /*Try disconnecting if already in connected state*/
10210 status = wlan_hdd_try_disconnect(pAdapter);
10211 if ( 0 > status)
10212 {
10213 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Failed to disconnect the existing"
10214 " connection"));
10215 return -EALREADY;
10216 }
10217
Jeff Johnson295189b2012-06-20 16:38:30 -070010218 /*initialise security parameters*/
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010219 status = wlan_hdd_cfg80211_set_privacy(pAdapter, req);
Jeff Johnson295189b2012-06-20 16:38:30 -070010220
10221 if ( 0 > status)
10222 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010223 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: failed to set security params",
Jeff Johnson295189b2012-06-20 16:38:30 -070010224 __func__);
10225 return status;
10226 }
Sushant Kaushikba6764e2014-06-30 19:52:09 +053010227 /* For SAP + STA concurrency , driver only supports SCC.
10228 * if SAP is ON, driver will stop it and after assoc completion,
10229 * or failure, SAP will be started on STA channel to force SCC.
10230 */
10231 pHostapdAdapter = hdd_get_adapter(pHddCtx, WLAN_HDD_SOFTAP);
10232 if (pHostapdAdapter != NULL)
10233 {
10234 hddLog(VOS_TRACE_LEVEL_INFO, "Close SAP until STA is connected");
10235 if (test_bit(SOFTAP_BSS_STARTED, &pHostapdAdapter->event_flags))
10236 {
10237 WLANSAP_StopBss((WLAN_HDD_GET_CTX(pHostapdAdapter))->pvosContext);
10238 clear_bit(SOFTAP_BSS_STARTED, &pHostapdAdapter->event_flags);
10239 }
10240 }
Mohit Khanna765234a2012-09-11 15:08:35 -070010241 if ( req->channel )
10242 {
10243 status = wlan_hdd_cfg80211_connect_start(pAdapter, req->ssid,
10244 req->ssid_len, req->bssid,
10245 req->channel->hw_value);
10246 }
10247 else
10248 {
10249 status = wlan_hdd_cfg80211_connect_start(pAdapter, req->ssid,
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053010250 req->ssid_len, req->bssid, 0);
Mohit Khanna765234a2012-09-11 15:08:35 -070010251 }
Jeff Johnson295189b2012-06-20 16:38:30 -070010252
10253 if (0 > status)
10254 {
10255 //ReEnable BMPS if disabled
10256 if((VOS_STATUS_SUCCESS == exitbmpsStatus) &&
10257 (NULL != pHddCtx))
10258 {
Gopichand Nakkalaa2fe5b02013-06-06 16:32:28 +053010259 if (pHddCtx->hdd_wlan_suspended)
10260 {
10261 hdd_set_pwrparams(pHddCtx);
10262 }
Jeff Johnson295189b2012-06-20 16:38:30 -070010263 //ReEnable Bmps and Imps back
10264 hdd_enable_bmps_imps(pHddCtx);
10265 }
Agarwal Ashish51325b52014-06-16 16:50:49 +053010266 hddLog(VOS_TRACE_LEVEL_ERROR, FL("connect failed"));
Jeff Johnson295189b2012-06-20 16:38:30 -070010267 return status;
10268 }
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053010269 pHddCtx->isAmpAllowed = VOS_FALSE;
Jeff Johnson295189b2012-06-20 16:38:30 -070010270 EXIT();
10271 return status;
10272}
10273
Mahesh A Saptasagarfafb7fe2014-05-16 13:19:37 +053010274static int wlan_hdd_cfg80211_connect( struct wiphy *wiphy,
10275 struct net_device *ndev,
10276 struct cfg80211_connect_params *req)
10277{
10278 int ret;
10279 vos_ssr_protect(__func__);
10280 ret = __wlan_hdd_cfg80211_connect(wiphy, ndev, req);
10281 vos_ssr_unprotect(__func__);
10282
10283 return ret;
10284}
Jeff Johnson295189b2012-06-20 16:38:30 -070010285
10286/*
Gopichand Nakkala78a6c812013-05-13 16:39:49 +053010287 * FUNCTION: wlan_hdd_disconnect
10288 * This function is used to issue a disconnect request to SME
10289 */
10290int wlan_hdd_disconnect( hdd_adapter_t *pAdapter, u16 reason )
10291{
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053010292 int status;
Gopichand Nakkala78a6c812013-05-13 16:39:49 +053010293 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053010294 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Abhishek Singhdc2bfd42014-06-19 17:59:05 +053010295 long ret;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053010296
10297 status = wlan_hdd_validate_context(pHddCtx);
10298
10299 if (0 != status)
10300 {
10301 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
10302 "%s: HDD context is not valid", __func__);
10303 return status;
10304 }
10305
10306 pHddCtx->isAmpAllowed = VOS_TRUE;
Agarwal Ashishc65b5ca2014-07-28 21:02:57 +053010307
10308 if (eConnectionState_Associated == pHddStaCtx->conn_info.connState)
10309 {
10310 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
10311 "%s: Set HDD connState to eConnectionState_Disconnecting",
10312 __func__);
10313 wlan_hdd_decr_active_session(pHddCtx, pAdapter->device_mode);
10314 }
10315
Abhishek Singhf4669da2014-05-26 15:07:49 +053010316 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
10317 "%s: Set HDD connState to eConnectionState_Disconnecting",
10318 __func__);
Vinay Krishna Erannab09d3e72014-03-26 21:23:55 +053010319 pHddStaCtx->conn_info.connState = eConnectionState_Disconnecting;
Gopichand Nakkala78a6c812013-05-13 16:39:49 +053010320 INIT_COMPLETION(pAdapter->disconnect_comp_var);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053010321
Gopichand Nakkala78a6c812013-05-13 16:39:49 +053010322 /*issue disconnect*/
Arun Kumar Khandavalli94a2bb02013-12-28 19:17:25 +053010323
Gopichand Nakkala78a6c812013-05-13 16:39:49 +053010324 status = sme_RoamDisconnect( WLAN_HDD_GET_HAL_CTX(pAdapter),
10325 pAdapter->sessionId, reason);
Abhishek Singhdc2bfd42014-06-19 17:59:05 +053010326 if(eHAL_STATUS_CMD_NOT_QUEUED == status)
10327 {
10328 hddLog(VOS_TRACE_LEVEL_INFO,
10329 FL("status = %d, already disconnected"),
10330 (int)status );
Gopichand Nakkala78a6c812013-05-13 16:39:49 +053010331
Abhishek Singhdc2bfd42014-06-19 17:59:05 +053010332 }
10333 else if ( 0 != status )
Gopichand Nakkala78a6c812013-05-13 16:39:49 +053010334 {
10335 hddLog(VOS_TRACE_LEVEL_ERROR,
Arif Hussain6d2a3322013-11-17 19:50:10 -080010336 "%s csrRoamDisconnect failure, returned %d",
Gopichand Nakkala78a6c812013-05-13 16:39:49 +053010337 __func__, (int)status );
10338 return -EINVAL;
10339 }
Abhishek Singhdc2bfd42014-06-19 17:59:05 +053010340 ret = wait_for_completion_interruptible_timeout(
Gopichand Nakkala78a6c812013-05-13 16:39:49 +053010341 &pAdapter->disconnect_comp_var,
10342 msecs_to_jiffies(WLAN_WAIT_TIME_DISCONNECT));
Abhishek Singhdc2bfd42014-06-19 17:59:05 +053010343 if (!ret && ( eHAL_STATUS_CMD_NOT_QUEUED != status ))
c_hpothu6ff1c3c2013-10-01 19:01:57 +053010344 {
10345 hddLog(VOS_TRACE_LEVEL_ERROR,
Mahesh A Saptasagar05a357e2014-02-26 16:28:06 +053010346 "%s: Failed to disconnect, timed out", __func__);
10347 return -ETIMEDOUT;
10348 }
Abhishek Singhdc2bfd42014-06-19 17:59:05 +053010349 else if (ret == -ERESTARTSYS)
Mahesh A Saptasagar05a357e2014-02-26 16:28:06 +053010350 {
10351 hddLog(VOS_TRACE_LEVEL_ERROR,
10352 "%s: Failed to disconnect, wait interrupted", __func__);
Abhishek Singhdc2bfd42014-06-19 17:59:05 +053010353 return ret;
c_hpothu6ff1c3c2013-10-01 19:01:57 +053010354 }
Abhishek Singhdc2bfd42014-06-19 17:59:05 +053010355 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
10356 FL("Set HDD connState to eConnectionState_NotConnected"));
10357 pHddStaCtx->conn_info.connState = eConnectionState_NotConnected;
10358
Gopichand Nakkala78a6c812013-05-13 16:39:49 +053010359 /*stop tx queues*/
10360 netif_tx_disable(pAdapter->dev);
10361 netif_carrier_off(pAdapter->dev);
Mahesh A Saptasagar05a357e2014-02-26 16:28:06 +053010362 return 0;
Gopichand Nakkala78a6c812013-05-13 16:39:49 +053010363}
10364
10365
10366/*
Mahesh A Saptasagarfafb7fe2014-05-16 13:19:37 +053010367 * FUNCTION: __wlan_hdd_cfg80211_disconnect
Jeff Johnson295189b2012-06-20 16:38:30 -070010368 * This function is used to issue a disconnect request to SME
10369 */
Mahesh A Saptasagarfafb7fe2014-05-16 13:19:37 +053010370static int __wlan_hdd_cfg80211_disconnect( struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -070010371 struct net_device *dev,
10372 u16 reason
10373 )
10374{
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010375 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( dev );
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053010376 tCsrRoamProfile *pRoamProfile =
10377 &(WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter))->roamProfile;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053010378 int status;
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053010379 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
10380 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Gopichand Nakkalaaa353782013-05-17 20:36:22 +053010381#ifdef FEATURE_WLAN_TDLS
Gopichand Nakkala2a0a1572013-02-10 21:39:16 -080010382 tANI_U8 staIdx;
10383#endif
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010384
Jeff Johnson295189b2012-06-20 16:38:30 -070010385 ENTER();
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053010386
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053010387 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
10388 TRACE_CODE_HDD_CFG80211_DISCONNECT,
10389 pAdapter->sessionId, reason));
Sushant Kaushik8bc7df22014-04-09 17:55:29 +053010390 hddLog(VOS_TRACE_LEVEL_INFO, "%s: device_mode = %s(%d)",
10391 __func__, hdd_device_modetoString(pAdapter->device_mode),
10392 pAdapter->device_mode);
Jeff Johnson295189b2012-06-20 16:38:30 -070010393
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010394 hddLog(VOS_TRACE_LEVEL_INFO, "%s: Disconnect called with reason code %d",
10395 __func__, reason);
Jeff Johnson295189b2012-06-20 16:38:30 -070010396
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053010397 status = wlan_hdd_validate_context(pHddCtx);
10398
10399 if (0 != status)
Jeff Johnson295189b2012-06-20 16:38:30 -070010400 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053010401 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
10402 "%s: HDD context is not valid", __func__);
10403 return status;
Jeff Johnson295189b2012-06-20 16:38:30 -070010404 }
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053010405
Jeff Johnson295189b2012-06-20 16:38:30 -070010406 if (NULL != pRoamProfile)
10407 {
10408 /*issue disconnect request to SME, if station is in connected state*/
Mahesh A Saptasagar280fd5a2013-12-05 15:38:31 +053010409 if ((pHddStaCtx->conn_info.connState == eConnectionState_Associated) ||
10410 (pHddStaCtx->conn_info.connState == eConnectionState_Connecting))
Jeff Johnson295189b2012-06-20 16:38:30 -070010411 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010412 eCsrRoamDisconnectReason reasonCode =
Jeff Johnson295189b2012-06-20 16:38:30 -070010413 eCSR_DISCONNECT_REASON_UNSPECIFIED;
Gopichand Nakkalaaa353782013-05-17 20:36:22 +053010414 hdd_scaninfo_t *pScanInfo;
Jeff Johnson295189b2012-06-20 16:38:30 -070010415 switch(reason)
10416 {
10417 case WLAN_REASON_MIC_FAILURE:
10418 reasonCode = eCSR_DISCONNECT_REASON_MIC_ERROR;
10419 break;
10420
10421 case WLAN_REASON_DISASSOC_DUE_TO_INACTIVITY:
10422 case WLAN_REASON_DISASSOC_AP_BUSY:
10423 case WLAN_REASON_CLASS3_FRAME_FROM_NONASSOC_STA:
10424 reasonCode = eCSR_DISCONNECT_REASON_DISASSOC;
10425 break;
10426
10427 case WLAN_REASON_PREV_AUTH_NOT_VALID:
10428 case WLAN_REASON_CLASS2_FRAME_FROM_NONAUTH_STA:
Abhishek Singhc3269a52014-05-21 17:22:24 +053010429 case WLAN_REASON_DEAUTH_LEAVING:
Jeff Johnson295189b2012-06-20 16:38:30 -070010430 reasonCode = eCSR_DISCONNECT_REASON_DEAUTH;
10431 break;
10432
Jeff Johnson295189b2012-06-20 16:38:30 -070010433 default:
10434 reasonCode = eCSR_DISCONNECT_REASON_UNSPECIFIED;
10435 break;
10436 }
Gopichand Nakkalaaa353782013-05-17 20:36:22 +053010437 pScanInfo = &pHddCtx->scan_info;
10438 if (pScanInfo->mScanPending)
10439 {
Srinivas, Dasari138af4f2014-02-07 11:13:45 +053010440 hddLog(VOS_TRACE_LEVEL_INFO, "Disconnect is in progress, "
Gopichand Nakkalaaa353782013-05-17 20:36:22 +053010441 "Aborting Scan");
Srinivas, Dasari138af4f2014-02-07 11:13:45 +053010442 hdd_abort_mac_scan(pHddCtx, pAdapter->sessionId,
10443 eCSR_SCAN_ABORT_DEFAULT);
Gopichand Nakkalaaa353782013-05-17 20:36:22 +053010444 }
Jeff Johnson295189b2012-06-20 16:38:30 -070010445
Gopichand Nakkala2a0a1572013-02-10 21:39:16 -080010446#ifdef FEATURE_WLAN_TDLS
10447 /* First clean up the tdls peers if any */
Gopichand Nakkala4327a152013-03-04 23:22:42 -080010448 for (staIdx = 0 ; staIdx < HDD_MAX_NUM_TDLS_STA; staIdx++)
Gopichand Nakkala2a0a1572013-02-10 21:39:16 -080010449 {
Gopichand Nakkala4327a152013-03-04 23:22:42 -080010450 if ((pHddCtx->tdlsConnInfo[staIdx].sessionId == pAdapter->sessionId) &&
10451 (pHddCtx->tdlsConnInfo[staIdx].staId))
Gopichand Nakkala2a0a1572013-02-10 21:39:16 -080010452 {
Hoonki Lee11f7dda2013-02-14 16:55:44 -080010453 uint8 *mac;
Gopichand Nakkala4327a152013-03-04 23:22:42 -080010454 mac = pHddCtx->tdlsConnInfo[staIdx].peerMac.bytes;
Hoonki Lee11f7dda2013-02-14 16:55:44 -080010455 VOS_TRACE(VOS_MODULE_ID_HDD, TDLS_LOG_LEVEL,
Gopichand Nakkalac87400e2013-03-13 18:51:00 -070010456 "%s: call sme_DeleteTdlsPeerSta staId %d sessionId %d " MAC_ADDRESS_STR,
Gopichand Nakkala4327a152013-03-04 23:22:42 -080010457 __func__, pHddCtx->tdlsConnInfo[staIdx].staId, pAdapter->sessionId,
Gopichand Nakkalac87400e2013-03-13 18:51:00 -070010458 MAC_ADDR_ARRAY(mac));
Gopichand Nakkala2a0a1572013-02-10 21:39:16 -080010459 sme_DeleteTdlsPeerSta(WLAN_HDD_GET_HAL_CTX(pAdapter),
Gopichand Nakkala4327a152013-03-04 23:22:42 -080010460 pAdapter->sessionId,
10461 mac);
Gopichand Nakkala2a0a1572013-02-10 21:39:16 -080010462 }
10463 }
10464#endif
Arun Kumar Khandavalli94a2bb02013-12-28 19:17:25 +053010465 hddLog(LOG1, FL("Disconnecting with reasoncode:%u"), reasonCode);
Gopichand Nakkala78a6c812013-05-13 16:39:49 +053010466 status = wlan_hdd_disconnect(pAdapter, reasonCode);
10467 if ( 0 != status )
Jeff Johnson295189b2012-06-20 16:38:30 -070010468 {
10469 hddLog(VOS_TRACE_LEVEL_ERROR,
Arif Hussain6d2a3322013-11-17 19:50:10 -080010470 "%s wlan_hdd_disconnect failure, returned %d",
Jeff Johnson295189b2012-06-20 16:38:30 -070010471 __func__, (int)status );
10472 return -EINVAL;
10473 }
Jeff Johnson295189b2012-06-20 16:38:30 -070010474 }
Mahesh A Saptasagar280fd5a2013-12-05 15:38:31 +053010475 else
10476 {
10477 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: unexpected cfg disconnect API"
10478 "called while in %d state", __func__,
10479 pHddStaCtx->conn_info.connState);
10480 }
Jeff Johnson295189b2012-06-20 16:38:30 -070010481 }
10482 else
10483 {
10484 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: No valid roam profile", __func__);
10485 }
10486
10487 return status;
10488}
10489
Mahesh A Saptasagarfafb7fe2014-05-16 13:19:37 +053010490static int wlan_hdd_cfg80211_disconnect( struct wiphy *wiphy,
10491 struct net_device *dev,
10492 u16 reason
10493 )
10494{
10495 int ret;
10496 vos_ssr_protect(__func__);
10497 ret = __wlan_hdd_cfg80211_disconnect(wiphy, dev, reason);
10498 vos_ssr_unprotect(__func__);
10499
10500 return ret;
10501}
Gopichand Nakkala78a6c812013-05-13 16:39:49 +053010502
Jeff Johnson295189b2012-06-20 16:38:30 -070010503/*
10504 * FUNCTION: wlan_hdd_cfg80211_set_privacy_ibss
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010505 * This function is used to initialize the security
Jeff Johnson295189b2012-06-20 16:38:30 -070010506 * settings in IBSS mode.
10507 */
10508static int wlan_hdd_cfg80211_set_privacy_ibss(
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010509 hdd_adapter_t *pAdapter,
Jeff Johnson295189b2012-06-20 16:38:30 -070010510 struct cfg80211_ibss_params *params
10511 )
10512{
10513 int status = 0;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010514 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
Jeff Johnson295189b2012-06-20 16:38:30 -070010515 eCsrEncryptionType encryptionType = eCSR_ENCRYPT_TYPE_NONE;
10516 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010517
Jeff Johnson295189b2012-06-20 16:38:30 -070010518 ENTER();
10519
10520 pWextState->wpaVersion = IW_AUTH_WPA_VERSION_DISABLED;
Ravi Joshib58ca0d2013-10-29 09:50:23 -070010521 vos_mem_zero(&pHddStaCtx->ibss_enc_key, sizeof(tCsrRoamSetKey));
Jeff Johnson295189b2012-06-20 16:38:30 -070010522
10523 if (params->ie_len && ( NULL != params->ie) )
10524 {
Shailender Karmuchi67edd312013-06-18 16:30:48 -070010525 if (wlan_hdd_cfg80211_get_ie_ptr (params->ie,
10526 params->ie_len, WLAN_EID_RSN ))
Jeff Johnson295189b2012-06-20 16:38:30 -070010527 {
10528 pWextState->wpaVersion = IW_AUTH_WPA_VERSION_WPA2;
10529 encryptionType = eCSR_ENCRYPT_TYPE_AES;
10530 }
Shailender Karmuchi67edd312013-06-18 16:30:48 -070010531 else if ( hdd_isWPAIEPresent (params->ie, params->ie_len ))
Jeff Johnson295189b2012-06-20 16:38:30 -070010532 {
Shailender Karmuchi642e9812013-05-30 14:34:49 -070010533 tDot11fIEWPA dot11WPAIE;
10534 tHalHandle halHandle = WLAN_HDD_GET_HAL_CTX(pAdapter);
Shailender Karmuchi67edd312013-06-18 16:30:48 -070010535 u8 *ie;
Shailender Karmuchi642e9812013-05-30 14:34:49 -070010536
Wilson Yang00256342013-10-10 23:13:38 -070010537 memset(&dot11WPAIE, 0, sizeof(dot11WPAIE));
Shailender Karmuchi67edd312013-06-18 16:30:48 -070010538 ie = wlan_hdd_cfg80211_get_ie_ptr (params->ie,
10539 params->ie_len, DOT11F_EID_WPA);
10540 if ( NULL != ie )
10541 {
10542 pWextState->wpaVersion = IW_AUTH_WPA_VERSION_WPA;
10543 // Unpack the WPA IE
10544 //Skip past the EID byte and length byte - and four byte WiFi OUI
10545 dot11fUnpackIeWPA((tpAniSirGlobal) halHandle,
10546 &ie[2+4],
10547 ie[1] - 4,
10548 &dot11WPAIE);
10549 /*Extract the multicast cipher, the encType for unicast
10550 cipher for wpa-none is none*/
10551 encryptionType =
10552 hdd_TranslateWPAToCsrEncryptionType(dot11WPAIE.multicast_cipher);
10553 }
Jeff Johnson295189b2012-06-20 16:38:30 -070010554 }
Shailender Karmuchi67edd312013-06-18 16:30:48 -070010555
Jeff Johnson295189b2012-06-20 16:38:30 -070010556 status = wlan_hdd_cfg80211_set_ie(pAdapter, params->ie, params->ie_len);
10557
10558 if (0 > status)
10559 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010560 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: failed to parse WPA/RSN IE",
Jeff Johnson295189b2012-06-20 16:38:30 -070010561 __func__);
10562 return status;
10563 }
10564 }
10565
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010566 pWextState->roamProfile.AuthType.authType[0] =
10567 pHddStaCtx->conn_info.authType =
Jeff Johnson295189b2012-06-20 16:38:30 -070010568 eCSR_AUTH_TYPE_OPEN_SYSTEM;
10569
10570 if (params->privacy)
10571 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010572 /* Security enabled IBSS, At this time there is no information available
10573 * about the security paramters, so initialise the encryption type to
Jeff Johnson295189b2012-06-20 16:38:30 -070010574 * eCSR_ENCRYPT_TYPE_WEP40_STATICKEY.
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010575 * The correct security parameters will be updated later in
Jeff Johnson295189b2012-06-20 16:38:30 -070010576 * wlan_hdd_cfg80211_add_key */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010577 /* Hal expects encryption type to be set inorder
Jeff Johnson295189b2012-06-20 16:38:30 -070010578 *enable privacy bit in beacons */
10579
10580 encryptionType = eCSR_ENCRYPT_TYPE_WEP40_STATICKEY;
10581 }
Shailender Karmuchi642e9812013-05-30 14:34:49 -070010582 VOS_TRACE (VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO_HIGH,
10583 "encryptionType=%d", encryptionType);
Jeff Johnson295189b2012-06-20 16:38:30 -070010584 pHddStaCtx->conn_info.ucEncryptionType = encryptionType;
10585 pWextState->roamProfile.EncryptionType.numEntries = 1;
10586 pWextState->roamProfile.EncryptionType.encryptionType[0] = encryptionType;
Jeff Johnson295189b2012-06-20 16:38:30 -070010587 return status;
10588}
10589
10590/*
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053010591 * FUNCTION: __wlan_hdd_cfg80211_join_ibss
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010592 * This function is used to create/join an IBSS
Jeff Johnson295189b2012-06-20 16:38:30 -070010593 */
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053010594static int __wlan_hdd_cfg80211_join_ibss( struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -070010595 struct net_device *dev,
10596 struct cfg80211_ibss_params *params
10597 )
10598{
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010599 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( dev );
Jeff Johnson295189b2012-06-20 16:38:30 -070010600 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
10601 tCsrRoamProfile *pRoamProfile;
10602 int status;
krunal sonie9002db2013-11-25 14:24:17 -080010603 bool alloc_bssid = VOS_FALSE;
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053010604 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
10605 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Jeff Johnson295189b2012-06-20 16:38:30 -070010606
10607 ENTER();
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053010608
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053010609 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
10610 TRACE_CODE_HDD_CFG80211_JOIN_IBSS,
10611 pAdapter->sessionId, pAdapter->device_mode));
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010612 hddLog(VOS_TRACE_LEVEL_INFO,
Sushant Kaushik8bc7df22014-04-09 17:55:29 +053010613 "%s: device_mode = %s (%d)", __func__,
10614 hdd_device_modetoString(pAdapter->device_mode),
10615 pAdapter->device_mode);
Jeff Johnson295189b2012-06-20 16:38:30 -070010616
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053010617 status = wlan_hdd_validate_context(pHddCtx);
10618
10619 if (0 != status)
Jeff Johnson295189b2012-06-20 16:38:30 -070010620 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053010621 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
10622 "%s: HDD context is not valid", __func__);
10623 return status;
Jeff Johnson295189b2012-06-20 16:38:30 -070010624 }
10625
10626 if (NULL == pWextState)
10627 {
Arif Hussain6d2a3322013-11-17 19:50:10 -080010628 hddLog (VOS_TRACE_LEVEL_ERROR, "%s ERROR: Data Storage Corruption",
Jeff Johnson295189b2012-06-20 16:38:30 -070010629 __func__);
10630 return -EIO;
10631 }
10632
Agarwal Ashish51325b52014-06-16 16:50:49 +053010633 if (vos_max_concurrent_connections_reached()) {
10634 hddLog(VOS_TRACE_LEVEL_INFO, FL("Reached max concurrent connections"));
10635 return -ECONNREFUSED;
10636 }
10637
Vinay Krishna Eranna21042322014-01-08 19:21:39 +053010638 /*Try disconnecting if already in connected state*/
10639 status = wlan_hdd_try_disconnect(pAdapter);
10640 if ( 0 > status)
10641 {
10642 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Failed to disconnect the existing"
10643 " IBSS connection"));
10644 return -EALREADY;
10645 }
10646
Jeff Johnson295189b2012-06-20 16:38:30 -070010647 pRoamProfile = &pWextState->roamProfile;
10648
10649 if ( eCSR_BSS_TYPE_START_IBSS != pRoamProfile->BSSType )
10650 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010651 hddLog (VOS_TRACE_LEVEL_ERROR,
Arif Hussain6d2a3322013-11-17 19:50:10 -080010652 "%s Interface type is not set to IBSS", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -070010653 return -EINVAL;
10654 }
10655
Praveen Kumar Sirisillad123d142013-09-24 16:50:13 -070010656 /* BSSID is provided by upper layers hence no need to AUTO generate */
10657 if (NULL != params->bssid) {
10658 if (ccmCfgSetInt(pHddCtx->hHal, WNI_CFG_IBSS_AUTO_BSSID, 0,
10659 NULL, eANI_BOOLEAN_FALSE)==eHAL_STATUS_FAILURE) {
10660 hddLog (VOS_TRACE_LEVEL_ERROR,
10661 "%s:ccmCfgStInt faild for WNI_CFG_IBSS_AUTO_BSSID", __func__);
10662 return -EIO;
10663 }
10664 }
krunal sonie9002db2013-11-25 14:24:17 -080010665 else if(pHddCtx->cfg_ini->isCoalesingInIBSSAllowed == 0)
10666 {
10667 if (ccmCfgSetInt(pHddCtx->hHal, WNI_CFG_IBSS_AUTO_BSSID, 0,
10668 NULL, eANI_BOOLEAN_FALSE)==eHAL_STATUS_FAILURE)
10669 {
10670 hddLog (VOS_TRACE_LEVEL_ERROR,
10671 "%s:ccmCfgStInt faild for WNI_CFG_IBSS_AUTO_BSSID", __func__);
10672 return -EIO;
10673 }
10674 params->bssid = vos_mem_malloc(sizeof(VOS_MAC_ADDR_SIZE));
10675 if (!params->bssid)
10676 {
10677 hddLog (VOS_TRACE_LEVEL_ERROR,
10678 "%s:Failed memory allocation", __func__);
10679 return -EIO;
10680 }
10681 vos_mem_copy((v_U8_t *)params->bssid,
10682 (v_U8_t *)&pHddCtx->cfg_ini->IbssBssid.bytes[0],
10683 VOS_MAC_ADDR_SIZE);
10684 alloc_bssid = VOS_TRUE;
10685 }
Praveen Kumar Sirisillad123d142013-09-24 16:50:13 -070010686
Jeff Johnson295189b2012-06-20 16:38:30 -070010687 /* Set Channel */
Yue Maf49ba872013-08-19 12:04:25 -070010688 if (NULL !=
10689#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,8,0))
10690 params->chandef.chan)
10691#else
10692 params->channel)
10693#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070010694 {
10695 u8 channelNum;
Shailender Karmuchi15cd0672013-05-15 19:50:04 -070010696 v_U32_t numChans = WNI_CFG_VALID_CHANNEL_LIST_LEN;
10697 v_U8_t validChan[WNI_CFG_VALID_CHANNEL_LIST_LEN];
10698 tHalHandle hHal = WLAN_HDD_GET_HAL_CTX(pAdapter);
10699 int indx;
Jeff Johnson295189b2012-06-20 16:38:30 -070010700
10701 /* Get channel number */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010702 channelNum =
Yue Maf49ba872013-08-19 12:04:25 -070010703 ieee80211_frequency_to_channel(
10704#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,8,0))
10705 params->chandef.chan->center_freq);
10706#else
10707 params->channel->center_freq);
10708#endif
Shailender Karmuchi15cd0672013-05-15 19:50:04 -070010709
10710 if (0 != ccmCfgGetStr(hHal, WNI_CFG_VALID_CHANNEL_LIST,
10711 validChan, &numChans))
Jeff Johnson295189b2012-06-20 16:38:30 -070010712 {
Shailender Karmuchi15cd0672013-05-15 19:50:04 -070010713 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: No valid channel list",
10714 __func__);
10715 return -EOPNOTSUPP;
Jeff Johnson295189b2012-06-20 16:38:30 -070010716 }
Shailender Karmuchi15cd0672013-05-15 19:50:04 -070010717
10718 for (indx = 0; indx < numChans; indx++)
Jeff Johnson295189b2012-06-20 16:38:30 -070010719 {
Shailender Karmuchi15cd0672013-05-15 19:50:04 -070010720 if (channelNum == validChan[indx])
10721 {
10722 break;
10723 }
10724 }
10725 if (indx >= numChans)
10726 {
10727 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Not valid Channel %d",
Jeff Johnson295189b2012-06-20 16:38:30 -070010728 __func__, channelNum);
10729 return -EINVAL;
10730 }
Shailender Karmuchi15cd0672013-05-15 19:50:04 -070010731 /* Set the Operational Channel */
10732 hddLog(VOS_TRACE_LEVEL_INFO_HIGH, "%s: set channel %d", __func__,
10733 channelNum);
10734 pRoamProfile->ChannelInfo.numOfChannels = 1;
10735 pHddStaCtx->conn_info.operationChannel = channelNum;
10736 pRoamProfile->ChannelInfo.ChannelList =
10737 &pHddStaCtx->conn_info.operationChannel;
Jeff Johnson295189b2012-06-20 16:38:30 -070010738 }
10739
10740 /* Initialize security parameters */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010741 status = wlan_hdd_cfg80211_set_privacy_ibss(pAdapter, params);
Jeff Johnson295189b2012-06-20 16:38:30 -070010742 if (status < 0)
10743 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010744 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: failed to set security parameters",
Jeff Johnson295189b2012-06-20 16:38:30 -070010745 __func__);
10746 return status;
10747 }
10748
10749 /* Issue connect start */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010750 status = wlan_hdd_cfg80211_connect_start(pAdapter, params->ssid,
Shailender Karmuchi15cd0672013-05-15 19:50:04 -070010751 params->ssid_len, params->bssid,
10752 pHddStaCtx->conn_info.operationChannel);
Jeff Johnson295189b2012-06-20 16:38:30 -070010753
10754 if (0 > status)
10755 {
10756 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: connect failed", __func__);
10757 return status;
10758 }
10759
krunal sonie9002db2013-11-25 14:24:17 -080010760 if (NULL != params->bssid &&
10761 pHddCtx->cfg_ini->isCoalesingInIBSSAllowed == 0 &&
10762 alloc_bssid == VOS_TRUE)
10763 {
10764 vos_mem_free(params->bssid);
10765 }
Jeff Johnson295189b2012-06-20 16:38:30 -070010766 return 0;
10767}
10768
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053010769static int wlan_hdd_cfg80211_join_ibss( struct wiphy *wiphy,
10770 struct net_device *dev,
10771 struct cfg80211_ibss_params *params
10772 )
10773{
10774 int ret = 0;
10775
10776 vos_ssr_protect(__func__);
10777 ret = __wlan_hdd_cfg80211_join_ibss(wiphy, dev, params);
10778 vos_ssr_unprotect(__func__);
10779
10780 return ret;
10781}
10782
Jeff Johnson295189b2012-06-20 16:38:30 -070010783/*
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053010784 * FUNCTION: __wlan_hdd_cfg80211_leave_ibss
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010785 * This function is used to leave an IBSS
Jeff Johnson295189b2012-06-20 16:38:30 -070010786 */
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053010787static int __wlan_hdd_cfg80211_leave_ibss( struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -070010788 struct net_device *dev
10789 )
10790{
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010791 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( dev );
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053010792 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
10793 tCsrRoamProfile *pRoamProfile;
10794 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053010795 int status;
Jeff Johnson295189b2012-06-20 16:38:30 -070010796
10797 ENTER();
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053010798
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053010799 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
10800 TRACE_CODE_HDD_CFG80211_LEAVE_IBSS,
10801 pAdapter->sessionId, eCSR_DISCONNECT_REASON_IBSS_LEAVE));
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053010802 status = wlan_hdd_validate_context(pHddCtx);
10803
10804 if (0 != status)
Jeff Johnson04dd8a82012-06-29 20:41:40 -070010805 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053010806 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
10807 "%s: HDD context is not valid", __func__);
10808 return status;
Jeff Johnson04dd8a82012-06-29 20:41:40 -070010809 }
10810
Sushant Kaushik8bc7df22014-04-09 17:55:29 +053010811 hddLog(VOS_TRACE_LEVEL_INFO, "%s: device_mode = %s (%d)", __func__,
10812 hdd_device_modetoString(pAdapter->device_mode),
10813 pAdapter->device_mode);
Jeff Johnson295189b2012-06-20 16:38:30 -070010814 if (NULL == pWextState)
10815 {
Arif Hussain6d2a3322013-11-17 19:50:10 -080010816 hddLog (VOS_TRACE_LEVEL_ERROR, "%s ERROR: Data Storage Corruption",
Jeff Johnson295189b2012-06-20 16:38:30 -070010817 __func__);
10818 return -EIO;
10819 }
10820
10821 pRoamProfile = &pWextState->roamProfile;
10822
10823 /* Issue disconnect only if interface type is set to IBSS */
10824 if (eCSR_BSS_TYPE_START_IBSS != pRoamProfile->BSSType)
10825 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010826 hddLog (VOS_TRACE_LEVEL_ERROR, "%s: BSS Type is not set to IBSS",
Jeff Johnson295189b2012-06-20 16:38:30 -070010827 __func__);
10828 return -EINVAL;
10829 }
10830
10831 /* Issue Disconnect request */
10832 INIT_COMPLETION(pAdapter->disconnect_comp_var);
10833 sme_RoamDisconnect( WLAN_HDD_GET_HAL_CTX(pAdapter), pAdapter->sessionId,
10834 eCSR_DISCONNECT_REASON_IBSS_LEAVE);
10835
10836 return 0;
10837}
10838
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053010839static int wlan_hdd_cfg80211_leave_ibss( struct wiphy *wiphy,
10840 struct net_device *dev
10841 )
10842{
10843 int ret = 0;
10844
10845 vos_ssr_protect(__func__);
10846 ret = __wlan_hdd_cfg80211_leave_ibss(wiphy, dev);
10847 vos_ssr_unprotect(__func__);
10848
10849 return ret;
10850}
10851
Jeff Johnson295189b2012-06-20 16:38:30 -070010852/*
Mahesh A Saptasagar179d2252014-06-02 21:32:21 +053010853 * FUNCTION: __wlan_hdd_cfg80211_set_wiphy_params
Jeff Johnson295189b2012-06-20 16:38:30 -070010854 * This function is used to set the phy parameters
10855 * (RTS Threshold/FRAG Threshold/Retry Count etc ...)
10856 */
Mahesh A Saptasagar179d2252014-06-02 21:32:21 +053010857static int __wlan_hdd_cfg80211_set_wiphy_params(struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -070010858 u32 changed)
10859{
10860 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
10861 tHalHandle hHal = pHddCtx->hHal;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053010862 int status;
Jeff Johnson295189b2012-06-20 16:38:30 -070010863
10864 ENTER();
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053010865 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
10866 TRACE_CODE_HDD_CFG80211_SET_WIPHY_PARAMS,
10867 NO_SESSION, wiphy->rts_threshold));
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053010868 status = wlan_hdd_validate_context(pHddCtx);
10869
10870 if (0 != status)
Jeff Johnson04dd8a82012-06-29 20:41:40 -070010871 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053010872 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
10873 "%s: HDD context is not valid", __func__);
10874 return status;
Jeff Johnson04dd8a82012-06-29 20:41:40 -070010875 }
10876
Jeff Johnson295189b2012-06-20 16:38:30 -070010877 if (changed & WIPHY_PARAM_RTS_THRESHOLD)
10878 {
10879 u16 rts_threshold = (wiphy->rts_threshold == -1) ?
10880 WNI_CFG_RTS_THRESHOLD_STAMAX :
10881 wiphy->rts_threshold;
10882
10883 if ((WNI_CFG_RTS_THRESHOLD_STAMIN > rts_threshold) ||
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010884 (WNI_CFG_RTS_THRESHOLD_STAMAX < rts_threshold))
Jeff Johnson295189b2012-06-20 16:38:30 -070010885 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010886 hddLog(VOS_TRACE_LEVEL_ERROR,
10887 "%s: Invalid RTS Threshold value %hu",
Jeff Johnson295189b2012-06-20 16:38:30 -070010888 __func__, rts_threshold);
10889 return -EINVAL;
10890 }
10891
10892 if (0 != ccmCfgSetInt(hHal, WNI_CFG_RTS_THRESHOLD,
10893 rts_threshold, ccmCfgSetCallback,
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010894 eANI_BOOLEAN_TRUE))
Jeff Johnson295189b2012-06-20 16:38:30 -070010895 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010896 hddLog(VOS_TRACE_LEVEL_ERROR,
10897 "%s: ccmCfgSetInt failed for rts_threshold value %hu",
Jeff Johnson295189b2012-06-20 16:38:30 -070010898 __func__, rts_threshold);
10899 return -EIO;
10900 }
10901
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010902 hddLog(VOS_TRACE_LEVEL_INFO_MED, "%s: set rts threshold %hu", __func__,
Jeff Johnson295189b2012-06-20 16:38:30 -070010903 rts_threshold);
10904 }
10905
10906 if (changed & WIPHY_PARAM_FRAG_THRESHOLD)
10907 {
10908 u16 frag_threshold = (wiphy->frag_threshold == -1) ?
10909 WNI_CFG_FRAGMENTATION_THRESHOLD_STAMAX :
10910 wiphy->frag_threshold;
10911
10912 if ((WNI_CFG_FRAGMENTATION_THRESHOLD_STAMIN > frag_threshold)||
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010913 (WNI_CFG_FRAGMENTATION_THRESHOLD_STAMAX < frag_threshold) )
Jeff Johnson295189b2012-06-20 16:38:30 -070010914 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010915 hddLog(VOS_TRACE_LEVEL_ERROR,
10916 "%s: Invalid frag_threshold value %hu", __func__,
Jeff Johnson295189b2012-06-20 16:38:30 -070010917 frag_threshold);
10918 return -EINVAL;
10919 }
10920
10921 if (0 != ccmCfgSetInt(hHal, WNI_CFG_FRAGMENTATION_THRESHOLD,
10922 frag_threshold, ccmCfgSetCallback,
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010923 eANI_BOOLEAN_TRUE))
Jeff Johnson295189b2012-06-20 16:38:30 -070010924 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010925 hddLog(VOS_TRACE_LEVEL_ERROR,
10926 "%s: ccmCfgSetInt failed for frag_threshold value %hu",
Jeff Johnson295189b2012-06-20 16:38:30 -070010927 __func__, frag_threshold);
10928 return -EIO;
10929 }
10930
10931 hddLog(VOS_TRACE_LEVEL_INFO_MED, "%s: set frag threshold %hu", __func__,
10932 frag_threshold);
10933 }
10934
10935 if ((changed & WIPHY_PARAM_RETRY_SHORT)
10936 || (changed & WIPHY_PARAM_RETRY_LONG))
10937 {
10938 u8 retry_value = (changed & WIPHY_PARAM_RETRY_SHORT) ?
10939 wiphy->retry_short :
10940 wiphy->retry_long;
10941
10942 if ((WNI_CFG_LONG_RETRY_LIMIT_STAMIN > retry_value) ||
10943 (WNI_CFG_LONG_RETRY_LIMIT_STAMAX < retry_value))
10944 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010945 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Invalid Retry count %hu",
Jeff Johnson295189b2012-06-20 16:38:30 -070010946 __func__, retry_value);
10947 return -EINVAL;
10948 }
10949
10950 if (changed & WIPHY_PARAM_RETRY_SHORT)
10951 {
10952 if (0 != ccmCfgSetInt(hHal, WNI_CFG_LONG_RETRY_LIMIT,
10953 retry_value, ccmCfgSetCallback,
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010954 eANI_BOOLEAN_TRUE))
Jeff Johnson295189b2012-06-20 16:38:30 -070010955 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010956 hddLog(VOS_TRACE_LEVEL_ERROR,
10957 "%s: ccmCfgSetInt failed for long retry count %hu",
Jeff Johnson295189b2012-06-20 16:38:30 -070010958 __func__, retry_value);
10959 return -EIO;
10960 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010961 hddLog(VOS_TRACE_LEVEL_INFO_MED, "%s: set long retry count %hu",
Jeff Johnson295189b2012-06-20 16:38:30 -070010962 __func__, retry_value);
10963 }
10964 else if (changed & WIPHY_PARAM_RETRY_SHORT)
10965 {
10966 if (0 != ccmCfgSetInt(hHal, WNI_CFG_SHORT_RETRY_LIMIT,
10967 retry_value, ccmCfgSetCallback,
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010968 eANI_BOOLEAN_TRUE))
Jeff Johnson295189b2012-06-20 16:38:30 -070010969 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010970 hddLog(VOS_TRACE_LEVEL_ERROR,
10971 "%s: ccmCfgSetInt failed for short retry count %hu",
Jeff Johnson295189b2012-06-20 16:38:30 -070010972 __func__, retry_value);
10973 return -EIO;
10974 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010975 hddLog(VOS_TRACE_LEVEL_INFO_MED, "%s: set short retry count %hu",
Jeff Johnson295189b2012-06-20 16:38:30 -070010976 __func__, retry_value);
10977 }
10978 }
10979
10980 return 0;
10981}
10982
Mahesh A Saptasagar179d2252014-06-02 21:32:21 +053010983static int wlan_hdd_cfg80211_set_wiphy_params(struct wiphy *wiphy,
10984 u32 changed)
10985{
10986 int ret;
10987
10988 vos_ssr_protect(__func__);
10989 ret = __wlan_hdd_cfg80211_set_wiphy_params(wiphy, changed);
10990 vos_ssr_unprotect(__func__);
10991
10992 return ret;
10993}
10994
Jeff Johnson295189b2012-06-20 16:38:30 -070010995/*
Mahesh A Saptasagar179d2252014-06-02 21:32:21 +053010996 * FUNCTION: __wlan_hdd_cfg80211_set_txpower
Jeff Johnson295189b2012-06-20 16:38:30 -070010997 * This function is used to set the txpower
10998 */
Mahesh A Saptasagar179d2252014-06-02 21:32:21 +053010999static int __wlan_hdd_cfg80211_set_txpower(struct wiphy *wiphy,
Yue Maf49ba872013-08-19 12:04:25 -070011000#if LINUX_VERSION_CODE >= KERNEL_VERSION(3,8,0)
11001 struct wireless_dev *wdev,
11002#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070011003#if LINUX_VERSION_CODE <= KERNEL_VERSION(2,6,35)
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011004 enum tx_power_setting type,
Jeff Johnson295189b2012-06-20 16:38:30 -070011005#else
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011006 enum nl80211_tx_power_setting type,
Jeff Johnson295189b2012-06-20 16:38:30 -070011007#endif
11008 int dbm)
11009{
11010 hdd_context_t *pHddCtx = (hdd_context_t*) wiphy_priv(wiphy);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053011011 tHalHandle hHal = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -070011012 tSirMacAddr bssid = {0xFF,0xFF,0xFF,0xFF,0xFF,0xFF};
11013 tSirMacAddr selfMac = {0xFF,0xFF,0xFF,0xFF,0xFF,0xFF};
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053011014 int status;
Jeff Johnson295189b2012-06-20 16:38:30 -070011015
11016 ENTER();
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053011017 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
11018 TRACE_CODE_HDD_CFG80211_SET_TXPOWER,
11019 NO_SESSION, type ));
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053011020 status = wlan_hdd_validate_context(pHddCtx);
11021
11022 if (0 != status)
11023 {
11024 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
11025 "%s: HDD context is not valid", __func__);
11026 return status;
11027 }
11028
11029 hHal = pHddCtx->hHal;
11030
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011031 if (0 != ccmCfgSetInt(hHal, WNI_CFG_CURRENT_TX_POWER_LEVEL,
11032 dbm, ccmCfgSetCallback,
11033 eANI_BOOLEAN_TRUE))
Jeff Johnson295189b2012-06-20 16:38:30 -070011034 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011035 hddLog(VOS_TRACE_LEVEL_ERROR,
Jeff Johnson295189b2012-06-20 16:38:30 -070011036 "%s: ccmCfgSetInt failed for tx power %hu", __func__, dbm);
11037 return -EIO;
11038 }
11039
11040 hddLog(VOS_TRACE_LEVEL_INFO_MED, "%s: set tx power level %d dbm", __func__,
11041 dbm);
11042
11043 switch(type)
11044 {
11045 case NL80211_TX_POWER_AUTOMATIC: /*automatically determine transmit power*/
11046 /* Fall through */
11047 case NL80211_TX_POWER_LIMITED: /*limit TX power by the mBm parameter*/
11048 if( sme_SetMaxTxPower(hHal, bssid, selfMac, dbm) != eHAL_STATUS_SUCCESS )
11049 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011050 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Setting maximum tx power failed",
11051 __func__);
11052 return -EIO;
Jeff Johnson295189b2012-06-20 16:38:30 -070011053 }
11054 break;
11055 case NL80211_TX_POWER_FIXED: /*fix TX power to the mBm parameter*/
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011056 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: NL80211_TX_POWER_FIXED not supported",
Jeff Johnson295189b2012-06-20 16:38:30 -070011057 __func__);
11058 return -EOPNOTSUPP;
11059 break;
11060 default:
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011061 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Invalid power setting type %d",
11062 __func__, type);
Jeff Johnson295189b2012-06-20 16:38:30 -070011063 return -EIO;
11064 }
11065
11066 return 0;
11067}
11068
Mahesh A Saptasagar179d2252014-06-02 21:32:21 +053011069static int wlan_hdd_cfg80211_set_txpower(struct wiphy *wiphy,
11070#if LINUX_VERSION_CODE >= KERNEL_VERSION(3,8,0)
11071 struct wireless_dev *wdev,
11072#endif
11073#if LINUX_VERSION_CODE <= KERNEL_VERSION(2,6,35)
11074 enum tx_power_setting type,
11075#else
11076 enum nl80211_tx_power_setting type,
11077#endif
11078 int dbm)
11079{
11080 int ret;
11081 vos_ssr_protect(__func__);
11082 ret = __wlan_hdd_cfg80211_set_txpower(wiphy,
11083#if LINUX_VERSION_CODE >= KERNEL_VERSION(3,8,0)
11084 wdev,
11085#endif
11086#if LINUX_VERSION_CODE <= KERNEL_VERSION(2,6,35)
11087 type,
11088#else
11089 type,
11090#endif
11091 dbm);
11092 vos_ssr_unprotect(__func__);
11093
11094 return ret;
11095}
11096
Jeff Johnson295189b2012-06-20 16:38:30 -070011097/*
11098 * FUNCTION: wlan_hdd_cfg80211_get_txpower
11099 * This function is used to read the txpower
11100 */
Yue Maf49ba872013-08-19 12:04:25 -070011101static int wlan_hdd_cfg80211_get_txpower(struct wiphy *wiphy,
11102#if LINUX_VERSION_CODE >= KERNEL_VERSION(3,8,0)
11103 struct wireless_dev *wdev,
11104#endif
11105 int *dbm)
Jeff Johnson295189b2012-06-20 16:38:30 -070011106{
11107
11108 hdd_adapter_t *pAdapter;
11109 hdd_context_t *pHddCtx = (hdd_context_t*) wiphy_priv(wiphy);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053011110 int status;
Jeff Johnson295189b2012-06-20 16:38:30 -070011111
Jeff Johnsone7245742012-09-05 17:12:55 -070011112 ENTER();
11113
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053011114 status = wlan_hdd_validate_context(pHddCtx);
Jeff Johnson295189b2012-06-20 16:38:30 -070011115
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053011116 if (0 != status)
Jeff Johnson04dd8a82012-06-29 20:41:40 -070011117 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053011118 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
11119 "%s: HDD context is not valid", __func__);
11120 *dbm = 0;
11121 return status;
Jeff Johnson04dd8a82012-06-29 20:41:40 -070011122 }
11123
Jeff Johnson295189b2012-06-20 16:38:30 -070011124 pAdapter = hdd_get_adapter(pHddCtx, WLAN_HDD_INFRA_STATION);
11125 if (NULL == pAdapter)
11126 {
11127 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: Not in station context " ,__func__);
11128 return -ENOENT;
11129 }
11130
11131 wlan_hdd_get_classAstats(pAdapter);
11132 *dbm = pAdapter->hdd_stats.ClassA_stat.max_pwr;
11133
Jeff Johnsone7245742012-09-05 17:12:55 -070011134 EXIT();
Jeff Johnson295189b2012-06-20 16:38:30 -070011135 return 0;
11136}
11137
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053011138static int __wlan_hdd_cfg80211_get_station(struct wiphy *wiphy, struct net_device *dev,
Jeff Johnson295189b2012-06-20 16:38:30 -070011139 u8* mac, struct station_info *sinfo)
11140{
11141 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( dev );
11142 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
11143 int ssidlen = pHddStaCtx->conn_info.SSID.SSID.length;
c_hpothu44ff4e02014-05-08 00:13:57 +053011144 tANI_U32 rate_flags;
Jeff Johnson295189b2012-06-20 16:38:30 -070011145
11146 hdd_context_t *pHddCtx = (hdd_context_t*) wiphy_priv(wiphy);
11147 hdd_config_t *pCfg = pHddCtx->cfg_ini;
Jeff Johnson295189b2012-06-20 16:38:30 -070011148
11149 tANI_U8 OperationalRates[CSR_DOT11_SUPPORTED_RATES_MAX];
11150 tANI_U32 ORLeng = CSR_DOT11_SUPPORTED_RATES_MAX;
11151 tANI_U8 ExtendedRates[CSR_DOT11_EXTENDED_SUPPORTED_RATES_MAX];
11152 tANI_U32 ERLeng = CSR_DOT11_EXTENDED_SUPPORTED_RATES_MAX;
11153 tANI_U8 MCSRates[SIZE_OF_BASIC_MCS_SET];
11154 tANI_U32 MCSLeng = SIZE_OF_BASIC_MCS_SET;
11155 tANI_U16 maxRate = 0;
11156 tANI_U16 myRate;
11157 tANI_U16 currentRate = 0;
11158 tANI_U8 maxSpeedMCS = 0;
11159 tANI_U8 maxMCSIdx = 0;
11160 tANI_U8 rateFlag = 1;
c_hpothu79aab322014-07-14 21:11:01 +053011161 tANI_U8 i, j, rssidx, mode=0;
Madan Mohan Koyyalamudic75be962012-10-18 19:19:03 -070011162 tANI_U16 temp;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053011163 int status;
Jeff Johnson295189b2012-06-20 16:38:30 -070011164
Leo Chang6f8870f2013-03-26 18:11:36 -070011165#ifdef WLAN_FEATURE_11AC
11166 tANI_U32 vht_mcs_map;
11167 eDataRate11ACMaxMcs vhtMaxMcs;
11168#endif /* WLAN_FEATURE_11AC */
11169
Jeff Johnsone7245742012-09-05 17:12:55 -070011170 ENTER();
11171
Jeff Johnson295189b2012-06-20 16:38:30 -070011172 if ((eConnectionState_Associated != pHddStaCtx->conn_info.connState) ||
11173 (0 == ssidlen))
11174 {
11175 hddLog(VOS_TRACE_LEVEL_INFO, "%s: Not associated or"
11176 " Invalid ssidlen, %d", __func__, ssidlen);
11177 /*To keep GUI happy*/
11178 return 0;
11179 }
11180
Mukul Sharma811205f2014-07-09 21:07:30 +053011181 if (VOS_TRUE == pHddStaCtx->hdd_ReassocScenario)
11182 {
11183 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
11184 "%s: Roaming in progress, so unable to proceed this request", __func__);
11185 return 0;
11186 }
11187
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053011188 status = wlan_hdd_validate_context(pHddCtx);
11189
11190 if (0 != status)
Jeff Johnson04dd8a82012-06-29 20:41:40 -070011191 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053011192 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
11193 "%s: HDD context is not valid", __func__);
11194 return status;
Jeff Johnson04dd8a82012-06-29 20:41:40 -070011195 }
11196
Jeff Johnson295189b2012-06-20 16:38:30 -070011197
Kiet Lam3b17fc82013-09-27 05:24:08 +053011198 wlan_hdd_get_rssi(pAdapter, &sinfo->signal);
11199 sinfo->filled |= STATION_INFO_SIGNAL;
11200
c_hpothu09f19542014-05-30 21:53:31 +053011201 wlan_hdd_get_station_stats(pAdapter);
11202 rate_flags = pAdapter->hdd_stats.ClassA_stat.tx_rate_flags;
11203
11204 /*overwrite rate_flags if MAX link-speed need to be reported*/
c_hpothu44ff4e02014-05-08 00:13:57 +053011205 if ((eHDD_LINK_SPEED_REPORT_MAX == pCfg->reportMaxLinkSpeed) ||
11206 (eHDD_LINK_SPEED_REPORT_MAX_SCALED == pCfg->reportMaxLinkSpeed &&
c_hpothu79aab322014-07-14 21:11:01 +053011207 sinfo->signal >= pCfg->linkSpeedRssiLow))
c_hpothu44ff4e02014-05-08 00:13:57 +053011208 {
11209 rate_flags = pAdapter->maxRateFlags;
11210 }
c_hpothu44ff4e02014-05-08 00:13:57 +053011211
Jeff Johnson295189b2012-06-20 16:38:30 -070011212 //convert to the UI units of 100kbps
11213 myRate = pAdapter->hdd_stats.ClassA_stat.tx_rate * 5;
11214
11215#ifdef LINKSPEED_DEBUG_ENABLED
Leo Chang6f8870f2013-03-26 18:11:36 -070011216 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 -070011217 sinfo->signal,
11218 pCfg->reportMaxLinkSpeed,
11219 myRate,
11220 (int) pCfg->linkSpeedRssiHigh,
Madan Mohan Koyyalamudi8df78d52012-11-02 12:30:06 -070011221 (int) pCfg->linkSpeedRssiMid,
11222 (int) pCfg->linkSpeedRssiLow,
Leo Chang6f8870f2013-03-26 18:11:36 -070011223 (int) rate_flags,
11224 (int) pAdapter->hdd_stats.ClassA_stat.mcs_index);
Jeff Johnson295189b2012-06-20 16:38:30 -070011225#endif //LINKSPEED_DEBUG_ENABLED
11226
11227 if (eHDD_LINK_SPEED_REPORT_ACTUAL != pCfg->reportMaxLinkSpeed)
11228 {
11229 // we do not want to necessarily report the current speed
11230 if (eHDD_LINK_SPEED_REPORT_MAX == pCfg->reportMaxLinkSpeed)
11231 {
11232 // report the max possible speed
11233 rssidx = 0;
11234 }
11235 else if (eHDD_LINK_SPEED_REPORT_MAX_SCALED == pCfg->reportMaxLinkSpeed)
11236 {
11237 // report the max possible speed with RSSI scaling
11238 if (sinfo->signal >= pCfg->linkSpeedRssiHigh)
11239 {
11240 // report the max possible speed
11241 rssidx = 0;
11242 }
Madan Mohan Koyyalamudi8df78d52012-11-02 12:30:06 -070011243 else if (sinfo->signal >= pCfg->linkSpeedRssiMid)
Jeff Johnson295189b2012-06-20 16:38:30 -070011244 {
11245 // report middle speed
11246 rssidx = 1;
11247 }
Madan Mohan Koyyalamudi8df78d52012-11-02 12:30:06 -070011248 else if (sinfo->signal >= pCfg->linkSpeedRssiLow)
11249 {
11250 // report middle speed
11251 rssidx = 2;
11252 }
Jeff Johnson295189b2012-06-20 16:38:30 -070011253 else
11254 {
11255 // report actual speed
Madan Mohan Koyyalamudi8df78d52012-11-02 12:30:06 -070011256 rssidx = 3;
Jeff Johnson295189b2012-06-20 16:38:30 -070011257 }
11258 }
11259 else
11260 {
11261 // unknown, treat as eHDD_LINK_SPEED_REPORT_MAX
11262 hddLog(VOS_TRACE_LEVEL_ERROR,
11263 "%s: Invalid value for reportMaxLinkSpeed: %u",
11264 __func__, pCfg->reportMaxLinkSpeed);
11265 rssidx = 0;
11266 }
11267
11268 maxRate = 0;
11269
11270 /* Get Basic Rate Set */
Gopichand Nakkala05ab1322013-02-15 11:28:38 +053011271 if (0 != ccmCfgGetStr(WLAN_HDD_GET_HAL_CTX(pAdapter), WNI_CFG_OPERATIONAL_RATE_SET,
11272 OperationalRates, &ORLeng))
11273 {
11274 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: ccm api returned failure", __func__);
11275 /*To keep GUI happy*/
11276 return 0;
11277 }
11278
Jeff Johnson295189b2012-06-20 16:38:30 -070011279 for (i = 0; i < ORLeng; i++)
11280 {
Jeff Johnsone7245742012-09-05 17:12:55 -070011281 for (j = 0; j < (sizeof(supported_data_rate) / sizeof(supported_data_rate[0])); j ++)
Jeff Johnson295189b2012-06-20 16:38:30 -070011282 {
11283 /* Validate Rate Set */
11284 if (supported_data_rate[j].beacon_rate_index == (OperationalRates[i] & 0x7F))
11285 {
11286 currentRate = supported_data_rate[j].supported_rate[rssidx];
11287 break;
11288 }
11289 }
11290 /* Update MAX rate */
11291 maxRate = (currentRate > maxRate)?currentRate:maxRate;
11292 }
11293
11294 /* Get Extended Rate Set */
Gopichand Nakkala05ab1322013-02-15 11:28:38 +053011295 if (0 != ccmCfgGetStr(WLAN_HDD_GET_HAL_CTX(pAdapter), WNI_CFG_EXTENDED_OPERATIONAL_RATE_SET,
11296 ExtendedRates, &ERLeng))
11297 {
11298 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: ccm api returned failure", __func__);
11299 /*To keep GUI happy*/
11300 return 0;
11301 }
11302
Jeff Johnson295189b2012-06-20 16:38:30 -070011303 for (i = 0; i < ERLeng; i++)
11304 {
Jeff Johnsone7245742012-09-05 17:12:55 -070011305 for (j = 0; j < (sizeof(supported_data_rate) / sizeof(supported_data_rate[0])); j ++)
Jeff Johnson295189b2012-06-20 16:38:30 -070011306 {
11307 if (supported_data_rate[j].beacon_rate_index == (ExtendedRates[i] & 0x7F))
11308 {
11309 currentRate = supported_data_rate[j].supported_rate[rssidx];
11310 break;
11311 }
11312 }
11313 /* Update MAX rate */
11314 maxRate = (currentRate > maxRate)?currentRate:maxRate;
11315 }
c_hpothu79aab322014-07-14 21:11:01 +053011316
Kiet Lamb69f8dc2013-11-15 15:34:27 +053011317 /* Get MCS Rate Set --
Kaushik, Sushantdc304d82014-01-22 10:58:37 +053011318 Only if we are always reporting max speed (or)
Kiet Lamb69f8dc2013-11-15 15:34:27 +053011319 if we have good rssi */
c_hpothu79aab322014-07-14 21:11:01 +053011320 if ((3 != rssidx) && !(rate_flags & eHAL_TX_RATE_LEGACY))
Jeff Johnson295189b2012-06-20 16:38:30 -070011321 {
c_hpothu79aab322014-07-14 21:11:01 +053011322 if (rate_flags & eHAL_TX_RATE_VHT80)
11323 mode = 2;
11324 else if (rate_flags & (eHAL_TX_RATE_VHT40 | eHAL_TX_RATE_HT40))
11325 mode = 1;
11326 else
11327 mode = 0;
11328
Gopichand Nakkala05ab1322013-02-15 11:28:38 +053011329 if (0 != ccmCfgGetStr(WLAN_HDD_GET_HAL_CTX(pAdapter), WNI_CFG_CURRENT_MCS_SET,
11330 MCSRates, &MCSLeng))
11331 {
11332 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: ccm api returned failure", __func__);
11333 /*To keep GUI happy*/
11334 return 0;
11335 }
Jeff Johnson295189b2012-06-20 16:38:30 -070011336 rateFlag = 0;
Leo Chang6f8870f2013-03-26 18:11:36 -070011337#ifdef WLAN_FEATURE_11AC
11338 /* VHT80 rate has seperate rate table */
Gopichand Nakkala4c705372013-04-24 13:20:33 +053011339 if (rate_flags & (eHAL_TX_RATE_VHT20|eHAL_TX_RATE_VHT40|eHAL_TX_RATE_VHT80))
Jeff Johnson295189b2012-06-20 16:38:30 -070011340 {
Leo Chang6f8870f2013-03-26 18:11:36 -070011341 ccmCfgGetInt(WLAN_HDD_GET_HAL_CTX(pAdapter), WNI_CFG_VHT_TX_MCS_MAP, &vht_mcs_map);
Gopichand Nakkala4c705372013-04-24 13:20:33 +053011342 vhtMaxMcs = (eDataRate11ACMaxMcs)(vht_mcs_map & DATA_RATE_11AC_MCS_MASK );
Leo Chang6f8870f2013-03-26 18:11:36 -070011343 if (rate_flags & eHAL_TX_RATE_SGI)
Jeff Johnson295189b2012-06-20 16:38:30 -070011344 {
Leo Chang6f8870f2013-03-26 18:11:36 -070011345 rateFlag |= 1;
Jeff Johnson295189b2012-06-20 16:38:30 -070011346 }
Leo Chang6f8870f2013-03-26 18:11:36 -070011347 if (DATA_RATE_11AC_MAX_MCS_7 == vhtMaxMcs)
Jeff Johnson295189b2012-06-20 16:38:30 -070011348 {
Leo Chang6f8870f2013-03-26 18:11:36 -070011349 maxMCSIdx = 7;
11350 }
11351 else if (DATA_RATE_11AC_MAX_MCS_8 == vhtMaxMcs)
11352 {
11353 maxMCSIdx = 8;
11354 }
11355 else if (DATA_RATE_11AC_MAX_MCS_9 == vhtMaxMcs)
11356 {
Gopichand Nakkala4c705372013-04-24 13:20:33 +053011357 //VHT20 is supporting 0~8
11358 if (rate_flags & eHAL_TX_RATE_VHT20)
11359 maxMCSIdx = 8;
11360 else
11361 maxMCSIdx = 9;
Leo Chang6f8870f2013-03-26 18:11:36 -070011362 }
Gopichand Nakkala4c705372013-04-24 13:20:33 +053011363
c_hpothu79aab322014-07-14 21:11:01 +053011364 if (0 != rssidx)/*check for scaled */
11365 {
11366 //get middle rate MCS index if rssi=1/2
11367 for (i=0; i <= maxMCSIdx; i++)
11368 {
11369 if (sinfo->signal <= rssiMcsTbl[mode][i])
11370 {
11371 maxMCSIdx = i;
11372 break;
11373 }
11374 }
11375 }
11376
Gopichand Nakkala4c705372013-04-24 13:20:33 +053011377 if (rate_flags & eHAL_TX_RATE_VHT80)
11378 {
11379 currentRate = supported_vht_mcs_rate[pAdapter->hdd_stats.ClassA_stat.mcs_index].supported_VHT80_rate[rateFlag];
11380 maxRate = supported_vht_mcs_rate[maxMCSIdx].supported_VHT80_rate[rateFlag];
11381 }
11382 else if (rate_flags & eHAL_TX_RATE_VHT40)
11383 {
11384 currentRate = supported_vht_mcs_rate[pAdapter->hdd_stats.ClassA_stat.mcs_index].supported_VHT40_rate[rateFlag];
11385 maxRate = supported_vht_mcs_rate[maxMCSIdx].supported_VHT40_rate[rateFlag];
11386 }
11387 else if (rate_flags & eHAL_TX_RATE_VHT20)
11388 {
11389 currentRate = supported_vht_mcs_rate[pAdapter->hdd_stats.ClassA_stat.mcs_index].supported_VHT20_rate[rateFlag];
11390 maxRate = supported_vht_mcs_rate[maxMCSIdx].supported_VHT20_rate[rateFlag];
11391 }
11392
Leo Chang6f8870f2013-03-26 18:11:36 -070011393 maxSpeedMCS = 1;
11394 if (currentRate > maxRate)
11395 {
11396 maxRate = currentRate;
11397 }
Gopichand Nakkala4c705372013-04-24 13:20:33 +053011398
Leo Chang6f8870f2013-03-26 18:11:36 -070011399 }
11400 else
11401#endif /* WLAN_FEATURE_11AC */
11402 {
11403 if (rate_flags & eHAL_TX_RATE_HT40)
11404 {
11405 rateFlag |= 1;
11406 }
11407 if (rate_flags & eHAL_TX_RATE_SGI)
11408 {
11409 rateFlag |= 2;
11410 }
11411
c_hpothu79aab322014-07-14 21:11:01 +053011412 if (rssidx == 1 || rssidx == 2)
11413 {
11414 //get middle rate MCS index if rssi=1/2
11415 for (i=0; i <= 7; i++)
11416 {
11417 if (sinfo->signal <= rssiMcsTbl[mode][i])
11418 {
11419 temp = i+1;
11420 break;
11421 }
11422 }
11423 }
11424 else
Leo Chang6f8870f2013-03-26 18:11:36 -070011425 {
11426 temp = sizeof(supported_mcs_rate) / sizeof(supported_mcs_rate[0]);
c_hpothu79aab322014-07-14 21:11:01 +053011427 }
11428
11429 for (i = 0; i < MCSLeng; i++)
11430 {
Leo Chang6f8870f2013-03-26 18:11:36 -070011431 for (j = 0; j < temp; j++)
11432 {
11433 if (supported_mcs_rate[j].beacon_rate_index == MCSRates[i])
11434 {
11435 currentRate = supported_mcs_rate[j].supported_rate[rateFlag];
11436 break;
11437 }
11438 }
11439 if ((j < temp) && (currentRate > maxRate))
11440 {
11441 maxRate = currentRate;
11442 maxSpeedMCS = 1;
11443 maxMCSIdx = supported_mcs_rate[j].beacon_rate_index;
11444 }
Jeff Johnson295189b2012-06-20 16:38:30 -070011445 }
11446 }
11447 }
11448
Gopichand Nakkala4c705372013-04-24 13:20:33 +053011449 else if (!(rate_flags & eHAL_TX_RATE_LEGACY))
11450 {
11451 maxRate = myRate;
11452 maxSpeedMCS = 1;
11453 maxMCSIdx = pAdapter->hdd_stats.ClassA_stat.mcs_index;
11454 }
Jeff Johnson295189b2012-06-20 16:38:30 -070011455 // make sure we report a value at least as big as our current rate
c_hpothu79aab322014-07-14 21:11:01 +053011456 if ((maxRate < myRate) || (0 == maxRate))
Jeff Johnson295189b2012-06-20 16:38:30 -070011457 {
11458 maxRate = myRate;
11459 if (rate_flags & eHAL_TX_RATE_LEGACY)
11460 {
11461 maxSpeedMCS = 0;
11462 }
11463 else
11464 {
11465 maxSpeedMCS = 1;
11466 maxMCSIdx = pAdapter->hdd_stats.ClassA_stat.mcs_index;
11467 }
11468 }
11469
Gopichand Nakkala4c705372013-04-24 13:20:33 +053011470 if (rate_flags & eHAL_TX_RATE_LEGACY)
Jeff Johnson295189b2012-06-20 16:38:30 -070011471 {
11472 sinfo->txrate.legacy = maxRate;
11473#ifdef LINKSPEED_DEBUG_ENABLED
11474 pr_info("Reporting legacy rate %d\n", sinfo->txrate.legacy);
11475#endif //LINKSPEED_DEBUG_ENABLED
11476 }
11477 else
11478 {
11479 sinfo->txrate.mcs = maxMCSIdx;
Leo Chang6f8870f2013-03-26 18:11:36 -070011480#ifdef WLAN_FEATURE_11AC
11481 sinfo->txrate.nss = 1;
11482 if (rate_flags & eHAL_TX_RATE_VHT80)
11483 {
11484 sinfo->txrate.flags |= RATE_INFO_FLAGS_VHT_MCS;
Gopichand Nakkala4c705372013-04-24 13:20:33 +053011485 sinfo->txrate.flags |= RATE_INFO_FLAGS_80_MHZ_WIDTH;
Leo Chang6f8870f2013-03-26 18:11:36 -070011486 }
Gopichand Nakkala4c705372013-04-24 13:20:33 +053011487 else if (rate_flags & eHAL_TX_RATE_VHT40)
Leo Chang6f8870f2013-03-26 18:11:36 -070011488 {
Gopichand Nakkala4c705372013-04-24 13:20:33 +053011489 sinfo->txrate.flags |= RATE_INFO_FLAGS_VHT_MCS;
11490 sinfo->txrate.flags |= RATE_INFO_FLAGS_40_MHZ_WIDTH;
11491 }
11492 else if (rate_flags & eHAL_TX_RATE_VHT20)
11493 {
11494 sinfo->txrate.flags |= RATE_INFO_FLAGS_VHT_MCS;
11495 }
11496#endif /* WLAN_FEATURE_11AC */
11497 if (rate_flags & (eHAL_TX_RATE_HT20 | eHAL_TX_RATE_HT40))
11498 {
11499 sinfo->txrate.flags |= RATE_INFO_FLAGS_MCS;
11500 if (rate_flags & eHAL_TX_RATE_HT40)
11501 {
11502 sinfo->txrate.flags |= RATE_INFO_FLAGS_40_MHZ_WIDTH;
11503 }
Leo Chang6f8870f2013-03-26 18:11:36 -070011504 }
Jeff Johnson295189b2012-06-20 16:38:30 -070011505 if (rate_flags & eHAL_TX_RATE_SGI)
11506 {
11507 sinfo->txrate.flags |= RATE_INFO_FLAGS_SHORT_GI;
11508 }
Gopichand Nakkala4c705372013-04-24 13:20:33 +053011509
Jeff Johnson295189b2012-06-20 16:38:30 -070011510#ifdef LINKSPEED_DEBUG_ENABLED
11511 pr_info("Reporting MCS rate %d flags %x\n",
11512 sinfo->txrate.mcs,
11513 sinfo->txrate.flags );
11514#endif //LINKSPEED_DEBUG_ENABLED
11515 }
11516 }
11517 else
11518 {
11519 // report current rate instead of max rate
11520
11521 if (rate_flags & eHAL_TX_RATE_LEGACY)
11522 {
11523 //provide to the UI in units of 100kbps
11524 sinfo->txrate.legacy = myRate;
11525#ifdef LINKSPEED_DEBUG_ENABLED
11526 pr_info("Reporting actual legacy rate %d\n", sinfo->txrate.legacy);
11527#endif //LINKSPEED_DEBUG_ENABLED
11528 }
11529 else
11530 {
11531 //must be MCS
11532 sinfo->txrate.mcs = pAdapter->hdd_stats.ClassA_stat.mcs_index;
Leo Chang6f8870f2013-03-26 18:11:36 -070011533#ifdef WLAN_FEATURE_11AC
11534 sinfo->txrate.nss = 1;
11535 if (rate_flags & eHAL_TX_RATE_VHT80)
11536 {
11537 sinfo->txrate.flags |= RATE_INFO_FLAGS_VHT_MCS;
11538 }
11539 else
11540#endif /* WLAN_FEATURE_11AC */
11541 {
11542 sinfo->txrate.flags |= RATE_INFO_FLAGS_MCS;
11543 }
Jeff Johnson295189b2012-06-20 16:38:30 -070011544 if (rate_flags & eHAL_TX_RATE_SGI)
11545 {
11546 sinfo->txrate.flags |= RATE_INFO_FLAGS_SHORT_GI;
11547 }
11548 if (rate_flags & eHAL_TX_RATE_HT40)
11549 {
11550 sinfo->txrate.flags |= RATE_INFO_FLAGS_40_MHZ_WIDTH;
11551 }
Leo Chang6f8870f2013-03-26 18:11:36 -070011552#ifdef WLAN_FEATURE_11AC
11553 else if (rate_flags & eHAL_TX_RATE_VHT80)
11554 {
11555 sinfo->txrate.flags |= RATE_INFO_FLAGS_80_MHZ_WIDTH;
11556 }
11557#endif /* WLAN_FEATURE_11AC */
Jeff Johnson295189b2012-06-20 16:38:30 -070011558#ifdef LINKSPEED_DEBUG_ENABLED
11559 pr_info("Reporting actual MCS rate %d flags %x\n",
11560 sinfo->txrate.mcs,
11561 sinfo->txrate.flags );
11562#endif //LINKSPEED_DEBUG_ENABLED
11563 }
11564 }
11565 sinfo->filled |= STATION_INFO_TX_BITRATE;
11566
Madan Mohan Koyyalamudi4d4d2812012-09-24 14:08:29 -070011567 sinfo->tx_packets =
11568 pAdapter->hdd_stats.summary_stat.tx_frm_cnt[0] +
11569 pAdapter->hdd_stats.summary_stat.tx_frm_cnt[1] +
11570 pAdapter->hdd_stats.summary_stat.tx_frm_cnt[2] +
11571 pAdapter->hdd_stats.summary_stat.tx_frm_cnt[3];
11572
11573 sinfo->tx_retries =
11574 pAdapter->hdd_stats.summary_stat.retry_cnt[0] +
11575 pAdapter->hdd_stats.summary_stat.retry_cnt[1] +
11576 pAdapter->hdd_stats.summary_stat.retry_cnt[2] +
11577 pAdapter->hdd_stats.summary_stat.retry_cnt[3];
11578
11579 sinfo->tx_failed =
11580 pAdapter->hdd_stats.summary_stat.fail_cnt[0] +
11581 pAdapter->hdd_stats.summary_stat.fail_cnt[1] +
11582 pAdapter->hdd_stats.summary_stat.fail_cnt[2] +
11583 pAdapter->hdd_stats.summary_stat.fail_cnt[3];
11584
11585 sinfo->filled |=
11586 STATION_INFO_TX_PACKETS |
11587 STATION_INFO_TX_RETRIES |
11588 STATION_INFO_TX_FAILED;
11589
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053011590 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
11591 TRACE_CODE_HDD_CFG80211_GET_STA,
11592 pAdapter->sessionId, maxRate));
Madan Mohan Koyyalamudi4d4d2812012-09-24 14:08:29 -070011593 EXIT();
11594 return 0;
Jeff Johnson295189b2012-06-20 16:38:30 -070011595}
11596
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053011597static int wlan_hdd_cfg80211_get_station(struct wiphy *wiphy, struct net_device *dev,
11598 u8* mac, struct station_info *sinfo)
11599{
11600 int ret;
11601
11602 vos_ssr_protect(__func__);
11603 ret = __wlan_hdd_cfg80211_get_station(wiphy, dev, mac, sinfo);
11604 vos_ssr_unprotect(__func__);
11605
11606 return ret;
11607}
11608
11609static int __wlan_hdd_cfg80211_set_power_mgmt(struct wiphy *wiphy,
Sameer Thalappilc9f26e92013-06-07 10:11:06 -070011610 struct net_device *dev, bool mode, int timeout)
Jeff Johnson295189b2012-06-20 16:38:30 -070011611{
11612 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
Gopichand Nakkala20c4c042013-04-19 22:08:55 +053011613 hdd_context_t *pHddCtx;
Jeff Johnson295189b2012-06-20 16:38:30 -070011614 VOS_STATUS vos_status;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053011615 int status;
Jeff Johnson295189b2012-06-20 16:38:30 -070011616
Jeff Johnsone7245742012-09-05 17:12:55 -070011617 ENTER();
11618
Jeff Johnson295189b2012-06-20 16:38:30 -070011619 if (NULL == pAdapter)
11620 {
Arif Hussain6d2a3322013-11-17 19:50:10 -080011621 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Adapter is NULL", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -070011622 return -ENODEV;
11623 }
11624
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053011625 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
11626 TRACE_CODE_HDD_CFG80211_SET_POWER_MGMT,
11627 pAdapter->sessionId, timeout));
11628
Gopichand Nakkala20c4c042013-04-19 22:08:55 +053011629 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053011630 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkala20c4c042013-04-19 22:08:55 +053011631
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053011632 if (0 != status)
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011633 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053011634 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
11635 "%s: HDD context is not valid", __func__);
11636 return status;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011637 }
11638
Gopichand Nakkala20c4c042013-04-19 22:08:55 +053011639 if ((DRIVER_POWER_MODE_AUTO == !mode) &&
11640 (TRUE == pHddCtx->hdd_wlan_suspended) &&
11641 (pHddCtx->cfg_ini->fhostArpOffload) &&
11642 (eConnectionState_Associated ==
11643 (WLAN_HDD_GET_STATION_CTX_PTR(pAdapter))->conn_info.connState))
11644 {
Amar Singhald53568e2013-09-26 11:03:45 -070011645
11646 hddLog(VOS_TRACE_LEVEL_INFO,
11647 "offload: in cfg80211_set_power_mgmt, calling arp offload");
Gopichand Nakkalab03e8082013-05-30 18:09:25 +053011648 vos_status = hdd_conf_arp_offload(pAdapter, TRUE);
Gopichand Nakkala20c4c042013-04-19 22:08:55 +053011649 if (!VOS_IS_STATUS_SUCCESS(vos_status))
11650 {
11651 hddLog(VOS_TRACE_LEVEL_INFO,
Arif Hussain6d2a3322013-11-17 19:50:10 -080011652 "%s:Failed to enable ARPOFFLOAD Feature %d",
Gopichand Nakkala20c4c042013-04-19 22:08:55 +053011653 __func__, vos_status);
11654 }
11655 }
11656
Jeff Johnson295189b2012-06-20 16:38:30 -070011657 /**The get power cmd from the supplicant gets updated by the nl only
11658 *on successful execution of the function call
11659 *we are oppositely mapped w.r.t mode in the driver
11660 **/
11661 vos_status = wlan_hdd_enter_bmps(pAdapter, !mode);
11662
Jeff Johnsone7245742012-09-05 17:12:55 -070011663 EXIT();
Jeff Johnson295189b2012-06-20 16:38:30 -070011664 if (VOS_STATUS_E_FAILURE == vos_status)
11665 {
c_hpothu6ff1c3c2013-10-01 19:01:57 +053011666 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
11667 "%s: failed to enter bmps mode", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -070011668 return -EINVAL;
11669 }
11670 return 0;
11671}
11672
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053011673static int wlan_hdd_cfg80211_set_power_mgmt(struct wiphy *wiphy,
11674 struct net_device *dev, bool mode, int timeout)
11675{
11676 int ret;
Jeff Johnson295189b2012-06-20 16:38:30 -070011677
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053011678 vos_ssr_protect(__func__);
11679 ret = __wlan_hdd_cfg80211_set_power_mgmt(wiphy, dev, mode, timeout);
11680 vos_ssr_unprotect(__func__);
11681
11682 return ret;
11683}
Jeff Johnson295189b2012-06-20 16:38:30 -070011684#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
11685static int wlan_hdd_set_default_mgmt_key(struct wiphy *wiphy,
11686 struct net_device *netdev,
11687 u8 key_index)
11688{
Jeff Johnsone7245742012-09-05 17:12:55 -070011689 ENTER();
Jeff Johnson295189b2012-06-20 16:38:30 -070011690 return 0;
11691}
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011692#endif //LINUX_VERSION_CODE
Jeff Johnson295189b2012-06-20 16:38:30 -070011693
11694#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,4,0))
11695static int wlan_hdd_set_txq_params(struct wiphy *wiphy,
11696 struct net_device *dev,
11697 struct ieee80211_txq_params *params)
11698{
Jeff Johnsone7245742012-09-05 17:12:55 -070011699 ENTER();
Jeff Johnson295189b2012-06-20 16:38:30 -070011700 return 0;
11701}
11702#elif (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
11703static int wlan_hdd_set_txq_params(struct wiphy *wiphy,
11704 struct ieee80211_txq_params *params)
11705{
Jeff Johnsone7245742012-09-05 17:12:55 -070011706 ENTER();
Jeff Johnson295189b2012-06-20 16:38:30 -070011707 return 0;
11708}
11709#endif //LINUX_VERSION_CODE
11710
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053011711static int __wlan_hdd_cfg80211_del_station(struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -070011712 struct net_device *dev, u8 *mac)
11713{
11714 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053011715 hdd_context_t *pHddCtx;
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -080011716 VOS_STATUS vos_status;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053011717 int status;
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -080011718 v_U8_t staId;
Jeff Johnson295189b2012-06-20 16:38:30 -070011719
Jeff Johnsone7245742012-09-05 17:12:55 -070011720 ENTER();
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053011721
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053011722 if ( NULL == pAdapter )
Jeff Johnson295189b2012-06-20 16:38:30 -070011723 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053011724 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Invalid Adapter" ,__func__);
Jeff Johnson295189b2012-06-20 16:38:30 -070011725 return -EINVAL;
11726 }
11727
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053011728 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
11729 TRACE_CODE_HDD_CFG80211_DEL_STA,
11730 pAdapter->sessionId, pAdapter->device_mode));
11731
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053011732 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
11733 status = wlan_hdd_validate_context(pHddCtx);
Jeff Johnson295189b2012-06-20 16:38:30 -070011734
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053011735 if (0 != status)
Jeff Johnson04dd8a82012-06-29 20:41:40 -070011736 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053011737 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
11738 "%s: HDD context is not valid", __func__);
11739 return status;
Jeff Johnson04dd8a82012-06-29 20:41:40 -070011740 }
11741
Jeff Johnson295189b2012-06-20 16:38:30 -070011742 if ( (WLAN_HDD_SOFTAP == pAdapter->device_mode)
Jeff Johnson295189b2012-06-20 16:38:30 -070011743 || (WLAN_HDD_P2P_GO == pAdapter->device_mode)
Jeff Johnson295189b2012-06-20 16:38:30 -070011744 )
11745 {
11746 if( NULL == mac )
11747 {
11748 v_U16_t i;
11749 for(i = 0; i < WLAN_MAX_STA_COUNT; i++)
11750 {
Rajesh Chauhan18488fc2013-08-22 10:15:03 -070011751 if ((pAdapter->aStaInfo[i].isUsed) &&
11752 (!pAdapter->aStaInfo[i].isDeauthInProgress))
Jeff Johnson295189b2012-06-20 16:38:30 -070011753 {
11754 u8 *macAddr = pAdapter->aStaInfo[i].macAddrSTA.bytes;
11755 hddLog(VOS_TRACE_LEVEL_INFO,
Arif Hussain24bafea2013-11-15 15:10:03 -080011756 "%s: Delete STA with MAC::"
11757 MAC_ADDRESS_STR,
11758 __func__, MAC_ADDR_ARRAY(macAddr));
Rajesh Chauhan18488fc2013-08-22 10:15:03 -070011759 vos_status = hdd_softap_sta_deauth(pAdapter, macAddr);
11760 if (VOS_IS_STATUS_SUCCESS(vos_status))
11761 pAdapter->aStaInfo[i].isDeauthInProgress = TRUE;
Jeff Johnson295189b2012-06-20 16:38:30 -070011762 }
11763 }
11764 }
11765 else
11766 {
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -080011767
11768 vos_status = hdd_softap_GetStaId(pAdapter,(v_MACADDR_t *)mac, &staId);
11769 if (!VOS_IS_STATUS_SUCCESS(vos_status))
11770 {
11771 hddLog(VOS_TRACE_LEVEL_INFO,
Arif Hussain24bafea2013-11-15 15:10:03 -080011772 "%s: Skip this DEL STA as this is not used::"
11773 MAC_ADDRESS_STR,
11774 __func__, MAC_ADDR_ARRAY(mac));
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -080011775 return -ENOENT;
11776 }
11777
11778 if( pAdapter->aStaInfo[staId].isDeauthInProgress == TRUE)
11779 {
11780 hddLog(VOS_TRACE_LEVEL_INFO,
Arif Hussain24bafea2013-11-15 15:10:03 -080011781 "%s: Skip this DEL STA as deauth is in progress::"
11782 MAC_ADDRESS_STR,
11783 __func__, MAC_ADDR_ARRAY(mac));
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -080011784 return -ENOENT;
11785 }
11786
11787 pAdapter->aStaInfo[staId].isDeauthInProgress = TRUE;
11788
Jeff Johnson295189b2012-06-20 16:38:30 -070011789 hddLog(VOS_TRACE_LEVEL_INFO,
11790 "%s: Delete STA with MAC::"
Arif Hussain24bafea2013-11-15 15:10:03 -080011791 MAC_ADDRESS_STR,
Jeff Johnson295189b2012-06-20 16:38:30 -070011792 __func__,
Arif Hussain24bafea2013-11-15 15:10:03 -080011793 MAC_ADDR_ARRAY(mac));
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -080011794
11795 vos_status = hdd_softap_sta_deauth(pAdapter, mac);
11796 if (!VOS_IS_STATUS_SUCCESS(vos_status))
11797 {
11798 pAdapter->aStaInfo[staId].isDeauthInProgress = FALSE;
11799 hddLog(VOS_TRACE_LEVEL_INFO,
11800 "%s: STA removal failed for ::"
Arif Hussain24bafea2013-11-15 15:10:03 -080011801 MAC_ADDRESS_STR,
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -080011802 __func__,
Arif Hussain24bafea2013-11-15 15:10:03 -080011803 MAC_ADDR_ARRAY(mac));
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -080011804 return -ENOENT;
11805 }
11806
Jeff Johnson295189b2012-06-20 16:38:30 -070011807 }
11808 }
11809
11810 EXIT();
11811
11812 return 0;
11813}
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053011814static int wlan_hdd_cfg80211_del_station(struct wiphy *wiphy,
11815 struct net_device *dev, u8 *mac)
11816{
11817 int ret;
Jeff Johnson295189b2012-06-20 16:38:30 -070011818
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053011819 vos_ssr_protect(__func__);
11820 ret = __wlan_hdd_cfg80211_del_station(wiphy, dev, mac);
11821 vos_ssr_unprotect(__func__);
11822
11823 return ret;
11824}
11825
11826static int __wlan_hdd_cfg80211_add_station(struct wiphy *wiphy,
Hoonki Lee11f7dda2013-02-14 16:55:44 -080011827 struct net_device *dev, u8 *mac, struct station_parameters *params)
11828{
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053011829 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
Gopichand Nakkalab977a972013-02-18 19:15:09 -080011830 int status = -EPERM;
Hoonki Lee11f7dda2013-02-14 16:55:44 -080011831#ifdef FEATURE_WLAN_TDLS
11832 u32 mask, set;
Hoonki Lee11f7dda2013-02-14 16:55:44 -080011833 ENTER();
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053011834
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053011835 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
11836 TRACE_CODE_HDD_CFG80211_ADD_STA,
11837 pAdapter->sessionId, params->listen_interval));
Mohit Khanna698ba2a2012-12-04 15:08:18 -080011838 mask = params->sta_flags_mask;
11839
11840 set = params->sta_flags_set;
11841
Gopichand Nakkalac87400e2013-03-13 18:51:00 -070011842#ifdef WLAN_FEATURE_TDLS_DEBUG
11843 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
11844 "%s: mask 0x%x set 0x%x " MAC_ADDRESS_STR,
11845 __func__, mask, set, MAC_ADDR_ARRAY(mac));
11846#endif
Mohit Khanna698ba2a2012-12-04 15:08:18 -080011847
11848 if (mask & BIT(NL80211_STA_FLAG_TDLS_PEER)) {
11849 if (set & BIT(NL80211_STA_FLAG_TDLS_PEER)) {
Gopichand Nakkala681989c2013-03-06 22:27:48 -080011850 status = wlan_hdd_tdls_add_station(wiphy, dev, mac, 0, NULL);
Mohit Khanna698ba2a2012-12-04 15:08:18 -080011851 }
11852 }
11853#endif
Gopichand Nakkalab977a972013-02-18 19:15:09 -080011854 return status;
Jeff Johnson295189b2012-06-20 16:38:30 -070011855}
11856
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053011857static int wlan_hdd_cfg80211_add_station(struct wiphy *wiphy,
11858 struct net_device *dev, u8 *mac, struct station_parameters *params)
11859{
11860 int ret;
Jeff Johnson04dd8a82012-06-29 20:41:40 -070011861
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053011862 vos_ssr_protect(__func__);
11863 ret = __wlan_hdd_cfg80211_add_station(wiphy, dev, mac, params);
11864 vos_ssr_unprotect(__func__);
11865
11866 return ret;
11867}
Jeff Johnson04dd8a82012-06-29 20:41:40 -070011868#ifdef FEATURE_WLAN_LFR
Wilson Yang6507c4e2013-10-01 20:11:19 -070011869
Mahesh A Saptasagarf7418d72014-06-02 14:48:54 +053011870static int __wlan_hdd_cfg80211_set_pmksa(struct wiphy *wiphy, struct net_device *dev,
Jeff Johnsond13512a2012-07-17 11:42:19 -070011871 struct cfg80211_pmksa *pmksa)
Jeff Johnson04dd8a82012-06-29 20:41:40 -070011872{
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011873 tANI_U32 j=0;
Jeff Johnson04dd8a82012-06-29 20:41:40 -070011874 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
Agarwal Ashish3da95242014-05-21 14:57:17 +053011875 hdd_station_ctx_t *pHddStaCtx;
Jeff Johnson04dd8a82012-06-29 20:41:40 -070011876 tHalHandle halHandle;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011877 eHalStatus result;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053011878 int status;
Jeff Johnson04dd8a82012-06-29 20:41:40 -070011879 tANI_U8 BSSIDMatched = 0;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053011880 hdd_context_t *pHddCtx;
Jeff Johnson0299d0a2013-10-30 12:37:43 -070011881 hddLog(VOS_TRACE_LEVEL_DEBUG, "%s: set PMKSA for " MAC_ADDRESS_STR,
11882 __func__, MAC_ADDR_ARRAY(pmksa->bssid));
Jeff Johnsone7245742012-09-05 17:12:55 -070011883
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011884 // Validate pAdapter
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053011885 if ( NULL == pAdapter )
Jeff Johnson04dd8a82012-06-29 20:41:40 -070011886 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053011887 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Invalid Adapter" ,__func__);
Jeff Johnson04dd8a82012-06-29 20:41:40 -070011888 return -EINVAL;
11889 }
11890
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053011891 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
11892 status = wlan_hdd_validate_context(pHddCtx);
Jeff Johnson04dd8a82012-06-29 20:41:40 -070011893
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053011894 if (0 != status)
Jeff Johnson04dd8a82012-06-29 20:41:40 -070011895 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053011896 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
11897 "%s: HDD context is not valid", __func__);
11898 return status;
Jeff Johnson04dd8a82012-06-29 20:41:40 -070011899 }
11900
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011901 // Retrieve halHandle
Jeff Johnson04dd8a82012-06-29 20:41:40 -070011902 halHandle = WLAN_HDD_GET_HAL_CTX(pAdapter);
Agarwal Ashish3da95242014-05-21 14:57:17 +053011903 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
Jeff Johnson04dd8a82012-06-29 20:41:40 -070011904
Agarwal Ashish3da95242014-05-21 14:57:17 +053011905 for (j = 0; j < pHddStaCtx->PMKIDCacheIndex; j++)
Jeff Johnson04dd8a82012-06-29 20:41:40 -070011906 {
Agarwal Ashish3da95242014-05-21 14:57:17 +053011907 if (vos_mem_compare(pHddStaCtx->PMKIDCache[j].BSSID,
Jeff Johnson04dd8a82012-06-29 20:41:40 -070011908 pmksa->bssid, WNI_CFG_BSSID_LEN))
11909 {
11910 /* BSSID matched previous entry. Overwrite it. */
11911 BSSIDMatched = 1;
Agarwal Ashish3da95242014-05-21 14:57:17 +053011912 vos_mem_copy(pHddStaCtx->PMKIDCache[j].BSSID,
Jeff Johnson04dd8a82012-06-29 20:41:40 -070011913 pmksa->bssid, WNI_CFG_BSSID_LEN);
Agarwal Ashish3da95242014-05-21 14:57:17 +053011914 vos_mem_copy(pHddStaCtx->PMKIDCache[j].PMKID,
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011915 pmksa->pmkid,
Jeff Johnson04dd8a82012-06-29 20:41:40 -070011916 CSR_RSN_PMKID_SIZE);
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011917 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: Reusing cache entry %d.",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -070011918 __func__, j );
Jeff Johnson04dd8a82012-06-29 20:41:40 -070011919 dump_bssid(pmksa->bssid);
11920 dump_pmkid(halHandle, pmksa->pmkid);
11921 break;
11922 }
11923 }
11924
Madan Mohan Koyyalamudic4b317d2012-10-18 19:43:08 -070011925 /* Check we compared all entries,if then take the first slot now */
Agarwal Ashish3da95242014-05-21 14:57:17 +053011926 if (j == MAX_PMKSAIDS_IN_CACHE) pHddStaCtx->PMKIDCacheIndex=0;
Madan Mohan Koyyalamudic4b317d2012-10-18 19:43:08 -070011927
Jeff Johnson04dd8a82012-06-29 20:41:40 -070011928 if (!BSSIDMatched)
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011929 {
11930 // Now, we DON'T have a BSSID match, so take a new entry in the cache.
Agarwal Ashish3da95242014-05-21 14:57:17 +053011931 vos_mem_copy(pHddStaCtx->PMKIDCache[pHddStaCtx->PMKIDCacheIndex].BSSID,
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011932 pmksa->bssid, ETHER_ADDR_LEN);
Agarwal Ashish3da95242014-05-21 14:57:17 +053011933 vos_mem_copy(pHddStaCtx->PMKIDCache[pHddStaCtx->PMKIDCacheIndex].PMKID,
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011934 pmksa->pmkid,
Jeff Johnson04dd8a82012-06-29 20:41:40 -070011935 CSR_RSN_PMKID_SIZE);
Agarwal Ashish3da95242014-05-21 14:57:17 +053011936 hddLog(VOS_TRACE_LEVEL_DEBUG, "%s: Adding a new cache entry %d.",
11937 __func__, pHddStaCtx->PMKIDCacheIndex );
Jeff Johnson04dd8a82012-06-29 20:41:40 -070011938 dump_bssid(pmksa->bssid);
11939 dump_pmkid(halHandle, pmksa->pmkid);
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011940 // Increment the HDD Local Cache index
Jeff Johnson04dd8a82012-06-29 20:41:40 -070011941 // The "i=0" doesn't work for the call to sme_RoamSetPMKIDCache() - LFR FIXME
Agarwal Ashish3da95242014-05-21 14:57:17 +053011942 if (pHddStaCtx->PMKIDCacheIndex <= (MAX_PMKSAIDS_IN_CACHE-1))
11943 pHddStaCtx->PMKIDCacheIndex++;
11944 else
11945 pHddStaCtx->PMKIDCacheIndex = 0;
Jeff Johnson04dd8a82012-06-29 20:41:40 -070011946 }
11947
11948
11949 // Calling csrRoamSetPMKIDCache to configure the PMKIDs into the cache
Agarwal Ashish3da95242014-05-21 14:57:17 +053011950 hddLog(VOS_TRACE_LEVEL_DEBUG, "%s: Calling csrRoamSetPMKIDCache with %d cache entries.",
11951 __func__, pHddStaCtx->PMKIDCacheIndex );
11952
Jeff Johnson04dd8a82012-06-29 20:41:40 -070011953 // Finally set the PMKSA ID Cache in CSR
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011954 result = sme_RoamSetPMKIDCache(halHandle,pAdapter->sessionId,
Agarwal Ashish3da95242014-05-21 14:57:17 +053011955 pHddStaCtx->PMKIDCache,
11956 pHddStaCtx->PMKIDCacheIndex);
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053011957 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
11958 TRACE_CODE_HDD_CFG80211_SET_PMKSA,
11959 pAdapter->sessionId, result));
Jeff Johnson04dd8a82012-06-29 20:41:40 -070011960 return 0;
11961}
11962
Mahesh A Saptasagarf7418d72014-06-02 14:48:54 +053011963static int wlan_hdd_cfg80211_set_pmksa(struct wiphy *wiphy, struct net_device *dev,
11964 struct cfg80211_pmksa *pmksa)
11965{
11966 int ret;
11967
11968 vos_ssr_protect(__func__);
11969 ret = __wlan_hdd_cfg80211_set_pmksa(wiphy, dev, pmksa);
11970 vos_ssr_unprotect(__func__);
11971
11972 return ret;
11973}
Jeff Johnson04dd8a82012-06-29 20:41:40 -070011974
Wilson Yang6507c4e2013-10-01 20:11:19 -070011975
Mahesh A Saptasagarf7418d72014-06-02 14:48:54 +053011976static int __wlan_hdd_cfg80211_del_pmksa(struct wiphy *wiphy, struct net_device *dev,
Wilson Yang6507c4e2013-10-01 20:11:19 -070011977 struct cfg80211_pmksa *pmksa)
Jeff Johnson04dd8a82012-06-29 20:41:40 -070011978{
Wilson Yang6507c4e2013-10-01 20:11:19 -070011979 tANI_U32 j=0;
11980 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
Agarwal Ashish3da95242014-05-21 14:57:17 +053011981 hdd_station_ctx_t *pHddStaCtx;
Wilson Yang6507c4e2013-10-01 20:11:19 -070011982 tHalHandle halHandle;
Wilson Yang6507c4e2013-10-01 20:11:19 -070011983 tANI_U8 BSSIDMatched = 0;
Wilson Yang6507c4e2013-10-01 20:11:19 -070011984 hdd_context_t *pHddCtx;
Wilson Yangef657d32014-01-15 19:19:23 -080011985 int status = 0;
Wilson Yang6507c4e2013-10-01 20:11:19 -070011986
Jeff Johnson0299d0a2013-10-30 12:37:43 -070011987 hddLog(VOS_TRACE_LEVEL_DEBUG, "%s: deleting PMKSA for " MAC_ADDRESS_STR,
11988 __func__, MAC_ADDR_ARRAY(pmksa->bssid));
Wilson Yang6507c4e2013-10-01 20:11:19 -070011989
11990 /* Validate pAdapter */
11991 if (NULL == pAdapter)
11992 {
11993 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Invalid Adapter" ,__func__);
11994 return -EINVAL;
11995 }
11996
11997 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
11998 status = wlan_hdd_validate_context(pHddCtx);
11999
12000 if (0 != status)
12001 {
12002 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
12003 "%s: HDD context is not valid", __func__);
12004 return status;
12005 }
12006
12007 /*Retrieve halHandle*/
12008 halHandle = WLAN_HDD_GET_HAL_CTX(pAdapter);
Agarwal Ashish3da95242014-05-21 14:57:17 +053012009 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
Wilson Yang6507c4e2013-10-01 20:11:19 -070012010
12011 /*in case index is 0,no entry to delete*/
Agarwal Ashish3da95242014-05-21 14:57:17 +053012012 if (0 == pHddStaCtx->PMKIDCacheIndex)
Wilson Yang6507c4e2013-10-01 20:11:19 -070012013 {
Agarwal Ashish3da95242014-05-21 14:57:17 +053012014 hddLog(VOS_TRACE_LEVEL_INFO, FL("No entries to flush"));
12015 return 0;
Wilson Yang6507c4e2013-10-01 20:11:19 -070012016 }
12017
12018 /*find the matching PMKSA entry from j=0 to (index-1),
12019 * and delete the matched one
12020 */
Agarwal Ashish3da95242014-05-21 14:57:17 +053012021 for (j = 0; j < pHddStaCtx->PMKIDCacheIndex; j++)
Wilson Yang6507c4e2013-10-01 20:11:19 -070012022 {
Agarwal Ashish3da95242014-05-21 14:57:17 +053012023 if (vos_mem_compare(pHddStaCtx->PMKIDCache[j].BSSID,
Wilson Yang6507c4e2013-10-01 20:11:19 -070012024 pmksa->bssid,
12025 WNI_CFG_BSSID_LEN))
12026 {
12027 /* BSSID matched entry */
12028 BSSIDMatched = 1;
Agarwal Ashish3da95242014-05-21 14:57:17 +053012029 if (j < pHddStaCtx->PMKIDCacheIndex-1)
Wilson Yang6507c4e2013-10-01 20:11:19 -070012030 {
12031 /*replace the matching entry with the last entry in HDD local cache*/
Agarwal Ashish3da95242014-05-21 14:57:17 +053012032 vos_mem_copy(pHddStaCtx->PMKIDCache[j].BSSID,
12033 pHddStaCtx->PMKIDCache[pHddStaCtx->PMKIDCacheIndex-1].BSSID,
12034 VOS_MAC_ADDR_SIZE);
12035 vos_mem_copy(pHddStaCtx->PMKIDCache[j].PMKID,
12036 pHddStaCtx->PMKIDCache[pHddStaCtx->PMKIDCacheIndex-1].PMKID,
12037 CSR_RSN_PMKID_SIZE);
12038 }
Wilson Yang6507c4e2013-10-01 20:11:19 -070012039
12040 /*clear the last entry in HDD cache ---[index-1]*/
Agarwal Ashish3da95242014-05-21 14:57:17 +053012041 vos_mem_zero(pHddStaCtx->PMKIDCache[pHddStaCtx->PMKIDCacheIndex-1].BSSID,
12042 VOS_MAC_ADDR_SIZE);
12043 vos_mem_zero(pHddStaCtx->PMKIDCache[pHddStaCtx->PMKIDCacheIndex-1].PMKID,
12044 CSR_RSN_PMKID_SIZE);
Wilson Yang6507c4e2013-10-01 20:11:19 -070012045 /*reduce the PMKID array index*/
Agarwal Ashish3da95242014-05-21 14:57:17 +053012046 pHddStaCtx->PMKIDCacheIndex--;
Wilson Yang6507c4e2013-10-01 20:11:19 -070012047 /*delete the last PMKID cache in CSR*/
Wilson Yangef657d32014-01-15 19:19:23 -080012048 if (eHAL_STATUS_SUCCESS !=
12049 sme_RoamDelPMKIDfromCache(halHandle, pAdapter->sessionId, pmksa->bssid))
Wilson Yang6507c4e2013-10-01 20:11:19 -070012050 {
12051 hddLog(VOS_TRACE_LEVEL_ERROR,"%s: cannot delete PMKSA %d CONTENT.",
Agarwal Ashish3da95242014-05-21 14:57:17 +053012052 __func__, pHddStaCtx->PMKIDCacheIndex);
Wilson Yangef657d32014-01-15 19:19:23 -080012053 status = -EINVAL;
Wilson Yang6507c4e2013-10-01 20:11:19 -070012054 }
12055
12056 dump_bssid(pmksa->bssid);
12057 dump_pmkid(halHandle,pmksa->pmkid);
12058
12059 break;
12060 }
12061 }
12062
12063 /* we compare all entries,but cannot find matching entry */
12064 if (j == MAX_PMKSAIDS_IN_CACHE && !BSSIDMatched)
12065 {
Jeff Johnson0299d0a2013-10-30 12:37:43 -070012066 hddLog(VOS_TRACE_LEVEL_FATAL,
12067 "%s: No such PMKSA entry existed " MAC_ADDRESS_STR,
12068 __func__, MAC_ADDR_ARRAY(pmksa->bssid));
Wilson Yang6507c4e2013-10-01 20:11:19 -070012069 dump_bssid(pmksa->bssid);
12070 dump_pmkid(halHandle, pmksa->pmkid);
12071 return -EINVAL;
12072 }
Wilson Yangef657d32014-01-15 19:19:23 -080012073 return status;
Jeff Johnson04dd8a82012-06-29 20:41:40 -070012074}
12075
Wilson Yang6507c4e2013-10-01 20:11:19 -070012076
Mahesh A Saptasagarf7418d72014-06-02 14:48:54 +053012077static int wlan_hdd_cfg80211_del_pmksa(struct wiphy *wiphy, struct net_device *dev,
12078 struct cfg80211_pmksa *pmksa)
12079{
12080 int ret;
Wilson Yang6507c4e2013-10-01 20:11:19 -070012081
Mahesh A Saptasagarf7418d72014-06-02 14:48:54 +053012082 vos_ssr_protect(__func__);
12083 ret = __wlan_hdd_cfg80211_del_pmksa(wiphy, dev, pmksa);
12084 vos_ssr_unprotect(__func__);
12085
12086 return ret;
12087
12088}
12089
12090static int __wlan_hdd_cfg80211_flush_pmksa(struct wiphy *wiphy, struct net_device *dev)
Jeff Johnson04dd8a82012-06-29 20:41:40 -070012091{
Wilson Yang6507c4e2013-10-01 20:11:19 -070012092 tANI_U32 j=0;
12093 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
Agarwal Ashish3da95242014-05-21 14:57:17 +053012094 hdd_station_ctx_t *pHddStaCtx;
Wilson Yang6507c4e2013-10-01 20:11:19 -070012095 tHalHandle halHandle;
12096 hdd_context_t *pHddCtx;
12097 tANI_U8 *pBSSId;
Wilson Yangef657d32014-01-15 19:19:23 -080012098 int status = 0;
Wilson Yang6507c4e2013-10-01 20:11:19 -070012099
12100 hddLog(VOS_TRACE_LEVEL_DEBUG, "%s: flushing PMKSA ",__func__);
12101
12102 /* Validate pAdapter */
12103 if (NULL == pAdapter)
12104 {
12105 hddLog(VOS_TRACE_LEVEL_ERROR,
12106 "%s: Invalid Adapter" ,__func__);
12107 return -EINVAL;
12108 }
12109
12110 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
12111 status = wlan_hdd_validate_context(pHddCtx);
12112
12113 if (0 != status)
12114 {
12115 hddLog(VOS_TRACE_LEVEL_ERROR,
12116 "%s: HDD context is not valid", __func__);
12117 return status;
12118 }
12119
12120 /*Retrieve halHandle*/
12121 halHandle = WLAN_HDD_GET_HAL_CTX(pAdapter);
Agarwal Ashish3da95242014-05-21 14:57:17 +053012122 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
Wilson Yang6507c4e2013-10-01 20:11:19 -070012123
12124 /*in case index is 0,no entry to delete*/
Agarwal Ashish3da95242014-05-21 14:57:17 +053012125 if (0 == pHddStaCtx->PMKIDCacheIndex)
Wilson Yang6507c4e2013-10-01 20:11:19 -070012126 {
Vinay Krishna Erannacbf75f42014-02-26 17:35:20 +053012127 hddLog(VOS_TRACE_LEVEL_ERROR, FL("No entries to flush"));
Agarwal Ashish3da95242014-05-21 14:57:17 +053012128 return 0;
Wilson Yang6507c4e2013-10-01 20:11:19 -070012129 }
12130
12131 /*delete all the PMKSA one by one */
Agarwal Ashish3da95242014-05-21 14:57:17 +053012132 for (j = 0; j < pHddStaCtx->PMKIDCacheIndex; j++)
Wilson Yang6507c4e2013-10-01 20:11:19 -070012133 {
Agarwal Ashish3da95242014-05-21 14:57:17 +053012134 pBSSId =(tANI_U8 *)(pHddStaCtx->PMKIDCache[j].BSSID);
Wilson Yang6507c4e2013-10-01 20:11:19 -070012135 /*delete the PMKID in CSR*/
Wilson Yangef657d32014-01-15 19:19:23 -080012136 if (eHAL_STATUS_SUCCESS !=
12137 sme_RoamDelPMKIDfromCache(halHandle, pAdapter->sessionId, pBSSId))
Wilson Yang6507c4e2013-10-01 20:11:19 -070012138 {
12139 hddLog(VOS_TRACE_LEVEL_ERROR ,"%s cannot flush PMKIDCache %d.",
12140 __func__,j);
Wilson Yangef657d32014-01-15 19:19:23 -080012141 status = -EINVAL;
Wilson Yang6507c4e2013-10-01 20:11:19 -070012142 }
Kiet Lam8d21d5b2013-10-31 17:18:29 +053012143 /*clear the entry in HDD cache 0--index-1 */
Agarwal Ashish3da95242014-05-21 14:57:17 +053012144 vos_mem_zero(pHddStaCtx->PMKIDCache[j].BSSID, VOS_MAC_ADDR_SIZE);
12145 vos_mem_zero(pHddStaCtx->PMKIDCache[j].PMKID, CSR_RSN_PMKID_SIZE);
12146 }
Wilson Yang6507c4e2013-10-01 20:11:19 -070012147
Agarwal Ashish3da95242014-05-21 14:57:17 +053012148 pHddStaCtx->PMKIDCacheIndex = 0;
Wilson Yangef657d32014-01-15 19:19:23 -080012149 return status;
Jeff Johnson04dd8a82012-06-29 20:41:40 -070012150}
Mahesh A Saptasagarf7418d72014-06-02 14:48:54 +053012151
12152static int wlan_hdd_cfg80211_flush_pmksa(struct wiphy *wiphy, struct net_device *dev)
12153{
12154 int ret;
12155
12156 vos_ssr_protect(__func__);
12157 ret = __wlan_hdd_cfg80211_flush_pmksa(wiphy, dev);
12158 vos_ssr_unprotect(__func__);
12159
12160 return ret;
12161}
Jeff Johnson04dd8a82012-06-29 20:41:40 -070012162#endif
12163
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070012164#if defined(WLAN_FEATURE_VOWIFI_11R) && defined(KERNEL_SUPPORT_11R_CFG80211)
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053012165static int __wlan_hdd_cfg80211_update_ft_ies(struct wiphy *wiphy,
12166 struct net_device *dev,
12167 struct cfg80211_update_ft_ies_params *ftie)
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070012168{
12169 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
12170 hdd_station_ctx_t *pHddStaCtx;
12171
12172 if (NULL == pAdapter)
12173 {
Arif Hussain6d2a3322013-11-17 19:50:10 -080012174 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Adapter is NULL", __func__);
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070012175 return -ENODEV;
12176 }
12177
12178 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
12179
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053012180 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
12181 TRACE_CODE_HDD_CFG80211_UPDATE_FT_IES,
12182 pAdapter->sessionId, pHddStaCtx->conn_info.connState));
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070012183 // Added for debug on reception of Re-assoc Req.
12184 if (eConnectionState_Associated != pHddStaCtx->conn_info.connState)
12185 {
Arif Hussain6d2a3322013-11-17 19:50:10 -080012186 hddLog(LOGE, FL("Called with Ie of length = %zu when not associated"),
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070012187 ftie->ie_len);
Arif Hussain6d2a3322013-11-17 19:50:10 -080012188 hddLog(LOGE, FL("Should be Re-assoc Req IEs"));
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070012189 }
12190
12191#ifdef WLAN_FEATURE_VOWIFI_11R_DEBUG
Arif Hussain6d2a3322013-11-17 19:50:10 -080012192 hddLog(LOGE, FL("%s called with Ie of length = %zu"), __func__,
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070012193 ftie->ie_len);
12194#endif
12195
12196 // Pass the received FT IEs to SME
Gopichand Nakkala356fb102013-03-06 12:34:04 +053012197 sme_SetFTIEs( WLAN_HDD_GET_HAL_CTX(pAdapter), pAdapter->sessionId,
12198 (const u8 *)ftie->ie,
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070012199 ftie->ie_len);
12200 return 0;
12201}
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053012202
12203static int wlan_hdd_cfg80211_update_ft_ies(struct wiphy *wiphy,
12204 struct net_device *dev,
12205 struct cfg80211_update_ft_ies_params *ftie)
12206{
12207 int ret;
12208
12209 vos_ssr_protect(__func__);
12210 ret = __wlan_hdd_cfg80211_update_ft_ies(wiphy, dev, ftie);
12211 vos_ssr_unprotect(__func__);
12212
12213 return ret;
12214}
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070012215#endif
Jeff Johnson04dd8a82012-06-29 20:41:40 -070012216
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053012217#ifdef FEATURE_WLAN_SCAN_PNO
12218
12219void hdd_cfg80211_sched_scan_done_callback(void *callbackContext,
12220 tSirPrefNetworkFoundInd *pPrefNetworkFoundInd)
12221{
12222 int ret;
12223 hdd_adapter_t* pAdapter = (hdd_adapter_t*)callbackContext;
12224 hdd_context_t *pHddCtx;
12225
Nirav Shah80830bf2013-12-31 16:35:12 +053012226 ENTER();
12227
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053012228 if (NULL == pAdapter)
12229 {
Agarwal Ashish971c2882013-10-30 20:11:12 +053012230 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053012231 "%s: HDD adapter is Null", __func__);
12232 return ;
12233 }
12234
12235 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
12236 if (NULL == pHddCtx)
12237 {
12238 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
12239 "%s: HDD context is Null!!!", __func__);
12240 return ;
12241 }
12242
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053012243 spin_lock(&pHddCtx->schedScan_lock);
12244 if (TRUE == pHddCtx->isWiphySuspended)
12245 {
12246 pHddCtx->isSchedScanUpdatePending = TRUE;
12247 spin_unlock(&pHddCtx->schedScan_lock);
12248 hddLog(VOS_TRACE_LEVEL_INFO,
12249 "%s: Update cfg80211 scan database after it resume", __func__);
12250 return ;
12251 }
12252 spin_unlock(&pHddCtx->schedScan_lock);
12253
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053012254 ret = wlan_hdd_cfg80211_update_bss(pHddCtx->wiphy, pAdapter);
12255
12256 if (0 > ret)
12257 hddLog(VOS_TRACE_LEVEL_INFO, "%s: NO SCAN result", __func__);
12258
12259 cfg80211_sched_scan_results(pHddCtx->wiphy);
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053012260 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
12261 "%s: cfg80211 scan result database updated", __func__);
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053012262}
12263
12264/*
Mahesh A Saptasagar0f7b0372013-11-28 23:23:07 +053012265 * FUNCTION: wlan_hdd_is_pno_allowed
Vinay Krishna Erannacbf75f42014-02-26 17:35:20 +053012266 * Disallow pno if any session is active
Mahesh A Saptasagar0f7b0372013-11-28 23:23:07 +053012267 */
12268static eHalStatus wlan_hdd_is_pno_allowed(hdd_adapter_t *pAdapter)
12269{
12270 hdd_adapter_list_node_t *pAdapterNode = NULL, *pNext = NULL;
12271 hdd_adapter_t *pTempAdapter = NULL;
Vinay Krishna Eranna23ffd182013-12-26 19:16:55 +053012272 hdd_station_ctx_t *pStaCtx;
Mahesh A Saptasagar0f7b0372013-11-28 23:23:07 +053012273 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
12274 int status = 0;
12275 status = hdd_get_front_adapter(pHddCtx, &pAdapterNode);
12276
Vinay Krishna Erannacbf75f42014-02-26 17:35:20 +053012277 /* The current firmware design does not allow PNO during any
12278 * active sessions. Hence, determine the active sessions
12279 * and return a failure.
12280 */
Mahesh A Saptasagar0f7b0372013-11-28 23:23:07 +053012281 while ((NULL != pAdapterNode) && (VOS_STATUS_SUCCESS == status))
12282 {
12283 pTempAdapter = pAdapterNode->pAdapter;
Vinay Krishna Eranna23ffd182013-12-26 19:16:55 +053012284 pStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pTempAdapter);
Mahesh A Saptasagar0f7b0372013-11-28 23:23:07 +053012285
Vinay Krishna Eranna23ffd182013-12-26 19:16:55 +053012286 if (((WLAN_HDD_INFRA_STATION == pTempAdapter->device_mode)
12287 && (eConnectionState_NotConnected != pStaCtx->conn_info.connState))
12288 || (WLAN_HDD_P2P_CLIENT == pTempAdapter->device_mode)
12289 || (WLAN_HDD_P2P_GO == pTempAdapter->device_mode)
12290 || (WLAN_HDD_SOFTAP == pTempAdapter->device_mode)
12291 )
Mahesh A Saptasagar0f7b0372013-11-28 23:23:07 +053012292 {
Vinay Krishna Eranna23ffd182013-12-26 19:16:55 +053012293 return eHAL_STATUS_FAILURE;
Mahesh A Saptasagar0f7b0372013-11-28 23:23:07 +053012294 }
12295 status = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
12296 pAdapterNode = pNext;
12297 }
Vinay Krishna Eranna23ffd182013-12-26 19:16:55 +053012298 return eHAL_STATUS_SUCCESS;
Mahesh A Saptasagar0f7b0372013-11-28 23:23:07 +053012299}
12300
Vinay Krishna Erannaf0e523b2014-03-01 21:00:16 +053012301void hdd_cfg80211_sched_scan_start_status_cb(void *callbackContext, VOS_STATUS status)
12302{
12303 hdd_adapter_t *pAdapter = callbackContext;
12304 hdd_context_t *pHddCtx;
12305
12306 if ((NULL == pAdapter) || (WLAN_HDD_ADAPTER_MAGIC != pAdapter->magic))
12307 {
12308 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
12309 FL("Invalid adapter or adapter has invalid magic"));
12310 return;
12311 }
12312
12313 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
12314 if (0 != wlan_hdd_validate_context(pHddCtx))
12315 {
12316 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
12317 FL("HDD context is not valid"));
12318 return;
12319 }
12320
12321 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
12322 FL("PNO enable response status = %d"), status);
12323
12324 pAdapter->pno_req_status = (status == VOS_STATUS_SUCCESS) ? 0 : -EBUSY;
12325 complete(&pAdapter->pno_comp_var);
12326}
12327
Mahesh A Saptasagar0f7b0372013-11-28 23:23:07 +053012328/*
Mahesh A Saptasagar6cc38562014-05-23 21:22:17 +053012329 * FUNCTION: __wlan_hdd_cfg80211_sched_scan_start
12330 * Function to enable PNO
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053012331 */
Mahesh A Saptasagar6cc38562014-05-23 21:22:17 +053012332static int __wlan_hdd_cfg80211_sched_scan_start(struct wiphy *wiphy,
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053012333 struct net_device *dev, struct cfg80211_sched_scan_request *request)
12334{
12335 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
12336 tpSirPNOScanReq pPnoRequest = NULL;
12337 hdd_context_t *pHddCtx;
12338 tHalHandle hHal;
Mahesh A Saptasagar7bd6ad42014-07-21 18:56:33 +053012339 v_U32_t i, indx, num_ch, tempInterval, j;
Sushant Kaushikd62d9782014-02-19 15:39:40 +053012340 u8 valid_ch[WNI_CFG_VALID_CHANNEL_LIST_LEN] = {0};
12341 u8 channels_allowed[WNI_CFG_VALID_CHANNEL_LIST_LEN] = {0};
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053012342 v_U32_t num_channels_allowed = WNI_CFG_VALID_CHANNEL_LIST_LEN;
12343 eHalStatus status = eHAL_STATUS_FAILURE;
Kamath Vinayakba5313f2013-08-22 15:52:39 +053012344 int ret = 0;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053012345
12346 if (NULL == pAdapter)
12347 {
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053012348 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053012349 "%s: HDD adapter is Null", __func__);
12350 return -ENODEV;
12351 }
12352
12353 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053012354 ret = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053012355
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053012356 if (0 != ret)
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053012357 {
Gopichand Nakkalac005b7c2013-05-14 16:04:14 +053012358 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
12359 "%s: HDD context is not valid", __func__);
Kamath Vinayakba5313f2013-08-22 15:52:39 +053012360 return -EINVAL;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053012361 }
12362
12363 hHal = WLAN_HDD_GET_HAL_CTX(pAdapter);
12364 if (NULL == hHal)
12365 {
12366 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
12367 "%s: HAL context is Null!!!", __func__);
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053012368 return -EINVAL;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053012369 }
Vinay Krishna Eranna23ffd182013-12-26 19:16:55 +053012370
Mahesh A Saptasagar2395ee62014-05-21 19:12:21 +053012371 ret = wlan_hdd_scan_abort(pAdapter);
Girish Gowli4bf7a632014-06-12 13:42:11 +053012372 if (ret < 0)
Mahesh A Saptasagar2395ee62014-05-21 19:12:21 +053012373 {
12374 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
12375 "%s: aborting the existing scan is unsuccessfull", __func__);
12376 return -EBUSY;
12377 }
12378
Vinay Krishna Eranna23ffd182013-12-26 19:16:55 +053012379 if (eHAL_STATUS_SUCCESS != wlan_hdd_is_pno_allowed(pAdapter))
Mahesh A Saptasagar0f7b0372013-11-28 23:23:07 +053012380 {
Vinay Krishna Erannacbf75f42014-02-26 17:35:20 +053012381 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_WARN,
Vinay Krishna Eranna23ffd182013-12-26 19:16:55 +053012382 FL("Cannot handle sched_scan"));
Mahesh A Saptasagar0f7b0372013-11-28 23:23:07 +053012383 return -EBUSY;
12384 }
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053012385
c_hpothu37f21312014-04-09 21:49:54 +053012386 if (TRUE == pHddCtx->isPnoEnable)
12387 {
12388 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_WARN,
12389 FL("already PNO is enabled"));
12390 return -EBUSY;
12391 }
12392 pHddCtx->isPnoEnable = TRUE;
12393
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053012394 pPnoRequest = (tpSirPNOScanReq) vos_mem_malloc(sizeof (tSirPNOScanReq));
12395 if (NULL == pPnoRequest)
12396 {
12397 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
12398 "%s: vos_mem_malloc failed", __func__);
c_hpothu37f21312014-04-09 21:49:54 +053012399 pHddCtx->isPnoEnable = FALSE;
Kamath Vinayakba5313f2013-08-22 15:52:39 +053012400 return -ENOMEM;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053012401 }
12402
Madan Mohan Koyyalamudic3f04352013-09-26 19:21:48 +053012403 memset(pPnoRequest, 0, sizeof (tSirPNOScanReq));
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053012404 pPnoRequest->enable = 1; /*Enable PNO */
12405 pPnoRequest->ucNetworksCount = request->n_match_sets;
12406
12407 if (( !pPnoRequest->ucNetworksCount ) ||
12408 ( pPnoRequest->ucNetworksCount > SIR_PNO_MAX_SUPP_NETWORKS ))
12409 {
12410 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Sushant Kaushik1e406c32014-05-09 15:57:52 +053012411 "%s: Network input is not correct %d Max Network supported is %d",
12412 __func__, pPnoRequest->ucNetworksCount,
12413 SIR_PNO_MAX_SUPP_NETWORKS);
Kamath Vinayakba5313f2013-08-22 15:52:39 +053012414 ret = -EINVAL;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053012415 goto error;
12416 }
12417
12418 if ( SIR_PNO_MAX_NETW_CHANNELS_EX < request->n_channels )
12419 {
12420 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Nirav Shah80830bf2013-12-31 16:35:12 +053012421 "%s: Incorrect number of channels %d",
12422 __func__, request->n_channels);
Kamath Vinayakba5313f2013-08-22 15:52:39 +053012423 ret = -EINVAL;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053012424 goto error;
12425 }
12426
12427 /* Framework provides one set of channels(all)
12428 * common for all saved profile */
12429 if (0 != ccmCfgGetStr(hHal, WNI_CFG_VALID_CHANNEL_LIST,
12430 channels_allowed, &num_channels_allowed))
12431 {
12432 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
12433 "%s: failed to get valid channel list", __func__);
Kamath Vinayakba5313f2013-08-22 15:52:39 +053012434 ret = -EINVAL;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053012435 goto error;
12436 }
12437 /* Checking each channel against allowed channel list */
12438 num_ch = 0;
Nirav Shah80830bf2013-12-31 16:35:12 +053012439 if (request->n_channels)
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053012440 {
Nirav Shah80830bf2013-12-31 16:35:12 +053012441 char chList [(request->n_channels*5)+1];
12442 int len;
12443 for (i = 0, len = 0; i < request->n_channels; i++)
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053012444 {
Nirav Shah80830bf2013-12-31 16:35:12 +053012445 for (indx = 0; indx < num_channels_allowed; indx++)
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053012446 {
Nirav Shah80830bf2013-12-31 16:35:12 +053012447 if (request->channels[i]->hw_value == channels_allowed[indx])
12448 {
12449 valid_ch[num_ch++] = request->channels[i]->hw_value;
12450 len += snprintf(chList+len, 5, "%d ",
12451 request->channels[i]->hw_value);
12452 break ;
12453 }
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053012454 }
12455 }
Nirav Shah80830bf2013-12-31 16:35:12 +053012456 hddLog(VOS_TRACE_LEVEL_INFO,"Channel-List: %s ", chList);
12457 }
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053012458
12459 /* Filling per profile params */
12460 for (i = 0; i < pPnoRequest->ucNetworksCount; i++)
12461 {
12462 pPnoRequest->aNetworks[i].ssId.length =
12463 request->match_sets[i].ssid.ssid_len;
12464
12465 if (( 0 == pPnoRequest->aNetworks[i].ssId.length ) ||
12466 ( pPnoRequest->aNetworks[i].ssId.length > 32 ) )
12467 {
12468 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Nirav Shah80830bf2013-12-31 16:35:12 +053012469 "%s: SSID Len %d is not correct for network %d",
12470 __func__, pPnoRequest->aNetworks[i].ssId.length, i);
Kamath Vinayakba5313f2013-08-22 15:52:39 +053012471 ret = -EINVAL;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053012472 goto error;
12473 }
12474
12475 memcpy(pPnoRequest->aNetworks[i].ssId.ssId,
12476 request->match_sets[i].ssid.ssid,
12477 request->match_sets[i].ssid.ssid_len);
Sushant Kaushik1e406c32014-05-09 15:57:52 +053012478 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
12479 "%s: SSID of network %d is %s ", __func__,
12480 i, pPnoRequest->aNetworks[i].ssId.ssId);
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053012481 pPnoRequest->aNetworks[i].authentication = 0; /*eAUTH_TYPE_ANY*/
12482 pPnoRequest->aNetworks[i].encryption = 0; /*eED_ANY*/
12483 pPnoRequest->aNetworks[i].bcastNetwType = 0; /*eBCAST_UNKNOWN*/
12484
12485 /*Copying list of valid channel into request */
12486 memcpy(pPnoRequest->aNetworks[i].aChannels, valid_ch, num_ch);
12487 pPnoRequest->aNetworks[i].ucChannelCount = num_ch;
12488
12489 pPnoRequest->aNetworks[i].rssiThreshold = 0; //Default value
12490 }
12491
Mahesh A Saptasagar7bd6ad42014-07-21 18:56:33 +053012492 for (i = 0; i < request->n_ssids; i++)
12493 {
12494 j = 0;
12495 while (j < pPnoRequest->ucNetworksCount)
12496 {
12497 if ((pPnoRequest->aNetworks[j].ssId.length ==
12498 request->ssids[i].ssid_len) &&
12499 (0 == memcmp(pPnoRequest->aNetworks[j].ssId.ssId,
12500 request->ssids[i].ssid,
12501 pPnoRequest->aNetworks[j].ssId.length)))
12502 {
12503 pPnoRequest->aNetworks[j].bcastNetwType = eBCAST_HIDDEN;
12504 break;
12505 }
12506 j++;
12507 }
12508 }
12509 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
12510 "Number of hidden networks being Configured = %d",
12511 request->n_ssids);
Madan Mohan Koyyalamudia7765d52013-09-18 16:49:56 +053012512 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Jeff Johnson59a121e2013-11-30 09:46:08 -080012513 "request->ie_len = %zu", request->ie_len);
Madan Mohan Koyyalamudia7765d52013-09-18 16:49:56 +053012514 if ((0 < request->ie_len) && (NULL != request->ie))
12515 {
12516 pPnoRequest->us24GProbeTemplateLen = request->ie_len;
12517 memcpy(&pPnoRequest->p24GProbeTemplate, request->ie,
12518 pPnoRequest->us24GProbeTemplateLen);
12519
12520 pPnoRequest->us5GProbeTemplateLen = request->ie_len;
12521 memcpy(&pPnoRequest->p5GProbeTemplate, request->ie,
12522 pPnoRequest->us5GProbeTemplateLen);
12523 }
12524
Madan Mohan Koyyalamudi1d16f462013-08-27 16:25:34 +053012525 /* Driver gets only one time interval which is hardcoded in
12526 * supplicant for 10000ms. Taking power consumption into account 6 timers
12527 * will be used, Timervalue is increased exponentially i.e 10,20,40,
12528 * 80,160,320 secs. And number of scan cycle for each timer
12529 * is configurable through INI param gPNOScanTimerRepeatValue.
12530 * If it is set to 0 only one timer will be used and PNO scan cycle
12531 * will be repeated after each interval specified by supplicant
12532 * till PNO is disabled.
12533 */
12534 if (0 == pHddCtx->cfg_ini->configPNOScanTimerRepeatValue)
12535 pPnoRequest->scanTimers.ucScanTimersCount = HDD_PNO_SCAN_TIMERS_SET_ONE;
12536 else
12537 pPnoRequest->scanTimers.ucScanTimersCount =
12538 HDD_PNO_SCAN_TIMERS_SET_MULTIPLE;
12539
12540 tempInterval = (request->interval)/1000;
12541 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
12542 "Base scan interval = %d PNOScanTimerRepeatValue = %d",
12543 tempInterval, pHddCtx->cfg_ini->configPNOScanTimerRepeatValue);
12544 for ( i = 0; i < pPnoRequest->scanTimers.ucScanTimersCount; i++)
12545 {
12546 pPnoRequest->scanTimers.aTimerValues[i].uTimerRepeat =
12547 pHddCtx->cfg_ini->configPNOScanTimerRepeatValue;
12548 pPnoRequest->scanTimers.aTimerValues[i].uTimerValue = tempInterval;
12549 tempInterval *= 2;
12550 }
12551 //Repeat last timer until pno disabled.
12552 pPnoRequest->scanTimers.aTimerValues[i-1].uTimerRepeat = 0;
12553
Madan Mohan Koyyalamudid206c7b2013-09-26 22:54:51 +053012554 pPnoRequest->modePNO = SIR_PNO_MODE_IMMEDIATE;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053012555
Vinay Krishna Erannaf0e523b2014-03-01 21:00:16 +053012556 INIT_COMPLETION(pAdapter->pno_comp_var);
12557 pPnoRequest->statusCallback = hdd_cfg80211_sched_scan_start_status_cb;
12558 pPnoRequest->callbackContext = pAdapter;
12559 pAdapter->pno_req_status = 0;
12560
Nirav Shah80830bf2013-12-31 16:35:12 +053012561 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
12562 "SessionId %d, enable %d, modePNO %d, ucScanTimersCount %d",
12563 pAdapter->sessionId, pPnoRequest->enable, pPnoRequest->modePNO,
12564 pPnoRequest->scanTimers.ucScanTimersCount);
12565
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053012566 status = sme_SetPreferredNetworkList(WLAN_HDD_GET_HAL_CTX(pAdapter),
12567 pPnoRequest, pAdapter->sessionId,
12568 hdd_cfg80211_sched_scan_done_callback, pAdapter);
12569 if (eHAL_STATUS_SUCCESS != status)
12570 {
12571 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Nirav Shah80830bf2013-12-31 16:35:12 +053012572 "%s: Failed to enable PNO", __func__);
Kamath Vinayakba5313f2013-08-22 15:52:39 +053012573 ret = -EINVAL;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053012574 goto error;
12575 }
12576
Vinay Krishna Erannaf0e523b2014-03-01 21:00:16 +053012577 ret = wait_for_completion_timeout(
12578 &pAdapter->pno_comp_var,
12579 msecs_to_jiffies(WLAN_WAIT_TIME_PNO));
12580 if (0 >= ret)
12581 {
12582 // Did not receive the response for PNO enable in time.
12583 // Assuming the PNO enable was success.
12584 // Returning error from here, because we timeout, results
12585 // in side effect of Wifi (Wifi Setting) not to work.
12586 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
12587 FL("Timed out waiting for PNO to be Enabled"));
12588 ret = 0;
12589 goto error;
12590 }
12591
c_hpothu3c986b22014-07-09 14:45:09 +053012592 vos_mem_free(pPnoRequest);
Vinay Krishna Erannaf0e523b2014-03-01 21:00:16 +053012593 ret = pAdapter->pno_req_status;
c_hpothu37f21312014-04-09 21:49:54 +053012594 return ret;
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053012595
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053012596error:
Vinay Krishna Erannaf0e523b2014-03-01 21:00:16 +053012597 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
12598 FL("PNO scanRequest offloaded ret = %d"), ret);
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053012599 vos_mem_free(pPnoRequest);
c_hpothu37f21312014-04-09 21:49:54 +053012600 pHddCtx->isPnoEnable = FALSE;
Kamath Vinayakba5313f2013-08-22 15:52:39 +053012601 return ret;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053012602}
12603
12604/*
Mahesh A Saptasagar6cc38562014-05-23 21:22:17 +053012605 * FUNCTION: wlan_hdd_cfg80211_sched_scan_start
12606 * NL interface to enable PNO
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053012607 */
Mahesh A Saptasagar6cc38562014-05-23 21:22:17 +053012608static int wlan_hdd_cfg80211_sched_scan_start(struct wiphy *wiphy,
12609 struct net_device *dev, struct cfg80211_sched_scan_request *request)
12610{
12611 int ret;
12612
12613 vos_ssr_protect(__func__);
12614 ret = __wlan_hdd_cfg80211_sched_scan_start(wiphy, dev, request);
12615 vos_ssr_unprotect(__func__);
12616
12617 return ret;
12618}
12619
12620/*
12621 * FUNCTION: __wlan_hdd_cfg80211_sched_scan_stop
12622 * Function to disable PNO
12623 */
12624static int __wlan_hdd_cfg80211_sched_scan_stop(struct wiphy *wiphy,
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053012625 struct net_device *dev)
12626{
12627 eHalStatus status = eHAL_STATUS_FAILURE;
12628 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
12629 hdd_context_t *pHddCtx;
12630 tHalHandle hHal;
12631 tpSirPNOScanReq pPnoRequest = NULL;
Kamath Vinayakba5313f2013-08-22 15:52:39 +053012632 int ret = 0;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053012633
12634 ENTER();
12635
12636 if (NULL == pAdapter)
12637 {
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053012638 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053012639 "%s: HDD adapter is Null", __func__);
12640 return -ENODEV;
12641 }
12642
12643 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053012644
Kamath Vinayakba5313f2013-08-22 15:52:39 +053012645 if (NULL == pHddCtx)
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053012646 {
Gopichand Nakkalac005b7c2013-05-14 16:04:14 +053012647 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Kamath Vinayakba5313f2013-08-22 15:52:39 +053012648 "%s: HDD context is Null", __func__);
12649 return -ENODEV;
12650 }
12651
12652 /* The return 0 is intentional when isLogpInProgress and
12653 * isLoadUnloadInProgress. We did observe a crash due to a return of
12654 * failure in sched_scan_stop , especially for a case where the unload
12655 * of the happens at the same time. The function __cfg80211_stop_sched_scan
12656 * was clearing rdev->sched_scan_req only when the sched_scan_stop returns
12657 * success. If it returns a failure , then its next invocation due to the
12658 * clean up of the second interface will have the dev pointer corresponding
12659 * to the first one leading to a crash.
12660 */
12661 if (pHddCtx->isLogpInProgress)
12662 {
12663 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
12664 "%s: LOGP in Progress. Ignore!!!", __func__);
12665 return ret;
12666 }
12667
Mihir Shete18156292014-03-11 15:38:30 +053012668 if (WLAN_HDD_IS_LOAD_UNLOAD_IN_PROGRESS(pHddCtx))
Kamath Vinayakba5313f2013-08-22 15:52:39 +053012669 {
12670 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
12671 "%s: Unloading/Loading in Progress. Ignore!!!", __func__);
12672 return ret;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053012673 }
12674
12675 hHal = WLAN_HDD_GET_HAL_CTX(pAdapter);
12676 if (NULL == hHal)
12677 {
12678 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
12679 "%s: HAL context is Null!!!", __func__);
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053012680 return -EINVAL;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053012681 }
12682
12683 pPnoRequest = (tpSirPNOScanReq) vos_mem_malloc(sizeof (tSirPNOScanReq));
12684 if (NULL == pPnoRequest)
12685 {
12686 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
12687 "%s: vos_mem_malloc failed", __func__);
Kamath Vinayakba5313f2013-08-22 15:52:39 +053012688 return -ENOMEM;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053012689 }
12690
12691 memset(pPnoRequest, 0, sizeof (tSirPNOScanReq));
12692 pPnoRequest->enable = 0; /* Disable PNO */
12693 pPnoRequest->ucNetworksCount = 0;
12694
12695 status = sme_SetPreferredNetworkList(hHal, pPnoRequest,
12696 pAdapter->sessionId,
12697 NULL, pAdapter);
12698 if (eHAL_STATUS_SUCCESS != status)
12699 {
12700 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
12701 "Failed to disabled PNO");
Kamath Vinayakba5313f2013-08-22 15:52:39 +053012702 ret = -EINVAL;
Vinay Krishna Erannaf0e523b2014-03-01 21:00:16 +053012703 goto error;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053012704 }
c_hpothu37f21312014-04-09 21:49:54 +053012705 pHddCtx->isPnoEnable = FALSE;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053012706
Vinay Krishna Erannaf0e523b2014-03-01 21:00:16 +053012707error:
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053012708 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Vinay Krishna Erannaf0e523b2014-03-01 21:00:16 +053012709 FL("PNO scan disabled ret = %d"), ret);
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053012710 vos_mem_free(pPnoRequest);
12711
12712 EXIT();
Kamath Vinayakba5313f2013-08-22 15:52:39 +053012713 return ret;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053012714}
12715
Mahesh A Saptasagar6cc38562014-05-23 21:22:17 +053012716/*
12717 * FUNCTION: wlan_hdd_cfg80211_sched_scan_stop
12718 * NL interface to disable PNO
12719 */
12720static int wlan_hdd_cfg80211_sched_scan_stop(struct wiphy *wiphy,
12721 struct net_device *dev)
12722{
12723 int ret;
12724
12725 vos_ssr_protect(__func__);
12726 ret = __wlan_hdd_cfg80211_sched_scan_stop(wiphy, dev);
12727 vos_ssr_unprotect(__func__);
12728
12729 return ret;
12730}
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053012731#endif /*FEATURE_WLAN_SCAN_PNO*/
12732
12733
Mohit Khanna698ba2a2012-12-04 15:08:18 -080012734#ifdef FEATURE_WLAN_TDLS
Sunil Dutt Undekarieacac6f2014-03-21 14:08:53 +053012735#if TDLS_MGMT_VERSION2
Mohit Khanna698ba2a2012-12-04 15:08:18 -080012736static int wlan_hdd_cfg80211_tdls_mgmt(struct wiphy *wiphy, struct net_device *dev,
12737 u8 *peer, u8 action_code, u8 dialog_token,
Sunil Dutt Undekarieacac6f2014-03-21 14:08:53 +053012738 u16 status_code, u32 peer_capability, const u8 *buf, size_t len)
12739#else
12740static int wlan_hdd_cfg80211_tdls_mgmt(struct wiphy *wiphy, struct net_device *dev,
12741 u8 *peer, u8 action_code, u8 dialog_token,
12742 u16 status_code, const u8 *buf, size_t len)
12743#endif
Mohit Khanna698ba2a2012-12-04 15:08:18 -080012744{
12745
12746 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
12747 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
Mohit Khanna698ba2a2012-12-04 15:08:18 -080012748 u8 peerMac[6];
12749 VOS_STATUS status;
Gopichand Nakkala05922802013-03-14 12:23:19 -070012750 int max_sta_failed = 0;
Hoonki Leea34dd892013-02-05 22:56:02 -080012751 int responder;
Hoonki Leed37cbb32013-04-20 00:31:14 -070012752 long rc;
Sunil Dutt Undekarieacac6f2014-03-21 14:08:53 +053012753#if !(TDLS_MGMT_VERSION2)
12754 u32 peer_capability = 0;
12755#endif
Rajesh Chauhana34c6e62014-03-25 16:37:58 +053012756 tANI_U16 numCurrTdlsPeers;
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053012757
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053012758 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
12759 TRACE_CODE_HDD_CFG80211_TDLS_MGMT,
12760 pAdapter->sessionId, action_code));
Hoonki Lee11f7dda2013-02-14 16:55:44 -080012761 if (NULL == pHddCtx || NULL == pHddCtx->cfg_ini)
Mohit Khanna698ba2a2012-12-04 15:08:18 -080012762 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012763 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Mohit Khanna698ba2a2012-12-04 15:08:18 -080012764 "Invalid arguments");
12765 return -EINVAL;
12766 }
12767
Sameer Thalappil75ea31a2013-02-21 19:38:16 -080012768 if (pHddCtx->isLogpInProgress)
12769 {
12770 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
12771 "%s:LOGP in Progress. Ignore!!!", __func__);
Gopichand Nakkala05922802013-03-14 12:23:19 -070012772 wlan_hdd_tdls_set_link_status(pAdapter, peer, eTDLS_LINK_IDLE);
Sameer Thalappil75ea31a2013-02-21 19:38:16 -080012773 return -EBUSY;
12774 }
12775
Hoonki Lee27511902013-03-14 18:19:06 -070012776 if (eTDLS_SUPPORT_NOT_ENABLED == pHddCtx->tdls_mode)
Mohit Khanna698ba2a2012-12-04 15:08:18 -080012777 {
Hoonki Lee27511902013-03-14 18:19:06 -070012778 VOS_TRACE( VOS_MODULE_ID_HDD, TDLS_LOG_LEVEL,
12779 "%s: TDLS mode is disabled OR not enabled in FW."
12780 MAC_ADDRESS_STR " action %d declined.",
12781 __func__, MAC_ADDR_ARRAY(peer), action_code);
Mohit Khanna698ba2a2012-12-04 15:08:18 -080012782 return -ENOTSUPP;
12783 }
Lee Hoonkic1262f22013-01-24 21:59:00 -080012784
Hoonki Lee27511902013-03-14 18:19:06 -070012785 /* other than teardown frame, other mgmt frames are not sent if disabled */
12786 if (SIR_MAC_TDLS_TEARDOWN != action_code)
12787 {
12788 /* if tdls_mode is disabled to respond to peer's request */
12789 if (eTDLS_SUPPORT_DISABLED == pHddCtx->tdls_mode)
12790 {
12791 VOS_TRACE( VOS_MODULE_ID_HDD, TDLS_LOG_LEVEL,
12792 "%s: " MAC_ADDRESS_STR
Gopichand Nakkala34d1b062013-03-19 15:28:33 -070012793 " TDLS mode is disabled. action %d declined.",
12794 __func__, MAC_ADDR_ARRAY(peer), action_code);
Hoonki Lee27511902013-03-14 18:19:06 -070012795
12796 return -ENOTSUPP;
12797 }
Agarwal Ashish4b87f922014-06-18 03:03:21 +053012798
12799 if (vos_max_concurrent_connections_reached())
12800 {
12801 hddLog(VOS_TRACE_LEVEL_INFO, FL("Reached max concurrent connections"));
12802 return -EINVAL;
12803 }
Hoonki Lee27511902013-03-14 18:19:06 -070012804 }
12805
Gopichand Nakkalab977a972013-02-18 19:15:09 -080012806 if (WLAN_IS_TDLS_SETUP_ACTION(action_code))
12807 {
Madan Mohan Koyyalamudi96797442013-10-08 16:04:42 +053012808 if (NULL != wlan_hdd_tdls_is_progress(pHddCtx, peer, TRUE))
Gopichand Nakkalab977a972013-02-18 19:15:09 -080012809 {
12810 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Gopichand Nakkalac87400e2013-03-13 18:51:00 -070012811 "%s: " MAC_ADDRESS_STR
Gopichand Nakkala34d1b062013-03-19 15:28:33 -070012812 " TDLS setup is ongoing. action %d declined.",
12813 __func__, MAC_ADDR_ARRAY(peer), action_code);
12814 return -EPERM;
Gopichand Nakkalab977a972013-02-18 19:15:09 -080012815 }
12816 }
12817
Hoonki Lee11f7dda2013-02-14 16:55:44 -080012818 if (SIR_MAC_TDLS_SETUP_REQ == action_code ||
12819 SIR_MAC_TDLS_SETUP_RSP == action_code )
Lee Hoonkic1262f22013-01-24 21:59:00 -080012820 {
Rajesh Chauhana34c6e62014-03-25 16:37:58 +053012821 numCurrTdlsPeers = wlan_hdd_tdlsConnectedPeers(pAdapter);
12822 if (HDD_MAX_NUM_TDLS_STA <= numCurrTdlsPeers)
Lee Hoonkic1262f22013-01-24 21:59:00 -080012823 {
12824 /* supplicant still sends tdls_mgmt(SETUP_REQ) even after
12825 we return error code at 'add_station()'. Hence we have this
12826 check again in addtion to add_station().
12827 Anyway, there is no hard to double-check. */
Hoonki Lee11f7dda2013-02-14 16:55:44 -080012828 if (SIR_MAC_TDLS_SETUP_REQ == action_code)
Lee Hoonkic1262f22013-01-24 21:59:00 -080012829 {
Gopichand Nakkalac87400e2013-03-13 18:51:00 -070012830 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
12831 "%s: " MAC_ADDRESS_STR
Rajesh Chauhana34c6e62014-03-25 16:37:58 +053012832 " TDLS Max peer already connected. action (%d) declined. Num of peers (%d), Max allowed (%d).",
12833 __func__, MAC_ADDR_ARRAY(peer), action_code,
12834 numCurrTdlsPeers, HDD_MAX_NUM_TDLS_STA);
Sunil Dutt388ac8f2013-11-28 18:06:52 +053012835 return -EINVAL;
Lee Hoonkic1262f22013-01-24 21:59:00 -080012836 }
12837 else
12838 {
Gopichand Nakkalab977a972013-02-18 19:15:09 -080012839 /* maximum reached. tweak to send error code to peer and return
12840 error code to supplicant */
Lee Hoonkic1262f22013-01-24 21:59:00 -080012841 status_code = eSIR_MAC_UNSPEC_FAILURE_STATUS;
Gopichand Nakkalac87400e2013-03-13 18:51:00 -070012842 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
12843 "%s: " MAC_ADDRESS_STR
Rajesh Chauhana34c6e62014-03-25 16:37:58 +053012844 " TDLS Max peer already connected, send response status (%d). Num of peers (%d), Max allowed (%d).",
12845 __func__, MAC_ADDR_ARRAY(peer), status_code,
12846 numCurrTdlsPeers, HDD_MAX_NUM_TDLS_STA);
Gopichand Nakkala05922802013-03-14 12:23:19 -070012847 max_sta_failed = -EPERM;
Gopichand Nakkalab977a972013-02-18 19:15:09 -080012848 /* fall through to send setup resp with failure status
12849 code */
Lee Hoonkic1262f22013-01-24 21:59:00 -080012850 }
12851 }
Hoonki Lee11f7dda2013-02-14 16:55:44 -080012852 else
12853 {
12854 hddTdlsPeer_t *pTdlsPeer;
Madan Mohan Koyyalamudi96797442013-10-08 16:04:42 +053012855 pTdlsPeer = wlan_hdd_tdls_find_peer(pAdapter, peer, TRUE);
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -070012856 if (pTdlsPeer && TDLS_IS_CONNECTED(pTdlsPeer))
Hoonki Lee11f7dda2013-02-14 16:55:44 -080012857 {
Gopichand Nakkalac87400e2013-03-13 18:51:00 -070012858 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Gopichand Nakkala34d1b062013-03-19 15:28:33 -070012859 "%s:" MAC_ADDRESS_STR " already connected. action %d declined.",
12860 __func__, MAC_ADDR_ARRAY(peer), action_code);
Hoonki Lee11f7dda2013-02-14 16:55:44 -080012861 return -EPERM;
12862 }
12863 }
Lee Hoonkic1262f22013-01-24 21:59:00 -080012864 }
Hoonki Lee11f7dda2013-02-14 16:55:44 -080012865 vos_mem_copy(peerMac, peer, 6);
Mohit Khanna698ba2a2012-12-04 15:08:18 -080012866
Hoonki Lee1090c6a2013-01-16 17:40:54 -080012867#ifdef WLAN_FEATURE_TDLS_DEBUG
12868 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Arun Kumar Khandavalli9fb625e2014-03-17 16:07:40 +053012869 "%s: " MAC_ADDRESS_STR " action %d, dialog_token %d status %d, len = %zu",
Gopichand Nakkalac87400e2013-03-13 18:51:00 -070012870 "tdls_mgmt", MAC_ADDR_ARRAY(peer),
12871 action_code, dialog_token, status_code, len);
Hoonki Lee1090c6a2013-01-16 17:40:54 -080012872#endif
Mohit Khanna698ba2a2012-12-04 15:08:18 -080012873
Hoonki Leea34dd892013-02-05 22:56:02 -080012874 /*Except teardown responder will not be used so just make 0*/
12875 responder = 0;
Hoonki Lee11f7dda2013-02-14 16:55:44 -080012876 if (SIR_MAC_TDLS_TEARDOWN == action_code)
Hoonki Leea34dd892013-02-05 22:56:02 -080012877 {
Gopichand Nakkala97a65fd2013-04-16 16:59:38 -070012878
12879 hddTdlsPeer_t *pTdlsPeer;
Madan Mohan Koyyalamudi96797442013-10-08 16:04:42 +053012880 pTdlsPeer = wlan_hdd_tdls_find_peer(pAdapter, peerMac, TRUE);
Gopichand Nakkala97a65fd2013-04-16 16:59:38 -070012881
12882 if(pTdlsPeer && TDLS_IS_CONNECTED(pTdlsPeer))
12883 responder = pTdlsPeer->is_responder;
12884 else
Hoonki Leea34dd892013-02-05 22:56:02 -080012885 {
Gopichand Nakkala97a65fd2013-04-16 16:59:38 -070012886 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Arun Kumar Khandavalli9fb625e2014-03-17 16:07:40 +053012887 "%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 -070012888 __func__, MAC_ADDR_ARRAY(peer), (NULL == pTdlsPeer) ? -1 : pTdlsPeer->link_status,
12889 dialog_token, status_code, len);
12890 return -EPERM;
Hoonki Leea34dd892013-02-05 22:56:02 -080012891 }
Mohit Khanna698ba2a2012-12-04 15:08:18 -080012892 }
Mohit Khanna698ba2a2012-12-04 15:08:18 -080012893
Gopichand Nakkala2f1ff152013-07-01 11:27:43 +053012894 /* For explicit trigger of DIS_REQ come out of BMPS for
12895 successfully receiving DIS_RSP from peer. */
Hoonki Lee14621352013-04-16 17:51:19 -070012896 if ((SIR_MAC_TDLS_SETUP_RSP == action_code) ||
Gopichand Nakkala2f1ff152013-07-01 11:27:43 +053012897 (SIR_MAC_TDLS_DIS_RSP == action_code) ||
12898 (SIR_MAC_TDLS_DIS_REQ == action_code))
Hoonki Lee14621352013-04-16 17:51:19 -070012899 {
12900 if (TRUE == sme_IsPmcBmps(WLAN_HDD_GET_HAL_CTX(pAdapter)))
12901 {
12902 VOS_TRACE( VOS_MODULE_ID_HDD, TDLS_LOG_LEVEL,
Gopichand Nakkala2f1ff152013-07-01 11:27:43 +053012903 "%s: Sending frame action_code %u.Disable BMPS", __func__, action_code);
Hoonki Lee14621352013-04-16 17:51:19 -070012904 hdd_disable_bmps_imps(pHddCtx, WLAN_HDD_INFRA_STATION);
12905 }
Gopichand Nakkala2f1ff152013-07-01 11:27:43 +053012906 if (SIR_MAC_TDLS_DIS_REQ != action_code)
12907 wlan_hdd_tdls_set_cap(pAdapter, peerMac, eTDLS_CAP_SUPPORTED);
Hoonki Lee14621352013-04-16 17:51:19 -070012908 }
12909
Hoonki Lee5305c3a2013-04-29 23:28:59 -070012910 /* make sure doesn't call send_mgmt() while it is pending */
12911 if (TDLS_CTX_MAGIC == pAdapter->mgmtTxCompletionStatus)
12912 {
12913 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Arif Hussain6d2a3322013-11-17 19:50:10 -080012914 "%s: " MAC_ADDRESS_STR " action %d couldn't sent, as one is pending. return EBUSY",
Hoonki Lee5305c3a2013-04-29 23:28:59 -070012915 __func__, MAC_ADDR_ARRAY(peer), action_code);
12916 return -EBUSY;
12917 }
12918
12919 pAdapter->mgmtTxCompletionStatus = TDLS_CTX_MAGIC;
Gopichand Nakkalab977a972013-02-18 19:15:09 -080012920 INIT_COMPLETION(pAdapter->tdls_mgmt_comp);
12921
Mohit Khanna698ba2a2012-12-04 15:08:18 -080012922 status = sme_SendTdlsMgmtFrame(WLAN_HDD_GET_HAL_CTX(pAdapter), pAdapter->sessionId,
Pradeep Reddy POTTETIca171f82014-03-21 14:17:35 +053012923 peerMac, action_code, dialog_token, status_code, peer_capability, (tANI_U8 *)buf, len, responder);
Mohit Khanna698ba2a2012-12-04 15:08:18 -080012924
Gopichand Nakkalab977a972013-02-18 19:15:09 -080012925 if (VOS_STATUS_SUCCESS != status)
12926 {
Mohit Khanna698ba2a2012-12-04 15:08:18 -080012927 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
12928 "%s: sme_SendTdlsMgmtFrame failed!", __func__);
Hoonki Lee5305c3a2013-04-29 23:28:59 -070012929 pAdapter->mgmtTxCompletionStatus = FALSE;
Hoonki Lee14621352013-04-16 17:51:19 -070012930 wlan_hdd_tdls_check_bmps(pAdapter);
Sunil Dutt388ac8f2013-11-28 18:06:52 +053012931 return -EINVAL;
Mohit Khanna698ba2a2012-12-04 15:08:18 -080012932 }
12933
Hoonki Leed37cbb32013-04-20 00:31:14 -070012934 rc = wait_for_completion_interruptible_timeout(&pAdapter->tdls_mgmt_comp,
12935 msecs_to_jiffies(WAIT_TIME_TDLS_MGMT));
12936
12937 if ((rc <= 0) || (TRUE != pAdapter->mgmtTxCompletionStatus))
Gopichand Nakkalab977a972013-02-18 19:15:09 -080012938 {
Hoonki Leed37cbb32013-04-20 00:31:14 -070012939 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Jeff Johnson0299d0a2013-10-30 12:37:43 -070012940 "%s: Mgmt Tx Completion failed status %ld TxCompletion %u",
Hoonki Leed37cbb32013-04-20 00:31:14 -070012941 __func__, rc, pAdapter->mgmtTxCompletionStatus);
Hoonki Lee5305c3a2013-04-29 23:28:59 -070012942 pAdapter->mgmtTxCompletionStatus = FALSE;
Yue Ma4f55ef32014-01-23 16:45:33 -080012943
12944 if (pHddCtx->isLogpInProgress)
12945 {
12946 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
12947 "%s: LOGP in Progress. Ignore!!!", __func__);
12948 return -EAGAIN;
12949 }
12950
Hoonki Leed37cbb32013-04-20 00:31:14 -070012951 wlan_hdd_tdls_check_bmps(pAdapter);
Sunil Dutt388ac8f2013-11-28 18:06:52 +053012952 return -EINVAL;
Gopichand Nakkalab977a972013-02-18 19:15:09 -080012953 }
12954
Gopichand Nakkala05922802013-03-14 12:23:19 -070012955 if (max_sta_failed)
Hoonki Lee14621352013-04-16 17:51:19 -070012956 {
12957 wlan_hdd_tdls_check_bmps(pAdapter);
Gopichand Nakkala05922802013-03-14 12:23:19 -070012958 return max_sta_failed;
Hoonki Lee14621352013-04-16 17:51:19 -070012959 }
Gopichand Nakkalab977a972013-02-18 19:15:09 -080012960
Hoonki Leea34dd892013-02-05 22:56:02 -080012961 if (SIR_MAC_TDLS_SETUP_RSP == action_code)
12962 {
Gopichand Nakkala4327a152013-03-04 23:22:42 -080012963 wlan_hdd_tdls_set_responder(pAdapter, peerMac, TRUE);
Hoonki Leea34dd892013-02-05 22:56:02 -080012964 }
12965 else if (SIR_MAC_TDLS_SETUP_CNF == action_code)
12966 {
Gopichand Nakkala4327a152013-03-04 23:22:42 -080012967 wlan_hdd_tdls_set_responder(pAdapter, peerMac, FALSE);
Hoonki Leea34dd892013-02-05 22:56:02 -080012968 }
Mohit Khanna698ba2a2012-12-04 15:08:18 -080012969
12970 return 0;
12971}
12972
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053012973static int __wlan_hdd_cfg80211_tdls_oper(struct wiphy *wiphy, struct net_device *dev,
Mohit Khanna698ba2a2012-12-04 15:08:18 -080012974 u8 *peer, enum nl80211_tdls_operation oper)
12975{
12976 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
12977 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053012978 int status;
Hoonki Lee5305c3a2013-04-29 23:28:59 -070012979 hddTdlsPeer_t *pTdlsPeer;
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053012980
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053012981 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
12982 TRACE_CODE_HDD_CFG80211_TDLS_OPER,
12983 pAdapter->sessionId, oper));
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053012984 if ( NULL == peer )
Mohit Khanna698ba2a2012-12-04 15:08:18 -080012985 {
Gopichand Nakkalab977a972013-02-18 19:15:09 -080012986 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Chilam Ngc4244af2013-04-01 15:37:32 -070012987 "%s: Invalid arguments", __func__);
Mohit Khanna698ba2a2012-12-04 15:08:18 -080012988 return -EINVAL;
12989 }
Hoonki Lee1090c6a2013-01-16 17:40:54 -080012990
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053012991 status = wlan_hdd_validate_context(pHddCtx);
12992
12993 if (0 != status)
Sameer Thalappil75ea31a2013-02-21 19:38:16 -080012994 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053012995 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
12996 "%s: HDD context is not valid", __func__);
12997 return status;
Sameer Thalappil75ea31a2013-02-21 19:38:16 -080012998 }
12999
Mohit Khanna698ba2a2012-12-04 15:08:18 -080013000
13001 if( FALSE == pHddCtx->cfg_ini->fEnableTDLSSupport ||
Hoonki Lee1090c6a2013-01-16 17:40:54 -080013002 FALSE == sme_IsFeatureSupportedByFW(TDLS))
Mohit Khanna698ba2a2012-12-04 15:08:18 -080013003 {
Hoonki Lee1090c6a2013-01-16 17:40:54 -080013004 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Chilam Ngc4244af2013-04-01 15:37:32 -070013005 "TDLS Disabled in INI OR not enabled in FW. "
13006 "Cannot process TDLS commands");
Mohit Khanna698ba2a2012-12-04 15:08:18 -080013007 return -ENOTSUPP;
13008 }
13009
13010 switch (oper) {
13011 case NL80211_TDLS_ENABLE_LINK:
13012 {
Mohit Khanna698ba2a2012-12-04 15:08:18 -080013013 VOS_STATUS status;
c_hpothu6ff1c3c2013-10-01 19:01:57 +053013014 long ret;
Gopichand Nakkala79ff85d2013-05-27 17:05:29 +053013015 tCsrTdlsLinkEstablishParams tdlsLinkEstablishParams;
Mohit Khanna698ba2a2012-12-04 15:08:18 -080013016
Sunil Dutt41de4e22013-11-14 18:09:02 +053013017 pTdlsPeer = wlan_hdd_tdls_find_peer(pAdapter, peer, TRUE);
13018
13019 if ( NULL == pTdlsPeer ) {
13020 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: " MAC_ADDRESS_STR
13021 " (oper %d) not exsting. ignored",
13022 __func__, MAC_ADDR_ARRAY(peer), (int)oper);
13023 return -EINVAL;
13024 }
13025
13026 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
13027 "%s: " MAC_ADDRESS_STR " link_status %d (%s) ", "tdls_oper",
13028 MAC_ADDR_ARRAY(peer), pTdlsPeer->link_status,
13029 "NL80211_TDLS_ENABLE_LINK");
13030
Gopichand Nakkala2f4a2822013-04-17 11:22:01 -070013031 if (!TDLS_STA_INDEX_VALID(pTdlsPeer->staId))
13032 {
13033 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Invalid Staion Index %u "
13034 MAC_ADDRESS_STR " failed",
13035 __func__, pTdlsPeer->staId, MAC_ADDR_ARRAY(peer));
13036 return -EINVAL;
13037 }
13038
Hoonki Lee5305c3a2013-04-29 23:28:59 -070013039 if (eTDLS_LINK_CONNECTED != pTdlsPeer->link_status)
Gopichand Nakkalac87400e2013-03-13 18:51:00 -070013040 {
Madan Mohan Koyyalamudice419872013-09-13 19:36:52 +053013041 if (IS_ADVANCE_TDLS_ENABLE) {
Gopichand Nakkala24be5312013-07-02 16:47:12 +053013042
Madan Mohan Koyyalamudice419872013-09-13 19:36:52 +053013043 if (0 != wlan_hdd_tdls_get_link_establish_params(
13044 pAdapter, peer,&tdlsLinkEstablishParams)) {
13045 return -EINVAL;
13046 }
13047 INIT_COMPLETION(pAdapter->tdls_link_establish_req_comp);
Gopichand Nakkala79ff85d2013-05-27 17:05:29 +053013048
Madan Mohan Koyyalamudice419872013-09-13 19:36:52 +053013049 sme_SendTdlsLinkEstablishParams(WLAN_HDD_GET_HAL_CTX(pAdapter),
13050 pAdapter->sessionId, peer, &tdlsLinkEstablishParams);
13051 /* Send TDLS peer UAPSD capabilities to the firmware and
13052 * register with the TL on after the response for this operation
13053 * is received .
13054 */
13055 ret = wait_for_completion_interruptible_timeout(
13056 &pAdapter->tdls_link_establish_req_comp,
13057 msecs_to_jiffies(WAIT_TIME_TDLS_LINK_ESTABLISH_REQ));
13058 if (ret <= 0)
13059 {
13060 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
13061 "%s: Link Establish Request Faled Status %ld",
13062 __func__, ret);
13063 return -EINVAL;
13064 }
Gopichand Nakkala79ff85d2013-05-27 17:05:29 +053013065 }
Gopichand Nakkalaccd3a382013-03-19 13:56:10 -070013066 wlan_hdd_tdls_set_peer_link_status(pTdlsPeer, eTDLS_LINK_CONNECTED);
Gopichand Nakkala471708b2013-06-04 20:03:01 +053013067 /* Mark TDLS client Authenticated .*/
13068 status = WLANTL_ChangeSTAState( pHddCtx->pvosContext,
13069 pTdlsPeer->staId,
13070 WLANTL_STA_AUTHENTICATED);
Gopichand Nakkalaccd3a382013-03-19 13:56:10 -070013071 if (VOS_STATUS_SUCCESS == status)
13072 {
Hoonki Lee14621352013-04-16 17:51:19 -070013073 if (pTdlsPeer->is_responder == 0)
13074 {
13075 v_U8_t staId = (v_U8_t)pTdlsPeer->staId;
13076
13077 wlan_hdd_tdls_timer_restart(pAdapter,
13078 &pTdlsPeer->initiatorWaitTimeoutTimer,
13079 WAIT_TIME_TDLS_INITIATOR);
13080 /* suspend initiator TX until it receives direct packet from the
13081 reponder or WAIT_TIME_TDLS_INITIATOR timer expires */
13082 WLANTL_SuspendDataTx( (WLAN_HDD_GET_CTX(pAdapter))->pvosContext,
13083 &staId, NULL);
13084 }
Gopichand Nakkalaccd3a382013-03-19 13:56:10 -070013085 wlan_hdd_tdls_increment_peer_count(pAdapter);
13086 }
Gopichand Nakkalac87400e2013-03-13 18:51:00 -070013087 wlan_hdd_tdls_check_bmps(pAdapter);
Gopichand Nakkala79ff85d2013-05-27 17:05:29 +053013088
13089 /* Update TL about the UAPSD masks , to route the packets to firmware */
Gopichand Nakkala574f6d12013-06-27 19:38:43 +053013090 if ((TRUE == pHddCtx->cfg_ini->fEnableTDLSBufferSta)
13091 || pHddCtx->cfg_ini->fTDLSUapsdMask )
Gopichand Nakkala79ff85d2013-05-27 17:05:29 +053013092 {
Gopichand Nakkala574f6d12013-06-27 19:38:43 +053013093 int ac;
13094 uint8 ucAc[4] = { WLANTL_AC_VO,
13095 WLANTL_AC_VI,
13096 WLANTL_AC_BK,
13097 WLANTL_AC_BE };
13098 uint8 tlTid[4] = { 7, 5, 2, 3 } ;
13099 for(ac=0; ac < 4; ac++)
13100 {
13101 status = WLANTL_EnableUAPSDForAC( (WLAN_HDD_GET_CTX(pAdapter))->pvosContext,
13102 pTdlsPeer->staId, ucAc[ac],
13103 tlTid[ac], tlTid[ac], 0, 0,
13104 WLANTL_BI_DIR );
13105 }
Gopichand Nakkala79ff85d2013-05-27 17:05:29 +053013106 }
Gopichand Nakkalac87400e2013-03-13 18:51:00 -070013107 }
13108
Mohit Khanna698ba2a2012-12-04 15:08:18 -080013109 }
13110 break;
13111 case NL80211_TDLS_DISABLE_LINK:
Lee Hoonkic1262f22013-01-24 21:59:00 -080013112 {
Sunil Dutt41de4e22013-11-14 18:09:02 +053013113 pTdlsPeer = wlan_hdd_tdls_find_peer(pAdapter, peer, TRUE);
13114
13115 if ( NULL == pTdlsPeer ) {
13116 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: " MAC_ADDRESS_STR
13117 " (oper %d) not exsting. ignored",
13118 __func__, MAC_ADDR_ARRAY(peer), (int)oper);
13119 return -EINVAL;
13120 }
13121
13122 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
13123 "%s: " MAC_ADDRESS_STR " link_status %d (%s) ", "tdls_oper",
13124 MAC_ADDR_ARRAY(peer), pTdlsPeer->link_status,
13125 "NL80211_TDLS_DISABLE_LINK");
13126
Hoonki Lee5305c3a2013-04-29 23:28:59 -070013127 if(TDLS_STA_INDEX_VALID(pTdlsPeer->staId))
Lee Hoonkic1262f22013-01-24 21:59:00 -080013128 {
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -070013129 long status;
13130
13131 INIT_COMPLETION(pAdapter->tdls_del_station_comp);
13132
Lee Hoonkic1262f22013-01-24 21:59:00 -080013133 sme_DeleteTdlsPeerSta( WLAN_HDD_GET_HAL_CTX(pAdapter),
13134 pAdapter->sessionId, peer );
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -070013135
13136 status = wait_for_completion_interruptible_timeout(&pAdapter->tdls_del_station_comp,
13137 msecs_to_jiffies(WAIT_TIME_TDLS_DEL_STA));
13138 if (status <= 0)
13139 {
Hoonki Lee5305c3a2013-04-29 23:28:59 -070013140 wlan_hdd_tdls_set_peer_link_status(pTdlsPeer, eTDLS_LINK_IDLE);
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -070013141 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
13142 "%s: Del station failed status %ld",
13143 __func__, status);
13144 return -EPERM;
13145 }
Hoonki Lee5305c3a2013-04-29 23:28:59 -070013146 wlan_hdd_tdls_set_peer_link_status(pTdlsPeer, eTDLS_LINK_IDLE);
Lee Hoonkic1262f22013-01-24 21:59:00 -080013147 }
13148 else
13149 {
Gopichand Nakkalac87400e2013-03-13 18:51:00 -070013150 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
13151 "%s: TDLS Peer Station doesn't exist.", __func__);
Lee Hoonkic1262f22013-01-24 21:59:00 -080013152 }
Lee Hoonkic1262f22013-01-24 21:59:00 -080013153 }
Gopichand Nakkalac87400e2013-03-13 18:51:00 -070013154 break;
Mohit Khanna698ba2a2012-12-04 15:08:18 -080013155 case NL80211_TDLS_TEARDOWN:
Sunil Dutt41de4e22013-11-14 18:09:02 +053013156 {
13157 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
13158 " %s : NL80211_TDLS_TEARDOWN for " MAC_ADDRESS_STR,
13159 __func__, MAC_ADDR_ARRAY(peer));
13160
13161 if ( (FALSE == pHddCtx->cfg_ini->fTDLSExternalControl) ||
13162 (FALSE == pHddCtx->cfg_ini->fEnableTDLSImplicitTrigger) ) {
13163
13164 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
13165 " %s TDLS External control and Implicit Trigger not enabled ",
13166 __func__);
13167 return -ENOTSUPP;
13168 }
13169
Sunil Dutt41de4e22013-11-14 18:09:02 +053013170
13171 pTdlsPeer = wlan_hdd_tdls_find_peer(pAdapter, peer, TRUE);
13172
13173 if ( NULL == pTdlsPeer ) {
13174 hddLog(VOS_TRACE_LEVEL_INFO, "%s: " MAC_ADDRESS_STR
13175 " peer not exsting",
13176 __func__, MAC_ADDR_ARRAY(peer));
Naresh Jayaram937abdf2013-11-26 19:50:25 +053013177 return -EINVAL;
Sunil Dutt41de4e22013-11-14 18:09:02 +053013178 }
13179 else {
13180 wlan_hdd_tdls_indicate_teardown(pAdapter, pTdlsPeer,
13181 eSIR_MAC_TDLS_TEARDOWN_UNSPEC_REASON);
13182 }
Naresh Jayaram937abdf2013-11-26 19:50:25 +053013183
13184 if ( 0 != wlan_hdd_tdls_set_force_peer(pAdapter, peer, FALSE) )
13185 return -EINVAL;
Sunil Dutt41de4e22013-11-14 18:09:02 +053013186 break;
13187 }
Mohit Khanna698ba2a2012-12-04 15:08:18 -080013188 case NL80211_TDLS_SETUP:
Sunil Dutt41de4e22013-11-14 18:09:02 +053013189 {
Naresh Jayaramdb4514b2013-11-25 18:08:10 +053013190 hddTdlsPeer_t *pTdlsPeer;
Sunil Dutt41de4e22013-11-14 18:09:02 +053013191 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
13192 " %s : NL80211_TDLS_SETUP for " MAC_ADDRESS_STR,
13193 __func__, MAC_ADDR_ARRAY(peer));
13194
13195 if ( (FALSE == pHddCtx->cfg_ini->fTDLSExternalControl) ||
13196 (FALSE == pHddCtx->cfg_ini->fEnableTDLSImplicitTrigger) ) {
13197
13198 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
13199 " %s TDLS External control and Implicit Trigger not enabled ",
13200 __func__);
13201 return -ENOTSUPP;
13202 }
13203
Naresh Jayaramdb4514b2013-11-25 18:08:10 +053013204 /* To cater the requirement of establishing the TDLS link
13205 * irrespective of the data traffic , get an entry of TDLS peer.
13206 */
13207 pTdlsPeer = wlan_hdd_tdls_get_peer(pAdapter, peer);
13208 if (pTdlsPeer == NULL) {
13209 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
13210 "%s: peer " MAC_ADDRESS_STR " not existing",
13211 __func__, MAC_ADDR_ARRAY(peer));
13212 return -EINVAL;
13213 }
Naresh Jayaram937abdf2013-11-26 19:50:25 +053013214
13215 if ( 0 != wlan_hdd_tdls_set_force_peer(pAdapter, peer, TRUE) ) {
13216
13217 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
13218 " %s TDLS Add Force Peer Failed",
13219 __func__);
13220 return -EINVAL;
13221 }
Naresh Jayaramdb4514b2013-11-25 18:08:10 +053013222 break;
Sunil Dutt41de4e22013-11-14 18:09:02 +053013223 }
Mohit Khanna698ba2a2012-12-04 15:08:18 -080013224 case NL80211_TDLS_DISCOVERY_REQ:
13225 /* We don't support in-driver setup/teardown/discovery */
c_hpothu6ff1c3c2013-10-01 19:01:57 +053013226 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_WARN,
13227 "%s: We don't support in-driver setup/teardown/discovery "
13228 ,__func__);
Mohit Khanna698ba2a2012-12-04 15:08:18 -080013229 return -ENOTSUPP;
13230 default:
c_hpothu6ff1c3c2013-10-01 19:01:57 +053013231 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
13232 "%s: unsupported event",__func__);
Mohit Khanna698ba2a2012-12-04 15:08:18 -080013233 return -ENOTSUPP;
13234 }
13235 return 0;
13236}
Chilam NG571c65a2013-01-19 12:27:36 +053013237
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053013238static int wlan_hdd_cfg80211_tdls_oper(struct wiphy *wiphy, struct net_device *dev,
13239 u8 *peer, enum nl80211_tdls_operation oper)
13240{
13241 int ret;
13242
13243 vos_ssr_protect(__func__);
13244 ret = __wlan_hdd_cfg80211_tdls_oper(wiphy, dev, peer, oper);
13245 vos_ssr_unprotect(__func__);
13246
13247 return ret;
13248}
13249
Chilam NG571c65a2013-01-19 12:27:36 +053013250int wlan_hdd_cfg80211_send_tdls_discover_req(struct wiphy *wiphy,
13251 struct net_device *dev, u8 *peer)
13252{
Arif Hussaina7c8e412013-11-20 11:06:42 -080013253 hddLog(VOS_TRACE_LEVEL_INFO,
13254 "tdls send discover req: "MAC_ADDRESS_STR,
13255 MAC_ADDR_ARRAY(peer));
Chilam NG571c65a2013-01-19 12:27:36 +053013256
Sunil Dutt Undekarieacac6f2014-03-21 14:08:53 +053013257#if TDLS_MGMT_VERSION2
13258 return wlan_hdd_cfg80211_tdls_mgmt(wiphy, dev, peer,
13259 WLAN_TDLS_DISCOVERY_REQUEST, 1, 0, 0, NULL, 0);
13260#else
Chilam NG571c65a2013-01-19 12:27:36 +053013261 return wlan_hdd_cfg80211_tdls_mgmt(wiphy, dev, peer,
13262 WLAN_TDLS_DISCOVERY_REQUEST, 1, 0, NULL, 0);
Sunil Dutt Undekarieacac6f2014-03-21 14:08:53 +053013263#endif
Chilam NG571c65a2013-01-19 12:27:36 +053013264}
Mohit Khanna698ba2a2012-12-04 15:08:18 -080013265#endif
13266
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053013267#ifdef WLAN_FEATURE_GTK_OFFLOAD
13268/*
13269 * FUNCTION: wlan_hdd_cfg80211_update_replayCounterCallback
13270 * Callback rountine called upon receiving response for
13271 * get offload info
13272 */
13273void wlan_hdd_cfg80211_update_replayCounterCallback(void *callbackContext,
13274 tpSirGtkOffloadGetInfoRspParams pGtkOffloadGetInfoRsp)
13275{
13276
13277 hdd_adapter_t *pAdapter = (hdd_adapter_t *)callbackContext;
Gopichand Nakkalad36ee622013-05-07 14:13:27 +053013278 tANI_U8 tempReplayCounter[8];
13279 hdd_station_ctx_t *pHddStaCtx;
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053013280
13281 ENTER();
13282
13283 if (NULL == pAdapter)
13284 {
Agarwal Ashish971c2882013-10-30 20:11:12 +053013285 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053013286 "%s: HDD adapter is Null", __func__);
13287 return ;
13288 }
13289
13290 if (NULL == pGtkOffloadGetInfoRsp)
13291 {
13292 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
13293 "%s: pGtkOffloadGetInfoRsp is Null", __func__);
13294 return ;
13295 }
13296
13297 if (VOS_STATUS_SUCCESS != pGtkOffloadGetInfoRsp->ulStatus)
13298 {
13299 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
13300 "%s: wlan Failed to get replay counter value",
13301 __func__);
13302 return ;
13303 }
13304
Gopichand Nakkalad36ee622013-05-07 14:13:27 +053013305 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
13306 /* Update replay counter */
13307 pHddStaCtx->gtkOffloadReqParams.ullKeyReplayCounter =
13308 pGtkOffloadGetInfoRsp->ullKeyReplayCounter;
13309
13310 {
13311 /* changing from little to big endian since supplicant
13312 * works on big endian format
13313 */
13314 int i;
13315 tANI_U8 *p = (tANI_U8 *)&pGtkOffloadGetInfoRsp->ullKeyReplayCounter;
13316
13317 for (i = 0; i < 8; i++)
13318 {
13319 tempReplayCounter[7-i] = (tANI_U8)p[i];
13320 }
13321 }
13322
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053013323 /* Update replay counter to NL */
13324 cfg80211_gtk_rekey_notify(pAdapter->dev, pGtkOffloadGetInfoRsp->bssId,
Gopichand Nakkalad36ee622013-05-07 14:13:27 +053013325 tempReplayCounter, GFP_KERNEL);
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053013326}
13327
13328/*
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053013329 * FUNCTION: __wlan_hdd_cfg80211_set_rekey_data
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053013330 * This function is used to offload GTK rekeying job to the firmware.
13331 */
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053013332int __wlan_hdd_cfg80211_set_rekey_data(struct wiphy *wiphy, struct net_device *dev,
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053013333 struct cfg80211_gtk_rekey_data *data)
13334{
13335 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
13336 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
13337 hdd_station_ctx_t *pHddStaCtx;
13338 tHalHandle hHal;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053013339 int result;
Gopichand Nakkalad36ee622013-05-07 14:13:27 +053013340 tSirGtkOffloadParams hddGtkOffloadReqParams;
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053013341 eHalStatus status = eHAL_STATUS_FAILURE;
13342
13343 ENTER();
13344
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053013345
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053013346 if (NULL == pAdapter)
13347 {
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053013348 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053013349 "%s: HDD adapter is Null", __func__);
13350 return -ENODEV;
13351 }
13352
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053013353 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
13354 TRACE_CODE_HDD_CFG80211_SET_REKEY_DATA,
13355 pAdapter->sessionId, pAdapter->device_mode));
13356
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053013357 result = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053013358
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053013359 if (0 != result)
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053013360 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053013361 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
13362 "%s: HDD context is not valid", __func__);
13363 return result;
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053013364 }
13365
13366 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
13367 hHal = WLAN_HDD_GET_HAL_CTX(pAdapter);
13368 if (NULL == hHal)
13369 {
13370 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
13371 "%s: HAL context is Null!!!", __func__);
13372 return -EAGAIN;
13373 }
13374
Gopichand Nakkalad36ee622013-05-07 14:13:27 +053013375 pHddStaCtx->gtkOffloadReqParams.ulFlags = GTK_OFFLOAD_ENABLE;
13376 memcpy(pHddStaCtx->gtkOffloadReqParams.aKCK, data->kck, NL80211_KCK_LEN);
13377 memcpy(pHddStaCtx->gtkOffloadReqParams.aKEK, data->kek, NL80211_KEK_LEN);
13378 memcpy(pHddStaCtx->gtkOffloadReqParams.bssId, &pHddStaCtx->conn_info.bssId,
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053013379 WNI_CFG_BSSID_LEN);
Gopichand Nakkalad36ee622013-05-07 14:13:27 +053013380 {
13381 /* changing from big to little endian since driver
13382 * works on little endian format
13383 */
13384 tANI_U8 *p =
13385 (tANI_U8 *)&pHddStaCtx->gtkOffloadReqParams.ullKeyReplayCounter;
13386 int i;
13387
13388 for (i = 0; i < 8; i++)
13389 {
13390 p[7-i] = data->replay_ctr[i];
13391 }
13392 }
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053013393
13394 if (TRUE == pHddCtx->hdd_wlan_suspended)
13395 {
13396 /* if wlan is suspended, enable GTK offload directly from here */
Gopichand Nakkalad36ee622013-05-07 14:13:27 +053013397 memcpy(&hddGtkOffloadReqParams, &pHddStaCtx->gtkOffloadReqParams,
13398 sizeof (tSirGtkOffloadParams));
13399 status = sme_SetGTKOffload(hHal, &hddGtkOffloadReqParams,
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053013400 pAdapter->sessionId);
13401
13402 if (eHAL_STATUS_SUCCESS != status)
13403 {
13404 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
13405 "%s: sme_SetGTKOffload failed, returned %d",
13406 __func__, status);
13407 return status;
13408 }
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053013409 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
13410 "%s: sme_SetGTKOffload successfull", __func__);
13411 }
13412 else
13413 {
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053013414 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
13415 "%s: wlan not suspended GTKOffload request is stored",
13416 __func__);
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053013417 }
Gopichand Nakkalad36ee622013-05-07 14:13:27 +053013418
13419 return eHAL_STATUS_SUCCESS;
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053013420}
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053013421
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053013422int wlan_hdd_cfg80211_set_rekey_data(struct wiphy *wiphy, struct net_device *dev,
13423 struct cfg80211_gtk_rekey_data *data)
13424{
13425 int ret;
13426
13427 vos_ssr_protect(__func__);
13428 ret = __wlan_hdd_cfg80211_set_rekey_data(wiphy, dev, data);
13429 vos_ssr_unprotect(__func__);
13430
13431 return ret;
13432}
13433#endif /*WLAN_FEATURE_GTK_OFFLOAD*/
Gopichand Nakkalac005b7c2013-05-14 16:04:14 +053013434/*
13435 * FUNCTION: wlan_hdd_cfg80211_set_mac_acl
13436 * This function is used to set access control policy
13437 */
13438static int wlan_hdd_cfg80211_set_mac_acl(struct wiphy *wiphy,
13439 struct net_device *dev, const struct cfg80211_acl_data *params)
13440{
13441 int i;
13442 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
13443 hdd_hostapd_state_t *pHostapdState;
13444 tsap_Config_t *pConfig;
13445 v_CONTEXT_t pVosContext = NULL;
13446 hdd_context_t *pHddCtx;
13447 int status;
13448
13449 ENTER();
13450
13451 if (NULL == pAdapter)
13452 {
13453 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
13454 "%s: HDD adapter is Null", __func__);
13455 return -ENODEV;
13456 }
13457
13458 if (NULL == params)
13459 {
13460 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
13461 "%s: params is Null", __func__);
13462 return -EINVAL;
13463 }
13464
13465 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
13466 status = wlan_hdd_validate_context(pHddCtx);
13467
13468 if (0 != status)
13469 {
13470 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
13471 "%s: HDD context is not valid", __func__);
13472 return status;
13473 }
13474
13475 pVosContext = pHddCtx->pvosContext;
13476 pHostapdState = WLAN_HDD_GET_HOSTAP_STATE_PTR(pAdapter);
13477
13478 if (NULL == pHostapdState)
13479 {
13480 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
13481 "%s: pHostapdState is Null", __func__);
13482 return -EINVAL;
13483 }
13484
13485 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,"acl policy: = %d"
13486 "no acl entries = %d", params->acl_policy, params->n_acl_entries);
13487
13488 if (WLAN_HDD_SOFTAP == pAdapter->device_mode)
13489 {
13490 pConfig = &pAdapter->sessionCtx.ap.sapConfig;
13491
13492 /* default value */
13493 pConfig->num_accept_mac = 0;
13494 pConfig->num_deny_mac = 0;
13495
13496 /**
13497 * access control policy
13498 * @NL80211_ACL_POLICY_ACCEPT_UNLESS_LISTED: Deny stations which are
13499 * listed in hostapd.deny file.
13500 * @NL80211_ACL_POLICY_DENY_UNLESS_LISTED: Allow stations which are
13501 * listed in hostapd.accept file.
13502 */
13503 if (NL80211_ACL_POLICY_DENY_UNLESS_LISTED == params->acl_policy)
13504 {
13505 pConfig->SapMacaddr_acl = eSAP_DENY_UNLESS_ACCEPTED;
13506 }
13507 else if (NL80211_ACL_POLICY_ACCEPT_UNLESS_LISTED == params->acl_policy)
13508 {
13509 pConfig->SapMacaddr_acl = eSAP_ACCEPT_UNLESS_DENIED;
13510 }
13511 else
13512 {
13513 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
13514 "%s:Acl Policy : %d is not supported",
13515 __func__, params->acl_policy);
13516 return -ENOTSUPP;
13517 }
13518
13519 if (eSAP_DENY_UNLESS_ACCEPTED == pConfig->SapMacaddr_acl)
13520 {
13521 pConfig->num_accept_mac = params->n_acl_entries;
13522 for (i = 0; i < params->n_acl_entries; i++)
13523 {
13524 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
13525 "** Add ACL MAC entry %i in WhiletList :"
13526 MAC_ADDRESS_STR, i,
13527 MAC_ADDR_ARRAY(params->mac_addrs[i].addr));
13528
13529 vos_mem_copy(&pConfig->accept_mac[i], params->mac_addrs[i].addr,
13530 sizeof(qcmacaddr));
13531 }
13532 }
13533 else if (eSAP_ACCEPT_UNLESS_DENIED == pConfig->SapMacaddr_acl)
13534 {
13535 pConfig->num_deny_mac = params->n_acl_entries;
13536 for (i = 0; i < params->n_acl_entries; i++)
13537 {
13538 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
13539 "** Add ACL MAC entry %i in BlackList :"
13540 MAC_ADDRESS_STR, i,
13541 MAC_ADDR_ARRAY(params->mac_addrs[i].addr));
13542
13543 vos_mem_copy(&pConfig->deny_mac[i], params->mac_addrs[i].addr,
13544 sizeof(qcmacaddr));
13545 }
13546 }
13547
13548 if (VOS_STATUS_SUCCESS != WLANSAP_SetMacACL(pVosContext, pConfig))
13549 {
13550 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
13551 "%s: SAP Set Mac Acl fail", __func__);
13552 return -EINVAL;
13553 }
13554 }
13555 else
13556 {
13557 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Sushant Kaushik8bc7df22014-04-09 17:55:29 +053013558 "%s: Invalid device_mode = %s (%d)",
13559 __func__, hdd_device_modetoString(pAdapter->device_mode),
13560 pAdapter->device_mode);
Gopichand Nakkalac005b7c2013-05-14 16:04:14 +053013561 return -EINVAL;
13562 }
13563
13564 return 0;
13565}
13566
Leo Chang9056f462013-08-01 19:21:11 -070013567#ifdef WLAN_NL80211_TESTMODE
13568#ifdef FEATURE_WLAN_LPHB
Leo Changd9df8aa2013-09-26 13:32:26 -070013569void wlan_hdd_cfg80211_lphb_ind_handler
Leo Chang9056f462013-08-01 19:21:11 -070013570(
13571 void *pAdapter,
13572 void *indCont
13573)
13574{
Leo Changd9df8aa2013-09-26 13:32:26 -070013575 tSirLPHBInd *lphbInd;
13576 struct sk_buff *skb;
c_hpothu73f35e62014-04-18 13:40:08 +053013577 hdd_context_t *pHddCtxt;
Leo Chang9056f462013-08-01 19:21:11 -070013578
13579 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Leo Changd9df8aa2013-09-26 13:32:26 -070013580 "LPHB indication arrived");
Leo Chang9056f462013-08-01 19:21:11 -070013581
c_hpothu73f35e62014-04-18 13:40:08 +053013582 if (pAdapter == NULL)
13583 {
13584 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
13585 "%s: pAdapter is NULL\n",__func__);
13586 return;
13587 }
13588
Leo Chang9056f462013-08-01 19:21:11 -070013589 if (NULL == indCont)
13590 {
13591 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Leo Changd9df8aa2013-09-26 13:32:26 -070013592 "LPHB IND, invalid argument");
Leo Chang9056f462013-08-01 19:21:11 -070013593 return;
13594 }
13595
c_hpothu73f35e62014-04-18 13:40:08 +053013596 pHddCtxt = (hdd_context_t *)pAdapter;
Leo Changd9df8aa2013-09-26 13:32:26 -070013597 lphbInd = (tSirLPHBInd *)indCont;
Leo Chang9056f462013-08-01 19:21:11 -070013598 skb = cfg80211_testmode_alloc_event_skb(
c_hpothu73f35e62014-04-18 13:40:08 +053013599 pHddCtxt->wiphy,
Leo Changd9df8aa2013-09-26 13:32:26 -070013600 sizeof(tSirLPHBInd),
Leo Chang9056f462013-08-01 19:21:11 -070013601 GFP_ATOMIC);
13602 if (!skb)
13603 {
13604 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
13605 "LPHB timeout, NL buffer alloc fail");
13606 return;
13607 }
13608
Leo Changac3ba772013-10-07 09:47:04 -070013609 if(nla_put_u32(skb, WLAN_HDD_TM_ATTR_CMD, WLAN_HDD_TM_CMD_WLAN_HB))
Leo Changd9df8aa2013-09-26 13:32:26 -070013610 {
13611 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
13612 "WLAN_HDD_TM_ATTR_CMD put fail");
13613 goto nla_put_failure;
13614 }
Leo Changac3ba772013-10-07 09:47:04 -070013615 if(nla_put_u32(skb, WLAN_HDD_TM_ATTR_TYPE, lphbInd->protocolType))
Leo Changd9df8aa2013-09-26 13:32:26 -070013616 {
13617 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
13618 "WLAN_HDD_TM_ATTR_TYPE put fail");
13619 goto nla_put_failure;
13620 }
Leo Changac3ba772013-10-07 09:47:04 -070013621 if(nla_put(skb, WLAN_HDD_TM_ATTR_DATA,
Leo Changd9df8aa2013-09-26 13:32:26 -070013622 sizeof(tSirLPHBInd), lphbInd))
13623 {
13624 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
13625 "WLAN_HDD_TM_ATTR_DATA put fail");
13626 goto nla_put_failure;
13627 }
Leo Chang9056f462013-08-01 19:21:11 -070013628 cfg80211_testmode_event(skb, GFP_ATOMIC);
13629 return;
13630
13631nla_put_failure:
13632 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
13633 "NLA Put fail");
13634 kfree_skb(skb);
13635
13636 return;
13637}
13638#endif /* FEATURE_WLAN_LPHB */
13639
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053013640static int __wlan_hdd_cfg80211_testmode(struct wiphy *wiphy, void *data, int len)
Leo Chang9056f462013-08-01 19:21:11 -070013641{
13642 struct nlattr *tb[WLAN_HDD_TM_ATTR_MAX + 1];
13643 int err = 0;
13644#ifdef FEATURE_WLAN_LPHB
13645 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
Leo Changd9df8aa2013-09-26 13:32:26 -070013646 eHalStatus smeStatus;
Leo Chang9056f462013-08-01 19:21:11 -070013647#endif /* FEATURE_WLAN_LPHB */
13648
13649 err = nla_parse(tb, WLAN_HDD_TM_ATTR_MAX, data, len, wlan_hdd_tm_policy);
13650 if (err)
13651 {
13652 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
13653 "%s Testmode INV ATTR", __func__);
13654 return err;
13655 }
13656
13657 if (!tb[WLAN_HDD_TM_ATTR_CMD])
13658 {
13659 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
13660 "%s Testmode INV CMD", __func__);
13661 return -EINVAL;
13662 }
13663
13664 switch (nla_get_u32(tb[WLAN_HDD_TM_ATTR_CMD]))
13665 {
13666#ifdef FEATURE_WLAN_LPHB
13667 /* Low Power Heartbeat configuration request */
13668 case WLAN_HDD_TM_CMD_WLAN_HB:
13669 {
13670 int buf_len;
13671 void *buf;
13672 tSirLPHBReq *hb_params = NULL;
Amar Singhal05852702014-02-04 14:40:00 -080013673 tSirLPHBReq *hb_params_temp = NULL;
Leo Chang9056f462013-08-01 19:21:11 -070013674
13675 if (!tb[WLAN_HDD_TM_ATTR_DATA])
13676 {
13677 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
13678 "%s Testmode INV DATA", __func__);
13679 return -EINVAL;
13680 }
13681
13682 buf = nla_data(tb[WLAN_HDD_TM_ATTR_DATA]);
13683 buf_len = nla_len(tb[WLAN_HDD_TM_ATTR_DATA]);
Amar Singhal05852702014-02-04 14:40:00 -080013684
13685 hb_params_temp =(tSirLPHBReq *)buf;
13686 if ((hb_params_temp->cmd == LPHB_SET_TCP_PARAMS_INDID) &&
13687 (hb_params_temp->params.lphbTcpParamReq.timePeriodSec == 0))
13688 return -EINVAL;
13689
Leo Chang9056f462013-08-01 19:21:11 -070013690 hb_params = (tSirLPHBReq *)vos_mem_malloc(sizeof(tSirLPHBReq));
13691 if (NULL == hb_params)
13692 {
13693 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
13694 "%s Request Buffer Alloc Fail", __func__);
13695 return -EINVAL;
13696 }
13697
13698 vos_mem_copy(hb_params, buf, buf_len);
Leo Changd9df8aa2013-09-26 13:32:26 -070013699 smeStatus = sme_LPHBConfigReq((tHalHandle)(pHddCtx->hHal),
13700 hb_params,
13701 wlan_hdd_cfg80211_lphb_ind_handler);
13702 if (eHAL_STATUS_SUCCESS != smeStatus)
Leo Chang9056f462013-08-01 19:21:11 -070013703 {
Leo Changd9df8aa2013-09-26 13:32:26 -070013704 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
13705 "LPHB Config Fail, disable");
Leo Chang9056f462013-08-01 19:21:11 -070013706 vos_mem_free(hb_params);
13707 }
Leo Chang9056f462013-08-01 19:21:11 -070013708 return 0;
13709 }
13710#endif /* FEATURE_WLAN_LPHB */
13711 default:
c_hpothu6ff1c3c2013-10-01 19:01:57 +053013712 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
13713 "%s: unsupported event",__func__);
Leo Chang9056f462013-08-01 19:21:11 -070013714 return -EOPNOTSUPP;
13715 }
13716
13717 return err;
13718}
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053013719
13720static int wlan_hdd_cfg80211_testmode(struct wiphy *wiphy, void *data, int len)
13721{
13722 int ret;
13723
13724 vos_ssr_protect(__func__);
13725 ret = __wlan_hdd_cfg80211_testmode(wiphy, data, len);
13726 vos_ssr_unprotect(__func__);
13727
13728 return ret;
13729}
Leo Chang9056f462013-08-01 19:21:11 -070013730#endif /* CONFIG_NL80211_TESTMODE */
13731
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053013732static int __wlan_hdd_cfg80211_dump_survey(struct wiphy *wiphy,
Madan Mohan Koyyalamudid9383fd2013-08-13 09:27:30 +053013733 struct net_device *dev,
13734 int idx, struct survey_info *survey)
13735{
13736 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
13737 hdd_context_t *pHddCtx;
Mihir Sheted9072e02013-08-21 17:02:29 +053013738 hdd_station_ctx_t *pHddStaCtx;
Madan Mohan Koyyalamudid9383fd2013-08-13 09:27:30 +053013739 tHalHandle halHandle;
Mihir Sheted9072e02013-08-21 17:02:29 +053013740 v_U32_t channel = 0, freq = 0; /* Initialization Required */
Madan Mohan Koyyalamudid9383fd2013-08-13 09:27:30 +053013741 v_S7_t snr,rssi;
13742 int status, i, j, filled = 0;
13743
13744 ENTER();
13745
Madan Mohan Koyyalamudid9383fd2013-08-13 09:27:30 +053013746 if (NULL == pAdapter)
13747 {
13748 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
13749 "%s: HDD adapter is Null", __func__);
13750 return -ENODEV;
13751 }
13752
13753 if (NULL == wiphy)
13754 {
13755 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
13756 "%s: wiphy is Null", __func__);
13757 return -ENODEV;
13758 }
13759
13760 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
13761 status = wlan_hdd_validate_context(pHddCtx);
13762
13763 if (0 != status)
13764 {
13765 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
13766 "%s: HDD context is not valid", __func__);
13767 return status;
13768 }
13769
Mihir Sheted9072e02013-08-21 17:02:29 +053013770 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
13771
Madan Mohan Koyyalamudid9383fd2013-08-13 09:27:30 +053013772 if (0 == pHddCtx->cfg_ini->fEnableSNRMonitoring ||
Mihir Sheted9072e02013-08-21 17:02:29 +053013773 0 != pAdapter->survey_idx ||
13774 eConnectionState_Associated != pHddStaCtx->conn_info.connState)
Madan Mohan Koyyalamudid9383fd2013-08-13 09:27:30 +053013775 {
13776 /* The survey dump ops when implemented completely is expected to
13777 * return a survey of all channels and the ops is called by the
13778 * kernel with incremental values of the argument 'idx' till it
13779 * returns -ENONET. But we can only support the survey for the
13780 * operating channel for now. survey_idx is used to track
13781 * that the ops is called only once and then return -ENONET for
13782 * the next iteration
13783 */
13784 pAdapter->survey_idx = 0;
13785 return -ENONET;
13786 }
13787
13788 halHandle = WLAN_HDD_GET_HAL_CTX(pAdapter);
13789
13790 wlan_hdd_get_snr(pAdapter, &snr);
13791 wlan_hdd_get_rssi(pAdapter, &rssi);
13792
13793 sme_GetOperationChannel(halHandle, &channel, pAdapter->sessionId);
13794 hdd_wlan_get_freq(channel, &freq);
13795
13796
13797 for (i = 0; i < IEEE80211_NUM_BANDS; i++)
13798 {
13799 if (NULL == wiphy->bands[i])
13800 {
13801 VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_INFO,
13802 "%s: wiphy->bands[i] is NULL, i = %d", __func__, i);
13803 continue;
13804 }
13805
13806 for (j = 0; j < wiphy->bands[i]->n_channels; j++)
13807 {
13808 struct ieee80211_supported_band *band = wiphy->bands[i];
13809
13810 if (band->channels[j].center_freq == (v_U16_t)freq)
13811 {
13812 survey->channel = &band->channels[j];
13813 /* The Rx BDs contain SNR values in dB for the received frames
13814 * while the supplicant expects noise. So we calculate and
13815 * return the value of noise (dBm)
13816 * SNR (dB) = RSSI (dBm) - NOISE (dBm)
13817 */
13818 survey->noise = rssi - snr;
13819 survey->filled = SURVEY_INFO_NOISE_DBM;
13820 filled = 1;
13821 }
13822 }
13823 }
13824
13825 if (filled)
13826 pAdapter->survey_idx = 1;
13827 else
13828 {
13829 pAdapter->survey_idx = 0;
13830 return -ENONET;
13831 }
13832
13833 return 0;
13834}
13835
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053013836static int wlan_hdd_cfg80211_dump_survey(struct wiphy *wiphy,
13837 struct net_device *dev,
13838 int idx, struct survey_info *survey)
13839{
13840 int ret;
13841
13842 vos_ssr_protect(__func__);
13843 ret = __wlan_hdd_cfg80211_dump_survey(wiphy, dev, idx, survey);
13844 vos_ssr_unprotect(__func__);
13845
13846 return ret;
13847}
13848
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053013849/*
Mahesh A Saptasagarbcc5b662014-06-02 21:46:23 +053013850 * FUNCTION: __wlan_hdd_cfg80211_resume_wlan
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053013851 * this is called when cfg80211 driver resume
13852 * driver updates latest sched_scan scan result(if any) to cfg80211 database
13853 */
Mahesh A Saptasagarbcc5b662014-06-02 21:46:23 +053013854int __wlan_hdd_cfg80211_resume_wlan(struct wiphy *wiphy)
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053013855{
13856 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
13857 hdd_adapter_t *pAdapter;
13858 hdd_adapter_list_node_t *pAdapterNode, *pNext;
13859 VOS_STATUS status = VOS_STATUS_SUCCESS;
13860
13861 ENTER();
13862
13863 if ( NULL == pHddCtx )
13864 {
13865 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
13866 "%s: HddCtx validation failed", __func__);
13867 return 0;
13868 }
13869
13870 if (pHddCtx->isLogpInProgress)
13871 {
13872 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
13873 "%s: LOGP in Progress. Ignore!!!", __func__);
13874 return 0;
13875 }
13876
Mihir Shete18156292014-03-11 15:38:30 +053013877 if (WLAN_HDD_IS_LOAD_UNLOAD_IN_PROGRESS(pHddCtx))
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053013878 {
13879 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
13880 "%s: Unloading/Loading in Progress. Ignore!!!", __func__);
13881 return 0;
13882 }
13883
13884 spin_lock(&pHddCtx->schedScan_lock);
13885 pHddCtx->isWiphySuspended = FALSE;
13886 if (TRUE != pHddCtx->isSchedScanUpdatePending)
13887 {
13888 spin_unlock(&pHddCtx->schedScan_lock);
13889 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
13890 "%s: Return resume is not due to PNO indication", __func__);
13891 return 0;
13892 }
13893 // Reset flag to avoid updatating cfg80211 data old results again
13894 pHddCtx->isSchedScanUpdatePending = FALSE;
13895 spin_unlock(&pHddCtx->schedScan_lock);
13896
Mahesh A Saptasagarb9c50402014-01-16 15:49:22 +053013897
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053013898 status = hdd_get_front_adapter ( pHddCtx, &pAdapterNode );
13899
13900 while ( NULL != pAdapterNode && VOS_STATUS_SUCCESS == status )
13901 {
13902 pAdapter = pAdapterNode->pAdapter;
13903 if ( (NULL != pAdapter) &&
13904 (WLAN_HDD_INFRA_STATION == pAdapter->device_mode) )
13905 {
13906 if (0 != wlan_hdd_cfg80211_update_bss(pHddCtx->wiphy, pAdapter))
Mahesh A Saptasagarb9c50402014-01-16 15:49:22 +053013907 {
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053013908 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_WARN,
13909 "%s: NO SCAN result", __func__);
Mahesh A Saptasagarb9c50402014-01-16 15:49:22 +053013910 }
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053013911 else
Mahesh A Saptasagarb9c50402014-01-16 15:49:22 +053013912 {
13913 /* Acquire wakelock to handle the case where APP's tries to
13914 * suspend immediately after updating the scan results. Whis
13915 * results in app's is in suspended state and not able to
13916 * process the connect request to AP
13917 */
13918 hdd_prevent_suspend_timeout(2000);
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053013919 cfg80211_sched_scan_results(pHddCtx->wiphy);
Mahesh A Saptasagarb9c50402014-01-16 15:49:22 +053013920 }
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053013921
13922 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
13923 "%s : cfg80211 scan result database updated", __func__);
13924
13925 return 0;
13926
13927 }
13928 status = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
13929 pAdapterNode = pNext;
13930 }
13931
13932 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
13933 "%s: Failed to find Adapter", __func__);
13934 return 0;
13935}
13936
Mahesh A Saptasagarbcc5b662014-06-02 21:46:23 +053013937int wlan_hdd_cfg80211_resume_wlan(struct wiphy *wiphy)
13938{
13939 int ret;
13940
13941 vos_ssr_protect(__func__);
13942 ret = __wlan_hdd_cfg80211_resume_wlan(wiphy);
13943 vos_ssr_unprotect(__func__);
13944
13945 return ret;
13946}
13947
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053013948/*
Mahesh A Saptasagarbcc5b662014-06-02 21:46:23 +053013949 * FUNCTION: __wlan_hdd_cfg80211_suspend_wlan
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053013950 * this is called when cfg80211 driver suspends
13951 */
Mahesh A Saptasagarbcc5b662014-06-02 21:46:23 +053013952int __wlan_hdd_cfg80211_suspend_wlan(struct wiphy *wiphy,
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053013953 struct cfg80211_wowlan *wow)
13954{
13955 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
13956
13957 ENTER();
13958 if (NULL == pHddCtx)
13959 {
13960 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
13961 "%s: HddCtx validation failed", __func__);
13962 return 0;
13963 }
13964
13965 pHddCtx->isWiphySuspended = TRUE;
13966
13967 EXIT();
13968
13969 return 0;
13970}
13971
Mahesh A Saptasagarbcc5b662014-06-02 21:46:23 +053013972int wlan_hdd_cfg80211_suspend_wlan(struct wiphy *wiphy,
13973 struct cfg80211_wowlan *wow)
13974{
13975 int ret;
13976
13977 vos_ssr_protect(__func__);
13978 ret = __wlan_hdd_cfg80211_suspend_wlan(wiphy, wow);
13979 vos_ssr_unprotect(__func__);
13980
13981 return ret;
13982}
Jeff Johnson295189b2012-06-20 16:38:30 -070013983/* cfg80211_ops */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013984static struct cfg80211_ops wlan_hdd_cfg80211_ops =
Jeff Johnson295189b2012-06-20 16:38:30 -070013985{
13986 .add_virtual_intf = wlan_hdd_add_virtual_intf,
13987 .del_virtual_intf = wlan_hdd_del_virtual_intf,
13988 .change_virtual_intf = wlan_hdd_cfg80211_change_iface,
13989 .change_station = wlan_hdd_change_station,
13990#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,4,0))
13991 .add_beacon = wlan_hdd_cfg80211_add_beacon,
13992 .del_beacon = wlan_hdd_cfg80211_del_beacon,
13993 .set_beacon = wlan_hdd_cfg80211_set_beacon,
Jeff Johnson04dd8a82012-06-29 20:41:40 -070013994#else
13995 .start_ap = wlan_hdd_cfg80211_start_ap,
13996 .change_beacon = wlan_hdd_cfg80211_change_beacon,
13997 .stop_ap = wlan_hdd_cfg80211_stop_ap,
Jeff Johnson295189b2012-06-20 16:38:30 -070013998#endif
13999 .change_bss = wlan_hdd_cfg80211_change_bss,
14000 .add_key = wlan_hdd_cfg80211_add_key,
14001 .get_key = wlan_hdd_cfg80211_get_key,
14002 .del_key = wlan_hdd_cfg80211_del_key,
14003 .set_default_key = wlan_hdd_cfg80211_set_default_key,
Jeff Johnson3bbe4bf2013-01-18 17:05:29 -080014004#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,6,0))
Jeff Johnson295189b2012-06-20 16:38:30 -070014005 .set_channel = wlan_hdd_cfg80211_set_channel,
Jeff Johnson3bbe4bf2013-01-18 17:05:29 -080014006#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070014007 .scan = wlan_hdd_cfg80211_scan,
14008 .connect = wlan_hdd_cfg80211_connect,
14009 .disconnect = wlan_hdd_cfg80211_disconnect,
14010 .join_ibss = wlan_hdd_cfg80211_join_ibss,
14011 .leave_ibss = wlan_hdd_cfg80211_leave_ibss,
14012 .set_wiphy_params = wlan_hdd_cfg80211_set_wiphy_params,
14013 .set_tx_power = wlan_hdd_cfg80211_set_txpower,
14014 .get_tx_power = wlan_hdd_cfg80211_get_txpower,
Jeff Johnson295189b2012-06-20 16:38:30 -070014015 .remain_on_channel = wlan_hdd_cfg80211_remain_on_channel,
14016 .cancel_remain_on_channel = wlan_hdd_cfg80211_cancel_remain_on_channel,
DARAM SUDHA39eede62014-02-12 11:16:40 +053014017 .mgmt_tx = wlan_hdd_mgmt_tx,
Jeff Johnson295189b2012-06-20 16:38:30 -070014018#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
14019 .mgmt_tx_cancel_wait = wlan_hdd_cfg80211_mgmt_tx_cancel_wait,
14020 .set_default_mgmt_key = wlan_hdd_set_default_mgmt_key,
14021 .set_txq_params = wlan_hdd_set_txq_params,
14022#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070014023 .get_station = wlan_hdd_cfg80211_get_station,
14024 .set_power_mgmt = wlan_hdd_cfg80211_set_power_mgmt,
14025 .del_station = wlan_hdd_cfg80211_del_station,
Jeff Johnson04dd8a82012-06-29 20:41:40 -070014026 .add_station = wlan_hdd_cfg80211_add_station,
14027#ifdef FEATURE_WLAN_LFR
14028 .set_pmksa = wlan_hdd_cfg80211_set_pmksa,
14029 .del_pmksa = wlan_hdd_cfg80211_del_pmksa,
14030 .flush_pmksa = wlan_hdd_cfg80211_flush_pmksa,
14031#endif
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070014032#if defined(WLAN_FEATURE_VOWIFI_11R) && defined(KERNEL_SUPPORT_11R_CFG80211)
14033 .update_ft_ies = wlan_hdd_cfg80211_update_ft_ies,
14034#endif
Mohit Khanna698ba2a2012-12-04 15:08:18 -080014035#ifdef FEATURE_WLAN_TDLS
14036 .tdls_mgmt = wlan_hdd_cfg80211_tdls_mgmt,
14037 .tdls_oper = wlan_hdd_cfg80211_tdls_oper,
14038#endif
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053014039#ifdef WLAN_FEATURE_GTK_OFFLOAD
14040 .set_rekey_data = wlan_hdd_cfg80211_set_rekey_data,
14041#endif /* WLAN_FEATURE_GTK_OFFLOAD */
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053014042#ifdef FEATURE_WLAN_SCAN_PNO
14043 .sched_scan_start = wlan_hdd_cfg80211_sched_scan_start,
14044 .sched_scan_stop = wlan_hdd_cfg80211_sched_scan_stop,
14045#endif /*FEATURE_WLAN_SCAN_PNO */
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053014046 .resume = wlan_hdd_cfg80211_resume_wlan,
14047 .suspend = wlan_hdd_cfg80211_suspend_wlan,
Gopichand Nakkalac005b7c2013-05-14 16:04:14 +053014048 .set_mac_acl = wlan_hdd_cfg80211_set_mac_acl,
Leo Chang9056f462013-08-01 19:21:11 -070014049#ifdef WLAN_NL80211_TESTMODE
14050 .testmode_cmd = wlan_hdd_cfg80211_testmode,
14051#endif
Madan Mohan Koyyalamudid9383fd2013-08-13 09:27:30 +053014052 .dump_survey = wlan_hdd_cfg80211_dump_survey,
Jeff Johnson295189b2012-06-20 16:38:30 -070014053};
14054